diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/barrier.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/barrier.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/barrier.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/barrier.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,11 +16,13 @@ __asm__ __volatile__("wmb": : :"memory")
 __asm__ __volatile__("mb": : :"memory")
 
 #ifdef CONFIG_SMP
+#define __ASM_SMP_MB	"\tmb\n"
 #define smp_mb()	mb()
 #define smp_rmb()	rmb()
 #define smp_wmb()	wmb()
 #define smp_read_barrier_depends()	read_barrier_depends()
 #else
+#define __ASM_SMP_MB
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
 #define smp_wmb()	barrier()
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/futex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,116 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
+#ifndef _ASM_ALPHA_FUTEX_H
+#define _ASM_ALPHA_FUTEX_H
 
-#include <asm-generic/futex.h>
+#ifdef __KERNEL__
 
-#endif
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+#include <asm/barrier.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+	__asm__ __volatile__(					\
+		__ASM_SMP_MB					\
+	"1:	ldl_l	%0,0(%2)\n"				\
+		insn						\
+	"2:	stl_c	%1,0(%2)\n"				\
+	"	beq	%1,4f\n"				\
+	"	mov	$31,%1\n"				\
+	"3:	.subsection 2\n"				\
+	"4:	br	1b\n"					\
+	"	.previous\n"					\
+	"	.section __ex_table,\"a\"\n"			\
+	"	.long	1b-.\n"					\
+	"	lda	$31,3b-1b(%1)\n"			\
+	"	.long	2b-.\n"					\
+	"	lda	$31,3b-2b(%1)\n"			\
+	"	.previous\n"					\
+	:	"=&r" (oldval), "=&r"(ret)			\
+	:	"r" (uaddr), "r"(oparg)				\
+	:	"memory")
+
+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("mov %3,%1\n", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ADD:
+		__futex_atomic_op("addl %0,%3,%1\n", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_OR:
+		__futex_atomic_op("or %0,%3,%1\n", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ANDN:
+		__futex_atomic_op("andnot %0,%3,%1\n", ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_XOR:
+		__futex_atomic_op("xor %0,%3,%1\n", 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__ (
+		__ASM_SMP_MB
+	"1:	ldl_l	%0,0(%2)\n"
+	"	cmpeq	%0,%3,%1\n"
+	"	beq	%1,3f\n"
+	"	mov	%4,%1\n"
+	"2:	stl_c	%1,0(%2)\n"
+	"	beq	%1,4f\n"
+	"3:	.subsection 2\n"
+	"4:	br	1b\n"
+	"	.previous\n"
+	"	.section __ex_table,\"a\"\n"
+	"	.long	1b-.\n"
+	"	lda	$31,3b-1b(%0)\n"
+	"	.long	2b-.\n"
+	"	lda	$31,3b-2b(%0)\n"
+	"	.previous\n"
+	:	"=&r"(prev), "=&r"(cmp)
+	:	"r"(uaddr), "r"((long)oldval), "r"(newval)
+	:	"memory");
+
+	return prev;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_ALPHA_FUTEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/hardirq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,17 +14,4 @@ typedef struct {
 
 void ack_bad_irq(unsigned int irq);
 
-#define HARDIRQ_BITS	12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially nestable IRQ sources in the system
- * to nest on a single CPU. On Alpha, interrupts are masked at the CPU
- * by IPL as well as at the system level. We only have 8 IPLs (UNIX PALcode)
- * so we really only have 8 nestable IRQs, but allow some overhead
- */
-#if (1 << HARDIRQ_BITS) < 16
-#error HARDIRQ_BITS is too low!
-#endif
-
 #endif /* _ALPHA_HARDIRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/machvec.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/machvec.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/machvec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/machvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@ struct alpha_machine_vector
 	void (*update_irq_hw)(unsigned long, unsigned long, int);
 	void (*ack_irq)(unsigned long);
 	void (*device_interrupt)(unsigned long vector);
-	void (*machine_check)(u64 vector, u64 la);
+	void (*machine_check)(unsigned long vector, unsigned long la);
 
 	void (*smp_callin)(void);
 	void (*init_arch)(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -273,4 +273,18 @@ struct pci_dev *alpha_gendev_to_pci(stru
 
 extern struct pci_dev *isa_bridge;
 
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+			   size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+			    size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+				      struct vm_area_struct *vma,
+				      enum pci_mmap_state mmap_state);
+extern void pci_adjust_legacy_attr(struct pci_bus *bus,
+				   enum pci_mmap_state mmap_type);
+#define HAVE_PCI_LEGACY	1
+
+extern int pci_create_resource_files(struct pci_dev *dev);
+extern void pci_remove_resource_files(struct pci_dev *dev);
+
 #endif /* __ALPHA_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/percpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,9 @@
 #ifndef __ALPHA_PERCPU_H
 #define __ALPHA_PERCPU_H
+
 #include <linux/compiler.h>
 #include <linux/threads.h>
+#include <linux/percpu-defs.h>
 
 /*
  * Determine the real variable name from the name visible in the
@@ -73,6 +75,28 @@ extern unsigned long __per_cpu_offset[NR
 
 #endif /* SMP */
 
-#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
+#ifdef CONFIG_SMP
+#define PER_CPU_BASE_SECTION ".data.percpu"
+#else
+#define PER_CPU_BASE_SECTION ".data"
+#endif
+
+#ifdef CONFIG_SMP
+
+#ifdef MODULE
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#else
+#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
+#endif
+#define PER_CPU_FIRST_SECTION ".first"
+
+#else
+
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#define PER_CPU_FIRST_SECTION ""
+
+#endif
+
+#define PER_CPU_ATTRIBUTES
 
 #endif /* __ALPHA_PERCPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -62,6 +62,9 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 /* 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.29-gnu1/arch/alpha/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -166,6 +166,9 @@ static inline void __raw_write_unlock(ra
 	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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/statfs.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/statfs.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/statfs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/statfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef _ALPHA_STATFS_H
 #define _ALPHA_STATFS_H
 
+#include <linux/types.h>
+
 /* Alpha is the only 64-bit platform with 32-bit statfs. And doesn't
    even seem to implement statfs64 */
 #define __statfs_word __u32
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _ALPHA_SWAB_H
 #define _ALPHA_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 #include <asm/compiler.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/system.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -309,518 +309,71 @@ extern int __min_ipl;
 #define tbia()		__tbi(-2, /* no second argument */)
 
 /*
- * Atomic exchange.
- * Since it can be used to implement critical sections
- * it must clobber "memory" (also for interrupts in UP).
+ * Atomic exchange routines.
  */
 
-static inline unsigned long
-__xchg_u8(volatile char *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	insbl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extbl	%2,%4,%0\n"
-	"	mskbl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u16(volatile short *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	inswl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extwl	%2,%4,%0\n"
-	"	mskwl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u32(volatile int *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-static inline unsigned long
-__xchg_u64(volatile long *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid xchg().  */
-extern void __xchg_called_with_bad_pointer(void);
-
-#define __xchg(ptr, x, size) \
-({ \
-	unsigned long __xchg__res; \
-	volatile void *__xchg__ptr = (ptr); \
-	switch (size) { \
-		case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
-		case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
-		case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
-		case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
-		default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
-	} \
-	__xchg__res; \
-})
+#define __ASM__MB
+#define ____xchg(type, args...)		__xchg ## type ## _local(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ## type ## _local(args)
+#include <asm/xchg.h>
 
-#define xchg(ptr,x)							     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+#define xchg_local(ptr,x)						\
+  ({									\
+     __typeof__(*(ptr)) _x_ = (x);					\
+     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	\
+				       sizeof(*(ptr)));			\
   })
 
-static inline unsigned long
-__xchg_u8_local(volatile char *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	insbl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extbl	%2,%4,%0\n"
-	"	mskbl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u16_local(volatile short *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	inswl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extwl	%2,%4,%0\n"
-	"	mskwl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u32_local(volatile int *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-static inline unsigned long
-__xchg_u64_local(volatile long *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-#define __xchg_local(ptr, x, size) \
-({ \
-	unsigned long __xchg__res; \
-	volatile void *__xchg__ptr = (ptr); \
-	switch (size) { \
-		case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
-		case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
-		case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
-		case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
-		default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
-	} \
-	__xchg__res; \
-})
-
-#define xchg_local(ptr,x)						     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	     \
-     		sizeof(*(ptr))); \
+#define cmpxchg_local(ptr, o, n)					\
+  ({									\
+     __typeof__(*(ptr)) _o_ = (o);					\
+     __typeof__(*(ptr)) _n_ = (n);					\
+     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	\
+					  (unsigned long)_n_,		\
+					  sizeof(*(ptr)));		\
   })
 
-/* 
- * 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.
- *
- * The memory barrier should be placed in SMP only when we actually
- * make the change. If we don't change anything (so if the returned
- * prev is equal to old) then we aren't acquiring anything new and
- * we don't need any memory barrier as far I can tell.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long
-__cmpxchg_u8(volatile char *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	insbl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extbl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskbl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16(volatile short *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	inswl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extwl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskwl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32(volatile int *m, int old, int new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
-{
-	unsigned long prev, cmp;
+#define cmpxchg64_local(ptr, o, n)					\
+  ({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg_local((ptr), (o), (n));					\
+  })
 
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,3f\n"
 #ifdef CONFIG_SMP
-	"	mb\n"
+#undef __ASM__MB
+#define __ASM__MB	"\tmb\n"
 #endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static __always_inline unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
-{
-	switch (size) {
-		case 1:
-			return __cmpxchg_u8(ptr, old, new);
-		case 2:
-			return __cmpxchg_u16(ptr, old, new);
-		case 4:
-			return __cmpxchg_u32(ptr, old, new);
-		case 8:
-			return __cmpxchg_u64(ptr, old, new);
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
+#undef ____xchg
+#undef ____cmpxchg
+#define ____xchg(type, args...)		__xchg ##type(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ##type(args)
+#include <asm/xchg.h>
 
-#define cmpxchg(ptr, o, n)						 \
-  ({									 \
-     __typeof__(*(ptr)) _o_ = (o);					 \
-     __typeof__(*(ptr)) _n_ = (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 xchg(ptr,x)							\
+  ({									\
+     __typeof__(*(ptr)) _x_ = (x);					\
+     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,		\
+				 sizeof(*(ptr)));			\
   })
 
-static inline unsigned long
-__cmpxchg_u8_local(volatile char *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	insbl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extbl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskbl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16_local(volatile short *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	inswl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extwl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskwl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32_local(volatile int *m, int old, int new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static __always_inline unsigned long
-__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
-		int size)
-{
-	switch (size) {
-		case 1:
-			return __cmpxchg_u8_local(ptr, old, new);
-		case 2:
-			return __cmpxchg_u16_local(ptr, old, new);
-		case 4:
-			return __cmpxchg_u32_local(ptr, old, new);
-		case 8:
-			return __cmpxchg_u64_local(ptr, old, new);
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
-
-#define cmpxchg_local(ptr, o, n)					 \
-  ({									 \
-     __typeof__(*(ptr)) _o_ = (o);					 \
-     __typeof__(*(ptr)) _n_ = (n);					 \
-     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	 \
-				    (unsigned long)_n_, sizeof(*(ptr))); \
+#define cmpxchg(ptr, o, n)						\
+  ({									\
+     __typeof__(*(ptr)) _o_ = (o);					\
+     __typeof__(*(ptr)) _n_ = (n);					\
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		\
+				    (unsigned long)_n_,	sizeof(*(ptr)));\
   })
-#define cmpxchg64_local(ptr, o, n)					 \
-  ({									 \
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				 \
-	cmpxchg_local((ptr), (o), (n));					 \
+
+#define cmpxchg64(ptr, o, n)						\
+  ({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg((ptr), (o), (n));					\
   })
 
+#undef __ASM__MB
+#undef ____cmpxchg
+
+#define __HAVE_ARCH_CMPXCHG 1
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/types.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/types.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+
+#ifdef __KERNEL__
+#include <asm-generic/int-ll64.h>
+#else
 #include <asm-generic/int-l64.h>
+#endif
 
 #ifndef __ASSEMBLY__
 
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/uaccess.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -498,14 +498,16 @@ struct exception_table_entry
 };
 
 /* Returns the new pc */
-#define fixup_exception(map_reg, fixup, pc)			\
+#define fixup_exception(map_reg, _fixup, pc)			\
 ({								\
-	if ((fixup)->fixup.bits.valreg != 31)			\
-		map_reg((fixup)->fixup.bits.valreg) = 0;	\
-	if ((fixup)->fixup.bits.errreg != 31)			\
-		map_reg((fixup)->fixup.bits.errreg) = -EFAULT;	\
-	(pc) + (fixup)->fixup.bits.nextinsn;			\
+	if ((_fixup)->fixup.bits.valreg != 31)			\
+		map_reg((_fixup)->fixup.bits.valreg) = 0;	\
+	if ((_fixup)->fixup.bits.errreg != 31)			\
+		map_reg((_fixup)->fixup.bits.errreg) = -EFAULT;	\
+	(pc) + (_fixup)->fixup.bits.nextinsn;			\
 })
 
+#define ARCH_HAS_SORT_EXTABLE
+#define ARCH_HAS_SEARCH_EXTABLE
 
 #endif /* __ALPHA_UACCESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/include/asm/xchg.h linux-libre-2.6.30-gnu1/arch/alpha/include/asm/xchg.h
--- linux-libre-2.6.29-gnu1/arch/alpha/include/asm/xchg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/alpha/include/asm/xchg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,258 @@
+#ifndef __ALPHA_SYSTEM_H
+#error Do not include xchg.h directly!
+#else
+/*
+ * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
+ * except that local version do not have the expensive memory barrier.
+ * So this file is included twice from asm/system.h.
+ */
+
+/*
+ * Atomic exchange.
+ * Since it can be used to implement critical sections
+ * it must clobber "memory" (also for interrupts in UP).
+ */
+
+static inline unsigned long
+____xchg(_u8, volatile char *m, unsigned long val)
+{
+	unsigned long ret, tmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%4,7,%3\n"
+	"	insbl	%1,%4,%1\n"
+	"1:	ldq_l	%2,0(%3)\n"
+	"	extbl	%2,%4,%0\n"
+	"	mskbl	%2,%4,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%3)\n"
+	"	beq	%2,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br	1b\n"
+	".previous"
+	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+	: "r" ((long)m), "1" (val) : "memory");
+
+	return ret;
+}
+
+static inline unsigned long
+____xchg(_u16, volatile short *m, unsigned long val)
+{
+	unsigned long ret, tmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%4,7,%3\n"
+	"	inswl	%1,%4,%1\n"
+	"1:	ldq_l	%2,0(%3)\n"
+	"	extwl	%2,%4,%0\n"
+	"	mskwl	%2,%4,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%3)\n"
+	"	beq	%2,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br	1b\n"
+	".previous"
+	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+	: "r" ((long)m), "1" (val) : "memory");
+
+	return ret;
+}
+
+static inline unsigned long
+____xchg(_u32, volatile int *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	"1:	ldl_l %0,%4\n"
+	"	bis $31,%3,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br 1b\n"
+	".previous"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "rI" (val), "m" (*m) : "memory");
+
+	return val;
+}
+
+static inline unsigned long
+____xchg(_u64, volatile long *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%4\n"
+	"	bis $31,%3,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br 1b\n"
+	".previous"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "rI" (val), "m" (*m) : "memory");
+
+	return val;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid xchg().  */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____xchg(, volatile void *ptr, unsigned long x, int size)
+{
+	switch (size) {
+		case 1:
+			return ____xchg(_u8, ptr, x);
+		case 2:
+			return ____xchg(_u16, ptr, x);
+		case 4:
+			return ____xchg(_u32, ptr, x);
+		case 8:
+			return ____xchg(_u64, ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+/*
+ * 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.
+ *
+ * The memory barrier should be placed in SMP only when we actually
+ * make the change. If we don't change anything (so if the returned
+ * prev is equal to old) then we aren't acquiring anything new and
+ * we don't need any memory barrier as far I can tell.
+ */
+
+static inline unsigned long
+____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
+{
+	unsigned long prev, tmp, cmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%5,7,%4\n"
+	"	insbl	%1,%5,%1\n"
+	"1:	ldq_l	%2,0(%4)\n"
+	"	extbl	%2,%5,%0\n"
+	"	cmpeq	%0,%6,%3\n"
+	"	beq	%3,2f\n"
+	"	mskbl	%2,%5,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%4)\n"
+	"	beq	%2,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
+{
+	unsigned long prev, tmp, cmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%5,7,%4\n"
+	"	inswl	%1,%5,%1\n"
+	"1:	ldq_l	%2,0(%4)\n"
+	"	extwl	%2,%5,%0\n"
+	"	cmpeq	%0,%6,%3\n"
+	"	beq	%3,2f\n"
+	"	mskwl	%2,%5,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%4)\n"
+	"	beq	%2,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u32, volatile int *m, int old, int new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldl_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new,
+	      int size)
+{
+	switch (size) {
+		case 1:
+			return ____cmpxchg(_u8, ptr, old, new);
+		case 2:
+			return ____cmpxchg(_u16, ptr, old, new);
+		case 4:
+			return ____cmpxchg(_u32, ptr, old, new);
+		case 8:
+			return ____cmpxchg(_u64, ptr, old, new);
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/binfmt_loader.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/binfmt_loader.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/binfmt_loader.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/binfmt_loader.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,6 @@ static struct linux_binfmt loader_format
 
 static int __init init_loader_binfmt(void)
 {
-	return register_binfmt(&loader_format);
+	return insert_binfmt(&loader_format);
 }
 arch_initcall(init_loader_binfmt);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/entry.S linux-libre-2.6.30-gnu1/arch/alpha/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -903,8 +903,9 @@ sys_alpha_pipe:
 	stq	$26, 0($sp)
 	.prologue 0
 
+	mov	$31, $17
 	lda	$16, 8($sp)
-	jsr	$26, do_pipe
+	jsr	$26, do_pipe_flags
 
 	ldq	$26, 0($sp)
 	bne	$0, 1f
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_ev6.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_ev6.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_ev6.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_ev6.c	2009-06-09 23:05:27.000000000 -0400
@@ -157,8 +157,8 @@ ev6_parse_cbox(u64 c_addr, u64 c1_syn, u
 		       err_print_prefix,
 		       streamname[stream], bitsname[bits], sourcename[source]);
 
-	printk("%s    Address: 0x%016lx\n"
-	         "    Syndrome[upper.lower]: %02lx.%02lx\n", 
+	printk("%s    Address: 0x%016llx\n"
+	         "    Syndrome[upper.lower]: %02llx.%02llx\n",
 	       err_print_prefix,
 	       c_addr,
 	       c2_syn, c1_syn);
@@ -229,7 +229,7 @@ ev6_process_logout_frame(struct el_commo
 }
 
 void
-ev6_machine_check(u64 vector, u64 la_ptr)
+ev6_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 	struct el_common *mchk_header = (struct el_common *)la_ptr;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_ev7.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_ev7.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_ev7.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_ev7.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,7 @@ ev7_collect_logout_frame_subpackets(stru
 }
 
 void
-ev7_machine_check(u64 vector, u64 la_ptr)
+ev7_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
 	char *saved_err_prefix = err_print_prefix;
@@ -246,13 +246,13 @@ ev7_process_pal_subpacket(struct el_subp
 
 	switch(header->type) {
 	case EL_TYPE__PAL__LOGOUT_FRAME:
-		printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n",
+		printk("%s*** MCHK occurred on LPID %lld (RBOX %llx)\n",
 		       err_print_prefix,
 		       packet->by_type.logout.whami, 
 		       packet->by_type.logout.rbox_whami);
 		el_print_timestamp(&packet->by_type.logout.timestamp);
-		printk("%s  EXC_ADDR: %016lx\n"
-		         "  HALT_CODE: %lx\n", 
+		printk("%s  EXC_ADDR: %016llx\n"
+		         "  HALT_CODE: %llx\n",
 		       err_print_prefix,
 		       packet->by_type.logout.exc_addr,
 		       packet->by_type.logout.halt_code);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_impl.h linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_impl.h
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_impl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_impl.h	2009-06-09 23:05:27.000000000 -0400
@@ -60,26 +60,26 @@ extern struct ev7_lf_subpackets *
 ev7_collect_logout_frame_subpackets(struct el_subpacket *,
 				    struct ev7_lf_subpackets *);
 extern void ev7_register_error_handlers(void);
-extern void ev7_machine_check(u64, u64);
+extern void ev7_machine_check(unsigned long, unsigned long);
 
 /*
  * err_ev6.c
  */
 extern void ev6_register_error_handlers(void);
 extern int ev6_process_logout_frame(struct el_common *, int);
-extern void ev6_machine_check(u64, u64);
+extern void ev6_machine_check(unsigned long, unsigned long);
 
 /*
  * err_marvel.c
  */
-extern void marvel_machine_check(u64, u64);
+extern void marvel_machine_check(unsigned long, unsigned long);
 extern void marvel_register_error_handlers(void);
 
 /*
  * err_titan.c
  */
 extern int titan_process_logout_frame(struct el_common *, int);
-extern void titan_machine_check(u64, u64);
+extern void titan_machine_check(unsigned long, unsigned long);
 extern void titan_register_error_handlers(void);
 extern int privateer_process_logout_frame(struct el_common *, int);
-extern void privateer_machine_check(u64, u64);
+extern void privateer_machine_check(unsigned long, unsigned long);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_marvel.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_marvel.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_marvel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_marvel.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,7 @@ marvel_print_po7_crrct_sym(u64 crrct_sym
 
 
 	printk("%s      Correctable Error Symptoms:\n"
-	       "%s        Syndrome: 0x%lx\n",
+	       "%s        Syndrome: 0x%llx\n",
 	       err_print_prefix,
 	       err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
 	marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
@@ -186,7 +186,7 @@ marvel_print_po7_uncrr_sym(u64 uncrr_sym
 	uncrr_sym &= valid_mask;
 
 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
-		printk("%s        Syndrome: 0x%lx\n",
+		printk("%s        Syndrome: 0x%llx\n",
 		       err_print_prefix, 
 		       EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
 
@@ -307,7 +307,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym
 		sprintf(opcode_str, "BlkIO");
 		break;
 	default:
-		sprintf(opcode_str, "0x%lx\n", 
+		sprintf(opcode_str, "0x%llx\n",
 			EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
 		break;
 	}
@@ -321,7 +321,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym
 	       opcode_str);
 
 	if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
-		printk("%s        Packet Offset 0x%08lx\n",
+		printk("%s        Packet Offset 0x%08llx\n",
 		       err_print_prefix,
 		       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
 }
@@ -480,8 +480,8 @@ marvel_print_po7_err_sum(struct ev7_pal_
 		printk("%s    Lost Error\n", err_print_prefix);
 
 	printk("%s    Failing Packet:\n"
-	       "%s      Cycle 1: %016lx\n"
-	       "%s      Cycle 2: %016lx\n",
+	       "%s      Cycle 1: %016llx\n"
+	       "%s      Cycle 2: %016llx\n",
 	       err_print_prefix,
 	       err_print_prefix, io->po7_err_pkt0,
 	       err_print_prefix, io->po7_err_pkt1);
@@ -515,9 +515,9 @@ marvel_print_pox_tlb_err(u64 tlb_err)
 	if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
 		return;
 
-	printk("%s      TLB Error on index 0x%lx:\n"
+	printk("%s      TLB Error on index 0x%llx:\n"
 	       "%s        - %s\n"
-	       "%s        - Addr: 0x%016lx\n",
+	       "%s        - Addr: 0x%016llx\n",
 	       err_print_prefix,
 	       EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
 	       err_print_prefix,
@@ -579,7 +579,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt
 		sprintf(message, "Uncorrectable Split Write Data Error");
 		break;
 	default:
-		sprintf(message, "%08lx\n", 
+		sprintf(message, "%08llx\n",
 			EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
 		break;
 	}
@@ -620,9 +620,9 @@ marvel_print_pox_trans_sum(u64 trans_sum
 		return;
 
 	printk("%s      Transaction Summary:\n"
-	       "%s        Command: 0x%lx - %s\n"
-	       "%s        Address: 0x%016lx%s\n"
-	       "%s        PCI-X Master Slot: 0x%lx\n",
+	       "%s        Command: 0x%llx - %s\n"
+	       "%s        Address: 0x%016llx%s\n"
+	       "%s        PCI-X Master Slot: 0x%llx\n",
 	       err_print_prefix, 
 	       err_print_prefix, 
 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
@@ -964,12 +964,12 @@ marvel_process_io_error(struct ev7_lf_su
 
 #if 0
 		printk("%s  PORT 7 ERROR:\n"
-		       "%s    PO7_ERROR_SUM: %016lx\n"
-		       "%s    PO7_UNCRR_SYM: %016lx\n"
-		       "%s    PO7_CRRCT_SYM: %016lx\n"
-		       "%s    PO7_UGBGE_SYM: %016lx\n"
-		       "%s    PO7_ERR_PKT0:  %016lx\n"
-		       "%s    PO7_ERR_PKT1:  %016lx\n",
+		       "%s    PO7_ERROR_SUM: %016llx\n"
+		       "%s    PO7_UNCRR_SYM: %016llx\n"
+		       "%s    PO7_CRRCT_SYM: %016llx\n"
+		       "%s    PO7_UGBGE_SYM: %016llx\n"
+		       "%s    PO7_ERR_PKT0:  %016llx\n"
+		       "%s    PO7_ERR_PKT1:  %016llx\n",
 		       err_print_prefix,
 		       err_print_prefix, io->po7_error_sum,
 		       err_print_prefix, io->po7_uncrr_sym,
@@ -987,12 +987,12 @@ marvel_process_io_error(struct ev7_lf_su
 		if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
 			continue;
 
-		printk("%s  PID %u PORT %d POx_ERR_SUM: %016lx\n", 
+		printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
 		       err_print_prefix, 
 		       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
 		marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
 
-		printk("%s  [ POx_FIRST_ERR: %016lx ]\n", 
+		printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
 		       err_print_prefix, io->ports[i].pox_first_err);
 		marvel_print_pox_err(io->ports[i].pox_first_err, 
 				     &io->ports[i]);
@@ -1042,7 +1042,7 @@ marvel_process_logout_frame(struct ev7_l
 }
 
 void
-marvel_machine_check(u64 vector, u64 la_ptr)
+marvel_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
 	int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_titan.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_titan.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/err_titan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/err_titan.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,12 +107,12 @@ titan_parse_p_serror(int which, u64 serr
 	if (!print)
 		return status;
 
-	printk("%s  PChip %d SERROR: %016lx\n", 
+	printk("%s  PChip %d SERROR: %016llx\n",
 	       err_print_prefix, which, serror);
 	if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
 		printk("%s    %sorrectable ECC Error:\n"
 		       "      Source: %-6s  Command: %-8s  Syndrome: 0x%08x\n"
-		       "      Address: 0x%lx\n", 
+		       "      Address: 0x%llx\n",
 		       err_print_prefix,
 		       (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
 		       serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
@@ -223,7 +223,7 @@ titan_parse_p_perror(int which, int port
 	if (!print) 
 		return status;
 
-	printk("%s  PChip %d %cPERROR: %016lx\n", 
+	printk("%s  PChip %d %cPERROR: %016llx\n",
 	       err_print_prefix, which, 
 	       port ? 'A' : 'G', perror);
 	if (perror & TITAN__PCHIP_PERROR__IPTPW)
@@ -316,7 +316,7 @@ titan_parse_p_agperror(int which, u64 ag
 	addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
 	len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
 
-	printk("%s  PChip %d AGPERROR: %016lx\n", err_print_prefix,
+	printk("%s  PChip %d AGPERROR: %016llx\n", err_print_prefix,
 	       which, agperror);
 	if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
 		printk("%s    No Window\n", err_print_prefix);
@@ -380,7 +380,7 @@ titan_process_logout_frame(struct el_com
 }
 
 void
-titan_machine_check(u64 vector, u64 la_ptr)
+titan_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 	struct el_common *mchk_header = (struct el_common *)la_ptr;
 	struct el_TITAN_sysdata_mcheck *tmchk =
@@ -597,16 +597,16 @@ privateer_process_680_frame(struct el_co
 		return status;
 
 	/* TODO - decode instead of just dumping... */
-	printk("%s  Summary Flags:         %016lx\n"
- 	         "  CChip DIRx:            %016lx\n"
-		 "  System Management IR:  %016lx\n"
-		 "  CPU IR:                %016lx\n"
-		 "  Power Supply IR:       %016lx\n"
-		 "  LM78 Fault Status:     %016lx\n"
-		 "  System Doors:          %016lx\n"
-		 "  Temperature Warning:   %016lx\n"
-		 "  Fan Control:           %016lx\n"
-		 "  Fatal Power Down Code: %016lx\n",
+	printk("%s  Summary Flags:         %016llx\n"
+ 	         "  CChip DIRx:            %016llx\n"
+		 "  System Management IR:  %016llx\n"
+		 "  CPU IR:                %016llx\n"
+		 "  Power Supply IR:       %016llx\n"
+		 "  LM78 Fault Status:     %016llx\n"
+		 "  System Doors:          %016llx\n"
+		 "  Temperature Warning:   %016llx\n"
+		 "  Fan Control:           %016llx\n"
+		 "  Fatal Power Down Code: %016llx\n",
 	       err_print_prefix,
 	       emchk->summary,
 	       emchk->c_dirx,
@@ -702,7 +702,7 @@ privateer_process_logout_frame(struct el
 }
 
 void
-privateer_machine_check(u64 vector, u64 la_ptr)
+privateer_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 	struct el_common *mchk_header = (struct el_common *)la_ptr;
 	struct el_TITAN_sysdata_mcheck *tmchk =
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/head.S linux-libre-2.6.30-gnu1/arch/alpha/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -7,10 +7,11 @@
  * the kernel global pointer and jump to the kernel entry-point.
  */
 
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/asm-offsets.h>
 
-.section .text.head, "ax"
+__HEAD
 .globl swapper_pg_dir
 .globl _stext
 swapper_pg_dir=SWAPPER_PGD
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/irq_alpha.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/irq_alpha.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/irq_alpha.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/irq_alpha.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,7 @@ do_entInt(unsigned long type, unsigned l
 		smp_percpu_timer_interrupt(regs);
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
-		        kstat_cpu(cpu).irqs[RTC_IRQ]++;
+		        kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
 		} else {
 			handle_irq(RTC_IRQ);
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/irq.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,7 +55,7 @@ int irq_select_affinity(unsigned int irq
 		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
 	last_cpu = cpu;
 
-	irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+	cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
 	irq_desc[irq].chip->set_affinity(irq, cpumask_of(cpu));
 	return 0;
 }
@@ -90,7 +90,7 @@ show_interrupts(struct seq_file *p, void
 		seq_printf(p, "%10u ", kstat_irqs(irq));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[irq].chip->typename);
 		seq_printf(p, "  %c%s",
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/Makefile linux-libre-2.6.30-gnu1/arch/alpha/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -8,11 +8,11 @@ EXTRA_CFLAGS	:= -Werror -Wno-sign-compar
 
 obj-y    := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
 	    irq_alpha.o signal.o setup.o ptrace.o time.o \
-	    alpha_ksyms.o systbls.o err_common.o io.o binfmt_loader.o
+	    alpha_ksyms.o systbls.o err_common.o io.o
 
 obj-$(CONFIG_VGA_HOSE)	+= console.o
 obj-$(CONFIG_SMP)	+= smp.o
-obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o
+obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o pci-sysfs.o
 obj-$(CONFIG_SRM_ENV)	+= srm_env.o
 obj-$(CONFIG_MODULES)	+= module.o
 
@@ -43,6 +43,10 @@ else
 # Misc support
 obj-$(CONFIG_ALPHA_SRM)		+= srmcons.o
 
+ifdef CONFIG_BINFMT_AOUT
+obj-y	+= binfmt_loader.o
+endif
+
 # Core logic support
 obj-$(CONFIG_ALPHA_APECS)	+= core_apecs.o
 obj-$(CONFIG_ALPHA_CIA)		+= core_cia.o
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/osf_sys.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/osf_sys.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/osf_sys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/osf_sys.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,8 +46,6 @@
 #include <asm/hwrpb.h>
 #include <asm/processor.h>
 
-extern int do_pipe(int *);
-
 /*
  * Brk needs to return an error.  Still support Linux's brk(0) query idiom,
  * which OSF programs just shouldn't be doing.  We're still not quite
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,7 +168,7 @@ pcibios_align_resource(void *data, struc
 		 */
 
 		/* Align to multiple of size of minimum base.  */
-		alignto = max(0x1000UL, align);
+		alignto = max_t(resource_size_t, 0x1000, align);
 		start = ALIGN(start, alignto);
 		if (hose->sparse_mem_base && size <= 7 * 16*MB) {
 			if (((start / (16*MB)) & 0x7) == 0) {
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci_iommu.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci_iommu.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci_iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci_iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -247,7 +247,7 @@ pci_map_single_1(struct pci_dev *pdev, v
 	    && paddr + size <= __direct_map_size) {
 		ret = paddr + __direct_map_base;
 
-		DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n",
+		DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n",
 		      cpu_addr, size, ret, __builtin_return_address(0));
 
 		return ret;
@@ -258,7 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, v
 	if (dac_allowed) {
 		ret = paddr + alpha_mv.pci_dac_offset;
 
-		DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n",
+		DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n",
 		      cpu_addr, size, ret, __builtin_return_address(0));
 
 		return ret;
@@ -299,7 +299,7 @@ pci_map_single_1(struct pci_dev *pdev, v
 	ret = arena->dma_base + dma_ofs * PAGE_SIZE;
 	ret += (unsigned long)cpu_addr & ~PAGE_MASK;
 
-	DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n",
+	DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n",
 	      cpu_addr, size, npages, ret, __builtin_return_address(0));
 
 	return ret;
@@ -355,14 +355,14 @@ pci_unmap_single(struct pci_dev *pdev, d
 	    && dma_addr < __direct_map_base + __direct_map_size) {
 		/* Nothing to do.  */
 
-		DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n",
+		DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n",
 		      dma_addr, size, __builtin_return_address(0));
 
 		return;
 	}
 
 	if (dma_addr > 0xffffffff) {
-		DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n",
+		DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n",
 		      dma_addr, size, __builtin_return_address(0));
 		return;
 	}
@@ -373,9 +373,9 @@ pci_unmap_single(struct pci_dev *pdev, d
 
 	dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT;
 	if (dma_ofs * PAGE_SIZE >= arena->size) {
-		printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx "
-		       " base %lx size %x\n", dma_addr, arena->dma_base,
-		       arena->size);
+		printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx "
+		       " base %llx size %x\n",
+		       dma_addr, arena->dma_base, arena->size);
 		return;
 		BUG();
 	}
@@ -394,7 +394,7 @@ pci_unmap_single(struct pci_dev *pdev, d
 
 	spin_unlock_irqrestore(&arena->lock, flags);
 
-	DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n",
+	DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
 	      dma_addr, size, npages, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(pci_unmap_single);
@@ -444,7 +444,7 @@ try_again:
 		goto try_again;
 	}
 		
-	DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
+	DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
 	      size, cpu_addr, *dma_addrp, __builtin_return_address(0));
 
 	return cpu_addr;
@@ -464,7 +464,7 @@ pci_free_consistent(struct pci_dev *pdev
 	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
 	free_pages((unsigned long)cpu_addr, get_order(size));
 
-	DBGA2("pci_free_consistent: [%x,%lx] from %p\n",
+	DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
 	      dma_addr, size, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(pci_free_consistent);
@@ -551,7 +551,7 @@ sg_fill(struct device *dev, struct scatt
 		out->dma_address = paddr + __direct_map_base;
 		out->dma_length = size;
 
-		DBGA("    sg_fill: [%p,%lx] -> direct %lx\n",
+		DBGA("    sg_fill: [%p,%lx] -> direct %llx\n",
 		     __va(paddr), size, out->dma_address);
 
 		return 0;
@@ -563,7 +563,7 @@ sg_fill(struct device *dev, struct scatt
 		out->dma_address = paddr + alpha_mv.pci_dac_offset;
 		out->dma_length = size;
 
-		DBGA("    sg_fill: [%p,%lx] -> DAC %lx\n",
+		DBGA("    sg_fill: [%p,%lx] -> DAC %llx\n",
 		     __va(paddr), size, out->dma_address);
 
 		return 0;
@@ -589,7 +589,7 @@ sg_fill(struct device *dev, struct scatt
 	out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
 	out->dma_length = size;
 
-	DBGA("    sg_fill: [%p,%lx] -> sg %lx np %ld\n",
+	DBGA("    sg_fill: [%p,%lx] -> sg %llx np %ld\n",
 	     __va(paddr), size, out->dma_address, npages);
 
 	/* All virtually contiguous.  We need to find the length of each
@@ -752,7 +752,7 @@ pci_unmap_sg(struct pci_dev *pdev, struc
 
 		if (addr > 0xffffffff) {
 			/* It's a DAC address -- nothing to do.  */
-			DBGA("    (%ld) DAC [%lx,%lx]\n",
+			DBGA("    (%ld) DAC [%llx,%zx]\n",
 			      sg - end + nents, addr, size);
 			continue;
 		}
@@ -760,12 +760,12 @@ pci_unmap_sg(struct pci_dev *pdev, struc
 		if (addr >= __direct_map_base
 		    && addr < __direct_map_base + __direct_map_size) {
 			/* Nothing to do.  */
-			DBGA("    (%ld) direct [%lx,%lx]\n",
+			DBGA("    (%ld) direct [%llx,%zx]\n",
 			      sg - end + nents, addr, size);
 			continue;
 		}
 
-		DBGA("    (%ld) sg [%lx,%lx]\n",
+		DBGA("    (%ld) sg [%llx,%zx]\n",
 		     sg - end + nents, addr, size);
 
 		npages = iommu_num_pages(addr, size, PAGE_SIZE);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci-sysfs.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci-sysfs.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/pci-sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/pci-sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,366 @@
+/*
+ * arch/alpha/kernel/pci-sysfs.c
+ *
+ * Copyright (C) 2009 Ivan Kokshaysky
+ *
+ * Alpha PCI resource files.
+ *
+ * Loosely based on generic HAVE_PCI_MMAP implementation in
+ * drivers/pci/pci-sysfs.c
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+
+static int hose_mmap_page_range(struct pci_controller *hose,
+				struct vm_area_struct *vma,
+				enum pci_mmap_state mmap_type, int sparse)
+{
+	unsigned long base;
+
+	if (mmap_type == pci_mmap_mem)
+		base = sparse ? hose->sparse_mem_base : hose->dense_mem_base;
+	else
+		base = sparse ? hose->sparse_io_base : hose->dense_io_base;
+
+	vma->vm_pgoff += base >> PAGE_SHIFT;
+	vma->vm_flags |= (VM_IO | VM_RESERVED);
+
+	return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+				  vma->vm_end - vma->vm_start,
+				  vma->vm_page_prot);
+}
+
+static int __pci_mmap_fits(struct pci_dev *pdev, int num,
+			   struct vm_area_struct *vma, int sparse)
+{
+	unsigned long nr, start, size;
+	int shift = sparse ? 5 : 0;
+
+	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	start = vma->vm_pgoff;
+	size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
+
+	if (start < size && size - start >= nr)
+		return 1;
+	WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d "
+		"(size 0x%08lx)\n",
+		current->comm, sparse ? " sparse" : "", start, start + nr,
+		pci_name(pdev), num, size);
+	return 0;
+}
+
+/**
+ * pci_mmap_resource - map a PCI resource into user memory space
+ * @kobj: kobject for mapping
+ * @attr: struct bin_attribute for the file being mapped
+ * @vma: struct vm_area_struct passed into the mmap
+ * @sparse: address space type
+ *
+ * Use the bus mapping routines to map a PCI resource into userspace.
+ */
+static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
+			     struct vm_area_struct *vma, int sparse)
+{
+	struct pci_dev *pdev = to_pci_dev(container_of(kobj,
+						       struct device, kobj));
+	struct resource *res = (struct resource *)attr->private;
+	enum pci_mmap_state mmap_type;
+	struct pci_bus_region bar;
+	int i;
+
+	for (i = 0; i < PCI_ROM_RESOURCE; i++)
+		if (res == &pdev->resource[i])
+			break;
+	if (i >= PCI_ROM_RESOURCE)
+		return -ENODEV;
+
+	if (!__pci_mmap_fits(pdev, i, vma, sparse))
+		return -EINVAL;
+
+	if (iomem_is_exclusive(res->start))
+		return -EINVAL;
+
+	pcibios_resource_to_bus(pdev, &bar, res);
+	vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0));
+	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
+
+	return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse);
+}
+
+static int pci_mmap_resource_sparse(struct kobject *kobj,
+				    struct bin_attribute *attr,
+				    struct vm_area_struct *vma)
+{
+	return pci_mmap_resource(kobj, attr, vma, 1);
+}
+
+static int pci_mmap_resource_dense(struct kobject *kobj,
+				   struct bin_attribute *attr,
+				   struct vm_area_struct *vma)
+{
+	return pci_mmap_resource(kobj, attr, vma, 0);
+}
+
+/**
+ * pci_remove_resource_files - cleanup resource files
+ * @dev: dev to cleanup
+ *
+ * If we created resource files for @dev, remove them from sysfs and
+ * free their resources.
+ */
+void pci_remove_resource_files(struct pci_dev *pdev)
+{
+	int i;
+
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+		struct bin_attribute *res_attr;
+
+		res_attr = pdev->res_attr[i];
+		if (res_attr) {
+			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+			kfree(res_attr);
+		}
+
+		res_attr = pdev->res_attr_wc[i];
+		if (res_attr) {
+			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+			kfree(res_attr);
+		}
+	}
+}
+
+static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
+{
+	struct pci_bus_region bar;
+	struct pci_controller *hose = pdev->sysdata;
+	long dense_offset;
+	unsigned long sparse_size;
+
+	pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]);
+
+	/* All core logic chips have 4G sparse address space, except
+	   CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
+	   definitions in asm/core_xxx.h files). This corresponds
+	   to 128M or 512M of the bus space. */
+	dense_offset = (long)(hose->dense_mem_base - hose->sparse_mem_base);
+	sparse_size = dense_offset >= 0x400000000UL ? 0x20000000 : 0x8000000;
+
+	return bar.end < sparse_size;
+}
+
+static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
+			       char *suffix, struct bin_attribute *res_attr,
+			       unsigned long sparse)
+{
+	size_t size = pci_resource_len(pdev, num);
+
+	sprintf(name, "resource%d%s", num, suffix);
+	res_attr->mmap = sparse ? pci_mmap_resource_sparse :
+				  pci_mmap_resource_dense;
+	res_attr->attr.name = name;
+	res_attr->attr.mode = S_IRUSR | S_IWUSR;
+	res_attr->size = sparse ? size << 5 : size;
+	res_attr->private = &pdev->resource[num];
+	return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+}
+
+static int pci_create_attr(struct pci_dev *pdev, int num)
+{
+	/* allocate attribute structure, piggyback attribute name */
+	int retval, nlen1, nlen2 = 0, res_count = 1;
+	unsigned long sparse_base, dense_base;
+	struct bin_attribute *attr;
+	struct pci_controller *hose = pdev->sysdata;
+	char *suffix, *attr_name;
+
+	suffix = "";	/* Assume bwx machine, normal resourceN files. */
+	nlen1 = 10;
+
+	if (pdev->resource[num].flags & IORESOURCE_MEM) {
+		sparse_base = hose->sparse_mem_base;
+		dense_base = hose->dense_mem_base;
+		if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
+			sparse_base = 0;
+			suffix = "_dense";
+			nlen1 = 16;	/* resourceN_dense */
+		}
+	} else {
+		sparse_base = hose->sparse_io_base;
+		dense_base = hose->dense_io_base;
+	}
+
+	if (sparse_base) {
+		suffix = "_sparse";
+		nlen1 = 17;
+		if (dense_base) {
+			nlen2 = 16;	/* resourceN_dense */
+			res_count = 2;
+		}
+	}
+
+	attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC);
+	if (!attr)
+		return -ENOMEM;
+
+	/* Create bwx, sparse or single dense file */
+	attr_name = (char *)(attr + res_count);
+	pdev->res_attr[num] = attr;
+	retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr,
+				     sparse_base);
+	if (retval || res_count == 1)
+		return retval;
+
+	/* Create dense file */
+	attr_name += nlen1;
+	attr++;
+	pdev->res_attr_wc[num] = attr;
+	return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0);
+}
+
+/**
+ * pci_create_resource_files - create resource files in sysfs for @dev
+ * @dev: dev in question
+ *
+ * Walk the resources in @dev creating files for each resource available.
+ */
+int pci_create_resource_files(struct pci_dev *pdev)
+{
+	int i;
+	int retval;
+
+	/* Expose the PCI resources from this device as files */
+	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+
+		/* skip empty resources */
+		if (!pci_resource_len(pdev, i))
+			continue;
+
+		retval = pci_create_attr(pdev, i);
+		if (retval) {
+			pci_remove_resource_files(pdev);
+			return retval;
+		}
+	}
+	return 0;
+}
+
+/* Legacy I/O bus mapping stuff. */
+
+static int __legacy_mmap_fits(struct pci_controller *hose,
+			      struct vm_area_struct *vma,
+			      unsigned long res_size, int sparse)
+{
+	unsigned long nr, start, size;
+
+	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	start = vma->vm_pgoff;
+	size = ((res_size - 1) >> PAGE_SHIFT) + 1;
+
+	if (start < size && size - start >= nr)
+		return 1;
+	WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on hose %d "
+		"(size 0x%08lx)\n",
+		current->comm, sparse ? " sparse" : "", start, start + nr,
+		hose->index, size);
+	return 0;
+}
+
+static inline int has_sparse(struct pci_controller *hose,
+			     enum pci_mmap_state mmap_type)
+{
+	unsigned long base;
+
+	base = (mmap_type == pci_mmap_mem) ? hose->sparse_mem_base :
+					     hose->sparse_io_base;
+
+	return base != 0;
+}
+
+int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
+			       enum pci_mmap_state mmap_type)
+{
+	struct pci_controller *hose = bus->sysdata;
+	int sparse = has_sparse(hose, mmap_type);
+	unsigned long res_size;
+
+	res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size :
+						 bus->legacy_io->size;
+	if (!__legacy_mmap_fits(hose, vma, res_size, sparse))
+		return -EINVAL;
+
+	return hose_mmap_page_range(hose, vma, mmap_type, sparse);
+}
+
+/**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Adjust file name and size for sparse mappings.
+ */
+void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	if (!has_sparse(hose, mmap_type))
+		return;
+
+	if (mmap_type == pci_mmap_mem) {
+		bus->legacy_mem->attr.name = "legacy_mem_sparse";
+		bus->legacy_mem->size <<= 5;
+	} else {
+		bus->legacy_io->attr.name = "legacy_io_sparse";
+		bus->legacy_io->size <<= 5;
+	}
+	return;
+}
+
+/* Legacy I/O bus read/write functions */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	port += hose->io_space->start;
+
+	switch(size) {
+	case 1:
+		*((u8 *)val) = inb(port);
+		return 1;
+	case 2:
+		if (port & 1)
+			return -EINVAL;
+		*((u16 *)val) = inw(port);
+		return 2;
+	case 4:
+		if (port & 3)
+			return -EINVAL;
+		*((u32 *)val) = inl(port);
+		return 4;
+	}
+	return -EINVAL;
+}
+
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	port += hose->io_space->start;
+
+	switch(size) {
+	case 1:
+		outb(port, val);
+		return 1;
+	case 2:
+		if (port & 1)
+			return -EINVAL;
+		outw(port, val);
+		return 2;
+	case 4:
+		if (port & 3)
+			return -EINVAL;
+		outl(port, val);
+		return 4;
+	}
+	return -EINVAL;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/process.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -272,7 +272,7 @@ alpha_vfork(struct pt_regs *regs)
  */
 
 int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
 	    unsigned long unused,
 	    struct task_struct * p, struct pt_regs * regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/proto.h linux-libre-2.6.30-gnu1/arch/alpha/kernel/proto.h
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/proto.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/proto.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@ struct pci_controller;
 extern struct pci_ops apecs_pci_ops;
 extern void apecs_init_arch(void);
 extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(u64, u64);
+extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_cia.c */
@@ -29,27 +29,26 @@ extern void cia_init_pci(void);
 extern void cia_init_arch(void);
 extern void pyxis_init_arch(void);
 extern void cia_kill_arch(int);
-extern void cia_machine_check(u64, u64);
+extern void cia_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_irongate.c */
 extern struct pci_ops irongate_pci_ops;
 extern int irongate_pci_clr_err(void);
 extern void irongate_init_arch(void);
-extern void irongate_machine_check(u64, u64);
 #define irongate_pci_tbi ((void *)0)
 
 /* core_lca.c */
 extern struct pci_ops lca_pci_ops;
 extern void lca_init_arch(void);
-extern void lca_machine_check(u64, u64);
+extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_marvel.c */
 extern struct pci_ops marvel_pci_ops;
 extern void marvel_init_arch(void);
 extern void marvel_kill_arch(int);
-extern void marvel_machine_check(u64, u64);
+extern void marvel_machine_check(unsigned long, unsigned long);
 extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern int marvel_pa_to_nid(unsigned long);
 extern int marvel_cpuid_to_nid(int);
@@ -64,7 +63,7 @@ void io7_clear_errors(struct io7 *io7);
 extern struct pci_ops mcpcia_pci_ops;
 extern void mcpcia_init_arch(void);
 extern void mcpcia_init_hoses(void);
-extern void mcpcia_machine_check(u64, u64);
+extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_polaris.c */
@@ -72,21 +71,21 @@ extern struct pci_ops polaris_pci_ops;
 extern int polaris_read_config_dword(struct pci_dev *, int, u32 *);
 extern int polaris_write_config_dword(struct pci_dev *, int, u32);
 extern void polaris_init_arch(void);
-extern void polaris_machine_check(u64, u64);
+extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr);
 #define polaris_pci_tbi ((void *)0)
 
 /* core_t2.c */
 extern struct pci_ops t2_pci_ops;
 extern void t2_init_arch(void);
 extern void t2_kill_arch(int);
-extern void t2_machine_check(u64, u64);
+extern void t2_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_titan.c */
 extern struct pci_ops titan_pci_ops;
 extern void titan_init_arch(void);
 extern void titan_kill_arch(int);
-extern void titan_machine_check(u64, u64);
+extern void titan_machine_check(unsigned long, unsigned long);
 extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern struct _alpha_agp_info *titan_agp_info(void);
 
@@ -94,14 +93,14 @@ extern struct _alpha_agp_info *titan_agp
 extern struct pci_ops tsunami_pci_ops;
 extern void tsunami_init_arch(void);
 extern void tsunami_kill_arch(int);
-extern void tsunami_machine_check(u64, u64);
+extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_wildfire.c */
 extern struct pci_ops wildfire_pci_ops;
 extern void wildfire_init_arch(void);
 extern void wildfire_kill_arch(int);
-extern void wildfire_machine_check(u64, u64);
+extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern int wildfire_pa_to_nid(unsigned long);
 extern int wildfire_cpuid_to_nid(int);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/setup.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -1255,7 +1255,7 @@ show_cpuinfo(struct seq_file *f, void *s
 		       platform_string(), nr_processors);
 
 #ifdef CONFIG_SMP
-	seq_printf(f, "cpus active\t\t: %d\n"
+	seq_printf(f, "cpus active\t\t: %u\n"
 		      "cpu active mask\t\t: %016lx\n",
 		       num_online_cpus(), cpus_addr(cpu_possible_map)[0]);
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/smc37c669.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/smc37c669.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/smc37c669.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/smc37c669.c	2009-06-09 23:05:27.000000000 -0400
@@ -2542,8 +2542,8 @@ void __init SMC669_Init ( int index )
         SMC37c669_display_device_info( );
 #endif
 	local_irq_restore(flags);
-        printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
-		(unsigned long) SMC_base );
+        printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
+		SMC_base );
     }
     else {
 	local_irq_restore(flags);
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/srm_env.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/srm_env.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/srm_env.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/srm_env.c	2009-06-09 23:05:27.000000000 -0400
@@ -218,7 +218,6 @@ srm_env_init(void)
 				BASE_DIR);
 		goto cleanup;
 	}
-	base_dir->owner = THIS_MODULE;
 
 	/*
 	 * Create per-name subdirectory
@@ -229,7 +228,6 @@ srm_env_init(void)
 				BASE_DIR, NAMED_DIR);
 		goto cleanup;
 	}
-	named_dir->owner = THIS_MODULE;
 
 	/*
 	 * Create per-number subdirectory
@@ -241,7 +239,6 @@ srm_env_init(void)
 		goto cleanup;
 
 	}
-	numbered_dir->owner = THIS_MODULE;
 
 	/*
 	 * Create all named nodes
@@ -254,7 +251,6 @@ srm_env_init(void)
 			goto cleanup;
 
 		entry->proc_entry->data		= (void *) entry;
-		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
 
@@ -275,7 +271,6 @@ srm_env_init(void)
 
 		entry->id			= var_num;
 		entry->proc_entry->data		= (void *) entry;
-		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/sys_jensen.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/sys_jensen.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/sys_jensen.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/sys_jensen.c	2009-06-09 23:05:27.000000000 -0400
@@ -244,12 +244,11 @@ jensen_init_arch(void)
 }
 
 static void
-jensen_machine_check (u64 vector, u64 la)
+jensen_machine_check(unsigned long vector, unsigned long la)
 {
 	printk(KERN_CRIT "Machine check\n");
 }
 
-
 /*
  * The System Vector
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/sys_sable.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/sys_sable.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/sys_sable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/sys_sable.c	2009-06-09 23:05:27.000000000 -0400
@@ -453,7 +453,7 @@ sable_lynx_enable_irq(unsigned int irq)
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
-	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
 	       __func__, mask, bit, irq);
 #endif
 }
@@ -469,7 +469,7 @@ sable_lynx_disable_irq(unsigned int irq)
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
-	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
 	       __func__, mask, bit, irq);
 #endif
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/traps.c linux-libre-2.6.30-gnu1/arch/alpha/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -623,7 +623,7 @@ do_entUna(void * va, unsigned long opcod
 	}
 
 	lock_kernel();
-	printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
+	printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
 		pc, va, opcode, reg);
 	do_exit(SIGSEGV);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/alpha/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/alpha/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ SECTIONS
 
 	_text = .;	/* Text and read-only data */
 	.text : {
-	*(.text.head)
+		HEAD_TEXT
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/mm/extable.c linux-libre-2.6.30-gnu1/arch/alpha/mm/extable.c
--- linux-libre-2.6.29-gnu1/arch/alpha/mm/extable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/mm/extable.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,11 +3,49 @@
  */
 
 #include <linux/module.h>
+#include <linux/sort.h>
 #include <asm/uaccess.h>
 
+static inline unsigned long ex_to_addr(const struct exception_table_entry *x)
+{
+	return (unsigned long)&x->insn + x->insn;
+}
+
+static void swap_ex(void *a, void *b, int size)
+{
+	struct exception_table_entry *ex_a = a, *ex_b = b;
+	unsigned long addr_a = ex_to_addr(ex_a), addr_b = ex_to_addr(ex_b);
+	unsigned int t = ex_a->fixup.unit;
+
+	ex_a->fixup.unit = ex_b->fixup.unit;
+	ex_b->fixup.unit = t;
+	ex_a->insn = (int)(addr_b - (unsigned long)&ex_a->insn);
+	ex_b->insn = (int)(addr_a - (unsigned long)&ex_b->insn);
+}
+
+/*
+ * The exception table needs to be sorted so that the binary
+ * search that we use to find entries in it works properly.
+ * This is used both for the kernel exception table and for
+ * the exception tables of modules that get loaded.
+ */
+static int cmp_ex(const void *a, const void *b)
+{
+	const struct exception_table_entry *x = a, *y = b;
+
+	/* avoid overflow */
+	if (ex_to_addr(x) > ex_to_addr(y))
+		return 1;
+	if (ex_to_addr(x) < ex_to_addr(y))
+		return -1;
+	return 0;
+}
+
 void sort_extable(struct exception_table_entry *start,
 		  struct exception_table_entry *finish)
 {
+	sort(start, finish - start, sizeof(struct exception_table_entry),
+	     cmp_ex, swap_ex);
 }
 
 const struct exception_table_entry *
@@ -20,7 +58,7 @@ search_extable(const struct exception_ta
 		unsigned long mid_value;
 
 		mid = (last - first) / 2 + first;
-		mid_value = (unsigned long)&mid->insn + mid->insn;
+		mid_value = ex_to_addr(mid);
                 if (mid_value == value)
                         return mid;
                 else if (mid_value < value)
diff -druNp linux-libre-2.6.29-gnu1/arch/alpha/mm/init.c linux-libre-2.6.30-gnu1/arch/alpha/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/alpha/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/alpha/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -189,9 +189,21 @@ callback_init(void * kernel_end)
 
 	if (alpha_using_srm) {
 		static struct vm_struct console_remap_vm;
-		unsigned long vaddr = VMALLOC_START;
+		unsigned long nr_pages = 0;
+		unsigned long vaddr;
 		unsigned long i, j;
 
+		/* calculate needed size */
+		for (i = 0; i < crb->map_entries; ++i)
+			nr_pages += crb->map[i].count;
+
+		/* register the vm area */
+		console_remap_vm.flags = VM_ALLOC;
+		console_remap_vm.size = nr_pages << PAGE_SHIFT;
+		vm_area_register_early(&console_remap_vm, PAGE_SIZE);
+
+		vaddr = (unsigned long)console_remap_vm.addr;
+
 		/* Set up the third level PTEs and update the virtual
 		   addresses of the CRB entries.  */
 		for (i = 0; i < crb->map_entries; ++i) {
@@ -213,12 +225,6 @@ callback_init(void * kernel_end)
 				vaddr += PAGE_SIZE;
 			}
 		}
-
-		/* Let vmalloc know that we've allocated some space.  */
-		console_remap_vm.flags = VM_ALLOC;
-		console_remap_vm.addr = (void *) VMALLOC_START;
-		console_remap_vm.size = vaddr - VMALLOC_START;
-		vmlist = &console_remap_vm;
 	}
 
 	callback_init_done = 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/head.S linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/head.S
--- linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,12 @@
 		.macro	writeb, ch, rb
 		mcr	p14, 0, \ch, c0, c5, 0
 		.endm
+#elif defined(CONFIG_CPU_XSCALE)
+		.macro	loadsp, rb
+		.endm
+		.macro	writeb, ch, rb
+		mcr	p14, 0, \ch, c8, c0, 0
+		.endm
 #else
 		.macro	loadsp, rb
 		.endm
@@ -459,6 +465,20 @@ __armv7_mmu_cache_on:
 		mcr	p15, 0, r0, c7, c5, 4	@ ISB
 		mov	pc, r12
 
+__fa526_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c7, 0	@ Invalidate whole cache
+		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
+		mcr	p15, 0, r0, c8, c7, 0	@ flush UTLB
+		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
+		orr	r0, r0, #0x1000		@ I-cache enable
+		bl	__common_mmu_cache_on
+		mov	r0, #0
+		mcr	p15, 0, r0, c8, c7, 0	@ flush UTLB
+		mov	pc, r12
+
 __arm6_mmu_cache_on:
 		mov	r12, lr
 		bl	__setup_mmu
@@ -630,12 +650,30 @@ proc_types:
 		b	__armv4_mmu_cache_off
 		b	__armv4_mmu_cache_flush
 
+		.word	0x56158000		@ PXA168
+		.word	0xfffff000
+		b __armv4_mmu_cache_on
+		b __armv4_mmu_cache_off
+		b __armv5tej_mmu_cache_flush
+
+		.word	0x56056930
+		.word	0xff0ffff0		@ PXA935
+		b	__armv4_mmu_cache_on
+		b	__armv4_mmu_cache_off
+		b	__armv4_mmu_cache_flush
+
 		.word	0x56050000		@ Feroceon
 		.word	0xff0f0000
 		b	__armv4_mmu_cache_on
 		b	__armv4_mmu_cache_off
 		b	__armv5tej_mmu_cache_flush
 
+		.word	0x66015261		@ FA526
+		.word	0xff01fff1
+		b	__fa526_cache_on
+		b	__armv4_mmu_cache_off
+		b	__fa526_cache_flush
+
 		@ These match on the architecture ID
 
 		.word	0x00020000		@ ARMv4T
@@ -775,6 +813,12 @@ __armv4_mpu_cache_flush:
 		mcr	p15, 0, ip, c7, c10, 4	@ drain WB
 		mov	pc, lr
 		
+__fa526_cache_flush:
+		mov	r1, #0
+		mcr	p15, 0, r1, c7, c14, 0	@ clean and invalidate D cache
+		mcr	p15, 0, r1, c7, c5, 0	@ flush I cache
+		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
+		mov	pc, lr
 
 __armv6_mmu_cache_flush:
 		mov	r1, #0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/misc.c linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/misc.c
--- linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/misc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/misc.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,10 @@
 
 unsigned int __machine_arch_type;
 
-#include <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>
 
 #ifdef STANDALONE_DEBUG
 #define putstr printf
@@ -46,6 +49,21 @@ static void icedcc_putc(int ch)
 
 	asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 }
+#elif defined(CONFIG_CPU_XSCALE)
+
+static void icedcc_putc(int ch)
+{
+	int status, i = 0x4000000;
+
+	do {
+		if (--i < 0)
+			return;
+
+		asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
+	} while (status & (1 << 28));
+
+	asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
+}
 
 #else
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/vmlinux.lds.in linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/vmlinux.lds.in
--- linux-libre-2.6.29-gnu1/arch/arm/boot/compressed/vmlinux.lds.in	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/boot/compressed/vmlinux.lds.in	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,11 @@ OUTPUT_ARCH(arm)
 ENTRY(_start)
 SECTIONS
 {
+  /DISCARD/ : {
+    *(.ARM.exidx*)
+    *(.ARM.extab*)
+  }
+
   . = TEXT_START;
   _text = .;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/clkdev.c linux-libre-2.6.30-gnu1/arch/arm/common/clkdev.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/clkdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/clkdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,9 +62,8 @@ static struct clk *clk_find(const char *
 	return clk;
 }
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 {
-	const char *dev_id = dev ? dev_name(dev) : NULL;
 	struct clk *clk;
 
 	mutex_lock(&clocks_mutex);
@@ -75,6 +74,14 @@ struct clk *clk_get(struct device *dev,
 
 	return clk ? clk : ERR_PTR(-ENOENT);
 }
+EXPORT_SYMBOL(clk_get_sys);
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+	const char *dev_id = dev ? dev_name(dev) : NULL;
+
+	return clk_get_sys(dev_id, con_id);
+}
 EXPORT_SYMBOL(clk_get);
 
 void clk_put(struct clk *clk)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/dmabounce.c linux-libre-2.6.30-gnu1/arch/arm/common/dmabounce.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/dmabounce.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/dmabounce.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/page-flags.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
@@ -349,6 +350,12 @@ dma_addr_t dma_map_page(struct device *d
 
 	BUG_ON(!valid_dma_direction(dir));
 
+	if (PageHighMem(page)) {
+		dev_err(dev, "DMA buffer bouncing of HIGHMEM pages "
+			     "is not supported\n");
+		return ~0;
+	}
+
 	return map_single(dev, page_address(page) + offset, size, dir);
 }
 EXPORT_SYMBOL(dma_map_page);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/gic.c linux-libre-2.6.30-gnu1/arch/arm/common/gic.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/gic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/gic.c	2009-06-09 23:05:27.000000000 -0400
@@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int
 }
 
 #ifdef CONFIG_SMP
-void gic_raise_softirq(cpumask_t cpumask, unsigned int irq)
+void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 {
-	unsigned long map = *cpus_addr(cpumask);
+	unsigned long map = *cpus_addr(*mask);
 
 	/* this always happens on GIC0 */
 	writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/scoop.c linux-libre-2.6.30-gnu1/arch/arm/common/scoop.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/scoop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/scoop.c	2009-06-09 23:05:27.000000000 -0400
@@ -124,37 +124,6 @@ static int scoop_gpio_direction_output(s
 	return 0;
 }
 
-unsigned short set_scoop_gpio(struct device *dev, unsigned short bit)
-{
-	unsigned short gpio_bit;
-	unsigned long flag;
-	struct scoop_dev *sdev = dev_get_drvdata(dev);
-
-	spin_lock_irqsave(&sdev->scoop_lock, flag);
-	gpio_bit = ioread16(sdev->base + SCOOP_GPWR) | bit;
-	iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
-	spin_unlock_irqrestore(&sdev->scoop_lock, flag);
-
-	return gpio_bit;
-}
-
-unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit)
-{
-	unsigned short gpio_bit;
-	unsigned long flag;
-	struct scoop_dev *sdev = dev_get_drvdata(dev);
-
-	spin_lock_irqsave(&sdev->scoop_lock, flag);
-	gpio_bit = ioread16(sdev->base + SCOOP_GPWR) & ~bit;
-	iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
-	spin_unlock_irqrestore(&sdev->scoop_lock, flag);
-
-	return gpio_bit;
-}
-
-EXPORT_SYMBOL(set_scoop_gpio);
-EXPORT_SYMBOL(reset_scoop_gpio);
-
 unsigned short read_scoop_reg(struct device *dev, unsigned short reg)
 {
 	struct scoop_dev *sdev = dev_get_drvdata(dev);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/sharpsl_pm.c linux-libre-2.6.30-gnu1/arch/arm/common/sharpsl_pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/sharpsl_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/sharpsl_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,8 +29,8 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <mach/pm.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
+#include <mach/regs-rtc.h>
 #include <mach/sharpsl.h>
 #include <asm/hardware/sharpsl_pm.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/common/vic.c linux-libre-2.6.30-gnu1/arch/arm/common/vic.c
--- linux-libre-2.6.29-gnu1/arch/arm/common/vic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/common/vic.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,12 +85,11 @@ void __init vic_init(void __iomem *base,
 	writel(32, base + VIC_PL190_DEF_VECT_ADDR);
 
 	for (i = 0; i < 32; i++) {
-		unsigned int irq = irq_start + i;
-
-		set_irq_chip(irq, &vic_chip);
-		set_irq_chip_data(irq, base);
-
 		if (vic_sources & (1 << i)) {
+			unsigned int irq = irq_start + i;
+
+			set_irq_chip(irq, &vic_chip);
+			set_irq_chip_data(irq, base);
 			set_irq_handler(irq, handle_level_irq);
 			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/acs5k_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/acs5k_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/acs5k_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/acs5k_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1233 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-simtec-micrel1
+# Tue Dec 16 13:31:34 2008
+#
+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_ARCH_SUPPORTS_AOUT=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_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_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT 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_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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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_VM_EVENT_COUNTERS=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_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# 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 is not set
+CONFIG_PROC_PAGE_MONITOR=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 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_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
+
+#
+# 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_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX 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=y
+# 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_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Kendin/Micrel KS8695 Implementations
+#
+CONFIG_MACH_KS8695=y
+CONFIG_MACH_DSM320=y
+CONFIG_MACH_ACS5K=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM922T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=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 is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE 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=y
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_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_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_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC 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
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=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 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_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
+# CONFIG_NET_SCHED 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=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 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=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=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 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_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 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_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# 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_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
+
+#
+# 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 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_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_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_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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_ARM_KS8695_ETHER=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_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_NET_PCI is not set
+# CONFIG_B44 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=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_PRISM54=m
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_NET_PCMCIA 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_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# 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=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=y
+# 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_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM 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_ACS5KCAN=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=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=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
+
+#
+# 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_AT24 is not set
+# CONFIG_SENSORS_EEPROM 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 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# 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_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_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB 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_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_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_KS8695_WATCHDOG=y
+# CONFIG_ALIM7101_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# 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_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
+
+#
+# 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_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_HID_DEBUG=y
+# CONFIG_HIDRAW 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
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC 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
+
+#
+# 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=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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO 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_EXT4DEV_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_OCFS2_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 is not set
+# CONFIG_FUSE_FS 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_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_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=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=y
+# 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 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_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_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_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_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+# 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_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER 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_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X 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_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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/acs5k_tiny_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/acs5k_tiny_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/acs5k_tiny_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/acs5k_tiny_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,941 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-simtec-micrel1
+# Tue Jan  6 13:23:07 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_ARCH_SUPPORTS_AOUT=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_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_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT 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_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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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_VM_EVENT_COUNTERS=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_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# 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 is not set
+CONFIG_PROC_PAGE_MONITOR=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 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_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
+
+#
+# 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_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX 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=y
+# 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_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Kendin/Micrel KS8695 Implementations
+#
+# CONFIG_MACH_KS8695 is not set
+# CONFIG_MACH_DSM320 is not set
+CONFIG_MACH_ACS5K=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM922T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=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 is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_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_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_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 init=/bin/sh"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC 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_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_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_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_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
+# CONFIG_NET_SCHED 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_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=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=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 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_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 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_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV 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_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_ARM_KS8695_ETHER=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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_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=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP 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
+
+#
+# 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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_ACS5KCAN=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=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_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_AT24 is not set
+# CONFIG_SENSORS_EEPROM 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 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# 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_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_KS8695_WATCHDOG=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_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
+
+#
+# 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 is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC 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
+
+#
+# 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=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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS 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 is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_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 is not set
+# CONFIG_FUSE_FS 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_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_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=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 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 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_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_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_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_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+# 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_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO 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_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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/assabet_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/assabet_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/assabet_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/assabet_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -89,7 +89,6 @@ CONFIG_SA1100_ASSABET=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/badge4_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/badge4_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/badge4_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/badge4_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -91,7 +91,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 CONFIG_SA1100_BADGE4=y
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/cerfcube_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/cerfcube_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/cerfcube_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/cerfcube_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -93,7 +93,6 @@ CONFIG_SA1100_CERF_FLASH_16MB=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/cm_x2xx_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/cm_x2xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/cm_x2xx_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/cm_x2xx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1962 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc2
+# Sun Feb  1 16:31:36 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_ARCH_MTD_XIP=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_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 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_SLUB_DEBUG is not set
+# 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
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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_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_FREEZER=y
+
+#
+# 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_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=y
+# 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 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 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_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_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_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=y
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA25x=y
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+# CONFIG_PXA_PWM is not set
+
+#
+# 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_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_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+CONFIG_DMABOUNCE=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_HOST_ITE8152=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_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+# CONFIG_YENTA_O2 is not set
+# CONFIG_YENTA_RICOH is not set
+CONFIG_YENTA_TI=y
+# CONFIG_YENTA_ENE_TUNE is not set
+# CONFIG_YENTA_TOSHIBA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_PCCARD_NONSTATIC=m
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# 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 is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+# 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
+
+#
+# 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=m
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+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 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_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_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 is not set
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# 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_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_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=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+# CONFIG_MAC80211 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=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_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
+# 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 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_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+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
+# 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_COMPAT is not set
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_SHARP_SL 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 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_H1900 is not set
+CONFIG_MTD_NAND_GPIO=m
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_CAFE is not set
+CONFIG_MTD_NAND_CM_X270=y
+# 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
+# CONFIG_MTD_QINFO_PROBE 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=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH 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
+
+#
+# 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_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 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_HPTIOP is not set
+# CONFIG_LIBFC 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
+# 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_IPR 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
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+# 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_PCMCIA=m
+# 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
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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=y
+CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X 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=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH 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=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# 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_VIA_RHINE is not set
+# CONFIG_SC92031 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
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+# CONFIG_LIBERTAS_CS is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_HERMES 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_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 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
+# 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 is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+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 is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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
+
+#
+# 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
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_PXA27x=m
+# CONFIG_KEYBOARD_GPIO 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_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_UCB1400=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_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=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 is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+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_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM 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_CHARDEV=m
+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_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
+
+#
+# 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_AT24 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
+# 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=m
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 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
+
+#
+# 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 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_UCB1400_CORE=m
+# 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=m
+CONFIG_VIDEO_V4L2_COMMON=m
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+CONFIG_MEDIA_TUNER_CUSTOMIZE=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_VIDEO_V4L2=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=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 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
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 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
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_IVTV is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+CONFIG_SOC_CAMERA=m
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=m
+# 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=m
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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_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_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_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+# 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_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE 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=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+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_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_VMASTER=y
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI 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 is not set
+# CONFIG_SND_PCMCIA 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_HID_DEBUG=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_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_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_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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 is not set
+# CONFIG_USB_SUSPEND 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_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_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
+# 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 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_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_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 is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_UWB is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+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_PXA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_SDRICOH_CS is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=m
+# CONFIG_LEDS_PCA955X 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_DEFAULT_ON 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
+
+#
+# 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_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=y
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES 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_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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 is not set
+# CONFIG_FUSE_FS 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 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_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 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 is not set
+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
+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=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 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=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=0
+# 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=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# 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_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 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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# 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_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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1481 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc3
-# Mon Dec  3 13:36:09 2007
-#
-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_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_ARCH_MTD_XIP=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=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-# 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=y
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-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_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
-# CONFIG_BLK_DEV_BSG 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"
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_PNX4008 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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
-
-#
-# Intel PXA2xx/PXA3xx Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_MACH_LOGICPD_PXA270 is not set
-# CONFIG_MACH_MAINSTONE is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_PXA_SHARPSL is not set
-# CONFIG_MACH_TRIZEPS4 is not set
-# CONFIG_MACH_EM_X270 is not set
-CONFIG_MACH_COLIBRI=y
-# CONFIG_MACH_ZYLONITE is not set
-# CONFIG_MACH_ARMCORE is not set
-CONFIG_PXA27x=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=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_OUTER_CACHE is not set
-CONFIG_IWMMXT=y
-CONFIG_XSCALE_PMU=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 is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_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_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC 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_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_UP_POSSIBLE=y
-CONFIG_SUSPEND=y
-# CONFIG_APM_EMULATION is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE 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 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 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_IP_VS 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=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_QUEUE=m
-# 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_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-CONFIG_VLAN_8021Q=m
-# 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_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-# CONFIG_KINGSUN_DONGLE is not set
-# CONFIG_KSDAZZLE_DONGLE is not set
-# CONFIG_KS959_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_SIGMATEL_FIR is not set
-# CONFIG_PXA_FICP is not set
-# CONFIG_MCS_FIR 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_HCIUSB is not set
-# CONFIG_BT_HCIBTUSB is not set
-# 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_AF_RXRPC is not set
-
-#
-# Wireless
-#
-CONFIG_CFG80211=y
-CONFIG_NL80211=y
-CONFIG_WIRELESS_EXT=y
-# CONFIG_MAC80211 is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG 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_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_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
-
-#
-# 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 is not set
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_LE_BYTE_SWAP=y
-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=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_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 is not set
-# 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_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-CONFIG_MTD_PXA2XX=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_SHARP_SL 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=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 is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=y
-CONFIG_MTD_NAND_DISKONCHIP=y
-CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
-CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
-CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
-CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
-# CONFIG_MTD_NAND_SHARPSL 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 is not set
-# CONFIG_MTD_ONENAND_GENERIC is not set
-# CONFIG_MTD_ONENAND_OTP is not set
-# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
-# CONFIG_MTD_ONENAND_SIM 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=m
-CONFIG_BLK_DEV_NBD=y
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=8
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=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=y
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-CONFIG_IDE_ARCH_OBSOLETE_INIT=y
-# CONFIG_BLK_DEV_HD 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_NETDEVICES_MULTIQUEUE 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_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_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=y
-# CONFIG_SMC911X 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_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=y
-# CONFIG_LIBERTAS is not set
-# CONFIG_USB_ZD1201 is not set
-CONFIG_HOSTAP=y
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-# CONFIG_ZD1211RW 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_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
-# 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=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
-# 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=m
-# CONFIG_KEYBOARD_SUNKBD is not set
-# 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_PXA27x is not set
-# CONFIG_KEYBOARD_GPIO is not set
-CONFIG_INPUT_MOUSE=y
-# CONFIG_MOUSE_PS2 is not set
-CONFIG_MOUSE_SERIAL=m
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_MTOUCH 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=y
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE 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_UINPUT=m
-
-#
-# 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_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM 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
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_PXA is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB 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_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 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
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER 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_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_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB 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_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_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
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_UVESA is not set
-# CONFIG_FB_S1D13XXX is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_PXA_PARAMETERS is not set
-# CONFIG_FB_MBX is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI 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=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
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-CONFIG_AC97_BUS=y
-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
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE 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
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_PERSIST is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_ISP116X_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
-
-#
-# 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_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MON is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_AIRPRIME 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_CP2101 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_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_NAVMAN is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_OTI6858 is not set
-# CONFIG_USB_SERIAL_HP4X is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-# CONFIG_USB_SERIAL_SIERRAWIRELESS 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_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_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_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=m
-# 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_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC 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_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_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
-CONFIG_USB_GADGET_DUMMY_HCD=y
-CONFIG_USB_DUMMY_HCD=m
-CONFIG_USB_GADGET_DUALSPEED=y
-# 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_MMC=y
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
-
-#
-# MMC/SD Card Drivers
-#
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_BOUNCE=y
-# CONFIG_SDIO_UART is not set
-
-#
-# MMC/SD Host Controller Drivers
-#
-# CONFIG_MMC_PXA is not set
-CONFIG_NEW_LEDS=y
-# CONFIG_LEDS_CLASS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-# 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=m
-# CONFIG_RTC_DRV_M41T80 is not set
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS 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_M48T86 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_RTC_DRV_SA1100 is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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=y
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
-# CONFIG_FUSE_FS 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=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=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_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=1
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_FS_WBUF_VERIFY=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_LZO is not set
-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
-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_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-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
-# 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-15"
-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=y
-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
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_PRINTK_TIME=y
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-# 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_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB 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 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_LIST is not set
-# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_SAMPLES is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITY=y
-# CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_MANAGER=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=y
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-CONFIG_CRYPTO_HW=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-# 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_REED_SOLOMON=y
-CONFIG_REED_SOLOMON_DEC16=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_pxa270_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_pxa270_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_pxa270_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_pxa270_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1737 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 16:18:17 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_ARCH_MTD_XIP=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=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=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_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=y
+CONFIG_INITRAMFS_SOURCE=""
+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=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
+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
+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=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE 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=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_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_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=y
+# 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 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 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_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_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_EM_X270 is not set
+CONFIG_MACH_COLIBRI=y
+# CONFIG_MACH_COLIBRI300 is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_RAUMFELD_PROTO 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_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA27x=y
+# CONFIG_PXA_PWM is not set
+
+#
+# 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_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_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+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 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=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+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
+
+#
+# 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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# 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 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 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=m
+# 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_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP 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_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_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_PXA_FICP is not set
+# CONFIG_MCS_FIR 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 is not set
+# 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_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=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_MAC80211 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=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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 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=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+# CONFIG_MTD_CFI_NOSWAP is not set
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+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=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_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 is not set
+# 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_SHARP_SL 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=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 is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+# CONFIG_MTD_NAND_SHARPSL 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 is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+# 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 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=y
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+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_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_93CX6 is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+# 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 is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEDMA 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=y
+# CONFIG_AX88796 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_SMC911X is not set
+# CONFIG_SMSC911X 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=y
+# CONFIG_LIBERTAS 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=y
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+
+#
+# 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
+
+#
+# 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=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# 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=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_PXA27x is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+# 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_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_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 is not set
+
+#
+# Non-8250 serial port support
+#
+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=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=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_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=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_PXA 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 is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# 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 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 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# 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_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_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_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_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_SA1100_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 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=y
+# CONFIG_USB_DABUSB 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 is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# 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_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM 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_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 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_COMPAT=y
+# CONFIG_HID_APPLE 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 is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_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
+# 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 depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# 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_CP2101 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_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_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_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=m
+# 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_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=y
+CONFIG_USB_DUMMY_HCD=m
+CONFIG_USB_GADGET_DUALSPEED=y
+# 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
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS 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_PXA is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# 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=m
+# 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
+#
+
+#
+# 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 is not set
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES 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_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=y
+# CONFIG_FUSE_FS 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=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+# 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=y
+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=1
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=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_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=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+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
+# 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-15"
+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=y
+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=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# 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=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_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 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 is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS 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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=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_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# 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=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
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# 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=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# 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=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=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=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_pxa300_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_pxa300_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/colibri_pxa300_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/colibri_pxa300_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1156 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 16:13:20 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_ARCH_MTD_XIP=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_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# 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=17
+# 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_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
+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
+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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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_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_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=y
+# 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 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Supported PXA3xx Processor Variants
+#
+CONFIG_CPU_PXA300=y
+# CONFIG_CPU_PXA310 is not set
+# CONFIG_CPU_PXA320 is not set
+# CONFIG_CPU_PXA930 is not set
+# CONFIG_CPU_PXA935 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 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_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_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+CONFIG_MACH_COLIBRI300=y
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_RAUMFELD_PROTO 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_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA3xx=y
+# CONFIG_PXA_PWM is not set
+
+#
+# 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_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_IO_36=y
+
+#
+# Processor Features
+#
+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_IWMMXT=y
+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 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 is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+
+#
+# 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 is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+# 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=y
+# 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_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=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 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=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 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_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_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
+
+#
+# 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 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_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_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=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
+# 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_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH 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=y
+# CONFIG_AX88796_93CX6 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X 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
+# CONFIG_IWLWIFI_LEDS 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
+
+#
+# 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 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=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=y
+
+#
+# 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 is not set
+
+#
+# Non-8250 serial port support
+#
+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=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# 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_DEBUG_GPIO=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_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_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=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_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# 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_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC 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 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 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_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_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 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_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_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 is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS 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_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_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=y
+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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 is not set
+# CONFIG_FUSE_FS 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 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_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
+# 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=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 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_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_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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# 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_FIPS is not set
+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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# 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=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
+
+#
+# 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=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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/collie_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/collie_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/collie_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/collie_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,6 @@ CONFIG_ARCH_SA1100=y
 CONFIG_SA1100_COLLIE=y
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/davinci_all_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/davinci_all_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/davinci_all_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/davinci_all_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1784 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc2
+# Wed Apr 15 08:16:53 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
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+CONFIG_ARCH_DAVINCI_DM644x=y
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_DAVINCI_EVM=y
+CONFIG_DAVINCI_MUX=y
+CONFIG_DAVINCI_MUX_DEBUG=y
+CONFIG_DAVINCI_MUX_WARNINGS=y
+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_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=m
+# 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_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# 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=m
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=m
+# 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=m
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=m
+# 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=m
+# 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=m
+# 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_IDS=m
+# 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_NAND_DAVINCI=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
+# 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_UB 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=m
+
+#
+# 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=m
+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 is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+CONFIG_BLK_DEV_PALMCHIP_BK3710=m
+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 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_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
+#
+
+#
+# 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=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 is not set
+# 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=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_USB_COMPOSITE 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
+# 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_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=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 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_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_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_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_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_DAVINCI_WATCHDOG=m
+
+#
+# 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 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=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=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+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_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+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_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_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_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_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=m
+# CONFIG_SND_DAVINCI_SOC 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=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID 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
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KYE is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_KENSINGTON is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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=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_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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_SOC=y
+
+#
+# DaVinci 35x and 644x USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_MUSB_PIO_ONLY=y
+# 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_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 is not set
+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_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_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+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=m
+
+#
+# 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=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+# 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_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY 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_LP5521 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# 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=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 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
+
+#
+# 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_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_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 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=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_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.29-gnu1/arch/arm/configs/em_x270_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/em_x270_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/em_x270_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/em_x270_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1741 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc2
+# Sun Feb  1 16:43:31 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_ARCH_MTD_XIP=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_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 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# 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
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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_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_FREEZER=y
+
+#
+# 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_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=y
+# 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 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 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_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_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
+CONFIG_MACH_EM_X270=y
+CONFIG_MACH_EXEDA=y
+# CONFIG_MACH_COLIBRI 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_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+# CONFIG_PXA_PWM is not set
+
+#
+# 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_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_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+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 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 is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+# 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 is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# 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
+
+#
+# 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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+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 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_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_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 is not set
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+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_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=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+# CONFIG_MAC80211 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=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_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
+# 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 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_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+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
+# 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_COMPAT is not set
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_SHARP_SL 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
+# 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_H1900 is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL 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
+# CONFIG_MTD_QINFO_PROBE 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=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH 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
+
+#
+# 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_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 is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X 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=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# 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
+# 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=y
+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 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
+
+#
+# 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
+CONFIG_INPUT_APMPOWER=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_PXA27x=y
+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_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_DA9034 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_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_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT 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 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+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=16
+# 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=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_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_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# 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=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_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 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_W1 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_BQ27x00 is not set
+CONFIG_BATTERY_DA9030=y
+# 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_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=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 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+CONFIG_MEDIA_TUNER_CUSTOMIZE=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_VIDEO_V4L2=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=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 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
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 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
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=m
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=m
+# 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=m
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB 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_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+# CONFIG_FB_MBX_DEBUG 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_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# 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
+#
+# 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=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+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_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_VMASTER=y
+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_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
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# 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_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_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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 is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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_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
+
+#
+# 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 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_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_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 is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+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_PXA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY 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_PCA955X is not set
+CONFIG_LEDS_DA903X=y
+
+#
+# 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_DEFAULT_ON 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
+
+#
+# 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_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=y
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES 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_BQ24022 is not set
+CONFIG_REGULATOR_DA903X=y
+# 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_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 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 is not set
+# CONFIG_FUSE_FS 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 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_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 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 is not set
+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
+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=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 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=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=0
+# 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 is not set
+# 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_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 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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# 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_FIPS is not set
+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_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# 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=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
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C 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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/h3600_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/h3600_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/h3600_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/h3600_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 CONFIG_SA1100_H3600=y
-# CONFIG_SA1100_H3800 is not set
 CONFIG_SA1100_H3XXX=y
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
@@ -100,7 +99,6 @@ CONFIG_SA1100_H3XXX=y
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SIMPAD is not set
 # CONFIG_SA1100_SSP is not set
-# CONFIG_H3600_SLEEVE is not set
 
 #
 # Processor Type
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/hackkit_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/hackkit_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/hackkit_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/hackkit_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -91,7 +91,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 CONFIG_SA1100_HACKKIT=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/imx27ads_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/imx27ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/imx27ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/imx27ads_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,826 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Fri Jun 20 16:29:34 2008
-#
-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_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=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_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT 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_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_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_KALLSYMS=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_VM_EVENT_COUNTERS=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
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=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 is not set
-# CONFIG_KMOD is not set
-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
-
-#
-# 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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-CONFIG_ARCH_MX2=y
-# CONFIG_ARCH_MX3 is not set
-
-#
-# MX2 family CPU support
-#
-CONFIG_MACH_MX27=y
-
-#
-# MX2 Platforms
-#
-CONFIG_MACH_MX27ADS=y
-# CONFIG_MACH_PCM038 is not set
-
-#
-# 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
-
-#
-# 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_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_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_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_VIRT_TO_BUS=y
-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
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# 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 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 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_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
-# CONFIG_NET_SCHED 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_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_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_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=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 is not set
-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 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
-# 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=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# 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
-
-#
-# 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_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 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_NETDEVICES_MULTIQUEUE 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_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 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_B44 is not set
-# CONFIG_FEC_OLD 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_IWLWIFI_LEDS 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
-
-#
-# 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_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_MTOUCH 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_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=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_IMX is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS 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
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO 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
-
-#
-# 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
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_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
-
-#
-# 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_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_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_VXFS_FS is not set
-# CONFIG_MINIX_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_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=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 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=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=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=m
-# 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 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 is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO 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_CRC_CCITT is not set
-# CONFIG_CRC16 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/jornada720_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/jornada720_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/jornada720_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/jornada720_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -178,7 +178,6 @@ CONFIG_DMABOUNCE=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 CONFIG_SA1100_JORNADA720=y
 CONFIG_SA1100_JORNADA720_SSP=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/kirkwood_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/kirkwood_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/kirkwood_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/kirkwood_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Thu Dec  4 15:27:39 2008
+# Linux kernel version: 2.6.30-rc4
+# Mon May  4 11:58:57 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
@@ -42,10 +42,19 @@ CONFIG_SYSVIPC_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 is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
+CONFIG_LOG_BUF_SHIFT=19
 # 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
@@ -53,23 +62,24 @@ CONFIG_NAMESPACES=y
 # 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_STRIP_ASM_SYMS is not set
 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
@@ -79,10 +89,12 @@ CONFIG_AIO=y
 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=y
+CONFIG_TRACEPOINTS=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
@@ -90,10 +102,10 @@ CONFIG_KPROBES=y
 CONFIG_KRETPROBES=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_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -101,11 +113,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
 
@@ -121,7 +130,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 is not set
 
 #
@@ -132,10 +140,10 @@ CONFIG_CLASSIC_RCU=y
 # 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_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
@@ -156,14 +164,17 @@ CONFIG_ARCH_KIRKWOOD=y
 # 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 is not set
 
 #
 # Marvell Kirkwood Implementations
@@ -171,14 +182,8 @@ CONFIG_ARCH_KIRKWOOD=y
 CONFIG_MACH_DB88F6281_BP=y
 CONFIG_MACH_RD88F6192_NAS=y
 CONFIG_MACH_RD88F6281=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_MACH_SHEEVAPLUG=y
+CONFIG_MACH_TS219=y
 CONFIG_PLAT_ORION=y
 
 #
@@ -214,6 +219,8 @@ 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
 
 #
@@ -234,6 +241,7 @@ CONFIG_AEABI=y
 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
@@ -242,11 +250,12 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
 # 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
 
 #
@@ -321,7 +330,7 @@ CONFIG_IP_PNP_BOOTP=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_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -354,26 +363,43 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
 # 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=m
 # 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=y
-# CONFIG_CFG80211 is not set
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+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
 
@@ -398,6 +424,7 @@ 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_AFS_PARTS is not set
@@ -451,9 +478,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # 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=0
+# 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
@@ -481,6 +506,7 @@ 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_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
@@ -491,6 +517,11 @@ CONFIG_MTD_NAND_ORION=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
@@ -567,7 +598,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
+# 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
@@ -587,6 +622,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -660,6 +696,7 @@ CONFIG_SATA_MV=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -682,6 +719,9 @@ CONFIG_MARVELL_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
@@ -694,7 +734,10 @@ CONFIG_MII=y
 # 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 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
@@ -710,7 +753,6 @@ CONFIG_NET_PCI=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -720,6 +762,7 @@ CONFIG_NET_PCI=y
 # 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_VIA_RHINE is not set
@@ -732,6 +775,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
@@ -746,6 +790,7 @@ 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
@@ -754,8 +799,40 @@ CONFIG_MV643XX_ETH=y
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_SPI is not set
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH5K is not set
+# CONFIG_ATH9K is not set
+# CONFIG_AR9170_USB is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI 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_HERMES is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -791,13 +868,20 @@ 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_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
@@ -807,7 +891,11 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # Hardware I/O ports
 #
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -835,15 +923,16 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 #
 # 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_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -879,6 +968,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # 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
@@ -905,12 +995,9 @@ CONFIG_I2C_MV64XXX=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
@@ -925,12 +1012,12 @@ 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_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -952,10 +1039,12 @@ CONFIG_SSB_POSSIBLE=y
 # 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 
 #
 # Multimedia devices
@@ -1008,28 +1097,31 @@ 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_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=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_NTRIG=y
 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_TOPSEED=y
 # CONFIG_THRUSTMASTER_FF is not set
 # CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
@@ -1058,6 +1150,7 @@ CONFIG_USB_DEVICE_CLASS=y
 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_OHCI_HCD is not set
@@ -1076,18 +1169,17 @@ CONFIG_USB_PRINTER=m
 # 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=y
 CONFIG_USB_STORAGE_FREECOM=y
 # CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
 # CONFIG_USB_STORAGE_USBAT is not set
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
@@ -1123,7 +1215,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=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
@@ -1135,21 +1226,60 @@ CONFIG_USB_STORAGE_JUMPSHOT=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_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
-# CONFIG_MMC 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=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MMC_MVSDIO=y
+# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
-# CONFIG_LEDS_CLASS is not set
+CONFIG_LEDS_CLASS=y
 
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP5521 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 is not set
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1178,7 +1308,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_S35390A is not set
+CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
 
@@ -1224,9 +1354,12 @@ 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_REGULATOR is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1235,19 +1368,18 @@ 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_FILE_LOCKING=y
-CONFIG_XFS_FS=y
-# 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_XFS_FS 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
@@ -1257,6 +1389,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
@@ -1268,9 +1405,9 @@ CONFIG_UDF_NLS=y
 #
 # DOS/FAT/NT Filesystems
 #
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+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
@@ -1286,10 +1423,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
@@ -1309,6 +1443,7 @@ CONFIG_JFFS2_ZLIB=y
 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
@@ -1317,6 +1452,7 @@ 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
@@ -1328,7 +1464,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
@@ -1393,13 +1528,16 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # 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 is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1416,6 +1554,7 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=
 # 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=y
@@ -1424,7 +1563,7 @@ CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# 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
@@ -1435,7 +1574,12 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1445,12 +1589,19 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # 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_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_FTRACE_STARTUP_TEST 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
@@ -1464,21 +1615,26 @@ CONFIG_DEBUG_LL=y
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_ASYNC_CORE=y
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
 # CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=m
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_RNG=m
-CONFIG_CRYPTO_MANAGER=m
+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
@@ -1496,7 +1652,7 @@ CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_CBC=m
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_ECB=y
 # CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_XTS is not set
@@ -1510,7 +1666,7 @@ CONFIG_CRYPTO_PCBC=m
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=y
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1527,9 +1683,9 @@ CONFIG_CRYPTO_PCBC=m
 #
 # Ciphers
 #
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
 # CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 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
@@ -1547,6 +1703,7 @@ CONFIG_CRYPTO_PCBC=m
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1555,11 +1712,13 @@ CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X 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
@@ -1569,7 +1728,7 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=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.29-gnu1/arch/arm/configs/lart_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/lart_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/lart_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/lart_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/magician_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/magician_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/magician_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/magician_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Sun Dec 30 13:02:54 2007
+# Linux kernel version: 2.6.29-rc3
+# Fri Jan 30 12:42:03 2009
 #
 CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
@@ -12,6 +13,7 @@ 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
@@ -21,8 +23,8 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=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"
 
@@ -41,16 +43,24 @@ 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=16
+# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-# CONFIG_FAIR_GROUP_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_CC_OPTIMIZE_FOR_SIZE=y
@@ -65,31 +75,41 @@ 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_VM_EVENT_COUNTERS=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
+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=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
@@ -103,8 +123,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -114,9 +133,7 @@ CONFIG_CLASSIC_RCU=y
 # 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_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
@@ -130,41 +147,58 @@ 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_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=y
 # 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 is not set
 
 #
 # Intel PXA2xx/PXA3xx Implementations
 #
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 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_ARCH_PXA_IDP is not set
 # CONFIG_PXA_SHARPSL is not set
-# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
 # CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI 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_MAGICIAN=y
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
 CONFIG_PXA27x=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_PXA_SSP=y
+CONFIG_PXA_PWM=y
+CONFIG_PXA_HAVE_BOARD_IRQS=y
 
 #
 # Processor Type
@@ -173,6 +207,7 @@ CONFIG_CPU_32=y
 CONFIG_CPU_XSCALE=y
 CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
 CONFIG_CPU_CP15=y
@@ -186,6 +221,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_OUTER_CACHE is not set
 CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -197,28 +233,33 @@ CONFIG_XSCALE_PMU=y
 #
 # Kernel Features
 #
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_NO_HZ is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
 # 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=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_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_UNEVICTABLE_LRU=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -229,9 +270,10 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="keepinitrd"
 # CONFIG_XIP_KERNEL is not set
 CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_TABLE=y
@@ -239,6 +281,7 @@ CONFIG_CPU_FREQ_TABLE=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
@@ -247,6 +290,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_USERSPACE is not set
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -263,6 +307,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
 
@@ -270,21 +316,18 @@ CONFIG_BINFMT_ELF=y
 # Power management options
 #
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_UP_POSSIBLE=y
 CONFIG_SUSPEND=y
-CONFIG_APM_EMULATION=y
-
-#
-# Networking
-#
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -316,33 +359,15 @@ CONFIG_IP_PNP=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 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES 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
@@ -353,6 +378,7 @@ CONFIG_NETFILTER=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -390,20 +416,17 @@ CONFIG_IRTTY_SIR=m
 # Dongle support
 #
 # CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
 
 #
 # FIR device drivers
 #
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
 CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR is not set
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
@@ -417,17 +440,17 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
+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_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_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
 
@@ -442,25 +465,28 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 CONFIG_STANDALONE=y
 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=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=0
+# 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_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
 #
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
+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
@@ -473,6 +499,7 @@ CONFIG_MTD_BLOCK=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
@@ -487,6 +514,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_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -497,9 +525,7 @@ CONFIG_MTD_CFI_INTELEXT=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x04000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PXA2XX is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_SHARP_SL is not set
@@ -523,6 +549,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -531,10 +563,12 @@ 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_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_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -547,7 +581,6 @@ CONFIG_BLK_DEV=y
 # 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
@@ -563,6 +596,20 @@ CONFIG_NETDEVICES=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
+#
+# 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
@@ -612,7 +659,26 @@ CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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
 
 #
@@ -625,9 +691,11 @@ CONFIG_INPUT_UINPUT=m
 # 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
 
 #
@@ -642,6 +710,7 @@ CONFIG_SERIAL_PXA=y
 # CONFIG_SERIAL_PXA_CONSOLE is not set
 CONFIG_SERIAL_CORE=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
@@ -649,37 +718,45 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-CONFIG_I2C=m
+CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+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_GPIO is not set
-CONFIG_I2C_PXA=m
-# CONFIG_I2C_PXA_SLAVE is not set
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT 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_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_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
@@ -688,19 +765,39 @@ CONFIG_I2C_PXA=m
 # 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
 
 #
-# SPI support
+# 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_SPI is not set
-# CONFIG_SPI_MASTER is not set
 CONFIG_W1=y
 
 #
 # 1-wire Bus Masters
 #
+# CONFIG_W1_MASTER_DS2490 is not set
 # CONFIG_W1_MASTER_DS2482 is not set
 CONFIG_W1_MASTER_DS1WM=y
+# CONFIG_W1_MASTER_GPIO is not set
 
 #
 # 1-wire Slaves
@@ -709,32 +806,56 @@ CONFIG_W1_MASTER_DS1WM=y
 # CONFIG_W1_SLAVE_SMEM is not set
 # CONFIG_W1_SLAVE_DS2433 is not set
 CONFIG_W1_SLAVE_DS2760=y
+# CONFIG_W1_SLAVE_BQ27000 is not set
 CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 CONFIG_PDA_POWER=y
-# CONFIG_APM_POWER is not set
 CONFIG_BATTERY_DS2760=y
+# CONFIG_BATTERY_BQ27x00 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_POSSIBLE=y
 # 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=y
 CONFIG_HTC_PASIC3=y
+# 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
 
 #
@@ -745,6 +866,7 @@ CONFIG_HTC_PASIC3=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
@@ -752,8 +874,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
@@ -765,13 +887,21 @@ CONFIG_FB_DEFERRED_IO=y
 #
 # 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 is not set
 # 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_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CORGI=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
 
 #
 # Display device support
@@ -802,15 +932,8 @@ 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_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -824,53 +947,185 @@ 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_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 is not set
+CONFIG_SND_PXA2XX_LIB=m
+# CONFIG_SND_USB 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_HID_SUPPORT is not set
+CONFIG_HID=m
+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
 
 #
-# ALSA ARM devices
+# Miscellaneous USB options
 #
-# CONFIG_SND_PXA2XX_AC97 is not set
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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
 
 #
-# System on Chip audio support
+# USB Host Controller Drivers
 #
-CONFIG_SND_SOC=m
-CONFIG_SND_PXA2XX_SOC=m
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD 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_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
 
 #
-# SoC Audio support for SuperH
+# 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
 
 #
-# Open Sound System
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_HID=m
-# CONFIG_USB_SUPPORT is not set
+
+#
+# see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 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_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_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_VBUS_DRAW=500
+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=y
+CONFIG_USB_PXA27X=y
+# 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_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO 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 is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+CONFIG_USB_GPIO_VBUS=y
 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=m
+# CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY 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_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -899,6 +1154,9 @@ 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
@@ -908,17 +1166,30 @@ CONFIG_RTC_INTF_DEV=y
 # 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_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_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES 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_BQ24022=y
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -927,19 +1198,18 @@ 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_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_FILE_LOCKING=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_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -965,15 +1235,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
@@ -997,9 +1265,13 @@ 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
@@ -1007,14 +1279,13 @@ 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_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
+# 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
@@ -1076,6 +1347,7 @@ CONFIG_NLS_UTF8=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 is not set
@@ -1083,15 +1355,18 @@ CONFIG_ENABLE_MUST_CHECK=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_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_PREEMPT=y
+# 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=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
@@ -1100,17 +1375,41 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_VM=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_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
 
@@ -1119,55 +1418,110 @@ CONFIG_DEBUG_LL=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=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_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# 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=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_NULL 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=m
 # 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 is not set
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT 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=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_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS 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_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 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
 
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/mv78xx0_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mv78xx0_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mv78xx0_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mv78xx0_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc5
-# Fri Jun 13 02:57:32 2008
+# Linux kernel version: 2.6.30-rc4
+# Mon May  4 14:22:12 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
@@ -22,8 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -43,10 +42,19 @@ CONFIG_SYSVIPC_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 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
@@ -54,32 +62,35 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=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=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_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
@@ -87,10 +98,9 @@ CONFIG_KPROBES=y
 CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=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
@@ -98,12 +108,10 @@ 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 is not set
 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
@@ -117,7 +125,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 is not set
 
 #
 # System Type
@@ -127,11 +135,10 @@ CONFIG_CLASSIC_RCU=y
 # 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_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
@@ -152,27 +159,23 @@ CONFIG_ARCH_MV78XX0=y
 # 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_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
 
 #
 # Marvell MV78xx0 Implementations
 #
 CONFIG_MACH_DB78X00_BP=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_MACH_RD78X00_MASA=y
 CONFIG_PLAT_ORION=y
 
 #
@@ -198,6 +201,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 CONFIG_OUTER_CACHE=y
 CONFIG_CACHE_FEROCEON_L2=y
+# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set
 
 #
 # Bus support
@@ -207,6 +211,8 @@ 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
 
 #
@@ -216,25 +222,33 @@ 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=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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=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_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_PHYS_ADDR_T_64BIT is not set
+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_ALIGNMENT_TRAP=y
 
 #
@@ -247,6 +261,11 @@ CONFIG_CMDLINE=""
 # CONFIG_KEXEC is not set
 
 #
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
 # Floating point emulation
 #
 
@@ -262,6 +281,8 @@ 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
 
@@ -270,10 +291,6 @@ CONFIG_BINFMT_ELF=y
 #
 # CONFIG_PM is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -309,7 +326,7 @@ CONFIG_IP_PNP_BOOTP=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_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -324,6 +341,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
@@ -333,26 +351,23 @@ 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=m
 # 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
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT=y
-# 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
 
@@ -367,6 +382,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 CONFIG_STANDALONE=y
 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
@@ -375,6 +392,7 @@ 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_AFS_PARTS is not set
@@ -428,9 +446,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # 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=0
+# 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
@@ -455,6 +471,7 @@ 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_GPIO is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
@@ -465,6 +482,11 @@ CONFIG_MTD_NAND_ORION=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
@@ -485,10 +507,20 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_ATA_OVER_ETH 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -546,7 +578,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
+# 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
@@ -565,6 +601,8 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -631,11 +669,15 @@ CONFIG_SATA_MV=y
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -643,7 +685,26 @@ CONFIG_NETDEVICES=y
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# 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
@@ -653,19 +714,25 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X 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_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=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -675,18 +742,20 @@ CONFIG_NET_PCI=y
 # 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_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_E1000E_ENABLED 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
@@ -700,6 +769,9 @@ CONFIG_NETDEV_1000=y
 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
 
@@ -708,7 +780,10 @@ CONFIG_MV643XX_ETH=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
@@ -785,11 +860,11 @@ 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_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -798,44 +873,63 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=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_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB 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_MV64XXX=y
+# 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_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -847,6 +941,7 @@ CONFIG_I2C_MV64XXX=y
 # 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_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -854,14 +949,17 @@ CONFIG_HWMON=y
 # 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_I5K_AMB 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
@@ -876,10 +974,15 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -899,20 +1002,28 @@ CONFIG_HWMON=y
 # 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_MFD_ASIC3 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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 
 #
 # Multimedia devices
@@ -943,10 +1054,6 @@ 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
@@ -957,9 +1064,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# 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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -977,6 +1111,9 @@ CONFIG_USB_DEVICE_CLASS=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
@@ -985,12 +1122,15 @@ CONFIG_USB_DEVICE_CLASS=y
 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_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
 
 #
 # USB Device Class drivers
@@ -998,20 +1138,20 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 # 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_DEBUG is not set
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 # CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
 # CONFIG_USB_STORAGE_USBAT is not set
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
@@ -1027,7 +1167,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1040,7 +1179,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=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 +1187,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=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
@@ -1058,14 +1196,29 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # 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_ACCESSIBILITY 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_LP5521 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -1073,7 +1226,12 @@ CONFIG_LEDS_CLASS=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_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
@@ -1104,6 +1262,8 @@ CONFIG_RTC_DRV_RS5C372=y
 CONFIG_RTC_DRV_M41T80=y
 # CONFIG_RTC_DRV_M41T80_WDT 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
@@ -1113,18 +1273,25 @@ CONFIG_RTC_DRV_M41T80=y
 # 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_REGULATOR is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1133,14 +1300,25 @@ 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=m
+# 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
 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 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1150,6 +1328,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
@@ -1173,15 +1356,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
@@ -1201,25 +1382,27 @@ CONFIG_JFFS2_ZLIB=y
 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_NFSD 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_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1300,11 +1483,16 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # 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=y
 # CONFIG_TIMER_STATS is not set
@@ -1319,22 +1507,55 @@ CONFIG_DEBUG_PREEMPT=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_HIGHMEM 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_FRAME_POINTER=y
+# 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_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_LKDTM 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_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_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_FTRACE_STARTUP_TEST 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
@@ -1346,17 +1567,27 @@ CONFIG_DEBUG_LL=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=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=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
@@ -1392,6 +1623,10 @@ CONFIG_CRYPTO_PCBC=m
 # 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
@@ -1421,25 +1656,32 @@ CONFIG_CRYPTO_PCBC=m
 # 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=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 is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
 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_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/mx1_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx1_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx1_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx1_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1105 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc1
+# Wed Apr  8 11:11:33 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_ARCH_MTD_XIP=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=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_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_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_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
+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_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+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=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=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_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=y
+# 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 is not set
+CONFIG_ARCH_MX1ADS=y
+
+#
+# Freescale MXC Implementations
+#
+CONFIG_ARCH_MX1=y
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX3 is not set
+
+#
+# MX1 platforms:
+#
+CONFIG_MACH_MXLADS=y
+CONFIG_MACH_SCB9328=y
+CONFIG_MXC_IRQ_PRIOR=y
+# CONFIG_MXC_PWM is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=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 is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# 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=y
+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=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=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
+# 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
+
+#
+# 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=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION 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_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 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_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=m
+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_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
+# 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 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_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 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_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=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=y
+CONFIG_DM9000_DEBUGLEVEL=4
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL 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 is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_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 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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=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
+
+#
+# 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_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
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# 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_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=y
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# 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 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_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_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=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_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
+# 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
+
+#
+# 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 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=y
+CONFIG_USB_IMX=y
+# 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_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO 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_MXC=y
+# 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 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_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_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_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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+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 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 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 is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# 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_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_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_FIPS is not set
+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 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=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 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.29-gnu1/arch/arm/configs/mx27_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx27_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx27_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx27_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1174 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc1
+# Wed Apr  8 10:18:06 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_ARCH_MTD_XIP=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 is not set
+CONFIG_LOG_BUF_SHIFT=14
+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_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 is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+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
+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_MARKERS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=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=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_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 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_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=y
+# 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 is not set
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+CONFIG_ARCH_MX2=y
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_MACH_MX21 is not set
+CONFIG_MACH_MX27=y
+
+#
+# MX2 platforms:
+#
+CONFIG_MACH_MX27ADS=y
+CONFIG_MACH_PCM038=y
+CONFIG_MACH_PCM970_BASEBOARD=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_MXC_PWM=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=y
+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=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=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=y
+CONFIG_FPE_NWFPE_XP=y
+# 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=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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# 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 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 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_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_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 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_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_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=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 is not set
+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 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
+# 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_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR 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
+# 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_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 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_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_NET_ETHERNET=y
+# CONFIG_MII is not set
+# 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 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_FEC=y
+# CONFIG_FEC2 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
+
+#
+# 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 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 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_MAX3100 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_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 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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=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
+
+#
+# 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_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=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# 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_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=y
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# 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 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_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_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+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=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+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_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB 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_IMX=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
+#
+# 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=y
+CONFIG_FONT_8x8=y
+# 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 is not set
+# 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 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
+
+#
+# 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_MXC=y
+# CONFIG_MMC_SPI 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=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=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
+
+#
+# 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_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_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 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_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
+# 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 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_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=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=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=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=m
+# 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 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 is not set
+# 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_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_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_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_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.29-gnu1/arch/arm/configs/mx31ads_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx31ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx31ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx31ads_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,839 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Fri Jun 20 16:21:11 2008
-#
-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_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=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=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
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-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_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=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=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_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_VM_EVENT_COUNTERS=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
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=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=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_BLK_DEV_BSG 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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-# CONFIG_ARCH_MX2 is not set
-CONFIG_ARCH_MX3=y
-
-#
-# MX3 Options
-#
-CONFIG_MACH_MX31ADS=y
-# CONFIG_MACH_PCM037 is not set
-
-#
-# 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_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 is not set
-
-#
-# 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_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_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_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_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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
-
-#
-# Networking
-#
-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 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_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
-# CONFIG_NET_SCHED 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_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=m
-# 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_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY 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=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 is not set
-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 is not set
-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 is not set
-# CONFIG_MTD_PHYSMAP 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=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_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-# CONFIG_BLK_DEV 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_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE 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_PHYLIB 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_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_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
-# CONFIG_IWLWIFI_LEDS 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
-
-#
-# 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=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS 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
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO 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
-
-#
-# 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
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# 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
-
-#
-# 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_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_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_VXFS_FS is not set
-# CONFIG_MINIX_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_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=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 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=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 is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY 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_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_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_LZO is not set
-# CONFIG_CRYPTO_HW 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_CRC_CCITT is not set
-# CONFIG_CRC16 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/mx31litekit_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx31litekit_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx31litekit_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx31litekit_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1100 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc5
-# Fri Jun 13 14:23:39 2008
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
-# 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_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=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=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
-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_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_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=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_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_VM_EVENT_COUNTERS=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
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=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=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_BLK_DEV_BSG 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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-CONFIG_ARCH_MX3=y
-
-#
-# MX3 Options
-#
-# CONFIG_MACH_MX31ADS is not set
-CONFIG_MACH_MX31LITE=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_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 is not set
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA is not set
-
-#
-# PC-card bridges
-#
-
-#
-# Kernel Features
-#
-# CONFIG_TICK_ONESHOT is not set
-CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_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_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_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-# CONFIG_SUSPEND is not set
-# CONFIG_APM_EMULATION is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
-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 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_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
-# CONFIG_NET_SCHED 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_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=m
-# 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_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY 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=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 is not set
-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 is not set
-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 is not set
-# CONFIG_MTD_PHYSMAP 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=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_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_ALAUDA is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-# CONFIG_BLK_DEV 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
-
-#
-# 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
-# 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_DEBUG is not set
-# 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
-# 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 is not set
-# CONFIG_DM9000 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_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
-# CONFIG_IWLWIFI_LEDS 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_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
-
-#
-# 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_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# 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_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_MTOUCH 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_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 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_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# 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
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-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=y
-
-#
-# Multimedia drivers
-#
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_VIDEO_V4L2=y
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CPIA2 is not set
-CONFIG_V4L_USB_DRIVERS=y
-# 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_ZR364XX is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_SOC_CAMERA is not set
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_SI470X is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB 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_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_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=y
-
-#
-# Sound
-#
-# 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_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_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
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM 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 is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
-
-#
-# 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_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_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# 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
-
-#
-# 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_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_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_VXFS_FS is not set
-# CONFIG_MINIX_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_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=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 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=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 is not set
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-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_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 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 is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-CONFIG_DEBUG_ERRORS=y
-# 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_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_MANAGER 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_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_LZO is not set
-CONFIG_CRYPTO_HW=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/mx31moboard_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx31moboard_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx31moboard_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx31moboard_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,790 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc5
-# Fri Oct 24 11:41:22 2008
-#
-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_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"
-
-#
-# 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
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-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_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=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-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_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_VM_EVENT_COUNTERS=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_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# 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 is not set
-CONFIG_PROC_PAGE_MONITOR=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=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_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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-# CONFIG_ARCH_MX2 is not set
-CONFIG_ARCH_MX3=y
-
-#
-# MX3 Options
-#
-# CONFIG_MACH_MX31ADS is not set
-# CONFIG_MACH_PCM037 is not set
-# CONFIG_MACH_MX31LITE is not set
-CONFIG_MACH_MX31MOBOARD=y
-# CONFIG_MXC_IRQ_PRIOR is not set
-
-#
-# 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_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 is not set
-
-#
-# 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_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
-# CONFIG_ARCH_DISCONTIGMEM_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_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_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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_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 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_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
-# CONFIG_NET_SCHED 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_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=m
-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_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=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=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 is not set
-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 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
-# 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_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
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-# CONFIG_BLK_DEV 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_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_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_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
-# CONFIG_IWLWIFI_LEDS 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
-
-#
-# 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=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS 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
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# 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_WATCHDOG is not set
-
-#
-# 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_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
-
-#
-# 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
-# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# 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
-
-#
-# 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_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_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_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 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 is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_LATENCYTOP is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE 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_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO 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_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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/mx3_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/mx3_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/mx3_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/mx3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1125 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc1
+# Wed Apr  8 11:06:37 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_ARCH_MTD_XIP=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=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_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_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_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
+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_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+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=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=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_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=y
+# 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 is not set
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+CONFIG_ARCH_MX3=y
+CONFIG_ARCH_MX31=y
+
+#
+# MX3 platforms:
+#
+CONFIG_MACH_MX31ADS=y
+CONFIG_MACH_MX31ADS_WM1133_EV1=y
+CONFIG_MACH_PCM037=y
+CONFIG_MACH_MX31LITE=y
+CONFIG_MACH_MX31_3DS=y
+CONFIG_MACH_MX31MOBOARD=y
+CONFIG_MACH_QONG=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_MXC_PWM=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_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_L2X0=y
+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=y
+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=4
+# 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=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
+# 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=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION 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_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 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_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=m
+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_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
+# 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 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_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 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_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=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_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_CS89x0=y
+CONFIG_CS89x0_NONISA_IRQ=y
+# 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
+
+#
+# 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_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 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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=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
+
+#
+# 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_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
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# 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_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=y
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# 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 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_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_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
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+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_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9M001=y
+CONFIG_SOC_CAMERA_MT9M111=y
+CONFIG_SOC_CAMERA_MT9T031=y
+CONFIG_SOC_CAMERA_MT9V022=y
+CONFIG_SOC_CAMERA_TW9910=y
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_MX3=y
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB 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_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_FB_MX3=y
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO 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
+
+#
+# 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_MXC=y
+# 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=y
+
+#
+# DMA Devices
+#
+CONFIG_MX3_IPU=y
+CONFIG_MX3_IPU_IRQS=4
+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_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+CONFIG_REGULATOR_WM8350=y
+# 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 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_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_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_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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+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 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 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 is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# 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_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_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_FIPS is not set
+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 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=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 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.29-gnu1/arch/arm/configs/neponset_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/neponset_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/neponset_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/neponset_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -91,7 +91,6 @@ CONFIG_ASSABET_NEPONSET=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/omap_3430sdp_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/omap_3430sdp_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/omap_3430sdp_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/omap_3430sdp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2061 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 14:17:01 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_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# 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_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_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
+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_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
+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=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE 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=y
+
+#
+# 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_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_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=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 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
+
+#
+# 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_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_SERIAL_WAKE=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_OMAP3_PANDORA=y
+CONFIG_MACH_OMAP_3430SDP=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_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_OUTER_CACHE is not set
+
+#
+# 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 is not set
+CONFIG_HZ=128
+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_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_UNEVICTABLE_LRU=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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
+
+#
+# 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_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 is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+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=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=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 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_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=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_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_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=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_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_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_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=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_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES 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_93CX6=m
+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 is not set
+CONFIG_CHR_DEV_SG=m
+# 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
+# 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_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH 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_NETDEVICES=y
+CONFIG_DUMMY=m
+# 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=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_SMC911X=m
+CONFIG_SMSC911X=m
+# 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=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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# 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_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_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
+
+#
+# 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 is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_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_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_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_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_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_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_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=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
+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_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_THERMAL is not set
+# CONFIG_THERMAL_HWMON 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
+
+#
+# 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_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=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
+
+#
+# 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=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=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=y
+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_HID_DEBUG=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_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_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_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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=y
+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_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=y
+# 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_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD 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_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_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_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_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO 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_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=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_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY 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_PCA955X 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_DEFAULT_ON 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
+
+#
+# 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_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_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_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_GFS2_FS 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=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=m
+
+#
+# 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 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_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_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
+# 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_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=y
+CONFIG_SCHEDSTATS=y
+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_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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB 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
+
+#
+# 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_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+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
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_MD4=m
+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=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 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
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# 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=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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/omap_ldp_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/omap_ldp_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/omap_ldp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/omap_ldp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -474,14 +474,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=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_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/orion5x_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/orion5x_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/orion5x_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/orion5x_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Fri Aug 22 12:38:51 2008
+# Linux kernel version: 2.6.30-rc4
+# Mon May  4 14:07:25 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -22,8 +22,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -44,10 +42,19 @@ CONFIG_SYSVIPC_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 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
@@ -55,48 +62,45 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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=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=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_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
 CONFIG_KRETPROBES=y
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# 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 is not set
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=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
@@ -104,11 +108,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
 
@@ -124,7 +125,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 is not set
 
 #
 # System Type
@@ -134,10 +135,10 @@ CONFIG_CLASSIC_RCU=y
 # 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_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
@@ -158,14 +159,17 @@ CONFIG_CLASSIC_RCU=y
 CONFIG_ARCH_ORION5X=y
 # 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_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
 
 #
 # Orion Implementations
@@ -175,6 +179,7 @@ CONFIG_MACH_RD88F5182=y
 CONFIG_MACH_KUROBOX_PRO=y
 CONFIG_MACH_DNS323=y
 CONFIG_MACH_TS209=y
+CONFIG_MACH_TERASTATION_PRO2=y
 CONFIG_MACH_LINKSTATION_PRO=y
 CONFIG_MACH_LINKSTATION_MINI=y
 CONFIG_MACH_TS409=y
@@ -187,14 +192,6 @@ CONFIG_MACH_WNR854T=y
 CONFIG_MACH_RD88F5181L_GE=y
 CONFIG_MACH_RD88F5181L_FXO=y
 CONFIG_MACH_RD88F6183AP_GE=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
 CONFIG_PLAT_ORION=y
 
 #
@@ -228,6 +225,8 @@ 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
 
 #
@@ -237,25 +236,32 @@ 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=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_LEDS=y
 CONFIG_LEDS_CPU=y
 CONFIG_ALIGNMENT_TRAP=y
@@ -270,6 +276,11 @@ CONFIG_CMDLINE=""
 # CONFIG_KEXEC is not set
 
 #
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
 # Floating point emulation
 #
 
@@ -285,13 +296,18 @@ 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_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -328,7 +344,7 @@ CONFIG_IP_PNP_BOOTP=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_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -343,6 +359,15 @@ 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=y
+CONFIG_NET_DSA_TAG_EDSA=y
+# CONFIG_NET_DSA_TAG_TRAILER is not set
+CONFIG_NET_DSA_MV88E6XXX=y
+# CONFIG_NET_DSA_MV88E6060 is not set
+CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -352,27 +377,29 @@ 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=m
 # 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
-
-#
-# Wireless
-#
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 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
 
@@ -397,6 +424,7 @@ 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_AFS_PARTS is not set
@@ -450,9 +478,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # 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=0
+# 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
@@ -477,16 +503,22 @@ 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_GPIO 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_NAND_PLATFORM=y
 # CONFIG_MTD_ALAUDA is not set
 CONFIG_MTD_NAND_ORION=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
@@ -507,11 +539,20 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_ATA_OVER_ETH 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -569,7 +610,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
+# 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
@@ -589,6 +634,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -663,6 +709,7 @@ CONFIG_SATA_MV=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -670,7 +717,26 @@ CONFIG_NETDEVICES=y
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# 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
@@ -680,19 +746,25 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X 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_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=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -702,10 +774,12 @@ CONFIG_NET_PCI=y
 # 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_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
@@ -713,6 +787,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
@@ -727,6 +802,8 @@ 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
 
@@ -735,7 +812,10 @@ CONFIG_MV643XX_ETH=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
@@ -819,11 +899,11 @@ 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_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -886,12 +966,9 @@ CONFIG_I2C_MV64XXX=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
@@ -911,14 +988,17 @@ CONFIG_HWMON=y
 # 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_I5K_AMB 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
@@ -933,10 +1013,15 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -956,12 +1041,14 @@ CONFIG_SENSORS_LM75=y
 # 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
 
 #
@@ -970,9 +1057,12 @@ CONFIG_SSB_POSSIBLE=y
 # 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_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB 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
@@ -1013,9 +1103,36 @@ CONFIG_HID=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# 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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1030,10 +1147,13 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND 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
@@ -1042,12 +1162,15 @@ CONFIG_USB_DEVICE_CLASS=y
 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_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
 
 #
 # USB Device Class drivers
@@ -1055,20 +1178,20 @@ CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 # 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_DEBUG is not set
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 # CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
 # CONFIG_USB_STORAGE_USBAT is not set
 CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_STORAGE_SDDR55=y
@@ -1076,7 +1199,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=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_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -1097,6 +1219,7 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # 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
@@ -1104,7 +1227,6 @@ CONFIG_USB_STORAGE_JUMPSHOT=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
@@ -1114,8 +1236,18 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
 # 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_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 
@@ -1124,7 +1256,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_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -1132,7 +1267,12 @@ 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_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1164,6 +1304,7 @@ CONFIG_RTC_DRV_M41T80=y
 # CONFIG_RTC_DRV_M41T80_WDT is not set
 CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
@@ -1173,12 +1314,15 @@ CONFIG_RTC_DRV_S35390A=y
 # 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_M48T86=y
+# 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
 
 #
@@ -1196,16 +1340,12 @@ CONFIG_DMA_ENGINE=y
 # DMA Clients
 #
 # CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
 # CONFIG_DMATEST is not set
-
-#
-# Voltage and Current regulators
-#
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1214,14 +1354,25 @@ 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=m
+# 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
 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 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1231,6 +1382,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
@@ -1254,15 +1410,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
@@ -1282,6 +1436,7 @@ CONFIG_JFFS2_ZLIB=y
 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
@@ -1290,6 +1445,7 @@ 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
@@ -1381,13 +1537,16 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # 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=y
 # CONFIG_TIMER_STATS is not set
@@ -1411,25 +1570,46 @@ CONFIG_DEBUG_INFO=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_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_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+# CONFIG_PAGE_POISONING 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_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_FTRACE_STARTUP_TEST 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
@@ -1441,18 +1621,27 @@ CONFIG_DEBUG_LL=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_ASYNC_CORE=y
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
 CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=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
@@ -1521,18 +1710,24 @@ CONFIG_CRYPTO_PCBC=m
 # 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=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 is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
@@ -1540,7 +1735,7 @@ 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
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/pcm037_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/pcm037_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/pcm037_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/pcm037_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,748 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Wed Jun 25 11:52:42 2008
-#
-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_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=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=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
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-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_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=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=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_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_VM_EVENT_COUNTERS=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
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=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=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_BLK_DEV_BSG 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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-CONFIG_ARCH_MX3=y
-
-#
-# MX3 Options
-#
-# CONFIG_MACH_MX31ADS is not set
-CONFIG_MACH_PCM037=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_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 is not set
-
-#
-# 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_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_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_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_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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
-
-#
-# Networking
-#
-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 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_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_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
-# CONFIG_NET_SCHED 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_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=m
-# 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_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_CFI_NOSWAP is not set
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP 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 is not set
-# CONFIG_MTD_CFI_STAA 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_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# 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
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-# CONFIG_BLK_DEV 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_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE 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_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_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_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
-# CONFIG_IWLWIFI_LEDS 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
-
-#
-# 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=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS 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
-CONFIG_HAVE_GPIO_LIB=y
-
-#
-# GPIO Support
-#
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO 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
-
-#
-# 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
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# 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
-
-#
-# 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_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_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_VXFS_FS is not set
-# CONFIG_MINIX_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_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=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 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 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 is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO 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_CRC_CCITT is not set
-# CONFIG_CRC16 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/pcm038_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/pcm038_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/pcm038_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/pcm038_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1008 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Fri Jun 20 16:38:36 2008
-#
-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_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_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
-CONFIG_ARCH_MTD_XIP=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_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT 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=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED 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 is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-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_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_MARKERS=y
-CONFIG_OPROFILE=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_KRETPROBES=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
-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 is not set
-# CONFIG_KMOD is not set
-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
-
-#
-# 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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-CONFIG_ARCH_MXC=y
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Freescale MXC Implementations
-#
-CONFIG_ARCH_MX2=y
-# CONFIG_ARCH_MX3 is not set
-
-#
-# MX2 family CPU support
-#
-CONFIG_MACH_MX27=y
-
-#
-# MX2 Platforms
-#
-# CONFIG_MACH_MX27ADS is not set
-CONFIG_MACH_PCM038=y
-CONFIG_MACH_PCM970_BASEBOARD=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
-
-#
-# 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_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_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_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_VIRT_TO_BUS=y
-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
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# 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 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 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_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
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE 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_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_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_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=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 is not set
-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 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
-# 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=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_ARM_INTEGRATOR 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
-# 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
-
-#
-# 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_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 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_NETDEVICES_MULTIQUEUE 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_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_AX88796 is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-# CONFIG_ENC28J60 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_B44 is not set
-CONFIG_FEC_OLD=y
-# 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_IWLWIFI_LEDS 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
-
-#
-# 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 is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_MTOUCH 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_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 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_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS 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=y
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Hardware Bus support
-#
-# 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
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_PLATFORM 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_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-CONFIG_SPI_BITBANG=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
-#
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_GPIO_MCP23S08 is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-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=y
-
-#
-# Multimedia drivers
-#
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=y
-CONFIG_MEDIA_TUNER_TDA8290=y
-CONFIG_MEDIA_TUNER_TDA9887=y
-CONFIG_MEDIA_TUNER_TEA5761=y
-CONFIG_MEDIA_TUNER_TEA5767=y
-CONFIG_MEDIA_TUNER_MT20XX=y
-CONFIG_MEDIA_TUNER_XC2028=y
-CONFIG_MEDIA_TUNER_XC5000=y
-CONFIG_VIDEO_V4L2=y
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_DAB 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_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_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=y
-CONFIG_FONT_8x8=y
-# 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 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_10x18 is not set
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC 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
-
-#
-# 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=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
-
-#
-# SPI RTC drivers
-#
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_UIO is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS 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 is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_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
-
-#
-# 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_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_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_VXFS_FS is not set
-# CONFIG_MINIX_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_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=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 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=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=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=m
-# 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 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 is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO 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_CRC_CCITT is not set
-# CONFIG_CRC16 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/pleb_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/pleb_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/pleb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/pleb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -88,7 +88,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/pxa168_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/pxa168_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/pxa168_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/pxa168_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,891 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Fri Mar 20 13:43: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
+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=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_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=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=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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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_VM_EVENT_COUNTERS=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
+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 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_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_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_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=y
+# 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 is not set
+# CONFIG_MACH_TAVOREVB is not set
+
+#
+# Marvell PXA168/910 Implmentations
+#
+CONFIG_MACH_ASPENITE=y
+CONFIG_MACH_ZYLONITE2=y
+# CONFIG_MACH_TTC_DKB is not set
+CONFIG_CPU_PXA168=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_MOHAWK=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=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_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+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=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+# 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=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 is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=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
+# 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 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_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_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_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
+# 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 is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+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 is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV 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_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_SMC911X is not set
+# CONFIG_SMSC911X 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
+# 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
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# 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=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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+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 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_DEBUG_GPIO is not set
+# 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_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_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 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_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_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 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_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_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_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_SUNRPC_REGISTER_V4 is not set
+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 is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS 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_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_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_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_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_HAVE_FUNCTION_TRACER=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_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=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_FIPS is not set
+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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# 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=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
+
+#
+# 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 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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/pxa910_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/pxa910_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/pxa910_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/pxa910_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,891 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Fri Mar 20 13:45: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_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=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_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=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=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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_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_VM_EVENT_COUNTERS=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
+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 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_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_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_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=y
+# 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 is not set
+CONFIG_MACH_TAVOREVB=y
+
+#
+# Marvell PXA168/910 Implmentations
+#
+# CONFIG_MACH_ASPENITE is not set
+# CONFIG_MACH_ZYLONITE2 is not set
+CONFIG_MACH_TTC_DKB=y
+CONFIG_CPU_PXA910=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_MOHAWK=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=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_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+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=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+# 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=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 is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=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
+# 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 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_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_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_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
+# 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 is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+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 is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV 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_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_SMC911X is not set
+# CONFIG_SMSC911X 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
+# 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
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# 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=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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+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 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_DEBUG_GPIO is not set
+# 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_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_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 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_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_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 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_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_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_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_SUNRPC_REGISTER_V4 is not set
+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 is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS 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_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_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_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_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_HAVE_FUNCTION_TRACER=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_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=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_FIPS is not set
+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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# 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=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
+
+#
+# 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 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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/realview_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/realview_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/realview_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/realview_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -490,13 +490,33 @@ 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=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_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/realview-smp_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/realview-smp_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/realview-smp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/realview-smp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -496,13 +496,33 @@ 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=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_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/rx51_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/rx51_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/rx51_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/rx51_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1821 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 15:28:56 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_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_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_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_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=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_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
+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=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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=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_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_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_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=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 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
+
+#
+# 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_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_SERIAL_WAKE=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_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+CONFIG_MACH_NOKIA_RX51=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_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_OUTER_CACHE is not set
+
+#
+# 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 is not set
+CONFIG_HZ=128
+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_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_UNEVICTABLE_LRU=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs rw console=ttyMTD5"
+# 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=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=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=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_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=m
+# 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_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 is not set
+# 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=m
+# 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=m
+# 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_RAW is not set
+# CONFIG_IP_NF_SECURITY is not set
+# CONFIG_IP_NF_ARPTABLES 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_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_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 is not set
+# 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_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 is not set
+CONFIG_MAC80211=m
+
+#
+# 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 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_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=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_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 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
+# 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=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# 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=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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES 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_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=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_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH 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 is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=m
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X 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=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM 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_IWLWIFI_LEDS 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
+
+#
+# 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
+
+#
+# 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_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_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_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_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
+
+#
+# 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=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# 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=m
+# 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_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_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=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
+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_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_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_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_OMAP_WATCHDOG=m
+
+#
+# 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_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=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_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_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_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION 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_VIDEO_OVCAMCHIP 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_ZR364XX is not set
+# 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_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=y
+
+#
+# Display hardware drivers
+#
+
+#
+# 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=y
+CONFIG_SND_PCM=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_SPI=y
+# CONFIG_SND_USB is not set
+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=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID 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
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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=y
+CONFIG_USB_OTG_BLACKLIST_HUB=y
+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_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 information
+#
+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=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_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=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_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_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_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST 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_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+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=m
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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 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=m
+# 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_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_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_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# 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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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=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=m
+
+#
+# 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_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 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# 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_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=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# 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=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_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_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB 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
+
+#
+# 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_DEFAULT_MMAP_MIN_ADDR=0
+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
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# 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=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
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# 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=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_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=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=m
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/s3c2410_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/s3c2410_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/s3c2410_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/s3c2410_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Mon Jul  7 16:59:23 2008
+# Linux kernel version: 2.6.30-rc2
 #
 CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_GENERIC_TIME is not set
@@ -12,6 +12,7 @@ CONFIG_MMU=y
 CONFIG_NO_IOPORT=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
@@ -21,8 +22,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -41,11 +41,20 @@ CONFIG_SYSVIPC_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=m
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
-# 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
@@ -54,31 +63,36 @@ CONFIG_NAMESPACES=y
 # 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_SYSCTL_SYSCALL_CHECK=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_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_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -88,11 +102,11 @@ 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
+# CONFIG_SLOW_WORK is not set
+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
@@ -100,12 +114,10 @@ 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
@@ -119,7 +131,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -129,11 +141,10 @@ CONFIG_CLASSIC_RCU=y
 # 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_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
@@ -145,26 +156,38 @@ 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_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=y
+# 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_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
 CONFIG_PLAT_S3C24XX=y
+CONFIG_S3C2410_CLOCK=y
+CONFIG_S3C24XX_DCLK=y
 CONFIG_CPU_S3C244X=y
-# CONFIG_S3C24XX_PWM is not set
+CONFIG_S3C24XX_PWM=y
+CONFIG_S3C24XX_GPIO_EXTRA=128
+CONFIG_S3C24XX_GPIO_EXTRA64=y
+CONFIG_S3C24XX_GPIO_EXTRA128=y
 CONFIG_PM_SIMTEC=y
 CONFIG_S3C2410_DMA=y
 # CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_S3C24XX_ADC=y
 CONFIG_MACH_SMDK=y
 CONFIG_PLAT_S3C=y
 CONFIG_CPU_LLSERIAL_S3C2410=y
@@ -174,7 +197,8 @@ CONFIG_CPU_LLSERIAL_S3C2440=y
 # Boot options
 #
 # CONFIG_S3C_BOOT_WATCHDOG is not set
-# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
 
 #
 # Power management
@@ -182,6 +206,8 @@ CONFIG_CPU_LLSERIAL_S3C2440=y
 # CONFIG_S3C2410_PM_DEBUG is not set
 # CONFIG_S3C2410_PM_CHECK is not set
 CONFIG_S3C_LOWLEVEL_UART_PORT=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_DEV_HSMMC=y
 
 #
 # S3C2400 Machines
@@ -190,7 +216,6 @@ CONFIG_CPU_S3C2410=y
 CONFIG_CPU_S3C2410_DMA=y
 CONFIG_S3C2410_PM=y
 CONFIG_S3C2410_GPIO=y
-CONFIG_S3C2410_CLOCK=y
 CONFIG_SIMTEC_NOR=y
 CONFIG_MACH_BAST_IDE=y
 
@@ -205,7 +230,7 @@ CONFIG_ARCH_BAST=y
 CONFIG_MACH_OTOM=y
 CONFIG_MACH_AML_M5900=y
 CONFIG_BAST_PC104_IRQ=y
-# CONFIG_MACH_TCT_HAMMER is not set
+CONFIG_MACH_TCT_HAMMER=y
 CONFIG_MACH_VR1000=y
 CONFIG_MACH_QT2410=y
 CONFIG_CPU_S3C2412=y
@@ -215,10 +240,11 @@ CONFIG_S3C2412_PM=y
 #
 # S3C2412 Machines
 #
-# CONFIG_MACH_JIVE is not set
+CONFIG_MACH_JIVE=y
+# CONFIG_MACH_JIVE_SHOW_BOOTLOADER is not set
 CONFIG_MACH_SMDK2413=y
 CONFIG_MACH_S3C2413=y
-# CONFIG_MACH_SMDK2412 is not set
+CONFIG_MACH_SMDK2412=y
 CONFIG_MACH_VSTMS=y
 CONFIG_CPU_S3C2440=y
 CONFIG_S3C2440_DMA=y
@@ -232,7 +258,7 @@ CONFIG_MACH_RX3715=y
 CONFIG_ARCH_S3C2440=y
 CONFIG_MACH_NEXCODER_2440=y
 CONFIG_SMDK2440_CPU2440=y
-# CONFIG_MACH_AT2440EVB is not set
+CONFIG_MACH_AT2440EVB=y
 CONFIG_CPU_S3C2442=y
 
 #
@@ -286,25 +312,31 @@ CONFIG_ISA=y
 #
 # Kernel Features
 #
-# CONFIG_TICK_ONESHOT is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=200
 # CONFIG_AEABI is not set
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -317,6 +349,11 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/
 # CONFIG_KEXEC is not set
 
 #
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
 # Floating point emulation
 #
 
@@ -332,6 +369,8 @@ CONFIG_FPE_NWFPE_XP=y
 # 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 is not set
 # CONFIG_ARTHUR is not set
@@ -346,10 +385,6 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=m
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -359,11 +394,13 @@ CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_XFRM_USER=m
 # 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_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -372,15 +409,16 @@ 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_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST 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_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
@@ -388,8 +426,25 @@ 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_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
@@ -413,12 +468,181 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=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=m
+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=m
+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_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_IP_VS=m
+# CONFIG_IP_VS_IPV6 is not set
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+# CONFIG_IP_VS_PROTO_TCP is not set
+# CONFIG_IP_VS_PROTO_UDP is not set
+# CONFIG_IP_VS_PROTO_ESP is not set
+# CONFIG_IP_VS_PROTO_AH is not set
+
+#
+# IPVS scheduler
+#
+# CONFIG_IP_VS_RR is not set
+# CONFIG_IP_VS_WRR is not set
+# CONFIG_IP_VS_LC is not set
+# CONFIG_IP_VS_WLC is not set
+# CONFIG_IP_VS_LBLC is not set
+# CONFIG_IP_VS_LBLCR is not set
+# CONFIG_IP_VS_DH is not set
+# CONFIG_IP_VS_SH is not set
+# CONFIG_IP_VS_SED is not set
+# CONFIG_IP_VS_NQ is not set
+
+#
+# IPVS application helper
+#
+
+#
+# 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_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
@@ -428,8 +652,10 @@ CONFIG_IPV6_TUNNEL=m
 # 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_NET_SCH_FIFO=y
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -451,8 +677,8 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
+# 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
@@ -462,35 +688,26 @@ CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
 CONFIG_BT_HCIVHCI=m
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
-CONFIG_NL80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
 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_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=y
 CONFIG_MAC80211_LEDS=y
-# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
-# CONFIG_MAC80211_DEBUG is not set
-# CONFIG_IEEE80211 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
 
@@ -504,7 +721,9 @@ CONFIG_MAC80211_LEDS=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+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
@@ -513,6 +732,7 @@ 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=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
@@ -545,7 +765,7 @@ 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=y
+# 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
@@ -566,8 +786,6 @@ CONFIG_MTD_ROM=y
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_IMPA7 is not set
-CONFIG_MTD_BAST=y
-CONFIG_MTD_BAST_MAXSIZE=4
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -590,6 +808,7 @@ 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_IDS=y
 CONFIG_MTD_NAND_S3C2410=y
 # CONFIG_MTD_NAND_S3C2410_DEBUG is not set
@@ -602,6 +821,11 @@ CONFIG_MTD_NAND_S3C2410=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
@@ -620,7 +844,7 @@ CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_UB=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
@@ -628,32 +852,40 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=m
+CONFIG_EEPROM_AT25=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_93CX6=m
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_PLATFORM=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -699,6 +931,8 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -711,11 +945,13 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 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_HAVE_PATA_PLATFORM=y
 # 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
@@ -731,9 +967,14 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
-# CONFIG_ENC28J60 is not set
 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
@@ -742,11 +983,14 @@ CONFIG_DM9000_DEBUGLEVEL=4
 # 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_NET_POCKET is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
 
@@ -755,7 +999,10 @@ CONFIG_NETDEV_10000=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
@@ -778,7 +1025,7 @@ CONFIG_NETDEV_10000=y
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -789,7 +1036,7 @@ 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_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
@@ -808,20 +1055,88 @@ 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_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_BCM5974=m
 # 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_MOUSE_GPIO is not set
-# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+# CONFIG_JOYSTICK_IFORCE_USB is not set
+# CONFIG_JOYSTICK_IFORCE_232 is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
 # CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC 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_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_HTCPEN is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
+CONFIG_TOUCHSCREEN_USB_EGALAX=y
+CONFIG_TOUCHSCREEN_USB_PANJIT=y
+CONFIG_TOUCHSCREEN_USB_3M=y
+CONFIG_TOUCHSCREEN_USB_ITM=y
+CONFIG_TOUCHSCREEN_USB_ETURBO=y
+CONFIG_TOUCHSCREEN_USB_GUNZE=y
+CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
+CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
+CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
+CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
+CONFIG_TOUCHSCREEN_USB_GOTOP=y
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_ATI_REMOTE=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_CM109=m
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
 
 #
 # Hardware I/O ports
@@ -831,12 +1146,15 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 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
@@ -877,14 +1195,17 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
 # CONFIG_SERIAL_SAMSUNG_DEBUG is not set
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_S3C2410=y
 CONFIG_SERIAL_S3C2412=y
 CONFIG_SERIAL_S3C2440=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=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_PRINTER=y
@@ -892,7 +1213,7 @@ CONFIG_PRINTER=y
 CONFIG_PPDEV=y
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -901,33 +1222,44 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=y
 
 #
 # I2C Hardware Bus support
 #
-# CONFIG_I2C_ELEKTOR is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 CONFIG_I2C_S3C2410=y
 CONFIG_I2C_SIMTEC=y
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT is not set
+# 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_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_DS1682 is not set
-CONFIG_EEPROM_LEGACY=m
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 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
@@ -943,6 +1275,7 @@ CONFIG_SPI_MASTER=y
 #
 CONFIG_SPI_BITBANG=m
 # CONFIG_SPI_BUTTERFLY is not set
+CONFIG_SPI_GPIO=m
 # CONFIG_SPI_LM70_LLP is not set
 CONFIG_SPI_S3C24XX=m
 CONFIG_SPI_S3C24XX_GPIO=m
@@ -950,44 +1283,56 @@ CONFIG_SPI_S3C24XX_GPIO=m
 #
 # 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
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_TLE62X0=m
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
 
 #
-# GPIO Support
+# Memory mapped GPIO expanders:
 #
-# CONFIG_DEBUG_GPIO 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:
 #
+# 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=m
+# 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
@@ -1003,10 +1348,16 @@ CONFIG_SENSORS_LM85=m
 # 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
@@ -1022,7 +1373,10 @@ CONFIG_SENSORS_LM85=m
 # 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_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
 
@@ -1043,20 +1397,33 @@ CONFIG_S3C2410_WATCHDOG=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=y
+# CONFIG_MFD_SM501_GPIO 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_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 
 #
 # Multimedia devices
@@ -1065,14 +1432,189 @@ CONFIG_MFD_SM501=y
 #
 # Multimedia core support
 #
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
+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_DAB is not set
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMISE 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_MEDIA_TUNER_MXL5007T=m
+CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_VMALLOC=m
+CONFIG_VIDEO_TVEEPROM=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=m
+CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_VIDEO_AU0828=m
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+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_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX 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_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_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_CX231XX is not set
+# CONFIG_VIDEO_USBVISION 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_VIDEO_OVCAMCHIP 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=y
+CONFIG_RADIO_CADET=m
+CONFIG_RADIO_RTRACK=m
+CONFIG_RADIO_RTRACK2=m
+CONFIG_RADIO_AZTECH=m
+CONFIG_RADIO_GEMTEK=m
+CONFIG_RADIO_SF16FMI=m
+CONFIG_RADIO_SF16FMR2=m
+CONFIG_RADIO_TERRATEC=m
+CONFIG_RADIO_TRUST=m
+CONFIG_RADIO_TYPHOON=m
+CONFIG_RADIO_TYPHOON_PROC_FS=y
+CONFIG_RADIO_ZOLTRIX=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_SI470X=m
+CONFIG_USB_MR800=m
+CONFIG_RADIO_TEA5764=m
+CONFIG_DVB_DYNAMIC_MINORS=y
+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 is not set
+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 is not set
+# CONFIG_DVB_USB_AU6610 is not set
+# CONFIG_DVB_USB_DIGITV is not set
+# CONFIG_DVB_USB_VP7045 is not set
+# CONFIG_DVB_USB_VP702X is not set
+# CONFIG_DVB_USB_GP8PSK is not set
+# CONFIG_DVB_USB_NOVA_T_USB2 is not set
+# CONFIG_DVB_USB_TTUSB2 is not set
+# CONFIG_DVB_USB_DTT200U is not set
+# CONFIG_DVB_USB_OPERA1 is not set
+CONFIG_DVB_USB_AF9005=m
+# CONFIG_DVB_USB_AF9005_REMOTE is not set
+# 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_USB_CE6230 is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_TDA1004X=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_LGDT330X=m
+CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+CONFIG_DVB_LGS8GL5=m
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
 
 #
 # Graphics support
@@ -1082,6 +1624,7 @@ CONFIG_MFD_SM501=y
 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
@@ -1105,7 +1648,19 @@ CONFIG_FB_S3C2410=y
 # CONFIG_FB_S3C2410_DEBUG is not set
 CONFIG_FB_SM501=y
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT 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_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
+CONFIG_BACKLIGHT_PWM=m
 
 #
 # Display device support
@@ -1125,11 +1680,54 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 # CONFIG_LOGO is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_JACK=y
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y
+# 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 is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+# CONFIG_SND_USB_CAIAQ_INPUT is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_S3C24XX_SOC=y
+CONFIG_SND_S3C24XX_SOC_I2S=m
+CONFIG_SND_S3C_I2SV2_SOC=m
+CONFIG_SND_S3C2412_SOC_I2S=m
+CONFIG_SND_S3C2443_SOC_AC97=m
+CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m
+CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m
+CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m
+CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X=m
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AC97_CODEC=m
+CONFIG_SND_SOC_L3=m
+CONFIG_SND_SOC_UDA134X=m
+CONFIG_SND_SOC_WM8750=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
@@ -1139,12 +1737,12 @@ CONFIG_HID=y
 # USB Input Devices
 #
 # CONFIG_USB_HID is not set
+# CONFIG_HID_PID is not set
 
 #
-# USB HID Boot Protocol drivers
+# Special HID drivers
 #
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
+CONFIG_HID_APPLE=m
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1161,19 +1759,26 @@ CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND 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_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_U132_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
@@ -1181,53 +1786,51 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 CONFIG_USB_WDM=m
+# 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=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
-# 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_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=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
 CONFIG_USB_LIBUSUAL=y
 
 #
 # USB Imaging devices
 #
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
 
 #
 # USB port drivers
 #
-# CONFIG_USB_USS720 is not set
+CONFIG_USB_USS720=m
 CONFIG_USB_SERIAL=y
 # CONFIG_USB_SERIAL_CONSOLE is not set
 # CONFIG_USB_EZUSB is not set
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_AIRPRIME 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_CP2101 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
@@ -1251,42 +1854,71 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 CONFIG_USB_SERIAL_NAVMAN=m
 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=m
 # 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_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_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_BERRY_CHARGE=m
 CONFIG_USB_LED=m
-# 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_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
 CONFIG_USB_LD=m
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
-# CONFIG_MMC 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=m
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SPI=m
+CONFIG_MMC_S3C=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=m
 
@@ -1295,7 +1927,14 @@ CONFIG_LEDS_CLASS=m
 #
 CONFIG_LEDS_S3C24XX=m
 CONFIG_LEDS_H1940=m
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_PCA9532=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+CONFIG_LEDS_LP5521=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_DAC124S085=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_BD2802=m
 
 #
 # LED Triggers
@@ -1304,7 +1943,13 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 # CONFIG_LEDS_TRIGGER_IDE_DISK is not set
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+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_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1335,31 +1980,43 @@ 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
 
 #
 # 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_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_S3C=y
+# 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
@@ -1370,27 +2027,40 @@ 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 is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4_FS=m
+# CONFIG_EXT4DEV_COMPAT is not set
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+# CONFIG_EXT4_FS_SECURITY is not set
 CONFIG_JBD=y
+CONFIG_JBD2=m
 CONFIG_FS_MBCACHE=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_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 is not set
-# CONFIG_FUSE_FS is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
 CONFIG_GENERIC_ACL=y
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -1416,15 +2086,13 @@ CONFIG_NTFS_FS=m
 #
 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
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1444,27 +2112,49 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+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=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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD 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=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
-# CONFIG_CIFS 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
@@ -1546,6 +2236,11 @@ CONFIG_MAGIC_SYSRQ=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=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1565,14 +2260,39 @@ 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_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_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_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1586,19 +2306,29 @@ CONFIG_DEBUG_S3C_UART=0
 #
 # 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=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 is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1630,10 +2360,14 @@ CONFIG_CRYPTO_HMAC=m
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # 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 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1663,23 +2397,37 @@ CONFIG_CRYPTO_DES=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 is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/shannon_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/shannon_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/shannon_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/shannon_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/shark_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/shark_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/shark_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/shark_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,88 +1,174 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-git3
-# Sat Jul 16 15:21:47 2005
+# Linux kernel version: 2.6.28-git6
+# Thu Jan  8 17:14:47 2009
 #
 CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_MMU=y
-CONFIG_UID16=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"
 
 #
-# 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 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_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # 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_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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=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_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=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_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 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=y
-CONFIG_OBSOLETE_MODPARM=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_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_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_FREEZER is not set
 
 #
 # System Type
 #
-# CONFIG_ARCH_CLPS7500 is not set
+# 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_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_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_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=y
 # CONFIG_ARCH_LH7A40X 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_AAEC2000 is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
 
 #
 # Processor Type
@@ -91,14 +177,20 @@ CONFIG_CPU_32=y
 CONFIG_CPU_SA110=y
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_NOIFAR=y
 CONFIG_CPU_CACHE_V4WB=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_COPY_V4WB=y
 CONFIG_CPU_TLB_V4WB=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_OUTER_CACHE is not set
 
 #
 # Bus support
@@ -107,22 +199,40 @@ CONFIG_ISA=y
 CONFIG_ISA_DMA=y
 CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
 CONFIG_PCI_HOST_VIA82C505=y
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
 # Kernel Features
 #
-# CONFIG_SMP is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
-# CONFIG_DISCONTIGMEM is not set
+CONFIG_HZ=100
+# CONFIG_AEABI 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_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_RESOURCES_64BIT 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_UNEVICTABLE_LRU=y
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 # CONFIG_LEDS_CPU is not set
@@ -135,6 +245,12 @@ 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
@@ -143,13 +259,16 @@ CONFIG_CMDLINE=""
 #
 # At least one emulation must be selected
 #
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FPE_FASTFPE=y
+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
 # CONFIG_ARTHUR is not set
@@ -158,44 +277,104 @@ CONFIG_BINFMT_ELF=y
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
 
 #
-# Device Drivers
+# Networking options
 #
+# CONFIG_NET_NS is not set
+CONFIG_COMPAT_NET_DEV_OPS=y
+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 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_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_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_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
-# Generic Driver Options
+# Network testing
 #
-# CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
+# 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_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
-# Memory Technology Devices (MTD)
+# Device Drivers
 #
-# CONFIG_MTD is not set
 
 #
-# Parallel port support
+# Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# 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_PARPORT=m
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_ARC is not set
 # CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
 # CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
 # CONFIG_PNP is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
@@ -210,52 +389,78 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-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
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# 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
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# 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_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_SL82C105 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
 CONFIG_IDE_ARM=y
-# CONFIG_IDE_CHIPSETS 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=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -275,17 +480,20 @@ CONFIG_CHR_DEV_SG=m
 # 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 Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# 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_CXGB3_ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_7000FASST is not set
@@ -296,12 +504,18 @@ CONFIG_CHR_DEV_SG=m
 # 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_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
@@ -314,20 +528,15 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 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_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
@@ -336,123 +545,57 @@ CONFIG_SCSI_QLA2XXX=m
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
 # 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
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
-# I2O device support
+# Enable only one of the two stacks, unless you know what you are doing
 #
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
-
-#
-# Networking support
-#
-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_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=y
-# 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 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_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# 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_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
 # 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
@@ -462,56 +605,69 @@ CONFIG_NET_PCI=y
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_CS89x0=y
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
+CONFIG_CS89x0_NOEEPROM=y
 # 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 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_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 # CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# 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_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_SK98LIN is not set
+# CONFIG_SKY2 is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E 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
-
-#
-# Token Ring devices
-#
+# 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_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -519,18 +675,17 @@ CONFIG_CS89x0=y
 # 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
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 # 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
@@ -540,7 +695,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
 
@@ -553,14 +707,25 @@ CONFIG_KEYBOARD_ATKBD=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_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_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
 
@@ -580,16 +745,22 @@ CONFIG_SERIO_LIBPS2=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
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -599,90 +770,122 @@ 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=256
 CONFIG_PRINTER=m
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
-# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
 # CONFIG_NVRAM is not set
-CONFIG_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# 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_SPI 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
 
 #
-# TPM devices
+# Sonics Silicon Backplane
 #
-# CONFIG_TCG_TPM is not set
+# CONFIG_SSB is not set
 
 #
-# I2C support
+# Multifunction device drivers
 #
-# CONFIG_I2C 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
 
 #
-# Misc devices
+# Multimedia devices
 #
 
 #
-# Multimedia devices
+# Multimedia core support
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
-# Digital Video Broadcasting Devices
+# Multimedia drivers
 #
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_DRM is not set
+# 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_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 CONFIG_FB_CYBER2000=y
 # 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_OLD 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_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_S1D13XXX 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_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -691,126 +894,132 @@ CONFIG_FB_CYBER2000=y
 # 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 is not set
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
 # CONFIG_SND is not set
-
-#
-# Open Sound System
-#
 CONFIG_SOUND_PRIME=m
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
 CONFIG_SOUND_OSS=m
 # CONFIG_SOUND_TRACEINIT is not set
 # CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_AD1889 is not set
-# CONFIG_SOUND_SGALAXY is not set
-CONFIG_SOUND_ADLIB=m
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
 # CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
 # CONFIG_SOUND_VMIDI is not set
 # CONFIG_SOUND_TRIX is not set
 # CONFIG_SOUND_MSS is not set
 # CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
 # CONFIG_SOUND_PAS is not set
 # CONFIG_SOUND_PSS is not set
 CONFIG_SOUND_SB=m
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
 # CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
 # CONFIG_SOUND_UART6850 is not set
 # CONFIG_SOUND_AEDSP16 is not set
 # CONFIG_SOUND_KAHLUA is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 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
 
 #
-# USB support
+# Special HID drivers
 #
+CONFIG_HID_COMPAT=y
+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
 
 #
-# USB Gadget Support
+# Enable Host or Gadget support to see Inventra options
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
+# CONFIG_USB_GADGET is not set
+# CONFIG_UWB 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=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=y
+# 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_REGULATOR is not set
+# CONFIG_UIO 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_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
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # 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_DNOTIFY=y
+# 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
 
 #
 # CD-ROM/DVD Filesystems
@@ -834,14 +1043,12 @@ 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=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -855,22 +1062,27 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS 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=m
+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_LOCKD=m
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=m
+CONFIG_EXPORTFS=m
+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
@@ -897,11 +1109,9 @@ CONFIG_MSDOS_PARTITION=y
 # 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_SYSV68_PARTITION is not set
 CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
@@ -942,30 +1152,74 @@ CONFIG_NLS_ISO8859_1=m
 # 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_DEBUG_KERNEL=y
+# 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_LOG_BUF_SHIFT=14
+# 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_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_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_FS 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_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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_LL is not set
 
 #
@@ -973,19 +1227,23 @@ CONFIG_DEBUG_USER=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/simpad_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/simpad_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/simpad_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/simpad_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -89,7 +89,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_COLLIE is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
 # CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HACKKIT is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/viper_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/viper_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/viper_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/viper_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -298,7 +298,6 @@ 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_FREQ_PXA=y
 
 #
 # Floating point emulation
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/configs/xm_x2xx_defconfig linux-libre-2.6.30-gnu1/arch/arm/configs/xm_x2xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/arm/configs/xm_x2xx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/configs/xm_x2xx_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1806 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc8
-# Sun Oct  5 11:05:36 2008
-#
-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_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"
-
-#
-# 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 is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-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_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_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=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_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_VM_EVENT_COUNTERS is not set
-# CONFIG_SLUB_DEBUG is not set
-# 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 is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# 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 is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=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 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_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_CLASSIC_RCU=y
-
-#
-# 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_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX 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=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 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_MSM7X00A is not set
-CONFIG_DMABOUNCE=y
-
-#
-# Intel PXA2xx/PXA3xx Implementations
-#
-# CONFIG_ARCH_GUMSTIX 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_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_TRIZEPS_PXA is not set
-CONFIG_MACH_EM_X270=y
-# CONFIG_MACH_COLIBRI 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=y
-# CONFIG_MACH_CM_X300 is not set
-# CONFIG_MACH_MAGICIAN is not set
-# CONFIG_MACH_MIOA701 is not set
-# CONFIG_MACH_PCM027 is not set
-# CONFIG_ARCH_PXA_PALM is not set
-# CONFIG_PXA_EZX is not set
-CONFIG_PXA25x=y
-CONFIG_PXA27x=y
-CONFIG_PXA_SSP=y
-# CONFIG_PXA_PWM is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# 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_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_OUTER_CACHE is not set
-CONFIG_IWMMXT=y
-CONFIG_XSCALE_PMU=y
-
-#
-# Bus support
-#
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-CONFIG_PCI_HOST_ITE8152=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-CONFIG_CARDBUS=y
-
-#
-# PC-card bridges
-#
-CONFIG_YENTA=m
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-CONFIG_YENTA_TI=y
-# CONFIG_YENTA_ENE_TUNE is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
-CONFIG_PCMCIA_PXA2XX=m
-CONFIG_PCCARD_NONSTATIC=m
-
-#
-# Kernel Features
-#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-# 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 is not set
-CONFIG_HZ=100
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f03 mem=32M"
-# 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
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=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=m
-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 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_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
-# CONFIG_NET_SCHED 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 is not set
-CONFIG_BT_BNEP=m
-# CONFIG_BT_BNEP_MC_FILTER is not set
-# CONFIG_BT_BNEP_PROTO_FILTER is not set
-CONFIG_BT_HIDP=m
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-# CONFIG_BT_HCIBTUSB is not set
-# 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_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_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 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=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_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 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_OTP is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-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
-# 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=0x400000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-CONFIG_MTD_PXA2XX=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_SHARP_SL 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_H1900 is not set
-CONFIG_MTD_NAND_GPIO=m
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_SHARPSL is not set
-# CONFIG_MTD_NAND_CAFE is not set
-CONFIG_MTD_NAND_CM_X270=y
-# CONFIG_MTD_NAND_NANDSIM is not set
-CONFIG_MTD_NAND_PLATFORM=y
-# CONFIG_MTD_ALAUDA is not set
-# CONFIG_MTD_ONENAND 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=4096
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH 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
-
-#
-# 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_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 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_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_MVSAS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR 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
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_ATA=m
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_SATA_PMP is not set
-# 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_PCMCIA=m
-# 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
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# 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=y
-CONFIG_DM9000_DEBUGLEVEL=1
-# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
-# CONFIG_SMC911X 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_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 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 is not set
-# 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_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 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=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
-CONFIG_LIBERTAS=m
-# CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBERTAS_CS is not set
-CONFIG_LIBERTAS_SDIO=m
-# CONFIG_LIBERTAS_DEBUG is not set
-# CONFIG_HERMES 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_USB_NET_RNDIS_WLAN is not set
-# CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_HOSTAP 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_NET_PCMCIA is not set
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-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 is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
-# CONFIG_SLIP is not set
-CONFIG_SLHC=m
-# 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
-
-#
-# 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
-# CONFIG_INPUT_APMPOWER is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# 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_PXA27x=m
-# CONFIG_KEYBOARD_GPIO 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_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO 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_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=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 is not set
-# CONFIG_NOZOMI is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=16
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM 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_CHARDEV=m
-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_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
-
-#
-# 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_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
-# 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
-
-#
-# 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
-
-#
-# 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
-
-#
-# 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_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_UCB1400_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
-
-#
-# 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_DRM is not set
-# 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_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_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_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_PXA=y
-# CONFIG_FB_PXA_SMARTPANEL is not set
-CONFIG_FB_PXA_PARAMETERS=y
-CONFIG_FB_MBX=m
-# CONFIG_FB_W100 is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME 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_SND=m
-CONFIG_SND_TIMER=m
-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_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_VMASTER=y
-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_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_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_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_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_ARM=y
-CONFIG_SND_PXA2XX_PCM=m
-CONFIG_SND_PXA2XX_AC97=m
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_PCMCIA=y
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_PDAUDIOCF 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_HID_DEBUG=y
-# 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_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 is not set
-# CONFIG_USB_SUSPEND 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
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_EHCI_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_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
-
-#
-# 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_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
-# 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_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_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_GADGET is not set
-CONFIG_MMC=m
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
-
-#
-# MMC/SD Card Drivers
-#
-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
-#
-CONFIG_MMC_PXA=m
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_TIFM_SD is not set
-# CONFIG_MMC_SDRICOH_CS is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY 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_CM_X270=y
-# CONFIG_LEDS_PCA955X is not set
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGERS=y
-# CONFIG_LEDS_TRIGGER_TIMER is not set
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-# CONFIG_LEDS_TRIGGER_DEFAULT_ON 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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS 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_M48T59 is not set
-CONFIG_RTC_DRV_V3020=y
-
-#
-# on-CPU RTC drivers
-#
-CONFIG_RTC_DRV_SA1100=y
-# CONFIG_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_UIO 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_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_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_OCFS2_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 is not set
-# CONFIG_FUSE_FS 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_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_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 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_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=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 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=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=0
-# 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=y
-# CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_DETECT_SOFTLOCKUP is not set
-# 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_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 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_FRAME_POINTER=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-# 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_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_MANAGER 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_LZO is not set
-# CONFIG_CRYPTO_HW 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_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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/a.out.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/a.out.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/a.out.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/a.out.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
 #define __ARM_A_OUT_H__
 
 #include <linux/personality.h>
-#include <asm/types.h>
+#include <linux/types.h>
 
 struct exec
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/assembler.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/assembler.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/assembler.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/assembler.h	2009-06-09 23:05:27.000000000 -0400
@@ -114,3 +114,16 @@
 	.align	3;				\
 	.long	9999b,9001f;			\
 	.previous
+
+/*
+ * SMP data memory barrier
+ */
+	.macro	smp_dmb
+#ifdef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7
+	dmb
+#elif __LINUX_ARM_ARCH__ == 6
+	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+#endif
+#endif
+	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/atomic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,11 +44,29 @@ static inline void atomic_set(atomic_t *
 	: "cc");
 }
 
+static inline void atomic_add(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	__asm__ __volatile__("@ atomic_add\n"
+"1:	ldrex	%0, [%2]\n"
+"	add	%0, %0, %3\n"
+"	strex	%1, %0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
 static inline int atomic_add_return(int i, atomic_t *v)
 {
 	unsigned long tmp;
 	int result;
 
+	smp_mb();
+
 	__asm__ __volatile__("@ atomic_add_return\n"
 "1:	ldrex	%0, [%2]\n"
 "	add	%0, %0, %3\n"
@@ -59,14 +77,34 @@ static inline int atomic_add_return(int
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 
+	smp_mb();
+
 	return result;
 }
 
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	unsigned long tmp;
+	int result;
+
+	__asm__ __volatile__("@ atomic_sub\n"
+"1:	ldrex	%0, [%2]\n"
+"	sub	%0, %0, %3\n"
+"	strex	%1, %0, [%2]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp)
+	: "r" (&v->counter), "Ir" (i)
+	: "cc");
+}
+
 static inline int atomic_sub_return(int i, atomic_t *v)
 {
 	unsigned long tmp;
 	int result;
 
+	smp_mb();
+
 	__asm__ __volatile__("@ atomic_sub_return\n"
 "1:	ldrex	%0, [%2]\n"
 "	sub	%0, %0, %3\n"
@@ -77,6 +115,8 @@ static inline int atomic_sub_return(int
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 
+	smp_mb();
+
 	return result;
 }
 
@@ -84,6 +124,8 @@ static inline int atomic_cmpxchg(atomic_
 {
 	unsigned long oldval, res;
 
+	smp_mb();
+
 	do {
 		__asm__ __volatile__("@ atomic_cmpxchg\n"
 		"ldrex	%1, [%2]\n"
@@ -95,6 +137,8 @@ static inline int atomic_cmpxchg(atomic_
 		    : "cc");
 	} while (res);
 
+	smp_mb();
+
 	return oldval;
 }
 
@@ -135,6 +179,7 @@ static inline int atomic_add_return(int
 
 	return val;
 }
+#define atomic_add(i, v)	(void) atomic_add_return(i, v)
 
 static inline int atomic_sub_return(int i, atomic_t *v)
 {
@@ -148,6 +193,7 @@ static inline int atomic_sub_return(int
 
 	return val;
 }
+#define atomic_sub(i, v)	(void) atomic_sub_return(i, v)
 
 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
@@ -187,10 +233,8 @@ static inline int atomic_add_unless(atom
 }
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-#define atomic_add(i, v)	(void) atomic_add_return(i, v)
-#define atomic_inc(v)		(void) atomic_add_return(1, v)
-#define atomic_sub(i, v)	(void) atomic_sub_return(i, v)
-#define atomic_dec(v)		(void) atomic_sub_return(1, v)
+#define atomic_inc(v)		atomic_add(1, v)
+#define atomic_dec(v)		atomic_sub(1, v)
 
 #define atomic_inc_and_test(v)	(atomic_add_return(1, v) == 0)
 #define atomic_dec_and_test(v)	(atomic_sub_return(1, v) == 0)
@@ -200,11 +244,10 @@ static inline int atomic_add_unless(atom
 
 #define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
 
-/* Atomic operations are already serializing on ARM */
-#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.h>
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/cacheflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,14 @@
 # define MULTI_CACHE 1
 #endif
 
+#if defined(CONFIG_CPU_FA526)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE fa
+# endif
+#endif
+
 #if defined(CONFIG_CPU_ARM926T)
 # ifdef _CACHE
 #  define MULTI_CACHE 1
@@ -94,6 +102,14 @@
 # endif
 #endif
 
+#if defined(CONFIG_CPU_MOHAWK)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE mohawk
+# endif
+#endif
+
 #if defined(CONFIG_CPU_FEROCEON)
 # define MULTI_CACHE 1
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/cache.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,4 +7,20 @@
 #define L1_CACHE_SHIFT		5
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
+/*
+ * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
+ */
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define ARCH_SLAB_MINALIGN 8
+#endif
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,21 +19,17 @@
 #include <asm/system.h>
 #include <asm/scatterlist.h>
 
-typedef unsigned int dmach_t;
-
 #include <mach/isa-dma.h>
 
 /*
- * DMA modes
+ * The DMA modes reflect the settings for the ISA DMA controller
  */
-typedef unsigned int dmamode_t;
-
-#define DMA_MODE_MASK	3
+#define DMA_MODE_MASK	 0xcc
 
-#define DMA_MODE_READ	 0
-#define DMA_MODE_WRITE	 1
-#define DMA_MODE_CASCADE 2
-#define DMA_AUTOINIT	 4
+#define DMA_MODE_READ	 0x44
+#define DMA_MODE_WRITE	 0x48
+#define DMA_MODE_CASCADE 0xc0
+#define DMA_AUTOINIT	 0x10
 
 extern spinlock_t  dma_spin_lock;
 
@@ -52,44 +48,44 @@ static inline void release_dma_lock(unsi
 /* Clear the 'DMA Pointer Flip Flop'.
  * Write 0 for LSB/MSB, 1 for MSB/LSB access.
  */
-#define clear_dma_ff(channel)
+#define clear_dma_ff(chan)
 
 /* Set only the page register bits of the transfer address.
  *
  * NOTE: This is an architecture specific function, and should
  *       be hidden from the drivers
  */
-extern void set_dma_page(dmach_t channel, char pagenr);
+extern void set_dma_page(unsigned int chan, char pagenr);
 
 /* Request a DMA channel
  *
  * Some architectures may need to do allocate an interrupt
  */
-extern int  request_dma(dmach_t channel, const char * device_id);
+extern int  request_dma(unsigned int chan, const char * device_id);
 
 /* Free a DMA channel
  *
  * Some architectures may need to do free an interrupt
  */
-extern void free_dma(dmach_t channel);
+extern void free_dma(unsigned int chan);
 
 /* Enable DMA for this channel
  *
  * On some architectures, this may have other side effects like
  * enabling an interrupt and setting the DMA registers.
  */
-extern void enable_dma(dmach_t channel);
+extern void enable_dma(unsigned int chan);
 
 /* Disable DMA for this channel
  *
  * On some architectures, this may have other side effects like
  * disabling an interrupt or whatever.
  */
-extern void disable_dma(dmach_t channel);
+extern void disable_dma(unsigned int chan);
 
 /* Test whether the specified channel has an active DMA transfer
  */
-extern int dma_channel_active(dmach_t channel);
+extern int dma_channel_active(unsigned int chan);
 
 /* Set the DMA scatter gather list for this channel
  *
@@ -97,7 +93,7 @@ extern int dma_channel_active(dmach_t ch
  * especially since some DMA architectures don't update the
  * DMA address immediately, but defer it to the enable_dma().
  */
-extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
+extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
 
 /* Set the DMA address for this channel
  *
@@ -105,9 +101,9 @@ extern void set_dma_sg(dmach_t channel,
  * especially since some DMA architectures don't update the
  * DMA address immediately, but defer it to the enable_dma().
  */
-extern void __set_dma_addr(dmach_t channel, void *addr);
-#define set_dma_addr(channel, addr)				\
-	__set_dma_addr(channel, bus_to_virt(addr))
+extern void __set_dma_addr(unsigned int chan, void *addr);
+#define set_dma_addr(chan, addr)				\
+	__set_dma_addr(chan, bus_to_virt(addr))
 
 /* Set the DMA byte count for this channel
  *
@@ -115,7 +111,7 @@ extern void __set_dma_addr(dmach_t chann
  * especially since some DMA architectures don't update the
  * DMA count immediately, but defer it to the enable_dma().
  */
-extern void set_dma_count(dmach_t channel, unsigned long count);
+extern void set_dma_count(unsigned int chan, unsigned long count);
 
 /* Set the transfer direction for this channel
  *
@@ -124,11 +120,11 @@ extern void set_dma_count(dmach_t channe
  * DMA transfer direction immediately, but defer it to the
  * enable_dma().
  */
-extern void set_dma_mode(dmach_t channel, dmamode_t mode);
+extern void set_dma_mode(unsigned int chan, unsigned int mode);
 
 /* Set the transfer speed for this channel
  */
-extern void set_dma_speed(dmach_t channel, int cycle_ns);
+extern void set_dma_speed(unsigned int chan, int cycle_ns);
 
 /* Get DMA residue count. After a DMA transfer, this
  * should return zero. Reading this while a DMA transfer is
@@ -136,7 +132,7 @@ extern void set_dma_speed(dmach_t channe
  * If called before the channel has been used, it may return 1.
  * Otherwise, it returns the number of _bytes_ left to transfer.
  */
-extern int  get_dma_residue(dmach_t channel);
+extern int  get_dma_residue(unsigned int chan);
 
 #ifndef NO_DMA
 #define NO_DMA	255
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,10 +15,20 @@
  * 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));
 }
+#elif defined(__pfn_to_bus)
+static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+{
+	return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+}
+#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)
 {
@@ -57,6 +67,8 @@ static inline dma_addr_t virt_to_dma(str
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
 extern void dma_cache_maint(const void *kaddr, size_t size, int rw);
+extern void dma_cache_maint_page(struct page *page, unsigned long offset,
+				 size_t size, int rw);
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -316,7 +328,7 @@ static inline dma_addr_t dma_map_page(st
 	BUG_ON(!valid_dma_direction(dir));
 
 	if (!arch_is_coherent())
-		dma_cache_maint(page_address(page) + offset, size, dir);
+		dma_cache_maint_page(page, offset, size, dir);
 
 	return page_to_dma(dev, page) + offset;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/elf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,11 +45,15 @@ typedef struct user_fp elf_fpregset_t;
 #define EF_ARM_HASENTRY		0x00000002	/* All */
 #define EF_ARM_RELEXEC		0x00000001	/* All */
 
-#define R_ARM_NONE	0
-#define R_ARM_PC24	1
-#define R_ARM_ABS32	2
-#define R_ARM_CALL	28
-#define R_ARM_JUMP24	29
+#define R_ARM_NONE		0
+#define R_ARM_PC24		1
+#define R_ARM_ABS32		2
+#define R_ARM_CALL		28
+#define R_ARM_JUMP24		29
+#define R_ARM_V4BX		40
+#define R_ARM_PREL31		42
+#define R_ARM_MOVW_ABS_NC	43
+#define R_ARM_MOVT_ABS		44
 
 /*
  * These are used to set parameters in the core dumps.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/fixmap.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/fixmap.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/fixmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/fixmap.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+/*
+ * Nothing too fancy for now.
+ *
+ * On ARM we already have well known fixed virtual addresses imposed by
+ * the architecture such as the vector page which is located at 0xffff0000,
+ * therefore a second level page table is already allocated covering
+ * 0xfff00000 upwards.
+ *
+ * The cache flushing code in proc-xscale.S uses the virtual area between
+ * 0xfffe0000 and 0xfffeffff.
+ */
+
+#define FIXADDR_START		0xfff00000UL
+#define FIXADDR_TOP		0xfffe0000UL
+#define FIXADDR_SIZE		(FIXADDR_TOP - FIXADDR_START)
+
+#define FIX_KMAP_BEGIN		0
+#define FIX_KMAP_END		(FIXADDR_SIZE >> PAGE_SHIFT)
+
+#define __fix_to_virt(x)	(FIXADDR_START + ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)	(((x) - FIXADDR_START) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+	if (idx >= FIX_KMAP_END)
+		__this_fixmap_does_not_exist();
+	return __fix_to_virt(idx);
+}
+
+static inline unsigned int virt_to_fix(const unsigned long vaddr)
+{
+	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+	return __virt_to_fix(vaddr);
+}
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/flat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,9 +5,6 @@
 #ifndef __ARM_FLAT_H__
 #define __ARM_FLAT_H__
 
-/* An odd number of words will be pushed after this alignment, so
-   deliberately misalign the value.  */
-#define	flat_stack_align(sp)	sp = (void *)(((unsigned long)(sp) - 4) | 4)
 #define	flat_argvp_envp_on_stack()		1
 #define	flat_old_ram_flag(flags)		(flags)
 #define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/hardware/gic.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/hardware/gic.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/hardware/gic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/hardware/gic.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,7 @@
 void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
 void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
-void gic_raise_softirq(cpumask_t cpumask, unsigned int irq);
+void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
 #endif
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/hardware/scoop.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/hardware/scoop.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/hardware/scoop.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/hardware/scoop.h	2009-06-09 23:05:27.000000000 -0400
@@ -63,7 +63,5 @@ struct scoop_pcmcia_config {
 extern struct scoop_pcmcia_config *platform_scoop_config;
 
 void reset_scoop(struct device *dev);
-unsigned short __deprecated set_scoop_gpio(struct device *dev, unsigned short bit);
-unsigned short __deprecated reset_scoop_gpio(struct device *dev, unsigned short bit);
 unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
 void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/highmem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <asm/kmap_types.h>
+
+#define PKMAP_BASE		(PAGE_OFFSET - PMD_SIZE)
+#define LAST_PKMAP		PTRS_PER_PTE
+#define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
+#define PKMAP_NR(virt)		(((virt) - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define kmap_prot		PAGE_KERNEL
+
+#define flush_cache_kmaps()	flush_cache_all()
+
+extern pte_t *pkmap_page_table;
+
+#define ARCH_NEEDS_KMAP_HIGH_GET
+
+extern void *kmap_high(struct page *page);
+extern void *kmap_high_get(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *kmap_atomic(struct page *page, enum km_type type);
+extern void kunmap_atomic(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+extern struct page *kmap_atomic_to_page(const void *ptr);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/hwcap.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/hwcap.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/hwcap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/hwcap.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,8 @@
 #define HWCAP_CRUNCH	1024
 #define HWCAP_THUMBEE	2048
 #define HWCAP_NEON	4096
+#define HWCAP_VFPv3	8192
+#define HWCAP_VFPv3D16	16384
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/kmap_types.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
+	KM_L2_CACHE,
 	KM_TYPE_NR
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/mach/dma.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/mach/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/mach/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/mach/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,13 +15,13 @@ struct dma_struct;
 typedef struct dma_struct dma_t;
 
 struct dma_ops {
-	int	(*request)(dmach_t, dma_t *);		/* optional */
-	void	(*free)(dmach_t, dma_t *);		/* optional */
-	void	(*enable)(dmach_t, dma_t *);		/* mandatory */
-	void 	(*disable)(dmach_t, dma_t *);		/* mandatory */
-	int	(*residue)(dmach_t, dma_t *);		/* optional */
-	int	(*setspeed)(dmach_t, dma_t *, int);	/* optional */
-	char	*type;
+	int	(*request)(unsigned int, dma_t *);		/* optional */
+	void	(*free)(unsigned int, dma_t *);			/* optional */
+	void	(*enable)(unsigned int, dma_t *);		/* mandatory */
+	void 	(*disable)(unsigned int, dma_t *);		/* mandatory */
+	int	(*residue)(unsigned int, dma_t *);		/* optional */
+	int	(*setspeed)(unsigned int, dma_t *, int);	/* optional */
+	const char *type;
 };
 
 struct dma_struct {
@@ -34,24 +34,21 @@ struct dma_struct {
 	unsigned int	active:1;	/* Transfer active		*/
 	unsigned int	invalid:1;	/* Address/Count changed	*/
 
-	dmamode_t	dma_mode;	/* DMA mode			*/
+	unsigned int	dma_mode;	/* DMA mode			*/
 	int		speed;		/* DMA speed			*/
 
 	unsigned int	lock;		/* Device is allocated		*/
 	const char	*device_id;	/* Device name			*/
 
-	unsigned int	dma_base;	/* Controller base address	*/
-	int		dma_irq;	/* Controller IRQ		*/
-	struct scatterlist cur_sg;	/* Current controller buffer	*/
-	unsigned int	state;
-
-	struct dma_ops	*d_ops;
+	const struct dma_ops *d_ops;
 };
 
-/* Prototype: void arch_dma_init(dma)
- * Purpose  : Initialise architecture specific DMA
- * Params   : dma - pointer to array of DMA structures
+/*
+ * isa_dma_add - add an ISA-style DMA channel
  */
-extern void arch_dma_init(dma_t *dma);
+extern int isa_dma_add(unsigned int, dma_t *dma);
 
-extern void isa_init_dma(dma_t *dma);
+/*
+ * Add the ISA DMA controller.  Always takes channels 0-7.
+ */
+extern void isa_init_dma(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/mach/map.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/mach/map.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/mach/map.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/mach/map.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@ struct map_desc {
 #define MT_HIGH_VECTORS		8
 #define MT_MEMORY		9
 #define MT_ROM			10
+#define MT_MEMORY_NONCACHED	11
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/memory.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,14 +44,21 @@
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 32MB of the kernel text.
  */
-#define MODULES_END		(PAGE_OFFSET)
-#define MODULES_VADDR		(MODULES_END - 16*1048576)
-
+#define MODULES_VADDR		(PAGE_OFFSET - 16*1024*1024)
 #if TASK_SIZE > MODULES_VADDR
 #error Top of user space clashes with start of module space
 #endif
 
 /*
+ * The highmem pkmap virtual space shares the end of the module area.
+ */
+#ifdef CONFIG_HIGHMEM
+#define MODULES_END		(PAGE_OFFSET - PMD_SIZE)
+#else
+#define MODULES_END		(PAGE_OFFSET)
+#endif
+
+/*
  * The XIP kernel gets mapped at the bottom of the module vm area.
  * Since we use sections to map it, this macro replaces the physical address
  * with its virtual address while keeping offset from the base section.
@@ -181,6 +188,7 @@ 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)
 #endif
 
 static inline __deprecated unsigned long virt_to_bus(void *x)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/module.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/module.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,15 +1,27 @@
 #ifndef _ASM_ARM_MODULE_H
 #define _ASM_ARM_MODULE_H
 
-struct mod_arch_specific
-{
-	int foo;
-};
-
 #define Elf_Shdr	Elf32_Shdr
 #define Elf_Sym		Elf32_Sym
 #define Elf_Ehdr	Elf32_Ehdr
 
+struct unwind_table;
+
+struct mod_arch_specific
+{
+#ifdef CONFIG_ARM_UNWIND
+	Elf_Shdr *unw_sec_init;
+	Elf_Shdr *unw_sec_devinit;
+	Elf_Shdr *unw_sec_core;
+	Elf_Shdr *sec_init_text;
+	Elf_Shdr *sec_devinit_text;
+	Elf_Shdr *sec_core_text;
+	struct unwind_table *unwind_init;
+	struct unwind_table *unwind_devinit;
+	struct unwind_table *unwind_core;
+#endif
+};
+
 /*
  * Include the ARM architecture version.
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/page.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -76,6 +76,14 @@
 # endif
 #endif
 
+#ifdef CONFIG_CPU_COPY_FA
+# ifdef _USER
+#  define MULTI_USER 1
+# else
+#  define _USER fa
+# endif
+#endif
+
 #ifdef CONFIG_CPU_SA1100
 # ifdef _USER
 #  define MULTI_USER 1
@@ -194,13 +202,6 @@ typedef struct page *pgtable_t;
 	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
 	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-/*
- * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
- */
-#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
-#define ARCH_SLAB_MINALIGN 8
-#endif
-
 #include <asm-generic/page.h>
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/proc-fns.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/proc-fns.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/proc-fns.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/proc-fns.h	2009-06-09 23:05:27.000000000 -0400
@@ -89,6 +89,14 @@
 #   define CPU_NAME cpu_arm922
 #  endif
 # 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_ARM925T
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
@@ -185,6 +193,14 @@
 #   define CPU_NAME cpu_xsc3
 #  endif
 # 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_FEROCEON
 #  ifdef CPU_NAME
 #   undef  MULTI_CPU
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,8 @@
 /* PTRACE_SYSCALL is 24 */
 #define PTRACE_GETCRUNCHREGS	25
 #define PTRACE_SETCRUNCHREGS	26
+#define PTRACE_GETVFPREGS	27
+#define PTRACE_SETVFPREGS	28
 
 /*
  * PSR bits
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/setup.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,7 @@
 #ifndef __ASMARM_SETUP_H
 #define __ASMARM_SETUP_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 
 #define COMMAND_LINE_SIZE 1024
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/sizes.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/sizes.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/sizes.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/sizes.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #define SZ_4K                           0x00001000
 #define SZ_8K                           0x00002000
 #define SZ_16K                          0x00004000
+#define SZ_32K                          0x00008000
 #define SZ_64K                          0x00010000
 #define SZ_128K                         0x00020000
 #define SZ_256K                         0x00040000
@@ -43,6 +44,7 @@
 #define SZ_8M                           0x00800000
 #define SZ_16M                          0x01000000
 #define SZ_32M                          0x02000000
+#define SZ_48M                          0x03000000
 #define SZ_64M                          0x04000000
 #define SZ_128M                         0x08000000
 #define SZ_256M                         0x10000000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned
 /*
  * Raise an IPI cross call on CPUs in callmap.
  */
-extern void smp_cross_call(cpumask_t callmap);
-
-/*
- * Broadcast a timer interrupt to the other CPUs.
- */
-extern void smp_send_timer(void);
+extern void smp_cross_call(const struct cpumask *mask);
 
 /*
  * Broadcast a clock event to other CPUs.
  */
-extern void smp_timer_broadcast(cpumask_t mask);
+extern void smp_timer_broadcast(const struct cpumask *mask);
 
 /*
  * Boot a secondary CPU, and assign it the specified idle task.
@@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned in
 extern void platform_cpu_enable(unsigned int cpu);
 
 extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
 
 /*
  * Local timer interrupt handling function (can be IPI'ed).
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -217,6 +217,9 @@ static inline int __raw_read_trylock(raw
 /* read_can_lock - would read_trylock() succeed? */
 #define __raw_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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/stacktrace.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/stacktrace.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/stacktrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/stacktrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+#ifndef __ASM_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+struct stackframe {
+	unsigned long fp;
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long pc;
+};
+
+extern int unwind_frame(struct stackframe *frame);
+extern void walk_stackframe(struct stackframe *frame,
+			    int (*fn)(struct stackframe *, void *), void *data);
+
+#endif	/* __ASM_STACKTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #define __ASM_ARM_SWAB_H
 
 #include <linux/compiler.h>
-#include <asm/types.h>
+#include <linux/types.h>
 
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __SWAB_64_THRU_32__
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/system.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,8 +97,8 @@ extern void __show_regs(struct pt_regs *
 extern int cpu_architecture(void);
 extern void cpu_init(void);
 
-void arm_machine_restart(char mode);
-extern void (*arm_pm_restart)(char str);
+void arm_machine_restart(char mode, const char *cmd);
+extern void (*arm_pm_restart)(char str, const char *cmd);
 
 #define UDBG_UNDEFINED	(1 << 0)
 #define UDBG_SYSCALL	(1 << 1)
@@ -125,6 +125,12 @@ extern unsigned int user_debug;
 				    : : "r" (0) : "memory")
 #define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
 				    : : "r" (0) : "memory")
+#elif defined(CONFIG_CPU_FA526)
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+				    : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+				    : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
 #else
 #define isb() __asm__ __volatile__ ("" : : : "memory")
 #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
@@ -242,6 +248,8 @@ static inline unsigned long __xchg(unsig
 	unsigned int tmp;
 #endif
 
+	smp_mb();
+
 	switch (size) {
 #if __LINUX_ARM_ARCH__ >= 6
 	case 1:
@@ -301,6 +309,7 @@ static inline unsigned long __xchg(unsig
 		__bad_xchg(ptr, size), ret = 0;
 		break;
 	}
+	smp_mb();
 
 	return ret;
 }
@@ -310,6 +319,12 @@ extern void enable_hlt(void);
 
 #include <asm-generic/cmpxchg-local.h>
 
+#if __LINUX_ARM_ARCH__ < 6
+
+#ifdef CONFIG_SMP
+#error "SMP is not supported on this platform"
+#endif
+
 /*
  * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
  * them available.
@@ -323,6 +338,173 @@ extern void enable_hlt(void);
 #include <asm-generic/cmpxchg.h>
 #endif
 
+#else	/* __LINUX_ARM_ARCH__ >= 6 */
+
+extern void __bad_cmpxchg(volatile void *ptr, int size);
+
+/*
+ * cmpxchg only support 32-bits operands on ARMv6.
+ */
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+				      unsigned long new, int size)
+{
+	unsigned long oldval, res;
+
+	switch (size) {
+#ifdef CONFIG_CPU_32v6K
+	case 1:
+		do {
+			asm volatile("@ __cmpxchg1\n"
+			"	ldrexb	%1, [%2]\n"
+			"	mov	%0, #0\n"
+			"	teq	%1, %3\n"
+			"	strexbeq %0, %4, [%2]\n"
+				: "=&r" (res), "=&r" (oldval)
+				: "r" (ptr), "Ir" (old), "r" (new)
+				: "memory", "cc");
+		} while (res);
+		break;
+	case 2:
+		do {
+			asm volatile("@ __cmpxchg1\n"
+			"	ldrexh	%1, [%2]\n"
+			"	mov	%0, #0\n"
+			"	teq	%1, %3\n"
+			"	strexheq %0, %4, [%2]\n"
+				: "=&r" (res), "=&r" (oldval)
+				: "r" (ptr), "Ir" (old), "r" (new)
+				: "memory", "cc");
+		} while (res);
+		break;
+#endif /* CONFIG_CPU_32v6K */
+	case 4:
+		do {
+			asm volatile("@ __cmpxchg4\n"
+			"	ldrex	%1, [%2]\n"
+			"	mov	%0, #0\n"
+			"	teq	%1, %3\n"
+			"	strexeq %0, %4, [%2]\n"
+				: "=&r" (res), "=&r" (oldval)
+				: "r" (ptr), "Ir" (old), "r" (new)
+				: "memory", "cc");
+		} while (res);
+		break;
+	default:
+		__bad_cmpxchg(ptr, size);
+		oldval = 0;
+	}
+
+	return oldval;
+}
+
+static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+					 unsigned long new, int size)
+{
+	unsigned long ret;
+
+	smp_mb();
+	ret = __cmpxchg(ptr, old, new, size);
+	smp_mb();
+
+	return ret;
+}
+
+#define cmpxchg(ptr,o,n)						\
+	((__typeof__(*(ptr)))__cmpxchg_mb((ptr),			\
+					  (unsigned long)(o),		\
+					  (unsigned long)(n),		\
+					  sizeof(*(ptr))))
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+					    unsigned long old,
+					    unsigned long new, int size)
+{
+	unsigned long ret;
+
+	switch (size) {
+#ifndef CONFIG_CPU_32v6K
+	case 1:
+	case 2:
+		ret = __cmpxchg_local_generic(ptr, old, new, size);
+		break;
+#endif	/* !CONFIG_CPU_32v6K */
+	default:
+		ret = __cmpxchg(ptr, old, new, size);
+	}
+
+	return ret;
+}
+
+#define cmpxchg_local(ptr,o,n)						\
+	((__typeof__(*(ptr)))__cmpxchg_local((ptr),			\
+				       (unsigned long)(o),		\
+				       (unsigned long)(n),		\
+				       sizeof(*(ptr))))
+
+#ifdef CONFIG_CPU_32v6K
+
+/*
+ * Note : ARMv7-M (currently unsupported by Linux) does not support
+ * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
+ * not be allowed to use __cmpxchg64.
+ */
+static inline unsigned long long __cmpxchg64(volatile void *ptr,
+					     unsigned long long old,
+					     unsigned long long new)
+{
+	register unsigned long long oldval asm("r0");
+	register unsigned long long __old asm("r2") = old;
+	register unsigned long long __new asm("r4") = new;
+	unsigned long res;
+
+	do {
+		asm volatile(
+		"	@ __cmpxchg8\n"
+		"	ldrexd	%1, %H1, [%2]\n"
+		"	mov	%0, #0\n"
+		"	teq	%1, %3\n"
+		"	teqeq	%H1, %H3\n"
+		"	strexdeq %0, %4, %H4, [%2]\n"
+			: "=&r" (res), "=&r" (oldval)
+			: "r" (ptr), "Ir" (__old), "r" (__new)
+			: "memory", "cc");
+	} while (res);
+
+	return oldval;
+}
+
+static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
+						unsigned long long old,
+						unsigned long long new)
+{
+	unsigned long long ret;
+
+	smp_mb();
+	ret = __cmpxchg64(ptr, old, new);
+	smp_mb();
+
+	return ret;
+}
+
+#define cmpxchg64(ptr,o,n)						\
+	((__typeof__(*(ptr)))__cmpxchg64_mb((ptr),			\
+					    (unsigned long long)(o),	\
+					    (unsigned long long)(n)))
+
+#define cmpxchg64_local(ptr,o,n)					\
+	((__typeof__(*(ptr)))__cmpxchg64((ptr),				\
+					 (unsigned long long)(o),	\
+					 (unsigned long long)(n)))
+
+#else	/* !CONFIG_CPU_32v6K */
+
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif	/* CONFIG_CPU_32v6K */
+
+#endif	/* __LINUX_ARM_ARCH__ >= 6 */
+
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/thread_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -99,6 +99,8 @@ static inline struct thread_info *curren
 
 #define thread_saved_pc(tsk)	\
 	((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
+#define thread_saved_sp(tsk)	\
+	((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
 #define thread_saved_fp(tsk)	\
 	((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
 
@@ -113,6 +115,8 @@ extern void iwmmxt_task_restore(struct t
 extern void iwmmxt_task_release(struct thread_info *);
 extern void iwmmxt_task_switch(struct thread_info *);
 
+extern void vfp_sync_state(struct thread_info *thread);
+
 #endif
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/tlbflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,7 @@
 #define TLB_V6_D_ASID	(1 << 17)
 #define TLB_V6_I_ASID	(1 << 18)
 
+#define TLB_BTB		(1 << 28)
 #define TLB_L2CLEAN_FR	(1 << 29)		/* Feroceon */
 #define TLB_DCLEAN	(1 << 30)
 #define TLB_WB		(1 << 31)
@@ -53,6 +54,7 @@
  *	  v4wb  - ARMv4 with write buffer without I TLB flush entry instruction
  *	  v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
  *	  fr    - Feroceon (v4wbi with non-outer-cacheable page table walks)
+ *	  fa    - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB))
  *	  v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
  *	  v7wbi - identical to v6wbi
  */
@@ -89,6 +91,22 @@
 # define v4_always_flags	(-1UL)
 #endif
 
+#define fa_tlb_flags	(TLB_WB | TLB_BTB | TLB_DCLEAN | \
+			 TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#ifdef CONFIG_CPU_TLB_FA
+# define fa_possible_flags	fa_tlb_flags
+# define fa_always_flags	fa_tlb_flags
+# ifdef _TLB
+#  define MULTI_TLB 1
+# else
+#  define _TLB fa
+# endif
+#else
+# define fa_possible_flags	0
+# define fa_always_flags	(-1UL)
+#endif
+
 #define v4wbi_tlb_flags	(TLB_WB | TLB_DCLEAN | \
 			 TLB_V4_I_FULL | TLB_V4_D_FULL | \
 			 TLB_V4_I_PAGE | TLB_V4_D_PAGE)
@@ -140,7 +158,7 @@
 # define v4wb_always_flags	(-1UL)
 #endif
 
-#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
+#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
 			 TLB_V6_I_FULL | TLB_V6_D_FULL | \
 			 TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
 			 TLB_V6_I_ASID | TLB_V6_D_ASID)
@@ -267,6 +285,7 @@ extern struct cpu_tlb_fns cpu_tlb;
 				 v4wbi_possible_flags | \
 				 fr_possible_flags | \
 				 v4wb_possible_flags | \
+				 fa_possible_flags | \
 				 v6wbi_possible_flags | \
 				 v7wbi_possible_flags)
 
@@ -275,6 +294,7 @@ extern struct cpu_tlb_fns cpu_tlb;
 				 v4wbi_always_flags & \
 				 fr_always_flags & \
 				 v4wb_always_flags & \
+				 fa_always_flags & \
 				 v6wbi_always_flags & \
 				 v7wbi_always_flags)
 
@@ -297,9 +317,7 @@ static inline void local_flush_tlb_all(v
 	if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
 		asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 
-	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
-		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
-		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
@@ -334,9 +352,7 @@ static inline void local_flush_tlb_mm(st
 	if (tlb_flag(TLB_V6_I_ASID))
 		asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
 
-	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
-		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
-		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
@@ -374,9 +390,7 @@ local_flush_tlb_page(struct vm_area_stru
 	if (tlb_flag(TLB_V6_I_PAGE))
 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
 
-	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
-		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
-		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
@@ -411,9 +425,7 @@ static inline void local_flush_tlb_kerne
 	if (tlb_flag(TLB_V6_I_PAGE))
 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
 
-	if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
-		     TLB_V6_I_PAGE | TLB_V6_D_PAGE |
-		     TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
 		asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
 		dsb();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/tlb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,8 @@
 struct mmu_gather {
 	struct mm_struct	*mm;
 	unsigned int		fullmm;
+	unsigned long		range_start;
+	unsigned long		range_end;
 };
 
 DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -63,7 +65,19 @@ tlb_finish_mmu(struct mmu_gather *tlb, u
 	put_cpu_var(mmu_gathers);
 }
 
-#define tlb_remove_tlb_entry(tlb,ptep,address)	do { } while (0)
+/*
+ * Memorize the range for the TLB flush.
+ */
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
+{
+	if (!tlb->fullmm) {
+		if (addr < tlb->range_start)
+			tlb->range_start = addr;
+		if (addr + PAGE_SIZE > tlb->range_end)
+			tlb->range_end = addr + PAGE_SIZE;
+	}
+}
 
 /*
  * In the case of tlb vma handling, we can optimise these away in the
@@ -73,15 +87,18 @@ tlb_finish_mmu(struct mmu_gather *tlb, u
 static inline void
 tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
 {
-	if (!tlb->fullmm)
+	if (!tlb->fullmm) {
 		flush_cache_range(vma, vma->vm_start, vma->vm_end);
+		tlb->range_start = TASK_SIZE;
+		tlb->range_end = 0;
+	}
 }
 
 static inline void
 tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
 {
-	if (!tlb->fullmm)
-		flush_tlb_range(vma, vma->vm_start, vma->vm_end);
+	if (!tlb->fullmm && tlb->range_end > 0)
+		flush_tlb_range(vma, tlb->range_start, tlb->range_end);
 }
 
 #define tlb_remove_page(tlb,page)	free_page_and_swap_cache(page)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/traps.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/traps.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/traps.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/traps.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,5 +25,6 @@ static inline int in_exception_text(unsi
 }
 
 extern void __init early_trap_init(void);
+extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -387,6 +387,8 @@
 #define __NR_dup3			(__NR_SYSCALL_BASE+358)
 #define __NR_pipe2			(__NR_SYSCALL_BASE+359)
 #define __NR_inotify_init1		(__NR_SYSCALL_BASE+360)
+#define __NR_preadv			(__NR_SYSCALL_BASE+361)
+#define __NR_pwritev			(__NR_SYSCALL_BASE+362)
 
 /*
  * The following SWIs are ARM private.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/unwind.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/unwind.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/unwind.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/unwind.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/include/asm/unwind.h
+ *
+ * Copyright (C) 2008 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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_UNWIND_H
+#define __ASM_UNWIND_H
+
+#ifndef __ASSEMBLY__
+
+/* Unwind reason code according the the ARM EABI documents */
+enum unwind_reason_code {
+	URC_OK = 0,			/* operation completed successfully */
+	URC_CONTINUE_UNWIND = 8,
+	URC_FAILURE = 9			/* unspecified failure of some kind */
+};
+
+struct unwind_idx {
+	unsigned long addr;
+	unsigned long insn;
+};
+
+struct unwind_table {
+	struct list_head list;
+	struct unwind_idx *start;
+	struct unwind_idx *stop;
+	unsigned long begin_addr;
+	unsigned long end_addr;
+};
+
+extern struct unwind_table *unwind_table_add(unsigned long start,
+					     unsigned long size,
+					     unsigned long text_addr,
+					     unsigned long text_size);
+extern void unwind_table_del(struct unwind_table *tab);
+extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk);
+
+#ifdef CONFIG_ARM_UNWIND
+extern int __init unwind_init(void);
+#else
+static inline int __init unwind_init(void)
+{
+	return 0;
+}
+#endif
+
+#endif	/* !__ASSEMBLY__ */
+
+#ifdef CONFIG_ARM_UNWIND
+#define UNWIND(code...)		code
+#else
+#define UNWIND(code...)
+#endif
+
+#endif	/* __ASM_UNWIND_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/include/asm/user.h linux-libre-2.6.30-gnu1/arch/arm/include/asm/user.h
--- linux-libre-2.6.29-gnu1/arch/arm/include/asm/user.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/include/asm/user.h	2009-06-09 23:05:27.000000000 -0400
@@ -81,4 +81,13 @@ struct user{
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
 
+/*
+ * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
+ * are ignored by the ptrace system call.
+ */
+struct user_vfp {
+	unsigned long long fpregs[32];
+	unsigned long fpscr;
+};
+
 #endif /* _ARM_USER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/Kconfig linux-libre-2.6.30-gnu1/arch/arm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -241,6 +241,7 @@ config ARCH_VERSATILE
 config ARCH_AT91
 	bool "Atmel AT91"
 	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
 	help
 	  This enables support for systems based on the Atmel AT91RM9200,
@@ -272,9 +273,18 @@ config ARCH_EP93XX
 	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
+config ARCH_GEMINI
+	bool "Cortina Systems Gemini"
+	select CPU_FA526
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  Support for the Cortina Systems Gemini family SoCs
+
 config ARCH_FOOTBRIDGE
 	bool "FootBridge"
 	select CPU_SA110
@@ -445,6 +455,7 @@ config ARCH_MXC
 	select ARCH_MTD_XIP
 	select GENERIC_GPIO
 	select ARCH_REQUIRE_GPIOLIB
+	select HAVE_CLK
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
@@ -480,9 +491,24 @@ config ARCH_PXA
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select TICK_ONESHOT
+	select PLAT_PXA
 	help
 	  Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
 
+config ARCH_MMP
+	bool "Marvell PXA168/910"
+	depends on MMU
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select TICK_ONESHOT
+	select PLAT_PXA
+	help
+	  Support for Marvell's PXA168/910 processor line.
+
 config ARCH_RPC
 	bool "RiscPC"
 	select ARCH_ACORN
@@ -559,6 +585,8 @@ config ARCH_DAVINCI
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
 	select ZONE_DMA
+	select HAVE_IDE
+	select COMMON_CLKDEV
 	help
 	  Support for TI's DaVinci platform.
 
@@ -598,6 +626,8 @@ source "arch/arm/mach-ep93xx/Kconfig"
 
 source "arch/arm/mach-footbridge/Kconfig"
 
+source "arch/arm/mach-gemini/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
 source "arch/arm/mach-iop32x/Kconfig"
@@ -617,6 +647,9 @@ source "arch/arm/mach-loki/Kconfig"
 source "arch/arm/mach-mv78xx0/Kconfig"
 
 source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
+
+source "arch/arm/mach-mmp/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
 
@@ -686,12 +719,15 @@ config PLAT_IOP
 config PLAT_ORION
 	bool
 
+config PLAT_PXA
+	bool
+
 source arch/arm/mm/Kconfig
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3
-	default y if PXA27x || PXA3xx
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+	default y if PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
@@ -706,6 +742,56 @@ if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
 
+config ARM_ERRATA_411920
+	bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
+	depends on CPU_V6 && !SMP
+	help
+	  Invalidation of the Instruction Cache operation can
+	  fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
+	  It does not affect the MPCore. This option enables the ARM Ltd.
+	  recommended workaround.
+
+config ARM_ERRATA_430973
+	bool "ARM errata: Stale prediction on replaced interworking branch"
+	depends on CPU_V7
+	help
+	  This option enables the workaround for the 430973 Cortex-A8
+	  (r1p0..r1p2) erratum. If a code sequence containing an ARM/Thumb
+	  interworking branch is replaced with another code sequence at the
+	  same virtual address, whether due to self-modifying code or virtual
+	  to physical address re-mapping, Cortex-A8 does not recover from the
+	  stale interworking branch prediction. This results in Cortex-A8
+	  executing the new code sequence in the incorrect ARM or Thumb state.
+	  The workaround enables the BTB/BTAC operations by setting ACTLR.IBE
+	  and also flushes the branch target cache at every context switch.
+	  Note that setting specific bits in the ACTLR register may not be
+	  available in non-secure mode.
+
+config ARM_ERRATA_458693
+	bool "ARM errata: Processor deadlock when a false hazard is created"
+	depends on CPU_V7
+	help
+	  This option enables the workaround for the 458693 Cortex-A8 (r2p0)
+	  erratum. For very specific sequences of memory operations, it is
+	  possible for a hazard condition intended for a cache line to instead
+	  be incorrectly associated with a different cache line. This false
+	  hazard might then cause a processor deadlock. The workaround enables
+	  the L1 caching of the NEON accesses and disables the PLD instruction
+	  in the ACTLR register. Note that setting specific bits in the ACTLR
+	  register may not be available in non-secure mode.
+
+config ARM_ERRATA_460075
+	bool "ARM errata: Data written to the L2 cache can be overwritten with stale data"
+	depends on CPU_V7
+	help
+	  This option enables the workaround for the 460075 Cortex-A8 (r2p0)
+	  erratum. Any asynchronous access to the L2 cache may encounter a
+	  situation in which recent store transactions to the L2 cache are lost
+	  and overwritten with stale memory contents from external memory. The
+	  workaround disables the write-allocate mode for the L2 cache via the
+	  ACTLR register. Note that setting specific bits in the ACTLR register
+	  may not be available in non-secure mode.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -891,10 +977,9 @@ config OABI_COMPAT
 	  UNPREDICTABLE (in fact it can be predicted that it won't work
 	  at all). If in doubt say Y.
 
-config ARCH_FLATMEM_HAS_HOLES
+config ARCH_HAS_HOLES_MEMORYMODEL
 	bool
-	default y
-	depends on FLATMEM
+	default n
 
 # Discontigmem is deprecated
 config ARCH_DISCONTIGMEM_ENABLE
@@ -915,6 +1000,23 @@ config NODES_SHIFT
 	default "2"
 	depends on NEED_MULTIPLE_NODES
 
+config HIGHMEM
+	bool "High Memory Support (EXPERIMENTAL)"
+	depends on MMU && EXPERIMENTAL
+	help
+	  The address space of ARM processors is only 4 Gigabytes large
+	  and it has to accommodate user address space, kernel address
+	  space as well as some memory mapped IO. That means that, if you
+	  have a large amount of physical memory and/or IO, not all of the
+	  memory can be "permanently mapped" by the kernel. The physical
+	  memory that is not permanently mapped is called "high memory".
+
+	  Depending on the selected kernel/user memory split, minimum
+	  vmalloc space and actual amount of RAM, you may not need this
+	  option which should result in a slightly faster kernel.
+
+	  If unsure, say n.
+
 source "mm/Kconfig"
 
 config LEDS
@@ -1092,7 +1194,7 @@ source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_SA1100
 	bool
-	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
+	depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
 	default y
 
 config CPU_FREQ_SA1110
@@ -1120,12 +1222,6 @@ config CPU_FREQ_IMX
 
 	  If in doubt, say N.
 
-config CPU_FREQ_PXA
-	bool
-	depends on CPU_FREQ && ARCH_PXA && PXA25x
-	default y
-	select CPU_FREQ_DEFAULT_GOV_USERSPACE
-
 endif
 
 source "drivers/cpuidle/Kconfig"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/Kconfig.debug linux-libre-2.6.30-gnu1/arch/arm/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/arm/Kconfig.debug	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -2,18 +2,29 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-# RMK wants arm kernels compiled with frame pointers so hardwire this to y.
+# RMK wants arm kernels compiled with frame pointers or stack unwinding.
 # If you know what you are doing and are willing to live without stack
 # traces, you can get a slightly smaller kernel by setting this option to
 # n, but then RMK will have to kill you ;).
 config FRAME_POINTER
 	bool
-	default y
+	default y if !ARM_UNWIND
 	help
 	  If you say N here, the resulting kernel will be slightly smaller and
-	  faster. However, when a problem occurs with the kernel, the
-	  information that is reported is severely limited. Most people
-	  should say Y here.
+	  faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
+	  when a problem occurs with the kernel, the information that is
+	  reported is severely limited.
+
+config ARM_UNWIND
+	bool "Enable stack unwinding support"
+	depends on AEABI && EXPERIMENTAL
+	default y
+	help
+	  This option enables stack unwinding support in the kernel
+	  using the information automatically generated by the
+	  compiler. The resulting kernel image is slightly bigger but
+	  the performance is not affected. Currently, this feature
+	  only works with EABI compilers. If unsure say Y.
 
 config DEBUG_USER
 	bool "Verbose user fault messages"
@@ -66,7 +77,7 @@ config DEBUG_ICEDCC
 	  Say Y here if you want the debug print routines to direct their
 	  output to the EmbeddedICE macrocell's DCC channel using
 	  co-processor 14. This is known to work on the ARM9 style ICE
-	  channel.
+	  channel and on the XScale with the PEEDI.
 
 	  It does include a timeout to ensure that the system does not
 	  totally freeze when there is nothing connected to read.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/calls.S linux-libre-2.6.30-gnu1/arch/arm/kernel/calls.S
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/calls.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/calls.S	2009-06-09 23:05:27.000000000 -0400
@@ -370,6 +370,8 @@
 		CALL(sys_dup3)
 		CALL(sys_pipe2)
 /* 360 */	CALL(sys_inotify_init1)
+		CALL(sys_preadv)
+		CALL(sys_pwritev)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/debug.S linux-libre-2.6.30-gnu1/arch/arm/kernel/debug.S
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/debug.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/debug.S	2009-06-09 23:05:27.000000000 -0400
@@ -49,6 +49,33 @@
 1002:
 		.endm
 
+#elif defined(CONFIG_CPU_XSCALE)
+
+		.macro	addruart, rx
+		.endm
+
+		.macro	senduart, rd, rx
+		mcr	p14, 0, \rd, c8, c0, 0
+		.endm
+
+		.macro	busyuart, rd, rx
+1001:
+		mrc	p14, 0, \rx, c14, c0, 0
+		tst	\rx, #0x10000000
+		beq	1001b
+		.endm
+
+		.macro	waituart, rd, rx
+		mov	\rd, #0x10000000
+1001:
+		subs	\rd, \rd, #1
+		bmi	1002f
+		mrc	p14, 0, \rx, c14, c0, 0
+		tst	\rx, #0x10000000
+		bne	1001b
+1002:
+		.endm
+
 #else
 
 		.macro	addruart, rx
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/dma.c linux-libre-2.6.30-gnu1/arch/arm/kernel/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
+#include <linux/scatterlist.h>
 
 #include <asm/dma.h>
 
@@ -23,19 +24,40 @@
 DEFINE_SPINLOCK(dma_spin_lock);
 EXPORT_SYMBOL(dma_spin_lock);
 
-static dma_t dma_chan[MAX_DMA_CHANNELS];
+static dma_t *dma_chan[MAX_DMA_CHANNELS];
+
+static inline dma_t *dma_channel(unsigned int chan)
+{
+	if (chan >= MAX_DMA_CHANNELS)
+		return NULL;
+
+	return dma_chan[chan];
+}
+
+int __init isa_dma_add(unsigned int chan, dma_t *dma)
+{
+	if (!dma->d_ops)
+		return -EINVAL;
+
+	sg_init_table(&dma->buf, 1);
+
+	if (dma_chan[chan])
+		return -EBUSY;
+	dma_chan[chan] = dma;
+	return 0;
+}
 
 /*
  * Request DMA channel
  *
  * On certain platforms, we have to allocate an interrupt as well...
  */
-int request_dma(dmach_t channel, const char *device_id)
+int request_dma(unsigned int chan, const char *device_id)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 	int ret;
 
-	if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+	if (!dma)
 		goto bad_dma;
 
 	if (xchg(&dma->lock, 1) != 0)
@@ -47,7 +69,7 @@ int request_dma(dmach_t channel, const c
 
 	ret = 0;
 	if (dma->d_ops->request)
-		ret = dma->d_ops->request(channel, dma);
+		ret = dma->d_ops->request(chan, dma);
 
 	if (ret)
 		xchg(&dma->lock, 0);
@@ -55,7 +77,7 @@ int request_dma(dmach_t channel, const c
 	return ret;
 
 bad_dma:
-	printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
+	printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan);
 	return -EINVAL;
 
 busy:
@@ -68,42 +90,42 @@ EXPORT_SYMBOL(request_dma);
  *
  * On certain platforms, we have to free interrupt as well...
  */
-void free_dma(dmach_t channel)
+void free_dma(unsigned int chan)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
-	if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+	if (!dma)
 		goto bad_dma;
 
 	if (dma->active) {
-		printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
-		dma->d_ops->disable(channel, dma);
+		printk(KERN_ERR "dma%d: freeing active DMA\n", chan);
+		dma->d_ops->disable(chan, dma);
 		dma->active = 0;
 	}
 
 	if (xchg(&dma->lock, 0) != 0) {
 		if (dma->d_ops->free)
-			dma->d_ops->free(channel, dma);
+			dma->d_ops->free(chan, dma);
 		return;
 	}
 
-	printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
+	printk(KERN_ERR "dma%d: trying to free free DMA\n", chan);
 	return;
 
 bad_dma:
-	printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
+	printk(KERN_ERR "dma: trying to free DMA%d\n", chan);
 }
 EXPORT_SYMBOL(free_dma);
 
 /* Set DMA Scatter-Gather list
  */
-void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
+void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (dma->active)
 		printk(KERN_ERR "dma%d: altering DMA SG while "
-		       "DMA active\n", channel);
+		       "DMA active\n", chan);
 
 	dma->sg = sg;
 	dma->sgcount = nr_sg;
@@ -115,13 +137,13 @@ EXPORT_SYMBOL(set_dma_sg);
  *
  * Copy address to the structure, and set the invalid bit
  */
-void __set_dma_addr (dmach_t channel, void *addr)
+void __set_dma_addr (unsigned int chan, void *addr)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (dma->active)
 		printk(KERN_ERR "dma%d: altering DMA address while "
-		       "DMA active\n", channel);
+		       "DMA active\n", chan);
 
 	dma->sg = NULL;
 	dma->addr = addr;
@@ -133,13 +155,13 @@ EXPORT_SYMBOL(__set_dma_addr);
  *
  * Copy address to the structure, and set the invalid bit
  */
-void set_dma_count (dmach_t channel, unsigned long count)
+void set_dma_count (unsigned int chan, unsigned long count)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (dma->active)
 		printk(KERN_ERR "dma%d: altering DMA count while "
-		       "DMA active\n", channel);
+		       "DMA active\n", chan);
 
 	dma->sg = NULL;
 	dma->count = count;
@@ -149,13 +171,13 @@ EXPORT_SYMBOL(set_dma_count);
 
 /* Set DMA direction mode
  */
-void set_dma_mode (dmach_t channel, dmamode_t mode)
+void set_dma_mode (unsigned int chan, unsigned int mode)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (dma->active)
 		printk(KERN_ERR "dma%d: altering DMA mode while "
-		       "DMA active\n", channel);
+		       "DMA active\n", chan);
 
 	dma->dma_mode = mode;
 	dma->invalid = 1;
@@ -164,42 +186,42 @@ EXPORT_SYMBOL(set_dma_mode);
 
 /* Enable DMA channel
  */
-void enable_dma (dmach_t channel)
+void enable_dma (unsigned int chan)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (!dma->lock)
 		goto free_dma;
 
 	if (dma->active == 0) {
 		dma->active = 1;
-		dma->d_ops->enable(channel, dma);
+		dma->d_ops->enable(chan, dma);
 	}
 	return;
 
 free_dma:
-	printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
+	printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan);
 	BUG();
 }
 EXPORT_SYMBOL(enable_dma);
 
 /* Disable DMA channel
  */
-void disable_dma (dmach_t channel)
+void disable_dma (unsigned int chan)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 
 	if (!dma->lock)
 		goto free_dma;
 
 	if (dma->active == 1) {
 		dma->active = 0;
-		dma->d_ops->disable(channel, dma);
+		dma->d_ops->disable(chan, dma);
 	}
 	return;
 
 free_dma:
-	printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
+	printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan);
 	BUG();
 }
 EXPORT_SYMBOL(disable_dma);
@@ -207,45 +229,38 @@ EXPORT_SYMBOL(disable_dma);
 /*
  * Is the specified DMA channel active?
  */
-int dma_channel_active(dmach_t channel)
+int dma_channel_active(unsigned int chan)
 {
-	return dma_chan[channel].active;
+	dma_t *dma = dma_channel(chan);
+	return dma->active;
 }
 EXPORT_SYMBOL(dma_channel_active);
 
-void set_dma_page(dmach_t channel, char pagenr)
+void set_dma_page(unsigned int chan, char pagenr)
 {
-	printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+	printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan);
 }
 EXPORT_SYMBOL(set_dma_page);
 
-void set_dma_speed(dmach_t channel, int cycle_ns)
+void set_dma_speed(unsigned int chan, int cycle_ns)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 	int ret = 0;
 
 	if (dma->d_ops->setspeed)
-		ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
+		ret = dma->d_ops->setspeed(chan, dma, cycle_ns);
 	dma->speed = ret;
 }
 EXPORT_SYMBOL(set_dma_speed);
 
-int get_dma_residue(dmach_t channel)
+int get_dma_residue(unsigned int chan)
 {
-	dma_t *dma = dma_chan + channel;
+	dma_t *dma = dma_channel(chan);
 	int ret = 0;
 
 	if (dma->d_ops->residue)
-		ret = dma->d_ops->residue(channel, dma);
+		ret = dma->d_ops->residue(chan, dma);
 
 	return ret;
 }
 EXPORT_SYMBOL(get_dma_residue);
-
-static int __init init_dma(void)
-{
-	arch_dma_init(dma_chan);
-	return 0;
-}
-
-core_initcall(init_dma);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/dma-isa.c linux-libre-2.6.30-gnu1/arch/arm/kernel/dma-isa.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/dma-isa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/dma-isa.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,11 +24,6 @@
 #include <asm/dma.h>
 #include <asm/mach/dma.h>
 
-#define ISA_DMA_MODE_READ	0x44
-#define ISA_DMA_MODE_WRITE	0x48
-#define ISA_DMA_MODE_CASCADE	0xc0
-#define ISA_DMA_AUTOINIT	0x10
-
 #define ISA_DMA_MASK		0
 #define ISA_DMA_MODE		1
 #define ISA_DMA_CLRFF		2
@@ -49,38 +44,35 @@ static unsigned int isa_dma_port[8][7] =
 	{  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
 };
 
-static int isa_get_dma_residue(dmach_t channel, dma_t *dma)
+static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
 {
-	unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
+	unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
 	int count;
 
 	count = 1 + inb(io_port);
 	count |= inb(io_port) << 8;
 
-	return channel < 4 ? count : (count << 1);
+	return chan < 4 ? count : (count << 1);
 }
 
-static void isa_enable_dma(dmach_t channel, dma_t *dma)
+static void isa_enable_dma(unsigned int chan, dma_t *dma)
 {
 	if (dma->invalid) {
 		unsigned long address, length;
 		unsigned int mode;
 		enum dma_data_direction direction;
 
-		mode = channel & 3;
+		mode = (chan & 3) | dma->dma_mode;
 		switch (dma->dma_mode & DMA_MODE_MASK) {
 		case DMA_MODE_READ:
-			mode |= ISA_DMA_MODE_READ;
 			direction = DMA_FROM_DEVICE;
 			break;
 
 		case DMA_MODE_WRITE:
-			mode |= ISA_DMA_MODE_WRITE;
 			direction = DMA_TO_DEVICE;
 			break;
 
 		case DMA_MODE_CASCADE:
-			mode |= ISA_DMA_MODE_CASCADE;
 			direction = DMA_BIDIRECTIONAL;
 			break;
 
@@ -105,34 +97,31 @@ static void isa_enable_dma(dmach_t chann
 		address = dma->buf.dma_address;
 		length  = dma->buf.length - 1;
 
-		outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
-		outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
+		outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
+		outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
 
-		if (channel >= 4) {
+		if (chan >= 4) {
 			address >>= 1;
 			length >>= 1;
 		}
 
-		outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
-
-		outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
-		outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
+		outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
 
-		outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
-		outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+		outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
+		outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
 
-		if (dma->dma_mode & DMA_AUTOINIT)
-			mode |= ISA_DMA_AUTOINIT;
+		outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
+		outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
 
-		outb(mode, isa_dma_port[channel][ISA_DMA_MODE]);
+		outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
 		dma->invalid = 0;
 	}
-	outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
+	outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
 }
 
-static void isa_disable_dma(dmach_t channel, dma_t *dma)
+static void isa_disable_dma(unsigned int chan, dma_t *dma)
 {
-	outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
+	outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
 }
 
 static struct dma_ops isa_dma_ops = {
@@ -160,7 +149,12 @@ static struct resource dma_resources[] =
 	.end	= 0x048f
 } };
 
-void __init isa_init_dma(dma_t *dma)
+static dma_t isa_dma[8];
+
+/*
+ * ISA DMA always starts at channel 0
+ */
+void __init isa_init_dma(void)
 {
 	/*
 	 * Try to autodetect presence of an ISA DMA controller.
@@ -178,11 +172,11 @@ void __init isa_init_dma(dma_t *dma)
 	outb(0xaa, 0x00);
 
 	if (inb(0) == 0x55 && inb(0) == 0xaa) {
-		int channel, i;
+		unsigned int chan, i;
 
-		for (channel = 0; channel < 8; channel++) {
-			dma[channel].d_ops = &isa_dma_ops;
-			isa_disable_dma(channel, NULL);
+		for (chan = 0; chan < 8; chan++) {
+			isa_dma[chan].d_ops = &isa_dma_ops;
+			isa_disable_dma(chan, NULL);
 		}
 
 		outb(0x40, 0x0b);
@@ -217,5 +211,12 @@ void __init isa_init_dma(dma_t *dma)
 
 		for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
 			request_resource(&ioport_resource, dma_resources + i);
+
+		for (chan = 0; chan < 8; chan++) {
+			int ret = isa_dma_add(chan, &isa_dma[chan]);
+			if (ret)
+				printk(KERN_ERR "ISADMA%u: unable to register: %d\n",
+					chan, ret);
+		}
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/elf.c linux-libre-2.6.30-gnu1/arch/arm/kernel/elf.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/elf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/elf.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,6 +78,15 @@ 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.29-gnu1/arch/arm/kernel/entry-armv.S linux-libre-2.6.30-gnu1/arch/arm/kernel/entry-armv.S
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/entry-armv.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/entry-armv.S	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/vfpmacros.h>
 #include <mach/entry-macro.S>
 #include <asm/thread_notify.h>
+#include <asm/unwind.h>
 
 #include "entry-header.S"
 
@@ -123,6 +124,8 @@ ENDPROC(__und_invalid)
 #endif
 
 	.macro	svc_entry, stack_hole=0
+ UNWIND(.fnstart		)
+ UNWIND(.save {r0 - pc}		)
 	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole)
  SPFIX(	tst	sp, #4		)
  SPFIX(	bicne	sp, sp, #4	)
@@ -196,6 +199,7 @@ __dabt_svc:
 	ldr	r0, [sp, #S_PSR]
 	msr	spsr_cxsf, r0
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ UNWIND(.fnend		)
 ENDPROC(__dabt_svc)
 
 	.align	5
@@ -228,6 +232,7 @@ __irq_svc:
 	bleq	trace_hardirqs_on
 #endif
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ UNWIND(.fnend		)
 ENDPROC(__irq_svc)
 
 	.ltorg
@@ -278,6 +283,7 @@ __und_svc:
 	ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
 	msr	spsr_cxsf, lr
 	ldmia	sp, {r0 - pc}^			@ Restore SVC registers
+ UNWIND(.fnend		)
 ENDPROC(__und_svc)
 
 	.align	5
@@ -320,6 +326,7 @@ __pabt_svc:
 	ldr	r0, [sp, #S_PSR]
 	msr	spsr_cxsf, r0
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+ UNWIND(.fnend		)
 ENDPROC(__pabt_svc)
 
 	.align	5
@@ -343,6 +350,8 @@ ENDPROC(__pabt_svc)
 #endif
 
 	.macro	usr_entry
+ UNWIND(.fnstart	)
+ UNWIND(.cantunwind	)	@ don't unwind the user space
 	sub	sp, sp, #S_FRAME_SIZE
 	stmib	sp, {r1 - r12}
 
@@ -420,6 +429,7 @@ __dabt_usr:
 	mov	r2, sp
 	adr	lr, ret_from_exception
 	b	do_DataAbort
+ UNWIND(.fnend		)
 ENDPROC(__dabt_usr)
 
 	.align	5
@@ -450,6 +460,7 @@ __irq_usr:
 
 	mov	why, #0
 	b	ret_to_user
+ UNWIND(.fnend		)
 ENDPROC(__irq_usr)
 
 	.ltorg
@@ -484,6 +495,7 @@ __und_usr:
 #else
 	b	__und_usr_unknown
 #endif
+ UNWIND(.fnend		)
 ENDPROC(__und_usr)
 
 	@
@@ -671,14 +683,18 @@ __pabt_usr:
 	enable_irq				@ Enable interrupts
 	mov	r1, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
+ UNWIND(.fnend		)
 	/* fall through */
 /*
  * This is the return code to user mode for abort handlers
  */
 ENTRY(ret_from_exception)
+ UNWIND(.fnstart	)
+ UNWIND(.cantunwind	)
 	get_thread_info tsk
 	mov	why, #0
 	b	ret_to_user
+ UNWIND(.fnend		)
 ENDPROC(__pabt_usr)
 ENDPROC(ret_from_exception)
 
@@ -688,6 +704,8 @@ ENDPROC(ret_from_exception)
  * previous and next are guaranteed not to be the same.
  */
 ENTRY(__switch_to)
+ UNWIND(.fnstart	)
+ UNWIND(.cantunwind	)
 	add	ip, r1, #TI_CPU_SAVE
 	ldr	r3, [r2, #TI_TP_VALUE]
 	stmia	ip!, {r4 - sl, fp, sp, lr}	@ Store most regs on stack
@@ -717,6 +735,7 @@ ENTRY(__switch_to)
 	bl	atomic_notifier_call_chain
 	mov	r0, r5
 	ldmia	r4, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
+ UNWIND(.fnend		)
 ENDPROC(__switch_to)
 
 	__INIT
@@ -796,10 +815,7 @@ __kuser_helper_start:
  */
 
 __kuser_memory_barrier:				@ 0xffff0fa0
-
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP)
-	mcr	p15, 0, r0, c7, c10, 5	@ dmb
-#endif
+	smp_dmb
 	usr_ret	lr
 
 	.align	5
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/entry-common.S linux-libre-2.6.30-gnu1/arch/arm/kernel/entry-common.S
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/entry-common.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/entry-common.S	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@
 #include <asm/unistd.h>
 #include <asm/ftrace.h>
 #include <mach/entry-macro.S>
+#include <asm/unwind.h>
 
 #include "entry-header.S"
 
@@ -22,6 +23,8 @@
  * stack.
  */
 ret_fast_syscall:
+ UNWIND(.fnstart	)
+ UNWIND(.cantunwind	)
 	disable_irq				@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
@@ -38,6 +41,7 @@ ret_fast_syscall:
 	mov	r0, r0
 	add	sp, sp, #S_FRAME_SIZE - S_PC
 	movs	pc, lr				@ return & move spsr_svc into cpsr
+ UNWIND(.fnend		)
 
 /*
  * Ok, we need to do extra processing, enter the slow path.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/irq.c linux-libre-2.6.30-gnu1/arch/arm/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_printf(p, "%3d: ", i);
 		for_each_present_cpu(cpu)
-			seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 		seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
@@ -104,6 +104,11 @@ static struct irq_desc bad_irq_desc = {
 	.lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
 };
 
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* We are not allocating bad_irq_desc.affinity or .pending_mask */
+#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK."
+#endif
+
 /*
  * do_IRQ handles all hardware IRQ's.  Decoded IRQs should not
  * come via this function.  Instead, they should provide their
@@ -161,7 +166,7 @@ void __init init_IRQ(void)
 		irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
 
 #ifdef CONFIG_SMP
-	bad_irq_desc.affinity = CPU_MASK_ALL;
+	cpumask_setall(bad_irq_desc.affinity);
 	bad_irq_desc.cpu = smp_processor_id();
 #endif
 	init_arch_irq();
@@ -191,15 +196,16 @@ void migrate_irqs(void)
 		struct irq_desc *desc = irq_desc + i;
 
 		if (desc->cpu == cpu) {
-			unsigned int newcpu = any_online_cpu(desc->affinity);
-
-			if (newcpu == NR_CPUS) {
+			unsigned int newcpu = cpumask_any_and(desc->affinity,
+							      cpu_online_mask);
+			if (newcpu >= nr_cpu_ids) {
 				if (printk_ratelimit())
 					printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
 					       i, cpu);
 
-				cpus_setall(desc->affinity);
-				newcpu = any_online_cpu(desc->affinity);
+				cpumask_setall(desc->affinity);
+				newcpu = cpumask_any_and(desc->affinity,
+							 cpu_online_mask);
 			}
 
 			route_irq(desc, i, newcpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/Makefile linux-libre-2.6.30-gnu1/arch/arm/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -29,12 +29,14 @@ obj-$(CONFIG_ATAGS_PROC)	+= atags.o
 obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
 obj-$(CONFIG_ARM_THUMBEE)	+= thumbee.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
+obj-$(CONFIG_ARM_UNWIND)	+= unwind.o
 
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
 AFLAGS_crunch-bits.o		:= -Wa,-mcpu=ep9312
 
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
+obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/module.c linux-libre-2.6.30-gnu1/arch/arm/kernel/module.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/module.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <asm/pgtable.h>
 #include <asm/sections.h>
+#include <asm/unwind.h>
 
 #ifdef CONFIG_XIP_KERNEL
 /*
@@ -66,6 +67,24 @@ int module_frob_arch_sections(Elf_Ehdr *
 			      char *secstrings,
 			      struct module *mod)
 {
+#ifdef CONFIG_ARM_UNWIND
+	Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+
+	for (s = sechdrs; s < sechdrs_end; s++) {
+		if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0)
+			mod->arch.unw_sec_init = s;
+		else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0)
+			mod->arch.unw_sec_devinit = s;
+		else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0)
+			mod->arch.unw_sec_core = s;
+		else if (strcmp(".init.text", secstrings + s->sh_name) == 0)
+			mod->arch.sec_init_text = s;
+		else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0)
+			mod->arch.sec_devinit_text = s;
+		else if (strcmp(".text", secstrings + s->sh_name) == 0)
+			mod->arch.sec_core_text = s;
+	}
+#endif
 	return 0;
 }
 
@@ -104,6 +123,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
 		loc = dstsec->sh_addr + rel->r_offset;
 
 		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_ARM_NONE:
+			/* ignore */
+			break;
+
 		case R_ARM_ABS32:
 			*(u32 *)loc += sym->st_value;
 			break;
@@ -132,6 +155,35 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
 			*(u32 *)loc |= offset & 0x00ffffff;
 			break;
 
+	       case R_ARM_V4BX:
+		       /* Preserve Rm and the condition code. Alter
+			* other bits to re-code instruction as
+			* MOV PC,Rm.
+			*/
+		       *(u32 *)loc &= 0xf000000f;
+		       *(u32 *)loc |= 0x01a0f000;
+		       break;
+
+		case R_ARM_PREL31:
+			offset = *(u32 *)loc + sym->st_value - loc;
+			*(u32 *)loc = offset & 0x7fffffff;
+			break;
+
+		case R_ARM_MOVW_ABS_NC:
+		case R_ARM_MOVT_ABS:
+			offset = *(u32 *)loc;
+			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
+			offset = (offset ^ 0x8000) - 0x8000;
+
+			offset += sym->st_value;
+			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
+				offset >>= 16;
+
+			*(u32 *)loc &= 0xfff0f000;
+			*(u32 *)loc |= ((offset & 0xf000) << 4) |
+					(offset & 0x0fff);
+			break;
+
 		default:
 			printk(KERN_ERR "%s: unknown relocation: %u\n",
 			       module->name, ELF32_R_TYPE(rel->r_info));
@@ -150,14 +202,50 @@ apply_relocate_add(Elf32_Shdr *sechdrs,
 	return -ENOEXEC;
 }
 
+#ifdef CONFIG_ARM_UNWIND
+static void register_unwind_tables(struct module *mod)
+{
+	if (mod->arch.unw_sec_init && mod->arch.sec_init_text)
+		mod->arch.unwind_init =
+			unwind_table_add(mod->arch.unw_sec_init->sh_addr,
+					 mod->arch.unw_sec_init->sh_size,
+					 mod->arch.sec_init_text->sh_addr,
+					 mod->arch.sec_init_text->sh_size);
+	if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text)
+		mod->arch.unwind_devinit =
+			unwind_table_add(mod->arch.unw_sec_devinit->sh_addr,
+					 mod->arch.unw_sec_devinit->sh_size,
+					 mod->arch.sec_devinit_text->sh_addr,
+					 mod->arch.sec_devinit_text->sh_size);
+	if (mod->arch.unw_sec_core && mod->arch.sec_core_text)
+		mod->arch.unwind_core =
+			unwind_table_add(mod->arch.unw_sec_core->sh_addr,
+					 mod->arch.unw_sec_core->sh_size,
+					 mod->arch.sec_core_text->sh_addr,
+					 mod->arch.sec_core_text->sh_size);
+}
+
+static void unregister_unwind_tables(struct module *mod)
+{
+	unwind_table_del(mod->arch.unwind_init);
+	unwind_table_del(mod->arch.unwind_devinit);
+	unwind_table_del(mod->arch.unwind_core);
+}
+#else
+static inline void register_unwind_tables(struct module *mod) { }
+static inline void unregister_unwind_tables(struct module *mod) { }
+#endif
+
 int
 module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
 		struct module *module)
 {
+	register_unwind_tables(module);
 	return 0;
 }
 
 void
 module_arch_cleanup(struct module *mod)
 {
+	unregister_unwind_tables(mod);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/process.c linux-libre-2.6.30-gnu1/arch/arm/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,7 @@
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/thread_notify.h>
+#include <asm/stacktrace.h>
 #include <asm/mach/time.h>
 
 static const char *processor_modes[] = {
@@ -82,7 +83,7 @@ static int __init hlt_setup(char *__unus
 __setup("nohlt", nohlt_setup);
 __setup("hlt", hlt_setup);
 
-void arm_machine_restart(char mode)
+void arm_machine_restart(char mode, const char *cmd)
 {
 	/*
 	 * Clean and disable cache, and turn off interrupts
@@ -99,7 +100,7 @@ void arm_machine_restart(char mode)
 	/*
 	 * Now call the architecture specific reboot code.
 	 */
-	arch_reset(mode);
+	arch_reset(mode, cmd);
 
 	/*
 	 * Whoops - the architecture was unable to reboot.
@@ -119,7 +120,7 @@ EXPORT_SYMBOL(pm_idle);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-void (*arm_pm_restart)(char str) = arm_machine_restart;
+void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
 EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 
@@ -194,9 +195,9 @@ void machine_power_off(void)
 		pm_power_off();
 }
 
-void machine_restart(char * __unused)
+void machine_restart(char *cmd)
 {
-	arm_pm_restart(reboot_mode);
+	arm_pm_restart(reboot_mode, cmd);
 }
 
 void __show_regs(struct pt_regs *regs)
@@ -300,7 +301,7 @@ void release_thread(struct task_struct *
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int
-copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
+copy_thread(unsigned long clone_flags, unsigned long stack_start,
 	    unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *thread = task_thread_info(p);
@@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread);
 
 unsigned long get_wchan(struct task_struct *p)
 {
-	unsigned long fp, lr;
-	unsigned long stack_start, stack_end;
+	struct stackframe frame;
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
-	stack_start = (unsigned long)end_of_stack(p);
-	stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-
-	fp = thread_saved_fp(p);
+	frame.fp = thread_saved_fp(p);
+	frame.sp = thread_saved_sp(p);
+	frame.lr = 0;			/* recovered from the stack */
+	frame.pc = thread_saved_pc(p);
 	do {
-		if (fp < stack_start || fp > stack_end)
+		int ret = unwind_frame(&frame);
+		if (ret < 0)
 			return 0;
-		lr = ((unsigned long *)fp)[-1];
-		if (!in_sched_functions(lr))
-			return lr;
-		fp = *(unsigned long *) (fp - 12);
+		if (!in_sched_functions(frame.pc))
+			return frame.pc;
 	} while (count ++ < 16);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/ptrace.c linux-libre-2.6.30-gnu1/arch/arm/kernel/ptrace.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/ptrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/ptrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -653,6 +653,54 @@ static int ptrace_setcrunchregs(struct t
 }
 #endif
 
+#ifdef CONFIG_VFP
+/*
+ * Get the child VFP state.
+ */
+static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
+{
+	struct thread_info *thread = task_thread_info(tsk);
+	union vfp_state *vfp = &thread->vfpstate;
+	struct user_vfp __user *ufp = data;
+
+	vfp_sync_state(thread);
+
+	/* copy the floating point registers */
+	if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
+			 sizeof(vfp->hard.fpregs)))
+		return -EFAULT;
+
+	/* copy the status and control register */
+	if (put_user(vfp->hard.fpscr, &ufp->fpscr))
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+ * Set the child VFP state.
+ */
+static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
+{
+	struct thread_info *thread = task_thread_info(tsk);
+	union vfp_state *vfp = &thread->vfpstate;
+	struct user_vfp __user *ufp = data;
+
+	vfp_sync_state(thread);
+
+	/* copy the floating point registers */
+	if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
+			   sizeof(vfp->hard.fpregs)))
+		return -EFAULT;
+
+	/* copy the status and control register */
+	if (get_user(vfp->hard.fpscr, &ufp->fpscr))
+		return -EFAULT;
+
+	return 0;
+}
+#endif
+
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	int ret;
@@ -775,6 +823,16 @@ long arch_ptrace(struct task_struct *chi
 			break;
 #endif
 
+#ifdef CONFIG_VFP
+		case PTRACE_GETVFPREGS:
+			ret = ptrace_getvfpregs(child, (void __user *)data);
+			break;
+
+		case PTRACE_SETVFPREGS:
+			ret = ptrace_setvfpregs(child, (void __user *)data);
+			break;
+#endif
+
 		default:
 			ret = ptrace_request(child, request, addr, data);
 			break;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/setup.c linux-libre-2.6.30-gnu1/arch/arm/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/traps.h>
+#include <asm/unwind.h>
 
 #include "compat.h"
 #include "atags.h"
@@ -685,6 +686,8 @@ void __init setup_arch(char **cmdline_p)
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
 
+	unwind_init();
+
 	setup_processor();
 	mdesc = setup_machine(machine_arch_type);
 	machine_name = mdesc->name;
@@ -780,6 +783,8 @@ static const char *hwcap_str[] = {
 	"crunch",
 	"thumbee",
 	"neon",
+	"vfpv3",
+	"vfpv3d16",
 	NULL
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/smp.c linux-libre-2.6.30-gnu1/arch/arm/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,6 +93,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
 	*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
 		     PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
+	flush_pmd_entry(pmd);
 
 	/*
 	 * We need to tell the secondary core where to find
@@ -130,6 +131,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	secondary_data.pgdir = 0;
 
 	*pmd = __pmd(0);
+	clean_pmd_entry(pmd);
 	pgd_free(&init_mm, pgd);
 
 	if (ret) {
@@ -324,14 +326,14 @@ void __init smp_prepare_boot_cpu(void)
 	per_cpu(cpu_data, cpu).idle = current;
 }
 
-static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
+static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg)
 {
 	unsigned long flags;
 	unsigned int cpu;
 
 	local_irq_save(flags);
 
-	for_each_cpu_mask(cpu, callmap) {
+	for_each_cpu(cpu, mask) {
 		struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
 
 		spin_lock(&ipi->lock);
@@ -342,19 +344,19 @@ static void send_ipi_message(cpumask_t c
 	/*
 	 * Call the platform specific cross-CPU call function.
 	 */
-	smp_cross_call(callmap);
+	smp_cross_call(mask);
 
 	local_irq_restore(flags);
 }
 
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	send_ipi_message(mask, IPI_CALL_FUNC);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-	send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE);
+	send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
 }
 
 void show_ipi_list(struct seq_file *p)
@@ -496,17 +498,10 @@ asmlinkage void __exception do_IPI(struc
 
 void smp_send_reschedule(int cpu)
 {
-	send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE);
-}
-
-void smp_send_timer(void)
-{
-	cpumask_t mask = cpu_online_map;
-	cpu_clear(smp_processor_id(), mask);
-	send_ipi_message(mask, IPI_TIMER);
+	send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
 }
 
-void smp_timer_broadcast(cpumask_t mask)
+void smp_timer_broadcast(const struct cpumask *mask)
 {
 	send_ipi_message(mask, IPI_TIMER);
 }
@@ -515,7 +510,7 @@ void smp_send_stop(void)
 {
 	cpumask_t mask = cpu_online_map;
 	cpu_clear(smp_processor_id(), mask);
-	send_ipi_message(mask, IPI_CPU_STOP);
+	send_ipi_message(&mask, IPI_CPU_STOP);
 }
 
 /*
@@ -526,20 +521,17 @@ int setup_profiling_timer(unsigned int m
 	return -EINVAL;
 }
 
-static int
-on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask)
+static void
+on_each_cpu_mask(void (*func)(void *), void *info, int wait,
+		const struct cpumask *mask)
 {
-	int ret = 0;
-
 	preempt_disable();
 
-	ret = smp_call_function_mask(mask, func, info, wait);
-	if (cpu_isset(smp_processor_id(), mask))
+	smp_call_function_many(mask, func, info, wait);
+	if (cpumask_test_cpu(smp_processor_id(), mask))
 		func(info);
 
 	preempt_enable();
-
-	return ret;
 }
 
 /**********************************************************************/
@@ -600,20 +592,17 @@ void flush_tlb_all(void)
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
-	cpumask_t mask = mm->cpu_vm_mask;
-
-	on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask);
+	on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask);
 }
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 {
-	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
 	struct tlb_args ta;
 
 	ta.ta_vma = vma;
 	ta.ta_start = uaddr;
 
-	on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask);
+	on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask);
 }
 
 void flush_tlb_kernel_page(unsigned long kaddr)
@@ -628,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long
 void flush_tlb_range(struct vm_area_struct *vma,
                      unsigned long start, unsigned long end)
 {
-	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
 	struct tlb_args ta;
 
 	ta.ta_vma = vma;
 	ta.ta_start = start;
 	ta.ta_end = end;
 
-	on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask);
+	on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask);
 }
 
 void flush_tlb_kernel_range(unsigned long start, unsigned long end)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/stacktrace.c linux-libre-2.6.30-gnu1/arch/arm/kernel/stacktrace.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/stacktrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/stacktrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,35 +2,60 @@
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
 
-#include "stacktrace.h"
+#include <asm/stacktrace.h>
 
-int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
-		    int (*fn)(struct stackframe *, void *), void *data)
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+/*
+ * Unwind the current stack frame and store the new register values in the
+ * structure passed as argument. Unwinding is equivalent to a function return,
+ * hence the new PC value rather than LR should be used for backtrace.
+ *
+ * With framepointer enabled, a simple function prologue looks like this:
+ *	mov	ip, sp
+ *	stmdb	sp!, {fp, ip, lr, pc}
+ *	sub	fp, ip, #4
+ *
+ * A simple function epilogue looks like this:
+ *	ldm	sp, {fp, sp, pc}
+ *
+ * Note that with framepointer enabled, even the leaf functions have the same
+ * prologue and epilogue, therefore we can ignore the LR value in this case.
+ */
+int unwind_frame(struct stackframe *frame)
 {
-	struct stackframe *frame;
-
-	do {
-		/*
-		 * Check current frame pointer is within bounds
-		 */
-		if (fp < (low + 12) || fp + 4 >= high)
-			break;
+	unsigned long high, low;
+	unsigned long fp = frame->fp;
 
-		frame = (struct stackframe *)(fp - 12);
+	/* only go to a higher address on the stack */
+	low = frame->sp;
+	high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
 
-		if (fn(frame, data))
-			break;
+	/* check current frame pointer is within bounds */
+	if (fp < (low + 12) || fp + 4 >= high)
+		return -EINVAL;
 
-		/*
-		 * Update the low bound - the next frame must always
-		 * be at a higher address than the current frame.
-		 */
-		low = fp + 4;
-		fp = frame->fp;
-	} while (fp);
+	/* restore the registers from the stack frame */
+	frame->fp = *(unsigned long *)(fp - 12);
+	frame->sp = *(unsigned long *)(fp - 8);
+	frame->pc = *(unsigned long *)(fp - 4);
 
 	return 0;
 }
+#endif
+
+void walk_stackframe(struct stackframe *frame,
+		     int (*fn)(struct stackframe *, void *), void *data)
+{
+	while (1) {
+		int ret;
+
+		if (fn(frame, data))
+			break;
+		ret = unwind_frame(frame);
+		if (ret < 0)
+			break;
+	}
+}
 EXPORT_SYMBOL(walk_stackframe);
 
 #ifdef CONFIG_STACKTRACE
@@ -44,7 +69,7 @@ static int save_trace(struct stackframe
 {
 	struct stack_trace_data *data = d;
 	struct stack_trace *trace = data->trace;
-	unsigned long addr = frame->lr;
+	unsigned long addr = frame->pc;
 
 	if (data->no_sched_functions && in_sched_functions(addr))
 		return 0;
@@ -61,11 +86,10 @@ static int save_trace(struct stackframe
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
 	struct stack_trace_data data;
-	unsigned long fp, base;
+	struct stackframe frame;
 
 	data.trace = trace;
 	data.skip = trace->skip;
-	base = (unsigned long)task_stack_page(tsk);
 
 	if (tsk != current) {
 #ifdef CONFIG_SMP
@@ -76,14 +100,22 @@ void save_stack_trace_tsk(struct task_st
 		BUG();
 #else
 		data.no_sched_functions = 1;
-		fp = thread_saved_fp(tsk);
+		frame.fp = thread_saved_fp(tsk);
+		frame.sp = thread_saved_sp(tsk);
+		frame.lr = 0;		/* recovered from the stack */
+		frame.pc = thread_saved_pc(tsk);
 #endif
 	} else {
+		register unsigned long current_sp asm ("sp");
+
 		data.no_sched_functions = 0;
-		asm("mov %0, fp" : "=r" (fp));
+		frame.fp = (unsigned long)__builtin_frame_address(0);
+		frame.sp = current_sp;
+		frame.lr = (unsigned long)__builtin_return_address(0);
+		frame.pc = (unsigned long)save_stack_trace_tsk;
 	}
 
-	walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
+	walk_stackframe(&frame, save_trace, &data);
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/stacktrace.h linux-libre-2.6.30-gnu1/arch/arm/kernel/stacktrace.h
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/stacktrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/stacktrace.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-struct stackframe {
-	unsigned long fp;
-	unsigned long sp;
-	unsigned long lr;
-	unsigned long pc;
-};
-
-int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
-		    int (*fn)(struct stackframe *, void *), void *data);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/sys_oabi-compat.c linux-libre-2.6.30-gnu1/arch/arm/kernel/sys_oabi-compat.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/sys_oabi-compat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/sys_oabi-compat.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,6 +83,7 @@
 #include <linux/net.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
+#include <linux/slab.h>
 
 struct oldabi_stat64 {
 	unsigned long long st_dev;
@@ -176,21 +177,12 @@ asmlinkage long sys_oabi_fstatat64(int d
 				   int flag)
 {
 	struct kstat stat;
-	int error = -EINVAL;
-
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-		goto out;
-
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
-	else
-		error = vfs_stat_fd(dfd, filename, &stat);
-
-	if (!error)
-	error = cp_oldabi_stat64(&stat, statbuf);
+	int error;
 
-out:
-	return error;
+	error = vfs_fstatat(dfd, filename, &stat, flag);
+	if (error)
+		return error;
+	return cp_oldabi_stat64(&stat, statbuf);
 }
 
 struct oabi_flock64 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/time.c linux-libre-2.6.30-gnu1/arch/arm/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,7 @@
 
 #include <asm/leds.h>
 #include <asm/thread_info.h>
+#include <asm/stacktrace.h>
 #include <asm/mach/time.h>
 
 /*
@@ -55,14 +56,22 @@ EXPORT_SYMBOL(rtc_lock);
 #ifdef CONFIG_SMP
 unsigned long profile_pc(struct pt_regs *regs)
 {
-	unsigned long fp, pc = instruction_pointer(regs);
+	struct stackframe frame;
 
-	if (in_lock_functions(pc)) {
-		fp = regs->ARM_fp;
-		pc = ((unsigned long *)fp)[-1];
-	}
+	if (!in_lock_functions(regs->ARM_pc))
+		return regs->ARM_pc;
 
-	return pc;
+	frame.fp = regs->ARM_fp;
+	frame.sp = regs->ARM_sp;
+	frame.lr = regs->ARM_lr;
+	frame.pc = regs->ARM_pc;
+	do {
+		int ret = unwind_frame(&frame);
+		if (ret < 0)
+			return 0;
+	} while (in_lock_functions(frame.pc));
+
+	return frame.pc;
 }
 EXPORT_SYMBOL(profile_pc);
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/traps.c linux-libre-2.6.30-gnu1/arch/arm/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@
 #include <asm/system.h>
 #include <asm/unistd.h>
 #include <asm/traps.h>
+#include <asm/unwind.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -61,6 +62,7 @@ void dump_backtrace_entry(unsigned long
 		dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
 }
 
+#ifndef CONFIG_ARM_UNWIND
 /*
  * Stack pointers should always be within the kernels view of
  * physical memory.  If it is not there, then we can't dump
@@ -74,6 +76,7 @@ static int verify_stack(unsigned long sp
 
 	return 0;
 }
+#endif
 
 /*
  * Dump out the contents of some memory nicely...
@@ -150,13 +153,33 @@ static void dump_instr(struct pt_regs *r
 	set_fs(fs);
 }
 
+#ifdef CONFIG_ARM_UNWIND
+static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+	unwind_backtrace(regs, tsk);
+}
+#else
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
-	unsigned int fp;
+	unsigned int fp, mode;
 	int ok = 1;
 
 	printk("Backtrace: ");
-	fp = regs->ARM_fp;
+
+	if (!tsk)
+		tsk = current;
+
+	if (regs) {
+		fp = regs->ARM_fp;
+		mode = processor_mode(regs);
+	} else if (tsk != current) {
+		fp = thread_saved_fp(tsk);
+		mode = 0x10;
+	} else {
+		asm("mov %0, fp" : "=r" (fp) : : "cc");
+		mode = 0x10;
+	}
+
 	if (!fp) {
 		printk("no frame pointer");
 		ok = 0;
@@ -168,29 +191,20 @@ static void dump_backtrace(struct pt_reg
 	printk("\n");
 
 	if (ok)
-		c_backtrace(fp, processor_mode(regs));
+		c_backtrace(fp, mode);
 }
+#endif
 
 void dump_stack(void)
 {
-	__backtrace();
+	dump_backtrace(NULL, NULL);
 }
 
 EXPORT_SYMBOL(dump_stack);
 
 void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
-	unsigned long fp;
-
-	if (!tsk)
-		tsk = current;
-
-	if (tsk != current)
-		fp = thread_saved_fp(tsk);
-	else
-		asm("mov %0, fp" : "=r" (fp) : : "cc");
-
-	c_backtrace(fp, 0x10);
+	dump_backtrace(NULL, tsk);
 	barrier();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/unwind.c linux-libre-2.6.30-gnu1/arch/arm/kernel/unwind.c
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/unwind.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/unwind.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,434 @@
+/*
+ * arch/arm/kernel/unwind.c
+ *
+ * Copyright (C) 2008 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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
+ *
+ *
+ * Stack unwinding support for ARM
+ *
+ * An ARM EABI version of gcc is required to generate the unwind
+ * tables. For information about the structure of the unwind tables,
+ * see "Exception Handling ABI for the ARM Architecture" at:
+ *
+ * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+#include <asm/stacktrace.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
+
+struct unwind_ctrl_block {
+	unsigned long vrs[16];		/* virtual register set */
+	unsigned long *insn;		/* pointer to the current instructions word */
+	int entries;			/* number of entries left to interpret */
+	int byte;			/* current byte number in the instructions word */
+};
+
+enum regs {
+	FP = 11,
+	SP = 13,
+	LR = 14,
+	PC = 15
+};
+
+extern struct unwind_idx __start_unwind_idx[];
+extern struct unwind_idx __stop_unwind_idx[];
+
+static DEFINE_SPINLOCK(unwind_lock);
+static LIST_HEAD(unwind_tables);
+
+/* Convert a prel31 symbol to an absolute address */
+#define prel31_to_addr(ptr)				\
+({							\
+	/* sign-extend to 32 bits */			\
+	long offset = (((long)*(ptr)) << 1) >> 1;	\
+	(unsigned long)(ptr) + offset;			\
+})
+
+/*
+ * Binary search in the unwind index. The entries entries are
+ * guaranteed to be sorted in ascending order by the linker.
+ */
+static struct unwind_idx *search_index(unsigned long addr,
+				       struct unwind_idx *first,
+				       struct unwind_idx *last)
+{
+	pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
+
+	if (addr < first->addr) {
+		pr_warning("unwind: Unknown symbol address %08lx\n", addr);
+		return NULL;
+	} else if (addr >= last->addr)
+		return last;
+
+	while (first < last - 1) {
+		struct unwind_idx *mid = first + ((last - first + 1) >> 1);
+
+		if (addr < mid->addr)
+			last = mid;
+		else
+			first = mid;
+	}
+
+	return first;
+}
+
+static struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+	struct unwind_idx *idx = NULL;
+	unsigned long flags;
+
+	pr_debug("%s(%08lx)\n", __func__, addr);
+
+	if (core_kernel_text(addr))
+		/* main unwind table */
+		idx = search_index(addr, __start_unwind_idx,
+				   __stop_unwind_idx - 1);
+	else {
+		/* module unwind tables */
+		struct unwind_table *table;
+
+		spin_lock_irqsave(&unwind_lock, flags);
+		list_for_each_entry(table, &unwind_tables, list) {
+			if (addr >= table->begin_addr &&
+			    addr < table->end_addr) {
+				idx = search_index(addr, table->start,
+						   table->stop - 1);
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&unwind_lock, flags);
+	}
+
+	pr_debug("%s: idx = %p\n", __func__, idx);
+	return idx;
+}
+
+static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
+{
+	unsigned long ret;
+
+	if (ctrl->entries <= 0) {
+		pr_warning("unwind: Corrupt unwind table\n");
+		return 0;
+	}
+
+	ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
+
+	if (ctrl->byte == 0) {
+		ctrl->insn++;
+		ctrl->entries--;
+		ctrl->byte = 3;
+	} else
+		ctrl->byte--;
+
+	return ret;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+	unsigned long insn = unwind_get_byte(ctrl);
+
+	pr_debug("%s: insn = %08lx\n", __func__, insn);
+
+	if ((insn & 0xc0) == 0x00)
+		ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
+	else if ((insn & 0xc0) == 0x40)
+		ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
+	else if ((insn & 0xf0) == 0x80) {
+		unsigned long mask;
+		unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+		int load_sp, reg = 4;
+
+		insn = (insn << 8) | unwind_get_byte(ctrl);
+		mask = insn & 0x0fff;
+		if (mask == 0) {
+			pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
+				   insn);
+			return -URC_FAILURE;
+		}
+
+		/* pop R4-R15 according to mask */
+		load_sp = mask & (1 << (13 - 4));
+		while (mask) {
+			if (mask & 1)
+				ctrl->vrs[reg] = *vsp++;
+			mask >>= 1;
+			reg++;
+		}
+		if (!load_sp)
+			ctrl->vrs[SP] = (unsigned long)vsp;
+	} else if ((insn & 0xf0) == 0x90 &&
+		   (insn & 0x0d) != 0x0d)
+		ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+	else if ((insn & 0xf0) == 0xa0) {
+		unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+		int reg;
+
+		/* pop R4-R[4+bbb] */
+		for (reg = 4; reg <= 4 + (insn & 7); reg++)
+			ctrl->vrs[reg] = *vsp++;
+		if (insn & 0x80)
+			ctrl->vrs[14] = *vsp++;
+		ctrl->vrs[SP] = (unsigned long)vsp;
+	} else if (insn == 0xb0) {
+		ctrl->vrs[PC] = ctrl->vrs[LR];
+		/* no further processing */
+		ctrl->entries = 0;
+	} else if (insn == 0xb1) {
+		unsigned long mask = unwind_get_byte(ctrl);
+		unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+		int reg = 0;
+
+		if (mask == 0 || mask & 0xf0) {
+			pr_warning("unwind: Spare encoding %04lx\n",
+			       (insn << 8) | mask);
+			return -URC_FAILURE;
+		}
+
+		/* pop R0-R3 according to mask */
+		while (mask) {
+			if (mask & 1)
+				ctrl->vrs[reg] = *vsp++;
+			mask >>= 1;
+			reg++;
+		}
+		ctrl->vrs[SP] = (unsigned long)vsp;
+	} else if (insn == 0xb2) {
+		unsigned long uleb128 = unwind_get_byte(ctrl);
+
+		ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+	} else {
+		pr_warning("unwind: Unhandled instruction %02lx\n", insn);
+		return -URC_FAILURE;
+	}
+
+	pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
+		 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
+
+	return URC_OK;
+}
+
+/*
+ * Unwind a single frame starting with *sp for the symbol at *pc. It
+ * updates the *pc and *sp with the new values.
+ */
+int unwind_frame(struct stackframe *frame)
+{
+	unsigned long high, low;
+	struct unwind_idx *idx;
+	struct unwind_ctrl_block ctrl;
+
+	/* only go to a higher address on the stack */
+	low = frame->sp;
+	high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
+
+	pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
+		 frame->pc, frame->lr, frame->sp);
+
+	if (!kernel_text_address(frame->pc))
+		return -URC_FAILURE;
+
+	idx = unwind_find_idx(frame->pc);
+	if (!idx) {
+		pr_warning("unwind: Index not found %08lx\n", frame->pc);
+		return -URC_FAILURE;
+	}
+
+	ctrl.vrs[FP] = frame->fp;
+	ctrl.vrs[SP] = frame->sp;
+	ctrl.vrs[LR] = frame->lr;
+	ctrl.vrs[PC] = 0;
+
+	if (idx->insn == 1)
+		/* can't unwind */
+		return -URC_FAILURE;
+	else if ((idx->insn & 0x80000000) == 0)
+		/* prel31 to the unwind table */
+		ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
+	else if ((idx->insn & 0xff000000) == 0x80000000)
+		/* only personality routine 0 supported in the index */
+		ctrl.insn = &idx->insn;
+	else {
+		pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
+			   idx->insn, idx);
+		return -URC_FAILURE;
+	}
+
+	/* check the personality routine */
+	if ((*ctrl.insn & 0xff000000) == 0x80000000) {
+		ctrl.byte = 2;
+		ctrl.entries = 1;
+	} else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
+		ctrl.byte = 1;
+		ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
+	} else {
+		pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
+			   *ctrl.insn, ctrl.insn);
+		return -URC_FAILURE;
+	}
+
+	while (ctrl.entries > 0) {
+		int urc;
+
+		if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+			return -URC_FAILURE;
+		urc = unwind_exec_insn(&ctrl);
+		if (urc < 0)
+			return urc;
+	}
+
+	if (ctrl.vrs[PC] == 0)
+		ctrl.vrs[PC] = ctrl.vrs[LR];
+
+	frame->fp = ctrl.vrs[FP];
+	frame->sp = ctrl.vrs[SP];
+	frame->lr = ctrl.vrs[LR];
+	frame->pc = ctrl.vrs[PC];
+
+	return URC_OK;
+}
+
+void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+	struct stackframe frame;
+	unsigned long high, low;
+	register unsigned long current_sp asm ("sp");
+
+	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+
+	if (!tsk)
+		tsk = current;
+
+	if (regs) {
+		frame.fp = regs->ARM_fp;
+		frame.sp = regs->ARM_sp;
+		frame.lr = regs->ARM_lr;
+		frame.pc = regs->ARM_pc;
+	} else if (tsk == current) {
+		frame.fp = (unsigned long)__builtin_frame_address(0);
+		frame.sp = current_sp;
+		frame.lr = (unsigned long)__builtin_return_address(0);
+		frame.pc = (unsigned long)unwind_backtrace;
+	} else {
+		/* task blocked in __switch_to */
+		frame.fp = thread_saved_fp(tsk);
+		frame.sp = thread_saved_sp(tsk);
+		/*
+		 * The function calling __switch_to cannot be a leaf function
+		 * so LR is recovered from the stack.
+		 */
+		frame.lr = 0;
+		frame.pc = thread_saved_pc(tsk);
+	}
+
+	low = frame.sp & ~(THREAD_SIZE - 1);
+	high = low + THREAD_SIZE;
+
+	while (1) {
+		int urc;
+		unsigned long where = frame.pc;
+
+		urc = unwind_frame(&frame);
+		if (urc < 0)
+			break;
+		dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+	}
+}
+
+struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
+				      unsigned long text_addr,
+				      unsigned long text_size)
+{
+	unsigned long flags;
+	struct unwind_idx *idx;
+	struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL);
+
+	pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
+		 text_addr, text_size);
+
+	if (!tab)
+		return tab;
+
+	tab->start = (struct unwind_idx *)start;
+	tab->stop = (struct unwind_idx *)(start + size);
+	tab->begin_addr = text_addr;
+	tab->end_addr = text_addr + text_size;
+
+	/* Convert the symbol addresses to absolute values */
+	for (idx = tab->start; idx < tab->stop; idx++)
+		idx->addr = prel31_to_addr(&idx->addr);
+
+	spin_lock_irqsave(&unwind_lock, flags);
+	list_add_tail(&tab->list, &unwind_tables);
+	spin_unlock_irqrestore(&unwind_lock, flags);
+
+	return tab;
+}
+
+void unwind_table_del(struct unwind_table *tab)
+{
+	unsigned long flags;
+
+	if (!tab)
+		return;
+
+	spin_lock_irqsave(&unwind_lock, flags);
+	list_del(&tab->list);
+	spin_unlock_irqrestore(&unwind_lock, flags);
+
+	kfree(tab);
+}
+
+int __init unwind_init(void)
+{
+	struct unwind_idx *idx;
+
+	/* Convert the symbol addresses to absolute values */
+	for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
+		idx->addr = prel31_to_addr(&idx->addr);
+
+	pr_debug("unwind: ARM stack unwinding initialised\n");
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/arm/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/arm/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,9 @@ SECTIONS
 		__initramfs_end = .;
 #endif
 		. = ALIGN(4096);
+		__per_cpu_load = .;
 		__per_cpu_start = .;
+			*(.data.percpu.page_aligned)
 			*(.data.percpu)
 			*(.data.percpu.shared_aligned)
 		__per_cpu_end = .;
@@ -80,6 +82,8 @@ SECTIONS
 		EXIT_TEXT
 		EXIT_DATA
 		*(.exitcall.exit)
+		*(.ARM.exidx.exit.text)
+		*(.ARM.extab.exit.text)
 #ifndef CONFIG_MMU
 		*(.fixup)
 		*(__ex_table)
@@ -110,6 +114,23 @@ SECTIONS
 
 	_etext = .;			/* End of text and rodata section */
 
+#ifdef CONFIG_ARM_UNWIND
+	/*
+	 * Stack unwinding tables
+	 */
+	. = ALIGN(8);
+	.ARM.unwind_idx : {
+		__start_unwind_idx = .;
+		*(.ARM.exidx*)
+		__stop_unwind_idx = .;
+	}
+	.ARM.unwind_tab : {
+		__start_unwind_tab = .;
+		*(.ARM.extab*)
+		__stop_unwind_tab = .;
+	}
+#endif
+
 #ifdef CONFIG_XIP_KERNEL
 	__data_loc = ALIGN(4);		/* location in binary */
 	. = PAGE_OFFSET + TEXT_OFFSET;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/lib/bitops.h linux-libre-2.6.30-gnu1/arch/arm/lib/bitops.h
--- linux-libre-2.6.29-gnu1/arch/arm/lib/bitops.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/lib/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,12 +18,14 @@
 	mov	r2, #1
 	add	r1, r1, r0, lsr #3	@ Get byte offset
 	mov	r3, r2, lsl r3		@ create mask
+	smp_dmb
 1:	ldrexb	r2, [r1]
 	ands	r0, r2, r3		@ save old value of bit
 	\instr	r2, r2, r3			@ toggle bit
 	strexb	ip, r2, [r1]
 	cmp	ip, #0
 	bne	1b
+	smp_dmb
 	cmp	r0, #0
 	movne	r0, #1
 2:	mov	pc, lr
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-aaec2000/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-aaec2000/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-aaec2000/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-aaec2000/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/at91rm9200_time.c linux-libre-2.6.30-gnu1/arch/arm/mach-at91/at91rm9200_time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/at91rm9200_time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/at91rm9200_time.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,7 +85,7 @@ static struct irqaction at91rm9200_timer
 	.handler	= at91rm9200_timer_interrupt
 };
 
-static cycle_t read_clk32k(void)
+static cycle_t read_clk32k(struct clocksource *cs)
 {
 	return read_CRTR();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/at91sam926x_time.c linux-libre-2.6.30-gnu1/arch/arm/mach-at91/at91sam926x_time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/at91sam926x_time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/at91sam926x_time.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ static u32 pit_cnt;		/* access only w/sy
  * Clocksource:  just a monotonic counter of MCK/16 cycles.
  * We don't care whether or not PIT irqs are enabled.
  */
-static cycle_t read_pit_clk(void)
+static cycle_t read_pit_clk(struct clocksource *cs)
 {
 	unsigned long flags;
 	u32 elapsed;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/board-sam9g20ek.c linux-libre-2.6.30-gnu1/arch/arm/mach-at91/board-sam9g20ek.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/board-sam9g20ek.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/board-sam9g20ek.c	2009-06-09 23:05:27.000000000 -0400
@@ -238,6 +238,10 @@ static void __init ek_board_init(void)
 	at91_add_device_i2c(NULL, 0);
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+	/* PCK0 provides MCLK to the WM8731 */
+	at91_set_B_periph(AT91_PIN_PC1, 0);
+	/* SSC (for WM8731) */
+	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
 }
 
 MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/generic.h linux-libre-2.6.30-gnu1/arch/arm/mach-at91/generic.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/generic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/generic.h	2009-06-09 23:05:27.000000000 -0400
@@ -47,9 +47,6 @@ extern void at91_irq_resume(void);
 #define AT91RM9200_BGA		4	/* AT91RM9200 BGA package has 4 banks */
 
 struct at91_gpio_bank {
-	unsigned chipbase;		/* bank's first GPIO number */
-	void __iomem *regbase;		/* base of register bank */
-	struct at91_gpio_bank *next;	/* bank sharing same IRQ/clock/... */
 	unsigned short id;		/* peripheral ID */
 	unsigned long offset;		/* offset from system peripheral base */
 	struct clk *clock;		/* associated clock */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/gpio.c linux-libre-2.6.30-gnu1/arch/arm/mach-at91/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,19 +24,59 @@
 #include <mach/at91_pio.h>
 #include <mach/gpio.h>
 
+#include <asm/gpio.h>
+
 #include "generic.h"
 
+struct at91_gpio_chip {
+	struct gpio_chip	chip;
+	struct at91_gpio_chip	*next;		/* Bank sharing same clock */
+	struct at91_gpio_bank	*bank;		/* Bank definition */
+	void __iomem		*regbase;	/* Base of register bank */
+};
+
+#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
 
-static struct at91_gpio_bank *gpio;
-static int gpio_banks;
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+					 unsigned offset, int val);
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+					unsigned offset);
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
+
+#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio)			\
+	{								\
+		.chip = {						\
+			.label		  = name,			\
+			.request	  = at91_gpiolib_request,	\
+			.direction_input  = at91_gpiolib_direction_input, \
+			.direction_output = at91_gpiolib_direction_output, \
+			.get		  = at91_gpiolib_get,		\
+			.set		  = at91_gpiolib_set,		\
+			.dbg_show	  = at91_gpiolib_dbg_show,	\
+			.base		  = base_gpio,			\
+			.ngpio		  = nr_gpio,			\
+		},							\
+	}
+
+static struct at91_gpio_chip gpio_chip[] = {
+	AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
+	AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
+	AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
+	AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
+	AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
+};
 
+static int gpio_banks;
 
 static inline void __iomem *pin_to_controller(unsigned pin)
 {
 	pin -= PIN_BASE;
 	pin /= 32;
 	if (likely(pin < gpio_banks))
-		return gpio[pin].regbase;
+		return gpio_chip[pin].regbase;
 
 	return NULL;
 }
@@ -197,39 +237,6 @@ int __init_or_module at91_set_multi_driv
 }
 EXPORT_SYMBOL(at91_set_multi_drive);
 
-/*--------------------------------------------------------------------------*/
-
-/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
- * called, and maybe at91_set_multi_drive() for putout pins.
- */
-
-int gpio_direction_input(unsigned pin)
-{
-	void __iomem	*pio = pin_to_controller(pin);
-	unsigned	mask = pin_to_mask(pin);
-
-	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
-		return -EINVAL;
-	__raw_writel(mask, pio + PIO_ODR);
-	return 0;
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-int gpio_direction_output(unsigned pin, int value)
-{
-	void __iomem	*pio = pin_to_controller(pin);
-	unsigned	mask = pin_to_mask(pin);
-
-	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
-		return -EINVAL;
-	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
-	__raw_writel(mask, pio + PIO_OER);
-	return 0;
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-/*--------------------------------------------------------------------------*/
-
 /*
  * assuming the pin is muxed as a gpio output, set its value.
  */
@@ -282,7 +289,7 @@ static int gpio_irq_set_wake(unsigned pi
 	else
 		wakeups[bank] &= ~mask;
 
-	set_irq_wake(gpio[bank].id, state);
+	set_irq_wake(gpio_chip[bank].bank->id, state);
 
 	return 0;
 }
@@ -292,14 +299,14 @@ void at91_gpio_suspend(void)
 	int i;
 
 	for (i = 0; i < gpio_banks; i++) {
-		void __iomem	*pio = gpio[i].regbase;
+		void __iomem	*pio = gpio_chip[i].regbase;
 
 		backups[i] = __raw_readl(pio + PIO_IMR);
 		__raw_writel(backups[i], pio + PIO_IDR);
 		__raw_writel(wakeups[i], pio + PIO_IER);
 
 		if (!wakeups[i])
-			clk_disable(gpio[i].clock);
+			clk_disable(gpio_chip[i].bank->clock);
 		else {
 #ifdef CONFIG_PM_DEBUG
 			printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
@@ -313,10 +320,10 @@ void at91_gpio_resume(void)
 	int i;
 
 	for (i = 0; i < gpio_banks; i++) {
-		void __iomem	*pio = gpio[i].regbase;
+		void __iomem	*pio = gpio_chip[i].regbase;
 
 		if (!wakeups[i])
-			clk_enable(gpio[i].clock);
+			clk_enable(gpio_chip[i].bank->clock);
 
 		__raw_writel(wakeups[i], pio + PIO_IDR);
 		__raw_writel(backups[i], pio + PIO_IER);
@@ -380,12 +387,12 @@ static void gpio_irq_handler(unsigned ir
 {
 	unsigned	pin;
 	struct irq_desc	*gpio;
-	struct at91_gpio_bank *bank;
+	struct at91_gpio_chip *at91_gpio;
 	void __iomem	*pio;
 	u32		isr;
 
-	bank = get_irq_chip_data(irq);
-	pio = bank->regbase;
+	at91_gpio = get_irq_chip_data(irq);
+	pio = at91_gpio->regbase;
 
 	/* temporarily mask (level sensitive) parent IRQ */
 	desc->chip->ack(irq);
@@ -396,14 +403,14 @@ static void gpio_irq_handler(unsigned ir
 		 */
 		isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
 		if (!isr) {
-			if (!bank->next)
+			if (!at91_gpio->next)
 				break;
-			bank = bank->next;
-			pio = bank->regbase;
+			at91_gpio = at91_gpio->next;
+			pio = at91_gpio->regbase;
 			continue;
 		}
 
-		pin = bank->chipbase;
+		pin = at91_gpio->chip.base;
 		gpio = &irq_desc[pin];
 
 		while (isr) {
@@ -502,17 +509,17 @@ static struct lock_class_key gpio_lock_c
 void __init at91_gpio_irq_setup(void)
 {
 	unsigned		pioc, pin;
-	struct at91_gpio_bank	*this, *prev;
+	struct at91_gpio_chip	*this, *prev;
 
-	for (pioc = 0, pin = PIN_BASE, this = gpio, prev = NULL;
+	for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
 			pioc++ < gpio_banks;
 			prev = this, this++) {
-		unsigned	id = this->id;
+		unsigned	id = this->bank->id;
 		unsigned	i;
 
 		__raw_writel(~0, this->regbase + PIO_IDR);
 
-		for (i = 0, pin = this->chipbase; i < 32; i++, pin++) {
+		for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
 			lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class);
 
 			/*
@@ -537,32 +544,117 @@ void __init at91_gpio_irq_setup(void)
 	pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
 }
 
+/* gpiolib support */
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+					unsigned offset)
+{
+	struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+	void __iomem *pio = at91_gpio->regbase;
+	unsigned mask = 1 << offset;
+
+	__raw_writel(mask, pio + PIO_ODR);
+	return 0;
+}
+
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+					 unsigned offset, int val)
+{
+	struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+	void __iomem *pio = at91_gpio->regbase;
+	unsigned mask = 1 << offset;
+
+	__raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+	__raw_writel(mask, pio + PIO_OER);
+	return 0;
+}
+
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+	void __iomem *pio = at91_gpio->regbase;
+	unsigned mask = 1 << offset;
+	u32 pdsr;
+
+	pdsr = __raw_readl(pio + PIO_PDSR);
+	return (pdsr & mask) != 0;
+}
+
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+	struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+	void __iomem *pio = at91_gpio->regbase;
+	unsigned mask = 1 << offset;
+
+	__raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+}
+
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
+{
+	unsigned pin = chip->base + offset;
+	void __iomem *pio = pin_to_controller(pin);
+	unsigned mask = pin_to_mask(pin);
+
+	/* Cannot request GPIOs that are in alternate function mode */
+	if (!(__raw_readl(pio + PIO_PSR) & mask))
+		return -EPERM;
+
+	return 0;
+}
+
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	int i;
+
+	for (i = 0; i < chip->ngpio; i++) {
+		unsigned pin = chip->base + i;
+		void __iomem *pio = pin_to_controller(pin);
+		unsigned mask = pin_to_mask(pin);
+		const char *gpio_label;
+
+		gpio_label = gpiochip_is_requested(chip, i);
+		if (gpio_label) {
+			seq_printf(s, "[%s] GPIO%s%d: ",
+				   gpio_label, chip->label, i);
+			if (__raw_readl(pio + PIO_PSR) & mask)
+				seq_printf(s, "[gpio] %s\n",
+					   at91_get_gpio_value(pin) ?
+					   "set" : "clear");
+			else
+				seq_printf(s, "[periph %s]\n",
+					   __raw_readl(pio + PIO_ABSR) &
+					   mask ? "B" : "A");
+		}
+	}
+}
+
 /*
  * Called from the processor-specific init to enable GPIO pin support.
  */
 void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
 {
 	unsigned		i;
-	struct at91_gpio_bank	*last;
+	struct at91_gpio_chip *at91_gpio, *last = NULL;
 
 	BUG_ON(nr_banks > MAX_GPIO_BANKS);
 
-	gpio = data;
 	gpio_banks = nr_banks;
 
-	for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) {
-		data->chipbase = PIN_BASE + i * 32;
-		data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS;
+	for (i = 0; i < nr_banks; i++) {
+		at91_gpio = &gpio_chip[i];
+
+		at91_gpio->bank = &data[i];
+		at91_gpio->chip.base = PIN_BASE + i * 32;
+		at91_gpio->regbase = at91_gpio->bank->offset +
+			(void __iomem *)AT91_VA_BASE_SYS;
 
 		/* enable PIO controller's clock */
-		clk_enable(data->clock);
+		clk_enable(at91_gpio->bank->clock);
 
-		/*
-		 * Some processors share peripheral ID between multiple GPIO banks.
-		 *  SAM9263 (PIOC, PIOD, PIOE)
-		 *  CAP9 (PIOA, PIOB, PIOC, PIOD)
-		 */
-		if (last && last->id == data->id)
-			last->next = data;
+		/* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
+		if (last && last->bank->id == at91_gpio->bank->id)
+			last->next = at91_gpio;
+		last = at91_gpio;
+
+		gpiochip_add(&at91_gpio->chip);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/board.h linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/board.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/board.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/board.h	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,7 @@ extern void __init at91_add_device_eth(s
  /* USB Host */
 struct at91_usbh_data {
 	u8		ports;		/* number of ports on root hub */
-	u8		vbus_pin[];	/* port power-control pin */
+	u8		vbus_pin[2];	/* port power-control pin */
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -213,32 +213,12 @@ extern void at91_gpio_resume(void);
  */
 
 #include <asm/errno.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-	return 0;
-}
-
-static inline void gpio_free(unsigned gpio)
-{
-	might_sleep();
-}
-
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-
-static inline int gpio_get_value(unsigned gpio)
-{
-	return at91_get_gpio_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	at91_set_gpio_value(gpio, value);
-}
-
 #include <asm-generic/gpio.h>		/* cansleep wrappers */
 
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+
 static inline int gpio_to_irq(unsigned gpio)
 {
 	return gpio;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -43,7 +43,7 @@ static inline void arch_idle(void)
 
 void (*at91_arch_reset)(void);
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/* call the CPU-specific reset function */
 	if (at91_arch_reset)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-at91/pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-at91/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-at91/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-at91/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,17 +198,17 @@ static int at91_pm_verify_clocks(void)
 	/* USB must not be using PLLB */
 	if (cpu_is_at91rm9200()) {
 		if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
 		if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	} else if (cpu_is_at91cap9()) {
 		if ((scsr & AT91CAP9_PMC_UHP) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	}
@@ -223,7 +223,7 @@ static int at91_pm_verify_clocks(void)
 
 		css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
-			pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-clps711x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-clps711x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-clps711x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-clps711x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ static inline void arch_idle(void)
 	mov	r0, r0");
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/board-dm644x-evm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,696 @@
+/*
+ * TI DaVinci EVM board support
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (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/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/etherdevice.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.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 <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>
+
+#define DM644X_EVM_PHY_MASK		(0x2)
+#define DM644X_EVM_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 DAVINCI_ASYNC_EMIF_DATA_CE1_BASE  0x04000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE  0x06000000
+#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE  0x08000000
+
+#define LXT971_PHY_ID	(0x001378e2)
+#define LXT971_PHY_MASK	(0xfffffff0)
+
+static struct mtd_partition davinci_evm_norflash_partitions[] = {
+	/* bootloader (UBL, U-Boot, etc) in first 5 sectors */
+	{
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= 5 * SZ_64K,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next 1 sectors */
+	{
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_64K,
+		.mask_flags	= 0,
+	},
+	/* kernel */
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_2M,
+		.mask_flags	= 0
+	},
+	/* file system */
+	{
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0
+	}
+};
+
+static struct physmap_flash_data davinci_evm_norflash_data = {
+	.width		= 2,
+	.parts		= davinci_evm_norflash_partitions,
+	.nr_parts	= ARRAY_SIZE(davinci_evm_norflash_partitions),
+};
+
+/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
+ * limits addresses to 16M, so using addresses past 16M will wrap */
+static struct resource davinci_evm_norflash_resource = {
+	.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+	.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device davinci_evm_norflash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &davinci_evm_norflash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &davinci_evm_norflash_resource,
+};
+
+/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks).
+ * It may used instead of the (default) NOR chip to boot, using TI's
+ * tools to install the secondary boot loader (UBL) and U-Boot.
+ */
+struct mtd_partition davinci_evm_nandflash_partition[] = {
+	/* Bootloader layout depends on whose u-boot is installed, but we
+	 * can hide all the details.
+	 *  - block 0 for u-boot environment ... in mainline u-boot
+	 *  - block 1 for UBL (plus up to four backup copies in blocks 2..5)
+	 *  - blocks 6...? for u-boot
+	 *  - blocks 16..23 for u-boot environment ... in TI's u-boot
+	 */
+	{
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= SZ_256K + SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	/* Kernel */
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	},
+	/* File system (older GIT kernels started this on the 5MB mark) */
+	{
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+	/* A few blocks at end hold a flash BBT ... created by TI's CCS
+	 * using flashwriter_nand.out, but ignored by TI's versions of
+	 * Linux and u-boot.  We boot faster by using them.
+	 */
+};
+
+static struct davinci_nand_pdata davinci_evm_nandflash_data = {
+	.parts		= davinci_evm_nandflash_partition,
+	.nr_parts	= ARRAY_SIZE(davinci_evm_nandflash_partition),
+	.ecc_mode	= NAND_ECC_HW,
+	.options	= NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_evm_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_evm_nandflash_device = {
+	.name		= "davinci_nand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &davinci_evm_nandflash_data,
+	},
+	.num_resources	= ARRAY_SIZE(davinci_evm_nandflash_resource),
+	.resource	= davinci_evm_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 platform_device rtc_dev = {
+	.name           = "rtc_davinci_evm",
+	.id             = -1,
+};
+
+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),
+	},
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * I2C GPIO expanders
+ */
+
+#define PCF_Uxx_BASE(x)	(DAVINCI_N_GPIO + ((x) * 8))
+
+
+/* U2 -- LEDs */
+
+static struct gpio_led evm_leds[] = {
+	{ .name = "DS8", .active_low = 1,
+		.default_trigger = "heartbeat", },
+	{ .name = "DS7", .active_low = 1, },
+	{ .name = "DS6", .active_low = 1, },
+	{ .name = "DS5", .active_low = 1, },
+	{ .name = "DS4", .active_low = 1, },
+	{ .name = "DS3", .active_low = 1, },
+	{ .name = "DS2", .active_low = 1,
+		.default_trigger = "mmc0", },
+	{ .name = "DS1", .active_low = 1,
+		.default_trigger = "ide-disk", },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+	.num_leds	= ARRAY_SIZE(evm_leds),
+	.leds		= evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int
+evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	struct gpio_led *leds = evm_leds;
+	int status;
+
+	while (ngpio--) {
+		leds->gpio = gpio++;
+		leds++;
+	}
+
+	/* what an extremely annoying way to be forced to handle
+	 * device unregistration ...
+	 */
+	evm_led_dev = platform_device_alloc("leds-gpio", 0);
+	platform_device_add_data(evm_led_dev,
+			&evm_led_data, sizeof evm_led_data);
+
+	evm_led_dev->dev.parent = &client->dev;
+	status = platform_device_add(evm_led_dev);
+	if (status < 0) {
+		platform_device_put(evm_led_dev);
+		evm_led_dev = NULL;
+	}
+	return status;
+}
+
+static int
+evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	if (evm_led_dev) {
+		platform_device_unregister(evm_led_dev);
+		evm_led_dev = NULL;
+	}
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u2 = {
+	.gpio_base	= PCF_Uxx_BASE(0),
+	.setup		= evm_led_setup,
+	.teardown	= evm_led_teardown,
+};
+
+
+/* U18 - A/V clock generator and user switch */
+
+static int sw_gpio;
+
+static ssize_t
+sw_show(struct device *d, struct device_attribute *a, char *buf)
+{
+	char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+
+	strcpy(buf, s);
+	return strlen(s);
+}
+
+static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
+
+static int
+evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	int	status;
+
+	/* export dip switch option */
+	sw_gpio = gpio + 7;
+	status = gpio_request(sw_gpio, "user_sw");
+	if (status == 0)
+		status = gpio_direction_input(sw_gpio);
+	if (status == 0)
+		status = device_create_file(&client->dev, &dev_attr_user_sw);
+	else
+		gpio_free(sw_gpio);
+	if (status != 0)
+		sw_gpio = -EINVAL;
+
+	/* audio PLL:  48 kHz (vs 44.1 or 32), single rate (vs double) */
+	gpio_request(gpio + 3, "pll_fs2");
+	gpio_direction_output(gpio + 3, 0);
+
+	gpio_request(gpio + 2, "pll_fs1");
+	gpio_direction_output(gpio + 2, 0);
+
+	gpio_request(gpio + 1, "pll_sr");
+	gpio_direction_output(gpio + 1, 0);
+
+	return 0;
+}
+
+static int
+evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	gpio_free(gpio + 1);
+	gpio_free(gpio + 2);
+	gpio_free(gpio + 3);
+
+	if (sw_gpio > 0) {
+		device_remove_file(&client->dev, &dev_attr_user_sw);
+		gpio_free(sw_gpio);
+	}
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u18 = {
+	.gpio_base	= PCF_Uxx_BASE(1),
+	.n_latch	= (1 << 3) | (1 << 2) | (1 << 1),
+	.setup		= evm_u18_setup,
+	.teardown	= evm_u18_teardown,
+};
+
+
+/* U35 - various I/O signals used to manage USB, CF, ATA, etc */
+
+static int
+evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	/* p0 = nDRV_VBUS (initial:  don't supply it) */
+	gpio_request(gpio + 0, "nDRV_VBUS");
+	gpio_direction_output(gpio + 0, 1);
+
+	/* p1 = VDDIMX_EN */
+	gpio_request(gpio + 1, "VDDIMX_EN");
+	gpio_direction_output(gpio + 1, 1);
+
+	/* p2 = VLYNQ_EN */
+	gpio_request(gpio + 2, "VLYNQ_EN");
+	gpio_direction_output(gpio + 2, 1);
+
+	/* p3 = n3V3_CF_RESET (initial: stay in reset) */
+	gpio_request(gpio + 3, "nCF_RESET");
+	gpio_direction_output(gpio + 3, 0);
+
+	/* (p4 unused) */
+
+	/* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
+	gpio_request(gpio + 5, "WLAN_RESET");
+	gpio_direction_output(gpio + 5, 1);
+
+	/* p6 = nATA_SEL (initial: select) */
+	gpio_request(gpio + 6, "nATA_SEL");
+	gpio_direction_output(gpio + 6, 0);
+
+	/* p7 = nCF_SEL (initial: deselect) */
+	gpio_request(gpio + 7, "nCF_SEL");
+	gpio_direction_output(gpio + 7, 1);
+
+	/* irlml6401 switches over 1A, in under 8 msec;
+	 * now it can be managed by nDRV_VBUS ...
+	 */
+	setup_usb(500, 8);
+
+	return 0;
+}
+
+static int
+evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 5);
+	gpio_free(gpio + 3);
+	gpio_free(gpio + 2);
+	gpio_free(gpio + 1);
+	gpio_free(gpio + 0);
+	return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u35 = {
+	.gpio_base	= PCF_Uxx_BASE(2),
+	.setup		= evm_u35_setup,
+	.teardown	= evm_u35_teardown,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ *  - 0x7f00, 6 bytes Ethernet Address
+ *  - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
+ *  - ... newer boards may have more
+ */
+static struct memory_accessor *at24_mem_acc;
+
+static void at24_setup(struct memory_accessor *mem_acc, void *context)
+{
+	DECLARE_MAC_BUF(mac_str);
+	char mac_addr[6];
+
+	at24_mem_acc = mem_acc;
+
+	/* Read MAC addr from EEPROM */
+	if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, 6) == 6) {
+		printk(KERN_INFO "Read MAC addr from EEPROM: %s\n",
+		       print_mac(mac_str, mac_addr));
+	}
+}
+
+static struct at24_platform_data eeprom_info = {
+	.byte_len	= (256*1024) / 8,
+	.page_size	= 64,
+	.flags		= AT24_FLAG_ADDR16,
+	.setup          = at24_setup,
+};
+
+int dm6446evm_eeprom_read(void *buf, off_t off, size_t count)
+{
+	if (at24_mem_acc)
+		return at24_mem_acc->read(at24_mem_acc, buf, off, count);
+	return -ENODEV;
+}
+EXPORT_SYMBOL(dm6446evm_eeprom_read);
+
+int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
+{
+	if (at24_mem_acc)
+		return at24_mem_acc->write(at24_mem_acc, buf, off, count);
+	return -ENODEV;
+}
+EXPORT_SYMBOL(dm6446evm_eeprom_write);
+
+/*
+ * MSP430 supports RTC, card detection, input from IR remote, and
+ * a bit more.  It triggers interrupts on GPIO(7) from pressing
+ * buttons on the IR remote, and for card detect switches.
+ */
+static struct i2c_client *dm6446evm_msp;
+
+static int dm6446evm_msp_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	dm6446evm_msp = client;
+	return 0;
+}
+
+static int dm6446evm_msp_remove(struct i2c_client *client)
+{
+	dm6446evm_msp = NULL;
+	return 0;
+}
+
+static const struct i2c_device_id dm6446evm_msp_ids[] = {
+	{ "dm6446evm_msp", 0, },
+	{ /* end of list */ },
+};
+
+static struct i2c_driver dm6446evm_msp_driver = {
+	.driver.name	= "dm6446evm_msp",
+	.id_table	= dm6446evm_msp_ids,
+	.probe		= dm6446evm_msp_probe,
+	.remove		= dm6446evm_msp_remove,
+};
+
+static int dm6444evm_msp430_get_pins(void)
+{
+	static const char txbuf[2] = { 2, 4, };
+	char buf[4];
+	struct i2c_msg msg[2] = {
+		{
+			.addr = dm6446evm_msp->addr,
+			.flags = 0,
+			.len = 2,
+			.buf = (void __force *)txbuf,
+		},
+		{
+			.addr = dm6446evm_msp->addr,
+			.flags = I2C_M_RD,
+			.len = 4,
+			.buf = buf,
+		},
+	};
+	int status;
+
+	if (!dm6446evm_msp)
+		return -ENXIO;
+
+	/* Command 4 == get input state, returns port 2 and port3 data
+	 *   S Addr W [A] len=2 [A] cmd=4 [A]
+	 *   RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P
+	 */
+	status = i2c_transfer(dm6446evm_msp->adapter, msg, 2);
+	if (status < 0)
+		return status;
+
+	dev_dbg(&dm6446evm_msp->dev,
+		"PINS: %02x %02x %02x %02x\n",
+		buf[0], buf[1], buf[2], buf[3]);
+
+	return (buf[3] << 8) | buf[2];
+}
+
+static struct i2c_board_info __initdata i2c_info[] =  {
+	{
+		I2C_BOARD_INFO("dm6446evm_msp", 0x23),
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x38),
+		.platform_data	= &pcf_data_u2,
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x39),
+		.platform_data	= &pcf_data_u18,
+	},
+	{
+		I2C_BOARD_INFO("pcf8574", 0x3a),
+		.platform_data	= &pcf_data_u35,
+	},
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &eeprom_info,
+	},
+	/* ALSO:
+	 * - tvl320aic33 audio codec (0x1b)
+	 * - tvp5146 video decoder (0x5d)
+	 */
+};
+
+/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
+ * which requires 100 usec of idle bus after i2c writes sent to it.
+ */
+static struct davinci_i2c_platform_data i2c_pdata = {
+	.bus_freq	= 20 /* kHz */,
+	.bus_delay	= 100 /* usec */,
+};
+
+static void __init evm_init_i2c(void)
+{
+	davinci_init_i2c(&i2c_pdata);
+	i2c_add_driver(&dm6446evm_msp_driver);
+	i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+	&davinci_fb_device,
+	&rtc_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+static void __init
+davinci_evm_map_io(void)
+{
+	davinci_map_common_io();
+	dm644x_init();
+}
+
+static int davinci_phy_fixup(struct phy_device *phydev)
+{
+	unsigned int control;
+	/* CRITICAL: Fix for increasing PHY signal drive strength for
+	 * TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
+	 * signal strength was low causing  TX to fail randomly. The
+	 * fix is to Set bit 11 (Increased MII drive strength) of PHY
+	 * register 26 (Digital Config register) on this phy. */
+	control = phy_read(phydev, 26);
+	phy_write(phydev, 26, (control | 0x800));
+	return 0;
+}
+
+#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_PHYSMAP) || \
+    defined(CONFIG_MTD_PHYSMAP_MODULE)
+#define HAS_NOR 1
+#else
+#define HAS_NOR 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_evm_init(void)
+{
+	struct clk *aemif_clk;
+
+	aemif_clk = clk_get(NULL, "aemif");
+	clk_enable(aemif_clk);
+
+	if (HAS_ATA) {
+		if (HAS_NAND || HAS_NOR)
+			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 || HAS_NOR) {
+		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_evm_nandflash_device);
+			evm_leds[7].default_trigger = "nand-disk";
+			if (HAS_NOR)
+				pr_warning("WARNING: both NAND and NOR flash "
+					"are enabled; disable one of them.\n");
+		} else if (HAS_NOR)
+			platform_device_register(&davinci_evm_norflash_device);
+	}
+
+	platform_add_devices(davinci_evm_devices,
+			     ARRAY_SIZE(davinci_evm_devices));
+	evm_init_i2c();
+
+	davinci_serial_init(&uart_config);
+
+	/* Register the fixup for PHY on DaVinci */
+	phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
+					davinci_phy_fixup);
+
+}
+
+static __init void davinci_evm_irq_init(void)
+{
+	davinci_irq_init();
+}
+
+MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
+	/* Maintainer: MontaVista Software <source@mvista.com> */
+	.phys_io      = IO_PHYS,
+	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params  = (DAVINCI_DDR_BASE + 0x100),
+	.map_io	      = davinci_evm_map_io,
+	.init_irq     = davinci_evm_irq_init,
+	.timer	      = &davinci_timer,
+	.init_machine = davinci_evm_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/board-evm.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/board-evm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/board-evm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/board-evm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,440 +0,0 @@
-/*
- * TI DaVinci EVM board support
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
- *
- * 2007 (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/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/i2c.h>
-#include <linux/i2c/pcf857x.h>
-#include <linux/i2c/at24.h>
-
-#include <linux/mtd/mtd.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/hardware.h>
-#include <mach/common.h>
-#include <mach/i2c.h>
-
-/* other misc. init functions */
-void __init davinci_psc_init(void);
-void __init davinci_irq_init(void);
-void __init davinci_map_common_io(void);
-void __init davinci_init_common_hw(void);
-
-#if defined(CONFIG_MTD_PHYSMAP) || \
-    defined(CONFIG_MTD_PHYSMAP_MODULE)
-
-static struct mtd_partition davinci_evm_norflash_partitions[] = {
-	/* bootloader (U-Boot, etc) in first 4 sectors */
-	{
-		.name		= "bootloader",
-		.offset		= 0,
-		.size		= 4 * SZ_64K,
-		.mask_flags	= MTD_WRITEABLE, /* force read-only */
-	},
-	/* bootloader params in the next 1 sectors */
-	{
-		.name		= "params",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= SZ_64K,
-		.mask_flags	= 0,
-	},
-	/* kernel */
-	{
-		.name		= "kernel",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= SZ_2M,
-		.mask_flags	= 0
-	},
-	/* file system */
-	{
-		.name		= "filesystem",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= MTDPART_SIZ_FULL,
-		.mask_flags	= 0
-	}
-};
-
-static struct physmap_flash_data davinci_evm_norflash_data = {
-	.width		= 2,
-	.parts		= davinci_evm_norflash_partitions,
-	.nr_parts	= ARRAY_SIZE(davinci_evm_norflash_partitions),
-};
-
-/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
- * limits addresses to 16M, so using addresses past 16M will wrap */
-static struct resource davinci_evm_norflash_resource = {
-	.start		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-	.end		= DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device davinci_evm_norflash_device = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &davinci_evm_norflash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &davinci_evm_norflash_resource,
-};
-
-#endif
-
-#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
-
-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_32BIT_MASK;
-
-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_32BIT_MASK,
-	},
-};
-
-#endif
-
-/*----------------------------------------------------------------------*/
-
-/*
- * I2C GPIO expanders
- */
-
-#define PCF_Uxx_BASE(x)	(DAVINCI_N_GPIO + ((x) * 8))
-
-
-/* U2 -- LEDs */
-
-static struct gpio_led evm_leds[] = {
-	{ .name = "DS8", .active_low = 1,
-		.default_trigger = "heartbeat", },
-	{ .name = "DS7", .active_low = 1, },
-	{ .name = "DS6", .active_low = 1, },
-	{ .name = "DS5", .active_low = 1, },
-	{ .name = "DS4", .active_low = 1, },
-	{ .name = "DS3", .active_low = 1, },
-	{ .name = "DS2", .active_low = 1,
-		.default_trigger = "mmc0", },
-	{ .name = "DS1", .active_low = 1,
-		.default_trigger = "ide-disk", },
-};
-
-static const struct gpio_led_platform_data evm_led_data = {
-	.num_leds	= ARRAY_SIZE(evm_leds),
-	.leds		= evm_leds,
-};
-
-static struct platform_device *evm_led_dev;
-
-static int
-evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	struct gpio_led *leds = evm_leds;
-	int status;
-
-	while (ngpio--) {
-		leds->gpio = gpio++;
-		leds++;
-	}
-
-	/* what an extremely annoying way to be forced to handle
-	 * device unregistration ...
-	 */
-	evm_led_dev = platform_device_alloc("leds-gpio", 0);
-	platform_device_add_data(evm_led_dev,
-			&evm_led_data, sizeof evm_led_data);
-
-	evm_led_dev->dev.parent = &client->dev;
-	status = platform_device_add(evm_led_dev);
-	if (status < 0) {
-		platform_device_put(evm_led_dev);
-		evm_led_dev = NULL;
-	}
-	return status;
-}
-
-static int
-evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	if (evm_led_dev) {
-		platform_device_unregister(evm_led_dev);
-		evm_led_dev = NULL;
-	}
-	return 0;
-}
-
-static struct pcf857x_platform_data pcf_data_u2 = {
-	.gpio_base	= PCF_Uxx_BASE(0),
-	.setup		= evm_led_setup,
-	.teardown	= evm_led_teardown,
-};
-
-
-/* U18 - A/V clock generator and user switch */
-
-static int sw_gpio;
-
-static ssize_t
-sw_show(struct device *d, struct device_attribute *a, char *buf)
-{
-	char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
-
-	strcpy(buf, s);
-	return strlen(s);
-}
-
-static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
-
-static int
-evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	int	status;
-
-	/* export dip switch option */
-	sw_gpio = gpio + 7;
-	status = gpio_request(sw_gpio, "user_sw");
-	if (status == 0)
-		status = gpio_direction_input(sw_gpio);
-	if (status == 0)
-		status = device_create_file(&client->dev, &dev_attr_user_sw);
-	else
-		gpio_free(sw_gpio);
-	if (status != 0)
-		sw_gpio = -EINVAL;
-
-	/* audio PLL:  48 kHz (vs 44.1 or 32), single rate (vs double) */
-	gpio_request(gpio + 3, "pll_fs2");
-	gpio_direction_output(gpio + 3, 0);
-
-	gpio_request(gpio + 2, "pll_fs1");
-	gpio_direction_output(gpio + 2, 0);
-
-	gpio_request(gpio + 1, "pll_sr");
-	gpio_direction_output(gpio + 1, 0);
-
-	return 0;
-}
-
-static int
-evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	gpio_free(gpio + 1);
-	gpio_free(gpio + 2);
-	gpio_free(gpio + 3);
-
-	if (sw_gpio > 0) {
-		device_remove_file(&client->dev, &dev_attr_user_sw);
-		gpio_free(sw_gpio);
-	}
-	return 0;
-}
-
-static struct pcf857x_platform_data pcf_data_u18 = {
-	.gpio_base	= PCF_Uxx_BASE(1),
-	.n_latch	= (1 << 3) | (1 << 2) | (1 << 1),
-	.setup		= evm_u18_setup,
-	.teardown	= evm_u18_teardown,
-};
-
-
-/* U35 - various I/O signals used to manage USB, CF, ATA, etc */
-
-static int
-evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	/* p0 = nDRV_VBUS (initial:  don't supply it) */
-	gpio_request(gpio + 0, "nDRV_VBUS");
-	gpio_direction_output(gpio + 0, 1);
-
-	/* p1 = VDDIMX_EN */
-	gpio_request(gpio + 1, "VDDIMX_EN");
-	gpio_direction_output(gpio + 1, 1);
-
-	/* p2 = VLYNQ_EN */
-	gpio_request(gpio + 2, "VLYNQ_EN");
-	gpio_direction_output(gpio + 2, 1);
-
-	/* p3 = n3V3_CF_RESET (initial: stay in reset) */
-	gpio_request(gpio + 3, "nCF_RESET");
-	gpio_direction_output(gpio + 3, 0);
-
-	/* (p4 unused) */
-
-	/* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
-	gpio_request(gpio + 5, "WLAN_RESET");
-	gpio_direction_output(gpio + 5, 1);
-
-	/* p6 = nATA_SEL (initial: select) */
-	gpio_request(gpio + 6, "nATA_SEL");
-	gpio_direction_output(gpio + 6, 0);
-
-	/* p7 = nCF_SEL (initial: deselect) */
-	gpio_request(gpio + 7, "nCF_SEL");
-	gpio_direction_output(gpio + 7, 1);
-
-	/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
-	setup_usb(500, 8);
-
-	return 0;
-}
-
-static int
-evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
-{
-	gpio_free(gpio + 7);
-	gpio_free(gpio + 6);
-	gpio_free(gpio + 5);
-	gpio_free(gpio + 3);
-	gpio_free(gpio + 2);
-	gpio_free(gpio + 1);
-	gpio_free(gpio + 0);
-	return 0;
-}
-
-static struct pcf857x_platform_data pcf_data_u35 = {
-	.gpio_base	= PCF_Uxx_BASE(2),
-	.setup		= evm_u35_setup,
-	.teardown	= evm_u35_teardown,
-};
-
-/*----------------------------------------------------------------------*/
-
-/* Most of this EEPROM is unused, but U-Boot uses some data:
- *  - 0x7f00, 6 bytes Ethernet Address
- *  - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
- *  - ... newer boards may have more
- */
-static struct at24_platform_data eeprom_info = {
-	.byte_len	= (256*1024) / 8,
-	.page_size	= 64,
-	.flags		= AT24_FLAG_ADDR16,
-};
-
-static struct i2c_board_info __initdata i2c_info[] =  {
-	{
-		I2C_BOARD_INFO("pcf8574", 0x38),
-		.platform_data	= &pcf_data_u2,
-	},
-	{
-		I2C_BOARD_INFO("pcf8574", 0x39),
-		.platform_data	= &pcf_data_u18,
-	},
-	{
-		I2C_BOARD_INFO("pcf8574", 0x3a),
-		.platform_data	= &pcf_data_u35,
-	},
-	{
-		I2C_BOARD_INFO("24c256", 0x50),
-		.platform_data	= &eeprom_info,
-	},
-	/* ALSO:
-	 * - tvl320aic33 audio codec (0x1b)
-	 * - msp430 microcontroller (0x23)
-	 * - tvp5146 video decoder (0x5d)
-	 */
-};
-
-/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
- * which requires 100 usec of idle bus after i2c writes sent to it.
- */
-static struct davinci_i2c_platform_data i2c_pdata = {
-	.bus_freq	= 20 /* kHz */,
-	.bus_delay	= 100 /* usec */,
-};
-
-static void __init evm_init_i2c(void)
-{
-	davinci_init_i2c(&i2c_pdata);
-	i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
-}
-
-static struct platform_device *davinci_evm_devices[] __initdata = {
-#if defined(CONFIG_MTD_PHYSMAP) || \
-    defined(CONFIG_MTD_PHYSMAP_MODULE)
-	&davinci_evm_norflash_device,
-#endif
-#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
-	&ide_dev,
-#endif
-};
-
-static void __init
-davinci_evm_map_io(void)
-{
-	davinci_map_common_io();
-}
-
-static __init void davinci_evm_init(void)
-{
-	davinci_psc_init();
-
-#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
-#if defined(CONFIG_MTD_PHYSMAP) || \
-    defined(CONFIG_MTD_PHYSMAP_MODULE)
-	printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
-	       "but share pins.\n\t Disable IDE for NOR support.\n");
-#endif
-#endif
-
-	platform_add_devices(davinci_evm_devices,
-			     ARRAY_SIZE(davinci_evm_devices));
-	evm_init_i2c();
-}
-
-static __init void davinci_evm_irq_init(void)
-{
-	davinci_init_common_hw();
-	davinci_irq_init();
-}
-
-MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
-	/* Maintainer: MontaVista Software <source@mvista.com> */
-	.phys_io      = IO_PHYS,
-	.io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
-	.boot_params  = (DAVINCI_DDR_BASE + 0x100),
-	.map_io	      = davinci_evm_map_io,
-	.init_irq     = davinci_evm_irq_init,
-	.timer	      = &davinci_timer,
-	.init_machine = davinci_evm_init,
-MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,8 @@
 /*
- * TI DaVinci clock config file
+ * Clock and PLL control for DaVinci devices
  *
- * Copyright (C) 2006 Texas Instruments.
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
@@ -21,98 +23,50 @@
 #include <mach/hardware.h>
 
 #include <mach/psc.h>
+#include <mach/cputype.h>
 #include "clock.h"
 
-/* PLL/Reset register offsets */
-#define PLLM		0x110
-
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
 static DEFINE_SPINLOCK(clockfw_lock);
 
-static unsigned int commonrate;
-static unsigned int armrate;
-static unsigned int fixedrate = 27000000;	/* 27 MHZ */
-
-extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
-
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
-	int idno;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	mutex_lock(&clocks_mutex);
-
-	list_for_each_entry(p, &clocks, node) {
-		if (p->id == idno &&
-		    strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			goto found;
-		}
-	}
-
-	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-
-found:
-	mutex_unlock(&clocks_mutex);
-
-	return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
+static unsigned psc_domain(struct clk *clk)
 {
-	if (clk && !IS_ERR(clk))
-		module_put(clk->owner);
+	return (clk->flags & PSC_DSP)
+		? DAVINCI_GPSC_DSPDOMAIN
+		: DAVINCI_GPSC_ARMDOMAIN;
 }
-EXPORT_SYMBOL(clk_put);
 
-static int __clk_enable(struct clk *clk)
+static void __clk_enable(struct clk *clk)
 {
-	if (clk->flags & ALWAYS_ENABLED)
-		return 0;
-
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
-	return 0;
+	if (clk->parent)
+		__clk_enable(clk->parent);
+	if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
+		davinci_psc_config(psc_domain(clk), clk->lpsc, 1);
 }
 
 static void __clk_disable(struct clk *clk)
 {
-	if (clk->usecount)
+	if (WARN_ON(clk->usecount == 0))
 		return;
-
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
+	if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
+		davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
+	if (clk->parent)
+		__clk_disable(clk->parent);
 }
 
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
-	int ret = 0;
 
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
-	if (clk->usecount++ == 0) {
-		spin_lock_irqsave(&clockfw_lock, flags);
-		ret = __clk_enable(clk);
-		spin_unlock_irqrestore(&clockfw_lock, flags);
-	}
+	spin_lock_irqsave(&clockfw_lock, flags);
+	__clk_enable(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(clk_enable);
 
@@ -123,11 +77,9 @@ void clk_disable(struct clk *clk)
 	if (clk == NULL || IS_ERR(clk))
 		return;
 
-	if (clk->usecount > 0 && !(--clk->usecount)) {
-		spin_lock_irqsave(&clockfw_lock, flags);
-		__clk_disable(clk);
-		spin_unlock_irqrestore(&clockfw_lock, flags);
-	}
+	spin_lock_irqsave(&clockfw_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
@@ -136,7 +88,7 @@ unsigned long clk_get_rate(struct clk *c
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
-	return *(clk->rate);
+	return clk->rate;
 }
 EXPORT_SYMBOL(clk_get_rate);
 
@@ -145,7 +97,7 @@ long clk_round_rate(struct clk *clk, uns
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
-	return *(clk->rate);
+	return clk->rate;
 }
 EXPORT_SYMBOL(clk_round_rate);
 
@@ -164,10 +116,23 @@ int clk_register(struct clk *clk)
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	if (WARN(clk->parent && !clk->parent->rate,
+			"CLK: %s parent %s has no rate!\n",
+			clk->name, clk->parent->name))
+		return -EINVAL;
+
 	mutex_lock(&clocks_mutex);
-	list_add(&clk->node, &clocks);
+	list_add_tail(&clk->node, &clocks);
 	mutex_unlock(&clocks_mutex);
 
+	/* If rate is already set, use it */
+	if (clk->rate)
+		return 0;
+
+	/* Otherwise, default to parent rate */
+	if (clk->parent)
+		clk->rate = clk->parent->rate;
+
 	return 0;
 }
 EXPORT_SYMBOL(clk_register);
@@ -183,84 +148,150 @@ void clk_unregister(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_unregister);
 
-static struct clk davinci_clks[] = {
-	{
-		.name = "ARMCLK",
-		.rate = &armrate,
-		.lpsc = -1,
-		.flags = ALWAYS_ENABLED,
-	},
-	{
-		.name = "UART",
-		.rate = &fixedrate,
-		.lpsc = DAVINCI_LPSC_UART0,
-	},
-	{
-		.name = "EMACCLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
-	},
-	{
-		.name = "I2CCLK",
-		.rate = &fixedrate,
-		.lpsc = DAVINCI_LPSC_I2C,
-	},
-	{
-		.name = "IDECLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_ATA,
-	},
-	{
-		.name = "McBSPCLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_McBSP,
-	},
-	{
-		.name = "MMCSDCLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_MMC_SD,
-	},
-	{
-		.name = "SPICLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_SPI,
-	},
-	{
-		.name = "gpio",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_GPIO,
-	},
-	{
-		.name = "usb",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_USB,
-	},
-	{
-		.name = "AEMIFCLK",
-		.rate = &commonrate,
-		.lpsc = DAVINCI_LPSC_AEMIF,
-		.usecount = 1,
+#ifdef CONFIG_DAVINCI_RESET_CLOCKS
+/*
+ * Disable any unused clocks left on by the bootloader
+ */
+static int __init clk_disable_unused(void)
+{
+	struct clk *ck;
+
+	spin_lock_irq(&clockfw_lock);
+	list_for_each_entry(ck, &clocks, node) {
+		if (ck->usecount > 0)
+			continue;
+		if (!(ck->flags & CLK_PSC))
+			continue;
+
+		/* ignore if in Disabled or SwRstDisable states */
+		if (!davinci_psc_is_clk_active(ck->lpsc))
+			continue;
+
+		pr_info("Clocks: disable unused %s\n", ck->name);
+		davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
 	}
-};
+	spin_unlock_irq(&clockfw_lock);
 
-int __init davinci_clk_init(void)
+	return 0;
+}
+late_initcall(clk_disable_unused);
+#endif
+
+static void clk_sysclk_recalc(struct clk *clk)
 {
-	struct clk *clkp;
-	int count = 0;
-	u32 pll_mult;
+	u32 v, plldiv;
+	struct pll_data *pll;
 
-	pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
-	commonrate = ((pll_mult + 1) * 27000000) / 6;
-	armrate = ((pll_mult + 1) * 27000000) / 2;
+	/* If this is the PLL base clock, no more calculations needed */
+	if (clk->pll_data)
+		return;
 
-	for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
-	     count++, clkp++) {
-		clk_register(clkp);
+	if (WARN_ON(!clk->parent))
+		return;
 
-		/* Turn on clocks that have been enabled in the
-		 * table above */
-		if (clkp->usecount)
-			clk_enable(clkp);
+	clk->rate = clk->parent->rate;
+
+	/* Otherwise, the parent must be a PLL */
+	if (WARN_ON(!clk->parent->pll_data))
+		return;
+
+	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;
+
+	if (!clk->div_reg)
+		return;
+
+	v = __raw_readl(pll->base + clk->div_reg);
+	if (v & PLLDIV_EN) {
+		plldiv = (v & PLLDIV_RATIO_MASK) + 1;
+		if (plldiv)
+			clk->rate /= plldiv;
+	}
+}
+
+static void __init clk_pll_init(struct clk *clk)
+{
+	u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
+	u8 bypass;
+	struct pll_data *pll = clk->pll_data;
+
+	pll->base = IO_ADDRESS(pll->phys_base);
+	ctrl = __raw_readl(pll->base + PLLCTL);
+	clk->rate = pll->input_rate = clk->parent->rate;
+
+	if (ctrl & PLLCTL_PLLEN) {
+		bypass = 0;
+		mult = __raw_readl(pll->base + PLLM);
+		mult = (mult & PLLM_PLLM_MASK) + 1;
+	} else
+		bypass = 1;
+
+	if (pll->flags & PLL_HAS_PREDIV) {
+		prediv = __raw_readl(pll->base + PREDIV);
+		if (prediv & PLLDIV_EN)
+			prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
+		else
+			prediv = 1;
+	}
+
+	/* pre-divider is fixed, but (some?) chips won't report that */
+	if (cpu_is_davinci_dm355() && pll->num == 1)
+		prediv = 8;
+
+	if (pll->flags & PLL_HAS_POSTDIV) {
+		postdiv = __raw_readl(pll->base + POSTDIV);
+		if (postdiv & PLLDIV_EN)
+			postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
+		else
+			postdiv = 1;
+	}
+
+	if (!bypass) {
+		clk->rate /= prediv;
+		clk->rate *= mult;
+		clk->rate /= postdiv;
+	}
+
+	pr_debug("PLL%d: input = %lu MHz [ ",
+		 pll->num, clk->parent->rate / 1000000);
+	if (bypass)
+		pr_debug("bypass ");
+	if (prediv > 1)
+		pr_debug("/ %d ", prediv);
+	if (mult > 1)
+		pr_debug("* %d ", mult);
+	if (postdiv > 1)
+		pr_debug("/ %d ", postdiv);
+	pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
+}
+
+int __init davinci_clk_init(struct davinci_clk *clocks)
+  {
+	struct davinci_clk *c;
+	struct clk *clk;
+
+	for (c = clocks; c->lk.clk; c++) {
+		clk = c->lk.clk;
+
+		if (clk->pll_data)
+			clk_pll_init(clk);
+
+		/* Calculate rates for PLL-derived clocks */
+		else if (clk->flags & CLK_PLL)
+			clk_sysclk_recalc(clk);
+
+		if (clk->lpsc)
+			clk->flags |= CLK_PSC;
+
+		clkdev_add(&c->lk);
+		clk_register(clk);
+
+		/* Turn on clocks that Linux doesn't otherwise manage */
+		if (clk->flags & ALWAYS_ENABLED)
+			clk_enable(clk);
 	}
 
 	return 0;
@@ -285,12 +316,52 @@ static void davinci_ck_stop(struct seq_f
 {
 }
 
-static int davinci_ck_show(struct seq_file *m, void *v)
+#define CLKNAME_MAX	10		/* longest clock name */
+#define NEST_DELTA	2
+#define NEST_MAX	4
+
+static void
+dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
 {
-	struct clk *cp;
+	char		*state;
+	char		buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
+	struct clk	*clk;
+	unsigned	i;
 
-	list_for_each_entry(cp, &clocks, node)
-		seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
+	if (parent->flags & CLK_PLL)
+		state = "pll";
+	else if (parent->flags & CLK_PSC)
+		state = "psc";
+	else
+		state = "";
+
+	/* <nest spaces> name <pad to end> */
+	memset(buf, ' ', sizeof(buf) - 1);
+	buf[sizeof(buf) - 1] = 0;
+	i = strlen(parent->name);
+	memcpy(buf + nest, parent->name,
+			min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+	seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
+		   buf, parent->usecount, state, clk_get_rate(parent));
+	/* 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);
+	}
+}
+
+static int davinci_ck_show(struct seq_file *m, void *v)
+{
+	/* Show clock tree; we know the main oscillator is first.
+	 * We trust nonzero usecounts equate to PSC enables...
+	 */
+	mutex_lock(&clocks_mutex);
+	if (!list_empty(&clocks))
+		dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
+	mutex_unlock(&clocks_mutex);
 
 	return 0;
 }
@@ -321,4 +392,4 @@ static int __init davinci_ck_proc_init(v
 
 }
 __initcall(davinci_ck_proc_init);
-#endif	/* CONFIG_DEBUG_PROC_FS */
+#endif /* CONFIG_DEBUG_PROC_FS */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,8 @@
 /*
  * TI DaVinci clock definitions
  *
- * Copyright (C) 2006 Texas Instruments.
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,23 +12,85 @@
 #ifndef __ARCH_ARM_DAVINCI_CLOCK_H
 #define __ARCH_ARM_DAVINCI_CLOCK_H
 
+#include <linux/list.h>
+#include <asm/clkdev.h>
+
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define MAX_PLL 2
+
+/* PLL/Reset register offsets */
+#define PLLCTL          0x100
+#define PLLCTL_PLLEN    BIT(0)
+#define PLLCTL_CLKMODE  BIT(8)
+
+#define PLLM		0x110
+#define PLLM_PLLM_MASK  0xff
+
+#define PREDIV          0x114
+#define PLLDIV1         0x118
+#define PLLDIV2         0x11c
+#define PLLDIV3         0x120
+#define POSTDIV         0x128
+#define BPDIV           0x12c
+#define PLLCMD		0x138
+#define PLLSTAT		0x13c
+#define PLLALNCTL	0x140
+#define PLLDCHANGE	0x144
+#define PLLCKEN		0x148
+#define PLLCKSTAT	0x14c
+#define PLLSYSTAT	0x150
+#define PLLDIV4         0x160
+#define PLLDIV5         0x164
+#define PLLDIV6         0x168
+#define PLLDIV7         0x16c
+#define PLLDIV8         0x170
+#define PLLDIV9         0x174
+#define PLLDIV_EN       BIT(15)
+#define PLLDIV_RATIO_MASK 0x1f
+
+struct pll_data {
+	u32 phys_base;
+	void __iomem *base;
+	u32 num;
+	u32 flags;
+	u32 input_rate;
+};
+#define PLL_HAS_PREDIV          0x01
+#define PLL_HAS_POSTDIV         0x02
+
 struct clk {
 	struct list_head	node;
 	struct module		*owner;
 	const char		*name;
-	unsigned int		*rate;
-	int			id;
-	__s8			usecount;
-	__u8			flags;
-	__u8			lpsc;
+	unsigned long		rate;
+	u8			usecount;
+	u8			flags;
+	u8			lpsc;
+	struct clk              *parent;
+	struct pll_data         *pll_data;
+	u32                     div_reg;
 };
 
 /* Clock flags */
-#define RATE_CKCTL		1
-#define RATE_FIXED		2
-#define RATE_PROPAGATES		4
-#define VIRTUAL_CLOCK		8
-#define ALWAYS_ENABLED		16
-#define ENABLE_REG_32BIT	32
+#define ALWAYS_ENABLED		BIT(1)
+#define CLK_PSC                 BIT(2)
+#define PSC_DSP                 BIT(3) /* PSC uses DSP domain, not ARM */
+#define CLK_PLL			BIT(4) /* PLL-derived clock */
+#define PRE_PLL                 BIT(5) /* source is before PLL mult/div */
+
+struct davinci_clk {
+	struct clk_lookup lk;
+};
 
+#define CLK(dev, con, ck) 		\
+	{				\
+		.lk = {			\
+			.dev_id = dev,	\
+			.con_id = con,	\
+			.clk = ck,	\
+		},			\
+	}
+
+int davinci_clk_init(struct davinci_clk *clocks);
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,10 @@
 #include <mach/hardware.h>
 #include <mach/i2c.h>
 #include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/mux.h>
+
+#define DAVINCI_I2C_BASE	     0x01C21000
 
 static struct resource i2c_resources[] = {
 	{
@@ -43,6 +47,9 @@ static struct platform_device davinci_i2
 
 void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
 {
+	if (cpu_is_davinci_dm644x())
+		davinci_cfg_reg(DM644X_I2C);
+
 	davinci_i2c_device.dev.platform_data = pdata;
 	(void) platform_device_register(&davinci_i2c_device);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/dm644x.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/dm644x.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/dm644x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/dm644x.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,461 @@
+/*
+ * TI DaVinci DM644x chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. 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/clk.h>
+#include <linux/platform_device.h>
+
+#include <mach/dm644x.h>
+#include <mach/clock.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/irqs.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/*
+ * Device specific clocks
+ */
+#define DM644X_REF_FREQ		27000000
+
+static struct pll_data pll1_data = {
+	.num       = 1,
+	.phys_base = DAVINCI_PLL1_BASE,
+};
+
+static struct pll_data pll2_data = {
+	.num       = 2,
+	.phys_base = DAVINCI_PLL2_BASE,
+};
+
+static struct clk ref_clk = {
+	.name = "ref_clk",
+	.rate = DM644X_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+	.name = "pll1",
+	.parent = &ref_clk,
+	.pll_data = &pll1_data,
+	.flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+	.name = "pll1_sysclk1",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+	.name = "pll1_sysclk2",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+	.name = "pll1_sysclk3",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk5 = {
+	.name = "pll1_sysclk5",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV5,
+};
+
+static struct clk pll1_aux_clk = {
+	.name = "pll1_aux_clk",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+	.name = "pll1_sysclkbp",
+	.parent = &pll1_clk,
+	.flags = CLK_PLL | PRE_PLL,
+	.div_reg = BPDIV
+};
+
+static struct clk pll2_clk = {
+	.name = "pll2",
+	.parent = &ref_clk,
+	.pll_data = &pll2_data,
+	.flags = CLK_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+	.name = "pll2_sysclk1",
+	.parent = &pll2_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+	.name = "pll2_sysclk2",
+	.parent = &pll2_clk,
+	.flags = CLK_PLL,
+	.div_reg = PLLDIV2,
+};
+
+static struct clk pll2_sysclkbp = {
+	.name = "pll2_sysclkbp",
+	.parent = &pll2_clk,
+	.flags = CLK_PLL | PRE_PLL,
+	.div_reg = BPDIV
+};
+
+static struct clk dsp_clk = {
+	.name = "dsp",
+	.parent = &pll1_sysclk1,
+	.lpsc = DAVINCI_LPSC_GEM,
+	.flags = PSC_DSP,
+	.usecount = 1,			/* REVISIT how to disable? */
+};
+
+static struct clk arm_clk = {
+	.name = "arm",
+	.parent = &pll1_sysclk2,
+	.lpsc = DAVINCI_LPSC_ARM,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk vicp_clk = {
+	.name = "vicp",
+	.parent = &pll1_sysclk2,
+	.lpsc = DAVINCI_LPSC_IMCOP,
+	.flags = PSC_DSP,
+	.usecount = 1,			/* REVISIT how to disable? */
+};
+
+static struct clk vpss_master_clk = {
+	.name = "vpss_master",
+	.parent = &pll1_sysclk3,
+	.lpsc = DAVINCI_LPSC_VPSSMSTR,
+	.flags = CLK_PSC,
+};
+
+static struct clk vpss_slave_clk = {
+	.name = "vpss_slave",
+	.parent = &pll1_sysclk3,
+	.lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+static struct clk uart0_clk = {
+	.name = "uart0",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+	.name = "uart1",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+	.name = "uart2",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_UART2,
+};
+
+static struct clk emac_clk = {
+	.name = "emac",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
+};
+
+static struct clk i2c_clk = {
+	.name = "i2c",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk ide_clk = {
+	.name = "ide",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_ATA,
+};
+
+static struct clk asp_clk = {
+	.name = "asp0",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_McBSP,
+};
+
+static struct clk mmcsd_clk = {
+	.name = "mmcsd",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk spi_clk = {
+	.name = "spi",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk gpio_clk = {
+	.name = "gpio",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk usb_clk = {
+	.name = "usb",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk vlynq_clk = {
+	.name = "vlynq",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_VLYNQ,
+};
+
+static struct clk aemif_clk = {
+	.name = "aemif",
+	.parent = &pll1_sysclk5,
+	.lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+	.name = "pwm0",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+	.name = "pwm1",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+	.name = "pwm2",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk timer0_clk = {
+	.name = "timer0",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+	.name = "timer1",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+	.name = "timer2",
+	.parent = &pll1_aux_clk,
+	.lpsc = DAVINCI_LPSC_TIMER2,
+	.usecount = 1,              /* REVISIT: why cant' this be disabled? */
+};
+
+struct davinci_clk dm644x_clks[] = {
+	CLK(NULL, "ref", &ref_clk),
+	CLK(NULL, "pll1", &pll1_clk),
+	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+	CLK(NULL, "pll1_aux", &pll1_aux_clk),
+	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+	CLK(NULL, "pll2", &pll2_clk),
+	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+	CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+	CLK(NULL, "dsp", &dsp_clk),
+	CLK(NULL, "arm", &arm_clk),
+	CLK(NULL, "vicp", &vicp_clk),
+	CLK(NULL, "vpss_master", &vpss_master_clk),
+	CLK(NULL, "vpss_slave", &vpss_slave_clk),
+	CLK(NULL, "arm", &arm_clk),
+	CLK(NULL, "uart0", &uart0_clk),
+	CLK(NULL, "uart1", &uart1_clk),
+	CLK(NULL, "uart2", &uart2_clk),
+	CLK("davinci_emac.1", NULL, &emac_clk),
+	CLK("i2c_davinci.1", NULL, &i2c_clk),
+	CLK("palm_bk3710", NULL, &ide_clk),
+	CLK("soc-audio.0", NULL, &asp_clk),
+	CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+	CLK(NULL, "spi", &spi_clk),
+	CLK(NULL, "gpio", &gpio_clk),
+	CLK(NULL, "usb", &usb_clk),
+	CLK(NULL, "vlynq", &vlynq_clk),
+	CLK(NULL, "aemif", &aemif_clk),
+	CLK(NULL, "pwm0", &pwm0_clk),
+	CLK(NULL, "pwm1", &pwm1_clk),
+	CLK(NULL, "pwm2", &pwm2_clk),
+	CLK(NULL, "timer0", &timer0_clk),
+	CLK(NULL, "timer1", &timer1_clk),
+	CLK("watchdog", NULL, &timer2_clk),
+	CLK(NULL, NULL, NULL),
+};
+
+#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
+
+static struct resource dm644x_emac_resources[] = {
+	{
+		.start	= DM644X_EMAC_BASE,
+		.end	= DM644X_EMAC_BASE + 0x47ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_EMACINT,
+		.end   = IRQ_EMACINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm644x_emac_device = {
+       .name		= "davinci_emac",
+       .id		= 1,
+       .num_resources	= ARRAY_SIZE(dm644x_emac_resources),
+       .resource	= dm644x_emac_resources,
+};
+
+#endif
+
+/*
+ * Device specific mux setup
+ *
+ *	soc	description	mux  mode   mode  mux	 dbg
+ *				reg  offset mask  mode
+ */
+static const struct mux_config dm644x_pins[] = {
+MUX_CFG(DM644X, HDIREN,		0,   16,    1,	  1,	 true)
+MUX_CFG(DM644X, ATAEN,		0,   17,    1,	  1,	 true)
+MUX_CFG(DM644X, ATAEN_DISABLE,	0,   17,    1,	  0,	 true)
+
+MUX_CFG(DM644X, HPIEN_DISABLE,	0,   29,    1,	  0,	 true)
+
+MUX_CFG(DM644X, AEAW,		0,   0,     31,	  31,	 true)
+
+MUX_CFG(DM644X, MSTK,		1,   9,     1,	  0,	 false)
+
+MUX_CFG(DM644X, I2C,		1,   7,     1,	  1,	 false)
+
+MUX_CFG(DM644X, MCBSP,		1,   10,    1,	  1,	 false)
+
+MUX_CFG(DM644X, UART1,		1,   1,     1,	  1,	 true)
+MUX_CFG(DM644X, UART2,		1,   2,     1,	  1,	 true)
+
+MUX_CFG(DM644X, PWM0,		1,   4,     1,	  1,	 false)
+
+MUX_CFG(DM644X, PWM1,		1,   5,     1,	  1,	 false)
+
+MUX_CFG(DM644X, PWM2,		1,   6,     1,	  1,	 false)
+
+MUX_CFG(DM644X, VLYNQEN,	0,   15,    1,	  1,	 false)
+MUX_CFG(DM644X, VLSCREN,	0,   14,    1,	  1,	 false)
+MUX_CFG(DM644X, VLYNQWD,	0,   12,    3,	  3,	 false)
+
+MUX_CFG(DM644X, EMACEN,		0,   31,    1,	  1,	 true)
+
+MUX_CFG(DM644X, GPIO3V,		0,   31,    1,	  0,	 true)
+
+MUX_CFG(DM644X, GPIO0,		0,   24,    1,	  0,	 true)
+MUX_CFG(DM644X, GPIO3,		0,   25,    1,	  0,	 false)
+MUX_CFG(DM644X, GPIO43_44,	1,   7,     1,	  0,	 false)
+MUX_CFG(DM644X, GPIO46_47,	0,   22,    1,	  0,	 true)
+
+MUX_CFG(DM644X, RGB666,		0,   22,    1,	  1,	 true)
+
+MUX_CFG(DM644X, LOEEN,		0,   24,    1,	  1,	 true)
+MUX_CFG(DM644X, LFLDEN,		0,   25,    1,	  1,	 false)
+};
+
+
+/*----------------------------------------------------------------------*/
+
+static const s8 dma_chan_dm644x_no_event[] = {
+	 0,  1, 12, 13, 14,
+	15, 25, 30, 31, 45,
+	46, 47, 55, 56, 57,
+	58, 59, 60, 61, 62,
+	63,
+	-1
+};
+
+static struct edma_soc_info dm644x_edma_info = {
+	.n_channel	= 64,
+	.n_region	= 4,
+	.n_slot		= 128,
+	.n_tc		= 2,
+	.noevent	= dma_chan_dm644x_no_event,
+};
+
+static struct resource edma_resources[] = {
+	{
+		.name	= "edma_cc",
+		.start	= 0x01c00000,
+		.end	= 0x01c00000 + SZ_64K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc0",
+		.start	= 0x01c10000,
+		.end	= 0x01c10000 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc1",
+		.start	= 0x01c10400,
+		.end	= 0x01c10400 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_CCINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_CCERRINT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	/* not using TC*_ERR */
+};
+
+static struct platform_device dm644x_edma_device = {
+	.name			= "edma",
+	.id			= -1,
+	.dev.platform_data	= &dm644x_edma_info,
+	.num_resources		= ARRAY_SIZE(edma_resources),
+	.resource		= edma_resources,
+};
+
+/*----------------------------------------------------------------------*/
+void __init dm644x_init(void)
+{
+	davinci_clk_init(dm644x_clks);
+	davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins));
+}
+
+static int __init dm644x_init_devices(void)
+{
+	if (!cpu_is_davinci_dm644x())
+		return 0;
+
+	platform_device_register(&dm644x_edma_device);
+	return 0;
+}
+postcore_initcall(dm644x_init_devices);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1135 @@
+/*
+ * EDMA3 support for DaVinci
+ *
+ * Copyright (C) 2006-2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/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
+#define PARM_SRC		0x04
+#define PARM_A_B_CNT		0x08
+#define PARM_DST		0x0c
+#define PARM_SRC_DST_BIDX	0x10
+#define PARM_LINK_BCNTRLD	0x14
+#define PARM_SRC_DST_CIDX	0x18
+#define PARM_CCNT		0x1c
+
+#define PARM_SIZE		0x20
+
+/* Offsets for EDMA CC global channel registers and their shadows */
+#define SH_ER		0x00	/* 64 bits */
+#define SH_ECR		0x08	/* 64 bits */
+#define SH_ESR		0x10	/* 64 bits */
+#define SH_CER		0x18	/* 64 bits */
+#define SH_EER		0x20	/* 64 bits */
+#define SH_EECR		0x28	/* 64 bits */
+#define SH_EESR		0x30	/* 64 bits */
+#define SH_SER		0x38	/* 64 bits */
+#define SH_SECR		0x40	/* 64 bits */
+#define SH_IER		0x50	/* 64 bits */
+#define SH_IECR		0x58	/* 64 bits */
+#define SH_IESR		0x60	/* 64 bits */
+#define SH_IPR		0x68	/* 64 bits */
+#define SH_ICR		0x70	/* 64 bits */
+#define SH_IEVAL	0x78
+#define SH_QER		0x80
+#define SH_QEER		0x84
+#define SH_QEECR	0x88
+#define SH_QEESR	0x8c
+#define SH_QSER		0x90
+#define SH_QSECR	0x94
+#define SH_SIZE		0x200
+
+/* Offsets for EDMA CC global registers */
+#define EDMA_REV	0x0000
+#define EDMA_CCCFG	0x0004
+#define EDMA_QCHMAP	0x0200	/* 8 registers */
+#define EDMA_DMAQNUM	0x0240	/* 8 registers (4 on OMAP-L1xx) */
+#define EDMA_QDMAQNUM	0x0260
+#define EDMA_QUETCMAP	0x0280
+#define EDMA_QUEPRI	0x0284
+#define EDMA_EMR	0x0300	/* 64 bits */
+#define EDMA_EMCR	0x0308	/* 64 bits */
+#define EDMA_QEMR	0x0310
+#define EDMA_QEMCR	0x0314
+#define EDMA_CCERR	0x0318
+#define EDMA_CCERRCLR	0x031c
+#define EDMA_EEVAL	0x0320
+#define EDMA_DRAE	0x0340	/* 4 x 64 bits*/
+#define EDMA_QRAE	0x0380	/* 4 registers */
+#define EDMA_QUEEVTENTRY	0x0400	/* 2 x 16 registers */
+#define EDMA_QSTAT	0x0600	/* 2 registers */
+#define EDMA_QWMTHRA	0x0620
+#define EDMA_QWMTHRB	0x0624
+#define EDMA_CCSTAT	0x0640
+
+#define EDMA_M		0x1000	/* global channel registers */
+#define EDMA_ECR	0x1008
+#define EDMA_ECRH	0x100C
+#define EDMA_SHADOW0	0x2000	/* 4 regions shadowing global channels */
+#define EDMA_PARM	0x4000	/* 128 param entries */
+
+#define DAVINCI_DMA_3PCC_BASE	0x01C00000
+
+#define PARM_OFFSET(param_no)	(EDMA_PARM + ((param_no) << 5))
+
+#define EDMA_MAX_DMACH           64
+#define EDMA_MAX_PARAMENTRY     512
+#define EDMA_MAX_EVQUE            2	/* FIXME too small */
+
+
+/*****************************************************************************/
+
+static void __iomem *edmacc_regs_base;
+
+static inline unsigned int edma_read(int offset)
+{
+	return (unsigned int)__raw_readl(edmacc_regs_base + offset);
+}
+
+static inline void edma_write(int offset, int val)
+{
+	__raw_writel(val, edmacc_regs_base + offset);
+}
+static inline void edma_modify(int offset, unsigned and, unsigned or)
+{
+	unsigned val = edma_read(offset);
+	val &= and;
+	val |= or;
+	edma_write(offset, val);
+}
+static inline void edma_and(int offset, unsigned and)
+{
+	unsigned val = edma_read(offset);
+	val &= and;
+	edma_write(offset, val);
+}
+static inline void edma_or(int offset, unsigned or)
+{
+	unsigned val = edma_read(offset);
+	val |= or;
+	edma_write(offset, val);
+}
+static inline unsigned int edma_read_array(int offset, int i)
+{
+	return edma_read(offset + (i << 2));
+}
+static inline void edma_write_array(int offset, int i, unsigned val)
+{
+	edma_write(offset + (i << 2), val);
+}
+static inline void edma_modify_array(int offset, int i,
+		unsigned and, unsigned or)
+{
+	edma_modify(offset + (i << 2), and, or);
+}
+static inline void edma_or_array(int offset, int i, unsigned or)
+{
+	edma_or(offset + (i << 2), or);
+}
+static inline void edma_or_array2(int offset, int i, int j, unsigned or)
+{
+	edma_or(offset + ((i*2 + j) << 2), or);
+}
+static inline void edma_write_array2(int offset, int i, int j, unsigned val)
+{
+	edma_write(offset + ((i*2 + j) << 2), val);
+}
+static inline unsigned int edma_shadow0_read(int offset)
+{
+	return edma_read(EDMA_SHADOW0 + offset);
+}
+static inline unsigned int edma_shadow0_read_array(int offset, int i)
+{
+	return edma_read(EDMA_SHADOW0 + offset + (i << 2));
+}
+static inline void edma_shadow0_write(int offset, unsigned val)
+{
+	edma_write(EDMA_SHADOW0 + offset, val);
+}
+static inline void edma_shadow0_write_array(int offset, int i, unsigned val)
+{
+	edma_write(EDMA_SHADOW0 + offset + (i << 2), val);
+}
+static inline unsigned int edma_parm_read(int offset, int param_no)
+{
+	return edma_read(EDMA_PARM + offset + (param_no << 5));
+}
+static inline void edma_parm_write(int offset, int param_no, unsigned val)
+{
+	edma_write(EDMA_PARM + offset + (param_no << 5), val);
+}
+static inline void edma_parm_modify(int offset, int param_no,
+		unsigned and, unsigned or)
+{
+	edma_modify(EDMA_PARM + offset + (param_no << 5), and, or);
+}
+static inline void edma_parm_and(int offset, int param_no, unsigned and)
+{
+	edma_and(EDMA_PARM + offset + (param_no << 5), and);
+}
+static inline void edma_parm_or(int offset, int param_no, unsigned or)
+{
+	edma_or(EDMA_PARM + offset + (param_no << 5), or);
+}
+
+/*****************************************************************************/
+
+/* actual number of DMA channels and slots on this silicon */
+static unsigned num_channels;
+static unsigned num_slots;
+
+static struct dma_interrupt_data {
+	void (*callback)(unsigned channel, unsigned short ch_status,
+			 void *data);
+	void *data;
+} intr_data[EDMA_MAX_DMACH];
+
+/* The edma_inuse bit for each PaRAM slot is clear unless the
+ * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+ */
+static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+
+/* The edma_noevent bit for each channel is clear unless
+ * it doesn't trigger DMA events on this platform.  It uses a
+ * bit of SOC-specific initialization code.
+ */
+static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
+
+/* dummy param set used to (re)initialize parameter RAM slots */
+static const struct edmacc_param dummy_paramset = {
+	.link_bcntrld = 0xffff,
+	.ccnt = 1,
+};
+
+static const int __initconst
+queue_tc_mapping[EDMA_MAX_EVQUE + 1][2] = {
+/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{-1, -1}
+};
+
+static const int __initconst
+queue_priority_mapping[EDMA_MAX_EVQUE + 1][2] = {
+	/* {event queue no, Priority} */
+	{0, 3},
+	{1, 7},
+	{-1, -1}
+};
+
+/*****************************************************************************/
+
+static void map_dmach_queue(unsigned ch_no, enum dma_event_q queue_no)
+{
+	int bit = (ch_no & 0x7) * 4;
+
+	/* default to low priority queue */
+	if (queue_no == EVENTQ_DEFAULT)
+		queue_no = EVENTQ_1;
+
+	queue_no &= 7;
+	edma_modify_array(EDMA_DMAQNUM, (ch_no >> 3),
+			~(0x7 << bit), queue_no << bit);
+}
+
+static void __init map_queue_tc(int queue_no, int tc_no)
+{
+	int bit = queue_no * 4;
+	edma_modify(EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
+}
+
+static void __init assign_priority_to_queue(int queue_no, int priority)
+{
+	int bit = queue_no * 4;
+	edma_modify(EDMA_QUEPRI, ~(0x7 << bit), ((priority & 0x7) << bit));
+}
+
+static inline void
+setup_dma_interrupt(unsigned lch,
+	void (*callback)(unsigned channel, u16 ch_status, void *data),
+	void *data)
+{
+	if (!callback) {
+		edma_shadow0_write_array(SH_IECR, lch >> 5,
+				(1 << (lch & 0x1f)));
+	}
+
+	intr_data[lch].callback = callback;
+	intr_data[lch].data = data;
+
+	if (callback) {
+		edma_shadow0_write_array(SH_ICR, lch >> 5,
+				(1 << (lch & 0x1f)));
+		edma_shadow0_write_array(SH_IESR, lch >> 5,
+				(1 << (lch & 0x1f)));
+	}
+}
+
+/******************************************************************************
+ *
+ * DMA interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_irq_handler(int irq, void *data)
+{
+	int i;
+	unsigned int cnt = 0;
+
+	dev_dbg(data, "dma_irq_handler\n");
+
+	if ((edma_shadow0_read_array(SH_IPR, 0) == 0)
+	    && (edma_shadow0_read_array(SH_IPR, 1) == 0))
+		return IRQ_NONE;
+
+	while (1) {
+		int j;
+		if (edma_shadow0_read_array(SH_IPR, 0))
+			j = 0;
+		else if (edma_shadow0_read_array(SH_IPR, 1))
+			j = 1;
+		else
+			break;
+		dev_dbg(data, "IPR%d %08x\n", j,
+				edma_shadow0_read_array(SH_IPR, j));
+		for (i = 0; i < 32; i++) {
+			int k = (j << 5) + i;
+			if (edma_shadow0_read_array(SH_IPR, j) & (1 << i)) {
+				/* Clear the corresponding IPR bits */
+				edma_shadow0_write_array(SH_ICR, j, (1 << i));
+				if (intr_data[k].callback) {
+					intr_data[k].callback(k, DMA_COMPLETE,
+						intr_data[k].data);
+				}
+			}
+		}
+		cnt++;
+		if (cnt > 10)
+			break;
+	}
+	edma_shadow0_write(SH_IEVAL, 1);
+	return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * DMA error interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_ccerr_handler(int irq, void *data)
+{
+	int i;
+	unsigned int cnt = 0;
+
+	dev_dbg(data, "dma_ccerr_handler\n");
+
+	if ((edma_read_array(EDMA_EMR, 0) == 0) &&
+	    (edma_read_array(EDMA_EMR, 1) == 0) &&
+	    (edma_read(EDMA_QEMR) == 0) && (edma_read(EDMA_CCERR) == 0))
+		return IRQ_NONE;
+
+	while (1) {
+		int j = -1;
+		if (edma_read_array(EDMA_EMR, 0))
+			j = 0;
+		else if (edma_read_array(EDMA_EMR, 1))
+			j = 1;
+		if (j >= 0) {
+			dev_dbg(data, "EMR%d %08x\n", j,
+					edma_read_array(EDMA_EMR, j));
+			for (i = 0; i < 32; i++) {
+				int k = (j << 5) + i;
+				if (edma_read_array(EDMA_EMR, j) & (1 << i)) {
+					/* Clear the corresponding EMR bits */
+					edma_write_array(EDMA_EMCR, j, 1 << i);
+					/* Clear any SER */
+					edma_shadow0_write_array(SH_SECR, j,
+							(1 << i));
+					if (intr_data[k].callback) {
+						intr_data[k].callback(k,
+								DMA_CC_ERROR,
+								intr_data
+								[k].data);
+					}
+				}
+			}
+		} else if (edma_read(EDMA_QEMR)) {
+			dev_dbg(data, "QEMR %02x\n",
+				edma_read(EDMA_QEMR));
+			for (i = 0; i < 8; i++) {
+				if (edma_read(EDMA_QEMR) & (1 << i)) {
+					/* Clear the corresponding IPR bits */
+					edma_write(EDMA_QEMCR, 1 << i);
+					edma_shadow0_write(SH_QSECR, (1 << i));
+
+					/* NOTE:  not reported!! */
+				}
+			}
+		} else if (edma_read(EDMA_CCERR)) {
+			dev_dbg(data, "CCERR %08x\n",
+				edma_read(EDMA_CCERR));
+			/* FIXME:  CCERR.BIT(16) ignored!  much better
+			 * to just write CCERRCLR with CCERR value...
+			 */
+			for (i = 0; i < 8; i++) {
+				if (edma_read(EDMA_CCERR) & (1 << i)) {
+					/* Clear the corresponding IPR bits */
+					edma_write(EDMA_CCERRCLR, 1 << i);
+
+					/* NOTE:  not reported!! */
+				}
+			}
+		}
+		if ((edma_read_array(EDMA_EMR, 0) == 0)
+		    && (edma_read_array(EDMA_EMR, 1) == 0)
+		    && (edma_read(EDMA_QEMR) == 0)
+		    && (edma_read(EDMA_CCERR) == 0)) {
+			break;
+		}
+		cnt++;
+		if (cnt > 10)
+			break;
+	}
+	edma_write(EDMA_EEVAL, 1);
+	return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * Transfer controller error interrupt handlers
+ *
+ *****************************************************************************/
+
+#define tc_errs_handled	false	/* disabled as long as they're NOPs */
+
+static irqreturn_t dma_tc0err_handler(int irq, void *data)
+{
+	dev_dbg(data, "dma_tc0err_handler\n");
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dma_tc1err_handler(int irq, void *data)
+{
+	dev_dbg(data, "dma_tc1err_handler\n");
+	return IRQ_HANDLED;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/* Resource alloc/free:  dma channels, parameter RAM slots */
+
+/**
+ * edma_alloc_channel - allocate DMA channel and paired parameter RAM
+ * @channel: specific channel to allocate; negative for "any unmapped channel"
+ * @callback: optional; to be issued on DMA completion or errors
+ * @data: passed to callback
+ * @eventq_no: an EVENTQ_* constant, used to choose which Transfer
+ *	Controller (TC) executes requests using this channel.  Use
+ *	EVENTQ_DEFAULT unless you really need a high priority queue.
+ *
+ * This allocates a DMA channel and its associated parameter RAM slot.
+ * The parameter RAM is initialized to hold a dummy transfer.
+ *
+ * Normal use is to pass a specific channel number as @channel, to make
+ * use of hardware events mapped to that channel.  When the channel will
+ * be used only for software triggering or event chaining, channels not
+ * mapped to hardware events (or mapped to unused events) are preferable.
+ *
+ * DMA transfers start from a channel using edma_start(), or by
+ * chaining.  When the transfer described in that channel's parameter RAM
+ * slot completes, that slot's data may be reloaded through a link.
+ *
+ * DMA errors are only reported to the @callback associated with the
+ * channel driving that transfer, but transfer completion callbacks can
+ * be sent to another channel under control of the TCC field in
+ * the option word of the transfer's parameter RAM set.  Drivers must not
+ * use DMA transfer completion callbacks for channels they did not allocate.
+ * (The same applies to TCC codes used in transfer chaining.)
+ *
+ * Returns the number of the channel, else negative errno.
+ */
+int edma_alloc_channel(int channel,
+		void (*callback)(unsigned channel, u16 ch_status, void *data),
+		void *data,
+		enum dma_event_q eventq_no)
+{
+	if (channel < 0) {
+		channel = 0;
+		for (;;) {
+			channel = find_next_bit(edma_noevent,
+					num_channels, channel);
+			if (channel == num_channels)
+				return -ENOMEM;
+			if (!test_and_set_bit(channel, edma_inuse))
+				break;
+			channel++;
+		}
+	} else if (channel >= num_channels) {
+		return -EINVAL;
+	} else if (test_and_set_bit(channel, edma_inuse)) {
+		return -EBUSY;
+	}
+
+	/* ensure access through shadow region 0 */
+	edma_or_array2(EDMA_DRAE, 0, channel >> 5, 1 << (channel & 0x1f));
+
+	/* ensure no events are pending */
+	edma_stop(channel);
+	memcpy_toio(edmacc_regs_base + PARM_OFFSET(channel),
+			&dummy_paramset, PARM_SIZE);
+
+	if (callback)
+		setup_dma_interrupt(channel, callback, data);
+
+	map_dmach_queue(channel, eventq_no);
+
+	return channel;
+}
+EXPORT_SYMBOL(edma_alloc_channel);
+
+
+/**
+ * edma_free_channel - deallocate DMA channel
+ * @channel: dma channel returned from edma_alloc_channel()
+ *
+ * This deallocates the DMA channel and associated parameter RAM slot
+ * allocated by edma_alloc_channel().
+ *
+ * Callers are responsible for ensuring the channel is inactive, and
+ * will not be reactivated by linking, chaining, or software calls to
+ * edma_start().
+ */
+void edma_free_channel(unsigned channel)
+{
+	if (channel >= num_channels)
+		return;
+
+	setup_dma_interrupt(channel, NULL, NULL);
+	/* REVISIT should probably take out of shadow region 0 */
+
+	memcpy_toio(edmacc_regs_base + PARM_OFFSET(channel),
+			&dummy_paramset, PARM_SIZE);
+	clear_bit(channel, edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_channel);
+
+/**
+ * edma_alloc_slot - allocate DMA parameter RAM
+ * @slot: specific slot to allocate; negative for "any unused slot"
+ *
+ * This allocates a parameter RAM slot, initializing it to hold a
+ * dummy transfer.  Slots allocated using this routine have not been
+ * mapped to a hardware DMA channel, and will normally be used by
+ * linking to them from a slot associated with a DMA channel.
+ *
+ * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
+ * slots may be allocated on behalf of DSP firmware.
+ *
+ * Returns the number of the slot, else negative errno.
+ */
+int edma_alloc_slot(int slot)
+{
+	if (slot < 0) {
+		slot = num_channels;
+		for (;;) {
+			slot = find_next_zero_bit(edma_inuse,
+					num_slots, slot);
+			if (slot == num_slots)
+				return -ENOMEM;
+			if (!test_and_set_bit(slot, edma_inuse))
+				break;
+		}
+	} else if (slot < num_channels || slot >= num_slots) {
+		return -EINVAL;
+	} else if (test_and_set_bit(slot, edma_inuse)) {
+		return -EBUSY;
+	}
+
+	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot),
+			&dummy_paramset, PARM_SIZE);
+
+	return slot;
+}
+EXPORT_SYMBOL(edma_alloc_slot);
+
+/**
+ * edma_free_slot - deallocate DMA parameter RAM
+ * @slot: parameter RAM slot returned from edma_alloc_slot()
+ *
+ * This deallocates the parameter RAM slot allocated by edma_alloc_slot().
+ * Callers are responsible for ensuring the slot is inactive, and will
+ * not be activated.
+ */
+void edma_free_slot(unsigned slot)
+{
+	if (slot < num_channels || slot >= num_slots)
+		return;
+
+	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot),
+			&dummy_paramset, PARM_SIZE);
+	clear_bit(slot, edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_slot);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (i) -- read/write partial slots */
+
+/**
+ * edma_set_src - set initial DMA source address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @src_port: physical address of source (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the source address is modified during the DMA transfer
+ * according to edma_set_src_index().
+ */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+				enum address_mode mode, enum fifo_width width)
+{
+	if (slot < num_slots) {
+		unsigned int i = edma_parm_read(PARM_OPT, slot);
+
+		if (mode) {
+			/* set SAM and program FWID */
+			i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8));
+		} else {
+			/* clear SAM */
+			i &= ~SAM;
+		}
+		edma_parm_write(PARM_OPT, slot, i);
+
+		/* set the source port address
+		   in source register of param structure */
+		edma_parm_write(PARM_SRC, slot, src_port);
+	}
+}
+EXPORT_SYMBOL(edma_set_src);
+
+/**
+ * edma_set_dest - set initial DMA destination address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @dest_port: physical address of destination (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the destination address is modified during the DMA transfer
+ * according to edma_set_dest_index().
+ */
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+				 enum address_mode mode, enum fifo_width width)
+{
+	if (slot < num_slots) {
+		unsigned int i = edma_parm_read(PARM_OPT, slot);
+
+		if (mode) {
+			/* set DAM and program FWID */
+			i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8));
+		} else {
+			/* clear DAM */
+			i &= ~DAM;
+		}
+		edma_parm_write(PARM_OPT, slot, i);
+		/* set the destination port address
+		   in dest register of param structure */
+		edma_parm_write(PARM_DST, slot, dest_port);
+	}
+}
+EXPORT_SYMBOL(edma_set_dest);
+
+/**
+ * edma_get_position - returns the current transfer points
+ * @slot: parameter RAM slot being examined
+ * @src: pointer to source port position
+ * @dst: pointer to destination port position
+ *
+ * Returns current source and destination addresses for a particular
+ * parameter RAM slot.  Its channel should not be active when this is called.
+ */
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
+{
+	struct edmacc_param temp;
+
+	edma_read_slot(slot, &temp);
+	if (src != NULL)
+		*src = temp.src;
+	if (dst != NULL)
+		*dst = temp.dst;
+}
+EXPORT_SYMBOL(edma_get_position);
+
+/**
+ * edma_set_src_index - configure DMA source address indexing
+ * @slot: parameter RAM slot being configured
+ * @src_bidx: byte offset between source arrays in a frame
+ * @src_cidx: byte offset between source frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
+{
+	if (slot < num_slots) {
+		edma_parm_modify(PARM_SRC_DST_BIDX, slot,
+				0xffff0000, src_bidx);
+		edma_parm_modify(PARM_SRC_DST_CIDX, slot,
+				0xffff0000, src_cidx);
+	}
+}
+EXPORT_SYMBOL(edma_set_src_index);
+
+/**
+ * edma_set_dest_index - configure DMA destination address indexing
+ * @slot: parameter RAM slot being configured
+ * @dest_bidx: byte offset between destination arrays in a frame
+ * @dest_cidx: byte offset between destination frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
+{
+	if (slot < num_slots) {
+		edma_parm_modify(PARM_SRC_DST_BIDX, slot,
+				0x0000ffff, dest_bidx << 16);
+		edma_parm_modify(PARM_SRC_DST_CIDX, slot,
+				0x0000ffff, dest_cidx << 16);
+	}
+}
+EXPORT_SYMBOL(edma_set_dest_index);
+
+/**
+ * edma_set_transfer_params - configure DMA transfer parameters
+ * @slot: parameter RAM slot being configured
+ * @acnt: how many bytes per array (at least one)
+ * @bcnt: how many arrays per frame (at least one)
+ * @ccnt: how many frames per block (at least one)
+ * @bcnt_rld: used only for A-Synchronized transfers; this specifies
+ *	the value to reload into bcnt when it decrements to zero
+ * @sync_mode: ASYNC or ABSYNC
+ *
+ * See the EDMA3 documentation to understand how to configure and link
+ * transfers using the fields in PaRAM slots.  If you are not doing it
+ * all at once with edma_write_slot(), you will use this routine
+ * plus two calls each for source and destination, setting the initial
+ * address and saying how to index that address.
+ *
+ * An example of an A-Synchronized transfer is a serial link using a
+ * single word shift register.  In that case, @acnt would be equal to
+ * that word size; the serial controller issues a DMA synchronization
+ * event to transfer each word, and memory access by the DMA transfer
+ * controller will be word-at-a-time.
+ *
+ * An example of an AB-Synchronized transfer is a device using a FIFO.
+ * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
+ * The controller with the FIFO issues DMA synchronization events when
+ * the FIFO threshold is reached, and the DMA transfer controller will
+ * transfer one frame to (or from) the FIFO.  It will probably use
+ * efficient burst modes to access memory.
+ */
+void edma_set_transfer_params(unsigned slot,
+		u16 acnt, u16 bcnt, u16 ccnt,
+		u16 bcnt_rld, enum sync_dimension sync_mode)
+{
+	if (slot < num_slots) {
+		edma_parm_modify(PARM_LINK_BCNTRLD, slot,
+				0x0000ffff, bcnt_rld << 16);
+		if (sync_mode == ASYNC)
+			edma_parm_and(PARM_OPT, slot, ~SYNCDIM);
+		else
+			edma_parm_or(PARM_OPT, slot, SYNCDIM);
+		/* Set the acount, bcount, ccount registers */
+		edma_parm_write(PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
+		edma_parm_write(PARM_CCNT, slot, ccnt);
+	}
+}
+EXPORT_SYMBOL(edma_set_transfer_params);
+
+/**
+ * edma_link - link one parameter RAM slot to another
+ * @from: parameter RAM slot originating the link
+ * @to: parameter RAM slot which is the link target
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ */
+void edma_link(unsigned from, unsigned to)
+{
+	if (from >= num_slots)
+		return;
+	if (to >= num_slots)
+		return;
+	edma_parm_modify(PARM_LINK_BCNTRLD, from, 0xffff0000, PARM_OFFSET(to));
+}
+EXPORT_SYMBOL(edma_link);
+
+/**
+ * edma_unlink - cut link from one parameter RAM slot
+ * @from: parameter RAM slot originating the link
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ * Its link is set to 0xffff.
+ */
+void edma_unlink(unsigned from)
+{
+	if (from >= num_slots)
+		return;
+	edma_parm_or(PARM_LINK_BCNTRLD, from, 0xffff);
+}
+EXPORT_SYMBOL(edma_unlink);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (ii) -- read/write whole parameter sets */
+
+/**
+ * edma_write_slot - write parameter RAM data for slot
+ * @slot: number of parameter RAM slot being modified
+ * @param: data to be written into parameter RAM slot
+ *
+ * Use this to assign all parameters of a transfer at once.  This
+ * allows more efficient setup of transfers than issuing multiple
+ * calls to set up those parameters in small pieces, and provides
+ * complete control over all transfer options.
+ */
+void edma_write_slot(unsigned slot, const struct edmacc_param *param)
+{
+	if (slot >= num_slots)
+		return;
+	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot), param, PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_write_slot);
+
+/**
+ * edma_read_slot - read parameter RAM data from slot
+ * @slot: number of parameter RAM slot being copied
+ * @param: where to store copy of parameter RAM data
+ *
+ * Use this to read data from a parameter RAM slot, perhaps to
+ * save them as a template for later reuse.
+ */
+void edma_read_slot(unsigned slot, struct edmacc_param *param)
+{
+	if (slot >= num_slots)
+		return;
+	memcpy_fromio(param, edmacc_regs_base + PARM_OFFSET(slot), PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_read_slot);
+
+/*-----------------------------------------------------------------------*/
+
+/* Various EDMA channel control operations */
+
+/**
+ * edma_pause - pause dma on a channel
+ * @channel: on which edma_start() has been called
+ *
+ * This temporarily disables EDMA hardware events on the specified channel,
+ * preventing them from triggering new transfers on its behalf
+ */
+void edma_pause(unsigned channel)
+{
+	if (channel < num_channels) {
+		unsigned int mask = (1 << (channel & 0x1f));
+
+		edma_shadow0_write_array(SH_EECR, channel >> 5, mask);
+	}
+}
+EXPORT_SYMBOL(edma_pause);
+
+/**
+ * edma_resume - resumes dma on a paused channel
+ * @channel: on which edma_pause() has been called
+ *
+ * This re-enables EDMA hardware events on the specified channel.
+ */
+void edma_resume(unsigned channel)
+{
+	if (channel < num_channels) {
+		unsigned int mask = (1 << (channel & 0x1f));
+
+		edma_shadow0_write_array(SH_EESR, channel >> 5, mask);
+	}
+}
+EXPORT_SYMBOL(edma_resume);
+
+/**
+ * edma_start - start dma on a channel
+ * @channel: channel being activated
+ *
+ * Channels with event associations will be triggered by their hardware
+ * events, and channels without such associations will be triggered by
+ * software.  (At this writing there is no interface for using software
+ * triggers except with channels that don't support hardware triggers.)
+ *
+ * Returns zero on success, else negative errno.
+ */
+int edma_start(unsigned channel)
+{
+	if (channel < num_channels) {
+		int j = channel >> 5;
+		unsigned int mask = (1 << (channel & 0x1f));
+
+		/* EDMA channels without event association */
+		if (test_bit(channel, edma_noevent)) {
+			pr_debug("EDMA: ESR%d %08x\n", j,
+				edma_shadow0_read_array(SH_ESR, j));
+			edma_shadow0_write_array(SH_ESR, j, mask);
+			return 0;
+		}
+
+		/* EDMA channel with event association */
+		pr_debug("EDMA: ER%d %08x\n", j,
+			edma_shadow0_read_array(SH_ER, j));
+		/* Clear any pending error */
+		edma_write_array(EDMA_EMCR, j, mask);
+		/* Clear any SER */
+		edma_shadow0_write_array(SH_SECR, j, mask);
+		edma_shadow0_write_array(SH_EESR, j, mask);
+		pr_debug("EDMA: EER%d %08x\n", j,
+			edma_shadow0_read_array(SH_EER, j));
+		return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(edma_start);
+
+/**
+ * edma_stop - stops dma on the channel passed
+ * @channel: channel being deactivated
+ *
+ * When @lch is a channel, any active transfer is paused and
+ * all pending hardware events are cleared.  The current transfer
+ * may not be resumed, and the channel's Parameter RAM should be
+ * reinitialized before being reused.
+ */
+void edma_stop(unsigned channel)
+{
+	if (channel < num_channels) {
+		int j = channel >> 5;
+		unsigned int mask = (1 << (channel & 0x1f));
+
+		edma_shadow0_write_array(SH_EECR, j, mask);
+		edma_shadow0_write_array(SH_ECR, j, mask);
+		edma_shadow0_write_array(SH_SECR, j, mask);
+		edma_write_array(EDMA_EMCR, j, mask);
+
+		pr_debug("EDMA: EER%d %08x\n", j,
+				edma_shadow0_read_array(SH_EER, j));
+
+		/* REVISIT:  consider guarding against inappropriate event
+		 * chaining by overwriting with dummy_paramset.
+		 */
+	}
+}
+EXPORT_SYMBOL(edma_stop);
+
+/******************************************************************************
+ *
+ * It cleans ParamEntry qand bring back EDMA to initial state if media has
+ * been removed before EDMA has finished.It is usedful for removable media.
+ * Arguments:
+ *      ch_no     - channel no
+ *
+ * Return: zero on success, or corresponding error no on failure
+ *
+ * FIXME this should not be needed ... edma_stop() should suffice.
+ *
+ *****************************************************************************/
+
+void edma_clean_channel(unsigned channel)
+{
+	if (channel < num_channels) {
+		int j = (channel >> 5);
+		unsigned int mask = 1 << (channel & 0x1f);
+
+		pr_debug("EDMA: EMR%d %08x\n", j,
+				edma_read_array(EDMA_EMR, j));
+		edma_shadow0_write_array(SH_ECR, j, mask);
+		/* Clear the corresponding EMR bits */
+		edma_write_array(EDMA_EMCR, j, mask);
+		/* Clear any SER */
+		edma_shadow0_write_array(SH_SECR, j, mask);
+		edma_write(EDMA_CCERRCLR, (1 << 16) | 0x3);
+	}
+}
+EXPORT_SYMBOL(edma_clean_channel);
+
+/*
+ * edma_clear_event - clear an outstanding event on the DMA channel
+ * Arguments:
+ *	channel - channel number
+ */
+void edma_clear_event(unsigned channel)
+{
+	if (channel >= num_channels)
+		return;
+	if (channel < 32)
+		edma_write(EDMA_ECR, 1 << channel);
+	else
+		edma_write(EDMA_ECRH, 1 << (channel - 32));
+}
+EXPORT_SYMBOL(edma_clear_event);
+
+/*-----------------------------------------------------------------------*/
+
+static int __init edma_probe(struct platform_device *pdev)
+{
+	struct edma_soc_info	*info = pdev->dev.platform_data;
+	int			i;
+	int			status;
+	const s8		*noevent;
+	int			irq = 0, err_irq = 0;
+	struct resource		*r;
+	resource_size_t		len;
+
+	if (!info)
+		return -ENODEV;
+
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edma_cc");
+	if (!r)
+		return -ENODEV;
+
+	len = r->end - r->start + 1;
+
+	r = request_mem_region(r->start, len, r->name);
+	if (!r)
+		return -EBUSY;
+
+	edmacc_regs_base = ioremap(r->start, len);
+	if (!edmacc_regs_base) {
+		status = -EBUSY;
+		goto fail1;
+	}
+
+	num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH);
+	num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY);
+
+	dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base);
+
+	for (i = 0; i < num_slots; i++)
+		memcpy_toio(edmacc_regs_base + PARM_OFFSET(i),
+				&dummy_paramset, PARM_SIZE);
+
+	noevent = info->noevent;
+	if (noevent) {
+		while (*noevent != -1)
+			set_bit(*noevent++, edma_noevent);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev);
+	if (status < 0) {
+		dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+			irq, status);
+		goto fail;
+	}
+
+	err_irq = platform_get_irq(pdev, 1);
+	status = request_irq(err_irq, dma_ccerr_handler, 0,
+				"edma_error", &pdev->dev);
+	if (status < 0) {
+		dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+			err_irq, status);
+		goto fail;
+	}
+
+	if (tc_errs_handled) {
+		status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
+					"edma_tc0", &pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+				IRQ_TCERRINT0, status);
+			return status;
+		}
+		status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
+					"edma_tc1", &pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
+				IRQ_TCERRINT, status);
+			return status;
+		}
+	}
+
+	/* Everything lives on transfer controller 1 until otherwise specified.
+	 * This way, long transfers on the low priority queue
+	 * started by the codec engine will not cause audio defects.
+	 */
+	for (i = 0; i < num_channels; i++)
+		map_dmach_queue(i, EVENTQ_1);
+
+	/* Event queue to TC mapping */
+	for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+		map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
+
+	/* Event queue priority mapping */
+	for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+		assign_priority_to_queue(queue_priority_mapping[i][0],
+					 queue_priority_mapping[i][1]);
+
+	for (i = 0; i < info->n_region; i++) {
+		edma_write_array2(EDMA_DRAE, i, 0, 0x0);
+		edma_write_array2(EDMA_DRAE, i, 1, 0x0);
+		edma_write_array(EDMA_QRAE, i, 0x0);
+	}
+
+	return 0;
+
+fail:
+	if (err_irq)
+		free_irq(err_irq, NULL);
+	if (irq)
+		free_irq(irq, NULL);
+	iounmap(edmacc_regs_base);
+fail1:
+	release_mem_region(r->start, len);
+	return status;
+}
+
+
+static struct platform_driver edma_driver = {
+	.driver.name	= "edma",
+};
+
+static int __init edma_init(void)
+{
+	return platform_driver_probe(&edma_driver, edma_probe);
+}
+arch_initcall(edma_init);
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/gpio.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/bitops.h>
 
+#include <mach/cputype.h>
 #include <mach/irqs.h>
 #include <mach/hardware.h>
 #include <mach/gpio.h>
@@ -36,9 +37,10 @@ struct davinci_gpio {
 
 static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
 
+static unsigned __initdata ngpio;
 
 /* create a non-inlined version */
-static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
+static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
 {
 	return __gpio_to_controller(gpio);
 }
@@ -114,9 +116,30 @@ static int __init davinci_gpio_setup(voi
 {
 	int i, base;
 
-	for (i = 0, base = 0;
-			i < ARRAY_SIZE(chips);
-			i++, base += 32) {
+	/* The gpio banks conceptually expose a segmented bitmap,
+	 * and "ngpio" is one more than the largest zero-based
+	 * bit index that's valid.
+	 */
+	if (cpu_is_davinci_dm355()) {		/* or dm335() */
+		ngpio = 104;
+	} else if (cpu_is_davinci_dm644x()) {	/* or dm337() */
+		ngpio = 71;
+	} else if (cpu_is_davinci_dm646x()) {
+		/* NOTE:  each bank has several "reserved" bits,
+		 * unusable as GPIOs.  Only 33 of the GPIO numbers
+		 * are usable, and we're not rejecting the others.
+		 */
+		ngpio = 43;
+	} else {
+		/* if cpu_is_davinci_dm643x() ngpio = 111 */
+		pr_err("GPIO setup:  how many GPIOs?\n");
+		return -EINVAL;
+	}
+
+	if (WARN_ON(DAVINCI_N_GPIO < ngpio))
+		ngpio = DAVINCI_N_GPIO;
+
+	for (i = 0, base = 0; base < ngpio; i++, base += 32) {
 		chips[i].chip.label = "DaVinci";
 
 		chips[i].chip.direction_input = davinci_direction_in;
@@ -125,7 +148,7 @@ static int __init davinci_gpio_setup(voi
 		chips[i].chip.set = davinci_gpio_set;
 
 		chips[i].chip.base = base;
-		chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
+		chips[i].chip.ngpio = ngpio - base;
 		if (chips[i].chip.ngpio > 32)
 			chips[i].chip.ngpio = 32;
 
@@ -143,11 +166,11 @@ pure_initcall(davinci_gpio_setup);
  * We expect irqs will normally be set up as input pins, but they can also be
  * used as output pins ... which is convenient for testing.
  *
- * NOTE:  GPIO0..GPIO7 also have direct INTC hookups, which work in addition
- * to their GPIOBNK0 irq (but with a bit less overhead).  But we don't have
- * a good way to hook those up ...
+ * NOTE:  The first few GPIOs also have direct INTC hookups in addition
+ * to their GPIOBNK0 irq, with a bit less overhead but less flexibility
+ * on triggering (e.g. no edge options).  We don't try to use those.
  *
- * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
+ * All those INTC hookups (direct, plus several IRQ banks) can also
  * serve as EDMA event triggers.
  */
 
@@ -235,29 +258,42 @@ gpio_irq_handler(unsigned irq, struct ir
 }
 
 /*
- * NOTE:  for suspend/resume, probably best to make a sysdev (and class)
- * with its suspend/resume calls hooking into the results of the set_wake()
+ * NOTE:  for suspend/resume, probably best to make a platform_device with
+ * suspend_late/resume_resume calls hooking into results of the set_wake()
  * calls ... so if no gpios are wakeup events the clock can be disabled,
  * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
- * can be set appropriately for GPIOV33 pins.
+ * (dm6446) can be set appropriately for GPIOV33 pins.
  */
 
 static int __init davinci_gpio_irq_setup(void)
 {
 	unsigned	gpio, irq, bank;
+	unsigned	bank_irq;
 	struct clk	*clk;
+	u32		binten = 0;
+
+	if (cpu_is_davinci_dm355()) {		/* or dm335() */
+		bank_irq = IRQ_DM355_GPIOBNK0;
+	} else if (cpu_is_davinci_dm644x()) {
+		bank_irq = IRQ_GPIOBNK0;
+	} else if (cpu_is_davinci_dm646x()) {
+		bank_irq = IRQ_DM646X_GPIOBNK0;
+	} else {
+		printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
+		return -EINVAL;
+	}
 
 	clk = clk_get(NULL, "gpio");
 	if (IS_ERR(clk)) {
 		printk(KERN_ERR "Error %ld getting gpio clock?\n",
 		       PTR_ERR(clk));
-		return 0;
+		return PTR_ERR(clk);
 	}
-
 	clk_enable(clk);
 
-	for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
-	     gpio < DAVINCI_N_GPIO; bank++) {
+	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
+			gpio < ngpio;
+			bank++, bank_irq++) {
 		struct gpio_controller	*__iomem g = gpio2controller(gpio);
 		unsigned		i;
 
@@ -265,28 +301,28 @@ static int __init davinci_gpio_irq_setup
 		__raw_writel(~0, &g->clr_rising);
 
 		/* set up all irqs in this bank */
-		set_irq_chained_handler(bank, gpio_irq_handler);
-		set_irq_chip_data(bank, g);
-		set_irq_data(bank, (void *)irq);
+		set_irq_chained_handler(bank_irq, gpio_irq_handler);
+		set_irq_chip_data(bank_irq, g);
+		set_irq_data(bank_irq, (void *)irq);
 
-		for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
-		     i++, irq++, gpio++) {
+		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
 			set_irq_chip(irq, &gpio_irqchip);
 			set_irq_chip_data(irq, g);
 			set_irq_handler(irq, handle_simple_irq);
 			set_irq_flags(irq, IRQF_VALID);
 		}
+
+		binten |= BIT(bank);
 	}
 
 	/* BINTEN -- per-bank interrupt enable. genirq would also let these
 	 * bits be set/cleared dynamically.
 	 */
-	__raw_writel(0x1f, (void *__iomem)
+	__raw_writel(binten, (void *__iomem)
 		     IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
 
 	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
 
 	return 0;
 }
-
 arch_initcall(davinci_gpio_irq_setup);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/id.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/id.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/id.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/id.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,9 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
-#define JTAG_ID_BASE		0x01c40028
+#define JTAG_ID_BASE		IO_ADDRESS(0x01c40028)
+
+static unsigned int davinci_revision;
 
 struct davinci_id {
 	u8	variant;	/* JTAG ID bits 31:28 */
@@ -33,6 +35,20 @@ static struct davinci_id davinci_ids[] _
 		.manufacturer = 0x017,
 		.type	      = 0x64460000,
 	},
+	{
+		/* DM646X */
+		.part_no      = 0xb770,
+		.variant      = 0x0,
+		.manufacturer = 0x017,
+		.type         = 0x64670000,
+	},
+	{
+		/* DM355 */
+		.part_no	= 0xb73b,
+		.variant	= 0x0,
+		.manufacturer	= 0x00f,
+		.type		= 0x03550000,
+	},
 };
 
 /*
@@ -42,7 +58,7 @@ static u16 __init davinci_get_part_no(vo
 {
 	u32 dev_id, part_no;
 
-	dev_id = davinci_readl(JTAG_ID_BASE);
+	dev_id = __raw_readl(JTAG_ID_BASE);
 
 	part_no = ((dev_id >> 12) & 0xffff);
 
@@ -56,13 +72,19 @@ static u8 __init davinci_get_variant(voi
 {
 	u32 variant;
 
-	variant = davinci_readl(JTAG_ID_BASE);
+	variant = __raw_readl(JTAG_ID_BASE);
 
 	variant = (variant >> 28) & 0xf;
 
 	return variant;
 }
 
+unsigned int davinci_rev(void)
+{
+	return davinci_revision >> 16;
+}
+EXPORT_SYMBOL(davinci_rev);
+
 void __init davinci_check_revision(void)
 {
 	int i;
@@ -75,7 +97,7 @@ void __init davinci_check_revision(void)
 	/* First check only the major version in a safe way */
 	for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
 		if (part_no == (davinci_ids[i].part_no)) {
-			system_rev = davinci_ids[i].type;
+			davinci_revision = davinci_ids[i].type;
 			break;
 		}
 	}
@@ -84,10 +106,11 @@ void __init davinci_check_revision(void)
 	for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
 		if (part_no == davinci_ids[i].part_no &&
 		    variant == davinci_ids[i].variant) {
-			system_rev = davinci_ids[i].type;
+			davinci_revision = davinci_ids[i].type;
 			break;
 		}
 	}
 
-	printk("DaVinci DM%04x variant 0x%x\n", system_rev >> 16, variant);
+	printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
+	       davinci_rev(), variant);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/asp.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/asp.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/asp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/asp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * <mach/asp.h> - DaVinci Audio Serial Port support
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_H
+
+#include <mach/irqs.h>
+
+/* Bases of register banks */
+#define DAVINCI_ASP0_BASE	0x01E02000
+#define DAVINCI_ASP1_BASE	0x01E04000
+
+/* EDMA channels */
+#define DAVINCI_DMA_ASP0_TX	2
+#define DAVINCI_DMA_ASP0_RX	3
+#define DAVINCI_DMA_ASP1_TX	8
+#define DAVINCI_DMA_ASP1_RX	9
+
+/* Interrupts */
+#define DAVINCI_ASP0_RX_INT	IRQ_MBRINT
+#define DAVINCI_ASP0_TX_INT	IRQ_MBXINT
+#define DAVINCI_ASP1_RX_INT	IRQ_MBRINT
+#define DAVINCI_ASP1_TX_INT	IRQ_MBXINT
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/board-dm6446evm.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/board-dm6446evm.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/board-dm6446evm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/board-dm6446evm.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * DaVinci DM6446 EVM board specific headers
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. 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 ifndef.
+ */
+
+#ifndef _MACH_DAVINCI_DM6446EVM_H
+#define _MACH_DAVINCI_DM6446EVM_H
+
+#include <linux/types.h>
+
+int dm6446evm_eeprom_read(char *buf, off_t off, size_t count);
+int dm6446evm_eeprom_write(char *buf, off_t off, size_t count);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/clkdev.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/clkdev.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/clkdev.h	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/arch/arm/mach-davinci/include/mach/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,5 @@ struct clk;
 
 extern int clk_register(struct clk *clk);
 extern void clk_unregister(struct clk *clk);
-extern int davinci_clk_init(void);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/common.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,12 @@ struct sys_timer;
 
 extern struct sys_timer davinci_timer;
 
+extern void davinci_irq_init(void);
+extern void davinci_map_common_io(void);
+
+/* 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);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/cputype.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/cputype.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/cputype.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/cputype.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ * DaVinci CPU type detection
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Defines the cpu_is_*() macros for runtime detection of DaVinci
+ * device type.  In addtion, if support for a given device is not
+ * compiled in to the kernel, the macros return 0 so that
+ * resulting code can be optimized out.
+ *
+ * 2009 (c) Deep Root Systems, LLC. 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_CPU_H
+#define _ASM_ARCH_CPU_H
+
+extern unsigned int davinci_rev(void);
+
+#define IS_DAVINCI_CPU(type, id)			\
+static inline int is_davinci_dm ##type(void)	        \
+{							\
+	return (davinci_rev() == (id)) ? 1 : 0;	        \
+}
+
+IS_DAVINCI_CPU(644x, 0x6446)
+IS_DAVINCI_CPU(646x, 0x6467)
+IS_DAVINCI_CPU(355, 0x355)
+
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
+#define cpu_is_davinci_dm644x() is_davinci_dm644x()
+#else
+#define cpu_is_davinci_dm644x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
+#define cpu_is_davinci_dm646x() is_davinci_dm646x()
+#else
+#define cpu_is_davinci_dm646x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM355
+#define cpu_is_davinci_dm355() is_davinci_dm355()
+#else
+#define cpu_is_davinci_dm355() 0
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/dm644x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * This file contains the processor specific definitions
+ * of the TI DM644x.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#ifndef __ASM_ARCH_DM644X_H
+#define __ASM_ARCH_DM644X_H
+
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+
+#define DM644X_EMAC_BASE		(0x01C80000)
+#define DM644X_EMAC_CNTRL_OFFSET	(0x0000)
+#define DM644X_EMAC_CNTRL_MOD_OFFSET	(0x1000)
+#define DM644X_EMAC_CNTRL_RAM_OFFSET	(0x2000)
+#define DM644X_EMAC_MDIO_OFFSET		(0x4000)
+#define DM644X_EMAC_CNTRL_RAM_SIZE	(0x2000)
+
+void __init dm644x_init(void);
+
+#endif /* __ASM_ARCH_DM644X_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/edma.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/edma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/edma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/edma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,228 @@
+/*
+ *  TI DAVINCI dma definitions
+ *
+ *  Copyright (C) 2006-2009 Texas Instruments.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This EDMA3 programming framework exposes two basic kinds of resource:
+ *
+ *  Channel	Triggers transfers, usually from a hardware event but
+ *		also manually or by "chaining" from DMA completions.
+ *		Each channel is coupled to a Parameter RAM (PaRAM) slot.
+ *
+ *  Slot	Each PaRAM slot holds a DMA transfer descriptor (PaRAM
+ *		"set"), source and destination addresses, a link to a
+ *		next PaRAM slot (if any), options for the transfer, and
+ *		instructions for updating those addresses.  There are
+ *		more than twice as many slots as event channels.
+ *
+ * Each PaRAM set describes a sequence of transfers, either for one large
+ * buffer or for several discontiguous smaller buffers.  An EDMA transfer
+ * is driven only from a channel, which performs the transfers specified
+ * in its PaRAM slot until there are no more transfers.  When that last
+ * transfer completes, the "link" field may be used to reload the channel's
+ * PaRAM slot with a new transfer descriptor.
+ *
+ * The EDMA Channel Controller (CC) maps requests from channels into physical
+ * Transfer Controller (TC) requests when the channel triggers (by hardware
+ * or software events, or by chaining).  The two physical DMA channels provided
+ * by the TCs are thus shared by many logical channels.
+ *
+ * DaVinci hardware also has a "QDMA" mechanism which is not currently
+ * supported through this interface.  (DSP firmware uses it though.)
+ */
+
+#ifndef EDMA_H_
+#define EDMA_H_
+
+/* PaRAM slots are laid out like this */
+struct edmacc_param {
+	unsigned int opt;
+	unsigned int src;
+	unsigned int a_b_cnt;
+	unsigned int dst;
+	unsigned int src_dst_bidx;
+	unsigned int link_bcntrld;
+	unsigned int src_dst_cidx;
+	unsigned int ccnt;
+};
+
+#define CCINT0_INTERRUPT     16
+#define CCERRINT_INTERRUPT   17
+#define TCERRINT0_INTERRUPT   18
+#define TCERRINT1_INTERRUPT   19
+
+/* fields in edmacc_param.opt */
+#define SAM		BIT(0)
+#define DAM		BIT(1)
+#define SYNCDIM		BIT(2)
+#define STATIC		BIT(3)
+#define EDMA_FWID	(0x07 << 8)
+#define TCCMODE		BIT(11)
+#define EDMA_TCC(t)	((t) << 12)
+#define TCINTEN		BIT(20)
+#define ITCINTEN	BIT(21)
+#define TCCHEN		BIT(22)
+#define ITCCHEN		BIT(23)
+
+#define TRWORD (0x7<<2)
+#define PAENTRY (0x1ff<<5)
+
+/* Drivers should avoid using these symbolic names for dm644x
+ * channels, and use platform_device IORESOURCE_DMA resources
+ * instead.  (Other DaVinci chips have different peripherals
+ * and thus have different DMA channel mappings.)
+ */
+#define DAVINCI_DMA_MCBSP_TX              2
+#define DAVINCI_DMA_MCBSP_RX              3
+#define DAVINCI_DMA_VPSS_HIST             4
+#define DAVINCI_DMA_VPSS_H3A              5
+#define DAVINCI_DMA_VPSS_PRVU             6
+#define DAVINCI_DMA_VPSS_RSZ              7
+#define DAVINCI_DMA_IMCOP_IMXINT          8
+#define DAVINCI_DMA_IMCOP_VLCDINT         9
+#define DAVINCI_DMA_IMCO_PASQINT         10
+#define DAVINCI_DMA_IMCOP_DSQINT         11
+#define DAVINCI_DMA_SPI_SPIX             16
+#define DAVINCI_DMA_SPI_SPIR             17
+#define DAVINCI_DMA_UART0_URXEVT0        18
+#define DAVINCI_DMA_UART0_UTXEVT0        19
+#define DAVINCI_DMA_UART1_URXEVT1        20
+#define DAVINCI_DMA_UART1_UTXEVT1        21
+#define DAVINCI_DMA_UART2_URXEVT2        22
+#define DAVINCI_DMA_UART2_UTXEVT2        23
+#define DAVINCI_DMA_MEMSTK_MSEVT         24
+#define DAVINCI_DMA_MMCRXEVT             26
+#define DAVINCI_DMA_MMCTXEVT             27
+#define DAVINCI_DMA_I2C_ICREVT           28
+#define DAVINCI_DMA_I2C_ICXEVT           29
+#define DAVINCI_DMA_GPIO_GPINT0          32
+#define DAVINCI_DMA_GPIO_GPINT1          33
+#define DAVINCI_DMA_GPIO_GPINT2          34
+#define DAVINCI_DMA_GPIO_GPINT3          35
+#define DAVINCI_DMA_GPIO_GPINT4          36
+#define DAVINCI_DMA_GPIO_GPINT5          37
+#define DAVINCI_DMA_GPIO_GPINT6          38
+#define DAVINCI_DMA_GPIO_GPINT7          39
+#define DAVINCI_DMA_GPIO_GPBNKINT0       40
+#define DAVINCI_DMA_GPIO_GPBNKINT1       41
+#define DAVINCI_DMA_GPIO_GPBNKINT2       42
+#define DAVINCI_DMA_GPIO_GPBNKINT3       43
+#define DAVINCI_DMA_GPIO_GPBNKINT4       44
+#define DAVINCI_DMA_TIMER0_TINT0         48
+#define DAVINCI_DMA_TIMER1_TINT1         49
+#define DAVINCI_DMA_TIMER2_TINT2         50
+#define DAVINCI_DMA_TIMER3_TINT3         51
+#define DAVINCI_DMA_PWM0                 52
+#define DAVINCI_DMA_PWM1                 53
+#define DAVINCI_DMA_PWM2                 54
+
+/*ch_status paramater of callback function possible values*/
+#define DMA_COMPLETE 1
+#define DMA_CC_ERROR 2
+#define DMA_TC1_ERROR 3
+#define DMA_TC2_ERROR 4
+
+enum address_mode {
+	INCR = 0,
+	FIFO = 1
+};
+
+enum fifo_width {
+	W8BIT = 0,
+	W16BIT = 1,
+	W32BIT = 2,
+	W64BIT = 3,
+	W128BIT = 4,
+	W256BIT = 5
+};
+
+enum dma_event_q {
+	EVENTQ_0 = 0,
+	EVENTQ_1 = 1,
+	EVENTQ_DEFAULT = -1
+};
+
+enum sync_dimension {
+	ASYNC = 0,
+	ABSYNC = 1
+};
+
+#define EDMA_CHANNEL_ANY		-1	/* for edma_alloc_channel() */
+#define EDMA_SLOT_ANY			-1	/* for edma_alloc_slot() */
+
+/* alloc/free DMA channels and their dedicated parameter RAM slots */
+int edma_alloc_channel(int channel,
+	void (*callback)(unsigned channel, u16 ch_status, void *data),
+	void *data, enum dma_event_q);
+void edma_free_channel(unsigned channel);
+
+/* alloc/free parameter RAM slots */
+int edma_alloc_slot(int slot);
+void edma_free_slot(unsigned slot);
+
+/* calls that operate on part of a parameter RAM slot */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+				enum address_mode mode, enum fifo_width);
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+				 enum address_mode mode, enum fifo_width);
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst);
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
+void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
+		u16 bcnt_rld, enum sync_dimension sync_mode);
+void edma_link(unsigned from, unsigned to);
+void edma_unlink(unsigned from);
+
+/* calls that operate on an entire parameter RAM slot */
+void edma_write_slot(unsigned slot, const struct edmacc_param *params);
+void edma_read_slot(unsigned slot, struct edmacc_param *params);
+
+/* channel control operations */
+int edma_start(unsigned channel);
+void edma_stop(unsigned channel);
+void edma_clean_channel(unsigned channel);
+void edma_clear_event(unsigned channel);
+void edma_pause(unsigned channel);
+void edma_resume(unsigned channel);
+
+/* UNRELATED TO DMA */
+int davinci_alloc_iram(unsigned size);
+void davinci_free_iram(unsigned addr, unsigned size);
+
+/* platform_data for EDMA driver */
+struct edma_soc_info {
+
+	/* how many dma resources of each type */
+	unsigned	n_channel;
+	unsigned	n_region;
+	unsigned	n_slot;
+	unsigned	n_tc;
+
+	/* list of channels with no even trigger; terminated by "-1" */
+	const s8	*noevent;
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,9 +15,11 @@
 
 #include <linux/io.h>
 #include <asm-generic/gpio.h>
-#include <mach/hardware.h>
+
 #include <mach/irqs.h>
 
+#define DAVINCI_GPIO_BASE 0x01C67000
+
 /*
  * basic gpio routines
  *
@@ -26,23 +28,18 @@
  * go through boot loaders.
  *
  * the gpio clock will be turned on when gpios are used, and you may also
- * need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
+ * need to pay attention to PINMUX registers to be sure those pins are
  * used as gpios, not with other peripherals.
  *
  * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
- * and maybe for later updates, code should write GPIO(N) or:
- *  - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
- *  - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
- *
- * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
- * for now, that's != GPIO(N)
+ * and maybe for later updates, code may write GPIO(N).  These may be
+ * all 1.8V signals, all 3.3V ones, or a mix of the two.  A given chip
+ * may not support all the GPIOs in that range.
  *
  * GPIOs can also be on external chips, numbered after the ones built-in
  * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
  */
-#define	GPIO(X)		(X)		/* 0 <= X <= 70 */
-#define	GPIOV18(X)	(X)		/* 1.8V i/o; 0 <= X <= 53 */
-#define	GPIOV33(X)	((X)+54)	/* 3.3V i/o; 0 <= X <= 17 */
+#define	GPIO(X)		(X)		/* 0 <= X <= (DAVINCI_N_GPIO - 1) */
 
 struct gpio_controller {
 	u32	dir;
@@ -71,12 +68,14 @@ __gpio_to_controller(unsigned gpio)
 {
 	void *__iomem ptr;
 
-	if (gpio < 32)
+	if (gpio < 32 * 1)
 		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
-	else if (gpio < 64)
+	else if (gpio < 32 * 2)
 		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
-	else if (gpio < DAVINCI_N_GPIO)
+	else if (gpio < 32 * 3)
 		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
+	else if (gpio < 32 * 4)
+		ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
 	else
 		ptr = NULL;
 	return ptr;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/hardware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * Common hardware definitions
+ * Hardware definitions common to all DaVinci family processors
  *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ * Author: Kevin Hilman, Deep Root Systems, LLC
  *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * 2007 (c) Deep Root Systems, LLC. 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.
@@ -12,41 +12,16 @@
 #define __ASM_ARCH_HARDWARE_H
 
 /*
- * Base register addresses
+ * Before you add anything to ths file:
+ *
+ * This header is for defines common to ALL DaVinci family chips.
+ * Anything that is chip specific should go in <chipname>.h,
+ * and the chip/board init code should then explicitly include
+ * <chipname>.h
  */
-#define DAVINCI_DMA_3PCC_BASE			(0x01C00000)
-#define DAVINCI_DMA_3PTC0_BASE			(0x01C10000)
-#define DAVINCI_DMA_3PTC1_BASE			(0x01C10400)
-#define DAVINCI_I2C_BASE			(0x01C21000)
-#define DAVINCI_PWM0_BASE			(0x01C22000)
-#define DAVINCI_PWM1_BASE			(0x01C22400)
-#define DAVINCI_PWM2_BASE			(0x01C22800)
-#define DAVINCI_SYSTEM_MODULE_BASE		(0x01C40000)
-#define DAVINCI_PLL_CNTRL0_BASE			(0x01C40800)
-#define DAVINCI_PLL_CNTRL1_BASE			(0x01C40C00)
-#define DAVINCI_PWR_SLEEP_CNTRL_BASE		(0x01C41000)
-#define DAVINCI_SYSTEM_DFT_BASE			(0x01C42000)
-#define DAVINCI_IEEE1394_BASE			(0x01C60000)
-#define DAVINCI_USB_OTG_BASE			(0x01C64000)
-#define DAVINCI_CFC_ATA_BASE			(0x01C66000)
-#define DAVINCI_SPI_BASE			(0x01C66800)
-#define DAVINCI_GPIO_BASE			(0x01C67000)
-#define DAVINCI_UHPI_BASE			(0x01C67800)
-#define DAVINCI_VPSS_REGS_BASE			(0x01C70000)
-#define DAVINCI_EMAC_CNTRL_REGS_BASE		(0x01C80000)
-#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE	(0x01C81000)
-#define DAVINCI_EMAC_WRAPPER_RAM_BASE		(0x01C82000)
-#define DAVINCI_MDIO_CNTRL_REGS_BASE		(0x01C84000)
-#define DAVINCI_IMCOP_BASE			(0x01CC0000)
-#define DAVINCI_ASYNC_EMIF_CNTRL_BASE		(0x01E00000)
-#define DAVINCI_VLYNQ_BASE			(0x01E01000)
-#define DAVINCI_MCBSP_BASE			(0x01E02000)
-#define DAVINCI_MMC_SD_BASE			(0x01E10000)
-#define DAVINCI_MS_BASE				(0x01E20000)
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	(0x02000000)
-#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE	(0x04000000)
-#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	(0x06000000)
-#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE	(0x08000000)
-#define DAVINCI_VLYNQ_REMOTE_BASE		(0x0C000000)
+#define DAVINCI_SYSTEM_MODULE_BASE        0x01C40000
+
+/* System control register offsets */
+#define DM64XX_VDD3P3V_PWDN	0x48
 
 #endif /* __ASM_ARCH_HARDWARE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/io.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/io.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,22 +40,12 @@
 #else
 #define IOMEM(x)                ((void __force __iomem *)(x))
 
-/*
- * Functions to access the DaVinci IO region
- *
- * NOTE: - Use davinci_read/write[bwl] for physical register addresses
- *	 - Use __raw_read/write[bwl]() for virtual register addresses
- *	 - Use IO_ADDRESS(phys_addr) to convert registers to virtual addresses
- *	 - DO NOT use hardcoded virtual addresses to allow changing the
- *	   IO address space again if needed
- */
-#define davinci_readb(a)	__raw_readb(IO_ADDRESS(a))
-#define davinci_readw(a)	__raw_readw(IO_ADDRESS(a))
-#define davinci_readl(a)	__raw_readl(IO_ADDRESS(a))
+#define __arch_ioremap(p, s, t)	davinci_ioremap(p, s, t)
+#define __arch_iounmap(v)	davinci_iounmap(v)
 
-#define davinci_writeb(v, a)	__raw_writeb(v, IO_ADDRESS(a))
-#define davinci_writew(v, a)	__raw_writew(v, IO_ADDRESS(a))
-#define davinci_writel(v, a)	__raw_writel(v, IO_ADDRESS(a))
+void __iomem *davinci_ioremap(unsigned long phys, size_t size,
+			      unsigned int type);
+void davinci_iounmap(volatile void __iomem *addr);
 
 #endif /* __ASSEMBLER__ */
 #endif /* __ASM_ARCH_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -96,10 +96,111 @@
 #define IRQ_EMUINT       63
 
 #define DAVINCI_N_AINTC_IRQ	64
-#define DAVINCI_N_GPIO		71
+#define DAVINCI_N_GPIO		104
 
 #define NR_IRQS			(DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)
 
 #define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
 
+/* DaVinci DM6467-specific Interrupts */
+#define IRQ_DM646X_VP_VERTINT0  0
+#define IRQ_DM646X_VP_VERTINT1  1
+#define IRQ_DM646X_VP_VERTINT2  2
+#define IRQ_DM646X_VP_VERTINT3  3
+#define IRQ_DM646X_VP_ERRINT    4
+#define IRQ_DM646X_RESERVED_1   5
+#define IRQ_DM646X_RESERVED_2   6
+#define IRQ_DM646X_WDINT        7
+#define IRQ_DM646X_CRGENINT0    8
+#define IRQ_DM646X_CRGENINT1    9
+#define IRQ_DM646X_TSIFINT0     10
+#define IRQ_DM646X_TSIFINT1     11
+#define IRQ_DM646X_VDCEINT      12
+#define IRQ_DM646X_USBINT       13
+#define IRQ_DM646X_USBDMAINT    14
+#define IRQ_DM646X_PCIINT       15
+#define IRQ_DM646X_TCERRINT2    20
+#define IRQ_DM646X_TCERRINT3    21
+#define IRQ_DM646X_IDE          22
+#define IRQ_DM646X_HPIINT       23
+#define IRQ_DM646X_EMACRXTHINT  24
+#define IRQ_DM646X_EMACRXINT    25
+#define IRQ_DM646X_EMACTXINT    26
+#define IRQ_DM646X_EMACMISCINT  27
+#define IRQ_DM646X_MCASP0TXINT  28
+#define IRQ_DM646X_MCASP0RXINT  29
+#define IRQ_DM646X_RESERVED_3   31
+#define IRQ_DM646X_MCASP1TXINT  32
+#define IRQ_DM646X_VLQINT       38
+#define IRQ_DM646X_UARTINT2     42
+#define IRQ_DM646X_SPINT0       43
+#define IRQ_DM646X_SPINT1       44
+#define IRQ_DM646X_DSP2ARMINT   45
+#define IRQ_DM646X_RESERVED_4   46
+#define IRQ_DM646X_PSCINT       47
+#define IRQ_DM646X_GPIO0        48
+#define IRQ_DM646X_GPIO1        49
+#define IRQ_DM646X_GPIO2        50
+#define IRQ_DM646X_GPIO3        51
+#define IRQ_DM646X_GPIO4        52
+#define IRQ_DM646X_GPIO5        53
+#define IRQ_DM646X_GPIO6        54
+#define IRQ_DM646X_GPIO7        55
+#define IRQ_DM646X_GPIOBNK0     56
+#define IRQ_DM646X_GPIOBNK1     57
+#define IRQ_DM646X_GPIOBNK2     58
+#define IRQ_DM646X_DDRINT       59
+#define IRQ_DM646X_AEMIFINT     60
+
+/* DaVinci DM355-specific Interrupts */
+#define IRQ_DM355_CCDC_VDINT0	0
+#define IRQ_DM355_CCDC_VDINT1	1
+#define IRQ_DM355_CCDC_VDINT2	2
+#define IRQ_DM355_IPIPE_HST	3
+#define IRQ_DM355_H3AINT	4
+#define IRQ_DM355_IPIPE_SDR	5
+#define IRQ_DM355_IPIPEIFINT	6
+#define IRQ_DM355_OSDINT	7
+#define IRQ_DM355_VENCINT	8
+#define IRQ_DM355_IMCOPINT	11
+#define IRQ_DM355_RTOINT	13
+#define IRQ_DM355_TINT4		13
+#define IRQ_DM355_TINT2_TINT12	13
+#define IRQ_DM355_UARTINT2	14
+#define IRQ_DM355_TINT5		14
+#define IRQ_DM355_TINT2_TINT34	14
+#define IRQ_DM355_TINT6		15
+#define IRQ_DM355_TINT3_TINT12	15
+#define IRQ_DM355_SPINT1_0	17
+#define IRQ_DM355_SPINT1_1	18
+#define IRQ_DM355_SPINT2_0	19
+#define IRQ_DM355_SPINT2_1	21
+#define IRQ_DM355_TINT7		22
+#define IRQ_DM355_TINT3_TINT34	22
+#define IRQ_DM355_SDIOINT0	23
+#define IRQ_DM355_MMCINT0	26
+#define IRQ_DM355_MSINT		26
+#define IRQ_DM355_MMCINT1	27
+#define IRQ_DM355_PWMINT3	28
+#define IRQ_DM355_SDIOINT1	31
+#define IRQ_DM355_SPINT0_0	42
+#define IRQ_DM355_SPINT0_1	43
+#define IRQ_DM355_GPIO0		44
+#define IRQ_DM355_GPIO1		45
+#define IRQ_DM355_GPIO2		46
+#define IRQ_DM355_GPIO3		47
+#define IRQ_DM355_GPIO4		48
+#define IRQ_DM355_GPIO5		49
+#define IRQ_DM355_GPIO6		50
+#define IRQ_DM355_GPIO7		51
+#define IRQ_DM355_GPIO8		52
+#define IRQ_DM355_GPIO9		53
+#define IRQ_DM355_GPIOBNK0	54
+#define IRQ_DM355_GPIOBNK1	55
+#define IRQ_DM355_GPIOBNK2	56
+#define IRQ_DM355_GPIOBNK3	57
+#define IRQ_DM355_GPIOBNK4	58
+#define IRQ_DM355_GPIOBNK5	59
+#define IRQ_DM355_GPIOBNK6	60
+
 #endif /* __ASM_ARCH_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/mux.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/mux.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/mux.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,55 +1,183 @@
 /*
- * DaVinci pin multiplexing defines
+ * Table of the DAVINCI register configurations for the PINMUX combinations
  *
  * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
  *
+ * Based on linux/include/asm-arm/arch-omap/mux.h:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
  * 2007 (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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
  */
-#ifndef __ASM_ARCH_MUX_H
-#define __ASM_ARCH_MUX_H
 
-#define DAVINCI_MUX_AEAW0	0
-#define DAVINCI_MUX_AEAW1	1
-#define DAVINCI_MUX_AEAW2	2
-#define DAVINCI_MUX_AEAW3	3
-#define DAVINCI_MUX_AEAW4	4
-#define DAVINCI_MUX_AECS4	10
-#define DAVINCI_MUX_AECS5	11
-#define DAVINCI_MUX_VLYNQWD0	12
-#define DAVINCI_MUX_VLYNQWD1	13
-#define DAVINCI_MUX_VLSCREN	14
-#define DAVINCI_MUX_VLYNQEN	15
-#define DAVINCI_MUX_HDIREN	16
-#define DAVINCI_MUX_ATAEN	17
-#define DAVINCI_MUX_RGB666	22
-#define DAVINCI_MUX_RGB888	23
-#define DAVINCI_MUX_LOEEN	24
-#define DAVINCI_MUX_LFLDEN	25
-#define DAVINCI_MUX_CWEN	26
-#define DAVINCI_MUX_CFLDEN	27
-#define DAVINCI_MUX_HPIEN	29
-#define DAVINCI_MUX_1394EN	30
-#define DAVINCI_MUX_EMACEN	31
+#ifndef __INC_MACH_MUX_H
+#define __INC_MACH_MUX_H
 
-#define DAVINCI_MUX_LEVEL2	32
-#define DAVINCI_MUX_UART0	(DAVINCI_MUX_LEVEL2 + 0)
-#define DAVINCI_MUX_UART1	(DAVINCI_MUX_LEVEL2 + 1)
-#define DAVINCI_MUX_UART2	(DAVINCI_MUX_LEVEL2 + 2)
-#define DAVINCI_MUX_U2FLO	(DAVINCI_MUX_LEVEL2 + 3)
-#define DAVINCI_MUX_PWM0	(DAVINCI_MUX_LEVEL2 + 4)
-#define DAVINCI_MUX_PWM1	(DAVINCI_MUX_LEVEL2 + 5)
-#define DAVINCI_MUX_PWM2	(DAVINCI_MUX_LEVEL2 + 6)
-#define DAVINCI_MUX_I2C		(DAVINCI_MUX_LEVEL2 + 7)
-#define DAVINCI_MUX_SPI		(DAVINCI_MUX_LEVEL2 + 8)
-#define DAVINCI_MUX_MSTK	(DAVINCI_MUX_LEVEL2 + 9)
-#define DAVINCI_MUX_ASP		(DAVINCI_MUX_LEVEL2 + 10)
-#define DAVINCI_MUX_CLK0	(DAVINCI_MUX_LEVEL2 + 16)
-#define DAVINCI_MUX_CLK1	(DAVINCI_MUX_LEVEL2 + 17)
-#define DAVINCI_MUX_TIMIN	(DAVINCI_MUX_LEVEL2 + 18)
+/* System module registers */
+#define PINMUX0			0x00
+#define PINMUX1			0x04
+/* dm355 only */
+#define PINMUX2			0x08
+#define PINMUX3			0x0c
+#define PINMUX4			0x10
+#define INTMUX			0x18
+#define EVTMUX			0x1c
 
-extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
+struct mux_config {
+	const char *name;
+	const char *mux_reg_name;
+	const unsigned char mux_reg;
+	const unsigned char mask_offset;
+	const unsigned char mask;
+	const unsigned char mode;
+	bool debug;
+};
 
-#endif /* __ASM_ARCH_MUX_H */
+enum davinci_dm644x_index {
+	/* ATA and HDDIR functions */
+	DM644X_HDIREN,
+	DM644X_ATAEN,
+	DM644X_ATAEN_DISABLE,
+
+	/* HPI functions */
+	DM644X_HPIEN_DISABLE,
+
+	/* AEAW functions */
+	DM644X_AEAW,
+
+	/* Memory Stick */
+	DM644X_MSTK,
+
+	/* I2C */
+	DM644X_I2C,
+
+	/* ASP function */
+	DM644X_MCBSP,
+
+	/* UART1 */
+	DM644X_UART1,
+
+	/* UART2 */
+	DM644X_UART2,
+
+	/* PWM0 */
+	DM644X_PWM0,
+
+	/* PWM1 */
+	DM644X_PWM1,
+
+	/* PWM2 */
+	DM644X_PWM2,
+
+	/* VLYNQ function */
+	DM644X_VLYNQEN,
+	DM644X_VLSCREN,
+	DM644X_VLYNQWD,
+
+	/* EMAC and MDIO function */
+	DM644X_EMACEN,
+
+	/* GPIO3V[0:16] pins */
+	DM644X_GPIO3V,
+
+	/* GPIO pins */
+	DM644X_GPIO0,
+	DM644X_GPIO3,
+	DM644X_GPIO43_44,
+	DM644X_GPIO46_47,
+
+	/* VPBE */
+	DM644X_RGB666,
+
+	/* LCD */
+	DM644X_LOEEN,
+	DM644X_LFLDEN,
+};
+
+enum davinci_dm646x_index {
+	/* ATA function */
+	DM646X_ATAEN,
+
+	/* AUDIO Clock */
+	DM646X_AUDCK1,
+	DM646X_AUDCK0,
+
+	/* CRGEN Control */
+	DM646X_CRGMUX,
+
+	/* VPIF Control */
+	DM646X_STSOMUX_DISABLE,
+	DM646X_STSIMUX_DISABLE,
+	DM646X_PTSOMUX_DISABLE,
+	DM646X_PTSIMUX_DISABLE,
+
+	/* TSIF Control */
+	DM646X_STSOMUX,
+	DM646X_STSIMUX,
+	DM646X_PTSOMUX_PARALLEL,
+	DM646X_PTSIMUX_PARALLEL,
+	DM646X_PTSOMUX_SERIAL,
+	DM646X_PTSIMUX_SERIAL,
+};
+
+enum davinci_dm355_index {
+	/* MMC/SD 0 */
+	DM355_MMCSD0,
+
+	/* MMC/SD 1 */
+	DM355_SD1_CLK,
+	DM355_SD1_CMD,
+	DM355_SD1_DATA3,
+	DM355_SD1_DATA2,
+	DM355_SD1_DATA1,
+	DM355_SD1_DATA0,
+
+	/* I2C */
+	DM355_I2C_SDA,
+	DM355_I2C_SCL,
+
+	/* ASP0 function */
+	DM355_MCBSP0_BDX,
+	DM355_MCBSP0_X,
+	DM355_MCBSP0_BFSX,
+	DM355_MCBSP0_BDR,
+	DM355_MCBSP0_R,
+	DM355_MCBSP0_BFSR,
+
+	/* SPI0 */
+	DM355_SPI0_SDI,
+	DM355_SPI0_SDENA0,
+	DM355_SPI0_SDENA1,
+
+	/* IRQ muxing */
+	DM355_INT_EDMA_CC,
+	DM355_INT_EDMA_TC0_ERR,
+	DM355_INT_EDMA_TC1_ERR,
+
+	/* EDMA event muxing */
+	DM355_EVT8_ASP1_TX,
+	DM355_EVT9_ASP1_RX,
+	DM355_EVT26_MMC0_RX,
+};
+
+#ifdef CONFIG_DAVINCI_MUX
+/* setup pin muxing */
+extern void davinci_mux_init(void);
+extern int davinci_mux_register(const struct mux_config *pins,
+				unsigned long size);
+extern int davinci_cfg_reg(unsigned long reg_cfg);
+#else
+/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
+static inline void davinci_mux_init(void) {}
+static inline int davinci_mux_register(const struct mux_config *pins,
+				       unsigned long size) { return 0; }
+static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
+#endif
+
+#endif /* __INC_MACH_MUX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/nand.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/nand.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/nand.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/nand.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,80 @@
+/*
+ * mach-davinci/nand.h
+ *
+ * Copyright Â© 2006 Texas Instruments.
+ *
+ * Ported to 2.6.23 Copyright Â© 2008 by
+ *   Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ *   Troy Kisky <troy.kisky@boundarydevices.com>
+ *   Dirk Behme <Dirk.Behme@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 __ARCH_ARM_DAVINCI_NAND_H
+#define __ARCH_ARM_DAVINCI_NAND_H
+
+#include <linux/mtd/nand.h>
+
+#define NRCSR_OFFSET		0x00
+#define AWCCR_OFFSET		0x04
+#define A1CR_OFFSET		0x10
+#define NANDFCR_OFFSET		0x60
+#define NANDFSR_OFFSET		0x64
+#define NANDF1ECC_OFFSET	0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET	0xbc
+#define NAND_4BIT_ECC1_OFFSET		0xc0
+#define NAND_4BIT_ECC2_OFFSET		0xc4
+#define NAND_4BIT_ECC3_OFFSET		0xc8
+#define NAND_4BIT_ECC4_OFFSET		0xcc
+#define NAND_ERR_ADD1_OFFSET		0xd0
+#define NAND_ERR_ADD2_OFFSET		0xd4
+#define NAND_ERR_ERRVAL1_OFFSET		0xd8
+#define NAND_ERR_ERRVAL2_OFFSET		0xdc
+
+/* NOTE:  boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define	MASK_ALE		0x08
+#define	MASK_CLE		0x10
+
+struct davinci_nand_pdata {		/* platform_data */
+	uint32_t		mask_ale;
+	uint32_t		mask_cle;
+
+	/* for packages using two chipselects */
+	uint32_t		mask_chipsel;
+
+	/* board's default static partition info */
+	struct mtd_partition	*parts;
+	unsigned		nr_parts;
+
+	/* none  == NAND_ECC_NONE (strongly *not* advised!!)
+	 * soft  == NAND_ECC_SOFT
+	 * 1-bit == NAND_ECC_HW
+	 * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips)
+	 */
+	nand_ecc_modes_t	ecc_mode;
+
+	/* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+	unsigned		options;
+};
+
+#endif	/* __ARCH_ARM_DAVINCI_NAND_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/psc.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/psc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/psc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/psc.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,8 +38,6 @@
 #define DAVINCI_LPSC_TPTC1          4
 #define DAVINCI_LPSC_EMAC           5
 #define DAVINCI_LPSC_EMAC_WRAPPER   6
-#define DAVINCI_LPSC_MDIO           7
-#define DAVINCI_LPSC_IEEE1394       8
 #define DAVINCI_LPSC_USB            9
 #define DAVINCI_LPSC_ATA            10
 #define DAVINCI_LPSC_VLYNQ          11
@@ -47,7 +45,6 @@
 #define DAVINCI_LPSC_DDR_EMIF       13
 #define DAVINCI_LPSC_AEMIF          14
 #define DAVINCI_LPSC_MMC_SD         15
-#define DAVINCI_LPSC_MEMSTICK       16
 #define DAVINCI_LPSC_McBSP          17
 #define DAVINCI_LPSC_I2C            18
 #define DAVINCI_LPSC_UART0          19
@@ -73,4 +70,54 @@
 #define DAVINCI_LPSC_GEM            39
 #define DAVINCI_LPSC_IMCOP          40
 
+#define DM355_LPSC_TIMER3		5
+#define DM355_LPSC_SPI1			6
+#define DM355_LPSC_MMC_SD1		7
+#define DM355_LPSC_McBSP1		8
+#define DM355_LPSC_PWM3			10
+#define DM355_LPSC_SPI2			11
+#define DM355_LPSC_RTO			12
+#define DM355_LPSC_VPSS_DAC		41
+
+/*
+ * LPSC Assignments
+ */
+#define DM646X_LPSC_ARM            0
+#define DM646X_LPSC_C64X_CPU       1
+#define DM646X_LPSC_HDVICP0        2
+#define DM646X_LPSC_HDVICP1        3
+#define DM646X_LPSC_TPCC           4
+#define DM646X_LPSC_TPTC0          5
+#define DM646X_LPSC_TPTC1          6
+#define DM646X_LPSC_TPTC2          7
+#define DM646X_LPSC_TPTC3          8
+#define DM646X_LPSC_PCI            13
+#define DM646X_LPSC_EMAC           14
+#define DM646X_LPSC_VDCE           15
+#define DM646X_LPSC_VPSSMSTR       16
+#define DM646X_LPSC_VPSSSLV        17
+#define DM646X_LPSC_TSIF0          18
+#define DM646X_LPSC_TSIF1          19
+#define DM646X_LPSC_DDR_EMIF       20
+#define DM646X_LPSC_AEMIF          21
+#define DM646X_LPSC_McASP0         22
+#define DM646X_LPSC_McASP1         23
+#define DM646X_LPSC_CRGEN0         24
+#define DM646X_LPSC_CRGEN1         25
+#define DM646X_LPSC_UART0          26
+#define DM646X_LPSC_UART1          27
+#define DM646X_LPSC_UART2          28
+#define DM646X_LPSC_PWM0           29
+#define DM646X_LPSC_PWM1           30
+#define DM646X_LPSC_I2C            31
+#define DM646X_LPSC_SPI            32
+#define DM646X_LPSC_GPIO           33
+#define DM646X_LPSC_TIMER0         34
+#define DM646X_LPSC_TIMER1         35
+#define DM646X_LPSC_ARM_INTC       45
+
+extern int davinci_psc_is_clk_active(unsigned int id);
+extern void davinci_psc_config(unsigned int domain, unsigned int id,
+			       char enable);
+
 #endif /* __ASM_ARCH_PSC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/serial.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/serial.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/serial.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,8 +13,23 @@
 
 #include <mach/io.h>
 
-#define DAVINCI_UART0_BASE   (IO_PHYS + 0x20000)
-#define DAVINCI_UART1_BASE   (IO_PHYS + 0x20400)
-#define DAVINCI_UART2_BASE   (IO_PHYS + 0x20800)
+#define DAVINCI_MAX_NR_UARTS	3
+#define DAVINCI_UART0_BASE	(IO_PHYS + 0x20000)
+#define DAVINCI_UART1_BASE	(IO_PHYS + 0x20400)
+#define DAVINCI_UART2_BASE	(IO_PHYS + 0x20800)
+
+#define DM355_UART2_BASE	(IO_PHYS + 0x206000)
+
+/* DaVinci UART register offsets */
+#define UART_DAVINCI_PWREMU		0x0c
+#define UART_DM646X_SCR			0x10
+#define UART_DM646X_SCR_TX_WATERMARK	0x08
+
+struct davinci_uart_config {
+	/* Bit field of UARTs present; bit 0 --> UART1 */
+	unsigned int enabled_uarts;
+};
+
+extern void davinci_serial_init(struct davinci_uart_config *);
 
 #endif /* __ASM_ARCH_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,7 @@ static void arch_idle(void)
 	cpu_do_idle();
 }
 
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
 {
 	davinci_watchdog_reset();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/io.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/io.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/io.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,26 @@ void __init davinci_map_common_io(void)
 	davinci_check_revision();
 }
 
-void __init davinci_init_common_hw(void)
+#define BETWEEN(p, st, sz)	((p) >= (st) && (p) < ((st) + (sz)))
+#define XLATE(p, pst, vst)	((void __iomem *)((p) - (pst) + (vst)))
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
 {
-	davinci_clk_init();
+	if (BETWEEN(p, IO_PHYS, IO_SIZE))
+		return XLATE(p, IO_PHYS, IO_VIRT);
+
+	return __arm_ioremap(p, size, type);
 }
+EXPORT_SYMBOL(davinci_ioremap);
+
+void davinci_iounmap(volatile void __iomem *addr)
+{
+	unsigned long virt = (unsigned long)addr;
+
+	if (virt >= VMALLOC_START && virt < VMALLOC_END)
+		__iounmap(addr);
+}
+EXPORT_SYMBOL(davinci_iounmap);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/cputype.h>
 #include <asm/mach/irq.h>
 
 #define IRQ_BIT(irq)		((irq) & 0x1f)
@@ -40,14 +41,18 @@
 #define IRQ_INTPRI0_REG_OFFSET	0x0030
 #define IRQ_INTPRI7_REG_OFFSET	0x004C
 
+const u8 *davinci_def_priorities;
+
+#define INTC_BASE IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
+
 static inline unsigned int davinci_irq_readl(int offset)
 {
-	return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
+	return __raw_readl(INTC_BASE + offset);
 }
 
 static inline void davinci_irq_writel(unsigned long value, int offset)
 {
-	davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset);
+	__raw_writel(value, INTC_BASE + offset);
 }
 
 /* Disable interrupt */
@@ -108,9 +113,8 @@ static struct irq_chip davinci_irq_chip_
 	.unmask = davinci_unmask_irq,
 };
 
-
 /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
-static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
+static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
 	[IRQ_VDINT0]		= 2,
 	[IRQ_VDINT1]		= 6,
 	[IRQ_VDINT2]		= 6,
@@ -177,11 +181,149 @@ static const u8 default_priorities[DAVIN
 	[IRQ_EMUINT]		= 7,
 };
 
+static const u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+	[IRQ_DM646X_VP_VERTINT0]        = 7,
+	[IRQ_DM646X_VP_VERTINT1]        = 7,
+	[IRQ_DM646X_VP_VERTINT2]        = 7,
+	[IRQ_DM646X_VP_VERTINT3]        = 7,
+	[IRQ_DM646X_VP_ERRINT]          = 7,
+	[IRQ_DM646X_RESERVED_1]         = 7,
+	[IRQ_DM646X_RESERVED_2]         = 7,
+	[IRQ_DM646X_WDINT]              = 7,
+	[IRQ_DM646X_CRGENINT0]          = 7,
+	[IRQ_DM646X_CRGENINT1]          = 7,
+	[IRQ_DM646X_TSIFINT0]           = 7,
+	[IRQ_DM646X_TSIFINT1]           = 7,
+	[IRQ_DM646X_VDCEINT]            = 7,
+	[IRQ_DM646X_USBINT]             = 7,
+	[IRQ_DM646X_USBDMAINT]          = 7,
+	[IRQ_DM646X_PCIINT]             = 7,
+	[IRQ_CCINT0]                    = 7,    /* dma */
+	[IRQ_CCERRINT]                  = 7,    /* dma */
+	[IRQ_TCERRINT0]                 = 7,    /* dma */
+	[IRQ_TCERRINT]                  = 7,    /* dma */
+	[IRQ_DM646X_TCERRINT2]          = 7,
+	[IRQ_DM646X_TCERRINT3]          = 7,
+	[IRQ_DM646X_IDE]                = 7,
+	[IRQ_DM646X_HPIINT]             = 7,
+	[IRQ_DM646X_EMACRXTHINT]        = 7,
+	[IRQ_DM646X_EMACRXINT]          = 7,
+	[IRQ_DM646X_EMACTXINT]          = 7,
+	[IRQ_DM646X_EMACMISCINT]        = 7,
+	[IRQ_DM646X_MCASP0TXINT]        = 7,
+	[IRQ_DM646X_MCASP0RXINT]        = 7,
+	[IRQ_AEMIFINT]                  = 7,
+	[IRQ_DM646X_RESERVED_3]         = 7,
+	[IRQ_DM646X_MCASP1TXINT]        = 7,    /* clockevent */
+	[IRQ_TINT0_TINT34]              = 7,    /* clocksource */
+	[IRQ_TINT1_TINT12]              = 7,    /* DSP timer */
+	[IRQ_TINT1_TINT34]              = 7,    /* system tick */
+	[IRQ_PWMINT0]                   = 7,
+	[IRQ_PWMINT1]                   = 7,
+	[IRQ_DM646X_VLQINT]             = 7,
+	[IRQ_I2C]                       = 7,
+	[IRQ_UARTINT0]                  = 7,
+	[IRQ_UARTINT1]                  = 7,
+	[IRQ_DM646X_UARTINT2]           = 7,
+	[IRQ_DM646X_SPINT0]             = 7,
+	[IRQ_DM646X_SPINT1]             = 7,
+	[IRQ_DM646X_DSP2ARMINT]         = 7,
+	[IRQ_DM646X_RESERVED_4]         = 7,
+	[IRQ_DM646X_PSCINT]             = 7,
+	[IRQ_DM646X_GPIO0]              = 7,
+	[IRQ_DM646X_GPIO1]              = 7,
+	[IRQ_DM646X_GPIO2]              = 7,
+	[IRQ_DM646X_GPIO3]              = 7,
+	[IRQ_DM646X_GPIO4]              = 7,
+	[IRQ_DM646X_GPIO5]              = 7,
+	[IRQ_DM646X_GPIO6]              = 7,
+	[IRQ_DM646X_GPIO7]              = 7,
+	[IRQ_DM646X_GPIOBNK0]           = 7,
+	[IRQ_DM646X_GPIOBNK1]           = 7,
+	[IRQ_DM646X_GPIOBNK2]           = 7,
+	[IRQ_DM646X_DDRINT]             = 7,
+	[IRQ_DM646X_AEMIFINT]           = 7,
+	[IRQ_COMMTX]                    = 7,
+	[IRQ_COMMRX]                    = 7,
+	[IRQ_EMUINT]                    = 7,
+};
+
+static const u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+	[IRQ_DM355_CCDC_VDINT0]		= 2,
+	[IRQ_DM355_CCDC_VDINT1]		= 6,
+	[IRQ_DM355_CCDC_VDINT2]		= 6,
+	[IRQ_DM355_IPIPE_HST]		= 6,
+	[IRQ_DM355_H3AINT]		= 6,
+	[IRQ_DM355_IPIPE_SDR]		= 6,
+	[IRQ_DM355_IPIPEIFINT]		= 6,
+	[IRQ_DM355_OSDINT]		= 7,
+	[IRQ_DM355_VENCINT]		= 6,
+	[IRQ_ASQINT]			= 6,
+	[IRQ_IMXINT]			= 6,
+	[IRQ_USBINT]			= 4,
+	[IRQ_DM355_RTOINT]		= 4,
+	[IRQ_DM355_UARTINT2]		= 7,
+	[IRQ_DM355_TINT6]		= 7,
+	[IRQ_CCINT0]			= 5,	/* dma */
+	[IRQ_CCERRINT]			= 5,	/* dma */
+	[IRQ_TCERRINT0]			= 5,	/* dma */
+	[IRQ_TCERRINT]			= 5,	/* dma */
+	[IRQ_DM355_SPINT2_1]		= 7,
+	[IRQ_DM355_TINT7]		= 4,
+	[IRQ_DM355_SDIOINT0]		= 7,
+	[IRQ_MBXINT]			= 7,
+	[IRQ_MBRINT]			= 7,
+	[IRQ_MMCINT]			= 7,
+	[IRQ_DM355_MMCINT1]		= 7,
+	[IRQ_DM355_PWMINT3]		= 7,
+	[IRQ_DDRINT]			= 7,
+	[IRQ_AEMIFINT]			= 7,
+	[IRQ_DM355_SDIOINT1]		= 4,
+	[IRQ_TINT0_TINT12]		= 2,	/* clockevent */
+	[IRQ_TINT0_TINT34]		= 2,	/* clocksource */
+	[IRQ_TINT1_TINT12]		= 7,	/* DSP timer */
+	[IRQ_TINT1_TINT34]		= 7,	/* system tick */
+	[IRQ_PWMINT0]			= 7,
+	[IRQ_PWMINT1]			= 7,
+	[IRQ_PWMINT2]			= 7,
+	[IRQ_I2C]			= 3,
+	[IRQ_UARTINT0]			= 3,
+	[IRQ_UARTINT1]			= 3,
+	[IRQ_DM355_SPINT0_0]		= 3,
+	[IRQ_DM355_SPINT0_1]		= 3,
+	[IRQ_DM355_GPIO0]		= 3,
+	[IRQ_DM355_GPIO1]		= 7,
+	[IRQ_DM355_GPIO2]		= 4,
+	[IRQ_DM355_GPIO3]		= 4,
+	[IRQ_DM355_GPIO4]		= 7,
+	[IRQ_DM355_GPIO5]		= 7,
+	[IRQ_DM355_GPIO6]		= 7,
+	[IRQ_DM355_GPIO7]		= 7,
+	[IRQ_DM355_GPIO8]		= 7,
+	[IRQ_DM355_GPIO9]		= 7,
+	[IRQ_DM355_GPIOBNK0]		= 7,
+	[IRQ_DM355_GPIOBNK1]		= 7,
+	[IRQ_DM355_GPIOBNK2]		= 7,
+	[IRQ_DM355_GPIOBNK3]		= 7,
+	[IRQ_DM355_GPIOBNK4]		= 7,
+	[IRQ_DM355_GPIOBNK5]		= 7,
+	[IRQ_DM355_GPIOBNK6]		= 7,
+	[IRQ_COMMTX]			= 7,
+	[IRQ_COMMRX]			= 7,
+	[IRQ_EMUINT]			= 7,
+};
+
 /* ARM Interrupt Controller Initialization */
 void __init davinci_irq_init(void)
 {
 	unsigned i;
-	const u8 *priority = default_priorities;
+
+	if (cpu_is_davinci_dm644x())
+		davinci_def_priorities = dm644x_default_priorities;
+	else if (cpu_is_davinci_dm646x())
+		davinci_def_priorities = dm646x_default_priorities;
+	else if (cpu_is_davinci_dm355())
+		davinci_def_priorities = dm355_default_priorities;
 
 	/* Clear all interrupt requests */
 	davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
@@ -209,8 +351,8 @@ void __init davinci_irq_init(void)
 		unsigned	j;
 		u32		pri;
 
-		for (j = 0, pri = 0; j < 32; j += 4, priority++)
-			pri |= (*priority & 0x07) << j;
+		for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
+			pri |= (*davinci_def_priorities & 0x07) << j;
 		davinci_irq_writel(pri, i);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -4,19 +4,56 @@ menu "TI DaVinci Implementations"
 
 comment "DaVinci Core Type"
 
-config ARCH_DAVINCI644x
-	default y
+config ARCH_DAVINCI_DM644x
 	bool "DaVinci 644x based system"
 
 comment "DaVinci Board Type"
 
 config MACH_DAVINCI_EVM
-	bool "TI DaVinci EVM"
+	bool "TI DM644x EVM"
 	default y
-	depends on ARCH_DAVINCI644x
+	depends on ARCH_DAVINCI_DM644x
 	help
 	  Configure this option to specify the whether the board used
-	  for development is a DaVinci EVM
+	  for development is a DM644x EVM
+
+
+config DAVINCI_MUX
+	bool "DAVINCI multiplexing support"
+	depends on ARCH_DAVINCI
+	default y
+	help
+	  Pin multiplexing support for DAVINCI boards. If your bootloader
+	  sets the multiplexing correctly, say N. Otherwise, or if unsure,
+	  say Y.
+
+config DAVINCI_MUX_DEBUG
+        bool "Multiplexing debug output"
+        depends on DAVINCI_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 DAVINCI_MUX_WARNINGS
+        bool "Warn about pins the bootloader didn't set up"
+        depends on DAVINCI_MUX
+        help
+          Choose Y here to warn whenever driver initialization logic needs
+          to change the pin multiplexing setup.  When there are no warnings
+          printed, it's safe to deselect DAVINCI_MUX for your product.
+
+config DAVINCI_RESET_CLOCKS
+	bool "Reset unused clocks during boot"
+	depends on ARCH_DAVINCI
+	help
+	  Say Y if you want to reset unused clocks during boot.
+	  This option saves power, but assumes all drivers are
+	  using the clock framework. Broken drivers that do not
+	  yet use clock framework may not work with this option.
+	  If you are booting from another operating system, you
+	  probably do not want this option enabled until your
+	  device drivers work properly.
 
 endmenu
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,12 @@
 
 # Common objects
 obj-y 			:= time.o irq.o clock.o serial.o io.o id.o psc.o \
-			   gpio.o mux.o devices.o usb.o
+			   gpio.o devices.o dma.o usb.o
+
+obj-$(CONFIG_DAVINCI_MUX)		+= mux.o
+
+# Chip specific
+obj-$(CONFIG_ARCH_DAVINCI_DM644x)       += dm644x.o
 
 # Board specific
-obj-$(CONFIG_MACH_DAVINCI_EVM)  += board-evm.o
+obj-$(CONFIG_MACH_DAVINCI_EVM)  	+= board-dm644x-evm.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/mux.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/mux.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/mux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/mux.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,41 +1,103 @@
 /*
- * DaVinci pin multiplexing configurations
+ * Utility to set the DAVINCI MUX register from a table in mux.h
  *
  * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
  *
+ * Based on linux/arch/arm/plat-omap/mux.c:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
  * 2007 (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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
  */
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/spinlock.h>
 
 #include <mach/hardware.h>
-
 #include <mach/mux.h>
 
-/* System control register offsets */
-#define PINMUX0         0x00
-#define PINMUX1         0x04
+static const struct mux_config *mux_table;
+static unsigned long pin_table_sz;
 
-static DEFINE_SPINLOCK(mux_lock);
+int __init davinci_mux_register(const struct mux_config *pins,
+				unsigned long size)
+{
+	mux_table = pins;
+	pin_table_sz = size;
 
-void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
+	return 0;
+}
+
+/*
+ * Sets the DAVINCI MUX register based on the table
+ */
+int __init_or_module davinci_cfg_reg(const unsigned long index)
 {
-	u32 pinmux, muxreg = PINMUX0;
+	static DEFINE_SPINLOCK(mux_spin_lock);
+	void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+	unsigned long flags;
+	const struct mux_config *cfg;
+	unsigned int reg_orig = 0, reg = 0;
+	unsigned int mask, warn = 0;
 
-	if (mux >= DAVINCI_MUX_LEVEL2) {
-		muxreg = PINMUX1;
-		mux -= DAVINCI_MUX_LEVEL2;
+	if (!mux_table)
+		BUG();
+
+	if (index >= pin_table_sz) {
+		printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+		       index, pin_table_sz);
+		dump_stack();
+		return -ENODEV;
 	}
 
-	spin_lock(&mux_lock);
-	pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
-	if (enable)
-		pinmux |= (1 << mux);
-	else
-		pinmux &= ~(1 << mux);
-	davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
-	spin_unlock(&mux_lock);
+	cfg = &mux_table[index];
+
+	if (cfg->name == NULL) {
+		printk(KERN_ERR "No entry for the specified index\n");
+		return -ENODEV;
+	}
+
+	/* Update the mux register in question */
+	if (cfg->mask) {
+		unsigned	tmp1, tmp2;
+
+		spin_lock_irqsave(&mux_spin_lock, flags);
+		reg_orig = __raw_readl(base + cfg->mux_reg);
+
+		mask = (cfg->mask << cfg->mask_offset);
+		tmp1 = reg_orig & mask;
+		reg = reg_orig & ~mask;
+
+		tmp2 = (cfg->mode << cfg->mask_offset);
+		reg |= tmp2;
+
+		if (tmp1 != tmp2)
+			warn = 1;
+
+		__raw_writel(reg, base + cfg->mux_reg);
+		spin_unlock_irqrestore(&mux_spin_lock, flags);
+	}
+
+	if (warn) {
+#ifdef CONFIG_DAVINCI_MUX_WARNINGS
+		printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
+#endif
+	}
+
+#ifdef CONFIG_DAVINCI_MUX_DEBUG
+	if (cfg->debug || warn) {
+		printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
+		printk(KERN_WARNING "	   %s (0x%08x) = 0x%08x -> 0x%08x\n",
+		       cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
+	}
+#endif
+
+	return 0;
 }
+EXPORT_SYMBOL(davinci_cfg_reg);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/mux.h linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/mux.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/mux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/mux.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * Pin-multiplex helper macros for TI DaVinci family devices
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (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.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+#ifndef _MACH_DAVINCI_MUX_H_
+#define _MACH_DAVINCI_MUX_H_
+
+#include <mach/mux.h>
+
+#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
+[soc##_##desc] = {							\
+			.name =  #desc,					\
+			.debug = dbg,					\
+			.mux_reg_name = "PINMUX"#muxreg,		\
+			.mux_reg = PINMUX##muxreg,			\
+			.mask_offset = mode_offset,			\
+			.mask = mode_mask,				\
+			.mode = mux_mode,				\
+		},
+
+#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg)	\
+[soc##_##desc] = {							\
+			.name =  #desc,					\
+			.debug = dbg,					\
+			.mux_reg_name = "INTMUX",			\
+			.mux_reg = INTMUX,				\
+			.mask_offset = mode_offset,			\
+			.mask = mode_mask,				\
+			.mode = mux_mode,				\
+		},
+
+#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg)	\
+[soc##_##desc] = {							\
+			.name =  #desc,					\
+			.debug = dbg,					\
+			.mux_reg_name = "EVTMUX",			\
+			.mux_reg = EVTMUX,				\
+			.mask_offset = mode_offset,			\
+			.mask = mode_mask,				\
+			.mode = mux_mode,				\
+		},
+
+#endif /* _MACH_DAVINCI_MUX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/psc.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/psc.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/psc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/psc.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,10 +23,13 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
+#include <mach/cputype.h>
 #include <mach/hardware.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
 
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
+
 /* PSC register offsets */
 #define EPCPR		0x070
 #define PTCMD		0x120
@@ -36,102 +39,61 @@
 #define MDSTAT		0x800
 #define MDCTL		0xA00
 
-/* System control register offsets */
-#define VDD3P3V_PWDN	0x48
+#define MDSTAT_STATE_MASK 0x1f
 
-static void davinci_psc_mux(unsigned int id)
+/* Return nonzero iff the domain's clock is active */
+int __init davinci_psc_is_clk_active(unsigned int id)
 {
-	switch (id) {
-	case DAVINCI_LPSC_ATA:
-		davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
-		davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
-		break;
-	case DAVINCI_LPSC_MMC_SD:
-		/* VDD power manupulations are done in U-Boot for CPMAC
-		 * so applies to MMC as well
-		 */
-		/*Set up the pull regiter for MMC */
-		davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
-		davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
-		break;
-	case DAVINCI_LPSC_I2C:
-		davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
-		break;
-	case DAVINCI_LPSC_McBSP:
-		davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
-		break;
-	default:
-		break;
-	}
+	void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
+	u32 mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+
+	/* if clocked, state can be "Enable" or "SyncReset" */
+	return mdstat & BIT(12);
 }
 
 /* Enable or disable a PSC domain */
 void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
 {
-	u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
+	u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
+	void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
+	u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */
 
-	mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
-	if (enable)
-		mdctl |= 0x00000003;	/* Enable Module */
-	else
-		mdctl &= 0xFFFFFFF2;	/* Disable Module */
-	davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
+	mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
+	mdctl &= ~MDSTAT_STATE_MASK;
+	mdctl |= next_state;
+	__raw_writel(mdctl, psc_base + MDCTL + 4 * id);
 
-	pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
+	pdstat = __raw_readl(psc_base + PDSTAT);
 	if ((pdstat & 0x00000001) == 0) {
-		pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+		pdctl1 = __raw_readl(psc_base + PDCTL1);
 		pdctl1 |= 0x1;
-		davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+		__raw_writel(pdctl1, psc_base + PDCTL1);
 
 		ptcmd = 1 << domain;
-		davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+		__raw_writel(ptcmd, psc_base + PTCMD);
 
 		do {
-			epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
-					      EPCPR);
+			epcpr = __raw_readl(psc_base + EPCPR);
 		} while ((((epcpr >> domain) & 1) == 0));
 
-		pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+		pdctl1 = __raw_readl(psc_base + PDCTL1);
 		pdctl1 |= 0x100;
-		davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+		__raw_writel(pdctl1, psc_base + PDCTL1);
 
 		do {
-			ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+			ptstat = __raw_readl(psc_base +
 					       PTSTAT);
 		} while (!(((ptstat >> domain) & 1) == 0));
 	} else {
 		ptcmd = 1 << domain;
-		davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+		__raw_writel(ptcmd, psc_base + PTCMD);
 
 		do {
-			ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
-					       PTSTAT);
+			ptstat = __raw_readl(psc_base + PTSTAT);
 		} while (!(((ptstat >> domain) & 1) == 0));
 	}
 
-	if (enable)
-		mdstat_mask = 0x3;
-	else
-		mdstat_mask = 0x2;
-
 	do {
-		mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
-				       MDSTAT + 4 * id);
-	} while (!((mdstat & 0x0000001F) == mdstat_mask));
-
-	if (enable)
-		davinci_psc_mux(id);
-}
-
-void __init davinci_psc_init(void)
-{
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);
-
-	/* Turn on WatchDog timer LPSC.	 Needed for RESET to work */
-	davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
+		mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+	} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/serial.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/serial.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,32 +32,47 @@
 #include <mach/hardware.h>
 #include <mach/serial.h>
 #include <mach/irqs.h>
+#include <mach/cputype.h>
+#include "clock.h"
 
-#define UART_DAVINCI_PWREMU 0x0c
-
-static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up,
-					  int offset)
+static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+					   int offset)
 {
 	offset <<= up->regshift;
-	return (unsigned int)__raw_readb(up->membase + offset);
+	return (unsigned int)__raw_readl(IO_ADDRESS(up->mapbase) + offset);
 }
 
-static inline void davinci_serial_outp(struct plat_serial8250_port *p,
-				       int offset, int value)
+static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+				    int value)
 {
 	offset <<= p->regshift;
-	__raw_writeb(value, p->membase + offset);
+	__raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
 }
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
-		.membase	= (char *)IO_ADDRESS(DAVINCI_UART0_BASE),
-		.mapbase	= (unsigned long)DAVINCI_UART0_BASE,
+		.mapbase	= DAVINCI_UART0_BASE,
 		.irq		= IRQ_UARTINT0,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.mapbase	= DAVINCI_UART1_BASE,
+		.irq		= IRQ_UARTINT1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.mapbase	= DAVINCI_UART2_BASE,
+		.irq		= IRQ_UARTINT2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_IOREMAP,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
-		.uartclk	= 27000000,
 	},
 	{
 		.flags		= 0
@@ -74,22 +89,68 @@ static struct platform_device serial_dev
 
 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
 {
-	/* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
 	unsigned int pwremu = 0;
 
-	davinci_serial_outp(p, UART_IER, 0);  /* disable all interrupts */
+	serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */
 
-	davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
+	/* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
+	serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
 	mdelay(10);
 
 	pwremu |= (0x3 << 13);
 	pwremu |= 0x1;
-	davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
+	serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
+
+	if (cpu_is_davinci_dm646x())
+		serial_write_reg(p, UART_DM646X_SCR,
+				 UART_DM646X_SCR_TX_WATERMARK);
+}
+
+void __init davinci_serial_init(struct davinci_uart_config *info)
+{
+	int i;
+	char name[16];
+	struct clk *uart_clk;
+	struct device *dev = &serial_device.dev;
+
+	/*
+	 * Make sure the serial ports are muxed on at this point.
+	 * You have to mux them off in device drivers later on
+	 * if not needed.
+	 */
+	for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++) {
+		struct plat_serial8250_port *p = serial_platform_data + i;
+
+		if (!(info->enabled_uarts & (1 << i))) {
+			p->flags = 0;
+			continue;
+		}
+
+		if (cpu_is_davinci_dm646x())
+			p->iotype = UPIO_MEM32;
+
+		if (cpu_is_davinci_dm355()) {
+			if (i == 2) {
+				p->mapbase = (unsigned long)DM355_UART2_BASE;
+				p->irq = IRQ_DM355_UARTINT2;
+			}
+		}
+
+		sprintf(name, "uart%d", i);
+		uart_clk = clk_get(dev, name);
+		if (IS_ERR(uart_clk))
+			printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
+					__func__, __LINE__, i);
+		else {
+			clk_enable(uart_clk);
+			p->uartclk = clk_get_rate(uart_clk);
+			davinci_serial_reset(p);
+		}
+	}
 }
 
 static int __init davinci_init(void)
 {
-	davinci_serial_reset(&serial_platform_data[0]);
 	return platform_device_register(&serial_device);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,9 @@
 #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 <mach/hardware.h>
 #include <asm/system.h>
@@ -24,8 +27,11 @@
 #include <asm/mach/time.h>
 #include <asm/errno.h>
 #include <mach/io.h>
+#include <mach/cputype.h>
+#include "clock.h"
 
 static struct clock_event_device clockevent_davinci;
+static unsigned int davinci_clock_tick_rate;
 
 #define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
 #define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
@@ -99,9 +105,9 @@ struct timer_s {
 	unsigned int id;
 	unsigned long period;
 	unsigned long opts;
-	unsigned long reg_base;
-	unsigned long tim_reg;
-	unsigned long prd_reg;
+	void __iomem *base;
+	unsigned long tim_off;
+	unsigned long prd_off;
 	unsigned long enamode_shift;
 	struct irqaction irqaction;
 };
@@ -114,15 +120,15 @@ static struct timer_s timers[];
 
 static int timer32_config(struct timer_s *t)
 {
-	u32 tcr = davinci_readl(t->reg_base + TCR);
+	u32 tcr = __raw_readl(t->base + TCR);
 
 	/* disable timer */
 	tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
-	davinci_writel(tcr, t->reg_base + TCR);
+	__raw_writel(tcr, t->base + TCR);
 
 	/* reset counter to zero, set new period */
-	davinci_writel(0, t->tim_reg);
-	davinci_writel(t->period, t->prd_reg);
+	__raw_writel(0, t->base + t->tim_off);
+	__raw_writel(t->period, t->base + t->prd_off);
 
 	/* Set enable mode */
 	if (t->opts & TIMER_OPTS_ONESHOT) {
@@ -131,13 +137,13 @@ static int timer32_config(struct timer_s
 		tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
 	}
 
-	davinci_writel(tcr, t->reg_base + TCR);
+	__raw_writel(tcr, t->base + TCR);
 	return 0;
 }
 
 static inline u32 timer32_read(struct timer_s *t)
 {
-	return davinci_readl(t->tim_reg);
+	return __raw_readl(t->base + t->tim_off);
 }
 
 static irqreturn_t timer_interrupt(int irq, void *dev_id)
@@ -176,51 +182,54 @@ static struct timer_s timers[] = {
 
 static void __init timer_init(void)
 {
-	u32 bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
+	u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
 	int i;
 
 	/* Global init of each 64-bit timer as a whole */
 	for(i=0; i<2; i++) {
-		u32 tgcr, base = bases[i];
+		u32 tgcr;
+		void __iomem *base = IO_ADDRESS(phys_bases[i]);
 
 		/* Disabled, Internal clock source */
-		davinci_writel(0, base + TCR);
+		__raw_writel(0, base + TCR);
 
 		/* reset both timers, no pre-scaler for timer34 */
 		tgcr = 0;
-		davinci_writel(tgcr, base + TGCR);
+		__raw_writel(tgcr, base + TGCR);
 
 		/* Set both timers to unchained 32-bit */
 		tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
-		davinci_writel(tgcr, base + TGCR);
+		__raw_writel(tgcr, base + TGCR);
 
 		/* Unreset timers */
 		tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
 			(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-		davinci_writel(tgcr, base + TGCR);
+		__raw_writel(tgcr, base + TGCR);
 
 		/* Init both counters to zero */
-		davinci_writel(0, base + TIM12);
-		davinci_writel(0, base + TIM34);
+		__raw_writel(0, base + TIM12);
+		__raw_writel(0, base + TIM34);
 	}
 
 	/* Init of each timer as a 32-bit timer */
 	for (i=0; i< ARRAY_SIZE(timers); i++) {
 		struct timer_s *t = &timers[i];
+		u32 phys_base;
 
 		if (t->name) {
 			t->id = i;
-			t->reg_base = (IS_TIMER1(t->id) ?
+			phys_base = (IS_TIMER1(t->id) ?
 			       DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE);
+			t->base = IO_ADDRESS(phys_base);
 
 			if (IS_TIMER_BOT(t->id)) {
 				t->enamode_shift = 6;
-				t->tim_reg = t->reg_base + TIM12;
-				t->prd_reg = t->reg_base + PRD12;
+				t->tim_off = TIM12;
+				t->prd_off = PRD12;
 			} else {
 				t->enamode_shift = 22;
-				t->tim_reg = t->reg_base + TIM34;
-				t->prd_reg = t->reg_base + PRD34;
+				t->tim_off = TIM34;
+				t->prd_off = PRD34;
 			}
 
 			/* Register interrupt */
@@ -238,7 +247,7 @@ static void __init timer_init(void)
 /*
  * clocksource
  */
-static cycle_t read_cycles(void)
+static cycle_t read_cycles(struct clocksource *cs)
 {
 	struct timer_s *t = &timers[TID_CLOCKSOURCE];
 
@@ -274,7 +283,7 @@ static void davinci_set_mode(enum clock_
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		t->period = CLOCK_TICK_RATE / (HZ);
+		t->period = davinci_clock_tick_rate / (HZ);
 		t->opts = TIMER_OPTS_PERIODIC;
 		timer32_config(t);
 		break;
@@ -301,21 +310,29 @@ static struct clock_event_device clockev
 
 static void __init davinci_timer_init(void)
 {
+	struct clk *timer_clk;
+
 	static char err[] __initdata = KERN_ERR
 		"%s: can't register clocksource!\n";
 
 	/* init timer hw */
 	timer_init();
 
+	timer_clk = clk_get(NULL, "timer0");
+	BUG_ON(IS_ERR(timer_clk));
+	clk_enable(timer_clk);
+
+	davinci_clock_tick_rate = clk_get_rate(timer_clk);
+
 	/* setup clocksource */
 	clocksource_davinci.mult =
-		clocksource_khz2mult(CLOCK_TICK_RATE/1000,
+		clocksource_khz2mult(davinci_clock_tick_rate/1000,
 				     clocksource_davinci.shift);
 	if (clocksource_register(&clocksource_davinci))
 		printk(err, clocksource_davinci.name);
 
 	/* setup clockevent */
-	clockevent_davinci.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+	clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
 					 clockevent_davinci.shift);
 	clockevent_davinci.max_delta_ns =
 		clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
@@ -333,42 +350,52 @@ struct sys_timer davinci_timer = {
 
 /* reset board using watchdog timer */
 void davinci_watchdog_reset(void) {
-	u32 tgcr, wdtcr, base = DAVINCI_WDOG_BASE;
+	u32 tgcr, wdtcr;
+	void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE);
+	struct device dev;
+	struct clk *wd_clk;
+	char *name = "watchdog";
+
+	dev_set_name(&dev, name);
+	wd_clk = clk_get(&dev, NULL);
+	if (WARN_ON(IS_ERR(wd_clk)))
+		return;
+	clk_enable(wd_clk);
 
 	/* disable, internal clock source */
-	davinci_writel(0, base + TCR);
+	__raw_writel(0, base + TCR);
 
 	/* reset timer, set mode to 64-bit watchdog, and unreset */
 	tgcr = 0;
-	davinci_writel(tgcr, base + TCR);
+	__raw_writel(tgcr, base + TCR);
 	tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
 	tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
 		(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-	davinci_writel(tgcr, base + TCR);
+	__raw_writel(tgcr, base + TCR);
 
 	/* clear counter and period regs */
-	davinci_writel(0, base + TIM12);
-	davinci_writel(0, base + TIM34);
-	davinci_writel(0, base + PRD12);
-	davinci_writel(0, base + PRD34);
+	__raw_writel(0, base + TIM12);
+	__raw_writel(0, base + TIM34);
+	__raw_writel(0, base + PRD12);
+	__raw_writel(0, base + PRD34);
 
 	/* enable */
-	wdtcr = davinci_readl(base + WDTCR);
+	wdtcr = __raw_readl(base + WDTCR);
 	wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT;
-	davinci_writel(wdtcr, base + WDTCR);
+	__raw_writel(wdtcr, base + WDTCR);
 
 	/* put watchdog in pre-active state */
 	wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
 		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
-	davinci_writel(wdtcr, base + WDTCR);
+	__raw_writel(wdtcr, base + WDTCR);
 
 	/* put watchdog in active state */
 	wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
 		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
-	davinci_writel(wdtcr, base + WDTCR);
+	__raw_writel(wdtcr, base + WDTCR);
 
 	/* write an invalid value to the WDKEY field to trigger
 	 * a watchdog reset */
 	wdtcr = 0x00004000;
-	davinci_writel(wdtcr, base + WDTCR);
+	__raw_writel(wdtcr, base + WDTCR);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/usb.c linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/usb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-davinci/usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-davinci/usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,8 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+#define DAVINCI_USB_OTG_BASE 0x01C64000
+
 #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
 static struct musb_hdrc_eps_bits musb_eps[] = {
 	{ "ep1_tx", 8, },
@@ -64,7 +66,7 @@ static struct resource usb_resources[] =
 	},
 };
 
-static u64 usb_dmamask = DMA_32BIT_MASK;
+static u64 usb_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device usb_dev = {
 	.name           = "musb_hdrc",
@@ -72,7 +74,7 @@ static struct platform_device usb_dev =
 	.dev = {
 		.platform_data		= &usb_data,
 		.dma_mask		= &usb_dmamask,
-		.coherent_dma_mask      = DMA_32BIT_MASK,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
 	},
 	.resource       = usb_resources,
 	.num_resources  = ARRAY_SIZE(usb_resources),
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ebsa110/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ebsa110/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ebsa110/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ebsa110/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,6 @@ static inline void arch_idle(void)
 	asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
 }
 
-#define arch_reset(mode)	cpu_reset(0x80000000)
+#define arch_reset(mode, cmd)	cpu_reset(0x80000000)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,15 +21,50 @@
 #include <asm/div64.h>
 #include <mach/hardware.h>
 
+
+/*
+ * The EP93xx has two external crystal oscillators.  To generate the
+ * required high-frequency clocks, the processor uses two phase-locked-
+ * loops (PLLs) to multiply the incoming external clock signal to much
+ * higher frequencies that are then divided down by programmable dividers
+ * to produce the needed clocks.  The PLLs operate independently of one
+ * another.
+ */
+#define EP93XX_EXT_CLK_RATE	14745600
+#define EP93XX_EXT_RTC_RATE	32768
+
+
 struct clk {
 	unsigned long	rate;
 	int		users;
+	int		sw_locked;
 	u32		enable_reg;
 	u32		enable_mask;
+
+	unsigned long	(*get_rate)(struct clk *clk);
 };
 
-static struct clk clk_uart = {
-	.rate		= 14745600,
+
+static unsigned long get_uart_rate(struct clk *clk);
+
+
+static struct clk clk_uart1 = {
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
+	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U1EN,
+	.get_rate	= get_uart_rate,
+};
+static struct clk clk_uart2 = {
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
+	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U2EN,
+	.get_rate	= get_uart_rate,
+};
+static struct clk clk_uart3 = {
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
+	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U3EN,
+	.get_rate	= get_uart_rate,
 };
 static struct clk clk_pll1;
 static struct clk clk_f;
@@ -41,19 +76,81 @@ static struct clk clk_usb_host = {
 	.enable_mask	= EP93XX_SYSCON_CLOCK_USH_EN,
 };
 
+/* DMA Clocks */
+static struct clk clk_m2p0 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00020000,
+};
+static struct clk clk_m2p1 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00010000,
+};
+static struct clk clk_m2p2 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00080000,
+};
+static struct clk clk_m2p3 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00040000,
+};
+static struct clk clk_m2p4 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00200000,
+};
+static struct clk clk_m2p5 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00100000,
+};
+static struct clk clk_m2p6 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00800000,
+};
+static struct clk clk_m2p7 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x00400000,
+};
+static struct clk clk_m2p8 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x02000000,
+};
+static struct clk clk_m2p9 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x01000000,
+};
+static struct clk clk_m2m0 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x04000000,
+};
+static struct clk clk_m2m1 = {
+	.enable_reg	= EP93XX_SYSCON_CLOCK_CONTROL,
+	.enable_mask	= 0x08000000,
+};
+
 #define INIT_CK(dev,con,ck)					\
 	{ .dev_id = dev, .con_id = con, .clk = ck }
 
 static struct clk_lookup clocks[] = {
-	INIT_CK("apb:uart1", NULL, &clk_uart),
-	INIT_CK("apb:uart2", NULL, &clk_uart),
-	INIT_CK("apb:uart3", NULL, &clk_uart),
+	INIT_CK("apb:uart1", NULL, &clk_uart1),
+	INIT_CK("apb:uart2", NULL, &clk_uart2),
+	INIT_CK("apb:uart3", NULL, &clk_uart3),
 	INIT_CK(NULL, "pll1", &clk_pll1),
 	INIT_CK(NULL, "fclk", &clk_f),
 	INIT_CK(NULL, "hclk", &clk_h),
 	INIT_CK(NULL, "pclk", &clk_p),
 	INIT_CK(NULL, "pll2", &clk_pll2),
 	INIT_CK(NULL, "usb_host", &clk_usb_host),
+	INIT_CK(NULL, "m2p0", &clk_m2p0),
+	INIT_CK(NULL, "m2p1", &clk_m2p1),
+	INIT_CK(NULL, "m2p2", &clk_m2p2),
+	INIT_CK(NULL, "m2p3", &clk_m2p3),
+	INIT_CK(NULL, "m2p4", &clk_m2p4),
+	INIT_CK(NULL, "m2p5", &clk_m2p5),
+	INIT_CK(NULL, "m2p6", &clk_m2p6),
+	INIT_CK(NULL, "m2p7", &clk_m2p7),
+	INIT_CK(NULL, "m2p8", &clk_m2p8),
+	INIT_CK(NULL, "m2p9", &clk_m2p9),
+	INIT_CK(NULL, "m2m0", &clk_m2m0),
+	INIT_CK(NULL, "m2m1", &clk_m2m1),
 };
 
 
@@ -63,6 +160,8 @@ int clk_enable(struct clk *clk)
 		u32 value;
 
 		value = __raw_readl(clk->enable_reg);
+		if (clk->sw_locked)
+			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
 		__raw_writel(value | clk->enable_mask, clk->enable_reg);
 	}
 
@@ -76,13 +175,29 @@ void clk_disable(struct clk *clk)
 		u32 value;
 
 		value = __raw_readl(clk->enable_reg);
+		if (clk->sw_locked)
+			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
 		__raw_writel(value & ~clk->enable_mask, clk->enable_reg);
 	}
 }
 EXPORT_SYMBOL(clk_disable);
 
+static unsigned long get_uart_rate(struct clk *clk)
+{
+	u32 value;
+
+	value = __raw_readl(EP93XX_SYSCON_CLOCK_CONTROL);
+	if (value & EP93XX_SYSCON_CLOCK_UARTBAUD)
+		return EP93XX_EXT_CLK_RATE;
+	else
+		return EP93XX_EXT_CLK_RATE / 2;
+}
+
 unsigned long clk_get_rate(struct clk *clk)
 {
+	if (clk->get_rate)
+		return clk->get_rate(clk);
+
 	return clk->rate;
 }
 EXPORT_SYMBOL(clk_get_rate);
@@ -100,7 +215,7 @@ static unsigned long calc_pll_rate(u32 c
 	unsigned long long rate;
 	int i;
 
-	rate = 14745600;
+	rate = EP93XX_EXT_CLK_RATE;
 	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
 	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
 	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
@@ -110,6 +225,22 @@ static unsigned long calc_pll_rate(u32 c
 	return (unsigned long)rate;
 }
 
+static void __init ep93xx_dma_clock_init(void)
+{
+	clk_m2p0.rate = clk_h.rate;
+	clk_m2p1.rate = clk_h.rate;
+	clk_m2p2.rate = clk_h.rate;
+	clk_m2p3.rate = clk_h.rate;
+	clk_m2p4.rate = clk_h.rate;
+	clk_m2p5.rate = clk_h.rate;
+	clk_m2p6.rate = clk_h.rate;
+	clk_m2p7.rate = clk_h.rate;
+	clk_m2p8.rate = clk_h.rate;
+	clk_m2p9.rate = clk_h.rate;
+	clk_m2m0.rate = clk_h.rate;
+	clk_m2m1.rate = clk_h.rate;
+}
+
 static int __init ep93xx_clock_init(void)
 {
 	u32 value;
@@ -117,17 +248,18 @@ static int __init ep93xx_clock_init(void
 
 	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
 	if (!(value & 0x00800000)) {			/* PLL1 bypassed?  */
-		clk_pll1.rate = 14745600;
+		clk_pll1.rate = EP93XX_EXT_CLK_RATE;
 	} else {
 		clk_pll1.rate = calc_pll_rate(value);
 	}
 	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
 	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
 	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+	ep93xx_dma_clock_init();
 
 	value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
 	if (!(value & 0x00080000)) {			/* PLL2 bypassed?  */
-		clk_pll2.rate = 14745600;
+		clk_pll2.rate = EP93XX_EXT_CLK_RATE;
 	} else if (value & 0x00040000) {		/* PLL2 enabled?  */
 		clk_pll2.rate = calc_pll_rate(value);
 	} else {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/core.c linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/core.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,7 +100,7 @@ static unsigned int last_jiffy_time;
 
 #define TIMER4_TICKS_PER_JIFFY		((CLOCK_TICK_RATE + (HZ/2)) / HZ)
 
-static int ep93xx_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
 {
 	__raw_writel(1, EP93XX_TIMER1_CLEAR);
 	while ((signed long)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/dma-m2p.c linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/dma-m2p.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/dma-m2p.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/dma-m2p.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,408 @@
+/*
+ * arch/arm/mach-ep93xx/dma-m2p.c
+ * M2P DMA handling for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2006 Applied Data Systems
+ *
+ * Copyright (C) 2009 Ryan Mallon <ryan@bluewatersys.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.
+ */
+
+/*
+ * On the EP93xx chip the following peripherals my be allocated to the 10
+ * Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive).
+ *
+ *	I2S	contains 3 Tx and 3 Rx DMA Channels
+ *	AAC	contains 3 Tx and 3 Rx DMA Channels
+ *	UART1	contains 1 Tx and 1 Rx DMA Channels
+ *	UART2	contains 1 Tx and 1 Rx DMA Channels
+ *	UART3	contains 1 Tx and 1 Rx DMA Channels
+ *	IrDA	contains 1 Tx and 1 Rx DMA Channels
+ *
+ * SSP and IDE use the Memory to Memory (M2M) channels and are not covered
+ * with this implementation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <mach/dma.h>
+#include <mach/hardware.h>
+
+#define M2P_CONTROL			0x00
+#define  M2P_CONTROL_STALL_IRQ_EN	(1 << 0)
+#define  M2P_CONTROL_NFB_IRQ_EN		(1 << 1)
+#define  M2P_CONTROL_ERROR_IRQ_EN	(1 << 3)
+#define  M2P_CONTROL_ENABLE		(1 << 4)
+#define M2P_INTERRUPT			0x04
+#define  M2P_INTERRUPT_STALL		(1 << 0)
+#define  M2P_INTERRUPT_NFB		(1 << 1)
+#define  M2P_INTERRUPT_ERROR		(1 << 3)
+#define M2P_PPALLOC			0x08
+#define M2P_STATUS			0x0c
+#define M2P_REMAIN			0x14
+#define M2P_MAXCNT0			0x20
+#define M2P_BASE0			0x24
+#define M2P_MAXCNT1			0x30
+#define M2P_BASE1			0x34
+
+#define STATE_IDLE	0	/* Channel is inactive.  */
+#define STATE_STALL	1	/* Channel is active, no buffers pending.  */
+#define STATE_ON	2	/* Channel is active, one buffer pending.  */
+#define STATE_NEXT	3	/* Channel is active, two buffers pending.  */
+
+struct m2p_channel {
+	char				*name;
+	void __iomem			*base;
+	int				irq;
+
+	struct clk			*clk;
+	spinlock_t			lock;
+
+	void				*client;
+	unsigned			next_slot:1;
+	struct ep93xx_dma_buffer	*buffer_xfer;
+	struct ep93xx_dma_buffer	*buffer_next;
+	struct list_head		buffers_pending;
+};
+
+static struct m2p_channel m2p_rx[] = {
+	{"m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1},
+	{"m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3},
+	{"m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5},
+	{"m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7},
+	{"m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9},
+	{NULL},
+};
+
+static struct m2p_channel m2p_tx[] = {
+	{"m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0},
+	{"m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2},
+	{"m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4},
+	{"m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6},
+	{"m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8},
+	{NULL},
+};
+
+static void feed_buf(struct m2p_channel *ch, struct ep93xx_dma_buffer *buf)
+{
+	if (ch->next_slot == 0) {
+		writel(buf->size, ch->base + M2P_MAXCNT0);
+		writel(buf->bus_addr, ch->base + M2P_BASE0);
+	} else {
+		writel(buf->size, ch->base + M2P_MAXCNT1);
+		writel(buf->bus_addr, ch->base + M2P_BASE1);
+	}
+	ch->next_slot ^= 1;
+}
+
+static void choose_buffer_xfer(struct m2p_channel *ch)
+{
+	struct ep93xx_dma_buffer *buf;
+
+	ch->buffer_xfer = NULL;
+	if (!list_empty(&ch->buffers_pending)) {
+		buf = list_entry(ch->buffers_pending.next,
+				 struct ep93xx_dma_buffer, list);
+		list_del(&buf->list);
+		feed_buf(ch, buf);
+		ch->buffer_xfer = buf;
+	}
+}
+
+static void choose_buffer_next(struct m2p_channel *ch)
+{
+	struct ep93xx_dma_buffer *buf;
+
+	ch->buffer_next = NULL;
+	if (!list_empty(&ch->buffers_pending)) {
+		buf = list_entry(ch->buffers_pending.next,
+				 struct ep93xx_dma_buffer, list);
+		list_del(&buf->list);
+		feed_buf(ch, buf);
+		ch->buffer_next = buf;
+	}
+}
+
+static inline void m2p_set_control(struct m2p_channel *ch, u32 v)
+{
+	/*
+	 * The control register must be read immediately after being written so
+	 * that the internal state machine is correctly updated. See the ep93xx
+	 * users' guide for details.
+	 */
+	writel(v, ch->base + M2P_CONTROL);
+	readl(ch->base + M2P_CONTROL);
+}
+
+static inline int m2p_channel_state(struct m2p_channel *ch)
+{
+	return (readl(ch->base + M2P_STATUS) >> 4) & 0x3;
+}
+
+static irqreturn_t m2p_irq(int irq, void *dev_id)
+{
+	struct m2p_channel *ch = dev_id;
+	struct ep93xx_dma_m2p_client *cl;
+	u32 irq_status, v;
+	int error = 0;
+
+	cl = ch->client;
+
+	spin_lock(&ch->lock);
+	irq_status = readl(ch->base + M2P_INTERRUPT);
+
+	if (irq_status & M2P_INTERRUPT_ERROR) {
+		writel(M2P_INTERRUPT_ERROR, ch->base + M2P_INTERRUPT);
+		error = 1;
+	}
+
+	if ((irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) == 0) {
+		spin_unlock(&ch->lock);
+		return IRQ_NONE;
+	}
+
+	switch (m2p_channel_state(ch)) {
+	case STATE_IDLE:
+		pr_crit("m2p_irq: dma interrupt without a dma buffer\n");
+		BUG();
+		break;
+
+	case STATE_STALL:
+		cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+		if (ch->buffer_next != NULL) {
+			cl->buffer_finished(cl->cookie, ch->buffer_next,
+					    0, error);
+		}
+		choose_buffer_xfer(ch);
+		choose_buffer_next(ch);
+		if (ch->buffer_xfer != NULL)
+			cl->buffer_started(cl->cookie, ch->buffer_xfer);
+		break;
+
+	case STATE_ON:
+		cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+		ch->buffer_xfer = ch->buffer_next;
+		choose_buffer_next(ch);
+		cl->buffer_started(cl->cookie, ch->buffer_xfer);
+		break;
+
+	case STATE_NEXT:
+		pr_crit("m2p_irq: dma interrupt while next\n");
+		BUG();
+		break;
+	}
+
+	v = readl(ch->base + M2P_CONTROL) & ~(M2P_CONTROL_STALL_IRQ_EN |
+					      M2P_CONTROL_NFB_IRQ_EN);
+	if (ch->buffer_xfer != NULL)
+		v |= M2P_CONTROL_STALL_IRQ_EN;
+	if (ch->buffer_next != NULL)
+		v |= M2P_CONTROL_NFB_IRQ_EN;
+	m2p_set_control(ch, v);
+
+	spin_unlock(&ch->lock);
+	return IRQ_HANDLED;
+}
+
+static struct m2p_channel *find_free_channel(struct ep93xx_dma_m2p_client *cl)
+{
+	struct m2p_channel *ch;
+	int i;
+
+	if (cl->flags & EP93XX_DMA_M2P_RX)
+		ch = m2p_rx;
+	else
+		ch = m2p_tx;
+
+	for (i = 0; ch[i].base; i++) {
+		struct ep93xx_dma_m2p_client *client;
+
+		client = ch[i].client;
+		if (client != NULL) {
+			int port;
+
+			port = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+			if (port == (client->flags &
+				     EP93XX_DMA_M2P_PORT_MASK)) {
+				pr_warning("DMA channel already used by %s\n",
+					   cl->name ? : "unknown client");
+				return ERR_PTR(-EBUSY);
+			}
+		}
+	}
+
+	for (i = 0; ch[i].base; i++) {
+		if (ch[i].client == NULL)
+			return ch + i;
+	}
+
+	pr_warning("No free DMA channel for %s\n",
+		   cl->name ? : "unknown client");
+	return ERR_PTR(-ENODEV);
+}
+
+static void channel_enable(struct m2p_channel *ch)
+{
+	struct ep93xx_dma_m2p_client *cl = ch->client;
+	u32 v;
+
+	clk_enable(ch->clk);
+
+	v = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+	writel(v, ch->base + M2P_PPALLOC);
+
+	v = cl->flags & EP93XX_DMA_M2P_ERROR_MASK;
+	v |= M2P_CONTROL_ENABLE | M2P_CONTROL_ERROR_IRQ_EN;
+	m2p_set_control(ch, v);
+}
+
+static void channel_disable(struct m2p_channel *ch)
+{
+	u32 v;
+
+	v = readl(ch->base + M2P_CONTROL);
+	v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN);
+	m2p_set_control(ch, v);
+
+	while (m2p_channel_state(ch) == STATE_ON)
+		cpu_relax();
+
+	m2p_set_control(ch, 0x0);
+
+	while (m2p_channel_state(ch) == STATE_STALL)
+		cpu_relax();
+
+	clk_disable(ch->clk);
+}
+
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *cl)
+{
+	struct m2p_channel *ch;
+	int err;
+
+	ch = find_free_channel(cl);
+	if (IS_ERR(ch))
+		return PTR_ERR(ch);
+
+	err = request_irq(ch->irq, m2p_irq, 0, cl->name ? : "dma-m2p", ch);
+	if (err)
+		return err;
+
+	ch->client = cl;
+	ch->next_slot = 0;
+	ch->buffer_xfer = NULL;
+	ch->buffer_next = NULL;
+	INIT_LIST_HEAD(&ch->buffers_pending);
+
+	cl->channel = ch;
+
+	channel_enable(ch);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_register);
+
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *cl)
+{
+	struct m2p_channel *ch = cl->channel;
+
+	channel_disable(ch);
+	free_irq(ch->irq, ch);
+	ch->client = NULL;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_unregister);
+
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *cl,
+			   struct ep93xx_dma_buffer *buf)
+{
+	struct m2p_channel *ch = cl->channel;
+	unsigned long flags;
+	u32 v;
+
+	spin_lock_irqsave(&ch->lock, flags);
+	v = readl(ch->base + M2P_CONTROL);
+	if (ch->buffer_xfer == NULL) {
+		ch->buffer_xfer = buf;
+		feed_buf(ch, buf);
+		cl->buffer_started(cl->cookie, buf);
+
+		v |= M2P_CONTROL_STALL_IRQ_EN;
+		m2p_set_control(ch, v);
+
+	} else if (ch->buffer_next == NULL) {
+		ch->buffer_next = buf;
+		feed_buf(ch, buf);
+
+		v |= M2P_CONTROL_NFB_IRQ_EN;
+		m2p_set_control(ch, v);
+	} else {
+		list_add_tail(&buf->list, &ch->buffers_pending);
+	}
+	spin_unlock_irqrestore(&ch->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit);
+
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *cl,
+				     struct ep93xx_dma_buffer *buf)
+{
+	struct m2p_channel *ch = cl->channel;
+
+	list_add_tail(&buf->list, &ch->buffers_pending);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit_recursive);
+
+void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *cl)
+{
+	struct m2p_channel *ch = cl->channel;
+
+	channel_disable(ch);
+	ch->next_slot = 0;
+	ch->buffer_xfer = NULL;
+	ch->buffer_next = NULL;
+	INIT_LIST_HEAD(&ch->buffers_pending);
+	channel_enable(ch);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_flush);
+
+static int init_channel(struct m2p_channel *ch)
+{
+	ch->clk = clk_get(NULL, ch->name);
+	if (IS_ERR(ch->clk))
+		return PTR_ERR(ch->clk);
+
+	spin_lock_init(&ch->lock);
+	ch->client = NULL;
+
+	return 0;
+}
+
+static int __init ep93xx_dma_m2p_init(void)
+{
+	int i;
+	int ret;
+
+	for (i = 0; m2p_rx[i].base; i++) {
+		ret = init_channel(m2p_rx + i);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; m2p_tx[i].base; i++) {
+		ret = init_channel(m2p_tx + i);
+		if (ret)
+			return ret;
+	}
+
+	pr_info("M2P DMA subsystem initialized\n");
+	return 0;
+}
+arch_initcall(ep93xx_dma_m2p_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/edb9307a.c linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/edb9307a.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/edb9307a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/edb9307a.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,12 +48,24 @@ static struct ep93xx_eth_data edb9307a_e
 	.phy_id		= 1,
 };
 
+static struct i2c_board_info __initdata edb9307a_i2c_data[] = {
+	{
+		/* On-board battery backed RTC */
+		I2C_BOARD_INFO("isl1208", 0x6f),
+	},
+	/*
+	 * The I2C signals are also routed to the Expansion Connector (J4)
+	 */
+};
+
 static void __init edb9307a_init_machine(void)
 {
 	ep93xx_init_devices();
 	platform_device_register(&edb9307a_flash);
 
 	ep93xx_register_eth(&edb9307a_eth_data, 1);
+
+	ep93xx_init_i2c(edb9307a_i2c_data, ARRAY_SIZE(edb9307a_i2c_data));
 }
 
 MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct ep93xx_dma_buffer {
+	struct list_head	list;
+	u32			bus_addr;
+	u16			size;
+};
+
+struct ep93xx_dma_m2p_client {
+	char			*name;
+	u8			flags;
+	void			*cookie;
+	void			(*buffer_started)(void *cookie,
+					struct ep93xx_dma_buffer *buf);
+	void			(*buffer_finished)(void *cookie,
+					struct ep93xx_dma_buffer *buf,
+					int bytes, int error);
+
+	/* Internal to the DMA code.  */
+	void			*channel;
+};
+
+#define EP93XX_DMA_M2P_PORT_I2S1	0x00
+#define EP93XX_DMA_M2P_PORT_I2S2	0x01
+#define EP93XX_DMA_M2P_PORT_AAC1	0x02
+#define EP93XX_DMA_M2P_PORT_AAC2	0x03
+#define EP93XX_DMA_M2P_PORT_AAC3	0x04
+#define EP93XX_DMA_M2P_PORT_I2S3	0x05
+#define EP93XX_DMA_M2P_PORT_UART1	0x06
+#define EP93XX_DMA_M2P_PORT_UART2	0x07
+#define EP93XX_DMA_M2P_PORT_UART3	0x08
+#define EP93XX_DMA_M2P_PORT_IRDA	0x09
+#define EP93XX_DMA_M2P_PORT_MASK	0x0f
+#define EP93XX_DMA_M2P_TX		0x00
+#define EP93XX_DMA_M2P_RX		0x10
+#define EP93XX_DMA_M2P_ABORT_ON_ERROR	0x20
+#define EP93XX_DMA_M2P_IGNORE_ERROR	0x40
+#define EP93XX_DMA_M2P_ERROR_MASK	0x60
+
+int  ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
+			   struct ep93xx_dma_buffer *buf);
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
+				     struct ep93xx_dma_buffer *buf);
+void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p);
+
+#endif /* __ASM_ARCH_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,7 +58,8 @@
 
 
 /* AHB peripherals */
-#define EP93XX_DMA_BASE			(EP93XX_AHB_VIRT_BASE + 0x00000000)
+#define EP93XX_DMA_BASE			((void __iomem *)		\
+					 (EP93XX_AHB_VIRT_BASE + 0x00000000))
 
 #define EP93XX_ETHERNET_BASE		(EP93XX_AHB_VIRT_BASE + 0x00010000)
 #define EP93XX_ETHERNET_PHYS_BASE	(EP93XX_AHB_PHYS_BASE + 0x00010000)
@@ -158,7 +159,10 @@
 #define EP93XX_SYSCON_CLOCK_SET1	EP93XX_SYSCON_REG(0x20)
 #define EP93XX_SYSCON_CLOCK_SET2	EP93XX_SYSCON_REG(0x24)
 #define EP93XX_SYSCON_DEVICE_CONFIG	EP93XX_SYSCON_REG(0x80)
-#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE	0x00800000
+#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN		(1<<24)
+#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE	(1<<23)
+#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN		(1<<20)
+#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN		(1<<18)
 #define EP93XX_SYSCON_SWLOCK		EP93XX_SYSCON_REG(0xc0)
 
 #define EP93XX_WATCHDOG_BASE		(EP93XX_APB_VIRT_BASE + 0x00140000)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	u32 devicecfg;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ep93xx/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ep93xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Makefile for the linux kernel.
 #
-obj-y			:= core.o clock.o gpio.o
+obj-y			:= core.o clock.o dma-m2p.o gpio.o
 obj-m			:=
 obj-n			:=
 obj-			:=
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-footbridge/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-footbridge/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-footbridge/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-footbridge/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,16 +21,16 @@
 #include <asm/hardware/dec21285.h>
 
 #if 0
-static int fb_dma_request(dmach_t channel, dma_t *dma)
+static int fb_dma_request(unsigned int chan, dma_t *dma)
 {
 	return -EINVAL;
 }
 
-static void fb_dma_enable(dmach_t channel, dma_t *dma)
+static void fb_dma_enable(unsigned int chan, dma_t *dma)
 {
 }
 
-static void fb_dma_disable(dmach_t channel, dma_t *dma)
+static void fb_dma_disable(unsigned int chan, dma_t *dma)
 {
 }
 
@@ -42,7 +42,7 @@ static struct dma_ops fb_dma_ops = {
 };
 #endif
 
-void __init arch_dma_init(dma_t *dma)
+static int __init fb_dma_init(void)
 {
 #if 0
 	dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
@@ -50,6 +50,8 @@ void __init arch_dma_init(dma_t *dma)
 #endif
 #ifdef CONFIG_ISA_DMA
 	if (footbridge_cfn_mode())
-		isa_init_dma(dma + _ISA_DMA(0));
+		isa_init_dma();
 #endif
+	return 0;
 }
+core_initcall(fb_dma_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-footbridge/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-footbridge/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-footbridge/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-footbridge/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	if (mode == 's') {
 		/*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/board-rut1xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/board-rut1xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/board-rut1xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/board-rut1xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ *  Support for Teltonika RUT1xx
+ *
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+static struct gpio_keys_button rut1xx_keys[] = {
+	{
+		.code		= KEY_SETUP,
+		.gpio		= 60,
+		.active_low	= 1,
+		.desc		= "Reset to defaults",
+		.type		= EV_KEY,
+	},
+};
+
+static struct gpio_keys_platform_data rut1xx_keys_data = {
+	.buttons	= rut1xx_keys,
+	.nbuttons	= ARRAY_SIZE(rut1xx_keys),
+};
+
+static struct platform_device rut1xx_keys_device = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &rut1xx_keys_data,
+	},
+};
+
+static struct gpio_led rut100_leds[] = {
+	{
+		.name			= "Power",
+		.default_trigger	= "heartbeat",
+		.gpio			= 17,
+	},
+	{
+		.name			= "GSM",
+		.default_trigger	= "default-on",
+		.gpio			= 7,
+		.active_low		= 1,
+	},
+};
+
+static struct gpio_led_platform_data rut100_leds_data = {
+	.num_leds	= ARRAY_SIZE(rut100_leds),
+	.leds		= rut100_leds,
+};
+
+static struct platform_device rut1xx_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &rut100_leds_data,
+	},
+};
+
+static struct sys_timer rut1xx_timer = {
+	.init	= gemini_timer_init,
+};
+
+static void __init rut1xx_init(void)
+{
+	gemini_gpio_init();
+	platform_register_uart();
+	platform_register_pflash(SZ_8M, NULL, 0);
+	platform_device_register(&rut1xx_leds);
+	platform_device_register(&rut1xx_keys_device);
+}
+
+MACHINE_START(RUT100, "Teltonika RUT100")
+	.phys_io	= 0x7fffc000,
+	.io_pg_offst	= ((0xffffc000) >> 18) & 0xfffc,
+	.boot_params	= 0x100,
+	.map_io		= gemini_map_io,
+	.init_irq	= gemini_init_irq,
+	.timer		= &rut1xx_timer,
+	.init_machine	= rut1xx_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/common.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * Common Gemini architecture functions
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __GEMINI_COMMON_H__
+#define __GEMINI_COMMON_H__
+
+struct mtd_partition;
+
+extern void gemini_map_io(void);
+extern void gemini_init_irq(void);
+extern void gemini_timer_init(void);
+extern void gemini_gpio_init(void);
+
+/* Common platform devices registration functions */
+extern int platform_register_uart(void);
+extern int platform_register_pflash(unsigned int size,
+				    struct mtd_partition *parts,
+				    unsigned int nr_parts);
+
+#endif /* __GEMINI_COMMON_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * Common devices definition for Gemini
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase	= (void *)IO_ADDRESS(GEMINI_UART_BASE),
+		.mapbase	= GEMINI_UART_BASE,
+		.irq		= IRQ_UART,
+		.uartclk	= UART_CLK,
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.type		= PORT_16550A,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE,
+	},
+	{},
+};
+
+static struct platform_device serial_device = {
+	.name	= "serial8250",
+	.id	= PLAT8250_DEV_PLATFORM,
+	.dev	= {
+		.platform_data = serial_platform_data,
+	},
+};
+
+int platform_register_uart(void)
+{
+	return platform_device_register(&serial_device);
+}
+
+static struct resource flash_resource = {
+	.start	= GEMINI_FLASH_BASE,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data pflash_platform_data = {};
+
+static struct platform_device pflash_device = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev 	= {
+		.platform_data = &pflash_platform_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+int platform_register_pflash(unsigned int size, struct mtd_partition *parts,
+			     unsigned int nr_parts)
+{
+	unsigned int reg;
+
+	reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS);
+
+	if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL)
+		return -ENXIO;
+
+	if (reg & FLASH_WIDTH_16BIT)
+		pflash_platform_data.width = 2;
+	else
+		pflash_platform_data.width = 1;
+
+	/* enable parallel flash pins and disable others */
+	reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+	reg &= ~PFLASH_PADS_DISABLE;
+	reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE;
+	__raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+
+	flash_resource.end = flash_resource.start + size - 1;
+
+	pflash_platform_data.parts = parts;
+	pflash_platform_data.nr_parts = nr_parts;
+
+	return platform_device_register(&pflash_device);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/gpio.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,232 @@
+/*
+ * Gemini gpiochip and interrupt routines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on plat-mxc/gpio.c:
+ *  MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ *  Copyright 2008 Juergen Beisert, 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 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/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#define GPIO_BASE(x)		IO_ADDRESS(GEMINI_GPIO_BASE(x))
+
+/* GPIO registers definition */
+#define GPIO_DATA_OUT		0x0
+#define GPIO_DATA_IN		0x4
+#define GPIO_DIR		0x8
+#define GPIO_DATA_SET		0x10
+#define GPIO_DATA_CLR		0x14
+#define GPIO_PULL_EN		0x18
+#define GPIO_PULL_TYPE		0x1C
+#define GPIO_INT_EN		0x20
+#define GPIO_INT_STAT		0x24
+#define GPIO_INT_MASK		0x2C
+#define GPIO_INT_CLR		0x30
+#define GPIO_INT_TYPE		0x34
+#define GPIO_INT_BOTH_EDGE	0x38
+#define GPIO_INT_LEVEL		0x3C
+#define GPIO_DEBOUNCE_EN	0x40
+#define GPIO_DEBOUNCE_PRESCALE	0x44
+
+#define GPIO_PORT_NUM		3
+
+static void _set_gpio_irqenable(unsigned int base, unsigned int index,
+				int enable)
+{
+	unsigned int reg;
+
+	reg = __raw_readl(base + GPIO_INT_EN);
+	reg = (reg & (~(1 << index))) | (!!enable << index);
+	__raw_writel(reg, base + GPIO_INT_EN);
+}
+
+static void gpio_ack_irq(unsigned int irq)
+{
+	unsigned int gpio = irq_to_gpio(irq);
+	unsigned int base = GPIO_BASE(gpio / 32);
+
+	__raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
+}
+
+static void gpio_mask_irq(unsigned int irq)
+{
+	unsigned int gpio = irq_to_gpio(irq);
+	unsigned int base = GPIO_BASE(gpio / 32);
+
+	_set_gpio_irqenable(base, gpio % 32, 0);
+}
+
+static void gpio_unmask_irq(unsigned int irq)
+{
+	unsigned int gpio = irq_to_gpio(irq);
+	unsigned int base = GPIO_BASE(gpio / 32);
+
+	_set_gpio_irqenable(base, gpio % 32, 1);
+}
+
+static int gpio_set_irq_type(unsigned int irq, unsigned int type)
+{
+	unsigned int gpio = irq_to_gpio(irq);
+	unsigned int gpio_mask = 1 << (gpio % 32);
+	unsigned int base = GPIO_BASE(gpio / 32);
+	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_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_BOTH:
+		reg_type &= ~gpio_mask;
+		reg_both |= gpio_mask;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		reg_type &= ~gpio_mask;
+		reg_both &= ~gpio_mask;
+		reg_level &= ~gpio_mask;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		reg_type &= ~gpio_mask;
+		reg_both &= ~gpio_mask;
+		reg_level |= gpio_mask;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		reg_type |= gpio_mask;
+		reg_level &= ~gpio_mask;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		reg_type |= gpio_mask;
+		reg_level |= gpio_mask;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	__raw_writel(reg_type, base + GPIO_INT_TYPE);
+	__raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE);
+	__raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
+
+	gpio_ack_irq(irq);
+
+	return 0;
+}
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned int gpio_irq_no, irq_stat;
+	unsigned int port = (unsigned int)get_irq_data(irq);
+
+	irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT);
+
+	gpio_irq_no = GPIO_IRQ_BASE + port * 32;
+	for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
+
+		if ((irq_stat & 1) == 0)
+			continue;
+
+		BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
+		irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
+				&irq_desc[gpio_irq_no]);
+	}
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.name = "GPIO",
+	.ack = gpio_ack_irq,
+	.mask = gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+	.set_type = gpio_set_irq_type,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+				int dir)
+{
+	unsigned int base = GPIO_BASE(offset / 32);
+	unsigned int reg;
+
+	reg = __raw_readl(base + GPIO_DIR);
+	if (dir)
+		reg |= 1 << (offset % 32);
+	else
+		reg &= ~(1 << (offset % 32));
+	__raw_writel(reg, base + GPIO_DIR);
+}
+
+static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	unsigned int base = GPIO_BASE(offset / 32);
+
+	if (value)
+		__raw_writel(1 << (offset % 32), base + GPIO_DATA_SET);
+	else
+		__raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR);
+}
+
+static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	unsigned int base = GPIO_BASE(offset / 32);
+
+	return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1;
+}
+
+static int gemini_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	_set_gpio_direction(chip, offset, 0);
+	return 0;
+}
+
+static int gemini_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+					int value)
+{
+	_set_gpio_direction(chip, offset, 1);
+	gemini_gpio_set(chip, offset, value);
+	return 0;
+}
+
+static struct gpio_chip gemini_gpio_chip = {
+	.label			= "Gemini",
+	.direction_input	= gemini_gpio_direction_input,
+	.get			= gemini_gpio_get,
+	.direction_output	= gemini_gpio_direction_output,
+	.set			= gemini_gpio_set,
+	.base			= 0,
+	.ngpio			= GPIO_PORT_NUM * 32,
+};
+
+void __init gemini_gpio_init(void)
+{
+	int i, j;
+
+	for (i = 0; i < GPIO_PORT_NUM; i++) {
+		/* disable, unmask and clear all interrupts */
+		__raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN);
+		__raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK);
+		__raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR);
+
+		for (j = GPIO_IRQ_BASE + i * 32;
+		     j < GPIO_IRQ_BASE + (i + 1) * 32; j++) {
+			set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, handle_edge_irq);
+			set_irq_flags(j, IRQF_VALID);
+		}
+
+		set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
+		set_irq_data(IRQ_GPIO(i), (void *)i);
+	}
+
+	BUG_ON(gpiochip_add(&gemini_gpio_chip));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/debug-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can 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/hardware.h>
+
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1					@ MMU enabled?
+	ldreq	\rx, =GEMINI_UART_BASE			@ physical
+	ldrne	\rx, =IO_ADDRESS(GEMINI_UART_BASE)	@ virtual
+	.endm
+
+#define UART_SHIFT	2
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Low-level IRQ helper macros for Gemini platform.
+ *
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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>
+
+#define IRQ_STATUS	0x14
+
+	.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     \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS)
+	ldr     \irqnr, [\irqstat]
+	cmp     \irqnr, #0
+	beq     2313f
+	mov     \tmp, \irqnr
+	mov     \irqnr, #0
+2312:
+	tst     \tmp, #1
+	bne     2313f
+	add     \irqnr, \irqnr, #1
+	mov     \tmp, \tmp, lsr #1
+	cmp     \irqnr, #31
+	bcc     2312b
+2313:
+	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/global_reg.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/global_reg.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/global_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/global_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,278 @@
+/*
+ *  This file contains the hardware definitions for Gemini.
+ *
+ *  Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_GLOBAL_REG_H
+#define __MACH_GLOBAL_REG_H
+
+/* Global Word ID Register*/
+#define GLOBAL_ID			0x00
+
+#define CHIP_ID(reg)			((reg) >> 8)
+#define CHIP_REVISION(reg)		((reg) & 0xFF)
+
+/* Global Status Register */
+#define GLOBAL_STATUS			0x04
+
+#define CPU_BIG_ENDIAN			(1 << 31)
+#define PLL_OSC_30M			(1 << 30)	/* else 60MHz */
+
+#define OPERATION_MODE_MASK		(0xF << 26)
+#define OPM_IDDQ			(0xF << 26)
+#define OPM_NAND			(0xE << 26)
+#define OPM_RING			(0xD << 26)
+#define OPM_DIRECT_BOOT			(0xC << 26)
+#define OPM_USB1_PHY_TEST		(0xB << 26)
+#define OPM_USB0_PHY_TEST		(0xA << 26)
+#define OPM_SATA1_PHY_TEST		(0x9 << 26)
+#define OPM_SATA0_PHY_TEST		(0x8 << 26)
+#define OPM_ICE_ARM			(0x7 << 26)
+#define OPM_ICE_FARADAY			(0x6 << 26)
+#define OPM_PLL_BYPASS			(0x5 << 26)
+#define OPM_DEBUG			(0x4 << 26)
+#define OPM_BURN_IN			(0x3 << 26)
+#define OPM_MBIST			(0x2 << 26)
+#define OPM_SCAN			(0x1 << 26)
+#define OPM_REAL			(0x0 << 26)
+
+#define FLASH_TYPE_MASK			(0x3 << 24)
+#define FLASH_TYPE_NAND_2K		(0x3 << 24)
+#define FLASH_TYPE_NAND_512		(0x2 << 24)
+#define FLASH_TYPE_PARALLEL		(0x1 << 24)
+#define FLASH_TYPE_SERIAL		(0x0 << 24)
+/* if parallel */
+#define FLASH_WIDTH_16BIT		(1 << 23)	/* else 8 bit */
+/* if serial */
+#define FLASH_ATMEL			(1 << 23)	/* else STM */
+
+#define FLASH_SIZE_MASK			(0x3 << 21)
+#define NAND_256M			(0x3 << 21)	/* and more */
+#define NAND_128M			(0x2 << 21)
+#define NAND_64M			(0x1 << 21)
+#define NAND_32M			(0x0 << 21)
+#define ATMEL_16M			(0x3 << 21)	/* and more */
+#define ATMEL_8M			(0x2 << 21)
+#define ATMEL_4M_2M			(0x1 << 21)
+#define ATMEL_1M			(0x0 << 21)	/* and less */
+#define STM_32M				(1 << 22)	/* and more */
+#define STM_16M				(0 << 22)	/* and less */
+
+#define FLASH_PARALLEL_HIGH_PIN_CNT	(1 << 20)	/* else low pin cnt */
+
+#define CPU_AHB_RATIO_MASK		(0x3 << 18)
+#define CPU_AHB_1_1			(0x0 << 18)
+#define CPU_AHB_3_2			(0x1 << 18)
+#define CPU_AHB_24_13			(0x2 << 18)
+#define CPU_AHB_2_1			(0x3 << 18)
+
+#define REG_TO_AHB_SPEED(reg)		((((reg) >> 15) & 0x7) * 10 + 130)
+#define AHB_SPEED_TO_REG(x)		((((x - 130)) / 10) << 15)
+
+/* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */
+#define OVERRIDE_FLASH_TYPE_SHIFT	16
+#define OVERRIDE_FLASH_WIDTH_SHIFT	16
+#define OVERRIDE_FLASH_SIZE_SHIFT	16
+#define OVERRIDE_CPU_AHB_RATIO_SHIFT	15
+#define OVERRIDE_AHB_SPEED_SHIFT	15
+
+/* Global PLL Control Register */
+#define GLOBAL_PLL_CTRL			0x08
+
+#define PLL_BYPASS			(1 << 31)
+#define PLL_POWER_DOWN			(1 << 8)
+#define PLL_CONTROL_Q			(0x1F << 0)
+
+/* Global Soft Reset Control Register */
+#define GLOBAL_RESET			0x0C
+
+#define RESET_GLOBAL			(1 << 31)
+#define RESET_CPU1			(1 << 30)
+#define RESET_TVE			(1 << 28)
+#define RESET_SATA1			(1 << 27)
+#define RESET_SATA0			(1 << 26)
+#define RESET_CIR			(1 << 25)
+#define RESET_EXT_DEV			(1 << 24)
+#define RESET_WD			(1 << 23)
+#define RESET_GPIO2			(1 << 22)
+#define RESET_GPIO1			(1 << 21)
+#define RESET_GPIO0			(1 << 20)
+#define RESET_SSP			(1 << 19)
+#define RESET_UART			(1 << 18)
+#define RESET_TIMER			(1 << 17)
+#define RESET_RTC			(1 << 16)
+#define RESET_INT1			(1 << 15)
+#define RESET_INT0			(1 << 14)
+#define RESET_LCD			(1 << 13)
+#define RESET_LPC			(1 << 12)
+#define RESET_APB			(1 << 11)
+#define RESET_DMA			(1 << 10)
+#define RESET_USB1			(1 << 9)
+#define RESET_USB0			(1 << 8)
+#define RESET_PCI			(1 << 7)
+#define RESET_GMAC1			(1 << 6)
+#define RESET_GMAC0			(1 << 5)
+#define RESET_SECURITY			(1 << 4)
+#define RESET_RAID			(1 << 3)
+#define RESET_IDE			(1 << 2)
+#define RESET_FLASH			(1 << 1)
+#define RESET_DRAM			(1 << 0)
+
+/* Global IO Pad Driving Capability Control Register */
+#define GLOBAL_IO_DRIVING_CTRL		0x10
+
+#define DRIVING_CURRENT_MASK		0x3
+
+/* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */
+#define GPIO1_PADS_31_28_SHIFT		28
+#define GPIO0_PADS_31_16_SHIFT		26
+#define GPIO0_PADS_15_0_SHIFT		24
+#define PCI_AND_EXT_RESET_PADS_SHIFT	22
+#define IDE_PADS_SHIFT			20
+#define GMAC1_PADS_SHIFT		18
+#define GMAC0_PADS_SHIFT		16
+/* DRAM is not in mA and poorly documented */
+#define DRAM_CLOCK_PADS_SHIFT		8
+#define DRAM_DATA_PADS_SHIFT		4
+#define DRAM_CONTROL_PADS_SHIFT		0
+
+/* Global IO Pad Slew Rate Control Register */
+#define GLOBAL_IO_SLEW_RATE_CTRL	0x14
+
+#define GPIO1_PADS_31_28_SLOW		(1 << 10)
+#define GPIO0_PADS_31_16_SLOW		(1 << 9)
+#define GPIO0_PADS_15_0_SLOW		(1 << 8)
+#define PCI_PADS_SLOW			(1 << 7)
+#define IDE_PADS_SLOW			(1 << 6)
+#define GMAC1_PADS_SLOW			(1 << 5)
+#define GMAC0_PADS_SLOW			(1 << 4)
+#define DRAM_CLOCK_PADS_SLOW		(1 << 1)
+#define DRAM_IO_PADS_SLOW		(1 << 0)
+
+/*
+ * General skew control defines
+ * 16 steps, each step is around 0.2ns
+ */
+#define SKEW_MASK			0xF
+
+/* Global IDE PAD Skew Control Register */
+#define GLOBAL_IDE_SKEW_CTRL		0x18
+
+#define IDE1_HOST_STROBE_DELAY_SHIFT	28
+#define IDE1_DEVICE_STROBE_DELAY_SHIFT	24
+#define IDE1_OUTPUT_IO_SKEW_SHIFT	20
+#define IDE1_INPUT_IO_SKEW_SHIFT	16
+#define IDE0_HOST_STROBE_DELAY_SHIFT	12
+#define IDE0_DEVICE_STROBE_DELAY_SHIFT	8
+#define IDE0_OUTPUT_IO_SKEW_SHIFT	4
+#define IDE0_INPUT_IO_SKEW_SHIFT	0
+
+/* Global GMAC Control Pad Skew Control Register */
+#define GLOBAL_GMAC_CTRL_SKEW_CTRL	0x1C
+
+#define GMAC1_TXC_SKEW_SHIFT		28
+#define GMAC1_TXEN_SKEW_SHIFT		24
+#define GMAC1_RXC_SKEW_SHIFT		20
+#define GMAC1_RXDV_SKEW_SHIFT		16
+#define GMAC0_TXC_SKEW_SHIFT		12
+#define GMAC0_TXEN_SKEW_SHIFT		8
+#define GMAC0_RXC_SKEW_SHIFT		4
+#define GMAC0_RXDV_SKEW_SHIFT		0
+
+/* Global GMAC0 Data PAD Skew Control Register */
+#define GLOBAL_GMAC0_DATA_SKEW_CTRL	0x20
+/* Global GMAC1 Data PAD Skew Control Register */
+#define GLOBAL_GMAC1_DATA_SKEW_CTRL	0x24
+
+#define GMAC_TXD_SKEW_SHIFT(x)		(((x) * 4) + 16)
+#define GMAC_RXD_SKEW_SHIFT(x)		((x) * 4)
+
+/* CPU has two AHB busses. */
+
+/* Global Arbitration0 Control Register */
+#define GLOBAL_ARBITRATION0_CTRL	0x28
+
+#define BOOT_CONTROLLER_HIGH_PRIO	(1 << 3)
+#define DMA_BUS1_HIGH_PRIO		(1 << 2)
+#define CPU0_HIGH_PRIO			(1 << 0)
+
+/* Global Arbitration1 Control Register */
+#define GLOBAL_ARBITRATION1_CTRL	0x2C
+
+#define TVE_HIGH_PRIO			(1 << 9)
+#define PCI_HIGH_PRIO			(1 << 8)
+#define USB1_HIGH_PRIO			(1 << 7)
+#define USB0_HIGH_PRIO			(1 << 6)
+#define GMAC1_HIGH_PRIO			(1 << 5)
+#define GMAC0_HIGH_PRIO			(1 << 4)
+#define SECURITY_HIGH_PRIO		(1 << 3)
+#define RAID_HIGH_PRIO			(1 << 2)
+#define IDE_HIGH_PRIO			(1 << 1)
+#define DMA_BUS2_HIGH_PRIO		(1 << 0)
+
+/* Common bits for both arbitration registers */
+#define BURST_LENGTH_SHIFT		16
+#define BURST_LENGTH_MASK		(0x3F << 16)
+
+/* Miscellaneous Control Register */
+#define GLOBAL_MISC_CTRL		0x30
+
+#define MEMORY_SPACE_SWAP		(1 << 31)
+#define USB1_PLUG_MINIB			(1 << 30) /* else plug is mini-A */
+#define USB0_PLUG_MINIB			(1 << 29)
+#define GMAC_GMII			(1 << 28)
+#define GMAC_1_ENABLE			(1 << 27)
+/* TODO: define ATA/SATA bits */
+#define USB1_VBUS_ON			(1 << 23)
+#define USB0_VBUS_ON			(1 << 22)
+#define APB_CLKOUT_ENABLE		(1 << 21)
+#define TVC_CLKOUT_ENABLE		(1 << 20)
+#define EXT_CLKIN_ENABLE		(1 << 19)
+#define PCI_66MHZ			(1 << 18) /* else 33 MHz */
+#define PCI_CLKOUT_ENABLE		(1 << 17)
+#define LPC_CLKOUT_ENABLE		(1 << 16)
+#define USB1_WAKEUP_ON			(1 << 15)
+#define USB0_WAKEUP_ON			(1 << 14)
+/* TODO: define PCI idle detect bits */
+#define TVC_PADS_ENABLE			(1 << 9)
+#define SSP_PADS_ENABLE			(1 << 8)
+#define LCD_PADS_ENABLE			(1 << 7)
+#define LPC_PADS_ENABLE			(1 << 6)
+#define PCI_PADS_ENABLE			(1 << 5)
+#define IDE_PADS_ENABLE			(1 << 4)
+#define DRAM_PADS_POWER_DOWN		(1 << 3)
+#define NAND_PADS_DISABLE		(1 << 2)
+#define PFLASH_PADS_DISABLE		(1 << 1)
+#define SFLASH_PADS_DISABLE		(1 << 0)
+
+/* Global Clock Control Register */
+#define GLOBAL_CLOCK_CTRL		0x34
+
+#define POWER_STATE_G0			(1 << 31)
+#define POWER_STATE_S1			(1 << 30) /* else it is S3/S4 state */
+#define SECURITY_APB_AHB		(1 << 29)
+/* else Security APB clk will be 0.75xAHB */
+/* TODO: TVC clock divider */
+#define PCI_CLKRUN_ENABLE		(1 << 16)
+#define BOOT_CLK_DISABLE		(1 << 13)
+#define TVC_CLK_DISABLE			(1 << 12)
+#define FLASH_CLK_DISABLE		(1 << 11)
+#define DDR_CLK_DISABLE			(1 << 10)
+#define PCI_CLK_DISABLE			(1 << 9)
+#define IDE_CLK_DISABLE			(1 << 8)
+#define USB1_CLK_DISABLE		(1 << 7)
+#define USB0_CLK_DISABLE		(1 << 6)
+#define SATA1_CLK_DISABLE		(1 << 5)
+#define SATA0_CLK_DISABLE		(1 << 4)
+#define GMAC1_CLK_DISABLE		(1 << 3)
+#define GMAC0_CLK_DISABLE		(1 << 2)
+#define SECURITY_CLK_DISABLE		(1 << 1)
+
+/* TODO: other registers definitions if needed */
+
+#endif /* __MACH_GLOBAL_REG_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * Gemini gpiolib specific defines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_GPIO_H__
+#define __MACH_GPIO_H__
+
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+
+#define gpio_to_irq(x)	((x) + GPIO_IRQ_BASE)
+#define irq_to_gpio(x)	((x) - GPIO_IRQ_BASE)
+
+#endif /* __MACH_GPIO_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ *  This file contains the hardware definitions for Gemini.
+ *
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/*
+ * Memory Map definitions
+ */
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define GEMINI_DRAM_BASE	0x00000000
+# define GEMINI_SRAM_BASE	0x70000000
+#else
+# define GEMINI_SRAM_BASE	0x00000000
+# define GEMINI_DRAM_BASE	0x10000000
+#endif
+#define GEMINI_FLASH_BASE	0x30000000
+#define GEMINI_GLOBAL_BASE	0x40000000
+#define GEMINI_WAQTCHDOG_BASE	0x41000000
+#define GEMINI_UART_BASE	0x42000000
+#define GEMINI_TIMER_BASE	0x43000000
+#define GEMINI_LCD_BASE		0x44000000
+#define GEMINI_RTC_BASE		0x45000000
+#define GEMINI_SATA_BASE	0x46000000
+#define GEMINI_LPC_HOST_BASE	0x47000000
+#define GEMINI_LPC_IO_BASE	0x47800000
+#define GEMINI_INTERRUPT_BASE	0x48000000
+/* TODO: Different interrupt controlers when SMP
+ * #define GEMINI_INTERRUPT0_BASE	0x48000000
+ * #define GEMINI_INTERRUPT1_BASE	0x49000000
+ */
+#define GEMINI_SSP_CTRL_BASE	0x4A000000
+#define GEMINI_POWER_CTRL_BASE	0x4B000000
+#define GEMINI_CIR_BASE		0x4C000000
+#define GEMINI_GPIO_BASE(x)	(0x4D000000 + (x) * 0x1000000)
+#define GEMINI_PCI_IO_BASE	0x50000000
+#define GEMINI_PCI_MEM_BASE	0x58000000
+#define GEMINI_TOE_BASE		0x60000000
+#define GEMINI_GMAC0_BASE	0x6000A000
+#define GEMINI_GMAC1_BASE	0x6000E000
+#define GEMINI_SECURITY_BASE	0x62000000
+#define GEMINI_IDE0_BASE	0x63000000
+#define GEMINI_IDE1_BASE	0x63400000
+#define GEMINI_RAID_BASE	0x64000000
+#define GEMINI_FLASH_CTRL_BASE	0x65000000
+#define GEMINI_DRAM_CTRL_BASE	0x66000000
+#define GEMINI_GENERAL_DMA_BASE	0x67000000
+#define GEMINI_USB0_BASE	0x68000000
+#define GEMINI_USB1_BASE	0x69000000
+#define GEMINI_BIG_ENDIAN_BASE	0x80000000
+
+#define GEMINI_TIMER1_BASE	GEMINI_TIMER_BASE
+#define GEMINI_TIMER2_BASE	(GEMINI_TIMER_BASE + 0x10)
+#define GEMINI_TIMER3_BASE	(GEMINI_TIMER_BASE + 0x20)
+
+/*
+ * UART Clock when System clk is 150MHz
+ */
+#define UART_CLK	48000000
+
+/*
+ * macro to get at IO space when running virtually
+ */
+#define IO_ADDRESS(x)	((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/io.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/io.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+#define __io(a)		__typesafe_io(a)
+#define __mem_pci(a)	(a)
+
+#endif /* __MACH_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_IRQS_H__
+#define __MACH_IRQS_H__
+
+#define IRQ_SERIRQ1	31
+#define IRQ_SERIRQ0	30
+#define IRQ_PCID	29
+#define IRQ_PCIC	28
+#define IRQ_PCIB	27
+#define IRQ_PWR		26
+#define IRQ_CIR		25
+#define IRQ_GPIO(x)	(22 + (x))
+#define IRQ_SSP		21
+#define IRQ_LPC		20
+#define IRQ_LCD		19
+#define IRQ_UART	18
+#define IRQ_RTC		17
+#define IRQ_TIMER3	16
+#define IRQ_TIMER2	15
+#define IRQ_TIMER1	14
+#define IRQ_FLASH	12
+#define IRQ_USB1	11
+#define IRQ_USB0	10
+#define IRQ_DMA		9
+#define IRQ_PCI		8
+#define IRQ_IPSEC	7
+#define IRQ_RAID	6
+#define IRQ_IDE1	5
+#define IRQ_IDE0	4
+#define IRQ_WATCHDOG	3
+#define IRQ_GMAC1	2
+#define IRQ_GMAC0	1
+#define IRQ_IPI		0
+
+#define NORMAL_IRQ_NUM	32
+
+#define GPIO_IRQ_BASE	NORMAL_IRQ_NUM
+#define GPIO_IRQ_NUM	(3 * 32)
+
+#define ARCH_TIMER_IRQ	IRQ_TIMER2
+
+#define NR_IRQS		(NORMAL_IRQ_NUM + GPIO_IRQ_NUM)
+
+#endif /* __MACH_IRQS_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define PHYS_OFFSET	UL(0x00000000)
+#else
+# define PHYS_OFFSET	UL(0x10000000)
+#endif
+
+#endif /* __MACH_MEMORY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * Because of broken hardware we have to enable interrupts or the CPU
+	 * will never wakeup... Acctualy it is not very good to enable
+	 * interrupts here since scheduler can miss a tick, but there is
+	 * no other way around this. Platforms that needs it for power saving
+	 * should call enable_hlt() in init code, since by default it is
+	 * disabled.
+	 */
+	local_irq_enable();
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	__raw_writel(RESET_GLOBAL | RESET_CPU1,
+		     IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
+}
+
+#endif /* __MACH_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/timex.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/timex.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+/*
+ * Gemini timex specifications
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/* When AHB bus frequency is 150MHz */
+#define CLOCK_TICK_RATE	38000000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/uncompress.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on mach-pxa/include/mach/uncompress.h:
+ * Copyright:	(C) 2001 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 Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE;
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ */
+static inline void putc(char c)
+{
+	while (!(UART[UART_LSR] & UART_LSR_THRE))
+		barrier();
+	UART[UART_TX] = c;
+}
+
+#define flush() do { } while (0)
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif /* __MACH_UNCOMPRESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/include/mach/vmalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+/*
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 VMALLOC_END	0xF0000000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,102 @@
+/*
+ *  Interrupt routines for Gemini
+ *
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/io.h>
+#include <linux/ioport.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+
+#define IRQ_SOURCE(base_addr)	(base_addr + 0x00)
+#define IRQ_MASK(base_addr)	(base_addr + 0x04)
+#define IRQ_CLEAR(base_addr)	(base_addr + 0x08)
+#define IRQ_TMODE(base_addr)	(base_addr + 0x0C)
+#define IRQ_TLEVEL(base_addr)	(base_addr + 0x10)
+#define IRQ_STATUS(base_addr)	(base_addr + 0x14)
+#define FIQ_SOURCE(base_addr)	(base_addr + 0x20)
+#define FIQ_MASK(base_addr)	(base_addr + 0x24)
+#define FIQ_CLEAR(base_addr)	(base_addr + 0x28)
+#define FIQ_TMODE(base_addr)	(base_addr + 0x2C)
+#define FIQ_LEVEL(base_addr)	(base_addr + 0x30)
+#define FIQ_STATUS(base_addr)	(base_addr + 0x34)
+
+static void gemini_ack_irq(unsigned int irq)
+{
+	__raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_mask_irq(unsigned int irq)
+{
+	unsigned int mask;
+
+	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+	mask &= ~(1 << irq);
+	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_unmask_irq(unsigned int irq)
+{
+	unsigned int mask;
+
+	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+	mask |= (1 << irq);
+	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static struct irq_chip gemini_irq_chip = {
+	.name	= "INTC",
+	.ack	= gemini_ack_irq,
+	.mask	= gemini_mask_irq,
+	.unmask	= gemini_unmask_irq,
+};
+
+static struct resource irq_resource = {
+	.name	= "irq_handler",
+	.start	= IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+	.end	= IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4,
+};
+
+void __init gemini_init_irq(void)
+{
+	unsigned int i, mode = 0, level = 0;
+
+	/*
+	 * Disable arch_idle() by default since it is buggy
+	 * For more info see arch/arm/mach-gemini/include/mach/system.h
+	 */
+	disable_hlt();
+
+	request_resource(&iomem_resource, &irq_resource);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		set_irq_chip(i, &gemini_irq_chip);
+		if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) {
+			set_irq_handler(i, handle_edge_irq);
+			mode |= 1 << i;
+			level |= 1 << i;
+		} else {			
+			set_irq_handler(i, handle_level_irq);
+		}
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+	}
+
+	/* Disable all interrupts */
+	__raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+	__raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+
+	/* Set interrupt mode */
+	__raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+	__raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+if ARCH_GEMINI
+
+menu "Cortina Systems Gemini Implementations"
+
+config MACH_RUT100
+	bool "Teltonika RUT100"
+	select GEMINI_MEM_SWAP
+	help
+	  Say Y here if you intend to run this kernel on a
+	  Teltonika 3G Router RUT100.
+
+endmenu
+
+config GEMINI_MEM_SWAP
+	bool "Gemini memory is swapped"
+	help
+	  Say Y here if Gemini memory is swapped by bootloader.
+
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y			:= irq.o mm.o time.o devices.o gpio.o
+
+# Board-specific support
+obj-$(CONFIG_MACH_RUT100)	+= board-rut1xx.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Makefile.boot linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Makefile.boot
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/Makefile.boot	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_GEMINI_MEM_SWAP),y)
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
+else
+   zreladdr-y	:= 0x10008000
+params_phys-y	:= 0x10000100
+initrd_phys-y	:= 0x10800000
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/mm.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/mm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/mm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/mm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ *  Static mappings for Gemini
+ *
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+/* Page table mapping for I/O region */
+static struct map_desc gemini_io_desc[] __initdata = {
+	{
+		.virtual	= IO_ADDRESS(GEMINI_GLOBAL_BASE),
+		.pfn		=__phys_to_pfn(GEMINI_GLOBAL_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_UART_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_UART_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_TIMER_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_TIMER_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_INTERRUPT_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_POWER_CTRL_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_POWER_CTRL_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(0)),
+		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(0)),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(1)),
+		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(1)),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(2)),
+		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(2)),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_DRAM_CTRL_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_DRAM_CTRL_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	}, {
+		.virtual	= IO_ADDRESS(GEMINI_GENERAL_DMA_BASE),
+		.pfn		= __phys_to_pfn(GEMINI_GENERAL_DMA_BASE),
+		.length		= SZ_512K,
+		.type 		= MT_DEVICE,
+	},
+};
+
+void __init gemini_map_io(void)
+{
+	iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-gemini/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-gemini/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (C) 2001-2006 Storlink, Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/irq.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+#include <asm/mach/time.h>
+
+/*
+ * Register definitions for the timers
+ */
+#define TIMER_COUNT(BASE_ADDR)		(BASE_ADDR  + 0x00)
+#define TIMER_LOAD(BASE_ADDR)		(BASE_ADDR  + 0x04)
+#define TIMER_MATCH1(BASE_ADDR)		(BASE_ADDR  + 0x08)
+#define TIMER_MATCH2(BASE_ADDR)		(BASE_ADDR  + 0x0C)
+#define TIMER_CR(BASE_ADDR)		(BASE_ADDR  + 0x30)
+
+#define TIMER_1_CR_ENABLE		(1 << 0)
+#define TIMER_1_CR_CLOCK		(1 << 1)
+#define TIMER_1_CR_INT			(1 << 2)
+#define TIMER_2_CR_ENABLE		(1 << 3)
+#define TIMER_2_CR_CLOCK		(1 << 4)
+#define TIMER_2_CR_INT			(1 << 5)
+#define TIMER_3_CR_ENABLE		(1 << 6)
+#define TIMER_3_CR_CLOCK		(1 << 7)
+#define TIMER_3_CR_INT			(1 << 8)
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)
+{
+	timer_tick();
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction gemini_timer_irq = {
+	.name		= "Gemini Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER,
+	.handler	= gemini_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init gemini_timer_init(void)
+{
+	unsigned int tick_rate, reg_v;
+
+	reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
+	tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;
+
+	printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);
+
+	tick_rate /= 6;		/* APB bus run AHB*(1/6) */
+
+	switch(reg_v & CPU_AHB_RATIO_MASK) {
+	case CPU_AHB_1_1:
+		printk(KERN_CONT "(1/1)\n");
+		break;
+	case CPU_AHB_3_2:
+		printk(KERN_CONT "(3/2)\n");
+		break;
+	case CPU_AHB_24_13:
+		printk(KERN_CONT "(24/13)\n");
+		break;
+	case CPU_AHB_2_1:
+		printk(KERN_CONT "(2/1)\n");
+		break;
+	}
+
+	/*
+	 * Make irqs happen for the system timer
+	 */
+	setup_irq(IRQ_TIMER2, &gemini_timer_irq);
+	/* Start the timer */
+	__raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+	__raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+	__raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-h720x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-h720x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-h720x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-h720x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@ static void arch_idle(void)
 }
 
 
-static __inline__ void arch_reset(char mode)
+static __inline__ void arch_reset(char mode, const char *cmd)
 {
 	CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-imx/generic.c linux-libre-2.6.30-gnu1/arch/arm/mach-imx/generic.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-imx/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-imx/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/string.h>
 
 #include <asm/errno.h>
-#include <mach/imxfb.h>
 #include <mach/hardware.h>
 #include <mach/imx-regs.h>
 
@@ -245,43 +244,8 @@ void __init imx_set_mmc_info(struct imxm
 	imx_mmc_device.dev.platform_data = info;
 }
 
-static struct imx_fb_platform_data imx_fb_info;
-
-void __init set_imx_fb_info(struct imx_fb_platform_data *hard_imx_fb_info)
-{
-	memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imx_fb_platform_data));
-}
-
-static struct resource imxfb_resources[] = {
-	[0] = {
-		.start	= 0x00205000,
-		.end	= 0x002050FF,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= LCDC_INT,
-		.end	= LCDC_INT,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 fb_dma_mask = ~(u64)0;
-
-static struct platform_device imxfb_device = {
-	.name		= "imx-fb",
-	.id		= 0,
-	.dev		= {
- 		.platform_data	= &imx_fb_info,
-		.dma_mask	= &fb_dma_mask,
-		.coherent_dma_mask = 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(imxfb_resources),
-	.resource	= imxfb_resources,
-};
-
 static struct platform_device *devices[] __initdata = {
 	&imx_mmc_device,
-	&imxfb_device,
 };
 
 static struct map_desc imx_io_desc[] __initdata = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef _IMX_GPIO_H
 
 #include <linux/kernel.h>
+#include <mach/hardware.h>
 #include <mach/imx-regs.h>
 
 #define IMX_GPIO_ALLOC_MODE_NORMAL	0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/imxfb.h linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/imxfb.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/imxfb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/imxfb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,83 +0,0 @@
-/*
- * This structure describes the machine which we are running on.
- */
-
-#define PCR_TFT		(1 << 31)
-#define PCR_COLOR	(1 << 30)
-#define PCR_PBSIZ_1	(0 << 28)
-#define PCR_PBSIZ_2	(1 << 28)
-#define PCR_PBSIZ_4	(2 << 28)
-#define PCR_PBSIZ_8	(3 << 28)
-#define PCR_BPIX_1	(0 << 25)
-#define PCR_BPIX_2	(1 << 25)
-#define PCR_BPIX_4	(2 << 25)
-#define PCR_BPIX_8	(3 << 25)
-#define PCR_BPIX_12	(4 << 25)
-#define PCR_BPIX_16	(4 << 25)
-#define PCR_PIXPOL	(1 << 24)
-#define PCR_FLMPOL	(1 << 23)
-#define PCR_LPPOL	(1 << 22)
-#define PCR_CLKPOL	(1 << 21)
-#define PCR_OEPOL	(1 << 20)
-#define PCR_SCLKIDLE	(1 << 19)
-#define PCR_END_SEL	(1 << 18)
-#define PCR_END_BYTE_SWAP (1 << 17)
-#define PCR_REV_VS	(1 << 16)
-#define PCR_ACD_SEL	(1 << 15)
-#define PCR_ACD(x)	(((x) & 0x7f) << 8)
-#define PCR_SCLK_SEL	(1 << 7)
-#define PCR_SHARP	(1 << 6)
-#define PCR_PCD(x)	((x) & 0x3f)
-
-#define PWMR_CLS(x)	(((x) & 0x1ff) << 16)
-#define PWMR_LDMSK	(1 << 15)
-#define PWMR_SCR1	(1 << 10)
-#define PWMR_SCR0	(1 << 9)
-#define PWMR_CC_EN	(1 << 8)
-#define PWMR_PW(x)	((x) & 0xff)
-
-#define LSCR1_PS_RISE_DELAY(x)    (((x) & 0x7f) << 26)
-#define LSCR1_CLS_RISE_DELAY(x)   (((x) & 0x3f) << 16)
-#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8)
-#define LSCR1_GRAY2(x)            (((x) & 0xf) << 4)
-#define LSCR1_GRAY1(x)            (((x) & 0xf))
-
-#define DMACR_BURST	(1 << 31)
-#define DMACR_HM(x)	(((x) & 0xf) << 16)
-#define DMACR_TM(x)	((x) & 0xf)
-
-struct imx_fb_platform_data {
-	u_long		pixclock;
-
-	u_short		xres;
-	u_short		yres;
-
-	u_int		nonstd;
-	u_char		bpp;
-	u_char		hsync_len;
-	u_char		left_margin;
-	u_char		right_margin;
-
-	u_char		vsync_len;
-	u_char		upper_margin;
-	u_char		lower_margin;
-	u_char		sync;
-
-	u_int		cmap_greyscale:1,
-			cmap_inverse:1,
-			cmap_static:1,
-			unused:29;
-
-	u_int		pcr;
-	u_int		pwmr;
-	u_int		lscr1;
-	u_int		dmacr;
-
-	u_char * fixed_screen_cpu;
-	dma_addr_t fixed_screen_dma;
-
-	void (*lcd_power)(int);
-	void (*backlight_power)(int);
-};
-
-void set_imx_fb_info(struct imx_fb_platform_data *);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-imx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-imx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ arch_idle(void)
 }
 
 static inline void
-arch_reset(char mode)
+arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-imx/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-imx/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-imx/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-imx/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -73,7 +73,7 @@ static void __init imx_timer_hardware_in
 	IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
 }
 
-cycle_t imx_get_cycles(void)
+cycle_t imx_get_cycles(struct clocksource *cs)
 {
 	return IMX_TCN(TIMER_BASE);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-integrator/core.c linux-libre-2.6.30-gnu1/arch/arm/mach-integrator/core.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-integrator/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-integrator/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -121,7 +121,7 @@ static struct clk uartclk = {
 	.rate	= 14745600,
 };
 
-static struct clk_lookup lookups[] __initdata = {
+static struct clk_lookup lookups[] = {
 	{	/* UART0 */
 		.dev_id		= "mb:16",
 		.clk		= &uartclk,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-integrator/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-integrator/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-integrator/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-integrator/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * To reset, we hit the on-board reset register
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -59,7 +59,10 @@ static inline unsigned long __lbus_to_vi
 	})
 
 #define __arch_page_to_dma(dev, page)					\
-	__arch_virt_to_dma(dev, page_address(page))
+	({								\
+		/* __is_lbus_virt() can never be true for RAM pages */	\
+		(dma_addr_t)page_to_phys(page);				\
+	})
 
 #endif /* CONFIG_ARCH_IOP13XX */
 #endif /* !ASSEMBLY */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Reset the internal bus (warning both cores are reset)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/pci.c linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/pci.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1026,8 +1026,10 @@ int iop13xx_pci_setup(int nr, struct pci
 		which_atu = 0;
 	}
 
-	if (!which_atu)
+	if (!which_atu) {
+		kfree(res);
 		return 0;
+	}
 
 	switch(which_atu) {
 	case IOP13XX_INIT_ATU_ATUX:
@@ -1074,6 +1076,7 @@ int iop13xx_pci_setup(int nr, struct pci
 		sys->map_irq = iop13xx_pcie_map_irq;
 		break;
 	default:
+		kfree(res);
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -307,7 +307,7 @@ static struct resource iop13xx_adma_2_re
 	}
 };
 
-static u64 iop13xx_adma_dmamask = DMA_64BIT_MASK;
+static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(64);
 static struct iop_adma_platform_data iop13xx_adma_0_data = {
 	.hw_id = 0,
 	.pool_size = PAGE_SIZE,
@@ -331,7 +331,7 @@ static struct platform_device iop13xx_ad
 	.resource = iop13xx_adma_0_resources,
 	.dev = {
 		.dma_mask = &iop13xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop13xx_adma_0_data,
 	},
 };
@@ -343,7 +343,7 @@ static struct platform_device iop13xx_ad
 	.resource = iop13xx_adma_1_resources,
 	.dev = {
 		.dma_mask = &iop13xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop13xx_adma_1_data,
 	},
 };
@@ -355,7 +355,7 @@ static struct platform_device iop13xx_ad
 	.resource = iop13xx_adma_2_resources,
 	.dev = {
 		.dma_mask = &iop13xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop13xx_adma_2_data,
 	},
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/tpmi.c linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/tpmi.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop13xx/tpmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop13xx/tpmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -151,7 +151,7 @@ static struct resource iop13xx_tpmi_3_re
 	}
 };
 
-u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
+u64 iop13xx_tpmi_mask = DMA_BIT_MASK(64);
 static struct platform_device iop13xx_tpmi_0_device = {
 	.name = "iop-tpmi",
 	.id = 0,
@@ -159,7 +159,7 @@ static struct platform_device iop13xx_tp
 	.resource = iop13xx_tpmi_0_resources,
 	.dev = {
 		.dma_mask          = &iop13xx_tpmi_mask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 	},
 };
 
@@ -170,7 +170,7 @@ static struct platform_device iop13xx_tp
 	.resource = iop13xx_tpmi_1_resources,
 	.dev = {
 		.dma_mask          = &iop13xx_tpmi_mask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 	},
 };
 
@@ -181,7 +181,7 @@ static struct platform_device iop13xx_tp
 	.resource = iop13xx_tpmi_2_resources,
 	.dev = {
 		.dma_mask          = &iop13xx_tpmi_mask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 	},
 };
 
@@ -192,7 +192,7 @@ static struct platform_device iop13xx_tp
 	.resource = iop13xx_tpmi_3_resources,
 	.dev = {
 		.dma_mask          = &iop13xx_tpmi_mask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 	},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop32x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-iop32x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop32x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop32x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	local_irq_disable();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-iop33x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-iop33x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-iop33x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-iop33x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	*IOP3XX_PCSR = 0x30;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp2000/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ixp2000/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp2000/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp2000/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	local_irq_disable();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp23xx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ixp23xx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp23xx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp23xx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@ static inline void arch_idle(void)
 #endif
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/* First try machine specific support */
 	if (machine_is_ixdp2351()) {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -401,7 +401,7 @@ void __init ixp4xx_sys_init(void)
 /*
  * clocksource
  */
-cycle_t ixp4xx_get_cycles(void)
+cycle_t ixp4xx_get_cycles(struct clocksource *cs)
 {
 	return *IXP4XX_OSTS;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/common-pci.c linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/common-pci.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/common-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -366,7 +366,7 @@ void __init ixp4xx_adjust_zones(int node
 }
 
 void __init ixp4xx_pci_preinit(void)
-{  
+{
 	unsigned long cpuid = read_cpuid_id();
 
 	/*
@@ -386,17 +386,17 @@ void __init ixp4xx_pci_preinit(void)
 
 	pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
 
-	/* 
+	/*
 	 * We use identity AHB->PCI address translation
 	 * in the 0x48000000 to 0x4bffffff address space
 	 */
 	*PCI_PCIMEMBASE = 0x48494A4B;
 
-	/* 
+	/*
 	 * We also use identity PCI->AHB address translation
 	 * in 4 16MB BARs that begin at the physical memory start
 	 */
-	*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) + 
+	*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
 		((PHYS_OFFSET & 0xFF000000) >> 8) +
 		((PHYS_OFFSET & 0xFF000000) >> 16) +
 		((PHYS_OFFSET & 0xFF000000) >> 24) +
@@ -408,18 +408,19 @@ void __init ixp4xx_pci_preinit(void)
 		pr_debug("setup BARs in controller\n");
 
 		/*
-		 * We configure the PCI inbound memory windows to be 
+		 * We configure the PCI inbound memory windows to be
 		 * 1:1 mapped to SDRAM
 		 */
-		local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET + 0x00000000);
-		local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + 0x01000000);
-		local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + 0x02000000);
-		local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + 0x03000000);
+		local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
+		local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
+		local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
+		local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
 
 		/*
-		 * Enable CSR window at 0xff000000.
+		 * Enable CSR window at 64 MiB to allow PCI masters
+		 * to continue prefetching past 64 MiB boundary.
 		 */
-		local_write_config(PCI_BASE_ADDRESS_4, 4, 0xff000008);
+		local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
 
 		/*
 		 * Enable the IO window to be way up high, at 0xfffffc00
@@ -500,7 +501,7 @@ int ixp4xx_setup(int nr, struct pci_sys_
 	return 1;
 }
 
-struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
 {
 	return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/cpu.h linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/cpu.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,26 +17,31 @@
 #include <asm/cputype.h>
 
 /* Processor id value in CP15 Register 0 */
-#define IXP425_PROCESSOR_ID_VALUE	0x690541c0
-#define IXP435_PROCESSOR_ID_VALUE	0x69054040
-#define IXP465_PROCESSOR_ID_VALUE	0x69054200
-#define IXP4XX_PROCESSOR_ID_MASK	0xfffffff0
+#define IXP42X_PROCESSOR_ID_VALUE	0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK	0xffffffc0
 
-#define cpu_is_ixp42x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
-			  IXP425_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp43x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
-			  IXP435_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp46x()	((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
-			  IXP465_PROCESSOR_ID_VALUE)
+#define IXP43X_PROCESSOR_ID_VALUE	0x69054040
+#define IXP43X_PROCESSOR_ID_MASK	0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE	0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK	0xfffffff0
+
+#define cpu_is_ixp42x()	((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+			 IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x()	((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+			 IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x()	((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+			 IXP46X_PROCESSOR_ID_VALUE)
 
 static inline u32 ixp4xx_read_feature_bits(void)
 {
 	unsigned int val = ~*IXP4XX_EXP_CFG2;
-	val &= ~IXP4XX_FEATURE_RESERVED;
-	if (!cpu_is_ixp46x())
-		val &= ~IXP4XX_FEATURE_IXP46X_ONLY;
 
-	return val;
+	if (cpu_is_ixp42x())
+		return val & IXP42X_FEATURE_MASK;
+	if (cpu_is_ixp43x())
+		return val & IXP43X_FEATURE_MASK;
+	return val & IXP46X_FEATURE_MASK;
 }
 
 static inline void ixp4xx_write_feature_bits(u32 value)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -604,6 +604,7 @@
 #define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
 
 /* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
 #define IXP4XX_FEATURE_RCOMP		(1 << 0)
 #define IXP4XX_FEATURE_USB_DEVICE	(1 << 1)
 #define IXP4XX_FEATURE_HASH		(1 << 2)
@@ -619,20 +620,41 @@
 #define IXP4XX_FEATURE_RESET_NPEB	(1 << 12)
 #define IXP4XX_FEATURE_RESET_NPEC	(1 << 13)
 #define IXP4XX_FEATURE_PCI		(1 << 14)
-#define IXP4XX_FEATURE_ECC_TIMESYNC	(1 << 15)
 #define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT	(3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ	(3 << 22)
+#define IXP42X_FEATURE_MASK		(IXP4XX_FEATURE_RCOMP            | \
+					 IXP4XX_FEATURE_USB_DEVICE       | \
+					 IXP4XX_FEATURE_HASH             | \
+					 IXP4XX_FEATURE_AES              | \
+					 IXP4XX_FEATURE_DES              | \
+					 IXP4XX_FEATURE_HDLC             | \
+					 IXP4XX_FEATURE_AAL              | \
+					 IXP4XX_FEATURE_HSS              | \
+					 IXP4XX_FEATURE_UTOPIA           | \
+					 IXP4XX_FEATURE_NPEB_ETH0        | \
+					 IXP4XX_FEATURE_NPEC_ETH         | \
+					 IXP4XX_FEATURE_RESET_NPEA       | \
+					 IXP4XX_FEATURE_RESET_NPEB       | \
+					 IXP4XX_FEATURE_RESET_NPEC       | \
+					 IXP4XX_FEATURE_PCI              | \
+					 IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+					 IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC	(1 << 15)
 #define IXP4XX_FEATURE_USB_HOST		(1 << 18)
 #define IXP4XX_FEATURE_NPEA_ETH		(1 << 19)
+#define IXP43X_FEATURE_MASK		(IXP42X_FEATURE_MASK             | \
+					 IXP4XX_FEATURE_ECC_TIMESYNC     | \
+					 IXP4XX_FEATURE_USB_HOST         | \
+					 IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
 #define IXP4XX_FEATURE_NPEB_ETH_1_TO_3	(1 << 20)
 #define IXP4XX_FEATURE_RSA		(1 << 21)
-#define IXP4XX_FEATURE_XSCALE_MAX_FREQ	(3 << 22)
-#define IXP4XX_FEATURE_RESERVED		(0xFF << 24)
-
-#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_ECC_TIMESYNC |	\
-				    IXP4XX_FEATURE_USB_HOST |		\
-				    IXP4XX_FEATURE_NPEA_ETH |		\
-				    IXP4XX_FEATURE_NPEB_ETH_1_TO_3 |	\
-				    IXP4XX_FEATURE_RSA |		\
-				    IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+#define IXP46X_FEATURE_MASK		(IXP43X_FEATURE_MASK             | \
+					 IXP4XX_FEATURE_NPEB_ETH_1_TO_3  | \
+					 IXP4XX_FEATURE_RSA)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@ static inline void arch_idle(void)
 }
 
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	if ( 1 && mode == 's') {
 		/* Jump into ROM at address 0 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 17:59:43.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ixp4xx/ixp4xx_npe.c	2013-05-03 16:43:25.000000000 -0400
@@ -575,8 +575,8 @@ int npe_load_firmware(struct npe *npe, c
 		for (i = 0; i < image->size; i++)
 			image->data[i] = swab32(image->data[i]);
 
-	if (!cpu_is_ixp46x() && ((image->id >> 28) & 0xF /* device ID */)) {
-		print_npe(KERN_INFO, npe, "IXP46x firmware ignored on "
+	if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
+		print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
 			  "IXP42x\n");
 		goto err;
 	}
@@ -596,7 +596,7 @@ int npe_load_firmware(struct npe *npe, c
 		  "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
 		  (image->id >> 8) & 0xFF, image->id & 0xFF);
 
-	if (!cpu_is_ixp46x()) {
+	if (cpu_is_ixp42x()) {
 		if (!npe->id)
 			instr_size = NPE_A_42X_INSTR_SIZE;
 		else
@@ -714,7 +714,7 @@ static int __init npe_init_module(void)
 	}
 
 	if (!found)
-		return -ENOSYS;
+		return -ENODEV;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/serial_8250.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 <net/dsa.h>
@@ -22,8 +23,10 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
 #include <plat/cache-feroceon-l2.h>
 #include <plat/ehci-orion.h>
+#include <plat/mvsdio.h>
 #include <plat/mv_xor.h>
 #include <plat/orion_nand.h>
 #include <plat/time.h>
@@ -141,6 +144,9 @@ static struct platform_device kirkwood_g
 	.id		= 0,
 	.num_resources	= 1,
 	.resource	= kirkwood_ge00_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
@@ -199,6 +205,9 @@ static struct platform_device kirkwood_g
 	.id		= 1,
 	.num_resources	= 1,
 	.resource	= kirkwood_ge01_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
@@ -231,14 +240,17 @@ static struct platform_device kirkwood_s
 
 void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
 {
+	int i;
+
 	if (irq != NO_IRQ) {
 		kirkwood_switch_resources[0].start = irq;
 		kirkwood_switch_resources[0].end = irq;
 		kirkwood_switch_device.num_resources = 1;
 	}
 
-	d->mii_bus = &kirkwood_ge00_shared.dev;
 	d->netdev = &kirkwood_ge00.dev;
+	for (i = 0; i < d->nr_chips; i++)
+		d->chip[i].mii_bus = &kirkwood_ge00_shared.dev;
 	kirkwood_switch_device.dev.platform_data = d;
 
 	platform_device_register(&kirkwood_switch_device);
@@ -254,7 +266,7 @@ static struct resource kirkwood_rtc_reso
 	.flags	= IORESOURCE_MEM,
 };
 
-void __init kirkwood_rtc_init(void)
+static void __init kirkwood_rtc_init(void)
 {
 	platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
 }
@@ -296,6 +308,50 @@ void __init kirkwood_sata_init(struct mv
 
 
 /*****************************************************************************
+ * SD/SDIO/MMC
+ ****************************************************************************/
+static struct resource mvsdio_resources[] = {
+	[0] = {
+		.start	= SDIO_PHYS_BASE,
+		.end	= SDIO_PHYS_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_KIRKWOOD_SDIO,
+		.end	= IRQ_KIRKWOOD_SDIO,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 mvsdio_dmamask = 0xffffffffUL;
+
+static struct platform_device kirkwood_sdio = {
+	.name		= "mvsdio",
+	.id		= -1,
+	.dev		= {
+		.dma_mask = &mvsdio_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(mvsdio_resources),
+	.resource	= mvsdio_resources,
+};
+
+void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
+{
+	u32 dev, rev;
+
+	kirkwood_pcie_id(&dev, &rev);
+	if (rev == 0)  /* catch all Kirkwood Z0's */
+		mvsdio_data->clock = 100000000;
+	else
+		mvsdio_data->clock = 200000000;
+	mvsdio_data->dram = &kirkwood_mbus_dram_info;
+	kirkwood_sdio.dev.platform_data = mvsdio_data;
+	platform_device_register(&kirkwood_sdio);
+}
+
+
+/*****************************************************************************
  * SPI
  ****************************************************************************/
 static struct orion_spi_info kirkwood_spi_plat_data = {
@@ -326,6 +382,43 @@ void __init kirkwood_spi_init()
 
 
 /*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = {
+	.freq_m		= 8, /* assumes 166 MHz TCLK */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource kirkwood_i2c_resources[] = {
+	{
+		.start	= I2C_PHYS_BASE,
+		.end	= I2C_PHYS_BASE + 0x1f,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= IRQ_KIRKWOOD_TWSI,
+		.end	= IRQ_KIRKWOOD_TWSI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kirkwood_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(kirkwood_i2c_resources),
+	.resource	= kirkwood_i2c_resources,
+	.dev		= {
+		.platform_data	= &kirkwood_i2c_pdata,
+	},
+};
+
+void __init kirkwood_i2c_init(void)
+{
+	platform_device_register(&kirkwood_i2c);
+}
+
+
+/*****************************************************************************
  * UART0
  ****************************************************************************/
 static struct plat_serial8250_port kirkwood_uart0_data[] = {
@@ -420,7 +513,7 @@ static struct mv_xor_platform_shared_dat
 	.dram		= &kirkwood_mbus_dram_info,
 };
 
-static u64 kirkwood_xor_dmamask = DMA_32BIT_MASK;
+static u64 kirkwood_xor_dmamask = DMA_BIT_MASK(32);
 
 
 /*****************************************************************************
@@ -471,7 +564,7 @@ static struct platform_device kirkwood_x
 	.resource	= kirkwood_xor00_resources,
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&kirkwood_xor00_data,
 	},
 };
@@ -497,12 +590,12 @@ static struct platform_device kirkwood_x
 	.resource	= kirkwood_xor01_resources,
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&kirkwood_xor01_data,
 	},
 };
 
-void __init kirkwood_xor0_init(void)
+static void __init kirkwood_xor0_init(void)
 {
 	platform_device_register(&kirkwood_xor0_shared);
 
@@ -569,7 +662,7 @@ static struct platform_device kirkwood_x
 	.resource	= kirkwood_xor10_resources,
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&kirkwood_xor10_data,
 	},
 };
@@ -595,12 +688,12 @@ static struct platform_device kirkwood_x
 	.resource	= kirkwood_xor11_resources,
 	.dev		= {
 		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&kirkwood_xor11_data,
 	},
 };
 
-void __init kirkwood_xor1_init(void)
+static void __init kirkwood_xor1_init(void)
 {
 	platform_device_register(&kirkwood_xor1_shared);
 
@@ -708,4 +801,9 @@ void __init kirkwood_init(void)
 #ifdef CONFIG_CACHE_FEROCEON_L2
 	kirkwood_l2_init();
 #endif
+
+	/* internal devices that every board has */
+	kirkwood_rtc_init();
+	kirkwood_xor0_init();
+	kirkwood_xor1_init();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/common.h linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
+struct mvsdio_platform_data;
 
 /*
  * Basic Kirkwood init functions used early by machine-setup.
@@ -33,14 +34,14 @@ void kirkwood_ge00_init(struct mv643xx_e
 void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
 void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
 void kirkwood_pcie_init(void);
-void kirkwood_rtc_init(void);
 void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
+void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
 void kirkwood_spi_init(void);
+void kirkwood_i2c_init(void);
 void kirkwood_uart0_init(void);
 void kirkwood_uart1_init(void);
-void kirkwood_xor0_init(void);
-void kirkwood_xor1_init(void);
 
+extern int kirkwood_tclk;
 extern struct sys_timer kirkwood_timer;
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/db88f6281-bp-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/db88f6281-bp-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/db88f6281-bp-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,18 +11,59 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
+#include <plat/orion_nand.h>
+#include <plat/mvsdio.h>
 #include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition db88f6281_nand_parts[] = {
+	{
+		.name = "u-boot",
+		.offset = 0,
+		.size = SZ_1M
+	}, {
+		.name = "uImage",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = SZ_4M
+	}, {
+		.name = "root",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = MTDPART_SIZ_FULL
+	},
+};
+
+static struct resource db88f6281_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= KIRKWOOD_NAND_MEM_PHYS_BASE,
+	.end		= KIRKWOOD_NAND_MEM_PHYS_BASE +
+			  KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data db88f6281_nand_data = {
+	.parts		= db88f6281_nand_parts,
+	.nr_parts	= ARRAY_SIZE(db88f6281_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+	.chip_delay	= 25,
+};
+
+static struct platform_device db88f6281_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &db88f6281_nand_data,
+	},
+	.resource	= &db88f6281_nand_resource,
+	.num_resources	= 1,
+};
 
 static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
@@ -32,18 +73,32 @@ static struct mv_sata_platform_data db88
 	.n_ports	= 2,
 };
 
+static struct mvsdio_platform_data db88f6281_mvsdio_data = {
+	.gpio_write_protect	= 37,
+	.gpio_card_detect	= 38,
+};
+
+static unsigned int db88f6281_mpp_config[] __initdata = {
+	MPP37_GPIO,
+	MPP38_GPIO,
+	0
+};
+
 static void __init db88f6281_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
 	kirkwood_init();
+	kirkwood_mpp_conf(db88f6281_mpp_config);
 
 	kirkwood_ehci_init();
 	kirkwood_ge00_init(&db88f6281_ge00_data);
-	kirkwood_rtc_init();
 	kirkwood_sata_init(&db88f6281_sata_data);
 	kirkwood_uart0_init();
+	kirkwood_sdio_init(&db88f6281_mvsdio_data);
+	
+	platform_device_register(&db88f6281_nand_flash);
 }
 
 static int __init db88f6281_pci_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/bridge-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/bridge-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/bridge-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-kirkwood/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/kirkwood.h>
+
+#define CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_RESET		0x00000002
+
+#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 IRQ_CAUSE_HIGH_OFF	0x0010
+#define IRQ_MASK_HIGH_OFF	0x0014
+
+#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0300)
+
+#define L2_CONFIG_REG		(BRIDGE_VIRT_BASE | 0x0128)
+#define L2_WRITETHROUGH		0x00000010
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/debug-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  * published by the Free Software Foundation.
 */
 
-#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
 
 	.macro	addruart,rx
 	mrc	p15, 0, \rx, c1, c0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/entry-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
 
 	.macro  disable_fiq
 	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/kirkwood.h linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/kirkwood.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/kirkwood.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/kirkwood.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,44 +44,6 @@
 #define KIRKWOOD_PCIE_MEM_SIZE		SZ_128M
 
 /*
- * MBUS bridge registers.
- */
-#define BRIDGE_VIRT_BASE	(KIRKWOOD_REGS_VIRT_BASE | 0x20000)
-#define  CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
-#define   CPU_RESET		0x00000002
-#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   IRQ_CAUSE_HIGH_OFF	0x0010
-#define   IRQ_MASK_HIGH_OFF	0x0014
-#define  TIMER_VIRT_BASE	(BRIDGE_VIRT_BASE | 0x0300)
-#define  L2_CONFIG_REG		(BRIDGE_VIRT_BASE | 0x0128)
-#define   L2_WRITETHROUGH	0x00000010
-
-/*
- * Supported devices and revisions.
- */
-#define MV88F6281_DEV_ID	0x6281
-#define MV88F6281_REV_Z0	0
-#define MV88F6281_REV_A0	2
-
-#define MV88F6192_DEV_ID	0x6192
-#define MV88F6192_REV_Z0	0
-#define MV88F6192_REV_A0	2
-
-#define MV88F6180_DEV_ID	0x6180
-#define MV88F6180_REV_A0	2
-
-/*
  * Register Map
  */
 #define DDR_VIRT_BASE		(KIRKWOOD_REGS_VIRT_BASE | 0x00000)
@@ -93,11 +55,14 @@
 #define  DEVICE_ID		(DEV_BUS_VIRT_BASE | 0x0034)
 #define  RTC_PHYS_BASE		(DEV_BUS_PHYS_BASE | 0x0300)
 #define  SPI_PHYS_BASE		(DEV_BUS_PHYS_BASE | 0x0600)
+#define  I2C_PHYS_BASE		(DEV_BUS_PHYS_BASE | 0x1000)
 #define  UART0_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x2000)
 #define  UART0_VIRT_BASE	(DEV_BUS_VIRT_BASE | 0x2000)
 #define  UART1_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x2100)
 #define  UART1_VIRT_BASE	(DEV_BUS_VIRT_BASE | 0x2100)
 
+#define BRIDGE_VIRT_BASE	(KIRKWOOD_REGS_VIRT_BASE | 0x20000)
+
 #define PCIE_VIRT_BASE		(KIRKWOOD_REGS_VIRT_BASE | 0x40000)
 
 #define USB_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x50000)
@@ -116,5 +81,20 @@
 
 #define SATA_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x80000)
 
+#define SDIO_PHYS_BASE		(KIRKWOOD_REGS_PHYS_BASE | 0x90000)
+
+/*
+ * Supported devices and revisions.
+ */
+#define MV88F6281_DEV_ID	0x6281
+#define MV88F6281_REV_Z0	0
+#define MV88F6281_REV_A0	2
+
+#define MV88F6192_DEV_ID	0x6192
+#define MV88F6192_REV_Z0	0
+#define MV88F6192_REV_A0	2
+
+#define MV88F6180_DEV_ID	0x6180
+#define MV88F6180_REV_A0	2
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,15 +9,14 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <mach/hardware.h>
-#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
 
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include <asm/gpio.h>
 #include "common.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,18 @@ config MACH_RD88F6281
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell RD-88F6281 Reference Board.
 
+config MACH_SHEEVAPLUG
+	bool "Marvell SheevaPlug Reference Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell SheevaPlug Reference Board.
+
+config MACH_TS219
+	bool "QNAP TS-119 and TS-219 Turbo NAS"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  QNAP TS-119 and TS-219 Turbo NAS devices.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,7 @@
-obj-y				+= common.o addr-map.o irq.o pcie.o
+obj-y				+= common.o addr-map.o irq.o pcie.o mpp.o
 
 obj-$(CONFIG_MACH_DB88F6281_BP)		+= db88f6281-bp-setup.o
 obj-$(CONFIG_MACH_RD88F6192_NAS)	+= rd88f6192-nas-setup.o
 obj-$(CONFIG_MACH_RD88F6281)		+= rd88f6281-setup.o
+obj-$(CONFIG_MACH_SHEEVAPLUG)		+= sheevaplug-setup.o
+obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/mpp.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/mpp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/mpp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/mpp.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-kirkwood/mpp.c
+ *
+ * MPP functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init kirkwood_variant(void)
+{
+	u32 dev, rev;
+
+	kirkwood_pcie_id(&dev, &rev);
+
+	if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
+		return MPP_F6281_MASK;
+	if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
+		return MPP_F6192_MASK;
+	if (dev == MV88F6180_DEV_ID)
+		return MPP_F6180_MASK;
+
+	printk(KERN_ERR "MPP setup: unknown kirkwood variant "
+			"(dev %#x rev %#x)\n", dev, rev);
+	return 0;
+}
+
+#define MPP_CTRL(i)	(DEV_BUS_VIRT_BASE + (i) * 4)
+#define MPP_NR_REGS	(1 + MPP_MAX/8)
+
+void __init kirkwood_mpp_conf(unsigned int *mpp_list)
+{
+	u32 mpp_ctrl[MPP_NR_REGS];
+	unsigned int variant_mask;
+	int i;
+
+	variant_mask = kirkwood_variant();
+	if (!variant_mask)
+		return;
+
+	printk(KERN_DEBUG "initial MPP regs:");
+	for (i = 0; i < MPP_NR_REGS; i++) {
+		mpp_ctrl[i] = readl(MPP_CTRL(i));
+		printk(" %08x", mpp_ctrl[i]);
+	}
+	printk("\n");
+
+	while (*mpp_list) {
+		unsigned int num = MPP_NUM(*mpp_list);
+		unsigned int sel = MPP_SEL(*mpp_list);
+		int shift, gpio_mode;
+
+		if (num > MPP_MAX) {
+			printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP "
+					"number (%u)\n", num);
+			continue;
+		}
+		if (!(*mpp_list & variant_mask)) {
+			printk(KERN_WARNING
+			       "kirkwood_mpp_conf: requested MPP%u config "
+			       "unavailable on this hardware\n", num);
+			continue;
+		}
+
+		shift = (num & 7) << 2;
+		mpp_ctrl[num / 8] &= ~(0xf << shift);
+		mpp_ctrl[num / 8] |= sel << shift;
+
+		gpio_mode = 0;
+		if (*mpp_list & MPP_INPUT_MASK)
+			gpio_mode |= GPIO_INPUT_OK;
+		if (*mpp_list & MPP_OUTPUT_MASK)
+			gpio_mode |= GPIO_OUTPUT_OK;
+		if (sel != 0)
+			gpio_mode = 0;
+		orion_gpio_set_valid(num, gpio_mode);
+
+		mpp_list++;
+	}
+
+	printk(KERN_DEBUG "  final MPP regs:");
+	for (i = 0; i < MPP_NR_REGS; i++) {
+		writel(mpp_ctrl[i], MPP_CTRL(i));
+		printk(" %08x", mpp_ctrl[i]);
+	}
+	printk("\n");
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/mpp.h linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/mpp.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/mpp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/mpp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,303 @@
+/*
+ * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins
+ *
+ * Copyright 2009: Marvell Technology Group Ltd.
+ *
+ * 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 __KIRKWOOD_MPP_H
+#define __KIRKWOOD_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \
+	/* MPP number */		((_num) & 0xff) | \
+	/* MPP select value */		(((_sel) & 0xf) << 8) | \
+	/* may be input signal */	((!!(_in)) << 12) | \
+	/* may be output signal */	((!!(_out)) << 13) | \
+	/* available on F6180 */	((!!(_F6180)) << 14) | \
+	/* available on F6190 */	((!!(_F6190)) << 15) | \
+	/* available on F6192 */	((!!(_F6192)) << 16) | \
+	/* available on F6281 */	((!!(_F6281)) << 17))
+
+#define MPP_NUM(x)	((x) & 0xff)
+#define MPP_SEL(x)	(((x) >> 8) & 0xf)
+
+				/*   num sel  i  o  6180 6190 6192 6281 */
+
+#define MPP_INPUT_MASK		MPP(  0, 0x0, 1, 0, 0,   0,   0,   0    )
+#define MPP_OUTPUT_MASK		MPP(  0, 0x0, 0, 1, 0,   0,   0,   0    )
+
+#define MPP_F6180_MASK		MPP(  0, 0x0, 0, 0, 1,   0,   0,   0    )
+#define MPP_F6190_MASK		MPP(  0, 0x0, 0, 0, 0,   1,   0,   0    )
+#define MPP_F6192_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   1,   0    )
+#define MPP_F6281_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   0,   1    )
+
+#define MPP0_GPIO		MPP(  0, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP0_NF_IO2		MPP(  0, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP0_SPI_SCn		MPP(  0, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP1_GPO		MPP(  1, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP1_NF_IO3		MPP(  1, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP1_SPI_MOSI		MPP(  1, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP2_GPO		MPP(  2, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP2_NF_IO4		MPP(  2, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP2_SPI_SCK		MPP(  2, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP3_GPO		MPP(  3, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP3_NF_IO5		MPP(  3, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP3_SPI_MISO		MPP(  3, 0x2, 1, 0, 1,   1,   1,   1    )
+
+#define MPP4_GPIO		MPP(  4, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP4_NF_IO6		MPP(  4, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP4_UART0_RXD		MPP(  4, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP4_SATA1_ACTn		MPP(  4, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP4_PTP_CLK		MPP(  4, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP5_GPO		MPP(  5, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP5_NF_IO7		MPP(  5, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP5_UART0_TXD		MPP(  5, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP5_PTP_TRIG_GEN	MPP(  5, 0x4, 0, 1, 1,   1,   1,   1    )
+#define MPP5_SATA0_ACTn		MPP(  5, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP6_SYSRST_OUTn	MPP(  6, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP6_SPI_MOSI		MPP(  6, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP6_PTP_TRIG_GEN	MPP(  6, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP7_GPO		MPP(  7, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PEX_RST_OUTn	MPP(  7, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP7_SPI_SCn		MPP(  7, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PTP_TRIG_GEN	MPP(  7, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP8_GPIO		MPP(  8, 0x0, 1, 1, 1,    1,  1,   1    )
+#define MPP8_TW_SDA		MPP(  8, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP8_UART0_RTS		MPP(  8, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP8_UART1_RTS		MPP(  8, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP8_MII0_RXERR		MPP(  8, 0x4, 1, 0, 0,   1,   1,   1    )
+#define MPP8_SATA1_PRESENTn	MPP(  8, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP8_PTP_CLK		MPP(  8, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP8_MII0_COL		MPP(  8, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP9_GPIO		MPP(  9, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP9_TW_SCK		MPP(  9, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP9_UART0_CTS		MPP(  9, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP9_UART1_CTS		MPP(  9, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP9_SATA0_PRESENTn	MPP(  9, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP9_PTP_EVENT_REQ	MPP(  9, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP9_MII0_CRS		MPP(  9, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP10_GPO		MPP( 10, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SPI_SCK		MPP( 10, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP10_UART0_TXD		MPP( 10, 0X3, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SATA1_ACTn	MPP( 10, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP10_PTP_TRIG_GEN	MPP( 10, 0xc, 0, 1, 1,   1,   1,   1    )
+
+#define MPP11_GPIO		MPP( 11, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP11_SPI_MISO		MPP( 11, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP11_UART0_RXD		MPP( 11, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_EVENT_REQ	MPP( 11, 0x4, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_TRIG_GEN	MPP( 11, 0xc, 0, 1, 1,   1,   1,   1    )
+#define MPP11_PTP_CLK		MPP( 11, 0xd, 1, 0, 1,   1,   1,   1    )
+#define MPP11_SATA0_ACTn	MPP( 11, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP12_GPO		MPP( 12, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP12_SD_CLK		MPP( 12, 0x1, 0, 1, 1,   1,   1,   1    )
+
+#define MPP13_GPIO		MPP( 13, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP13_SD_CMD		MPP( 13, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP13_UART1_TXD		MPP( 13, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP14_GPIO		MPP( 14, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP14_SD_D0		MPP( 14, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP14_UART1_RXD		MPP( 14, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP14_SATA1_PRESENTn	MPP( 14, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP14_MII0_COL		MPP( 14, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP15_GPIO		MPP( 15, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP15_SD_D1		MPP( 15, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP15_UART0_RTS		MPP( 15, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP15_UART1_TXD		MPP( 15, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP15_SATA0_ACTn	MPP( 15, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP16_GPIO		MPP( 16, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP16_SD_D2		MPP( 16, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP16_UART0_CTS		MPP( 16, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP16_UART1_RXD		MPP( 16, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP16_SATA1_ACTn	MPP( 16, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP16_MII0_CRS		MPP( 16, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP17_GPIO		MPP( 17, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SD_D3		MPP( 17, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SATA0_PRESENTn	MPP( 17, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP18_GPO		MPP( 18, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP18_NF_IO0		MPP( 18, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP19_GPO		MPP( 19, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP19_NF_IO1		MPP( 19, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP20_GPIO		MPP( 20, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP20_TSMP0		MPP( 20, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP20_TDM_CH0_TX_QL	MPP( 20, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP20_GE1_0		MPP( 20, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP20_AUDIO_SPDIFI	MPP( 20, 0x4, 1, 0, 0,   0,   1,   1    )
+#define MPP20_SATA1_ACTn	MPP( 20, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP21_GPIO		MPP( 21, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP21_TSMP1		MPP( 21, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP21_TDM_CH0_RX_QL	MPP( 21, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP21_GE1_1		MPP( 21, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP21_AUDIO_SPDIFO	MPP( 21, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP21_SATA0_ACTn	MPP( 21, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP22_GPIO		MPP( 22, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP22_TSMP2		MPP( 22, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP22_TDM_CH2_TX_QL	MPP( 22, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP22_GE1_2		MPP( 22, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP22_AUDIO_SPDIFRMKCLK	MPP( 22, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP22_SATA1_PRESENTn	MPP( 22, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP23_GPIO		MPP( 23, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP23_TSMP3		MPP( 23, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP23_TDM_CH2_RX_QL	MPP( 23, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP23_GE1_3		MPP( 23, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP23_AUDIO_I2SBCLK	MPP( 23, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP23_SATA0_PRESENTn	MPP( 23, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP24_GPIO		MPP( 24, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP24_TSMP4		MPP( 24, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP24_TDM_SPI_CS0	DEV( 24, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP24_GE1_4		MPP( 24, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP24_AUDIO_I2SDO	MPP( 24, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP25_GPIO		MPP( 25, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP25_TSMP5		MPP( 25, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP25_TDM_SPI_SCK	MPP( 25, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP25_GE1_5		MPP( 25, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP25_AUDIO_I2SLRCLK	MPP( 25, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP26_GPIO		MPP( 26, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP26_TSMP6		MPP( 26, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP26_TDM_SPI_MISO	MPP( 26, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP26_GE1_6		MPP( 26, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP26_AUDIO_I2SMCLK	MPP( 26, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP27_GPIO		MPP( 27, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP27_TSMP7		MPP( 27, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP27_TDM_SPI_MOSI	MPP( 27, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP27_GE1_7		MPP( 27, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP27_AUDIO_I2SDI	MPP( 27, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP28_GPIO		MPP( 28, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP28_TSMP8		MPP( 28, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP28_TDM_CODEC_INTn	MPP( 28, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP28_GE1_8		MPP( 28, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP28_AUDIO_EXTCLK	MPP( 28, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP29_GPIO		MPP( 29, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP29_TSMP9		MPP( 29, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP29_TDM_CODEC_RSTn	MPP( 29, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP29_GE1_9		MPP( 29, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP30_GPIO		MPP( 30, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP30_TSMP10		MPP( 30, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP30_TDM_PCLK		MPP( 30, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP30_GE1_10		MPP( 30, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP31_GPIO		MPP( 31, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP31_TSMP11		MPP( 31, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP31_TDM_FS		MPP( 31, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP31_GE1_11		MPP( 31, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP32_GPIO		MPP( 32, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP32_TSMP12		MPP( 32, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP32_TDM_DRX		MPP( 32, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP32_GE1_12		MPP( 32, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP33_GPIO		MPP( 33, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP33_TDM_DTX		MPP( 33, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP33_GE1_13		MPP( 33, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP34_GPIO		MPP( 34, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP34_TDM_SPI_CS1	MPP( 34, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP34_GE1_14		MPP( 34, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP35_GPIO		MPP( 35, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP35_TDM_CH0_TX_QL	MPP( 35, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP35_GE1_15		MPP( 35, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP35_SATA0_ACTn	MPP( 35, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP35_MII0_RXERR	MPP( 35, 0xc, 1, 0, 1,   1,   1,   1    )
+
+#define MPP36_GPIO		MPP( 36, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP36_TSMP0		MPP( 36, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP36_TDM_SPI_CS1	MPP( 36, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP36_AUDIO_SPDIFI	MPP( 36, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP37_GPIO		MPP( 37, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP37_TSMP1		MPP( 37, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP37_TDM_CH2_TX_QL	MPP( 37, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP37_AUDIO_SPDIFO	MPP( 37, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP38_GPIO		MPP( 38, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP38_TSMP2		MPP( 38, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP38_TDM_CH2_RX_QL	MPP( 38, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP38_AUDIO_SPDIFRMLCLK	MPP( 38, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP39_GPIO		MPP( 39, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP39_TSMP3		MPP( 39, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP39_TDM_SPI_CS0	MPP( 39, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP39_AUDIO_I2SBCLK	MPP( 39, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP40_GPIO		MPP( 40, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP40_TSMP4		MPP( 40, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP40_TDM_SPI_SCK	MPP( 40, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP40_AUDIO_I2SDO	MPP( 40, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP41_GPIO		MPP( 41, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP41_TSMP5		MPP( 41, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP41_TDM_SPI_MISO	MPP( 41, 0x2, 1, 0, 0,   0,   0,   1    )
+#define MPP41_AUDIO_I2SLRC	MPP( 41, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP42_GPIO		MPP( 42, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP42_TSMP6		MPP( 42, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP42_TDM_SPI_MOSI	MPP( 42, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP42_AUDIO_I2SMCLK	MPP( 42, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP43_GPIO		MPP( 43, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP43_TSMP7		MPP( 43, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP43_TDM_CODEC_INTn	MPP( 43, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP43_AUDIO_I2SDI	MPP( 43, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP44_GPIO		MPP( 44, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP44_TSMP8		MPP( 44, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP44_TDM_CODEC_RSTn	MPP( 44, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP44_AUDIO_EXTCLK	MPP( 44, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP45_GPIO		MPP( 45, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TSMP9		MPP( 45, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TDM_PCLK		MPP( 45, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP46_GPIO		MPP( 46, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TSMP10		MPP( 46, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TDM_FS		MPP( 46, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP47_GPIO		MPP( 47, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TSMP11		MPP( 47, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TDM_DRX		MPP( 47, 0x2, 1, 0, 0,   0,   0,   1    )
+
+#define MPP48_GPIO		MPP( 48, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TSMP12		MPP( 48, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TDM_DTX		MPP( 48. 0x2, 0, 1, 0,   0,   0,   1    )
+
+#define MPP49_GPIO		MPP( 49, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TSMP9		MPP( 49, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TDM_CH0_RX_QL	MPP( 49, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP49_PTP_CLK		MPP( 49, 0x5, 1, 0, 0,   0,   0,   1    )
+
+#define MPP_MAX			49
+
+void kirkwood_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,11 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/spi/flash.h>
@@ -23,7 +20,6 @@
 #include <linux/spi/orion_spi.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
 #include "common.h"
 
@@ -61,14 +57,11 @@ static void __init rd88f6192_init(void)
 
 	kirkwood_ehci_init();
 	kirkwood_ge00_init(&rd88f6192_ge00_data);
-	kirkwood_rtc_init();
 	kirkwood_sata_init(&rd88f6192_sata_data);
 	spi_register_board_info(rd88F6192_spi_slave_info,
 				ARRAY_SIZE(rd88F6192_spi_slave_info));
 	kirkwood_spi_init();
 	kirkwood_uart0_init();
-	kirkwood_xor0_init();
-	kirkwood_xor1_init();
 }
 
 static int __init rd88f6192_pci_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/rd88f6281-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/rd88f6281-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/rd88f6281-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/rd88f6281-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,21 +11,20 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
 #include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
 #include <plat/orion_nand.h>
 #include "common.h"
+#include "mpp.h"
 
 static struct mtd_partition rd88f6281_nand_parts[] = {
 	{
@@ -75,7 +74,7 @@ static struct mv643xx_eth_platform_data
 	.duplex		= DUPLEX_FULL,
 };
 
-static struct dsa_platform_data rd88f6281_switch_data = {
+static struct dsa_chip_data rd88f6281_switch_chip_data = {
 	.port_names[0]	= "lan1",
 	.port_names[1]	= "lan2",
 	.port_names[2]	= "lan3",
@@ -83,6 +82,11 @@ static struct dsa_platform_data rd88f628
 	.port_names[5]	= "cpu",
 };
 
+static struct dsa_platform_data rd88f6281_switch_plat_data = {
+	.nr_chips	= 1,
+	.chip		= &rd88f6281_switch_chip_data,
+};
+
 static struct mv643xx_eth_platform_data rd88f6281_ge01_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(11),
 };
@@ -91,6 +95,15 @@ static struct mv_sata_platform_data rd88
 	.n_ports	= 2,
 };
 
+static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
+	.gpio_card_detect = 28,
+};
+
+static unsigned int rd88f6281_mpp_config[] __initdata = {
+	MPP28_GPIO,
+	0
+};
+
 static void __init rd88f6281_init(void)
 {
 	u32 dev, rev;
@@ -99,21 +112,22 @@ static void __init rd88f6281_init(void)
 	 * Basic setup. Needs to be called early.
 	 */
 	kirkwood_init();
+	kirkwood_mpp_conf(rd88f6281_mpp_config);
 
 	kirkwood_ehci_init();
 
 	kirkwood_ge00_init(&rd88f6281_ge00_data);
 	kirkwood_pcie_id(&dev, &rev);
 	if (rev == MV88F6281_REV_A0) {
-		rd88f6281_switch_data.sw_addr = 10;
+		rd88f6281_switch_chip_data.sw_addr = 10;
 		kirkwood_ge01_init(&rd88f6281_ge01_data);
 	} else {
-		rd88f6281_switch_data.port_names[4] = "wan";
+		rd88f6281_switch_chip_data.port_names[4] = "wan";
 	}
-	kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
+	kirkwood_ge00_switch_init(&rd88f6281_switch_plat_data, NO_IRQ);
 
-	kirkwood_rtc_init();
 	kirkwood_sata_init(&rd88f6281_sata_data);
+	kirkwood_sdio_init(&rd88f6281_mvsdio_data);
 	kirkwood_uart0_init();
 
 	platform_device_register(&rd88f6281_nand_flash);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/sheevaplug-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,136 @@
+/*
+ * arch/arm/mach-kirkwood/sheevaplug-setup.c
+ *
+ * Marvell SheevaPlug Reference 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/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include <plat/orion_nand.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition sheevaplug_nand_parts[] = {
+	{
+		.name = "u-boot",
+		.offset = 0,
+		.size = SZ_1M
+	}, {
+		.name = "uImage",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = SZ_4M
+	}, {
+		.name = "root",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = MTDPART_SIZ_FULL
+	},
+};
+
+static struct resource sheevaplug_nand_resource = {
+	.flags		= IORESOURCE_MEM,
+	.start		= KIRKWOOD_NAND_MEM_PHYS_BASE,
+	.end		= KIRKWOOD_NAND_MEM_PHYS_BASE +
+			  KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data sheevaplug_nand_data = {
+	.parts		= sheevaplug_nand_parts,
+	.nr_parts	= ARRAY_SIZE(sheevaplug_nand_parts),
+	.cle		= 0,
+	.ale		= 1,
+	.width		= 8,
+	.chip_delay	= 25,
+};
+
+static struct platform_device sheevaplug_nand_flash = {
+	.name		= "orion_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &sheevaplug_nand_data,
+	},
+	.resource	= &sheevaplug_nand_resource,
+	.num_resources	= 1,
+};
+
+static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
+	// unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led sheevaplug_led_pins[] = {
+	{
+		.name			= "plug:green:health",
+		.default_trigger	= "default-on",
+		.gpio			= 49,
+		.active_low		= 1,
+	},
+};
+
+static struct gpio_led_platform_data sheevaplug_led_data = {
+	.leds		= sheevaplug_led_pins,
+	.num_leds	= ARRAY_SIZE(sheevaplug_led_pins),
+};
+
+static struct platform_device sheevaplug_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &sheevaplug_led_data,
+	}
+};
+
+static unsigned int sheevaplug_mpp_config[] __initdata = {
+	MPP29_GPIO,	/* USB Power Enable */
+	MPP49_GPIO,	/* LED */
+	0
+};
+
+static void __init sheevaplug_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(sheevaplug_mpp_config);
+
+	kirkwood_uart0_init();
+
+	if (gpio_request(29, "USB Power Enable") != 0 ||
+	    gpio_direction_output(29, 1) != 0)
+		printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+	kirkwood_ehci_init();
+
+	kirkwood_ge00_init(&sheevaplug_ge00_data);
+	kirkwood_sdio_init(&sheevaplug_mvsdio_data);
+
+	platform_device_register(&sheevaplug_nand_flash);
+	platform_device_register(&sheevaplug_leds);
+}
+
+MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
+	/* Maintainer: shadi Ammouri <shadi@marvell.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= sheevaplug_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/ts219-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/ts219-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-kirkwood/ts219-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-kirkwood/ts219-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,218 @@
+/*
+ *
+ * QNAP TS-119/TS-219 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/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,
+	},
+};
+
+static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = {
+	I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data qnap_ts219_sata_data = {
+	.n_ports	= 2,
+};
+
+static struct gpio_keys_button qnap_ts219_buttons[] = {
+	{
+		.code		= KEY_COPY,
+		.gpio		= 15,
+		.desc		= "USB Copy",
+		.active_low	= 1,
+	},
+	{
+		.code		= KEY_RESTART,
+		.gpio		= 16,
+		.desc		= "Reset",
+		.active_low	= 1,
+	},
+};
+
+static struct gpio_keys_platform_data qnap_ts219_button_data = {
+	.buttons	= qnap_ts219_buttons,
+	.nbuttons	= ARRAY_SIZE(qnap_ts219_buttons),
+};
+
+static struct platform_device qnap_ts219_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &qnap_ts219_button_data,
+	}
+};
+
+static unsigned int qnap_ts219_mpp_config[] __initdata = {
+	MPP0_SPI_SCn,
+	MPP1_SPI_MOSI,
+	MPP2_SPI_SCK,
+	MPP3_SPI_MISO,
+	MPP4_SATA1_ACTn,
+	MPP5_SATA0_ACTn,
+	MPP8_TW_SDA,
+	MPP9_TW_SCK,
+	MPP10_UART0_TXD,
+	MPP11_UART0_RXD,
+	MPP13_UART1_TXD,	/* PIC controller */
+	MPP14_UART1_RXD,	/* PIC controller */
+	MPP15_GPIO,		/* USB Copy button */
+	MPP16_GPIO,		/* Reset button */
+	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)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(qnap_ts219_mpp_config);
+
+	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();
+	kirkwood_i2c_init();
+	i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
+	kirkwood_ge00_init(&qnap_ts219_ge00_data);
+	kirkwood_sata_init(&qnap_ts219_sata_data);
+	kirkwood_ehci_init();
+	platform_device_register(&qnap_ts219_button_device);
+
+	pm_power_off = qnap_ts219_power_off;
+
+}
+
+MACHINE_START(TS219, "QNAP TS-119/TS-219")
+	/* 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_ts219_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/board-acs5k.c linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/board-acs5k.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/board-acs5k.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/board-acs5k.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,233 @@
+/*
+ * arch/arm/mach-ks8695/board-acs5k.c
+ *
+ * Brivo Systems LLC, ACS-5000 Master Board
+ *
+ * Copyright 2008 Simtec Electronics
+ *		  Daniel Silverstone <dsilvers@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pca953x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/devices.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
+	.sda_pin	= 4,
+	.scl_pin	= 5,
+	.udelay		= 10,
+};
+
+static struct platform_device acs5k_i2c_device = {
+	.name		= "i2c-gpio",
+	.id		= -1,
+	.num_resources	= 0,
+	.resource	= NULL,
+	.dev		= {
+		.platform_data	= &acs5k_i2c_device_platdata,
+	},
+};
+
+static int acs5k_pca9555_setup(struct i2c_client *client,
+			       unsigned gpio_base, unsigned ngpio,
+			       void *context)
+{
+	static int acs5k_gpio_value[] = {
+		-1, -1, -1, -1, -1, -1, -1, 0, 1, 1, -1, 0, 1, 0, -1, -1
+	};
+	int n;
+
+	for (n = 0; n < ARRAY_SIZE(acs5k_gpio_value); ++n) {
+		gpio_request(gpio_base + n, "ACS-5000 GPIO Expander");
+		if (acs5k_gpio_value[n] < 0)
+			gpio_direction_input(gpio_base + n);
+		else
+			gpio_direction_output(gpio_base + n,
+					      acs5k_gpio_value[n]);
+		gpio_export(gpio_base + n, 0); /* Export, direction locked down */
+	}
+
+	return 0;
+}
+
+static struct pca953x_platform_data acs5k_i2c_pca9555_platdata = {
+	.gpio_base	= 16, /* Start directly after the CPU's GPIO */
+	.invert		= 0, /* Do not invert */
+	.setup		= acs5k_pca9555_setup,
+};
+
+static struct i2c_board_info acs5k_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	},
+	{
+		I2C_BOARD_INFO("pca9555", 0x20),
+		.platform_data = &acs5k_i2c_pca9555_platdata,
+	},
+};
+
+static void __devinit acs5k_i2c_init(void)
+{
+	/* The gpio interface */
+	platform_device_register(&acs5k_i2c_device);
+	/* I2C devices */
+	i2c_register_board_info(0, acs5k_i2c_devs,
+				ARRAY_SIZE(acs5k_i2c_devs));
+}
+
+static struct mtd_partition acs5k_nor_partitions[] = {
+	[0] = {
+		.name	= "Boot Agent and config",
+		.size	= SZ_256K,
+		.offset	= 0,
+		.mask_flags = MTD_WRITEABLE,
+	},
+	[1] = {
+		.name	= "Kernel",
+		.size	= SZ_1M,
+		.offset	= SZ_256K,
+	},
+	[2] = {
+		.name	= "SquashFS1",
+		.size	= SZ_2M,
+		.offset	= SZ_256K + SZ_1M,
+	},
+	[3] = {
+		.name	= "SquashFS2",
+		.size	= SZ_4M + SZ_2M,
+		.offset	= SZ_256K + SZ_1M + SZ_2M,
+	},
+	[4] = {
+		.name	= "Data",
+		.size	= SZ_16M + SZ_4M + SZ_2M + SZ_512K, /* 22.5 MB */
+		.offset	= SZ_256K + SZ_8M + SZ_1M,
+	}
+};
+
+static struct physmap_flash_data acs5k_nor_pdata = {
+	.width		= 4,
+	.nr_parts	= ARRAY_SIZE(acs5k_nor_partitions),
+	.parts		= acs5k_nor_partitions,
+};
+
+static struct resource acs5k_nor_resource[] = {
+	[0] = {
+		.start = SZ_32M, /* We expect the bootloader to map
+				  * the flash here.
+				  */
+		.end   = SZ_32M + SZ_16M - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = SZ_32M + SZ_16M,
+		.end   = SZ_32M + SZ_32M - SZ_256K - 1,
+		.flags = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device acs5k_device_nor = {
+	.name		= "physmap-flash",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(acs5k_nor_resource),
+	.resource	= acs5k_nor_resource,
+	.dev		= {
+		.platform_data = &acs5k_nor_pdata,
+	},
+};
+
+static void __init acs5k_register_nor(void)
+{
+	int ret;
+
+	if (acs5k_nor_partitions[0].mask_flags == 0)
+		printk(KERN_WARNING "Warning: Unprotecting bootloader and configuration partition\n");
+
+	ret = platform_device_register(&acs5k_device_nor);
+	if (ret < 0)
+		printk(KERN_ERR "failed to register physmap-flash device\n");
+}
+
+static int __init acs5k_protection_setup(char *s)
+{
+	/* We can't allocate anything here but we should be able
+	 * to trivially parse s and decide if we can protect the
+	 * bootloader partition or not
+	 */
+	if (strcmp(s, "no") == 0)
+		acs5k_nor_partitions[0].mask_flags = 0;
+
+	return 1;
+}
+
+__setup("protect_bootloader=", acs5k_protection_setup);
+
+static void __init acs5k_init_gpio(void)
+{
+	int i;
+
+	ks8695_register_gpios();
+	for (i = 0; i < 4; ++i)
+		gpio_request(i, "ACS5K IRQ");
+	gpio_request(7, "ACS5K KS_FRDY");
+	for (i = 8; i < 16; ++i)
+		gpio_request(i, "ACS5K Unused");
+
+	gpio_request(3, "ACS5K CAN Control");
+	gpio_request(6, "ACS5K Heartbeat");
+	gpio_direction_output(3, 1); /* Default CAN_RESET high */
+	gpio_direction_output(6, 0); /* Default KS8695_ACTIVE low */
+	gpio_export(3, 0); /* export CAN_RESET as output only */
+	gpio_export(6, 0); /* export KS8695_ACTIVE as output only */
+}
+
+static void __init acs5k_init(void)
+{
+	acs5k_init_gpio();
+
+	/* Network device */
+	ks8695_add_device_lan();	/* eth0 = LAN */
+	ks8695_add_device_wan();	/* ethX = WAN */
+
+	/* NOR devices */
+	acs5k_register_nor();
+
+	/* I2C bus */
+	acs5k_i2c_init();
+}
+
+MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
+	/* Maintainer: Simtec Electronics. */
+	.phys_io	= KS8695_IO_PA,
+	.io_pg_offst	= (KS8695_IO_VA >> 18) & 0xfffc,
+	.boot_params	= KS8695_SDRAM_PA + 0x100,
+	.map_io		= ks8695_map_io,
+	.init_irq	= ks8695_init_irq,
+	.init_machine	= acs5k_init,
+	.timer		= &ks8695_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/include/mach/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,11 @@ extern struct bus_type platform_bus_type
 					__phys_to_virt(x) : __bus_to_virt(x)); })
 #define __arch_virt_to_dma(dev, x)	({ is_lbus_device(dev) ? \
 					(dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
-#define __arch_page_to_dma(dev, x)	__arch_virt_to_dma(dev, page_address(x))
+#define __arch_page_to_dma(dev, x)	\
+	({ dma_addr_t __dma = page_to_phys(page); \
+	   if (!is_lbus_device(dev)) \
+		__dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
+	   __dma; })
 
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@ static void arch_idle(void)
 
 }
 
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
 {
 	unsigned int reg;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,12 @@ config MACH_DSM320
 	  Say 'Y' here if you want your kernel to run on the D-Link
 	  DSM-320 Wireless Media Player.
 
+config MACH_ACS5K
+	bool "Brivo Systems LLC, ACS-5000 Master board"
+	help
+	  say 'Y' here if you want your kernel to run on the Brivo
+	  Systems LLC, ACS-5000 Master board.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ks8695/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ks8695/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -17,3 +17,4 @@ obj-$(CONFIG_LEDS)		+= leds.o
 # Board-specific support
 obj-$(CONFIG_MACH_KS8695)	+= board-micrel.o
 obj-$(CONFIG_MACH_DSM320)	+= board-dsm320.o
+obj-$(CONFIG_MACH_ACS5K)	+= board-acs5k.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-l7200/include/mach/sys-clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-l7200/include/mach/sys-clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-l7200/include/mach/sys-clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-l7200/include/mach/sys-clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 
 /* IO_START and IO_BASE are defined in hardware.h */
 
-#define SYS_CLOCK_START (IO_START + SYS_CLCOK_OFF)  /* Physical address */
+#define SYS_CLOCK_START (IO_START + SYS_CLOCK_OFF)  /* Physical address */
 #define SYS_CLOCK_BASE  (IO_BASE  + SYS_CLOCK_OFF)  /* Virtual address  */
 
 /* Define the interface to the SYS_CLOCK */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-l7200/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-l7200/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-l7200/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-l7200/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@ static inline void arch_idle(void)
 	*(unsigned long *)(IO_BASE + 0x50004) = 1;	/* idle mode */
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	if (mode == 's') {
 		cpu_reset(0);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-lh7a40x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-lh7a40x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-lh7a40x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-lh7a40x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@ static inline void arch_idle(void)
 	cpu_do_idle ();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset (0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/addr-map.c linux-libre-2.6.30-gnu1/arch/arm/mach-loki/addr-map.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/addr-map.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/addr-map.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@
 /*
  * CPU Address Decode Windows registers
  */
+#define BRIDGE_REG(x)		(BRIDGE_VIRT_BASE | (x))
 #define CPU_WIN_CTRL(n)		BRIDGE_REG(0x000 | ((n) << 4))
 #define CPU_WIN_BASE(n)		BRIDGE_REG(0x004 | ((n) << 4))
 #define CPU_WIN_REMAP_LO(n)	BRIDGE_REG(0x008 | ((n) << 4))
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-loki/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,6 +82,9 @@ static struct platform_device loki_ge0 =
 	.id		= 0,
 	.num_resources	= 1,
 	.resource	= loki_ge0_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data)
@@ -136,6 +139,9 @@ static struct platform_device loki_ge1 =
 	.id		= 1,
 	.num_resources	= 1,
 	.resource	= loki_ge1_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/bridge-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/bridge-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/bridge-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/bridge-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-loki/include/mach/bridge-regs.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_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/loki.h>
+
+#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_OFF		0x0000
+#define IRQ_MASK_OFF		0x0004
+
+#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/entry-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/loki.h>
+#include <mach/bridge-regs.h>
 
 	.macro  disable_fiq
 	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/loki.h linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/loki.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/loki.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/loki.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,20 +58,6 @@
 #define  UART1_VIRT_BASE	(DEV_BUS_VIRT_BASE | 0x2100)
 
 #define BRIDGE_VIRT_BASE	(LOKI_REGS_VIRT_BASE | 0x20000)
-#define  BRIDGE_REG(x)		(BRIDGE_VIRT_BASE | (x))
-#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_OFF		0x0000
-#define   IRQ_MASK_OFF		0x0004
-#define  TIMER_VIRT_BASE	(BRIDGE_VIRT_BASE | 0x0300)
 
 #define PCIE0_VIRT_BASE		(LOKI_REGS_VIRT_BASE | 0x30000)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,15 +9,14 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <mach/hardware.h>
-#include <mach/loki.h>
+#include <mach/bridge-regs.h>
 
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-loki/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-loki/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-loki/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-loki/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include "common.h"
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/aspenite.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/aspenite.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/aspenite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/aspenite.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ *  linux/arch/arm/mach-mmp/aspenite.c
+ *
+ *  Support for the Marvell PXA168-based Aspenite and Zylonite2
+ *  Development 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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+static unsigned long common_pin_config[] __initdata = {
+	/* Data Flash Interface */
+	GPIO0_DFI_D15,
+	GPIO1_DFI_D14,
+	GPIO2_DFI_D13,
+	GPIO3_DFI_D12,
+	GPIO4_DFI_D11,
+	GPIO5_DFI_D10,
+	GPIO6_DFI_D9,
+	GPIO7_DFI_D8,
+	GPIO8_DFI_D7,
+	GPIO9_DFI_D6,
+	GPIO10_DFI_D5,
+	GPIO11_DFI_D4,
+	GPIO12_DFI_D3,
+	GPIO13_DFI_D2,
+	GPIO14_DFI_D1,
+	GPIO15_DFI_D0,
+
+	/* Static Memory Controller */
+	GPIO18_SMC_nCS0,
+	GPIO34_SMC_nCS1,
+	GPIO23_SMC_nLUA,
+	GPIO25_SMC_nLLA,
+	GPIO28_SMC_RDY,
+	GPIO29_SMC_SCLK,
+	GPIO35_SMC_BE1,
+	GPIO36_SMC_BE2,
+	GPIO27_GPIO,	/* Ethernet IRQ */
+
+	/* UART1 */
+	GPIO107_UART1_RXD,
+	GPIO108_UART1_TXD,
+};
+
+static struct smc91x_platdata smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= SMC_CS1_PHYS_BASE + 0x300,
+		.end	= SMC_CS1_PHYS_BASE + 0xfffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gpio_to_irq(27),
+		.end	= gpio_to_irq(27),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+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 void __init common_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+	/* on-chip devices */
+	pxa168_add_uart(1);
+
+	/* off-chip devices */
+	platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
+	.phys_io        = APB_PHYS_BASE,
+	.boot_params    = 0x00000100,
+	.io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq       = pxa168_init_irq,
+	.timer          = &pxa168_timer,
+	.init_machine   = common_init,
+MACHINE_END
+
+MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
+	.phys_io        = APB_PHYS_BASE,
+	.boot_params    = 0x00000100,
+	.io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq       = pxa168_init_irq,
+	.timer          = &pxa168_timer,
+	.init_machine   = common_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ *  linux/arch/arm/mach-mmp/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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-apbc.h>
+#include "clock.h"
+
+static void apbc_clk_enable(struct clk *clk)
+{
+	uint32_t clk_rst;
+
+	clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
+	__raw_writel(clk_rst, clk->clk_rst);
+}
+
+static void apbc_clk_disable(struct clk *clk)
+{
+	__raw_writel(0, clk->clk_rst);
+}
+
+struct clkops apbc_clk_ops = {
+	.enable		= apbc_clk_enable,
+	.disable	= apbc_clk_disable,
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (clk->enabled++ == 0)
+		clk->ops->enable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	WARN_ON(clk->enabled == 0);
+
+	spin_lock_irqsave(&clocks_lock, flags);
+	if (--clk->enabled == 0)
+		clk->ops->disable(clk);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	unsigned long rate;
+
+	if (clk->ops->getrate)
+		rate = clk->ops->getrate(clk);
+	else
+		rate = clk->rate;
+
+	return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clks_register(struct clk_lookup *clks, size_t num)
+{
+	int i;
+
+	for (i = 0; i < num; i++)
+		clkdev_add(&clks[i]);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ *  linux/arch/arm/mach-mmp/clock.h
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <asm/clkdev.h>
+
+struct clkops {
+	void			(*enable)(struct clk *);
+	void			(*disable)(struct clk *);
+	unsigned long		(*getrate)(struct clk *);
+};
+
+struct clk {
+	const struct clkops	*ops;
+
+	void __iomem	*clk_rst;	/* clock reset control register */
+	int		fnclksel;	/* functional clock select (APBC) */
+	uint32_t	enable_val;	/* value for clock enable (APMU) */
+	unsigned long	rate;
+	int		enabled;
+};
+
+extern struct clkops apbc_clk_ops;
+
+#define APBC_CLK(_name, _reg, _fnclksel, _rate)			\
+struct clk clk_##_name = {					\
+		.clk_rst	= (void __iomem *)APBC_##_reg,	\
+		.fnclksel	= _fnclksel,			\
+		.rate		= _rate,			\
+		.ops		= &apbc_clk_ops,		\
+}
+
+#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops)	\
+struct clk clk_##_name = {					\
+		.clk_rst	= (void __iomem *)APBC_##_reg,	\
+		.fnclksel	= _fnclksel,			\
+		.rate		= _rate,			\
+		.ops		= _ops,				\
+}
+
+#define APMU_CLK(_name, _reg, _eval, _rate)			\
+struct clk clk_##_name = {					\
+		.clk_rst	= (void __iomem *)APMU_##_reg,	\
+		.enable_val	= _eval,			\
+		.rate		= _rate,			\
+		.ops		= &apmu_clk_ops,		\
+}
+
+#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops)		\
+struct clk clk_##_name = {					\
+		.clk_rst	= (void __iomem *)APMU_##_reg,	\
+		.enable_val	= _eval,			\
+		.rate		= _rate,			\
+		.ops		= _ops,				\
+}
+
+#define INIT_CLKREG(_clk, _devname, _conname)			\
+	{							\
+		.clk		= _clk,				\
+		.dev_id		= _devname,			\
+		.con_id		= _conname,			\
+	}
+
+extern struct clk clk_pxa168_gpio;
+extern struct clk clk_pxa168_timers;
+
+extern void clks_register(struct clk_lookup *, size_t);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ *  linux/arch/arm/mach-mmp/common.c
+ *
+ *  Code common to PXA168 processor lines
+ *
+ * This program is free software; you can 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 <asm/page.h>
+#include <asm/mach/map.h>
+#include <mach/addr-map.h>
+
+#include "common.h"
+
+static struct map_desc standard_io_desc[] __initdata = {
+	{
+		.pfn		= __phys_to_pfn(APB_PHYS_BASE),
+		.virtual	= APB_VIRT_BASE,
+		.length		= APB_PHYS_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.pfn		= __phys_to_pfn(AXI_PHYS_BASE),
+		.virtual	= AXI_VIRT_BASE,
+		.length		= AXI_PHYS_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init pxa_map_io(void)
+{
+	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/common.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
+
+struct sys_timer;
+
+extern void timer_init(int irq);
+
+extern struct sys_timer pxa168_timer;
+extern struct sys_timer pxa910_timer;
+extern void __init pxa168_init_irq(void);
+extern void __init pxa910_init_irq(void);
+
+extern void __init icu_init_irq(void);
+extern void __init pxa_map_io(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-mmp/devices.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/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <mach/devices.h>
+
+int __init pxa_register_device(struct pxa_device_desc *desc,
+				void *data, size_t size)
+{
+	struct platform_device *pdev;
+	struct resource res[2 + MAX_RESOURCE_DMA];
+	int i, ret = 0, nres = 0;
+
+	pdev = platform_device_alloc(desc->drv_name, desc->id);
+	if (pdev == NULL)
+		return -ENOMEM;
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+	memset(res, 0, sizeof(res));
+
+	if (desc->start != -1ul && desc->size > 0) {
+		res[nres].start	= desc->start;
+		res[nres].end	= desc->start + desc->size - 1;
+		res[nres].flags	= IORESOURCE_MEM;
+		nres++;
+	}
+
+	if (desc->irq != NO_IRQ) {
+		res[nres].start	= desc->irq;
+		res[nres].end	= desc->irq;
+		res[nres].flags	= IORESOURCE_IRQ;
+		nres++;
+	}
+
+	for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
+		if (desc->dma[i] == 0)
+			break;
+
+		res[nres].start	= desc->dma[i];
+		res[nres].end	= desc->dma[i];
+		res[nres].flags	= IORESOURCE_DMA;
+	}
+
+	ret = platform_device_add_resources(pdev, res, nres);
+	if (ret) {
+		platform_device_put(pdev);
+		return ret;
+	}
+
+	if (data && size) {
+		ret = platform_device_add_data(pdev, data, size);
+		if (ret) {
+			platform_device_put(pdev);
+			return ret;
+		}
+	}
+
+	return platform_device_add(pdev);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/addr-map.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/addr-map.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/addr-map.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/addr-map.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/addr-map.h
+ *
+ *   Common address map 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_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/* APB - Application Subsystem Peripheral Bus
+ *
+ * NOTE: the DMA controller registers are actually on the AXI fabric #1
+ * slave port to AHB/APB bridge, due to its close relationship to those
+ * peripherals on APB, let's count it into the ABP mapping area.
+ */
+#define APB_PHYS_BASE		0xd4000000
+#define APB_VIRT_BASE		0xfe000000
+#define APB_PHYS_SIZE		0x00200000
+
+#define AXI_PHYS_BASE		0xd4200000
+#define AXI_VIRT_BASE		0xfe200000
+#define AXI_PHYS_SIZE		0x00200000
+
+/* Static Memory Controller - Chip Select 0 and 1 */
+#define SMC_CS0_PHYS_BASE	0x80000000
+#define SMC_CS0_PHYS_SIZE	0x10000000
+#define SMC_CS1_PHYS_BASE	0x90000000
+#define SMC_CS1_PHYS_SIZE	0x10000000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/clkdev.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/clkdev.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/clkdev.h	2009-06-09 23:05:27.000000000 -0400
@@ -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 /* __ASM_MACH_CLKDEV_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/cputype.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/cputype.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/cputype.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/cputype.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+#ifndef __ASM_MACH_CPUTYPE_H
+#define __ASM_MACH_CPUTYPE_H
+
+#include <asm/cputype.h>
+
+/*
+ *  CPU   Stepping   OLD_ID       CPU_ID      CHIP_ID
+ *
+ * PXA168    A0    0x41159263   0x56158400   0x00A0A333
+ * PXA910    Y0    0x41159262   0x56158000   0x00F0C910
+ */
+
+#ifdef CONFIG_CPU_PXA168
+#  define __cpu_is_pxa168(id)	\
+	({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
+#else
+#  define __cpu_is_pxa168(id)	(0)
+#endif
+
+#ifdef CONFIG_CPU_PXA910
+#  define __cpu_is_pxa910(id)	\
+	({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; })
+#else
+#  define __cpu_is_pxa910(id)	(0)
+#endif
+
+#define cpu_is_pxa168()		({ __cpu_is_pxa168(read_cpuid_id()); })
+#define cpu_is_pxa910()		({ __cpu_is_pxa910(read_cpuid_id()); })
+
+#endif /* __ASM_MACH_CPUTYPE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/debug-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/* arch/arm/mach-mmp/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copied from arch/arm/mach-pxa/include/mach/debug.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/addr-map.h>
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1				@ MMU enabled?
+		ldreq	\rx, =APB_PHYS_BASE		@ physical
+		ldrne	\rx, =APB_VIRT_BASE		@ virtual
+		orr	\rx, \rx, #0x00017000
+		.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/devices.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/devices.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/devices.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+#include <linux/types.h>
+
+#define MAX_RESOURCE_DMA	2
+
+/* structure for describing the on-chip devices */
+struct pxa_device_desc {
+	const char	*dev_name;
+	const char	*drv_name;
+	int		id;
+	int		irq;
+	unsigned long	start;
+	unsigned long	size;
+	int		dma[MAX_RESOURCE_DMA];
+};
+
+#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
+struct pxa_device_desc pxa168_device_##_name __initdata = {		\
+	.dev_name	= "pxa168-" #_name,				\
+	.drv_name	= _drv,						\
+	.id		= _id,						\
+	.irq		= IRQ_PXA168_##_irq,				\
+	.start		= _start,					\
+	.size		= _size,					\
+	.dma		= { _dma },					\
+};
+
+#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
+struct pxa_device_desc pxa910_device_##_name __initdata = {		\
+	.dev_name	= "pxa910-" #_name,				\
+	.drv_name	= _drv,						\
+	.id		= _id,						\
+	.irq		= IRQ_PXA910_##_irq,				\
+	.start		= _start,					\
+	.size		= _size,					\
+	.dma		= { _dma },					\
+};
+extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/dma.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/dma.h
+ */
+
+#ifndef __ASM_MACH_DMA_H
+#define __ASM_MACH_DMA_H
+
+#include <mach/addr-map.h>
+
+#define DMAC_REGS_VIRT	(APB_VIRT_BASE + 0x00000)
+
+#include <plat/dma.h>
+#endif /* __ASM_MACH_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/entry-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/regs-icu.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =ICU_AP_IRQ_SEL_INT_NUM
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\tmp, [\base, #0]
+	and	\irqnr, \tmp, #0x3f
+	tst	\tmp, #(1 << 6)
+	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#include <mach/addr-map.h>
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define GPIO_REGS_VIRT	(APB_VIRT_BASE + 0x19000)
+
+#define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x)	(*((volatile u32 *)(GPIO_REGS_VIRT + (x))))
+
+#define NR_BUILTIN_GPIO	(128)
+
+#define gpio_to_bank(gpio)	((gpio) >> 5)
+#define gpio_to_irq(gpio)	(IRQ_GPIO_START + (gpio))
+#define irq_to_gpio(irq)	((irq) - IRQ_GPIO_START)
+
+
+#define __gpio_is_inverted(gpio)	(0)
+#define __gpio_is_occupied(gpio)	(0)
+
+/* NOTE: these macros are defined here to make optimization of
+ * gpio_{get,set}_value() to work when 'gpio' is a constant.
+ * Usage of these macros otherwise is no longer recommended,
+ * use generic GPIO API whenever possible.
+ */
+#define GPIO_bit(gpio)	(1 << ((gpio) & 0x1f))
+
+#define GPLR(x)		GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x00)
+#define GPDR(x)		GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x0c)
+#define GPSR(x)		GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x18)
+#define GPCR(x)		GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x24)
+
+#include <plat/gpio.h>
+#endif /* __ASM_MACH_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/io.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/io.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/io.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_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 /* __ASM_MACH_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,119 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+/*
+ * Interrupt numbers for PXA168
+ */
+#define IRQ_PXA168_NONE			(-1)
+#define IRQ_PXA168_SSP3			0
+#define IRQ_PXA168_SSP2			1
+#define IRQ_PXA168_SSP1			2
+#define IRQ_PXA168_SSP0			3
+#define IRQ_PXA168_PMIC_INT		4
+#define IRQ_PXA168_RTC_INT		5
+#define IRQ_PXA168_RTC_ALARM		6
+#define IRQ_PXA168_TWSI0		7
+#define IRQ_PXA168_GPU			8
+#define IRQ_PXA168_KEYPAD		9
+#define IRQ_PXA168_ONEWIRE		12
+#define IRQ_PXA168_TIMER1		13
+#define IRQ_PXA168_TIMER2		14
+#define IRQ_PXA168_TIMER3		15
+#define IRQ_PXA168_CMU			16
+#define IRQ_PXA168_SSP4			17
+#define IRQ_PXA168_MSP_WAKEUP		19
+#define IRQ_PXA168_CF_WAKEUP		20
+#define IRQ_PXA168_XD_WAKEUP		21
+#define IRQ_PXA168_MFU			22
+#define IRQ_PXA168_MSP			23
+#define IRQ_PXA168_CF			24
+#define IRQ_PXA168_XD			25
+#define IRQ_PXA168_DDR_INT		26
+#define IRQ_PXA168_UART1		27
+#define IRQ_PXA168_UART2		28
+#define IRQ_PXA168_WDT			35
+#define IRQ_PXA168_FRQ_CHANGE		38
+#define IRQ_PXA168_SDH1			39
+#define IRQ_PXA168_SDH2			40
+#define IRQ_PXA168_LCD			41
+#define IRQ_PXA168_CI			42
+#define IRQ_PXA168_USB1			44
+#define IRQ_PXA168_NAND			45
+#define IRQ_PXA168_HIFI_DMA		46
+#define IRQ_PXA168_DMA_INT0		47
+#define IRQ_PXA168_DMA_INT1		48
+#define IRQ_PXA168_GPIOX		49
+#define IRQ_PXA168_USB2			51
+#define IRQ_PXA168_AC97			57
+#define IRQ_PXA168_TWSI1		58
+#define IRQ_PXA168_PMU			60
+#define IRQ_PXA168_SM_INT		63
+
+/*
+ * Interrupt numbers for PXA910
+ */
+#define IRQ_PXA910_AIRQ			0
+#define IRQ_PXA910_SSP3			1
+#define IRQ_PXA910_SSP2			2
+#define IRQ_PXA910_SSP1			3
+#define IRQ_PXA910_PMIC_INT		4
+#define IRQ_PXA910_RTC_INT		5
+#define IRQ_PXA910_RTC_ALARM		6
+#define IRQ_PXA910_TWSI0		7
+#define IRQ_PXA910_GPU			8
+#define IRQ_PXA910_KEYPAD		9
+#define IRQ_PXA910_ROTARY		10
+#define IRQ_PXA910_TRACKBALL		11
+#define IRQ_PXA910_ONEWIRE		12
+#define IRQ_PXA910_AP1_TIMER1		13
+#define IRQ_PXA910_AP1_TIMER2		14
+#define IRQ_PXA910_AP1_TIMER3		15
+#define IRQ_PXA910_IPC_AP0		16
+#define IRQ_PXA910_IPC_AP1		17
+#define IRQ_PXA910_IPC_AP2		18
+#define IRQ_PXA910_IPC_AP3		19
+#define IRQ_PXA910_IPC_AP4		20
+#define IRQ_PXA910_IPC_CP0		21
+#define IRQ_PXA910_IPC_CP1		22
+#define IRQ_PXA910_IPC_CP2		23
+#define IRQ_PXA910_IPC_CP3		24
+#define IRQ_PXA910_IPC_CP4		25
+#define IRQ_PXA910_L2_DDR		26
+#define IRQ_PXA910_UART2		27
+#define IRQ_PXA910_UART3		28
+#define IRQ_PXA910_AP2_TIMER1		29
+#define IRQ_PXA910_AP2_TIMER2		30
+#define IRQ_PXA910_CP2_TIMER1		31
+#define IRQ_PXA910_CP2_TIMER2		32
+#define IRQ_PXA910_CP2_TIMER3		33
+#define IRQ_PXA910_GSSP			34
+#define IRQ_PXA910_CP2_WDT		35
+#define IRQ_PXA910_MAIN_PMU		36
+#define IRQ_PXA910_CP_FREQ_CHG		37
+#define IRQ_PXA910_AP_FREQ_CHG		38
+#define IRQ_PXA910_MMC			39
+#define IRQ_PXA910_AEU			40
+#define IRQ_PXA910_LCD			41
+#define IRQ_PXA910_CCIC			42
+#define IRQ_PXA910_IRE			43
+#define IRQ_PXA910_USB1			44
+#define IRQ_PXA910_NAND			45
+#define IRQ_PXA910_HIFI_DMA		46
+#define IRQ_PXA910_DMA_INT0		47
+#define IRQ_PXA910_DMA_INT1		48
+#define IRQ_PXA910_AP_GPIO		49
+#define IRQ_PXA910_AP2_TIMER3		50
+#define IRQ_PXA910_USB2			51
+#define IRQ_PXA910_TWSI1		54
+#define IRQ_PXA910_CP_GPIO		55
+#define IRQ_PXA910_UART1		59	/* Slow UART */
+#define IRQ_PXA910_AP_PMU		60
+#define IRQ_PXA910_SM_INT		63	/* from PinMux */
+
+#define IRQ_GPIO_START			64
+#define IRQ_GPIO_NUM			128
+#define IRQ_GPIO(x)			(IRQ_GPIO_START + (x))
+
+#define NR_IRQS		(IRQ_GPIO_START + IRQ_GPIO_NUM)
+
+#endif /* __ASM_MACH_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/memory.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PHYS_OFFSET	UL(0x00000000)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_MFP_H
+#define __ASM_MACH_MFP_H
+
+#include <plat/mfp.h>
+
+/*
+ * NOTE: the MFPR register bit definitions on PXA168 processor lines are a
+ * bit different from those on PXA3xx.  Bit [7:10] are now reserved, which
+ * were SLEEP_OE_N, SLEEP_DATA, SLEEP_SEL and the LSB of DRIVE bits.
+ *
+ * To cope with this difference and re-use the pxa3xx mfp code as much as
+ * possible, we make the following compromise:
+ *
+ * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
+ * 2. DRIVE strength definitions redefined to include the reserved bit
+ *    - the reserved bit differs between pxa168 and pxa910, and the
+ *      MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h
+ * 3. Override MFP_CFG() and MFP_CFG_DRV()
+ * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
+ */
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+#undef MFP_CFG_LPM
+#undef MFP_CFG_X
+#undef MFP_CFG_DEFAULT
+
+#define MFP_CFG(pin, af)		\
+	(MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv)	\
+	(MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+#endif /* __ASM_MACH_MFP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa168.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,263 @@
+#ifndef __ASM_MACH_MFP_PXA168_H
+#define __ASM_MACH_MFP_PXA168_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW	(0x0 << 13)
+#define MFP_DRIVE_SLOW		(0x1 << 13)
+#define MFP_DRIVE_MEDIUM	(0x2 << 13)
+#define MFP_DRIVE_FAST		(0x3 << 13)
+
+/* GPIO */
+#define GPIO0_GPIO		MFP_CFG(GPIO0, AF5)
+#define GPIO1_GPIO		MFP_CFG(GPIO1, AF5)
+#define GPIO2_GPIO		MFP_CFG(GPIO2, AF5)
+#define GPIO3_GPIO		MFP_CFG(GPIO3, AF5)
+#define GPIO4_GPIO		MFP_CFG(GPIO4, AF5)
+#define GPIO5_GPIO		MFP_CFG(GPIO5, AF5)
+#define GPIO6_GPIO		MFP_CFG(GPIO6, AF5)
+#define GPIO7_GPIO		MFP_CFG(GPIO7, AF5)
+#define GPIO8_GPIO		MFP_CFG(GPIO8, AF5)
+#define GPIO9_GPIO		MFP_CFG(GPIO9, AF5)
+#define GPIO10_GPIO		MFP_CFG(GPIO10, AF5)
+#define GPIO11_GPIO		MFP_CFG(GPIO11, AF5)
+#define GPIO12_GPIO		MFP_CFG(GPIO12, AF5)
+#define GPIO13_GPIO		MFP_CFG(GPIO13, AF5)
+#define GPIO14_GPIO		MFP_CFG(GPIO14, AF5)
+#define GPIO15_GPIO		MFP_CFG(GPIO15, AF5)
+#define GPIO16_GPIO		MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO		MFP_CFG(GPIO17, AF5)
+#define GPIO18_GPIO		MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO		MFP_CFG(GPIO19, AF5)
+#define GPIO20_GPIO		MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO		MFP_CFG(GPIO21, AF5)
+#define GPIO22_GPIO		MFP_CFG(GPIO22, AF5)
+#define GPIO23_GPIO		MFP_CFG(GPIO23, AF5)
+#define GPIO24_GPIO		MFP_CFG(GPIO24, AF5)
+#define GPIO25_GPIO		MFP_CFG(GPIO25, AF5)
+#define GPIO26_GPIO		MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO		MFP_CFG(GPIO27, AF5)
+#define GPIO28_GPIO		MFP_CFG(GPIO28, AF5)
+#define GPIO29_GPIO		MFP_CFG(GPIO29, AF5)
+#define GPIO30_GPIO		MFP_CFG(GPIO30, AF5)
+#define GPIO31_GPIO		MFP_CFG(GPIO31, AF5)
+#define GPIO32_GPIO		MFP_CFG(GPIO32, AF5)
+#define GPIO33_GPIO		MFP_CFG(GPIO33, AF5)
+#define GPIO34_GPIO		MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO		MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO		MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO		MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO		MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO		MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO		MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO		MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO		MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO		MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO		MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO		MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO		MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO		MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO		MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO		MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO		MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO		MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO		MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO		MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO		MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO		MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO		MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO		MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO		MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO		MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO		MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO		MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO		MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO		MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO		MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO		MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO		MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO		MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO		MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO		MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO		MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO		MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO		MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO		MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO		MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO		MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO		MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO		MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO		MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO		MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO		MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO		MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO		MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO		MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO		MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO		MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO		MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO		MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO		MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO		MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO		MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO		MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO		MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO		MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO		MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO		MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO		MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO		MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO		MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO		MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO		MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO		MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO		MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO		MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO		MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO		MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO		MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO		MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO		MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO		MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO		MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO		MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO		MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO		MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO		MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO		MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO		MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO		MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO		MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO		MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO		MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO		MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO		MFP_CFG(GPIO122, AF0)
+
+/* DFI */
+#define GPIO0_DFI_D15		MFP_CFG(GPIO0, AF0)
+#define GPIO1_DFI_D14		MFP_CFG(GPIO1, AF0)
+#define GPIO2_DFI_D13		MFP_CFG(GPIO2, AF0)
+#define GPIO3_DFI_D12		MFP_CFG(GPIO3, AF0)
+#define GPIO4_DFI_D11		MFP_CFG(GPIO4, AF0)
+#define GPIO5_DFI_D10		MFP_CFG(GPIO5, AF0)
+#define GPIO6_DFI_D9		MFP_CFG(GPIO6, AF0)
+#define GPIO7_DFI_D8		MFP_CFG(GPIO7, AF0)
+#define GPIO8_DFI_D7		MFP_CFG(GPIO8, AF0)
+#define GPIO9_DFI_D6		MFP_CFG(GPIO9, AF0)
+#define GPIO10_DFI_D5		MFP_CFG(GPIO10, AF0)
+#define GPIO11_DFI_D4		MFP_CFG(GPIO11, AF0)
+#define GPIO12_DFI_D3		MFP_CFG(GPIO12, AF0)
+#define GPIO13_DFI_D2		MFP_CFG(GPIO13, AF0)
+#define GPIO14_DFI_D1		MFP_CFG(GPIO14, AF0)
+#define GPIO15_DFI_D0		MFP_CFG(GPIO15, AF0)
+
+#define GPIO30_DFI_ADDR0	MFP_CFG(GPIO30, AF0)
+#define GPIO31_DFI_ADDR1	MFP_CFG(GPIO31, AF0)
+#define GPIO32_DFI_ADDR2	MFP_CFG(GPIO32, AF0)
+#define GPIO33_DFI_ADDR3	MFP_CFG(GPIO33, AF0)
+
+/* NAND */
+#define GPIO16_ND_nCS0		MFP_CFG(GPIO16, AF1)
+#define GPIO17_ND_nWE		MFP_CFG(GPIO17, AF0)
+#define GPIO21_ND_ALE		MFP_CFG(GPIO21, AF0)
+#define GPIO22_ND_CLE		MFP_CFG(GPIO22, AF0)
+#define GPIO24_ND_nRE		MFP_CFG(GPIO24, AF0)
+#define GPIO26_ND_RnB1		MFP_CFG(GPIO26, AF1)
+#define GPIO27_ND_RnB2		MFP_CFG(GPIO27, AF1)
+
+/* Static Memory Controller */
+#define GPIO18_SMC_nCS0		MFP_CFG(GPIO18, AF3)
+#define GPIO18_SMC_nCS1		MFP_CFG(GPIO18, AF2)
+#define GPIO16_SMC_nCS0		MFP_CFG(GPIO16, AF2)
+#define GPIO16_SMC_nCS1		MFP_CFG(GPIO16, AF3)
+#define GPIO19_SMC_nCS0		MFP_CFG(GPIO19, AF0)
+#define GPIO20_SMC_nCS1		MFP_CFG(GPIO20, AF2)
+#define GPIO23_SMC_nLUA		MFP_CFG(GPIO23, AF0)
+#define GPIO25_SMC_nLLA		MFP_CFG(GPIO25, AF0)
+#define GPIO27_SMC_IRQ		MFP_CFG(GPIO27, AF0)
+#define GPIO28_SMC_RDY		MFP_CFG(GPIO28, AF0)
+#define GPIO29_SMC_SCLK		MFP_CFG(GPIO29, AF0)
+#define GPIO34_SMC_nCS1		MFP_CFG(GPIO34, AF2)
+#define GPIO35_SMC_BE1		MFP_CFG(GPIO35, AF2)
+#define GPIO36_SMC_BE2		MFP_CFG(GPIO36, AF2)
+
+/* Compact Flash */
+#define GPIO19_CF_nCE1		MFP_CFG(GPIO19, AF3)
+#define GPIO20_CF_nCE2		MFP_CFG(GPIO20, AF3)
+#define GPIO23_CF_nALE		MFP_CFG(GPIO23, AF3)
+#define GPIO25_CF_nRESET	MFP_CFG(GPIO25, AF3)
+#define GPIO28_CF_RDY		MFP_CFG(GPIO28, AF3)
+#define GPIO29_CF_STSCH		MFP_CFG(GPIO29, AF3)
+#define GPIO30_CF_nREG		MFP_CFG(GPIO30, AF3)
+#define GPIO31_CF_nIOIS16	MFP_CFG(GPIO31, AF3)
+#define GPIO32_CF_nCD1		MFP_CFG(GPIO32, AF3)
+#define GPIO33_CF_nCD2		MFP_CFG(GPIO33, AF3)
+
+/* UART1 */
+#define GPIO107_UART1_TXD	MFP_CFG_DRV(GPIO107, AF1, FAST)
+#define GPIO107_UART1_RXD	MFP_CFG_DRV(GPIO107, AF2, FAST)
+#define GPIO108_UART1_RXD	MFP_CFG_DRV(GPIO108, AF1, FAST)
+#define GPIO108_UART1_TXD	MFP_CFG_DRV(GPIO108, AF2, FAST)
+#define GPIO109_UART1_CTS	MFP_CFG(GPIO109, AF1)
+#define GPIO109_UART1_RTS	MFP_CFG(GPIO109, AF2)
+#define GPIO110_UART1_RTS	MFP_CFG(GPIO110, AF1)
+#define GPIO110_UART1_CTS	MFP_CFG(GPIO110, AF2)
+#define GPIO111_UART1_RI	MFP_CFG(GPIO111, AF1)
+#define GPIO111_UART1_DSR	MFP_CFG(GPIO111, AF2)
+#define GPIO112_UART1_DTR	MFP_CFG(GPIO111, AF1)
+#define GPIO112_UART1_DCD	MFP_CFG(GPIO112, AF2)
+
+/* MMC1 */
+#define GPIO37_MMC1_DAT7	MFP_CFG(GPIO37, AF1)
+#define GPIO38_MMC1_DAT6	MFP_CFG(GPIO38, AF1)
+#define GPIO54_MMC1_DAT5	MFP_CFG(GPIO54, AF1)
+#define GPIO48_MMC1_DAT4	MFP_CFG(GPIO48, AF1)
+#define GPIO51_MMC1_DAT3	MFP_CFG(GPIO51, AF1)
+#define GPIO52_MMC1_DAT2	MFP_CFG(GPIO52, AF1)
+#define GPIO40_MMC1_DAT1	MFP_CFG(GPIO40, AF1)
+#define GPIO41_MMC1_DAT0	MFP_CFG(GPIO41, AF1)
+#define GPIO49_MMC1_CMD		MFP_CFG(GPIO49, AF1)
+#define GPIO43_MMC1_CLK		MFP_CFG(GPIO43, AF1)
+#define GPIO53_MMC1_CD		MFP_CFG(GPIO53, AF1)
+#define GPIO46_MMC1_WP		MFP_CFG(GPIO46, AF1)
+
+/* LCD */
+#define GPIO84_LCD_CS		MFP_CFG(GPIO84, AF1)
+#define GPIO60_LCD_DD0		MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCD_DD1		MFP_CFG(GPIO61, AF1)
+#define GPIO70_LCD_DD10		MFP_CFG(GPIO70, AF1)
+#define GPIO71_LCD_DD11		MFP_CFG(GPIO71, AF1)
+#define GPIO72_LCD_DD12		MFP_CFG(GPIO72, AF1)
+#define GPIO73_LCD_DD13		MFP_CFG(GPIO73, AF1)
+#define GPIO74_LCD_DD14		MFP_CFG(GPIO74, AF1)
+#define GPIO75_LCD_DD15		MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCD_DD16		MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCD_DD17		MFP_CFG(GPIO77, AF1)
+#define GPIO78_LCD_DD18		MFP_CFG(GPIO78, AF1)
+#define GPIO79_LCD_DD19		MFP_CFG(GPIO79, AF1)
+#define GPIO62_LCD_DD2		MFP_CFG(GPIO62, AF1)
+#define GPIO80_LCD_DD20		MFP_CFG(GPIO80, AF1)
+#define GPIO81_LCD_DD21		MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_DD22		MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_DD23		MFP_CFG(GPIO83, AF1)
+#define GPIO63_LCD_DD3		MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCD_DD4		MFP_CFG(GPIO64, AF1)
+#define GPIO65_LCD_DD5		MFP_CFG(GPIO65, AF1)
+#define GPIO66_LCD_DD6		MFP_CFG(GPIO66, AF1)
+#define GPIO67_LCD_DD7		MFP_CFG(GPIO67, AF1)
+#define GPIO68_LCD_DD8		MFP_CFG(GPIO68, AF1)
+#define GPIO69_LCD_DD9		MFP_CFG(GPIO69, AF1)
+#define GPIO59_LCD_DENA_BIAS	MFP_CFG(GPIO59, AF1)
+#define GPIO56_LCD_FCLK_RD	MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCD_LCLK_A0	MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCD_PCLK_WR	MFP_CFG(GPIO58, AF1)
+#define GPIO85_LCD_VSYNC	MFP_CFG(GPIO85, AF1)
+
+/* I2S */
+#define GPIO113_I2S_MCLK	MFP_CFG(GPIO113,AF6)
+#define GPIO114_I2S_FRM		MFP_CFG(GPIO114,AF1)
+#define GPIO115_I2S_BCLK	MFP_CFG(GPIO115,AF1)
+#define GPIO116_I2S_RXD		MFP_CFG(GPIO116,AF2)
+#define GPIO117_I2S_TXD		MFP_CFG(GPIO117,AF2)
+
+#endif /* __ASM_MACH_MFP_PXA168_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa910.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa910.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/mfp-pxa910.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,162 @@
+#ifndef __ASM_MACH_MFP_PXA910_H
+#define __ASM_MACH_MFP_PXA910_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW	(0x0 << 13)
+#define MFP_DRIVE_SLOW		(0x2 << 13)
+#define MFP_DRIVE_MEDIUM	(0x4 << 13)
+#define MFP_DRIVE_FAST		(0x8 << 13)
+
+/* UART2 */
+#define GPIO47_UART2_RXD	MFP_CFG(GPIO47, AF6)
+#define GPIO48_UART2_TXD	MFP_CFG(GPIO48, AF6)
+
+/* UART3 */
+#define GPIO31_UART3_RXD	MFP_CFG(GPIO31, AF4)
+#define GPIO32_UART3_TXD	MFP_CFG(GPIO32, AF4)
+
+/*IRDA*/
+#define GPIO51_IRDA_SHDN	MFP_CFG(GPIO51, AF0)
+
+/* SMC */
+#define SM_nCS0_nCS0		MFP_CFG(SM_nCS0, AF0)
+#define SM_ADV_SM_ADV		MFP_CFG(SM_ADV, AF0)
+#define SM_SCLK_SM_SCLK		MFP_CFG(SM_SCLK, AF0)
+#define SM_SCLK_SM_SCLK		MFP_CFG(SM_SCLK, AF0)
+#define SM_BE0_SM_BE0		MFP_CFG(SM_BE0, AF1)
+#define SM_BE1_SM_BE1		MFP_CFG(SM_BE1, AF1)
+
+/* I2C */
+#define GPIO53_CI2C_SCL		MFP_CFG(GPIO53, AF2)
+#define GPIO54_CI2C_SDA		MFP_CFG(GPIO54, AF2)
+
+/* SSP1 (I2S) */
+#define GPIO24_SSP1_SDATA_IN	MFP_CFG_DRV(GPIO24, AF1, MEDIUM)
+#define GPIO21_SSP1_BITCLK	MFP_CFG_DRV(GPIO21, AF1, MEDIUM)
+#define GPIO20_SSP1_SYSCLK	MFP_CFG_DRV(GPIO20, AF1, MEDIUM)
+#define GPIO22_SSP1_SYNC	MFP_CFG_DRV(GPIO22, AF1, MEDIUM)
+#define GPIO23_SSP1_DATA_OUT	MFP_CFG_DRV(GPIO23, AF1, MEDIUM)
+#define GPIO124_MN_CLK_OUT	MFP_CFG_DRV(GPIO124, AF1, MEDIUM)
+#define GPIO123_CLK_REQ		MFP_CFG_DRV(GPIO123, AF0, MEDIUM)
+
+/* DFI */
+#define DF_IO0_ND_IO0		MFP_CFG(DF_IO0, AF0)
+#define DF_IO1_ND_IO1		MFP_CFG(DF_IO1, AF0)
+#define DF_IO2_ND_IO2		MFP_CFG(DF_IO2, AF0)
+#define DF_IO3_ND_IO3		MFP_CFG(DF_IO3, AF0)
+#define DF_IO4_ND_IO4		MFP_CFG(DF_IO4, AF0)
+#define DF_IO5_ND_IO5		MFP_CFG(DF_IO5, AF0)
+#define DF_IO6_ND_IO6		MFP_CFG(DF_IO6, AF0)
+#define DF_IO7_ND_IO7		MFP_CFG(DF_IO7, AF0)
+#define DF_IO8_ND_IO8		MFP_CFG(DF_IO8, AF0)
+#define DF_IO9_ND_IO9		MFP_CFG(DF_IO9, AF0)
+#define DF_IO10_ND_IO10		MFP_CFG(DF_IO10, AF0)
+#define DF_IO11_ND_IO11		MFP_CFG(DF_IO11, AF0)
+#define DF_IO12_ND_IO12		MFP_CFG(DF_IO12, AF0)
+#define DF_IO13_ND_IO13		MFP_CFG(DF_IO13, AF0)
+#define DF_IO14_ND_IO14		MFP_CFG(DF_IO14, AF0)
+#define DF_IO15_ND_IO15		MFP_CFG(DF_IO15, AF0)
+#define DF_nCS0_SM_nCS2_nCS0	MFP_CFG(DF_nCS0_SM_nCS2, AF0)
+#define DF_ALE_SM_WEn_ND_ALE	MFP_CFG(DF_ALE_SM_WEn, AF1)
+#define DF_CLE_SM_OEn_ND_CLE	MFP_CFG(DF_CLE_SM_OEn, AF0)
+#define DF_WEn_DF_WEn		MFP_CFG(DF_WEn, AF1)
+#define DF_REn_DF_REn		MFP_CFG(DF_REn, AF1)
+#define DF_RDY0_DF_RDY0		MFP_CFG(DF_RDY0, AF0)
+
+/*keypad*/
+#define GPIO00_KP_MKIN0		MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0	MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1		MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1	MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2		MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2	MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3		MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3	MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4		MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4	MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5		MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5	MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6		MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6	MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7		MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7	MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0		MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1		MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2		MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3		MFP_CFG(GPIO19, AF1)
+
+/* LCD */
+#define GPIO81_LCD_FCLK		MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_LCLK		MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_PCLK		MFP_CFG(GPIO83, AF1)
+#define GPIO84_LCD_DENA		MFP_CFG(GPIO84, AF1)
+#define GPIO85_LCD_DD0		MFP_CFG(GPIO85, AF1)
+#define GPIO86_LCD_DD1		MFP_CFG(GPIO86, AF1)
+#define GPIO87_LCD_DD2		MFP_CFG(GPIO87, AF1)
+#define GPIO88_LCD_DD3		MFP_CFG(GPIO88, AF1)
+#define GPIO89_LCD_DD4		MFP_CFG(GPIO89, AF1)
+#define GPIO90_LCD_DD5		MFP_CFG(GPIO90, AF1)
+#define GPIO91_LCD_DD6		MFP_CFG(GPIO91, AF1)
+#define GPIO92_LCD_DD7		MFP_CFG(GPIO92, AF1)
+#define GPIO93_LCD_DD8		MFP_CFG(GPIO93, AF1)
+#define GPIO94_LCD_DD9		MFP_CFG(GPIO94, AF1)
+#define GPIO95_LCD_DD10		MFP_CFG(GPIO95, AF1)
+#define GPIO96_LCD_DD11		MFP_CFG(GPIO96, AF1)
+#define GPIO97_LCD_DD12		MFP_CFG(GPIO97, AF1)
+#define GPIO98_LCD_DD13		MFP_CFG(GPIO98, AF1)
+#define GPIO100_LCD_DD14	MFP_CFG(GPIO100, AF1)
+#define GPIO101_LCD_DD15	MFP_CFG(GPIO101, AF1)
+#define GPIO102_LCD_DD16	MFP_CFG(GPIO102, AF1)
+#define GPIO103_LCD_DD17	MFP_CFG(GPIO103, AF1)
+#define GPIO104_LCD_DD18	MFP_CFG(GPIO104, AF1)
+#define GPIO105_LCD_DD19	MFP_CFG(GPIO105, AF1)
+#define GPIO106_LCD_DD20	MFP_CFG(GPIO106, AF1)
+#define GPIO107_LCD_DD21	MFP_CFG(GPIO107, AF1)
+#define GPIO108_LCD_DD22	MFP_CFG(GPIO108, AF1)
+#define GPIO109_LCD_DD23	MFP_CFG(GPIO109, AF1)
+
+#define GPIO104_LCD_SPIDOUT	MFP_CFG(GPIO104, AF3)
+#define GPIO105_LCD_SPIDIN	MFP_CFG(GPIO105, AF3)
+#define GPIO107_LCD_CS1 	MFP_CFG(GPIO107, AF3)
+#define GPIO108_LCD_DCLK	MFP_CFG(GPIO108, AF3)
+
+#define GPIO106_LCD_RESET	MFP_CFG(GPIO106, AF0)
+
+/*smart panel*/
+#define GPIO82_LCD_A0		MFP_CFG(GPIO82, AF0)
+#define GPIO83_LCD_WR		MFP_CFG(GPIO83, AF0)
+#define GPIO103_LCD_CS		MFP_CFG(GPIO103, AF0)
+
+/*1wire*/
+#define GPIO106_1WIRE		MFP_CFG(GPIO106, AF3)
+
+/*CCIC*/
+#define GPIO67_CCIC_IN7		MFP_CFG_DRV(GPIO67, AF1, MEDIUM)
+#define GPIO68_CCIC_IN6		MFP_CFG_DRV(GPIO68, AF1, MEDIUM)
+#define GPIO69_CCIC_IN5		MFP_CFG_DRV(GPIO69, AF1, MEDIUM)
+#define GPIO70_CCIC_IN4		MFP_CFG_DRV(GPIO70, AF1, MEDIUM)
+#define GPIO71_CCIC_IN3		MFP_CFG_DRV(GPIO71, AF1, MEDIUM)
+#define GPIO72_CCIC_IN2		MFP_CFG_DRV(GPIO72, AF1, MEDIUM)
+#define GPIO73_CCIC_IN1		MFP_CFG_DRV(GPIO73, AF1, MEDIUM)
+#define GPIO74_CCIC_IN0		MFP_CFG_DRV(GPIO74, AF1, MEDIUM)
+#define GPIO75_CAM_HSYNC	MFP_CFG_DRV(GPIO75, AF1, MEDIUM)
+#define GPIO76_CAM_VSYNC	MFP_CFG_DRV(GPIO76, AF1, MEDIUM)
+#define GPIO77_CAM_MCLK		MFP_CFG_DRV(GPIO77, AF1, MEDIUM)
+#define GPIO78_CAM_PCLK		MFP_CFG_DRV(GPIO78, AF1, MEDIUM)
+
+/* MMC1 */
+#define MMC1_DAT7_MMC1_DAT7	MFP_CFG_DRV(MMC1_DAT7, AF0, MEDIUM)
+#define MMC1_DAT6_MMC1_DAT6	MFP_CFG_DRV(MMC1_DAT6, AF0, MEDIUM)
+#define MMC1_DAT5_MMC1_DAT5	MFP_CFG_DRV(MMC1_DAT5, AF0, MEDIUM)
+#define MMC1_DAT4_MMC1_DAT4	MFP_CFG_DRV(MMC1_DAT4, AF0, MEDIUM)
+#define MMC1_DAT3_MMC1_DAT3	MFP_CFG_DRV(MMC1_DAT3, AF0, MEDIUM)
+#define MMC1_DAT2_MMC1_DAT2	MFP_CFG_DRV(MMC1_DAT2, AF0, MEDIUM)
+#define MMC1_DAT1_MMC1_DAT1	MFP_CFG_DRV(MMC1_DAT1, AF0, MEDIUM)
+#define MMC1_DAT0_MMC1_DAT0	MFP_CFG_DRV(MMC1_DAT0, AF0, MEDIUM)
+#define MMC1_CMD_MMC1_CMD	MFP_CFG_DRV(MMC1_CMD, AF0, MEDIUM)
+#define MMC1_CLK_MMC1_CLK	MFP_CFG_DRV(MMC1_CLK, AF0, MEDIUM)
+#define MMC1_CD_MMC1_CD		MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
+#define MMC1_WP_MMC1_WP		MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
+
+#endif /* __ASM_MACH MFP_PXA910_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/pxa168.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_PXA168_H
+#define __ASM_MACH_PXA168_H
+
+#include <mach/devices.h>
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+
+static inline int pxa168_add_uart(int id)
+{
+	struct pxa_device_desc *d = NULL;
+
+	switch (id) {
+	case 1: d = &pxa168_device_uart1; break;
+	case 2: d = &pxa168_device_uart2; break;
+	}
+
+	if (d == NULL)
+		return -EINVAL;
+
+	return pxa_register_device(d, NULL, 0);
+}
+#endif /* __ASM_MACH_PXA168_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/pxa910.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_PXA910_H
+#define __ASM_MACH_PXA910_H
+
+#include <mach/devices.h>
+
+extern struct pxa_device_desc pxa910_device_uart1;
+extern struct pxa_device_desc pxa910_device_uart2;
+
+static inline int pxa910_add_uart(int id)
+{
+	struct pxa_device_desc *d = NULL;
+
+	switch (id) {
+	case 1: d = &pxa910_device_uart1; break;
+	case 2: d = &pxa910_device_uart2; break;
+	}
+
+	if (d == NULL)
+		return -EINVAL;
+
+	return pxa_register_device(d, NULL, 0);
+}
+#endif /* __ASM_MACH_PXA910_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-apbc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apbc.h
+ *
+ *   Application Peripheral Bus Clock Unit
+ *
+ * This program is free software; you can 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_MACH_REGS_APBC_H
+#define __ASM_MACH_REGS_APBC_H
+
+#include <mach/addr-map.h>
+
+#define APBC_VIRT_BASE	(APB_VIRT_BASE + 0x015000)
+#define APBC_REG(x)	(APBC_VIRT_BASE + (x))
+
+/*
+ * APB clock register offsets for PXA168
+ */
+#define APBC_PXA168_UART1	APBC_REG(0x000)
+#define APBC_PXA168_UART2	APBC_REG(0x004)
+#define APBC_PXA168_GPIO	APBC_REG(0x008)
+#define APBC_PXA168_PWM0	APBC_REG(0x00c)
+#define APBC_PXA168_PWM1	APBC_REG(0x010)
+#define APBC_PXA168_SSP1	APBC_REG(0x01c)
+#define APBC_PXA168_SSP2	APBC_REG(0x020)
+#define APBC_PXA168_RTC		APBC_REG(0x028)
+#define APBC_PXA168_TWSI0	APBC_REG(0x02c)
+#define APBC_PXA168_KPC		APBC_REG(0x030)
+#define APBC_PXA168_TIMERS	APBC_REG(0x034)
+#define APBC_PXA168_AIB		APBC_REG(0x03c)
+#define APBC_PXA168_SW_JTAG	APBC_REG(0x040)
+#define APBC_PXA168_ONEWIRE	APBC_REG(0x048)
+#define APBC_PXA168_SSP3	APBC_REG(0x04c)
+#define APBC_PXA168_ASFAR	APBC_REG(0x050)
+#define APBC_PXA168_ASSAR	APBC_REG(0x054)
+#define APBC_PXA168_SSP4	APBC_REG(0x058)
+#define APBC_PXA168_SSP5	APBC_REG(0x05c)
+#define APBC_PXA168_TWSI1	APBC_REG(0x06c)
+#define APBC_PXA168_UART3	APBC_REG(0x070)
+#define APBC_PXA168_AC97	APBC_REG(0x084)
+
+/*
+ * APB Clock register offsets for PXA910
+ */
+#define APBC_PXA910_UART0	APBC_REG(0x000)
+#define APBC_PXA910_UART1	APBC_REG(0x004)
+#define APBC_PXA910_GPIO	APBC_REG(0x008)
+#define APBC_PXA910_PWM0	APBC_REG(0x00c)
+#define APBC_PXA910_PWM1	APBC_REG(0x010)
+#define APBC_PXA910_PWM2	APBC_REG(0x014)
+#define APBC_PXA910_PWM3	APBC_REG(0x018)
+#define APBC_PXA910_SSP1	APBC_REG(0x01c)
+#define APBC_PXA910_SSP2	APBC_REG(0x020)
+#define APBC_PXA910_IPC		APBC_REG(0x024)
+#define APBC_PXA910_TWSI0	APBC_REG(0x02c)
+#define APBC_PXA910_KPC		APBC_REG(0x030)
+#define APBC_PXA910_TIMERS	APBC_REG(0x034)
+#define APBC_PXA910_TBROT	APBC_REG(0x038)
+#define APBC_PXA910_AIB		APBC_REG(0x03c)
+#define APBC_PXA910_SW_JTAG	APBC_REG(0x040)
+#define APBC_PXA910_TIMERS1	APBC_REG(0x044)
+#define APBC_PXA910_ONEWIRE	APBC_REG(0x048)
+#define APBC_PXA910_SSP3	APBC_REG(0x04c)
+#define APBC_PXA910_ASFAR	APBC_REG(0x050)
+#define APBC_PXA910_ASSAR	APBC_REG(0x054)
+
+/* Common APB clock register bit definitions */
+#define APBC_APBCLK	(1 << 0)  /* APB Bus Clock Enable */
+#define APBC_FNCLK	(1 << 1)  /* Functional Clock Enable */
+#define APBC_RST	(1 << 2)  /* Reset Generation */
+
+/* Functional Clock Selection Mask */
+#define APBC_FNCLKSEL(x)	(((x) & 0xf) << 4)
+
+#endif /* __ASM_MACH_REGS_APBC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-apmu.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-apmu.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-apmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-apmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apmu.h
+ *
+ *   Application Subsystem Power Management Unit
+ *
+ * This program is free software; you can 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_MACH_REGS_APMU_H
+#define __ASM_MACH_REGS_APMU_H
+
+#include <mach/addr-map.h>
+
+#define APMU_VIRT_BASE	(AXI_VIRT_BASE + 0x82800)
+#define APMU_REG(x)	(APMU_VIRT_BASE + (x))
+
+/* Clock Reset Control */
+#define APMU_IRE	APMU_REG(0x048)
+#define APMU_LCD	APMU_REG(0x04c)
+#define APMU_CCIC	APMU_REG(0x050)
+#define APMU_SDH0	APMU_REG(0x054)
+#define APMU_SDH1	APMU_REG(0x058)
+#define APMU_USB	APMU_REG(0x05c)
+#define APMU_NAND	APMU_REG(0x060)
+#define APMU_DMA	APMU_REG(0x064)
+#define APMU_GEU	APMU_REG(0x068)
+#define APMU_BUS	APMU_REG(0x06c)
+
+#define APMU_FNCLK_EN	(1 << 4)
+#define APMU_AXICLK_EN	(1 << 3)
+#define APMU_FNRST_DIS	(1 << 1)
+#define APMU_AXIRST_DIS	(1 << 0)
+
+#endif /* __ASM_MACH_REGS_APMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-icu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-icu.h
+ *
+ *   Interrupt Control Unit
+ *
+ * This program is free software; you can 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_MACH_ICU_H
+#define __ASM_MACH_ICU_H
+
+#include <mach/addr-map.h>
+
+#define ICU_VIRT_BASE	(AXI_VIRT_BASE + 0x82000)
+#define ICU_REG(x)	(ICU_VIRT_BASE + (x))
+
+#define ICU_INT_CONF(n)		ICU_REG((n) << 2)
+#define ICU_INT_CONF_AP_INT	(1 << 6)
+#define ICU_INT_CONF_CP_INT	(1 << 5)
+#define ICU_INT_CONF_IRQ	(1 << 4)
+#define ICU_INT_CONF_MASK	(0xf)
+
+#define ICU_AP_FIQ_SEL_INT_NUM	ICU_REG(0x108)	/* AP FIQ Selected Interrupt */
+#define ICU_AP_IRQ_SEL_INT_NUM	ICU_REG(0x10C)	/* AP IRQ Selected Interrupt */
+#define ICU_AP_GBL_IRQ_MSK	ICU_REG(0x114)	/* AP Global Interrupt Mask */
+#define ICU_INT_STATUS_0	ICU_REG(0x128)	/* Interrupt Stuats 0 */
+#define ICU_INT_STATUS_1	ICU_REG(0x12C)	/* Interrupt Status 1 */
+
+#endif /* __ASM_MACH_ICU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-timers.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-timers.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/regs-timers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/regs-timers.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-timers.h
+ *
+ *   Timers Module
+ *
+ * This program is free software; you can 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_MACH_REGS_TIMERS_H
+#define __ASM_MACH_REGS_TIMERS_H
+
+#include <mach/addr-map.h>
+
+#define TIMERS1_VIRT_BASE	(APB_VIRT_BASE + 0x14000)
+#define TIMERS2_VIRT_BASE	(APB_VIRT_BASE + 0x16000)
+
+#define TMR_CCR		(0x0000)
+#define TMR_TN_MM(n, m)	(0x0004 + ((n) << 3) + (((n) + (m)) << 2))
+#define TMR_CR(n)	(0x0028 + ((n) << 2))
+#define TMR_SR(n)	(0x0034 + ((n) << 2))
+#define TMR_IER(n)	(0x0040 + ((n) << 2))
+#define TMR_PLVR(n)	(0x004c + ((n) << 2))
+#define TMR_PLCR(n)	(0x0058 + ((n) << 2))
+#define TMR_WMER	(0x0064)
+#define TMR_WMR		(0x0068)
+#define TMR_WVR		(0x006c)
+#define TMR_WSR		(0x0070)
+#define TMR_ICR(n)	(0x0074 + ((n) << 2))
+#define TMR_WICR	(0x0080)
+#define TMR_CER		(0x0084)
+#define TMR_CMR		(0x0088)
+#define TMR_ILR(n)	(0x008c + ((n) << 2))
+#define TMR_WCR		(0x0098)
+#define TMR_WFAR	(0x009c)
+#define TMR_WSAR	(0x00A0)
+#define TMR_CVWR(n)	(0x00A4 + ((n) << 2))
+
+#define TMR_CCR_CS_0(x)	(((x) & 0x3) << 0)
+#define TMR_CCR_CS_1(x)	(((x) & 0x7) << 2)
+#define TMR_CCR_CS_2(x)	(((x) & 0x3) << 5)
+
+#endif /* __ASM_MACH_REGS_TIMERS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/system.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_SYSTEM_H
+#define __ASM_MACH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	cpu_reset(0);
+}
+#endif /* __ASM_MACH_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/timex.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/timex.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/timex.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define CLOCK_TICK_RATE		3250000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/uncompress.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-mmp/include/mach/uncompress.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/addr-map.h>
+
+#define UART1_BASE	(APB_PHYS_BASE + 0x36000)
+#define UART2_BASE	(APB_PHYS_BASE + 0x17000)
+#define UART3_BASE	(APB_PHYS_BASE + 0x18000)
+
+static inline void putc(char c)
+{
+	volatile unsigned long *UART = (unsigned long *)UART2_BASE;
+
+	/* UART enabled? */
+	if (!(UART[UART_IER] & UART_IER_UUE))
+		return;
+
+	while (!(UART[UART_LSR] & UART_LSR_THRE))
+		barrier();
+
+	UART[UART_TX] = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/include/mach/vmalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,5 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END	0xfe000000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ *  linux/arch/arm/mach-mmp/irq.c
+ *
+ *  Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ *  Author:	Bin Yang <bin.yang@marvell.com>
+ *  Created:	Sep 30, 2008
+ *  Copyright:	Marvell International 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/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-icu.h>
+
+#include "common.h"
+
+#define IRQ_ROUTE_TO_AP		(ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ)
+
+#define PRIORITY_DEFAULT	0x1
+#define PRIORITY_NONE		0x0	/* means IRQ disabled */
+
+static void icu_mask_irq(unsigned int irq)
+{
+	__raw_writel(PRIORITY_NONE, ICU_INT_CONF(irq));
+}
+
+static void icu_unmask_irq(unsigned int irq)
+{
+	__raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+	.name	= "icu_irq",
+	.ack	= icu_mask_irq,
+	.mask	= icu_mask_irq,
+	.unmask	= icu_unmask_irq,
+};
+
+void __init icu_init_irq(void)
+{
+	int irq;
+
+	for (irq = 0; irq < 64; irq++) {
+		icu_mask_irq(irq);
+		set_irq_chip(irq, &icu_irq_chip);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+if ARCH_MMP
+
+menu "Marvell PXA168/910 Implmentations"
+
+config MACH_ASPENITE
+	bool "Marvell's PXA168 Aspenite Development Board"
+	select CPU_PXA168
+	help
+	  Say 'Y' here if you want to support the Marvell PXA168-based
+	  Aspenite Development Board.
+
+config MACH_ZYLONITE2
+	bool "Marvell's PXA168 Zylonite2 Development Board"
+	select CPU_PXA168
+	help
+	  Say 'Y' here if you want to support the Marvell PXA168-based
+	  Zylonite2 Development Board.
+
+config MACH_TAVOREVB
+	bool "Marvell's PXA910 TavorEVB Development Board"
+	select CPU_PXA910
+	help
+	  Say 'Y' here if you want to support the Marvell PXA910-based
+	  TavorEVB Development Board.
+
+config MACH_TTC_DKB
+	bool "Marvell's PXA910 TavorEVB Development Board"
+	select CPU_PXA910
+	help
+	  Say 'Y' here if you want to support the Marvell PXA910-based
+	  TTC_DKB Development Board.
+
+endmenu
+
+config CPU_PXA168
+	bool
+	select CPU_MOHAWK
+	help
+	  Select code specific to PXA168
+
+config CPU_PXA910
+	bool
+	select CPU_MOHAWK
+	help
+	  Select code specific to PXA910
+
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+#
+# Makefile for Marvell's PXA168 processors line
+#
+
+obj-y				+= common.o clock.o devices.o irq.o time.o
+
+# SoC support
+obj-$(CONFIG_CPU_PXA168)	+= pxa168.o
+obj-$(CONFIG_CPU_PXA910)	+= pxa910.o
+
+# board support
+obj-$(CONFIG_MACH_ASPENITE)	+= aspenite.o
+obj-$(CONFIG_MACH_ZYLONITE2)	+= aspenite.o
+obj-$(CONFIG_MACH_TAVOREVB)	+= tavorevb.o
+obj-$(CONFIG_MACH_TTC_DKB)	+= ttc_dkb.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Makefile.boot linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Makefile.boot
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/Makefile.boot	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+   zreladdr-y	:= 0x00008000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/pxa168.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/pxa168.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/pxa168.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/pxa168.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ *  linux/arch/arm/mach-mmp/pxa168.c
+ *
+ *  Code specific to PXA168
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/cputype.h>
+#include <mach/regs-apbc.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/devices.h>
+#include <mach/mfp.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE	(APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
+{
+	MFP_ADDR_X(GPIO0,   GPIO36,  0x04c),
+	MFP_ADDR_X(GPIO37,  GPIO55,  0x000),
+	MFP_ADDR_X(GPIO56,  GPIO123, 0x0e0),
+	MFP_ADDR_X(GPIO124, GPIO127, 0x0f4),
+
+	MFP_ADDR_END,
+};
+
+#define APMASK(i)	(GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa168_init_gpio(void)
+{
+	int i;
+
+	/* enable GPIO clock */
+	__raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO);
+
+	/* unmask GPIO edge detection for all 4 banks - APMASKx */
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xffffffff, APMASK(i));
+
+	pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL);
+}
+
+void __init pxa168_init_irq(void)
+{
+	icu_init_irq();
+	pxa168_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
+static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
+
+/* device and clock bindings */
+static struct clk_lookup pxa168_clkregs[] = {
+	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+	INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+};
+
+static int __init pxa168_init(void)
+{
+	if (cpu_is_pxa168()) {
+		mfp_init_base(MFPR_VIRT_BASE);
+		mfp_init_addr(pxa168_mfp_addr_map);
+		pxa_init_dma(IRQ_PXA168_DMA_INT0, 32);
+		clks_register(ARRAY_AND_SIZE(pxa168_clkregs));
+	}
+
+	return 0;
+}
+postcore_initcall(pxa168_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST	(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa168_timer_init(void)
+{
+	/* this is early, we have to initialize the CCU registers by
+	 * ourselves instead of using clk_* API. Clock rate is defined
+	 * by APBC_TIMERS_CLK_RST (3.25MHz) and enabled free-running
+	 */
+	__raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA168_TIMERS);
+
+	/* 3.25MHz, bus/functional clock enabled, release reset */
+	__raw_writel(TIMER_CLK_RST, APBC_PXA168_TIMERS);
+
+	timer_init(IRQ_PXA168_TIMER1);
+}
+
+struct sys_timer pxa168_timer = {
+	.init	= pxa168_timer_init,
+};
+
+/* on-chip devices */
+PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
+PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/pxa910.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/pxa910.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/pxa910.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/pxa910.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ *  linux/arch/arm/mach-mmp/pxa910.c
+ *
+ *  Code specific to PXA910
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/devices.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE	(APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata =
+{
+	MFP_ADDR_X(GPIO0, GPIO54, 0xdc),
+	MFP_ADDR_X(GPIO67, GPIO98, 0x1b8),
+	MFP_ADDR_X(GPIO100, GPIO109, 0x238),
+
+	MFP_ADDR(GPIO123, 0xcc),
+	MFP_ADDR(GPIO124, 0xd0),
+
+	MFP_ADDR(DF_IO0, 0x40),
+	MFP_ADDR(DF_IO1, 0x3c),
+	MFP_ADDR(DF_IO2, 0x38),
+	MFP_ADDR(DF_IO3, 0x34),
+	MFP_ADDR(DF_IO4, 0x30),
+	MFP_ADDR(DF_IO5, 0x2c),
+	MFP_ADDR(DF_IO6, 0x28),
+	MFP_ADDR(DF_IO7, 0x24),
+	MFP_ADDR(DF_IO8, 0x20),
+	MFP_ADDR(DF_IO9, 0x1c),
+	MFP_ADDR(DF_IO10, 0x18),
+	MFP_ADDR(DF_IO11, 0x14),
+	MFP_ADDR(DF_IO12, 0x10),
+	MFP_ADDR(DF_IO13, 0xc),
+	MFP_ADDR(DF_IO14, 0x8),
+	MFP_ADDR(DF_IO15, 0x4),
+
+	MFP_ADDR(DF_nCS0_SM_nCS2, 0x44),
+	MFP_ADDR(DF_nCS1_SM_nCS3, 0x48),
+	MFP_ADDR(SM_nCS0, 0x4c),
+	MFP_ADDR(SM_nCS1, 0x50),
+	MFP_ADDR(DF_WEn, 0x54),
+	MFP_ADDR(DF_REn, 0x58),
+	MFP_ADDR(DF_CLE_SM_OEn, 0x5c),
+	MFP_ADDR(DF_ALE_SM_WEn, 0x60),
+	MFP_ADDR(SM_SCLK, 0x64),
+	MFP_ADDR(DF_RDY0, 0x68),
+	MFP_ADDR(SM_BE0, 0x6c),
+	MFP_ADDR(SM_BE1, 0x70),
+	MFP_ADDR(SM_ADV, 0x74),
+	MFP_ADDR(DF_RDY1, 0x78),
+	MFP_ADDR(SM_ADVMUX, 0x7c),
+	MFP_ADDR(SM_RDY, 0x80),
+
+	MFP_ADDR_X(MMC1_DAT7, MMC1_WP, 0x84),
+
+	MFP_ADDR_END,
+};
+
+#define APMASK(i)	(GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa910_init_gpio(void)
+{
+	int i;
+
+	/* enable GPIO clock */
+	__raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO);
+
+	/* unmask GPIO edge detection for all 4 banks - APMASKx */
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xffffffff, APMASK(i));
+
+	pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL);
+}
+
+void __init pxa910_init_irq(void)
+{
+	icu_init_irq();
+	pxa910_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA910_UART0, 1, 14745600);
+static APBC_CLK(uart2, PXA910_UART1, 1, 14745600);
+
+/* device and clock bindings */
+static struct clk_lookup pxa910_clkregs[] = {
+	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+	INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+};
+
+static int __init pxa910_init(void)
+{
+	if (cpu_is_pxa910()) {
+		mfp_init_base(MFPR_VIRT_BASE);
+		mfp_init_addr(pxa910_mfp_addr_map);
+		pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
+		clks_register(ARRAY_AND_SIZE(pxa910_clkregs));
+	}
+
+	return 0;
+}
+postcore_initcall(pxa910_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST	(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa910_timer_init(void)
+{
+	/* reset and configure */
+	__raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA910_TIMERS);
+	__raw_writel(TIMER_CLK_RST, APBC_PXA910_TIMERS);
+
+	timer_init(IRQ_PXA910_AP1_TIMER1);
+}
+
+struct sys_timer pxa910_timer = {
+	.init	= pxa910_timer_init,
+};
+
+/* on-chip devices */
+
+/* NOTE: there are totally 3 UARTs on PXA910:
+ *
+ *   UART1   - Slow UART (can be used both by AP and CP)
+ *   UART2/3 - Fast UART
+ *
+ * To be backward compatible with the legacy FFUART/BTUART/STUART sequence,
+ * they are re-ordered as:
+ *
+ *   pxa910_device_uart1 - UART2 as FFUART
+ *   pxa910_device_uart2 - UART3 as BTUART
+ *
+ * UART1 is not used by AP for the moment.
+ */
+PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22);
+PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/tavorevb.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/tavorevb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/tavorevb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/tavorevb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,109 @@
+/*
+ *  linux/arch/arm/mach-mmp/tavorevb.c
+ *
+ *  Support for the Marvell PXA910-based TavorEVB Development 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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa910.h>
+#include <mach/pxa910.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+static unsigned long tavorevb_pin_config[] __initdata = {
+	/* UART2 */
+	GPIO47_UART2_RXD,
+	GPIO48_UART2_TXD,
+
+	/* SMC */
+	SM_nCS0_nCS0,
+	SM_ADV_SM_ADV,
+	SM_SCLK_SM_SCLK,
+	SM_SCLK_SM_SCLK,
+	SM_BE0_SM_BE0,
+	SM_BE1_SM_BE1,
+
+	/* 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 smc91x_platdata tavorevb_smc91x_info = {
+	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= SMC_CS1_PHYS_BASE + 0x300,
+		.end	= SMC_CS1_PHYS_BASE + 0xfffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gpio_to_irq(80),
+		.end	= gpio_to_irq(80),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &tavorevb_smc91x_info,
+	},
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static void __init tavorevb_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(tavorevb_pin_config));
+
+	/* on-chip devices */
+	pxa910_add_uart(1);
+
+	/* off-chip devices */
+	platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
+	.phys_io        = APB_PHYS_BASE,
+	.boot_params    = 0x00000100,
+	.io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq       = pxa910_init_irq,
+	.timer          = &pxa910_timer,
+	.init_machine   = tavorevb_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/mach-mmp/time.c
+ *
+ *   Support for clocksource and clockevents
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * All rights reserved.
+ *
+ *   2008-04-11: Jason Chagas <Jason.chagas@marvell.com>
+ *   2008-10-08: Bin Yang <bin.yang@marvell.com>
+ *
+ * The timers module actually includes three timers, each timer with upto
+ * three match comparators. Timer #0 is used here in free-running mode as
+ * the clock source, and match comparator #1 used as clock event device.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/cnt32_to_63.h>
+
+#include <mach/addr-map.h>
+#include <mach/regs-timers.h>
+#include <mach/irqs.h>
+
+#include "clock.h"
+
+#define TIMERS_VIRT_BASE	TIMERS1_VIRT_BASE
+
+#define MAX_DELTA		(0xfffffffe)
+#define MIN_DELTA		(16)
+
+#define TCR2NS_SCALE_FACTOR	10
+
+static unsigned long tcr2ns_scale;
+
+static void __init set_tcr2ns_scale(unsigned long tcr_rate)
+{
+	unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR;
+	do_div(v, tcr_rate);
+	tcr2ns_scale = v;
+	/*
+	 * We want an even value to automatically clear the top bit
+	 * returned by cnt32_to_63() without an additional run time
+	 * instruction. So if the LSB is 1 then round it up.
+	 */
+	if (tcr2ns_scale & 1)
+		tcr2ns_scale++;
+}
+
+/*
+ * FIXME: the timer needs some delay to stablize the counter capture
+ */
+static inline uint32_t timer_read(void)
+{
+	int delay = 100;
+
+	__raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0));
+
+	while (delay--)
+		cpu_relax();
+
+	return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0));
+}
+
+unsigned long long sched_clock(void)
+{
+	unsigned long long v = cnt32_to_63(timer_read());
+	return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR;
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *c = dev_id;
+
+	/* disable and clear pending interrupt status */
+	__raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+	__raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0));
+	c->event_handler(c);
+	return IRQ_HANDLED;
+}
+
+static int timer_set_next_event(unsigned long delta,
+				struct clock_event_device *dev)
+{
+	unsigned long flags, next;
+
+	local_irq_save(flags);
+
+	/* clear pending interrupt status and enable */
+	__raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
+	__raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0));
+
+	next = timer_read() + delta;
+	__raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0));
+
+	local_irq_restore(flags);
+	return 0;
+}
+
+static void timer_set_mode(enum clock_event_mode mode,
+			   struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	switch (mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		/* disable the matching interrupt */
+		__raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0));
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_PERIODIC:
+		break;
+	}
+	local_irq_restore(flags);
+}
+
+static struct clock_event_device ckevt = {
+	.name		= "clockevent",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.rating		= 200,
+	.set_next_event	= timer_set_next_event,
+	.set_mode	= timer_set_mode,
+};
+
+static cycle_t clksrc_read(struct clocksource *cs)
+{
+	return timer_read();
+}
+
+static struct clocksource cksrc = {
+	.name		= "clocksource",
+	.shift		= 20,
+	.rating		= 200,
+	.read		= clksrc_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init timer_config(void)
+{
+	uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR);
+	uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER);
+	uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR);
+
+	__raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
+
+	ccr &= TMR_CCR_CS_0(0x3);
+	__raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
+
+	/* free-running mode */
+	__raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR);
+
+	__raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */
+	__raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0));  /* clear status */
+	__raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+
+	/* enable timer counter */
+	__raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER);
+}
+
+static struct irqaction timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= timer_interrupt,
+	.dev_id		= &ckevt,
+};
+
+void __init timer_init(int irq)
+{
+	timer_config();
+
+	set_tcr2ns_scale(CLOCK_TICK_RATE);
+
+	ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
+	ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
+	ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt);
+	ckevt.cpumask = cpumask_of(0);
+
+	cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift);
+
+	setup_irq(irq, &timer_irq);
+
+	clocksource_register(&cksrc);
+	clockevents_register_device(&ckevt);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/ttc_dkb.c linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/ttc_dkb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mmp/ttc_dkb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mmp/ttc_dkb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ *  linux/arch/arm/mach-mmp/ttc_dkb.c
+ *
+ *  Support for the Marvell PXA910-based TTC_DKB Development 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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.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,
+};
+
+static void __init ttc_dkb_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
+
+	/* on-chip devices */
+	pxa910_add_uart(1);
+}
+
+MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
+	.phys_io        = APB_PHYS_BASE,
+	.boot_params    = 0x00000100,
+	.io_pg_offst    = (APB_VIRT_BASE >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq       = pxa910_init_irq,
+	.timer          = &pxa910_timer,
+	.init_machine   = ttc_dkb_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-msm/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-msm/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-msm/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-msm/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@
 
 void arch_idle(void);
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	for (;;) ;  /* depends on IPC w/ other core */
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-msm/timer.c linux-libre-2.6.30-gnu1/arch/arm/mach-msm/timer.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-msm/timer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-msm/timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,12 +57,12 @@ static irqreturn_t msm_timer_interrupt(i
 	return IRQ_HANDLED;
 }
 
-static cycle_t msm_gpt_read(void)
+static cycle_t msm_gpt_read(struct clocksource *cs)
 {
 	return readl(MSM_GPT_BASE + TIMER_COUNT_VAL);
 }
 
-static cycle_t msm_dgt_read(void)
+static cycle_t msm_dgt_read(struct clocksource *cs)
 {
 	return readl(MSM_DGT_BASE + TIMER_COUNT_VAL) >> MSM_DGT_SHIFT;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,10 +14,13 @@
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
+#include <linux/ethtool.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
 #include <plat/cache-feroceon-l2.h>
 #include <plat/ehci-orion.h>
 #include <plat/orion_nand.h>
@@ -318,6 +321,9 @@ static struct platform_device mv78xx0_ge
 	.id		= 0,
 	.num_resources	= 1,
 	.resource	= mv78xx0_ge00_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
@@ -372,6 +378,9 @@ static struct platform_device mv78xx0_ge
 	.id		= 1,
 	.num_resources	= 1,
 	.resource	= mv78xx0_ge01_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
@@ -426,13 +435,29 @@ static struct platform_device mv78xx0_ge
 	.id		= 2,
 	.num_resources	= 1,
 	.resource	= mv78xx0_ge10_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 {
+	u32 dev, rev;
+
 	eth_data->shared = &mv78xx0_ge10_shared;
 	mv78xx0_ge10.dev.platform_data = eth_data;
 
+	/*
+	 * On the Z0, ge10 and ge11 are internally connected back
+	 * to back, and not brought out.
+	 */
+	mv78xx0_pcie_id(&dev, &rev);
+	if (dev == MV78X00_Z0_DEV_ID) {
+		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+		eth_data->speed = SPEED_1000;
+		eth_data->duplex = DUPLEX_FULL;
+	}
+
 	platform_device_register(&mv78xx0_ge10_shared);
 	platform_device_register(&mv78xx0_ge10);
 }
@@ -480,17 +505,104 @@ static struct platform_device mv78xx0_ge
 	.id		= 3,
 	.num_resources	= 1,
 	.resource	= mv78xx0_ge11_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
 {
+	u32 dev, rev;
+
 	eth_data->shared = &mv78xx0_ge11_shared;
 	mv78xx0_ge11.dev.platform_data = eth_data;
 
+	/*
+	 * On the Z0, ge10 and ge11 are internally connected back
+	 * to back, and not brought out.
+	 */
+	mv78xx0_pcie_id(&dev, &rev);
+	if (dev == MV78X00_Z0_DEV_ID) {
+		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+		eth_data->speed = SPEED_1000;
+		eth_data->duplex = DUPLEX_FULL;
+	}
+
 	platform_device_register(&mv78xx0_ge11_shared);
 	platform_device_register(&mv78xx0_ge11);
 }
 
+/*****************************************************************************
+ * I2C bus 0
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
+	.freq_m		= 8, /* assumes 166 MHz TCLK */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_0_resources[] = {
+	{
+		.start  = I2C_0_PHYS_BASE,
+		.end    = I2C_0_PHYS_BASE + 0x1f,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = IRQ_MV78XX0_I2C_0,
+		.end    = IRQ_MV78XX0_I2C_0,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+
+static struct platform_device mv78xx0_i2c_0 = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_0_resources),
+	.resource	= mv78xx0_i2c_0_resources,
+	.dev		= {
+		.platform_data	= &mv78xx0_i2c_0_pdata,
+	},
+};
+
+/*****************************************************************************
+ * I2C bus 1
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
+	.freq_m		= 8, /* assumes 166 MHz TCLK */
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_1_resources[] = {
+	{
+		.start  = I2C_1_PHYS_BASE,
+		.end    = I2C_1_PHYS_BASE + 0x1f,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = IRQ_MV78XX0_I2C_1,
+		.end    = IRQ_MV78XX0_I2C_1,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+
+static struct platform_device mv78xx0_i2c_1 = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_1_resources),
+	.resource	= mv78xx0_i2c_1_resources,
+	.dev		= {
+		.platform_data	= &mv78xx0_i2c_1_pdata,
+	},
+};
+
+void __init mv78xx0_i2c_init(void)
+{
+	platform_device_register(&mv78xx0_i2c_0);
+	platform_device_register(&mv78xx0_i2c_1);
+}
 
 /*****************************************************************************
  * SATA
@@ -719,6 +831,32 @@ struct sys_timer mv78xx0_timer = {
 /*****************************************************************************
  * General
  ****************************************************************************/
+static char * __init mv78xx0_id(void)
+{
+	u32 dev, rev;
+
+	mv78xx0_pcie_id(&dev, &rev);
+
+	if (dev == MV78X00_Z0_DEV_ID) {
+		if (rev == MV78X00_REV_Z0)
+			return "MV78X00-Z0";
+		else
+			return "MV78X00-Rev-Unsupported";
+	} else if (dev == MV78100_DEV_ID) {
+		if (rev == MV78100_REV_A0)
+			return "MV78100-A0";
+		else
+			return "MV78100-Rev-Unsupported";
+	} else if (dev == MV78200_DEV_ID) {
+		if (rev == MV78100_REV_A0)
+			return "MV78200-A0";
+		else
+			return "MV78200-Rev-Unsupported";
+	} else {
+		return "Device-Unknown";
+	}
+}
+
 static int __init is_l2_writethrough(void)
 {
 	return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
@@ -737,7 +875,8 @@ void __init mv78xx0_init(void)
 	get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
 	tclk = get_tclk();
 
-	printk(KERN_INFO "MV78xx0 core #%d, ", core_index);
+	printk(KERN_INFO "%s ", mv78xx0_id());
+	printk("core #%d, ", core_index);
 	printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
 	printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
 	printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/common.h linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,8 @@ void mv78xx0_setup_pcie_io_win(int windo
 void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
 				int maj, int min);
 
+void mv78xx0_pcie_id(u32 *dev, u32 *rev);
+
 void mv78xx0_ehci0_init(void);
 void mv78xx0_ehci1_init(void);
 void mv78xx0_ehci2_init(void);
@@ -42,6 +44,7 @@ void mv78xx0_uart0_init(void);
 void mv78xx0_uart1_init(void);
 void mv78xx0_uart2_init(void);
 void mv78xx0_uart3_init(void);
+void mv78xx0_i2c_init(void);
 
 extern struct sys_timer mv78xx0_timer;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/db78x00-bp-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/db78x00-bp-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/db78x00-bp-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <linux/i2c.h>
 #include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -28,21 +29,22 @@ static struct mv643xx_eth_platform_data
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge10_data = {
-	.phy_addr	= MV643XX_ETH_PHY_NONE,
-	.speed		= SPEED_1000,
-	.duplex		= DUPLEX_FULL,
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(10),
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge11_data = {
-	.phy_addr	= MV643XX_ETH_PHY_NONE,
-	.speed		= SPEED_1000,
-	.duplex		= DUPLEX_FULL,
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(11),
 };
 
 static struct mv_sata_platform_data db78x00_sata_data = {
 	.n_ports	= 2,
 };
 
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+	I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
 static void __init db78x00_init(void)
 {
 	/*
@@ -64,6 +66,8 @@ static void __init db78x00_init(void)
 		mv78xx0_sata_init(&db78x00_sata_data);
 		mv78xx0_uart0_init();
 		mv78xx0_uart2_init();
+		mv78xx0_i2c_init();
+		i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
 	} else {
 		mv78xx0_uart1_init();
 		mv78xx0_uart3_init();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/bridge-regs.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_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/mv78xx0.h>
+
+#define CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
+#define L2_WRITETHROUGH		0x00020000
+
+#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_ERR_OFF	0x0000
+#define IRQ_CAUSE_LOW_OFF	0x0004
+#define IRQ_CAUSE_HIGH_OFF	0x0008
+#define IRQ_MASK_ERR_OFF	0x000c
+#define IRQ_MASK_LOW_OFF	0x0010
+#define IRQ_MASK_HIGH_OFF	0x0014
+
+#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/entry-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
 
 	.macro  disable_fiq
 	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h	2009-06-09 23:05:27.000000000 -0400
@@ -59,25 +59,6 @@
  * Core-specific peripheral registers.
  */
 #define BRIDGE_VIRT_BASE	(MV78XX0_CORE_REGS_VIRT_BASE)
-#define  CPU_CONTROL		(BRIDGE_VIRT_BASE | 0x0104)
-#define   L2_WRITETHROUGH	0x00020000
-#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_ERR_OFF	0x0000
-#define   IRQ_CAUSE_LOW_OFF	0x0004
-#define   IRQ_CAUSE_HIGH_OFF	0x0008
-#define   IRQ_MASK_ERR_OFF	0x000c
-#define   IRQ_MASK_LOW_OFF	0x0010
-#define   IRQ_MASK_HIGH_OFF	0x0014
-#define  TIMER_VIRT_BASE	(BRIDGE_VIRT_BASE | 0x0300)
 
 /*
  * Register Map
@@ -90,6 +71,8 @@
 #define DEV_BUS_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE | 0x10000)
 #define  SAMPLE_AT_RESET_LOW	(DEV_BUS_VIRT_BASE | 0x0030)
 #define  SAMPLE_AT_RESET_HIGH	(DEV_BUS_VIRT_BASE | 0x0034)
+#define  I2C_0_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x1000)
+#define  I2C_1_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x1100)
 #define  UART0_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x2000)
 #define  UART0_VIRT_BASE	(DEV_BUS_VIRT_BASE | 0x2000)
 #define  UART1_PHYS_BASE	(DEV_BUS_PHYS_BASE | 0x2100)
@@ -121,5 +104,16 @@
 
 #define SATA_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE | 0xa0000)
 
+/*
+ * Supported devices and revisions.
+ */
+#define MV78X00_Z0_DEV_ID	0x6381
+#define MV78X00_REV_Z0		1
+
+#define MV78100_DEV_ID		0x7810
+#define MV78100_REV_A0		1
+
+#define MV78200_DEV_ID		0x7820
+#define MV78200_REV_A0		1
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,15 +9,14 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <mach/hardware.h>
-#include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
 
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/pci.h>
 #include <linux/irq.h>
 #include <asm/gpio.h>
-#include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include "common.h"
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,12 @@ config MACH_DB78X00_BP
 	  Say 'Y' here if you want your kernel to support the
 	  Marvell DB-78x00-BP Development Board.
 
+config MACH_RD78X00_MASA
+	bool "Marvell RD-78x00-mASA Reference Design"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell RD-78x00-mASA Reference Design.
+
 endmenu
 
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,2 +1,3 @@
 obj-y				+= common.o addr-map.o irq.o pcie.o
 obj-$(CONFIG_MACH_DB78X00_BP)	+= db78x00-bp-setup.o
+obj-$(CONFIG_MACH_RD78X00_MASA)	+= rd78x00-masa-setup.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/pcie.c linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/pcie.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/pcie.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/pcie.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,12 @@ static struct resource pcie_io_space;
 static struct resource pcie_mem_space;
 
 
+void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
+{
+	*dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE);
+	*rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
+}
+
 static void __init mv78xx0_pcie_preinit(void)
 {
 	int i;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-mv78x00/rd78x00-masa-setup.c
+ *
+ * Marvell RD-78x00-mASA 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/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge01_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(9),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge10_data = {
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge11_data = {
+};
+
+static struct mv_sata_platform_data rd78x00_masa_sata_data = {
+	.n_ports	= 2,
+};
+
+static void __init rd78x00_masa_init(void)
+{
+	/*
+	 * Basic MV78x00 setup. Needs to be called early.
+	 */
+	mv78xx0_init();
+
+	/*
+	 * Partition on-chip peripherals between the two CPU cores.
+	 */
+	if (mv78xx0_core_index() == 0) {
+		mv78xx0_ehci0_init();
+		mv78xx0_ehci1_init();
+		mv78xx0_ge00_init(&rd78x00_masa_ge00_data);
+		mv78xx0_ge10_init(&rd78x00_masa_ge10_data);
+		mv78xx0_sata_init(&rd78x00_masa_sata_data);
+		mv78xx0_uart0_init();
+		mv78xx0_uart2_init();
+	} else {
+		mv78xx0_ehci2_init();
+		mv78xx0_ge01_init(&rd78x00_masa_ge01_data);
+		mv78xx0_ge11_init(&rd78x00_masa_ge11_data);
+		mv78xx0_uart1_init();
+		mv78xx0_uart3_init();
+	}
+}
+
+static int __init rd78x00_pci_init(void)
+{
+	/*
+	 * Assign all PCIe devices to CPU core #0.
+	 */
+	if (machine_is_rd78x00_masa() && mv78xx0_core_index() == 0)
+		mv78xx0_pcie_init(1, 1);
+
+	return 0;
+}
+subsys_initcall(rd78x00_pci_init);
+
+MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
+	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+	.phys_io	= MV78XX0_REGS_PHYS_BASE,
+	.io_pg_offst	= ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= rd78x00_masa_init,
+	.map_io		= mv78xx0_map_io,
+	.init_irq	= mv78xx0_init_irq,
+	.timer		= &mv78xx0_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 
 #include <mach/clock.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include "crm_regs.h"
 
 static int _clk_enable(struct clk *clk)
@@ -87,33 +88,6 @@ static int _clk_parent_set_rate(struct c
 	return clk->parent->set_rate(clk->parent, rate);
 }
 
-/*
- *  get the system pll clock in Hz
- *
- *                  mfi + mfn / (mfd +1)
- *  f = 2 * f_ref * --------------------
- *                        pd + 1
- */
-static unsigned long mx1_decode_pll(unsigned int pll, u32 f_ref)
-{
-	unsigned long long ll;
-	unsigned long quot;
-
-	u32 mfi = (pll >> 10) & 0xf;
-	u32 mfn = pll & 0x3ff;
-	u32 mfd = (pll >> 16) & 0x3ff;
-	u32 pd =  (pll >> 26) & 0xf;
-
-	mfi = mfi <= 5 ? 5 : mfi;
-
-	ll = 2 * (unsigned long long)f_ref *
-		((mfi << 16) + (mfn << 16) / (mfd + 1));
-	quot = (pd + 1) * (1 << 16);
-	ll += quot / 2;
-	do_div(ll, quot);
-	return (unsigned long)ll;
-}
-
 static unsigned long clk16m_get_rate(struct clk *clk)
 {
 	return 16000000;
@@ -188,7 +162,7 @@ static struct clk prem_clk = {
 
 static unsigned long system_clk_get_rate(struct clk *clk)
 {
-	return mx1_decode_pll(__raw_readl(CCM_SPCTL0),
+	return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
 			      clk_get_rate(clk->parent));
 }
 
@@ -200,7 +174,7 @@ static struct clk system_clk = {
 
 static unsigned long mcu_clk_get_rate(struct clk *clk)
 {
-	return mx1_decode_pll(__raw_readl(CCM_MPCTL0),
+	return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
 			      clk_get_rate(clk->parent));
 }
 
@@ -488,7 +462,7 @@ static struct clk clko_clk = {
 };
 
 static struct clk dma_clk = {
-	.name = "dma_clk",
+	.name = "dma",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -539,7 +513,7 @@ static struct clk gpt_clk = {
 };
 
 static struct clk uart_clk = {
-	.name = "uart_clk",
+	.name = "uart",
 	.parent = &perclk[0],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -621,7 +595,7 @@ static struct clk *mxc_clks[] = {
 	&rtc_clk,
 };
 
-int __init mxc_clocks_init(unsigned long fref)
+int __init mx1_clocks_init(unsigned long fref)
 {
 	struct clk **clkp;
 	unsigned int reg;
@@ -652,5 +626,7 @@ int __init mxc_clocks_init(unsigned long
 	clk_enable(&hclk);
 	clk_enable(&fclk);
 
+	mxc_timer_init(&gpt_clk);
+
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,10 +23,11 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
-
 #include <mach/irqs.h>
 #include <mach/hardware.h>
 
+#include "devices.h"
+
 static struct resource imx_csi_resources[] = {
 	[0] = {
 		.start  = 0x00224000,
@@ -43,7 +44,7 @@ static struct resource imx_csi_resources
 static u64 imx_csi_dmamask = 0xffffffffUL;
 
 struct platform_device imx_csi_device = {
-	.name           = "imx-csi",
+	.name           = "mx1-camera",
 	.id             = 0, /* This is used to put cameras on this interface */
 	.dev		= {
 		.dma_mask = &imx_csi_dmamask,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 if ARCH_MX1
 
-comment "MX1 Platforms"
+comment "MX1 platforms:"
 
 config MACH_MXLADS
 	bool
@@ -11,4 +11,9 @@ config ARCH_MX1ADS
 	help
 	  Say Y here if you are using Motorola MX1ADS/MXLADS boards
 
+config MACH_SCB9328
+	bool "Synertronixx scb9328"
+	help
+	  Say Y here if you are using a Synertronixx scb9328 board
+
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/ksym_mx1.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/ksym_mx1.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/ksym_mx1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/ksym_mx1.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Exported ksyms of ARCH_MX1
+ *
+ * Copyright (C) 2008, Darius Augulis <augulis.darius@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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+
+#include <mach/mx1_camera.h>
+
+/* IMX camera FIQ handler */
+EXPORT_SYMBOL(mx1_camera_sof_fiq_start);
+EXPORT_SYMBOL(mx1_camera_sof_fiq_end);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,5 +6,9 @@
 
 obj-y			+= generic.o clock.o devices.o
 
+# Support for CMOS sensor interface
+obj-$(CONFIG_MX1_VIDEO)	+= ksym_mx1.o mx1_camera_fiq.o
+
 # Specific board support
 obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += scb9328.o
\ No newline at end of file
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/mx1ads.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/mx1ads.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/mx1ads.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/mx1ads.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -25,7 +27,9 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/irqs.h>
+#include <mach/i2c.h>
+#include <mach/iomux.h>
 #include "devices.h"
 
 /*
@@ -105,6 +109,53 @@ static struct platform_device flash_devi
 };
 
 /*
+ * I2C
+ */
+
+static int i2c_pins[] = {
+	PA15_PF_I2C_SDA,
+	PA16_PF_I2C_SCL,
+};
+
+static int i2c_init(struct device *dev)
+{
+	return mxc_gpio_setup_multiple_pins(i2c_pins,
+			ARRAY_SIZE(i2c_pins), "I2C");
+}
+
+static void i2c_exit(struct device *dev)
+{
+	mxc_gpio_release_multiple_pins(i2c_pins,
+			ARRAY_SIZE(i2c_pins));
+}
+
+static struct pcf857x_platform_data pcf857x_data[] = {
+	{
+		.gpio_base = 4 * 32,
+	}, {
+		.gpio_base = 4 * 32 + 16,
+	}
+};
+
+static struct imxi2c_platform_data mx1ads_i2c_data = {
+	.bitrate = 100000,
+	.init = i2c_init,
+	.exit = i2c_exit,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf857x", 0x22),
+		.type = "pcf8575",
+		.platform_data = &pcf857x_data[0],
+	}, {
+		I2C_BOARD_INFO("pcf857x", 0x24),
+		.type = "pcf8575",
+		.platform_data = &pcf857x_data[1],
+	},
+};
+
+/*
  * Board init
  */
 static void __init mx1ads_init(void)
@@ -115,12 +166,17 @@ static void __init mx1ads_init(void)
 
 	/* Physmap flash */
 	mxc_register_device(&flash_device, &mx1ads_flash_data);
+
+	/* I2C */
+	i2c_register_board_info(0, mx1ads_i2c_devices,
+				ARRAY_SIZE(mx1ads_i2c_devices));
+
+	mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
 }
 
 static void __init mx1ads_timer_init(void)
 {
-	mxc_clocks_init(32000);
-	mxc_timer_init("gpt_clk");
+	mx1_clocks_init(32000);
 }
 
 struct sys_timer mx1ads_timer = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/mx1_camera_fiq.S linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/mx1_camera_fiq.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/mx1_camera_fiq.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/mx1_camera_fiq.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ *  Based on linux/arch/arm/lib/floppydma.S
+ *      Copyright (C) 1995, 1996 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/linkage.h>
+#include <asm/assembler.h>
+
+		.text
+		.global	mx1_camera_sof_fiq_end
+		.global	mx1_camera_sof_fiq_start
+mx1_camera_sof_fiq_start:
+		@ enable dma
+		ldr	r12, [r9]
+		orr	r12, r12, #0x00000001
+		str	r12, [r9]
+		@ unmask DMA interrupt
+		ldr	r12, [r8]
+		bic	r12, r12, r13
+		str	r12, [r8]
+		@ disable SOF interrupt
+		ldr	r12, [r10]
+		bic	r12, r12, #0x00010000
+		str	r12, [r10]
+		@ clear SOF flag
+		mov	r12, #0x00010000
+		str	r12, [r11]
+		@ return from FIQ
+		subs	pc, lr, #4
+mx1_camera_sof_fiq_end:
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/scb9328.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/scb9328.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx1/scb9328.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx1/scb9328.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,160 @@
+/*
+ * linux/arch/arm/mach-mx1/scb9328.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/interrupt.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+/*
+ * This scb9328 has a 32MiB flash
+ */
+static struct resource flash_resource = {
+	.start	= IMX_CS0_PHYS,
+	.end	= IMX_CS0_PHYS + (32 * 1024 * 1024) - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data scb_flash_data = {
+	.width  = 2,
+};
+
+static struct platform_device scb_flash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev = {
+		.platform_data = &scb_flash_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * scb9328 has a DM9000 network controller
+ * connected to CS5, with 16 bit data path
+ * and interrupt connected to GPIO 3
+ */
+
+/*
+ * internal datapath is fixed 16 bit
+ */
+static struct dm9000_plat_data dm9000_platdata = {
+	.flags	= DM9000_PLATF_16BITONLY,
+};
+
+/*
+ * the DM9000 drivers wants two defined address spaces
+ * to gain access to address latch registers and the data path.
+ */
+static struct resource dm9000x_resources[] = {
+	[0] = {
+		.name	= "address area",
+		.start	= IMX_CS5_PHYS,
+		.end	= IMX_CS5_PHYS + 1,
+		.flags	= IORESOURCE_MEM	/* address access */
+	},
+	[1] = {
+		.name	= "data area",
+		.start	= IMX_CS5_PHYS + 4,
+		.end	= IMX_CS5_PHYS + 5,
+		.flags	= IORESOURCE_MEM	/* data access */
+	},
+	[2] = {
+		.start	= IRQ_GPIOC(3),
+		.end	= IRQ_GPIOC(3),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL
+	},
+};
+
+static struct platform_device dm9000x_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm9000x_resources),
+	.resource	= dm9000x_resources,
+	.dev		= {
+		.platform_data = &dm9000_platdata,
+	}
+};
+
+static int mxc_uart1_pins[] = {
+	PC9_PF_UART1_CTS,
+	PC10_PF_UART1_RTS,
+	PC11_PF_UART1_TXD,
+	PC12_PF_UART1_RXD,
+};
+
+static int uart1_mxc_init(struct platform_device *pdev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+			ARRAY_SIZE(mxc_uart1_pins), "UART1");
+}
+
+static int uart1_mxc_exit(struct platform_device *pdev)
+{
+	mxc_gpio_release_multiple_pins(mxc_uart1_pins,
+			ARRAY_SIZE(mxc_uart1_pins));
+	return 0;
+}
+
+static struct imxuart_platform_data uart_pdata = {
+	.init = uart1_mxc_init,
+	.exit = uart1_mxc_exit,
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&scb_flash_device,
+	&dm9000x_device,
+};
+
+/*
+ * scb9328_init - Init the CPU card itself
+ */
+static void __init scb9328_init(void)
+{
+	mxc_register_device(&imx_uart1_device, &uart_pdata);
+
+	printk(KERN_INFO"Scb9328: Adding devices\n");
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+	mx1_clocks_init(32000);
+}
+
+static struct sys_timer scb9328_timer = {
+	.init	= scb9328_timer_init,
+};
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+    /* Sascha Hauer */
+	.phys_io	= 0x00200000,
+	.io_pg_offst	= ((0xe0200000) >> 18) & 0xfffc,
+	.boot_params	= 0x08000100,
+	.map_io		= mxc_map_io,
+	.init_irq	= mxc_init_irq,
+	.timer		= &scb9328_timer,
+	.init_machine	= scb9328_init,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/clock_imx21.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/clock_imx21.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/clock_imx21.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/clock_imx21.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,984 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include "crm_regs.h"
+
+static int _clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 1 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+	return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(1 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_spll_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CSCR);
+	reg |= CCM_CSCR_SPEN;
+	__raw_writel(reg, CCM_CSCR);
+
+	while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
+		;
+	return 0;
+}
+
+static void _clk_spll_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CSCR);
+	reg &= ~CCM_CSCR_SPEN;
+	__raw_writel(reg, CCM_CSCR);
+}
+
+
+#define CSCR() (__raw_readl(CCM_CSCR))
+#define PCDR0() (__raw_readl(CCM_PCDR0))
+#define PCDR1() (__raw_readl(CCM_PCDR1))
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+					     unsigned long rate)
+{
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+	if (parent_rate % rate)
+		div++;
+
+	if (div > 64)
+		div = 64;
+
+	return parent_rate / div;
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->id < 0 || clk->id > 3)
+		return -EINVAL;
+
+	div = parent_rate / rate;
+	if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+	div--;
+
+	reg =
+	    __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
+				       (clk->id << 3));
+	reg |= div << (clk->id << 3);
+	__raw_writel(reg, CCM_PCDR1);
+
+	return 0;
+}
+
+static unsigned long _clk_usb_recalc(struct clk *clk)
+{
+	unsigned long usb_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+
+	return parent_rate / (usb_pdf + 1U);
+}
+
+static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
+{
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pdf = (pdf < 2) ? 124UL : pdf;  /* MX21 & MX27 TO1 */
+
+	return 2UL * parent_rate / pdf;
+}
+
+static unsigned long _clk_ssi1_recalc(struct clk *clk)
+{
+	return _clk_ssix_recalc(clk,
+		(PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
+		>> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_ssi2_recalc(struct clk *clk)
+{
+	return _clk_ssix_recalc(clk,
+		(PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
+		CCM_PCDR0_SSI2BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_nfc_recalc(struct clk *clk)
+{
+	unsigned long nfc_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
+		>> CCM_PCDR0_NFCDIV_OFFSET;
+
+	return parent_rate / (nfc_pdf + 1);
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->parent->set_rate(clk->parent, rate);
+}
+
+static unsigned long external_high_reference; /* in Hz */
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+	return external_high_reference;
+}
+
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz.
+ */
+static struct clk ckih_clk = {
+	.get_rate = get_high_reference_clock_rate,
+};
+
+static unsigned long external_low_reference; /* in Hz */
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+	return external_low_reference;
+}
+
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+	.get_rate = get_low_reference_clock_rate,
+};
+
+
+static unsigned long _clk_fpm_recalc(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) * 512;
+}
+
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+	.parent = &ckil_clk,
+	.get_rate = _clk_fpm_recalc,
+};
+
+static unsigned long get_mpll_clk(struct clk *clk)
+{
+	uint32_t reg;
+	unsigned long ref_clk;
+	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+	unsigned long long temp;
+
+	ref_clk = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(CCM_MPCTL0);
+	pdf = (reg & CCM_MPCTL0_PD_MASK)  >> CCM_MPCTL0_PD_OFFSET;
+	mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
+	mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
+	mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
+
+	mfi = (mfi <= 5) ? 5 : mfi;
+	temp = 2LL * ref_clk * mfn;
+	do_div(temp, mfd + 1);
+	temp = 2LL * ref_clk * mfi + temp;
+	do_div(temp, pdf + 1);
+
+	return (unsigned long)temp;
+}
+
+static struct clk mpll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = get_mpll_clk,
+};
+
+static unsigned long _clk_fclk_get_rate(struct clk *clk)
+{
+	unsigned long parent_rate;
+	u32 div;
+
+	div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+	parent_rate = clk_get_rate(clk->parent);
+
+	return parent_rate / (div+1);
+}
+
+static struct clk fclk_clk = {
+	.parent = &mpll_clk,
+	.get_rate = _clk_fclk_get_rate
+};
+
+static unsigned long get_spll_clk(struct clk *clk)
+{
+	uint32_t reg;
+	unsigned long ref_clk;
+	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+	unsigned long long temp;
+
+	ref_clk = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(CCM_SPCTL0);
+	pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
+	mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
+	mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
+	mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
+
+	mfi = (mfi <= 5) ? 5 : mfi;
+	temp = 2LL * ref_clk * mfn;
+	do_div(temp, mfd + 1);
+	temp = 2LL * ref_clk * mfi + temp;
+	do_div(temp, pdf + 1);
+
+	return (unsigned long)temp;
+}
+
+static struct clk spll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = get_spll_clk,
+	.enable = _clk_spll_enable,
+	.disable = _clk_spll_disable,
+};
+
+static unsigned long get_hclk_clk(struct clk *clk)
+{
+	unsigned long rate;
+	unsigned long bclk_pdf;
+
+	bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
+		>> CCM_CSCR_BCLK_OFFSET;
+
+	rate = clk_get_rate(clk->parent);
+	return rate / (bclk_pdf + 1);
+}
+
+static struct clk hclk_clk = {
+	.parent = &fclk_clk,
+	.get_rate = get_hclk_clk,
+};
+
+static unsigned long get_ipg_clk(struct clk *clk)
+{
+	unsigned long rate;
+	unsigned long ipg_pdf;
+
+	ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+
+	rate = clk_get_rate(clk->parent);
+	return rate / (ipg_pdf + 1);
+}
+
+static struct clk ipg_clk = {
+	.parent = &hclk_clk,
+	.get_rate = get_ipg_clk,
+};
+
+static unsigned long _clk_perclkx_recalc(struct clk *clk)
+{
+	unsigned long perclk_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->id < 0 || clk->id > 3)
+		return 0;
+
+	perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+
+	return parent_rate / (perclk_pdf + 1);
+}
+
+static struct clk per_clk[] = {
+	{
+		.id = 0,
+		.parent = &mpll_clk,
+		.get_rate = _clk_perclkx_recalc,
+	}, {
+		.id = 1,
+		.parent = &mpll_clk,
+		.get_rate = _clk_perclkx_recalc,
+	}, {
+		.id = 2,
+		.parent = &mpll_clk,
+		.round_rate = _clk_perclkx_round_rate,
+		.set_rate = _clk_perclkx_set_rate,
+		.get_rate = _clk_perclkx_recalc,
+		/* Enable/Disable done via lcd_clkc[1] */
+	}, {
+		.id = 3,
+		.parent = &mpll_clk,
+		.round_rate = _clk_perclkx_round_rate,
+		.set_rate = _clk_perclkx_set_rate,
+		.get_rate = _clk_perclkx_recalc,
+		/* Enable/Disable done via csi_clk[1] */
+	},
+};
+
+static struct clk uart_ipg_clk[];
+
+static struct clk uart_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[2],
+	}, {
+		.id = 3,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[3],
+	},
+};
+
+static struct clk uart_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART1_REG,
+		.enable_shift = CCM_PCCR_UART1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART2_REG,
+		.enable_shift = CCM_PCCR_UART2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 2,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART3_REG,
+		.enable_shift = CCM_PCCR_UART3_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 3,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART4_REG,
+		.enable_shift = CCM_PCCR_UART4_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk gpt_ipg_clk[];
+
+static struct clk gpt_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[2],
+	},
+};
+
+static struct clk gpt_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT1_REG,
+		.enable_shift = CCM_PCCR_GPT1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT2_REG,
+		.enable_shift = CCM_PCCR_GPT2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 2,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT3_REG,
+		.enable_shift = CCM_PCCR_GPT3_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk pwm_clk[] = {
+	{
+		.parent = &per_clk[0],
+		.secondary = &pwm_clk[1],
+	}, {
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_PWM_REG,
+		.enable_shift = CCM_PCCR_PWM_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk sdhc_ipg_clk[];
+
+static struct clk sdhc_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[1],
+		.secondary = &sdhc_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[1],
+		.secondary = &sdhc_ipg_clk[1],
+	},
+};
+
+static struct clk sdhc_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SDHC1_REG,
+		.enable_shift = CCM_PCCR_SDHC1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SDHC2_REG,
+		.enable_shift = CCM_PCCR_SDHC2_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk cspi_ipg_clk[];
+
+static struct clk cspi_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[2],
+	},
+};
+
+static struct clk cspi_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI1_REG,
+		.enable_shift = CCM_PCCR_CSPI1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI2_REG,
+		.enable_shift = CCM_PCCR_CSPI2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 3,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI3_REG,
+		.enable_shift = CCM_PCCR_CSPI3_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk lcdc_clk[] = {
+	{
+		.parent = &per_clk[2],
+		.secondary = &lcdc_clk[1],
+		.round_rate = _clk_parent_round_rate,
+		.set_rate = _clk_parent_set_rate,
+	}, {
+		.parent = &ipg_clk,
+		.secondary = &lcdc_clk[2],
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_LCDC_REG,
+		.enable_shift = CCM_PCCR_LCDC_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_LCDC_REG,
+		.enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk csi_clk[] = {
+	{
+		.parent = &per_clk[3],
+		.secondary = &csi_clk[1],
+		.round_rate = _clk_parent_round_rate,
+		.set_rate = _clk_parent_set_rate,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_CSI_REG,
+		.enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk usb_clk[] = {
+	{
+		.parent = &spll_clk,
+		.get_rate = _clk_usb_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_USBOTG_REG,
+		.enable_shift = CCM_PCCR_USBOTG_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
+		.enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk ssi_ipg_clk[];
+
+static struct clk ssi_clk[] = {
+	{
+		.id = 0,
+		.parent = &mpll_clk,
+		.secondary = &ssi_ipg_clk[0],
+		.get_rate = _clk_ssi1_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI1_BAUD_REG,
+		.enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &mpll_clk,
+		.secondary = &ssi_ipg_clk[1],
+		.get_rate = _clk_ssi2_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI2_BAUD_REG,
+		.enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk ssi_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI1_REG,
+		.enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI2_REG,
+		.enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+
+static struct clk nfc_clk = {
+	.parent = &fclk_clk,
+	.get_rate = _clk_nfc_recalc,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_NFC_REG,
+	.enable_shift = CCM_PCCR_NFC_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk dma_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_DMA_REG,
+		.enable_shift = CCM_PCCR_DMA_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &dma_clk[1],
+	},  {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_DMA_REG,
+		.enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk brom_clk = {
+	.parent = &hclk_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_HCLK_BROM_REG,
+	.enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk emma_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_EMMA_REG,
+		.enable_shift = CCM_PCCR_EMMA_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &emma_clk[1],
+	}, {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_EMMA_REG,
+		.enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk slcdc_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SLCDC_REG,
+		.enable_shift = CCM_PCCR_SLCDC_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &slcdc_clk[1],
+	}, {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
+		.enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk wdog_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_WDT_REG,
+	.enable_shift = CCM_PCCR_WDT_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk gpio_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_GPIO_REG,
+	.enable_shift = CCM_PCCR_GPIO_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk i2c_clk = {
+	.id = 0,
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_I2C1_REG,
+	.enable_shift = CCM_PCCR_I2C1_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_KPP_REG,
+	.enable_shift = CCM_PCCR_KPP_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_OWIRE_REG,
+	.enable_shift = CCM_PCCR_OWIRE_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_RTC_REG,
+	.enable_shift = CCM_PCCR_RTC_OFFSET,
+	.disable = _clk_disable,
+};
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+	div = parent_rate / rate;
+	if (parent_rate % rate)
+		div++;
+
+	if (div > 8)
+		div = 8;
+
+	return parent_rate / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+
+	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+	div--;
+
+	reg = __raw_readl(CCM_PCDR0);
+
+	if (clk->parent == &usb_clk[0]) {
+		reg &= ~CCM_PCDR0_48MDIV_MASK;
+		reg |= div << CCM_PCDR0_48MDIV_OFFSET;
+	}
+	__raw_writel(reg, CCM_PCDR0);
+
+	return 0;
+}
+
+static unsigned long _clk_clko_recalc(struct clk *clk)
+{
+	u32 div = 0;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &usb_clk[0]) /* 48M */
+		div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
+			 >> CCM_PCDR0_48MDIV_OFFSET;
+	div++;
+
+	return parent_rate / div;
+}
+
+static struct clk clko_clk;
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
+
+	if (parent == &ckil_clk)
+		reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &fpm_clk)
+		reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ckih_clk)
+		reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == mpll_clk.parent)
+		reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == spll_clk.parent)
+		reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &mpll_clk)
+		reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &spll_clk)
+		reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &fclk_clk)
+		reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &hclk_clk)
+		reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ipg_clk)
+		reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[0])
+		reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[1])
+		reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[2])
+		reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[3])
+		reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ssi_clk[0])
+		reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ssi_clk[1])
+		reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &nfc_clk)
+		reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &usb_clk[0])
+		reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &clko_clk)
+		reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, CCM_CCSR);
+
+	return 0;
+}
+
+static struct clk clko_clk = {
+	.get_rate = _clk_clko_recalc,
+	.set_rate = _clk_clko_set_rate,
+	.round_rate = _clk_clko_round_rate,
+	.set_parent = _clk_clko_set_parent,
+};
+
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+static struct clk_lookup lookups[] = {
+/* It's unlikely that any driver wants one of them directly:
+	_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+	_REGISTER_CLOCK(NULL, "ckil", ckil_clk)
+	_REGISTER_CLOCK(NULL, "fpm", fpm_clk)
+	_REGISTER_CLOCK(NULL, "mpll", mpll_clk)
+	_REGISTER_CLOCK(NULL, "spll", spll_clk)
+	_REGISTER_CLOCK(NULL, "fclk", fclk_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hclk_clk)
+	_REGISTER_CLOCK(NULL, "ipg", ipg_clk)
+*/
+	_REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
+	_REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
+	_REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
+	_REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
+	_REGISTER_CLOCK(NULL, "clko", clko_clk)
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
+	_REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
+	_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
+	_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
+	_REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
+	_REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
+	_REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
+	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
+	_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
+	_REGISTER_CLOCK(NULL, "usb", usb_clk[0])
+	_REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
+	_REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+	_REGISTER_CLOCK(NULL, "dma", dma_clk[0])
+	_REGISTER_CLOCK(NULL, "brom", brom_clk)
+	_REGISTER_CLOCK(NULL, "emma", emma_clk[0])
+	_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
+	_REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+	_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+	_REGISTER_CLOCK(NULL, "owire", owire_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+};
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+	int i;
+	u32 cscr;
+
+	external_low_reference = lref;
+	external_high_reference = href;
+
+	/* detect clock reference for both system PLL */
+	cscr = CSCR();
+	if (cscr & CCM_CSCR_MCU)
+		mpll_clk.parent = &ckih_clk;
+	else
+		mpll_clk.parent = &fpm_clk;
+
+	if (cscr & CCM_CSCR_SP)
+		spll_clk.parent = &ckih_clk;
+	else
+		spll_clk.parent = &fpm_clk;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	/* Turn off all clock gates */
+	__raw_writel(0, CCM_PCCR0);
+	__raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
+
+	/* This turns of the serial PLL as well */
+	spll_clk.disable(&spll_clk);
+
+	/* This will propagate to all children and init all the clock rates. */
+	clk_enable(&per_clk[0]);
+	clk_enable(&gpio_clk);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+	clk_enable(&uart_clk[0]);
+#endif
+
+	mxc_timer_init(&gpt_clk[0]);
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/clock_imx27.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/clock_imx27.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/clock_imx27.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/clock_imx27.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -20,23 +21,60 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
 
 #include <mach/clock.h>
 #include <mach/common.h>
-#include <asm/div64.h>
+#include <mach/hardware.h>
 
-#include "crm_regs.h"
+/* Register offsets */
+#define CCM_CSCR                (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
+#define CCM_MPCTL0              (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
+#define CCM_MPCTL1              (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
+#define CCM_SPCTL0              (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
+#define CCM_SPCTL1              (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
+#define CCM_OSC26MCTL           (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
+#define CCM_PCDR0               (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
+#define CCM_PCDR1               (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
+#define CCM_PCCR0               (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
+#define CCM_PCCR1               (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
+#define CCM_CCSR                (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
+#define CCM_PMCTL               (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
+#define CCM_PMCOUNT             (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
+#define CCM_WKGDCTL             (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
 
-static struct clk ckil_clk;
-static struct clk mpll_clk;
-static struct clk mpll_main_clk[];
-static struct clk spll_clk;
+#define CCM_CSCR_UPDATE_DIS	(1 << 31)
+#define CCM_CSCR_SSI2		(1 << 23)
+#define CCM_CSCR_SSI1		(1 << 22)
+#define CCM_CSCR_VPU		(1 << 21)
+#define CCM_CSCR_MSHC           (1 << 20)
+#define CCM_CSCR_SPLLRES        (1 << 19)
+#define CCM_CSCR_MPLLRES        (1 << 18)
+#define CCM_CSCR_SP             (1 << 17)
+#define CCM_CSCR_MCU            (1 << 16)
+#define CCM_CSCR_OSC26MDIV      (1 << 4)
+#define CCM_CSCR_OSC26M         (1 << 3)
+#define CCM_CSCR_FPM            (1 << 2)
+#define CCM_CSCR_SPEN           (1 << 1)
+#define CCM_CSCR_MPEN           (1 << 0)
 
-static int _clk_enable(struct clk *clk)
+/* i.MX27 TO 2+ */
+#define CCM_CSCR_ARM_SRC        (1 << 15)
+
+#define CCM_SPCTL1_LF           (1 << 15)
+#define CCM_SPCTL1_BRMO         (1 << 6)
+
+static struct clk mpll_main1_clk, mpll_main2_clk;
+
+static int clk_pccr_enable(struct clk *clk)
 {
 	unsigned long reg;
 
+	if (!clk->enable_reg)
+		return 0;
+
 	reg = __raw_readl(clk->enable_reg);
 	reg |= 1 << clk->enable_shift;
 	__raw_writel(reg, clk->enable_reg);
@@ -44,16 +82,19 @@ static int _clk_enable(struct clk *clk)
 	return 0;
 }
 
-static void _clk_disable(struct clk *clk)
+static void clk_pccr_disable(struct clk *clk)
 {
 	unsigned long reg;
 
+	if (!clk->enable_reg)
+		return;
+
 	reg = __raw_readl(clk->enable_reg);
 	reg &= ~(1 << clk->enable_shift);
 	__raw_writel(reg, clk->enable_reg);
 }
 
-static int _clk_spll_enable(struct clk *clk)
+static int clk_spll_enable(struct clk *clk)
 {
 	unsigned long reg;
 
@@ -61,13 +102,12 @@ static int _clk_spll_enable(struct clk *
 	reg |= CCM_CSCR_SPEN;
 	__raw_writel(reg, CCM_CSCR);
 
-	while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
-		;
+	while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
 
 	return 0;
 }
 
-static void _clk_spll_disable(struct clk *clk)
+static void clk_spll_disable(struct clk *clk)
 {
 	unsigned long reg;
 
@@ -76,192 +116,30 @@ static void _clk_spll_disable(struct clk
 	__raw_writel(reg, CCM_CSCR);
 }
 
-static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR0);
-	reg |= mask0;
-	__raw_writel(reg, CCM_PCCR0);
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg |= mask1;
-	__raw_writel(reg, CCM_PCCR1);
-
-}
-
-static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR0);
-	reg &= ~mask0;
-	__raw_writel(reg, CCM_PCCR0);
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg &= ~mask1;
-	__raw_writel(reg, CCM_PCCR1);
-}
-
-static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg |= mask1;
-	__raw_writel(reg, CCM_PCCR1);
-
-	reg = __raw_readl(CCM_PCCR0);
-	reg |= mask0;
-	__raw_writel(reg, CCM_PCCR0);
-}
-
-static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg &= ~mask1;
-	__raw_writel(reg, CCM_PCCR1);
-
-	reg = __raw_readl(CCM_PCCR0);
-	reg &= ~mask0;
-	__raw_writel(reg, CCM_PCCR0);
-}
-
-static int _clk_dma_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
-
-	return 0;
-}
-
-static void _clk_dma_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
-}
-
-static int _clk_rtic_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
-
-	return 0;
-}
-
-static void _clk_rtic_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
-}
-
-static int _clk_emma_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
-
-	return 0;
-}
-
-static void _clk_emma_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
-}
-
-static int _clk_slcdc_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
-
-	return 0;
-}
-
-static void _clk_slcdc_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
-}
-
-static int _clk_fec_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
-
-	return 0;
-}
-
-static void _clk_fec_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
-}
-
-static int _clk_vpu_enable(struct clk *clk)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
-	__raw_writel(reg, CCM_PCCR1);
-
-	return 0;
-}
-
-static void _clk_vpu_disable(struct clk *clk)
-{
-	unsigned long reg;
-
-	reg = __raw_readl(CCM_PCCR1);
-	reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
-	__raw_writel(reg, CCM_PCCR1);
-}
-
-static int _clk_sahara2_enable(struct clk *clk)
-{
-	_clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
-
-	return 0;
-}
-
-static void _clk_sahara2_disable(struct clk *clk)
-{
-	_clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
-}
-
-static int _clk_mstick1_enable(struct clk *clk)
-{
-	_clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
-
-	return 0;
-}
-
-static void _clk_mstick1_disable(struct clk *clk)
-{
-	_clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
-}
-
-#define CSCR() (__raw_readl(CCM_CSCR))
-#define PCDR0() (__raw_readl(CCM_PCDR0))
-#define PCDR1() (__raw_readl(CCM_PCDR1))
-
-static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
+static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
 {
-	int cscr = CSCR();
+	int cscr = __raw_readl(CCM_CSCR);
 
 	if (clk->parent == parent)
 		return 0;
 
 	if (mx27_revision() >= CHIP_REV_2_0) {
-		if (parent == &mpll_main_clk[0]) {
+		if (parent == &mpll_main1_clk) {
 			cscr |= CCM_CSCR_ARM_SRC;
 		} else {
-			if (parent == &mpll_main_clk[1])
+			if (parent == &mpll_main2_clk)
 				cscr &= ~CCM_CSCR_ARM_SRC;
 			else
 				return -EINVAL;
 		}
 		__raw_writel(cscr, CCM_CSCR);
-	} else
-		return -ENODEV;
-
-	clk->parent = parent;
-	return 0;
+		clk->parent = parent;
+		return 0;
+	}
+	return -ENODEV;
 }
 
-static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
 {
 	int div;
 	unsigned long parent_rate;
@@ -278,7 +156,7 @@ static unsigned long _clk_cpu_round_rate
 	return parent_rate / div;
 }
 
-static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+static int set_rate_cpu(struct clk *clk, unsigned long rate)
 {
 	unsigned int div;
 	uint32_t reg;
@@ -295,19 +173,18 @@ static int _clk_cpu_set_rate(struct clk
 
 	reg = __raw_readl(CCM_CSCR);
 	if (mx27_revision() >= CHIP_REV_2_0) {
-		reg &= ~CCM_CSCR_ARM_MASK;
-		reg |= div << CCM_CSCR_ARM_OFFSET;
-		reg &= ~0x06;
-		__raw_writel(reg | 0x80000000, CCM_CSCR);
+		reg &= ~(3 << 12);
+		reg |= div << 12;
+		reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
+		__raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
 	} else {
-		printk(KERN_ERR "Cant set CPU frequency!\n");
+		printk(KERN_ERR "Can't set CPU frequency!\n");
 	}
 
 	return 0;
 }
 
-static unsigned long _clk_perclkx_round_rate(struct clk *clk,
-					     unsigned long rate)
+static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
 {
 	u32 div;
 	unsigned long parent_rate;
@@ -324,7 +201,7 @@ static unsigned long _clk_perclkx_round_
 	return parent_rate / div;
 }
 
-static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+static int set_rate_per(struct clk *clk, unsigned long rate)
 {
 	u32 reg;
 	u32 div;
@@ -340,84 +217,65 @@ static int _clk_perclkx_set_rate(struct
 		return -EINVAL;
 	div--;
 
-	reg =
-	    __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
-				       (clk->id << 3));
+	reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
 	reg |= div << (clk->id << 3);
 	__raw_writel(reg, CCM_PCDR1);
 
 	return 0;
 }
 
-static unsigned long _clk_usb_recalc(struct clk *clk)
+static unsigned long get_rate_usb(struct clk *clk)
 {
 	unsigned long usb_pdf;
 	unsigned long parent_rate;
 
 	parent_rate = clk_get_rate(clk->parent);
 
-	usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+	usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
 
 	return parent_rate / (usb_pdf + 1U);
 }
 
-static unsigned long _clk_ssi1_recalc(struct clk *clk)
+static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
 {
-	unsigned long ssi1_pdf;
 	unsigned long parent_rate;
 
 	parent_rate = clk_get_rate(clk->parent);
 
-	ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
-					CCM_PCDR0_SSI1BAUDDIV_OFFSET;
-
 	if (mx27_revision() >= CHIP_REV_2_0)
-		ssi1_pdf += 4;
+		pdf += 4;  /* MX27 TO2+ */
 	else
-		ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf;
+		pdf = (pdf < 2) ? 124UL : pdf;  /* MX21 & MX27 TO1 */
 
-	return 2UL * parent_rate / ssi1_pdf;
+	return 2UL * parent_rate / pdf;
 }
 
-static unsigned long _clk_ssi2_recalc(struct clk *clk)
+static unsigned long get_rate_ssi1(struct clk *clk)
 {
-	unsigned long ssi2_pdf;
-	unsigned long parent_rate;
-
-	parent_rate = clk_get_rate(clk->parent);
-
-	ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
-	    CCM_PCDR0_SSI2BAUDDIV_OFFSET;
-
-	if (mx27_revision() >= CHIP_REV_2_0)
-		ssi2_pdf += 4;
-	else
-		ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
+	return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
+}
 
-	return 2UL * parent_rate / ssi2_pdf;
+static unsigned long get_rate_ssi2(struct clk *clk)
+{
+	return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
 }
 
-static unsigned long _clk_nfc_recalc(struct clk *clk)
+static unsigned long get_rate_nfc(struct clk *clk)
 {
 	unsigned long nfc_pdf;
 	unsigned long parent_rate;
 
 	parent_rate = clk_get_rate(clk->parent);
 
-	if (mx27_revision() >= CHIP_REV_2_0) {
-		nfc_pdf =
-		    (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >>
-		    CCM_PCDR0_NFCDIV2_OFFSET;
-	} else {
-		nfc_pdf =
-		    (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
-		    CCM_PCDR0_NFCDIV_OFFSET;
-	}
+	if (mx27_revision() >= CHIP_REV_2_0)
+		nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
+	else
+		nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
 
 	return parent_rate / (nfc_pdf + 1);
 }
 
-static unsigned long _clk_vpu_recalc(struct clk *clk)
+static unsigned long get_rate_vpu(struct clk *clk)
 {
 	unsigned long vpu_pdf;
 	unsigned long parent_rate;
@@ -425,25 +283,27 @@ static unsigned long _clk_vpu_recalc(str
 	parent_rate = clk_get_rate(clk->parent);
 
 	if (mx27_revision() >= CHIP_REV_2_0) {
-		vpu_pdf =
-		    (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
-		    CCM_PCDR0_VPUDIV2_OFFSET;
+		vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
 		vpu_pdf += 4;
 	} else {
-		vpu_pdf =
-		    (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
-		    CCM_PCDR0_VPUDIV_OFFSET;
+		vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
 		vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
 	}
+
 	return 2UL * parent_rate / vpu_pdf;
 }
 
-static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
 {
 	return clk->parent->round_rate(clk->parent, rate);
 }
 
-static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long get_rate_parent(struct clk *clk)
+{
+	return clk_get_rate(clk->parent);
+}
+
+static int set_rate_parent(struct clk *clk, unsigned long rate)
 {
 	return clk->parent->set_rate(clk->parent, rate);
 }
@@ -451,1112 +311,380 @@ static int _clk_parent_set_rate(struct c
 /* in Hz */
 static unsigned long external_high_reference = 26000000;
 
-static unsigned long get_high_reference_clock_rate(struct clk *clk)
+static unsigned long get_rate_high_reference(struct clk *clk)
 {
 	return external_high_reference;
 }
 
-/*
- * the high frequency external clock reference
- * Default case is 26MHz. Could be changed at runtime
- * with a call to change_external_high_reference()
- */
-static struct clk ckih_clk = {
-	.name = "ckih",
-	.get_rate = get_high_reference_clock_rate,
-};
-
 /* in Hz */
 static unsigned long external_low_reference = 32768;
 
-static unsigned long get_low_reference_clock_rate(struct clk *clk)
+static unsigned long get_rate_low_reference(struct clk *clk)
 {
 	return external_low_reference;
 }
 
-/*
- * the low frequency external clock reference
- * Default case is 32.768kHz Could be changed at runtime
- * with a call to change_external_low_reference()
- */
-static struct clk ckil_clk = {
-	.name = "ckil",
-	.get_rate = get_low_reference_clock_rate,
-};
-
-static unsigned long get_mpll_clk(struct clk *clk)
+static unsigned long get_rate_fpm(struct clk *clk)
 {
-	uint32_t reg;
-	unsigned long ref_clk;
-	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
-	unsigned long long temp;
-
-	ref_clk = clk_get_rate(clk->parent);
-
-	reg = __raw_readl(CCM_MPCTL0);
-	pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
-	mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
-	mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
-	mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
-
-	mfi = (mfi <= 5) ? 5 : mfi;
-	temp = 2LL * ref_clk * mfn;
-	do_div(temp, mfd + 1);
-	temp = 2LL * ref_clk * mfi + temp;
-	do_div(temp, pdf + 1);
-
-	return (unsigned long)temp;
+	return clk_get_rate(clk->parent) * 1024;
 }
 
-static struct clk mpll_clk = {
-	.name = "mpll",
-	.parent = &ckih_clk,
-	.get_rate = get_mpll_clk,
-};
+static unsigned long get_rate_mpll(struct clk *clk)
+{
+	return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
+			clk_get_rate(clk->parent));
+}
 
-static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
+static unsigned long get_rate_mpll_main(struct clk *clk)
 {
 	unsigned long parent_rate;
 
 	parent_rate = clk_get_rate(clk->parent);
 
 	/* i.MX27 TO2:
-	 * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
-	 * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
+	 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
+	 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
 	 */
-
 	if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
 		return 2UL * parent_rate / 3UL;
 
 	return parent_rate;
 }
 
-static struct clk mpll_main_clk[] = {
-	{
-		/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
-		 * It provide the clock source whose rate is same as MPLL
-		 */
-		.name = "mpll_main",
-		.id = 0,
-		.parent = &mpll_clk,
-		.get_rate = _clk_mpll_main_get_rate
-	}, {
-		/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
-		 * It provide the clock source whose rate is same MPLL * 2/3
-		 */
-		.name = "mpll_main",
-		.id = 1,
-		.parent = &mpll_clk,
-		.get_rate = _clk_mpll_main_get_rate
-	}
-};
-
-static unsigned long get_spll_clk(struct clk *clk)
+static unsigned long get_rate_spll(struct clk *clk)
 {
 	uint32_t reg;
-	unsigned long ref_clk;
-	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
-	unsigned long long temp;
+	unsigned long rate;
 
-	ref_clk = clk_get_rate(clk->parent);
+	rate = clk_get_rate(clk->parent);
 
 	reg = __raw_readl(CCM_SPCTL0);
-	/*TODO: This is TO2 Bug */
+
+	/* On TO2 we have to write the value back. Otherwise we
+	 * read 0 from this register the next time.
+	 */
 	if (mx27_revision() >= CHIP_REV_2_0)
 		__raw_writel(reg, CCM_SPCTL0);
 
-	pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
-	mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
-	mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
-	mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
-
-	mfi = (mfi <= 5) ? 5 : mfi;
-	temp = 2LL * ref_clk * mfn;
-	do_div(temp, mfd + 1);
-	temp = 2LL * ref_clk * mfi + temp;
-	do_div(temp, pdf + 1);
-
-	return (unsigned long)temp;
+	return mxc_decode_pll(reg, rate);
 }
 
-static struct clk spll_clk = {
-	.name = "spll",
-	.parent = &ckih_clk,
-	.get_rate = get_spll_clk,
-	.enable = _clk_spll_enable,
-	.disable = _clk_spll_disable,
-};
-
-static unsigned long get_cpu_clk(struct clk *clk)
+static unsigned long get_rate_cpu(struct clk *clk)
 {
 	u32 div;
 	unsigned long rate;
 
 	if (mx27_revision() >= CHIP_REV_2_0)
-		div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
+		div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
 	else
-		div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+		div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
 
 	rate = clk_get_rate(clk->parent);
 	return rate / (div + 1);
 }
 
-static struct clk cpu_clk = {
-	.name = "cpu_clk",
-	.parent = &mpll_main_clk[1],
-	.set_parent = _clk_cpu_set_parent,
-	.round_rate = _clk_cpu_round_rate,
-	.get_rate = get_cpu_clk,
-	.set_rate = _clk_cpu_set_rate,
-};
-
-static unsigned long get_ahb_clk(struct clk *clk)
+static unsigned long get_rate_ahb(struct clk *clk)
 {
-	unsigned long rate;
-	unsigned long bclk_pdf;
+	unsigned long rate, bclk_pdf;
 
 	if (mx27_revision() >= CHIP_REV_2_0)
-		bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK)
-					>> CCM_CSCR_AHB_OFFSET;
+		bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
 	else
-		bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
-					>> CCM_CSCR_BCLK_OFFSET;
+		bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
 
 	rate = clk_get_rate(clk->parent);
 	return rate / (bclk_pdf + 1);
 }
 
-static struct clk ahb_clk = {
-	.name = "ahb_clk",
-	.parent = &mpll_main_clk[1],
-	.get_rate = get_ahb_clk,
-};
-
-static unsigned long get_ipg_clk(struct clk *clk)
+static unsigned long get_rate_ipg(struct clk *clk)
 {
-	unsigned long rate;
-	unsigned long ipg_pdf;
+	unsigned long rate, ipg_pdf;
 
 	if (mx27_revision() >= CHIP_REV_2_0)
 		return clk_get_rate(clk->parent);
 	else
-		ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+		ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
 
 	rate = clk_get_rate(clk->parent);
 	return rate / (ipg_pdf + 1);
 }
 
-static struct clk ipg_clk = {
-	.name = "ipg_clk",
-	.parent = &ahb_clk,
-	.get_rate = get_ipg_clk,
-};
-
-static unsigned long _clk_perclkx_recalc(struct clk *clk)
+static unsigned long get_rate_per(struct clk *clk)
 {
-	unsigned long perclk_pdf;
-	unsigned long parent_rate;
+	unsigned long perclk_pdf, parent_rate;
 
 	parent_rate = clk_get_rate(clk->parent);
 
 	if (clk->id < 0 || clk->id > 3)
 		return 0;
 
-	perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+	perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
 
 	return parent_rate / (perclk_pdf + 1);
 }
 
-static struct clk per_clk[] = {
-	{
-		.name = "per_clk",
-		.id = 0,
-		.parent = &mpll_main_clk[1],
-		.get_rate = _clk_perclkx_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "per_clk",
-		.id = 1,
-		.parent = &mpll_main_clk[1],
-		.get_rate = _clk_perclkx_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "per_clk",
-		.id = 2,
-		.parent = &mpll_main_clk[1],
-		.round_rate = _clk_perclkx_round_rate,
-		.set_rate = _clk_perclkx_set_rate,
-		.get_rate = _clk_perclkx_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "per_clk",
-		.id = 3,
-		.parent = &mpll_main_clk[1],
-		.round_rate = _clk_perclkx_round_rate,
-		.set_rate = _clk_perclkx_set_rate,
-		.get_rate = _clk_perclkx_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart1_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 0,
-		.parent = &per_clk[0],
-		.secondary = &uart1_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART1_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart2_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 1,
-		.parent = &per_clk[0],
-		.secondary = &uart2_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART2_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart3_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 2,
-		.parent = &per_clk[0],
-		.secondary = &uart3_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 2,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART3_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart4_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 3,
-		.parent = &per_clk[0],
-		.secondary = &uart4_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 3,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART4_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart5_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 4,
-		.parent = &per_clk[0],
-		.secondary = &uart5_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 4,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART5_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-struct clk uart6_clk[] = {
-	{
-		.name = "uart_clk",
-		.id = 5,
-		.parent = &per_clk[0],
-		.secondary = &uart6_clk[1],
-	}, {
-		.name = "uart_ipg_clk",
-		.id = 5,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_UART6_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk gpt1_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 0,
-		.parent = &per_clk[0],
-		.secondary = &gpt1_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT1_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk gpt2_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 1,
-		.parent = &per_clk[0],
-		.secondary = &gpt2_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT2_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk gpt3_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 2,
-		.parent = &per_clk[0],
-		.secondary = &gpt3_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 2,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT3_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk gpt4_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 3,
-		.parent = &per_clk[0],
-		.secondary = &gpt4_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 3,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT4_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk gpt5_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 4,
-		.parent = &per_clk[0],
-		.secondary = &gpt5_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 4,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT5_OFFSET,
-		.disable = _clk_disable,
-	},
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz. Could be changed at runtime
+ * with a call to change_external_high_reference()
+ */
+static struct clk ckih_clk = {
+	.get_rate	= get_rate_high_reference,
 };
 
-static struct clk gpt6_clk[] = {
-	{
-		.name = "gpt_clk",
-		.id = 5,
-		.parent = &per_clk[0],
-		.secondary = &gpt6_clk[1],
-	}, {
-		.name = "gpt_ipg_clk",
-		.id = 5,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_GPT6_OFFSET,
-		.disable = _clk_disable,
-	},
+static struct clk mpll_clk = {
+	.parent		= &ckih_clk,
+	.get_rate	= get_rate_mpll,
 };
 
-static struct clk pwm_clk[] = {
-	{
-		.name = "pwm_clk",
-		.parent = &per_clk[0],
-		.secondary = &pwm_clk[1],
-	}, {
-		.name = "pwm_clk",
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_PWM_OFFSET,
-		.disable = _clk_disable,
-	},
+/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
+ * It provides the clock source whose rate is same as MPLL
+ */
+static struct clk mpll_main1_clk = {
+	.id		= 0,
+	.parent		= &mpll_clk,
+	.get_rate	= get_rate_mpll_main,
 };
 
-static struct clk sdhc1_clk[] = {
-	{
-		.name = "sdhc_clk",
-		.id = 0,
-		.parent = &per_clk[1],
-		.secondary = &sdhc1_clk[1],
-	}, {
-		.name = "sdhc_ipg_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_SDHC1_OFFSET,
-		.disable = _clk_disable,
-	},
+/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
+ * It provides the clock source whose rate is same MPLL * 2 / 3
+ */
+static struct clk mpll_main2_clk = {
+	.id		= 1,
+	.parent		= &mpll_clk,
+	.get_rate	= get_rate_mpll_main,
 };
 
-static struct clk sdhc2_clk[] = {
-	{
-		.name = "sdhc_clk",
-		.id = 1,
-		.parent = &per_clk[1],
-		.secondary = &sdhc2_clk[1],
-	}, {
-		.name = "sdhc_ipg_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_SDHC2_OFFSET,
-		.disable = _clk_disable,
-	},
+static struct clk ahb_clk = {
+	.parent		= &mpll_main2_clk,
+	.get_rate	= get_rate_ahb,
 };
 
-static struct clk sdhc3_clk[] = {
-	{
-		.name = "sdhc_clk",
-		.id = 2,
-		.parent = &per_clk[1],
-		.secondary = &sdhc3_clk[1],
-	}, {
-		.name = "sdhc_ipg_clk",
-		.id = 2,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_SDHC3_OFFSET,
-		.disable = _clk_disable,
-	},
+static struct clk ipg_clk = {
+	.parent		= &ahb_clk,
+	.get_rate	= get_rate_ipg,
 };
 
-static struct clk cspi1_clk[] = {
-	{
-		.name = "cspi_clk",
-		.id = 0,
-		.parent = &per_clk[1],
-		.secondary = &cspi1_clk[1],
-	}, {
-		.name = "cspi_ipg_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_CSPI1_OFFSET,
-		.disable = _clk_disable,
-	},
+static struct clk cpu_clk = {
+	.parent = &mpll_main2_clk,
+	.set_parent = clk_cpu_set_parent,
+	.round_rate = round_rate_cpu,
+	.get_rate = get_rate_cpu,
+	.set_rate = set_rate_cpu,
 };
 
-static struct clk cspi2_clk[] = {
-	{
-		.name = "cspi_clk",
-		.id = 1,
-		.parent = &per_clk[1],
-		.secondary = &cspi2_clk[1],
-	}, {
-		.name = "cspi_ipg_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_CSPI2_OFFSET,
-		.disable = _clk_disable,
-	},
+static struct clk spll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = get_rate_spll,
+	.enable = clk_spll_enable,
+	.disable = clk_spll_disable,
 };
 
-static struct clk cspi3_clk[] = {
-	{
-		.name = "cspi_clk",
-		.id = 2,
-		.parent = &per_clk[1],
-		.secondary = &cspi3_clk[1],
-	}, {
-		.name = "cspi_ipg_clk",
-		.id = 2,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_CSPI3_OFFSET,
-		.disable = _clk_disable,
-	},
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+	.get_rate = get_rate_low_reference,
 };
 
-static struct clk lcdc_clk[] = {
-	{
-		.name = "lcdc_clk",
-		.parent = &per_clk[2],
-		.secondary = &lcdc_clk[1],
-		.round_rate = _clk_parent_round_rate,
-		.set_rate = _clk_parent_set_rate,
-	}, {
-		.name = "lcdc_ipg_clk",
-		.parent = &ipg_clk,
-		.secondary = &lcdc_clk[2],
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_LCDC_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "lcdc_ahb_clk",
-		.parent = &ahb_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
-		.disable = _clk_disable,
-	},
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+	.parent = &ckil_clk,
+	.get_rate = get_rate_fpm,
 };
 
-static struct clk csi_clk[] = {
-	{
-		.name = "csi_perclk",
-		.parent = &per_clk[3],
-		.secondary = &csi_clk[1],
-		.round_rate = _clk_parent_round_rate,
-		.set_rate = _clk_parent_set_rate,
-	}, {
-		.name = "csi_ahb_clk",
-		.parent = &ahb_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
-		.disable = _clk_disable,
-	},
-};
+#define PCCR0 CCM_PCCR0
+#define PCCR1 CCM_PCCR1
 
-static struct clk usb_clk[] = {
-	{
-		.name = "usb_clk",
-		.parent = &spll_clk,
-		.get_rate = _clk_usb_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_USBOTG_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "usb_ahb_clk",
-		.parent = &ahb_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
-		.disable = _clk_disable,
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.enable		= clk_pccr_enable,	\
+		.disable	= clk_pccr_disable,	\
+		.secondary	= s,			\
+		.parent		= p,			\
 	}
-};
-
-static struct clk ssi1_clk[] = {
-	{
-		.name = "ssi_clk",
-		.id = 0,
-		.parent = &mpll_main_clk[1],
-		.secondary = &ssi1_clk[1],
-		.get_rate = _clk_ssi1_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "ssi_ipg_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
-		.disable = _clk_disable,
-	},
-};
 
-static struct clk ssi2_clk[] = {
-	{
-		.name = "ssi_clk",
-		.id = 1,
-		.parent = &mpll_main_clk[1],
-		.secondary = &ssi2_clk[1],
-		.get_rate = _clk_ssi2_recalc,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR1,
-		.enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "ssi_ipg_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
-		.disable = _clk_disable,
-	},
-};
-
-static struct clk nfc_clk = {
-	.name = "nfc_clk",
-	.parent = &cpu_clk,
-	.get_rate = _clk_nfc_recalc,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk vpu_clk = {
-	.name = "vpu_clk",
-	.parent = &mpll_main_clk[1],
-	.get_rate = _clk_vpu_recalc,
-	.enable = _clk_vpu_enable,
-	.disable = _clk_vpu_disable,
-};
-
-static struct clk dma_clk = {
-	.name = "dma_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_dma_enable,
-	.disable = _clk_dma_disable,
-};
-
-static struct clk rtic_clk = {
-	.name = "rtic_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_rtic_enable,
-	.disable = _clk_rtic_disable,
-};
-
-static struct clk brom_clk = {
-	.name = "brom_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk emma_clk = {
-	.name = "emma_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_emma_enable,
-	.disable = _clk_emma_disable,
-};
-
-static struct clk slcdc_clk = {
-	.name = "slcdc_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_slcdc_enable,
-	.disable = _clk_slcdc_disable,
-};
-
-static struct clk fec_clk = {
-	.name = "fec_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_fec_enable,
-	.disable = _clk_fec_disable,
-};
-
-static struct clk emi_clk = {
-	.name = "emi_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk sahara2_clk = {
-	.name = "sahara_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_sahara2_enable,
-	.disable = _clk_sahara2_disable,
-};
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p)	\
+	static struct clk name = {				\
+		.id		= i,				\
+		.enable_reg	= er,				\
+		.enable_shift	= es,				\
+		.get_rate	= get_rate_##getsetround,	\
+		.set_rate	= set_rate_##getsetround,	\
+		.round_rate	= round_rate_##getsetround,	\
+		.enable		= clk_pccr_enable,		\
+		.disable	= clk_pccr_disable,		\
+		.secondary	= s,				\
+		.parent		= p,				\
+	}
 
-static struct clk ata_clk = {
-	.name = "ata_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
-	.disable = _clk_disable,
-};
+/* Forward declaration to keep the following list in order */
+static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
+		  dma_clk1, lcdc_clk2, vpu_clk1;
 
-static struct clk mstick1_clk = {
-	.name = "mstick1_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_mstick1_enable,
-	.disable = _clk_mstick1_disable,
-};
+/* All clocks we can gate through PCCRx in the order of PCCRx bits */
+DEFINE_CLOCK(ssi2_clk1,    1, PCCR0,  0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ssi1_clk1,    0, PCCR0,  1, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(slcdc_clk,    0, PCCR0,  2, NULL, &slcdc_clk1, &ahb_clk);
+DEFINE_CLOCK(sdhc3_clk1,   0, PCCR0,  3, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc2_clk1,   0, PCCR0,  4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc1_clk1,   0, PCCR0,  5, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(scc_clk,      0, PCCR0,  6, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sahara2_clk,  0, PCCR0,  7, NULL, &sahara2_clk1, &ahb_clk);
+DEFINE_CLOCK(rtic_clk,     0, PCCR0,  8, NULL, &rtic_clk1, &ahb_clk);
+DEFINE_CLOCK(rtc_clk,      0, PCCR0,  9, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk1,     0, PCCR0, 11, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(owire_clk,    0, PCCR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mstick_clk1,  0, PCCR0, 13, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(lcdc_clk1,    0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
+DEFINE_CLOCK(kpp_clk,      0, PCCR0, 15, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(iim_clk,      0, PCCR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c2_clk,     1, PCCR0, 17, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c1_clk,     0, PCCR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt6_clk1,    0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt5_clk1,    0, PCCR0, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt4_clk1,    0, PCCR0, 21, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt3_clk1,    0, PCCR0, 22, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt2_clk1,    0, PCCR0, 23, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt1_clk1,    0, PCCR0, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpio_clk,     0, PCCR0, 25, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(fec_clk,      0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
+DEFINE_CLOCK(emma_clk,     0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
+DEFINE_CLOCK(dma_clk,      0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi13_clk1,  0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk1,   0, PCCR0, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi1_clk1,   0, PCCR0, 31, NULL, NULL, &ipg_clk);
 
-static struct clk wdog_clk = {
-	.name = "wdog_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR1_WDT_OFFSET,
-	.disable = _clk_disable,
-};
+DEFINE_CLOCK(mstick_clk,   0, PCCR1,  2, NULL, &mstick_clk1, &ipg_clk);
+DEFINE_CLOCK(nfc_clk,      0, PCCR1,  3, get_rate_nfc, NULL, &cpu_clk);
+DEFINE_CLOCK(ssi2_clk,     1, PCCR1,  4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(ssi1_clk,     0, PCCR1,  5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(vpu_clk,      0, PCCR1,  6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
+DEFINE_CLOCK1(per4_clk,    3, PCCR1,  7, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per3_clk,    2, PCCR1,  8, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per2_clk,    1, PCCR1,  9, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per1_clk,    0, PCCR1, 10, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK(usb_clk1,     0, PCCR1, 11, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(slcdc_clk1,   0, PCCR1, 12, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk1,    0, PCCR1, 14, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(lcdc_clk2,    0, PCCR1, 15, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(vpu_clk1,     0, PCCR1, 16, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(fec_clk1,     0, PCCR1, 17, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emma_clk1,    0, PCCR1, 18, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk,      0, PCCR1, 19, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(dma_clk1,     0, PCCR1, 20, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(csi_clk1,     0, PCCR1, 21, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(brom_clk,     0, PCCR1, 22, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(ata_clk,      0, PCCR1, 23, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(wdog_clk,     0, PCCR1, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk,      0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
+DEFINE_CLOCK(uart6_clk1,   0, PCCR1, 26, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart5_clk1,   0, PCCR1, 27, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart4_clk1,   0, PCCR1, 28, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart3_clk1,   0, PCCR1, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart2_clk1,   0, PCCR1, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk1,   0, PCCR1, 31, NULL, NULL, &ipg_clk);
 
-static struct clk gpio_clk = {
-	.name = "gpio_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR1,
-	.enable_shift = CCM_PCCR0_GPIO_OFFSET,
-	.disable = _clk_disable,
-};
+/* Clocks we cannot directly gate, but drivers need their rates */
+DEFINE_CLOCK(cspi1_clk,    0, 0,      0, NULL, &cspi1_clk1, &per2_clk);
+DEFINE_CLOCK(cspi2_clk,    1, 0,      0, NULL, &cspi2_clk1, &per2_clk);
+DEFINE_CLOCK(cspi3_clk,    2, 0,      0, NULL, &cspi13_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc1_clk,    0, 0,      0, NULL, &sdhc1_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc2_clk,    1, 0,      0, NULL, &sdhc2_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc3_clk,    2, 0,      0, NULL, &sdhc3_clk1, &per2_clk);
+DEFINE_CLOCK(pwm_clk,      0, 0,      0, NULL, &pwm_clk1, &per1_clk);
+DEFINE_CLOCK(gpt1_clk,     0, 0,      0, NULL, &gpt1_clk1, &per1_clk);
+DEFINE_CLOCK(gpt2_clk,     1, 0,      0, NULL, &gpt2_clk1, &per1_clk);
+DEFINE_CLOCK(gpt3_clk,     2, 0,      0, NULL, &gpt3_clk1, &per1_clk);
+DEFINE_CLOCK(gpt4_clk,     3, 0,      0, NULL, &gpt4_clk1, &per1_clk);
+DEFINE_CLOCK(gpt5_clk,     4, 0,      0, NULL, &gpt5_clk1, &per1_clk);
+DEFINE_CLOCK(gpt6_clk,     5, 0,      0, NULL, &gpt6_clk1, &per1_clk);
+DEFINE_CLOCK(uart1_clk,    0, 0,      0, NULL, &uart1_clk1, &per1_clk);
+DEFINE_CLOCK(uart2_clk,    1, 0,      0, NULL, &uart2_clk1, &per1_clk);
+DEFINE_CLOCK(uart3_clk,    2, 0,      0, NULL, &uart3_clk1, &per1_clk);
+DEFINE_CLOCK(uart4_clk,    3, 0,      0, NULL, &uart4_clk1, &per1_clk);
+DEFINE_CLOCK(uart5_clk,    4, 0,      0, NULL, &uart5_clk1, &per1_clk);
+DEFINE_CLOCK(uart6_clk,    5, 0,      0, NULL, &uart6_clk1, &per1_clk);
+DEFINE_CLOCK1(lcdc_clk,    0, 0,      0, parent, &lcdc_clk1, &per3_clk);
+DEFINE_CLOCK1(csi_clk,     0, 0,      0, parent, &csi_clk1, &per4_clk);
 
-static struct clk i2c_clk[] = {
-	{
-		.name = "i2c_clk",
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_I2C1_OFFSET,
-		.disable = _clk_disable,
-	}, {
-		.name = "i2c_clk",
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable = _clk_enable,
-		.enable_reg = CCM_PCCR0,
-		.enable_shift = CCM_PCCR0_I2C2_OFFSET,
-		.disable = _clk_disable,
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
 	},
-};
-
-static struct clk iim_clk = {
-	.name = "iim_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR0,
-	.enable_shift = CCM_PCCR0_IIM_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk kpp_clk = {
-	.name = "kpp_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR0,
-	.enable_shift = CCM_PCCR0_KPP_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk owire_clk = {
-	.name = "owire_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR0,
-	.enable_shift = CCM_PCCR0_OWIRE_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk rtc_clk = {
-	.name = "rtc_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR0,
-	.enable_shift = CCM_PCCR0_RTC_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk scc_clk = {
-	.name = "scc_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = CCM_PCCR0,
-	.enable_shift = CCM_PCCR0_SCC_OFFSET,
-	.disable = _clk_disable,
-};
-
-static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
-{
-	u32 div;
-	unsigned long parent_rate;
-
-	parent_rate = clk_get_rate(clk->parent);
-	div = parent_rate / rate;
-	if (parent_rate % rate)
-		div++;
-
-	if (div > 8)
-		div = 8;
-
-	return parent_rate / div;
-}
-
-static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 reg;
-	u32 div;
-	unsigned long parent_rate;
-
-	parent_rate = clk_get_rate(clk->parent);
-
-	div = parent_rate / rate;
-
-	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
-		return -EINVAL;
-	div--;
-
-	reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
-	reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
-	__raw_writel(reg, CCM_PCDR0);
-
-	return 0;
-}
 
-static unsigned long _clk_clko_recalc(struct clk *clk)
-{
-	u32 div;
-	unsigned long parent_rate;
-
-	parent_rate = clk_get_rate(clk->parent);
-
-	div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
-		CCM_PCDR0_CLKODIV_OFFSET;
-	div++;
-
-	return parent_rate / div;
-}
-
-static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
-{
-	u32 reg;
-
-	reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
-
-	if (parent == &ckil_clk)
-		reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &ckih_clk)
-		reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == mpll_clk.parent)
-		reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == spll_clk.parent)
-		reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &mpll_clk)
-		reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &spll_clk)
-		reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &cpu_clk)
-		reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &ahb_clk)
-		reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &ipg_clk)
-		reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &per_clk[0])
-		reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &per_clk[1])
-		reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &per_clk[2])
-		reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &per_clk[3])
-		reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &ssi1_clk[0])
-		reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &ssi2_clk[0])
-		reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &nfc_clk)
-		reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &mstick1_clk)
-		reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &vpu_clk)
-		reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
-	else if (parent == &usb_clk[0])
-		reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
-	else
-		return -EINVAL;
-
-	__raw_writel(reg, CCM_CCSR);
-
-	return 0;
-}
-
-static int _clk_clko_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
-	__raw_writel(reg, CCM_PCDR0);
-
-	return 0;
-}
-
-static void _clk_clko_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
-	__raw_writel(reg, CCM_PCDR0);
-}
-
-static struct clk clko_clk = {
-	.name = "clko_clk",
-	.get_rate = _clk_clko_recalc,
-	.set_rate = _clk_clko_set_rate,
-	.round_rate = _clk_clko_round_rate,
-	.set_parent = _clk_clko_set_parent,
-	.enable = _clk_clko_enable,
-	.disable = _clk_clko_disable,
-};
-
-static struct clk *mxc_clks[] = {
-	&ckih_clk,
-	&ckil_clk,
-	&mpll_clk,
-	&mpll_main_clk[0],
-	&mpll_main_clk[1],
-	&spll_clk,
-	&cpu_clk,
-	&ahb_clk,
-	&ipg_clk,
-	&per_clk[0],
-	&per_clk[1],
-	&per_clk[2],
-	&per_clk[3],
-	&clko_clk,
-	&uart1_clk[0],
-	&uart1_clk[1],
-	&uart2_clk[0],
-	&uart2_clk[1],
-	&uart3_clk[0],
-	&uart3_clk[1],
-	&uart4_clk[0],
-	&uart4_clk[1],
-	&uart5_clk[0],
-	&uart5_clk[1],
-	&uart6_clk[0],
-	&uart6_clk[1],
-	&gpt1_clk[0],
-	&gpt1_clk[1],
-	&gpt2_clk[0],
-	&gpt2_clk[1],
-	&gpt3_clk[0],
-	&gpt3_clk[1],
-	&gpt4_clk[0],
-	&gpt4_clk[1],
-	&gpt5_clk[0],
-	&gpt5_clk[1],
-	&gpt6_clk[0],
-	&gpt6_clk[1],
-	&pwm_clk[0],
-	&pwm_clk[1],
-	&sdhc1_clk[0],
-	&sdhc1_clk[1],
-	&sdhc2_clk[0],
-	&sdhc2_clk[1],
-	&sdhc3_clk[0],
-	&sdhc3_clk[1],
-	&cspi1_clk[0],
-	&cspi1_clk[1],
-	&cspi2_clk[0],
-	&cspi2_clk[1],
-	&cspi3_clk[0],
-	&cspi3_clk[1],
-	&lcdc_clk[0],
-	&lcdc_clk[1],
-	&lcdc_clk[2],
-	&csi_clk[0],
-	&csi_clk[1],
-	&usb_clk[0],
-	&usb_clk[1],
-	&ssi1_clk[0],
-	&ssi1_clk[1],
-	&ssi2_clk[0],
-	&ssi2_clk[1],
-	&nfc_clk,
-	&vpu_clk,
-	&dma_clk,
-	&rtic_clk,
-	&brom_clk,
-	&emma_clk,
-	&slcdc_clk,
-	&fec_clk,
-	&emi_clk,
-	&sahara2_clk,
-	&ata_clk,
-	&mstick1_clk,
-	&wdog_clk,
-	&gpio_clk,
-	&i2c_clk[0],
-	&i2c_clk[1],
-	&iim_clk,
-	&kpp_clk,
-	&owire_clk,
-	&rtc_clk,
-	&scc_clk,
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+	_REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+	_REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+	_REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
+	_REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
+	_REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
+	_REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
+	_REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
+	_REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
+	_REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
+	_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
+	_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+	_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+	_REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
+	_REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
+	_REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
+	_REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
+	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+	_REGISTER_CLOCK(NULL, "csi", csi_clk)
+	_REGISTER_CLOCK(NULL, "usb", usb_clk)
+	_REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
+	_REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+	_REGISTER_CLOCK(NULL, "vpu", vpu_clk)
+	_REGISTER_CLOCK(NULL, "dma", dma_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_REGISTER_CLOCK(NULL, "brom", brom_clk)
+	_REGISTER_CLOCK(NULL, "emma", emma_clk)
+	_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
+	_REGISTER_CLOCK(NULL, "ata", ata_clk)
+	_REGISTER_CLOCK(NULL, "mstick", mstick_clk)
+	_REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+	_REGISTER_CLOCK(NULL, "iim", iim_clk)
+	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+	_REGISTER_CLOCK(NULL, "scc", scc_clk)
 };
 
-void __init change_external_low_reference(unsigned long new_ref)
-{
-	external_low_reference = new_ref;
-}
-
-unsigned long __init clk_early_get_timer_rate(void)
-{
-	return clk_get_rate(&per_clk[0]);
-}
-
-static void __init probe_mxc_clocks(void)
+/* Adjust the clock path for TO2 and later */
+static void __init to2_adjust_clocks(void)
 {
-	int i;
+	unsigned long cscr = __raw_readl(CCM_CSCR);
 
 	if (mx27_revision() >= CHIP_REV_2_0) {
-		if (CSCR() & 0x8000)
-			cpu_clk.parent = &mpll_main_clk[0];
+		if (cscr & CCM_CSCR_ARM_SRC)
+			cpu_clk.parent = &mpll_main1_clk;
 
-		if (!(CSCR() & 0x00800000))
-			ssi2_clk[0].parent = &spll_clk;
+		if (!(cscr & CCM_CSCR_SSI2))
+			ssi1_clk.parent = &spll_clk;
 
-		if (!(CSCR() & 0x00400000))
-			ssi1_clk[0].parent = &spll_clk;
+		if (!(cscr & CCM_CSCR_SSI1))
+			ssi1_clk.parent = &spll_clk;
 
-		if (!(CSCR() & 0x00200000))
+		if (!(cscr & CCM_CSCR_VPU))
 			vpu_clk.parent = &spll_clk;
 	} else {
 		cpu_clk.parent = &mpll_clk;
@@ -1565,11 +693,13 @@ static void __init probe_mxc_clocks(void
 		cpu_clk.set_rate = NULL;
 		ahb_clk.parent = &mpll_clk;
 
-		for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
-			per_clk[i].parent = &mpll_clk;
+		per1_clk.parent = &mpll_clk;
+		per2_clk.parent = &mpll_clk;
+		per3_clk.parent = &mpll_clk;
+		per4_clk.parent = &mpll_clk;
 
-		ssi1_clk[0].parent = &mpll_clk;
-		ssi2_clk[0].parent = &mpll_clk;
+		ssi1_clk.parent = &mpll_clk;
+		ssi2_clk.parent = &mpll_clk;
 
 		vpu_clk.parent = &mpll_clk;
 	}
@@ -1579,47 +709,47 @@ static void __init probe_mxc_clocks(void
  * must be called very early to get information about the
  * available clock rate when the timer framework starts
  */
-int __init mxc_clocks_init(unsigned long fref)
+int __init mx27_clocks_init(unsigned long fref)
 {
-	u32 cscr;
-	struct clk **clkp;
+	u32 cscr = __raw_readl(CCM_CSCR);
+	int i;
 
 	external_high_reference = fref;
 
-	/* detect clock reference for both system PLL */
-	cscr = CSCR();
+	/* detect clock reference for both system PLLs */
 	if (cscr & CCM_CSCR_MCU)
 		mpll_clk.parent = &ckih_clk;
 	else
-		mpll_clk.parent = &ckil_clk;
+		mpll_clk.parent = &fpm_clk;
 
 	if (cscr & CCM_CSCR_SP)
 		spll_clk.parent = &ckih_clk;
 	else
-		spll_clk.parent = &ckil_clk;
+		spll_clk.parent = &fpm_clk;
 
-	probe_mxc_clocks();
+	to2_adjust_clocks();
 
-	per_clk[0].enable(&per_clk[0]);
-	gpt1_clk[1].enable(&gpt1_clk[1]);
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
 
-	for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
-		clk_register(*clkp);
+	/* Turn off all clocks we do not need */
+	__raw_writel(0, CCM_PCCR0);
+	__raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
 
-	/* Turn off all possible clocks */
-	__raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
-	__raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
-		     CCM_PCCR1);
 	spll_clk.disable(&spll_clk);
 
-	/* This will propagate to all children and init all the clock rates */
-
-	clk_enable(&emi_clk);
+	/* enable basic clocks */
+	clk_enable(&per1_clk);
 	clk_enable(&gpio_clk);
+	clk_enable(&emi_clk);
 	clk_enable(&iim_clk);
-	clk_enable(&gpt1_clk[0]);
+
 #ifdef CONFIG_DEBUG_LL_CONSOLE
-	clk_enable(&uart1_clk[0]);
+	clk_enable(&uart1_clk);
 #endif
+
+	mxc_timer_init(&gpt1_clk);
+
 	return 0;
 }
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/cpu_imx27.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/cpu_imx27.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/cpu_imx27.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/cpu_imx27.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,11 +26,11 @@
 
 #include <mach/hardware.h>
 
-#include "crm_regs.h"
-
 static int cpu_silicon_rev = -1;
 static int cpu_partnumber;
 
+#define SYS_CHIP_ID             0x00    /* The offset of CHIP ID register */
+
 static void query_silicon_parameter(void)
 {
 	u32 val;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/crm_regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/crm_regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/crm_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/crm_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,42 +38,36 @@
 #define CCM_PMCOUNT             (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
 #define CCM_WKGDCTL             (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
 
-#define CCM_CSCR_USB_OFFSET     28
-#define CCM_CSCR_USB_MASK       (0x7 << 28)
+#define CCM_CSCR_PRESC_OFFSET   29
+#define CCM_CSCR_PRESC_MASK     (0x7 << CCM_CSCR_PRESC_OFFSET)
+
+#define CCM_CSCR_USB_OFFSET     26
+#define CCM_CSCR_USB_MASK       (0x7 << CCM_CSCR_USB_OFFSET)
 #define CCM_CSCR_SD_OFFSET      24
-#define CCM_CSCR_SD_MASK        (0x3 << 24)
-#define CCM_CSCR_SSI2           (1 << 23)
-#define CCM_CSCR_SSI2_OFFSET    23
-#define CCM_CSCR_SSI1           (1 << 22)
-#define CCM_CSCR_SSI1_OFFSET    22
-#define CCM_CSCR_VPU           (1 << 21)
-#define CCM_CSCR_VPU_OFFSET    21
-#define CCM_CSCR_MSHC           (1 << 20)
-#define CCM_CSCR_SPLLRES        (1 << 19)
-#define CCM_CSCR_MPLLRES        (1 << 18)
+#define CCM_CSCR_SD_MASK        (0x3 << CCM_CSCR_SD_OFFSET)
+#define CCM_CSCR_SPLLRES        (1 << 22)
+#define CCM_CSCR_MPLLRES        (1 << 21)
+#define CCM_CSCR_SSI2_OFFSET    20
+#define CCM_CSCR_SSI2           (1 << CCM_CSCR_SSI2_OFFSET)
+#define CCM_CSCR_SSI1_OFFSET    19
+#define CCM_CSCR_SSI1           (1 << CCM_CSCR_SSI1_OFFSET)
+#define CCM_CSCR_FIR_OFFSET    	18
+#define CCM_CSCR_FIR		(1 << CCM_CSCR_FIR_OFFSET)
 #define CCM_CSCR_SP             (1 << 17)
 #define CCM_CSCR_MCU            (1 << 16)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_ARM_SRC        (1 << 15)
-#define CCM_CSCR_ARM_OFFSET     12
-#define CCM_CSCR_ARM_MASK       (0x3 << 12)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_PRESC_OFFSET   13
-#define CCM_CSCR_PRESC_MASK     (0x7 << 13)
-#define CCM_CSCR_BCLK_OFFSET    9
-#define CCM_CSCR_BCLK_MASK      (0xf << 9)
-#define CCM_CSCR_IPDIV_OFFSET   8
-#define CCM_CSCR_IPDIV          (1 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_AHB_OFFSET     8
-#define CCM_CSCR_AHB_MASK       (0x3 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_BCLK_OFFSET	10
+#define CCM_CSCR_BCLK_MASK      (0xf << CCM_CSCR_BCLK_OFFSET)
+#define CCM_CSCR_IPDIV_OFFSET   9
+#define CCM_CSCR_IPDIV          (1 << CCM_CSCR_IPDIV_OFFSET)
+
 #define CCM_CSCR_OSC26MDIV      (1 << 4)
 #define CCM_CSCR_OSC26M         (1 << 3)
 #define CCM_CSCR_FPM            (1 << 2)
 #define CCM_CSCR_SPEN           (1 << 1)
 #define CCM_CSCR_MPEN           1
 
+
+
 #define CCM_MPCTL0_CPLM         (1 << 31)
 #define CCM_MPCTL0_PD_OFFSET    26
 #define CCM_MPCTL0_PD_MASK      (0xf << 26)
@@ -109,25 +103,14 @@
 
 #define CCM_PCDR0_SSI2BAUDDIV_OFFSET    26
 #define CCM_PCDR0_SSI2BAUDDIV_MASK      (0x3f << 26)
-#define CCM_PCDR0_CLKO_EN               25
-#define CCM_PCDR0_CLKODIV_OFFSET        22
-#define CCM_PCDR0_CLKODIV_MASK          (0x7 << 22)
 #define CCM_PCDR0_SSI1BAUDDIV_OFFSET    16
 #define CCM_PCDR0_SSI1BAUDDIV_MASK      (0x3f << 16)
-/*The difinition for i.MX27 TO2*/
-#define CCM_PCDR0_VPUDIV2_OFFSET        10
-#define CCM_PCDR0_VPUDIV2_MASK          (0x3f << 10)
-#define CCM_PCDR0_NFCDIV2_OFFSET         6
-#define CCM_PCDR0_NFCDIV2_MASK           (0xf << 6)
-#define CCM_PCDR0_MSHCDIV2_MASK          0x3f
-/*The difinition for i.MX27 TO2*/
 #define CCM_PCDR0_NFCDIV_OFFSET         12
 #define CCM_PCDR0_NFCDIV_MASK           (0xf << 12)
-#define CCM_PCDR0_VPUDIV_OFFSET        8
-#define CCM_PCDR0_VPUDIV_MASK          (0xf << 8)
-#define CCM_PCDR0_MSHCDIV_OFFSET        0
-#define CCM_PCDR0_MSHCDIV_MASK          0x1f
-
+#define CCM_PCDR0_48MDIV_OFFSET		5
+#define CCM_PCDR0_48MDIV_MASK		(0x7 << CCM_PCDR0_48MDIV_OFFSET)
+#define CCM_PCDR0_FIRIDIV_OFFSET	0
+#define CCM_PCDR0_FIRIDIV_MASK		0x1f
 #define CCM_PCDR1_PERDIV4_OFFSET        24
 #define CCM_PCDR1_PERDIV4_MASK          (0x3f << 24)
 #define CCM_PCDR1_PERDIV3_OFFSET        16
@@ -137,133 +120,135 @@
 #define CCM_PCDR1_PERDIV1_OFFSET        0
 #define CCM_PCDR1_PERDIV1_MASK          0x3f
 
-#define CCM_PCCR0_CSPI1_OFFSET          31
-#define CCM_PCCR0_CSPI1_MASK            (1 << 31)
-#define CCM_PCCR0_CSPI2_OFFSET          30
-#define CCM_PCCR0_CSPI2_MASK            (1 << 30)
-#define CCM_PCCR0_CSPI3_OFFSET          29
-#define CCM_PCCR0_CSPI3_MASK            (1 << 29)
-#define CCM_PCCR0_DMA_OFFSET            28
-#define CCM_PCCR0_DMA_MASK              (1 << 28)
-#define CCM_PCCR0_EMMA_OFFSET           27
-#define CCM_PCCR0_EMMA_MASK             (1 << 27)
-#define CCM_PCCR0_FEC_OFFSET            26
-#define CCM_PCCR0_FEC_MASK              (1 << 26)
-#define CCM_PCCR0_GPIO_OFFSET           25
-#define CCM_PCCR0_GPIO_MASK             (1 << 25)
-#define CCM_PCCR0_GPT1_OFFSET           24
-#define CCM_PCCR0_GPT1_MASK             (1 << 24)
-#define CCM_PCCR0_GPT2_OFFSET           23
-#define CCM_PCCR0_GPT2_MASK             (1 << 23)
-#define CCM_PCCR0_GPT3_OFFSET           22
-#define CCM_PCCR0_GPT3_MASK             (1 << 22)
-#define CCM_PCCR0_GPT4_OFFSET           21
-#define CCM_PCCR0_GPT4_MASK             (1 << 21)
-#define CCM_PCCR0_GPT5_OFFSET           20
-#define CCM_PCCR0_GPT5_MASK             (1 << 20)
-#define CCM_PCCR0_GPT6_OFFSET           19
-#define CCM_PCCR0_GPT6_MASK             (1 << 19)
-#define CCM_PCCR0_I2C1_OFFSET           18
-#define CCM_PCCR0_I2C1_MASK             (1 << 18)
-#define CCM_PCCR0_I2C2_OFFSET           17
-#define CCM_PCCR0_I2C2_MASK             (1 << 17)
-#define CCM_PCCR0_IIM_OFFSET            16
-#define CCM_PCCR0_IIM_MASK              (1 << 16)
-#define CCM_PCCR0_KPP_OFFSET            15
-#define CCM_PCCR0_KPP_MASK              (1 << 15)
-#define CCM_PCCR0_LCDC_OFFSET           14
-#define CCM_PCCR0_LCDC_MASK             (1 << 14)
-#define CCM_PCCR0_MSHC_OFFSET           13
-#define CCM_PCCR0_MSHC_MASK             (1 << 13)
-#define CCM_PCCR0_OWIRE_OFFSET          12
-#define CCM_PCCR0_OWIRE_MASK            (1 << 12)
-#define CCM_PCCR0_PWM_OFFSET            11
-#define CCM_PCCR0_PWM_MASK              (1 << 11)
-#define CCM_PCCR0_RTC_OFFSET            9
-#define CCM_PCCR0_RTC_MASK              (1 << 9)
-#define CCM_PCCR0_RTIC_OFFSET           8
-#define CCM_PCCR0_RTIC_MASK             (1 << 8)
-#define CCM_PCCR0_SAHARA_OFFSET         7
-#define CCM_PCCR0_SAHARA_MASK           (1 << 7)
-#define CCM_PCCR0_SCC_OFFSET            6
-#define CCM_PCCR0_SCC_MASK              (1 << 6)
-#define CCM_PCCR0_SDHC1_OFFSET          5
-#define CCM_PCCR0_SDHC1_MASK            (1 << 5)
-#define CCM_PCCR0_SDHC2_OFFSET          4
-#define CCM_PCCR0_SDHC2_MASK            (1 << 4)
-#define CCM_PCCR0_SDHC3_OFFSET          3
-#define CCM_PCCR0_SDHC3_MASK            (1 << 3)
-#define CCM_PCCR0_SLCDC_OFFSET          2
-#define CCM_PCCR0_SLCDC_MASK            (1 << 2)
-#define CCM_PCCR0_SSI1_IPG_OFFSET       1
-#define CCM_PCCR0_SSI1_IPG_MASK         (1 << 1)
-#define CCM_PCCR0_SSI2_IPG_OFFSET       0
-#define CCM_PCCR0_SSI2_IPG_MASK         (1 << 0)
+#define CCM_PCCR_HCLK_CSI_OFFSET       	31
+#define CCM_PCCR_HCLK_CSI_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_DMA_OFFSET       	30
+#define CCM_PCCR_HCLK_DMA_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_BROM_OFFSET      	28
+#define CCM_PCCR_HCLK_BROM_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_EMMA_OFFSET      	27
+#define CCM_PCCR_HCLK_EMMA_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_LCDC_OFFSET      	26
+#define CCM_PCCR_HCLK_LCDC_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_SLCDC_OFFSET     	25
+#define CCM_PCCR_HCLK_SLCDC_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_USBOTG_OFFSET    	24
+#define CCM_PCCR_HCLK_USBOTG_REG	CCM_PCCR0
+#define CCM_PCCR_HCLK_BMI_OFFSET    	23
+#define CCM_PCCR_BMI_MASK          	(1 << CCM_PCCR_BMI_MASK)
+#define CCM_PCCR_HCLK_BMI_REG	    	CCM_PCCR0
+#define CCM_PCCR_PERCLK4_OFFSET        	22
+#define CCM_PCCR_PERCLK4_REG	    	CCM_PCCR0
+#define CCM_PCCR_SLCDC_OFFSET          	21
+#define CCM_PCCR_SLCDC_REG		CCM_PCCR0
+#define CCM_PCCR_FIRI_BAUD_OFFSET       20
+#define CCM_PCCR_FIRI_BAUD_MASK         (1 << CCM_PCCR_FIRI_BAUD_MASK)
+#define CCM_PCCR_FIRI_BAUD_REG	        CCM_PCCR0
+#define CCM_PCCR_NFC_OFFSET		19
+#define CCM_PCCR_NFC_REG		CCM_PCCR0
+#define CCM_PCCR_LCDC_OFFSET           	18
+#define CCM_PCCR_LCDC_REG		CCM_PCCR0
+#define CCM_PCCR_SSI1_BAUD_OFFSET      	17
+#define CCM_PCCR_SSI1_BAUD_REG	    	CCM_PCCR0
+#define CCM_PCCR_SSI2_BAUD_OFFSET      	16
+#define CCM_PCCR_SSI2_BAUD_REG	    	CCM_PCCR0
+#define CCM_PCCR_EMMA_OFFSET           	15
+#define CCM_PCCR_EMMA_REG		CCM_PCCR0
+#define CCM_PCCR_USBOTG_OFFSET         	14
+#define CCM_PCCR_USBOTG_REG		CCM_PCCR0
+#define CCM_PCCR_DMA_OFFSET            	13
+#define CCM_PCCR_DMA_REG            	CCM_PCCR0
+#define CCM_PCCR_I2C1_OFFSET           	12
+#define CCM_PCCR_I2C1_REG		CCM_PCCR0
+#define CCM_PCCR_GPIO_OFFSET           	11
+#define CCM_PCCR_GPIO_REG		CCM_PCCR0
+#define CCM_PCCR_SDHC2_OFFSET          	10
+#define CCM_PCCR_SDHC2_REG		CCM_PCCR0
+#define CCM_PCCR_SDHC1_OFFSET          	9
+#define CCM_PCCR_SDHC1_REG		CCM_PCCR0
+#define CCM_PCCR_FIRI_OFFSET		8
+#define CCM_PCCR_FIRI_MASK		(1 << CCM_PCCR_BAUD_MASK)
+#define CCM_PCCR_FIRI_REG		CCM_PCCR0
+#define CCM_PCCR_SSI2_IPG_OFFSET       	7
+#define CCM_PCCR_SSI2_REG		CCM_PCCR0
+#define CCM_PCCR_SSI1_IPG_OFFSET       	6
+#define CCM_PCCR_SSI1_REG		CCM_PCCR0
+#define CCM_PCCR_CSPI2_OFFSET		5
+#define	CCM_PCCR_CSPI2_REG		CCM_PCCR0
+#define CCM_PCCR_CSPI1_OFFSET		4
+#define	CCM_PCCR_CSPI1_REG		CCM_PCCR0
+#define CCM_PCCR_UART4_OFFSET          	3
+#define CCM_PCCR_UART4_REG		CCM_PCCR0
+#define CCM_PCCR_UART3_OFFSET          	2
+#define CCM_PCCR_UART3_REG		CCM_PCCR0
+#define CCM_PCCR_UART2_OFFSET          	1
+#define CCM_PCCR_UART2_REG		CCM_PCCR0
+#define CCM_PCCR_UART1_OFFSET          	0
+#define CCM_PCCR_UART1_REG		CCM_PCCR0
+
+#define CCM_PCCR_OWIRE_OFFSET          	31
+#define CCM_PCCR_OWIRE_REG		CCM_PCCR1
+#define CCM_PCCR_KPP_OFFSET            	30
+#define CCM_PCCR_KPP_REG		CCM_PCCR1
+#define CCM_PCCR_RTC_OFFSET            	29
+#define CCM_PCCR_RTC_REG		CCM_PCCR1
+#define CCM_PCCR_PWM_OFFSET            	28
+#define CCM_PCCR_PWM_REG		CCM_PCCR1
+#define CCM_PCCR_GPT3_OFFSET           	27
+#define CCM_PCCR_GPT3_REG		CCM_PCCR1
+#define CCM_PCCR_GPT2_OFFSET           	26
+#define CCM_PCCR_GPT2_REG		CCM_PCCR1
+#define CCM_PCCR_GPT1_OFFSET           	25
+#define CCM_PCCR_GPT1_REG		CCM_PCCR1
+#define CCM_PCCR_WDT_OFFSET            	24
+#define CCM_PCCR_WDT_REG		CCM_PCCR1
+#define CCM_PCCR_CSPI3_OFFSET		23
+#define	CCM_PCCR_CSPI3_REG		CCM_PCCR1
+
+#define CCM_PCCR_CSPI1_MASK            	(1 << CCM_PCCR_CSPI1_OFFSET)
+#define CCM_PCCR_CSPI2_MASK            	(1 << CCM_PCCR_CSPI2_OFFSET)
+#define CCM_PCCR_CSPI3_MASK            	(1 << CCM_PCCR_CSPI3_OFFSET)
+#define CCM_PCCR_DMA_MASK              	(1 << CCM_PCCR_DMA_OFFSET)
+#define CCM_PCCR_EMMA_MASK             	(1 << CCM_PCCR_EMMA_OFFSET)
+#define CCM_PCCR_GPIO_MASK             	(1 << CCM_PCCR_GPIO_OFFSET)
+#define CCM_PCCR_GPT1_MASK             	(1 << CCM_PCCR_GPT1_OFFSET)
+#define CCM_PCCR_GPT2_MASK             	(1 << CCM_PCCR_GPT2_OFFSET)
+#define CCM_PCCR_GPT3_MASK             	(1 << CCM_PCCR_GPT3_OFFSET)
+#define CCM_PCCR_HCLK_BROM_MASK		(1 << CCM_PCCR_HCLK_BROM_OFFSET)
+#define CCM_PCCR_HCLK_CSI_MASK         	(1 << CCM_PCCR_HCLK_CSI_OFFSET)
+#define CCM_PCCR_HCLK_DMA_MASK         	(1 << CCM_PCCR_HCLK_DMA_OFFSET)
+#define CCM_PCCR_HCLK_EMMA_MASK        	(1 << CCM_PCCR_HCLK_EMMA_OFFSET)
+#define CCM_PCCR_HCLK_LCDC_MASK        	(1 << CCM_PCCR_HCLK_LCDC_OFFSET)
+#define CCM_PCCR_HCLK_SLCDC_MASK       	(1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
+#define CCM_PCCR_HCLK_USBOTG_MASK      	(1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
+#define CCM_PCCR_I2C1_MASK             	(1 << CCM_PCCR_I2C1_OFFSET)
+#define CCM_PCCR_KPP_MASK              	(1 << CCM_PCCR_KPP_OFFSET)
+#define CCM_PCCR_LCDC_MASK             	(1 << CCM_PCCR_LCDC_OFFSET)
+#define CCM_PCCR_NFC_MASK		(1 << CCM_PCCR_NFC_OFFSET)
+#define CCM_PCCR_OWIRE_MASK            	(1 << CCM_PCCR_OWIRE_OFFSET)
+#define CCM_PCCR_PERCLK4_MASK          	(1 << CCM_PCCR_PERCLK4_OFFSET)
+#define CCM_PCCR_PWM_MASK              	(1 << CCM_PCCR_PWM_OFFSET)
+#define CCM_PCCR_RTC_MASK              	(1 << CCM_PCCR_RTC_OFFSET)
+#define CCM_PCCR_SDHC1_MASK            	(1 << CCM_PCCR_SDHC1_OFFSET)
+#define CCM_PCCR_SDHC2_MASK            	(1 << CCM_PCCR_SDHC2_OFFSET)
+#define CCM_PCCR_SLCDC_MASK            	(1 << CCM_PCCR_SLCDC_OFFSET)
+#define CCM_PCCR_SSI1_BAUD_MASK        	(1 << CCM_PCCR_SSI1_BAUD_OFFSET)
+#define CCM_PCCR_SSI1_IPG_MASK         	(1 << CCM_PCCR_SSI1_IPG_OFFSET)
+#define CCM_PCCR_SSI2_BAUD_MASK        	(1 << CCM_PCCR_SSI2_BAUD_OFFSET)
+#define CCM_PCCR_SSI2_IPG_MASK         	(1 << CCM_PCCR_SSI2_IPG_OFFSET)
+#define CCM_PCCR_UART1_MASK            	(1 << CCM_PCCR_UART1_OFFSET)
+#define CCM_PCCR_UART2_MASK            	(1 << CCM_PCCR_UART2_OFFSET)
+#define CCM_PCCR_UART3_MASK            	(1 << CCM_PCCR_UART3_OFFSET)
+#define CCM_PCCR_UART4_MASK            	(1 << CCM_PCCR_UART4_OFFSET)
+#define CCM_PCCR_USBOTG_MASK           	(1 << CCM_PCCR_USBOTG_OFFSET)
+#define CCM_PCCR_WDT_MASK              	(1 << CCM_PCCR_WDT_OFFSET)
 
-#define CCM_PCCR1_UART1_OFFSET          31
-#define CCM_PCCR1_UART1_MASK            (1 << 31)
-#define CCM_PCCR1_UART2_OFFSET          30
-#define CCM_PCCR1_UART2_MASK            (1 << 30)
-#define CCM_PCCR1_UART3_OFFSET          29
-#define CCM_PCCR1_UART3_MASK            (1 << 29)
-#define CCM_PCCR1_UART4_OFFSET          28
-#define CCM_PCCR1_UART4_MASK            (1 << 28)
-#define CCM_PCCR1_UART5_OFFSET          27
-#define CCM_PCCR1_UART5_MASK            (1 << 27)
-#define CCM_PCCR1_UART6_OFFSET          26
-#define CCM_PCCR1_UART6_MASK            (1 << 26)
-#define CCM_PCCR1_USBOTG_OFFSET         25
-#define CCM_PCCR1_USBOTG_MASK           (1 << 25)
-#define CCM_PCCR1_WDT_OFFSET            24
-#define CCM_PCCR1_WDT_MASK              (1 << 24)
-#define CCM_PCCR1_HCLK_ATA_OFFSET       23
-#define CCM_PCCR1_HCLK_ATA_MASK         (1 << 23)
-#define CCM_PCCR1_HCLK_BROM_OFFSET      22
-#define CCM_PCCR1_HCLK_BROM_MASK        (1 << 22)
-#define CCM_PCCR1_HCLK_CSI_OFFSET       21
-#define CCM_PCCR1_HCLK_CSI_MASK         (1 << 21)
-#define CCM_PCCR1_HCLK_DMA_OFFSET       20
-#define CCM_PCCR1_HCLK_DMA_MASK         (1 << 20)
-#define CCM_PCCR1_HCLK_EMI_OFFSET       19
-#define CCM_PCCR1_HCLK_EMI_MASK         (1 << 19)
-#define CCM_PCCR1_HCLK_EMMA_OFFSET      18
-#define CCM_PCCR1_HCLK_EMMA_MASK        (1 << 18)
-#define CCM_PCCR1_HCLK_FEC_OFFSET       17
-#define CCM_PCCR1_HCLK_FEC_MASK         (1 << 17)
-#define CCM_PCCR1_HCLK_VPU_OFFSET       16
-#define CCM_PCCR1_HCLK_VPU_MASK         (1 << 16)
-#define CCM_PCCR1_HCLK_LCDC_OFFSET      15
-#define CCM_PCCR1_HCLK_LCDC_MASK        (1 << 15)
-#define CCM_PCCR1_HCLK_RTIC_OFFSET      14
-#define CCM_PCCR1_HCLK_RTIC_MASK        (1 << 14)
-#define CCM_PCCR1_HCLK_SAHARA_OFFSET    13
-#define CCM_PCCR1_HCLK_SAHARA_MASK      (1 << 13)
-#define CCM_PCCR1_HCLK_SLCDC_OFFSET     12
-#define CCM_PCCR1_HCLK_SLCDC_MASK       (1 << 12)
-#define CCM_PCCR1_HCLK_USBOTG_OFFSET    11
-#define CCM_PCCR1_HCLK_USBOTG_MASK      (1 << 11)
-#define CCM_PCCR1_PERCLK1_OFFSET        10
-#define CCM_PCCR1_PERCLK1_MASK          (1 << 10)
-#define CCM_PCCR1_PERCLK2_OFFSET        9
-#define CCM_PCCR1_PERCLK2_MASK          (1 << 9)
-#define CCM_PCCR1_PERCLK3_OFFSET        8
-#define CCM_PCCR1_PERCLK3_MASK          (1 << 8)
-#define CCM_PCCR1_PERCLK4_OFFSET        7
-#define CCM_PCCR1_PERCLK4_MASK          (1 << 7)
-#define CCM_PCCR1_VPU_BAUD_OFFSET       6
-#define CCM_PCCR1_VPU_BAUD_MASK         (1 << 6)
-#define CCM_PCCR1_SSI1_BAUD_OFFSET      5
-#define CCM_PCCR1_SSI1_BAUD_MASK        (1 << 5)
-#define CCM_PCCR1_SSI2_BAUD_OFFSET      4
-#define CCM_PCCR1_SSI2_BAUD_MASK        (1 << 4)
-#define CCM_PCCR1_NFC_BAUD_OFFSET       3
-#define CCM_PCCR1_NFC_BAUD_MASK         (1 << 3)
-#define CCM_PCCR1_MSHC_BAUD_OFFSET      2
-#define CCM_PCCR1_MSHC_BAUD_MASK        (1 << 2)
 
 #define CCM_CCSR_32KSR          (1 << 15)
+
 #define CCM_CCSR_CLKMODE1       (1 << 9)
 #define CCM_CCSR_CLKMODE0       (1 << 8)
+
 #define CCM_CCSR_CLKOSEL_OFFSET 0
 #define CCM_CCSR_CLKOSEL_MASK   0x1f
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,10 @@
 
 #include <mach/irqs.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
 
 /*
  * Resource definition for the MXC IrDA
@@ -225,37 +229,215 @@ struct platform_device mxc_nand_device =
 	.resource = mxc_nand_resources,
 };
 
+/*
+ * lcdc:
+ * - i.MX1: the basic controller
+ * - i.MX21: to be checked
+ * - i.MX27: like i.MX1, with slightly variations
+ */
+static struct resource mxc_fb[] = {
+	{
+		.start = LCDC_BASE_ADDR,
+		.end   = LCDC_BASE_ADDR + 0xFFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_LCDC,
+		.end   = MXC_INT_LCDC,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+/* mxc lcd driver */
+struct platform_device mxc_fb_device = {
+	.name = "imx-fb",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fb),
+	.resource = mxc_fb,
+	.dev = {
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+};
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= FEC_BASE_ADDR,
+		.end	= FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MXC_INT_FEC,
+		.end	= MXC_INT_FEC,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mxc_fec_device = {
+	.name = "fec",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fec_resources),
+	.resource = mxc_fec_resources,
+};
+#endif
+
+static struct resource mxc_i2c_1_resources[] = {
+	[0] = {
+		.start	= I2C_BASE_ADDR,
+		.end	= I2C_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start	= MXC_INT_I2C,
+		.end	= MXC_INT_I2C,
+		.flags	= IORESOURCE_IRQ
+	}
+};
+
+struct platform_device mxc_i2c_device0 = {
+	.name = "imx-i2c",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+	.resource = mxc_i2c_1_resources
+};
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_i2c_2_resources[] = {
+	[0] = {
+		.start	= I2C2_BASE_ADDR,
+		.end	= I2C2_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start	= MXC_INT_I2C2,
+		.end	= MXC_INT_I2C2,
+		.flags	= IORESOURCE_IRQ
+	}
+};
+
+struct platform_device mxc_i2c_device1 = {
+	.name = "imx-i2c",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+	.resource = mxc_i2c_2_resources
+};
+#endif
+
+static struct resource mxc_pwm_resources[] = {
+	[0] = {
+		.start	= PWM_BASE_ADDR,
+		.end	= PWM_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start   = MXC_INT_PWM,
+		.end     = MXC_INT_PWM,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device = {
+	.name = "mxc_pwm",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources),
+	.resource = mxc_pwm_resources
+};
+
+/*
+ * Resource definition for the MXC SDHC
+ */
+static struct resource mxc_sdhc1_resources[] = {
+	[0] = {
+			.start = SDHC1_BASE_ADDR,
+			.end   = SDHC1_BASE_ADDR + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+			},
+	[1] = {
+			.start = MXC_INT_SDHC1,
+			.end   = MXC_INT_SDHC1,
+			.flags = IORESOURCE_IRQ,
+			},
+	[2] = {
+			.start  = DMA_REQ_SDHC1,
+			.end    = DMA_REQ_SDHC1,
+			.flags  = IORESOURCE_DMA
+		},
+};
+
+static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device0 = {
+       .name           = "mxc-mmc",
+       .id             = 0,
+       .dev            = {
+               .dma_mask = &mxc_sdhc1_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mxc_sdhc1_resources),
+       .resource       = mxc_sdhc1_resources,
+};
+
+static struct resource mxc_sdhc2_resources[] = {
+	[0] = {
+			.start = SDHC2_BASE_ADDR,
+			.end   = SDHC2_BASE_ADDR + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+			},
+	[1] = {
+			.start = MXC_INT_SDHC2,
+			.end   = MXC_INT_SDHC2,
+			.flags = IORESOURCE_IRQ,
+			},
+	[2] = {
+			.start  = DMA_REQ_SDHC2,
+			.end    = DMA_REQ_SDHC2,
+			.flags  = IORESOURCE_DMA
+		},
+};
+
+static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device1 = {
+       .name           = "mxc-mmc",
+       .id             = 1,
+       .dev            = {
+               .dma_mask = &mxc_sdhc2_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mxc_sdhc2_resources),
+       .resource       = mxc_sdhc2_resources,
+};
+
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
 	[0] = {
 		.chip.label = "gpio-0",
 		.irq = MXC_INT_GPIO,
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR),
 		.virtual_irq_start = MXC_GPIO_IRQ_START,
 	},
 	[1] = {
 		.chip.label = "gpio-1",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
 	},
 	[2] = {
 		.chip.label = "gpio-2",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
 	},
 	[3] = {
 		.chip.label = "gpio-3",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
 	},
 	[4] = {
 		.chip.label = "gpio-4",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
 	},
 	[5] = {
 		.chip.label = "gpio-5",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
 	}
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/devices.h linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/devices.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/devices.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/devices.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,3 @@
-
 extern struct platform_device mxc_gpt1;
 extern struct platform_device mxc_gpt2;
 extern struct platform_device mxc_gpt3;
@@ -14,3 +13,10 @@ extern struct platform_device mxc_uart_d
 extern struct platform_device mxc_uart_device5;
 extern struct platform_device mxc_w1_master_device;
 extern struct platform_device mxc_nand_device;
+extern struct platform_device mxc_fb_device;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxc_pwm_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_sdhc_device0;
+extern struct platform_device mxc_sdhc_device1;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/generic.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/generic.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,22 @@
-comment "MX2 family CPU support"
-	depends on ARCH_MX2
+if ARCH_MX2
+
+choice
+	prompt "CPUs:"
+	default MACH_MX21
+
+config MACH_MX21
+	bool "i.MX21 support"
+	help
+	  This enables support for Freescale's MX2 based i.MX21 processor.
 
 config MACH_MX27
 	bool "i.MX27 support"
-	depends on ARCH_MX2
 	help
 	  This enables support for Freescale's MX2 based i.MX27 processor.
 
-comment "MX2 Platforms"
-	depends on ARCH_MX2
+endchoice
+
+comment "MX2 platforms:"
 
 config MACH_MX27ADS
 	bool "MX27ADS platform"
@@ -37,3 +45,5 @@ config MACH_PCM970_BASEBOARD
 	  PCM970 evaluation board.
 
 endchoice
+
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,9 @@
 
 # Object file lists.
 
-obj-y	:=  system.o generic.o devices.o serial.o
+obj-y	:=  generic.o devices.o serial.o
+
+obj-$(CONFIG_MACH_MX21) += clock_imx21.o
 
 obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
 obj-$(CONFIG_MACH_MX27) += clock_imx27.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Makefile.boot linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Makefile.boot
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/Makefile.boot	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/Makefile.boot	2009-06-09 23:05:27.000000000 -0400
@@ -1,3 +1,7 @@
-   zreladdr-y	:= 0xA0008000
-params_phys-y	:= 0xA0000100
-initrd_phys-y	:= 0xA0800000
+zreladdr-$(CONFIG_MACH_MX21)	:= 0xC0008000
+params_phys-$(CONFIG_MACH_MX21)	:= 0xC0000100
+initrd_phys-$(CONFIG_MACH_MX21)	:= 0xC0800000
+
+zreladdr-$(CONFIG_MACH_MX27)	:= 0xA0008000
+params_phys-$(CONFIG_MACH_MX27)	:= 0xA0000100
+initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/mx27ads.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/mx27ads.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/mx27ads.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/mx27ads.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@
 #include <asm/mach/map.h>
 #include <mach/gpio.h>
 #include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
 #include <mach/board-mx27ads.h>
 
 #include "devices.h"
@@ -135,6 +135,7 @@ static int uart_mxc_port3_exit(struct pl
 {
 	mxc_gpio_release_multiple_pins(mxc_uart3_pins,
 			ARRAY_SIZE(mxc_uart3_pins));
+	return 0;
 }
 
 static int mxc_uart4_pins[] = {
@@ -179,6 +180,7 @@ static int uart_mxc_port5_exit(struct pl
 
 static struct platform_device *platform_devices[] __initdata = {
 	&mx27ads_nor_mtd_device,
+	&mxc_fec_device,
 };
 
 static int mxc_fec_pins[] = {
@@ -196,7 +198,7 @@ static int mxc_fec_pins[] = {
 	PD11_AOUT_FEC_TX_CLK,
 	PD12_AOUT_FEC_RXD0,
 	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_CLR,
+	PD14_AOUT_FEC_RX_CLK,
 	PD15_AOUT_FEC_COL,
 	PD16_AIN_FEC_TX_ER,
 	PF23_AIN_FEC_TX_EN
@@ -208,12 +210,6 @@ static void gpio_fec_active(void)
 			ARRAY_SIZE(mxc_fec_pins), "FEC");
 }
 
-static void gpio_fec_inactive(void)
-{
-	mxc_gpio_release_multiple_pins(mxc_fec_pins,
-			ARRAY_SIZE(mxc_fec_pins));
-}
-
 static struct imxuart_platform_data uart_pdata[] = {
 	{
 		.init = uart_mxc_port0_init,
@@ -263,11 +259,10 @@ static void __init mx27ads_timer_init(vo
 	if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
 		fref = 27000000;
 
-	mxc_clocks_init(fref);
-	mxc_timer_init("gpt_clk.0");
+	mx27_clocks_init(fref);
 }
 
-struct sys_timer mx27ads_timer = {
+static struct sys_timer mx27ads_timer = {
 	.init	= mx27ads_timer_init,
 };
 
@@ -280,7 +275,7 @@ static struct map_desc mx27ads_io_desc[]
 	},
 };
 
-void __init mx27ads_map_io(void)
+static void __init mx27ads_map_io(void)
 {
 	mxc_map_io();
 	iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/pcm038.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/pcm038.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/pcm038.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/pcm038.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,11 +20,18 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/plat-ram.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
 #include <asm/mach/time.h>
 #include <mach/imx-uart.h>
 #include <mach/board-pcm038.h>
@@ -121,10 +128,10 @@ static int uart_mxc_port1_exit(struct pl
 	return 0;
 }
 
-static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS,
+static int mxc_uart2_pins[] = { PE8_PF_UART3_TXD,
 				PE9_PF_UART3_RXD,
 				PE10_PF_UART3_CTS,
-				PE9_PF_UART3_RXD };
+				PE11_PF_UART3_RTS };
 
 static int uart_mxc_port2_init(struct platform_device *pdev)
 {
@@ -170,7 +177,7 @@ static int mxc_fec_pins[] = {
 	PD11_AOUT_FEC_TX_CLK,
 	PD12_AOUT_FEC_RXD0,
 	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_CLR,
+	PD14_AOUT_FEC_RX_CLK,
 	PD15_AOUT_FEC_COL,
 	PD16_AIN_FEC_TX_ER,
 	PF23_AIN_FEC_TX_EN
@@ -182,12 +189,6 @@ static void gpio_fec_active(void)
 			ARRAY_SIZE(mxc_fec_pins), "FEC");
 }
 
-static void gpio_fec_inactive(void)
-{
-	mxc_gpio_release_multiple_pins(mxc_fec_pins,
-			ARRAY_SIZE(mxc_fec_pins));
-}
-
 static struct mxc_nand_platform_data pcm038_nand_board_info = {
 	.width = 1,
 	.hw_ecc = 1,
@@ -196,6 +197,7 @@ static struct mxc_nand_platform_data pcm
 static struct platform_device *platform_devices[] __initdata = {
 	&pcm038_nor_mtd_device,
 	&mxc_w1_master_device,
+	&mxc_fec_device,
 	&pcm038_sram_mtd_device,
 };
 
@@ -208,6 +210,51 @@ static void __init pcm038_init_sram(void
 	__raw_writel(0x22220a00, CSCR_A(1));
 }
 
+#ifdef CONFIG_I2C_IMX
+static int mxc_i2c1_pins[] = {
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL
+};
+
+static int pcm038_i2c_1_init(struct device *dev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins),
+			"I2C1");
+}
+
+static void pcm038_i2c_1_exit(struct device *dev)
+{
+	mxc_gpio_release_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins));
+}
+
+static struct imxi2c_platform_data pcm038_i2c_1_data = {
+	.bitrate = 100000,
+	.init = pcm038_i2c_1_init,
+	.exit = pcm038_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm038_i2c_devices[] = {
+	[0] = {
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	},
+	[1] = {
+		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+		.type = "pcf8563"
+	},
+	[2] = {
+		I2C_BOARD_INFO("lm75", 0x4a),
+		.type = "lm75"
+	}
+};
+#endif
+
 static void __init pcm038_init(void)
 {
 	gpio_fec_active();
@@ -217,9 +264,17 @@ static void __init pcm038_init(void)
 	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
 	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
 
-	mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */
+	mxc_gpio_mode(PE16_AF_OWIRE);
 	mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
 
+#ifdef CONFIG_I2C_IMX
+	/* only the i2c master 1 is used on this CPU card */
+	i2c_register_board_info(1, pcm038_i2c_devices,
+				ARRAY_SIZE(pcm038_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
+#endif
+
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
 #ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -229,11 +284,10 @@ static void __init pcm038_init(void)
 
 static void __init pcm038_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("gpt_clk.0");
+	mx27_clocks_init(26000000);
 }
 
-struct sys_timer pcm038_timer = {
+static struct sys_timer pcm038_timer = {
 	.init = pcm038_timer_init,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/pcm970-baseboard.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,9 +17,138 @@
  */
 
 #include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
 #include <asm/mach/arch.h>
 
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/imxfb.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+static int pcm970_sdhc2_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_PORTC + 28);
+}
+
+static int pcm970_sdhc2_pins[] = {
+	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 int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
+{
+	int ret;
+
+	ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
+		ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
+	if(ret)
+		return ret;
+
+	ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
+				"imx-mmc-detect", data);
+	if (ret)
+		goto out_release_gpio;
+
+	set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
+
+	ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
+	if (ret)
+		goto out_release_gpio;
+
+	mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
+	gpio_direction_input(GPIO_PORTC + 28);
+
+	return 0;
+
+out_release_gpio:
+	mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+			ARRAY_SIZE(pcm970_sdhc2_pins));
+	return ret;
+}
+
+static void pcm970_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOC(29), data);
+	gpio_free(GPIO_PORTC + 28);
+	mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+			ARRAY_SIZE(pcm970_sdhc2_pins));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+	.get_ro = pcm970_sdhc2_get_ro,
+	.init = pcm970_sdhc2_init,
+	.exit = pcm970_sdhc2_exit,
+};
+
+static int mxc_fb_pins[] = {
+	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,	PA24_PF_REV,
+	PA25_PF_CLS,	PA26_PF_PS,	PA27_PF_SPL_SPR, PA28_PF_HSYNC,
+	PA29_PF_VSYNC,	PA30_PF_CONTRAST, PA31_PF_OE_ACD
+};
+
+static int pcm038_fb_init(struct platform_device *pdev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
+			ARRAY_SIZE(mxc_fb_pins), "FB");
+}
+
+static int pcm038_fb_exit(struct platform_device *pdev)
+{
+	mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
+
+	return 0;
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DH06
+ */
+static struct imx_fb_platform_data pcm038_fb_data = {
+	.pixclock	= 188679, /* in ps (5.3MHz) */
+	.xres		= 240,
+	.yres		= 320,
+
+	.bpp		= 16,
+	.hsync_len	= 7,
+	.left_margin	= 5,
+	.right_margin	= 16,
+
+	.vsync_len	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 9,
+	.fixed_screen_cpu = 0,
+
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock not inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pcr		= 0xFA0080C0,
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+
+	.init = pcm038_fb_init,
+	.exit = pcm038_fb_exit,
+};
+
 /*
  * system init for baseboard usage. Will be called by pcm038 init.
  *
@@ -28,4 +157,6 @@
  */
 void __init pcm970_baseboard_init(void)
 {
+	mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/serial.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/serial.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/serial.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
+#include "devices.h"
 
 static struct resource uart0[] = {
 	{
@@ -99,6 +100,7 @@ struct platform_device mxc_uart_device3
 	.num_resources = ARRAY_SIZE(uart3),
 };
 
+#ifdef CONFIG_MACH_MX27
 static struct resource uart4[] = {
 	{
 		.start = UART5_BASE_ADDR,
@@ -136,3 +138,4 @@ struct platform_device mxc_uart_device5
 	.resource = uart5,
 	.num_resources = ARRAY_SIZE(uart5),
 };
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/system.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/system.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx2/system.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx2/system.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, 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 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/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/proc-fns.h>
-#include <asm/system.h>
-
-/*
- * Put the CPU into idle mode. It is called by default_idle()
- * in process.c file.
- */
-void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks.
-	 */
-	cpu_do_idle();
-}
-
-#define WDOG_WCR_REG                    IO_ADDRESS(WDOG_BASE_ADDR)
-#define WDOG_WCR_SRS                    (1 << 4)
-
-/*
- * Reset the system. It is called by machine_restart().
- */
-void arch_reset(char mode)
-{
-	struct clk *clk;
-
-	clk = clk_get(NULL, "wdog_clk");
-	if (!clk) {
-		printk(KERN_ERR"Cannot activate the watchdog. Giving up\n");
-		return;
-	}
-
-	clk_enable(clk);
-
-	/* Assert SRS signal */
-	__raw_writew(__raw_readw(WDOG_WCR_REG) & ~WDOG_WCR_SRS, WDOG_WCR_REG);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,9 +23,13 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
 #include <mach/clock.h>
 #include <mach/hardware.h>
-#include <asm/div64.h>
+#include <mach/common.h>
 
 #include "crm_regs.h"
 
@@ -64,17 +68,17 @@ static void __calc_pre_post_dividers(u32
 }
 
 static struct clk mcu_pll_clk;
-static struct clk mcu_main_clk;
-static struct clk usb_pll_clk;
 static struct clk serial_pll_clk;
 static struct clk ipg_clk;
 static struct clk ckih_clk;
-static struct clk ahb_clk;
 
-static int _clk_enable(struct clk *clk)
+static int cgr_enable(struct clk *clk)
 {
 	u32 reg;
 
+	if (!clk->enable_reg)
+		return 0;
+
 	reg = __raw_readl(clk->enable_reg);
 	reg |= 3 << clk->enable_shift;
 	__raw_writel(reg, clk->enable_reg);
@@ -82,133 +86,69 @@ static int _clk_enable(struct clk *clk)
 	return 0;
 }
 
-static void _clk_disable(struct clk *clk)
+static void cgr_disable(struct clk *clk)
 {
 	u32 reg;
 
+	if (!clk->enable_reg)
+		return;
+
 	reg = __raw_readl(clk->enable_reg);
 	reg &= ~(3 << clk->enable_shift);
-	__raw_writel(reg, clk->enable_reg);
-}
 
-static void _clk_emi_disable(struct clk *clk)
-{
-	u32 reg;
+	/* special case for EMI clock */
+	if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
+		reg |= (1 << clk->enable_shift);
 
-	reg = __raw_readl(clk->enable_reg);
-	reg &= ~(3 << clk->enable_shift);
-	reg |= (1 << clk->enable_shift);
 	__raw_writel(reg, clk->enable_reg);
 }
 
-static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long pll_ref_get_rate(void)
 {
-	u32 reg;
-	signed long pd = 1;	/* Pre-divider */
-	signed long mfi;	/* Multiplication Factor (Integer part) */
-	signed long mfn;	/* Multiplication Factor (Integer part) */
-	signed long mfd;	/* Multiplication Factor (Denominator Part) */
-	signed long tmp;
-	u32 ref_freq = clk_get_rate(clk->parent);
-
-	while (((ref_freq / pd) * 10) > rate)
-		pd++;
-
-	if ((ref_freq / pd) < PRE_DIV_MIN_FREQ)
-		return -EINVAL;
+	unsigned long ccmr;
+	unsigned int prcs;
 
-	/* the ref_freq/2 in the following is to round up */
-	mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq;
-	if (mfi < 5 || mfi > 15)
-		return -EINVAL;
+	ccmr = __raw_readl(MXC_CCM_CCMR);
+	prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
+	if (prcs == 0x1)
+		return CKIL_CLK_FREQ * 1024;
+	else
+		return clk_get_rate(&ckih_clk);
+}
 
-	/* pick a mfd value that will work
-	 * then solve for mfn */
-	mfd = ref_freq / 50000;
+static unsigned long usb_pll_get_rate(struct clk *clk)
+{
+	unsigned long reg;
 
-	/*
-	 *          pll_freq * pd * mfd
-	 *   mfn = --------------------  -  (mfi * mfd)
-	 *           2 * ref_freq
-	 */
-	/* the tmp/2 is for rounding */
-	tmp = ref_freq / 10000;
-	mfn =
-	    ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) -
-	    (mfi * mfd);
+	reg = __raw_readl(MXC_CCM_UPCTL);
 
-	mfn = mfn & 0x3ff;
-	pd--;
-	mfd--;
+	return mxc_decode_pll(reg, pll_ref_get_rate());
+}
 
-	/* Change the Pll value */
-	reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) |
-	    (mfn << MXC_CCM_PCTL_MFN_OFFSET) |
-	    (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET);
+static unsigned long serial_pll_get_rate(struct clk *clk)
+{
+	unsigned long reg;
 
-	if (clk == &mcu_pll_clk)
-		__raw_writel(reg, MXC_CCM_MPCTL);
-	else if (clk == &usb_pll_clk)
-		__raw_writel(reg, MXC_CCM_UPCTL);
-	else if (clk == &serial_pll_clk)
-		__raw_writel(reg, MXC_CCM_SRPCTL);
+	reg = __raw_readl(MXC_CCM_SRPCTL);
 
-	return 0;
+	return mxc_decode_pll(reg, pll_ref_get_rate());
 }
 
-static unsigned long _clk_pll_get_rate(struct clk *clk)
+static unsigned long mcu_pll_get_rate(struct clk *clk)
 {
-	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
 	unsigned long reg, ccmr;
-	s64 temp;
-	unsigned int prcs;
 
 	ccmr = __raw_readl(MXC_CCM_CCMR);
-	prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
-	if (prcs == 0x1)
-		ref_clk = CKIL_CLK_FREQ * 1024;
-	else
-		ref_clk = clk_get_rate(&ckih_clk);
 
-	if (clk == &mcu_pll_clk) {
-		if ((ccmr & MXC_CCM_CCMR_MPE) == 0)
-			return ref_clk;
-		if ((ccmr & MXC_CCM_CCMR_MDS) != 0)
-			return ref_clk;
-		reg = __raw_readl(MXC_CCM_MPCTL);
-	} else if (clk == &usb_pll_clk)
-		reg = __raw_readl(MXC_CCM_UPCTL);
-	else if (clk == &serial_pll_clk)
-		reg = __raw_readl(MXC_CCM_SRPCTL);
-	else {
-		BUG();
-		return 0;
-	}
-
-	pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET;
-	mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET;
-	mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET;
-	mfi = (mfi <= 5) ? 5 : mfi;
-	mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK;
-
-	if (mfn >= 0x200) {
-		mfn |= 0xFFFFFE00;
-		mfn_abs = -mfn;
-	}
-
-	ref_clk *= 2;
-	ref_clk /= pdf + 1;
+	if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
+		return clk_get_rate(&ckih_clk);
 
-	temp = (u64) ref_clk * mfn_abs;
-	do_div(temp, mfd + 1);
-	if (mfn < 0)
-		temp = -temp;
-	temp = (ref_clk * mfi) + temp;
+	reg = __raw_readl(MXC_CCM_MPCTL);
 
-	return temp;
+	return mxc_decode_pll(reg, pll_ref_get_rate());
 }
 
-static int _clk_usb_pll_enable(struct clk *clk)
+static int usb_pll_enable(struct clk *clk)
 {
 	u32 reg;
 
@@ -222,7 +162,7 @@ static int _clk_usb_pll_enable(struct cl
 	return 0;
 }
 
-static void _clk_usb_pll_disable(struct clk *clk)
+static void usb_pll_disable(struct clk *clk)
 {
 	u32 reg;
 
@@ -231,7 +171,7 @@ static void _clk_usb_pll_disable(struct
 	__raw_writel(reg, MXC_CCM_CCMR);
 }
 
-static int _clk_serial_pll_enable(struct clk *clk)
+static int serial_pll_enable(struct clk *clk)
 {
 	u32 reg;
 
@@ -245,7 +185,7 @@ static int _clk_serial_pll_enable(struct
 	return 0;
 }
 
-static void _clk_serial_pll_disable(struct clk *clk)
+static void serial_pll_disable(struct clk *clk)
 {
 	u32 reg;
 
@@ -258,7 +198,7 @@ static void _clk_serial_pll_disable(stru
 #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
 #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
 
-static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
+static unsigned long mcu_main_get_rate(struct clk *clk)
 {
 	u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
 
@@ -268,7 +208,7 @@ static unsigned long _clk_mcu_main_get_r
 		return clk_get_rate(&mcu_pll_clk);
 }
 
-static unsigned long _clk_hclk_get_rate(struct clk *clk)
+static unsigned long ahb_get_rate(struct clk *clk)
 {
 	unsigned long max_pdf;
 
@@ -277,7 +217,7 @@ static unsigned long _clk_hclk_get_rate(
 	return clk_get_rate(clk->parent) / (max_pdf + 1);
 }
 
-static unsigned long _clk_ipg_get_rate(struct clk *clk)
+static unsigned long ipg_get_rate(struct clk *clk)
 {
 	unsigned long ipg_pdf;
 
@@ -286,7 +226,7 @@ static unsigned long _clk_ipg_get_rate(s
 	return clk_get_rate(clk->parent) / (ipg_pdf + 1);
 }
 
-static unsigned long _clk_nfc_get_rate(struct clk *clk)
+static unsigned long nfc_get_rate(struct clk *clk)
 {
 	unsigned long nfc_pdf;
 
@@ -295,7 +235,7 @@ static unsigned long _clk_nfc_get_rate(s
 	return clk_get_rate(clk->parent) / (nfc_pdf + 1);
 }
 
-static unsigned long _clk_hsp_get_rate(struct clk *clk)
+static unsigned long hsp_get_rate(struct clk *clk)
 {
 	unsigned long hsp_pdf;
 
@@ -304,7 +244,7 @@ static unsigned long _clk_hsp_get_rate(s
 	return clk_get_rate(clk->parent) / (hsp_pdf + 1);
 }
 
-static unsigned long _clk_usb_get_rate(struct clk *clk)
+static unsigned long usb_get_rate(struct clk *clk)
 {
 	unsigned long usb_pdf, usb_prepdf;
 
@@ -315,7 +255,7 @@ static unsigned long _clk_usb_get_rate(s
 	return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
 }
 
-static unsigned long _clk_csi_get_rate(struct clk *clk)
+static unsigned long csi_get_rate(struct clk *clk)
 {
 	u32 reg, pre, post;
 
@@ -329,7 +269,7 @@ static unsigned long _clk_csi_get_rate(s
 	return clk_get_rate(clk->parent) / (pre * post);
 }
 
-static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
 {
 	u32 pre, post, parent = clk_get_rate(clk->parent);
 	u32 div = parent / rate;
@@ -342,7 +282,7 @@ static unsigned long _clk_csi_round_rate
 	return parent / (pre * post);
 }
 
-static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
+static int csi_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
 
@@ -363,16 +303,7 @@ static int _clk_csi_set_rate(struct clk
 	return 0;
 }
 
-static unsigned long _clk_per_get_rate(struct clk *clk)
-{
-	unsigned long per_pdf;
-
-	per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
-		       MXC_CCM_PDR0_PER_PODF_OFFSET);
-	return clk_get_rate(clk->parent) / (per_pdf + 1);
-}
-
-static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+static unsigned long ssi1_get_rate(struct clk *clk)
 {
 	unsigned long ssi1_pdf, ssi1_prepdf;
 
@@ -383,7 +314,7 @@ static unsigned long _clk_ssi1_get_rate(
 	return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
 }
 
-static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+static unsigned long ssi2_get_rate(struct clk *clk)
 {
 	unsigned long ssi2_pdf, ssi2_prepdf;
 
@@ -394,7 +325,7 @@ static unsigned long _clk_ssi2_get_rate(
 	return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
 }
 
-static unsigned long _clk_firi_get_rate(struct clk *clk)
+static unsigned long firi_get_rate(struct clk *clk)
 {
 	unsigned long firi_pdf, firi_prepdf;
 
@@ -405,7 +336,7 @@ static unsigned long _clk_firi_get_rate(
 	return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
 }
 
-static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
 {
 	u32 pre, post;
 	u32 parent = clk_get_rate(clk->parent);
@@ -420,7 +351,7 @@ static unsigned long _clk_firi_round_rat
 
 }
 
-static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
+static int firi_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
 
@@ -441,12 +372,12 @@ static int _clk_firi_set_rate(struct clk
 	return 0;
 }
 
-static unsigned long _clk_mbx_get_rate(struct clk *clk)
+static unsigned long mbx_get_rate(struct clk *clk)
 {
 	return clk_get_rate(clk->parent) / 2;
 }
 
-static unsigned long _clk_mstick1_get_rate(struct clk *clk)
+static unsigned long mstick1_get_rate(struct clk *clk)
 {
 	unsigned long msti_pdf;
 
@@ -455,7 +386,7 @@ static unsigned long _clk_mstick1_get_ra
 	return clk_get_rate(clk->parent) / (msti_pdf + 1);
 }
 
-static unsigned long _clk_mstick2_get_rate(struct clk *clk)
+static unsigned long mstick2_get_rate(struct clk *clk)
 {
 	unsigned long msti_pdf;
 
@@ -472,661 +403,185 @@ static unsigned long clk_ckih_get_rate(s
 }
 
 static struct clk ckih_clk = {
-	.name = "ckih",
 	.get_rate = clk_ckih_get_rate,
 };
 
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
-	return CKIL_CLK_FREQ;
-}
-
-static struct clk ckil_clk = {
-	.name = "ckil",
-	.get_rate = clk_ckil_get_rate,
-};
-
 static struct clk mcu_pll_clk = {
-	.name = "mcu_pll",
 	.parent = &ckih_clk,
-	.set_rate = _clk_pll_set_rate,
-	.get_rate = _clk_pll_get_rate,
+	.get_rate = mcu_pll_get_rate,
 };
 
 static struct clk mcu_main_clk = {
-	.name = "mcu_main_clk",
 	.parent = &mcu_pll_clk,
-	.get_rate = _clk_mcu_main_get_rate,
+	.get_rate = mcu_main_get_rate,
 };
 
 static struct clk serial_pll_clk = {
-	.name = "serial_pll",
 	.parent = &ckih_clk,
-	.set_rate = _clk_pll_set_rate,
-	.get_rate = _clk_pll_get_rate,
-	.enable = _clk_serial_pll_enable,
-	.disable = _clk_serial_pll_disable,
+	.get_rate = serial_pll_get_rate,
+	.enable = serial_pll_enable,
+	.disable = serial_pll_disable,
 };
 
 static struct clk usb_pll_clk = {
-	.name = "usb_pll",
 	.parent = &ckih_clk,
-	.set_rate = _clk_pll_set_rate,
-	.get_rate = _clk_pll_get_rate,
-	.enable = _clk_usb_pll_enable,
-	.disable = _clk_usb_pll_disable,
+	.get_rate = usb_pll_get_rate,
+	.enable = usb_pll_enable,
+	.disable = usb_pll_disable,
 };
 
 static struct clk ahb_clk = {
-	.name = "ahb_clk",
-	.parent = &mcu_main_clk,
-	.get_rate = _clk_hclk_get_rate,
-};
-
-static struct clk per_clk = {
-	.name = "per_clk",
-	.parent = &usb_pll_clk,
-	.get_rate = _clk_per_get_rate,
-};
-
-static struct clk perclk_clk = {
-	.name = "perclk_clk",
-	.parent = &ipg_clk,
-};
-
-static struct clk cspi_clk[] = {
-	{
-	 .name = "cspi_clk",
-	 .id = 0,
-	 .parent = &ipg_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR2,
-	 .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "cspi_clk",
-	 .id = 1,
-	 .parent = &ipg_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR2,
-	 .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "cspi_clk",
-	 .id = 2,
-	 .parent = &ipg_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk ipg_clk = {
-	.name = "ipg_clk",
-	.parent = &ahb_clk,
-	.get_rate = _clk_ipg_get_rate,
-};
-
-static struct clk emi_clk = {
-	.name = "emi_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR2,
-	.enable_shift = MXC_CCM_CGR2_EMI_OFFSET,
-	.disable = _clk_emi_disable,
-};
-
-static struct clk gpt_clk = {
-	.name = "gpt_clk",
-	.parent = &perclk_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR0,
-	.enable_shift = MXC_CCM_CGR0_GPT_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk pwm_clk = {
-	.name = "pwm_clk",
-	.parent = &perclk_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR0,
-	.enable_shift = MXC_CCM_CGR1_PWM_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk epit_clk[] = {
-	{
-	 .name = "epit_clk",
-	 .id = 0,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "epit_clk",
-	 .id = 1,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk nfc_clk = {
-	.name = "nfc_clk",
-	.parent = &ahb_clk,
-	.get_rate = _clk_nfc_get_rate,
-};
-
-static struct clk scc_clk = {
-	.name = "scc_clk",
-	.parent = &ipg_clk,
-};
-
-static struct clk ipu_clk = {
-	.name = "ipu_clk",
 	.parent = &mcu_main_clk,
-	.get_rate = _clk_hsp_get_rate,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk kpp_clk = {
-	.name = "kpp_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_KPP_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk wdog_clk = {
-	.name = "wdog_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_WDOG_OFFSET,
-	.disable = _clk_disable,
-};
-static struct clk rtc_clk = {
-	.name = "rtc_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_RTC_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk usb_clk[] = {
-	{
-	 .name = "usb_clk",
-	 .parent = &usb_pll_clk,
-	 .get_rate = _clk_usb_get_rate,},
-	{
-	 .name = "usb_ahb_clk",
-	 .parent = &ahb_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk csi_clk = {
-	.name = "csi_clk",
-	.parent = &serial_pll_clk,
-	.get_rate = _clk_csi_get_rate,
-	.round_rate = _clk_csi_round_rate,
-	.set_rate = _clk_csi_set_rate,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_CSI_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk uart_clk[] = {
-	{
-	 .name = "uart_clk",
-	 .id = 0,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_UART1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "uart_clk",
-	 .id = 1,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_UART2_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "uart_clk",
-	 .id = 2,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_UART3_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "uart_clk",
-	 .id = 3,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_UART4_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "uart_clk",
-	 .id = 4,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_UART5_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk i2c_clk[] = {
-	{
-	 .name = "i2c_clk",
-	 .id = 0,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "i2c_clk",
-	 .id = 1,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "i2c_clk",
-	 .id = 2,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk owire_clk = {
-	.name = "owire_clk",
-	.parent = &perclk_clk,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET,
-	.enable = _clk_enable,
-	.disable = _clk_disable,
-};
-
-static struct clk sdhc_clk[] = {
-	{
-	 .name = "sdhc_clk",
-	 .id = 0,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "sdhc_clk",
-	 .id = 1,
-	 .parent = &perclk_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk ssi_clk[] = {
-	{
-	 .name = "ssi_clk",
-	 .parent = &serial_pll_clk,
-	 .get_rate = _clk_ssi1_get_rate,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "ssi_clk",
-	 .id = 1,
-	 .parent = &serial_pll_clk,
-	 .get_rate = _clk_ssi2_get_rate,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR2,
-	 .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
-	 .disable = _clk_disable,},
-};
-
-static struct clk firi_clk = {
-	.name = "firi_clk",
-	.parent = &usb_pll_clk,
-	.round_rate = _clk_firi_round_rate,
-	.set_rate = _clk_firi_set_rate,
-	.get_rate = _clk_firi_get_rate,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR2,
-	.enable_shift = MXC_CCM_CGR2_FIRI_OFFSET,
-	.disable = _clk_disable,
-};
-
-static struct clk ata_clk = {
-	.name = "ata_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR0,
-	.enable_shift = MXC_CCM_CGR0_ATA_OFFSET,
-	.disable = _clk_disable,
+	.get_rate = ahb_get_rate,
 };
 
-static struct clk mbx_clk = {
-	.name = "mbx_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR2,
-	.enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
-	.get_rate = _clk_mbx_get_rate,
-};
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.enable		= cgr_enable,		\
+		.disable	= cgr_disable,		\
+		.secondary	= s,			\
+		.parent		= p,			\
+	}
 
-static struct clk vpu_clk = {
-	.name = "vpu_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR2,
-	.enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
-	.get_rate = _clk_mbx_get_rate,
-};
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p)	\
+	static struct clk name = {				\
+		.id		= i,				\
+		.enable_reg	= er,				\
+		.enable_shift	= es,				\
+		.get_rate	= getsetround##_get_rate,	\
+		.set_rate	= getsetround##_set_rate,	\
+		.round_rate	= getsetround##_round_rate,	\
+		.enable		= cgr_enable,			\
+		.disable	= cgr_disable,			\
+		.secondary	= s,				\
+		.parent		= p,				\
+	}
 
-static struct clk rtic_clk = {
-	.name = "rtic_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR2,
-	.enable_shift = MXC_CCM_CGR2_RTIC_OFFSET,
-	.disable = _clk_disable,
-};
+DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
 
-static struct clk rng_clk = {
-	.name = "rng_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR0,
-	.enable_shift = MXC_CCM_CGR0_RNG_OFFSET,
-	.disable = _clk_disable,
-};
+DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(gpt_clk,     0, MXC_CCM_CGR0,  4, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit1_clk,   0, MXC_CCM_CGR0,  6, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit2_clk,   1, MXC_CCM_CGR0,  8, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(iim_clk,     0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ata_clk,     0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdma_clk1,   0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi3_clk,   2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rng_clk,     0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk,   0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart2_clk,   1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(ssi1_clk,    0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(i2c1_clk,    0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c2_clk,    1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c3_clk,    2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
 
-static struct clk sdma_clk[] = {
-	{
-	 .name = "sdma_ahb_clk",
-	 .parent = &ahb_clk,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR0,
-	 .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "sdma_ipg_clk",
-	 .parent = &ipg_clk,}
-};
+DEFINE_CLOCK(mpeg4_clk,   0, MXC_CCM_CGR1,  0, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &ahb_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(kpp_clk,     0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipu_clk,     0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
+DEFINE_CLOCK(uart3_clk,   2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart4_clk,   3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart5_clk,   4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(owire_clk,   0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
 
-static struct clk mpeg4_clk = {
-	.name = "mpeg4_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
-	.disable = _clk_disable,
-};
+DEFINE_CLOCK(ssi2_clk,    1, MXC_CCM_CGR2,  0, ssi2_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(cspi1_clk,   0, MXC_CCM_CGR2,  2, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk,   1, MXC_CCM_CGR2,  4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mbx_clk,     0, MXC_CCM_CGR2,  6, mbx_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk,     0, MXC_CCM_CGR2,  8, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk,    0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK1(firi_clk,   0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
 
-static struct clk vl2cc_clk = {
-	.name = "vl2cc_clk",
-	.parent = &ahb_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR1,
-	.enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
-	.disable = _clk_disable,
-};
+DEFINE_CLOCK(sdma_clk2,   0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
 
-static struct clk mstick_clk[] = {
-	{
-	 .name = "mstick_clk",
-	 .id = 0,
-	 .parent = &usb_pll_clk,
-	 .get_rate = _clk_mstick1_get_rate,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET,
-	 .disable = _clk_disable,},
-	{
-	 .name = "mstick_clk",
-	 .id = 1,
-	 .parent = &usb_pll_clk,
-	 .get_rate = _clk_mstick2_get_rate,
-	 .enable = _clk_enable,
-	 .enable_reg = MXC_CCM_CGR1,
-	 .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET,
-	 .disable = _clk_disable,},
-};
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
 
-static struct clk iim_clk = {
-	.name = "iim_clk",
-	.parent = &ipg_clk,
-	.enable = _clk_enable,
-	.enable_reg = MXC_CCM_CGR0,
-	.enable_shift = MXC_CCM_CGR0_IIM_OFFSET,
-	.disable = _clk_disable,
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK(NULL, "cspi", cspi1_clk)
+	_REGISTER_CLOCK(NULL, "cspi", cspi2_clk)
+	_REGISTER_CLOCK(NULL, "cspi", cspi3_clk)
+	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit1_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit2_clk)
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+	_REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+	_REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
+	_REGISTER_CLOCK("mx3-camera.0", NULL, csi_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)
+	_REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+	_REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+	_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(NULL, "firi", firi_clk)
+	_REGISTER_CLOCK(NULL, "ata", ata_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_REGISTER_CLOCK(NULL, "rng", rng_clk)
+	_REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
+	_REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
+	_REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
+	_REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
+	_REGISTER_CLOCK(NULL, "scc", scc_clk)
+	_REGISTER_CLOCK(NULL, "iim", iim_clk)
+	_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
+	_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
 };
 
-static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate)
-{
-	u32 div, parent = clk_get_rate(clk->parent);
-
-	div = parent / rate;
-	if (parent % rate)
-		div++;
-
-	if (div > 8)
-		div = 16;
-	else if (div > 4)
-		div = 8;
-	else if (div > 2)
-		div = 4;
-
-	return parent / div;
-}
-
-static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 reg, div, parent = clk_get_rate(clk->parent);
-
-	div = parent / rate;
-
-	if (div == 16)
-		div = 4;
-	else if (div == 8)
-		div = 3;
-	else if (div == 4)
-		div = 2;
-	else if (div == 2)
-		div = 1;
-	else if (div == 1)
-		div = 0;
-	else
-		return -EINVAL;
-
-	reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK;
-	reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET;
-	__raw_writel(reg, MXC_CCM_COSR);
-
-	return 0;
-}
-
-static unsigned long _clk_cko1_get_rate(struct clk *clk)
-{
-	u32 div;
-
-	div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >>
-	    MXC_CCM_COSR_CLKOUTDIV_OFFSET;
-
-	return clk_get_rate(clk->parent) / (1 << div);
-}
-
-static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK;
-
-	if (parent == &mcu_main_clk)
-		reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &ipg_clk)
-		reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &usb_pll_clk)
-		reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == mcu_main_clk.parent)
-		reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &ahb_clk)
-		reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &serial_pll_clk)
-		reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &ckih_clk)
-		reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &emi_clk)
-		reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &ipu_clk)
-		reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &nfc_clk)
-		reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else if (parent == &uart_clk[0])
-		reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET;
-	else
-		return -EINVAL;
-
-	__raw_writel(reg, MXC_CCM_COSR);
-
-	return 0;
-}
-
-static int _clk_cko1_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN;
-	__raw_writel(reg, MXC_CCM_COSR);
-
-	return 0;
-}
-
-static void _clk_cko1_disable(struct clk *clk)
+int __init mx31_clocks_init(unsigned long fref)
 {
 	u32 reg;
+	int i;
 
-	reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN;
-	__raw_writel(reg, MXC_CCM_COSR);
-}
-
-static struct clk cko1_clk = {
-	.name = "cko1_clk",
-	.get_rate = _clk_cko1_get_rate,
-	.set_rate = _clk_cko1_set_rate,
-	.round_rate = _clk_cko1_round_rate,
-	.set_parent = _clk_cko1_set_parent,
-	.enable = _clk_cko1_enable,
-	.disable = _clk_cko1_disable,
-};
-
-static struct clk *mxc_clks[] = {
-	&ckih_clk,
-	&ckil_clk,
-	&mcu_pll_clk,
-	&usb_pll_clk,
-	&serial_pll_clk,
-	&mcu_main_clk,
-	&ahb_clk,
-	&per_clk,
-	&perclk_clk,
-	&cko1_clk,
-	&emi_clk,
-	&cspi_clk[0],
-	&cspi_clk[1],
-	&cspi_clk[2],
-	&ipg_clk,
-	&gpt_clk,
-	&pwm_clk,
-	&wdog_clk,
-	&rtc_clk,
-	&epit_clk[0],
-	&epit_clk[1],
-	&nfc_clk,
-	&ipu_clk,
-	&kpp_clk,
-	&usb_clk[0],
-	&usb_clk[1],
-	&csi_clk,
-	&uart_clk[0],
-	&uart_clk[1],
-	&uart_clk[2],
-	&uart_clk[3],
-	&uart_clk[4],
-	&i2c_clk[0],
-	&i2c_clk[1],
-	&i2c_clk[2],
-	&owire_clk,
-	&sdhc_clk[0],
-	&sdhc_clk[1],
-	&ssi_clk[0],
-	&ssi_clk[1],
-	&firi_clk,
-	&ata_clk,
-	&rtic_clk,
-	&rng_clk,
-	&sdma_clk[0],
-	&sdma_clk[1],
-	&mstick_clk[0],
-	&mstick_clk[1],
-	&scc_clk,
-	&iim_clk,
-};
-
-int __init mxc_clocks_init(unsigned long fref)
-{
-	u32 reg;
-	struct clk **clkp;
+	mxc_set_cpu_type(MXC_CPU_MX31);
 
 	ckih_rate = fref;
 
-	for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
-		clk_register(*clkp);
-
-	if (cpu_is_mx31()) {
-		clk_register(&mpeg4_clk);
-		clk_register(&mbx_clk);
-	} else {
-		clk_register(&vpu_clk);
-		clk_register(&vl2cc_clk);
-	}
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
 
 	/* Turn off all possible clocks */
-	__raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0);
+	__raw_writel((3 << 4), MXC_CCM_CGR0);
 	__raw_writel(0, MXC_CCM_CGR1);
-
-	__raw_writel(MXC_CCM_CGR2_EMI_MASK |
-		     MXC_CCM_CGR2_IPMUX1_MASK |
-		     MXC_CCM_CGR2_IPMUX2_MASK |
-		     MXC_CCM_CGR2_MXCCLKENSEL_MASK |	/* for MX32 */
-		     MXC_CCM_CGR2_CHIKCAMPEN_MASK |	/* for MX32 */
-		     MXC_CCM_CGR2_OVRVPUBUSY_MASK |	/* for MX32 */
+	__raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
 		     1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
 					   MX32, but still required to be set */
 		     MXC_CCM_CGR2);
 
-	clk_disable(&cko1_clk);
-	clk_disable(&usb_pll_clk);
+	usb_pll_disable(&usb_pll_clk);
 
 	pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
 
@@ -1143,6 +598,8 @@ int __init mxc_clocks_init(unsigned long
 		__raw_writel(reg, MXC_CCM_PMCR1);
 	}
 
+	mxc_timer_init(&ipg_clk);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/clock-imx35.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/clock-imx35.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/clock-imx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/clock-imx35.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define CCM_BASE	IO_ADDRESS(CCM_BASE_ADDR)
+
+#define CCM_CCMR        0x00
+#define CCM_PDR0        0x04
+#define CCM_PDR1        0x08
+#define CCM_PDR2        0x0C
+#define CCM_PDR3        0x10
+#define CCM_PDR4        0x14
+#define CCM_RCSR        0x18
+#define CCM_MPCTL       0x1C
+#define CCM_PPCTL       0x20
+#define CCM_ACMR        0x24
+#define CCM_COSR        0x28
+#define CCM_CGR0        0x2C
+#define CCM_CGR1        0x30
+#define CCM_CGR2        0x34
+#define CCM_CGR3        0x38
+
+#ifdef HAVE_SET_RATE_SUPPORT
+static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
+{
+	u32 min_pre, temp_pre, old_err, err;
+
+	min_pre = (div - 1) / maxpost + 1;
+	old_err = 8;
+
+	for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+		if (div > (temp_pre * maxpost))
+			break;
+
+		if (div < (temp_pre * temp_pre))
+			continue;
+
+		err = div % temp_pre;
+
+		if (err == 0) {
+			*pre = temp_pre;
+			break;
+		}
+
+		err = temp_pre - err;
+
+		if (err < old_err) {
+			old_err = err;
+			*pre = temp_pre;
+		}
+	}
+
+	*post = (div + *pre - 1) / *pre;
+}
+
+/* get the best values for a 3-bit divider combined with a 6-bit divider */
+static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 512) {
+		*pre = 8;
+		*post = 64;
+	} else if (div >= 64) {
+		calc_dividers(div, pre, post, 64);
+	} else if (div <= 8) {
+		*pre = div;
+		*post = 1;
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+
+/* get the best values for two cascaded 3-bit dividers */
+static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 64) {
+		*pre = *post = 8;
+	} else if (div > 8) {
+		calc_dividers(div, pre, post, 8);
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+#endif
+
+static unsigned long get_rate_mpll(void)
+{
+	ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+
+	return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_ppll(void)
+{
+	ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+
+	return mxc_decode_pll(ppctl, 24000000);
+}
+
+struct arm_ahb_div {
+	unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+	{ .arm = 1, .ahb = 4, .sel = 0},
+	{ .arm = 1, .ahb = 3, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 1, .sel = 0},
+	{ .arm = 1, .ahb = 5, .sel = 0},
+	{ .arm = 1, .ahb = 8, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 1},
+	{ .arm = 2, .ahb = 4, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static struct arm_ahb_div clk_automotive[] = {
+	{ .arm = 1, .ahb = 3, .sel = 0},
+	{ .arm = 1, .ahb = 2, .sel = 1},
+	{ .arm = 2, .ahb = 1, .sel = 1},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 0},
+	{ .arm = 1, .ahb = 4, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 1},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static unsigned long get_rate_arm(void)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_mpll();
+
+	if (pdr0 & 1) {
+		/* consumer path */
+		aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+		if (aad->sel)
+			fref = fref * 2 / 3;
+	} else {
+		/* auto path */
+		aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+		if (aad->sel)
+			fref = fref * 3 / 4;
+	}
+	return fref / aad->arm;
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_mpll();
+
+	if (pdr0 & 1)
+		/* consumer path */
+		aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+	else
+		/* auto path */
+		aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+
+	return fref / aad->ahb;
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+	return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_3_3_div(unsigned long in)
+{
+	return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div = get_3_3_div(pdr4 >> 10);
+
+	if (pdr3 & (1 << 14))
+		return get_rate_arm() / div;
+	else
+		return get_rate_ppll() / div;
+}
+
+static unsigned long get_rate_sdhc(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long div, rate;
+
+	if (pdr3 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div = pdr3 & 0x3f;
+		break;
+	case 1:
+		div = (pdr3 >> 8) & 0x3f;
+		break;
+	case 2:
+		div = (pdr3 >> 16) & 0x3f;
+		break;
+	}
+
+	return rate / get_3_3_div(div);
+}
+
+static unsigned long get_rate_mshc(struct clk *clk)
+{
+	unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+	unsigned long div1, div2, rate;
+
+	if (pdr1 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	div1 = (pdr1 >> 29) & 0x7;
+	div2 = (pdr1 >> 22) & 0x3f;
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_ssi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long div1, div2, rate;
+
+	if (pdr2 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div1 = pdr2 & 0x3f;
+		div2 = (pdr2 >> 24) & 0x7;
+		break;
+	case 1:
+		div1 = (pdr2 >> 8) & 0x3f;
+		div2 = (pdr2 >> 27) & 0x7;
+		break;
+	}
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long rate;
+
+	if (pdr2 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
+}
+
+static unsigned long get_rate_ipg_per(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div1, div2;
+
+	if (pdr0 & (1 << 26)) {
+		div1 = (pdr4 >> 19) & 0x7;
+		div2 = (pdr4 >> 16) & 0x7;
+		return get_rate_arm() / ((div1 + 1) * (div2 + 1));
+	} else {
+		div1 = (pdr0 >> 12) & 0x7;
+		return get_rate_ahb(NULL) / div1;
+	}
+}
+
+static int clk_cgr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 3 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void clk_cgr_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(3 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= CCM_BASE + er,	\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= clk_cgr_enable,	\
+		.disable	= clk_cgr_disable,	\
+	}
+
+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(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);
+DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, NULL, NULL);
+DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
+DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, 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(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 _REGISTER_CLOCK(d, n, c)	\
+	{				\
+		.dev_id = d,		\
+		.con_id = n,		\
+		.clk = &c,		\
+	},
+
+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)
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK(NULL, "ect", ect_clk)
+	_REGISTER_CLOCK(NULL, "edio", edio_clk)
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit1_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit2_clk)
+	_REGISTER_CLOCK(NULL, "esai", esai_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
+	_REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+	_REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
+	_REGISTER_CLOCK(NULL, "ipu", ipu_clk)
+	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK(NULL, "mlb", mlb_clk)
+	_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+	_REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "rngc", rngc_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_REGISTER_CLOCK(NULL, "scc", scc_clk)
+	_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-uart.0", NULL, uart1_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+	_REGISTER_CLOCK(NULL, "usbotg", usbotg_clk)
+	_REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
+	_REGISTER_CLOCK(NULL, "max", max_clk)
+	_REGISTER_CLOCK(NULL, "admux", admux_clk)
+	_REGISTER_CLOCK(NULL, "csi", csi_clk)
+	_REGISTER_CLOCK(NULL, "iim", iim_clk)
+	_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+};
+
+int __init mx35_clocks_init()
+{
+	int i;
+	unsigned int ll = 0;
+
+	mxc_set_cpu_type(MXC_CPU_MX35);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+	ll = (3 << 16);
+#endif
+
+	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/2/3, GPT, IOMUX, MAX and eventually uart
+	 */
+	__raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+	__raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
+			CCM_BASE + CCM_CGR1);
+	__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
+	__raw_writel(0, CCM_BASE + CCM_CGR3);
+
+	mxc_timer_init(&gpt_clk);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/crm_regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/crm_regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/crm_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/crm_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -91,47 +91,6 @@
 #define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
 #define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
 
-#define MXC_CCM_PDR0_HSP_DIV_1                  (0x0 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_2                  (0x1 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_3                  (0x2 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_4                  (0x3 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_5                  (0x4 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_6                  (0x5 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_7                  (0x6 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_8                  (0x7 << 11)
-
-#define MXC_CCM_PDR0_IPG_DIV_1                  (0x0 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_2                  (0x1 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_3                  (0x2 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_4                  (0x3 << 6)
-
-#define MXC_CCM_PDR0_MAX_DIV_1                  (0x0 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_2                  (0x1 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_3                  (0x2 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_4                  (0x3 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_5                  (0x4 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_6                  (0x5 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_7                  (0x6 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_8                  (0x7 << 3)
-
-#define MXC_CCM_PDR0_NFC_DIV_1                  (0x0 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_2                  (0x1 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_3                  (0x2 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_4                  (0x3 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_5                  (0x4 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_6                  (0x5 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_7                  (0x6 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_8                  (0x7 << 8)
-
-#define MXC_CCM_PDR0_MCU_DIV_1                  0x0
-#define MXC_CCM_PDR0_MCU_DIV_2                  0x1
-#define MXC_CCM_PDR0_MCU_DIV_3                  0x2
-#define MXC_CCM_PDR0_MCU_DIV_4                  0x3
-#define MXC_CCM_PDR0_MCU_DIV_5                  0x4
-#define MXC_CCM_PDR0_MCU_DIV_6                  0x5
-#define MXC_CCM_PDR0_MCU_DIV_7                  0x6
-#define MXC_CCM_PDR0_MCU_DIV_8                  0x7
-
 #define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
 #define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
 #define MXC_CCM_PDR1_USB_PODF_OFFSET            27
@@ -152,118 +111,6 @@
 /* Bit definitions for RCSR */
 #define MXC_CCM_RCSR_NF16B			0x80000000
 
-/* Bit definitions for both MCU, USB and SR PLL control registers */
-#define MXC_CCM_PCTL_BRM                        0x80000000
-#define MXC_CCM_PCTL_PD_OFFSET                  26
-#define MXC_CCM_PCTL_PD_MASK                    (0xF << 26)
-#define MXC_CCM_PCTL_MFD_OFFSET                 16
-#define MXC_CCM_PCTL_MFD_MASK                   (0x3FF << 16)
-#define MXC_CCM_PCTL_MFI_OFFSET                 10
-#define MXC_CCM_PCTL_MFI_MASK                   (0xF << 10)
-#define MXC_CCM_PCTL_MFN_OFFSET                 0
-#define MXC_CCM_PCTL_MFN_MASK                   0x3FF
-
-#define MXC_CCM_CGR0_SD_MMC1_OFFSET             0
-#define MXC_CCM_CGR0_SD_MMC1_MASK               (0x3 << 0)
-#define MXC_CCM_CGR0_SD_MMC2_OFFSET             2
-#define MXC_CCM_CGR0_SD_MMC2_MASK               (0x3 << 2)
-#define MXC_CCM_CGR0_GPT_OFFSET                 4
-#define MXC_CCM_CGR0_GPT_MASK                   (0x3 << 4)
-#define MXC_CCM_CGR0_EPIT1_OFFSET               6
-#define MXC_CCM_CGR0_EPIT1_MASK                 (0x3 << 6)
-#define MXC_CCM_CGR0_EPIT2_OFFSET               8
-#define MXC_CCM_CGR0_EPIT2_MASK                 (0x3 << 8)
-#define MXC_CCM_CGR0_IIM_OFFSET                 10
-#define MXC_CCM_CGR0_IIM_MASK                   (0x3 << 10)
-#define MXC_CCM_CGR0_ATA_OFFSET                 12
-#define MXC_CCM_CGR0_ATA_MASK                   (0x3 << 12)
-#define MXC_CCM_CGR0_SDMA_OFFSET                14
-#define MXC_CCM_CGR0_SDMA_MASK                  (0x3 << 14)
-#define MXC_CCM_CGR0_CSPI3_OFFSET               16
-#define MXC_CCM_CGR0_CSPI3_MASK                 (0x3 << 16)
-#define MXC_CCM_CGR0_RNG_OFFSET                 18
-#define MXC_CCM_CGR0_RNG_MASK                   (0x3 << 18)
-#define MXC_CCM_CGR0_UART1_OFFSET               20
-#define MXC_CCM_CGR0_UART1_MASK                 (0x3 << 20)
-#define MXC_CCM_CGR0_UART2_OFFSET               22
-#define MXC_CCM_CGR0_UART2_MASK                 (0x3 << 22)
-#define MXC_CCM_CGR0_SSI1_OFFSET                24
-#define MXC_CCM_CGR0_SSI1_MASK                  (0x3 << 24)
-#define MXC_CCM_CGR0_I2C1_OFFSET                26
-#define MXC_CCM_CGR0_I2C1_MASK                  (0x3 << 26)
-#define MXC_CCM_CGR0_I2C2_OFFSET                28
-#define MXC_CCM_CGR0_I2C2_MASK                  (0x3 << 28)
-#define MXC_CCM_CGR0_I2C3_OFFSET                30
-#define MXC_CCM_CGR0_I2C3_MASK                  (0x3 << 30)
-
-#define MXC_CCM_CGR1_HANTRO_OFFSET              0
-#define MXC_CCM_CGR1_HANTRO_MASK                (0x3 << 0)
-#define MXC_CCM_CGR1_MEMSTICK1_OFFSET           2
-#define MXC_CCM_CGR1_MEMSTICK1_MASK             (0x3 << 2)
-#define MXC_CCM_CGR1_MEMSTICK2_OFFSET           4
-#define MXC_CCM_CGR1_MEMSTICK2_MASK             (0x3 << 4)
-#define MXC_CCM_CGR1_CSI_OFFSET                 6
-#define MXC_CCM_CGR1_CSI_MASK                   (0x3 << 6)
-#define MXC_CCM_CGR1_RTC_OFFSET                 8
-#define MXC_CCM_CGR1_RTC_MASK                   (0x3 << 8)
-#define MXC_CCM_CGR1_WDOG_OFFSET                10
-#define MXC_CCM_CGR1_WDOG_MASK                  (0x3 << 10)
-#define MXC_CCM_CGR1_PWM_OFFSET                 12
-#define MXC_CCM_CGR1_PWM_MASK                   (0x3 << 12)
-#define MXC_CCM_CGR1_SIM_OFFSET                 14
-#define MXC_CCM_CGR1_SIM_MASK                   (0x3 << 14)
-#define MXC_CCM_CGR1_ECT_OFFSET                 16
-#define MXC_CCM_CGR1_ECT_MASK                   (0x3 << 16)
-#define MXC_CCM_CGR1_USBOTG_OFFSET              18
-#define MXC_CCM_CGR1_USBOTG_MASK                (0x3 << 18)
-#define MXC_CCM_CGR1_KPP_OFFSET                 20
-#define MXC_CCM_CGR1_KPP_MASK                   (0x3 << 20)
-#define MXC_CCM_CGR1_IPU_OFFSET                 22
-#define MXC_CCM_CGR1_IPU_MASK                   (0x3 << 22)
-#define MXC_CCM_CGR1_UART3_OFFSET               24
-#define MXC_CCM_CGR1_UART3_MASK                 (0x3 << 24)
-#define MXC_CCM_CGR1_UART4_OFFSET               26
-#define MXC_CCM_CGR1_UART4_MASK                 (0x3 << 26)
-#define MXC_CCM_CGR1_UART5_OFFSET               28
-#define MXC_CCM_CGR1_UART5_MASK                 (0x3 << 28)
-#define MXC_CCM_CGR1_OWIRE_OFFSET               30
-#define MXC_CCM_CGR1_OWIRE_MASK                 (0x3 << 30)
-
-#define MXC_CCM_CGR2_SSI2_OFFSET                0
-#define MXC_CCM_CGR2_SSI2_MASK                  (0x3 << 0)
-#define MXC_CCM_CGR2_CSPI1_OFFSET               2
-#define MXC_CCM_CGR2_CSPI1_MASK                 (0x3 << 2)
-#define MXC_CCM_CGR2_CSPI2_OFFSET               4
-#define MXC_CCM_CGR2_CSPI2_MASK                 (0x3 << 4)
-#define MXC_CCM_CGR2_GACC_OFFSET                6
-#define MXC_CCM_CGR2_GACC_MASK                  (0x3 << 6)
-#define MXC_CCM_CGR2_EMI_OFFSET                 8
-#define MXC_CCM_CGR2_EMI_MASK                   (0x3 << 8)
-#define MXC_CCM_CGR2_RTIC_OFFSET                10
-#define MXC_CCM_CGR2_RTIC_MASK                  (0x3 << 10)
-#define MXC_CCM_CGR2_FIRI_OFFSET                12
-#define MXC_CCM_CGR2_FIRI_MASK                  (0x3 << 12)
-#define MXC_CCM_CGR2_IPMUX1_OFFSET              14
-#define MXC_CCM_CGR2_IPMUX1_MASK                (0x3 << 14)
-#define MXC_CCM_CGR2_IPMUX2_OFFSET              16
-#define MXC_CCM_CGR2_IPMUX2_MASK                (0x3 << 16)
-
-/* These new CGR2 bits are added in MX32 */
-#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET	18
-#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK		(0x3 << 18)
-#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET	20
-#define MXC_CCM_CGR2_APMSSICLKSEL_MASK		(0x3 << 20)
-#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET	22
-#define MXC_CCM_CGR2_APMPERCLKSEL_MASK		(0x3 << 22)
-#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET		24
-#define MXC_CCM_CGR2_MXCCLKENSEL_MASK		(0x1 << 24)
-#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET		25
-#define MXC_CCM_CGR2_CHIKCAMPEN_MASK		(0x1 << 25)
-#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET		26
-#define MXC_CCM_CGR2_OVRVPUBUSY_MASK		(0x1 << 26)
-#define MXC_CCM_CGR2_APMENA_OFFSET		30
-#define MXC_CCM_CGR2_AOMENA_MASK		(0x1 << 30)
-
 /*
  * LTR0 register offsets
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,8 @@
 #include <mach/irqs.h>
 #include <mach/imx-uart.h>
 
+#include "devices.h"
+
 static struct resource uart0[] = {
 	{
 		.start = UART1_BASE_ADDR,
@@ -82,6 +84,7 @@ struct platform_device mxc_uart_device2
 	.num_resources = ARRAY_SIZE(uart2),
 };
 
+#ifdef CONFIG_ARCH_MX31
 static struct resource uart3[] = {
 	{
 		.start = UART4_BASE_ADDR,
@@ -119,6 +122,7 @@ struct platform_device mxc_uart_device4
 	.resource = uart4,
 	.num_resources = ARRAY_SIZE(uart4),
 };
+#endif /* CONFIG_ARCH_MX31 */
 
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
@@ -164,8 +168,8 @@ struct platform_device mxc_w1_master_dev
 
 static struct resource mxc_nand_resources[] = {
 	{
-		.start	= NFC_BASE_ADDR,
-		.end	= NFC_BASE_ADDR + 0xfff,
+		.start	= 0, /* runtime dependent */
+		.end	= 0,
 		.flags	= IORESOURCE_MEM
 	}, {
 		.start	= MXC_INT_NANDFC,
@@ -180,3 +184,188 @@ struct platform_device mxc_nand_device =
 	.num_resources = ARRAY_SIZE(mxc_nand_resources),
 	.resource = mxc_nand_resources,
 };
+
+static struct resource mxc_i2c0_resources[] = {
+	{
+		.start = I2C_BASE_ADDR,
+		.end = I2C_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C,
+		.end = MXC_INT_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device0 = {
+	.name = "imx-i2c",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_i2c0_resources),
+	.resource = mxc_i2c0_resources,
+};
+
+static struct resource mxc_i2c1_resources[] = {
+	{
+		.start = I2C2_BASE_ADDR,
+		.end = I2C2_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C2,
+		.end = MXC_INT_I2C2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device1 = {
+	.name = "imx-i2c",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_i2c1_resources),
+	.resource = mxc_i2c1_resources,
+};
+
+static struct resource mxc_i2c2_resources[] = {
+	{
+		.start = I2C3_BASE_ADDR,
+		.end = I2C3_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C3,
+		.end = MXC_INT_I2C3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device2 = {
+	.name = "imx-i2c",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_i2c2_resources),
+	.resource = mxc_i2c2_resources,
+};
+
+#ifdef CONFIG_ARCH_MX31
+static struct resource mxcsdhc0_resources[] = {
+	{
+		.start = MMC_SDHC1_BASE_ADDR,
+		.end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_MMC_SDHC1,
+		.end = MXC_INT_MMC_SDHC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource mxcsdhc1_resources[] = {
+	{
+		.start = MMC_SDHC2_BASE_ADDR,
+		.end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_MMC_SDHC2,
+		.end = MXC_INT_MMC_SDHC2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxcsdhc_device0 = {
+	.name = "mxc-mmc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxcsdhc0_resources),
+	.resource = mxcsdhc0_resources,
+};
+
+struct platform_device mxcsdhc_device1 = {
+	.name = "mxc-mmc",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+	.resource = mxcsdhc1_resources,
+};
+#endif /* CONFIG_ARCH_MX31 */
+
+/* i.MX31 Image Processing Unit */
+
+/* The resource order is important! */
+static struct resource mx3_ipu_rsrc[] = {
+	{
+		.start = IPU_CTRL_BASE_ADDR,
+		.end = IPU_CTRL_BASE_ADDR + 0x5F,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IPU_CTRL_BASE_ADDR + 0x88,
+		.end = IPU_CTRL_BASE_ADDR + 0xB3,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_IPU_SYN,
+		.end = MXC_INT_IPU_SYN,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC_INT_IPU_ERR,
+		.end = MXC_INT_IPU_ERR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mx3_ipu = {
+	.name = "ipu-core",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(mx3_ipu_rsrc),
+	.resource = mx3_ipu_rsrc,
+};
+
+static struct resource fb_resources[] = {
+	{
+		.start	= IPU_CTRL_BASE_ADDR + 0xB4,
+		.end	= IPU_CTRL_BASE_ADDR + 0x1BF,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device mx3_fb = {
+	.name		= "mx3_sdc_fb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(fb_resources),
+	.resource	= fb_resources,
+	.dev		= {
+		.coherent_dma_mask = 0xffffffff,
+       },
+};
+
+#ifdef CONFIG_ARCH_MX35
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= MXC_FEC_BASE_ADDR,
+		.end	= MXC_FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MXC_INT_FEC,
+		.end	= MXC_INT_FEC,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mxc_fec_device = {
+	.name = "fec",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fec_resources),
+	.resource = mxc_fec_resources,
+};
+#endif
+
+static int mx3_devices_init(void)
+{
+	if (cpu_is_mx31()) {
+		mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
+		mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+	}
+	if (cpu_is_mx35()) {
+		mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
+		mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
+	}
+
+	return 0;
+}
+
+subsys_initcall(mx3_devices_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/devices.h linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/devices.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/devices.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/devices.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,3 +6,11 @@ extern struct platform_device mxc_uart_d
 extern struct platform_device mxc_uart_device4;
 extern struct platform_device mxc_w1_master_device;
 extern struct platform_device mxc_nand_device;
+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 mx3_ipu;
+extern struct platform_device mx3_fb;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxcsdhc_device0;
+extern struct platform_device mxcsdhc_device1;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/iomux.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/iomux.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/iomux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/iomux.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -21,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/kernel.h>
 #include <mach/hardware.h>
 #include <mach/gpio.h>
 #include <mach/iomux-mx3.h>
@@ -38,6 +40,8 @@
 static DEFINE_SPINLOCK(gpio_mux_lock);
 
 #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
 /*
  * set the mode for a IOMUX pin.
  */
@@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode
 	field = pin_mode & 0x3;
 	mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
 
-	pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
-			__func__, (pin_mode & IOMUX_REG_MASK), field, mode);
-
 	spin_lock(&gpio_mux_lock);
 
 	l = __raw_readl(reg);
@@ -93,6 +94,86 @@ void mxc_iomux_set_pad(enum iomux_pins p
 EXPORT_SYMBOL(mxc_iomux_set_pad);
 
 /*
+ * 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 through kernel gpiolib
+ */
+int mxc_iomux_setup_pin(const unsigned int pin, const char *label)
+{
+	unsigned pad = pin & IOMUX_PADNUM_MASK;
+	unsigned gpio;
+
+	if (pad >= (PIN_MAX + 1)) {
+		printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+			pad, label ? label : "?");
+		return -EINVAL;
+	}
+
+	if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+		printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+			pad, label ? label : "?");
+		return -EINVAL;
+	}
+	mxc_iomux_mode(pin);
+
+	/* if we have a gpio, we can allocate it */
+	gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+	if (gpio < (GPIO_PORT_MAX + 1) * 32)
+		if (gpio_request(gpio, label))
+			return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_pin);
+
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+		const char *label)
+{
+	unsigned int *p = pin_list;
+	int i;
+	int ret = -EINVAL;
+
+	for (i = 0; i < count; i++) {
+		if (mxc_iomux_setup_pin(*p, label))
+			goto setup_error;
+		p++;
+	}
+	return 0;
+
+setup_error:
+	mxc_iomux_release_multiple_pins(pin_list, i);
+	return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(const unsigned int pin)
+{
+	unsigned pad = pin & IOMUX_PADNUM_MASK;
+	unsigned gpio;
+
+	if (pad < (PIN_MAX + 1))
+		clear_bit(pad, mxc_pin_alloc_map);
+
+	gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+	if (gpio < (GPIO_PORT_MAX + 1) * 32)
+		gpio_free(gpio);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+{
+	unsigned int *p = pin_list;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		mxc_iomux_release_pin(*p);
+		p++;
+	}
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
+
+/*
  * This function enables/disables the general purpose function for a particular
  * signal.
  */
@@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_fun
 	spin_unlock(&gpio_mux_lock);
 }
 EXPORT_SYMBOL(mxc_iomux_set_gpr);
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,21 +1,42 @@
-menu "MX3 Options"
-	depends on ARCH_MX3
+if ARCH_MX3
+
+config ARCH_MX31
+	bool
+
+config ARCH_MX35
+	bool
+
+comment "MX3 platforms:"
 
 config MACH_MX31ADS
 	bool "Support MX31ADS platforms"
+	select ARCH_MX31
 	default y
 	help
 	  Include support for MX31ADS platform. This includes specific
 	  configurations for the board and its peripherals.
 
+config MACH_MX31ADS_WM1133_EV1
+	bool "Support Wolfson Microelectronics 1133-EV1 module"
+	depends on MACH_MX31ADS
+	depends on MFD_WM8350_I2C
+	depends on REGULATOR_WM8350
+	select MFD_WM8350_CONFIG_MODE_0
+	select MFD_WM8352_CONFIG_MODE_0
+	help
+	  Include support for the Wolfson Microelectronics 1133-EV1 PMU
+	  and audio module for the MX31ADS platform.
+
 config MACH_PCM037
-	bool "Support Phytec pcm037 platforms"
+	bool "Support Phytec pcm037 (i.MX31) platforms"
+	select ARCH_MX31
 	help
 	  Include support for Phytec pcm037 platform. This includes
 	  specific configurations for the board and its peripherals.
 
 config MACH_MX31LITE
 	bool "Support MX31 LITEKIT (LogicPD)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for MX31 LITEKIT platform. This includes specific
@@ -23,6 +44,7 @@ config MACH_MX31LITE
 
 config MACH_MX31_3DS
 	bool "Support MX31PDK (3DS)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for MX31PDK (3DS) platform. This includes specific
@@ -30,10 +52,18 @@ config MACH_MX31_3DS
 
 config MACH_MX31MOBOARD
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for mx31moboard platform. This includes specific
 	  configurations for the board and its peripherals.
 
-endmenu
+config MACH_QONG
+	bool "Support Dave/DENX QongEVB-LITE platform"
+	select ARCH_MX31
+	default n
+	help
+	  Include support for Dave/DENX QongEVB-LITE platform. This includes
+	  specific configurations for the board and its peripherals.
 
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,9 +4,13 @@
 
 # Object file lists.
 
-obj-y			:= mm.o clock.o devices.o iomux.o
+obj-y				:= mm.o devices.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_MX31LITE)	+= mx31lite.o
 obj-$(CONFIG_MACH_PCM037)	+= pcm037.o
 obj-$(CONFIG_MACH_MX31_3DS)	+= mx31pdk.o
-obj-$(CONFIG_MACH_MX31MOBOARD)	+= mx31moboard.o
+obj-$(CONFIG_MACH_MX31MOBOARD)	+= mx31moboard.o mx31moboard-devboard.o \
+				   mx31moboard-marxbot.o
+obj-$(CONFIG_MACH_QONG)		+= qong.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mm.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mm.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,10 +22,14 @@
 
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <mach/hardware.h>
+#include <linux/err.h>
+
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
 #include <mach/common.h>
+#include <mach/hardware.h>
 
 /*!
  * @file mm.c
@@ -50,6 +54,16 @@ static struct map_desc mxc_io_desc[] __i
 		.pfn		= __phys_to_pfn(AVIC_BASE_ADDR),
 		.length		= AVIC_SIZE,
 		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= AIPS1_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
+		.length		= AIPS1_SIZE,
+		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= AIPS2_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
+		.length		= AIPS2_SIZE,
+		.type		= MT_DEVICE_NONSHARED
 	},
 };
 
@@ -62,3 +76,24 @@ void __init mxc_map_io(void)
 {
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
+
+#ifdef CONFIG_CACHE_L2X0
+static int mxc_init_l2x0(void)
+{
+	void __iomem *l2x0_base;
+
+	l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
+	if (IS_ERR(l2x0_base)) {
+		printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
+				PTR_ERR(l2x0_base));
+		return 0;
+	}
+
+	l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+
+	return 0;
+}
+
+arch_initcall(mxc_init_l2x0);
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31ads.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31ads.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31ads.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31ads.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,8 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
 #include <linux/irq.h>
 
 #include <mach/hardware.h>
@@ -35,6 +37,12 @@
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
 #include "devices.h"
 
 /*!
@@ -94,13 +102,16 @@ static struct imxuart_platform_data uart
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
+static unsigned int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
 static inline void mxc_init_imx_uart(void)
 {
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 }
 #else /* !SERIAL_IMX */
@@ -176,7 +187,7 @@ static void __init mx31ads_init_expio(vo
 	/*
 	 * Configure INT line as GPIO input
 	 */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+	mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
 
 	/* disable the interrupt and clear the status */
 	__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
@@ -191,26 +202,303 @@ static void __init mx31ads_init_expio(vo
 	set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
 }
 
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+/* This section defines setup for the Wolfson Microelectronics
+ * 1133-EV1 PMU/audio board.  When other PMU boards are supported the
+ * regulator definitions may be shared with them, but for now they can
+ * only be used with this board so would generate warnings about
+ * unused statics and some of the configuration is specific to this
+ * module.
+ */
+
+/* CPU */
+static struct regulator_consumer_supply sw1a_consumers[] = {
+	{
+		.supply = "cpu_vcc",
+	}
+};
+
+static struct regulator_init_data sw1a_data = {
+	.constraints = {
+		.name = "SW1A",
+		.min_uV = 1275000,
+		.max_uV = 1600000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_MODE,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+				    REGULATOR_MODE_FAST,
+		.state_mem = {
+			 .uV = 1400000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+	.consumer_supplies = sw1a_consumers,
+};
+
+/* System IO - High */
+static struct regulator_init_data viohi_data = {
+	.constraints = {
+		.name = "VIOHO",
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+		.state_mem = {
+			 .uV = 2800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* System IO - Low */
+static struct regulator_init_data violo_data = {
+	.constraints = {
+		.name = "VIOLO",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.state_mem = {
+			 .uV = 1800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* DDR RAM */
+static struct regulator_init_data sw2a_data = {
+	.constraints = {
+		.name = "SW2A",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.state_mem = {
+			 .uV = 1800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.state_disk = {
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 0,
+		 },
+		.always_on = 1,
+		.boot_on = 1,
+		.initial_state = PM_SUSPEND_MEM,
+	},
+};
+
+static struct regulator_init_data ldo1_data = {
+	.constraints = {
+		.name = "VCAM/VMMC1/VMMC2",
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+	},
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+	{
+		.supply = "AVDD",
+	},
+	{
+		.supply = "HPVDD",
+	},
+};
+
+/* CODEC and SIM */
+static struct regulator_init_data ldo2_data = {
+	.constraints = {
+		.name = "VESIM/VSIM/AVDD",
+		.min_uV = 3300000,
+		.max_uV = 3300000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+	.consumer_supplies = ldo2_consumers,
+};
+
+/* General */
+static struct regulator_init_data vdig_data = {
+	.constraints = {
+		.name = "VDIG",
+		.min_uV = 1500000,
+		.max_uV = 1500000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* Tranceivers */
+static struct regulator_init_data ldo4_data = {
+	.constraints = {
+		.name = "VRF1/CVDD_2.775",
+		.min_uV = 2500000,
+		.max_uV = 2500000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+static struct wm8350_led_platform_data wm8350_led_data = {
+	.name            = "wm8350:white",
+	.default_trigger = "heartbeat",
+	.max_uA          = 27899,
+};
+
+static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
+	.vmid_discharge_msecs = 1000,
+	.drain_msecs = 30,
+	.cap_discharge_msecs = 700,
+	.vmid_charge_msecs = 700,
+	.vmid_s_curve = WM8350_S_CURVE_SLOW,
+	.dis_out4 = WM8350_DISCHARGE_SLOW,
+	.dis_out3 = WM8350_DISCHARGE_SLOW,
+	.dis_out2 = WM8350_DISCHARGE_SLOW,
+	.dis_out1 = WM8350_DISCHARGE_SLOW,
+	.vroi_out4 = WM8350_TIE_OFF_500R,
+	.vroi_out3 = WM8350_TIE_OFF_500R,
+	.vroi_out2 = WM8350_TIE_OFF_500R,
+	.vroi_out1 = WM8350_TIE_OFF_500R,
+	.vroi_enable = 0,
+	.codec_current_on = WM8350_CODEC_ISEL_1_0,
+	.codec_current_standby = WM8350_CODEC_ISEL_0_5,
+	.codec_current_charge = WM8350_CODEC_ISEL_1_5,
+};
+
+static int mx31_wm8350_init(struct wm8350 *wm8350)
+{
+	int i;
+
+	wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_ON);
+
+	wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_ON);
+
+	wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	/* Fix up for our own supplies. */
+	for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++)
+		ldo2_consumers[i].dev = wm8350->dev;
+
+	wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
+
+	/* LEDs */
+	wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
+			     WM8350_DC5_ERRACT_SHUTDOWN_CONV);
+	wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
+			       WM8350_ISINK_FLASH_DISABLE,
+			       WM8350_ISINK_FLASH_TRIG_BIT,
+			       WM8350_ISINK_FLASH_DUR_32MS,
+			       WM8350_ISINK_FLASH_ON_INSTANT,
+			       WM8350_ISINK_FLASH_OFF_INSTANT,
+			       WM8350_ISINK_FLASH_MODE_EN);
+	wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
+			       WM8350_ISINK_MODE_BOOST,
+			       WM8350_ISINK_ILIM_NORMAL,
+			       WM8350_DC5_RMP_20V,
+			       WM8350_DC5_FBSRC_ISINKA);
+	wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
+			    &wm8350_led_data);
+
+	wm8350->codec.platform_data = &imx32ads_wm8350_setup;
+
+	regulator_has_full_constraints();
+
+	return 0;
+}
+
+static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
+	.init = mx31_wm8350_init,
+};
+#endif
+
+#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
+static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+	{
+		I2C_BOARD_INFO("wm8350", 0x1a),
+		.platform_data = &mx31_wm8350_pdata,
+		.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+	},
+#endif
+};
+
+static void mxc_init_i2c(void)
+{
+	i2c_register_board_info(1, mx31ads_i2c1_devices,
+				ARRAY_SIZE(mx31ads_i2c1_devices));
+
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
+
+	mxc_register_device(&mxc_i2c_device1, NULL);
+}
+#else
+static void mxc_init_i2c(void)
+{
+}
+#endif
+
 /*!
  * This structure defines static mappings for the i.MX31ADS board.
  */
 static struct map_desc mx31ads_io_desc[] __initdata = {
 	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
 		.virtual	= SPBA0_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length		= SPBA0_SIZE,
 		.type		= MT_DEVICE_NONSHARED
 	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
 		.virtual	= CS4_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
 		.length		= CS4_SIZE / 2,
@@ -221,13 +509,13 @@ static struct map_desc mx31ads_io_desc[]
 /*!
  * Set up static virtual mappings.
  */
-void __init mx31ads_map_io(void)
+static void __init mx31ads_map_io(void)
 {
 	mxc_map_io();
 	iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
 }
 
-void __init mx31ads_init_irq(void)
+static void __init mx31ads_init_irq(void)
 {
 	mxc_init_irq();
 	mx31ads_init_expio();
@@ -240,15 +528,15 @@ static void __init mxc_board_init(void)
 {
 	mxc_init_extuart();
 	mxc_init_imx_uart();
+	mxc_init_i2c();
 }
 
 static void __init mx31ads_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
-struct sys_timer mx31ads_timer = {
+static struct sys_timer mx31ads_timer = {
 	.init	= mx31ads_timer_init,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31lite.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31lite.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31lite.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31lite.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,21 +42,11 @@
  */
 static struct map_desc mx31lite_io_desc[] __initdata = {
 	{
-		.virtual = AIPS1_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length = AIPS1_SIZE,
-		.type = MT_DEVICE_NONSHARED
-	}, {
 		.virtual = SPBA0_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length = SPBA0_SIZE,
 		.type = MT_DEVICE_NONSHARED
 	}, {
-		.virtual = AIPS2_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length = AIPS2_SIZE,
-		.type = MT_DEVICE_NONSHARED
-	}, {
 		.virtual = CS4_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
 		.length = CS4_SIZE,
@@ -82,8 +72,7 @@ static void __init mxc_board_init(void)
 
 static void __init mx31lite_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer mx31lite_timer = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #include <mach/common.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
 
 #include "devices.h"
 
@@ -63,6 +64,18 @@ static struct platform_device *devices[]
 	&mx31moboard_flash,
 };
 
+static int mxc_uart0_pins[] = {
+	MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+};
+static int mxc_uart4_pins[] = {
+	MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+	MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+};
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
 /*
  * Board specific initialization.
  */
@@ -70,58 +83,29 @@ static void __init mxc_board_init(void)
 {
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_CTS2__CTS2);
-	mxc_iomux_mode(MX31_PIN_RTS2__RTS2);
-	mxc_iomux_mode(MX31_PIN_TXD2__TXD2);
-	mxc_iomux_mode(MX31_PIN_RXD2__RXD2);
-
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
-	mxc_iomux_mode(MX31_PIN_PC_RST__CTS5);
-	mxc_iomux_mode(MX31_PIN_PC_VS2__RTS5);
-	mxc_iomux_mode(MX31_PIN_PC_BVD2__TXD5);
-	mxc_iomux_mode(MX31_PIN_PC_BVD1__RXD5);
-
+	mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4");
 	mxc_register_device(&mxc_uart_device4, &uart_pdata);
-}
-
-/*
- * This structure defines static mappings for the mx31moboard.
- */
-static struct map_desc mx31moboard_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
 
-/*
- * Set up static virtual mappings.
- */
-void __init mx31moboard_map_io(void)
-{
-	mxc_map_io();
-	iotable_init(mx31moboard_io_desc, ARRAY_SIZE(mx31moboard_io_desc));
+	switch (mx31moboard_baseboard) {
+	case MX31NOBOARD:
+		break;
+	case MX31DEVBOARD:
+		mx31moboard_devboard_init();
+		break;
+	case MX31MARXBOT:
+		mx31moboard_marxbot_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard);
+	}
 }
 
 static void __init mx31moboard_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer mx31moboard_timer = {
@@ -133,7 +117,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31moboard_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31moboard_timer,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard-devboard.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int mxc_uart1_pins[] = {
+	MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_devboard_init(void)
+{
+	printk(KERN_INFO "Initializing mx31devboard peripherals\n");
+	mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1");
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31moboard-marxbot.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * 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/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_marxbot_init(void)
+{
+	printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31pdk.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31pdk.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/mx31pdk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/mx31pdk.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,40 +45,17 @@ static struct imxuart_platform_data uart
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static inline void mxc_init_imx_uart(void)
-{
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-}
-
-/*!
- * This structure defines static mappings for the i.MX31PDK board.
- */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
+static int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
 };
 
-/*!
- * Set up static virtual mappings.
- */
-static void __init mx31pdk_map_io(void)
+static inline void mxc_init_imx_uart(void)
 {
-	mxc_map_io();
-	iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 }
 
 /*!
@@ -91,8 +68,7 @@ static void __init mxc_board_init(void)
 
 static void __init mx31pdk_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 static struct sys_timer mx31pdk_timer = {
@@ -108,7 +84,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31P
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31pdk_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31pdk_timer,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/pcm037.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/pcm037.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/pcm037.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/pcm037.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,10 @@
 #include <linux/mtd/plat-ram.h>
 #include <linux/memory.h>
 #include <linux/gpio.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
 #include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -37,6 +39,10 @@
 #include <mach/iomux-mx3.h>
 #include <mach/board-pcm037.h>
 #include <mach/mxc_nand.h>
+#include <mach/mmc.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
 
 #include "devices.h"
 
@@ -64,7 +70,7 @@ static struct imxuart_platform_data uart
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static struct resource smc911x_resources[] = {
+static struct resource smsc911x_resources[] = {
 	[0] = {
 		.start		= CS1_BASE_ADDR + 0x300,
 		.end		= CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
@@ -73,22 +79,25 @@ static struct resource smc911x_resources
 	[1] = {
 		.start		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
 		.end		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
-		.flags		= IORESOURCE_IRQ,
+		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
 
-static struct smc911x_platdata smc911x_info = {
-	.flags		= SMC911X_USE_32BIT,
-	.irq_flags	= IRQF_SHARED | IRQF_TRIGGER_LOW,
+static struct smsc911x_platform_config smsc911x_info = {
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+			  SMSC911X_SAVE_MAC_ADDRESS,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
 };
 
 static struct platform_device pcm037_eth = {
-	.name		= "smc911x",
+	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smc911x_resources),
-	.resource	= smc911x_resources,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
 	.dev		= {
-		.platform_data = &smc911x_info,
+		.platform_data = &smsc911x_info,
 	},
 };
 
@@ -117,12 +126,90 @@ static struct mxc_nand_platform_data pcm
 	.hw_ecc = 1,
 };
 
+#ifdef CONFIG_I2C_IMX
+static int i2c_1_pins[] = {
+	MX31_PIN_CSPI2_MOSI__SCL,
+	MX31_PIN_CSPI2_MISO__SDA,
+};
+
+static int pcm037_i2c_1_init(struct device *dev)
+{
+	return mxc_iomux_setup_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins),
+			"i2c-1");
+}
+
+static void pcm037_i2c_1_exit(struct device *dev)
+{
+	mxc_iomux_release_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins));
+}
+
+static struct imxi2c_platform_data pcm037_i2c_1_data = {
+	.bitrate = 100000,
+	.init = pcm037_i2c_1_init,
+	.exit = pcm037_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm037_i2c_devices[] = {
+       {
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+		.type = "pcf8563",
+	}
+};
+#endif
+
+static int sdhc1_pins[] = {
+	MX31_PIN_SD1_DATA3__SD1_DATA3,
+	MX31_PIN_SD1_DATA2__SD1_DATA2,
+	MX31_PIN_SD1_DATA1__SD1_DATA1,
+	MX31_PIN_SD1_DATA0__SD1_DATA0,
+	MX31_PIN_SD1_CLK__SD1_CLK,
+	MX31_PIN_SD1_CMD__SD1_CMD,
+};
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t h, void *data)
+{
+	return mxc_iomux_setup_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins),
+				"sdhc-1");
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+	mxc_iomux_release_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins));
+}
+
+/* No card and rw detection at the moment */
+static struct imxmmc_platform_data sdhc_pdata = {
+	.init = pcm970_sdhc1_init,
+	.exit = pcm970_sdhc1_exit,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&pcm037_flash,
 	&pcm037_eth,
 	&pcm037_sram_device,
 };
 
+static int uart0_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
+static int uart2_pins[] = {
+	MX31_PIN_CSPI3_MOSI__RXD3,
+	MX31_PIN_CSPI3_MISO__TXD3
+};
+
 /*
  * Board specific initialization.
  */
@@ -130,59 +217,33 @@ static void __init mxc_board_init(void)
 {
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(uart0_pins, ARRAY_SIZE(uart0_pins), "uart-0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
-	mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
-
+	mxc_iomux_setup_multiple_pins(uart2_pins, ARRAY_SIZE(uart2_pins), "uart-2");
 	mxc_register_device(&mxc_uart_device2, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_BATT_LINE__OWIRE);
+	mxc_iomux_setup_pin(MX31_PIN_BATT_LINE__OWIRE, "batt-0wire");
 	mxc_register_device(&mxc_w1_master_device, NULL);
 
-	/* SMSC9215 IRQ pin */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO));
-	if (!gpio_request(MX31_PIN_GPIO3_1, "pcm037-eth"))
-		gpio_direction_input(MX31_PIN_GPIO3_1);
-
-	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
-}
+	/* LAN9217 IRQ pin */
+	if (!mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+				"pcm037-eth"))
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
 
-/*
- * This structure defines static mappings for the pcm037 board.
- */
-static struct map_desc pcm037_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
+#ifdef CONFIG_I2C_IMX
+	i2c_register_board_info(1, pcm037_i2c_devices,
+			ARRAY_SIZE(pcm037_i2c_devices));
 
-/*
- * Set up static virtual mappings.
- */
-void __init pcm037_map_io(void)
-{
-	mxc_map_io();
-	iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc));
+	mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
+#endif
+	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
 }
 
 static void __init pcm037_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer pcm037_timer = {
@@ -194,7 +255,7 @@ MACHINE_START(PCM037, "Phytec Phycore pc
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = pcm037_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &pcm037_timer,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/qong.c linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/qong.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-mx3/qong.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-mx3/qong.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,286 @@
+/*
+ *  Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@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
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.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/board-qong.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include "devices.h"
+
+/* FPGA defines */
+#define QONG_FPGA_VERSION(major, minor, rev)	\
+	(((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
+
+#define QONG_FPGA_BASEADDR 		CS1_BASE_ADDR
+#define QONG_FPGA_PERIPH_SIZE 		(1 << 24)
+
+#define QONG_FPGA_CTRL_BASEADDR		QONG_FPGA_BASEADDR
+#define QONG_FPGA_CTRL_SIZE 		0x10
+/* FPGA control registers */
+#define QONG_FPGA_CTRL_VERSION		0x00
+
+#define QONG_DNET_ID		1
+#define QONG_DNET_BASEADDR	\
+	(QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
+#define QONG_DNET_SIZE 		0x00001000
+
+#define QONG_FPGA_IRQ		IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
+
+/*
+ * This file contains the board-specific initialization routines.
+ */
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
+			"uart-0");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+
+static struct resource dnet_resources[] = {
+	[0] = {
+		.name	= "dnet-memory",
+		.start	= QONG_DNET_BASEADDR,
+		.end	= QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= QONG_FPGA_IRQ,
+		.end	= QONG_FPGA_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dnet_device = {
+	.name			= "dnet",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(dnet_resources),
+	.resource		= dnet_resources,
+};
+
+static int __init qong_init_dnet(void)
+{
+	int ret;
+
+	ret = platform_device_register(&dnet_device);
+	return ret;
+}
+
+/* MTD NOR flash */
+
+static struct physmap_flash_data qong_flash_data = {
+	.width = 2,
+};
+
+static struct resource qong_flash_resource = {
+	.start = CS0_BASE_ADDR,
+	.end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &qong_flash_data,
+		},
+	.resource = &qong_flash_resource,
+	.num_resources = 1,
+};
+
+static void qong_init_nor_mtd(void)
+{
+	(void)platform_device_register(&qong_nor_mtd_device);
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
+	else
+		writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int qong_nand_device_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+}
+
+static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	if (chip >= 0)
+		gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+	else
+		gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
+}
+
+static struct platform_nand_data qong_nand_data = {
+	.chip = {
+		.chip_delay		= 20,
+		.options		= 0,
+	},
+	.ctrl = {
+		.cmd_ctrl 		= qong_nand_cmd_ctrl,
+		.dev_ready		= qong_nand_device_ready,
+		.select_chip		= qong_nand_select_chip,
+	}
+};
+
+static struct resource qong_nand_resource = {
+	.start  	= CS3_BASE_ADDR,
+	.end    	= CS3_BASE_ADDR + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nand_device = {
+	.name		= "gen_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &qong_nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &qong_nand_resource,
+};
+
+static void __init qong_init_nand_mtd(void)
+{
+	/* init CS */
+	__raw_writel(0x00004f00, CSCR_U(3));
+	__raw_writel(0x20013b31, CSCR_L(3));
+	__raw_writel(0x00020800, CSCR_A(3));
+	mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
+
+	/* enable pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
+		gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+
+	/* ready/busy pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+
+	/* write protect pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
+
+	platform_device_register(&qong_nand_device);
+}
+
+static void __init qong_init_fpga(void)
+{
+	void __iomem *regs;
+	u32 fpga_ver;
+
+	regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
+	if (!regs) {
+		printk(KERN_ERR "%s: failed to map registers, aborting.\n",
+				__func__);
+		return;
+	}
+
+	fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
+	iounmap(regs);
+	printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
+			(fpga_ver & 0xF000) >> 12,
+			(fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
+	if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
+		printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
+				"devices won't be registered!\n");
+		return;
+	}
+
+	/* register FPGA-based devices */
+	qong_init_nand_mtd();
+	qong_init_dnet();
+}
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_init_imx_uart();
+	qong_init_nor_mtd();
+	qong_init_fpga();
+}
+
+static void __init qong_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer qong_timer = {
+	.init	= qong_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_QONG data structure.
+ */
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+	/* Maintainer: DENX Software Engineering GmbH */
+	.phys_io        = AIPS1_BASE_ADDR,
+	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mxc_map_io,
+	.init_irq       = mxc_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &qong_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-netx/include/mach/netx-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-netx/include/mach/netx-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-netx/include/mach/netx-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-netx/include/mach/netx-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@
 #define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
 #define NETX_PA_VIC      (NETX_IO_PHYS + NETX_OFS_VIC)
 
-/* virual addresses */
+/* virtual addresses */
 #define NETX_VA_SYSTEM   (NETX_IO_VIRT + NETX_OFS_SYSTEM)
 #define NETX_VA_MEMCR    (NETX_IO_VIRT + NETX_OFS_MEMCR)
 #define NETX_VA_DPMAS    (NETX_IO_VIRT + NETX_OFS_DPMAS)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-netx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-netx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-netx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-netx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
 	       NETX_SYSTEM_RES_CR);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-netx/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-netx/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-netx/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-netx/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,7 @@ static struct irqaction netx_timer_irq =
 	.handler	= netx_timer_interrupt,
 };
 
-cycle_t netx_get_cycles(void)
+cycle_t netx_get_cycles(struct clocksource *cs)
 {
 	return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 #ifdef CONFIG_PROCESSOR_NS9360
 	if (processor_is_ns9360())
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,7 +63,6 @@ static struct irq_chip ns9xxx_chip = {
 #else
 static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned int cpu = smp_processor_id();
 	struct irqaction *action;
 	irqreturn_t action_ret;
 
@@ -72,7 +71,7 @@ static void handle_prio_irq(unsigned int
 	BUG_ON(desc->status & IRQ_INPROGRESS);
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-	kstat_cpu(cpu).irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	action = desc->action;
 	if (unlikely(!action || (desc->status & IRQ_DISABLED)))
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/time-ns9360.c linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/time-ns9360.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-ns9xxx/time-ns9360.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-ns9xxx/time-ns9360.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
 #define TIMER_CLOCKEVENT 1
 static u32 latch;
 
-static cycle_t ns9360_clocksource_read(void)
+static cycle_t ns9360_clocksource_read(struct clocksource *cs)
 {
 	return __raw_readl(SYS_TR(TIMER_CLOCKSOURCE));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-ams-delta.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-ams-delta.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-ams-delta.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-ams-delta.c	2009-06-09 23:05:27.000000000 -0400
@@ -175,7 +175,6 @@ static struct omap_usb_config ams_delta_
 static struct omap_board_config_kernel ams_delta_config[] = {
 	{ OMAP_TAG_LCD,		&ams_delta_lcd_config },
 	{ OMAP_TAG_UART,	&ams_delta_uart_config },
-	{ OMAP_TAG_USB,		&ams_delta_usb_config },
 };
 
 static struct resource ams_delta_kp_resources[] = {
@@ -232,6 +231,7 @@ static void __init ams_delta_init(void)
 	/* Clear latch2 (NAND, LCD, modem enable) */
 	ams_delta_latch2_write(~0, 0);
 
+	omap_usb_init(&ams_delta_usb_config);
 	platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-fsample.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-fsample.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-fsample.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-fsample.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,39 @@
 #include <mach/keypad.h>
 #include <mach/common.h>
 #include <mach/board.h>
-#include <mach/board-fsample.h>
+
+/* fsample is pretty close to p2-sample */
+
+#define fsample_cpld_read(reg) __raw_readb(reg)
+#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
+
+#define FSAMPLE_CPLD_BASE    0xE8100000
+#define FSAMPLE_CPLD_SIZE    SZ_4K
+#define FSAMPLE_CPLD_START   0x05080000
+
+#define FSAMPLE_CPLD_REG_A   (FSAMPLE_CPLD_BASE + 0x00)
+#define FSAMPLE_CPLD_SWITCH  (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_UART    (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_REG_B   (FSAMPLE_CPLD_BASE + 0x04)
+#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
+#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
+
+#define FSAMPLE_CPLD_BIT_BT_RESET         0
+#define FSAMPLE_CPLD_BIT_LCD_RESET        1
+#define FSAMPLE_CPLD_BIT_CAM_PWDN         2
+#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE   3
+#define FSAMPLE_CPLD_BIT_SD_MMC_EN        4
+#define FSAMPLE_CPLD_BIT_aGPS_PWREN       5
+#define FSAMPLE_CPLD_BIT_BACKLIGHT        6
+#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET    7
+#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N    8
+#define FSAMPLE_CPLD_BIT_OTG_RESET        9
+
+#define fsample_cpld_set(bit) \
+    fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
+
+#define fsample_cpld_clear(bit) \
+    fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
 
 static int fsample_keymap[] = {
 	KEY(0,0,KEY_UP),
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-generic.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-generic.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,7 +62,6 @@ static struct omap_uart_config generic_u
 };
 
 static struct omap_board_config_kernel generic_config[] __initdata = {
-	{ OMAP_TAG_USB,		NULL },
 	{ OMAP_TAG_UART,	&generic_uart_config },
 };
 
@@ -70,12 +69,12 @@ static void __init omap_generic_init(voi
 {
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap15xx()) {
-		generic_config[0].data = &generic1510_usb_config;
+		omap_usb_init(&generic1510_usb_config);
 	}
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
 	if (!cpu_is_omap1510()) {
-		generic_config[0].data = &generic1610_usb_config;
+		omap_usb_init(&generic1610_usb_config);
 	}
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,11 @@
 #include <mach/keypad.h>
 #include <mach/common.h>
 
+#include "board-h2.h"
+
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define OMAP1610_ETHR_START		0x04000300
+
 static int h2_keymap[] = {
 	KEY(0, 0, KEY_LEFT),
 	KEY(0, 1, KEY_RIGHT),
@@ -364,7 +369,6 @@ static struct omap_lcd_config h2_lcd_con
 };
 
 static struct omap_board_config_kernel h2_config[] __initdata = {
-	{ OMAP_TAG_USB,		&h2_usb_config },
 	{ OMAP_TAG_UART,	&h2_uart_config },
 	{ OMAP_TAG_LCD,		&h2_lcd_config },
 };
@@ -413,6 +417,7 @@ static void __init h2_init(void)
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, h2_i2c_board_info,
 			      ARRAY_SIZE(h2_i2c_board_info));
+	omap_usb_init(&h2_usb_config);
 	h2_mmc_init();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-omap1/board-h2.h
+ *
+ * Hardware definitions for TI OMAP1610 H2 board.
+ *
+ * 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_OMAP_H2_H
+#define __ASM_ARCH_OMAP_H2_H
+
+#define H2_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+#	define H2_TPS_GPIO_MMC_PWR_EN	(H2_TPS_GPIO_BASE + 3)
+
+extern void h2_mmc_init(void);
+
+#endif /*  __ASM_ARCH_OMAP_H2_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2-mmc.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2-mmc.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h2-mmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h2-mmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,24 +19,20 @@
 #include <mach/mmc.h>
 #include <mach/gpio.h>
 
+#include "board-h2.h"
+
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
 static int mmc_set_power(struct device *dev, int slot, int power_on,
 				int vdd)
 {
-	if (power_on)
-		gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
-	else
-		gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
-
+	gpio_set_value(H2_TPS_GPIO_MMC_PWR_EN, power_on);
 	return 0;
 }
 
 static int mmc_late_init(struct device *dev)
 {
-	int ret;
-
-	ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+	int ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
 	if (ret < 0)
 		return ret;
 
@@ -45,7 +41,7 @@ static int mmc_late_init(struct device *
 	return ret;
 }
 
-static void mmc_shutdown(struct device *dev)
+static void mmc_cleanup(struct device *dev)
 {
 	gpio_free(H2_TPS_GPIO_MMC_PWR_EN);
 }
@@ -58,7 +54,7 @@ static void mmc_shutdown(struct device *
 static struct omap_mmc_platform_data mmc1_data = {
 	.nr_slots                       = 1,
 	.init				= mmc_late_init,
-	.shutdown			= mmc_shutdown,
+	.cleanup			= mmc_cleanup,
 	.dma_mask			= 0xffffffff,
 	.slots[0]       = {
 		.set_power              = mmc_set_power,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,17 +39,20 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpioexpander.h>
 #include <mach/irqs.h>
 #include <mach/mux.h>
 #include <mach/tc.h>
 #include <mach/nand.h>
-#include <mach/irda.h>
 #include <mach/usb.h>
 #include <mach/keypad.h>
 #include <mach/dma.h>
 #include <mach/common.h>
 
+#include "board-h3.h"
+
+/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
+#define OMAP1710_ETHR_START		0x04000300
+
 #define H3_TS_GPIO	48
 
 static int h3_keymap[] = {
@@ -271,104 +274,6 @@ static struct platform_device h3_kp_devi
 	.resource	= h3_kp_resources,
 };
 
-
-/* Select between the IrDA and aGPS module
- */
-static int h3_select_irda(struct device *dev, int state)
-{
-	unsigned char expa;
-	int err = 0;
-
-	if ((err = read_gpio_expa(&expa, 0x26))) {
-		printk(KERN_ERR "Error reading from I/O EXPANDER \n");
-		return err;
-	}
-
-	/* 'P6' enable/disable IRDA_TX and IRDA_RX */
-	if (state & IR_SEL) { /* IrDA */
-		if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
-			printk(KERN_ERR "Error writing to I/O EXPANDER \n");
-			return err;
-		}
-	} else {
-		if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
-			printk(KERN_ERR "Error writing to I/O EXPANDER \n");
-			return err;
-		}
-	}
-	return err;
-}
-
-static void set_trans_mode(struct work_struct *work)
-{
-	struct omap_irda_config *irda_config =
-		container_of(work, struct omap_irda_config, gpio_expa.work);
-	int mode = irda_config->mode;
-	unsigned char expa;
-	int err = 0;
-
-	if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
-		printk(KERN_ERR "Error reading from I/O expander\n");
-	}
-
-	expa &= ~0x03;
-
-	if (mode & IR_SIRMODE) {
-		expa |= 0x01;
-	} else { /* MIR/FIR */
-		expa |= 0x03;
-	}
-
-	if ((err = write_gpio_expa(expa, 0x27)) != 0) {
-		printk(KERN_ERR "Error writing to I/O expander\n");
-	}
-}
-
-static int h3_transceiver_mode(struct device *dev, int mode)
-{
-	struct omap_irda_config *irda_config = dev->platform_data;
-
-	irda_config->mode = mode;
-	cancel_delayed_work(&irda_config->gpio_expa);
-	PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode);
-	schedule_delayed_work(&irda_config->gpio_expa, 0);
-
-	return 0;
-}
-
-static struct omap_irda_config h3_irda_data = {
-	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
-	.transceiver_mode	= h3_transceiver_mode,
-	.select_irda	 	= h3_select_irda,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource h3_irda_resources[] = {
-	[0] = {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 irda_dmamask = 0xffffffff;
-
-static struct platform_device h3_irda_device = {
-	.name		= "omapirda",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &h3_irda_data,
-		.dma_mask	= &irda_dmamask,
-	},
-	.num_resources	= ARRAY_SIZE(h3_irda_resources),
-	.resource	= h3_irda_resources,
-};
-
 static struct platform_device h3_lcd_device = {
 	.name		= "lcd_h3",
 	.id		= -1,
@@ -390,7 +295,6 @@ static struct platform_device *devices[]
 	&nand_device,
         &smc91x_device,
 	&intlat_device,
-	&h3_irda_device,
 	&h3_kp_device,
 	&h3_lcd_device,
 };
@@ -418,7 +322,6 @@ static struct omap_lcd_config h3_lcd_con
 };
 
 static struct omap_board_config_kernel h3_config[] __initdata = {
-	{ OMAP_TAG_USB,		&h3_usb_config },
 	{ OMAP_TAG_UART,	&h3_uart_config },
 	{ OMAP_TAG_LCD,		&h3_lcd_config },
 };
@@ -472,6 +375,7 @@ static void __init h3_init(void)
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, h3_i2c_board_info,
 			      ARRAY_SIZE(h3_i2c_board_info));
+	omap_usb_init(&h3_usb_config);
 	h3_mmc_init();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-omap1/board-h3.h
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2004 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 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_H3_H
+#define __ASM_ARCH_OMAP_H3_H
+
+#define H3_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+#	define H3_TPS_GPIO_MMC_PWR_EN	(H3_TPS_GPIO_BASE + 4)
+
+extern void h3_mmc_init(void);
+
+#endif /*  __ASM_ARCH_OMAP_H3_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3-mmc.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3-mmc.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-h3-mmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-h3-mmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,16 +19,14 @@
 #include <mach/mmc.h>
 #include <mach/gpio.h>
 
+#include "board-h3.h"
+
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
 static int mmc_set_power(struct device *dev, int slot, int power_on,
 				int vdd)
 {
-	if (power_on)
-		gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
-	else
-		gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
-
+	gpio_set_value(H3_TPS_GPIO_MMC_PWR_EN, power_on);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-innovator.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-innovator.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-innovator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-innovator.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,9 @@
 #include <mach/common.h>
 #include <mach/mmc.h>
 
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define INNOVATOR1610_ETHR_START	0x04000300
+
 static int innovator_keymap[] = {
 	KEY(0, 0, KEY_F1),
 	KEY(0, 3, KEY_DOWN),
@@ -370,7 +373,6 @@ static struct omap_uart_config innovator
 };
 
 static struct omap_board_config_kernel innovator_config[] = {
-	{ OMAP_TAG_USB,         NULL },
 	{ OMAP_TAG_LCD,		NULL },
 	{ OMAP_TAG_UART,	&innovator_uart_config },
 };
@@ -392,13 +394,13 @@ static void __init innovator_init(void)
 
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
-		innovator_config[0].data = &innovator1510_usb_config;
+		omap_usb_init(&innovator1510_usb_config);
 		innovator_config[1].data = &innovator1510_lcd_config;
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP16XX
 	if (cpu_is_omap1610()) {
-		innovator_config[0].data = &h2_usb_config;
+		omap_usb_init(&h2_usb_config);
 		innovator_config[1].data = &innovator1610_lcd_config;
 	}
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-nokia770.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-nokia770.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-nokia770.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-nokia770.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,11 +181,7 @@ static struct omap_usb_config nokia770_u
 static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
 				int vdd)
 {
-	if (power_on)
-		gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
-	else
-		gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
-
+	gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on);
 	return 0;
 }
 
@@ -233,10 +229,6 @@ static inline void nokia770_mmc_init(voi
 }
 #endif
 
-static struct omap_board_config_kernel nokia770_config[] __initdata = {
-	{ OMAP_TAG_USB,		NULL },
-};
-
 #if	defined(CONFIG_OMAP_DSP)
 /*
  * audio power control
@@ -371,19 +363,16 @@ static __init int omap_dsp_init(void)
 
 static void __init omap_nokia770_init(void)
 {
-	nokia770_config[0].data = &nokia770_usb_config;
-
 	platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
 	spi_register_board_info(nokia770_spi_board_info,
 				ARRAY_SIZE(nokia770_spi_board_info));
-	omap_board_config = nokia770_config;
-	omap_board_config_size = ARRAY_SIZE(nokia770_config);
 	omap_gpio_init();
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, NULL, 0);
 	omap_dsp_init();
 	ads7846_dev_init();
 	mipid_dev_init();
+	omap_usb_init(&nokia770_usb_config);
 	nokia770_mmc_init();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-osk.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-osk.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-osk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-osk.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,20 @@
 #include <mach/tc.h>
 #include <mach/common.h>
 
+/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
+#define OMAP_OSK_ETHR_START		0x04800300
+
+/* TPS65010 has four GPIOs.  nPG and LED2 can be treated like GPIOs with
+ * alternate pin configurations for hardware-controlled blinking.
+ */
+#define OSK_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+#	define OSK_TPS_GPIO_USB_PWR_EN	(OSK_TPS_GPIO_BASE + 0)
+#	define OSK_TPS_GPIO_LED_D3	(OSK_TPS_GPIO_BASE + 1)
+#	define OSK_TPS_GPIO_LAN_RESET	(OSK_TPS_GPIO_BASE + 2)
+#	define OSK_TPS_GPIO_DSP_PWR_EN	(OSK_TPS_GPIO_BASE + 3)
+#	define OSK_TPS_GPIO_LED_D9	(OSK_TPS_GPIO_BASE + 4)
+#	define OSK_TPS_GPIO_LED_D2	(OSK_TPS_GPIO_BASE + 5)
+
 static struct mtd_partition osk_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -290,7 +304,6 @@ static struct omap_lcd_config osk_lcd_co
 #endif
 
 static struct omap_board_config_kernel osk_config[] __initdata = {
-	{ OMAP_TAG_USB,           &osk_usb_config },
 	{ OMAP_TAG_UART,		&osk_uart_config },
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 	{ OMAP_TAG_LCD,			&osk_lcd_config },
@@ -541,6 +554,8 @@ static void __init osk_init(void)
 	l |= (3 << 1);
 	omap_writel(l, USB_TRANSCEIVER_CTRL);
 
+	omap_usb_init(&osk_usb_config);
+
 	/* irq for tps65010 chip */
 	/* bootloader effectively does:  omap_cfg_reg(U19_1610_MPUIO1); */
 	if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmte.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmte.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmte.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmte.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,21 @@
 #include <mach/keypad.h>
 #include <mach/common.h>
 
+#define PALMTE_USBDETECT_GPIO	0
+#define PALMTE_USB_OR_DC_GPIO	1
+#define PALMTE_TSC_GPIO		4
+#define PALMTE_PINTDAV_GPIO	6
+#define PALMTE_MMC_WP_GPIO	8
+#define PALMTE_MMC_POWER_GPIO	9
+#define PALMTE_HDQ_GPIO		11
+#define PALMTE_HEADPHONES_GPIO	14
+#define PALMTE_SPEAKER_GPIO	15
+#define PALMTE_DC_GPIO		OMAP_MPUIO(2)
+#define PALMTE_MMC_SWITCH_GPIO	OMAP_MPUIO(4)
+#define PALMTE_MMC1_GPIO	OMAP_MPUIO(6)
+#define PALMTE_MMC2_GPIO	OMAP_MPUIO(7)
+#define PALMTE_MMC3_GPIO	OMAP_MPUIO(11)
+
 static void __init omap_palmte_init_irq(void)
 {
 	omap1_init_common_hw();
@@ -286,7 +301,6 @@ static void palmte_get_power_status(stru
 #endif
 
 static struct omap_board_config_kernel palmte_config[] __initdata = {
-	{ OMAP_TAG_USB,		&palmte_usb_config },
 	{ OMAP_TAG_LCD,		&palmte_lcd_config },
 	{ OMAP_TAG_UART,	&palmte_uart_config },
 };
@@ -341,6 +355,7 @@ static void __init omap_palmte_init(void
 	spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
 	palmte_misc_gpio_setup();
 	omap_serial_init();
+	omap_usb_init(&palmte_usb_config);
 	omap_register_i2c_bus(1, 100, NULL, 0);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmtt.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmtt.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmtt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmtt.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,13 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
+#define PALMTT_USBDETECT_GPIO	0
+#define PALMTT_CABLE_GPIO	1
+#define PALMTT_LED_GPIO		3
+#define PALMTT_PENIRQ_GPIO	6
+#define PALMTT_MMC_WP_GPIO	8
+#define PALMTT_HDQ_GPIO		11
+
 static int palmtt_keymap[] = {
 	KEY(0, 0, KEY_ESC),
 	KEY(0, 1, KEY_SPACE),
@@ -272,7 +279,6 @@ static struct omap_uart_config palmtt_ua
 };
 
 static struct omap_board_config_kernel palmtt_config[] __initdata = {
-	{ OMAP_TAG_USB,		&palmtt_usb_config	},
 	{ OMAP_TAG_LCD,		&palmtt_lcd_config	},
 	{ OMAP_TAG_UART,	&palmtt_uart_config	},
 };
@@ -297,6 +303,7 @@ static void __init omap_palmtt_init(void
 
 	spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
 	omap_serial_init();
+	omap_usb_init(&palmtt_usb_config);
 	omap_register_i2c_bus(1, 100, NULL, 0);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmz71.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmz71.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-palmz71.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-palmz71.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,16 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
+#define PALMZ71_USBDETECT_GPIO	0
+#define PALMZ71_PENIRQ_GPIO	6
+#define PALMZ71_MMC_WP_GPIO	8
+#define PALMZ71_HDQ_GPIO 	11
+
+#define PALMZ71_HOTSYNC_GPIO	OMAP_MPUIO(1)
+#define PALMZ71_CABLE_GPIO	OMAP_MPUIO(2)
+#define PALMZ71_SLIDER_GPIO	OMAP_MPUIO(3)
+#define PALMZ71_MMC_IN_GPIO	OMAP_MPUIO(4)
+
 static void __init
 omap_palmz71_init_irq(void)
 {
@@ -239,7 +249,6 @@ static struct omap_uart_config palmz71_u
 };
 
 static struct omap_board_config_kernel palmz71_config[] __initdata = {
-	{OMAP_TAG_USB,	&palmz71_usb_config},
 	{OMAP_TAG_LCD,	&palmz71_lcd_config},
 	{OMAP_TAG_UART,	&palmz71_uart_config},
 };
@@ -313,6 +322,7 @@ omap_palmz71_init(void)
 
 	spi_register_board_info(palmz71_boardinfo,
 				ARRAY_SIZE(palmz71_boardinfo));
+	omap_usb_init(&palmz71_usb_config);
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, NULL, 0);
 	palmz71_gpio_setup(0);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-sx1.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-sx1.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-sx1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-sx1.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,7 @@
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/keypad.h>
+#include <mach/board-sx1.h>
 
 /* Write to I2C device */
 int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
@@ -373,7 +374,6 @@ static struct omap_uart_config sx1_uart_
 };
 
 static struct omap_board_config_kernel sx1_config[] __initdata = {
-	{ OMAP_TAG_USB,	&sx1_usb_config },
 	{ OMAP_TAG_LCD,	&sx1_lcd_config },
 	{ OMAP_TAG_UART,	&sx1_uart_config },
 };
@@ -388,6 +388,7 @@ static void __init omap_sx1_init(void)
 	omap_board_config_size = ARRAY_SIZE(sx1_config);
 	omap_serial_init();
 	omap_register_i2c_bus(1, 100, NULL, 0);
+	omap_usb_init(&sx1_usb_config);
 	sx1_mmc_init();
 
 	/* turn on USB power */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-sx1-mmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 #include <mach/hardware.h>
 #include <mach/mmc.h>
 #include <mach/gpio.h>
+#include <mach/board-sx1.h>
 
 #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-voiceblue.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-voiceblue.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/board-voiceblue.c	2009-06-09 23:05:27.000000000 -0400
@@ -145,7 +145,6 @@ static struct omap_uart_config voiceblue
 };
 
 static struct omap_board_config_kernel voiceblue_config[] = {
-	{ OMAP_TAG_USB,  &voiceblue_usb_config },
 	{ OMAP_TAG_UART, &voiceblue_uart_config },
 };
 
@@ -185,6 +184,7 @@ static void __init voiceblue_init(void)
 	omap_board_config = voiceblue_config;
 	omap_board_config_size = ARRAY_SIZE(voiceblue_config);
 	omap_serial_init();
+	omap_usb_init(&voiceblue_usb_config);
 	omap_register_i2c_bus(1, 100, NULL, 0);
 
 	/* There is a good chance board is going up, so enable power LED
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,41 +20,161 @@
 #include <linux/io.h>
 
 #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 "clock.h"
 
+static int clk_omap1_dummy_enable(struct clk *clk)
+{
+	return 0;
+}
+
+static void clk_omap1_dummy_disable(struct clk *clk)
+{
+}
+
+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),
+};
+
+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 void omap1_watchdog_recalc(struct clk * clk)
+static unsigned long omap1_watchdog_recalc(struct clk *clk)
 {
-	clk->rate = clk->parent->rate / 14;
+	return clk->parent->rate / 14;
 }
 
-static void omap1_uart_recalc(struct clk * clk)
+static unsigned long omap1_uart_recalc(struct clk *clk)
 {
-	unsigned int val = omap_readl(clk->enable_reg);
-	if (val & clk->enable_bit)
-		clk->rate = 48000000;
-	else
-		clk->rate = 12000000;
+	unsigned int val = __raw_readl(clk->enable_reg);
+	return val & clk->enable_bit ? 48000000 : 12000000;
 }
 
-static void omap1_sossi_recalc(struct clk *clk)
+static unsigned long omap1_sossi_recalc(struct clk *clk)
 {
 	u32 div = omap_readl(MOD_CONF_CTRL_1);
 
 	div = (div >> 17) & 0x7;
 	div++;
-	clk->rate = clk->parent->rate / div;
+
+	return clk->parent->rate / div;
 }
 
 static int omap1_clk_enable_dsp_domain(struct clk *clk)
@@ -78,6 +198,11 @@ static void omap1_clk_disable_dsp_domain
 	}
 }
 
+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;
@@ -105,6 +230,11 @@ static void omap1_clk_disable_uart_funct
 	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;
@@ -197,9 +327,6 @@ static int calc_dsor_exp(struct clk *clk
 	struct clk * parent;
 	unsigned  dsor_exp;
 
-	if (unlikely(!(clk->flags & RATE_CKCTL)))
-		return -EINVAL;
-
 	parent = clk->parent;
 	if (unlikely(parent == NULL))
 		return -EIO;
@@ -215,22 +342,15 @@ static int calc_dsor_exp(struct clk *clk
 	return dsor_exp;
 }
 
-static void omap1_ckctl_recalc(struct clk * clk)
+static unsigned long omap1_ckctl_recalc(struct clk *clk)
 {
-	int dsor;
-
 	/* Calculate divisor encoded as 2-bit exponent */
-	dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
-
-	if (unlikely(clk->rate == clk->parent->rate / dsor))
-		return; /* No change, quick exit */
-	clk->rate = clk->parent->rate / dsor;
+	int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
 
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
+	return clk->parent->rate / dsor;
 }
 
-static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
+static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
 {
 	int dsor;
 
@@ -245,12 +365,7 @@ static void omap1_ckctl_recalc_dsp_domai
 	dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
 	omap1_clk_disable(&api_ck.clk);
 
-	if (unlikely(clk->rate == clk->parent->rate / dsor))
-		return; /* No change, quick exit */
-	clk->rate = clk->parent->rate / dsor;
-
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
+	return clk->parent->rate / dsor;
 }
 
 /* MPU virtual clock functions */
@@ -289,35 +404,57 @@ static int omap1_select_table_rate(struc
 		omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
 
 	ck_dpll1.rate = ptr->pll_rate;
-	propagate_rate(&ck_dpll1);
 	return 0;
 }
 
 static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
 {
-	int  ret = -EINVAL;
-	int  dsor_exp;
-	__u16  regval;
+	int dsor_exp;
+	u16 regval;
 
-	if (clk->flags & RATE_CKCTL) {
-		dsor_exp = calc_dsor_exp(clk, rate);
-		if (dsor_exp > 3)
-			dsor_exp = -EINVAL;
-		if (dsor_exp < 0)
-			return dsor_exp;
+	dsor_exp = calc_dsor_exp(clk, rate);
+	if (dsor_exp > 3)
+		dsor_exp = -EINVAL;
+	if (dsor_exp < 0)
+		return dsor_exp;
 
-		regval = __raw_readw(DSP_CKCTL);
-		regval &= ~(3 << clk->rate_offset);
-		regval |= dsor_exp << clk->rate_offset;
-		__raw_writew(regval, DSP_CKCTL);
-		clk->rate = clk->parent->rate / (1 << dsor_exp);
-		ret = 0;
-	}
+	regval = __raw_readw(DSP_CKCTL);
+	regval &= ~(3 << clk->rate_offset);
+	regval |= dsor_exp << clk->rate_offset;
+	__raw_writew(regval, DSP_CKCTL);
+	clk->rate = clk->parent->rate / (1 << dsor_exp);
 
-	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
-		propagate_rate(clk);
+	return 0;
+}
 
-	return ret;
+static 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)
+		return dsor_exp;
+	if (dsor_exp > 3)
+		dsor_exp = 3;
+	return clk->parent->rate / (1 << dsor_exp);
+}
+
+static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+{
+	int dsor_exp;
+	u16 regval;
+
+	dsor_exp = calc_dsor_exp(clk, rate);
+	if (dsor_exp > 3)
+		dsor_exp = -EINVAL;
+	if (dsor_exp < 0)
+		return dsor_exp;
+
+	regval = omap_readw(ARM_CKCTL);
+	regval &= ~(3 << clk->rate_offset);
+	regval |= dsor_exp << clk->rate_offset;
+	regval = verify_ckctl_value(regval);
+	omap_writew(regval, ARM_CKCTL);
+	clk->rate = clk->parent->rate / (1 << dsor_exp);
+	return 0;
 }
 
 static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
@@ -372,14 +509,14 @@ static int omap1_set_uart_rate(struct cl
 {
 	unsigned int val;
 
-	val = omap_readl(clk->enable_reg);
+	val = __raw_readl(clk->enable_reg);
 	if (rate == 12000000)
 		val &= ~(1 << clk->enable_bit);
 	else if (rate == 48000000)
 		val |= (1 << clk->enable_bit);
 	else
 		return -EINVAL;
-	omap_writel(val, clk->enable_reg);
+	__raw_writel(val, clk->enable_reg);
 	clk->rate = rate;
 
 	return 0;
@@ -398,8 +535,8 @@ static int omap1_set_ext_clk_rate(struct
 	else
 		ratio_bits = (dsor - 2) << 2;
 
-	ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
-	omap_writew(ratio_bits, clk->enable_reg);
+	ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
+	__raw_writew(ratio_bits, clk->enable_reg);
 
 	return 0;
 }
@@ -423,8 +560,6 @@ static int omap1_set_sossi_rate(struct c
 	omap_writel(l, MOD_CONF_CTRL_1);
 
 	clk->rate = p_rate / (div + 1);
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
 
 	return 0;
 }
@@ -440,8 +575,8 @@ static void omap1_init_ext_clk(struct cl
 	__u16 ratio_bits;
 
 	/* Determine current rate and ensure clock is based on 96MHz APLL */
-	ratio_bits = omap_readw(clk->enable_reg) & ~1;
-	omap_writew(ratio_bits, clk->enable_reg);
+	ratio_bits = __raw_readw(clk->enable_reg) & ~1;
+	__raw_writew(ratio_bits, clk->enable_reg);
 
 	ratio_bits = (ratio_bits & 0xfc) >> 2;
 	if (ratio_bits > 6)
@@ -455,34 +590,35 @@ static void omap1_init_ext_clk(struct cl
 static int omap1_clk_enable(struct clk *clk)
 {
 	int ret = 0;
+
 	if (clk->usecount++ == 0) {
-		if (likely(clk->parent)) {
+		if (clk->parent) {
 			ret = omap1_clk_enable(clk->parent);
-
-			if (unlikely(ret != 0)) {
-				clk->usecount--;
-				return ret;
-			}
+			if (ret)
+				goto err;
 
 			if (clk->flags & CLOCK_NO_IDLE_PARENT)
 				omap1_clk_deny_idle(clk->parent);
 		}
 
-		ret = clk->enable(clk);
-
-		if (unlikely(ret != 0) && clk->parent) {
-			omap1_clk_disable(clk->parent);
-			clk->usecount--;
+		ret = clk->ops->enable(clk);
+		if (ret) {
+			if (clk->parent)
+				omap1_clk_disable(clk->parent);
+			goto err;
 		}
 	}
+	return ret;
 
+err:
+	clk->usecount--;
 	return ret;
 }
 
 static void omap1_clk_disable(struct clk *clk)
 {
 	if (clk->usecount > 0 && !(--clk->usecount)) {
-		clk->disable(clk);
+		clk->ops->disable(clk);
 		if (likely(clk->parent)) {
 			omap1_clk_disable(clk->parent);
 			if (clk->flags & CLOCK_NO_IDLE_PARENT)
@@ -496,9 +632,6 @@ static int omap1_clk_enable_generic(stru
 	__u16 regval16;
 	__u32 regval32;
 
-	if (clk->flags & ALWAYS_ENABLED)
-		return 0;
-
 	if (unlikely(clk->enable_reg == NULL)) {
 		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
 		       clk->name);
@@ -506,25 +639,13 @@ static int omap1_clk_enable_generic(stru
 	}
 
 	if (clk->flags & ENABLE_REG_32BIT) {
-		if (clk->flags & VIRTUAL_IO_ADDRESS) {
-			regval32 = __raw_readl(clk->enable_reg);
-			regval32 |= (1 << clk->enable_bit);
-			__raw_writel(regval32, clk->enable_reg);
-		} else {
-			regval32 = omap_readl(clk->enable_reg);
-			regval32 |= (1 << clk->enable_bit);
-			omap_writel(regval32, clk->enable_reg);
-		}
+		regval32 = __raw_readl(clk->enable_reg);
+		regval32 |= (1 << clk->enable_bit);
+		__raw_writel(regval32, clk->enable_reg);
 	} else {
-		if (clk->flags & VIRTUAL_IO_ADDRESS) {
-			regval16 = __raw_readw(clk->enable_reg);
-			regval16 |= (1 << clk->enable_bit);
-			__raw_writew(regval16, clk->enable_reg);
-		} else {
-			regval16 = omap_readw(clk->enable_reg);
-			regval16 |= (1 << clk->enable_bit);
-			omap_writew(regval16, clk->enable_reg);
-		}
+		regval16 = __raw_readw(clk->enable_reg);
+		regval16 |= (1 << clk->enable_bit);
+		__raw_writew(regval16, clk->enable_reg);
 	}
 
 	return 0;
@@ -539,44 +660,26 @@ static void omap1_clk_disable_generic(st
 		return;
 
 	if (clk->flags & ENABLE_REG_32BIT) {
-		if (clk->flags & VIRTUAL_IO_ADDRESS) {
-			regval32 = __raw_readl(clk->enable_reg);
-			regval32 &= ~(1 << clk->enable_bit);
-			__raw_writel(regval32, clk->enable_reg);
-		} else {
-			regval32 = omap_readl(clk->enable_reg);
-			regval32 &= ~(1 << clk->enable_bit);
-			omap_writel(regval32, clk->enable_reg);
-		}
+		regval32 = __raw_readl(clk->enable_reg);
+		regval32 &= ~(1 << clk->enable_bit);
+		__raw_writel(regval32, clk->enable_reg);
 	} else {
-		if (clk->flags & VIRTUAL_IO_ADDRESS) {
-			regval16 = __raw_readw(clk->enable_reg);
-			regval16 &= ~(1 << clk->enable_bit);
-			__raw_writew(regval16, clk->enable_reg);
-		} else {
-			regval16 = omap_readw(clk->enable_reg);
-			regval16 &= ~(1 << clk->enable_bit);
-			omap_writew(regval16, clk->enable_reg);
-		}
+		regval16 = __raw_readw(clk->enable_reg);
+		regval16 &= ~(1 << clk->enable_bit);
+		__raw_writew(regval16, clk->enable_reg);
 	}
 }
 
+static 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)
 {
-	int dsor_exp;
-
 	if (clk->flags & RATE_FIXED)
 		return clk->rate;
 
-	if (clk->flags & RATE_CKCTL) {
-		dsor_exp = calc_dsor_exp(clk, rate);
-		if (dsor_exp < 0)
-			return dsor_exp;
-		if (dsor_exp > 3)
-			dsor_exp = 3;
-		return clk->parent->rate / (1 << dsor_exp);
-	}
-
 	if (clk->round_rate != NULL)
 		return clk->round_rate(clk, rate);
 
@@ -586,30 +689,9 @@ static long omap1_clk_round_rate(struct
 static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	int  ret = -EINVAL;
-	int  dsor_exp;
-	__u16  regval;
 
 	if (clk->set_rate)
 		ret = clk->set_rate(clk, rate);
-	else if (clk->flags & RATE_CKCTL) {
-		dsor_exp = calc_dsor_exp(clk, rate);
-		if (dsor_exp > 3)
-			dsor_exp = -EINVAL;
-		if (dsor_exp < 0)
-			return dsor_exp;
-
-		regval = omap_readw(ARM_CKCTL);
-		regval &= ~(3 << clk->rate_offset);
-		regval |= dsor_exp << clk->rate_offset;
-		regval = verify_ckctl_value(regval);
-		omap_writew(regval, ARM_CKCTL);
-		clk->rate = clk->parent->rate / (1 << dsor_exp);
-		ret = 0;
-	}
-
-	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
-		propagate_rate(clk);
-
 	return ret;
 }
 
@@ -632,17 +714,10 @@ static void __init omap1_clk_disable_unu
 	}
 
 	/* Is the clock already disabled? */
-	if (clk->flags & ENABLE_REG_32BIT) {
-		if (clk->flags & VIRTUAL_IO_ADDRESS)
-			regval32 = __raw_readl(clk->enable_reg);
-			else
-				regval32 = omap_readl(clk->enable_reg);
-	} else {
-		if (clk->flags & VIRTUAL_IO_ADDRESS)
-			regval32 = __raw_readw(clk->enable_reg);
-		else
-			regval32 = omap_readw(clk->enable_reg);
-	}
+	if (clk->flags & ENABLE_REG_32BIT)
+		regval32 = __raw_readl(clk->enable_reg);
+	else
+		regval32 = __raw_readw(clk->enable_reg);
 
 	if ((regval32 & (1 << clk->enable_bit)) == 0)
 		return;
@@ -659,7 +734,7 @@ static void __init omap1_clk_disable_unu
 	}
 
 	printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
-	clk->disable(clk);
+	clk->ops->disable(clk);
 	printk(" done\n");
 }
 
@@ -677,10 +752,10 @@ static struct clk_functions omap1_clk_fu
 
 int __init omap1_clk_init(void)
 {
-	struct clk ** clkp;
+	struct omap_clk *c;
 	const struct omap_clock_config *info;
 	int crystal_type = 0; /* Default 12 MHz */
-	u32 reg;
+	u32 reg, cpu_mask;
 
 #ifdef CONFIG_DEBUG_LL
 	/* Resets some clocks that may be left on from bootloader,
@@ -700,27 +775,24 @@ int __init omap1_clk_init(void)
 	/* By default all idlect1 clocks are allowed to idle */
 	arm_idlect1_mask = ~0;
 
-	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
-		if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
-			clk_register(*clkp);
-			continue;
-		}
-
-		if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
-			clk_register(*clkp);
-			continue;
-		}
+	for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+		clk_init_one(c->lk.clk);
 
-		if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
-			clk_register(*clkp);
-			continue;
-		}
+	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;
 
-		if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
-			clk_register(*clkp);
-			continue;
+	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) {
@@ -769,7 +841,6 @@ int __init omap1_clk_init(void)
 			}
 		}
 	}
-	propagate_rate(&ck_dpll1);
 #else
 	/* Find the highest supported frequency and enable it */
 	if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
@@ -778,9 +849,9 @@ int __init omap1_clk_init(void)
 		omap_writew(0x2290, DPLL_CTL);
 		omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
 		ck_dpll1.rate = 60000000;
-		propagate_rate(&ck_dpll1);
 	}
 #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): "
@@ -832,4 +903,3 @@ int __init omap1_clk_init(void)
 
 	return 0;
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,27 +13,22 @@
 #ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
 #define __ARCH_ARM_MACH_OMAP1_CLOCK_H
 
-static int omap1_clk_enable_generic(struct clk * clk);
-static void omap1_clk_disable_generic(struct clk * clk);
-static void omap1_ckctl_recalc(struct clk * clk);
-static void omap1_watchdog_recalc(struct clk * clk);
+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 void omap1_sossi_recalc(struct clk *clk);
-static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
-static int omap1_clk_enable_dsp_domain(struct clk * clk);
+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 void omap1_clk_disable_dsp_domain(struct clk * clk);
 static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
-static void omap1_uart_recalc(struct clk * clk);
-static int omap1_clk_enable_uart_functional(struct clk * clk);
-static void omap1_clk_disable_uart_functional(struct clk * clk);
+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);
-static int omap1_clk_enable(struct clk *clk);
-static void omap1_clk_disable(struct clk *clk);
+
+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);
 
 struct mpu_rate {
 	unsigned long		rate;
@@ -152,101 +147,84 @@ static struct mpu_rate rate_table[] = {
 
 static struct clk ck_ref = {
 	.name		= "ck_ref",
+	.ops		= &clkops_null,
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk ck_dpll1 = {
 	.name		= "ck_dpll1",
+	.ops		= &clkops_null,
 	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk ck_dpll1out = {
 	.clk = {
 		.name		= "ck_dpll1out",
+		.ops		= &clkops_generic,
 		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL |
-				  ENABLE_REG_32BIT | RATE_PROPAGATES,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_CKOUT_ARM,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 12,
 };
 
 static struct clk sossi_ck = {
 	.name		= "ck_sossi",
+	.ops		= &clkops_generic,
 	.parent		= &ck_dpll1out.clk,
-	.flags		= CLOCK_IN_OMAP16XX | CLOCK_NO_IDLE_PARENT |
-			  ENABLE_REG_32BIT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_1,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk arm_ck = {
 	.name		= "arm_ck",
+	.ops		= &clkops_null,
 	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
-			  ALWAYS_ENABLED,
 	.rate_offset	= CKCTL_ARMDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.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_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP310 | RATE_CKCTL |
-				  CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_PERCK,
 		.rate_offset	= CKCTL_PERDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
+		.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,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
-	.enable_reg	= (void __iomem *)ARM_IDLECT2,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 	.enable_bit	= EN_GPIOCK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk armxor_ck = {
 	.clk = {
 		.name		= "armxor_ck",
+		.ops		= &clkops_generic,
 		.parent		= &ck_ref,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_XORPCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 1,
 };
@@ -254,14 +232,12 @@ static struct arm_idlect1_clk armxor_ck
 static struct arm_idlect1_clk armtim_ck = {
 	.clk = {
 		.name		= "armtim_ck",
+		.ops		= &clkops_generic,
 		.parent		= &ck_ref,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_TIMCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 9,
 };
@@ -269,201 +245,166 @@ static struct arm_idlect1_clk armtim_ck
 static struct arm_idlect1_clk armwdt_ck = {
 	.clk = {
 		.name		= "armwdt_ck",
+		.ops		= &clkops_generic,
 		.parent		= &ck_ref,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_WDTCK,
 		.recalc		= &omap1_watchdog_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 0,
 };
 
 static struct clk arminth_ck16xx = {
 	.name		= "arminth_ck",
+	.ops		= &clkops_null,
 	.parent		= &arm_ck,
-	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.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.
 	 */
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dsp_ck = {
 	.name		= "dsp_ck",
+	.ops		= &clkops_generic,
 	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL,
-	.enable_reg	= (void __iomem *)ARM_CKCTL,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_CKCTL),
 	.enable_bit	= EN_DSPCK,
 	.rate_offset	= CKCTL_DSPDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.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,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL | ALWAYS_ENABLED,
 	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.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,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL | VIRTUAL_IO_ADDRESS,
 	.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,
-	.enable		= &omap1_clk_enable_dsp_domain,
-	.disable	= &omap1_clk_disable_dsp_domain,
 };
 
 static struct clk dspxor_ck = {
 	.name		= "dspxor_ck",
+	.ops		= &clkops_dspck,
 	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  VIRTUAL_IO_ADDRESS,
 	.enable_reg	= DSP_IDLECT2,
 	.enable_bit	= EN_XORPCK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_dsp_domain,
-	.disable	= &omap1_clk_disable_dsp_domain,
 };
 
 static struct clk dsptim_ck = {
 	.name		= "dsptim_ck",
+	.ops		= &clkops_dspck,
 	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  VIRTUAL_IO_ADDRESS,
 	.enable_reg	= DSP_IDLECT2,
 	.enable_bit	= EN_DSPTIMCK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_dsp_domain,
-	.disable	= &omap1_clk_disable_dsp_domain,
 };
 
 /* 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_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
-				  RATE_CKCTL | RATE_PROPAGATES |
-				  ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
+		.flags		= CLOCK_IDLE_CONTROL,
 		.rate_offset	= CKCTL_TCDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
+		.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,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-			  ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 	/* Note: On 1510 the frequency follows TC_CK
 	 *
 	 * 16xx version is in MPU clocks.
 	 */
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tipb_ck = {
 	/* No-idle controlled by "tc_ck" */
 	.name		= "tipb_ck",
+	.ops		= &clkops_null,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-			  ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk l3_ocpi_ck = {
 	/* No-idle controlled by "tc_ck" */
 	.name		= "l3_ocpi_ck",
+	.ops		= &clkops_generic,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
 	.enable_bit	= EN_OCPI_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tc1_ck = {
 	.name		= "tc1_ck",
+	.ops		= &clkops_generic,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
 	.enable_bit	= EN_TC1_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk tc2_ck = {
 	.name		= "tc2_ck",
+	.ops		= &clkops_generic,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
 	.enable_bit	= EN_TC2_CK,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dma_ck = {
 	/* No-idle controlled by "tc_ck" */
 	.name		= "dma_ck",
+	.ops		= &clkops_null,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk dma_lcdfree_ck = {
 	.name		= "dma_lcdfree_ck",
+	.ops		= &clkops_null,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct arm_idlect1_clk api_ck = {
 	.clk = {
 		.name		= "api_ck",
+		.ops		= &clkops_generic,
 		.parent		= &tc_ck.clk,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_APICK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 8,
 };
@@ -471,276 +412,238 @@ static struct arm_idlect1_clk api_ck = {
 static struct arm_idlect1_clk lb_ck = {
 	.clk = {
 		.name		= "lb_ck",
+		.ops		= &clkops_generic,
 		.parent		= &tc_ck.clk,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-				  CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_LBCK,
 		.recalc		= &followparent_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
 	},
 	.idlect_shift	= 4,
 };
 
 static struct clk rhea1_ck = {
 	.name		= "rhea1_ck",
+	.ops		= &clkops_null,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk rhea2_ck = {
 	.name		= "rhea2_ck",
+	.ops		= &clkops_null,
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk lcd_ck_16xx = {
 	.name		= "lcd_ck",
+	.ops		= &clkops_generic,
 	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
-	.enable_reg	= (void __iomem *)ARM_IDLECT2,
+	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 	.enable_bit	= EN_LCDCK,
 	.rate_offset	= CKCTL_LCDDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.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_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-				  RATE_CKCTL | CLOCK_IDLE_CONTROL,
-		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.flags		= CLOCK_IDLE_CONTROL,
+		.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT2),
 		.enable_bit	= EN_LCDCK,
 		.rate_offset	= CKCTL_LCDDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
-		.enable		= &omap1_clk_enable_generic,
-		.disable	= &omap1_clk_disable_generic,
+		.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		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
-			  CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP16XX | RATE_FIXED |
-				  ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-		.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
+				  CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 		.enable_bit	= 29,
-		.enable		= &omap1_clk_enable_uart_functional,
-		.disable	= &omap1_clk_disable_uart_functional,
 	},
 	.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		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
-			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk uart3_1510 = {
 	.name		= "uart3_ck",
+	.ops		= &clkops_null,
 	/* Direct from ULPD, no real parent */
 	.parent		= &armper_ck.clk,
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
-			  CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP16XX | RATE_FIXED |
-				  ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-		.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+		.flags		= RATE_FIXED | ENABLE_REG_32BIT |
+				  CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 		.enable_bit	= 31,
-		.enable		= &omap1_clk_enable_uart_functional,
-		.disable	= &omap1_clk_disable_uart_functional,
 	},
 	.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		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= (void __iomem *)ULPD_CLOCK_CTRL,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
 	.enable_bit	= USB_MCLK_EN_BIT,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= USB_HOST_HHC_UHOST_EN,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
 	.enable_bit	= 8 /* UHOST_EN */,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk usb_dc_ck = {
 	.name		= "usb_dc_ck",
+	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED,
-	.enable_reg	= (void __iomem *)SOFT_REQ_REG,
+	.flags		= RATE_FIXED,
+	.enable_reg	= OMAP1_IO_ADDRESS(SOFT_REQ_REG),
 	.enable_bit	= 4,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk mclk_1510 = {
 	.name		= "mclk",
+	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
- 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
- 	.enable_reg	= (void __iomem *)SOFT_REQ_REG,
- 	.enable_bit	= 6,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.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. */
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= (void __iomem *)COM_CLK_DIV_CTRL_SEL,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk bclk_1510 = {
 	.name		= "bclk",
+	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk bclk_16xx = {
 	.name		= "bclk",
+	.ops		= &clkops_generic,
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
-			  CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= 23,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 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		= CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
-	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.flags		= RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
 	.enable_bit	= 20,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk virtual_ck_mpu = {
 	.name		= "mpu",
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
+	.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,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 /* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
@@ -748,78 +651,19 @@ remains active during MPU idle whenever
 static struct clk i2c_fck = {
 	.name		= "i2c_fck",
 	.id		= 1,
-	.flags		= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
-			  ALWAYS_ENABLED,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_NO_IDLE_PARENT,
 	.parent		= &armxor_ck.clk,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
 };
 
 static struct clk i2c_ick = {
 	.name		= "i2c_ick",
 	.id		= 1,
-	.flags		= CLOCK_IN_OMAP16XX |
-			  VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
-			  ALWAYS_ENABLED,
+	.ops		= &clkops_null,
+	.flags		= CLOCK_NO_IDLE_PARENT,
 	.parent		= &armper_ck.clk,
 	.recalc		= &followparent_recalc,
-	.enable		= &omap1_clk_enable_generic,
-	.disable	= &omap1_clk_disable_generic,
-};
-
-static struct clk * onchip_clks[] = {
-	/* non-ULPD clocks */
-	&ck_ref,
-	&ck_dpll1,
-	/* CK_GEN1 clocks */
-	&ck_dpll1out.clk,
-	&sossi_ck,
-	&arm_ck,
-	&armper_ck.clk,
-	&arm_gpio_ck,
-	&armxor_ck.clk,
-	&armtim_ck.clk,
-	&armwdt_ck.clk,
-	&arminth_ck1510,  &arminth_ck16xx,
-	/* CK_GEN2 clocks */
-	&dsp_ck,
-	&dspmmu_ck,
-	&dspper_ck,
-	&dspxor_ck,
-	&dsptim_ck,
-	/* CK_GEN3 clocks */
-	&tc_ck.clk,
-	&tipb_ck,
-	&l3_ocpi_ck,
-	&tc1_ck,
-	&tc2_ck,
-	&dma_ck,
-	&dma_lcdfree_ck,
-	&api_ck.clk,
-	&lb_ck.clk,
-	&rhea1_ck,
-	&rhea2_ck,
-	&lcd_ck_16xx,
-	&lcd_ck_1510.clk,
-	/* ULPD clocks */
-	&uart1_1510,
-	&uart1_16xx.clk,
-	&uart2_ck,
-	&uart3_1510,
-	&uart3_16xx.clk,
-	&usb_clko,
-	&usb_hhc_ck1510, &usb_hhc_ck16xx,
-	&usb_dc_ck,
-	&mclk_1510,  &mclk_16xx,
-	&bclk_1510,  &bclk_16xx,
-	&mmc1_ck,
-	&mmc2_ck,
-	/* Virtual clocks */
-	&virtual_ck_mpu,
-	&i2c_fck,
-	&i2c_ick,
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ static struct resource mbox_resources[]
 };
 
 static struct platform_device mbox_device = {
-	.name		= "mailbox",
+	.name		= "omap1-mailbox",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(mbox_resources),
 	.resource	= mbox_resources,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/id.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/id.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/id.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/id.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@ static struct omap_id omap_ids[] __initd
 	{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
 	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
 	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320500, .type = 0x08500000},
 	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
 	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
 	{ .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
@@ -77,7 +78,7 @@ static u16 __init omap_get_jtag_id(void)
 	prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
 	omap_id = omap_readl(OMAP32_ID_1);
 
-	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730/850 */
 	if (((prod_id >> 20) == 0) || (prod_id == omap_id))
 		prod_id = 0;
 	else
@@ -178,6 +179,7 @@ void __init omap_check_revision(void)
 
 	switch (cpu_type) {
 	case 0x07:
+	case 0x08:
 		omap_revision |= 0x07;
 		break;
 	case 0x03:
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/io.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/io.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/io.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,22 @@ static struct map_desc omap730_io_desc[]
 };
 #endif
 
+#ifdef CONFIG_ARCH_OMAP850
+static struct map_desc omap850_io_desc[] __initdata = {
+	{
+		.virtual	= OMAP850_DSP_BASE,
+		.pfn		= __phys_to_pfn(OMAP850_DSP_START),
+		.length		= OMAP850_DSP_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= OMAP850_DSPREG_BASE,
+		.pfn		= __phys_to_pfn(OMAP850_DSPREG_START),
+		.length		= OMAP850_DSPREG_SIZE,
+		.type		= MT_DEVICE
+	}
+};
+#endif
+
 #ifdef CONFIG_ARCH_OMAP15XX
 static struct map_desc omap1510_io_desc[] __initdata = {
 	{
@@ -109,6 +125,13 @@ void __init omap1_map_common_io(void)
 		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));
+	}
+#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.29-gnu1/arch/arm/mach-omap1/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -145,6 +145,14 @@ static struct omap_irq_bank omap730_irq_
 };
 #endif
 
+#ifdef CONFIG_ARCH_OMAP850
+static struct omap_irq_bank omap850_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_OMAP15XX
 static struct omap_irq_bank omap1510_irq_banks[] = {
 	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3febfff },
@@ -184,6 +192,12 @@ void __init omap_init_irq(void)
 		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);
+	}
+#endif
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 		irq_banks = omap1510_irq_banks;
@@ -214,9 +228,8 @@ void __init omap_init_irq(void)
 	irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
 
 	/* Enable interrupts in global mask */
-	if (cpu_is_omap730()) {
+	if (cpu_is_omap7xx())
 		irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
-	}
 
 	/* Install the interrupt handlers for each bank */
 	for (i = 0; i < irq_bank_count; i++) {
@@ -236,6 +249,8 @@ void __init omap_init_irq(void)
 
 	if (cpu_is_omap730())
 		omap_unmask_irq(INT_730_IH2_IRQ);
+	else if (cpu_is_omap850())
+		omap_unmask_irq(INT_850_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.29-gnu1/arch/arm/mach-omap1/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,11 @@ config ARCH_OMAP730
 	select CPU_ARM926T
 	select ARCH_OMAP_OTG
 
+config ARCH_OMAP850
+	depends on ARCH_OMAP1
+	bool "OMAP850 Based System"
+	select CPU_ARM926T
+
 config ARCH_OMAP15XX
 	depends on ARCH_OMAP1
 	default y
@@ -46,6 +51,12 @@ config MACH_OMAP_H3
 	  TI OMAP 1710 H3 board support. Say Y here if you have such
 	  a board.
 
+config MACH_OMAP_HTCWIZARD
+	bool "HTC Wizard"
+	depends on ARCH_OMAP850
+	help
+	  HTC Wizard smartphone support (AKA QTEK 9100, ...)
+
 config MACH_OMAP_OSK
 	bool "TI OSK Support"
 	depends on ARCH_OMAP1 && ARCH_OMAP16XX
@@ -98,7 +109,7 @@ config MACH_OMAP_PALMZ71
 	help
 	 Support for the Palm Zire71 PDA. To boot the kernel,
 	 you'll need a PalmOS compatible bootloader; check out
-	 http://hackndev.com/palm/z71 for more informations.
+	 http://hackndev.com/palm/z71 for more information.
 	 Say Y here if you have such a PDA, say N otherwise.
 
 config MACH_OMAP_PALMTT
@@ -163,7 +174,7 @@ config OMAP_ARM_216MHZ
 
 config OMAP_ARM_195MHZ
 	bool "OMAP ARM 195 MHz CPU"
-	depends on ARCH_OMAP1 && ARCH_OMAP730
+	depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
 	help
           Enable 195MHz clock for OMAP CPU. If unsure, say N.
 
@@ -175,13 +186,13 @@ config OMAP_ARM_192MHZ
 
 config OMAP_ARM_182MHZ
 	bool "OMAP ARM 182 MHz CPU"
-	depends on ARCH_OMAP1 && ARCH_OMAP730
+	depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
 	help
           Enable 182MHz clock for OMAP CPU. If unsure, say N.
 
 config OMAP_ARM_168MHZ
 	bool "OMAP ARM 168 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
 	help
           Enable 168MHz clock for OMAP CPU. If unsure, say N.
 
@@ -193,20 +204,20 @@ config OMAP_ARM_150MHZ
 
 config OMAP_ARM_120MHZ
 	bool "OMAP ARM 120 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
 	help
           Enable 120MHz clock for OMAP CPU. If unsure, say N.
 
 config OMAP_ARM_60MHZ
 	bool "OMAP ARM 60 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
         default y
 	help
           Enable 60MHz clock for OMAP CPU. If unsure, say Y.
 
 config OMAP_ARM_30MHZ
 	bool "OMAP ARM 30 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
 	help
           Enable 30MHz clock for OMAP CPU. If unsure, say N.
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mailbox.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mailbox.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mailbox.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mailbox.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Mailbox reservation modules for DSP
  *
- * Copyright (C) 2006 Nokia Corporation
+ * Copyright (C) 2006-2009 Nokia Corporation
  * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -27,7 +27,7 @@
 #define MAILBOX_DSP2ARM1_Flag		0x1c
 #define MAILBOX_DSP2ARM2_Flag		0x20
 
-unsigned long mbox_base;
+static void __iomem *mbox_base;
 
 struct omap_mbox1_fifo {
 	unsigned long cmd;
@@ -40,14 +40,14 @@ struct omap_mbox1_priv {
 	struct omap_mbox1_fifo rx_fifo;
 };
 
-static inline int mbox_read_reg(unsigned int reg)
+static inline int mbox_read_reg(size_t ofs)
 {
-	return __raw_readw(mbox_base + reg);
+	return __raw_readw(mbox_base + ofs);
 }
 
-static inline void mbox_write_reg(unsigned int val, unsigned int reg)
+static inline void mbox_write_reg(u32 val, size_t ofs)
 {
-	__raw_writew(val, mbox_base + reg);
+	__raw_writew(val, mbox_base + ofs);
 }
 
 /* msg */
@@ -143,7 +143,7 @@ struct omap_mbox mbox_dsp_info = {
 };
 EXPORT_SYMBOL(mbox_dsp_info);
 
-static int __init omap1_mbox_probe(struct platform_device *pdev)
+static int __devinit omap1_mbox_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	int ret = 0;
@@ -170,12 +170,10 @@ static int __init omap1_mbox_probe(struc
 	}
 	mbox_dsp_info.irq = res->start;
 
-	ret = omap_mbox_register(&mbox_dsp_info);
-
-	return ret;
+	return omap_mbox_register(&pdev->dev, &mbox_dsp_info);
 }
 
-static int omap1_mbox_remove(struct platform_device *pdev)
+static int __devexit omap1_mbox_remove(struct platform_device *pdev)
 {
 	omap_mbox_unregister(&mbox_dsp_info);
 
@@ -184,9 +182,9 @@ static int omap1_mbox_remove(struct plat
 
 static struct platform_driver omap1_mbox_driver = {
 	.probe	= omap1_mbox_probe,
-	.remove	= omap1_mbox_remove,
+	.remove	= __devexit_p(omap1_mbox_remove),
 	.driver	= {
-		.name	= "mailbox",
+		.name	= "omap1-mailbox",
 	},
 };
 
@@ -203,4 +201,7 @@ static void __exit omap1_mbox_exit(void)
 module_init(omap1_mbox_init);
 module_exit(omap1_mbox_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU" <Hiroshi.DOYU@nokia.com>);
+MODULE_ALIAS("platform:omap1-mailbox");
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mcbsp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mcbsp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mcbsp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mcbsp.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,9 +28,9 @@
 #define DPS_RSTCT2_PER_EN	(1 << 0)
 #define DSP_RSTCT2_WD_PER_EN	(1 << 1)
 
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
-#endif
+static int dsp_use;
+static struct clk *api_clk;
+static struct clk *dsp_clk;
 
 static void omap1_mcbsp_request(unsigned int id)
 {
@@ -39,20 +39,40 @@ static void omap1_mcbsp_request(unsigned
 	 * are DSP public peripherals.
 	 */
 	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
-		omap_dsp_request_mem();
-		/*
-		 * DSP external peripheral reset
-		 * FIXME: This should be moved to dsp code
-		 */
-		__raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
-				DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+		if (dsp_use++ == 0) {
+			api_clk = clk_get(NULL, "api_ck");
+			dsp_clk = clk_get(NULL, "dsp_ck");
+			if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
+				clk_enable(api_clk);
+				clk_enable(dsp_clk);
+
+				omap_dsp_request_mem();
+				/*
+				 * DSP external peripheral reset
+				 * FIXME: This should be moved to dsp code
+				 */
+				__raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
+						DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+			}
+		}
 	}
 }
 
 static void omap1_mcbsp_free(unsigned int id)
 {
-	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
-		omap_dsp_release_mem();
+	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
+		if (--dsp_use == 0) {
+			omap_dsp_release_mem();
+			if (!IS_ERR(api_clk)) {
+				clk_disable(api_clk);
+				clk_put(api_clk);
+			}
+			if (!IS_ERR(dsp_clk)) {
+				clk_disable(dsp_clk);
+				clk_put(dsp_clk);
+			}
+		}
+	}
 }
 
 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
@@ -94,8 +114,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_McBSP1RX,
 		.tx_irq		= INT_McBSP1TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 3,
 	},
 	{
 		.phys_base	= OMAP1510_MCBSP2_BASE,
@@ -112,8 +130,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_McBSP3RX,
 		.tx_irq		= INT_McBSP3TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 3,
 	},
 };
 #define OMAP15XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap15xx_mcbsp_pdata)
@@ -131,8 +147,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_McBSP1RX,
 		.tx_irq		= INT_McBSP1TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 3,
 	},
 	{
 		.phys_base	= OMAP1610_MCBSP2_BASE,
@@ -149,8 +163,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_McBSP3RX,
 		.tx_irq		= INT_McBSP3TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 3,
 	},
 };
 #define OMAP16XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap16xx_mcbsp_pdata)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mux.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mux.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/mux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/mux.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,6 +58,25 @@ MUX_CFG_730("W17_730_USB_VBUSI",   2,
 #define OMAP730_PINS_SZ		0
 #endif	/* CONFIG_ARCH_OMAP730 */
 
+#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)
+
+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)
+};
+#endif
+
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
 static struct pin_config __initdata_or_module omap1xxx_pins[] = {
 /*
@@ -419,6 +438,11 @@ 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
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/serial.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/serial.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -121,6 +121,13 @@ void __init omap_serial_init(void)
 		serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
 	}
 
+	if (cpu_is_omap850()) {
+		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;
+	}
+
 	if (cpu_is_omap15xx()) {
 		serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
 		serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap1/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap1/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,7 +198,7 @@ static struct irqaction omap_mpu_timer2_
 	.handler	= omap_mpu_timer2_interrupt,
 };
 
-static cycle_t mpu_read(void)
+static cycle_t mpu_read(struct clocksource *cs)
 {
 	return ~omap_mpu_timer_read(1);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-2430sdp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-2430sdp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-2430sdp.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,12 +35,16 @@
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
+#include <mach/usb.h>
 
 #include "mmc-twl4030.h"
 
+#define SDP2430_CS0_BASE	0x04000000
 #define	SDP2430_FLASH_CS	0
 #define	SDP2430_SMC91X_CS	5
 
+#define SDP2430_ETHR_GPIO_IRQ		149
+
 static struct mtd_partition sdp2430_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -102,8 +106,8 @@ static struct resource sdp2430_smc91x_re
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
-		.end	= OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+		.start	= OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
+		.end	= OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
 		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
@@ -170,13 +174,13 @@ static inline void __init sdp2430_init_s
 	sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f;
 	udelay(100);
 
-	if (gpio_request(OMAP24XX_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
+	if (gpio_request(SDP2430_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
 		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
-			OMAP24XX_ETHR_GPIO_IRQ);
+			SDP2430_ETHR_GPIO_IRQ);
 		gpmc_cs_free(eth_cs);
 		goto out;
 	}
-	gpio_direction_input(OMAP24XX_ETHR_GPIO_IRQ);
+	gpio_direction_input(SDP2430_ETHR_GPIO_IRQ);
 
 out:
 	clk_disable(gpmc_fck);
@@ -185,7 +189,7 @@ out:
 
 static void __init omap_2430sdp_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
 	sdp2430_init_smc91x();
@@ -251,6 +255,7 @@ static void __init omap_2430sdp_init(voi
 	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
 	omap_serial_init();
 	twl4030_mmc_init(mmc);
+	usb_musb_init();
 }
 
 static void __init omap_2430sdp_map_io(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-3430sdp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-3430sdp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-3430sdp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-3430sdp.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,542 @@
+/*
+ * linux/arch/arm/mach-omap2/board-3430sdp.c
+ *
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can 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/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.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 <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 <mach/control.h>
+#include <mach/keypad.h>
+
+#include "mmc-twl4030.h"
+
+#define CONFIG_DISABLE_HFCLK 1
+
+#define SDP3430_ETHR_GPIO_IRQ_SDPV1	29
+#define SDP3430_ETHR_GPIO_IRQ_SDPV2	6
+#define SDP3430_SMC91X_CS		3
+
+#define SDP3430_TS_GPIO_IRQ_SDPV1	3
+#define SDP3430_TS_GPIO_IRQ_SDPV2	2
+
+#define ENABLE_VAUX3_DEDICATED	0x03
+#define ENABLE_VAUX3_DEV_GRP	0x20
+
+#define TWL4030_MSECURE_GPIO 22
+
+static struct resource sdp3430_smc91x_resources[] = {
+	[0] = {
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 0,
+		.end	= 0,
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct platform_device sdp3430_smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(sdp3430_smc91x_resources),
+	.resource	= sdp3430_smc91x_resources,
+};
+
+static int sdp3430_keymap[] = {
+	KEY(0, 0, KEY_LEFT),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_A),
+	KEY(0, 3, KEY_B),
+	KEY(0, 4, KEY_C),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_UP),
+	KEY(1, 2, KEY_E),
+	KEY(1, 3, KEY_F),
+	KEY(1, 4, KEY_G),
+	KEY(2, 0, KEY_ENTER),
+	KEY(2, 1, KEY_I),
+	KEY(2, 2, KEY_J),
+	KEY(2, 3, KEY_K),
+	KEY(2, 4, KEY_3),
+	KEY(3, 0, KEY_M),
+	KEY(3, 1, KEY_N),
+	KEY(3, 2, KEY_O),
+	KEY(3, 3, KEY_P),
+	KEY(3, 4, KEY_Q),
+	KEY(4, 0, KEY_R),
+	KEY(4, 1, KEY_4),
+	KEY(4, 2, KEY_T),
+	KEY(4, 3, KEY_U),
+	KEY(4, 4, KEY_D),
+	KEY(5, 0, KEY_V),
+	KEY(5, 1, KEY_W),
+	KEY(5, 2, KEY_L),
+	KEY(5, 3, KEY_S),
+	KEY(5, 4, KEY_H),
+	0
+};
+
+static struct twl4030_keypad_data sdp3430_kp_data = {
+	.rows		= 5,
+	.cols		= 6,
+	.keymap		= sdp3430_keymap,
+	.keymapsize	= ARRAY_SIZE(sdp3430_keymap),
+	.rep		= 1,
+};
+
+static int ts_gpio;	/* Needed for ads7846_get_pendown_state */
+
+/**
+ * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
+ *
+ * @return - void. If request gpio fails then Flag KERN_ERR.
+ */
+static void ads7846_dev_init(void)
+{
+	if (gpio_request(ts_gpio, "ADS7846 pendown") < 0) {
+		printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+		return;
+	}
+
+	gpio_direction_input(ts_gpio);
+
+	omap_set_gpio_debounce(ts_gpio, 1);
+	omap_set_gpio_debounce_time(ts_gpio, 0xa);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+	return !gpio_get_value(ts_gpio);
+}
+
+static struct ads7846_platform_data tsc2046_config __initdata = {
+	.get_pendown_state	= ads7846_get_pendown_state,
+	.keep_vref_on		= 1,
+};
+
+
+static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static struct spi_board_info sdp3430_spi_board_info[] __initdata = {
+	[0] = {
+		/*
+		 * TSC2046 operates at a max freqency of 2MHz, so
+		 * operate slightly below at 1.5MHz
+		 */
+		.modalias		= "ads7846",
+		.bus_num		= 1,
+		.chip_select		= 0,
+		.max_speed_hz		= 1500000,
+		.controller_data	= &tsc2046_mcspi_config,
+		.irq			= 0,
+		.platform_data		= &tsc2046_config,
+	},
+};
+
+static struct platform_device sdp3430_lcd_device = {
+	.name		= "sdp2430_lcd",
+	.id		= -1,
+};
+
+static struct regulator_consumer_supply sdp3430_vdac_supply = {
+	.supply		= "vdac",
+	.dev		= &sdp3430_lcd_device.dev,
+};
+
+static struct regulator_consumer_supply sdp3430_vdvi_supply = {
+	.supply		= "vdvi",
+	.dev		= &sdp3430_lcd_device.dev,
+};
+
+static struct platform_device *sdp3430_devices[] __initdata = {
+	&sdp3430_smc91x_device,
+	&sdp3430_lcd_device,
+};
+
+static inline void __init sdp3430_init_smc91x(void)
+{
+	int eth_cs;
+	unsigned long cs_mem_base;
+	int eth_gpio = 0;
+
+	eth_cs = SDP3430_SMC91X_CS;
+
+	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
+		printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+		return;
+	}
+
+	sdp3430_smc91x_resources[0].start = cs_mem_base + 0x300;
+	sdp3430_smc91x_resources[0].end = cs_mem_base + 0x30f;
+	udelay(100);
+
+	if (omap_rev() > OMAP3430_REV_ES1_0)
+		eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV2;
+	else
+		eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV1;
+
+	sdp3430_smc91x_resources[1].start = gpio_to_irq(eth_gpio);
+
+	if (gpio_request(eth_gpio, "SMC91x irq") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+			eth_gpio);
+		return;
+	}
+	gpio_direction_input(eth_gpio);
+}
+
+static void __init omap_3430sdp_init_irq(void)
+{
+	omap2_init_common_hw(NULL);
+	omap_init_irq();
+	omap_gpio_init();
+	sdp3430_init_smc91x();
+}
+
+static struct omap_uart_config sdp3430_uart_config __initdata = {
+	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config sdp3430_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel sdp3430_config[] __initdata = {
+	{ OMAP_TAG_UART,	&sdp3430_uart_config },
+	{ OMAP_TAG_LCD,		&sdp3430_lcd_config },
+};
+
+static int sdp3430_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 sdp3430_bci_data = {
+	.battery_tmp_tbl	= sdp3430_batt_table,
+	.tblsize		= ARRAY_SIZE(sdp3430_batt_table),
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+	{
+		.mmc		= 1,
+		/* 8 bits (default) requires S6.3 == ON,
+		 * so the SIM card isn't used; else 4 bits.
+		 */
+		.wires		= 8,
+		.gpio_wp	= 4,
+	},
+	{
+		.mmc		= 2,
+		.wires		= 8,
+		.gpio_wp	= 7,
+	},
+	{}	/* Terminator */
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply sdp3430_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc2_supply = {
+	.supply			= "vmmc",
+};
+
+static int sdp3430_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.
+	 */
+	sdp3430_vmmc1_supply.dev = mmc[0].dev;
+	sdp3430_vsim_supply.dev = mmc[0].dev;
+	sdp3430_vmmc2_supply.dev = mmc[1].dev;
+
+	/* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
+	gpio_request(gpio + 7, "sub_lcd_en_bkl");
+	gpio_direction_output(gpio + 7, 0);
+
+	/* gpio + 15 is "sub_lcd_nRST" (output) */
+	gpio_request(gpio + 15, "sub_lcd_nRST");
+	gpio_direction_output(gpio + 15, 0);
+
+	return 0;
+}
+
+static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
+	.gpio_base	= OMAP_MAX_GPIO_LINES,
+	.irq_base	= TWL4030_GPIO_IRQ_BASE,
+	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.pulldowns	= BIT(2) | BIT(6) | BIT(8) | BIT(13)
+				| BIT(16) | BIT(17),
+	.setup		= sdp3430_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data sdp3430_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_madc_platform_data sdp3430_madc_data = {
+	.irq_line	= 1,
+};
+
+/*
+ * Apply all the fixed voltages since most versions of U-Boot
+ * don't bother with that initialization.
+ */
+
+/* VAUX1 for mainboard (irda and sub-lcd) */
+static struct regulator_init_data sdp3430_vaux1 = {
+	.constraints = {
+		.min_uV			= 2800000,
+		.max_uV			= 2800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+/* VAUX2 for camera module */
+static struct regulator_init_data sdp3430_vaux2 = {
+	.constraints = {
+		.min_uV			= 2800000,
+		.max_uV			= 2800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+/* VAUX3 for LCD board */
+static struct regulator_init_data sdp3430_vaux3 = {
+	.constraints = {
+		.min_uV			= 2800000,
+		.max_uV			= 2800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+/* VAUX4 for OMAP VDD_CSI2 (camera) */
+static struct regulator_init_data sdp3430_vaux4 = {
+	.constraints = {
+		.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,
+	},
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp3430_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	= &sdp3430_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data sdp3430_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	= &sdp3430_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data sdp3430_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	= &sdp3430_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data sdp3430_vdac = {
+	.constraints = {
+		.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_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data sdp3430_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	= &sdp3430_vdvi_supply,
+};
+
+static struct twl4030_platform_data sdp3430_twldata = {
+	.irq_base	= TWL4030_IRQ_BASE,
+	.irq_end	= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.bci		= &sdp3430_bci_data,
+	.gpio		= &sdp3430_gpio_data,
+	.madc		= &sdp3430_madc_data,
+	.keypad		= &sdp3430_kp_data,
+	.usb		= &sdp3430_usb_data,
+
+	.vaux1		= &sdp3430_vaux1,
+	.vaux2		= &sdp3430_vaux2,
+	.vaux3		= &sdp3430_vaux3,
+	.vaux4		= &sdp3430_vaux4,
+	.vmmc1		= &sdp3430_vmmc1,
+	.vmmc2		= &sdp3430_vmmc2,
+	.vsim		= &sdp3430_vsim,
+	.vdac		= &sdp3430_vdac,
+	.vpll2		= &sdp3430_vpll2,
+};
+
+static struct i2c_board_info __initdata sdp3430_i2c_boardinfo[] = {
+	{
+		I2C_BOARD_INFO("twl4030", 0x48),
+		.flags = I2C_CLIENT_WAKE,
+		.irq = INT_34XX_SYS_NIRQ,
+		.platform_data = &sdp3430_twldata,
+	},
+};
+
+static int __init omap3430_i2c_init(void)
+{
+	/* i2c1 for PMIC only */
+	omap_register_i2c_bus(1, 2600, sdp3430_i2c_boardinfo,
+			ARRAY_SIZE(sdp3430_i2c_boardinfo));
+	/* i2c2 on camera connector (for sensor control) and optional isp1301 */
+	omap_register_i2c_bus(2, 400, NULL, 0);
+	/* i2c3 on display connector (for DVI, tfp410) */
+	omap_register_i2c_bus(3, 400, NULL, 0);
+	return 0;
+}
+
+static void __init omap_3430sdp_init(void)
+{
+	omap3430_i2c_init();
+	platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
+	omap_board_config = sdp3430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	if (omap_rev() > OMAP3430_REV_ES1_0)
+		ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
+	else
+		ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV1;
+	sdp3430_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
+	spi_register_board_info(sdp3430_spi_board_info,
+				ARRAY_SIZE(sdp3430_spi_board_info));
+	ads7846_dev_init();
+	omap_serial_init();
+	usb_musb_init();
+}
+
+static void __init omap_3430sdp_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
+	/* Maintainer: Syed Khasim - Texas Instruments Inc */
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_3430sdp_map_io,
+	.init_irq	= omap_3430sdp_init_irq,
+	.init_machine	= omap_3430sdp_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-apollon.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-apollon.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-apollon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-apollon.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,7 @@
 
 #define APOLLON_FLASH_CS	0
 #define APOLLON_ETH_CS		1
+#define APOLLON_ETHR_GPIO_IRQ	74
 
 static struct mtd_partition apollon_partitions[] = {
 	{
@@ -249,7 +250,7 @@ out:
 
 static void __init omap_apollon_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
 	apollon_init_smc91x();
@@ -272,7 +273,6 @@ static struct omap_lcd_config apollon_lc
 
 static struct omap_board_config_kernel apollon_config[] = {
 	{ OMAP_TAG_UART,	&apollon_uart_config },
-	{ OMAP_TAG_USB,		&apollon_usb_config },
 	{ OMAP_TAG_LCD,		&apollon_lcd_config },
 };
 
@@ -299,6 +299,7 @@ static void __init apollon_usb_init(void
 	omap_cfg_reg(P21_242X_GPIO12);
 	gpio_request(12, "USB suspend");
 	gpio_direction_output(12, 0);
+	omap_usb_init(&apollon_usb_config);
 }
 
 static void __init omap_apollon_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-generic.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-generic.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-h4.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-h4.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-h4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-h4.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,10 +33,8 @@
 
 #include <mach/control.h>
 #include <mach/gpio.h>
-#include <mach/gpioexpander.h>
 #include <mach/mux.h>
 #include <mach/usb.h>
-#include <mach/irda.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/keypad.h>
@@ -47,6 +45,8 @@
 #define H4_FLASH_CS	0
 #define H4_SMC91X_CS	1
 
+#define H4_ETHR_GPIO_IRQ		92
+
 static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
 static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
 
@@ -136,98 +136,6 @@ static struct platform_device h4_flash_d
 	.resource	= &h4_flash_resource,
 };
 
-/* Select between the IrDA and aGPS module
- */
-static int h4_select_irda(struct device *dev, int state)
-{
-	unsigned char expa;
-	int err = 0;
-
-	if ((err = read_gpio_expa(&expa, 0x21))) {
-		printk(KERN_ERR "Error reading from I/O expander\n");
-		return err;
-	}
-
-	/* 'P6' enable/disable IRDA_TX and IRDA_RX */
-	if (state & IR_SEL) {	/* IrDa */
-		if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
-			printk(KERN_ERR "Error writing to I/O expander\n");
-			return err;
-		}
-	} else {
-		if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
-			printk(KERN_ERR "Error writing to I/O expander\n");
-			return err;
-		}
-	}
-	return err;
-}
-
-static void set_trans_mode(struct work_struct *work)
-{
-	struct omap_irda_config *irda_config =
-		container_of(work, struct omap_irda_config, gpio_expa.work);
-	int mode = irda_config->mode;
-	unsigned char expa;
-	int err = 0;
-
-	if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
-		printk(KERN_ERR "Error reading from I/O expander\n");
-	}
-
-	expa &= ~0x01;
-
-	if (!(mode & IR_SIRMODE)) { /* MIR/FIR */
-		expa |= 0x01;
-	}
-
-	if ((err = write_gpio_expa(expa, 0x20)) != 0) {
-		printk(KERN_ERR "Error writing to I/O expander\n");
-	}
-}
-
-static int h4_transceiver_mode(struct device *dev, int mode)
-{
-	struct omap_irda_config *irda_config = dev->platform_data;
-
-	irda_config->mode = mode;
-	cancel_delayed_work(&irda_config->gpio_expa);
-	PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode);
-	schedule_delayed_work(&irda_config->gpio_expa, 0);
-
-	return 0;
-}
-
-static struct omap_irda_config h4_irda_data = {
-	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
-	.transceiver_mode	= h4_transceiver_mode,
-	.select_irda	 	= h4_select_irda,
-	.rx_channel		= OMAP24XX_DMA_UART3_RX,
-	.tx_channel		= OMAP24XX_DMA_UART3_TX,
-	.dest_start		= OMAP_UART3_BASE,
-	.src_start		= OMAP_UART3_BASE,
-	.tx_trigger		= OMAP24XX_DMA_UART3_TX,
-	.rx_trigger		= OMAP24XX_DMA_UART3_RX,
-};
-
-static struct resource h4_irda_resources[] = {
-	[0] = {
-		.start	= INT_24XX_UART3_IRQ,
-		.end	= INT_24XX_UART3_IRQ,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device h4_irda_device = {
-	.name		= "omapirda",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &h4_irda_data,
-	},
-	.num_resources	= 1,
-	.resource	= h4_irda_resources,
-};
-
 static struct omap_kp_platform_data h4_kp_data = {
 	.rows		= 6,
 	.cols		= 7,
@@ -253,7 +161,6 @@ static struct platform_device h4_lcd_dev
 
 static struct platform_device *h4_devices[] __initdata = {
 	&h4_flash_device,
-	&h4_irda_device,
 	&h4_kp_device,
 	&h4_lcd_device,
 };
@@ -341,7 +248,7 @@ static inline void __init h4_init_debug(
 	udelay(100);
 
 	omap_cfg_reg(M15_24XX_GPIO92);
-	if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0)
+	if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
 		gpmc_cs_free(eth_cs);
 
 out:
@@ -363,7 +270,7 @@ static void __init h4_init_flash(void)
 
 static void __init omap_h4_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
 	h4_init_flash();
@@ -377,6 +284,39 @@ static struct omap_lcd_config h4_lcd_con
 	.ctrl_name	= "internal",
 };
 
+static struct omap_usb_config h4_usb_config __initdata = {
+#ifdef	CONFIG_MACH_OMAP2_H4_USB1
+	/* NOTE:  usb1 could also be used with 3 wire signaling */
+	.pins[1]	= 4,
+#endif
+
+#ifdef	CONFIG_MACH_OMAP_H4_OTG
+	/* S1.10 ON -- USB OTG port
+	 * usb0 switched to Mini-AB port and isp1301 transceiver;
+	 * S2.POS3 = OFF, S2.POS4 = ON ... to allow battery charging
+	 */
+	.otg		= 1,
+	.pins[0]	= 4,
+#ifdef	CONFIG_USB_GADGET_OMAP
+	/* use OTG cable, or standard A-to-MiniB */
+	.hmc_mode	= 0x14,	/* 0:dev/otg 1:host 2:disable */
+#elif	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	/* use OTG cable, or NONSTANDARD (B-to-MiniB) */
+	.hmc_mode	= 0x11,	/* 0:host 1:host 2:disable */
+#endif	/* XX */
+
+#else
+	/* S1.10 OFF -- usb "download port"
+	 * usb0 switched to Mini-B port and isp1105 transceiver;
+	 * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging
+	 */
+	.register_dev	= 1,
+	.pins[0]	= 3,
+/*	.hmc_mode	= 0x14,*/	/* 0:dev 1:host 2:disable */
+	.hmc_mode	= 0x00,		/* 0:dev|otg 1:disable 2:disable */
+#endif
+};
+
 static struct omap_board_config_kernel h4_config[] = {
 	{ OMAP_TAG_UART,	&h4_uart_config },
 	{ OMAP_TAG_LCD,		&h4_lcd_config },
@@ -428,6 +368,7 @@ static void __init omap_h4_init(void)
 	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
 	omap_board_config = h4_config;
 	omap_board_config_size = ARRAY_SIZE(h4_config);
+	omap_usb_init(&h4_usb_config);
 	omap_serial_init();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-ldp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-ldp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-ldp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-ldp.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,31 +22,35 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/board-ldp.h>
 #include <mach/mcspi.h>
 #include <mach/gpio.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpmc.h>
 
-#include <asm/io.h>
 #include <asm/delay.h>
 #include <mach/control.h>
+#include <mach/usb.h>
 
 #include "mmc-twl4030.h"
 
-#define SDP3430_SMC91X_CS	3
+#define LDP_SMSC911X_CS		1
+#define LDP_SMSC911X_GPIO	152
+#define DEBUG_BASE		0x08000000
+#define LDP_ETHR_START		DEBUG_BASE
 
-static struct resource ldp_smc911x_resources[] = {
+static struct resource ldp_smsc911x_resources[] = {
 	[0] = {
-		.start	= OMAP34XX_ETHR_START,
-		.end	= OMAP34XX_ETHR_START + SZ_4K,
+		.start	= LDP_ETHR_START,
+		.end	= LDP_ETHR_START + SZ_4K,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -56,40 +60,50 @@ static struct resource ldp_smc911x_resou
 	},
 };
 
-static struct platform_device ldp_smc911x_device = {
-	.name		= "smc911x",
+static struct smsc911x_platform_config ldp_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 ldp_smsc911x_device = {
+	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ldp_smc911x_resources),
-	.resource	= ldp_smc911x_resources,
+	.num_resources	= ARRAY_SIZE(ldp_smsc911x_resources),
+	.resource	= ldp_smsc911x_resources,
+	.dev		= {
+		.platform_data = &ldp_smsc911x_config,
+	},
 };
 
 static struct platform_device *ldp_devices[] __initdata = {
-	&ldp_smc911x_device,
+	&ldp_smsc911x_device,
 };
 
-static inline void __init ldp_init_smc911x(void)
+static inline void __init ldp_init_smsc911x(void)
 {
 	int eth_cs;
 	unsigned long cs_mem_base;
 	int eth_gpio = 0;
 
-	eth_cs = LDP_SMC911X_CS;
+	eth_cs = LDP_SMSC911X_CS;
 
 	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed to request GPMC mem for smc911x\n");
+		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
 		return;
 	}
 
-	ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
-	ldp_smc911x_resources[0].end   = cs_mem_base + 0xff;
+	ldp_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	ldp_smsc911x_resources[0].end   = cs_mem_base + 0xff;
 	udelay(100);
 
-	eth_gpio = LDP_SMC911X_GPIO;
+	eth_gpio = LDP_SMSC911X_GPIO;
 
-	ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
+	ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
 
-	if (gpio_request(eth_gpio, "smc911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+	if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
 				eth_gpio);
 		return;
 	}
@@ -98,10 +112,10 @@ static inline void __init ldp_init_smc91
 
 static void __init omap_ldp_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
-	ldp_init_smc911x();
+	ldp_init_smsc911x();
 }
 
 static struct omap_uart_config ldp_uart_config __initdata = {
@@ -162,6 +176,7 @@ static void __init omap_ldp_init(void)
 	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	omap_serial_init();
 	twl4030_mmc_init(mmc);
+	usb_musb_init();
 }
 
 static void __init omap_ldp_map_io(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-omap3beagle.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-omap3beagle.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-omap3beagle.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,8 @@
 #include <mach/gpmc.h>
 #include <mach/nand.h>
 #include <mach/mux.h>
+#include <mach/usb.h>
+#include <mach/timer-gp.h>
 
 #include "mmc-twl4030.h"
 
@@ -175,9 +177,6 @@ static int __init omap3_beagle_i2c_init(
 {
 	omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
 			ARRAY_SIZE(beagle_i2c_boardinfo));
-#ifdef CONFIG_I2C2_OMAP_BEAGLE
-	omap_register_i2c_bus(2, 400, NULL, 0);
-#endif
 	/* 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);
@@ -186,8 +185,11 @@ static int __init omap3_beagle_i2c_init(
 
 static void __init omap3_beagle_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+	omap2_gp_clockevent_set_gptimer(12);
+#endif
 	omap_gpio_init();
 }
 
@@ -316,6 +318,7 @@ static void __init omap3_beagle_init(voi
 	/* REVISIT leave DVI powered down until it's needed ... */
 	gpio_direction_output(170, true);
 
+	usb_musb_init();
 	omap3beagle_flash_init();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-omap3pandora.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-omap3pandora.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-omap3pandora.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,7 @@
 #include <mach/gpio.h>
 #include <mach/hardware.h>
 #include <mach/mcspi.h>
+#include <mach/usb.h>
 
 #include "mmc-twl4030.h"
 
@@ -53,6 +54,13 @@ static struct twl4030_hsmmc_info omap3pa
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= 127,
 		.ext_clock	= 1,
+		.transceiver	= true,
+	},
+	{
+		.mmc		= 3,
+		.wires		= 4,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
 	},
 	{}	/* Terminator */
 };
@@ -110,7 +118,7 @@ static int __init omap3pandora_i2c_init(
 
 static void __init omap3pandora_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
 }
@@ -193,6 +201,7 @@ static void __init omap3pandora_init(voi
 	spi_register_board_info(omap3pandora_spi_board_info,
 			ARRAY_SIZE(omap3pandora_spi_board_info));
 	omap3pandora_ads7846_init();
+	usb_musb_init();
 }
 
 static void __init omap3pandora_map_io(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-overo.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-overo.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-overo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-overo.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,20 +37,149 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/board-overo.h>
 #include <mach/board.h>
 #include <mach/common.h>
 #include <mach/gpio.h>
 #include <mach/gpmc.h>
 #include <mach/hardware.h>
 #include <mach/nand.h>
+#include <mach/usb.h>
 
 #include "mmc-twl4030.h"
 
+#define OVERO_GPIO_BT_XGATE	15
+#define OVERO_GPIO_W2W_NRESET	16
+#define OVERO_GPIO_BT_NRESET	164
+#define OVERO_GPIO_USBH_CPEN	168
+#define OVERO_GPIO_USBH_NRESET	183
+
 #define NAND_BLOCK_SIZE SZ_128K
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
 
+#define OVERO_SMSC911X_CS      5
+#define OVERO_SMSC911X_GPIO    176
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+#include <mach/mcspi.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.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(OVERO_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 overo_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(OVERO_GPIO_PENDOWN),
+		.platform_data		= &ads7846_config,
+	}
+};
+
+static void __init overo_ads7846_init(void)
+{
+	if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
+	    (gpio_direction_input(OVERO_GPIO_PENDOWN) == 0)) {
+		gpio_export(OVERO_GPIO_PENDOWN, 0);
+	} else {
+		printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n");
+		return;
+	}
+
+	spi_register_board_info(overo_spi_board_info,
+			ARRAY_SIZE(overo_spi_board_info));
+}
+
+#else
+static inline void __init overo_ads7846_init(void) { return; }
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct resource overo_smsc911x_resources[] = {
+	{
+		.name	= "smsc911x-memory",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config overo_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 overo_smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(overo_smsc911x_resources),
+	.resource	= &overo_smsc911x_resources,
+	.dev		= {
+		.platform_data = &overo_smsc911x_config,
+	},
+};
+
+static inline void __init overo_init_smsc911x(void)
+{
+	unsigned long cs_mem_base;
+
+	if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+		printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
+		return;
+	}
+
+	overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	overo_smsc911x_resources[0].end   = cs_mem_base + 0xff;
+
+	if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+	    (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
+		gpio_export(OVERO_SMSC911X_GPIO, 0);
+	} else {
+		printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
+		return;
+	}
+
+	overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
+	overo_smsc911x_resources[1].end	  = 0;
+
+	platform_device_register(&overo_smsc911x_device);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
 static struct mtd_partition overo_nand_partitions[] = {
 	{
 		.name           = "xloader",
@@ -174,7 +303,7 @@ static int __init overo_i2c_init(void)
 
 static void __init overo_init_irq(void)
 {
-	omap2_init_common_hw();
+	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
 }
@@ -209,6 +338,7 @@ static struct twl4030_hsmmc_info mmc[] _
 		.wires		= 4,
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
+		.transceiver	= true,
 	},
 	{}	/* Terminator */
 };
@@ -222,6 +352,9 @@ static void __init overo_init(void)
 	omap_serial_init();
 	twl4030_mmc_init(mmc);
 	overo_flash_init();
+	usb_musb_init();
+	overo_ads7846_init();
+	overo_init_smsc911x();
 
 	if ((gpio_request(OVERO_GPIO_W2W_NRESET,
 			  "OVERO_GPIO_W2W_NRESET") == 0) &&
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-rx51.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-rx51.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-rx51.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-rx51.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51.c
+ *
+ * Copyright (C) 2007, 2008 Nokia
+ *
+ * This program is free software; you can 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 <mach/hardware.h>
+#include <asm/mach-types.h>
+#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/keypad.h>
+#include <mach/dma.h>
+#include <mach/gpmc.h>
+#include <mach/usb.h>
+
+static struct omap_uart_config rx51_uart_config = {
+	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config rx51_lcd_config = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_fbmem_config rx51_fbmem0_config = {
+	.size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem1_config = {
+	.size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem2_config = {
+	.size = 752 * 1024,
+};
+
+static struct omap_board_config_kernel rx51_config[] = {
+	{ OMAP_TAG_UART,	&rx51_uart_config },
+	{ OMAP_TAG_FBMEM,	&rx51_fbmem0_config },
+	{ OMAP_TAG_FBMEM,	&rx51_fbmem1_config },
+	{ OMAP_TAG_FBMEM,	&rx51_fbmem2_config },
+	{ OMAP_TAG_LCD,		&rx51_lcd_config },
+};
+
+static void __init rx51_init_irq(void)
+{
+	omap2_init_common_hw(NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+extern void __init rx51_peripherals_init(void);
+
+static void __init rx51_init(void)
+{
+	omap_board_config = rx51_config;
+	omap_board_config_size = ARRAY_SIZE(rx51_config);
+	omap_serial_init();
+	usb_musb_init();
+	rx51_peripherals_init();
+}
+
+static void __init rx51_map_io(void)
+{
+	omap2_set_globals_343x();
+	omap2_map_common_io();
+}
+
+MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
+	/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= rx51_map_io,
+	.init_irq	= rx51_init_irq,
+	.init_machine	= rx51_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,419 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-flash.c
+ *
+ * Copyright (C) 2008-2009 Nokia
+ *
+ * This program is free software; you can 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/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.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/keypad.h>
+
+#include "mmc-twl4030.h"
+
+
+#define SMC91X_CS			1
+#define SMC91X_GPIO_IRQ			54
+#define SMC91X_GPIO_RESET		164
+#define SMC91X_GPIO_PWRDWN		86
+
+static struct resource rx51_smc91x_resources[] = {
+	[0] = {
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	},
+};
+
+static struct platform_device rx51_smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(rx51_smc91x_resources),
+	.resource	= rx51_smc91x_resources,
+};
+
+static int rx51_keymap[] = {
+	KEY(0, 0, KEY_Q),
+	KEY(0, 1, KEY_W),
+	KEY(0, 2, KEY_E),
+	KEY(0, 3, KEY_R),
+	KEY(0, 4, KEY_T),
+	KEY(0, 5, KEY_Y),
+	KEY(0, 6, KEY_U),
+	KEY(0, 7, KEY_I),
+	KEY(1, 0, KEY_O),
+	KEY(1, 1, KEY_D),
+	KEY(1, 2, KEY_DOT),
+	KEY(1, 3, KEY_V),
+	KEY(1, 4, KEY_DOWN),
+	KEY(2, 0, KEY_P),
+	KEY(2, 1, KEY_F),
+	KEY(2, 2, KEY_UP),
+	KEY(2, 3, KEY_B),
+	KEY(2, 4, KEY_RIGHT),
+	KEY(3, 0, KEY_COMMA),
+	KEY(3, 1, KEY_G),
+	KEY(3, 2, KEY_ENTER),
+	KEY(3, 3, KEY_N),
+	KEY(4, 0, KEY_BACKSPACE),
+	KEY(4, 1, KEY_H),
+	KEY(4, 3, KEY_M),
+	KEY(4, 4, KEY_LEFTCTRL),
+	KEY(5, 1, KEY_J),
+	KEY(5, 2, KEY_Z),
+	KEY(5, 3, KEY_SPACE),
+	KEY(5, 4, KEY_LEFTSHIFT),
+	KEY(6, 0, KEY_A),
+	KEY(6, 1, KEY_K),
+	KEY(6, 2, KEY_X),
+	KEY(6, 3, KEY_SPACE),
+	KEY(6, 4, KEY_FN),
+	KEY(7, 0, KEY_S),
+	KEY(7, 1, KEY_L),
+	KEY(7, 2, KEY_C),
+	KEY(7, 3, KEY_LEFT),
+	KEY(0xff, 0, KEY_F6),
+	KEY(0xff, 1, KEY_F7),
+	KEY(0xff, 2, KEY_F8),
+	KEY(0xff, 4, KEY_F9),
+	KEY(0xff, 5, KEY_F10),
+};
+
+static struct twl4030_keypad_data rx51_kp_data = {
+	.rows		= 8,
+	.cols		= 8,
+	.keymap		= rx51_keymap,
+	.keymapsize	= ARRAY_SIZE(rx51_keymap),
+	.rep		= 1,
+};
+
+static struct platform_device *rx51_peripherals_devices[] = {
+	&rx51_smc91x_device,
+};
+
+/*
+ * Timings are taken from smsc-lan91c96-ms.pdf
+ */
+static int smc91x_init_gpmc(int cs)
+{
+	struct gpmc_timings t;
+	const int t2_r = 45;		/* t2 in Figure 12.10 */
+	const int t2_w = 30;		/* t2 in Figure 12.11 */
+	const int t3 = 15;		/* t3 in Figure 12.10 */
+	const int t5_r = 0;		/* t5 in Figure 12.10 */
+	const int t6_r = 45;		/* t6 in Figure 12.10 */
+	const int t6_w = 0;		/* t6 in Figure 12.11 */
+	const int t7_w = 15;		/* t7 in Figure 12.11 */
+	const int t15 = 12;		/* t15 in Figure 12.2 */
+	const int t20 = 185;		/* t20 in Figure 12.2 */
+
+	memset(&t, 0, sizeof(t));
+
+	t.cs_on = t15;
+	t.cs_rd_off = t3 + t2_r + t5_r;	/* Figure 12.10 */
+	t.cs_wr_off = t3 + t2_w + t6_w;	/* Figure 12.11 */
+	t.adv_on = t3;			/* Figure 12.10 */
+	t.adv_rd_off = t3 + t2_r;	/* Figure 12.10 */
+	t.adv_wr_off = t3 + t2_w;	/* Figure 12.11 */
+	t.oe_off = t3 + t2_r + t5_r;	/* Figure 12.10 */
+	t.oe_on = t.oe_off - t6_r;	/* Figure 12.10 */
+	t.we_off = t3 + t2_w + t6_w;	/* Figure 12.11 */
+	t.we_on = t.we_off - t7_w;	/* Figure 12.11 */
+	t.rd_cycle = t20;		/* Figure 12.2 */
+	t.wr_cycle = t20;		/* Figure 12.4 */
+	t.access = t3 + t2_r + t5_r;	/* Figure 12.10 */
+	t.wr_access = t3 + t2_w + t6_w;	/* Figure 12.11 */
+
+	gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16);
+
+	return gpmc_cs_set_timings(cs, &t);
+}
+
+static void __init rx51_init_smc91x(void)
+{
+	unsigned long cs_mem_base;
+	int ret;
+
+	omap_cfg_reg(U8_34XX_GPIO54_DOWN);
+	omap_cfg_reg(G25_34XX_GPIO86_OUT);
+	omap_cfg_reg(H19_34XX_GPIO164_OUT);
+
+	if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) {
+		printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+		return;
+	}
+
+	rx51_smc91x_resources[0].start = cs_mem_base + 0x300;
+	rx51_smc91x_resources[0].end = cs_mem_base + 0x30f;
+
+	smc91x_init_gpmc(SMC91X_CS);
+
+	if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0)
+		goto free1;
+
+	gpio_direction_input(SMC91X_GPIO_IRQ);
+	rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ);
+
+	ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown");
+	if (ret)
+		goto free2;
+	gpio_direction_output(SMC91X_GPIO_PWRDWN, 0);
+
+	ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset");
+	if (ret)
+		goto free3;
+	gpio_direction_output(SMC91X_GPIO_RESET, 0);
+	gpio_set_value(SMC91X_GPIO_RESET, 1);
+	msleep(100);
+	gpio_set_value(SMC91X_GPIO_RESET, 0);
+
+	return;
+
+free3:
+	gpio_free(SMC91X_GPIO_PWRDWN);
+free2:
+	gpio_free(SMC91X_GPIO_IRQ);
+free1:
+	gpmc_cs_free(SMC91X_CS);
+
+	printk(KERN_ERR "Could not initialize smc91x\n");
+}
+
+static struct twl4030_madc_platform_data rx51_madc_data = {
+	.irq_line		= 1,
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+	{
+		.name		= "external",
+		.mmc		= 1,
+		.wires		= 4,
+		.cover_only	= true,
+		.gpio_cd	= 160,
+		.gpio_wp	= -EINVAL,
+	},
+	{
+		.name		= "internal",
+		.mmc		= 2,
+		.wires		= 8,
+		.gpio_cd	= -EINVAL,
+		.gpio_wp	= -EINVAL,
+	},
+	{}	/* Terminator */
+};
+
+static struct regulator_consumer_supply rx51_vmmc1_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply rx51_vmmc2_supply = {
+	.supply			= "vmmc",
+};
+
+static struct regulator_consumer_supply rx51_vsim_supply = {
+	.supply			= "vmmc_aux",
+};
+
+static struct regulator_init_data rx51_vaux1 = {
+	.constraints = {
+		.name			= "V28",
+		.min_uV			= 2800000,
+		.max_uV			= 2800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static struct regulator_init_data rx51_vaux2 = {
+	.constraints = {
+		.name			= "VCSI",
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+/* VAUX3 - adds more power to VIO_18 rail */
+static struct regulator_init_data rx51_vaux3 = {
+	.constraints = {
+		.name			= "VCAM_DIG_18",
+		.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,
+	},
+};
+
+static struct regulator_init_data rx51_vaux4 = {
+	.constraints = {
+		.name			= "VCAM_ANA_28",
+		.min_uV			= 2800000,
+		.max_uV			= 2800000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static struct regulator_init_data rx51_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	= &rx51_vmmc1_supply,
+};
+
+static struct regulator_init_data rx51_vmmc2 = {
+	.constraints = {
+		.name			= "VMMC2_30",
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &rx51_vmmc2_supply,
+};
+
+static struct regulator_init_data rx51_vsim = {
+	.constraints = {
+		.name			= "VMMC2_IO_18",
+		.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	= &rx51_vsim_supply,
+};
+
+static struct regulator_init_data rx51_vdac = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+};
+
+static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
+{
+	/* FIXME this gpio setup is just a placeholder for now */
+	gpio_request(gpio + 6, "backlight_pwm");
+	gpio_direction_output(gpio + 6, 0);
+	gpio_request(gpio + 7, "speaker_en");
+	gpio_direction_output(gpio + 7, 1);
+
+	/* set up MMC adapters, linking their regulators to them */
+	twl4030_mmc_init(mmc);
+	rx51_vmmc1_supply.dev = mmc[0].dev;
+	rx51_vmmc2_supply.dev = mmc[1].dev;
+	rx51_vsim_supply.dev = mmc[1].dev;
+
+	return 0;
+}
+
+static struct twl4030_gpio_platform_data rx51_gpio_data = {
+	.gpio_base		= OMAP_MAX_GPIO_LINES,
+	.irq_base		= TWL4030_GPIO_IRQ_BASE,
+	.irq_end		= TWL4030_GPIO_IRQ_END,
+	.pulldowns		= BIT(0) | BIT(1) | BIT(2) | BIT(3)
+				| BIT(4) | BIT(5)
+				| BIT(8) | BIT(9) | BIT(10) | BIT(11)
+				| BIT(12) | BIT(13) | BIT(14) | BIT(15)
+				| BIT(16) | BIT(17) ,
+	.setup			= rx51_twlgpio_setup,
+};
+
+static struct twl4030_platform_data rx51_twldata = {
+	.irq_base		= TWL4030_IRQ_BASE,
+	.irq_end		= TWL4030_IRQ_END,
+
+	/* platform_data for children goes here */
+	.gpio			= &rx51_gpio_data,
+	.keypad			= &rx51_kp_data,
+	.madc			= &rx51_madc_data,
+
+	.vaux1			= &rx51_vaux1,
+	.vaux2			= &rx51_vaux2,
+	.vaux3			= &rx51_vaux3,
+	.vaux4			= &rx51_vaux4,
+	.vmmc1			= &rx51_vmmc1,
+	.vmmc2			= &rx51_vmmc2,
+	.vsim			= &rx51_vsim,
+	.vdac			= &rx51_vdac,
+};
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
+	{
+		I2C_BOARD_INFO("twl5030", 0x48),
+		.flags = I2C_CLIENT_WAKE,
+		.irq = INT_34XX_SYS_NIRQ,
+		.platform_data = &rx51_twldata,
+	},
+};
+
+static int __init rx51_i2c_init(void)
+{
+	omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
+			ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
+	omap_register_i2c_bus(2, 100, NULL, 0);
+	omap_register_i2c_bus(3, 400, NULL, 0);
+	return 0;
+}
+
+
+void __init rx51_peripherals_init(void)
+{
+	platform_add_devices(rx51_peripherals_devices,
+				ARRAY_SIZE(rx51_peripherals_devices));
+	rx51_i2c_init();
+	rx51_init_smc91x();
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock24xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock24xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock24xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock24xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,15 +31,193 @@
 #include <mach/clock.h>
 #include <mach/sram.h>
 #include <asm/div64.h>
+#include <asm/clkdev.h>
 
-#include "memory.h"
+#include <mach/sdrc.h>
 #include "clock.h"
-#include "clock24xx.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;
+
+#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
@@ -59,19 +237,32 @@ static struct clk *sclk;
  * Omap24xx specific clock functions
  *-------------------------------------------------------------------------*/
 
-/* This actually returns the rate of core_ck, not dpll_ck. */
-static u32 omap2_get_dpll_rate_24xx(struct clk *tclk)
+/**
+ * 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 dpll_clk;
-	u8 amult;
+	long long core_clk;
+	u32 v;
 
-	dpll_clk = omap2_get_dpll_rate(tclk);
+	core_clk = omap2_get_dpll_rate(clk);
 
-	amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
-	amult &= OMAP24XX_CORE_CLK_SRC_MASK;
-	dpll_clk *= amult;
+	v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+	v &= OMAP24XX_CORE_CLK_SRC_MASK;
 
-	return dpll_clk;
+	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)
@@ -96,6 +287,11 @@ static void omap2_disable_osc_ck(struct
 		      OMAP24XX_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)
@@ -149,11 +345,16 @@ static void omap2_clk_fixed_disable(stru
 	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.
  */
-long omap2_dpllcore_round_rate(unsigned long target_rate)
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
 {
 	u32 high, low, core_clk_src;
 
@@ -182,11 +383,9 @@ long omap2_dpllcore_round_rate(unsigned
 
 }
 
-static void omap2_dpllcore_recalc(struct clk *clk)
+static unsigned long omap2_dpllcore_recalc(struct clk *clk)
 {
-	clk->rate = omap2_get_dpll_rate_24xx(clk);
-
-	propagate_rate(clk);
+	return omap2xxx_clk_get_core_rate(clk);
 }
 
 static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
@@ -195,22 +394,19 @@ static int omap2_reprogram_dpllcore(stru
 	u32 bypass = 0;
 	struct prcm_config tmpset;
 	const struct dpll_data *dd;
-	unsigned long flags;
-	int ret = -EINVAL;
 
-	local_irq_save(flags);
-	cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
+	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)) {
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
 	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 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)
-			goto dpll_exit;
+			return -EINVAL;
 
 		if (mult == 1)
 			low = curr_prcm_set->dpll_speed;
@@ -219,7 +415,7 @@ static int omap2_reprogram_dpllcore(stru
 
 		dd = clk->dpll_data;
 		if (!dd)
-			goto dpll_exit;
+			return -EINVAL;
 
 		tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
 		tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
@@ -245,22 +441,19 @@ static int omap2_reprogram_dpllcore(stru
 		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
 			bypass = 1;
 
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */
+		/* 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 */
-		omap2_init_memory_params(omap2_dll_force_needed());
-		omap2_reprogram_sdrc(done_rate, 0);
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
 	}
-	omap2_dpllcore_recalc(&dpll_ck);
-	ret = 0;
 
-dpll_exit:
-	local_irq_restore(flags);
-	return(ret);
+	return 0;
 }
 
 /**
@@ -269,9 +462,9 @@ dpll_exit:
  *
  * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
  */
-static void omap2_table_mpu_recalc(struct clk *clk)
+static unsigned long omap2_table_mpu_recalc(struct clk *clk)
 {
-	clk->rate = curr_prcm_set->mpu_speed;
+	return curr_prcm_set->mpu_speed;
 }
 
 /*
@@ -337,12 +530,12 @@ static int omap2_select_table_rate(struc
 	}
 
 	curr_prcm_set = prcm;
-	cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
+	cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
 
 	if (prcm->dpll_speed == cur_rate / 2) {
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
 	} else if (prcm->dpll_speed == cur_rate * 2) {
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
+		omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
 	} else if (prcm->dpll_speed != cur_rate) {
 		local_irq_save(flags);
 
@@ -366,27 +559,67 @@ static int omap2_select_table_rate(struc
 
 		/* 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);
+		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 init_mem */
-		omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
+		/* 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);
 
-		omap2_init_memory_params(omap2_dll_force_needed());
-		omap2_reprogram_sdrc(done_rate, 0);
+		omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+		omap2xxx_sdrc_reprogram(done_rate, 0);
 
 		local_irq_restore(flags);
 	}
-	omap2_dpllcore_recalc(&dpll_ck);
 
 	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,
@@ -394,24 +627,27 @@ static struct clk_functions omap2_clk_fu
 	.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, sclk = 0;
+	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)
-		sclk = 19200000;
+		srate = 19200000;
 	else if (aplls == APLLS_CLKIN_13MHZ)
-		sclk = 13000000;
+		srate = 13000000;
 	else if (aplls == APLLS_CLKIN_12MHZ)
-		sclk = 12000000;
+		srate = 12000000;
 
-	return sclk;
+	return srate;
 }
 
 static u32 omap2_get_sysclkdiv(void)
@@ -425,16 +661,14 @@ static u32 omap2_get_sysclkdiv(void)
 	return div;
 }
 
-static void omap2_osc_clk_recalc(struct clk *clk)
+static unsigned long omap2_osc_clk_recalc(struct clk *clk)
 {
-	clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv();
-	propagate_rate(clk);
+	return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
 }
 
-static void omap2_sys_clk_recalc(struct clk *clk)
+static unsigned long omap2_sys_clk_recalc(struct clk *clk)
 {
-	clk->rate = clk->parent->rate / omap2_get_sysclkdiv();
-	propagate_rate(clk);
+	return clk->parent->rate / omap2_get_sysclkdiv();
 }
 
 /*
@@ -460,7 +694,7 @@ static int __init omap2_clk_arch_init(vo
 	if (!mpurate)
 		return -EINVAL;
 
-	if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+	if (clk_set_rate(&virt_prcm_set, mpurate))
 		printk(KERN_ERR "Could not find matching MPU rate\n");
 
 	recalculate_root_clocks();
@@ -477,7 +711,7 @@ arch_initcall(omap2_clk_arch_init);
 int __init omap2_clk_init(void)
 {
 	struct prcm_config *prcm;
-	struct clk **clkp;
+	struct omap_clk *c;
 	u32 clkrate;
 
 	if (cpu_is_omap242x())
@@ -487,26 +721,22 @@ int __init omap2_clk_init(void)
 
 	clk_init(&omap2_clk_functions);
 
-	omap2_osc_clk_recalc(&osc_ck);
-	omap2_sys_clk_recalc(&sys_ck);
-
-	for (clkp = onchip_24xx_clks;
-	     clkp < onchip_24xx_clks + ARRAY_SIZE(onchip_24xx_clks);
-	     clkp++) {
+	for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+		clk_init_one(c->lk.clk);
 
-		if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
-			clk_register(*clkp);
-			continue;
-		}
+	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);
 
-		if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
-			clk_register(*clkp);
-			continue;
+	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);
 		}
-	}
 
 	/* Check the MPU rate set by bootloader */
-	clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
+	clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
 	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
 		if (!(prcm->flags & cpu_mask))
 			continue;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock24xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock24xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock24xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock24xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,17 +24,13 @@
 #include "cm-regbits-24xx.h"
 #include "sdrc.h"
 
-static void omap2_table_mpu_recalc(struct clk *clk);
+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 void omap2_sys_clk_recalc(struct clk *clk);
-static void omap2_osc_clk_recalc(struct clk *clk);
-static void omap2_sys_clk_recalc(struct clk *clk);
-static void omap2_dpllcore_recalc(struct clk *clk);
-static int omap2_clk_fixed_enable(struct clk *clk);
-static void omap2_clk_fixed_disable(struct clk *clk);
-static int omap2_enable_osc_ck(struct clk *clk);
-static void omap2_disable_osc_ck(struct clk *clk);
+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.
@@ -623,41 +619,43 @@ static struct prcm_config rate_table[] =
 /* Base external input clocks */
 static struct clk func_32k_ck = {
 	.name		= "func_32k_ck",
+	.ops		= &clkops_null,
 	.rate		= 32000,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+	.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",
-	.recalc		= &propagate_rate,
 };
 
 /* 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",
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES,
+	.ops		= &clkops_oscck,
 	.clkdm_name	= "wkup_clkdm",
-	.enable		= &omap2_enable_osc_ck,
-	.disable	= &omap2_disable_osc_ck,
 	.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,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ALWAYS_ENABLED | RATE_PROPAGATES,
 	.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		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+	.flags		= RATE_FIXED,
 	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &propagate_rate,
 };
 
 /*
@@ -673,7 +671,12 @@ 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
 };
@@ -684,10 +687,9 @@ static struct dpll_data dpll_dd = {
  */
 static struct clk dpll_ck = {
 	.name		= "dpll_ck",
+	.ops		= &clkops_null,
 	.parent		= &sys_ck,		/* Can be func_32k also */
 	.dpll_data	= &dpll_dd,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &omap2_dpllcore_recalc,
 	.set_rate	= &omap2_reprogram_dpllcore,
@@ -695,30 +697,24 @@ static struct clk dpll_ck = {
 
 static struct clk apll96_ck = {
 	.name		= "apll96_ck",
+	.ops		= &clkops_fixed,
 	.parent		= &sys_ck,
 	.rate		= 96000000,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+	.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,
-	.enable		= &omap2_clk_fixed_enable,
-	.disable	= &omap2_clk_fixed_disable,
-	.recalc		= &propagate_rate,
 };
 
 static struct clk apll54_ck = {
 	.name		= "apll54_ck",
+	.ops		= &clkops_fixed,
 	.parent		= &sys_ck,
 	.rate		= 54000000,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+	.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,
-	.enable		= &omap2_clk_fixed_enable,
-	.disable	= &omap2_clk_fixed_disable,
-	.recalc		= &propagate_rate,
 };
 
 /*
@@ -745,9 +741,8 @@ static const struct clksel func_54m_clks
 
 static struct clk func_54m_ck = {
 	.name		= "func_54m_ck",
+	.ops		= &clkops_null,
 	.parent		= &apll54_ck,	/* can also be alt_clk */
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.init		= &omap2_init_clksel_parent,
 	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -758,9 +753,8 @@ static struct clk func_54m_ck = {
 
 static struct clk core_ck = {
 	.name		= "core_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll_ck,		/* can also be 32k */
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ALWAYS_ENABLED | RATE_PROPAGATES,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -785,9 +779,8 @@ static const struct clksel func_96m_clks
 /* 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,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.init		= &omap2_init_clksel_parent,
 	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -818,9 +811,8 @@ static const struct clksel func_48m_clks
 
 static struct clk func_48m_ck = {
 	.name		= "func_48m_ck",
+	.ops		= &clkops_null,
 	.parent		= &apll96_ck,	 /* 96M or Alt */
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.init		= &omap2_init_clksel_parent,
 	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -833,10 +825,9 @@ static struct clk func_48m_ck = {
 
 static struct clk func_12m_ck = {
 	.name		= "func_12m_ck",
+	.ops		= &clkops_null,
 	.parent		= &func_48m_ck,
 	.fixed_div	= 4,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &omap2_fixed_divisor_recalc,
 };
@@ -844,8 +835,8 @@ static struct clk func_12m_ck = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.recalc		= &followparent_recalc,
 };
 
@@ -887,9 +878,8 @@ static const struct clksel common_clkout
 
 static struct clk sys_clkout_src = {
 	.name		= "sys_clkout_src",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &func_54m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_PROPAGATES,
 	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
 	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
@@ -918,9 +908,8 @@ static const struct clksel sys_clkout_cl
 
 static struct clk sys_clkout = {
 	.name		= "sys_clkout",
+	.ops		= &clkops_null,
 	.parent		= &sys_clkout_src,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
 	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
@@ -933,8 +922,8 @@ static struct clk sys_clkout = {
 /* In 2430, new in 2420 ES2 */
 static struct clk sys_clkout2_src = {
 	.name		= "sys_clkout2_src",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &func_54m_ck,
-	.flags		= CLOCK_IN_OMAP242X | RATE_PROPAGATES,
 	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
 	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
@@ -955,8 +944,8 @@ static const struct clksel sys_clkout2_c
 /* In 2430, new in 2420 ES2 */
 static struct clk sys_clkout2 = {
 	.name		= "sys_clkout2",
+	.ops		= &clkops_null,
 	.parent		= &sys_clkout2_src,
-	.flags		= CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "wkup_clkdm",
 	.clksel_reg	= OMAP24XX_PRCM_CLKOUT_CTRL,
 	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
@@ -968,8 +957,8 @@ static struct clk sys_clkout2 = {
 
 static struct clk emul_ck = {
 	.name		= "emul_ck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &func_54m_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP24XX_PRCM_CLKEMUL_CTRL,
 	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
@@ -1003,10 +992,9 @@ static const struct clksel mpu_clksel[]
 
 static struct clk mpu_ck = {	/* Control cpu */
 	.name		= "mpu_ck",
+	.ops		= &clkops_null,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ALWAYS_ENABLED | DELAYED_APP |
-				CONFIG_PARTICIPANT | RATE_PROPAGATES,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
 	.clkdm_name	= "mpu_clkdm",
 	.init		= &omap2_init_clksel_parent,
 	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
@@ -1046,9 +1034,9 @@ static const struct clksel dsp_fck_clkse
 
 static struct clk dsp_fck = {
 	.name		= "dsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
-				CONFIG_PARTICIPANT | RATE_PROPAGATES,
+	.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,
@@ -1076,9 +1064,9 @@ static const struct clksel dsp_irate_ick
 /* 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		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
-				CONFIG_PARTICIPANT | PARENT_CONTROLS_CLOCK,
+	.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,
@@ -1090,8 +1078,9 @@ static struct clk dsp_irate_ick = {
 /* 2420 only */
 static struct clk dsp_ick = {
 	.name		= "dsp_ick",	 /* apparently ipi and isp */
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &dsp_irate_ick,
-	.flags		= CLOCK_IN_OMAP242X | DELAYED_APP | CONFIG_PARTICIPANT,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
 };
@@ -1099,8 +1088,9 @@ static struct clk dsp_ick = {
 /* 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		= CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+	.flags		= DELAYED_APP | CONFIG_PARTICIPANT,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
 };
@@ -1112,9 +1102,9 @@ static struct clk iva2_1_ick = {
  */
 static struct clk iva1_ifck = {
 	.name		= "iva1_ifck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT |
-				RATE_PROPAGATES | DELAYED_APP,
+	.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,
@@ -1129,8 +1119,8 @@ static struct clk iva1_ifck = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "iva1_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
@@ -1175,10 +1165,9 @@ static const struct clksel core_l3_clkse
 
 static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
 	.name		= "core_l3_ck",
+	.ops		= &clkops_null,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ALWAYS_ENABLED | DELAYED_APP |
-				CONFIG_PARTICIPANT | RATE_PROPAGATES,
+	.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,
@@ -1204,9 +1193,9 @@ static const struct clksel usb_l4_ick_cl
 /* 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		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				DELAYED_APP | CONFIG_PARTICIPANT,
+	.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,
@@ -1238,9 +1227,9 @@ static const struct clksel l4_clksel[] =
 
 static struct clk l4_ck = {		/* used both as an ick and fck */
 	.name		= "l4_ck",
+	.ops		= &clkops_null,
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
+	.flags		= DELAYED_APP,
 	.clkdm_name	= "core_l4_clkdm",
 	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
 	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
@@ -1276,9 +1265,9 @@ static const struct clksel ssi_ssr_sst_f
 
 static struct clk ssi_ssr_sst_fck = {
 	.name		= "ssi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				DELAYED_APP,
+	.flags		= DELAYED_APP,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
@@ -1290,6 +1279,20 @@ static struct clk ssi_ssr_sst_fck = {
 	.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
@@ -1312,8 +1315,8 @@ static const struct clksel gfx_fck_clkse
 
 static struct clk gfx_3d_fck = {
 	.name		= "gfx_3d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "gfx_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
@@ -1327,8 +1330,8 @@ static struct clk gfx_3d_fck = {
 
 static struct clk gfx_2d_fck = {
 	.name		= "gfx_2d_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "gfx_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
@@ -1342,8 +1345,8 @@ static struct clk gfx_2d_fck = {
 
 static struct clk gfx_ick = {
 	.name		= "gfx_ick",		/* From l3 */
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "gfx_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP_EN_GFX_SHIFT,
@@ -1372,8 +1375,9 @@ static const struct clksel mdm_ick_clkse
 
 static struct clk mdm_ick = {		/* used both as a ick and fck */
 	.name		= "mdm_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_ck,
-	.flags		= CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+	.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,
@@ -1387,8 +1391,8 @@ static struct clk mdm_ick = {		/* used b
 
 static struct clk mdm_osc_ck = {
 	.name		= "mdm_osc_ck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &osc_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "mdm_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
@@ -1432,8 +1436,8 @@ static const struct clksel dss1_fck_clks
 
 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 */
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
@@ -1442,9 +1446,9 @@ static struct clk dss_ick = {		/* Enable
 
 static struct clk dss1_fck = {
 	.name		= "dss1_fck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &core_ck,		/* Core or sys */
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				DELAYED_APP,
+	.flags		= DELAYED_APP,
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
@@ -1475,9 +1479,9 @@ static const struct clksel dss2_fck_clks
 
 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		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				DELAYED_APP,
+	.flags		= DELAYED_APP,
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
@@ -1490,8 +1494,8 @@ static struct clk dss2_fck = {		/* Alt c
 
 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,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "dss_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
@@ -1518,8 +1522,8 @@ static const struct clksel omap24xx_gpt_
 
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
@@ -1528,8 +1532,8 @@ static struct clk gpt1_ick = {
 
 static struct clk gpt1_fck = {
 	.name		= "gpt1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
@@ -1544,8 +1548,8 @@ static struct clk gpt1_fck = {
 
 static struct clk gpt2_ick = {
 	.name		= "gpt2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
@@ -1554,8 +1558,8 @@ static struct clk gpt2_ick = {
 
 static struct clk gpt2_fck = {
 	.name		= "gpt2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
@@ -1568,8 +1572,8 @@ static struct clk gpt2_fck = {
 
 static struct clk gpt3_ick = {
 	.name		= "gpt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
@@ -1578,8 +1582,8 @@ static struct clk gpt3_ick = {
 
 static struct clk gpt3_fck = {
 	.name		= "gpt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
@@ -1592,8 +1596,8 @@ static struct clk gpt3_fck = {
 
 static struct clk gpt4_ick = {
 	.name		= "gpt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
@@ -1602,8 +1606,8 @@ static struct clk gpt4_ick = {
 
 static struct clk gpt4_fck = {
 	.name		= "gpt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
@@ -1616,8 +1620,8 @@ static struct clk gpt4_fck = {
 
 static struct clk gpt5_ick = {
 	.name		= "gpt5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
@@ -1626,8 +1630,8 @@ static struct clk gpt5_ick = {
 
 static struct clk gpt5_fck = {
 	.name		= "gpt5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
@@ -1640,8 +1644,8 @@ static struct clk gpt5_fck = {
 
 static struct clk gpt6_ick = {
 	.name		= "gpt6_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
@@ -1650,8 +1654,8 @@ static struct clk gpt6_ick = {
 
 static struct clk gpt6_fck = {
 	.name		= "gpt6_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
@@ -1664,8 +1668,8 @@ static struct clk gpt6_fck = {
 
 static struct clk gpt7_ick = {
 	.name		= "gpt7_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1673,8 +1677,8 @@ static struct clk gpt7_ick = {
 
 static struct clk gpt7_fck = {
 	.name		= "gpt7_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
@@ -1687,8 +1691,8 @@ static struct clk gpt7_fck = {
 
 static struct clk gpt8_ick = {
 	.name		= "gpt8_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
@@ -1697,8 +1701,8 @@ static struct clk gpt8_ick = {
 
 static struct clk gpt8_fck = {
 	.name		= "gpt8_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
@@ -1711,8 +1715,8 @@ static struct clk gpt8_fck = {
 
 static struct clk gpt9_ick = {
 	.name		= "gpt9_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
@@ -1721,8 +1725,8 @@ static struct clk gpt9_ick = {
 
 static struct clk gpt9_fck = {
 	.name		= "gpt9_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
@@ -1735,8 +1739,8 @@ static struct clk gpt9_fck = {
 
 static struct clk gpt10_ick = {
 	.name		= "gpt10_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
@@ -1745,8 +1749,8 @@ static struct clk gpt10_ick = {
 
 static struct clk gpt10_fck = {
 	.name		= "gpt10_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
@@ -1759,8 +1763,8 @@ static struct clk gpt10_fck = {
 
 static struct clk gpt11_ick = {
 	.name		= "gpt11_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
@@ -1769,8 +1773,8 @@ static struct clk gpt11_ick = {
 
 static struct clk gpt11_fck = {
 	.name		= "gpt11_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
@@ -1783,8 +1787,8 @@ static struct clk gpt11_fck = {
 
 static struct clk gpt12_ick = {
 	.name		= "gpt12_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
@@ -1793,8 +1797,8 @@ static struct clk gpt12_ick = {
 
 static struct clk gpt12_fck = {
 	.name		= "gpt12_fck",
-	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.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,
@@ -1807,9 +1811,9 @@ static struct clk gpt12_fck = {
 
 static struct clk mcbsp1_ick = {
 	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
@@ -1818,9 +1822,9 @@ static struct clk mcbsp1_ick = {
 
 static struct clk mcbsp1_fck = {
 	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
@@ -1829,9 +1833,9 @@ static struct clk mcbsp1_fck = {
 
 static struct clk mcbsp2_ick = {
 	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
@@ -1840,9 +1844,9 @@ static struct clk mcbsp2_ick = {
 
 static struct clk mcbsp2_fck = {
 	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
@@ -1851,9 +1855,9 @@ static struct clk mcbsp2_fck = {
 
 static struct clk mcbsp3_ick = {
 	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 3,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
@@ -1862,9 +1866,9 @@ static struct clk mcbsp3_ick = {
 
 static struct clk mcbsp3_fck = {
 	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 3,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
@@ -1873,9 +1877,9 @@ static struct clk mcbsp3_fck = {
 
 static struct clk mcbsp4_ick = {
 	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 4,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
@@ -1884,9 +1888,9 @@ static struct clk mcbsp4_ick = {
 
 static struct clk mcbsp4_fck = {
 	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 4,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
@@ -1895,9 +1899,9 @@ static struct clk mcbsp4_fck = {
 
 static struct clk mcbsp5_ick = {
 	.name		= "mcbsp_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 5,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
@@ -1906,9 +1910,9 @@ static struct clk mcbsp5_ick = {
 
 static struct clk mcbsp5_fck = {
 	.name		= "mcbsp_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 5,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
@@ -1917,10 +1921,10 @@ static struct clk mcbsp5_fck = {
 
 static struct clk mcspi1_ick = {
 	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &l4_ck,
 	.clkdm_name	= "core_l4_clkdm",
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1928,9 +1932,9 @@ static struct clk mcspi1_ick = {
 
 static struct clk mcspi1_fck = {
 	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
@@ -1939,9 +1943,9 @@ static struct clk mcspi1_fck = {
 
 static struct clk mcspi2_ick = {
 	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
@@ -1950,9 +1954,9 @@ static struct clk mcspi2_ick = {
 
 static struct clk mcspi2_fck = {
 	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
@@ -1961,9 +1965,9 @@ static struct clk mcspi2_fck = {
 
 static struct clk mcspi3_ick = {
 	.name		= "mcspi_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 3,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
@@ -1972,9 +1976,9 @@ static struct clk mcspi3_ick = {
 
 static struct clk mcspi3_fck = {
 	.name		= "mcspi_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 3,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
@@ -1983,8 +1987,8 @@ static struct clk mcspi3_fck = {
 
 static struct clk uart1_ick = {
 	.name		= "uart1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
@@ -1993,8 +1997,8 @@ static struct clk uart1_ick = {
 
 static struct clk uart1_fck = {
 	.name		= "uart1_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
@@ -2003,8 +2007,8 @@ static struct clk uart1_fck = {
 
 static struct clk uart2_ick = {
 	.name		= "uart2_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
@@ -2013,8 +2017,8 @@ static struct clk uart2_ick = {
 
 static struct clk uart2_fck = {
 	.name		= "uart2_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
@@ -2023,8 +2027,8 @@ static struct clk uart2_fck = {
 
 static struct clk uart3_ick = {
 	.name		= "uart3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
@@ -2033,8 +2037,8 @@ static struct clk uart3_ick = {
 
 static struct clk uart3_fck = {
 	.name		= "uart3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
@@ -2043,8 +2047,8 @@ static struct clk uart3_fck = {
 
 static struct clk gpios_ick = {
 	.name		= "gpios_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
@@ -2053,8 +2057,8 @@ static struct clk gpios_ick = {
 
 static struct clk gpios_fck = {
 	.name		= "gpios_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
@@ -2063,8 +2067,8 @@ static struct clk gpios_fck = {
 
 static struct clk mpu_wdt_ick = {
 	.name		= "mpu_wdt_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
@@ -2073,8 +2077,8 @@ static struct clk mpu_wdt_ick = {
 
 static struct clk mpu_wdt_fck = {
 	.name		= "mpu_wdt_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
@@ -2083,9 +2087,9 @@ static struct clk mpu_wdt_fck = {
 
 static struct clk sync_32k_ick = {
 	.name		= "sync_32k_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ENABLE_ON_INIT,
+	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
@@ -2094,8 +2098,8 @@ static struct clk sync_32k_ick = {
 
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
@@ -2104,9 +2108,9 @@ static struct clk wdt1_ick = {
 
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ENABLE_ON_INIT,
+	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
@@ -2115,8 +2119,8 @@ static struct clk omapctrl_ick = {
 
 static struct clk icr_ick = {
 	.name		= "icr_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
@@ -2125,8 +2129,8 @@ static struct clk icr_ick = {
 
 static struct clk cam_ick = {
 	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
@@ -2140,8 +2144,8 @@ static struct clk cam_ick = {
  */
 static struct clk cam_fck = {
 	.name		= "cam_fck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
@@ -2150,8 +2154,8 @@ static struct clk cam_fck = {
 
 static struct clk mailboxes_ick = {
 	.name		= "mailboxes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
@@ -2160,8 +2164,8 @@ static struct clk mailboxes_ick = {
 
 static struct clk wdt4_ick = {
 	.name		= "wdt4_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
@@ -2170,8 +2174,8 @@ static struct clk wdt4_ick = {
 
 static struct clk wdt4_fck = {
 	.name		= "wdt4_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
@@ -2180,8 +2184,8 @@ static struct clk wdt4_fck = {
 
 static struct clk wdt3_ick = {
 	.name		= "wdt3_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
@@ -2190,8 +2194,8 @@ static struct clk wdt3_ick = {
 
 static struct clk wdt3_fck = {
 	.name		= "wdt3_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
@@ -2200,8 +2204,8 @@ static struct clk wdt3_fck = {
 
 static struct clk mspro_ick = {
 	.name		= "mspro_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
@@ -2210,8 +2214,8 @@ static struct clk mspro_ick = {
 
 static struct clk mspro_fck = {
 	.name		= "mspro_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
@@ -2220,8 +2224,8 @@ static struct clk mspro_fck = {
 
 static struct clk mmc_ick = {
 	.name		= "mmc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
@@ -2230,8 +2234,8 @@ static struct clk mmc_ick = {
 
 static struct clk mmc_fck = {
 	.name		= "mmc_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
@@ -2240,8 +2244,8 @@ static struct clk mmc_fck = {
 
 static struct clk fac_ick = {
 	.name		= "fac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
@@ -2250,8 +2254,8 @@ static struct clk fac_ick = {
 
 static struct clk fac_fck = {
 	.name		= "fac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_12m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
@@ -2260,8 +2264,8 @@ static struct clk fac_fck = {
 
 static struct clk eac_ick = {
 	.name		= "eac_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
@@ -2270,8 +2274,8 @@ static struct clk eac_ick = {
 
 static struct clk eac_fck = {
 	.name		= "eac_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
@@ -2280,8 +2284,8 @@ static struct clk eac_fck = {
 
 static struct clk hdq_ick = {
 	.name		= "hdq_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
@@ -2290,8 +2294,8 @@ static struct clk hdq_ick = {
 
 static struct clk hdq_fck = {
 	.name		= "hdq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_12m_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
@@ -2300,9 +2304,9 @@ static struct clk hdq_fck = {
 
 static struct clk i2c2_ick = {
 	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
@@ -2311,9 +2315,9 @@ static struct clk i2c2_ick = {
 
 static struct clk i2c2_fck = {
 	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &func_12m_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
@@ -2322,9 +2326,9 @@ static struct clk i2c2_fck = {
 
 static struct clk i2chs2_fck = {
 	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 2,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
@@ -2333,9 +2337,9 @@ static struct clk i2chs2_fck = {
 
 static struct clk i2c1_ick = {
 	.name		= "i2c_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
@@ -2344,9 +2348,9 @@ static struct clk i2c1_ick = {
 
 static struct clk i2c1_fck = {
 	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_12m_ck,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
@@ -2355,9 +2359,9 @@ static struct clk i2c1_fck = {
 
 static struct clk i2chs1_fck = {
 	.name		= "i2c_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
@@ -2366,33 +2370,33 @@ static struct clk i2chs1_fck = {
 
 static struct clk gpmc_fck = {
 	.name		= "gpmc_fck",
+	.ops		= &clkops_null, /* RMK: missing? */
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				ENABLE_ON_INIT,
+	.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,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l3_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk sdma_ick = {
 	.name		= "sdma_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.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,
-	.flags		= CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
@@ -2426,8 +2430,9 @@ static const struct clksel vlynq_fck_clk
 
 static struct clk vlynq_fck = {
 	.name		= "vlynq_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP242X | DELAYED_APP,
+	.flags		= DELAYED_APP,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
@@ -2442,8 +2447,9 @@ static struct clk vlynq_fck = {
 
 static struct clk sdrc_ick = {
 	.name		= "sdrc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+	.flags		= ENABLE_ON_INIT,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
 	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
@@ -2452,8 +2458,8 @@ static struct clk sdrc_ick = {
 
 static struct clk des_ick = {
 	.name		= "des_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
 	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
@@ -2462,8 +2468,8 @@ static struct clk des_ick = {
 
 static struct clk sha_ick = {
 	.name		= "sha_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
 	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
@@ -2472,8 +2478,8 @@ static struct clk sha_ick = {
 
 static struct clk rng_ick = {
 	.name		= "rng_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
 	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
@@ -2482,8 +2488,8 @@ static struct clk rng_ick = {
 
 static struct clk aes_ick = {
 	.name		= "aes_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
 	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
@@ -2492,8 +2498,8 @@ static struct clk aes_ick = {
 
 static struct clk pka_ick = {
 	.name		= "pka_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
 	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
@@ -2502,8 +2508,8 @@ static struct clk pka_ick = {
 
 static struct clk usb_fck = {
 	.name		= "usb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_48m_ck,
-	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
@@ -2512,8 +2518,8 @@ static struct clk usb_fck = {
 
 static struct clk usbhs_ick = {
 	.name		= "usbhs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_l3_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
@@ -2522,8 +2528,8 @@ static struct clk usbhs_ick = {
 
 static struct clk mmchs1_ick = {
 	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
@@ -2532,8 +2538,8 @@ static struct clk mmchs1_ick = {
 
 static struct clk mmchs1_fck = {
 	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l3_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
@@ -2542,9 +2548,9 @@ static struct clk mmchs1_fck = {
 
 static struct clk mmchs2_ick = {
 	.name		= "mmchs_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
@@ -2553,9 +2559,9 @@ static struct clk mmchs2_ick = {
 
 static struct clk mmchs2_fck = {
 	.name		= "mmchs_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_96m_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -2563,8 +2569,8 @@ static struct clk mmchs2_fck = {
 
 static struct clk gpio5_ick = {
 	.name		= "gpio5_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
@@ -2573,8 +2579,8 @@ static struct clk gpio5_ick = {
 
 static struct clk gpio5_fck = {
 	.name		= "gpio5_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
@@ -2583,8 +2589,8 @@ static struct clk gpio5_fck = {
 
 static struct clk mdm_intc_ick = {
 	.name		= "mdm_intc_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
 	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
@@ -2593,8 +2599,8 @@ static struct clk mdm_intc_ick = {
 
 static struct clk mmchsdb1_fck = {
 	.name		= "mmchsdb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
@@ -2603,9 +2609,9 @@ static struct clk mmchsdb1_fck = {
 
 static struct clk mmchsdb2_fck = {
 	.name		= "mmchsdb_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.id		= 1,
 	.parent		= &func_32k_ck,
-	.flags		= CLOCK_IN_OMAP243X,
 	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
 	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
@@ -2628,166 +2634,13 @@ static struct clk mmchsdb2_fck = {
  */
 static struct clk virt_prcm_set = {
 	.name		= "virt_prcm_set",
-	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP,
+	.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,
 };
 
-static struct clk *onchip_24xx_clks[] __initdata = {
-	/* external root sources */
-	&func_32k_ck,
-	&osc_ck,
-	&sys_ck,
-	&alt_ck,
-	/* internal analog sources */
-	&dpll_ck,
-	&apll96_ck,
-	&apll54_ck,
-	/* internal prcm root sources */
-	&func_54m_ck,
-	&core_ck,
-	&func_96m_ck,
-	&func_48m_ck,
-	&func_12m_ck,
-	&wdt1_osc_ck,
-	&sys_clkout_src,
-	&sys_clkout,
-	&sys_clkout2_src,
-	&sys_clkout2,
-	&emul_ck,
-	/* mpu domain clocks */
-	&mpu_ck,
-	/* dsp domain clocks */
-	&dsp_fck,
-	&dsp_irate_ick,
-	&dsp_ick,		/* 242x */
-	&iva2_1_ick,		/* 243x */
-	&iva1_ifck,		/* 242x */
-	&iva1_mpu_int_ifck,	/* 242x */
-	/* GFX domain clocks */
-	&gfx_3d_fck,
-	&gfx_2d_fck,
-	&gfx_ick,
-	/* Modem domain clocks */
-	&mdm_ick,
-	&mdm_osc_ck,
-	/* DSS domain clocks */
-	&dss_ick,
-	&dss1_fck,
-	&dss2_fck,
-	&dss_54m_fck,
-	/* L3 domain clocks */
-	&core_l3_ck,
-	&ssi_ssr_sst_fck,
-	&usb_l4_ick,
-	/* L4 domain clocks */
-	&l4_ck,			/* used as both core_l4 and wu_l4 */
-	/* virtual meta-group clock */
-	&virt_prcm_set,
-	/* general l4 interface ck, multi-parent functional clk */
-	&gpt1_ick,
-	&gpt1_fck,
-	&gpt2_ick,
-	&gpt2_fck,
-	&gpt3_ick,
-	&gpt3_fck,
-	&gpt4_ick,
-	&gpt4_fck,
-	&gpt5_ick,
-	&gpt5_fck,
-	&gpt6_ick,
-	&gpt6_fck,
-	&gpt7_ick,
-	&gpt7_fck,
-	&gpt8_ick,
-	&gpt8_fck,
-	&gpt9_ick,
-	&gpt9_fck,
-	&gpt10_ick,
-	&gpt10_fck,
-	&gpt11_ick,
-	&gpt11_fck,
-	&gpt12_ick,
-	&gpt12_fck,
-	&mcbsp1_ick,
-	&mcbsp1_fck,
-	&mcbsp2_ick,
-	&mcbsp2_fck,
-	&mcbsp3_ick,
-	&mcbsp3_fck,
-	&mcbsp4_ick,
-	&mcbsp4_fck,
-	&mcbsp5_ick,
-	&mcbsp5_fck,
-	&mcspi1_ick,
-	&mcspi1_fck,
-	&mcspi2_ick,
-	&mcspi2_fck,
-	&mcspi3_ick,
-	&mcspi3_fck,
-	&uart1_ick,
-	&uart1_fck,
-	&uart2_ick,
-	&uart2_fck,
-	&uart3_ick,
-	&uart3_fck,
-	&gpios_ick,
-	&gpios_fck,
-	&mpu_wdt_ick,
-	&mpu_wdt_fck,
-	&sync_32k_ick,
-	&wdt1_ick,
-	&omapctrl_ick,
-	&icr_ick,
-	&cam_fck,
-	&cam_ick,
-	&mailboxes_ick,
-	&wdt4_ick,
-	&wdt4_fck,
-	&wdt3_ick,
-	&wdt3_fck,
-	&mspro_ick,
-	&mspro_fck,
-	&mmc_ick,
-	&mmc_fck,
-	&fac_ick,
-	&fac_fck,
-	&eac_ick,
-	&eac_fck,
-	&hdq_ick,
-	&hdq_fck,
-	&i2c1_ick,
-	&i2c1_fck,
-	&i2chs1_fck,
-	&i2c2_ick,
-	&i2c2_fck,
-	&i2chs2_fck,
-	&gpmc_fck,
-	&sdma_fck,
-	&sdma_ick,
-	&vlynq_ick,
-	&vlynq_fck,
-	&sdrc_ick,
-	&des_ick,
-	&sha_ick,
-	&rng_ick,
-	&aes_ick,
-	&pka_ick,
-	&usb_fck,
-	&usbhs_ick,
-	&mmchs1_ick,
-	&mmchs1_fck,
-	&mmchs2_ick,
-	&mmchs2_fck,
-	&gpio5_ick,
-	&gpio5_fck,
-	&mdm_intc_ick,
-	&mmchsdb1_fck,
-	&mmchsdb2_fck,
-};
-
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock34xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock34xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock34xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock34xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,15 +30,251 @@
 #include <mach/clock.h>
 #include <mach/sram.h>
 #include <asm/div64.h>
+#include <asm/clkdev.h>
 
-#include "memory.h"
+#include <mach/sdrc.h>
 #include "clock.h"
-#include "clock34xx.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;
+
+#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,	"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,	CK_343X),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck,	CK_343X),
+	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_343X),
+	CLK("musb_hdrc",	"ick",	&hsotgusb_ick,	CK_343X),
+	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,	CK_343X),
+	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, CK_343X),
+	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,	CK_343X),
+	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
@@ -51,11 +287,9 @@
  *
  * Recalculate and propagate the DPLL rate.
  */
-static void omap3_dpll_recalc(struct clk *clk)
+static unsigned long omap3_dpll_recalc(struct clk *clk)
 {
-	clk->rate = omap2_get_dpll_rate(clk);
-
-	propagate_rate(clk);
+	return omap2_get_dpll_rate(clk);
 }
 
 /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
@@ -78,14 +312,12 @@ static int _omap3_wait_dpll_status(struc
 	const struct dpll_data *dd;
 	int i = 0;
 	int ret = -EINVAL;
-	u32 idlest_mask;
 
 	dd = clk->dpll_data;
 
-	state <<= dd->idlest_bit;
-	idlest_mask = 1 << dd->idlest_bit;
+	state <<= __ffs(dd->idlest_mask);
 
-	while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
+	while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
 	       i < MAX_DPLL_WAIT_TRIES) {
 		i++;
 		udelay(1);
@@ -104,6 +336,42 @@ static int _omap3_wait_dpll_status(struc
 	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 + 1);
+
+	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 */
 
 /*
@@ -128,25 +396,20 @@ static int _omap3_noncore_dpll_lock(stru
 
 	ai = omap3_dpll_autoidle_read(clk);
 
+	omap3_dpll_deny_idle(clk);
+
 	_omap3_dpll_write_clken(clk, DPLL_LOCKED);
 
-	if (ai) {
-		/*
-		 * If no downstream clocks are enabled, CM_IDLEST bit
-		 * may never become active, so don't wait for DPLL to lock.
-		 */
-		r = 0;
+	r = _omap3_wait_dpll_status(clk, 1);
+
+	if (ai)
 		omap3_dpll_allow_idle(clk);
-	} else {
-		r = _omap3_wait_dpll_status(clk, 1);
-		omap3_dpll_deny_idle(clk);
-	};
 
 	return r;
 }
 
 /*
- * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * _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
@@ -236,14 +499,25 @@ static int _omap3_noncore_dpll_stop(stru
 static int omap3_noncore_dpll_enable(struct clk *clk)
 {
 	int r;
+	struct dpll_data *dd;
 
 	if (clk == &dpll3_ck)
 		return -EINVAL;
 
-	if (clk->parent->rate == clk_get_rate(clk))
+	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
+	} 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;
 }
@@ -270,6 +544,215 @@ static void omap3_noncore_dpll_disable(s
 	_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);
+
+	return 0;
+}
+
+static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
+{
+	/*
+	 * According to the 12-5 CDP code from TI, "Limitation 2.5"
+	 * on 3430ES1 prevents us from changing DPLL multipliers or dividers
+	 * on DPLL4.
+	 */
+	if (omap_rev() == OMAP3430_REV_ES1_0) {
+		printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
+		       "silicon 'Limitation 2.5' on 3430ES1.\n");
+		return -EINVAL;
+	}
+	return omap3_noncore_dpll_set_rate(clk, rate);
+}
+
+
+/*
+ * CORE DPLL (DPLL3) rate programming functions
+ *
+ * These call into SRAM code to do the actual CM writes, since the SDRAM
+ * is clocked from DPLL3.
+ */
+
+/**
+ * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * 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)
+{
+	u32 new_div = 0;
+	unsigned long validrate, sdrcrate;
+	struct omap_sdrc_params *sp;
+
+	if (!clk || !rate)
+		return -EINVAL;
+
+	if (clk != &dpll3_m2_ck)
+		return -EINVAL;
+
+	if (rate == clk->rate)
+		return 0;
+
+	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+	if (validrate != rate)
+		return -EINVAL;
+
+	sdrcrate = sdrc_ick.rate;
+	if (rate > clk->rate)
+		sdrcrate <<= ((rate / clk->rate) - 1);
+	else
+		sdrcrate >>= ((clk->rate / rate) - 1);
+
+	sp = omap2_sdrc_get_params(sdrcrate);
+	if (!sp)
+		return -EINVAL;
+
+	pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+		validrate);
+	pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
+		sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
+
+	/* REVISIT: SRAM code doesn't support other M2 divisors yet */
+	WARN_ON(new_div != 1 && new_div != 2);
+
+	/* REVISIT: Add SDRC_MR changing to this code also */
+	omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
+				  sp->actim_ctrlb, new_div);
+
+	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
@@ -356,9 +839,10 @@ static void omap3_dpll_deny_idle(struct
  * 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 void omap3_clkoutx2_recalc(struct clk *clk)
+static unsigned long omap3_clkoutx2_recalc(struct clk *clk)
 {
 	const struct dpll_data *dd;
+	unsigned long rate;
 	u32 v;
 	struct clk *pclk;
 
@@ -372,17 +856,15 @@ static void omap3_clkoutx2_recalc(struct
 
 	dd = pclk->dpll_data;
 
-	WARN_ON(!dd->control_reg || !dd->enable_mask);
+	WARN_ON(!dd->enable_mask);
 
 	v = __raw_readl(dd->control_reg) & dd->enable_mask;
 	v >>= __ffs(dd->enable_mask);
-	if (v != DPLL_LOCKED)
-		clk->rate = clk->parent->rate;
+	if (v != OMAP3XXX_EN_DPLL_LOCKED)
+		rate = clk->parent->rate;
 	else
-		clk->rate = clk->parent->rate * 2;
-
-	if (clk->flags & RATE_PROPAGATES)
-		propagate_rate(clk);
+		rate = clk->parent->rate * 2;
+	return rate;
 }
 
 /* Common clock code */
@@ -432,7 +914,7 @@ static int __init omap2_clk_arch_init(vo
 
 	/* REVISIT: not yet ready for 343x */
 #if 0
-	if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+	if (clk_set_rate(&virt_prcm_set, mpurate))
 		printk(KERN_ERR "Could not find matching MPU rate\n");
 #endif
 
@@ -450,26 +932,13 @@ arch_initcall(omap2_clk_arch_init);
 int __init omap2_clk_init(void)
 {
 	/* struct prcm_config *prcm; */
-	struct clk **clkp;
+	struct omap_clk *c;
 	/* u32 clkrate; */
 	u32 cpu_clkflg;
 
-	/* REVISIT: Ultimately this will be used for multiboot */
-#if 0
-	if (cpu_is_omap242x()) {
-		cpu_mask = RATE_IN_242X;
-		cpu_clkflg = CLOCK_IN_OMAP242X;
-		clkp = onchip_24xx_clks;
-	} else if (cpu_is_omap2430()) {
-		cpu_mask = RATE_IN_243X;
-		cpu_clkflg = CLOCK_IN_OMAP243X;
-		clkp = onchip_24xx_clks;
-	}
-#endif
 	if (cpu_is_omap34xx()) {
 		cpu_mask = RATE_IN_343X;
-		cpu_clkflg = CLOCK_IN_OMAP343X;
-		clkp = onchip_34xx_clks;
+		cpu_clkflg = CK_343X;
 
 		/*
 		 * Update this if there are further clock changes between ES2
@@ -477,23 +946,24 @@ int __init omap2_clk_init(void)
 		 */
 		if (omap_rev() == OMAP3430_REV_ES1_0) {
 			/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
-			cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
+			cpu_clkflg |= CK_3430ES1;
 		} else {
 			cpu_mask |= RATE_IN_3430ES2;
-			cpu_clkflg |= CLOCK_IN_OMAP3430ES2;
+			cpu_clkflg |= CK_3430ES2;
 		}
 	}
 
 	clk_init(&omap2_clk_functions);
 
-	for (clkp = onchip_34xx_clks;
-	     clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
-	     clkp++) {
-		if ((*clkp)->flags & cpu_clkflg) {
-			clk_register(*clkp);
-			omap2_init_clk_clkdm(*clkp);
+	for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
+		clk_init_one(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
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock34xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock34xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock34xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock34xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,13 +27,14 @@
 #include "prm.h"
 #include "prm-regbits-34xx.h"
 
-static void omap3_dpll_recalc(struct clk *clk);
-static void omap3_clkoutx2_recalc(struct clk *clk);
+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_enable(struct clk *clk);
-static void omap3_noncore_dpll_disable(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
@@ -47,6 +48,10 @@ static void omap3_noncore_dpll_disable(s
  * 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
@@ -57,67 +62,59 @@ static void omap3_noncore_dpll_disable(s
 /* 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		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk secure_32k_fck = {
 	.name		= "secure_32k_fck",
+	.ops		= &clkops_null,
 	.rate		= 32768,
-	.flags		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.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		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk virt_13m_ck = {
 	.name		= "virt_13m_ck",
+	.ops		= &clkops_null,
 	.rate		= 13000000,
-	.flags		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk virt_16_8m_ck = {
 	.name		= "virt_16_8m_ck",
+	.ops		= &clkops_null,
 	.rate		= 16800000,
-	.flags		= CLOCK_IN_OMAP3430ES2 | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk virt_19_2m_ck = {
 	.name		= "virt_19_2m_ck",
+	.ops		= &clkops_null,
 	.rate		= 19200000,
-	.flags		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk virt_26m_ck = {
 	.name		= "virt_26m_ck",
+	.ops		= &clkops_null,
 	.rate		= 26000000,
-	.flags		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static struct clk virt_38_4m_ck = {
 	.name		= "virt_38_4m_ck",
+	.ops		= &clkops_null,
 	.rate		= 38400000,
-	.flags		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.flags		= RATE_FIXED,
 };
 
 static const struct clksel_rate osc_sys_12m_rates[] = {
@@ -164,13 +161,13 @@ static const struct clksel osc_sys_clkse
 /* 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		= CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
-				ALWAYS_ENABLED,
+	.flags		= RATE_FIXED,
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -189,36 +186,34 @@ static const struct clksel sys_clksel[]
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.recalc		= &omap2_clksel_recalc,
 };
 
 static struct clk sys_altclk = {
 	.name		= "sys_altclk",
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.ops		= &clkops_null,
 };
 
 /* Optional external clock input for some McBSPs */
 static struct clk mcbsp_clks = {
 	.name		= "mcbsp_clks",
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
-	.recalc		= &propagate_rate,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.recalc		= &followparent_recalc,
 };
 
@@ -226,16 +221,6 @@ static struct clk sys_clkout1 = {
 
 /* CM CLOCKS */
 
-static const struct clksel_rate dpll_bypass_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dpll_locked_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
-	{ .div = 0 }
-};
-
 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 },
@@ -263,6 +248,9 @@ 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),
@@ -272,18 +260,21 @@ static struct dpll_data dpll1_dd = {
 	.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_bit	= OMAP3430_ST_MPU_CLK_SHIFT,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll1_clkdm",
 	.recalc		= &omap3_dpll_recalc,
 };
 
@@ -293,9 +284,9 @@ static struct clk dpll1_ck = {
  */
 static struct clk dpll1_x2_ck = {
 	.name		= "dpll1_x2_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll1_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll1_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
@@ -311,13 +302,13 @@ static const struct clksel div16_dpll1_x
  */
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll1_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -329,6 +320,9 @@ 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) |
@@ -339,20 +333,21 @@ static struct dpll_data dpll2_dd = {
 	.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_bit	= OMAP3430_ST_IVA2_CLK_SHIFT,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
 	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll2_clkdm",
 	.recalc		= &omap3_dpll_recalc,
 };
 
@@ -367,14 +362,14 @@ static const struct clksel div16_dpll2_m
  */
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll2_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -387,6 +382,9 @@ 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,
@@ -394,17 +392,21 @@ static struct dpll_data dpll3_dd = {
 	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.round_rate	= &omap2_dpll_round_rate,
+	.clkdm_name	= "dpll3_clkdm",
 	.recalc		= &omap3_dpll_recalc,
 };
 
@@ -414,9 +416,9 @@ static struct clk dpll3_ck = {
  */
 static struct clk dpll3_x2_ck = {
 	.name		= "dpll3_x2_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll3_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll3_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
@@ -460,55 +462,34 @@ static const struct clksel div31_dpll3m2
 	{ .parent = NULL }
 };
 
-/*
- * DPLL3 output M2
- * REVISIT: This DPLL output divider must be changed in SRAM, so until
- * that code is ready, this should remain a 'read-only' clksel clock.
- */
+/* 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll3_clkdm",
+	.round_rate	= &omap2_clksel_round_rate,
+	.set_rate	= &omap3_core_dpll_m2_set_rate,
 	.recalc		= &omap2_clksel_recalc,
 };
 
-static const struct clksel core_ck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk core_ck = {
 	.name		= "core_ck",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= core_ck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel dpll3_m2x2_ck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
+	.ops		= &clkops_null,
+	.parent		= &dpll3_m2_ck,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk dpll3_m2x2_ck = {
 	.name		= "dpll3_m2x2_ck",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= dpll3_m2x2_ck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
+	.ops		= &clkops_null,
+	.parent		= &dpll3_x2_ck,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &followparent_recalc,
 };
 
 /* The PWRDN bit is apparently only available on 3430ES2 and above */
@@ -520,42 +501,34 @@ static const struct clksel div16_dpll3_c
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll3_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel emu_core_alwon_ck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk emu_core_alwon_ck = {
 	.name		= "emu_core_alwon_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll3_m3x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.clksel		= emu_core_alwon_ck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
+	.clkdm_name	= "dpll3_clkdm",
+	.recalc		= &followparent_recalc,
 };
 
 /* DPLL4 */
@@ -565,6 +538,9 @@ 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),
@@ -574,20 +550,21 @@ static struct dpll_data dpll4_dd = {
 	.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_bit	= OMAP3430_ST_PERIPH_CLK_SHIFT,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
 	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_dpll4_set_rate,
+	.clkdm_name	= "dpll4_clkdm",
 	.recalc		= &omap3_dpll_recalc,
 };
 
@@ -598,9 +575,9 @@ static struct clk dpll4_ck = {
  */
 static struct clk dpll4_x2_ck = {
 	.name		= "dpll4_x2_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll4_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll4_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
@@ -612,112 +589,101 @@ static const struct clksel div16_dpll4_c
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel omap_96m_alwon_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
+/*
+ * 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,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= omap_96m_alwon_fck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				 PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
-static struct clk omap_96m_fck = {
-	.name		= "omap_96m_fck",
+static struct clk cm_96m_fck = {
+	.name		= "cm_96m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_96m_alwon_fck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.recalc		= &followparent_recalc,
 };
 
-static const struct clksel cm_96m_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
+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 cm_96m_fck = {
-	.name		= "cm_96m_fck",
-	.parent		= &dpll4_m2x2_ck,
+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_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= cm_96m_fck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
 	.recalc		= &omap3_clkoutx2_recalc,
 };
 
-static const struct clksel virt_omap_54m_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
-static struct clk virt_omap_54m_fck = {
-	.name		= "virt_omap_54m_fck",
-	.parent		= &dpll4_m3x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= virt_omap_54m_fck_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
 static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
 	{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
 	{ .div = 0 }
@@ -729,23 +695,22 @@ static const struct clksel_rate omap_54m
 };
 
 static const struct clksel omap_54m_clksel[] = {
-	{ .parent = &virt_omap_54m_fck, .rates = omap_54m_d4m3x2_rates },
+	{ .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,
+	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
 	.clksel		= omap_54m_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_clksel_recalc,
 };
 
-static const struct clksel_rate omap_48m_96md2_rates[] = {
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
 	{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
 	{ .div = 0 }
 };
@@ -756,106 +721,112 @@ static const struct clksel_rate omap_48m
 };
 
 static const struct clksel omap_48m_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_48m_96md2_rates },
+	{ .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,
+	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
 	.clksel		= omap_48m_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_clksel_recalc,
 };
 
 static struct clk omap_12m_fck = {
 	.name		= "omap_12m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_48m_fck,
 	.fixed_div	= 4,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.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		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll4_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
@@ -867,6 +838,9 @@ 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),
@@ -876,20 +850,21 @@ static struct dpll_data dpll5_dd = {
 	.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_bit	= OMAP3430ES2_ST_PERIPH2_CLK_SHIFT,
+	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES,
-	.enable		= &omap3_noncore_dpll_enable,
-	.disable	= &omap3_noncore_dpll_disable,
 	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.clkdm_name	= "dpll5_clkdm",
 	.recalc		= &omap3_dpll_recalc,
 };
 
@@ -900,31 +875,13 @@ static const struct clksel div16_dpll5_c
 
 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,
-	.flags		= CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel omap_120m_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_120m_fck = {
-	.name		= "omap_120m_fck",
-	.parent		= &dpll5_m2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.clksel_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.clksel		= omap_120m_fck_clksel,
-	.flags		= CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clkdm_name	= "dpll5_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -951,22 +908,23 @@ static const struct clksel_rate clkout2_
 };
 
 static const struct clksel clkout2_src_clksel[] = {
-	{ .parent = &core_ck,		  .rates = clkout2_src_core_rates },
-	{ .parent = &sys_ck,		  .rates = clkout2_src_sys_rates },
-	{ .parent = &omap_96m_alwon_fck,  .rates = clkout2_src_96m_rates },
-	{ .parent = &omap_54m_fck,	  .rates = clkout2_src_54m_rates },
+	{ .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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+	.clkdm_name	= "core_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -986,11 +944,11 @@ static const struct clksel sys_clkout2_c
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -998,16 +956,22 @@ static struct clk sys_clkout2 = {
 
 static struct clk corex2_fck = {
 	.name		= "corex2_fck",
+	.ops		= &clkops_null,
 	.parent		= &dpll3_m2x2_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.recalc		= &followparent_recalc,
 };
 
 /* DPLL power domain clock controls */
 
-static const struct clksel div2_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div2_rates },
+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 }
 };
 
@@ -1017,39 +981,21 @@ static const struct clksel div2_core_clk
  */
 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		= div2_core_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clksel		= div4_core_clksel,
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/*
- * MPU clksel:
- * If DPLL1 is locked, mpu_ck derives from DPLL1; otherwise, mpu_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll1_fck'
- */
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &dpll1_fck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk mpu_ck = {
 	.name		= "mpu_ck",
+	.ops		= &clkops_null,
 	.parent		= &dpll1_x2m2_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		= mpu_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 /* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
@@ -1066,13 +1012,12 @@ static const struct clksel arm_fck_clkse
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -1084,63 +1029,48 @@ static struct clk arm_fck = {
  */
 static struct clk emu_mpu_alwon_ck = {
 	.name		= "emu_mpu_alwon_ck",
+	.ops		= &clkops_null,
 	.parent		= &mpu_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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		= div2_core_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
+	.clksel		= div4_core_clksel,
 	.recalc		= &omap2_clksel_recalc,
 };
 
-/*
- * IVA2 clksel:
- * If DPLL2 is locked, iva2_ck derives from DPLL2; otherwise, iva2_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll2_fck'
- */
-
-static const struct clksel iva2_clksel[] = {
-	{ .parent = &dpll2_fck,	  .rates = dpll_bypass_rates },
-	{ .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 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,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
-					  OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.clksel		= iva2_clksel,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
 	.clkdm_name	= "iva2_clkdm",
-	.recalc		= &omap2_clksel_recalc,
+	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "core_l3_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -1152,13 +1082,12 @@ static const struct clksel div2_l3_clkse
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 
@@ -1171,12 +1100,12 @@ static const struct clksel div2_l4_clkse
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -1192,53 +1121,52 @@ static const struct clksel gfx_l3_clksel
 /* 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,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK,
 	.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? */
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.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? */
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.clkdm_name	= "gfx_3430es1_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1265,24 +1193,24 @@ static const struct clksel sgx_clksel[]
 
 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_EN_SGX_SHIFT,
+	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.clkdm_name	= "sgx_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
 static struct clk sgx_ick = {
 	.name		= "sgx_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l3_ick,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_SGX_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES2,
+	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
 	.clkdm_name	= "sgx_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1291,11 +1219,11 @@ static struct clk sgx_ick = {
 
 static struct clk d2d_26m_fck = {
 	.name		= "d2d_26m_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &sys_ck,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.clkdm_name	= "d2d_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1308,6 +1236,7 @@ static const struct clksel omap343x_gpt_
 
 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),
@@ -1315,13 +1244,13 @@ static struct clk gpt10_fck = {
 	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
 	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
 	.clksel		= omap343x_gpt_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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),
@@ -1329,35 +1258,34 @@ static struct clk gpt11_fck = {
 	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
 	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
 	.clksel		= omap343x_gpt_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk usbtll_fck = {
 	.name		= "usbtll_fck",
-	.parent		= &omap_120m_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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1365,84 +1293,83 @@ static struct clk usbtll_fck = {
 
 static struct clk core_96m_fck = {
 	.name		= "core_96m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_96m_fck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1469,6 +1396,7 @@ static const struct clksel mcbsp_15_clks
 
 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),
@@ -1476,13 +1404,13 @@ static struct clk mcbsp5_fck = {
 	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
 	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
 	.clksel		= mcbsp_15_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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),
@@ -1490,7 +1418,6 @@ static struct clk mcbsp1_fck = {
 	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
 	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
 	.clksel		= mcbsp_15_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -1499,77 +1426,76 @@ static struct clk mcbsp1_fck = {
 
 static struct clk core_48m_fck = {
 	.name		= "core_48m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_48m_fck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1577,19 +1503,18 @@ static struct clk fshostusb_fck = {
 
 static struct clk core_12m_fck = {
 	.name		= "core_12m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_12m_fck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1612,22 +1537,22 @@ static const struct clksel ssi_ssr_clkse
 
 static struct clk ssi_ssr_fck = {
 	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
 static struct clk ssi_sst_fck = {
 	.name		= "ssi_sst_fck",
+	.ops		= &clkops_null,
 	.parent		= &ssi_ssr_fck,
 	.fixed_div	= 2,
-	.flags		= CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
 	.recalc		= &omap2_fixed_divisor_recalc,
 };
 
@@ -1641,39 +1566,39 @@ static struct clk ssi_sst_fck = {
  */
 static struct clk core_l3_ick = {
 	.name		= "core_l3_ick",
+	.ops		= &clkops_null,
 	.parent		= &l3_ick,
 	.init		= &omap2_init_clk_clkdm,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "core_l3_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk hsotgusb_ick = {
 	.name		= "hsotgusb_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &core_l3_ick,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
 	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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		= CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+	.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		= CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK |
-				ENABLE_ON_INIT,
+	.flags		= ENABLE_ON_INIT, /* huh? */
 	.clkdm_name	= "core_l3_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1682,18 +1607,17 @@ static struct clk gpmc_fck = {
 
 static struct clk security_l3_ick = {
 	.name		= "security_l3_ick",
+	.ops		= &clkops_null,
 	.parent		= &l3_ick,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1701,31 +1625,30 @@ static struct clk pka_ick = {
 
 static struct clk core_l4_ick = {
 	.name		= "core_l4_ick",
+	.ops		= &clkops_null,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clk_clkdm,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1733,250 +1656,251 @@ static struct clk mmchs3_ick = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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		= CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+	.flags		= ENABLE_ON_INIT,
 	.recalc		= &followparent_recalc,
 };
 
@@ -1984,19 +1908,18 @@ static struct clk omapctrl_ick = {
 
 static struct clk ssi_l4_ick = {
 	.name		= "ssi_l4_ick",
+	.ops		= &clkops_null,
 	.parent		= &l4_ick,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk ssi_ick = {
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2011,6 +1934,7 @@ static const struct clksel usb_l4_clksel
 
 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),
@@ -2018,7 +1942,6 @@ static struct clk usb_l4_ick = {
 	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
 	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
 	.clksel		= usb_l4_clksel,
-	.flags		= CLOCK_IN_OMAP3430ES1,
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -2028,98 +1951,87 @@ static struct clk usb_l4_ick = {
 
 static struct clk security_l4_ick2 = {
 	.name		= "security_l4_ick2",
+	.ops		= &clkops_null,
 	.parent		= &l4_ick,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.recalc		= &followparent_recalc,
 };
 
 /* DSS */
-static const struct clksel dss1_alwon_fck_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk dss1_alwon_fck = {
 	.name		= "dss1_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &dpll4_m4x2_ck,
-	.init		= &omap2_init_clksel_parent,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= dss1_alwon_fck_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "dss_clkdm",
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk dss_tv_fck = {
 	.name		= "dss_tv_fck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &omap_54m_fck,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "dss_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk dss2_alwon_fck = {
 	.name		= "dss2_alwon_fck",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &sys_ck,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "dss_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2127,45 +2039,46 @@ static struct clk dss2_alwon_fck = {
 static struct clk dss_ick = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "dss_ick",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "dss_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 /* CAM */
 
-static const struct clksel cam_mclk_clksel[] = {
-	{ .parent = &sys_ck,	    .rates = dpll_bypass_rates },
-	{ .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
-	{ .parent = NULL }
-};
-
 static struct clk cam_mclk = {
 	.name		= "cam_mclk",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &dpll4_m5x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.clksel_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.clksel		= cam_mclk_clksel,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "cam_clkdm",
-	.recalc		= &omap2_clksel_recalc,
+	.recalc		= &followparent_recalc,
 };
 
 static struct clk cam_ick = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "cam_ick",
+	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.flags		= CLOCK_IN_OMAP343X,
+	.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,
+	.init		= &omap2_init_clk_clkdm,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
 	.clkdm_name	= "cam_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2174,22 +2087,22 @@ static struct clk cam_ick = {
 
 static struct clk usbhost_120m_fck = {
 	.name		= "usbhost_120m_fck",
-	.parent		= &omap_120m_fck,
+	.ops		= &clkops_omap2_dflt_wait,
+	.parent		= &dpll5_m2_ck,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.clkdm_name	= "usbhost_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk usbhost_48m_fck = {
 	.name		= "usbhost_48m_fck",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &omap_48m_fck,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.clkdm_name	= "usbhost_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2197,22 +2110,11 @@ static struct clk usbhost_48m_fck = {
 static struct clk usbhost_ick = {
 	/* Handles both L3 and L4 clocks */
 	.name		= "usbhost_ick",
+	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l4_ick,
 	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES2,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_sar_fck = {
-	.name		= "usbhost_sar_fck",
-	.parent		= &osc_sys_ck,
-	.init		= &omap2_init_clk_clkdm,
-	.enable_reg	= OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL),
-	.enable_bit	= OMAP3430ES2_SAVEANDRESTORE_SHIFT,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.clkdm_name	= "usbhost_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2237,7 +2139,7 @@ static const struct clksel_rate usim_120
 
 static const struct clksel usim_clksel[] = {
 	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
-	{ .parent = &omap_120m_fck,	.rates = usim_120m_rates },
+	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
 	{ .parent = &sys_ck,		.rates = div2_rates },
 	{ .parent = NULL },
 };
@@ -2245,63 +2147,63 @@ static const struct clksel usim_clksel[]
 /* 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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
 static struct clk wkup_32k_fck = {
 	.name		= "wkup_32k_fck",
+	.ops		= &clkops_null,
 	.init		= &omap2_init_clk_clkdm,
 	.parent		= &omap_32k_fck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk wkup_l4_ick = {
 	.name		= "wkup_l4_ick",
+	.ops		= &clkops_null,
 	.parent		= &sys_ck,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2310,50 +2212,50 @@ static struct clk wkup_l4_ick = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP3430ES2,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2361,20 +2263,20 @@ static struct clk omap_32ksync_ick = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2385,406 +2287,404 @@ static struct clk gpt1_ick = {
 
 static struct clk per_96m_fck = {
 	.name		= "per_96m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_96m_alwon_fck,
 	.init		= &omap2_init_clk_clkdm,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.clkdm_name	= "per_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk per_48m_fck = {
 	.name		= "per_48m_fck",
+	.ops		= &clkops_null,
 	.parent		= &omap_48m_fck,
 	.init		= &omap2_init_clk_clkdm,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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",
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "per_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk per_l4_ick = {
 	.name		= "per_l4_ick",
+	.ops		= &clkops_null,
 	.parent		= &l4_ick,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES |
-				PARENT_CONTROLS_CLOCK,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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 = &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),
@@ -2792,13 +2692,13 @@ static struct clk mcbsp2_fck = {
 	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
 	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
 	.clksel		= mcbsp_234_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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),
@@ -2806,13 +2706,13 @@ static struct clk mcbsp3_fck = {
 	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
 	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
 	.clksel		= mcbsp_234_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.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),
@@ -2820,7 +2720,6 @@ static struct clk mcbsp4_fck = {
 	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
 	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
 	.clksel		= mcbsp_234_clksel,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "per_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2864,11 +2763,11 @@ static const struct clksel emu_src_clkse
  */
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "emu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2888,11 +2787,11 @@ static const struct clksel pclk_emu_clks
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "emu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2911,11 +2810,11 @@ static const struct clksel pclkx2_emu_cl
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "emu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2927,22 +2826,22 @@ static const struct clksel atclk_emu_clk
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.clkdm_name	= "emu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2961,11 +2860,11 @@ static const struct clksel traceclk_clks
 
 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,
-	.flags		= CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
 	.clkdm_name	= "emu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
@@ -2975,261 +2874,45 @@ static struct clk traceclk_fck = {
 /* 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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
 	.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,
-	.flags		= CLOCK_IN_OMAP343X | RATE_PROPAGATES,
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk sr_l4_ick = {
 	.name		= "sr_l4_ick",
+	.ops		= &clkops_null, /* RMK: missing? */
 	.parent		= &l4_ick,
-	.flags		= CLOCK_IN_OMAP343X,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
 
 /* SECURE_32K_FCK clocks */
 
-/* XXX This clock no longer exists in 3430 TRM rev F */
 static struct clk gpt12_fck = {
 	.name		= "gpt12_fck",
+	.ops		= &clkops_null,
 	.parent		= &secure_32k_fck,
-	.flags		= CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 };
 
 static struct clk wdt1_fck = {
 	.name		= "wdt1_fck",
+	.ops		= &clkops_null,
 	.parent		= &secure_32k_fck,
-	.flags		= CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 };
 
-static struct clk *onchip_34xx_clks[] __initdata = {
-	&omap_32k_fck,
-	&virt_12m_ck,
-	&virt_13m_ck,
-	&virt_16_8m_ck,
-	&virt_19_2m_ck,
-	&virt_26m_ck,
-	&virt_38_4m_ck,
-	&osc_sys_ck,
-	&sys_ck,
-	&sys_altclk,
-	&mcbsp_clks,
-	&sys_clkout1,
-	&dpll1_ck,
-	&dpll1_x2_ck,
-	&dpll1_x2m2_ck,
-	&dpll2_ck,
-	&dpll2_m2_ck,
-	&dpll3_ck,
-	&core_ck,
-	&dpll3_x2_ck,
-	&dpll3_m2_ck,
-	&dpll3_m2x2_ck,
-	&dpll3_m3_ck,
-	&dpll3_m3x2_ck,
-	&emu_core_alwon_ck,
-	&dpll4_ck,
-	&dpll4_x2_ck,
-	&omap_96m_alwon_fck,
-	&omap_96m_fck,
-	&cm_96m_fck,
-	&virt_omap_54m_fck,
-	&omap_54m_fck,
-	&omap_48m_fck,
-	&omap_12m_fck,
-	&dpll4_m2_ck,
-	&dpll4_m2x2_ck,
-	&dpll4_m3_ck,
-	&dpll4_m3x2_ck,
-	&dpll4_m4_ck,
-	&dpll4_m4x2_ck,
-	&dpll4_m5_ck,
-	&dpll4_m5x2_ck,
-	&dpll4_m6_ck,
-	&dpll4_m6x2_ck,
-	&emu_per_alwon_ck,
-	&dpll5_ck,
-	&dpll5_m2_ck,
-	&omap_120m_fck,
-	&clkout2_src_ck,
-	&sys_clkout2,
-	&corex2_fck,
-	&dpll1_fck,
-	&mpu_ck,
-	&arm_fck,
-	&emu_mpu_alwon_ck,
-	&dpll2_fck,
-	&iva2_ck,
-	&l3_ick,
-	&l4_ick,
-	&rm_ick,
-	&gfx_l3_ck,
-	&gfx_l3_fck,
-	&gfx_l3_ick,
-	&gfx_cg1_ck,
-	&gfx_cg2_ck,
-	&sgx_fck,
-	&sgx_ick,
-	&d2d_26m_fck,
-	&gpt10_fck,
-	&gpt11_fck,
-	&cpefuse_fck,
-	&ts_fck,
-	&usbtll_fck,
-	&core_96m_fck,
-	&mmchs3_fck,
-	&mmchs2_fck,
-	&mspro_fck,
-	&mmchs1_fck,
-	&i2c3_fck,
-	&i2c2_fck,
-	&i2c1_fck,
-	&mcbsp5_fck,
-	&mcbsp1_fck,
-	&core_48m_fck,
-	&mcspi4_fck,
-	&mcspi3_fck,
-	&mcspi2_fck,
-	&mcspi1_fck,
-	&uart2_fck,
-	&uart1_fck,
-	&fshostusb_fck,
-	&core_12m_fck,
-	&hdq_fck,
-	&ssi_ssr_fck,
-	&ssi_sst_fck,
-	&core_l3_ick,
-	&hsotgusb_ick,
-	&sdrc_ick,
-	&gpmc_fck,
-	&security_l3_ick,
-	&pka_ick,
-	&core_l4_ick,
-	&usbtll_ick,
-	&mmchs3_ick,
-	&icr_ick,
-	&aes2_ick,
-	&sha12_ick,
-	&des2_ick,
-	&mmchs2_ick,
-	&mmchs1_ick,
-	&mspro_ick,
-	&hdq_ick,
-	&mcspi4_ick,
-	&mcspi3_ick,
-	&mcspi2_ick,
-	&mcspi1_ick,
-	&i2c3_ick,
-	&i2c2_ick,
-	&i2c1_ick,
-	&uart2_ick,
-	&uart1_ick,
-	&gpt11_ick,
-	&gpt10_ick,
-	&mcbsp5_ick,
-	&mcbsp1_ick,
-	&fac_ick,
-	&mailboxes_ick,
-	&omapctrl_ick,
-	&ssi_l4_ick,
-	&ssi_ick,
-	&usb_l4_ick,
-	&security_l4_ick2,
-	&aes1_ick,
-	&rng_ick,
-	&sha11_ick,
-	&des1_ick,
-	&dss1_alwon_fck,
-	&dss_tv_fck,
-	&dss_96m_fck,
-	&dss2_alwon_fck,
-	&dss_ick,
-	&cam_mclk,
-	&cam_ick,
-	&usbhost_120m_fck,
-	&usbhost_48m_fck,
-	&usbhost_ick,
-	&usbhost_sar_fck,
-	&usim_fck,
-	&gpt1_fck,
-	&wkup_32k_fck,
-	&gpio1_dbck,
-	&wdt2_fck,
-	&wkup_l4_ick,
-	&usim_ick,
-	&wdt2_ick,
-	&wdt1_ick,
-	&gpio1_ick,
-	&omap_32ksync_ick,
-	&gpt12_ick,
-	&gpt1_ick,
-	&per_96m_fck,
-	&per_48m_fck,
-	&uart3_fck,
-	&gpt2_fck,
-	&gpt3_fck,
-	&gpt4_fck,
-	&gpt5_fck,
-	&gpt6_fck,
-	&gpt7_fck,
-	&gpt8_fck,
-	&gpt9_fck,
-	&per_32k_alwon_fck,
-	&gpio6_dbck,
-	&gpio5_dbck,
-	&gpio4_dbck,
-	&gpio3_dbck,
-	&gpio2_dbck,
-	&wdt3_fck,
-	&per_l4_ick,
-	&gpio6_ick,
-	&gpio5_ick,
-	&gpio4_ick,
-	&gpio3_ick,
-	&gpio2_ick,
-	&wdt3_ick,
-	&uart3_ick,
-	&gpt9_ick,
-	&gpt8_ick,
-	&gpt7_ick,
-	&gpt6_ick,
-	&gpt5_ick,
-	&gpt4_ick,
-	&gpt3_ick,
-	&gpt2_ick,
-	&mcbsp2_ick,
-	&mcbsp3_ick,
-	&mcbsp4_ick,
-	&mcbsp2_fck,
-	&mcbsp3_fck,
-	&mcbsp4_fck,
-	&emu_src_ck,
-	&pclk_fck,
-	&pclkx2_fck,
-	&atclk_fck,
-	&traceclk_src_fck,
-	&traceclk_fck,
-	&sr1_fck,
-	&sr2_fck,
-	&sr_l4_ick,
-	&secure_32k_fck,
-	&gpt12_fck,
-	&wdt1_fck,
-};
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,11 +26,10 @@
 
 #include <mach/clock.h>
 #include <mach/clockdomain.h>
-#include <mach/sram.h>
 #include <mach/cpu.h>
 #include <asm/div64.h>
 
-#include "memory.h"
+#include <mach/sdrc.h>
 #include "sdrc.h"
 #include "clock.h"
 #include "prm.h"
@@ -46,7 +45,7 @@
 #define DPLL_MIN_DIVIDER		1
 
 /* Possible error results from _dpll_test_mult */
-#define DPLL_MULT_UNDERFLOW		(1 << 0)
+#define DPLL_MULT_UNDERFLOW		-1
 
 /*
  * Scale factor to mitigate roundoff errors in DPLL rate rounding.
@@ -59,6 +58,16 @@
 #define DPLL_ROUNDING_VAL		((DPLL_SCALE_BASE / 2) * \
 					 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
 
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define DPLL_FINT_BAND1_MIN		750000
+#define DPLL_FINT_BAND1_MAX		2100000
+#define DPLL_FINT_BAND2_MIN		7500000
+#define DPLL_FINT_BAND2_MAX		21000000
+
+/* _dpll_test_fint() return codes */
+#define DPLL_FINT_UNDERFLOW		-1
+#define DPLL_FINT_INVALID		-2
+
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
@@ -66,6 +75,74 @@ u8 cpu_mask;
  *-------------------------------------------------------------------------*/
 
 /**
+ * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
+ * @clk: struct clk *
+ *
+ * If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
+ * don't take effect until the VALID_CONFIG bit is written, write the
+ * VALID_CONFIG bit and wait for the write to complete.  No return value.
+ */
+static void _omap2xxx_clk_commit(struct clk *clk)
+{
+	if (!cpu_is_omap24xx())
+		return;
+
+	if (!(clk->flags & DELAYED_APP))
+		return;
+
+	prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
+		OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
+	/* OCP barrier */
+	prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
+}
+
+/*
+ * _dpll_test_fint - test whether an Fint value is valid for the DPLL
+ * @clk: DPLL struct clk to test
+ * @n: divider value (N) to test
+ *
+ * Tests whether a particular divider @n will result in a valid DPLL
+ * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
+ * Correction".  Returns 0 if OK, -1 if the enclosing loop can terminate
+ * (assuming that it is counting N upwards), or -2 if the enclosing loop
+ * should skip to the next iteration (again assuming N is increasing).
+ */
+static int _dpll_test_fint(struct clk *clk, u8 n)
+{
+	struct dpll_data *dd;
+	long fint;
+	int ret = 0;
+
+	dd = clk->dpll_data;
+
+	/* DPLL divider must result in a valid jitter correction val */
+	fint = clk->parent->rate / (n + 1);
+	if (fint < DPLL_FINT_BAND1_MIN) {
+
+		pr_debug("rejecting n=%d due to Fint failure, "
+			 "lowering max_divider\n", n);
+		dd->max_divider = n;
+		ret = DPLL_FINT_UNDERFLOW;
+
+	} else if (fint > DPLL_FINT_BAND1_MAX &&
+		   fint < DPLL_FINT_BAND2_MIN) {
+
+		pr_debug("rejecting n=%d due to Fint failure\n", n);
+		ret = DPLL_FINT_INVALID;
+
+	} else if (fint > DPLL_FINT_BAND2_MAX) {
+
+		pr_debug("rejecting n=%d due to Fint failure, "
+			 "boosting min_divider\n", n);
+		dd->min_divider = n;
+		ret = DPLL_FINT_INVALID;
+
+	}
+
+	return ret;
+}
+
+/**
  * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
  * @clk: OMAP clock struct ptr to use
  *
@@ -120,7 +197,7 @@ void omap2_init_clksel_parent(struct clk
 						 clk->name, clks->parent->name,
 						 ((clk->parent) ?
 						  clk->parent->name : "NULL"));
-					clk->parent = clks->parent;
+					clk_reparent(clk, clks->parent);
 				};
 				found = 1;
 			}
@@ -134,25 +211,52 @@ void omap2_init_clksel_parent(struct clk
 	return;
 }
 
-/* Returns the DPLL rate */
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values.  When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk.  Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
 u32 omap2_get_dpll_rate(struct clk *clk)
 {
 	long long dpll_clk;
-	u32 dpll_mult, dpll_div, dpll;
+	u32 dpll_mult, dpll_div, v;
 	struct dpll_data *dd;
 
 	dd = clk->dpll_data;
-	/* REVISIT: What do we return on error? */
 	if (!dd)
 		return 0;
 
-	dpll = __raw_readl(dd->mult_div1_reg);
-	dpll_mult = dpll & dd->mult_mask;
+	/* Return bypass rate if DPLL is bypassed */
+	v = __raw_readl(dd->control_reg);
+	v &= dd->enable_mask;
+	v >>= __ffs(dd->enable_mask);
+
+	if (cpu_is_omap24xx()) {
+		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
+			return dd->clk_bypass->rate;
+	} else if (cpu_is_omap34xx()) {
+		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
+			return dd->clk_bypass->rate;
+	}
+
+	v = __raw_readl(dd->mult_div1_reg);
+	dpll_mult = v & dd->mult_mask;
 	dpll_mult >>= __ffs(dd->mult_mask);
-	dpll_div = dpll & dd->div1_mask;
+	dpll_div = v & dd->div1_mask;
 	dpll_div >>= __ffs(dd->div1_mask);
 
-	dpll_clk = (long long)clk->parent->rate * dpll_mult;
+	dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
 	do_div(dpll_clk, dpll_div + 1);
 
 	return dpll_clk;
@@ -162,14 +266,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
  * Used for clocks that have the same value as the parent clock,
  * divided by some factor
  */
-void omap2_fixed_divisor_recalc(struct clk *clk)
+unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
 {
 	WARN_ON(!clk->fixed_div);
 
-	clk->rate = clk->parent->rate / clk->fixed_div;
-
-	if (clk->flags & RATE_PROPAGATES)
-		propagate_rate(clk);
+	return clk->parent->rate / clk->fixed_div;
 }
 
 /**
@@ -190,11 +291,10 @@ int omap2_wait_clock_ready(void __iomem
 	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
 	 * 34xx reverses this, just to keep us on our toes
 	 */
-	if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) {
+	if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
 		ena = mask;
-	} else if (cpu_mask & RATE_IN_343X) {
+	else if (cpu_mask & RATE_IN_343X)
 		ena = 0;
-	}
 
 	/* Wait for lock */
 	while (((__raw_readl(reg) & mask) != ena) &&
@@ -228,31 +328,12 @@ static void omap2_clk_wait_ready(struct
 	 * it and pull it into struct clk itself somehow.
 	 */
 	reg = clk->enable_reg;
-	if ((((u32)reg & 0xff) >= CM_FCLKEN1) &&
-	    (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
-		other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
-	else if ((((u32)reg & 0xff) >= CM_ICLKEN1) &&
-		 (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
-		other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
-	else
-		return;
-
-	/* REVISIT: What are the appropriate exclusions for 34XX? */
-	/* No check for DSS or cam clocks */
-	if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
-		if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
-		    clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
-		    clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
-			return;
-	}
 
-	/* REVISIT: What are the appropriate exclusions for 34XX? */
-	/* OMAP3: ignore DSS-mod clocks */
-	if (cpu_is_omap34xx() &&
-	    (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
-	     ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) &&
-	     clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
-		return;
+	/*
+	 * Convert CM_ICLKEN* <-> CM_FCLKEN*.  This conversion assumes
+	 * it's just a matter of XORing the bits.
+	 */
+	other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN));
 
 	/* Check if both functional and interface clocks
 	 * are running. */
@@ -264,18 +345,9 @@ static void omap2_clk_wait_ready(struct
 	omap2_wait_clock_ready(st_reg, bit, clk->name);
 }
 
-/* Enables clock without considering parent dependencies or use count
- * REVISIT: Maybe change this to use clk->enable like on omap1?
- */
-int _omap2_clk_enable(struct clk *clk)
+static int omap2_dflt_clk_enable(struct clk *clk)
 {
-	u32 regval32;
-
-	if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
-		return 0;
-
-	if (clk->enable)
-		return clk->enable(clk);
+	u32 v;
 
 	if (unlikely(clk->enable_reg == NULL)) {
 		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
@@ -283,33 +355,38 @@ int _omap2_clk_enable(struct clk *clk)
 		return 0; /* REVISIT: -EINVAL */
 	}
 
-	regval32 = __raw_readl(clk->enable_reg);
+	v = __raw_readl(clk->enable_reg);
 	if (clk->flags & INVERT_ENABLE)
-		regval32 &= ~(1 << clk->enable_bit);
+		v &= ~(1 << clk->enable_bit);
 	else
-		regval32 |= (1 << clk->enable_bit);
-	__raw_writel(regval32, clk->enable_reg);
-	wmb();
-
-	omap2_clk_wait_ready(clk);
+		v |= (1 << clk->enable_bit);
+	__raw_writel(v, clk->enable_reg);
+	v = __raw_readl(clk->enable_reg); /* OCP barrier */
 
 	return 0;
 }
 
-/* Disables clock without considering parent dependencies or use count */
-void _omap2_clk_disable(struct clk *clk)
+static int omap2_dflt_clk_enable_wait(struct clk *clk)
 {
-	u32 regval32;
-
-	if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
-		return;
+	int ret;
 
-	if (clk->disable) {
-		clk->disable(clk);
-		return;
+	if (!clk->enable_reg) {
+		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+		       clk->name);
+		return 0; /* REVISIT: -EINVAL */
 	}
 
-	if (clk->enable_reg == NULL) {
+	ret = omap2_dflt_clk_enable(clk);
+	if (ret == 0)
+		omap2_clk_wait_ready(clk);
+	return ret;
+}
+
+static void omap2_dflt_clk_disable(struct clk *clk)
+{
+	u32 v;
+
+	if (!clk->enable_reg) {
 		/*
 		 * 'Independent' here refers to a clock which is not
 		 * controlled by its parent.
@@ -319,20 +396,44 @@ void _omap2_clk_disable(struct clk *clk)
 		return;
 	}
 
-	regval32 = __raw_readl(clk->enable_reg);
+	v = __raw_readl(clk->enable_reg);
 	if (clk->flags & INVERT_ENABLE)
-		regval32 |= (1 << clk->enable_bit);
+		v |= (1 << clk->enable_bit);
 	else
-		regval32 &= ~(1 << clk->enable_bit);
-	__raw_writel(regval32, clk->enable_reg);
-	wmb();
+		v &= ~(1 << clk->enable_bit);
+	__raw_writel(v, clk->enable_reg);
+	/* No OCP barrier needed here since it is a disable operation */
+}
+
+const struct clkops clkops_omap2_dflt_wait = {
+	.enable		= omap2_dflt_clk_enable_wait,
+	.disable	= omap2_dflt_clk_disable,
+};
+
+const struct clkops clkops_omap2_dflt = {
+	.enable		= omap2_dflt_clk_enable,
+	.disable	= omap2_dflt_clk_disable,
+};
+
+/* Enables clock without considering parent dependencies or use count
+ * REVISIT: Maybe change this to use clk->enable like on omap1?
+ */
+static int _omap2_clk_enable(struct clk *clk)
+{
+	return clk->ops->enable(clk);
+}
+
+/* Disables clock without considering parent dependencies or use count */
+static void _omap2_clk_disable(struct clk *clk)
+{
+	clk->ops->disable(clk);
 }
 
 void omap2_clk_disable(struct clk *clk)
 {
 	if (clk->usecount > 0 && !(--clk->usecount)) {
 		_omap2_clk_disable(clk);
-		if (likely((u32)clk->parent))
+		if (clk->parent)
 			omap2_clk_disable(clk->parent);
 		if (clk->clkdm)
 			omap2_clkdm_clk_disable(clk->clkdm, clk);
@@ -345,30 +446,29 @@ int omap2_clk_enable(struct clk *clk)
 	int ret = 0;
 
 	if (clk->usecount++ == 0) {
-		if (likely((u32)clk->parent))
-			ret = omap2_clk_enable(clk->parent);
-
-		if (unlikely(ret != 0)) {
-			clk->usecount--;
-			return ret;
-		}
-
 		if (clk->clkdm)
 			omap2_clkdm_clk_enable(clk->clkdm, clk);
 
-		ret = _omap2_clk_enable(clk);
-
-		if (unlikely(ret != 0)) {
-			if (clk->clkdm)
-				omap2_clkdm_clk_disable(clk->clkdm, clk);
+		if (clk->parent) {
+			ret = omap2_clk_enable(clk->parent);
+			if (ret)
+				goto err;
+		}
 
-			if (clk->parent) {
+		ret = _omap2_clk_enable(clk);
+		if (ret) {
+			if (clk->parent)
 				omap2_clk_disable(clk->parent);
-				clk->usecount--;
-			}
+
+			goto err;
 		}
 	}
+	return ret;
 
+err:
+	if (clk->clkdm)
+		omap2_clkdm_clk_disable(clk->clkdm, clk);
+	clk->usecount--;
 	return ret;
 }
 
@@ -376,24 +476,22 @@ int omap2_clk_enable(struct clk *clk)
  * Used for clocks that are part of CLKSEL_xyz governed clocks.
  * REVISIT: Maybe change to use clk->enable() functions like on omap1?
  */
-void omap2_clksel_recalc(struct clk *clk)
+unsigned long omap2_clksel_recalc(struct clk *clk)
 {
+	unsigned long rate;
 	u32 div = 0;
 
 	pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
 
 	div = omap2_clksel_get_divisor(clk);
 	if (div == 0)
-		return;
+		return clk->rate;
 
-	if (unlikely(clk->rate == clk->parent->rate / div))
-		return;
-	clk->rate = clk->parent->rate / div;
+	rate = clk->parent->rate / div;
 
-	pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div);
+	pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
 
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
+	return rate;
 }
 
 /**
@@ -405,8 +503,8 @@ void omap2_clksel_recalc(struct clk *clk
  * the element associated with the supplied parent clock address.
  * Returns a pointer to the struct clksel on success or NULL on error.
  */
-const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
-						struct clk *src_clk)
+static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
+						       struct clk *src_clk)
 {
 	const struct clksel *clks;
 
@@ -455,7 +553,7 @@ u32 omap2_clksel_round_rate_div(struct c
 	*new_div = 1;
 
 	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (clks == NULL)
+	if (!clks)
 		return ~0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
@@ -514,7 +612,7 @@ long omap2_clksel_round_rate(struct clk
 /* Given a clock and a rate apply a clock specific rounding function */
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	if (clk->round_rate != NULL)
+	if (clk->round_rate)
 		return clk->round_rate(clk, rate);
 
 	if (clk->flags & RATE_FIXED)
@@ -540,7 +638,7 @@ u32 omap2_clksel_to_divisor(struct clk *
 	const struct clksel_rate *clkr;
 
 	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (clks == NULL)
+	if (!clks)
 		return 0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
@@ -576,7 +674,7 @@ u32 omap2_divisor_to_clksel(struct clk *
 	WARN_ON(div == 0);
 
 	clks = omap2_get_clksel_by_parent(clk, clk->parent);
-	if (clks == NULL)
+	if (!clks)
 		return ~0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
@@ -595,23 +693,6 @@ u32 omap2_divisor_to_clksel(struct clk *
 }
 
 /**
- * omap2_get_clksel - find clksel register addr & field mask for a clk
- * @clk: struct clk to use
- * @field_mask: ptr to u32 to store the register field mask
- *
- * Returns the address of the clksel register upon success or NULL on error.
- */
-void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
-{
-	if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
-		return NULL;
-
-	*field_mask = clk->clksel_mask;
-
-	return clk->clksel_reg;
-}
-
-/**
  * omap2_clksel_get_divisor - get current divider applied to parent clock.
  * @clk: OMAP struct clk to use.
  *
@@ -619,49 +700,41 @@ void __iomem *omap2_get_clksel(struct cl
  */
 u32 omap2_clksel_get_divisor(struct clk *clk)
 {
-	u32 field_mask, field_val;
-	void __iomem *div_addr;
+	u32 v;
 
-	div_addr = omap2_get_clksel(clk, &field_mask);
-	if (div_addr == NULL)
+	if (!clk->clksel_mask)
 		return 0;
 
-	field_val = __raw_readl(div_addr) & field_mask;
-	field_val >>= __ffs(field_mask);
+	v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+	v >>= __ffs(clk->clksel_mask);
 
-	return omap2_clksel_to_divisor(clk, field_val);
+	return omap2_clksel_to_divisor(clk, v);
 }
 
 int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
 {
-	u32 field_mask, field_val, reg_val, validrate, new_div = 0;
-	void __iomem *div_addr;
+	u32 v, field_val, validrate, new_div = 0;
 
-	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
-	if (validrate != rate)
+	if (!clk->clksel_mask)
 		return -EINVAL;
 
-	div_addr = omap2_get_clksel(clk, &field_mask);
-	if (div_addr == NULL)
+	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+	if (validrate != rate)
 		return -EINVAL;
 
 	field_val = omap2_divisor_to_clksel(clk, new_div);
 	if (field_val == ~0)
 		return -EINVAL;
 
-	reg_val = __raw_readl(div_addr);
-	reg_val &= ~field_mask;
-	reg_val |= (field_val << __ffs(field_mask));
-	__raw_writel(reg_val, div_addr);
-	wmb();
+	v = __raw_readl(clk->clksel_reg);
+	v &= ~clk->clksel_mask;
+	v |= field_val << __ffs(clk->clksel_mask);
+	__raw_writel(v, clk->clksel_reg);
+	v = __raw_readl(clk->clksel_reg); /* OCP barrier */
 
 	clk->rate = clk->parent->rate / new_div;
 
-	if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
-		prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
-			OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
-		wmb();
-	}
+	_omap2xxx_clk_commit(clk);
 
 	return 0;
 }
@@ -680,31 +753,24 @@ int omap2_clk_set_rate(struct clk *clk,
 		return -EINVAL;
 
 	/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
-	if (clk->set_rate != NULL)
+	if (clk->set_rate)
 		ret = clk->set_rate(clk, rate);
 
-	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
-		propagate_rate(clk);
-
 	return ret;
 }
 
 /*
  * Converts encoded control register address into a full address
- * On error, *src_addr will be returned as 0.
+ * On error, the return value (parent_div) will be 0.
  */
-static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
-				      struct clk *src_clk, u32 *field_mask,
-				      struct clk *clk, u32 *parent_div)
+static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
+				       u32 *field_val)
 {
 	const struct clksel *clks;
 	const struct clksel_rate *clkr;
 
-	*parent_div = 0;
-	*src_addr = NULL;
-
 	clks = omap2_get_clksel_by_parent(clk, src_clk);
-	if (clks == NULL)
+	if (!clks)
 		return 0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
@@ -722,47 +788,35 @@ static u32 omap2_clksel_get_src_field(vo
 	/* Should never happen.  Add a clksel mask to the struct clk. */
 	WARN_ON(clk->clksel_mask == 0);
 
-	*field_mask = clk->clksel_mask;
-	*src_addr = clk->clksel_reg;
-	*parent_div = clkr->div;
+	*field_val = clkr->val;
 
-	return clkr->val;
+	return clkr->div;
 }
 
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 {
-	void __iomem *src_addr;
-	u32 field_val, field_mask, reg_val, parent_div;
+	u32 field_val, v, parent_div;
 
-	if (unlikely(clk->flags & CONFIG_PARTICIPANT))
+	if (clk->flags & CONFIG_PARTICIPANT)
 		return -EINVAL;
 
 	if (!clk->clksel)
 		return -EINVAL;
 
-	field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
-					       &field_mask, clk, &parent_div);
-	if (src_addr == NULL)
+	parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
+	if (!parent_div)
 		return -EINVAL;
 
-	if (clk->usecount > 0)
-		omap2_clk_disable(clk);
-
 	/* Set new source value (previous dividers if any in effect) */
-	reg_val = __raw_readl(src_addr) & ~field_mask;
-	reg_val |= (field_val << __ffs(field_mask));
-	__raw_writel(reg_val, src_addr);
-	wmb();
-
-	if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
-		__raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
-		wmb();
-	}
+	v = __raw_readl(clk->clksel_reg);
+	v &= ~clk->clksel_mask;
+	v |= field_val << __ffs(clk->clksel_mask);
+	__raw_writel(v, clk->clksel_reg);
+	v = __raw_readl(clk->clksel_reg);    /* OCP barrier */
 
-	clk->parent = new_parent;
+	_omap2xxx_clk_commit(clk);
 
-	if (clk->usecount > 0)
-		omap2_clk_enable(clk);
+	clk_reparent(clk, new_parent);
 
 	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
 	clk->rate = new_parent->rate;
@@ -773,9 +827,6 @@ int omap2_clk_set_parent(struct clk *clk
 	pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
 		 clk->name, clk->parent->name, clk->rate);
 
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
-
 	return 0;
 }
 
@@ -805,7 +856,8 @@ int omap2_dpll_set_rate_tolerance(struct
 	return 0;
 }
 
-static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n)
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+					    unsigned int m, unsigned int n)
 {
 	unsigned long long num;
 
@@ -838,7 +890,7 @@ static int _dpll_test_mult(int *m, int n
 			   unsigned long target_rate,
 			   unsigned long parent_rate)
 {
-	int flags = 0, carry = 0;
+	int r = 0, carry = 0;
 
 	/* Unscale m and round if necessary */
 	if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
@@ -859,13 +911,13 @@ static int _dpll_test_mult(int *m, int n
 	if (*m < DPLL_MIN_MULTIPLIER) {
 		*m = DPLL_MIN_MULTIPLIER;
 		*new_rate = 0;
-		flags = DPLL_MULT_UNDERFLOW;
+		r = DPLL_MULT_UNDERFLOW;
 	}
 
 	if (*new_rate == 0)
 		*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
 
-	return flags;
+	return r;
 }
 
 /**
@@ -889,54 +941,65 @@ long omap2_dpll_round_rate(struct clk *c
 	int m, n, r, e, scaled_max_m;
 	unsigned long scaled_rt_rp, new_rate;
 	int min_e = -1, min_e_m = -1, min_e_n = -1;
+	struct dpll_data *dd;
 
 	if (!clk || !clk->dpll_data)
 		return ~0;
 
+	dd = clk->dpll_data;
+
 	pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
 		 "%ld\n", clk->name, target_rate);
 
-	scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR);
-	scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR;
+	scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
 
-	clk->dpll_data->last_rounded_rate = 0;
+	dd->last_rounded_rate = 0;
 
-	for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
+	for (n = dd->min_divider; n <= dd->max_divider; n++) {
+
+		/* Is the (input clk, divider) pair valid for the DPLL? */
+		r = _dpll_test_fint(clk, n);
+		if (r == DPLL_FINT_UNDERFLOW)
+			break;
+		else if (r == DPLL_FINT_INVALID)
+			continue;
 
 		/* Compute the scaled DPLL multiplier, based on the divider */
 		m = scaled_rt_rp * n;
 
 		/*
-		 * Since we're counting n down, a m overflow means we can
-		 * can immediately skip to the next n
+		 * Since we're counting n up, a m overflow means we
+		 * can bail out completely (since as n increases in
+		 * the next iteration, there's no way that m can
+		 * increase beyond the current m)
 		 */
 		if (m > scaled_max_m)
-			continue;
+			break;
 
 		r = _dpll_test_mult(&m, n, &new_rate, target_rate,
-				    clk->parent->rate);
+				    dd->clk_ref->rate);
+
+		/* m can't be set low enough for this n - try with a larger n */
+		if (r == DPLL_MULT_UNDERFLOW)
+			continue;
 
 		e = target_rate - new_rate;
 		pr_debug("clock: n = %d: m = %d: rate error is %d "
 			 "(new_rate = %ld)\n", n, m, e, new_rate);
 
 		if (min_e == -1 ||
-		    min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) {
+		    min_e >= (int)(abs(e) - dd->rate_tolerance)) {
 			min_e = e;
 			min_e_m = m;
 			min_e_n = n;
 
 			pr_debug("clock: found new least error %d\n", min_e);
-		}
 
-		/*
-		 * Since we're counting n down, a m underflow means we
-		 * can bail out completely (since as n decreases in
-		 * the next iteration, there's no way that m can
-		 * increase beyond the current m)
-		 */
-		if (r & DPLL_MULT_UNDERFLOW)
-			break;
+			/* We found good settings -- bail out now */
+			if (min_e <= dd->rate_tolerance)
+				break;
+		}
 	}
 
 	if (min_e < 0) {
@@ -944,17 +1007,17 @@ long omap2_dpll_round_rate(struct clk *c
 		return ~0;
 	}
 
-	clk->dpll_data->last_rounded_m = min_e_m;
-	clk->dpll_data->last_rounded_n = min_e_n;
-	clk->dpll_data->last_rounded_rate =
-		_dpll_compute_new_rate(clk->parent->rate, min_e_m,  min_e_n);
+	dd->last_rounded_m = min_e_m;
+	dd->last_rounded_n = min_e_n;
+	dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
+						       min_e_m,  min_e_n);
 
 	pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
 		 min_e, min_e_m, min_e_n);
 	pr_debug("clock: final rate: %ld  (target rate: %ld)\n",
-		 clk->dpll_data->last_rounded_rate, target_rate);
+		 dd->last_rounded_rate, target_rate);
 
-	return clk->dpll_data->last_rounded_rate;
+	return dd->last_rounded_rate;
 }
 
 /*-------------------------------------------------------------------------
@@ -973,6 +1036,10 @@ void omap2_clk_disable_unused(struct clk
 		return;
 
 	printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
-	_omap2_clk_disable(clk);
+	if (cpu_is_omap34xx()) {
+		omap2_clk_enable(clk);
+		omap2_clk_disable(clk);
+	} else
+		_omap2_clk_disable(clk);
 }
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clockdomain.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clockdomain.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clockdomain.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clockdomain.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/limits.h>
+#include <linux/err.h>
 
 #include <linux/io.h>
 
@@ -71,16 +72,13 @@ static void _autodep_lookup(struct clkdm
 	if (!omap_chip_is(autodep->omap_chip))
 		return;
 
-	pwrdm = pwrdm_lookup(autodep->pwrdm_name);
+	pwrdm = pwrdm_lookup(autodep->pwrdm.name);
 	if (!pwrdm) {
-		pr_debug("clockdomain: _autodep_lookup: powerdomain %s "
-			 "does not exist\n", autodep->pwrdm_name);
-		WARN_ON(1);
-		return;
+		pr_err("clockdomain: autodeps: powerdomain %s does not exist\n",
+			 autodep->pwrdm.name);
+		pwrdm = ERR_PTR(-ENOENT);
 	}
-	autodep->pwrdm = pwrdm;
-
-	return;
+	autodep->pwrdm.ptr = pwrdm;
 }
 
 /*
@@ -95,16 +93,19 @@ static void _clkdm_add_autodeps(struct c
 {
 	struct clkdm_pwrdm_autodep *autodep;
 
-	for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
-		if (!autodep->pwrdm)
+	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
+		if (IS_ERR(autodep->pwrdm.ptr))
+			continue;
+
+		if (!omap_chip_is(autodep->omap_chip))
 			continue;
 
 		pr_debug("clockdomain: adding %s sleepdep/wkdep for "
-			 "pwrdm %s\n", autodep->pwrdm_name,
-			 clkdm->pwrdm->name);
+			 "pwrdm %s\n", autodep->pwrdm.ptr->name,
+			 clkdm->pwrdm.ptr->name);
 
-		pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm);
-		pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm);
+		pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+		pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
 	}
 }
 
@@ -120,16 +121,19 @@ static void _clkdm_del_autodeps(struct c
 {
 	struct clkdm_pwrdm_autodep *autodep;
 
-	for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
-		if (!autodep->pwrdm)
+	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
+		if (IS_ERR(autodep->pwrdm.ptr))
+			continue;
+
+		if (!omap_chip_is(autodep->omap_chip))
 			continue;
 
 		pr_debug("clockdomain: removing %s sleepdep/wkdep for "
-			 "pwrdm %s\n", autodep->pwrdm_name,
-			 clkdm->pwrdm->name);
+			 "pwrdm %s\n", autodep->pwrdm.ptr->name,
+			 clkdm->pwrdm.ptr->name);
 
-		pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm);
-		pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm);
+		pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+		pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
 	}
 }
 
@@ -179,7 +183,7 @@ void clkdm_init(struct clockdomain **clk
 
 	autodeps = init_autodeps;
 	if (autodeps)
-		for (autodep = autodeps; autodep->pwrdm_name; autodep++)
+		for (autodep = autodeps; autodep->pwrdm.ptr; autodep++)
 			_autodep_lookup(autodep);
 }
 
@@ -202,20 +206,20 @@ int clkdm_register(struct clockdomain *c
 	if (!omap_chip_is(clkdm->omap_chip))
 		return -EINVAL;
 
-	pwrdm = pwrdm_lookup(clkdm->pwrdm_name);
+	pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
 	if (!pwrdm) {
-		pr_debug("clockdomain: clkdm_register %s: powerdomain %s "
-			 "does not exist\n", clkdm->name, clkdm->pwrdm_name);
+		pr_err("clockdomain: %s: powerdomain %s does not exist\n",
+			clkdm->name, clkdm->pwrdm.name);
 		return -EINVAL;
 	}
-	clkdm->pwrdm = pwrdm;
+	clkdm->pwrdm.ptr = pwrdm;
 
 	mutex_lock(&clkdm_mutex);
 	/* Verify that the clockdomain is not already registered */
 	if (_clkdm_lookup(clkdm->name)) {
 		ret = -EEXIST;
 		goto cr_unlock;
-	};
+	}
 
 	list_add(&clkdm->node, &clkdm_list);
 
@@ -242,7 +246,7 @@ int clkdm_unregister(struct clockdomain
 	if (!clkdm)
 		return -EINVAL;
 
-	pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
+	pwrdm_del_clkdm(clkdm->pwrdm.ptr, clkdm);
 
 	mutex_lock(&clkdm_mutex);
 	list_del(&clkdm->node);
@@ -327,7 +331,7 @@ struct powerdomain *clkdm_get_pwrdm(stru
 	if (!clkdm)
 		return NULL;
 
-	return clkdm->pwrdm;
+	return clkdm->pwrdm.ptr;
 }
 
 
@@ -348,7 +352,7 @@ static int omap2_clkdm_clktrctrl_read(st
 	if (!clkdm)
 		return -EINVAL;
 
-	v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+	v = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
 	v &= clkdm->clktrctrl_mask;
 	v >>= __ffs(clkdm->clktrctrl_mask);
 
@@ -380,7 +384,7 @@ int omap2_clkdm_sleep(struct clockdomain
 	if (cpu_is_omap24xx()) {
 
 		cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
-				    clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+				    clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
 
 	} else if (cpu_is_omap34xx()) {
 
@@ -388,7 +392,7 @@ int omap2_clkdm_sleep(struct clockdomain
 			 __ffs(clkdm->clktrctrl_mask));
 
 		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
-				    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
 
 	} else {
 		BUG();
@@ -422,7 +426,7 @@ int omap2_clkdm_wakeup(struct clockdomai
 	if (cpu_is_omap24xx()) {
 
 		cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
-				      clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+				      clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
 
 	} else if (cpu_is_omap34xx()) {
 
@@ -430,7 +434,7 @@ int omap2_clkdm_wakeup(struct clockdomai
 			 __ffs(clkdm->clktrctrl_mask));
 
 		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
-				    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
 
 	} else {
 		BUG();
@@ -478,7 +482,7 @@ void omap2_clkdm_allow_idle(struct clock
 
 	cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
 			    v << __ffs(clkdm->clktrctrl_mask),
-			    clkdm->pwrdm->prcm_offs,
+			    clkdm->pwrdm.ptr->prcm_offs,
 			    CM_CLKSTCTRL);
 }
 
@@ -516,7 +520,7 @@ void omap2_clkdm_deny_idle(struct clockd
 
 	cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
 			    v << __ffs(clkdm->clktrctrl_mask),
-			    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+			    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
 
 	if (atomic_read(&clkdm->usecount) > 0)
 		_clkdm_del_autodeps(clkdm);
@@ -567,6 +571,8 @@ int omap2_clkdm_clk_enable(struct clockd
 	else
 		omap2_clkdm_wakeup(clkdm);
 
+	pwrdm_wait_transition(clkdm->pwrdm.ptr);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clockdomains.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clockdomains.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clockdomains.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clockdomains.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,12 +14,29 @@
 
 /*
  * OMAP2/3-common clockdomains
+ *
+ * Even though the 2420 has a single PRCM module from the
+ * interconnect's perspective, internally it does appear to have
+ * separate PRM and CM clockdomains.  The usual test case is
+ * sys_clkout/sys_clkout2.
  */
 
 /* This is an implicit clockdomain - it is never defined as such in TRM */
 static struct clockdomain wkup_clkdm = {
 	.name		= "wkup_clkdm",
-	.pwrdm_name	= "wkup_pwrdm",
+	.pwrdm		= { .name = "wkup_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain prm_clkdm = {
+	.name		= "prm_clkdm",
+	.pwrdm		= { .name = "wkup_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cm_clkdm = {
+	.name		= "cm_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
 };
 
@@ -31,7 +48,7 @@ static struct clockdomain wkup_clkdm = {
 
 static struct clockdomain mpu_2420_clkdm = {
 	.name		= "mpu_clkdm",
-	.pwrdm_name	= "mpu_pwrdm",
+	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -39,7 +56,7 @@ static struct clockdomain mpu_2420_clkdm
 
 static struct clockdomain iva1_2420_clkdm = {
 	.name		= "iva1_clkdm",
-	.pwrdm_name	= "dsp_pwrdm",
+	.pwrdm		= { .name = "dsp_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -56,7 +73,7 @@ static struct clockdomain iva1_2420_clkd
 
 static struct clockdomain mpu_2430_clkdm = {
 	.name		= "mpu_clkdm",
-	.pwrdm_name	= "mpu_pwrdm",
+	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -64,7 +81,7 @@ static struct clockdomain mpu_2430_clkdm
 
 static struct clockdomain mdm_clkdm = {
 	.name		= "mdm_clkdm",
-	.pwrdm_name	= "mdm_pwrdm",
+	.pwrdm		= { .name = "mdm_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -81,7 +98,7 @@ static struct clockdomain mdm_clkdm = {
 
 static struct clockdomain dsp_clkdm = {
 	.name		= "dsp_clkdm",
-	.pwrdm_name	= "dsp_pwrdm",
+	.pwrdm		= { .name = "dsp_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -89,7 +106,7 @@ static struct clockdomain dsp_clkdm = {
 
 static struct clockdomain gfx_24xx_clkdm = {
 	.name		= "gfx_clkdm",
-	.pwrdm_name	= "gfx_pwrdm",
+	.pwrdm		= { .name = "gfx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -97,7 +114,7 @@ static struct clockdomain gfx_24xx_clkdm
 
 static struct clockdomain core_l3_24xx_clkdm = {
 	.name		= "core_l3_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -105,7 +122,7 @@ static struct clockdomain core_l3_24xx_c
 
 static struct clockdomain core_l4_24xx_clkdm = {
 	.name		= "core_l4_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -113,7 +130,7 @@ static struct clockdomain core_l4_24xx_c
 
 static struct clockdomain dss_24xx_clkdm = {
 	.name		= "dss_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -130,7 +147,7 @@ static struct clockdomain dss_24xx_clkdm
 
 static struct clockdomain mpu_34xx_clkdm = {
 	.name		= "mpu_clkdm",
-	.pwrdm_name	= "mpu_pwrdm",
+	.pwrdm		= { .name = "mpu_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -138,7 +155,7 @@ static struct clockdomain mpu_34xx_clkdm
 
 static struct clockdomain neon_clkdm = {
 	.name		= "neon_clkdm",
-	.pwrdm_name	= "neon_pwrdm",
+	.pwrdm		= { .name = "neon_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -146,7 +163,7 @@ static struct clockdomain neon_clkdm = {
 
 static struct clockdomain iva2_clkdm = {
 	.name		= "iva2_clkdm",
-	.pwrdm_name	= "iva2_pwrdm",
+	.pwrdm		= { .name = "iva2_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -154,7 +171,7 @@ static struct clockdomain iva2_clkdm = {
 
 static struct clockdomain gfx_3430es1_clkdm = {
 	.name		= "gfx_clkdm",
-	.pwrdm_name	= "gfx_pwrdm",
+	.pwrdm		= { .name = "gfx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
@@ -162,10 +179,10 @@ static struct clockdomain gfx_3430es1_cl
 
 static struct clockdomain sgx_clkdm = {
 	.name		= "sgx_clkdm",
-	.pwrdm_name	= "sgx_pwrdm",
+	.pwrdm		= { .name = "sgx_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 };
 
 /*
@@ -177,7 +194,7 @@ static struct clockdomain sgx_clkdm = {
  */
 static struct clockdomain d2d_clkdm = {
 	.name		= "d2d_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -185,7 +202,7 @@ static struct clockdomain d2d_clkdm = {
 
 static struct clockdomain core_l3_34xx_clkdm = {
 	.name		= "core_l3_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -193,7 +210,7 @@ static struct clockdomain core_l3_34xx_c
 
 static struct clockdomain core_l4_34xx_clkdm = {
 	.name		= "core_l4_clkdm",
-	.pwrdm_name	= "core_pwrdm",
+	.pwrdm		= { .name = "core_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -201,7 +218,7 @@ static struct clockdomain core_l4_34xx_c
 
 static struct clockdomain dss_34xx_clkdm = {
 	.name		= "dss_clkdm",
-	.pwrdm_name	= "dss_pwrdm",
+	.pwrdm		= { .name = "dss_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -209,7 +226,7 @@ static struct clockdomain dss_34xx_clkdm
 
 static struct clockdomain cam_clkdm = {
 	.name		= "cam_clkdm",
-	.pwrdm_name	= "cam_pwrdm",
+	.pwrdm		= { .name = "cam_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -217,28 +234,62 @@ static struct clockdomain cam_clkdm = {
 
 static struct clockdomain usbhost_clkdm = {
 	.name		= "usbhost_clkdm",
-	.pwrdm_name	= "usbhost_pwrdm",
+	.pwrdm		= { .name = "usbhost_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
-	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 };
 
 static struct clockdomain per_clkdm = {
 	.name		= "per_clkdm",
-	.pwrdm_name	= "per_pwrdm",
+	.pwrdm		= { .name = "per_pwrdm" },
 	.flags		= CLKDM_CAN_HWSUP_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/*
+ * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
+ * switched of even if sdti is in use
+ */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
-	.pwrdm_name	= "emu_pwrdm",
-	.flags		= CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP,
+	.pwrdm		= { .name = "emu_pwrdm" },
+	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+static struct clockdomain dpll1_clkdm = {
+	.name		= "dpll1_clkdm",
+	.pwrdm		= { .name = "dpll1_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll2_clkdm = {
+	.name		= "dpll2_clkdm",
+	.pwrdm		= { .name = "dpll2_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll3_clkdm = {
+	.name		= "dpll3_clkdm",
+	.pwrdm		= { .name = "dpll3_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll4_clkdm = {
+	.name		= "dpll4_clkdm",
+	.pwrdm		= { .name = "dpll4_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll5_clkdm = {
+	.name		= "dpll5_clkdm",
+	.pwrdm		= { .name = "dpll5_pwrdm" },
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
 #endif   /* CONFIG_ARCH_OMAP34XX */
 
 /*
@@ -247,14 +298,16 @@ static struct clockdomain emu_clkdm = {
 
 static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
 	{
-		.pwrdm_name = "mpu_pwrdm",
+		.pwrdm	   = { .name = "mpu_pwrdm" },
 		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
 	},
 	{
-		.pwrdm_name = "iva2_pwrdm",
+		.pwrdm	   = { .name = "iva2_pwrdm" },
 		.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
 	},
-	{ NULL }
+	{
+		.pwrdm	   = { .name = NULL },
+	}
 };
 
 /*
@@ -264,6 +317,8 @@ static struct clkdm_pwrdm_autodep clkdm_
 static struct clockdomain *clockdomains_omap[] = {
 
 	&wkup_clkdm,
+	&cm_clkdm,
+	&prm_clkdm,
 
 #ifdef CONFIG_ARCH_OMAP2420
 	&mpu_2420_clkdm,
@@ -297,6 +352,11 @@ static struct clockdomain *clockdomains_
 	&usbhost_clkdm,
 	&per_clkdm,
 	&emu_clkdm,
+	&dpll1_clkdm,
+	&dpll2_clkdm,
+	&dpll3_clkdm,
+	&dpll4_clkdm,
+	&dpll5_clkdm,
 #endif
 
 	NULL,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,13 +21,28 @@
 /* The maximum error between a target DPLL rate and the rounded rate in Hz */
 #define DEFAULT_DPLL_RATE_TOLERANCE	50000
 
+/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
+#define CORE_CLK_SRC_32K		0x0
+#define CORE_CLK_SRC_DPLL		0x1
+#define CORE_CLK_SRC_DPLL_X2		0x2
+
+/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP2XXX_EN_DPLL_LPBYPASS		0x1
+#define OMAP2XXX_EN_DPLL_FRBYPASS		0x2
+#define OMAP2XXX_EN_DPLL_LOCKED			0x3
+
+/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP3XXX_EN_DPLL_LPBYPASS		0x5
+#define OMAP3XXX_EN_DPLL_FRBYPASS		0x6
+#define OMAP3XXX_EN_DPLL_LOCKED			0x7
+
 int omap2_clk_init(void);
 int omap2_clk_enable(struct clk *clk);
 void omap2_clk_disable(struct clk *clk);
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
-int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance);
+int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
@@ -36,7 +51,7 @@ void omap2_clk_disable_unused(struct clk
 #define omap2_clk_disable_unused	NULL
 #endif
 
-void omap2_clksel_recalc(struct clk *clk);
+unsigned long omap2_clksel_recalc(struct clk *clk);
 void omap2_init_clk_clkdm(struct clk *clk);
 void omap2_init_clksel_parent(struct clk *clk);
 u32 omap2_clksel_get_divisor(struct clk *clk);
@@ -44,13 +59,16 @@ u32 omap2_clksel_round_rate_div(struct c
 				u32 *new_div);
 u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val);
 u32 omap2_divisor_to_clksel(struct clk *clk, u32 div);
-void omap2_fixed_divisor_recalc(struct clk *clk);
+unsigned long omap2_fixed_divisor_recalc(struct clk *clk);
 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);
 int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
 void omap2_clk_prepare_for_reboot(void);
 
+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 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/cm-regbits-24xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/cm-regbits-24xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/cm-regbits-24xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/cm-regbits-24xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -110,35 +110,56 @@
 #define OMAP24XX_EN_DES					(1 << 0)
 
 /* CM_IDLEST1_CORE specific bits */
-#define OMAP24XX_ST_MAILBOXES				(1 << 30)
-#define OMAP24XX_ST_WDT4				(1 << 29)
-#define OMAP2420_ST_WDT3				(1 << 28)
-#define OMAP24XX_ST_MSPRO				(1 << 27)
-#define OMAP24XX_ST_FAC					(1 << 25)
-#define OMAP2420_ST_EAC					(1 << 24)
-#define OMAP24XX_ST_HDQ					(1 << 23)
-#define OMAP24XX_ST_I2C2				(1 << 20)
-#define OMAP24XX_ST_I2C1				(1 << 19)
-#define OMAP24XX_ST_MCBSP2				(1 << 16)
-#define OMAP24XX_ST_MCBSP1				(1 << 15)
-#define OMAP24XX_ST_DSS					(1 << 0)
+#define OMAP24XX_ST_MAILBOXES_SHIFT			30
+#define OMAP24XX_ST_MAILBOXES_MASK			(1 << 30)
+#define OMAP24XX_ST_WDT4_SHIFT				29
+#define OMAP24XX_ST_WDT4_MASK				(1 << 29)
+#define OMAP2420_ST_WDT3_SHIFT				28
+#define OMAP2420_ST_WDT3_MASK				(1 << 28)
+#define OMAP24XX_ST_MSPRO_SHIFT				27
+#define OMAP24XX_ST_MSPRO_MASK				(1 << 27)
+#define OMAP24XX_ST_FAC_SHIFT				25
+#define OMAP24XX_ST_FAC_MASK				(1 << 25)
+#define OMAP2420_ST_EAC_SHIFT				24
+#define OMAP2420_ST_EAC_MASK				(1 << 24)
+#define OMAP24XX_ST_HDQ_SHIFT				23
+#define OMAP24XX_ST_HDQ_MASK				(1 << 23)
+#define OMAP2420_ST_I2C2_SHIFT				20
+#define OMAP2420_ST_I2C2_MASK				(1 << 20)
+#define OMAP2420_ST_I2C1_SHIFT				19
+#define OMAP2420_ST_I2C1_MASK				(1 << 19)
+#define OMAP24XX_ST_MCBSP2_SHIFT			16
+#define OMAP24XX_ST_MCBSP2_MASK				(1 << 16)
+#define OMAP24XX_ST_MCBSP1_SHIFT			15
+#define OMAP24XX_ST_MCBSP1_MASK				(1 << 15)
+#define OMAP24XX_ST_DSS_SHIFT				0
+#define OMAP24XX_ST_DSS_MASK				(1 << 0)
 
 /* CM_IDLEST2_CORE */
-#define OMAP2430_ST_MCBSP5				(1 << 5)
-#define OMAP2430_ST_MCBSP4				(1 << 4)
-#define OMAP2430_ST_MCBSP3				(1 << 3)
-#define OMAP24XX_ST_SSI					(1 << 1)
+#define OMAP2430_ST_MCBSP5_SHIFT			5
+#define OMAP2430_ST_MCBSP5_MASK				(1 << 5)
+#define OMAP2430_ST_MCBSP4_SHIFT				4
+#define OMAP2430_ST_MCBSP4_MASK				(1 << 4)
+#define OMAP2430_ST_MCBSP3_SHIFT				3
+#define OMAP2430_ST_MCBSP3_MASK				(1 << 3)
+#define OMAP24XX_ST_SSI_SHIFT				1
+#define OMAP24XX_ST_SSI_MASK				(1 << 1)
 
 /* CM_IDLEST3_CORE */
 /* 2430 only */
-#define OMAP2430_ST_SDRC				(1 << 2)
+#define OMAP2430_ST_SDRC_MASK				(1 << 2)
 
 /* CM_IDLEST4_CORE */
-#define OMAP24XX_ST_PKA					(1 << 4)
-#define OMAP24XX_ST_AES					(1 << 3)
-#define OMAP24XX_ST_RNG					(1 << 2)
-#define OMAP24XX_ST_SHA					(1 << 1)
-#define OMAP24XX_ST_DES					(1 << 0)
+#define OMAP24XX_ST_PKA_SHIFT				4
+#define OMAP24XX_ST_PKA_MASK				(1 << 4)
+#define OMAP24XX_ST_AES_SHIFT				3
+#define OMAP24XX_ST_AES_MASK				(1 << 3)
+#define OMAP24XX_ST_RNG_SHIFT				2
+#define OMAP24XX_ST_RNG_MASK				(1 << 2)
+#define OMAP24XX_ST_SHA_SHIFT				1
+#define OMAP24XX_ST_SHA_MASK				(1 << 1)
+#define OMAP24XX_ST_DES_SHIFT				0
+#define OMAP24XX_ST_DES_MASK				(1 << 0)
 
 /* CM_AUTOIDLE1_CORE */
 #define OMAP24XX_AUTO_CAM				(1 << 31)
@@ -275,11 +296,16 @@
 #define OMAP24XX_EN_32KSYNC				(1 << 1)
 
 /* CM_IDLEST_WKUP specific bits */
-#define OMAP2430_ST_ICR					(1 << 6)
-#define OMAP24XX_ST_OMAPCTRL				(1 << 5)
-#define OMAP24XX_ST_WDT1				(1 << 4)
-#define OMAP24XX_ST_MPU_WDT				(1 << 3)
-#define OMAP24XX_ST_32KSYNC				(1 << 1)
+#define OMAP2430_ST_ICR_SHIFT				6
+#define OMAP2430_ST_ICR_MASK				(1 << 6)
+#define OMAP24XX_ST_OMAPCTRL_SHIFT			5
+#define OMAP24XX_ST_OMAPCTRL_MASK			(1 << 5)
+#define OMAP24XX_ST_WDT1_SHIFT				4
+#define OMAP24XX_ST_WDT1_MASK				(1 << 4)
+#define OMAP24XX_ST_MPU_WDT_SHIFT			3
+#define OMAP24XX_ST_MPU_WDT_MASK			(1 << 3)
+#define OMAP24XX_ST_32KSYNC_SHIFT			1
+#define OMAP24XX_ST_32KSYNC_MASK			(1 << 1)
 
 /* CM_AUTOIDLE_WKUP */
 #define OMAP24XX_AUTO_OMAPCTRL				(1 << 5)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/cm-regbits-34xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -183,31 +183,58 @@
 #define OMAP3430ES2_EN_CPEFUSE_MASK			(1 << 0)
 
 /* CM_IDLEST1_CORE specific bits */
-#define OMAP3430_ST_ICR					(1 << 29)
-#define OMAP3430_ST_AES2				(1 << 28)
-#define OMAP3430_ST_SHA12				(1 << 27)
-#define OMAP3430_ST_DES2				(1 << 26)
-#define OMAP3430_ST_MSPRO				(1 << 23)
-#define OMAP3430_ST_HDQ					(1 << 22)
-#define OMAP3430ES1_ST_FAC				(1 << 8)
-#define OMAP3430ES1_ST_MAILBOXES			(1 << 7)
-#define OMAP3430_ST_OMAPCTRL				(1 << 6)
-#define OMAP3430_ST_SDMA				(1 << 2)
-#define OMAP3430_ST_SDRC				(1 << 1)
-#define OMAP3430_ST_SSI					(1 << 0)
+#define OMAP3430ES2_ST_MMC3_SHIFT			30
+#define OMAP3430ES2_ST_MMC3_MASK			(1 << 30)
+#define OMAP3430_ST_ICR_SHIFT				29
+#define OMAP3430_ST_ICR_MASK				(1 << 29)
+#define OMAP3430_ST_AES2_SHIFT				28
+#define OMAP3430_ST_AES2_MASK				(1 << 28)
+#define OMAP3430_ST_SHA12_SHIFT				27
+#define OMAP3430_ST_SHA12_MASK				(1 << 27)
+#define OMAP3430_ST_DES2_SHIFT				26
+#define OMAP3430_ST_DES2_MASK				(1 << 26)
+#define OMAP3430_ST_MSPRO_SHIFT				23
+#define OMAP3430_ST_MSPRO_MASK				(1 << 23)
+#define OMAP3430_ST_HDQ_SHIFT				22
+#define OMAP3430_ST_HDQ_MASK				(1 << 22)
+#define OMAP3430ES1_ST_FAC_SHIFT			8
+#define OMAP3430ES1_ST_FAC_MASK				(1 << 8)
+#define OMAP3430ES2_ST_SSI_IDLE_SHIFT			8
+#define OMAP3430ES2_ST_SSI_IDLE_MASK			(1 << 8)
+#define OMAP3430_ST_MAILBOXES_SHIFT			7
+#define OMAP3430_ST_MAILBOXES_MASK			(1 << 7)
+#define OMAP3430_ST_OMAPCTRL_SHIFT			6
+#define OMAP3430_ST_OMAPCTRL_MASK			(1 << 6)
+#define OMAP3430_ST_SDMA_SHIFT				2
+#define OMAP3430_ST_SDMA_MASK				(1 << 2)
+#define OMAP3430_ST_SDRC_SHIFT				1
+#define OMAP3430_ST_SDRC_MASK				(1 << 1)
+#define OMAP3430_ST_SSI_STDBY_SHIFT			0
+#define OMAP3430_ST_SSI_STDBY_MASK			(1 << 0)
 
 /* CM_IDLEST2_CORE */
-#define OMAP3430_ST_PKA					(1 << 4)
-#define OMAP3430_ST_AES1				(1 << 3)
-#define OMAP3430_ST_RNG					(1 << 2)
-#define OMAP3430_ST_SHA11				(1 << 1)
-#define OMAP3430_ST_DES1				(1 << 0)
+#define OMAP3430_ST_PKA_SHIFT				4
+#define OMAP3430_ST_PKA_MASK				(1 << 4)
+#define OMAP3430_ST_AES1_SHIFT				3
+#define OMAP3430_ST_AES1_MASK				(1 << 3)
+#define OMAP3430_ST_RNG_SHIFT				2
+#define OMAP3430_ST_RNG_MASK				(1 << 2)
+#define OMAP3430_ST_SHA11_SHIFT				1
+#define OMAP3430_ST_SHA11_MASK				(1 << 1)
+#define OMAP3430_ST_DES1_SHIFT				0
+#define OMAP3430_ST_DES1_MASK				(1 << 0)
 
 /* CM_IDLEST3_CORE */
 #define OMAP3430ES2_ST_USBTLL_SHIFT			2
 #define OMAP3430ES2_ST_USBTLL_MASK			(1 << 2)
+#define OMAP3430ES2_ST_CPEFUSE_SHIFT			0
+#define OMAP3430ES2_ST_CPEFUSE_MASK			(1 << 0)
 
 /* CM_AUTOIDLE1_CORE */
+#define OMAP3430ES2_AUTO_MMC3				(1 << 30)
+#define OMAP3430ES2_AUTO_MMC3_SHIFT			30
+#define OMAP3430ES2_AUTO_ICR				(1 << 29)
+#define OMAP3430ES2_AUTO_ICR_SHIFT			29
 #define OMAP3430_AUTO_AES2				(1 << 28)
 #define OMAP3430_AUTO_AES2_SHIFT			28
 #define OMAP3430_AUTO_SHA12				(1 << 27)
@@ -276,6 +303,9 @@
 #define OMAP3430_AUTO_DES1_SHIFT			0
 
 /* CM_AUTOIDLE3_CORE */
+#define	OMAP3430ES2_AUTO_USBHOST			(1 << 0)
+#define	OMAP3430ES2_AUTO_USBHOST_SHIFT			0
+#define	OMAP3430ES2_AUTO_USBTLL				(1 << 2)
 #define OMAP3430ES2_AUTO_USBTLL_SHIFT			2
 #define OMAP3430ES2_AUTO_USBTLL_MASK			(1 << 2)
 
@@ -332,8 +362,12 @@
 #define OMAP3430ES1_CLKACTIVITY_GFX_MASK		(1 << 0)
 
 /* CM_FCLKEN_SGX */
-#define OMAP3430ES2_EN_SGX_SHIFT			1
-#define OMAP3430ES2_EN_SGX_MASK				(1 << 1)
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT		1
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK		(1 << 1)
+
+/* CM_ICLKEN_SGX */
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT		0
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_MASK		(1 << 0)
 
 /* CM_CLKSEL_SGX */
 #define OMAP3430ES2_CLKSEL_SGX_SHIFT			0
@@ -349,6 +383,7 @@
 
 /* CM_FCLKEN_WKUP specific bits */
 #define OMAP3430ES2_EN_USIMOCP_SHIFT			9
+#define OMAP3430ES2_EN_USIMOCP_MASK			(1 << 9)
 
 /* CM_ICLKEN_WKUP specific bits */
 #define OMAP3430_EN_WDT1				(1 << 4)
@@ -357,11 +392,18 @@
 #define OMAP3430_EN_32KSYNC_SHIFT			2
 
 /* CM_IDLEST_WKUP specific bits */
-#define OMAP3430_ST_WDT2				(1 << 5)
-#define OMAP3430_ST_WDT1				(1 << 4)
-#define OMAP3430_ST_32KSYNC				(1 << 2)
+#define OMAP3430ES2_ST_USIMOCP_SHIFT			9
+#define OMAP3430ES2_ST_USIMOCP_MASK			(1 << 9)
+#define OMAP3430_ST_WDT2_SHIFT				5
+#define OMAP3430_ST_WDT2_MASK				(1 << 5)
+#define OMAP3430_ST_WDT1_SHIFT				4
+#define OMAP3430_ST_WDT1_MASK				(1 << 4)
+#define OMAP3430_ST_32KSYNC_SHIFT			2
+#define OMAP3430_ST_32KSYNC_MASK			(1 << 2)
 
 /* CM_AUTOIDLE_WKUP */
+#define OMAP3430ES2_AUTO_USIMOCP				(1 << 9)
+#define OMAP3430ES2_AUTO_USIMOCP_SHIFT			9
 #define OMAP3430_AUTO_WDT2				(1 << 5)
 #define OMAP3430_AUTO_WDT2_SHIFT			5
 #define OMAP3430_AUTO_WDT1				(1 << 4)
@@ -426,6 +468,8 @@
 #define OMAP3430_ST_CORE_CLK_MASK			(1 << 0)
 
 /* CM_IDLEST2_CKGEN */
+#define OMAP3430ES2_ST_USIM_CLK_SHIFT			2
+#define OMAP3430ES2_ST_USIM_CLK_MASK			(1 << 2)
 #define OMAP3430ES2_ST_120M_CLK_SHIFT			1
 #define OMAP3430ES2_ST_120M_CLK_MASK			(1 << 1)
 #define OMAP3430ES2_ST_PERIPH2_CLK_SHIFT		0
@@ -449,8 +493,12 @@
 #define OMAP3430_CORE_DPLL_MULT_MASK			(0x7ff << 16)
 #define OMAP3430_CORE_DPLL_DIV_SHIFT			8
 #define OMAP3430_CORE_DPLL_DIV_MASK			(0x7f << 8)
-#define OMAP3430_SOURCE_54M				(1 << 5)
-#define OMAP3430_SOURCE_48M				(1 << 3)
+#define OMAP3430_SOURCE_96M_SHIFT			6
+#define OMAP3430_SOURCE_96M_MASK			(1 << 6)
+#define OMAP3430_SOURCE_54M_SHIFT			5
+#define OMAP3430_SOURCE_54M_MASK			(1 << 5)
+#define OMAP3430_SOURCE_48M_SHIFT			3
+#define OMAP3430_SOURCE_48M_MASK			(1 << 3)
 
 /* CM_CLKSEL2_PLL */
 #define OMAP3430_PERIPH_DPLL_MULT_SHIFT			8
@@ -493,7 +541,12 @@
 #define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT		0
 
 /* CM_IDLEST_DSS */
-#define OMAP3430_ST_DSS					(1 << 0)
+#define OMAP3430ES2_ST_DSS_IDLE_SHIFT			1
+#define OMAP3430ES2_ST_DSS_IDLE_MASK			(1 << 1)
+#define OMAP3430ES2_ST_DSS_STDBY_SHIFT			0
+#define OMAP3430ES2_ST_DSS_STDBY_MASK			(1 << 0)
+#define OMAP3430ES1_ST_DSS_SHIFT			0
+#define OMAP3430ES1_ST_DSS_MASK				(1 << 0)
 
 /* CM_AUTOIDLE_DSS */
 #define OMAP3430_AUTO_DSS				(1 << 0)
@@ -516,6 +569,8 @@
 #define OMAP3430_CLKACTIVITY_DSS_MASK			(1 << 0)
 
 /* CM_FCLKEN_CAM specific bits */
+#define OMAP3430_EN_CSI2				(1 << 1)
+#define OMAP3430_EN_CSI2_SHIFT				1
 
 /* CM_ICLKEN_CAM specific bits */
 
@@ -545,10 +600,14 @@
 /* CM_ICLKEN_PER specific bits */
 
 /* CM_IDLEST_PER */
-#define OMAP3430_ST_WDT3				(1 << 12)
-#define OMAP3430_ST_MCBSP4				(1 << 2)
-#define OMAP3430_ST_MCBSP3				(1 << 1)
-#define OMAP3430_ST_MCBSP2				(1 << 0)
+#define OMAP3430_ST_WDT3_SHIFT				12
+#define OMAP3430_ST_WDT3_MASK				(1 << 12)
+#define OMAP3430_ST_MCBSP4_SHIFT			2
+#define OMAP3430_ST_MCBSP4_MASK				(1 << 2)
+#define OMAP3430_ST_MCBSP3_SHIFT			1
+#define OMAP3430_ST_MCBSP3_MASK				(1 << 1)
+#define OMAP3430_ST_MCBSP2_SHIFT			0
+#define OMAP3430_ST_MCBSP2_MASK				(1 << 0)
 
 /* CM_AUTOIDLE_PER */
 #define OMAP3430_AUTO_GPIO6				(1 << 17)
@@ -676,6 +735,10 @@
 #define OMAP3430ES2_EN_USBHOST_MASK			(1 << 0)
 
 /* CM_IDLEST_USBHOST */
+#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT		1
+#define OMAP3430ES2_ST_USBHOST_IDLE_MASK		(1 << 1)
+#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT		0
+#define OMAP3430ES2_ST_USBHOST_STDBY_MASK		(1 << 0)
 
 /* CM_AUTOIDLE_USBHOST */
 #define OMAP3430ES2_AUTO_USBHOST_SHIFT			0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,16 +25,123 @@
 #include <mach/board.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
-#include <mach/eac.h>
 #include <mach/mmc.h>
 
-#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
-#define OMAP2_MBOX_BASE		IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
+#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
-static struct resource mbox_resources[] = {
+static struct resource cam_resources[] = {
 	{
-		.start		= OMAP2_MBOX_BASE,
-		.end		= OMAP2_MBOX_BASE + 0x11f,
+		.start		= OMAP24XX_CAMERA_BASE,
+		.end		= OMAP24XX_CAMERA_BASE + 0xfff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= INT_24XX_CAM_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device omap_cam_device = {
+	.name		= "omap24xxcam",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(cam_resources),
+	.resource	= cam_resources,
+};
+
+static inline void omap_init_camera(void)
+{
+	platform_device_register(&omap_cam_device);
+}
+
+#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+
+static struct resource omap3isp_resources[] = {
+	{
+		.start		= OMAP3430_ISP_BASE,
+		.end		= OMAP3430_ISP_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CBUFF_BASE,
+		.end		= OMAP3430_ISP_CBUFF_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CCP2_BASE,
+		.end		= OMAP3430_ISP_CCP2_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CCDC_BASE,
+		.end		= OMAP3430_ISP_CCDC_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_HIST_BASE,
+		.end		= OMAP3430_ISP_HIST_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_H3A_BASE,
+		.end		= OMAP3430_ISP_H3A_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_PREV_BASE,
+		.end		= OMAP3430_ISP_PREV_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_RESZ_BASE,
+		.end		= OMAP3430_ISP_RESZ_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_SBL_BASE,
+		.end		= OMAP3430_ISP_SBL_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CSI2A_BASE,
+		.end		= OMAP3430_ISP_CSI2A_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP3430_ISP_CSI2PHY_BASE,
+		.end		= OMAP3430_ISP_CSI2PHY_END,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= INT_34XX_CAM_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device omap3isp_device = {
+	.name		= "omap3isp",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(omap3isp_resources),
+	.resource	= omap3isp_resources,
+};
+
+static inline void omap_init_camera(void)
+{
+	platform_device_register(&omap3isp_device);
+}
+#else
+static inline void omap_init_camera(void)
+{
+}
+#endif
+
+#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
+
+#define MBOX_REG_SIZE	0x120
+
+static struct resource omap2_mbox_resources[] = {
+	{
+		.start		= OMAP24XX_MAILBOX_BASE,
+		.end		= OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
@@ -47,20 +154,40 @@ static struct resource mbox_resources[]
 	},
 };
 
+static struct resource omap3_mbox_resources[] = {
+	{
+		.start		= OMAP34XX_MAILBOX_BASE,
+		.end		= OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= INT_24XX_MAIL_U0_MPU,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
 static struct platform_device mbox_device = {
-	.name		= "mailbox",
+	.name		= "omap2-mailbox",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(mbox_resources),
-	.resource	= mbox_resources,
 };
 
 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;
+	} else {
+		pr_err("%s: platform not supported\n", __func__);
+		return;
+	}
 	platform_device_register(&mbox_device);
 }
 #else
 static inline void omap_init_mbox(void) { }
-#endif
+#endif /* CONFIG_OMAP_MBOX_FWK */
 
 #if defined(CONFIG_OMAP_STI)
 
@@ -227,10 +354,12 @@ static void omap_init_mcspi(void)
 	platform_device_register(&omap2_mcspi1);
 	platform_device_register(&omap2_mcspi2);
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
-	platform_device_register(&omap2_mcspi3);
+	if (cpu_is_omap2430() || cpu_is_omap343x())
+		platform_device_register(&omap2_mcspi3);
 #endif
 #ifdef CONFIG_ARCH_OMAP3
-	platform_device_register(&omap2_mcspi4);
+	if (cpu_is_omap343x())
+		platform_device_register(&omap2_mcspi4);
 #endif
 }
 
@@ -238,38 +367,6 @@ static void omap_init_mcspi(void)
 static inline void omap_init_mcspi(void) {}
 #endif
 
-#ifdef CONFIG_SND_OMAP24XX_EAC
-
-#define OMAP2_EAC_BASE			0x48090000
-
-static struct resource omap2_eac_resources[] = {
-	{
-		.start		= OMAP2_EAC_BASE,
-		.end		= OMAP2_EAC_BASE + 0x109,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device omap2_eac_device = {
-	.name		= "omap24xx-eac",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(omap2_eac_resources),
-	.resource	= omap2_eac_resources,
-	.dev = {
-		.platform_data = NULL,
-	},
-};
-
-void omap_init_eac(struct eac_platform_data *pdata)
-{
-	omap2_eac_device.dev.platform_data = pdata;
-	platform_device_register(&omap2_eac_device);
-}
-
-#else
-void omap_init_eac(struct eac_platform_data *pdata) {}
-#endif
-
 #ifdef CONFIG_OMAP_SHA1_MD5
 static struct resource sha1_md5_resources[] = {
 	{
@@ -348,11 +445,12 @@ static void __init omap_hsmmc_reset(void
 		}
 
 		dummy_pdev.id = i;
-		iclk = clk_get(dev, "mmchs_ick");
+		dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
+		iclk = clk_get(dev, "ick");
 		if (iclk && clk_enable(iclk))
 			iclk = NULL;
 
-		fclk = clk_get(dev, "mmchs_fck");
+		fclk = clk_get(dev, "fck");
 		if (fclk && clk_enable(fclk))
 			fclk = NULL;
 
@@ -506,6 +604,7 @@ static int __init omap2_init_devices(voi
 	 * in alphabetical order so they're easier to sort through.
 	 */
 	omap_hsmmc_reset();
+	omap_init_camera();
 	omap_init_mbox();
 	omap_init_mcspi();
 	omap_hdq_init();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/id.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/id.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/id.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/id.c	2009-06-09 23:05:27.000000000 -0400
@@ -217,8 +217,13 @@ void __init omap2_check_revision(void)
 		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_ES1_0)
+		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");
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/io.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/io.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/io.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,8 +27,8 @@
 #include <mach/mux.h>
 #include <mach/omapfb.h>
 #include <mach/sram.h>
-
-#include "memory.h"
+#include <mach/sdrc.h>
+#include <mach/gpmc.h>
 
 #include "clock.h"
 
@@ -195,12 +195,12 @@ void __init omap2_map_common_io(void)
 	omapfb_reserve_sdram();
 }
 
-void __init omap2_init_common_hw(void)
+void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
 {
 	omap2_mux_init();
 	pwrdm_init(powerdomains_omap);
 	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
 	omap2_clk_init();
-	omap2_init_memory();
+	omap2_sdrc_init(sp);
 	gpmc_init();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -73,9 +73,9 @@ static int omap_check_spurious(unsigned
 	u32 sir, spurious;
 
 	sir = intc_bank_read_reg(&irq_banks[0], INTC_SIR);
-	spurious = sir >> 6;
+	spurious = sir >> 7;
 
-	if (spurious > 1) {
+	if (spurious) {
 		printk(KERN_WARNING "Spurious irq %i: 0x%08x, please flush "
 					"posted write for irq %i\n",
 					irq, sir, previous_irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -58,4 +58,12 @@ config MACH_OVERO
 
 config MACH_OMAP3_PANDORA
 	bool "OMAP3 Pandora"
-	depends on ARCH_OMAP3 && ARCH_OMAP34XX
\ No newline at end of file
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP_3430SDP
+	bool "OMAP 3430 SDP board"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_NOKIA_RX51
+	bool "Nokia RX-51 board"
+	depends on ARCH_OMAP3 && ARCH_OMAP34XX
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mailbox.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mailbox.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mailbox.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mailbox.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * Mailbox reservation modules for OMAP2
+ * Mailbox reservation modules for OMAP2/3
  *
- * Copyright (C) 2006 Nokia Corporation
+ * Copyright (C) 2006-2009 Nokia Corporation
  * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *        and  Paul Mundt <paul.mundt@nokia.com>
+ *        and  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -18,40 +18,22 @@
 #include <mach/mailbox.h>
 #include <mach/irqs.h>
 
-#define MAILBOX_REVISION		0x00
-#define MAILBOX_SYSCONFIG		0x10
-#define MAILBOX_SYSSTATUS		0x14
-#define MAILBOX_MESSAGE_0		0x40
-#define MAILBOX_MESSAGE_1		0x44
-#define MAILBOX_MESSAGE_2		0x48
-#define MAILBOX_MESSAGE_3		0x4c
-#define MAILBOX_MESSAGE_4		0x50
-#define MAILBOX_MESSAGE_5		0x54
-#define MAILBOX_FIFOSTATUS_0		0x80
-#define MAILBOX_FIFOSTATUS_1		0x84
-#define MAILBOX_FIFOSTATUS_2		0x88
-#define MAILBOX_FIFOSTATUS_3		0x8c
-#define MAILBOX_FIFOSTATUS_4		0x90
-#define MAILBOX_FIFOSTATUS_5		0x94
-#define MAILBOX_MSGSTATUS_0		0xc0
-#define MAILBOX_MSGSTATUS_1		0xc4
-#define MAILBOX_MSGSTATUS_2		0xc8
-#define MAILBOX_MSGSTATUS_3		0xcc
-#define MAILBOX_MSGSTATUS_4		0xd0
-#define MAILBOX_MSGSTATUS_5		0xd4
-#define MAILBOX_IRQSTATUS_0		0x100
-#define MAILBOX_IRQENABLE_0		0x104
-#define MAILBOX_IRQSTATUS_1		0x108
-#define MAILBOX_IRQENABLE_1		0x10c
-#define MAILBOX_IRQSTATUS_2		0x110
-#define MAILBOX_IRQENABLE_2		0x114
-#define MAILBOX_IRQSTATUS_3		0x118
-#define MAILBOX_IRQENABLE_3		0x11c
+#define MAILBOX_REVISION		0x000
+#define MAILBOX_SYSCONFIG		0x010
+#define MAILBOX_SYSSTATUS		0x014
+#define MAILBOX_MESSAGE(m)		(0x040 + 4 * (m))
+#define MAILBOX_FIFOSTATUS(m)		(0x080 + 4 * (m))
+#define MAILBOX_MSGSTATUS(m)		(0x0c0 + 4 * (m))
+#define MAILBOX_IRQSTATUS(u)		(0x100 + 8 * (u))
+#define MAILBOX_IRQENABLE(u)		(0x104 + 8 * (u))
 
-static unsigned long mbox_base;
+#define MAILBOX_IRQ_NEWMSG(u)		(1 << (2 * (u)))
+#define MAILBOX_IRQ_NOTFULL(u)		(1 << (2 * (u) + 1))
 
-#define MAILBOX_IRQ_NOTFULL(n)		(1 << (2 * (n) + 1))
-#define MAILBOX_IRQ_NEWMSG(n)		(1 << (2 * (n)))
+#define MBOX_REG_SIZE			0x120
+#define MBOX_NR_REGS			(MBOX_REG_SIZE / sizeof(u32))
+
+static void __iomem *mbox_base;
 
 struct omap_mbox2_fifo {
 	unsigned long msg;
@@ -66,6 +48,7 @@ struct omap_mbox2_priv {
 	unsigned long irqstatus;
 	u32 newmsg_bit;
 	u32 notfull_bit;
+	u32 ctx[MBOX_NR_REGS];
 };
 
 static struct clk *mbox_ick_handle;
@@ -73,14 +56,14 @@ static struct clk *mbox_ick_handle;
 static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
 				  omap_mbox_type_t irq);
 
-static inline unsigned int mbox_read_reg(unsigned int reg)
+static inline unsigned int mbox_read_reg(size_t ofs)
 {
-	return __raw_readl(mbox_base + reg);
+	return __raw_readl(mbox_base + ofs);
 }
 
-static inline void mbox_write_reg(unsigned int val, unsigned int reg)
+static inline void mbox_write_reg(u32 val, size_t ofs)
 {
-	__raw_writel(val, mbox_base + reg);
+	__raw_writel(val, mbox_base + ofs);
 }
 
 /* Mailbox H/W preparations */
@@ -95,6 +78,9 @@ static int omap2_mbox_startup(struct oma
 	}
 	clk_enable(mbox_ick_handle);
 
+	l = mbox_read_reg(MAILBOX_REVISION);
+	pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
+
 	/* set smart-idle & autoidle */
 	l = mbox_read_reg(MAILBOX_SYSCONFIG);
 	l |= 0x00000011;
@@ -183,6 +169,32 @@ static int omap2_mbox_is_irq(struct omap
 	return (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++) {
+		p->ctx[i] = mbox_read_reg(i * sizeof(u32));
+
+		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+			i, p->ctx[i]);
+	}
+}
+
+static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+	int i;
+	struct omap_mbox2_priv *p = mbox->priv;
+
+	for (i = 0; i < MBOX_NR_REGS; i++) {
+		mbox_write_reg(p->ctx[i], i * sizeof(u32));
+
+		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+			i, p->ctx[i]);
+	}
+}
+
 static struct omap_mbox_ops omap2_mbox_ops = {
 	.type		= OMAP_MBOX_TYPE2,
 	.startup	= omap2_mbox_startup,
@@ -195,6 +207,8 @@ static struct omap_mbox_ops omap2_mbox_o
 	.disable_irq	= omap2_mbox_disable_irq,
 	.ack_irq	= omap2_mbox_ack_irq,
 	.is_irq		= omap2_mbox_is_irq,
+	.save_ctx	= omap2_mbox_save_ctx,
+	.restore_ctx	= omap2_mbox_restore_ctx,
 };
 
 /*
@@ -209,15 +223,15 @@ static struct omap_mbox_ops omap2_mbox_o
 /* DSP */
 static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
 	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE_0,
-		.fifo_stat	= MAILBOX_FIFOSTATUS_0,
+		.msg		= MAILBOX_MESSAGE(0),
+		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
 	},
 	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE_1,
-		.msg_stat	= MAILBOX_MSGSTATUS_1,
+		.msg		= MAILBOX_MESSAGE(1),
+		.msg_stat	= MAILBOX_MSGSTATUS(1),
 	},
-	.irqenable	= MAILBOX_IRQENABLE_0,
-	.irqstatus	= MAILBOX_IRQSTATUS_0,
+	.irqenable	= MAILBOX_IRQENABLE(0),
+	.irqstatus	= MAILBOX_IRQSTATUS(0),
 	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
 	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(1),
 };
@@ -229,18 +243,18 @@ struct omap_mbox mbox_dsp_info = {
 };
 EXPORT_SYMBOL(mbox_dsp_info);
 
-/* IVA */
+#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
 static struct omap_mbox2_priv omap2_mbox_iva_priv = {
 	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE_2,
-		.fifo_stat	= MAILBOX_FIFOSTATUS_2,
+		.msg		= MAILBOX_MESSAGE(2),
+		.fifo_stat	= MAILBOX_FIFOSTATUS(2),
 	},
 	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE_3,
-		.msg_stat	= MAILBOX_MSGSTATUS_3,
+		.msg		= MAILBOX_MESSAGE(3),
+		.msg_stat	= MAILBOX_MSGSTATUS(3),
 	},
-	.irqenable	= MAILBOX_IRQENABLE_3,
-	.irqstatus	= MAILBOX_IRQSTATUS_3,
+	.irqenable	= MAILBOX_IRQENABLE(3),
+	.irqstatus	= MAILBOX_IRQSTATUS(3),
 	.notfull_bit	= MAILBOX_IRQ_NOTFULL(2),
 	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(3),
 };
@@ -250,17 +264,12 @@ static struct omap_mbox mbox_iva_info =
 	.ops	= &omap2_mbox_ops,
 	.priv	= &omap2_mbox_iva_priv,
 };
+#endif
 
-static int __init omap2_mbox_probe(struct platform_device *pdev)
+static int __devinit omap2_mbox_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	int ret = 0;
-
-	if (pdev->num_resources != 3) {
-		dev_err(&pdev->dev, "invalid number of resources: %d\n",
-			pdev->num_resources);
-		return -ENODEV;
-	}
+	int ret;
 
 	/* MBOX base */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -268,42 +277,61 @@ static int __init omap2_mbox_probe(struc
 		dev_err(&pdev->dev, "invalid mem resource\n");
 		return -ENODEV;
 	}
-	mbox_base = res->start;
+	mbox_base = ioremap(res->start, res->end - res->start);
+	if (!mbox_base)
+		return -ENOMEM;
 
-	/* DSP IRQ */
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (unlikely(!res)) {
+	/* DSP or IVA2 IRQ */
+	mbox_dsp_info.irq = platform_get_irq(pdev, 0);
+	if (mbox_dsp_info.irq < 0) {
 		dev_err(&pdev->dev, "invalid irq resource\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err_dsp;
 	}
-	mbox_dsp_info.irq = res->start;
 
-	ret = omap_mbox_register(&mbox_dsp_info);
+	ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
+	if (ret)
+		goto err_dsp;
 
-	/* IVA IRQ */
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "invalid irq resource\n");
-		return -ENODEV;
+#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
+	if (cpu_is_omap2420()) {
+		/* IVA IRQ */
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+		if (unlikely(!res)) {
+			dev_err(&pdev->dev, "invalid irq resource\n");
+			ret = -ENODEV;
+			goto err_iva1;
+		}
+		mbox_iva_info.irq = res->start;
+		ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
+		if (ret)
+			goto err_iva1;
 	}
-	mbox_iva_info.irq = res->start;
-
-	ret = omap_mbox_register(&mbox_iva_info);
+#endif
+	return 0;
 
+err_iva1:
+	omap_mbox_unregister(&mbox_dsp_info);
+err_dsp:
+	iounmap(mbox_base);
 	return ret;
 }
 
-static int omap2_mbox_remove(struct platform_device *pdev)
+static int __devexit omap2_mbox_remove(struct platform_device *pdev)
 {
+#if defined(CONFIG_ARCH_OMAP2420)
+	omap_mbox_unregister(&mbox_iva_info);
+#endif
 	omap_mbox_unregister(&mbox_dsp_info);
+	iounmap(mbox_base);
 	return 0;
 }
 
 static struct platform_driver omap2_mbox_driver = {
 	.probe = omap2_mbox_probe,
-	.remove = omap2_mbox_remove,
+	.remove = __devexit_p(omap2_mbox_remove),
 	.driver = {
-		.name = "mailbox",
+		.name = "omap2-mailbox",
 	},
 };
 
@@ -320,4 +348,7 @@ static void __exit omap2_mbox_exit(void)
 module_init(omap2_mbox_init);
 module_exit(omap2_mbox_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap2/3 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, Paul Mundt");
+MODULE_ALIAS("platform:omap2-mailbox");
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
+obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \
 		devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
 		clockdomain.o
 
@@ -14,6 +14,10 @@ obj-$(CONFIG_ARCH_OMAP2420)		+= sram242x
 obj-$(CONFIG_ARCH_OMAP2430)		+= sram243x.o
 obj-$(CONFIG_ARCH_OMAP3)		+= sram34xx.o
 
+# SMS/SDRC
+obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
+# obj-$(CONFIG_ARCH_OMAP3)		+= sdrc3xxx.o
+
 # Power Management
 ifeq ($(CONFIG_PM),y)
 obj-y					+= pm.o
@@ -38,4 +42,14 @@ obj-$(CONFIG_MACH_OVERO)		+= board-overo
 					   mmc-twl4030.o
 obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o \
 					   mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o \
+					   mmc-twl4030.o
 
+obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
+					   board-rx51-peripherals.o \
+					   mmc-twl4030.o
+
+# Platform specific device init code
+ifeq ($(CONFIG_USB_MUSB_SOC),y)
+obj-y					+= usb-musb.o
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mcbsp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mcbsp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mcbsp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mcbsp.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,6 @@
 #include <mach/cpu.h>
 #include <mach/mcbsp.h>
 
-const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
-
 static void omap2_mcbsp2_mux_setup(void)
 {
 	omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
@@ -57,8 +55,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP24XX_MCBSP2_BASE,
@@ -67,8 +63,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 };
 #define OMAP2420_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2420_mcbsp_pdata)
@@ -86,8 +80,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP24XX_MCBSP2_BASE,
@@ -96,8 +88,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP3_BASE,
@@ -106,8 +96,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP4_BASE,
@@ -116,8 +104,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP5_BASE,
@@ -126,8 +112,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 };
 #define OMAP2430_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2430_mcbsp_pdata)
@@ -145,8 +129,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP2_BASE,
@@ -155,8 +137,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP3_BASE,
@@ -165,8 +145,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP4_BASE,
@@ -175,8 +153,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP5_BASE,
@@ -185,8 +161,6 @@ static struct omap_mcbsp_platform_data o
 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_names	= clk_names,
-		.num_clks	= 2,
 	},
 };
 #define OMAP34XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap34xx_mcbsp_pdata)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/memory.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/memory.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/memory.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/memory.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,191 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/memory.c
- *
- * Memory timing related functions for OMAP24XX
- *
- * Copyright (C) 2005 Texas Instruments Inc.
- * Richard Woodruff <r-woodruff2@ti.com>
- *
- * Copyright (C) 2005 Nokia Corporation
- * Tony Lindgren <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.
- */
-
-#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 <mach/common.h>
-#include <mach/clock.h>
-#include <mach/sram.h>
-
-#include "prm.h"
-
-#include "memory.h"
-#include "sdrc.h"
-
-void __iomem *omap2_sdrc_base;
-void __iomem *omap2_sms_base;
-
-static struct memory_timings mem_timings;
-static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
-
-u32 omap2_memory_get_slow_dll_ctrl(void)
-{
-	return mem_timings.slow_dll_ctrl;
-}
-
-u32 omap2_memory_get_fast_dll_ctrl(void)
-{
-	return mem_timings.fast_dll_ctrl;
-}
-
-u32 omap2_memory_get_type(void)
-{
-	return mem_timings.m_type;
-}
-
-/*
- * Check the DLL lock state, and return tue if running in unlock mode.
- * This is needed to compensate for the shifted DLL value in unlock mode.
- */
-u32 omap2_dll_force_needed(void)
-{
-	/* dlla and dllb are a set */
-	u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
-
-	if ((dll_state & (1 << 2)) == (1 << 2))
-		return 1;
-	else
-		return 0;
-}
-
-/*
- * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
- * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
- * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
- */
-u32 omap2_reprogram_sdrc(u32 level, u32 force)
-{
-	u32 dll_ctrl, m_type;
-	u32 prev = curr_perf_level;
-	unsigned long flags;
-
-	if ((curr_perf_level == level) && !force)
-		return prev;
-
-	if (level == CORE_CLK_SRC_DPLL) {
-		dll_ctrl = omap2_memory_get_slow_dll_ctrl();
-	} else if (level == CORE_CLK_SRC_DPLL_X2) {
-		dll_ctrl = omap2_memory_get_fast_dll_ctrl();
-	} else {
-		return prev;
-	}
-
-	m_type = omap2_memory_get_type();
-
-	local_irq_save(flags);
-	__raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP);
-	omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type);
-	curr_perf_level = level;
-	local_irq_restore(flags);
-
-	return prev;
-}
-
-#if !defined(CONFIG_ARCH_OMAP2)
-void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
-				u32 base_cs, u32 force_unlock)
-{
-}
-void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
-				      u32 mem_type)
-{
-}
-#endif
-
-void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
-{
-	unsigned long dll_cnt;
-	u32 fast_dll = 0;
-
-	mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
-
-	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
-	 * In the case of 2422, its ok to use CS1 instead of CS0.
-	 */
-	if (cpu_is_omap2422())
-		mem_timings.base_cs = 1;
-	else
-		mem_timings.base_cs = 0;
-
-	if (mem_timings.m_type != M_DDR)
-		return;
-
-	/* With DDR we need to determine the low frequency DLL value */
-	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
-		mem_timings.dll_mode = M_UNLOCK;
-	else
-		mem_timings.dll_mode = M_LOCK;
-
-	if (mem_timings.base_cs == 0) {
-		fast_dll = sdrc_read_reg(SDRC_DLLA_CTRL);
-		dll_cnt = sdrc_read_reg(SDRC_DLLA_STATUS) & 0xff00;
-	} else {
-		fast_dll = sdrc_read_reg(SDRC_DLLB_CTRL);
-		dll_cnt = sdrc_read_reg(SDRC_DLLB_STATUS) & 0xff00;
-	}
-	if (force_lock_to_unlock_mode) {
-		fast_dll &= ~0xff00;
-		fast_dll |= dll_cnt;		/* Current lock mode */
-	}
-	/* set fast timings with DLL filter disabled */
-	mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
-
-	/* No disruptions, DDR will be offline & C-ABI not followed */
-	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
-			    mem_timings.fast_dll_ctrl,
-			    mem_timings.base_cs,
-			    force_lock_to_unlock_mode);
-	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */
-
-	/* Turn status into unlock ctrl */
-	mem_timings.slow_dll_ctrl |=
-		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
-
-	/* 90 degree phase for anything below 133Mhz + disable DLL filter */
-	mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
-}
-
-void __init omap2_set_globals_memory(struct omap_globals *omap2_globals)
-{
-	omap2_sdrc_base = omap2_globals->sdrc;
-	omap2_sms_base = omap2_globals->sms;
-}
-
-/* turn on smart idle modes for SDRAM scheduler and controller */
-void __init omap2_init_memory(void)
-{
-	u32 l;
-
-	if (!cpu_is_omap2420())
-		return;
-
-	l = sms_read_reg(SMS_SYSCONFIG);
-	l &= ~(0x3 << 3);
-	l |= (0x2 << 3);
-	sms_write_reg(l, SMS_SYSCONFIG);
-
-	l = sdrc_read_reg(SDRC_SYSCONFIG);
-	l &= ~(0x3 << 3);
-	l |= (0x2 << 3);
-	sdrc_write_reg(l, SDRC_SYSCONFIG);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/memory.h
- *
- * Interface for memory timing related functions for OMAP24XX
- *
- * Copyright (C) 2005 Texas Instruments Inc.
- * Richard Woodruff <r-woodruff2@ti.com>
- *
- * Copyright (C) 2005 Nokia Corporation
- * Tony Lindgren <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 ARCH_ARM_MACH_OMAP2_MEMORY_H
-#define ARCH_ARM_MACH_OMAP2_MEMORY_H
-
-/* Memory timings */
-#define M_DDR		1
-#define M_LOCK_CTRL	(1 << 2)
-#define M_UNLOCK	0
-#define M_LOCK		1
-
-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 omap2_init_memory_params(u32 force_lock_to_unlock_mode);
-extern u32 omap2_memory_get_slow_dll_ctrl(void);
-extern u32 omap2_memory_get_fast_dll_ctrl(void);
-extern u32 omap2_memory_get_type(void);
-u32 omap2_dll_force_needed(void);
-u32 omap2_reprogram_sdrc(u32 level, u32 force);
-void __init omap2_init_memory(void);
-void __init gpmc_init(void);
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mmc-twl4030.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mmc-twl4030.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mmc-twl4030.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <mach/control.h>
@@ -44,6 +45,7 @@
 #define VMMC2_315V		0x0c
 #define VMMC2_300V		0x0b
 #define VMMC2_285V		0x0a
+#define VMMC2_280V		0x09
 #define VMMC2_260V		0x08
 #define VMMC2_185V		0x06
 #define VMMC2_DEDICATED		0x2E
@@ -59,8 +61,8 @@ static struct twl_mmc_controller {
 	struct omap_mmc_platform_data	*mmc;
 	u8		twl_vmmc_dev_grp;
 	u8		twl_mmc_dedicated;
-	char		name[HSMMC_NAME_LEN];
-} hsmmc[] = {
+	char		name[HSMMC_NAME_LEN + 1];
+} hsmmc[OMAP34XX_NR_MMC] = {
 	{
 		.twl_vmmc_dev_grp		= VMMC1_DEV_GRP,
 		.twl_mmc_dedicated		= VMMC1_DEDICATED,
@@ -98,6 +100,14 @@ static int twl_mmc_get_ro(struct device
 	return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
 }
 
+static int twl_mmc_get_cover_state(struct device *dev, int slot)
+{
+	struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+	/* NOTE: assumes card detect signal is active-low */
+	return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+}
+
 /*
  * MMC Slot Initialization.
  */
@@ -166,66 +176,85 @@ static int twl_mmc_resume(struct device
 /*
  * Sets the MMC voltage in twl4030
  */
+
+#define MMC1_OCR	(MMC_VDD_165_195 \
+		|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
+#define MMC2_OCR	(MMC_VDD_165_195 \
+		|MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \
+		|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
+
 static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
 {
 	int ret;
-	u8 vmmc, dev_grp_val;
+	u8 vmmc = 0, dev_grp_val;
 
-	switch (1 << vdd) {
-	case MMC_VDD_35_36:
-	case MMC_VDD_34_35:
-	case MMC_VDD_33_34:
-	case MMC_VDD_32_33:
-	case MMC_VDD_31_32:
-	case MMC_VDD_30_31:
-		if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
-			vmmc = VMMC1_315V;
-		else
-			vmmc = VMMC2_315V;
-		break;
-	case MMC_VDD_29_30:
-		if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
-			vmmc = VMMC1_315V;
-		else
-			vmmc = VMMC2_300V;
-		break;
-	case MMC_VDD_27_28:
-	case MMC_VDD_26_27:
-		if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
-			vmmc = VMMC1_285V;
-		else
-			vmmc = VMMC2_285V;
-		break;
-	case MMC_VDD_25_26:
-	case MMC_VDD_24_25:
-	case MMC_VDD_23_24:
-	case MMC_VDD_22_23:
-	case MMC_VDD_21_22:
-	case MMC_VDD_20_21:
-		if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
-			vmmc = VMMC1_285V;
-		else
-			vmmc = VMMC2_260V;
-		break;
-	case MMC_VDD_165_195:
-		if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+	if (!vdd)
+		goto doit;
+
+	if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) {
+		/* VMMC1:  max 220 mA.  And for 8-bit mode,
+		 * VSIM:  max 50 mA
+		 */
+		switch (1 << vdd) {
+		case MMC_VDD_165_195:
 			vmmc = VMMC1_185V;
-		else
+			/* and VSIM_180V */
+			break;
+		case MMC_VDD_28_29:
+			vmmc = VMMC1_285V;
+			/* and VSIM_280V */
+			break;
+		case MMC_VDD_29_30:
+		case MMC_VDD_30_31:
+			vmmc = VMMC1_300V;
+			/* and VSIM_300V */
+			break;
+		case MMC_VDD_31_32:
+			vmmc = VMMC1_315V;
+			/* error if VSIM needed */
+			break;
+		default:
+			return -EINVAL;
+		}
+	} else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) {
+		/* VMMC2:  max 100 mA */
+		switch (1 << vdd) {
+		case MMC_VDD_165_195:
 			vmmc = VMMC2_185V;
-		break;
-	default:
-		vmmc = 0;
-		break;
+			break;
+		case MMC_VDD_25_26:
+		case MMC_VDD_26_27:
+			vmmc = VMMC2_260V;
+			break;
+		case MMC_VDD_27_28:
+			vmmc = VMMC2_280V;
+			break;
+		case MMC_VDD_28_29:
+			vmmc = VMMC2_285V;
+			break;
+		case MMC_VDD_29_30:
+		case MMC_VDD_30_31:
+			vmmc = VMMC2_300V;
+			break;
+		case MMC_VDD_31_32:
+			vmmc = VMMC2_315V;
+			break;
+		default:
+			return -EINVAL;
+		}
+	} else {
+		return -EINVAL;
 	}
 
-	if (vmmc)
+doit:
+	if (vdd)
 		dev_grp_val = VMMC_DEV_GRP_P1;	/* Power up */
 	else
 		dev_grp_val = LDO_CLR;		/* Power down */
 
 	ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
 					dev_grp_val, c->twl_vmmc_dev_grp);
-	if (ret)
+	if (ret || !vdd)
 		return ret;
 
 	ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
@@ -242,6 +271,14 @@ static int twl_mmc1_set_power(struct dev
 	struct twl_mmc_controller *c = &hsmmc[0];
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
 
+	/*
+	 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
+	 * card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both
+	 * 1.8V and 3.0V modes, controlled by the PBIAS register.
+	 *
+	 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
+	 * is most naturally TWL VSIM; those pins also use PBIAS.
+	 */
 	if (power_on) {
 		if (cpu_is_omap2430()) {
 			reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
@@ -298,6 +335,12 @@ static int twl_mmc2_set_power(struct dev
 	struct twl_mmc_controller *c = &hsmmc[1];
 	struct omap_mmc_platform_data *mmc = dev->platform_data;
 
+	/*
+	 * Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP
+	 * VDDS is used to power the pins, optionally with a transceiver to
+	 * support cards using voltages other than VDDS (1.8V nominal).  When a
+	 * transceiver is used, DAT3..7 are muxed as transceiver control pins.
+	 */
 	if (power_on) {
 		if (mmc->slots[0].internal_clock) {
 			u32 reg;
@@ -314,6 +357,16 @@ static int twl_mmc2_set_power(struct dev
 	return ret;
 }
 
+static int twl_mmc3_set_power(struct device *dev, int slot, int power_on,
+		int vdd)
+{
+	/*
+	 * Assume MMC3 has self-powered device connected, for example on-board
+	 * chip with external power source.
+	 */
+	return 0;
+}
+
 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
 
 void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -349,13 +402,13 @@ void __init twl4030_mmc_init(struct twl4
 			return;
 		}
 
-		sprintf(twl->name, "mmc%islot%i", c->mmc, 1);
+		if (c->name)
+			strncpy(twl->name, c->name, HSMMC_NAME_LEN);
+		else
+			snprintf(twl->name, ARRAY_SIZE(twl->name),
+				"mmc%islot%i", c->mmc, 1);
 		mmc->slots[0].name = twl->name;
 		mmc->nr_slots = 1;
-		mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
-					MMC_VDD_26_27 | MMC_VDD_27_28 |
-					MMC_VDD_29_30 |
-					MMC_VDD_30_31 | MMC_VDD_31_32;
 		mmc->slots[0].wires = c->wires;
 		mmc->slots[0].internal_clock = !c->ext_clock;
 		mmc->dma_mask = 0xffffffff;
@@ -369,7 +422,10 @@ void __init twl4030_mmc_init(struct twl4
 
 			mmc->slots[0].switch_pin = c->gpio_cd;
 			mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd);
-			mmc->slots[0].card_detect = twl_mmc_card_detect;
+			if (c->cover_only)
+				mmc->slots[0].get_cover_state = twl_mmc_get_cover_state;
+			else
+				mmc->slots[0].card_detect = twl_mmc_card_detect;
 		} else
 			mmc->slots[0].switch_pin = -EINVAL;
 
@@ -385,24 +441,43 @@ void __init twl4030_mmc_init(struct twl4
 
 		/* NOTE:  we assume OMAP's MMC1 and MMC2 use
 		 * the TWL4030's VMMC1 and VMMC2, respectively;
-		 * and that OMAP's MMC3 isn't used.
+		 * and that MMC3 device has it's own power source.
 		 */
 
 		switch (c->mmc) {
 		case 1:
 			mmc->slots[0].set_power = twl_mmc1_set_power;
+			mmc->slots[0].ocr_mask = MMC1_OCR;
 			break;
 		case 2:
 			mmc->slots[0].set_power = twl_mmc2_set_power;
+			if (c->transceiver)
+				mmc->slots[0].ocr_mask = MMC2_OCR;
+			else
+				mmc->slots[0].ocr_mask = MMC_VDD_165_195;
+			break;
+		case 3:
+			mmc->slots[0].set_power = twl_mmc3_set_power;
+			mmc->slots[0].ocr_mask = MMC_VDD_165_195;
 			break;
 		default:
 			pr_err("MMC%d configuration not supported!\n", c->mmc);
+			kfree(mmc);
 			continue;
 		}
 		hsmmc_data[c->mmc - 1] = mmc;
 	}
 
 	omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
+
+	/* pass the device nodes back to board setup code */
+	for (c = controllers; c->mmc; c++) {
+		struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
+
+		if (!c->mmc || c->mmc > nr_hsmmc)
+			continue;
+		c->dev = mmc->dev;
+	}
 }
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mmc-twl4030.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mmc-twl4030.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mmc-twl4030.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mmc-twl4030.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,9 +9,13 @@
 struct twl4030_hsmmc_info {
 	u8	mmc;		/* controller 1/2/3 */
 	u8	wires;		/* 1/4/8 wires */
+	bool	transceiver;	/* MMC-2 option */
+	bool	ext_clock;	/* use external pin for input clock */
+	bool	cover_only;	/* No card detect - just cover switch */
 	int	gpio_cd;	/* or -EINVAL */
 	int	gpio_wp;	/* or -EINVAL */
-	int	ext_clock:1;	/* use external pin for input clock */
+	char	*name;		/* or NULL for default */
+	struct device *dev;	/* returned: pointer to mmc adapter */
 };
 
 #if	defined(CONFIG_TWL4030_CORE) && \
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mux.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mux.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/mux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/mux.c	2009-06-09 23:05:27.000000000 -0400
@@ -453,10 +453,37 @@ MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TX
 
 
 /* 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("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("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)
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ static struct platform_suspend_ops omap_
 	.valid		= suspend_valid_only_mem,
 };
 
-int __init omap2_pm_init(void)
+static int __init omap2_pm_init(void)
 {
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/powerdomains34xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/powerdomains34xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/powerdomains34xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -200,12 +200,33 @@ static struct powerdomain mpu_34xx_pwrdm
 };
 
 /* No wkdeps or sleepdeps for 34xx core apparently */
-static struct powerdomain core_34xx_pwrdm = {
+static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
 	.name		  = "core_pwrdm",
 	.prcm_offs	  = CORE_MOD,
-	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+					   CHIP_IS_OMAP3430ES2 |
+					   CHIP_IS_OMAP3430ES3_0),
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.dep_bit	  = OMAP3430_EN_CORE_SHIFT,
+	.banks		  = 2,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
+		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+	},
+};
+
+/* No wkdeps or sleepdeps for 34xx core apparently */
+static struct powerdomain core_34xx_es3_1_pwrdm = {
+	.name		  = "core_pwrdm",
+	.prcm_offs	  = CORE_MOD,
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.dep_bit	  = OMAP3430_EN_CORE_SHIFT,
+	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
 	.banks		  = 2,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
@@ -236,14 +257,19 @@ static struct powerdomain dss_pwrdm = {
 	},
 };
 
+/*
+ * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
+ * possible SGX powerstate, the SGX device itself does not support
+ * retention.
+ */
 static struct powerdomain sgx_pwrdm = {
 	.name		  = "sgx_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
-	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 	.wkdep_srcs	  = gfx_sgx_wkdeps,
 	.sleepdep_srcs	  = cam_gfx_sleepdeps,
 	/* XXX This is accurate for 3430 SGX, but what about GFX? */
-	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts		  = PWRSTS_OFF_ON,
 	.pwrsts_logic_ret = PWRDM_POWER_RET,
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
@@ -307,11 +333,12 @@ static struct powerdomain neon_pwrdm = {
 static struct powerdomain usbhost_pwrdm = {
 	.name		  = "usbhost_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
-	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+	.omap_chip	  = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
 	.wkdep_srcs	  = per_usbhost_wkdeps,
 	.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 */
 	.banks		  = 1,
 	.pwrsts_mem_ret	  = {
 		[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
@@ -321,6 +348,37 @@ static struct powerdomain usbhost_pwrdm
 	},
 };
 
+static struct powerdomain dpll1_pwrdm = {
+	.name		= "dpll1_pwrdm",
+	.prcm_offs	= MPU_MOD,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll2_pwrdm = {
+	.name		= "dpll2_pwrdm",
+	.prcm_offs	= OMAP3430_IVA2_MOD,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll3_pwrdm = {
+	.name		= "dpll3_pwrdm",
+	.prcm_offs	= PLL_MOD,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll4_pwrdm = {
+	.name		= "dpll4_pwrdm",
+	.prcm_offs	= PLL_MOD,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll5_pwrdm = {
+	.name		= "dpll5_pwrdm",
+	.prcm_offs	= PLL_MOD,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+
 #endif    /* CONFIG_ARCH_OMAP34XX */
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/powerdomains.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/powerdomains.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/powerdomains.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/powerdomains.h	2009-06-09 23:05:27.000000000 -0400
@@ -171,13 +171,19 @@ static struct powerdomain *powerdomains_
 	&iva2_pwrdm,
 	&mpu_34xx_pwrdm,
 	&neon_pwrdm,
-	&core_34xx_pwrdm,
+	&core_34xx_pre_es3_1_pwrdm,
+	&core_34xx_es3_1_pwrdm,
 	&cam_pwrdm,
 	&dss_pwrdm,
 	&per_pwrdm,
 	&emu_pwrdm,
 	&sgx_pwrdm,
 	&usbhost_pwrdm,
+	&dpll1_pwrdm,
+	&dpll2_pwrdm,
+	&dpll3_pwrdm,
+	&dpll4_pwrdm,
+	&dpll5_pwrdm,
 #endif
 
 	NULL
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prcm-common.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prcm-common.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prcm-common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prcm-common.h	2009-06-09 23:05:27.000000000 -0400
@@ -113,33 +113,58 @@
 #define OMAP2430_EN_USBHS				(1 << 6)
 
 /* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */
-#define OMAP2420_ST_MMC					(1 << 26)
-#define OMAP24XX_ST_UART2				(1 << 22)
-#define OMAP24XX_ST_UART1				(1 << 21)
-#define OMAP24XX_ST_MCSPI2				(1 << 18)
-#define OMAP24XX_ST_MCSPI1				(1 << 17)
-#define OMAP24XX_ST_GPT12				(1 << 14)
-#define OMAP24XX_ST_GPT11				(1 << 13)
-#define OMAP24XX_ST_GPT10				(1 << 12)
-#define OMAP24XX_ST_GPT9				(1 << 11)
-#define OMAP24XX_ST_GPT8				(1 << 10)
-#define OMAP24XX_ST_GPT7				(1 << 9)
-#define OMAP24XX_ST_GPT6				(1 << 8)
-#define OMAP24XX_ST_GPT5				(1 << 7)
-#define OMAP24XX_ST_GPT4				(1 << 6)
-#define OMAP24XX_ST_GPT3				(1 << 5)
-#define OMAP24XX_ST_GPT2				(1 << 4)
-#define OMAP2420_ST_VLYNQ				(1 << 3)
+#define OMAP2420_ST_MMC_SHIFT				26
+#define OMAP2420_ST_MMC_MASK				(1 << 26)
+#define OMAP24XX_ST_UART2_SHIFT				22
+#define OMAP24XX_ST_UART2_MASK				(1 << 22)
+#define OMAP24XX_ST_UART1_SHIFT				21
+#define OMAP24XX_ST_UART1_MASK				(1 << 21)
+#define OMAP24XX_ST_MCSPI2_SHIFT			18
+#define OMAP24XX_ST_MCSPI2_MASK				(1 << 18)
+#define OMAP24XX_ST_MCSPI1_SHIFT			17
+#define OMAP24XX_ST_MCSPI1_MASK				(1 << 17)
+#define OMAP24XX_ST_GPT12_SHIFT				14
+#define OMAP24XX_ST_GPT12_MASK				(1 << 14)
+#define OMAP24XX_ST_GPT11_SHIFT				13
+#define OMAP24XX_ST_GPT11_MASK				(1 << 13)
+#define OMAP24XX_ST_GPT10_SHIFT				12
+#define OMAP24XX_ST_GPT10_MASK				(1 << 12)
+#define OMAP24XX_ST_GPT9_SHIFT				11
+#define OMAP24XX_ST_GPT9_MASK				(1 << 11)
+#define OMAP24XX_ST_GPT8_SHIFT				10
+#define OMAP24XX_ST_GPT8_MASK				(1 << 10)
+#define OMAP24XX_ST_GPT7_SHIFT				9
+#define OMAP24XX_ST_GPT7_MASK				(1 << 9)
+#define OMAP24XX_ST_GPT6_SHIFT				8
+#define OMAP24XX_ST_GPT6_MASK				(1 << 8)
+#define OMAP24XX_ST_GPT5_SHIFT				7
+#define OMAP24XX_ST_GPT5_MASK				(1 << 7)
+#define OMAP24XX_ST_GPT4_SHIFT				6
+#define OMAP24XX_ST_GPT4_MASK				(1 << 6)
+#define OMAP24XX_ST_GPT3_SHIFT				5
+#define OMAP24XX_ST_GPT3_MASK				(1 << 5)
+#define OMAP24XX_ST_GPT2_SHIFT				4
+#define OMAP24XX_ST_GPT2_MASK				(1 << 4)
+#define OMAP2420_ST_VLYNQ_SHIFT				3
+#define OMAP2420_ST_VLYNQ_MASK				(1 << 3)
 
 /* CM_IDLEST2_CORE, PM_WKST2_CORE shared bits */
-#define OMAP2430_ST_MDM_INTC				(1 << 11)
-#define OMAP2430_ST_GPIO5				(1 << 10)
-#define OMAP2430_ST_MCSPI3				(1 << 9)
-#define OMAP2430_ST_MMCHS2				(1 << 8)
-#define OMAP2430_ST_MMCHS1				(1 << 7)
-#define OMAP2430_ST_USBHS				(1 << 6)
-#define OMAP24XX_ST_UART3				(1 << 2)
-#define OMAP24XX_ST_USB					(1 << 0)
+#define OMAP2430_ST_MDM_INTC_SHIFT			11
+#define OMAP2430_ST_MDM_INTC_MASK			(1 << 11)
+#define OMAP2430_ST_GPIO5_SHIFT				10
+#define OMAP2430_ST_GPIO5_MASK				(1 << 10)
+#define OMAP2430_ST_MCSPI3_SHIFT			9
+#define OMAP2430_ST_MCSPI3_MASK				(1 << 9)
+#define OMAP2430_ST_MMCHS2_SHIFT			8
+#define OMAP2430_ST_MMCHS2_MASK				(1 << 8)
+#define OMAP2430_ST_MMCHS1_SHIFT			7
+#define OMAP2430_ST_MMCHS1_MASK				(1 << 7)
+#define OMAP2430_ST_USBHS_SHIFT				6
+#define OMAP2430_ST_USBHS_MASK				(1 << 6)
+#define OMAP24XX_ST_UART3_SHIFT				2
+#define OMAP24XX_ST_UART3_MASK				(1 << 2)
+#define OMAP24XX_ST_USB_SHIFT				0
+#define OMAP24XX_ST_USB_MASK				(1 << 0)
 
 /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
 #define OMAP24XX_EN_GPIOS_SHIFT				2
@@ -148,11 +173,13 @@
 #define OMAP24XX_EN_GPT1				(1 << 0)
 
 /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS				(1 << 2)
-#define OMAP24XX_ST_GPT1				(1 << 0)
+#define OMAP24XX_ST_GPIOS_SHIFT				(1 << 2)
+#define OMAP24XX_ST_GPIOS_MASK				2
+#define OMAP24XX_ST_GPT1_SHIFT				(1 << 0)
+#define OMAP24XX_ST_GPT1_MASK				0
 
 /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM					(1 << 0)
+#define OMAP2430_ST_MDM_SHIFT				(1 << 0)
 
 
 /* 3430 register bits shared between CM & PRM registers */
@@ -205,24 +232,46 @@
 #define OMAP3430_EN_HSOTGUSB_SHIFT				4
 
 /* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */
-#define OMAP3430_ST_MMC2				(1 << 25)
-#define OMAP3430_ST_MMC1				(1 << 24)
-#define OMAP3430_ST_MCSPI4				(1 << 21)
-#define OMAP3430_ST_MCSPI3				(1 << 20)
-#define OMAP3430_ST_MCSPI2				(1 << 19)
-#define OMAP3430_ST_MCSPI1				(1 << 18)
-#define OMAP3430_ST_I2C3				(1 << 17)
-#define OMAP3430_ST_I2C2				(1 << 16)
-#define OMAP3430_ST_I2C1				(1 << 15)
-#define OMAP3430_ST_UART2				(1 << 14)
-#define OMAP3430_ST_UART1				(1 << 13)
-#define OMAP3430_ST_GPT11				(1 << 12)
-#define OMAP3430_ST_GPT10				(1 << 11)
-#define OMAP3430_ST_MCBSP5				(1 << 10)
-#define OMAP3430_ST_MCBSP1				(1 << 9)
-#define OMAP3430_ST_FSHOSTUSB				(1 << 5)
-#define OMAP3430_ST_HSOTGUSB				(1 << 4)
-#define OMAP3430_ST_D2D					(1 << 3)
+#define OMAP3430_ST_MMC2_SHIFT				25
+#define OMAP3430_ST_MMC2_MASK				(1 << 25)
+#define OMAP3430_ST_MMC1_SHIFT				24
+#define OMAP3430_ST_MMC1_MASK				(1 << 24)
+#define OMAP3430_ST_MCSPI4_SHIFT			21
+#define OMAP3430_ST_MCSPI4_MASK				(1 << 21)
+#define OMAP3430_ST_MCSPI3_SHIFT			20
+#define OMAP3430_ST_MCSPI3_MASK				(1 << 20)
+#define OMAP3430_ST_MCSPI2_SHIFT			19
+#define OMAP3430_ST_MCSPI2_MASK				(1 << 19)
+#define OMAP3430_ST_MCSPI1_SHIFT			18
+#define OMAP3430_ST_MCSPI1_MASK				(1 << 18)
+#define OMAP3430_ST_I2C3_SHIFT				17
+#define OMAP3430_ST_I2C3_MASK				(1 << 17)
+#define OMAP3430_ST_I2C2_SHIFT				16
+#define OMAP3430_ST_I2C2_MASK				(1 << 16)
+#define OMAP3430_ST_I2C1_SHIFT				15
+#define OMAP3430_ST_I2C1_MASK				(1 << 15)
+#define OMAP3430_ST_UART2_SHIFT				14
+#define OMAP3430_ST_UART2_MASK				(1 << 14)
+#define OMAP3430_ST_UART1_SHIFT				13
+#define OMAP3430_ST_UART1_MASK				(1 << 13)
+#define OMAP3430_ST_GPT11_SHIFT				12
+#define OMAP3430_ST_GPT11_MASK				(1 << 12)
+#define OMAP3430_ST_GPT10_SHIFT				11
+#define OMAP3430_ST_GPT10_MASK				(1 << 11)
+#define OMAP3430_ST_MCBSP5_SHIFT			10
+#define OMAP3430_ST_MCBSP5_MASK				(1 << 10)
+#define OMAP3430_ST_MCBSP1_SHIFT			9
+#define OMAP3430_ST_MCBSP1_MASK				(1 << 9)
+#define OMAP3430ES1_ST_FSHOSTUSB_SHIFT			5
+#define OMAP3430ES1_ST_FSHOSTUSB_MASK			(1 << 5)
+#define OMAP3430ES1_ST_HSOTGUSB_SHIFT			4
+#define OMAP3430ES1_ST_HSOTGUSB_MASK			(1 << 4)
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT		5
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_MASK		(1 << 5)
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT		4
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_MASK		(1 << 4)
+#define OMAP3430_ST_D2D_SHIFT				3
+#define OMAP3430_ST_D2D_MASK				(1 << 3)
 
 /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
 #define OMAP3430_EN_GPIO1				(1 << 3)
@@ -241,11 +290,16 @@
 #define OMAP3430_EN_GPT12_SHIFT				1
 
 /* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */
-#define OMAP3430_ST_SR2					(1 << 7)
-#define OMAP3430_ST_SR1					(1 << 6)
-#define OMAP3430_ST_GPIO1				(1 << 3)
-#define OMAP3430_ST_GPT12				(1 << 1)
-#define OMAP3430_ST_GPT1				(1 << 0)
+#define OMAP3430_ST_SR2_SHIFT				7
+#define OMAP3430_ST_SR2_MASK				(1 << 7)
+#define OMAP3430_ST_SR1_SHIFT				6
+#define OMAP3430_ST_SR1_MASK				(1 << 6)
+#define OMAP3430_ST_GPIO1_SHIFT				3
+#define OMAP3430_ST_GPIO1_MASK				(1 << 3)
+#define OMAP3430_ST_GPT12_SHIFT				1
+#define OMAP3430_ST_GPT12_MASK				(1 << 1)
+#define OMAP3430_ST_GPT1_SHIFT				0
+#define OMAP3430_ST_GPT1_MASK				(1 << 0)
 
 /*
  * CM_SLEEPDEP_GFX, CM_SLEEPDEP_DSS, CM_SLEEPDEP_CAM,
@@ -296,20 +350,34 @@
 #define OMAP3430_EN_MCBSP2_SHIFT			0
 
 /* CM_IDLEST_PER, PM_WKST_PER shared bits */
-#define OMAP3430_ST_GPIO6				(1 << 17)
-#define OMAP3430_ST_GPIO5				(1 << 16)
-#define OMAP3430_ST_GPIO4				(1 << 15)
-#define OMAP3430_ST_GPIO3				(1 << 14)
-#define OMAP3430_ST_GPIO2				(1 << 13)
-#define OMAP3430_ST_UART3				(1 << 11)
-#define OMAP3430_ST_GPT9				(1 << 10)
-#define OMAP3430_ST_GPT8				(1 << 9)
-#define OMAP3430_ST_GPT7				(1 << 8)
-#define OMAP3430_ST_GPT6				(1 << 7)
-#define OMAP3430_ST_GPT5				(1 << 6)
-#define OMAP3430_ST_GPT4				(1 << 5)
-#define OMAP3430_ST_GPT3				(1 << 4)
-#define OMAP3430_ST_GPT2				(1 << 3)
+#define OMAP3430_ST_GPIO6_SHIFT				17
+#define OMAP3430_ST_GPIO6_MASK				(1 << 17)
+#define OMAP3430_ST_GPIO5_SHIFT				16
+#define OMAP3430_ST_GPIO5_MASK				(1 << 16)
+#define OMAP3430_ST_GPIO4_SHIFT				15
+#define OMAP3430_ST_GPIO4_MASK				(1 << 15)
+#define OMAP3430_ST_GPIO3_SHIFT				14
+#define OMAP3430_ST_GPIO3_MASK				(1 << 14)
+#define OMAP3430_ST_GPIO2_SHIFT				13
+#define OMAP3430_ST_GPIO2_MASK				(1 << 13)
+#define OMAP3430_ST_UART3_SHIFT				11
+#define OMAP3430_ST_UART3_MASK				(1 << 11)
+#define OMAP3430_ST_GPT9_SHIFT				10
+#define OMAP3430_ST_GPT9_MASK				(1 << 10)
+#define OMAP3430_ST_GPT8_SHIFT				9
+#define OMAP3430_ST_GPT8_MASK				(1 << 9)
+#define OMAP3430_ST_GPT7_SHIFT				8
+#define OMAP3430_ST_GPT7_MASK				(1 << 8)
+#define OMAP3430_ST_GPT6_SHIFT				7
+#define OMAP3430_ST_GPT6_MASK				(1 << 7)
+#define OMAP3430_ST_GPT5_SHIFT				6
+#define OMAP3430_ST_GPT5_MASK				(1 << 6)
+#define OMAP3430_ST_GPT4_SHIFT				5
+#define OMAP3430_ST_GPT4_MASK				(1 << 5)
+#define OMAP3430_ST_GPT3_SHIFT				4
+#define OMAP3430_ST_GPT3_MASK				(1 << 4)
+#define OMAP3430_ST_GPT2_SHIFT				3
+#define OMAP3430_ST_GPT2_MASK				(1 << 3)
 
 /* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
 #define OMAP3430_EN_CORE_SHIFT				0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prm.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prm.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prm.h	2009-06-09 23:05:27.000000000 -0400
@@ -141,6 +141,19 @@
 #define PM_PWSTCTRL					0x00e0
 #define PM_PWSTST					0x00e4
 
+/* Omap2 specific registers */
+#define OMAP24XX_PM_WKEN2				0x00a4
+#define OMAP24XX_PM_WKST2				0x00b4
+
+#define OMAP24XX_PRCM_IRQSTATUS_DSP			0x00f0	/* IVA mod */
+#define OMAP24XX_PRCM_IRQENABLE_DSP			0x00f4	/* IVA mod */
+#define OMAP24XX_PRCM_IRQSTATUS_IVA			0x00f8
+#define OMAP24XX_PRCM_IRQENABLE_IVA			0x00fc
+
+/* Omap3 specific registers */
+#define OMAP3430ES2_PM_WKEN3				0x00f0
+#define OMAP3430ES2_PM_WKST3				0x00b8
+
 #define OMAP3430_PM_MPUGRPSEL				0x00a4
 #define OMAP3430_PM_MPUGRPSEL1				OMAP3430_PM_MPUGRPSEL
 
@@ -153,16 +166,6 @@
 #define OMAP3430_PRM_IRQENABLE_IVA2			0x00fc
 
 
-/* Architecture-specific registers */
-
-#define OMAP24XX_PM_WKEN2				0x00a4
-#define OMAP24XX_PM_WKST2				0x00b4
-
-#define OMAP24XX_PRCM_IRQSTATUS_DSP			0x00f0	/* IVA mod */
-#define OMAP24XX_PRCM_IRQENABLE_DSP			0x00f4	/* IVA mod */
-#define OMAP24XX_PRCM_IRQSTATUS_IVA			0x00f8
-#define OMAP24XX_PRCM_IRQENABLE_IVA			0x00fc
-
 #ifndef __ASSEMBLER__
 
 /* Power/reset management domain register get/set */
@@ -228,7 +231,6 @@ static inline u32 prm_clear_mod_reg_bits
 #define OMAP_RSTTIME1_SHIFT				0
 #define OMAP_RSTTIME1_MASK				(0xff << 0)
 
-
 /* PRM_RSTCTRL */
 /* Named RM_RSTCTRL_WKUP on the 24xx */
 /* 2420 calls RST_DPLL3 'RST_DPLL' */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/prm-regbits-34xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -366,6 +366,7 @@
 
 /* PM_WKEN_WKUP specific bits */
 #define OMAP3430_EN_IO					(1 << 8)
+#define OMAP3430_EN_GPIO1				(1 << 3)
 
 /* PM_MPUGRPSEL_WKUP specific bits */
 
@@ -408,7 +409,7 @@
 /* PM_PREPWSTST_CAM specific bits */
 
 /* PM_PWSTCTRL_USBHOST specific bits */
-#define OMAP3430ES2_SAVEANDRESTORE_SHIFT		(1 << 4)
+#define OMAP3430ES2_SAVEANDRESTORE_SHIFT		4
 
 /* RM_RSTST_PER specific bits */
 
@@ -452,6 +453,14 @@
 #define OMAP3430_CMDRA0_MASK				(0xff << 0)
 
 /* PRM_VC_CMD_VAL_0 specific bits */
+#define OMAP3430_VC_CMD_ON_SHIFT			24
+#define OMAP3430_VC_CMD_ON_MASK				(0xFF << 24)
+#define OMAP3430_VC_CMD_ONLP_SHIFT			16
+#define OMAP3430_VC_CMD_ONLP_MASK			(0xFF << 16)
+#define OMAP3430_VC_CMD_RET_SHIFT			8
+#define OMAP3430_VC_CMD_RET_MASK			(0xFF << 8)
+#define OMAP3430_VC_CMD_OFF_SHIFT			0
+#define OMAP3430_VC_CMD_OFF_MASK			(0xFF << 0)
 
 /* PRM_VC_CMD_VAL_1 specific bits */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/sdrc2xxx.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/sdrc2xxx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/sdrc2xxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/sdrc2xxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * linux/arch/arm/mach-omap2/sdrc2xxx.c
+ *
+ * SDRAM timing related functions for OMAP2xxx
+ *
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
+ *
+ * Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@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/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 <mach/common.h>
+#include <mach/clock.h>
+#include <mach/sram.h>
+
+#include "prm.h"
+#include "clock.h"
+#include <mach/sdrc.h>
+#include "sdrc.h"
+
+/* Memory timing, DLL mode flags */
+#define M_DDR		1
+#define M_LOCK_CTRL	(1 << 2)
+#define M_UNLOCK	0
+#define M_LOCK		1
+
+
+static struct memory_timings mem_timings;
+static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
+
+static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void)
+{
+	return mem_timings.slow_dll_ctrl;
+}
+
+static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void)
+{
+	return mem_timings.fast_dll_ctrl;
+}
+
+static u32 omap2xxx_sdrc_get_type(void)
+{
+	return mem_timings.m_type;
+}
+
+/*
+ * Check the DLL lock state, and return tue if running in unlock mode.
+ * This is needed to compensate for the shifted DLL value in unlock mode.
+ */
+u32 omap2xxx_sdrc_dll_is_unlocked(void)
+{
+	/* dlla and dllb are a set */
+	u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
+
+	if ((dll_state & (1 << 2)) == (1 << 2))
+		return 1;
+	else
+		return 0;
+}
+
+/*
+ * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
+ * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
+ * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
+ *
+ * Used by the clock framework during CORE DPLL changes
+ */
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
+{
+	u32 dll_ctrl, m_type;
+	u32 prev = curr_perf_level;
+	unsigned long flags;
+
+	if ((curr_perf_level == level) && !force)
+		return prev;
+
+	if (level == CORE_CLK_SRC_DPLL)
+		dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl();
+	else if (level == CORE_CLK_SRC_DPLL_X2)
+		dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl();
+	else
+		return prev;
+
+	m_type = omap2xxx_sdrc_get_type();
+
+	local_irq_save(flags);
+	__raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP);
+	omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type);
+	curr_perf_level = level;
+	local_irq_restore(flags);
+
+	return prev;
+}
+
+/* Used by the clock framework during CORE DPLL changes */
+void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode)
+{
+	unsigned long dll_cnt;
+	u32 fast_dll = 0;
+
+	/* DDR = 1, SDR = 0 */
+	mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1);
+
+	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
+	 * In the case of 2422, its ok to use CS1 instead of CS0.
+	 */
+	if (cpu_is_omap2422())
+		mem_timings.base_cs = 1;
+	else
+		mem_timings.base_cs = 0;
+
+	if (mem_timings.m_type != M_DDR)
+		return;
+
+	/* With DDR we need to determine the low frequency DLL value */
+	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
+		mem_timings.dll_mode = M_UNLOCK;
+	else
+		mem_timings.dll_mode = M_LOCK;
+
+	if (mem_timings.base_cs == 0) {
+		fast_dll = sdrc_read_reg(SDRC_DLLA_CTRL);
+		dll_cnt = sdrc_read_reg(SDRC_DLLA_STATUS) & 0xff00;
+	} else {
+		fast_dll = sdrc_read_reg(SDRC_DLLB_CTRL);
+		dll_cnt = sdrc_read_reg(SDRC_DLLB_STATUS) & 0xff00;
+	}
+	if (force_lock_to_unlock_mode) {
+		fast_dll &= ~0xff00;
+		fast_dll |= dll_cnt;		/* Current lock mode */
+	}
+	/* set fast timings with DLL filter disabled */
+	mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
+
+	/* No disruptions, DDR will be offline & C-ABI not followed */
+	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
+			    mem_timings.fast_dll_ctrl,
+			    mem_timings.base_cs,
+			    force_lock_to_unlock_mode);
+	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */
+
+	/* Turn status into unlock ctrl */
+	mem_timings.slow_dll_ctrl |=
+		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
+
+	/* 90 degree phase for anything below 133Mhz + disable DLL filter */
+	mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/sdrc.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/sdrc.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/sdrc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/sdrc.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * SMS/SDRC (SDRAM controller) common code for OMAP2/3
+ *
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
+ *
+ * Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@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.
+ */
+#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 <mach/common.h>
+#include <mach/clock.h>
+#include <mach/sram.h>
+
+#include "prm.h"
+
+#include <mach/sdrc.h>
+#include "sdrc.h"
+
+static struct omap_sdrc_params *sdrc_init_params;
+
+void __iomem *omap2_sdrc_base;
+void __iomem *omap2_sms_base;
+
+
+/**
+ * omap2_sdrc_get_params - return SDRC register values for a given clock rate
+ * @r: SDRC clock rate (in Hz)
+ *
+ * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
+ * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given
+ * SDRC clock rate 'r'.  These parameters control various timing
+ * delays in the SDRAM controller that are expressed in terms of the
+ * number of SDRC clock cycles to wait; hence the clock rate
+ * dependency. Note that sdrc_init_params must be sorted rate
+ * descending.  Also assumes that both chip-selects use the same
+ * timing parameters.  Returns a struct omap_sdrc_params * upon
+ * success, or NULL upon failure.
+ */
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
+{
+	struct omap_sdrc_params *sp;
+
+	sp = sdrc_init_params;
+
+	while (sp->rate != r)
+		sp++;
+
+	if (!sp->rate)
+		return NULL;
+
+	return sp;
+}
+
+
+void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
+{
+	omap2_sdrc_base = omap2_globals->sdrc;
+	omap2_sms_base = omap2_globals->sms;
+}
+
+/* turn on smart idle modes for SDRAM scheduler and controller */
+void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
+{
+	u32 l;
+
+	l = sms_read_reg(SMS_SYSCONFIG);
+	l &= ~(0x3 << 3);
+	l |= (0x2 << 3);
+	sms_write_reg(l, SMS_SYSCONFIG);
+
+	l = sdrc_read_reg(SDRC_SYSCONFIG);
+	l &= ~(0x3 << 3);
+	l |= (0x2 << 3);
+	sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+	sdrc_init_params = sp;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/timer-gp.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/timer-gp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/timer-gp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/timer-gp.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,8 @@
  *
  * OMAP2 GP timer support.
  *
+ * Copyright (C) 2009 Nokia Corporation
+ *
  * Update to use new clocksource/clockevent layers
  * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
  * Copyright (C) 2007 MontaVista Software, Inc.
@@ -36,8 +38,13 @@
 #include <asm/mach/time.h>
 #include <mach/dmtimer.h>
 
+/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
+#define MAX_GPTIMER_ID		12
+
 static struct omap_dm_timer *gptimer;
 static struct clock_event_device clockevent_gpt;
+static u8 __initdata gptimer_id = 1;
+static u8 __initdata inited;
 
 static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
@@ -95,20 +102,53 @@ static struct clock_event_device clockev
 	.set_mode	= omap2_gp_timer_set_mode,
 };
 
+/**
+ * omap2_gp_clockevent_set_gptimer - set which GPTIMER is used for clockevents
+ * @id: GPTIMER to use (1..MAX_GPTIMER_ID)
+ *
+ * Define the GPTIMER that the system should use for the tick timer.
+ * Meant to be called from board-*.c files in the event that GPTIMER1, the
+ * default, is unsuitable.  Returns -EINVAL on error or 0 on success.
+ */
+int __init omap2_gp_clockevent_set_gptimer(u8 id)
+{
+	if (id < 1 || id > MAX_GPTIMER_ID)
+		return -EINVAL;
+
+	BUG_ON(inited);
+
+	gptimer_id = id;
+
+	return 0;
+}
+
 static void __init omap2_gp_clockevent_init(void)
 {
 	u32 tick_rate;
+	int src;
 
-	gptimer = omap_dm_timer_request_specific(1);
+	inited = 1;
+
+	gptimer = omap_dm_timer_request_specific(gptimer_id);
 	BUG_ON(gptimer == NULL);
 
 #if defined(CONFIG_OMAP_32K_TIMER)
-	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
+	src = OMAP_TIMER_SRC_32_KHZ;
 #else
-	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
+	src = OMAP_TIMER_SRC_SYS_CLK;
+	WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the "
+	     "secure 32KiHz clock source\n");
 #endif
+
+	if (gptimer_id != 12)
+		WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)),
+		     "timer-gp: omap_dm_timer_set_source() failed\n");
+
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
 
+	pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
+		gptimer_id, tick_rate);
+
 	omap2_gp_timer_irq.dev_id = (void *)gptimer;
 	setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
 	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
@@ -125,6 +165,8 @@ static void __init omap2_gp_clockevent_i
 	clockevents_register_device(&clockevent_gpt);
 }
 
+/* Clocksource code */
+
 #ifdef CONFIG_OMAP_32K_TIMER
 /* 
  * When 32k-timer is enabled, don't use GPTimer for clocksource
@@ -138,7 +180,7 @@ static inline void __init omap2_gp_clock
  * clocksource
  */
 static struct omap_dm_timer *gpt_clocksource;
-static cycle_t clocksource_read_cycles(void)
+static cycle_t clocksource_read_cycles(struct clocksource *cs)
 {
 	return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/usb-musb.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/usb-musb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/usb-musb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/usb-musb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,187 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-musb.c
+ *
+ * This file will contain the board specific details for the
+ * MENTOR USB OTG controller on OMAP3430
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Vikram Pandita
+ *
+ * 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 <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <linux/usb/musb.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/pm.h>
+#include <mach/mux.h>
+#include <mach/usb.h>
+
+static struct resource musb_resources[] = {
+	[0] = { /* start and end set dynamically */
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {	/* general IRQ */
+		.start	= INT_243X_HS_USB_MC,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {	/* DMA IRQ */
+		.start	= INT_243X_HS_USB_DMA,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static int clk_on;
+
+static int musb_set_clock(struct clk *clk, int state)
+{
+	if (state) {
+		if (clk_on > 0)
+			return -ENODEV;
+
+		clk_enable(clk);
+		clk_on = 1;
+	} else {
+		if (clk_on == 0)
+			return -ENODEV;
+
+		clk_disable(clk);
+		clk_on = 0;
+	}
+
+	return 0;
+}
+
+static struct musb_hdrc_eps_bits musb_eps[] = {
+	{	"ep1_tx", 10,	},
+	{	"ep1_rx", 10,	},
+	{	"ep2_tx", 9,	},
+	{	"ep2_rx", 9,	},
+	{	"ep3_tx", 3,	},
+	{	"ep3_rx", 3,	},
+	{	"ep4_tx", 3,	},
+	{	"ep4_rx", 3,	},
+	{	"ep5_tx", 3,	},
+	{	"ep5_rx", 3,	},
+	{	"ep6_tx", 3,	},
+	{	"ep6_rx", 3,	},
+	{	"ep7_tx", 3,	},
+	{	"ep7_rx", 3,	},
+	{	"ep8_tx", 2,	},
+	{	"ep8_rx", 2,	},
+	{	"ep9_tx", 2,	},
+	{	"ep9_rx", 2,	},
+	{	"ep10_tx", 2,	},
+	{	"ep10_rx", 2,	},
+	{	"ep11_tx", 2,	},
+	{	"ep11_rx", 2,	},
+	{	"ep12_tx", 2,	},
+	{	"ep12_rx", 2,	},
+	{	"ep13_tx", 2,	},
+	{	"ep13_rx", 2,	},
+	{	"ep14_tx", 2,	},
+	{	"ep14_rx", 2,	},
+	{	"ep15_tx", 2,	},
+	{	"ep15_rx", 2,	},
+};
+
+static struct musb_hdrc_config musb_config = {
+	.multipoint	= 1,
+	.dyn_fifo	= 1,
+	.soft_con	= 1,
+	.dma		= 1,
+	.num_eps	= 16,
+	.dma_channels	= 7,
+	.dma_req_chan	= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
+	.ram_bits	= 12,
+	.eps_bits	= musb_eps,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#ifdef CONFIG_USB_MUSB_OTG
+	.mode		= MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+	.mode		= MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+	.mode		= MUSB_PERIPHERAL,
+#endif
+	/* .clock is set dynamically */
+	.set_clock	= musb_set_clock,
+	.config		= &musb_config,
+
+	/* REVISIT charge pump on TWL4030 can supply up to
+	 * 100 mA ... but this value is board-specific, like
+	 * "mode", and should be passed to usb_musb_init().
+	 */
+	.power		= 50,			/* up to 100 mA */
+};
+
+static u64 musb_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device musb_device = {
+	.name		= "musb_hdrc",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &musb_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &musb_plat,
+	},
+	.num_resources	= ARRAY_SIZE(musb_resources),
+	.resource	= musb_resources,
+};
+
+#ifdef CONFIG_NOP_USB_XCEIV
+static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device nop_xceiv_device = {
+	.name		= "nop_usb_xceiv",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &nop_xceiv_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= NULL,
+	},
+};
+#endif
+
+void __init usb_musb_init(void)
+{
+	if (cpu_is_omap243x())
+		musb_resources[0].start = OMAP243X_HS_BASE;
+	else
+		musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
+	musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
+
+	/*
+	 * REVISIT: This line can be removed once all the platforms using
+	 * musb_core.c have been converted to use use clkdev.
+	 */
+	musb_plat.clock = "ick";
+
+#ifdef CONFIG_NOP_USB_XCEIV
+	if (platform_device_register(&nop_xceiv_device) < 0) {
+		printk(KERN_ERR "Unable to register NOP-XCEIV device\n");
+		return;
+	}
+#endif
+
+	if (platform_device_register(&musb_device) < 0) {
+		printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
+		return;
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/usb-tusb6010.c linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/usb-tusb6010.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-omap2/usb-tusb6010.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-omap2/usb-tusb6010.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,7 @@ int tusb6010_platform_retime(unsigned is
 	unsigned	sysclk_ps;
 	int		status;
 
-	if (!refclk_psec)
+	if (!refclk_psec || fclk_ps == 0)
 		return -ENODEV;
 
 	sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/addr-map.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/addr-map.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/addr-map.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/addr-map.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,12 +57,14 @@
 /*
  * Helpers to get DDR bank info
  */
+#define ORION5X_DDR_REG(x)	(ORION5X_DDR_VIRT_BASE | (x))
 #define DDR_BASE_CS(n)		ORION5X_DDR_REG(0x1500 + ((n) << 3))
 #define DDR_SIZE_CS(n)		ORION5X_DDR_REG(0x1504 + ((n) << 3))
 
 /*
  * CPU Address Decode Windows registers
  */
+#define ORION5X_BRIDGE_REG(x)	(ORION5X_BRIDGE_VIRT_BASE | (x))
 #define CPU_WIN_CTRL(n)		ORION5X_BRIDGE_REG(0x000 | ((n) << 4))
 #define CPU_WIN_BASE(n)		ORION5X_BRIDGE_REG(0x004 | ((n) << 4))
 #define CPU_WIN_REMAP_LO(n)	ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/common.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
 #include <plat/ehci-orion.h>
 #include <plat/mv_xor.h>
 #include <plat/orion_nand.h>
+#include <plat/orion5x_wdt.h>
 #include <plat/time.h>
 #include "common.h"
 
@@ -187,6 +188,9 @@ static struct platform_device orion5x_et
 	.id		= 0,
 	.num_resources	= 1,
 	.resource	= orion5x_eth_resources,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
 };
 
 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
@@ -219,14 +223,17 @@ static struct platform_device orion5x_sw
 
 void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
 {
+	int i;
+
 	if (irq != NO_IRQ) {
 		orion5x_switch_resources[0].start = irq;
 		orion5x_switch_resources[0].end = irq;
 		orion5x_switch_device.num_resources = 1;
 	}
 
-	d->mii_bus = &orion5x_eth_shared.dev;
 	d->netdev = &orion5x_eth.dev;
+	for (i = 0; i < d->nr_chips; i++)
+		d->chip[i].mii_bus = &orion5x_eth_shared.dev;
 	orion5x_switch_device.dev.platform_data = d;
 
 	platform_device_register(&orion5x_switch_device);
@@ -244,12 +251,10 @@ static struct mv64xxx_i2c_pdata orion5x_
 
 static struct resource orion5x_i2c_resources[] = {
 	{
-		.name	= "i2c base",
 		.start	= I2C_PHYS_BASE,
 		.end	= I2C_PHYS_BASE + 0x1f,
 		.flags	= IORESOURCE_MEM,
 	}, {
-		.name	= "i2c irq",
 		.start	= IRQ_ORION5X_I2C,
 		.end	= IRQ_ORION5X_I2C,
 		.flags	= IORESOURCE_IRQ,
@@ -459,7 +464,7 @@ static struct platform_device orion5x_xo
 	.resource	= orion5x_xor_shared_resources,
 };
 
-static u64 orion5x_xor_dmamask = DMA_32BIT_MASK;
+static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
 
 static struct resource orion5x_xor0_resources[] = {
 	[0] = {
@@ -482,7 +487,7 @@ static struct platform_device orion5x_xo
 	.resource	= orion5x_xor0_resources,
 	.dev		= {
 		.dma_mask		= &orion5x_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&orion5x_xor0_data,
 	},
 };
@@ -508,7 +513,7 @@ static struct platform_device orion5x_xo
 	.resource	= orion5x_xor1_resources,
 	.dev		= {
 		.dma_mask		= &orion5x_xor_dmamask,
-		.coherent_dma_mask	= DMA_64BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
 		.platform_data		= (void *)&orion5x_xor1_data,
 	},
 };
@@ -533,6 +538,29 @@ void __init orion5x_xor_init(void)
 
 
 /*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct orion5x_wdt_platform_data orion5x_wdt_data = {
+	.tclk			= 0,
+};
+
+static struct platform_device orion5x_wdt_device = {
+	.name		= "orion5x_wdt",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &orion5x_wdt_data,
+	},
+	.num_resources	= 0,
+};
+
+void __init orion5x_wdt_init(void)
+{
+	orion5x_wdt_data.tclk = orion5x_tclk;
+	platform_device_register(&orion5x_wdt_device);
+}
+
+
+/*****************************************************************************
  * Time handling
  ****************************************************************************/
 int orion5x_tclk;
@@ -631,6 +659,11 @@ void __init orion5x_init(void)
 		printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
 		disable_hlt();
 	}
+
+	/*
+	 * Register watchdog driver
+	 */
+	orion5x_wdt_init();
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/dns323-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/dns323-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/dns323-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,7 @@ static int __init dns323_dev_id(void)
 
 static int __init dns323_pci_init(void)
 {
-	/* The 5182 doesn't really use it's PCI bus, and initialising PCI
+	/* The 5182 doesn't really use its PCI bus, and initialising PCI
 	 * gets in the way of initialising the SATA controller.
 	 */
 	if (machine_is_dns323() && dns323_dev_id() != MV88F5182_DEV_ID)
@@ -418,7 +418,7 @@ static void __init dns323_init(void)
 	orion5x_i2c_init();
 	orion5x_uart0_init();
 
-	/* The 5182 has it's SATA controller on-chip, and needs it's own little
+	/* The 5182 has its SATA controller on-chip, and needs its own little
 	 * init routine.
 	 */
 	if (dns323_dev_id() == MV88F5182_DEV_ID)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/bridge-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/bridge-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/bridge-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/bridge-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/bridge-regs.h
+ *
+ * Orion CPU 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/orion5x.h>
+
+#define CPU_CONF		(ORION5X_BRIDGE_VIRT_BASE | 0x100)
+
+#define CPU_CTRL		(ORION5X_BRIDGE_VIRT_BASE | 0x104)
+
+#define CPU_RESET_MASK		(ORION5X_BRIDGE_VIRT_BASE | 0x108)
+#define WDT_RESET		0x0002
+
+#define CPU_SOFT_RESET		(ORION5X_BRIDGE_VIRT_BASE | 0x10c)
+
+#define POWER_MNG_CTRL_REG	(ORION5X_BRIDGE_VIRT_BASE | 0x11C)
+
+#define BRIDGE_CAUSE		(ORION5X_BRIDGE_VIRT_BASE | 0x110)
+#define WDT_INT_REQ		0x0008
+
+#define BRIDGE_MASK		(ORION5X_BRIDGE_VIRT_BASE | 0x114)
+#define BRIDGE_INT_TIMER0	0x0002
+#define BRIDGE_INT_TIMER1	0x0004
+#define BRIDGE_INT_TIMER1_CLR	(~0x0004)
+
+#define MAIN_IRQ_CAUSE		(ORION5X_BRIDGE_VIRT_BASE | 0x200)
+
+#define MAIN_IRQ_MASK		(ORION5X_BRIDGE_VIRT_BASE | 0x204)
+
+#define TIMER_VIRT_BASE		(ORION5X_BRIDGE_VIRT_BASE | 0x300)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/entry-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/entry-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/entry-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/entry-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
 
 	.macro  disable_fiq
 	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/orion5x.h linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/orion5x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/orion5x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/orion5x.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,30 +61,10 @@
 #define ORION5X_PCI_MEM_SIZE		SZ_128M
 
 /*******************************************************************************
- * Supported Devices & Revisions
- ******************************************************************************/
-/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
-#define MV88F5181_DEV_ID	0x5181
-#define MV88F5181_REV_B1	3
-#define MV88F5181L_REV_A0	8
-#define MV88F5181L_REV_A1	9
-/* Orion-NAS (88F5182) */
-#define MV88F5182_DEV_ID	0x5182
-#define MV88F5182_REV_A2	2
-/* Orion-2 (88F5281) */
-#define MV88F5281_DEV_ID	0x5281
-#define MV88F5281_REV_D0	4
-#define MV88F5281_REV_D1	5
-#define MV88F5281_REV_D2	6
-/* Orion-1-90 (88F6183) */
-#define MV88F6183_DEV_ID	0x6183
-#define MV88F6183_REV_B0	3
-
-/*******************************************************************************
  * Orion Registers Map
  ******************************************************************************/
+
 #define ORION5X_DDR_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x00000)
-#define ORION5X_DDR_REG(x)		(ORION5X_DDR_VIRT_BASE | (x))
 
 #define ORION5X_DEV_BUS_PHYS_BASE	(ORION5X_REGS_PHYS_BASE | 0x10000)
 #define ORION5X_DEV_BUS_VIRT_BASE	(ORION5X_REGS_VIRT_BASE | 0x10000)
@@ -97,34 +77,25 @@
 #define  UART1_VIRT_BASE		(ORION5X_DEV_BUS_VIRT_BASE | 0x2100)
 
 #define ORION5X_BRIDGE_VIRT_BASE	(ORION5X_REGS_VIRT_BASE | 0x20000)
-#define ORION5X_BRIDGE_REG(x)		(ORION5X_BRIDGE_VIRT_BASE | (x))
-#define  TIMER_VIRT_BASE		(ORION5X_BRIDGE_VIRT_BASE | 0x300)
 
 #define ORION5X_PCI_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x30000)
-#define ORION5X_PCI_REG(x)		(ORION5X_PCI_VIRT_BASE | (x))
 
 #define ORION5X_PCIE_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x40000)
-#define ORION5X_PCIE_REG(x)		(ORION5X_PCIE_VIRT_BASE | (x))
 
 #define ORION5X_USB0_PHYS_BASE		(ORION5X_REGS_PHYS_BASE | 0x50000)
 #define ORION5X_USB0_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x50000)
-#define ORION5X_USB0_REG(x)		(ORION5X_USB0_VIRT_BASE | (x))
 
 #define ORION5X_XOR_PHYS_BASE		(ORION5X_REGS_PHYS_BASE | 0x60900)
 #define ORION5X_XOR_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x60900)
-#define ORION5X_XOR_REG(x)		(ORION5X_XOR_VIRT_BASE | (x))
 
 #define ORION5X_ETH_PHYS_BASE		(ORION5X_REGS_PHYS_BASE | 0x70000)
 #define ORION5X_ETH_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x70000)
-#define ORION5X_ETH_REG(x)		(ORION5X_ETH_VIRT_BASE | (x))
 
 #define ORION5X_SATA_PHYS_BASE		(ORION5X_REGS_PHYS_BASE | 0x80000)
 #define ORION5X_SATA_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0x80000)
-#define ORION5X_SATA_REG(x)		(ORION5X_SATA_VIRT_BASE | (x))
 
 #define ORION5X_USB1_PHYS_BASE		(ORION5X_REGS_PHYS_BASE | 0xa0000)
 #define ORION5X_USB1_VIRT_BASE		(ORION5X_REGS_VIRT_BASE | 0xa0000)
-#define ORION5X_USB1_REG(x)		(ORION5X_USB1_VIRT_BASE | (x))
 
 /*******************************************************************************
  * Device Bus Registers
@@ -142,23 +113,24 @@
 #define DEV_BUS_INT_CAUSE	ORION5X_DEV_BUS_REG(0x4d0)
 #define DEV_BUS_INT_MASK	ORION5X_DEV_BUS_REG(0x4d4)
 
-/***************************************************************************
- * Orion CPU Bridge Registers
- **************************************************************************/
-#define CPU_CONF		ORION5X_BRIDGE_REG(0x100)
-#define CPU_CTRL		ORION5X_BRIDGE_REG(0x104)
-#define CPU_RESET_MASK		ORION5X_BRIDGE_REG(0x108)
-#define  WDT_RESET		0x0002
-#define CPU_SOFT_RESET		ORION5X_BRIDGE_REG(0x10c)
-#define POWER_MNG_CTRL_REG	ORION5X_BRIDGE_REG(0x11C)
-#define BRIDGE_CAUSE		ORION5X_BRIDGE_REG(0x110)
-#define  WDT_INT_REQ		0x0008
-#define BRIDGE_MASK		ORION5X_BRIDGE_REG(0x114)
-#define  BRIDGE_INT_TIMER0	0x0002
-#define  BRIDGE_INT_TIMER1	0x0004
-#define  BRIDGE_INT_TIMER1_CLR	(~0x0004)
-#define MAIN_IRQ_CAUSE		ORION5X_BRIDGE_REG(0x200)
-#define MAIN_IRQ_MASK		ORION5X_BRIDGE_REG(0x204)
-
+/*******************************************************************************
+ * Supported Devices & Revisions
+ ******************************************************************************/
+/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
+#define MV88F5181_DEV_ID	0x5181
+#define MV88F5181_REV_B1	3
+#define MV88F5181L_REV_A0	8
+#define MV88F5181L_REV_A1	9
+/* Orion-NAS (88F5182) */
+#define MV88F5182_DEV_ID	0x5182
+#define MV88F5182_REV_A2	2
+/* Orion-2 (88F5281) */
+#define MV88F5281_DEV_ID	0x5281
+#define MV88F5281_REV_D0	4
+#define MV88F5281_REV_D1	5
+#define MV88F5281_REV_D2	6
+/* Orion-1-90 (88F6183) */
+#define MV88F6183_DEV_ID	0x6183
+#define MV88F6183_REV_B0	3
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,15 +11,14 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <mach/hardware.h>
-#include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
 
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	/*
 	 * Enable and issue soft reset
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <asm/gpio.h>
-#include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
 #include <plat/irq.h>
 #include "common.h"
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -71,6 +71,7 @@ config MACH_WRT350N_V2
 
 config MACH_TS78XX
 	bool "Technologic Systems TS-78xx"
+	select PM
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Technologic Systems TS-78xx platform.
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/lsmini-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/lsmini-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/lsmini-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/lsmini-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -186,7 +186,7 @@ static struct mv_sata_platform_data lsmi
 
 static void lsmini_power_off(void)
 {
-	arch_reset(0);
+	arch_reset(0, NULL);
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/mss2-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/mss2-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/mss2-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/mss2-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
 #include "common.h"
 #include "mpp.h"
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/pci.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/pci.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -196,6 +196,7 @@ static int __init pcie_setup(struct pci_
 /*****************************************************************************
  * PCI controller
  ****************************************************************************/
+#define ORION5X_PCI_REG(x)	(ORION5X_PCI_VIRT_BASE | (x))
 #define PCI_MODE		ORION5X_PCI_REG(0xd00)
 #define PCI_CMD			ORION5X_PCI_REG(0xc00)
 #define PCI_P2P_CONF		ORION5X_PCI_REG(0x1d14)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,7 +94,7 @@ static struct mv643xx_eth_platform_data
 	.duplex		= DUPLEX_FULL,
 };
 
-static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
+static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
 	.port_names[0]	= "lan2",
 	.port_names[1]	= "lan1",
 	.port_names[2]	= "wan",
@@ -103,6 +103,11 @@ static struct dsa_platform_data rd88f518
 	.port_names[7]	= "lan3",
 };
 
+static struct dsa_platform_data rd88f5181l_fxo_switch_plat_data = {
+	.nr_chips	= 1,
+	.chip		= &rd88f5181l_fxo_switch_chip_data,
+};
+
 static void __init rd88f5181l_fxo_init(void)
 {
 	/*
@@ -117,7 +122,7 @@ static void __init rd88f5181l_fxo_init(v
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f5181l_fxo_eth_data);
-	orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ);
+	orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
 	orion5x_uart0_init();
 
 	orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -95,7 +95,7 @@ static struct mv643xx_eth_platform_data
 	.duplex		= DUPLEX_FULL,
 };
 
-static struct dsa_platform_data rd88f5181l_ge_switch_data = {
+static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
 	.port_names[0]	= "lan2",
 	.port_names[1]	= "lan1",
 	.port_names[2]	= "wan",
@@ -104,6 +104,11 @@ static struct dsa_platform_data rd88f518
 	.port_names[7]	= "lan3",
 };
 
+static struct dsa_platform_data rd88f5181l_ge_switch_plat_data = {
+	.nr_chips	= 1,
+	.chip		= &rd88f5181l_ge_switch_chip_data,
+};
+
 static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
 	I2C_BOARD_INFO("ds1338", 0x68),
 };
@@ -122,7 +127,8 @@ static void __init rd88f5181l_ge_init(vo
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f5181l_ge_eth_data);
-	orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8));
+	orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data,
+				gpio_to_irq(8));
 	orion5x_i2c_init();
 	orion5x_uart0_init();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,7 @@ static struct mv643xx_eth_platform_data
 	.duplex		= DUPLEX_FULL,
 };
 
-static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
+static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
 	.port_names[0]	= "lan1",
 	.port_names[1]	= "lan2",
 	.port_names[2]	= "lan3",
@@ -44,6 +44,11 @@ static struct dsa_platform_data rd88f618
 	.port_names[5]	= "cpu",
 };
 
+static struct dsa_platform_data rd88f6183ap_ge_switch_plat_data = {
+	.nr_chips	= 1,
+	.chip		= &rd88f6183ap_ge_switch_chip_data,
+};
+
 static struct mtd_partition rd88f6183ap_ge_partitions[] = {
 	{
 		.name	= "kernel",
@@ -89,7 +94,8 @@ static void __init rd88f6183ap_ge_init(v
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f6183ap_ge_eth_data);
-	orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3));
+	orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data,
+				gpio_to_irq(3));
 	spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
 				ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
 	orion5x_spi_init();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/ts78xx-fpga.h linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/ts78xx-fpga.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/ts78xx-fpga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/ts78xx-fpga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
+
+/*
+ * get yer id's from http://ts78xx.digriz.org.uk/
+ * do *not* make up your own or 'borrow' any!
+ */
+enum fpga_ids {
+	/* Technologic Systems */
+	TS7800_REV_1	= FPGAID(0x00b480, 0x01),
+	TS7800_REV_2	= FPGAID(0x00b480, 0x02),
+	TS7800_REV_3	= FPGAID(0x00b480, 0x03),
+	TS7800_REV_4	= FPGAID(0x00b480, 0x04),
+	TS7800_REV_5	= FPGAID(0x00b480, 0x05),
+
+	/* Unaffordable & Expensive */
+	UAE_DUMMY	= FPGAID(0xffffff, 0x01),
+};
+
+struct fpga_device {
+	unsigned		present:1;
+	unsigned		init:1;
+};
+
+struct fpga_devices {
+	/* Technologic Systems */
+	struct fpga_device 	ts_rtc;
+	struct fpga_device 	ts_nand;
+};
+
+struct ts78xx_fpga_data {
+	unsigned int		id;
+	int			state;
+
+	struct fpga_devices	supports;
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,17 +10,20 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/sysfs.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ata_platform.h>
 #include <linux/m48t86.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 <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "ts78xx-fpga.h"
 
 /*****************************************************************************
  * TS-78xx Info
@@ -33,18 +36,11 @@
 #define TS78XX_FPGA_REGS_VIRT_BASE	0xff900000
 #define TS78XX_FPGA_REGS_SIZE		SZ_1M
 
-#define TS78XX_FPGA_REGS_SYSCON_ID	(TS78XX_FPGA_REGS_VIRT_BASE | 0x000)
-#define TS78XX_FPGA_REGS_SYSCON_LCDI	(TS78XX_FPGA_REGS_VIRT_BASE | 0x004)
-#define TS78XX_FPGA_REGS_SYSCON_LCDO	(TS78XX_FPGA_REGS_VIRT_BASE | 0x008)
-
-#define TS78XX_FPGA_REGS_RTC_CTRL	(TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
-#define TS78XX_FPGA_REGS_RTC_DATA	(TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
-
-/*
- * 512kB NOR flash Device
- */
-#define TS78XX_NOR_BOOT_BASE		0xff800000
-#define TS78XX_NOR_BOOT_SIZE		SZ_512K
+static struct ts78xx_fpga_data ts78xx_fpga = {
+	.id		= 0,
+	.state		= 1,
+/*	.supports	= ... - populated by ts78xx_fpga_supports() */
+};
 
 /*****************************************************************************
  * I/O Address Mapping
@@ -65,73 +61,47 @@ void __init ts78xx_map_io(void)
 }
 
 /*****************************************************************************
- * 512kB NOR Boot Flash - the chip is a M25P40
+ * Ethernet
  ****************************************************************************/
-static struct mtd_partition ts78xx_nor_boot_flash_resources[] = {
-	{
-		.name		= "ts-bootrom",
-		.offset		= 0,
-		/* only the first 256kB is used */
-		.size		= SZ_256K,
-		.mask_flags	= MTD_WRITEABLE,
-	},
-};
-
-static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
-	.width		= 1,
-	.parts		= ts78xx_nor_boot_flash_resources,
-	.nr_parts	= ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
-};
-
-static struct resource ts78xx_nor_boot_flash_resource = {
-	.flags		= IORESOURCE_MEM,
-	.start		= TS78XX_NOR_BOOT_BASE,
-	.end		= TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
-};
-
-static struct platform_device ts78xx_nor_boot_flash = {
-	.name		= "physmap-flash",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &ts78xx_nor_boot_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &ts78xx_nor_boot_flash_resource,
+static struct mv643xx_eth_platform_data ts78xx_eth_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
 };
 
 /*****************************************************************************
- * Ethernet
+ * SATA
  ****************************************************************************/
-static struct mv643xx_eth_platform_data ts78xx_eth_data = {
-	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+static struct mv_sata_platform_data ts78xx_sata_data = {
+	.n_ports	= 2,
 };
 
 /*****************************************************************************
  * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
  ****************************************************************************/
-#ifdef CONFIG_RTC_DRV_M48T86
-static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
+#define TS_RTC_CTRL	(TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
+#define TS_RTC_DATA	(TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+
+static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
 {
-	writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
-	return readb(TS78XX_FPGA_REGS_RTC_DATA);
+	writeb(addr, TS_RTC_CTRL);
+	return readb(TS_RTC_DATA);
 }
 
-static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
+static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
 {
-	writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
-	writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
+	writeb(addr, TS_RTC_CTRL);
+	writeb(value, TS_RTC_DATA);
 }
 
-static struct m48t86_ops ts78xx_rtc_ops = {
-	.readbyte	= ts78xx_rtc_readbyte,
-	.writebyte	= ts78xx_rtc_writebyte,
+static struct m48t86_ops ts78xx_ts_rtc_ops = {
+	.readbyte	= ts78xx_ts_rtc_readbyte,
+	.writebyte	= ts78xx_ts_rtc_writebyte,
 };
 
-static struct platform_device ts78xx_rtc_device = {
+static struct platform_device ts78xx_ts_rtc_device = {
 	.name		= "rtc-m48t86",
 	.id		= -1,
 	.dev		= {
-		.platform_data	= &ts78xx_rtc_ops,
+		.platform_data	= &ts78xx_ts_rtc_ops,
 	},
 	.num_resources	= 0,
 };
@@ -146,59 +116,314 @@ static struct platform_device ts78xx_rtc
  * TODO: track down a guinea pig without an RTC to see if we can work out a
  * 		better RTC detection routine
  */
-static int __init ts78xx_rtc_init(void)
+static int ts78xx_ts_rtc_load(void)
 {
+	int rc;
 	unsigned char tmp_rtc0, tmp_rtc1;
 
-	tmp_rtc0 = ts78xx_rtc_readbyte(126);
-	tmp_rtc1 = ts78xx_rtc_readbyte(127);
+	tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
+	tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
 
-	ts78xx_rtc_writebyte(0x00, 126);
-	ts78xx_rtc_writebyte(0x55, 127);
-	if (ts78xx_rtc_readbyte(127) == 0x55) {
-		ts78xx_rtc_writebyte(0xaa, 127);
-		if (ts78xx_rtc_readbyte(127) == 0xaa
-				&& ts78xx_rtc_readbyte(126) == 0x00) {
-			ts78xx_rtc_writebyte(tmp_rtc0, 126);
-			ts78xx_rtc_writebyte(tmp_rtc1, 127);
-			platform_device_register(&ts78xx_rtc_device);
-			return 1;
+	ts78xx_ts_rtc_writebyte(0x00, 126);
+	ts78xx_ts_rtc_writebyte(0x55, 127);
+	if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
+		ts78xx_ts_rtc_writebyte(0xaa, 127);
+		if (ts78xx_ts_rtc_readbyte(127) == 0xaa
+				&& ts78xx_ts_rtc_readbyte(126) == 0x00) {
+			ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
+			ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
+
+			if (ts78xx_fpga.supports.ts_rtc.init == 0) {
+				rc = platform_device_register(&ts78xx_ts_rtc_device);
+				if (!rc)
+					ts78xx_fpga.supports.ts_rtc.init = 1;
+			} else
+				rc = platform_device_add(&ts78xx_ts_rtc_device);
+
+			return rc;
 		}
 	}
 
-	return 0;
+	return -ENODEV;
 };
-#else
-static int __init ts78xx_rtc_init(void)
+
+static void ts78xx_ts_rtc_unload(void)
 {
-	return 0;
+	platform_device_del(&ts78xx_ts_rtc_device);
 }
-#endif
 
 /*****************************************************************************
- * SATA
+ * NAND Flash
  ****************************************************************************/
-static struct mv_sata_platform_data ts78xx_sata_data = {
-	.n_ports	= 2,
+#define TS_NAND_CTRL	(TS78XX_FPGA_REGS_VIRT_BASE | 0x800)	/* VIRT */
+#define TS_NAND_DATA	(TS78XX_FPGA_REGS_PHYS_BASE | 0x804)	/* PHYS */
+
+/*
+ * hardware specific access to control-lines
+ *
+ * ctrl:
+ * NAND_NCE: bit 0 -> bit 2
+ * NAND_CLE: bit 1 -> bit 1
+ * NAND_ALE: bit 2 -> bit 0
+ */
+static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+			unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		unsigned char bits;
+
+		bits = (ctrl & NAND_NCE) << 2;
+		bits |= ctrl & NAND_CLE;
+		bits |= (ctrl & NAND_ALE) >> 2;
+
+		writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		writeb(cmd, this->IO_ADDR_W);
+}
+
+static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
+{
+	return readb(TS_NAND_CTRL) & 0x20;
+}
+
+const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ts78xx_ts_nand_parts[] = {
+	{
+		.name		= "mbr",
+		.offset		= 0,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+	}, {
+		.name		= "initrd",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+	}, {
+		.name		= "rootfs",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct platform_nand_data ts78xx_ts_nand_data = {
+	.chip	= {
+		.part_probe_types	= ts_nand_part_probes,
+		.partitions		= ts78xx_ts_nand_parts,
+		.nr_partitions		= ARRAY_SIZE(ts78xx_ts_nand_parts),
+		.chip_delay		= 15,
+		.options		= NAND_USE_FLASH_BBT,
+	},
+	.ctrl	= {
+		/*
+		 * The HW ECC offloading functions, used to give about a 9%
+		 * performance increase for 'dd if=/dev/mtdblockX' and 5% for
+		 * nanddump.  This all however was changed by git commit
+		 * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
+		 * no performance advantage to be had so we no longer bother
+		 */
+		.cmd_ctrl		= ts78xx_ts_nand_cmd_ctrl,
+		.dev_ready		= ts78xx_ts_nand_dev_ready,
+	},
+};
+
+static struct resource ts78xx_ts_nand_resources = {
+	.start		= TS_NAND_DATA,
+	.end		= TS_NAND_DATA + 4,
+	.flags		= IORESOURCE_IO,
+};
+
+static struct platform_device ts78xx_ts_nand_device = {
+	.name		= "gen_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &ts78xx_ts_nand_data,
+	},
+	.resource	= &ts78xx_ts_nand_resources,
+	.num_resources	= 1,
+};
+
+static int ts78xx_ts_nand_load(void)
+{
+	int rc;
+
+	if (ts78xx_fpga.supports.ts_nand.init == 0) {
+		rc = platform_device_register(&ts78xx_ts_nand_device);
+		if (!rc)
+			ts78xx_fpga.supports.ts_nand.init = 1;
+	} else
+		rc = platform_device_add(&ts78xx_ts_nand_device);
+
+	return rc;
 };
 
+static void ts78xx_ts_nand_unload(void)
+{
+	platform_device_del(&ts78xx_ts_nand_device);
+}
+
 /*****************************************************************************
- * print some information regarding the board
+ * FPGA 'hotplug' support code
  ****************************************************************************/
-static void __init ts78xx_print_board_id(void)
+static void ts78xx_fpga_devices_zero_init(void)
 {
-	unsigned int board_info;
+	ts78xx_fpga.supports.ts_rtc.init = 0;
+	ts78xx_fpga.supports.ts_nand.init = 0;
+}
 
-	board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID);
-	printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ",
-				board_info & 0xff,
-				(board_info >> 8) & 0xffffff);
-	board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI);
-	printk("JP1=%d, JP2=%d\n",
-				(board_info >> 30) & 0x1,
-				(board_info >> 31) & 0x1);
+static void ts78xx_fpga_supports(void)
+{
+	/* TODO: put this 'table' into ts78xx-fpga.h */
+	switch (ts78xx_fpga.id) {
+	case TS7800_REV_1:
+	case TS7800_REV_2:
+	case TS7800_REV_3:
+	case TS7800_REV_4:
+	case TS7800_REV_5:
+		ts78xx_fpga.supports.ts_rtc.present = 1;
+		ts78xx_fpga.supports.ts_nand.present = 1;
+		break;
+	default:
+		ts78xx_fpga.supports.ts_rtc.present = 0;
+		ts78xx_fpga.supports.ts_nand.present = 0;
+	}
+}
+
+static int ts78xx_fpga_load_devices(void)
+{
+	int tmp, ret = 0;
+
+	if (ts78xx_fpga.supports.ts_rtc.present == 1) {
+		tmp = ts78xx_ts_rtc_load();
+		if (tmp) {
+			printk(KERN_INFO "TS-78xx: RTC not registered\n");
+			ts78xx_fpga.supports.ts_rtc.present = 0;
+		}
+		ret |= tmp;
+	}
+	if (ts78xx_fpga.supports.ts_nand.present == 1) {
+		tmp = ts78xx_ts_nand_load();
+		if (tmp) {
+			printk(KERN_INFO "TS-78xx: NAND not registered\n");
+			ts78xx_fpga.supports.ts_nand.present = 0;
+		}
+		ret |= tmp;
+	}
+
+	return ret;
+}
+
+static int ts78xx_fpga_unload_devices(void)
+{
+	int ret = 0;
+
+	if (ts78xx_fpga.supports.ts_rtc.present == 1)
+		ts78xx_ts_rtc_unload();
+	if (ts78xx_fpga.supports.ts_nand.present == 1)
+		ts78xx_ts_nand_unload();
+
+	return ret;
+}
+
+static int ts78xx_fpga_load(void)
+{
+	ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+	printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+			(ts78xx_fpga.id >> 8) & 0xffffff,
+			ts78xx_fpga.id & 0xff);
+
+	ts78xx_fpga_supports();
+
+	if (ts78xx_fpga_load_devices()) {
+		ts78xx_fpga.state = -1;
+		return -EBUSY;
+	}
+
+	return 0;
 };
 
+static int ts78xx_fpga_unload(void)
+{
+	unsigned int fpga_id;
+
+	fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+	/*
+	 * There does not seem to be a feasible way to block access to the GPIO
+	 * pins from userspace (/dev/mem).  This if clause should hopefully warn
+	 * those foolish enough not to follow 'policy' :)
+	 *
+	 * UrJTAG SVN since r1381 can be used to reprogram the FPGA
+	 */
+	if (ts78xx_fpga.id != fpga_id) {
+		printk(KERN_ERR	"TS-78xx FPGA: magic/rev mismatch\n"
+			"TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
+			(ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
+			(fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
+		ts78xx_fpga.state = -1;
+		return -EBUSY;
+	}
+
+	if (ts78xx_fpga_unload_devices()) {
+		ts78xx_fpga.state = -1;
+		return -EBUSY;
+	}
+
+	return 0;
+};
+
+static ssize_t ts78xx_fpga_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	if (ts78xx_fpga.state < 0)
+		return sprintf(buf, "borked\n");
+
+	return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
+}
+
+static ssize_t ts78xx_fpga_store(struct kobject *kobj,
+			struct kobj_attribute *attr, const char *buf, size_t n)
+{
+	int value, ret;
+
+	if (ts78xx_fpga.state < 0) {
+		printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+		return -EBUSY;
+	}
+
+	if (strncmp(buf, "online", sizeof("online") - 1) == 0)
+		value = 1;
+	else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
+		value = 0;
+	else {
+		printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+		return -EINVAL;
+	}
+
+	if (ts78xx_fpga.state == value)
+		return n;
+
+	ret = (ts78xx_fpga.state == 0)
+		? ts78xx_fpga_load()
+		: ts78xx_fpga_unload();
+
+	if (!(ret < 0))
+		ts78xx_fpga.state = value;
+
+	return n;
+}
+
+static struct kobj_attribute ts78xx_fpga_attr =
+	__ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
+
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
@@ -223,30 +448,29 @@ static struct orion5x_mpp_mode ts78xx_mp
 	{ 17, MPP_UART },
 	{ 18, MPP_UART },
 	{ 19, MPP_UART },
+	/*
+	 * MPP[20] PCI Clock Out 1
+	 * MPP[21] PCI Clock Out 0
+	 * MPP[22] Unused
+	 * MPP[23] Unused
+	 * MPP[24] Unused
+	 * MPP[25] Unused
+	 */
 	{ -1 },
 };
 
 static void __init ts78xx_init(void)
 {
+	int ret;
+
 	/*
 	 * Setup basic Orion functions. Need to be called early.
 	 */
 	orion5x_init();
 
-	ts78xx_print_board_id();
-
 	orion5x_mpp_conf(ts78xx_mpp_modes);
 
 	/*
-	 * MPP[20] PCI Clock Out 1
-	 * MPP[21] PCI Clock Out 0
-	 * MPP[22] Unused
-	 * MPP[23] Unused
-	 * MPP[24] Unused
-	 * MPP[25] Unused
-	 */
-
-	/*
 	 * Configure peripherals.
 	 */
 	orion5x_ehci0_init();
@@ -257,12 +481,12 @@ static void __init ts78xx_init(void)
 	orion5x_uart1_init();
 	orion5x_xor_init();
 
-	orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
-				   TS78XX_NOR_BOOT_SIZE);
-	platform_device_register(&ts78xx_nor_boot_flash);
-
-	if (!ts78xx_rtc_init())
-		printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
+	/* FPGA init */
+	ts78xx_fpga_devices_zero_init();
+	ret = ts78xx_fpga_load();
+	ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
+	if (ret)
+		printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
 }
 
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -106,7 +106,7 @@ static struct mv643xx_eth_platform_data
 	.duplex		= DUPLEX_FULL,
 };
 
-static struct dsa_platform_data wrt350n_v2_switch_data = {
+static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
 	.port_names[0]	= "lan2",
 	.port_names[1]	= "lan1",
 	.port_names[2]	= "wan",
@@ -115,6 +115,11 @@ static struct dsa_platform_data wrt350n_
 	.port_names[7]	= "lan4",
 };
 
+static struct dsa_platform_data wrt350n_v2_switch_plat_data = {
+	.nr_chips	= 1,
+	.chip		= &wrt350n_v2_switch_chip_data,
+};
+
 static void __init wrt350n_v2_init(void)
 {
 	/*
@@ -129,7 +134,7 @@ static void __init wrt350n_v2_init(void)
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&wrt350n_v2_eth_data);
-	orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ);
+	orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
 	orion5x_uart0_init();
 
 	orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pnx4008/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-pnx4008/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pnx4008/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pnx4008/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -30,7 +30,7 @@ static void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/am200epd.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/am200epd.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/am200epd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/am200epd.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,8 +30,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
+#include <mach/pxa25x.h>
 #include <mach/gumstix.h>
-#include <mach/mfp-pxa25x.h>
 #include <mach/pxafb.h>
 
 #include "generic.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/am300epd.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/am300epd.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/am300epd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/am300epd.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ * am300epd.c -- Platform device for AM300 EPD kit
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * 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 work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Broadsheet display controller.
+ * on the AM300 EPD prototype kit/development kit with an E-Ink 800x600
+ * Vizplex EPD on a Gumstix board using the Broadsheet interface board.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/gumstix.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+
+#include <video/broadsheetfb.h>
+
+static unsigned int panel_type = 6;
+static struct platform_device *am300_device;
+static struct broadsheet_board am300_board;
+
+static unsigned long am300_pin_config[] __initdata = {
+	GPIO16_GPIO,
+	GPIO17_GPIO,
+	GPIO32_GPIO,
+	GPIO48_GPIO,
+	GPIO49_GPIO,
+	GPIO51_GPIO,
+	GPIO74_GPIO,
+	GPIO75_GPIO,
+	GPIO76_GPIO,
+	GPIO77_GPIO,
+
+	/* this is the 16-bit hdb bus 58-73 */
+	GPIO58_GPIO,
+	GPIO59_GPIO,
+	GPIO60_GPIO,
+	GPIO61_GPIO,
+
+	GPIO62_GPIO,
+	GPIO63_GPIO,
+	GPIO64_GPIO,
+	GPIO65_GPIO,
+
+	GPIO66_GPIO,
+	GPIO67_GPIO,
+	GPIO68_GPIO,
+	GPIO69_GPIO,
+
+	GPIO70_GPIO,
+	GPIO71_GPIO,
+	GPIO72_GPIO,
+	GPIO73_GPIO,
+};
+
+/* register offsets for gpio control */
+#define PWR_GPIO_PIN	16
+#define CFG_GPIO_PIN	17
+#define RDY_GPIO_PIN	32
+#define DC_GPIO_PIN	48
+#define RST_GPIO_PIN	49
+#define LED_GPIO_PIN	51
+#define RD_GPIO_PIN	74
+#define WR_GPIO_PIN	75
+#define CS_GPIO_PIN	76
+#define IRQ_GPIO_PIN	77
+
+/* hdb bus */
+#define DB0_GPIO_PIN	58
+#define DB15_GPIO_PIN	73
+
+static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN,
+			RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN,
+			IRQ_GPIO_PIN, LED_GPIO_PIN };
+static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR",
+				"CS", "IRQ", "LED" };
+
+static int am300_wait_event(struct broadsheetfb_par *par)
+{
+	/* todo: improve err recovery */
+	wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
+	return 0;
+}
+
+static int am300_init_gpio_regs(struct broadsheetfb_par *par)
+{
+	int i;
+	int err;
+	char dbname[8];
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+		err = gpio_request(gpios[i], gpio_names[i]);
+		if (err) {
+			dev_err(&am300_device->dev, "failed requesting "
+				"gpio %s, err=%d\n", gpio_names[i], err);
+			goto err_req_gpio;
+		}
+	}
+
+	/* we also need to take care of the hdb bus */
+	for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) {
+		sprintf(dbname, "DB%d", i);
+		err = gpio_request(i, dbname);
+		if (err) {
+			dev_err(&am300_device->dev, "failed requesting "
+				"gpio %d, err=%d\n", i, err);
+			while (i >= DB0_GPIO_PIN)
+				gpio_free(i--);
+			i = ARRAY_SIZE(gpios) - 1;
+			goto err_req_gpio;
+		}
+	}
+
+	/* setup the outputs and init values */
+	gpio_direction_output(PWR_GPIO_PIN, 0);
+	gpio_direction_output(CFG_GPIO_PIN, 1);
+	gpio_direction_output(DC_GPIO_PIN, 0);
+	gpio_direction_output(RD_GPIO_PIN, 1);
+	gpio_direction_output(WR_GPIO_PIN, 1);
+	gpio_direction_output(CS_GPIO_PIN, 1);
+	gpio_direction_output(RST_GPIO_PIN, 0);
+
+	/* setup the inputs */
+	gpio_direction_input(RDY_GPIO_PIN);
+	gpio_direction_input(IRQ_GPIO_PIN);
+
+	/* start the hdb bus as an input */
+	for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+		gpio_direction_output(i, 0);
+
+	/* go into command mode */
+	gpio_set_value(CFG_GPIO_PIN, 1);
+	gpio_set_value(RST_GPIO_PIN, 0);
+	msleep(10);
+	gpio_set_value(RST_GPIO_PIN, 1);
+	msleep(10);
+	am300_wait_event(par);
+
+	return 0;
+
+err_req_gpio:
+	while (i > 0)
+		gpio_free(gpios[i--]);
+
+	return err;
+}
+
+static int am300_init_board(struct broadsheetfb_par *par)
+{
+	return am300_init_gpio_regs(par);
+}
+
+static void am300_cleanup(struct broadsheetfb_par *par)
+{
+	int i;
+
+	free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
+
+	for (i = 0; i < ARRAY_SIZE(gpios); i++)
+		gpio_free(gpios[i]);
+
+	for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+		gpio_free(i);
+
+}
+
+static u16 am300_get_hdb(struct broadsheetfb_par *par)
+{
+	u16 res = 0;
+	int i;
+
+	for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+		res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0;
+
+	return res;
+}
+
+static void am300_set_hdb(struct broadsheetfb_par *par, u16 data)
+{
+	int i;
+
+	for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+		gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01);
+}
+
+
+static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit,
+				u8 state)
+{
+	switch (bit) {
+	case BS_CS:
+		gpio_set_value(CS_GPIO_PIN, state);
+		break;
+	case BS_DC:
+		gpio_set_value(DC_GPIO_PIN, state);
+		break;
+	case BS_WR:
+		gpio_set_value(WR_GPIO_PIN, state);
+		break;
+	}
+}
+
+static int am300_get_panel_type(void)
+{
+	return panel_type;
+}
+
+static irqreturn_t am300_handle_irq(int irq, void *dev_id)
+{
+	struct broadsheetfb_par *par = dev_id;
+
+	wake_up(&par->waitq);
+	return IRQ_HANDLED;
+}
+
+static int am300_setup_irq(struct fb_info *info)
+{
+	int ret;
+	struct broadsheetfb_par *par = info->par;
+
+	ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq,
+				IRQF_DISABLED|IRQF_TRIGGER_RISING,
+				"AM300", par);
+	if (ret)
+		dev_err(&am300_device->dev, "request_irq failed: %d\n", ret);
+
+	return ret;
+}
+
+static struct broadsheet_board am300_board = {
+	.owner			= THIS_MODULE,
+	.init			= am300_init_board,
+	.cleanup		= am300_cleanup,
+	.set_hdb		= am300_set_hdb,
+	.get_hdb		= am300_get_hdb,
+	.set_ctl		= am300_set_ctl,
+	.wait_for_rdy		= am300_wait_event,
+	.get_panel_type		= am300_get_panel_type,
+	.setup_irq		= am300_setup_irq,
+};
+
+int __init am300_init(void)
+{
+	int ret;
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config));
+
+	/* request our platform independent driver */
+	request_module("broadsheetfb");
+
+	am300_device = platform_device_alloc("broadsheetfb", -1);
+	if (!am300_device)
+		return -ENOMEM;
+
+	/* the am300_board that will be seen by broadsheetfb is a copy */
+	platform_device_add_data(am300_device, &am300_board,
+					sizeof(am300_board));
+
+	ret = platform_device_add(am300_device);
+
+	if (ret) {
+		platform_device_put(am300_device);
+		return ret;
+	}
+
+	return 0;
+}
+
+module_param(panel_type, uint, 0);
+MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+
+MODULE_DESCRIPTION("board driver for am300 epd kit");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/clock.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,7 @@ void clks_register(struct clk_lookup *cl
 		clkdev_add(&clks[i]);
 }
 
-int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
 	struct device *dev)
 {
 	struct clk *r = clk_get(dev, id);
@@ -96,7 +96,7 @@ int clk_add_alias(char *alias, struct de
 	if (!r)
 		return -ENODEV;
 
-	l = clkdev_alloc(r, alias, alias_dev ? dev_name(alias_dev) : NULL);
+	l = clkdev_alloc(r, alias, alias_dev_name);
 	clk_put(r);
 	if (!l)
 		return -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/clock.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -69,6 +69,6 @@ extern void clk_pxa3xx_cken_disable(stru
 #endif
 
 void clks_register(struct clk_lookup *clks, size_t num);
-int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+int clk_add_alias(const char *alias, const char *alias_name, char *id,
 	struct device *dev);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x255.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x255.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x255.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x255.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,10 +22,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
 #include <mach/pxa2xx_spi.h>
-#include <mach/bitfield.h>
 
 #include "generic.h"
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x270.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x270.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x270.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x270.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/rtc-v3020.h>
 #include <video/mbxfb.h>
 
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
 #include <mach/ohci.h>
 #include <mach/mmc.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x2xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x2xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x2xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x2xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,8 +22,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 
@@ -96,7 +94,7 @@ static struct resource cmx270_dm9000_res
 };
 
 static struct dm9000_plat_data cmx270_dm9000_platdata = {
-	.flags		= DM9000_PLATF_32BITONLY,
+	.flags		= DM9000_PLATF_32BITONLY | DM9000_PLATF_NO_EEPROM,
 };
 
 static struct platform_device cmx2xx_dm9000_device = {
@@ -123,7 +121,7 @@ static inline void cmx2xx_init_dm9000(vo
 /* UCB1400 touchscreen controller */
 #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
 static struct platform_device cmx2xx_ts_device = {
-	.name		= "ucb1400_ts",
+	.name		= "ucb1400_core",
 	.id		= -1,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x2xx-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/gpio.h>
 
 #include <asm/mach/pci.h>
-#include <mach/pxa-regs.h>
 #include <asm/mach-types.h>
 
 #include <asm/hardware/it8152.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x300.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x300.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cm-x300.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cm-x300.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,9 +28,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/mfp-pxa300.h>
-
-#include <mach/hardware.h>
+#include <mach/pxa300.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
@@ -162,7 +160,7 @@ static struct resource dm9000_resources[
 };
 
 static struct dm9000_plat_data cm_x300_dm9000_platdata = {
-	.flags		= DM9000_PLATF_16BITONLY,
+	.flags		= DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
 };
 
 static struct platform_device dm9000_device = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,137 +0,0 @@
-/*
- *  linux/arch/arm/mach-pxa/colibri.c
- *
- *  Support for Toradex PXA27x based Colibri module
- *  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 version 2 as
- *  published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/sizes.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/flash.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/colibri.h>
-
-#include "generic.h"
-#include "devices.h"
-
-static unsigned long colibri_pin_config[] __initdata = {
-	GPIO78_nCS_2,	/* Ethernet CS */
-	GPIO114_GPIO,	/* Ethernet IRQ */
-};
-
-/*
- * Flash
- */
-static struct mtd_partition colibri_partitions[] = {
-	{
-		.name =		"Bootloader",
-		.offset =	0x00000000,
-		.size =		0x00040000,
-		.mask_flags =	MTD_WRITEABLE  /* force read-only */
-	}, {
-		.name =		"Kernel",
-		.offset =	0x00040000,
-		.size =		0x00400000,
-		.mask_flags =	0
-	}, {
-		.name =		"Rootfs",
-		.offset =	0x00440000,
-		.size =		MTDPART_SIZ_FULL,
-		.mask_flags =	0
-	}
-};
-
-static struct physmap_flash_data colibri_flash_data[] = {
-	{
-		.width		= 4,			/* bankwidth in bytes */
-		.parts		= colibri_partitions,
-		.nr_parts	= ARRAY_SIZE(colibri_partitions)
-	}
-};
-
-static struct resource flash_resource = {
-	.start	= PXA_CS0_PHYS,
-	.end	= PXA_CS0_PHYS + SZ_32M - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device flash_device = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev 	= {
-		.platform_data = colibri_flash_data,
-	},
-	.resource = &flash_resource,
-	.num_resources = 1,
-};
-
-/*
- * DM9000 Ethernet
- */
-static struct resource dm9000_resources[] = {
-	[0] = {
-		.start	= COLIBRI_ETH_PHYS,
-		.end	= COLIBRI_ETH_PHYS + 3,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= COLIBRI_ETH_PHYS + 4,
-		.end	= COLIBRI_ETH_PHYS + 4 + 500,
-		.flags	= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start	= COLIBRI_ETH_IRQ,
-		.end	= COLIBRI_ETH_IRQ,
-		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
-	},
-};
-
-static struct platform_device dm9000_device = {
-	.name		= "dm9000",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(dm9000_resources),
-	.resource	= dm9000_resources,
-};
-
-static struct platform_device *colibri_devices[] __initdata = {
-	&flash_device,
-	&dm9000_device,
-};
-
-static void __init colibri_init(void)
-{
-	pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pin_config));
-
-	platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
-}
-
-MACHINE_START(COLIBRI, "Toradex Colibri PXA27x")
-	.phys_io	= 0x40000000,
-	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params	= COLIBRI_SDRAM_BASE + 0x100,
-	.init_machine	= colibri_init,
-	.map_io		= pxa_map_io,
-	.init_irq	= pxa27x_init_irq,
-	.timer		= &pxa_timer,
-MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa270.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa270.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa270.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa270.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ *  linux/arch/arm/mach-pxa/colibri-pxa270.c
+ *
+ *  Support for Toradex PXA270 based Colibri module
+ *  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 version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/colibri.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/*
+ * GPIO configuration
+ */
+static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = {
+	GPIO78_nCS_2,	/* Ethernet CS */
+	GPIO114_GPIO,	/* Ethernet IRQ */
+};
+
+/*
+ * NOR flash
+ */
+static struct mtd_partition colibri_partitions[] = {
+	{
+		.name =		"Bootloader",
+		.offset =	0x00000000,
+		.size =		0x00040000,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	}, {
+		.name =		"Kernel",
+		.offset =	0x00040000,
+		.size =		0x00400000,
+		.mask_flags =	0
+	}, {
+		.name =		"Rootfs",
+		.offset =	0x00440000,
+		.size =		MTDPART_SIZ_FULL,
+		.mask_flags =	0
+	}
+};
+
+static struct physmap_flash_data colibri_flash_data[] = {
+	{
+		.width		= 4,			/* bankwidth in bytes */
+		.parts		= colibri_partitions,
+		.nr_parts	= ARRAY_SIZE(colibri_partitions)
+	}
+};
+
+static struct resource colibri_pxa270_flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_32M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device colibri_pxa270_flash_device = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev 	= {
+		.platform_data = colibri_flash_data,
+	},
+	.resource = &colibri_pxa270_flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * DM9000 Ethernet
+ */
+#if defined(CONFIG_DM9000)
+static struct resource dm9000_resources[] = {
+	[0] = {
+		.start	= COLIBRI_PXA270_ETH_PHYS,
+		.end	= COLIBRI_PXA270_ETH_PHYS + 3,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= COLIBRI_PXA270_ETH_PHYS + 4,
+		.end	= COLIBRI_PXA270_ETH_PHYS + 4 + 500,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= COLIBRI_PXA270_ETH_IRQ,
+		.end	= COLIBRI_PXA270_ETH_IRQ,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
+	},
+};
+
+static struct platform_device dm9000_device = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+};
+#endif /* CONFIG_DM9000 */
+
+static struct platform_device *colibri_pxa270_devices[] __initdata = {
+	&colibri_pxa270_flash_device,
+#if defined(CONFIG_DM9000)
+	&dm9000_device,
+#endif
+};
+
+static void __init colibri_pxa270_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config));
+	platform_add_devices(ARRAY_AND_SIZE(colibri_pxa270_devices));
+}
+
+MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= COLIBRI_SDRAM_BASE + 0x100,
+	.init_machine	= colibri_pxa270_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa300.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa300.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa300.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa300.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,191 @@
+/*
+ *  arch/arm/mach-pxa/colibri-pxa300.c
+ *
+ *  Support for Toradex PXA300/310 based Colibri module
+ *
+ *  Daniel Mack <daniel@caiaq.de>
+ *  Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa300.h>
+#include <mach/colibri.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO	mfp_to_gpio(GPIO26_GPIO)
+
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+	.flags		= 0, /* defined later */
+	.wordlength	= 2,
+};
+
+static struct resource colibri_asix_resource[] = {
+	[0] = {
+		.start = PXA3xx_CS2_PHYS,
+		.end   = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+		.end   = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+	}
+};
+
+static struct platform_device asix_device = {
+	.name		= "ax88796",
+	.id		= 0,
+	.num_resources 	= ARRAY_SIZE(colibri_asix_resource),
+	.resource	= colibri_asix_resource,
+	.dev		= {
+		.platform_data = &colibri_asix_platdata
+	}
+};
+
+static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = {
+	GPIO1_nCS2,			/* AX88796 chip select */
+	GPIO26_GPIO | MFP_PULL_HIGH	/* AX88796 IRQ */
+};
+
+static void __init colibri_pxa300_init_eth(void)
+{
+	colibri_pxa3xx_init_eth(&colibri_asix_platdata);
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config));
+	platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa300_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static mfp_cfg_t colibri_pxa300_usb_pin_config[] __initdata = {
+	GPIO0_2_USBH_PEN,
+	GPIO1_2_USBH_PWR,
+};
+
+static struct pxaohci_platform_data colibri_pxa300_ohci_info = {
+	.port_mode	= PMM_GLOBAL_MODE,
+	.flags		= ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+void __init colibri_pxa300_init_ohci(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_usb_pin_config));
+	pxa_set_ohci_info(&colibri_pxa300_ohci_info);
+}
+#else
+static inline void colibri_pxa300_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
+static mfp_cfg_t colibri_pxa300_mmc_pin_config[] __initdata = {
+	GPIO7_MMC1_CLK,
+	GPIO14_MMC1_CMD,
+	GPIO3_MMC1_DAT0,
+	GPIO4_MMC1_DAT1,
+	GPIO5_MMC1_DAT2,
+	GPIO6_MMC1_DAT3,
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = {
+	GPIO54_LCD_LDD_0,
+	GPIO55_LCD_LDD_1,
+	GPIO56_LCD_LDD_2,
+	GPIO57_LCD_LDD_3,
+	GPIO58_LCD_LDD_4,
+	GPIO59_LCD_LDD_5,
+	GPIO60_LCD_LDD_6,
+	GPIO61_LCD_LDD_7,
+	GPIO62_LCD_LDD_8,
+	GPIO63_LCD_LDD_9,
+	GPIO64_LCD_LDD_10,
+	GPIO65_LCD_LDD_11,
+	GPIO66_LCD_LDD_12,
+	GPIO67_LCD_LDD_13,
+	GPIO68_LCD_LDD_14,
+	GPIO69_LCD_LDD_15,
+	GPIO70_LCD_LDD_16,
+	GPIO71_LCD_LDD_17,
+	GPIO62_LCD_CS_N,
+	GPIO72_LCD_FCLK,
+	GPIO73_LCD_LCLK,
+	GPIO74_LCD_PCLK,
+	GPIO75_LCD_BIAS,
+	GPIO76_LCD_VSYNC,
+};
+
+static void __init colibri_pxa300_init_lcd(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_lcd_pin_config));
+}
+
+#else
+static inline void colibri_pxa300_init_lcd(void) {}
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
+
+#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa310_ac97_pin_config[] __initdata = {
+	GPIO24_AC97_SYSCLK,
+	GPIO23_AC97_nACRESET,
+	GPIO25_AC97_SDATA_IN_0,
+	GPIO27_AC97_SDATA_OUT,
+	GPIO28_AC97_SYNC,
+	GPIO29_AC97_BITCLK
+};
+
+static inline void __init colibri_pxa310_init_ac97(void)
+{
+	/* no AC97 codec on Colibri PXA300 */
+	if (!cpu_is_pxa310())
+		return;
+
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa310_ac97_pin_config));
+	pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa310_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa300_init(void)
+{
+	colibri_pxa300_init_eth();
+	colibri_pxa300_init_ohci();
+	colibri_pxa300_init_lcd();
+	colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO));
+	colibri_pxa310_init_ac97();
+	colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa300_mmc_pin_config),
+				mfp_to_gpio(MFP_PIN_GPIO13));
+}
+
+MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= COLIBRI_SDRAM_BASE + 0x100,
+	.init_machine	= colibri_pxa300_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa320.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa320.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa320.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa320.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,187 @@
+/*
+ *  arch/arm/mach-pxa/colibri-pxa320.c
+ *
+ *  Support for Toradex PXA320/310 based Colibri module
+ *
+ *  Daniel Mack <daniel@caiaq.de>
+ *  Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+#include <mach/colibri.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO	mfp_to_gpio(GPIO36_GPIO)
+
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+	.flags		= 0, /* defined later */
+	.wordlength	= 2,
+};
+
+static struct resource colibri_asix_resource[] = {
+	[0] = {
+		.start = PXA3xx_CS2_PHYS,
+		.end   = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+		.end   = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+	}
+};
+
+static struct platform_device asix_device = {
+	.name		= "ax88796",
+	.id		= 0,
+	.num_resources 	= ARRAY_SIZE(colibri_asix_resource),
+	.resource	= colibri_asix_resource,
+	.dev		= {
+		.platform_data = &colibri_asix_platdata
+	}
+};
+
+static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = {
+	GPIO3_nCS2,			/* AX88796 chip select */
+	GPIO36_GPIO | MFP_PULL_HIGH	/* AX88796 IRQ */
+};
+
+static void __init colibri_pxa320_init_eth(void)
+{
+	colibri_pxa3xx_init_eth(&colibri_asix_platdata);
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config));
+	platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa320_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static mfp_cfg_t colibri_pxa320_usb_pin_config[] __initdata = {
+	GPIO2_2_USBH_PEN,
+	GPIO3_2_USBH_PWR,
+};
+
+static struct pxaohci_platform_data colibri_pxa320_ohci_info = {
+	.port_mode	= PMM_GLOBAL_MODE,
+	.flags		= ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+void __init colibri_pxa320_init_ohci(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_usb_pin_config));
+	pxa_set_ohci_info(&colibri_pxa320_ohci_info);
+}
+#else
+static inline void colibri_pxa320_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
+static mfp_cfg_t colibri_pxa320_mmc_pin_config[] __initdata = {
+	GPIO22_MMC1_CLK,
+	GPIO23_MMC1_CMD,
+	GPIO18_MMC1_DAT0,
+	GPIO19_MMC1_DAT1,
+	GPIO20_MMC1_DAT2,
+	GPIO21_MMC1_DAT3
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = {
+	GPIO6_2_LCD_LDD_0,
+	GPIO7_2_LCD_LDD_1,
+	GPIO8_2_LCD_LDD_2,
+	GPIO9_2_LCD_LDD_3,
+	GPIO10_2_LCD_LDD_4,
+	GPIO11_2_LCD_LDD_5,
+	GPIO12_2_LCD_LDD_6,
+	GPIO13_2_LCD_LDD_7,
+	GPIO63_LCD_LDD_8,
+	GPIO64_LCD_LDD_9,
+	GPIO65_LCD_LDD_10,
+	GPIO66_LCD_LDD_11,
+	GPIO67_LCD_LDD_12,
+	GPIO68_LCD_LDD_13,
+	GPIO69_LCD_LDD_14,
+	GPIO70_LCD_LDD_15,
+	GPIO71_LCD_LDD_16,
+	GPIO72_LCD_LDD_17,
+	GPIO73_LCD_CS_N,
+	GPIO74_LCD_VSYNC,
+	GPIO14_2_LCD_FCLK,
+	GPIO15_2_LCD_LCLK,
+	GPIO16_2_LCD_PCLK,
+	GPIO17_2_LCD_BIAS,
+};
+
+static void __init colibri_pxa320_init_lcd(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config));
+}
+#else
+static inline void colibri_pxa320_init_lcd(void) {}
+#endif
+
+#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = {
+	GPIO34_AC97_SYSCLK,
+	GPIO35_AC97_SDATA_IN_0,
+	GPIO37_AC97_SDATA_OUT,
+	GPIO38_AC97_SYNC,
+	GPIO39_AC97_BITCLK,
+	GPIO40_AC97_nACRESET
+};
+
+static inline void __init colibri_pxa320_init_ac97(void)
+{
+	pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config));
+	pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa320_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa320_init(void)
+{
+	colibri_pxa320_init_eth();
+	colibri_pxa320_init_ohci();
+	colibri_pxa320_init_lcd();
+	colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO));
+	colibri_pxa320_init_ac97();
+	colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa320_mmc_pin_config),
+				mfp_to_gpio(MFP_PIN_GPIO28));
+}
+
+MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= COLIBRI_SDRAM_BASE + 0x100,
+	.init_machine	= colibri_pxa320_init,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa3xx_init_irq,
+	.timer		= &pxa_timer,
+MACHINE_END
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/colibri-pxa3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,156 @@
+/*
+ *  arch/arm/mach-pxa/colibri-pxa3xx.c
+ *
+ *  Common functions for all Toradex PXA3xx modules
+ *
+ *  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 version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/colibri.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define ETHER_ADDR_LEN 6
+static u8 ether_mac_addr[ETHER_ADDR_LEN];
+
+void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data)
+{
+	int i;
+	u64 serial = ((u64) system_serial_high << 32) | system_serial_low;
+
+	/*
+	 * If the bootloader passed in a serial boot tag, which contains a
+	 * valid ethernet MAC, pass it to the interface. Toradex ships the
+	 * modules with their own bootloader which provides a valid MAC
+	 * this way.
+	 */
+
+	for (i = 0; i < ETHER_ADDR_LEN; i++) {
+		ether_mac_addr[i] = serial & 0xff;
+		serial >>= 8;
+	}
+
+	if (is_valid_ether_addr(ether_mac_addr)) {
+		plat_data->flags |= AXFLG_MAC_FROMPLATFORM;
+		plat_data->mac_addr = ether_mac_addr;
+		printk(KERN_INFO "%s(): taking MAC from serial boot tag\n",
+			__func__);
+	} else {
+		plat_data->flags |= AXFLG_MAC_FROMDEV;
+		printk(KERN_INFO "%s(): no valid serial boot tag found, "
+			"taking MAC from device\n", __func__);
+	}
+}
+#endif
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static int mmc_detect_pin;
+
+static int colibri_pxa3xx_mci_init(struct device *dev,
+				   irq_handler_t colibri_mmc_detect_int,
+				   void *data)
+{
+	int ret;
+
+	ret = gpio_request(mmc_detect_pin, "mmc card detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(mmc_detect_pin);
+	ret = request_irq(gpio_to_irq(mmc_detect_pin), colibri_mmc_detect_int,
+			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			  "MMC card detect", data);
+	if (ret) {
+		gpio_free(mmc_detect_pin);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void colibri_pxa3xx_mci_exit(struct device *dev, void *data)
+{
+	free_irq(mmc_detect_pin, data);
+	gpio_free(gpio_to_irq(mmc_detect_pin));
+}
+
+static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
+	.detect_delay	= 20,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.init		= colibri_pxa3xx_mci_init,
+	.exit		= colibri_pxa3xx_mci_exit,
+};
+
+void __init colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin)
+{
+	pxa3xx_mfp_config(pins, len);
+	mmc_detect_pin = detect_pin;
+	pxa_set_mci_info(&colibri_pxa3xx_mci_platform_data);
+}
+#endif /* CONFIG_MMC_PXA || CONFIG_MMC_PXA_MODULE */
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static int lcd_bl_pin;
+
+/*
+ * LCD panel (Sharp LQ043T3DX02)
+ */
+static void colibri_lcd_backlight(int on)
+{
+	gpio_set_value(lcd_bl_pin, !!on);
+}
+
+static struct pxafb_mode_info sharp_lq43_mode = {
+	.pixclock	= 101936,
+	.xres		= 480,
+	.yres		= 272,
+	.bpp		= 32,
+	.depth		= 18,
+	.hsync_len      = 41,
+	.left_margin    = 2,
+	.right_margin   = 2,
+	.vsync_len      = 10,
+	.upper_margin   = 2,
+	.lower_margin   = 2,
+	.sync	   	= 0,
+	.cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lq43_info = {
+	.modes		= &sharp_lq43_mode,
+	.num_modes	= 1,
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+	.lcd_conn	= LCD_COLOR_TFT_18BPP,
+	.pxafb_backlight_power = colibri_lcd_backlight,
+};
+
+void __init colibri_pxa3xx_init_lcd(int bl_pin)
+{
+	lcd_bl_pin = bl_pin;
+	gpio_request(bl_pin, "lcd backlight");
+	gpio_direction_output(bl_pin, 0);
+	set_pxa_fb_info(&sharp_lq43_info);
+}
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,9 +41,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
 #include <mach/i2c.h>
 #include <mach/irda.h>
 #include <mach/mmc.h>
@@ -429,12 +427,22 @@ static struct pxa2xx_spi_master corgi_sp
 	.num_chipselect	= 3,
 };
 
+static void corgi_wait_for_hsync(void)
+{
+	while (gpio_get_value(CORGI_GPIO_HSYNC))
+		cpu_relax();
+
+	while (!gpio_get_value(CORGI_GPIO_HSYNC))
+		cpu_relax();
+}
+
 static struct ads7846_platform_data corgi_ads7846_info = {
 	.model			= 7846,
 	.vref_delay_usecs	= 100,
 	.x_plate_ohms		= 419,
 	.y_plate_ohms		= 486,
 	.gpio_pendown		= CORGI_GPIO_TP_INT,
+	.wait_for_sync		= corgi_wait_for_hsync,
 };
 
 static void corgi_ads7846_cs(u32 command)
@@ -637,16 +645,16 @@ static void corgi_poweroff(void)
 		/* Green LED off tells the bootloader to halt */
 		gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
 
-	arm_machine_restart('h');
+	arm_machine_restart('h', NULL);
 }
 
-static void corgi_restart(char mode)
+static void corgi_restart(char mode, const char *cmd)
 {
 	if (!machine_is_corgi())
 		/* Green LED on tells the bootloader to reboot */
 		gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
 
-	arm_machine_restart('h');
+	arm_machine_restart('h', cmd);
 }
 
 static void __init corgi_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_lcd.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_lcd.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_lcd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_lcd.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/string.h>
 #include <mach/corgi.h>
 #include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/sharpsl.h>
 #include <mach/spitz.h>
 #include <asm/hardware/scoop.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,6 @@
 
 #include <mach/sharpsl.h>
 #include <mach/corgi.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx-gpio.h>
 #include "sharpsl.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_ssp.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_ssp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/corgi_ssp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/corgi_ssp.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@
 #include <asm/mach-types.h>
 
 #include <mach/ssp.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 #include <mach/regs-ssp.h>
 #include "sharpsl.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cpufreq-pxa2xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cpufreq-pxa2xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cpufreq-pxa2xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cpufreq-pxa2xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,8 +37,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 
 #ifdef DEBUG
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/cpufreq-pxa3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,8 +15,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa3xx-regs.h>
 
 #include "generic.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/csb701.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/csb701.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/csb701.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/csb701.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,66 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+
+static struct gpio_keys_button csb701_buttons[] = {
+	{
+		.code	= 0x7,
+		.gpio	= 1,
+		.active_low = 1,
+		.desc	= "SW2",
+		.type	= EV_SW,
+		.wakeup = 1,
+	},
+};
+
+static struct gpio_keys_platform_data csb701_gpio_keys_data = {
+	.buttons = csb701_buttons,
+	.nbuttons = ARRAY_SIZE(csb701_buttons),
+};
+
+static struct gpio_led csb701_leds[] = {
+	{
+		.name	= "csb701:yellow:heartbeat",
+		.default_trigger = "heartbeat",
+		.gpio	= 11,
+		.active_low = 1,
+	},
+};
+
+static struct platform_device csb701_gpio_keys = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev.platform_data = &csb701_gpio_keys_data,
+};
+
+static struct gpio_led_platform_data csb701_leds_gpio_data = {
+	.leds		= csb701_leds,
+	.num_leds	= ARRAY_SIZE(csb701_leds),
+};
+
+static struct platform_device csb701_leds_gpio = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev.platform_data = &csb701_leds_gpio_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&csb701_gpio_keys,
+	&csb701_leds_gpio,
+};
+
+static int __init csb701_init(void)
+{
+	if (!machine_is_csb726())
+		return -ENODEV;
+
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+module_init(csb701_init);
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/csb726.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/csb726.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/csb726.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/csb726.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,318 @@
+/*
+ *  Support for Cogent CSB726
+ *
+ *  Copyright (c) 2008 Dmitry Eremin-Solenikov
+ *
+ *  This program is free software; you can 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/io.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/sm501.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/csb726.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/i2c.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa2xx-regs.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/*
+ * n/a: 2, 5, 6, 7, 8, 23, 24, 25, 26, 27, 87, 88, 89,
+ * nu: 58 -- 77, 90, 91, 93, 102, 105-108, 114-116,
+ * XXX: 21,
+ * XXX: 79 CS_3 for LAN9215 or PSKTSEL on R2, R3
+ * XXX: 33 CS_5 for LAN9215 on R1
+ */
+
+static unsigned long csb726_pin_config[] = {
+	GPIO78_nCS_2, /* EXP_CS */
+	GPIO79_nCS_3, /* SMSC9215 */
+	GPIO80_nCS_4, /* SM501 */
+
+	GPIO52_GPIO, /* #SMSC9251 int */
+	GPIO53_GPIO, /* SM501 int */
+
+	GPIO1_GPIO, /* GPIO0 */
+	GPIO11_GPIO, /* GPIO1 */
+	GPIO9_GPIO, /* GPIO2 */
+	GPIO10_GPIO, /* GPIO3 */
+	GPIO16_PWM0_OUT, /* or GPIO4 */
+	GPIO17_PWM1_OUT, /* or GPIO5 */
+	GPIO94_GPIO, /* GPIO6 */
+	GPIO95_GPIO, /* GPIO7 */
+	GPIO96_GPIO, /* GPIO8 */
+	GPIO97_GPIO, /* GPIO9 */
+	GPIO15_GPIO, /* EXP_IRQ */
+	GPIO18_RDY, /* EXP_WAIT */
+
+	GPIO0_GPIO, /* PWR_INT */
+	GPIO104_GPIO, /* PWR_OFF */
+
+	GPIO12_GPIO, /* touch irq */
+
+	GPIO13_SSP2_TXD,
+	GPIO14_SSP2_SFRM,
+	MFP_CFG_OUT(GPIO19, AF1, DRIVE_LOW),/* SSP2_SYSCLK */
+	GPIO22_SSP2_SCLK,
+
+	GPIO81_SSP3_TXD,
+	GPIO82_SSP3_RXD,
+	GPIO83_SSP3_SFRM,
+	GPIO84_SSP3_SCLK,
+
+	GPIO20_GPIO, /* SDIO int */
+	GPIO32_MMC_CLK,
+	GPIO92_MMC_DAT_0,
+	GPIO109_MMC_DAT_1,
+	GPIO110_MMC_DAT_2,
+	GPIO111_MMC_DAT_3,
+	GPIO112_MMC_CMD,
+	GPIO100_GPIO, /* SD CD */
+	GPIO101_GPIO, /* SD WP */
+
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO113_AC97_nRESET,
+
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+	GPIO36_FFUART_DCD,
+	GPIO37_FFUART_DSR,
+	GPIO38_FFUART_RI,
+	GPIO39_FFUART_TXD,
+	GPIO40_FFUART_DTR,
+	GPIO41_FFUART_RTS,
+
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	GPIO46_STUART_RXD,
+	GPIO47_STUART_TXD,
+
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO54_nPCE_2,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16, /* maybe unused */
+	GPIO85_nPCE_1,
+	GPIO98_GPIO, /* CF IRQ */
+	GPIO99_GPIO, /* CF CD */
+	GPIO103_GPIO, /* Reset */
+
+	GPIO117_I2C_SCL,
+	GPIO118_I2C_SDA,
+};
+
+static struct pxamci_platform_data csb726_mci_data;
+
+static int csb726_mci_init(struct device *dev,
+		irq_handler_t detect, void *data)
+{
+	int err;
+
+	csb726_mci_data.detect_delay = msecs_to_jiffies(500);
+
+	err = gpio_request(CSB726_GPIO_MMC_DETECT, "MMC detect");
+	if (err)
+		goto err_det_req;
+
+	err = gpio_direction_input(CSB726_GPIO_MMC_DETECT);
+	if (err)
+		goto err_det_dir;
+
+	err = gpio_request(CSB726_GPIO_MMC_RO, "MMC ro");
+	if (err)
+		goto err_ro_req;
+
+	err = gpio_direction_input(CSB726_GPIO_MMC_RO);
+	if (err)
+		goto err_ro_dir;
+
+	err = request_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), detect,
+			IRQF_DISABLED, "MMC card detect", data);
+	if (err)
+		goto err_irq;
+
+	return 0;
+
+err_irq:
+err_ro_dir:
+	gpio_free(CSB726_GPIO_MMC_RO);
+err_ro_req:
+err_det_dir:
+	gpio_free(CSB726_GPIO_MMC_DETECT);
+err_det_req:
+	return err;
+}
+
+static int csb726_mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(CSB726_GPIO_MMC_RO);
+}
+
+static void csb726_mci_exit(struct device *dev, void *data)
+{
+	free_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), data);
+	gpio_free(CSB726_GPIO_MMC_RO);
+	gpio_free(CSB726_GPIO_MMC_DETECT);
+}
+
+static struct pxamci_platform_data csb726_mci = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init		= csb726_mci_init,
+	.get_ro		= csb726_mci_get_ro,
+	/* FIXME setpower */
+	.exit		= csb726_mci_exit,
+};
+
+static struct pxaohci_platform_data csb726_ohci_platform_data = {
+	.port_mode	= PMM_NPS_MODE,
+	.flags		= ENABLE_PORT1 | NO_OC_PROTECTION,
+};
+
+static struct mtd_partition csb726_flash_partitions[] = {
+	{
+		.name		= "Bootloader",
+		.offset		= 0,
+		.size		= CSB726_FLASH_uMON,
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	},
+	{
+		.name		= "root",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	}
+};
+
+static struct physmap_flash_data csb726_flash_data = {
+	.width		= 2,
+	.parts		= csb726_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(csb726_flash_partitions),
+};
+
+static struct resource csb726_flash_resources[] = {
+	{
+		.start          = PXA_CS0_PHYS,
+		.end            = PXA_CS0_PHYS + CSB726_FLASH_SIZE - 1 ,
+		.flags          = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device csb726_flash = {
+	.name           = "physmap-flash",
+	.dev            = {
+		.platform_data  = &csb726_flash_data,
+	},
+	.resource       = csb726_flash_resources,
+	.num_resources  = ARRAY_SIZE(csb726_flash_resources),
+};
+
+static struct resource csb726_sm501_resources[] = {
+	{
+		.start          = PXA_CS4_PHYS,
+		.end            = PXA_CS4_PHYS + SZ_8M - 1,
+		.flags          = IORESOURCE_MEM,
+		.name		= "sm501-localmem",
+	},
+	{
+		.start          = PXA_CS4_PHYS + SZ_64M - SZ_2M,
+		.end            = PXA_CS4_PHYS + SZ_64M - 1,
+		.flags          = IORESOURCE_MEM,
+		.name		= "sm501-regs",
+	},
+	{
+		.start		= CSB726_IRQ_SM501,
+		.end		= CSB726_IRQ_SM501,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct sm501_initdata csb726_sm501_initdata = {
+/*	.devices	= SM501_USE_USB_HOST, */
+	.devices	= SM501_USE_USB_HOST | SM501_USE_UART0 | SM501_USE_UART1,
+};
+
+static struct sm501_platdata csb726_sm501_platdata = {
+	.init		= &csb726_sm501_initdata,
+};
+
+static struct platform_device csb726_sm501 = {
+	.name		= "sm501",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(csb726_sm501_resources),
+	.resource	= csb726_sm501_resources,
+	.dev		= {
+		.platform_data = &csb726_sm501_platdata,
+	},
+};
+
+static struct resource csb726_lan_resources[] = {
+	{
+		.start	= PXA_CS3_PHYS,
+		.end	= PXA_CS3_PHYS + SZ_64K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= CSB726_IRQ_LAN,
+		.end	= CSB726_IRQ_LAN,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device csb726_lan = {
+	.name		= "smc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(csb726_lan_resources),
+	.resource	= csb726_lan_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&csb726_flash,
+	&csb726_sm501,
+	&csb726_lan,
+};
+
+static void __init csb726_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config));
+/*	MSC1 = 0x7ffc3ffc; *//* LAN9215/EXP_CS */
+/*	MSC2 = 0x06697ff4; *//* none/SM501 */
+	MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */
+
+	pxa_set_i2c_info(NULL);
+	pxa27x_set_i2c_power_info(NULL);
+	pxa_set_mci_info(&csb726_mci);
+	pxa_set_ohci_info(&csb726_ohci_platform_data);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(CSB726, "Cogent CSB726")
+	.phys_io	= 0x40000000,
+	.boot_params	= 0xa0000100,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io         = pxa_map_io,
+	.init_irq       = pxa27x_init_irq,
+	.init_machine   = csb726_init,
+	.timer          = &pxa_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/devices.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,6 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
-#include <mach/pxa-regs.h>
 #include <mach/udc.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
@@ -73,7 +72,10 @@ void __init pxa_set_mci_info(struct pxam
 }
 
 
-static struct pxa2xx_udc_mach_info pxa_udc_info;
+static struct pxa2xx_udc_mach_info pxa_udc_info = {
+	.gpio_pullup = -1,
+	.gpio_vbus   = -1,
+};
 
 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,146 +0,0 @@
-/*
- *  linux/arch/arm/mach-pxa/dma.c
- *
- *  PXA DMA registration and IRQ dispatching
- *
- *  Author:	Nicolas Pitre
- *  Created:	Nov 15, 2001
- *  Copyright:	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 version 2 as
- *  published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-
-#include <mach/pxa-regs.h>
-
-struct dma_channel {
-	char *name;
-	pxa_dma_prio prio;
-	void (*irq_handler)(int, void *);
-	void *data;
-};
-
-static struct dma_channel *dma_channels;
-static int num_dma_channels;
-
-int pxa_request_dma (char *name, pxa_dma_prio prio,
-			 void (*irq_handler)(int, void *),
-		 	 void *data)
-{
-	unsigned long flags;
-	int i, found = 0;
-
-	/* basic sanity checks */
-	if (!name || !irq_handler)
-		return -EINVAL;
-
-	local_irq_save(flags);
-
-	do {
-		/* try grabbing a DMA channel with the requested priority */
-		for (i = 0; i < num_dma_channels; i++) {
-			if ((dma_channels[i].prio == prio) &&
-			    !dma_channels[i].name) {
-				found = 1;
-				break;
-			}
-		}
-		/* if requested prio group is full, try a hier priority */
-	} while (!found && prio--);
-
-	if (found) {
-		DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-		dma_channels[i].name = name;
-		dma_channels[i].irq_handler = irq_handler;
-		dma_channels[i].data = data;
-	} else {
-		printk (KERN_WARNING "No more available DMA channels for %s\n", name);
-		i = -ENODEV;
-	}
-
-	local_irq_restore(flags);
-	return i;
-}
-
-void pxa_free_dma (int dma_ch)
-{
-	unsigned long flags;
-
-	if (!dma_channels[dma_ch].name) {
-		printk (KERN_CRIT
-			"%s: trying to free channel %d which is already freed\n",
-			__func__, dma_ch);
-		return;
-	}
-
-	local_irq_save(flags);
-	DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-	dma_channels[dma_ch].name = NULL;
-	local_irq_restore(flags);
-}
-
-static irqreturn_t dma_irq_handler(int irq, void *dev_id)
-{
-	int i, dint = DINT;
-
-	for (i = 0; i < num_dma_channels; i++) {
-		if (dint & (1 << i)) {
-			struct dma_channel *channel = &dma_channels[i];
-			if (channel->name && channel->irq_handler) {
-				channel->irq_handler(i, channel->data);
-			} else {
-				/*
-				 * IRQ for an unregistered DMA channel:
-				 * let's clear the interrupts and disable it.
-				 */
-				printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
-				DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-			}
-		}
-	}
-	return IRQ_HANDLED;
-}
-
-int __init pxa_init_dma(int num_ch)
-{
-	int i, ret;
-
-	dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
-	if (dma_channels == NULL)
-		return -ENOMEM;
-
-	/* dma channel priorities on pxa2xx processors:
-	 * ch 0 - 3,  16 - 19  <--> (0) DMA_PRIO_HIGH
-	 * ch 4 - 7,  20 - 23  <--> (1) DMA_PRIO_MEDIUM
-	 * ch 8 - 15, 24 - 31  <--> (2) DMA_PRIO_LOW
-	 */
-	for (i = 0; i < num_ch; i++) {
-		DCSR(i) = 0;
-		dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
-	}
-
-	ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
-	if (ret) {
-		printk (KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
-		kfree(dma_channels);
-		return ret;
-	}
-
-	num_dma_channels = num_ch;
-	return 0;
-}
-
-EXPORT_SYMBOL(pxa_request_dma);
-EXPORT_SYMBOL(pxa_free_dma);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e330.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e330.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e330.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e330.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,9 +20,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e350.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e350.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e350.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e350.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,9 +21,7 @@
 #include <asm/mach-types.h>
 
 #include <mach/irqs.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e400.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e400.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e400.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e400.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,9 +22,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/pxafb.h>
 #include <mach/udc.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e740.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e740.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e740.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e740.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,13 +24,12 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 #include <mach/irda.h>
 #include <mach/irqs.h>
+#include <mach/audio.h>
 
 #include "generic.h"
 #include "eseries.h"
@@ -135,6 +134,11 @@ static unsigned long e740_pin_config[] _
 	/* IrDA */
 	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
 
+	/* Audio power control */
+	GPIO16_GPIO,  /* AC97 codec AVDD2 supply (analogue power) */
+	GPIO40_GPIO,  /* Mic amp power */
+	GPIO41_GPIO,  /* Headphone amp power */
+
 	/* PC Card */
 	GPIO8_GPIO,   /* CD0 */
 	GPIO44_GPIO,  /* CD1 */
@@ -189,11 +193,12 @@ static void __init e740_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
 	eseries_register_clks();
-	clk_add_alias("CLK_CK48M", &e740_t7l66xb_device.dev,
+	clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
 			"UDCCLK", &pxa25x_device_udc.dev),
 	eseries_get_tmio_gpios();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_udc_info(&e7xx_udc_mach_info);
+	pxa_set_ac97_info(NULL);
 	e7xx_irda_init();
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e750.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e750.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e750.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e750.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,13 +23,12 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 #include <mach/irda.h>
 #include <mach/irqs.h>
+#include <mach/audio.h>
 
 #include "generic.h"
 #include "eseries.h"
@@ -133,6 +132,11 @@ static unsigned long e750_pin_config[] _
 	/* IrDA */
 	GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
 
+	/* Audio power control */
+	GPIO4_GPIO,  /* Headphone amp power */
+	GPIO7_GPIO,  /* Speaker amp power */
+	GPIO37_GPIO, /* Headphone detect */
+
 	/* PC Card */
 	GPIO8_GPIO,   /* CD0 */
 	GPIO44_GPIO,  /* CD1 */
@@ -190,11 +194,12 @@ static struct platform_device *devices[]
 static void __init e750_init(void)
 {
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config));
-	clk_add_alias("CLK_CK3P6MI", &e750_tc6393xb_device.dev,
+	clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_udc_info(&e7xx_udc_mach_info);
+	pxa_set_ac97_info(NULL);
 	e7xx_irda_init();
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e800.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e800.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/e800.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/e800.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,12 +23,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 #include <mach/irqs.h>
+#include <mach/audio.h>
 
 #include "generic.h"
 #include "eseries.h"
@@ -196,11 +195,12 @@ static struct platform_device *devices[]
 
 static void __init e800_init(void)
 {
-	clk_add_alias("CLK_CK3P6MI", &e800_tc6393xb_device.dev,
+	clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
 			"GPIO11_CLK", NULL),
 	eseries_get_tmio_gpios();
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_udc_info(&e800_udc_mach_info);
+	pxa_set_ac97_info(NULL);
 }
 
 MACHINE_START(E800, "Toshiba e800")
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/em-x270.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/em-x270.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/em-x270.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/em-x270.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,40 +11,66 @@
 
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 
 #include <linux/dm9000.h>
 #include <linux/rtc-v3020.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio.h>
+#include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+
+#include <media/soc_camera.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
 #include <mach/ohci.h>
 #include <mach/mmc.h>
 #include <mach/pxa27x_keypad.h>
+#include <mach/i2c.h>
+#include <mach/camera.h>
+#include <mach/pxa2xx_spi.h>
 
 #include "generic.h"
+#include "devices.h"
 
-/* GPIO IRQ usage */
-#define GPIO41_ETHIRQ		(41)
+/* EM-X270 specific GPIOs */
 #define GPIO13_MMC_CD		(13)
+#define GPIO95_MMC_WP		(95)
+#define GPIO56_NAND_RB		(56)
+
+/* eXeda specific GPIOs */
+#define GPIO114_MMC_CD		(114)
+#define GPIO20_NAND_RB		(20)
+#define GPIO38_SD_PWEN		(38)
+
+/* common  GPIOs */
+#define GPIO11_NAND_CS		(11)
+#define GPIO93_CAM_RESET	(93)
+#define GPIO41_ETHIRQ		(41)
 #define EM_X270_ETHIRQ		IRQ_GPIO(GPIO41_ETHIRQ)
-#define EM_X270_MMC_CD		IRQ_GPIO(GPIO13_MMC_CD)
+#define GPIO115_WLAN_PWEN	(115)
+#define GPIO19_WLAN_STRAP	(19)
 
-/* NAND control GPIOs */
-#define GPIO11_NAND_CS	(11)
-#define GPIO56_NAND_RB	(56)
+static int mmc_cd;
+static int nand_rb;
+static int dm9000_flags;
 
-static unsigned long em_x270_pin_config[] = {
+static unsigned long common_pin_config[] = {
 	/* AC'97 */
 	GPIO28_AC97_BITCLK,
 	GPIO29_AC97_SDATA_IN_0,
@@ -136,8 +162,8 @@ static unsigned long em_x270_pin_config[
 	GPIO57_SSP1_TXD,
 
 	/* SSP2 */
-	GPIO19_SSP2_SCLK,
-	GPIO14_SSP2_SFRM,
+	GPIO19_GPIO,	/* SSP2 clock is used as GPIO for Libertas pin-strap */
+	GPIO14_GPIO,
 	GPIO89_SSP2_TXD,
 	GPIO88_SSP2_RXD,
 
@@ -150,21 +176,32 @@ static unsigned long em_x270_pin_config[
 	GPIO18_RDY,
 
 	/* GPIO */
-	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+	GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,	/* sleep/resume button */
 
 	/* power controls */
 	GPIO20_GPIO	| MFP_LPM_DRIVE_LOW,	/* GPRS_PWEN */
+	GPIO93_GPIO	| MFP_LPM_DRIVE_LOW,	/* Camera reset */
 	GPIO115_GPIO	| MFP_LPM_DRIVE_LOW,	/* WLAN_PWEN */
 
 	/* NAND controls */
 	GPIO11_GPIO	| MFP_LPM_DRIVE_HIGH,	/* NAND CE# */
-	GPIO56_GPIO,				/* NAND Ready/Busy */
 
 	/* interrupts */
-	GPIO13_GPIO,	/* MMC card detect */
 	GPIO41_GPIO,	/* DM9000 interrupt */
 };
 
+static unsigned long em_x270_pin_config[] = {
+	GPIO13_GPIO,	/* MMC card detect */
+	GPIO56_GPIO,	/* NAND Ready/Busy */
+	GPIO95_GPIO,	/* MMC Write protect */
+};
+
+static unsigned long exeda_pin_config[] = {
+	GPIO20_GPIO,				/* NAND Ready/Busy */
+	GPIO38_GPIO	| MFP_LPM_DRIVE_LOW,	/* SD slot power */
+	GPIO114_GPIO,				/* MMC card detect */
+};
+
 #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
 static struct resource em_x270_dm9000_resource[] = {
 	[0] = {
@@ -185,7 +222,7 @@ static struct resource em_x270_dm9000_re
 };
 
 static struct dm9000_plat_data em_x270_dm9000_platdata = {
-	.flags		= DM9000_PLATF_32BITONLY,
+	.flags		= DM9000_PLATF_NO_EEPROM,
 };
 
 static struct platform_device em_x270_dm9000 = {
@@ -200,6 +237,7 @@ static struct platform_device em_x270_dm
 
 static void __init em_x270_init_dm9000(void)
 {
+	em_x270_dm9000_platdata.flags |= dm9000_flags;
 	platform_device_register(&em_x270_dm9000);
 }
 #else
@@ -289,7 +327,7 @@ static int em_x270_nand_device_ready(str
 {
 	dsb();
 
-	return gpio_get_value(GPIO56_NAND_RB);
+	return gpio_get_value(nand_rb);
 }
 
 static struct mtd_partition em_x270_partition_info[] = {
@@ -354,14 +392,14 @@ static void __init em_x270_init_nand(voi
 
 	gpio_direction_output(GPIO11_NAND_CS, 1);
 
-	err = gpio_request(GPIO56_NAND_RB, "NAND R/B");
+	err = gpio_request(nand_rb, "NAND R/B");
 	if (err) {
 		pr_warning("EM-X270: failed to request NAND R/B gpio\n");
 		gpio_free(GPIO11_NAND_CS);
 		return;
 	}
 
-	gpio_direction_input(GPIO56_NAND_RB);
+	gpio_direction_input(nand_rb);
 
 	platform_device_register(&em_x270_nand);
 }
@@ -369,6 +407,61 @@ static void __init em_x270_init_nand(voi
 static inline void em_x270_init_nand(void) {}
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition em_x270_nor_parts[] = {
+	{
+		.name =		"Bootloader",
+		.offset =	0x00000000,
+		.size =		0x00050000,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	}, {
+		.name =		"Environment",
+		.offset =	0x00050000,
+		.size =		0x00010000,
+	}, {
+		.name =		"Reserved",
+		.offset =	0x00060000,
+		.size =		0x00050000,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	}, {
+		.name =		"Splashscreen",
+		.offset =	0x000b0000,
+		.size =		0x00050000,
+	}
+};
+
+static struct physmap_flash_data em_x270_nor_data[] = {
+	[0] = {
+		.width = 2,
+		.parts = em_x270_nor_parts,
+		.nr_parts = ARRAY_SIZE(em_x270_nor_parts),
+	},
+};
+
+static struct resource em_x270_nor_flash_resource = {
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_1M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device em_x270_physmap_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= &em_x270_nor_flash_resource,
+	.dev		= {
+		.platform_data	= &em_x270_nor_data,
+	},
+};
+
+static void __init em_x270_init_nor(void)
+{
+	platform_device_register(&em_x270_physmap_flash);
+}
+#else
+static inline void em_x270_init_nor(void) {}
+#endif
+
 /* PXA27x OHCI controller setup */
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static int em_x270_ohci_init(struct device *dev)
@@ -395,40 +488,93 @@ static inline void em_x270_init_ohci(voi
 
 /* MCI controller setup */
 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+static struct regulator *em_x270_sdio_ldo;
+
 static int em_x270_mci_init(struct device *dev,
 			    irq_handler_t em_x270_detect_int,
 			    void *data)
 {
-	int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
-			      IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+	int err;
+
+	em_x270_sdio_ldo = regulator_get(dev, "vcc sdio");
+	if (IS_ERR(em_x270_sdio_ldo)) {
+		dev_err(dev, "can't request SDIO power supply: %ld\n",
+			PTR_ERR(em_x270_sdio_ldo));
+		return PTR_ERR(em_x270_sdio_ldo);
+	}
+
+	err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int,
+			      IRQF_DISABLED | IRQF_TRIGGER_RISING |
+			      IRQF_TRIGGER_FALLING,
 			      "MMC card detect", data);
 	if (err) {
-		printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
-		       __func__, err);
-		return err;
+		dev_err(dev, "can't request MMC card detect IRQ: %d\n", err);
+		goto err_irq;
+	}
+
+	if (machine_is_em_x270()) {
+		err = gpio_request(GPIO95_MMC_WP, "MMC WP");
+		if (err) {
+			dev_err(dev, "can't request MMC write protect: %d\n",
+				err);
+			goto err_gpio_wp;
+		}
+		gpio_direction_input(GPIO95_MMC_WP);
+	} else {
+		err = gpio_request(GPIO38_SD_PWEN, "sdio power");
+		if (err) {
+			dev_err(dev, "can't request MMC power control : %d\n",
+				err);
+			goto err_gpio_wp;
+		}
+		gpio_direction_output(GPIO38_SD_PWEN, 1);
 	}
 
 	return 0;
+
+err_gpio_wp:
+	free_irq(gpio_to_irq(mmc_cd), data);
+err_irq:
+	regulator_put(em_x270_sdio_ldo);
+
+	return err;
 }
 
 static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
 {
-	/*
-	   FIXME: current hardware implementation does not allow to
-	   enable/disable MMC power. This will be fixed in next HW releases,
-	   and we'll need to add implmentation here.
-	*/
-	return;
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if ((1 << vdd) & p_d->ocr_mask) {
+		int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
+
+		regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
+		regulator_enable(em_x270_sdio_ldo);
+	} else {
+		regulator_disable(em_x270_sdio_ldo);
+	}
 }
 
 static void em_x270_mci_exit(struct device *dev, void *data)
 {
-	int irq = gpio_to_irq(GPIO13_MMC_CD);
-	free_irq(irq, data);
+	free_irq(gpio_to_irq(mmc_cd), data);
+	regulator_put(em_x270_sdio_ldo);
+
+	if (machine_is_em_x270())
+		gpio_free(GPIO95_MMC_WP);
+	else
+		gpio_free(GPIO38_SD_PWEN);
+}
+
+static int em_x270_mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO95_MMC_WP);
 }
 
 static struct pxamci_platform_data em_x270_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
+	.ocr_mask	= MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
+			  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
+			  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
+			  MMC_VDD_30_31|MMC_VDD_31_32,
 	.init 		= em_x270_mci_init,
 	.setpower 	= em_x270_mci_setpower,
 	.exit		= em_x270_mci_exit,
@@ -436,33 +582,53 @@ static struct pxamci_platform_data em_x2
 
 static void __init em_x270_init_mmc(void)
 {
+	if (machine_is_em_x270())
+		em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
+
+	em_x270_mci_platform_data.detect_delay	= msecs_to_jiffies(250);
 	pxa_set_mci_info(&em_x270_mci_platform_data);
 }
 #else
 static inline void em_x270_init_mmc(void) {}
 #endif
 
-/* LCD 480x640 */
+/* LCD */
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-static struct pxafb_mode_info em_x270_lcd_mode = {
-	.pixclock	= 50000,
-	.bpp		= 16,
-	.xres		= 480,
-	.yres		= 640,
-	.hsync_len	= 8,
-	.vsync_len	= 2,
-	.left_margin	= 8,
-	.upper_margin	= 0,
-	.right_margin	= 24,
-	.lower_margin	= 4,
-	.cmap_greyscale	= 0,
+static struct pxafb_mode_info em_x270_lcd_modes[] = {
+	[0] = {
+		.pixclock	= 38250,
+		.bpp		= 16,
+		.xres		= 480,
+		.yres		= 640,
+		.hsync_len	= 8,
+		.vsync_len	= 2,
+		.left_margin	= 8,
+		.upper_margin	= 2,
+		.right_margin	= 24,
+		.lower_margin	= 4,
+		.sync		= 0,
+	},
+	[1] = {
+		.pixclock       = 153800,
+		.bpp		= 16,
+		.xres		= 240,
+		.yres		= 320,
+		.hsync_len	= 8,
+		.vsync_len	= 2,
+		.left_margin	= 8,
+		.upper_margin	= 2,
+		.right_margin	= 88,
+		.lower_margin	= 2,
+		.sync		= 0,
+	},
 };
 
 static struct pxafb_mach_info em_x270_lcd = {
-	.modes		= &em_x270_lcd_mode,
-	.num_modes	= 1,
+	.modes		= em_x270_lcd_modes,
+	.num_modes	= 2,
 	.lcd_conn	= LCD_COLOR_TFT_16BPP,
 };
+
 static void __init em_x270_init_lcd(void)
 {
 	set_pxa_fb_info(&em_x270_lcd);
@@ -471,6 +637,107 @@ static void __init em_x270_init_lcd(void
 static inline void em_x270_init_lcd(void) {}
 #endif
 
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master em_x270_spi_info = {
+	.num_chipselect	= 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_tdo24m_chip = {
+	.rx_threshold	= 1,
+	.tx_threshold	= 1,
+	.gpio_cs	= -1,
+};
+
+static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
+	.model = TDO35S,
+};
+
+static struct pxa2xx_spi_master em_x270_spi_2_info = {
+	.num_chipselect	= 1,
+	.enable_dma	= 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_libertas_chip = {
+	.rx_threshold	= 1,
+	.tx_threshold	= 1,
+	.timeout	= 1000,
+};
+
+static unsigned long em_x270_libertas_pin_config[] = {
+	/* SSP2 */
+	GPIO19_SSP2_SCLK,
+	GPIO14_GPIO,
+	GPIO89_SSP2_TXD,
+	GPIO88_SSP2_RXD,
+};
+
+static int em_x270_libertas_setup(struct spi_device *spi)
+{
+	int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN");
+	if (err)
+		return err;
+
+	gpio_direction_output(GPIO19_WLAN_STRAP, 1);
+	mdelay(100);
+
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config));
+
+	gpio_direction_output(GPIO115_WLAN_PWEN, 0);
+	mdelay(100);
+	gpio_set_value(GPIO115_WLAN_PWEN, 1);
+	mdelay(100);
+
+	spi->bits_per_word = 16;
+	spi_setup(spi);
+
+	return 0;
+}
+
+static int em_x270_libertas_teardown(struct spi_device *spi)
+{
+	gpio_set_value(GPIO115_WLAN_PWEN, 0);
+	gpio_free(GPIO115_WLAN_PWEN);
+
+	return 0;
+}
+
+struct libertas_spi_platform_data em_x270_libertas_pdata = {
+	.use_dummy_writes	= 1,
+	.gpio_cs		= 14,
+	.setup			= em_x270_libertas_setup,
+	.teardown		= em_x270_libertas_teardown,
+};
+
+static struct spi_board_info em_x270_spi_devices[] __initdata = {
+	{
+		.modalias		= "tdo24m",
+		.max_speed_hz		= 1000000,
+		.bus_num		= 1,
+		.chip_select		= 0,
+		.controller_data	= &em_x270_tdo24m_chip,
+		.platform_data		= &em_x270_tdo24m_pdata,
+	},
+	{
+		.modalias		= "libertas_spi",
+		.max_speed_hz		= 13000000,
+		.bus_num		= 2,
+		.irq			= IRQ_GPIO(116),
+		.chip_select		= 0,
+		.controller_data	= &em_x270_libertas_chip,
+		.platform_data		= &em_x270_libertas_pdata,
+	},
+};
+
+static void __init em_x270_init_spi(void)
+{
+	pxa2xx_set_spi_info(1, &em_x270_spi_info);
+	pxa2xx_set_spi_info(2, &em_x270_spi_2_info);
+	spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices));
+}
+#else
+static inline void em_x270_init_spi(void) {}
+#endif
+
 #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
 static void __init em_x270_init_ac97(void)
 {
@@ -481,23 +748,76 @@ static inline void em_x270_init_ac97(voi
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int em_x270_matrix_keys[] = {
+static unsigned int em_x270_module_matrix_keys[] = {
 	KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
 	KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
 	KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
 };
 
-struct pxa27x_keypad_platform_data em_x270_keypad_info = {
+struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
 	/* code map for the matrix keys */
 	.matrix_key_rows	= 3,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= em_x270_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(em_x270_matrix_keys),
+	.matrix_key_map		= em_x270_module_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
+static unsigned int em_x270_exeda_matrix_keys[] = {
+	KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
+	KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
+	KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
+	KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH),
+
+	KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M),
+	KEY(1, 2, KEY_N), KEY(1, 3, KEY_B),
+	KEY(1, 4, KEY_V), KEY(1, 5, KEY_C),
+	KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z),
+
+	KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON),
+	KEY(2, 2, KEY_L), KEY(2, 3, KEY_K),
+	KEY(2, 4, KEY_J), KEY(2, 5, KEY_H),
+	KEY(2, 6, KEY_G), KEY(2, 7, KEY_F),
+
+	KEY(3, 0, KEY_D), KEY(3, 1, KEY_S),
+	KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB),
+	KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P),
+	KEY(3, 6, KEY_O), KEY(3, 7, KEY_I),
+
+	KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y),
+	KEY(4, 2, KEY_T), KEY(4, 3, KEY_R),
+	KEY(4, 4, KEY_E), KEY(4, 5, KEY_W),
+	KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS),
+
+	KEY(5, 0, KEY_0), KEY(5, 1, KEY_9),
+	KEY(5, 2, KEY_8), KEY(5, 3, KEY_7),
+	KEY(5, 4, KEY_6), KEY(5, 5, KEY_5),
+	KEY(5, 6, KEY_4), KEY(5, 7, KEY_3),
+
+	KEY(6, 0, KEY_2), KEY(6, 1, KEY_1),
+	KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END),
+	KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP),
+	KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1),
+
+	KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT),
+	KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME),
+	KEY(7, 4, 0), KEY(7, 5, 0),
+	KEY(7, 6, 0), KEY(7, 7, 0),
+};
+
+struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
+	/* code map for the matrix keys */
+	.matrix_key_rows	= 8,
+	.matrix_key_cols	= 8,
+	.matrix_key_map		= em_x270_exeda_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(em_x270_exeda_matrix_keys),
 };
 
 static void __init em_x270_init_keypad(void)
 {
-	pxa_set_keypad_info(&em_x270_keypad_info);
+	if (machine_is_em_x270())
+		pxa_set_keypad_info(&em_x270_module_keypad_info);
+	else
+		pxa_set_keypad_info(&em_x270_exeda_keypad_info);
 }
 #else
 static inline void em_x270_init_keypad(void) {}
@@ -535,25 +855,280 @@ static void __init em_x270_init_gpio_key
 static inline void em_x270_init_gpio_keys(void) {}
 #endif
 
-static void __init em_x270_init(void)
+/* Quick Capture Interface and sensor setup */
+#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)
+{
+	int ret;
+
+	ret = gpio_request(GPIO93_CAM_RESET, "camera reset");
+	if (ret)
+		return ret;
+
+	gpio_direction_output(GPIO93_CAM_RESET, 0);
+
+	em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
+	if (em_x270_camera_ldo == NULL) {
+		gpio_free(GPIO93_CAM_RESET);
+		return -ENODEV;
+	}
+
+	ret = regulator_enable(em_x270_camera_ldo);
+	if (ret) {
+		regulator_put(em_x270_camera_ldo);
+		gpio_free(GPIO93_CAM_RESET);
+		return ret;
+	}
+
+	gpio_set_value(GPIO93_CAM_RESET, 1);
+
+	return 0;
+}
+
+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,
+};
+
+static int em_x270_sensor_power(struct device *dev, int on)
+{
+	int ret;
+	int is_on = regulator_is_enabled(em_x270_camera_ldo);
+
+	if (on == is_on)
+		return 0;
+
+	gpio_set_value(GPIO93_CAM_RESET, !on);
+
+	if (on)
+		ret = regulator_enable(em_x270_camera_ldo);
+	else
+		ret = regulator_disable(em_x270_camera_ldo);
+
+	if (ret)
+		return ret;
+
+	gpio_set_value(GPIO93_CAM_RESET, on);
+
+	return 0;
+}
+
+static struct soc_camera_link iclink = {
+	.bus_id	= 0,
+	.power = em_x270_sensor_power,
+};
+
+static struct i2c_board_info em_x270_i2c_cam_info[] = {
+	{
+		I2C_BOARD_INFO("mt9m111", 0x48),
+		.platform_data = &iclink,
+	},
+};
+
+static struct i2c_pxa_platform_data em_x270_i2c_info = {
+	.fast_mode = 1,
+};
+
+static void  __init em_x270_init_camera(void)
+{
+	pxa_set_i2c_info(&em_x270_i2c_info);
+	i2c_register_board_info(0, ARRAY_AND_SIZE(em_x270_i2c_cam_info));
+	pxa_set_camera_info(&em_x270_camera_platform_data);
+}
+#else
+static inline void em_x270_init_camera(void) {}
+#endif
+
+/* DA9030 related initializations */
+#define REGULATOR_CONSUMER(_name, _dev, _supply)			       \
+	static struct regulator_consumer_supply _name##_consumers[] = {	\
+		{							\
+			.dev = _dev,					\
+			.supply = _supply,				\
+		},							\
+	}
+
+REGULATOR_CONSUMER(ldo3, NULL, "vcc gps");
+REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
+REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio");
+REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
+REGULATOR_CONSUMER(ldo19, NULL, "vcc gprs");
+
+#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask)		\
+	static struct regulator_init_data _ldo##_data = {		\
+		.constraints = {					\
+			.min_uV = _min_uV,				\
+			.max_uV = _max_uV,				\
+			.state_mem = {					\
+				.enabled = 0,				\
+			},						\
+			.valid_ops_mask = _ops_mask,			\
+		},							\
+		.num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers),	\
+		.consumer_supplies = _ldo##_consumers,			\
+	};
+
+REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo10, 2000000, 3200000,
+	       REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE);
+REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+
+struct led_info em_x270_led_info = {
+	.name = "em-x270:orange",
+	.default_trigger = "battery-charging-or-full",
+};
+
+struct power_supply_info em_x270_psy_info = {
+	.name = "LP555597P6H-FPS",
+	.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.voltage_max_design = 4200000,
+	.voltage_min_design = 3000000,
+	.use_for_apm = 1,
+};
+
+static void em_x270_battery_low(void)
+{
+	apm_queue_event(APM_LOW_BATTERY);
+}
+
+static void em_x270_battery_critical(void)
+{
+	apm_queue_event(APM_CRITICAL_SUSPEND);
+}
+
+struct da9030_battery_info em_x270_batterty_info = {
+	.battery_info = &em_x270_psy_info,
+
+	.charge_milliamp = 1000,
+	.charge_millivolt = 4200,
+
+	.vbat_low = 3600,
+	.vbat_crit = 3400,
+	.vbat_charge_start = 4100,
+	.vbat_charge_stop = 4200,
+	.vbat_charge_restart = 4000,
+
+	.vcharge_min = 3200,
+	.vcharge_max = 5500,
+
+	.tbat_low = 197,
+	.tbat_high = 78,
+	.tbat_restart = 100,
+
+	.batmon_interval = 0,
+
+	.battery_low = em_x270_battery_low,
+	.battery_critical = em_x270_battery_critical,
+};
+
+#define DA9030_SUBDEV(_name, _id, _pdata)	\
+	{					\
+		.name = "da903x-" #_name,	\
+		.id = DA9030_ID_##_id,		\
+		.platform_data = _pdata,	\
+	}
+
+#define DA9030_LDO(num)	DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data)
+
+struct da903x_subdev_info em_x270_da9030_subdevs[] = {
+	DA9030_LDO(3),
+	DA9030_LDO(5),
+	DA9030_LDO(10),
+	DA9030_LDO(12),
+	DA9030_LDO(19),
+
+	DA9030_SUBDEV(led, LED_PC, &em_x270_led_info),
+	DA9030_SUBDEV(backlight, WLED, &em_x270_led_info),
+	DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info),
+};
+
+static struct da903x_platform_data em_x270_da9030_info = {
+	.num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs),
+	.subdevs = em_x270_da9030_subdevs,
+};
+
+static struct i2c_board_info em_x270_i2c_pmic_info = {
+	I2C_BOARD_INFO("da9030", 0x49),
+	.irq = IRQ_GPIO(0),
+	.platform_data = &em_x270_da9030_info,
+};
+
+static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = {
+	.use_pio = 1,
+};
+
+static void __init em_x270_init_da9030(void)
 {
+	pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info);
+	i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1);
+}
+
+static void __init em_x270_module_init(void)
+{
+	pr_info("%s\n", __func__);
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
 
+	mmc_cd = GPIO13_MMC_CD;
+	nand_rb = GPIO56_NAND_RB;
+	dm9000_flags = DM9000_PLATF_32BITONLY;
+}
+
+static void __init em_x270_exeda_init(void)
+{
+	pr_info("%s\n", __func__);
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config));
+
+	mmc_cd = GPIO114_MMC_CD;
+	nand_rb = GPIO20_NAND_RB;
+	dm9000_flags = DM9000_PLATF_16BITONLY;
+}
+
+static void __init em_x270_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+	if (machine_is_em_x270())
+		em_x270_module_init();
+	else if (machine_is_exeda())
+		em_x270_exeda_init();
+	else
+		panic("Unsupported machine: %d\n", machine_arch_type);
+
+	em_x270_init_da9030();
 	em_x270_init_dm9000();
 	em_x270_init_rtc();
 	em_x270_init_nand();
+	em_x270_init_nor();
 	em_x270_init_lcd();
 	em_x270_init_mmc();
 	em_x270_init_ohci();
 	em_x270_init_keypad();
 	em_x270_init_gpio_keys();
 	em_x270_init_ac97();
+	em_x270_init_camera();
+	em_x270_init_spi();
 }
 
 MACHINE_START(EM_X270, "Compulab EM-X270")
 	.boot_params	= 0xa0000100,
 	.phys_io	= 0x40000000,
 	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= em_x270_init,
+MACHINE_END
+
+MACHINE_START(EXEDA, "Compulab eXeda")
+	.boot_params	= 0xa0000100,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
 	.map_io		= pxa_map_io,
 	.init_irq	= pxa27x_init_irq,
 	.timer		= &pxa_timer,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/eseries.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/eseries.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/eseries.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/eseries.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,8 +20,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
-#include <mach/mfp-pxa25x.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
 #include <mach/eseries-gpio.h>
 #include <mach/udc.h>
 #include <mach/irda.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/ezx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/ezx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/ezx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/ezx.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,18 +19,16 @@
 #include <linux/input.h>
 
 #include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
 #include <mach/pxafb.h>
 #include <mach/ohci.h>
 #include <mach/i2c.h>
 #include <mach/hardware.h>
 #include <mach/pxa27x_keypad.h>
 
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
 #include "devices.h"
 #include "generic.h"
 
@@ -113,9 +111,9 @@ static unsigned long ezx_pin_config[] __
 	GPIO25_SSP1_TXD,
 	GPIO26_SSP1_RXD,
 	GPIO24_GPIO,				/* pcap chip select */
-	GPIO1_GPIO,				/* pcap interrupt */
-	GPIO4_GPIO,				/* WDI_AP */
-	GPIO55_GPIO,				/* SYS_RESTART */
+	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,	/* pcap interrupt */
+	GPIO4_GPIO | MFP_LPM_DRIVE_HIGH,	/* WDI_AP */
+	GPIO55_GPIO | MFP_LPM_DRIVE_HIGH,	/* SYS_RESTART */
 
 	/* MMC */
 	GPIO32_MMC_CLK,
@@ -146,20 +144,20 @@ static unsigned long ezx_pin_config[] __
 #if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680)
 static unsigned long gen1_pin_config[] __initdata = {
 	/* flip / lockswitch */
-	GPIO12_GPIO,
+	GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH,
 
 	/* bluetooth (bcm2035) */
-	GPIO14_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* HOSTWAKE */
+	GPIO14_GPIO | WAKEUP_ON_EDGE_RISE,	/* HOSTWAKE */
 	GPIO48_GPIO,				/* RESET */
 	GPIO28_GPIO,				/* WAKEUP */
 
 	/* Neptune handshake */
-	GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* BP_RDY */
-	GPIO57_GPIO,				/* AP_RDY */
-	GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* WDI */
-	GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* WDI2 */
-	GPIO82_GPIO,				/* RESET */
-	GPIO99_GPIO,				/* TC_MM_EN */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,	/* BP_RDY */
+	GPIO57_GPIO | MFP_LPM_DRIVE_HIGH,	/* AP_RDY */
+	GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH,	/* WDI */
+	GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,	/* WDI2 */
+	GPIO82_GPIO | MFP_LPM_DRIVE_HIGH,	/* RESET */
+	GPIO99_GPIO | MFP_LPM_DRIVE_HIGH,	/* TC_MM_EN */
 
 	/* sound */
 	GPIO52_SSP3_SCLK,
@@ -201,21 +199,21 @@ static unsigned long gen1_pin_config[] _
 	defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6)
 static unsigned long gen2_pin_config[] __initdata = {
 	/* flip / lockswitch */
-	GPIO15_GPIO,
+	GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,
 
 	/* EOC */
-	GPIO10_GPIO,
+	GPIO10_GPIO | WAKEUP_ON_EDGE_RISE,
 
 	/* bluetooth (bcm2045) */
-	GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* HOSTWAKE */
+	GPIO13_GPIO | WAKEUP_ON_EDGE_RISE,	/* HOSTWAKE */
 	GPIO37_GPIO,				/* RESET */
 	GPIO57_GPIO,				/* WAKEUP */
 
 	/* Neptune handshake */
-	GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* BP_RDY */
-	GPIO96_GPIO,				/* AP_RDY */
-	GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH,	/* WDI */
-	GPIO116_GPIO,				/* RESET */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,	/* BP_RDY */
+	GPIO96_GPIO | MFP_LPM_DRIVE_HIGH,	/* AP_RDY */
+	GPIO3_GPIO | WAKEUP_ON_EDGE_FALL,	/* WDI */
+	GPIO116_GPIO | MFP_LPM_DRIVE_HIGH,	/* RESET */
 	GPIO41_GPIO,				/* BP_FLASH */
 
 	/* sound */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/generic.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/generic.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,8 +26,9 @@
 #include <asm/mach/map.h>
 #include <asm/mach-types.h>
 
-#include <mach/pxa-regs.h>
 #include <mach/reset.h>
+#include <mach/gpio.h>
+#include <mach/pxa2xx-gpio.h>
 
 #include "generic.h"
 
@@ -127,3 +128,33 @@ void __init pxa_map_io(void)
 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
 	get_clk_frequency_khz(1);
 }
+
+/*
+ * Configure pins for GPIO or other functions
+ */
+int pxa_gpio_mode(int gpio_mode)
+{
+	unsigned long flags;
+	int gpio = gpio_mode & GPIO_MD_MASK_NR;
+	int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
+	int gafr;
+
+	if (gpio > pxa_last_gpio)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	if (gpio_mode & GPIO_DFLT_LOW)
+		GPCR(gpio) = GPIO_bit(gpio);
+	else if (gpio_mode & GPIO_DFLT_HIGH)
+		GPSR(gpio) = GPIO_bit(gpio);
+	if (gpio_mode & GPIO_MD_MASK_DIR)
+		GPDR(gpio) |= GPIO_bit(gpio);
+	else
+		GPDR(gpio) &= ~GPIO_bit(gpio);
+	gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
+	GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
+	local_irq_restore(flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(pxa_gpio_mode);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/generic.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/generic.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/generic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/generic.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,20 +9,20 @@
  * published by the Free Software Foundation.
  */
 
-typedef int (*set_wake_t)(unsigned int, unsigned int);
-
 struct sys_timer;
 
 extern struct sys_timer pxa_timer;
-extern void __init pxa_init_irq(int irq_nr, set_wake_t fn);
-extern void __init pxa_init_gpio(int gpio_nr, set_wake_t fn);
+extern void __init pxa_init_irq(int irq_nr,
+				int (*set_wake)(unsigned int, unsigned int));
 extern void __init pxa25x_init_irq(void);
+#ifdef CONFIG_CPU_PXA26x
+extern void __init pxa26x_init_irq(void);
+#endif
 extern void __init pxa27x_init_irq(void);
 extern void __init pxa3xx_init_irq(void);
 extern void __init pxa_map_io(void);
 
 extern unsigned int get_clk_frequency_khz(int info);
-extern int pxa_last_gpio;
 
 #define SET_BANK(__nr,__start,__size) \
 	mi->bank[__nr].start = (__start), \
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/gpio.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,453 +0,0 @@
-/*
- *  linux/arch/arm/mach-pxa/gpio.c
- *
- *  Generic PXA GPIO handling
- *
- *  Author:	Nicolas Pitre
- *  Created:	Jun 15, 2001
- *  Copyright:	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 version 2 as
- *  published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <asm/gpio.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
-
-#include "generic.h"
-
-#define GPIO0_BASE	((void __iomem *)io_p2v(0x40E00000))
-#define GPIO1_BASE	((void __iomem *)io_p2v(0x40E00004))
-#define GPIO2_BASE	((void __iomem *)io_p2v(0x40E00008))
-#define GPIO3_BASE	((void __iomem *)io_p2v(0x40E00100))
-
-#define GPLR_OFFSET	0x00
-#define GPDR_OFFSET	0x0C
-#define GPSR_OFFSET	0x18
-#define GPCR_OFFSET	0x24
-#define GRER_OFFSET	0x30
-#define GFER_OFFSET	0x3C
-#define GEDR_OFFSET	0x48
-
-struct pxa_gpio_chip {
-	struct gpio_chip chip;
-	void __iomem     *regbase;
-};
-
-int pxa_last_gpio;
-
-#ifdef CONFIG_CPU_PXA26x
-/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
- * as well as their Alternate Function value being '1' for GPIO in GAFRx.
- */
-static int __gpio_is_inverted(unsigned gpio)
-{
-	return cpu_is_pxa25x() && gpio > 85;
-}
-#else
-#define __gpio_is_inverted(gpio)	(0)
-#endif
-
-/*
- * Configure pins for GPIO or other functions
- */
-int pxa_gpio_mode(int gpio_mode)
-{
-	unsigned long flags;
-	int gpio = gpio_mode & GPIO_MD_MASK_NR;
-	int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
-	int gafr;
-
-	if (gpio > pxa_last_gpio)
-		return -EINVAL;
-
-	local_irq_save(flags);
-	if (gpio_mode & GPIO_DFLT_LOW)
-		GPCR(gpio) = GPIO_bit(gpio);
-	else if (gpio_mode & GPIO_DFLT_HIGH)
-		GPSR(gpio) = GPIO_bit(gpio);
-	if (gpio_mode & GPIO_MD_MASK_DIR)
-		GPDR(gpio) |= GPIO_bit(gpio);
-	else
-		GPDR(gpio) &= ~GPIO_bit(gpio);
-	gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
-	GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
-	local_irq_restore(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(pxa_gpio_mode);
-
-static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	unsigned long        flags;
-	u32                  mask = 1 << offset;
-	u32                  value;
-	struct pxa_gpio_chip *pxa;
-	void __iomem         *gpdr;
-
-	pxa = container_of(chip, struct pxa_gpio_chip, chip);
-	gpdr = pxa->regbase + GPDR_OFFSET;
-	local_irq_save(flags);
-	value = __raw_readl(gpdr);
-	if (__gpio_is_inverted(chip->base + offset))
-		value |= mask;
-	else
-		value &= ~mask;
-	__raw_writel(value, gpdr);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static int pxa_gpio_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	unsigned long        flags;
-	u32                  mask = 1 << offset;
-	u32                  tmp;
-	struct pxa_gpio_chip *pxa;
-	void __iomem         *gpdr;
-
-	pxa = container_of(chip, struct pxa_gpio_chip, chip);
-	__raw_writel(mask,
-			pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
-	gpdr = pxa->regbase + GPDR_OFFSET;
-	local_irq_save(flags);
-	tmp = __raw_readl(gpdr);
-	if (__gpio_is_inverted(chip->base + offset))
-		tmp &= ~mask;
-	else
-		tmp |= mask;
-	__raw_writel(tmp, gpdr);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-/*
- * Return GPIO level
- */
-static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	u32                  mask = 1 << offset;
-	struct pxa_gpio_chip *pxa;
-
-	pxa = container_of(chip, struct pxa_gpio_chip, chip);
-	return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
-}
-
-/*
- * Set output GPIO level
- */
-static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	u32                  mask = 1 << offset;
-	struct pxa_gpio_chip *pxa;
-
-	pxa = container_of(chip, struct pxa_gpio_chip, chip);
-
-	if (value)
-		__raw_writel(mask, pxa->regbase + GPSR_OFFSET);
-	else
-		__raw_writel(mask, pxa->regbase + GPCR_OFFSET);
-}
-
-#define GPIO_CHIP(_n)							\
-	[_n] = {							\
-		.regbase = GPIO##_n##_BASE,				\
-		.chip = {						\
-			.label		  = "gpio-" #_n,		\
-			.direction_input  = pxa_gpio_direction_input,	\
-			.direction_output = pxa_gpio_direction_output,	\
-			.get		  = pxa_gpio_get,		\
-			.set		  = pxa_gpio_set,		\
-			.base		  = (_n) * 32,			\
-			.ngpio		  = 32,				\
-		},							\
-	}
-
-static struct pxa_gpio_chip pxa_gpio_chip[] = {
-	GPIO_CHIP(0),
-	GPIO_CHIP(1),
-	GPIO_CHIP(2),
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-	GPIO_CHIP(3),
-#endif
-};
-
-/*
- * PXA GPIO edge detection for IRQs:
- * IRQs are generated on Falling-Edge, Rising-Edge, or both.
- * Use this instead of directly setting GRER/GFER.
- */
-
-static unsigned long GPIO_IRQ_rising_edge[4];
-static unsigned long GPIO_IRQ_falling_edge[4];
-static unsigned long GPIO_IRQ_mask[4];
-
-/*
- * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
- * function of a GPIO, and GPDRx cannot be altered once configured. It
- * is attributed as "occupied" here (I know this terminology isn't
- * accurate, you are welcome to propose a better one :-)
- */
-static int __gpio_is_occupied(unsigned gpio)
-{
-	if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
-		int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
-		int dir = GPDR(gpio) & GPIO_bit(gpio);
-
-		if (__gpio_is_inverted(gpio))
-			return af != 1 || dir == 0;
-		else
-			return af != 0 || dir != 0;
-	}
-
-	return 0;
-}
-
-static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
-{
-	int gpio, idx;
-
-	gpio = IRQ_TO_GPIO(irq);
-	idx = gpio >> 5;
-
-	if (type == IRQ_TYPE_PROBE) {
-		/* Don't mess with enabled GPIOs using preconfigured edges or
-		 * GPIOs set to alternate function or to output during probe
-		 */
-		if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
-		    (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
-			return 0;
-
-		if (__gpio_is_occupied(gpio))
-			return 0;
-
-		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
-	}
-
-	if (__gpio_is_inverted(gpio))
-		GPDR(gpio) |= GPIO_bit(gpio);
-	else
-		GPDR(gpio) &= ~GPIO_bit(gpio);
-
-	if (type & IRQ_TYPE_EDGE_RISING)
-		__set_bit(gpio, GPIO_IRQ_rising_edge);
-	else
-		__clear_bit(gpio, GPIO_IRQ_rising_edge);
-
-	if (type & IRQ_TYPE_EDGE_FALLING)
-		__set_bit(gpio, GPIO_IRQ_falling_edge);
-	else
-		__clear_bit(gpio, GPIO_IRQ_falling_edge);
-
-	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
-	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
-
-	pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio,
-		((type & IRQ_TYPE_EDGE_RISING)  ? " rising"  : ""),
-		((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
-	return 0;
-}
-
-/*
- * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
- */
-
-static void pxa_ack_low_gpio(unsigned int irq)
-{
-	GEDR0 = (1 << (irq - IRQ_GPIO0));
-}
-
-static void pxa_mask_low_gpio(unsigned int irq)
-{
-	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
-}
-
-static void pxa_unmask_low_gpio(unsigned int irq)
-{
-	ICMR |= 1 << (irq - PXA_IRQ(0));
-}
-
-static struct irq_chip pxa_low_gpio_chip = {
-	.name		= "GPIO-l",
-	.ack		= pxa_ack_low_gpio,
-	.mask		= pxa_mask_low_gpio,
-	.unmask		= pxa_unmask_low_gpio,
-	.set_type	= pxa_gpio_irq_type,
-};
-
-/*
- * Demux handler for GPIO>=2 edge detect interrupts
- */
-
-#define GEDR_BITS	(sizeof(gedr) * BITS_PER_BYTE)
-
-static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
-{
-	int loop, bit, n;
-	unsigned long gedr[4];
-
-	do {
-		gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3;
-		gedr[1] = GEDR1 & GPIO_IRQ_mask[1];
-		gedr[2] = GEDR2 & GPIO_IRQ_mask[2];
-		gedr[3] = GEDR3 & GPIO_IRQ_mask[3];
-
-		GEDR0 = gedr[0]; GEDR1 = gedr[1];
-		GEDR2 = gedr[2]; GEDR3 = gedr[3];
-
-		loop = 0;
-		bit = find_first_bit(gedr, GEDR_BITS);
-		while (bit < GEDR_BITS) {
-			loop = 1;
-
-			n = PXA_GPIO_IRQ_BASE + bit;
-			generic_handle_irq(n);
-
-			bit = find_next_bit(gedr, GEDR_BITS, bit + 1);
-		}
-	} while (loop);
-}
-
-static void pxa_ack_muxed_gpio(unsigned int irq)
-{
-	int gpio = irq - IRQ_GPIO(2) + 2;
-	GEDR(gpio) = GPIO_bit(gpio);
-}
-
-static void pxa_mask_muxed_gpio(unsigned int irq)
-{
-	int gpio = irq - IRQ_GPIO(2) + 2;
-	__clear_bit(gpio, GPIO_IRQ_mask);
-	GRER(gpio) &= ~GPIO_bit(gpio);
-	GFER(gpio) &= ~GPIO_bit(gpio);
-}
-
-static void pxa_unmask_muxed_gpio(unsigned int irq)
-{
-	int gpio = irq - IRQ_GPIO(2) + 2;
-	int idx = gpio >> 5;
-	__set_bit(gpio, GPIO_IRQ_mask);
-	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
-	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
-}
-
-static struct irq_chip pxa_muxed_gpio_chip = {
-	.name		= "GPIO",
-	.ack		= pxa_ack_muxed_gpio,
-	.mask		= pxa_mask_muxed_gpio,
-	.unmask		= pxa_unmask_muxed_gpio,
-	.set_type	= pxa_gpio_irq_type,
-};
-
-void __init pxa_init_gpio(int gpio_nr, set_wake_t fn)
-{
-	int irq, i, gpio;
-
-	pxa_last_gpio = gpio_nr - 1;
-
-	/* clear all GPIO edge detects */
-	for (i = 0; i < gpio_nr; i += 32) {
-		GFER(i) = 0;
-		GRER(i) = 0;
-		GEDR(i) = GEDR(i);
-	}
-
-	/* GPIO 0 and 1 must have their mask bit always set */
-	GPIO_IRQ_mask[0] = 3;
-
-	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
-		set_irq_chip(irq, &pxa_low_gpio_chip);
-		set_irq_handler(irq, handle_edge_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-
-	for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) {
-		set_irq_chip(irq, &pxa_muxed_gpio_chip);
-		set_irq_handler(irq, handle_edge_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-
-	/* Install handler for GPIO>=2 edge detect interrupts */
-	set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
-
-	pxa_low_gpio_chip.set_wake = fn;
-	pxa_muxed_gpio_chip.set_wake = fn;
-
-	/* add a GPIO chip for each register bank.
-	 * the last PXA25x register only contains 21 GPIOs
-	 */
-	for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) {
-		if (gpio + 32 > gpio_nr)
-			pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio;
-		gpiochip_add(&pxa_gpio_chip[i].chip);
-	}
-}
-
-#ifdef CONFIG_PM
-
-static unsigned long saved_gplr[4];
-static unsigned long saved_gpdr[4];
-static unsigned long saved_grer[4];
-static unsigned long saved_gfer[4];
-
-static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
-{
-	int i, gpio;
-
-	for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
-		saved_gplr[i] = GPLR(gpio);
-		saved_gpdr[i] = GPDR(gpio);
-		saved_grer[i] = GRER(gpio);
-		saved_gfer[i] = GFER(gpio);
-
-		/* Clear GPIO transition detect bits */
-		GEDR(gpio) = GEDR(gpio);
-	}
-	return 0;
-}
-
-static int pxa_gpio_resume(struct sys_device *dev)
-{
-	int i, gpio;
-
-	for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
-		/* restore level with set/clear */
-		GPSR(gpio) = saved_gplr[i];
-		GPCR(gpio) = ~saved_gplr[i];
-
-		GRER(gpio) = saved_grer[i];
-		GFER(gpio) = saved_gfer[i];
-		GPDR(gpio) = saved_gpdr[i];
-	}
-	return 0;
-}
-#else
-#define pxa_gpio_suspend	NULL
-#define pxa_gpio_resume		NULL
-#endif
-
-struct sysdev_class pxa_gpio_sysclass = {
-	.name		= "gpio",
-	.suspend	= pxa_gpio_suspend,
-	.resume		= pxa_gpio_resume,
-};
-
-static int __init pxa_gpio_init(void)
-{
-	return sysdev_class_register(&pxa_gpio_sysclass);
-}
-
-core_initcall(pxa_gpio_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/gumstix.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/gumstix.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/gumstix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/gumstix.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,14 +38,12 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+
+#include <mach/pxa25x.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/gumstix.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
-
 #include "generic.h"
 
 static struct resource flash_resource = {
@@ -191,6 +189,11 @@ int __attribute__((weak)) am200_init(voi
 	return 0;
 }
 
+int __attribute__((weak)) am300_init(void)
+{
+	return 0;
+}
+
 static void __init carrier_board_init(void)
 {
 	/*
@@ -198,6 +201,7 @@ static void __init carrier_board_init(vo
 	 * they cannot be detected programatically
 	 */
 	am200_init();
+	am300_init();
 }
 
 static void __init gumstix_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/h5000.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/h5000.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/h5000.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/h5000.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,14 +24,15 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+
+#include <mach/pxa25x.h>
 #include <mach/h5000.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
 #include <mach/udc.h>
+
 #include "generic.h"
 
 /*
@@ -153,6 +154,13 @@ static unsigned long h5000_pin_config[]
 	GPIO23_SSP1_SCLK,
 	GPIO25_SSP1_TXD,
 	GPIO26_SSP1_RXD,
+
+	/* I2S */
+	GPIO28_I2S_BITCLK_OUT,
+	GPIO29_I2S_SDATA_IN,
+	GPIO30_I2S_SDATA_OUT,
+	GPIO31_I2S_SYNC,
+	GPIO32_I2S_SYSCLK,
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/himalaya.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/himalaya.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/himalaya.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/himalaya.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-pxa/himalaya.c
+ *
+ * Hardware definitions for the HTC Himalaya
+ *
+ * Based on 2.6.21-hh20's himalaya.c and himalaya_lcd.c
+ *
+ * Copyright (c) 2008 Zbynek Michl <Zbynek.Michl@seznam.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
+#include "generic.h"
+
+/* ---------------------- Himalaya LCD definitions -------------------- */
+
+static struct w100_gen_regs himalaya_lcd_regs = {
+	.lcd_format =        0x00000003,
+	.lcdd_cntl1 =        0x00000000,
+	.lcdd_cntl2 =        0x0003ffff,
+	.genlcd_cntl1 =      0x00fff003,
+	.genlcd_cntl2 =      0x00000003,
+	.genlcd_cntl3 =      0x000102aa,
+};
+
+static struct w100_mode himalaya4_lcd_mode = {
+	.xres 		= 240,
+	.yres 		= 320,
+	.left_margin 	= 0,
+	.right_margin 	= 31,
+	.upper_margin 	= 15,
+	.lower_margin 	= 0,
+	.crtc_ss	= 0x80150014,
+	.crtc_ls	= 0xa0fb00f7,
+	.crtc_gs	= 0xc0080007,
+	.crtc_vpos_gs	= 0x00080007,
+	.crtc_rev	= 0x0000000a,
+	.crtc_dclk	= 0x81700030,
+	.crtc_gclk	= 0x8015010f,
+	.crtc_goe	= 0x00000000,
+	.pll_freq 	= 80,
+	.pixclk_divider = 15,
+	.pixclk_divider_rotated = 15,
+	.pixclk_src     = CLK_SRC_PLL,
+	.sysclk_divider = 0,
+	.sysclk_src     = CLK_SRC_PLL,
+};
+
+static struct w100_mode himalaya6_lcd_mode = {
+	.xres 		= 240,
+	.yres 		= 320,
+	.left_margin 	= 9,
+	.right_margin 	= 8,
+	.upper_margin 	= 5,
+	.lower_margin 	= 4,
+	.crtc_ss	= 0x80150014,
+	.crtc_ls	= 0xa0fb00f7,
+	.crtc_gs	= 0xc0080007,
+	.crtc_vpos_gs	= 0x00080007,
+	.crtc_rev	= 0x0000000a,
+	.crtc_dclk	= 0xa1700030,
+	.crtc_gclk	= 0x8015010f,
+	.crtc_goe	= 0x00000000,
+	.pll_freq 	= 95,
+	.pixclk_divider = 0xb,
+	.pixclk_divider_rotated = 4,
+	.pixclk_src     = CLK_SRC_PLL,
+	.sysclk_divider = 1,
+	.sysclk_src     = CLK_SRC_PLL,
+};
+
+static struct w100_gpio_regs himalaya_w100_gpio_info = {
+	.init_data1 = 0xffff0000,	/* GPIO_DATA  */
+	.gpio_dir1  = 0x00000000,	/* GPIO_CNTL1 */
+	.gpio_oe1   = 0x003c0000,	/* GPIO_CNTL2 */
+	.init_data2 = 0x00000000,	/* GPIO_DATA2 */
+	.gpio_dir2  = 0x00000000,	/* GPIO_CNTL3 */
+	.gpio_oe2   = 0x00000000,	/* GPIO_CNTL4 */
+};
+
+static struct w100fb_mach_info himalaya_fb_info = {
+	.num_modes  = 1,
+	.regs       = &himalaya_lcd_regs,
+	.gpio       = &himalaya_w100_gpio_info,
+	.xtal_freq = 16000000,
+};
+
+static struct resource himalaya_fb_resources[] = {
+	[0] = {
+		.start	= 0x08000000,
+		.end	= 0x08ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device himalaya_fb_device = {
+	.name           = "w100fb",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &himalaya_fb_info,
+	},
+	.num_resources  = ARRAY_SIZE(himalaya_fb_resources),
+	.resource       = himalaya_fb_resources,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *devices[] __initdata = {
+	&himalaya_fb_device,
+};
+
+static void __init himalaya_lcd_init(void)
+{
+	int himalaya_boardid;
+
+	himalaya_boardid = 0x4; /* hardcoded (detection needs ASIC3 functions) */
+	printk(KERN_INFO "himalaya LCD Driver init. boardid=%d\n",
+		himalaya_boardid);
+
+	switch (himalaya_boardid) {
+	case 0x4:
+		himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+	break;
+	case 0x6:
+		himalaya_fb_info.modelist = &himalaya6_lcd_mode;
+	break;
+	default:
+		printk(KERN_INFO "himalaya lcd_init: unknown boardid=%d. Using 0x4\n",
+			himalaya_boardid);
+		himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+	}
+}
+
+static void __init himalaya_init(void)
+{
+	himalaya_lcd_init();
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+
+MACHINE_START(HIMALAYA, "HTC Himalaya")
+	.phys_io = 0x40000000,
+	.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params = 0xa0000100,
+	.map_io = pxa_map_io,
+	.init_irq = pxa25x_init_irq,
+	.init_machine = himalaya_init,
+	.timer = &pxa_timer,
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/idp.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/idp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/idp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/idp.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,8 +31,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
 #include <mach/idp.h>
 #include <mach/pxafb.h>
 #include <mach/bitfield.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/imote2.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/imote2.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/imote2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/imote2.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,11 +28,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
+#include <mach/pxa27x.h>
 #include <mach/i2c.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/regs-ssp.h>
 #include <mach/udc.h>
 #include <mach/mmc.h>
 #include <mach/pxa2xx_spi.h>
@@ -415,7 +412,7 @@ static struct platform_device imote2_fla
  */
 static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
 	{ /* UCAM sensor board */
-		.type = "max1238",
+		.type = "max1239",
 		.addr = 0x35,
 	}, { /* ITS400 Sensor board only */
 		.type = "max1363",
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/audio.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/audio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/audio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/audio.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,12 +4,22 @@
 #include <sound/core.h>
 #include <sound/pcm.h>
 
+/*
+ * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95)
+ *              a -1 value means no gpio will be used for reset
+
+ * reset_gpio should only be specified for pxa27x CPUs where a silicon
+ * bug prevents correct operation of the reset line. If not specified,
+ * the default behaviour on these CPUs is to consider gpio 113 as the
+ * AC97 reset line, which is the default on most boards.
+ */
 typedef struct {
 	int (*startup)(struct snd_pcm_substream *, void *);
 	void (*shutdown)(struct snd_pcm_substream *, void *);
 	void (*suspend)(void *);
 	void (*resume)(void *);
 	void *priv;
+	int reset_gpio;
 } pxa2xx_audio_ops_t;
 
 extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/colibri.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/colibri.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/colibri.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/colibri.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,19 +1,38 @@
 #ifndef _COLIBRI_H_
 #define _COLIBRI_H_
 
+#include <net/ax88796.h>
+
+/*
+ * common settings for all modules
+ */
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin);
+#else
+static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern void colibri_pxa3xx_init_lcd(int bl_pin);
+#else
+static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
+#endif
+
+#if defined(CONFIG_AX88796)
+extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
+#endif
+
 /* physical memory regions */
-#define COLIBRI_FLASH_PHYS	(PXA_CS0_PHYS)  /* Flash region */
-#define COLIBRI_ETH_PHYS	(PXA_CS2_PHYS)  /* Ethernet DM9000 region */
 #define COLIBRI_SDRAM_BASE	0xa0000000      /* SDRAM region */
 
-/* virtual memory regions */
-#define COLIBRI_DISK_VIRT	0xF0000000	/* Disk On Chip region */
-
-/* size of flash */
-#define COLIBRI_FLASH_SIZE	0x02000000	/* Flash size 32 MB */
+/* definitions for Colibri PXA270 */
 
-/* Ethernet Controller Davicom DM9000 */
-#define GPIO_DM9000		114
-#define COLIBRI_ETH_IRQ	IRQ_GPIO(GPIO_DM9000)
+#define COLIBRI_PXA270_FLASH_PHYS	(PXA_CS0_PHYS)  /* Flash region */
+#define COLIBRI_PXA270_ETH_PHYS		(PXA_CS2_PHYS)  /* Ethernet */
+#define COLIBRI_PXA270_ETH_IRQ_GPIO	114
+#define COLIBRI_PXA270_ETH_IRQ		\
+	gpio_to_irq(mfp_to_gpio(COLIBRI_PXA270_ETH_IRQ_GPIO))
 
 #endif /* _COLIBRI_H_ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/csb726.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/csb726.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/csb726.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/csb726.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ *  Support for Cogent CSB726
+ *
+ *  Copyright (c) 2008 Dmitry Baryshkov
+ *
+ *  This program is free software; you can 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 CSB726_H
+#define CSB726_H
+
+#define CSB726_GPIO_IRQ_LAN	52
+#define CSB726_GPIO_IRQ_SM501	53
+#define CSB726_GPIO_MMC_DETECT	100
+#define CSB726_GPIO_MMC_RO	101
+
+#define CSB726_FLASH_SIZE	(64 * 1024 * 1024)
+#define CSB726_FLASH_uMON	(8 * 1024 * 1024)
+
+#define CSB726_IRQ_LAN		gpio_to_irq(CSB726_GPIO_IRQ_LAN)
+#define CSB726_IRQ_SM501	gpio_to_irq(CSB726_GPIO_IRQ_SM501)
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/dma.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -12,35 +12,10 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-/*
- * Descriptor structure for PXA's DMA engine
- * Note: this structure must always be aligned to a 16-byte boundary.
- */
-
-typedef struct pxa_dma_desc {
-	volatile u32 ddadr;	/* Points to the next descriptor + flags */
-	volatile u32 dsadr;	/* DSADR value for the current transfer */
-	volatile u32 dtadr;	/* DTADR value for the current transfer */
-	volatile u32 dcmd;	/* DCMD value for the current transfer */
-} pxa_dma_desc;
-
-typedef enum {
-	DMA_PRIO_HIGH = 0,
-	DMA_PRIO_MEDIUM = 1,
-	DMA_PRIO_LOW = 2
-} pxa_dma_prio;
-
-/*
- * DMA registration
- */
-
-int __init pxa_init_dma(int num_ch);
-
-int pxa_request_dma (char *name,
-			 pxa_dma_prio prio,
-			 void (*irq_handler)(int, void *),
-			 void *data);
+#include <mach/hardware.h>
 
-void pxa_free_dma (int dma_ch);
+/* DMA Controller Registers Definitions */
+#define DMAC_REGS_VIRT	io_p2v(0x40000000)
 
+#include <plat/dma.h>
 #endif /* _ASM_ARCH_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/eseries-gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/eseries-gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/eseries-gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/eseries-gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,6 +45,21 @@
 /* e7xx IrDA power control */
 #define GPIO_E7XX_IR_OFF         38
 
+/* e740 audio control GPIOs */
+#define GPIO_E740_WM9705_nAVDD2  16
+#define GPIO_E740_MIC_ON         40
+#define GPIO_E740_AMP_ON         41
+
+/* e750 audio control GPIOs */
+#define GPIO_E750_HP_AMP_OFF      4
+#define GPIO_E750_SPK_AMP_OFF     7
+#define GPIO_E750_HP_DETECT      37
+
+/* e800 audio control GPIOs */
+#define GPIO_E800_HP_DETECT      81
+#define GPIO_E800_HP_AMP_OFF     82
+#define GPIO_E800_SPK_AMP_ON     83
+
 /* ASIC related GPIOs */
 #define GPIO_ESERIES_TMIO_IRQ        5
 #define GPIO_ESERIES_TMIO_PCLR      19
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,42 +24,118 @@
 #ifndef __ASM_ARCH_PXA_GPIO_H
 #define __ASM_ARCH_PXA_GPIO_H
 
-#include <mach/pxa-regs.h>
-#include <asm/irq.h>
+#include <mach/irqs.h>
 #include <mach/hardware.h>
-
 #include <asm-generic/gpio.h>
 
+#define GPIO_REGS_VIRT	io_p2v(0x40E00000)
+
+#define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x)	(*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
+
+/* GPIO Pin Level Registers */
+#define GPLR0		GPIO_REG(BANK_OFF(0) + 0x00)
+#define GPLR1		GPIO_REG(BANK_OFF(1) + 0x00)
+#define GPLR2		GPIO_REG(BANK_OFF(2) + 0x00)
+#define GPLR3		GPIO_REG(BANK_OFF(3) + 0x00)
+
+/* GPIO Pin Direction Registers */
+#define GPDR0		GPIO_REG(BANK_OFF(0) + 0x0c)
+#define GPDR1		GPIO_REG(BANK_OFF(1) + 0x0c)
+#define GPDR2		GPIO_REG(BANK_OFF(2) + 0x0c)
+#define GPDR3		GPIO_REG(BANK_OFF(3) + 0x0c)
+
+/* GPIO Pin Output Set Registers */
+#define GPSR0		GPIO_REG(BANK_OFF(0) + 0x18)
+#define GPSR1		GPIO_REG(BANK_OFF(1) + 0x18)
+#define GPSR2		GPIO_REG(BANK_OFF(2) + 0x18)
+#define GPSR3		GPIO_REG(BANK_OFF(3) + 0x18)
+
+/* GPIO Pin Output Clear Registers */
+#define GPCR0		GPIO_REG(BANK_OFF(0) + 0x24)
+#define GPCR1		GPIO_REG(BANK_OFF(1) + 0x24)
+#define GPCR2		GPIO_REG(BANK_OFF(2) + 0x24)
+#define GPCR3		GPIO_REG(BANK_OFF(3) + 0x24)
+
+/* GPIO Rising Edge Detect Registers */
+#define GRER0		GPIO_REG(BANK_OFF(0) + 0x30)
+#define GRER1		GPIO_REG(BANK_OFF(1) + 0x30)
+#define GRER2		GPIO_REG(BANK_OFF(2) + 0x30)
+#define GRER3		GPIO_REG(BANK_OFF(3) + 0x30)
+
+/* GPIO Falling Edge Detect Registers */
+#define GFER0		GPIO_REG(BANK_OFF(0) + 0x3c)
+#define GFER1		GPIO_REG(BANK_OFF(1) + 0x3c)
+#define GFER2		GPIO_REG(BANK_OFF(2) + 0x3c)
+#define GFER3		GPIO_REG(BANK_OFF(3) + 0x3c)
+
+/* GPIO Edge Detect Status Registers */
+#define GEDR0		GPIO_REG(BANK_OFF(0) + 0x48)
+#define GEDR1		GPIO_REG(BANK_OFF(1) + 0x48)
+#define GEDR2		GPIO_REG(BANK_OFF(2) + 0x48)
+#define GEDR3		GPIO_REG(BANK_OFF(3) + 0x48)
+
+/* GPIO Alternate Function Select Registers */
+#define GAFR0_L		GPIO_REG(0x0054)
+#define GAFR0_U		GPIO_REG(0x0058)
+#define GAFR1_L		GPIO_REG(0x005C)
+#define GAFR1_U		GPIO_REG(0x0060)
+#define GAFR2_L		GPIO_REG(0x0064)
+#define GAFR2_U		GPIO_REG(0x0068)
+#define GAFR3_L		GPIO_REG(0x006C)
+#define GAFR3_U		GPIO_REG(0x0070)
+
+/* More handy macros.  The argument is a literal GPIO number. */
+
+#define GPIO_bit(x)	(1 << ((x) & 0x1f))
+
+#define GPLR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x00)
+#define GPDR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x0c)
+#define GPSR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x18)
+#define GPCR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x24)
+#define GRER(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x30)
+#define GFER(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x3c)
+#define GEDR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x48)
+#define GAFR(x)		GPIO_REG(0x54 + (((x) & 0x70) >> 2))
+
 
-/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
- * Those cases currently cause holes in the GPIO number space.
- */
 #define NR_BUILTIN_GPIO 128
 
-static inline int gpio_get_value(unsigned gpio)
+#define gpio_to_bank(gpio)	((gpio) >> 5)
+#define gpio_to_irq(gpio)	IRQ_GPIO(gpio)
+#define irq_to_gpio(irq)	IRQ_TO_GPIO(irq)
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
+ * as well as their Alternate Function value being '1' for GPIO in GAFRx.
+ */
+static inline int __gpio_is_inverted(unsigned gpio)
 {
-	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
-		return GPLR(gpio) & GPIO_bit(gpio);
-	else
-		return __gpio_get_value(gpio);
+	return cpu_is_pxa25x() && gpio > 85;
 }
+#else
+static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
+#endif
 
-static inline void gpio_set_value(unsigned gpio, int value)
+/*
+ * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
+ * function of a GPIO, and GPDRx cannot be altered once configured. It
+ * is attributed as "occupied" here (I know this terminology isn't
+ * accurate, you are welcome to propose a better one :-)
+ */
+static inline int __gpio_is_occupied(unsigned gpio)
 {
-	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
-		if (value)
-			GPSR(gpio) = GPIO_bit(gpio);
+	if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
+		int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
+		int dir = GPDR(gpio) & GPIO_bit(gpio);
+
+		if (__gpio_is_inverted(gpio))
+			return af != 1 || dir == 0;
 		else
-			GPCR(gpio) = GPIO_bit(gpio);
-	} else {
-		__gpio_set_value(gpio, value);
-	}
+			return af != 0 || dir != 0;
+	} else
+		return GPDR(gpio) & GPIO_bit(gpio);
 }
 
-#define gpio_cansleep __gpio_cansleep
-
-#define gpio_to_irq(gpio)	IRQ_GPIO(gpio)
-#define irq_to_gpio(irq)	IRQ_TO_GPIO(irq)
-
-
+#include <plat/gpio.h>
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/gumstix.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/gumstix.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/gumstix.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/gumstix.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,4 +97,5 @@ has detected a cable insertion; driven l
 
 /* for expansion boards that can't be programatically detected */
 extern int am200_init(void);
+extern int am300_init(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/lubbock.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,6 @@
 
 /* FPGA register virtual addresses */
 #define LUB_WHOAMI		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x000)
-#define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
 #define LUB_DISC_BLNK_LED	__LUB_REG(LUBBOCK_FPGA_PHYS + 0x040)
 #define LUB_CONF_SWITCHES	__LUB_REG(LUBBOCK_FPGA_PHYS + 0x050)
 #define LUB_USER_SWITCHES	__LUB_REG(LUBBOCK_FPGA_PHYS + 0x060)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/magician.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/magician.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/magician.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/magician.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@
 #define GPIO22_MAGICIAN_VIBRA_EN		22
 #define GPIO26_MAGICIAN_GSM_POWER		26
 #define GPIO27_MAGICIAN_USBC_PUEN		27
-#define GPIO30_MAGICIAN_nCHARGE_EN		30
+#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN	30
 #define GPIO37_MAGICIAN_KEY_HANGUP		37
 #define GPIO38_MAGICIAN_KEY_CONTACTS		38
 #define GPIO40_MAGICIAN_GSM_OUT2		40
@@ -69,7 +69,7 @@
 #define IRQ_MAGICIAN_SD		(IRQ_BOARD_START + 0)
 #define IRQ_MAGICIAN_EP		(IRQ_BOARD_START + 1)
 #define IRQ_MAGICIAN_BT		(IRQ_BOARD_START + 2)
-#define IRQ_MAGICIAN_AC		(IRQ_BOARD_START + 3)
+#define IRQ_MAGICIAN_VBUS	(IRQ_BOARD_START + 3)
 
 /*
  * CPLD EGPIOs
@@ -98,7 +98,7 @@
 #define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL	MAGICIAN_EGPIO(2, 2)
 #define EGPIO_MAGICIAN_FLASH_VPP		MAGICIAN_EGPIO(2, 3)
 #define EGPIO_MAGICIAN_BL_POWER2		MAGICIAN_EGPIO(2, 4)
-#define EGPIO_MAGICIAN_CHARGE_EN		MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_BQ24022_ISET2		MAGICIAN_EGPIO(2, 5)
 #define EGPIO_MAGICIAN_GSM_POWER		MAGICIAN_EGPIO(2, 7)
 
 /* input */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,6 @@
 #ifndef __ASM_ARCH_MFP_PXA25X_H
 #define __ASM_ARCH_MFP_PXA25X_H
 
-#include <mach/mfp.h>
 #include <mach/mfp-pxa2xx.h>
 
 /* GPIO */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,6 @@
  * specific controller, and this should work in most cases.
  */
 
-#include <mach/mfp.h>
 #include <mach/mfp-pxa2xx.h>
 
 /* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef __ASM_ARCH_MFP_PXA2XX_H
 #define __ASM_ARCH_MFP_PXA2XX_H
 
-#include <mach/mfp.h>
+#include <plat/mfp.h>
 
 /*
  * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa300.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa300.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa300.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@
 #ifndef __ASM_ARCH_MFP_PXA300_H
 #define __ASM_ARCH_MFP_PXA300_H
 
-#include <mach/mfp.h>
 #include <mach/mfp-pxa3xx.h>
 
 /* GPIO */
@@ -41,6 +40,7 @@
 #endif
 
 /* Chip Select */
+#define GPIO1_nCS2		MFP_CFG(GPIO1,	AF1)
 #define GPIO2_nCS3		MFP_CFG(GPIO2,  AF1)
 
 /* AC97 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa320.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa320.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa320.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@
 #ifndef __ASM_ARCH_MFP_PXA320_H
 #define __ASM_ARCH_MFP_PXA320_H
 
-#include <mach/mfp.h>
 #include <mach/mfp-pxa3xx.h>
 
 /* GPIO */
@@ -38,6 +37,7 @@
 #define GPIO17_2_GPIO		MFP_CFG(GPIO17_2, AF0)
 
 /* Chip Select */
+#define GPIO3_nCS2		MFP_CFG(GPIO3, AF1)
 #define GPIO4_nCS3		MFP_CFG(GPIO4, AF1)
 
 /* AC97 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,68 +1,9 @@
 #ifndef __ASM_ARCH_MFP_PXA3XX_H
 #define __ASM_ARCH_MFP_PXA3XX_H
 
-#define MFPR_BASE	(0x40e10000)
-#define MFPR_SIZE	(PAGE_SIZE)
-
-/* MFPR register bit definitions */
-#define MFPR_PULL_SEL		(0x1 << 15)
-#define MFPR_PULLUP_EN		(0x1 << 14)
-#define MFPR_PULLDOWN_EN	(0x1 << 13)
-#define MFPR_SLEEP_SEL		(0x1 << 9)
-#define MFPR_SLEEP_OE_N		(0x1 << 7)
-#define MFPR_EDGE_CLEAR		(0x1 << 6)
-#define MFPR_EDGE_FALL_EN	(0x1 << 5)
-#define MFPR_EDGE_RISE_EN	(0x1 << 4)
-
-#define MFPR_SLEEP_DATA(x)	((x) << 8)
-#define MFPR_DRIVE(x)		(((x) & 0x7) << 10)
-#define MFPR_AF_SEL(x)		(((x) & 0x7) << 0)
-
-#define MFPR_EDGE_NONE		(0)
-#define MFPR_EDGE_RISE		(MFPR_EDGE_RISE_EN)
-#define MFPR_EDGE_FALL		(MFPR_EDGE_FALL_EN)
-#define MFPR_EDGE_BOTH		(MFPR_EDGE_RISE | MFPR_EDGE_FALL)
-
-/*
- * Table that determines the low power modes outputs, with actual settings
- * used in parentheses for don't-care values. Except for the float output,
- * the configured driven and pulled levels match, so if there is a need for
- * non-LPM pulled output, the same configuration could probably be used.
- *
- * Output value  sleep_oe_n  sleep_data  pullup_en  pulldown_en  pull_sel
- *                 (bit 7)    (bit 8)    (bit 14)     (bit 13)   (bit 15)
- *
- * Input            0          X(0)        X(0)        X(0)       0
- * Drive 0          0          0           0           X(1)       0
- * Drive 1          0          1           X(1)        0	  0
- * Pull hi (1)      1          X(1)        1           0	  0
- * Pull lo (0)      1          X(0)        0           1	  0
- * Z (float)        1          X(0)        0           0	  0
- */
-#define MFPR_LPM_INPUT		(0)
-#define MFPR_LPM_DRIVE_LOW	(MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
-#define MFPR_LPM_DRIVE_HIGH    	(MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
-#define MFPR_LPM_PULL_LOW      	(MFPR_LPM_DRIVE_LOW  | MFPR_SLEEP_OE_N)
-#define MFPR_LPM_PULL_HIGH     	(MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
-#define MFPR_LPM_FLOAT         	(MFPR_SLEEP_OE_N)
-#define MFPR_LPM_MASK		(0xe080)
+#include <plat/mfp.h>
 
-/*
- * The pullup and pulldown state of the MFP pin at run mode is by default
- * determined by the selected alternate function. In case that some buggy
- * devices need to override this default behavior,  the definitions below
- * indicates the setting of corresponding MFPR bits
- *
- * Definition       pull_sel  pullup_en  pulldown_en
- * MFPR_PULL_NONE       0         0        0
- * MFPR_PULL_LOW        1         0        1
- * MFPR_PULL_HIGH       1         1        0
- * MFPR_PULL_BOTH       1         1        1
- */
-#define MFPR_PULL_NONE		(0)
-#define MFPR_PULL_LOW		(MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
-#define MFPR_PULL_BOTH		(MFPR_PULL_LOW | MFPR_PULLUP_EN)
-#define MFPR_PULL_HIGH		(MFPR_PULL_SEL | MFPR_PULLUP_EN)
+#define MFPR_BASE	(0x40e10000)
 
 /* PXA3xx common MFP configurations - processor specific ones defined
  * in mfp-pxa300.h and mfp-pxa320.h
@@ -197,56 +138,21 @@
 #define GPIO5_2_GPIO		MFP_CFG(GPIO5_2, AF0)
 #define GPIO6_2_GPIO		MFP_CFG(GPIO6_2, AF0)
 
-/*
- * each MFP pin will have a MFPR register, since the offset of the
- * register varies between processors, the processor specific code
- * should initialize the pin offsets by pxa3xx_mfp_init_addr()
- *
- * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
- * structure, which represents a range of MFP pins from "start" to
- * "end", with the offset begining at "offset", to define a single
- * pin, let "end" = -1
- *
- * use
- *
- * MFP_ADDR_X() to define a range of pins
- * MFP_ADDR()   to define a single pin
- * MFP_ADDR_END to signal the end of pin offset definitions
- */
-struct pxa3xx_mfp_addr_map {
-	unsigned int	start;
-	unsigned int	end;
-	unsigned long	offset;
-};
-
-#define MFP_ADDR_X(start, end, offset) \
-	{ MFP_PIN_##start, MFP_PIN_##end, offset }
-
-#define MFP_ADDR(pin, offset) \
-	{ MFP_PIN_##pin, -1, offset }
-
-#define MFP_ADDR_END	{ MFP_PIN_INVALID, 0 }
-
-/*
- * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
- * to the MFPR register
+/* NOTE: usage of these two functions is not recommended,
+ * use pxa3xx_mfp_config() instead.
  */
-unsigned long pxa3xx_mfp_read(int mfp);
-void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
+static inline unsigned long pxa3xx_mfp_read(int mfp)
+{
+	return mfp_read(mfp);
+}
 
-/*
- * pxa3xx_mfp_config - configure the MFPR registers
- *
- * used by board specific initialization code
- */
-void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num);
+static inline void pxa3xx_mfp_write(int mfp, unsigned long val)
+{
+	mfp_write(mfp, val);
+}
 
-/*
- * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
- * index and MFPR register offset
- *
- * used by processor specific code
- */
-void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
-void __init pxa3xx_init_mfp(void);
+static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num)
+{
+	mfp_config(mfp_cfg, num);
+}
 #endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa930.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa930.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mfp-pxa930.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@
 #ifndef __ASM_ARCH_MFP_PXA9xx_H
 #define __ASM_ARCH_MFP_PXA9xx_H
 
-#include <mach/mfp.h>
 #include <mach/mfp-pxa3xx.h>
 
 /* GPIO */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mtd-xip.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mtd-xip.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/mtd-xip.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/mtd-xip.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,8 +15,8 @@
 #ifndef __ARCH_PXA_MTD_XIP_H__
 #define __ARCH_PXA_MTD_XIP_H__
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
+#include <mach/regs-intc.h>
 
 #define xip_irqpending()	(ICIP & ICMR)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmasoc.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmasoc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmasoc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmasoc.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,8 @@
 #ifndef _INCLUDE_PALMASOC_H_
 #define _INCLUDE_PALMASOC_H_
+
 struct palm27x_asoc_info {
 	int	jack_gpio;
 };
 
-#ifdef CONFIG_SND_PXA2XX_SOC_PALM27X
-void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data);
-#else
-static inline void palm27x_asoc_set_pdata(struct palm27x_asoc_info *data) {}
-#endif
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmld.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmld.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * GPIOs and interrupts for Palm LifeDrive Handheld Computer
+ *
+ * Authors:	Alex Osborne <ato@meshy.org>
+ *		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 _INCLUDE_PALMLD_H_
+#define _INCLUDE_PALMLD_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMLD_GPIO_RESET	1
+#define GPIO_NR_PALMLD_POWER_DETECT	4
+#define GPIO_NR_PALMLD_HOTSYNC_BUTTON_N	10
+#define GPIO_NR_PALMLD_POWER_SWITCH	12
+#define GPIO_NR_PALMLD_EARPHONE_DETECT 	13
+#define GPIO_NR_PALMLD_LOCK_SWITCH	15
+
+/* SD/MMC */
+#define GPIO_NR_PALMLD_SD_DETECT_N	14
+#define GPIO_NR_PALMLD_SD_POWER		114
+#define GPIO_NR_PALMLD_SD_READONLY	116
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMLD_WM9712_IRQ	27
+
+/* IRDA */
+#define GPIO_NR_PALMLD_IR_DISABLE	108
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMLD_BL_POWER		19
+#define GPIO_NR_PALMLD_LCD_POWER	96
+
+/* LCD BORDER */
+#define GPIO_NR_PALMLD_BORDER_SWITCH	21
+#define GPIO_NR_PALMLD_BORDER_SELECT	22
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMLD_BT_POWER		17
+#define GPIO_NR_PALMLD_BT_RESET		83
+
+/* PCMCIA (WiFi) */
+#define GPIO_NR_PALMLD_PCMCIA_READY	38
+#define GPIO_NR_PALMLD_PCMCIA_POWER	36
+#define GPIO_NR_PALMLD_PCMCIA_RESET	81
+
+/* LEDs */
+#define GPIO_NR_PALMLD_LED_GREEN	52
+#define GPIO_NR_PALMLD_LED_AMBER	94
+
+/* IDE */
+#define GPIO_NR_PALMLD_IDE_IRQ		95
+#define GPIO_NR_PALMLD_IDE_RESET	98
+#define GPIO_NR_PALMLD_IDE_PWEN		115
+
+/* USB */
+#define GPIO_NR_PALMLD_USB_DETECT_N	3
+#define GPIO_NR_PALMLD_USB_READY	86
+#define GPIO_NR_PALMLD_USB_RESET	88
+#define GPIO_NR_PALMLD_USB_INT		106
+#define GPIO_NR_PALMLD_USB_POWER	118
+/* 20, 53 and 86 are usb related too */
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMLD_GPIO_RESET	IRQ_GPIO(GPIO_NR_PALMLD_GPIO_RESET)
+#define IRQ_GPIO_PALMLD_SD_DETECT_N	IRQ_GPIO(GPIO_NR_PALMLD_SD_DETECT_N)
+#define IRQ_GPIO_PALMLD_WM9712_IRQ	IRQ_GPIO(GPIO_NR_PALMLD_WM9712_IRQ)
+#define IRQ_GPIO_PALMLD_IDE_IRQ		IRQ_GPIO(GPIO_NR_PALMLD_IDE_IRQ)
+
+
+/** HERE ARE INIT VALUES **/
+
+/* IO mappings */
+#define PALMLD_USB_PHYS		PXA_CS2_PHYS
+#define PALMLD_USB_VIRT		0xf0000000
+#define PALMLD_USB_SIZE		0x00100000
+
+#define PALMLD_IDE_PHYS		0x20000000
+#define PALMLD_IDE_VIRT		0xf1000000
+#define PALMLD_IDE_SIZE		0x00100000
+
+#define PALMLD_PHYS_IO_START	0x40000000
+#define PALMLD_STR_BASE		0xa0200000
+
+/* 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_MIN_CURRENT		0	/* unknown */
+#define PALMLD_BAT_MAX_CHARGE		1	/* unknown */
+#define PALMLD_BAT_MIN_CHARGE		1	/* unknown */
+#define PALMLD_MAX_LIFE_MINS		240	/* on-life in minutes */
+
+#define PALMLD_BAT_MEASURE_DELAY	(HZ * 1)
+
+/* BACKLIGHT */
+#define PALMLD_MAX_INTENSITY		0xFE
+#define PALMLD_DEFAULT_INTENSITY	0x7E
+#define PALMLD_LIMIT_MASK		0x7F
+#define PALMLD_PRESCALER		0x3F
+#define PALMLD_PERIOD_NS		3500
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmt5.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,84 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
+ *
+ * Authors:	Ales Snuparek <snuparek@atlas.cz>
+ *		Marek Vasut <marek.vasut@gmail.com>
+ *		Justin Kendrick <twilightsentry@gmail.com>
+ *		RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMT5_H_
+#define _INCLUDE_PALMT5_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMT5_GPIO_RESET		1
+
+#define GPIO_NR_PALMT5_POWER_DETECT		90
+#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N		10
+#define GPIO_NR_PALMT5_EARPHONE_DETECT		107
+
+/* SD/MMC */
+#define GPIO_NR_PALMT5_SD_DETECT_N		14
+#define GPIO_NR_PALMT5_SD_POWER			114
+#define GPIO_NR_PALMT5_SD_READONLY		115
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMT5_WM9712_IRQ		27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMT5_IR_DISABLE		40
+
+/* USB */
+#define GPIO_NR_PALMT5_USB_DETECT_N		15
+#define GPIO_NR_PALMT5_USB_PULLUP		93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMT5_BL_POWER			84
+#define GPIO_NR_PALMT5_LCD_POWER		96
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMT5_BT_POWER			17
+#define GPIO_NR_PALMT5_BT_RESET			83
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMT5_SD_DETECT_N	IRQ_GPIO(GPIO_NR_PALMT5_SD_DETECT_N)
+#define IRQ_GPIO_PALMT5_WM9712_IRQ	IRQ_GPIO(GPIO_NR_PALMT5_WM9712_IRQ)
+#define IRQ_GPIO_PALMT5_USB_DETECT	IRQ_GPIO(GPIO_NR_PALMT5_USB_DETECT)
+#define IRQ_GPIO_PALMT5_GPIO_RESET	IRQ_GPIO(GPIO_NR_PALMT5_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses  */
+#define PALMT5_PHYS_RAM_START	0xa0000000
+#define PALMT5_PHYS_IO_START	0x40000000
+#define PALMT5_STR_BASE		0xa0200000
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME		21
+
+/* 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_MIN_CURRENT		0	/* unknown */
+#define PALMT5_BAT_MAX_CHARGE		1	/* unknown */
+#define PALMT5_BAT_MIN_CHARGE		1	/* unknown */
+#define PALMT5_MAX_LIFE_MINS		360    /* on-life in minutes */
+
+#define PALMT5_BAT_MEASURE_DELAY	(HZ * 1)
+
+/* BACKLIGHT */
+#define PALMT5_MAX_INTENSITY		0xFE
+#define PALMT5_DEFAULT_INTENSITY	0x7E
+#define PALMT5_LIMIT_MASK		0x7F
+#define PALMT5_PRESCALER		0x3F
+#define PALMT5_PERIOD_NS		3500
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmte2.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
+ *
+ * Author:
+ *		Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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 _INCLUDE_PALMTE2_H_
+#define _INCLUDE_PALMTE2_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTE2_POWER_DETECT		9
+#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N	4
+#define GPIO_NR_PALMTE2_EARPHONE_DETECT		15
+
+/* SD/MMC */
+#define GPIO_NR_PALMTE2_SD_DETECT_N		10
+#define GPIO_NR_PALMTE2_SD_POWER		55
+#define GPIO_NR_PALMTE2_SD_READONLY		51
+
+/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTE2_IR_DISABLE		48
+
+/* USB */
+#define GPIO_NR_PALMTE2_USB_DETECT_N		35
+#define GPIO_NR_PALMTE2_USB_PULLUP		53
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTE2_BL_POWER		56
+#define GPIO_NR_PALMTE2_LCD_POWER		37
+
+/* KEYS */
+#define GPIO_NR_PALMTE2_KEY_NOTES	5
+#define GPIO_NR_PALMTE2_KEY_TASKS	7
+#define GPIO_NR_PALMTE2_KEY_CALENDAR	11
+#define GPIO_NR_PALMTE2_KEY_CONTACTS	13
+#define GPIO_NR_PALMTE2_KEY_CENTER	14
+#define GPIO_NR_PALMTE2_KEY_LEFT	19
+#define GPIO_NR_PALMTE2_KEY_RIGHT	20
+#define GPIO_NR_PALMTE2_KEY_DOWN	21
+#define GPIO_NR_PALMTE2_KEY_UP		22
+
+/** HERE ARE INIT VALUES **/
+
+/* BACKLIGHT */
+#define PALMTE2_MAX_INTENSITY		0xFE
+#define PALMTE2_DEFAULT_INTENSITY	0x7E
+#define PALMTE2_LIMIT_MASK		0x7F
+#define PALMTE2_PRESCALER		0x3F
+#define PALMTE2_PERIOD_NS		3500
+
+/* 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_MIN_CURRENT		0	/* unknown */
+#define PALMTE2_BAT_MAX_CHARGE		1	/* unknown */
+#define PALMTE2_BAT_MIN_CHARGE		1	/* unknown */
+#define PALMTE2_MAX_LIFE_MINS		360	/* on-life in minutes */
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/palmtx.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,6 @@
 
 /* USB */
 #define GPIO_NR_PALMTX_USB_DETECT_N		13
-#define GPIO_NR_PALMTX_USB_POWER		95
 #define GPIO_NR_PALMTX_USB_PULLUP		93
 
 /* LCD/BACKLIGHT */
@@ -78,6 +77,8 @@
 #define PALMTX_PHYS_RAM_START	0xa0000000
 #define PALMTX_PHYS_IO_START	0x40000000
 
+#define PALMTX_STR_BASE		0xa0200000
+
 #define PALMTX_PHYS_FLASH_START	PXA_CS0_PHYS	/* ChipSelect 0 */
 #define PALMTX_PHYS_NAND_START	PXA_CS1_PHYS	/* ChipSelect 1 */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pm.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pm.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pm.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,3 +27,13 @@ extern void pxa27x_cpu_suspend(unsigned
 extern void pxa_cpu_resume(void);
 
 extern int pxa_pm_enter(suspend_state_t state);
+
+/* NOTE: this is for PM debugging on Lubbock,  it's really a big
+ * ugly, but let's keep the crap minimum here, instead of direct
+ * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
+ */
+#ifdef CONFIG_ARCH_LUBBOCK
+extern void lubbock_set_hexled(uint32_t value);
+#else
+#define lubbock_set_hexled(x)
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa25x.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa25x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa25x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa25x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+
+#endif /* __MACH_PXA25x_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa27x.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa27x.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa27x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa27x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#ifndef __MACH_PXA27x_H
+#define __MACH_PXA27x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+
+#define ARB_CNTRL	__REG(0x48000048)  /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK	(1<<31)	   /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK		(1<<30)	   /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK 	(1<<29)	   /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK	(1<<28)	   /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK		(1<<27)	   /* Be parked with USB when idle */
+#define ARB_LCD_PARK		(1<<26)	   /* Be parked with LCD when idle */
+#define ARB_DMA_PARK		(1<<25)	   /* Be parked with DMA when idle */
+#define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
+#define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
+#endif /* __MACH_PXA27x_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,8 @@
 
 #warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h
 
+#include <mach/gpio.h>
+
 /* GPIO alternate function assignments */
 
 #define GPIO1_RST		1	/* reset */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,19 @@
 #ifndef __PXA2XX_REGS_H
 #define __PXA2XX_REGS_H
 
+#include <mach/hardware.h>
+
+/*
+ * PXA Chip selects
+ */
+
+#define PXA_CS0_PHYS	0x00000000
+#define PXA_CS1_PHYS	0x04000000
+#define PXA_CS2_PHYS	0x08000000
+#define PXA_CS3_PHYS	0x0C000000
+#define PXA_CS4_PHYS	0x10000000
+#define PXA_CS5_PHYS	0x14000000
+
 /*
  * Memory controller
  */
@@ -69,24 +82,6 @@
 #define MDREFR_K0RUN	(1 << 13)	/* SDCLK0 Run Control/Status */
 #define MDREFR_E0PIN	(1 << 12)	/* SDCKE0 Level Control/Status */
 
-
-#ifdef CONFIG_PXA27x
-
-#define ARB_CNTRL	__REG(0x48000048)  /* Arbiter Control Register */
-
-#define ARB_DMA_SLV_PARK	(1<<31)	   /* Be parked with DMA slave when idle */
-#define ARB_CI_PARK		(1<<30)	   /* Be parked with Camera Interface when idle */
-#define ARB_EX_MEM_PARK 	(1<<29)	   /* Be parked with external MEMC when idle */
-#define ARB_INT_MEM_PARK	(1<<28)	   /* Be parked with internal MEMC when idle */
-#define ARB_USB_PARK		(1<<27)	   /* Be parked with USB when idle */
-#define ARB_LCD_PARK		(1<<26)	   /* Be parked with LCD when idle */
-#define ARB_DMA_PARK		(1<<25)	   /* Be parked with DMA when idle */
-#define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
-#define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
-
-#endif
-
-
 /*
  * Power Manager
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@ struct pxa2xx_spi_chip {
 	u8 dma_burst_size;
 	u32 timeout;
 	u8 enable_loopback;
+	int gpio_cs;
 	void (*cs_control)(u32 command);
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa300.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa300.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa300.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa300.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+
+#endif /* __MACH_PXA300_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa320.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa320.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa320.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa320.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+
+#endif /* __MACH_PXA320_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data {
 	 */
 	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;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,17 @@
 #ifndef __ASM_ARCH_PXA3XX_REGS_H
 #define __ASM_ARCH_PXA3XX_REGS_H
 
+#include <mach/hardware.h>
+
+/*
+ * Static Chip Selects
+ */
+
+#define PXA300_CS0_PHYS		(0x00000000)	/* PXA300/PXA310 _only_ */
+#define PXA300_CS1_PHYS		(0x30000000)	/* PXA300/PXA310 _only_ */
+#define PXA3xx_CS2_PHYS		(0x10000000)
+#define PXA3xx_CS3_PHYS		(0x14000000)
+
 /*
  * Oscillator Configuration Register (OSCC)
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa930.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa930.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa930.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa930.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa930.h>
+
+#endif /* __MACH_PXA930_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa-regs.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa-regs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/pxa-regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/pxa-regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,263 +0,0 @@
-/*
- *  arch/arm/mach-pxa/include/mach/pxa-regs.h
- *
- *  Author:	Nicolas Pitre
- *  Created:	Jun 15, 2001
- *  Copyright:	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 version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __PXA_REGS_H
-#define __PXA_REGS_H
-
-#include <mach/hardware.h>
-
-/*
- * PXA Chip selects
- */
-
-#define PXA_CS0_PHYS	0x00000000
-#define PXA_CS1_PHYS	0x04000000
-#define PXA_CS2_PHYS	0x08000000
-#define PXA_CS3_PHYS	0x0C000000
-#define PXA_CS4_PHYS	0x10000000
-#define PXA_CS5_PHYS	0x14000000
-
-
-/*
- * Personal Computer Memory Card International Association (PCMCIA) sockets
- */
-
-#define PCMCIAPrtSp	0x04000000	/* PCMCIA Partition Space [byte]   */
-#define PCMCIASp	(4*PCMCIAPrtSp)	/* PCMCIA Space [byte]             */
-#define PCMCIAIOSp	PCMCIAPrtSp	/* PCMCIA I/O Space [byte]         */
-#define PCMCIAAttrSp	PCMCIAPrtSp	/* PCMCIA Attribute Space [byte]   */
-#define PCMCIAMemSp	PCMCIAPrtSp	/* PCMCIA Memory Space [byte]      */
-
-#define PCMCIA0Sp	PCMCIASp	/* PCMCIA 0 Space [byte]           */
-#define PCMCIA0IOSp	PCMCIAIOSp	/* PCMCIA 0 I/O Space [byte]       */
-#define PCMCIA0AttrSp	PCMCIAAttrSp	/* PCMCIA 0 Attribute Space [byte] */
-#define PCMCIA0MemSp	PCMCIAMemSp	/* PCMCIA 0 Memory Space [byte]    */
-
-#define PCMCIA1Sp	PCMCIASp	/* PCMCIA 1 Space [byte]           */
-#define PCMCIA1IOSp	PCMCIAIOSp	/* PCMCIA 1 I/O Space [byte]       */
-#define PCMCIA1AttrSp	PCMCIAAttrSp	/* PCMCIA 1 Attribute Space [byte] */
-#define PCMCIA1MemSp	PCMCIAMemSp	/* PCMCIA 1 Memory Space [byte]    */
-
-#define _PCMCIA(Nb)	        	/* PCMCIA [0..1]                   */ \
-                	(0x20000000 + (Nb)*PCMCIASp)
-#define _PCMCIAIO(Nb)	_PCMCIA (Nb)	/* PCMCIA I/O [0..1]               */
-#define _PCMCIAAttr(Nb)	        	/* PCMCIA Attribute [0..1]         */ \
-                	(_PCMCIA (Nb) + 2*PCMCIAPrtSp)
-#define _PCMCIAMem(Nb)	        	/* PCMCIA Memory [0..1]            */ \
-                	(_PCMCIA (Nb) + 3*PCMCIAPrtSp)
-
-#define _PCMCIA0	_PCMCIA (0)	/* PCMCIA 0                        */
-#define _PCMCIA0IO	_PCMCIAIO (0)	/* PCMCIA 0 I/O                    */
-#define _PCMCIA0Attr	_PCMCIAAttr (0)	/* PCMCIA 0 Attribute              */
-#define _PCMCIA0Mem	_PCMCIAMem (0)	/* PCMCIA 0 Memory                 */
-
-#define _PCMCIA1	_PCMCIA (1)	/* PCMCIA 1                        */
-#define _PCMCIA1IO	_PCMCIAIO (1)	/* PCMCIA 1 I/O                    */
-#define _PCMCIA1Attr	_PCMCIAAttr (1)	/* PCMCIA 1 Attribute              */
-#define _PCMCIA1Mem	_PCMCIAMem (1)	/* PCMCIA 1 Memory                 */
-
-
-
-/*
- * DMA Controller
- */
-#define DCSR(x)		__REG2(0x40000000, (x) << 2)
-
-#define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
-#define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
-#define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
-#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
-#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
-#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
-#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
-#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
-#define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
-#define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
-#define DCSR_SETCMPST	(1 << 25)       /* Set Descriptor Compare Status */
-#define DCSR_CLRCMPST	(1 << 24)       /* Clear Descriptor Compare Status */
-#define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
-#define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
-#endif
-
-#define DALGN		__REG(0x400000a0)  /* DMA Alignment Register */
-#define DINT		__REG(0x400000f0)  /* DMA Interrupt Register */
-
-#define DRCMR(n)	(*(((n) < 64) ? \
-			&__REG2(0x40000100, ((n) & 0x3f) << 2) : \
-			&__REG2(0x40001100, ((n) & 0x3f) << 2)))
-
-#define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
-#define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
-
-#define DDADR(x)	__REG2(0x40000200, (x) << 4)
-#define DSADR(x)	__REG2(0x40000204, (x) << 4)
-#define DTADR(x)	__REG2(0x40000208, (x) << 4)
-#define DCMD(x)		__REG2(0x4000020c, (x) << 4)
-
-#define DDADR_DESCADDR	0xfffffff0	/* Address of next descriptor (mask) */
-#define DDADR_STOP	(1 << 0)	/* Stop (read / write) */
-
-#define DCMD_INCSRCADDR	(1 << 31)	/* Source Address Increment Setting. */
-#define DCMD_INCTRGADDR	(1 << 30)	/* Target Address Increment Setting. */
-#define DCMD_FLOWSRC	(1 << 29)	/* Flow Control by the source. */
-#define DCMD_FLOWTRG	(1 << 28)	/* Flow Control by the target. */
-#define DCMD_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
-#define DCMD_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
-#define DCMD_ENDIAN	(1 << 18)	/* Device Endian-ness. */
-#define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
-#define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
-#define DCMD_BURST32	(3 << 16)	/* 32 byte burst */
-#define DCMD_WIDTH1	(1 << 14)	/* 1 byte width */
-#define DCMD_WIDTH2	(2 << 14)	/* 2 byte width (HalfWord) */
-#define DCMD_WIDTH4	(3 << 14)	/* 4 byte width (Word) */
-#define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
-
-/*
- * Real Time Clock
- */
-
-#define RCNR		__REG(0x40900000)  /* RTC Count Register */
-#define RTAR		__REG(0x40900004)  /* RTC Alarm Register */
-#define RTSR		__REG(0x40900008)  /* RTC Status Register */
-#define RTTR		__REG(0x4090000C)  /* RTC Timer Trim Register */
-#define PIAR		__REG(0x40900038)  /* Periodic Interrupt Alarm Register */
-
-#define RTSR_PICE	(1 << 15)	/* Periodic interrupt count enable */
-#define RTSR_PIALE	(1 << 14)	/* Periodic interrupt Alarm enable */
-#define RTSR_HZE	(1 << 3)	/* HZ interrupt enable */
-#define RTSR_ALE	(1 << 2)	/* RTC alarm interrupt enable */
-#define RTSR_HZ		(1 << 1)	/* HZ rising-edge detected */
-#define RTSR_AL		(1 << 0)	/* RTC alarm detected */
-
-
-/*
- * OS Timer & Match Registers
- */
-
-#define OSMR0		__REG(0x40A00000)  /* */
-#define OSMR1		__REG(0x40A00004)  /* */
-#define OSMR2		__REG(0x40A00008)  /* */
-#define OSMR3		__REG(0x40A0000C)  /* */
-#define OSMR4		__REG(0x40A00080)  /* */
-#define OSCR		__REG(0x40A00010)  /* OS Timer Counter Register */
-#define OSCR4		__REG(0x40A00040)  /* OS Timer Counter Register */
-#define OMCR4		__REG(0x40A000C0)  /* */
-#define OSSR		__REG(0x40A00014)  /* OS Timer Status Register */
-#define OWER		__REG(0x40A00018)  /* OS Timer Watchdog Enable Register */
-#define OIER		__REG(0x40A0001C)  /* OS Timer Interrupt Enable Register */
-
-#define OSSR_M3		(1 << 3)	/* Match status channel 3 */
-#define OSSR_M2		(1 << 2)	/* Match status channel 2 */
-#define OSSR_M1		(1 << 1)	/* Match status channel 1 */
-#define OSSR_M0		(1 << 0)	/* Match status channel 0 */
-
-#define OWER_WME	(1 << 0)	/* Watchdog Match Enable */
-
-#define OIER_E3		(1 << 3)	/* Interrupt enable channel 3 */
-#define OIER_E2		(1 << 2)	/* Interrupt enable channel 2 */
-#define OIER_E1		(1 << 1)	/* Interrupt enable channel 1 */
-#define OIER_E0		(1 << 0)	/* Interrupt enable channel 0 */
-
-
-/*
- * Interrupt Controller
- */
-
-#define ICIP		__REG(0x40D00000)  /* Interrupt Controller IRQ Pending Register */
-#define ICMR		__REG(0x40D00004)  /* Interrupt Controller Mask Register */
-#define ICLR		__REG(0x40D00008)  /* Interrupt Controller Level Register */
-#define ICFP		__REG(0x40D0000C)  /* Interrupt Controller FIQ Pending Register */
-#define ICPR		__REG(0x40D00010)  /* Interrupt Controller Pending Register */
-#define ICCR		__REG(0x40D00014)  /* Interrupt Controller Control Register */
-
-#define ICIP2		__REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */
-#define ICMR2		__REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */
-#define ICLR2		__REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */
-#define ICFP2		__REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */
-#define ICPR2		__REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */
-
-/*
- * General Purpose I/O
- */
-
-#define GPLR0		__REG(0x40E00000)  /* GPIO Pin-Level Register GPIO<31:0> */
-#define GPLR1		__REG(0x40E00004)  /* GPIO Pin-Level Register GPIO<63:32> */
-#define GPLR2		__REG(0x40E00008)  /* GPIO Pin-Level Register GPIO<80:64> */
-
-#define GPDR0		__REG(0x40E0000C)  /* GPIO Pin Direction Register GPIO<31:0> */
-#define GPDR1		__REG(0x40E00010)  /* GPIO Pin Direction Register GPIO<63:32> */
-#define GPDR2		__REG(0x40E00014)  /* GPIO Pin Direction Register GPIO<80:64> */
-
-#define GPSR0		__REG(0x40E00018)  /* GPIO Pin Output Set Register GPIO<31:0> */
-#define GPSR1		__REG(0x40E0001C)  /* GPIO Pin Output Set Register GPIO<63:32> */
-#define GPSR2		__REG(0x40E00020)  /* GPIO Pin Output Set Register GPIO<80:64> */
-
-#define GPCR0		__REG(0x40E00024)  /* GPIO Pin Output Clear Register GPIO<31:0> */
-#define GPCR1		__REG(0x40E00028)  /* GPIO Pin Output Clear Register GPIO <63:32> */
-#define GPCR2		__REG(0x40E0002C)  /* GPIO Pin Output Clear Register GPIO <80:64> */
-
-#define GRER0		__REG(0x40E00030)  /* GPIO Rising-Edge Detect Register GPIO<31:0> */
-#define GRER1		__REG(0x40E00034)  /* GPIO Rising-Edge Detect Register GPIO<63:32> */
-#define GRER2		__REG(0x40E00038)  /* GPIO Rising-Edge Detect Register GPIO<80:64> */
-
-#define GFER0		__REG(0x40E0003C)  /* GPIO Falling-Edge Detect Register GPIO<31:0> */
-#define GFER1		__REG(0x40E00040)  /* GPIO Falling-Edge Detect Register GPIO<63:32> */
-#define GFER2		__REG(0x40E00044)  /* GPIO Falling-Edge Detect Register GPIO<80:64> */
-
-#define GEDR0		__REG(0x40E00048)  /* GPIO Edge Detect Status Register GPIO<31:0> */
-#define GEDR1		__REG(0x40E0004C)  /* GPIO Edge Detect Status Register GPIO<63:32> */
-#define GEDR2		__REG(0x40E00050)  /* GPIO Edge Detect Status Register GPIO<80:64> */
-
-#define GAFR0_L		__REG(0x40E00054)  /* GPIO Alternate Function Select Register GPIO<15:0> */
-#define GAFR0_U		__REG(0x40E00058)  /* GPIO Alternate Function Select Register GPIO<31:16> */
-#define GAFR1_L		__REG(0x40E0005C)  /* GPIO Alternate Function Select Register GPIO<47:32> */
-#define GAFR1_U		__REG(0x40E00060)  /* GPIO Alternate Function Select Register GPIO<63:48> */
-#define GAFR2_L		__REG(0x40E00064)  /* GPIO Alternate Function Select Register GPIO<79:64> */
-#define GAFR2_U		__REG(0x40E00068)  /* GPIO Alternate Function Select Register GPIO<95-80> */
-#define GAFR3_L		__REG(0x40E0006C)  /* GPIO Alternate Function Select Register GPIO<111:96> */
-#define GAFR3_U		__REG(0x40E00070)  /* GPIO Alternate Function Select Register GPIO<127:112> */
-
-#define GPLR3		__REG(0x40E00100)  /* GPIO Pin-Level Register GPIO<127:96> */
-#define GPDR3		__REG(0x40E0010C)  /* GPIO Pin Direction Register GPIO<127:96> */
-#define GPSR3		__REG(0x40E00118)  /* GPIO Pin Output Set Register GPIO<127:96> */
-#define GPCR3		__REG(0x40E00124)  /* GPIO Pin Output Clear Register GPIO<127:96> */
-#define GRER3		__REG(0x40E00130)  /* GPIO Rising-Edge Detect Register GPIO<127:96> */
-#define GFER3		__REG(0x40E0013C)  /* GPIO Falling-Edge Detect Register GPIO<127:96> */
-#define GEDR3		__REG(0x40E00148)  /* GPIO Edge Detect Status Register GPIO<127:96> */
-
-/* More handy macros.  The argument is a literal GPIO number. */
-
-#define GPIO_bit(x)	(1 << ((x) & 0x1f))
-
-#define _GPLR(x)	__REG2(0x40E00000, ((x) & 0x60) >> 3)
-#define _GPDR(x)	__REG2(0x40E0000C, ((x) & 0x60) >> 3)
-#define _GPSR(x)	__REG2(0x40E00018, ((x) & 0x60) >> 3)
-#define _GPCR(x)	__REG2(0x40E00024, ((x) & 0x60) >> 3)
-#define _GRER(x)	__REG2(0x40E00030, ((x) & 0x60) >> 3)
-#define _GFER(x)	__REG2(0x40E0003C, ((x) & 0x60) >> 3)
-#define _GEDR(x)	__REG2(0x40E00048, ((x) & 0x60) >> 3)
-#define _GAFR(x)	__REG2(0x40E00054, ((x) & 0x70) >> 2)
-
-#define GPLR(x) 	(*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3))
-#define GPDR(x)		(*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3))
-#define GPSR(x)		(*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3))
-#define GPCR(x)		(*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3))
-#define GRER(x)		(*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3))
-#define GFER(x)		(*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3))
-#define GEDR(x)		(*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3))
-#define GAFR(x)		(*((((x) & 0x7f) < 96) ? &_GAFR(x) : \
-			 ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U)))
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-intc.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-intc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-intc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-intc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_INTC_H
+#define __ASM_MACH_REGS_INTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Interrupt Controller
+ */
+
+#define ICIP		__REG(0x40D00000)  /* Interrupt Controller IRQ Pending Register */
+#define ICMR		__REG(0x40D00004)  /* Interrupt Controller Mask Register */
+#define ICLR		__REG(0x40D00008)  /* Interrupt Controller Level Register */
+#define ICFP		__REG(0x40D0000C)  /* Interrupt Controller FIQ Pending Register */
+#define ICPR		__REG(0x40D00010)  /* Interrupt Controller Pending Register */
+#define ICCR		__REG(0x40D00014)  /* Interrupt Controller Control Register */
+
+#define ICIP2		__REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */
+#define ICMR2		__REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */
+#define ICLR2		__REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */
+#define ICFP2		__REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */
+#define ICPR2		__REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */
+
+#endif /* __ASM_MACH_REGS_INTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-ost.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-ost.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-ost.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-ost.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_REGS_OST_H
+#define __ASM_MACH_REGS_OST_H
+
+#include <mach/hardware.h>
+
+/*
+ * OS Timer & Match Registers
+ */
+
+#define OSMR0		__REG(0x40A00000)  /* */
+#define OSMR1		__REG(0x40A00004)  /* */
+#define OSMR2		__REG(0x40A00008)  /* */
+#define OSMR3		__REG(0x40A0000C)  /* */
+#define OSMR4		__REG(0x40A00080)  /* */
+#define OSCR		__REG(0x40A00010)  /* OS Timer Counter Register */
+#define OSCR4		__REG(0x40A00040)  /* OS Timer Counter Register */
+#define OMCR4		__REG(0x40A000C0)  /* */
+#define OSSR		__REG(0x40A00014)  /* OS Timer Status Register */
+#define OWER		__REG(0x40A00018)  /* OS Timer Watchdog Enable Register */
+#define OIER		__REG(0x40A0001C)  /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3		(1 << 3)	/* Match status channel 3 */
+#define OSSR_M2		(1 << 2)	/* Match status channel 2 */
+#define OSSR_M1		(1 << 1)	/* Match status channel 1 */
+#define OSSR_M0		(1 << 0)	/* Match status channel 0 */
+
+#define OWER_WME	(1 << 0)	/* Watchdog Match Enable */
+
+#define OIER_E3		(1 << 3)	/* Interrupt enable channel 3 */
+#define OIER_E2		(1 << 2)	/* Interrupt enable channel 2 */
+#define OIER_E1		(1 << 1)	/* Interrupt enable channel 1 */
+#define OIER_E0		(1 << 0)	/* Interrupt enable channel 0 */
+
+#endif /* __ASM_MACH_REGS_OST_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-rtc.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-rtc.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR		__REG(0x40900000)  /* RTC Count Register */
+#define RTAR		__REG(0x40900004)  /* RTC Alarm Register */
+#define RTSR		__REG(0x40900008)  /* RTC Status Register */
+#define RTTR		__REG(0x4090000C)  /* RTC Timer Trim Register */
+#define PIAR		__REG(0x40900038)  /* Periodic Interrupt Alarm Register */
+
+#define RTSR_PICE	(1 << 15)	/* Periodic interrupt count enable */
+#define RTSR_PIALE	(1 << 14)	/* Periodic interrupt Alarm enable */
+#define RTSR_HZE	(1 << 3)	/* HZ interrupt enable */
+#define RTSR_ALE	(1 << 2)	/* RTC alarm interrupt enable */
+#define RTSR_HZ		(1 << 1)	/* HZ rising-edge detected */
+#define RTSR_AL		(1 << 0)	/* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-ssp.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-ssp.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/regs-ssp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/regs-ssp.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,6 @@
 #if defined(CONFIG_PXA25x)
 #define SSCR0_SCR	(0x0000ff00)	/* Serial Clock Rate (mask) */
 #define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-
 #elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define SSCR0_SCR	(0x000fff00)	/* Serial Clock Rate (mask) */
 #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
@@ -50,7 +49,7 @@
 #define SSCR0_TUM	(1 << 23)	/* Transmit FIFO underrun interrupt mask */
 #define SSCR0_FRDC	(0x07000000)	/* Frame rate divider control (mask) */
 #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24)	/* Time slots per frame [1..8] */
-#define SSCR0_ADC	(1 << 30)	/* Audio clock select */
+#define SSCR0_ACS	(1 << 30)	/* Audio clock select */
 #define SSCR0_MOD	(1 << 31)	/* Mode (normal or network) */
 #endif
 
@@ -109,6 +108,11 @@
 #define SSSR_TINT		(1 << 19)	/* Receiver Time-out Interrupt */
 #define SSSR_PINT		(1 << 18)	/* Peripheral Trailing Byte Interrupt */
 
+#if defined(CONFIG_PXA3xx)
+#define SSPSP_EDMYSTOP(x)	((x) << 28)     /* Extended Dummy Stop */
+#define SSPSP_EDMYSTRT(x)	((x) << 26)     /* Extended Dummy Start */
+#endif
+
 #define SSPSP_FSRT		(1 << 25)	/* Frame Sync Relative Timing */
 #define SSPSP_DMYSTOP(x)	((x) << 23)	/* Dummy Stop */
 #define SSPSP_SFRMWDTH(x)	((x) << 16)	/* Serial Frame Width */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/reset.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/reset.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/reset.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/reset.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,8 +13,9 @@ extern void clear_reset_status(unsigned
 /**
  * init_gpio_reset() - register GPIO as reset generator
  * @gpio: gpio nr
- * @output: set gpio as out/low instead of input during normal work
+ * @output: set gpio as output instead of input during normal work
+ * @level: output level
  */
-extern int init_gpio_reset(int gpio, int output);
+extern int init_gpio_reset(int gpio, int output, int level);
 
 #endif /* __ASM_ARCH_RESET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@
 #include <asm/proc-fns.h>
 #include "hardware.h"
 #include "pxa2xx-regs.h"
-#include "pxa-regs.h"
 
 static inline void arch_idle(void)
 {
@@ -21,4 +20,4 @@ static inline void arch_idle(void)
 }
 
 
-void arch_reset(char mode);
+void arch_reset(char mode, const char *cmd);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/include/mach/uncompress.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,8 @@ static inline void flush(void)
 
 static inline void arch_decomp_setup(void)
 {
-	if (machine_is_littleton() || machine_is_intelmote2())
+	if (machine_is_littleton() || machine_is_intelmote2()
+			|| machine_is_csb726())
 		UART = STUART;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/irq.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,8 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
+#include <mach/gpio.h>
+#include <mach/regs-intc.h>
 
 #include "generic.h"
 
@@ -51,6 +52,72 @@ static struct irq_chip pxa_internal_irq_
 	.unmask		= pxa_unmask_irq,
 };
 
+/*
+ * GPIO IRQs for GPIO 0 and 1
+ */
+static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
+{
+	int gpio = irq - IRQ_GPIO0;
+
+	if (__gpio_is_occupied(gpio)) {
+		pr_err("%s failed: GPIO is configured\n", __func__);
+		return -EINVAL;
+	}
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		GRER0 |= GPIO_bit(gpio);
+	else
+		GRER0 &= ~GPIO_bit(gpio);
+
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		GFER0 |= GPIO_bit(gpio);
+	else
+		GFER0 &= ~GPIO_bit(gpio);
+
+	return 0;
+}
+
+static void pxa_ack_low_gpio(unsigned int irq)
+{
+	GEDR0 = (1 << (irq - IRQ_GPIO0));
+}
+
+static void pxa_mask_low_gpio(unsigned int irq)
+{
+	ICMR &= ~(1 << (irq - PXA_IRQ(0)));
+}
+
+static void pxa_unmask_low_gpio(unsigned int irq)
+{
+	ICMR |= 1 << (irq - PXA_IRQ(0));
+}
+
+static struct irq_chip pxa_low_gpio_chip = {
+	.name		= "GPIO-l",
+	.ack		= pxa_ack_low_gpio,
+	.mask		= pxa_mask_low_gpio,
+	.unmask		= pxa_unmask_low_gpio,
+	.set_type	= pxa_set_low_gpio_type,
+};
+
+static void __init pxa_init_low_gpio_irq(set_wake_t fn)
+{
+	int irq;
+
+	/* clear edge detection on GPIO 0 and 1 */
+	GFER0 &= ~0x3;
+	GRER0 &= ~0x3;
+	GEDR0 = 0x3;
+
+	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
+		set_irq_chip(irq, &pxa_low_gpio_chip);
+		set_irq_handler(irq, handle_edge_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	pxa_low_gpio_chip.set_wake = fn;
+}
+
 void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 {
 	int irq;
@@ -72,6 +139,7 @@ void __init pxa_init_irq(int irq_nr, set
 	}
 
 	pxa_internal_irq_chip.set_wake = fn;
+	pxa_init_low_gpio_irq(fn);
 }
 
 #ifdef CONFIG_PM
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,9 @@ choice
 config GUMSTIX_AM200EPD
 	bool "Enable AM200EPD board support"
 
+config GUMSTIX_AM300EPD
+	bool "Enable AM300EPD board support"
+
 endchoice
 
 config MACH_INTELMOTE2
@@ -254,10 +257,24 @@ config MACH_EM_X270
 	bool "CompuLab EM-x270 platform"
 	select PXA27x
 
+config MACH_EXEDA
+	bool "CompuLab eXeda platform"
+	select PXA27x
+
 config MACH_COLIBRI
-	bool "Toradex Colibri PX27x"
+	bool "Toradex Colibri PXA270"
 	select PXA27x
 
+config MACH_COLIBRI300
+	bool "Toradex Colibri PXA300/310"
+	select PXA3xx
+	select CPU_PXA300
+
+config MACH_COLIBRI320
+	bool "Toradex Colibri PXA320"
+	select PXA3xx
+	select CPU_PXA320
+
 config MACH_ZYLONITE
 	bool "PXA3xx Development Platform (aka Zylonite)"
 	select PXA3xx
@@ -272,12 +289,12 @@ config MACH_LITTLETON
 config MACH_TAVOREVB
 	bool "PXA930 Evaluation Board (aka TavorEVB)"
 	select PXA3xx
-	select PXA930
+	select CPU_PXA930
 
 config MACH_SAAR
 	bool "PXA930 Handheld Platform (aka SAAR)"
 	select PXA3xx
-	select PXA930
+	select CPU_PXA930
 
 config MACH_ARMCORE
 	bool "CompuLab CM-X255/CM-X270 modules"
@@ -295,8 +312,15 @@ config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
 	select PXA27x
 	select IWMMXT
+	select PXA_SSP
+	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
@@ -319,6 +343,25 @@ config ARCH_PXA_PALM
 	bool "PXA based Palm PDAs"
 	select HAVE_PWM
 
+config MACH_PALMTE2
+	bool "Palm Tungsten|E2"
+	default y
+	depends on ARCH_PXA_PALM
+	select PXA25x
+	help
+	  Say Y here if you intend to run this kernel on a Palm Tungsten|E2
+	  handheld computer.
+
+config MACH_PALMT5
+	bool "Palm Tungsten|T5"
+	default y
+	depends on ARCH_PXA_PALM
+	select PXA27x
+	select IWMMXT
+	help
+	  Say Y here if you intend to run this kernel on a Palm Tungsten|T5
+	  handheld computer.
+
 config MACH_PALMTX
 	bool "Palm T|X"
 	default y
@@ -339,6 +382,16 @@ config MACH_PALMZ72
 	  Say Y here if you intend to run this kernel on Palm Zire 72
 	  handheld computer.
 
+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 a Palm LifeDrive
+	  handheld computer.
+
 config MACH_PCM990_BASEBOARD
 	bool "PHYTEC PCM-990 development board"
 	select HAVE_PWM
@@ -359,6 +412,18 @@ config PCM990_DISPLAY_NONE
 
 endchoice
 
+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 Cogent
+	  CSB726 System On Module.
+
+config CSB726_CSB701
+	bool "Enable supprot for CSB701 baseboard"
+	depends on MACH_CSB726
+
 config PXA_EZX
 	bool "Motorola EZX Platform"
 	select PXA27x
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-idp.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-idp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-idp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-idp.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/leds.h>
 #include <asm/system.h>
 
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
 #include <mach/idp.h>
 
 #include "leds.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-lubbock.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-lubbock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-lubbock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-lubbock.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
 #include <mach/lubbock.h>
 
 #include "leds.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-mainstone.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-mainstone.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/leds-mainstone.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/leds-mainstone.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #include <asm/leds.h>
 #include <asm/system.h>
 
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
 #include <mach/mainstone.h>
 
 #include "leds.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/littleton.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/littleton.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/littleton.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/littleton.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,8 +39,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
 #include <mach/pxafb.h>
 #include <mach/ssp.h>
 #include <mach/pxa2xx_spi.h>
@@ -335,6 +334,11 @@ static struct led_info littleton_da9034_
 	},
 };
 
+static struct da9034_touch_pdata littleton_da9034_touch = {
+	.x_inverted     = 1,
+	.interval_ms    = 20,
+};
+
 static struct da903x_subdev_info littleton_da9034_subdevs[] = {
 	{
 		.name		= "da903x-led",
@@ -351,6 +355,10 @@ static struct da903x_subdev_info littlet
 	}, {
 		.name		= "da903x-backlight",
 		.id		= DA9034_ID_WLED,
+	}, {
+		.name		= "da9034-touch",
+		.id		= DA9034_ID_TOUCH,
+		.platform_data	= &littleton_da9034_touch,
 	},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/lpd270.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/lpd270.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/lpd270.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/lpd270.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,9 +38,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
 #include <mach/lpd270.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/lubbock.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/lubbock.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/lubbock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/lubbock.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,15 +41,15 @@
 
 #include <asm/hardware/sa1111.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
+#include <mach/gpio.h>
 #include <mach/audio.h>
 #include <mach/lubbock.h>
 #include <mach/udc.h>
 #include <mach/irda.h>
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
+#include <mach/pm.h>
 
 #include "generic.h"
 #include "clock.h"
@@ -113,8 +113,14 @@ static unsigned long lubbock_pin_config[
 	GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
 };
 
+#define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
 #define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
 
+void lubbock_set_hexled(uint32_t value)
+{
+	LUB_HEXLED = value;
+}
+
 void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
 {
 	unsigned long flags;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/magician.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/magician.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/magician.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/magician.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,14 +25,16 @@
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
+#include <linux/regulator/bq24022.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/gpio_vbus.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
 #include <mach/magician.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
 #include <mach/pxafb.h>
 #include <mach/i2c.h>
 #include <mach/mmc.h>
@@ -66,6 +68,11 @@ static unsigned long magician_pin_config
 	GPIO31_I2S_SYNC,
 	GPIO113_I2S_SYSCLK,
 
+	/* SSP 1 */
+	GPIO23_SSP1_SCLK,
+	GPIO24_SSP1_SFRM,
+	GPIO25_SSP1_TXD,
+
 	/* SSP 2 */
 	GPIO19_SSP2_SCLK,
 	GPIO14_SSP2_SFRM,
@@ -148,22 +155,31 @@ static struct pxaficp_platform_data magi
  * GPIO Keys
  */
 
+#define INIT_KEY(_code, _gpio, _desc)	\
+	{				\
+		.code   = KEY_##_code,	\
+		.gpio   = _gpio,	\
+		.desc   = _desc,	\
+		.type   = EV_KEY,	\
+		.wakeup = 1,		\
+	}
+
 static struct gpio_keys_button magician_button_table[] = {
-	{KEY_POWER,      GPIO0_MAGICIAN_KEY_POWER,      0, "Power button"},
-	{KEY_ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    0, "Hangup button"},
-	{KEY_F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  0, "Contacts button"},
-	{KEY_CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  0, "Calendar button"},
-	{KEY_CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    0, "Camera button"},
-	{KEY_UP,         GPIO93_MAGICIAN_KEY_UP,        0, "Up button"},
-	{KEY_DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      0, "Down button"},
-	{KEY_LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      0, "Left button"},
-	{KEY_RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     0, "Right button"},
-	{KEY_KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     0, "Action button"},
-	{KEY_RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    0, "Record button"},
-	{KEY_VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   0, "Volume up"},
-	{KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
-	{KEY_PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    0, "Phone button"},
-	{KEY_PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  0, "Headset button"},
+	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
+	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
+	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
+	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
+	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
+	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
+	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
+	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
+	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
+	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
+	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
+	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
+	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
+	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
+	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
 };
 
 static struct gpio_keys_platform_data gpio_keys_data = {
@@ -189,7 +205,7 @@ static struct platform_device gpio_keys
 static struct resource egpio_resources[] = {
 	[0] = {
 		.start = PXA_CS3_PHYS,
-		.end   = PXA_CS3_PHYS + 0x20,
+		.end   = PXA_CS3_PHYS + 0x20 - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -420,7 +436,7 @@ static struct gpio_led gpio_leds[] = {
 	},
 	{
 		.name = "magician::phone_bl",
-		.default_trigger = "none",
+		.default_trigger = "backlight",
 		.gpio = GPIO103_MAGICIAN_LED_KP,
 	},
 };
@@ -468,8 +484,6 @@ static struct pasic3_led pasic3_leds[] =
 	},
 };
 
-static struct platform_device pasic3;
-
 static struct pasic3_leds_machinfo pasic3_leds_info = {
 	.num_leds   = ARRAY_SIZE(pasic3_leds),
 	.power_gpio = EGPIO_MAGICIAN_LED_POWER,
@@ -495,7 +509,6 @@ static struct resource pasic3_resources[
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-	.bus_shift  = 2,
 	.led_pdata  = &pasic3_leds_info,
 	.clock_rate = 4000000,
 };
@@ -511,61 +524,46 @@ static struct platform_device pasic3 = {
 };
 
 /*
- * External power
+ * USB "Transceiver"
  */
 
-static int power_supply_init(struct device *dev)
-{
-	int ret;
-
-	ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
-	if (ret)
-		goto err_cs_ac;
-	ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB");
-	if (ret)
-		goto err_cs_usb;
-	ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN");
-	if (ret)
-		goto err_chg_en;
-	ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN");
-	if (!ret)
-		ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0);
-	if (ret)
-		goto err_nchg_en;
+static struct resource gpio_vbus_resource = {
+	.flags = IORESOURCE_IRQ,
+	.start = IRQ_MAGICIAN_VBUS,
+	.end   = IRQ_MAGICIAN_VBUS,
+};
 
-	return 0;
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+	.gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
+};
 
-err_nchg_en:
-	gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
-err_chg_en:
-	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
-err_cs_usb:
-	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
-err_cs_ac:
-	return ret;
-}
+static struct platform_device gpio_vbus = {
+	.name          = "gpio-vbus",
+	.id            = -1,
+	.num_resources = 1,
+	.resource      = &gpio_vbus_resource,
+	.dev = {
+		.platform_data = &gpio_vbus_info,
+	},
+};
 
-static int magician_is_ac_online(void)
-{
-	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
-}
+/*
+ * External power
+ */
 
-static int magician_is_usb_online(void)
+static int power_supply_init(struct device *dev)
 {
-	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_USB);
+	return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
 }
 
-static void magician_set_charge(int flags)
+static int magician_is_ac_online(void)
 {
-	gpio_set_value(GPIO30_MAGICIAN_nCHARGE_EN, !flags);
-	gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags);
+	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
 }
 
 static void power_supply_exit(struct device *dev)
 {
-	gpio_free(GPIO30_MAGICIAN_nCHARGE_EN);
-	gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
-	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
 	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
 }
 
@@ -576,8 +574,6 @@ static char *magician_supplicants[] = {
 static struct pda_power_pdata power_supply_info = {
 	.init            = power_supply_init,
 	.is_ac_online    = magician_is_ac_online,
-	.is_usb_online   = magician_is_usb_online,
-	.set_charge      = magician_set_charge,
 	.exit            = power_supply_exit,
 	.supplied_to     = magician_supplicants,
 	.num_supplicants = ARRAY_SIZE(magician_supplicants),
@@ -586,15 +582,17 @@ static struct pda_power_pdata power_supp
 static struct resource power_supply_resources[] = {
 	[0] = {
 		.name  = "ac",
-		.flags = IORESOURCE_IRQ,
-		.start = IRQ_MAGICIAN_AC,
-		.end   = IRQ_MAGICIAN_AC,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+		         IORESOURCE_IRQ_LOWEDGE,
+		.start = IRQ_MAGICIAN_VBUS,
+		.end   = IRQ_MAGICIAN_VBUS,
 	},
 	[1] = {
 		.name  = "usb",
-		.flags = IORESOURCE_IRQ,
-		.start = IRQ_MAGICIAN_AC,
-		.end   = IRQ_MAGICIAN_AC,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+		         IORESOURCE_IRQ_LOWEDGE,
+		.start = IRQ_MAGICIAN_VBUS,
+		.end   = IRQ_MAGICIAN_VBUS,
 	},
 };
 
@@ -608,6 +606,43 @@ static struct platform_device power_supp
 	.num_resources = ARRAY_SIZE(power_supply_resources),
 };
 
+/*
+ * Battery charger
+ */
+
+static struct regulator_consumer_supply bq24022_consumers[] = {
+	{
+		.dev = &gpio_vbus.dev,
+		.supply = "vbus_draw",
+	},
+	{
+		.dev = &power_supply.dev,
+		.supply = "ac_draw",
+	},
+};
+
+static struct regulator_init_data bq24022_init_data = {
+	.constraints = {
+		.max_uA         = 500000,
+		.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
+	.consumer_supplies      = bq24022_consumers,
+};
+
+static struct bq24022_mach_info bq24022_info = {
+	.gpio_nce   = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+	.gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
+	.init_data  = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+	.name = "bq24022",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &bq24022_info,
+	},
+};
 
 /*
  * MMC/SD
@@ -688,11 +723,9 @@ static void magician_set_vpp(struct map_
 	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
 
-#define PXA_CS_SIZE		0x04000000
-
 static struct resource strataflash_resource = {
 	.start = PXA_CS0_PHYS,
-	.end   = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
+	.end   = PXA_CS0_PHYS + SZ_64M - 1,
 	.flags = IORESOURCE_MEM,
 };
 
@@ -720,6 +753,8 @@ static struct platform_device *devices[]
 	&egpio,
 	&backlight,
 	&pasic3,
+	&bq24022,
+	&gpio_vbus,
 	&power_supply,
 	&strataflash,
 	&leds_gpio,
@@ -743,6 +778,7 @@ static void __init magician_init(void)
 		gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
 		pxa_set_ficp_info(&magician_ficp_info);
 	}
+	pxa27x_set_i2c_power_info(NULL);
 	pxa_set_i2c_info(NULL);
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mainstone.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mainstone.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mainstone.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mainstone.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,9 +41,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
 #include <mach/mainstone.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/Makefile linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,8 +3,8 @@
 #
 
 # Common support (must be linked before board specific support)
-obj-y				+= clock.o devices.o generic.o irq.o dma.o \
-				   time.o gpio.o reset.o
+obj-y				+= clock.o devices.o generic.o irq.o \
+				   time.o reset.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o standby.o
 
 ifeq ($(CONFIG_CPU_FREQ),y)
@@ -28,13 +28,16 @@ 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
 obj-$(CONFIG_ARCH_LUBBOCK)	+= lubbock.o
 obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
 obj-$(CONFIG_MACH_MAINSTONE)	+= mainstone.o
 obj-$(CONFIG_MACH_MP900C)	+= mp900.o
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
 obj-$(CONFIG_MACH_TRIZEPS4)	+= trizeps4.o
-obj-$(CONFIG_MACH_COLIBRI)	+= colibri.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
 obj-$(CONFIG_MACH_H5000)	+= h5000.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
@@ -45,6 +48,7 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= p
 obj-$(CONFIG_MACH_TOSA)		+= tosa.o
 obj-$(CONFIG_MACH_EM_X270)	+= em-x270.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
@@ -53,7 +57,10 @@ 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_PALMT5)	+= palmt5.o
 obj-$(CONFIG_MACH_PALMTX)	+= palmtx.o
+obj-$(CONFIG_MACH_PALMLD)	+= palmld.o
 obj-$(CONFIG_MACH_PALMZ72)	+= palmz72.o
 obj-$(CONFIG_ARCH_VIPER)	+= viper.o
 
@@ -71,6 +78,8 @@ obj-$(CONFIG_MACH_CM_X300)      += cm-x3
 obj-$(CONFIG_PXA_EZX)           += ezx.o
 
 obj-$(CONFIG_MACH_INTELMOTE2)   += imote2.o
+obj-$(CONFIG_MACH_CSB726)	+= csb726.o
+obj-$(CONFIG_CSB726_CSB701)	+= csb701.o
 
 # Support for blinky lights
 led-y := leds.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mfp-pxa2xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mfp-pxa2xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mfp-pxa2xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mfp-pxa2xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,15 +18,12 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/gpio.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/mfp-pxa2xx.h>
 
 #include "generic.h"
 
-#define gpio_to_bank(gpio)	((gpio) >> 5)
-
 #define PGSR(x)		__REG2(0x40F00020, (x) << 2)
 #define __GAFR(u, x)	__REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
 #define GAFR_L(x)	__GAFR(0, x)
@@ -325,6 +322,7 @@ static inline void pxa27x_mfp_init(void)
 #ifdef CONFIG_PM
 static unsigned long saved_gafr[2][4];
 static unsigned long saved_gpdr[4];
+static unsigned long saved_pgsr[4];
 
 static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
 {
@@ -335,6 +333,7 @@ static int pxa2xx_mfp_suspend(struct sys
 		saved_gafr[0][i] = GAFR_L(i);
 		saved_gafr[1][i] = GAFR_U(i);
 		saved_gpdr[i] = GPDR(i * 32);
+		saved_pgsr[i] = PGSR(i);
 
 		GPDR(i * 32) = gpdr_lpm[i];
 	}
@@ -349,6 +348,7 @@ static int pxa2xx_mfp_resume(struct sys_
 		GAFR_L(i) = saved_gafr[0][i];
 		GAFR_U(i) = saved_gafr[1][i];
 		GPDR(i * 32) = saved_gpdr[i];
+		PGSR(i) = saved_pgsr[i];
 	}
 	PSSR = PSSR_RDH | PSSR_PH;
 	return 0;
@@ -377,6 +377,9 @@ static int __init pxa2xx_mfp_init(void)
 	if (cpu_is_pxa27x())
 		pxa27x_mfp_init();
 
+	/* clear RDH bit to enable GPIO receivers after reset/sleep exit */
+	PSSR = PSSR_RDH;
+
 	/* initialize gafr_run[], pgsr_lpm[] from existing values */
 	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
 		gpdr_lpm[i] = GPDR(i * 32);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mfp-pxa3xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mfp-pxa3xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mfp-pxa3xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mfp-pxa3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,183 +20,9 @@
 #include <linux/sysdev.h>
 
 #include <mach/hardware.h>
-#include <mach/mfp.h>
 #include <mach/mfp-pxa3xx.h>
 #include <mach/pxa3xx-regs.h>
 
-/* mfp_spin_lock is used to ensure that MFP register configuration
- * (most likely a read-modify-write operation) is atomic, and that
- * mfp_table[] is consistent
- */
-static DEFINE_SPINLOCK(mfp_spin_lock);
-
-static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
-
-struct pxa3xx_mfp_pin {
-	unsigned long	config;		/* -1 for not configured */
-	unsigned long	mfpr_off;	/* MFPRxx Register offset */
-	unsigned long	mfpr_run;	/* Run-Mode Register Value */
-	unsigned long	mfpr_lpm;	/* Low Power Mode Register Value */
-};
-
-static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
-
-/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
-static const unsigned long mfpr_lpm[] = {
-	MFPR_LPM_INPUT,
-	MFPR_LPM_DRIVE_LOW,
-	MFPR_LPM_DRIVE_HIGH,
-	MFPR_LPM_PULL_LOW,
-	MFPR_LPM_PULL_HIGH,
-	MFPR_LPM_FLOAT,
-};
-
-/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
-static const unsigned long mfpr_pull[] = {
-	MFPR_PULL_NONE,
-	MFPR_PULL_LOW,
-	MFPR_PULL_HIGH,
-	MFPR_PULL_BOTH,
-};
-
-/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
-static const unsigned long mfpr_edge[] = {
-	MFPR_EDGE_NONE,
-	MFPR_EDGE_RISE,
-	MFPR_EDGE_FALL,
-	MFPR_EDGE_BOTH,
-};
-
-#define mfpr_readl(off)			\
-	__raw_readl(mfpr_mmio_base + (off))
-
-#define mfpr_writel(off, val)		\
-	__raw_writel(val, mfpr_mmio_base + (off))
-
-#define mfp_configured(p)	((p)->config != -1)
-
-/*
- * perform a read-back of any MFPR register to make sure the
- * previous writings are finished
- */
-#define mfpr_sync()	(void)__raw_readl(mfpr_mmio_base + 0)
-
-static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
-{
-	if (mfp_configured(p))
-		mfpr_writel(p->mfpr_off, p->mfpr_run);
-}
-
-static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
-{
-	if (mfp_configured(p)) {
-		unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
-		if (mfpr_clr != p->mfpr_run)
-			mfpr_writel(p->mfpr_off, mfpr_clr);
-		if (p->mfpr_lpm != mfpr_clr)
-			mfpr_writel(p->mfpr_off, p->mfpr_lpm);
-	}
-}
-
-void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
-{
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	for (i = 0; i < num; i++, mfp_cfgs++) {
-		unsigned long tmp, c = *mfp_cfgs;
-		struct pxa3xx_mfp_pin *p;
-		int pin, af, drv, lpm, edge, pull;
-
-		pin = MFP_PIN(c);
-		BUG_ON(pin >= MFP_PIN_MAX);
-		p = &mfp_table[pin];
-
-		af  = MFP_AF(c);
-		drv = MFP_DS(c);
-		lpm = MFP_LPM_STATE(c);
-		edge = MFP_LPM_EDGE(c);
-		pull = MFP_PULL(c);
-
-		/* run-mode pull settings will conflict with MFPR bits of
-		 * low power mode state,  calculate mfpr_run and mfpr_lpm
-		 * individually if pull != MFP_PULL_NONE
-		 */
-		tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
-
-		if (likely(pull == MFP_PULL_NONE)) {
-			p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
-			p->mfpr_lpm = p->mfpr_run;
-		} else {
-			p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
-			p->mfpr_run = tmp | mfpr_pull[pull];
-		}
-
-		p->config = c; __mfp_config_run(p);
-	}
-
-	mfpr_sync();
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-unsigned long pxa3xx_mfp_read(int mfp)
-{
-	unsigned long val, flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-	val = mfpr_readl(mfp_table[mfp].mfpr_off);
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-
-	return val;
-}
-
-void pxa3xx_mfp_write(int mfp, unsigned long val)
-{
-	unsigned long flags;
-
-	BUG_ON(mfp >= MFP_PIN_MAX);
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-	mfpr_writel(mfp_table[mfp].mfpr_off, val);
-	mfpr_sync();
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
-{
-	struct pxa3xx_mfp_addr_map *p;
-	unsigned long offset, flags;
-	int i;
-
-	spin_lock_irqsave(&mfp_spin_lock, flags);
-
-	for (p = map; p->start != MFP_PIN_INVALID; p++) {
-		offset = p->offset;
-		i = p->start;
-
-		do {
-			mfp_table[i].mfpr_off = offset;
-			mfp_table[i].mfpr_run = 0;
-			mfp_table[i].mfpr_lpm = 0;
-			offset += 4; i++;
-		} while ((i <= p->end) && (p->end != -1));
-	}
-
-	spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void __init pxa3xx_init_mfp(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
-		mfp_table[i].config = -1;
-}
-
 #ifdef CONFIG_PM
 /*
  * Configure the MFPs appropriately for suspend/resume.
@@ -207,23 +33,13 @@ void __init pxa3xx_init_mfp(void)
  */
 static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
 {
-	int pin;
-
-	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
-		struct pxa3xx_mfp_pin *p = &mfp_table[pin];
-		__mfp_config_lpm(p);
-	}
+	mfp_config_lpm();
 	return 0;
 }
 
 static int pxa3xx_mfp_resume(struct sys_device *d)
 {
-	int pin;
-
-	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
-		struct pxa3xx_mfp_pin *p = &mfp_table[pin];
-		__mfp_config_run(p);
-	}
+	mfp_config_run();
 
 	/* clear RDH bit when MFP settings are restored
 	 *
@@ -231,7 +47,6 @@ static int pxa3xx_mfp_resume(struct sys_
 	 * preserve them here in case they will be referenced later
 	 */
 	ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
-
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mioa701.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mioa701.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mioa701.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mioa701.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,18 +36,21 @@
 #include <linux/power_supply.h>
 #include <linux/wm97xx_batt.h>
 #include <linux/mtd/physmap.h>
+#include <linux/usb/gpio_vbus.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/mfp-pxa27x.h>
+
+#include <mach/pxa27x.h>
+#include <mach/regs-rtc.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/pxafb.h>
-#include <mach/pxa2xx-regs.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/i2c.h>
 #include <mach/camera.h>
+#include <mach/audio.h>
 #include <media/soc_camera.h>
 
 #include <mach/mioa701.h>
@@ -411,21 +414,6 @@ static void gsm_exit(void)
 /*
  * USB UDC
  */
-static void udc_power_command(int cmd)
-{
-	switch (cmd) {
-	case PXA2XX_UDC_CMD_DISCONNECT:
-		gpio_set_value(GPIO22_USB_ENABLE, 0);
-		break;
-	case PXA2XX_UDC_CMD_CONNECT:
-		gpio_set_value(GPIO22_USB_ENABLE, 1);
-		break;
-	default:
-		printk(KERN_INFO "udc_control: unknown command (0x%x)!\n", cmd);
-		break;
-	}
-}
-
 static int is_usb_connected(void)
 {
 	return !gpio_get_value(GPIO13_nUSB_DETECT);
@@ -433,24 +421,15 @@ static int is_usb_connected(void)
 
 static struct pxa2xx_udc_mach_info mioa701_udc_info = {
 	.udc_is_connected = is_usb_connected,
-	.udc_command	  = udc_power_command,
+	.gpio_pullup	  = GPIO22_USB_ENABLE,
 };
 
-struct gpio_ress udc_gpios[] = {
-	MIO_GPIO_OUT(GPIO22_USB_ENABLE, 0, "USB Vbus enable")
+struct gpio_vbus_mach_info gpio_vbus_data = {
+	.gpio_vbus = GPIO13_nUSB_DETECT,
+	.gpio_vbus_inverted = 1,
+	.gpio_pullup = -1,
 };
 
-static int __init udc_init(void)
-{
-	pxa_set_udc_info(&mioa701_udc_info);
-	return mio_gpio_request(ARRAY_AND_SIZE(udc_gpios));
-}
-
-static void udc_exit(void)
-{
-	mio_gpio_free(ARRAY_AND_SIZE(udc_gpios));
-}
-
 /*
  * SDIO/MMC Card controller
  */
@@ -763,6 +742,10 @@ struct i2c_pxa_platform_data i2c_pdata =
 	.fast_mode = 1,
 };
 
+static pxa2xx_audio_ops_t mioa701_ac97_info = {
+	.reset_gpio = 95,
+};
+
 /*
  * Mio global
  */
@@ -785,22 +768,20 @@ MIO_PARENT_DEV(mioa701_backlight, "pwm-b
 		&mioa701_backlight_data);
 MIO_SIMPLE_DEV(mioa701_led,	  "leds-gpio",	    &gpio_led_info)
 MIO_SIMPLE_DEV(pxa2xx_pcm,	  "pxa2xx-pcm",	    NULL)
-MIO_SIMPLE_DEV(pxa2xx_ac97,	  "pxa2xx-ac97",    NULL)
-MIO_PARENT_DEV(mio_wm9713_codec,  "wm9713-codec",   &pxa2xx_ac97.dev, NULL)
 MIO_SIMPLE_DEV(mioa701_sound,	  "mioa701-wm9713", NULL)
 MIO_SIMPLE_DEV(mioa701_board,	  "mioa701-board",  NULL)
+MIO_SIMPLE_DEV(gpio_vbus,	  "gpio-vbus",      &gpio_vbus_data);
 
 static struct platform_device *devices[] __initdata = {
 	&mioa701_gpio_keys,
 	&mioa701_backlight,
 	&mioa701_led,
 	&pxa2xx_pcm,
-	&pxa2xx_ac97,
-	&mio_wm9713_codec,
 	&mioa701_sound,
 	&power_dev,
 	&strataflash,
-	&mioa701_board
+	&gpio_vbus,
+	&mioa701_board,
 };
 
 static void mioa701_machine_exit(void);
@@ -808,13 +789,13 @@ static void mioa701_machine_exit(void);
 static void mioa701_poweroff(void)
 {
 	mioa701_machine_exit();
-	arm_machine_restart('s');
+	arm_machine_restart('s', NULL);
 }
 
-static void mioa701_restart(char c)
+static void mioa701_restart(char c, const char *cmd)
 {
 	mioa701_machine_exit();
-	arm_machine_restart('s');
+	arm_machine_restart('s', cmd);
 }
 
 struct gpio_ress global_gpios[] = {
@@ -837,7 +818,8 @@ static void __init mioa701_machine_init(
 	pxa_set_mci_info(&mioa701_mci_info);
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	wm97xx_bat_set_pdata(&mioa701_battery_data);
-	udc_init();
+	pxa_set_udc_info(&mioa701_udc_info);
+	pxa_set_ac97_info(&mioa701_ac97_info);
 	pm_power_off = mioa701_poweroff;
 	arm_pm_restart = mioa701_restart;
 	platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -850,7 +832,6 @@ static void __init mioa701_machine_init(
 
 static void mioa701_machine_exit(void)
 {
-	udc_exit();
 	bootstrap_exit();
 	gsm_exit();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mp900.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mp900.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/mp900.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/mp900.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,10 +19,10 @@
 #include <linux/types.h>
 #include <linux/usb/isp116x.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+
+#include <mach/pxa25x.h>
 #include "generic.h"
 
 static void isp116x_pfm_delay(struct device *dev, int delay)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmld.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmld.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmld.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmld.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,607 @@
+/*
+ * Hardware definitions for Palm LifeDrive
+ *
+ * Author:     Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ *		Alex Osborne <ato@meshy.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.
+ *
+ * (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 <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmld.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/palmasoc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmld_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,
+	GPIO14_GPIO,	/* SD detect */
+	GPIO114_GPIO,	/* SD power */
+	GPIO116_GPIO,	/* SD r/o switch */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO89_AC97_SYSCLK,
+	GPIO95_AC97_nRESET,
+
+	/* IrDA */
+	GPIO108_GPIO,	/* ir disable */
+	GPIO46_FICP_RXD,
+	GPIO47_FICP_TXD,
+
+	/* MATRIX KEYPAD */
+	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO103_KP_MKOUT_0,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+
+	/* 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,
+	GPIO77_LCD_BIAS,
+
+	/* PWM */
+	GPIO16_PWM0_OUT,
+
+	/* GPIO KEYS */
+	GPIO10_GPIO,	/* hotsync button */
+	GPIO12_GPIO,	/* power switch */
+	GPIO15_GPIO,	/* lock switch */
+
+	/* LEDs */
+	GPIO52_GPIO,	/* green led */
+	GPIO94_GPIO,	/* orange led */
+
+	/* PCMCIA */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO85_nPCE_1,
+	GPIO54_nPCE_2,
+	GPIO79_PSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+	GPIO36_GPIO,	/* wifi power */
+	GPIO38_GPIO,	/* wifi ready */
+	GPIO81_GPIO,	/* wifi reset */
+
+	/* HDD */
+	GPIO95_GPIO,	/* HDD irq */
+	GPIO115_GPIO,	/* HDD power */
+
+	/* MISC */
+	GPIO13_GPIO,	/* earphone detect */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmld_mci_init(struct device *dev, irq_handler_t palmld_detect_int,
+				void *data)
+{
+	int err = 0;
+
+	/* Setup an interrupt for detecting card insert/remove events */
+	err = gpio_request(GPIO_NR_PALMLD_SD_DETECT_N, "SD IRQ");
+	if (err)
+		goto err;
+	err = gpio_direction_input(GPIO_NR_PALMLD_SD_DETECT_N);
+	if (err)
+		goto err2;
+	err = request_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N),
+			palmld_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"SD/MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+				__func__);
+		goto err2;
+	}
+
+	err = gpio_request(GPIO_NR_PALMLD_SD_POWER, "SD_POWER");
+	if (err)
+		goto err3;
+	err = gpio_direction_output(GPIO_NR_PALMLD_SD_POWER, 0);
+	if (err)
+		goto err4;
+
+	err = gpio_request(GPIO_NR_PALMLD_SD_READONLY, "SD_READONLY");
+	if (err)
+		goto err4;
+	err = gpio_direction_input(GPIO_NR_PALMLD_SD_READONLY);
+	if (err)
+		goto err5;
+
+	printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+	return 0;
+
+err5:
+	gpio_free(GPIO_NR_PALMLD_SD_READONLY);
+err4:
+	gpio_free(GPIO_NR_PALMLD_SD_POWER);
+err3:
+	free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
+err2:
+	gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
+err:
+	return err;
+}
+
+static void palmld_mci_exit(struct device *dev, void *data)
+{
+	gpio_free(GPIO_NR_PALMLD_SD_READONLY);
+	gpio_free(GPIO_NR_PALMLD_SD_POWER);
+	free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
+	gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
+}
+
+static void palmld_mci_power(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+	gpio_set_value(GPIO_NR_PALMLD_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmld_mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_NR_PALMLD_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmld_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.setpower	= palmld_mci_power,
+	.get_ro		= palmld_mci_get_ro,
+	.init 		= palmld_mci_init,
+	.exit		= palmld_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmld_matrix_keys[] = {
+	KEY(0, 1, KEY_F2),
+	KEY(0, 2, KEY_UP),
+
+	KEY(1, 0, KEY_F3),
+	KEY(1, 1, KEY_F4),
+	KEY(1, 2, KEY_RIGHT),
+
+	KEY(2, 0, KEY_F1),
+	KEY(2, 1, KEY_F5),
+	KEY(2, 2, KEY_DOWN),
+
+	KEY(3, 0, KEY_F6),
+	KEY(3, 1, KEY_ENTER),
+	KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
+	.matrix_key_rows	= 4,
+	.matrix_key_cols	= 3,
+	.matrix_key_map		= palmld_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(palmld_matrix_keys),
+
+	.debounce_interval	= 30,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmld_pxa_buttons[] = {
+	{KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+	{KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
+	{KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
+};
+
+static struct gpio_keys_platform_data palmld_pxa_keys_data = {
+	.buttons	= palmld_pxa_buttons,
+	.nbuttons	= ARRAY_SIZE(palmld_pxa_buttons),
+};
+
+static struct platform_device palmld_pxa_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &palmld_pxa_keys_data,
+	},
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmld_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMLD_BL_POWER, "BL POWER");
+	if (ret)
+		goto err;
+	ret = gpio_direction_output(GPIO_NR_PALMLD_BL_POWER, 0);
+	if (ret)
+		goto err2;
+	ret = gpio_request(GPIO_NR_PALMLD_LCD_POWER, "LCD POWER");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_output(GPIO_NR_PALMLD_LCD_POWER, 0);
+	if (ret)
+		goto err3;
+
+	return 0;
+err3:
+	gpio_free(GPIO_NR_PALMLD_LCD_POWER);
+err2:
+	gpio_free(GPIO_NR_PALMLD_BL_POWER);
+err:
+	return ret;
+}
+
+static int palmld_backlight_notify(int brightness)
+{
+	gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness);
+	gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness);
+	return brightness;
+}
+
+static void palmld_backlight_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMLD_BL_POWER);
+	gpio_free(GPIO_NR_PALMLD_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmld_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= PALMLD_MAX_INTENSITY,
+	.dft_brightness	= PALMLD_MAX_INTENSITY,
+	.pwm_period_ns	= PALMLD_PERIOD_NS,
+	.init		= palmld_backlight_init,
+	.notify		= palmld_backlight_notify,
+	.exit		= palmld_backlight_exit,
+};
+
+static struct platform_device palmld_backlight = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &palmld_backlight_data,
+	},
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmld_irda_startup(struct device *dev)
+{
+	int err;
+	err = gpio_request(GPIO_NR_PALMLD_IR_DISABLE, "IR DISABLE");
+	if (err)
+		goto err;
+	err = gpio_direction_output(GPIO_NR_PALMLD_IR_DISABLE, 1);
+	if (err)
+		gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
+err:
+	return err;
+}
+
+static void palmld_irda_shutdown(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
+}
+
+static void palmld_irda_transceiver_mode(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_NR_PALMLD_IR_DISABLE, mode & IR_OFF);
+	pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmld_ficp_platform_data = {
+	.startup		= palmld_irda_startup,
+	.shutdown		= palmld_irda_shutdown,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode	= palmld_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+struct gpio_led gpio_leds[] = {
+{
+	.name			= "palmld:green:led",
+	.default_trigger	= "none",
+	.gpio			= GPIO_NR_PALMLD_LED_GREEN,
+}, {
+	.name			= "palmld:amber:led",
+	.default_trigger	= "none",
+	.gpio			= GPIO_NR_PALMLD_LED_AMBER,
+},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds		= gpio_leds,
+	.num_leds	= ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device palmld_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_led_info,
+	}
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMLD_POWER_DETECT, "CABLE_STATE_AC");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_input(GPIO_NR_PALMLD_POWER_DETECT);
+	if (ret)
+		goto err2;
+
+	ret = gpio_request(GPIO_NR_PALMLD_USB_DETECT_N, "CABLE_STATE_USB");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_input(GPIO_NR_PALMLD_USB_DETECT_N);
+	if (ret)
+		goto err3;
+
+	return 0;
+
+err3:
+	gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
+err2:
+	gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
+err1:
+	return ret;
+}
+
+static int palmld_is_ac_online(void)
+{
+	return gpio_get_value(GPIO_NR_PALMLD_POWER_DETECT);
+}
+
+static int palmld_is_usb_online(void)
+{
+	return !gpio_get_value(GPIO_NR_PALMLD_USB_DETECT_N);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
+	gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
+}
+
+static char *palmld_supplicants[] = {
+	"main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+	.init            = power_supply_init,
+	.is_ac_online    = palmld_is_ac_online,
+	.is_usb_online   = palmld_is_usb_online,
+	.exit            = power_supply_exit,
+	.supplied_to     = palmld_supplicants,
+	.num_supplicants = ARRAY_SIZE(palmld_supplicants),
+};
+
+static struct platform_device power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+	.batt_aux	= WM97XX_AUX_ID3,
+	.temp_aux	= WM97XX_AUX_ID2,
+	.charge_gpio	= -1,
+	.max_voltage	= PALMLD_BAT_MAX_VOLTAGE,
+	.min_voltage	= PALMLD_BAT_MIN_VOLTAGE,
+	.batt_mult	= 1000,
+	.batt_div	= 414,
+	.temp_mult	= 1,
+	.temp_div	= 1,
+	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.batt_name	= "main-batt",
+};
+
+/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palmld_asoc_pdata = {
+	.jack_gpio	= GPIO_NR_PALMLD_EARPHONE_DETECT,
+};
+
+static pxa2xx_audio_ops_t palmld_ac97_pdata = {
+	.reset_gpio	= 95,
+};
+
+static struct platform_device palmld_asoc = {
+	.name = "palm27x-asoc",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &palmld_asoc_pdata,
+	},
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmld_lcd_modes[] = {
+{
+	.pixclock	= 57692,
+	.xres		= 320,
+	.yres		= 480,
+	.bpp		= 16,
+
+	.left_margin	= 32,
+	.right_margin	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 1,
+
+	.hsync_len	= 4,
+	.vsync_len	= 1,
+},
+};
+
+static struct pxafb_mach_info palmld_lcd_screen = {
+	.modes		= palmld_lcd_modes,
+	.num_modes	= ARRAY_SIZE(palmld_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+	0xe3a00101,	/* mov	r0,	#0x40000000 */
+	0xe380060f,	/* orr	r0, r0, #0x00f00000 */
+	0xe590f008,	/* ldr	pc, [r0, #0x08] */
+};
+
+static int __init palmld_pm_init(void)
+{
+	int i;
+
+	/* this is where the bootloader jumps */
+	addr = phys_to_virt(PALMLD_STR_BASE);
+
+	for (i = 0; i < 3; i++)
+		addr[i] = resume[i];
+
+	return 0;
+}
+
+device_initcall(palmld_pm_init);
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+	&palmld_pxa_keys,
+#endif
+	&palmld_backlight,
+	&palmld_leds,
+	&power_supply,
+	&palmld_asoc,
+};
+
+static struct map_desc palmld_io_desc[] __initdata = {
+{
+	.virtual	= PALMLD_IDE_VIRT,
+	.pfn		= __phys_to_pfn(PALMLD_IDE_PHYS),
+	.length		= PALMLD_IDE_SIZE,
+	.type		= MT_DEVICE
+},
+{
+	.virtual	= PALMLD_USB_VIRT,
+	.pfn		= __phys_to_pfn(PALMLD_USB_PHYS),
+	.length		= PALMLD_USB_SIZE,
+	.type		= MT_DEVICE
+},
+};
+
+static void __init palmld_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
+}
+
+static void __init palmld_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
+
+	set_pxa_fb_info(&palmld_lcd_screen);
+	pxa_set_mci_info(&palmld_mci_platform_data);
+	pxa_set_ac97_info(&palmld_ac97_pdata);
+	pxa_set_ficp_info(&palmld_ficp_platform_data);
+	pxa_set_keypad_info(&palmld_keypad_platform_data);
+	wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMLD, "Palm LifeDrive")
+	.phys_io	= PALMLD_PHYS_IO_START,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= palmld_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= palmld_init
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmt5.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmt5.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmt5.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmt5.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,537 @@
+/*
+ * Hardware definitions for Palm Tungsten|T5
+ *
+ * Author:	Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ *		Ales Snuparek <snuparek@atlas.cz>
+ *		Justin Kendrick <twilightsentry@gmail.com>
+ *		RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (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 <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmt5.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmt5_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,
+	GPIO14_GPIO,	/* SD detect */
+	GPIO114_GPIO,	/* SD power */
+	GPIO115_GPIO,	/* SD r/o switch */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+	GPIO89_AC97_SYSCLK,
+	GPIO95_AC97_nRESET,
+
+	/* IrDA */
+	GPIO40_GPIO,	/* ir disable */
+	GPIO46_FICP_RXD,
+	GPIO47_FICP_TXD,
+
+	/* USB */
+	GPIO15_GPIO,	/* usb detect */
+	GPIO93_GPIO,	/* usb power */
+
+	/* MATRIX KEYPAD */
+	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO103_KP_MKOUT_0,
+	GPIO104_KP_MKOUT_1,
+	GPIO105_KP_MKOUT_2,
+
+	/* 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,
+	GPIO77_LCD_BIAS,
+
+	/* PWM */
+	GPIO16_PWM0_OUT,
+
+	/* MISC */
+	GPIO10_GPIO,	/* hotsync button */
+	GPIO90_GPIO,	/* power detect */
+	GPIO107_GPIO,	/* earphone detect */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmt5_mci_init(struct device *dev, irq_handler_t palmt5_detect_int,
+				void *data)
+{
+	int err = 0;
+
+	/* Setup an interrupt for detecting card insert/remove events */
+	err = gpio_request(GPIO_NR_PALMT5_SD_DETECT_N, "SD IRQ");
+	if (err)
+		goto err;
+	err = gpio_direction_input(GPIO_NR_PALMT5_SD_DETECT_N);
+	if (err)
+		goto err2;
+	err = request_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N),
+			palmt5_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"SD/MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+				__func__);
+		goto err2;
+	}
+
+	err = gpio_request(GPIO_NR_PALMT5_SD_POWER, "SD_POWER");
+	if (err)
+		goto err3;
+	err = gpio_direction_output(GPIO_NR_PALMT5_SD_POWER, 0);
+	if (err)
+		goto err4;
+
+	err = gpio_request(GPIO_NR_PALMT5_SD_READONLY, "SD_READONLY");
+	if (err)
+		goto err4;
+	err = gpio_direction_input(GPIO_NR_PALMT5_SD_READONLY);
+	if (err)
+		goto err5;
+
+	printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+	return 0;
+
+err5:
+	gpio_free(GPIO_NR_PALMT5_SD_READONLY);
+err4:
+	gpio_free(GPIO_NR_PALMT5_SD_POWER);
+err3:
+	free_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N), data);
+err2:
+	gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
+err:
+	return err;
+}
+
+static void palmt5_mci_exit(struct device *dev, void *data)
+{
+	gpio_free(GPIO_NR_PALMT5_SD_READONLY);
+	gpio_free(GPIO_NR_PALMT5_SD_POWER);
+	free_irq(IRQ_GPIO_PALMT5_SD_DETECT_N, data);
+	gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
+}
+
+static void palmt5_mci_power(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+	gpio_set_value(GPIO_NR_PALMT5_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmt5_mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_NR_PALMT5_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmt5_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.setpower	= palmt5_mci_power,
+	.get_ro		= palmt5_mci_get_ro,
+	.init 		= palmt5_mci_init,
+	.exit		= palmt5_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmt5_matrix_keys[] = {
+	KEY(0, 0, KEY_POWER),
+	KEY(0, 1, KEY_F1),
+	KEY(0, 2, KEY_ENTER),
+
+	KEY(1, 0, KEY_F2),
+	KEY(1, 1, KEY_F3),
+	KEY(1, 2, KEY_F4),
+
+	KEY(2, 0, KEY_UP),
+	KEY(2, 2, KEY_DOWN),
+
+	KEY(3, 0, KEY_RIGHT),
+	KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
+	.matrix_key_rows	= 4,
+	.matrix_key_cols	= 3,
+	.matrix_key_map		= palmt5_matrix_keys,
+	.matrix_key_map_size	= ARRAY_SIZE(palmt5_matrix_keys),
+
+	.debounce_interval	= 30,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmt5_pxa_buttons[] = {
+	{KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+};
+
+static struct gpio_keys_platform_data palmt5_pxa_keys_data = {
+	.buttons	= palmt5_pxa_buttons,
+	.nbuttons	= ARRAY_SIZE(palmt5_pxa_buttons),
+};
+
+static struct platform_device palmt5_pxa_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &palmt5_pxa_keys_data,
+	},
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmt5_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMT5_BL_POWER, "BL POWER");
+	if (ret)
+		goto err;
+	ret = gpio_direction_output(GPIO_NR_PALMT5_BL_POWER, 0);
+	if (ret)
+		goto err2;
+	ret = gpio_request(GPIO_NR_PALMT5_LCD_POWER, "LCD POWER");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_output(GPIO_NR_PALMT5_LCD_POWER, 0);
+	if (ret)
+		goto err3;
+
+	return 0;
+err3:
+	gpio_free(GPIO_NR_PALMT5_LCD_POWER);
+err2:
+	gpio_free(GPIO_NR_PALMT5_BL_POWER);
+err:
+	return ret;
+}
+
+static int palmt5_backlight_notify(int brightness)
+{
+	gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness);
+	gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness);
+	return brightness;
+}
+
+static void palmt5_backlight_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMT5_BL_POWER);
+	gpio_free(GPIO_NR_PALMT5_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmt5_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= PALMT5_MAX_INTENSITY,
+	.dft_brightness	= PALMT5_MAX_INTENSITY,
+	.pwm_period_ns	= PALMT5_PERIOD_NS,
+	.init		= palmt5_backlight_init,
+	.notify		= palmt5_backlight_notify,
+	.exit		= palmt5_backlight_exit,
+};
+
+static struct platform_device palmt5_backlight = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &palmt5_backlight_data,
+	},
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmt5_irda_startup(struct device *dev)
+{
+	int err;
+	err = gpio_request(GPIO_NR_PALMT5_IR_DISABLE, "IR DISABLE");
+	if (err)
+		goto err;
+	err = gpio_direction_output(GPIO_NR_PALMT5_IR_DISABLE, 1);
+	if (err)
+		gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
+err:
+	return err;
+}
+
+static void palmt5_irda_shutdown(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
+}
+
+static void palmt5_irda_transceiver_mode(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_NR_PALMT5_IR_DISABLE, mode & IR_OFF);
+	pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmt5_ficp_platform_data = {
+	.startup		= palmt5_irda_startup,
+	.shutdown		= palmt5_irda_shutdown,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode	= palmt5_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct pxa2xx_udc_mach_info palmt5_udc_info __initdata = {
+	.gpio_vbus		= GPIO_NR_PALMT5_USB_DETECT_N,
+	.gpio_vbus_inverted	= 1,
+	.gpio_pullup		= GPIO_NR_PALMT5_USB_PULLUP,
+	.gpio_pullup_inverted	= 0,
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMT5_POWER_DETECT, "CABLE_STATE_AC");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_input(GPIO_NR_PALMT5_POWER_DETECT);
+	if (ret)
+		goto err2;
+
+	return 0;
+err2:
+	gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
+err1:
+	return ret;
+}
+
+static int palmt5_is_ac_online(void)
+{
+	return gpio_get_value(GPIO_NR_PALMT5_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
+}
+
+static char *palmt5_supplicants[] = {
+	"main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+	.init            = power_supply_init,
+	.is_ac_online    = palmt5_is_ac_online,
+	.exit            = power_supply_exit,
+	.supplied_to     = palmt5_supplicants,
+	.num_supplicants = ARRAY_SIZE(palmt5_supplicants),
+};
+
+static struct platform_device power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+	.batt_aux	= WM97XX_AUX_ID3,
+	.temp_aux	= WM97XX_AUX_ID2,
+	.charge_gpio	= -1,
+	.max_voltage	= PALMT5_BAT_MAX_VOLTAGE,
+	.min_voltage	= PALMT5_BAT_MIN_VOLTAGE,
+	.batt_mult	= 1000,
+	.batt_div	= 414,
+	.temp_mult	= 1,
+	.temp_div	= 1,
+	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.batt_name	= "main-batt",
+};
+
+/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palmt5_asoc_pdata = {
+	.jack_gpio	= GPIO_NR_PALMT5_EARPHONE_DETECT,
+};
+
+static pxa2xx_audio_ops_t palmt5_ac97_pdata = {
+	.reset_gpio	= 95,
+};
+
+static struct platform_device palmt5_asoc = {
+	.name = "palm27x-asoc",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &palmt5_asoc_pdata,
+	},
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmt5_lcd_modes[] = {
+{
+	.pixclock	= 57692,
+	.xres		= 320,
+	.yres		= 480,
+	.bpp		= 16,
+
+	.left_margin	= 32,
+	.right_margin	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 1,
+
+	.hsync_len	= 4,
+	.vsync_len	= 1,
+},
+};
+
+static struct pxafb_mach_info palmt5_lcd_screen = {
+	.modes		= palmt5_lcd_modes,
+	.num_modes	= ARRAY_SIZE(palmt5_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+	0xe3a00101,	/* mov	r0,	#0x40000000 */
+	0xe380060f,	/* orr	r0, r0, #0x00f00000 */
+	0xe590f008,	/* ldr	pc, [r0, #0x08] */
+};
+
+static int __init palmt5_pm_init(void)
+{
+	int i;
+
+	/* this is where the bootloader jumps */
+	addr = phys_to_virt(PALMT5_STR_BASE);
+
+	for (i = 0; i < 3; i++)
+		addr[i] = resume[i];
+
+	return 0;
+}
+
+device_initcall(palmt5_pm_init);
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+	&palmt5_pxa_keys,
+#endif
+	&palmt5_backlight,
+	&power_supply,
+	&palmt5_asoc,
+};
+
+/* setup udc GPIOs initial state */
+static void __init palmt5_udc_init(void)
+{
+	if (!gpio_request(GPIO_NR_PALMT5_USB_PULLUP, "UDC Vbus")) {
+		gpio_direction_output(GPIO_NR_PALMT5_USB_PULLUP, 1);
+		gpio_free(GPIO_NR_PALMT5_USB_PULLUP);
+	}
+}
+
+static void __init palmt5_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
+
+	set_pxa_fb_info(&palmt5_lcd_screen);
+	pxa_set_mci_info(&palmt5_mci_platform_data);
+	palmt5_udc_init();
+	pxa_set_ac97_info(&palmt5_ac97_pdata);
+	pxa_set_udc_info(&palmt5_udc_info);
+	pxa_set_ficp_info(&palmt5_ficp_platform_data);
+	pxa_set_keypad_info(&palmt5_keypad_platform_data);
+	wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMT5, "Palm Tungsten|T5")
+	.phys_io	= PALMT5_PHYS_IO_START,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa27x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= palmt5_init
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmte2.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmte2.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmte2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmte2.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,466 @@
+/*
+ * Hardware definitions for Palm Tungsten|E2
+ *
+ * Author:
+ *	Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
+ *
+ * Rewrite for mainline:
+ *	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.
+ *
+ * (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 <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/audio.h>
+#include <mach/palmte2.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/irda.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmte2_pin_config[] __initdata = {
+	/* MMC */
+	GPIO6_MMC_CLK,
+	GPIO8_MMC_CS0,
+	GPIO10_GPIO,	/* SD detect */
+	GPIO55_GPIO,	/* SD power */
+	GPIO51_GPIO,	/* SD r/o switch */
+
+	/* AC97 */
+	GPIO28_AC97_BITCLK,
+	GPIO29_AC97_SDATA_IN_0,
+	GPIO30_AC97_SDATA_OUT,
+	GPIO31_AC97_SYNC,
+
+	/* PWM */
+	GPIO16_PWM0_OUT,
+
+	/* USB */
+	GPIO15_GPIO,	/* usb detect */
+	GPIO53_GPIO,	/* usb power */
+
+	/* IrDA */
+	GPIO48_GPIO,	/* ir disable */
+	GPIO46_FICP_RXD,
+	GPIO47_FICP_TXD,
+
+	/* 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,
+	GPIO77_LCD_BIAS,
+
+	/* GPIO KEYS */
+	GPIO5_GPIO,	/* notes */
+	GPIO7_GPIO,	/* tasks */
+	GPIO11_GPIO,	/* calendar */
+	GPIO13_GPIO,	/* contacts */
+	GPIO14_GPIO,	/* center */
+	GPIO19_GPIO,	/* left */
+	GPIO20_GPIO,	/* right */
+	GPIO21_GPIO,	/* down */
+	GPIO22_GPIO,	/* up */
+
+	/* MISC */
+	GPIO1_RST,	/* reset */
+	GPIO4_GPIO,	/* Hotsync button */
+	GPIO9_GPIO,	/* power detect */
+	GPIO37_GPIO,	/* LCD power */
+	GPIO56_GPIO,	/* Backlight power */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmte2_mci_init(struct device *dev,
+				irq_handler_t palmte2_detect_int, void *data)
+{
+	int err = 0;
+
+	/* Setup an interrupt for detecting card insert/remove events */
+	err = gpio_request(GPIO_NR_PALMTE2_SD_DETECT_N, "SD IRQ");
+	if (err)
+		goto err;
+	err = gpio_direction_input(GPIO_NR_PALMTE2_SD_DETECT_N);
+	if (err)
+		goto err2;
+	err = request_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N),
+			palmte2_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"SD/MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+				__func__);
+		goto err2;
+	}
+
+	err = gpio_request(GPIO_NR_PALMTE2_SD_POWER, "SD_POWER");
+	if (err)
+		goto err3;
+	err = gpio_direction_output(GPIO_NR_PALMTE2_SD_POWER, 0);
+	if (err)
+		goto err4;
+
+	err = gpio_request(GPIO_NR_PALMTE2_SD_READONLY, "SD_READONLY");
+	if (err)
+		goto err4;
+	err = gpio_direction_input(GPIO_NR_PALMTE2_SD_READONLY);
+	if (err)
+		goto err5;
+
+	printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+	return 0;
+
+err5:
+	gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
+err4:
+	gpio_free(GPIO_NR_PALMTE2_SD_POWER);
+err3:
+	free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
+err2:
+	gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
+err:
+	return err;
+}
+
+static void palmte2_mci_exit(struct device *dev, void *data)
+{
+	gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
+	gpio_free(GPIO_NR_PALMTE2_SD_POWER);
+	free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
+	gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
+}
+
+static void palmte2_mci_power(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data *p_d = dev->platform_data;
+	gpio_set_value(GPIO_NR_PALMTE2_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmte2_mci_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_NR_PALMTE2_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmte2_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.setpower	= palmte2_mci_power,
+	.get_ro		= palmte2_mci_get_ro,
+	.init 		= palmte2_mci_init,
+	.exit		= palmte2_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmte2_pxa_buttons[] = {
+	{KEY_F1,	GPIO_NR_PALMTE2_KEY_CONTACTS,	1, "Contacts" },
+	{KEY_F2,	GPIO_NR_PALMTE2_KEY_CALENDAR,	1, "Calendar" },
+	{KEY_F3,	GPIO_NR_PALMTE2_KEY_TASKS,	1, "Tasks" },
+	{KEY_F4,	GPIO_NR_PALMTE2_KEY_NOTES,	1, "Notes" },
+	{KEY_ENTER,	GPIO_NR_PALMTE2_KEY_CENTER,	1, "Center" },
+	{KEY_LEFT,	GPIO_NR_PALMTE2_KEY_LEFT,	1, "Left" },
+	{KEY_RIGHT,	GPIO_NR_PALMTE2_KEY_RIGHT,	1, "Right" },
+	{KEY_DOWN,	GPIO_NR_PALMTE2_KEY_DOWN,	1, "Down" },
+	{KEY_UP,	GPIO_NR_PALMTE2_KEY_UP,		1, "Up" },
+};
+
+static struct gpio_keys_platform_data palmte2_pxa_keys_data = {
+	.buttons	= palmte2_pxa_buttons,
+	.nbuttons	= ARRAY_SIZE(palmte2_pxa_buttons),
+};
+
+static struct platform_device palmte2_pxa_keys = {
+	.name	= "gpio-keys",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &palmte2_pxa_keys_data,
+	},
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmte2_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER");
+	if (ret)
+		goto err;
+	ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0);
+	if (ret)
+		goto err2;
+	ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER");
+	if (ret)
+		goto err2;
+	ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0);
+	if (ret)
+		goto err3;
+
+	return 0;
+err3:
+	gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+err2:
+	gpio_free(GPIO_NR_PALMTE2_BL_POWER);
+err:
+	return ret;
+}
+
+static int palmte2_backlight_notify(int brightness)
+{
+	gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness);
+	gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness);
+	return brightness;
+}
+
+static void palmte2_backlight_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMTE2_BL_POWER);
+	gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmte2_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= PALMTE2_MAX_INTENSITY,
+	.dft_brightness	= PALMTE2_MAX_INTENSITY,
+	.pwm_period_ns	= PALMTE2_PERIOD_NS,
+	.init		= palmte2_backlight_init,
+	.notify		= palmte2_backlight_notify,
+	.exit		= palmte2_backlight_exit,
+};
+
+static struct platform_device palmte2_backlight = {
+	.name	= "pwm-backlight",
+	.dev	= {
+		.parent		= &pxa25x_device_pwm0.dev,
+		.platform_data	= &palmte2_backlight_data,
+	},
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmte2_irda_startup(struct device *dev)
+{
+	int err;
+	err = gpio_request(GPIO_NR_PALMTE2_IR_DISABLE, "IR DISABLE");
+	if (err)
+		goto err;
+	err = gpio_direction_output(GPIO_NR_PALMTE2_IR_DISABLE, 1);
+	if (err)
+		gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
+err:
+	return err;
+}
+
+static void palmte2_irda_shutdown(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
+}
+
+static void palmte2_irda_transceiver_mode(struct device *dev, int mode)
+{
+	gpio_set_value(GPIO_NR_PALMTE2_IR_DISABLE, mode & IR_OFF);
+	pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmte2_ficp_platform_data = {
+	.startup		= palmte2_irda_startup,
+	.shutdown		= palmte2_irda_shutdown,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode	= palmte2_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct pxa2xx_udc_mach_info palmte2_udc_info __initdata = {
+	.gpio_vbus		= GPIO_NR_PALMTE2_USB_DETECT_N,
+	.gpio_vbus_inverted	= 1,
+	.gpio_pullup		= GPIO_NR_PALMTE2_USB_PULLUP,
+	.gpio_pullup_inverted	= 0,
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC");
+	if (ret)
+		goto err1;
+	ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT);
+	if (ret)
+		goto err2;
+
+	return 0;
+
+err2:
+	gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+err1:
+	return ret;
+}
+
+static int palmte2_is_ac_online(void)
+{
+	return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+	gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static char *palmte2_supplicants[] = {
+	"main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+	.init            = power_supply_init,
+	.is_ac_online    = palmte2_is_ac_online,
+	.exit            = power_supply_exit,
+	.supplied_to     = palmte2_supplicants,
+	.num_supplicants = ARRAY_SIZE(palmte2_supplicants),
+};
+
+static struct platform_device power_supply = {
+	.name = "pda-power",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &power_supply_info,
+	},
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+	.batt_aux	= WM97XX_AUX_ID3,
+	.temp_aux	= WM97XX_AUX_ID2,
+	.charge_gpio	= -1,
+	.max_voltage	= PALMTE2_BAT_MAX_VOLTAGE,
+	.min_voltage	= PALMTE2_BAT_MIN_VOLTAGE,
+	.batt_mult	= 1000,
+	.batt_div	= 414,
+	.temp_mult	= 1,
+	.temp_div	= 1,
+	.batt_tech	= POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.batt_name	= "main-batt",
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmte2_lcd_modes[] = {
+{
+	.pixclock	= 77757,
+	.xres		= 320,
+	.yres		= 320,
+	.bpp		= 16,
+
+	.left_margin	= 28,
+	.right_margin	= 7,
+	.upper_margin	= 7,
+	.lower_margin	= 5,
+
+	.hsync_len	= 4,
+	.vsync_len	= 1,
+},
+};
+
+static struct pxafb_mach_info palmte2_lcd_screen = {
+	.modes		= palmte2_lcd_modes,
+	.num_modes	= ARRAY_SIZE(palmte2_lcd_modes),
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+	&palmte2_pxa_keys,
+#endif
+	&palmte2_backlight,
+	&power_supply,
+};
+
+/* setup udc GPIOs initial state */
+static void __init palmte2_udc_init(void)
+{
+	if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) {
+		gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1);
+		gpio_free(GPIO_NR_PALMTE2_USB_PULLUP);
+	}
+}
+
+static void __init palmte2_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));
+
+	set_pxa_fb_info(&palmte2_lcd_screen);
+	pxa_set_mci_info(&palmte2_mci_platform_data);
+	palmte2_udc_init();
+	pxa_set_udc_info(&palmte2_udc_info);
+	pxa_set_ac97_info(NULL);
+	pxa_set_ficp_info(&palmte2_ficp_platform_data);
+	wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMTE2, "Palm Tungsten|E2")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= palmte2_init
+MACHINE_END
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmtx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmtx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmtx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmtx.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,15 +32,15 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <mach/pxa27x.h>
 #include <mach/audio.h>
 #include <mach/palmtx.h>
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
 #include <mach/irda.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/udc.h>
+#include <mach/palmasoc.h>
 
 #include "generic.h"
 #include "devices.h"
@@ -65,6 +65,8 @@ static unsigned long palmtx_pin_config[]
 	GPIO29_AC97_SDATA_IN_0,
 	GPIO30_AC97_SDATA_OUT,
 	GPIO31_AC97_SYNC,
+	GPIO89_AC97_SYSCLK,
+	GPIO95_AC97_nRESET,
 
 	/* IrDA */
 	GPIO40_GPIO,	/* ir disable */
@@ -76,7 +78,7 @@ static unsigned long palmtx_pin_config[]
 
 	/* USB */
 	GPIO13_GPIO,	/* usb detect */
-	GPIO95_GPIO,	/* usb power */
+	GPIO93_GPIO,	/* usb power */
 
 	/* PCMCIA */
 	GPIO48_nPOE,
@@ -94,10 +96,10 @@ static unsigned long palmtx_pin_config[]
 	GPIO116_GPIO,	/* wifi ready */
 
 	/* MATRIX KEYPAD */
-	GPIO100_KP_MKIN_0,
-	GPIO101_KP_MKIN_1,
-	GPIO102_KP_MKIN_2,
-	GPIO97_KP_MKIN_3,
+	GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+	GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
 	GPIO103_KP_MKOUT_0,
 	GPIO104_KP_MKOUT_1,
 	GPIO105_KP_MKOUT_2,
@@ -360,7 +362,7 @@ static struct pxaficp_platform_data palm
 static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
 	.gpio_vbus		= GPIO_NR_PALMTX_USB_DETECT_N,
 	.gpio_vbus_inverted	= 1,
-	.gpio_pullup		= GPIO_NR_PALMTX_USB_POWER,
+	.gpio_pullup		= GPIO_NR_PALMTX_USB_PULLUP,
 	.gpio_pullup_inverted	= 0,
 };
 
@@ -434,6 +436,25 @@ static struct wm97xx_batt_info wm97xx_ba
 };
 
 /******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palmtx_asoc_pdata = {
+	.jack_gpio	= GPIO_NR_PALMTX_EARPHONE_DETECT,
+};
+
+static pxa2xx_audio_ops_t palmtx_ac97_pdata = {
+	.reset_gpio	= 95,
+};
+
+static struct platform_device palmtx_asoc = {
+	.name = "palm27x-asoc",
+	.id   = -1,
+	.dev  = {
+		.platform_data = &palmtx_asoc_pdata,
+	},
+};
+
+/******************************************************************************
  * Framebuffer
  ******************************************************************************/
 static struct pxafb_mode_info palmtx_lcd_modes[] = {
@@ -460,6 +481,33 @@ static struct pxafb_mach_info palmtx_lcd
 };
 
 /******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#ifdef CONFIG_PM
+static u32 *addr __initdata;
+static u32 resume[3] __initdata = {
+	0xe3a00101,	/* mov	r0,	#0x40000000 */
+	0xe380060f,	/* orr	r0, r0, #0x00f00000 */
+	0xe590f008,	/* ldr	pc, [r0, #0x08] */
+};
+
+static int __init palmtx_pm_init(void)
+{
+	int i;
+
+	/* this is where the bootloader jumps */
+	addr = phys_to_virt(PALMTX_STR_BASE);
+
+	for (i = 0; i < 3; i++)
+		addr[i] = resume[i];
+
+	return 0;
+}
+
+device_initcall(palmtx_pm_init);
+#endif
+
+/******************************************************************************
  * Machine init
  ******************************************************************************/
 static struct platform_device *devices[] __initdata = {
@@ -468,6 +516,7 @@ static struct platform_device *devices[]
 #endif
 	&palmtx_backlight,
 	&power_supply,
+	&palmtx_asoc,
 };
 
 static struct map_desc palmtx_io_desc[] __initdata = {
@@ -488,9 +537,9 @@ static void __init palmtx_map_io(void)
 /* setup udc GPIOs initial state */
 static void __init palmtx_udc_init(void)
 {
-	if (!gpio_request(GPIO_NR_PALMTX_USB_POWER, "UDC Vbus")) {
-		gpio_direction_output(GPIO_NR_PALMTX_USB_POWER, 1);
-		gpio_free(GPIO_NR_PALMTX_USB_POWER);
+	if (!gpio_request(GPIO_NR_PALMTX_USB_PULLUP, "UDC Vbus")) {
+		gpio_direction_output(GPIO_NR_PALMTX_USB_PULLUP, 1);
+		gpio_free(GPIO_NR_PALMTX_USB_PULLUP);
 	}
 }
 
@@ -502,8 +551,8 @@ static void __init palmtx_init(void)
 	set_pxa_fb_info(&palmtx_lcd_screen);
 	pxa_set_mci_info(&palmtx_mci_platform_data);
 	palmtx_udc_init();
+	pxa_set_ac97_info(&palmtx_ac97_pdata);
 	pxa_set_udc_info(&palmtx_udc_info);
-	pxa_set_ac97_info(NULL);
 	pxa_set_ficp_info(&palmtx_ficp_platform_data);
 	pxa_set_keypad_info(&palmtx_keypad_platform_data);
 	wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmz72.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmz72.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/palmz72.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/palmz72.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,13 +33,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
+#include <mach/pxa27x.h>
 #include <mach/audio.h>
 #include <mach/palmz72.h>
 #include <mach/mmc.h>
 #include <mach/pxafb.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
 #include <mach/irda.h>
 #include <mach/pxa27x_keypad.h>
 #include <mach/udc.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pcm027.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pcm027.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pcm027.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pcm027.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,10 +29,7 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa2xx-regs.h>
+#include <mach/pxa27x.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/pcm027.h>
 #include "generic.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pcm990-baseboard.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,13 +31,12 @@
 #include <mach/i2c.h>
 #include <mach/camera.h>
 #include <asm/mach/map.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
 #include <mach/audio.h>
 #include <mach/mmc.h>
 #include <mach/ohci.h>
 #include <mach/pcm990_baseboard.h>
 #include <mach/pxafb.h>
-#include <mach/mfp-pxa27x.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -378,17 +377,52 @@ struct pxacamera_platform_data pcm990_px
 #include <linux/i2c/pca953x.h>
 
 static struct pca953x_platform_data pca9536_data = {
-	.gpio_base	= NR_BUILTIN_GPIO + 1,
+	.gpio_base	= NR_BUILTIN_GPIO,
 };
 
-static struct soc_camera_link iclink[] = {
-	{
-		.bus_id	= 0, /* Must match with the camera ID above */
-		.gpio	= NR_BUILTIN_GPIO + 1,
-	}, {
-		.bus_id	= 0, /* Must match with the camera ID above */
-		.gpio	= -ENXIO,
+static int gpio_bus_switch;
+
+static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
+		unsigned long flags)
+{
+	if (gpio_bus_switch <= 0) {
+		if (flags == SOCAM_DATAWIDTH_10)
+			return 0;
+		else
+			return -EINVAL;
+	}
+
+	if (flags & SOCAM_DATAWIDTH_8)
+		gpio_set_value(gpio_bus_switch, 1);
+	else
+		gpio_set_value(gpio_bus_switch, 0);
+
+	return 0;
+}
+
+static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
+{
+	int ret;
+
+	if (!gpio_bus_switch) {
+		ret = gpio_request(NR_BUILTIN_GPIO, "camera");
+		if (!ret) {
+			gpio_bus_switch = NR_BUILTIN_GPIO;
+			gpio_direction_output(gpio_bus_switch, 0);
+		} else
+			gpio_bus_switch = -EINVAL;
 	}
+
+	if (gpio_bus_switch > 0)
+		return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
+	else
+		return SOCAM_DATAWIDTH_10;
+}
+
+static struct soc_camera_link iclink = {
+	.bus_id	= 0, /* Must match with the camera ID above */
+	.query_bus_param = pcm990_camera_query_bus_param,
+	.set_bus_param = pcm990_camera_set_bus_param,
 };
 
 /* Board I2C devices. */
@@ -399,10 +433,10 @@ static struct i2c_board_info __initdata
 		.platform_data = &pca9536_data,
 	}, {
 		I2C_BOARD_INFO("mt9v022", 0x48),
-		.platform_data = &iclink[0], /* With extender */
+		.platform_data = &iclink, /* With extender */
 	}, {
 		I2C_BOARD_INFO("mt9m001", 0x5d),
-		.platform_data = &iclink[0], /* With extender */
+		.platform_data = &iclink, /* With extender */
 	},
 };
 #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,15 +14,8 @@
 #include <linux/module.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
-#include <linux/time.h>
 
-#include <mach/hardware.h>
-#include <asm/memory.h>
-#include <asm/system.h>
 #include <mach/pm.h>
-#include <mach/pxa-regs.h>
-#include <mach/lubbock.h>
-#include <asm/mach/time.h>
 
 struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
 static unsigned long *sleep_save;
@@ -57,9 +50,9 @@ int pxa_pm_enter(suspend_state_t state)
 
 		/* if invalid, display message and wait for a hardware reset */
 		if (checksum != sleep_save_checksum) {
-#ifdef CONFIG_ARCH_LUBBOCK
-			LUB_HEXLED = 0xbadbadc5;
-#endif
+
+			lubbock_set_hexled(0xbadbadc5);
+
 			while (1)
 				pxa_cpu_pm_fns->enter(state);
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/poodle.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/poodle.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/poodle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/poodle.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,9 +36,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
 #include <mach/i2c.h>
@@ -503,12 +501,12 @@ static struct platform_device *devices[]
 
 static void poodle_poweroff(void)
 {
-	arm_machine_restart('h');
+	arm_machine_restart('h', NULL);
 }
 
-static void poodle_restart(char mode)
+static void poodle_restart(char mode, const char *cmd)
 {
-	arm_machine_restart('h');
+	arm_machine_restart('h', cmd);
 }
 
 static void __init poodle_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pwm.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pwm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pwm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pwm.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/pwm.h>
 
 #include <asm/div64.h>
-#include <mach/pxa-regs.h>
 
 /* PWM registers and bits definitions */
 #define PWMCR		(0x00)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa25x.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa25x.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa25x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa25x.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,9 +25,8 @@
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/gpio.h>
+#include <mach/pxa25x.h>
 #include <mach/reset.h>
 #include <mach/pm.h>
 #include <mach/dma.h>
@@ -310,14 +309,14 @@ set_pwer:
 void __init pxa25x_init_irq(void)
 {
 	pxa_init_irq(32, pxa25x_set_wake);
-	pxa_init_gpio(85, pxa25x_set_wake);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 84, pxa25x_set_wake);
 }
 
 #ifdef CONFIG_CPU_PXA26x
 void __init pxa26x_init_irq(void)
 {
 	pxa_init_irq(32, pxa25x_set_wake);
-	pxa_init_gpio(90, pxa25x_set_wake);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 89, pxa25x_set_wake);
 }
 #endif
 
@@ -355,7 +354,7 @@ static int __init pxa25x_init(void)
 
 		clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
 
-		if ((ret = pxa_init_dma(16)))
+		if ((ret = pxa_init_dma(IRQ_DMA, 16)))
 			return ret;
 
 		pxa25x_init_pm();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa27x.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa27x.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa27x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa27x.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,9 +21,8 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <mach/irqs.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/gpio.h>
+#include <mach/pxa27x.h>
 #include <mach/reset.h>
 #include <mach/ohci.h>
 #include <mach/pm.h>
@@ -332,7 +331,7 @@ static int pxa27x_set_wake(unsigned int
 void __init pxa27x_init_irq(void)
 {
 	pxa_init_irq(34, pxa27x_set_wake);
-	pxa_init_gpio(121, pxa27x_set_wake);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake);
 }
 
 /*
@@ -381,7 +380,7 @@ static int __init pxa27x_init(void)
 
 		clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
 
-		if ((ret = pxa_init_dma(32)))
+		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
 
 		pxa27x_init_pm();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa2xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa2xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa2xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa2xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,6 @@
 
 #include <mach/hardware.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa2xx.h>
 #include <mach/mfp-pxa25x.h>
 #include <mach/reset.h>
 #include <mach/irda.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa300.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa300.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa300.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa300.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,15 +17,13 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
 
 #include "generic.h"
 #include "devices.h"
 #include "clock.h"
 
-static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
 
 	MFP_ADDR_X(GPIO0,   GPIO2,   0x00b4),
 	MFP_ADDR_X(GPIO3,   GPIO26,  0x027c),
@@ -74,7 +72,7 @@ static struct pxa3xx_mfp_addr_map pxa300
 };
 
 /* override pxa300 MFP register addresses */
-static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
 	MFP_ADDR_X(GPIO30,  GPIO98,   0x0418),
 	MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
 
@@ -100,13 +98,13 @@ static struct clk_lookup pxa310_clkregs[
 static int __init pxa300_init(void)
 {
 	if (cpu_is_pxa300() || cpu_is_pxa310()) {
-		pxa3xx_init_mfp();
-		pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
+		mfp_init_base(io_p2v(MFPR_BASE));
+		mfp_init_addr(pxa300_mfp_addr_map);
 		clks_register(ARRAY_AND_SIZE(common_clkregs));
 	}
 
 	if (cpu_is_pxa310()) {
-		pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
+		mfp_init_addr(pxa310_mfp_addr_map);
 		clks_register(ARRAY_AND_SIZE(pxa310_clkregs));
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa320.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa320.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa320.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa320.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,16 +17,13 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
-#include <mach/mfp.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa320.h>
+#include <mach/pxa320.h>
 
 #include "generic.h"
 #include "devices.h"
 #include "clock.h"
 
-static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
 
 	MFP_ADDR_X(GPIO0,  GPIO4,   0x0124),
 	MFP_ADDR_X(GPIO5,  GPIO9,   0x028C),
@@ -89,8 +86,8 @@ static struct clk_lookup pxa320_clkregs[
 static int __init pxa320_init(void)
 {
 	if (cpu_is_pxa320()) {
-		pxa3xx_init_mfp();
-		pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
+		mfp_init_base(io_p2v(MFPR_BASE));
+		mfp_init_addr(pxa320_mfp_addr_map);
 		clks_register(ARRAY_AND_SIZE(pxa320_clkregs));
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa3xx.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa3xx.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa3xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/sysdev.h>
 
 #include <mach/hardware.h>
+#include <mach/gpio.h>
 #include <mach/pxa3xx-regs.h>
 #include <mach/reset.h>
 #include <mach/ohci.h>
@@ -538,7 +539,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_gpio(128, NULL);
+	pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
 }
 
 /*
@@ -594,7 +595,7 @@ static int __init pxa3xx_init(void)
 
 		clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
 
-		if ((ret = pxa_init_dma(32)))
+		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
 
 		pxa3xx_init_pm();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa930.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa930.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/pxa930.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/pxa930.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,10 +16,9 @@
 #include <linux/irq.h>
 #include <linux/dma-mapping.h>
 
-#include <mach/hardware.h>
-#include <mach/mfp-pxa930.h>
+#include <mach/pxa930.h>
 
-static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
 
 	MFP_ADDR(GPIO0, 0x02e0),
 	MFP_ADDR(GPIO1, 0x02dc),
@@ -180,8 +179,8 @@ static struct pxa3xx_mfp_addr_map pxa930
 static int __init pxa930_init(void)
 {
 	if (cpu_is_pxa930()) {
-		pxa3xx_init_mfp();
-		pxa3xx_mfp_init_addr(pxa930_mfp_addr_map);
+		mfp_init_base(io_p2v(MFPR_BASE));
+		mfp_init_addr(pxa930_mfp_addr_map);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/reset.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/reset.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/reset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/reset.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@
 #include <linux/io.h>
 #include <asm/proc-fns.h>
 
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
 #include <mach/reset.h>
 
 unsigned int reset_status;
@@ -20,7 +20,7 @@ static void do_hw_reset(void);
 
 static int reset_gpio = -1;
 
-int init_gpio_reset(int gpio, int output)
+int init_gpio_reset(int gpio, int output, int level)
 {
 	int rc;
 
@@ -31,7 +31,7 @@ int init_gpio_reset(int gpio, int output
 	}
 
 	if (output)
-		rc = gpio_direction_output(gpio, 0);
+		rc = gpio_direction_output(gpio, level);
 	else
 		rc = gpio_direction_input(gpio);
 	if (rc) {
@@ -81,7 +81,7 @@ static void do_hw_reset(void)
 	OSMR3 = OSCR + 368640;	/* ... in 100 ms */
 }
 
-void arch_reset(char mode)
+void arch_reset(char mode, const char *cmd)
 {
 	clear_reset_status(RESET_STATUS_ALL);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/saar.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/saar.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/saar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/saar.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,11 +25,9 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa930.h>
+
+#include <mach/pxa930.h>
 #include <mach/i2c.h>
-#include <mach/regs-lcd.h>
 #include <mach/pxafb.h>
 
 #include "devices.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/sharpsl_pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/sharpsl_pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/sharpsl_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,6 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <mach/pm.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 #include <mach/sharpsl.h>
 #include "sharpsl.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/sleep.S linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/sleep.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/sleep.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/sleep.S	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@
 #include <asm/assembler.h>
 #include <mach/hardware.h>
 
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 
 #define MDREFR_KDIV	0x200a4000	// all banks
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/spitz.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/spitz.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/spitz.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/spitz.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,9 +44,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
 #include <mach/pxa27x-udc.h>
 #include <mach/reset.h>
 #include <mach/i2c.h>
@@ -105,6 +103,12 @@ static unsigned long spitz_pin_config[]
 	GPIO57_nIOIS16,
 	GPIO104_PSKTSEL,
 
+	/* I2S */
+	GPIO28_I2S_BITCLK_OUT,
+	GPIO29_I2S_SDATA_IN,
+	GPIO30_I2S_SDATA_OUT,
+	GPIO31_I2S_SYNC,
+
 	/* MMC */
 	GPIO32_MMC_CLK,
 	GPIO112_MMC_CMD,
@@ -295,12 +299,22 @@ static struct pxa2xx_spi_master spitz_sp
 	.num_chipselect	= 3,
 };
 
+static void spitz_wait_for_hsync(void)
+{
+	while (gpio_get_value(SPITZ_GPIO_HSYNC))
+		cpu_relax();
+
+	while (!gpio_get_value(SPITZ_GPIO_HSYNC))
+		cpu_relax();
+}
+
 static struct ads7846_platform_data spitz_ads7846_info = {
 	.model			= 7846,
 	.vref_delay_usecs	= 100,
 	.x_plate_ohms		= 419,
 	.y_plate_ohms		= 486,
 	.gpio_pendown		= SPITZ_GPIO_TP_INT,
+	.wait_for_sync		= spitz_wait_for_hsync,
 };
 
 static void spitz_ads7846_cs(u32 command)
@@ -517,9 +531,15 @@ static int spitz_ohci_init(struct device
 	return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
 }
 
+static void spitz_ohci_exit(struct device *dev)
+{
+	gpio_free(SPITZ_GPIO_USB_HOST);
+}
+
 static struct pxaohci_platform_data spitz_ohci_platform_data = {
 	.port_mode	= PMM_NPS_MODE,
 	.init		= spitz_ohci_init,
+	.exit		= spitz_ohci_exit,
 	.flags		= ENABLE_PORT_ALL | NO_OC_PROTECTION,
 	.power_budget	= 150,
 };
@@ -703,10 +723,10 @@ static struct platform_device *devices[]
 
 static void spitz_poweroff(void)
 {
-	arm_machine_restart('g');
+	arm_machine_restart('g', NULL);
 }
 
-static void spitz_restart(char mode)
+static void spitz_restart(char mode, const char *cmd)
 {
 	/* Bootloader magic for a reboot */
 	if((MSC0 & 0xffff0000) == 0x7ff00000)
@@ -717,7 +737,7 @@ static void spitz_restart(char mode)
 
 static void __init common_init(void)
 {
-	init_gpio_reset(SPITZ_GPIO_ON_RESET, 1);
+	init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
 	pm_power_off = spitz_poweroff;
 	arm_pm_restart = spitz_restart;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/spitz_pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/spitz_pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/spitz_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/spitz_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,6 @@
 
 #include <mach/sharpsl.h>
 #include <mach/spitz.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 #include <mach/pxa2xx-gpio.h>
 #include "sharpsl.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/ssp.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/ssp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/ssp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/ssp.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,6 @@
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <mach/ssp.h>
-#include <mach/pxa-regs.h>
 #include <mach/regs-ssp.h>
 
 #define TIMEOUT 100000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/standby.S linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/standby.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/standby.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/standby.S	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@
 #include <asm/assembler.h>
 #include <mach/hardware.h>
 
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 
 		.text
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/tavorevb.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/tavorevb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/tavorevb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/tavorevb.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,9 +22,8 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa930.h>
+
+#include <mach/pxa930.h>
 #include <mach/pxafb.h>
 #include <mach/pxa27x_keypad.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/time.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,8 +22,7 @@
 #include <asm/div64.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
 
 /*
  * This is PXA's sched_clock implementation. This has a resolution
@@ -126,7 +125,7 @@ static struct clock_event_device ckevt_p
 	.set_mode	= pxa_osmr0_set_mode,
 };
 
-static cycle_t pxa_read_oscr(void)
+static cycle_t pxa_read_oscr(struct clocksource *cs)
 {
 	return OSCR;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/tosa.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/tosa.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/tosa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/tosa.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,8 +36,8 @@
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+
+#include <mach/pxa25x.h>
 #include <mach/reset.h>
 #include <mach/irda.h>
 #include <mach/i2c.h>
@@ -45,6 +45,7 @@
 #include <mach/udc.h>
 #include <mach/tosa_bt.h>
 #include <mach/pxa2xx_spi.h>
+#include <mach/audio.h>
 
 #include <asm/mach/arch.h>
 #include <mach/tosa.h>
@@ -876,10 +877,10 @@ static struct platform_device *devices[]
 
 static void tosa_poweroff(void)
 {
-	arm_machine_restart('g');
+	arm_machine_restart('g', NULL);
 }
 
-static void tosa_restart(char mode)
+static void tosa_restart(char mode, const char *cmd)
 {
 	/* Bootloader magic for a reboot */
 	if((MSC0 & 0xffff0000) == 0x7ff00000)
@@ -896,7 +897,7 @@ static void __init tosa_init(void)
 	gpio_set_wake(MFP_PIN_GPIO1, 1);
 	/* We can't pass to gpio-keys since it will drop the Reset altfunc */
 
-	init_gpio_reset(TOSA_GPIO_ON_RESET, 0);
+	init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);
 
 	pm_power_off = tosa_poweroff;
 	arm_pm_restart = tosa_restart;
@@ -914,12 +915,13 @@ static void __init tosa_init(void)
 	pxa_set_udc_info(&udc_info);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
+	pxa_set_ac97_info(NULL);
 	platform_scoop_config = &tosa_pcmcia_config;
 
 	pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 
-	clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
+	clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/trizeps4.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/trizeps4.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/trizeps4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/trizeps4.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,10 +39,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/trizeps4.h>
 #include <mach/audio.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/viper.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/viper.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/viper.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/viper.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,13 +42,11 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/bitfield.h>
+#include <mach/pxa25x.h>
 #include <mach/audio.h>
 #include <mach/pxafb.h>
-#include <mach/mfp-pxa25x.h>
 #include <mach/i2c.h>
+#include <mach/regs-uart.h>
 #include <mach/viper.h>
 
 #include <asm/setup.h>
@@ -956,7 +954,7 @@ static struct map_desc viper_io_desc[] _
 	},
 	{
 		.virtual = VIPER_PC104IO_BASE,
-		.pfn     = __phys_to_pfn(_PCMCIA1IO),
+		.pfn     = __phys_to_pfn(0x30000000),
 		.length  = 0x00800000,
 		.type    = MT_DEVICE,
 	},
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/zylonite_pxa300.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,9 +18,9 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
+#include <linux/gpio.h>
 
-#include <asm/gpio.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
 #include <mach/i2c.h>
 #include <mach/zylonite.h>
 
@@ -72,6 +72,7 @@ static mfp_cfg_t common_mfp_cfg[] __init
 	GPIO25_AC97_SDATA_IN_0,
 	GPIO27_AC97_SDATA_OUT,
 	GPIO28_AC97_SYNC,
+	GPIO17_GPIO,	/* SDATA_IN_1 but unused - configure to GPIO */
 
 	/* SSP3 */
 	GPIO91_SSP3_SCLK,
@@ -126,6 +127,10 @@ static mfp_cfg_t common_mfp_cfg[] __init
 	/* Standard I2C */
 	GPIO21_I2C_SCL,
 	GPIO22_I2C_SDA,
+
+	/* GPIO */
+	GPIO18_GPIO,	/* GPIO Expander #0 INT_N */
+	GPIO19_GPIO,	/* GPIO Expander #1 INT_N */
 };
 
 static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-pxa/zylonite_pxa320.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 
-#include <mach/mfp-pxa320.h>
+#include <mach/pxa320.h>
 #include <mach/zylonite.h>
 
 #include "generic.h"
@@ -68,6 +68,7 @@ static mfp_cfg_t mfp_cfg[] __initdata =
 	GPIO38_AC97_SYNC,
 	GPIO39_AC97_BITCLK,
 	GPIO40_AC97_nACRESET,
+	GPIO36_GPIO,	/* SDATA_IN_1 but unused - configure to GPIO */
 
 	/* SSP3 */
 	GPIO89_SSP3_SCLK,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/core.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/core.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,8 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
+#include <linux/ata_platform.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
@@ -127,14 +128,15 @@ int realview_flash_register(struct resou
 	return platform_device_register(&realview_flash_device);
 }
 
-static struct smc911x_platdata realview_smc911x_platdata = {
-	.flags		= SMC911X_USE_32BIT,
-	.irq_flags	= IRQF_SHARED,
-	.irq_polarity	= 1,
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags		= SMSC911X_USE_32BIT,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
 };
 
 static struct platform_device realview_eth_device = {
-	.name		= "smc911x",
+	.name		= "smsc911x",
 	.id		= 0,
 	.num_resources	= 2,
 };
@@ -144,12 +146,50 @@ int realview_eth_register(const char *na
 	if (name)
 		realview_eth_device.name = name;
 	realview_eth_device.resource = res;
-	if (strcmp(realview_eth_device.name, "smc911x") == 0)
-		realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
+	if (strcmp(realview_eth_device.name, "smsc911x") == 0)
+		realview_eth_device.dev.platform_data = &smsc911x_config;
 
 	return platform_device_register(&realview_eth_device);
 }
 
+struct platform_device realview_usb_device = {
+	.name			= "isp1760",
+	.num_resources		= 2,
+};
+
+int realview_usb_register(struct resource *res)
+{
+	realview_usb_device.resource = res;
+	return platform_device_register(&realview_usb_device);
+}
+
+static struct pata_platform_info pata_platform_data = {
+	.ioport_shift		= 1,
+};
+
+static struct resource pata_resources[] = {
+	[0] = {
+		.start		= REALVIEW_CF_BASE,
+		.end		= REALVIEW_CF_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= REALVIEW_CF_BASE + 0x100,
+		.end		= REALVIEW_CF_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device realview_cf_device = {
+	.name			= "pata_platform",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(pata_resources),
+	.resource		= pata_resources,
+	.dev			= {
+		.platform_data	= &pata_platform_data,
+	},
+};
+
 static struct resource realview_i2c_resource = {
 	.start		= REALVIEW_I2C_BASE,
 	.end		= REALVIEW_I2C_BASE + SZ_4K - 1,
@@ -158,11 +198,25 @@ static struct resource realview_i2c_reso
 
 struct platform_device realview_i2c_device = {
 	.name		= "versatile-i2c",
-	.id		= -1,
+	.id		= 0,
 	.num_resources	= 1,
 	.resource	= &realview_i2c_resource,
 };
 
+static struct i2c_board_info realview_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1),
+		.type = "ds1338",
+	},
+};
+
+static int __init realview_i2c_init(void)
+{
+	return i2c_register_board_info(0, realview_i2c_board_info,
+				       ARRAY_SIZE(realview_i2c_board_info));
+}
+arch_initcall(realview_i2c_init);
+
 #define REALVIEW_SYSMCI	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
 
 static unsigned int realview_mmc_status(struct device *dev)
@@ -661,7 +715,7 @@ static struct irqaction realview_timer_i
 	.handler	= realview_timer_interrupt,
 };
 
-static cycle_t realview_get_cycles(void)
+static cycle_t realview_get_cycles(struct clocksource *cs)
 {
 	return ~readl(timer3_va_base + TIMER_VALUE);
 }
@@ -696,14 +750,6 @@ void __init realview_timer_init(unsigned
 {
 	u32 val;
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-	/*
-	 * The dummy clock device has to be registered before the main device
-	 * so that the latter will broadcast the clock events
-	 */
-	local_timer_setup();
-#endif
-
 	/* 
 	 * set clock frequency: 
 	 *	REALVIEW_REFCLK is 32KHz
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/core.h linux-libre-2.6.30-gnu1/arch/arm/mach-realview/core.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/core.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,6 +45,7 @@ static struct amba_device name##_device
 }
 
 extern struct platform_device realview_flash_device;
+extern struct platform_device realview_cf_device;
 extern struct platform_device realview_i2c_device;
 extern struct mmc_platform_data realview_mmc0_plat_data;
 extern struct mmc_platform_data realview_mmc1_plat_data;
@@ -62,5 +63,6 @@ extern void realview_leds_event(led_even
 extern void realview_timer_init(unsigned int timer_irq);
 extern int realview_flash_register(struct resource *res, u32 num);
 extern int realview_eth_register(const char *name, struct resource *res);
+extern int realview_usb_register(struct resource *res);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/board-pba8.h linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/board-pba8.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/board-pba8.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/board-pba8.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,8 +45,6 @@
 #define REALVIEW_PBA8_DMC_BASE			0x100E0000	/* DMC configuration */
 #define REALVIEW_PBA8_SMC_BASE			0x100E1000	/* SMC configuration */
 #define REALVIEW_PBA8_CAN_BASE			0x100E2000	/* CAN bus */
-#define REALVIEW_PBA8_CF_BASE			0x18000000	/* Compact flash */
-#define REALVIEW_PBA8_CF_MEM_BASE		0x18003000	/* SMC for Compact flash */
 #define REALVIEW_PBA8_GIC_CPU_BASE		0x1E000000	/* Generic interrupt controller CPU interface */
 #define REALVIEW_PBA8_FLASH0_BASE		0x40000000
 #define REALVIEW_PBA8_FLASH0_SIZE		SZ_64M
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/platform.h linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/platform.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/platform.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/platform.h	2009-06-09 23:05:27.000000000 -0400
@@ -204,6 +204,12 @@
 #define REALVIEW_LT_BASE              0x80000000	/* Logic Tile expansion */
 
 /*
+ * CompactFlash
+ */
+#define REALVIEW_CF_BASE		0x18000000	/* CompactFlash */
+#define REALVIEW_CF_MEM_BASE		0x18003000	/* SMC for CompactFlash */
+
+/*
  * Disk on Chip
  */
 #define REALVIEW_DOC_BASE             0x2C000000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/smp.h linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/smp.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,16 +15,9 @@
 /*
  * We use IRQ1 as the IPI
  */
-static inline void smp_cross_call(cpumask_t callmap)
-{
-	gic_raise_softirq(callmap, 1);
-}
-
-/*
- * Do nothing on MPcore.
- */
-static inline void smp_cross_call_done(cpumask_t callmap)
+static inline void smp_cross_call(const struct cpumask *mask)
 {
+	gic_raise_softirq(mask, 1);
 }
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET;
 	unsigned int val;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-realview/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,7 @@ config MACH_REALVIEW_PB11MP
 	bool "Support RealView/PB11MPCore platform"
 	select CPU_V6
 	select ARM_GIC
+	select HAVE_PATA_PLATFORM
 	help
 	  Include support for the ARM(R) RealView MPCore Platform Baseboard.
 	  PB11MPCore is a platform with an on-board ARM11MPCore and has
@@ -51,6 +52,7 @@ config MACH_REALVIEW_PBA8
 	bool "Support RealView/PB-A8 platform"
 	select CPU_V7
 	select ARM_GIC
+	select HAVE_PATA_PLATFORM
 	help
 	  Include support for the ARM(R) RealView Cortex-A8 Platform Baseboard.
 	  PB-A8 is a platform with an on-board Cortex-A8 and has support for
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/localtimer.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/localtimer.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/localtimer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/localtimer.c	2009-06-09 23:05:27.000000000 -0400
@@ -189,8 +189,11 @@ void __cpuinit local_timer_setup(void)
 	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
 
 	clk->name		= "dummy_timer";
-	clk->features		= CLOCK_EVT_FEAT_DUMMY;
-	clk->rating		= 200;
+	clk->features		= CLOCK_EVT_FEAT_ONESHOT |
+				  CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_DUMMY;
+	clk->rating		= 400;
+	clk->mult               = 1;
 	clk->set_mode		= dummy_timer_set_mode;
 	clk->broadcast		= smp_timer_broadcast;
 	clk->cpumask		= cpumask_of(cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/platsmp.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/platsmp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/platsmp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/platsmp.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,13 +78,6 @@ void __cpuinit platform_secondary_init(u
 	trace_hardirqs_off();
 
 	/*
-	 * the primary core may have used a "cross call" soft interrupt
-	 * to get this processor out of WFI in the BootMonitor - make
-	 * sure that we are no longer being sent this soft interrupt
-	 */
-	smp_cross_call_done(cpumask_of_cpu(cpu));
-
-	/*
 	 * 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
@@ -136,7 +129,7 @@ int __cpuinit boot_secondary(unsigned in
 	 * Use smp_cross_call() for this, since there's little
 	 * point duplicating the code here
 	 */
-	smp_cross_call(cpumask_of_cpu(cpu));
+	smp_cross_call(cpumask_of(cpu));
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -224,11 +217,9 @@ void __init smp_prepare_cpus(unsigned in
 	if (max_cpus > ncores)
 		max_cpus = ncores;
 
-#ifdef CONFIG_LOCAL_TIMERS
+#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
 	/*
-	 * Enable the local timer for primary CPU. If the device is
-	 * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in
-	 * realview_timer_init
+	 * Enable the local timer or broadcast device for the boot CPU.
 	 */
 	local_timer_setup();
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_eb.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_eb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_eb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_eb.c	2009-06-09 23:05:27.000000000 -0400
@@ -264,6 +264,19 @@ static int eth_device_register(void)
 	return realview_eth_register(name, realview_eb_eth_resources);
 }
 
+static struct resource realview_eb_isp1761_resources[] = {
+	[0] = {
+		.start		= REALVIEW_EB_USB_BASE,
+		.end		= REALVIEW_EB_USB_BASE + SZ_128K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_EB_USB,
+		.end		= IRQ_EB_USB,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
 static void __init gic_init_irq(void)
 {
 	if (core_tile_eb11mp() || core_tile_a9mp()) {
@@ -323,6 +336,8 @@ static void realview_eb11mp_fixup(void)
 	/* platform devices */
 	realview_eb_eth_resources[1].start	= IRQ_EB11MP_ETH;
 	realview_eb_eth_resources[1].end	= IRQ_EB11MP_ETH;
+	realview_eb_isp1761_resources[1].start	= IRQ_EB11MP_USB;
+	realview_eb_isp1761_resources[1].end	= IRQ_EB11MP_USB;
 }
 
 static void __init realview_eb_timer_init(void)
@@ -366,6 +381,7 @@ static void __init realview_eb_init(void
 	realview_flash_register(&realview_eb_flash_resource, 1);
 	platform_device_register(&realview_i2c_device);
 	eth_device_register();
+	realview_usb_register(realview_eb_isp1761_resources);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pb1176.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pb1176.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pb1176.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pb1176.c	2009-06-09 23:05:27.000000000 -0400
@@ -222,6 +222,19 @@ static struct resource realview_pb1176_s
 	},
 };
 
+static struct resource realview_pb1176_isp1761_resources[] = {
+	[0] = {
+		.start		= REALVIEW_PB1176_USB_BASE,
+		.end		= REALVIEW_PB1176_USB_BASE + SZ_128K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_PB1176_USB,
+		.end		= IRQ_PB1176_USB,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
 static void __init gic_init_irq(void)
 {
 	/* ARM1176 DevChip GIC, primary */
@@ -260,6 +273,8 @@ static void __init realview_pb1176_init(
 
 	realview_flash_register(&realview_pb1176_flash_resource, 1);
 	realview_eth_register(NULL, realview_pb1176_smsc911x_resources);
+	platform_device_register(&realview_i2c_device);
+	realview_usb_register(realview_pb1176_isp1761_resources);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pb11mp.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pb11mp.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pb11mp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pb11mp.c	2009-06-09 23:05:27.000000000 -0400
@@ -230,31 +230,19 @@ static struct resource realview_pb11mp_s
 	},
 };
 
-struct resource realview_pb11mp_cf_resources[] = {
+static struct resource realview_pb11mp_isp1761_resources[] = {
 	[0] = {
-		.start		= REALVIEW_PB11MP_CF_BASE,
-		.end		= REALVIEW_PB11MP_CF_BASE + SZ_4K - 1,
+		.start		= REALVIEW_PB11MP_USB_BASE,
+		.end		= REALVIEW_PB11MP_USB_BASE + SZ_128K - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= REALVIEW_PB11MP_CF_MEM_BASE,
-		.end		= REALVIEW_PB11MP_CF_MEM_BASE + SZ_4K - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start		= -1,		/* FIXME: Find correct irq */
-		.end		= -1,
+		.start		= IRQ_TC11MP_USB,
+		.end		= IRQ_TC11MP_USB,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
 
-struct platform_device realview_pb11mp_cf_device = {
-	.name		= "compactflash",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(realview_pb11mp_cf_resources),
-	.resource	= realview_pb11mp_cf_resources,
-};
-
 static void __init gic_init_irq(void)
 {
 	unsigned int pldctrl;
@@ -308,7 +296,8 @@ static void __init realview_pb11mp_init(
 				ARRAY_SIZE(realview_pb11mp_flash_resource));
 	realview_eth_register(NULL, realview_pb11mp_smsc911x_resources);
 	platform_device_register(&realview_i2c_device);
-	platform_device_register(&realview_pb11mp_cf_device);
+	platform_device_register(&realview_cf_device);
+	realview_usb_register(realview_pb11mp_isp1761_resources);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pba8.c linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pba8.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-realview/realview_pba8.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-realview/realview_pba8.c	2009-06-09 23:05:27.000000000 -0400
@@ -221,31 +221,19 @@ static struct resource realview_pba8_sms
 	},
 };
 
-struct resource realview_pba8_cf_resources[] = {
+static struct resource realview_pba8_isp1761_resources[] = {
 	[0] = {
-		.start		= REALVIEW_PBA8_CF_BASE,
-		.end		= REALVIEW_PBA8_CF_BASE + SZ_4K - 1,
+		.start		= REALVIEW_PBA8_USB_BASE,
+		.end		= REALVIEW_PBA8_USB_BASE + SZ_128K - 1,
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= REALVIEW_PBA8_CF_MEM_BASE,
-		.end		= REALVIEW_PBA8_CF_MEM_BASE + SZ_4K - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start		= -1,		/* FIXME: Find correct irq */
-		.end		= -1,
+		.start		= IRQ_PBA8_USB,
+		.end		= IRQ_PBA8_USB,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
 
-struct platform_device realview_pba8_cf_device = {
-	.name		= "compactflash",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(realview_pba8_cf_resources),
-	.resource	= realview_pba8_cf_resources,
-};
-
 static void __init gic_init_irq(void)
 {
 	/* ARM PB-A8 on-board GIC */
@@ -276,7 +264,8 @@ static void __init realview_pba8_init(vo
 				ARRAY_SIZE(realview_pba8_flash_resource));
 	realview_eth_register(NULL, realview_pba8_smsc911x_resources);
 	platform_device_register(&realview_i2c_device);
-	platform_device_register(&realview_pba8_cf_device);
+	platform_device_register(&realview_cf_device);
+	realview_usb_register(realview_pba8_isp1761_resources);
 
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,16 @@
 #include <asm/mach/dma.h>
 #include <asm/hardware/iomd.h>
 
+struct iomd_dma {
+	struct dma_struct	dma;
+	unsigned int		state;
+	unsigned long		base;		/* Controller base address */
+	int			irq;		/* Controller IRQ */
+	struct scatterlist	cur_sg;		/* Current controller buffer */
+	dma_addr_t		dma_addr;
+	unsigned int		dma_len;
+};
+
 #if 0
 typedef enum {
 	dma_size_8	= 1,
@@ -44,15 +54,15 @@ typedef enum {
 #define CR	(IOMD_IO0CR - IOMD_IO0CURA)
 #define ST	(IOMD_IO0ST - IOMD_IO0CURA)
 
-static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
+static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma)
 {
 	unsigned long end, offset, flags = 0;
 
-	if (dma->sg) {
-		sg->dma_address = dma->sg->dma_address;
+	if (idma->dma.sg) {
+		sg->dma_address = idma->dma_addr;
 		offset = sg->dma_address & ~PAGE_MASK;
 
-		end = offset + dma->sg->length;
+		end = offset + idma->dma_len;
 
 		if (end > PAGE_SIZE)
 			end = PAGE_SIZE;
@@ -62,15 +72,17 @@ static void iomd_get_next_sg(struct scat
 
 		sg->length = end - TRANSFER_SIZE;
 
-		dma->sg->length -= end - offset;
-		dma->sg->dma_address += end - offset;
+		idma->dma_len -= end - offset;
+		idma->dma_addr += end - offset;
 
-		if (dma->sg->length == 0) {
-			if (dma->sgcount > 1) {
-				dma->sg++;
-				dma->sgcount--;
+		if (idma->dma_len == 0) {
+			if (idma->dma.sgcount > 1) {
+				idma->dma.sg = sg_next(idma->dma.sg);
+				idma->dma_addr = idma->dma.sg->dma_address;
+				idma->dma_len = idma->dma.sg->length;
+				idma->dma.sgcount--;
 			} else {
-				dma->sg = NULL;
+				idma->dma.sg = NULL;
 				flags |= DMA_END_S;
 			}
 		}
@@ -85,8 +97,8 @@ static void iomd_get_next_sg(struct scat
 
 static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
 {
-	dma_t *dma = (dma_t *)dev_id;
-	unsigned long base = dma->dma_base;
+	struct iomd_dma *idma = dev_id;
+	unsigned long base = idma->base;
 
 	do {
 		unsigned int status;
@@ -95,93 +107,99 @@ static irqreturn_t iomd_dma_handle(int i
 		if (!(status & DMA_ST_INT))
 			return IRQ_HANDLED;
 
-		if ((dma->state ^ status) & DMA_ST_AB)
-			iomd_get_next_sg(&dma->cur_sg, dma);
+		if ((idma->state ^ status) & DMA_ST_AB)
+			iomd_get_next_sg(&idma->cur_sg, idma);
 
 		switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
 		case DMA_ST_OFL:			/* OIA */
 		case DMA_ST_AB:				/* .IB */
-			iomd_writel(dma->cur_sg.dma_address, base + CURA);
-			iomd_writel(dma->cur_sg.length, base + ENDA);
-			dma->state = DMA_ST_AB;
+			iomd_writel(idma->cur_sg.dma_address, base + CURA);
+			iomd_writel(idma->cur_sg.length, base + ENDA);
+			idma->state = DMA_ST_AB;
 			break;
 
 		case DMA_ST_OFL | DMA_ST_AB:		/* OIB */
 		case 0:					/* .IA */
-			iomd_writel(dma->cur_sg.dma_address, base + CURB);
-			iomd_writel(dma->cur_sg.length, base + ENDB);
-			dma->state = 0;
+			iomd_writel(idma->cur_sg.dma_address, base + CURB);
+			iomd_writel(idma->cur_sg.length, base + ENDB);
+			idma->state = 0;
 			break;
 		}
 
 		if (status & DMA_ST_OFL &&
-		    dma->cur_sg.length == (DMA_END_S|DMA_END_L))
+		    idma->cur_sg.length == (DMA_END_S|DMA_END_L))
 			break;
 	} while (1);
 
-	dma->state = ~DMA_ST_AB;
+	idma->state = ~DMA_ST_AB;
 	disable_irq(irq);
 
 	return IRQ_HANDLED;
 }
 
-static int iomd_request_dma(dmach_t channel, dma_t *dma)
+static int iomd_request_dma(unsigned int chan, dma_t *dma)
 {
-	return request_irq(dma->dma_irq, iomd_dma_handle,
-			   IRQF_DISABLED, dma->device_id, dma);
+	struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+	return request_irq(idma->irq, iomd_dma_handle,
+			   IRQF_DISABLED, idma->dma.device_id, idma);
 }
 
-static void iomd_free_dma(dmach_t channel, dma_t *dma)
+static void iomd_free_dma(unsigned int chan, dma_t *dma)
 {
-	free_irq(dma->dma_irq, dma);
+	struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+	free_irq(idma->irq, idma);
 }
 
-static void iomd_enable_dma(dmach_t channel, dma_t *dma)
+static void iomd_enable_dma(unsigned int chan, dma_t *dma)
 {
-	unsigned long dma_base = dma->dma_base;
+	struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+	unsigned long dma_base = idma->base;
 	unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
 
-	if (dma->invalid) {
-		dma->invalid = 0;
+	if (idma->dma.invalid) {
+		idma->dma.invalid = 0;
 
 		/*
 		 * Cope with ISA-style drivers which expect cache
 		 * coherence.
 		 */
-		if (!dma->sg) {
-			dma->sg = &dma->buf;
-			dma->sgcount = 1;
-			dma->buf.length = dma->count;
-			dma->buf.dma_address = dma_map_single(NULL,
-				dma->addr, dma->count,
-				dma->dma_mode == DMA_MODE_READ ?
+		if (!idma->dma.sg) {
+			idma->dma.sg = &idma->dma.buf;
+			idma->dma.sgcount = 1;
+			idma->dma.buf.length = idma->dma.count;
+			idma->dma.buf.dma_address = dma_map_single(NULL,
+				idma->dma.addr, idma->dma.count,
+				idma->dma.dma_mode == DMA_MODE_READ ?
 				DMA_FROM_DEVICE : DMA_TO_DEVICE);
 		}
 
 		iomd_writeb(DMA_CR_C, dma_base + CR);
-		dma->state = DMA_ST_AB;
+		idma->state = DMA_ST_AB;
 	}
-		
-	if (dma->dma_mode == DMA_MODE_READ)
+
+	if (idma->dma.dma_mode == DMA_MODE_READ)
 		ctrl |= DMA_CR_D;
 
 	iomd_writeb(ctrl, dma_base + CR);
-	enable_irq(dma->dma_irq);
+	enable_irq(idma->irq);
 }
 
-static void iomd_disable_dma(dmach_t channel, dma_t *dma)
+static void iomd_disable_dma(unsigned int chan, dma_t *dma)
 {
-	unsigned long dma_base = dma->dma_base;
+	struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+	unsigned long dma_base = idma->base;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if (dma->state != ~DMA_ST_AB)
-		disable_irq(dma->dma_irq);
+	if (idma->state != ~DMA_ST_AB)
+		disable_irq(idma->irq);
 	iomd_writeb(0, dma_base + CR);
 	local_irq_restore(flags);
 }
 
-static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
+static int iomd_set_dma_speed(unsigned int chan, dma_t *dma, int cycle)
 {
 	int tcr, speed;
 
@@ -197,7 +215,7 @@ static int iomd_set_dma_speed(dmach_t ch
 	tcr = iomd_readb(IOMD_DMATCR);
 	speed &= 3;
 
-	switch (channel) {
+	switch (chan) {
 	case DMA_0:
 		tcr = (tcr & ~0x03) | speed;
 		break;
@@ -236,16 +254,22 @@ static struct fiq_handler fh = {
 	.name	= "floppydma"
 };
 
-static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+struct floppy_dma {
+	struct dma_struct	dma;
+	unsigned int		fiq;
+};
+
+static void floppy_enable_dma(unsigned int chan, dma_t *dma)
 {
+	struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
 	void *fiqhandler_start;
 	unsigned int fiqhandler_length;
 	struct pt_regs regs;
 
-	if (dma->sg)
+	if (fdma->dma.sg)
 		BUG();
 
-	if (dma->dma_mode == DMA_MODE_READ) {
+	if (fdma->dma.dma_mode == DMA_MODE_READ) {
 		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
 		fiqhandler_start = &floppy_fiqin_start;
 		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
@@ -255,8 +279,8 @@ static void floppy_enable_dma(dmach_t ch
 		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
 	}
 
-	regs.ARM_r9  = dma->count;
-	regs.ARM_r10 = (unsigned long)dma->addr;
+	regs.ARM_r9  = fdma->dma.count;
+	regs.ARM_r10 = (unsigned long)fdma->dma.addr;
 	regs.ARM_fp  = (unsigned long)FLOPPYDMA_BASE;
 
 	if (claim_fiq(&fh)) {
@@ -266,16 +290,17 @@ static void floppy_enable_dma(dmach_t ch
 
 	set_fiq_handler(fiqhandler_start, fiqhandler_length);
 	set_fiq_regs(&regs);
-	enable_fiq(dma->dma_irq);
+	enable_fiq(fdma->fiq);
 }
 
-static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+static void floppy_disable_dma(unsigned int chan, dma_t *dma)
 {
-	disable_fiq(dma->dma_irq);
+	struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
+	disable_fiq(fdma->fiq);
 	release_fiq(&fh);
 }
 
-static int floppy_get_residue(dmach_t channel, dma_t *dma)
+static int floppy_get_residue(unsigned int chan, dma_t *dma)
 {
 	struct pt_regs regs;
 	get_fiq_regs(&regs);
@@ -292,7 +317,7 @@ static struct dma_ops floppy_dma_ops = {
 /*
  * This is virtual DMA - we don't need anything here.
  */
-static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+static void sound_enable_disable_dma(unsigned int chan, dma_t *dma)
 {
 }
 
@@ -302,8 +327,24 @@ static struct dma_ops sound_dma_ops = {
 	.disable	= sound_enable_disable_dma,
 };
 
-void __init arch_dma_init(dma_t *dma)
+static struct iomd_dma iomd_dma[6];
+
+static struct floppy_dma floppy_dma = {
+	.dma		= {
+		.d_ops	= &floppy_dma_ops,
+	},
+	.fiq		= FIQ_FLOPPYDATA,
+};
+
+static dma_t sound_dma = {
+	.d_ops		= &sound_dma_ops,
+};
+
+static int __init rpc_dma_init(void)
 {
+	unsigned int i;
+	int ret;
+
 	iomd_writeb(0, IOMD_IO0CR);
 	iomd_writeb(0, IOMD_IO1CR);
 	iomd_writeb(0, IOMD_IO2CR);
@@ -311,31 +352,39 @@ void __init arch_dma_init(dma_t *dma)
 
 	iomd_writeb(0xa0, IOMD_DMATCR);
 
-	dma[DMA_0].dma_base		= IOMD_IO0CURA;
-	dma[DMA_0].dma_irq		= IRQ_DMA0;
-	dma[DMA_0].d_ops		= &iomd_dma_ops;
-	dma[DMA_1].dma_base		= IOMD_IO1CURA;
-	dma[DMA_1].dma_irq		= IRQ_DMA1;
-	dma[DMA_1].d_ops		= &iomd_dma_ops;
-	dma[DMA_2].dma_base		= IOMD_IO2CURA;
-	dma[DMA_2].dma_irq		= IRQ_DMA2;
-	dma[DMA_2].d_ops		= &iomd_dma_ops;
-	dma[DMA_3].dma_base		= IOMD_IO3CURA;
-	dma[DMA_3].dma_irq		= IRQ_DMA3;
-	dma[DMA_3].d_ops		= &iomd_dma_ops;
-	dma[DMA_S0].dma_base		= IOMD_SD0CURA;
-	dma[DMA_S0].dma_irq		= IRQ_DMAS0;
-	dma[DMA_S0].d_ops		= &iomd_dma_ops;
-	dma[DMA_S1].dma_base		= IOMD_SD1CURA;
-	dma[DMA_S1].dma_irq		= IRQ_DMAS1;
-	dma[DMA_S1].d_ops		= &iomd_dma_ops;
-	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= FIQ_FLOPPYDATA;
-	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
-	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
-
 	/*
 	 * Setup DMA channels 2,3 to be for podules
 	 * and channels 0,1 for internal devices
 	 */
 	iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
+
+	iomd_dma[DMA_0].base	= IOMD_IO0CURA;
+	iomd_dma[DMA_0].irq	= IRQ_DMA0;
+	iomd_dma[DMA_1].base	= IOMD_IO1CURA;
+	iomd_dma[DMA_1].irq	= IRQ_DMA1;
+	iomd_dma[DMA_2].base	= IOMD_IO2CURA;
+	iomd_dma[DMA_2].irq	= IRQ_DMA2;
+	iomd_dma[DMA_3].base	= IOMD_IO3CURA;
+	iomd_dma[DMA_3].irq	= IRQ_DMA3;
+	iomd_dma[DMA_S0].base	= IOMD_SD0CURA;
+	iomd_dma[DMA_S0].irq	= IRQ_DMAS0;
+	iomd_dma[DMA_S1].base	= IOMD_SD1CURA;
+	iomd_dma[DMA_S1].irq	= IRQ_DMAS1;
+
+	for (i = DMA_0; i <= DMA_S1; i++) {
+		iomd_dma[i].dma.d_ops = &iomd_dma_ops;
+
+		ret = isa_dma_add(i, &iomd_dma[i].dma);
+		if (ret)
+			printk("IOMDDMA%u: unable to register: %d\n", i, ret);
+	}
+
+	ret = isa_dma_add(DMA_VIRTUAL_FLOPPY, &floppy_dma.dma);
+	if (ret)
+		printk("IOMDFLOPPY: unable to register: %d\n", ret);
+	ret = isa_dma_add(DMA_VIRTUAL_SOUND, &sound_dma);
+	if (ret)
+		printk("IOMDSOUND: unable to register: %d\n", ret);
+	return 0;
 }
+core_initcall(rpc_dma_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/include/mach/isa-dma.h linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/include/mach/isa-dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/include/mach/isa-dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/include/mach/isa-dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,5 +23,7 @@
 
 #define DMA_FLOPPY		DMA_VIRTUAL_FLOPPY
 
+#define IOMD_DMA_BOUNDARY	(PAGE_SIZE - 1)
+
 #endif /* _ASM_ARCH_DMA_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-rpc/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-rpc/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	iomd_writeb(0, IOMD_ROMCR0);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
 static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/audio.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/audio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/audio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/audio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/* 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>
- *
- * S3C24XX - Audio platfrom_device info
- *
- * This program is free software; you can 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);
-};
-
-#endif /* __ASM_ARCH_AUDIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,3 +23,6 @@
 #define ARCH_NR_GPIOS	(256 + CONFIG_S3C24XX_GPIO_EXTRA)
 
 #include <asm-generic/gpio.h>
+#include <mach/gpio-nrs.h>
+
+#define S3C_GPIO_END	(S3C2410_GPIO_BANKH + 32)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO bank numbering
+ *
+ * This program is free software; you can 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 S3C2410_GPIONO(bank,offset) ((bank) + (offset))
+
+#define S3C2410_GPIO_BANKA   (32*0)
+#define S3C2410_GPIO_BANKB   (32*1)
+#define S3C2410_GPIO_BANKC   (32*2)
+#define S3C2410_GPIO_BANKD   (32*3)
+#define S3C2410_GPIO_BANKE   (32*4)
+#define S3C2410_GPIO_BANKF   (32*5)
+#define S3C2410_GPIO_BANKG   (32*6)
+#define S3C2410_GPIO_BANKH   (32*7)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@
 #define IRQ_EINT22     S3C2410_IRQ(50)
 #define IRQ_EINT23     S3C2410_IRQ(51)
 
-
+#define IRQ_EINT_BIT(x)	((x) - IRQ_EINT4 + 4)
 #define IRQ_EINT(x)    (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x)))
 
 #define IRQ_LCD_FIFO   S3C2410_IRQ(52)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/regs-gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,16 +14,7 @@
 #ifndef __ASM_ARCH_REGS_GPIO_H
 #define __ASM_ARCH_REGS_GPIO_H
 
-#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
-
-#define S3C2410_GPIO_BANKA   (32*0)
-#define S3C2410_GPIO_BANKB   (32*1)
-#define S3C2410_GPIO_BANKC   (32*2)
-#define S3C2410_GPIO_BANKD   (32*3)
-#define S3C2410_GPIO_BANKE   (32*4)
-#define S3C2410_GPIO_BANKF   (32*5)
-#define S3C2410_GPIO_BANKG   (32*6)
-#define S3C2410_GPIO_BANKH   (32*7)
+#include <mach/gpio-nrs.h>
 
 #ifdef CONFIG_CPU_S3C2400
 #define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/system-reset.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/system-reset.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/system-reset.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/system-reset.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
 extern void (*s3c24xx_reset_hook)(void);
 
 static void
-arch_reset(char mode)
+arch_reset(char mode, const char *cmd)
 {
 	struct clk *wdtclk;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/usb-control.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/usb-control.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/include/mach/usb-control.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/include/mach/usb-control.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/usb-control.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - usb port information
- *
- * This program is free software; you can 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_USBCONTROL_H
-#define __ASM_ARCH_USBCONTROL_H "arch/arm/mach-s3c2410/include/mach/usb-control.h"
-
-#define S3C_HCDFLG_USED	(1)
-
-struct s3c2410_hcd_port {
-	unsigned char	flags;
-	unsigned char	power;
-	unsigned char	oc_status;
-	unsigned char	oc_changed;
-};
-
-struct s3c2410_hcd_info {
-	struct usb_hcd		*hcd;
-	struct s3c2410_hcd_port	port[2];
-
-	void		(*power_control)(int port, int to);
-	void		(*enable_oc)(struct s3c2410_hcd_info *, int on);
-	void		(*report_oc)(struct s3c2410_hcd_info *, int ports);
-};
-
-static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
-{
-	if (info->report_oc != NULL) {
-		(info->report_oc)(info, ports);
-	}
-}
-
-#endif /*__ASM_ARCH_USBCONTROL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-bast.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-bast.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-bast.c	2009-06-09 23:05:27.000000000 -0400
@@ -409,8 +409,7 @@ static struct platform_device bast_sio =
 static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
 	.flags		= 0,
 	.slave_addr	= 0x10,
-	.bus_freq	= 100*1000,
-	.max_freq	= 130*1000,
+	.frequency	= 100*1000,
 };
 
 /* Asix AX88796 10/100 ethernet controller */
@@ -589,8 +588,6 @@ static void __init bast_map_io(void)
 
 	s3c_device_nand.dev.platform_data = &bast_nand_info;
 
-	s3c_i2c0_set_platdata(&bast_i2c_info);
-
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
@@ -603,6 +600,7 @@ static void __init bast_init(void)
 	sysdev_class_register(&bast_pm_sysclass);
 	sysdev_register(&bast_pm_sysdev);
 
+	s3c_i2c0_set_platdata(&bast_i2c_info);
 	s3c24xx_fb_set_platdata(&bast_fb_info);
 	platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-h1940.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-h1940.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-h1940.c	2009-06-09 23:05:27.000000000 -0400
@@ -203,7 +203,7 @@ static void __init h1940_map_io(void)
 #ifdef CONFIG_PM_H1940
 	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
 #endif
-	s3c2410_pm_init();
+	s3c_pm_init();
 }
 
 static void __init h1940_init_irq(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-n30.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-n30.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-n30.c	2009-06-09 23:05:27.000000000 -0400
@@ -340,8 +340,7 @@ static struct platform_device *n35_devic
 static struct s3c2410_platform_i2c n30_i2ccfg = {
 	.flags		= 0,
 	.slave_addr	= 0x10,
-	.bus_freq	= 10*1000,
-	.max_freq	= 10*1000,
+	.frequency	= 10*1000,
 };
 
 /* Lots of hardcoded stuff, but it sets up the hardware in a useful
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/mach-qt2410.c	2009-06-09 23:05:27.000000000 -0400
@@ -355,7 +355,7 @@ static void __init qt2410_machine_init(v
 	s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
 
 	platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
-	s3c2410_pm_init();
+	s3c_pm_init();
 }
 
 MACHINE_START(QT2410, "QT2410")
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,21 +37,14 @@
 #include <plat/cpu.h>
 #include <plat/pm.h>
 
-#ifdef CONFIG_S3C2410_PM_DEBUG
-extern void pm_dbg(const char *fmt, ...);
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
 static void s3c2410_pm_prepare(void)
 {
 	/* ensure at least GSTATUS3 has the resume address */
 
-	__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
+	__raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
 
-	DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
-	DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+	S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+	S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
 
 	if (machine_is_h1940()) {
 		void *base = phys_to_virt(H1940_SUSPEND_CHECK);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/usb-simtec.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/usb-simtec.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2410/usb-simtec.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,13 +29,14 @@
 
 #include <mach/bast-map.h>
 #include <mach/bast-irq.h>
-#include <mach/usb-control.h>
 #include <mach/regs-gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
+#include <plat/usb-control.h>
 #include <plat/devs.h>
+
 #include "usb-simtec.h"
 
 /* control power and monitor over-current events on various Simtec
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,8 +29,8 @@
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-s3c2412-iis.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-s3c2412-iis.h>
+#include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
 #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/mach-jive.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/mach-jive.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/mach-jive.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,7 +52,6 @@
 #include <plat/cpu.h>
 #include <plat/pm.h>
 #include <plat/udc.h>
-#include <plat/iic.h>
 
 static struct map_desc jive_iodesc[] __initdata = {
 };
@@ -278,7 +277,7 @@ __setup("mtdset=", jive_mtdset);
 #define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
 #define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
 
-struct s3c2410fb_display jive_vgg2432a4_display[] = {
+static struct s3c2410fb_display jive_vgg2432a4_display[] = {
 	[0] = {
 		.width		= LCD_XRES,
 		.height		= LCD_YRES,
@@ -311,7 +310,7 @@ struct s3c2410fb_display jive_vgg2432a4_
 #define S3C2410_GPCCON_MASK(x)	(3 << ((x) * 2))
 #define S3C2410_GPDCON_MASK(x)	(3 << ((x) * 2))
 
-struct s3c2410fb_mach_info jive_lcd_config = {
+static struct s3c2410fb_mach_info jive_lcd_config = {
 	.displays	 = jive_vgg2432a4_display,
 	.num_displays	 = ARRAY_SIZE(jive_vgg2432a4_display),
 	.default_display = 0,
@@ -453,8 +452,7 @@ static struct spi_board_info __initdata
 /* I2C bus and device configuration. */
 
 static struct s3c2410_platform_i2c jive_i2c_cfg __initdata = {
-	.max_freq	= 80 * 1000,
-	.bus_freq	= 50 * 1000,
+	.frequency	= 80 * 1000,
 	.flags		= S3C_IICFLG_FILTER,
 	.sda_delay	= 2,
 };
@@ -494,7 +492,7 @@ static int jive_pm_suspend(struct sys_de
 	 * correct address to resume from. */
 
 	__raw_writel(0x2BED, S3C2412_INFORM0);
-	__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1);
+	__raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
 
 	return 0;
 }
@@ -630,7 +628,7 @@ static void __init jive_machine_init(voi
 
 	/* initialise the power management now we've setup everything. */
 
-	s3c2410_pm_init();
+	s3c_pm_init();
 
 	s3c_device_nand.dev.platform_data = &jive_nand_info;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2412/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2412/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <asm/cacheflush.h>
 #include <asm/irq.h>
 
 #include <mach/regs-power.h>
@@ -39,6 +40,8 @@ static void s3c2412_cpu_suspend(void)
 {
 	unsigned long tmp;
 
+	flush_cache_all();
+
 	/* set our standby method to sleep */
 
 	tmp = __raw_readl(S3C2412_PWRCFG);
@@ -85,7 +88,7 @@ static struct sleep_save s3c2412_sleep[]
 
 static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
 {
-	s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+	s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
 	return 0;
 }
 
@@ -98,7 +101,7 @@ static int s3c2412_pm_resume(struct sys_
 	tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
 	__raw_writel(tmp, S3C2412_PWRCFG);
 
-	s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+	s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
 static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-anubis.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-anubis.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-anubis.c	2009-06-09 23:05:27.000000000 -0400
@@ -243,7 +243,7 @@ static struct s3c2410_platform_nand anub
 
 /* IDE channels */
 
-struct pata_platform_info anubis_ide_platdata = {
+static struct pata_platform_info anubis_ide_platdata = {
 	.ioport_shift	= 5,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-osiris.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-osiris.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-osiris.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-osiris.c	2009-06-09 23:05:27.000000000 -0400
@@ -413,7 +413,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= osiris_map_io,
-	.init_machine	= osiris_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_machine	= osiris_init,
 	.timer		= &s3c24xx_timer,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2440/mach-rx3715.c	2009-06-09 23:05:27.000000000 -0400
@@ -203,7 +203,7 @@ static void __init rx3715_init_machine(v
 #ifdef CONFIG_PM_H1940
 	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
 #endif
-	s3c2410_pm_init();
+	s3c_pm_init();
 
 	s3c24xx_fb_set_platdata(&rx3715_fb_info);
 	platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2443/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2443/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c2443/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c2443/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
 #include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
 #define MAP(x) { \
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c24a0/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c24a0/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c24a0/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c24a0/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -70,6 +70,8 @@
 #define IRQ_EINT17	S3C2410_IRQ(49)
 #define IRQ_EINT18	S3C2410_IRQ(50)
 
+#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT00)
+
 /* SUB IRQS */
 #define IRQ_S3CUART_RX0		S3C2410_IRQ(51)	/* 67 */
 #define IRQ_S3CUART_TX0		S3C2410_IRQ(52)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6400/include/mach/map.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6400/include/mach/map.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6400/include/mach/map.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,8 @@
 
 #define S3C64XX_PA_FB		(0x77100000)
 #define S3C64XX_PA_SYSCON	(0x7E00F000)
+#define S3C64XX_PA_IIS0		(0x7F002000)
+#define S3C64XX_PA_IIS1		(0x7F003000)
 #define S3C64XX_PA_TIMER	(0x7F006000)
 #define S3C64XX_PA_IIC0		(0x7F004000)
 #define S3C64XX_PA_IIC1		(0x7F00F000)
@@ -52,6 +54,9 @@
 #define S3C64XX_PA_VIC0		(0x71200000)
 #define S3C64XX_PA_VIC1		(0x71300000)
 
+#define S3C64XX_PA_MODEM	(0x74108000)
+#define S3C64XX_VA_MODEM	S3C_ADDR(0x00600000)
+
 /* place VICs close together */
 #define S3C_VA_VIC0		(S3C_VA_IRQ + 0x00)
 #define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6400/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6400/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6400/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6400/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ static void arch_idle(void)
 	/* nothing here yet */
 }
 
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
 {
 	/* nothing here yet */
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-s3c6410/mach-smdk6410.c	2009-06-09 23:05:27.000000000 -0400
@@ -166,6 +166,10 @@ static void __init smdk6410_machine_init
 	s3c_i2c1_set_platdata(NULL);
 	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
 
+	gpio_request(S3C64XX_GPN(5), "LCD power");
+	gpio_request(S3C64XX_GPF(13), "LCD power");
+	gpio_request(S3C64XX_GPF(15), "LCD power");
+
 	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/collie.c linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/collie.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/collie.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/collie.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -145,7 +146,8 @@ static struct locomo_driver collie_uart_
 	.remove	= collie_uart_remove,
 };
 
-static int __init collie_uart_init(void) {
+static int __init collie_uart_init(void)
+{
 	return locomo_driver_register(&collie_uart_driver);
 }
 device_initcall(collie_uart_init);
@@ -195,18 +197,34 @@ static struct mtd_partition collie_parti
 	}
 };
 
+static int collie_flash_init(void)
+{
+	int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
+	if (rc)
+		return rc;
+
+	rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
+	if (rc)
+		gpio_free(COLLIE_GPIO_VPEN);
+
+	return rc;
+}
+
 static void collie_set_vpp(int vpp)
 {
-	write_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR) | COLLIE_SCP_VPEN);
-	if (vpp)
-		write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) | COLLIE_SCP_VPEN);
-	else
-		write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) & ~COLLIE_SCP_VPEN);
+	gpio_set_value(COLLIE_GPIO_VPEN, vpp);
+}
+
+static void collie_flash_exit(void)
+{
+	gpio_free(COLLIE_GPIO_VPEN);
 }
 
 static struct flash_platform_data collie_flash_data = {
 	.map_name	= "cfi_probe",
+	.init		= collie_flash_init,
 	.set_vpp	= collie_set_vpp,
+	.exit		= collie_flash_exit,
 	.parts		= collie_partitions,
 	.nr_parts	= ARRAY_SIZE(collie_partitions),
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/collie_pm.c linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/collie_pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/collie_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/collie_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
@@ -58,6 +59,9 @@ static void collie_charger_init(void)
 		return;
 	}
 
+	gpio_request(COLLIE_GPIO_CHARGE_ON, "charge on");
+	gpio_direction_output(COLLIE_GPIO_CHARGE_ON, 1);
+
 	ucb1x00_io_set_dir(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON | COLLIE_TC35143_GPIO_TMP_ON |
 			           COLLIE_TC35143_GPIO_BBAT_ON);
 	return;
@@ -73,17 +77,11 @@ static void collie_measure_temp(int on)
 
 static void collie_charge(int on)
 {
-	extern struct platform_device colliescoop_device;
-
 	/* Zaurus seems to contain LTC1731; it should know when to
 	 * stop charging itself, so setting charge on should be
 	 * relatively harmless (as long as it is not done too often).
 	 */
-	if (on) {
-		set_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON);
-	} else {
-		reset_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON);
-	}
+	gpio_set_value(COLLIE_GPIO_CHARGE_ON, on);
 }
 
 static void collie_discharge(int on)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/h3600.c linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/h3600.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/h3600.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/h3600.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,19 +42,12 @@
 #include <asm/mach/serial_sa1100.h>
 
 #include <mach/h3600.h>
-
-#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
 #include <mach/h3600_gpio.h>
-#endif
-
-#ifdef CONFIG_SA1100_H3800
-#include <mach/h3600_asic.h>
-#endif
 
 #include "generic.h"
 
-struct ipaq_model_ops ipaq_model_ops;
-EXPORT_SYMBOL(ipaq_model_ops);
+void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
+EXPORT_SYMBOL(assign_h3600_egpio);
 
 static struct mtd_partition h3xxx_partitions[] = {
 	{
@@ -63,41 +56,9 @@ static struct mtd_partition h3xxx_partit
 		.offset		= 0,
 		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
 	}, {
-#ifdef CONFIG_MTD_2PARTS_IPAQ
-		.name		= "H3XXX root jffs2",
+		.name		= "H3XXX rootfs",
 		.size		= MTDPART_SIZ_FULL,
 		.offset		= 0x00040000,
-#else
-		.name		= "H3XXX kernel",
-		.size		= 0x00080000,
-		.offset		= 0x00040000,
-	}, {
-		.name		= "H3XXX params",
-		.size		= 0x00040000,
-		.offset		= 0x000C0000,
-	}, {
-#ifdef CONFIG_JFFS2_FS
-		.name		= "H3XXX root jffs2",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= 0x00100000,
-#else
-		.name		= "H3XXX initrd",
-		.size		= 0x00100000,
-		.offset		= 0x00100000,
-	}, {
-		.name		= "H3XXX root cramfs",
-		.size		= 0x00300000,
-		.offset		= 0x00200000,
-	}, {
-		.name		= "H3XXX usr cramfs",
-		.size		= 0x00800000,
-		.offset		= 0x00500000,
-	}, {
-		.name		= "H3XXX usr local",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= 0x00d00000,
-#endif
-#endif
 	}
 };
 
@@ -131,11 +92,7 @@ static int h3600_irda_set_power(struct d
 
 static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
 {
-	if (speed < 4000000) {
-		clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
-	} else {
-		set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
-	}
+	assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL, !(speed < 4000000));
 }
 
 static struct irda_platform_data h3600_irda_data = {
@@ -266,12 +223,6 @@ static void __init h3xxx_map_io(void)
 	sa1100fb_lcd_power = h3xxx_lcd_power;
 }
 
-static __inline__ void do_blank(int setp)
-{
-	if (ipaq_model_ops.blank_callback)
-		ipaq_model_ops.blank_callback(1-setp);
-}
-
 /************************* H3100 *************************/
 
 #ifdef CONFIG_SA1100_H3100
@@ -289,7 +240,6 @@ static void h3100_control_egpio(enum ipa
 	case IPAQ_EGPIO_LCD_POWER:
 		egpio |= EGPIO_H3600_LCD_ON;
 		gpio  |= GPIO_H3100_LCD_3V_ON;
-		do_blank(setp);
 		break;
 	case IPAQ_EGPIO_LCD_ENABLE:
 		break;
@@ -343,25 +293,6 @@ static void h3100_control_egpio(enum ipa
 	}
 }
 
-static unsigned long h3100_read_egpio(void)
-{
-	return h3100_egpio;
-}
-
-static int h3100_pm_callback(int req)
-{
-	if (ipaq_model_ops.pm_callback_aux)
-		return ipaq_model_ops.pm_callback_aux(req);
-	return 0;
-}
-
-static struct ipaq_model_ops h3100_model_ops __initdata = {
-	.generic_name	= "3100",
-	.control	= h3100_control_egpio,
-	.read		= h3100_read_egpio,
-	.pm_callback	= h3100_pm_callback
-};
-
 #define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON	  \
 			  | GPIO_H3100_GPIO3	  \
 			  | GPIO_H3100_QMUTE	  \
@@ -387,7 +318,7 @@ static void __init h3100_map_io(void)
 	GAFR &= ~H3100_DIRECT_EGPIO;
 
 	H3100_EGPIO = h3100_egpio;
-	ipaq_model_ops = h3100_model_ops;
+	assign_h3600_egpio = h3100_control_egpio;
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
@@ -420,7 +351,6 @@ static void h3600_control_egpio(enum ipa
 			 EGPIO_H3600_LCD_PCI |
 			 EGPIO_H3600_LCD_5V_ON |
 			 EGPIO_H3600_LVDD_ON;
-		do_blank(setp);
 		break;
 	case IPAQ_EGPIO_LCD_ENABLE:
 		break;
@@ -471,25 +401,6 @@ static void h3600_control_egpio(enum ipa
 	}
 }
 
-static unsigned long h3600_read_egpio(void)
-{
-	return h3600_egpio;
-}
-
-static int h3600_pm_callback(int req)
-{
-	if (ipaq_model_ops.pm_callback_aux)
-		return ipaq_model_ops.pm_callback_aux(req);
-	return 0;
-}
-
-static struct ipaq_model_ops h3600_model_ops __initdata = {
-	.generic_name	= "3600",
-	.control	= h3600_control_egpio,
-	.read		= h3600_read_egpio,
-	.pm_callback	= h3600_pm_callback
-};
-
 static void __init h3600_map_io(void)
 {
 	h3xxx_map_io();
@@ -504,7 +415,7 @@ static void __init h3600_map_io(void)
 	       GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
 
 	H3600_EGPIO = h3600_egpio;	   /* Maintains across sleep? */
-	ipaq_model_ops = h3600_model_ops;
+	assign_h3600_egpio = h3600_control_egpio;
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
@@ -519,388 +430,3 @@ MACHINE_END
 
 #endif /* CONFIG_SA1100_H3600 */
 
-#ifdef CONFIG_SA1100_H3800
-
-#define SET_ASIC1(x) \
-   do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
-
-#define SET_ASIC2(x) \
-   do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
-
-#define CLEAR_ASIC1(x) \
-   do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
-
-#define CLEAR_ASIC2(x) \
-   do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
-
-
-/*
-  On screen enable, we get
-
-     h3800_video_power_on(1)
-     LCD controller starts
-     h3800_video_lcd_enable(1)
-
-  On screen disable, we get
-
-     h3800_video_lcd_enable(0)
-     LCD controller stops
-     h3800_video_power_on(0)
-*/
-
-
-static void h3800_video_power_on(int setp)
-{
-	if (setp) {
-		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
-		msleep(30);
-		H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
-		msleep(5);
-		H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
-		msleep(50);
-		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
-		msleep(5);
-	} else {
-		msleep(5);
-		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
-		msleep(50);
-		H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
-		msleep(5);
-		H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
-		msleep(100);
-		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
-	}
-}
-
-static void h3800_video_lcd_enable(int setp)
-{
-	if (setp) {
-		msleep(17);	// Wait one from before turning on
-		H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
-	} else {
-		H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
-		msleep(30);	// Wait before turning off
-	}
-}
-
-
-static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
-{
-	switch (x) {
-	case IPAQ_EGPIO_LCD_POWER:
-		h3800_video_power_on(setp);
-		break;
-	case IPAQ_EGPIO_LCD_ENABLE:
-		h3800_video_lcd_enable(setp);
-		break;
-	case IPAQ_EGPIO_CODEC_NRESET:
-	case IPAQ_EGPIO_AUDIO_ON:
-	case IPAQ_EGPIO_QMUTE:
-		printk("%s: error - should not be called\n", __func__);
-		break;
-	case IPAQ_EGPIO_OPT_NVRAM_ON:
-		SET_ASIC2(GPIO2_OPT_ON_NVRAM);
-		break;
-	case IPAQ_EGPIO_OPT_ON:
-		SET_ASIC2(GPIO2_OPT_ON);
-		break;
-	case IPAQ_EGPIO_CARD_RESET:
-		SET_ASIC2(GPIO2_OPT_PCM_RESET);
-		break;
-	case IPAQ_EGPIO_OPT_RESET:
-		SET_ASIC2(GPIO2_OPT_RESET);
-		break;
-	case IPAQ_EGPIO_IR_ON:
-		CLEAR_ASIC1(GPIO1_IR_ON_N);
-		break;
-	case IPAQ_EGPIO_IR_FSEL:
-		break;
-	case IPAQ_EGPIO_RS232_ON:
-		SET_ASIC1(GPIO1_RS232_ON);
-		break;
-	case IPAQ_EGPIO_VPP_ON:
-		H3800_ASIC2_FlashWP_VPP_ON = setp;
-		break;
-	}
-}
-
-static unsigned long h3800_read_egpio(void)
-{
-	return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
-}
-
-/* We need to fix ASIC2 GPIO over suspend/resume.  At the moment,
-   it doesn't appear that ASIC1 GPIO has the same problem */
-
-static int h3800_pm_callback(int req)
-{
-	static u16 asic1_data;
-	static u16 asic2_data;
-	int result = 0;
-
-	printk("%s %d\n", __func__, req);
-
-	switch (req) {
-	case PM_RESUME:
-		MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;  /* Set MSC2 correctly */
-
-		H3800_ASIC2_GPIOPIOD = asic2_data;
-		H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
-			| GPIO2_SD_DETECT
-			| GPIO2_EAR_IN_N
-			| GPIO2_USB_DETECT_N
-			| GPIO2_SD_CON_SLT;
-
-		H3800_ASIC1_GPIO_OUT = asic1_data;
-
-		if (ipaq_model_ops.pm_callback_aux)
-			result = ipaq_model_ops.pm_callback_aux(req);
-		break;
-
-	case PM_SUSPEND:
-		if (ipaq_model_ops.pm_callback_aux &&
-		     ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
-			return result;
-
-		asic1_data = H3800_ASIC1_GPIO_OUT;
-		asic2_data = H3800_ASIC2_GPIOPIOD;
-		break;
-	default:
-		printk("%s: unrecognized PM callback\n", __func__);
-		break;
-	}
-	return result;
-}
-
-static struct ipaq_model_ops h3800_model_ops __initdata = {
-	.generic_name	= "3800",
-	.control	= h3800_control_egpio,
-	.read		= h3800_read_egpio,
-	.pm_callback	= h3800_pm_callback
-};
-
-#define MAX_ASIC_ISR_LOOPS    20
-
-/* The order of these is important - see #include <mach/irqs.h> */
-static u32 kpio_irq_mask[] = {
-	KPIO_KEY_ALL,
-	KPIO_SPI_INT,
-	KPIO_OWM_INT,
-	KPIO_ADC_INT,
-	KPIO_UART_0_INT,
-	KPIO_UART_1_INT,
-	KPIO_TIMER_0_INT,
-	KPIO_TIMER_1_INT,
-	KPIO_TIMER_2_INT
-};
-
-static u32 gpio_irq_mask[] = {
-	GPIO2_PEN_IRQ,
-	GPIO2_SD_DETECT,
-	GPIO2_EAR_IN_N,
-	GPIO2_USB_DETECT_N,
-	GPIO2_SD_CON_SLT,
-};
-
-static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc)
-{
-	int i;
-
-	if (0) printk("%s: interrupt received\n", __func__);
-
-	desc->chip->ack(irq);
-
-	for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
-		u32 irq;
-		int j;
-
-		/* KPIO */
-		irq = H3800_ASIC2_KPIINTFLAG;
-		if (0) printk("%s KPIO 0x%08X\n", __func__, irq);
-		for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
-			if (irq & kpio_irq_mask[j])
-				handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j);
-
-		/* GPIO2 */
-		irq = H3800_ASIC2_GPIINTFLAG;
-		if (0) printk("%s GPIO 0x%08X\n", __func__, irq);
-		for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
-			if (irq & gpio_irq_mask[j])
-				handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j);
-	}
-
-	if (i >= MAX_ASIC_ISR_LOOPS)
-		printk("%s: interrupt processing overrun\n", __func__);
-
-	/* For level-based interrupts */
-	desc->chip->unmask(irq);
-
-}
-
-static struct irqaction h3800_irq = {
-	.name		= "h3800_asic",
-	.handler	= h3800_IRQ_demux,
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-};
-
-u32 kpio_int_shadow = 0;
-
-
-/* mask_ack <- IRQ is first serviced.
-       mask <- IRQ is disabled.
-     unmask <- IRQ is enabled
-
-     The INTCLR registers are poorly documented.  I believe that writing
-     a "1" to the register clears the specific interrupt, but the documentation
-     indicates writing a "0" clears the interrupt.  In any case, they shouldn't
-     be read (that's the INTFLAG register)
- */
-
-static void h3800_mask_ack_kpio_irq(unsigned int irq)
-{
-	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
-	kpio_int_shadow &= ~mask;
-	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
-	H3800_ASIC2_KPIINTCLR  = mask;
-}
-
-static void h3800_mask_kpio_irq(unsigned int irq)
-{
-	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
-	kpio_int_shadow &= ~mask;
-	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
-}
-
-static void h3800_unmask_kpio_irq(unsigned int irq)
-{
-	u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
-	kpio_int_shadow |= mask;
-	H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
-}
-
-static void h3800_mask_ack_gpio_irq(unsigned int irq)
-{
-	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
-	H3800_ASIC2_GPIINTSTAT &= ~mask;
-	H3800_ASIC2_GPIINTCLR	= mask;
-}
-
-static void h3800_mask_gpio_irq(unsigned int irq)
-{
-	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
-	H3800_ASIC2_GPIINTSTAT &= ~mask;
-	}
-
-static void h3800_unmask_gpio_irq(unsigned int irq)
-{
-	u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
-	H3800_ASIC2_GPIINTSTAT |= mask;
-}
-
-static void __init h3800_init_irq(void)
-{
-	int i;
-
-	/* Initialize standard IRQs */
-	sa1100_init_irq();
-
-	/* Disable all IRQs and set up clock */
-	H3800_ASIC2_KPIINTSTAT	   =  0;     /* Disable all interrupts */
-	H3800_ASIC2_GPIINTSTAT	   =  0;
-
-	H3800_ASIC2_KPIINTCLR	   =  0;     /* Clear all KPIO interrupts */
-	H3800_ASIC2_GPIINTCLR	   =  0;     /* Clear all GPIO interrupts */
-
-//	H3800_ASIC2_KPIINTCLR	   =  0xffff;	  /* Clear all KPIO interrupts */
-//	H3800_ASIC2_GPIINTCLR	   =  0xffff;	  /* Clear all GPIO interrupts */
-
-	H3800_ASIC2_CLOCK_Enable       |= ASIC2_CLOCK_EX0;   /* 32 kHZ crystal on */
-	H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
-	H3800_ASIC2_INTR_ClockPrescale	= ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
-	H3800_ASIC2_INTR_TimerSet	= 1;
-
-#if 0
-	for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
-		int irq = i + H3800_KPIO_IRQ_START;
-		irq_desc[irq].valid    = 1;
-		irq_desc[irq].probe_ok = 1;
-		set_irq_chip(irq, &h3800_kpio_irqchip);
-	}
-
-	for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
-		int irq = i + H3800_GPIO_IRQ_START;
-		irq_desc[irq].valid    = 1;
-		irq_desc[irq].probe_ok = 1;
-		set_irq_chip(irq, &h3800_gpio_irqchip);
-	}
-#endif
-	set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING);
-	set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
-}
-
-
-#define ASIC1_OUTPUTS	 0x7fff   /* First 15 bits are used */
-
-static void __init h3800_map_io(void)
-{
-	h3xxx_map_io();
-
-	/* Add wakeup on AC plug/unplug */
-	PWER  |= PWER_GPIO12;
-
-	/* Initialize h3800-specific values here */
-	GPCR = 0x0fffffff;	 /* All outputs are set low by default */
-	GAFR =	GPIO_H3800_CLK_OUT |
-		GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
-		GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
-	GPDR =	GPIO_H3800_CLK_OUT |
-		GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
-		GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
-		GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
-		GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
-	TUCR =	TUCR_3_6864MHz;   /* Seems to be used only for the Bluetooth UART */
-
-	/* Fix the memory bus */
-	MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;
-
-	/* Set up ASIC #1 */
-	H3800_ASIC1_GPIO_DIR		= ASIC1_OUTPUTS;	    /* All outputs */
-	H3800_ASIC1_GPIO_MASK		= ASIC1_OUTPUTS;	    /* No interrupts */
-	H3800_ASIC1_GPIO_SLEEP_MASK	= ASIC1_OUTPUTS;
-	H3800_ASIC1_GPIO_SLEEP_DIR	= ASIC1_OUTPUTS;
-	H3800_ASIC1_GPIO_SLEEP_OUT	= GPIO1_EAR_ON_N;
-	H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
-	H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;
-
-	H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
-				      | GPIO1_RS232_ON
-				      | GPIO1_EAR_ON_N;
-
-	/* Set up ASIC #2 */
-	H3800_ASIC2_GPIOPIOD	= GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
-	H3800_ASIC2_GPOBFSTAT	= GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
-
-	H3800_ASIC2_GPIODIR	= GPIO2_PEN_IRQ
-				      | GPIO2_SD_DETECT
-				      | GPIO2_EAR_IN_N
-				      | GPIO2_USB_DETECT_N
-				      | GPIO2_SD_CON_SLT;
-
-	/* TODO : Set sleep states & battery fault states */
-
-	/* Clear VPP Enable */
-	H3800_ASIC2_FlashWP_VPP_ON = 0;
-	ipaq_model_ops = h3800_model_ops;
-}
-
-MACHINE_START(H3800, "Compaq iPAQ H3800")
-	.phys_io	= 0x80000000,
-	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
-	.boot_params	= 0xc0000100,
-	.map_io		= h3800_map_io,
-	.init_irq	= h3800_init_irq,
-	.timer		= &sa1100_timer,
-	.init_machine	= h3xxx_mach_init,
-MACHINE_END
-
-#endif /* CONFIG_SA1100_H3800 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/collie.h linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/collie.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/collie.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,21 +14,21 @@
 #define __ASM_ARCH_COLLIE_H
 
 
-#define COLLIE_SCP_CHARGE_ON	SCOOP_GPCR_PA11
+#define COLLIE_SCOOP_GPIO_BASE	(GPIO_MAX + 1)
+#define COLLIE_GPIO_CHARGE_ON	(COLLIE_SCOOP_GPIO_BASE + 0)
 #define COLLIE_SCP_DIAG_BOOT1	SCOOP_GPCR_PA12
 #define COLLIE_SCP_DIAG_BOOT2	SCOOP_GPCR_PA13
 #define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
 #define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
 #define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
 #define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
-#define COLLIE_SCP_VPEN		SCOOP_GPCR_PA18
+#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_CHARGE_ON | COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
-				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | COLLIE_SCP_VPEN | \
+#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_VPEN | \
-				COLLIE_SCP_CHARGE_ON )
+#define COLLIE_SCOOP_IO_OUT	( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R )
 
 /* GPIOs for which the generic definition doesn't say much */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/h3600_gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -48,22 +48,11 @@
 #define GPIO_H3600_OPT_LOCK		GPIO_GPIO (22)
 #define GPIO_H3600_OPT_DET		GPIO_GPIO (27)
 
-/* H3800 specific pins */
-#define GPIO_H3800_AC_IN                GPIO_GPIO (12)
-#define GPIO_H3800_COM_DSR              GPIO_GPIO (13)
-#define GPIO_H3800_MMC_INT              GPIO_GPIO (18)
-#define GPIO_H3800_NOPT_IND             GPIO_GPIO (20)   /* Almost exactly the same as GPIO_H3600_OPT_DET */
-#define GPIO_H3800_OPT_BAT_FAULT        GPIO_GPIO (22)
-#define GPIO_H3800_CLK_OUT              GPIO_GPIO (27)
-
 /****************************************************/
 
 #define IRQ_GPIO_H3600_ACTION_BUTTON    IRQ_GPIO18
 #define IRQ_GPIO_H3600_OPT_DET		IRQ_GPIO27
 
-#define IRQ_GPIO_H3800_MMC_INT          IRQ_GPIO18
-#define IRQ_GPIO_H3800_NOPT_IND         IRQ_GPIO20 /* almost same as OPT_DET */
-
 /* 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. */
@@ -84,457 +73,5 @@
 #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. */
 
-/********************* H3800, ASIC #2 ********************/
-
-#define _H3800_ASIC2_Base            (H3600_EGPIO_VIRT)
-#define H3800_ASIC2_OFFSET(s,x,y)    \
-    (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
-#define H3800_ASIC2_NOFFSET(s,x,n,y) \
-    (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _ ## n ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
-
-#define _H3800_ASIC2_GPIO_Base                 0x0000
-#define _H3800_ASIC2_GPIO_Direction            0x0000    /* R/W, 16 bits 1:input, 0:output */
-#define _H3800_ASIC2_GPIO_InterruptType        0x0004    /* R/W, 12 bits 1:edge, 0:level          */
-#define _H3800_ASIC2_GPIO_InterruptEdgeType    0x0008    /* R/W, 12 bits 1:rising, 0:falling */
-#define _H3800_ASIC2_GPIO_InterruptLevelType   0x000C    /* R/W, 12 bits 1:high, 0:low  */
-#define _H3800_ASIC2_GPIO_InterruptClear       0x0010    /* W,   12 bits */
-#define _H3800_ASIC2_GPIO_InterruptFlag        0x0010    /* R,   12 bits - reads int status */
-#define _H3800_ASIC2_GPIO_Data                 0x0014    /* R/W, 16 bits */
-#define _H3800_ASIC2_GPIO_BattFaultOut         0x0018    /* R/W, 16 bit - sets level on batt fault */
-#define _H3800_ASIC2_GPIO_InterruptEnable      0x001c    /* R/W, 12 bits 1:enable interrupt */
-#define _H3800_ASIC2_GPIO_Alternate            0x003c    /* R/W, 12+1 bits - set alternate functions */
-
-#define H3800_ASIC2_GPIO_Direction          H3800_ASIC2_OFFSET( u16, GPIO, Direction )
-#define H3800_ASIC2_GPIO_InterruptType      H3800_ASIC2_OFFSET( u16, GPIO, InterruptType )
-#define H3800_ASIC2_GPIO_InterruptEdgeType  H3800_ASIC2_OFFSET( u16, GPIO, InterruptEdgeType )
-#define H3800_ASIC2_GPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, GPIO, InterruptLevelType )
-#define H3800_ASIC2_GPIO_InterruptClear     H3800_ASIC2_OFFSET( u16, GPIO, InterruptClear )
-#define H3800_ASIC2_GPIO_InterruptFlag      H3800_ASIC2_OFFSET( u16, GPIO, InterruptFlag )
-#define H3800_ASIC2_GPIO_Data               H3800_ASIC2_OFFSET( u16, GPIO, Data )
-#define H3800_ASIC2_GPIO_BattFaultOut       H3800_ASIC2_OFFSET( u16, GPIO, BattFaultOut )
-#define H3800_ASIC2_GPIO_InterruptEnable    H3800_ASIC2_OFFSET( u16, GPIO, InterruptEnable )
-#define H3800_ASIC2_GPIO_Alternate          H3800_ASIC2_OFFSET( u16, GPIO, Alternate )
-
-#define GPIO_H3800_ASIC2_IN_Y1_N          (1 << 0)   /* Output: Touchscreen Y1 */
-#define GPIO_H3800_ASIC2_IN_X0            (1 << 1)   /* Output: Touchscreen X0 */
-#define GPIO_H3800_ASIC2_IN_Y0            (1 << 2)   /* Output: Touchscreen Y0 */
-#define GPIO_H3800_ASIC2_IN_X1_N          (1 << 3)   /* Output: Touchscreen X1 */
-#define GPIO_H3800_ASIC2_BT_RST           (1 << 4)   /* Output: Bluetooth reset */
-#define GPIO_H3800_ASIC2_PEN_IRQ          (1 << 5)   /* Input : Pen down        */
-#define GPIO_H3800_ASIC2_SD_DETECT        (1 << 6)   /* Input : SD detect */
-#define GPIO_H3800_ASIC2_EAR_IN_N         (1 << 7)   /* Input : Audio jack plug inserted */
-#define GPIO_H3800_ASIC2_OPT_PCM_RESET    (1 << 8)   /* Output: */
-#define GPIO_H3800_ASIC2_OPT_RESET        (1 << 9)   /* Output: */
-#define GPIO_H3800_ASIC2_USB_DETECT_N     (1 << 10)  /* Input : */
-#define GPIO_H3800_ASIC2_SD_CON_SLT       (1 << 11)  /* Input : */
-
-#define _H3800_ASIC2_KPIO_Base                 0x0200
-#define _H3800_ASIC2_KPIO_Direction            0x0000    /* R/W, 12 bits 1:input, 0:output */
-#define _H3800_ASIC2_KPIO_InterruptType        0x0004    /* R/W, 12 bits 1:edge, 0:level          */
-#define _H3800_ASIC2_KPIO_InterruptEdgeType    0x0008    /* R/W, 12 bits 1:rising, 0:falling */
-#define _H3800_ASIC2_KPIO_InterruptLevelType   0x000C    /* R/W, 12 bits 1:high, 0:low  */
-#define _H3800_ASIC2_KPIO_InterruptClear       0x0010    /* W,   20 bits - 8 special */
-#define _H3800_ASIC2_KPIO_InterruptFlag        0x0010    /* R,   20 bits - 8 special - reads int status */
-#define _H3800_ASIC2_KPIO_Data                 0x0014    /* R/W, 16 bits */
-#define _H3800_ASIC2_KPIO_BattFaultOut         0x0018    /* R/W, 16 bit - sets level on batt fault */
-#define _H3800_ASIC2_KPIO_InterruptEnable      0x001c    /* R/W, 20 bits - 8 special */
-#define _H3800_ASIC2_KPIO_Alternate            0x003c    /* R/W, 6 bits */
-
-#define H3800_ASIC2_KPIO_Direction          H3800_ASIC2_OFFSET( u16, KPIO, Direction )
-#define H3800_ASIC2_KPIO_InterruptType      H3800_ASIC2_OFFSET( u16, KPIO, InterruptType )
-#define H3800_ASIC2_KPIO_InterruptEdgeType  H3800_ASIC2_OFFSET( u16, KPIO, InterruptEdgeType )
-#define H3800_ASIC2_KPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, KPIO, InterruptLevelType )
-#define H3800_ASIC2_KPIO_InterruptClear     H3800_ASIC2_OFFSET( u32, KPIO, InterruptClear )
-#define H3800_ASIC2_KPIO_InterruptFlag      H3800_ASIC2_OFFSET( u32, KPIO, InterruptFlag )
-#define H3800_ASIC2_KPIO_Data               H3800_ASIC2_OFFSET( u16, KPIO, Data )
-#define H3800_ASIC2_KPIO_BattFaultOut       H3800_ASIC2_OFFSET( u16, KPIO, BattFaultOut )
-#define H3800_ASIC2_KPIO_InterruptEnable    H3800_ASIC2_OFFSET( u32, KPIO, InterruptEnable )
-#define H3800_ASIC2_KPIO_Alternate          H3800_ASIC2_OFFSET( u16, KPIO, Alternate )
-
-#define H3800_ASIC2_KPIO_SPI_INT        ( 1 << 16 )
-#define H3800_ASIC2_KPIO_OWM_INT        ( 1 << 17 )
-#define H3800_ASIC2_KPIO_ADC_INT        ( 1 << 18 )
-#define H3800_ASIC2_KPIO_UART_0_INT     ( 1 << 19 )
-#define H3800_ASIC2_KPIO_UART_1_INT     ( 1 << 20 )
-#define H3800_ASIC2_KPIO_TIMER_0_INT    ( 1 << 21 )
-#define H3800_ASIC2_KPIO_TIMER_1_INT    ( 1 << 22 )
-#define H3800_ASIC2_KPIO_TIMER_2_INT    ( 1 << 23 )
-
-#define KPIO_H3800_ASIC2_RECORD_BTN_N     (1 << 0)   /* Record button */
-#define KPIO_H3800_ASIC2_KEY_5W1_N        (1 << 1)   /* Keypad */
-#define KPIO_H3800_ASIC2_KEY_5W2_N        (1 << 2)   /* */
-#define KPIO_H3800_ASIC2_KEY_5W3_N        (1 << 3)   /* */
-#define KPIO_H3800_ASIC2_KEY_5W4_N        (1 << 4)   /* */
-#define KPIO_H3800_ASIC2_KEY_5W5_N        (1 << 5)   /* */
-#define KPIO_H3800_ASIC2_KEY_LEFT_N       (1 << 6)   /* */
-#define KPIO_H3800_ASIC2_KEY_RIGHT_N      (1 << 7)   /* */
-#define KPIO_H3800_ASIC2_KEY_AP1_N        (1 << 8)   /* Old "Calendar" */
-#define KPIO_H3800_ASIC2_KEY_AP2_N        (1 << 9)   /* Old "Schedule" */
-#define KPIO_H3800_ASIC2_KEY_AP3_N        (1 << 10)  /* Old "Q"        */
-#define KPIO_H3800_ASIC2_KEY_AP4_N        (1 << 11)  /* Old "Undo"     */
-
-/* Alternate KPIO functions (set by default) */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W1_N        (1 << 1)   /* Action key */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W2_N        (1 << 2)   /* J1 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W3_N        (1 << 3)   /* J2 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W4_N        (1 << 4)   /* J3 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W5_N        (1 << 5)   /* J4 of keypad input */
-
-#define _H3800_ASIC2_SPI_Base                  0x0400
-#define _H3800_ASIC2_SPI_Control               0x0000    /* R/W 8 bits */
-#define _H3800_ASIC2_SPI_Data                  0x0004    /* R/W 8 bits */
-#define _H3800_ASIC2_SPI_ChipSelectDisabled    0x0008    /* W   8 bits */
-
-#define H3800_ASIC2_SPI_Control             H3800_ASIC2_OFFSET( u8, SPI, Control )
-#define H3800_ASIC2_SPI_Data                H3800_ASIC2_OFFSET( u8, SPI, Data )
-#define H3800_ASIC2_SPI_ChipSelectDisabled  H3800_ASIC2_OFFSET( u8, SPI, ChipSelectDisabled )
-
-#define _H3800_ASIC2_PWM_0_Base                0x0600
-#define _H3800_ASIC2_PWM_1_Base                0x0700
-#define _H3800_ASIC2_PWM_TimeBase              0x0000    /* R/W 6 bits */
-#define _H3800_ASIC2_PWM_PeriodTime            0x0004    /* R/W 12 bits */
-#define _H3800_ASIC2_PWM_DutyTime              0x0008    /* R/W 12 bits */
-
-#define H3800_ASIC2_PWM_0_TimeBase          H3800_ASIC2_NOFFSET(  u8, PWM, 0, TimeBase )
-#define H3800_ASIC2_PWM_0_PeriodTime        H3800_ASIC2_NOFFSET( u16, PWM, 0, PeriodTime )
-#define H3800_ASIC2_PWM_0_DutyTime          H3800_ASIC2_NOFFSET( u16, PWM, 0, DutyTime )
-
-#define H3800_ASIC2_PWM_1_TimeBase          H3800_ASIC2_NOFFSET(  u8, PWM, 1, TimeBase )
-#define H3800_ASIC2_PWM_1_PeriodTime        H3800_ASIC2_NOFFSET( u16, PWM, 1, PeriodTime )
-#define H3800_ASIC2_PWM_1_DutyTime          H3800_ASIC2_NOFFSET( u16, PWM, 1, DutyTime )
-
-#define H3800_ASIC2_PWM_TIMEBASE_MASK             0xf    /* Low 4 bits sets time base, max = 8 */
-#define H3800_ASIC2_PWM_TIMEBASE_ENABLE    ( 1 << 4 )    /* Enable clock */
-#define H3800_ASIC2_PWM_TIMEBASE_CLEAR     ( 1 << 5 )    /* Clear the PWM */
-
-#define _H3800_ASIC2_LED_0_Base                0x0800
-#define _H3800_ASIC2_LED_1_Base                0x0880
-#define _H3800_ASIC2_LED_2_Base                0x0900
-#define _H3800_ASIC2_LED_TimeBase              0x0000    /* R/W  7 bits */
-#define _H3800_ASIC2_LED_PeriodTime            0x0004    /* R/W 12 bits */
-#define _H3800_ASIC2_LED_DutyTime              0x0008    /* R/W 12 bits */
-#define _H3800_ASIC2_LED_AutoStopCount         0x000c    /* R/W 16 bits */
-
-#define H3800_ASIC2_LED_0_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 0, TimeBase )
-#define H3800_ASIC2_LED_0_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 0, PeriodTime )
-#define H3800_ASIC2_LED_0_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 0, DutyTime )
-#define H3800_ASIC2_LED_0_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 0, AutoStopClock )
-
-#define H3800_ASIC2_LED_1_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 1, TimeBase )
-#define H3800_ASIC2_LED_1_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 1, PeriodTime )
-#define H3800_ASIC2_LED_1_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 1, DutyTime )
-#define H3800_ASIC2_LED_1_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 1, AutoStopClock )
-
-#define H3800_ASIC2_LED_2_TimeBase          H3800_ASIC2_NOFFSET(  u8, LED, 2, TimeBase )
-#define H3800_ASIC2_LED_2_PeriodTime        H3800_ASIC2_NOFFSET( u16, LED, 2, PeriodTime )
-#define H3800_ASIC2_LED_2_DutyTime          H3800_ASIC2_NOFFSET( u16, LED, 2, DutyTime )
-#define H3800_ASIC2_LED_2_AutoStopClock     H3800_ASIC2_NOFFSET( u16, LED, 2, AutoStopClock )
-
-#define H3800_ASIC2_LED_TIMEBASE_MASK            0x0f    /* Low 4 bits sets time base, max = 13 */
-#define H3800_ASIC2_LED_TIMEBASE_BLINK     ( 1 << 4 )    /* Enable blinking */
-#define H3800_ASIC2_LED_TIMEBASE_AUTOSTOP  ( 1 << 5 )
-#define H3800_ASIC2_LED_TIMEBASE_ALWAYS    ( 1 << 6 )    /* Enable blink always */
-
-#define _H3800_ASIC2_UART_0_Base               0x0A00
-#define _H3800_ASIC2_UART_1_Base               0x0C00
-#define _H3800_ASIC2_UART_Receive              0x0000    /* R    8 bits */
-#define _H3800_ASIC2_UART_Transmit             0x0000    /*   W  8 bits */
-#define _H3800_ASIC2_UART_IntEnable            0x0004    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_IntVerify            0x0008    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_FIFOControl          0x000c    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_LineControl          0x0010    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_ModemStatus          0x0014    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_LineStatus           0x0018    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_ScratchPad           0x001c    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_DivisorLatchL        0x0020    /* R/W  8 bits */
-#define _H3800_ASIC2_UART_DivisorLatchH        0x0024    /* R/W  8 bits */
-
-#define H3800_ASIC2_UART_0_Receive          H3800_ASIC2_NOFFSET(  u8, UART, 0, Receive )
-#define H3800_ASIC2_UART_0_Transmit         H3800_ASIC2_NOFFSET(  u8, UART, 0, Transmit )
-#define H3800_ASIC2_UART_0_IntEnable        H3800_ASIC2_NOFFSET(  u8, UART, 0, IntEnable )
-#define H3800_ASIC2_UART_0_IntVerify        H3800_ASIC2_NOFFSET(  u8, UART, 0, IntVerify )
-#define H3800_ASIC2_UART_0_FIFOControl      H3800_ASIC2_NOFFSET(  u8, UART, 0, FIFOControl )
-#define H3800_ASIC2_UART_0_LineControl      H3800_ASIC2_NOFFSET(  u8, UART, 0, LineControl )
-#define H3800_ASIC2_UART_0_ModemStatus      H3800_ASIC2_NOFFSET(  u8, UART, 0, ModemStatus )
-#define H3800_ASIC2_UART_0_LineStatus       H3800_ASIC2_NOFFSET(  u8, UART, 0, LineStatus )
-#define H3800_ASIC2_UART_0_ScratchPad       H3800_ASIC2_NOFFSET(  u8, UART, 0, ScratchPad )
-#define H3800_ASIC2_UART_0_DivisorLatchL    H3800_ASIC2_NOFFSET(  u8, UART, 0, DivisorLatchL )
-#define H3800_ASIC2_UART_0_DivisorLatchH    H3800_ASIC2_NOFFSET(  u8, UART, 0, DivisorLatchH )
-
-#define H3800_ASIC2_UART_1_Receive          H3800_ASIC2_NOFFSET(  u8, UART, 1, Receive )
-#define H3800_ASIC2_UART_1_Transmit         H3800_ASIC2_NOFFSET(  u8, UART, 1, Transmit )
-#define H3800_ASIC2_UART_1_IntEnable        H3800_ASIC2_NOFFSET(  u8, UART, 1, IntEnable )
-#define H3800_ASIC2_UART_1_IntVerify        H3800_ASIC2_NOFFSET(  u8, UART, 1, IntVerify )
-#define H3800_ASIC2_UART_1_FIFOControl      H3800_ASIC2_NOFFSET(  u8, UART, 1, FIFOControl )
-#define H3800_ASIC2_UART_1_LineControl      H3800_ASIC2_NOFFSET(  u8, UART, 1, LineControl )
-#define H3800_ASIC2_UART_1_ModemStatus      H3800_ASIC2_NOFFSET(  u8, UART, 1, ModemStatus )
-#define H3800_ASIC2_UART_1_LineStatus       H3800_ASIC2_NOFFSET(  u8, UART, 1, LineStatus )
-#define H3800_ASIC2_UART_1_ScratchPad       H3800_ASIC2_NOFFSET(  u8, UART, 1, ScratchPad )
-#define H3800_ASIC2_UART_1_DivisorLatchL    H3800_ASIC2_NOFFSET(  u8, UART, 1, DivisorLatchL )
-#define H3800_ASIC2_UART_1_DivisorLatchH    H3800_ASIC2_NOFFSET(  u8, UART, 1, DivisorLatchH )
-
-#define _H3800_ASIC2_TIMER_Base                0x0E00
-#define _H3800_ASIC2_TIMER_Command             0x0000    /* R/W  8 bits */
-
-#define H3800_ASIC2_TIMER_Command           H3800_ASIC2_OFFSET( u8, Timer, Command )
-
-#define H3800_ASIC2_TIMER_GAT_0            ( 1 << 0 )    /* Gate enable, counter 0 */
-#define H3800_ASIC2_TIMER_GAT_1            ( 1 << 1 )    /* Gate enable, counter 1 */
-#define H3800_ASIC2_TIMER_GAT_2            ( 1 << 2 )    /* Gate enable, counter 2 */
-#define H3800_ASIC2_TIMER_CLK_0            ( 1 << 3 )    /* Clock enable, counter 0 */
-#define H3800_ASIC2_TIMER_CLK_1            ( 1 << 4 )    /* Clock enable, counter 1 */
-#define H3800_ASIC2_TIMER_CLK_2            ( 1 << 5 )    /* Clock enable, counter 2 */
-#define H3800_ASIC2_TIMER_MODE_0           ( 1 << 6 )    /* Mode 0 enable, counter 0 */
-#define H3800_ASIC2_TIMER_MODE_1           ( 1 << 7 )    /* Mode 0 enable, counter 1 */
-
-#define _H3800_ASIC2_CLOCK_Base                0x1000
-#define _H3800_ASIC2_CLOCK_Enable              0x0000    /* R/W  18 bits */
-
-#define H3800_ASIC2_CLOCK_Enable            H3800_ASIC2_OFFSET( u32, CLOCK, Enable )
-
-#define H3800_ASIC2_CLOCK_AUDIO_1              0x0001    /* Enable 4.1 MHz clock for 8Khz and 4khz sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_2              0x0002    /* Enable 12.3 MHz clock for 48Khz and 32khz sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_3              0x0004    /* Enable 5.6 MHz clock for 11 kHZ sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_4              0x0008    /* Enable 11.289 MHz clock for 44 and 22 kHz sample rate */
-#define H3800_ASIC2_CLOCK_ADC              ( 1 << 4 )    /* 1.024 MHz clock to ADC */
-#define H3800_ASIC2_CLOCK_SPI              ( 1 << 5 )    /* 4.096 MHz clock to SPI */
-#define H3800_ASIC2_CLOCK_OWM              ( 1 << 6 )    /* 4.096 MHz clock to OWM */
-#define H3800_ASIC2_CLOCK_PWM              ( 1 << 7 )    /* 2.048 MHz clock to PWM */
-#define H3800_ASIC2_CLOCK_UART_1           ( 1 << 8 )    /* 24.576 MHz clock to UART1 (turn off bit 16) */
-#define H3800_ASIC2_CLOCK_UART_0           ( 1 << 9 )    /* 24.576 MHz clock to UART0 (turn off bit 17) */
-#define H3800_ASIC2_CLOCK_SD_1             ( 1 << 10 )   /* 16.934 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_2             ( 2 << 10 )   /* 24.576 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_3             ( 3 << 10 )   /* 33.869 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_4             ( 4 << 10 )   /* 49.152 MHz to SD */
-#define H3800_ASIC2_CLOCK_EX0              ( 1 << 13 )   /* Enable 32.768 kHz crystal */
-#define H3800_ASIC2_CLOCK_EX1              ( 1 << 14 )   /* Enable 24.576 MHz crystal */
-#define H3800_ASIC2_CLOCK_EX2              ( 1 << 15 )   /* Enable 33.869 MHz crystal */
-#define H3800_ASIC2_CLOCK_SLOW_UART_1      ( 1 << 16 )   /* Enable 3.686 MHz to UART1 (turn off bit 8) */
-#define H3800_ASIC2_CLOCK_SLOW_UART_0      ( 1 << 17 )   /* Enable 3.686 MHz to UART0 (turn off bit 9) */
-
-#define _H3800_ASIC2_ADC_Base                  0x1200
-#define _H3800_ASIC2_ADC_Multiplexer           0x0000    /* R/W 4 bits - low 3 bits set channel */
-#define _H3800_ASIC2_ADC_ControlStatus         0x0004    /* R/W 8 bits */
-#define _H3800_ASIC2_ADC_Data                  0x0008    /* R   10 bits */
-
-#define H3800_ASIC2_ADC_Multiplexer       H3800_ASIC2_OFFSET(  u8, ADC, Multiplexer )
-#define H3800_ASIC2_ADC_ControlStatus     H3800_ASIC2_OFFSET(  u8, ADC, ControlStatus )
-#define H3800_ASIC2_ADC_Data              H3800_ASIC2_OFFSET( u16, ADC, Data )
-
-#define H3600_ASIC2_ADC_MUX_CHANNEL_MASK         0x07    /* Low 3 bits sets channel.  max = 4 */
-#define H3600_ASIC2_ADC_MUX_CLKEN          ( 1 << 3 )    /* Enable clock */
-
-#define H3600_ASIC2_ADC_CSR_ADPS_MASK            0x0f    /* Low 4 bits sets prescale, max = 8 */
-#define H3600_ASIC2_ADC_CSR_FREE_RUN       ( 1 << 4 )
-#define H3600_ASIC2_ADC_CSR_INT_ENABLE     ( 1 << 5 )
-#define H3600_ASIC2_ADC_CSR_START          ( 1 << 6 )    /* Set to start conversion.  Goes to 0 when done */
-#define H3600_ASIC2_ADC_CSR_ENABLE         ( 1 << 7 )    /* 1:power up ADC, 0:power down */
-
-
-#define _H3800_ASIC2_INTR_Base                 0x1600
-#define _H3800_ASIC2_INTR_MaskAndFlag          0x0000    /* R/(W) 8bits */
-#define _H3800_ASIC2_INTR_ClockPrescale        0x0004    /* R/(W) 5bits */
-#define _H3800_ASIC2_INTR_TimerSet             0x0008    /* R/(W) 8bits */
-
-#define H3800_ASIC2_INTR_MaskAndFlag      H3800_ASIC2_OFFSET( u8, INTR, MaskAndFlag )
-#define H3800_ASIC2_INTR_ClockPrescale    H3800_ASIC2_OFFSET( u8, INTR, ClockPrescale )
-#define H3800_ASIC2_INTR_TimerSet         H3800_ASIC2_OFFSET( u8, INTR, TimerSet )
-
-#define H3800_ASIC2_INTR_GLOBAL_MASK       ( 1 << 0 )    /* Global interrupt mask */
-#define H3800_ASIC2_INTR_POWER_ON_RESET    ( 1 << 1 )    /* 01: Power on reset (bits 1 & 2 ) */
-#define H3800_ASIC2_INTR_EXTERNAL_RESET    ( 2 << 1 )    /* 10: External reset (bits 1 & 2 ) */
-#define H3800_ASIC2_INTR_MASK_UART_0       ( 1 << 4 )
-#define H3800_ASIC2_INTR_MASK_UART_1       ( 1 << 5 )
-#define H3800_ASIC2_INTR_MASK_TIMER        ( 1 << 6 )
-#define H3800_ASIC2_INTR_MASK_OWM          ( 1 << 7 )
-
-#define H3800_ASIC2_INTR_CLOCK_PRESCALE          0x0f    /* 4 bits, max 14 */
-#define H3800_ASIC2_INTR_SET               ( 1 << 4 )    /* Time base enable */
-
-
-#define _H3800_ASIC2_OWM_Base                  0x1800
-#define _H3800_ASIC2_OWM_Command               0x0000    /* R/W 4 bits command register */
-#define _H3800_ASIC2_OWM_Data                  0x0004    /* R/W 8 bits, transmit / receive buffer */
-#define _H3800_ASIC2_OWM_Interrupt             0x0008    /* R/W Command register */
-#define _H3800_ASIC2_OWM_InterruptEnable       0x000c    /* R/W Command register */
-#define _H3800_ASIC2_OWM_ClockDivisor          0x0010    /* R/W 5 bits of divisor and pre-scale */
-
-#define H3800_ASIC2_OWM_Command            H3800_ASIC2_OFFSET( u8, OWM, Command )
-#define H3800_ASIC2_OWM_Data               H3800_ASIC2_OFFSET( u8, OWM, Data )
-#define H3800_ASIC2_OWM_Interrupt          H3800_ASIC2_OFFSET( u8, OWM, Interrupt )
-#define H3800_ASIC2_OWM_InterruptEnable    H3800_ASIC2_OFFSET( u8, OWM, InterruptEnable )
-#define H3800_ASIC2_OWM_ClockDivisor       H3800_ASIC2_OFFSET( u8, OWM, ClockDivisor )
-
-#define H3800_ASIC2_OWM_CMD_ONE_WIRE_RESET ( 1 << 0 )    /* Set to force reset on 1-wire bus */
-#define H3800_ASIC2_OWM_CMD_SRA            ( 1 << 1 )    /* Set to switch to Search ROM accelerator mode */
-#define H3800_ASIC2_OWM_CMD_DQ_OUTPUT      ( 1 << 2 )    /* Write only - forces bus low */
-#define H3800_ASIC2_OWM_CMD_DQ_INPUT       ( 1 << 3 )    /* Read only - reflects state of bus */
-
-#define H3800_ASIC2_OWM_INT_PD             ( 1 << 0 )    /* Presence detect */
-#define H3800_ASIC2_OWM_INT_PDR            ( 1 << 1 )    /* Presence detect result */
-#define H3800_ASIC2_OWM_INT_TBE            ( 1 << 2 )    /* Transmit buffer empty */
-#define H3800_ASIC2_OWM_INT_TEMT           ( 1 << 3 )    /* Transmit shift register empty */
-#define H3800_ASIC2_OWM_INT_RBF            ( 1 << 4 )    /* Receive buffer full */
-
-#define H3800_ASIC2_OWM_INTEN_EPD          ( 1 << 0 )    /* Enable receive buffer full interrupt */
-#define H3800_ASIC2_OWM_INTEN_IAS          ( 1 << 1 )    /* Enable transmit shift register empty interrupt */
-#define H3800_ASIC2_OWM_INTEN_ETBE         ( 1 << 2 )    /* Enable transmit buffer empty interrupt */
-#define H3800_ASIC2_OWM_INTEN_ETMT         ( 1 << 3 )    /* INTR active state */
-#define H3800_ASIC2_OWM_INTEN_ERBF         ( 1 << 4 )    /* Enable presence detect interrupt */
-
-#define _H3800_ASIC2_FlashCtl_Base             0x1A00
-
-/****************************************************/
-/* H3800, ASIC #1
- * This ASIC is accesed through ASIC #2, and
- * mapped into the 1c00 - 1f00 region
- */
-
-#define H3800_ASIC1_OFFSET(s,x,y)   \
-     (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC1_ ## x ## _Base + (_H3800_ASIC1_ ## x ## _ ## y << 1))))
-
-#define _H3800_ASIC1_MMC_Base             0x1c00
-
-#define _H3800_ASIC1_MMC_StartStopClock     0x00    /* R/W 8bit                                  */
-#define _H3800_ASIC1_MMC_Status             0x02    /* R   See below, default 0x0040             */
-#define _H3800_ASIC1_MMC_ClockRate          0x04    /* R/W 8bit, low 3 bits are clock divisor    */
-#define _H3800_ASIC1_MMC_SPIRegister        0x08    /* R/W 8bit, see below                       */
-#define _H3800_ASIC1_MMC_CmdDataCont        0x0a    /* R/W 8bit, write to start MMC adapter      */
-#define _H3800_ASIC1_MMC_ResponseTimeout    0x0c    /* R/W 8bit, clocks before response timeout  */
-#define _H3800_ASIC1_MMC_ReadTimeout        0x0e    /* R/W 16bit, clocks before received data timeout */
-#define _H3800_ASIC1_MMC_BlockLength        0x10    /* R/W 10bit */
-#define _H3800_ASIC1_MMC_NumOfBlocks        0x12    /* R/W 16bit, in block mode, number of blocks  */
-#define _H3800_ASIC1_MMC_InterruptMask      0x1a    /* R/W 8bit */
-#define _H3800_ASIC1_MMC_CommandNumber      0x1c    /* R/W 6 bits */
-#define _H3800_ASIC1_MMC_ArgumentH          0x1e    /* R/W 16 bits  */
-#define _H3800_ASIC1_MMC_ArgumentL          0x20    /* R/W 16 bits */
-#define _H3800_ASIC1_MMC_ResFifo            0x22    /* R   8 x 16 bits - contains response FIFO */
-#define _H3800_ASIC1_MMC_BufferPartFull     0x28    /* R/W 8 bits */
-
-#define H3800_ASIC1_MMC_StartStopClock    H3800_ASIC1_OFFSET(  u8, MMC, StartStopClock )
-#define H3800_ASIC1_MMC_Status            H3800_ASIC1_OFFSET( u16, MMC, Status )
-#define H3800_ASIC1_MMC_ClockRate         H3800_ASIC1_OFFSET(  u8, MMC, ClockRate )
-#define H3800_ASIC1_MMC_SPIRegister       H3800_ASIC1_OFFSET(  u8, MMC, SPIRegister )
-#define H3800_ASIC1_MMC_CmdDataCont       H3800_ASIC1_OFFSET(  u8, MMC, CmdDataCont )
-#define H3800_ASIC1_MMC_ResponseTimeout   H3800_ASIC1_OFFSET(  u8, MMC, ResponseTimeout )
-#define H3800_ASIC1_MMC_ReadTimeout       H3800_ASIC1_OFFSET( u16, MMC, ReadTimeout )
-#define H3800_ASIC1_MMC_BlockLength       H3800_ASIC1_OFFSET( u16, MMC, BlockLength )
-#define H3800_ASIC1_MMC_NumOfBlocks       H3800_ASIC1_OFFSET( u16, MMC, NumOfBlocks )
-#define H3800_ASIC1_MMC_InterruptMask     H3800_ASIC1_OFFSET(  u8, MMC, InterruptMask )
-#define H3800_ASIC1_MMC_CommandNumber     H3800_ASIC1_OFFSET(  u8, MMC, CommandNumber )
-#define H3800_ASIC1_MMC_ArgumentH         H3800_ASIC1_OFFSET( u16, MMC, ArgumentH )
-#define H3800_ASIC1_MMC_ArgumentL         H3800_ASIC1_OFFSET( u16, MMC, ArgumentL )
-#define H3800_ASIC1_MMC_ResFifo           H3800_ASIC1_OFFSET( u16, MMC, ResFifo )
-#define H3800_ASIC1_MMC_BufferPartFull    H3800_ASIC1_OFFSET(  u8, MMC, BufferPartFull )
-
-#define H3800_ASIC1_MMC_STOP_CLOCK                   (1 << 0)   /* Write to "StartStopClock" register */
-#define H3800_ASIC1_MMC_START_CLOCK                  (1 << 1)
-
-#define H3800_ASIC1_MMC_STATUS_READ_TIMEOUT          (1 << 0)
-#define H3800_ASIC1_MMC_STATUS_RESPONSE_TIMEOUT      (1 << 1)
-#define H3800_ASIC1_MMC_STATUS_CRC_WRITE_ERROR       (1 << 2)
-#define H3800_ASIC1_MMC_STATUS_CRC_READ_ERROR        (1 << 3)
-#define H3800_ASIC1_MMC_STATUS_SPI_READ_ERROR        (1 << 4)  /* SPI data token error received */
-#define H3800_ASIC1_MMC_STATUS_CRC_RESPONSE_ERROR    (1 << 5)
-#define H3800_ASIC1_MMC_STATUS_FIFO_EMPTY            (1 << 6)
-#define H3800_ASIC1_MMC_STATUS_FIFO_FULL             (1 << 7)
-#define H3800_ASIC1_MMC_STATUS_CLOCK_ENABLE          (1 << 8)  /* MultiMediaCard clock stopped */
-#define H3800_ASIC1_MMC_STATUS_DATA_TRANSFER_DONE    (1 << 11) /* Write operation, indicates transfer finished */
-#define H3800_ASIC1_MMC_STATUS_END_PROGRAM           (1 << 12) /* End write and read operations */
-#define H3800_ASIC1_MMC_STATUS_END_COMMAND_RESPONSE  (1 << 13) /* End command response */
-
-#define H3800_ASIC1_MMC_SPI_REG_SPI_ENABLE           (1 << 0)  /* Enables SPI mode */
-#define H3800_ASIC1_MMC_SPI_REG_CRC_ON               (1 << 1)  /* 1:turn on CRC    */
-#define H3800_ASIC1_MMC_SPI_REG_SPI_CS_ENABLE        (1 << 2)  /* 1:turn on SPI CS */
-#define H3800_ASIC1_MMC_SPI_REG_CS_ADDRESS_MASK      0x38      /* Bits 3,4,5 are the SPI CS relative address */
-
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_NO_RESPONSE  0x00
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R1           0x01
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R2           0x02
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R3           0x03
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_DATA_ENABLE         (1 << 2)  /* This command contains a data transfer */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_WRITE               (1 << 3)  /* This data transfer is a write */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_STREAM_MODE         (1 << 4)  /* This data transfer is in stream mode */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_BUSY_BIT            (1 << 5)  /* Busy signal expected after current cmd */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_INITIALIZE          (1 << 6)  /* Enables the 80 bits for initializing card */
-
-#define H3800_ASIC1_MMC_INT_MASK_DATA_TRANSFER_DONE       (1 << 0)
-#define H3800_ASIC1_MMC_INT_MASK_PROGRAM_DONE             (1 << 1)
-#define H3800_ASIC1_MMC_INT_MASK_END_COMMAND_RESPONSE     (1 << 2)
-#define H3800_ASIC1_MMC_INT_MASK_BUFFER_READY             (1 << 3)
-
-#define H3800_ASIC1_MMC_BUFFER_PART_FULL                  (1 << 0)
-
-/********* GPIO **********/
-
-#define _H3800_ASIC1_GPIO_Base        0x1e00
-
-#define _H3800_ASIC1_GPIO_Mask          0x30    /* R/W 0:don't mask, 1:mask interrupt */
-#define _H3800_ASIC1_GPIO_Direction     0x32    /* R/W 0:input, 1:output              */
-#define _H3800_ASIC1_GPIO_Out           0x34    /* R/W 0:output low, 1:output high    */
-#define _H3800_ASIC1_GPIO_TriggerType   0x36    /* R/W 0:level, 1:edge                */
-#define _H3800_ASIC1_GPIO_EdgeTrigger   0x38    /* R/W 0:falling, 1:rising            */
-#define _H3800_ASIC1_GPIO_LevelTrigger  0x3A    /* R/W 0:low, 1:high level detect     */
-#define _H3800_ASIC1_GPIO_LevelStatus   0x3C    /* R/W 0:none, 1:detect               */
-#define _H3800_ASIC1_GPIO_EdgeStatus    0x3E    /* R/W 0:none, 1:detect               */
-#define _H3800_ASIC1_GPIO_State         0x40    /* R   See masks below  (default 0)         */
-#define _H3800_ASIC1_GPIO_Reset         0x42    /* R/W See masks below  (default 0x04)      */
-#define _H3800_ASIC1_GPIO_SleepMask     0x44    /* R/W 0:don't mask, 1:mask trigger in sleep mode  */
-#define _H3800_ASIC1_GPIO_SleepDir      0x46    /* R/W direction 0:input, 1:output in sleep mode    */
-#define _H3800_ASIC1_GPIO_SleepOut      0x48    /* R/W level 0:low, 1:high in sleep mode           */
-#define _H3800_ASIC1_GPIO_Status        0x4A    /* R   Pin status                                  */
-#define _H3800_ASIC1_GPIO_BattFaultDir  0x4C    /* R/W direction 0:input, 1:output in batt_fault   */
-#define _H3800_ASIC1_GPIO_BattFaultOut  0x4E    /* R/W level 0:low, 1:high in batt_fault           */
-
-#define H3800_ASIC1_GPIO_Mask         H3800_ASIC1_OFFSET( u16, GPIO, Mask )
-#define H3800_ASIC1_GPIO_Direction    H3800_ASIC1_OFFSET( u16, GPIO, Direction )
-#define H3800_ASIC1_GPIO_Out          H3800_ASIC1_OFFSET( u16, GPIO, Out )
-#define H3800_ASIC1_GPIO_TriggerType  H3800_ASIC1_OFFSET( u16, GPIO, TriggerType )
-#define H3800_ASIC1_GPIO_EdgeTrigger  H3800_ASIC1_OFFSET( u16, GPIO, EdgeTrigger )
-#define H3800_ASIC1_GPIO_LevelTrigger H3800_ASIC1_OFFSET( u16, GPIO, LevelTrigger )
-#define H3800_ASIC1_GPIO_LevelStatus  H3800_ASIC1_OFFSET( u16, GPIO, LevelStatus )
-#define H3800_ASIC1_GPIO_EdgeStatus   H3800_ASIC1_OFFSET( u16, GPIO, EdgeStatus )
-#define H3800_ASIC1_GPIO_State        H3800_ASIC1_OFFSET(  u8, GPIO, State )
-#define H3800_ASIC1_GPIO_Reset        H3800_ASIC1_OFFSET(  u8, GPIO, Reset )
-#define H3800_ASIC1_GPIO_SleepMask    H3800_ASIC1_OFFSET( u16, GPIO, SleepMask )
-#define H3800_ASIC1_GPIO_SleepDir     H3800_ASIC1_OFFSET( u16, GPIO, SleepDir )
-#define H3800_ASIC1_GPIO_SleepOut     H3800_ASIC1_OFFSET( u16, GPIO, SleepOut )
-#define H3800_ASIC1_GPIO_Status       H3800_ASIC1_OFFSET( u16, GPIO, Status )
-#define H3800_ASIC1_GPIO_BattFaultDir H3800_ASIC1_OFFSET( u16, GPIO, BattFaultDir )
-#define H3800_ASIC1_GPIO_BattFaultOut H3800_ASIC1_OFFSET( u16, GPIO, BattFaultOut )
-
-#define H3800_ASIC1_GPIO_STATE_MASK            (1 << 0)
-#define H3800_ASIC1_GPIO_STATE_DIRECTION       (1 << 1)
-#define H3800_ASIC1_GPIO_STATE_OUT             (1 << 2)
-#define H3800_ASIC1_GPIO_STATE_TRIGGER_TYPE    (1 << 3)
-#define H3800_ASIC1_GPIO_STATE_EDGE_TRIGGER    (1 << 4)
-#define H3800_ASIC1_GPIO_STATE_LEVEL_TRIGGER   (1 << 5)
-
-#define H3800_ASIC1_GPIO_RESET_SOFTWARE        (1 << 0)
-#define H3800_ASIC1_GPIO_RESET_AUTO_SLEEP      (1 << 1)
-#define H3800_ASIC1_GPIO_RESET_FIRST_PWR_ON    (1 << 2)
-
-/* These are all outputs */
-#define GPIO_H3800_ASIC1_IR_ON_N          (1 << 0)   /* Apply power to the IR Module */
-#define GPIO_H3800_ASIC1_SD_PWR_ON        (1 << 1)   /* Secure Digital power on */
-#define GPIO_H3800_ASIC1_RS232_ON         (1 << 2)   /* Turn on power to the RS232 chip ? */
-#define GPIO_H3800_ASIC1_PULSE_GEN        (1 << 3)   /* Goes to speaker / earphone */
-#define GPIO_H3800_ASIC1_CH_TIMER         (1 << 4)   /* */
-#define GPIO_H3800_ASIC1_LCD_5V_ON        (1 << 5)   /* Enables LCD_5V */
-#define GPIO_H3800_ASIC1_LCD_ON           (1 << 6)   /* Enables LCD_3V */
-#define GPIO_H3800_ASIC1_LCD_PCI          (1 << 7)   /* Connects to PDWN on LCD controller */
-#define GPIO_H3800_ASIC1_VGH_ON           (1 << 8)   /* Drives VGH on the LCD (+9??) */
-#define GPIO_H3800_ASIC1_VGL_ON           (1 << 9)   /* Drivers VGL on the LCD (-6??) */
-#define GPIO_H3800_ASIC1_FL_PWR_ON        (1 << 10)  /* Frontlight power on */
-#define GPIO_H3800_ASIC1_BT_PWR_ON        (1 << 11)  /* Bluetooth power on */
-#define GPIO_H3800_ASIC1_SPK_ON           (1 << 12)  /* */
-#define GPIO_H3800_ASIC1_EAR_ON_N         (1 << 13)  /* */
-#define GPIO_H3800_ASIC1_AUD_PWR_ON       (1 << 14)  /* */
-
-/* Write enable for the flash */
-
-#define _H3800_ASIC1_FlashWP_Base         0x1F00
-#define _H3800_ASIC1_FlashWP_VPP_ON         0x00    /* R   1: write, 0: protect */
-#define H3800_ASIC1_FlashWP_VPP_ON       H3800_ASIC1_OFFSET( u8, FlashWP, VPP_ON )
 
 #endif /* _INCLUDE_H3600_GPIO_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/h3600.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@ typedef int __bitwise pm_request_t;
 #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() || machine_is_h3800())
+#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)
@@ -93,76 +93,7 @@ enum ipaq_egpio_type {
 	IPAQ_EGPIO_LCD_ENABLE,	  /* Enable/disable LCD controller */
 };
 
-struct ipaq_model_ops {
-	const char     *generic_name;
-	void	      (*control)(enum ipaq_egpio_type, int);
-	unsigned long (*read)(void);
-	void	      (*blank_callback)(int blank);
-	int	      (*pm_callback)(int req);	    /* Primary model callback */
-	int	      (*pm_callback_aux)(int req);  /* Secondary callback (used by HAL modules) */
-};
-
-extern struct ipaq_model_ops ipaq_model_ops;
-
-static __inline__ const char * h3600_generic_name(void)
-{
-	return ipaq_model_ops.generic_name;
-}
-
-static __inline__ void assign_h3600_egpio(enum ipaq_egpio_type x, int level)
-{
-	if (ipaq_model_ops.control)
-		ipaq_model_ops.control(x,level);
-}
-
-static __inline__ void clr_h3600_egpio(enum ipaq_egpio_type x)
-{
-	if (ipaq_model_ops.control)
-		ipaq_model_ops.control(x,0);
-}
-
-static __inline__ void set_h3600_egpio(enum ipaq_egpio_type x)
-{
-	if (ipaq_model_ops.control)
-		ipaq_model_ops.control(x,1);
-}
-
-static __inline__ unsigned long read_h3600_egpio(void)
-{
-	if (ipaq_model_ops.read)
-		return ipaq_model_ops.read();
-	return 0;
-}
-
-static __inline__ int  h3600_register_blank_callback(void (*f)(int))
-{
-	ipaq_model_ops.blank_callback = f;
-	return 0;
-}
-
-static __inline__ void h3600_unregister_blank_callback(void (*f)(int))
-{
-	ipaq_model_ops.blank_callback = NULL;
-}
-
-
-static __inline__ int  h3600_register_pm_callback(int (*f)(int))
-{
-	ipaq_model_ops.pm_callback_aux = f;
-	return 0;
-}
-
-static __inline__ void h3600_unregister_pm_callback(int (*f)(int))
-{
-	ipaq_model_ops.pm_callback_aux = NULL;
-}
-
-static __inline__ int h3600_power_management(int req)
-{
-	if (ipaq_model_ops.pm_callback)
-		return ipaq_model_ops.pm_callback(req);
-	return 0;
-}
+extern void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
 
 #endif /* ASSEMBLY */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -153,8 +153,6 @@
  */
 #ifdef CONFIG_SA1111
 #define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SA1100_H3800)
-#define NR_IRQS			(IRQ_BOARD_END)
 #elif defined(CONFIG_SHARP_LOCOMO)
 #define NR_IRQS			(IRQ_LOCOMO_SPI_TEND + 1)
 #else
@@ -175,23 +173,3 @@
 #define IRQ_LOCOMO_LT_BASE	(IRQ_BOARD_START + 2)
 #define IRQ_LOCOMO_SPI_BASE	(IRQ_BOARD_START + 3)
 
-/* H3800-specific IRQs (CONFIG_SA1100_H3800) */
-#define H3800_KPIO_IRQ_START    (IRQ_BOARD_START)
-#define IRQ_H3800_KEY           (IRQ_BOARD_START + 0)
-#define IRQ_H3800_SPI           (IRQ_BOARD_START + 1)
-#define IRQ_H3800_OWM           (IRQ_BOARD_START + 2)
-#define IRQ_H3800_ADC           (IRQ_BOARD_START + 3)
-#define IRQ_H3800_UART_0        (IRQ_BOARD_START + 4)
-#define IRQ_H3800_UART_1        (IRQ_BOARD_START + 5)
-#define IRQ_H3800_TIMER_0       (IRQ_BOARD_START + 6)
-#define IRQ_H3800_TIMER_1       (IRQ_BOARD_START + 7)
-#define IRQ_H3800_TIMER_2       (IRQ_BOARD_START + 8)
-#define H3800_KPIO_IRQ_COUNT    9
-
-#define H3800_GPIO_IRQ_START    (IRQ_BOARD_START + 9)
-#define IRQ_H3800_PEN           (IRQ_BOARD_START + 9)
-#define IRQ_H3800_SD_DETECT     (IRQ_BOARD_START + 10)
-#define IRQ_H3800_EAR_IN        (IRQ_BOARD_START + 11)
-#define IRQ_H3800_USB_DETECT    (IRQ_BOARD_START + 12)
-#define IRQ_H3800_SD_CON_SLT    (IRQ_BOARD_START + 13)
-#define H3800_GPIO_IRQ_COUNT    5
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	if (mode == 's') {
 		/* Jump into ROM at address 0 */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/jornada720.c linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/jornada720.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/jornada720.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/jornada720.c	2009-06-09 23:05:27.000000000 -0400
@@ -226,12 +226,22 @@ static struct platform_device jornada_ss
 	.id             = -1,
 };
 
+static struct platform_device jornada_kbd_device = {
+	.name		= "jornada720_kbd",
+	.id		= -1,
+};
+
+static struct platform_device jornada_ts_device = {
+	.name		= "jornada_ts",
+	.id		= -1,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&sa1111_device,
-#ifdef CONFIG_SA1100_JORNADA720_SSP
 	&jornada_ssp_device,
-#endif
 	&s1d13xxxfb_device,
+	&jornada_kbd_device,
+	&jornada_ts_device,
 };
 
 static int __init jornada720_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -71,19 +71,9 @@ config SA1100_H3600
 	  <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
 	  <http://www.compaq.com/products/handhelds/pocketpc/>
 
-config SA1100_H3800
-	bool "Compaq iPAQ H3800"
-	help
-	  Say Y here if you intend to run this kernel on the Compaq iPAQ H3800
-	  series 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_H3800>
-	  <http://www.compaq.com/products/handhelds/pocketpc/>
-
 config SA1100_H3XXX
 	bool
-	depends on SA1100_H3100 || SA1100_H3600 || SA1100_H3800
+	depends on SA1100_H3100 || SA1100_H3600
 	default y
 
 config SA1100_BADGE4
@@ -157,15 +147,6 @@ config SA1100_SSP
 	  This isn't for audio support, but for attached sensors and
 	  other devices, eg for BadgePAD 4 sensor support.
 
-config H3600_SLEEVE
-	tristate "Compaq iPAQ Handheld sleeve support"
-	depends on SA1100_H3100 || SA1100_H3600
-	help
-	  Choose this option to enable support for extension packs (sleeves)
-	  for the Compaq iPAQ H3XXX series of handheld computers.  This option
-	  is required for the CF, PCMCIA, Bluetooth and GSM/GPRS extension
-	  packs.
-
 endmenu
 
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/lart.c linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/lart.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-sa1100/lart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-sa1100/lart.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 #include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
+#include <asm/page.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/core.c linux-libre-2.6.30-gnu1/arch/arm/mach-shark/core.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,12 +16,28 @@
 #include <asm/leds.h>
 #include <asm/param.h>
 
-#include <mach/hardware.h>
-
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 
+#define IO_BASE                 0xe0000000
+#define IO_SIZE                 0x08000000
+#define IO_START                0x40000000
+#define ROMCARD_SIZE            0x08000000
+#define ROMCARD_START           0x10000000
+
+void arch_reset(char mode, const char *cmd)
+{
+        short temp;
+        local_irq_disable();
+        /* Reset the Machine via pc[3] of the sequoia chipset */
+        outw(0x09,0x24);
+        temp=inw(0x26);
+        temp = temp | (1<<3) | (1<<10);
+        outw(0x09,0x24);
+        outw(temp,0x26);
+}
+
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
 		.iobase		= 0x3f8,
@@ -50,14 +66,38 @@ static struct platform_device serial_dev
 	},
 };
 
+static struct resource rtc_resources[] = {
+	[0] = {
+		.start	= 0x70,
+		.end	= 0x73,
+		.flags	= IORESOURCE_IO,
+	},
+	[1] = {
+		.start	= IRQ_ISA_RTC_ALARM,
+		.end	= IRQ_ISA_RTC_ALARM,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device rtc_device = {
+	.name		= "rtc_cmos",
+	.id		= -1,
+	.resource	= rtc_resources,
+	.num_resources	= ARRAY_SIZE(rtc_resources),
+};
+
 static int __init shark_init(void)
 {
 	int ret;
 
 	if (machine_is_shark())
+	{
+	        ret = platform_device_register(&rtc_device);
+		if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret);
 		ret = platform_device_register(&serial_device);
-
-	return ret;
+		if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret);
+	}
+	return 0;
 }
 
 arch_initcall(shark_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/dma.c linux-libre-2.6.30-gnu1/arch/arm/mach-shark/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,9 +13,11 @@
 #include <asm/dma.h>
 #include <asm/mach/dma.h>
 
-void __init arch_dma_init(dma_t *dma)
+static int __init shark_dma_init(void)
 {
 #ifdef CONFIG_ISA_DMA
-	isa_init_dma(dma);
+	isa_init_dma();
 #endif
+	return 0;
 }
+core_initcall(shark_dma_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/debug-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -27,5 +27,3 @@
 		bne	1001b
 		.endm
 
-		.macro	waituart,rd,rx
-		.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/framebuffer.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/framebuffer.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/framebuffer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/framebuffer.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-shark/include/mach/framebuffer.h
+ *
+ * by Alexander Schulz
+ *
+ */
+
+#ifndef __ASM_ARCH_FRAMEBUFFER_H
+#define __ASM_ARCH_FRAMEBUFFER_H
+
+/* defines for the Framebuffer */
+#define FB_START		0x06000000
+#define FB_SIZE			0x01000000
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/hardware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,35 +10,8 @@
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-#ifndef __ASSEMBLY__
-
-/*
- * Mapping areas
- */
-#define IO_BASE			0xe0000000
-
-#else
-
-#define IO_BASE			0
-
-#endif
-
-#define IO_SIZE			0x08000000
-#define IO_START		0x40000000
-#define ROMCARD_SIZE		0x08000000
-#define ROMCARD_START		0x10000000
-
-
-/* defines for the Framebuffer */
-#define FB_START		0x06000000
-#define FB_SIZE			0x01000000
-
 #define UNCACHEABLE_ADDR        0xdf010000
 
-#define SEQUOIA_LED_GREEN       (1<<6)
-#define SEQUOIA_LED_AMBER       (1<<5)
-#define SEQUOIA_LED_BACK        (1<<7)
-
 #define pcibios_assign_all_busses()     1
 
 #define PCIBIOS_MIN_IO          0x6000
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/io.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/io.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,10 +11,10 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define PCIO_BASE	0xe0000000
-#define IO_SPACE_LIMIT	0xffffffff
+#define IO_SPACE_LIMIT 0xffffffff
 
-#define __io(a)		((void __iomem *)(PCIO_BASE + (a)))
-#define __mem_pci(addr)	(addr)
+#define __io(a)                 ((void __iomem *)(0xe0000000 + (a)))
+
+#define __mem_pci(addr) (addr)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
 #define NR_IRQS			16
 
 #define IRQ_ISA_KEYBOARD	 1
-#define RTC_IRQ			 8
+#define IRQ_ISA_RTC_ALARM	 8
 #define I8042_KBD_IRQ		 1
 #define I8042_AUX_IRQ		12
 #define IRQ_HARDDISK            14
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/isa-dma.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/isa-dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/isa-dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/isa-dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,10 +6,6 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-/* Use only the lowest 4MB, nothing else works.
- * The rest is not DMAable. See dev /  .properties
- * in OpenFirmware.
- */
 #define MAX_DMA_CHANNELS	8
 #define DMA_ISA_CASCADE         4
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@ static inline void __arch_adjust_zones(i
 {
   if (node != 0) return;
   /* Only the first 4 MB (=1024 Pages) are usable for DMA */
+  /* See dev / -> .properties in OpenFirmware. */
   zone_size[1] = zone_size[0] - 1024;
   zone_size[0] = 1024;
   zhole_size[1] = zhole_size[0];
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,20 +6,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <linux/io.h>
-
-static void arch_reset(char mode)
-{
-	short temp;
-	local_irq_disable();
-	/* Reset the Machine via pc[3] of the sequoia chipset */
-	outw(0x09,0x24);
-	temp=inw(0x26);
-	temp = temp | (1<<3) | (1<<10);
-	outw(0x09,0x24);
-	outw(temp,0x26);
-
-}
+/* Found in arch/mach-shark/core.c */
+extern void arch_reset(char mode, const char *cmd);
 
 static inline void arch_idle(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/uncompress.h linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/uncompress.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/include/mach/uncompress.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/include/mach/uncompress.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,7 @@
 
 static inline void putc(int c)
 {
-	int t;
+	volatile int t;
 
 	SERIAL_BASE[0] = c;
 	t=0x10000;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-shark/leds.c linux-libre-2.6.30-gnu1/arch/arm/mach-shark/leds.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-shark/leds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-shark/leds.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,12 +22,16 @@
 #include <linux/ioport.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 
 #define LED_STATE_ENABLED	1
 #define LED_STATE_CLAIMED	2
+
+#define SEQUOIA_LED_GREEN       (1<<6)
+#define SEQUOIA_LED_AMBER       (1<<5)
+#define SEQUOIA_LED_BACK        (1<<7)
+
 static char led_state;
 static short hw_led_state;
 static short saved_state;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-versatile/core.c linux-libre-2.6.30-gnu1/arch/arm/mach-versatile/core.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-versatile/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-versatile/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -335,11 +335,25 @@ static struct resource versatile_i2c_res
 
 static struct platform_device versatile_i2c_device = {
 	.name			= "versatile-i2c",
-	.id			= -1,
+	.id			= 0,
 	.num_resources		= 1,
 	.resource		= &versatile_i2c_resource,
 };
 
+static struct i2c_board_info versatile_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1),
+		.type = "ds1338",
+	},
+};
+
+static int __init versatile_i2c_init(void)
+{
+	return i2c_register_board_info(0, versatile_i2c_board_info,
+				       ARRAY_SIZE(versatile_i2c_board_info));
+}
+arch_initcall(versatile_i2c_init);
+
 #define VERSATILE_SYSMCI	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 
 unsigned int mmc_status(struct device *dev)
@@ -399,7 +413,7 @@ static struct clk ref24_clk = {
 	.rate	= 24000000,
 };
 
-static struct clk_lookup lookups[] __initdata = {
+static struct clk_lookup lookups[] = {
 	{	/* UART0 */
 		.dev_id		= "dev:f1",
 		.clk		= &ref24_clk,
@@ -934,7 +948,7 @@ static struct irqaction versatile_timer_
 	.handler	= versatile_timer_interrupt,
 };
 
-static cycle_t versatile_get_cycles(void)
+static cycle_t versatile_get_cycles(struct clocksource *cs)
 {
 	return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-versatile/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-versatile/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-versatile/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-versatile/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	u32 val;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/cpu.h linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/cpu.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -43,35 +43,16 @@ extern void w90p910_init_io(struct map_d
 extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no);
 extern void w90p910_init_clocks(int xtal);
 extern void w90p910_map_io(struct map_desc *mach_desc, int size);
+extern struct platform_device w90p910_serial_device;
 extern struct sys_timer w90x900_timer;
 
-#define W90X900_RES(name)				\
-struct resource w90x900_##name##_resource[] = {		\
-	[0] = {						\
-		.start = name##_PA,			\
-		.end   = name##_PA + 0x0ff,		\
-		.flags = IORESOURCE_MEM,		\
-	},						\
-	[1] = {						\
-		.start = IRQ_##name,			\
-		.end   = IRQ_##name,			\
-		.flags = IORESOURCE_IRQ,		\
-	}						\
-}
-
-#define W90X900_DEVICE(devname, regname, devid, platdevname)		\
-struct platform_device w90x900_##devname = {				\
-	.name		= platdevname,					\
-	.id		= devid,					\
-	.num_resources 	= ARRAY_SIZE(w90x900_##regname##_resource),	\
-	.resource 	= w90x900_##regname##_resource,			\
-}
-
-#define W90X900_UARTCFG(port, flag, uc, ulc, ufc)	\
-{							\
-		.hwport	= port,				\
-		.flags	= flag,				\
-		.ucon	= uc,				\
-		.ulcon	= ulc,				\
-		.ufcon	= ufc,				\
+#define W90X900_8250PORT(name)					\
+{								\
+	.membase	= name##_BA,				\
+	.mapbase	= name##_PA,				\
+	.irq		= IRQ_##name,				\
+	.uartclk	= 11313600,				\
+	.regshift	= 2,					\
+	.iotype		= UPIO_MEM,				\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,7 @@ static void arch_idle(void)
 {
 }
 
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/mach-w90p910evb.c linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/mach-w90p910evb.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/mach-w90p910evb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/mach-w90p910evb.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,28 +33,67 @@
 #include <mach/map.h>
 
 #include "cpu.h"
+/*w90p910 evb norflash driver data */
 
-static struct map_desc w90p910_iodesc[] __initdata = {
+#define W90P910_FLASH_BASE	0xA0000000
+#define W90P910_FLASH_SIZE	0x400000
+
+static struct mtd_partition w90p910_flash_partitions[] = {
+	{
+		.name	=	"NOR Partition 1 for kernel (960K)",
+		.size	=	0xF0000,
+		.offset	=	0x10000,
+	},
+	{
+		.name	=	"NOR Partition 2 for image (1M)",
+		.size	=	0x100000,
+		.offset	=	0x100000,
+	},
+	{
+		.name	=	"NOR Partition 3 for user (2M)",
+		.size	=	0x200000,
+		.offset	=	0x00200000,
+	}
 };
 
-static struct w90x900_uartcfg w90p910_uartcfgs[] = {
-	W90X900_UARTCFG(0, 0, 0, 0, 0),
-	W90X900_UARTCFG(1, 0, 0, 0, 0),
-	W90X900_UARTCFG(2, 0, 0, 0, 0),
-	W90X900_UARTCFG(3, 0, 0, 0, 0),
-	W90X900_UARTCFG(4, 0, 0, 0, 0),
+static struct physmap_flash_data w90p910_flash_data = {
+	.width		=	2,
+	.parts		=	w90p910_flash_partitions,
+	.nr_parts	=	ARRAY_SIZE(w90p910_flash_partitions),
+};
+
+static struct resource w90p910_flash_resources[] = {
+	{
+		.start	=	W90P910_FLASH_BASE,
+		.end	=	W90P910_FLASH_BASE + W90P910_FLASH_SIZE - 1,
+		.flags	=	IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device w90p910_flash_device = {
+	.name		=	"physmap-flash",
+	.id		=	0,
+	.dev		= {
+				.platform_data = &w90p910_flash_data,
+			},
+	.resource	=	w90p910_flash_resources,
+	.num_resources	=	ARRAY_SIZE(w90p910_flash_resources),
+};
+
+static struct map_desc w90p910_iodesc[] __initdata = {
 };
 
 /*Here should be your evb resourse,such as LCD*/
 
 static struct platform_device *w90p910evb_dev[] __initdata = {
+	&w90p910_serial_device,
+	&w90p910_flash_device,
 };
 
 static void __init w90p910evb_map_io(void)
 {
 	w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
 	w90p910_init_clocks(0);
-	w90p910_init_uarts(w90p910_uartcfgs, ARRAY_SIZE(w90p910_uartcfgs));
 }
 
 static void __init w90p910evb_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/w90p910.c linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/w90p910.c
--- linux-libre-2.6.29-gnu1/arch/arm/mach-w90x900/w90p910.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mach-w90x900/w90p910.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/serial_8250.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -36,12 +37,6 @@
 
 #include "cpu.h"
 
-/*W90P910 has five uarts*/
-
-#define MAX_UART_COUNT 5
-static int uart_count;
-static struct platform_device *uart_devs[MAX_UART_COUNT-1];
-
 /* Initial IO mappings */
 
 static struct map_desc w90p910_iodesc[] __initdata = {
@@ -53,48 +48,19 @@ static struct map_desc w90p910_iodesc[]
 	/*IODESC_ENT(LCD),*/
 };
 
-/*Init the dev resource*/
-
-static W90X900_RES(UART0);
-static W90X900_RES(UART1);
-static W90X900_RES(UART2);
-static W90X900_RES(UART3);
-static W90X900_RES(UART4);
-static W90X900_DEVICE(uart0, UART0, 0, "w90x900-uart");
-static W90X900_DEVICE(uart1, UART1, 1, "w90x900-uart");
-static W90X900_DEVICE(uart2, UART2, 2, "w90x900-uart");
-static W90X900_DEVICE(uart3, UART3, 3, "w90x900-uart");
-static W90X900_DEVICE(uart4, UART4, 4, "w90x900-uart");
+/* Initial serial platform data */
 
-static struct platform_device *uart_devices[] __initdata = {
-	&w90x900_uart0,
-	&w90x900_uart1,
-	&w90x900_uart2,
-	&w90x900_uart3,
-	&w90x900_uart4
+struct plat_serial8250_port w90p910_uart_data[] = {
+	W90X900_8250PORT(UART0),
 };
 
-/*Init W90P910 uart device*/
-
-void __init w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no)
-{
-	struct platform_device *platdev;
-	int uart, uartdev;
-
-	/*By min() to judge count of uart be used indeed*/
-
-	uartdev = ARRAY_SIZE(uart_devices);
-	no = min(uartdev, no);
-
-	for (uart = 0; uart < no; uart++, cfg++) {
-		if (cfg->hwport != uart)
-			printk(KERN_ERR "w90x900_uartcfg[%d] error\n", uart);
-		platdev = uart_devices[cfg->hwport];
-		uart_devs[uart] = platdev;
-		platdev->dev.platform_data = cfg;
-	}
-	uart_count = uart;
-}
+struct platform_device w90p910_serial_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= w90p910_uart_data,
+	},
+};
 
 /*Init W90P910 evb io*/
 
@@ -122,13 +88,6 @@ static int __init w90p910_init_cpu(void)
 
 static int __init w90x900_arch_init(void)
 {
-	int ret;
-
-	ret = w90p910_init_cpu();
-	if (ret != 0)
-		return ret;
-
-	return platform_add_devices(uart_devs, uart_count);
-
+	return w90p910_init_cpu();
 }
 arch_initcall(w90x900_arch_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/Makefile linux-libre-2.6.30-gnu1/arch/arm/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -72,6 +72,7 @@ tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9
 tune-$(CONFIG_CPU_ARM922T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_ARM925T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_FA526)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
@@ -85,6 +86,10 @@ else
 CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
 endif
 
+ifeq ($(CONFIG_ARM_UNWIND),y)
+CFLAGS_ABI	+=-funwind-tables
+endif
+
 # Need -Uarm for gcc < 3.x
 KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
@@ -105,8 +110,11 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
  textofs-$(CONFIG_SA1111)	   := 0x00208000
 endif
  machine-$(CONFIG_ARCH_PXA)	   := pxa
+ machine-$(CONFIG_ARCH_MMP)	   := mmp
+    plat-$(CONFIG_PLAT_PXA)	   := pxa
  machine-$(CONFIG_ARCH_L7200)	   := l7200
  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+ machine-$(CONFIG_ARCH_GEMINI)     := gemini
  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
  machine-$(CONFIG_ARCH_IOP32X)	   := iop32x
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/abort-ev6.S linux-libre-2.6.30-gnu1/arch/arm/mm/abort-ev6.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/abort-ev6.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/abort-ev6.S	2009-06-09 23:05:27.000000000 -0400
@@ -29,10 +29,10 @@ ENTRY(v6_early_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 /*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
  * The test below covers all the write situations, including Java bytecodes
  */
-	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
 	tst	r3, #PSR_J_BIT			@ Java?
 	movne	pc, lr
 	do_thumb_abort
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/cache-fa.S linux-libre-2.6.30-gnu1/arch/arm/mm/cache-fa.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/cache-fa.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/cache-fa.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,220 @@
+/*
+ *  linux/arch/arm/mm/cache-fa.S
+ *
+ *  Copyright (C) 2005 Faraday Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on cache-v4wb.S:
+ *  Copyright (C) 1997-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.
+ *
+ *  Processors: FA520 FA526 FA626	
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE	16
+
+/*
+ * The total size of the data cache.
+ */
+#ifdef CONFIG_ARCH_GEMINI
+#define CACHE_DSIZE	8192
+#else
+#define CACHE_DSIZE	16384 
+#endif 
+
+/* FIXME: put optimal value here. Current one is just estimation */
+#define CACHE_DLIMIT	(CACHE_DSIZE * 2)
+
+/*
+ *	flush_user_cache_all()
+ *
+ *	Clean and invalidate all cache entries in a particular address
+ *	space.
+ */
+ENTRY(fa_flush_user_cache_all)
+	/* FALLTHROUGH */
+/*
+ *	flush_kern_cache_all()
+ *
+ *	Clean and invalidate the entire cache.
+ */
+ENTRY(fa_flush_kern_cache_all)
+	mov	ip, #0
+	mov	r2, #VM_EXEC
+__flush_whole_cache:
+	mcr	p15, 0, ip, c7, c14, 0		@ clean/invalidate D cache
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain write buffer
+	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_range(start, end, flags)
+ *
+ *	Invalidate a range of cache entries in the specified
+ *	address space.
+ *
+ *	- start - start address (inclusive, page aligned)
+ *	- end	- end address (exclusive, page aligned)
+ *	- flags	- vma_area_struct flags describing address space
+ */
+ENTRY(fa_flush_user_cache_range)
+	mov	ip, #0
+	sub	r3, r1, r0			@ calculate total size
+	cmp	r3, #CACHE_DLIMIT		@ total size >= limit?
+	bhs	__flush_whole_cache		@ flush whole D cache
+
+1:	tst	r2, #VM_EXEC
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I line
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 6		@ invalidate BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcrne	p15, 0, ip, c7, c5, 4		@ prefetch flush
+	mov	pc, lr
+
+/*
+ *	coherent_kern_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(fa_coherent_kern_range)
+	/* fall through */
+
+/*
+ *	coherent_user_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(fa_coherent_user_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
+	mov	pc, lr
+
+/*
+ *	flush_kern_dcache_page(kaddr)
+ *
+ *	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)
+ */
+ENTRY(fa_flush_kern_dcache_page)
+	add	r1, r0, #PAGE_SZ
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mov	pc, lr
+
+/*
+ *	dma_inv_range(start, end)
+ *
+ *	Invalidate (discard) the specified virtual address range.
+ *	May not write back any entries.  If 'start' or 'end'
+ *	are not cache line aligned, those lines must be written
+ *	back.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(fa_dma_inv_range)
+	tst	r0, #CACHE_DLINESIZE - 1
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
+	tst	r1, #CACHE_DLINESIZE - 1
+	bic	r1, r1, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r1, c7, c14, 1		@ clean & invalidate D entry
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mov	pc, lr
+
+/*
+ *	dma_clean_range(start, end)
+ *
+ *	Clean (write back) the specified virtual address range.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(fa_dma_clean_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0	
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mov	pc, lr
+
+/*
+ *	dma_flush_range(start,end)
+ *	- start   - virtual start address of region
+ *	- end     - virtual end address of region
+ */
+ENTRY(fa_dma_flush_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0	
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mov	pc, lr
+
+	__INITDATA
+
+	.type	fa_cache_fns, #object
+ENTRY(fa_cache_fns)
+	.long	fa_flush_kern_cache_all
+	.long	fa_flush_user_cache_all
+	.long	fa_flush_user_cache_range
+	.long	fa_coherent_kern_range
+	.long	fa_coherent_user_range
+	.long	fa_flush_kern_dcache_page
+	.long	fa_dma_inv_range
+	.long	fa_dma_clean_range
+	.long	fa_dma_flush_range
+	.size	fa_cache_fns, . - fa_cache_fns
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/cache-feroceon-l2.c linux-libre-2.6.30-gnu1/arch/arm/mm/cache-feroceon-l2.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/cache-feroceon-l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/cache-feroceon-l2.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,8 +14,12 @@
 
 #include <linux/init.h>
 #include <asm/cacheflush.h>
+#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
 #include <plat/cache-feroceon-l2.h>
-
+#include "mm.h"
 
 /*
  * Low-level cache maintenance operations.
@@ -34,14 +38,36 @@
  * The range operations require two successive cp15 writes, in
  * between which we don't want to be preempted.
  */
+
+static inline unsigned long l2_start_va(unsigned long paddr)
+{
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Let's do our own fixmap stuff in a minimal way here.
+	 * Because range ops can't be done on physical addresses,
+	 * we simply install a virtual mapping for it only for the
+	 * TLB lookup to occur, hence no need to flush the untouched
+	 * memory mapping.  This is protected with the disabling of
+	 * interrupts by the caller.
+	 */
+	unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
+	unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
+	local_flush_tlb_kernel_page(vaddr);
+	return vaddr + (paddr & ~PAGE_MASK);
+#else
+	return __phys_to_virt(paddr);
+#endif
+}
+
 static inline void l2_clean_pa(unsigned long addr)
 {
 	__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
 }
 
-static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
+static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
 {
-	unsigned long flags;
+	unsigned long va_start, va_end, flags;
 
 	/*
 	 * Make sure 'start' and 'end' reference the same page, as
@@ -51,17 +77,14 @@ static inline void l2_clean_mva_range(un
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 	raw_local_irq_save(flags);
+	va_start = l2_start_va(start);
+	va_end = va_start + (end - start);
 	__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
 		"mcr p15, 1, %1, c15, c9, 5"
-		: : "r" (start), "r" (end));
+		: : "r" (va_start), "r" (va_end));
 	raw_local_irq_restore(flags);
 }
 
-static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
-{
-	l2_clean_mva_range(__phys_to_virt(start), __phys_to_virt(end));
-}
-
 static inline void l2_clean_inv_pa(unsigned long addr)
 {
 	__asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr));
@@ -72,9 +95,9 @@ static inline void l2_inv_pa(unsigned lo
 	__asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr));
 }
 
-static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
+static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
 {
-	unsigned long flags;
+	unsigned long va_start, va_end, flags;
 
 	/*
 	 * Make sure 'start' and 'end' reference the same page, as
@@ -84,18 +107,19 @@ static inline void l2_inv_mva_range(unsi
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 	raw_local_irq_save(flags);
+	va_start = l2_start_va(start);
+	va_end = va_start + (end - start);
 	__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
 		"mcr p15, 1, %1, c15, c11, 5"
-		: : "r" (start), "r" (end));
+		: : "r" (va_start), "r" (va_end));
 	raw_local_irq_restore(flags);
 }
 
-static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
+static inline void l2_inv_all(void)
 {
-	l2_inv_mva_range(__phys_to_virt(start), __phys_to_virt(end));
+	__asm__("mcr p15, 1, %0, c15, c11, 0" : : "r" (0));
 }
 
-
 /*
  * Linux primitives.
  *
@@ -234,9 +258,7 @@ static void __init enable_dcache(void)
 
 static void __init __invalidate_icache(void)
 {
-	int dummy;
-
-	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
+	__asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
 }
 
 static int __init invalidate_and_disable_icache(void)
@@ -301,6 +323,7 @@ static void __init enable_l2(void)
 
 		d = flush_and_disable_dcache();
 		i = invalidate_and_disable_icache();
+		l2_inv_all();
 		write_extra_features(u | 0x00400000);
 		if (i)
 			enable_icache();
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/cache-v6.S linux-libre-2.6.30-gnu1/arch/arm/mm/cache-v6.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/cache-v6.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/cache-v6.S	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,31 @@
 #define D_CACHE_LINE_SIZE	32
 #define BTB_FLUSH_SIZE		8
 
+#ifdef CONFIG_ARM_ERRATA_411920
+/*
+ * Invalidate the entire I cache (this code is a workaround for the ARM1136
+ * erratum 411920 - Invalidate Instruction Cache operation can fail. This
+ * erratum is present in 1136, 1156 and 1176. It does not affect the MPCore.
+ *
+ * Registers:
+ *   r0 - set to 0
+ *   r1 - corrupted
+ */
+ENTRY(v6_icache_inval_all)
+	mov	r0, #0
+	mrs	r1, cpsr
+	cpsid	ifa				@ disable interrupts
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate entire I-cache
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate entire I-cache
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate entire I-cache
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate entire I-cache
+	msr	cpsr_cx, r1			@ restore interrupts
+	.rept	11				@ ARM Ltd recommends at least
+	nop					@ 11 NOPs
+	.endr
+	mov	pc, lr
+#endif
+
 /*
  *	v6_flush_cache_all()
  *
@@ -31,8 +56,12 @@ ENTRY(v6_flush_kern_cache_all)
 	mov	r0, #0
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c14, 0		@ D cache clean+invalidate
+#ifndef CONFIG_ARM_ERRATA_411920
 	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
 #else
+	b	v6_icache_inval_all
+#endif
+#else
 	mcr	p15, 0, r0, c7, c15, 0		@ Cache clean+invalidate
 #endif
 	mov	pc, lr
@@ -103,8 +132,12 @@ ENTRY(v6_coherent_user_range)
 	mov	r0, #0
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+#ifndef CONFIG_ARM_ERRATA_411920
 	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
 #else
+	b	v6_icache_inval_all
+#endif
+#else
 	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
 #endif
 	mov	pc, lr
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/cache-xsc3l2.c linux-libre-2.6.30-gnu1/arch/arm/mm/cache-xsc3l2.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/cache-xsc3l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/cache-xsc3l2.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,12 +17,14 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
 #include <asm/system.h>
 #include <asm/cputype.h>
 #include <asm/cacheflush.h>
+#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include "mm.h"
 
 #define CR_L2	(1 << 26)
 
@@ -47,21 +49,11 @@ static inline void xsc3_l2_clean_mva(uns
 	__asm__("mcr p15, 1, %0, c7, c11, 1" : : "r" (addr));
 }
 
-static inline void xsc3_l2_clean_pa(unsigned long addr)
-{
-	xsc3_l2_clean_mva(__phys_to_virt(addr));
-}
-
 static inline void xsc3_l2_inv_mva(unsigned long addr)
 {
 	__asm__("mcr p15, 1, %0, c7, c7, 1" : : "r" (addr));
 }
 
-static inline void xsc3_l2_inv_pa(unsigned long addr)
-{
-	xsc3_l2_inv_mva(__phys_to_virt(addr));
-}
-
 static inline void xsc3_l2_inv_all(void)
 {
 	unsigned long l2ctype, set_way;
@@ -79,50 +71,103 @@ static inline void xsc3_l2_inv_all(void)
 	dsb();
 }
 
+#ifdef CONFIG_HIGHMEM
+#define l2_map_save_flags(x)		raw_local_save_flags(x)
+#define l2_map_restore_flags(x)		raw_local_irq_restore(x)
+#else
+#define l2_map_save_flags(x)		((x) = 0)
+#define l2_map_restore_flags(x)		((void)(x))
+#endif
+
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
+				      unsigned long flags)
+{
+#ifdef CONFIG_HIGHMEM
+	unsigned long va = prev_va & PAGE_MASK;
+	unsigned long pa_offset = pa << (32 - PAGE_SHIFT);
+	if (unlikely(pa_offset < (prev_va << (32 - PAGE_SHIFT)))) {
+		/*
+		 * Switching to a new page.  Because cache ops are
+		 * using virtual addresses only, we must put a mapping
+		 * in place for it.  We also enable interrupts for a
+		 * short while and disable them again to protect this
+		 * mapping.
+		 */
+		unsigned long idx;
+		raw_local_irq_restore(flags);
+		idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
+		va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+		raw_local_irq_restore(flags | PSR_I_BIT);
+		set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
+		local_flush_tlb_kernel_page(va);
+	}
+	return va + (pa_offset >> (32 - PAGE_SHIFT));
+#else
+	return __phys_to_virt(pa);
+#endif
+}
+
 static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 {
+	unsigned long vaddr, flags;
+
 	if (start == 0 && end == -1ul) {
 		xsc3_l2_inv_all();
 		return;
 	}
 
+	vaddr = -1;  /* to force the first mapping */
+	l2_map_save_flags(flags);
+
 	/*
 	 * Clean and invalidate partial first cache line.
 	 */
 	if (start & (CACHE_LINE_SIZE - 1)) {
-		xsc3_l2_clean_pa(start & ~(CACHE_LINE_SIZE - 1));
-		xsc3_l2_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
+		vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags);
+		xsc3_l2_clean_mva(vaddr);
+		xsc3_l2_inv_mva(vaddr);
 		start = (start | (CACHE_LINE_SIZE - 1)) + 1;
 	}
 
 	/*
-	 * Clean and invalidate partial last cache line.
+	 * Invalidate all full cache lines between 'start' and 'end'.
 	 */
-	if (start < end && (end & (CACHE_LINE_SIZE - 1))) {
-		xsc3_l2_clean_pa(end & ~(CACHE_LINE_SIZE - 1));
-		xsc3_l2_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
-		end &= ~(CACHE_LINE_SIZE - 1);
+	while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
+		vaddr = l2_map_va(start, vaddr, flags);
+		xsc3_l2_inv_mva(vaddr);
+		start += CACHE_LINE_SIZE;
 	}
 
 	/*
-	 * Invalidate all full cache lines between 'start' and 'end'.
+	 * Clean and invalidate partial last cache line.
 	 */
-	while (start < end) {
-		xsc3_l2_inv_pa(start);
-		start += CACHE_LINE_SIZE;
+	if (start < end) {
+		vaddr = l2_map_va(start, vaddr, flags);
+		xsc3_l2_clean_mva(vaddr);
+		xsc3_l2_inv_mva(vaddr);
 	}
 
+	l2_map_restore_flags(flags);
+
 	dsb();
 }
 
 static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
 {
+	unsigned long vaddr, flags;
+
+	vaddr = -1;  /* to force the first mapping */
+	l2_map_save_flags(flags);
+
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
-		xsc3_l2_clean_pa(start);
+		vaddr = l2_map_va(start, vaddr, flags);
+		xsc3_l2_clean_mva(vaddr);
 		start += CACHE_LINE_SIZE;
 	}
 
+	l2_map_restore_flags(flags);
+
 	dsb();
 }
 
@@ -148,18 +193,26 @@ static inline void xsc3_l2_flush_all(voi
 
 static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
 {
+	unsigned long vaddr, flags;
+
 	if (start == 0 && end == -1ul) {
 		xsc3_l2_flush_all();
 		return;
 	}
 
+	vaddr = -1;  /* to force the first mapping */
+	l2_map_save_flags(flags);
+
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
-		xsc3_l2_clean_pa(start);
-		xsc3_l2_inv_pa(start);
+		vaddr = l2_map_va(start, vaddr, flags);
+		xsc3_l2_clean_mva(vaddr);
+		xsc3_l2_inv_mva(vaddr);
 		start += CACHE_LINE_SIZE;
 	}
 
+	l2_map_restore_flags(flags);
+
 	dsb();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/copypage-fa.c linux-libre-2.6.30-gnu1/arch/arm/mm/copypage-fa.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/copypage-fa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/copypage-fa.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/*
+ *  linux/arch/arm/lib/copypage-fa.S
+ *
+ *  Copyright (C) 2005 Faraday Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on copypage-v4wb.S:
+ *  Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+/*
+ * Faraday optimised copy_user_page
+ */
+static void __naked
+fa_copy_user_page(void *kto, const void *kfrom)
+{
+	asm("\
+	stmfd	sp!, {r4, lr}			@ 2\n\
+	mov	r2, %0				@ 1\n\
+1:	ldmia	r1!, {r3, r4, ip, lr}		@ 4\n\
+	stmia	r0, {r3, r4, ip, lr}		@ 4\n\
+	mcr	p15, 0, r0, c7, c14, 1		@ 1   clean and invalidate D line\n\
+	add	r0, r0, #16			@ 1\n\
+	ldmia	r1!, {r3, r4, ip, lr}		@ 4\n\
+	stmia	r0, {r3, r4, ip, lr}		@ 4\n\
+	mcr	p15, 0, r0, c7, c14, 1		@ 1   clean and invalidate D line\n\
+	add	r0, r0, #16			@ 1\n\
+	subs	r2, r2, #1			@ 1\n\
+	bne	1b				@ 1\n\
+	mcr	p15, 0, r2, c7, c10, 4		@ 1   drain WB\n\
+	ldmfd	sp!, {r4, pc}			@ 3"
+	:
+	: "I" (PAGE_SIZE / 32));
+}
+
+void fa_copy_user_highpage(struct page *to, struct page *from,
+	unsigned long vaddr)
+{
+	void *kto, *kfrom;
+
+	kto = kmap_atomic(to, KM_USER0);
+	kfrom = kmap_atomic(from, KM_USER1);
+	fa_copy_user_page(kto, kfrom);
+	kunmap_atomic(kfrom, KM_USER1);
+	kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * Faraday optimised clear_user_page
+ *
+ * Same story as above.
+ */
+void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	asm volatile("\
+	mov	r1, %2				@ 1\n\
+	mov	r2, #0				@ 1\n\
+	mov	r3, #0				@ 1\n\
+	mov	ip, #0				@ 1\n\
+	mov	lr, #0				@ 1\n\
+1:	stmia	%0, {r2, r3, ip, lr}		@ 4\n\
+	mcr	p15, 0, %0, c7, c14, 1		@ 1   clean and invalidate D line\n\
+	add	%0, %0, #16			@ 1\n\
+	stmia	%0, {r2, r3, ip, lr}		@ 4\n\
+	mcr	p15, 0, %0, c7, c14, 1		@ 1   clean and invalidate D line\n\
+	add	%0, %0, #16			@ 1\n\
+	subs	r1, r1, #1			@ 1\n\
+	bne	1b				@ 1\n\
+	mcr	p15, 0, r1, c7, c10, 4		@ 1   drain WB"
+	: "=r" (ptr)
+	: "0" (kaddr), "I" (PAGE_SIZE / 32)
+	: "r1", "r2", "r3", "ip", "lr");
+	kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns fa_user_fns __initdata = {
+	.cpu_clear_user_highpage = fa_clear_user_highpage,
+	.cpu_copy_user_highpage	= fa_copy_user_highpage,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/dma-mapping.c linux-libre-2.6.30-gnu1/arch/arm/mm/dma-mapping.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/dma-mapping.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/dma-mapping.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/dma-mapping.h>
 
 #include <asm/memory.h>
+#include <asm/highmem.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/sizes.h>
@@ -517,6 +518,74 @@ void dma_cache_maint(const void *start,
 }
 EXPORT_SYMBOL(dma_cache_maint);
 
+static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
+				       size_t size, int direction)
+{
+	void *vaddr;
+	unsigned long paddr;
+	void (*inner_op)(const void *, const void *);
+	void (*outer_op)(unsigned long, unsigned long);
+
+	switch (direction) {
+	case DMA_FROM_DEVICE:		/* invalidate only */
+		inner_op = dmac_inv_range;
+		outer_op = outer_inv_range;
+		break;
+	case DMA_TO_DEVICE:		/* writeback only */
+		inner_op = dmac_clean_range;
+		outer_op = outer_clean_range;
+		break;
+	case DMA_BIDIRECTIONAL:		/* writeback and invalidate */
+		inner_op = dmac_flush_range;
+		outer_op = outer_flush_range;
+		break;
+	default:
+		BUG();
+	}
+
+	if (!PageHighMem(page)) {
+		vaddr = page_address(page) + offset;
+		inner_op(vaddr, vaddr + size);
+	} else {
+		vaddr = kmap_high_get(page);
+		if (vaddr) {
+			vaddr += offset;
+			inner_op(vaddr, vaddr + size);
+			kunmap_high(page);
+		}
+	}
+
+	paddr = page_to_phys(page) + offset;
+	outer_op(paddr, paddr + size);
+}
+
+void dma_cache_maint_page(struct page *page, unsigned long offset,
+			  size_t size, int dir)
+{
+	/*
+	 * A single sg entry may refer to multiple physically contiguous
+	 * pages.  But we still need to process highmem pages individually.
+	 * If highmem is not configured then the bulk of this loop gets
+	 * optimized out.
+	 */
+	size_t left = size;
+	do {
+		size_t len = left;
+		if (PageHighMem(page) && len + offset > PAGE_SIZE) {
+			if (offset >= PAGE_SIZE) {
+				page += offset / PAGE_SIZE;
+				offset %= PAGE_SIZE;
+			}
+			len = PAGE_SIZE - offset;
+		}
+		dma_cache_maint_contiguous(page, offset, len, dir);
+		offset = 0;
+		page++;
+		left -= len;
+	} while (left);
+}
+EXPORT_SYMBOL(dma_cache_maint_page);
+
 /**
  * dma_map_sg - map a set of SG buffers for streaming mode DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -614,7 +683,8 @@ void dma_sync_sg_for_device(struct devic
 			continue;
 
 		if (!arch_is_coherent())
-			dma_cache_maint(sg_virt(s), s->length, dir);
+			dma_cache_maint_page(sg_page(s), s->offset,
+					     s->length, dir);
 	}
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/flush.c linux-libre-2.6.30-gnu1/arch/arm/mm/flush.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/flush.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/flush.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,10 @@
 
 #include "mm.h"
 
+#ifdef CONFIG_ARM_ERRATA_411920
+extern void v6_icache_inval_all(void);
+#endif
+
 #ifdef CONFIG_CPU_CACHE_VIPT
 
 #define ALIAS_FLUSH_START	0xffff4000
@@ -32,10 +36,15 @@ static void flush_pfn_alias(unsigned lon
 
 	asm(	"mcrr	p15, 0, %1, %0, c14\n"
 	"	mcr	p15, 0, %2, c7, c10, 4\n"
+#ifndef CONFIG_ARM_ERRATA_411920
 	"	mcr	p15, 0, %2, c7, c5, 0\n"
+#endif
 	    :
 	    : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
 	    : "cc");
+#ifdef CONFIG_ARM_ERRATA_411920
+	v6_icache_inval_all();
+#endif
 }
 
 void flush_cache_mm(struct mm_struct *mm)
@@ -48,11 +57,16 @@ void flush_cache_mm(struct mm_struct *mm
 
 	if (cache_is_vipt_aliasing()) {
 		asm(	"mcr	p15, 0, %0, c7, c14, 0\n"
+		"	mcr	p15, 0, %0, c7, c10, 4\n"
+#ifndef CONFIG_ARM_ERRATA_411920
 		"	mcr	p15, 0, %0, c7, c5, 0\n"
-		"	mcr	p15, 0, %0, c7, c10, 4"
+#endif
 		    :
 		    : "r" (0)
 		    : "cc");
+#ifdef CONFIG_ARM_ERRATA_411920
+		v6_icache_inval_all();
+#endif
 	}
 }
 
@@ -67,11 +81,16 @@ void flush_cache_range(struct vm_area_st
 
 	if (cache_is_vipt_aliasing()) {
 		asm(	"mcr	p15, 0, %0, c7, c14, 0\n"
+		"	mcr	p15, 0, %0, c7, c10, 4\n"
+#ifndef CONFIG_ARM_ERRATA_411920
 		"	mcr	p15, 0, %0, c7, c5, 0\n"
-		"	mcr	p15, 0, %0, c7, c10, 4"
+#endif
 		    :
 		    : "r" (0)
 		    : "cc");
+#ifdef CONFIG_ARM_ERRATA_411920
+		v6_icache_inval_all();
+#endif
 	}
 }
 
@@ -192,7 +211,7 @@ void flush_dcache_page(struct page *page
 	struct address_space *mapping = page_mapping(page);
 
 #ifndef CONFIG_SMP
-	if (mapping && !mapping_mapped(mapping))
+	if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
 	else
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/highmem.c linux-libre-2.6.30-gnu1/arch/arm/mm/highmem.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/highmem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/highmem.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mm/highmem.c -- ARM highmem support
+ *
+ * Author:	Nicolas Pitre
+ * Created:	september 8, 2008
+ * Copyright:	Marvell Semiconductors 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/module.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <asm/fixmap.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include "mm.h"
+
+void *kmap(struct page *page)
+{
+	might_sleep();
+	if (!PageHighMem(page))
+		return page_address(page);
+	return kmap_high(page);
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+	BUG_ON(in_interrupt());
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+void *kmap_atomic(struct page *page, enum km_type type)
+{
+	unsigned int idx;
+	unsigned long vaddr;
+
+	pagefault_disable();
+	if (!PageHighMem(page))
+		return page_address(page);
+
+	idx = type + KM_TYPE_NR * smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+	/*
+	 * With debugging enabled, kunmap_atomic forces that entry to 0.
+	 * Make sure it was indeed properly unmapped.
+	 */
+	BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+	set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
+	/*
+	 * When debugging is off, kunmap_atomic leaves the previous mapping
+	 * in place, so this TLB flush ensures the TLB is updated with the
+	 * new mapping.
+	 */
+	local_flush_tlb_kernel_page(vaddr);
+
+	return (void *)vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+	unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
+
+	if (kvaddr >= (void *)FIXADDR_START) {
+		__cpuc_flush_dcache_page((void *)vaddr);
+#ifdef CONFIG_DEBUG_HIGHMEM
+		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
+		local_flush_tlb_kernel_page(vaddr);
+#else
+		(void) idx;  /* to kill a warning */
+#endif
+	}
+	pagefault_enable();
+}
+EXPORT_SYMBOL(kunmap_atomic);
+
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+	unsigned int idx;
+	unsigned long vaddr;
+
+	pagefault_disable();
+
+	idx = type + KM_TYPE_NR * smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+	BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+	set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0);
+	local_flush_tlb_kernel_page(vaddr);
+
+	return (void *)vaddr;
+}
+
+struct page *kmap_atomic_to_page(const void *ptr)
+{
+	unsigned long vaddr = (unsigned long)ptr;
+	pte_t *pte;
+
+	if (vaddr < FIXADDR_START)
+		return virt_to_page(ptr);
+
+	pte = TOP_PTE(vaddr);
+	return pte_page(*pte);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/init.c linux-libre-2.6.30-gnu1/arch/arm/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
+#include <linux/highmem.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -485,7 +486,7 @@ void __init mem_init(void)
 	int i, node;
 
 #ifndef CONFIG_DISCONTIGMEM
-	max_mapnr   = virt_to_page(high_memory) - mem_map;
+	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 #endif
 
 	/* this will put all unused low memory onto the freelists */
@@ -504,6 +505,19 @@ void __init mem_init(void)
 				    __phys_to_pfn(__pa(swapper_pg_dir)), NULL);
 #endif
 
+#ifdef CONFIG_HIGHMEM
+	/* set highmem page free */
+	for_each_online_node(node) {
+		for_each_nodebank (i, &meminfo, node) {
+			unsigned long start = bank_pfn_start(&meminfo.bank[i]);
+			unsigned long end = bank_pfn_end(&meminfo.bank[i]);
+			if (start >= max_low_pfn + PHYS_PFN_OFFSET)
+				totalhigh_pages += free_area(start, end, NULL);
+		}
+	}
+	totalram_pages += totalhigh_pages;
+#endif
+
 	/*
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
@@ -521,9 +535,10 @@ void __init mem_init(void)
 	initsize = __init_end - __init_begin;
 
 	printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
-		"%dK data, %dK init)\n",
+		"%dK data, %dK init, %luK highmem)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-		codesize >> 10, datasize >> 10, initsize >> 10);
+		codesize >> 10, datasize >> 10, initsize >> 10,
+		(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
 
 	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
 		extern int sysctl_overcommit_memory;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/Kconfig linux-libre-2.6.30-gnu1/arch/arm/mm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/mm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -186,6 +186,24 @@ config CPU_ARM926T
 	  Say Y if you want support for the ARM926T processor.
 	  Otherwise, say N.
 
+# FA526
+config CPU_FA526
+	bool
+	select CPU_32v4
+	select CPU_ABRT_EV4
+	select CPU_PABRT_NOIFAR
+	select CPU_CACHE_VIVT
+	select CPU_CP15_MMU
+	select CPU_CACHE_FA
+	select CPU_COPY_FA if MMU
+	select CPU_TLB_FA if MMU
+	help
+	  The FA526 is a version of the ARMv4 compatible processor with
+	  Branch Target Buffer, Unified TLB and cache line size 16.
+
+	  Say Y if you want support for the FA526 processor.
+	  Otherwise, say N.
+
 # ARM940T
 config CPU_ARM940T
 	bool "Support ARM940T processor" if ARCH_INTEGRATOR
@@ -340,6 +358,17 @@ config CPU_XSC3
 	select CPU_TLB_V4WBI if MMU
 	select IO_36
 
+# Marvell PJ1 (Mohawk)
+config CPU_MOHAWK
+	bool
+	select CPU_32v5
+	select CPU_ABRT_EV5T
+	select CPU_PABRT_NOIFAR
+	select CPU_CACHE_VIVT
+	select CPU_CP15_MMU
+	select CPU_TLB_V4WBI if MMU
+	select CPU_COPY_V4WB if MMU
+
 # Feroceon
 config CPU_FEROCEON
 	bool
@@ -484,6 +513,9 @@ config CPU_CACHE_VIVT
 config CPU_CACHE_VIPT
 	bool
 
+config CPU_CACHE_FA
+	bool
+
 if MMU
 # The copy-page model
 config CPU_COPY_V3
@@ -498,6 +530,9 @@ config CPU_COPY_V4WB
 config CPU_COPY_FEROCEON
 	bool
 
+config CPU_COPY_FA
+	bool
+
 config CPU_COPY_V6
 	bool
 
@@ -528,6 +563,13 @@ config CPU_TLB_FEROCEON
 	help
 	  Feroceon TLB (v4wbi with non-outer-cachable page table walks).
 
+config CPU_TLB_FA
+	bool
+	help
+	  Faraday ARM FA526 architecture, unified TLB with writeback cache
+	  and invalidate instruction cache entry. Branch target buffer is
+	  also supported.
+
 config CPU_TLB_V6
 	bool
 
@@ -569,7 +611,7 @@ comment "Processor Features"
 
 config ARM_THUMB
 	bool "Support Thumb user binaries"
-	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON
+	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V7 || CPU_FEROCEON
 	default y
 	help
 	  Say Y if you want to include kernel support for running user space
@@ -638,7 +680,7 @@ config CPU_DCACHE_SIZE
 
 config CPU_DCACHE_WRITETHROUGH
 	bool "Force write through D-cache"
-	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
+	depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE
 	default y if CPU_ARM925T
 	help
 	  Say Y here to use the data cache in writethrough mode. Unless you
@@ -653,7 +695,7 @@ config CPU_CACHE_ROUND_ROBIN
 
 config CPU_BPREDICT_DISABLE
 	bool "Disable branch prediction"
-	depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7
+	depends on CPU_ARM1020 || CPU_V6 || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526
 	help
 	  Say Y here to disable branch prediction.  If unsure, say N.
 
@@ -704,7 +746,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 
 config CACHE_L2X0
 	bool "Enable the L2x0 outer cache controller"
-	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || REALVIEW_EB_A9MP
+	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
+		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31
 	default y
 	select OUTER_CACHE
 	help
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/Makefile linux-libre-2.6.30-gnu1/arch/arm/mm/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/mm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@ obj-$(CONFIG_MODULES)		+= proc-syms.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
 obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
+obj-$(CONFIG_HIGHMEM)		+= highmem.o
 
 obj-$(CONFIG_CPU_ABRT_NOMMU)	+= abort-nommu.o
 obj-$(CONFIG_CPU_ABRT_EV4)	+= abort-ev4.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_CPU_CACHE_V4WT)	+= cache-v4
 obj-$(CONFIG_CPU_CACHE_V4WB)	+= cache-v4wb.o
 obj-$(CONFIG_CPU_CACHE_V6)	+= cache-v6.o
 obj-$(CONFIG_CPU_CACHE_V7)	+= cache-v7.o
+obj-$(CONFIG_CPU_CACHE_FA)	+= cache-fa.o
 
 obj-$(CONFIG_CPU_COPY_V3)	+= copypage-v3.o
 obj-$(CONFIG_CPU_COPY_V4WT)	+= copypage-v4wt.o
@@ -41,6 +43,7 @@ obj-$(CONFIG_CPU_COPY_V6)	+= copypage-v6
 obj-$(CONFIG_CPU_SA1100)	+= copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)	+= copypage-xscale.o
 obj-$(CONFIG_CPU_XSC3)		+= copypage-xsc3.o
+obj-$(CONFIG_CPU_COPY_FA)	+= copypage-fa.o
 
 obj-$(CONFIG_CPU_TLB_V3)	+= tlb-v3.o
 obj-$(CONFIG_CPU_TLB_V4WT)	+= tlb-v4.o
@@ -49,6 +52,7 @@ obj-$(CONFIG_CPU_TLB_V4WBI)	+= tlb-v4wbi
 obj-$(CONFIG_CPU_TLB_FEROCEON)	+= tlb-v4wbi.o	# reuse v4wbi TLB functions
 obj-$(CONFIG_CPU_TLB_V6)	+= tlb-v6.o
 obj-$(CONFIG_CPU_TLB_V7)	+= tlb-v7.o
+obj-$(CONFIG_CPU_TLB_FA)	+= tlb-fa.o
 
 obj-$(CONFIG_CPU_ARM610)	+= proc-arm6_7.o
 obj-$(CONFIG_CPU_ARM710)	+= proc-arm6_7.o
@@ -62,6 +66,7 @@ obj-$(CONFIG_CPU_ARM925T)	+= proc-arm925
 obj-$(CONFIG_CPU_ARM926T)	+= proc-arm926.o
 obj-$(CONFIG_CPU_ARM940T)	+= proc-arm940.o
 obj-$(CONFIG_CPU_ARM946E)	+= proc-arm946.o
+obj-$(CONFIG_CPU_FA526)		+= proc-fa526.o
 obj-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
 obj-$(CONFIG_CPU_ARM1020E)	+= proc-arm1020e.o
 obj-$(CONFIG_CPU_ARM1022)	+= proc-arm1022.o
@@ -70,6 +75,7 @@ obj-$(CONFIG_CPU_SA110)		+= proc-sa110.o
 obj-$(CONFIG_CPU_SA1100)	+= proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)	+= proc-xscale.o
 obj-$(CONFIG_CPU_XSC3)		+= proc-xsc3.o
+obj-$(CONFIG_CPU_MOHAWK)	+= proc-mohawk.o
 obj-$(CONFIG_CPU_FEROCEON)	+= proc-feroceon.o
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
 obj-$(CONFIG_CPU_V7)		+= proc-v7.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/mm.h linux-libre-2.6.30-gnu1/arch/arm/mm/mm.h
--- linux-libre-2.6.29-gnu1/arch/arm/mm/mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/mm.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,6 @@
-/* the upper-most page table pointer */
-
 #ifdef CONFIG_MMU
 
+/* the upper-most page table pointer */
 extern pmd_t *top_pmd;
 
 #define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/mmu.c linux-libre-2.6.30-gnu1/arch/arm/mm/mmu.c
--- linux-libre-2.6.29-gnu1/arch/arm/mm/mmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/mmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,9 +18,11 @@
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
 #include <asm/sections.h>
+#include <asm/cachetype.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
 #include <asm/tlb.h>
+#include <asm/highmem.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -243,6 +245,10 @@ static struct mem_type mem_types[] = {
 		.prot_sect = PMD_TYPE_SECT,
 		.domain    = DOMAIN_KERNEL,
 	},
+	[MT_MEMORY_NONCACHED] = {
+		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+		.domain    = DOMAIN_KERNEL,
+	},
 };
 
 const struct mem_type *get_mem_type(unsigned int type)
@@ -406,9 +412,28 @@ static void __init build_mem_type_table(
 		kern_pgprot |= L_PTE_SHARED;
 		vecs_pgprot |= L_PTE_SHARED;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
 	}
 
+	/*
+	 * Non-cacheable Normal - intended for memory areas that must
+	 * not cause dirty cache line writebacks when used
+	 */
+	if (cpu_arch >= CPU_ARCH_ARMv6) {
+		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+			/* Non-cacheable Normal is XCB = 001 */
+			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+				PMD_SECT_BUFFERED;
+		} else {
+			/* For both ARMv6 and non-TEX-remapping ARMv7 */
+			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+				PMD_SECT_TEX(1);
+		}
+	} else {
+		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+	}
+
 	for (i = 0; i < 16; i++) {
 		unsigned long v = pgprot_val(protection_map[i]);
 		protection_map[i] = __pgprot(v | user_pgprot);
@@ -677,6 +702,10 @@ static void __init sanity_check_meminfo(
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
+			} else if (cache_is_vipt_aliasing()) {
+				printk(KERN_CRIT "HIGHMEM is not yet supported "
+						 "with VIPT aliasing cache, "
+						 "ignoring high memory\n");
 			} else {
 				memmove(bank + 1, bank,
 					(meminfo.nr_banks - i) * sizeof(*bank));
@@ -694,7 +723,7 @@ static void __init sanity_check_meminfo(
 		 * the vmalloc area.
 		 */
 		if (__va(bank->start) >= VMALLOC_MIN ||
-		    __va(bank->start) < PAGE_OFFSET) {
+		    __va(bank->start) < (void *)PAGE_OFFSET) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
 			       "(vmalloc region overlap).\n",
 			       bank->start, bank->start + bank->size - 1);
@@ -799,6 +828,17 @@ void __init reserve_node_zero(pg_data_t
 				BOOTMEM_DEFAULT);
 	}
 
+	if (machine_is_palmld() || machine_is_palmtx()) {
+		reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
+				BOOTMEM_EXCLUSIVE);
+		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
+				BOOTMEM_EXCLUSIVE);
+	}
+
+	if (machine_is_palmt5())
+		reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
+				BOOTMEM_EXCLUSIVE);
+
 #ifdef CONFIG_SA1111
 	/*
 	 * Because of the SA1111 DMA bug, we want to preserve our
@@ -895,6 +935,17 @@ static void __init devicemaps_init(struc
 	flush_cache_all();
 }
 
+static void __init kmap_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+	pmd_t *pmd = pmd_off_k(PKMAP_BASE);
+	pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+	BUG_ON(!pmd_none(*pmd) || !pte);
+	__pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
+	pkmap_page_table = pte + PTRS_PER_PTE;
+#endif
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -908,6 +959,7 @@ void __init paging_init(struct machine_d
 	prepare_page_table();
 	bootmem_init();
 	devicemaps_init(mdesc);
+	kmap_init();
 
 	top_pmd = pmd_off_k(0xffff0000);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/proc-fa526.S linux-libre-2.6.30-gnu1/arch/arm/mm/proc-fa526.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/proc-fa526.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/proc-fa526.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,248 @@
+/*
+ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
+ *
+ *  Written by : Luke Lee
+ *  Copyright (C) 2005 Faraday Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the fa526.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#include "proc-macros.S"
+
+#define CACHE_DLINESIZE	16
+
+	.text
+/*
+ * cpu_fa526_proc_init()
+ */
+ENTRY(cpu_fa526_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_fa526_proc_fin()
+ */
+ENTRY(cpu_fa526_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	fa_flush_kern_cache_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	nop
+	nop
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_fa526_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	4
+ENTRY(cpu_fa526_reset)
+/* TODO: Use CP8 if possible... */
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+#ifdef CONFIG_MMU
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+#endif
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	bic	ip, ip, #0x0800			@ BTB off
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	nop
+	nop
+	mov	pc, r0
+
+/*
+ * cpu_fa526_do_idle()
+ */
+	.align	4
+ENTRY(cpu_fa526_do_idle)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+	mov	pc, lr
+
+
+ENTRY(cpu_fa526_dcache_clean_area)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	subs	r1, r1, #CACHE_DLINESIZE
+	bhi	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_fa526_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	4
+ENTRY(cpu_fa526_switch_mm)
+#ifdef CONFIG_MMU
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+	mcr	p15, 0, ip, c7, c14, 0		@ clean and invalidate whole D cache
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c5, 6		@ invalidate BTB since mm changed
+	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, ip, c7, c5, 4		@ prefetch flush
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate UTLB
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_fa526_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	4
+ENTRY(cpu_fa526_set_pte_ext)
+#ifdef CONFIG_MMU
+	armv3_set_pte_ext
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+#endif
+	mov	pc, lr
+
+	__INIT
+
+	.type	__fa526_setup, #function
+__fa526_setup:
+	/* On return of this routine, r0 must carry correct flags for CFG register */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+#ifdef CONFIG_MMU
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+#endif
+	mcr	p15, 0, r0, c7, c5, 5		@ invalidate IScratchpad RAM
+
+	mov	r0, #1
+	mcr	p15, 0, r0, c1, c1, 0		@ turn-on ECR
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB All
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c5, 4		@ prefetch flush
+
+	mov	r0, #0x1f			@ Domains 0, 1 = manager, 2 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+	ldr	r5, fa526_cr1_clear
+	bic	r0, r0, r5
+	ldr	r5, fa526_cr1_set
+	orr	r0, r0, r5
+	mov	pc, lr
+	.size	__fa526_setup, . - __fa526_setup
+
+	/*
+	 * .RVI ZFRS BLDP WCAM
+	 * ..11 1001 .111 1101
+	 *
+	 */
+	.type	fa526_cr1_clear, #object
+	.type	fa526_cr1_set, #object
+fa526_cr1_clear:
+	.word	0x3f3f
+fa526_cr1_set:
+	.word	0x397D
+
+	__INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	fa526_processor_functions, #object
+fa526_processor_functions:
+	.word	v4_early_abort
+	.word	pabort_noifar
+	.word	cpu_fa526_proc_init
+	.word	cpu_fa526_proc_fin
+	.word	cpu_fa526_reset
+	.word   cpu_fa526_do_idle
+	.word	cpu_fa526_dcache_clean_area
+	.word	cpu_fa526_switch_mm
+	.word	cpu_fa526_set_pte_ext
+	.size	fa526_processor_functions, . - fa526_processor_functions
+
+	.section ".rodata"
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+
+	.type	cpu_fa526_name, #object
+cpu_fa526_name:
+	.asciz	"FA526"
+	.size	cpu_fa526_name, . - cpu_fa526_name
+
+	.align
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+	.type	__fa526_proc_info,#object
+__fa526_proc_info:
+	.long	0x66015261
+	.long	0xff01fff1
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__fa526_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF
+	.long	cpu_fa526_name
+	.long	fa526_processor_functions
+	.long	fa_tlb_fns
+	.long	fa_user_fns
+	.long	fa_cache_fns
+	.size	__fa526_proc_info, . - __fa526_proc_info
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/proc-mohawk.S linux-libre-2.6.30-gnu1/arch/arm/mm/proc-mohawk.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/proc-mohawk.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/proc-mohawk.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,416 @@
+/*
+ *  linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core
+ *
+ *  PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core.
+ *
+ *  Heavily based on proc-arm926.S and proc-xsc3.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed.  If the
+ * area is larger than this, then we flush the whole cache.
+ */
+#define CACHE_DLIMIT	32768
+
+/*
+ * The cache line size of the L1 D cache.
+ */
+#define CACHE_DLINESIZE	32
+
+/*
+ * cpu_mohawk_proc_init()
+ */
+ENTRY(cpu_mohawk_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_mohawk_proc_fin()
+ */
+ENTRY(cpu_mohawk_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	mohawk_flush_kern_cache_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1800			@ ...iz...........
+	bic	r0, r0, #0x0006			@ .............ca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_mohawk_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ *
+ * (same as arm926)
+ */
+	.align	5
+ENTRY(cpu_mohawk_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x0007			@ .............cam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_mohawk_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+	.align	5
+ENTRY(cpu_mohawk_do_idle)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_all()
+ *
+ *	Clean and invalidate all cache entries in a particular
+ *	address space.
+ */
+ENTRY(mohawk_flush_user_cache_all)
+	/* FALLTHROUGH */
+
+/*
+ *	flush_kern_cache_all()
+ *
+ *	Clean and invalidate the entire cache.
+ */
+ENTRY(mohawk_flush_kern_cache_all)
+	mov	r2, #VM_EXEC
+	mov	ip, #0
+__flush_whole_cache:
+	mcr	p15, 0, ip, c7, c14, 0		@ clean & invalidate all D cache
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcrne	p15, 0, ip, c7, c10, 0		@ drain write buffer
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_range(start, end, flags)
+ *
+ *	Clean and invalidate a range of cache entries in the
+ *	specified address range.
+ *
+ *	- start	- start address (inclusive)
+ *	- end	- end address (exclusive)
+ *	- flags	- vm_flags describing address space
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_flush_user_cache_range)
+	mov	ip, #0
+	sub	r3, r1, r0			@ calculate total size
+	cmp	r3, #CACHE_DLIMIT
+	bgt	__flush_whole_cache
+1:	tst	r2, #VM_EXEC
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	coherent_kern_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
+ */
+ENTRY(mohawk_coherent_kern_range)
+	/* FALLTHROUGH */
+
+/*
+ *	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
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_coherent_user_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	flush_kern_dcache_page(void *page)
+ *
+ *	Ensure no D cache aliasing occurs, either with itself or
+ *	the I cache
+ *
+ *	- addr	- page aligned address
+ */
+ENTRY(mohawk_flush_kern_dcache_page)
+	add	r1, r0, #PAGE_SZ
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_inv_range(start, end)
+ *
+ *	Invalidate (discard) the specified virtual address range.
+ *	May not write back any entries.  If 'start' or 'end'
+ *	are not cache line aligned, those lines must be written
+ *	back.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(mohawk_dma_inv_range)
+	tst	r0, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_clean_range(start, end)
+ *
+ *	Clean the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(mohawk_dma_clean_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ *	dma_flush_range(start, end)
+ *
+ *	Clean and invalidate the specified virtual address range.
+ *
+ *	- start	- virtual start address
+ *	- end	- virtual end address
+ */
+ENTRY(mohawk_dma_flush_range)
+	bic	r0, r0, #CACHE_DLINESIZE - 1
+1:
+	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(mohawk_cache_fns)
+	.long	mohawk_flush_kern_cache_all
+	.long	mohawk_flush_user_cache_all
+	.long	mohawk_flush_user_cache_range
+	.long	mohawk_coherent_kern_range
+	.long	mohawk_coherent_user_range
+	.long	mohawk_flush_kern_dcache_page
+	.long	mohawk_dma_inv_range
+	.long	mohawk_dma_clean_range
+	.long	mohawk_dma_flush_range
+
+ENTRY(cpu_mohawk_dcache_clean_area)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHE_DLINESIZE
+	subs	r1, r1, #CACHE_DLINESIZE
+	bhi	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_mohawk_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_mohawk_switch_mm)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c14, 0		@ clean & invalidate all D cache
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	orr	r0, r0, #0x18			@ cache the page table in L2
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_mohawk_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_mohawk_set_pte_ext)
+	armv3_set_pte_ext
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+	__INIT
+
+	.type	__mohawk_setup, #function
+__mohawk_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs
+	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
+	mcr	p15, 0, r0, c15, c1, 0		@ write CP access register
+
+	adr	r5, mohawk_crval
+	ldmia	r5, {r5, r6}
+	mrc	p15, 0, r0, c1, c0		@ get control register
+	bic	r0, r0, r5
+	orr	r0, r0, r6
+	mov	pc, lr
+
+	.size	__mohawk_setup, . - __mohawk_setup
+
+	/*
+	 *  R
+	 * .RVI ZFRS BLDP WCAM
+	 * .011 1001 ..00 0101
+	 *
+	 */
+	.type	mohawk_crval, #object
+mohawk_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134
+
+	__INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	mohawk_processor_functions, #object
+mohawk_processor_functions:
+	.word	v5t_early_abort
+	.word	pabort_noifar
+	.word	cpu_mohawk_proc_init
+	.word	cpu_mohawk_proc_fin
+	.word	cpu_mohawk_reset
+	.word	cpu_mohawk_do_idle
+	.word	cpu_mohawk_dcache_clean_area
+	.word	cpu_mohawk_switch_mm
+	.word	cpu_mohawk_set_pte_ext
+	.size	mohawk_processor_functions, . - mohawk_processor_functions
+
+	.section ".rodata"
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5te"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5"
+	.size	cpu_elf_name, . - cpu_elf_name
+
+	.type	cpu_mohawk_name, #object
+cpu_mohawk_name:
+	.asciz	"Marvell 88SV331x"
+	.size	cpu_mohawk_name, . - cpu_mohawk_name
+
+	.align
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+	.type	__88sv331x_proc_info,#object
+__88sv331x_proc_info:
+	.long	0x56158000			@ Marvell 88SV331x (MOHAWK)
+	.long	0xfffff000
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	b	__mohawk_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_mohawk_name
+	.long	mohawk_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	v4wb_user_fns
+	.long	mohawk_cache_fns
+	.size	__88sv331x_proc_info, . - __88sv331x_proc_info
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/proc-v6.S linux-libre-2.6.30-gnu1/arch/arm/mm/proc-v6.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/proc-v6.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/proc-v6.S	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
  *
  *  This is the "shell" of the ARMv6 processor support.
  */
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
@@ -132,7 +133,7 @@ cpu_v6_name:
 	.asciz	"ARMv6-compatible processor"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 /*
  *	__v6_setup
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/proc-v7.S linux-libre-2.6.30-gnu1/arch/arm/mm/proc-v7.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/proc-v7.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/proc-v7.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  *
  *  This is the "shell" of the ARMv7 processor support.
  */
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
@@ -95,6 +96,9 @@ ENTRY(cpu_v7_switch_mm)
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
 	orr	r0, r0, #TTB_FLAGS
+#ifdef CONFIG_ARM_ERRATA_430973
+	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
+#endif
 	mcr	p15, 0, r2, c13, c0, 1		@ set reserved context ID
 	isb
 1:	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
@@ -153,7 +157,7 @@ cpu_v7_name:
 	.ascii	"ARMv7 Processor"
 	.align
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 /*
  *	__v7_setup
@@ -180,7 +184,37 @@ __v7_setup:
 	stmia	r12, {r0-r5, r7, r9, r11, lr}
 	bl	v7_flush_dcache_all
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
-	mov	r10, #0
+
+	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
+	and	r10, r0, #0xff000000		@ ARM?
+	teq	r10, #0x41000000
+	bne	2f
+	and	r5, r0, #0x00f00000		@ variant
+	and	r6, r0, #0x0000000f		@ revision
+	orr	r0, r6, r5, lsr #20-4		@ combine variant and revision
+
+#ifdef CONFIG_ARM_ERRATA_430973
+	teq	r5, #0x00100000			@ only present in r1p*
+	mrceq	p15, 0, r10, c1, c0, 1		@ read aux control register
+	orreq	r10, r10, #(1 << 6)		@ set IBE to 1
+	mcreq	p15, 0, r10, c1, c0, 1		@ write aux control register
+#endif
+#ifdef CONFIG_ARM_ERRATA_458693
+	teq	r0, #0x20			@ only present in r2p0
+	mrceq	p15, 0, r10, c1, c0, 1		@ read aux control register
+	orreq	r10, r10, #(1 << 5)		@ set L1NEON to 1
+	orreq	r10, r10, #(1 << 9)		@ set PLDNOP to 1
+	mcreq	p15, 0, r10, c1, c0, 1		@ write aux control register
+#endif
+#ifdef CONFIG_ARM_ERRATA_460075
+	teq	r0, #0x20			@ only present in r2p0
+	mrceq	p15, 1, r10, c9, c0, 2		@ read L2 cache aux ctrl register
+	tsteq	r10, #1 << 22
+	orreq	r10, r10, #(1 << 22)		@ set the Write Allocate disable bit
+	mcreq	p15, 1, r10, c9, c0, 2		@ write the L2 cache aux ctrl register
+#endif
+
+2:	mov	r10, #0
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r10, c7, c5, 0		@ I+BTB cache invalidate
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-fa.S linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-fa.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-fa.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-fa.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ *  linux/arch/arm/mm/tlb-fa.S
+ *
+ *  Copyright (C) 2005 Faraday Corp.
+ *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on tlb-v4wbi.S:
+ *  Copyright (C) 1997-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.
+ *
+ *  ARM architecture version 4, Faraday variation.
+ *  This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
+ *
+ *  Processors: FA520 FA526 FA626
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+
+/*
+ *	flush_user_tlb_range(start, end, mm)
+ *
+ *	Invalidate a range of TLB entries in the specified address space.
+ *
+ *	- start - range start address
+ *	- end   - range end address
+ *	- mm    - mm_struct describing address space
+ */
+	.align	4
+ENTRY(fa_flush_user_tlb_range)
+	vma_vm_mm ip, r2
+	act_mm	r3				@ get current->active_mm
+	eors	r3, ip, r3			@ == mm ?
+	movne	pc, lr				@ no, we dont do anything
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	bic	r0, r0, #0x0ff
+	bic	r0, r0, #0xf00
+1:	mcr	p15, 0, r0, c8, c7, 1		@ invalidate UTLB entry
+	add	r0, r0, #PAGE_SZ
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r3, c7, c5, 6		@ invalidate BTB
+	mcr	p15, 0, r3, c7, c10, 4		@ data write barrier
+	mov	pc, lr
+
+
+ENTRY(fa_flush_kern_tlb_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	bic	r0, r0, #0x0ff
+	bic	r0, r0, #0xf00
+1:	mcr	p15, 0, r0, c8, c7, 1		@ invalidate UTLB entry
+	add	r0, r0, #PAGE_SZ
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r3, c7, c5, 6		@ invalidate BTB
+	mcr	p15, 0, r3, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r3, c7, c5, 4		@ prefetch flush
+	mov	pc, lr
+
+	__INITDATA
+
+	.type	fa_tlb_fns, #object
+ENTRY(fa_tlb_fns)
+	.long	fa_flush_user_tlb_range
+	.long	fa_flush_kern_tlb_range
+	.long	fa_tlb_flags
+	.size	fa_tlb_fns, . - fa_tlb_fns
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-v6.S linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-v6.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-v6.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-v6.S	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
  *  ARM architecture version 6 TLB handling functions.
  *  These assume a split I/D TLB.
  */
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
@@ -87,7 +88,7 @@ ENTRY(v6wbi_flush_kern_tlb_range)
 	mcr	p15, 0, r2, c7, c5, 4		@ prefetch flush
 	mov	pc, lr
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 	.type	v6wbi_tlb_fns, #object
 ENTRY(v6wbi_tlb_fns)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-v7.S linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-v7.S
--- linux-libre-2.6.29-gnu1/arch/arm/mm/tlb-v7.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/mm/tlb-v7.S	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@
  *  ARM architecture version 6 TLB handling functions.
  *  These assume a split I/D TLB.
  */
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
@@ -80,7 +81,7 @@ ENTRY(v7wbi_flush_kern_tlb_range)
 	mov	pc, lr
 ENDPROC(v7wbi_flush_kern_tlb_range)
 
-	.section ".text.init", #alloc, #execinstr
+	__INIT
 
 	.type	v7wbi_tlb_fns, #object
 ENTRY(v7wbi_tlb_fns)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/nwfpe/fpa11_cprt.c linux-libre-2.6.30-gnu1/arch/arm/nwfpe/fpa11_cprt.c
--- linux-libre-2.6.29-gnu1/arch/arm/nwfpe/fpa11_cprt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/nwfpe/fpa11_cprt.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,10 +27,6 @@
 #include "fpmodule.inl"
 #include "softfloat.h"
 
-#ifdef CONFIG_FPE_NWFPE_XP
-extern flag floatx80_is_nan(floatx80);
-#endif
-
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/nwfpe/fpa11.h linux-libre-2.6.30-gnu1/arch/arm/nwfpe/fpa11.h
--- linux-libre-2.6.29-gnu1/arch/arm/nwfpe/fpa11.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/nwfpe/fpa11.h	2009-06-09 23:05:27.000000000 -0400
@@ -114,4 +114,8 @@ extern unsigned int SingleCPDO(struct ro
 extern unsigned int DoubleCPDO(struct roundingData *roundData,
 			       const unsigned int opcode, FPREG * rFd);
 
+/* extneded_cpdo.c */
+extern unsigned int ExtendedCPDO(struct roundingData *roundData,
+				 const unsigned int opcode, FPREG * rFd);
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/nwfpe/softfloat.h linux-libre-2.6.30-gnu1/arch/arm/nwfpe/softfloat.h
--- linux-libre-2.6.29-gnu1/arch/arm/nwfpe/softfloat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/nwfpe/softfloat.h	2009-06-09 23:05:27.000000000 -0400
@@ -226,6 +226,8 @@ char floatx80_le_quiet( floatx80, floatx
 char floatx80_lt_quiet( floatx80, floatx80 );
 char floatx80_is_signaling_nan( floatx80 );
 
+extern flag floatx80_is_nan(floatx80);
+
 #endif
 
 static inline flag extractFloat32Sign(float32 a)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/oprofile/backtrace.c linux-libre-2.6.30-gnu1/arch/arm/oprofile/backtrace.c
--- linux-libre-2.6.29-gnu1/arch/arm/oprofile/backtrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/oprofile/backtrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,15 +18,14 @@
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 #include <asm/ptrace.h>
-
-#include "../kernel/stacktrace.h"
+#include <asm/stacktrace.h>
 
 static int report_trace(struct stackframe *frame, void *d)
 {
 	unsigned int *depth = d;
 
 	if (*depth) {
-		oprofile_add_trace(frame->lr);
+		oprofile_add_trace(frame->pc);
 		(*depth)--;
 	}
 
@@ -70,9 +69,12 @@ void arm_backtrace(struct pt_regs * cons
 	struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
 
 	if (!user_mode(regs)) {
-		unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1);
-		walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE,
-				report_trace, &depth);
+		struct stackframe frame;
+		frame.fp = regs->ARM_fp;
+		frame.sp = regs->ARM_sp;
+		frame.lr = regs->ARM_lr;
+		frame.pc = regs->ARM_pc;
+		walk_stackframe(&frame, report_trace, &depth);
 		return;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/oprofile/op_model_mpcore.c linux-libre-2.6.30-gnu1/arch/arm/oprofile/op_model_mpcore.c
--- linux-libre-2.6.29-gnu1/arch/arm/oprofile/op_model_mpcore.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/oprofile/op_model_mpcore.c	2009-06-09 23:05:27.000000000 -0400
@@ -263,7 +263,7 @@ static void em_route_irq(int irq, unsign
 	const struct cpumask *mask = cpumask_of(cpu);
 
 	spin_lock_irq(&desc->lock);
-	desc->affinity = *mask;
+	cpumask_copy(desc->affinity, mask);
 	desc->chip->set_affinity(irq, mask);
 	spin_unlock_irq(&desc->lock);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-iop/adma.c linux-libre-2.6.30-gnu1/arch/arm/plat-iop/adma.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-iop/adma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-iop/adma.c	2009-06-09 23:05:27.000000000 -0400
@@ -119,7 +119,7 @@ static struct resource iop3xx_aau_resour
 	}
 };
 
-static u64 iop3xx_adma_dmamask = DMA_32BIT_MASK;
+static u64 iop3xx_adma_dmamask = DMA_BIT_MASK(32);
 
 static struct iop_adma_platform_data iop3xx_dma_0_data = {
 	.hw_id = DMA0_ID,
@@ -143,7 +143,7 @@ struct platform_device iop3xx_dma_0_chan
 	.resource = iop3xx_dma_0_resources,
 	.dev = {
 		.dma_mask = &iop3xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop3xx_dma_0_data,
 	},
 };
@@ -155,7 +155,7 @@ struct platform_device iop3xx_dma_1_chan
 	.resource = iop3xx_dma_1_resources,
 	.dev = {
 		.dma_mask = &iop3xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop3xx_dma_1_data,
 	},
 };
@@ -167,7 +167,7 @@ struct platform_device iop3xx_aau_channe
 	.resource = iop3xx_aau_resources,
 	.dev = {
 		.dma_mask = &iop3xx_adma_dmamask,
-		.coherent_dma_mask = DMA_64BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(64),
 		.platform_data = (void *) &iop3xx_aau_data,
 	},
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/clock.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,11 @@ static DEFINE_MUTEX(clocks_mutex);
  *-------------------------------------------------------------------------*/
 
 /*
+ * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all
+ * MXC architectures have switched to using clkdev.
+ */
+#ifndef CONFIG_COMMON_CLKDEV
+/*
  * Retrieve a clock by name.
  *
  * Note that we first try to use device id on the bus
@@ -110,6 +115,7 @@ found:
 	return clk;
 }
 EXPORT_SYMBOL(clk_get);
+#endif
 
 static void __clk_disable(struct clk *clk)
 {
@@ -187,6 +193,7 @@ unsigned long clk_get_rate(struct clk *c
 }
 EXPORT_SYMBOL(clk_get_rate);
 
+#ifndef CONFIG_COMMON_CLKDEV
 /* Decrement the clock's module reference count */
 void clk_put(struct clk *clk)
 {
@@ -194,6 +201,7 @@ void clk_put(struct clk *clk)
 		module_put(clk->owner);
 }
 EXPORT_SYMBOL(clk_put);
+#endif
 
 /* Round the requested clock rate to the nearest supported
  * rate that is less than or equal to the requested rate.
@@ -257,6 +265,7 @@ struct clk *clk_get_parent(struct clk *c
 }
 EXPORT_SYMBOL(clk_get_parent);
 
+#ifndef CONFIG_COMMON_CLKDEV
 /*
  * Add a new clock to the clock tree.
  */
@@ -327,4 +336,49 @@ static int __init mxc_setup_proc_entry(v
 }
 
 late_initcall(mxc_setup_proc_entry);
+#endif /* CONFIG_PROC_FS */
+#endif
+
+/*
+ * Get the resulting clock rate from a PLL register value and the input
+ * frequency. PLLs with this register layout can at least be found on
+ * MX1, MX21, MX27 and MX31
+ *
+ *                  mfi + mfn / (mfd + 1)
+ *  f = 2 * f_ref * --------------------
+ *                        pd + 1
+ */
+unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
+{
+	long long ll;
+	int mfn_abs;
+	unsigned int mfi, mfn, mfd, pd;
+
+	mfi = (reg_val >> 10) & 0xf;
+	mfn = reg_val & 0x3ff;
+	mfd = (reg_val >> 16) & 0x3ff;
+	pd =  (reg_val >> 26) & 0xf;
+
+	mfi = mfi <= 5 ? 5 : mfi;
+
+	mfn_abs = mfn;
+
+#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
+	if (mfn >= 0x200) {
+		mfn |= 0xFFFFFE00;
+		mfn_abs = -mfn;
+	}
 #endif
+
+	freq *= 2;
+	freq /= pd + 1;
+
+	ll = (unsigned long long)freq * mfn_abs;
+
+	do_div(ll, mfd + 1);
+	if (mfn < 0)
+		ll = -ll;
+	ll = (freq * mfi) + ll;
+
+	return ll;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/cpu.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/cpu.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/cpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/cpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+
+#include <linux/module.h>
+
+unsigned int __mxc_cpu_type;
+EXPORT_SYMBOL(__mxc_cpu_type);
+
+void mxc_set_cpu_type(unsigned int type)
+{
+	__mxc_cpu_type = type;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/devices.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <mach/common.h>
 
 int __init mxc_register_device(struct platform_device *pdev, void *data)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/dma-mx1-mx2.c	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,7 @@ struct imx_dma_channel {
 	void (*err_handler) (int, void *, int errcode);
 	void (*prog_handler) (int, void *, struct scatterlist *);
 	void *data;
-	unsigned int  dma_mode;
+	unsigned int dma_mode;
 	struct scatterlist *sg;
 	unsigned int resbytes;
 	int dma_num;
@@ -693,12 +693,15 @@ int imx_dma_request(int channel, const c
 		local_irq_restore(flags);
 		return -EBUSY;
 	}
+	memset(imxdma, 0, sizeof(imxdma));
+	imxdma->name = name;
+	local_irq_restore(flags); /* request_irq() can block */
 
 #ifdef CONFIG_ARCH_MX2
 	ret = request_irq(MXC_INT_DMACH0 + channel, dma_irq_handler, 0, "DMA",
 			NULL);
 	if (ret) {
-		local_irq_restore(flags);
+		imxdma->name = NULL;
 		printk(KERN_CRIT "Can't register IRQ %d for DMA channel %d\n",
 				MXC_INT_DMACH0 + channel, channel);
 		return ret;
@@ -708,13 +711,6 @@ int imx_dma_request(int channel, const c
 	imxdma->watchdog.data = channel;
 #endif
 
-	imxdma->name = name;
-	imxdma->irq_handler = NULL;
-	imxdma->err_handler = NULL;
-	imxdma->data = NULL;
-	imxdma->sg = NULL;
-
-	local_irq_restore(flags);
 	return ret;
 }
 EXPORT_SYMBOL(imx_dma_request);
@@ -737,10 +733,7 @@ void imx_dma_free(int channel)
 
 	local_irq_save(flags);
 	/* Disable interrupts */
-	__raw_writel(__raw_readl(DMA_BASE + DMA_DIMR) | (1 << channel),
-		DMA_BASE + DMA_DIMR);
-	__raw_writel(__raw_readl(DMA_BASE + DMA_CCR(channel)) & ~CCR_CEN,
-		DMA_BASE + DMA_CCR(channel));
+	imx_dma_disable(channel);
 	imxdma->name = NULL;
 
 #ifdef CONFIG_ARCH_MX2
@@ -802,7 +795,7 @@ static int __init imx_dma_init(void)
 	int ret = 0;
 	int i;
 
-	dma_clk = clk_get(NULL, "dma_clk");
+	dma_clk = clk_get(NULL, "dma");
 	clk_enable(dma_clk);
 
 	/* reset DMA module */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/gpio.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -124,7 +124,7 @@ static void mx3_gpio_irq_handler(u32 irq
 
 	irq_stat = __raw_readl(port->base + GPIO_ISR) &
 			__raw_readl(port->base + GPIO_IMR);
-	BUG_ON(!irq_stat);
+
 	mxc_gpio_irq_handler(port, irq_stat);
 }
 #endif
@@ -200,8 +200,8 @@ static int mxc_gpio_direction_input(stru
 static int mxc_gpio_direction_output(struct gpio_chip *chip,
 				     unsigned offset, int value)
 {
-	_set_gpio_direction(chip, offset, 1);
 	mxc_gpio_set(chip, offset, value);
+	_set_gpio_direction(chip, offset, 1);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx27ads.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx27ads.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx27ads.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx27ads.h	2009-06-09 23:05:27.000000000 -0400
@@ -47,8 +47,9 @@
 /*
  * Base address of PBC controller, CS4
  */
-#define PBC_BASE_ADDRESS        0xEB000000
-#define PBC_REG_ADDR(offset)    (PBC_BASE_ADDRESS + (offset))
+#define PBC_BASE_ADDRESS        0xf4300000
+#define PBC_REG_ADDR(offset)    (void __force __iomem *) \
+		(PBC_BASE_ADDRESS + (offset))
 
 /*
  * PBC Interupt name definitions
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx31ads.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
 #define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
 
+#include <mach/hardware.h>
+
 /* Base address of PBC controller */
 #define PBC_BASE_ADDRESS        IO_ADDRESS(CS4_BASE_ADDR)
 /* Offsets for the PBC Controller register */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-mx31moboard.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * 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_MX31MOBOARD_H__
+#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
+
+/* mandatory for CONFIG_LL_DEBUG */
+
+#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR	(AIPI_BASE_ADDR_VIRT + 0x0A000)
+
+#ifndef __ASSEMBLY__
+
+enum mx31moboard_boards {
+	MX31NOBOARD	= 0,
+	MX31DEVBOARD	= 1,
+	MX31MARXBOT	= 2,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ */
+
+extern void mx31moboard_devboard_init(void);
+extern void mx31moboard_marxbot_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-qong.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-qong.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/board-qong.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/board-qong.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.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_MXC_BOARD_QONG_H__
+#define __ASM_ARCH_MXC_BOARD_QONG_H__
+
+/* mandatory for CONFIG_LL_DEBUG */
+
+#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+/* NOR FLASH */
+#define QONG_NOR_SIZE		(128*1024*1024)
+
+#endif /* __ASM_ARCH_MXC_BOARD_QONG_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/clkdev.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/clkdev.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/clkdev.h	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/arch/arm/plat-mxc/include/mach/clock.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,9 +26,13 @@
 struct module;
 
 struct clk {
+#ifndef CONFIG_COMMON_CLKDEV
+	/* As soon as i.MX1 and i.MX31 switched to clkdev, this
+	 * block can go away */
 	struct list_head node;
 	struct module *owner;
 	const char *name;
+#endif
 	int id;
 	/* Source clock this clk depends on */
 	struct clk *parent;
@@ -63,5 +67,7 @@ struct clk {
 int clk_register(struct clk *clk);
 void clk_unregister(struct clk *clk);
 
+unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/common.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -12,12 +12,18 @@
 #define __ASM_ARCH_MXC_COMMON_H__
 
 struct platform_device;
+struct clk;
 
 extern void mxc_map_io(void);
 extern void mxc_init_irq(void);
-extern void mxc_timer_init(const char *clk_timer);
-extern int mxc_clocks_init(unsigned long fref);
+extern void mxc_timer_init(struct clk *timer_clk);
+extern int mx1_clocks_init(unsigned long fref);
+extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
+extern int mx27_clocks_init(unsigned long fref);
+extern int mx31_clocks_init(unsigned long fref);
+extern int mx35_clocks_init(void);
 extern int mxc_register_gpios(void);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
+extern void mxc_set_cpu_type(unsigned int type);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/debug-macro.S	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,9 @@
 #ifdef CONFIG_MACH_MX31_3DS
 #include <mach/board-mx31pdk.h>
 #endif
+#ifdef CONFIG_MACH_QONG
+#include <mach/board-qong.h>
+#endif
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/hardware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,10 +23,16 @@
 #include <asm/sizes.h>
 
 #ifdef CONFIG_ARCH_MX3
-# include <mach/mx31.h>
+#include <mach/mx3x.h>
+#include <mach/mx31.h>
+#include <mach/mx35.h>
 #endif
 
 #ifdef CONFIG_ARCH_MX2
+# include <mach/mx2x.h>
+# ifdef CONFIG_MACH_MX21
+#  include <mach/mx21.h>
+# endif
 # ifdef CONFIG_MACH_MX27
 #  include <mach/mx27.h>
 # endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/i2c.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/i2c.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/i2c.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/i2c.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * i2c.h - i.MX I2C driver header file
+ *
+ * Copyright (c) 2008, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __ASM_ARCH_I2C_H_
+#define __ASM_ARCH_I2C_H_
+
+/**
+ * struct imxi2c_platform_data - structure of platform data for MXC I2C driver
+ * @init:	Initialise gpio's and other board specific things
+ * @exit:	Free everything initialised by @init
+ * @bitrate:	Bus speed measured in Hz
+ *
+ **/
+struct imxi2c_platform_data {
+	int (*init)(struct device *dev);
+	void (*exit)(struct device *dev);
+	int bitrate;
+};
+
+#endif /* __ASM_ARCH_I2C_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/imxfb.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/imxfb.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/imxfb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/imxfb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/*
+ * This structure describes the machine which we are running on.
+ */
+
+#define PCR_TFT		(1 << 31)
+#define PCR_COLOR	(1 << 30)
+#define PCR_PBSIZ_1	(0 << 28)
+#define PCR_PBSIZ_2	(1 << 28)
+#define PCR_PBSIZ_4	(2 << 28)
+#define PCR_PBSIZ_8	(3 << 28)
+#define PCR_BPIX_1	(0 << 25)
+#define PCR_BPIX_2	(1 << 25)
+#define PCR_BPIX_4	(2 << 25)
+#define PCR_BPIX_8	(3 << 25)
+#define PCR_BPIX_12	(4 << 25)
+#define PCR_BPIX_16	(4 << 25)
+#define PCR_PIXPOL	(1 << 24)
+#define PCR_FLMPOL	(1 << 23)
+#define PCR_LPPOL	(1 << 22)
+#define PCR_CLKPOL	(1 << 21)
+#define PCR_OEPOL	(1 << 20)
+#define PCR_SCLKIDLE	(1 << 19)
+#define PCR_END_SEL	(1 << 18)
+#define PCR_END_BYTE_SWAP (1 << 17)
+#define PCR_REV_VS	(1 << 16)
+#define PCR_ACD_SEL	(1 << 15)
+#define PCR_ACD(x)	(((x) & 0x7f) << 8)
+#define PCR_SCLK_SEL	(1 << 7)
+#define PCR_SHARP	(1 << 6)
+#define PCR_PCD(x)	((x) & 0x3f)
+
+#define PWMR_CLS(x)	(((x) & 0x1ff) << 16)
+#define PWMR_LDMSK	(1 << 15)
+#define PWMR_SCR1	(1 << 10)
+#define PWMR_SCR0	(1 << 9)
+#define PWMR_CC_EN	(1 << 8)
+#define PWMR_PW(x)	((x) & 0xff)
+
+#define LSCR1_PS_RISE_DELAY(x)    (((x) & 0x7f) << 26)
+#define LSCR1_CLS_RISE_DELAY(x)   (((x) & 0x3f) << 16)
+#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8)
+#define LSCR1_GRAY2(x)            (((x) & 0xf) << 4)
+#define LSCR1_GRAY1(x)            (((x) & 0xf))
+
+#define DMACR_BURST	(1 << 31)
+#define DMACR_HM(x)	(((x) & 0xf) << 16)
+#define DMACR_TM(x)	((x) & 0xf)
+
+struct imx_fb_platform_data {
+	u_long		pixclock;
+
+	u_short		xres;
+	u_short		yres;
+
+	u_int		nonstd;
+	u_char		bpp;
+	u_char		hsync_len;
+	u_char		left_margin;
+	u_char		right_margin;
+
+	u_char		vsync_len;
+	u_char		upper_margin;
+	u_char		lower_margin;
+	u_char		sync;
+
+	u_int		cmap_greyscale:1,
+			cmap_inverse:1,
+			cmap_static:1,
+			unused:29;
+
+	u_int		pcr;
+	u_int		pwmr;
+	u_int		lscr1;
+	u_int		dmacr;
+
+	u_char * fixed_screen_cpu;
+	dma_addr_t fixed_screen_dma;
+
+	int (*init)(struct platform_device*);
+	int (*exit)(struct platform_device*);
+
+	void (*lcd_power)(int);
+	void (*backlight_power)(int);
+};
+
+void set_imx_fb_info(struct imx_fb_platform_data *);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/imx-uart.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/imx-uart.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/imx-uart.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/imx-uart.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,4 @@ struct imxuart_platform_data {
 	unsigned int flags;
 };
 
-int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata);
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,127 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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.
+*/
+
+#ifndef _MXC_IOMUX_H
+#define _MXC_IOMUX_H
+
+/*
+*  GPIO Module and I/O Multiplexer
+*  x = 0..3 for reg_A, reg_B, reg_C, reg_D
+*/
+#define VA_GPIO_BASE	IO_ADDRESS(GPIO_BASE_ADDR)
+#define MXC_DDIR(x)    (0x00 + ((x) << 8))
+#define MXC_OCR1(x)    (0x04 + ((x) << 8))
+#define MXC_OCR2(x)    (0x08 + ((x) << 8))
+#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
+#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
+#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
+#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
+#define MXC_DR(x)      (0x1c + ((x) << 8))
+#define MXC_GIUS(x)    (0x20 + ((x) << 8))
+#define MXC_SSR(x)     (0x24 + ((x) << 8))
+#define MXC_ICR1(x)    (0x28 + ((x) << 8))
+#define MXC_ICR2(x)    (0x2c + ((x) << 8))
+#define MXC_IMR(x)     (0x30 + ((x) << 8))
+#define MXC_ISR(x)     (0x34 + ((x) << 8))
+#define MXC_GPR(x)     (0x38 + ((x) << 8))
+#define MXC_SWR(x)     (0x3c + ((x) << 8))
+#define MXC_PUEN(x)    (0x40 + ((x) << 8))
+
+#ifdef CONFIG_ARCH_MX1
+# define GPIO_PORT_MAX  3
+#endif
+#ifdef CONFIG_ARCH_MX2
+# define GPIO_PORT_MAX  5
+#endif
+
+#ifndef GPIO_PORT_MAX
+# error "GPIO config port count unknown!"
+#endif
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
+#define GPIO_OUT   (1 << 8)
+#define GPIO_IN    (0 << 8)
+#define GPIO_PUEN  (1 << 9)
+
+#define GPIO_PF    (1 << 10)
+#define GPIO_AF    (1 << 11)
+
+#define GPIO_OCR_SHIFT 12
+#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
+#define GPIO_AIN   (0 << GPIO_OCR_SHIFT)
+#define GPIO_BIN   (1 << GPIO_OCR_SHIFT)
+#define GPIO_CIN   (2 << GPIO_OCR_SHIFT)
+#define GPIO_GPIO  (3 << GPIO_OCR_SHIFT)
+
+#define GPIO_AOUT_SHIFT 14
+#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT     (0 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_0   (2 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_1   (3 << GPIO_AOUT_SHIFT)
+
+#define GPIO_BOUT_SHIFT 16
+#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT      (0 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_ISR  (1 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_0    (2 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_1    (3 << GPIO_BOUT_SHIFT)
+
+
+#ifdef CONFIG_ARCH_MX1
+#include <mach/iomux-mx1.h>
+#endif
+#ifdef CONFIG_ARCH_MX2
+#include <mach/iomux-mx2x.h>
+#ifdef CONFIG_MACH_MX21
+#include <mach/iomux-mx21.h>
+#endif
+#ifdef CONFIG_MACH_MX27
+#include <mach/iomux-mx27.h>
+#endif
+#endif
+
+
+/* decode irq number to use with IMR(x), ISR(x) and friends */
+#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
+
+#define IRQ_GPIOA(x)  (MXC_GPIO_IRQ_START + x)
+#define IRQ_GPIOB(x)  (IRQ_GPIOA(32) + x)
+#define IRQ_GPIOC(x)  (IRQ_GPIOB(32) + x)
+#define IRQ_GPIOD(x)  (IRQ_GPIOC(32) + x)
+#define IRQ_GPIOE(x)  (IRQ_GPIOD(32) + x)
+
+
+extern void mxc_gpio_mode(int gpio_mode);
+extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+	const char *label);
+extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <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
+* 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 _MXC_IOMUX_MX1_H
+#define _MXC_IOMUX_MX1_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+/* FIXME: This list is not completed. The correct directions are
+* missing on some (many) pins
+*/
+
+
+/* Primary GPIO pin functions */
+
+#define PA0_AIN_SPI2_CLK        (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA0_AF_ETMTRACESYNC     (GPIO_PORTA | GPIO_AF | 0)
+#define PA1_AOUT_SPI2_RXD       (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1)
+#define PA1_PF_TIN              (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_PWM0             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2)
+#define PA3_PF_CSI_MCLK         (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_CSI_D0           (GPIO_PORTA | GPIO_PF | 4)
+#define PA5_PF_CSI_D1           (GPIO_PORTA | GPIO_PF | 5)
+#define PA6_PF_CSI_D2           (GPIO_PORTA | GPIO_PF | 6)
+#define PA7_PF_CSI_D3           (GPIO_PORTA | GPIO_PF | 7)
+#define PA8_PF_CSI_D4           (GPIO_PORTA | GPIO_PF | 8)
+#define PA9_PF_CSI_D5           (GPIO_PORTA | GPIO_PF | 9)
+#define PA10_PF_CSI_D6          (GPIO_PORTA | GPIO_PF | 10)
+#define PA11_PF_CSI_D7          (GPIO_PORTA | GPIO_PF | 11)
+#define PA12_PF_CSI_VSYNC       (GPIO_PORTA | GPIO_PF | 12)
+#define PA13_PF_CSI_HSYNC       (GPIO_PORTA | GPIO_PF | 13)
+#define PA14_PF_CSI_PIXCLK      (GPIO_PORTA | GPIO_PF | 14)
+#define PA15_PF_I2C_SDA         (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_I2C_SCL         (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_AF_ETMTRACEPKT4    (GPIO_PORTA | GPIO_AF | 17)
+#define PA17_AIN_SPI2_SS        (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA18_AF_ETMTRACEPKT5    (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_ETMTRACEPKT6    (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_ETMTRACEPKT7    (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_PF_A0              (GPIO_PORTA | GPIO_PF | 21)
+#define PA22_PF_CS4             (GPIO_PORTA | GPIO_PF | 22)
+#define PA23_PF_CS5             (GPIO_PORTA | GPIO_PF | 23)
+#define PA24_PF_A16             (GPIO_PORTA | GPIO_PF | 24)
+#define PA24_AF_ETMTRACEPKT0    (GPIO_PORTA | GPIO_AF | 24)
+#define PA25_PF_A17             (GPIO_PORTA | GPIO_PF | 25)
+#define PA25_AF_ETMTRACEPKT1    (GPIO_PORTA | GPIO_AF | 25)
+#define PA26_PF_A18             (GPIO_PORTA | GPIO_PF | 26)
+#define PA26_AF_ETMTRACEPKT2    (GPIO_PORTA | GPIO_AF | 26)
+#define PA27_PF_A19             (GPIO_PORTA | GPIO_PF | 27)
+#define PA27_AF_ETMTRACEPKT3    (GPIO_PORTA | GPIO_AF | 27)
+#define PA28_PF_A20             (GPIO_PORTA | GPIO_PF | 28)
+#define PA28_AF_ETMPIPESTAT0    (GPIO_PORTA | GPIO_AF | 28)
+#define PA29_PF_A21             (GPIO_PORTA | GPIO_PF | 29)
+#define PA29_AF_ETMPIPESTAT1    (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_PF_A22             (GPIO_PORTA | GPIO_PF | 30)
+#define PA30_AF_ETMPIPESTAT2    (GPIO_PORTA | GPIO_AF | 30)
+#define PA31_PF_A23             (GPIO_PORTA | GPIO_PF | 31)
+#define PA31_AF_ETMTRACECLK     (GPIO_PORTA | GPIO_AF | 31)
+#define PB8_PF_SD_DAT0          (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
+#define PB8_AF_MS_PIO           (GPIO_PORTB | GPIO_AF | 8)
+#define PB9_PF_SD_DAT1          (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
+#define PB9_AF_MS_PI1           (GPIO_PORTB | GPIO_AF | 9)
+#define PB10_PF_SD_DAT2         (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
+#define PB10_AF_MS_SCLKI        (GPIO_PORTB | GPIO_AF | 10)
+#define PB11_PF_SD_DAT3         (GPIO_PORTB | GPIO_PF | 11)
+#define PB11_AF_MS_SDIO         (GPIO_PORTB | GPIO_AF | 11)
+#define PB12_PF_SD_CLK          (GPIO_PORTB | GPIO_PF | 12)
+#define PB12_AF_MS_SCLK0        (GPIO_PORTB | GPIO_AF | 12)
+#define PB13_PF_SD_CMD          (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
+#define PB13_AF_MS_BS           (GPIO_PORTB | GPIO_AF | 13)
+#define PB14_AF_SSI_RXFS        (GPIO_PORTB | GPIO_AF | 14)
+#define PB15_AF_SSI_RXCLK       (GPIO_PORTB | GPIO_AF | 15)
+#define PB16_AF_SSI_RXDAT       (GPIO_PORTB | GPIO_AF | GPIO_IN | 16)
+#define PB17_AF_SSI_TXDAT       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17)
+#define PB18_AF_SSI_TXFS        (GPIO_PORTB | GPIO_AF | 18)
+#define PB19_AF_SSI_TXCLK       (GPIO_PORTB | GPIO_AF | 19)
+#define PB20_PF_USBD_AFE        (GPIO_PORTB | GPIO_PF | 20)
+#define PB21_PF_USBD_OE         (GPIO_PORTB | GPIO_PF | 21)
+#define PB22_PF_USBD_RCV        (GPIO_PORTB | GPIO_PF | 22)
+#define PB23_PF_USBD_SUSPND     (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USBD_VP         (GPIO_PORTB | GPIO_PF | 24)
+#define PB25_PF_USBD_VM         (GPIO_PORTB | GPIO_PF | 25)
+#define PB26_PF_USBD_VPO        (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBD_VMO        (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_UART2_CTS       (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28)
+#define PB29_PF_UART2_RTS       (GPIO_PORTB | GPIO_PF | GPIO_IN | 29)
+#define PB30_PF_UART2_TXD       (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30)
+#define PB31_PF_UART2_RXD       (GPIO_PORTB | GPIO_PF | GPIO_IN | 31)
+#define PC3_PF_SSI_RXFS         (GPIO_PORTC | GPIO_PF | 3)
+#define PC4_PF_SSI_RXCLK        (GPIO_PORTC | GPIO_PF | 4)
+#define PC5_PF_SSI_RXDAT        (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_SSI_TXDAT        (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6)
+#define PC7_PF_SSI_TXFS         (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_SSI_TXCLK        (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_UART1_CTS        (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_UART1_RTS       (GPIO_PORTC | GPIO_PF | GPIO_IN | 10)
+#define PC11_PF_UART1_TXD       (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_UART1_RXD       (GPIO_PORTC | GPIO_PF | GPIO_IN | 12)
+#define PC13_PF_SPI1_SPI_RDY    (GPIO_PORTC | GPIO_PF | 13)
+#define PC14_PF_SPI1_SCLK       (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_SPI1_SS         (GPIO_PORTC | GPIO_PF | 15)
+#define PC16_PF_SPI1_MISO       (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SPI1_MOSI       (GPIO_PORTC | GPIO_PF | 17)
+#define PC24_BIN_UART3_RI       (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24)
+#define PC25_BIN_UART3_DSR      (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25)
+#define PC26_AOUT_UART3_DTR     (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26)
+#define PC27_BIN_UART3_DCD      (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27)
+#define PC28_BIN_UART3_CTS      (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28)
+#define PC29_AOUT_UART3_RTS     (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29)
+#define PC30_BIN_UART3_TX       (GPIO_PORTC | GPIO_BIN | 30)
+#define PC31_AOUT_UART3_RX      (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31)
+#define PD6_PF_LSCLK            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6)
+#define PD7_PF_REV              (GPIO_PORTD | GPIO_PF | 7)
+#define PD7_AF_UART2_DTR        (GPIO_PORTD | GPIO_AF | GPIO_IN | 7)
+#define PD7_AIN_SPI2_SCLK       (GPIO_PORTD | GPIO_AIN | 7)
+#define PD8_PF_CLS              (GPIO_PORTD | GPIO_PF | 8)
+#define PD8_AF_UART2_DCD        (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8)
+#define PD8_AIN_SPI2_SS         (GPIO_PORTD | GPIO_AIN | 8)
+#define PD9_PF_PS               (GPIO_PORTD | GPIO_PF | 9)
+#define PD9_AF_UART2_RI         (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9)
+#define PD9_AOUT_SPI2_RXD       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9)
+#define PD10_PF_SPL_SPR         (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10)
+#define PD10_AF_UART2_DSR       (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10)
+#define PD10_AIN_SPI2_TXD       (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10)
+#define PD11_PF_CONTRAST        (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11)
+#define PD12_PF_ACD_OE          (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12)
+#define PD13_PF_LP_HSYNC        (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13)
+#define PD14_PF_FLM_VSYNC       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14)
+#define PD15_PF_LD0             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15)
+#define PD16_PF_LD1             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16)
+#define PD17_PF_LD2             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_LD3             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_LD4             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_LD5             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_LD6             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_LD7             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_LD8             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23)
+#define PD24_PF_LD9             (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
+#define PD25_PF_LD10            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_LD11            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_LD12            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_LD13            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_LD14            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_LD15            (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30)
+#define PD31_PF_TMR2OUT         (GPIO_PORTD | GPIO_PF | 31)
+#define PD31_BIN_SPI2_TXD       (GPIO_PORTD | GPIO_BIN | 31)
+
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2008 by Sascha Hauer <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
- * 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 _MXC_GPIO_MX1_MX2_H
-#define _MXC_GPIO_MX1_MX2_H
-
-#include <linux/io.h>
-
-/*
- *  GPIO Module and I/O Multiplexer
- *  x = 0..3 for reg_A, reg_B, reg_C, reg_D
- */
-#define VA_GPIO_BASE	IO_ADDRESS(GPIO_BASE_ADDR)
-#define MXC_DDIR(x)    (0x00 + ((x) << 8))
-#define MXC_OCR1(x)    (0x04 + ((x) << 8))
-#define MXC_OCR2(x)    (0x08 + ((x) << 8))
-#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
-#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
-#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
-#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
-#define MXC_DR(x)      (0x1c + ((x) << 8))
-#define MXC_GIUS(x)    (0x20 + ((x) << 8))
-#define MXC_SSR(x)     (0x24 + ((x) << 8))
-#define MXC_ICR1(x)    (0x28 + ((x) << 8))
-#define MXC_ICR2(x)    (0x2c + ((x) << 8))
-#define MXC_IMR(x)     (0x30 + ((x) << 8))
-#define MXC_ISR(x)     (0x34 + ((x) << 8))
-#define MXC_GPR(x)     (0x38 + ((x) << 8))
-#define MXC_SWR(x)     (0x3c + ((x) << 8))
-#define MXC_PUEN(x)    (0x40 + ((x) << 8))
-
-#ifdef CONFIG_ARCH_MX1
-# define GPIO_PORT_MAX  3
-#endif
-#ifdef CONFIG_ARCH_MX2
-# define GPIO_PORT_MAX  5
-#endif
-
-#ifndef GPIO_PORT_MAX
-# error "GPIO config port count unknown!"
-#endif
-
-#define GPIO_PIN_MASK 0x1f
-
-#define GPIO_PORT_SHIFT 5
-#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
-
-#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
-#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
-#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
-#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
-#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
-#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
-
-#define GPIO_OUT   (1 << 8)
-#define GPIO_IN    (0 << 8)
-#define GPIO_PUEN  (1 << 9)
-
-#define GPIO_PF    (1 << 10)
-#define GPIO_AF    (1 << 11)
-
-#define GPIO_OCR_SHIFT 12
-#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
-#define GPIO_AIN   (0 << GPIO_OCR_SHIFT)
-#define GPIO_BIN   (1 << GPIO_OCR_SHIFT)
-#define GPIO_CIN   (2 << GPIO_OCR_SHIFT)
-#define GPIO_GPIO  (3 << GPIO_OCR_SHIFT)
-
-#define GPIO_AOUT_SHIFT 14
-#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT     (0 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_0   (2 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_1   (3 << GPIO_AOUT_SHIFT)
-
-#define GPIO_BOUT_SHIFT 16
-#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT      (0 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_ISR  (1 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_0    (2 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_1    (3 << GPIO_BOUT_SHIFT)
-
-extern void mxc_gpio_mode(int gpio_mode);
-extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
-					const char *label);
-extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
-
-/*-------------------------------------------------------------------------*/
-
-/* assignements for GPIO alternate/primary functions */
-
-/* FIXME: This list is not completed. The correct directions are
- * missing on some (many) pins
- */
-#ifdef CONFIG_ARCH_MX1
-#define PA0_AIN_SPI2_CLK     (GPIO_PORTA | GPIO_OUT | 0)
-#define PA0_AF_ETMTRACESYNC  (GPIO_PORTA | GPIO_AF | 0)
-#define PA1_AOUT_SPI2_RXD    (GPIO_PORTA | GPIO_IN | 1)
-#define PA1_PF_TIN           (GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_PWM0          (GPIO_PORTA | GPIO_OUT | GPIO_PF | 2)
-#define PA3_PF_CSI_MCLK      (GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_CSI_D0        (GPIO_PORTA | GPIO_PF | 4)
-#define PA5_PF_CSI_D1        (GPIO_PORTA | GPIO_PF | 5)
-#define PA6_PF_CSI_D2        (GPIO_PORTA | GPIO_PF | 6)
-#define PA7_PF_CSI_D3        (GPIO_PORTA | GPIO_PF | 7)
-#define PA8_PF_CSI_D4        (GPIO_PORTA | GPIO_PF | 8)
-#define PA9_PF_CSI_D5        (GPIO_PORTA | GPIO_PF | 9)
-#define PA10_PF_CSI_D6       (GPIO_PORTA | GPIO_PF | 10)
-#define PA11_PF_CSI_D7       (GPIO_PORTA | GPIO_PF | 11)
-#define PA12_PF_CSI_VSYNC    (GPIO_PORTA | GPIO_PF | 12)
-#define PA13_PF_CSI_HSYNC    (GPIO_PORTA | GPIO_PF | 13)
-#define PA14_PF_CSI_PIXCLK   (GPIO_PORTA | GPIO_PF | 14)
-#define PA15_PF_I2C_SDA      (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15)
-#define PA16_PF_I2C_SCL      (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16)
-#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
-#define PA17_AIN_SPI2_SS     (GPIO_PORTA | GPIO_OUT | 17)
-#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
-#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
-#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
-#define PA21_PF_A0           (GPIO_PORTA | GPIO_PF | 21)
-#define PA22_PF_CS4          (GPIO_PORTA | GPIO_PF | 22)
-#define PA23_PF_CS5          (GPIO_PORTA | GPIO_PF | 23)
-#define PA24_PF_A16          (GPIO_PORTA | GPIO_PF | 24)
-#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
-#define PA25_PF_A17          (GPIO_PORTA | GPIO_PF | 25)
-#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
-#define PA26_PF_A18          (GPIO_PORTA | GPIO_PF | 26)
-#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
-#define PA27_PF_A19          (GPIO_PORTA | GPIO_PF | 27)
-#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
-#define PA28_PF_A20          (GPIO_PORTA | GPIO_PF | 28)
-#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
-#define PA29_PF_A21          (GPIO_PORTA | GPIO_PF | 29)
-#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
-#define PA30_PF_A22          (GPIO_PORTA | GPIO_PF | 30)
-#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
-#define PA31_PF_A23          (GPIO_PORTA | GPIO_PF | 31)
-#define PA31_AF_ETMTRACECLK  (GPIO_PORTA | GPIO_AF | 31)
-#define PB8_PF_SD_DAT0       (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
-#define PB8_AF_MS_PIO        (GPIO_PORTB | GPIO_AF | 8)
-#define PB9_PF_SD_DAT1       (GPIO_PORTB | GPIO_PF | GPIO_PUEN  | 9)
-#define PB9_AF_MS_PI1        (GPIO_PORTB | GPIO_AF | 9)
-#define PB10_PF_SD_DAT2      (GPIO_PORTB | GPIO_PF | GPIO_PUEN  | 10)
-#define PB10_AF_MS_SCLKI     (GPIO_PORTB | GPIO_AF | 10)
-#define PB11_PF_SD_DAT3      (GPIO_PORTB | GPIO_PF | 11)
-#define PB11_AF_MS_SDIO      (GPIO_PORTB | GPIO_AF | 11)
-#define PB12_PF_SD_CLK       (GPIO_PORTB | GPIO_PF | 12)
-#define PB12_AF_MS_SCLK0     (GPIO_PORTB | GPIO_AF | 12)
-#define PB13_PF_SD_CMD       (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
-#define PB13_AF_MS_BS        (GPIO_PORTB | GPIO_AF | 13)
-#define PB14_AF_SSI_RXFS     (GPIO_PORTB | GPIO_AF | 14)
-#define PB15_AF_SSI_RXCLK    (GPIO_PORTB | GPIO_AF | 15)
-#define PB16_AF_SSI_RXDAT    (GPIO_PORTB | GPIO_IN | GPIO_AF | 16)
-#define PB17_AF_SSI_TXDAT    (GPIO_PORTB | GPIO_OUT | GPIO_AF | 17)
-#define PB18_AF_SSI_TXFS     (GPIO_PORTB | GPIO_AF | 18)
-#define PB19_AF_SSI_TXCLK    (GPIO_PORTB | GPIO_AF | 19)
-#define PB20_PF_USBD_AFE     (GPIO_PORTB | GPIO_PF | 20)
-#define PB21_PF_USBD_OE      (GPIO_PORTB | GPIO_PF | 21)
-#define PB22_PFUSBD_RCV      (GPIO_PORTB | GPIO_PF | 22)
-#define PB23_PF_USBD_SUSPND  (GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USBD_VP      (GPIO_PORTB | GPIO_PF | 24)
-#define PB25_PF_USBD_VM      (GPIO_PORTB | GPIO_PF | 25)
-#define PB26_PF_USBD_VPO     (GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBD_VMO     (GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_UART2_CTS    (GPIO_PORTB | GPIO_OUT | GPIO_PF | 28)
-#define PB29_PF_UART2_RTS    (GPIO_PORTB | GPIO_IN | GPIO_PF | 29)
-#define PB30_PF_UART2_TXD    (GPIO_PORTB | GPIO_OUT | GPIO_PF | 30)
-#define PB31_PF_UART2_RXD    (GPIO_PORTB | GPIO_IN | GPIO_PF | 31)
-#define PC3_PF_SSI_RXFS      (GPIO_PORTC | GPIO_PF | 3)
-#define PC4_PF_SSI_RXCLK     (GPIO_PORTC | GPIO_PF | 4)
-#define PC5_PF_SSI_RXDAT     (GPIO_PORTC | GPIO_IN | GPIO_PF | 5)
-#define PC6_PF_SSI_TXDAT     (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6)
-#define PC7_PF_SSI_TXFS      (GPIO_PORTC | GPIO_PF | 7)
-#define PC8_PF_SSI_TXCLK     (GPIO_PORTC | GPIO_PF | 8)
-#define PC9_PF_UART1_CTS     (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9)
-#define PC10_PF_UART1_RTS    (GPIO_PORTC | GPIO_IN | GPIO_PF | 10)
-#define PC11_PF_UART1_TXD    (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11)
-#define PC12_PF_UART1_RXD    (GPIO_PORTC | GPIO_IN | GPIO_PF | 12)
-#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
-#define PC14_PF_SPI1_SCLK    (GPIO_PORTC | GPIO_PF | 14)
-#define PC15_PF_SPI1_SS      (GPIO_PORTC | GPIO_PF | 15)
-#define PC16_PF_SPI1_MISO    (GPIO_PORTC | GPIO_PF | 16)
-#define PC17_PF_SPI1_MOSI    (GPIO_PORTC | GPIO_PF | 17)
-#define PC24_BIN_UART3_RI    (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24)
-#define PC25_BIN_UART3_DSR   (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25)
-#define PC26_AOUT_UART3_DTR  (GPIO_PORTC | GPIO_IN | 26)
-#define PC27_BIN_UART3_DCD   (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27)
-#define PC28_BIN_UART3_CTS   (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28)
-#define PC29_AOUT_UART3_RTS  (GPIO_PORTC | GPIO_IN | 29)
-#define PC30_BIN_UART3_TX    (GPIO_PORTC | GPIO_BIN | 30)
-#define PC31_AOUT_UART3_RX   (GPIO_PORTC | GPIO_IN | 31)
-#define PD6_PF_LSCLK         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 6)
-#define PD7_PF_REV           (GPIO_PORTD | GPIO_PF | 7)
-#define PD7_AF_UART2_DTR     (GPIO_PORTD | GPIO_IN | GPIO_AF | 7)
-#define PD7_AIN_SPI2_SCLK    (GPIO_PORTD | GPIO_AIN | 7)
-#define PD8_PF_CLS           (GPIO_PORTD | GPIO_PF | 8)
-#define PD8_AF_UART2_DCD     (GPIO_PORTD | GPIO_OUT | GPIO_AF | 8)
-#define PD8_AIN_SPI2_SS      (GPIO_PORTD | GPIO_AIN | 8)
-#define PD9_PF_PS            (GPIO_PORTD | GPIO_PF | 9)
-#define PD9_AF_UART2_RI      (GPIO_PORTD | GPIO_OUT | GPIO_AF | 9)
-#define PD9_AOUT_SPI2_RXD    (GPIO_PORTD | GPIO_IN | 9)
-#define PD10_PF_SPL_SPR      (GPIO_PORTD | GPIO_OUT | GPIO_PF | 10)
-#define PD10_AF_UART2_DSR    (GPIO_PORTD | GPIO_OUT | GPIO_AF | 10)
-#define PD10_AIN_SPI2_TXD    (GPIO_PORTD | GPIO_OUT | 10)
-#define PD11_PF_CONTRAST     (GPIO_PORTD | GPIO_OUT | GPIO_PF | 11)
-#define PD12_PF_ACD_OE       (GPIO_PORTD | GPIO_OUT | GPIO_PF | 12)
-#define PD13_PF_LP_HSYNC     (GPIO_PORTD | GPIO_OUT | GPIO_PF | 13)
-#define PD14_PF_FLM_VSYNC    (GPIO_PORTD | GPIO_OUT | GPIO_PF | 14)
-#define PD15_PF_LD0          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 15)
-#define PD16_PF_LD1          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 16)
-#define PD17_PF_LD2          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17)
-#define PD18_PF_LD3          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18)
-#define PD19_PF_LD4          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 19)
-#define PD20_PF_LD5          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 20)
-#define PD21_PF_LD6          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 21)
-#define PD22_PF_LD7          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 22)
-#define PD23_PF_LD8          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 23)
-#define PD24_PF_LD9          (GPIO_PORTD | GPIO_OUT | GPIO_PF | 24)
-#define PD25_PF_LD10         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25)
-#define PD26_PF_LD11         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26)
-#define PD27_PF_LD12         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27)
-#define PD28_PF_LD13         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28)
-#define PD29_PF_LD14         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29)
-#define PD30_PF_LD15         (GPIO_PORTD | GPIO_OUT | GPIO_PF | 30)
-#define PD31_PF_TMR2OUT      (GPIO_PORTD | GPIO_PF | 31)
-#define PD31_BIN_SPI2_TXD    (GPIO_PORTD | GPIO_BIN | 31)
-#endif
-
-#ifdef CONFIG_ARCH_MX2
-#define PA0_PF_USBH2_CLK	(GPIO_PORTA | GPIO_PF | 0)
-#define PA1_PF_USBH2_DIR	(GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_USBH2_DATA7	(GPIO_PORTA | GPIO_PF | 2)
-#define PA3_PF_USBH2_NXT	(GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_USBH2_STP	(GPIO_PORTA | GPIO_PF | 4)
-#define PA5_PF_LSCLK		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 5)
-#define PA6_PF_LD0		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 6)
-#define PA7_PF_LD1		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 7)
-#define PA8_PF_LD2		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 8)
-#define PA9_PF_LD3		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 9)
-#define PA10_PF_LD4		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 10)
-#define PA11_PF_LD5		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 11)
-#define PA12_PF_LD6		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 12)
-#define PA13_PF_LD7		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 13)
-#define PA14_PF_LD8		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 14)
-#define PA15_PF_LD9		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 15)
-#define PA16_PF_LD10		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 16)
-#define PA17_PF_LD11		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 17)
-#define PA18_PF_LD12		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 18)
-#define PA19_PF_LD13		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 19)
-#define PA20_PF_LD14		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 20)
-#define PA21_PF_LD15		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 21)
-#define PA22_PF_LD16		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 22)
-#define PA23_PF_LD17		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 23)
-#define PA24_PF_REV		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 24)
-#define PA25_PF_CLS		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 25)
-#define PA26_PF_PS		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 26)
-#define PA27_PF_SPL_SPR		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 27)
-#define PA28_PF_HSYNC		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 28)
-#define PA29_PF_VSYNC		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 29)
-#define PA30_PF_CONTRAST	(GPIO_PORTA | GPIO_OUT | GPIO_PF | 30)
-#define PA31_PF_OE_ACD		(GPIO_PORTA | GPIO_OUT | GPIO_PF | 31)
-#define PB4_PF_SD2_D0		(GPIO_PORTB | GPIO_PF |  4)
-#define PB5_PF_SD2_D1		(GPIO_PORTB | GPIO_PF |  5)
-#define PB6_PF_SD2_D2		(GPIO_PORTB | GPIO_PF |  6)
-#define PB7_PF_SD2_D3		(GPIO_PORTB | GPIO_PF |  7)
-#define PB8_PF_SD2_CMD		(GPIO_PORTB | GPIO_PF |  8)
-#define PB9_PF_SD2_CLK		(GPIO_PORTB | GPIO_PF |  9)
-#define PB10_PF_CSI_D0		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 10)
-#define PB10_AF_UART6_TXD	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 10)
-#define PB11_PF_CSI_D1		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 11)
-#define PB11_AF_UART6_RXD	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 11)
-#define PB12_PF_CSI_D2		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 12)
-#define PB12_AF_UART6_CTS	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 12)
-#define PB13_PF_CSI_D3		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 13)
-#define PB13_AF_UART6_RTS	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 13)
-#define PB14_PF_CSI_D4		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 14)
-#define PB15_PF_CSI_MCLK	(GPIO_PORTB | GPIO_OUT | GPIO_PF | 15)
-#define PB16_PF_CSI_PIXCLK	(GPIO_PORTB | GPIO_OUT | GPIO_PF | 16)
-#define PB17_PF_CSI_D5		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 17)
-#define PB18_PF_CSI_D6		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 18)
-#define PB18_AF_UART5_TXD	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 18)
-#define PB19_PF_CSI_D7		(GPIO_PORTB | GPIO_OUT | GPIO_PF | 19)
-#define PB19_AF_UART5_RXD	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 19)
-#define PB20_PF_CSI_VSYNC	(GPIO_PORTB | GPIO_OUT | GPIO_PF | 20)
-#define PB20_AF_UART5_CTS	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 20)
-#define PB21_PF_CSI_HSYNC	(GPIO_PORTB | GPIO_OUT | GPIO_PF | 21)
-#define PB21_AF_UART5_RTS	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 21)
-#define PB22_PF_USBH1_SUSP	(GPIO_PORTB | GPIO_PF | 22)
-#define PB23_PF_USB_PWR		(GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USB_OC_B	(GPIO_PORTB | GPIO_PF | 24)
-#define PB25_PF_USBH1_RCV	(GPIO_PORTB | GPIO_PF | 25)
-#define PB26_PF_USBH1_FS	(GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBH1_OE_B	(GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_USBH1_TXDM	(GPIO_PORTB | GPIO_PF | 28)
-#define PB29_PF_USBH1_TXDP	(GPIO_PORTB | GPIO_PF | 29)
-#define PB30_PF_USBH1_RXDM	(GPIO_PORTB | GPIO_PF | 30)
-#define PB31_PF_USBH1_RXDP	(GPIO_PORTB | GPIO_PF | 31)
-#define PB26_AF_UART4_RTS	(GPIO_PORTB | GPIO_IN  | GPIO_PF | 26)
-#define PB28_AF_UART4_TXD	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 28)
-#define PB29_AF_UART4_CTS	(GPIO_PORTB | GPIO_OUT | GPIO_AF | 29)
-#define PB31_AF_UART4_RXD	(GPIO_PORTB | GPIO_IN  | GPIO_AF | 31)
-#define PC5_PF_I2C2_SDA		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 5)
-#define PC6_PF_I2C2_SCL		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 6)
-#define PC7_PF_USBOTG_DATA5	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 7)
-#define PC8_PF_USBOTG_DATA6	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 8)
-#define PC9_PF_USBOTG_DATA0	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 9)
-#define PC10_PF_USBOTG_DATA2	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 10)
-#define PC11_PF_USBOTG_DATA1	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 11)
-#define PC12_PF_USBOTG_DATA4	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 12)
-#define PC13_PF_USBOTG_DATA3	(GPIO_PORTC | GPIO_OUT | GPIO_PF | 13)
-#define PC16_PF_SSI4_FS		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 16)
-#define PC17_PF_SSI4_RXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 17)
-#define PC18_PF_SSI4_TXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 18)
-#define PC19_PF_SSI4_CLK	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 19)
-#define PC20_PF_SSI1_FS		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 20)
-#define PC21_PF_SSI1_RXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 21)
-#define PC22_PF_SSI1_TXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 22)
-#define PC23_PF_SSI1_CLK	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 23)
-#define PC24_PF_SSI2_FS		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 24)
-#define PC25_PF_SSI2_RXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 25)
-#define PC26_PF_SSI2_TXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 26)
-#define PC27_PF_SSI2_CLK	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 27)
-#define PC28_PF_SSI3_FS		(GPIO_PORTC | GPIO_IN  | GPIO_PF | 28)
-#define PC29_PF_SSI3_RXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 29)
-#define PC30_PF_SSI3_TXD	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 30)
-#define PC31_PF_SSI3_CLK	(GPIO_PORTC | GPIO_IN  | GPIO_PF | 31)
-#define PD0_AIN_FEC_TXD0	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0)
-#define PD1_AIN_FEC_TXD1	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1)
-#define PD2_AIN_FEC_TXD2	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2)
-#define PD3_AIN_FEC_TXD3	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3)
-#define PD4_AOUT_FEC_RX_ER	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4)
-#define PD5_AOUT_FEC_RXD1	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5)
-#define PD6_AOUT_FEC_RXD2	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6)
-#define PD7_AOUT_FEC_RXD3	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7)
-#define PD8_AF_FEC_MDIO		(GPIO_PORTD | GPIO_IN | GPIO_AF | 8)
-#define PD9_AIN_FEC_MDC		(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9)
-#define PD10_AOUT_FEC_CRS	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10)
-#define PD11_AOUT_FEC_TX_CLK	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11)
-#define PD12_AOUT_FEC_RXD0	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12)
-#define PD13_AOUT_FEC_RX_DV	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13)
-#define PD14_AOUT_FEC_CLR	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14)
-#define PD15_AOUT_FEC_COL	(GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15)
-#define PD16_AIN_FEC_TX_ER	(GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16)
-#define PD17_PF_I2C_DATA	(GPIO_PORTD | GPIO_OUT | GPIO_PF | 17)
-#define PD18_PF_I2C_CLK		(GPIO_PORTD | GPIO_OUT | GPIO_PF | 18)
-#define PD19_AF_USBH2_DATA4	(GPIO_PORTD | GPIO_AF | 19)
-#define PD20_AF_USBH2_DATA3	(GPIO_PORTD | GPIO_AF | 20)
-#define PD21_AF_USBH2_DATA6	(GPIO_PORTD | GPIO_AF | 21)
-#define PD22_AF_USBH2_DATA0	(GPIO_PORTD | GPIO_AF | 22)
-#define PD23_AF_USBH2_DATA2	(GPIO_PORTD | GPIO_AF | 23)
-#define PD24_AF_USBH2_DATA1	(GPIO_PORTD | GPIO_AF | 24)
-#define PD25_PF_CSPI1_RDY	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 25)
-#define PD26_PF_CSPI1_SS2	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 26)
-#define PD26_AF_USBH2_DATA5     (GPIO_PORTD | GPIO_AF | 26)
-#define PD27_PF_CSPI1_SS1	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 27)
-#define PD28_PF_CSPI1_SS0	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 28)
-#define PD29_PF_CSPI1_SCLK	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 29)
-#define PD30_PF_CSPI1_MISO	(GPIO_PORTD | GPIO_IN | GPIO_PF  | 30)
-#define PD31_PF_CSPI1_MOSI	(GPIO_PORTD | GPIO_OUT | GPIO_PF  | 31)
-#define PF23_AIN_FEC_TX_EN	(GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23)
-#define PE0_PF_USBOTG_NXT	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 0)
-#define PE1_PF_USBOTG_STP	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 1)
-#define PE2_PF_USBOTG_DIR	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 2)
-#define PE3_PF_UART2_CTS	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 3)
-#define PE4_PF_UART2_RTS	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 4)
-#define PE6_PF_UART2_TXD	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 6)
-#define PE7_PF_UART2_RXD	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 7)
-#define PE8_PF_UART3_TXD	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 8)
-#define PE9_PF_UART3_RXD	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 9)
-#define PE10_PF_UART3_CTS	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 10)
-#define PE11_PF_UART3_RTS	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 11)
-#define PE12_PF_UART1_TXD	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 12)
-#define PE13_PF_UART1_RXD	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 13)
-#define PE14_PF_UART1_CTS	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 14)
-#define PE15_PF_UART1_RTS	(GPIO_PORTE | GPIO_IN  | GPIO_PF | 15)
-#define PE16_AF_RTCK		(GPIO_PORTE | GPIO_OUT | GPIO_AF | 16)
-#define PE16_PF_RTCK		(GPIO_PORTE | GPIO_OUT | GPIO_PF | 16)
-#define PE18_PF_SDHC1_D0	(GPIO_PORTE | GPIO_PF | 18)
-#define PE18_AF_CSPI3_MISO	(GPIO_PORTE | GPIO_IN  | GPIO_AF | 18)
-#define PE19_PF_SDHC1_D1	(GPIO_PORTE | GPIO_PF | 19)
-#define PE20_PF_SDHC1_D2	(GPIO_PORTE | GPIO_PF | 20)
-#define PE21_PF_SDHC1_D3	(GPIO_PORTE | GPIO_PF | 21)
-#define PE21_AF_CSPI3_SS	(GPIO_PORTE | GPIO_OUT | GPIO_AF | 21)
-#define PE22_PF_SDHC1_CMD	(GPIO_PORTE | GPIO_PF | 22)
-#define PE22_AF_CSPI3_MOSI	(GPIO_PORTE | GPIO_OUT | GPIO_AF | 22)
-#define PE22_PF_SDHC1_CLK	(GPIO_PORTE | GPIO_PF | 23)
-#define PE23_AF_CSPI3_SCLK	(GPIO_PORTE | GPIO_OUT | GPIO_AF | 23)
-#define PE24_PF_USBOTG_CLK	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 24)
-#define PE25_PF_USBOTG_DATA7	(GPIO_PORTE | GPIO_OUT | GPIO_PF | 25)
-#endif
-
-/* decode irq number to use with IMR(x), ISR(x) and friends */
-#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
-
-#define IRQ_GPIOA(x)  (MXC_GPIO_IRQ_START + x)
-#define IRQ_GPIOB(x)  (IRQ_GPIOA(32) + x)
-#define IRQ_GPIOC(x)  (IRQ_GPIOB(32) + x)
-#define IRQ_GPIOD(x)  (IRQ_GPIOC(32) + x)
-#define IRQ_GPIOE(x)  (IRQ_GPIOD(32) + x)
-
-#endif /* _MXC_GPIO_MX1_MX2_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx21.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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.
+*/
+
+#ifndef _MXC_IOMUX_MX21_H
+#define _MXC_IOMUX_MX21_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PB22_PF_USBH1_BYP       (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_ON        (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_USBOTG_SDA       (GPIO_PORTC | GPIO_PF | 5)
+#define PC6_PF_USBOTG_SCL       (GPIO_PORTC | GPIO_PF | 6)
+#define PC7_PF_USBOTG_ON        (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_USBOTG_FS        (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_USBOTG_OE        (GPIO_PORTC | GPIO_PF | 9)
+#define PC10_PF_USBOTG_TXDM     (GPIO_PORTC | GPIO_PF | 10)
+#define PC11_PF_USBOTG_TXDP     (GPIO_PORTC | GPIO_PF | 11)
+#define PC12_PF_USBOTG_RXDM     (GPIO_PORTC | GPIO_PF | 12)
+#define PC13_PF_USBOTG_RXDP     (GPIO_PORTC | GPIO_PF | 13)
+#define PC16_PF_SAP_FS          (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SAP_RXD         (GPIO_PORTC | GPIO_PF | 17)
+#define PC18_PF_SAP_TXD         (GPIO_PORTC | GPIO_PF | 18)
+#define PC19_PF_SAP_CLK         (GPIO_PORTC | GPIO_PF | 19)
+#define PE0_PF_TEST_WB2         (GPIO_PORTE | GPIO_PF | 0)
+#define PE1_PF_TEST_WB1         (GPIO_PORTE | GPIO_PF | 1)
+#define PE2_PF_TEST_WB0         (GPIO_PORTE | GPIO_PF | 2)
+#define PF1_PF_NFCE             (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCLE            (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_NFIO0            (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_NFIO1            (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_NFIO2            (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_NFIO3           (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_NFIO4           (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_NFIO5           (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_NFIO6           (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_NFIO7           (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_RES             (GPIO_PORTF | GPIO_PF | 16)
+
+/* Alternate GPIO pin functions */
+
+#define PA5_AF_BMI_CLK_CS       (GPIO_PORTA | GPIO_AF | 5)
+#define PA6_AF_BMI_D0           (GPIO_PORTA | GPIO_AF | 6)
+#define PA7_AF_BMI_D1           (GPIO_PORTA | GPIO_AF | 7)
+#define PA8_AF_BMI_D2           (GPIO_PORTA | GPIO_AF | 8)
+#define PA9_AF_BMI_D3           (GPIO_PORTA | GPIO_AF | 9)
+#define PA10_AF_BMI_D4          (GPIO_PORTA | GPIO_AF | 10)
+#define PA11_AF_BMI_D5          (GPIO_PORTA | GPIO_AF | 11)
+#define PA12_AF_BMI_D6          (GPIO_PORTA | GPIO_AF | 12)
+#define PA13_AF_BMI_D7          (GPIO_PORTA | GPIO_AF | 13)
+#define PA14_AF_BMI_D8          (GPIO_PORTA | GPIO_AF | 14)
+#define PA15_AF_BMI_D9          (GPIO_PORTA | GPIO_AF | 15)
+#define PA16_AF_BMI_D10         (GPIO_PORTA | GPIO_AF | 16)
+#define PA17_AF_BMI_D11         (GPIO_PORTA | GPIO_AF | 17)
+#define PA18_AF_BMI_D12         (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_BMI_D13         (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_BMI_D14         (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_AF_BMI_D15         (GPIO_PORTA | GPIO_AF | 21)
+#define PA22_AF_BMI_READ_REQ    (GPIO_PORTA | GPIO_AF | 22)
+#define PA23_AF_BMI_WRITE       (GPIO_PORTA | GPIO_AF | 23)
+#define PA29_AF_BMI_RX_FULL     (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_AF_BMI_READ        (GPIO_PORTA | GPIO_AF | 30)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SYS_CLK        (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PD21_AIN_USBH2_FS       (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21)
+#define PD22_AIN_USBH2_OE       (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22)
+#define PD23_AIN_USBH2_TXDM     (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23)
+#define PD24_AIN_USBH2_TXDP     (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24)
+#define PE8_AIN_IR_TXD          (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8)
+#define PF0_AIN_PC_RST          (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0)
+#define PF1_AIN_PC_CE1          (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1)
+#define PF2_AIN_PC_CE2          (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2)
+#define PF3_AIN_PC_POE          (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3)
+#define PF4_AIN_PC_OE           (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4)
+#define PF5_AIN_PC_RW           (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SYS_CLK        (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+#define PD27_BIN_EXT_DMA_GRANT  (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27)
+
+/* CIN GPIO pin functions */
+
+#define PB26_CIN_USBH1_RXDAT    (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26)
+
+/* AOUT GPIO pin functions */
+
+#define PA29_AOUT_BMI_WAIT      (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29)
+#define PD19_AOUT_USBH2_RXDM    (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19)
+#define PD20_AOUT_USBH2_RXDP    (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20)
+#define PD25_AOUT_EXT_DMAREQ    (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25)
+#define PD26_AOUT_USBOTG_RXDAT  (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26)
+#define PE9_AOUT_IR_RXD         (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9)
+#define PF6_AOUT_PC_BVD2        (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6)
+#define PF7_AOUT_PC_BVD1        (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7)
+#define PF8_AOUT_PC_VS2         (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8)
+#define PF9_AOUT_PC_VS1         (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9)
+#define PF10_AOUT_PC_WP         (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10)
+#define PF11_AOUT_PC_READY      (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11)
+#define PF12_AOUT_PC_WAIT       (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12)
+#define PF13_AOUT_PC_CD2        (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13)
+#define PF14_AOUT_PC_CD1        (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14)
+
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx27.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,207 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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.
+*/
+
+#ifndef _MXC_IOMUX_MX27_H
+#define _MXC_IOMUX_MX27_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PA0_PF_USBH2_CLK        (GPIO_PORTA | GPIO_PF | 0)
+#define PA1_PF_USBH2_DIR        (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_USBH2_DATA7      (GPIO_PORTA | GPIO_PF | 2)
+#define PA3_PF_USBH2_NXT        (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_USBH2_STP        (GPIO_PORTA | GPIO_PF | 4)
+#define PB22_PF_USBH1_SUSP      (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_RCV       (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_I2C2_SDA         (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_I2C2_SCL         (GPIO_PORTC | GPIO_PF | GPIO_IN | 6)
+#define PC7_PF_USBOTG_DATA5     (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7)
+#define PC8_PF_USBOTG_DATA6     (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8)
+#define PC9_PF_USBOTG_DATA0     (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_USBOTG_DATA2    (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10)
+#define PC11_PF_USBOTG_DATA1    (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_USBOTG_DATA4    (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12)
+#define PC13_PF_USBOTG_DATA3    (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13)
+#define PC16_PF_SSI4_FS         (GPIO_PORTC | GPIO_PF | GPIO_IN | 16)
+#define PC17_PF_SSI4_RXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 17)
+#define PC18_PF_SSI4_TXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 18)
+#define PC19_PF_SSI4_CLK        (GPIO_PORTC | GPIO_PF | GPIO_IN | 19)
+#define PC25_AF_GPT5_TIN        (GPIO_PORTC | GPIO_AF | 25)
+#define PC27_AF_GPT4_TIN        (GPIO_PORTC | GPIO_AF | 27)
+#define PD0_PF_SD3_CMD          (GPIO_PORTD | GPIO_PF | 0)
+#define PD1_PF_SD3_CLK          (GPIO_PORTD | GPIO_PF | 1)
+#define PD2_PF_ATA_DATA0        (GPIO_PORTD | GPIO_PF | 2)
+#define PD3_PF_ATA_DATA1        (GPIO_PORTD | GPIO_PF | 3)
+#define PD4_PF_ATA_DATA2        (GPIO_PORTD | GPIO_PF | 4)
+#define PD5_PF_ATA_DATA3        (GPIO_PORTD | GPIO_PF | 5)
+#define PD6_PF_ATA_DATA4        (GPIO_PORTD | GPIO_PF | 6)
+#define PD7_PF_ATA_DATA5        (GPIO_PORTD | GPIO_PF | 7)
+#define PD8_PF_ATA_DATA6        (GPIO_PORTD | GPIO_PF | 8)
+#define PD9_PF_ATA_DATA7        (GPIO_PORTD | GPIO_PF | 9)
+#define PD10_PF_ATA_DATA8       (GPIO_PORTD | GPIO_PF | 10)
+#define PD11_PF_ATA_DATA9       (GPIO_PORTD | GPIO_PF | 11)
+#define PD12_PF_ATA_DATA10      (GPIO_PORTD | GPIO_PF | 12)
+#define PD13_PF_ATA_DATA11      (GPIO_PORTD | GPIO_PF | 13)
+#define PD14_PF_ATA_DATA12      (GPIO_PORTD | GPIO_PF | 14)
+#define PD15_PF_ATA_DATA13      (GPIO_PORTD | GPIO_PF | 15)
+#define PD16_PF_ATA_DATA14      (GPIO_PORTD | GPIO_PF | 16)
+#define PE0_PF_USBOTG_NXT       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0)
+#define PE1_PF_USBOTG_STP       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1)
+#define PE2_PF_USBOTG_DIR       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2)
+#define PE24_PF_USBOTG_CLK      (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24)
+#define PE25_PF_USBOTG_DATA7    (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25)
+#define PF1_PF_NFCLE            (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCE             (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_PC_POE           (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_PC_RW            (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_PC_IOIS16        (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_PC_RST          (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_PC_BVD2         (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_PC_BVD1         (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_PC_VS2          (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_PC_VS1          (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_PC_PWRON        (GPIO_PORTF | GPIO_PF | 16)
+#define PF17_PF_PC_READY        (GPIO_PORTF | GPIO_PF | 17)
+#define PF18_PF_PC_WAIT         (GPIO_PORTF | GPIO_PF | 18)
+#define PF19_PF_PC_CD2          (GPIO_PORTF | GPIO_PF | 19)
+#define PF20_PF_PC_CD1          (GPIO_PORTF | GPIO_PF | 20)
+#define PF23_PF_ATA_DATA15      (GPIO_PORTF | GPIO_PF | 23)
+
+/* Alternate GPIO pin functions */
+
+#define PB4_AF_MSHC_DATA0       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4)
+#define PB5_AF_MSHC_DATA1       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5)
+#define PB6_AF_MSHC_DATA2       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6)
+#define PB7_AF_MSHC_DATA4       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7)
+#define PB8_AF_MSHC_BS          (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8)
+#define PB9_AF_MSHC_SCLK        (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9)
+#define PB10_AF_UART6_TXD       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10)
+#define PB11_AF_UART6_RXD       (GPIO_PORTB | GPIO_AF | GPIO_IN | 11)
+#define PB12_AF_UART6_CTS       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12)
+#define PB13_AF_UART6_RTS       (GPIO_PORTB | GPIO_AF | GPIO_IN | 13)
+#define PB18_AF_UART5_TXD       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18)
+#define PB19_AF_UART5_RXD       (GPIO_PORTB | GPIO_AF | GPIO_IN | 19)
+#define PB20_AF_UART5_CTS       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20)
+#define PB21_AF_UART5_RTS       (GPIO_PORTB | GPIO_AF | GPIO_IN | 21)
+#define PC8_AF_FEC_MDIO         (GPIO_PORTC | GPIO_AF | GPIO_IN | 8)
+#define PC24_AF_GPT5_TOUT       (GPIO_PORTC | GPIO_AF | 24)
+#define PC26_AF_GPT4_TOUT       (GPIO_PORTC | GPIO_AF | 26)
+#define PD1_AF_ETMTRACE_PKT15   (GPIO_PORTD | GPIO_AF | 1)
+#define PD6_AF_ETMTRACE_PKT14   (GPIO_PORTD | GPIO_AF | 6)
+#define PD7_AF_ETMTRACE_PKT13   (GPIO_PORTD | GPIO_AF | 7)
+#define PD9_AF_ETMTRACE_PKT12   (GPIO_PORTD | GPIO_AF | 9)
+#define PD2_AF_SD3_D0           (GPIO_PORTD | GPIO_AF | 2)
+#define PD3_AF_SD3_D1           (GPIO_PORTD | GPIO_AF | 3)
+#define PD4_AF_SD3_D2           (GPIO_PORTD | GPIO_AF | 4)
+#define PD5_AF_SD3_D3           (GPIO_PORTD | GPIO_AF | 5)
+#define PD8_AF_FEC_MDIO         (GPIO_PORTD | GPIO_AF | GPIO_IN | 8)
+#define PD10_AF_ETMTRACE_PKT11  (GPIO_PORTD | GPIO_AF | 10)
+#define PD11_AF_ETMTRACE_PKT10  (GPIO_PORTD | GPIO_AF | 11)
+#define PD12_AF_ETMTRACE_PKT9   (GPIO_PORTD | GPIO_AF | 12)
+#define PD13_AF_ETMTRACE_PKT8   (GPIO_PORTD | GPIO_AF | 13)
+#define PD14_AF_ETMTRACE_PKT7   (GPIO_PORTD | GPIO_AF | 14)
+#define PD15_AF_ETMTRACE_PKT6   (GPIO_PORTD | GPIO_AF | 15)
+#define PD16_AF_ETMTRACE_PKT5   (GPIO_PORTD | GPIO_AF | 16)
+#define PF1_AF_ETMTRACE_PKT0    (GPIO_PORTF | GPIO_AF | 1)
+#define PF3_AF_ETMTRACE_PKT2    (GPIO_PORTF | GPIO_AF | 3)
+#define PF5_AF_ETMPIPESTAT11    (GPIO_PORTF | GPIO_AF | 5)
+#define PF7_AF_ATA_BUFFER_EN    (GPIO_PORTF | GPIO_AF | 7)
+#define PF8_AF_ATA_IORDY        (GPIO_PORTF | GPIO_AF | 8)
+#define PF9_AF_ATA_INTRQ        (GPIO_PORTF | GPIO_AF | 9)
+#define PF10_AF_ATA_RESET       (GPIO_PORTF | GPIO_AF | 10)
+#define PF11_AF_ATA_DMACK       (GPIO_PORTF | GPIO_AF | 11)
+#define PF12_AF_ATA_DMAREQ      (GPIO_PORTF | GPIO_AF | 12)
+#define PF13_AF_ATA_DA0         (GPIO_PORTF | GPIO_AF | 13)
+#define PF14_AF_ATA_DA1         (GPIO_PORTF | GPIO_AF | 14)
+#define PF15_AF_ETMTRACE_SYNC   (GPIO_PORTF | GPIO_AF | 15)
+#define PF16_AF_ATA_DA2         (GPIO_PORTF | GPIO_AF | 16)
+#define PF17_AF_ATA_CS0         (GPIO_PORTF | GPIO_AF | 17)
+#define PF18_AF_ATA_CS1         (GPIO_PORTF | GPIO_AF | 18)
+#define PF19_AF_ATA_DIOW        (GPIO_PORTF | GPIO_AF | 19)
+#define PF20_AF_ATA_DIOR        (GPIO_PORTF | GPIO_AF | 20)
+#define PF22_AF_ETMTRACE_CLK    (GPIO_PORTF | GPIO_AF | 22)
+#define PF23_AF_ETMTRACE_PKT4   (GPIO_PORTF | GPIO_AF | 23)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SSI1_MCLK      (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PC15_AIN_GPT6_TOUT      (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15)
+#define PD0_AIN_FEC_TXD0        (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0)
+#define PD1_AIN_FEC_TXD1        (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1)
+#define PD2_AIN_FEC_TXD2        (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2)
+#define PD3_AIN_FEC_TXD3        (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3)
+#define PD9_AIN_FEC_MDC         (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9)
+#define PD16_AIN_FEC_TX_ER      (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16)
+#define PD27_AIN_EXT_DMA_GRANT  (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27)
+#define PF23_AIN_FEC_TX_EN      (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SSI2_MCLK      (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+
+/* CIN GPIO pin functions */
+
+#define PD2_CIN_SLCDC1_DAT0     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2)
+#define PD3_CIN_SLCDC1_DAT1     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3)
+#define PD4_CIN_SLCDC1_DAT2     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4)
+#define PD5_CIN_SLCDC1_DAT3     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5)
+#define PD6_CIN_SLCDC1_DAT4     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6)
+#define PD7_CIN_SLCDC1_DAT5     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7)
+#define PD8_CIN_SLCDC1_DAT6     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8)
+#define PD9_CIN_SLCDC1_DAT7     (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9)
+#define PD10_CIN_SLCDC1_DAT8    (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10)
+#define PD11_CIN_SLCDC1_DAT9    (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11)
+#define PD12_CIN_SLCDC1_DAT10   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12)
+#define PD13_CIN_SLCDC1_DAT11   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13)
+#define PD14_CIN_SLCDC1_DAT12   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14)
+#define PD15_CIN_SLCDC1_DAT13   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15)
+#define PD16_CIN_SLCDC1_DAT14   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16)
+#define PD23_CIN_SLCDC1_DAT15   (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23)
+#define PF27_CIN_EXT_DMA_GRANT  (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27)
+/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */
+
+/* AOUT GPIO pin functions */
+
+#define PC14_AOUT_GPT6_TIN      (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14)
+#define PD4_AOUT_FEC_RX_ER      (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4)
+#define PD5_AOUT_FEC_RXD1       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5)
+#define PD6_AOUT_FEC_RXD2       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6)
+#define PD7_AOUT_FEC_RXD3       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7)
+#define PD10_AOUT_FEC_CRS       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10)
+#define PD11_AOUT_FEC_TX_CLK    (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11)
+#define PD12_AOUT_FEC_RXD0      (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12)
+#define PD13_AOUT_FEC_RX_DV     (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13)
+#define PD14_AOUT_FEC_RX_CLK    (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14)
+#define PD15_AOUT_FEC_COL       (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15)
+
+#define PC17_BOUT_PC_IOIS16     (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17)
+#define PC18_BOUT_PC_BVD2       (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18)
+#define PC19_BOUT_PC_BVD1       (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19)
+#define PC28_BOUT_PC_BVD2       (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28)
+#define PC29_BOUT_PC_VS1        (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29)
+#define PC30_BOUT_PC_READY      (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30)
+#define PC31_BOUT_PC_WAIT       (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31)
+
+
+#endif /* _MXC_GPIO_MX1_MX2_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx2x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,237 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.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.
+*/
+
+#ifndef _MXC_IOMUX_MX2x_H
+#define _MXC_IOMUX_MX2x_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PA5_PF_LSCLK            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
+#define PA6_PF_LD0              (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
+#define PA7_PF_LD1              (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
+#define PA8_PF_LD2              (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
+#define PA9_PF_LD3              (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
+#define PA10_PF_LD4             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
+#define PA11_PF_LD5             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
+#define PA12_PF_LD6             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
+#define PA13_PF_LD7             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
+#define PA14_PF_LD8             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
+#define PA15_PF_LD9             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_LD10            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_PF_LD11            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
+#define PA18_PF_LD12            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
+#define PA19_PF_LD13            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
+#define PA20_PF_LD14            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
+#define PA21_PF_LD15            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
+#define PA22_PF_LD16            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
+#define PA23_PF_LD17            (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
+#define PA24_PF_REV             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
+#define PA25_PF_CLS             (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
+#define PA26_PF_PS              (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
+#define PA27_PF_SPL_SPR         (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
+#define PA28_PF_HSYNC           (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
+#define PA29_PF_VSYNC           (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
+#define PA30_PF_CONTRAST        (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
+#define PA31_PF_OE_ACD          (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
+#define PB4_PF_SD2_D0           (GPIO_PORTB | GPIO_PF | 4)
+#define PB5_PF_SD2_D1           (GPIO_PORTB | GPIO_PF | 5)
+#define PB6_PF_SD2_D2           (GPIO_PORTB | GPIO_PF | 6)
+#define PB7_PF_SD2_D3           (GPIO_PORTB | GPIO_PF | 7)
+#define PB8_PF_SD2_CMD          (GPIO_PORTB | GPIO_PF | 8)
+#define PB9_PF_SD2_CLK          (GPIO_PORTB | GPIO_PF | 9)
+#define PB10_PF_CSI_D0          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10)
+#define PB11_PF_CSI_D1          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11)
+#define PB12_PF_CSI_D2          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12)
+#define PB13_PF_CSI_D3          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13)
+#define PB14_PF_CSI_D4          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14)
+#define PB15_PF_CSI_MCLK        (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15)
+#define PB16_PF_CSI_PIXCLK      (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16)
+#define PB17_PF_CSI_D5          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17)
+#define PB18_PF_CSI_D6          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18)
+#define PB19_PF_CSI_D7          (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19)
+#define PB20_PF_CSI_VSYNC       (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20)
+#define PB21_PF_CSI_HSYNC       (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21)
+#define PB23_PF_USB_PWR         (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USB_OC          (GPIO_PORTB | GPIO_PF | 24)
+#define PB26_PF_USBH1_FS        (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBH1_OE        (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_USBH1_TXDM      (GPIO_PORTB | GPIO_PF | 28)
+#define PB29_PF_USBH1_TXDP      (GPIO_PORTB | GPIO_PF | 29)
+#define PB30_PF_USBH1_RXDM      (GPIO_PORTB | GPIO_PF | 30)
+#define PB31_PF_USBH1_RXDP      (GPIO_PORTB | GPIO_PF | 31)
+#define PC14_PF_TOUT            (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_TIN             (GPIO_PORTC | GPIO_PF | 15)
+#define PC20_PF_SSI1_FS         (GPIO_PORTC | GPIO_PF | GPIO_IN | 20)
+#define PC21_PF_SSI1_RXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 21)
+#define PC22_PF_SSI1_TXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 22)
+#define PC23_PF_SSI1_CLK        (GPIO_PORTC | GPIO_PF | GPIO_IN | 23)
+#define PC24_PF_SSI2_FS         (GPIO_PORTC | GPIO_PF | GPIO_IN | 24)
+#define PC25_PF_SSI2_RXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 25)
+#define PC26_PF_SSI2_TXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 26)
+#define PC27_PF_SSI2_CLK        (GPIO_PORTC | GPIO_PF | GPIO_IN | 27)
+#define PC28_PF_SSI3_FS         (GPIO_PORTC | GPIO_PF | GPIO_IN | 28)
+#define PC29_PF_SSI3_RXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 29)
+#define PC30_PF_SSI3_TXD        (GPIO_PORTC | GPIO_PF | GPIO_IN | 30)
+#define PC31_PF_SSI3_CLK        (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
+#define PD17_PF_I2C_DATA        (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_I2C_CLK         (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_CSPI2_SS2       (GPIO_PORTD | GPIO_PF | 19)
+#define PD20_PF_CSPI2_SS1       (GPIO_PORTD | GPIO_PF | 20)
+#define PD21_PF_CSPI2_SS0       (GPIO_PORTD | GPIO_PF | 21)
+#define PD22_PF_CSPI2_SCLK      (GPIO_PORTD | GPIO_PF | 22)
+#define PD23_PF_CSPI2_MISO      (GPIO_PORTD | GPIO_PF | 23)
+#define PD24_PF_CSPI2_MOSI      (GPIO_PORTD | GPIO_PF | 24)
+#define PD25_PF_CSPI1_RDY       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_CSPI1_SS2       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_CSPI1_SS1       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_CSPI1_SS0       (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_CSPI1_SCLK      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_CSPI1_MISO      (GPIO_PORTD | GPIO_PF | GPIO_IN | 30)
+#define PD31_PF_CSPI1_MOSI      (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31)
+#define PE3_PF_UART2_CTS        (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3)
+#define PE4_PF_UART2_RTS        (GPIO_PORTE | GPIO_PF | GPIO_IN | 4)
+#define PE5_PF_PWMO             (GPIO_PORTE | GPIO_PF | 5)
+#define PE6_PF_UART2_TXD        (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6)
+#define PE7_PF_UART2_RXD        (GPIO_PORTE | GPIO_PF | GPIO_IN | 7)
+#define PE8_PF_UART3_TXD        (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8)
+#define PE9_PF_UART3_RXD        (GPIO_PORTE | GPIO_PF | GPIO_IN | 9)
+#define PE10_PF_UART3_CTS       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10)
+#define PE11_PF_UART3_RTS       (GPIO_PORTE | GPIO_PF | GPIO_IN | 11)
+#define PE12_PF_UART1_TXD       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12)
+#define PE13_PF_UART1_RXD       (GPIO_PORTE | GPIO_PF | GPIO_IN | 13)
+#define PE14_PF_UART1_CTS       (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14)
+#define PE15_PF_UART1_RTS       (GPIO_PORTE | GPIO_PF | GPIO_IN | 15)
+#define PE16_PF_RTCK            (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16)
+#define PE17_PF_RESET_OUT       (GPIO_PORTE | GPIO_PF | 17)
+#define PE18_PF_SD1_D0          (GPIO_PORTE | GPIO_PF | 18)
+#define PE19_PF_SD1_D1          (GPIO_PORTE | GPIO_PF | 19)
+#define PE20_PF_SD1_D2          (GPIO_PORTE | GPIO_PF | 20)
+#define PE21_PF_SD1_D3          (GPIO_PORTE | GPIO_PF | 21)
+#define PE22_PF_SD1_CMD         (GPIO_PORTE | GPIO_PF | 22)
+#define PE23_PF_SD1_CLK         (GPIO_PORTE | GPIO_PF | 23)
+#define PF0_PF_NRFB             (GPIO_PORTF | GPIO_PF | 0)
+#define PF2_PF_NFWP             (GPIO_PORTF | GPIO_PF | 2)
+#define PF4_PF_NFALE            (GPIO_PORTF | GPIO_PF | 4)
+#define PF5_PF_NFRE             (GPIO_PORTF | GPIO_PF | 5)
+#define PF6_PF_NFWE             (GPIO_PORTF | GPIO_PF | 6)
+#define PF15_PF_CLKO            (GPIO_PORTF | GPIO_PF | 15)
+#define PF21_PF_CS4             (GPIO_PORTF | GPIO_PF | 21)
+#define PF22_PF_CS5             (GPIO_PORTF | GPIO_PF | 22)
+
+/* Alternate GPIO pin functions */
+
+#define PB26_AF_UART4_RTS       (GPIO_PORTB | GPIO_AF | GPIO_IN | 26)
+#define PB28_AF_UART4_TXD       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28)
+#define PB29_AF_UART4_CTS       (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29)
+#define PB31_AF_UART4_RXD       (GPIO_PORTB | GPIO_AF | GPIO_IN | 31)
+#define PC28_AF_SLCDC2_D0       (GPIO_PORTC | GPIO_AF | 28)
+#define PC29_AF_SLCDC2_RS       (GPIO_PORTC | GPIO_AF | 29)
+#define PC30_AF_SLCDC2_CS       (GPIO_PORTC | GPIO_AF | 30)
+#define PC31_AF_SLCDC2_CLK      (GPIO_PORTC | GPIO_AF | 31)
+#define PD19_AF_USBH2_DATA4     (GPIO_PORTD | GPIO_AF | 19)
+#define PD20_AF_USBH2_DATA3     (GPIO_PORTD | GPIO_AF | 20)
+#define PD21_AF_USBH2_DATA6     (GPIO_PORTD | GPIO_AF | 21)
+#define PD22_AF_USBH2_DATA0     (GPIO_PORTD | GPIO_AF | 22)
+#define PD23_AF_USBH2_DATA2     (GPIO_PORTD | GPIO_AF | 23)
+#define PD24_AF_USBH2_DATA1     (GPIO_PORTD | GPIO_AF | 24)
+#define PD26_AF_USBH2_DATA5     (GPIO_PORTD | GPIO_AF | 26)
+#define PE0_AF_KP_COL6          (GPIO_PORTE | GPIO_AF | 0)
+#define PE1_AF_KP_ROW6          (GPIO_PORTE | GPIO_AF | 1)
+#define PE2_AF_KP_ROW7          (GPIO_PORTE | GPIO_AF | 2)
+#define PE3_AF_KP_COL7          (GPIO_PORTE | GPIO_AF | 3)
+#define PE4_AF_KP_ROW7          (GPIO_PORTE | GPIO_AF | 4)
+#define PE6_AF_KP_COL6          (GPIO_PORTE | GPIO_AF | 6)
+#define PE7_AF_KP_ROW6          (GPIO_PORTE | GPIO_AF | 7)
+#define PE16_AF_OWIRE           (GPIO_PORTE | GPIO_AF | 16)
+#define PE18_AF_CSPI3_MISO      (GPIO_PORTE | GPIO_AF | GPIO_IN | 18)
+#define PE21_AF_CSPI3_SS        (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21)
+#define PE22_AF_CSPI3_MOSI      (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22)
+#define PE23_AF_CSPI3_SCLK      (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23)
+
+/* AIN GPIO pin functions */
+
+#define PA6_AIN_SLCDC1_DAT0     (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6)
+#define PA7_AIN_SLCDC1_DAT1     (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7)
+#define PA8_AIN_SLCDC1_DAT2     (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8)
+#define PA0_AIN_SLCDC1_DAT3     (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA11_AIN_SLCDC1_DAT5    (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11)
+#define PA13_AIN_SLCDC1_DAT7    (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13)
+#define PA15_AIN_SLCDC1_DAT9    (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15)
+#define PA17_AIN_SLCDC1_DAT11   (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA19_AIN_SLCDC1_DAT13   (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19)
+#define PA21_AIN_SLCDC1_DAT15   (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21)
+#define PA22_AIN_EXT_DMAGRANT   (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22)
+#define PA24_AIN_SLCDC1_D0      (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24)
+#define PA25_AIN_SLCDC1_RS      (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25)
+#define PA26_AIN_SLCDC1_CS      (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26)
+#define PA27_AIN_SLCDC1_CLK     (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27)
+#define PB6_AIN_SLCDC1_D0       (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6)
+#define PB7_AIN_SLCDC1_RS       (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7)
+#define PB8_AIN_SLCDC1_CS       (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8)
+#define PB9_AIN_SLCDC1_CLK      (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9)
+#define PB25_AIN_SLCDC1_DAT0    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25)
+#define PB26_AIN_SLCDC1_DAT1    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26)
+#define PB27_AIN_SLCDC1_DAT2    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27)
+#define PB28_AIN_SLCDC1_DAT3    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28)
+#define PB29_AIN_SLCDC1_DAT4    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29)
+#define PB30_AIN_SLCDC1_DAT5    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30)
+#define PB31_AIN_SLCDC1_DAT6    (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31)
+#define PC5_AIN_SLCDC1_DAT7     (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5)
+#define PC6_AIN_SLCDC1_DAT8     (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6)
+#define PC7_AIN_SLCDC1_DAT9     (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7)
+#define PC8_AIN_SLCDC1_DAT10    (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8)
+#define PC9_AIN_SLCDC1_DAT11    (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9)
+#define PC10_AIN_SLCDC1_DAT12   (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10)
+#define PC11_AIN_SLCDC1_DAT13   (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11)
+#define PC12_AIN_SLCDC1_DAT14   (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12)
+#define PC13_AIN_SLCDC1_DAT15   (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13)
+#define PE5_AIN_PC_SPKOUT       (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PE5_BIN_TOUT2           (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5)
+
+/* CIN GPIO pin functions */
+
+#define PA14_CIN_SLCDC1_DAT0    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14)
+#define PA15_CIN_SLCDC1_DAT1    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15)
+#define PA16_CIN_SLCDC1_DAT2    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16)
+#define PA17_CIN_SLCDC1_DAT3    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17)
+#define PA18_CIN_SLCDC1_DAT4    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18)
+#define PA19_CIN_SLCDC1_DAT5    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19)
+#define PA20_CIN_SLCDC1_DAT6    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20)
+#define PA21_CIN_SLCDC1_DAT7    (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21)
+#define PB30_CIN_UART4_CTS      (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30)
+#define PE5_CIN_TOUT3           (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5)
+
+/* AOUT GPIO pin functions */
+
+#define PB29_AOUT_UART4_RXD     (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29)
+#define PB31_AOUT_UART4_RTS     (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31)
+#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8)
+#define PC15_AOUT_WKGD          (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
+#define PF21_AOUT_DTACK         (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
+
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/iomux-mx3.h	2009-06-09 23:05:27.000000000 -0400
@@ -92,7 +92,7 @@ enum iomux_gp_func {
 	MUX_EXTDMAREQ2_MBX_SEL		= 1 << 15,
 	MUX_TAMPER_DETECT_EN		= 1 << 16,
 	MUX_PGP_USB_4WIRE		= 1 << 17,
-	MUX_PGB_USB_COMMON		= 1 << 18,
+	MUX_PGP_USB_COMMON		= 1 << 18,
 	MUX_SDHC_MEMSTICK1		= 1 << 19,
 	MUX_SDHC_MEMSTICK2		= 1 << 20,
 	MUX_PGP_SPLL_BYP		= 1 << 21,
@@ -109,21 +109,44 @@ enum iomux_gp_func {
 };
 
 /*
- * This function enables/disables the general purpose function for a particular
- * signal.
+ * 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
  */
-void iomux_config_gpr(enum iomux_gp_func , bool);
+int mxc_iomux_setup_pin(const unsigned int pin, const char *label);
+/*
+ * setups mutliple pins
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+		const char *label);
 
 /*
- * set the mode for a IOMUX pin.
+ * releases a single pin:
+ * 	- make it available for a future use by another driver
+ * 	- frees the GPIO if the pin was configured as GPIO
+ * 	- DOES NOT reconfigure the IOMUX in its reset state
  */
-int mxc_iomux_mode(unsigned int);
+void mxc_iomux_release_pin(const unsigned int pin);
+/*
+ * releases multiple pins
+ * convenvient way to call the above function with tables
+ */
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
 
 /*
  * This function enables/disables the general purpose function for a particular
  * signal.
  */
-void mxc_iomux_set_gpr(enum iomux_gp_func, bool);
+void mxc_iomux_set_gpr(enum iomux_gp_func, bool en);
+
+/*
+ * This function only configures the iomux hardware.
+ * It is called by the setup functions and should not be called directly anymore.
+ * It is here visible for backward compatibility
+ */
+int mxc_iomux_mode(unsigned int pin_mode);
 
 #define IOMUX_PADNUM_MASK	0x1ff
 #define IOMUX_GPIONUM_SHIFT	9
@@ -144,6 +167,11 @@ void mxc_iomux_set_gpr(enum iomux_gp_fun
 	MXC_GPIO_IRQ_START)
 
 /*
+ * The number of gpio devices among the pads
+ */
+#define GPIO_PORT_MAX 3
+
+/*
  * This enumeration is constructed based on the Section
  * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
  * value is constructed based on the rules described above.
@@ -480,6 +508,9 @@ enum iomux_pins {
 	MX31_PIN_CAPTURE	= IOMUX_PIN( 7,   327),
 };
 
+#define PIN_MAX 327
+#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */
+
 /*
  * Convenience values for use with mxc_iomux_mode()
  *
@@ -487,6 +518,8 @@ enum iomux_pins {
  */
 #define MX31_PIN_CSPI3_MOSI__RXD3	IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CSPI3_MISO__TXD3	IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI3_SCLK__RTS3	IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI3_SPI_RDY__CTS3	IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CTS1__CTS1		IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC)
 #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)
@@ -507,7 +540,9 @@ enum iomux_pins {
 #define MX31_PIN_CSPI1_SS1__SS1		IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_CSPI1_SS2__SS2		IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_CSPI2_MOSI__MOSI	IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MOSI__SCL	IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CSPI2_MISO__MISO	IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MISO__SDA	IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)
 #define MX31_PIN_CSPI2_SCLK__SCLK	IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY	IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_CSPI2_SS0__SS0		IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC)
@@ -525,6 +560,79 @@ enum iomux_pins {
 #define MX31_PIN_SD1_DATA0__SD1_DATA0	IOMUX_MODE(MX31_PIN_SD1_DATA0, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SD1_CLK__SD1_CLK	IOMUX_MODE(MX31_PIN_SD1_CLK, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SD1_CMD__SD1_CMD	IOMUX_MODE(MX31_PIN_SD1_CMD, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_ATA_CS0__GPIO3_26	IOMUX_MODE(MX31_PIN_ATA_CS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_CS1__GPIO3_27	IOMUX_MODE(MX31_PIN_ATA_CS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_PC_PWRON__SD2_DATA3	IOMUX_MODE(MX31_PIN_PC_PWRON, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_VS1__SD2_DATA2	IOMUX_MODE(MX31_PIN_PC_VS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_READY__SD2_DATA1	IOMUX_MODE(MX31_PIN_PC_READY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_WAIT_B__SD2_DATA0	IOMUX_MODE(MX31_PIN_PC_WAIT_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD2_B__SD2_CLK	IOMUX_MODE(MX31_PIN_PC_CD2_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD1_B__SD2_CMD	IOMUX_MODE(MX31_PIN_PC_CD1_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_ATA_DIOR__GPIO3_28	IOMUX_MODE(MX31_PIN_ATA_DIOR, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_DIOW__GPIO3_29	IOMUX_MODE(MX31_PIN_ATA_DIOW, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_LD0__LD0		IOMUX_MODE(MX31_PIN_LD0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD1__LD1		IOMUX_MODE(MX31_PIN_LD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD2__LD2		IOMUX_MODE(MX31_PIN_LD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD3__LD3		IOMUX_MODE(MX31_PIN_LD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD4__LD4		IOMUX_MODE(MX31_PIN_LD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD5__LD5		IOMUX_MODE(MX31_PIN_LD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD6__LD6		IOMUX_MODE(MX31_PIN_LD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD7__LD7		IOMUX_MODE(MX31_PIN_LD7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD8__LD8		IOMUX_MODE(MX31_PIN_LD8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD9__LD9		IOMUX_MODE(MX31_PIN_LD9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD10__LD10		IOMUX_MODE(MX31_PIN_LD10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD11__LD11		IOMUX_MODE(MX31_PIN_LD11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD12__LD12		IOMUX_MODE(MX31_PIN_LD12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD13__LD13		IOMUX_MODE(MX31_PIN_LD13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD14__LD14		IOMUX_MODE(MX31_PIN_LD14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD15__LD15		IOMUX_MODE(MX31_PIN_LD15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD16__LD16		IOMUX_MODE(MX31_PIN_LD16, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD17__LD17		IOMUX_MODE(MX31_PIN_LD17, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_VSYNC3__VSYNC3		IOMUX_MODE(MX31_PIN_VSYNC3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_HSYNC__HSYNC		IOMUX_MODE(MX31_PIN_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_FPSHIFT__FPSHIFT	IOMUX_MODE(MX31_PIN_FPSHIFT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DRDY0__DRDY0		IOMUX_MODE(MX31_PIN_DRDY0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_REV__D3_REV		IOMUX_MODE(MX31_PIN_D3_REV, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CONTRAST__CONTRAST	IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_SPL__D3_SPL		IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_CLS__D3_CLS		IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LCS0__GPI03_23		IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO1_1__GPIO          IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_I2C_CLK__SCL		IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_I2C_DAT__SDA		IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DTE1__I2C2_SDA	IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_RI_DTE1__I2C2_SCL	IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_CSI_D4__CSI_D4		IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D5__CSI_D5		IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D6__CSI_D6		IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D7__CSI_D7		IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D8__CSI_D8		IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D9__CSI_D9		IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D10__CSI_D10	IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D11__CSI_D11	IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D12__CSI_D12	IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D13__CSI_D13	IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D14__CSI_D14	IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D15__CSI_D15	IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_HSYNC__CSI_HSYNC	IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_MCLK__CSI_MCLK	IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_PIXCLK__CSI_PIXCLK	IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_VSYNC__CSI_VSYNC	IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC)
+#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_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)
+#define MX31_PIN_USBOTG_DATA3__USBOTG_DATA3    IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA4__USBOTG_DATA4    IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA5__USBOTG_DATA5    IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA6__USBOTG_DATA6    IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA7__USBOTG_DATA7    IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_CLK__USBOTG_CLK        IOMUX_MODE(MX31_PIN_USBOTG_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DIR__USBOTG_DIR        IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_NXT__USBOTG_NXT        IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_STP__USBOTG_STP        IOMUX_MODE(MX31_PIN_USBOTG_STP, 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.29-gnu1/arch/arm/plat-mxc/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,7 @@
 
 #define NR_IRQS			(MXC_IPU_IRQ_START + MX3_IPU_IRQS)
 
-extern void imx_irq_set_priority(unsigned char irq, unsigned char prio);
+extern int imx_irq_set_priority(unsigned char irq, unsigned char prio);
 
 /* all normal IRQs can be FIQs */
 #define FIQ_START	0
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,9 +14,22 @@
 #if defined CONFIG_ARCH_MX1
 #define PHYS_OFFSET		UL(0x08000000)
 #elif defined CONFIG_ARCH_MX2
+#ifdef CONFIG_MACH_MX21
+#define PHYS_OFFSET		UL(0xC0000000)
+#endif
+#ifdef CONFIG_MACH_MX27
 #define PHYS_OFFSET		UL(0xA0000000)
+#endif
 #elif defined CONFIG_ARCH_MX3
 #define PHYS_OFFSET		UL(0x80000000)
 #endif
 
+#if defined(CONFIG_MX1_VIDEO)
+/*
+ * Increase size of DMA-consistent memory region.
+ * This is required for i.MX camera driver to capture at least four VGA frames.
+ */
+#define CONSISTENT_DMA_SIZE SZ_4M
+#endif /* CONFIG_MX1_VIDEO */
+
 #endif /* __ASM_ARCH_MXC_MEMORY_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx1_camera.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx1_camera.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx1_camera.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx1_camera.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * mx1_camera.h - i.MX1/i.MXL camera driver header file
+ *
+ * Copyright (c) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * Based on PXA camera.h file:
+ * Copyright (C) 2003, Intel Corporation
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#define MX1_CAMERA_DATA_HIGH	1
+#define MX1_CAMERA_PCLK_RISING	2
+#define MX1_CAMERA_VSYNC_HIGH	4
+
+extern unsigned char mx1_camera_sof_fiq_start, mx1_camera_sof_fiq_end;
+
+/**
+ * struct mx1_camera_pdata - i.MX1/i.MXL camera platform data
+ * @mclk_10khz:	master clock frequency in 10kHz units
+ * @flags:	MX1 camera platform flags
+ */
+struct mx1_camera_pdata {
+	unsigned long mclk_10khz;
+	unsigned long flags;
+};
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx21.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx21.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx21.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Holger Schurig, hs4233@mail.mn-solutions.de
+ *
+ * This contains i.MX21-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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_MX21_H__
+#define __ASM_ARCH_MXC_MX21_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+
+/* Memory regions and CS */
+#define SDRAM_BASE_ADDR         0xC0000000
+#define 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
+
+/* 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 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 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
+
+/* fixed DMA request numbers */
+#define DMA_REQ_BMI_RX          29
+#define DMA_REQ_BMI_TX          28
+#define DMA_REQ_FIRI_RX         4
+
+#endif /* __ASM_ARCH_MXC_MX21_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx27.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx27.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx27.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,10 @@
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  *
+ * This contains i.MX27-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -27,35 +31,6 @@
 /* IRAM */
 #define IRAM_BASE_ADDR          0xFFFF4C00	/* internal ram */
 
-/* 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 MSHC_BASE_ADDR          (AIPI_BASE_ADDR + 0x18000)
 #define GPT5_BASE_ADDR          (AIPI_BASE_ADDR + 0x19000)
 #define GPT4_BASE_ADDR          (AIPI_BASE_ADDR + 0x1A000)
@@ -64,55 +39,24 @@
 #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 LCDC_BASE_ADDR          (AIPI_BASE_ADDR + 0x21000)
-#define SLCDC_BASE_ADDR         (AIPI_BASE_ADDR + 0x22000)
 #define VPU_BASE_ADDR           (AIPI_BASE_ADDR + 0x23000)
-#define USBOTG_BASE_ADDR        (AIPI_BASE_ADDR + 0x24000)
-/* for mx27*/
 #define OTG_BASE_ADDR           USBOTG_BASE_ADDR
 #define SAHARA_BASE_ADDR        (AIPI_BASE_ADDR + 0x25000)
-#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 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 JAM_BASE_ADDR           (AIPI_BASE_ADDR + 0x3E000)
-#define MAX_BASE_ADDR           (AIPI_BASE_ADDR + 0x3F000)
-
-/* ROMP and AVIC */
+/* ROM patch */
 #define ROMP_BASE_ADDR          0x10041000
 
-#define AVIC_BASE_ADDR          0x10040000
-
-#define SAHB1_BASE_ADDR         0x80000000
-#define SAHB1_BASE_ADDR_VIRT    0xF4100000
-#define SAHB1_SIZE              SZ_1M
-
-#define CSI_BASE_ADDR           (SAHB1_BASE_ADDR + 0x0000)
 #define ATA_BASE_ADDR           (SAHB1_BASE_ADDR + 0x1000)
 
-/* 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 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)
-
 /* Memory regions and CS */
-#define SDRAM_BASE_ADDR		0xA0000000
-#define CSD1_BASE_ADDR		0xB0000000
+#define SDRAM_BASE_ADDR         0xA0000000
+#define CSD1_BASE_ADDR          0xB0000000
 
 #define CS0_BASE_ADDR           0xC0000000
 #define CS1_BASE_ADDR           0xC8000000
@@ -122,44 +66,20 @@
 #define CS5_BASE_ADDR           0xD6000000
 #define PCMCIA_MEM_BASE_ADDR    0xDC000000
 
-/*
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-#define IO_ADDRESS(x)   \
-	(void __iomem *) \
-	(((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
-		AIPI_IO_ADDRESS(x) : \
-	((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
-		SAHB1_IO_ADDRESS(x) : \
-	((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \
-		X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF)
-
-/* define the address mapping macros: in physical address order */
-#define AIPI_IO_ADDRESS(x)  \
-	(((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x)	AIPI_IO_ADDRESS(x)
-
-#define SAHB1_IO_ADDRESS(x)  \
-	(((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x)  \
-	(((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x)  \
-	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+/* 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 PCMCIA_IO_ADDRESS(x) \
-	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+#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)
 
-/* fixed interrput numbers */
+/* fixed interrupt numbers */
 #define MXC_INT_CCM		63
 #define MXC_INT_IIM		62
-#define MXC_INT_LCDC		61
-#define MXC_INT_SLCDC		60
 #define MXC_INT_SAHARA		59
 #define MXC_INT_SCC_SCM		58
 #define MXC_INT_SCC_SMN		57
@@ -167,54 +87,12 @@
 #define MXC_INT_USB2		55
 #define MXC_INT_USB1		54
 #define MXC_INT_VPU		53
-#define MXC_INT_EMMAPP		52
-#define MXC_INT_EMMAPRP		51
 #define MXC_INT_FEC		50
 #define MXC_INT_UART5		49
 #define MXC_INT_UART6		48
-#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_ATA		30
-#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_SDHC3		9
-#define MXC_INT_GPIO		8
 #define MXC_INT_SDHC		7
-#define MXC_INT_CSPI3		6
 #define MXC_INT_RTIC		5
 #define MXC_INT_GPT4		4
 #define MXC_INT_GPT5		3
@@ -228,36 +106,9 @@
 #define DMA_REQ_UART6_TX        34
 #define DMA_REQ_UART5_RX        33
 #define DMA_REQ_UART5_TX        32
-#define DMA_REQ_CSI_RX          31
-#define DMA_REQ_CSI_STAT        30
 #define DMA_REQ_ATA_RCV         29
 #define DMA_REQ_ATA_TX          28
-#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_MSHC            4
-#define DMA_REQ_EXT             3
-#define DMA_REQ_CSPI3_TX        2
-#define DMA_REQ_CSPI3_RX        1
 
 /* silicon revisions specific to i.MX27 */
 #define CHIP_REV_1_0		0x00
@@ -267,25 +118,8 @@
 extern int mx27_revision(void);
 #endif
 
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR		 	0x1C
-#define GPIO_GDIR	 	0x00
-#define GPIO_PSR	 	0x24
-#define GPIO_ICR1	 	0x28
-#define GPIO_ICR2	 	0x2C
-#define GPIO_IMR	 	0x30
-#define GPIO_ISR	 	0x34
-#define GPIO_INT_LOW_LEV	0x3
-#define GPIO_INT_HIGH_LEV	0x2
-#define GPIO_INT_RISE_EDGE 	0x0
-#define GPIO_INT_FALL_EDGE	0x1
-#define GPIO_INT_NONE		0x4
-
 /* Mandatory defines used globally */
 
-/* this is an i.MX27 CPU */
-#define cpu_is_mx27()		(1)
-
 /* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
 #define ARCH_NR_GPIOS		(192 + 16)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx2x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This contains hardware definitions that are common between i.MX21 and
+ * i.MX27.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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_MX2x_H__
+#define __ASM_ARCH_MXC_MX2x_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/* 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
+
+#define SAHB1_BASE_ADDR         0x80000000
+#define SAHB1_BASE_ADDR_VIRT    0xF4100000
+#define SAHB1_SIZE              SZ_1M
+
+#define CSI_BASE_ADDR           (SAHB1_BASE_ADDR + 0x0000)
+
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x)   \
+	(void __force __iomem *) \
+	(((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
+		AIPI_IO_ADDRESS(x) : \
+	((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
+		SAHB1_IO_ADDRESS(x) : \
+	((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \
+		X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF)
+
+/* define the address mapping macros: in physical address order */
+#define AIPI_IO_ADDRESS(x)  \
+	(((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x)	AIPI_IO_ADDRESS(x)
+
+#define SAHB1_IO_ADDRESS(x)  \
+	(((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x)  \
+	(((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x)  \
+	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+	(((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
+
+/* gpio and gpio based interrupt handling */
+#define GPIO_DR		 	0x1C
+#define GPIO_GDIR	 	0x00
+#define GPIO_PSR	 	0x24
+#define GPIO_ICR1	 	0x28
+#define GPIO_ICR2	 	0x2C
+#define GPIO_IMR	 	0x30
+#define GPIO_ISR	 	0x34
+#define GPIO_INT_LOW_LEV	0x3
+#define GPIO_INT_HIGH_LEV	0x2
+#define GPIO_INT_RISE_EDGE 	0x0
+#define GPIO_INT_FALL_EDGE	0x1
+#define GPIO_INT_NONE		0x4
+
+/* 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
+
+#endif /* __ASM_ARCH_MXC_MX2x_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx31.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx31.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx31.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,360 +1,45 @@
 /*
- * Copyright 2004-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 version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_MX31_H__
-#define __ASM_ARCH_MXC_MX31_H__
-
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
-/*
- * MX31 memory map:
- *
- * Virt		Phys		Size	What
- * ---------------------------------------------------------------------------
- * F8000000	1FFC0000	16K	IRAM
- * F9000000	30000000	256M	L2CC
- * FC000000	43F00000	1M	AIPS 1
- * FC100000	50000000	1M	SPBA
- * FC200000	53F00000	1M	AIPS 2
- * FC500000	60000000	128M	ROMPATCH
- * FC400000	68000000	128M	AVIC
- *         	70000000	256M	IPU (MAX M2)
- *         	80000000	256M	CSD0 SDRAM/DDR
- *         	90000000	256M	CSD1 SDRAM/DDR
- *         	A0000000	128M	CS0 Flash
- *         	A8000000	128M	CS1 Flash
- *         	B0000000	32M	CS2
- *         	B2000000	32M	CS3
- * F4000000	B4000000	32M	CS4
- *         	B6000000	32M	CS5
- * FC320000	B8000000	64K	NAND, SDRAM, WEIM, M3IF, EMI controllers
- *         	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 PCMCIA_MEM_BASE_ADDR	0xBC000000
-
-/*
  * IRAM
  */
-#define IRAM_BASE_ADDR		0x1FFC0000	/* internal ram */
-#define IRAM_BASE_ADDR_VIRT	0xF8000000
-#define IRAM_SIZE		SZ_16K
-
-/*
- * L2CC
- */
-#define L2CC_BASE_ADDR		0x30000000
-#define L2CC_BASE_ADDR_VIRT	0xF9000000
-#define L2CC_SIZE		SZ_1M
-
-/*
- * AIPS 1
- */
-#define AIPS1_BASE_ADDR		0x43F00000
-#define AIPS1_BASE_ADDR_VIRT	0xFC000000
-#define AIPS1_SIZE		SZ_1M
+#define MX31_IRAM_BASE_ADDR		0x1FFC0000	/* internal ram */
+#define MX31_IRAM_SIZE			SZ_16K
 
-#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 OTG_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00088000)
 #define ATA_BASE_ADDR		(AIPS1_BASE_ADDR + 0x0008C000)
-#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 UART4_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B0000)
 #define UART5_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B4000)
-#define ECT_IP1_BASE_ADDR	(AIPS1_BASE_ADDR + 0x000B8000)
-#define ECT_IP2_BASE_ADDR	(AIPS1_BASE_ADDR + 0x000BC000)
-
-/*
- * SPBA global module enabled #0
- */
-#define SPBA0_BASE_ADDR 	0x50000000
-#define SPBA0_BASE_ADDR_VIRT	0xFC100000
-#define SPBA0_SIZE		SZ_1M
 
 #define MMC_SDHC1_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00004000)
 #define MMC_SDHC2_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00008000)
-#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 SIM1_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00018000)
 #define IIM_BASE_ADDR		(SPBA0_BASE_ADDR + 0x0001C000)
-#define ATA_DMA_BASE_ADDR	(SPBA0_BASE_ADDR + 0x00020000)
-#define MSHC1_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00024000)
-#define MSHC2_BASE_ADDR		(SPBA0_BASE_ADDR + 0x00024000)
-#define SPBA_CTRL_BASE_ADDR	(SPBA0_BASE_ADDR + 0x0003C000)
 
-/*
- * 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 CSPI3_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00084000)
 #define FIRI_BASE_ADDR		(AIPS2_BASE_ADDR + 0x0008C000)
-#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 SCM_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000AE000)
 #define SMN_BASE_ADDR		(AIPS2_BASE_ADDR + 0x000AF000)
-#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 MPEG4_ENC_BASE_ADDR	(AIPS2_BASE_ADDR + 0x000C8000)
-#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)
-
-/*
- * ROMP and AVIC
- */
-#define ROMP_BASE_ADDR		0x60000000
-#define ROMP_BASE_ADDR_VIRT	0xFC500000
-#define ROMP_SIZE		SZ_1M
-
-#define AVIC_BASE_ADDR		0x68000000
-#define AVIC_BASE_ADDR_VIRT	0xFC400000
-#define AVIC_SIZE		SZ_1M
-
-/*
- * NAND, SDRAM, WEIM, M3IF, EMI controllers
- */
-#define X_MEMC_BASE_ADDR	0xB8000000
-#define X_MEMC_BASE_ADDR_VIRT	0xFC320000
-#define X_MEMC_SIZE		SZ_64K
 
-#define NFC_BASE_ADDR		(X_MEMC_BASE_ADDR + 0x0000)
-#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
-
-/*
- * Memory regions and CS
- */
-#define IPU_MEM_BASE_ADDR	0x70000000
-#define CSD0_BASE_ADDR		0x80000000
-#define CSD1_BASE_ADDR		0x90000000
-#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 PCMCIA_MEM_BASE_ADDR	0xBC000000
-
-/*!
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-#define IO_ADDRESS(x)   \
-	(void __iomem *) \
-	(((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
-	((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\
-	((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
-	((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
-	((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
-	((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
-	((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
-	((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
-	((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
-	0xDEADBEEF)
-
-/*
- * define the address mapping macros: in physical address order
- */
-
-#define IRAM_IO_ADDRESS(x)  \
-	(((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
-
-#define L2CC_IO_ADDRESS(x)  \
-	(((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
-
-#define AIPS1_IO_ADDRESS(x)  \
-	(((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
-
-#define SPBA0_IO_ADDRESS(x)  \
-	(((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
-
-#define AIPS2_IO_ADDRESS(x)  \
-	(((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
-
-#define ROMP_IO_ADDRESS(x)  \
-	(((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x)  \
-	(((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x)  \
-	(((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x)  \
-	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
-#define PCMCIA_IO_ADDRESS(x) \
-	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+#define MX31_NFC_BASE_ADDR	(X_MEMC_BASE_ADDR + 0x0000)
 
-/*
- * Interrupt numbers
- */
-#define MXC_INT_PEN_ADS7843	0
-#define MXC_INT_RESV1		1
-#define MXC_INT_CS8900A		2
-#define MXC_INT_I2C3		3
-#define MXC_INT_I2C2		4
 #define MXC_INT_MPEG4_ENCODER	5
-#define MXC_INT_RTIC		6
 #define MXC_INT_FIRI		7
-#define MXC_INT_MMC_SDHC2	8
+#define MX31_INT_MMC_SDHC2	8
 #define MXC_INT_MMC_SDHC1	9
-#define MXC_INT_I2C		10
-#define MXC_INT_SSI2		11
-#define MXC_INT_SSI1		12
-#define MXC_INT_CSPI2		13
-#define MXC_INT_CSPI1		14
-#define MXC_INT_ATA		15
+#define MX31_INT_SSI2		11
+#define MX31_INT_SSI1		12
 #define MXC_INT_MBX		16
 #define MXC_INT_CSPI3		17
-#define MXC_INT_UART3		18
-#define MXC_INT_IIM		19
 #define MXC_INT_SIM2		20
 #define MXC_INT_SIM1		21
-#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_RESV30		30
-#define MXC_INT_RESV31		31
-#define MXC_INT_UART2		32
-#define MXC_INT_NANDFC		33
-#define MXC_INT_SDMA		34
+#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_MSHC1		39
 #define MXC_INT_MSHC2		40
-#define MXC_INT_IPU_ERR		41
-#define MXC_INT_IPU_SYN		42
-#define MXC_INT_RESV43		43
-#define MXC_INT_RESV44		44
-#define MXC_INT_UART1		45
 #define MXC_INT_UART4		46
 #define MXC_INT_UART5		47
-#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_CCM		53
 #define MXC_INT_PCMCIA		54
-#define MXC_INT_WDOG		55
-#define MXC_INT_GPIO3		56
-#define MXC_INT_RESV57		57
-#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 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 SYSTEM_REV_MIN		CHIP_REV_1_0
-#define SYSTEM_REV_NUM		3
-
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR		 	0x00
-#define GPIO_GDIR	 	0x04
-#define GPIO_PSR	 	0x08
-#define GPIO_ICR1	 	0x0C
-#define GPIO_ICR2	 	0x10
-#define GPIO_IMR	 	0x14
-#define GPIO_ISR	 	0x18
-#define GPIO_INT_LOW_LEV	0x0
-#define GPIO_INT_HIGH_LEV	0x1
-#define GPIO_INT_RISE_EDGE	0x2
-#define GPIO_INT_FALL_EDGE	0x3
-#define GPIO_INT_NONE		0x4
-
-/* Mandatory defines used globally */
-
-/* this CPU supports up to 96 GPIOs */
-#define ARCH_NR_GPIOS		96
-
-#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-
-/* this is a i.MX31 CPU */
-#define cpu_is_mx31()		(1)
-
-extern unsigned int system_rev;
-
-static inline int mx31_revision(void)
-{
-	return system_rev;
-}
-#endif
-
-#endif /*  __ASM_ARCH_MXC_MX31_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx35.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx35.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx35.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * IRAM
+ */
+#define MX35_IRAM_BASE_ADDR		0x10000000	/* internal ram */
+#define MX35_IRAM_SIZE		SZ_128K
+
+#define MXC_FEC_BASE_ADDR	0x50038000
+#define MX35_NFC_BASE_ADDR	0xBB000000
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_OWIRE		2
+#define MX35_INT_MMC_SDHC1	7
+#define MXC_INT_MMC_SDHC2	8
+#define MXC_INT_MMC_SDHC3	9
+#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
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3_camera.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3_camera.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3_camera.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3_camera.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ * mx3_camera.h - i.MX3x camera driver header file
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering, <lg@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MX3_CAMERA_H_
+#define _MX3_CAMERA_H_
+
+#include <linux/device.h>
+
+#define MX3_CAMERA_CLK_SRC	1
+#define MX3_CAMERA_EXT_VSYNC	2
+#define MX3_CAMERA_DP		4
+#define MX3_CAMERA_PCP		8
+#define MX3_CAMERA_HSP		0x10
+#define MX3_CAMERA_VSP		0x20
+#define MX3_CAMERA_DATAWIDTH_4	0x40
+#define MX3_CAMERA_DATAWIDTH_8	0x80
+#define MX3_CAMERA_DATAWIDTH_10	0x100
+#define MX3_CAMERA_DATAWIDTH_15	0x200
+
+#define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \
+				   MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15)
+
+/**
+ * struct mx3_camera_pdata - i.MX3x camera platform data
+ * @flags:	MX3_CAMERA_* flags
+ * @mclk_10khz:	master clock frequency in 10kHz units
+ * @dma_dev:	IPU DMA device to match against in channel allocation
+ */
+struct mx3_camera_pdata {
+	unsigned long flags;
+	unsigned long mclk_10khz;
+	struct device *dma_dev;
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3fb.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3fb.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3fb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,25 +14,25 @@
 #include <linux/fb.h>
 
 /* Proprietary FB_SYNC_ flags */
-#define FB_SYNC_OE_ACT_HIGH    0x80000000
-#define FB_SYNC_CLK_INVERT     0x40000000
-#define FB_SYNC_DATA_INVERT    0x20000000
-#define FB_SYNC_CLK_IDLE_EN    0x10000000
-#define FB_SYNC_SHARP_MODE     0x08000000
-#define FB_SYNC_SWAP_RGB       0x04000000
-#define FB_SYNC_CLK_SEL_EN     0x02000000
+#define FB_SYNC_OE_ACT_HIGH	0x80000000
+#define FB_SYNC_CLK_INVERT	0x40000000
+#define FB_SYNC_DATA_INVERT	0x20000000
+#define FB_SYNC_CLK_IDLE_EN	0x10000000
+#define FB_SYNC_SHARP_MODE	0x08000000
+#define FB_SYNC_SWAP_RGB	0x04000000
+#define FB_SYNC_CLK_SEL_EN	0x02000000
 
 /**
  * struct mx3fb_platform_data - mx3fb platform data
  *
- * @dma_dev:   pointer to the dma-device, used for dma-slave connection
- * @mode:      pointer to a platform-provided per mxc_register_fb() videomode
+ * @dma_dev:	pointer to the dma-device, used for dma-slave connection
+ * @mode:	pointer to a platform-provided per mxc_register_fb() videomode
  */
 struct mx3fb_platform_data {
-       struct device                   *dma_dev;
-       const char                      *name;
-       const struct fb_videomode       *mode;
-       int                             num_modes;
+	struct device			*dma_dev;
+	const char			*name;
+	const struct fb_videomode	*mode;
+	int				num_modes;
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mx3x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX31_H__
+#define __ASM_ARCH_MXC_MX31_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*
+ * MX31 memory map:
+ *
+ * Virt		Phys		Size	What
+ * ---------------------------------------------------------------------------
+ * FC000000	43F00000	1M	AIPS 1
+ * FC100000	50000000	1M	SPBA
+ * FC200000	53F00000	1M	AIPS 2
+ * FC500000	60000000	128M	ROMPATCH
+ * FC400000	68000000	128M	AVIC
+ *         	70000000	256M	IPU (MAX M2)
+ *         	80000000	256M	CSD0 SDRAM/DDR
+ *         	90000000	256M	CSD1 SDRAM/DDR
+ *         	A0000000	128M	CS0 Flash
+ *         	A8000000	128M	CS1 Flash
+ *         	B0000000	32M	CS2
+ *         	B2000000	32M	CS3
+ * F4000000	B4000000	32M	CS4
+ *         	B6000000	32M	CS5
+ * FC320000	B8000000	64K	NAND, SDRAM, WEIM, M3IF, EMI controllers
+ *         	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 PCMCIA_MEM_BASE_ADDR	0xBC000000
+
+/*
+ * L2CC
+ */
+#define L2CC_BASE_ADDR		0x30000000
+#define 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)
+
+/*
+ * 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)
+
+/*
+ * 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)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR		0x60000000
+#define ROMP_BASE_ADDR_VIRT	0xFC500000
+#define ROMP_SIZE		SZ_1M
+
+#define AVIC_BASE_ADDR		0x68000000
+#define AVIC_BASE_ADDR_VIRT	0xFC400000
+#define AVIC_SIZE		SZ_1M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR	0xB8000000
+#define X_MEMC_BASE_ADDR_VIRT	0xFC320000
+#define X_MEMC_SIZE		SZ_64K
+
+#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
+
+/*
+ * Memory regions and CS
+ */
+#define IPU_MEM_BASE_ADDR	0x70000000
+#define CSD0_BASE_ADDR		0x80000000
+#define CSD1_BASE_ADDR		0x90000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x)   \
+	(void __force __iomem *) \
+	(((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
+	((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
+	((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
+	((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
+	((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
+	((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
+	((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+	0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define L2CC_IO_ADDRESS(x)  \
+	(((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x)  \
+	(((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x)  \
+	(((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x)  \
+	(((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define ROMP_IO_ADDRESS(x)  \
+	(((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x)  \
+	(((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x)  \
+	(((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x)  \
+	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+	(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+/*
+ * 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 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 SYSTEM_REV_MIN		CHIP_REV_1_0
+#define SYSTEM_REV_NUM		3
+
+/* gpio and gpio based interrupt handling */
+#define GPIO_DR		 	0x00
+#define GPIO_GDIR	 	0x04
+#define GPIO_PSR	 	0x08
+#define GPIO_ICR1	 	0x0C
+#define GPIO_ICR2	 	0x10
+#define GPIO_IMR	 	0x14
+#define GPIO_ISR	 	0x18
+#define GPIO_INT_LOW_LEV	0x0
+#define GPIO_INT_HIGH_LEV	0x1
+#define GPIO_INT_RISE_EDGE	0x2
+#define GPIO_INT_FALL_EDGE	0x3
+#define GPIO_INT_NONE		0x4
+
+/* Mandatory defines used globally */
+
+/* this CPU supports up to 96 GPIOs */
+#define ARCH_NR_GPIOS		96
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern unsigned int system_rev;
+
+static inline int mx31_revision(void)
+{
+	return system_rev;
+}
+#endif
+
+#endif /*  __ASM_ARCH_MXC_MX31_H__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mxc.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mxc.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/mxc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/mxc.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,13 +24,74 @@
 #error "Do not include directly."
 #endif
 
-/* clean up all things that are not used */
-#ifndef CONFIG_ARCH_MX3
-# define cpu_is_mx31() (0)
+#define MXC_CPU_MX1		1
+#define MXC_CPU_MX21		21
+#define MXC_CPU_MX27		27
+#define MXC_CPU_MX31		31
+#define MXC_CPU_MX35		35
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxc_cpu_type;
 #endif
 
-#ifndef CONFIG_MACH_MX27
-# define cpu_is_mx27() (0)
+#ifdef CONFIG_ARCH_MX1
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX1
+# endif
+# define cpu_is_mx1()		(mxc_cpu_type == MXC_CPU_MX1)
+#else
+# define cpu_is_mx1()		(0)
+#endif
+
+#ifdef CONFIG_MACH_MX21
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX21
+# endif
+# define cpu_is_mx21()		(mxc_cpu_type == MXC_CPU_MX21)
+#else
+# define cpu_is_mx21()		(0)
+#endif
+
+#ifdef CONFIG_MACH_MX27
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX27
+# endif
+# define cpu_is_mx27()		(mxc_cpu_type == MXC_CPU_MX27)
+#else
+# define cpu_is_mx27()		(0)
+#endif
+
+#ifdef CONFIG_ARCH_MX31
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX31
+# endif
+# define cpu_is_mx31()		(mxc_cpu_type == MXC_CPU_MX31)
+#else
+# define cpu_is_mx31()		(0)
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX35
+# endif
+# define cpu_is_mx35()		(mxc_cpu_type == MXC_CPU_MX35)
+#else
+# define cpu_is_mx35()		(0)
 #endif
 
 #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
@@ -39,4 +100,7 @@
 #define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
 #endif
 
+#define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
+
 #endif /*  __ASM_ARCH_MXC_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,9 +26,6 @@ static inline void arch_idle(void)
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
-{
-	cpu_reset(0);
-}
+void arch_reset(char mode, const char *cmd);
 
 #endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/iomux-mx1-mx2.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@
 
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
 
 void mxc_gpio_mode(int gpio_mode)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/irq.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,23 +50,27 @@
 #define IIM_PROD_REV_SH		3
 #define IIM_PROD_REV_LEN	5
 
-#ifdef CONFIG_MXC_IRQ_PRIOR
-void imx_irq_set_priority(unsigned char irq, unsigned char prio)
+int imx_irq_set_priority(unsigned char irq, unsigned char prio)
 {
+#ifdef CONFIG_MXC_IRQ_PRIOR
 	unsigned int temp;
 	unsigned int mask = 0x0F << irq % 8 * 4;
 
-	if (irq > 63)
-		return;
+	if (irq >= MXC_INTERNAL_IRQS)
+		return -EINVAL;;
 
 	temp = __raw_readl(AVIC_NIPRIORITY(irq / 8));
 	temp &= ~mask;
 	temp |= prio & mask;
 
 	__raw_writel(temp, AVIC_NIPRIORITY(irq / 8));
+
+	return 0;
+#else
+	return -ENOSYS;
+#endif
 }
 EXPORT_SYMBOL(imx_irq_set_priority);
-#endif
 
 #ifdef CONFIG_FIQ
 int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/Kconfig linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@ if ARCH_MXC
 menu "Freescale MXC Implementations"
 
 choice
-	prompt "MXC/iMX Base Type"
+	prompt "Freescale CPU family:"
 	default ARCH_MX3
 
 config ARCH_MX1
@@ -15,12 +15,14 @@ config ARCH_MX1
 config ARCH_MX2
 	bool "MX2-based"
 	select CPU_ARM926T
+	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale i.MX2 family
 
 config ARCH_MX3
 	bool "MX3-based"
 	select CPU_V6
+	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale i.MX3 family
 
@@ -43,4 +45,10 @@ config MXC_IRQ_PRIOR
 	  requirements for timing.
 	  Say N here, unless you have a specialized requirement.
 
+config MXC_PWM
+	tristate "Enable PWM driver"
+	depends on ARCH_MXC
+	help
+	  Enable support for the i.MX PWM controller(s).
+
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/Makefile linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,8 @@
 #
 
 # Common support
-obj-y := irq.o clock.o gpio.o time.o devices.o
+obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
 
 obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
+obj-$(CONFIG_MXC_PWM)  += pwm.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/pwm.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/pwm.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/pwm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/pwm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,300 @@
+/*
+ * simple driver for PWM (Pulse Width Modulator) controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#if defined CONFIG_ARCH_MX1 || defined CONFIG_ARCH_MX21
+#define PWM_VER_1
+
+#define PWMCR	0x00	/* PWM Control Register		*/
+#define PWMSR	0x04	/* PWM Sample Register		*/
+#define PWMPR	0x08	/* PWM Period Register		*/
+#define PWMCNR	0x0C	/* PWM Counter Register		*/
+
+#define PWMCR_HCTR		(1 << 18)		/* Halfword FIFO Data Swapping	*/
+#define PWMCR_BCTR		(1 << 17)		/* Byte FIFO Data Swapping	*/
+#define PWMCR_SWR		(1 << 16)		/* Software Reset		*/
+#define PWMCR_CLKSRC_PERCLK	(0 << 15)		/* PERCLK Clock Source		*/
+#define PWMCR_CLKSRC_CLK32	(1 << 15)		/* 32KHz Clock Source		*/
+#define PWMCR_PRESCALER(x)	(((x - 1) & 0x7F) << 8)	/* PRESCALER			*/
+#define PWMCR_IRQ		(1 << 7)		/* Interrupt Request		*/
+#define PWMCR_IRQEN		(1 << 6)		/* Interrupt Request Enable	*/
+#define PWMCR_FIFOAV		(1 << 5)		/* FIFO Available		*/
+#define PWMCR_EN		(1 << 4)		/* Enables/Disables the PWM	*/
+#define PWMCR_REPEAT(x)		(((x) & 0x03) << 2)	/* Sample Repeats		*/
+#define PWMCR_DIV(x)		(((x) & 0x03) << 0)	/* Clock divider 2/4/8/16	*/
+
+#define MAX_DIV			(128 * 16)
+#endif
+
+#if defined CONFIG_MACH_MX27 || defined CONFIG_ARCH_MX31
+#define PWM_VER_2
+
+#define PWMCR	0x00	/* PWM Control Register		*/
+#define PWMSR	0x04	/* PWM Status Register		*/
+#define PWMIR	0x08	/* PWM Interrupt Register	*/
+#define PWMSAR	0x0C	/* PWM Sample Register		*/
+#define PWMPR	0x10	/* PWM Period Register		*/
+#define PWMCNR	0x14	/* PWM Counter Register		*/
+
+#define PWMCR_EN		(1 << 0)		/* Enables/Disables the PWM	*/
+#define PWMCR_REPEAT(x)		(((x) & 0x03) << 1)	/* Sample Repeats		*/
+#define PWMCR_SWR		(1 << 3)		/* Software Reset		*/
+#define PWMCR_PRESCALER(x)	(((x - 1) & 0xFFF) << 4)/* PRESCALER			*/
+#define PWMCR_CLKSRC(x)		(((x) & 0x3) << 16)
+#define PWMCR_CLKSRC_OFF	(0 << 16)
+#define PWMCR_CLKSRC_IPG	(1 << 16)
+#define PWMCR_CLKSRC_IPG_HIGH	(2 << 16)
+#define PWMCR_CLKSRC_CLK32	(3 << 16)
+#define PWMCR_POUTC
+#define PWMCR_HCTR		(1 << 20)		/* Halfword FIFO Data Swapping	*/
+#define PWMCR_BCTR		(1 << 21)		/* Byte FIFO Data Swapping	*/
+#define PWMCR_DBGEN		(1 << 22)		/* Debug Mode			*/
+#define PWMCR_WAITEN		(1 << 23)		/* Wait Mode			*/
+#define PWMCR_DOZEN		(1 << 24)		/* Doze Mode			*/
+#define PWMCR_STOPEN		(1 << 25)		/* Stop Mode			*/
+#define PWMCR_FWM(x)		(((x) & 0x3) << 26)	/* FIFO Water Mark		*/
+
+#define MAX_DIV 4096
+#endif
+
+#define PWMS_SAMPLE(x)		((x) & 0xFFFF)		/* Contains a two-sample word	*/
+#define PWMP_PERIOD(x)		((x) & 0xFFFF)		/* Represents the PWM's period	*/
+#define PWMC_COUNTER(x)		((x) & 0xFFFF)		/* Represents the current count value	*/
+
+struct pwm_device {
+	struct list_head	node;
+	struct platform_device *pdev;
+
+	const char	*label;
+	struct clk	*clk;
+
+	int		clk_enabled;
+	void __iomem	*mmio_base;
+
+	unsigned int	use_count;
+	unsigned int	pwm_id;
+};
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	unsigned long long c;
+	unsigned long period_cycles, duty_cycles, prescale;
+
+	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+		return -EINVAL;
+
+	c = clk_get_rate(pwm->clk);
+	c = c * period_ns;
+	do_div(c, 1000000000);
+	period_cycles = c;
+
+	prescale = period_cycles / 0x10000 + 1;
+
+	period_cycles /= prescale;
+	c = (unsigned long long)period_cycles * duty_ns;
+	do_div(c, period_ns);
+	duty_cycles = c;
+
+#ifdef PWM_VER_2
+	writel(duty_cycles, pwm->mmio_base + PWMSAR);
+	writel(period_cycles, pwm->mmio_base + PWMPR);
+	writel(PWMCR_PRESCALER(prescale - 1) | PWMCR_CLKSRC_IPG_HIGH | PWMCR_EN,
+			pwm->mmio_base + PWMCR);
+#elif defined PWM_VER_1
+#error PWM not yet working on MX1 / MX21
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+	int rc = 0;
+
+	if (!pwm->clk_enabled) {
+		rc = clk_enable(pwm->clk);
+		if (!rc)
+			pwm->clk_enabled = 1;
+	}
+	return rc;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+	if (pwm->clk_enabled) {
+		clk_disable(pwm->clk);
+		pwm->clk_enabled = 0;
+	}
+}
+EXPORT_SYMBOL(pwm_disable);
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	struct pwm_device *pwm;
+	int found = 0;
+
+	mutex_lock(&pwm_lock);
+
+	list_for_each_entry(pwm, &pwm_list, node) {
+		if (pwm->pwm_id == pwm_id) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		if (pwm->use_count == 0) {
+			pwm->use_count++;
+			pwm->label = label;
+		} else
+			pwm = ERR_PTR(-EBUSY);
+	} else
+		pwm = ERR_PTR(-ENOENT);
+
+	mutex_unlock(&pwm_lock);
+	return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+	mutex_lock(&pwm_lock);
+
+	if (pwm->use_count) {
+		pwm->use_count--;
+		pwm->label = NULL;
+	} else
+		pr_warning("PWM device already freed\n");
+
+	mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static int __devinit mxc_pwm_probe(struct platform_device *pdev)
+{
+	struct pwm_device *pwm;
+	struct resource *r;
+	int ret = 0;
+
+	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+	if (pwm == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	pwm->clk = clk_get(&pdev->dev, "pwm");
+
+	if (IS_ERR(pwm->clk)) {
+		ret = PTR_ERR(pwm->clk);
+		goto err_free;
+	}
+
+	pwm->clk_enabled = 0;
+
+	pwm->use_count = 0;
+	pwm->pwm_id = pdev->id;
+	pwm->pdev = pdev;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		ret = -ENODEV;
+		goto err_free_clk;
+	}
+
+	r = request_mem_region(r->start, r->end - r->start + 1, 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);
+	if (pwm->mmio_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() registers\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
+
+	mutex_lock(&pwm_lock);
+	list_add_tail(&pwm->node, &pwm_list);
+	mutex_unlock(&pwm_lock);
+
+	platform_set_drvdata(pdev, pwm);
+	return 0;
+
+err_free_mem:
+	release_mem_region(r->start, r->end - r->start + 1);
+err_free_clk:
+	clk_put(pwm->clk);
+err_free:
+	kfree(pwm);
+	return ret;
+}
+
+static int __devexit mxc_pwm_remove(struct platform_device *pdev)
+{
+	struct pwm_device *pwm;
+	struct resource *r;
+
+	pwm = platform_get_drvdata(pdev);
+	if (pwm == NULL)
+		return -ENODEV;
+
+	mutex_lock(&pwm_lock);
+	list_del(&pwm->node);
+	mutex_unlock(&pwm_lock);
+
+	iounmap(pwm->mmio_base);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(r->start, r->end - r->start + 1);
+
+	clk_put(pwm->clk);
+
+	kfree(pwm);
+	return 0;
+}
+
+static struct platform_driver mxc_pwm_driver = {
+	.driver		= {
+		.name	= "mxc_pwm",
+	},
+	.probe		= mxc_pwm_probe,
+	.remove		= __devexit_p(mxc_pwm_remove),
+};
+
+static int __init mxc_pwm_init(void)
+{
+	return platform_driver_register(&mxc_pwm_driver);
+}
+arch_initcall(mxc_pwm_init);
+
+static void __exit mxc_pwm_exit(void)
+{
+	platform_driver_unregister(&mxc_pwm_driver);
+}
+module_exit(mxc_pwm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/system.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/system.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/system.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/system.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@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
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_ARCH_MX1
+#define WDOG_WCR_REG		IO_ADDRESS(WDT_BASE_ADDR)
+#define WDOG_WCR_ENABLE		(1 << 0)
+#else
+#define WDOG_WCR_REG		IO_ADDRESS(WDOG_BASE_ADDR)
+#define WDOG_WCR_ENABLE		(1 << 2)
+#endif
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+	if (!cpu_is_mx1()) {
+		struct clk *clk;
+
+		clk = clk_get_sys("imx-wdt.0", NULL);
+		if (!IS_ERR(clk))
+			clk_enable(clk);
+	}
+
+	/* Assert SRS signal */
+	__raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG);
+
+	/* wait for reset to assert... */
+	mdelay(500);
+
+	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+	/* delay to allow the serial port to show the message */
+	mdelay(50);
+
+	/* we'll take a jump through zero as a poor second */
+	cpu_reset(0);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/time.c linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-mxc/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-mxc/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,12 +34,9 @@
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
-/* clock source for the timer */
-static struct clk *timer_clk;
-
 /* clock source */
 
-static cycle_t mxc_get_cycles(void)
+static cycle_t mxc_get_cycles(struct clocksource *cs)
 {
 	return __raw_readl(TIMER_BASE + MXC_TCN);
 }
@@ -53,13 +50,11 @@ static struct clocksource clocksource_mx
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static int __init mxc_clocksource_init(void)
+static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
-	unsigned int clock;
-
-	clock = clk_get_rate(timer_clk);
+	unsigned int c = clk_get_rate(timer_clk);
 
-	clocksource_mxc.mult = clocksource_hz2mult(clock,
+	clocksource_mxc.mult = clocksource_hz2mult(c,
 					clocksource_mxc.shift);
 	clocksource_register(&clocksource_mxc);
 
@@ -177,13 +172,11 @@ static struct clock_event_device clockev
 	.rating		= 200,
 };
 
-static int __init mxc_clockevent_init(void)
+static int __init mxc_clockevent_init(struct clk *timer_clk)
 {
-	unsigned int clock;
-
-	clock = clk_get_rate(timer_clk);
+	unsigned int c = clk_get_rate(timer_clk);
 
-	clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC,
+	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
 					clockevent_mxc.shift);
 	clockevent_mxc.max_delta_ns =
 			clockevent_delta2ns(0xfffffffe, &clockevent_mxc);
@@ -197,14 +190,8 @@ static int __init mxc_clockevent_init(vo
 	return 0;
 }
 
-void __init mxc_timer_init(const char *clk_timer)
+void __init mxc_timer_init(struct clk *timer_clk)
 {
-	timer_clk = clk_get(NULL, clk_timer);
-	if (!timer_clk) {
-		printk(KERN_ERR"Cannot determine timer clock. Giving up.\n");
-		return;
-	}
-
 	clk_enable(timer_clk);
 
 	/*
@@ -219,10 +206,9 @@ void __init mxc_timer_init(const char *c
 		     TIMER_BASE + MXC_TCTL);
 
 	/* init and register the timer to the framework */
-	mxc_clocksource_init();
-	mxc_clockevent_init();
+	mxc_clocksource_init(timer_clk);
+	mxc_clockevent_init(timer_clk);
 
 	/* Make irqs happen */
 	setup_irq(TIMER_INTERRUPT, &mxc_timer_irq);
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/clock.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,44 +36,6 @@ static struct clk_functions *arch_clock;
  * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk * clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
-	int idno;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	mutex_lock(&clocks_mutex);
-
-	list_for_each_entry(p, &clocks, node) {
-		if (p->id == idno &&
-		    strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			goto found;
-		}
-	}
-
-	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-
-found:
-	mutex_unlock(&clocks_mutex);
-
-	return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
@@ -114,22 +76,6 @@ out:
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_get_usecount(struct clk *clk)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	if (clk == NULL || IS_ERR(clk))
-		return 0;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = clk->usecount;
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_get_usecount);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	unsigned long flags;
@@ -146,13 +92,6 @@ unsigned long clk_get_rate(struct clk *c
 }
 EXPORT_SYMBOL(clk_get_rate);
 
-void clk_put(struct clk *clk)
-{
-	if (clk && !IS_ERR(clk))
-		module_put(clk->owner);
-}
-EXPORT_SYMBOL(clk_put);
-
 /*-------------------------------------------------------------------------
  * Optional clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
@@ -185,6 +124,11 @@ int clk_set_rate(struct clk *clk, unsign
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_set_rate)
 		ret = arch_clock->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;
@@ -200,8 +144,16 @@ int clk_set_parent(struct clk *clk, stru
 		return ret;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_set_parent)
-		ret =  arch_clock->clk_set_parent(clk, parent);
+	if (clk->usecount == 0) {
+		if (arch_clock->clk_set_parent)
+			ret = arch_clock->clk_set_parent(clk, parent);
+		if (ret == 0) {
+			if (clk->recalc)
+				clk->rate = clk->recalc(clk);
+			propagate_rate(clk);
+		}
+	} else
+		ret = -EBUSY;
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -210,18 +162,7 @@ EXPORT_SYMBOL(clk_set_parent);
 
 struct clk *clk_get_parent(struct clk *clk)
 {
-	unsigned long flags;
-	struct clk * ret = NULL;
-
-	if (clk == NULL || IS_ERR(clk))
-		return ret;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_get_parent)
-		ret = arch_clock->clk_get_parent(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
+	return clk->parent;
 }
 EXPORT_SYMBOL(clk_get_parent);
 
@@ -250,14 +191,20 @@ static int __init omap_clk_setup(char *s
 __setup("mpurate=", omap_clk_setup);
 
 /* Used for clocks that always have same value as the parent clock */
-void followparent_recalc(struct clk *clk)
+unsigned long followparent_recalc(struct clk *clk)
 {
-	if (clk == NULL || IS_ERR(clk))
-		return;
+	return clk->parent->rate;
+}
 
-	clk->rate = clk->parent->rate;
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
+void clk_reparent(struct clk *child, struct clk *parent)
+{
+	list_del_init(&child->sibling);
+	if (parent)
+		list_add(&child->sibling, &parent->children);
+	child->parent = parent;
+
+	/* now do the debugfs renaming to reattach the child
+	   to the proper parent */
 }
 
 /* Propagate rate to children */
@@ -265,17 +212,15 @@ void propagate_rate(struct clk * tclk)
 {
 	struct clk *clkp;
 
-	if (tclk == NULL || IS_ERR(tclk))
-		return;
-
-	list_for_each_entry(clkp, &clocks, node) {
-		if (likely(clkp->parent != tclk))
-			continue;
-		if (likely((u32)clkp->recalc))
-			clkp->recalc(clkp);
+	list_for_each_entry(clkp, &tclk->children, sibling) {
+		if (clkp->recalc)
+			clkp->rate = clkp->recalc(clkp);
+		propagate_rate(clkp);
 	}
 }
 
+static LIST_HEAD(root_clks);
+
 /**
  * recalculate_root_clocks - recalculate and propagate all root clocks
  *
@@ -287,18 +232,42 @@ void recalculate_root_clocks(void)
 {
 	struct clk *clkp;
 
-	list_for_each_entry(clkp, &clocks, node) {
-		if (unlikely(!clkp->parent) && likely((u32)clkp->recalc))
-			clkp->recalc(clkp);
+	list_for_each_entry(clkp, &root_clks, sibling) {
+		if (clkp->recalc)
+			clkp->rate = clkp->recalc(clkp);
+		propagate_rate(clkp);
 	}
 }
 
+/**
+ * clk_init_one - initialize any fields in the struct clk before clk init
+ * @clk: struct clk * to initialize
+ *
+ * Initialize any struct clk fields needed before normal clk initialization
+ * can run.  No return value.
+ */
+void clk_init_one(struct clk *clk)
+{
+	INIT_LIST_HEAD(&clk->children);
+}
+
 int clk_register(struct clk *clk)
 {
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	/*
+	 * trap out already registered clocks
+	 */
+	if (clk->node.next || clk->node.prev)
+		return 0;
+
 	mutex_lock(&clocks_mutex);
+	if (clk->parent)
+		list_add(&clk->sibling, &clk->parent->children);
+	else
+		list_add(&clk->sibling, &root_clks);
+
 	list_add(&clk->node, &clocks);
 	if (clk->init)
 		clk->init(clk);
@@ -314,39 +283,12 @@ void clk_unregister(struct clk *clk)
 		return;
 
 	mutex_lock(&clocks_mutex);
+	list_del(&clk->sibling);
 	list_del(&clk->node);
 	mutex_unlock(&clocks_mutex);
 }
 EXPORT_SYMBOL(clk_unregister);
 
-void clk_deny_idle(struct clk *clk)
-{
-	unsigned long flags;
-
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_deny_idle)
-		arch_clock->clk_deny_idle(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_deny_idle);
-
-void clk_allow_idle(struct clk *clk)
-{
-	unsigned long flags;
-
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_allow_idle)
-		arch_clock->clk_allow_idle(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_allow_idle);
-
 void clk_enable_init_clocks(void)
 {
 	struct clk *clkp;
@@ -358,6 +300,23 @@ void clk_enable_init_clocks(void)
 }
 EXPORT_SYMBOL(clk_enable_init_clocks);
 
+/*
+ * Low level helpers
+ */
+static int clkll_enable_null(struct clk *clk)
+{
+	return 0;
+}
+
+static void clkll_disable_null(struct clk *clk)
+{
+}
+
+const struct clkops clkops_null = {
+	.enable		= clkll_enable_null,
+	.disable	= clkll_disable_null,
+};
+
 #ifdef CONFIG_CPU_FREQ
 void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
 {
@@ -383,8 +342,10 @@ static int __init clk_disable_unused(voi
 	unsigned long flags;
 
 	list_for_each_entry(ck, &clocks, node) {
-		if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
-			ck->enable_reg == 0)
+		if (ck->ops == &clkops_null)
+			continue;
+
+		if (ck->usecount > 0 || ck->enable_reg == 0)
 			continue;
 
 		spin_lock_irqsave(&clockfw_lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/common.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/common.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -185,7 +185,7 @@ console_initcall(omap_add_serial_console
 
 #include <linux/clocksource.h>
 
-static cycle_t omap_32k_read(void)
+static cycle_t omap_32k_read(struct clocksource *cs)
 {
 	return omap_readl(TIMER_32K_SYNCHRONIZED);
 }
@@ -207,7 +207,7 @@ unsigned long long sched_clock(void)
 {
 	unsigned long long ret;
 
-	ret = (unsigned long long)omap_32k_read();
+	ret = (unsigned long long)omap_32k_read(&clocksource_32k);
 	ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
 	return ret;
 }
@@ -245,7 +245,7 @@ static struct omap_globals *omap2_global
 static void __init __omap2_set_globals(void)
 {
 	omap2_set_globals_tap(omap2_globals);
-	omap2_set_globals_memory(omap2_globals);
+	omap2_set_globals_sdrc(omap2_globals);
 	omap2_set_globals_control(omap2_globals);
 	omap2_set_globals_prcm(omap2_globals);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/cpu-omap.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/cpu-omap.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/cpu-omap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/cpu-omap.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,10 +23,13 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/clock.h>
 #include <asm/system.h>
 
 #define VERY_HI_RATE	900000000
 
+static struct cpufreq_frequency_table *freq_table;
+
 #ifdef CONFIG_ARCH_OMAP1
 #define MPU_CLK		"mpu"
 #else
@@ -39,6 +42,9 @@ static struct clk *mpu_clk;
 
 int omap_verify_speed(struct cpufreq_policy *policy)
 {
+	if (freq_table)
+		return cpufreq_frequency_table_verify(policy, freq_table);
+
 	if (policy->cpu)
 		return -EINVAL;
 
@@ -70,12 +76,26 @@ static int omap_target(struct cpufreq_po
 	struct cpufreq_freqs freqs;
 	int ret = 0;
 
+	/* 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 = omap_getspeed(0);
 	freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
 	freqs.cpu = 0;
 
+	if (freqs.old == freqs.new)
+		return ret;
+
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	ret = clk_set_rate(mpu_clk, target_freq * 1000);
+#ifdef CONFIG_CPU_FREQ_DEBUG
+	printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
+	       freqs.old, freqs.new);
+#endif
+	ret = clk_set_rate(mpu_clk, freqs.new * 1000);
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
 	return ret;
@@ -83,16 +103,31 @@ static int omap_target(struct cpufreq_po
 
 static int __init omap_cpu_init(struct cpufreq_policy *policy)
 {
+	int result = 0;
+
 	mpu_clk = clk_get(NULL, MPU_CLK);
 	if (IS_ERR(mpu_clk))
 		return PTR_ERR(mpu_clk);
 
 	if (policy->cpu != 0)
 		return -EINVAL;
+
 	policy->cur = policy->min = policy->max = omap_getspeed(0);
-	policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
-	policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
+	clk_init_cpufreq_table(&freq_table);
+	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 = clk_round_rate(mpu_clk, 0) / 1000;
+		policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+							VERY_HI_RATE) / 1000;
+	}
+
+	/* FIXME: what's the actual transition time? */
+	policy->cpuinfo.transition_latency = 10 * 1000 * 1000;
 
 	return 0;
 }
@@ -103,6 +138,11 @@ static int omap_cpu_exit(struct cpufreq_
 	return 0;
 }
 
+static struct freq_attr *omap_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
 static struct cpufreq_driver omap_driver = {
 	.flags		= CPUFREQ_STICKY,
 	.verify		= omap_verify_speed,
@@ -111,6 +151,7 @@ static struct cpufreq_driver omap_driver
 	.init		= omap_cpu_init,
 	.exit		= omap_cpu_exit,
 	.name		= "omap",
+	.attr		= omap_cpufreq_attr,
 };
 
 static int __init omap_cpufreq_init(void)
@@ -119,3 +160,11 @@ static int __init omap_cpufreq_init(void
 }
 
 arch_initcall(omap_cpufreq_init);
+
+/*
+ * if ever we want to remove this, upon cleanup call:
+ *
+ * cpufreq_unregister_driver()
+ * cpufreq_frequency_table_put_attr()
+ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/devices.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/devices.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -228,6 +228,9 @@ int __init omap_mmc_add(const char *name
 	ret = platform_device_add(pdev);
 	if (ret)
 		goto fail;
+
+	/* return device handle to board setup code */
+	data->dev = &pdev->dev;
 	return 0;
 
 fail:
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/dma.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -123,6 +123,7 @@ static struct dma_link_info *dma_linked_
 
 static int dma_lch_count;
 static int dma_chan_count;
+static int omap_dma_reserve_channels;
 
 static spinlock_t dma_chan_lock;
 static struct omap_dma_lch *dma_chan;
@@ -737,7 +738,7 @@ int omap_request_dma(int dev_id, const c
 		 * id.
 		 */
 		dma_write(dev_id | (1 << 10), CCR(free_ch));
-	} else if (cpu_is_omap730() || cpu_is_omap15xx()) {
+	} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
 		dma_write(dev_id, CCR(free_ch));
 	}
 
@@ -759,19 +760,12 @@ void omap_free_dma(int lch)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&dma_chan_lock, flags);
 	if (dma_chan[lch].dev_id == -1) {
 		pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
 		       lch);
-		spin_unlock_irqrestore(&dma_chan_lock, flags);
 		return;
 	}
 
-	dma_chan[lch].dev_id = -1;
-	dma_chan[lch].next_lch = -1;
-	dma_chan[lch].callback = NULL;
-	spin_unlock_irqrestore(&dma_chan_lock, flags);
-
 	if (cpu_class_is_omap1()) {
 		/* Disable all DMA interrupts for the channel. */
 		dma_write(0, CICR(lch));
@@ -797,6 +791,12 @@ void omap_free_dma(int lch)
 		dma_write(0, CCR(lch));
 		omap_clear_dma(lch);
 	}
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	dma_chan[lch].dev_id = -1;
+	dma_chan[lch].next_lch = -1;
+	dma_chan[lch].callback = NULL;
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 EXPORT_SYMBOL(omap_free_dma);
 
@@ -1900,7 +1900,7 @@ static int omap2_dma_handle_ch(int ch)
 /* STATUS register count is from 1-32 while our is 0-31 */
 static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
 {
-	u32 val;
+	u32 val, enable_reg;
 	int i;
 
 	val = dma_read(IRQSTATUS_L0);
@@ -1909,6 +1909,8 @@ static irqreturn_t omap2_dma_irq_handler
 			printk(KERN_WARNING "Spurious DMA IRQ\n");
 		return IRQ_HANDLED;
 	}
+	enable_reg = dma_read(IRQENABLE_L0);
+	val &= enable_reg; /* Dispatch only relevant interrupts */
 	for (i = 0; i < dma_lch_count && val != 0; i++) {
 		if (val & 1)
 			omap2_dma_handle_ch(i);
@@ -2321,6 +2323,10 @@ static int __init omap_init_dma(void)
 		return -ENODEV;
 	}
 
+	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)
@@ -2339,7 +2345,7 @@ static int __init omap_init_dma(void)
 		printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
 		dma_chan_count = 9;
 		enable_1510_mode = 1;
-	} else if (cpu_is_omap16xx() || cpu_is_omap730()) {
+	} else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
 		printk(KERN_INFO "OMAP DMA hardware version %d\n",
 		       dma_read(HW_ID));
 		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
@@ -2371,7 +2377,7 @@ static int __init omap_init_dma(void)
 		u8 revision = dma_read(REVISION) & 0xff;
 		printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
 		       revision >> 4, revision & 0xf);
-		dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
+		dma_chan_count = dma_lch_count;
 	} else {
 		dma_chan_count = 0;
 		return 0;
@@ -2437,4 +2443,17 @@ static int __init omap_init_dma(void)
 
 arch_initcall(omap_init_dma);
 
+/*
+ * Reserve the omap SDMA channels using cmdline bootarg
+ * "omap_dma_reserve_ch=". The valid range is 1 to 32
+ */
+static int __init omap_dma_cmdline_reserve_ch(char *str)
+{
+	if (get_option(&str, &omap_dma_reserve_channels) != 1)
+		omap_dma_reserve_channels = 0;
+	return 1;
+}
+
+__setup("omap_dma_reserve_ch=", omap_dma_cmdline_reserve_ch);
+
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/dmtimer.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/dmtimer.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/dmtimer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/dmtimer.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <mach/dmtimer.h>
 #include <mach/irqs.h>
@@ -237,7 +238,7 @@ static struct omap_dm_timer omap3_dm_tim
 	{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
 	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
 	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
-	{ .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 },
+	{ .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
 };
 
 static const char *omap3_dm_source_names[] __initdata = {
@@ -320,11 +321,9 @@ static void omap_dm_timer_reset(struct o
 	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
 
 	/*
-	 * Enable wake-up only for GPT1 on OMAP2 CPUs.
-	 * FIXME: All timers should have wake-up enabled and clear
-	 * PRCM status.
+	 * Enable wake-up on OMAP2 CPUs.
 	 */
-	if (cpu_class_is_omap2() && (timer == &dm_timers[0]))
+	if (cpu_class_is_omap2())
 		l |= 1 << 2;
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
 
@@ -362,6 +361,7 @@ struct omap_dm_timer *omap_dm_timer_requ
 
 	return timer;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
@@ -385,6 +385,7 @@ struct omap_dm_timer *omap_dm_timer_requ
 
 	return timer;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 void omap_dm_timer_free(struct omap_dm_timer *timer)
 {
@@ -395,6 +396,7 @@ void omap_dm_timer_free(struct omap_dm_t
 	WARN_ON(!timer->reserved);
 	timer->reserved = 0;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
@@ -406,6 +408,7 @@ void omap_dm_timer_enable(struct omap_dm
 
 	timer->enabled = 1;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
@@ -417,11 +420,13 @@ void omap_dm_timer_disable(struct omap_d
 
 	timer->enabled = 0;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
 	return timer->irq;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
 
 #if defined(CONFIG_ARCH_OMAP1)
 
@@ -452,6 +457,7 @@ __u32 omap_dm_timer_modify_idlect_mask(_
 
 	return inputmask;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #elif defined(CONFIG_ARCH_OMAP2) || defined (CONFIG_ARCH_OMAP3)
 
@@ -459,6 +465,7 @@ struct clk *omap_dm_timer_get_fclk(struc
 {
 	return timer->fclk;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
@@ -466,6 +473,7 @@ __u32 omap_dm_timer_modify_idlect_mask(_
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #endif
 
@@ -473,6 +481,7 @@ void omap_dm_timer_trigger(struct omap_d
 {
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
 
 void omap_dm_timer_start(struct omap_dm_timer *timer)
 {
@@ -484,6 +493,7 @@ void omap_dm_timer_start(struct omap_dm_
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 	}
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
 void omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
@@ -495,10 +505,11 @@ void omap_dm_timer_stop(struct omap_dm_t
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 	}
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
 #ifdef CONFIG_ARCH_OMAP1
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int n = (timer - dm_timers) << 1;
 	u32 l;
@@ -506,23 +517,33 @@ void omap_dm_timer_set_source(struct oma
 	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
 	l |= source << n;
 	omap_writel(l, MOD_CONF_CTRL_1);
+
+	return 0;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 #else
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
+	int ret = -EINVAL;
+
 	if (source < 0 || source >= 3)
-		return;
+		return -EINVAL;
 
 	clk_disable(timer->fclk);
-	clk_set_parent(timer->fclk, dm_source_clocks[source]);
+	ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
 	clk_enable(timer->fclk);
 
-	/* When the functional clock disappears, too quick writes seem to
-	 * cause an abort. */
+	/*
+	 * When the functional clock disappears, too quick writes seem
+	 * to cause an abort. XXX Is this still necessary?
+	 */
 	__delay(150000);
+
+	return ret;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 #endif
 
@@ -541,6 +562,7 @@ void omap_dm_timer_set_load(struct omap_
 
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
 
 /* Optimized set_load which removes costly spin wait in timer_start */
 void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -560,6 +582,7 @@ void omap_dm_timer_set_load_start(struct
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
 
 void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 			     unsigned int match)
@@ -574,6 +597,7 @@ void omap_dm_timer_set_match(struct omap
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
 
 void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 			   int toggle, int trigger)
@@ -590,6 +614,7 @@ void omap_dm_timer_set_pwm(struct omap_d
 	l |= trigger << 10;
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
 
 void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 {
@@ -603,6 +628,7 @@ void omap_dm_timer_set_prescaler(struct
 	}
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
 
 void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
 				  unsigned int value)
@@ -610,6 +636,7 @@ void omap_dm_timer_set_int_enable(struct
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
 
 unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
@@ -619,11 +646,13 @@ unsigned int omap_dm_timer_read_status(s
 
 	return l;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
 
 void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
 
 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
@@ -633,11 +662,13 @@ unsigned int omap_dm_timer_read_counter(
 
 	return l;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
 
 void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
 }
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
 
 int omap_dm_timers_active(void)
 {
@@ -658,6 +689,7 @@ int omap_dm_timers_active(void)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
 int __init omap_dm_timer_init(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/fb.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/fb.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/fb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/fb.c	2009-06-09 23:05:27.000000000 -0400
@@ -206,9 +206,10 @@ void __init omapfb_reserve_sdram(void)
 			config_invalid = 1;
 			return;
 		}
-		if (rg.paddr)
+		if (rg.paddr) {
 			reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
-		reserved += rg.size;
+			reserved += rg.size;
+		}
 		omapfb_config.mem_desc.region[i] = rg;
 		configured_regions++;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/gpio.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,6 +81,22 @@
 #define OMAP730_GPIO_INT_STATUS		0x14
 
 /*
+ * OMAP850 specific GPIO registers
+ */
+#define OMAP850_GPIO1_BASE		IO_ADDRESS(0xfffbc000)
+#define OMAP850_GPIO2_BASE		IO_ADDRESS(0xfffbc800)
+#define OMAP850_GPIO3_BASE		IO_ADDRESS(0xfffbd000)
+#define OMAP850_GPIO4_BASE		IO_ADDRESS(0xfffbd800)
+#define OMAP850_GPIO5_BASE		IO_ADDRESS(0xfffbe000)
+#define OMAP850_GPIO6_BASE		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
+
+/*
  * omap24xx specific GPIO registers
  */
 #define OMAP242X_GPIO1_BASE		IO_ADDRESS(0x48018000)
@@ -159,7 +175,8 @@ struct gpio_bank {
 #define METHOD_GPIO_1510	1
 #define METHOD_GPIO_1610	2
 #define METHOD_GPIO_730		3
-#define METHOD_GPIO_24XX	4
+#define METHOD_GPIO_850		4
+#define METHOD_GPIO_24XX	5
 
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
@@ -190,6 +207,19 @@ static struct gpio_bank gpio_bank_730[7]
 };
 #endif
 
+#ifdef CONFIG_ARCH_OMAP850
+static struct gpio_bank gpio_bank_850[7] = {
+	{ OMAP_MPUIO_BASE,     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 },
+};
+#endif
+
+
 #ifdef CONFIG_ARCH_OMAP24XX
 
 static struct gpio_bank gpio_bank_242x[4] = {
@@ -236,7 +266,7 @@ static inline struct gpio_bank *get_gpio
 			return &gpio_bank[0];
 		return &gpio_bank[1 + (gpio >> 4)];
 	}
-	if (cpu_is_omap730()) {
+	if (cpu_is_omap7xx()) {
 		if (OMAP_GPIO_IS_MPUIO(gpio))
 			return &gpio_bank[0];
 		return &gpio_bank[1 + (gpio >> 5)];
@@ -251,7 +281,7 @@ static inline struct gpio_bank *get_gpio
 
 static inline int get_gpio_index(int gpio)
 {
-	if (cpu_is_omap730())
+	if (cpu_is_omap7xx())
 		return gpio & 0x1f;
 	if (cpu_is_omap24xx())
 		return gpio & 0x1f;
@@ -273,11 +303,11 @@ static inline int gpio_valid(int gpio)
 		return 0;
 	if ((cpu_is_omap16xx()) && gpio < 64)
 		return 0;
-	if (cpu_is_omap730() && gpio < 192)
+	if (cpu_is_omap7xx() && gpio < 192)
 		return 0;
 	if (cpu_is_omap24xx() && gpio < 128)
 		return 0;
-	if (cpu_is_omap34xx() && gpio < 160)
+	if (cpu_is_omap34xx() && gpio < 192)
 		return 0;
 	return -1;
 }
@@ -318,6 +348,11 @@ static void _set_gpio_direction(struct g
 		reg += OMAP730_GPIO_DIR_CONTROL;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_DIR_CONTROL;
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
@@ -380,6 +415,16 @@ static void _set_gpio_dataout(struct gpi
 			l &= ~(1 << gpio);
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_DATA_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		if (enable)
@@ -426,6 +471,11 @@ static int __omap_get_gpio_datain(int gp
 		reg += OMAP730_GPIO_DATA_INPUT;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_DATA_INPUT;
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_DATAIN;
@@ -598,6 +648,18 @@ static int _set_gpio_triggering(struct g
 			goto bad;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_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
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		set_24xx_gpio_triggering(bank, gpio, trigger);
@@ -678,6 +740,11 @@ static void _clear_gpio_irqbank(struct g
 		reg += OMAP730_GPIO_INT_STATUS;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_INT_STATUS;
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQSTATUS1;
@@ -691,8 +758,12 @@ static void _clear_gpio_irqbank(struct g
 
 	/* Workaround for clearing DSP GPIO interrupts to allow retention */
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+	reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
 	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		__raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2);
+		__raw_writel(gpio_mask, reg);
+
+	/* Flush posted write for the irq status to avoid spurious interrupts */
+	__raw_readl(reg);
 #endif
 }
 
@@ -736,6 +807,13 @@ static u32 _get_gpio_irqbank_mask(struct
 		inv = 1;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_INT_MASK;
+		mask = 0xffffffff;
+		inv = 1;
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQENABLE1;
@@ -799,6 +877,16 @@ static void _enable_gpio_irqbank(struct
 			l |= gpio_mask;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_INT_MASK;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		if (enable)
@@ -837,13 +925,10 @@ static int _set_gpio_wakeup(struct gpio_
 	case METHOD_MPUIO:
 	case METHOD_GPIO_1610:
 		spin_lock_irqsave(&bank->lock, flags);
-		if (enable) {
+		if (enable)
 			bank->suspend_wakeup |= (1 << gpio);
-			enable_irq_wake(bank->irq);
-		} else {
-			disable_irq_wake(bank->irq);
+		else
 			bank->suspend_wakeup &= ~(1 << gpio);
-		}
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
 #endif
@@ -856,13 +941,10 @@ static int _set_gpio_wakeup(struct gpio_
 			return -EINVAL;
 		}
 		spin_lock_irqsave(&bank->lock, flags);
-		if (enable) {
+		if (enable)
 			bank->suspend_wakeup |= (1 << gpio);
-			enable_irq_wake(bank->irq);
-		} else {
-			disable_irq_wake(bank->irq);
+		else
 			bank->suspend_wakeup &= ~(1 << gpio);
-		}
 		spin_unlock_irqrestore(&bank->lock, flags);
 		return 0;
 #endif
@@ -983,6 +1065,10 @@ static void gpio_irq_handler(unsigned in
 	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;
+#endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	if (bank->method == METHOD_GPIO_24XX)
 		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
@@ -1372,6 +1458,13 @@ static int __init _omap_gpio_init(void)
 		gpio_bank = gpio_bank_730;
 	}
 #endif
+#ifdef CONFIG_ARCH_OMAP850
+	if (cpu_is_omap850()) {
+		printk(KERN_INFO "OMAP850 GPIO hardware\n");
+		gpio_bank_count = 7;
+		gpio_bank = gpio_bank_850;
+	}
+#endif
 
 #ifdef CONFIG_ARCH_OMAP24XX
 	if (cpu_is_omap242x()) {
@@ -1420,7 +1513,7 @@ 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_omap730() && bank->method == METHOD_GPIO_730) {
+		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);
 
@@ -1743,6 +1836,9 @@ static int gpio_is_input(struct gpio_ban
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DIR_CONTROL;
 		break;
+	case METHOD_GPIO_850:
+		reg += OMAP850_GPIO_DIR_CONTROL;
+		break;
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
 		break;
@@ -1762,7 +1858,8 @@ 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())
+		else if (cpu_class_is_omap2() || cpu_is_omap730() ||
+				cpu_is_omap850())
 			bankwidth = 32;
 
 		for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/i2c.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/i2c.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,6 +98,8 @@ static const int omap34xx_pins[][2] = {
 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;
@@ -119,14 +121,9 @@ static void __init omap_i2c_mux_pins(int
 	omap_cfg_reg(scl);
 }
 
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
-			  struct i2c_board_info const *info,
-			  unsigned len)
+static int __init omap_i2c_nr_ports(void)
 {
-	int ports, err;
-	struct platform_device *pdev;
-	struct resource *res;
-	resource_size_t base, irq;
+	int ports = 0;
 
 	if (cpu_class_is_omap1())
 		ports = 1;
@@ -135,17 +132,16 @@ int __init omap_register_i2c_bus(int bus
 	else if (cpu_is_omap34xx())
 		ports = 3;
 
-	BUG_ON(bus_id < 1 || bus_id > ports);
+	return ports;
+}
 
-	if (info) {
-		err = i2c_register_board_info(bus_id, info, len);
-		if (err)
-			return err;
-	}
+static int __init omap_i2c_add_bus(int bus_id)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	resource_size_t base, irq;
 
 	pdev = &omap_i2c_devices[bus_id - 1];
-	*(u32 *)pdev->dev.platform_data = clkrate;
-
 	if (bus_id == 1) {
 		res = pdev->resource;
 		if (cpu_class_is_omap1()) {
@@ -163,3 +159,81 @@ int __init omap_register_i2c_bus(int bus
 	omap_i2c_mux_pins(bus_id - 1);
 	return platform_device_register(pdev);
 }
+
+/**
+ * omap_i2c_bus_setup - Process command line options for the I2C bus speed
+ * @str: String of options
+ *
+ * This function allow to override the default I2C bus speed for given I2C
+ * bus with a command line option.
+ *
+ * Format: i2c_bus=bus_id,clkrate (in kHz)
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int __init omap_i2c_bus_setup(char *str)
+{
+	int ports;
+	int ints[3];
+
+	ports = omap_i2c_nr_ports();
+	get_options(str, 3, ints);
+	if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports)
+		return 0;
+	i2c_rate[ints[1] - 1] = ints[2];
+	i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP;
+
+	return 1;
+}
+__setup("i2c_bus=", omap_i2c_bus_setup);
+
+/*
+ * Register busses defined in command line but that are not registered with
+ * omap_register_i2c_bus from board initialization code.
+ */
+static int __init omap_register_i2c_bus_cmdline(void)
+{
+	int i, err = 0;
+
+	for (i = 0; i < ARRAY_SIZE(i2c_rate); i++)
+		if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) {
+			i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP;
+			err = omap_i2c_add_bus(i + 1);
+			if (err)
+				goto out;
+		}
+
+out:
+	return err;
+}
+subsys_initcall(omap_register_i2c_bus_cmdline);
+
+/**
+ * omap_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
+ * @len: number of descriptors in the table
+ *
+ * Returns 0 on success or an error code.
+ */
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+			  struct i2c_board_info const *info,
+			  unsigned len)
+{
+	int err;
+
+	BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports());
+
+	if (info) {
+		err = i2c_register_board_info(bus_id, info, len);
+		if (err)
+			return err;
+	}
+
+	if (!i2c_rate[bus_id - 1])
+		i2c_rate[bus_id - 1] = clkrate;
+	i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP;
+
+	return omap_i2c_add_bus(bus_id);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-2430sdp.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-2430sdp.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-2430sdp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-2430sdp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-2430sdp.h
- *
- * Hardware definitions for TI OMAP2430 SDP board.
- *
- * Based on board-h4.h 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_OMAP_2430SDP_H
-#define __ASM_ARCH_OMAP_2430SDP_H
-
-/* Placeholder for 2430SDP specific defines */
-#define OMAP24XX_ETHR_START		0x08000300
-#define OMAP24XX_ETHR_GPIO_IRQ		149
-#define SDP2430_CS0_BASE		0x04000000
-
-/* Function prototypes */
-extern void sdp2430_flash_init(void);
-extern void sdp2430_usb_init(void);
-
-#endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-apollon.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-apollon.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-apollon.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-apollon.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-apollon.h
- *
- * Hardware definitions for Samsung OMAP24XX Apollon board.
- *
- * Initial creation by 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 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_APOLLON_H
-#define __ASM_ARCH_OMAP_APOLLON_H
-
-#include <mach/cpu.h>
-
-extern void apollon_mmc_init(void);
-
-static inline int apollon_plus(void)
-{
-	/* The apollon plus has IDCODE revision 5 */
-	return omap_rev() & 0xc0;
-}
-
-/* Placeholder for APOLLON specific defines */
-#define APOLLON_ETHR_GPIO_IRQ		74
-
-#endif /*  __ASM_ARCH_OMAP_APOLLON_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-fsample.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-fsample.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-fsample.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-fsample.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-fsample.h
- *
- * Board-specific goodies for TI F-Sample.
- *
- * Copyright (C) 2006 Google, Inc.
- * Author: Brian Swetland <swetland@google.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_FSAMPLE_H
-#define __ASM_ARCH_OMAP_FSAMPLE_H
-
-/* fsample is pretty close to p2-sample */
-#include <mach/board-perseus2.h>
-
-#define fsample_cpld_read(reg) __raw_readb(reg)
-#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
-
-#define FSAMPLE_CPLD_BASE    0xE8100000
-#define FSAMPLE_CPLD_SIZE    SZ_4K
-#define FSAMPLE_CPLD_START   0x05080000
-
-#define FSAMPLE_CPLD_REG_A   (FSAMPLE_CPLD_BASE + 0x00)
-#define FSAMPLE_CPLD_SWITCH  (FSAMPLE_CPLD_BASE + 0x02)
-#define FSAMPLE_CPLD_UART    (FSAMPLE_CPLD_BASE + 0x02)
-#define FSAMPLE_CPLD_REG_B   (FSAMPLE_CPLD_BASE + 0x04)
-#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
-#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
-
-#define FSAMPLE_CPLD_BIT_BT_RESET         0
-#define FSAMPLE_CPLD_BIT_LCD_RESET        1
-#define FSAMPLE_CPLD_BIT_CAM_PWDN         2
-#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE   3
-#define FSAMPLE_CPLD_BIT_SD_MMC_EN        4
-#define FSAMPLE_CPLD_BIT_aGPS_PWREN       5
-#define FSAMPLE_CPLD_BIT_BACKLIGHT        6
-#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET    7
-#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N    8
-#define FSAMPLE_CPLD_BIT_OTG_RESET        9
-
-#define fsample_cpld_set(bit) \
-    fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
-
-#define fsample_cpld_clear(bit) \
-    fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,6 @@
 /* Different peripheral ids */
 #define OMAP_TAG_CLOCK		0x4f01
 #define OMAP_TAG_SERIAL_CONSOLE 0x4f03
-#define OMAP_TAG_USB		0x4f04
 #define OMAP_TAG_LCD		0x4f05
 #define OMAP_TAG_GPIO_SWITCH	0x4f06
 #define OMAP_TAG_UART		0x4f07
@@ -133,9 +132,6 @@ struct omap_version_config {
 	char version[12];
 };
 
-
-#include <mach/board-nokia.h>
-
 struct omap_board_config_entry {
 	u16 tag;
 	u16 len;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h2.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h2.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-h2.h
- *
- * Hardware definitions for TI OMAP1610 H2 board.
- *
- * 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_OMAP_H2_H
-#define __ASM_ARCH_OMAP_H2_H
-
-/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
-#define OMAP1610_ETHR_START		0x04000300
-
-#define H2_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
-#	define H2_TPS_GPIO_MMC_PWR_EN	(H2_TPS_GPIO_BASE + 3)
-
-extern void h2_mmc_init(void);
-
-#endif /*  __ASM_ARCH_OMAP_H2_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h3.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h3.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h3.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h3.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-h3.h
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Copyright (C) 2004 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 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_H3_H
-#define __ASM_ARCH_OMAP_H3_H
-
-/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
-#define OMAP1710_ETHR_START		0x04000300
-
-#define H3_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
-#	define H3_TPS_GPIO_MMC_PWR_EN	(H3_TPS_GPIO_BASE + 4)
-
-extern void h3_mmc_init(void);
-
-#endif /*  __ASM_ARCH_OMAP_H3_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h4.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h4.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-h4.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-h4.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-h4.h
- *
- * Hardware definitions for TI OMAP2420 H4 board.
- *
- * Initial creation 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_OMAP_H4_H
-#define __ASM_ARCH_OMAP_H4_H
-
-/* MMC Prototypes */
-extern void h4_mmc_init(void);
-
-/* Placeholder for H4 specific defines */
-#define OMAP24XX_ETHR_GPIO_IRQ		92
-#endif /*  __ASM_ARCH_OMAP_H4_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-innovator.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-innovator.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-innovator.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-innovator.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-innovator.h
- *
- * Copyright (C) 2001 RidgeRun, 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 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_INNOVATOR_H
-#define __ASM_ARCH_OMAP_INNOVATOR_H
-
-#if defined (CONFIG_ARCH_OMAP15XX)
-
-#ifndef OMAP_SDRAM_DEVICE
-#define OMAP_SDRAM_DEVICE			D256M_1X16_4B
-#endif
-
-#define OMAP1510P1_IMIF_PRI_VALUE		0x00
-#define OMAP1510P1_EMIFS_PRI_VALUE		0x00
-#define OMAP1510P1_EMIFF_PRI_VALUE		0x00
-
-#ifndef __ASSEMBLY__
-void fpga_write(unsigned char val, int reg);
-unsigned char fpga_read(int reg);
-#endif
-
-#endif /* CONFIG_ARCH_OMAP15XX */
-
-#if defined (CONFIG_ARCH_OMAP16XX)
-
-/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
-#define INNOVATOR1610_ETHR_START	0x04000300
-
-#endif /* CONFIG_ARCH_OMAP1610 */
-#endif /* __ASM_ARCH_OMAP_INNOVATOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-ldp.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-ldp.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-ldp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-ldp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-ldp.h
- *
- * Hardware definitions for TI OMAP3 LDP.
- *
- * Copyright (C) 2008 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 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_LDP_H
-#define __ASM_ARCH_OMAP_LDP_H
-
-extern void twl4030_bci_battery_init(void);
-
-#define TWL4030_IRQNUM		INT_34XX_SYS_NIRQ
-#define LDP_SMC911X_CS         1
-#define LDP_SMC911X_GPIO       152
-#define DEBUG_BASE             0x08000000
-#define OMAP34XX_ETHR_START    DEBUG_BASE
-#endif /* __ASM_ARCH_OMAP_LDP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-nokia.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-nokia.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-nokia.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-nokia.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/board-nokia.h
- *
- *  Information structures for Nokia-specific board config data
- *
- *  Copyright (C) 2005	Nokia Corporation
- */
-
-#ifndef _OMAP_BOARD_NOKIA_H
-#define _OMAP_BOARD_NOKIA_H
-
-#include <linux/types.h>
-
-#define OMAP_TAG_NOKIA_BT	0x4e01
-#define OMAP_TAG_WLAN_CX3110X	0x4e02
-#define OMAP_TAG_CBUS		0x4e03
-#define OMAP_TAG_EM_ASIC_BB5	0x4e04
-
-
-#define BT_CHIP_CSR		1
-#define BT_CHIP_TI		2
-
-#define BT_SYSCLK_12		1
-#define BT_SYSCLK_38_4		2
-
-struct omap_bluetooth_config {
-	u8    chip_type;
-	u8    bt_wakeup_gpio;
-	u8    host_wakeup_gpio;
-	u8    reset_gpio;
-	u8    bt_uart;
-	u8    bd_addr[6];
-	u8    bt_sysclk;
-};
-
-struct omap_wlan_cx3110x_config {
-	u8  chip_type;
-	s16 power_gpio;
-	s16 irq_gpio;
-	s16 spi_cs_gpio;
-};
-
-struct omap_cbus_config {
-	s16 clk_gpio;
-	s16 dat_gpio;
-	s16 sel_gpio;
-};
-
-struct omap_em_asic_bb5_config {
-	s16 retu_irq_gpio;
-	s16 tahvo_irq_gpio;
-};
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-omap3beagle.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-omap3beagle.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-omap3beagle.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-omap3beagle.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-omap3beagle.h
- *
- * Hardware definitions for TI OMAP3 BEAGLE.
- *
- * Initial creation by Syed Mohammed Khasim <khasim@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.
- */
-
-#ifndef __ASM_ARCH_OMAP3_BEAGLE_H
-#define __ASM_ARCH_OMAP3_BEAGLE_H
-
-#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-osk.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-osk.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-osk.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-osk.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,47 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-osk.h
- *
- * Hardware definitions for TI OMAP5912 OSK board.
- *
- * Written 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_OMAP_OSK_H
-#define __ASM_ARCH_OMAP_OSK_H
-
-/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
-#define OMAP_OSK_ETHR_START		0x04800300
-
-/* TPS65010 has four GPIOs.  nPG and LED2 can be treated like GPIOs with
- * alternate pin configurations for hardware-controlled blinking.
- */
-#define OSK_TPS_GPIO_BASE		(OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
-#	define OSK_TPS_GPIO_USB_PWR_EN	(OSK_TPS_GPIO_BASE + 0)
-#	define OSK_TPS_GPIO_LED_D3	(OSK_TPS_GPIO_BASE + 1)
-#	define OSK_TPS_GPIO_LAN_RESET	(OSK_TPS_GPIO_BASE + 2)
-#	define OSK_TPS_GPIO_DSP_PWR_EN	(OSK_TPS_GPIO_BASE + 3)
-#	define OSK_TPS_GPIO_LED_D9	(OSK_TPS_GPIO_BASE + 4)
-#	define OSK_TPS_GPIO_LED_D2	(OSK_TPS_GPIO_BASE + 5)
-
-#endif /*  __ASM_ARCH_OMAP_OSK_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-overo.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-overo.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-overo.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-overo.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * board-overo.h (Gumstix Overo)
- *
- * Initial code: Steve Sakoman <steve@sakoman.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.
- *
- * You 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_OVERO_H
-#define __ASM_ARCH_OVERO_H
-
-#define OVERO_GPIO_BT_XGATE	15
-#define OVERO_GPIO_W2W_NRESET	16
-#define OVERO_GPIO_BT_NRESET	164
-#define OVERO_GPIO_USBH_CPEN	168
-#define OVERO_GPIO_USBH_NRESET	183
-
-#endif /* ____ASM_ARCH_OVERO_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmte.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmte.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmte.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmte.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmte.h
- *
- * Hardware definitions for the Palm Tungsten E device.
- *
- * Maintainters :	http://palmtelinux.sf.net
- *			palmtelinux-developpers@lists.sf.net
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __OMAP_BOARD_PALMTE_H
-#define __OMAP_BOARD_PALMTE_H
-
-#define PALMTE_USBDETECT_GPIO	0
-#define PALMTE_USB_OR_DC_GPIO	1
-#define PALMTE_TSC_GPIO		4
-#define PALMTE_PINTDAV_GPIO	6
-#define PALMTE_MMC_WP_GPIO	8
-#define PALMTE_MMC_POWER_GPIO	9
-#define PALMTE_HDQ_GPIO		11
-#define PALMTE_HEADPHONES_GPIO	14
-#define PALMTE_SPEAKER_GPIO	15
-#define PALMTE_DC_GPIO		OMAP_MPUIO(2)
-#define PALMTE_MMC_SWITCH_GPIO	OMAP_MPUIO(4)
-#define PALMTE_MMC1_GPIO	OMAP_MPUIO(6)
-#define PALMTE_MMC2_GPIO	OMAP_MPUIO(7)
-#define PALMTE_MMC3_GPIO	OMAP_MPUIO(11)
-
-#endif	/* __OMAP_BOARD_PALMTE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmtt.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmtt.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmtt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmtt.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmte.h
- *
- * Hardware definitions for the Palm Tungsten|T device.
- *
- * Maintainters :	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 __OMAP_BOARD_PALMTT_H
-#define __OMAP_BOARD_PALMTT_H
-
-#define PALMTT_USBDETECT_GPIO	0
-#define PALMTT_CABLE_GPIO	1
-#define PALMTT_LED_GPIO		3
-#define PALMTT_PENIRQ_GPIO	6
-#define PALMTT_MMC_WP_GPIO	8
-#define PALMTT_HDQ_GPIO		11
-
-#endif	/* __OMAP_BOARD_PALMTT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmz71.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmz71.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-palmz71.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-palmz71.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmz71.h
- *
- * Hardware definitions for the Palm Zire71 device.
- *
- * Maintainters :	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 __OMAP_BOARD_PALMZ71_H
-#define __OMAP_BOARD_PALMZ71_H
-
-#define PALMZ71_USBDETECT_GPIO	0
-#define PALMZ71_PENIRQ_GPIO	6
-#define PALMZ71_MMC_WP_GPIO	8
-#define PALMZ71_HDQ_GPIO 	11
-
-#define PALMZ71_HOTSYNC_GPIO	OMAP_MPUIO(1)
-#define PALMZ71_CABLE_GPIO	OMAP_MPUIO(2)
-#define PALMZ71_SLIDER_GPIO	OMAP_MPUIO(3)
-#define PALMZ71_MMC_IN_GPIO	OMAP_MPUIO(4)
-
-#endif	/* __OMAP_BOARD_PALMZ71_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-perseus2.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-perseus2.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-perseus2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-perseus2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/board-perseus2.h
- *
- *  Copyright 2003 by Texas Instruments Incorporated
- *    OMAP730 / Perseus2 support by Jean Pihet
- *
- * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
- * Author: RidgeRun, 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 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_PERSEUS2_H
-#define __ASM_ARCH_OMAP_PERSEUS2_H
-
-#include <mach/fpga.h>
-
-#ifndef OMAP_SDRAM_DEVICE
-#define OMAP_SDRAM_DEVICE		D256M_1X16_4B
-#endif
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/board-voiceblue.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,6 @@
 extern void voiceblue_wdt_enable(void);
 extern void voiceblue_wdt_disable(void);
 extern void voiceblue_wdt_ping(void);
-extern void voiceblue_reset(void);
 
 #endif /*  __ASM_ARCH_VOICEBLUE_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/clkdev.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clkdev.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clkdev.h	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clockdomain.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-omap/clockdomain.h
+ * arch/arm/plat-omap/include/mach/clockdomain.h
  *
  * OMAP2/3 clockdomain framework functions
  *
@@ -48,11 +48,13 @@
  */
 struct clkdm_pwrdm_autodep {
 
-	/* Name of the powerdomain to add a wkdep/sleepdep on */
-	const char *pwrdm_name;
+	union {
+		/* Name of the powerdomain to add a wkdep/sleepdep on */
+		const char *name;
 
-	/* Powerdomain pointer (looked up at clkdm_init() time) */
-	struct powerdomain *pwrdm;
+		/* 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;
@@ -64,8 +66,13 @@ struct clockdomain {
 	/* Clockdomain name */
 	const char *name;
 
-	/* Powerdomain enclosing this clockdomain */
-	const char *pwrdm_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;
@@ -79,9 +86,6 @@ struct clockdomain {
 	/* Usecount tracking */
 	atomic_t usecount;
 
-	/* Powerdomain pointer assigned at clkdm_register() */
-	struct powerdomain *pwrdm;
-
 	struct list_head node;
 
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/clock.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clock.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,11 +17,16 @@ struct module;
 struct clk;
 struct clockdomain;
 
+struct clkops {
+	int			(*enable)(struct clk *);
+	void			(*disable)(struct clk *);
+};
+
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 
 struct clksel_rate {
-	u8			div;
 	u32			val;
+	u8			div;
 	u8			flags;
 };
 
@@ -34,24 +39,28 @@ 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;
-	unsigned long		last_rounded_rate;
-	unsigned int		rate_tolerance;
-	u16			max_multiplier;
+	u8			min_divider;
 	u8			max_divider;
 	u32			max_tolerance;
+	u16			max_multiplier;
 #  if defined(CONFIG_ARCH_OMAP3)
 	u8			modes;
-	void __iomem		*control_reg;
-	u32			enable_mask;
+	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;
-	void __iomem		*autoidle_reg;
-	u32			autoidle_mask;
-	void __iomem		*idlest_reg;
-	u8			idlest_bit;
 #  endif
 };
 
@@ -59,21 +68,21 @@ struct dpll_data {
 
 struct clk {
 	struct list_head	node;
-	struct module		*owner;
+	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;
-	__u8			enable_bit;
-	__s8			usecount;
-	void			(*recalc)(struct clk *);
+	unsigned long		(*recalc)(struct clk *);
 	int			(*set_rate)(struct clk *, unsigned long);
 	long			(*round_rate)(struct clk *, unsigned long);
 	void			(*init)(struct clk *);
-	int			(*enable)(struct clk *);
-	void			(*disable)(struct clk *);
+	__u8			enable_bit;
+	__s8			usecount;
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 	u8			fixed_div;
 	void __iomem		*clksel_reg;
@@ -99,7 +108,6 @@ struct clk_functions {
 	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);
-	struct clk *	(*clk_get_parent)(struct clk *clk);
 	void		(*clk_allow_idle)(struct clk *clk);
 	void		(*clk_deny_idle)(struct clk *clk);
 	void		(*clk_disable_unused)(struct clk *clk);
@@ -110,42 +118,33 @@ struct clk_functions {
 
 extern unsigned int mpurate;
 
-extern int clk_init(struct clk_functions * custom_clocks);
+extern int clk_init(struct clk_functions *custom_clocks);
+extern void clk_init_one(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 void followparent_recalc(struct clk * clk);
-extern void clk_allow_idle(struct clk *clk);
-extern void clk_deny_idle(struct clk *clk);
-extern int clk_get_usecount(struct clk *clk);
+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 */
-#define RATE_CKCTL		(1 << 0)	/* Main fixed ratio clocks */
+/* bit 0 is free */
 #define RATE_FIXED		(1 << 1)	/* Fixed clock rate */
-#define RATE_PROPAGATES		(1 << 2)	/* Program children too */
-#define VIRTUAL_CLOCK		(1 << 3)	/* Composite clock from table */
-#define ALWAYS_ENABLED		(1 << 4)	/* Clock cannot be disabled */
+/* bits 2-4 are free */
 #define ENABLE_REG_32BIT	(1 << 5)	/* Use 32-bit access */
-#define VIRTUAL_IO_ADDRESS	(1 << 6)	/* Clock in virtual address */
 #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-20 are currently free */
-#define CLOCK_IN_OMAP310	(1 << 21)
-#define CLOCK_IN_OMAP730	(1 << 22)
-#define CLOCK_IN_OMAP1510	(1 << 23)
-#define CLOCK_IN_OMAP16XX	(1 << 24)
-#define CLOCK_IN_OMAP242X	(1 << 25)
-#define CLOCK_IN_OMAP243X	(1 << 26)
-#define CLOCK_IN_OMAP343X	(1 << 27)	/* clocks common to all 343X */
-#define PARENT_CONTROLS_CLOCK	(1 << 28)
-#define CLOCK_IN_OMAP3430ES1	(1 << 29)	/* 3430ES1 clocks only */
-#define CLOCK_IN_OMAP3430ES2	(1 << 30)	/* 3430ES2 clocks only */
+/* bits 13-31 are currently free */
 
 /* Clksel_rate flags */
 #define DEFAULT_RATE		(1 << 0)
@@ -157,9 +156,4 @@ extern void clk_enable_init_clocks(void)
 #define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
 
 
-/* CM_CLKSEL2_PLL.CORE_CLK_SRC options (24XX) */
-#define CORE_CLK_SRC_32K		0
-#define CORE_CLK_SRC_DPLL		1
-#define CORE_CLK_SRC_DPLL_X2		2
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/common.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/common.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,7 @@ void omap2_set_globals_343x(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_memory(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 *);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/cpu.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/cpu.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,14 @@ unsigned int omap_rev(void);
 #  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
@@ -105,7 +113,7 @@ unsigned int omap_rev(void);
 /*
  * Macros to group OMAP into cpu classes.
  * These can be used in most places.
- * cpu_is_omap7xx():	True for OMAP730
+ * 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
@@ -153,6 +161,10 @@ IS_OMAP_SUBCLASS(343x, 0x343)
 #  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()
@@ -166,6 +178,10 @@ IS_OMAP_SUBCLASS(343x, 0x343)
 #  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
@@ -219,6 +235,7 @@ IS_OMAP_SUBCLASS(343x, 0x343)
  * 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
@@ -241,6 +258,7 @@ static inline int is_omap ##type (void)
 
 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)
@@ -255,6 +273,7 @@ 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
@@ -272,12 +291,22 @@ IS_OMAP_TYPE(3430, 0x3430)
 #  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
 #else
 # if defined(CONFIG_ARCH_OMAP730)
 #  undef  cpu_is_omap730
 #  define cpu_is_omap730()		1
 # endif
 #endif
+#else
+# if defined(CONFIG_ARCH_OMAP850)
+#  undef  cpu_is_omap850
+#  define cpu_is_omap850()		1
+# endif
+#endif
 
 /*
  * Whether we have MULTI_OMAP1 or not, we still need to distinguish
@@ -320,7 +349,7 @@ IS_OMAP_TYPE(3430, 0x3430)
 #endif
 
 /* Macros to detect if we have OMAP1 or OMAP2 */
-#define cpu_class_is_omap1()	(cpu_is_omap730() || cpu_is_omap15xx() || \
+#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())
 
@@ -355,13 +384,27 @@ IS_OMAP_TYPE(3430, 0x3430)
  * 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_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)
 
-#define CHIP_IS_OMAP24XX       (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
 
 int omap_chip_is(struct omap_chip_id oci);
 int omap_type(void);
@@ -378,5 +421,3 @@ int omap_type(void);
 void omap2_check_revision(void);
 
 #endif    /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/dmtimer.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,7 @@ void omap_dm_timer_trigger(struct omap_d
 void omap_dm_timer_start(struct omap_dm_timer *timer);
 void omap_dm_timer_stop(struct omap_dm_timer *timer);
 
-void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+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);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/eac.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/eac.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/eac.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/eac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach2/eac.h
- *
- * Defines for Enhanced Audio Controller
- *
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
- *
- * Copyright (C) 2006 Nokia Corporation
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __ASM_ARM_ARCH_OMAP2_EAC_H
-#define __ASM_ARM_ARCH_OMAP2_EAC_H
-
-#include <mach/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <sound/core.h>
-
-/* master codec clock source */
-#define EAC_MCLK_EXT_MASK	0x100
-enum eac_mclk_src {
-	EAC_MCLK_INT_11290000, /* internal 96 MHz / 8.5 = 11.29 Mhz */
-	EAC_MCLK_EXT_11289600 = EAC_MCLK_EXT_MASK,
-	EAC_MCLK_EXT_12288000,
-	EAC_MCLK_EXT_2x11289600,
-	EAC_MCLK_EXT_2x12288000,
-};
-
-/* codec port interface mode */
-enum eac_codec_mode {
-	EAC_CODEC_PCM,
-	EAC_CODEC_AC97,
-	EAC_CODEC_I2S_MASTER, /* codec port, I.e. EAC is the master */
-	EAC_CODEC_I2S_SLAVE,
-};
-
-/* configuration structure for I2S mode */
-struct eac_i2s_conf {
-	/* if enabled, then first data slot (left channel) is signaled as
-	 * positive level of frame sync EAC.AC_FS */
-	unsigned	polarity_changed_mode:1;
-	/* if enabled, then serial data starts one clock cycle after the
-	 * of EAC.AC_FS for first audio slot */
-	unsigned	sync_delay_enable:1;
-};
-
-/* configuration structure for EAC codec port */
-struct eac_codec {
-	enum eac_mclk_src	mclk_src;
-
-	enum eac_codec_mode	codec_mode;
-	union {
-		struct eac_i2s_conf	i2s;
-	} codec_conf;
-
-	int		default_rate; /* audio sampling rate */
-
-	int		(* set_power)(void *private_data, int dac, int adc);
-	int		(* register_controls)(void *private_data,
-					      struct snd_card *card);
-	const char 	*short_name;
-
-	void		*private_data;
-};
-
-/* structure for passing platform dependent data to the EAC driver */
-struct eac_platform_data {
-        int	(* init)(struct device *eac_dev);
-	void	(* cleanup)(struct device *eac_dev);
-	/* these callbacks are used to configure & control external MCLK
-	 * source. NULL if not used */
-	int	(* enable_ext_clocks)(struct device *eac_dev);
-	void	(* disable_ext_clocks)(struct device *eac_dev);
-};
-
-extern void omap_init_eac(struct eac_platform_data *pdata);
-
-extern int eac_register_codec(struct device *eac_dev, struct eac_codec *codec);
-extern void eac_unregister_codec(struct device *eac_dev);
-
-extern int eac_set_mode(struct device *eac_dev, int play, int rec);
-
-#endif /* __ASM_ARM_ARCH_OMAP2_EAC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpioexpander.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpioexpander.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpioexpander.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpioexpander.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/gpioexpander.h
- *
- *
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef __ASM_ARCH_OMAP_GPIOEXPANDER_H
-#define __ASM_ARCH_OMAP_GPIOEXPANDER_H
-
-/* Function Prototypes for GPIO Expander functions */
-
-#ifdef CONFIG_GPIOEXPANDER_OMAP
-int read_gpio_expa(u8 *, int);
-int write_gpio_expa(u8 , int);
-#else
-static inline int read_gpio_expa(u8 *val, int addr)
-{
-	return 0;
-}
-static inline int write_gpio_expa(u8 val, int addr)
-{
-	return 0;
-}
-#endif
-
-#endif /* __ASM_ARCH_OMAP_GPIOEXPANDER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpio.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,8 @@
 
 #define OMAP_MPUIO_BASE			0xfffb5000
 
-#ifdef CONFIG_ARCH_OMAP730
+#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
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpmc.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpmc.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/gpmc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/gpmc.h	2009-06-09 23:05:27.000000000 -0400
@@ -103,6 +103,6 @@ extern int gpmc_cs_request(int cs, unsig
 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 void gpmc_init(void);
+extern void __init gpmc_init(void);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/hardware.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/hardware.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/hardware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -286,78 +286,4 @@
 #include "omap24xx.h"
 #include "omap34xx.h"
 
-#ifndef __ASSEMBLER__
-
-/*
- * ---------------------------------------------------------------------------
- * Board specific defines
- * ---------------------------------------------------------------------------
- */
-
-#ifdef CONFIG_MACH_OMAP_INNOVATOR
-#include "board-innovator.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H2
-#include "board-h2.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
-#include "board-perseus2.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_FSAMPLE
-#include "board-fsample.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H3
-#include "board-h3.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H4
-#include "board-h4.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_2430SDP
-#include "board-2430sdp.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP3_BEAGLE
-#include "board-omap3beagle.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_LDP
-#include "board-ldp.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_APOLLON
-#include "board-apollon.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_OSK
-#include "board-osk.h"
-#endif
-
-#ifdef CONFIG_MACH_VOICEBLUE
-#include "board-voiceblue.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMTE
-#include "board-palmte.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMZ71
-#include "board-palmz71.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMTT
-#include "board-palmtt.h"
-#endif
-
-#ifdef CONFIG_MACH_SX1
-#include "board-sx1.h"
-#endif
-
-#endif /* !__ASSEMBLER__ */
-
 #endif	/* __ASM_ARCH_OMAP_HARDWARE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/io.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/io.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -185,11 +185,13 @@
 #define omap_writew(v,a)	__raw_writew(v, IO_ADDRESS(a))
 #define omap_writel(v,a)	__raw_writel(v, IO_ADDRESS(a))
 
+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(void);
+extern void omap2_init_common_hw(struct omap_sdrc_params *sp);
 
 #define __arch_ioremap(p,s,t)	omap_ioremap(p,s,t)
 #define __arch_iounmap(v)	omap_iounmap(v)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/irda.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/irda.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/irda.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/irda.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,10 +21,6 @@ struct omap_irda_config {
 	int transceiver_cap;
 	int (*transceiver_mode)(struct device *dev, int mode);
 	int (*select_irda)(struct device *dev, int state);
-	/* Very specific to the needs of some platforms (h3,h4)
-	 * having calls which can sleep in irda_set_speed.
-	 */
-	struct delayed_work gpio_expa;
 	int rx_channel;
 	int tx_channel;
 	unsigned long dest_start;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/irqs.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/irqs.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/irqs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -105,6 +105,29 @@
 #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
@@ -237,6 +260,64 @@
 #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
@@ -341,7 +422,7 @@
 
 #define	INT_34XX_BENCH_MPU_EMUL	3
 
-/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
+/* 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)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mailbox.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mailbox.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mailbox.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mailbox.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,9 @@ struct omap_mbox_ops {
 	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 {
@@ -53,7 +56,7 @@ struct omap_mbox {
 
 	mbox_msg_t		seq_snd, seq_rcv;
 
-	struct device		dev;
+	struct device		*dev;
 
 	struct omap_mbox	*next;
 	void			*priv;
@@ -67,7 +70,27 @@ 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 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.29-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mcbsp.h	2009-06-09 23:05:27.000000000 -0400
@@ -344,8 +344,6 @@ struct omap_mcbsp_platform_data {
 	u8 dma_rx_sync, dma_tx_sync;
 	u16 rx_irq, tx_irq;
 	struct omap_mcbsp_ops *ops;
-	char const **clk_names;
-	int num_clks;
 };
 
 struct omap_mcbsp {
@@ -377,8 +375,8 @@ struct omap_mcbsp {
 	/* Protect the field .free, while checking if the mcbsp is in use */
 	spinlock_t lock;
 	struct omap_mcbsp_platform_data *pdata;
-	struct clk **clks;
-	int num_clks;
+	struct clk *iclk;
+	struct clk *fclk;
 };
 extern struct omap_mcbsp **mcbsp_ptr;
 extern int omap_mcbsp_count;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/memory.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/memory.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/memory.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/memory.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,9 +61,11 @@
 #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)	({is_lbus_device(dev) ? \
-					(dma_addr_t)virt_to_lbus(page_address(page)) : \
-					(dma_addr_t)__virt_to_phys(page_address(page));})
+#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) : \
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mmc.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mmc.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mmc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mmc.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,8 @@
 #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;
@@ -77,7 +79,6 @@ struct omap_mmc_platform_data {
 
 		/* use the internal clock */
 		unsigned internal_clock:1;
-		s16 power_pin;
 
 		int switch_pin;			/* gpio (card detect) */
 		int gpio_wp;			/* gpio (write protect) */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mux.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mux.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/mux.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/mux.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,6 +61,16 @@
 					.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, \
@@ -83,6 +93,15 @@
 					.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,	\
@@ -98,7 +117,7 @@
 
 
 /*
- * OMAP730 has a slightly different config for the pin mux.
+ * 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
@@ -114,6 +133,17 @@
 	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)	\
 {								\
@@ -221,6 +251,26 @@ enum omap730_index {
 	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,
@@ -788,7 +838,20 @@ enum omap34xx_index {
 	 *  - "_DOWN" suffix (GPIO3_DOWN) with internal pulldown
 	 *  - "_OUT" suffix (GPIO3_OUT) for output-only pins (unlike 24xx)
 	 */
+	AF26_34XX_GPIO0,
+	AF22_34XX_GPIO9,
 	AH8_34XX_GPIO29,
+	U8_34XX_GPIO54_OUT,
+	U8_34XX_GPIO54_DOWN,
+	L8_34XX_GPIO63,
+	G25_34XX_GPIO86_OUT,
+	AG4_34XX_GPIO134_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,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/omap34xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,11 +49,39 @@
 #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)
 
 #if defined(CONFIG_ARCH_OMAP3430)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/omap850.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/omap850.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/omap850.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/omap850.h	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/arch/arm/plat-omap/include/mach/pm.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/pm.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/pm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/pm.h	2009-06-09 23:05:27.000000000 -0400
@@ -118,18 +118,6 @@
 extern void prevent_idle_sleep(void);
 extern void allow_idle_sleep(void);
 
-/**
- * clk_deny_idle - Prevents the clock from being idled during MPU idle
- * @clk: clock signal handle
- */
-void clk_deny_idle(struct clk *clk);
-
-/**
- * clk_allow_idle - Counters previous clk_deny_idle
- * @clk: clock signal handle
- */
-void clk_allow_idle(struct clk *clk);
-
 extern void omap_pm_idle(void);
 extern void omap_pm_suspend(void);
 extern void omap730_cpu_suspend(unsigned short, unsigned short);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/powerdomain.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,9 +50,9 @@
 
 /*
  * Maximum number of clockdomains that can be associated with a powerdomain.
- * CORE powerdomain is probably the worst case.
+ * CORE powerdomain on OMAP3 is the worst case
  */
-#define PWRDM_MAX_CLKDMS	3
+#define PWRDM_MAX_CLKDMS	4
 
 /* XXX A completely arbitrary number. What is reasonable here? */
 #define PWRDM_TRANSITION_BAILOUT 100000
@@ -145,6 +145,7 @@ int pwrdm_get_mem_bank_count(struct powe
 
 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);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/prcm.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/prcm.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/prcm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/prcm.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,10 +20,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
-#define __ASM_ARM_ARCH_DPM_PRCM_H
+#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);
 
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/sdrc.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/sdrc.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/sdrc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/sdrc.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,10 +4,12 @@
 /*
  * OMAP2/3 SDRC/SMS register definitions
  *
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
  *
- * Written by Paul Walmsley
+ * 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
@@ -64,14 +66,62 @@
  * SMS register access
  */
 
-
-#define OMAP242X_SMS_REGADDR(reg)	IO_ADDRESS(OMAP2420_SMS_BASE + reg)
-#define OMAP243X_SMS_REGADDR(reg)	IO_ADDRESS(OMAP243X_SMS_BASE + reg)
-#define OMAP343X_SMS_REGADDR(reg)	IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+#define OMAP242X_SMS_REGADDR(reg)					\
+			(void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg)					\
+			(void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg)					\
+			(void __iomem *)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 *sp);
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r);
+
+#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.29-gnu1/arch/arm/plat-omap/include/mach/system.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/system.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,12 +9,14 @@
 #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
 
-extern void omap_prcm_arch_reset(char mode);
-
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
@@ -38,7 +40,7 @@ static inline void omap1_arch_reset(char
 		omap_writew(1, ARM_RSTCT1);
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	if (!cpu_class_is_omap2())
 		omap1_arch_reset(mode);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/timer-gp.h	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/arch/arm/plat-omap/include/mach/usb.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/usb.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/include/mach/usb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/include/mach/usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,8 +27,18 @@
 #define UDC_BASE			OMAP2_UDC_BASE
 #define OMAP_OHCI_BASE			OMAP2_OHCI_BASE
 
+#ifdef CONFIG_USB_MUSB_SOC
+extern void usb_musb_init(void);
+#else
+static inline void usb_musb_init(void)
+{
+}
+#endif
+
 #endif
 
+void omap_usb_init(struct omap_usb_config *pdata);
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/Kconfig linux-libre-2.6.30-gnu1/arch/arm/plat-omap/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -11,14 +11,17 @@ choice
 
 config ARCH_OMAP1
 	bool "TI OMAP1"
+	select COMMON_CLKDEV
 
 config ARCH_OMAP2
 	bool "TI OMAP2"
 	select CPU_V6
+	select COMMON_CLKDEV
 
 config ARCH_OMAP3
 	bool "TI OMAP3"
 	select CPU_V7
+	select COMMON_CLKDEV
 
 endchoice
 
@@ -104,6 +107,14 @@ config OMAP_MCBSP
 	  Say Y here if you want support for the OMAP Multichannel
 	  Buffered Serial Port.
 
+config OMAP_MBOX_FWK
+	tristate "Mailbox framework support"
+	depends on ARCH_OMAP
+	default n
+	help
+	  Say Y here if you want to use OMAP Mailbox framework support for
+	  DSP, IVA1.0 and IVA2 in OMAP1/2/3.
+
 choice
         prompt "System timer"
 	default OMAP_MPU_TIMER
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mailbox.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mailbox.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mailbox.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mailbox.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,9 @@
 /*
  * OMAP mailbox driver
  *
- * Copyright (C) 2006 Nokia Corporation. All rights reserved.
+ * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
  *
- * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
- *		Restructured by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -22,21 +21,98 @@
  *
  */
 
-#include <linux/init.h>
 #include <linux/module.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
-#include <linux/blkdev.h>
-#include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/io.h>
+
 #include <mach/mailbox.h>
-#include "mailbox.h"
+
+static int enable_seq_bit;
+module_param(enable_seq_bit, bool, 0);
+MODULE_PARM_DESC(enable_seq_bit, "Enable sequence bit checking.");
 
 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;
+}
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_read(mbox);
+}
+static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	mbox->ops->fifo_write(mbox, msg);
+}
+static inline int mbox_fifo_empty(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_empty(mbox);
+}
+static inline int mbox_fifo_full(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_full(mbox);
+}
+
+/* Mailbox IRQ handle functions */
+static inline void 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)
+		mbox->ops->ack_irq(mbox, irq);
+}
+static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	return mbox->ops->is_irq(mbox, irq);
+}
+
 /* Mailbox Sequence Bit function */
 void omap_mbox_init_seq(struct omap_mbox *mbox)
 {
@@ -136,7 +212,7 @@ static void mbox_rx_work(struct work_str
 	unsigned long flags;
 
 	if (mbox->rxq->callback == NULL) {
-		sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
+		sysfs_notify(&mbox->dev->kobj, NULL, "mbox");
 		return;
 	}
 
@@ -204,7 +280,7 @@ 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:
+nomem:
 	schedule_work(&mbox->rxq->work);
 }
 
@@ -286,7 +362,7 @@ static ssize_t mbox_show(struct class *c
 static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
 
 static struct class omap_mbox_class = {
-	.name = "omap_mbox",
+	.name = "omap-mailbox",
 };
 
 static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
@@ -333,21 +409,6 @@ static int omap_mbox_init(struct omap_mb
 			return ret;
 	}
 
-	mbox->dev.class = &omap_mbox_class;
-	dev_set_name(&mbox->dev, "%s", mbox->name);
-	dev_set_drvdata(&mbox->dev, mbox);
-
-	ret = device_register(&mbox->dev);
-	if (unlikely(ret))
-		goto fail_device_reg;
-
-	ret = device_create_file(&mbox->dev, &dev_attr_mbox);
-	if (unlikely(ret)) {
-		printk(KERN_ERR
-			"device_create_file failed: %d\n", ret);
-		goto fail_create_mbox;
-	}
-
 	ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
 				mbox->name, mbox);
 	if (unlikely(ret)) {
@@ -377,10 +438,6 @@ static int omap_mbox_init(struct omap_mb
  fail_alloc_txq:
 	free_irq(mbox->irq, mbox);
  fail_request_irq:
-	device_remove_file(&mbox->dev, &dev_attr_mbox);
- fail_create_mbox:
-	device_unregister(&mbox->dev);
- fail_device_reg:
 	if (unlikely(mbox->ops->shutdown))
 		mbox->ops->shutdown(mbox);
 
@@ -393,8 +450,6 @@ static void omap_mbox_fini(struct omap_m
 	mbox_queue_free(mbox->rxq);
 
 	free_irq(mbox->irq, mbox);
-	device_remove_file(&mbox->dev, &dev_attr_mbox);
-	class_unregister(&omap_mbox_class);
 
 	if (unlikely(mbox->ops->shutdown))
 		mbox->ops->shutdown(mbox);
@@ -440,7 +495,7 @@ void omap_mbox_put(struct omap_mbox *mbo
 }
 EXPORT_SYMBOL(omap_mbox_put);
 
-int omap_mbox_register(struct omap_mbox *mbox)
+int omap_mbox_register(struct device *parent, struct omap_mbox *mbox)
 {
 	int ret = 0;
 	struct omap_mbox **tmp;
@@ -450,14 +505,31 @@ int omap_mbox_register(struct omap_mbox
 	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)
+	if (*tmp) {
 		ret = -EBUSY;
-	else
-		*tmp = mbox;
+		write_unlock(&mboxes_lock);
+		goto err_find;
+	}
+	*tmp = mbox;
 	write_unlock(&mboxes_lock);
 
+	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);
@@ -473,6 +545,8 @@ 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;
@@ -501,4 +575,6 @@ static void __exit omap_mbox_class_exit(
 subsys_initcall(omap_mbox_class_init);
 module_exit(omap_mbox_class_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
+MODULE_AUTHOR("Toshihiro Kobayashi and Hiroshi DOYU");
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mailbox.h linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mailbox.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mailbox.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mailbox.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*
- * Mailbox internal functions
- *
- * Copyright (C) 2006 Nokia Corporation
- * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef __ARCH_ARM_PLAT_MAILBOX_H
-#define __ARCH_ARM_PLAT_MAILBOX_H
-
-/*
- * Mailbox sequence bit API
- */
-#if defined(CONFIG_ARCH_OMAP1)
-#  define MBOX_USE_SEQ_BIT
-#elif defined(CONFIG_ARCH_OMAP2)
-#  define MBOX_USE_SEQ_BIT
-#endif
-
-#ifdef MBOX_USE_SEQ_BIT
-/* 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)
-{
-	/* 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)
-{
-	/* 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 = msg & (1 << 31);
-	if (seq == mbox->seq_rcv)
-		return -1;
-	mbox->seq_rcv = seq;
-	return 0;
-}
-#else
-static inline void mbox_seq_init(struct omap_mbox *mbox)
-{
-}
-static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
-{
-}
-static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	return 0;
-}
-#endif
-
-/* Mailbox FIFO handle functions */
-static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_read(mbox);
-}
-static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	mbox->ops->fifo_write(mbox, msg);
-}
-static inline int mbox_fifo_empty(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_empty(mbox);
-}
-static inline int mbox_fifo_full(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_full(mbox);
-}
-
-/* Mailbox IRQ handle functions */
-static inline void 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)
-		mbox->ops->ack_irq(mbox, irq);
-}
-static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	return mbox->ops->is_irq(mbox, irq);
-}
-
-#endif				/* __ARCH_ARM_PLAT_MAILBOX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mcbsp.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mcbsp.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/mcbsp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/mcbsp.c	2009-06-09 23:05:27.000000000 -0400
@@ -214,7 +214,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 int omap_mcbsp_request(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
-	int i;
 	int err;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
@@ -223,23 +222,23 @@ int omap_mcbsp_request(unsigned int id)
 	}
 	mcbsp = id_to_mcbsp_ptr(id);
 
-	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
-		mcbsp->pdata->ops->request(id);
-
-	for (i = 0; i < mcbsp->num_clks; i++)
-		clk_enable(mcbsp->clks[i]);
-
 	spin_lock(&mcbsp->lock);
 	if (!mcbsp->free) {
 		dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
 			mcbsp->id);
 		spin_unlock(&mcbsp->lock);
-		return -1;
+		return -EBUSY;
 	}
 
 	mcbsp->free = 0;
 	spin_unlock(&mcbsp->lock);
 
+	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+		mcbsp->pdata->ops->request(id);
+
+	clk_enable(mcbsp->iclk);
+	clk_enable(mcbsp->fclk);
+
 	/*
 	 * Make sure that transmitter, receiver and sample-rate generator are
 	 * not running before activating IRQs.
@@ -278,7 +277,6 @@ EXPORT_SYMBOL(omap_mcbsp_request);
 void omap_mcbsp_free(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
-	int i;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -289,8 +287,14 @@ void omap_mcbsp_free(unsigned int id)
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
 		mcbsp->pdata->ops->free(id);
 
-	for (i = mcbsp->num_clks - 1; i >= 0; i--)
-		clk_disable(mcbsp->clks[i]);
+	clk_disable(mcbsp->fclk);
+	clk_disable(mcbsp->iclk);
+
+	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
+		/* Free IRQs */
+		free_irq(mcbsp->rx_irq, (void *)mcbsp);
+		free_irq(mcbsp->tx_irq, (void *)mcbsp);
+	}
 
 	spin_lock(&mcbsp->lock);
 	if (mcbsp->free) {
@@ -302,12 +306,6 @@ void omap_mcbsp_free(unsigned int id)
 
 	mcbsp->free = 1;
 	spin_unlock(&mcbsp->lock);
-
-	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
-		/* Free IRQs */
-		free_irq(mcbsp->rx_irq, (void *)mcbsp);
-		free_irq(mcbsp->tx_irq, (void *)mcbsp);
-	}
 }
 EXPORT_SYMBOL(omap_mcbsp_free);
 
@@ -876,7 +874,6 @@ static int __devinit omap_mcbsp_probe(st
 	struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
 	struct omap_mcbsp *mcbsp;
 	int id = pdev->id - 1;
-	int i;
 	int ret = 0;
 
 	if (!pdata) {
@@ -899,7 +896,6 @@ static int __devinit omap_mcbsp_probe(st
 		ret = -ENOMEM;
 		goto exit;
 	}
-	mcbsp_ptr[id] = mcbsp;
 
 	spin_lock_init(&mcbsp->lock);
 	mcbsp->id = id + 1;
@@ -921,39 +917,32 @@ static int __devinit omap_mcbsp_probe(st
 	mcbsp->dma_rx_sync = pdata->dma_rx_sync;
 	mcbsp->dma_tx_sync = pdata->dma_tx_sync;
 
-	if (pdata->num_clks) {
-		mcbsp->num_clks = pdata->num_clks;
-		mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *),
-					GFP_KERNEL);
-		if (!mcbsp->clks) {
-			ret = -ENOMEM;
-			goto exit;
-		}
-		for (i = 0; i < mcbsp->num_clks; i++) {
-			mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]);
-			if (IS_ERR(mcbsp->clks[i])) {
-				dev_err(&pdev->dev,
-					"Invalid %s configuration for McBSP%d.\n",
-					pdata->clk_names[i], mcbsp->id);
-				ret = PTR_ERR(mcbsp->clks[i]);
-				goto err_clk;
-			}
-		}
+	mcbsp->iclk = clk_get(&pdev->dev, "ick");
+	if (IS_ERR(mcbsp->iclk)) {
+		ret = PTR_ERR(mcbsp->iclk);
+		dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
+		goto err_iclk;
+	}
 
+	mcbsp->fclk = clk_get(&pdev->dev, "fck");
+	if (IS_ERR(mcbsp->fclk)) {
+		ret = PTR_ERR(mcbsp->fclk);
+		dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
+		goto err_fclk;
 	}
 
 	mcbsp->pdata = pdata;
 	mcbsp->dev = &pdev->dev;
+	mcbsp_ptr[id] = mcbsp;
 	platform_set_drvdata(pdev, mcbsp);
 	return 0;
 
-err_clk:
-	while (i--)
-		clk_put(mcbsp->clks[i]);
-	kfree(mcbsp->clks);
+err_fclk:
+	clk_put(mcbsp->iclk);
+err_iclk:
 	iounmap(mcbsp->io_base);
 err_ioremap:
-	mcbsp->free = 0;
+	kfree(mcbsp);
 exit:
 	return ret;
 }
@@ -961,7 +950,6 @@ exit:
 static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
 {
 	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
-	int i;
 
 	platform_set_drvdata(pdev, NULL);
 	if (mcbsp) {
@@ -970,18 +958,15 @@ static int __devexit omap_mcbsp_remove(s
 				mcbsp->pdata->ops->free)
 			mcbsp->pdata->ops->free(mcbsp->id);
 
-		for (i = mcbsp->num_clks - 1; i >= 0; i--) {
-			clk_disable(mcbsp->clks[i]);
-			clk_put(mcbsp->clks[i]);
-		}
+		clk_disable(mcbsp->fclk);
+		clk_disable(mcbsp->iclk);
+		clk_put(mcbsp->fclk);
+		clk_put(mcbsp->iclk);
 
 		iounmap(mcbsp->io_base);
 
-		if (mcbsp->num_clks) {
-			kfree(mcbsp->clks);
-			mcbsp->clks = NULL;
-			mcbsp->num_clks = 0;
-		}
+		mcbsp->fclk = NULL;
+		mcbsp->iclk = NULL;
 		mcbsp->free = 0;
 		mcbsp->dev = NULL;
 	}
@@ -1002,4 +987,3 @@ int __init omap_mcbsp_init(void)
 	/* Register the McBSP driver */
 	return platform_driver_register(&omap_mcbsp_driver);
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/sram.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/sram.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/sram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/sram.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,7 +148,7 @@ void __init omap_detect_sram(void)
 		omap_sram_base = OMAP1_SRAM_VA;
 		omap_sram_start = OMAP1_SRAM_PA;
 
-		if (cpu_is_omap730())
+		if (cpu_is_omap7xx())
 			omap_sram_size = 0x32000;	/* 200K */
 		else if (cpu_is_omap15xx())
 			omap_sram_size = 0x30000;	/* 192K */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-omap/usb.c linux-libre-2.6.30-gnu1/arch/arm/plat-omap/usb.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-omap/usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-omap/usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -729,30 +729,13 @@ static inline void omap_1510_usb_init(st
 
 /*-------------------------------------------------------------------------*/
 
-static struct omap_usb_config platform_data;
-
-static int __init
-omap_usb_init(void)
+void __init omap_usb_init(struct omap_usb_config *pdata)
 {
-	const struct omap_usb_config *config;
-
-	config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
-	if (config == NULL) {
-		printk(KERN_ERR "USB: No board-specific "
-				"platform config found\n");
-		return -ENODEV;
-	}
-	platform_data = *config;
-
 	if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
-		omap_otg_init(&platform_data);
+		omap_otg_init(pdata);
 	else if (cpu_is_omap15xx())
-		omap_1510_usb_init(&platform_data);
-	else {
+		omap_1510_usb_init(pdata);
+	else
 		printk(KERN_ERR "USB: No init for your chip yet\n");
-		return -ENODEV;
-	}
-	return 0;
 }
 
-subsys_initcall(omap_usb_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-orion/gpio.c linux-libre-2.6.30-gnu1/arch/arm/plat-orion/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-orion/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-orion/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,8 @@
 
 static DEFINE_SPINLOCK(gpio_lock);
 static const char *gpio_label[GPIO_MAX];  /* non null for allocated GPIOs */
-static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
 
 static inline void __set_direction(unsigned pin, int input)
 {
@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin)
 {
 	unsigned long flags;
 
-	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
 		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
 		return -EINVAL;
 	}
@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin,
 	unsigned long flags;
 	u32 u;
 
-	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
 		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
 		return -EINVAL;
 	}
@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const cha
 	unsigned long flags;
 	int ret;
 
-	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+	if (pin >= GPIO_MAX ||
+	    !(test_bit(pin, gpio_valid_input) ||
+	      test_bit(pin, gpio_valid_output))) {
 		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
 		return -EINVAL;
 	}
@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request);
 
 void gpio_free(unsigned pin)
 {
-	if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+	if (pin >= GPIO_MAX ||
+	    !(test_bit(pin, gpio_valid_input) ||
+	      test_bit(pin, gpio_valid_output))) {
 		pr_debug("%s: invalid GPIO %d\n", __func__, pin);
 		return;
 	}
@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsign
 	__set_direction(pin, 0);
 }
 
-void __init orion_gpio_set_valid(unsigned pin, int valid)
+void __init orion_gpio_set_valid(unsigned pin, int mode)
 {
-	if (valid)
-		__set_bit(pin, gpio_valid);
+	if (mode == 1)
+		mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
+	if (mode & GPIO_INPUT_OK)
+		__set_bit(pin, gpio_valid_input);
 	else
-		__clear_bit(pin, gpio_valid);
+		__clear_bit(pin, gpio_valid_input);
+	if (mode & GPIO_OUTPUT_OK)
+		__set_bit(pin, gpio_valid_output);
+	else
+		__clear_bit(pin, gpio_valid_output);
 }
 
 void orion_gpio_set_blink(unsigned pin, int blink)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/gpio.h linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int va
  * Orion-specific GPIO API extensions.
  */
 void orion_gpio_set_unused(unsigned pin);
-void orion_gpio_set_valid(unsigned pin, int valid);
 void orion_gpio_set_blink(unsigned pin, int blink);
 
+#define GPIO_BIDI_OK		(1 << 0)
+#define GPIO_INPUT_OK		(1 << 1)
+#define GPIO_OUTPUT_OK		(1 << 2)
+void orion_gpio_set_valid(unsigned pin, int mode);
+
 /*
  * GPIO interrupt handling.
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/mvsdio.h linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/mvsdio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/mvsdio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/mvsdio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-orion/include/plat/mvsdio.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 __MACH_MVSDIO_H
+#define __MACH_MVSDIO_H
+
+#include <linux/mbus.h>
+
+struct mvsdio_platform_data {
+	struct mbus_dram_target_info *dram;
+	unsigned int clock;
+	int gpio_card_detect;
+	int gpio_write_protect;
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/orion5x_wdt.h linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/orion5x_wdt.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-orion/include/plat/orion5x_wdt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-orion/include/plat/orion5x_wdt.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/plat-orion/include/plat/orion5x_wdt.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 __PLAT_ORION5X_WDT_H
+#define __PLAT_ORION5X_WDT_H
+
+struct orion5x_wdt_platform_data {
+	u32	tclk;		/* no <linux/clk.h> support yet */
+};
+
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-orion/time.c linux-libre-2.6.30-gnu1/arch/arm/plat-orion/time.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-orion/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-orion/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/mach/time.h>
-#include <mach/hardware.h>
+#include <mach/bridge-regs.h>
 
 /*
  * Number of timer ticks per jiffy.
@@ -41,7 +41,7 @@ static u32 ticks_per_jiffy;
 /*
  * Clocksource handling.
  */
-static cycle_t orion_clksrc_read(void)
+static cycle_t orion_clksrc_read(struct clocksource *cs)
 {
 	return 0xffffffff - readl(TIMER0_VAL);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/dma.c linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ *  linux/arch/arm/plat-pxa/dma.c
+ *
+ *  PXA DMA registration and IRQ dispatching
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Nov 15, 2001
+ *  Copyright:	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 version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+
+struct dma_channel {
+	char *name;
+	pxa_dma_prio prio;
+	void (*irq_handler)(int, void *);
+	void *data;
+};
+
+static struct dma_channel *dma_channels;
+static int num_dma_channels;
+
+int pxa_request_dma (char *name, pxa_dma_prio prio,
+			void (*irq_handler)(int, void *),
+			void *data)
+{
+	unsigned long flags;
+	int i, found = 0;
+
+	/* basic sanity checks */
+	if (!name || !irq_handler)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	do {
+		/* try grabbing a DMA channel with the requested priority */
+		for (i = 0; i < num_dma_channels; i++) {
+			if ((dma_channels[i].prio == prio) &&
+			    !dma_channels[i].name) {
+				found = 1;
+				break;
+			}
+		}
+		/* if requested prio group is full, try a hier priority */
+	} while (!found && prio--);
+
+	if (found) {
+		DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+		dma_channels[i].name = name;
+		dma_channels[i].irq_handler = irq_handler;
+		dma_channels[i].data = data;
+	} else {
+		printk (KERN_WARNING "No more available DMA channels for %s\n", name);
+		i = -ENODEV;
+	}
+
+	local_irq_restore(flags);
+	return i;
+}
+
+void pxa_free_dma (int dma_ch)
+{
+	unsigned long flags;
+
+	if (!dma_channels[dma_ch].name) {
+		printk (KERN_CRIT
+			"%s: trying to free channel %d which is already freed\n",
+			__func__, dma_ch);
+		return;
+	}
+
+	local_irq_save(flags);
+	DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+	dma_channels[dma_ch].name = NULL;
+	local_irq_restore(flags);
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	int i, dint = DINT;
+
+	for (i = 0; i < num_dma_channels; i++) {
+		if (dint & (1 << i)) {
+			struct dma_channel *channel = &dma_channels[i];
+			if (channel->name && channel->irq_handler) {
+				channel->irq_handler(i, channel->data);
+			} else {
+				/*
+				 * IRQ for an unregistered DMA channel:
+				 * let's clear the interrupts and disable it.
+				 */
+				printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
+				DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+int __init pxa_init_dma(int irq, int num_ch)
+{
+	int i, ret;
+
+	dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
+	if (dma_channels == NULL)
+		return -ENOMEM;
+
+	/* dma channel priorities on pxa2xx processors:
+	 * ch 0 - 3,  16 - 19  <--> (0) DMA_PRIO_HIGH
+	 * ch 4 - 7,  20 - 23  <--> (1) DMA_PRIO_MEDIUM
+	 * ch 8 - 15, 24 - 31  <--> (2) DMA_PRIO_LOW
+	 */
+	for (i = 0; i < num_ch; i++) {
+		DCSR(i) = 0;
+		dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
+	}
+
+	ret = request_irq(irq, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
+	if (ret) {
+		printk (KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
+		kfree(dma_channels);
+		return ret;
+	}
+
+	num_dma_channels = num_ch;
+	return 0;
+}
+
+EXPORT_SYMBOL(pxa_request_dma);
+EXPORT_SYMBOL(pxa_free_dma);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/gpio.c linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/gpio.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,352 @@
+/*
+ *  linux/arch/arm/plat-pxa/gpio.c
+ *
+ *  Generic PXA GPIO handling
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	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 version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/bootmem.h>
+
+#include <mach/gpio.h>
+
+int pxa_last_gpio;
+
+struct pxa_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem	*regbase;
+	char label[10];
+
+	unsigned long	irq_mask;
+	unsigned long	irq_edge_rise;
+	unsigned long	irq_edge_fall;
+
+#ifdef CONFIG_PM
+	unsigned long	saved_gplr;
+	unsigned long	saved_gpdr;
+	unsigned long	saved_grer;
+	unsigned long	saved_gfer;
+#endif
+};
+
+static DEFINE_SPINLOCK(gpio_lock);
+static struct pxa_gpio_chip *pxa_gpio_chips;
+
+#define for_each_gpio_chip(i, c)			\
+	for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
+
+static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
+{
+	return container_of(c, struct pxa_gpio_chip, chip)->regbase;
+}
+
+static inline struct pxa_gpio_chip *gpio_to_chip(unsigned gpio)
+{
+	return &pxa_gpio_chips[gpio_to_bank(gpio)];
+}
+
+static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	void __iomem *base = gpio_chip_base(chip);
+	uint32_t value, mask = 1 << offset;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	value = __raw_readl(base + GPDR_OFFSET);
+	if (__gpio_is_inverted(chip->base + offset))
+		value |= mask;
+	else
+		value &= ~mask;
+	__raw_writel(value, base + GPDR_OFFSET);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+
+static int pxa_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	void __iomem *base = gpio_chip_base(chip);
+	uint32_t tmp, mask = 1 << offset;
+	unsigned long flags;
+
+	__raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	tmp = __raw_readl(base + GPDR_OFFSET);
+	if (__gpio_is_inverted(chip->base + offset))
+		tmp &= ~mask;
+	else
+		tmp |= mask;
+	__raw_writel(tmp, base + GPDR_OFFSET);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+	return 0;
+}
+
+static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
+}
+
+static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	__raw_writel(1 << offset, gpio_chip_base(chip) +
+				(value ? GPSR_OFFSET : GPCR_OFFSET));
+}
+
+static int __init pxa_init_gpio_chip(int gpio_end)
+{
+	int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+	struct pxa_gpio_chip *chips;
+
+	/* this is early, we have to use bootmem allocator, and we really
+	 * want this to be allocated dynamically for different 'gpio_end'
+	 */
+	chips = alloc_bootmem_low(nbanks * sizeof(struct pxa_gpio_chip));
+	if (chips == NULL) {
+		pr_err("%s: failed to allocate GPIO chips\n", __func__);
+		return -ENOMEM;
+	}
+
+	memset(chips, 0, nbanks * sizeof(struct pxa_gpio_chip));
+
+	for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
+		struct gpio_chip *c = &chips[i].chip;
+
+		sprintf(chips[i].label, "gpio-%d", i);
+		chips[i].regbase = (void __iomem *)GPIO_BANK(i);
+
+		c->base  = gpio;
+		c->label = chips[i].label;
+
+		c->direction_input  = pxa_gpio_direction_input;
+		c->direction_output = pxa_gpio_direction_output;
+		c->get = pxa_gpio_get;
+		c->set = pxa_gpio_set;
+
+		/* number of GPIOs on last bank may be less than 32 */
+		c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+		gpiochip_add(c);
+	}
+	pxa_gpio_chips = chips;
+	return 0;
+}
+
+/* Update only those GRERx and GFERx edge detection register bits if those
+ * bits are set in c->irq_mask
+ */
+static inline void update_edge_detect(struct pxa_gpio_chip *c)
+{
+	uint32_t grer, gfer;
+
+	grer = __raw_readl(c->regbase + GRER_OFFSET) & ~c->irq_mask;
+	gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~c->irq_mask;
+	grer |= c->irq_edge_rise & c->irq_mask;
+	gfer |= c->irq_edge_fall & c->irq_mask;
+	__raw_writel(grer, c->regbase + GRER_OFFSET);
+	__raw_writel(gfer, c->regbase + GFER_OFFSET);
+}
+
+static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+	struct pxa_gpio_chip *c;
+	int gpio = irq_to_gpio(irq);
+	unsigned long gpdr, mask = GPIO_bit(gpio);
+
+	c = gpio_to_chip(gpio);
+
+	if (type == IRQ_TYPE_PROBE) {
+		/* Don't mess with enabled GPIOs using preconfigured edges or
+		 * GPIOs set to alternate function or to output during probe
+		 */
+		if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
+			return 0;
+
+		if (__gpio_is_occupied(gpio))
+			return 0;
+
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+
+	if (__gpio_is_inverted(gpio))
+		__raw_writel(gpdr | mask,  c->regbase + GPDR_OFFSET);
+	else
+		__raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET);
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		c->irq_edge_rise |= mask;
+	else
+		c->irq_edge_rise &= ~mask;
+
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		c->irq_edge_fall |= mask;
+	else
+		c->irq_edge_fall &= ~mask;
+
+	update_edge_detect(c);
+
+	pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio,
+		((type & IRQ_TYPE_EDGE_RISING)  ? " rising"  : ""),
+		((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
+	return 0;
+}
+
+static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct pxa_gpio_chip *c;
+	int loop, gpio, gpio_base, n;
+	unsigned long gedr;
+
+	do {
+		loop = 0;
+		for_each_gpio_chip(gpio, c) {
+			gpio_base = c->chip.base;
+
+			gedr = __raw_readl(c->regbase + GEDR_OFFSET);
+			gedr = gedr & c->irq_mask;
+			__raw_writel(gedr, c->regbase + GEDR_OFFSET);
+
+			n = find_first_bit(&gedr, BITS_PER_LONG);
+			while (n < BITS_PER_LONG) {
+				loop = 1;
+
+				generic_handle_irq(gpio_to_irq(gpio_base + n));
+				n = find_next_bit(&gedr, BITS_PER_LONG, n + 1);
+			}
+		}
+	} while (loop);
+}
+
+static void pxa_ack_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq_to_gpio(irq);
+	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+
+	__raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
+}
+
+static void pxa_mask_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq_to_gpio(irq);
+	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+	uint32_t grer, gfer;
+
+	c->irq_mask &= ~GPIO_bit(gpio);
+
+	grer = __raw_readl(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
+	gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+	__raw_writel(grer, c->regbase + GRER_OFFSET);
+	__raw_writel(gfer, c->regbase + GFER_OFFSET);
+}
+
+static void pxa_unmask_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq_to_gpio(irq);
+	struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+
+	c->irq_mask |= GPIO_bit(gpio);
+	update_edge_detect(c);
+}
+
+static struct irq_chip pxa_muxed_gpio_chip = {
+	.name		= "GPIO",
+	.ack		= pxa_ack_muxed_gpio,
+	.mask		= pxa_mask_muxed_gpio,
+	.unmask		= pxa_unmask_muxed_gpio,
+	.set_type	= pxa_gpio_irq_type,
+};
+
+void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
+{
+	struct pxa_gpio_chip *c;
+	int gpio, irq;
+
+	pxa_last_gpio = end;
+
+	/* Initialize GPIO chips */
+	pxa_init_gpio_chip(end);
+
+	/* clear all GPIO edge detects */
+	for_each_gpio_chip(gpio, c) {
+		__raw_writel(0, c->regbase + GFER_OFFSET);
+		__raw_writel(0, c->regbase + GRER_OFFSET);
+		__raw_writel(~0,c->regbase + GEDR_OFFSET);
+	}
+
+	for (irq  = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) {
+		set_irq_chip(irq, &pxa_muxed_gpio_chip);
+		set_irq_handler(irq, handle_edge_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	/* Install handler for GPIO>=2 edge detect interrupts */
+	set_irq_chained_handler(mux_irq, pxa_gpio_demux_handler);
+	pxa_muxed_gpio_chip.set_wake = fn;
+}
+
+#ifdef CONFIG_PM
+static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct pxa_gpio_chip *c;
+	int gpio;
+
+	for_each_gpio_chip(gpio, c) {
+		c->saved_gplr = __raw_readl(c->regbase + GPLR_OFFSET);
+		c->saved_gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+		c->saved_grer = __raw_readl(c->regbase + GRER_OFFSET);
+		c->saved_gfer = __raw_readl(c->regbase + GFER_OFFSET);
+
+		/* Clear GPIO transition detect bits */
+		__raw_writel(0xffffffff, c->regbase + GEDR_OFFSET);
+	}
+	return 0;
+}
+
+static int pxa_gpio_resume(struct sys_device *dev)
+{
+	struct pxa_gpio_chip *c;
+	int gpio;
+
+	for_each_gpio_chip(gpio, c) {
+		/* restore level with set/clear */
+		__raw_writel( c->saved_gplr, c->regbase + GPSR_OFFSET);
+		__raw_writel(~c->saved_gplr, c->regbase + GPCR_OFFSET);
+
+		__raw_writel(c->saved_grer, c->regbase + GRER_OFFSET);
+		__raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET);
+		__raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET);
+	}
+	return 0;
+}
+#else
+#define pxa_gpio_suspend	NULL
+#define pxa_gpio_resume		NULL
+#endif
+
+struct sysdev_class pxa_gpio_sysclass = {
+	.name		= "gpio",
+	.suspend	= pxa_gpio_suspend,
+	.resume		= pxa_gpio_resume,
+};
+
+static int __init pxa_gpio_init(void)
+{
+	return sysdev_class_register(&pxa_gpio_sysclass);
+}
+
+core_initcall(pxa_gpio_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/dma.h linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/dma.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,85 @@
+#ifndef __PLAT_DMA_H
+#define __PLAT_DMA_H
+
+#define DMAC_REG(x)	(*((volatile u32 *)(DMAC_REGS_VIRT + (x))))
+
+#define DCSR(n)		DMAC_REG((n) << 2)
+#define DALGN		DMAC_REG(0x00a0)  /* DMA Alignment Register */
+#define DINT		DMAC_REG(0x00f0)  /* DMA Interrupt Register */
+#define DDADR(n)	DMAC_REG(0x0200 + ((n) << 4))
+#define DSADR(n)	DMAC_REG(0x0204 + ((n) << 4))
+#define DTADR(n)	DMAC_REG(0x0208 + ((n) << 4))
+#define DCMD(n)		DMAC_REG(0x020c + ((n) << 4))
+#define DRCMR(n)	DMAC_REG((((n) < 64) ? 0x0100 : 0x1100) + \
+				 (((n) & 0x3f) << 2))
+
+#define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
+#define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
+#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
+#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
+#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
+#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
+#define DCSR_SETCMPST	(1 << 25)       /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST	(1 << 24)       /* Clear Descriptor Compare Status */
+#define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
+#define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
+
+#define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
+#define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
+
+#define DDADR_DESCADDR	0xfffffff0	/* Address of next descriptor (mask) */
+#define DDADR_STOP	(1 << 0)	/* Stop (read / write) */
+
+#define DCMD_INCSRCADDR	(1 << 31)	/* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR	(1 << 30)	/* Target Address Increment Setting. */
+#define DCMD_FLOWSRC	(1 << 29)	/* Flow Control by the source. */
+#define DCMD_FLOWTRG	(1 << 28)	/* Flow Control by the target. */
+#define DCMD_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
+#define DCMD_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
+#define DCMD_ENDIAN	(1 << 18)	/* Device Endian-ness. */
+#define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
+#define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
+#define DCMD_BURST32	(3 << 16)	/* 32 byte burst */
+#define DCMD_WIDTH1	(1 << 14)	/* 1 byte width */
+#define DCMD_WIDTH2	(2 << 14)	/* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4	(3 << 14)	/* 4 byte width (Word) */
+#define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
+
+/*
+ * Descriptor structure for PXA's DMA engine
+ * Note: this structure must always be aligned to a 16-byte boundary.
+ */
+
+typedef struct pxa_dma_desc {
+	volatile u32 ddadr;	/* Points to the next descriptor + flags */
+	volatile u32 dsadr;	/* DSADR value for the current transfer */
+	volatile u32 dtadr;	/* DTADR value for the current transfer */
+	volatile u32 dcmd;	/* DCMD value for the current transfer */
+} pxa_dma_desc;
+
+typedef enum {
+	DMA_PRIO_HIGH = 0,
+	DMA_PRIO_MEDIUM = 1,
+	DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
+/*
+ * DMA registration
+ */
+
+int __init pxa_init_dma(int irq, int num_ch);
+
+int pxa_request_dma (char *name,
+			 pxa_dma_prio prio,
+			 void (*irq_handler)(int, void *),
+			 void *data);
+
+void pxa_free_dma (int dma_ch);
+
+#endif /* __PLAT_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/gpio.h linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+/*
+ * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
+ * one set of registers. The register offsets are organized below:
+ *
+ *           GPLR    GPDR    GPSR    GPCR    GRER    GFER    GEDR
+ * BANK 0 - 0x0000  0x000C  0x0018  0x0024  0x0030  0x003C  0x0048
+ * BANK 1 - 0x0004  0x0010  0x001C  0x0028  0x0034  0x0040  0x004C
+ * BANK 2 - 0x0008  0x0014  0x0020  0x002C  0x0038  0x0044  0x0050
+ *
+ * BANK 3 - 0x0100  0x010C  0x0118  0x0124  0x0130  0x013C  0x0148
+ * BANK 4 - 0x0104  0x0110  0x011C  0x0128  0x0134  0x0140  0x014C
+ * BANK 5 - 0x0108  0x0114  0x0120  0x012C  0x0138  0x0144  0x0150
+ *
+ * NOTE:
+ *   BANK 3 is only available on PXA27x and later processors.
+ *   BANK 4 and 5 are only available on PXA935
+ */
+
+#define GPIO_BANK(n)	(GPIO_REGS_VIRT + BANK_OFF(n))
+
+#define GPLR_OFFSET	0x00
+#define GPDR_OFFSET	0x0C
+#define GPSR_OFFSET	0x18
+#define GPCR_OFFSET	0x24
+#define GRER_OFFSET	0x30
+#define GFER_OFFSET	0x3C
+#define GEDR_OFFSET	0x48
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
+		return GPLR(gpio) & GPIO_bit(gpio);
+	else
+		return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
+		if (value)
+			GPSR(gpio) = GPIO_bit(gpio);
+		else
+			GPCR(gpio) = GPIO_bit(gpio);
+	} else
+		__gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep		__gpio_cansleep
+
+/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
+ * Those cases currently cause holes in the GPIO number space, the
+ * actual number of the last GPIO is recorded by 'pxa_last_gpio'.
+ */
+extern int pxa_last_gpio;
+
+typedef int (*set_wake_t)(unsigned int irq, unsigned int on);
+
+extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
+#endif /* __PLAT_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/mfp.h linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/mfp.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/include/plat/mfp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/include/plat/mfp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,399 @@
+/*
+ * arch/arm/plat-pxa/include/plat/mfp.h
+ *
+ *   Common Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ *            initial version
+ *
+ *  This program is free software; you can 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_PLAT_MFP_H
+#define __ASM_PLAT_MFP_H
+
+#define mfp_to_gpio(m)	((m) % 128)
+
+/* list of all the configurable MFP pins */
+enum {
+	MFP_PIN_INVALID = -1,
+
+	MFP_PIN_GPIO0 = 0,
+	MFP_PIN_GPIO1,
+	MFP_PIN_GPIO2,
+	MFP_PIN_GPIO3,
+	MFP_PIN_GPIO4,
+	MFP_PIN_GPIO5,
+	MFP_PIN_GPIO6,
+	MFP_PIN_GPIO7,
+	MFP_PIN_GPIO8,
+	MFP_PIN_GPIO9,
+	MFP_PIN_GPIO10,
+	MFP_PIN_GPIO11,
+	MFP_PIN_GPIO12,
+	MFP_PIN_GPIO13,
+	MFP_PIN_GPIO14,
+	MFP_PIN_GPIO15,
+	MFP_PIN_GPIO16,
+	MFP_PIN_GPIO17,
+	MFP_PIN_GPIO18,
+	MFP_PIN_GPIO19,
+	MFP_PIN_GPIO20,
+	MFP_PIN_GPIO21,
+	MFP_PIN_GPIO22,
+	MFP_PIN_GPIO23,
+	MFP_PIN_GPIO24,
+	MFP_PIN_GPIO25,
+	MFP_PIN_GPIO26,
+	MFP_PIN_GPIO27,
+	MFP_PIN_GPIO28,
+	MFP_PIN_GPIO29,
+	MFP_PIN_GPIO30,
+	MFP_PIN_GPIO31,
+	MFP_PIN_GPIO32,
+	MFP_PIN_GPIO33,
+	MFP_PIN_GPIO34,
+	MFP_PIN_GPIO35,
+	MFP_PIN_GPIO36,
+	MFP_PIN_GPIO37,
+	MFP_PIN_GPIO38,
+	MFP_PIN_GPIO39,
+	MFP_PIN_GPIO40,
+	MFP_PIN_GPIO41,
+	MFP_PIN_GPIO42,
+	MFP_PIN_GPIO43,
+	MFP_PIN_GPIO44,
+	MFP_PIN_GPIO45,
+	MFP_PIN_GPIO46,
+	MFP_PIN_GPIO47,
+	MFP_PIN_GPIO48,
+	MFP_PIN_GPIO49,
+	MFP_PIN_GPIO50,
+	MFP_PIN_GPIO51,
+	MFP_PIN_GPIO52,
+	MFP_PIN_GPIO53,
+	MFP_PIN_GPIO54,
+	MFP_PIN_GPIO55,
+	MFP_PIN_GPIO56,
+	MFP_PIN_GPIO57,
+	MFP_PIN_GPIO58,
+	MFP_PIN_GPIO59,
+	MFP_PIN_GPIO60,
+	MFP_PIN_GPIO61,
+	MFP_PIN_GPIO62,
+	MFP_PIN_GPIO63,
+	MFP_PIN_GPIO64,
+	MFP_PIN_GPIO65,
+	MFP_PIN_GPIO66,
+	MFP_PIN_GPIO67,
+	MFP_PIN_GPIO68,
+	MFP_PIN_GPIO69,
+	MFP_PIN_GPIO70,
+	MFP_PIN_GPIO71,
+	MFP_PIN_GPIO72,
+	MFP_PIN_GPIO73,
+	MFP_PIN_GPIO74,
+	MFP_PIN_GPIO75,
+	MFP_PIN_GPIO76,
+	MFP_PIN_GPIO77,
+	MFP_PIN_GPIO78,
+	MFP_PIN_GPIO79,
+	MFP_PIN_GPIO80,
+	MFP_PIN_GPIO81,
+	MFP_PIN_GPIO82,
+	MFP_PIN_GPIO83,
+	MFP_PIN_GPIO84,
+	MFP_PIN_GPIO85,
+	MFP_PIN_GPIO86,
+	MFP_PIN_GPIO87,
+	MFP_PIN_GPIO88,
+	MFP_PIN_GPIO89,
+	MFP_PIN_GPIO90,
+	MFP_PIN_GPIO91,
+	MFP_PIN_GPIO92,
+	MFP_PIN_GPIO93,
+	MFP_PIN_GPIO94,
+	MFP_PIN_GPIO95,
+	MFP_PIN_GPIO96,
+	MFP_PIN_GPIO97,
+	MFP_PIN_GPIO98,
+	MFP_PIN_GPIO99,
+	MFP_PIN_GPIO100,
+	MFP_PIN_GPIO101,
+	MFP_PIN_GPIO102,
+	MFP_PIN_GPIO103,
+	MFP_PIN_GPIO104,
+	MFP_PIN_GPIO105,
+	MFP_PIN_GPIO106,
+	MFP_PIN_GPIO107,
+	MFP_PIN_GPIO108,
+	MFP_PIN_GPIO109,
+	MFP_PIN_GPIO110,
+	MFP_PIN_GPIO111,
+	MFP_PIN_GPIO112,
+	MFP_PIN_GPIO113,
+	MFP_PIN_GPIO114,
+	MFP_PIN_GPIO115,
+	MFP_PIN_GPIO116,
+	MFP_PIN_GPIO117,
+	MFP_PIN_GPIO118,
+	MFP_PIN_GPIO119,
+	MFP_PIN_GPIO120,
+	MFP_PIN_GPIO121,
+	MFP_PIN_GPIO122,
+	MFP_PIN_GPIO123,
+	MFP_PIN_GPIO124,
+	MFP_PIN_GPIO125,
+	MFP_PIN_GPIO126,
+	MFP_PIN_GPIO127,
+	MFP_PIN_GPIO0_2,
+	MFP_PIN_GPIO1_2,
+	MFP_PIN_GPIO2_2,
+	MFP_PIN_GPIO3_2,
+	MFP_PIN_GPIO4_2,
+	MFP_PIN_GPIO5_2,
+	MFP_PIN_GPIO6_2,
+	MFP_PIN_GPIO7_2,
+	MFP_PIN_GPIO8_2,
+	MFP_PIN_GPIO9_2,
+	MFP_PIN_GPIO10_2,
+	MFP_PIN_GPIO11_2,
+	MFP_PIN_GPIO12_2,
+	MFP_PIN_GPIO13_2,
+	MFP_PIN_GPIO14_2,
+	MFP_PIN_GPIO15_2,
+	MFP_PIN_GPIO16_2,
+	MFP_PIN_GPIO17_2,
+
+	MFP_PIN_ULPI_STP,
+	MFP_PIN_ULPI_NXT,
+	MFP_PIN_ULPI_DIR,
+
+	MFP_PIN_nXCVREN,
+	MFP_PIN_DF_CLE_nOE,
+	MFP_PIN_DF_nADV1_ALE,
+	MFP_PIN_DF_SCLK_E,
+	MFP_PIN_DF_SCLK_S,
+	MFP_PIN_nBE0,
+	MFP_PIN_nBE1,
+	MFP_PIN_DF_nADV2_ALE,
+	MFP_PIN_DF_INT_RnB,
+	MFP_PIN_DF_nCS0,
+	MFP_PIN_DF_nCS1,
+	MFP_PIN_nLUA,
+	MFP_PIN_nLLA,
+	MFP_PIN_DF_nWE,
+	MFP_PIN_DF_ALE_nWE,
+	MFP_PIN_DF_nRE_nOE,
+	MFP_PIN_DF_ADDR0,
+	MFP_PIN_DF_ADDR1,
+	MFP_PIN_DF_ADDR2,
+	MFP_PIN_DF_ADDR3,
+	MFP_PIN_DF_IO0,
+	MFP_PIN_DF_IO1,
+	MFP_PIN_DF_IO2,
+	MFP_PIN_DF_IO3,
+	MFP_PIN_DF_IO4,
+	MFP_PIN_DF_IO5,
+	MFP_PIN_DF_IO6,
+	MFP_PIN_DF_IO7,
+	MFP_PIN_DF_IO8,
+	MFP_PIN_DF_IO9,
+	MFP_PIN_DF_IO10,
+	MFP_PIN_DF_IO11,
+	MFP_PIN_DF_IO12,
+	MFP_PIN_DF_IO13,
+	MFP_PIN_DF_IO14,
+	MFP_PIN_DF_IO15,
+	MFP_PIN_DF_nCS0_SM_nCS2,
+	MFP_PIN_DF_nCS1_SM_nCS3,
+	MFP_PIN_SM_nCS0,
+	MFP_PIN_SM_nCS1,
+	MFP_PIN_DF_WEn,
+	MFP_PIN_DF_REn,
+	MFP_PIN_DF_CLE_SM_OEn,
+	MFP_PIN_DF_ALE_SM_WEn,
+	MFP_PIN_DF_RDY0,
+	MFP_PIN_DF_RDY1,
+
+	MFP_PIN_SM_SCLK,
+	MFP_PIN_SM_BE0,
+	MFP_PIN_SM_BE1,
+	MFP_PIN_SM_ADV,
+	MFP_PIN_SM_ADVMUX,
+	MFP_PIN_SM_RDY,
+
+	MFP_PIN_MMC1_DAT7,
+	MFP_PIN_MMC1_DAT6,
+	MFP_PIN_MMC1_DAT5,
+	MFP_PIN_MMC1_DAT4,
+	MFP_PIN_MMC1_DAT3,
+	MFP_PIN_MMC1_DAT2,
+	MFP_PIN_MMC1_DAT1,
+	MFP_PIN_MMC1_DAT0,
+	MFP_PIN_MMC1_CMD,
+	MFP_PIN_MMC1_CLK,
+	MFP_PIN_MMC1_CD,
+	MFP_PIN_MMC1_WP,
+
+	/* additional pins on PXA930 */
+	MFP_PIN_GSIM_UIO,
+	MFP_PIN_GSIM_UCLK,
+	MFP_PIN_GSIM_UDET,
+	MFP_PIN_GSIM_nURST,
+	MFP_PIN_PMIC_INT,
+	MFP_PIN_RDY,
+
+	MFP_PIN_MAX,
+};
+
+/*
+ * a possible MFP configuration is represented by a 32-bit integer
+ *
+ * bit  0.. 9 - MFP Pin Number (1024 Pins Maximum)
+ * bit 10..12 - Alternate Function Selection
+ * bit 13..15 - Drive Strength
+ * bit 16..18 - Low Power Mode State
+ * bit 19..20 - Low Power Mode Edge Detection
+ * bit 21..22 - Run Mode Pull State
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * MFP_CFG_DEFAULT - default MFP configuration value, with
+ * 		  alternate function = 0,
+ * 		  drive strength = fast 3mA (MFP_DS03X)
+ * 		  low power mode = default
+ * 		  edge detection = none
+ *
+ * MFP_CFG	- default MFPR value with alternate function
+ * MFP_CFG_DRV	- default MFPR value with alternate function and
+ * 		  pin drive strength
+ * MFP_CFG_LPM	- default MFPR value with alternate function and
+ * 		  low power mode
+ * MFP_CFG_X	- default MFPR value with alternate function,
+ * 		  pin drive strength and low power mode
+ */
+
+typedef unsigned long mfp_cfg_t;
+
+#define MFP_PIN(x)		((x) & 0x3ff)
+
+#define MFP_AF0			(0x0 << 10)
+#define MFP_AF1			(0x1 << 10)
+#define MFP_AF2			(0x2 << 10)
+#define MFP_AF3			(0x3 << 10)
+#define MFP_AF4			(0x4 << 10)
+#define MFP_AF5			(0x5 << 10)
+#define MFP_AF6			(0x6 << 10)
+#define MFP_AF7			(0x7 << 10)
+#define MFP_AF_MASK		(0x7 << 10)
+#define MFP_AF(x)		(((x) >> 10) & 0x7)
+
+#define MFP_DS01X		(0x0 << 13)
+#define MFP_DS02X		(0x1 << 13)
+#define MFP_DS03X		(0x2 << 13)
+#define MFP_DS04X		(0x3 << 13)
+#define MFP_DS06X		(0x4 << 13)
+#define MFP_DS08X		(0x5 << 13)
+#define MFP_DS10X		(0x6 << 13)
+#define MFP_DS13X		(0x7 << 13)
+#define MFP_DS_MASK		(0x7 << 13)
+#define MFP_DS(x)		(((x) >> 13) & 0x7)
+
+#define MFP_LPM_DEFAULT		(0x0 << 16)
+#define MFP_LPM_DRIVE_LOW	(0x1 << 16)
+#define MFP_LPM_DRIVE_HIGH	(0x2 << 16)
+#define MFP_LPM_PULL_LOW	(0x3 << 16)
+#define MFP_LPM_PULL_HIGH	(0x4 << 16)
+#define MFP_LPM_FLOAT		(0x5 << 16)
+#define MFP_LPM_INPUT		(0x6 << 16)
+#define MFP_LPM_STATE_MASK	(0x7 << 16)
+#define MFP_LPM_STATE(x)	(((x) >> 16) & 0x7)
+
+#define MFP_LPM_EDGE_NONE	(0x0 << 19)
+#define MFP_LPM_EDGE_RISE	(0x1 << 19)
+#define MFP_LPM_EDGE_FALL	(0x2 << 19)
+#define MFP_LPM_EDGE_BOTH	(0x3 << 19)
+#define MFP_LPM_EDGE_MASK	(0x3 << 19)
+#define MFP_LPM_EDGE(x)		(((x) >> 19) & 0x3)
+
+#define MFP_PULL_NONE		(0x0 << 21)
+#define MFP_PULL_LOW		(0x1 << 21)
+#define MFP_PULL_HIGH		(0x2 << 21)
+#define MFP_PULL_BOTH		(0x3 << 21)
+#define MFP_PULL_MASK		(0x3 << 21)
+#define MFP_PULL(x)		(((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT		(MFP_AF0 | MFP_DS03X | MFP_LPM_DEFAULT |\
+				 MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
+
+#define MFP_CFG(pin, af)		\
+	((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_DRV(pin, af, drv)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
+
+#define MFP_CFG_LPM(pin, af, lpm)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
+
+#define MFP_CFG_X(pin, af, drv, lpm)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by mfp_init()
+ *
+ * mfp_init_base() - accepts a virtual base for all MFPR registers and
+ * initialize the MFP table to a default state
+ *
+ * mfp_init_addr() - accepts a table of "mfp_addr_map" structure, which
+ * represents a range of MFP pins from "start" to "end", with the offset
+ * begining at "offset", to define a single pin, let "end" = -1.
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR()   to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct mfp_addr_map {
+	unsigned int	start;
+	unsigned int	end;
+	unsigned long	offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+	{ MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+	{ MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END	{ MFP_PIN_INVALID, 0 }
+
+void __init mfp_init_base(unsigned long mfpr_base);
+void __init mfp_init_addr(struct mfp_addr_map *map);
+
+/*
+ * mfp_{read, write}()	- for direct read/write access to the MFPR register
+ * mfp_config()		- for configuring a group of MFPR registers
+ * mfp_config_lpm()	- configuring all low power MFPR registers for suspend
+ * mfp_config_run()	- configuring all run time  MFPR registers after resume
+ */
+unsigned long mfp_read(int mfp);
+void mfp_write(int mfp, unsigned long mfpr_val);
+void mfp_config(unsigned long *mfp_cfgs, int num);
+void mfp_config_run(void);
+void mfp_config_lpm(void);
+#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
+
+#endif /* __ASM_PLAT_MFP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/Kconfig linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/Kconfig
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+if PLAT_PXA
+
+endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/Makefile linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+#
+# Makefile for code common across different PXA processor families
+#
+
+obj-y	:= dma.o
+
+obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
+obj-$(CONFIG_PXA3xx)		+= mfp.o
+obj-$(CONFIG_ARCH_MMP)		+= mfp.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/mfp.c linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/mfp.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-pxa/mfp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-pxa/mfp.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,278 @@
+/*
+ * linux/arch/arm/plat-pxa/mfp.c
+ *
+ *   Multi-Function Pin Support
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ *             initial version
+ *
+ *  This program is free software; you can 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/init.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <plat/mfp.h>
+
+#define MFPR_SIZE	(PAGE_SIZE)
+
+/* MFPR register bit definitions */
+#define MFPR_PULL_SEL		(0x1 << 15)
+#define MFPR_PULLUP_EN		(0x1 << 14)
+#define MFPR_PULLDOWN_EN	(0x1 << 13)
+#define MFPR_SLEEP_SEL		(0x1 << 9)
+#define MFPR_SLEEP_OE_N		(0x1 << 7)
+#define MFPR_EDGE_CLEAR		(0x1 << 6)
+#define MFPR_EDGE_FALL_EN	(0x1 << 5)
+#define MFPR_EDGE_RISE_EN	(0x1 << 4)
+
+#define MFPR_SLEEP_DATA(x)	((x) << 8)
+#define MFPR_DRIVE(x)		(((x) & 0x7) << 10)
+#define MFPR_AF_SEL(x)		(((x) & 0x7) << 0)
+
+#define MFPR_EDGE_NONE		(0)
+#define MFPR_EDGE_RISE		(MFPR_EDGE_RISE_EN)
+#define MFPR_EDGE_FALL		(MFPR_EDGE_FALL_EN)
+#define MFPR_EDGE_BOTH		(MFPR_EDGE_RISE | MFPR_EDGE_FALL)
+
+/*
+ * Table that determines the low power modes outputs, with actual settings
+ * used in parentheses for don't-care values. Except for the float output,
+ * the configured driven and pulled levels match, so if there is a need for
+ * non-LPM pulled output, the same configuration could probably be used.
+ *
+ * Output value  sleep_oe_n  sleep_data  pullup_en  pulldown_en  pull_sel
+ *                 (bit 7)    (bit 8)    (bit 14)     (bit 13)   (bit 15)
+ *
+ * Input            0          X(0)        X(0)        X(0)       0
+ * Drive 0          0          0           0           X(1)       0
+ * Drive 1          0          1           X(1)        0	  0
+ * Pull hi (1)      1          X(1)        1           0	  0
+ * Pull lo (0)      1          X(0)        0           1	  0
+ * Z (float)        1          X(0)        0           0	  0
+ */
+#define MFPR_LPM_INPUT		(0)
+#define MFPR_LPM_DRIVE_LOW	(MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
+#define MFPR_LPM_DRIVE_HIGH    	(MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
+#define MFPR_LPM_PULL_LOW      	(MFPR_LPM_DRIVE_LOW  | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_PULL_HIGH     	(MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_FLOAT         	(MFPR_SLEEP_OE_N)
+#define MFPR_LPM_MASK		(0xe080)
+
+/*
+ * The pullup and pulldown state of the MFP pin at run mode is by default
+ * determined by the selected alternate function. In case that some buggy
+ * devices need to override this default behavior,  the definitions below
+ * indicates the setting of corresponding MFPR bits
+ *
+ * Definition       pull_sel  pullup_en  pulldown_en
+ * MFPR_PULL_NONE       0         0        0
+ * MFPR_PULL_LOW        1         0        1
+ * MFPR_PULL_HIGH       1         1        0
+ * MFPR_PULL_BOTH       1         1        1
+ */
+#define MFPR_PULL_NONE		(0)
+#define MFPR_PULL_LOW		(MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
+#define MFPR_PULL_BOTH		(MFPR_PULL_LOW | MFPR_PULLUP_EN)
+#define MFPR_PULL_HIGH		(MFPR_PULL_SEL | MFPR_PULLUP_EN)
+
+/* mfp_spin_lock is used to ensure that MFP register configuration
+ * (most likely a read-modify-write operation) is atomic, and that
+ * mfp_table[] is consistent
+ */
+static DEFINE_SPINLOCK(mfp_spin_lock);
+
+static void __iomem *mfpr_mmio_base;
+
+struct mfp_pin {
+	unsigned long	config;		/* -1 for not configured */
+	unsigned long	mfpr_off;	/* MFPRxx Register offset */
+	unsigned long	mfpr_run;	/* Run-Mode Register Value */
+	unsigned long	mfpr_lpm;	/* Low Power Mode Register Value */
+};
+
+static struct mfp_pin mfp_table[MFP_PIN_MAX];
+
+/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
+static const unsigned long mfpr_lpm[] = {
+	MFPR_LPM_INPUT,
+	MFPR_LPM_DRIVE_LOW,
+	MFPR_LPM_DRIVE_HIGH,
+	MFPR_LPM_PULL_LOW,
+	MFPR_LPM_PULL_HIGH,
+	MFPR_LPM_FLOAT,
+};
+
+/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
+static const unsigned long mfpr_pull[] = {
+	MFPR_PULL_NONE,
+	MFPR_PULL_LOW,
+	MFPR_PULL_HIGH,
+	MFPR_PULL_BOTH,
+};
+
+/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
+static const unsigned long mfpr_edge[] = {
+	MFPR_EDGE_NONE,
+	MFPR_EDGE_RISE,
+	MFPR_EDGE_FALL,
+	MFPR_EDGE_BOTH,
+};
+
+#define mfpr_readl(off)			\
+	__raw_readl(mfpr_mmio_base + (off))
+
+#define mfpr_writel(off, val)		\
+	__raw_writel(val, mfpr_mmio_base + (off))
+
+#define mfp_configured(p)	((p)->config != -1)
+
+/*
+ * perform a read-back of any MFPR register to make sure the
+ * previous writings are finished
+ */
+#define mfpr_sync()	(void)__raw_readl(mfpr_mmio_base + 0)
+
+static inline void __mfp_config_run(struct mfp_pin *p)
+{
+	if (mfp_configured(p))
+		mfpr_writel(p->mfpr_off, p->mfpr_run);
+}
+
+static inline void __mfp_config_lpm(struct mfp_pin *p)
+{
+	if (mfp_configured(p)) {
+		unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
+		if (mfpr_clr != p->mfpr_run)
+			mfpr_writel(p->mfpr_off, mfpr_clr);
+		if (p->mfpr_lpm != mfpr_clr)
+			mfpr_writel(p->mfpr_off, p->mfpr_lpm);
+	}
+}
+
+void mfp_config(unsigned long *mfp_cfgs, int num)
+{
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&mfp_spin_lock, flags);
+
+	for (i = 0; i < num; i++, mfp_cfgs++) {
+		unsigned long tmp, c = *mfp_cfgs;
+		struct mfp_pin *p;
+		int pin, af, drv, lpm, edge, pull;
+
+		pin = MFP_PIN(c);
+		BUG_ON(pin >= MFP_PIN_MAX);
+		p = &mfp_table[pin];
+
+		af  = MFP_AF(c);
+		drv = MFP_DS(c);
+		lpm = MFP_LPM_STATE(c);
+		edge = MFP_LPM_EDGE(c);
+		pull = MFP_PULL(c);
+
+		/* run-mode pull settings will conflict with MFPR bits of
+		 * low power mode state,  calculate mfpr_run and mfpr_lpm
+		 * individually if pull != MFP_PULL_NONE
+		 */
+		tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
+
+		if (likely(pull == MFP_PULL_NONE)) {
+			p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+			p->mfpr_lpm = p->mfpr_run;
+		} else {
+			p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+			p->mfpr_run = tmp | mfpr_pull[pull];
+		}
+
+		p->config = c; __mfp_config_run(p);
+	}
+
+	mfpr_sync();
+	spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+unsigned long mfp_read(int mfp)
+{
+	unsigned long val, flags;
+
+	BUG_ON(mfp >= MFP_PIN_MAX);
+
+	spin_lock_irqsave(&mfp_spin_lock, flags);
+	val = mfpr_readl(mfp_table[mfp].mfpr_off);
+	spin_unlock_irqrestore(&mfp_spin_lock, flags);
+
+	return val;
+}
+
+void mfp_write(int mfp, unsigned long val)
+{
+	unsigned long flags;
+
+	BUG_ON(mfp >= MFP_PIN_MAX);
+
+	spin_lock_irqsave(&mfp_spin_lock, flags);
+	mfpr_writel(mfp_table[mfp].mfpr_off, val);
+	mfpr_sync();
+	spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void __init mfp_init_base(unsigned long mfpr_base)
+{
+	int i;
+
+	/* initialize the table with default - unconfigured */
+	for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
+		mfp_table[i].config = -1;
+
+	mfpr_mmio_base = (void __iomem *)mfpr_base;
+}
+
+void __init mfp_init_addr(struct mfp_addr_map *map)
+{
+	struct mfp_addr_map *p;
+	unsigned long offset, flags;
+	int i;
+
+	spin_lock_irqsave(&mfp_spin_lock, flags);
+
+	for (p = map; p->start != MFP_PIN_INVALID; p++) {
+		offset = p->offset;
+		i = p->start;
+
+		do {
+			mfp_table[i].mfpr_off = offset;
+			mfp_table[i].mfpr_run = 0;
+			mfp_table[i].mfpr_lpm = 0;
+			offset += 4; i++;
+		} while ((i <= p->end) && (p->end != -1));
+	}
+
+	spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void mfp_config_lpm(void)
+{
+	struct mfp_pin *p = &mfp_table[0];
+	int pin;
+
+	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+		__mfp_config_lpm(p);
+}
+
+void mfp_config_run(void)
+{
+	struct mfp_pin *p = &mfp_table[0];
+	int pin;
+
+	for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+		__mfp_config_run(p);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/clock.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/clock.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -306,8 +306,6 @@ struct clk s3c24xx_uclk = {
 
 int s3c24xx_register_clock(struct clk *clk)
 {
-	clk->owner = THIS_MODULE;
-
 	if (clk->enable == NULL)
 		clk->enable = clk_null_enable;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/dev-i2c0.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/dev-i2c0.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/dev-i2c0.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/dev-i2c0.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c/dev-i2c0.c
  *
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008,2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
@@ -50,9 +50,8 @@ struct platform_device s3c_device_i2c0 =
 static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
 	.flags		= 0,
 	.slave_addr	= 0x10,
-	.bus_freq	= 100*1000,
-	.max_freq	= 400*1000,
-	.sda_delay	= S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
 };
 
 void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/dev-i2c1.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/dev-i2c1.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/dev-i2c1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/dev-i2c1.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c/dev-i2c1.c
  *
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008,2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *	http://armlinux.simtec.co.uk/
  *
@@ -47,9 +47,8 @@ static struct s3c2410_platform_i2c defau
 	.flags		= 0,
 	.bus_num	= 1,
 	.slave_addr	= 0x10,
-	.bus_freq	= 100*1000,
-	.max_freq	= 400*1000,
-	.sda_delay	= S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
 };
 
 void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/gpio-config.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/gpio-config.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/gpio-config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/gpio-config.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 
@@ -38,6 +39,7 @@ int s3c_gpio_cfgpin(unsigned int pin, un
 
 	return ret;
 }
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
 
 int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 {
@@ -56,6 +58,7 @@ int s3c_gpio_setpull(unsigned int pin, s
 
 	return ret;
 }
+EXPORT_SYMBOL(s3c_gpio_setpull);
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
 int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/audio.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/audio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/audio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/audio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/* 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>
+ *
+ * S3C24XX - Audio platfrom_device info
+ *
+ * This program is free software; you can 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);
+};
+
+#endif /* __ASM_ARCH_AUDIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/devs.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/devs.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/devs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/devs.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,7 @@ extern struct platform_device s3c_device
 extern struct platform_device s3c_device_rtc;
 extern struct platform_device s3c_device_adc;
 extern struct platform_device s3c_device_sdi;
+extern struct platform_device s3c_device_hwmon;
 extern struct platform_device s3c_device_hsmmc0;
 extern struct platform_device s3c_device_hsmmc1;
 extern struct platform_device s3c_device_hsmmc2;
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/iic.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/iic.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/iic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/iic.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
-/* arch/arm/mach-s3c2410/include/mach/iic.h
+/* arch/arm/plat-s3c/include/plat/iic.h
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright 2004,2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 - I2C Controller platfrom_device info
+ * S3C - I2C Controller platform_device info
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -15,19 +15,24 @@
 
 #define S3C_IICFLG_FILTER	(1<<0)	/* enable s3c2440 filter */
 
-/* Notes:
- *	1) All frequencies are expressed in Hz
- *	2) A value of zero is `do not care`
-*/
-
+/**
+ *	struct s3c2410_platform_i2c - Platform data for s3c I2C.
+ *	@bus_num: The bus number to use (if possible).
+ *	@flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER).
+ *	@slave_addr: The I2C address for the slave device (if enabled).
+ *	@frequency: The desired frequency in Hz of the bus.  This is
+ *                  guaranteed to not be exceeded.  If the caller does
+ *                  not care, use zero and the driver will select a
+ *                  useful default.
+ *	@sda_delay: The delay (in ns) applied to SDA edges.
+ *	@cfg_gpio: A callback to configure the pins for I2C operation.
+ */
 struct s3c2410_platform_i2c {
-	int		bus_num;	/* bus number to use */
+	int		bus_num;
 	unsigned int	flags;
-	unsigned int	slave_addr;	/* slave address for controller */
-	unsigned long	bus_freq;	/* standard bus frequency */
-	unsigned long	max_freq;	/* max frequency for the bus */
-	unsigned long	min_freq;	/* min frequency for the bus */
-	unsigned int	sda_delay;	/* pclks (s3c2440 only) */
+	unsigned int	slave_addr;
+	unsigned long	frequency;
+	unsigned int	sda_delay;
 
 	void	(*cfg_gpio)(struct platform_device *dev);
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/pm.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/pm.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/pm.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,174 @@
+/* linux/include/asm-arm/plat-s3c24xx/pm.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* s3c_pm_init
+ *
+ * called from board at initialisation time to setup the power
+ * management
+*/
+
+#ifdef CONFIG_PM
+
+extern __init int s3c_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+	return 0;
+}
+#endif
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+/* from sleep.S */
+
+extern int  s3c_cpu_save(unsigned long *saveblk);
+extern void s3c_cpu_resume(void);
+
+extern void s3c2410_cpu_suspend(void);
+
+extern unsigned long s3c_sleep_save_phys;
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+	void __iomem	*reg;
+	unsigned long	val;
+};
+
+#define SAVE_ITEM(x) \
+	{ .reg = (x) }
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+	u32	ulcon;
+	u32	ucon;
+	u32	ufcon;
+	u32	umcon;
+	u32	ubrdiv;
+};
+
+/* helper functions to save/restore lists of registers. */
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c_irqext_wake(unsigned int irqno, unsigned int state);
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c_irqext_wake NULL
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
+
+/* PM debug functions */
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+extern void s3c_pm_dbg(const char *msg, ...);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+#else
+#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#endif
+
+/* suspend memory checking */
+
+#ifdef CONFIG_S3C2410_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+extern void s3c_pm_check_restore(void);
+extern void s3c_pm_check_cleanup(void);
+extern void s3c_pm_check_store(void);
+#else
+#define s3c_pm_check_prepare() do { } while(0)
+#define s3c_pm_check_restore() do { } while(0)
+#define s3c_pm_check_cleanup() do { } while(0)
+#define s3c_pm_check_store()   do { } while(0)
+#endif
+
+/**
+ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
+ *
+ * Setup all the necessary GPIO pins for waking the system on external
+ * interrupt.
+ */
+extern void s3c_pm_configure_extint(void);
+
+/**
+ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ *
+ * Restore the state of the GPIO pins after sleep, which may involve ensuring
+ * that we do not glitch the state of the pins from that the bootloader's
+ * resume code has done.
+*/
+extern void s3c_pm_restore_gpios(void);
+
+/**
+ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ */
+extern void s3c_pm_save_gpios(void);
+
+/**
+ * s3c_pm_cb_flushcache - callback for assembly code
+ *
+ * Callback to issue flush_cache_all() as this call is
+ * not a directly callable object.
+ */
+extern void s3c_pm_cb_flushcache(void);
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,75 @@
+/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
+ *
+ * Copyright 2007 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
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H
+#define __ASM_ARCH_REGS_S3C2412_IIS_H
+
+#define S3C2412_IISCON			(0x00)
+#define S3C2412_IISMOD			(0x04)
+#define S3C2412_IISFIC			(0x08)
+#define S3C2412_IISPSR			(0x0C)
+#define S3C2412_IISTXD			(0x10)
+#define S3C2412_IISRXD			(0x14)
+
+#define S3C2412_IISCON_LRINDEX		(1 << 11)
+#define S3C2412_IISCON_TXFIFO_EMPTY	(1 << 10)
+#define S3C2412_IISCON_RXFIFO_EMPTY	(1 << 9)
+#define S3C2412_IISCON_TXFIFO_FULL	(1 << 8)
+#define S3C2412_IISCON_RXFIFO_FULL	(1 << 7)
+#define S3C2412_IISCON_TXDMA_PAUSE	(1 << 6)
+#define S3C2412_IISCON_RXDMA_PAUSE	(1 << 5)
+#define S3C2412_IISCON_TXCH_PAUSE	(1 << 4)
+#define S3C2412_IISCON_RXCH_PAUSE	(1 << 3)
+#define S3C2412_IISCON_TXDMA_ACTIVE	(1 << 2)
+#define S3C2412_IISCON_RXDMA_ACTIVE	(1 << 1)
+#define S3C2412_IISCON_IIS_ACTIVE	(1 << 0)
+
+#define S3C64XX_IISMOD_IMS_PCLK		(0 << 10)
+#define S3C64XX_IISMOD_IMS_SYSMUX	(1 << 10)
+
+#define S3C2412_IISMOD_MASTER_INTERNAL	(0 << 10)
+#define S3C2412_IISMOD_MASTER_EXTERNAL	(1 << 10)
+#define S3C2412_IISMOD_SLAVE		(2 << 10)
+#define S3C2412_IISMOD_MASTER_MASK	(3 << 10)
+#define S3C2412_IISMOD_MODE_TXONLY	(0 << 8)
+#define S3C2412_IISMOD_MODE_RXONLY	(1 << 8)
+#define S3C2412_IISMOD_MODE_TXRX	(2 << 8)
+#define S3C2412_IISMOD_MODE_MASK	(3 << 8)
+#define S3C2412_IISMOD_LR_LLOW		(0 << 7)
+#define S3C2412_IISMOD_LR_RLOW		(1 << 7)
+#define S3C2412_IISMOD_SDF_IIS		(0 << 5)
+#define S3C2412_IISMOD_SDF_MSB		(1 << 5)
+#define S3C2412_IISMOD_SDF_LSB		(2 << 5)
+#define S3C2412_IISMOD_SDF_MASK		(3 << 5)
+#define S3C2412_IISMOD_RCLK_256FS	(0 << 3)
+#define S3C2412_IISMOD_RCLK_512FS	(1 << 3)
+#define S3C2412_IISMOD_RCLK_384FS	(2 << 3)
+#define S3C2412_IISMOD_RCLK_768FS	(3 << 3)
+#define S3C2412_IISMOD_RCLK_MASK 	(3 << 3)
+#define S3C2412_IISMOD_BCLK_32FS	(0 << 1)
+#define S3C2412_IISMOD_BCLK_48FS	(1 << 1)
+#define S3C2412_IISMOD_BCLK_16FS	(2 << 1)
+#define S3C2412_IISMOD_BCLK_24FS	(3 << 1)
+#define S3C2412_IISMOD_BCLK_MASK	(3 << 1)
+#define S3C2412_IISMOD_8BIT		(1 << 0)
+
+#define S3C2412_IISPSR_PSREN		(1 << 15)
+
+#define S3C2412_IISFIC_TXFLUSH		(1 << 15)
+#define S3C2412_IISFIC_RXFLUSH		(1 << 7)
+#define S3C2412_IISFIC_TXCOUNT(x)	(((x) >>  8) & 0xf)
+#define S3C2412_IISFIC_RXCOUNT(x)	(((x) >>  0) & 0xf)
+
+
+
+#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/uncompress.h	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,10 @@ static inline void flush(void)
 {
 }
 
-#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
+#define __raw_writel(d, ad)			\
+	do {							\
+		*((volatile unsigned int __force *)(ad)) = (d); \
+	} while (0)
 
 /* CONFIG_S3C_BOOT_WATCHDOG
  *
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/include/plat/usb-control.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/* arch/arm/plat-s3c/include/plat/usb-control.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB host port information
+ *
+ * This program is free software; you can 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_USBCONTROL_H
+#define __ASM_ARCH_USBCONTROL_H
+
+#define S3C_HCDFLG_USED	(1)
+
+struct s3c2410_hcd_port {
+	unsigned char	flags;
+	unsigned char	power;
+	unsigned char	oc_status;
+	unsigned char	oc_changed;
+};
+
+struct s3c2410_hcd_info {
+	struct usb_hcd		*hcd;
+	struct s3c2410_hcd_port	port[2];
+
+	void		(*power_control)(int port, int to);
+	void		(*enable_oc)(struct s3c2410_hcd_info *, int on);
+	void		(*report_oc)(struct s3c2410_hcd_info *, int ports);
+};
+
+static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
+{
+	if (info->report_oc != NULL) {
+		(info->report_oc)(info, ports);
+	}
+}
+
+#endif /*__ASM_ARCH_USBCONTROL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/Makefile linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,11 @@ obj-y				+= pwm-clock.o
 obj-y				+= gpio.o
 obj-y				+= gpio-config.o
 
+# PM support
+
+obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_S3C2410_PM_CHECK)	+= pm-check.o
+
 # devices
 
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/pm.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,363 @@
+/* linux/arch/arm/plat-s3c/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2004,2006,2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C common power management (suspend to ram) support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-irq.h>
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <plat/pm-core.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+/* Debug code:
+ *
+ * This code supports debug output to the low level UARTs for use on
+ * resume before the console layer is available.
+*/
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+	va_list va;
+	char buff[256];
+
+	va_start(va, fmt);
+	vsprintf(buff, fmt, va);
+	va_end(va);
+
+	printascii(buff);
+}
+
+static inline void s3c_pm_debug_init(void)
+{
+	/* restart uart clocks so we can use them to output */
+	s3c_pm_debug_init_uart();
+}
+
+#else
+#define s3c_pm_debug_init() do { } while(0)
+
+#endif /* CONFIG_S3C2410_PM_DEBUG */
+
+/* Save the UART configurations if we are configured for debug. */
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+
+struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
+{
+	void __iomem *regs = S3C_VA_UARTx(uart);
+
+	save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+	save->ucon = __raw_readl(regs + S3C2410_UCON);
+	save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+	save->umcon = __raw_readl(regs + S3C2410_UMCON);
+	save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+}
+
+static void s3c_pm_save_uarts(void)
+{
+	struct pm_uart_save *save = uart_save;
+	unsigned int uart;
+
+	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+		s3c_pm_save_uart(uart, save);
+}
+
+static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
+{
+	void __iomem *regs = S3C_VA_UARTx(uart);
+
+	__raw_writel(save->ulcon, regs + S3C2410_ULCON);
+	__raw_writel(save->ucon,  regs + S3C2410_UCON);
+	__raw_writel(save->ufcon, regs + S3C2410_UFCON);
+	__raw_writel(save->umcon, regs + S3C2410_UMCON);
+	__raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+}
+
+static void s3c_pm_restore_uarts(void)
+{
+	struct pm_uart_save *save = uart_save;
+	unsigned int uart;
+
+	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+		s3c_pm_restore_uart(uart, save);
+}
+#else
+static void s3c_pm_save_uarts(void) { }
+static void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* The IRQ ext-int code goes here, it is too small to currently bother
+ * with its own file. */
+
+unsigned long s3c_irqwake_intmask	= 0xffffffffL;
+unsigned long s3c_irqwake_eintmask	= 0xffffffffL;
+
+int s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+	unsigned long bit = 1L << IRQ_EINT_BIT(irqno);
+
+	if (!(s3c_irqwake_eintallow & bit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", irqno);
+
+	if (!state)
+		s3c_irqwake_eintmask |= bit;
+	else
+		s3c_irqwake_eintmask &= ~bit;
+
+	return 0;
+}
+
+/* helper functions to save and restore register state */
+
+/**
+ * s3c_pm_do_save() - save a set of registers for restoration on resume.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Run through the list of registers given, saving their contents in the
+ * array for later restoration when we wakeup.
+ */
+void s3c_pm_do_save(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++) {
+		ptr->val = __raw_readl(ptr->reg);
+		S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+	}
+}
+
+/**
+ * s3c_pm_do_restore() - restore register values from the save list.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Restore the register values saved from s3c_pm_do_save().
+ *
+ * Note, we do not use S3C_PMDBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c_pm_do_restore(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++) {
+		printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+		       ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+		__raw_writel(ptr->val, ptr->reg);
+	}
+}
+
+/**
+ * s3c_pm_do_restore_core() - early restore register values from save list.
+ *
+ * This is similar to s3c_pm_do_restore() except we try and minimise the
+ * side effects of the function in case registers that hardware might need
+ * to work has been restored.
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+	for (; count > 0; count--, ptr++)
+		__raw_writel(ptr->val, ptr->reg);
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+				    unsigned long mask)
+{
+	int i;
+
+	which &= ~mask;
+
+	for (i = 0; i <= 31; i++) {
+		if (which & (1L<<i)) {
+			S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
+		}
+	}
+}
+
+
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c_pm_enter(suspend_state_t state)
+{
+	static unsigned long regs_save[16];
+
+	/* ensure the debug is initialised (if enabled) */
+
+	s3c_pm_debug_init();
+
+	S3C_PMDBG("%s(%d)\n", __func__, state);
+
+	if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+		printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__);
+		return -EINVAL;
+	}
+
+	/* check if we have anything to wake-up with... bad things seem
+	 * to happen if you suspend with no wakeup (system will often
+	 * require a full power-cycle)
+	*/
+
+	if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+	    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+		printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
+		printk(KERN_ERR "%s: Aborting sleep\n", __func__);
+		return -EINVAL;
+	}
+
+	/* store the physical address of the register recovery block */
+
+	s3c_sleep_save_phys = virt_to_phys(regs_save);
+
+	S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
+
+	/* save all necessary core registers not covered by the drivers */
+
+	s3c_pm_save_gpios();
+	s3c_pm_save_uarts();
+	s3c_pm_save_core();
+
+	/* set the irq configuration for wake */
+
+	s3c_pm_configure_extint();
+
+	S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+	    s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+	s3c_pm_arch_prepare_irqs();
+
+	/* call cpu specific preparation */
+
+	pm_cpu_prep();
+
+	/* flush cache back to ram */
+
+	flush_cache_all();
+
+	s3c_pm_check_store();
+
+	/* send the cpu to sleep... */
+
+	s3c_pm_arch_stop_clocks();
+
+	/* s3c_cpu_save will also act as our return point from when
+	 * we resume as it saves its own register state and restores it
+	 * during the resume.  */
+
+	s3c_cpu_save(regs_save);
+
+	/* restore the cpu state using the kernel's cpu init code. */
+
+	cpu_init();
+
+	/* restore the system state */
+
+	s3c_pm_restore_core();
+	s3c_pm_restore_uarts();
+	s3c_pm_restore_gpios();
+
+	s3c_pm_debug_init();
+
+	/* check what irq (if any) restored the system */
+
+	s3c_pm_arch_show_resume_irqs();
+
+	S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
+
+	s3c_pm_check_restore();
+
+	/* ok, let's return from sleep */
+
+	S3C_PMDBG("S3C PM Resume (post-restore)\n");
+	return 0;
+}
+
+/* callback from assembly code */
+void s3c_pm_cb_flushcache(void)
+{
+	flush_cache_all();
+}
+
+static int s3c_pm_prepare(void)
+{
+	/* prepare check area if configured */
+
+	s3c_pm_check_prepare();
+	return 0;
+}
+
+static void s3c_pm_finish(void)
+{
+	s3c_pm_check_cleanup();
+}
+
+static struct platform_suspend_ops s3c_pm_ops = {
+	.enter		= s3c_pm_enter,
+	.prepare	= s3c_pm_prepare,
+	.finish		= s3c_pm_finish,
+	.valid		= suspend_valid_only_mem,
+};
+
+/* s3c_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c_pm_init(void)
+{
+	printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+
+	suspend_set_ops(&s3c_pm_ops);
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/pm-check.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/pm-check.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c/pm-check.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c/pm-check.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,242 @@
+/* linux/arch/arm/plat-s3c/pm-check.c
+ *  originally in linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004,2006,2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Power Mangament - suspend/resume memory corruptiuon check.
+ *
+ * This program is free software; you can 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/suspend.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+
+#include <plat/pm.h>
+
+#if CONFIG_S3C2410_PM_CHECK_CHUNKSIZE < 1
+#error CONFIG_S3C2410_PM_CHECK_CHUNKSIZE must be a positive non-zero value
+#endif
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size;	/* size needed for the crc block */
+static u32 *crcs;	/* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c_pm_run_res
+ *
+ * go through the given resource list, and look for system ram
+*/
+
+static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+	while (ptr != NULL) {
+		if (ptr->child != NULL)
+			s3c_pm_run_res(ptr->child, fn, arg);
+
+		if ((ptr->flags & IORESOURCE_MEM) &&
+		    strcmp(ptr->name, "System RAM") == 0) {
+			S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
+				  (unsigned long)ptr->start,
+				  (unsigned long)ptr->end);
+			arg = (fn)(ptr, arg);
+		}
+
+		ptr = ptr->sibling;
+	}
+}
+
+static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+	s3c_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c_pm_countram(struct resource *res, u32 *val)
+{
+	u32 size = (u32)(res->end - res->start)+1;
+
+	size += CHECK_CHUNKSIZE-1;
+	size /= CHECK_CHUNKSIZE;
+
+	S3C_PMDBG("Area %08lx..%08lx, %d blocks\n",
+		  (unsigned long)res->start, (unsigned long)res->end, size);
+
+	*val += size * sizeof(u32);
+	return val;
+}
+
+/* s3c_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+void s3c_pm_check_prepare(void)
+{
+	crc_size = 0;
+
+	s3c_pm_run_sysram(s3c_pm_countram, &crc_size);
+
+	S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size);
+
+	crcs = kmalloc(crc_size+4, GFP_KERNEL);
+	if (crcs == NULL)
+		printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c_pm_makecheck(struct resource *res, u32 *val)
+{
+	unsigned long addr, left;
+
+	for (addr = res->start; addr < res->end;
+	     addr += CHECK_CHUNKSIZE) {
+		left = res->end - addr;
+
+		if (left > CHECK_CHUNKSIZE)
+			left = CHECK_CHUNKSIZE;
+
+		*val = crc32_le(~0, phys_to_virt(addr), left);
+		val++;
+	}
+
+	return val;
+}
+
+/* s3c_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+void s3c_pm_check_store(void)
+{
+	if (crcs != NULL)
+		s3c_pm_run_sysram(s3c_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contains the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+	if ((what+whatsz) < ptr)
+		return 0;
+
+	if (what > (ptr+size))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * s3c_pm_runcheck() - helper to check a resource on restore.
+ * @res: The resource to check
+ * @vak: Pointer to list of CRC32 values to check.
+ *
+ * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this
+ * function runs the given memory resource checking it against the stored
+ * CRC to ensure that memory is restored. The function tries to skip as
+ * many of the areas used during the suspend process.
+ */
+static u32 *s3c_pm_runcheck(struct resource *res, u32 *val)
+{
+	void *save_at = phys_to_virt(s3c_sleep_save_phys);
+	unsigned long addr;
+	unsigned long left;
+	void *stkpage;
+	void *ptr;
+	u32 calc;
+
+	stkpage = (void *)((u32)&calc & ~PAGE_MASK);
+
+	for (addr = res->start; addr < res->end;
+	     addr += CHECK_CHUNKSIZE) {
+		left = res->end - addr;
+
+		if (left > CHECK_CHUNKSIZE)
+			left = CHECK_CHUNKSIZE;
+
+		ptr = phys_to_virt(addr);
+
+		if (in_region(ptr, left, stkpage, 4096)) {
+			S3C_PMDBG("skipping %08lx, has stack in\n", addr);
+			goto skip_check;
+		}
+
+		if (in_region(ptr, left, crcs, crc_size)) {
+			S3C_PMDBG("skipping %08lx, has crc block in\n", addr);
+			goto skip_check;
+		}
+
+		if (in_region(ptr, left, save_at, 32*4 )) {
+			S3C_PMDBG("skipping %08lx, has save block in\n", addr);
+			goto skip_check;
+		}
+
+		/* calculate and check the checksum */
+
+		calc = crc32_le(~0, ptr, left);
+		if (calc != *val) {
+			printk(KERN_ERR "Restore CRC error at "
+			       "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+			S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+			    addr, calc, *val);
+		}
+
+	skip_check:
+		val++;
+	}
+
+	return val;
+}
+
+/**
+ * s3c_pm_check_restore() - memory check called on resume
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+void s3c_pm_check_restore(void)
+{
+	if (crcs != NULL)
+		s3c_pm_run_sysram(s3c_pm_runcheck, crcs);
+}
+
+/**
+ * s3c_pm_check_cleanup() - free memory resources
+ *
+ * Free the resources that where allocated by the suspend
+ * memory check code. We do this separately from the
+ * s3c_pm_check_restore() function as we cannot call any
+ * functions that might sleep during that resume.
+ */
+void s3c_pm_check_cleanup(void)
+{
+	kfree(crcs);
+	crcs = NULL;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/adc.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/adc.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/adc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/adc.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,7 +100,7 @@ static void s3c_adc_dbgshow(struct adc_d
 		readl(adc->regs + S3C2410_ADCDLY));
 }
 
-void s3c_adc_try(struct adc_device *adc)
+static void s3c_adc_try(struct adc_device *adc)
 {
 	struct s3c_adc_client *next = adc->ts_pend;
 
@@ -190,6 +190,23 @@ EXPORT_SYMBOL_GPL(s3c_adc_register);
 void s3c_adc_release(struct s3c_adc_client *client)
 {
 	/* We should really check that nothing is in progress. */
+	if (adc_dev->cur == client)
+		adc_dev->cur = NULL;
+	if (adc_dev->ts_pend == client)
+		adc_dev->ts_pend = NULL;
+	else {
+		struct list_head *p, *n;
+		struct s3c_adc_client *tmp;
+
+		list_for_each_safe(p, n, &adc_pending) {
+			tmp = list_entry(p, struct s3c_adc_client, pend);
+			if (tmp == client)
+				list_del(&tmp->pend);
+		}
+	}
+
+	if (adc_dev->cur == NULL)
+		s3c_adc_try(adc_dev);
 	kfree(client);
 }
 EXPORT_SYMBOL_GPL(s3c_adc_release);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/common-smdk.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/common-smdk.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/common-smdk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/common-smdk.c	2009-06-09 23:05:27.000000000 -0400
@@ -201,5 +201,5 @@ void __init smdk_machine_init(void)
 
 	platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
 
-	s3c2410_pm_init();
+	s3c_pm_init();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/cpu.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/cpu.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/cpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/cpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,7 @@ static unsigned long s3c24xx_read_idcode
  * with the caches enabled. It seems at least the S3C2440 has a problem
  * resetting if there is bus activity interrupted by the reset.
  */
-static void s3c24xx_pm_restart(char mode)
+static void s3c24xx_pm_restart(char mode, const char *cmd)
 {
 	if (mode != 's') {
 		unsigned long flags;
@@ -191,12 +191,12 @@ static void s3c24xx_pm_restart(char mode
 		__cpuc_flush_kern_all();
 		__cpuc_flush_user_all();
 
-		arch_reset(mode);
+		arch_reset(mode, cmd);
 		local_irq_restore(flags);
 	}
 
 	/* fallback, or unhandled */
-	arm_machine_restart(mode);
+	arm_machine_restart(mode, cmd);
 }
 
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/dma.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/dma.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -1235,7 +1235,7 @@ int s3c2410_dma_getposition(unsigned int
 
 EXPORT_SYMBOL(s3c2410_dma_getposition);
 
-static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
+static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
 {
 	return container_of(dev, struct s3c2410_dma_chan, dev);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/gpiolib.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/gpiolib.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/gpiolib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/gpiolib.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <plat/gpio-core.h>
+#include <mach/gpio-core.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/irq.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/irq.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,12 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
 #define irqdbf(x...)
 #define irqdbf2(x...)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/map.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,8 @@
 #define S3C24XX_SZ_UART	   SZ_1M
 #define S3C_UART_OFFSET	   (0x4000)
 
+#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
 /* Timers */
 #define S3C24XX_VA_TIMER   S3C_VA_TIMER
 #define S3C2410_PA_TIMER   (0x51000000)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/pm-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,59 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.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.
+ */
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+	unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+	/* re-start uart clocks */
+	tmp |= S3C2410_CLKCON_UART0;
+	tmp |= S3C2410_CLKCON_UART1;
+	tmp |= S3C2410_CLKCON_UART2;
+
+	__raw_writel(tmp, S3C2410_CLKCON);
+	udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+	__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+	__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+	/* ack any outstanding external interrupts before we go to sleep */
+
+	__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+	__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+	__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
+}
+
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+				    unsigned long mask);
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+	S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+		  __raw_readl(S3C2410_SRCPND),
+		  __raw_readl(S3C2410_EINTPEND));
+
+	s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+				s3c_irqwake_intmask);
+
+	s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+				s3c_irqwake_eintmask);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/pm.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/pm.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/pm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/pm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/pm.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *	Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* s3c2410_pm_init
- *
- * called from board at initialisation time to setup the power
- * management
-*/
-
-#ifdef CONFIG_PM
-
-extern __init int s3c2410_pm_init(void);
-
-#else
-
-static inline int s3c2410_pm_init(void)
-{
-	return 0;
-}
-#endif
-
-/* configuration for the IRQ mask over sleep */
-extern unsigned long s3c_irqwake_intmask;
-extern unsigned long s3c_irqwake_eintmask;
-
-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
-extern unsigned long s3c_irqwake_intallow;
-extern unsigned long s3c_irqwake_eintallow;
-
-/* per-cpu sleep functions */
-
-extern void (*pm_cpu_prep)(void);
-extern void (*pm_cpu_sleep)(void);
-
-/* Flags for PM Control */
-
-extern unsigned long s3c_pm_flags;
-
-/* from sleep.S */
-
-extern int  s3c2410_cpu_save(unsigned long *saveblk);
-extern void s3c2410_cpu_suspend(void);
-extern void s3c2410_cpu_resume(void);
-
-extern unsigned long s3c2410_sleep_save_phys;
-
-/* sleep save info */
-
-struct sleep_save {
-	void __iomem	*reg;
-	unsigned long	val;
-};
-
-#define SAVE_ITEM(x) \
-	{ .reg = (x) }
-
-extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
-extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
-
-#ifdef CONFIG_PM
-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
-extern int s3c24xx_irq_resume(struct sys_device *dev);
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-iis.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-iis.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/include/plat/regs-iis.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,77 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-iis.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ *		      http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_IIS_H
+#define __ASM_ARCH_REGS_IIS_H
+
+#define S3C2410_IISCON	 (0x00)
+
+#define S3C2410_IISCON_LRINDEX	  (1<<8)
+#define S3C2410_IISCON_TXFIFORDY  (1<<7)
+#define S3C2410_IISCON_RXFIFORDY  (1<<6)
+#define S3C2410_IISCON_TXDMAEN	  (1<<5)
+#define S3C2410_IISCON_RXDMAEN	  (1<<4)
+#define S3C2410_IISCON_TXIDLE	  (1<<3)
+#define S3C2410_IISCON_RXIDLE	  (1<<2)
+#define S3C2410_IISCON_PSCEN	  (1<<1)
+#define S3C2410_IISCON_IISEN	  (1<<0)
+
+#define S3C2410_IISMOD	 (0x04)
+
+#define S3C2440_IISMOD_MPLL	  (1<<9)
+#define S3C2410_IISMOD_SLAVE	  (1<<8)
+#define S3C2410_IISMOD_NOXFER	  (0<<6)
+#define S3C2410_IISMOD_RXMODE	  (1<<6)
+#define S3C2410_IISMOD_TXMODE	  (2<<6)
+#define S3C2410_IISMOD_TXRXMODE	  (3<<6)
+#define S3C2410_IISMOD_LR_LLOW	  (0<<5)
+#define S3C2410_IISMOD_LR_RLOW	  (1<<5)
+#define S3C2410_IISMOD_IIS	  (0<<4)
+#define S3C2410_IISMOD_MSB	  (1<<4)
+#define S3C2410_IISMOD_8BIT	  (0<<3)
+#define S3C2410_IISMOD_16BIT	  (1<<3)
+#define S3C2410_IISMOD_BITMASK	  (1<<3)
+#define S3C2410_IISMOD_256FS	  (0<<2)
+#define S3C2410_IISMOD_384FS	  (1<<2)
+#define S3C2410_IISMOD_16FS	  (0<<0)
+#define S3C2410_IISMOD_32FS	  (1<<0)
+#define S3C2410_IISMOD_48FS	  (2<<0)
+#define S3C2410_IISMOD_FS_MASK	  (3<<0)
+
+#define S3C2410_IISPSR		(0x08)
+#define S3C2410_IISPSR_INTMASK	(31<<5)
+#define S3C2410_IISPSR_INTSHIFT	(5)
+#define S3C2410_IISPSR_EXTMASK	(31<<0)
+#define S3C2410_IISPSR_EXTSHFIT	(0)
+
+#define S3C2410_IISFCON  (0x0c)
+
+#define S3C2410_IISFCON_TXDMA	  (1<<15)
+#define S3C2410_IISFCON_RXDMA	  (1<<14)
+#define S3C2410_IISFCON_TXENABLE  (1<<13)
+#define S3C2410_IISFCON_RXENABLE  (1<<12)
+#define S3C2410_IISFCON_TXMASK	  (0x3f << 6)
+#define S3C2410_IISFCON_TXSHIFT	  (6)
+#define S3C2410_IISFCON_RXMASK	  (0x3f)
+#define S3C2410_IISFCON_RXSHIFT	  (0)
+
+#define S3C2400_IISFCON_TXDMA     (1<<11)
+#define S3C2400_IISFCON_RXDMA     (1<<10)
+#define S3C2400_IISFCON_TXENABLE  (1<<9)
+#define S3C2400_IISFCON_RXENABLE  (1<<8)
+#define S3C2400_IISFCON_TXMASK	  (0x07 << 4)
+#define S3C2400_IISFCON_TXSHIFT	  (4)
+#define S3C2400_IISFCON_RXMASK	  (0x07)
+#define S3C2400_IISFCON_RXSHIFT	  (0)
+
+#define S3C2410_IISFIFO  (0x10)
+#endif /* __ASM_ARCH_REGS_IIS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/irq.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/irq.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -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
@@ -16,38 +16,6 @@
  * You 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
- *
- * Changelog:
- *
- *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
- *                Fixed compile warnings
- *
- *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
- *                Fixed s3c_extirq_type
- *
- *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
- *                Addition of ADC/TC demux
- *
- *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
- *		  Fix for set_irq_type() on low EINT numbers
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *		  Tidy up KF's patch and sort out new release
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *		  Add support for power management controls
- *
- *   04-Nov-2004  Ben Dooks
- *		  Fix standard IRQ wake for EINT0..4 and RTC
- *
- *   22-Feb-2005  Ben Dooks
- *		  Fixed edge-triggering on ADC IRQ
- *
- *   28-Jun-2005  Ben Dooks
- *		  Mark IRQ_LCD valid
- *
- *   25-Jul-2005  Ben Dooks
- *		  Split the S3C2440 IRQ code to separate file
 */
 
 #include <linux/init.h>
@@ -55,81 +23,16 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
-#include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/irq.h>
-
 #include <asm/mach/irq.h>
 
 #include <plat/regs-irqtype.h>
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
 #include <plat/irq.h>
 
-/* wakeup irq control */
-
-#ifdef CONFIG_PM
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_intmask	= 0xffffffffL;
-unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
-unsigned long s3c_irqwake_eintmask	= 0xffffffffL;
-
-int
-s3c_irq_wake(unsigned int irqno, unsigned int state)
-{
-	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
-
-	if (!(s3c_irqwake_intallow & irqbit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", irqno);
-
-	if (!state)
-		s3c_irqwake_intmask |= irqbit;
-	else
-		s3c_irqwake_intmask &= ~irqbit;
-
-	return 0;
-}
-
-static int
-s3c_irqext_wake(unsigned int irqno, unsigned int state)
-{
-	unsigned long bit = 1L << (irqno - EXTINT_OFF);
-
-	if (!(s3c_irqwake_eintallow & bit))
-		return -ENOENT;
-
-	printk(KERN_INFO "wake %s for irq %d\n",
-	       state ? "enabled" : "disabled", irqno);
-
-	if (!state)
-		s3c_irqwake_eintmask |= bit;
-	else
-		s3c_irqwake_eintmask &= ~bit;
-
-	return 0;
-}
-
-#else
-#define s3c_irqext_wake NULL
-#define s3c_irq_wake NULL
-#endif
-
-
 static void
 s3c_irq_mask(unsigned int irqno)
 {
@@ -590,59 +493,6 @@ s3c_irq_demux_extint4t7(unsigned int irq
 	}
 }
 
-#ifdef CONFIG_PM
-
-static struct sleep_save irq_save[] = {
-	SAVE_ITEM(S3C2410_INTMSK),
-	SAVE_ITEM(S3C2410_INTSUBMSK),
-};
-
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
-	s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-int s3c24xx_irq_resume(struct sys_device *dev)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
-	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
-	s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
-	return 0;
-}
-
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
-#endif
-
 /* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/irq-pm.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/irq-pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/irq-pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/irq-pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-s3c24xx/irq-om.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C24XX - IRQ PM code
+ *
+ * This program is free software; you can 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/sysdev.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow	= 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_eintallow	= 0x0000fff0L;
+
+int s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+	unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+
+	if (!(s3c_irqwake_intallow & irqbit))
+		return -ENOENT;
+
+	printk(KERN_INFO "wake %s for irq %d\n",
+	       state ? "enabled" : "disabled", irqno);
+
+	if (!state)
+		s3c_irqwake_intmask |= irqbit;
+	else
+		s3c_irqwake_intmask &= ~irqbit;
+
+	return 0;
+}
+
+static struct sleep_save irq_save[] = {
+	SAVE_ITEM(S3C2410_INTMSK),
+	SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+	save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+	return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/Makefile linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/Makefile
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-clock.o
 obj-$(CONFIG_PM_SIMTEC)		+= pm-simtec.o
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM)		+= irq-pm.o
 obj-$(CONFIG_PM)		+= sleep.o
 obj-$(CONFIG_HAVE_PWM)		+= pwm.o
 obj-$(CONFIG_S3C2410_CLOCK)	+= s3c2410-clock.o
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/pm.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/pm.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,14 +31,9 @@
 #include <linux/errno.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
-#include <linux/crc32.h>
-#include <linux/ioport.h>
 #include <linux/serial_core.h>
 #include <linux/io.h>
 
-#include <asm/cacheflush.h>
-#include <mach/hardware.h>
-
 #include <plat/regs-serial.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
@@ -49,10 +44,6 @@
 
 #include <plat/pm.h>
 
-/* for external use */
-
-unsigned long s3c_pm_flags;
-
 #define PFX "s3c24xx-pm: "
 
 static struct sleep_save core_save[] = {
@@ -120,328 +111,14 @@ static struct sleep_save misc_save[] = {
 	SAVE_ITEM(S3C2410_DCLKCON),
 };
 
-#ifdef CONFIG_S3C2410_PM_DEBUG
-
-#define SAVE_UART(va) \
-	SAVE_ITEM((va) + S3C2410_ULCON), \
-	SAVE_ITEM((va) + S3C2410_UCON), \
-	SAVE_ITEM((va) + S3C2410_UFCON), \
-	SAVE_ITEM((va) + S3C2410_UMCON), \
-	SAVE_ITEM((va) + S3C2410_UBRDIV)
-
-static struct sleep_save uart_save[] = {
-	SAVE_UART(S3C24XX_VA_UART0),
-	SAVE_UART(S3C24XX_VA_UART1),
-#ifndef CONFIG_CPU_S3C2400
-	SAVE_UART(S3C24XX_VA_UART2),
-#endif
-};
-
-/* debug
- *
- * we send the debug to printascii() to allow it to be seen if the
- * system never wakes up from the sleep
-*/
-
-extern void printascii(const char *);
-
-void pm_dbg(const char *fmt, ...)
-{
-	va_list va;
-	char buff[256];
-
-	va_start(va, fmt);
-	vsprintf(buff, fmt, va);
-	va_end(va);
-
-	printascii(buff);
-}
-
-static void s3c2410_pm_debug_init(void)
-{
-	unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
-	/* re-start uart clocks */
-	tmp |= S3C2410_CLKCON_UART0;
-	tmp |= S3C2410_CLKCON_UART1;
-	tmp |= S3C2410_CLKCON_UART2;
-
-	__raw_writel(tmp, S3C2410_CLKCON);
-	udelay(10);
-}
-
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-
-#define s3c2410_pm_debug_init() do { } while(0)
-
-static struct sleep_save uart_save[] = {};
-#endif
-
-#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
-
-/* suspend checking code...
- *
- * this next area does a set of crc checks over all the installed
- * memory, so the system can verify if the resume was ok.
- *
- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
- * increasing it will mean that the area corrupted will be less easy to spot,
- * and reducing the size will cause the CRC save area to grow
-*/
-
-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
-
-static u32 crc_size;	/* size needed for the crc block */
-static u32 *crcs;	/* allocated over suspend/resume */
-
-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
-
-/* s3c2410_pm_run_res
- *
- * go thorugh the given resource list, and look for system ram
-*/
-
-static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
-{
-	while (ptr != NULL) {
-		if (ptr->child != NULL)
-			s3c2410_pm_run_res(ptr->child, fn, arg);
-
-		if ((ptr->flags & IORESOURCE_MEM) &&
-		    strcmp(ptr->name, "System RAM") == 0) {
-			DBG("Found system RAM at %08lx..%08lx\n",
-			    ptr->start, ptr->end);
-			arg = (fn)(ptr, arg);
-		}
-
-		ptr = ptr->sibling;
-	}
-}
-
-static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
-{
-	s3c2410_pm_run_res(&iomem_resource, fn, arg);
-}
-
-static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
-{
-	u32 size = (u32)(res->end - res->start)+1;
-
-	size += CHECK_CHUNKSIZE-1;
-	size /= CHECK_CHUNKSIZE;
-
-	DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
-
-	*val += size * sizeof(u32);
-	return val;
-}
-
-/* s3c2410_pm_prepare_check
- *
- * prepare the necessary information for creating the CRCs. This
- * must be done before the final save, as it will require memory
- * allocating, and thus touching bits of the kernel we do not
- * know about.
-*/
-
-static void s3c2410_pm_check_prepare(void)
-{
-	crc_size = 0;
-
-	s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
-
-	DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
-
-	crcs = kmalloc(crc_size+4, GFP_KERNEL);
-	if (crcs == NULL)
-		printk(KERN_ERR "Cannot allocated CRC save area\n");
-}
-
-static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
-{
-	unsigned long addr, left;
-
-	for (addr = res->start; addr < res->end;
-	     addr += CHECK_CHUNKSIZE) {
-		left = res->end - addr;
-
-		if (left > CHECK_CHUNKSIZE)
-			left = CHECK_CHUNKSIZE;
-
-		*val = crc32_le(~0, phys_to_virt(addr), left);
-		val++;
-	}
-
-	return val;
-}
-
-/* s3c2410_pm_check_store
- *
- * compute the CRC values for the memory blocks before the final
- * sleep.
-*/
-
-static void s3c2410_pm_check_store(void)
-{
-	if (crcs != NULL)
-		s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
-}
-
-/* in_region
- *
- * return TRUE if the area defined by ptr..ptr+size contatins the
- * what..what+whatsz
-*/
-
-static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
-{
-	if ((what+whatsz) < ptr)
-		return 0;
-
-	if (what > (ptr+size))
-		return 0;
-
-	return 1;
-}
-
-static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
-{
-	void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
-	unsigned long addr;
-	unsigned long left;
-	void *ptr;
-	u32 calc;
-
-	for (addr = res->start; addr < res->end;
-	     addr += CHECK_CHUNKSIZE) {
-		left = res->end - addr;
-
-		if (left > CHECK_CHUNKSIZE)
-			left = CHECK_CHUNKSIZE;
-
-		ptr = phys_to_virt(addr);
-
-		if (in_region(ptr, left, crcs, crc_size)) {
-			DBG("skipping %08lx, has crc block in\n", addr);
-			goto skip_check;
-		}
-
-		if (in_region(ptr, left, save_at, 32*4 )) {
-			DBG("skipping %08lx, has save block in\n", addr);
-			goto skip_check;
-		}
 
-		/* calculate and check the checksum */
-
-		calc = crc32_le(~0, ptr, left);
-		if (calc != *val) {
-			printk(KERN_ERR PFX "Restore CRC error at "
-			       "%08lx (%08x vs %08x)\n", addr, calc, *val);
-
-			DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
-			    addr, calc, *val);
-		}
-
-	skip_check:
-		val++;
-	}
-
-	return val;
-}
-
-/* s3c2410_pm_check_restore
- *
- * check the CRCs after the restore event and free the memory used
- * to hold them
-*/
-
-static void s3c2410_pm_check_restore(void)
-{
-	if (crcs != NULL) {
-		s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
-		kfree(crcs);
-		crcs = NULL;
-	}
-}
-
-#else
-
-#define s3c2410_pm_check_prepare() do { } while(0)
-#define s3c2410_pm_check_restore() do { } while(0)
-#define s3c2410_pm_check_store()   do { } while(0)
-#endif
-
-/* helper functions to save and restore register state */
-
-void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		ptr->val = __raw_readl(ptr->reg);
-		DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
-	}
-}
-
-/* s3c2410_pm_do_restore
- *
- * restore the system from the given list of saved registers
- *
- * Note, we do not use DBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
-
-void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
-		       ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
-		__raw_writel(ptr->val, ptr->reg);
-	}
-}
-
-/* s3c2410_pm_do_restore_core
- *
- * similar to s3c2410_pm_do_restore_core
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
-
-static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
-{
-	for (; count > 0; count--, ptr++) {
-		__raw_writel(ptr->val, ptr->reg);
-	}
-}
-
-/* s3c2410_pm_show_resume_irqs
- *
- * print any IRQs asserted at resume time (ie, we woke from)
-*/
-
-static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
-					unsigned long mask)
-{
-	int i;
-
-	which &= ~mask;
-
-	for (i = 0; i <= 31; i++) {
-		if ((which) & (1L<<i)) {
-			DBG("IRQ %d asserted at resume\n", start+i);
-		}
-	}
-}
-
-/* s3c2410_pm_check_resume_pin
+/* s3c_pm_check_resume_pin
  *
  * check to see if the pin is configured correctly for sleep mode, and
  * make any necessary adjustments if it is not
 */
 
-static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
 {
 	unsigned long irqstate;
 	unsigned long pinstate;
@@ -456,21 +133,21 @@ static void s3c2410_pm_check_resume_pin(
 
 	if (!irqstate) {
 		if (pinstate == S3C2410_GPIO_IRQ)
-			DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+			S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
 	} else {
 		if (pinstate == S3C2410_GPIO_IRQ) {
-			DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+			S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
 			s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
 		}
 	}
 }
 
-/* s3c2410_pm_configure_extint
+/* s3c_pm_configure_extint
  *
  * configure all external interrupt pins
 */
 
-static void s3c2410_pm_configure_extint(void)
+void s3c_pm_configure_extint(void)
 {
 	int pin;
 
@@ -480,11 +157,11 @@ static void s3c2410_pm_configure_extint(
 	*/
 
 	for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
-		s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
+		s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
 	}
 
 	for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
-		s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
+		s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
 	}
 }
 
@@ -494,12 +171,12 @@ static void s3c2410_pm_configure_extint(
 #define OFFS_DAT	(S3C2410_GPADAT - S3C2410_GPACON)
 #define OFFS_UP		(S3C2410_GPBUP  - S3C2410_GPBCON)
 
-/* s3c2410_pm_save_gpios()
+/* s3c_pm_save_gpios()
  *
  * Save the state of the GPIOs
  */
 
-static void s3c2410_pm_save_gpios(void)
+void s3c_pm_save_gpios(void)
 {
 	struct gpio_sleep *gps = gpio_save;
 	unsigned int gpio;
@@ -538,7 +215,10 @@ static inline int is_out(unsigned long c
 	return con == 1;
 }
 
-/* s3c2410_pm_restore_gpio()
+/**
+ * s3c2410_pm_restore_gpio() - restore the given GPIO bank
+ * @index: The number of the GPIO bank being resumed.
+ * @gps: The sleep confgiuration for the bank.
  *
  * Restore one of the GPIO banks that was saved during suspend. This is
  * not as simple as once thought, due to the possibility of glitches
@@ -646,8 +326,8 @@ static void s3c2410_pm_restore_gpio(int
 		__raw_writel(gps->gpup, base + OFFS_UP);
 	}
 
-	DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
-	    index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+	S3C_PMDBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
+		  index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
 }
 
 
@@ -656,7 +336,7 @@ static void s3c2410_pm_restore_gpio(int
  * Restore the state of the GPIOs
  */
 
-static void s3c2410_pm_restore_gpios(void)
+void s3c_pm_restore_gpios(void)
 {
 	struct gpio_sleep *gps = gpio_save;
 	int gpio;
@@ -666,150 +346,15 @@ static void s3c2410_pm_restore_gpios(voi
 	}
 }
 
-void (*pm_cpu_prep)(void);
-void (*pm_cpu_sleep)(void);
-
-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
-
-/* s3c2410_pm_enter
- *
- * central control for sleep/resume process
-*/
-
-static int s3c2410_pm_enter(suspend_state_t state)
+void s3c_pm_restore_core(void)
 {
-	unsigned long regs_save[16];
-
-	/* ensure the debug is initialised (if enabled) */
-
-	s3c2410_pm_debug_init();
-
-	DBG("s3c2410_pm_enter(%d)\n", state);
-
-	if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
-		printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
-		return -EINVAL;
-	}
-
-	/* check if we have anything to wake-up with... bad things seem
-	 * to happen if you suspend with no wakeup (system will often
-	 * require a full power-cycle)
-	*/
-
-	if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
-	    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
-		printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
-		printk(KERN_ERR PFX "Aborting sleep\n");
-		return -EINVAL;
-	}
-
-	/* prepare check area if configured */
-
-	s3c2410_pm_check_prepare();
-
-	/* store the physical address of the register recovery block */
-
-	s3c2410_sleep_save_phys = virt_to_phys(regs_save);
-
-	DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
-
-	/* save all necessary core registers not covered by the drivers */
-
-	s3c2410_pm_save_gpios();
-	s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
-	s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
-	s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
-
-	/* set the irq configuration for wake */
-
-	s3c2410_pm_configure_extint();
-
-	DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
-	    s3c_irqwake_intmask, s3c_irqwake_eintmask);
-
-	__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
-	__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
-	/* ack any outstanding external interrupts before we go to sleep */
-
-	__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
-	__raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
-	__raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
-	/* call cpu specific preparation */
-
-	pm_cpu_prep();
-
-	/* flush cache back to ram */
-
-	flush_cache_all();
-
-	s3c2410_pm_check_store();
-
-	/* send the cpu to sleep... */
-
-	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
-
-	/* s3c2410_cpu_save will also act as our return point from when
-	 * we resume as it saves its own register state, so use the return
-	 * code to differentiate return from save and return from sleep */
-
-	if (s3c2410_cpu_save(regs_save) == 0) {
-		flush_cache_all();
-		pm_cpu_sleep();
-	}
-
-	/* restore the cpu state */
-
-	cpu_init();
-
-	/* restore the system state */
-
-	s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-	s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
-	s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
-	s3c2410_pm_restore_gpios();
-
-	s3c2410_pm_debug_init();
-
-	/* check what irq (if any) restored the system */
-
-	DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
-	    __raw_readl(S3C2410_SRCPND),
-	    __raw_readl(S3C2410_EINTPEND));
-
-	s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
-				    s3c_irqwake_intmask);
-
-	s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
-				    s3c_irqwake_eintmask);
-
-	DBG("post sleep, preparing to return\n");
-
-	s3c2410_pm_check_restore();
-
-	/* ok, let's return from sleep */
-
-	DBG("S3C2410 PM Resume (post-restore)\n");
-	return 0;
+	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
 }
 
-static struct platform_suspend_ops s3c2410_pm_ops = {
-	.enter		= s3c2410_pm_enter,
-	.valid		= suspend_valid_only_mem,
-};
-
-/* s3c2410_pm_init
- *
- * Attach the power management functions. This should be called
- * from the board specific initialisation if the board supports
- * it.
-*/
-
-int __init s3c2410_pm_init(void)
+void s3c_pm_save_core(void)
 {
-	printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
-
-	suspend_set_ops(&s3c2410_pm_ops);
-	return 0;
+	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 }
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/pm-simtec.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,7 @@ static __init int pm_simtec_init(void)
 
 	__raw_writel(gstatus4, S3C2410_GSTATUS4);
 
-	return s3c2410_pm_init();
+	return s3c_pm_init();
 }
 
 arch_initcall(pm_simtec_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/s3c244x.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/s3c244x.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/s3c244x.c	2009-06-09 23:05:27.000000000 -0400
@@ -145,13 +145,13 @@ static struct sleep_save s3c244x_sleep[]
 
 static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
 {
-	s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
 	return 0;
 }
 
 static int s3c244x_resume(struct sys_device *dev)
 {
-	s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/sleep.S linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/sleep.S
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c24xx/sleep.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c24xx/sleep.S	2009-06-09 23:05:27.000000000 -0400
@@ -41,25 +41,13 @@
 
 	.text
 
-	/* s3c2410_cpu_save
-	 *
-	 * save enough of the CPU state to allow us to re-start
-	 * pm.c code. as we store items like the sp/lr, we will
-	 * end up returning from this function when the cpu resumes
-	 * so the return value is set to mark this.
-	 *
-	 * This arangement means we avoid having to flush the cache
-	 * from this code.
+	/* s3c_cpu_save
 	 *
 	 * entry:
-	 *	r0 = pointer to save block
-	 *
-	 * exit:
-	 *	r0 = 0 => we stored everything
-	 *	     1 => resumed from sleep
+	 *	r0 = save address (virtual addr of s3c_sleep_save_phys)
 	*/
 
-ENTRY(s3c2410_cpu_save)
+ENTRY(s3c_cpu_save)
 	stmfd	sp!, { r4 - r12, lr }
 
 	@@ store co-processor registers
@@ -71,20 +59,25 @@ ENTRY(s3c2410_cpu_save)
 
 	stmia	r0, { r4 - r13 }
 
-	mov	r0, #0
-	ldmfd	sp, { r4 - r12, pc }
+	@@ write our state back to RAM
+	bl	s3c_pm_cb_flushcache
 
+	@@ jump to final code to send system to sleep
+	ldr	r0, =pm_cpu_sleep
+	@@ldr	pc, [ r0 ]
+	ldr	r0, [ r0 ]
+	mov	pc, r0
+	
 	@@ return to the caller, after having the MMU
 	@@ turned on, this restores the last bits from the
 	@@ stack
 resume_with_mmu:
-	mov	r0, #1
 	ldmfd	sp!, { r4 - r12, pc }
 
 	.ltorg
 
 	@@ the next bits sit in the .data segment, even though they
-	@@ happen to be code... the s3c2410_sleep_save_phys needs to be
+	@@ happen to be code... the s3c_sleep_save_phys needs to be
 	@@ accessed by the resume code before it can restore the MMU.
 	@@ This means that the variable has to be close enough for the
 	@@ code to read it... since the .text segment needs to be RO,
@@ -92,19 +85,19 @@ resume_with_mmu:
 
 	.data
 
-	.global	s3c2410_sleep_save_phys
-s3c2410_sleep_save_phys:
+	.global	s3c_sleep_save_phys
+s3c_sleep_save_phys:
 	.word	0
 
 
 	/* sleep magic, to allow the bootloader to check for an valid
 	 * image to resume to. Must be the first word before the
-	 * s3c2410_cpu_resume entry.
+	 * s3c_cpu_resume entry.
 	*/
 
 	.word	0x2bedf00d
 
-	/* s3c2410_cpu_resume
+	/* s3c_cpu_resume
 	 *
 	 * resume code entry for bootloader to call
 	 *
@@ -113,7 +106,7 @@ s3c2410_sleep_save_phys:
 	 * must not write to the code segment (code is read-only)
 	*/
 
-ENTRY(s3c2410_cpu_resume)
+ENTRY(s3c_cpu_resume)
 	mov	r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
 	msr	cpsr_c, r0
 
@@ -145,7 +138,7 @@ ENTRY(s3c2410_cpu_resume)
 	mcr	p15, 0, r1, c8, c7, 0		@@ invalidate I & D TLBs
 	mcr	p15, 0, r1, c7, c7, 0		@@ invalidate I & D caches
 
-	ldr	r0, s3c2410_sleep_save_phys	@ address of restore block
+	ldr	r0, s3c_sleep_save_phys		@ address of restore block
 	ldmia	r0, { r4 - r13 }
 
 	mcr	p15, 0, r4, c13, c0, 0		@ PID
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/cpu.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/cpu.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/cpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/cpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -96,6 +96,11 @@ static struct map_desc s3c_iodesc[] __in
 		.pfn		= __phys_to_pfn(S3C64XX_PA_GPIO),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S3C64XX_VA_MODEM,
+		.pfn		= __phys_to_pfn(S3C64XX_PA_MODEM),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
 	},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/gpiolib.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/gpiolib.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/gpiolib.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@
 #if 1
 #define gpio_dbg(x...) do { } while(0)
 #else
-#define gpio_dbg(x...) printk(KERN_DEBUG ## x)
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
 #endif
 
 /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,14 +61,14 @@
 #define S3C64XX_GPH7_ADDR_CF1		(0x06 << 28)
 #define S3C64XX_GPH7_EINT_G6_7		(0x07 << 28)
 
-#define S3C64XX_GPH8_MMC1_DATA6		(0x02 << 32)
-#define S3C64XX_GPH8_MMC2_DATA2		(0x03 << 32)
-#define S3C64XX_GPH8_I2S_V40_LRCLK	(0x05 << 32)
-#define S3C64XX_GPH8_ADDR_CF2		(0x06 << 32)
-#define S3C64XX_GPH8_EINT_G6_8		(0x07 << 32)
-
-#define S3C64XX_GPH9_MMC1_DATA7		(0x02 << 36)
-#define S3C64XX_GPH9_MMC2_DATA3		(0x03 << 36)
-#define S3C64XX_GPH9_I2S_V40_DI		(0x05 << 36)
-#define S3C64XX_GPH9_EINT_G6_9		(0x07 << 36)
+#define S3C64XX_GPH8_MMC1_DATA6		(0x02 <<  0)
+#define S3C64XX_GPH8_MMC2_DATA2		(0x03 <<  0)
+#define S3C64XX_GPH8_I2S_V40_LRCLK	(0x05 <<  0)
+#define S3C64XX_GPH8_ADDR_CF2		(0x06 <<  0)
+#define S3C64XX_GPH8_EINT_G6_8		(0x07 <<  0)
 
+#define S3C64XX_GPH9_OUTPUT		(0x01 <<  4)
+#define S3C64XX_GPH9_MMC1_DATA7		(0x02 <<  4)
+#define S3C64XX_GPH9_MMC2_DATA3		(0x03 <<  4)
+#define S3C64XX_GPH9_I2S_V40_DI		(0x05 <<  4)
+#define S3C64XX_GPH9_EINT_G6_9		(0x07 <<  4)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,23 +13,175 @@
 
 /* Base addresses for each of the banks */
 
-#define S3C64XX_GPA_BASE	(S3C64XX_VA_GPIO + 0x0000)
-#define S3C64XX_GPB_BASE	(S3C64XX_VA_GPIO + 0x0020)
-#define S3C64XX_GPC_BASE	(S3C64XX_VA_GPIO + 0x0040)
-#define S3C64XX_GPD_BASE	(S3C64XX_VA_GPIO + 0x0060)
-#define S3C64XX_GPE_BASE	(S3C64XX_VA_GPIO + 0x0080)
-#define S3C64XX_GPF_BASE	(S3C64XX_VA_GPIO + 0x00A0)
-#define S3C64XX_GPG_BASE	(S3C64XX_VA_GPIO + 0x00C0)
-#define S3C64XX_GPH_BASE	(S3C64XX_VA_GPIO + 0x00E0)
-#define S3C64XX_GPI_BASE	(S3C64XX_VA_GPIO + 0x0100)
-#define S3C64XX_GPJ_BASE	(S3C64XX_VA_GPIO + 0x0120)
-#define S3C64XX_GPK_BASE	(S3C64XX_VA_GPIO + 0x0800)
-#define S3C64XX_GPL_BASE	(S3C64XX_VA_GPIO + 0x0810)
-#define S3C64XX_GPM_BASE	(S3C64XX_VA_GPIO + 0x0820)
-#define S3C64XX_GPN_BASE	(S3C64XX_VA_GPIO + 0x0830)
-#define S3C64XX_GPO_BASE	(S3C64XX_VA_GPIO + 0x0140)
-#define S3C64XX_GPP_BASE	(S3C64XX_VA_GPIO + 0x0160)
-#define S3C64XX_GPQ_BASE	(S3C64XX_VA_GPIO + 0x0180)
+#define S3C64XX_GPIOREG(reg)	(S3C64XX_VA_GPIO + (reg))
+
+#define S3C64XX_GPA_BASE	S3C64XX_GPIOREG(0x0000)
+#define S3C64XX_GPB_BASE	S3C64XX_GPIOREG(0x0020)
+#define S3C64XX_GPC_BASE	S3C64XX_GPIOREG(0x0040)
+#define S3C64XX_GPD_BASE	S3C64XX_GPIOREG(0x0060)
+#define S3C64XX_GPE_BASE	S3C64XX_GPIOREG(0x0080)
+#define S3C64XX_GPF_BASE	S3C64XX_GPIOREG(0x00A0)
+#define S3C64XX_GPG_BASE	S3C64XX_GPIOREG(0x00C0)
+#define S3C64XX_GPH_BASE	S3C64XX_GPIOREG(0x00E0)
+#define S3C64XX_GPI_BASE	S3C64XX_GPIOREG(0x0100)
+#define S3C64XX_GPJ_BASE	S3C64XX_GPIOREG(0x0120)
+#define S3C64XX_GPK_BASE	S3C64XX_GPIOREG(0x0800)
+#define S3C64XX_GPL_BASE	S3C64XX_GPIOREG(0x0810)
+#define S3C64XX_GPM_BASE	S3C64XX_GPIOREG(0x0820)
+#define S3C64XX_GPN_BASE	S3C64XX_GPIOREG(0x0830)
+#define S3C64XX_GPO_BASE	S3C64XX_GPIOREG(0x0140)
+#define S3C64XX_GPP_BASE	S3C64XX_GPIOREG(0x0160)
+#define S3C64XX_GPQ_BASE	S3C64XX_GPIOREG(0x0180)
+
+/* SPCON */
+
+#define S3C64XX_SPCON		S3C64XX_GPIOREG(0x1A0)
+
+#define S3C64XX_SPCON_DRVCON_CAM_MASK		(0x3 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_SHIFT		(30)
+#define S3C64XX_SPCON_DRVCON_CAM_2mA		(0x0 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_4mA		(0x1 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_7mA		(0x2 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_9mA		(0x3 << 30)
+
+#define S3C64XX_SPCON_DRVCON_HSSPI_MASK		(0x3 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT	(28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_2mA		(0x0 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_4mA		(0x1 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_7mA		(0x2 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_9mA		(0x3 << 28)
+
+#define S3C64XX_SPCON_DRVCON_HSMMC_MASK		(0x3 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT	(26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_2mA		(0x0 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_4mA		(0x1 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_7mA		(0x2 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_9mA		(0x3 << 26)
+
+#define S3C64XX_SPCON_DRVCON_LCD_MASK		(0x3 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_SHIFT		(24)
+#define S3C64XX_SPCON_DRVCON_LCD_2mA		(0x0 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_4mA		(0x1 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_7mA		(0x2 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_9mA		(0x3 << 24)
+
+#define S3C64XX_SPCON_DRVCON_MODEM_MASK		(0x3 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT	(22)
+#define S3C64XX_SPCON_DRVCON_MODEM_2mA		(0x0 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_4mA		(0x1 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_7mA		(0x2 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_9mA		(0x3 << 22)
+
+#define S3C64XX_SPCON_nRSTOUT_OEN		(1 << 21)
+
+#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK	(0x3 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT	(18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA	(0x0 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA	(0x1 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA	(0x2 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA	(0x3 << 18)
+
+#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK		(0x3 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT	(16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED	(0x0 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN		(0x1 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_UP		(0x2 << 16)
+
+#define S3C64XX_SPCON_MEM1_D_PUD1_MASK		(0x3 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT		(14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED	(0x0 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN		(0x1 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_UP		(0x2 << 14)
+
+#define S3C64XX_SPCON_MEM1_D_PUD0_MASK		(0x3 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT		(12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED	(0x0 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN		(0x1 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_UP		(0x2 << 12)
+
+#define S3C64XX_SPCON_MEM0_D_PUD_MASK		(0x3 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT		(8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED	(0x0 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DOWN		(0x1 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_UP		(0x2 << 8)
+
+#define S3C64XX_SPCON_USBH_DMPD			(1 << 7)
+#define S3C64XX_SPCON_USBH_DPPD			(1 << 6)
+#define S3C64XX_SPCON_USBH_PUSW2		(1 << 5)
+#define S3C64XX_SPCON_USBH_PUSW1		(1 << 4)
+#define S3C64XX_SPCON_USBH_SUSPND		(1 << 3)
+
+#define S3C64XX_SPCON_LCD_SEL_MASK		(0x3 << 0)
+#define S3C64XX_SPCON_LCD_SEL_SHIFT		(0)
+#define S3C64XX_SPCON_LCD_SEL_HOST		(0x0 << 0)
+#define S3C64XX_SPCON_LCD_SEL_RGB		(0x1 << 0)
+#define S3C64XX_SPCON_LCD_SEL_606_656		(0x2 << 0)
+
+
+/* External interrupt registers */
+
+#define S3C64XX_EINT12CON	S3C64XX_GPIOREG(0x200)
+#define S3C64XX_EINT34CON	S3C64XX_GPIOREG(0x204)
+#define S3C64XX_EINT56CON	S3C64XX_GPIOREG(0x208)
+#define S3C64XX_EINT78CON	S3C64XX_GPIOREG(0x20C)
+#define S3C64XX_EINT9CON	S3C64XX_GPIOREG(0x210)
+
+#define S3C64XX_EINT12FLTCON	S3C64XX_GPIOREG(0x220)
+#define S3C64XX_EINT34FLTCON	S3C64XX_GPIOREG(0x224)
+#define S3C64XX_EINT56FLTCON	S3C64XX_GPIOREG(0x228)
+#define S3C64XX_EINT78FLTCON	S3C64XX_GPIOREG(0x22C)
+#define S3C64XX_EINT9FLTCON	S3C64XX_GPIOREG(0x230)
+
+#define S3C64XX_EINT12MASK	S3C64XX_GPIOREG(0x240)
+#define S3C64XX_EINT34MASK	S3C64XX_GPIOREG(0x244)
+#define S3C64XX_EINT56MASK	S3C64XX_GPIOREG(0x248)
+#define S3C64XX_EINT78MASK	S3C64XX_GPIOREG(0x24C)
+#define S3C64XX_EINT9MASK	S3C64XX_GPIOREG(0x250)
+
+#define S3C64XX_EINT12PEND	S3C64XX_GPIOREG(0x260)
+#define S3C64XX_EINT34PEND	S3C64XX_GPIOREG(0x264)
+#define S3C64XX_EINT56PEND	S3C64XX_GPIOREG(0x268)
+#define S3C64XX_EINT78PEND	S3C64XX_GPIOREG(0x26C)
+#define S3C64XX_EINT9PEND	S3C64XX_GPIOREG(0x270)
+
+#define S3C64XX_PRIORITY	S3C64XX_GPIOREG(0x280)
+#define S3C64XX_PRIORITY_ARB(x)	(1 << (x))
+
+#define S3C64XX_SERVICE		S3C64XX_GPIOREG(0x284)
+#define S3C64XX_SERVICEPEND	S3C64XX_GPIOREG(0x288)
+
+#define S3C64XX_EINT0CON0	S3C64XX_GPIOREG(0x900)
+#define S3C64XX_EINT0CON1	S3C64XX_GPIOREG(0x904)
+#define S3C64XX_EINT0FLTCON0	S3C64XX_GPIOREG(0x910)
+#define S3C64XX_EINT0FLTCON1	S3C64XX_GPIOREG(0x914)
+#define S3C64XX_EINT0FLTCON2	S3C64XX_GPIOREG(0x918)
+#define S3C64XX_EINT0FLTCON3	S3C64XX_GPIOREG(0x91C)
+
+#define S3C64XX_EINT0MASK	S3C64XX_GPIOREG(0x920)
+#define S3C64XX_EINT0PEND	S3C64XX_GPIOREG(0x924)
+
+/* GPIO sleep configuration */
+
+#define S3C64XX_SPCONSLP	S3C64XX_GPIOREG(0x880)
+
+#define S3C64XX_SPCONSLP_TDO_PULLDOWN	(1 << 14)
+#define S3C64XX_SPCONSLP_CKE1INIT	(1 << 5)
+
+#define S3C64XX_SPCONSLP_RSTOUT_MASK	(0x3 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT0	(0x0 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT1	(0x1 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_HIZ	(0x2 << 12)
+
+#define S3C64XX_SPCONSLP_KPCOL_MASK	(0x3 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT0	(0x0 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT1	(0x1 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_INP	(0x2 << 0)
+
+
+#define S3C64XX_SLPEN		S3C64XX_GPIOREG(0x930)
+
+#define S3C64XX_SLPEN_USE_xSLP		(1 << 0)
+#define S3C64XX_SLPEN_CFG_BYSLPEN	(1 << 1)
 
 #endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO memory port register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__
+
+#define S3C64XX_MEM0CONSTOP	S3C64XX_GPIOREG(0x1B0)
+#define S3C64XX_MEM1CONSTOP	S3C64XX_GPIOREG(0x1B4)
+
+#define S3C64XX_MEM0CONSLP0	S3C64XX_GPIOREG(0x1C0)
+#define S3C64XX_MEM0CONSLP1	S3C64XX_GPIOREG(0x1C4)
+#define S3C64XX_MEM1CONSLP	S3C64XX_GPIOREG(0x1C8)
+
+#define S3C64XX_MEM0DRVCON	S3C64XX_GPIOREG(0x1D0)
+#define S3C64XX_MEM1DRVCON	S3C64XX_GPIOREG(0x1D4)
+
+#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-modem.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - modem block registers
+ *
+ * This program is free software; you can 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 __PLAT_S3C64XX_REGS_MODEM_H
+#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__
+
+#define S3C64XX_MODEMREG(x)	(S3C64XX_VA_MODEM + (x))
+
+#define S3C64XX_MODEM_INT2AP			S3C64XX_MODEMREG(0x0)
+#define S3C64XX_MODEM_INT2MODEM			S3C64XX_MODEMREG(0x4)
+#define S3C64XX_MODEM_MIFCON			S3C64XX_MODEMREG(0x8)
+#define S3C64XX_MODEM_MIFPCON			S3C64XX_MODEMREG(0xC)
+#define S3C64XX_MODEM_INTCLR			S3C64XX_MODEMREG(0x10)
+#define S3C64XX_MODEM_DMA_TXADDR		S3C64XX_MODEMREG(0x14)
+#define S3C64XX_MODEM_DMA_RXADDR		S3C64XX_MODEMREG(0x18)
+
+#define MIFPCON_INT2M_LEVEL			(1 << 4)
+#define MIFPCON_LCD_BYPASS			(1 << 3)
+
+#endif /* __PLAT_S3C64XX_REGS_MODEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - syscon power and sleep control registers
+ *
+ * This program is free software; you can 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 __PLAT_S3C64XX_REGS_SYSCON_POWER_H
+#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__
+
+#define S3C64XX_PWR_CFG				S3C_SYSREG(0x804)
+
+#define S3C64XX_PWRCFG_OSC_OTG_DISABLE		(1 << 17)
+#define S3C64XX_PWRCFG_MMC2_DISABLE		(1 << 16)
+#define S3C64XX_PWRCFG_MMC1_DISABLE		(1 << 15)
+#define S3C64XX_PWRCFG_MMC0_DISABLE		(1 << 14)
+#define S3C64XX_PWRCFG_HSI_DISABLE		(1 << 13)
+#define S3C64XX_PWRCFG_TS_DISABLE		(1 << 12)
+#define S3C64XX_PWRCFG_RTC_TICK_DISABLE		(1 << 11)
+#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE	(1 << 10)
+#define S3C64XX_PWRCFG_MSM_DISABLE		(1 << 9)
+#define S3C64XX_PWRCFG_KEY_DISABLE		(1 << 8)
+#define S3C64XX_PWRCFG_BATF_DISABLE		(1 << 7)
+
+#define S3C64XX_PWRCFG_CFG_WFI_MASK		(0x3 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SHIFT		(5)
+#define S3C64XX_PWRCFG_CFG_WFI_IGNORE		(0x0 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_IDLE		(0x1 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_STOP		(0x2 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SLEEP		(0x3 << 5)
+
+#define S3C64XX_PWRCFG_CFG_BATFLT_MASK		(0x3 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT		(3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE	(0x0 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ		(0x1 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP		(0x3 << 3)
+
+#define S3C64XX_PWRCFG_CFG_BAT_WAKE		(1 << 2)
+#define S3C64XX_PWRCFG_OSC27_EN			(1 << 0)
+
+#define S3C64XX_EINT_MASK			S3C_SYSREG(0x808)
+
+#define S3C64XX_NORMAL_CFG			S3C_SYSREG(0x810)
+
+#define S3C64XX_NORMALCFG_IROM_ON		(1 << 30)
+#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON		(1 << 16)
+#define S3C64XX_NORMALCFG_DOMAIN_S_ON		(1 << 15)
+#define S3C64XX_NORMALCFG_DOMAIN_F_ON		(1 << 14)
+#define S3C64XX_NORMALCFG_DOMAIN_P_ON		(1 << 13)
+#define S3C64XX_NORMALCFG_DOMAIN_I_ON		(1 << 12)
+#define S3C64XX_NORMALCFG_DOMAIN_G_ON		(1 << 10)
+#define S3C64XX_NORMALCFG_DOMAIN_V_ON		(1 << 9)
+
+#define S3C64XX_STOP_CFG			S3C_SYSREG(0x814)
+
+#define S3C64XX_STOPCFG_MEMORY_ARM_ON		(1 << 29)
+#define S3C64XX_STOPCFG_TOP_MEMORY_ON		(1 << 20)
+#define S3C64XX_STOPCFG_ARM_LOGIC_ON		(1 << 17)
+#define S3C64XX_STOPCFG_TOP_LOGIC_ON		(1 << 8)
+#define S3C64XX_STOPCFG_OSC_EN			(1 << 0)
+
+#define S3C64XX_SLEEP_CFG			S3C_SYSREG(0x818)
+
+#define S3C64XX_SLEEPCFG_OSC_EN			(1 << 0)
+
+#define S3C64XX_STOP_MEM_CFG			S3C_SYSREG(0x81c)
+
+#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN	(1 << 6)
+#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN	(1 << 5)
+#define S3C64XX_STOPMEMCFG_OTG_RETAIN		(1 << 4)
+#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN		(1 << 3)
+#define S3C64XX_STOPMEMCFG_IROM_RETAIN		(1 << 2)
+#define S3C64XX_STOPMEMCFG_IRDA_RETAIN		(1 << 1)
+#define S3C64XX_STOPMEMCFG_NFCON_RETAIN		(1 << 0)
+
+#define S3C64XX_OSC_STABLE			S3C_SYSREG(0x824)
+#define S3C64XX_PWR_STABLE			S3C_SYSREG(0x828)
+
+#define S3C64XX_WAKEUP_STAT			S3C_SYSREG(0x908)
+
+#define S3C64XX_WAKEUPSTAT_MMC2			(1 << 11)
+#define S3C64XX_WAKEUPSTAT_MMC1			(1 << 10)
+#define S3C64XX_WAKEUPSTAT_MMC0			(1 << 9)
+#define S3C64XX_WAKEUPSTAT_HSI			(1 << 8)
+#define S3C64XX_WAKEUPSTAT_BATFLT		(1 << 6)
+#define S3C64XX_WAKEUPSTAT_MSM			(1 << 5)
+#define S3C64XX_WAKEUPSTAT_KEY			(1 << 4)
+#define S3C64XX_WAKEUPSTAT_TS			(1 << 3)
+#define S3C64XX_WAKEUPSTAT_RTC_TICK		(1 << 2)
+#define S3C64XX_WAKEUPSTAT_RTC_ALARM		(1 << 1)
+#define S3C64XX_WAKEUPSTAT_EINT			(1 << 0)
+
+#define S3C64XX_BLK_PWR_STAT			S3C_SYSREG(0x90c)
+
+#define S3C64XX_BLKPWRSTAT_G			(1 << 7)
+#define S3C64XX_BLKPWRSTAT_ETM			(1 << 6)
+#define S3C64XX_BLKPWRSTAT_S			(1 << 5)
+#define S3C64XX_BLKPWRSTAT_F			(1 << 4)
+#define S3C64XX_BLKPWRSTAT_P			(1 << 3)
+#define S3C64XX_BLKPWRSTAT_I			(1 << 2)
+#define S3C64XX_BLKPWRSTAT_V			(1 << 1)
+#define S3C64XX_BLKPWRSTAT_TOP			(1 << 0)
+
+#define S3C64XX_INFORM0				S3C_SYSREG(0xA00)
+#define S3C64XX_INFORM1				S3C_SYSREG(0xA04)
+#define S3C64XX_INFORM2				S3C_SYSREG(0xA08)
+#define S3C64XX_INFORM3				S3C_SYSREG(0xA0C)
+
+#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/include/plat/regs-sys.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,10 @@
 
 #define S3C_SYSREG(x)		(S3C_VA_SYS + (x))
 
+#define S3C64XX_AHB_CON0	S3C_SYSREG(0x100)
+#define S3C64XX_AHB_CON1	S3C_SYSREG(0x104)
+#define S3C64XX_AHB_CON2	S3C_SYSREG(0x108)
+
 #define S3C64XX_OTHERS		S3C_SYSREG(0x900)
 
 #define S3C64XX_OTHERS_USBMASK	(1 << 16)
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/irq-eint.c linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/irq-eint.c
--- linux-libre-2.6.29-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/plat-s3c64xx/irq-eint.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,20 +27,6 @@
 #include <mach/map.h>
 #include <plat/cpu.h>
 
-/* GPIO is 0x7F008xxx, */
-#define S3C64XX_GPIOREG(x)	(S3C64XX_VA_GPIO + (x))
-
-#define S3C64XX_EINT0CON0	S3C64XX_GPIOREG(0x900)
-#define S3C64XX_EINT0CON1	S3C64XX_GPIOREG(0x904)
-#define S3C64XX_EINT0FLTCON0	S3C64XX_GPIOREG(0x910)
-#define S3C64XX_EINT0FLTCON1	S3C64XX_GPIOREG(0x914)
-#define S3C64XX_EINT0FLTCON2	S3C64XX_GPIOREG(0x918)
-#define S3C64XX_EINT0FLTCON3	S3C64XX_GPIOREG(0x91C)
-
-#define S3C64XX_EINT0MASK	S3C64XX_GPIOREG(0x920)
-#define S3C64XX_EINT0PEND	S3C64XX_GPIOREG(0x924)
-
-
 #define eint_offset(irq)	((irq) - IRQ_EINT(0))
 #define eint_irq_to_bit(irq)	(1 << eint_offset(irq))
 
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/tools/mach-types linux-libre-2.6.30-gnu1/arch/arm/tools/mach-types
--- linux-libre-2.6.29-gnu1/arch/arm/tools/mach-types	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/tools/mach-types	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Thu Mar 12 18:01:45 2009
+# Last update: Fri May 29 10:14:20 2009
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -916,7 +916,7 @@ nxdb500			MACH_NXDB500		NXDB500			905
 apf9328			MACH_APF9328		APF9328			906
 omap_wipoq		MACH_OMAP_WIPOQ		OMAP_WIPOQ		907
 omap_twip		MACH_OMAP_TWIP		OMAP_TWIP		908
-palmt650		MACH_PALMT650		PALMT650		909
+treo650			MACH_TREO650		TREO650			909
 acumen			MACH_ACUMEN		ACUMEN			910
 xp100			MACH_XP100		XP100			911
 fs2410			MACH_FS2410		FS2410			912
@@ -1232,7 +1232,7 @@ ql202b			MACH_QL202B		QL202B			1226
 vpac270			MACH_VPAC270		VPAC270			1227
 rd129			MACH_RD129		RD129			1228
 htcwizard		MACH_HTCWIZARD		HTCWIZARD		1229
-xscale_treo680		MACH_XSCALE_TREO680	XSCALE_TREO680		1230
+treo680			MACH_TREO680		TREO680			1230
 tecon_tmezon		MACH_TECON_TMEZON	TECON_TMEZON		1231
 zylonite		MACH_ZYLONITE		ZYLONITE		1233
 gene1270		MACH_GENE1270		GENE1270		1234
@@ -1418,10 +1418,10 @@ looxc550		MACH_LOOXC550		LOOXC550		1417
 cnty_titan		MACH_CNTY_TITAN		CNTY_TITAN		1418
 app3xx			MACH_APP3XX		APP3XX			1419
 sideoatsgrama		MACH_SIDEOATSGRAMA	SIDEOATSGRAMA		1420
-palmtreo700p		MACH_PALMTREO700P	PALMTREO700P		1421
-palmtreo700w		MACH_PALMTREO700W	PALMTREO700W		1422
-palmtreo750		MACH_PALMTREO750	PALMTREO750		1423
-palmtreo755p		MACH_PALMTREO755P	PALMTREO755P		1424
+treo700p		MACH_TREO700P		TREO700P		1421
+treo700w		MACH_TREO700W		TREO700W		1422
+treo750			MACH_TREO750		TREO750			1423
+treo755p		MACH_TREO755P		TREO755P		1424
 ezreganut9200		MACH_EZREGANUT9200	EZREGANUT9200		1425
 sarge			MACH_SARGE		SARGE			1426
 a696			MACH_A696		A696			1427
@@ -1721,7 +1721,7 @@ sapphire		MACH_SAPPHIRE		SAPPHIRE		1729
 csb637xo		MACH_CSB637XO		CSB637XO		1730
 evisiong		MACH_EVISIONG		EVISIONG		1731
 stmp37xx		MACH_STMP37XX		STMP37XX		1732
-stmp378x		MACH_STMP38XX		STMP38XX		1733
+stmp378x		MACH_STMP378X		STMP378X		1733
 tnt			MACH_TNT		TNT			1734
 tbxt			MACH_TBXT		TBXT			1735
 playmate		MACH_PLAYMATE		PLAYMATE		1736
@@ -1817,7 +1817,7 @@ smdkc100		MACH_SMDKC100		SMDKC100		1826
 tavorevb		MACH_TAVOREVB		TAVOREVB		1827
 saar			MACH_SAAR		SAAR			1828
 deister_eyecam		MACH_DEISTER_EYECAM	DEISTER_EYECAM		1829
-at91sam9m10ek		MACH_AT91SAM9M10EK	AT91SAM9M10EK		1830
+at91sam9m10g45ek	MACH_AT91SAM9M10G45EK	AT91SAM9M10G45EK	1830
 linkstation_produo	MACH_LINKSTATION_PRODUO	LINKSTATION_PRODUO	1831
 hit_b0			MACH_HIT_B0		HIT_B0			1832
 adx_rmu			MACH_ADX_RMU		ADX_RMU			1833
@@ -2124,3 +2124,124 @@ mx27wallace		MACH_MX27WALLACE	MX27WALLAC
 fmzwebmodul		MACH_FMZWEBMODUL	FMZWEBMODUL		2134
 rd78x00_masa		MACH_RD78X00_MASA	RD78X00_MASA		2135
 smallogger		MACH_SMALLOGGER		SMALLOGGER		2136
+ccw9p9215		MACH_CCW9P9215		CCW9P9215		2137
+dm355_leopard		MACH_DM355_LEOPARD	DM355_LEOPARD		2138
+ts219			MACH_TS219		TS219			2139
+tny_a9263		MACH_TNY_A9263		TNY_A9263		2140
+apollo			MACH_APOLLO		APOLLO			2141
+at91cap9stk		MACH_AT91CAP9STK	AT91CAP9STK		2142
+spc300			MACH_SPC300		SPC300			2143
+eko			MACH_EKO		EKO			2144
+ccw9m2443		MACH_CCW9M2443		CCW9M2443		2145
+ccw9m2443js		MACH_CCW9M2443JS	CCW9M2443JS		2146
+m2m_router_device	MACH_M2M_ROUTER_DEVICE	M2M_ROUTER_DEVICE	2147
+str9104nas		MACH_STAR9104NAS	STAR9104NAS		2148
+pca100			MACH_PCA100		PCA100			2149
+z3_dm365_mod_01		MACH_Z3_DM365_MOD_01	Z3_DM365_MOD_01		2150
+hipox			MACH_HIPOX		HIPOX			2151
+omap3_piteds		MACH_OMAP3_PITEDS	OMAP3_PITEDS		2152
+bm150r			MACH_BM150R		BM150R			2153
+tbone			MACH_TBONE		TBONE			2154
+merlin			MACH_MERLIN		MERLIN			2155
+falcon			MACH_FALCON		FALCON			2156
+davinci_da850_evm	MACH_DAVINCI_DA850_EVM	DAVINCI_DA850_EVM	2157
+s5p6440			MACH_S5P6440		S5P6440			2158
+at91sam9g10ek		MACH_AT91SAM9G10EK	AT91SAM9G10EK		2159
+omap_4430sdp		MACH_OMAP_4430SDP	OMAP_4430SDP		2160
+lpc313x			MACH_LPC313X		LPC313X			2161
+magx_zn5		MACH_MAGX_ZN5		MAGX_ZN5		2162
+magx_em30		MACH_MAGX_EM30		MAGX_EM30		2163
+magx_ve66		MACH_MAGX_VE66		MAGX_VE66		2164
+meesc			MACH_MEESC		MEESC			2165
+otc570			MACH_OTC570		OTC570			2166
+bcu2412			MACH_BCU2412		BCU2412			2167
+beacon			MACH_BEACON		BEACON			2168
+actia_tgw		MACH_ACTIA_TGW		ACTIA_TGW		2169
+e4430			MACH_E4430		E4430			2170
+ql300			MACH_QL300		QL300			2171
+btmavb101		MACH_BTMAVB101		BTMAVB101		2172
+btmawb101		MACH_BTMAWB101		BTMAWB101		2173
+sq201			MACH_SQ201		SQ201			2174
+quatro45xx		MACH_QUATRO45XX		QUATRO45XX		2175
+openpad			MACH_OPENPAD		OPENPAD			2176
+tx25			MACH_TX25		TX25			2177
+omap3_torpedo		MACH_OMAP3_TORPEDO	OMAP3_TORPEDO		2178
+htcraphael_k		MACH_HTCRAPHAEL_K	HTCRAPHAEL_K		2179
+lal43			MACH_LAL43		LAL43			2181
+htcraphael_cdma500	MACH_HTCRAPHAEL_CDMA500	HTCRAPHAEL_CDMA500	2182
+anw6410			MACH_ANW6410		ANW6410			2183
+htcprophet		MACH_HTCPROPHET		HTCPROPHET		2185
+cfa_10022		MACH_CFA_10022		CFA_10022		2186
+imx27_visstrim_m10	MACH_IMX27_VISSTRIM_M10	IMX27_VISSTRIM_M10	2187
+px2imx27		MACH_PX2IMX27		PX2IMX27		2188
+stm3210e_eval		MACH_STM3210E_EVAL	STM3210E_EVAL		2189
+dvs10			MACH_DVS10		DVS10			2190
+portuxg20		MACH_PORTUXG20		PORTUXG20		2191
+arm_spv			MACH_ARM_SPV		ARM_SPV			2192
+smdkc110		MACH_SMDKC110		SMDKC110		2193
+cabespresso		MACH_CABESPRESSO	CABESPRESSO		2194
+hmc800			MACH_HMC800		HMC800			2195
+sholes			MACH_SHOLES		SHOLES			2196
+btmxc31			MACH_BTMXC31		BTMXC31			2197
+dt501			MACH_DT501		DT501			2198
+ktx			MACH_KTX		KTX			2199
+omap3517evm		MACH_OMAP3517EVM	OMAP3517EVM		2200
+netspace_v2		MACH_NETSPACE_V2	NETSPACE_V2		2201
+netspace_max_v2		MACH_NETSPACE_MAX_V2	NETSPACE_MAX_V2		2202
+d2net_v2		MACH_D2NET_V2		D2NET_V2		2203
+net2big_v2		MACH_NET2BIG_V2		NET2BIG_V2		2204
+net4big_v2		MACH_NET4BIG_V2		NET4BIG_V2		2205
+net5big_v2		MACH_NET5BIG_V2		NET5BIG_V2		2206
+endb2443		MACH_ENDB2443		ENDB2443		2207
+inetspace_v2		MACH_INETSPACE_V2	INETSPACE_V2		2208
+tros			MACH_TROS		TROS			2209
+pelco_homer		MACH_PELCO_HOMER	PELCO_HOMER		2210
+ofsp8			MACH_OFSP8		OFSP8			2211
+at91sam9g45ekes		MACH_AT91SAM9G45EKES	AT91SAM9G45EKES		2212
+guf_cupid		MACH_GUF_CUPID		GUF_CUPID		2213
+eab1r			MACH_EAB1R		EAB1R			2214
+desirec			MACH_DESIREC		DESIREC			2215
+cordoba			MACH_CORDOBA		CORDOBA			2216
+irvine			MACH_IRVINE		IRVINE			2217
+sff772			MACH_SFF772		SFF772			2218
+pelco_milano		MACH_PELCO_MILANO	PELCO_MILANO		2219
+pc7302			MACH_PC7302		PC7302			2220
+bip6000			MACH_BIP6000		BIP6000			2221
+silvermoon		MACH_SILVERMOON		SILVERMOON		2222
+vc0830			MACH_VC0830		VC0830			2223
+dt430			MACH_DT430		DT430			2224
+ji42pf			MACH_JI42PF		JI42PF			2225
+gnet_ksm		MACH_GNET_KSM		GNET_KSM		2226
+gnet_sgm		MACH_GNET_SGM		GNET_SGM		2227
+gnet_sgr		MACH_GNET_SGR		GNET_SGR		2228
+omap3_icetekevm		MACH_OMAP3_ICETEKEVM	OMAP3_ICETEKEVM		2229
+pnp			MACH_PNP		PNP			2230
+ctera_2bay_k		MACH_CTERA_2BAY_K	CTERA_2BAY_K		2231
+ctera_2bay_u		MACH_CTERA_2BAY_U	CTERA_2BAY_U		2232
+sas_c			MACH_SAS_C		SAS_C			2233
+vma2315			MACH_VMA2315		VMA2315			2234
+vcs			MACH_VCS		VCS			2235
+spear600		MACH_SPEAR600		SPEAR600		2236
+spear300		MACH_SPEAR300		SPEAR300		2237
+spear1300		MACH_SPEAR1300		SPEAR1300		2238
+lilly1131		MACH_LILLY1131		LILLY1131		2239
+arvoo_ax301		MACH_ARVOO_AX301	ARVOO_AX301		2240
+mapphone		MACH_MAPPHONE		MAPPHONE		2241
+legend			MACH_LEGEND		LEGEND			2242
+salsa			MACH_SALSA		SALSA			2243
+lounge			MACH_LOUNGE		LOUNGE			2244
+vision			MACH_VISION		VISION			2245
+vmb20			MACH_VMB20		VMB20			2246
+hy2410			MACH_HY2410		HY2410			2247
+hy9315			MACH_HY9315		HY9315			2248
+bullwinkle		MACH_BULLWINKLE		BULLWINKLE		2249
+arm_ultimator2		MACH_ARM_ULTIMATOR2	ARM_ULTIMATOR2		2250
+vs_v210			MACH_VS_V210		VS_V210			2252
+vs_v212			MACH_VS_V212		VS_V212			2253
+hmt			MACH_HMT		HMT			2254
+suen3			MACH_SUEN3		SUEN3			2255
+vesper			MACH_VESPER		VESPER			2256
+str9			MACH_STR9		STR9			2257
+omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258
+simcom			MACH_SIMCOM		SIMCOM			2259
+mcwebio			MACH_MCWEBIO		MCWEBIO			2260
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/vfp/entry.S linux-libre-2.6.30-gnu1/arch/arm/vfp/entry.S
--- linux-libre-2.6.29-gnu1/arch/arm/vfp/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/vfp/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -15,13 +15,16 @@
  *  r10 = thread_info structure
  *  lr  = failure return
  */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/asm-offsets.h>
-#include <asm/assembler.h>
+#include <asm/thread_info.h>
 #include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
 
 ENTRY(do_vfp)
+#ifdef CONFIG_PREEMPT
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	add	r11, r4, #1		@ increment it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	enable_irq
  	ldr	r4, .LCvfp
 	ldr	r11, [r10, #TI_CPU]	@ CPU number
@@ -30,6 +33,12 @@ ENTRY(do_vfp)
 ENDPROC(do_vfp)
 
 ENTRY(vfp_null_entry)
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, lr
 ENDPROC(vfp_null_entry)
 
@@ -41,6 +50,12 @@ ENDPROC(vfp_null_entry)
 
 	__INIT
 ENTRY(vfp_testing_entry)
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	ldr	r0, VFP_arch_address
 	str	r5, [r0]		@ known non-zero value
 	mov	pc, r9			@ we have handled the fault
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/vfp/vfp.h linux-libre-2.6.30-gnu1/arch/arm/vfp/vfp.h
--- linux-libre-2.6.29-gnu1/arch/arm/vfp/vfp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/vfp/vfp.h	2009-06-09 23:05:27.000000000 -0400
@@ -377,6 +377,4 @@ struct op {
 	u32 flags;
 };
 
-#if defined(CONFIG_SMP) || defined(CONFIG_PM)
 extern void vfp_save_state(void *location, u32 fpexc);
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/vfp/vfphw.S linux-libre-2.6.30-gnu1/arch/arm/vfp/vfphw.S
--- linux-libre-2.6.29-gnu1/arch/arm/vfp/vfphw.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/vfp/vfphw.S	2009-06-09 23:05:27.000000000 -0400
@@ -137,6 +137,12 @@ check_for_exception:
 	VFPFMXR	FPEXC, r1		@ restore FPEXC last
 	sub	r2, r2, #4
 	str	r2, [sp, #S_PC]		@ retry the instruction
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, r9			@ we think we have handled things
 
 
@@ -155,6 +161,12 @@ look_for_VFP_exceptions:
 	@ not recognised by VFP
 
 	DBGSTR	"not VFP"
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, lr
 
 process_exception:
@@ -172,7 +184,6 @@ process_exception:
 					@ retry the faulted instruction
 ENDPROC(vfp_support_entry)
 
-#if defined(CONFIG_SMP) || defined(CONFIG_PM)
 ENTRY(vfp_save_state)
 	@ Save the current VFP state
 	@ r0 - save location
@@ -190,7 +201,6 @@ ENTRY(vfp_save_state)
 	stmia	r0, {r1, r2, r3, r12}	@ save FPEXC, FPSCR, FPINST, FPINST2
 	mov	pc, lr
 ENDPROC(vfp_save_state)
-#endif
 
 last_VFP_context_address:
 	.word	last_VFP_context
diff -druNp linux-libre-2.6.29-gnu1/arch/arm/vfp/vfpmodule.c linux-libre-2.6.30-gnu1/arch/arm/vfp/vfpmodule.c
--- linux-libre-2.6.29-gnu1/arch/arm/vfp/vfpmodule.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/arm/vfp/vfpmodule.c	2009-06-09 23:05:27.000000000 -0400
@@ -266,7 +266,7 @@ void VFP_bounce(u32 trigger, u32 fpexc,
 		 * on VFP subarch 1.
 		 */
 		 vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
-		 return;
+		goto exit;
 	}
 
 	/*
@@ -297,7 +297,7 @@ void VFP_bounce(u32 trigger, u32 fpexc,
 	 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
 	 */
 	if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
-		return;
+		goto exit;
 
 	/*
 	 * The barrier() here prevents fpinst2 being read
@@ -310,6 +310,8 @@ void VFP_bounce(u32 trigger, u32 fpexc,
 	exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
 	if (exceptions)
 		vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+ exit:
+	preempt_enable();
 }
 
 static void vfp_enable(void *unused)
@@ -377,6 +379,55 @@ static void vfp_pm_init(void)
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
 
+/*
+ * Synchronise the hardware VFP state of a thread other than current with the
+ * saved one. This function is used by the ptrace mechanism.
+ */
+#ifdef CONFIG_SMP
+void vfp_sync_state(struct thread_info *thread)
+{
+	/*
+	 * On SMP systems, the VFP state is automatically saved at every
+	 * context switch. We mark the thread VFP state as belonging to a
+	 * non-existent CPU so that the saved one will be reloaded when
+	 * needed.
+	 */
+	thread->vfpstate.hard.cpu = NR_CPUS;
+}
+#else
+void vfp_sync_state(struct thread_info *thread)
+{
+	unsigned int cpu = get_cpu();
+	u32 fpexc = fmrx(FPEXC);
+
+	/*
+	 * If VFP is enabled, the previous state was already saved and
+	 * last_VFP_context updated.
+	 */
+	if (fpexc & FPEXC_EN)
+		goto out;
+
+	if (!last_VFP_context[cpu])
+		goto out;
+
+	/*
+	 * Save the last VFP state on this CPU.
+	 */
+	fmxr(FPEXC, fpexc | FPEXC_EN);
+	vfp_save_state(last_VFP_context[cpu], fpexc);
+	fmxr(FPEXC, fpexc);
+
+	/*
+	 * Set the context to NULL to force a reload the next time the thread
+	 * uses the VFP.
+	 */
+	last_VFP_context[cpu] = NULL;
+
+out:
+	put_cpu();
+}
+#endif
+
 #include <linux/smp.h>
 
 /*
@@ -427,6 +478,18 @@ static int __init vfp_init(void)
 		 * in place; report VFP support to userspace.
 		 */
 		elf_hwcap |= HWCAP_VFP;
+#ifdef CONFIG_VFPv3
+		if (VFP_arch >= 3) {
+			elf_hwcap |= HWCAP_VFPv3;
+
+			/*
+			 * Check for VFPv3 D16. CPUs in this configuration
+			 * only have 16 x 64bit registers.
+			 */
+			if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
+				elf_hwcap |= HWCAP_VFPv3D16;
+		}
+#endif
 #ifdef CONFIG_NEON
 		/*
 		 * Check for the presence of the Advanced SIMD
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/atngw100/evklcd10x.c linux-libre-2.6.30-gnu1/arch/avr32/boards/atngw100/evklcd10x.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/atngw100/evklcd10x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/atngw100/evklcd10x.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/linkage.h>
+#include <linux/gpio.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 
@@ -19,26 +20,26 @@
 #include <asm/setup.h>
 
 #include <mach/at32ap700x.h>
+#include <mach/portmux.h>
 #include <mach/board.h>
 
+#include <sound/atmel-ac97c.h>
+
 static struct ac97c_platform_data __initdata ac97c0_data = {
-	.dma_rx_periph_id	= 3,
-	.dma_tx_periph_id	= 4,
-	.dma_controller_id	= 0,
-	.reset_pin		= GPIO_PIN_PB(19),
+	.reset_pin = GPIO_PIN_PB(19),
 };
 
 #ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
 static struct fb_videomode __initdata tcg057vglad_modes[] = {
 	{
-		.name		= "640x480 @ 60",
-		.refresh	= 60,
+		.name		= "640x480 @ 50",
+		.refresh	= 50,
 		.xres		= 640,		.yres		= 480,
 		.pixclock	= KHZ2PICOS(25180),
 
-		.left_margin	= 64,		.right_margin	= 31,
-		.upper_margin	= 34,		.lower_margin	= 2,
-		.hsync_len	= 96,		.vsync_len	= 4,
+		.left_margin	= 64,		.right_margin	= 96,
+		.upper_margin	= 34,		.lower_margin	= 11,
+		.hsync_len	= 64,		.vsync_len	= 15,
 
 		.sync		= 0,
 		.vmode		= FB_VMODE_NONINTERLACED,
@@ -69,14 +70,14 @@ static struct atmel_lcdfb_info __initdat
 #elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
 static struct fb_videomode __initdata tcg057qvlad_modes[] = {
 	{
-		.name		= "320x240 @ 60",
-		.refresh	= 60,
+		.name		= "320x240 @ 50",
+		.refresh	= 50,
 		.xres		= 320,		.yres		= 240,
 		.pixclock	= KHZ2PICOS(6300),
 
-		.left_margin	= 52,		.right_margin	= 28,
-		.upper_margin	= 7,		.lower_margin	= 2,
-		.hsync_len	= 96,		.vsync_len	= 4,
+		.left_margin	= 34,		.right_margin	= 46,
+		.upper_margin	= 7,		.lower_margin	= 15,
+		.hsync_len	= 64,		.vsync_len	= 12,
 
 		.sync		= 0,
 		.vmode		= FB_VMODE_NONINTERLACED,
@@ -144,12 +145,29 @@ static struct atmel_lcdfb_info __initdat
 };
 #endif
 
+static void atevklcd10x_lcdc_power_control(int on)
+{
+	gpio_set_value(GPIO_PIN_PB(15), on);
+}
+
 static int __init atevklcd10x_init(void)
 {
-	at32_add_device_ac97c(0, &ac97c0_data);
+	/* PB15 is connected to the enable line on the boost regulator
+	 * controlling the backlight for the LCD panel.
+	 */
+	at32_select_gpio(GPIO_PIN_PB(15), AT32_GPIOF_OUTPUT);
+	gpio_request(GPIO_PIN_PB(15), "backlight");
+	gpio_direction_output(GPIO_PIN_PB(15), 0);
+
+	atevklcd10x_lcdc_data.atmel_lcdfb_power_control =
+		atevklcd10x_lcdc_power_control;
 
 	at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
-			fbmem_start, fbmem_size, 1);
+			fbmem_start, fbmem_size,
+			ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL);
+
+	at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH);
+
 	return 0;
 }
 postcore_initcall(atevklcd10x_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/atngw100/setup.c linux-libre-2.6.30-gnu1/arch/avr32/boards/atngw100/setup.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/atngw100/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/atngw100/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,13 +56,8 @@ static struct spi_board_info spi0_board_
 static struct mci_platform_data __initdata mci0_data = {
 	.slot[0] = {
 		.bus_width	= 4,
-#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
 		.detect_pin	= GPIO_PIN_PC(25),
 		.wp_pin		= GPIO_PIN_PE(0),
-#else
-		.detect_pin	= GPIO_PIN_NONE,
-		.wp_pin		= GPIO_PIN_NONE,
-#endif
 	},
 };
 
@@ -123,7 +118,7 @@ static void __init set_hw_addr(struct pl
 
 void __init setup_board(void)
 {
-	at32_map_usart(1, 0);	/* USART 1: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1: /dev/ttyS0, DB9 */
 	at32_setup_serial_console(0);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1002.c linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1002.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1002.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1002.c	2009-06-09 23:05:27.000000000 -0400
@@ -252,12 +252,12 @@ static void __init atstk1002_setup_extda
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1003.c linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1003.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1003.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1003.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,12 +115,12 @@ static void __init atstk1003_setup_extda
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1004.c linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1004.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/atstk1000/atstk1004.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/atstk1000/atstk1004.c	2009-06-09 23:05:27.000000000 -0400
@@ -120,12 +120,12 @@ static void __init atstk1004_setup_extda
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/favr-32/setup.c linux-libre-2.6.30-gnu1/arch/avr32/boards/favr-32/setup.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/favr-32/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/favr-32/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,8 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
+#include <sound/atmel-abdac.h>
+
 #include <video/atmel_lcdc.h>
 
 #include <asm/setup.h>
@@ -41,6 +43,9 @@ unsigned long at32_board_osc_rates[3] =
 /* Initialized by bootloader-specific startup code. */
 struct tag *bootloader_tags __initdata;
 
+static struct atmel_abdac_pdata __initdata abdac0_data = {
+};
+
 struct eth_addr {
 	u8 addr[6];
 };
@@ -245,7 +250,7 @@ static void __init favr32_setup_atmel_pw
 
 void __init setup_board(void)
 {
-	at32_map_usart(3, 0);	/* USART 3 => /dev/ttyS0 */
+	at32_map_usart(3, 0, 0);	/* USART 3 => /dev/ttyS0 */
 	at32_setup_serial_console(0);
 }
 
@@ -326,7 +331,7 @@ static int __init favr32_init(void)
 
 	spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
 
-	set_abdac_rate(at32_add_device_abdac(0));
+	set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
 
 	at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
 	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/hammerhead/flash.c linux-libre-2.6.30-gnu1/arch/avr32/boards/hammerhead/flash.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/hammerhead/flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/hammerhead/flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/mtd/physmap.h>
 #include <linux/usb/isp116x.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
 #include <linux/delay.h>
 
 #include <mach/portmux.h>
@@ -281,13 +280,13 @@ static struct resource hh_fpga0_resource
 	},
 };
 
-static u64 hh_fpga0_dma_mask = DMA_32BIT_MASK;
+static u64 hh_fpga0_dma_mask = DMA_BIT_MASK(32);
 static struct platform_device hh_fpga0_device = {
 	.name		= "hh_fpga",
 	.id		= 0,
 	.dev		= {
 		.dma_mask = &hh_fpga0_dma_mask,
-		.coherent_dma_mask = DMA_32BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.resource	= hh_fpga0_resource,
 	.num_resources	= ARRAY_SIZE(hh_fpga0_resource),
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/hammerhead/setup.c linux-libre-2.6.30-gnu1/arch/avr32/boards/hammerhead/setup.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/hammerhead/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/hammerhead/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,8 @@
 #include <mach/init.h>
 #include <mach/portmux.h>
 
+#include <sound/atmel-ac97c.h>
+
 #include "../../mach-at32ap/clock.h"
 #include "flash.h"
 
@@ -163,7 +165,7 @@ static void __init set_hw_addr(struct pl
 
 void __init setup_board(void)
 {
-	at32_map_usart(1, 0);	/* USART 1: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1: /dev/ttyS0, DB9 */
 	at32_setup_serial_console(0);
 }
 
@@ -233,7 +235,7 @@ static int __init hammerhead_init(void)
 	i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
 
 #ifdef CONFIG_BOARD_HAMMERHEAD_SND
-	at32_add_device_ac97c(0, &ac97c_data);
+	at32_add_device_ac97c(0, &ac97c_data, AC97C_BOTH);
 #endif
 
 	/* Select the Touchscreen interrupt pin mode */
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/display.c linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/display.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/display.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/display.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * Display setup code for the Merisc board
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+#include <asm/setup.h>
+#include <mach/board.h>
+#include "merisc.h"
+
+static struct fb_videomode merisc_fb_videomode[] = {
+	{
+		.refresh	= 44,
+		.xres		= 640,
+		.yres		= 480,
+		.left_margin	= 96,
+		.right_margin	= 96,
+		.upper_margin	= 34,
+		.lower_margin	= 8,
+		.hsync_len	= 64,
+		.vsync_len	= 64,
+		.name		= "640x480 @ 44",
+		.pixclock	= KHZ2PICOS(25180),
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct fb_monspecs merisc_fb_monspecs = {
+	.manufacturer	= "Kyo",
+	.monitor	= "TCG075VG2AD",
+	.modedb		= merisc_fb_videomode,
+	.modedb_len	= ARRAY_SIZE(merisc_fb_videomode),
+	.hfmin		= 30000,
+	.hfmax		= 33333,
+	.vfmin		= 60,
+	.vfmax		= 90,
+	.dclkmax	= 30000000,
+};
+
+struct atmel_lcdfb_info merisc_lcdc_data = {
+	.default_bpp		= 24,
+	.default_dmacon		= ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+	.default_lcdcon2	= (ATMEL_LCDC_DISTYPE_TFT
+				   | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+				   | ATMEL_LCDC_MEMOR_BIG),
+	.default_monspecs	= &merisc_fb_monspecs,
+	.guard_time		= 2,
+};
+
+static int __init merisc_display_init(void)
+{
+	at32_add_device_lcdc(0, &merisc_lcdc_data, fbmem_start,
+			     fbmem_size, 0);
+
+	return 0;
+}
+device_initcall(merisc_display_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/flash.c linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/flash.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,139 @@
+/*
+ * Merisc board-specific flash initialization
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mach/smc.h>
+
+/* Will be translated to units of 14.3 ns, rounded up */
+static struct smc_timing flash_timing __initdata = {
+	.ncs_read_setup		= 1 * 14,
+	.nrd_setup		= 5 * 14,
+	.ncs_write_setup	= 1 * 14,
+	.nwe_setup		= 2 * 14,
+
+	.ncs_read_pulse		= 12 * 14,
+	.nrd_pulse		= 7 * 14,
+	.ncs_write_pulse	= 8 * 14,
+	.nwe_pulse		= 4 * 14,
+
+	.read_cycle		= 14 * 14,
+	.write_cycle		= 10 * 14,
+};
+
+static struct smc_config flash_config __initdata = {
+	.bus_width	= 2,
+	.nrd_controlled	= 1,
+	.nwe_controlled	= 1,
+	.byte_write	= 1,
+	.tdf_cycles	= 3,
+};
+
+static struct mtd_partition flash_0_parts[] = {
+	{
+		.name		= "boot",
+		.offset		= 0x00000000,
+		.size		= 0x00060000,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "kernel",
+		.offset		= 0x00060000,
+		.size		= 0x00200000,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "root",
+		.offset		= 0x00260000,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static struct mtd_partition flash_1_parts[] = {
+	{
+		.name		= "2ndflash",
+		.offset		= 0x00000000,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static struct physmap_flash_data flash_data[] = {
+	{
+		.width		= 2,
+		.nr_parts	= ARRAY_SIZE(flash_0_parts),
+		.parts		= flash_0_parts,
+	},
+	{
+		.width		= 2,
+		.nr_parts	= ARRAY_SIZE(flash_1_parts),
+		.parts		= flash_1_parts,
+	}
+};
+
+static struct resource flash_resource[] = {
+	{
+		.start		= 0x00000000,
+		.end		= 0x03ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 0x04000000,
+		.end		= 0x07ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device flash_device[] = {
+	{
+		.name		= "physmap-flash",
+		.id		= 0,
+		.resource	= &flash_resource[0],
+		.num_resources	= 1,
+		.dev		= {
+			.platform_data	= &flash_data[0],
+		},
+	},
+	{
+		.name		= "physmap-flash",
+		.id		= 1,
+		.resource	= &flash_resource[1],
+		.num_resources	= 1,
+		.dev		= {
+			.platform_data	= &flash_data[1],
+		},
+	},
+};
+
+static int __init merisc_flash_init(void)
+{
+	int ret;
+	smc_set_timing(&flash_config, &flash_timing);
+
+	ret = smc_set_configuration(0, &flash_config);
+	if (ret < 0) {
+		printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n");
+		return ret;
+	}
+
+	ret = smc_set_configuration(4, &flash_config);
+	if (ret < 0) {
+		printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n");
+		return ret;
+	}
+
+	platform_device_register(&flash_device[0]);
+	platform_device_register(&flash_device[1]);
+	return 0;
+}
+device_initcall(merisc_flash_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/Kconfig linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/Kconfig
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,5 @@
+# Merisc customization
+
+if BOARD_MERISC
+
+endif	# BOARD_MERISC
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/Makefile linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/Makefile
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+obj-y					+= setup.o flash.o display.o merisc_sysfs.o
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/merisc.h linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/merisc.h
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/merisc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/merisc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Merisc exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can 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_AVR32_BOARDS_MERISC_MERISC_H
+#define __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+
+const char *merisc_revision(void);
+const char *merisc_model(void);
+
+extern struct class merisc_class;
+
+#endif /* __ARCH_AVR32_BOARDS_MERISC_MERISC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/merisc_sysfs.c linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/merisc_sysfs.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/merisc_sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/merisc_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * Merisc sysfs exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include "merisc.h"
+
+static ssize_t merisc_model_show(struct class *class, char *buf)
+{
+	ssize_t ret = 0;
+
+	sprintf(buf, "%s\n", merisc_model());
+	ret = strlen(buf) + 1;
+
+	return ret;
+}
+
+static ssize_t merisc_revision_show(struct class *class, char *buf)
+{
+	ssize_t ret = 0;
+
+	sprintf(buf, "%s\n", merisc_revision());
+	ret = strlen(buf) + 1;
+
+	return ret;
+}
+
+static struct class_attribute merisc_class_attrs[] = {
+	__ATTR(model, S_IRUGO, merisc_model_show, NULL),
+	__ATTR(revision, S_IRUGO, merisc_revision_show, NULL),
+	__ATTR_NULL,
+};
+
+struct class merisc_class = {
+	.name =		"merisc",
+	.owner =	THIS_MODULE,
+	.class_attrs =	merisc_class_attrs,
+};
+
+static int __init merisc_sysfs_init(void)
+{
+	int status;
+
+	status = class_register(&merisc_class);
+	if (status < 0)
+		return status;
+
+	return 0;
+}
+
+postcore_initcall(merisc_sysfs_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/setup.c linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/setup.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/merisc/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/merisc/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,297 @@
+/*
+ * Board-specific setup code for the Merisc
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/atmel-mci.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/gpio.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+
+#include "merisc.h"
+
+/* Holds the autodetected board model and revision */
+static int merisc_board_id;
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+/* Oscillator frequencies. These are board specific */
+unsigned long at32_board_osc_rates[3] = {
+	[0]	= 32768,	/* 32.768 kHz on RTC osc */
+	[1]	= 20000000,	/* 20 MHz on osc0 */
+	[2]	= 12000000,	/* 12 MHz on osc1 */
+};
+
+struct eth_addr {
+	u8 addr[6];
+};
+
+static struct eth_addr __initdata hw_addr[2];
+static struct eth_platform_data __initdata eth_data[2];
+
+static int ads7846_get_pendown_state_PB26(void)
+{
+	return !gpio_get_value(GPIO_PIN_PB(26));
+}
+
+static int ads7846_get_pendown_state_PB28(void)
+{
+	return !gpio_get_value(GPIO_PIN_PB(28));
+}
+
+static struct ads7846_platform_data __initdata ads7846_data = {
+	.model				= 7846,
+	.vref_delay_usecs		= 100,
+	.vref_mv			= 0,
+	.keep_vref_on			= 0,
+	.settle_delay_usecs		= 150,
+	.penirq_recheck_delay_usecs	= 1,
+	.x_plate_ohms			= 800,
+	.debounce_rep			= 4,
+	.debounce_max			= 10,
+	.debounce_tol			= 50,
+	.get_pendown_state		= ads7846_get_pendown_state_PB26,
+	.filter_init			= NULL,
+	.filter				= NULL,
+	.filter_cleanup			= NULL,
+};
+
+static struct spi_board_info __initdata spi0_board_info[] = {
+	{
+		.modalias	= "ads7846",
+		.max_speed_hz	= 3250000,
+		.chip_select	= 0,
+		.bus_num	= 0,
+		.platform_data	= &ads7846_data,
+		.mode		= SPI_MODE_0,
+	},
+};
+
+static struct mci_platform_data __initdata mci0_data = {
+	.slot[0] = {
+		.bus_width	= 4,
+		.detect_pin	= GPIO_PIN_PE(19),
+		.wp_pin		= GPIO_PIN_PE(20),
+	},
+};
+
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+	int i;
+
+	i = tag->u.ethernet.mac_index;
+	if (i < ARRAY_SIZE(hw_addr)) {
+		memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+		       sizeof(hw_addr[i].addr));
+	}
+
+	return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	const u8 *addr;
+	void __iomem *regs;
+	struct clk *pclk;
+
+	if (!res)
+		return;
+
+	if (pdev->id >= ARRAY_SIZE(hw_addr))
+		return;
+
+	addr = hw_addr[pdev->id].addr;
+	if (!is_valid_ether_addr(addr))
+		return;
+
+	regs = (void __iomem __force *)res->start;
+	pclk = clk_get(&pdev->dev, "pclk");
+	if (!pclk)
+		return;
+
+	clk_enable(pclk);
+	__raw_writel((addr[3] << 24) | (addr[2] << 16)
+		     | (addr[1] << 8) | addr[0], regs + 0x98);
+	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+	clk_disable(pclk);
+	clk_put(pclk);
+}
+
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+	.sda_pin		= GPIO_PIN_PA(6),
+	.scl_pin		= GPIO_PIN_PA(7),
+	.sda_is_open_drain	= 1,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,
+};
+
+static struct platform_device i2c_gpio_device = {
+	.name	= "i2c-gpio",
+	.id	= 0,
+	.dev	= {
+		.platform_data	= &i2c_gpio_data,
+	},
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51)
+	},
+};
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+static struct gpio_led stk_pwm_led[] = {
+	{
+		.name	= "backlight",
+		.gpio	= 0,		/* PWM channel 0 (LCD backlight) */
+	},
+};
+
+static struct gpio_led_platform_data stk_pwm_led_data = {
+	.num_leds	= ARRAY_SIZE(stk_pwm_led),
+	.leds		= stk_pwm_led,
+};
+
+static struct platform_device stk_pwm_led_dev = {
+	.name	= "leds-atmel-pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &stk_pwm_led_data,
+	},
+};
+#endif
+
+const char *merisc_model(void)
+{
+	switch (merisc_board_id) {
+	case 0:
+	case 1:
+		return "500-01";
+	case 2:
+		return "BT";
+	default:
+		return "Unknown";
+	}
+}
+
+const char *merisc_revision(void)
+{
+	switch (merisc_board_id) {
+	case 0:
+		return "B";
+	case 1:
+		return "D";
+	case 2:
+		return "A";
+	default:
+		return "Unknown";
+	}
+}
+
+static void detect_merisc_board_id(void)
+{
+	/* Board ID pins MUST be set as input or the board may be damaged */
+	at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);
+
+	merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
+		!gpio_get_value(GPIO_PIN_PA(25)) * 2 +
+		!gpio_get_value(GPIO_PIN_PA(26)) * 4 +
+		!gpio_get_value(GPIO_PIN_PA(27)) * 8;
+}
+
+void __init setup_board(void)
+{
+	at32_map_usart(0, 0, 0);
+	at32_map_usart(1, 1, 0);
+	at32_map_usart(3, 3, 0);
+	at32_setup_serial_console(1);
+}
+
+static int __init merisc_init(void)
+{
+	detect_merisc_board_id();
+
+	printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
+	       merisc_revision());
+
+	/* Reserve pins for SDRAM */
+	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));
+
+	if (merisc_board_id >= 1)
+		at32_map_usart(2, 2, 0);
+
+	at32_add_device_usart(0);
+	at32_add_device_usart(1);
+	if (merisc_board_id >= 1)
+		at32_add_device_usart(2);
+	at32_add_device_usart(3);
+	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+
+	/* ADS7846 PENIRQ */
+	if (merisc_board_id == 0) {
+		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
+		at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
+				   GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
+		spi0_board_info[0].irq = AT32_EXTINT(1);
+	} else {
+		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
+		at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
+				   AT32_GPIOF_PULLUP);
+		spi0_board_info[0].irq = AT32_EXTINT(3);
+	}
+
+	/* ADS7846 busy pin */
+	at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);
+
+	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+	at32_add_device_mci(0, &mci0_data);
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+	at32_add_device_pwm((1 << 0) | (1 << 2));
+	platform_device_register(&stk_pwm_led_dev);
+#else
+	at32_add_device_pwm((1 << 2));
+#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,
+		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+	platform_device_register(&i2c_gpio_device);
+
+	i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
+
+	return 0;
+}
+postcore_initcall(merisc_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/boards/mimc200/setup.c linux-libre-2.6.30-gnu1/arch/avr32/boards/mimc200/setup.c
--- linux-libre-2.6.29-gnu1/arch/avr32/boards/mimc200/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/boards/mimc200/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -175,10 +175,10 @@ static void __init set_hw_addr(struct pl
 
 void __init setup_board(void)
 {
-	at32_map_usart(0, 0);	/* USART 0: /dev/ttyS0 (TTL --> Altera) */
-	at32_map_usart(1, 1);	/* USART 1: /dev/ttyS1 (RS232) */
-	at32_map_usart(2, 2);	/* USART 2: /dev/ttyS2 (RS485) */
-	at32_map_usart(3, 3);	/* USART 3: /dev/ttyS3 (RS422 Multidrop) */
+	at32_map_usart(0, 0, 0);	/* USART 0: /dev/ttyS0 (TTL --> Altera) */
+	at32_map_usart(1, 1, 0);	/* USART 1: /dev/ttyS1 (RS232) */
+	at32_map_usart(2, 2, 0);	/* USART 2: /dev/ttyS2 (RS485) */
+	at32_map_usart(3, 3, 0);	/* USART 3: /dev/ttyS3 (RS422 Multidrop) */
 }
 
 static struct i2c_gpio_platform_data i2c_gpio_data = {
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/configs/merisc_defconfig linux-libre-2.6.30-gnu1/arch/avr32/configs/merisc_defconfig
--- linux-libre-2.6.29-gnu1/arch/avr32/configs/merisc_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/configs/merisc_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1237 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc1
+# Wed Mar 25 14:06:15 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"
+
+#
+# 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_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+# 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
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=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_CLK=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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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=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_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_FREEZER is not set
+
+#
+# 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_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_MERISC=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_AP700X_32_BIT_SMC=y
+# CONFIG_AP700X_16_BIT_SMC is not set
+# 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_NODE 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_UNEVICTABLE_LRU=y
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_NMI_DEBUGGING is not set
+# 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 is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# 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_COMPAT_NET_DEV_OPS=y
+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 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_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=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES 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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER 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=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_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 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=y
+
+#
+# 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 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
+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 is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE 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_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT 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
+
+#
+# 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_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_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
+# 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
+# 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_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_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_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=y
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# 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_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=y
+CONFIG_I2C_BOARDINFO=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_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_AT24 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
+# 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_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_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=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
+
+#
+# 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 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_AT32AP700X_WDT 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_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
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=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
+# 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_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+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 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
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+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 also be needed;
+#
+# 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 is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=y
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# 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=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
+
+#
+# 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_RTC_DRV_AT32AP700X is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 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_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_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# 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
+
+#
+# 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_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=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_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_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_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
+# 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=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 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=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 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_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_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_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# 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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW 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_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/avr32/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/avr32/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/avr32/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/avr32/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/avr32/include/asm/hardirq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,15 +20,4 @@ void ack_bad_irq(unsigned int irq);
 
 #endif /* __ASSEMBLY__ */
 
-#define HARDIRQ_BITS	12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
 #endif /* __ASM_AVR32_HARDIRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/avr32/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/avr32/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* __ASM_AVR32_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/avr32/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/avr32/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
 #ifndef __ASM_AVR32_SWAB_H
 #define __ASM_AVR32_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 #define __SWAB_64_THRU_32__
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/avr32/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/avr32/include/asm/uaccess.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -230,10 +230,10 @@ extern int __put_user_bad(void);
 	asm volatile(							\
 		"1:	ld." suffix "	%1, %3			\n"	\
 		"2:						\n"	\
-		"	.section .fixup, \"ax\"			\n"	\
+		"	.subsection 1				\n"	\
 		"3:	mov	%0, %4				\n"	\
 		"	rjmp	2b				\n"	\
-		"	.previous				\n"	\
+		"	.subsection 0				\n"	\
 		"	.section __ex_table, \"a\"		\n"	\
 		"	.long	1b, 3b				\n"	\
 		"	.previous				\n"	\
@@ -295,10 +295,10 @@ extern int __put_user_bad(void);
 	asm volatile(							\
 		"1:	st." suffix "	%1, %3			\n"	\
 		"2:						\n"	\
-		"	.section .fixup, \"ax\"			\n"	\
+		"	.subsection 1				\n"	\
 		"3:	mov	%0, %4				\n"	\
 		"	rjmp	2b				\n"	\
-		"	.previous				\n"	\
+		"	.subsection 0				\n"	\
 		"	.section __ex_table, \"a\"		\n"	\
 		"	.long	1b, 3b				\n"	\
 		"	.previous				\n"	\
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/Kconfig linux-libre-2.6.30-gnu1/arch/avr32/Kconfig
--- linux-libre-2.6.29-gnu1/arch/avr32/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -127,13 +127,13 @@ config BOARD_HAMMERHEAD
 	select CPU_AT32AP7000
 	select USB_ARCH_HAS_HCD
 	help
-	  The Hammerhead platform is built around a AVR32 32-bit microcontroller from Atmel.
+	  The Hammerhead platform is built around an AVR32 32-bit microcontroller from Atmel.
 	  It offers versatile peripherals, such as ethernet, usb device, usb host etc.
 
-	  The board also incooperates a power supply and is a Power over Ethernet (PoE) Powered
+	  The board also incorporates a power supply and is a Power over Ethernet (PoE) Powered
 	  Device (PD).
 
-	  Additonally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
+	  Additionally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
 	  mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which
 	  will cover even the most exceptional need of memory bandwidth. Together with the onboard
 	  video decoder the board is ready for video processing.
@@ -144,6 +144,19 @@ config BOARD_FAVR_32
 	bool "Favr-32 LCD-board"
 	select CPU_AT32AP7000
 
+config BOARD_MERISC
+	bool "Merisc board"
+	select CPU_AT32AP7000
+	help
+	  Merisc is the family name for a range of AVR32-based boards.
+
+	  The boards are designed to be used in a man-machine
+	  interfacing environment, utilizing a touch-based graphical
+	  user interface. They host a vast range of I/O peripherals as
+	  well as a large SDRAM & Flash memory bank.
+
+	  For more information see: http://www.martinsson.se/merisc
+
 config BOARD_MIMC200
 	bool "MIMC200 CPU board"
 	select CPU_AT32AP7000
@@ -153,6 +166,7 @@ source "arch/avr32/boards/atstk1000/Kcon
 source "arch/avr32/boards/atngw100/Kconfig"
 source "arch/avr32/boards/hammerhead/Kconfig"
 source "arch/avr32/boards/favr-32/Kconfig"
+source "arch/avr32/boards/merisc/Kconfig"
 
 choice
 	prompt "Boot loader type"
@@ -181,7 +195,7 @@ source "kernel/Kconfig.preempt"
 config QUICKLIST
 	def_bool y
 
-config HAVE_ARCH_BOOTMEM_NODE
+config HAVE_ARCH_BOOTMEM
 	def_bool n
 
 config ARCH_HAVE_MEMORY_PRESENT
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/kernel/entry-avr32b.S linux-libre-2.6.30-gnu1/arch/avr32/kernel/entry-avr32b.S
--- linux-libre-2.6.29-gnu1/arch/avr32/kernel/entry-avr32b.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/kernel/entry-avr32b.S	2009-06-09 23:05:27.000000000 -0400
@@ -150,10 +150,10 @@ page_not_present:
 	tlbmiss_restore
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_page_fault
+	call	do_page_fault
 	rjmp	ret_from_exception
 
 	.align	2
@@ -250,7 +250,7 @@ syscall_badsys:
 
 	.global ret_from_fork
 ret_from_fork:
-	rcall   schedule_tail
+	call   schedule_tail
 
 	/* check for syscall tracing */
 	get_thread_info r0
@@ -261,7 +261,7 @@ ret_from_fork:
 
 syscall_trace_enter:
 	pushm	r8-r12
-	rcall	syscall_trace
+	call	syscall_trace
 	popm	r8-r12
 	rjmp	syscall_trace_cont
 
@@ -269,14 +269,14 @@ syscall_exit_work:
 	bld	r1, TIF_SYSCALL_TRACE
 	brcc	1f
 	unmask_interrupts
-	rcall	syscall_trace
+	call	syscall_trace
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
 
 1:	bld	r1, TIF_NEED_RESCHED
 	brcc	2f
 	unmask_interrupts
-	rcall	schedule
+	call	schedule
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
 	rjmp	1b
@@ -287,7 +287,7 @@ syscall_exit_work:
 	unmask_interrupts
 	mov	r12, sp
 	mov	r11, r0
-	rcall	do_notify_resume
+	call	do_notify_resume
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
 	rjmp	1b
@@ -394,7 +394,7 @@ handle_critical:
 
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_critical_exception
+	call	do_critical_exception
 
 	/* We should never get here... */
 bad_return:
@@ -407,18 +407,18 @@ bad_return:
 do_bus_error_write:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mov	r11, 1
 	rjmp	1f
 
 do_bus_error_read:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mov	r11, 0
 1:	mfsr	r12, SYSREG_BEAR
 	mov	r10, sp
-	rcall	do_bus_error
+	call	do_bus_error
 	rjmp	ret_from_exception
 
 	.align	1
@@ -433,7 +433,7 @@ do_nmi_ll:
 1:	pushm	r8, r9	/* PC and SR */
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_nmi
+	call	do_nmi
 	popm	r8-r9
 	mtsr	SYSREG_RAR_NMI, r8
 	tst	r0, r0
@@ -457,29 +457,29 @@ do_nmi_ll:
 handle_address_fault:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_address_exception
+	call	do_address_exception
 	rjmp	ret_from_exception
 
 handle_protection_fault:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_page_fault
+	call	do_page_fault
 	rjmp	ret_from_exception
 
 	.align	1
 do_illegal_opcode_ll:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	mfsr	r12, SYSREG_ECR
 	mov	r11, sp
-	rcall	do_illegal_opcode
+	call	do_illegal_opcode
 	rjmp	ret_from_exception
 
 do_dtlb_modified:
@@ -513,11 +513,11 @@ do_dtlb_modified:
 do_fpe_ll:
 	sub	sp, 4
 	stmts	--sp, r0-lr
-	rcall	save_full_context_ex
+	call	save_full_context_ex
 	unmask_interrupts
 	mov	r12, 26
 	mov	r11, sp
-	rcall	do_fpe
+	call	do_fpe
 	rjmp	ret_from_exception
 
 ret_from_exception:
@@ -553,7 +553,7 @@ fault_resume_kernel:
 	lddsp	r4, sp[REG_SR]
 	bld	r4, SYSREG_GM_OFFSET
 	brcs	1f
-	rcall	preempt_schedule_irq
+	call	preempt_schedule_irq
 1:
 #endif
 
@@ -582,7 +582,7 @@ fault_exit_work:
 	bld	r1, TIF_NEED_RESCHED
 	brcc	1f
 	unmask_interrupts
-	rcall	schedule
+	call	schedule
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
 	rjmp	fault_exit_work
@@ -593,7 +593,7 @@ fault_exit_work:
 	unmask_interrupts
 	mov	r12, sp
 	mov	r11, r0
-	rcall	do_notify_resume
+	call	do_notify_resume
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
 	rjmp	fault_exit_work
@@ -616,10 +616,10 @@ handle_debug:
 
 .Ldebug_fixup_cont:
 #ifdef CONFIG_TRACE_IRQFLAGS
-	rcall	trace_hardirqs_off
+	call	trace_hardirqs_off
 #endif
 	mov	r12, sp
-	rcall	do_debug
+	call	do_debug
 	mov	sp, r12
 
 	lddsp	r2, sp[REG_SR]
@@ -643,7 +643,7 @@ handle_debug:
 	mtsr	SYSREG_RSR_DBG, r11
 	mtsr	SYSREG_RAR_DBG, r10
 #ifdef CONFIG_TRACE_IRQFLAGS
-	rcall	trace_hardirqs_on
+	call	trace_hardirqs_on
 1:
 #endif
 	ldmts	sp++, r0-lr
@@ -676,7 +676,7 @@ debug_resume_kernel:
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bld	r11, SYSREG_GM_OFFSET
 	brcc	1f
-	rcall	trace_hardirqs_on
+	call	trace_hardirqs_on
 1:
 #endif
 	mfsr	r2, SYSREG_SR
@@ -747,7 +747,7 @@ irq_level\level:
 	mov	r11, sp
 	mov	r12, \level
 
-	rcall	do_IRQ
+	call	do_IRQ
 
 	lddsp	r4, sp[REG_SR]
 	bfextu	r4, r4, SYSREG_M0_OFFSET, 3
@@ -767,7 +767,7 @@ irq_level\level:
 
 1:
 #ifdef CONFIG_TRACE_IRQFLAGS
-	rcall	trace_hardirqs_on
+	call	trace_hardirqs_on
 #endif
 	popm	r8-r9
 	mtsr	rar_int\level, r8
@@ -807,7 +807,7 @@ irq_level\level:
 	lddsp	r4, sp[REG_SR]
 	bld	r4, SYSREG_GM_OFFSET
 	brcs	1b
-	rcall	preempt_schedule_irq
+	call	preempt_schedule_irq
 #endif
 	rjmp	1b
 	.endm
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/kernel/irq.c linux-libre-2.6.30-gnu1/arch/avr32/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/avr32/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,7 +58,7 @@ int show_interrupts(struct seq_file *p,
 
 		seq_printf(p, "%3d: ", i);
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 		seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/kernel/process.c linux-libre-2.6.30-gnu1/arch/avr32/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/avr32/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -332,7 +332,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 
 asmlinkage void ret_from_fork(void);
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/kernel/syscall-stubs.S linux-libre-2.6.30-gnu1/arch/avr32/kernel/syscall-stubs.S
--- linux-libre-2.6.29-gnu1/arch/avr32/kernel/syscall-stubs.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/kernel/syscall-stubs.S	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,7 @@ __sys_execve:
 __sys_mmap2:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_mmap2
+	call	sys_mmap2
 	sub	sp, -4
 	popm	pc
 
@@ -70,7 +70,7 @@ __sys_mmap2:
 __sys_sendto:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_sendto
+	call	sys_sendto
 	sub	sp, -4
 	popm	pc
 
@@ -79,7 +79,7 @@ __sys_sendto:
 __sys_recvfrom:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_recvfrom
+	call	sys_recvfrom
 	sub	sp, -4
 	popm	pc
 
@@ -88,7 +88,7 @@ __sys_recvfrom:
 __sys_pselect6:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_pselect6
+	call	sys_pselect6
 	sub	sp, -4
 	popm	pc
 
@@ -97,7 +97,7 @@ __sys_pselect6:
 __sys_splice:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_splice
+	call	sys_splice
 	sub	sp, -4
 	popm	pc
 
@@ -106,7 +106,7 @@ __sys_splice:
 __sys_epoll_pwait:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_epoll_pwait
+	call	sys_epoll_pwait
 	sub	sp, -4
 	popm	pc
 
@@ -115,6 +115,6 @@ __sys_epoll_pwait:
 __sys_sync_file_range:
 	pushm	lr
 	st.w	--sp, ARG6
-	rcall	sys_sync_file_range
+	call	sys_sync_file_range
 	sub	sp, -4
 	popm	pc
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/kernel/time.c linux-libre-2.6.30-gnu1/arch/avr32/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/avr32/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <mach/pm.h>
 
 
-static cycle_t read_cycle_count(void)
+static cycle_t read_cycle_count(struct clocksource *cs)
 {
 	return (cycle_t)sysreg_read(COUNT);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/lib/strnlen_user.S linux-libre-2.6.30-gnu1/arch/avr32/lib/strnlen_user.S
--- linux-libre-2.6.29-gnu1/arch/avr32/lib/strnlen_user.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/lib/strnlen_user.S	2009-06-09 23:05:27.000000000 -0400
@@ -48,7 +48,7 @@ adjust_length:
 	lddpc	lr, _task_size
 	sub	r11, lr, r12
 	mov	r9, r11
-	rcall	__strnlen_user
+	call	__strnlen_user
 	cp.w	r12, r9
 	brgt	1f
 	popm	pc
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/at32ap700x.c linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/at32ap700x.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,9 @@
 #include <mach/portmux.h>
 #include <mach/sram.h>
 
+#include <sound/atmel-abdac.h>
+#include <sound/atmel-ac97c.h>
+
 #include <video/atmel_lcdc.h>
 
 #include "clock.h"
@@ -57,26 +60,26 @@
  * don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more.
  */
 #define DEFINE_DEV(_name, _id)					\
-static u64 _name##_id##_dma_mask = DMA_32BIT_MASK;		\
+static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32);		\
 static struct platform_device _name##_id##_device = {		\
 	.name		= #_name,				\
 	.id		= _id,					\
 	.dev		= {					\
 		.dma_mask = &_name##_id##_dma_mask,		\
-		.coherent_dma_mask = DMA_32BIT_MASK,		\
+		.coherent_dma_mask = DMA_BIT_MASK(32),		\
 	},							\
 	.resource	= _name##_id##_resource,		\
 	.num_resources	= ARRAY_SIZE(_name##_id##_resource),	\
 }
 #define DEFINE_DEV_DATA(_name, _id)				\
-static u64 _name##_id##_dma_mask = DMA_32BIT_MASK;		\
+static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32);		\
 static struct platform_device _name##_id##_device = {		\
 	.name		= #_name,				\
 	.id		= _id,					\
 	.dev		= {					\
 		.dma_mask = &_name##_id##_dma_mask,		\
 		.platform_data	= &_name##_id##_data,		\
-		.coherent_dma_mask = DMA_32BIT_MASK,		\
+		.coherent_dma_mask = DMA_BIT_MASK(32),		\
 	},							\
 	.resource	= _name##_id##_resource,		\
 	.num_resources	= ARRAY_SIZE(_name##_id##_resource),	\
@@ -963,56 +966,68 @@ static struct resource atmel_usart3_reso
 DEFINE_DEV_DATA(atmel_usart, 3);
 DEV_CLK(usart, atmel_usart3, pba, 6);
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(int flags)
 {
 	u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 6);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 7);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 10);
 
 	select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(int flags)
 {
 	u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 19);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 20);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 16);
 
 	select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(int flags)
 {
 	u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 30);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 29);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 28);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(int flags)
 {
 	u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 16);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 15);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 19);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
 static struct platform_device *__initdata at32_usarts[4];
 
-void __init at32_map_usart(unsigned int hw_id, unsigned int line)
+void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)
 {
 	struct platform_device *pdev;
 
 	switch (hw_id) {
 	case 0:
 		pdev = &atmel_usart0_device;
-		configure_usart0_pins();
+		configure_usart0_pins(flags);
 		break;
 	case 1:
 		pdev = &atmel_usart1_device;
-		configure_usart1_pins();
+		configure_usart1_pins(flags);
 		break;
 	case 2:
 		pdev = &atmel_usart2_device;
-		configure_usart2_pins();
+		configure_usart2_pins(flags);
 		break;
 	case 3:
 		pdev = &atmel_usart3_device;
-		configure_usart3_pins();
+		configure_usart3_pins(flags);
 		break;
 	default:
 		return;
@@ -1753,7 +1768,7 @@ at32_add_device_usba(unsigned int id, st
 	if (platform_device_add_data(pdev, data, sizeof(usba_data)))
 		goto out_free_pdev;
 
-	if (data->vbus_pin >= 0)
+	if (gpio_is_valid(data->vbus_pin))
 		at32_select_gpio(data->vbus_pin, 0);
 
 	usba0_pclk.dev = &pdev->dev;
@@ -1980,11 +1995,14 @@ static struct clk atmel_ac97c0_pclk = {
 };
 
 struct platform_device *__init
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+		      unsigned int flags)
 {
-	struct platform_device *pdev;
-	struct ac97c_platform_data _data;
-	u32 pin_mask;
+	struct platform_device		*pdev;
+	struct dw_dma_slave		*rx_dws;
+	struct dw_dma_slave		*tx_dws;
+	struct ac97c_platform_data	_data;
+	u32				pin_mask;
 
 	if (id != 0)
 		return NULL;
@@ -1995,37 +2013,52 @@ at32_add_device_ac97c(unsigned int id, s
 
 	if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
 				ARRAY_SIZE(atmel_ac97c0_resource)))
-		goto fail;
+		goto out_free_resources;
 
 	if (!data) {
 		data = &_data;
 		memset(data, 0, sizeof(struct ac97c_platform_data));
-		data->reset_pin = GPIO_PIN_NONE;
+		data->reset_pin = -ENODEV;
 	}
 
-	data->dma_rx_periph_id = 3;
-	data->dma_tx_periph_id = 4;
-	data->dma_controller_id = 0;
+	rx_dws = &data->rx_dws;
+	tx_dws = &data->tx_dws;
+
+	/* Check if DMA slave interface for capture should be configured. */
+	if (flags & AC97C_CAPTURE) {
+		rx_dws->dma_dev = &dw_dmac0_device.dev;
+		rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+		rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
+		rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+	}
+
+	/* Check if DMA slave interface for playback should be configured. */
+	if (flags & AC97C_PLAYBACK) {
+		tx_dws->dma_dev = &dw_dmac0_device.dev;
+		tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+		tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
+		tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+	}
 
 	if (platform_device_add_data(pdev, data,
 				sizeof(struct ac97c_platform_data)))
-		goto fail;
+		goto out_free_resources;
 
-	pin_mask  = (1 << 20) | (1 << 21);	/* SDO & SYNC */
-	pin_mask |= (1 << 22) | (1 << 23);	/* SCLK & SDI */
+	/* SDO | SYNC | SCLK | SDI */
+	pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 
-	/* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
-	if (data->reset_pin != GPIO_PIN_NONE)
-		at32_select_gpio(data->reset_pin, 0);
+	if (gpio_is_valid(data->reset_pin))
+		at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT
+				| AT32_GPIOF_HIGH);
 
 	atmel_ac97c0_pclk.dev = &pdev->dev;
 
 	platform_device_add(pdev);
 	return pdev;
 
-fail:
+out_free_resources:
 	platform_device_put(pdev);
 	return NULL;
 }
@@ -2053,21 +2086,34 @@ static struct clk abdac0_sample_clk = {
 	.index		= 6,
 };
 
-struct platform_device *__init at32_add_device_abdac(unsigned int id)
+struct platform_device *__init
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
 {
-	struct platform_device *pdev;
-	u32 pin_mask;
+	struct platform_device	*pdev;
+	struct dw_dma_slave	*dws;
+	u32			pin_mask;
 
-	if (id != 0)
+	if (id != 0 || !data)
 		return NULL;
 
-	pdev = platform_device_alloc("abdac", id);
+	pdev = platform_device_alloc("atmel_abdac", id);
 	if (!pdev)
 		return NULL;
 
 	if (platform_device_add_resources(pdev, abdac0_resource,
 				ARRAY_SIZE(abdac0_resource)))
-		goto err_add_resources;
+		goto out_free_resources;
+
+	dws = &data->dws;
+
+	dws->dma_dev = &dw_dmac0_device.dev;
+	dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+	dws->cfg_hi = DWC_CFGH_DST_PER(2);
+	dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct atmel_abdac_pdata)))
+		goto out_free_resources;
 
 	pin_mask  = (1 << 20) | (1 << 22);	/* DATA1 & DATAN1 */
 	pin_mask |= (1 << 21) | (1 << 23);	/* DATA0 & DATAN0 */
@@ -2080,7 +2126,7 @@ struct platform_device *__init at32_add_
 	platform_device_add(pdev);
 	return pdev;
 
-err_add_resources:
+out_free_resources:
 	platform_device_put(pdev);
 	return NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/include/mach/at32ap700x.h linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
--- linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/include/mach/at32ap700x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/include/mach/at32ap700x.h	2009-06-09 23:05:27.000000000 -0400
@@ -171,25 +171,49 @@
 		ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |	\
 		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
 
-#define ATMEL_LCDC_PRI_15B_DATA (					\
-		ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |	\
+#define ATMEL_LCDC_PRI_18B_DATA (					\
 		ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |	\
 		ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
-		ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
 		ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |	\
-		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) |	\
-		ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) |	\
-		ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) |	\
+		ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
 
-#define ATMEL_LCDC_ALT_15B_DATA	(					\
-		ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |	\
+#define ATMEL_LCDC_ALT_18B_DATA	(					\
 		ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |	\
 		ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
-		ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
 		ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |	\
-		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) |	\
-		ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) |	\
-		ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) |	\
+		ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA (					\
+		ATMEL_LCDC(PC, DATA3)  | ATMEL_LCDC(PC, DATA4)  |	\
+		ATMEL_LCDC(PC, DATA5)  | ATMEL_LCDC(PD, DATA6)  |	\
+		ATMEL_LCDC(PD, DATA7)  |				\
+		ATMEL_LCDC(PD, DATA11) | ATMEL_LCDC(PD, DATA12) |	\
+		ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) |	\
+		ATMEL_LCDC(PD, DATA15) |				\
+		ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20) |	\
+		ATMEL_LCDC(PD, DATA21) | ATMEL_LCDC(PD, DATA22) |	\
+		ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_15B_DATA	(					\
+		ATMEL_LCDC(PE, DATA3)  | ATMEL_LCDC(PE, DATA4)  |	\
+		ATMEL_LCDC(PC, DATA5)  | ATMEL_LCDC(PD, DATA6)  |	\
+		ATMEL_LCDC(PD, DATA7)  |				\
+		ATMEL_LCDC(PE, DATA11) | ATMEL_LCDC(PE, DATA12) |	\
+		ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) |	\
+		ATMEL_LCDC(PD, DATA15) |				\
+		ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20) |	\
+		ATMEL_LCDC(PE, DATA21) | ATMEL_LCDC(PD, DATA22) |	\
+		ATMEL_LCDC(PD, DATA23))
 
 #define ATMEL_LCDC_PRI_CONTROL (					\
 		ATMEL_LCDC(PC, CC)   | ATMEL_LCDC(PC, DVAL) |		\
@@ -207,6 +231,10 @@
 
 #define ATMEL_LCDC_ALT_24BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
 
+#define ATMEL_LCDC_PRI_18BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_18B_DATA)
+
+#define ATMEL_LCDC_ALT_18BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_18B_DATA)
+
 #define ATMEL_LCDC_PRI_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
 
 #define ATMEL_LCDC_ALT_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/include/mach/board.h linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/include/mach/board.h
--- linux-libre-2.6.29-gnu1/arch/avr32/mach-at32ap/include/mach/board.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/mach-at32ap/include/mach/board.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@
  * in this array is chip-dependent.
  */
 extern unsigned long at32_board_osc_rates[];
-  
+
 /*
  * This used to add essential system devices, but this is now done
  * automatically. Please don't use it in new board code.
@@ -26,12 +26,17 @@ static inline void __deprecated at32_add
 #define ATMEL_MAX_UART	4
 extern struct platform_device *atmel_default_console_device;
 
+/* Flags for selecting USART extra pins */
+#define	ATMEL_USART_RTS		0x01
+#define	ATMEL_USART_CTS		0x02
+#define	ATMEL_USART_CLK		0x03
+
 struct atmel_uart_data {
 	short		use_dma_tx;	/* use transmit DMA? */
 	short		use_dma_rx;	/* use receive DMA? */
 	void __iomem	*regs;		/* virtual base address, if any */
 };
-void at32_map_usart(unsigned int hw_id, unsigned int line);
+void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
 struct platform_device *at32_add_device_usart(unsigned int id);
 
 struct eth_platform_data {
@@ -88,16 +93,15 @@ struct mci_platform_data;
 struct platform_device *
 at32_add_device_mci(unsigned int id, struct mci_platform_data *data);
 
-struct ac97c_platform_data {
-	unsigned short dma_rx_periph_id;
-	unsigned short dma_tx_periph_id;
-	unsigned short dma_controller_id;
-	int reset_pin;
-};
+struct ac97c_platform_data;
 struct platform_device *
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data);
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+		      unsigned int flags);
+
+struct atmel_abdac_pdata;
+struct platform_device *
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data);
 
-struct platform_device *at32_add_device_abdac(unsigned int id);
 struct platform_device *at32_add_device_psif(unsigned int id);
 
 struct cf_platform_data {
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/Makefile linux-libre-2.6.30-gnu1/arch/avr32/Makefile
--- linux-libre-2.6.29-gnu1/arch/avr32/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,7 @@ core-$(CONFIG_BOARD_ATSTK1000)		+= arch/
 core-$(CONFIG_BOARD_ATNGW100)		+= 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/
 core-$(CONFIG_BOARD_MIMC200)		+= arch/avr32/boards/mimc200/
 core-$(CONFIG_LOADER_U_BOOT)		+= arch/avr32/boot/u-boot/
 core-y					+= arch/avr32/kernel/
@@ -42,8 +43,6 @@ core-y					+= arch/avr32/mm/
 drivers-$(CONFIG_OPROFILE)		+= arch/avr32/oprofile/
 libs-y					+= arch/avr32/lib/
 
-CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch
-
 BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec
 
 .PHONY: $(BOOT_TARGETS) install
diff -druNp linux-libre-2.6.29-gnu1/arch/avr32/mm/fault.c linux-libre-2.6.30-gnu1/arch/avr32/mm/fault.c
--- linux-libre-2.6.29-gnu1/arch/avr32/mm/fault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/avr32/mm/fault.c	2009-06-09 23:05:27.000000000 -0400
@@ -250,21 +250,3 @@ asmlinkage void do_bus_error(unsigned lo
 	dump_dtlb();
 	die("Bus Error", regs, SIGKILL);
 }
-
-/*
- * This functionality is currently not possible to implement because
- * we're using segmentation to ensure a fixed mapping of the kernel
- * virtual address space.
- *
- * It would be possible to implement this, but it would require us to
- * disable segmentation at startup and load the kernel mappings into
- * the TLB like any other pages. There will be lots of trickery to
- * avoid recursive invocation of the TLB miss handler, though...
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-void kernel_map_pages(struct page *page, int numpages, int enable)
-{
-
-}
-EXPORT_SYMBOL(kernel_map_pages);
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF518F-EZBRD_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Feb 20 10:01:44 2009
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -43,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -314,7 +313,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_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -375,7 +374,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
@@ -634,6 +632,7 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # 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
 
@@ -793,6 +792,7 @@ 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
 
 #
@@ -816,6 +816,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
@@ -865,7 +871,26 @@ 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_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_SDH_BFIN=m
+CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y
+CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ=y
+# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1121,7 +1146,6 @@ 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF526-EZBRD_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -42,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -55,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -132,15 +132,20 @@ CONFIG_BF526=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=0
 CONFIG_BF_REV_MAX=2
-CONFIG_BF_REV_0_0=y
-# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=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
@@ -313,7 +318,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_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -374,7 +379,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
@@ -583,7 +587,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -637,6 +643,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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -815,6 +822,7 @@ 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
 
 #
@@ -838,6 +846,7 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
@@ -896,6 +905,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
@@ -904,8 +919,10 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -940,55 +957,7 @@ CONFIG_BFIN_WDT=y
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-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_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_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
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_SOC=m
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_BF5XX_I2S=m
-CONFIG_SND_BF5XX_SOC_SSM2602=m
-# CONFIG_SND_BF5XX_SOC_AD73311 is not set
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_MMAP_SUPPORT=y
-# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
-CONFIG_SND_BF5XX_SOC_SPORT=m
-CONFIG_SND_BF5XX_SOC_I2S=m
-CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
-CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_AD1980=m
-CONFIG_SND_SOC_SSM2602=m
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
+# CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
@@ -1063,13 +1032,15 @@ CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_MUSB_SOC=y
 
 #
-# Blackfin high speed USB support
+# Blackfin 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=y
+CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
@@ -1081,18 +1052,33 @@ CONFIG_MUSB_PIO_ONLY=y
 # 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 also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
+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
+# 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
@@ -1124,6 +1110,30 @@ CONFIG_MUSB_PIO_ONLY=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET 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_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE 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_ZERO 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
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1158,12 +1168,14 @@ 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
 
 #
 # 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
@@ -1384,6 +1396,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1423,6 +1442,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF527-EZKIT_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -133,15 +132,20 @@ CONFIG_BF527=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=0
 CONFIG_BF_REV_MAX=2
-CONFIG_BF_REV_0_0=y
-# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=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
@@ -314,7 +318,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_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -375,7 +379,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
@@ -626,7 +629,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -681,6 +686,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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -755,8 +761,8 @@ CONFIG_INPUT_MISC=y
 # CONFIG_SPI_ADC_BF533 is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-# CONFIG_BFIN_SPORT is not set
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
 # CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_TWI_LCD is not set
 CONFIG_BFIN_DMA_INTERFACE=m
@@ -859,6 +865,7 @@ 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
 
 #
@@ -871,60 +878,7 @@ 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_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_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -940,6 +894,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
@@ -948,8 +908,10 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -1000,6 +962,7 @@ CONFIG_FB_BFIN_T350MCQB=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_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=m
 CONFIG_LCD_LTV350QV=m
@@ -1152,13 +1115,15 @@ CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_MUSB_SOC=y
 
 #
-# Blackfin high speed USB support
+# Blackfin 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=y
+CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
@@ -1170,18 +1135,33 @@ CONFIG_MUSB_PIO_ONLY=y
 # 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 also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
+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
+# 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
@@ -1213,6 +1193,30 @@ CONFIG_MUSB_PIO_ONLY=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET 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_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE 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_ZERO 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
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1247,12 +1251,14 @@ 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
 
 #
 # 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
@@ -1473,6 +1479,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1512,6 +1525,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF533-EZKIT_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_BF533=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=3
 CONFIG_BF_REV_MAX=6
@@ -157,7 +161,6 @@ CONFIG_BFIN533_EZKIT=y
 # CONFIG_BFIN533_BLUETECHNIX_CM is not set
 # CONFIG_H8606_HVSISTEMAS is not set
 # CONFIG_BFIN532_IP0X is not set
-# CONFIG_GENERIC_BF533_BOARD is not set
 
 #
 # BF533/2/1 Specific Configuration
@@ -277,7 +280,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_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -575,6 +578,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -608,6 +612,7 @@ CONFIG_SMC91X=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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -714,6 +719,7 @@ 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
 
 #
@@ -726,22 +732,7 @@ 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_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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -752,6 +743,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
@@ -760,7 +757,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
@@ -826,6 +823,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 # 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
@@ -1046,6 +1044,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1084,6 +1089,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF533-STAMP_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_BF533=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=3
 CONFIG_BF_REV_MAX=6
@@ -157,7 +161,6 @@ CONFIG_BFIN533_STAMP=y
 # CONFIG_BFIN533_BLUETECHNIX_CM is not set
 # CONFIG_H8606_HVSISTEMAS is not set
 # CONFIG_BFIN532_IP0X is not set
-# CONFIG_GENERIC_BF533_BOARD is not set
 
 #
 # BF533/2/1 Specific Configuration
@@ -277,7 +280,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_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -578,7 +581,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -612,6 +617,7 @@ CONFIG_SMC91X=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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -671,10 +677,10 @@ CONFIG_CONFIG_INPUT_PCF8574=m
 # CONFIG_SPI_ADC_BF533 is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_SPORT=y
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
 # CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_TWI_LCD=m
+# CONFIG_TWI_LCD is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
@@ -765,6 +771,7 @@ 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
 
 #
@@ -777,60 +784,7 @@ 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_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_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -841,6 +795,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
@@ -851,6 +811,7 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -909,6 +870,7 @@ CONFIG_ADV7393_1XMEM=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_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1018,12 +980,14 @@ 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
 
 #
 # 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
@@ -1244,6 +1208,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1282,6 +1253,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF537-STAMP_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
-# Tue Dec 30 17:24:37 2008
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -37,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -134,10 +132,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
@@ -184,7 +187,6 @@ CONFIG_BFIN537_STAMP=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
@@ -589,7 +591,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -644,6 +648,7 @@ CONFIG_BFIN_RX_DESC_NUM=20
 # 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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -706,10 +711,10 @@ CONFIG_SERIO_LIBPS2=y
 # CONFIG_SPI_ADC_BF533 is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
+CONFIG_BF5xx_PPI=m
 CONFIG_BFIN_SPORT=m
 # CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_TWI_LCD=m
+# CONFIG_TWI_LCD is not set
 CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
@@ -808,6 +813,7 @@ 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
 
 #
@@ -820,60 +826,7 @@ 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_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_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -884,6 +837,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
@@ -894,6 +853,7 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -957,6 +917,7 @@ CONFIG_ADV7393_1XMEM=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_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=m
 # CONFIG_LCD_LTV350QV is not set
@@ -1074,12 +1035,14 @@ 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
 
 #
 # 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
@@ -1300,6 +1263,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1338,6 +1308,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF538-EZKIT_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -42,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -55,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -132,10 +132,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_BF538=y
 # 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=4
 CONFIG_BF_REV_MAX=5
@@ -293,7 +298,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_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -354,7 +359,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
@@ -645,6 +649,7 @@ CONFIG_SMC91X=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
 
@@ -690,7 +695,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_AD7877 is not set
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 CONFIG_TOUCHSCREEN_AD7879_SPI=y
-CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879=y
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
@@ -718,8 +723,8 @@ CONFIG_INPUT_MISC=y
 # CONFIG_SPI_ADC_BF533 is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_SPORT=y
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
 # CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_TWI_LCD is not set
 CONFIG_BFIN_DMA_INTERFACE=m
@@ -762,7 +767,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
+CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
@@ -774,7 +779,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
-CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI=m
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
@@ -818,6 +823,7 @@ 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
 
 #
@@ -830,60 +836,7 @@ 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_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_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -894,6 +847,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
@@ -904,6 +863,7 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -954,6 +914,7 @@ CONFIG_FB_BFIN_LQ035Q1=m
 # 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_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1007,12 +968,14 @@ 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
 
 #
 # 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
@@ -1233,6 +1196,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1271,6 +1241,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF548-EZKIT_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -133,16 +132,21 @@ CONFIG_PREEMPT_VOLUNTARY=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=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=y
+# 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_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
@@ -348,7 +352,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_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 CONFIG_DMA_UNCACHED_2M=y
 # CONFIG_DMA_UNCACHED_1M is not set
@@ -413,7 +417,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
@@ -512,9 +515,9 @@ CONFIG_IRCOMM=m
 #
 CONFIG_IRTTY_SIR=m
 CONFIG_BFIN_SIR=m
-CONFIG_BFIN_SIR3=y
 # CONFIG_BFIN_SIR0 is not set
 # CONFIG_BFIN_SIR2 is not set
+CONFIG_BFIN_SIR3=y
 CONFIG_SIR_BFIN_DMA=y
 # CONFIG_SIR_BFIN_PIO is not set
 
@@ -538,7 +541,8 @@ CONFIG_SIR_BFIN_DMA=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
@@ -554,7 +558,9 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+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
@@ -668,7 +674,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -743,6 +751,7 @@ CONFIG_SMSC911X=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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -751,8 +760,16 @@ CONFIG_NETDEV_10000=y
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_POWEROF2_BLOCKSIZE_ONLY=y
+# 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
 
 #
 # USB Network Adapters
@@ -844,8 +861,8 @@ CONFIG_INPUT_MISC=y
 # CONFIG_SPI_ADC_BF533 is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-# CONFIG_BFIN_SPORT is not set
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
 # CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_TWI_LCD is not set
 CONFIG_BFIN_DMA_INTERFACE=m
@@ -950,6 +967,7 @@ 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
 
 #
@@ -962,60 +980,7 @@ 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_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_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -1031,6 +996,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
@@ -1039,8 +1010,10 @@ CONFIG_BFIN_WDT=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -1092,6 +1065,7 @@ CONFIG_FB_BF54X_LQ043=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_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1243,15 +1217,15 @@ CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_MUSB_SOC=y
 
 #
-# Blackfin high speed USB support
+# Blackfin 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_MUSB_PIO_ONLY=y
+CONFIG_MUSB_DMA_POLL=y
 # CONFIG_USB_MUSB_DEBUG is not set
 
 #
@@ -1263,11 +1237,11 @@ CONFIG_USB_INVENTRA_DMA=y
 # 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 also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1321,7 +1295,31 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
-CONFIG_MMC=m
+# 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_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE 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_ZERO 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
+CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
@@ -1337,8 +1335,9 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-CONFIG_SDH_BFIN=m
+CONFIG_SDH_BFIN=y
 # 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_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1373,12 +1372,14 @@ 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
 
 #
 # 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
@@ -1641,6 +1642,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1680,6 +1688,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BF561-EZKIT_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_PREEMPT_VOLUNTARY=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=y
 # CONFIG_SMP is not set
 CONFIG_BF_REV_MIN=3
@@ -166,7 +170,6 @@ CONFIG_IRQ_SPI_ERROR=7
 CONFIG_BFIN561_EZKIT=y
 # CONFIG_BFIN561_TEPLA is not set
 # CONFIG_BFIN561_BLUETECHNIX_CM is not set
-# CONFIG_GENERIC_BF561_BOARD is not set
 
 #
 # BF561 Specific Configuration
@@ -316,7 +319,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_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
 # CONFIG_DMA_UNCACHED_4M is not set
 # CONFIG_DMA_UNCACHED_2M is not set
 CONFIG_DMA_UNCACHED_1M=y
@@ -382,7 +385,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
@@ -612,6 +614,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -645,6 +648,7 @@ CONFIG_SMC91X=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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -751,6 +755,7 @@ 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
 
 #
@@ -763,22 +768,7 @@ 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_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_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_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
@@ -789,6 +779,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
@@ -797,7 +793,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
@@ -1041,6 +1037,13 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1079,6 +1082,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/BlackStamp_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/BlackStamp_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/BlackStamp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/BlackStamp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -43,7 +43,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,7 +56,7 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF527_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF527_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF527_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF527_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -43,7 +43,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +56,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF533_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF533_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF533_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF533_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF537E_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF537E_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF537E_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF537E_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF537U_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF537U_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF537U_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF537U_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF548_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF548_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF548_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF548_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_FAIR_USER_SCHED=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF561_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF561_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/CM-BF561_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/CM-BF561_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/H8606_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/H8606_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/H8606_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/H8606_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,7 @@ CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -56,7 +56,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/IP0X_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/IP0X_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/IP0X_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/IP0X_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ CONFIG_SYSFS_DEPRECATED=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/PNAV-10_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/PNAV-10_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/PNAV-10_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -35,13 +35,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
 # CONFIG_GROUP_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 is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -53,13 +52,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -130,10 +129,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
@@ -180,7 +184,6 @@ CONFIG_IRQ_SPI=10
 # CONFIG_BFIN537_BLUETECHNIX_TCM is not set
 CONFIG_PNAV10=y
 # CONFIG_CAMSIG_MINOTAUR is not set
-# CONFIG_GENERIC_BF537_BOARD is not set
 
 #
 # BF537 Specific Configuration
@@ -341,7 +344,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
@@ -538,7 +540,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -593,6 +597,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=y
 # CONFIG_AX88180 is not set
 CONFIG_NETDEV_10000=y
@@ -776,6 +781,7 @@ 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
 
 #
@@ -799,6 +805,7 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
@@ -845,6 +852,12 @@ CONFIG_HWMON=y
 # 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
@@ -853,8 +866,10 @@ CONFIG_HWMON=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -910,6 +925,7 @@ CONFIG_FB_BFIN_LANDSCAPE=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_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_LTV350QV is not set
@@ -966,7 +982,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 #
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
@@ -1003,12 +1019,14 @@ 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
 
 #
 # 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
@@ -1196,6 +1214,10 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -1230,6 +1252,7 @@ CONFIG_CRYPTO=y
 #
 # 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
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/SRV1_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/SRV1_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/SRV1_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/SRV1_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -49,7 +49,7 @@ CONFIG_SYSFS_DEPRECATED=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -61,7 +61,7 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/configs/TCM-BF537_defconfig linux-libre-2.6.30-gnu1/arch/blackfin/configs/TCM-BF537_defconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/configs/TCM-BF537_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/configs/TCM-BF537_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 CONFIG_SYSCTL_SYSCALL=y
@@ -51,13 +51,13 @@ CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-CONFIG_FUTEX=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_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/bfin5xx_spi.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/bfin5xx_spi.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/bfin5xx_spi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/bfin5xx_spi.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef _SPI_CHANNEL_H_
 #define _SPI_CHANNEL_H_
 
+#define MIN_SPI_BAUD_VAL	2
+
 #define SPI_READ              0
 #define SPI_WRITE             1
 
@@ -110,7 +112,7 @@
 struct bfin5xx_spi_master {
 	u16 num_chipselect;
 	u8 enable_dma;
-	u16 pin_req[4];
+	u16 pin_req[7];
 };
 
 /* spi_board_info.controller_data for SPI slave devices,
@@ -122,6 +124,9 @@ struct bfin5xx_spi_chip {
 	u8 bits_per_word;
 	u8 cs_change_per_word;
 	u16 cs_chg_udelay; /* Some devices require 16-bit delays */
+	u32 cs_gpio;
+	/* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
+	u16 idle_tx_val;
 };
 
 #endif /* _SPI_CHANNEL_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/bfin_sport.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/bfin_sport.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/bfin_sport.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/bfin_sport.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,13 @@
 #ifndef __BFIN_SPORT_H__
 #define __BFIN_SPORT_H__
 
+#ifdef __KERNEL__
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#endif
+
 #define SPORT_MAJOR	237
 #define SPORT_NR_DEVS	2
 
@@ -119,7 +126,7 @@ struct sport_dev {
 	int tx_len;
 	int tx_sent;
 
-	int sport_err_irq;
+	int err_irq;
 
 	struct mutex mutex;	/* mutual exclusion semaphore */
 	struct task_struct *task;
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/flat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,6 @@
 
 #include <asm/unaligned.h>
 
-#define	flat_stack_align(sp)	/* nothing needed */
 #define	flat_argvp_envp_on_stack()		0
 #define	flat_old_ram_flag(flags)		(flags)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/.gitignore linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/.gitignore
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/.gitignore	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/.gitignore	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-+mach
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/gpio.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/gpio.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -110,7 +110,7 @@
 * MODIFICATION HISTORY :
 **************************************************************/
 
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
 void set_gpio_dir(unsigned, unsigned short);
 void set_gpio_inen(unsigned, unsigned short);
 void set_gpio_polar(unsigned, unsigned short);
@@ -303,7 +303,10 @@ static inline void gpio_set_value(unsign
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-	return (gpio + GPIO_IRQ_BASE);
+	if (likely(gpio < MAX_BLACKFIN_GPIOS))
+		return gpio + GPIO_IRQ_BASE;
+
+	return -EINVAL;
 }
 
 static inline int irq_to_gpio(unsigned irq)
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/gptimers.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/gptimers.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/gptimers.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/gptimers.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,16 +15,16 @@
 #include <asm/blackfin.h>
 
 /*
- * BF537/BF527: 8 timers:
+ * BF51x/BF52x/BF537: 8 timers:
  */
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+#if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || defined(BF537_FAMILY)
 # define MAX_BLACKFIN_GPTIMERS 8
 # define TIMER0_GROUP_REG      TIMER_ENABLE
 #endif
 /*
  * BF54x: 11 timers (BF542: 8 timers):
  */
-#if defined(BF548_FAMILY)
+#if defined(CONFIG_BF54x)
 # ifdef CONFIG_BF542
 #  define MAX_BLACKFIN_GPTIMERS 8
 # else
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/percpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,14 +3,4 @@
 
 #include <asm-generic/percpu.h>
 
-#ifdef CONFIG_MODULES
-#define PERCPU_MODULE_RESERVE 8192
-#else
-#define PERCPU_MODULE_RESERVE 0
-#endif
-
-#define PERCPU_ENOUGH_ROOM \
-	(ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \
-	 PERCPU_MODULE_RESERVE)
-
 #endif	/* __ARCH_BLACKFIN_PERCPU__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,4 +53,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif				/* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _BLACKFIN_SWAB_H
 #define _BLACKFIN_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -378,8 +378,10 @@
 #define __NR_dup3		363
 #define __NR_pipe2		364
 #define __NR_inotify_init1	365
+#define __NR_preadv		366
+#define __NR_pwritev		367
 
-#define __NR_syscall		366
+#define __NR_syscall		368
 #define NR_syscalls		__NR_syscall
 
 /* Old optional stuff no one actually uses */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/Kconfig linux-libre-2.6.30-gnu1/arch/blackfin/Kconfig
--- linux-libre-2.6.29-gnu1/arch/blackfin/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -777,7 +777,7 @@ config CACHELINE_ALIGNED_L1
 	default n if BF54x
 	depends on !BF531
 	help
-	  If enabled, cacheline_anligned data is linked
+	  If enabled, cacheline_aligned data is linked
 	  into L1 data memory. (less latency)
 
 config SYSCALL_TAB_L1
@@ -957,7 +957,7 @@ config MPU
 	  memory they do not own.  This comes at a performance penalty
 	  and is recommended only for debugging.
 
-comment "Asynchonous Memory Configuration"
+comment "Asynchronous Memory Configuration"
 
 menu "EBIU_AMGCTL Global Control"
 config C_AMCKEN
@@ -989,7 +989,7 @@ config C_B3PEN
 	default n
 
 choice
-	prompt"Enable Asynchonous Memory Banks"
+	prompt "Enable Asynchronous Memory Banks"
 	default C_AMBEN_ALL
 
 config C_AMBEN
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/bfin_gpio.c linux-libre-2.6.30-gnu1/arch/blackfin/kernel/bfin_gpio.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/bfin_gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/bfin_gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,7 +69,7 @@ enum {
 static struct gpio_port_t * const gpio_array[] = {
 #if defined(BF533_FAMILY) || defined(BF538_FAMILY)
 	(struct gpio_port_t *) FIO_FLAG_D,
-#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 	(struct gpio_port_t *) PORTFIO,
 	(struct gpio_port_t *) PORTGIO,
 	(struct gpio_port_t *) PORTHIO,
@@ -77,7 +77,7 @@ static struct gpio_port_t * const gpio_a
 	(struct gpio_port_t *) FIO0_FLAG_D,
 	(struct gpio_port_t *) FIO1_FLAG_D,
 	(struct gpio_port_t *) FIO2_FLAG_D,
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
 	(struct gpio_port_t *)PORTA_FER,
 	(struct gpio_port_t *)PORTB_FER,
 	(struct gpio_port_t *)PORTC_FER,
@@ -93,7 +93,7 @@ static struct gpio_port_t * const gpio_a
 #endif
 };
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 static unsigned short * const port_fer[] = {
 	(unsigned short *) PORTF_FER,
 	(unsigned short *) PORTG_FER,
@@ -109,11 +109,11 @@ static unsigned short * const port_mux[]
 
 static const
 u8 pmux_offset[][16] = {
-#  if defined(BF527_FAMILY)
+#  if defined(CONFIG_BF52x)
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
 	{ 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
-#  elif defined(BF518_FAMILY)
+#  elif defined(CONFIG_BF51x)
 	{ 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
 	{ 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
 	{ 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
@@ -139,7 +139,7 @@ static struct gpio_port_s gpio_bank_save
 
 inline int check_gpio(unsigned gpio)
 {
-#if defined(BF548_FAMILY)
+#if defined(CONFIG_BF54x)
 	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
 	    || gpio == GPIO_PH14 || gpio == GPIO_PH15
 	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
@@ -187,13 +187,13 @@ static void port_setup(unsigned gpio, un
 	if (check_gpio(gpio))
 		return;
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 	if (usage == GPIO_USAGE)
 		*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 	else
 		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 	SSYNC();
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
 	if (usage == GPIO_USAGE)
 		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
 	else
@@ -273,7 +273,7 @@ static void portmux_setup(unsigned short
 		}
 	}
 }
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
 inline void portmux_setup(unsigned short per)
 {
 	u32 pmux;
@@ -297,7 +297,7 @@ inline u16 get_portmux(unsigned short pe
 
 	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
 }
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 inline void portmux_setup(unsigned short per)
 {
 	u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
@@ -322,7 +322,7 @@ static int __init bfin_gpio_init(void)
 arch_initcall(bfin_gpio_init);
 
 
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -489,7 +489,7 @@ static const unsigned int sic_iwr_irqs[]
 	IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
 #elif defined(BF538_FAMILY)
 	IRQ_PORTF_INTB
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 	IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB
 #elif defined(BF561_FAMILY)
 	IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB
@@ -586,7 +586,7 @@ u32 bfin_pm_standby_setup(void)
 		gpio_array[bank]->maskb = 0;
 
 		if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 			gpio_bank_saved[bank].fer   = *port_fer[bank];
 #endif
 			gpio_bank_saved[bank].inen  = gpio_array[bank]->inen;
@@ -631,7 +631,7 @@ void bfin_pm_standby_restore(void)
 		bank = gpio_bank(i);
 
 		if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 			*port_fer[bank]   	= gpio_bank_saved[bank].fer;
 #endif
 			gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
@@ -657,9 +657,9 @@ void bfin_gpio_pm_hibernate_suspend(void
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 		bank = gpio_bank(i);
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
 		gpio_bank_saved[bank].fer = *port_fer[bank];
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 		gpio_bank_saved[bank].mux = *port_mux[bank];
 #else
 		if (bank == 0)
@@ -685,8 +685,8 @@ void bfin_gpio_pm_hibernate_restore(void
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 		bank = gpio_bank(i);
 
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 		*port_mux[bank] = gpio_bank_saved[bank].mux;
 #else
 		if (bank == 0)
@@ -710,7 +710,7 @@ void bfin_gpio_pm_hibernate_restore(void
 
 
 #endif
-#else /* BF548_FAMILY */
+#else /* CONFIG_BF54x */
 #ifdef CONFIG_PM
 
 u32 bfin_pm_standby_setup(void)
@@ -762,7 +762,7 @@ unsigned short get_gpio_dir(unsigned gpi
 }
 EXPORT_SYMBOL(get_gpio_dir);
 
-#endif /* BF548_FAMILY */
+#endif /* CONFIG_BF54x */
 
 /***********************************************************
 *
@@ -802,7 +802,8 @@ int peripheral_request(unsigned short pe
 	 */
 	if (unlikely(!check_gpio(ident) &&
 	    reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		printk(KERN_ERR
 		       "%s: Peripheral %d is already reserved as GPIO by %s !\n",
 		       __func__, ident, get_label(ident));
@@ -817,7 +818,7 @@ int peripheral_request(unsigned short pe
 		 * be requested and used by several drivers
 		 */
 
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
 #else
 		if (!(per & P_MAYSHARE)) {
@@ -830,7 +831,8 @@ int peripheral_request(unsigned short pe
 			if (cmp_label(ident, label) == 0)
 				goto anyway;
 
-			dump_stack();
+			if (system_state == SYSTEM_BOOTING)
+				dump_stack();
 			printk(KERN_ERR
 			       "%s: Peripheral %d function %d is already reserved by %s !\n",
 			       __func__, ident, P_FUNCT2MUX(per), get_label(ident));
@@ -946,14 +948,16 @@ int bfin_gpio_request(unsigned gpio, con
 	}
 
 	if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
 		       gpio, get_label(gpio));
 		local_irq_restore_hw(flags);
 		return -EBUSY;
 	}
 	if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		printk(KERN_ERR
 		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 		       gpio, get_label(gpio));
@@ -964,7 +968,7 @@ int bfin_gpio_request(unsigned gpio, con
 		printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
 		       " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
 	}
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
 	else {	/* Reset POLAR setting when acquiring a gpio for the first time */
 		set_gpio_polar(gpio, 0);
 	}
@@ -993,7 +997,8 @@ void bfin_gpio_free(unsigned gpio)
 	local_irq_save_hw(flags);
 
 	if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		gpio_error(gpio);
 		local_irq_restore_hw(flags);
 		return;
@@ -1017,7 +1022,8 @@ int bfin_gpio_irq_request(unsigned gpio,
 	local_irq_save_hw(flags);
 
 	if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		printk(KERN_ERR
 		       "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n",
 		       gpio);
@@ -1025,7 +1031,8 @@ int bfin_gpio_irq_request(unsigned gpio,
 		return -EBUSY;
 	}
 	if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		printk(KERN_ERR
 		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 		       gpio, get_label(gpio));
@@ -1057,7 +1064,8 @@ void bfin_gpio_irq_free(unsigned gpio)
 	local_irq_save_hw(flags);
 
 	if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
-		dump_stack();
+		if (system_state == SYSTEM_BOOTING)
+			dump_stack();
 		gpio_error(gpio);
 		local_irq_restore_hw(flags);
 		return;
@@ -1072,7 +1080,7 @@ void bfin_gpio_irq_free(unsigned gpio)
 
 static inline void __bfin_gpio_direction_input(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
 #else
 	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
@@ -1100,13 +1108,13 @@ EXPORT_SYMBOL(bfin_gpio_direction_input)
 
 void bfin_gpio_irq_prepare(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 	unsigned long flags;
 #endif
 
 	port_setup(gpio, GPIO_USAGE);
 
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 	local_irq_save_hw(flags);
 	__bfin_gpio_direction_input(gpio);
 	local_irq_restore_hw(flags);
@@ -1135,7 +1143,7 @@ int bfin_gpio_direction_output(unsigned
 
 	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
 	gpio_set_value(gpio, value);
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
 #else
 	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
@@ -1150,7 +1158,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_output
 
 int bfin_gpio_get_value(unsigned gpio)
 {
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
 	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
 #else
 	unsigned long flags;
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/.gitignore linux-libre-2.6.30-gnu1/arch/blackfin/kernel/.gitignore
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/.gitignore	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+vmlinux.lds
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/irqchip.c linux-libre-2.6.30-gnu1/arch/blackfin/kernel/irqchip.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/irqchip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/irqchip.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,6 +70,11 @@ static struct irq_desc bad_irq_desc = {
 #endif
 };
 
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* We are not allocating a variable-sized bad_irq_desc.affinity */
+#error "Blackfin architecture does not support CONFIG_CPUMASK_OFFSTACK."
+#endif
+
 int show_interrupts(struct seq_file *p, void *v)
 {
 	int i = *(loff_t *) v, j;
@@ -83,7 +88,7 @@ int show_interrupts(struct seq_file *p,
 			goto skip;
 		seq_printf(p, "%3d: ", i);
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		seq_printf(p, " %8s", irq_desc[i].chip->name);
 		seq_printf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next)
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/process.c linux-libre-2.6.30-gnu1/arch/blackfin/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ asmlinkage int bfin_clone(struct pt_regs
 }
 
 int
-copy_thread(int nr, unsigned long clone_flags,
+copy_thread(unsigned long clone_flags,
 	    unsigned long usp, unsigned long topstk,
 	    struct task_struct *p, struct pt_regs *regs)
 {
@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsig
 	if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
 		return 1;
 
-#ifdef CONFIG_ROMFS_MTD_FS
+#ifdef CONFIG_ROMFS_ON_MTD
 	/* For XIP, allow user space to use pointers within the ROMFS.  */
 	if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
 		return 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/time-ts.c linux-libre-2.6.30-gnu1/arch/blackfin/kernel/time-ts.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/time-ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/time-ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,16 +58,11 @@ static inline unsigned long long cycles_
 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
 }
 
-static cycle_t read_cycles(void)
+static cycle_t read_cycles(struct clocksource *cs)
 {
 	return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
 }
 
-unsigned long long sched_clock(void)
-{
-	return cycles_2_ns(read_cycles());
-}
-
 static struct clocksource clocksource_bfin = {
 	.name		= "bfin_cycles",
 	.rating		= 350,
@@ -77,6 +72,11 @@ static struct clocksource clocksource_bf
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+unsigned long long sched_clock(void)
+{
+	return cycles_2_ns(read_cycles(&clocksource_bfin));
+}
+
 static int __init bfin_clocksource_init(void)
 {
 	set_cyc2ns_scale(get_cclk() / 1000);
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/blackfin/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -183,6 +183,7 @@ SECTIONS
 		. = ALIGN(4);
 		__etext_l1 = .;
 	}
+	ASSERT (SIZEOF(.text_l1) <= L1_CODE_LENGTH, "L1 text overflow!")
 
 	.data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))
 	{
@@ -200,6 +201,7 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l1 = .;
 	}
+	ASSERT (SIZEOF(.data_a_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
 
 	.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
 	{
@@ -214,6 +216,7 @@ 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);
 
@@ -239,6 +242,7 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l2 = .;
 	}
+	ASSERT (SIZEOF(.text_data_l1) <= 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.
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/lib/strncmp.c linux-libre-2.6.30-gnu1/arch/blackfin/lib/strncmp.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/lib/strncmp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/lib/strncmp.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,9 +8,8 @@
 
 #define strncmp __inline_strncmp
 #include <asm/string.h>
-#undef strncmp
-
 #include <linux/module.h>
+#undef strncmp
 
 int strncmp(const char *cs, const char *ct, size_t count)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -87,6 +87,7 @@
 struct bfin_serial_port {
 	struct uart_port port;
 	unsigned int old_status;
+	int status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long uart_base_addr;
 	int uart_irq;
+	int uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int uart_tx_dma_channel;
 	unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	 0xFFC00400,
 	 IRQ_UART0_RX,
+	 IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	 CH_UART0_TX,
 	 CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	 0xFFC02000,
 	 IRQ_UART1_RX,
+	 IRQ_UART1_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	 CH_UART1_TX,
 	 CH_UART1_RX,
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/blackfin.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,8 +32,6 @@
 #ifndef _MACH_BLACKFIN_H_
 #define _MACH_BLACKFIN_H_
 
-#define BF518_FAMILY
-
 #include "bf518.h"
 #include "mem_map.h"
 #include "defBF512.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF514.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,4 +45,71 @@
 
 /* The following are the #defines needed by ADSP-BF514 that are not in the common header */
 
+/* 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_BF514_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/cdefBF516.h	2009-06-09 23:05:27.000000000 -0400
@@ -210,4 +210,71 @@
 #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.29-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/defBF514.h	2009-06-09 23:05:27.000000000 -0400
@@ -110,4 +110,139 @@
 #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_BF514_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf518/include/mach/defBF516.h	2009-06-09 23:05:27.000000000 -0400
@@ -487,4 +487,139 @@
 #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.29-gnu1/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -87,6 +87,7 @@
 struct bfin_serial_port {
 	struct uart_port port;
 	unsigned int old_status;
+	int status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long uart_base_addr;
 	int uart_irq;
+	int uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int uart_tx_dma_channel;
 	unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	 0xFFC00400,
 	 IRQ_UART0_RX,
+	 IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	 CH_UART0_TX,
 	 CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	 0xFFC02000,
 	 IRQ_UART1_RX,
+	 IRQ_UART1_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	 CH_UART1_TX,
 	 CH_UART1_RX,
@@ -167,29 +171,3 @@ struct bfin_serial_res bfin_serial_resou
 };
 
 #define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	peripheral_request(P_UART0_TX, DRIVER_NAME);
-	peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	peripheral_request(P_UART1_TX, DRIVER_NAME);
-	peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_input(uart->cts_pin);
-	}
-
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf527/include/mach/blackfin.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,8 +32,6 @@
 #ifndef _MACH_BLACKFIN_H_
 #define _MACH_BLACKFIN_H_
 
-#define BF527_FAMILY
-
 #include "bf527.h"
 #include "mem_map.h"
 #include "defBF522.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -74,6 +74,7 @@
 struct bfin_serial_port {
         struct uart_port        port;
         unsigned int            old_status;
+	int			status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int			tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long	uart_base_addr;
 	int		uart_irq;
+	int		uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int	uart_tx_dma_channel;
 	unsigned int	uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC00400,
 	IRQ_UART_RX,
+	IRQ_UART_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART_TX,
 	CH_UART_RX,
@@ -142,23 +145,3 @@ struct bfin_serial_res bfin_serial_resou
 };
 
 #define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	peripheral_request(P_UART0_TX, DRIVER_NAME);
-	peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_input(uart->cts_pin);
-	}
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf537/boards/stamp.c linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2009-06-09 23:05:27.000000000 -0400
@@ -843,6 +843,71 @@ static struct platform_device bfin_spi0_
 };
 #endif  /* spi master and devices */
 
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+
+/* SPORT SPI controller data */
+static struct bfin5xx_spi_master bfin_sport_spi0_info = {
+	.num_chipselect = 1, /* master only supports one device */
+	.enable_dma = 0,  /* master don't support DMA */
+	.pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI,
+		P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0},
+};
+
+static struct resource bfin_sport_spi0_resource[] = {
+	[0] = {
+		.start = SPORT0_TCR1,
+		.end   = SPORT0_TCR1 + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = IRQ_SPORT0_ERROR,
+		.end   = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+		},
+};
+
+static struct platform_device bfin_sport_spi0_device = {
+	.name = "bfin-sport-spi",
+	.id = 1, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_sport_spi0_resource),
+	.resource = bfin_sport_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_sport_spi0_info, /* Passed to driver */
+	},
+};
+
+static struct bfin5xx_spi_master bfin_sport_spi1_info = {
+	.num_chipselect = 1, /* master only supports one device */
+	.enable_dma = 0,  /* master don't support DMA */
+	.pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI,
+		P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0},
+};
+
+static struct resource bfin_sport_spi1_resource[] = {
+	[0] = {
+		.start = SPORT1_TCR1,
+		.end   = SPORT1_TCR1 + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = IRQ_SPORT1_ERROR,
+		.end   = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+		},
+};
+
+static struct platform_device bfin_sport_spi1_device = {
+	.name = "bfin-sport-spi",
+	.id = 2, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_sport_spi1_resource),
+	.resource = bfin_sport_spi1_resource,
+	.dev = {
+		.platform_data = &bfin_sport_spi1_info, /* Passed to driver */
+	},
+};
+
+#endif  /* sport 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",
@@ -1073,6 +1138,141 @@ static struct adp5588_kpad_platform_data
 };
 #endif
 
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+#include <linux/mfd/adp5520.h>
+
+	/*
+	 *  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),
+};
+
+	/*
+	 *  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,
+	},
+#ifdef ADP5520_EN_ALL_LEDS
+	{
+		.name = "adp5520-led2",
+		.default_trigger = "none",
+		.flags = FLAG_ID_ADP5520_LED2_ADP5501_LED1,
+	},
+	{
+		.name = "adp5520-led3",
+		.default_trigger = "none",
+		.flags = FLAG_ID_ADP5520_LED3_ADP5501_LED2,
+	},
+#endif
+};
+
+static struct adp5520_leds_platfrom_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,
+};
+
+	/*
+	 *  ADP5520 GPIO Data
+	 */
+
+static struct adp5520_gpio_platfrom_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,
+};
+
+	/*
+	 *  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,
+};
+
+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,
+	.keymap		= adp5520_keymap,
+	.keymapsize	= ARRAY_SIZE(adp5520_keymap),
+	.repeat		= 0,
+};
+
+	/*
+	 *  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,
+};
+
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
 	{
@@ -1105,6 +1305,13 @@ static struct i2c_board_info __initdata
 		.platform_data = (void *)&adp5588_kpad_data,
 	},
 #endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+	{
+		I2C_BOARD_INFO("pmic-adp5520", 0x32),
+		.irq = IRQ_PF7,
+		.platform_data = (void *)&adp5520_pdev_data,
+	},
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1120,8 +1327,11 @@ static struct platform_device bfin_sport
 #endif
 
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-#define PATA_INT	IRQ_PF5
+#define CF_IDE_NAND_CARD_USE_HDD_INTERFACE
+/* #define CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE */
 
+#ifdef CF_IDE_NAND_CARD_USE_HDD_INTERFACE
+#define PATA_INT	IRQ_PF5
 static struct pata_platform_info bfin_pata_platform_data = {
 	.ioport_shift = 1,
 	.irq_flags = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
@@ -1144,6 +1354,24 @@ static struct resource bfin_pata_resourc
 		.flags = IORESOURCE_IRQ,
 	},
 };
+#elif defined(CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE)
+static struct pata_platform_info bfin_pata_platform_data = {
+	.ioport_shift = 0,
+};
+
+static struct resource bfin_pata_resources[] = {
+	{
+		.start = 0x20211820,
+		.end = 0x2021183F,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0x2021181C,
+		.end = 0x2021181F,
+		.flags = IORESOURCE_MEM,
+	},
+};
+#endif
 
 static struct platform_device bfin_pata_device = {
 	.name = "pata_platform",
@@ -1232,6 +1460,11 @@ static struct platform_device *stamp_dev
 	&bfin_spi0_device,
 #endif
 
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+	&bfin_sport_spi0_device,
+	&bfin_sport_spi1_device,
+#endif
+
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
 	&bfin_fb_device,
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -87,6 +87,7 @@
 struct bfin_serial_port {
         struct uart_port        port;
         unsigned int            old_status;
+	int			status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int			tx_done;
@@ -99,7 +100,6 @@ struct bfin_serial_port {
 	struct work_struct	tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	struct timer_list 	cts_timer;
 	int		cts_pin;
 	int 		rts_pin;
 #endif
@@ -125,6 +125,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long	uart_base_addr;
 	int		uart_irq;
+	int		uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int	uart_tx_dma_channel;
 	unsigned int	uart_rx_dma_channel;
@@ -140,6 +141,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC00400,
 	IRQ_UART0_RX,
+	IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART0_TX,
 	CH_UART0_RX,
@@ -154,6 +156,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC02000,
 	IRQ_UART1_RX,
+	IRQ_UART1_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART1_TX,
 	CH_UART1_RX,
@@ -167,29 +170,3 @@ struct bfin_serial_res bfin_serial_resou
 };
 
 #define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	peripheral_request(P_UART0_TX, DRIVER_NAME);
-	peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	peripheral_request(P_UART1_TX, DRIVER_NAME);
-	peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_input(uart->cts_pin);
-	}
-
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -87,6 +87,7 @@
 struct bfin_serial_port {
 	struct uart_port	port;
 	unsigned int		old_status;
+	int			status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int			tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long	uart_base_addr;
 	int		uart_irq;
+	int		uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int	uart_tx_dma_channel;
 	unsigned int	uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC00400,
 	IRQ_UART0_RX,
+	IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART0_TX,
 	CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC02000,
 	IRQ_UART1_RX,
+	IRQ_UART1_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART1_TX,
 	CH_UART1_RX,
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -46,41 +46,27 @@
 #define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
 #define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
 #define UART_SET_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
-#define UART_CLEAR_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
+#define UART_CLEAR_IER(uart,v)  bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
 #define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
 #define UART_PUT_LSR(uart,v)	bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
 #define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
 #define UART_CLEAR_LSR(uart)    bfin_write16(((uart)->port.membase + OFFSET_LSR), -1)
 #define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
 #define UART_PUT_MCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
+#define UART_CLEAR_SCTS(uart)   bfin_write16(((uart)->port.membase + OFFSET_MSR),SCTS)
 
 #define UART_SET_DLAB(uart)     /* MMRs not muxed on BF54x */
 #define UART_CLEAR_DLAB(uart)   /* MMRs not muxed on BF54x */
 
 #define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
-#define UART_SET_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS))
-#define UART_CLEAR_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) & ~MRTS))
+#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS|MRTS))
+#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
 #define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)
 
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART2_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_CTS_PIN
-#  define CONFIG_UART2_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_RTS_PIN
-#  define CONFIG_UART2_RTS_PIN -1
-# endif
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \
+	defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS)
+# define CONFIG_SERIAL_BFIN_HARD_CTSRTS
 #endif
 
 #define BFIN_UART_TX_FIFO_SIZE	2
@@ -91,6 +77,7 @@
 struct bfin_serial_port {
         struct uart_port        port;
         unsigned int            old_status;
+	int			status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int			tx_done;
 	int			tx_count;
@@ -101,23 +88,24 @@ struct bfin_serial_port {
 	unsigned int		rx_dma_channel;
 	struct work_struct	tx_dma_workqueue;
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	struct timer_list 	cts_timer;
-	int		cts_pin;
-	int 		rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	int			scts;
+	int			cts_pin;
+	int			rts_pin;
 #endif
 };
 
 struct bfin_serial_res {
 	unsigned long	uart_base_addr;
 	int		uart_irq;
+	int		uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int	uart_tx_dma_channel;
 	unsigned int	uart_rx_dma_channel;
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int	uart_cts_pin;
-	int	uart_rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	int		uart_cts_pin;
+	int		uart_rts_pin;
 #endif
 };
 
@@ -126,13 +114,14 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC00400,
 	IRQ_UART0_RX,
+	IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART0_TX,
 	CH_UART0_RX,
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART0_CTS_PIN,
-	CONFIG_UART0_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	0,
+	0,
 #endif
 	},
 #endif
@@ -140,13 +129,14 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC02000,
 	IRQ_UART1_RX,
+	IRQ_UART1_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART1_TX,
 	CH_UART1_RX,
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	0,
-	0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	GPIO_PE10,
+	GPIO_PE9,
 #endif
 	},
 #endif
@@ -154,13 +144,14 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC02100,
 	IRQ_UART2_RX,
+	IRQ_UART2_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART2_TX,
 	CH_UART2_RX,
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART2_CTS_PIN,
-	CONFIG_UART2_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	0,
+	0,
 #endif
 	},
 #endif
@@ -168,61 +159,17 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC03100,
 	IRQ_UART3_RX,
+	IRQ_UART3_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART3_TX,
 	CH_UART3_RX,
 #endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	0,
-	0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+	GPIO_PB3,
+	GPIO_PB2,
 #endif
 	},
 #endif
 };
 
 #define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	peripheral_request(P_UART0_TX, DRIVER_NAME);
-	peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	peripheral_request(P_UART1_TX, DRIVER_NAME);
-	peripheral_request(P_UART1_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART1_CTSRTS
-	peripheral_request(P_UART1_RTS, DRIVER_NAME);
-	peripheral_request(P_UART1_CTS, DRIVER_NAME);
-#endif
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART2
-	peripheral_request(P_UART2_TX, DRIVER_NAME);
-	peripheral_request(P_UART2_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART3
-	peripheral_request(P_UART3_TX, DRIVER_NAME);
-	peripheral_request(P_UART3_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART3_CTSRTS
-	peripheral_request(P_UART3_RTS, DRIVER_NAME);
-	peripheral_request(P_UART3_CTS, DRIVER_NAME);
-#endif
-#endif
-	SSYNC();
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_input(uart->cts_pin);
-	}
-
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf548/include/mach/blackfin.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,8 +32,6 @@
 #ifndef _MACH_BLACKFIN_H_
 #define _MACH_BLACKFIN_H_
 
-#define BF548_FAMILY
-
 #include "bf548.h"
 #include "mem_map.h"
 #include "anomaly.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,9 +53,9 @@
 #define UART_SET_DLAB(uart)     do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
 #define UART_CLEAR_DLAB(uart)   do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
 
-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
 #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
 #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
 
@@ -74,6 +74,7 @@
 struct bfin_serial_port {
         struct uart_port        port;
         unsigned int            old_status;
+	int			status_irq;
 	unsigned int lsr;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	int			tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct
 struct bfin_serial_res {
 	unsigned long	uart_base_addr;
 	int		uart_irq;
+	int		uart_status_irq;
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	unsigned int	uart_tx_dma_channel;
 	unsigned int	uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resou
 	{
 	0xFFC00400,
 	IRQ_UART_RX,
+	IRQ_UART_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	CH_UART_TX,
 	CH_UART_RX,
@@ -142,23 +145,3 @@ struct bfin_serial_res bfin_serial_resou
 };
 
 #define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	peripheral_request(P_UART0_TX, DRIVER_NAME);
-	peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	if (uart->cts_pin >= 0) {
-		gpio_request(uart->cts_pin, DRIVER_NAME);
-		gpio_direction_input(uart->cts_pin);
-	}
-	if (uart->rts_pin >= 0) {
-		gpio_request(uart->rts_pin, DRIVER_NAME);
-		gpio_direction_output(uart->rts_pin, 0);
-	}
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-common/entry.S linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/entry.S
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-common/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -1581,6 +1581,8 @@ ENTRY(_sys_call_table)
 	.long _sys_dup3
 	.long _sys_pipe2
 	.long _sys_inotify_init1	/* 365 */
+	.long _sys_preadv
+	.long _sys_pwritev
 
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mach-common/pm.c linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/pm.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/mach-common/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -287,7 +287,7 @@ int bfin_pm_suspend_mem_enter(void)
 static int bfin_pm_valid(suspend_state_t state)
 {
 	return (state == PM_SUSPEND_STANDBY
-#ifndef BF533_FAMILY
+#if !(defined(BF533_FAMILY) || defined(CONFIG_BF561))
 	/*
 	 * On BF533/2/1:
 	 * If we enter Hibernate the SCKE Pin is driven Low,
diff -druNp linux-libre-2.6.29-gnu1/arch/blackfin/mm/sram-alloc.c linux-libre-2.6.30-gnu1/arch/blackfin/mm/sram-alloc.c
--- linux-libre-2.6.29-gnu1/arch/blackfin/mm/sram-alloc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/blackfin/mm/sram-alloc.c	2009-06-09 23:05:27.000000000 -0400
@@ -854,7 +854,6 @@ static int __init sram_proc_init(void)
 		printk(KERN_WARNING "unable to create /proc/sram\n");
 		return -1;
 	}
-	ptr->owner = THIS_MODULE;
 	ptr->read_proc = sram_proc_read;
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/decompress.lds linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/decompress.lds
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/decompress.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/decompress.lds	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/* OUTPUT_FORMAT(elf32-us-cris) */
-OUTPUT_FORMAT(elf32-cris)
-
-MEMORY 
-	{
-	dram : ORIGIN = 0x40700000,
-	       LENGTH = 0x00100000
-	}
-
-SECTIONS
-{
-	.text :
-	{
-		_stext = . ;
-		*(.text)
-		*(.rodata)
-		*(.rodata.*)
-		_etext = . ;
-	} > dram
-	.data :
-	{
-		*(.data)
-		_edata = . ;
-	} > dram
-	.bss :
-	{
-		*(.bss)
-		_end = ALIGN( 0x10 ) ;
-	} > dram
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/head.S linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/head.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/head.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,126 +0,0 @@
-/*
- *  arch/cris/boot/compressed/head.S
- *
- *  Copyright (C) 1999, 2001 Axis Communications AB
- *
- *  Code that sets up the DRAM registers, calls the
- *  decompressor to unpack the piggybacked kernel, and jumps.
- *
- */
-
-#define ASSEMBLER_MACROS_ONLY
-#include <arch/sv_addr_ag.h>
-
-#define RAM_INIT_MAGIC 0x56902387
-#define COMMAND_LINE_MAGIC 0x87109563
-
-	;; Exported symbols
-
-	.globl	input_data
-
-
-	.text
-
-	nop
-	di
-
-;; We need to initialze DRAM registers before we start using the DRAM
-
-	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
-	beq	dram_init_finished
-	nop
-
-#include "../../lib/dram_init.S"
-
-dram_init_finished:
-
-	;; Initiate the PA and PB ports
-
-	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
-	move.b   $r0, [R_PORT_PA_DATA]
-
-	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
-	move.b   $r0, [R_PORT_PA_DIR]
-
-	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
-	move.b   $r0, [R_PORT_PB_DATA]
-
-	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
-	move.b   $r0, [R_PORT_PB_DIR]
-
-	;; Setup the stack to a suitably high address.
-	;; We assume 8 MB is the minimum DRAM in an eLinux
-	;; product and put the sp at the top for now.
-
-	move.d	0x40800000, $sp
-
-	;; Figure out where the compressed piggyback image is
-	;; in the flash (since we wont try to copy it to DRAM
-	;; before unpacking). It is at _edata, but in flash.
-	;; Use (_edata - basse) as offset to the current PC.
-
-basse:	move.d	$pc, $r5
-	and.d	0x7fffffff, $r5	; strip any non-cache bit
-	subq	2, $r5		; compensate for the move.d $pc instr
-	move.d	$r5, $r0		; save for later - flash address of 'basse'
-	add.d	_edata, $r5
-	sub.d	basse, $r5	; $r5 = flash address of '_edata'
-
-	;; Copy text+data to DRAM
-
-	move.d	basse, $r1	; destination
-	move.d	_edata, $r2	; end destination
-1:	move.w	[$r0+], $r3
-	move.w	$r3, [$r1+]
-	cmp.d	$r2, $r1
-	bcs	1b
-	nop
-
-	move.d	$r5, [input_data] ; for the decompressor
-
-
-	;; Clear the decompressors BSS (between _edata and _end)
-
-	moveq	0, $r0
-	move.d	_edata, $r1
-	move.d	_end, $r2
-1:	move.w	$r0, [$r1+]
-	cmp.d	$r2, $r1
-	bcs	1b
-	nop
-
-	;;  Save command line magic and address.
-	move.d	_cmd_line_magic, $r12
-	move.d  $r10, [$r12]
-	move.d	_cmd_line_addr, $r12
-	move.d  $r11, [$r12]
-
-	;; Do the decompression and save compressed size in inptr
-
-	jsr	decompress_kernel
-
-	;; Put start address of root partition in $r9 so the kernel can use it
-	;; when mounting from flash
-
-	move.d	[input_data], $r9	; flash address of compressed kernel
-	add.d	[inptr], $r9		; size of compressed kernel
-
-	;; Restore command line magic and address.
-	move.d  _cmd_line_magic, $r10
-	move.d  [$r10], $r10
-	move.d  _cmd_line_addr, $r11
-	move.d  [$r11], $r11
-
-	;; Enter the decompressed kernel
-	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
-	jump	0x40004000	; kernel is linked to this address
-
-	.data
-
-input_data:
-	.dword	0		; used by the decompressor
-_cmd_line_magic:
-	.dword 0
-_cmd_line_addr:
-	.dword 0
-#include "../../lib/hw_settings.S"
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-#
-# arch/cris/arch-v10/boot/compressed/Makefile
-#
-
-asflags-y += $(LINUXINCLUDE)
-ccflags-y += -O2 $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-
-quiet_cmd_image = BUILD   $@
-cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
-
-targets := vmlinux piggy.gz decompress.o decompress.bin
-
-$(obj)/decompress.o: $(OBJECTS) FORCE
-	$(call if_changed,ld)
-
-$(obj)/decompress.bin: $(obj)/decompress.o FORCE
-	$(call if_changed,objcopy)
-
-$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
-	$(call if_changed,image)
-
-$(obj)/piggy.gz: $(obj)/../Image FORCE
-	$(call if_changed,gzip)
-
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/misc.c linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/misc.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/misc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/misc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,246 +0,0 @@
-/*
- * misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adaptation for Linux/CRIS Axis Communications AB, 1999
- *
- */
-
-/* where the piggybacked kernel image expects itself to live.
- * it is the same address we use when we network load an uncompressed
- * image into DRAM, and it is the address the kernel is linked to live
- * at by vmlinux.lds.S
- */
-
-#define KERNEL_LOAD_ADR 0x40004000
-
-
-#include <linux/types.h>
-#include <arch/svinto.h>
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-void *memset(void *s, int c, size_t n);
-void *memcpy(void *__dest, __const void *__src, size_t __n);
-
-#define memzero(s, n)     memset((s), 0, (n))
-
-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 */
-
-unsigned inptr = 0;	/* index of next byte to be processed in inbuf
-			 * After decompression it will contain the
-			 * compressed size, and head.S will read it.
-			 */
-
-static unsigned outcnt = 0;  /* 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() (inbuf[inptr++])
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond, msg) do { \
-		if (!(cond)) \
-			error(msg); \
-	} while (0)
-#  define Trace(x) fprintf x
-#  define Tracev(x) do { \
-		if (verbose) \
-			fprintf x; \
-	} while (0)
-#  define Tracevv(x) do { \
-		if (verbose > 1) \
-			fprintf x; \
-	} while (0)
-#  define Tracec(c, x) do { \
-		if (verbose && (c)) \
-			fprintf x; \
-	} while (0)
-#  define Tracecv(c, x) do { \
-		if (verbose > 1 && (c)) \
-			fprintf x; \
-	} while (0)
-#else
-#  define Assert(cond, msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c, x)
-#  define Tracecv(c, x)
-#endif
-
-static void flush_window(void);
-static void error(char *m);
-
-extern char *input_data;  /* lives in head.S */
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-static void puts(const char *);
-
-/* the "heap" is put directly after the BSS ends, at end */
-
-extern int _end;
-static long free_mem_ptr = (long)&_end;
-static long free_mem_end_ptr;
-
-#include "../../../../../lib/inflate.c"
-
-/* decompressor info and error messages to serial console */
-
-static void
-puts(const char *s)
-{
-#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
-	while (*s) {
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
-		while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
-		*R_SERIAL0_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
-		while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
-		*R_SERIAL1_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
-		while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
-		*R_SERIAL2_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
-		while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
-		*R_SERIAL3_TR_DATA = *s++;
-#endif
-	}
-#endif
-}
-
-void *memset(void *s, int c, size_t n)
-{
-	int i;
-	char *ss = (char *)s;
-
-	for (i = 0; i < n; i++)
-		ss[i] = c;
-
-	return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-	int i;
-	char *d = (char *)__dest, *s = (char *)__src;
-
-	for (i = 0; i < __n; i++)
-		d[i] = s[i];
-
-	return __dest;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void flush_window(void)
-{
-	ulg c = crc;         /* temporary variable */
-	unsigned n;
-	uch *in, *out, ch;
-
-	in = window;
-	out = &output_data[output_ptr];
-	for (n = 0; n < outcnt; n++) {
-		ch = *out = *in;
-		out++;
-		in++;
-		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-	}
-	crc = c;
-	bytes_out += (ulg)outcnt;
-	output_ptr += (ulg)outcnt;
-	outcnt = 0;
-}
-
-static void error(char *x)
-{
-	puts("\n\n");
-	puts(x);
-	puts("\n\n -- System halted\n");
-
-	while (1);	/* Halt */
-}
-
-void setup_normal_output_buffer(void)
-{
-	output_data = (char *)KERNEL_LOAD_ADR;
-}
-
-void decompress_kernel(void)
-{
-	char revision;
-
-	/* input_data is set in head.S */
-	inbuf = input_data;
-
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
-	*R_SERIAL0_XOFF = 0;
-	*R_SERIAL0_BAUD = 0x99;
-	*R_SERIAL0_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
-	*R_SERIAL1_XOFF = 0;
-	*R_SERIAL1_BAUD = 0x99;
-	*R_SERIAL1_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
-	*R_GEN_CONFIG = 0x08;
-	*R_SERIAL2_XOFF = 0;
-	*R_SERIAL2_BAUD = 0x99;
-	*R_SERIAL2_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
-	*R_GEN_CONFIG = 0x100;
-	*R_SERIAL3_XOFF = 0;
-	*R_SERIAL3_BAUD = 0x99;
-	*R_SERIAL3_TR_CTRL = 0x40;
-#endif
-
-	setup_normal_output_buffer();
-
-	makecrc();
-
-	__asm__ volatile ("move $vr,%0" : "=rm" (revision));
-	if (revision < 10) {
-		puts("You need an ETRAX 100LX to run linux 2.6\n");
-		while (1);
-	}
-
-	puts("Uncompressing Linux...\n");
-	gunzip();
-	puts("Done. Now booting the kernel.\n");
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/README linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/README
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/compressed/README	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/compressed/README	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-Creation of the self-extracting compressed kernel image (vmlinuz)
------------------------------------------------------------------
-$Id: README,v 1.1 2001/12/17 13:59:27 bjornw Exp $
-
-This can be slightly confusing because it's a process with many steps.
-
-The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
-by that makefile into text and data binary files, vmlinux.text and 
-vmlinux.data.
-
-Those files together with a ROM filesystem can be catted together and
-burned into a flash or executed directly at the DRAM origin.
-
-They can also be catted together and compressed with gzip, which is what
-happens in this makefile. Together they make up piggy.img. 
-
-The decompressor is built into the file decompress.o. It is turned into
-the binary file decompress.bin, which is catted together with piggy.img
-into the file vmlinuz. It can be executed in an arbitrary place in flash.
-
-Be careful - it assumes some things about free locations in DRAM. It
-assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
-so it puts its code at 0x40700000, and initial stack at 0x40800000.
-
--Bjorn
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/.gitignore linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/.gitignore
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/.gitignore	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/.gitignore	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-Image
-zImage
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-#
-# arch/cris/arch-v10/boot/Makefile
-#
-
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-
-subdir- := compressed rescue
-targets := Image
-
-$(obj)/Image: vmlinux FORCE
-	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready'
-
-$(obj)/compressed/vmlinux: $(obj)/Image FORCE
-	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
-	$(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
-
-$(obj)/zImage:  $(obj)/compressed/vmlinux
-	@cp $< $@
-	@echo '  Kernel: $@ is ready'
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/head.S linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/head.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/head.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,360 +0,0 @@
-/*
- * Rescue code, made to reside at the beginning of the
- * flash-memory. when it starts, it checks a partition
- * table at the first sector after the rescue sector.
- * the partition table was generated by the product builder
- * script and contains offsets, lengths, types and checksums
- * for each partition that this code should check.
- *
- * If any of the checksums fail, we assume the flash is so
- * corrupt that we cant use it to boot into the ftp flash
- * loader, and instead we initialize the serial port to
- * receive a flash-loader and new flash image. we dont include
- * any flash code here, but just accept a certain amount of
- * bytes from the serial port and jump into it. the downloaded
- * code is put in the cache.
- *
- * The partitiontable is designed so that it is transparent to
- * code execution - it has a relative branch opcode in the
- * beginning that jumps over it. each entry contains extra
- * data so we can add stuff later.
- *
- * Partition table format:
- *
- *     Code transparency:
- *
- *     2 bytes    [opcode 'nop']
- *     2 bytes    [opcode 'di']
- *     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
- *     2 bytes    [opcode 'nop', delay slot]
- *
- *     Table validation (at +10):
- *
- *     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
- *     2 bytes    [length of all entries plus the end marker]
- *     4 bytes    [checksum for the partitiontable itself]
- *
- *     Entries, each with the following format, last has offset -1:
- *
- *        4 bytes    [offset in bytes, from start of flash]
- *        4 bytes    [length in bytes of partition]
- *        4 bytes    [checksum, simple longword sum]
- *        2 bytes    [partition type]
- *        2 bytes    [flags, only bit 0 used, ro/rw = 1/0]
- *        16 bytes   [reserved for future use]
- *
- *     End marker
- *
- *        4 bytes    [-1]
- *
- *	 10 bytes    [0, padding]
- *
- * Bit 0 in flags signifies RW or RO. The rescue code only bothers
- * to check the checksum for RO partitions, since the others will
- * change their data without updating the checksums. A 1 in bit 0
- * means RO, 0 means RW. That way, it is possible to set a partition
- * in RO mode initially, and later mark it as RW, since you can always
- * write 0's to the flash.
- *
- * During the wait for serial input, the status LED will flash so the
- * user knows something went wrong.
- *
- * Copyright (C) 1999-2007 Axis Communications AB
- */
-
-#ifdef CONFIG_ETRAX_AXISFLASHMAP
-
-#define ASSEMBLER_MACROS_ONLY
-#include <arch/sv_addr_ag.h>
-
-	;; The partitiontable is looked for at the first sector after the boot
-	;; sector. Sector size is 65536 bytes in all flashes we use.
-
-#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
-#define PTABLE_MAGIC 0xbeef
-
-	;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
-	;; That is not where we put our downloaded serial boot-code.
-	;; The length is enough for downloading code that loads the rest
-	;; of itself (after having setup the DRAM etc).
-	;; It is the same length as the on-chip ROM loads, so the same
-	;; host loader can be used to load a rescued product as well as
-	;; one booted through the Etrax serial boot code.
-
-#define CODE_START 0x40000000
-#define CODE_LENGTH 784
-
-#ifdef CONFIG_ETRAX_RESCUE_SER0
-#define SERXOFF R_SERIAL0_XOFF
-#define SERBAUD R_SERIAL0_BAUD
-#define SERRECC R_SERIAL0_REC_CTRL
-#define SERRDAT R_SERIAL0_REC_DATA
-#define SERSTAT R_SERIAL0_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER1
-#define SERXOFF R_SERIAL1_XOFF
-#define SERBAUD R_SERIAL1_BAUD
-#define SERRECC R_SERIAL1_REC_CTRL
-#define SERRDAT R_SERIAL1_REC_DATA
-#define SERSTAT R_SERIAL1_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER2
-#define SERXOFF R_SERIAL2_XOFF
-#define SERBAUD R_SERIAL2_BAUD
-#define SERRECC R_SERIAL2_REC_CTRL
-#define SERRDAT R_SERIAL2_REC_DATA
-#define SERSTAT R_SERIAL2_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER3
-#define SERXOFF R_SERIAL3_XOFF
-#define SERBAUD R_SERIAL3_BAUD
-#define SERRECC R_SERIAL3_REC_CTRL
-#define SERRDAT R_SERIAL3_REC_DATA
-#define SERSTAT R_SERIAL3_STATUS
-#endif
-
-#define NOP_DI 0xf025050f
-#define RAM_INIT_MAGIC 0x56902387
-
-	.text
-
-	;; This is the entry point of the rescue code
-	;; 0x80000000 if loaded in flash (as it should be)
-	;; Since etrax actually starts at address 2 when booting from flash, we
-	;; put a nop (2 bytes) here first so we dont accidentally skip the di
-
-	nop
-	di
-
-	jump	in_cache	; enter cached area instead
-in_cache:
-
-
-	;; First put a jump test to give a possibility of upgrading the
-	;; rescue code without erasing/reflashing the sector.
-	;; We put a longword of -1 here and if it is not -1, we jump using
-	;; the value as jump target. Since we can always change 1's to 0's
-	;; without erasing the sector, it is possible to add new
-	;; code after this and altering the jumptarget in an upgrade.
-
-jtcd:	move.d	[jumptarget], $r0
-	cmp.d	0xffffffff, $r0
-	beq	no_newjump
-	nop
-
-	jump	[$r0]
-
-jumptarget:
-	.dword	0xffffffff	; can be overwritten later to insert new code
-
-no_newjump:
-#ifdef CONFIG_ETRAX_ETHERNET
-	;; Start MII clock to make sure it is running when tranceiver is reset
-	move.d 0x3, $r0    ; enable = on, phy = mii_clk
-	move.d $r0, [R_NETWORK_GEN_CONFIG]
-#endif
-
-	;; We need to setup the bus registers before we start using the DRAM
-#include "../../lib/dram_init.S"
-
-	;; we now should go through the checksum-table and check the listed
-	;; partitions for errors.
-
-	move.d	PTABLE_START, $r3
-	move.d	[$r3], $r0
-	cmp.d	NOP_DI, $r0	; make sure the nop/di is there...
-	bne	do_rescue
-	nop
-
-	;; skip the code transparency block (10 bytes).
-
-	addq	10, $r3
-
-	;; check for correct magic
-
-	move.w	[$r3+], $r0
-	cmp.w	PTABLE_MAGIC, $r0
-	bne	do_rescue	; didn't recognize - trig rescue
-	nop
-
-	;; check for correct ptable checksum
-
-	movu.w	[$r3+], $r2	; ptable length
-	move.d	$r2, $r8	; save for later, length of total ptable
-	addq	28, $r8		; account for the rest
-	move.d	[$r3+], $r4	; ptable checksum
-	move.d	$r3, $r1
-	jsr	checksum	; r1 source, r2 length, returns in r0
-
-	cmp.d	$r0, $r4
-	bne	do_rescue	; didn't match - trig rescue
-	nop
-
-	;; ptable is ok. validate each entry.
-
-	moveq	-1, $r7
-
-ploop:	move.d	[$r3+], $r1	; partition offset (from ptable start)
-	bne	notfirst	; check if it is the partition containing ptable
-	nop			; yes..
-	move.d	$r8, $r1	; for its checksum check, skip the ptable
-	move.d	[$r3+], $r2	; partition length
-	sub.d	$r8, $r2	; minus the ptable length
-	ba	bosse
-	nop
-notfirst:
-	cmp.d	-1, $r1		; the end of the ptable ?
-	beq	flash_ok	;   if so, the flash is validated
-	move.d	[$r3+], $r2	; partition length
-bosse:	move.d	[$r3+], $r5	; checksum
-	move.d	[$r3+], $r4	; type and flags
-	addq	16, $r3		; skip the reserved bytes
-	btstq	16, $r4		; check ro flag
-	bpl	ploop		;   rw partition, skip validation
-	nop
-	btstq	17, $r4		; check bootable flag
-	bpl	1f
-	nop
-	move.d	$r1, $r7	; remember boot partition offset
-1:
-	add.d	PTABLE_START, $r1
-
-	jsr	checksum	; checksum the partition
-
-	cmp.d	$r0, $r5
-	beq	ploop		; checksums matched, go to next entry
-	nop
-
-	;; otherwise fall through to the rescue code.
-
-do_rescue:
-	;; setup port PA and PB default initial directions and data
-	;; (so we can flash LEDs, and so that DTR and others are set)
-
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
-	move.b	$r0, [R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
-	move.b	$r0, [R_PORT_PA_DATA]
-
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
-	move.b	$r0, [R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
-	move.b	$r0, [R_PORT_PB_DATA]
-
-	;; setup the serial port at 115200 baud
-
-	moveq	0, $r0
-	move.d	$r0, [SERXOFF]
-
-	move.b	0x99, $r0
-	move.b	$r0, [SERBAUD]	; 115.2kbaud for both transmit and receive
-
-	move.b	0x40, $r0	; rec enable
-	move.b	$r0, [SERRECC]
-
-	moveq	0, $r1		; "timer" to clock out a LED red flash
-	move.d	CODE_START, $r3	; destination counter
-	movu.w	CODE_LENGTH, $r4; length
-
-wait_ser:
-	addq	1, $r1
-#ifndef CONFIG_ETRAX_NO_LEDS
-#ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
-#endif
-#ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
-#endif
-	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
-	btstq	16, $r1
-	bpl	1f
-	nop
-	or.d	$r0, $r2	; set bit
-	ba	2f
-	nop
-1:	not	$r0		; clear bit
-	and.d	$r0, $r2
-2:
-#ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	$r2, [R_PORT_PA_DATA]
-#endif
-#ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	$r2, [R_PORT_PB_DATA]
-#endif
-#ifdef CONFIG_ETRAX_90000000_LEDS
-	move.b	$r2, [0x90000000]
-#endif
-#endif
-
-	;; check if we got something on the serial port
-
-	move.b	[SERSTAT], $r0
-	btstq	0, $r0		; data_avail
-	bpl	wait_ser
-	nop
-
-	;; got something - copy the byte and loop
-
-	move.b	[SERRDAT], $r0
-	move.b	$r0, [$r3+]
-
-	subq	1, $r4		; decrease length
-	bne	wait_ser
-	nop
-
-	;; jump into downloaded code
-
-	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is
-					; initialized
-	jump	CODE_START
-
-flash_ok:
-	;; check r7, which contains either -1 or the partition to boot from
-
-	cmp.d	-1, $r7
-	bne	1f
-	nop
-	move.d	PTABLE_START, $r7; otherwise use the ptable start
-1:
-	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is
-					; initialized
-	jump	$r7		; boot!
-
-
-	;; Helper subroutines
-
-	;; Will checksum by simple addition
-	;; r1 - source
-	;; r2 - length in bytes
-	;; result will be in r0
-checksum:
-	moveq	0, $r0
-	moveq   CONFIG_ETRAX_FLASH1_SIZE, $r6
-
-	;; If the first physical flash memory is exceeded wrap to the
-	;; second one
-	btstq	26, $r1		; Are we addressing first flash?
-	bpl	1f
-	nop
-	clear.d	$r6
-
-1:	test.d  $r6		; 0 = no wrapping
-	beq	2f
-	nop
-	lslq	20, $r6		; Convert MB to bytes
-	sub.d	$r1, $r6
-
-2:	addu.b	[$r1+], $r0
-	subq	1, $r6		; Flash memory left
-	beq	3f
-	subq	1, $r2		; Length left
-	bne	2b
-	nop
-	ret
-	nop
-
-3:	move.d	MEM_CSE1_START, $r1 ; wrap to second flash
-	ba	2b
-	nop
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/kimagerescue.S linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/kimagerescue.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/kimagerescue.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/kimagerescue.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,143 +0,0 @@
-/*
- * Rescue code to be prepended on a kimage and copied to the
- * rescue serial port.
- * This is called from the rescue code, it will copy received data to
- * 4004000 and after a timeout jump to it.
- */
-
-#define ASSEMBLER_MACROS_ONLY
-#include <arch/sv_addr_ag.h>
-
-#define CODE_START 0x40004000
-#define CODE_LENGTH 784
-#define TIMEOUT_VALUE 1000
-
-
-#ifdef CONFIG_ETRAX_RESCUE_SER0
-#define SERXOFF R_SERIAL0_XOFF
-#define SERBAUD R_SERIAL0_BAUD
-#define SERRECC R_SERIAL0_REC_CTRL
-#define SERRDAT R_SERIAL0_REC_DATA
-#define SERSTAT R_SERIAL0_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER1
-#define SERXOFF R_SERIAL1_XOFF
-#define SERBAUD R_SERIAL1_BAUD
-#define SERRECC R_SERIAL1_REC_CTRL
-#define SERRDAT R_SERIAL1_REC_DATA
-#define SERSTAT R_SERIAL1_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER2
-#define SERXOFF R_SERIAL2_XOFF
-#define SERBAUD R_SERIAL2_BAUD
-#define SERRECC R_SERIAL2_REC_CTRL
-#define SERRDAT R_SERIAL2_REC_DATA
-#define SERSTAT R_SERIAL2_STATUS
-#endif
-#ifdef CONFIG_ETRAX_RESCUE_SER3
-#define SERXOFF R_SERIAL3_XOFF
-#define SERBAUD R_SERIAL3_BAUD
-#define SERRECC R_SERIAL3_REC_CTRL
-#define SERRDAT R_SERIAL3_REC_DATA
-#define SERSTAT R_SERIAL3_STATUS
-#endif
-
-	.text
-	;; This is the entry point of the rescue code
-	;; 0x80000000 if loaded in flash (as it should be)
-	;; since etrax actually starts at address 2 when booting from flash, we
-	;; put a nop (2 bytes) here first so we dont accidentally skip the di
-
-	nop
-	di
-#ifndef CONFIG_SVINTO_SIM
-	;; setup port PA and PB default initial directions and data
-	;; (so we can flash LEDs, and so that DTR and others are set)
-
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
-	move.b	$r0, [R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
-	move.b	$r0, [R_PORT_PA_DATA]
-
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
-	move.b	$r0, [R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
-	move.b	$r0, [R_PORT_PB_DATA]
-
-	;; We need to setup the bus registers before we start using the DRAM
-#include "../../lib/dram_init.S"
-
-#endif
-	;; Setup the stack to a suitably high address.
-	;; We assume 8 MB is the minimum DRAM in an eLinux
-	;; product and put the sp at the top for now.
-
-	move.d	0x40800000, $sp
-
-	;; setup the serial port at 115200 baud
-
-	moveq	0, $r0
-	move.d	$r0, [SERXOFF]
-
-	move.b	0x99, $r0
-	move.b	$r0, [SERBAUD]		; 115.2kbaud for both transmit
-					; and receive
-
-	move.b	0x40, $r0		; rec enable
-	move.b	$r0, [SERRECC]
-
-
-	moveq	0, $r1			; "timer" to clock out a LED red flash
-	move.d	CODE_START, $r3		; destination counter
-	move.d	CODE_LENGTH, $r4	; length
-	move.d	TIMEOUT_VALUE, $r5	; "timeout" until jump
-
-wait_ser:
-	addq	1, $r1
-	subq	1, $r5			; decrease timeout
-	beq	jump_start		; timed out
-	nop
-#ifndef CONFIG_ETRAX_NO_LEDS
-#ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
-#endif
-#ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
-#endif
-	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
-	btstq	16, $r1
-	bpl	1f
-	nop
-	or.d	$r0, $r2		; set bit
-	ba	2f
-	nop
-1:	not	$r0			; clear bit
-	and.d	$r0, $r2
-2:
-#ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	$r2, [R_PORT_PA_DATA]
-#endif
-#ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	$r2, [R_PORT_PB_DATA]
-#endif
-#endif
-
-	;; check if we got something on the serial port
-
-	move.b	[SERSTAT], $r0
-	btstq	0, $r0			; data_avail
-	bpl	wait_ser
-	nop
-
-	;; got something - copy the byte and loop
-
-	move.b	[SERRDAT], $r0
-	move.b	$r0, [$r3+]
-	move.d	TIMEOUT_VALUE, $r5	; reset "timeout"
-	subq	1, $r4			; decrease length
-	bne	wait_ser
-	nop
-jump_start:
-	;; jump into downloaded code
-
-	jump	CODE_START
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-#
-# Makefile for rescue (bootstrap) code
-#
-
-ccflags-y += -O2 $(LINUXINCLUDE)
-asflags-y += $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
-
-targets := rescue.o rescue.bin
-
-$(obj)/rescue.o: $(OBJECT) FORCE
-	$(call if_changed,ld)
-
-$(obj)/rescue.bin: $(obj)/rescue.o FORCE
-	$(call if_changed,objcopy)
-	cp -p $(obj)/rescue.bin $(objtree)
-
-$(obj)/testrescue.bin: $(obj)/testrescue.o
-	$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
-# Pad it to 784 bytes
-	dd if=/dev/zero of=tmp2423 bs=1 count=784
-	cat tr.bin tmp2423 >testrescue_tmp.bin
-	dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
-	rm tr.bin tmp2423 testrescue_tmp.bin
-
-$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
-	$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
-# Pad it to 784 bytes, that's what the rescue loader expects
-	dd if=/dev/zero of=tmp2423 bs=1 count=784
-	cat ktr.bin tmp2423 >kimagerescue_tmp.bin
-	dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
-	rm ktr.bin tmp2423 kimagerescue_tmp.bin
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/rescue.lds linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/rescue.lds
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/rescue.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/rescue.lds	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-MEMORY 
-	{
-	flash : ORIGIN = 0x00000000,
-	        LENGTH = 0x00100000
-	}
-
-SECTIONS
-{
-	.text :
-	{
-		stext = . ;
-		*(.text)
-		etext = . ;
-	} > flash
-	.data :
-	{
-		*(.data)
-		edata = . ;
-	} > flash
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/testrescue.S linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/testrescue.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/rescue/testrescue.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/rescue/testrescue.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * Simple testcode to download by the rescue block.
- * Just lights some LEDs to show it was downloaded correctly.
- *
- * Copyright (C) 1999 Axis Communications AB
- */
-
-#define ASSEMBLER_MACROS_ONLY
-#include <arch/sv_addr_ag.h>
-
-	.text
-
-	nop
-	nop
-	moveq	-1, $r2
-	move.b	$r2, [R_PORT_PA_DIR]
-	moveq	0, $r2
-	move.b	$r2, [R_PORT_PA_DATA]
-
-endless:
-	nop
-	ba	endless
-	nop
-
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/tools/build.c linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/tools/build.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/boot/tools/build.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/boot/tools/build.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,287 +0,0 @@
-/*
- *  linux/tools/build.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/*
- * This file builds a disk-image from three different files:
- *
- * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
- * - setup: 8086 machine code, sets up system parm
- * - system: 80386 code for actual system
- *
- * It does some checking that all files are of the correct type, and
- * just writes the result to stdout, removing headers and padding to
- * the right amount. It also writes some system data to stderr.
- */
-
-/*
- * Changes by tytso to allow root device specification
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- * Cross compiling fixes by Gertjan van Wingerde, July 1996
- */
-
-#include <stdio.h>	/* fprintf */
-#include <string.h>
-#include <stdlib.h>	/* contains exit */
-#include <sys/types.h>	/* unistd.h needs this */
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <unistd.h>	/* contains read/write */
-#include <fcntl.h>
-#include <errno.h>
-
-#define MINIX_HEADER 32
-
-#define N_MAGIC_OFFSET 1024
-#ifndef __BFD__
-static int GCC_HEADER = sizeof(struct exec);
-#endif
-
-#ifdef __BIG_KERNEL__
-#define SYS_SIZE 0xffff
-#else
-#define SYS_SIZE DEF_SYSSIZE
-#endif
-
-#define DEFAULT_MAJOR_ROOT 0
-#define DEFAULT_MINOR_ROOT 0
-
-/* max nr of sectors of setup: don't change unless you also change
- * bootsect etc */
-#define SETUP_SECTS 4
-
-#define STRINGIFY(x) #x
-
-typedef union {
-	int i;
-	long l;
-	short s[2];
-	char b[4];
-} conv;
-
-long intel_long(long l)
-{
-	conv t;
-
-	t.b[0] = l & 0xff; l >>= 8;
-	t.b[1] = l & 0xff; l >>= 8;
-	t.b[2] = l & 0xff; l >>= 8;
-	t.b[3] = l & 0xff; l >>= 8;
-	return t.l;
-}
-
-int intel_int(int i)
-{
-	conv t;
-
-	t.b[0] = i & 0xff; i >>= 8;
-        t.b[1] = i & 0xff; i >>= 8;
-        t.b[2] = i & 0xff; i >>= 8;
-        t.b[3] = i & 0xff; i >>= 8;
-        return t.i;
-}
-
-short intel_short(short l)
-{
-	conv t;
-
-	t.b[0] = l & 0xff; l >>= 8;
-	t.b[1] = l & 0xff; l >>= 8;
-	return t.s[0];
-}
-
-void die(const char * str)
-{
-	fprintf(stderr,"%s\n",str);
-	exit(1);
-}
-
-void usage(void)
-{
-	die("Usage: build bootsect setup system [rootdev] [> image]");
-}
-
-int main(int argc, char ** argv)
-{
-	int i,c,id,sz,tmp_int;
-	unsigned long sys_size, tmp_long;
-	char buf[1024];
-#ifndef __BFD__
-	struct exec *ex = (struct exec *)buf;
-#endif
-	char major_root, minor_root;
-	struct stat sb;
-	unsigned char setup_sectors;
-
-	if ((argc < 4) || (argc > 5))
-		usage();
-	if (argc > 4) {
-		if (!strcmp(argv[4], "CURRENT")) {
-			if (stat("/", &sb)) {
-				perror("/");
-				die("Couldn't stat /");
-			}
-			major_root = major(sb.st_dev);
-			minor_root = minor(sb.st_dev);
-		} else if (strcmp(argv[4], "FLOPPY")) {
-			if (stat(argv[4], &sb)) {
-				perror(argv[4]);
-				die("Couldn't stat root device.");
-			}
-			major_root = major(sb.st_rdev);
-			minor_root = minor(sb.st_rdev);
-		} else {
-			major_root = 0;
-			minor_root = 0;
-		}
-	} else {
-		major_root = DEFAULT_MAJOR_ROOT;
-		minor_root = DEFAULT_MINOR_ROOT;
-	}
-	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
-	for (i=0;i<sizeof buf; i++) buf[i]=0;
-	if ((id=open(argv[1],O_RDONLY,0))<0)
-		die("Unable to open 'boot'");
-	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
-		die("Unable to read header of 'boot'");
-	if (((long *) buf)[0]!=intel_long(0x04100301))
-		die("Non-Minix header of 'boot'");
-	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
-		die("Non-Minix header of 'boot'");
-	if (((long *) buf)[3] != 0)
-		die("Illegal data segment in 'boot'");
-	if (((long *) buf)[4] != 0)
-		die("Illegal bss in 'boot'");
-	if (((long *) buf)[5] != 0)
-		die("Non-Minix header of 'boot'");
-	if (((long *) buf)[7] != 0)
-		die("Illegal symbol table in 'boot'");
-	i=read(id,buf,sizeof buf);
-	fprintf(stderr,"Boot sector %d bytes.\n",i);
-	if (i != 512)
-		die("Boot block must be exactly 512 bytes");
-	if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
-		die("Boot block hasn't got boot flag (0xAA55)");
-	buf[508] = (char) minor_root;
-	buf[509] = (char) major_root;	
-	i=write(1,buf,512);
-	if (i!=512)
-		die("Write call failed");
-	close (id);
-	
-	if ((id=open(argv[2],O_RDONLY,0))<0)
-		die("Unable to open 'setup'");
-	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
-		die("Unable to read header of 'setup'");
-	if (((long *) buf)[0]!=intel_long(0x04100301))
-		die("Non-Minix header of 'setup'");
-	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
-		die("Non-Minix header of 'setup'");
-	if (((long *) buf)[3] != 0)
-		die("Illegal data segment in 'setup'");
-	if (((long *) buf)[4] != 0)
-		die("Illegal bss in 'setup'");
-	if (((long *) buf)[5] != 0)
-		die("Non-Minix header of 'setup'");
-	if (((long *) buf)[7] != 0)
-		die("Illegal symbol table in 'setup'");
-	for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
-#ifdef __BIG_KERNEL__
-	{
-		if (!i) {
-			/* Working with memcpy because of alignment constraints
-			   on Sparc - Gertjan */
-			memcpy(&tmp_long, &buf[2], sizeof(long));
-			if (tmp_long != intel_long(0x53726448) )
-				die("Wrong magic in loader header of 'setup'");
-			memcpy(&tmp_int, &buf[6], sizeof(int));
-			if (tmp_int < intel_int(0x200))
-				die("Wrong version of loader header of 'setup'");
-			buf[0x11] = 1; /* LOADED_HIGH */
-			tmp_long = intel_long(0x100000);
-			memcpy(&buf[0x14], &tmp_long, sizeof(long));  /* code32_start */
-		}
-#endif
-		if (write(1,buf,c)!=c)
-			die("Write call failed");
-#ifdef __BIG_KERNEL__
-	}
-#endif
-	if (c != 0)
-		die("read-error on 'setup'");
-	close (id);
-	setup_sectors = (unsigned char)((i + 511) / 512);
-	/* for compatibility with LILO */
-	if (setup_sectors < SETUP_SECTS)
-		setup_sectors = SETUP_SECTS;
-	fprintf(stderr,"Setup is %d bytes.\n",i);
-	for (c=0 ; c<sizeof(buf) ; c++)
-		buf[c] = '\0';
-	while (i < setup_sectors * 512) {
-		c = setup_sectors * 512 - i;
-		if (c > sizeof(buf))
-			c = sizeof(buf);
-		if (write(1,buf,c) != c)
-			die("Write call failed");
-		i += c;
-	}
-	
-	if ((id=open(argv[3],O_RDONLY,0))<0)
-		die("Unable to open 'system'");
-#ifndef __BFD__
-	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
-		die("Unable to read header of 'system'");
-	if (N_MAGIC(*ex) == ZMAGIC) {
-		GCC_HEADER = N_MAGIC_OFFSET;
-		lseek(id, GCC_HEADER, SEEK_SET);
-	} else if (N_MAGIC(*ex) != QMAGIC)
-		die("Non-GCC header of 'system'");
-	fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
-		(ex->a_text+ex->a_data+ex->a_bss)/1024,
-		ex->a_text /1024,
-		ex->a_data /1024,
-		ex->a_bss  /1024);
-	sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
-#else
-	if (fstat (id, &sb)) {
-	  perror ("fstat");
-	  die ("Unable to stat 'system'");
-	}
-	sz = sb.st_size;
-	fprintf (stderr, "System is %d kB\n", sz/1024);
-#endif
-	sys_size = (sz + 15) / 16;
-	if (sys_size > SYS_SIZE)
-		die("System is too big");
-	while (sz > 0) {
-		int l, n;
-
-		l = sz;
-		if (l > sizeof(buf))
-			l = sizeof(buf);
-		if ((n=read(id, buf, l)) != l) {
-			if (n == -1) 
-				perror(argv[1]);
-			else
-				fprintf(stderr, "Unexpected EOF\n");
-			die("Can't read 'system'");
-		}
-		if (write(1, buf, l) != l)
-			die("Write failed");
-		sz -= l;
-	}
-	close(id);
-	if (lseek(1, 497, 0) == 497) {
-		if (write(1, &setup_sectors, 1) != 1)
-			die("Write of setup sectors failed");
-	}
-	if (lseek(1,500,0) == 500) {
-		buf[0] = (sys_size & 0xff);
-		buf[1] = ((sys_size >> 8) & 0xff);
-		if (write(1, buf, 2) != 2)
-			die("Write failed");
-	}
-	return(0);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/entry.S linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -536,10 +536,10 @@ multiple_interrupt:
 	movem	$r13, [$sp]
 	push	$r10		; push orig_r10
 	clear.d [$sp=$sp-4]	; frametype == 0, normal frame
-	
+
 	move.d  $sp, $r10
 	jsr	do_multiple_IRQ
-	
+
 	jump    ret_from_intr
 
 do_sigtrap:
@@ -585,7 +585,7 @@ _ugdb_handle_breakpoint:
 	pop	$r0			; Restore r0. 
 	ba	do_sigtrap		; SIGTRAP the offending process. 
 	pop	$dccr			; Restore dccr in delay slot.
-	
+
 	.global kernel_execve
 kernel_execve:
 	move.d __NR_execve, $r9
@@ -929,6 +929,14 @@ sys_call_table:
 	.long sys_fallocate
 	.long sys_timerfd_settime	/* 325 */
 	.long sys_timerfd_gettime
+	.long sys_signalfd4
+	.long sys_eventfd2
+	.long sys_epoll_create1
+	.long sys_dup3			/* 330 */
+	.long sys_pipe2
+	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/irq.c linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -132,7 +132,7 @@ static void end_crisv10_irq(unsigned int
 {
 }
 
-static struct hw_interrupt_type crisv10_irq_type = {
+static struct irq_chip crisv10_irq_type = {
 	.typename =    "CRISv10",
 	.startup =     startup_crisv10_irq,
 	.shutdown =    shutdown_crisv10_irq,
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/process.c linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,7 +115,7 @@ int kernel_thread(int (*fn)(void *), voi
  */
 asmlinkage void ret_from_fork(void);
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/time.c linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v10/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v10/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -261,7 +261,6 @@ timer_interrupt(int irq, void *dev_id)
 static struct irqaction irq2  = {
 	.handler = timer_interrupt,
 	.flags = IRQF_SHARED | IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "timer",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/decompress.lds linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/decompress.lds
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/decompress.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/decompress.lds	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*#OUTPUT_FORMAT(elf32-us-cris) */
-OUTPUT_ARCH (crisv32)
-
-MEMORY
-	{
-	dram : ORIGIN = 0x40700000,
-	       LENGTH = 0x00100000
-	}
-
-SECTIONS
-{
-	.text :
-	{
-		_stext = . ;
-		*(.text)
-		*(.rodata)
-		*(.rodata.*)
-		_etext = . ;
-	} > dram
-	.data :
-	{
-		*(.data)
-		_edata = . ;
-	} > dram
-	.bss :
-	{
-		*(.bss)
-		_end = ALIGN( 0x10 ) ;
-	} > dram
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/head.S linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/head.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/head.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-/*
- *  Code that sets up the DRAM registers, calls the
- *  decompressor to unpack the piggybacked kernel, and jumps.
- *
- *  Copyright (C) 1999 - 2006, Axis Communications AB
- */
-
-#define ASSEMBLER_MACROS_ONLY
-#include <hwregs/asm/reg_map_asm.h>
-#include <mach/startup.inc>
-
-#define RAM_INIT_MAGIC 0x56902387
-#define COMMAND_LINE_MAGIC 0x87109563
-
-	;; Exported symbols
-
-	.globl	input_data
-
-	.text
-_start:
-	di
-
-	;; Start clocks for used blocks.
-	START_CLOCKS
-
-	;; Initialize the DRAM registers.
-	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
-	beq	dram_init_finished
-	nop
-
-#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/dram_init.S"
-#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/dram_init.S"
-#else
-#error Only ETRAXFS and ARTPEC-3 supported!
-#endif
-
-dram_init_finished:
-
-	GIO_INIT
-	;; Setup the stack to a suitably high address.
-	;; We assume 8 MB is the minimum DRAM and put
-	;; the SP at the top for now.
-
-	move.d	0x40800000, $sp
-
-	;; Figure out where the compressed piggyback image is.
-	;; It is either in [NOR] flash (we don't want to copy it
-	;; to DRAM before unpacking), or copied to DRAM
-	;; by the [NAND] flash boot loader.
-	;; The piggyback image is at _edata, but relative to where the
-	;; image is actually located in memory, not where it is linked
-	;; (the decompressor is linked at 0x40700000+ and runs there).
-	;; Use (_edata - herami) as offset to the current PC.
-
-hereami:
-	lapcq	., $r5		; get PC
-	and.d	0x7fffffff, $r5	; strip any non-cache bit
-	move.d	$r5, $r0	; source address of 'herami'
-	add.d	_edata, $r5
-	sub.d	hereami, $r5	; r5 = flash address of '_edata'
-	move.d	hereami, $r1	; destination
-
-	;; Copy text+data to DRAM
-
-	move.d	_edata, $r2	; end destination
-1:	move.w	[$r0+], $r3	; from herami+ source
-	move.w	$r3, [$r1+]	; to hereami+ destination (linked address)
-	cmp.d	$r2, $r1	; finish when destination == _edata
-	bcs	1b
-	nop
-	move.d	input_data, $r0 ; for the decompressor
-	move.d	$r5, [$r0]	; for the decompressor
-
-	;; Clear the decompressors BSS (between _edata and _end)
-
-	moveq	0, $r0
-	move.d	_edata, $r1
-	move.d	_end, $r2
-1:	move.w	$r0, [$r1+]
-	cmp.d	$r2, $r1
-	bcs	1b
-	nop
-
-	;;  Save command line magic and address.
-	move.d	_cmd_line_magic, $r0
-	move.d  $r10, [$r0]
-	move.d	_cmd_line_addr, $r0
-	move.d  $r11, [$r0]
-
-	;;  Save boot source indicator
-	move.d	_boot_source, $r0
-	move.d	$r12, [$r0]
-
-	;; Do the decompression and save compressed size in _inptr
-
-	jsr	decompress_kernel
-	nop
-
-	;; Restore boot source indicator
-	move.d	_boot_source, $r12
-	move.d	[$r12], $r12
-
-	;; Restore command line magic and address.
-	move.d  _cmd_line_magic, $r10
-	move.d  [$r10], $r10
-	move.d  _cmd_line_addr, $r11
-	move.d  [$r11], $r11
-
-	;; Put start address of root partition in r9 so the kernel can use it
-	;; when mounting from flash
-	move.d  input_data, $r0
-	move.d	[$r0], $r9		; flash address of compressed kernel
-	move.d  inptr, $r0
-	add.d	[$r0], $r9		; size of compressed kernel
-	cmp.d   0x40000000, $r9		; image in DRAM ?
-	blo	enter_kernel		; no, must be [NOR] flash, jump
-	nop				; delay slot
-	and.d   0x001fffff, $r9		; assume compressed kernel was < 2M
-
-enter_kernel:
-	;; Enter the decompressed kernel
-	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
-	jump	0x40004000	; kernel is linked to this address
-	nop
-
-	.data
-
-input_data:
-	.dword	0		; used by the decompressor
-_cmd_line_magic:
-	.dword 0
-_cmd_line_addr:
-	.dword 0
-_boot_source:
-	.dword 0
-
-#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/hw_settings.S"
-#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/hw_settings.S"
-#else
-#error Only ETRAXFS and ARTPEC-3 supported!
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-#
-# arch/cris/arch-v32/boot/compressed/Makefile
-#
-
-asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-
-quiet_cmd_image = BUILD   $@
-cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
-
-targets := vmlinux piggy.gz decompress.o decompress.bin
-
-$(obj)/decompress.o: $(OBJECTS) FORCE
-	$(call if_changed,ld)
-
-$(obj)/decompress.bin: $(obj)/decompress.o FORCE
-	$(call if_changed,objcopy)
-
-$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
-	$(call if_changed,image)
-
-$(obj)/piggy.gz: $(obj)/../Image FORCE
-	$(call if_changed,gzip)
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/misc.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/misc.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/misc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/misc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,318 +0,0 @@
-/*
- * misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adaptation for Linux/CRIS Axis Communications AB, 1999
- *
- */
-
-/* where the piggybacked kernel image expects itself to live.
- * it is the same address we use when we network load an uncompressed
- * image into DRAM, and it is the address the kernel is linked to live
- * at by vmlinux.lds.S
- */
-
-#define KERNEL_LOAD_ADR 0x40004000
-
-
-#include <linux/types.h>
-#include <hwregs/reg_rdwr.h>
-#include <hwregs/reg_map.h>
-#include <hwregs/ser_defs.h>
-#include <hwregs/pinmux_defs.h>
-#ifdef CONFIG_CRIS_MACH_ARTPEC3
-#include <hwregs/clkgen_defs.h>
-#endif
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-void* memset(void* s, int c, size_t n);
-void* memcpy(void* __dest, __const void* __src,
-	     size_t __n);
-
-#define memzero(s, n)     memset ((s), 0, (n))
-
-
-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 */
-
-unsigned inptr = 0;	/* index of next byte to be processed in inbuf
-			 * After decompression it will contain the
-			 * compressed size, and head.S will read it.
-			 */
-
-static unsigned outcnt = 0;  /* 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() inbuf[inptr++]
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static void flush_window(void);
-static void error(char *m);
-
-extern char *input_data;  /* lives in head.S */
-
-static long bytes_out;
-static uch *output_data;
-static unsigned long output_ptr;
-
-static void error(char *m);
-
-static void puts(const char *);
-
-/* the "heap" is put directly after the BSS ends, at end */
-
-extern int _end;
-static long free_mem_ptr = (long)&_end;
-static long free_mem_end_ptr;
-
-#include "../../../../../lib/inflate.c"
-
-/* decompressor info and error messages to serial console */
-
-static inline void
-serout(const char *s, reg_scope_instances regi_ser)
-{
-	reg_ser_rs_stat_din rs;
-	reg_ser_rw_dout dout = {.data = *s};
-
-	do {
-		rs = REG_RD(ser, regi_ser, rs_stat_din);
-	}
-	while (!rs.tr_rdy);/* Wait for transceiver. */
-
-	REG_WR(ser, regi_ser, rw_dout, dout);
-}
-
-static void
-puts(const char *s)
-{
-#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
-	while (*s) {
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
-		serout(s, regi_ser0);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
-		serout(s, regi_ser1);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
-		serout(s, regi_ser2);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
-		serout(s, regi_ser3);
-#endif
-		*s++;
-	}
-/* CONFIG_ETRAX_DEBUG_PORT_NULL */
-#endif
-}
-
-void*
-memset(void* s, int c, size_t n)
-{
-	int i;
-	char *ss = (char*)s;
-
-	for (i=0;i<n;i++) ss[i] = c;
-
-	return s;
-}
-
-void*
-memcpy(void* __dest, __const void* __src,
-			    size_t __n)
-{
-	int i;
-	char *d = (char *)__dest, *s = (char *)__src;
-
-	for (i=0;i<__n;i++) d[i] = s[i];
-
-	return __dest;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void
-flush_window()
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, *out, ch;
-
-    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;
-}
-
-static void
-error(char *x)
-{
-	puts("\r\n\n");
-	puts(x);
-	puts("\r\n\n -- System halted\n");
-
-	while(1);	/* Halt */
-}
-
-void
-setup_normal_output_buffer(void)
-{
-	output_data = (char *)KERNEL_LOAD_ADR;
-}
-
-static inline void
-serial_setup(reg_scope_instances regi_ser)
-{
-	reg_ser_rw_xoff xoff;
-	reg_ser_rw_tr_ctrl tr_ctrl;
-	reg_ser_rw_rec_ctrl rec_ctrl;
-	reg_ser_rw_tr_baud_div tr_baud;
-	reg_ser_rw_rec_baud_div rec_baud;
-
-	/* Turn off XOFF. */
-	xoff = REG_RD(ser, regi_ser, rw_xoff);
-
-	xoff.chr = 0;
-	xoff.automatic = regk_ser_no;
-
-	REG_WR(ser, regi_ser, rw_xoff, xoff);
-
-	/* Set baudrate and stopbits. */
-	tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
-	rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
-	tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
-	rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
-
-	tr_ctrl.stop_bits = 1;	/* 2 stop bits. */
-	tr_ctrl.en = 1; /* enable transmitter */
-	rec_ctrl.en = 1; /* enabler receiver */
-
-	/*
-	 * The baudrate setup used to be a bit fishy, but now transmitter and
-	 * receiver are both set to the intended baud rate, 115200.
-	 * The magic value is 29.493 MHz.
-	 */
-	tr_ctrl.base_freq = regk_ser_f29_493;
-	rec_ctrl.base_freq = regk_ser_f29_493;
-	tr_baud.div = (29493000 / 8) / 115200;
-	rec_baud.div = (29493000 / 8) / 115200;
-
-	REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
-	REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
-	REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
-	REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
-}
-
-void
-decompress_kernel(void)
-{
-	char revision;
-
-#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
-    defined(CONFIG_ETRAX_DEBUG_PORT2) || \
-    defined(CONFIG_ETRAX_DEBUG_PORT3)
-	reg_pinmux_rw_hwprot hwprot;
-
-#ifdef CONFIG_CRIS_MACH_ARTPEC3
-	reg_clkgen_rw_clk_ctrl clk_ctrl;
-
-	/* Enable corresponding clock region when serial 1..3 selected */
-
-	clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
-	clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
-	REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
-#endif
-
-	/* pinmux setup for ports 1..3 */
-	hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
-#endif
-
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
-	serial_setup(regi_ser0);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
-	hwprot.ser1 = regk_pinmux_yes;
-	serial_setup(regi_ser1);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
-	hwprot.ser2 = regk_pinmux_yes;
-	serial_setup(regi_ser2);
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
-	hwprot.ser3 = regk_pinmux_yes;
-	serial_setup(regi_ser3);
-#endif
-#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
-    defined(CONFIG_ETRAX_DEBUG_PORT2) || \
-    defined(CONFIG_ETRAX_DEBUG_PORT3)
-	REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
-#endif
-
-	/* input_data is set in head.S */
-	inbuf = input_data;
-
-	setup_normal_output_buffer();
-
-	makecrc();
-
-	__asm__ volatile ("move $vr,%0" : "=rm" (revision));
-	if (revision < 32)
-	{
-		puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
-		while(1);
-	}
-
-	puts("Uncompressing Linux...\r\n");
-	gunzip();
-	puts("Done. Now booting the kernel.\r\n");
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/README linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/README
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/compressed/README	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/compressed/README	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-Creation of the self-extracting compressed kernel image (vmlinuz)
------------------------------------------------------------------
-
-This can be slightly confusing because it's a process with many steps.
-
-The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
-by that makefile into text and data binary files, vmlinux.text and
-vmlinux.data.
-
-Those files together with a ROM filesystem can be catted together and
-burned into a flash or executed directly at the DRAM origin.
-
-They can also be catted together and compressed with gzip, which is what
-happens in this makefile. Together they make up piggy.img.
-
-The decompressor is built into the file decompress.o. It is turned into
-the binary file decompress.bin, which is catted together with piggy.img
-into the file vmlinuz. It can be executed in an arbitrary place in flash.
-
-Be careful - it assumes some things about free locations in DRAM. It
-assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
-so it puts its code at 0x40700000, and initial stack at 0x40800000.
-
--Bjorn
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-#
-# arch/cris/arch-v32/boot/Makefile
-#
-
-OBJCOPYFLAGS = -O binary -R .note -R .comment
-
-subdir- := compressed rescue
-targets := Image
-
-$(obj)/Image: vmlinux FORCE
-	$(call if_changed,objcopy)
-	@echo '  Kernel: $@ is ready'
-
-$(obj)/compressed/vmlinux: $(obj)/Image FORCE
-	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
-	$(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
-
-$(obj)/zImage:  $(obj)/compressed/vmlinux
-	@cp $< $@
-	@echo '  Kernel: $@ is ready'
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/head.S linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/head.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/head.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start
- * kernel decompressor.
- *
- * In practice, this only works for NOR flash (or some convoluted RAM boot)
- * and hence is not really useful for Artpec-3, so it's Etrax FS / NOR only.
- *
- */
-
-#include <mach/startup.inc>
-
-#ifdef CONFIG_ETRAX_AXISFLASHMAP
-
-;; Code
-
-	.text
-start:
-
-	;; Start clocks for used blocks.
-	START_CLOCKS
-
-	move.d	CONFIG_ETRAX_PTABLE_SECTOR, $r10
-	jump	$r10			; Jump to decompressor
-	nop
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-#
-# Makefile for rescue (bootstrap) code
-#
-
-CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
-ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
-		-I $(srctree)/include/asm/arch
-asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
-LD = gcc-cris -mlinux -march=v32 -nostdlib
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
-LDPOSTFLAGS = -lgcc
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
-
-targets := rescue.o rescue.bin
-
-quiet_cmd_ldlibgcc = LD      $@
-cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
-
-$(obj)/rescue.o: $(OBJECTS) FORCE
-	$(call if_changed,ldlibgcc)
-
-$(obj)/rescue.bin: $(obj)/rescue.o FORCE
-	$(call if_changed,objcopy)
-	cp -p $(obj)/rescue.bin $(objtree)
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/rescue.lds linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/rescue.lds
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/boot/rescue/rescue.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/boot/rescue/rescue.lds	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*#OUTPUT_FORMAT(elf32-us-cris) */
-OUTPUT_ARCH (crisv32)
-/* Now that NAND support has been stripped, this file could be simplified,
- * but it doesn't do any harm on the other hand so why bother. */
-
-MEMORY
-	{
-	bootblk : ORIGIN = 0x38000000,
-	          LENGTH = 0x00004000
-	intmem  : ORIGIN = 0x38004000,
-		  LENGTH = 0x00005000
-	}
-
-SECTIONS
-{
-	.text :
-	{
-		_stext = . ;
-		*(.text)
-		*(.init.text)
-		*(.rodata)
-		*(.rodata.*)
-		_etext = . ;
-	} > bootblk
-	.data :
-	{
-		*(.data)
-		_edata = . ;
-	} > bootblk
-	.bss :
-	{
-		_bss = . ;
-		*(.bss)
-		_end = ALIGN( 0x10 ) ;
-	} > intmem
-
-	/* Get rid of stuff from EXPORT_SYMBOL(foo). */
-	/DISCARD/ :
-	{
-	        *(__ksymtab_strings)
-	        *(__ksymtab)
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/drivers/Kconfig linux-libre-2.6.30-gnu1/arch/cris/arch-v32/drivers/Kconfig
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/drivers/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/drivers/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -342,7 +342,7 @@ config ETRAX_SERIAL_PORT4_DMA9_IN
 	help
 	  Enables the DMA9 input channel for ser4 (ttyS4).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/drivers/mach-a3/gpio.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/drivers/mach-a3/gpio.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/drivers/mach-a3/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/drivers/mach-a3/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -681,7 +681,7 @@ static int virtual_gpio_ioctl(struct fil
 		shadow |= ~readl(dir_oe[priv->minor]) |
 			(arg & changeable_bits[priv->minor]);
 		i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
-		spin_lock_irqrestore(&gpio_lock, flags);
+		spin_unlock_irqrestore(&gpio_lock, flags);
 		break;
 	case IO_CLRBITS:
 		spin_lock_irqsave(&gpio_lock, flags);
@@ -690,7 +690,7 @@ static int virtual_gpio_ioctl(struct fil
 		shadow |= ~readl(dir_oe[priv->minor]) &
 			~(arg & changeable_bits[priv->minor]);
 		i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
-		spin_lock_irqrestore(&gpio_lock, flags);
+		spin_unlock_irqrestore(&gpio_lock, flags);
 		break;
 	case IO_HIGHALARM:
 		/* Set alarm when bits with 1 in arg go high. */
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/Kconfig linux-libre-2.6.30-gnu1/arch/cris/arch-v32/Kconfig
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ config	ETRAX_NBR_LED_GRP_ONE
 	help
 	  Select this if you want one Ethernet LED group. This LED group
 	  can be used for one or more Ethernet interfaces. However, it is
-	  recomended that each Ethernet interface use a dedicated LED group.
+	  recommended that each Ethernet interface use a dedicated LED group.
 
 config	ETRAX_NBR_LED_GRP_TWO
 	bool "Use two LED groups"
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/entry.S linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -852,6 +852,14 @@ sys_call_table:
 	.long sys_fallocate
 	.long sys_timerfd_settime       /* 325 */
 	.long sys_timerfd_gettime
+	.long sys_signalfd4
+	.long sys_eventfd2
+	.long sys_epoll_create1
+	.long sys_dup3			/* 330 */
+	.long sys_pipe2
+	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/irq.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -333,7 +333,7 @@ void set_affinity_crisv32_irq(unsigned i
 	spin_unlock_irqrestore(&irq_lock, flags);
 }
 
-static struct hw_interrupt_type crisv32_irq_type = {
+static struct irq_chip crisv32_irq_type = {
 	.typename =    "CRISv32",
 	.startup =     startup_crisv32_irq,
 	.shutdown =    shutdown_crisv32_irq,
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/Makefile linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,8 +9,6 @@ obj-y   := entry.o traps.o irq.o debugpo
 	   process.o ptrace.o setup.o signal.o traps.o time.o \
 	   cache.o cacheflush.o
 
-obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
-
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
 obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/process.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -131,7 +131,7 @@ kernel_thread(int (*fn)(void *), void *
 extern asmlinkage void ret_from_fork(void);
 
 int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
 	unsigned long unused,
 	struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/smp.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,6 @@ static int send_ipi(int vector, int wait
 static struct irqaction irq_ipi  = {
 	.handler = crisv32_ipi_interrupt,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "ipi",
 };
 
@@ -98,9 +97,9 @@ void __devinit smp_prepare_boot_cpu(void
 	SUPP_BANK_SEL(2);
 	SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
 
-	cpu_set(0, cpu_online_map);
+	set_cpu_online(0, true);
 	cpu_set(0, phys_cpu_present_map);
-	cpu_set(0, cpu_possible_map);
+	set_cpu_possible(0, true);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -232,7 +231,7 @@ void flush_tlb_common(struct mm_struct*
 	cpumask_t cpu_mask;
 
 	spin_lock_irqsave(&tlbstate_lock, flags);
-	cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask);
+	cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm));
 	cpu_clear(smp_processor_id(), cpu_mask);
 	flush_mm = mm;
 	flush_vma = vma;
@@ -252,8 +251,8 @@ void flush_tlb_mm(struct mm_struct *mm)
 	__flush_tlb_mm(mm);
 	flush_tlb_common(mm, FLUSH_ALL, 0);
 	/* No more mappings in other CPUs */
-	cpus_clear(mm->cpu_vm_mask);
-	cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+	cpumask_clear(mm_cpumask(mm));
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
 }
 
 void flush_tlb_page(struct vm_area_struct *vma,
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/time.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -267,7 +267,6 @@ timer_interrupt(int irq, void *dev_id)
 static struct irqaction irq_timer = {
 	.handler = timer_interrupt,
 	.flags = IRQF_SHARED | IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "timer"
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/mach-fs/Kconfig linux-libre-2.6.30-gnu1/arch/cris/arch-v32/mach-fs/Kconfig
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/mach-fs/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/mach-fs/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -59,7 +59,7 @@ config ETRAX_SDRAM_GRP1_CONFIG
 	depends on ETRAX_ARCH_V32
 	default "0"
 	help
-	  SDRAM configuration for group 1. The defult value is 0
+	  SDRAM configuration for group 1. The default value is 0
 	  because group 1 is not used in the default configuration,
 	  described in the help for SDRAM_GRP0_CONFIG.
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/arch-v32/mm/tlb.c linux-libre-2.6.30-gnu1/arch/cris/arch-v32/mm/tlb.c
--- linux-libre-2.6.29-gnu1/arch/cris/arch-v32/mm/tlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/arch-v32/mm/tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -185,7 +185,7 @@ switch_mm(struct mm_struct *prev, struct
 		/* Make sure there is a MMU context. */
 		spin_lock(&mmu_context_lock);
 		get_mmu_context(next);
-		cpu_set(cpu, next->cpu_vm_mask);
+		cpumask_set_cpu(cpu, mm_cpumask(next));
 		spin_unlock(&mmu_context_lock);
 
 		/*
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/decompress_v10.lds linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/decompress_v10.lds
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/decompress_v10.lds	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/decompress_v10.lds	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/* OUTPUT_FORMAT(elf32-us-cris) */
+OUTPUT_FORMAT(elf32-cris)
+
+MEMORY 
+	{
+	dram : ORIGIN = 0x40700000,
+	       LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		*(.rodata)
+		*(.rodata.*)
+		_etext = . ;
+	} > dram
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > dram
+	.bss :
+	{
+		*(.bss)
+		_end = ALIGN( 0x10 ) ;
+	} > dram
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/decompress_v32.lds linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/decompress_v32.lds
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/decompress_v32.lds	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/decompress_v32.lds	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/*#OUTPUT_FORMAT(elf32-us-cris) */
+OUTPUT_ARCH (crisv32)
+
+MEMORY
+	{
+	dram : ORIGIN = 0x40700000,
+	       LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		*(.rodata)
+		*(.rodata.*)
+		_etext = . ;
+	} > dram
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > dram
+	.bss :
+	{
+		*(.bss)
+		_end = ALIGN( 0x10 ) ;
+	} > dram
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/head_v10.S linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/head_v10.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/head_v10.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/head_v10.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+ *  arch/cris/boot/compressed/head.S
+ *
+ *  Copyright (C) 1999, 2001 Axis Communications AB
+ *
+ *  Code that sets up the DRAM registers, calls the
+ *  decompressor to unpack the piggybacked kernel, and jumps.
+ *
+ */
+
+#define ASSEMBLER_MACROS_ONLY
+#include <arch/sv_addr_ag.h>
+
+#define RAM_INIT_MAGIC 0x56902387
+#define COMMAND_LINE_MAGIC 0x87109563
+
+	;; Exported symbols
+
+	.globl	input_data
+
+
+	.text
+
+	nop
+	di
+
+;; We need to initialze DRAM registers before we start using the DRAM
+
+	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
+	beq	dram_init_finished
+	nop
+
+#include "../../arch-v10/lib/dram_init.S"
+
+dram_init_finished:
+
+	;; Initiate the PA and PB ports
+
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b   $r0, [R_PORT_PA_DATA]
+
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b   $r0, [R_PORT_PA_DIR]
+
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b   $r0, [R_PORT_PB_DATA]
+
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b   $r0, [R_PORT_PB_DIR]
+
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM in an eLinux
+	;; product and put the sp at the top for now.
+
+	move.d	0x40800000, $sp
+
+	;; Figure out where the compressed piggyback image is
+	;; in the flash (since we wont try to copy it to DRAM
+	;; before unpacking). It is at _edata, but in flash.
+	;; Use (_edata - basse) as offset to the current PC.
+
+basse:	move.d	$pc, $r5
+	and.d	0x7fffffff, $r5	; strip any non-cache bit
+	subq	2, $r5		; compensate for the move.d $pc instr
+	move.d	$r5, $r0		; save for later - flash address of 'basse'
+	add.d	_edata, $r5
+	sub.d	basse, $r5	; $r5 = flash address of '_edata'
+
+	;; Copy text+data to DRAM
+
+	move.d	basse, $r1	; destination
+	move.d	_edata, $r2	; end destination
+1:	move.w	[$r0+], $r3
+	move.w	$r3, [$r1+]
+	cmp.d	$r2, $r1
+	bcs	1b
+	nop
+
+	move.d	$r5, [input_data] ; for the decompressor
+
+
+	;; Clear the decompressors BSS (between _edata and _end)
+
+	moveq	0, $r0
+	move.d	_edata, $r1
+	move.d	_end, $r2
+1:	move.w	$r0, [$r1+]
+	cmp.d	$r2, $r1
+	bcs	1b
+	nop
+
+	;;  Save command line magic and address.
+	move.d	_cmd_line_magic, $r12
+	move.d  $r10, [$r12]
+	move.d	_cmd_line_addr, $r12
+	move.d  $r11, [$r12]
+
+	;; Do the decompression and save compressed size in inptr
+
+	jsr	decompress_kernel
+
+	;; Put start address of root partition in $r9 so the kernel can use it
+	;; when mounting from flash
+
+	move.d	[input_data], $r9	; flash address of compressed kernel
+	add.d	[inptr], $r9		; size of compressed kernel
+
+	;; Restore command line magic and address.
+	move.d  _cmd_line_magic, $r10
+	move.d  [$r10], $r10
+	move.d  _cmd_line_addr, $r11
+	move.d  [$r11], $r11
+
+	;; Enter the decompressed kernel
+	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
+	jump	0x40004000	; kernel is linked to this address
+
+	.data
+
+input_data:
+	.dword	0		; used by the decompressor
+_cmd_line_magic:
+	.dword 0
+_cmd_line_addr:
+	.dword 0
+#include "../../arch-v10/lib/hw_settings.S"
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/head_v32.S linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/head_v32.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/head_v32.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/head_v32.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ *  Code that sets up the DRAM registers, calls the
+ *  decompressor to unpack the piggybacked kernel, and jumps.
+ *
+ *  Copyright (C) 1999 - 2006, Axis Communications AB
+ */
+
+#define ASSEMBLER_MACROS_ONLY
+#include <hwregs/asm/reg_map_asm.h>
+#include <mach/startup.inc>
+
+#define RAM_INIT_MAGIC 0x56902387
+#define COMMAND_LINE_MAGIC 0x87109563
+
+	;; Exported symbols
+
+	.globl	input_data
+
+	.text
+start:
+	di
+
+	;; Start clocks for used blocks.
+	START_CLOCKS
+
+	;; Initialize the DRAM registers.
+	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
+	beq	dram_init_finished
+	nop
+
+#if defined CONFIG_ETRAXFS
+#include "../../arch-v32/mach-fs/dram_init.S"
+#elif defined CONFIG_CRIS_MACH_ARTPEC3
+#include "../../arch-v32/mach-a3/dram_init.S"
+#else
+#error Only ETRAXFS and ARTPEC-3 supported!
+#endif
+
+dram_init_finished:
+
+	GIO_INIT
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM and put
+	;; the SP at the top for now.
+
+	move.d	0x40800000, $sp
+
+	;; Figure out where the compressed piggyback image is.
+	;; It is either in [NOR] flash (we don't want to copy it
+	;; to DRAM before unpacking), or copied to DRAM
+	;; by the [NAND] flash boot loader.
+	;; The piggyback image is at _edata, but relative to where the
+	;; image is actually located in memory, not where it is linked
+	;; (the decompressor is linked at 0x40700000+ and runs there).
+	;; Use (_edata - herami) as offset to the current PC.
+
+hereami:
+	lapcq	., $r5		; get PC
+	and.d	0x7fffffff, $r5	; strip any non-cache bit
+	move.d	$r5, $r0	; source address of 'herami'
+	add.d	_edata, $r5
+	sub.d	hereami, $r5	; r5 = flash address of '_edata'
+	move.d	hereami, $r1	; destination
+
+	;; Copy text+data to DRAM
+
+	move.d	_edata, $r2	; end destination
+1:	move.w	[$r0+], $r3	; from herami+ source
+	move.w	$r3, [$r1+]	; to hereami+ destination (linked address)
+	cmp.d	$r2, $r1	; finish when destination == _edata
+	bcs	1b
+	nop
+	move.d	input_data, $r0 ; for the decompressor
+	move.d	$r5, [$r0]	; for the decompressor
+
+	;; Clear the decompressors BSS (between _edata and _end)
+
+	moveq	0, $r0
+	move.d	_edata, $r1
+	move.d	_end, $r2
+1:	move.w	$r0, [$r1+]
+	cmp.d	$r2, $r1
+	bcs	1b
+	nop
+
+	;;  Save command line magic and address.
+	move.d	_cmd_line_magic, $r0
+	move.d  $r10, [$r0]
+	move.d	_cmd_line_addr, $r0
+	move.d  $r11, [$r0]
+
+	;;  Save boot source indicator
+	move.d	_boot_source, $r0
+	move.d	$r12, [$r0]
+
+	;; Do the decompression and save compressed size in _inptr
+
+	jsr	decompress_kernel
+	nop
+
+	;; Restore boot source indicator
+	move.d	_boot_source, $r12
+	move.d	[$r12], $r12
+
+	;; Restore command line magic and address.
+	move.d  _cmd_line_magic, $r10
+	move.d  [$r10], $r10
+	move.d  _cmd_line_addr, $r11
+	move.d  [$r11], $r11
+
+	;; Put start address of root partition in r9 so the kernel can use it
+	;; when mounting from flash
+	move.d  input_data, $r0
+	move.d	[$r0], $r9		; flash address of compressed kernel
+	move.d  inptr, $r0
+	add.d	[$r0], $r9		; size of compressed kernel
+	cmp.d   0x40000000, $r9		; image in DRAM ?
+	blo	enter_kernel		; no, must be [NOR] flash, jump
+	nop				; delay slot
+	and.d   0x001fffff, $r9		; assume compressed kernel was < 2M
+
+enter_kernel:
+	;; Enter the decompressed kernel
+	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
+	jump	0x40004000	; kernel is linked to this address
+	nop
+
+	.data
+
+input_data:
+	.dword	0		; used by the decompressor
+_cmd_line_magic:
+	.dword 0
+_cmd_line_addr:
+	.dword 0
+_boot_source:
+	.dword 0
+
+#if defined CONFIG_ETRAXFS
+#include "../../arch-v32/mach-fs/hw_settings.S"
+#elif defined CONFIG_CRIS_MACH_ARTPEC3
+#include "../../arch-v32/mach-a3/hw_settings.S"
+#else
+#error Only ETRAXFS and ARTPEC-3 supported!
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/Makefile linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+#
+# arch/cris/boot/compressed/Makefile
+#
+
+asflags-y += $(LINUXINCLUDE)
+ccflags-y += -O2 $(LINUXINCLUDE)
+
+# asflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/mach \
+# 				    -I$(srctree)/include/asm/arch
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -O2 -I$(srctree)/include/asm/mach
+# 					-I$(srctree)/include/asm/arch
+
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
+
+OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS= $(OBJECTS-y) $(obj)/misc.o
+OBJCOPYFLAGS = -O binary --remove-section=.bss
+
+quiet_cmd_image = BUILD   $@
+cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
+
+targets := vmlinux piggy.gz decompress.o decompress.bin
+
+$(obj)/decompress.o: $(OBJECTS) FORCE
+	$(call if_changed,ld)
+
+$(obj)/decompress.bin: $(obj)/decompress.o FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
+	$(call if_changed,image)
+
+$(obj)/piggy.gz: $(obj)/../Image FORCE
+	$(call if_changed,gzip)
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/misc.c linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/misc.c
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/misc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/misc.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,391 @@
+/*
+ * misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
+ *
+ */
+
+/* where the piggybacked kernel image expects itself to live.
+ * it is the same address we use when we network load an uncompressed
+ * image into DRAM, and it is the address the kernel is linked to live
+ * at by vmlinux.lds.S
+ */
+
+#define KERNEL_LOAD_ADR 0x40004000
+
+#include <linux/types.h>
+
+#ifdef CONFIG_ETRAX_ARCH_V32
+#include <hwregs/reg_rdwr.h>
+#include <hwregs/reg_map.h>
+#include <hwregs/ser_defs.h>
+#include <hwregs/pinmux_defs.h>
+#ifdef CONFIG_CRIS_MACH_ARTPEC3
+#include <hwregs/clkgen_defs.h>
+#endif
+#else
+#include <arch/svinto.h>
+#endif
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+void *memset(void *s, int c, size_t n);
+void *memcpy(void *__dest, __const void *__src, size_t __n);
+
+#define memzero(s, n)     memset((s), 0, (n))
+
+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 */
+
+unsigned inptr = 0;	/* index of next byte to be processed in inbuf
+			 * After decompression it will contain the
+			 * compressed size, and head.S will read it.
+			 */
+
+static unsigned outcnt = 0;  /* 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() (inbuf[inptr++])
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond, msg) do { \
+		if (!(cond)) \
+			error(msg); \
+	} while (0)
+#  define Trace(x) fprintf x
+#  define Tracev(x) do { \
+		if (verbose) \
+			fprintf x; \
+	} while (0)
+#  define Tracevv(x) do { \
+		if (verbose > 1) \
+			fprintf x; \
+	} while (0)
+#  define Tracec(c, x) do { \
+		if (verbose && (c)) \
+			fprintf x; \
+	} while (0)
+#  define Tracecv(c, x) do { \
+		if (verbose > 1 && (c)) \
+			fprintf x; \
+	} while (0)
+#else
+#  define Assert(cond, msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c, x)
+#  define Tracecv(c, x)
+#endif
+
+static void flush_window(void);
+static void error(char *m);
+static void puts(const char *);
+
+extern char *input_data;  /* lives in head.S */
+
+static long bytes_out;
+static uch *output_data;
+static unsigned long output_ptr;
+
+/* the "heap" is put directly after the BSS ends, at end */
+
+extern int _end;
+static long free_mem_ptr = (long)&_end;
+static long free_mem_end_ptr;
+
+#include "../../../../../lib/inflate.c"
+
+/* decompressor info and error messages to serial console */
+
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serout(const char *s, reg_scope_instances regi_ser)
+{
+	reg_ser_rs_stat_din rs;
+	reg_ser_rw_dout dout = {.data = *s};
+
+	do {
+		rs = REG_RD(ser, regi_ser, rs_stat_din);
+	}
+	while (!rs.tr_rdy);/* Wait for transceiver. */
+
+	REG_WR(ser, regi_ser, rw_dout, dout);
+}
+#endif
+
+static void puts(const char *s)
+{
+#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
+	while (*s) {
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+#ifdef CONFIG_ETRAX_ARCH_V32
+		serout(s, regi_ser0);
+#else
+		while (!(*R_SERIAL0_STATUS & (1 << 5)))
+			;
+		*R_SERIAL0_TR_DATA = *s++;
+#endif
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_ARCH_V32
+		serout(s, regi_ser1);
+#else
+		while (!(*R_SERIAL1_STATUS & (1 << 5)))
+			;
+		*R_SERIAL1_TR_DATA = *s++;
+#endif
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_ARCH_V32
+		serout(s, regi_ser2);
+#else
+		while (!(*R_SERIAL2_STATUS & (1 << 5)))
+			;
+		*R_SERIAL2_TR_DATA = *s++;
+#endif
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_ARCH_V32
+		serout(s, regi_ser3);
+#else
+		while (!(*R_SERIAL3_STATUS & (1 << 5)))
+			;
+		*R_SERIAL3_TR_DATA = *s++;
+#endif
+#endif
+		*s++;
+	}
+/* CONFIG_ETRAX_DEBUG_PORT_NULL */
+#endif
+}
+
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+
+	return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i = 0; i < __n; i++)
+		d[i] = s[i];
+
+	return __dest;
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+
+static void flush_window(void)
+{
+	ulg c = crc;         /* temporary variable */
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out = *in;
+		out++;
+		in++;
+		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg)outcnt;
+	output_ptr += (ulg)outcnt;
+	outcnt = 0;
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted\n");
+
+	while(1);	/* Halt */
+}
+
+void setup_normal_output_buffer(void)
+{
+	output_data = (char *)KERNEL_LOAD_ADR;
+}
+
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serial_setup(reg_scope_instances regi_ser)
+{
+	reg_ser_rw_xoff xoff;
+	reg_ser_rw_tr_ctrl tr_ctrl;
+	reg_ser_rw_rec_ctrl rec_ctrl;
+	reg_ser_rw_tr_baud_div tr_baud;
+	reg_ser_rw_rec_baud_div rec_baud;
+
+	/* Turn off XOFF. */
+	xoff = REG_RD(ser, regi_ser, rw_xoff);
+
+	xoff.chr = 0;
+	xoff.automatic = regk_ser_no;
+
+	REG_WR(ser, regi_ser, rw_xoff, xoff);
+
+	/* Set baudrate and stopbits. */
+	tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
+	rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
+	tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
+	rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
+
+	tr_ctrl.stop_bits = 1;	/* 2 stop bits. */
+	tr_ctrl.en = 1; /* enable transmitter */
+	rec_ctrl.en = 1; /* enabler receiver */
+
+	/*
+	 * The baudrate setup used to be a bit fishy, but now transmitter and
+	 * receiver are both set to the intended baud rate, 115200.
+	 * The magic value is 29.493 MHz.
+	 */
+	tr_ctrl.base_freq = regk_ser_f29_493;
+	rec_ctrl.base_freq = regk_ser_f29_493;
+	tr_baud.div = (29493000 / 8) / 115200;
+	rec_baud.div = (29493000 / 8) / 115200;
+
+	REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
+	REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
+	REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
+	REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
+}
+#endif
+
+void decompress_kernel(void)
+{
+	char revision;
+	char compile_rev;
+
+#ifdef CONFIG_ETRAX_ARCH_V32
+	/* Need at least a CRISv32 to run. */
+	compile_rev = 32;
+#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
+    defined(CONFIG_ETRAX_DEBUG_PORT2) || \
+    defined(CONFIG_ETRAX_DEBUG_PORT3)
+	reg_pinmux_rw_hwprot hwprot;
+
+#ifdef CONFIG_CRIS_MACH_ARTPEC3
+	reg_clkgen_rw_clk_ctrl clk_ctrl;
+
+	/* Enable corresponding clock region when serial 1..3 selected */
+
+	clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
+	clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
+	REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
+#endif
+
+	/* pinmux setup for ports 1..3 */
+	hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
+#endif
+
+
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+	serial_setup(regi_ser0);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+	hwprot.ser1 = regk_pinmux_yes;
+	serial_setup(regi_ser1);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+	hwprot.ser2 = regk_pinmux_yes;
+	serial_setup(regi_ser2);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+	hwprot.ser3 = regk_pinmux_yes;
+	serial_setup(regi_ser3);
+#endif
+#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
+    defined(CONFIG_ETRAX_DEBUG_PORT2) || \
+    defined(CONFIG_ETRAX_DEBUG_PORT3)
+	REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
+#endif
+
+	/* input_data is set in head.S */
+	inbuf = input_data;
+#else /* CRISv10 */
+	/* Need at least a crisv10 to run. */
+	compile_rev = 10;
+
+	/* input_data is set in head.S */
+	inbuf = input_data;
+
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+	*R_SERIAL0_XOFF = 0;
+	*R_SERIAL0_BAUD = 0x99;
+	*R_SERIAL0_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+	*R_SERIAL1_XOFF = 0;
+	*R_SERIAL1_BAUD = 0x99;
+	*R_SERIAL1_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+	*R_GEN_CONFIG = 0x08;
+	*R_SERIAL2_XOFF = 0;
+	*R_SERIAL2_BAUD = 0x99;
+	*R_SERIAL2_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+	*R_GEN_CONFIG = 0x100;
+	*R_SERIAL3_XOFF = 0;
+	*R_SERIAL3_BAUD = 0x99;
+	*R_SERIAL3_TR_CTRL = 0x40;
+#endif
+#endif
+
+	setup_normal_output_buffer();
+
+	makecrc();
+
+	__asm__ volatile ("move $vr,%0" : "=rm" (revision));
+	if (revision < compile_rev) {
+#ifdef CONFIG_ETRAX_ARCH_V32
+		puts("You need an ETRAX FS to run Linux 2.6/crisv32\n");
+#else
+		puts("You need an ETRAX 100LX to run linux 2.6\n");
+#endif
+		while(1);
+	}
+
+	puts("Uncompressing Linux...\n");
+	gunzip();
+	puts("Done. Now booting the kernel\n");
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/README linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/README
--- linux-libre-2.6.29-gnu1/arch/cris/boot/compressed/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/compressed/README	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+Creation of the self-extracting compressed kernel image (vmlinuz)
+-----------------------------------------------------------------
+
+This can be slightly confusing because it's a process with many steps.
+
+The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
+by that makefile into text and data binary files, vmlinux.text and
+vmlinux.data.
+
+Those files together with a ROM filesystem can be catted together and
+burned into a flash or executed directly at the DRAM origin.
+
+They can also be catted together and compressed with gzip, which is what
+happens in this makefile. Together they make up piggy.img.
+
+The decompressor is built into the file decompress.o. It is turned into
+the binary file decompress.bin, which is catted together with piggy.img
+into the file vmlinuz. It can be executed in an arbitrary place in flash.
+
+Be careful - it assumes some things about free locations in DRAM. It
+assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
+so it puts its code at 0x40700000, and initial stack at 0x40800000.
+
+-Bjorn
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/.gitignore linux-libre-2.6.30-gnu1/arch/cris/boot/.gitignore
--- linux-libre-2.6.29-gnu1/arch/cris/boot/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/.gitignore	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2 @@
+Image
+zImage
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/Makefile linux-libre-2.6.30-gnu1/arch/cris/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/boot/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+#
+# arch/cris/boot/Makefile
+#
+
+objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
+objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss
+
+OBJCOPYFLAGS = -O binary $(objcopyflags-y)
+
+
+subdir- := compressed rescue
+targets := Image
+
+$(obj)/Image: vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/Image FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+	$(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
+
+$(obj)/zImage:  $(obj)/compressed/vmlinux
+	@cp $< $@
+	@echo '  Kernel: $@ is ready'
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/head_v10.S linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/head_v10.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/head_v10.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/head_v10.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,360 @@
+/*
+ * Rescue code, made to reside at the beginning of the
+ * flash-memory. when it starts, it checks a partition
+ * table at the first sector after the rescue sector.
+ * the partition table was generated by the product builder
+ * script and contains offsets, lengths, types and checksums
+ * for each partition that this code should check.
+ *
+ * If any of the checksums fail, we assume the flash is so
+ * corrupt that we cant use it to boot into the ftp flash
+ * loader, and instead we initialize the serial port to
+ * receive a flash-loader and new flash image. we dont include
+ * any flash code here, but just accept a certain amount of
+ * bytes from the serial port and jump into it. the downloaded
+ * code is put in the cache.
+ *
+ * The partitiontable is designed so that it is transparent to
+ * code execution - it has a relative branch opcode in the
+ * beginning that jumps over it. each entry contains extra
+ * data so we can add stuff later.
+ *
+ * Partition table format:
+ *
+ *     Code transparency:
+ *
+ *     2 bytes    [opcode 'nop']
+ *     2 bytes    [opcode 'di']
+ *     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
+ *     2 bytes    [opcode 'nop', delay slot]
+ *
+ *     Table validation (at +10):
+ *
+ *     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
+ *     2 bytes    [length of all entries plus the end marker]
+ *     4 bytes    [checksum for the partitiontable itself]
+ *
+ *     Entries, each with the following format, last has offset -1:
+ *
+ *        4 bytes    [offset in bytes, from start of flash]
+ *        4 bytes    [length in bytes of partition]
+ *        4 bytes    [checksum, simple longword sum]
+ *        2 bytes    [partition type]
+ *        2 bytes    [flags, only bit 0 used, ro/rw = 1/0]
+ *        16 bytes   [reserved for future use]
+ *
+ *     End marker
+ *
+ *        4 bytes    [-1]
+ *
+ *	 10 bytes    [0, padding]
+ *
+ * Bit 0 in flags signifies RW or RO. The rescue code only bothers
+ * to check the checksum for RO partitions, since the others will
+ * change their data without updating the checksums. A 1 in bit 0
+ * means RO, 0 means RW. That way, it is possible to set a partition
+ * in RO mode initially, and later mark it as RW, since you can always
+ * write 0's to the flash.
+ *
+ * During the wait for serial input, the status LED will flash so the
+ * user knows something went wrong.
+ *
+ * Copyright (C) 1999-2007 Axis Communications AB
+ */
+
+#ifdef CONFIG_ETRAX_AXISFLASHMAP
+
+#define ASSEMBLER_MACROS_ONLY
+#include <arch/sv_addr_ag.h>
+
+	;; The partitiontable is looked for at the first sector after the boot
+	;; sector. Sector size is 65536 bytes in all flashes we use.
+
+#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
+#define PTABLE_MAGIC 0xbeef
+
+	;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
+	;; That is not where we put our downloaded serial boot-code.
+	;; The length is enough for downloading code that loads the rest
+	;; of itself (after having setup the DRAM etc).
+	;; It is the same length as the on-chip ROM loads, so the same
+	;; host loader can be used to load a rescued product as well as
+	;; one booted through the Etrax serial boot code.
+
+#define CODE_START 0x40000000
+#define CODE_LENGTH 784
+
+#ifdef CONFIG_ETRAX_RESCUE_SER0
+#define SERXOFF R_SERIAL0_XOFF
+#define SERBAUD R_SERIAL0_BAUD
+#define SERRECC R_SERIAL0_REC_CTRL
+#define SERRDAT R_SERIAL0_REC_DATA
+#define SERSTAT R_SERIAL0_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER1
+#define SERXOFF R_SERIAL1_XOFF
+#define SERBAUD R_SERIAL1_BAUD
+#define SERRECC R_SERIAL1_REC_CTRL
+#define SERRDAT R_SERIAL1_REC_DATA
+#define SERSTAT R_SERIAL1_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER2
+#define SERXOFF R_SERIAL2_XOFF
+#define SERBAUD R_SERIAL2_BAUD
+#define SERRECC R_SERIAL2_REC_CTRL
+#define SERRDAT R_SERIAL2_REC_DATA
+#define SERSTAT R_SERIAL2_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER3
+#define SERXOFF R_SERIAL3_XOFF
+#define SERBAUD R_SERIAL3_BAUD
+#define SERRECC R_SERIAL3_REC_CTRL
+#define SERRDAT R_SERIAL3_REC_DATA
+#define SERSTAT R_SERIAL3_STATUS
+#endif
+
+#define NOP_DI 0xf025050f
+#define RAM_INIT_MAGIC 0x56902387
+
+	.text
+
+	;; This is the entry point of the rescue code
+	;; 0x80000000 if loaded in flash (as it should be)
+	;; Since etrax actually starts at address 2 when booting from flash, we
+	;; put a nop (2 bytes) here first so we dont accidentally skip the di
+
+	nop
+	di
+
+	jump	in_cache	; enter cached area instead
+in_cache:
+
+
+	;; First put a jump test to give a possibility of upgrading the
+	;; rescue code without erasing/reflashing the sector.
+	;; We put a longword of -1 here and if it is not -1, we jump using
+	;; the value as jump target. Since we can always change 1's to 0's
+	;; without erasing the sector, it is possible to add new
+	;; code after this and altering the jumptarget in an upgrade.
+
+jtcd:	move.d	[jumptarget], $r0
+	cmp.d	0xffffffff, $r0
+	beq	no_newjump
+	nop
+
+	jump	[$r0]
+
+jumptarget:
+	.dword	0xffffffff	; can be overwritten later to insert new code
+
+no_newjump:
+#ifdef CONFIG_ETRAX_ETHERNET
+	;; Start MII clock to make sure it is running when tranceiver is reset
+	move.d 0x3, $r0    ; enable = on, phy = mii_clk
+	move.d $r0, [R_NETWORK_GEN_CONFIG]
+#endif
+
+	;; We need to setup the bus registers before we start using the DRAM
+#include "../../../arch-v10/lib/dram_init.S"
+
+	;; we now should go through the checksum-table and check the listed
+	;; partitions for errors.
+
+	move.d	PTABLE_START, $r3
+	move.d	[$r3], $r0
+	cmp.d	NOP_DI, $r0	; make sure the nop/di is there...
+	bne	do_rescue
+	nop
+
+	;; skip the code transparency block (10 bytes).
+
+	addq	10, $r3
+
+	;; check for correct magic
+
+	move.w	[$r3+], $r0
+	cmp.w	PTABLE_MAGIC, $r0
+	bne	do_rescue	; didn't recognize - trig rescue
+	nop
+
+	;; check for correct ptable checksum
+
+	movu.w	[$r3+], $r2	; ptable length
+	move.d	$r2, $r8	; save for later, length of total ptable
+	addq	28, $r8		; account for the rest
+	move.d	[$r3+], $r4	; ptable checksum
+	move.d	$r3, $r1
+	jsr	checksum	; r1 source, r2 length, returns in r0
+
+	cmp.d	$r0, $r4
+	bne	do_rescue	; didn't match - trig rescue
+	nop
+
+	;; ptable is ok. validate each entry.
+
+	moveq	-1, $r7
+
+ploop:	move.d	[$r3+], $r1	; partition offset (from ptable start)
+	bne	notfirst	; check if it is the partition containing ptable
+	nop			; yes..
+	move.d	$r8, $r1	; for its checksum check, skip the ptable
+	move.d	[$r3+], $r2	; partition length
+	sub.d	$r8, $r2	; minus the ptable length
+	ba	bosse
+	nop
+notfirst:
+	cmp.d	-1, $r1		; the end of the ptable ?
+	beq	flash_ok	;   if so, the flash is validated
+	move.d	[$r3+], $r2	; partition length
+bosse:	move.d	[$r3+], $r5	; checksum
+	move.d	[$r3+], $r4	; type and flags
+	addq	16, $r3		; skip the reserved bytes
+	btstq	16, $r4		; check ro flag
+	bpl	ploop		;   rw partition, skip validation
+	nop
+	btstq	17, $r4		; check bootable flag
+	bpl	1f
+	nop
+	move.d	$r1, $r7	; remember boot partition offset
+1:
+	add.d	PTABLE_START, $r1
+
+	jsr	checksum	; checksum the partition
+
+	cmp.d	$r0, $r5
+	beq	ploop		; checksums matched, go to next entry
+	nop
+
+	;; otherwise fall through to the rescue code.
+
+do_rescue:
+	;; setup port PA and PB default initial directions and data
+	;; (so we can flash LEDs, and so that DTR and others are set)
+
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b	$r0, [R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b	$r0, [R_PORT_PA_DATA]
+
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b	$r0, [R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b	$r0, [R_PORT_PB_DATA]
+
+	;; setup the serial port at 115200 baud
+
+	moveq	0, $r0
+	move.d	$r0, [SERXOFF]
+
+	move.b	0x99, $r0
+	move.b	$r0, [SERBAUD]	; 115.2kbaud for both transmit and receive
+
+	move.b	0x40, $r0	; rec enable
+	move.b	$r0, [SERRECC]
+
+	moveq	0, $r1		; "timer" to clock out a LED red flash
+	move.d	CODE_START, $r3	; destination counter
+	movu.w	CODE_LENGTH, $r4; length
+
+wait_ser:
+	addq	1, $r1
+#ifndef CONFIG_ETRAX_NO_LEDS
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
+#endif
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
+	btstq	16, $r1
+	bpl	1f
+	nop
+	or.d	$r0, $r2	; set bit
+	ba	2f
+	nop
+1:	not	$r0		; clear bit
+	and.d	$r0, $r2
+2:
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	$r2, [R_PORT_PA_DATA]
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	$r2, [R_PORT_PB_DATA]
+#endif
+#ifdef CONFIG_ETRAX_90000000_LEDS
+	move.b	$r2, [0x90000000]
+#endif
+#endif
+
+	;; check if we got something on the serial port
+
+	move.b	[SERSTAT], $r0
+	btstq	0, $r0		; data_avail
+	bpl	wait_ser
+	nop
+
+	;; got something - copy the byte and loop
+
+	move.b	[SERRDAT], $r0
+	move.b	$r0, [$r3+]
+
+	subq	1, $r4		; decrease length
+	bne	wait_ser
+	nop
+
+	;; jump into downloaded code
+
+	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is
+					; initialized
+	jump	CODE_START
+
+flash_ok:
+	;; check r7, which contains either -1 or the partition to boot from
+
+	cmp.d	-1, $r7
+	bne	1f
+	nop
+	move.d	PTABLE_START, $r7; otherwise use the ptable start
+1:
+	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is
+					; initialized
+	jump	$r7		; boot!
+
+
+	;; Helper subroutines
+
+	;; Will checksum by simple addition
+	;; r1 - source
+	;; r2 - length in bytes
+	;; result will be in r0
+checksum:
+	moveq	0, $r0
+	moveq   CONFIG_ETRAX_FLASH1_SIZE, $r6
+
+	;; If the first physical flash memory is exceeded wrap to the
+	;; second one
+	btstq	26, $r1		; Are we addressing first flash?
+	bpl	1f
+	nop
+	clear.d	$r6
+
+1:	test.d  $r6		; 0 = no wrapping
+	beq	2f
+	nop
+	lslq	20, $r6		; Convert MB to bytes
+	sub.d	$r1, $r6
+
+2:	addu.b	[$r1+], $r0
+	subq	1, $r6		; Flash memory left
+	beq	3f
+	subq	1, $r2		; Length left
+	bne	2b
+	nop
+	ret
+	nop
+
+3:	move.d	MEM_CSE1_START, $r1 ; wrap to second flash
+	ba	2b
+	nop
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/head_v32.S linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/head_v32.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/head_v32.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/head_v32.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start
+ * kernel decompressor.
+ *
+ * In practice, this only works for NOR flash (or some convoluted RAM boot)
+ * and hence is not really useful for Artpec-3, so it's Etrax FS / NOR only.
+ *
+ */
+
+#include <mach/startup.inc>
+
+#ifdef CONFIG_ETRAX_AXISFLASHMAP
+
+;; Code
+
+	.text
+start:
+
+	;; Start clocks for used blocks.
+	START_CLOCKS
+
+	move.d	CONFIG_ETRAX_PTABLE_SECTOR, $r10
+	jump	$r10			; Jump to decompressor
+	nop
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/kimagerescue.S linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/kimagerescue.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/kimagerescue.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/kimagerescue.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,143 @@
+/*
+ * Rescue code to be prepended on a kimage and copied to the
+ * rescue serial port.
+ * This is called from the rescue code, it will copy received data to
+ * 4004000 and after a timeout jump to it.
+ */
+
+#define ASSEMBLER_MACROS_ONLY
+#include <arch/sv_addr_ag.h>
+
+#define CODE_START 0x40004000
+#define CODE_LENGTH 784
+#define TIMEOUT_VALUE 1000
+
+
+#ifdef CONFIG_ETRAX_RESCUE_SER0
+#define SERXOFF R_SERIAL0_XOFF
+#define SERBAUD R_SERIAL0_BAUD
+#define SERRECC R_SERIAL0_REC_CTRL
+#define SERRDAT R_SERIAL0_REC_DATA
+#define SERSTAT R_SERIAL0_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER1
+#define SERXOFF R_SERIAL1_XOFF
+#define SERBAUD R_SERIAL1_BAUD
+#define SERRECC R_SERIAL1_REC_CTRL
+#define SERRDAT R_SERIAL1_REC_DATA
+#define SERSTAT R_SERIAL1_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER2
+#define SERXOFF R_SERIAL2_XOFF
+#define SERBAUD R_SERIAL2_BAUD
+#define SERRECC R_SERIAL2_REC_CTRL
+#define SERRDAT R_SERIAL2_REC_DATA
+#define SERSTAT R_SERIAL2_STATUS
+#endif
+#ifdef CONFIG_ETRAX_RESCUE_SER3
+#define SERXOFF R_SERIAL3_XOFF
+#define SERBAUD R_SERIAL3_BAUD
+#define SERRECC R_SERIAL3_REC_CTRL
+#define SERRDAT R_SERIAL3_REC_DATA
+#define SERSTAT R_SERIAL3_STATUS
+#endif
+
+	.text
+	;; This is the entry point of the rescue code
+	;; 0x80000000 if loaded in flash (as it should be)
+	;; since etrax actually starts at address 2 when booting from flash, we
+	;; put a nop (2 bytes) here first so we dont accidentally skip the di
+
+	nop
+	di
+#ifndef CONFIG_SVINTO_SIM
+	;; setup port PA and PB default initial directions and data
+	;; (so we can flash LEDs, and so that DTR and others are set)
+
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b	$r0, [R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b	$r0, [R_PORT_PA_DATA]
+
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b	$r0, [R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b	$r0, [R_PORT_PB_DATA]
+
+	;; We need to setup the bus registers before we start using the DRAM
+#include "../../lib/dram_init.S"
+
+#endif
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM in an eLinux
+	;; product and put the sp at the top for now.
+
+	move.d	0x40800000, $sp
+
+	;; setup the serial port at 115200 baud
+
+	moveq	0, $r0
+	move.d	$r0, [SERXOFF]
+
+	move.b	0x99, $r0
+	move.b	$r0, [SERBAUD]		; 115.2kbaud for both transmit
+					; and receive
+
+	move.b	0x40, $r0		; rec enable
+	move.b	$r0, [SERRECC]
+
+
+	moveq	0, $r1			; "timer" to clock out a LED red flash
+	move.d	CODE_START, $r3		; destination counter
+	move.d	CODE_LENGTH, $r4	; length
+	move.d	TIMEOUT_VALUE, $r5	; "timeout" until jump
+
+wait_ser:
+	addq	1, $r1
+	subq	1, $r5			; decrease timeout
+	beq	jump_start		; timed out
+	nop
+#ifndef CONFIG_ETRAX_NO_LEDS
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
+#endif
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
+	btstq	16, $r1
+	bpl	1f
+	nop
+	or.d	$r0, $r2		; set bit
+	ba	2f
+	nop
+1:	not	$r0			; clear bit
+	and.d	$r0, $r2
+2:
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	$r2, [R_PORT_PA_DATA]
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	$r2, [R_PORT_PB_DATA]
+#endif
+#endif
+
+	;; check if we got something on the serial port
+
+	move.b	[SERSTAT], $r0
+	btstq	0, $r0			; data_avail
+	bpl	wait_ser
+	nop
+
+	;; got something - copy the byte and loop
+
+	move.b	[SERRDAT], $r0
+	move.b	$r0, [$r3+]
+	move.d	TIMEOUT_VALUE, $r5	; reset "timeout"
+	subq	1, $r4			; decrease length
+	bne	wait_ser
+	nop
+jump_start:
+	;; jump into downloaded code
+
+	jump	CODE_START
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/Makefile linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+#
+# Makefile for rescue (bootstrap) code
+#
+
+# CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/arch/mach/ \
+# 				    -I$(srctree)/include/asm/arch
+# asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
+# LD = gcc-cris -mlinux -march=v32 -nostdlib
+
+asflags-y += $(LINUXINCLUDE)
+ccflags-y += -O2 $(LINUXINCLUDE)
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/rescue_$(arch-y).lds
+OBJCOPYFLAGS = -O binary --remove-section=.bss
+obj-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+obj-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS := $(obj-y)
+
+targets := rescue.o rescue.bin
+
+$(obj)/rescue.o: $(OBJECTS) FORCE
+	$(call if_changed,ld)
+
+$(obj)/rescue.bin: $(obj)/rescue.o FORCE
+	$(call if_changed,objcopy)
+	cp -p $(obj)/rescue.bin $(objtree)
+
+$(obj)/testrescue.bin: $(obj)/testrescue.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
+# Pad it to 784 bytes
+	dd if=/dev/zero of=tmp2423 bs=1 count=784
+	cat tr.bin tmp2423 >testrescue_tmp.bin
+	dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
+	rm tr.bin tmp2423 testrescue_tmp.bin
+
+
+$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
+# Pad it to 784 bytes, that's what the rescue loader expects
+	dd if=/dev/zero of=tmp2423 bs=1 count=784
+	cat ktr.bin tmp2423 >kimagerescue_tmp.bin
+	dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
+	rm ktr.bin tmp2423 kimagerescue_tmp.bin
+
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/rescue_v10.lds linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/rescue_v10.lds
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/rescue_v10.lds	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/rescue_v10.lds	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+MEMORY 
+	{
+	flash : ORIGIN = 0x00000000,
+	        LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		stext = . ;
+		*(.text)
+		etext = . ;
+	} > flash
+	.data :
+	{
+		*(.data)
+		edata = . ;
+	} > flash
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/rescue_v32.lds linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/rescue_v32.lds
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/rescue_v32.lds	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/rescue_v32.lds	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/*#OUTPUT_FORMAT(elf32-us-cris) */
+OUTPUT_ARCH (crisv32)
+/* Now that NAND support has been stripped, this file could be simplified,
+ * but it doesn't do any harm on the other hand so why bother. */
+
+MEMORY
+	{
+	bootblk : ORIGIN = 0x38000000,
+	          LENGTH = 0x00004000
+	intmem  : ORIGIN = 0x38004000,
+		  LENGTH = 0x00005000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		*(.init.text)
+		*(.rodata)
+		*(.rodata.*)
+		_etext = . ;
+	} > bootblk
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > bootblk
+	.bss :
+	{
+		_bss = . ;
+		*(.bss)
+		_end = ALIGN( 0x10 ) ;
+	} > intmem
+
+	/* Get rid of stuff from EXPORT_SYMBOL(foo). */
+	/DISCARD/ :
+	{
+	        *(__ksymtab_strings)
+	        *(__ksymtab)
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/testrescue.S linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/testrescue.S
--- linux-libre-2.6.29-gnu1/arch/cris/boot/rescue/testrescue.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/rescue/testrescue.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * Simple testcode to download by the rescue block.
+ * Just lights some LEDs to show it was downloaded correctly.
+ *
+ * Copyright (C) 1999 Axis Communications AB
+ */
+
+#define ASSEMBLER_MACROS_ONLY
+#include <arch/sv_addr_ag.h>
+
+	.text
+
+	nop
+	nop
+	moveq	-1, $r2
+	move.b	$r2, [R_PORT_PA_DIR]
+	moveq	0, $r2
+	move.b	$r2, [R_PORT_PA_DATA]
+
+endless:
+	nop
+	ba	endless
+	nop
+
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/boot/tools/build.c linux-libre-2.6.30-gnu1/arch/cris/boot/tools/build.c
--- linux-libre-2.6.29-gnu1/arch/cris/boot/tools/build.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/boot/tools/build.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,287 @@
+/*
+ *  linux/tools/build.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * This file builds a disk-image from three different files:
+ *
+ * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - setup: 8086 machine code, sets up system parm
+ * - system: 80386 code for actual system
+ *
+ * It does some checking that all files are of the correct type, and
+ * just writes the result to stdout, removing headers and padding to
+ * the right amount. It also writes some system data to stderr.
+ */
+
+/*
+ * Changes by tytso to allow root device specification
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ * Cross compiling fixes by Gertjan van Wingerde, July 1996
+ */
+
+#include <stdio.h>	/* fprintf */
+#include <string.h>
+#include <stdlib.h>	/* contains exit */
+#include <sys/types.h>	/* unistd.h needs this */
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <unistd.h>	/* contains read/write */
+#include <fcntl.h>
+#include <errno.h>
+
+#define MINIX_HEADER 32
+
+#define N_MAGIC_OFFSET 1024
+#ifndef __BFD__
+static int GCC_HEADER = sizeof(struct exec);
+#endif
+
+#ifdef __BIG_KERNEL__
+#define SYS_SIZE 0xffff
+#else
+#define SYS_SIZE DEF_SYSSIZE
+#endif
+
+#define DEFAULT_MAJOR_ROOT 0
+#define DEFAULT_MINOR_ROOT 0
+
+/* max nr of sectors of setup: don't change unless you also change
+ * bootsect etc */
+#define SETUP_SECTS 4
+
+#define STRINGIFY(x) #x
+
+typedef union {
+	int i;
+	long l;
+	short s[2];
+	char b[4];
+} conv;
+
+long intel_long(long l)
+{
+	conv t;
+
+	t.b[0] = l & 0xff; l >>= 8;
+	t.b[1] = l & 0xff; l >>= 8;
+	t.b[2] = l & 0xff; l >>= 8;
+	t.b[3] = l & 0xff; l >>= 8;
+	return t.l;
+}
+
+int intel_int(int i)
+{
+	conv t;
+
+	t.b[0] = i & 0xff; i >>= 8;
+        t.b[1] = i & 0xff; i >>= 8;
+        t.b[2] = i & 0xff; i >>= 8;
+        t.b[3] = i & 0xff; i >>= 8;
+        return t.i;
+}
+
+short intel_short(short l)
+{
+	conv t;
+
+	t.b[0] = l & 0xff; l >>= 8;
+	t.b[1] = l & 0xff; l >>= 8;
+	return t.s[0];
+}
+
+void die(const char * str)
+{
+	fprintf(stderr,"%s\n",str);
+	exit(1);
+}
+
+void usage(void)
+{
+	die("Usage: build bootsect setup system [rootdev] [> image]");
+}
+
+int main(int argc, char ** argv)
+{
+	int i,c,id,sz,tmp_int;
+	unsigned long sys_size, tmp_long;
+	char buf[1024];
+#ifndef __BFD__
+	struct exec *ex = (struct exec *)buf;
+#endif
+	char major_root, minor_root;
+	struct stat sb;
+	unsigned char setup_sectors;
+
+	if ((argc < 4) || (argc > 5))
+		usage();
+	if (argc > 4) {
+		if (!strcmp(argv[4], "CURRENT")) {
+			if (stat("/", &sb)) {
+				perror("/");
+				die("Couldn't stat /");
+			}
+			major_root = major(sb.st_dev);
+			minor_root = minor(sb.st_dev);
+		} else if (strcmp(argv[4], "FLOPPY")) {
+			if (stat(argv[4], &sb)) {
+				perror(argv[4]);
+				die("Couldn't stat root device.");
+			}
+			major_root = major(sb.st_rdev);
+			minor_root = minor(sb.st_rdev);
+		} else {
+			major_root = 0;
+			minor_root = 0;
+		}
+	} else {
+		major_root = DEFAULT_MAJOR_ROOT;
+		minor_root = DEFAULT_MINOR_ROOT;
+	}
+	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
+	for (i=0;i<sizeof buf; i++) buf[i]=0;
+	if ((id=open(argv[1],O_RDONLY,0))<0)
+		die("Unable to open 'boot'");
+	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
+		die("Unable to read header of 'boot'");
+	if (((long *) buf)[0]!=intel_long(0x04100301))
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[3] != 0)
+		die("Illegal data segment in 'boot'");
+	if (((long *) buf)[4] != 0)
+		die("Illegal bss in 'boot'");
+	if (((long *) buf)[5] != 0)
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[7] != 0)
+		die("Illegal symbol table in 'boot'");
+	i=read(id,buf,sizeof buf);
+	fprintf(stderr,"Boot sector %d bytes.\n",i);
+	if (i != 512)
+		die("Boot block must be exactly 512 bytes");
+	if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
+		die("Boot block hasn't got boot flag (0xAA55)");
+	buf[508] = (char) minor_root;
+	buf[509] = (char) major_root;	
+	i=write(1,buf,512);
+	if (i!=512)
+		die("Write call failed");
+	close (id);
+	
+	if ((id=open(argv[2],O_RDONLY,0))<0)
+		die("Unable to open 'setup'");
+	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
+		die("Unable to read header of 'setup'");
+	if (((long *) buf)[0]!=intel_long(0x04100301))
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[3] != 0)
+		die("Illegal data segment in 'setup'");
+	if (((long *) buf)[4] != 0)
+		die("Illegal bss in 'setup'");
+	if (((long *) buf)[5] != 0)
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[7] != 0)
+		die("Illegal symbol table in 'setup'");
+	for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
+#ifdef __BIG_KERNEL__
+	{
+		if (!i) {
+			/* Working with memcpy because of alignment constraints
+			   on Sparc - Gertjan */
+			memcpy(&tmp_long, &buf[2], sizeof(long));
+			if (tmp_long != intel_long(0x53726448) )
+				die("Wrong magic in loader header of 'setup'");
+			memcpy(&tmp_int, &buf[6], sizeof(int));
+			if (tmp_int < intel_int(0x200))
+				die("Wrong version of loader header of 'setup'");
+			buf[0x11] = 1; /* LOADED_HIGH */
+			tmp_long = intel_long(0x100000);
+			memcpy(&buf[0x14], &tmp_long, sizeof(long));  /* code32_start */
+		}
+#endif
+		if (write(1,buf,c)!=c)
+			die("Write call failed");
+#ifdef __BIG_KERNEL__
+	}
+#endif
+	if (c != 0)
+		die("read-error on 'setup'");
+	close (id);
+	setup_sectors = (unsigned char)((i + 511) / 512);
+	/* for compatibility with LILO */
+	if (setup_sectors < SETUP_SECTS)
+		setup_sectors = SETUP_SECTS;
+	fprintf(stderr,"Setup is %d bytes.\n",i);
+	for (c=0 ; c<sizeof(buf) ; c++)
+		buf[c] = '\0';
+	while (i < setup_sectors * 512) {
+		c = setup_sectors * 512 - i;
+		if (c > sizeof(buf))
+			c = sizeof(buf);
+		if (write(1,buf,c) != c)
+			die("Write call failed");
+		i += c;
+	}
+	
+	if ((id=open(argv[3],O_RDONLY,0))<0)
+		die("Unable to open 'system'");
+#ifndef __BFD__
+	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
+		die("Unable to read header of 'system'");
+	if (N_MAGIC(*ex) == ZMAGIC) {
+		GCC_HEADER = N_MAGIC_OFFSET;
+		lseek(id, GCC_HEADER, SEEK_SET);
+	} else if (N_MAGIC(*ex) != QMAGIC)
+		die("Non-GCC header of 'system'");
+	fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
+		(ex->a_text+ex->a_data+ex->a_bss)/1024,
+		ex->a_text /1024,
+		ex->a_data /1024,
+		ex->a_bss  /1024);
+	sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
+#else
+	if (fstat (id, &sb)) {
+	  perror ("fstat");
+	  die ("Unable to stat 'system'");
+	}
+	sz = sb.st_size;
+	fprintf (stderr, "System is %d kB\n", sz/1024);
+#endif
+	sys_size = (sz + 15) / 16;
+	if (sys_size > SYS_SIZE)
+		die("System is too big");
+	while (sz > 0) {
+		int l, n;
+
+		l = sz;
+		if (l > sizeof(buf))
+			l = sizeof(buf);
+		if ((n=read(id, buf, l)) != l) {
+			if (n == -1) 
+				perror(argv[1]);
+			else
+				fprintf(stderr, "Unexpected EOF\n");
+			die("Can't read 'system'");
+		}
+		if (write(1, buf, l) != l)
+			die("Write failed");
+		sz -= l;
+	}
+	close(id);
+	if (lseek(1, 497, 0) == 497) {
+		if (write(1, &setup_sectors, 1) != 1)
+			die("Write of setup sectors failed");
+	}
+	if (lseek(1,500,0) == 500) {
+		buf[0] = (sys_size & 0xff);
+		buf[1] = ((sys_size >> 8) & 0xff);
+		if (write(1, buf, 2) != 2)
+			die("Write failed");
+	}
+	return(0);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/arch-v32/arch/spinlock.h linux-libre-2.6.30-gnu1/arch/cris/include/arch-v32/arch/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/arch-v32/arch/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/arch-v32/arch/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -121,6 +121,8 @@ static  inline int __raw_write_trylock(r
 	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()
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/ioctls.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/ioctls.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/ioctls.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/ioctls.h	2009-06-09 23:05:27.000000000 -0400
@@ -74,8 +74,9 @@
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
 #define FIOQSIZE	0x5460
 
-#define TIOCSERSETRS485 0x5461  /* enable rs-485 */
-#define TIOCSERWRRS485  0x5462  /* write rs-485 */
+#define TIOCSERSETRS485	0x5461  /* enable rs-485 (deprecated) */
+#define TIOCSERWRRS485	0x5462  /* write rs-485 */
+#define TIOCSRS485	0x5463  /* enable rs-485 */
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/rs485.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/rs485.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/rs485.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/rs485.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,15 +1,13 @@
 /* RS-485 structures */
 
-/* RS-485 support */
-/* Used with ioctl() TIOCSERSETRS485 */
+/* Used with ioctl() TIOCSERSETRS485 for backward compatibility!
+ * XXX: Do not use it for new code!
+ */
 struct rs485_control {
         unsigned short rts_on_send;
         unsigned short rts_after_sent;
         unsigned long delay_rts_before_send;
         unsigned short enabled;
-#ifdef __KERNEL__
-        int disable_serial_loopback;
-#endif
 };
 
 /* Used with ioctl() TIOCSERWRRS485 */
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,9 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_SOCKET_H */
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/termios.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/termios.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/termios.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/termios.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,7 @@
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
 #include <asm/rs485.h>
+#include <linux/serial.h>
 
 struct winsize {
 	unsigned short ws_row;
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/cris/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/cris/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -281,7 +281,7 @@
 #define __NR_mbind		274
 #define __NR_get_mempolicy	275
 #define __NR_set_mempolicy	276
-#define __NR_mq_open 		277
+#define __NR_mq_open		277
 #define __NR_mq_unlink		(__NR_mq_open+1)
 #define __NR_mq_timedsend	(__NR_mq_open+2)
 #define __NR_mq_timedreceive	(__NR_mq_open+3)
@@ -331,10 +331,18 @@
 #define __NR_fallocate		324
 #define __NR_timerfd_settime	325
 #define __NR_timerfd_gettime	326
+#define __NR_signalfd4		327
+#define __NR_eventfd2		328
+#define __NR_epoll_create1	329
+#define __NR_dup3		330
+#define __NR_pipe2		331
+#define __NR_inotify_init1	332
+#define __NR_preadv		333
+#define __NR_pwritev		334
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 327
+#define NR_syscalls 335
 
 #include <arch/unistd.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/Kconfig linux-libre-2.6.30-gnu1/arch/cris/Kconfig
--- linux-libre-2.6.29-gnu1/arch/cris/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -438,7 +438,7 @@ config ETRAX_SERIAL_PORT0_DMA1_IN
 	help
 	  Enables the DMA1 input channel for ser0 (ttyS0).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
@@ -565,7 +565,7 @@ config ETRAX_SERIAL_PORT2_DMA7_IN
 	help
 	  Enables the DMA7 input channel for ser2 (ttyS2).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
@@ -604,7 +604,7 @@ config ETRAX_SERIAL_PORT3_DMA3_IN
 	help
 	  Enables the DMA3 input channel for ser3 (ttyS3).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/kernel/irq.c linux-libre-2.6.30-gnu1/arch/cris/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/cris/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/kernel/process.c linux-libre-2.6.30-gnu1/arch/cris/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/cris/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,6 @@
 #include <asm/system.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <linux/fs_struct.h>
 #include <linux/init_task.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/kernel/setup.c linux-libre-2.6.30-gnu1/arch/cris/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/cris/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -166,7 +166,7 @@ void __init setup_arch(char **cmdline_p)
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL;
+	return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/Makefile linux-libre-2.6.30-gnu1/arch/cris/Makefile
--- linux-libre-2.6.29-gnu1/arch/cris/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -70,7 +70,7 @@ SRC_ARCH              = $(srctree)/arch/
 # cris object files path
 OBJ_ARCH              = $(objtree)/arch/cris
 
-boot := arch/cris/$(SARCH)/boot
+boot := arch/cris/boot
 MACHINE := arch/cris/$(SARCH)
 
 all: zImage
@@ -81,15 +81,15 @@ zImage Image: vmlinux
 archprepare:
 
 archclean:
-	$(Q)if [ -e arch/cris/$(SARCH)/boot ]; then \
-		$(MAKE) $(clean)=arch/cris/$(SARCH)/boot; \
+	$(Q)if [ -e arch/cris/boot ]; then \
+		$(MAKE) $(clean)=arch/cris/boot; \
 	fi
 
 CLEAN_FILES += \
-	$(MACHINE)/boot/zImage \
-	$(MACHINE)/boot/compressed/decompress.bin \
-	$(MACHINE)/boot/compressed/piggy.gz \
-	$(MACHINE)/boot/rescue/rescue.bin
+	$(boot)/zImage \
+	$(boot)/compressed/decompress.bin \
+	$(boot)/compressed/piggy.gz \
+	$(boot)/rescue/rescue.bin
 
 
 # MRPROPER_FILES +=
diff -druNp linux-libre-2.6.29-gnu1/arch/cris/mm/init.c linux-libre-2.6.30-gnu1/arch/cris/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/cris/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/cris/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,8 +25,7 @@ mem_init(void)
 	int codesize, reservedpages, datasize, initsize;
 	unsigned long tmp;
 
-	if(!mem_map)
-		BUG();
+	BUG_ON(!mem_map);
 
 	/* max/min_low_pfn was set by setup.c
 	 * now we just copy it to some other necessary places...
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/atomic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,198 @@
+/* atomic.h: atomic operation emulation for FR-V
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/types.h>
+#include <asm/spr-regs.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+#error not SMP safe
+#endif
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ *
+ * We do not have SMP systems, so we don't have to deal with that.
+ */
+
+/* Atomic operations are already serializing */
+#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 ATOMIC_INIT(i)		{ (i) }
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = (i))
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	add%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long val;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	sub%I2		%1,%2,%1		\n"
+	    "	cst.p		%1,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    : "+U"(v->counter), "=&r"(val)
+	    : "NPr"(i)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	return val;
+}
+
+#else
+
+extern int atomic_add_return(int i, atomic_t *v);
+extern int atomic_sub_return(int i, atomic_t *v);
+
+#endif
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+	return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+	atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+	atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v)		atomic_sub_return(1, (v))
+#define atomic_inc_return(v)		atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i,v)	(atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) == 0)
+
+/*****************************************************************************/
+/*
+ * exchange value with memory
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define xchg(ptr, x)								\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 4:									\
+		asm volatile(							\
+			"swap%I0 %M0,%1"					\
+			: "+m"(*__xg_ptr), "=r"(__xg_orig)			\
+			: "1"(x)						\
+			: "memory"						\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = (__typeof__(__xg_orig))0;				\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+
+#define xchg(ptr, x)										\
+({												\
+	__typeof__(ptr) __xg_ptr = (ptr);							\
+	__typeof__(*(ptr)) __xg_orig;								\
+												\
+	switch (sizeof(__xg_orig)) {								\
+	case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr);	break;	\
+	default:										\
+		__xg_orig = (__typeof__(__xg_orig))0;									\
+		asm volatile("break");								\
+		break;										\
+	}											\
+	__xg_orig;										\
+})
+
+#endif
+
+#define tas(ptr) (xchg((ptr), 1))
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+	c = atomic_read(v);
+	for (;;) {
+		if (unlikely(c == (u)))
+			break;
+		old = atomic_cmpxchg((v), c, c + (a));
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != (u);
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#include <asm-generic/atomic.h>
+#endif /* _ASM_ATOMIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/auxvec.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/auxvec.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/auxvec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/auxvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef __FRV_AUXVEC_H
+#define __FRV_AUXVEC_H
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ax88796.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ax88796.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ax88796.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ax88796.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/* ax88796.h: access points to the driver for the AX88796 NE2000 clone
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_AX88796_H
+#define _ASM_AX88796_H
+
+#include <asm/mb-regs.h>
+
+#define AX88796_IOADDR		(__region_CS1 + 0x200)
+#define AX88796_IRQ		IRQ_CPU_EXTERNAL7
+#define AX88796_FULL_DUPLEX	0			/* force full duplex */
+#define AX88796_BUS_INFO	"CS1#+0x200"		/* bus info for ethtool */
+
+#endif /* _ASM_AX88796_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,412 @@
+/* bitops.h: bit operations for the Fujitsu FR-V CPUs
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ *   Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+
+#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <asm-generic/bitops/ffz.h>
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline
+unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	and%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(~mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	or%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+static inline
+unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v)
+{
+	unsigned long old, tmp;
+
+	asm volatile(
+		"0:						\n"
+		"	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+		"	ckeq		icc3,cc7		\n"
+		"	ld.p		%M0,%1			\n"	/* LD.P/ORCR are atomic */
+		"	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+		"	xor%I3		%1,%3,%2		\n"
+		"	cst.p		%2,%M0		,cc3,#1	\n"	/* if store happens... */
+		"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* ... clear ICC3.Z */
+		"	beq		icc3,#0,0b		\n"
+		: "+U"(*v), "=&r"(old), "=r"(tmp)
+		: "NPr"(mask)
+		: "memory", "cc7", "cc3", "icc3"
+		);
+
+	return old;
+}
+
+#else
+
+extern unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+
+#endif
+
+#define atomic_clear_mask(mask, v)	atomic_test_and_ANDNOT_mask((mask), (v))
+#define atomic_set_mask(mask, v)	atomic_test_and_OR_mask((mask), (v))
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *ptr = addr;
+	unsigned long mask = 1UL << (nr & 31);
+	ptr += nr >> 5;
+	return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+	test_and_clear_bit(nr, addr);
+}
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+	test_and_set_bit(nr, addr);
+}
+
+static inline void change_bit(int nr, volatile void * addr)
+{
+	test_and_change_bit(nr, addr);
+}
+
+static inline void __clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a &= ~mask;
+}
+
+static inline void __set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a |= mask;
+}
+
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	volatile unsigned long *a = addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	*a ^= mask;
+}
+
+static inline int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	return retval;
+}
+
+static inline int __test_and_set_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	return retval;
+}
+
+static inline int __test_and_change_bit(int nr, volatile void * addr)
+{
+	volatile unsigned long *a = addr;
+	int mask, retval;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int __constant_test_bit(int nr, const volatile void * addr)
+{
+	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static inline int __test_bit(int nr, const volatile void * addr)
+{
+	int 	* a = (int *) addr;
+	int	mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#include <asm-generic/bitops/find.h>
+
+/**
+ * fls - find last bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs:
+ * - return 32..1 to indicate bit 31..0 most significant bit set
+ * - return 0 to indicate no bits set
+ */
+#define fls(x)						\
+({							\
+	int bit;					\
+							\
+	asm("	subcc	%1,gr0,gr0,icc0		\n"	\
+	    "	ckne	icc0,cc4		\n"	\
+	    "	cscan.p	%1,gr0,%0	,cc4,#1	\n"	\
+	    "	csub	%0,%0,%0	,cc4,#0	\n"	\
+	    "   csub    %2,%0,%0	,cc4,#1	\n"	\
+	    : "=&r"(bit)				\
+	    : "r"(x), "r"(32)				\
+	    : "icc0", "cc4"				\
+	    );						\
+							\
+	bit;						\
+})
+
+/**
+ * fls64 - find last bit set in a 64-bit value
+ * @n: the value to search
+ *
+ * This is defined the same way as ffs:
+ * - return 64..1 to indicate bit 63..0 most significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int fls64(u64 n)
+{
+	union {
+		u64 ll;
+		struct { u32 h, l; };
+	} _;
+	int bit, x, y;
+
+	_.ll = n;
+
+	asm("	subcc.p		%3,gr0,gr0,icc0		\n"
+	    "	subcc		%4,gr0,gr0,icc1		\n"
+	    "	ckne		icc0,cc4		\n"
+	    "	ckne		icc1,cc5		\n"
+	    "	norcr		cc4,cc5,cc6		\n"
+	    "	csub.p		%0,%0,%0	,cc6,1	\n"
+	    "	orcr		cc5,cc4,cc4		\n"
+	    "	andcr		cc4,cc5,cc4		\n"
+	    "	cscan.p		%3,gr0,%0	,cc4,0	\n"
+	    "   setlos		#64,%1			\n"
+	    "	cscan.p		%4,gr0,%0	,cc4,1	\n"
+	    "   setlos		#32,%2			\n"
+	    "	csub.p		%1,%0,%0	,cc4,0	\n"
+	    "	csub		%2,%0,%0	,cc4,1	\n"
+	    : "=&r"(bit), "=r"(x), "=r"(y)
+	    : "0r"(_.h), "r"(_.l)
+	    : "icc0", "icc1", "cc4", "cc5", "cc6"
+	    );
+	return bit;
+
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 32..1 to indicate bit 31..0 most least significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int ffs(int x)
+{
+	/* Note: (x & -x) gives us a mask that is the least significant
+	 * (rightmost) 1-bit of the value in x.
+	 */
+	return fls(x & -x);
+}
+
+/**
+ * __ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 31..0 to indicate bit 31..0 most least significant bit set
+ * - if no bits are set in x, the result is undefined
+ */
+static inline __attribute__((const))
+int __ffs(unsigned long x)
+{
+	int bit;
+	asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x & -x));
+	return 31 - bit;
+}
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+	unsigned long bit;
+	asm("scan %1,gr0,%0" : "=r"(bit) : "r"(word));
+	return bit;
+}
+
+/*
+ * special slimline version of fls() for calculating ilog2_u32()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+	int bit;
+	asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n));
+	return 31 - bit;
+}
+
+/*
+ * special slimline version of fls64() for calculating ilog2_u64()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+	union {
+		u64 ll;
+		struct { u32 h, l; };
+	} _;
+	int bit, x, y;
+
+	_.ll = n;
+
+	asm("	subcc		%3,gr0,gr0,icc0		\n"
+	    "	ckeq		icc0,cc4		\n"
+	    "	cscan.p		%3,gr0,%0	,cc4,0	\n"
+	    "   setlos		#63,%1			\n"
+	    "	cscan.p		%4,gr0,%0	,cc4,1	\n"
+	    "   setlos		#31,%2			\n"
+	    "	csub.p		%1,%0,%0	,cc4,0	\n"
+	    "	csub		%2,%0,%0	,cc4,1	\n"
+	    : "=&r"(bit), "=r"(x), "=r"(y)
+	    : "0r"(_.h), "r"(_.l)
+	    : "icc0", "cc4"
+	    );
+	return bit;
+}
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/ext2-non-atomic.h>
+
+#define ext2_set_bit_atomic(lock,nr,addr)	test_and_set_bit  ((nr) ^ 0x18, (addr))
+#define ext2_clear_bit_atomic(lock,nr,addr)	test_and_clear_bit((nr) ^ 0x18, (addr))
+
+#include <asm-generic/bitops/minix-le.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/bug.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/bug.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/bug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/bug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+/* bug.h: FRV bug trapping
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#include <linux/linkage.h>
+
+#ifdef CONFIG_BUG
+/*
+ * Tell the user there is some problem.
+ */
+extern asmlinkage void __debug_bug_trap(int signr);
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define	_debug_bug_printk()
+#else
+extern void __debug_bug_printk(const char *file, unsigned line);
+#define	_debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__)
+#endif
+
+#define _debug_bug_trap(signr)			\
+do {						\
+	__debug_bug_trap(signr);		\
+	asm volatile("nop");			\
+} while(1)
+
+#define HAVE_ARCH_BUG
+#define BUG()					\
+do {						\
+	_debug_bug_printk();			\
+	_debug_bug_trap(6 /*SIGABRT*/);		\
+} while (0)
+
+#ifdef CONFIG_GDBSTUB
+#define HAVE_ARCH_KGDB_RAISE
+#define kgdb_raise(signr) do { _debug_bug_trap(signr); } while(0)
+
+#define HAVE_ARCH_KGDB_BAD_PAGE
+#define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0)
+#endif
+
+#endif /* CONFIG_BUG */
+
+#include <asm-generic/bug.h>
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/bugs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/bugs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/bugs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/bugs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/* bugs.h: arch bug checking entry
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+static inline void check_bugs(void)
+{
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/busctl-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/busctl-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/busctl-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/busctl-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/* busctl-regs.h: FR400-series CPU bus controller registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_BUSCTL_REGS_H
+#define _ASM_BUSCTL_REGS_H
+
+/* bus controller registers */
+#define __get_LGCR()	({ *(volatile unsigned long *)(0xfe000010); })
+#define __get_LMAICR()	({ *(volatile unsigned long *)(0xfe000030); })
+#define __get_LEMBR()	({ *(volatile unsigned long *)(0xfe000040); })
+#define __get_LEMAM()	({ *(volatile unsigned long *)(0xfe000048); })
+#define __get_LCR(R)	({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); })
+#define __get_LSBR(R)	({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); })
+#define __get_LSAM(R)	({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); })
+
+#define __set_LGCR(V)	do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0)
+#define __set_LMAICR(V)	do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0)
+#define __set_LEMBR(V)	do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0)
+#define __set_LEMAM(V)	do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0)
+#define __set_LCR(R,V)	do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0)
+#define __set_LSBR(R,V)	do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0)
+#define __set_LSAM(R,V)	do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0)
+
+/* FR401 SDRAM controller registers */
+#define __get_DBR(R)	({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); })
+#define __get_DAM(R)	({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); })
+
+/* FR551 SDRAM controller registers */
+#define __get_DARS(R)	({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); })
+#define __get_DAMK(R)	({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); })
+
+
+#endif /* _ASM_BUSCTL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/byteorder.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/byteorder.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/byteorder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/byteorder.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/cacheflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,104 @@
+/* cacheflush.h: FRV cache flushing routines
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+/* Keep includes the same across arches.  */
+#include <linux/mm.h>
+
+/*
+ * virtually-indexed cache management (our cache is physically indexed)
+ */
+#define flush_cache_all()			do {} while(0)
+#define flush_cache_mm(mm)			do {} while(0)
+#define flush_cache_dup_mm(mm)			do {} while(0)
+#define flush_cache_range(mm, start, end)	do {} while(0)
+#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 flush_dcache_mmap_lock(mapping)		do {} while(0)
+#define flush_dcache_mmap_unlock(mapping)	do {} while(0)
+
+/*
+ * physically-indexed cache management
+ * - see arch/frv/lib/cache.S
+ */
+extern void frv_dcache_writeback(unsigned long start, unsigned long size);
+extern void frv_cache_invalidate(unsigned long start, unsigned long size);
+extern void frv_icache_invalidate(unsigned long start, unsigned long size);
+extern void frv_cache_wback_inv(unsigned long start, unsigned long size);
+
+static inline void __flush_cache_all(void)
+{
+	asm volatile("	dcef	@(gr0,gr0),#1	\n"
+		     "	icei	@(gr0,gr0),#1	\n"
+		     "	membar			\n"
+		     : : : "memory"
+		     );
+}
+
+/* dcache/icache coherency... */
+#ifdef CONFIG_MMU
+extern void flush_dcache_page(struct page *page);
+#else
+static inline void flush_dcache_page(struct page *page)
+{
+	unsigned long addr = page_to_phys(page);
+	frv_dcache_writeback(addr, addr + PAGE_SIZE);
+}
+#endif
+
+static inline void flush_page_to_ram(struct page *page)
+{
+	flush_dcache_page(page);
+}
+
+static inline void flush_icache(void)
+{
+	__flush_cache_all();
+}
+
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+	frv_cache_wback_inv(start, end);
+}
+
+#ifdef CONFIG_MMU
+extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+				    unsigned long start, unsigned long len);
+#else
+static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+					   unsigned long start, unsigned long len)
+{
+	frv_cache_wback_inv(start, start + len);
+}
+#endif
+
+static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE);
+}
+
+/*
+ * permit ptrace to access another process's address space through the icache
+ * and the dcache
+ */
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
+do {								\
+	memcpy((dst), (src), (len));				\
+	flush_icache_user_range((vma), (page), (vaddr), (len));	\
+} while(0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
+	memcpy((dst), (src), (len))
+
+#endif /* _ASM_CACHEFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/* cache.h: FRV cache definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT		(CONFIG_FRV_L1_CACHE_SHIFT)
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+#define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/checksum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,180 @@
+/* checksum.h: FRV checksumming
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.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_nocheck(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);
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+static inline
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	unsigned int tmp, inc, sum = 0;
+
+	asm("	addcc		gr0,gr0,gr0,icc0\n" /* clear icc0.C */
+	    "	subi		%1,#4,%1	\n"
+	    "0:					\n"
+	    "	ldu.p		@(%1,%3),%4	\n"
+	    "	subicc		%2,#1,%2,icc1	\n"
+	    "	addxcc.p	%4,%0,%0,icc0	\n"
+	    "	bhi		icc1,#2,0b	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
+	    : "0" (sum), "1" (iph), "2" (ihl), "3" (4),
+	    "m"(*(volatile struct { int _[100]; } *)iph)
+	    : "icc0", "icc1", "memory"
+	    );
+
+	return (__force __sum16)~sum;
+}
+
+/*
+ *	Fold a partial checksum
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+	unsigned int tmp;
+
+	asm("	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+	    : "=r"(sum), "=&r"(tmp)
+	    : "0"(sum)
+	    );
+
+	return (__force __sum16)~sum;
+}
+
+/*
+ * 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,
+		  unsigned short proto, __wsum sum)
+{
+	asm("	addcc		%1,%0,%0,icc0	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	addxcc		%3,%0,%0,icc0	\n"
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    : "=r" (sum)
+	    : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
+	    : "icc0"
+	    );
+	return sum;
+}
+
+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);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+		__u32 len, unsigned short proto, __wsum sum)
+{
+	unsigned long tmp, tmp2;
+
+	asm("	addcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the source addr */
+	    "	ldi		@(%3,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%3,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%3,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* add up the dest addr */
+	    "	ldi		@(%4,0),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,4),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+	    "	ldi		@(%4,8),%1	\n"
+	    "	addxcc		%1,%0,%0,icc0	\n"
+	    "	ldi		@(%4,12),%2	\n"
+	    "	addxcc		%2,%0,%0,icc0	\n"
+
+	    /* fold the 33-bit result into 16-bits */
+	    "	addxcc		gr0,%0,%0,icc0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	sethi		#0,%0		\n"
+	    "	add		%1,%0,%0	\n"
+	    "	srli		%0,#16,%1	\n"
+	    "	add		%1,%0,%0	\n"
+
+	    : "=r" (sum), "=&r" (tmp), "=r" (tmp2)
+	    : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
+	    : "icc0"
+	    );
+
+	return (__force __sum16)~sum;
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/cpu-irqs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/cpu-irqs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/cpu-irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/cpu-irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,81 @@
+/* cpu-irqs.h: on-CPU peripheral irqs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CPU_IRQS_H
+#define _ASM_CPU_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+/* IRQ to level mappings */
+#define IRQ_GDBSTUB_LEVEL	15
+#define IRQ_UART_LEVEL		13
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define IRQ_UART0_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART0_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#ifdef CONFIG_GDBSTUB_UART1
+#define IRQ_UART1_LEVEL		IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART1_LEVEL		IRQ_UART_LEVEL
+#endif
+
+#define IRQ_DMA0_LEVEL		14
+#define IRQ_DMA1_LEVEL		14
+#define IRQ_DMA2_LEVEL		14
+#define IRQ_DMA3_LEVEL		14
+#define IRQ_DMA4_LEVEL		14
+#define IRQ_DMA5_LEVEL		14
+#define IRQ_DMA6_LEVEL		14
+#define IRQ_DMA7_LEVEL		14
+
+#define IRQ_TIMER0_LEVEL	12
+#define IRQ_TIMER1_LEVEL	11
+#define IRQ_TIMER2_LEVEL	10
+
+#define IRQ_XIRQ0_LEVEL		1
+#define IRQ_XIRQ1_LEVEL		2
+#define IRQ_XIRQ2_LEVEL		3
+#define IRQ_XIRQ3_LEVEL		4
+#define IRQ_XIRQ4_LEVEL		5
+#define IRQ_XIRQ5_LEVEL		6
+#define IRQ_XIRQ6_LEVEL		7
+#define IRQ_XIRQ7_LEVEL		8
+
+/* IRQ IDs presented to drivers */
+#define IRQ_CPU__UNUSED		IRQ_BASE_CPU
+#define IRQ_CPU_UART0		(IRQ_BASE_CPU + IRQ_UART0_LEVEL)
+#define IRQ_CPU_UART1		(IRQ_BASE_CPU + IRQ_UART1_LEVEL)
+#define IRQ_CPU_TIMER0		(IRQ_BASE_CPU + IRQ_TIMER0_LEVEL)
+#define IRQ_CPU_TIMER1		(IRQ_BASE_CPU + IRQ_TIMER1_LEVEL)
+#define IRQ_CPU_TIMER2		(IRQ_BASE_CPU + IRQ_TIMER2_LEVEL)
+#define IRQ_CPU_DMA0		(IRQ_BASE_CPU + IRQ_DMA0_LEVEL)
+#define IRQ_CPU_DMA1		(IRQ_BASE_CPU + IRQ_DMA1_LEVEL)
+#define IRQ_CPU_DMA2		(IRQ_BASE_CPU + IRQ_DMA2_LEVEL)
+#define IRQ_CPU_DMA3		(IRQ_BASE_CPU + IRQ_DMA3_LEVEL)
+#define IRQ_CPU_DMA4		(IRQ_BASE_CPU + IRQ_DMA4_LEVEL)
+#define IRQ_CPU_DMA5		(IRQ_BASE_CPU + IRQ_DMA5_LEVEL)
+#define IRQ_CPU_DMA6		(IRQ_BASE_CPU + IRQ_DMA6_LEVEL)
+#define IRQ_CPU_DMA7		(IRQ_BASE_CPU + IRQ_DMA7_LEVEL)
+#define IRQ_CPU_EXTERNAL0	(IRQ_BASE_CPU + IRQ_XIRQ0_LEVEL)
+#define IRQ_CPU_EXTERNAL1	(IRQ_BASE_CPU + IRQ_XIRQ1_LEVEL)
+#define IRQ_CPU_EXTERNAL2	(IRQ_BASE_CPU + IRQ_XIRQ2_LEVEL)
+#define IRQ_CPU_EXTERNAL3	(IRQ_BASE_CPU + IRQ_XIRQ3_LEVEL)
+#define IRQ_CPU_EXTERNAL4	(IRQ_BASE_CPU + IRQ_XIRQ4_LEVEL)
+#define IRQ_CPU_EXTERNAL5	(IRQ_BASE_CPU + IRQ_XIRQ5_LEVEL)
+#define IRQ_CPU_EXTERNAL6	(IRQ_BASE_CPU + IRQ_XIRQ6_LEVEL)
+#define IRQ_CPU_EXTERNAL7	(IRQ_BASE_CPU + IRQ_XIRQ7_LEVEL)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_CPU_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/cpumask.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/cpumask.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/cpumask.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/cpumask.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_CPUMASK_H
+#define _ASM_CPUMASK_H
+
+#include <asm-generic/cpumask.h>
+
+#endif /* _ASM_CPUMASK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/cputime.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/cputime.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/cputime.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/cputime.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_CPUTIME_H
+#define _ASM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _ASM_CPUTIME_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/current.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/current.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/* current.h: FRV current task pointer
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR29 to keeping the current task pointer
+ */
+register struct task_struct *current asm("gr29");
+
+#define get_current() current
+
+#else
+
+#define CURRENT gr29
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/delay.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/delay.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/delay.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/delay.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+/* delay.h: FRV delay code
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <asm/param.h>
+#include <asm/timer-regs.h>
+
+/*
+ * delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop]
+ */
+extern unsigned long __delay_loops_MHz;
+
+static inline void __delay(unsigned long loops)
+{
+	asm volatile("1:	subicc	%0,#1,%0,icc0	\n"
+		     "		bnc	icc0,#2,1b	\n"
+		     : "=r" (loops)
+		     : "0" (loops)
+		     : "icc0"
+		     );
+}
+
+/*
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+extern unsigned long loops_per_jiffy;
+
+static inline void udelay(unsigned long usecs)
+{
+	__delay(usecs * __delay_loops_MHz);
+}
+
+#define ndelay(n)	udelay((n) * 5)
+
+#endif /* _ASM_DELAY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/device.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/device.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/div64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/dm9000.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/dm9000.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/dm9000.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/dm9000.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/* dm9000.h: Davicom DM9000 adapter configuration
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DM9000_H
+#define _ASM_DM9000_H
+
+#include <asm/mb-regs.h>
+
+#define DM9000_ARCH_IOBASE	(__region_CS6 + 0x300)
+#define DM9000_ARCH_IRQ		IRQ_CPU_EXTERNAL3	/* XIRQ #3 (shared with FPGA) */
+#undef DM9000_ARCH_IRQ_ACTLOW				/* IRQ pin active high */
+#define DM9000_ARCH_BUS_INFO	"CS6#+0x300"		/* bus info for ethtool */
+
+#undef __is_PCI_IO
+#define __is_PCI_IO(addr)	0	/* not PCI */
+
+#undef inl
+#define inl(addr)										\
+({												\
+	unsigned long __ioaddr = (unsigned long) addr;						\
+	uint32_t x = readl(__ioaddr);								\
+	((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff);	\
+})
+
+#undef insl
+#define insl(a,b,l)	__insl(a,b,l,0) /* don't byte-swap */
+
+
+#endif /* _ASM_DM9000_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+/* dma.h: FRV DMA controller management
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+//#define DMA_DEBUG 1
+
+#include <linux/interrupt.h>
+
+#undef MAX_DMA_CHANNELS		/* don't use kernel/dma.c */
+
+/* under 2.4 this is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS		PAGE_OFFSET
+
+/*
+ * FRV DMA controller management
+ */
+typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data);
+
+extern void frv_dma_init(void);
+
+extern int frv_dma_open(const char *devname,
+			unsigned long dmamask,
+			int dmacap,
+			dma_irq_handler_t handler,
+			unsigned long irq_flags,
+			void *data);
+
+/* channels required */
+#define FRV_DMA_MASK_ANY	ULONG_MAX	/* any channel */
+
+/* capabilities required */
+#define FRV_DMA_CAP_DREQ	0x01		/* DMA request pin */
+#define FRV_DMA_CAP_DACK	0x02		/* DMA ACK pin */
+#define FRV_DMA_CAP_DONE	0x04		/* DMA done pin */
+
+extern void frv_dma_close(int dma);
+
+extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr);
+
+extern void frv_dma_start(int dma,
+			  unsigned long sba, unsigned long dba,
+			  unsigned long pix, unsigned long six, unsigned long bcl);
+
+extern void frv_dma_restart_circular(int dma, unsigned long six);
+
+extern void frv_dma_stop(int dma);
+
+extern int is_frv_dma_interrupting(int dma);
+
+extern void frv_dma_dump(int dma);
+
+extern void frv_dma_status_clear(int dma);
+
+#define FRV_DMA_NCHANS	8
+#define FRV_DMA_4CHANS	4
+#define FRV_DMA_8CHANS	8
+
+#define DMAC_CCFRx		0x00	/* channel configuration reg */
+#define DMAC_CCFRx_CM_SHIFT	16
+#define DMAC_CCFRx_CM_DA	0x00000000
+#define DMAC_CCFRx_CM_SCA	0x00010000
+#define DMAC_CCFRx_CM_DCA	0x00020000
+#define DMAC_CCFRx_CM_2D	0x00030000
+#define DMAC_CCFRx_ATS_SHIFT	8
+#define DMAC_CCFRx_RS_INTERN	0x00000000
+#define DMAC_CCFRx_RS_EXTERN	0x00000001
+#define DMAC_CCFRx_RS_SHIFT	0
+
+#define DMAC_CSTRx		0x08	/* channel status reg */
+#define DMAC_CSTRx_FS		0x0000003f
+#define DMAC_CSTRx_NE		0x00000100
+#define DMAC_CSTRx_FED		0x00000200
+#define DMAC_CSTRx_WER		0x00000800
+#define DMAC_CSTRx_RER		0x00001000
+#define DMAC_CSTRx_CE		0x00002000
+#define DMAC_CSTRx_INT		0x00800000
+#define DMAC_CSTRx_BUSY		0x80000000
+
+#define DMAC_CCTRx		0x10	/* channel control reg */
+#define DMAC_CCTRx_DSIZ_1	0x00000000
+#define DMAC_CCTRx_DSIZ_2	0x00000001
+#define DMAC_CCTRx_DSIZ_4	0x00000002
+#define DMAC_CCTRx_DSIZ_32	0x00000005
+#define DMAC_CCTRx_DAU_HOLD	0x00000000
+#define DMAC_CCTRx_DAU_INC	0x00000010
+#define DMAC_CCTRx_DAU_DEC	0x00000020
+#define DMAC_CCTRx_SSIZ_1	0x00000000
+#define DMAC_CCTRx_SSIZ_2	0x00000100
+#define DMAC_CCTRx_SSIZ_4	0x00000200
+#define DMAC_CCTRx_SSIZ_32	0x00000500
+#define DMAC_CCTRx_SAU_HOLD	0x00000000
+#define DMAC_CCTRx_SAU_INC	0x00001000
+#define DMAC_CCTRx_SAU_DEC	0x00002000
+#define DMAC_CCTRx_FC		0x08000000
+#define DMAC_CCTRx_ICE		0x10000000
+#define DMAC_CCTRx_IE		0x40000000
+#define DMAC_CCTRx_ACT		0x80000000
+
+#define DMAC_SBAx		0x18	/* source base address reg */
+#define DMAC_DBAx		0x20	/* data base address reg */
+#define DMAC_PIXx		0x28	/* primary index reg */
+#define DMAC_SIXx		0x30	/* secondary index reg */
+#define DMAC_BCLx		0x38	/* byte count limit reg */
+#define DMAC_APRx		0x40	/* alternate pointer reg */
+
+/*
+ * required for PCI + MODULES
+ */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/dma-mapping.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,174 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <linux/device.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+
+#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)
+
+extern unsigned long __nongprelbss dma_coherent_mem_start;
+extern unsigned long __nongprelbss dma_coherent_mem_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, dma_addr_t dma_handle);
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * 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);
+
+/*
+ * 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 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+/*
+ * 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.
+ */
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		      enum dma_data_direction direction);
+
+/*
+ * 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 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+extern
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+			size_t size, enum dma_data_direction direction);
+
+static inline
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+		    enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+			     enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+				enum dma_data_direction direction)
+{
+	flush_write_buffers();
+}
+
+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)
+{
+}
+
+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)
+{
+	flush_write_buffers();
+}
+
+static inline
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+			 enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+			    enum dma_data_direction direction)
+{
+	flush_write_buffers();
+}
+
+static inline
+int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline
+int 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 < 0x00ffffff)
+                return 0;
+
+	return 1;
+}
+
+static inline
+int dma_set_mask(struct device *dev, u64 mask)
+{
+	if (!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline
+int dma_get_cache_alignment(void)
+{
+	return 1 << L1_CACHE_SHIFT;
+}
+
+#define dma_is_consistent(d, h)	(1)
+
+static inline
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+		    enum dma_data_direction direction)
+{
+	flush_write_buffers();
+}
+
+#endif  /* _ASM_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/elf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,142 @@
+/* elf.h: FR-V ELF definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68knommu/elf.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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_ELF_H
+#define __ASM_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+struct elf32_hdr;
+
+/*
+ * ELF header e_flags defines.
+ */
+#define EF_FRV_GPR_MASK         0x00000003 /* mask for # of gprs */
+#define EF_FRV_GPR32		0x00000001 /* Only uses GR on 32-register */
+#define EF_FRV_GPR64		0x00000002 /* Only uses GR on 64-register */
+#define EF_FRV_FPR_MASK         0x0000000c /* mask for # of fprs */
+#define EF_FRV_FPR32		0x00000004 /* Only uses FR on 32-register */
+#define EF_FRV_FPR64		0x00000008 /* Only uses FR on 64-register */
+#define EF_FRV_FPR_NONE		0x0000000C /* Uses software floating-point */
+#define EF_FRV_DWORD_MASK       0x00000030 /* mask for dword support */
+#define EF_FRV_DWORD_YES	0x00000010 /* Assumes stack aligned to 8-byte boundaries. */
+#define EF_FRV_DWORD_NO		0x00000020 /* Assumes stack aligned to 4-byte boundaries. */
+#define EF_FRV_DOUBLE		0x00000040 /* Uses double instructions. */
+#define EF_FRV_MEDIA		0x00000080 /* Uses media instructions. */
+#define EF_FRV_PIC		0x00000100 /* Uses position independent code. */
+#define EF_FRV_NON_PIC_RELOCS	0x00000200 /* Does not use position Independent code. */
+#define EF_FRV_MULADD           0x00000400 /* -mmuladd */
+#define EF_FRV_BIGPIC           0x00000800 /* -fPIC */
+#define EF_FRV_LIBPIC           0x00001000 /* -mlibrary-pic */
+#define EF_FRV_G0               0x00002000 /* -G 0, no small data ptr */
+#define EF_FRV_NOPACK           0x00004000 /* -mnopack */
+#define EF_FRV_FDPIC            0x00008000 /* -mfdpic */
+#define EF_FRV_CPU_MASK         0xff000000 /* specific cpu bits */
+#define EF_FRV_CPU_GENERIC	0x00000000 /* Set CPU type is FR-V */
+#define EF_FRV_CPU_FR500	0x01000000 /* Set CPU type is FR500 */
+#define EF_FRV_CPU_FR300	0x02000000 /* Set CPU type is FR300 */
+#define EF_FRV_CPU_SIMPLE       0x03000000 /* SIMPLE */
+#define EF_FRV_CPU_TOMCAT       0x04000000 /* Tomcat, FR500 prototype */
+#define EF_FRV_CPU_FR400	0x05000000 /* Set CPU type is FR400 */
+#define EF_FRV_CPU_FR550        0x06000000 /* Set CPU type is FR550 */
+#define EF_FRV_CPU_FR405	0x07000000 /* Set CPU type is FR405 */
+#define EF_FRV_CPU_FR450	0x08000000 /* Set CPU type is FR450 */
+
+/*
+ * FR-V ELF relocation types
+ */
+
+
+/*
+ * ELF register definitions..
+ */
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpmedia_regs elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+extern int elf_check_arch(const struct elf32_hdr *hdr);
+
+#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS))
+#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_FRV
+
+#define ELF_PLAT_INIT(_r)			\
+do {						\
+	__kernel_frame0_ptr->gr16	= 0;	\
+	__kernel_frame0_ptr->gr17	= 0;	\
+	__kernel_frame0_ptr->gr18	= 0;	\
+	__kernel_frame0_ptr->gr19	= 0;	\
+	__kernel_frame0_ptr->gr20	= 0;	\
+	__kernel_frame0_ptr->gr21	= 0;	\
+	__kernel_frame0_ptr->gr22	= 0;	\
+	__kernel_frame0_ptr->gr23	= 0;	\
+	__kernel_frame0_ptr->gr24	= 0;	\
+	__kernel_frame0_ptr->gr25	= 0;	\
+	__kernel_frame0_ptr->gr26	= 0;	\
+	__kernel_frame0_ptr->gr27	= 0;	\
+	__kernel_frame0_ptr->gr29	= 0;	\
+} while(0)
+
+#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr)	\
+do {											\
+	__kernel_frame0_ptr->gr16	= _exec_map_addr;				\
+	__kernel_frame0_ptr->gr17	= _interp_map_addr;				\
+	__kernel_frame0_ptr->gr18	= _dynamic_addr;				\
+	__kernel_frame0_ptr->gr19	= 0;						\
+	__kernel_frame0_ptr->gr20	= 0;						\
+	__kernel_frame0_ptr->gr21	= 0;						\
+	__kernel_frame0_ptr->gr22	= 0;						\
+	__kernel_frame0_ptr->gr23	= 0;						\
+	__kernel_frame0_ptr->gr24	= 0;						\
+	__kernel_frame0_ptr->gr25	= 0;						\
+	__kernel_frame0_ptr->gr26	= 0;						\
+	__kernel_frame0_ptr->gr27	= 0;						\
+	__kernel_frame0_ptr->gr29	= 0;						\
+} while(0)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_FDPIC_CORE_EFLAGS	EF_FRV_FDPIC
+#define ELF_EXEC_PAGESIZE	16384
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         0x08000000UL
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/emergency-restart.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/emergency-restart.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/emergency-restart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/emergency-restart.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/errno.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/errno.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/errno.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/errno.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_ERRNO_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/fb.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/fb.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+#include <linux/fb.h>
+
+#define fb_pgprotect(...) do {} while (0)
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/fcntl.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/fcntl.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/fcntl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/fcntl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/fpu.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/fpu.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/fpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/fpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+#ifndef __ASM_FPU_H
+#define __ASM_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#define kernel_fpu_end() do { asm volatile("bar":::"memory"); preempt_enable(); } while(0)
+
+#endif /* __ASM_FPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/futex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);
+
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+	return -ENOSYS;
+}
+
+#endif
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/gdb-stub.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/gdb-stub.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/gdb-stub.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/gdb-stub.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,140 @@
+/* gdb-stub.h: FRV GDB stub
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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_GDB_STUB_H
+#define __ASM_GDB_STUB_H
+
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+#include <asm/ptrace.h>
+
+/*
+ * important register numbers in GDB protocol
+ * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
+ * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
+ * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+ * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+ * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+ * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+ * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+ * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+ * - FR0,  FR1,  FR2,  FR3,  FR4,  FR5,  FR6,  FR7,
+ * - FR8,  FR9,  FR10, FR11, FR12, FR13, FR14, FR15,
+ * - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23,
+ * - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31,
+ * - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39,
+ * - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47,
+ * - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55,
+ * - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63,
+ * - PC, PSR, CCR, CCCR,
+ * - _X132, _X133, _X134
+ * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+ * - SCR0, SCR1, SCR2, SCR3,
+ * - LR, LCR,
+ * - IACC0H, IACC0L,
+ * - FSR0,
+ * - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7,
+ * - ACCG0123, ACCG4567,
+ * - MSR0, MSR1,
+ * - GNER0, GNER1,
+ * - FNER0, FNER1,
+ */
+#define GDB_REG_GR(N)	(N)
+#define GDB_REG_FR(N)	(64+(N))
+#define GDB_REG_PC	128
+#define GDB_REG_PSR	129
+#define GDB_REG_CCR	130
+#define GDB_REG_CCCR	131
+#define GDB_REG_TBR	135
+#define GDB_REG_BRR	136
+#define GDB_REG_DBAR(N)	(137+(N))
+#define GDB_REG_SCR(N)	(141+(N))
+#define GDB_REG_LR	145
+#define GDB_REG_LCR	146
+#define GDB_REG_FSR0	149
+#define GDB_REG_ACC(N)	(150+(N))
+#define GDB_REG_ACCG(N)	(158+(N)/4)
+#define GDB_REG_MSR(N)	(160+(N))
+#define GDB_REG_GNER(N)	(162+(N))
+#define GDB_REG_FNER(N)	(164+(N))
+
+#define GDB_REG_SP	GDB_REG_GR(1)
+#define GDB_REG_FP	GDB_REG_GR(2)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/*
+ * Prototypes
+ */
+extern void show_registers_only(struct pt_regs *regs);
+
+extern void gdbstub_init(void);
+extern void gdbstub(int type);
+extern void gdbstub_exit(int status);
+
+extern void gdbstub_io_init(void);
+extern void gdbstub_set_baud(unsigned baud);
+extern int gdbstub_rx_char(unsigned char *_ch, int nonblock);
+extern void gdbstub_tx_char(unsigned char ch);
+extern void gdbstub_tx_flush(void);
+extern void gdbstub_do_rx(void);
+
+extern asmlinkage void __debug_stub_init_break(void);
+extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+extern asmlinkage void start_kernel(void);
+
+extern asmlinkage void gdbstub_rx_handler(void);
+extern asmlinkage void gdbstub_rx_irq(void);
+extern asmlinkage void gdbstub_intercept(void);
+
+extern uint32_t __entry_usertrap_table[];
+extern uint32_t __entry_kerneltrap_table[];
+
+extern volatile u8	gdbstub_rx_buffer[PAGE_SIZE];
+extern volatile u32	gdbstub_rx_inp;
+extern volatile u32	gdbstub_rx_outp;
+extern volatile u8	gdbstub_rx_overflow;
+extern u8		gdbstub_rx_unget;
+
+extern void gdbstub_printk(const char *fmt, ...);
+extern void debug_to_serial(const char *p, int n);
+extern void console_set_baud(unsigned baud);
+
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
+#else
+#define gdbstub_proto(FMT,...) ({ 0; })
+#endif
+
+/*
+ * we dedicate GR31 to keeping a pointer to the gdbstub exception frame
+ * - gr31 is destroyed on entry to the gdbstub if !MMU
+ * - gr31 is saved in scr3 on entry to the gdbstub if in !MMU
+ */
+register struct frv_frame0 *__debug_frame0 asm("gr31");
+
+#define __debug_frame		(&__debug_frame0->regs)
+#define __debug_user_context	(&__debug_frame0->uc)
+#define __debug_regs		(&__debug_frame0->debug)
+#define __debug_reg(X)		((unsigned long *) ((unsigned long) &__debug_frame0 + (X)))
+
+struct frv_debug_status {
+	unsigned long		bpsr;
+	unsigned long		dcr;
+	unsigned long		brr;
+	unsigned long		nmar;
+};
+
+extern struct frv_debug_status __debug_status;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASM_GDB_STUB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/gpio-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/gpio-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/gpio-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/gpio-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+/* gpio-regs.h: on-chip general purpose I/O registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_GPIO_REGS
+#define _ASM_GPIO_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_PDR()	({ __reg(0xfeff0400); })
+#define __set_PDR(V)	do { __reg(0xfeff0400) = (V); mb(); } while(0)
+
+#define __get_GPDR()	({ __reg(0xfeff0408); })
+#define __set_GPDR(V)	do { __reg(0xfeff0408) = (V); mb(); } while(0)
+
+#define __get_SIR()	({ __reg(0xfeff0410); })
+#define __set_SIR(V)	do { __reg(0xfeff0410) = (V); mb(); } while(0)
+
+#define __get_SOR()	({ __reg(0xfeff0418); })
+#define __set_SOR(V)	do { __reg(0xfeff0418) = (V); mb(); } while(0)
+
+#define __set_PDSR(V)	do { __reg(0xfeff0420) = (V); mb(); } while(0)
+
+#define __set_PDCR(V)	do { __reg(0xfeff0428) = (V); mb(); } while(0)
+
+#define __get_RSTR()	({ __reg(0xfeff0500); })
+#define __set_RSTR(V)	do { __reg(0xfeff0500) = (V); mb(); } while(0)
+
+
+
+/* PDR definitions */
+#define PDR_GPIO_DATA(X)	(1 << (X))
+
+/* GPDR definitions */
+#define GPDR_INPUT		0
+#define GPDR_OUTPUT		1
+#define GPDR_DREQ0_BIT		0x00001000
+#define GPDR_DREQ1_BIT		0x00008000
+#define GPDR_DREQ2_BIT		0x00040000
+#define GPDR_DREQ3_BIT		0x00080000
+#define GPDR_DREQ4_BIT		0x00004000
+#define GPDR_DREQ5_BIT		0x00020000
+#define GPDR_DREQ6_BIT		0x00100000
+#define GPDR_DREQ7_BIT		0x00200000
+#define GPDR_DACK0_BIT		0x00002000
+#define GPDR_DACK1_BIT		0x00010000
+#define GPDR_DACK2_BIT		0x00100000
+#define GPDR_DACK3_BIT		0x00200000
+#define GPDR_DONE0_BIT		0x00004000
+#define GPDR_DONE1_BIT		0x00020000
+#define GPDR_GPIO_DIR(X,D)	((D) << (X))
+
+/* SIR definitions */
+#define SIR_GPIO_INPUT		0
+#define SIR_DREQ7_INPUT		0x00200000
+#define SIR_DREQ6_INPUT		0x00100000
+#define SIR_DREQ3_INPUT		0x00080000
+#define SIR_DREQ2_INPUT		0x00040000
+#define SIR_DREQ5_INPUT		0x00020000
+#define SIR_DREQ1_INPUT		0x00008000
+#define SIR_DREQ4_INPUT		0x00004000
+#define SIR_DREQ0_INPUT		0x00001000
+#define SIR_RXD1_INPUT		0x00000400
+#define SIR_CTS0_INPUT		0x00000100
+#define SIR_RXD0_INPUT		0x00000040
+#define SIR_GATE1_INPUT		0x00000020
+#define SIR_GATE0_INPUT		0x00000010
+#define SIR_IRQ3_INPUT		0x00000008
+#define SIR_IRQ2_INPUT		0x00000004
+#define SIR_IRQ1_INPUT		0x00000002
+#define SIR_IRQ0_INPUT		0x00000001
+#define SIR_DREQ_BITS		(SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \
+				 SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \
+				 SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \
+				 SIR_DREQ6_INPUT | SIR_DREQ7_INPUT)
+
+/* SOR definitions */
+#define SOR_GPIO_OUTPUT		0
+#define SOR_DACK3_OUTPUT	0x00200000
+#define SOR_DACK2_OUTPUT	0x00100000
+#define SOR_DONE1_OUTPUT	0x00020000
+#define SOR_DACK1_OUTPUT	0x00010000
+#define SOR_DONE0_OUTPUT	0x00004000
+#define SOR_DACK0_OUTPUT	0x00002000
+#define SOR_TXD1_OUTPUT		0x00000800
+#define SOR_RTS0_OUTPUT		0x00000200
+#define SOR_TXD0_OUTPUT		0x00000080
+#define SOR_TOUT1_OUTPUT	0x00000020
+#define SOR_TOUT0_OUTPUT	0x00000010
+#define SOR_DONE_BITS		(SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT)
+#define SOR_DACK_BITS		(SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \
+				 SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT)
+
+/* PDSR definitions */
+#define PDSR_UNCHANGED		0
+#define PDSR_SET_BIT(X)		(1 << (X))
+
+/* PDCR definitions */
+#define PDCR_UNCHANGED		0
+#define PDCR_CLEAR_BIT(X)	(1 << (X))
+
+/* RSTR definitions */
+/* Read Only */
+#define RSTR_POWERON		0x00000400
+#define RSTR_SOFTRESET_STATUS	0x00000100
+/* Write Only */
+#define RSTR_SOFTRESET		0x00000001
+
+#endif /* _ASM_GPIO_REGS */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/hardirq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+/* hardirq.h: FRV hardware IRQ management
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned long idle_timestamp;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+#ifdef CONFIG_SMP
+#error SMP not available on FR-V
+#endif /* CONFIG_SMP */
+
+extern atomic_t irq_err_count;
+static inline void ack_bad_irq(int irq)
+{
+	atomic_inc(&irq_err_count);
+}
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/highmem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,182 @@
+/* highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-i386/highmem.h
+ *
+ * See Documentation/frv/mmu-layout.txt for more information.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+
+#define NR_TLB_LINES		64	/* number of lines in the TLB */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define HIGHMEM_DEBUG 1
+#else
+#define HIGHMEM_DEBUG 0
+#endif
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+#define kmap_prot PAGE_KERNEL
+#define kmap_pte ______kmap_pte_in_TLB
+extern pte_t *pkmap_page_table;
+
+#define flush_cache_kmaps()  do { } while (0)
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP	PTRS_PER_PTE
+#define LAST_PKMAP_MASK	(LAST_PKMAP - 1)
+#define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+
+extern struct page *kmap_atomic_to_page(void *ptr);
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+#define KMAP_ATOMIC_CACHE_DAMR		8
+
+#ifndef __ASSEMBLY__
+
+#define __kmap_atomic_primary(type, paddr, ampr)						\
+({												\
+	unsigned long damlr, dampr;								\
+												\
+	dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V;		\
+												\
+	if (type != __KM_CACHE)									\
+		asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory");			\
+	else											\
+		asm volatile("movgs %0,iampr"#ampr"\n"						\
+			     "movgs %0,dampr"#ampr"\n"						\
+			     :: "r"(dampr) : "memory"						\
+			     );									\
+												\
+	asm("movsg damlr"#ampr",%0" : "=r"(damlr));						\
+												\
+	/*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/		\
+												\
+	(void *) damlr;										\
+})
+
+#define __kmap_atomic_secondary(slot, paddr)							  \
+({												  \
+	unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE;			  \
+	unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
+												  \
+	asm volatile("movgs %0,tplr \n"								  \
+		     "movgs %1,tppr \n"								  \
+		     "tlbpr %0,gr0,#2,#1"							  \
+		     : : "r"(damlr), "r"(dampr) : "memory");					  \
+												  \
+	/*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/			  \
+												  \
+	(void *) damlr;										  \
+})
+
+static inline void *kmap_atomic(struct page *page, enum km_type type)
+{
+	unsigned long paddr;
+
+	pagefault_disable();
+	debug_kmap_atomic(type);
+	paddr = page_to_phys(page);
+
+	switch (type) {
+        case 0:		return __kmap_atomic_primary(0, paddr, 2);
+        case 1:		return __kmap_atomic_primary(1, paddr, 3);
+        case 2:		return __kmap_atomic_primary(2, paddr, 4);
+        case 3:		return __kmap_atomic_primary(3, paddr, 5);
+        case 4:		return __kmap_atomic_primary(4, paddr, 6);
+        case 5:		return __kmap_atomic_primary(5, paddr, 7);
+        case 6:		return __kmap_atomic_primary(6, paddr, 8);
+        case 7:		return __kmap_atomic_primary(7, paddr, 9);
+        case 8:		return __kmap_atomic_primary(8, paddr, 10);
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		return __kmap_atomic_secondary(type - 9, paddr);
+
+	default:
+		BUG();
+		return NULL;
+	}
+}
+
+#define __kunmap_atomic_primary(type, ampr)				\
+do {									\
+	asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory");		\
+	if (type == __KM_CACHE)						\
+		asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory");	\
+} while(0)
+
+#define __kunmap_atomic_secondary(slot, vaddr)				\
+do {									\
+	asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory");	\
+} while(0)
+
+static inline void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+	switch (type) {
+        case 0:		__kunmap_atomic_primary(0, 2);	break;
+        case 1:		__kunmap_atomic_primary(1, 3);	break;
+        case 2:		__kunmap_atomic_primary(2, 4);	break;
+        case 3:		__kunmap_atomic_primary(3, 5);	break;
+        case 4:		__kunmap_atomic_primary(4, 6);	break;
+        case 5:		__kunmap_atomic_primary(5, 7);	break;
+        case 6:		__kunmap_atomic_primary(6, 8);	break;
+        case 7:		__kunmap_atomic_primary(7, 9);	break;
+        case 8:		__kunmap_atomic_primary(8, 10);	break;
+
+	case 9 ... 9 + NR_TLB_LINES - 1:
+		__kunmap_atomic_secondary(type - 9, kvaddr);
+		break;
+
+	default:
+		BUG();
+	}
+	pagefault_enable();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/hw_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/* hw_irq.h: FR-V specific h/w IRQ stuff
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+
+#endif /* _ASM_HW_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ioctl.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ioctl.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ioctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ioctls.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ioctls.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ioctls.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ioctls.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+#ifndef __ASM_IOCTLS_H__
+#define __ASM_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TCGETS2		_IOR('T',0x2A, struct termios2)
+#define TCSETS2		_IOW('T',0x2B, struct termios2)
+#define TCSETSW2	_IOW('T',0x2C, struct termios2)
+#define TCSETSF2	_IOW('T',0x2D, struct termios2)
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ASM_IOCTLS_H__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/io.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,392 @@
+/* io.h: FRV I/O operations
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This gets interesting when talking to the PCI bus - the CPU is in big endian
+ * mode, the PCI bus is little endian and the hardware in the middle can do
+ * byte swapping
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/virtconvert.h>
+#include <asm/string.h>
+#include <asm/mb-regs.h>
+#include <linux/delay.h>
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+static inline unsigned short _swapw(unsigned short v)
+{
+    return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned long _swapl(unsigned long v)
+{
+    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+//#define __iormb() asm volatile("membar")
+//#define __iowmb() asm volatile("membar")
+
+#define __raw_readb __builtin_read8
+#define __raw_readw __builtin_read16
+#define __raw_readl __builtin_read32
+
+#define __raw_writeb(datum, addr) __builtin_write8(addr, datum)
+#define __raw_writew(datum, addr) __builtin_write16(addr, datum)
+#define __raw_writel(datum, addr) __builtin_write32(addr, datum)
+
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint8_t *bp = buf;
+
+	while (len--)
+		__builtin_write8((volatile void __iomem *) __ioaddr, *bp++);
+}
+
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+	const uint16_t *bp = buf;
+
+	while (len--)
+		__builtin_write16((volatile void __iomem *) __ioaddr, (*bp++));
+}
+
+extern void __outsl_ns(unsigned int addr, const void *buf, int len);
+extern void __outsl_sw(unsigned int addr, const void *buf, int len);
+static inline void __outsl(unsigned int addr, const void *buf, int len, int swap)
+{
+	unsigned long __ioaddr = (unsigned long) addr;
+
+	if (!swap)
+		__outsl_ns(__ioaddr, buf, len);
+	else
+		__outsl_sw(__ioaddr, buf, len);
+}
+
+static inline void io_insb(unsigned long addr, void *buf, int len)
+{
+	uint8_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read8((volatile void __iomem *) addr);
+}
+
+static inline void io_insw(unsigned long addr, void *buf, int len)
+{
+	uint16_t *bp = buf;
+
+	while (len--)
+		*bp++ = __builtin_read16((volatile void __iomem *) addr);
+}
+
+extern void __insl_ns(unsigned long addr, void *buf, int len);
+extern void __insl_sw(unsigned long addr, void *buf, int len);
+static inline void __insl(unsigned long addr, void *buf, int len, int swap)
+{
+	if (!swap)
+		__insl_ns(addr, buf, len);
+	else
+		__insl_sw(addr, buf, len);
+}
+
+#define mmiowb() mb()
+
+/*
+ *	make the short names macros so specific devices
+ *	can override them as required
+ */
+
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+	memset((void __force *) addr, val, count);
+}
+
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+{
+	memcpy(dst, (void __force *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+	memcpy((void __force *) dst, src, count);
+}
+
+static inline uint8_t inb(unsigned long addr)
+{
+	return __builtin_read8((void __iomem *)addr);
+}
+
+static inline uint16_t inw(unsigned long addr)
+{
+	uint16_t ret = __builtin_read16((void __iomem *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapw(ret);
+
+	return ret;
+}
+
+static inline uint32_t inl(unsigned long addr)
+{
+	uint32_t ret = __builtin_read32((void __iomem *)addr);
+
+	if (__is_PCI_IO(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+static inline void outb(uint8_t datum, unsigned long addr)
+{
+	__builtin_write8((void __iomem *)addr, datum);
+}
+
+static inline void outw(uint16_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapw(datum);
+	__builtin_write16((void __iomem *)addr, datum);
+}
+
+static inline void outl(uint32_t datum, unsigned long addr)
+{
+	if (__is_PCI_IO(addr))
+		datum = _swapl(datum);
+	__builtin_write32((void __iomem *)addr, datum);
+}
+
+#define inb_p(addr)	inb(addr)
+#define inw_p(addr)	inw(addr)
+#define inl_p(addr)	inl(addr)
+#define outb_p(x,addr)	outb(x,addr)
+#define outw_p(x,addr)	outw(x,addr)
+#define outl_p(x,addr)	outl(x,addr)
+
+#define outsb(a,b,l)	io_outsb(a,b,l)
+#define outsw(a,b,l)	io_outsw(a,b,l)
+#define outsl(a,b,l)	__outsl(a,b,l,0)
+
+#define insb(a,b,l)	io_insb(a,b,l)
+#define insw(a,b,l)	io_insw(a,b,l)
+#define insl(a,b,l)	__insl(a,b,l,0)
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+static inline uint8_t readb(const volatile void __iomem *addr)
+{
+	return __builtin_read8((__force void volatile __iomem *) addr);
+}
+
+static inline uint16_t readw(const volatile void __iomem *addr)
+{
+	uint16_t ret =	__builtin_read16((__force void volatile __iomem *)addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapw(ret);
+	return ret;
+}
+
+static inline uint32_t readl(const volatile void __iomem *addr)
+{
+	uint32_t ret =	__builtin_read32((__force void volatile __iomem *)addr);
+
+	if (__is_PCI_MEM(addr))
+		ret = _swapl(ret);
+
+	return ret;
+}
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
+static inline void writeb(uint8_t datum, volatile void __iomem *addr)
+{
+	__builtin_write8(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writew(uint16_t datum, volatile void __iomem *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapw(datum);
+
+	__builtin_write16(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+static inline void writel(uint32_t datum, volatile void __iomem *addr)
+{
+	if (__is_PCI_MEM(addr))
+		datum = _swapl(datum);
+
+	__builtin_write32(addr, datum);
+	if (__is_PCI_MEM(addr))
+		__flush_PCI_writes();
+}
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING		0
+#define IOMAP_NOCACHE_SER		1
+#define IOMAP_NOCACHE_NONSER		2
+#define IOMAP_WRITETHROUGH		3
+
+extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+
+static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+#define ioremap_wc ioremap_nocache
+
+extern void iounmap(void volatile __iomem *addr);
+
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) port;
+}
+
+static inline void ioport_unmap(void __iomem *p)
+{
+}
+
+static inline void flush_write_buffers(void)
+{
+	__asm__ __volatile__ ("membar" : : :"memory");
+}
+
+/*
+ * do appropriate I/O accesses for token type
+ */
+static inline unsigned int ioread8(void __iomem *p)
+{
+	return __builtin_read8(p);
+}
+
+static inline unsigned int ioread16(void __iomem *p)
+{
+	uint16_t ret = __builtin_read16(p);
+	if (__is_PCI_addr(p))
+		ret = _swapw(ret);
+	return ret;
+}
+
+static inline unsigned int ioread32(void __iomem *p)
+{
+	uint32_t ret = __builtin_read32(p);
+	if (__is_PCI_addr(p))
+		ret = _swapl(ret);
+	return ret;
+}
+
+static inline void iowrite8(u8 val, void __iomem *p)
+{
+	__builtin_write8(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void iowrite16(u16 val, void __iomem *p)
+{
+	if (__is_PCI_addr(p))
+		val = _swapw(val);
+	__builtin_write16(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void iowrite32(u32 val, void __iomem *p)
+{
+	if (__is_PCI_addr(p))
+		val = _swapl(val);
+	__builtin_write32(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void ioread8_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	io_insb((unsigned long) p, dst, count);
+}
+
+static inline void ioread16_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	io_insw((unsigned long) p, dst, count);
+}
+
+static inline void ioread32_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	__insl_ns((unsigned long) p, dst, count);
+}
+
+static inline void iowrite8_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	io_outsb((unsigned long) p, src, count);
+}
+
+static inline void iowrite16_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	io_outsw((unsigned long) p, src, count);
+}
+
+static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	__outsl_ns((unsigned long) p, src, count);
+}
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
+{
+}
+
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ipcbuf.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ipcbuf.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ipcbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ipcbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+#ifndef __ASM_IPCBUF_H__
+#define __ASM_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* __ASM_IPCBUF_H__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/irc-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/irc-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/irc-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/irc-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,53 @@
+/* irc-regs.h: on-chip interrupt controller registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRC_REGS
+#define _ASM_IRC_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_TM0()	({ __reg(0xfeff9800); })
+#define __get_TM1()	({ __reg(0xfeff9808); })
+#define __set_TM1(V)	do { __reg(0xfeff9808) = (V); mb(); } while(0)
+
+#define __set_TM1x(XI,V)			\
+do {						\
+	int shift = (XI) * 2 + 16;		\
+	unsigned long tm1 = __reg(0xfeff9808);	\
+	tm1 &= ~(0x3 << shift);			\
+	tm1 |= (V) << shift;			\
+	__reg(0xfeff9808) = tm1;		\
+	mb();					\
+} while(0)
+
+#define __get_RS(C)	({ (__reg(0xfeff9810) >> ((C)+16)) & 1; })
+
+#define __clr_RC(C)	do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0)
+
+#define __get_MASK(C)	({ (__reg(0xfeff9820) >> ((C)+16)) & 1; })
+#define __set_MASK(C)	do { __reg(0xfeff9820) |=  1 << ((C)+16); mb(); } while(0)
+#define __clr_MASK(C)	do { __reg(0xfeff9820) &=  ~(1 << ((C)+16)); mb(); } while(0)
+
+#define __get_MASK_all() __get_MASK(0)
+#define __set_MASK_all() __set_MASK(0)
+#define __clr_MASK_all() __clr_MASK(0)
+
+#define __get_IRL()	({ (__reg(0xfeff9828) >> 16) & 0xf; })
+#define __clr_IRL()	do { __reg(0xfeff9828) = 0x100000; mb(); } while(0)
+
+#define __get_IRR(N)	({ __reg(0xfeff9840 + (N) * 8); })
+#define __set_IRR(N,V)	do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0)
+
+#define __get_IITMR(N)	({ __reg(0xfeff9880 + (N) * 8); })
+#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0)
+
+
+#endif /* _ASM_IRC_REGS */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/* irq.h: FRV IRQ definitions
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_H_
+#define _ASM_IRQ_H_
+
+#define NR_IRQS				48
+#define IRQ_BASE_CPU			(0 * 16)
+#define IRQ_BASE_FPGA			(1 * 16)
+#define IRQ_BASE_MB93493		(2 * 16)
+
+/* probe returns a 32-bit IRQ mask:-/ */
+#define MIN_PROBE_IRQ			(NR_IRQS - 32)
+
+#ifndef __ASSEMBLY__
+static inline int irq_canonicalize(int irq)
+{
+	return irq;
+}
+#endif
+
+#endif /* _ASM_IRQ_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/irq_regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/irq_regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/irq_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/irq_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+/* FRV per-CPU frame pointer holder
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_REGS_H
+#define _ASM_IRQ_REGS_H
+
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack
+ * - on FRV, GR28 is dedicated to keeping a pointer to the current exception
+ *   frame
+ */
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#ifndef __ASSEMBLY__
+#define get_irq_regs() (__frame)
+#endif
+
+#endif /* _ASM_IRQ_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/Kbuild linux-libre-2.6.30-gnu1/arch/frv/include/asm/Kbuild
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/Kbuild	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/Kbuild	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,5 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += registers.h
+
+unifdef-y += termios.h
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/kdebug.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/kdebug.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/kdebug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/kdebug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/kmap_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	/* arch specific kmaps - change the numbers attached to these at your peril */
+	__KM_CACHE,		/* cache flush page attachment point */
+	__KM_PGD,		/* current page directory */
+	__KM_ITLB_PTD,		/* current instruction TLB miss page table lookup */
+	__KM_DTLB_PTD,		/* current data TLB miss page table lookup */
+
+	/* general kmaps */
+        KM_BOUNCE_READ,
+        KM_SKB_SUNRPC_DATA,
+        KM_SKB_DATA_SOFTIRQ,
+        KM_USER0,
+        KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/linkage.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/linkage.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/linkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN		.align 4
+#define __ALIGN_STR	".align 4"
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/local.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/local.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/local.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/local.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_LOCAL_H
+#define _ASM_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_LOCAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/math-emu.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/math-emu.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/math-emu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/math-emu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,301 @@
+#ifndef _ASM_MATH_EMU_H
+#define _ASM_MATH_EMU_H
+
+#include <asm/setup.h>
+#include <linux/linkage.h>
+
+/* Status Register bits */
+
+/* accrued exception bits */
+#define FPSR_AEXC_INEX	3
+#define FPSR_AEXC_DZ	4
+#define FPSR_AEXC_UNFL	5
+#define FPSR_AEXC_OVFL	6
+#define FPSR_AEXC_IOP	7
+
+/* exception status bits */
+#define FPSR_EXC_INEX1	8
+#define FPSR_EXC_INEX2	9
+#define FPSR_EXC_DZ	10
+#define FPSR_EXC_UNFL	11
+#define FPSR_EXC_OVFL	12
+#define FPSR_EXC_OPERR	13
+#define FPSR_EXC_SNAN	14
+#define FPSR_EXC_BSUN	15
+
+/* quotient byte, assumes big-endian, of course */
+#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
+
+/* condition code bits */
+#define FPSR_CC_NAN	24
+#define FPSR_CC_INF	25
+#define FPSR_CC_Z	26
+#define FPSR_CC_NEG	27
+
+
+/* Control register bits */
+
+/* rounding mode */
+#define	FPCR_ROUND_RN	0		/* round to nearest/even */
+#define FPCR_ROUND_RZ	1		/* round to zero */
+#define FPCR_ROUND_RM	2		/* minus infinity */
+#define FPCR_ROUND_RP	3		/* plus infinity */
+
+/* rounding precision */
+#define FPCR_PRECISION_X	0	/* long double */
+#define FPCR_PRECISION_S	1	/* double */
+#define FPCR_PRECISION_D	2	/* float */
+
+
+/* Flags to select the debugging output */
+#define PDECODE		0
+#define PEXECUTE	1
+#define PCONV		2
+#define PNORM		3
+#define PREGISTER	4
+#define PINSTR		5
+#define PUNIMPL		6
+#define PMOVEM		7
+
+#define PMDECODE	(1<<PDECODE)
+#define PMEXECUTE	(1<<PEXECUTE)
+#define PMCONV		(1<<PCONV)
+#define PMNORM		(1<<PNORM)
+#define PMREGISTER	(1<<PREGISTER)
+#define PMINSTR		(1<<PINSTR)
+#define PMUNIMPL	(1<<PUNIMPL)
+#define PMMOVEM		(1<<PMOVEM)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+union fp_mant64 {
+	unsigned long long m64;
+	unsigned long m32[2];
+};
+
+union fp_mant128 {
+	unsigned long long m64[2];
+	unsigned long m32[4];
+};
+
+/* internal representation of extended fp numbers */
+struct fp_ext {
+	unsigned char lowmant;
+	unsigned char sign;
+	unsigned short exp;
+	union fp_mant64 mant;
+};
+
+/* C representation of FPU registers */
+/* NOTE: if you change this, you have to change the assembler offsets
+   below and the size in <asm/fpu.h>, too */
+struct fp_data {
+	struct fp_ext fpreg[8];
+	unsigned int fpcr;
+	unsigned int fpsr;
+	unsigned int fpiar;
+	unsigned short prec;
+	unsigned short rnd;
+	struct fp_ext temp[2];
+};
+
+#if FPU_EMU_DEBUG
+extern unsigned int fp_debugprint;
+
+#define dprint(bit, fmt, args...) ({			\
+	if (fp_debugprint & (1 << (bit)))		\
+		printk(fmt, ## args);			\
+})
+#else
+#define dprint(bit, fmt, args...)
+#endif
+
+#define uprint(str) ({					\
+	static int __count = 3;				\
+							\
+	if (__count > 0) {				\
+		printk("You just hit an unimplemented "	\
+		       "fpu instruction (%s)\n", str);	\
+		printk("Please report this to ....\n");	\
+		__count--;				\
+	}						\
+})
+
+#define FPDATA		((struct fp_data *)current->thread.fp)
+
+#else	/* __ASSEMBLY__ */
+
+#define FPDATA		%a2
+
+/* offsets from the base register to the floating point data in the task struct */
+#define FPD_FPREG	(TASK_THREAD+THREAD_FPREG+0)
+#define FPD_FPCR	(TASK_THREAD+THREAD_FPREG+96)
+#define FPD_FPSR	(TASK_THREAD+THREAD_FPREG+100)
+#define FPD_FPIAR	(TASK_THREAD+THREAD_FPREG+104)
+#define FPD_PREC	(TASK_THREAD+THREAD_FPREG+108)
+#define FPD_RND		(TASK_THREAD+THREAD_FPREG+110)
+#define FPD_TEMPFP1	(TASK_THREAD+THREAD_FPREG+112)
+#define FPD_TEMPFP2	(TASK_THREAD+THREAD_FPREG+124)
+#define FPD_SIZEOF	(TASK_THREAD+THREAD_FPREG+136)
+
+/* offsets on the stack to access saved registers,
+ * these are only used during instruction decoding
+ * where we always know how deep we're on the stack.
+ */
+#define FPS_DO		(PT_D0)
+#define FPS_D1		(PT_D1)
+#define FPS_D2		(PT_D2)
+#define FPS_A0		(PT_A0)
+#define FPS_A1		(PT_A1)
+#define FPS_A2		(PT_A2)
+#define FPS_SR		(PT_SR)
+#define FPS_PC		(PT_PC)
+#define FPS_EA		(PT_PC+6)
+#define FPS_PC2		(PT_PC+10)
+
+.macro	fp_get_fp_reg
+	lea	(FPD_FPREG,FPDATA,%d0.w*4),%a0
+	lea	(%a0,%d0.w*8),%a0
+.endm
+
+/* Macros used to get/put the current program counter.
+ * 020/030 use a different stack frame then 040/060, for the
+ * 040/060 the return pc points already to the next location,
+ * so this only needs to be modified for jump instructions.
+ */
+.macro	fp_get_pc dest
+	move.l	(FPS_PC+4,%sp),\dest
+.endm
+
+.macro	fp_put_pc src,jump=0
+	move.l	\src,(FPS_PC+4,%sp)
+.endm
+
+.macro	fp_get_instr_data	f,s,dest,label
+	getuser	\f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4)
+	addq.l	#\s,%sp@(FPS_PC+4)
+.endm
+
+.macro	fp_get_instr_word	dest,label,addr
+	fp_get_instr_data	w,2,\dest,\label,\addr
+.endm
+
+.macro	fp_get_instr_long	dest,label,addr
+	fp_get_instr_data	l,4,\dest,\label,\addr
+.endm
+
+/* These macros are used to read from/write to user space
+ * on error we jump to the fixup section, load the fault
+ * address into %a0 and jump to the exit.
+ * (derived from <asm/uaccess.h>)
+ */
+.macro	getuser	size,src,dest,label,addr
+|	printf	,"[\size<%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+
+	.section .fixup,"ax"
+	.even
+.Lu2\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu2\@
+	.previous
+.endm
+
+.macro	putuser	size,src,dest,label,addr
+|	printf	,"[\size>%08x]",1,\addr
+.Lu1\@:	moves\size	\src,\dest
+.Lu2\@:
+
+	.section .fixup,"ax"
+	.even
+.Lu3\@:	move.l	\addr,%a0
+	jra	\label
+	.previous
+
+	.section __ex_table,"a"
+	.align	4
+	.long	.Lu1\@,.Lu3\@
+	.long	.Lu2\@,.Lu3\@
+	.previous
+.endm
+
+
+.macro	movestack	nr,arg1,arg2,arg3,arg4,arg5
+	.if	\nr
+	movestack	(\nr-1),\arg2,\arg3,\arg4,\arg5
+	move.l	\arg1,-(%sp)
+	.endif
+.endm
+
+.macro	printf	bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
+#ifdef FPU_EMU_DEBUG
+	.data
+.Lpdata\@:
+	.string	"\string"
+	.previous
+
+	movem.l	%d0/%d1/%a0/%a1,-(%sp)
+	.if	\bit+1
+#if 0
+	moveq	#\bit,%d0
+	andw	#7,%d0
+	btst	%d0,fp_debugprint+((31-\bit)/8)
+#else
+	btst	#\bit,fp_debugprint+((31-\bit)/8)
+#endif
+	jeq	.Lpskip\@
+	.endif
+	movestack	\nr,\arg1,\arg2,\arg3,\arg4,\arg5
+	pea	.Lpdata\@
+	jsr	printk
+	lea	((\nr+1)*4,%sp),%sp
+.Lpskip\@:
+	movem.l	(%sp)+,%d0/%d1/%a0/%a1
+#endif
+.endm
+
+.macro	printx	bit,fp
+#ifdef FPU_EMU_DEBUG
+	movem.l	%d0/%a0,-(%sp)
+	lea	\fp,%a0
+#if 0
+	moveq	#'+',%d0
+	tst.w	(%a0)
+	jeq	.Lx1\@
+	moveq	#'-',%d0
+.Lx1\@:	printf	\bit," %c",1,%d0
+	move.l	(4,%a0),%d0
+	bclr	#31,%d0
+	jne	.Lx2\@
+	printf	\bit,"0."
+	jra	.Lx3\@
+.Lx2\@:	printf	\bit,"1."
+.Lx3\@:	printf	\bit,"%08x%08x",2,%d0,%a0@(8)
+	move.w	(2,%a0),%d0
+	ext.l	%d0
+	printf	\bit,"E%04x",1,%d0
+#else
+	printf	\bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
+#endif
+	movem.l	(%sp)+,%d0/%a0
+#endif
+.endm
+
+.macro	debug	instr,args
+#ifdef FPU_EMU_DEBUG
+	\instr	\args
+#endif
+.endm
+
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_FRV_MATH_EMU_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb86943a.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb86943a.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb86943a.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb86943a.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/* mb86943a.h: MB86943 SPARClite <-> PCI bridge registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB86943A_H
+#define _ASM_MB86943A_H
+
+#include <asm/mb-regs.h>
+
+#define __reg_MB86943_sl_ctl		*(volatile uint32_t *) (__region_CS1 + 0x00)
+
+#define MB86943_SL_CTL_BUS_WIDTH_64	0x00000001
+#define MB86943_SL_CTL_AS_HOST		0x00000002
+#define MB86943_SL_CTL_DRCT_MASTER_SWAP	0x00000004
+#define MB86943_SL_CTL_DRCT_SLAVE_SWAP	0x00000008
+#define MB86943_SL_CTL_PCI_CONFIG_SWAP	0x00000010
+#define MB86943_SL_CTL_ECS0_ENABLE	0x00000020
+#define MB86943_SL_CTL_ECS1_ENABLE	0x00000040
+#define MB86943_SL_CTL_ECS2_ENABLE	0x00000080
+
+#define __reg_MB86943_ecs_ctl(N)	*(volatile uint32_t *) (__region_CS1 + 0x08 + (0x08*(N)))
+#define __reg_MB86943_ecs_range(N)	*(volatile uint32_t *) (__region_CS1 + 0x20 + (0x10*(N)))
+#define __reg_MB86943_ecs_base(N)	*(volatile uint32_t *) (__region_CS1 + 0x28 + (0x10*(N)))
+
+#define __reg_MB86943_sl_pci_io_range	*(volatile uint32_t *) (__region_CS1 + 0x50)
+#define __reg_MB86943_sl_pci_io_base	*(volatile uint32_t *) (__region_CS1 + 0x58)
+#define __reg_MB86943_sl_pci_mem_range	*(volatile uint32_t *) (__region_CS1 + 0x60)
+#define __reg_MB86943_sl_pci_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x68)
+#define __reg_MB86943_pci_sl_io_base	*(volatile uint32_t *) (__region_CS1 + 0x70)
+#define __reg_MB86943_pci_sl_mem_base	*(volatile uint32_t *) (__region_CS1 + 0x78)
+
+#define __reg_MB86943_pci_arbiter	*(volatile uint32_t *) (__region_CS2 + 0x01300014)
+#define MB86943_PCIARB_EN		0x00000001
+
+#endif /* _ASM_MB86943A_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93091-fpga-irqs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93091-fpga-irqs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93091-fpga-irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93091-fpga-irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/* mb93091-fpga-irqs.h: MB93091 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93091_FPGA_IRQS_H
+#define _ASM_MB93091_FPGA_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA__UNUSED			= IRQ_BASE_FPGA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_1,
+	IRQ_FPGA_SL_BUS_EXPANSION_2,
+	IRQ_FPGA_PCI_INTD,
+	IRQ_FPGA_PCI_INTC,
+	IRQ_FPGA_PCI_INTB,
+	IRQ_FPGA_PCI_INTA,
+	IRQ_FPGA_SL_BUS_EXPANSION_7,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_8,
+	IRQ_FPGA_SL_BUS_EXPANSION_9,
+	IRQ_FPGA_MB86943_PCI_INTA,
+	IRQ_FPGA_MB86943_SLBUS_SIDE,
+	IRQ_FPGA_RTL8029_INTA,
+	IRQ_FPGA_SYSINT_BUS_EXPANSION_13,
+	IRQ_FPGA_SL_BUS_EXPANSION_14,
+	IRQ_FPGA_NMI,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93091_FPGA_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93093-fpga-irqs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93093-fpga-irqs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93093-fpga-irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93093-fpga-irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93093_FPGA_IRQS_H
+#define _ASM_MB93093_FPGA_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_FPGA_PUSH_BUTTON_SW1_5		= IRQ_BASE_FPGA + 8,
+	IRQ_FPGA_ROCKER_C_SW8			= IRQ_BASE_FPGA + 9,
+	IRQ_FPGA_ROCKER_C_SW9			= IRQ_BASE_FPGA + 10,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93093_FPGA_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93493-irqs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93493-irqs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93493-irqs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93493-irqs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+/* mb93493-irqs.h: MB93493 companion chip IRQs
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_IRQS_H
+#define _ASM_MB93493_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+	IRQ_MB93493_VDC			= IRQ_BASE_MB93493 + 0,
+	IRQ_MB93493_VCC			= IRQ_BASE_MB93493 + 1,
+	IRQ_MB93493_AUDIO_OUT		= IRQ_BASE_MB93493 + 2,
+	IRQ_MB93493_I2C_0		= IRQ_BASE_MB93493 + 3,
+	IRQ_MB93493_I2C_1		= IRQ_BASE_MB93493 + 4,
+	IRQ_MB93493_USB			= IRQ_BASE_MB93493 + 5,
+	IRQ_MB93493_LOCAL_BUS		= IRQ_BASE_MB93493 + 7,
+	IRQ_MB93493_PCMCIA		= IRQ_BASE_MB93493 + 8,
+	IRQ_MB93493_GPIO		= IRQ_BASE_MB93493 + 9,
+	IRQ_MB93493_AUDIO_IN		= IRQ_BASE_MB93493 + 10,
+};
+
+/* IRQ multiplexor mappings */
+#define ROUTE_VIA_IRQ0	0	/* route IRQ by way of CPU external IRQ 0 */
+#define ROUTE_VIA_IRQ1	1	/* route IRQ by way of CPU external IRQ 1 */
+
+#define IRQ_MB93493_VDC_ROUTE		ROUTE_VIA_IRQ0
+#define IRQ_MB93493_VCC_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_OUT_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_0_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_1_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_USB_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_LOCAL_BUS_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_PCMCIA_ROUTE	ROUTE_VIA_IRQ1
+#define IRQ_MB93493_GPIO_ROUTE		ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_IN_ROUTE	ROUTE_VIA_IRQ1
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93493_IRQS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93493-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93493-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb93493-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb93493-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,281 @@
+/* mb93493-regs.h: MB93493 companion chip registers
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_REGS_H
+#define _ASM_MB93493_REGS_H
+
+#include <asm/mb-regs.h>
+#include <asm/mb93493-irqs.h>
+
+#define __addr_MB93493(X)	((volatile unsigned long *)(__region_CS3 + (X)))
+#define __get_MB93493(X)	({ *(volatile unsigned long *)(__region_CS3 + (X)); })
+
+#define __set_MB93493(X,V)						\
+do {									\
+	*(volatile unsigned long *)(__region_CS3 + (X)) = (V); mb();	\
+} while(0)
+
+#define __get_MB93493_STSR(X)	__get_MB93493(0x3c0 + (X) * 4)
+#define __set_MB93493_STSR(X,V)	__set_MB93493(0x3c0 + (X) * 4, (V))
+#define MB93493_STSR_EN
+
+#define __addr_MB93493_IQSR(X)	__addr_MB93493(0x3d0 + (X) * 4)
+#define __get_MB93493_IQSR(X)	__get_MB93493(0x3d0 + (X) * 4)
+#define __set_MB93493_IQSR(X,V)	__set_MB93493(0x3d0 + (X) * 4, (V))
+
+#define __get_MB93493_DQSR(X)	__get_MB93493(0x3e0 + (X) * 4)
+#define __set_MB93493_DQSR(X,V)	__set_MB93493(0x3e0 + (X) * 4, (V))
+
+#define __get_MB93493_LBSER()	__get_MB93493(0x3f0)
+#define __set_MB93493_LBSER(V)	__set_MB93493(0x3f0, (V))
+
+#define MB93493_LBSER_VDC	0x00010000
+#define MB93493_LBSER_VCC	0x00020000
+#define MB93493_LBSER_AUDIO	0x00040000
+#define MB93493_LBSER_I2C_0	0x00080000
+#define MB93493_LBSER_I2C_1	0x00100000
+#define MB93493_LBSER_USB	0x00200000
+#define MB93493_LBSER_GPIO	0x00800000
+#define MB93493_LBSER_PCMCIA	0x01000000
+
+#define __get_MB93493_LBSR()	__get_MB93493(0x3fc)
+#define __set_MB93493_LBSR(V)	__set_MB93493(0x3fc, (V))
+
+/*
+ * video display controller
+ */
+#define __get_MB93493_VDC(X)	__get_MB93493(MB93493_VDC_##X)
+#define __set_MB93493_VDC(X,V)	__set_MB93493(MB93493_VDC_##X, (V))
+
+#define MB93493_VDC_RCURSOR	0x140	/* cursor position */
+#define MB93493_VDC_RCT1	0x144	/* cursor colour 1 */
+#define MB93493_VDC_RCT2	0x148	/* cursor colour 2 */
+#define MB93493_VDC_RHDC	0x150	/* horizontal display period */
+#define MB93493_VDC_RH_MARGINS	0x154	/* horizontal margin sizes */
+#define MB93493_VDC_RVDC	0x158	/* vertical display period */
+#define MB93493_VDC_RV_MARGINS	0x15c	/* vertical margin sizes */
+#define MB93493_VDC_RC		0x170	/* VDC control */
+#define MB93493_VDC_RCLOCK	0x174	/* clock divider, DMA req delay */
+#define MB93493_VDC_RBLACK	0x178	/* black insert sizes */
+#define MB93493_VDC_RS		0x17c	/* VDC status */
+
+#define __addr_MB93493_VDC_BCI(X)  ({ (volatile unsigned long *)(__region_CS3 + 0x000 + (X)); })
+#define __addr_MB93493_VDC_TPO(X)  (__region_CS3 + 0x1c0 + (X))
+
+#define VDC_TPO_WIDTH		32
+
+#define VDC_RC_DSR		0x00000080	/* VDC master reset */
+
+#define VDC_RS_IT		0x00060000	/* interrupt indicators */
+#define VDC_RS_IT_UNDERFLOW	0x00040000	/* - underflow event */
+#define VDC_RS_IT_VSYNC		0x00020000	/* - VSYNC event */
+#define VDC_RS_DFI		0x00010000	/* current interlace field number */
+#define VDC_RS_DFI_TOP		0x00000000	/* - top field */
+#define VDC_RS_DFI_BOTTOM	0x00010000	/* - bottom field */
+#define VDC_RS_DCSR		0x00000010	/* cursor state */
+#define VDC_RS_DCM		0x00000003	/* display mode */
+#define VDC_RS_DCM_DISABLED	0x00000000	/* - display disabled */
+#define VDC_RS_DCM_STOPPED	0x00000001	/* - VDC stopped */
+#define VDC_RS_DCM_FREERUNNING	0x00000002	/* - VDC free-running */
+#define VDC_RS_DCM_TRANSFERRING	0x00000003	/* - data being transferred to VDC */
+
+/*
+ * video capture controller
+ */
+#define __get_MB93493_VCC(X)	__get_MB93493(MB93493_VCC_##X)
+#define __set_MB93493_VCC(X,V)	__set_MB93493(MB93493_VCC_##X, (V))
+
+#define MB93493_VCC_RREDUCT	0x104	/* reduction rate */
+#define MB93493_VCC_RHY		0x108	/* horizontal brightness filter coefficients */
+#define MB93493_VCC_RHC		0x10c	/* horizontal colour-difference filter coefficients */
+#define MB93493_VCC_RHSIZE	0x110	/* horizontal cycle sizes */
+#define MB93493_VCC_RHBC	0x114	/* horizontal back porch size */
+#define MB93493_VCC_RVCC	0x118	/* vertical capture period */
+#define MB93493_VCC_RVBC	0x11c	/* vertical back porch period */
+#define MB93493_VCC_RV		0x120	/* vertical filter coefficients */
+#define MB93493_VCC_RDTS	0x128	/* DMA transfer size */
+#define MB93493_VCC_RDTS_4B	0x01000000	/* 4-byte transfer */
+#define MB93493_VCC_RDTS_32B	0x03000000	/* 32-byte transfer */
+#define MB93493_VCC_RDTS_SHIFT	24
+#define MB93493_VCC_RCC		0x130	/* VCC control */
+#define MB93493_VCC_RIS		0x134	/* VCC interrupt status */
+
+#define __addr_MB93493_VCC_TPI(X)  (__region_CS3 + 0x180 + (X))
+
+#define VCC_RHSIZE_RHCC		0x000007ff
+#define VCC_RHSIZE_RHCC_SHIFT	0
+#define VCC_RHSIZE_RHTCC	0x0fff0000
+#define VCC_RHSIZE_RHTCC_SHIFT	16
+
+#define VCC_RVBC_RVBC		0x00003f00
+#define VCC_RVBC_RVBC_SHIFT	8
+
+#define VCC_RREDUCT_RHR		0x07ff0000
+#define VCC_RREDUCT_RHR_SHIFT	16
+#define VCC_RREDUCT_RVR		0x000007ff
+#define VCC_RREDUCT_RVR_SHIFT	0
+
+#define VCC_RCC_CE		0x00000001	/* VCC enable */
+#define VCC_RCC_CS		0x00000002	/* request video capture start */
+#define VCC_RCC_CPF		0x0000000c	/* pixel format */
+#define VCC_RCC_CPF_YCBCR_16	0x00000000	/* - YCbCr 4:2:2 16-bit format */
+#define VCC_RCC_CPF_RGB		0x00000004	/* - RGB 4:4:4 format */
+#define VCC_RCC_CPF_YCBCR_24	0x00000008	/* - YCbCr 4:2:2 24-bit format */
+#define VCC_RCC_CPF_BT656	0x0000000c	/* - ITU R-BT.656 format */
+#define VCC_RCC_CPF_SHIFT	2
+#define VCC_RCC_CSR		0x00000080	/* request reset */
+#define VCC_RCC_HSIP		0x00000100	/* HSYNC polarity */
+#define VCC_RCC_HSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_HSIP_HIACT	0x00000100	/* - high active */
+#define VCC_RCC_VSIP		0x00000200	/* VSYNC polarity */
+#define VCC_RCC_VSIP_LOACT	0x00000000	/* - low active */
+#define VCC_RCC_VSIP_HIACT	0x00000200	/* - high active */
+#define VCC_RCC_CIE		0x00000800	/* interrupt enable */
+#define VCC_RCC_CFP		0x00001000	/* RGB pixel packing */
+#define VCC_RCC_CFP_4TO3	0x00000000	/* - pack 4 pixels into 3 words */
+#define VCC_RCC_CFP_1TO1	0x00001000	/* - pack 1 pixel into 1 words */
+#define VCC_RCC_CSM		0x00006000	/* interlace specification */
+#define VCC_RCC_CSM_ONEPASS	0x00002000	/* - non-interlaced */
+#define VCC_RCC_CSM_INTERLACE	0x00004000	/* - interlaced */
+#define VCC_RCC_CSM_SHIFT	13
+#define VCC_RCC_ES		0x00008000	/* capture start polarity */
+#define VCC_RCC_ES_NEG		0x00000000	/* - negative edge */
+#define VCC_RCC_ES_POS		0x00008000	/* - positive edge */
+#define VCC_RCC_IFI		0x00080000	/* inferlace field evaluation reverse */
+#define VCC_RCC_FDTS		0x00300000	/* interlace field start */
+#define VCC_RCC_FDTS_3_8	0x00000000	/* - 3/8 of horizontal entire cycle */
+#define VCC_RCC_FDTS_1_4	0x00100000	/* - 1/4 of horizontal entire cycle */
+#define VCC_RCC_FDTS_7_16	0x00200000	/* - 7/16 of horizontal entire cycle */
+#define VCC_RCC_FDTS_SHIFT	20
+#define VCC_RCC_MOV		0x00400000	/* test bit - always set to 1 */
+#define VCC_RCC_STP		0x00800000	/* request video capture stop */
+#define VCC_RCC_TO		0x01000000	/* input during top-field only */
+
+#define VCC_RIS_VSYNC		0x01000000	/* VSYNC interrupt */
+#define VCC_RIS_OV		0x02000000	/* overflow interrupt */
+#define VCC_RIS_BOTTOM		0x08000000	/* interlace bottom field */
+#define VCC_RIS_STARTED		0x10000000	/* capture started */
+
+/*
+ * I2C
+ */
+#define MB93493_I2C_BSR 	0x340		/* bus status */
+#define MB93493_I2C_BCR		0x344		/* bus control */
+#define MB93493_I2C_CCR		0x348		/* clock control */
+#define MB93493_I2C_ADR		0x34c		/* address */
+#define MB93493_I2C_DTR		0x350		/* data */
+#define MB93493_I2C_BC2R	0x35c		/* bus control 2 */
+
+#define __addr_MB93493_I2C(port,X)   (__region_CS3 + MB93493_I2C_##X + ((port)*0x20))
+#define __get_MB93493_I2C(port,X)    __get_MB93493(MB93493_I2C_##X + ((port)*0x20))
+#define __set_MB93493_I2C(port,X,V)  __set_MB93493(MB93493_I2C_##X + ((port)*0x20), (V))
+
+#define I2C_BSR_BB	(1 << 7)
+
+/*
+ * audio controller (I2S) registers
+ */
+#define __get_MB93493_I2S(X)	__get_MB93493(MB93493_I2S_##X)
+#define __set_MB93493_I2S(X,V)	__set_MB93493(MB93493_I2S_##X, (V))
+
+#define MB93493_I2S_ALDR	0x300		/* L-channel data */
+#define MB93493_I2S_ARDR	0x304		/* R-channel data */
+#define MB93493_I2S_APDR	0x308		/* 16-bit packed data */
+#define MB93493_I2S_AISTR	0x310		/* status */
+#define MB93493_I2S_AICR	0x314		/* control */
+
+#define __addr_MB93493_I2S_ALDR(X)	(__region_CS3 + MB93493_I2S_ALDR + (X))
+#define __addr_MB93493_I2S_ARDR(X)	(__region_CS3 + MB93493_I2S_ARDR + (X))
+#define __addr_MB93493_I2S_APDR(X)	(__region_CS3 + MB93493_I2S_APDR + (X))
+#define __addr_MB93493_I2S_ADR(X)	(__region_CS3 + 0x320 + (X))
+
+#define I2S_AISTR_OTST		0x00000003	/* status of output data transfer */
+#define I2S_AISTR_OTR		0x00000010	/* output transfer request pending */
+#define I2S_AISTR_OUR		0x00000020	/* output FIFO underrun detected */
+#define I2S_AISTR_OOR		0x00000040	/* output FIFO overrun detected */
+#define I2S_AISTR_ODS		0x00000100	/* output DMA transfer size */
+#define I2S_AISTR_ODE		0x00000400	/* output DMA transfer request enable */
+#define I2S_AISTR_OTRIE		0x00001000	/* output transfer request interrupt enable */
+#define I2S_AISTR_OURIE		0x00002000	/* output FIFO underrun interrupt enable */
+#define I2S_AISTR_OORIE		0x00004000	/* output FIFO overrun interrupt enable */
+#define I2S_AISTR__OUT_MASK	0x00007570
+#define I2S_AISTR_ITST		0x00030000	/* status of input data transfer */
+#define I2S_AISTR_ITST_SHIFT	16
+#define I2S_AISTR_ITR		0x00100000	/* input transfer request pending */
+#define I2S_AISTR_IUR		0x00200000	/* input FIFO underrun detected */
+#define I2S_AISTR_IOR		0x00400000	/* input FIFO overrun detected */
+#define I2S_AISTR_IDS		0x01000000	/* input DMA transfer size */
+#define I2S_AISTR_IDE		0x04000000	/* input DMA transfer request enable */
+#define I2S_AISTR_ITRIE		0x10000000	/* input transfer request interrupt enable */
+#define I2S_AISTR_IURIE		0x20000000	/* input FIFO underrun interrupt enable */
+#define I2S_AISTR_IORIE		0x40000000	/* input FIFO overrun interrupt enable */
+#define I2S_AISTR__IN_MASK	0x75700000
+
+#define I2S_AICR_MI		0x00000001	/* mono input requested */
+#define I2S_AICR_AMI		0x00000002	/* relation between LRCKI/FS1 and SDI */
+#define I2S_AICR_LRI		0x00000004	/* function of LRCKI pin */
+#define I2S_AICR_SDMI		0x00000070	/* format of input audio data */
+#define I2S_AICR_SDMI_SHIFT	4
+#define I2S_AICR_CLI		0x00000080	/* input FIFO clearing control */
+#define I2S_AICR_IM		0x00000300	/* input state control */
+#define I2S_AICR_IM_SHIFT	8
+#define I2S_AICR__IN_MASK	0x000003f7
+#define I2S_AICR_MO		0x00001000	/* mono output requested */
+#define I2S_AICR_AMO		0x00002000	/* relation between LRCKO/FS0 and SDO */
+#define I2S_AICR_AMO_SHIFT	13
+#define I2S_AICR_LRO		0x00004000	/* function of LRCKO pin */
+#define I2S_AICR_SDMO		0x00070000	/* format of output audio data */
+#define I2S_AICR_SDMO_SHIFT	16
+#define I2S_AICR_CLO		0x00080000	/* output FIFO clearing control */
+#define I2S_AICR_OM		0x00100000	/* output state control */
+#define I2S_AICR__OUT_MASK	0x001f7000
+#define I2S_AICR_DIV		0x03000000	/* frequency division rate */
+#define I2S_AICR_DIV_SHIFT	24
+#define I2S_AICR_FL		0x20000000	/* frame length */
+#define I2S_AICR_FS		0x40000000	/* frame sync method */
+#define I2S_AICR_ME		0x80000000	/* master enable */
+
+/*
+ * PCMCIA
+ */
+#define __addr_MB93493_PCMCIA(X)  ((volatile unsigned long *)(__region_CS5 + (X)))
+
+/*
+ * GPIO
+ */
+#define __get_MB93493_GPIO_PDR(X)	__get_MB93493(0x380 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDR(X,V)	__set_MB93493(0x380 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_GPDR(X)	__get_MB93493(0x384 + (X) * 0xc0)
+#define __set_MB93493_GPIO_GPDR(X,V)	__set_MB93493(0x384 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SIR(X)	__get_MB93493(0x388 + (X) * 0xc0)
+#define __set_MB93493_GPIO_SIR(X,V)	__set_MB93493(0x388 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SOR(X)	__get_MB93493(0x38c + (X) * 0xc0)
+#define __set_MB93493_GPIO_SOR(X,V)	__set_MB93493(0x38c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDSR(X)	__get_MB93493(0x390 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDSR(X,V)	__set_MB93493(0x390 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDCR(X)	__get_MB93493(0x394 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDCR(X,V)	__set_MB93493(0x394 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_INTST(X)	__get_MB93493(0x398 + (X) * 0xc0)
+#define __set_MB93493_GPIO_INTST(X,V)	__set_MB93493(0x398 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IEHL(X)	__get_MB93493(0x39c + (X) * 0xc0)
+#define __set_MB93493_GPIO_IEHL(X,V)	__set_MB93493(0x39c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IELH(X)	__get_MB93493(0x3a0 + (X) * 0xc0)
+#define __set_MB93493_GPIO_IELH(X,V)	__set_MB93493(0x3a0 + (X) * 0xc0, (V))
+
+#endif /* _ASM_MB93493_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mb-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mb-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,200 @@
+/* mb-regs.h: motherboard registers
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB_REGS_H
+#define _ASM_MB_REGS_H
+
+#include <asm/cpu-irqs.h>
+#include <asm/sections.h>
+#include <asm/mem-layout.h>
+
+#ifndef __ASSEMBLY__
+/* gcc builtins, annotated */
+
+unsigned long __builtin_read8(volatile void __iomem *);
+unsigned long __builtin_read16(volatile void __iomem *);
+unsigned long __builtin_read32(volatile void __iomem *);
+void __builtin_write8(volatile void __iomem *, unsigned char);
+void __builtin_write16(volatile void __iomem *, unsigned short);
+void __builtin_write32(volatile void __iomem *, unsigned long);
+#endif
+
+#define __region_IO	KERNEL_IO_START	/* the region from 0xe0000000 to 0xffffffff has suitable
+					 * protection laid over the top for use in memory-mapped
+					 * I/O
+					 */
+
+#define __region_CS0	0xff000000	/* Boot ROMs area */
+
+#ifdef CONFIG_MB93091_VDK
+/*
+ * VDK motherboard and CPU card specific stuff
+ */
+
+#include <asm/mb93091-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS2	0xe0000000	/* SLBUS/PCI I/O space */
+#define __region_CS2_M		0x0fffffff /* mask */
+#define __region_CS2_C		0x00000000 /* control */
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff
+#define __region_CS5_C		0x00010000
+#define __region_CS7	0xf1000000	/* CB70 CPU-card PCMCIA port I/O space */
+#define __region_CS7_M		0x00ffffff
+#define __region_CS7_C		0x00410701
+#define __region_CS1	0xfc000000	/* SLBUS/PCI bridge control registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00000000
+#define __region_CS6	0xfc100000	/* CB70 CPU-card DM9000 LAN I/O space */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00400707
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8100000
+#define __region_CS4	0xfd000000	/* CB70 CPU-card extra flash space */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_PCI_IO		(__region_CS2 + 0x04000000UL)
+#define __region_PCI_MEM	(__region_CS2 + 0x08000000UL)
+#define __flush_PCI_writes()						\
+do {									\
+	__builtin_write8((volatile void __iomem *) __region_PCI_MEM, 0);	\
+} while(0)
+
+#define __is_PCI_IO(addr) \
+	(((unsigned long)(addr) >> 24) - (__region_PCI_IO >> 24)  < (0x04000000UL >> 24))
+
+#define __is_PCI_MEM(addr) \
+	((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
+
+#define __is_PCI_addr(addr) \
+	((unsigned long)(addr) - __region_PCI_IO < 0x0c000000UL)
+
+#define __get_CLKSW()	({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
+#define __get_CLKIN()	(__get_CLKSW() * 125U * 100000U / 24U)
+
+#ifndef __ASSEMBLY__
+extern int __nongprelbss mb93090_mb00_detected;
+#endif
+
+#define __addr_LEDS()		(__region_CS2 + 0x01200004UL)
+#ifdef CONFIG_MB93090_MB00
+#define __set_LEDS(X)							\
+do {									\
+	if (mb93090_mb00_detected)					\
+		__builtin_write32((void __iomem *) __addr_LEDS(), ~(X));	\
+} while (0)
+#else
+#define __set_LEDS(X)
+#endif
+
+#define __addr_LCD()		(__region_CS2 + 0x01200008UL)
+#define __get_LCD(B)		__builtin_read32((volatile void __iomem *) (B))
+#define __set_LCD(B,X)		__builtin_write32((volatile void __iomem *) (B), (X))
+
+#define LCD_D			0x000000ff		/* LCD data bus */
+#define LCD_RW			0x00000100		/* LCD R/W signal */
+#define LCD_RS			0x00000200		/* LCD Register Select */
+#define LCD_E			0x00000400		/* LCD Start Enable Signal */
+
+#define LCD_CMD_CLEAR		(LCD_E|0x001)
+#define LCD_CMD_HOME		(LCD_E|0x002)
+#define LCD_CMD_CURSOR_INC	(LCD_E|0x004)
+#define LCD_CMD_SCROLL_INC	(LCD_E|0x005)
+#define LCD_CMD_CURSOR_DEC	(LCD_E|0x006)
+#define LCD_CMD_SCROLL_DEC	(LCD_E|0x007)
+#define LCD_CMD_OFF		(LCD_E|0x008)
+#define LCD_CMD_ON(CRSR,BLINK)	(LCD_E|0x00c|(CRSR<<1)|BLINK)
+#define LCD_CMD_CURSOR_MOVE_L	(LCD_E|0x010)
+#define LCD_CMD_CURSOR_MOVE_R	(LCD_E|0x014)
+#define LCD_CMD_DISPLAY_SHIFT_L	(LCD_E|0x018)
+#define LCD_CMD_DISPLAY_SHIFT_R	(LCD_E|0x01c)
+#define LCD_CMD_FUNCSET(DL,N,F)	(LCD_E|0x020|(DL<<4)|(N<<3)|(F<<2))
+#define LCD_CMD_SET_CG_ADDR(X)	(LCD_E|0x040|X)
+#define LCD_CMD_SET_DD_ADDR(X)	(LCD_E|0x080|X)
+#define LCD_CMD_READ_BUSY	(LCD_E|LCD_RW)
+#define LCD_DATA_WRITE(X)	(LCD_E|LCD_RS|(X))
+#define LCD_DATA_READ		(LCD_E|LCD_RS|LCD_RW)
+
+#else
+/*
+ * PDK unit specific stuff
+ */
+
+#include <asm/mb93093-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0	IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1	IRQ_CPU_EXTERNAL1
+
+#define __region_CS5	0xf0000000	/* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M		0x00ffffff /* mask */
+#define __region_CS5_C		0x00010000 /* control */
+#define __region_CS2	0x20000000	/* FPGA registers */
+#define __region_CS2_M		0x000fffff
+#define __region_CS2_C		0x00000000
+#define __region_CS1	0xfc100000	/* LAN registers */
+#define __region_CS1_M		0x000fffff
+#define __region_CS1_C		0x00010404
+#define __region_CS3	0xfc200000	/* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M		0x000fffff
+#define __region_CS3_C		0xc8000000
+#define __region_CS4	0xfd000000	/* extra ROMs area */
+#define __region_CS4_M		0x00ffffff
+#define __region_CS4_C		0x00000f07
+
+#define __region_CS6	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS6_M		0x000fffff
+#define __region_CS6_C		0x00000f07
+#define __region_CS7	0xfe000000	/* not used - hide behind CPU resource I/O regs */
+#define __region_CS7_M		0x000fffff
+#define __region_CS7_C		0x00000f07
+
+#define __is_PCI_IO(addr)	0	/* no PCI */
+#define __is_PCI_MEM(addr)	0
+#define __is_PCI_addr(addr)	0
+#define __region_PCI_IO		0
+#define __region_PCI_MEM	0
+#define __flush_PCI_writes()	do { } while(0)
+
+#define __get_CLKSW()		0UL
+#define __get_CLKIN()		66000000UL
+
+#define __addr_LEDS()		(__region_CS2 + 0x00000023UL)
+#define __set_LEDS(X)		__builtin_write8((volatile void __iomem *) __addr_LEDS(), (X))
+
+#define __addr_FPGATR()		(__region_CS2 + 0x00000030UL)
+#define __set_FPGATR(X)		__builtin_write32((volatile void __iomem *) __addr_FPGATR(), (X))
+#define __get_FPGATR()		__builtin_read32((volatile void __iomem *) __addr_FPGATR())
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK	0x00000003
+
+#define __set_FPGATR_AUDIO_CLK(V) \
+	__set_FPGATR((__get_FPGATR() & ~MB93093_FPGA_FPGATR_AUDIO_CLK) | (V))
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_OFF	0x0
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_11MHz	0x1
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_12MHz	0x2
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_02MHz	0x3
+
+#define MB93093_FPGA_SWR_PUSHSWMASK	(0x1F<<26)
+#define MB93093_FPGA_SWR_PUSHSW4	(1<<29)
+
+#define __addr_FPGA_SWR		((volatile void __iomem *)(__region_CS2 + 0x28UL))
+#define __get_FPGA_PUSHSW1_5()	(__builtin_read32(__addr_FPGA_SWR) & MB93093_FPGA_SWR_PUSHSWMASK)
+
+
+#endif
+
+#endif /* _ASM_MB_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mc146818rtc.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mc146818rtc.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mc146818rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mc146818rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/* mc146818rtc.h: RTC defs
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#endif /* _ASM_MC146818RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mem-layout.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mem-layout.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mem-layout.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mem-layout.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/* mem-layout.h: memory layout
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MEM_LAYOUT_H
+#define _ASM_MEM_LAYOUT_H
+
+#ifndef __ASSEMBLY__
+#define __UL(X)	((unsigned long) (X))
+#else
+#define __UL(X)	(X)
+#endif
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT			14
+
+#ifndef __ASSEMBLY__
+#define PAGE_SIZE			(1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE			(1 << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK			(~(PAGE_SIZE-1))
+
+/*
+ * the slab must be aligned such that load- and store-double instructions don't
+ * fault if used
+ */
+#define	ARCH_KMALLOC_MINALIGN		8
+#define	ARCH_SLAB_MINALIGN		8
+
+/*****************************************************************************/
+/*
+ * virtual memory layout from kernel's point of view
+ */
+#define PAGE_OFFSET			((unsigned long) &__page_offset)
+
+#ifdef CONFIG_MMU
+
+/* see Documentation/frv/mmu-layout.txt */
+#define KERNEL_LOWMEM_START		__UL(0xc0000000)
+#define KERNEL_LOWMEM_END		__UL(0xd0000000)
+#define VMALLOC_START			__UL(0xd0000000)
+#define VMALLOC_END			__UL(0xd8000000)
+#define PKMAP_BASE			__UL(0xd8000000)
+#define PKMAP_END			__UL(0xdc000000)
+#define KMAP_ATOMIC_SECONDARY_FRAME	__UL(0xdc000000)
+#define KMAP_ATOMIC_PRIMARY_FRAME	__UL(0xdd000000)
+
+#endif
+
+#define KERNEL_IO_START			__UL(0xe0000000)
+
+
+/*****************************************************************************/
+/*
+ * memory layout from userspace's point of view
+ */
+#define BRK_BASE			__UL(2 * 1024 * 1024 + PAGE_SIZE)
+#define STACK_TOP			__UL(2 * 1024 * 1024)
+#define STACK_TOP_MAX			__UL(0xc0000000)
+
+/* userspace process size */
+#ifdef CONFIG_MMU
+#define TASK_SIZE			(PAGE_OFFSET)
+#else
+#define TASK_SIZE			__UL(0xFFFFFFFFUL)
+#endif
+
+/* base of area at which unspecified mmaps will start */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+#define TASK_UNMAPPED_BASE		__UL(16 * 1024 * 1024)
+#else
+#define TASK_UNMAPPED_BASE		__UL(TASK_SIZE / 3)
+#endif
+
+#endif /* _ASM_MEM_LAYOUT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mman.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mman.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mman.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mman.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#endif /* __ASM_MMAN_H__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mmu_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+/* mmu_context.h: MMU context management routines
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd);
+extern void destroy_context(struct mm_struct *mm);
+
+#else
+#define init_new_context(tsk, mm)		({ 0; })
+#define change_mm_context(old, ctx, _pml4)	do {} while(0)
+#define destroy_context(mm)			do {} while(0)
+#endif
+
+#define switch_mm(prev, next, tsk)						\
+do {										\
+	if (prev != next)							\
+		change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#define activate_mm(prev, next)						\
+do {									\
+	change_mm_context(&prev->context, &next->context, next->pgd);	\
+} while(0)
+
+#define deactivate_mm(tsk, mm)			\
+do {						\
+} while(0)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/* mmu.h: memory management context for FR-V with or without MMU support
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+typedef struct {
+#ifdef CONFIG_MMU
+	struct list_head id_link;		/* link in list of context ID owners */
+	unsigned short	id;			/* MMU context ID */
+	unsigned short	id_busy;		/* true if ID is in CXNR */
+	unsigned long	itlb_cached_pge;	/* [SCR0] PGE cached for insn TLB handler */
+	unsigned long	itlb_ptd_mapping;	/* [DAMR4] PTD mapping for itlb cached PGE */
+	unsigned long	dtlb_cached_pge;	/* [SCR1] PGE cached for data TLB handler */
+	unsigned long	dtlb_ptd_mapping;	/* [DAMR5] PTD mapping for dtlb cached PGE */
+
+#else
+	unsigned long		end_brk;
+
+#endif
+
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+	unsigned long	exec_fdpic_loadmap;
+	unsigned long	interp_fdpic_loadmap;
+#endif
+
+} mm_context_t;
+
+#ifdef CONFIG_MMU
+extern int __nongpreldata cxn_pinned;
+extern int cxn_pin_by_pid(pid_t pid);
+#endif
+
+#endif /* _ASM_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/module.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/module.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+/* module.h: FRV module stuff
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+struct mod_arch_specific
+{
+};
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+
+/*
+ * Include the architecture version.
+ */
+#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
+
+#endif /* _ASM_MODULE_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/msgbuf.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/msgbuf.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/msgbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/msgbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,32 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm	msg_perm;
+	__kernel_time_t		msg_stime;	/* last msgsnd time */
+	unsigned long		__unused1;
+	__kernel_time_t		msg_rtime;	/* last msgrcv time */
+	unsigned long		__unused2;
+	__kernel_time_t		msg_ctime;	/* last change time */
+	unsigned long		__unused3;
+	unsigned long		msg_cbytes;	/* current number of bytes on queue */
+	unsigned long		msg_qnum;	/* number of messages in queue */
+	unsigned long		msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t		msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t		msg_lrpid;	/* last receive pid */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+#endif /* _ASM_MSGBUF_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/mutex.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/mutex.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/mutex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/mutex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/page.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/page.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,78 @@
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#include <asm/virtconvert.h>
+#include <asm/mem-layout.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr)			__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)		free_page(addr)
+
+#define clear_page(pgaddr)			memset((pgaddr), 0, PAGE_SIZE)
+#define copy_page(to,from)			memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(pgaddr, vaddr, page)	memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg)	memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long	pte;	} pte_t;
+typedef struct { unsigned long	ste[64];} pmd_t;
+typedef struct { pmd_t		pue[1]; } pud_t;
+typedef struct { pud_t		pge[1];	} pgd_t;
+typedef struct { unsigned long	pgprot;	} pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).ste[0])
+#define pud_val(x)	((x).pue[0])
+#define pgd_val(x)	((x).pge[0])
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pud(x)	((pud_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+#define PTE_MASK	PAGE_MASK
+
+#define devmem_is_allowed(pfn)	1
+
+#define __pa(vaddr)		virt_to_phys((void *) (unsigned long) (vaddr))
+#define __va(paddr)		phys_to_virt((unsigned long) (paddr))
+
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#ifdef CONFIG_MMU
+#define pfn_valid(pfn)		((pfn) < max_mapnr)
+#else
+#define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
+#define pfn_valid(pfn)		((pfn) >= min_low_pfn && (pfn) < max_low_pfn)
+
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#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__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_PAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/param.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/param.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/param.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+#ifndef _ASM_PARAM_H
+#define _ASM_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	16384
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN		64	/* max length of hostname */
+
+#endif /* _ASM_PARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,118 @@
+/* pci.h: FR-V specific PCI declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68k/pci.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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_PCI_H
+#define	ASM_PCI_H
+
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci.h>
+
+struct pci_dev;
+
+#define pcibios_assign_all_busses()	0
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+extern void pcibios_penalize_isa_irq(int irq);
+
+#ifdef CONFIG_MMU
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
+extern void consistent_free(void *vaddr);
+extern void consistent_sync(void *vaddr, size_t size, int direction);
+extern void consistent_sync_page(struct page *page, unsigned long offset,
+				 size_t size, int direction);
+#endif
+
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				  dma_addr_t *dma_handle);
+
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+				void *vaddr, dma_addr_t dma_handle);
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV)	(0)
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
+/*
+ *	These are pretty much arbitary with the CoMEM implementation.
+ *	We have the whole address space to ourselves.
+ */
+#define PCIBIOS_MIN_IO		0x100
+#define PCIBIOS_MIN_MEM		0x00010000
+
+/* 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();
+
+	frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle),
+			    (unsigned long)bus_to_virt(dma_handle) + size);
+}
+
+/* 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)
+{
+	int i;
+
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+	for (i = 0; i < nelems; i++)
+		frv_cache_wback_inv(sg_dma_address(&sg[i]),
+				    sg_dma_address(&sg[i])+sg_dma_len(&sg[i]));
+}
+
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/percpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __ASM_PERCPU_H
+#define __ASM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif	/* __ASM_PERCPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/pgalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/* pgalloc.h: Page allocation routines for FRV
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgalloc.h
+ *	include/asm-i386/pgalloc.h
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+#ifdef CONFIG_MMU
+
+#define pmd_populate_kernel(mm, pmd, pte) __set_pmd(pmd, __pa(pte) | _PAGE_TABLE)
+#define pmd_populate(MM, PMD, PAGE)						\
+do {										\
+	__set_pmd((PMD), page_to_pfn(PAGE) << PAGE_SHIFT | _PAGE_TABLE);	\
+} while(0)
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Allocate and free page tables.
+ */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *);
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+
+extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+	pgtable_page_dtor(pte);
+	__free_page(pte);
+}
+
+#define __pte_free_tlb(tlb,pte)				\
+do {							\
+	pgtable_page_dtor(pte);				\
+	tlb_remove_page((tlb),(pte));			\
+} while (0)
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *) 2); })
+#define pmd_free(mm, x)			do { } while (0)
+#define __pmd_free_tlb(tlb,x)		do { } while (0)
+
+#endif /* CONFIG_MMU */
+
+#endif /* _ASM_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/pgtable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,549 @@
+/* pgtable.h: FR-V page table mangling
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ *	include/asm-m68knommu/pgtable.h
+ *	include/asm-i386/pgtable.h
+ */
+
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <asm/mem-layout.h>
+#include <asm/setup.h>
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+struct vm_area_struct;
+#endif
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_HIGHPTE)
+typedef unsigned long pte_addr_t;
+#else
+typedef pte_t *pte_addr_t;
+#endif
+#endif
+
+/*****************************************************************************/
+/*
+ * MMU-less operation case first
+ */
+#ifndef CONFIG_MMU
+
+#define pgd_present(pgd)	(1)		/* pages are always present on NO_MM */
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr)	(1)
+#define	pmd_offset(a, b)	((void *) 0)
+
+#define PAGE_NONE		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_SHARED		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_COPY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_READONLY		__pgprot(0)	/* these mean nothing to NO_MM */
+#define PAGE_KERNEL		__pgprot(0)	/* these mean nothing to NO_MM */
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ,off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif
+
+#define ZERO_PAGE(vaddr)	({ BUG(); NULL; })
+
+#define swapper_pg_dir		((pgd_t *) NULL)
+
+#define pgtable_cache_init()		do {} while (0)
+
+#include <asm-generic/pgtable.h>
+
+#else /* !CONFIG_MMU */
+/*****************************************************************************/
+/*
+ * then MMU operation
+ */
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long empty_zero_page;
+#define ZERO_PAGE(vaddr)	virt_to_page(empty_zero_page)
+#endif
+
+/*
+ * we use 2-level page tables, folding the PMD (mid-level table) into the PGE (top-level entry)
+ * [see Documentation/frv/mmu-layout.txt]
+ *
+ * Page Directory:
+ *  - Size: 16KB
+ *  - 64 PGEs per PGD
+ *  - Each PGE holds 1 PUD and covers 64MB
+ *
+ * Page Upper Directory:
+ *  - Size: 256B
+ *  - 1 PUE per PUD
+ *  - Each PUE holds 1 PMD and covers 64MB
+ *
+ * Page Mid-Level Directory
+ *  - Size: 256B
+ *  - 1 PME per PMD
+ *  - Each PME holds 64 STEs, all of which point to separate chunks of the same Page Table
+ *  - All STEs are instantiated at the same time
+ *
+ * Page Table
+ *  - Size: 16KB
+ *  - 4096 PTEs per PT
+ *  - Each Linux PT is subdivided into 64 FR451 PT's, each of which holds 64 entries
+ *
+ * Pages
+ *  - Size: 4KB
+ *
+ * total PTEs
+ *	= 1 PML4E * 64 PGEs * 1 PUEs * 1 PMEs * 4096 PTEs
+ *	= 1 PML4E * 64 PGEs * 64 STEs * 64 PTEs/FR451-PT
+ *	= 262144 (or 256 * 1024)
+ */
+#define PGDIR_SHIFT		26
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE - 1))
+#define PTRS_PER_PGD		64
+
+#define PUD_SHIFT		26
+#define PTRS_PER_PUD		1
+#define PUD_SIZE		(1UL << PUD_SHIFT)
+#define PUD_MASK		(~(PUD_SIZE - 1))
+#define PUE_SIZE		256
+
+#define PMD_SHIFT		26
+#define PMD_SIZE		(1UL << PMD_SHIFT)
+#define PMD_MASK		(~(PMD_SIZE - 1))
+#define PTRS_PER_PMD		1
+#define PME_SIZE		256
+
+#define __frv_PT_SIZE		256
+
+#define PTRS_PER_PTE		4096
+
+#define USER_PGDS_IN_LAST_PML4	(TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS	0
+
+#define USER_PGD_PTRS		(PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS		(PTRS_PER_PGD - USER_PGD_PTRS)
+
+#define TWOLEVEL_PGDIR_SHIFT	26
+#define BOOT_USER_PGD_PTRS	(__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_KERNEL_PGD_PTRS	(PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
+
+#ifndef __ASSEMBLY__
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pud_ERROR(e) \
+	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e)))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval)				\
+do {							\
+	*(pteptr) = (pteval);				\
+	asm volatile("dcf %M0" :: "U"(*pteptr));	\
+} while(0)
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pud is never bad, and a pud always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t *pgd)	{ }
+
+#define pgd_populate(mm, pgd, pud)		do { } while (0)
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pgd(pgdptr, pgdval)				\
+do {							\
+	memcpy((pgdptr), &(pgdval), sizeof(pgd_t));	\
+	asm volatile("dcf %M0" :: "U"(*(pgdptr)));	\
+} while(0)
+
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+{
+	return (pud_t *) pgd;
+}
+
+#define pgd_page(pgd)				(pud_page((pud_t){ pgd }))
+#define pgd_page_vaddr(pgd)			(pud_page_vaddr((pud_t){ pgd }))
+
+/*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+#define pud_alloc_one(mm, address)		NULL
+#define pud_free(mm, x)				do { } while (0)
+#define __pud_free_tlb(tlb, x)			do { } while (0)
+
+/*
+ * The "pud_xxx()" functions here are trivial for a folded two-level
+ * setup: the pmd is never bad, and a pmd always exists (as it's folded
+ * into the pud entry)
+ */
+static inline int pud_none(pud_t pud)		{ return 0; }
+static inline int pud_bad(pud_t pud)		{ return 0; }
+static inline int pud_present(pud_t pud)	{ return 1; }
+static inline void pud_clear(pud_t *pud)	{ }
+
+#define pud_populate(mm, pmd, pte)		do { } while (0)
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval)			set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
+
+#define pud_page(pud)				(pmd_page((pmd_t){ pud }))
+#define pud_page_vaddr(pud)			(pmd_page_vaddr((pmd_t){ pud }))
+
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
+
+#define set_pmd(pmdptr, pmdval)			\
+do {						\
+	__set_pmd((pmdptr), (pmdval).ste[0]);	\
+} while(0)
+
+#define __pmd_index(address)			0
+
+static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
+{
+	return (pmd_t *) dir + __pmd_index(address);
+}
+
+#define pte_same(a, b)		((a).pte == (b).pte)
+#define pte_page(x)		(mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
+#define pte_none(x)		(!(x).pte)
+#define pte_pfn(x)		((unsigned long)(((x).pte >> PAGE_SHIFT)))
+#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define VMALLOC_VMADDR(x)	((unsigned long) (x))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * control flags in AMPR registers and TLB entries
+ */
+#define _PAGE_BIT_PRESENT	xAMPRx_V_BIT
+#define _PAGE_BIT_WP		DAMPRx_WP_BIT
+#define _PAGE_BIT_NOCACHE	xAMPRx_C_BIT
+#define _PAGE_BIT_SUPER		xAMPRx_S_BIT
+#define _PAGE_BIT_ACCESSED	xAMPRx_RESERVED8_BIT
+#define _PAGE_BIT_DIRTY		xAMPRx_M_BIT
+#define _PAGE_BIT_NOTGLOBAL	xAMPRx_NG_BIT
+
+#define _PAGE_PRESENT		xAMPRx_V
+#define _PAGE_WP		DAMPRx_WP
+#define _PAGE_NOCACHE		xAMPRx_C
+#define _PAGE_SUPER		xAMPRx_S
+#define _PAGE_ACCESSED		xAMPRx_RESERVED8	/* accessed if set */
+#define _PAGE_DIRTY		xAMPRx_M
+#define _PAGE_NOTGLOBAL		xAMPRx_NG
+
+#define _PAGE_RESERVED_MASK	(xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
+
+#define _PAGE_FILE		0x002	/* set:pagecache unset:swap */
+#define _PAGE_PROTNONE		0x000	/* If not present */
+
+#define _PAGE_CHG_MASK		(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define __PGPROT_BASE \
+	(_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
+
+#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(__PGPROT_BASE)
+#define PAGE_COPY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+#define PAGE_READONLY	__pgprot(__PGPROT_BASE | _PAGE_WP)
+
+#define __PAGE_KERNEL		(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
+#define __PAGE_KERNEL_NOCACHE	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
+#define __PAGE_KERNEL_RO	(__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
+
+#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
+
+#define PAGE_KERNEL		MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO		MAKE_GLOBAL(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+
+#define _PAGE_TABLE		(_PAGE_PRESENT | xAMPRx_SS_16Kb)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The FR451 can do execute protection by virtue of having separate TLB miss handlers for
+ * instruction access and for data access. However, we don't have enough reserved bits to say
+ * "execute only", so we don't bother. If you can read it, you can execute it and vice versa.
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+/*
+ * Define this to warn about kernel memory accesses that are
+ * done without a 'access_ok(VERIFY_WRITE,..)'
+ */
+#undef TEST_ACCESS_OK
+
+#define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define	pmd_bad(x)	(pmd_val(x) & xAMPRx_SS)
+#define pmd_clear(xp)	do { __set_pmd(xp, 0); } while(0)
+
+#define pmd_page_vaddr(pmd) \
+	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pmd_page(pmd)	(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+#endif
+
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_dirty(pte_t pte)		{ return (pte).pte & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)		{ return (pte).pte & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)		{ return !((pte).pte & _PAGE_WP); }
+static inline int pte_special(pte_t pte)	{ return 0; }
+
+static inline pte_t pte_mkclean(pte_t pte)	{ (pte).pte &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ (pte).pte &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)	{ (pte).pte |= _PAGE_WP; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ (pte).pte |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ (pte).pte |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)	{ (pte).pte &= ~_PAGE_WP; return pte; }
+static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
+
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+{
+	int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return i;
+}
+
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	unsigned long x = xchg(&ptep->pte, 0);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+	return __pte(x);
+}
+
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_WP, ptep);
+	asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+/*
+ * Macro to mark a page protection value as "uncacheable"
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+#define mk_pte_huge(entry)	((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
+
+/* This takes a physical page address that is used by the remapping functions */
+#define mk_pte_phys(physpage, pgprot)	pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte &= _PAGE_CHG_MASK;
+	pte.pte |= pgprot_val(newprot);
+	return pte;
+}
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_index_k(addr) pgd_index(addr)
+
+/* Find an entry in the bottom-level page table.. */
+#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define pte_index(address) \
+		(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address) \
+	((pte_t *) pmd_page_vaddr(*(dir)) +  pte_index(address))
+
+#if defined(CONFIG_HIGHPTE)
+#define pte_offset_map(dir, address) \
+	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
+#define pte_offset_map_nested(dir, address) \
+	((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address))
+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
+#else
+#define pte_offset_map(dir, address) \
+	((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address))
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+#endif
+
+/*
+ * Handle swap and file entries
+ * - the PTE is encoded in the following format:
+ *	bit 0:		Must be 0 (!_PAGE_PRESENT)
+ *	bit 1:		Type: 0 for swap, 1 for file (_PAGE_FILE)
+ *	bits 2-7:	Swap type
+ *	bits 8-31:	Swap offset
+ *	bits 2-31:	File pgoff
+ */
+#define __swp_type(x)			(((x).val >> 2) & 0x1f)
+#define __swp_offset(x)			((x).val >> 8)
+#define __swp_entry(type, offset)	((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
+#define __pte_to_swp_entry(_pte)	((swp_entry_t) { (_pte).pte })
+#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+static inline int pte_file(pte_t pte)
+{
+	return pte.pte & _PAGE_FILE;
+}
+
+#define PTE_FILE_MAX_BITS	29
+
+#define pte_to_pgoff(PTE)	((PTE).pte >> 2)
+#define pgoff_to_pte(off)	__pte((off) << 2 | _PAGE_FILE)
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+		remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTE_SAME
+#include <asm-generic/pgtable.h>
+
+/*
+ * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	struct mm_struct *mm;
+	unsigned long ampr;
+
+	mm = current->mm;
+	if (mm) {
+		pgd_t *pge = pgd_offset(mm, address);
+		pud_t *pue = pud_offset(pge, address);
+		pmd_t *pme = pmd_offset(pue, address);
+
+		ampr = pme->ste[0] & 0xffffff00;
+		ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C |
+			xAMPRx_V;
+	} else {
+		address = ULONG_MAX;
+		ampr = 0;
+	}
+
+	asm volatile("movgs %0,scr0\n"
+		     "movgs %0,scr1\n"
+		     "movgs %1,dampr4\n"
+		     "movgs %1,dampr5\n"
+		     :
+		     : "r"(address), "r"(ampr)
+		     );
+}
+
+#ifdef CONFIG_PROC_FS
+extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
+#endif
+
+extern void __init pgtable_cache_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+extern void __init paging_init(void);
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/poll.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/poll.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/poll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/poll.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLWRNORM	POLLOUT
+#define POLLWRBAND	256
+
+#include <asm-generic/poll.h>
+
+#undef POLLREMOVE
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/posix_types.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/posix_types.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/posix_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/posix_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) */
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/processor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,153 @@
+/* processor.h: FRV processor definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <asm/mem-layout.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <asm/sections.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/registers.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/cache.h>
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ */
+struct cpuinfo_frv {
+#ifdef CONFIG_MMU
+	unsigned long	*pgd_quick;
+	unsigned long	*pte_quick;
+	unsigned long	pgtable_cache_sz;
+#endif
+} __cacheline_aligned;
+
+extern struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+#define cpu_data		(&boot_cpu_data)
+#define current_cpu_data	boot_cpu_data
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define MCA_bus 0
+
+struct thread_struct {
+	struct pt_regs		*frame;		/* [GR28] exception frame ptr for this thread */
+	struct task_struct	*curr;		/* [GR29] current pointer for this thread */
+	unsigned long		sp;		/* [GR1 ] kernel stack pointer */
+	unsigned long		fp;		/* [GR2 ] kernel frame pointer */
+	unsigned long		lr;		/* link register */
+	unsigned long		pc;		/* program counter */
+	unsigned long		gr[12];		/* [GR16-GR27] */
+	unsigned long		sched_lr;	/* LR from schedule() */
+
+	union {
+		struct pt_regs		*frame0;	/* top (user) stack frame */
+		struct user_context	*user;		/* userspace context */
+	};
+} __attribute__((aligned(8)));
+
+extern struct pt_regs *__kernel_frame0_ptr;
+extern struct task_struct *__kernel_current_task;
+
+#endif
+
+#ifndef __ASSEMBLY__
+#define INIT_THREAD_FRAME0 \
+	((struct pt_regs *) \
+	(sizeof(init_stack) + (unsigned long) init_stack - sizeof(struct user_context)))
+
+#define INIT_THREAD {				\
+	NULL,					\
+	(struct task_struct *) init_stack,	\
+	0, 0, 0, 0,				\
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },	\
+	0,					\
+	{ INIT_THREAD_FRAME0 },			\
+}
+
+/*
+ * do necessary setup to start up a newly executed thread.
+ * - need to discard the frame stacked by init() invoking the execve syscall
+ */
+#define start_thread(_regs, _pc, _usp)			\
+do {							\
+	set_fs(USER_DS); /* reads from user space */	\
+	__frame = __kernel_frame0_ptr;			\
+	__frame->pc	= (_pc);			\
+	__frame->psr	&= ~PSR_S;			\
+	__frame->sp	= (_usp);			\
+} while(0)
+
+extern void prepare_to_copy(struct task_struct *tsk);
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+extern asmlinkage void save_user_regs(struct user_context *target);
+extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	((tsk)->thread.frame0->pc)
+#define	KSTK_ESP(tsk)	((tsk)->thread.frame0->sp)
+
+/* Allocation and freeing of basic task resources. */
+extern struct task_struct *alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *p);
+
+#define cpu_relax()    barrier()
+
+/* data cache prefetch */
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x)
+{
+	asm volatile("dcpl %0,gr0,#0" : : "r"(x));
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_PROCESSOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ptrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,83 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+#ifdef __KERNEL__
+#include <asm/irq_regs.h>
+
+#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
+#endif
+
+
+#define PT_PSR		0
+#define	PT_ISR		1
+#define PT_CCR		2
+#define PT_CCCR		3
+#define PT_LR		4
+#define PT_LCR		5
+#define PT_PC		6
+
+#define PT__STATUS	7	/* exception status */
+#define PT_SYSCALLNO	8	/* syscall number or -1 */
+#define PT_ORIG_GR8	9	/* saved GR8 for signal handling */
+#define PT_GNER0	10
+#define PT_GNER1	11
+#define PT_IACC0H	12
+#define PT_IACC0L	13
+
+#define PT_GR(j)	( 14 + (j))	/* GRj for 0<=j<=63 */
+#define PT_FR(j)	( 78 + (j))	/* FRj for 0<=j<=63 */
+#define PT_FNER(j)	(142 + (j))	/* FNERj for 0<=j<=1 */
+#define PT_MSR(j)	(144 + (j))	/* MSRj for 0<=j<=2 */
+#define PT_ACC(j)	(146 + (j))	/* ACCj for 0<=j<=7 */
+#define PT_ACCG(jklm)	(154 + (jklm))	/* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
+#define PT_FSR(j)	(156 + (j))	/* FSRj for 0<=j<=0 */
+#define PT__GPEND	78
+#define PT__END		157
+
+#define PT_TBR		PT_GR(0)
+#define PT_SP		PT_GR(1)
+#define PT_FP		PT_GR(2)
+#define PT_PREV_FRAME	PT_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define PT_CURR_TASK	PT_GR(29)	/* current task */
+
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+#define PTRACE_GETFPREGS	14
+#define PTRACE_SETFPREGS	15
+#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 */
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/*
+ * we dedicate GR28 to keeping a pointer to the current exception frame
+ * - gr28 is destroyed on entry to the kernel from userspace
+ */
+register struct pt_regs *__frame asm("gr28");
+
+#define user_mode(regs)			(!((regs)->psr & PSR_S))
+#define instruction_pointer(regs)	((regs)->pc)
+
+extern unsigned long user_stack(const struct pt_regs *);
+extern void show_regs(struct pt_regs *);
+#define profile_pc(regs) ((regs)->pc)
+#endif
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_PTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/registers.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/registers.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/registers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/registers.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,232 @@
+/* registers.h: register frame declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * notes:
+ *
+ * (1) that the members of all these structures are carefully aligned to permit
+ *     usage of STD/STDF instructions
+ *
+ * (2) if you change these structures, you must change the code in
+ *     arch/frvnommu/kernel/{break.S,entry.S,switch_to.S,gdb-stub.c}
+ *
+ *
+ * the kernel stack space block looks like this:
+ *
+ *	+0x2000	+----------------------
+ *		| union {
+ *		|	struct frv_frame0 {
+ *		|		struct user_context {
+ *		|			struct user_int_regs
+ *		|			struct user_fpmedia_regs
+ *		|		}
+ *		|		struct frv_debug_regs
+ *		|	}
+ *		|	struct pt_regs [user exception]
+ *		| }
+ *		+---------------------- <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|......................
+ *		| struct pt_regs [kernel exception]
+ *		|...................... <-- __kernel_frame0_ptr (maybe GR28)
+ *		|
+ *		| kernel stack
+ *		|
+ *		|...................... <-- stack pointer (GR1)
+ *		|
+ *		| unused stack space
+ *		|
+ *		+----------------------
+ *		| struct thread_info
+ *	+0x0000	+---------------------- <-- __current_thread_info (GR15);
+ *
+ * note that GR28 points to the current exception frame
+ */
+
+#ifndef _ASM_REGISTERS_H
+#define _ASM_REGISTERS_H
+
+#ifndef __ASSEMBLY__
+#define __OFFSET(X,N)	((X)+(N)*4)
+#define __OFFSETC(X,N)	xxxxxxxxxxxxxxxxxxxxxxxx
+#else
+#define __OFFSET(X,N)	((X)+(N)*4)
+#define __OFFSETC(X,N)	((X)+(N))
+#endif
+
+/*****************************************************************************/
+/*
+ * Exception/Interrupt frame
+ * - held on kernel stack
+ * - 8-byte aligned on stack (old SP is saved in frame)
+ * - GR0 is fixed 0, so we don't save it
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner0;
+	unsigned long		gner1;
+	unsigned long long	iacc0;
+	unsigned long		tbr;		/* GR0 is fixed zero, so we use this for TBR */
+	unsigned long		sp;		/* GR1: USP/KSP */
+	unsigned long		fp;		/* GR2: FP */
+	unsigned long		gr3;
+	unsigned long		gr4;
+	unsigned long		gr5;
+	unsigned long		gr6;
+	unsigned long		gr7;		/* syscall number */
+	unsigned long		gr8;		/* 1st syscall param; syscall return */
+	unsigned long		gr9;		/* 2nd syscall param */
+	unsigned long		gr10;		/* 3rd syscall param */
+	unsigned long		gr11;		/* 4th syscall param */
+	unsigned long		gr12;		/* 5th syscall param */
+	unsigned long		gr13;		/* 6th syscall param */
+	unsigned long		gr14;
+	unsigned long		gr15;
+	unsigned long		gr16;		/* GP pointer */
+	unsigned long		gr17;		/* small data */
+	unsigned long		gr18;		/* PIC/PID */
+	unsigned long		gr19;
+	unsigned long		gr20;
+	unsigned long		gr21;
+	unsigned long		gr22;
+	unsigned long		gr23;
+	unsigned long		gr24;
+	unsigned long		gr25;
+	unsigned long		gr26;
+	unsigned long		gr27;
+	struct pt_regs		*next_frame;	/* GR28 - next exception frame */
+	unsigned long		gr29;		/* GR29 - OS reserved */
+	unsigned long		gr30;		/* GR30 - OS reserved */
+	unsigned long		gr31;		/* GR31 - OS reserved */
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG__STATUS_STEP	0x00000001	/* - reenable single stepping on return */
+#define REG__STATUS_STEPPED	0x00000002	/* - single step caused exception */
+#define REG__STATUS_BROKE	0x00000004	/* - BREAK insn caused exception */
+#define REG__STATUS_SYSC_ENTRY	0x40000000	/* - T on syscall entry (ptrace.c only) */
+#define REG__STATUS_SYSC_EXIT	0x80000000	/* - T on syscall exit (ptrace.c only) */
+
+#define REG_GR(R)	__OFFSET(REG_GR0, (R))
+
+#define REG_SP		REG_GR(1)
+#define REG_FP		REG_GR(2)
+#define REG_PREV_FRAME	REG_GR(28)	/* previous exception frame pointer (old gr28 value) */
+#define REG_CURR_TASK	REG_GR(29)	/* current task */
+
+/*****************************************************************************/
+/*
+ * debugging registers
+ */
+#ifndef __ASSEMBLY__
+
+struct frv_debug_regs
+{
+	unsigned long		dcr;
+	unsigned long		ibar[4] __attribute__((aligned(8)));
+	unsigned long		dbar[4] __attribute__((aligned(8)));
+	unsigned long		dbdr[4][4] __attribute__((aligned(8)));
+	unsigned long		dbmr[4][4] __attribute__((aligned(8)));
+} __attribute__((aligned(8)));
+
+#endif
+
+/*****************************************************************************/
+/*
+ * userspace registers
+ */
+#ifndef __ASSEMBLY__
+
+struct user_int_regs
+{
+	/* integer registers
+	 * - up to gr[31] mirror pt_regs
+	 * - total size must be multiple of 8 bytes
+	 */
+	unsigned long		psr;		/* Processor Status Register */
+	unsigned long		isr;		/* Integer Status Register */
+	unsigned long		ccr;		/* Condition Code Register */
+	unsigned long		cccr;		/* Condition Code for Conditional Insns Register */
+	unsigned long		lr;		/* Link Register */
+	unsigned long		lcr;		/* Loop Count Register */
+	unsigned long		pc;		/* Program Counter Register */
+	unsigned long		__status;	/* exception status */
+	unsigned long		syscallno;	/* syscall number or -1 */
+	unsigned long		orig_gr8;	/* original syscall arg #1 */
+	unsigned long		gner[2];
+	unsigned long long	iacc[1];
+
+	union {
+		unsigned long	tbr;
+		unsigned long	gr[64];
+	};
+};
+
+struct user_fpmedia_regs
+{
+	/* FP/Media registers */
+	unsigned long	fr[64];
+	unsigned long	fner[2];
+	unsigned long	msr[2];
+	unsigned long	acc[8];
+	unsigned char	accg[8];
+	unsigned long	fsr[1];
+};
+
+struct user_context
+{
+	struct user_int_regs		i;
+	struct user_fpmedia_regs	f;
+
+	/* we provide a context extension so that we can save the regs for CPUs that
+	 * implement many more of Fujitsu's lavish register spec
+	 */
+	void *extension;
+} __attribute__((aligned(8)));
+
+struct frv_frame0 {
+	union {
+		struct pt_regs		regs;
+		struct user_context	uc;
+	};
+
+	struct frv_debug_regs		debug;
+
+} __attribute__((aligned(32)));
+
+#endif
+
+#define __INT_GR(R)		__OFFSET(__INT_GR0,		(R))
+
+#define __FPMEDIA_FR(R)		__OFFSET(__FPMEDIA_FR0,		(R))
+#define __FPMEDIA_FNER(R)	__OFFSET(__FPMEDIA_FNER0,	(R))
+#define __FPMEDIA_MSR(R)	__OFFSET(__FPMEDIA_MSR0,	(R))
+#define __FPMEDIA_ACC(R)	__OFFSET(__FPMEDIA_ACC0,	(R))
+#define __FPMEDIA_ACCG(R)	__OFFSETC(__FPMEDIA_ACCG0,	(R))
+#define __FPMEDIA_FSR(R)	__OFFSET(__FPMEDIA_FSR0,	(R))
+
+#define __THREAD_GR(R)		__OFFSET(__THREAD_GR16,		(R) - 16)
+
+#endif /* _ASM_REGISTERS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/resource.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/resource.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/resource.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/resource.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_RESOURCE_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/scatterlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,46 @@
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+#include <asm/types.h>
+
+/*
+ * Drivers must set either ->address or (preferred) page and ->offset
+ * to indicate where data must be transferred to/from.
+ *
+ * Using page is recommended since it handles highmem data as well as
+ * low mem. ->address is restricted to data which has a virtual mapping, and
+ * it will go away in the future. Updating to page can be automated very
+ * easily -- something like
+ *
+ * sg->address = some_ptr;
+ *
+ * can be rewritten as
+ *
+ * sg_set_buf(sg, some_ptr, length);
+ *
+ * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
+ */
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
+	unsigned int	offset;		/* for highmem, page offset */
+
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)	((sg)->dma_address)
+#define sg_dma_len(sg)		((sg)->length)
+
+#define ISA_DMA_THRESHOLD (0xffffffffUL)
+
+#endif /* !_ASM_SCATTERLIST_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/sections.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,46 @@
+/* sections.h: linkage layout variables
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SECTIONS_H
+#define _ASM_SECTIONS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm-generic/sections.h>
+
+#ifdef __KERNEL__
+
+/*
+ * we don't want to put variables in the GP-REL section if they're not used very much - that would
+ * be waste since GP-REL addressing is limited to GP16+/-2048
+ */
+#define __nongpreldata	__attribute__((section(".data")))
+#define __nongprelbss	__attribute__((section(".bss")))
+
+/*
+ * linker symbols
+ */
+extern const void __kernel_image_start, __kernel_image_end, __page_offset;
+
+extern unsigned long __nongprelbss memory_start;
+extern unsigned long __nongprelbss memory_end;
+extern unsigned long __nongprelbss rom_length;
+
+/* determine if we're running from ROM */
+static inline int is_in_rom(unsigned long addr)
+{
+	return 0; /* default case: not in ROM */
+}
+
+#endif
+#endif
+#endif /* _ASM_SECTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/segment.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/segment.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/segment.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/segment.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/* segment.h: MMU segment settings
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#define KERNEL_DS		MAKE_MM_SEG(0xdfffffffUL)
+
+#ifdef CONFIG_MMU
+#define USER_DS			MAKE_MM_SEG(TASK_SIZE - 1)
+#else
+#define USER_DS			KERNEL_DS
+#endif
+
+#define get_ds()		(KERNEL_DS)
+#define get_fs()		(__current_thread_info->addr_limit)
+#define segment_eq(a,b)		((a).seg == (b).seg)
+#define __kernel_ds_p()		segment_eq(get_fs(), KERNEL_DS)
+#define get_addr_limit()	(get_fs().seg)
+
+#define set_fs(_x)					\
+do {							\
+	__current_thread_info->addr_limit = (_x);	\
+} while(0)
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/sembuf.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/sembuf.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/sembuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/sembuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm	sem_perm;	/* permissions .. see ipc.h */
+	__kernel_time_t		sem_otime;	/* last semop time */
+	unsigned long		__unused1;
+	__kernel_time_t		sem_ctime;	/* last change time */
+	unsigned long		__unused2;
+	unsigned long		sem_nsems;	/* no. of semaphores in array */
+	unsigned long		__unused3;
+	unsigned long		__unused4;
+};
+
+#endif /* _ASM_SEMBUF_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/serial.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/serial.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * serial.h
+ *
+ * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
+ * Author: Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * Based on linux/include/asm-i386/serial.h
+ */
+#include <asm/serial-regs.h>
+
+/*
+ * the base baud is derived from the clock speed and so is variable
+ */
+#define BASE_BAUD 0
+
+#define STD_COM_FLAGS		ASYNC_BOOT_AUTOCONF
+
+#define SERIAL_PORT_DFNS
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/serial-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/serial-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/serial-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/serial-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,44 @@
+/* serial-regs.h: serial port registers
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SERIAL_REGS_H
+#define _ASM_SERIAL_REGS_H
+
+#include <linux/serial_reg.h>
+#include <asm/irc-regs.h>
+
+#define SERIAL_ICLK	33333333	/* the target serial input clock */
+#define UART0_BASE	0xfeff9c00
+#define UART1_BASE	0xfeff9c40
+
+#define __get_UART0(R) ({ __reg(UART0_BASE + (R) * 8) >> 24; })
+#define __get_UART1(R) ({ __reg(UART1_BASE + (R) * 8) >> 24; })
+#define __set_UART0(R,V) do { __reg(UART0_BASE + (R) * 8) = (V) << 24; } while(0)
+#define __set_UART1(R,V) do { __reg(UART1_BASE + (R) * 8) = (V) << 24; } while(0)
+
+#define __get_UART0_LSR() ({ __get_UART0(UART_LSR); })
+#define __get_UART1_LSR() ({ __get_UART1(UART_LSR); })
+
+#define __set_UART0_IER(V) __set_UART0(UART_IER,(V))
+#define __set_UART1_IER(V) __set_UART1(UART_IER,(V))
+
+/* serial prescaler select register */
+#define __get_UCPSR()	({ *(volatile unsigned long *)(0xfeff9c90); })
+#define __set_UCPSR(V)	do { *(volatile unsigned long *)(0xfeff9c90) = (V); } while(0)
+#define UCPSR_SELECT0	0x07000000
+#define UCPSR_SELECT1	0x38000000
+
+/* serial prescaler base value register */
+#define __get_UCPVR()	({ *(volatile unsigned long *)(0xfeff9c98); mb(); })
+#define __set_UCPVR(V)	do { *(volatile unsigned long *)(0xfeff9c98) = (V) << 24; mb(); } while(0)
+
+
+#endif /* _ASM_SERIAL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/setup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/* setup.h: setup stuff
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+#define COMMAND_LINE_SIZE       512
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MMU
+extern unsigned long __initdata num_mappedpages;
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif  /*  __KERNEL__  */
+
+#endif /* _ASM_SETUP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/shmbuf.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/shmbuf.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/shmbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/shmbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for FR-V architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/shmparam.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/shmparam.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/shmparam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/shmparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/sigcontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+/* sigcontext.h: FRV signal context
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/registers.h>
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked.  Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+	struct user_context	sc_context;
+	unsigned long		sc_oldmask; 	/* old sigmask */
+} __attribute__((aligned(8)));
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/siginfo.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/siginfo.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/siginfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/siginfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#define FPE_MDAOVF	(__SI_FAULT|9)	/* media overflow */
+#undef NSIGFPE
+#define NSIGFPE		9
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/signal.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/signal.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/signal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/signal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,161 @@
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void __user *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SIGNAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/socket.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,61 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockopt(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_SNDBUFFORCE	32
+#define SO_RCVBUFFORCE	33
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+#define SO_PEERSEC		31
+#define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
+
+#define SO_MARK			36
+
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
+#endif /* _ASM_SOCKET_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/sockios.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/sockios.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/sockios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/sockios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+#ifndef _ASM_SOCKIOS__
+#define _ASM_SOCKIOS__
+
+/* 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) */
+
+#endif /* _ASM_SOCKIOS__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/spinlock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* spinlock.h: spinlocks for FR-V
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#error no spinlocks for FR-V yet
+
+#endif /* _ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/spr-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/spr-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/spr-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/spr-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,416 @@
+/* spr-regs.h: special-purpose registers on the FRV
+ *
+ * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPR_REGS_H
+#define _ASM_SPR_REGS_H
+
+/*
+ * PSR - Processor Status Register
+ */
+#define PSR_ET			0x00000001	/* enable interrupts/exceptions flag */
+#define PSR_PS			0x00000002	/* previous supervisor mode flag */
+#define PSR_S			0x00000004	/* supervisor mode flag */
+#define PSR_PIL			0x00000078	/* processor external interrupt level */
+#define PSR_PIL_0		0x00000000	/* - no interrupt in progress */
+#define PSR_PIL_13		0x00000068	/* - debugging only */
+#define PSR_PIL_14		0x00000070	/* - debugging in progress */
+#define PSR_PIL_15		0x00000078	/* - NMI in progress */
+#define PSR_EM			0x00000080	/* enable media operation */
+#define PSR_EF			0x00000100	/* enable FPU operation */
+#define PSR_BE			0x00001000	/* endianness mode */
+#define PSR_BE_LE		0x00000000	/* - little endian mode */
+#define PSR_BE_BE		0x00001000	/* - big endian mode */
+#define PSR_CM			0x00002000	/* conditional mode */
+#define PSR_NEM			0x00004000	/* non-excepting mode */
+#define PSR_ICE			0x00010000	/* in-circuit emulation mode */
+#define PSR_VERSION_SHIFT	24		/* CPU silicon ID */
+#define PSR_IMPLE_SHIFT		28		/* CPU core ID */
+
+#define PSR_VERSION(psr)	(((psr) >> PSR_VERSION_SHIFT) & 0xf)
+#define PSR_IMPLE(psr)		(((psr) >> PSR_IMPLE_SHIFT) & 0xf)
+
+#define PSR_IMPLE_FR401		0x2
+#define PSR_VERSION_FR401_MB93401	0x0
+#define PSR_VERSION_FR401_MB93401A	0x1
+#define PSR_VERSION_FR401_MB93403	0x2
+
+#define PSR_IMPLE_FR405		0x4
+#define PSR_VERSION_FR405_MB93405	0x0
+
+#define PSR_IMPLE_FR451		0x5
+#define PSR_VERSION_FR451_MB93451	0x0
+
+#define PSR_IMPLE_FR501		0x1
+#define PSR_VERSION_FR501_MB93501	0x1
+#define PSR_VERSION_FR501_MB93501A	0x2
+
+#define PSR_IMPLE_FR551		0x3
+#define PSR_VERSION_FR551_MB93555	0x1
+
+#define __get_PSR()	({ unsigned long x; asm volatile("movsg psr,%0" : "=r"(x)); x; })
+#define __set_PSR(V)	do { asm volatile("movgs %0,psr" : : "r"(V)); } while(0)
+
+/*
+ * TBR - Trap Base Register
+ */
+#define TBR_TT			0x00000ff0
+#define TBR_TT_INSTR_MMU_MISS	(0x01 << 4)
+#define TBR_TT_INSTR_ACC_ERROR	(0x02 << 4)
+#define TBR_TT_INSTR_ACC_EXCEP	(0x03 << 4)
+#define TBR_TT_PRIV_INSTR	(0x06 << 4)
+#define TBR_TT_ILLEGAL_INSTR	(0x07 << 4)
+#define TBR_TT_FP_EXCEPTION	(0x0d << 4)
+#define TBR_TT_MP_EXCEPTION	(0x0e << 4)
+#define TBR_TT_DATA_ACC_ERROR	(0x11 << 4)
+#define TBR_TT_DATA_MMU_MISS	(0x12 << 4)
+#define TBR_TT_DATA_ACC_EXCEP	(0x13 << 4)
+#define TBR_TT_DATA_STR_ERROR	(0x14 << 4)
+#define TBR_TT_DIVISION_EXCEP	(0x17 << 4)
+#define TBR_TT_COMMIT_EXCEP	(0x19 << 4)
+#define TBR_TT_INSTR_TLB_MISS	(0x1a << 4)
+#define TBR_TT_DATA_TLB_MISS	(0x1b << 4)
+#define TBR_TT_DATA_DAT_EXCEP	(0x1d << 4)
+#define TBR_TT_DECREMENT_TIMER	(0x1f << 4)
+#define TBR_TT_COMPOUND_EXCEP	(0x20 << 4)
+#define TBR_TT_INTERRUPT_1	(0x21 << 4)
+#define TBR_TT_INTERRUPT_2	(0x22 << 4)
+#define TBR_TT_INTERRUPT_3	(0x23 << 4)
+#define TBR_TT_INTERRUPT_4	(0x24 << 4)
+#define TBR_TT_INTERRUPT_5	(0x25 << 4)
+#define TBR_TT_INTERRUPT_6	(0x26 << 4)
+#define TBR_TT_INTERRUPT_7	(0x27 << 4)
+#define TBR_TT_INTERRUPT_8	(0x28 << 4)
+#define TBR_TT_INTERRUPT_9	(0x29 << 4)
+#define TBR_TT_INTERRUPT_10	(0x2a << 4)
+#define TBR_TT_INTERRUPT_11	(0x2b << 4)
+#define TBR_TT_INTERRUPT_12	(0x2c << 4)
+#define TBR_TT_INTERRUPT_13	(0x2d << 4)
+#define TBR_TT_INTERRUPT_14	(0x2e << 4)
+#define TBR_TT_INTERRUPT_15	(0x2f << 4)
+#define TBR_TT_TRAP0		(0x80 << 4)
+#define TBR_TT_TRAP1		(0x81 << 4)
+#define TBR_TT_TRAP2		(0x82 << 4)
+#define TBR_TT_TRAP3		(0x83 << 4)
+#define TBR_TT_TRAP120		(0xf8 << 4)
+#define TBR_TT_TRAP121		(0xf9 << 4)
+#define TBR_TT_TRAP122		(0xfa << 4)
+#define TBR_TT_TRAP123		(0xfb << 4)
+#define TBR_TT_TRAP124		(0xfc << 4)
+#define TBR_TT_TRAP125		(0xfd << 4)
+#define TBR_TT_TRAP126		(0xfe << 4)
+#define TBR_TT_BREAK		(0xff << 4)
+
+#define TBR_TT_ATOMIC_CMPXCHG32	TBR_TT_TRAP120
+#define TBR_TT_ATOMIC_XCHG32	TBR_TT_TRAP121
+#define TBR_TT_ATOMIC_XOR	TBR_TT_TRAP122
+#define TBR_TT_ATOMIC_OR	TBR_TT_TRAP123
+#define TBR_TT_ATOMIC_AND	TBR_TT_TRAP124
+#define TBR_TT_ATOMIC_SUB	TBR_TT_TRAP125
+#define TBR_TT_ATOMIC_ADD	TBR_TT_TRAP126
+
+#define __get_TBR()	({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; })
+
+/*
+ * HSR0 - Hardware Status Register 0
+ */
+#define HSR0_PDM		0x00000007	/* power down mode */
+#define HSR0_PDM_NORMAL		0x00000000	/* - normal mode */
+#define HSR0_PDM_CORE_SLEEP	0x00000001	/* - CPU core sleep mode */
+#define HSR0_PDM_BUS_SLEEP	0x00000003	/* - bus sleep mode */
+#define HSR0_PDM_PLL_RUN	0x00000005	/* - PLL run */
+#define HSR0_PDM_PLL_STOP	0x00000007	/* - PLL stop */
+#define HSR0_GRLE		0x00000040	/* GR lower register set enable */
+#define HSR0_GRHE		0x00000080	/* GR higher register set enable */
+#define HSR0_FRLE		0x00000100	/* FR lower register set enable */
+#define HSR0_FRHE		0x00000200	/* FR higher register set enable */
+#define HSR0_GRN		0x00000400	/* GR quantity */
+#define HSR0_GRN_64		0x00000000	/* - 64 GR registers */
+#define HSR0_GRN_32		0x00000400	/* - 32 GR registers */
+#define HSR0_FRN		0x00000800	/* FR quantity */
+#define HSR0_FRN_64		0x00000000	/* - 64 FR registers */
+#define HSR0_FRN_32		0x00000800	/* - 32 FR registers */
+#define HSR0_SA			0x00001000	/* start address (RAMBOOT#) */
+#define HSR0_ETMI		0x00008000	/* enable TIMERI (64-bit up timer) */
+#define HSR0_ETMD		0x00004000	/* enable TIMERD (32-bit down timer) */
+#define HSR0_PEDAT		0x00010000	/* previous DAT mode */
+#define HSR0_XEDAT		0x00020000	/* exception DAT mode */
+#define HSR0_EDAT		0x00080000	/* enable DAT mode */
+#define HSR0_RME		0x00400000	/* enable RAM mode */
+#define HSR0_EMEM		0x00800000	/* enable MMU_Miss mask */
+#define HSR0_EXMMU		0x01000000	/* enable extended MMU mode */
+#define HSR0_EDMMU		0x02000000	/* enable data MMU */
+#define HSR0_EIMMU		0x04000000	/* enable instruction MMU */
+#define HSR0_CBM		0x08000000	/* copy back mode */
+#define HSR0_CBM_WRITE_THRU	0x00000000	/* - write through */
+#define HSR0_CBM_COPY_BACK	0x08000000	/* - copy back */
+#define HSR0_NWA		0x10000000	/* no write allocate */
+#define HSR0_DCE		0x40000000	/* data cache enable */
+#define HSR0_ICE		0x80000000	/* instruction cache enable */
+
+#define __get_HSR(R)	({ unsigned long x; asm volatile("movsg hsr"#R",%0" : "=r"(x)); x; })
+#define __set_HSR(R,V)	do { asm volatile("movgs %0,hsr"#R : : "r"(V)); } while(0)
+
+/*
+ * CCR - Condition Codes Register
+ */
+#define CCR_FCC0		0x0000000f	/* FP/Media condition 0 (fcc0 reg) */
+#define CCR_FCC1		0x000000f0	/* FP/Media condition 1 (fcc1 reg) */
+#define CCR_FCC2		0x00000f00	/* FP/Media condition 2 (fcc2 reg) */
+#define CCR_FCC3		0x0000f000	/* FP/Media condition 3 (fcc3 reg) */
+#define CCR_ICC0		0x000f0000	/* Integer condition 0 (icc0 reg) */
+#define CCR_ICC0_C		0x00010000	/* - Carry flag */
+#define CCR_ICC0_V		0x00020000	/* - Overflow flag */
+#define CCR_ICC0_Z		0x00040000	/* - Zero flag */
+#define CCR_ICC0_N		0x00080000	/* - Negative flag */
+#define CCR_ICC1		0x00f00000	/* Integer condition 1 (icc1 reg) */
+#define CCR_ICC2		0x0f000000	/* Integer condition 2 (icc2 reg) */
+#define CCR_ICC3		0xf0000000	/* Integer condition 3 (icc3 reg) */
+
+/*
+ * CCCR - Condition Codes for Conditional Instructions Register
+ */
+#define CCCR_CC0		0x00000003	/* condition 0 (cc0 reg) */
+#define CCCR_CC0_FALSE		0x00000002	/* - condition is false */
+#define CCCR_CC0_TRUE		0x00000003	/* - condition is true */
+#define CCCR_CC1		0x0000000c	/* condition 1 (cc1 reg) */
+#define CCCR_CC2		0x00000030	/* condition 2 (cc2 reg) */
+#define CCCR_CC3		0x000000c0	/* condition 3 (cc3 reg) */
+#define CCCR_CC4		0x00000300	/* condition 4 (cc4 reg) */
+#define CCCR_CC5		0x00000c00	/* condition 5 (cc5 reg) */
+#define CCCR_CC6		0x00003000	/* condition 6 (cc6 reg) */
+#define CCCR_CC7		0x0000c000	/* condition 7 (cc7 reg) */
+
+/*
+ * ISR - Integer Status Register
+ */
+#define ISR_EMAM		0x00000001	/* memory misaligned access handling */
+#define ISR_EMAM_EXCEPTION	0x00000000	/* - generate exception */
+#define ISR_EMAM_FUDGE		0x00000001	/* - mask out invalid address bits */
+#define ISR_AEXC		0x00000004	/* accrued [overflow] exception */
+#define ISR_DTT			0x00000018	/* division type trap */
+#define ISR_DTT_IGNORE		0x00000000	/* - ignore division error */
+#define ISR_DTT_DIVBYZERO	0x00000008	/* - generate exception */
+#define ISR_DTT_OVERFLOW	0x00000010	/* - record overflow */
+#define ISR_EDE			0x00000020	/* enable division exception */
+#define ISR_PLI			0x20000000	/* pre-load instruction information */
+#define ISR_QI			0x80000000	/* quad data implementation information */
+
+/*
+ * EPCR0 - Exception PC Register
+ */
+#define EPCR0_V			0x00000001	/* register content validity indicator */
+#define EPCR0_PC		0xfffffffc	/* faulting instruction address */
+
+/*
+ * ESR0/14/15 - Exception Status Register
+ */
+#define ESRx_VALID		0x00000001	/* register content validity indicator */
+#define ESRx_EC			0x0000003e	/* exception type */
+#define ESRx_EC_DATA_STORE	0x00000000	/* - data_store_error */
+#define ESRx_EC_INSN_ACCESS	0x00000006	/* - instruction_access_error */
+#define ESRx_EC_PRIV_INSN	0x00000008	/* - privileged_instruction */
+#define ESRx_EC_ILL_INSN	0x0000000a	/* - illegal_instruction */
+#define ESRx_EC_MP_EXCEP	0x0000001c	/* - mp_exception */
+#define ESRx_EC_DATA_ACCESS	0x00000020	/* - data_access_error */
+#define ESRx_EC_DIVISION	0x00000026	/* - division_exception */
+#define ESRx_EC_ITLB_MISS	0x00000034	/* - instruction_access_TLB_miss */
+#define ESRx_EC_DTLB_MISS	0x00000036	/* - data_access_TLB_miss */
+#define ESRx_EC_DATA_ACCESS_DAT	0x0000003a	/* - data_access_DAT_exception */
+
+#define ESR0_IAEC		0x00000100	/* info for instruction-access-exception */
+#define ESR0_IAEC_RESV		0x00000000	/* - reserved */
+#define ESR0_IAEC_PROT_VIOL	0x00000100	/* - protection violation */
+
+#define ESR0_ATXC		0x00f00000	/* address translation exception code */
+#define ESR0_ATXC_MMU_MISS	0x00000000	/* - MMU miss exception and more (?) */
+#define ESR0_ATXC_MULTI_DAT	0x00800000	/* - multiple DAT entry hit */
+#define ESR0_ATXC_MULTI_SAT	0x00900000	/* - multiple SAT entry hit */
+#define ESR0_ATXC_AMRTLB_MISS	0x00a00000	/* - MMU/TLB miss exception */
+#define ESR0_ATXC_PRIV_EXCEP	0x00c00000	/* - privilege protection fault */
+#define ESR0_ATXC_WP_EXCEP	0x00d00000	/* - write protection fault */
+
+#define ESR0_EAV		0x00000800	/* true if EAR0 register valid */
+#define ESR15_EAV		0x00000800	/* true if EAR15 register valid */
+
+/*
+ * ESFR1 - Exception Status Valid Flag Register
+ */
+#define ESFR1_ESR0		0x00000001	/* true if ESR0 is valid */
+#define ESFR1_ESR14		0x00004000	/* true if ESR14 is valid */
+#define ESFR1_ESR15		0x00008000	/* true if ESR15 is valid */
+
+/*
+ * MSR - Media Status Register
+ */
+#define MSR0_AOVF		0x00000001	/* overflow exception accrued */
+#define MSRx_OVF		0x00000002	/* overflow exception detected */
+#define MSRx_SIE		0x0000003c	/* last SIMD instruction exception detected */
+#define MSRx_SIE_NONE		0x00000000	/* - none detected */
+#define MSRx_SIE_FRkHI_ACCk	0x00000020	/* - exception at FRkHI or ACCk */
+#define MSRx_SIE_FRkLO_ACCk1	0x00000010	/* - exception at FRkLO or ACCk+1 */
+#define MSRx_SIE_FRk1HI_ACCk2	0x00000008	/* - exception at FRk+1HI or ACCk+2 */
+#define MSRx_SIE_FRk1LO_ACCk3	0x00000004	/* - exception at FRk+1LO or ACCk+3 */
+#define MSR0_MTT		0x00007000	/* type of last media trap detected */
+#define MSR0_MTT_NONE		0x00000000	/* - none detected */
+#define MSR0_MTT_OVERFLOW	0x00001000	/* - overflow detected */
+#define MSR0_HI			0x00c00000	/* hardware implementation */
+#define MSR0_HI_ROUNDING	0x00000000	/* - rounding mode */
+#define MSR0_HI_NONROUNDING	0x00c00000	/* - non-rounding mode */
+#define MSR0_EMCI		0x01000000	/* enable media custom instructions */
+#define MSR0_SRDAV		0x10000000	/* select rounding mode of MAVEH */
+#define MSR0_SRDAV_RDAV		0x00000000	/* - controlled by MSR.RDAV */
+#define MSR0_SRDAV_RD		0x10000000	/* - controlled by MSR.RD */
+#define MSR0_RDAV		0x20000000	/* rounding mode of MAVEH */
+#define MSR0_RDAV_NEAREST_MI	0x00000000	/* - round to nearest minus */
+#define MSR0_RDAV_NEAREST_PL	0x20000000	/* - round to nearest plus */
+#define MSR0_RD			0xc0000000	/* rounding mode */
+#define MSR0_RD_NEAREST		0x00000000	/* - nearest */
+#define MSR0_RD_ZERO		0x40000000	/* - zero */
+#define MSR0_RD_POS_INF		0x80000000	/* - postive infinity */
+#define MSR0_RD_NEG_INF		0xc0000000	/* - negative infinity */
+
+/*
+ * IAMPR0-7 - Instruction Address Mapping Register
+ * DAMPR0-7 - Data Address Mapping Register
+ */
+#define xAMPRx_V		0x00000001	/* register content validity indicator */
+#define DAMPRx_WP		0x00000002	/* write protect */
+#define DAMPRx_WP_RW		0x00000000	/* - read/write */
+#define DAMPRx_WP_RO		0x00000002	/* - read-only */
+#define xAMPRx_C		0x00000004	/* cached/uncached */
+#define xAMPRx_C_CACHED		0x00000000	/* - cached */
+#define xAMPRx_C_UNCACHED	0x00000004	/* - uncached */
+#define xAMPRx_S		0x00000008	/* supervisor only */
+#define xAMPRx_S_USER		0x00000000	/* - userspace can access */
+#define xAMPRx_S_KERNEL		0x00000008	/* - kernel only */
+#define xAMPRx_SS		0x000000f0	/* segment size */
+#define xAMPRx_SS_16Kb		0x00000000	/* - 16 kilobytes */
+#define xAMPRx_SS_64Kb		0x00000010	/* - 64 kilobytes */
+#define xAMPRx_SS_256Kb		0x00000020	/* - 256 kilobytes */
+#define xAMPRx_SS_1Mb		0x00000030	/* - 1 megabyte */
+#define xAMPRx_SS_2Mb		0x00000040	/* - 2 megabytes */
+#define xAMPRx_SS_4Mb		0x00000050	/* - 4 megabytes */
+#define xAMPRx_SS_8Mb		0x00000060	/* - 8 megabytes */
+#define xAMPRx_SS_16Mb		0x00000070	/* - 16 megabytes */
+#define xAMPRx_SS_32Mb		0x00000080	/* - 32 megabytes */
+#define xAMPRx_SS_64Mb		0x00000090	/* - 64 megabytes */
+#define xAMPRx_SS_128Mb		0x000000a0	/* - 128 megabytes */
+#define xAMPRx_SS_256Mb		0x000000b0	/* - 256 megabytes */
+#define xAMPRx_SS_512Mb		0x000000c0	/* - 512 megabytes */
+#define xAMPRx_RESERVED8	0x00000100	/* reserved bit */
+#define xAMPRx_NG		0x00000200	/* non-global */
+#define xAMPRx_L		0x00000400	/* locked */
+#define xAMPRx_M		0x00000800	/* modified */
+#define xAMPRx_D		0x00001000	/* DAT entry */
+#define xAMPRx_RESERVED13	0x00002000	/* reserved bit */
+#define xAMPRx_PPFN		0xfff00000	/* physical page frame number */
+
+#define xAMPRx_V_BIT		0
+#define DAMPRx_WP_BIT		1
+#define xAMPRx_C_BIT		2
+#define xAMPRx_S_BIT		3
+#define xAMPRx_RESERVED8_BIT	8
+#define xAMPRx_NG_BIT		9
+#define xAMPRx_L_BIT		10
+#define xAMPRx_M_BIT		11
+#define xAMPRx_D_BIT		12
+#define xAMPRx_RESERVED13_BIT	13
+
+#define __get_IAMPR(R) ({ unsigned long x; asm volatile("movsg iampr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMPR(R) ({ unsigned long x; asm volatile("movsg dampr"#R",%0" : "=r"(x)); x; })
+
+#define __get_IAMLR(R) ({ unsigned long x; asm volatile("movsg iamlr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMLR(R) ({ unsigned long x; asm volatile("movsg damlr"#R",%0" : "=r"(x)); x; })
+
+#define __set_IAMPR(R,V) 	do { asm volatile("movgs %0,iampr"#R : : "r"(V)); } while(0)
+#define __set_DAMPR(R,V)  	do { asm volatile("movgs %0,dampr"#R : : "r"(V)); } while(0)
+
+#define __set_IAMLR(R,V) 	do { asm volatile("movgs %0,iamlr"#R : : "r"(V)); } while(0)
+#define __set_DAMLR(R,V)  	do { asm volatile("movgs %0,damlr"#R : : "r"(V)); } while(0)
+
+#define save_dampr(R, _dampr)					\
+do {								\
+	asm volatile("movsg dampr"R",%0" : "=r"(_dampr));	\
+} while(0)
+
+#define restore_dampr(R, _dampr)			\
+do {							\
+	asm volatile("movgs %0,dampr"R :: "r"(_dampr));	\
+} while(0)
+
+/*
+ * AMCR - Address Mapping Control Register
+ */
+#define AMCR_IAMRN		0x000000ff	/* quantity of IAMPR registers */
+#define AMCR_DAMRN		0x0000ff00	/* quantity of DAMPR registers */
+
+/*
+ * TTBR - Address Translation Table Base Register
+ */
+#define __get_TTBR()		({ unsigned long x; asm volatile("movsg ttbr,%0" : "=r"(x)); x; })
+
+/*
+ * TPXR - TLB Probe Extend Register
+ */
+#define TPXR_E			0x00000001
+#define TPXR_LMAX_SHIFT		20
+#define TPXR_LMAX_SMASK		0xf
+#define TPXR_WMAX_SHIFT		24
+#define TPXR_WMAX_SMASK		0xf
+#define TPXR_WAY_SHIFT		28
+#define TPXR_WAY_SMASK		0xf
+
+/*
+ * DCR - Debug Control Register
+ */
+#define DCR_IBCE3		0x00000001	/* break on conditional insn pointed to by IBAR3 */
+#define DCR_IBE3		0x00000002	/* break on insn pointed to by IBAR3 */
+#define DCR_IBCE1		0x00000004	/* break on conditional insn pointed to by IBAR2 */
+#define DCR_IBE1		0x00000008	/* break on insn pointed to by IBAR2 */
+#define DCR_IBCE2		0x00000010	/* break on conditional insn pointed to by IBAR1 */
+#define DCR_IBE2		0x00000020	/* break on insn pointed to by IBAR1 */
+#define DCR_IBCE0		0x00000040	/* break on conditional insn pointed to by IBAR0 */
+#define DCR_IBE0		0x00000080	/* break on insn pointed to by IBAR0 */
+
+#define DCR_DDBE1		0x00004000	/* use DBDR1x when checking DBAR1 */
+#define DCR_DWBE1		0x00008000	/* break on store to address in DBAR1/DBMR1x */
+#define DCR_DRBE1		0x00010000	/* break on load from address in DBAR1/DBMR1x */
+#define DCR_DDBE0		0x00020000	/* use DBDR0x when checking DBAR0 */
+#define DCR_DWBE0		0x00040000	/* break on store to address in DBAR0/DBMR0x */
+#define DCR_DRBE0		0x00080000	/* break on load from address in DBAR0/DBMR0x */
+
+#define DCR_EIM			0x0c000000	/* external interrupt disable */
+#define DCR_IBM			0x10000000	/* instruction break disable */
+#define DCR_SE			0x20000000	/* single step enable */
+#define DCR_EBE			0x40000000	/* exception break enable */
+
+/*
+ * BRR - Break Interrupt Request Register
+ */
+#define BRR_ST			0x00000001	/* single-step detected */
+#define BRR_SB			0x00000002	/* break instruction detected */
+#define BRR_BB			0x00000004	/* branch with hint detected */
+#define BRR_CBB			0x00000008	/* branch to LR detected */
+#define BRR_IBx			0x000000f0	/* hardware breakpoint detected */
+#define BRR_DBx			0x00000f00	/* hardware watchpoint detected */
+#define BRR_DBNEx		0x0000f000	/* ? */
+#define BRR_EBTT		0x00ff0000	/* trap type of exception break */
+#define BRR_TB			0x10000000	/* external break request detected */
+#define BRR_CB			0x20000000	/* ICE break command detected */
+#define BRR_EB			0x40000000	/* exception break detected */
+
+/*
+ * BPSR - Break PSR Save Register
+ */
+#define BPSR_BET		0x00000001	/* former PSR.ET */
+#define BPSR_BS			0x00001000	/* former PSR.S */
+
+#endif /* _ASM_SPR_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/statfs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/statfs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/statfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/statfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_STATFS_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/stat.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/stat.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/stat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/stat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,100 @@
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+/* This matches struct stat in uClibc/glibc.  */
+struct stat {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long __pad2;
+	unsigned long st_ino;
+
+	unsigned short __pad3;
+	unsigned short st_mode;
+	unsigned short __pad4;
+	unsigned short st_nlink;
+
+	unsigned short __pad5;
+	unsigned short st_uid;
+	unsigned short __pad6;
+	unsigned short st_gid;
+
+	unsigned char __pad7[6];
+	unsigned short st_rdev;
+
+	unsigned long __pad8;
+	unsigned long st_size;
+
+	unsigned long __pad9;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad10;	/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long __unused1;
+	unsigned long st_atime;
+
+	unsigned long __unused2;
+	unsigned long st_mtime;
+
+	unsigned long __unused3;
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+/* This matches struct stat64 in uClibc/glibc.  The layout is exactly
+   the same as that of struct stat above, with 64-bit types taking up
+   space that was formerly used by padding.  stat syscalls are still
+   different from stat64, though, in that the former tests for
+   overflow.  */
+struct stat64 {
+	unsigned char __pad1[6];
+	unsigned short st_dev;
+
+	unsigned long long st_ino;
+
+	unsigned int st_mode;
+	unsigned int st_nlink;
+
+	unsigned long st_uid;
+	unsigned long st_gid;
+
+	unsigned char __pad2[6];
+	unsigned short st_rdev;
+
+	long long st_size;
+
+	unsigned long __pad3;		/* align 64-bit st_blocks to 2-word */
+	unsigned long st_blksize;
+
+	unsigned long __pad4;		/* future possible st_blocks high bits */
+	unsigned long st_blocks;	/* Number 512-byte blocks allocated. */
+
+	unsigned long st_atime_nsec;
+	unsigned long st_atime;
+
+	unsigned int st_mtime_nsec;
+	unsigned long st_mtime;
+
+	unsigned long st_ctime_nsec;
+	unsigned long st_ctime;
+
+	unsigned long long __unused4;
+};
+
+#endif /* _ASM_STAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/string.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/string.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/string.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/string.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,51 @@
+/* string.h: FRV string handling
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_STRING_H_
+#define _ASM_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#else /* KERNEL */
+
+/*
+ *	let user libraries deal with these,
+ *	IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+#endif /* _ASM_STRING_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/suspend.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/suspend.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/suspend.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/suspend.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/* suspend.h: suspension stuff
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SUSPEND_H
+#define _ASM_SUSPEND_H
+
+static inline int arch_prepare_suspend(void)
+{
+	return 0;
+}
+
+#endif /* _ASM_SUSPEND_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/swab.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+#include <linux/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_SWAB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/system.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,301 @@
+/* system.h: FR-V CPU control definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+
+struct thread_struct;
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ * The `mb' is to tell GCC not to cache `current' across this call.
+ */
+extern asmlinkage
+struct task_struct *__switch_to(struct thread_struct *prev_thread,
+				struct thread_struct *next_thread,
+				struct task_struct *prev);
+
+#define switch_to(prev, next, last)					\
+do {									\
+	(prev)->thread.sched_lr =					\
+		(unsigned long) __builtin_return_address(0);		\
+	(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev));	\
+	mb();								\
+} while(0)
+
+/*
+ * interrupt flag manipulation
+ * - use virtual interrupt management since touching the PSR is slow
+ *   - ICC2.Z: T if interrupts virtually disabled
+ *   - ICC2.C: F if interrupts really disabled
+ * - if Z==1 upon interrupt:
+ *   - C is set to 0
+ *   - interrupts are really disabled
+ *   - entry.S returns immediately
+ * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
+ *   - if taken, the trap:
+ *     - sets ICC2.C
+ *     - enables interrupts
+ */
+#define local_irq_disable()					\
+do {								\
+	/* set Z flag, but don't change the C flag */		\
+	asm volatile("	andcc	gr0,gr0,gr0,icc2	\n"	\
+		     :						\
+		     :						\
+		     : "memory", "icc2"				\
+		     );						\
+} while(0)
+
+#define local_irq_enable()					\
+do {								\
+	/* clear Z flag and then test the C flag */		\
+	asm volatile("  oricc	gr0,#1,gr0,icc2		\n"	\
+		     "	tihi	icc2,gr0,#2		\n"	\
+		     :						\
+		     :						\
+		     : "memory", "icc2"				\
+		     );						\
+} while(0)
+
+#define local_save_flags(flags)					\
+do {								\
+	typecheck(unsigned long, flags);			\
+	asm volatile("movsg ccr,%0"				\
+		     : "=r"(flags)				\
+		     :						\
+		     : "memory");				\
+								\
+	/* shift ICC2.Z to bit 0 */				\
+	flags >>= 26;						\
+								\
+	/* make flags 1 if interrupts disabled, 0 otherwise */	\
+	flags &= 1UL;						\
+} while(0)
+
+#define irqs_disabled() \
+	({unsigned long flags; local_save_flags(flags); !!flags; })
+
+#define	local_irq_save(flags)			\
+do {						\
+	typecheck(unsigned long, flags);	\
+	local_save_flags(flags);		\
+	local_irq_disable();			\
+} while(0)
+
+#define	local_irq_restore(flags)					\
+do {									\
+	typecheck(unsigned long, flags);				\
+									\
+	/* load the Z flag by turning 1 if disabled into 0 if disabled	\
+	 * and thus setting the Z flag but not the C flag */		\
+	asm volatile("  xoricc	%0,#1,gr0,icc2		\n"		\
+		     /* then test Z=0 and C=0 */			\
+		     "	tihi	icc2,gr0,#2		\n"		\
+		     :							\
+		     : "r"(flags)					\
+		     : "memory", "icc2"					\
+		     );							\
+									\
+} while(0)
+
+/*
+ * real interrupt flag manipulation
+ */
+#define __local_irq_disable()				\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%2,%0	\n"	\
+		     "	ori	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (PSR_PIL_14), "i" (~PSR_PIL)	\
+		     : "memory");			\
+} while(0)
+
+#define __local_irq_enable()				\
+do {							\
+	unsigned long psr;				\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%1,%0	\n"	\
+		     "	movgs	%0,psr		\n"	\
+		     : "=r"(psr)			\
+		     : "i" (~PSR_PIL)			\
+		     : "memory");			\
+} while(0)
+
+#define __local_save_flags(flags)		\
+do {						\
+	typecheck(unsigned long, flags);	\
+	asm("movsg psr,%0"			\
+	    : "=r"(flags)			\
+	    :					\
+	    : "memory");			\
+} while(0)
+
+#define	__local_irq_save(flags)				\
+do {							\
+	unsigned long npsr;				\
+	typecheck(unsigned long, flags);		\
+	asm volatile("	movsg	psr,%0		\n"	\
+		     "	andi	%0,%3,%1	\n"	\
+		     "	ori	%1,%2,%1	\n"	\
+		     "	movgs	%1,psr		\n"	\
+		     : "=r"(flags), "=r"(npsr)		\
+		     : "i" (PSR_PIL_14), "i" (~PSR_PIL)	\
+		     : "memory");			\
+} while(0)
+
+#define	__local_irq_restore(flags)			\
+do {							\
+	typecheck(unsigned long, flags);		\
+	asm volatile("	movgs	%0,psr		\n"	\
+		     :					\
+		     : "r" (flags)			\
+		     : "memory");			\
+} while(0)
+
+#define __irqs_disabled() \
+	((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
+
+/*
+ * Force strict CPU ordering.
+ */
+#define nop()			asm volatile ("nop"::)
+#define mb()			asm volatile ("membar" : : :"memory")
+#define rmb()			asm volatile ("membar" : : :"memory")
+#define wmb()			asm volatile ("membar" : : :"memory")
+#define read_barrier_depends()	do { } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()			mb()
+#define smp_rmb()			rmb()
+#define smp_wmb()			wmb()
+#define smp_read_barrier_depends()	read_barrier_depends()
+#define set_mb(var, value) \
+	do { xchg(&var, (value)); } while (0)
+#else
+#define smp_mb()			barrier()
+#define smp_rmb()			barrier()
+#define smp_wmb()			barrier()
+#define smp_read_barrier_depends()	do {} while(0)
+#define set_mb(var, value) \
+	do { var = (value); barrier(); } while (0)
+#endif
+
+extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
+extern void free_initmem(void);
+
+#define arch_align_stack(x) (x)
+
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig, __xg_tmp;					\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 4:									\
+		asm volatile(							\
+			"0:						\n"	\
+			"	orcc		gr0,gr0,gr0,icc3	\n"	\
+			"	ckeq		icc3,cc7		\n"	\
+			"	ld.p		%M0,%1			\n"	\
+			"	orcr		cc7,cc7,cc3		\n"	\
+			"	sub%I4cc	%1,%4,%2,icc0		\n"	\
+			"	bne		icc0,#0,1f		\n"	\
+			"	cst.p		%3,%M0		,cc3,#1	\n"	\
+			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
+			"	beq		icc3,#0,0b		\n"	\
+			"1:						\n"	\
+			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
+			: "r"(__xg_new), "NPr"(__xg_test)			\
+			: "memory", "cc7", "cc3", "icc3", "icc0"		\
+			);							\
+		break;								\
+										\
+	default:								\
+		__xg_orig = (__typeof__(__xg_orig))0;				\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#else
+
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new)							\
+({										\
+	__typeof__(ptr) __xg_ptr = (ptr);					\
+	__typeof__(*(ptr)) __xg_orig;						\
+	__typeof__(*(ptr)) __xg_test = (test);					\
+	__typeof__(*(ptr)) __xg_new = (new);					\
+										\
+	switch (sizeof(__xg_orig)) {						\
+	case 4: __xg_orig = (__force __typeof__(*ptr))				\
+			__cmpxchg_32((__force uint32_t *)__xg_ptr,		\
+					 (__force uint32_t)__xg_test,		\
+					 (__force uint32_t)__xg_new); break;	\
+	default:								\
+		__xg_orig = (__typeof__(__xg_orig))0;				\
+		asm volatile("break");						\
+		break;								\
+	}									\
+										\
+	__xg_orig;								\
+})
+
+#endif
+
+#include <asm-generic/cmpxchg-local.h>
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+				      unsigned long old,
+				      unsigned long new, int size)
+{
+	switch (size) {
+	case 4:
+		return cmpxchg((unsigned long *)ptr, old, new);
+	default:
+		return __cmpxchg_local_generic(ptr, old, new, size);
+	}
+
+	return old;
+}
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n)				  	\
+	((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o),	\
+			(unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif /* _ASM_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/termbits.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/termbits.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/termbits.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/termbits.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,202 @@
+#ifndef _ASM_TERMBITS_H__
+#define _ASM_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 CTVB	  004000000000		/* VisioBraille Terminal flow control */
+#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
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ASM_TERMBITS_H__ */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/termios.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/termios.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/termios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/termios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,58 @@
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+#define TIOCM_MODEM_BITS       TIOCM_OUT2      /* IRDA support */
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+#ifdef __KERNEL__
+#include <asm-generic/termios.h>
+#endif
+
+#endif /* _ASM_TERMIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/thread_info.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,144 @@
+/* thread_info.h: description
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * Derived from include/asm-i386/thread_info.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#endif
+
+#define THREAD_SIZE		8192
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants must also be changed
+ */
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	unsigned long		status;		/* thread-synchronous flags */
+	__u32			cpu;		/* current CPU */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+
+	mm_segment_t		addr_limit;	/* thread address space:
+						 * 0-0xBFFFFFFF for user-thead
+						 * 0-0xFFFFFFFF for kernel-thread
+						 */
+	struct restart_block    restart_block;
+
+	__u8			supervisor_stack[0];
+};
+
+#else /* !__ASSEMBLY__ */
+
+#include <asm/asm-offsets.h>
+
+#endif
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *__current_thread_info asm("gr15");
+
+#define current_thread_info() ({ __current_thread_info; })
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+/* thread information allocation */
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk)					\
+	({							\
+		struct thread_info *ret;			\
+								\
+		ret = kzalloc(THREAD_SIZE, GFP_KERNEL);		\
+								\
+		ret;						\
+	})
+#else
+#define alloc_thread_info(tsk)	kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+
+#define free_thread_info(info)	kfree(info)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_SIGPENDING		1	/* signal pending */
+#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
+#define TIF_SINGLESTEP		3	/* restore singlestep on return to user mode */
+#define TIF_IRET		4	/* return with iret */
+#define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
+#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		17	/* OOM killer killed process */
+#define TIF_FREEZE		18	/* freezing for suspend */
+
+#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
+#define _TIF_IRET		(1 << TIF_IRET)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
+#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		(1 << TIF_FREEZE)
+
+#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+#define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
+
+/*
+ * 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_USEDFPM		0x0001	/* FPU/Media was used by this task this quantum (SMP) */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/timer-regs.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/timer-regs.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/timer-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/timer-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,106 @@
+/* timer-regs.h: hardware timer register definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+#include <asm/sections.h>
+
+extern unsigned long __nongprelbss __clkin_clock_speed_HZ;
+extern unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __sdram_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_clock_speed_HZ;
+extern unsigned long __nongprelbss __dsu_clock_speed_HZ;
+extern unsigned long __nongprelbss __serial_clock_speed_HZ;
+
+#define __get_CLKC()	({ *(volatile unsigned long *)(0xfeff9a00); })
+
+static inline void __set_CLKC(unsigned long v)
+{
+	int tmp;
+
+	asm volatile("	st%I0.p	%2,%M0		\n"
+		     "	setlos	%3,%1		\n"
+		     "	membar			\n"
+		     "0:			\n"
+		     "	subicc	%1,#1,%1,icc0	\n"
+		     "	bnc	icc0,#1,0b	\n"
+		     : "=m"(*(volatile unsigned long *) 0xfeff9a00), "=r"(tmp)
+		     : "r"(v), "i"(256)
+		     : "icc0");
+}
+
+#define __get_TCTR()	({ *(volatile unsigned long *)(0xfeff9418); })
+#define __get_TPRV()	({ *(volatile unsigned long *)(0xfeff9420); })
+#define __get_TPRCKSL()	({ *(volatile unsigned long *)(0xfeff9428); })
+#define __get_TCSR(T)	({ *(volatile unsigned long *)(0xfeff9400 + 8 * (T)); })
+#define __get_TxCKSL(T)	({ *(volatile unsigned long *)(0xfeff9430 + 8 * (T)); })
+
+#define __get_TCSR_DATA(T) ({ __get_TCSR(T) >> 24; })
+
+#define __set_TCTR(V)	do { *(volatile unsigned long *)(0xfeff9418) = (V); mb(); } while(0)
+#define __set_TPRV(V)	do { *(volatile unsigned long *)(0xfeff9420) = (V) << 24; mb(); } while(0)
+#define __set_TPRCKSL(V) do { *(volatile unsigned long *)(0xfeff9428) = (V); mb(); } while(0)
+#define __set_TCSR(T,V)	\
+do { *(volatile unsigned long *)(0xfeff9400 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TxCKSL(T,V) \
+do { *(volatile unsigned long *)(0xfeff9430 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TCSR_DATA(T,V) __set_TCSR(T, (V) << 24)
+#define __set_TxCKSL_DATA(T,V) __set_TxCKSL(T, TxCKSL_EIGHT | __TxCKSL_SELECT((V)))
+
+/* clock control register */
+#define CLKC_CMODE		0x0f000000
+#define CLKC_SLPL		0x000f0000
+#define CLKC_P0			0x00000100
+#define CLKC_CM			0x00000003
+
+#define CLKC_CMODE_s		24
+
+/* timer control register - non-readback mode */
+#define TCTR_MODE_0		0x00000000
+#define TCTR_MODE_2		0x04000000
+#define TCTR_MODE_4		0x08000000
+#define TCTR_MODE_5		0x0a000000
+#define TCTR_RL_LATCH		0x00000000
+#define TCTR_RL_RW_LOW8		0x10000000
+#define TCTR_RL_RW_HIGH8	0x20000000
+#define TCTR_RL_RW_LH8		0x30000000
+#define TCTR_SC_CTR0		0x00000000
+#define TCTR_SC_CTR1		0x40000000
+#define TCTR_SC_CTR2		0x80000000
+
+/* timer control register - readback mode */
+#define TCTR_CNT0		0x02000000
+#define TCTR_CNT1		0x04000000
+#define TCTR_CNT2		0x08000000
+#define TCTR_NSTATUS		0x10000000
+#define TCTR_NCOUNT		0x20000000
+#define TCTR_SC_READBACK	0xc0000000
+
+/* timer control status registers - non-readback mode */
+#define TCSRx_DATA		0xff000000
+
+/* timer control status registers - readback mode */
+#define TCSRx_OUTPUT		0x80000000
+#define TCSRx_NULLCOUNT		0x40000000
+#define TCSRx_RL		0x30000000
+#define TCSRx_MODE		0x07000000
+
+/* timer clock select registers */
+#define TxCKSL_SELECT		0x0f000000
+#define __TxCKSL_SELECT(X)	((X) << 24)
+#define TxCKSL_EIGHT		0xf0000000
+
+#endif /* _ASM_TIMER_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/* timex.h: FR-V architecture timex specifications
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE		1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
+#define vxtime_lock()		do {} while (0)
+#define vxtime_unlock()		do {} while (0)
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/tlbflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/* tlbflush.h: TLB flushing functions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+
+#ifndef __ASSEMBLY__
+extern void asmlinkage __flush_tlb_all(void);
+extern void asmlinkage __flush_tlb_mm(unsigned long contextid);
+extern void asmlinkage __flush_tlb_page(unsigned long contextid, unsigned long start);
+extern void asmlinkage __flush_tlb_range(unsigned long contextid,
+					 unsigned long start, unsigned long end);
+#endif /* !__ASSEMBLY__ */
+
+#define flush_tlb_all()				\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_all();			\
+	preempt_enable();			\
+} while(0)
+
+#define flush_tlb_mm(mm)			\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_mm((mm)->context.id);	\
+	preempt_enable();			\
+} while(0)
+
+#define flush_tlb_range(vma,start,end)					\
+do {									\
+	preempt_disable();						\
+	__flush_tlb_range((vma)->vm_mm->context.id, start, end);	\
+	preempt_enable();						\
+} while(0)
+
+#define flush_tlb_page(vma,addr)				\
+do {								\
+	preempt_disable();					\
+	__flush_tlb_page((vma)->vm_mm->context.id, addr);	\
+	preempt_enable();					\
+} while(0)
+
+
+#define __flush_tlb_global()			flush_tlb_all()
+#define flush_tlb()				flush_tlb_all()
+#define flush_tlb_kernel_range(start, end)	flush_tlb_all()
+
+#else
+
+#define flush_tlb()				BUG()
+#define flush_tlb_all()				BUG()
+#define flush_tlb_mm(mm)			BUG()
+#define flush_tlb_page(vma,addr)		BUG()
+#define flush_tlb_range(mm,start,end)		BUG()
+#define flush_tlb_kernel_range(start, end)	BUG()
+
+#endif
+
+
+#endif /* _ASM_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/tlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_MMU
+extern void check_pgt_cache(void);
+#else
+#define check_pgt_cache() do {} while(0)
+#endif
+
+/*
+ * we don't need any special per-pte or per-vma handling...
+ */
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up
+ */
+#define tlb_flush(tlb)		flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TLB_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/topology.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_TOPOLOGY_H
+#define _ASM_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#error NUMA not supported yet
+
+#endif /* CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_TOPOLOGY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/types.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,40 @@
+/* types.h: FRV types
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/uaccess.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,321 @@
+/* uaccess.h: userspace accessor functions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+
+#define HAVE_ARCH_UNMAPPED_AREA	/* we decide where to put mmaps */
+
+#define __ptr(x) ((unsigned long __force *)(x))
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit())
+
+/*
+ * check that a range of addresses falls within the current address limit
+ */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
+{
+#ifdef CONFIG_MMU
+	int flag = -EFAULT, tmp;
+
+	asm volatile (
+		"	addcc	%3,%2,%1,icc0	\n"	/* set C-flag if addr+size>4GB */
+		"	subcc.p	%1,%4,gr0,icc1	\n"	/* jump if addr+size>limit */
+		"	bc	icc0,#0,0f	\n"
+		"	bhi	icc1,#0,0f	\n"
+		"	setlos	#0,%0		\n"	/* mark okay */
+		"0:				\n"
+		: "=r"(flag), "=&r"(tmp)
+		: "r"(addr), "r"(size), "r"(get_addr_limit()), "0"(flag)
+		);
+
+	return flag;
+
+#else
+
+	if (addr < memory_start ||
+	    addr > memory_end ||
+	    size > memory_end - memory_start ||
+	    addr + size > memory_end)
+		return -EFAULT;
+
+	return 0;
+#endif
+}
+
+#define __range_ok(addr,size) ___range_ok((unsigned long) (addr), (unsigned long) (size))
+
+#define access_ok(type,addr,size) (__range_ok((void __user *)(addr), (size)) == 0)
+#define __access_ok(addr,size) (__range_ok((addr), (size)) == 0)
+
+/*
+ * 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
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+#define __put_user(x, ptr)						\
+({									\
+	int __pu_err = 0;						\
+									\
+	typeof(*(ptr)) __pu_val = (x);					\
+	__chk_user_ptr(ptr);						\
+									\
+	switch (sizeof (*(ptr))) {					\
+	case 1:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "b", "r");	\
+		break;							\
+	case 2:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "h", "r");	\
+		break;							\
+	case 4:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "",  "r");	\
+		break;							\
+	case 8:								\
+		__put_user_asm(__pu_err, __pu_val, ptr, "d", "e");	\
+		break;							\
+	default:							\
+		__pu_err = __put_user_bad();				\
+		break;							\
+	}								\
+	__pu_err;							\
+})
+
+#define put_user(x, ptr)			\
+({						\
+	typeof(*(ptr)) __user *_p = (ptr);	\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (_e == 0)				\
+		_e = __put_user((x), _p);	\
+	_e;					\
+})
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#ifdef CONFIG_MMU
+
+#define __put_user_asm(err,x,ptr,dsize,constraint)					\
+do {											\
+	asm volatile("1:	st"dsize"%I1	%2,%M1	\n"				\
+		     "2:				\n"				\
+		     ".subsection 2			\n"				\
+		     "3:	setlos		%3,%0	\n"				\
+		     "		bra		2b	\n"				\
+		     ".previous				\n"				\
+		     ".section __ex_table,\"a\"		\n"				\
+		     "		.balign		8	\n"				\
+		     "		.long		1b,3b	\n"				\
+		     ".previous"							\
+		     : "=r" (err)							\
+		     : "m" (*__ptr(ptr)), constraint (x), "i"(-EFAULT), "0"(err)	\
+		     : "memory");							\
+} while (0)
+
+#else
+
+#define __put_user_asm(err,x,ptr,bwl,con)	\
+do {						\
+	asm("	st"bwl"%I0	%1,%M0	\n"	\
+	    "	membar			\n"	\
+	    :					\
+	    : "m" (*__ptr(ptr)), con (x)	\
+	    : "memory");			\
+} while (0)
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define __get_user(x, ptr)						\
+({									\
+	int __gu_err = 0;						\
+	__chk_user_ptr(ptr);						\
+									\
+	switch (sizeof(*(ptr))) {					\
+	case 1: {							\
+		unsigned char __gu_val;					\
+		__get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r");	\
+		(x) = *(__force __typeof__(*(ptr)) *) &__gu_val;	\
+		break;							\
+	}								\
+	case 2: {							\
+		unsigned short __gu_val;				\
+		__get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r");	\
+		(x) = *(__force __typeof__(*(ptr)) *) &__gu_val;	\
+		break;							\
+	}								\
+	case 4: {							\
+		unsigned int __gu_val;					\
+		__get_user_asm(__gu_err, __gu_val, ptr, "", "=r");	\
+		(x) = *(__force __typeof__(*(ptr)) *) &__gu_val;	\
+		break;							\
+	}								\
+	case 8: {							\
+		unsigned long long __gu_val;				\
+		__get_user_asm(__gu_err, __gu_val, ptr, "d", "=e");	\
+		(x) = *(__force __typeof__(*(ptr)) *) &__gu_val;	\
+		break;							\
+	}								\
+	default:							\
+		__gu_err = __get_user_bad();				\
+		break;							\
+	}								\
+	__gu_err;							\
+})
+
+#define get_user(x, ptr)			\
+({						\
+	const typeof(*(ptr)) __user *_p = (ptr);\
+	int _e;					\
+						\
+	_e = __range_ok(_p, sizeof(*_p));	\
+	if (likely(_e == 0))			\
+		_e = __get_user((x), _p);	\
+	else					\
+		(x) = (typeof(x)) 0;		\
+	_e;					\
+})
+
+extern int __get_user_bad(void);
+
+#ifdef CONFIG_MMU
+
+#define __get_user_asm(err,x,ptr,dtype,constraint)	\
+do {							\
+	asm("1:		ld"dtype"%I2	%M2,%1	\n"	\
+	    "2:					\n"	\
+	    ".subsection 2			\n"	\
+	    "3:		setlos		%3,%0	\n"	\
+	    "		setlos		#0,%1	\n"	\
+	    "		bra		2b	\n"	\
+	    ".previous				\n"	\
+	    ".section __ex_table,\"a\"		\n"	\
+	    "		.balign		8	\n"	\
+	    "		.long		1b,3b	\n"	\
+	    ".previous"					\
+	    : "=r" (err), constraint (x)		\
+	    : "m" (*__ptr(ptr)), "i"(-EFAULT), "0"(err)	\
+	    );						\
+} while(0)
+
+#else
+
+#define __get_user_asm(err,x,ptr,bwl,con)	\
+	asm("	ld"bwl"%I1	%M1,%0	\n"	\
+	    "	membar			\n"	\
+	    : con(x)				\
+	    : "m" (*__ptr(ptr)))
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define ____force(x) (__force void *)(void __user *)(x)
+#ifdef CONFIG_MMU
+extern long __memset_user(void *dst, unsigned long count);
+extern long __memcpy_user(void *dst, const void *src, unsigned long count);
+
+#define clear_user(dst,count)			__memset_user(____force(dst), (count))
+#define __copy_from_user_inatomic(to, from, n)	__memcpy_user((to), ____force(from), (n))
+#define __copy_to_user_inatomic(to, from, n)	__memcpy_user(____force(to), (from), (n))
+
+#else
+
+#define clear_user(dst,count)			(memset(____force(dst), 0, (count)), 0)
+#define __copy_from_user_inatomic(to, from, n)	(memcpy((to), ____force(from), (n)), 0)
+#define __copy_to_user_inatomic(to, from, n)	(memcpy(____force(to), (from), (n)), 0)
+
+#endif
+
+#define __clear_user clear_user
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       might_sleep();
+       return __copy_to_user_inatomic(to, from, n);
+}
+
+static inline unsigned long
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+       might_sleep();
+       return __copy_from_user_inatomic(to, from, n);
+}
+
+static inline long copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	unsigned long ret = n;
+
+	if (likely(__access_ok(from, n)))
+		ret = __copy_from_user(to, from, n);
+
+	if (unlikely(ret != 0))
+		memset(to + (n - ret), 0, ret);
+
+	return ret;
+}
+
+static inline long copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n;
+}
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *src, long count);
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+extern unsigned long search_exception_table(unsigned long addr);
+
+#endif /* _ASM_UACCESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/ucontext.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/ucontext.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/ucontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/ucontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long		uc_flags;
+	struct ucontext		*uc_link;
+	stack_t			uc_stack;
+	struct sigcontext	uc_mcontext;
+	sigset_t		uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/unaligned.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/unaligned.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/unaligned.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/unaligned.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/* unaligned.h: unaligned access handler
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
+#endif /* _ASM_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/unistd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,384 @@
+#ifndef _ASM_UNISTD_H_
+#define _ASM_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+// #define __NR_oldolduname	 /* 59 */ obsolete
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76	/* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+// #define __NR_mmap		 90	/* obsolete - not implemented */
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+// #define __NR_profil		 /* 98 */ obsolete
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+// #define __NR_ioperm		/* 101 */ not supported
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+// #define __NR_olduname		/* 109 */ obsolete
+// #define __NR_iopl		/* 110 */ not supported
+#define __NR_vhangup		111
+// #define __NR_idle		/* 112 */ Obsolete
+// #define __NR_vm86old		/* 113 */ not supported
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+// #define __NR_modify_ldt	/* 123 */ not supported
+#define __NR_cacheflush		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+// #define __NR_vm86		/* 166 */ not supported
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl		172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64		180
+#define __NR_pwrite64		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+#define __NR_security		223	/* syscall for security modules */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#define __NR_mq_timedreceive	(__NR_mq_open+3)
+#define __NR_mq_notify		(__NR_mq_open+4)
+#define __NR_mq_getsetattr	(__NR_mq_open+5)
+#define __NR_kexec_load		283
+#define __NR_waitid		284
+/* #define __NR_sys_setaltroot	285 */
+#define __NR_add_key		286
+#define __NR_request_key	287
+#define __NR_keyctl		288
+#define __NR_ioprio_set		289
+#define __NR_ioprio_get		290
+#define __NR_inotify_init	291
+#define __NR_inotify_add_watch	292
+#define __NR_inotify_rm_watch	293
+#define __NR_migrate_pages	294
+#define __NR_openat		295
+#define __NR_mkdirat		296
+#define __NR_mknodat		297
+#define __NR_fchownat		298
+#define __NR_futimesat		299
+#define __NR_fstatat64		300
+#define __NR_unlinkat		301
+#define __NR_renameat		302
+#define __NR_linkat		303
+#define __NR_symlinkat		304
+#define __NR_readlinkat		305
+#define __NR_fchmodat		306
+#define __NR_faccessat		307
+#define __NR_pselect6		308
+#define __NR_ppoll		309
+#define __NR_unshare		310
+#define __NR_set_robust_list	311
+#define __NR_get_robust_list	312
+#define __NR_splice		313
+#define __NR_sync_file_range	314
+#define __NR_tee		315
+#define __NR_vmsplice		316
+#define __NR_move_pages		317
+#define __NR_getcpu		318
+#define __NR_epoll_pwait	319
+#define __NR_utimensat		320
+#define __NR_signalfd		321
+#define __NR_timerfd_create	322
+#define __NR_eventfd		323
+#define __NR_fallocate		324
+#define __NR_timerfd_settime	325
+#define __NR_timerfd_gettime	326
+#define __NR_signalfd4		327
+#define __NR_eventfd2		328
+#define __NR_epoll_create1	329
+#define __NR_dup3		330
+#define __NR_pipe2		331
+#define __NR_inotify_init1	332
+#define __NR_preadv		333
+#define __NR_pwritev		334
+
+#ifdef __KERNEL__
+
+#define NR_syscalls 335
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+/* #define __ARCH_WANT_OLD_READDIR */
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+/* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_PAUSE
+/* #define __ARCH_WANT_SYS_SGETMASK */
+/* #define __ARCH_WANT_SYS_SIGNAL */
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+/* #define __ARCH_WANT_SYS_SIGPENDING */
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#ifndef cond_syscall
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_UNISTD_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/user.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/user.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/user.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,80 @@
+/* user.h: FR-V core file format stuff
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <asm/registers.h>
+
+/* Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the 'trad-core' bfd).  There are quite a number of
+ * obstacles to being able to view the contents of the floating point
+ * registers, and until these are solved you will not be able to view
+ * the contents of them.  Actually, you can read in the core file and
+ * look at the contents of the user struct to find out what the
+ * floating point registers contain.
+ *
+ * The actual file contents are as follows:
+ * UPAGE:
+ *   1 page consisting of a user struct that tells gdb what is present
+ *   in the file.  Directly after this is a copy of the task_struct,
+ *   which is currently not used by gdb, but it may come in useful at
+ *   some point.  All of the registers are stored as part of the
+ *   upage.  The upage should always be only one page.
+ *
+ * DATA:
+ *   The data area is stored.  We use current->end_text to
+ *   current->brk to pick up all of the user variables, plus any
+ *   memory that may have been malloced.  No attempt is made to
+ *   determine if a page is demand-zero or if a page is totally
+ *   unused, we just cover the entire range.  All of the addresses are
+ *   rounded in such a way that an integral number of pages is
+ *   written.
+ *
+ * STACK:
+ *   We need the stack information in order to get a meaningful
+ *   backtrace.  We need to write the data from (esp) to
+ *   current->start_stack, so we round each of these off in order to
+ *   be able to write an integer number of pages.  The minimum core
+ *   file size is 3 pages, or 12288 bytes.
+ */
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+ * this will be used by gdb to figure out where the data and stack segments
+ *  are within the file, and what virtual addresses to use.
+ */
+struct user {
+	/* We start with the registers, to mimic the way that "memory" is returned
+	 * from the ptrace(3,...) function.  */
+	struct user_context	regs;
+
+	/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long		u_tsize;	/* Text segment size (pages). */
+	unsigned long		u_dsize;	/* Data segment size (pages). */
+	unsigned long		u_ssize;	/* Stack segment size (pages). */
+	unsigned long		start_code;     /* Starting virtual address of text. */
+	unsigned long		start_stack;	/* Starting virtual address of stack area.
+						 * This is actually the bottom of the stack,
+						 * the top of the stack is always found in the
+						 * esp register.  */
+	long int		signal;		/* Signal that caused the core dump. */
+
+	unsigned long		magic;		/* To uniquely identify a core file */
+	char			u_comm[32];	/* User command that was responsible */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/vga.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/vga.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/vga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* vga.h: VGA register stuff
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_VGA_H
+#define _ASM_VGA_H
+
+
+
+#endif /* _ASM_VGA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/virtconvert.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/virtconvert.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/virtconvert.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/virtconvert.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/* virtconvert.h: virtual/physical/page address convertion
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_VIRTCONVERT_H
+#define _ASM_VIRTCONVERT_H
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+
+#define phys_to_virt(vaddr)	((void *) ((unsigned long)(vaddr) + PAGE_OFFSET))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr) - PAGE_OFFSET)
+
+#else
+
+#define phys_to_virt(vaddr)	((void *) (vaddr))
+#define virt_to_phys(vaddr)	((unsigned long) (vaddr))
+
+#endif
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page)	virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/include/asm/xor.h linux-libre-2.6.30-gnu1/arch/frv/include/asm/xor.h
--- linux-libre-2.6.29-gnu1/arch/frv/include/asm/xor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/frv/include/asm/xor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/entry.S linux-libre-2.6.30-gnu1/arch/frv/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -1525,5 +1525,7 @@ sys_call_table:
 	.long sys_dup3			/* 330 */
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev
 
 syscall_table_size = (. - sys_call_table)
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/head-mmu-fr451.S linux-libre-2.6.30-gnu1/arch/frv/kernel/head-mmu-fr451.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/head-mmu-fr451.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/head-mmu-fr451.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/ptrace.h>
@@ -31,7 +32,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	__INIT
 	.balign		4
 
 ###############################################################################
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/head.S linux-libre-2.6.30-gnu1/arch/frv/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
@@ -27,7 +28,7 @@
 #   command line string
 #
 ###############################################################################
-	.section	.text.head,"ax"
+	__HEAD
 	.balign		4
 
 	.globl		_boot, __head_reference
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr401.S linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr401.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr401.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr401.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/ptrace.h>
@@ -30,7 +31,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	__INIT
 	.balign		4
 
 ###############################################################################
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr451.S linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr451.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr451.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr451.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/ptrace.h>
@@ -30,7 +31,7 @@
 #define __400_LCR	0xfe000100
 #define __400_LSBR	0xfe000c00
 
-	.section	.text.init,"ax"
+	__INIT
 	.balign		4
 
 ###############################################################################
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr555.S linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr555.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/head-uc-fr555.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/head-uc-fr555.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <asm/ptrace.h>
@@ -29,7 +30,7 @@
 #define __551_LCR	0xfeff1100
 #define __551_LSBR	0xfeff1c00
 
-	.section	.text.init,"ax"
+	__INIT
 	.balign		4
 
 ###############################################################################
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/irq.c linux-libre-2.6.30-gnu1/arch/frv/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p,
 		if (action) {
 			seq_printf(p, "%3d: ", i);
 			for_each_present_cpu(cpu)
-				seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+				seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 			seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
 			seq_printf(p, "  %s", action->name);
 			for (action = action->next;
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93091.c linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93091.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93091.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93091.c	2009-06-09 23:05:27.000000000 -0400
@@ -109,28 +109,24 @@ static struct irqaction fpga_irq[4]  = {
 	[0] = {
 		.handler	= fpga_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "fpga.0",
 		.dev_id		= (void *) 0x0028UL,
 	},
 	[1] = {
 		.handler	= fpga_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "fpga.1",
 		.dev_id		= (void *) 0x0050UL,
 	},
 	[2] = {
 		.handler	= fpga_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "fpga.2",
 		.dev_id		= (void *) 0x1c00UL,
 	},
 	[3] = {
 		.handler	= fpga_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "fpga.3",
 		.dev_id		= (void *) 0x6386UL,
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93093.c linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93093.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93093.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93093.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,7 +108,6 @@ static struct irqaction fpga_irq[1]  = {
 	[0] = {
 		.handler	= fpga_interrupt,
 		.flags		= IRQF_DISABLED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "fpga.0",
 		.dev_id		= (void *) 0x0700UL,
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93493.c linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93493.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/irq-mb93493.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/irq-mb93493.c	2009-06-09 23:05:27.000000000 -0400
@@ -120,14 +120,12 @@ static struct irqaction mb93493_irq[2]
 	[0] = {
 		.handler	= mb93493_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "mb93493.0",
 		.dev_id		= (void *) __addr_MB93493_IQSR(0),
 	},
 	[1] = {
 		.handler	= mb93493_interrupt,
 		.flags		= IRQF_DISABLED | IRQF_SHARED,
-		.mask		= CPU_MASK_NONE,
 		.name		= "mb93493.1",
 		.dev_id		= (void *) __addr_MB93493_IQSR(1),
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/process.c linux-libre-2.6.30-gnu1/arch/frv/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -204,7 +204,7 @@ void prepare_to_copy(struct task_struct
 /*
  * set up the kernel stack and exception frames for a new process
  */
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
 		unsigned long usp, unsigned long topstk,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/setup.c linux-libre-2.6.30-gnu1/arch/frv/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_BLK_DEV_INITRD
-#include <linux/blk.h>
 #include <asm/pgtable.h>
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/time.c linux-libre-2.6.30-gnu1/arch/frv/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,6 @@ static irqreturn_t timer_interrupt(int i
 static struct irqaction timer_irq  = {
 	.handler = timer_interrupt,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "timer",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/frv/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/frv/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,7 @@ SECTIONS
 
   _sinittext = .;
   .init.text : {
-	*(.text.head)
+	HEAD_TEXT
 #ifndef CONFIG_DEBUG_INFO
 	INIT_TEXT
 	EXIT_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/mb93090-mb00/pci-vdk.c linux-libre-2.6.30-gnu1/arch/frv/mb93090-mb00/pci-vdk.c
--- linux-libre-2.6.29-gnu1/arch/frv/mb93090-mb00/pci-vdk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/mb93090-mb00/pci-vdk.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,29 @@ struct pci_bus *__nongpreldata pci_root_
 struct pci_ops *__nongpreldata 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	= 0,
+	.end	= IO_SPACE_LIMIT,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource pci_iomem_resource = {
+	.name	= "PCI mem",
+	.start	= 0,
+	.end	= -1,
+	.flags	= IORESOURCE_MEM,
+};
+
+/*
  * Functions for accessing PCI configuration space
  */
 
@@ -304,6 +327,12 @@ void __init pcibios_fixup_bus(struct pci
 #if 0
 	printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
 #endif
+
+	if (bus->number == 0) {
+		bus->resource[0] = &pci_ioport_resource;
+		bus->resource[1] = &pci_iomem_resource;
+	}
+
 	pci_read_bridge_bases(bus);
 
 	if (bus->number == 0) {
@@ -350,28 +379,36 @@ int __init pcibios_init(void)
 	/* enable PCI arbitration */
 	__reg_MB86943_pci_arbiter	= MB86943_PCIARB_EN;
 
-	ioport_resource.start	= (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
-	ioport_resource.end	= (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
-	ioport_resource.end	+= ioport_resource.start;
+	pci_ioport_resource.start	= (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
+	pci_ioport_resource.end		= (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
+	pci_ioport_resource.end		+= pci_ioport_resource.start;
 
 	printk("PCI IO window:  %08llx-%08llx\n",
-	       (unsigned long long) ioport_resource.start,
-	       (unsigned long long) ioport_resource.end);
-
-	iomem_resource.start	= (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+	       (unsigned long long) pci_ioport_resource.start,
+	       (unsigned long long) pci_ioport_resource.end);
 
-	/* Reserve somewhere to write to flush posted writes. */
-	iomem_resource.start += 0x400;
+	pci_iomem_resource.start	= (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+	pci_iomem_resource.end		= (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
+	pci_iomem_resource.end		+= pci_iomem_resource.start;
 
-	iomem_resource.end	= (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
-	iomem_resource.end	+= iomem_resource.start;
+	/* Reserve somewhere to write to flush posted writes.  This is used by
+	 * __flush_PCI_writes() from asm/io.h to force the write FIFO in the
+	 * CPU-PCI bridge to flush as this doesn't happen automatically when a
+	 * read is performed on the MB93090 development kit motherboard.
+	 */
+	pci_iomem_resource.start	+= 0x400;
 
 	printk("PCI MEM window: %08llx-%08llx\n",
-	       (unsigned long long) iomem_resource.start,
-	       (unsigned long long) iomem_resource.end);
+	       (unsigned long long) pci_iomem_resource.start,
+	       (unsigned long long) pci_iomem_resource.end);
 	printk("PCI DMA memory: %08lx-%08lx\n",
 	       dma_coherent_mem_start, dma_coherent_mem_end);
 
+	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 -ENXIO;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/frv/mm/tlb-miss.S linux-libre-2.6.30-gnu1/arch/frv/mm/tlb-miss.S
--- linux-libre-2.6.29-gnu1/arch/frv/mm/tlb-miss.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/frv/mm/tlb-miss.S	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/linkage.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/highmem.h>
 #include <asm/spr-regs.h>
 
 	.section	.text.tlbmiss
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/h8300/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/h8300/include/asm/flat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
 #ifndef __H8300_FLAT_H__
 #define __H8300_FLAT_H__
 
-#define	flat_stack_align(sp)			/* nothing needed */
 #define	flat_argvp_envp_on_stack()		1
 #define	flat_old_ram_flag(flags)		1
 #define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/h8300/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/h8300/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/h8300/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/h8300/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/h8300/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/h8300/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/h8300/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _H8300_SWAB_H
 #define _H8300_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __SWAB_64_THRU_32__
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/include/asm/timer.h linux-libre-2.6.30-gnu1/arch/h8300/include/asm/timer.h
--- linux-libre-2.6.29-gnu1/arch/h8300/include/asm/timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/h8300/include/asm/timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+#ifndef __H8300_TIMER_H
+#define __H8300_TIMER_H
+
+void h8300_timer_tick(void);
+void h8300_timer_setup(void);
+void h8300_gettod(unsigned int *year, unsigned int *mon, unsigned int *day,
+		   unsigned int *hour, unsigned int *min, unsigned int *sec);
+
+#define TIMER_FREQ (CONFIG_CPU_CLOCK*10000) /* Timer input freq. */
+
+#define calc_param(cnt, div, rate, limit)			\
+do {								\
+	cnt = TIMER_FREQ / HZ;					\
+	for (div = 0; div < ARRAY_SIZE(divide_rate); div++) {	\
+		if (rate[div] == 0)				\
+			continue;				\
+		if ((cnt / rate[div]) > limit)			\
+			break;					\
+	}							\
+	if (div == ARRAY_SIZE(divide_rate))			\
+		panic("Timer counter overflow");		\
+	cnt /= divide_rate[div];				\
+} while(0)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/irq.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -183,7 +183,7 @@ asmlinkage void do_IRQ(int irq)
 #if defined(CONFIG_PROC_FS)
 int show_interrupts(struct seq_file *p, void *v)
 {
-	int i = *(loff_t *) v, j;
+	int i = *(loff_t *) v;
 	struct irqaction * action;
 	unsigned long flags;
 
@@ -196,7 +196,7 @@ int show_interrupts(struct seq_file *p,
 		if (!action)
 			goto unlock;
 		seq_printf(p, "%3d: ",i);
-		seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "  %s", action->name);
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/process.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -191,7 +191,7 @@ asmlinkage int h8300_clone(struct pt_reg
 
 }
 
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
                 unsigned long usp, unsigned long topstk,
 		 struct task_struct * p, struct pt_regs * regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/itu.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/itu.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/itu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/itu.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,7 +60,6 @@ static struct irqaction itu_irq = {
 	.name		= "itu",
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 };
 
 static const int __initdata divide_rate[] = {1, 2, 4, 8};
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/timer16.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/timer16.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/timer16.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/timer16.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,7 +55,6 @@ static struct irqaction timer16_irq = {
 	.name		= "timer-16",
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 };
 
 static const int __initdata divide_rate[] = {1, 2, 4, 8};
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/timer8.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/timer8.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/timer8.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/timer8.c	2009-06-09 23:05:27.000000000 -0400
@@ -75,7 +75,6 @@ static struct irqaction timer8_irq = {
 	.name		= "timer-8",
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 };
 
 static const int __initdata divide_rate[] = {8, 64, 8192};
diff -druNp linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/tpu.c linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/tpu.c
--- linux-libre-2.6.29-gnu1/arch/h8300/kernel/timer/tpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/h8300/kernel/timer/tpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,10 +65,9 @@ static struct irqaction tpu_irq = {
 	.name		= "tpu",
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 };
 
-const static int __initdata divide_rate[] = {
+static const int __initdata divide_rate[] = {
 #if CONFIG_H8300_TPU_CH == 0
 	1,4,16,64,0,0,0,0,
 #elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/configs/generic_defconfig linux-libre-2.6.30-gnu1/arch/ia64/configs/generic_defconfig
--- linux-libre-2.6.29-gnu1/arch/ia64/configs/generic_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/configs/generic_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,6 @@ CONFIG_BOUNCE=y
 CONFIG_NR_QUICK=1
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
-CONFIG_MMU_NOTIFIER=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -416,8 +415,6 @@ CONFIG_SGI_IOC4=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 CONFIG_SGI_XP=m
 # CONFIG_HP_ILO is not set
-CONFIG_SGI_GRU=m
-# CONFIG_SGI_GRU_DEBUG is not set
 # CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/dig/dig_vtd_iommu.c linux-libre-2.6.30-gnu1/arch/ia64/dig/dig_vtd_iommu.c
--- linux-libre-2.6.29-gnu1/arch/ia64/dig/dig_vtd_iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/dig/dig_vtd_iommu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/intel-iommu.h>
-
-void *
-vtd_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		 gfp_t flags)
-{
-	return intel_alloc_coherent(dev, size, dma_handle, flags);
-}
-EXPORT_SYMBOL_GPL(vtd_alloc_coherent);
-
-void
-vtd_free_coherent(struct device *dev, size_t size, void *vaddr,
-		 dma_addr_t dma_handle)
-{
-	intel_free_coherent(dev, size, vaddr, dma_handle);
-}
-EXPORT_SYMBOL_GPL(vtd_free_coherent);
-
-dma_addr_t
-vtd_map_single_attrs(struct device *dev, void *addr, size_t size,
-		     int dir, struct dma_attrs *attrs)
-{
-	return intel_map_single(dev, (phys_addr_t)addr, size, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_map_single_attrs);
-
-void
-vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
-		       int dir, struct dma_attrs *attrs)
-{
-	intel_unmap_single(dev, iova, size, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_unmap_single_attrs);
-
-int
-vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
-		 int dir, struct dma_attrs *attrs)
-{
-	return intel_map_sg(dev, sglist, nents, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_map_sg_attrs);
-
-void
-vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
-		   int nents, int dir, struct dma_attrs *attrs)
-{
-	intel_unmap_sg(dev, sglist, nents, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_unmap_sg_attrs);
-
-int
-vtd_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-EXPORT_SYMBOL_GPL(vtd_dma_mapping_error);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/dig/Makefile linux-libre-2.6.30-gnu1/arch/ia64/dig/Makefile
--- linux-libre-2.6.29-gnu1/arch/ia64/dig/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/dig/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,8 +7,8 @@
 
 obj-y := setup.o
 ifeq ($(CONFIG_DMAR), y)
-obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o dig_vtd_iommu.o
+obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o
 else
 obj-$(CONFIG_IA64_GENERIC) += machvec.o
 endif
-obj-$(CONFIG_IA64_DIG_VTD) += dig_vtd_iommu.o
+
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/hp/common/hwsw_iommu.c linux-libre-2.6.30-gnu1/arch/ia64/hp/common/hwsw_iommu.c
--- linux-libre-2.6.29-gnu1/arch/ia64/hp/common/hwsw_iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/hp/common/hwsw_iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,49 +13,34 @@
  */
 
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
 #include <linux/swiotlb.h>
-
 #include <asm/machvec.h>
 
+extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
+
 /* swiotlb declarations & definitions: */
 extern int swiotlb_late_init_with_default_size (size_t size);
 
-/* hwiommu declarations & definitions: */
-
-extern ia64_mv_dma_alloc_coherent	sba_alloc_coherent;
-extern ia64_mv_dma_free_coherent	sba_free_coherent;
-extern ia64_mv_dma_map_single_attrs	sba_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs	sba_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs		sba_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs	sba_unmap_sg_attrs;
-extern ia64_mv_dma_supported		sba_dma_supported;
-extern ia64_mv_dma_mapping_error	sba_dma_mapping_error;
-
-#define hwiommu_alloc_coherent		sba_alloc_coherent
-#define hwiommu_free_coherent		sba_free_coherent
-#define hwiommu_map_single_attrs	sba_map_single_attrs
-#define hwiommu_unmap_single_attrs	sba_unmap_single_attrs
-#define hwiommu_map_sg_attrs		sba_map_sg_attrs
-#define hwiommu_unmap_sg_attrs		sba_unmap_sg_attrs
-#define hwiommu_dma_supported		sba_dma_supported
-#define hwiommu_dma_mapping_error	sba_dma_mapping_error
-#define hwiommu_sync_single_for_cpu	machvec_dma_sync_single
-#define hwiommu_sync_sg_for_cpu		machvec_dma_sync_sg
-#define hwiommu_sync_single_for_device	machvec_dma_sync_single
-#define hwiommu_sync_sg_for_device	machvec_dma_sync_sg
-
-
 /*
  * Note: we need to make the determination of whether or not to use
  * the sw I/O TLB based purely on the device structure.  Anything else
  * would be unreliable or would be too intrusive.
  */
-static inline int
-use_swiotlb (struct device *dev)
+static inline int use_swiotlb(struct device *dev)
 {
-	return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
+	return dev && dev->dma_mask &&
+		!sba_dma_ops.dma_supported(dev, *dev->dma_mask);
 }
 
+struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
+{
+	if (use_swiotlb(dev))
+		return &swiotlb_dma_ops;
+	return &sba_dma_ops;
+}
+EXPORT_SYMBOL(hwsw_dma_get_ops);
+
 void __init
 hwsw_init (void)
 {
@@ -71,125 +56,3 @@ hwsw_init (void)
 #endif
 	}
 }
-
-void *
-hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
-{
-	if (use_swiotlb(dev))
-		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
-	else
-		return hwiommu_alloc_coherent(dev, size, dma_handle, flags);
-}
-
-void
-hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
-{
-	if (use_swiotlb(dev))
-		swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-	else
-		hwiommu_free_coherent(dev, size, vaddr, dma_handle);
-}
-
-dma_addr_t
-hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir,
-		       struct dma_attrs *attrs)
-{
-	if (use_swiotlb(dev))
-		return swiotlb_map_single_attrs(dev, addr, size, dir, attrs);
-	else
-		return hwiommu_map_single_attrs(dev, addr, size, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_map_single_attrs);
-
-void
-hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
-			 int dir, struct dma_attrs *attrs)
-{
-	if (use_swiotlb(dev))
-		return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs);
-	else
-		return hwiommu_unmap_single_attrs(dev, iova, size, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_unmap_single_attrs);
-
-int
-hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
-		   int dir, struct dma_attrs *attrs)
-{
-	if (use_swiotlb(dev))
-		return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs);
-	else
-		return hwiommu_map_sg_attrs(dev, sglist, nents, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_map_sg_attrs);
-
-void
-hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
-		     int dir, struct dma_attrs *attrs)
-{
-	if (use_swiotlb(dev))
-		return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
-	else
-		return hwiommu_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_unmap_sg_attrs);
-
-void
-hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir)
-{
-	if (use_swiotlb(dev))
-		swiotlb_sync_single_for_cpu(dev, addr, size, dir);
-	else
-		hwiommu_sync_single_for_cpu(dev, addr, size, dir);
-}
-
-void
-hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir)
-{
-	if (use_swiotlb(dev))
-		swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir);
-	else
-		hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
-
-void
-hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir)
-{
-	if (use_swiotlb(dev))
-		swiotlb_sync_single_for_device(dev, addr, size, dir);
-	else
-		hwiommu_sync_single_for_device(dev, addr, size, dir);
-}
-
-void
-hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir)
-{
-	if (use_swiotlb(dev))
-		swiotlb_sync_sg_for_device(dev, sg, nelems, dir);
-	else
-		hwiommu_sync_sg_for_device(dev, sg, nelems, dir);
-}
-
-int
-hwsw_dma_supported (struct device *dev, u64 mask)
-{
-	if (hwiommu_dma_supported(dev, mask))
-		return 1;
-	return swiotlb_dma_supported(dev, mask);
-}
-
-int
-hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return hwiommu_dma_mapping_error(dev, dma_addr) ||
-		swiotlb_dma_mapping_error(dev, dma_addr);
-}
-
-EXPORT_SYMBOL(hwsw_dma_mapping_error);
-EXPORT_SYMBOL(hwsw_dma_supported);
-EXPORT_SYMBOL(hwsw_alloc_coherent);
-EXPORT_SYMBOL(hwsw_free_coherent);
-EXPORT_SYMBOL(hwsw_sync_single_for_cpu);
-EXPORT_SYMBOL(hwsw_sync_single_for_device);
-EXPORT_SYMBOL(hwsw_sync_sg_for_cpu);
-EXPORT_SYMBOL(hwsw_sync_sg_for_device);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/hp/common/sba_iommu.c linux-libre-2.6.30-gnu1/arch/ia64/hp/common/sba_iommu.c
--- linux-libre-2.6.29-gnu1/arch/ia64/hp/common/sba_iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/hp/common/sba_iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/bitops.h>         /* hweight64() */
 #include <linux/crash_dump.h>
 #include <linux/iommu-helper.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/delay.h>		/* ia64_get_itc() */
 #include <asm/io.h>
@@ -908,11 +909,13 @@ sba_mark_invalid(struct ioc *ioc, dma_ad
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-dma_addr_t
-sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir,
-		     struct dma_attrs *attrs)
+static dma_addr_t sba_map_page(struct device *dev, struct page *page,
+			       unsigned long poff, size_t size,
+			       enum dma_data_direction dir,
+			       struct dma_attrs *attrs)
 {
 	struct ioc *ioc;
+	void *addr = page_address(page) + poff;
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
@@ -990,7 +993,14 @@ sba_map_single_attrs(struct device *dev,
 #endif
 	return SBA_IOVA(ioc, iovp, offset);
 }
-EXPORT_SYMBOL(sba_map_single_attrs);
+
+static dma_addr_t sba_map_single_attrs(struct device *dev, void *addr,
+				       size_t size, enum dma_data_direction dir,
+				       struct dma_attrs *attrs)
+{
+	return sba_map_page(dev, virt_to_page(addr),
+			    (unsigned long)addr & ~PAGE_MASK, size, dir, attrs);
+}
 
 #ifdef ENABLE_MARK_CLEAN
 static SBA_INLINE void
@@ -1026,8 +1036,8 @@ sba_mark_clean(struct ioc *ioc, dma_addr
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
-			    int dir, struct dma_attrs *attrs)
+static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
+			   enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	struct ioc *ioc;
 #if DELAYED_RESOURCE_CNT > 0
@@ -1094,7 +1104,12 @@ void sba_unmap_single_attrs(struct devic
 	spin_unlock_irqrestore(&ioc->res_lock, flags);
 #endif /* DELAYED_RESOURCE_CNT == 0 */
 }
-EXPORT_SYMBOL(sba_unmap_single_attrs);
+
+void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
+			    enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+	sba_unmap_page(dev, iova, size, dir, attrs);
+}
 
 /**
  * sba_alloc_coherent - allocate/map shared mem for DMA
@@ -1104,7 +1119,7 @@ EXPORT_SYMBOL(sba_unmap_single_attrs);
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-void *
+static void *
 sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
 {
 	struct ioc *ioc;
@@ -1167,7 +1182,8 @@ sba_alloc_coherent (struct device *dev,
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void sba_free_coherent (struct device *dev, size_t size, void *vaddr,
+			       dma_addr_t dma_handle)
 {
 	sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL);
 	free_pages((unsigned long) vaddr, get_order(size));
@@ -1422,8 +1438,9 @@ sba_coalesce_chunks(struct ioc *ioc, str
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
-		     int dir, struct dma_attrs *attrs)
+static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist,
+			    int nents, enum dma_data_direction dir,
+			    struct dma_attrs *attrs)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
@@ -1502,7 +1519,6 @@ int sba_map_sg_attrs(struct device *dev,
 
 	return filled;
 }
-EXPORT_SYMBOL(sba_map_sg_attrs);
 
 /**
  * sba_unmap_sg_attrs - unmap Scatter/Gather list
@@ -1514,8 +1530,9 @@ EXPORT_SYMBOL(sba_map_sg_attrs);
  *
  * See Documentation/PCI/PCI-DMA-mapping.txt
  */
-void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
-			int nents, int dir, struct dma_attrs *attrs)
+static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
+			       int nents, enum dma_data_direction dir,
+			       struct dma_attrs *attrs)
 {
 #ifdef ASSERT_PDIR_SANITY
 	struct ioc *ioc;
@@ -1551,7 +1568,6 @@ void sba_unmap_sg_attrs(struct device *d
 #endif
 
 }
-EXPORT_SYMBOL(sba_unmap_sg_attrs);
 
 /**************************************************************
 *
@@ -2064,6 +2080,8 @@ static struct acpi_driver acpi_sba_ioc_d
 	},
 };
 
+extern struct dma_map_ops swiotlb_dma_ops;
+
 static int __init
 sba_init(void)
 {
@@ -2077,6 +2095,7 @@ sba_init(void)
 	 * a successful kdump kernel boot is to use the swiotlb.
 	 */
 	if (is_kdump_kernel()) {
+		dma_ops = &swiotlb_dma_ops;
 		if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
 			panic("Unable to initialize software I/O TLB:"
 				  " Try machvec=dig boot option");
@@ -2092,6 +2111,7 @@ sba_init(void)
 		 * If we didn't find something sba_iommu can claim, we
 		 * need to setup the swiotlb and switch to the dig machvec.
 		 */
+		dma_ops = &swiotlb_dma_ops;
 		if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
 			panic("Unable to find SBA IOMMU or initialize "
 			      "software I/O TLB: Try machvec=dig boot option");
@@ -2138,15 +2158,13 @@ nosbagart(char *str)
 	return 1;
 }
 
-int
-sba_dma_supported (struct device *dev, u64 mask)
+static int sba_dma_supported (struct device *dev, u64 mask)
 {
 	/* make sure it's at least 32bit capable */
 	return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
 }
 
-int
-sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static int sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return 0;
 }
@@ -2176,7 +2194,22 @@ sba_page_override(char *str)
 
 __setup("sbapagesize=",sba_page_override);
 
-EXPORT_SYMBOL(sba_dma_mapping_error);
-EXPORT_SYMBOL(sba_dma_supported);
-EXPORT_SYMBOL(sba_alloc_coherent);
-EXPORT_SYMBOL(sba_free_coherent);
+struct dma_map_ops sba_dma_ops = {
+	.alloc_coherent		= sba_alloc_coherent,
+	.free_coherent		= sba_free_coherent,
+	.map_page		= sba_map_page,
+	.unmap_page		= sba_unmap_page,
+	.map_sg			= sba_map_sg_attrs,
+	.unmap_sg		= sba_unmap_sg_attrs,
+	.sync_single_for_cpu	= machvec_dma_sync_single,
+	.sync_sg_for_cpu	= machvec_dma_sync_sg,
+	.sync_single_for_device	= machvec_dma_sync_single,
+	.sync_sg_for_device	= machvec_dma_sync_sg,
+	.dma_supported		= sba_dma_supported,
+	.mapping_error		= sba_dma_mapping_error,
+};
+
+void sba_dma_init(void)
+{
+	dma_ops = &sba_dma_ops;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/hp/sim/simserial.c linux-libre-2.6.30-gnu1/arch/ia64/hp/sim/simserial.c
--- linux-libre-2.6.29-gnu1/arch/ia64/hp/sim/simserial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/hp/sim/simserial.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/major.h>
 #include <linux/fcntl.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/capability.h>
 #include <linux/console.h>
@@ -848,38 +849,36 @@ static int rs_open(struct tty_struct *tt
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
 {
-	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+	seq_printf(m, "%d: uart:%s port:%lX irq:%d\n",
 		       state->line, uart_config[state->type].name,
 		       state->port, state->irq);
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int i, len = 0, l;
-	off_t	begin = 0;
+	int i;
 
-	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
-	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		l = line_info(page + len, &rs_table[i]);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (begin-off);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS; i++)
+		line_info(m, &rs_table[i]);
+	return 0;
 }
 
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * ---------------------------------------------------------------------
  * rs_init() and friends
@@ -917,7 +916,7 @@ static const struct tty_operations hp_op
 	.start = rs_start,
 	.hangup = rs_hangup,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc,
+	.proc_fops = &rs_proc_fops,
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/ia32/ia32_entry.S linux-libre-2.6.30-gnu1/arch/ia64/ia32/ia32_entry.S
--- linux-libre-2.6.29-gnu1/arch/ia64/ia32/ia32_entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/ia32/ia32_entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -240,7 +240,7 @@ ia32_syscall_table:
 	data8 sys_ni_syscall
 	data8 sys_umask		  /* 60 */
 	data8 sys_chroot
-	data8 sys_ustat
+	data8 compat_sys_ustat
 	data8 sys_dup2
 	data8 sys_getppid
 	data8 sys_getpgrp	  /* 65 */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,99 +11,128 @@
 
 #define ARCH_HAS_DMA_GET_REQUIRED_MASK
 
-struct dma_mapping_ops {
-	int             (*mapping_error)(struct device *dev,
-					 dma_addr_t dma_addr);
-	void*           (*alloc_coherent)(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t gfp);
-	void            (*free_coherent)(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle);
-	dma_addr_t      (*map_single)(struct device *hwdev, unsigned long ptr,
-				size_t size, int direction);
-	void            (*unmap_single)(struct device *dev, dma_addr_t addr,
-				size_t size, int direction);
-	void            (*sync_single_for_cpu)(struct device *hwdev,
-				dma_addr_t dma_handle, size_t size,
-				int direction);
-	void            (*sync_single_for_device)(struct device *hwdev,
-				dma_addr_t dma_handle, size_t size,
-				int direction);
-	void            (*sync_single_range_for_cpu)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size, int direction);
-	void            (*sync_single_range_for_device)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size, int direction);
-	void            (*sync_sg_for_cpu)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				int direction);
-	void            (*sync_sg_for_device)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				int direction);
-	int             (*map_sg)(struct device *hwdev, struct scatterlist *sg,
-				int nents, int direction);
-	void            (*unmap_sg)(struct device *hwdev,
-				struct scatterlist *sg, int nents,
-				int direction);
-	int             (*dma_supported_op)(struct device *hwdev, u64 mask);
-	int		is_phys;
-};
-
-extern struct dma_mapping_ops *dma_ops;
+extern struct dma_map_ops *dma_ops;
 extern struct ia64_machine_vector ia64_mv;
 extern void set_iommu_machvec(void);
 
-#define dma_alloc_coherent(dev, size, handle, gfp)	\
-	platform_dma_alloc_coherent(dev, size, handle, (gfp) | GFP_DMA)
+extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
+				    enum dma_data_direction);
+extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
+				enum dma_data_direction);
 
-/* coherent mem. is cheap */
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		      gfp_t flag)
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *daddr, gfp_t gfp)
 {
-	return dma_alloc_coherent(dev, size, dma_handle, flag);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->alloc_coherent(dev, size, daddr, gfp);
 }
-#define dma_free_coherent	platform_dma_free_coherent
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
-		     dma_addr_t dma_handle)
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *caddr, dma_addr_t daddr)
 {
-	dma_free_coherent(dev, size, cpu_addr, dma_handle);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->free_coherent(dev, size, caddr, daddr);
 }
-#define dma_map_single_attrs	platform_dma_map_single_attrs
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
-					size_t size, int 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)
+
+static inline dma_addr_t dma_map_single_attrs(struct device *dev,
+					      void *caddr, size_t size,
+					      enum dma_data_direction dir,
+					      struct dma_attrs *attrs)
 {
-	return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->map_page(dev, virt_to_page(caddr),
+			     (unsigned long)caddr & ~PAGE_MASK, size,
+			     dir, attrs);
 }
-#define dma_map_sg_attrs	platform_dma_map_sg_attrs
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl,
-			     int nents, int dir)
+
+static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t daddr,
+					  size_t size,
+					  enum dma_data_direction dir,
+					  struct dma_attrs *attrs)
 {
-	return dma_map_sg_attrs(dev, sgl, nents, dir, NULL);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->unmap_page(dev, daddr, size, dir, attrs);
 }
-#define dma_unmap_single_attrs	platform_dma_unmap_single_attrs
-static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr,
-				    size_t size, int dir)
+
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
+
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
+				   int nents, enum dma_data_direction dir,
+				   struct dma_attrs *attrs)
 {
-	return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->map_sg(dev, sgl, nents, dir, attrs);
 }
-#define dma_unmap_sg_attrs	platform_dma_unmap_sg_attrs
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
-				int nents, int dir)
+
+static inline void dma_unmap_sg_attrs(struct device *dev,
+				      struct scatterlist *sgl, int nents,
+				      enum dma_data_direction dir,
+				      struct dma_attrs *attrs)
 {
-	return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->unmap_sg(dev, sgl, nents, dir, attrs);
 }
-#define dma_sync_single_for_cpu	platform_dma_sync_single_for_cpu
-#define dma_sync_sg_for_cpu	platform_dma_sync_sg_for_cpu
-#define dma_sync_single_for_device platform_dma_sync_single_for_device
-#define dma_sync_sg_for_device	platform_dma_sync_sg_for_device
-#define dma_mapping_error	platform_dma_mapping_error
 
-#define dma_map_page(dev, pg, off, size, dir)				\
-	dma_map_single(dev, page_address(pg) + (off), (size), (dir))
-#define dma_unmap_page(dev, dma_addr, size, dir)			\
-	dma_unmap_single(dev, dma_addr, size, dir)
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t daddr,
+					   size_t size,
+					   enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->sync_single_for_cpu(dev, daddr, size, dir);
+}
+
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+				       struct scatterlist *sgl,
+				       int nents, enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->sync_sg_for_cpu(dev, sgl, nents, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+					      dma_addr_t daddr,
+					      size_t size,
+					      enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->sync_single_for_device(dev, daddr, size, dir);
+}
+
+static inline void dma_sync_sg_for_device(struct device *dev,
+					  struct scatterlist *sgl,
+					  int nents,
+					  enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	ops->sync_sg_for_device(dev, sgl, nents, dir);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->mapping_error(dev, daddr);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+				      size_t offset, size_t size,
+				      enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->map_page(dev, page, offset, size, dir, NULL);
+}
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
+				  size_t size, enum dma_data_direction dir)
+{
+	dma_unmap_single(dev, addr, size, dir);
+}
 
 /*
  * Rest of this file is part of the "Advanced DMA API".  Use at your own risk.
@@ -115,7 +144,11 @@ static inline void dma_unmap_sg(struct d
 #define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir)	\
 	dma_sync_single_for_device(dev, dma_handle, size, dir)
 
-#define dma_supported		platform_dma_supported
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
+	return ops->dma_supported(dev, mask);
+}
 
 static inline int
 dma_set_mask (struct device *dev, u64 mask)
@@ -141,11 +174,4 @@ dma_cache_sync (struct device *dev, void
 
 #define dma_is_consistent(d, h)	(1)	/* all we do is coherent memory... */
 
-static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
-{
-	return dma_ops;
-}
-
-
-
 #endif /* _ASM_IA64_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/fpu.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/fpu.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/fpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/fpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,8 +6,6 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-#include <asm/types.h>
-
 /* floating point status register: */
 #define FPSR_TRAP_VD	(1 << 0)	/* invalid op trap disabled */
 #define FPSR_TRAP_DD	(1 << 1)	/* denormal trap disabled */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+#ifndef _ASM_IA64_FTRACE_H
+#define _ASM_IA64_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+#define MCOUNT_INSN_SIZE        32 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+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)
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+	/* second bundle, insn 2 */
+	return addr - 0x12;
+}
+
+struct dyn_arch_ftrace {
+};
+#endif
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#endif /* _ASM_IA64_FTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/gcc_intrin.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/gcc_intrin.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/gcc_intrin.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/gcc_intrin.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@
  * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
  */
 
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 /* define this macro to get some asm stmts included in 'c' files */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/hardirq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,16 +20,6 @@
 
 #define local_softirq_pending()		(local_cpu_data->softirq_pending)
 
-#define HARDIRQ_BITS	14
-
-/*
- * The hardirq mask has to be large enough to have space for potentially all IRQ sources
- * in the system nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
 extern void __iomem *ipi_base_addr;
 
 void ack_bad_irq(unsigned int irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/idle.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/idle.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/idle.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/idle.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _ASM_IA64_IDLE_H
+#define _ASM_IA64_IDLE_H
+
+static inline void enter_idle(void) { }
+static inline void exit_idle(void) { }
+
+#endif /* _ASM_IA64_IDLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/intrinsics.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/intrinsics.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/intrinsics.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/intrinsics.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/types.h>
 /* include compiler specific intrinsics */
 #include <asm/ia64regs.h>
 #ifdef __INTEL_COMPILER
@@ -201,7 +202,11 @@ extern long ia64_cmpxchg_called_with_bad
 
 #ifndef __ASSEMBLY__
 #if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
-#define IA64_INTRINSIC_API(name)	pv_cpu_ops.name
+#ifdef ASM_SUPPORTED
+# define IA64_INTRINSIC_API(name)	paravirt_ ## name
+#else
+# define IA64_INTRINSIC_API(name)	pv_cpu_ops.name
+#endif
 #define IA64_INTRINSIC_MACRO(name)	paravirt_ ## name
 #else
 #define IA64_INTRINSIC_API(name)	ia64_native_ ## name
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/kvm.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/kvm.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/kvm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/kvm.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,8 +21,7 @@
  *
  */
 
-#include <asm/types.h>
-
+#include <linux/types.h>
 #include <linux/ioctl.h>
 
 /* Select x86 specific features in <linux/kvm.h> */
@@ -166,7 +165,40 @@ struct saved_vpd {
 	unsigned long  vcpuid[5];
 	unsigned long  vpsr;
 	unsigned long  vpr;
-	unsigned long  vcr[128];
+	union {
+		unsigned long  vcr[128];
+		struct {
+			unsigned long dcr;
+			unsigned long itm;
+			unsigned long iva;
+			unsigned long rsv1[5];
+			unsigned long pta;
+			unsigned long rsv2[7];
+			unsigned long ipsr;
+			unsigned long isr;
+			unsigned long rsv3;
+			unsigned long iip;
+			unsigned long ifa;
+			unsigned long itir;
+			unsigned long iipa;
+			unsigned long ifs;
+			unsigned long iim;
+			unsigned long iha;
+			unsigned long rsv4[38];
+			unsigned long lid;
+			unsigned long ivr;
+			unsigned long tpr;
+			unsigned long eoi;
+			unsigned long irr[4];
+			unsigned long itv;
+			unsigned long pmv;
+			unsigned long cmcv;
+			unsigned long rsv5[5];
+			unsigned long lrr0;
+			unsigned long lrr1;
+			unsigned long rsv6[46];
+		};
+	};
 };
 
 struct kvm_regs {
@@ -214,4 +246,18 @@ struct kvm_sregs {
 struct kvm_fpu {
 };
 
+#define KVM_IA64_VCPU_STACK_SHIFT	16
+#define KVM_IA64_VCPU_STACK_SIZE	(1UL << KVM_IA64_VCPU_STACK_SHIFT)
+
+struct kvm_ia64_vcpu_stack {
+	unsigned char stack[KVM_IA64_VCPU_STACK_SIZE];
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/kvm_host.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/kvm_host.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/kvm_host.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,11 @@
 #define VCPU_STRUCT_SHIFT	16
 #define VCPU_STRUCT_SIZE	(__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT)
 
-#define KVM_STK_OFFSET		VCPU_STRUCT_SIZE
+/*
+ * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h
+ */
+#define KVM_STK_SHIFT		16
+#define KVM_STK_OFFSET		(__IA64_UL_CONST(1)<< KVM_STK_SHIFT)
 
 #define KVM_VM_STRUCT_SHIFT	19
 #define KVM_VM_STRUCT_SIZE	(__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT)
@@ -153,10 +157,10 @@ struct kvm_vm_data {
 	struct kvm_vcpu_data vcpu_data[KVM_MAX_VCPUS];
 };
 
-#define VCPU_BASE(n)	KVM_VM_DATA_BASE + \
-				offsetof(struct kvm_vm_data, vcpu_data[n])
-#define VM_BASE		KVM_VM_DATA_BASE + \
-				offsetof(struct kvm_vm_data, kvm_vm_struct)
+#define VCPU_BASE(n)	(KVM_VM_DATA_BASE + \
+				offsetof(struct kvm_vm_data, vcpu_data[n]))
+#define KVM_VM_BASE	(KVM_VM_DATA_BASE + \
+				offsetof(struct kvm_vm_data, kvm_vm_struct))
 #define KVM_MEM_DIRTY_LOG_BASE	KVM_VM_DATA_BASE + \
 				offsetof(struct kvm_vm_data, kvm_mem_dirty_log)
 
@@ -235,8 +239,6 @@ struct kvm_vm_data {
 
 struct kvm;
 struct kvm_vcpu;
-struct kvm_guest_debug{
-};
 
 struct kvm_mmio_req {
 	uint64_t addr;          /*  physical address		*/
@@ -462,6 +464,8 @@ struct kvm_arch {
 	unsigned long	metaphysical_rr4;
 	unsigned long	vmm_init_rr;
 
+	int		online_vcpus;
+
 	struct kvm_ioapic *vioapic;
 	struct kvm_vm_stat stat;
 	struct kvm_sal_data rdv_sal_data;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_dig_vtd.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_dig_vtd.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_dig_vtd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_dig_vtd.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,14 +2,6 @@
 #define _ASM_IA64_MACHVEC_DIG_VTD_h
 
 extern ia64_mv_setup_t			dig_setup;
-extern ia64_mv_dma_alloc_coherent	vtd_alloc_coherent;
-extern ia64_mv_dma_free_coherent	vtd_free_coherent;
-extern ia64_mv_dma_map_single_attrs	vtd_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs	vtd_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs		vtd_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs	vtd_unmap_sg_attrs;
-extern ia64_mv_dma_supported		iommu_dma_supported;
-extern ia64_mv_dma_mapping_error	vtd_dma_mapping_error;
 extern ia64_mv_dma_init			pci_iommu_alloc;
 
 /*
@@ -22,17 +14,5 @@ extern ia64_mv_dma_init			pci_iommu_allo
 #define platform_name				"dig_vtd"
 #define platform_setup				dig_setup
 #define platform_dma_init			pci_iommu_alloc
-#define platform_dma_alloc_coherent		vtd_alloc_coherent
-#define platform_dma_free_coherent		vtd_free_coherent
-#define platform_dma_map_single_attrs		vtd_map_single_attrs
-#define platform_dma_unmap_single_attrs		vtd_unmap_single_attrs
-#define platform_dma_map_sg_attrs		vtd_map_sg_attrs
-#define platform_dma_unmap_sg_attrs		vtd_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu	machvec_dma_sync_single
-#define platform_dma_sync_sg_for_cpu		machvec_dma_sync_sg
-#define platform_dma_sync_single_for_device	machvec_dma_sync_single
-#define platform_dma_sync_sg_for_device		machvec_dma_sync_sg
-#define platform_dma_supported			iommu_dma_supported
-#define platform_dma_mapping_error		vtd_dma_mapping_error
 
 #endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,6 @@
 #define _ASM_IA64_MACHVEC_H
 
 #include <linux/types.h>
-#include <linux/swiotlb.h>
 
 /* forward declarations: */
 struct device;
@@ -45,24 +44,8 @@ typedef void ia64_mv_kernel_launch_event
 
 /* DMA-mapping interface: */
 typedef void ia64_mv_dma_init (void);
-typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t);
-typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t);
-typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int);
-typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int);
-typedef int ia64_mv_dma_map_sg (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_unmap_sg (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_t, int);
-typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int);
-typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int);
-typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr);
-typedef int ia64_mv_dma_supported (struct device *, u64);
-
-typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *);
-typedef void ia64_mv_dma_unmap_single_attrs (struct device *, dma_addr_t, size_t, int, struct dma_attrs *);
-typedef int ia64_mv_dma_map_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *);
-typedef void ia64_mv_dma_unmap_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *);
 typedef u64 ia64_mv_dma_get_required_mask (struct device *);
+typedef struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
 
 /*
  * WARNING: The legacy I/O space is _architected_.  Platforms are
@@ -114,8 +97,6 @@ machvec_noop_bus (struct pci_bus *bus)
 
 extern void machvec_setup (char **);
 extern void machvec_timer_interrupt (int, void *);
-extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int);
-extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int);
 extern void machvec_tlb_migrate_finish (struct mm_struct *);
 
 # if defined (CONFIG_IA64_HP_SIM)
@@ -148,19 +129,8 @@ extern void machvec_tlb_migrate_finish (
 #  define platform_global_tlb_purge	ia64_mv.global_tlb_purge
 #  define platform_tlb_migrate_finish	ia64_mv.tlb_migrate_finish
 #  define platform_dma_init		ia64_mv.dma_init
-#  define platform_dma_alloc_coherent	ia64_mv.dma_alloc_coherent
-#  define platform_dma_free_coherent	ia64_mv.dma_free_coherent
-#  define platform_dma_map_single_attrs	ia64_mv.dma_map_single_attrs
-#  define platform_dma_unmap_single_attrs	ia64_mv.dma_unmap_single_attrs
-#  define platform_dma_map_sg_attrs	ia64_mv.dma_map_sg_attrs
-#  define platform_dma_unmap_sg_attrs	ia64_mv.dma_unmap_sg_attrs
-#  define platform_dma_sync_single_for_cpu ia64_mv.dma_sync_single_for_cpu
-#  define platform_dma_sync_sg_for_cpu	ia64_mv.dma_sync_sg_for_cpu
-#  define platform_dma_sync_single_for_device ia64_mv.dma_sync_single_for_device
-#  define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device
-#  define platform_dma_mapping_error		ia64_mv.dma_mapping_error
-#  define platform_dma_supported	ia64_mv.dma_supported
 #  define platform_dma_get_required_mask ia64_mv.dma_get_required_mask
+#  define platform_dma_get_ops		ia64_mv.dma_get_ops
 #  define platform_irq_to_vector	ia64_mv.irq_to_vector
 #  define platform_local_vector_to_irq	ia64_mv.local_vector_to_irq
 #  define platform_pci_get_legacy_mem	ia64_mv.pci_get_legacy_mem
@@ -203,19 +173,8 @@ struct ia64_machine_vector {
 	ia64_mv_global_tlb_purge_t *global_tlb_purge;
 	ia64_mv_tlb_migrate_finish_t *tlb_migrate_finish;
 	ia64_mv_dma_init *dma_init;
-	ia64_mv_dma_alloc_coherent *dma_alloc_coherent;
-	ia64_mv_dma_free_coherent *dma_free_coherent;
-	ia64_mv_dma_map_single_attrs *dma_map_single_attrs;
-	ia64_mv_dma_unmap_single_attrs *dma_unmap_single_attrs;
-	ia64_mv_dma_map_sg_attrs *dma_map_sg_attrs;
-	ia64_mv_dma_unmap_sg_attrs *dma_unmap_sg_attrs;
-	ia64_mv_dma_sync_single_for_cpu *dma_sync_single_for_cpu;
-	ia64_mv_dma_sync_sg_for_cpu *dma_sync_sg_for_cpu;
-	ia64_mv_dma_sync_single_for_device *dma_sync_single_for_device;
-	ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device;
-	ia64_mv_dma_mapping_error *dma_mapping_error;
-	ia64_mv_dma_supported *dma_supported;
 	ia64_mv_dma_get_required_mask *dma_get_required_mask;
+	ia64_mv_dma_get_ops *dma_get_ops;
 	ia64_mv_irq_to_vector *irq_to_vector;
 	ia64_mv_local_vector_to_irq *local_vector_to_irq;
 	ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
@@ -254,19 +213,8 @@ struct ia64_machine_vector {
 	platform_global_tlb_purge,		\
 	platform_tlb_migrate_finish,		\
 	platform_dma_init,			\
-	platform_dma_alloc_coherent,		\
-	platform_dma_free_coherent,		\
-	platform_dma_map_single_attrs,		\
-	platform_dma_unmap_single_attrs,	\
-	platform_dma_map_sg_attrs,		\
-	platform_dma_unmap_sg_attrs,		\
-	platform_dma_sync_single_for_cpu,	\
-	platform_dma_sync_sg_for_cpu,		\
-	platform_dma_sync_single_for_device,	\
-	platform_dma_sync_sg_for_device,	\
-	platform_dma_mapping_error,			\
-	platform_dma_supported,			\
 	platform_dma_get_required_mask,		\
+	platform_dma_get_ops,			\
 	platform_irq_to_vector,			\
 	platform_local_vector_to_irq,		\
 	platform_pci_get_legacy_mem,		\
@@ -302,6 +250,9 @@ extern void machvec_init_from_cmdline(co
 #  error Unknown configuration.  Update arch/ia64/include/asm/machvec.h.
 # endif /* CONFIG_IA64_GENERIC */
 
+extern void swiotlb_dma_init(void);
+extern struct dma_map_ops *dma_get_ops(struct device *);
+
 /*
  * Define default versions so we can extend machvec for new platforms without having
  * to update the machvec files for all existing platforms.
@@ -332,43 +283,10 @@ extern void machvec_init_from_cmdline(co
 # define platform_kernel_launch_event	machvec_noop
 #endif
 #ifndef platform_dma_init
-# define platform_dma_init		swiotlb_init
-#endif
-#ifndef platform_dma_alloc_coherent
-# define platform_dma_alloc_coherent	swiotlb_alloc_coherent
-#endif
-#ifndef platform_dma_free_coherent
-# define platform_dma_free_coherent	swiotlb_free_coherent
-#endif
-#ifndef platform_dma_map_single_attrs
-# define platform_dma_map_single_attrs	swiotlb_map_single_attrs
-#endif
-#ifndef platform_dma_unmap_single_attrs
-# define platform_dma_unmap_single_attrs	swiotlb_unmap_single_attrs
-#endif
-#ifndef platform_dma_map_sg_attrs
-# define platform_dma_map_sg_attrs	swiotlb_map_sg_attrs
-#endif
-#ifndef platform_dma_unmap_sg_attrs
-# define platform_dma_unmap_sg_attrs	swiotlb_unmap_sg_attrs
-#endif
-#ifndef platform_dma_sync_single_for_cpu
-# define platform_dma_sync_single_for_cpu	swiotlb_sync_single_for_cpu
-#endif
-#ifndef platform_dma_sync_sg_for_cpu
-# define platform_dma_sync_sg_for_cpu		swiotlb_sync_sg_for_cpu
-#endif
-#ifndef platform_dma_sync_single_for_device
-# define platform_dma_sync_single_for_device	swiotlb_sync_single_for_device
-#endif
-#ifndef platform_dma_sync_sg_for_device
-# define platform_dma_sync_sg_for_device	swiotlb_sync_sg_for_device
-#endif
-#ifndef platform_dma_mapping_error
-# define platform_dma_mapping_error		swiotlb_dma_mapping_error
+# define platform_dma_init		swiotlb_dma_init
 #endif
-#ifndef platform_dma_supported
-# define  platform_dma_supported	swiotlb_dma_supported
+#ifndef platform_dma_get_ops
+# define platform_dma_get_ops		dma_get_ops
 #endif
 #ifndef platform_dma_get_required_mask
 # define  platform_dma_get_required_mask	ia64_dma_get_required_mask
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_hpzx1.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_hpzx1.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_hpzx1.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_hpzx1.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,14 +2,7 @@
 #define _ASM_IA64_MACHVEC_HPZX1_h
 
 extern ia64_mv_setup_t			dig_setup;
-extern ia64_mv_dma_alloc_coherent	sba_alloc_coherent;
-extern ia64_mv_dma_free_coherent	sba_free_coherent;
-extern ia64_mv_dma_map_single_attrs	sba_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs	sba_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs		sba_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs	sba_unmap_sg_attrs;
-extern ia64_mv_dma_supported		sba_dma_supported;
-extern ia64_mv_dma_mapping_error	sba_dma_mapping_error;
+extern ia64_mv_dma_init			sba_dma_init;
 
 /*
  * This stuff has dual use!
@@ -20,18 +13,6 @@ extern ia64_mv_dma_mapping_error	sba_dma
  */
 #define platform_name				"hpzx1"
 #define platform_setup				dig_setup
-#define platform_dma_init			machvec_noop
-#define platform_dma_alloc_coherent		sba_alloc_coherent
-#define platform_dma_free_coherent		sba_free_coherent
-#define platform_dma_map_single_attrs		sba_map_single_attrs
-#define platform_dma_unmap_single_attrs		sba_unmap_single_attrs
-#define platform_dma_map_sg_attrs		sba_map_sg_attrs
-#define platform_dma_unmap_sg_attrs		sba_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu	machvec_dma_sync_single
-#define platform_dma_sync_sg_for_cpu		machvec_dma_sync_sg
-#define platform_dma_sync_single_for_device	machvec_dma_sync_single
-#define platform_dma_sync_sg_for_device		machvec_dma_sync_sg
-#define platform_dma_supported			sba_dma_supported
-#define platform_dma_mapping_error		sba_dma_mapping_error
+#define platform_dma_init			sba_dma_init
 
 #endif /* _ASM_IA64_MACHVEC_HPZX1_h */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,18 +2,7 @@
 #define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
 
 extern ia64_mv_setup_t				dig_setup;
-extern ia64_mv_dma_alloc_coherent		hwsw_alloc_coherent;
-extern ia64_mv_dma_free_coherent		hwsw_free_coherent;
-extern ia64_mv_dma_map_single_attrs		hwsw_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs		hwsw_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs			hwsw_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs		hwsw_unmap_sg_attrs;
-extern ia64_mv_dma_supported			hwsw_dma_supported;
-extern ia64_mv_dma_mapping_error		hwsw_dma_mapping_error;
-extern ia64_mv_dma_sync_single_for_cpu		hwsw_sync_single_for_cpu;
-extern ia64_mv_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu;
-extern ia64_mv_dma_sync_single_for_device	hwsw_sync_single_for_device;
-extern ia64_mv_dma_sync_sg_for_device		hwsw_sync_sg_for_device;
+extern ia64_mv_dma_get_ops			hwsw_dma_get_ops;
 
 /*
  * This stuff has dual use!
@@ -23,20 +12,8 @@ extern ia64_mv_dma_sync_sg_for_device		h
  * the macros are used directly.
  */
 #define platform_name				"hpzx1_swiotlb"
-
 #define platform_setup				dig_setup
 #define platform_dma_init			machvec_noop
-#define platform_dma_alloc_coherent		hwsw_alloc_coherent
-#define platform_dma_free_coherent		hwsw_free_coherent
-#define platform_dma_map_single_attrs		hwsw_map_single_attrs
-#define platform_dma_unmap_single_attrs		hwsw_unmap_single_attrs
-#define platform_dma_map_sg_attrs		hwsw_map_sg_attrs
-#define platform_dma_unmap_sg_attrs		hwsw_unmap_sg_attrs
-#define platform_dma_supported			hwsw_dma_supported
-#define platform_dma_mapping_error		hwsw_dma_mapping_error
-#define platform_dma_sync_single_for_cpu	hwsw_sync_single_for_cpu
-#define platform_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu
-#define platform_dma_sync_single_for_device	hwsw_sync_single_for_device
-#define platform_dma_sync_sg_for_device		hwsw_sync_sg_for_device
+#define platform_dma_get_ops			hwsw_dma_get_ops
 
 #endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_sn2.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_sn2.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/machvec_sn2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/machvec_sn2.h	2009-06-09 23:05:27.000000000 -0400
@@ -55,19 +55,8 @@ extern ia64_mv_readb_t __sn_readb_relaxe
 extern ia64_mv_readw_t __sn_readw_relaxed;
 extern ia64_mv_readl_t __sn_readl_relaxed;
 extern ia64_mv_readq_t __sn_readq_relaxed;
-extern ia64_mv_dma_alloc_coherent	sn_dma_alloc_coherent;
-extern ia64_mv_dma_free_coherent	sn_dma_free_coherent;
-extern ia64_mv_dma_map_single_attrs	sn_dma_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs	sn_dma_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs		sn_dma_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs	sn_dma_unmap_sg_attrs;
-extern ia64_mv_dma_sync_single_for_cpu	sn_dma_sync_single_for_cpu;
-extern ia64_mv_dma_sync_sg_for_cpu	sn_dma_sync_sg_for_cpu;
-extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device;
-extern ia64_mv_dma_sync_sg_for_device	sn_dma_sync_sg_for_device;
-extern ia64_mv_dma_mapping_error	sn_dma_mapping_error;
-extern ia64_mv_dma_supported		sn_dma_supported;
 extern ia64_mv_dma_get_required_mask	sn_dma_get_required_mask;
+extern ia64_mv_dma_init			sn_dma_init;
 extern ia64_mv_migrate_t		sn_migrate;
 extern ia64_mv_kernel_launch_event_t	sn_kernel_launch_event;
 extern ia64_mv_setup_msi_irq_t		sn_setup_msi_irq;
@@ -111,20 +100,8 @@ extern ia64_mv_pci_fixup_bus_t		sn_pci_f
 #define platform_pci_get_legacy_mem	sn_pci_get_legacy_mem
 #define platform_pci_legacy_read	sn_pci_legacy_read
 #define platform_pci_legacy_write	sn_pci_legacy_write
-#define platform_dma_init		machvec_noop
-#define platform_dma_alloc_coherent	sn_dma_alloc_coherent
-#define platform_dma_free_coherent	sn_dma_free_coherent
-#define platform_dma_map_single_attrs	sn_dma_map_single_attrs
-#define platform_dma_unmap_single_attrs	sn_dma_unmap_single_attrs
-#define platform_dma_map_sg_attrs	sn_dma_map_sg_attrs
-#define platform_dma_unmap_sg_attrs	sn_dma_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu
-#define platform_dma_sync_sg_for_cpu	sn_dma_sync_sg_for_cpu
-#define platform_dma_sync_single_for_device sn_dma_sync_single_for_device
-#define platform_dma_sync_sg_for_device	sn_dma_sync_sg_for_device
-#define platform_dma_mapping_error		sn_dma_mapping_error
-#define platform_dma_supported		sn_dma_supported
 #define platform_dma_get_required_mask	sn_dma_get_required_mask
+#define platform_dma_init		sn_dma_init
 #define platform_migrate		sn_migrate
 #define platform_kernel_launch_event    sn_kernel_launch_event
 #ifdef CONFIG_PCI_MSI
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,7 @@ get_mmu_context (struct mm_struct *mm)
 	/* re-check, now that we've got the lock: */
 	context = mm->context;
 	if (context == 0) {
-		cpus_clear(mm->cpu_vm_mask);
+		cpumask_clear(mm_cpumask(mm));
 		if (ia64_ctx.next >= ia64_ctx.limit) {
 			ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
 					ia64_ctx.max_ctx, ia64_ctx.next);
@@ -166,8 +166,8 @@ activate_context (struct mm_struct *mm)
 
 	do {
 		context = get_mmu_context(mm);
-		if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
-			cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+		if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
+			cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
 		reload_context(context);
 		/*
 		 * in the unlikely event of a TLB-flush by another thread,
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/module.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/module.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,12 @@ struct mod_arch_specific {
 	struct elf64_shdr *got;		/* global offset table */
 	struct elf64_shdr *opd;		/* official procedure descriptors */
 	struct elf64_shdr *unwind;	/* unwind-table section */
+#ifdef CONFIG_PARAVIRT
+	struct elf64_shdr *paravirt_bundles;
+					/* paravirt_alt_bundle_patch table */
+	struct elf64_shdr *paravirt_insts;
+					/* paravirt_alt_inst_patch table */
+#endif
 	unsigned long gp;		/* global-pointer for module */
 
 	void *core_unw_table;		/* core unwind-table cookie returned by unwinder */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/msidef.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/msidef.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/msidef.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/msidef.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+#ifndef _IA64_MSI_DEF_H
+#define _IA64_MSI_DEF_H
+
+/*
+ * Shifts for APIC-based data
+ */
+
+#define     MSI_DATA_VECTOR_SHIFT	0
+#define	    MSI_DATA_VECTOR(v)		(((u8)v) << MSI_DATA_VECTOR_SHIFT)
+#define     MSI_DATA_VECTOR_MASK	0xffffff00
+
+#define     MSI_DATA_DELIVERY_MODE_SHIFT	8
+#define     MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define     MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define     MSI_DATA_LEVEL_SHIFT	14
+#define     MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
+#define     MSI_DATA_LEVEL_ASSERT	(1 << MSI_DATA_LEVEL_SHIFT)
+
+#define     MSI_DATA_TRIGGER_SHIFT	15
+#define     MSI_DATA_TRIGGER_EDGE	(0 << MSI_DATA_TRIGGER_SHIFT)
+#define     MSI_DATA_TRIGGER_LEVEL	(1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for APIC-based bus address
+ */
+
+#define     MSI_ADDR_DEST_ID_SHIFT	4
+#define     MSI_ADDR_HEADER		0xfee00000
+
+#define     MSI_ADDR_DEST_ID_MASK	0xfff0000f
+#define     MSI_ADDR_DEST_ID_CPU(cpu)	((cpu) << MSI_ADDR_DEST_ID_SHIFT)
+
+#define     MSI_ADDR_DEST_MODE_SHIFT	2
+#define     MSI_ADDR_DEST_MODE_PHYS	(0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define	    MSI_ADDR_DEST_MODE_LOGIC	(1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define     MSI_ADDR_REDIRECTION_SHIFT	3
+#define     MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define     MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+#endif/* _IA64_MSI_DEF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/inst.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/inst.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/inst.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/inst.h	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,9 @@
 #define __paravirt_work_processed_syscall_target \
 						ia64_work_processed_syscall
 
+#define paravirt_fsyscall_table			ia64_native_fsyscall_table
+#define paravirt_fsys_bubble_down		ia64_native_fsys_bubble_down
+
 #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
 # define PARAVIRT_POISON	0xdeadbeefbaadf00d
 # define CLOBBER(clob)				\
@@ -74,6 +77,11 @@
 (pred)	mov reg = psr			\
 	CLOBBER(clob)
 
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob)	\
+(pred)	mov reg = ar.itc				\
+	CLOBBER(clob)					\
+	CLOBBER_PRED(pred_clob)
+
 #define MOV_TO_IFA(reg, clob)	\
 	mov cr.ifa = reg	\
 	CLOBBER(clob)
@@ -158,6 +166,11 @@
 #define RSM_PSR_DT		\
 	rsm psr.dt
 
+#define RSM_PSR_BE_I(clob0, clob1)	\
+	rsm psr.be | psr.i		\
+	CLOBBER(clob0)			\
+	CLOBBER(clob1)
+
 #define SSM_PSR_DT_AND_SRLZ_I	\
 	ssm psr.dt		\
 	;;			\
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/patchlist.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/patchlist.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/patchlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/patchlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * arch/ia64/include/asm/native/inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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 __paravirt_start_gate_fsyscall_patchlist		\
+	__ia64_native_start_gate_fsyscall_patchlist
+#define __paravirt_end_gate_fsyscall_patchlist			\
+	__ia64_native_end_gate_fsyscall_patchlist
+#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist	\
+	__ia64_native_start_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist	\
+	__ia64_native_end_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_start_gate_vtop_patchlist			\
+	__ia64_native_start_gate_vtop_patchlist
+#define __paravirt_end_gate_vtop_patchlist			\
+	__ia64_native_end_gate_vtop_patchlist
+#define __paravirt_start_gate_mckinley_e9_patchlist		\
+	__ia64_native_start_gate_mckinley_e9_patchlist
+#define __paravirt_end_gate_mckinley_e9_patchlist		\
+	__ia64_native_end_gate_mckinley_e9_patchlist
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/pvchk_inst.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/pvchk_inst.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/native/pvchk_inst.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/native/pvchk_inst.h	2009-06-09 23:05:27.000000000 -0400
@@ -180,6 +180,11 @@
 	IS_PRED_IN(pred)			\
 	IS_RREG_OUT(reg)			\
 	IS_RREG_CLOB(clob)
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob)	\
+	IS_PRED_IN(pred)				\
+	IS_PRED_CLOB(pred_clob)				\
+	IS_RREG_OUT(reg)				\
+	IS_RREG_CLOB(clob)
 #define MOV_TO_IFA(reg, clob)			\
 	IS_RREG_IN(reg)				\
 	IS_RREG_CLOB(clob)
@@ -246,6 +251,9 @@
 	IS_RREG_CLOB(clob2)
 #define RSM_PSR_DT				\
 	nop 0
+#define RSM_PSR_BE_I(clob0, clob1)		\
+	IS_RREG_CLOB(clob0)			\
+	IS_RREG_CLOB(clob1)
 #define SSM_PSR_DT_AND_SRLZ_I			\
 	nop 0
 #define BSW_0(clob0, clob1, clob2)		\
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,56 @@
 #ifndef __ASM_PARAVIRT_H
 #define __ASM_PARAVIRT_H
 
+#ifndef __ASSEMBLY__
+/******************************************************************************
+ * fsys related addresses
+ */
+struct pv_fsys_data {
+	unsigned long *fsyscall_table;
+	void *fsys_bubble_down;
+};
+
+extern struct pv_fsys_data pv_fsys_data;
+
+unsigned long *paravirt_get_fsyscall_table(void);
+char *paravirt_get_fsys_bubble_down(void);
+
+/******************************************************************************
+ * patchlist addresses for gate page
+ */
+enum pv_gate_patchlist {
+	PV_GATE_START_FSYSCALL,
+	PV_GATE_END_FSYSCALL,
+
+	PV_GATE_START_BRL_FSYS_BUBBLE_DOWN,
+	PV_GATE_END_BRL_FSYS_BUBBLE_DOWN,
+
+	PV_GATE_START_VTOP,
+	PV_GATE_END_VTOP,
+
+	PV_GATE_START_MCKINLEY_E9,
+	PV_GATE_END_MCKINLEY_E9,
+};
+
+struct pv_patchdata {
+	unsigned long start_fsyscall_patchlist;
+	unsigned long end_fsyscall_patchlist;
+	unsigned long start_brl_fsys_bubble_down_patchlist;
+	unsigned long end_brl_fsys_bubble_down_patchlist;
+	unsigned long start_vtop_patchlist;
+	unsigned long end_vtop_patchlist;
+	unsigned long start_mckinley_e9_patchlist;
+	unsigned long end_mckinley_e9_patchlist;
+
+	void *gate_section;
+};
+
+extern struct pv_patchdata pv_patchdata;
+
+unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type);
+void *paravirt_get_gate_section(void);
+#endif
+
 #ifdef CONFIG_PARAVIRT_GUEST
 
 #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT	0
@@ -68,6 +118,14 @@ struct pv_init_ops {
 	int (*arch_setup_nomca)(void);
 
 	void (*post_smp_prepare_boot_cpu)(void);
+
+#ifdef ASM_SUPPORTED
+	unsigned long (*patch_bundle)(void *sbundle, void *ebundle,
+				      unsigned long type);
+	unsigned long (*patch_inst)(unsigned long stag, unsigned long etag,
+				    unsigned long type);
+#endif
+	void (*patch_branch)(unsigned long tag, unsigned long type);
 };
 
 extern struct pv_init_ops pv_init_ops;
@@ -210,6 +268,8 @@ struct pv_time_ops {
 	int (*do_steal_accounting)(unsigned long *new_itm);
 
 	void (*clocksource_resume)(void);
+
+	unsigned long long (*sched_clock)(void);
 };
 
 extern struct pv_time_ops pv_time_ops;
@@ -227,6 +287,11 @@ paravirt_do_steal_accounting(unsigned lo
 	return pv_time_ops.do_steal_accounting(new_itm);
 }
 
+static inline unsigned long long paravirt_sched_clock(void)
+{
+	return pv_time_ops.sched_clock();
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #else
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt_patch.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt_patch.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt_patch.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt_patch.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,143 @@
+/******************************************************************************
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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_PARAVIRT_PATCH_H
+#define __ASM_PARAVIRT_PATCH_H
+
+#ifdef __ASSEMBLY__
+
+	.section .paravirt_branches, "a"
+	.previous
+#define PARAVIRT_PATCH_SITE_BR(type)		\
+	{					\
+	[1:] ;					\
+	br.cond.sptk.many 2f ;			\
+	nop.b 0 ;				\
+	nop.b 0;; ;				\
+	} ;					\
+	2:					\
+	.xdata8 ".paravirt_branches", 1b, type
+
+#else
+
+#include <linux/stringify.h>
+#include <asm/intrinsics.h>
+
+/* for binary patch */
+struct paravirt_patch_site_bundle {
+	void		*sbundle;
+	void		*ebundle;
+	unsigned long	type;
+};
+
+/* label means the beginning of new bundle */
+#define paravirt_alt_bundle(instr, privop)				\
+	"\t998:\n"							\
+	"\t" instr "\n"							\
+	"\t999:\n"							\
+	"\t.pushsection .paravirt_bundles, \"a\"\n"			\
+	"\t.popsection\n"						\
+	"\t.xdata8 \".paravirt_bundles\", 998b, 999b, "			\
+	__stringify(privop) "\n"
+
+
+struct paravirt_patch_bundle_elem {
+	const void	*sbundle;
+	const void	*ebundle;
+	unsigned long	type;
+};
+
+
+struct paravirt_patch_site_inst {
+	unsigned long	stag;
+	unsigned long	etag;
+	unsigned long	type;
+};
+
+#define paravirt_alt_inst(instr, privop)				\
+	"\t[998:]\n"							\
+	"\t" instr "\n"							\
+	"\t[999:]\n"							\
+	"\t.pushsection .paravirt_insts, \"a\"\n"			\
+	"\t.popsection\n"						\
+	"\t.xdata8 \".paravirt_insts\", 998b, 999b, "			\
+	__stringify(privop) "\n"
+
+struct paravirt_patch_site_branch {
+	unsigned long	tag;
+	unsigned long	type;
+};
+
+struct paravirt_patch_branch_target {
+	const void	*entry;
+	unsigned long	type;
+};
+
+void
+__paravirt_patch_apply_branch(
+	unsigned long tag, unsigned long type,
+	const struct paravirt_patch_branch_target *entries,
+	unsigned int nr_entries);
+
+void
+paravirt_patch_reloc_br(unsigned long tag, const void *target);
+
+void
+paravirt_patch_reloc_brl(unsigned long tag, const void *target);
+
+
+#if defined(ASM_SUPPORTED) && defined(CONFIG_PARAVIRT)
+unsigned long
+ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type);
+
+unsigned long
+__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
+			      const struct paravirt_patch_bundle_elem *elems,
+			      unsigned long nelems,
+			      const struct paravirt_patch_bundle_elem **found);
+
+void
+paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
+			    const struct paravirt_patch_site_bundle *end);
+
+void
+paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
+			  const struct paravirt_patch_site_inst *end);
+
+void paravirt_patch_apply(void);
+#else
+#define paravirt_patch_apply_bundle(start, end)	do { } while (0)
+#define paravirt_patch_apply_inst(start, end)	do { } while (0)
+#define paravirt_patch_apply()			do { } while (0)
+#endif
+
+#endif /* !__ASSEMBLEY__ */
+
+#endif /* __ASM_PARAVIRT_PATCH_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "linux"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt_privop.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt_privop.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/paravirt_privop.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/paravirt_privop.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,7 @@
  */
 
 struct pv_cpu_ops {
-	void (*fc)(unsigned long addr);
+	void (*fc)(void *addr);
 	unsigned long (*thash)(unsigned long addr);
 	unsigned long (*get_cpuid)(int index);
 	unsigned long (*get_pmd)(int index);
@@ -60,12 +60,18 @@ extern unsigned long ia64_native_getreg_
 /* Instructions paravirtualized for performance */
 /************************************************/
 
+#ifndef ASM_SUPPORTED
+#define paravirt_ssm_i()	pv_cpu_ops.ssm_i()
+#define paravirt_rsm_i()	pv_cpu_ops.rsm_i()
+#define __paravirt_getreg()	pv_cpu_ops.getreg()
+#endif
+
 /* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
  * static inline function doesn't satisfy it. */
 #define paravirt_ssm(mask)			\
 	do {					\
 		if ((mask) == IA64_PSR_I)	\
-			pv_cpu_ops.ssm_i();	\
+			paravirt_ssm_i();	\
 		else				\
 			ia64_native_ssm(mask);	\
 	} while (0)
@@ -73,7 +79,7 @@ extern unsigned long ia64_native_getreg_
 #define paravirt_rsm(mask)			\
 	do {					\
 		if ((mask) == IA64_PSR_I)	\
-			pv_cpu_ops.rsm_i();	\
+			paravirt_rsm_i();	\
 		else				\
 			ia64_native_rsm(mask);	\
 	} while (0)
@@ -86,7 +92,7 @@ extern unsigned long ia64_native_getreg_
 		if ((reg) == _IA64_REG_IP)			\
 			res = ia64_native_getreg(_IA64_REG_IP); \
 		else						\
-			res = pv_cpu_ops.getreg(reg);		\
+			res = __paravirt_getreg(reg);		\
 		res;						\
 	})
 
@@ -112,6 +118,12 @@ void paravirt_cpu_asm_init(const struct
 
 #endif /* CONFIG_PARAVIRT */
 
+#if defined(CONFIG_PARAVIRT) && defined(ASM_SUPPORTED)
+#define paravirt_dv_serialize_data()	ia64_dv_serialize_data()
+#else
+#define paravirt_dv_serialize_data()	/* nothing */
+#endif
+
 /* these routines utilize privilege-sensitive or performance-sensitive
  * privileged instructions so the code must be replaced with
  * paravirtualized versions */
@@ -121,4 +133,347 @@ void paravirt_cpu_asm_init(const struct
 	IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
 #define ia64_leave_kernel		IA64_PARAVIRT_ASM_FUNC(leave_kernel)
 
+
+#if defined(CONFIG_PARAVIRT)
+/******************************************************************************
+ * binary patching infrastructure
+ */
+#define PARAVIRT_PATCH_TYPE_FC				1
+#define PARAVIRT_PATCH_TYPE_THASH			2
+#define PARAVIRT_PATCH_TYPE_GET_CPUID			3
+#define PARAVIRT_PATCH_TYPE_GET_PMD			4
+#define PARAVIRT_PATCH_TYPE_PTCGA			5
+#define PARAVIRT_PATCH_TYPE_GET_RR			6
+#define PARAVIRT_PATCH_TYPE_SET_RR			7
+#define PARAVIRT_PATCH_TYPE_SET_RR0_TO_RR4		8
+#define PARAVIRT_PATCH_TYPE_SSM_I			9
+#define PARAVIRT_PATCH_TYPE_RSM_I			10
+#define PARAVIRT_PATCH_TYPE_GET_PSR_I			11
+#define PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE	12
+
+/* PARAVIRT_PATY_TYPE_[GS]ETREG + _IA64_REG_xxx */
+#define PARAVIRT_PATCH_TYPE_GETREG			0x10000000
+#define PARAVIRT_PATCH_TYPE_SETREG			0x20000000
+
+/*
+ * struct task_struct* (*ia64_switch_to)(void* next_task);
+ * void *ia64_leave_syscall;
+ * void *ia64_work_processed_syscall
+ * void *ia64_leave_kernel;
+ */
+
+#define PARAVIRT_PATCH_TYPE_BR_START			0x30000000
+#define PARAVIRT_PATCH_TYPE_BR_SWITCH_TO		\
+	(PARAVIRT_PATCH_TYPE_BR_START + 0)
+#define PARAVIRT_PATCH_TYPE_BR_LEAVE_SYSCALL		\
+	(PARAVIRT_PATCH_TYPE_BR_START + 1)
+#define PARAVIRT_PATCH_TYPE_BR_WORK_PROCESSED_SYSCALL	\
+	(PARAVIRT_PATCH_TYPE_BR_START + 2)
+#define PARAVIRT_PATCH_TYPE_BR_LEAVE_KERNEL		\
+	(PARAVIRT_PATCH_TYPE_BR_START + 3)
+
+#ifdef ASM_SUPPORTED
+#include <asm/paravirt_patch.h>
+
+/*
+ * pv_cpu_ops calling stub.
+ * normal function call convension can't be written by gcc
+ * inline assembly.
+ *
+ * from the caller's point of view,
+ * the following registers will be clobbered.
+ * r2, r3
+ * r8-r15
+ * r16, r17
+ * b6, b7
+ * p6-p15
+ * ar.ccv
+ *
+ * from the callee's point of view ,
+ * the following registers can be used.
+ * r2, r3: scratch
+ * r8: scratch, input argument0 and return value
+ * r0-r15: scratch, input argument1-5
+ * b6: return pointer
+ * b7: scratch
+ * p6-p15: scratch
+ * ar.ccv: scratch
+ *
+ * other registers must not be changed. especially
+ * b0: rp: preserved. gcc ignores b0 in clobbered register.
+ * r16: saved gp
+ */
+/* 5 bundles */
+#define __PARAVIRT_BR							\
+	";;\n"								\
+	"{ .mlx\n"							\
+	"nop 0\n"							\
+	"movl r2 = %[op_addr]\n"/* get function pointer address */	\
+	";;\n"								\
+	"}\n"								\
+	"1:\n"								\
+	"{ .mii\n"							\
+	"ld8 r2 = [r2]\n"	/* load function descriptor address */	\
+	"mov r17 = ip\n"	/* get ip to calc return address */	\
+	"mov r16 = gp\n"	/* save gp */				\
+	";;\n"								\
+	"}\n"								\
+	"{ .mii\n"							\
+	"ld8 r3 = [r2], 8\n"	/* load entry address */		\
+	"adds r17 =  1f - 1b, r17\n"	/* calculate return address */	\
+	";;\n"								\
+	"mov b7 = r3\n"		/* set entry address */			\
+	"}\n"								\
+	"{ .mib\n"							\
+	"ld8 gp = [r2]\n"	/* load gp value */			\
+	"mov b6 = r17\n"	/* set return address */		\
+	"br.cond.sptk.few b7\n"	/* intrinsics are very short isns */	\
+	"}\n"								\
+	"1:\n"								\
+	"{ .mii\n"							\
+	"mov gp = r16\n"	/* restore gp value */			\
+	"nop 0\n"							\
+	"nop 0\n"							\
+	";;\n"								\
+	"}\n"
+
+#define PARAVIRT_OP(op)				\
+	[op_addr] "i"(&pv_cpu_ops.op)
+
+#define PARAVIRT_TYPE(type)			\
+	PARAVIRT_PATCH_TYPE_ ## type
+
+#define PARAVIRT_REG_CLOBBERS0					\
+	"r2", "r3", /*"r8",*/ "r9", "r10", "r11", "r14",	\
+		"r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS1					\
+	"r2","r3", /*"r8",*/ "r9", "r10", "r11", "r14",		\
+		"r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS2					\
+	"r2", "r3", /*"r8", "r9",*/ "r10", "r11", "r14",	\
+		"r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS5					\
+	"r2", "r3", /*"r8", "r9", "r10", "r11", "r14",*/	\
+		"r15", "r16", "r17"
+
+#define PARAVIRT_BR_CLOBBERS			\
+	"b6", "b7"
+
+#define PARAVIRT_PR_CLOBBERS						\
+	"p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15"
+
+#define PARAVIRT_AR_CLOBBERS			\
+	"ar.ccv"
+
+#define PARAVIRT_CLOBBERS0			\
+		PARAVIRT_REG_CLOBBERS0,		\
+		PARAVIRT_BR_CLOBBERS,		\
+		PARAVIRT_PR_CLOBBERS,		\
+		PARAVIRT_AR_CLOBBERS,		\
+		"memory"
+
+#define PARAVIRT_CLOBBERS1			\
+		PARAVIRT_REG_CLOBBERS1,		\
+		PARAVIRT_BR_CLOBBERS,		\
+		PARAVIRT_PR_CLOBBERS,		\
+		PARAVIRT_AR_CLOBBERS,		\
+		"memory"
+
+#define PARAVIRT_CLOBBERS2			\
+		PARAVIRT_REG_CLOBBERS2,		\
+		PARAVIRT_BR_CLOBBERS,		\
+		PARAVIRT_PR_CLOBBERS,		\
+		PARAVIRT_AR_CLOBBERS,		\
+		"memory"
+
+#define PARAVIRT_CLOBBERS5			\
+		PARAVIRT_REG_CLOBBERS5,		\
+		PARAVIRT_BR_CLOBBERS,		\
+		PARAVIRT_PR_CLOBBERS,		\
+		PARAVIRT_AR_CLOBBERS,		\
+		"memory"
+
+#define PARAVIRT_BR0(op, type)					\
+	register unsigned long ia64_clobber asm ("r8");		\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+					  PARAVIRT_TYPE(type))	\
+		      :	"=r"(ia64_clobber)			\
+		      : PARAVIRT_OP(op)				\
+		      : PARAVIRT_CLOBBERS0)
+
+#define PARAVIRT_BR0_RET(op, type)				\
+	register unsigned long ia64_intri_res asm ("r8");	\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+					  PARAVIRT_TYPE(type))	\
+		      : "=r"(ia64_intri_res)			\
+		      : PARAVIRT_OP(op)				\
+		      : PARAVIRT_CLOBBERS0)
+
+#define PARAVIRT_BR1(op, type, arg1)				\
+	register unsigned long __##arg1 asm ("r8") = arg1;	\
+	register unsigned long ia64_clobber asm ("r8");		\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+					  PARAVIRT_TYPE(type))	\
+		      :	"=r"(ia64_clobber)			\
+		      : PARAVIRT_OP(op), "0"(__##arg1)		\
+		      : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR1_RET(op, type, arg1)			\
+	register unsigned long ia64_intri_res asm ("r8");	\
+	register unsigned long __##arg1 asm ("r8") = arg1;	\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+					  PARAVIRT_TYPE(type))	\
+		      : "=r"(ia64_intri_res)			\
+		      : PARAVIRT_OP(op), "0"(__##arg1)		\
+		      : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR1_VOID(op, type, arg1)			\
+	register void *__##arg1 asm ("r8") = arg1;		\
+	register unsigned long ia64_clobber asm ("r8");		\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+					  PARAVIRT_TYPE(type))	\
+		      :	"=r"(ia64_clobber)			\
+		      : PARAVIRT_OP(op), "0"(__##arg1)		\
+		      : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR2(op, type, arg1, arg2)				\
+	register unsigned long __##arg1 asm ("r8") = arg1;		\
+	register unsigned long __##arg2 asm ("r9") = arg2;		\
+	register unsigned long ia64_clobber1 asm ("r8");		\
+	register unsigned long ia64_clobber2 asm ("r9");		\
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,		\
+					  PARAVIRT_TYPE(type))		\
+		      : "=r"(ia64_clobber1), "=r"(ia64_clobber2)	\
+		      : PARAVIRT_OP(op), "0"(__##arg1), "1"(__##arg2)	\
+		      : PARAVIRT_CLOBBERS2)
+
+
+#define PARAVIRT_DEFINE_CPU_OP0(op, type)		\
+	static inline void				\
+	paravirt_ ## op (void)				\
+	{						\
+		PARAVIRT_BR0(op, type);			\
+	}
+
+#define PARAVIRT_DEFINE_CPU_OP0_RET(op, type)		\
+	static inline unsigned long			\
+	paravirt_ ## op (void)				\
+	{						\
+		PARAVIRT_BR0_RET(op, type);		\
+		return ia64_intri_res;			\
+	}
+
+#define PARAVIRT_DEFINE_CPU_OP1_VOID(op, type)		\
+	static inline void				\
+	paravirt_ ## op (void *arg1)			\
+	{						\
+		PARAVIRT_BR1_VOID(op, type, arg1);	\
+	}
+
+#define PARAVIRT_DEFINE_CPU_OP1(op, type)		\
+	static inline void				\
+	paravirt_ ## op (unsigned long arg1)		\
+	{						\
+		PARAVIRT_BR1(op, type, arg1);		\
+	}
+
+#define PARAVIRT_DEFINE_CPU_OP1_RET(op, type)		\
+	static inline unsigned long			\
+	paravirt_ ## op (unsigned long arg1)		\
+	{						\
+		PARAVIRT_BR1_RET(op, type, arg1);	\
+		return ia64_intri_res;			\
+	}
+
+#define PARAVIRT_DEFINE_CPU_OP2(op, type)		\
+	static inline void				\
+	paravirt_ ## op (unsigned long arg1,		\
+			 unsigned long arg2)		\
+	{						\
+		PARAVIRT_BR2(op, type, arg1, arg2);	\
+	}
+
+
+PARAVIRT_DEFINE_CPU_OP1_VOID(fc, FC);
+PARAVIRT_DEFINE_CPU_OP1_RET(thash, THASH)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_cpuid, GET_CPUID)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_pmd, GET_PMD)
+PARAVIRT_DEFINE_CPU_OP2(ptcga, PTCGA)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_rr, GET_RR)
+PARAVIRT_DEFINE_CPU_OP2(set_rr, SET_RR)
+PARAVIRT_DEFINE_CPU_OP0(ssm_i, SSM_I)
+PARAVIRT_DEFINE_CPU_OP0(rsm_i, RSM_I)
+PARAVIRT_DEFINE_CPU_OP0_RET(get_psr_i, GET_PSR_I)
+PARAVIRT_DEFINE_CPU_OP1(intrin_local_irq_restore, INTRIN_LOCAL_IRQ_RESTORE)
+
+static inline void
+paravirt_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
+			unsigned long val2, unsigned long val3,
+			unsigned long val4)
+{
+	register unsigned long __val0 asm ("r8") = val0;
+	register unsigned long __val1 asm ("r9") = val1;
+	register unsigned long __val2 asm ("r10") = val2;
+	register unsigned long __val3 asm ("r11") = val3;
+	register unsigned long __val4 asm ("r14") = val4;
+
+	register unsigned long ia64_clobber0 asm ("r8");
+	register unsigned long ia64_clobber1 asm ("r9");
+	register unsigned long ia64_clobber2 asm ("r10");
+	register unsigned long ia64_clobber3 asm ("r11");
+	register unsigned long ia64_clobber4 asm ("r14");
+
+	asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,
+					  PARAVIRT_TYPE(SET_RR0_TO_RR4))
+		      : "=r"(ia64_clobber0),
+			"=r"(ia64_clobber1),
+			"=r"(ia64_clobber2),
+			"=r"(ia64_clobber3),
+			"=r"(ia64_clobber4)
+		      : PARAVIRT_OP(set_rr0_to_rr4),
+			"0"(__val0), "1"(__val1), "2"(__val2),
+			"3"(__val3), "4"(__val4)
+		      : PARAVIRT_CLOBBERS5);
+}
+
+/* unsigned long paravirt_getreg(int reg) */
+#define __paravirt_getreg(reg)						\
+	({								\
+		register unsigned long ia64_intri_res asm ("r8");	\
+		register unsigned long __reg asm ("r8") = (reg);	\
+									\
+		asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+						  PARAVIRT_TYPE(GETREG) \
+						  + (reg))		\
+			      : "=r"(ia64_intri_res)			\
+			      : PARAVIRT_OP(getreg), "0"(__reg)		\
+			      : PARAVIRT_CLOBBERS1);			\
+									\
+		ia64_intri_res;						\
+	})
+
+/* void paravirt_setreg(int reg, unsigned long val) */
+#define paravirt_setreg(reg, val)					\
+	do {								\
+		register unsigned long __val asm ("r8") = val;		\
+		register unsigned long __reg asm ("r9") = reg;		\
+		register unsigned long ia64_clobber1 asm ("r8");	\
+		register unsigned long ia64_clobber2 asm ("r9");	\
+									\
+		asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,	\
+						  PARAVIRT_TYPE(SETREG) \
+						  + (reg))		\
+			      : "=r"(ia64_clobber1),			\
+				"=r"(ia64_clobber2)			\
+			      : PARAVIRT_OP(setreg),			\
+				"1"(__reg), "0"(__val)			\
+			      : PARAVIRT_CLOBBERS2);			\
+	} while (0)
+
+#endif /* ASM_SUPPORTED */
+#endif /* CONFIG_PARAVIRT && ASM_SUPPOTED */
+
 #endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/percpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,12 +27,12 @@ extern void *per_cpu_init(void);
 
 #else /* ! SMP */
 
-#define PER_CPU_ATTRIBUTES	__attribute__((__section__(".data.percpu")))
-
 #define per_cpu_init()				(__phys_per_cpu_start)
 
 #endif	/* SMP */
 
+#define PER_CPU_BASE_SECTION ".data.percpu"
+
 /*
  * Be extremely careful when taking the address of this variable!  Due to virtual
  * remapping, it is different from the canonical address returned by __get_cpu_var(var)!
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,7 +58,7 @@ extern struct smp_boot_data {
 extern char no_int_routing __devinitdata;
 
 extern cpumask_t cpu_core_map[NR_CPUS];
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
+DECLARE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
 extern int smp_num_siblings;
 extern void __iomem *ipi_base_addr;
 extern unsigned char smp_int_redirect;
@@ -126,7 +126,8 @@ extern void identify_siblings (struct cp
 extern int is_multithreading_enabled(void);
 
 extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
 
 #else /* CONFIG_SMP */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -63,4 +63,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_IA64_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -120,6 +120,38 @@ do {											\
 #define __raw_read_can_lock(rw)		(*(volatile int *)(rw) >= 0)
 #define __raw_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)
+{
+	__asm__ __volatile__ (
+		"tbit.nz p6, p0 = %1,%2\n"
+		"br.few 3f\n"
+		"1:\n"
+		"fetchadd4.rel r2 = [%0], -1;;\n"
+		"(p6) ssm psr.i\n"
+		"2:\n"
+		"hint @pause\n"
+		"ld4 r2 = [%0];;\n"
+		"cmp4.lt p7,p0 = r2, r0\n"
+		"(p7) br.cond.spnt.few 2b\n"
+		"(p6) rsm psr.i\n"
+		";;\n"
+		"3:\n"
+		"fetchadd4.acq r2 = [%0], 1;;\n"
+		"cmp4.lt p7,p0 = r2, r0\n"
+		"(p7) br.cond.spnt.few 1b\n"
+		: : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
+		: "p6", "p7", "r2", "memory");
+}
+
+#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0)
+
+#else /* !ASM_SUPPORTED */
+
+#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
+
 #define __raw_read_lock(rw)								\
 do {											\
 	raw_rwlock_t *__read_lock_ptr = (rw);						\
@@ -131,6 +163,8 @@ do {											\
 	}										\
 } while (0)
 
+#endif /* !ASM_SUPPORTED */
+
 #define __raw_read_unlock(rw)					\
 do {								\
 	raw_rwlock_t *__read_lock_ptr = (rw);			\
@@ -138,20 +172,33 @@ do {								\
 } while (0)
 
 #ifdef ASM_SUPPORTED
-#define __raw_write_lock(rw)							\
-do {										\
- 	__asm__ __volatile__ (							\
-		"mov ar.ccv = r0\n"						\
-		"dep r29 = -1, r0, 31, 1;;\n"					\
-		"1:\n"								\
-		"ld4 r2 = [%0];;\n"						\
-		"cmp4.eq p0,p7 = r0,r2\n"					\
-		"(p7) br.cond.spnt.few 1b \n"					\
-		"cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n"			\
-		"cmp4.eq p0,p7 = r0, r2\n"					\
-		"(p7) br.cond.spnt.few 1b;;\n"					\
-		:: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory");		\
-} while(0)
+
+static __always_inline void
+__raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags)
+{
+	__asm__ __volatile__ (
+		"tbit.nz p6, p0 = %1, %2\n"
+		"mov ar.ccv = r0\n"
+		"dep r29 = -1, r0, 31, 1\n"
+		"br.few 3f;;\n"
+		"1:\n"
+		"(p6) ssm psr.i\n"
+		"2:\n"
+		"hint @pause\n"
+		"ld4 r2 = [%0];;\n"
+		"cmp4.eq p0,p7 = r0, r2\n"
+		"(p7) br.cond.spnt.few 2b\n"
+		"(p6) rsm psr.i\n"
+		";;\n"
+		"3:\n"
+		"cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n"
+		"cmp4.eq p0,p7 = r0, r2\n"
+		"(p7) br.cond.spnt.few 1b;;\n"
+		: : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
+		: "ar.ccv", "p6", "p7", "r2", "r29", "memory");
+}
+
+#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0)
 
 #define __raw_write_trylock(rw)							\
 ({										\
@@ -174,6 +221,8 @@ static inline void __raw_write_unlock(ra
 
 #else /* !ASM_SUPPORTED */
 
+#define __raw_write_lock_flags(l, flags) __raw_write_lock(l)
+
 #define __raw_write_lock(l)								\
 ({											\
 	__u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1);			\
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
  */
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/intrinsics.h>
 #include <linux/compiler.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/timex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,5 +40,6 @@ get_cycles (void)
 }
 
 extern void ia64_cpu_local_tick (void);
+extern unsigned long long ia64_native_sched_clock (void);
 
 #endif /* _ASM_IA64_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,11 +44,6 @@
 #define parent_node(nid) (nid)
 
 /*
- * Returns the number of the first CPU on Node 'node'.
- */
-#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node)))
-
-/*
  * Determines the node for a given pci bus
  */
 #define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node
@@ -84,7 +79,7 @@ void build_cpu_to_node_map(void);
 	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
-	.max_interval		= 8*(min(num_online_cpus(), 32)), \
+	.max_interval		= 8*(min(num_online_cpus(), 32U)), \
 	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
 	.cache_nice_tries	= 2,			\
@@ -117,11 +112,6 @@ void build_cpu_to_node_map(void);
 
 extern void arch_fix_phys_package_id(int num, u32 slot);
 
-#define pcibus_to_cpumask(bus)	(pcibus_to_node(bus) == -1 ? \
-					CPU_MASK_ALL : \
-					node_to_cpumask(pcibus_to_node(bus)) \
-				)
-
 #define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ?		\
 				 cpu_all_mask :				\
 				 cpumask_of_node(pcibus_to_node(bus)))
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -308,11 +308,13 @@
 #define __NR_dup3			1316
 #define __NR_pipe2			1317
 #define __NR_inotify_init1		1318
+#define __NR_preadv			1319
+#define __NR_pwritev			1320
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls			295 /* length of syscall table */
+#define NR_syscalls			297 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef _ASM_IA64_UV_UV_H
+#define _ASM_IA64_UV_UV_H
+
+#include <asm/system.h>
+#include <asm/sn/simulator.h>
+
+static inline int is_uv_system(void)
+{
+	/* temporary support for running on hardware simulator */
+	return IS_MEDUSA() || ia64_platform_is("uv");
+}
+
+#endif	/* _ASM_IA64_UV_UV_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv_hub.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv_hub.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv_hub.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv_hub.h	2009-06-09 23:05:27.000000000 -0400
@@ -305,5 +305,11 @@ static inline int uv_num_possible_blades
 	return 1;
 }
 
+static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
+{
+	/* not currently needed on ia64 */
+}
+
+
 #endif /* __ASM_IA64_UV_HUB__ */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv_mmrs.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv_mmrs.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/uv/uv_mmrs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/uv/uv_mmrs.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,8 +8,8 @@
  * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
  */
 
-#ifndef __ASM_IA64_UV_MMRS__
-#define __ASM_IA64_UV_MMRS__
+#ifndef _ASM_IA64_UV_UV_MMRS_H
+#define _ASM_IA64_UV_UV_MMRS_H
 
 #define UV_MMR_ENABLE		(1UL << 63)
 
@@ -243,6 +243,158 @@ union uvh_event_occurred0_u {
 #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
 
 /* ========================================================================= */
+/*                         UVH_GR0_TLB_INT0_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
+
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int0_config_u {
+    unsigned long	v;
+    struct uvh_gr0_tlb_int0_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR0_TLB_INT1_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL
+
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int1_config_u {
+    unsigned long	v;
+    struct uvh_gr0_tlb_int1_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR1_TLB_INT0_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL
+
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int0_config_u {
+    unsigned long	v;
+    struct uvh_gr1_tlb_int0_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR1_TLB_INT1_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL
+
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int1_config_u {
+    unsigned long	v;
+    struct uvh_gr1_tlb_int1_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
 /*                               UVH_INT_CMPB                                */
 /* ========================================================================= */
 #define UVH_INT_CMPB 0x22080UL
@@ -670,4 +822,4 @@ union uvh_si_alias2_overlay_config_u {
 };
 
 
-#endif /* __ASM_IA64_UV_MMRS__ */
+#endif /* _ASM_IA64_UV_UV_MMRS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/events.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/events.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/events.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/events.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,14 +36,9 @@ static inline int xen_irqs_disabled(stru
 	return !(ia64_psr(regs)->i);
 }
 
-static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
+static inline void handle_irq(int irq, struct pt_regs *regs)
 {
-	struct pt_regs *old_regs;
-	old_regs = set_irq_regs(regs);
-	irq_enter();
 	__do_IRQ(irq);
-	irq_exit();
-	set_irq_regs(old_regs);
 }
 #define irq_ctx_init(cpu)	do { } while (0)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/hypervisor.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/hypervisor.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/hypervisor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/hypervisor.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,9 +33,6 @@
 #ifndef _ASM_IA64_XEN_HYPERVISOR_H
 #define _ASM_IA64_XEN_HYPERVISOR_H
 
-#ifdef CONFIG_XEN
-
-#include <linux/init.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>	/* to compile feature.c */
 #include <xen/features.h>		/* to comiple xen-netfront.c */
@@ -43,22 +40,32 @@
 
 /* xen_domain_type is set before executing any C code by early_xen_setup */
 enum xen_domain_type {
-	XEN_NATIVE,
-	XEN_PV_DOMAIN,
-	XEN_HVM_DOMAIN,
+	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_type == XEN_PV_DOMAIN)
-#define xen_initial_domain()	(xen_pv_domain() && \
+#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))
-#define xen_hvm_domain()	(xen_domain_type == XEN_HVM_DOMAIN)
+#else
+#define xen_initial_domain()	(0)
+#endif
 
-/* deprecated. remove this */
-#define is_running_on_xen()	(xen_domain_type == XEN_PV_DOMAIN)
 
+#ifdef CONFIG_XEN
 extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
 
@@ -74,16 +81,6 @@ void force_evtchn_callback(void);
 
 /* For setup_arch() in arch/ia64/kernel/setup.c */
 void xen_ia64_enable_opt_feature(void);
-
-#else /* CONFIG_XEN */
-
-#define xen_domain()		(0)
-#define xen_pv_domain()		(0)
-#define xen_initial_domain()	(0)
-#define xen_hvm_domain()	(0)
-#define is_running_on_xen()	(0)	/* deprecated. remove this */
 #endif
 
-#define is_initial_xendomain()	(0)	/* deprecated. remove this */
-
 #endif /* _ASM_IA64_XEN_HYPERVISOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/inst.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/inst.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/inst.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/inst.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,9 @@
 #define __paravirt_work_processed_syscall_target \
 						xen_work_processed_syscall
 
+#define paravirt_fsyscall_table			xen_fsyscall_table
+#define paravirt_fsys_bubble_down		xen_fsys_bubble_down
+
 #define MOV_FROM_IFA(reg)	\
 	movl reg = XSI_IFA;	\
 	;;			\
@@ -110,6 +113,27 @@
 .endm
 #define MOV_FROM_PSR(pred, reg, clob)	__MOV_FROM_PSR pred, reg, clob
 
+/* assuming ar.itc is read with interrupt disabled. */
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob)		\
+(pred)	movl clob = XSI_ITC_OFFSET;				\
+	;;							\
+(pred)	ld8 clob = [clob];					\
+(pred)	mov reg = ar.itc;					\
+	;;							\
+(pred)	add reg = reg, clob;					\
+	;;							\
+(pred)	movl clob = XSI_ITC_LAST;				\
+	;;							\
+(pred)	ld8 clob = [clob];					\
+	;;							\
+(pred)	cmp.geu.unc pred_clob, p0 = clob, reg;			\
+	;;							\
+(pred_clob)	add reg = 1, clob;				\
+	;;							\
+(pred)	movl clob = XSI_ITC_LAST;				\
+	;;							\
+(pred)	st8 [clob] = reg
+
 
 #define MOV_TO_IFA(reg, clob)	\
 	movl clob = XSI_IFA;	\
@@ -362,6 +386,10 @@
 #define RSM_PSR_DT		\
 	XEN_HYPER_RSM_PSR_DT
 
+#define RSM_PSR_BE_I(clob0, clob1)	\
+	RSM_PSR_I(p0, clob0, clob1);	\
+	rum psr.be
+
 #define SSM_PSR_DT_AND_SRLZ_I	\
 	XEN_HYPER_SSM_PSR_DT
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/interface.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/interface.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/interface.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/interface.h	2009-06-09 23:05:27.000000000 -0400
@@ -209,6 +209,15 @@ struct mapped_regs {
 			unsigned long krs[8];	/* kernel registers */
 			unsigned long tmp[16];	/* temp registers
 						   (e.g. for hyperprivops) */
+
+			/* itc paravirtualization
+			 * vAR.ITC = mAR.ITC + itc_offset
+			 * itc_last is one which was lastly passed to
+			 * the guest OS in order to prevent it from
+			 * going backwords.
+			 */
+			unsigned long itc_offset;
+			unsigned long itc_last;
 		};
 	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/minstate.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/minstate.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/minstate.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/minstate.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,3 +1,12 @@
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/* read ar.itc in advance, and use it before leaving bank 0 */
+#define XEN_ACCOUNT_GET_STAMP		\
+	MOV_FROM_ITC(pUStk, p6, r20, r2);
+#else
+#define XEN_ACCOUNT_GET_STAMP
+#endif
+
 /*
  * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
  * the minimum state necessary that allows us to turn psr.ic back
@@ -123,7 +132,7 @@
 	;;											\
 .mem.offset 0,0; st8.spill [r16]=r2,16;								\
 .mem.offset 8,0; st8.spill [r17]=r3,16;								\
-	ACCOUNT_GET_STAMP									\
+	XEN_ACCOUNT_GET_STAMP									\
 	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
 	;;											\
 	EXTRA;											\
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/patchlist.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/patchlist.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/patchlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/patchlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/patchlist.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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 __paravirt_start_gate_fsyscall_patchlist		\
+	__xen_start_gate_fsyscall_patchlist
+#define __paravirt_end_gate_fsyscall_patchlist			\
+	__xen_end_gate_fsyscall_patchlist
+#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist	\
+	__xen_start_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist	\
+	__xen_end_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_start_gate_vtop_patchlist			\
+	__xen_start_gate_vtop_patchlist
+#define __paravirt_end_gate_vtop_patchlist			\
+	__xen_end_gate_vtop_patchlist
+#define __paravirt_start_gate_mckinley_e9_patchlist		\
+	__xen_start_gate_mckinley_e9_patchlist
+#define __paravirt_end_gate_mckinley_e9_patchlist		\
+	__xen_end_gate_mckinley_e9_patchlist
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/privop.h linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/privop.h
--- linux-libre-2.6.29-gnu1/arch/ia64/include/asm/xen/privop.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/include/asm/xen/privop.h	2009-06-09 23:05:27.000000000 -0400
@@ -55,6 +55,8 @@
 #define XSI_BANK1_R16			(XSI_BASE + XSI_BANK1_R16_OFS)
 #define XSI_BANKNUM			(XSI_BASE + XSI_BANKNUM_OFS)
 #define XSI_IHA				(XSI_BASE + XSI_IHA_OFS)
+#define XSI_ITC_OFFSET			(XSI_BASE + XSI_ITC_OFFSET_OFS)
+#define XSI_ITC_LAST			(XSI_BASE + XSI_ITC_LAST_OFS)
 #endif
 
 #ifndef __ASSEMBLY__
@@ -67,7 +69,7 @@
  *  may have different semantics depending on whether they are executed
  *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
  *  be allowed to execute directly, lest incorrect semantics result. */
-extern void xen_fc(unsigned long addr);
+extern void xen_fc(void *addr);
 extern unsigned long xen_thash(unsigned long addr);
 
 /* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
@@ -80,8 +82,10 @@ extern unsigned long xen_thash(unsigned
 extern unsigned long xen_get_cpuid(int index);
 extern unsigned long xen_get_pmd(int index);
 
+#ifndef ASM_SUPPORTED
 extern unsigned long xen_get_eflag(void);	/* see xen_ia64_getreg */
 extern void xen_set_eflag(unsigned long);	/* see xen_ia64_setreg */
+#endif
 
 /************************************************/
 /* Instructions paravirtualized for performance */
@@ -106,6 +110,7 @@ extern void xen_set_eflag(unsigned long)
 #define xen_get_virtual_pend()		\
 	(*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
 
+#ifndef ASM_SUPPORTED
 /* Although all privileged operations can be left to trap and will
  * be properly handled by Xen, some are frequent enough that we use
  * hyperprivops for performance. */
@@ -123,6 +128,7 @@ extern void xen_set_rr0_to_rr4(unsigned
 			       unsigned long val4);
 extern void xen_set_kr(unsigned long index, unsigned long val);
 extern void xen_ptcga(unsigned long addr, unsigned long size);
+#endif /* !ASM_SUPPORTED */
 
 #endif /* !__ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/Kconfig linux-libre-2.6.30-gnu1/arch/ia64/Kconfig
--- linux-libre-2.6.29-gnu1/arch/ia64/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,9 @@ config IA64
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
+	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
+	select HAVE_FUNCTION_TRACER
 	select HAVE_DMA_ATTRS
 	select HAVE_KVM
 	select HAVE_ARCH_TRACEHOOK
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/acpi.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/acpi.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -199,6 +199,10 @@ char *__init __acpi_map_table(unsigned l
 	return __va(phys_addr);
 }
 
+void __init __acpi_unmap_table(char *map, unsigned long size)
+{
+}
+
 /* --------------------------------------------------------------------------
                             Boot-time Table Parsing
    -------------------------------------------------------------------------- */
@@ -886,7 +890,7 @@ __init void prefill_possible_map(void)
 		possible, max((possible - available_cpus), 0));
 
 	for (i = 0; i < possible; i++)
-		cpu_set(i, cpu_possible_map);
+		set_cpu_possible(i, true);
 }
 
 int acpi_map_lsapic(acpi_handle handle, int *pcpu)
@@ -924,9 +928,9 @@ int acpi_map_lsapic(acpi_handle handle,
 	buffer.length = ACPI_ALLOCATE_BUFFER;
 	buffer.pointer = NULL;
 
-	cpus_complement(tmp_map, cpu_present_map);
-	cpu = first_cpu(tmp_map);
-	if (cpu >= NR_CPUS)
+	cpumask_complement(&tmp_map, cpu_present_mask);
+	cpu = cpumask_first(&tmp_map);
+	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
 	acpi_map_cpu2node(handle, cpu, physid);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/asm-offsets.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -316,5 +316,7 @@ void foo(void)
 	DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]);
 	DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat);
 	DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat);
+	DEFINE_MAPPED_REG_OFS(XSI_ITC_OFFSET_OFS, itc_offset);
+	DEFINE_MAPPED_REG_OFS(XSI_ITC_LAST_OFS, itc_last);
 #endif /* CONFIG_XEN */
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/cyclone.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/cyclone.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/cyclone.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/cyclone.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,7 @@ void __init cyclone_setup(void)
 
 static void __iomem *cyclone_mc;
 
-static cycle_t read_cyclone(void)
+static cycle_t read_cyclone(struct clocksource *cs)
 {
 	return (cycle_t)readq((void __iomem *)cyclone_mc);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/dma-mapping.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/dma-mapping.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/dma-mapping.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/dma-mapping.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#include <linux/dma-mapping.h>
+
+/* Set this to 1 if there is a HW IOMMU in the system */
+int iommu_detected __read_mostly;
+
+struct dma_map_ops *dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
+struct dma_map_ops *dma_get_ops(struct device *dev)
+{
+	return dma_ops;
+}
+EXPORT_SYMBOL(dma_get_ops);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/efi.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/efi.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/efi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/efi.c	2009-06-09 23:05:27.000000000 -0400
@@ -456,6 +456,7 @@ efi_map_pal_code (void)
 		 GRANULEROUNDDOWN((unsigned long) pal_vaddr),
 		 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
 		 IA64_GRANULE_SHIFT);
+	paravirt_dv_serialize_data();
 	ia64_set_psr(psr);		/* restore psr */
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/entry.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -47,6 +47,7 @@
 #include <asm/processor.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
+#include <asm/ftrace.h>
 
 #include "minstate.h"
 
@@ -735,7 +736,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall)
 __paravirt_work_processed_syscall:
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	adds r2=PT(LOADRS)+16,r12
-(pUStk)	mov.m r22=ar.itc			// fetch time at leave
+	MOV_FROM_ITC(pUStk, p9, r22, r19)	// fetch time at leave
 	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
 (p6)	ld4 r31=[r18]				// load current_thread_info()->flags
@@ -984,7 +985,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel)
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	.pred.rel.mutex pUStk,pKStk
 	MOV_FROM_PSR(pKStk, r22, r29)	// M2 read PSR now that interrupts are disabled
-(pUStk)	mov.m r22=ar.itc	// M  fetch time at leave
+	MOV_FROM_ITC(pUStk, p9, r22, r29)	// M  fetch time at leave
 	nop.i 0
 	;;
 #else
@@ -1404,6 +1405,105 @@ GLOBAL_ENTRY(unw_init_running)
 	br.ret.sptk.many rp
 END(unw_init_running)
 
+#ifdef CONFIG_FUNCTION_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+GLOBAL_ENTRY(_mcount)
+	br ftrace_stub
+END(_mcount)
+
+.here:
+	br.ret.sptk.many b0
+
+GLOBAL_ENTRY(ftrace_caller)
+	alloc out0 = ar.pfs, 8, 0, 4, 0
+	mov out3 = r0
+	;;
+	mov out2 = b0
+	add r3 = 0x20, r3
+	mov out1 = r1;
+	br.call.sptk.many b0 = ftrace_patch_gp
+	//this might be called from module, so we must patch gp
+ftrace_patch_gp:
+	movl gp=__gp
+	mov b0 = r3
+	;;
+.global ftrace_call;
+ftrace_call:
+{
+	.mlx
+	nop.m 0x0
+	movl r3 = .here;;
+}
+	alloc loc0 = ar.pfs, 4, 4, 2, 0
+	;;
+	mov loc1 = b0
+	mov out0 = b0
+	mov loc2 = r8
+	mov loc3 = r15
+	;;
+	adds out0 = -MCOUNT_INSN_SIZE, out0
+	mov out1 = in2
+	mov b6 = r3
+
+	br.call.sptk.many b0 = b6
+	;;
+	mov ar.pfs = loc0
+	mov b0 = loc1
+	mov r8 = loc2
+	mov r15 = loc3
+	br ftrace_stub
+	;;
+END(ftrace_caller)
+
+#else
+GLOBAL_ENTRY(_mcount)
+	movl r2 = ftrace_stub
+	movl r3 = ftrace_trace_function;;
+	ld8 r3 = [r3];;
+	ld8 r3 = [r3];;
+	cmp.eq p7,p0 = r2, r3
+(p7)	br.sptk.many ftrace_stub
+	;;
+
+	alloc loc0 = ar.pfs, 4, 4, 2, 0
+	;;
+	mov loc1 = b0
+	mov out0 = b0
+	mov loc2 = r8
+	mov loc3 = r15
+	;;
+	adds out0 = -MCOUNT_INSN_SIZE, out0
+	mov out1 = in2
+	mov b6 = r3
+
+	br.call.sptk.many b0 = b6
+	;;
+	mov ar.pfs = loc0
+	mov b0 = loc1
+	mov r8 = loc2
+	mov r15 = loc3
+	br ftrace_stub
+	;;
+END(_mcount)
+#endif
+
+GLOBAL_ENTRY(ftrace_stub)
+	mov r3 = b0
+	movl r2 = _mcount_ret_helper
+	;;
+	mov b6 = r2
+	mov b7 = r3
+	br.ret.sptk.many b6
+
+_mcount_ret_helper:
+	mov b0 = r42
+	mov r1 = r41
+	mov ar.pfs = r40
+	br b7
+END(ftrace_stub)
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
 	.rodata
 	.align 8
 	.globl sys_call_table
@@ -1703,6 +1803,8 @@ sys_call_table:
 	data8 sys_dup3
 	data8 sys_pipe2
 	data8 sys_inotify_init1
+	data8 sys_preadv
+	data8 sys_pwritev			// 1320
 
 	.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.29-gnu1/arch/ia64/kernel/fsys.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/fsys.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/fsys.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/fsys.S	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #include <asm/unistd.h>
 
 #include "entry.h"
+#include "paravirt_inst.h"
 
 /*
  * See Documentation/ia64/fsys.txt for details on fsyscalls.
@@ -279,7 +280,7 @@ ENTRY(fsys_gettimeofday)
 (p9)	cmp.eq p13,p0 = 0,r30	// if mmio_ptr, clear p13 jitter control
 	;;
 	.pred.rel.mutex p8,p9
-(p8)	mov r2 = ar.itc		// CPU_TIMER. 36 clocks latency!!!
+	MOV_FROM_ITC(p8, p6, r2, r10)	// CPU_TIMER. 36 clocks latency!!!
 (p9)	ld8 r2 = [r30]		// MMIO_TIMER. Could also have latency issues..
 (p13)	ld8 r25 = [r19]		// get itc_lastcycle value
 	ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET	// tv_sec
@@ -418,7 +419,7 @@ EX(.fail_efault, ld8 r14=[r33])			// r14
 	mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1))
 	;;
 
-	rsm psr.i				// mask interrupt delivery
+	RSM_PSR_I(p0, r18, r19)			// mask interrupt delivery
 	mov ar.ccv=0
 	andcm r14=r14,r17			// filter out SIGKILL & SIGSTOP
 
@@ -491,7 +492,7 @@ EX(.fail_efault, ld8 r14=[r33])			// r14
 #ifdef CONFIG_SMP
 	st4.rel [r31]=r0			// release the lock
 #endif
-	ssm psr.i
+	SSM_PSR_I(p0, p9, r31)
 	;;
 
 	srlz.d					// ensure psr.i is set again
@@ -513,7 +514,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
 #ifdef CONFIG_SMP
 	st4.rel [r31]=r0			// release the lock
 #endif
-	ssm psr.i
+	SSM_PSR_I(p0, p9, r17)
 	;;
 	srlz.d
 	br.sptk.many fsys_fallback_syscall	// with signal pending, do the heavy-weight syscall
@@ -521,7 +522,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
 #ifdef CONFIG_SMP
 .lock_contention:
 	/* Rather than spinning here, fall back on doing a heavy-weight syscall.  */
-	ssm psr.i
+	SSM_PSR_I(p0, p9, r17)
 	;;
 	srlz.d
 	br.sptk.many fsys_fallback_syscall
@@ -592,17 +593,17 @@ ENTRY(fsys_fallback_syscall)
 	adds r17=-1024,r15
 	movl r14=sys_call_table
 	;;
-	rsm psr.i
+	RSM_PSR_I(p0, r26, r27)
 	shladd r18=r17,3,r14
 	;;
 	ld8 r18=[r18]				// load normal (heavy-weight) syscall entry-point
-	mov r29=psr				// read psr (12 cyc load latency)
+	MOV_FROM_PSR(p0, r29, r26)		// read psr (12 cyc load latency)
 	mov r27=ar.rsc
 	mov r21=ar.fpsr
 	mov r26=ar.pfs
 END(fsys_fallback_syscall)
 	/* FALL THROUGH */
-GLOBAL_ENTRY(fsys_bubble_down)
+GLOBAL_ENTRY(paravirt_fsys_bubble_down)
 	.prologue
 	.altrp b6
 	.body
@@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	 *
 	 * PSR.BE : already is turned off in __kernel_syscall_via_epc()
 	 * PSR.AC : don't care (kernel normally turns PSR.AC on)
-	 * PSR.I  : already turned off by the time fsys_bubble_down gets
+	 * PSR.I  : already turned off by the time paravirt_fsys_bubble_down gets
 	 *	    invoked
 	 * PSR.DFL: always 0 (kernel never turns it on)
 	 * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
@@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	 * PSR.DB : don't care --- kernel never enables kernel-level
 	 *	    breakpoints
 	 * PSR.TB : must be 0 already; if it wasn't zero on entry to
-	 *          __kernel_syscall_via_epc, the branch to fsys_bubble_down
+	 *          __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down
 	 *          will trigger a taken branch; the taken-trap-handler then
 	 *          converts the syscall into a break-based system-call.
 	 */
@@ -683,7 +684,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	;;
 	mov ar.rsc=0				// M2   set enforced lazy mode, pl 0, LE, loadrs=0
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-	mov.m r30=ar.itc			// M    get cycle for accounting
+	MOV_FROM_ITC(p0, p6, r30, r23)		// M    get cycle for accounting
 #else
 	nop.m 0
 #endif
@@ -734,21 +735,21 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	mov rp=r14				// I0   set the real return addr
 	and r3=_TIF_SYSCALL_TRACEAUDIT,r3	// A
 	;;
-	ssm psr.i				// M2   we're on kernel stacks now, reenable irqs
+	SSM_PSR_I(p0, p6, r22)			// M2   we're on kernel stacks now, reenable irqs
 	cmp.eq p8,p0=r3,r0			// A
 (p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
 
 	nop.m 0
 (p8)	br.call.sptk.many b6=b6			// B    (ignore return address)
 	br.cond.spnt ia64_trace_syscall		// B
-END(fsys_bubble_down)
+END(paravirt_fsys_bubble_down)
 
 	.rodata
 	.align 8
-	.globl fsyscall_table
+	.globl paravirt_fsyscall_table
 
-	data8 fsys_bubble_down
-fsyscall_table:
+	data8 paravirt_fsys_bubble_down
+paravirt_fsyscall_table:
 	data8 fsys_ni_syscall
 	data8 0				// exit			// 1025
 	data8 0				// read
@@ -1033,4 +1034,4 @@ fsyscall_table:
 
 	// fill in zeros for the remaining entries
 	.zero:
-	.space fsyscall_table + 8*NR_syscalls - .zero, 0
+	.space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/ftrace.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/ftrace.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/ftrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/ftrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,206 @@
+/*
+ * Dynamic function tracing support.
+ *
+ * Copyright (C) 2008 Shaohua Li <shaohua.li@intel.com>
+ *
+ * For licencing details, see COPYING.
+ *
+ * Defines low-level handling of mcount calls when the kernel
+ * is compiled with the -pg flag. When using dynamic ftrace, the
+ * mcount call-sites get patched lazily with NOP till they are
+ * enabled. All code mutation routines here take effect atomically.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+
+#include <asm/cacheflush.h>
+#include <asm/patch.h>
+
+/* In IA64, each function will be added below two bundles with -pg option */
+static unsigned char __attribute__((aligned(8)))
+ftrace_orig_code[MCOUNT_INSN_SIZE] = {
+	0x02, 0x40, 0x31, 0x10, 0x80, 0x05, /* alloc r40=ar.pfs,12,8,0 */
+	0xb0, 0x02, 0x00, 0x00, 0x42, 0x40, /* mov r43=r0;; */
+	0x05, 0x00, 0xc4, 0x00,             /* mov r42=b0 */
+	0x11, 0x48, 0x01, 0x02, 0x00, 0x21, /* mov r41=r1 */
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
+	0x08, 0x00, 0x00, 0x50              /* br.call.sptk.many b0 = _mcount;; */
+};
+
+struct ftrace_orig_insn {
+	u64 dummy1, dummy2, dummy3;
+	u64 dummy4:64-41+13;
+	u64 imm20:20;
+	u64 dummy5:3;
+	u64 sign:1;
+	u64 dummy6:4;
+};
+
+/* mcount stub will be converted below for nop */
+static unsigned char ftrace_nop_code[MCOUNT_INSN_SIZE] = {
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+	0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+	0x00, 0x00, 0x04, 0x00,             /* nop.i 0x0 */
+	0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* nop.x 0x0;; */
+	0x00, 0x00, 0x04, 0x00
+};
+
+static unsigned char *ftrace_nop_replace(void)
+{
+	return ftrace_nop_code;
+}
+
+/*
+ * mcount stub will be converted below for call
+ * Note: Just the last instruction is changed against nop
+ * */
+static unsigned char __attribute__((aligned(8)))
+ftrace_call_code[MCOUNT_INSN_SIZE] = {
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+	0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+	0x00, 0x00, 0x04, 0x00,             /* nop.i 0x0 */
+	0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+	0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, /* brl.many .;;*/
+	0xf8, 0xff, 0xff, 0xc8
+};
+
+struct ftrace_call_insn {
+	u64 dummy1, dummy2;
+	u64 dummy3:48;
+	u64 imm39_l:16;
+	u64 imm39_h:23;
+	u64 dummy4:13;
+	u64 imm20:20;
+	u64 dummy5:3;
+	u64 i:1;
+	u64 dummy6:4;
+};
+
+static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+{
+	struct ftrace_call_insn *code = (void *)ftrace_call_code;
+	unsigned long offset = addr - (ip + 0x10);
+
+	code->imm39_l = offset >> 24;
+	code->imm39_h = offset >> 40;
+	code->imm20 = offset >> 4;
+	code->i = offset >> 63;
+	return ftrace_call_code;
+}
+
+static int
+ftrace_modify_code(unsigned long ip, unsigned char *old_code,
+		   unsigned char *new_code, int do_check)
+{
+	unsigned char replaced[MCOUNT_INSN_SIZE];
+
+	/*
+	 * Note: Due to modules and __init, code can
+	 *  disappear and change, we need to protect against faulting
+	 *  as well as code changing. We do this by using the
+	 *  probe_kernel_* functions.
+	 *
+	 * No real locking needed, this code is run through
+	 * kstop_machine, or before SMP starts.
+	 */
+
+	if (!do_check)
+		goto skip_check;
+
+	/* read the text we want to modify */
+	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+
+	/* Make sure it is what we expect it to be */
+	if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+		return -EINVAL;
+
+skip_check:
+	/* replace the text with the new text */
+	if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE))
+		return -EPERM;
+	flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
+
+	return 0;
+}
+
+static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
+	unsigned long ip = rec->ip;
+
+	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+	if (rec->flags & FTRACE_FL_CONVERTED) {
+		struct ftrace_call_insn *call_insn, *tmp_call;
+
+		call_insn = (void *)ftrace_call_code;
+		tmp_call = (void *)replaced;
+		call_insn->imm39_l = tmp_call->imm39_l;
+		call_insn->imm39_h = tmp_call->imm39_h;
+		call_insn->imm20 = tmp_call->imm20;
+		call_insn->i = tmp_call->i;
+		if (memcmp(replaced, ftrace_call_code, MCOUNT_INSN_SIZE) != 0)
+			return -EINVAL;
+		return 0;
+	} else {
+		struct ftrace_orig_insn *call_insn, *tmp_call;
+
+		call_insn = (void *)ftrace_orig_code;
+		tmp_call = (void *)replaced;
+		call_insn->sign = tmp_call->sign;
+		call_insn->imm20 = tmp_call->imm20;
+		if (memcmp(replaced, ftrace_orig_code, MCOUNT_INSN_SIZE) != 0)
+			return -EINVAL;
+		return 0;
+	}
+}
+
+int ftrace_make_nop(struct module *mod,
+		    struct dyn_ftrace *rec, unsigned long addr)
+{
+	int ret;
+	char *new;
+
+	ret = ftrace_make_nop_check(rec, addr);
+	if (ret)
+		return ret;
+	new = ftrace_nop_replace();
+	return ftrace_modify_code(rec->ip, NULL, new, 0);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned long ip = rec->ip;
+	unsigned char *old, *new;
+
+	old=  ftrace_nop_replace();
+	new = ftrace_call_replace(ip, addr);
+	return ftrace_modify_code(ip, old, new, 1);
+}
+
+/* in IA64, _mcount can't directly call ftrace_stub. Only jump is ok */
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+	unsigned long ip;
+	unsigned long addr = ((struct fnptr *)ftrace_call)->ip;
+
+	if (func == ftrace_stub)
+		return 0;
+	ip = ((struct fnptr *)func)->ip;
+
+	ia64_patch_imm64(addr + 2, ip);
+
+	flush_icache_range(addr, addr + 16);
+	return 0;
+}
+
+/* run from kstop_machine */
+int __init ftrace_dyn_arch_init(void *data)
+{
+	*(unsigned long *)data = 0;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/gate.lds.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/gate.lds.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/gate.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/gate.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@
 
 
 #include <asm/system.h>
+#include "paravirt_patchlist.h"
 
 SECTIONS
 {
@@ -33,21 +34,21 @@ SECTIONS
 	. = GATE_ADDR + 0x600;
 
 	.data.patch		: {
-		__start_gate_mckinley_e9_patchlist = .;
+		__paravirt_start_gate_mckinley_e9_patchlist = .;
 		*(.data.patch.mckinley_e9)
-		__end_gate_mckinley_e9_patchlist = .;
+		__paravirt_end_gate_mckinley_e9_patchlist = .;
 
-		__start_gate_vtop_patchlist = .;
+		__paravirt_start_gate_vtop_patchlist = .;
 		*(.data.patch.vtop)
-		__end_gate_vtop_patchlist = .;
+		__paravirt_end_gate_vtop_patchlist = .;
 
-		__start_gate_fsyscall_patchlist = .;
+		__paravirt_start_gate_fsyscall_patchlist = .;
 		*(.data.patch.fsyscall_table)
-		__end_gate_fsyscall_patchlist = .;
+		__paravirt_end_gate_fsyscall_patchlist = .;
 
-		__start_gate_brl_fsys_bubble_down_patchlist = .;
+		__paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
 		*(.data.patch.brl_fsys_bubble_down)
-		__end_gate_brl_fsys_bubble_down_patchlist = .;
+		__paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
 	}						:readable
 
 	.IA_64.unwind_info	: { *(.IA_64.unwind_info*) }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/gate.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/gate.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/gate.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/gate.S	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 #include <asm/sigcontext.h>
 #include <asm/system.h>
 #include <asm/unistd.h>
+#include "paravirt_inst.h"
 
 /*
  * We can't easily refer to symbols inside the kernel.  To avoid full runtime relocation,
@@ -48,87 +49,6 @@ GLOBAL_ENTRY(__kernel_syscall_via_break)
 }
 END(__kernel_syscall_via_break)
 
-/*
- * On entry:
- *	r11 = saved ar.pfs
- *	r15 = system call #
- *	b0  = saved return address
- *	b6  = return address
- * On exit:
- *	r11 = saved ar.pfs
- *	r15 = system call #
- *	b0  = saved return address
- *	all other "scratch" registers:	undefined
- *	all "preserved" registers:	same as on entry
- */
-
-GLOBAL_ENTRY(__kernel_syscall_via_epc)
-	.prologue
-	.altrp b6
-	.body
-{
-	/*
-	 * Note: the kernel cannot assume that the first two instructions in this
-	 * bundle get executed.  The remaining code must be safe even if
-	 * they do not get executed.
-	 */
-	adds r17=-1024,r15			// A
-	mov r10=0				// A    default to successful syscall execution
-	epc					// B	causes split-issue
-}
-	;;
-	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
-	LOAD_FSYSCALL_TABLE(r14)		// X
-	;;
-	mov r16=IA64_KR(CURRENT)		// M2 (12 cyc)
-	shladd r18=r17,3,r14			// A
-	mov r19=NR_syscalls-1			// A
-	;;
-	lfetch [r18]				// M0|1
-	mov r29=psr				// M2 (12 cyc)
-	// If r17 is a NaT, p6 will be zero
-	cmp.geu p6,p7=r19,r17			// A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
-	;;
-	mov r21=ar.fpsr				// M2 (12 cyc)
-	tnat.nz p10,p9=r15			// I0
-	mov.i r26=ar.pfs			// I0 (would stall anyhow due to srlz.d...)
-	;;
-	srlz.d					// M0 (forces split-issue) ensure PSR.BE==0
-(p6)	ld8 r18=[r18]				// M0|1
-	nop.i 0
-	;;
-	nop.m 0
-(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
-	nop.i 0
-	;;
-(p8)	ssm psr.i
-(p6)	mov b7=r18				// I0
-(p8)	br.dptk.many b7				// B
-
-	mov r27=ar.rsc				// M2 (12 cyc)
-/*
- * brl.cond doesn't work as intended because the linker would convert this branch
- * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
- * future version of the linker.  In the meantime, we just use an indirect branch
- * instead.
- */
-#ifdef CONFIG_ITANIUM
-(p6)	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
-	;;
-(p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
-	;;
-(p6)	mov b7=r14
-(p6)	br.sptk.many b7
-#else
-	BRL_COND_FSYS_BUBBLE_DOWN(p6)
-#endif
-	ssm psr.i
-	mov r10=-1
-(p10)	mov r8=EINVAL
-(p9)	mov r8=ENOSYS
-	FSYS_RETURN
-END(__kernel_syscall_via_epc)
-
 #	define ARG0_OFF		(16 + IA64_SIGFRAME_ARG0_OFFSET)
 #	define ARG1_OFF		(16 + IA64_SIGFRAME_ARG1_OFFSET)
 #	define ARG2_OFF		(16 + IA64_SIGFRAME_ARG2_OFFSET)
@@ -374,3 +294,92 @@ restore_rbs:
 	// invala not necessary as that will happen when returning to user-mode
 	br.cond.sptk back_from_restore_rbs
 END(__kernel_sigtramp)
+
+/*
+ * On entry:
+ *	r11 = saved ar.pfs
+ *	r15 = system call #
+ *	b0  = saved return address
+ *	b6  = return address
+ * On exit:
+ *	r11 = saved ar.pfs
+ *	r15 = system call #
+ *	b0  = saved return address
+ *	all other "scratch" registers:	undefined
+ *	all "preserved" registers:	same as on entry
+ */
+
+GLOBAL_ENTRY(__kernel_syscall_via_epc)
+	.prologue
+	.altrp b6
+	.body
+{
+	/*
+	 * Note: the kernel cannot assume that the first two instructions in this
+	 * bundle get executed.  The remaining code must be safe even if
+	 * they do not get executed.
+	 */
+	adds r17=-1024,r15			// A
+	mov r10=0				// A    default to successful syscall execution
+	epc					// B	causes split-issue
+}
+	;;
+	RSM_PSR_BE_I(r20, r22)			// M2 (5 cyc to srlz.d)
+	LOAD_FSYSCALL_TABLE(r14)		// X
+	;;
+	mov r16=IA64_KR(CURRENT)		// M2 (12 cyc)
+	shladd r18=r17,3,r14			// A
+	mov r19=NR_syscalls-1			// A
+	;;
+	lfetch [r18]				// M0|1
+	MOV_FROM_PSR(p0, r29, r8)		// M2 (12 cyc)
+	// If r17 is a NaT, p6 will be zero
+	cmp.geu p6,p7=r19,r17			// A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+	;;
+	mov r21=ar.fpsr				// M2 (12 cyc)
+	tnat.nz p10,p9=r15			// I0
+	mov.i r26=ar.pfs			// I0 (would stall anyhow due to srlz.d...)
+	;;
+	srlz.d					// M0 (forces split-issue) ensure PSR.BE==0
+(p6)	ld8 r18=[r18]				// M0|1
+	nop.i 0
+	;;
+	nop.m 0
+(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
+	nop.i 0
+	;;
+	SSM_PSR_I(p8, p14, r25)
+(p6)	mov b7=r18				// I0
+(p8)	br.dptk.many b7				// B
+
+	mov r27=ar.rsc				// M2 (12 cyc)
+/*
+ * brl.cond doesn't work as intended because the linker would convert this branch
+ * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
+ * future version of the linker.  In the meantime, we just use an indirect branch
+ * instead.
+ */
+#ifdef CONFIG_ITANIUM
+(p6)	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
+	;;
+(p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
+	;;
+(p6)	mov b7=r14
+(p6)	br.sptk.many b7
+#else
+	BRL_COND_FSYS_BUBBLE_DOWN(p6)
+#endif
+	SSM_PSR_I(p0, p14, r10)
+	mov r10=-1
+(p10)	mov r8=EINVAL
+(p9)	mov r8=ENOSYS
+	FSYS_RETURN
+
+#ifdef CONFIG_PARAVIRT
+	/*
+	 * padd to make the size of this symbol constant
+	 * independent of paravirtualization.
+	 */
+	.align PAGE_SIZE / 8
+#endif
+END(__kernel_syscall_via_epc)
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/head.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -1050,7 +1050,7 @@ END(ia64_delay_loop)
  * except that the multiplication and the shift are done with 128-bit
  * intermediate precision so that we can produce a full 64-bit result.
  */
-GLOBAL_ENTRY(sched_clock)
+GLOBAL_ENTRY(ia64_native_sched_clock)
 	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
 	mov.m r9=ar.itc		// fetch cycle-counter				(35 cyc)
 	;;
@@ -1066,7 +1066,13 @@ GLOBAL_ENTRY(sched_clock)
 	;;
 	shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
 	br.ret.sptk.many rp
-END(sched_clock)
+END(ia64_native_sched_clock)
+#ifndef CONFIG_PARAVIRT
+	//unsigned long long
+	//sched_clock(void) __attribute__((alias("ia64_native_sched_clock")));
+	.global sched_clock
+sched_clock = ia64_native_sched_clock
+#endif
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 GLOBAL_ENTRY(cycle_to_cputime)
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/ia64_ksyms.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/ia64_ksyms.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/ia64_ksyms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/ia64_ksyms.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,3 +112,9 @@ EXPORT_SYMBOL_GPL(esi_call_phys);
 #endif
 extern char ia64_ivt[];
 EXPORT_SYMBOL(ia64_ivt);
+
+#include <asm/ftrace.h>
+#ifdef CONFIG_FUNCTION_TRACER
+/* mcount is defined in assembly */
+EXPORT_SYMBOL(_mcount);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/iosapic.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/iosapic.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/iosapic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/iosapic.c	2009-06-09 23:05:27.000000000 -0400
@@ -880,7 +880,7 @@ iosapic_unregister_intr (unsigned int gs
 	if (iosapic_intr_info[irq].count == 0) {
 #ifdef CONFIG_SMP
 		/* Clear affinity */
-		cpus_setall(idesc->affinity);
+		cpumask_setall(idesc->affinity);
 #endif
 		/* Clear the interrupt information */
 		iosapic_intr_info[irq].dest = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/irq.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j) {
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		}
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
@@ -103,7 +103,7 @@ static char irq_redir [NR_IRQS]; // = {
 void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
 {
 	if (irq < NR_IRQS) {
-		cpumask_copy(&irq_desc[irq].affinity,
+		cpumask_copy(irq_desc[irq].affinity,
 			     cpumask_of(cpu_logical_id(hwid)));
 		irq_redir[irq] = (char) (redir & 0xff);
 	}
@@ -148,7 +148,7 @@ static void migrate_irqs(void)
 		if (desc->status == IRQ_PER_CPU)
 			continue;
 
-		if (cpumask_any_and(&irq_desc[irq].affinity, cpu_online_mask)
+		if (cpumask_any_and(irq_desc[irq].affinity, cpu_online_mask)
 		    >= nr_cpu_ids) {
 			/*
 			 * Save it for phase 2 processing
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/irq_ia64.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/irq_ia64.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/irq_ia64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/irq_ia64.c	2009-06-09 23:05:27.000000000 -0400
@@ -493,14 +493,15 @@ ia64_handle_irq (ia64_vector vector, str
 	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
 	ia64_srlz_d();
 	while (vector != IA64_SPURIOUS_INT_VECTOR) {
+		int irq = local_vector_to_irq(vector);
+		struct irq_desc *desc = irq_to_desc(irq);
+
 		if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
 			smp_local_flush_tlb();
-			kstat_this_cpu.irqs[vector]++;
-		} else if (unlikely(IS_RESCHEDULE(vector)))
-			kstat_this_cpu.irqs[vector]++;
-		else {
-			int irq = local_vector_to_irq(vector);
-
+			kstat_incr_irqs_this_cpu(irq, desc);
+		} else if (unlikely(IS_RESCHEDULE(vector))) {
+			kstat_incr_irqs_this_cpu(irq, desc);
+		} else {
 			ia64_setreg(_IA64_REG_CR_TPR, vector);
 			ia64_srlz_d();
 
@@ -543,22 +544,24 @@ void ia64_process_pending_intr(void)
 
 	vector = ia64_get_ivr();
 
-	 irq_enter();
-	 saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
-	 ia64_srlz_d();
+	irq_enter();
+	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
+	ia64_srlz_d();
 
 	 /*
 	  * Perform normal interrupt style processing
 	  */
 	while (vector != IA64_SPURIOUS_INT_VECTOR) {
+		int irq = local_vector_to_irq(vector);
+		struct irq_desc *desc = irq_to_desc(irq);
+
 		if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
 			smp_local_flush_tlb();
-			kstat_this_cpu.irqs[vector]++;
-		} else if (unlikely(IS_RESCHEDULE(vector)))
-			kstat_this_cpu.irqs[vector]++;
-		else {
+			kstat_incr_irqs_this_cpu(irq, desc);
+		} else if (unlikely(IS_RESCHEDULE(vector))) {
+			kstat_incr_irqs_this_cpu(irq, desc);
+		} else {
 			struct pt_regs *old_regs = set_irq_regs(NULL);
-			int irq = local_vector_to_irq(vector);
 
 			ia64_setreg(_IA64_REG_CR_TPR, vector);
 			ia64_srlz_d();
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/ivt.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/ivt.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/ivt.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/ivt.S	2009-06-09 23:05:27.000000000 -0400
@@ -804,7 +804,7 @@ ENTRY(break_fault)
 ///////////////////////////////////////////////////////////////////////
 	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-	mov.m r30=ar.itc			// M    get cycle for accounting
+	MOV_FROM_ITC(p0, p14, r30, r18)		// M    get cycle for accounting
 #else
 	mov b6=r30				// I0   setup syscall handler branch reg early
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/machvec.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/machvec.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/machvec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/machvec.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 #include <linux/module.h>
-
+#include <linux/dma-mapping.h>
 #include <asm/machvec.h>
 #include <asm/system.h>
 
@@ -75,14 +75,16 @@ machvec_timer_interrupt (int irq, void *
 EXPORT_SYMBOL(machvec_timer_interrupt);
 
 void
-machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, size_t size, int dir)
+machvec_dma_sync_single(struct device *hwdev, dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction dir)
 {
 	mb();
 }
 EXPORT_SYMBOL(machvec_dma_sync_single);
 
 void
-machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, int dir)
+machvec_dma_sync_sg(struct device *hwdev, struct scatterlist *sg, int n,
+		    enum dma_data_direction dir)
 {
 	mb();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/Makefile linux-libre-2.6.30-gnu1/arch/ia64/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,12 +2,16 @@
 # Makefile for the linux kernel.
 #
 
+ifdef CONFIG_DYNAMIC_FTRACE
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
 extra-y	:= head.o init_task.o vmlinux.lds
 
 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o	\
-	 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o		\
+	 irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o		\
 	 salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
-	 unwind.o mca.o mca_asm.o topology.o
+	 unwind.o mca.o mca_asm.o topology.o dma-mapping.o
 
 obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
@@ -28,6 +32,7 @@ obj-$(CONFIG_IA64_CYCLONE)	+= cyclone.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_IA64_MCA_RECOVERY)	+= mca_recovery.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o jprobes.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
@@ -36,46 +41,23 @@ obj-$(CONFIG_PCI_MSI)		+= msi_ia64.o
 mca_recovery-y			+= mca_drv.o mca_drv_asm.o
 obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
 
-obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirtentry.o
+obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirtentry.o \
+				   paravirt_patch.o
 
 obj-$(CONFIG_IA64_ESI)		+= esi.o
 ifneq ($(CONFIG_IA64_ESI),)
 obj-y				+= esi_stub.o	# must be in kernel proper
 endif
 obj-$(CONFIG_DMAR)		+= pci-dma.o
-ifeq ($(CONFIG_DMAR), y)
 obj-$(CONFIG_SWIOTLB)		+= pci-swiotlb.o
-endif
-
-# The gate DSO image is built using a special linker script.
-targets += gate.so gate-syms.o
-
-extra-y += gate.so gate-syms.o gate.lds gate.o
 
 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
 CFLAGS_traps.o  += -mfixed-range=f2-f5,f16-f31
 
-CPPFLAGS_gate.lds := -P -C -U$(ARCH)
-
-quiet_cmd_gate = GATE $@
-      cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
-		     $(call ld-option, -Wl$(comma)--hash-style=sysv)
-$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
-	$(call if_changed,gate)
-
-$(obj)/built-in.o: $(obj)/gate-syms.o
-$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
-
-GATECFLAGS_gate-syms.o = -r
-$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
-	$(call if_changed,gate)
-
-# gate-data.o contains the gate DSO image as data in section .data.gate.
-# We must build gate.so before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/gate-data.o: $(obj)/gate.so
+# The gate DSO image is built using a special linker script.
+include $(srctree)/arch/ia64/kernel/Makefile.gate
+# tell compiled for native
+CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE
 
 # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
 define sed-y
@@ -111,9 +93,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCAR
 clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
 
 #
-# native ivt.S and entry.S
+# native ivt.S, entry.S and fsys.S
 #
-ASM_PARAVIRT_OBJS = ivt.o entry.o
+ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o
 define paravirtualized_native
 AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
 AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/Makefile.gate linux-libre-2.6.30-gnu1/arch/ia64/kernel/Makefile.gate
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/Makefile.gate	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/Makefile.gate	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+# The gate DSO image is built using a special linker script.
+
+targets += gate.so gate-syms.o
+
+extra-y += gate.so gate-syms.o gate.lds gate.o
+
+CPPFLAGS_gate.lds := -P -C -U$(ARCH)
+
+quiet_cmd_gate = GATE $@
+      cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
+		     $(call ld-option, -Wl$(comma)--hash-style=sysv)
+$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
+	$(call if_changed,gate)
+
+$(obj)/built-in.o: $(obj)/gate-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
+
+GATECFLAGS_gate-syms.o = -r
+$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
+	$(call if_changed,gate)
+
+# gate-data.o contains the gate DSO image as data in section .data.gate.
+# We must build gate.so before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .incbin
+$(obj)/gate-data.o: $(obj)/gate.so
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/mca.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/mca.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/mca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/mca.c	2009-06-09 23:05:27.000000000 -0400
@@ -1456,9 +1456,9 @@ ia64_mca_cmc_int_caller(int cmc_irq, voi
 
 	ia64_mca_cmc_int_handler(cmc_irq, arg);
 
-	for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+	cpuid = cpumask_next(cpuid+1, cpu_online_mask);
 
-	if (cpuid < NR_CPUS) {
+	if (cpuid < nr_cpu_ids) {
 		platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
 	} else {
 		/* If no log record, switch out of polling mode */
@@ -1525,7 +1525,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, voi
 
 	ia64_mca_cpe_int_handler(cpe_irq, arg);
 
-	for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+	cpuid = cpumask_next(cpuid+1, cpu_online_mask);
 
 	if (cpuid < NR_CPUS) {
 		platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/module.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/module.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/module.c	2009-06-09 23:05:27.000000000 -0400
@@ -446,6 +446,14 @@ module_frob_arch_sections (Elf_Ehdr *ehd
 			mod->arch.opd = s;
 		else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
 			mod->arch.unwind = s;
+#ifdef CONFIG_PARAVIRT
+		else if (strcmp(".paravirt_bundles",
+				secstrings + s->sh_name) == 0)
+			mod->arch.paravirt_bundles = s;
+		else if (strcmp(".paravirt_insts",
+				secstrings + s->sh_name) == 0)
+			mod->arch.paravirt_insts = s;
+#endif
 
 	if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
 		printk(KERN_ERR "%s: sections missing\n", mod->name);
@@ -525,8 +533,7 @@ get_ltoff (struct module *mod, uint64_t
 			goto found;
 
 	/* Not enough GOT entries? */
-	if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size))
-		BUG();
+	BUG_ON(e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size));
 
 	e->val = value;
 	++mod->arch.next_got_entry;
@@ -921,6 +928,30 @@ module_finalize (const Elf_Ehdr *hdr, co
 	DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
 	if (mod->arch.unwind)
 		register_unwind_table(mod);
+#ifdef CONFIG_PARAVIRT
+        if (mod->arch.paravirt_bundles) {
+                struct paravirt_patch_site_bundle *start =
+                        (struct paravirt_patch_site_bundle *)
+                        mod->arch.paravirt_bundles->sh_addr;
+                struct paravirt_patch_site_bundle *end =
+                        (struct paravirt_patch_site_bundle *)
+                        (mod->arch.paravirt_bundles->sh_addr +
+                         mod->arch.paravirt_bundles->sh_size);
+
+                paravirt_patch_apply_bundle(start, end);
+        }
+        if (mod->arch.paravirt_insts) {
+                struct paravirt_patch_site_inst *start =
+                        (struct paravirt_patch_site_inst *)
+                        mod->arch.paravirt_insts->sh_addr;
+                struct paravirt_patch_site_inst *end =
+                        (struct paravirt_patch_site_inst *)
+                        (mod->arch.paravirt_insts->sh_addr +
+                         mod->arch.paravirt_insts->sh_size);
+
+                paravirt_patch_apply_inst(start, end);
+        }
+#endif
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/msi_ia64.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/msi_ia64.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/msi_ia64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/msi_ia64.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,44 +7,7 @@
 #include <linux/msi.h>
 #include <linux/dmar.h>
 #include <asm/smp.h>
-
-/*
- * Shifts for APIC-based data
- */
-
-#define MSI_DATA_VECTOR_SHIFT		0
-#define	    MSI_DATA_VECTOR(v)		(((u8)v) << MSI_DATA_VECTOR_SHIFT)
-#define MSI_DATA_VECTOR_MASK		0xffffff00
-
-#define MSI_DATA_DELIVERY_SHIFT		8
-#define     MSI_DATA_DELIVERY_FIXED	(0 << MSI_DATA_DELIVERY_SHIFT)
-#define     MSI_DATA_DELIVERY_LOWPRI	(1 << MSI_DATA_DELIVERY_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT		14
-#define     MSI_DATA_LEVEL_DEASSERT	(0 << MSI_DATA_LEVEL_SHIFT)
-#define     MSI_DATA_LEVEL_ASSERT	(1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT		15
-#define     MSI_DATA_TRIGGER_EDGE	(0 << MSI_DATA_TRIGGER_SHIFT)
-#define     MSI_DATA_TRIGGER_LEVEL	(1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for APIC-based bus address
- */
-
-#define MSI_TARGET_CPU_SHIFT		4
-#define MSI_ADDR_HEADER			0xfee00000
-
-#define MSI_ADDR_DESTID_MASK		0xfff0000f
-#define     MSI_ADDR_DESTID_CPU(cpu)	((cpu) << MSI_TARGET_CPU_SHIFT)
-
-#define MSI_ADDR_DESTMODE_SHIFT		2
-#define     MSI_ADDR_DESTMODE_PHYS	(0 << MSI_ADDR_DESTMODE_SHIFT)
-#define	    MSI_ADDR_DESTMODE_LOGIC	(1 << MSI_ADDR_DESTMODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT	3
-#define     MSI_ADDR_REDIRECTION_CPU	(0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define     MSI_ADDR_REDIRECTION_LOWPRI	(1 << MSI_ADDR_REDIRECTION_SHIFT)
+#include <asm/msidef.h>
 
 static struct irq_chip	ia64_msi_chip;
 
@@ -65,8 +28,8 @@ static void ia64_set_msi_irq_affinity(un
 	read_msi_msg(irq, &msg);
 
 	addr = msg.address_lo;
-	addr &= MSI_ADDR_DESTID_MASK;
-	addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
+	addr &= MSI_ADDR_DEST_ID_MASK;
+	addr |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
 	msg.address_lo = addr;
 
 	data = msg.data;
@@ -75,7 +38,7 @@ static void ia64_set_msi_irq_affinity(un
 	msg.data = data;
 
 	write_msi_msg(irq, &msg);
-	irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+	cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
 }
 #endif /* CONFIG_SMP */
 
@@ -98,9 +61,9 @@ int ia64_setup_msi_irq(struct pci_dev *p
 	msg.address_hi = 0;
 	msg.address_lo =
 		MSI_ADDR_HEADER |
-		MSI_ADDR_DESTMODE_PHYS |
+		MSI_ADDR_DEST_MODE_PHYS |
 		MSI_ADDR_REDIRECTION_CPU |
-		MSI_ADDR_DESTID_CPU(dest_phys_id);
+		MSI_ADDR_DEST_ID_CPU(dest_phys_id);
 
 	msg.data =
 		MSI_DATA_TRIGGER_EDGE |
@@ -183,11 +146,11 @@ static void dmar_msi_set_affinity(unsign
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
-	msg.address_lo &= ~MSI_ADDR_DESTID_MASK;
-	msg.address_lo |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
 
 	dmar_msi_write(irq, &msg);
-	irq_desc[irq].affinity = *mask;
+	cpumask_copy(irq_desc[irq].affinity, mask);
 }
 #endif /* CONFIG_SMP */
 
@@ -215,9 +178,9 @@ msi_compose_msg(struct pci_dev *pdev, un
 	msg->address_hi = 0;
 	msg->address_lo =
 		MSI_ADDR_HEADER |
-		MSI_ADDR_DESTMODE_PHYS |
+		MSI_ADDR_DEST_MODE_PHYS |
 		MSI_ADDR_REDIRECTION_CPU |
-		MSI_ADDR_DESTID_CPU(dest);
+		MSI_ADDR_DEST_ID_CPU(dest);
 
 	msg->data =
 		MSI_DATA_TRIGGER_EDGE |
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/palinfo.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/palinfo.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/palinfo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/palinfo.c	2009-06-09 23:05:27.000000000 -0400
@@ -1002,8 +1002,6 @@ create_palinfo_proc_entries(unsigned int
 		*pdir = create_proc_read_entry(
 				palinfo_entries[j].name, 0, cpu_dir,
 				palinfo_read_entry, (void *)f.value);
-		if (*pdir)
-			(*pdir)->owner = THIS_MODULE;
 		pdir++;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,13 +46,23 @@ struct pv_info pv_info = {
  * initialization hooks.
  */
 
-struct pv_init_ops pv_init_ops;
+static void __init
+ia64_native_patch_branch(unsigned long tag, unsigned long type);
+
+struct pv_init_ops pv_init_ops =
+{
+#ifdef ASM_SUPPORTED
+	.patch_bundle = ia64_native_patch_bundle,
+#endif
+	.patch_branch = ia64_native_patch_branch,
+};
 
 /***************************************************************************
  * pv_cpu_ops
  * intrinsics hooks.
  */
 
+#ifndef ASM_SUPPORTED
 /* ia64_native_xxx are macros so that we have to make them real functions */
 
 #define DEFINE_VOID_FUNC1(name)					\
@@ -60,7 +70,14 @@ struct pv_init_ops pv_init_ops;
 	ia64_native_ ## name ## _func(unsigned long arg)	\
 	{							\
 		ia64_native_ ## name(arg);			\
-	}							\
+	}
+
+#define DEFINE_VOID_FUNC1_VOID(name)				\
+	static void						\
+	ia64_native_ ## name ## _func(void *arg)		\
+	{							\
+		ia64_native_ ## name(arg);			\
+	}
 
 #define DEFINE_VOID_FUNC2(name)					\
 	static void						\
@@ -68,7 +85,7 @@ struct pv_init_ops pv_init_ops;
 				      unsigned long arg1)	\
 	{							\
 		ia64_native_ ## name(arg0, arg1);		\
-	}							\
+	}
 
 #define DEFINE_FUNC0(name)			\
 	static unsigned long			\
@@ -84,7 +101,7 @@ struct pv_init_ops pv_init_ops;
 		return ia64_native_ ## name(arg);	\
 	}						\
 
-DEFINE_VOID_FUNC1(fc);
+DEFINE_VOID_FUNC1_VOID(fc);
 DEFINE_VOID_FUNC1(intrin_local_irq_restore);
 
 DEFINE_VOID_FUNC2(ptcga);
@@ -274,6 +291,266 @@ ia64_native_setreg_func(int regnum, unsi
 		break;
 	}
 }
+#else
+
+#define __DEFINE_FUNC(name, code)					\
+	extern const char ia64_native_ ## name ## _direct_start[];	\
+	extern const char ia64_native_ ## name ## _direct_end[];	\
+	asm (".align 32\n"						\
+	     ".proc ia64_native_" #name "_func\n"			\
+	     "ia64_native_" #name "_func:\n"				\
+	     "ia64_native_" #name "_direct_start:\n"			\
+	     code							\
+	     "ia64_native_" #name "_direct_end:\n"			\
+	     "br.cond.sptk.many b6\n"					\
+	     ".endp ia64_native_" #name "_func\n")
+
+#define DEFINE_VOID_FUNC0(name, code)				\
+	extern void						\
+	ia64_native_ ## name ## _func(void);			\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1(name, code)				\
+	extern void						\
+	ia64_native_ ## name ## _func(unsigned long arg);	\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1_VOID(name, code)			\
+	extern void						\
+	ia64_native_ ## name ## _func(void *arg);		\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC2(name, code)				\
+	extern void						\
+	ia64_native_ ## name ## _func(unsigned long arg0,	\
+				      unsigned long arg1);	\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC0(name, code)		\
+	extern unsigned long			\
+	ia64_native_ ## name ## _func(void);	\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC1(name, type, code)			\
+	extern unsigned long				\
+	ia64_native_ ## name ## _func(type arg);	\
+	__DEFINE_FUNC(name, code)
+
+DEFINE_VOID_FUNC1_VOID(fc,
+		       "fc r8\n");
+DEFINE_VOID_FUNC1(intrin_local_irq_restore,
+		  ";;\n"
+		  "     cmp.ne p6, p7 = r8, r0\n"
+		  ";;\n"
+		  "(p6) ssm psr.i\n"
+		  "(p7) rsm psr.i\n"
+		  ";;\n"
+		  "(p6) srlz.d\n");
+
+DEFINE_VOID_FUNC2(ptcga,
+		  "ptc.ga r8, r9\n");
+DEFINE_VOID_FUNC2(set_rr,
+		  "mov rr[r8] = r9\n");
+
+/* ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I */
+DEFINE_FUNC0(get_psr_i,
+	     "mov r2 = " __stringify(1 << IA64_PSR_I_BIT) "\n"
+	     "mov r8 = psr\n"
+	     ";;\n"
+	     "and r8 = r2, r8\n");
+
+DEFINE_FUNC1(thash, unsigned long,
+	     "thash r8 = r8\n");
+DEFINE_FUNC1(get_cpuid, int,
+	     "mov r8 = cpuid[r8]\n");
+DEFINE_FUNC1(get_pmd, int,
+	     "mov r8 = pmd[r8]\n");
+DEFINE_FUNC1(get_rr, unsigned long,
+	     "mov r8 = rr[r8]\n");
+
+DEFINE_VOID_FUNC0(ssm_i,
+		  "ssm psr.i\n");
+DEFINE_VOID_FUNC0(rsm_i,
+		  "rsm psr.i\n");
+
+extern void
+ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
+				unsigned long val2, unsigned long val3,
+				unsigned long val4);
+__DEFINE_FUNC(set_rr0_to_rr4,
+	      "mov rr[r0] = r8\n"
+	      "movl r2 = 0x2000000000000000\n"
+	      ";;\n"
+	      "mov rr[r2] = r9\n"
+	      "shl r3 = r2, 1\n"	/* movl r3 = 0x4000000000000000 */
+	      ";;\n"
+	      "add r2 = r2, r3\n"	/* movl r2 = 0x6000000000000000 */
+	      "mov rr[r3] = r10\n"
+	      ";;\n"
+	      "mov rr[r2] = r11\n"
+	      "shl r3 = r3, 1\n"	/* movl r3 = 0x8000000000000000 */
+	      ";;\n"
+	      "mov rr[r3] = r14\n");
+
+extern unsigned long ia64_native_getreg_func(int regnum);
+asm(".global ia64_native_getreg_func\n");
+#define __DEFINE_GET_REG(id, reg)			\
+	"mov r2 = " __stringify(_IA64_REG_ ## id) "\n"	\
+	";;\n"						\
+	"cmp.eq p6, p0 = r2, r8\n"			\
+	";;\n"						\
+	"(p6) mov r8 = " #reg "\n"			\
+	"(p6) br.cond.sptk.many b6\n"			\
+	";;\n"
+#define __DEFINE_GET_AR(id, reg)	__DEFINE_GET_REG(AR_ ## id, ar.reg)
+#define __DEFINE_GET_CR(id, reg)	__DEFINE_GET_REG(CR_ ## id, cr.reg)
+
+__DEFINE_FUNC(getreg,
+	      __DEFINE_GET_REG(GP, gp)
+	      /*__DEFINE_GET_REG(IP, ip)*/ /* returned ip value shouldn't be constant */
+	      __DEFINE_GET_REG(PSR, psr)
+	      __DEFINE_GET_REG(TP, tp)
+	      __DEFINE_GET_REG(SP, sp)
+
+	      __DEFINE_GET_REG(AR_KR0, ar0)
+	      __DEFINE_GET_REG(AR_KR1, ar1)
+	      __DEFINE_GET_REG(AR_KR2, ar2)
+	      __DEFINE_GET_REG(AR_KR3, ar3)
+	      __DEFINE_GET_REG(AR_KR4, ar4)
+	      __DEFINE_GET_REG(AR_KR5, ar5)
+	      __DEFINE_GET_REG(AR_KR6, ar6)
+	      __DEFINE_GET_REG(AR_KR7, ar7)
+	      __DEFINE_GET_AR(RSC, rsc)
+	      __DEFINE_GET_AR(BSP, bsp)
+	      __DEFINE_GET_AR(BSPSTORE, bspstore)
+	      __DEFINE_GET_AR(RNAT, rnat)
+	      __DEFINE_GET_AR(FCR, fcr)
+	      __DEFINE_GET_AR(EFLAG, eflag)
+	      __DEFINE_GET_AR(CSD, csd)
+	      __DEFINE_GET_AR(SSD, ssd)
+	      __DEFINE_GET_REG(AR_CFLAG, ar27)
+	      __DEFINE_GET_AR(FSR, fsr)
+	      __DEFINE_GET_AR(FIR, fir)
+	      __DEFINE_GET_AR(FDR, fdr)
+	      __DEFINE_GET_AR(CCV, ccv)
+	      __DEFINE_GET_AR(UNAT, unat)
+	      __DEFINE_GET_AR(FPSR, fpsr)
+	      __DEFINE_GET_AR(ITC, itc)
+	      __DEFINE_GET_AR(PFS, pfs)
+	      __DEFINE_GET_AR(LC, lc)
+	      __DEFINE_GET_AR(EC, ec)
+
+	      __DEFINE_GET_CR(DCR, dcr)
+	      __DEFINE_GET_CR(ITM, itm)
+	      __DEFINE_GET_CR(IVA, iva)
+	      __DEFINE_GET_CR(PTA, pta)
+	      __DEFINE_GET_CR(IPSR, ipsr)
+	      __DEFINE_GET_CR(ISR, isr)
+	      __DEFINE_GET_CR(IIP, iip)
+	      __DEFINE_GET_CR(IFA, ifa)
+	      __DEFINE_GET_CR(ITIR, itir)
+	      __DEFINE_GET_CR(IIPA, iipa)
+	      __DEFINE_GET_CR(IFS, ifs)
+	      __DEFINE_GET_CR(IIM, iim)
+	      __DEFINE_GET_CR(IHA, iha)
+	      __DEFINE_GET_CR(LID, lid)
+	      __DEFINE_GET_CR(IVR, ivr)
+	      __DEFINE_GET_CR(TPR, tpr)
+	      __DEFINE_GET_CR(EOI, eoi)
+	      __DEFINE_GET_CR(IRR0, irr0)
+	      __DEFINE_GET_CR(IRR1, irr1)
+	      __DEFINE_GET_CR(IRR2, irr2)
+	      __DEFINE_GET_CR(IRR3, irr3)
+	      __DEFINE_GET_CR(ITV, itv)
+	      __DEFINE_GET_CR(PMV, pmv)
+	      __DEFINE_GET_CR(CMCV, cmcv)
+	      __DEFINE_GET_CR(LRR0, lrr0)
+	      __DEFINE_GET_CR(LRR1, lrr1)
+
+	      "mov r8 = -1\n"	/* unsupported case */
+	);
+
+extern void ia64_native_setreg_func(int regnum, unsigned long val);
+asm(".global ia64_native_setreg_func\n");
+#define __DEFINE_SET_REG(id, reg)			\
+	"mov r2 = " __stringify(_IA64_REG_ ## id) "\n"	\
+	";;\n"						\
+	"cmp.eq p6, p0 = r2, r9\n"			\
+	";;\n"						\
+	"(p6) mov " #reg " = r8\n"			\
+	"(p6) br.cond.sptk.many b6\n"			\
+	";;\n"
+#define __DEFINE_SET_AR(id, reg)	__DEFINE_SET_REG(AR_ ## id, ar.reg)
+#define __DEFINE_SET_CR(id, reg)	__DEFINE_SET_REG(CR_ ## id, cr.reg)
+__DEFINE_FUNC(setreg,
+	      "mov r2 = " __stringify(_IA64_REG_PSR_L) "\n"
+	      ";;\n"
+	      "cmp.eq p6, p0 = r2, r9\n"
+	      ";;\n"
+	      "(p6) mov psr.l = r8\n"
+#ifdef HAVE_SERIALIZE_DIRECTIVE
+	      ".serialize.data\n"
+#endif
+	      "(p6) br.cond.sptk.many b6\n"
+	      __DEFINE_SET_REG(GP, gp)
+	      __DEFINE_SET_REG(SP, sp)
+
+	      __DEFINE_SET_REG(AR_KR0, ar0)
+	      __DEFINE_SET_REG(AR_KR1, ar1)
+	      __DEFINE_SET_REG(AR_KR2, ar2)
+	      __DEFINE_SET_REG(AR_KR3, ar3)
+	      __DEFINE_SET_REG(AR_KR4, ar4)
+	      __DEFINE_SET_REG(AR_KR5, ar5)
+	      __DEFINE_SET_REG(AR_KR6, ar6)
+	      __DEFINE_SET_REG(AR_KR7, ar7)
+	      __DEFINE_SET_AR(RSC, rsc)
+	      __DEFINE_SET_AR(BSP, bsp)
+	      __DEFINE_SET_AR(BSPSTORE, bspstore)
+	      __DEFINE_SET_AR(RNAT, rnat)
+	      __DEFINE_SET_AR(FCR, fcr)
+	      __DEFINE_SET_AR(EFLAG, eflag)
+	      __DEFINE_SET_AR(CSD, csd)
+	      __DEFINE_SET_AR(SSD, ssd)
+	      __DEFINE_SET_REG(AR_CFLAG, ar27)
+	      __DEFINE_SET_AR(FSR, fsr)
+	      __DEFINE_SET_AR(FIR, fir)
+	      __DEFINE_SET_AR(FDR, fdr)
+	      __DEFINE_SET_AR(CCV, ccv)
+	      __DEFINE_SET_AR(UNAT, unat)
+	      __DEFINE_SET_AR(FPSR, fpsr)
+	      __DEFINE_SET_AR(ITC, itc)
+	      __DEFINE_SET_AR(PFS, pfs)
+	      __DEFINE_SET_AR(LC, lc)
+	      __DEFINE_SET_AR(EC, ec)
+
+	      __DEFINE_SET_CR(DCR, dcr)
+	      __DEFINE_SET_CR(ITM, itm)
+	      __DEFINE_SET_CR(IVA, iva)
+	      __DEFINE_SET_CR(PTA, pta)
+	      __DEFINE_SET_CR(IPSR, ipsr)
+	      __DEFINE_SET_CR(ISR, isr)
+	      __DEFINE_SET_CR(IIP, iip)
+	      __DEFINE_SET_CR(IFA, ifa)
+	      __DEFINE_SET_CR(ITIR, itir)
+	      __DEFINE_SET_CR(IIPA, iipa)
+	      __DEFINE_SET_CR(IFS, ifs)
+	      __DEFINE_SET_CR(IIM, iim)
+	      __DEFINE_SET_CR(IHA, iha)
+	      __DEFINE_SET_CR(LID, lid)
+	      __DEFINE_SET_CR(IVR, ivr)
+	      __DEFINE_SET_CR(TPR, tpr)
+	      __DEFINE_SET_CR(EOI, eoi)
+	      __DEFINE_SET_CR(IRR0, irr0)
+	      __DEFINE_SET_CR(IRR1, irr1)
+	      __DEFINE_SET_CR(IRR2, irr2)
+	      __DEFINE_SET_CR(IRR3, irr3)
+	      __DEFINE_SET_CR(ITV, itv)
+	      __DEFINE_SET_CR(PMV, pmv)
+	      __DEFINE_SET_CR(CMCV, cmcv)
+	      __DEFINE_SET_CR(LRR0, lrr0)
+	      __DEFINE_SET_CR(LRR1, lrr1)
+	);
+#endif
 
 struct pv_cpu_ops pv_cpu_ops = {
 	.fc		= ia64_native_fc_func,
@@ -366,4 +643,258 @@ ia64_native_do_steal_accounting(unsigned
 
 struct pv_time_ops pv_time_ops = {
 	.do_steal_accounting = ia64_native_do_steal_accounting,
+	.sched_clock = ia64_native_sched_clock,
 };
+
+/***************************************************************************
+ * binary pacthing
+ * pv_init_ops.patch_bundle
+ */
+
+#ifdef ASM_SUPPORTED
+#define IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg)	\
+	__DEFINE_FUNC(get_ ## name,			\
+		      ";;\n"				\
+		      "mov r8 = " #reg "\n"		\
+		      ";;\n")
+
+#define IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg)	\
+	__DEFINE_FUNC(set_ ## name,			\
+		      ";;\n"				\
+		      "mov " #reg " = r8\n"		\
+		      ";;\n")
+
+#define IA64_NATIVE_PATCH_DEFINE_REG(name, reg)		\
+	IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg);	\
+	IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg)	\
+
+#define IA64_NATIVE_PATCH_DEFINE_AR(name, reg)			\
+	IA64_NATIVE_PATCH_DEFINE_REG(ar_ ## name, ar.reg)
+
+#define IA64_NATIVE_PATCH_DEFINE_CR(name, reg)			\
+	IA64_NATIVE_PATCH_DEFINE_REG(cr_ ## name, cr.reg)
+
+
+IA64_NATIVE_PATCH_DEFINE_GET_REG(psr, psr);
+IA64_NATIVE_PATCH_DEFINE_GET_REG(tp, tp);
+
+/* IA64_NATIVE_PATCH_DEFINE_SET_REG(psr_l, psr.l); */
+__DEFINE_FUNC(set_psr_l,
+	      ";;\n"
+	      "mov psr.l = r8\n"
+#ifdef HAVE_SERIALIZE_DIRECTIVE
+	      ".serialize.data\n"
+#endif
+	      ";;\n");
+
+IA64_NATIVE_PATCH_DEFINE_REG(gp, gp);
+IA64_NATIVE_PATCH_DEFINE_REG(sp, sp);
+
+IA64_NATIVE_PATCH_DEFINE_REG(kr0, ar0);
+IA64_NATIVE_PATCH_DEFINE_REG(kr1, ar1);
+IA64_NATIVE_PATCH_DEFINE_REG(kr2, ar2);
+IA64_NATIVE_PATCH_DEFINE_REG(kr3, ar3);
+IA64_NATIVE_PATCH_DEFINE_REG(kr4, ar4);
+IA64_NATIVE_PATCH_DEFINE_REG(kr5, ar5);
+IA64_NATIVE_PATCH_DEFINE_REG(kr6, ar6);
+IA64_NATIVE_PATCH_DEFINE_REG(kr7, ar7);
+
+IA64_NATIVE_PATCH_DEFINE_AR(rsc, rsc);
+IA64_NATIVE_PATCH_DEFINE_AR(bsp, bsp);
+IA64_NATIVE_PATCH_DEFINE_AR(bspstore, bspstore);
+IA64_NATIVE_PATCH_DEFINE_AR(rnat, rnat);
+IA64_NATIVE_PATCH_DEFINE_AR(fcr, fcr);
+IA64_NATIVE_PATCH_DEFINE_AR(eflag, eflag);
+IA64_NATIVE_PATCH_DEFINE_AR(csd, csd);
+IA64_NATIVE_PATCH_DEFINE_AR(ssd, ssd);
+IA64_NATIVE_PATCH_DEFINE_REG(ar27, ar27);
+IA64_NATIVE_PATCH_DEFINE_AR(fsr, fsr);
+IA64_NATIVE_PATCH_DEFINE_AR(fir, fir);
+IA64_NATIVE_PATCH_DEFINE_AR(fdr, fdr);
+IA64_NATIVE_PATCH_DEFINE_AR(ccv, ccv);
+IA64_NATIVE_PATCH_DEFINE_AR(unat, unat);
+IA64_NATIVE_PATCH_DEFINE_AR(fpsr, fpsr);
+IA64_NATIVE_PATCH_DEFINE_AR(itc, itc);
+IA64_NATIVE_PATCH_DEFINE_AR(pfs, pfs);
+IA64_NATIVE_PATCH_DEFINE_AR(lc, lc);
+IA64_NATIVE_PATCH_DEFINE_AR(ec, ec);
+
+IA64_NATIVE_PATCH_DEFINE_CR(dcr, dcr);
+IA64_NATIVE_PATCH_DEFINE_CR(itm, itm);
+IA64_NATIVE_PATCH_DEFINE_CR(iva, iva);
+IA64_NATIVE_PATCH_DEFINE_CR(pta, pta);
+IA64_NATIVE_PATCH_DEFINE_CR(ipsr, ipsr);
+IA64_NATIVE_PATCH_DEFINE_CR(isr, isr);
+IA64_NATIVE_PATCH_DEFINE_CR(iip, iip);
+IA64_NATIVE_PATCH_DEFINE_CR(ifa, ifa);
+IA64_NATIVE_PATCH_DEFINE_CR(itir, itir);
+IA64_NATIVE_PATCH_DEFINE_CR(iipa, iipa);
+IA64_NATIVE_PATCH_DEFINE_CR(ifs, ifs);
+IA64_NATIVE_PATCH_DEFINE_CR(iim, iim);
+IA64_NATIVE_PATCH_DEFINE_CR(iha, iha);
+IA64_NATIVE_PATCH_DEFINE_CR(lid, lid);
+IA64_NATIVE_PATCH_DEFINE_CR(ivr, ivr);
+IA64_NATIVE_PATCH_DEFINE_CR(tpr, tpr);
+IA64_NATIVE_PATCH_DEFINE_CR(eoi, eoi);
+IA64_NATIVE_PATCH_DEFINE_CR(irr0, irr0);
+IA64_NATIVE_PATCH_DEFINE_CR(irr1, irr1);
+IA64_NATIVE_PATCH_DEFINE_CR(irr2, irr2);
+IA64_NATIVE_PATCH_DEFINE_CR(irr3, irr3);
+IA64_NATIVE_PATCH_DEFINE_CR(itv, itv);
+IA64_NATIVE_PATCH_DEFINE_CR(pmv, pmv);
+IA64_NATIVE_PATCH_DEFINE_CR(cmcv, cmcv);
+IA64_NATIVE_PATCH_DEFINE_CR(lrr0, lrr0);
+IA64_NATIVE_PATCH_DEFINE_CR(lrr1, lrr1);
+
+static const struct paravirt_patch_bundle_elem ia64_native_patch_bundle_elems[]
+__initdata_or_module =
+{
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM(name, type)		\
+	{							\
+		(void*)ia64_native_ ## name ## _direct_start,	\
+		(void*)ia64_native_ ## name ## _direct_end,	\
+		PARAVIRT_PATCH_TYPE_ ## type,			\
+	}
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(fc, FC),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(thash, THASH),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(ptcga, PTCGA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(get_rr, GET_RR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr, SET_RR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(ssm_i, SSM_I),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(rsm_i, RSM_I),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM(intrin_local_irq_restore,
+				      INTRIN_LOCAL_IRQ_RESTORE),
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg)			\
+	{								\
+		(void*)ia64_native_get_ ## name ## _direct_start,	\
+		(void*)ia64_native_get_ ## name ## _direct_end,		\
+		PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg,		\
+	}
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg)			\
+	{								\
+		(void*)ia64_native_set_ ## name ## _direct_start,	\
+		(void*)ia64_native_set_ ## name ## _direct_end,		\
+		PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg,		\
+	}
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(name, reg)		\
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg),	\
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg)		\
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(name, reg)		\
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar_ ## name, AR_ ## reg)
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(name, reg)		\
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(cr_ ## name, CR_ ## reg)
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(psr, PSR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(tp, TP),
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(psr_l, PSR_L),
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(gp, GP),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(sp, SP),
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr0, AR_KR0),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr1, AR_KR1),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr2, AR_KR2),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr3, AR_KR3),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr4, AR_KR4),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr5, AR_KR5),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr6, AR_KR6),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr7, AR_KR7),
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rsc, RSC),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bsp, BSP),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bspstore, BSPSTORE),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rnat, RNAT),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fcr, FCR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(eflag, EFLAG),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(csd, CSD),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ssd, SSD),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar27, AR_CFLAG),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fsr, FSR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fir, FIR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fdr, FDR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ccv, CCV),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(unat, UNAT),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fpsr, FPSR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(itc, ITC),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(pfs, PFS),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(lc, LC),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ec, EC),
+
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(dcr, DCR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itm, ITM),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iva, IVA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pta, PTA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ipsr, IPSR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(isr, ISR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iip, IIP),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifa, IFA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itir, ITIR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iipa, IIPA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifs, IFS),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iim, IIM),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iha, IHA),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lid, LID),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ivr, IVR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(tpr, TPR),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(eoi, EOI),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr0, IRR0),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr1, IRR1),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr2, IRR2),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr3, IRR3),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itv, ITV),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pmv, PMV),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(cmcv, CMCV),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr0, LRR0),
+	IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr1, LRR1),
+};
+
+unsigned long __init_or_module
+ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type)
+{
+	const unsigned long nelems = sizeof(ia64_native_patch_bundle_elems) /
+		sizeof(ia64_native_patch_bundle_elems[0]);
+
+	return __paravirt_patch_apply_bundle(sbundle, ebundle, type,
+					      ia64_native_patch_bundle_elems,
+					      nelems, NULL);
+}
+#endif /* ASM_SUPPOTED */
+
+extern const char ia64_native_switch_to[];
+extern const char ia64_native_leave_syscall[];
+extern const char ia64_native_work_processed_syscall[];
+extern const char ia64_native_leave_kernel[];
+
+const struct paravirt_patch_branch_target ia64_native_branch_target[]
+__initconst = {
+#define PARAVIRT_BR_TARGET(name, type)			\
+	{						\
+		ia64_native_ ## name,			\
+		PARAVIRT_PATCH_TYPE_BR_ ## type,	\
+	}
+	PARAVIRT_BR_TARGET(switch_to, SWITCH_TO),
+	PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL),
+	PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL),
+	PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL),
+};
+
+static void __init
+ia64_native_patch_branch(unsigned long tag, unsigned long type)
+{
+	const unsigned long nelem =
+		sizeof(ia64_native_branch_target) /
+		sizeof(ia64_native_branch_target[0]);
+	__paravirt_patch_apply_branch(tag, type,
+				      ia64_native_branch_target, nelem);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirtentry.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirtentry.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirtentry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirtentry.S	2009-06-09 23:05:27.000000000 -0400
@@ -20,8 +20,11 @@
  *
  */
 
+#include <linux/init.h>
 #include <asm/asmmacro.h>
 #include <asm/asm-offsets.h>
+#include <asm/paravirt_privop.h>
+#include <asm/paravirt_patch.h>
 #include "entry.h"
 
 #define DATA8(sym, init_value)			\
@@ -32,29 +35,87 @@
 	data8 init_value ;			\
 	.popsection
 
-#define BRANCH(targ, reg, breg)		\
-	movl reg=targ ;			\
-	;;				\
-	ld8 reg=[reg] ;			\
-	;;				\
-	mov breg=reg ;			\
+#define BRANCH(targ, reg, breg, type)					\
+	PARAVIRT_PATCH_SITE_BR(PARAVIRT_PATCH_TYPE_BR_ ## type) ;	\
+	;;								\
+	movl reg=targ ;							\
+	;;								\
+	ld8 reg=[reg] ;							\
+	;;								\
+	mov breg=reg ;							\
 	br.cond.sptk.many breg
 
-#define BRANCH_PROC(sym, reg, breg)				\
-	DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
-	GLOBAL_ENTRY(paravirt_ ## sym) ;			\
-		BRANCH(paravirt_ ## sym ## _targ, reg, breg) ;	\
+#define BRANCH_PROC(sym, reg, breg, type)				\
+	DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ;		\
+	GLOBAL_ENTRY(paravirt_ ## sym) ;				\
+		BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ;	\
 	END(paravirt_ ## sym)
 
-#define BRANCH_PROC_UNWINFO(sym, reg, breg)			\
-	DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
-	GLOBAL_ENTRY(paravirt_ ## sym) ;			\
-		PT_REGS_UNWIND_INFO(0) ;			\
-		BRANCH(paravirt_ ## sym ## _targ, reg, breg) ;	\
+#define BRANCH_PROC_UNWINFO(sym, reg, breg, type)			\
+	DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ;		\
+	GLOBAL_ENTRY(paravirt_ ## sym) ;				\
+		PT_REGS_UNWIND_INFO(0) ;				\
+		BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ;	\
 	END(paravirt_ ## sym)
 
 
-BRANCH_PROC(switch_to, r22, b7)
-BRANCH_PROC_UNWINFO(leave_syscall, r22, b7)
-BRANCH_PROC(work_processed_syscall, r2, b7)
-BRANCH_PROC_UNWINFO(leave_kernel, r22, b7)
+BRANCH_PROC(switch_to, r22, b7, SWITCH_TO)
+BRANCH_PROC_UNWINFO(leave_syscall, r22, b7, LEAVE_SYSCALL)
+BRANCH_PROC(work_processed_syscall, r2, b7, WORK_PROCESSED_SYSCALL)
+BRANCH_PROC_UNWINFO(leave_kernel, r22, b7, LEAVE_KERNEL)
+
+
+#ifdef CONFIG_MODULES
+#define __INIT_OR_MODULE	.text
+#define __INITDATA_OR_MODULE	.data
+#else
+#define __INIT_OR_MODULE	__INIT
+#define __INITDATA_OR_MODULE	__INITDATA
+#endif /* CONFIG_MODULES */
+
+	__INIT_OR_MODULE
+	GLOBAL_ENTRY(paravirt_fc_i)
+	fc.i r32
+	br.ret.sptk.many rp
+	END(paravirt_fc_i)
+	__FINIT
+
+	__INIT_OR_MODULE
+	.align 32
+	GLOBAL_ENTRY(paravirt_nop_b_inst_bundle)
+	{
+		nop.b 0
+		nop.b 0
+		nop.b 0
+	}
+	END(paravirt_nop_b_inst_bundle)
+	__FINIT
+
+	/* NOTE: nop.[mfi] has same format */
+	__INIT_OR_MODULE
+	GLOBAL_ENTRY(paravirt_nop_mfi_inst_bundle)
+	{
+		nop.m 0
+		nop.f 0
+		nop.i 0
+	}
+	END(paravirt_nop_mfi_inst_bundle)
+	__FINIT
+
+	__INIT_OR_MODULE
+	GLOBAL_ENTRY(paravirt_nop_bundle)
+paravirt_nop_bundle_start:
+	{
+		nop 0
+		nop 0
+		nop 0
+	}
+paravirt_nop_bundle_end:
+	END(paravirt_nop_bundle)
+	__FINIT
+
+	__INITDATA_OR_MODULE
+	.align 8
+	.global paravirt_nop_bundle_size
+paravirt_nop_bundle_size:
+	data8	paravirt_nop_bundle_end - paravirt_nop_bundle_start
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patch.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patch.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patch.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patch.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,514 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_patch.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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 <asm/intrinsics.h>
+#include <asm/kprobes.h>
+#include <asm/paravirt.h>
+#include <asm/paravirt_patch.h>
+
+typedef union ia64_inst {
+        struct {
+		unsigned long long qp : 6;
+		unsigned long long : 31;
+		unsigned long long opcode : 4;
+		unsigned long long reserved : 23;
+        } generic;
+        unsigned long long l;
+} ia64_inst_t;
+
+/*
+ * flush_icache_range() can't be used here.
+ * we are here before cpu_init() which initializes
+ * ia64_i_cache_stride_shift. flush_icache_range() uses it.
+ */
+void __init_or_module
+paravirt_flush_i_cache_range(const void *instr, unsigned long size)
+{
+	extern void paravirt_fc_i(const void *addr);
+	unsigned long i;
+
+	for (i = 0; i < size; i += sizeof(bundle_t))
+		paravirt_fc_i(instr + i);
+}
+
+bundle_t* __init_or_module
+paravirt_get_bundle(unsigned long tag)
+{
+	return (bundle_t *)(tag & ~3UL);
+}
+
+unsigned long __init_or_module
+paravirt_get_slot(unsigned long tag)
+{
+	return tag & 3UL;
+}
+
+unsigned long __init_or_module
+paravirt_get_num_inst(unsigned long stag, unsigned long etag)
+{
+	bundle_t *sbundle = paravirt_get_bundle(stag);
+	unsigned long sslot = paravirt_get_slot(stag);
+	bundle_t *ebundle = paravirt_get_bundle(etag);
+	unsigned long eslot = paravirt_get_slot(etag);
+
+	return (ebundle - sbundle) * 3 + eslot - sslot + 1;
+}
+
+unsigned long __init_or_module
+paravirt_get_next_tag(unsigned long tag)
+{
+	unsigned long slot = paravirt_get_slot(tag);
+
+	switch (slot) {
+	case 0:
+	case 1:
+		return tag + 1;
+	case 2: {
+		bundle_t *bundle = paravirt_get_bundle(tag);
+		return (unsigned long)(bundle + 1);
+	}
+	default:
+		BUG();
+	}
+	/* NOTREACHED */
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot0(const bundle_t *bundle)
+{
+	ia64_inst_t inst;
+	inst.l = bundle->quad0.slot0;
+	return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot1(const bundle_t *bundle)
+{
+	ia64_inst_t inst;
+	inst.l = bundle->quad0.slot1_p0 |
+		((unsigned long long)bundle->quad1.slot1_p1 << 18UL);
+	return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot2(const bundle_t *bundle)
+{
+	ia64_inst_t inst;
+	inst.l = bundle->quad1.slot2;
+	return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_inst(unsigned long tag)
+{
+	bundle_t *bundle = paravirt_get_bundle(tag);
+	unsigned long slot = paravirt_get_slot(tag);
+
+	switch (slot) {
+	case 0:
+		return paravirt_read_slot0(bundle);
+	case 1:
+		return paravirt_read_slot1(bundle);
+	case 2:
+		return paravirt_read_slot2(bundle);
+	default:
+		BUG();
+	}
+	/* NOTREACHED */
+}
+
+void __init_or_module
+paravirt_write_slot0(bundle_t *bundle, ia64_inst_t inst)
+{
+	bundle->quad0.slot0 = inst.l;
+}
+
+void __init_or_module
+paravirt_write_slot1(bundle_t *bundle, ia64_inst_t inst)
+{
+	bundle->quad0.slot1_p0 = inst.l;
+	bundle->quad1.slot1_p1 = inst.l >> 18UL;
+}
+
+void __init_or_module
+paravirt_write_slot2(bundle_t *bundle, ia64_inst_t inst)
+{
+	bundle->quad1.slot2 = inst.l;
+}
+
+void __init_or_module
+paravirt_write_inst(unsigned long tag, ia64_inst_t inst)
+{
+	bundle_t *bundle = paravirt_get_bundle(tag);
+	unsigned long slot = paravirt_get_slot(tag);
+
+	switch (slot) {
+	case 0:
+		paravirt_write_slot0(bundle, inst);
+		break;
+	case 1:
+		paravirt_write_slot1(bundle, inst);
+		break;
+	case 2:
+		paravirt_write_slot2(bundle, inst);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	paravirt_flush_i_cache_range(bundle, sizeof(*bundle));
+}
+
+/* for debug */
+void
+paravirt_print_bundle(const bundle_t *bundle)
+{
+	const unsigned long *quad = (const unsigned long *)bundle;
+	ia64_inst_t slot0 = paravirt_read_slot0(bundle);
+	ia64_inst_t slot1 = paravirt_read_slot1(bundle);
+	ia64_inst_t slot2 = paravirt_read_slot2(bundle);
+
+	printk(KERN_DEBUG
+	       "bundle 0x%p 0x%016lx 0x%016lx\n", bundle, quad[0], quad[1]);
+	printk(KERN_DEBUG
+	       "bundle template 0x%x\n",
+	       bundle->quad0.template);
+	printk(KERN_DEBUG
+	       "slot0 0x%lx slot1_p0 0x%lx slot1_p1 0x%lx slot2 0x%lx\n",
+	       (unsigned long)bundle->quad0.slot0,
+	       (unsigned long)bundle->quad0.slot1_p0,
+	       (unsigned long)bundle->quad1.slot1_p1,
+	       (unsigned long)bundle->quad1.slot2);
+	printk(KERN_DEBUG
+	       "slot0 0x%016llx slot1 0x%016llx slot2 0x%016llx\n",
+	       slot0.l, slot1.l, slot2.l);
+}
+
+static int noreplace_paravirt __init_or_module = 0;
+
+static int __init setup_noreplace_paravirt(char *str)
+{
+	noreplace_paravirt = 1;
+	return 1;
+}
+__setup("noreplace-paravirt", setup_noreplace_paravirt);
+
+#ifdef ASM_SUPPORTED
+static void __init_or_module
+fill_nop_bundle(void *sbundle, void *ebundle)
+{
+	extern const char paravirt_nop_bundle[];
+	extern const unsigned long paravirt_nop_bundle_size;
+
+	void *bundle = sbundle;
+
+	BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
+	BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
+
+	while (bundle < ebundle) {
+		memcpy(bundle, paravirt_nop_bundle, paravirt_nop_bundle_size);
+
+		bundle += paravirt_nop_bundle_size;
+	}
+}
+
+/* helper function */
+unsigned long __init_or_module
+__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
+			      const struct paravirt_patch_bundle_elem *elems,
+			      unsigned long nelems,
+			      const struct paravirt_patch_bundle_elem **found)
+{
+	unsigned long used = 0;
+	unsigned long i;
+
+	BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
+	BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
+
+	found = NULL;
+	for (i = 0; i < nelems; i++) {
+		const struct paravirt_patch_bundle_elem *p = &elems[i];
+		if (p->type == type) {
+			unsigned long need = p->ebundle - p->sbundle;
+			unsigned long room = ebundle - sbundle;
+
+			if (found != NULL)
+				*found = p;
+
+			if (room < need) {
+				/* no room to replace. skip it */
+				printk(KERN_DEBUG
+				       "the space is too small to put "
+				       "bundles. type %ld need %ld room %ld\n",
+				       type, need, room);
+				break;
+			}
+
+			used = need;
+			memcpy(sbundle, p->sbundle, used);
+			break;
+		}
+	}
+
+	return used;
+}
+
+void __init_or_module
+paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
+			    const struct paravirt_patch_site_bundle *end)
+{
+	const struct paravirt_patch_site_bundle *p;
+
+	if (noreplace_paravirt)
+		return;
+	if (pv_init_ops.patch_bundle == NULL)
+		return;
+
+	for (p = start; p < end; p++) {
+		unsigned long used;
+
+		used = (*pv_init_ops.patch_bundle)(p->sbundle, p->ebundle,
+						   p->type);
+		if (used == 0)
+			continue;
+
+		fill_nop_bundle(p->sbundle + used, p->ebundle);
+		paravirt_flush_i_cache_range(p->sbundle,
+					     p->ebundle - p->sbundle);
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+/*
+ * nop.i, nop.m, nop.f instruction are same format.
+ * but nop.b has differennt format.
+ * This doesn't support nop.b for now.
+ */
+static void __init_or_module
+fill_nop_inst(unsigned long stag, unsigned long etag)
+{
+	extern const bundle_t paravirt_nop_mfi_inst_bundle[];
+	unsigned long tag;
+	const ia64_inst_t nop_inst =
+		paravirt_read_slot0(paravirt_nop_mfi_inst_bundle);
+
+	for (tag = stag; tag < etag; tag = paravirt_get_next_tag(tag))
+		paravirt_write_inst(tag, nop_inst);
+}
+
+void __init_or_module
+paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
+			  const struct paravirt_patch_site_inst *end)
+{
+	const struct paravirt_patch_site_inst *p;
+
+	if (noreplace_paravirt)
+		return;
+	if (pv_init_ops.patch_inst == NULL)
+		return;
+
+	for (p = start; p < end; p++) {
+		unsigned long tag;
+		bundle_t *sbundle;
+		bundle_t *ebundle;
+
+		tag = (*pv_init_ops.patch_inst)(p->stag, p->etag, p->type);
+		if (tag == p->stag)
+			continue;
+
+		fill_nop_inst(tag, p->etag);
+		sbundle = paravirt_get_bundle(p->stag);
+		ebundle = paravirt_get_bundle(p->etag) + 1;
+		paravirt_flush_i_cache_range(sbundle, (ebundle - sbundle) *
+					     sizeof(bundle_t));
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+#endif /* ASM_SUPPOTED */
+
+/* brl.cond.sptk.many <target64> X3 */
+typedef union inst_x3_op {
+	ia64_inst_t inst;
+	struct {
+		unsigned long qp: 6;
+		unsigned long btyp: 3;
+		unsigned long unused: 3;
+		unsigned long p: 1;
+		unsigned long imm20b: 20;
+		unsigned long wh: 2;
+		unsigned long d: 1;
+		unsigned long i: 1;
+		unsigned long opcode: 4;
+	};
+	unsigned long l;
+} inst_x3_op_t;
+
+typedef union inst_x3_imm {
+	ia64_inst_t inst;
+	struct {
+		unsigned long unused: 2;
+		unsigned long imm39: 39;
+	};
+	unsigned long l;
+} inst_x3_imm_t;
+
+void __init_or_module
+paravirt_patch_reloc_brl(unsigned long tag, const void *target)
+{
+	unsigned long tag_op = paravirt_get_next_tag(tag);
+	unsigned long tag_imm = tag;
+	bundle_t *bundle = paravirt_get_bundle(tag);
+
+	ia64_inst_t inst_op = paravirt_read_inst(tag_op);
+	ia64_inst_t inst_imm = paravirt_read_inst(tag_imm);
+
+	inst_x3_op_t inst_x3_op = { .l = inst_op.l };
+	inst_x3_imm_t inst_x3_imm = { .l = inst_imm.l };
+
+	unsigned long imm60 =
+		((unsigned long)target - (unsigned long)bundle) >> 4;
+
+	BUG_ON(paravirt_get_slot(tag) != 1); /* MLX */
+	BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
+
+	/* imm60[59] 1bit */
+	inst_x3_op.i = (imm60 >> 59) & 1;
+	/* imm60[19:0] 20bit */
+	inst_x3_op.imm20b = imm60 & ((1UL << 20) - 1);
+	/* imm60[58:20] 39bit */
+	inst_x3_imm.imm39 = (imm60 >> 20) & ((1UL << 39) - 1);
+
+	inst_op.l = inst_x3_op.l;
+	inst_imm.l = inst_x3_imm.l;
+
+	paravirt_write_inst(tag_op, inst_op);
+	paravirt_write_inst(tag_imm, inst_imm);
+}
+
+/* br.cond.sptk.many <target25>	B1 */
+typedef union inst_b1 {
+	ia64_inst_t inst;
+	struct {
+		unsigned long qp: 6;
+		unsigned long btype: 3;
+		unsigned long unused: 3;
+		unsigned long p: 1;
+		unsigned long imm20b: 20;
+		unsigned long wh: 2;
+		unsigned long d: 1;
+		unsigned long s: 1;
+		unsigned long opcode: 4;
+	};
+	unsigned long l;
+} inst_b1_t;
+
+void __init
+paravirt_patch_reloc_br(unsigned long tag, const void *target)
+{
+	bundle_t *bundle = paravirt_get_bundle(tag);
+	ia64_inst_t inst = paravirt_read_inst(tag);
+	unsigned long target25 = (unsigned long)target - (unsigned long)bundle;
+	inst_b1_t inst_b1;
+
+	BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
+
+	inst_b1.l = inst.l;
+	if (target25 & (1UL << 63))
+		inst_b1.s = 1;
+	else
+		inst_b1.s = 0;
+
+	inst_b1.imm20b = target25 >> 4;
+	inst.l = inst_b1.l;
+
+	paravirt_write_inst(tag, inst);
+}
+
+void __init
+__paravirt_patch_apply_branch(
+	unsigned long tag, unsigned long type,
+	const struct paravirt_patch_branch_target *entries,
+	unsigned int nr_entries)
+{
+	unsigned int i;
+	for (i = 0; i < nr_entries; i++) {
+		if (entries[i].type == type) {
+			paravirt_patch_reloc_br(tag, entries[i].entry);
+			break;
+		}
+	}
+}
+
+static void __init
+paravirt_patch_apply_branch(const struct paravirt_patch_site_branch *start,
+			    const struct paravirt_patch_site_branch *end)
+{
+	const struct paravirt_patch_site_branch *p;
+
+	if (noreplace_paravirt)
+		return;
+	if (pv_init_ops.patch_branch == NULL)
+		return;
+
+	for (p = start; p < end; p++)
+		(*pv_init_ops.patch_branch)(p->tag, p->type);
+
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+void __init
+paravirt_patch_apply(void)
+{
+	extern const char __start_paravirt_bundles[];
+	extern const char __stop_paravirt_bundles[];
+	extern const char __start_paravirt_insts[];
+	extern const char __stop_paravirt_insts[];
+	extern const char __start_paravirt_branches[];
+	extern const char __stop_paravirt_branches[];
+
+	paravirt_patch_apply_bundle((const struct paravirt_patch_site_bundle *)
+				    __start_paravirt_bundles,
+				    (const struct paravirt_patch_site_bundle *)
+				    __stop_paravirt_bundles);
+	paravirt_patch_apply_inst((const struct paravirt_patch_site_inst *)
+				  __start_paravirt_insts,
+				  (const struct paravirt_patch_site_inst *)
+				  __stop_paravirt_insts);
+	paravirt_patch_apply_branch((const struct paravirt_patch_site_branch *)
+				    __start_paravirt_branches,
+				    (const struct paravirt_patch_site_branch *)
+				    __stop_paravirt_branches);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "linux"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patchlist.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patchlist.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patchlist.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patchlist.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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/bug.h>
+#include <asm/paravirt.h>
+
+#define DECLARE(name)						\
+	extern unsigned long					\
+		__ia64_native_start_gate_##name##_patchlist[];	\
+	extern unsigned long					\
+		__ia64_native_end_gate_##name##_patchlist[]
+
+DECLARE(fsyscall);
+DECLARE(brl_fsys_bubble_down);
+DECLARE(vtop);
+DECLARE(mckinley_e9);
+
+extern unsigned long __start_gate_section[];
+
+#define ASSIGN(name)							    \
+	.start_##name##_patchlist =					    \
+		(unsigned long)__ia64_native_start_gate_##name##_patchlist, \
+	.end_##name##_patchlist =					    \
+		(unsigned long)__ia64_native_end_gate_##name##_patchlist
+
+struct pv_patchdata pv_patchdata __initdata = {
+	ASSIGN(fsyscall),
+	ASSIGN(brl_fsys_bubble_down),
+	ASSIGN(vtop),
+	ASSIGN(mckinley_e9),
+
+	.gate_section = (void*)__start_gate_section,
+};
+
+
+unsigned long __init
+paravirt_get_gate_patchlist(enum pv_gate_patchlist type)
+{
+
+#define CASE(NAME, name)					\
+	case PV_GATE_START_##NAME:				\
+		return pv_patchdata.start_##name##_patchlist;	\
+	case PV_GATE_END_##NAME:				\
+		return pv_patchdata.end_##name##_patchlist;	\
+
+	switch (type) {
+		CASE(FSYSCALL, fsyscall);
+		CASE(BRL_FSYS_BUBBLE_DOWN, brl_fsys_bubble_down);
+		CASE(VTOP, vtop);
+		CASE(MCKINLEY_E9, mckinley_e9);
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+void * __init
+paravirt_get_gate_section(void)
+{
+	return pv_patchdata.gate_section;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patchlist.h linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patchlist.h
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/paravirt_patchlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/paravirt_patchlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_patchlist.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.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; 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
+ *
+ */
+
+#if defined(__IA64_GATE_PARAVIRTUALIZED_XEN)
+#include <asm/xen/patchlist.h>
+#else
+#include <asm/native/patchlist.h>
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/patch.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/patch.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/patch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/patch.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 
+#include <asm/paravirt.h>
 #include <asm/patch.h>
 #include <asm/processor.h>
 #include <asm/sections.h>
@@ -169,16 +170,35 @@ ia64_patch_mckinley_e9 (unsigned long st
 	ia64_srlz_i();
 }
 
+extern unsigned long ia64_native_fsyscall_table[NR_syscalls];
+extern char ia64_native_fsys_bubble_down[];
+struct pv_fsys_data pv_fsys_data __initdata = {
+	.fsyscall_table = (unsigned long *)ia64_native_fsyscall_table,
+	.fsys_bubble_down = (void *)ia64_native_fsys_bubble_down,
+};
+
+unsigned long * __init
+paravirt_get_fsyscall_table(void)
+{
+	return pv_fsys_data.fsyscall_table;
+}
+
+char * __init
+paravirt_get_fsys_bubble_down(void)
+{
+	return pv_fsys_data.fsys_bubble_down;
+}
+
 static void __init
 patch_fsyscall_table (unsigned long start, unsigned long end)
 {
-	extern unsigned long fsyscall_table[NR_syscalls];
+	u64 fsyscall_table = (u64)paravirt_get_fsyscall_table();
 	s32 *offp = (s32 *) start;
 	u64 ip;
 
 	while (offp < (s32 *) end) {
 		ip = (u64) ia64_imva((char *) offp + *offp);
-		ia64_patch_imm64(ip, (u64) fsyscall_table);
+		ia64_patch_imm64(ip, fsyscall_table);
 		ia64_fc((void *) ip);
 		++offp;
 	}
@@ -189,7 +209,7 @@ patch_fsyscall_table (unsigned long star
 static void __init
 patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
 {
-	extern char fsys_bubble_down[];
+	u64 fsys_bubble_down = (u64)paravirt_get_fsys_bubble_down();
 	s32 *offp = (s32 *) start;
 	u64 ip;
 
@@ -207,13 +227,13 @@ patch_brl_fsys_bubble_down (unsigned lon
 void __init
 ia64_patch_gate (void)
 {
-#	define START(name)	((unsigned long) __start_gate_##name##_patchlist)
-#	define END(name)	((unsigned long)__end_gate_##name##_patchlist)
+#	define START(name)	paravirt_get_gate_patchlist(PV_GATE_START_##name)
+#	define END(name)	paravirt_get_gate_patchlist(PV_GATE_END_##name)
 
-	patch_fsyscall_table(START(fsyscall), END(fsyscall));
-	patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
-	ia64_patch_vtop(START(vtop), END(vtop));
-	ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
+	patch_fsyscall_table(START(FSYSCALL), END(FSYSCALL));
+	patch_brl_fsys_bubble_down(START(BRL_FSYS_BUBBLE_DOWN), END(BRL_FSYS_BUBBLE_DOWN));
+	ia64_patch_vtop(START(VTOP), END(VTOP));
+	ia64_patch_mckinley_e9(START(MCKINLEY_E9), END(MCKINLEY_E9));
 }
 
 void ia64_patch_phys_stack_reg(unsigned long val)
@@ -229,7 +249,7 @@ void ia64_patch_phys_stack_reg(unsigned
 	while (offp < end) {
 		ip = (u64) offp + *offp;
 		ia64_patch(ip, mask, imm);
-		ia64_fc(ip);
+		ia64_fc((void *)ip);
 		++offp;
 	}
 	ia64_sync_i();
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/pci-dma.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-dma.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/pci-dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,30 +32,16 @@ int force_iommu __read_mostly = 1;
 int force_iommu __read_mostly;
 #endif
 
-/* Set this to 1 if there is a HW IOMMU in the system */
-int iommu_detected __read_mostly;
-
 /* Dummy device used for NULL arguments (normally ISA). Better would
    be probably a smaller DMA mask, but this is bug-to-bug compatible
    to i386. */
 struct device fallback_dev = {
 	.init_name = "fallback device",
-	.coherent_dma_mask = DMA_32BIT_MASK,
+	.coherent_dma_mask = DMA_BIT_MASK(32),
 	.dma_mask = &fallback_dev.coherent_dma_mask,
 };
 
-void __init pci_iommu_alloc(void)
-{
-	/*
-	 * The order of these functions is important for
-	 * fall-back/fail-over reasons
-	 */
-	detect_intel_iommu();
-
-#ifdef CONFIG_SWIOTLB
-	pci_swiotlb_init();
-#endif
-}
+extern struct dma_map_ops intel_dma_ops;
 
 static int __init pci_iommu_init(void)
 {
@@ -79,20 +65,17 @@ iommu_dma_init(void)
 	return;
 }
 
-struct dma_mapping_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
-
 int iommu_dma_supported(struct device *dev, u64 mask)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = platform_dma_get_ops(dev);
 
-	if (ops->dma_supported_op)
-		return ops->dma_supported_op(dev, mask);
+	if (ops->dma_supported)
+		return ops->dma_supported(dev, mask);
 
 	/* Copied from i386. Doesn't make much sense, because it will
 	   only work for pci_alloc_coherent.
 	   The caller just has to use GFP_DMA in this case. */
-	if (mask < DMA_24BIT_MASK)
+	if (mask < DMA_BIT_MASK(24))
 		return 0;
 
 	/* Tell the device to use SAC when IOMMU force is on.  This
@@ -107,7 +90,7 @@ int iommu_dma_supported(struct device *d
 	   SAC for these.  Assume all masks <= 40 bits are of this
 	   type. Normally this doesn't make any difference, but gives
 	   more gentle handling of IOMMU overflow. */
-	if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+	if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
 		dev_info(dev, "Force SAC with mask %lx\n", mask);
 		return 0;
 	}
@@ -116,4 +99,25 @@ int iommu_dma_supported(struct device *d
 }
 EXPORT_SYMBOL(iommu_dma_supported);
 
+void __init pci_iommu_alloc(void)
+{
+	dma_ops = &intel_dma_ops;
+
+	dma_ops->sync_single_for_cpu = machvec_dma_sync_single;
+	dma_ops->sync_sg_for_cpu = machvec_dma_sync_sg;
+	dma_ops->sync_single_for_device = machvec_dma_sync_single;
+	dma_ops->sync_sg_for_device = machvec_dma_sync_sg;
+	dma_ops->dma_supported = iommu_dma_supported;
+
+	/*
+	 * The order of these functions is important for
+	 * fall-back/fail-over reasons
+	 */
+	detect_intel_iommu();
+
+#ifdef CONFIG_SWIOTLB
+	pci_swiotlb_init();
+#endif
+}
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/pci-swiotlb.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-swiotlb.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/pci-swiotlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-swiotlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,23 +13,37 @@
 int swiotlb __read_mostly;
 EXPORT_SYMBOL(swiotlb);
 
-struct dma_mapping_ops swiotlb_dma_ops = {
-	.mapping_error = swiotlb_dma_mapping_error,
-	.alloc_coherent = swiotlb_alloc_coherent,
+static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
+					 dma_addr_t *dma_handle, gfp_t gfp)
+{
+	if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
+		gfp |= GFP_DMA;
+	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+}
+
+struct dma_map_ops swiotlb_dma_ops = {
+	.alloc_coherent = ia64_swiotlb_alloc_coherent,
 	.free_coherent = swiotlb_free_coherent,
-	.map_single = swiotlb_map_single,
-	.unmap_single = swiotlb_unmap_single,
+	.map_page = swiotlb_map_page,
+	.unmap_page = swiotlb_unmap_page,
+	.map_sg = swiotlb_map_sg_attrs,
+	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
 	.sync_single_for_device = swiotlb_sync_single_for_device,
 	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
 	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
 	.sync_sg_for_device = swiotlb_sync_sg_for_device,
-	.map_sg = swiotlb_map_sg,
-	.unmap_sg = swiotlb_unmap_sg,
-	.dma_supported_op = swiotlb_dma_supported,
+	.dma_supported = swiotlb_dma_supported,
+	.mapping_error = swiotlb_dma_mapping_error,
 };
 
+void __init swiotlb_dma_init(void)
+{
+	dma_ops = &swiotlb_dma_ops;
+	swiotlb_init();
+}
+
 void __init pci_swiotlb_init(void)
 {
 	if (!iommu_detected) {
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/perfmon.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/perfmon.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/perfmon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/perfmon.c	2009-06-09 23:05:27.000000000 -0400
@@ -2196,7 +2196,7 @@ pfmfs_delete_dentry(struct dentry *dentr
 	return 1;
 }
 
-static struct dentry_operations pfmfs_dentry_operations = {
+static const struct dentry_operations pfmfs_dentry_operations = {
 	.d_delete = pfmfs_delete_dentry,
 };
 
@@ -5603,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg
  * /proc/perfmon interface, for debug only
  */
 
-#define PFM_PROC_SHOW_HEADER	((void *)NR_CPUS+1)
+#define PFM_PROC_SHOW_HEADER	((void *)nr_cpu_ids+1)
 
 static void *
 pfm_proc_start(struct seq_file *m, loff_t *pos)
@@ -5612,7 +5612,7 @@ pfm_proc_start(struct seq_file *m, loff_
 		return PFM_PROC_SHOW_HEADER;
 	}
 
-	while (*pos <= NR_CPUS) {
+	while (*pos <= nr_cpu_ids) {
 		if (cpu_online(*pos - 1)) {
 			return (void *)*pos;
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/process.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -413,7 +413,7 @@ ia64_load_extra (struct task_struct *tas
  * so there is nothing to worry about.
  */
 int
-copy_thread (int nr, unsigned long clone_flags,
+copy_thread(unsigned long clone_flags,
 	     unsigned long user_stack_base, unsigned long user_stack_size,
 	     struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/salinfo.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/salinfo.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/salinfo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/salinfo.c	2009-06-09 23:05:27.000000000 -0400
@@ -317,7 +317,7 @@ retry:
 	}
 
 	n = data->cpu_check;
-	for (i = 0; i < NR_CPUS; i++) {
+	for (i = 0; i < nr_cpu_ids; i++) {
 		if (cpu_isset(n, data->cpu_event)) {
 			if (!cpu_online(n)) {
 				cpu_clear(n, data->cpu_event);
@@ -326,7 +326,7 @@ retry:
 			cpu = n;
 			break;
 		}
-		if (++n == NR_CPUS)
+		if (++n == nr_cpu_ids)
 			n = 0;
 	}
 
@@ -337,7 +337,7 @@ retry:
 
 	/* for next read, start checking at next CPU */
 	data->cpu_check = cpu;
-	if (++data->cpu_check == NR_CPUS)
+	if (++data->cpu_check == nr_cpu_ids)
 		data->cpu_check = 0;
 
 	snprintf(cmd, sizeof(cmd), "read %d\n", cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/setup.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,7 @@
 #include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/paravirt.h>
+#include <asm/paravirt_patch.h>
 #include <asm/patch.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -537,6 +538,7 @@ setup_arch (char **cmdline_p)
 	paravirt_arch_setup_early();
 
 	ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
+	paravirt_patch_apply();
 
 	*cmdline_p = __va(ia64_boot_param->command_line);
 	strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
@@ -730,10 +732,10 @@ static void *
 c_start (struct seq_file *m, loff_t *pos)
 {
 #ifdef CONFIG_SMP
-	while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
+	while (*pos < nr_cpu_ids && !cpu_online(*pos))
 		++*pos;
 #endif
-	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
+	return *pos < nr_cpu_ids ? cpu_data(*pos) : NULL;
 }
 
 static void *
@@ -1016,8 +1018,7 @@ cpu_init (void)
 					| IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
-	if (current->mm)
-		BUG();
+	BUG_ON(current->mm);
 
 	ia64_mmu_init(ia64_imva(cpu_data));
 	ia64_mca_cpu_init(ia64_imva(cpu_data));
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/smpboot.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/smpboot.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/smpboot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/smpboot.c	2009-06-09 23:05:27.000000000 -0400
@@ -581,14 +581,14 @@ smp_build_cpu_map (void)
 
 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
 	cpus_clear(cpu_present_map);
-	cpu_set(0, cpu_present_map);
-	cpu_set(0, cpu_possible_map);
+	set_cpu_present(0, true);
+	set_cpu_possible(0, true);
 	for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
 		sapicid = smp_boot_data.cpu_phys_id[i];
 		if (sapicid == boot_cpu_id)
 			continue;
-		cpu_set(cpu, cpu_present_map);
-		cpu_set(cpu, cpu_possible_map);
+		set_cpu_present(cpu, true);
+		set_cpu_possible(cpu, true);
 		ia64_cpu_to_sapicid[cpu] = sapicid;
 		cpu++;
 	}
@@ -626,12 +626,9 @@ smp_prepare_cpus (unsigned int max_cpus)
 	 */
 	if (!max_cpus) {
 		printk(KERN_INFO "SMP mode deactivated.\n");
-		cpus_clear(cpu_online_map);
-		cpus_clear(cpu_present_map);
-		cpus_clear(cpu_possible_map);
-		cpu_set(0, cpu_online_map);
-		cpu_set(0, cpu_present_map);
-		cpu_set(0, cpu_possible_map);
+		init_cpu_online(cpumask_of(0));
+		init_cpu_present(cpumask_of(0));
+		init_cpu_possible(cpumask_of(0));
 		return;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/smp.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -166,11 +166,11 @@ send_IPI_allbutself (int op)
  * Called with preemption disabled.
  */
 static inline void
-send_IPI_mask(cpumask_t mask, int op)
+send_IPI_mask(const struct cpumask *mask, int op)
 {
 	unsigned int cpu;
 
-	for_each_cpu_mask(cpu, mask) {
+	for_each_cpu(cpu, mask) {
 			send_IPI_single(cpu, op);
 	}
 }
@@ -225,6 +225,7 @@ smp_send_reschedule (int cpu)
 {
 	platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
 }
+EXPORT_SYMBOL_GPL(smp_send_reschedule);
 
 /*
  * Called with preemption disabled.
@@ -300,15 +301,12 @@ smp_flush_tlb_mm (struct mm_struct *mm)
 		return;
 	}
 
+	smp_call_function_mask(mm->cpu_vm_mask,
+		(void (*)(void *))local_finish_flush_tlb_mm, mm, 1);
+	local_irq_disable();
+	local_finish_flush_tlb_mm(mm);
+	local_irq_enable();
 	preempt_enable();
-	/*
-	 * We could optimize this further by using mm->cpu_vm_mask to track which CPUs
-	 * have been running in the address space.  It's not clear that this is worth the
-	 * trouble though: to avoid races, we have to raise the IPI on the target CPU
-	 * anyhow, and once a CPU is interrupted, the cost of local_flush_tlb_all() is
-	 * rather trivial.
-	 */
-	on_each_cpu((void (*)(void *))local_finish_flush_tlb_mm, mm, 1);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
@@ -316,7 +314,7 @@ void arch_send_call_function_single_ipi(
 	send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
 }
 
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	send_IPI_mask(mask, IPI_CALL_FUNC);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/time.c linux-libre-2.6.30-gnu1/arch/ia64/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
+#include <linux/platform_device.h>
 
 #include <asm/machvec.h>
 #include <asm/delay.h>
@@ -32,7 +33,7 @@
 
 #include "fsyscall_gtod_data.h"
 
-static cycle_t itc_get_cycles(void);
+static cycle_t itc_get_cycles(struct clocksource *cs);
 
 struct fsyscall_gtod_data_t fsyscall_gtod_data = {
 	.lock = SEQLOCK_UNLOCKED,
@@ -50,6 +51,15 @@ EXPORT_SYMBOL(last_cli_ip);
 #endif
 
 #ifdef CONFIG_PARAVIRT
+/* We need to define a real function for sched_clock, to override the
+   weak default version */
+unsigned long long sched_clock(void)
+{
+        return paravirt_sched_clock();
+}
+#endif
+
+#ifdef CONFIG_PARAVIRT
 static void
 paravirt_clocksource_resume(void)
 {
@@ -373,7 +383,7 @@ ia64_init_itm (void)
 	}
 }
 
-static cycle_t itc_get_cycles(void)
+static cycle_t itc_get_cycles(struct clocksource *cs)
 {
 	u64 lcycle, now, ret;
 
@@ -405,6 +415,21 @@ static struct irqaction timer_irqaction
 	.name =		"timer"
 };
 
+static struct platform_device rtc_efi_dev = {
+	.name = "rtc-efi",
+	.id = -1,
+};
+
+static int __init rtc_init(void)
+{
+	if (platform_device_register(&rtc_efi_dev) < 0)
+		printk(KERN_ERR "unable to register rtc device...\n");
+
+	/* not necessarily an error */
+	return 0;
+}
+module_init(rtc_init);
+
 void __init
 time_init (void)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/ia64/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/ia64/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -169,6 +169,30 @@ SECTIONS
 	  __end___mckinley_e9_bundles = .;
 	}
 
+#if defined(CONFIG_PARAVIRT)
+  . = ALIGN(16);
+  .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET)
+	{
+	  __start_paravirt_bundles = .;
+          *(.paravirt_bundles)
+	  __stop_paravirt_bundles = .;
+	}
+  . = ALIGN(16);
+  .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET)
+	{
+	  __start_paravirt_insts = .;
+          *(.paravirt_insts)
+	  __stop_paravirt_insts = .;
+	}
+  . = ALIGN(16);
+  .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET)
+	{
+	  __start_paravirt_branches = .;
+	  *(.paravirt_branches)
+	  __stop_paravirt_branches = .;
+	}
+#endif
+
 #if defined(CONFIG_IA64_GENERIC)
   /* Machine Vector */
   . = ALIGN(16);
@@ -201,6 +225,12 @@ SECTIONS
 	  __start_gate_section = .;
 	  *(.data.gate)
 	  __stop_gate_section = .;
+#ifdef CONFIG_XEN
+	  . = ALIGN(PAGE_SIZE);
+	  __xen_start_gate_section = .;
+	  *(.data.gate.xen)
+	  __xen_stop_gate_section = .;
+#endif
 	}
   . = ALIGN(PAGE_SIZE);		/* make sure the gate page doesn't expose
   				 * kernel data
@@ -213,16 +243,9 @@ SECTIONS
         { *(.data.cacheline_aligned) }
 
   /* Per-cpu data: */
-  percpu : { } :percpu
   . = ALIGN(PERCPU_PAGE_SIZE);
-  __phys_per_cpu_start = .;
-  .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
-	{
-		__per_cpu_start = .;
-		*(.data.percpu)
-		*(.data.percpu.shared_aligned)
-		__per_cpu_end = .;
-	}
+  PERCPU_VADDR(PERCPU_ADDR, :percpu)
+  __phys_per_cpu_start = __per_cpu_load;
   . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;	/* ensure percpu data fits
   						 * into percpu page size
 						 */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/irq.h linux-libre-2.6.30-gnu1/arch/ia64/kvm/irq.h
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,8 @@
 #ifndef __IRQ_H
 #define __IRQ_H
 
+#include "lapic.h"
+
 static inline int irqchip_in_kernel(struct kvm *kvm)
 {
 	return 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/Kconfig linux-libre-2.6.30-gnu1/arch/ia64/kvm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,10 @@
 config HAVE_KVM
 	bool
 
+config HAVE_KVM_IRQCHIP
+       bool
+       default y
+
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
 	depends on HAVE_KVM || IA64
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/kvm_fw.c linux-libre-2.6.30-gnu1/arch/ia64/kvm/kvm_fw.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/kvm_fw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/kvm_fw.c	2009-06-09 23:05:27.000000000 -0400
@@ -227,6 +227,18 @@ static struct ia64_pal_retval pal_proc_g
 	return result;
 }
 
+static struct ia64_pal_retval pal_register_info(struct kvm_vcpu *vcpu)
+{
+
+	struct ia64_pal_retval result = {0, 0, 0, 0};
+	long in0, in1, in2, in3;
+
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+	result.status = ia64_pal_register_info(in1, &result.v1, &result.v2);
+
+	return result;
+}
+
 static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu)
 {
 
@@ -268,8 +280,12 @@ static struct ia64_pal_retval pal_vm_sum
 static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu)
 {
 	struct ia64_pal_retval result;
+	unsigned long in0, in1, in2, in3;
 
-	INIT_PAL_STATUS_UNIMPLEMENTED(result);
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+
+	result.status = ia64_pal_vm_info(in1, in2,
+			(pal_tc_info_u_t *)&result.v1, &result.v2);
 
 	return result;
 }
@@ -292,6 +308,108 @@ static void prepare_for_halt(struct kvm_
 	vcpu->arch.timer_fired = 0;
 }
 
+static struct ia64_pal_retval pal_perf_mon_info(struct kvm_vcpu *vcpu)
+{
+	long status;
+	unsigned long in0, in1, in2, in3, r9;
+	unsigned long pm_buffer[16];
+
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+	status = ia64_pal_perf_mon_info(pm_buffer,
+				(pal_perf_mon_info_u_t *) &r9);
+	if (status != 0) {
+		printk(KERN_DEBUG"PAL_PERF_MON_INFO fails ret=%ld\n", status);
+	} else {
+		if (in1)
+			memcpy((void *)in1, pm_buffer, sizeof(pm_buffer));
+		else {
+			status = PAL_STATUS_EINVAL;
+			printk(KERN_WARNING"Invalid parameters "
+						"for PAL call:0x%lx!\n", in0);
+		}
+	}
+	return (struct ia64_pal_retval){status, r9, 0, 0};
+}
+
+static struct ia64_pal_retval pal_halt_info(struct kvm_vcpu *vcpu)
+{
+	unsigned long in0, in1, in2, in3;
+	long status;
+	unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32)
+					| (1UL << 61) | (1UL << 60);
+
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+	if (in1) {
+		memcpy((void *)in1, &res, sizeof(res));
+		status = 0;
+	} else{
+		status = PAL_STATUS_EINVAL;
+		printk(KERN_WARNING"Invalid parameters "
+					"for PAL call:0x%lx!\n", in0);
+	}
+
+	return (struct ia64_pal_retval){status, 0, 0, 0};
+}
+
+static struct ia64_pal_retval pal_mem_attrib(struct kvm_vcpu *vcpu)
+{
+	unsigned long r9;
+	long status;
+
+	status = ia64_pal_mem_attrib(&r9);
+
+	return (struct ia64_pal_retval){status, r9, 0, 0};
+}
+
+static void remote_pal_prefetch_visibility(void *v)
+{
+	s64 trans_type = (s64)v;
+	ia64_pal_prefetch_visibility(trans_type);
+}
+
+static struct ia64_pal_retval pal_prefetch_visibility(struct kvm_vcpu *vcpu)
+{
+	struct ia64_pal_retval result = {0, 0, 0, 0};
+	unsigned long in0, in1, in2, in3;
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+	result.status = ia64_pal_prefetch_visibility(in1);
+	if (result.status == 0) {
+		/* Must be performed on all remote processors
+		in the coherence domain. */
+		smp_call_function(remote_pal_prefetch_visibility,
+					(void *)in1, 1);
+		/* Unnecessary on remote processor for other vcpus!*/
+		result.status = 1;
+	}
+	return result;
+}
+
+static void remote_pal_mc_drain(void *v)
+{
+	ia64_pal_mc_drain();
+}
+
+static struct ia64_pal_retval pal_get_brand_info(struct kvm_vcpu *vcpu)
+{
+	struct ia64_pal_retval result = {0, 0, 0, 0};
+	unsigned long in0, in1, in2, in3;
+
+	kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+
+	if (in1 == 0 && in2) {
+		char brand_info[128];
+		result.status = ia64_pal_get_brand_info(brand_info);
+		if (result.status == PAL_STATUS_SUCCESS)
+			memcpy((void *)in2, brand_info, 128);
+	} else {
+		result.status = PAL_STATUS_REQUIRES_MEMORY;
+		printk(KERN_WARNING"Invalid parameters for "
+					"PAL call:0x%lx!\n", in0);
+	}
+
+	return result;
+}
+
 int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
 
@@ -300,14 +418,22 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu,
 	int ret = 1;
 
 	gr28 = kvm_get_pal_call_index(vcpu);
-	/*printk("pal_call index:%lx\n",gr28);*/
 	switch (gr28) {
 	case PAL_CACHE_FLUSH:
 		result = pal_cache_flush(vcpu);
 		break;
+	case PAL_MEM_ATTRIB:
+		result = pal_mem_attrib(vcpu);
+		break;
 	case PAL_CACHE_SUMMARY:
 		result = pal_cache_summary(vcpu);
 		break;
+	case PAL_PERF_MON_INFO:
+		result = pal_perf_mon_info(vcpu);
+		break;
+	case PAL_HALT_INFO:
+		result = pal_halt_info(vcpu);
+		break;
 	case PAL_HALT_LIGHT:
 	{
 		INIT_PAL_STATUS_SUCCESS(result);
@@ -317,6 +443,16 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu,
 	}
 		break;
 
+	case PAL_PREFETCH_VISIBILITY:
+		result = pal_prefetch_visibility(vcpu);
+		break;
+	case PAL_MC_DRAIN:
+		result.status = ia64_pal_mc_drain();
+		/* FIXME: All vcpus likely call PAL_MC_DRAIN.
+		   That causes the congestion. */
+		smp_call_function(remote_pal_mc_drain, NULL, 1);
+		break;
+
 	case PAL_FREQ_RATIOS:
 		result = pal_freq_ratios(vcpu);
 		break;
@@ -346,6 +482,9 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu,
 		INIT_PAL_STATUS_SUCCESS(result);
 		result.v1 = (1L << 32) | 1L;
 		break;
+	case PAL_REGISTER_INFO:
+		result = pal_register_info(vcpu);
+		break;
 	case PAL_VM_PAGE_SIZE:
 		result.status = ia64_pal_vm_page_size(&result.v0,
 							&result.v1);
@@ -365,12 +504,18 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu,
 		result.status = ia64_pal_version(
 				(pal_version_u_t *)&result.v0,
 				(pal_version_u_t *)&result.v1);
-
 		break;
 	case PAL_FIXED_ADDR:
 		result.status = PAL_STATUS_SUCCESS;
 		result.v0 = vcpu->vcpu_id;
 		break;
+	case PAL_BRAND_INFO:
+		result = pal_get_brand_info(vcpu);
+		break;
+	case PAL_GET_PSTATE:
+	case PAL_CACHE_SHARED_INFO:
+		INIT_PAL_STATUS_UNIMPLEMENTED(result);
+		break;
 	default:
 		INIT_PAL_STATUS_UNIMPLEMENTED(result);
 		printk(KERN_WARNING"kvm: Unsupported pal call,"
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/kvm-ia64.c linux-libre-2.6.30-gnu1/arch/ia64/kvm/kvm-ia64.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/kvm-ia64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/kvm-ia64.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,7 +70,7 @@ static void kvm_flush_icache(unsigned lo
 	int l;
 
 	for (l = 0; l < (len + 32); l += 32)
-		ia64_fc(start + l);
+		ia64_fc((void *)(start + l));
 
 	ia64_sync_i();
 	ia64_srlz_i();
@@ -182,7 +182,7 @@ int kvm_dev_ioctl_check_extension(long e
 	switch (ext) {
 	case KVM_CAP_IRQCHIP:
 	case KVM_CAP_MP_STATE:
-
+	case KVM_CAP_IRQ_INJECT_STATUS:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -314,7 +314,7 @@ static struct kvm_vcpu *lid_to_vcpu(stru
 	union ia64_lid lid;
 	int i;
 
-	for (i = 0; i < KVM_MAX_VCPUS; i++) {
+	for (i = 0; i < kvm->arch.online_vcpus; i++) {
 		if (kvm->vcpus[i]) {
 			lid.val = VCPU_LID(kvm->vcpus[i]);
 			if (lid.id == id && lid.eid == eid)
@@ -388,7 +388,7 @@ static int handle_global_purge(struct kv
 
 	call_data.ptc_g_data = p->u.ptc_g_data;
 
-	for (i = 0; i < KVM_MAX_VCPUS; i++) {
+	for (i = 0; i < kvm->arch.online_vcpus; i++) {
 		if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state ==
 						KVM_MP_STATE_UNINITIALIZED ||
 					vcpu == kvm->vcpus[i])
@@ -610,20 +610,22 @@ static int __vcpu_run(struct kvm_vcpu *v
 	int r;
 
 again:
-	preempt_disable();
-	local_irq_disable();
-
 	if (signal_pending(current)) {
-		local_irq_enable();
-		preempt_enable();
 		r = -EINTR;
 		kvm_run->exit_reason = KVM_EXIT_INTR;
 		goto out;
 	}
 
+	/*
+	 * down_read() may sleep and return with interrupts enabled
+	 */
+	down_read(&vcpu->kvm->slots_lock);
+
+	preempt_disable();
+	local_irq_disable();
+
 	vcpu->guest_mode = 1;
 	kvm_guest_enter();
-	down_read(&vcpu->kvm->slots_lock);
 	r = vti_vcpu_run(vcpu, kvm_run);
 	if (r < 0) {
 		local_irq_enable();
@@ -788,6 +790,8 @@ struct  kvm *kvm_arch_create_vm(void)
 		return ERR_PTR(-ENOMEM);
 	kvm_init_vm(kvm);
 
+	kvm->arch.online_vcpus = 0;
+
 	return kvm;
 
 }
@@ -919,7 +923,13 @@ long kvm_arch_vm_ioctl(struct file *filp
 		r = kvm_ioapic_init(kvm);
 		if (r)
 			goto out;
+		r = kvm_setup_default_irq_routing(kvm);
+		if (r) {
+			kfree(kvm->arch.vioapic);
+			goto out;
+		}
 		break;
+	case KVM_IRQ_LINE_STATUS:
 	case KVM_IRQ_LINE: {
 		struct kvm_irq_level irq_event;
 
@@ -927,10 +937,17 @@ long kvm_arch_vm_ioctl(struct file *filp
 		if (copy_from_user(&irq_event, argp, sizeof irq_event))
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
+			__s32 status;
 			mutex_lock(&kvm->lock);
-			kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 				    irq_event.irq, irq_event.level);
 			mutex_unlock(&kvm->lock);
+			if (ioctl == KVM_IRQ_LINE_STATUS) {
+				irq_event.status = status;
+				if (copy_to_user(argp, &irq_event,
+							sizeof irq_event))
+					goto out;
+			}
 			r = 0;
 		}
 		break;
@@ -1149,7 +1166,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 
 		/*Initialize itc offset for vcpus*/
 		itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
-		for (i = 0; i < KVM_MAX_VCPUS; i++) {
+		for (i = 0; i < kvm->arch.online_vcpus; i++) {
 			v = (struct kvm_vcpu *)((char *)vcpu +
 					sizeof(struct kvm_vcpu_data) * i);
 			v->arch.itc_offset = itc_offset;
@@ -1283,6 +1300,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 		goto fail;
 	}
 
+	kvm->arch.online_vcpus++;
+
 	return vcpu;
 fail:
 	return ERR_PTR(r);
@@ -1303,8 +1322,8 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct k
 	return -EINVAL;
 }
 
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
-		struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					struct kvm_guest_debug *dbg)
 {
 	return -EINVAL;
 }
@@ -1421,6 +1440,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	return 0;
 }
 
+int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu,
+				  struct kvm_ia64_vcpu_stack *stack)
+{
+	memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack));
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu,
+				  struct kvm_ia64_vcpu_stack *stack)
+{
+	memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu),
+	       sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu));
+
+	vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data;
+	return 0;
+}
+
 void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
 
@@ -1430,9 +1466,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
 
 
 long kvm_arch_vcpu_ioctl(struct file *filp,
-		unsigned int ioctl, unsigned long arg)
+			 unsigned int ioctl, unsigned long arg)
 {
-	return -EINVAL;
+	struct kvm_vcpu *vcpu = filp->private_data;
+	void __user *argp = (void __user *)arg;
+	struct kvm_ia64_vcpu_stack *stack = NULL;
+	long r;
+
+	switch (ioctl) {
+	case KVM_IA64_VCPU_GET_STACK: {
+		struct kvm_ia64_vcpu_stack __user *user_stack;
+	        void __user *first_p = argp;
+
+		r = -EFAULT;
+		if (copy_from_user(&user_stack, first_p, sizeof(void *)))
+			goto out;
+
+		if (!access_ok(VERIFY_WRITE, user_stack,
+			       sizeof(struct kvm_ia64_vcpu_stack))) {
+			printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: "
+			       "Illegal user destination address for stack\n");
+			goto out;
+		}
+		stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
+		if (!stack) {
+			r = -ENOMEM;
+			goto out;
+		}
+
+		r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack);
+		if (r)
+			goto out;
+
+		if (copy_to_user(user_stack, stack,
+				 sizeof(struct kvm_ia64_vcpu_stack)))
+			goto out;
+
+		break;
+	}
+	case KVM_IA64_VCPU_SET_STACK: {
+		struct kvm_ia64_vcpu_stack __user *user_stack;
+	        void __user *first_p = argp;
+
+		r = -EFAULT;
+		if (copy_from_user(&user_stack, first_p, sizeof(void *)))
+			goto out;
+
+		if (!access_ok(VERIFY_READ, user_stack,
+			    sizeof(struct kvm_ia64_vcpu_stack))) {
+			printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: "
+			       "Illegal user address for stack\n");
+			goto out;
+		}
+		stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
+		if (!stack) {
+			r = -ENOMEM;
+			goto out;
+		}
+		if (copy_from_user(stack, user_stack,
+				   sizeof(struct kvm_ia64_vcpu_stack)))
+			goto out;
+
+		r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack);
+		break;
+	}
+
+	default:
+		r = -EINVAL;
+	}
+
+out:
+	kfree(stack);
+	return r;
 }
 
 int kvm_arch_set_memory_region(struct kvm *kvm,
@@ -1472,7 +1577,7 @@ void kvm_arch_flush_shadow(struct kvm *k
 }
 
 long kvm_arch_dev_ioctl(struct file *filp,
-		unsigned int ioctl, unsigned long arg)
+			unsigned int ioctl, unsigned long arg)
 {
 	return -EINVAL;
 }
@@ -1737,7 +1842,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcp
 	struct kvm_vcpu *lvcpu = kvm->vcpus[0];
 	int i;
 
-	for (i = 1; i < KVM_MAX_VCPUS; i++) {
+	for (i = 1; i < kvm->arch.online_vcpus; i++) {
 		if (!kvm->vcpus[i])
 			continue;
 		if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/process.c linux-libre-2.6.30-gnu1/arch/ia64/kvm/process.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -167,7 +167,6 @@ static u64 vcpu_get_itir_on_fault(struct
 	return (rr1.val);
 }
 
-
 /*
  * Set vIFA & vITIR & vIHA, when vPSR.ic =1
  * Parameter:
@@ -222,8 +221,6 @@ void itlb_fault(struct kvm_vcpu *vcpu, u
 	inject_guest_interruption(vcpu, IA64_INST_TLB_VECTOR);
 }
 
-
-
 /*
  * Data Nested TLB Fault
  *  @ Data Nested TLB Vector
@@ -245,7 +242,6 @@ void alt_dtlb(struct kvm_vcpu *vcpu, u64
 	inject_guest_interruption(vcpu, IA64_ALT_DATA_TLB_VECTOR);
 }
 
-
 /*
  * Data TLB Fault
  *  @ Data TLB vector
@@ -265,8 +261,6 @@ static void _vhpt_fault(struct kvm_vcpu
 	/* If vPSR.ic, IFA, ITIR, IHA*/
 	set_ifa_itir_iha(vcpu, vadr, 1, 1, 1);
 	inject_guest_interruption(vcpu, IA64_VHPT_TRANS_VECTOR);
-
-
 }
 
 /*
@@ -279,7 +273,6 @@ void ivhpt_fault(struct kvm_vcpu *vcpu,
 	_vhpt_fault(vcpu, vadr);
 }
 
-
 /*
  * VHPT Data Fault
  *  @ VHPT Translation vector
@@ -290,8 +283,6 @@ void dvhpt_fault(struct kvm_vcpu *vcpu,
 	_vhpt_fault(vcpu, vadr);
 }
 
-
-
 /*
  * Deal with:
  *  General Exception vector
@@ -301,7 +292,6 @@ void _general_exception(struct kvm_vcpu
 	inject_guest_interruption(vcpu, IA64_GENEX_VECTOR);
 }
 
-
 /*
  * Illegal Operation Fault
  *  @ General Exception Vector
@@ -419,19 +409,16 @@ static void __page_not_present(struct kv
 	inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);
 }
 
-
 void data_page_not_present(struct kvm_vcpu *vcpu, u64 vadr)
 {
 	__page_not_present(vcpu, vadr);
 }
 
-
 void inst_page_not_present(struct kvm_vcpu *vcpu, u64 vadr)
 {
 	__page_not_present(vcpu, vadr);
 }
 
-
 /* Deal with
  *  Data access rights vector
  */
@@ -563,22 +550,64 @@ void reflect_interruption(u64 ifa, u64 i
 	inject_guest_interruption(vcpu, vector);
 }
 
+static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu,
+						unsigned long arg)
+{
+	struct thash_data *data;
+	unsigned long gpa, poff;
+
+	if (!is_physical_mode(vcpu)) {
+		/* Depends on caller to provide the DTR or DTC mapping.*/
+		data = vtlb_lookup(vcpu, arg, D_TLB);
+		if (data)
+			gpa = data->page_flags & _PAGE_PPN_MASK;
+		else {
+			data = vhpt_lookup(arg);
+			if (!data)
+				return 0;
+			gpa = data->gpaddr & _PAGE_PPN_MASK;
+		}
+
+		poff = arg & (PSIZE(data->ps) - 1);
+		arg = PAGEALIGN(gpa, data->ps) | poff;
+	}
+	arg = kvm_gpa_to_mpa(arg << 1 >> 1);
+
+	return (unsigned long)__va(arg);
+}
+
 static void set_pal_call_data(struct kvm_vcpu *vcpu)
 {
 	struct exit_ctl_data *p = &vcpu->arch.exit_data;
+	unsigned long gr28 = vcpu_get_gr(vcpu, 28);
+	unsigned long gr29 = vcpu_get_gr(vcpu, 29);
+	unsigned long gr30 = vcpu_get_gr(vcpu, 30);
 
 	/*FIXME:For static and stacked convention, firmware
 	 * has put the parameters in gr28-gr31 before
 	 * break to vmm  !!*/
 
-	p->u.pal_data.gr28 = vcpu_get_gr(vcpu, 28);
-	p->u.pal_data.gr29 = vcpu_get_gr(vcpu, 29);
-	p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+	switch (gr28) {
+	case PAL_PERF_MON_INFO:
+	case PAL_HALT_INFO:
+		p->u.pal_data.gr29 =  kvm_trans_pal_call_args(vcpu, gr29);
+		p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+		break;
+	case PAL_BRAND_INFO:
+		p->u.pal_data.gr29 = gr29;;
+		p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30);
+		break;
+	default:
+		p->u.pal_data.gr29 = gr29;;
+		p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+	}
+	p->u.pal_data.gr28 = gr28;
 	p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31);
+
 	p->exit_reason = EXIT_REASON_PAL_CALL;
 }
 
-static void set_pal_call_result(struct kvm_vcpu *vcpu)
+static void get_pal_call_result(struct kvm_vcpu *vcpu)
 {
 	struct exit_ctl_data *p = &vcpu->arch.exit_data;
 
@@ -606,7 +635,7 @@ static void set_sal_call_data(struct kvm
 	p->exit_reason = EXIT_REASON_SAL_CALL;
 }
 
-static void set_sal_call_result(struct kvm_vcpu *vcpu)
+static void get_sal_call_result(struct kvm_vcpu *vcpu)
 {
 	struct exit_ctl_data *p = &vcpu->arch.exit_data;
 
@@ -629,13 +658,13 @@ void  kvm_ia64_handle_break(unsigned lon
 		if (iim == DOMN_PAL_REQUEST) {
 			set_pal_call_data(v);
 			vmm_transition(v);
-			set_pal_call_result(v);
+			get_pal_call_result(v);
 			vcpu_increment_iip(v);
 			return;
 		} else if (iim == DOMN_SAL_REQUEST) {
 			set_sal_call_data(v);
 			vmm_transition(v);
-			set_sal_call_result(v);
+			get_sal_call_result(v);
 			vcpu_increment_iip(v);
 			return;
 		}
@@ -703,7 +732,6 @@ void vhpi_detection(struct kvm_vcpu *vcp
 	}
 }
 
-
 void leave_hypervisor_tail(void)
 {
 	struct kvm_vcpu *v = current_vcpu;
@@ -737,7 +765,6 @@ void leave_hypervisor_tail(void)
 	}
 }
 
-
 static inline void handle_lds(struct kvm_pt_regs *regs)
 {
 	regs->cr_ipsr |= IA64_PSR_ED;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/vcpu.c linux-libre-2.6.30-gnu1/arch/ia64/kvm/vcpu.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/vcpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/vcpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,6 @@ void switch_to_physical_rid(struct kvm_v
 	return;
 }
 
-
 void switch_to_virtual_rid(struct kvm_vcpu *vcpu)
 {
 	unsigned long psr;
@@ -166,8 +165,6 @@ void switch_mm_mode(struct kvm_vcpu *vcp
 	return;
 }
 
-
-
 /*
  * In physical mode, insert tc/tr for region 0 and 4 uses
  * RID[0] and RID[4] which is for physical mode emulation.
@@ -269,7 +266,6 @@ static inline unsigned long fph_index(st
 	return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR));
 }
 
-
 /*
  * The inverse of the above: given bspstore and the number of
  * registers, calculate ar.bsp.
@@ -390,7 +386,7 @@ void set_rse_reg(struct kvm_pt_regs *reg
 		else
 			*rnat_addr = (*rnat_addr) & (~nat_mask);
 
-		ia64_setreg(_IA64_REG_AR_BSPSTORE, bspstore);
+		ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore);
 		ia64_setreg(_IA64_REG_AR_RNAT, rnat);
 	}
 	local_irq_restore(psr);
@@ -811,12 +807,15 @@ static inline void vcpu_set_itm(struct k
 static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
 {
 	struct kvm_vcpu *v;
+	struct kvm *kvm;
 	int i;
 	long itc_offset = val - ia64_getreg(_IA64_REG_AR_ITC);
 	unsigned long vitv = VCPU(vcpu, itv);
 
+	kvm = (struct kvm *)KVM_VM_BASE;
+
 	if (vcpu->vcpu_id == 0) {
-		for (i = 0; i < KVM_MAX_VCPUS; i++) {
+		for (i = 0; i < kvm->arch.online_vcpus; i++) {
 			v = (struct kvm_vcpu *)((char *)vcpu +
 					sizeof(struct kvm_vcpu_data) * i);
 			VMX(v, itc_offset) = itc_offset;
@@ -1039,8 +1038,6 @@ u64 vcpu_tak(struct kvm_vcpu *vcpu, u64
 	return key;
 }
 
-
-
 void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long thash, vadr;
@@ -1050,7 +1047,6 @@ void kvm_thash(struct kvm_vcpu *vcpu, IN
 	vcpu_set_gr(vcpu, inst.M46.r1, thash, 0);
 }
 
-
 void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long tag, vadr;
@@ -1131,7 +1127,6 @@ int vcpu_tpa(struct kvm_vcpu *vcpu, u64
 	return IA64_NO_FAULT;
 }
 
-
 int kvm_tpa(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long r1, r3;
@@ -1154,7 +1149,6 @@ void kvm_tak(struct kvm_vcpu *vcpu, INST
 	vcpu_set_gr(vcpu, inst.M46.r1, r1, 0);
 }
 
-
 /************************************
  * Insert/Purge translation register/cache
  ************************************/
@@ -1385,7 +1379,6 @@ void kvm_mov_to_ar_reg(struct kvm_vcpu *
 	vcpu_set_itc(vcpu, r2);
 }
 
-
 void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long r1;
@@ -1393,8 +1386,9 @@ void kvm_mov_from_ar_reg(struct kvm_vcpu
 	r1 = vcpu_get_itc(vcpu);
 	vcpu_set_gr(vcpu, inst.M31.r1, r1, 0);
 }
+
 /**************************************************************************
-  struct kvm_vcpu*protection key register access routines
+  struct kvm_vcpu protection key register access routines
  **************************************************************************/
 
 unsigned long vcpu_get_pkr(struct kvm_vcpu *vcpu, unsigned long reg)
@@ -1407,20 +1401,6 @@ void vcpu_set_pkr(struct kvm_vcpu *vcpu,
 	ia64_set_pkr(reg, val);
 }
 
-
-unsigned long vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, unsigned long ifa)
-{
-	union ia64_rr rr, rr1;
-
-	rr.val = vcpu_get_rr(vcpu, ifa);
-	rr1.val = 0;
-	rr1.ps = rr.ps;
-	rr1.rid = rr.rid;
-	return (rr1.val);
-}
-
-
-
 /********************************
  * Moves to privileged registers
  ********************************/
@@ -1464,8 +1444,6 @@ unsigned long vcpu_set_rr(struct kvm_vcp
 	return (IA64_NO_FAULT);
 }
 
-
-
 void kvm_mov_to_rr(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long r3, r2;
@@ -1510,8 +1488,6 @@ void kvm_mov_to_pkr(struct kvm_vcpu *vcp
 	vcpu_set_pkr(vcpu, r3, r2);
 }
 
-
-
 void kvm_mov_from_rr(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long r3, r1;
@@ -1557,7 +1533,6 @@ void kvm_mov_from_pmc(struct kvm_vcpu *v
 	vcpu_set_gr(vcpu, inst.M43.r1, r1, 0);
 }
 
-
 unsigned long vcpu_get_cpuid(struct kvm_vcpu *vcpu, unsigned long reg)
 {
 	/* FIXME: This could get called as a result of a rsvd-reg fault */
@@ -1609,7 +1584,6 @@ unsigned long kvm_mov_to_cr(struct kvm_v
 	return 0;
 }
 
-
 unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst)
 {
 	unsigned long tgt = inst.M33.r1;
@@ -1633,8 +1607,6 @@ unsigned long kvm_mov_from_cr(struct kvm
 	return 0;
 }
 
-
-
 void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val)
 {
 
@@ -1776,9 +1748,6 @@ void vcpu_bsw1(struct kvm_vcpu *vcpu)
 	}
 }
 
-
-
-
 void vcpu_rfi(struct kvm_vcpu *vcpu)
 {
 	unsigned long ifs, psr;
@@ -1796,7 +1765,6 @@ void vcpu_rfi(struct kvm_vcpu *vcpu)
 	regs->cr_iip = VCPU(vcpu, iip);
 }
 
-
 /*
    VPSR can't keep track of below bits of guest PSR
    This function gets guest PSR
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/vcpu.h linux-libre-2.6.30-gnu1/arch/ia64/kvm/vcpu.h
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/vcpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/vcpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -703,7 +703,7 @@ extern u64 guest_vhpt_lookup(u64 iha, u6
 extern void thash_purge_entries(struct kvm_vcpu *v, u64 va, u64 ps);
 extern void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps);
 extern u64 translate_phy_pte(u64 *pte, u64 itir, u64 va);
-extern int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte,
+extern void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte,
 		u64 itir, u64 ifa, int type);
 extern void thash_purge_all(struct kvm_vcpu *v);
 extern struct thash_data *vtlb_lookup(struct kvm_vcpu *v,
@@ -738,7 +738,7 @@ void kvm_init_vhpt(struct kvm_vcpu *v);
 void thash_init(struct thash_cb *hcb, u64 sz);
 
 void panic_vm(struct kvm_vcpu *v, const char *fmt, ...);
-
+u64 kvm_gpa_to_mpa(u64 gpa);
 extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, u64 arg3,
 		u64 arg4, u64 arg5, u64 arg6, u64 arg7);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/kvm/vtlb.c linux-libre-2.6.30-gnu1/arch/ia64/kvm/vtlb.c
--- linux-libre-2.6.29-gnu1/arch/ia64/kvm/vtlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/kvm/vtlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -164,11 +164,11 @@ static void vhpt_insert(u64 pte, u64 iti
 	unsigned long ps, gpaddr;
 
 	ps = itir_ps(itir);
+	rr.val = ia64_get_rr(ifa);
 
-	gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
-		(ifa & ((1UL << ps) - 1));
+	 gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
+					(ifa & ((1UL << ps) - 1));
 
-	rr.val = ia64_get_rr(ifa);
 	head = (struct thash_data *)ia64_thash(ifa);
 	head->etag = INVALID_TI_TAG;
 	ia64_mf();
@@ -210,6 +210,7 @@ void thash_vhpt_insert(struct kvm_vcpu *
 		phy_pte  &= ~PAGE_FLAGS_RV_MASK;
 		psr = ia64_clear_ic();
 		ia64_itc(type, va, phy_pte, itir_ps(itir));
+		paravirt_dv_serialize_data();
 		ia64_set_psr(psr);
 	}
 
@@ -412,16 +413,14 @@ u64 translate_phy_pte(u64 *pte, u64 itir
 
 /*
  * Purge overlap TCs and then insert the new entry to emulate itc ops.
- *    Notes: Only TC entry can purge and insert.
- *    1 indicates this is MMIO
+ * Notes: Only TC entry can purge and insert.
  */
-int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
+void  thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
 						u64 ifa, int type)
 {
 	u64 ps;
 	u64 phy_pte, io_mask, index;
 	union ia64_rr vrr, mrr;
-	int ret = 0;
 
 	ps = itir_ps(itir);
 	vrr.val = vcpu_get_rr(v, ifa);
@@ -441,35 +440,29 @@ int thash_purge_and_insert(struct kvm_vc
 		phy_pte &= ~_PAGE_MA_MASK;
 	}
 
-	if (pte & VTLB_PTE_IO)
-		ret = 1;
-
 	vtlb_purge(v, ifa, ps);
 	vhpt_purge(v, ifa, ps);
 
-	if (ps == mrr.ps) {
-		if (!(pte&VTLB_PTE_IO)) {
-			vhpt_insert(phy_pte, itir, ifa, pte);
-		} else {
-			vtlb_insert(v, pte, itir, ifa);
-			vcpu_quick_region_set(VMX(v, tc_regions), ifa);
-		}
-	} else if (ps > mrr.ps) {
+	if ((ps != mrr.ps) || (pte & VTLB_PTE_IO)) {
 		vtlb_insert(v, pte, itir, ifa);
 		vcpu_quick_region_set(VMX(v, tc_regions), ifa);
-		if (!(pte&VTLB_PTE_IO))
-			vhpt_insert(phy_pte, itir, ifa, pte);
-	} else {
+	}
+	if (pte & VTLB_PTE_IO)
+		return;
+
+	if (ps >= mrr.ps)
+		vhpt_insert(phy_pte, itir, ifa, pte);
+	else {
 		u64 psr;
 		phy_pte  &= ~PAGE_FLAGS_RV_MASK;
 		psr = ia64_clear_ic();
 		ia64_itc(type, ifa, phy_pte, ps);
+		paravirt_dv_serialize_data();
 		ia64_set_psr(psr);
 	}
 	if (!(pte&VTLB_PTE_IO))
 		mark_pages_dirty(v, pte, ps);
 
-	return ret;
 }
 
 /*
@@ -509,7 +502,6 @@ void thash_purge_all(struct kvm_vcpu *v)
 	local_flush_tlb_all();
 }
 
-
 /*
  * Lookup the hash table and its collision chain to find an entry
  * covering this address rid:va or the entry.
@@ -517,7 +509,6 @@ void thash_purge_all(struct kvm_vcpu *v)
  * INPUT:
  *  in: TLB format for both VHPT & TLB.
  */
-
 struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data)
 {
 	struct thash_data  *cch;
@@ -547,7 +538,6 @@ struct thash_data *vtlb_lookup(struct kv
 	return NULL;
 }
 
-
 /*
  * Initialize internal control data before service.
  */
@@ -573,6 +563,10 @@ void thash_init(struct thash_cb *hcb, u6
 u64 kvm_get_mpt_entry(u64 gpfn)
 {
 	u64 *base = (u64 *) KVM_P2M_BASE;
+
+	if (gpfn >= (KVM_P2M_SIZE >> 3))
+		panic_vm(current_vcpu, "Invalid gpfn =%lx\n", gpfn);
+
 	return *(base + gpfn);
 }
 
@@ -589,7 +583,6 @@ u64 kvm_gpa_to_mpa(u64 gpa)
 	return (pte >> PAGE_SHIFT << PAGE_SHIFT) | (gpa & ~PAGE_MASK);
 }
 
-
 /*
  * Fetch guest bundle code.
  * INPUT:
@@ -631,7 +624,6 @@ int fetch_code(struct kvm_vcpu *vcpu, u6
 	return IA64_NO_FAULT;
 }
 
-
 void kvm_init_vhpt(struct kvm_vcpu *v)
 {
 	v->arch.vhpt.num = VHPT_NUM_ENTRIES;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/mm/init.c linux-libre-2.6.30-gnu1/arch/ia64/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/ia64/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/mca.h>
+#include <asm/paravirt.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -259,6 +260,7 @@ put_kernel_page (struct page *page, unsi
 static void __init
 setup_gate (void)
 {
+	void *gate_section;
 	struct page *page;
 
 	/*
@@ -266,10 +268,11 @@ setup_gate (void)
 	 * headers etc. and once execute-only page to enable
 	 * privilege-promotion via "epc":
 	 */
-	page = virt_to_page(ia64_imva(__start_gate_section));
+	gate_section = paravirt_get_gate_section();
+	page = virt_to_page(ia64_imva(gate_section));
 	put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
 #ifdef HAVE_BUGGY_SEGREL
-	page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
+	page = virt_to_page(ia64_imva(gate_section + PAGE_SIZE));
 	put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
 #else
 	put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
@@ -633,8 +636,7 @@ mem_init (void)
 #endif
 
 #ifdef CONFIG_FLATMEM
-	if (!mem_map)
-		BUG();
+	BUG_ON(!mem_map);
 	max_mapnr = max_low_pfn;
 #endif
 
@@ -667,8 +669,8 @@ mem_init (void)
 	 * code can tell them apart.
 	 */
 	for (i = 0; i < NR_syscalls; ++i) {
-		extern unsigned long fsyscall_table[NR_syscalls];
 		extern unsigned long sys_call_table[NR_syscalls];
+		unsigned long *fsyscall_table = paravirt_get_fsyscall_table();
 
 		if (!fsyscall_table[i] || nolwsys)
 			fsyscall_table[i] = sys_call_table[i] | 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/mm/tlb.c linux-libre-2.6.30-gnu1/arch/ia64/mm/tlb.c
--- linux-libre-2.6.29-gnu1/arch/ia64/mm/tlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/mm/tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -309,7 +309,7 @@ flush_tlb_range (struct vm_area_struct *
 
 	preempt_disable();
 #ifdef CONFIG_SMP
-	if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) {
+	if (mm != current->active_mm || cpumask_weight(mm_cpumask(mm)) != 1) {
 		platform_global_tlb_purge(mm, start, end, nbits);
 		preempt_enable();
 		return;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/scripts/pvcheck.sed linux-libre-2.6.30-gnu1/arch/ia64/scripts/pvcheck.sed
--- linux-libre-2.6.29-gnu1/arch/ia64/scripts/pvcheck.sed	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/scripts/pvcheck.sed	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@ s/mov.*=.*cr\.iip/.warning \"cr.iip shou
 s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g
 s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g	# avoid ar.fpsr
 s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g
+s/mov.*=.*ar\.itc.*/.warning \"ar.itc should not used directly\"/g
 s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g
 s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g
 s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/io_common.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/io_common.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/io_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/io_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -135,8 +135,7 @@ static s64 sn_device_fixup_war(u64 nasid
 	}
 
 	war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
-	if (!war_list)
-		BUG();
+	BUG_ON(!war_list);
 
 	SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
 			nasid, widget, __pa(war_list), 0, 0, 0 ,0);
@@ -180,23 +179,20 @@ sn_common_hubdev_init(struct hubdev_info
 		sizeof(struct sn_flush_device_kernel *);
 	hubdev->hdi_flush_nasid_list.widget_p =
 		kzalloc(size, GFP_KERNEL);
-	if (!hubdev->hdi_flush_nasid_list.widget_p)
-		BUG();
+	BUG_ON(!hubdev->hdi_flush_nasid_list.widget_p);
 
 	for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
 		size = DEV_PER_WIDGET *
 			sizeof(struct sn_flush_device_kernel);
 		sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
-		if (!sn_flush_device_kernel)
-			BUG();
+		BUG_ON(!sn_flush_device_kernel);
 
 		dev_entry = sn_flush_device_kernel;
 		for (device = 0; device < DEV_PER_WIDGET;
 		     device++, dev_entry++) {
 			size = sizeof(struct sn_flush_device_common);
 			dev_entry->common = kzalloc(size, GFP_KERNEL);
-			if (!dev_entry->common)
-				BUG();
+			BUG_ON(!dev_entry->common);
 			if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST))
 				status = sal_get_device_dmaflush_list(
 					     hubdev->hdi_nasid, widget, device,
@@ -326,8 +322,7 @@ sn_common_bus_fixup(struct pci_bus *bus,
 	 */
 	controller->platform_data = kzalloc(sizeof(struct sn_platform_data),
 					    GFP_KERNEL);
-	if (controller->platform_data == NULL)
-		BUG();
+	BUG_ON(controller->platform_data == NULL);
 	sn_platform_data =
 			(struct sn_platform_data *) controller->platform_data;
 	sn_platform_data->provider_soft = provider_soft;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/io_init.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/io_init.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/io_init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/io_init.c	2009-06-09 23:05:27.000000000 -0400
@@ -128,8 +128,7 @@ sn_legacy_pci_window_fixup(struct pci_co
 {
 		controller->window = kcalloc(2, sizeof(struct pci_window),
 					     GFP_KERNEL);
-		if (controller->window == NULL)
-			BUG();
+		BUG_ON(controller->window == NULL);
 		controller->window[0].offset = legacy_io;
 		controller->window[0].resource.name = "legacy_io";
 		controller->window[0].resource.flags = IORESOURCE_IO;
@@ -168,8 +167,7 @@ sn_pci_window_fixup(struct pci_dev *dev,
 	idx = controller->windows;
 	new_count = controller->windows + count;
 	new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
-	if (new_window == NULL)
-		BUG();
+	BUG_ON(new_window == NULL);
 	if (controller->window) {
 		memcpy(new_window, controller->window,
 		       sizeof(struct pci_window) * controller->windows);
@@ -222,8 +220,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
 		(u64) __pa(pcidev_info),
 		(u64) __pa(sn_irq_info));
 
-	if (status)
-		BUG(); /* Cannot get platform pci device information */
+	BUG_ON(status); /* Cannot get platform pci device information */
 
 
 	/* Copy over PIO Mapped Addresses */
@@ -307,8 +304,7 @@ sn_pci_controller_fixup(int segment, int
 	prom_bussoft_ptr = __va(prom_bussoft_ptr);
 
 	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
-	if (!controller)
-		BUG();
+	BUG_ON(!controller);
 	controller->segment = segment;
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/msi_sn.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/msi_sn.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/msi_sn.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/msi_sn.c	2009-06-09 23:05:27.000000000 -0400
@@ -205,7 +205,7 @@ static void sn_set_msi_irq_affinity(unsi
 	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
 	write_msi_msg(irq, &msg);
-	irq_desc[irq].affinity = *cpu_mask;
+	cpumask_copy(irq_desc[irq].affinity, cpu_mask);
 }
 #endif /* CONFIG_SMP */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/setup.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -732,8 +732,7 @@ void __init build_cnode_tables(void)
 		kl_config_hdr_t *klgraph_header;
 		nasid = cnodeid_to_nasid(node);
 		klgraph_header = ia64_sn_get_klconfig_addr(nasid);
-		if (klgraph_header == NULL)
-			BUG();
+		BUG_ON(klgraph_header == NULL);
 		brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
 		while (brd) {
 			if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
@@ -750,7 +749,7 @@ nasid_slice_to_cpuid(int nasid, int slic
 {
 	long cpu;
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
 		if (cpuid_to_nasid(cpu) == nasid &&
 					cpuid_to_slice(cpu) == slice)
 			return cpu;
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/prominfo_proc.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -225,7 +225,6 @@ static struct proc_dir_entry *sgi_promin
 int __init prominfo_init(void)
 {
 	struct proc_dir_entry **entp;
-	struct proc_dir_entry *p;
 	cnodeid_t cnodeid;
 	unsigned long nasid;
 	int size;
@@ -246,14 +245,10 @@ int __init prominfo_init(void)
 		sprintf(name, "node%d", cnodeid);
 		*entp = proc_mkdir(name, sgi_prominfo_entry);
 		nasid = cnodeid_to_nasid(cnodeid);
-		p = create_proc_read_entry("fit", 0, *entp, read_fit_entry,
+		create_proc_read_entry("fit", 0, *entp, read_fit_entry,
 					   (void *)nasid);
-		if (p)
-			p->owner = THIS_MODULE;
-		p = create_proc_read_entry("version", 0, *entp,
+		create_proc_read_entry("version", 0, *entp,
 					   read_version_entry, (void *)nasid);
-		if (p)
-			p->owner = THIS_MODULE;
 		entp++;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/sn2_smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -133,7 +133,7 @@ sn2_ipi_flush_all_tlb(struct mm_struct *
 	unsigned long itc;
 
 	itc = ia64_get_itc();
-	smp_flush_tlb_cpumask(mm->cpu_vm_mask);
+	smp_flush_tlb_cpumask(*mm_cpumask(mm));
 	itc = ia64_get_itc() - itc;
 	__get_cpu_var(ptcstats).shub_ipi_flushes_itc_clocks += itc;
 	__get_cpu_var(ptcstats).shub_ipi_flushes++;
@@ -182,7 +182,7 @@ sn2_global_tlb_purge(struct mm_struct *m
 	nodes_clear(nodes_flushed);
 	i = 0;
 
-	for_each_cpu_mask(cpu, mm->cpu_vm_mask) {
+	for_each_cpu(cpu, mm_cpumask(mm)) {
 		cnode = cpu_to_node(cpu);
 		node_set(cnode, nodes_flushed);
 		lcpu = cpu;
@@ -461,7 +461,7 @@ bool sn_cpu_disable_allowed(int cpu)
 
 static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset)
 {
-	if (*offset < NR_CPUS)
+	if (*offset < nr_cpu_ids)
 		return offset;
 	return NULL;
 }
@@ -469,7 +469,7 @@ static void *sn2_ptc_seq_start(struct se
 static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset)
 {
 	(*offset)++;
-	if (*offset < NR_CPUS)
+	if (*offset < nr_cpu_ids)
 		return offset;
 	return NULL;
 }
@@ -491,7 +491,7 @@ static int sn2_ptc_seq_show(struct seq_f
 		seq_printf(file, "# ptctest %d, flushopt %d\n", sn2_ptctest, sn2_flush_opt);
 	}
 
-	if (cpu < NR_CPUS && cpu_online(cpu)) {
+	if (cpu < nr_cpu_ids && cpu_online(cpu)) {
 		stat = &per_cpu(ptcstats, cpu);
 		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,
@@ -554,7 +554,7 @@ static int __init sn2_ptc_init(void)
 
 	proc_sn2_ptc = proc_create(PTC_BASENAME, 0444,
 				   NULL, &proc_sn2_ptc_operations);
-	if (!&proc_sn2_ptc_operations) {
+	if (!proc_sn2_ptc) {
 		printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/sn_hwperf.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/sn_hwperf.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2009-06-09 23:05:27.000000000 -0400
@@ -275,8 +275,7 @@ static int sn_hwperf_get_nearest_node_ob
 
 	/* get it's interconnect topology */
 	sz = op->ports * sizeof(struct sn_hwperf_port_info);
-	if (sz > sizeof(ptdata))
-		BUG();
+	BUG_ON(sz > sizeof(ptdata));
 	e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
 			      SN_HWPERF_ENUM_PORTS, nodeobj->id, sz,
 			      (u64)&ptdata, 0, 0, NULL);
@@ -310,8 +309,7 @@ static int sn_hwperf_get_nearest_node_ob
 	if (router && (!found_cpu || !found_mem)) {
 		/* search for a node connected to the same router */
 		sz = router->ports * sizeof(struct sn_hwperf_port_info);
-		if (sz > sizeof(ptdata))
-			BUG();
+		BUG_ON(sz > sizeof(ptdata));
 		e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
 				      SN_HWPERF_ENUM_PORTS, router->id, sz,
 				      (u64)&ptdata, 0, 0, NULL);
@@ -612,7 +610,7 @@ static int sn_hwperf_op_cpu(struct sn_hw
 	op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK;
 
 	if (cpu != SN_HWPERF_ARG_ANY_CPU) {
-		if (cpu >= NR_CPUS || !cpu_online(cpu)) {
+		if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
 			r = -EINVAL;
 			goto out;
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/timer.c linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/timer.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/kernel/sn2/timer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/kernel/sn2/timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@
 
 extern unsigned long sn_rtc_cycles_per_second;
 
-static cycle_t read_sn2(void)
+static cycle_t read_sn2(struct clocksource *cs)
 {
 	return (cycle_t)readq(RTC_COUNTER_ADDR);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/pci/pcibr/pcibr_dma.c linux-libre-2.6.30-gnu1/arch/ia64/sn/pci/pcibr/pcibr_dma.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/pci/pcibr/pcibr_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/pci/pcibr/pcibr_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -256,9 +256,7 @@ void sn_dma_flush(u64 addr)
 
 	hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo;
 
-	if (!hubinfo) {
-		BUG();
-	}
+	BUG_ON(!hubinfo);
 
 	flush_nasid_list = &hubinfo->hdi_flush_nasid_list;
 	if (flush_nasid_list->widget_p == NULL)
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/sn/pci/pci_dma.c linux-libre-2.6.30-gnu1/arch/ia64/sn/pci/pci_dma.c
--- linux-libre-2.6.29-gnu1/arch/ia64/sn/pci/pci_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/sn/pci/pci_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/dma-attrs.h>
+#include <linux/dma-mapping.h>
 #include <asm/dma.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/pcibus_provider_defs.h>
@@ -31,7 +31,7 @@
  * this function.  Of course, SN only supports devices that have 32 or more
  * address bits when using the PMU.
  */
-int sn_dma_supported(struct device *dev, u64 mask)
+static int sn_dma_supported(struct device *dev, u64 mask)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
@@ -39,7 +39,6 @@ int sn_dma_supported(struct device *dev,
 		return 0;
 	return 1;
 }
-EXPORT_SYMBOL(sn_dma_supported);
 
 /**
  * sn_dma_set_mask - set the DMA mask
@@ -75,8 +74,8 @@ EXPORT_SYMBOL(sn_dma_set_mask);
  * queue for a SCSI controller).  See Documentation/DMA-API.txt for
  * more information.
  */
-void *sn_dma_alloc_coherent(struct device *dev, size_t size,
-			    dma_addr_t * dma_handle, gfp_t flags)
+static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
+				   dma_addr_t * dma_handle, gfp_t flags)
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
@@ -124,7 +123,6 @@ void *sn_dma_alloc_coherent(struct devic
 
 	return cpuaddr;
 }
-EXPORT_SYMBOL(sn_dma_alloc_coherent);
 
 /**
  * sn_pci_free_coherent - free memory associated with coherent DMAable region
@@ -136,8 +134,8 @@ EXPORT_SYMBOL(sn_dma_alloc_coherent);
  * Frees the memory allocated by dma_alloc_coherent(), potentially unmapping
  * any associated IOMMU mappings.
  */
-void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t dma_handle)
+static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+				 dma_addr_t dma_handle)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -147,7 +145,6 @@ void sn_dma_free_coherent(struct device
 	provider->dma_unmap(pdev, dma_handle, 0);
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
-EXPORT_SYMBOL(sn_dma_free_coherent);
 
 /**
  * sn_dma_map_single_attrs - map a single page for DMA
@@ -173,10 +170,12 @@ EXPORT_SYMBOL(sn_dma_free_coherent);
  * TODO: simplify our interface;
  *       figure out how to save dmamap handle so can use two step.
  */
-dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr,
-				   size_t size, int direction,
-				   struct dma_attrs *attrs)
+static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page,
+				  unsigned long offset, size_t size,
+				  enum dma_data_direction dir,
+				  struct dma_attrs *attrs)
 {
+	void *cpu_addr = page_address(page) + offset;
 	dma_addr_t dma_addr;
 	unsigned long phys_addr;
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -201,7 +200,6 @@ dma_addr_t sn_dma_map_single_attrs(struc
 	}
 	return dma_addr;
 }
-EXPORT_SYMBOL(sn_dma_map_single_attrs);
 
 /**
  * sn_dma_unmap_single_attrs - unamp a DMA mapped page
@@ -215,21 +213,20 @@ EXPORT_SYMBOL(sn_dma_map_single_attrs);
  * by @dma_handle into the coherence domain.  On SN, we're always cache
  * coherent, so we just need to free any ATEs associated with this mapping.
  */
-void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr,
-			       size_t size, int direction,
-			       struct dma_attrs *attrs)
+static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+			      size_t size, enum dma_data_direction dir,
+			      struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	provider->dma_unmap(pdev, dma_addr, direction);
+	provider->dma_unmap(pdev, dma_addr, dir);
 }
-EXPORT_SYMBOL(sn_dma_unmap_single_attrs);
 
 /**
- * sn_dma_unmap_sg_attrs - unmap a DMA scatterlist
+ * sn_dma_unmap_sg - unmap a DMA scatterlist
  * @dev: device to unmap
  * @sg: scatterlist to unmap
  * @nhwentries: number of scatterlist entries
@@ -238,9 +235,9 @@ EXPORT_SYMBOL(sn_dma_unmap_single_attrs)
  *
  * Unmap a set of streaming mode DMA translations.
  */
-void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
-			   int nhwentries, int direction,
-			   struct dma_attrs *attrs)
+static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
+			    int nhwentries, enum dma_data_direction dir,
+			    struct dma_attrs *attrs)
 {
 	int i;
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -250,15 +247,14 @@ void sn_dma_unmap_sg_attrs(struct device
 	BUG_ON(dev->bus != &pci_bus_type);
 
 	for_each_sg(sgl, sg, nhwentries, i) {
-		provider->dma_unmap(pdev, sg->dma_address, direction);
+		provider->dma_unmap(pdev, sg->dma_address, dir);
 		sg->dma_address = (dma_addr_t) NULL;
 		sg->dma_length = 0;
 	}
 }
-EXPORT_SYMBOL(sn_dma_unmap_sg_attrs);
 
 /**
- * sn_dma_map_sg_attrs - map a scatterlist for DMA
+ * sn_dma_map_sg - map a scatterlist for DMA
  * @dev: device to map for
  * @sg: scatterlist to map
  * @nhwentries: number of entries
@@ -272,8 +268,9 @@ EXPORT_SYMBOL(sn_dma_unmap_sg_attrs);
  *
  * Maps each entry of @sg for DMA.
  */
-int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
-			int nhwentries, int direction, struct dma_attrs *attrs)
+static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl,
+			 int nhwentries, enum dma_data_direction dir,
+			 struct dma_attrs *attrs)
 {
 	unsigned long phys_addr;
 	struct scatterlist *saved_sg = sgl, *sg;
@@ -310,8 +307,7 @@ int sn_dma_map_sg_attrs(struct device *d
 			 * Free any successfully allocated entries.
 			 */
 			if (i > 0)
-				sn_dma_unmap_sg_attrs(dev, saved_sg, i,
-						      direction, attrs);
+				sn_dma_unmap_sg(dev, saved_sg, i, dir, attrs);
 			return 0;
 		}
 
@@ -320,45 +316,40 @@ int sn_dma_map_sg_attrs(struct device *d
 
 	return nhwentries;
 }
-EXPORT_SYMBOL(sn_dma_map_sg_attrs);
 
-void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-				size_t size, int direction)
+static void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+				       size_t size, enum dma_data_direction dir)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 }
-EXPORT_SYMBOL(sn_dma_sync_single_for_cpu);
 
-void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-				   size_t size, int direction)
+static void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+					  size_t size,
+					  enum dma_data_direction dir)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 }
-EXPORT_SYMBOL(sn_dma_sync_single_for_device);
 
-void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-			    int nelems, int direction)
+static void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+				   int nelems, enum dma_data_direction dir)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 }
-EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu);
 
-void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-			       int nelems, int direction)
+static void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+				      int nelems, enum dma_data_direction dir)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 }
-EXPORT_SYMBOL(sn_dma_sync_sg_for_device);
 
-int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
 	return 0;
 }
-EXPORT_SYMBOL(sn_dma_mapping_error);
 
 u64 sn_dma_get_required_mask(struct device *dev)
 {
-	return DMA_64BIT_MASK;
+	return DMA_BIT_MASK(64);
 }
 EXPORT_SYMBOL_GPL(sn_dma_get_required_mask);
 
@@ -471,3 +462,23 @@ int sn_pci_legacy_write(struct pci_bus *
  out:
 	return ret;
 }
+
+static struct dma_map_ops sn_dma_ops = {
+	.alloc_coherent		= sn_dma_alloc_coherent,
+	.free_coherent		= sn_dma_free_coherent,
+	.map_page		= sn_dma_map_page,
+	.unmap_page		= sn_dma_unmap_page,
+	.map_sg			= sn_dma_map_sg,
+	.unmap_sg		= sn_dma_unmap_sg,
+	.sync_single_for_cpu 	= sn_dma_sync_single_for_cpu,
+	.sync_sg_for_cpu	= sn_dma_sync_sg_for_cpu,
+	.sync_single_for_device = sn_dma_sync_single_for_device,
+	.sync_sg_for_device	= sn_dma_sync_sg_for_device,
+	.mapping_error		= sn_dma_mapping_error,
+	.dma_supported		= sn_dma_supported,
+};
+
+void sn_dma_init(void)
+{
+	dma_ops = &sn_dma_ops;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/gate-data.S linux-libre-2.6.30-gnu1/arch/ia64/xen/gate-data.S
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/gate-data.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/gate-data.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+	.section .data.gate.xen, "aw"
+
+	.incbin "arch/ia64/xen/gate.so"
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/hypercall.S linux-libre-2.6.30-gnu1/arch/ia64/xen/hypercall.S
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/hypercall.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/hypercall.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 #include <asm/intrinsics.h>
 #include <asm/xen/privop.h>
 
+#ifdef __INTEL_COMPILER
 /*
  * Hypercalls without parameter.
  */
@@ -72,6 +73,7 @@ GLOBAL_ENTRY(xen_set_rr0_to_rr4)
 	br.ret.sptk.many rp
 	;;
 END(xen_set_rr0_to_rr4)
+#endif
 
 GLOBAL_ENTRY(xen_send_ipi)
 	mov r14=r32
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/Makefile linux-libre-2.6.30-gnu1/arch/ia64/xen/Makefile
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,14 +3,29 @@
 #
 
 obj-y := hypercall.o xenivt.o xensetup.o xen_pv_ops.o irq_xen.o \
-	 hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o
+	 hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o \
+	 gate-data.o
 
 obj-$(CONFIG_IA64_GENERIC) += machvec.o
 
+# The gate DSO image is built using a special linker script.
+include $(srctree)/arch/ia64/kernel/Makefile.gate
+
+# tell compiled for xen
+CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_XEN
+AFLAGS_gate.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN -D__IA64_GATE_PARAVIRTUALIZED_XEN
+
+# use same file of native.
+$(obj)/gate.o: $(src)/../kernel/gate.S FORCE
+	$(call if_changed_dep,as_o_S)
+$(obj)/gate.lds: $(src)/../kernel/gate.lds.S FORCE
+	$(call if_changed_dep,cpp_lds_S)
+
+
 AFLAGS_xenivt.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN
 
 # xen multi compile
-ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S
+ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S fsys.S
 ASM_PARAVIRT_OBJS = $(addprefix xen-,$(ASM_PARAVIRT_MULTI_COMPILE_SRCS:.S=.o))
 obj-y += $(ASM_PARAVIRT_OBJS)
 define paravirtualized_xen
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/time.c linux-libre-2.6.30-gnu1/arch/ia64/xen/time.c
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -175,10 +175,58 @@ static void xen_itc_jitter_data_reset(vo
 	} while (unlikely(ret != lcycle));
 }
 
+/* based on xen_sched_clock() in arch/x86/xen/time.c. */
+/*
+ * This relies on HAVE_UNSTABLE_SCHED_CLOCK. If it can't be defined,
+ * something similar logic should be implemented here.
+ */
+/*
+ * Xen sched_clock implementation.  Returns the number of unstolen
+ * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED
+ * states.
+ */
+static unsigned long long xen_sched_clock(void)
+{
+	struct vcpu_runstate_info runstate;
+
+	unsigned long long now;
+	unsigned long long offset;
+	unsigned long long ret;
+
+	/*
+	 * Ideally sched_clock should be called on a per-cpu basis
+	 * anyway, so preempt should already be disabled, but that's
+	 * not current practice at the moment.
+	 */
+	preempt_disable();
+
+	/*
+	 * both ia64_native_sched_clock() and xen's runstate are
+	 * based on mAR.ITC. So difference of them makes sense.
+	 */
+	now = ia64_native_sched_clock();
+
+	get_runstate_snapshot(&runstate);
+
+	WARN_ON(runstate.state != RUNSTATE_running);
+
+	offset = 0;
+	if (now > runstate.state_entry_time)
+		offset = now - runstate.state_entry_time;
+	ret = runstate.time[RUNSTATE_blocked] +
+		runstate.time[RUNSTATE_running] +
+		offset;
+
+	preempt_enable();
+
+	return ret;
+}
+
 struct pv_time_ops xen_time_ops __initdata = {
 	.init_missing_ticks_accounting	= xen_init_missing_ticks_accounting,
 	.do_steal_accounting		= xen_do_steal_accounting,
 	.clocksource_resume		= xen_itc_jitter_data_reset,
+	.sched_clock			= xen_sched_clock,
 };
 
 /* Called after suspend, to resume time.  */
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/xen_pv_ops.c linux-libre-2.6.30-gnu1/arch/ia64/xen/xen_pv_ops.c
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/xen_pv_ops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/xen_pv_ops.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/pm.h>
+#include <linux/unistd.h>
 
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/xencomm.h>
@@ -153,6 +154,13 @@ xen_post_smp_prepare_boot_cpu(void)
 	xen_setup_vcpu_info_placement();
 }
 
+#ifdef ASM_SUPPORTED
+static unsigned long __init_or_module
+xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type);
+#endif
+static void __init
+xen_patch_branch(unsigned long tag, unsigned long type);
+
 static const struct pv_init_ops xen_init_ops __initconst = {
 	.banner = xen_banner,
 
@@ -163,6 +171,53 @@ static const struct pv_init_ops xen_init
 	.arch_setup_nomca = xen_arch_setup_nomca,
 
 	.post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu,
+#ifdef ASM_SUPPORTED
+	.patch_bundle = xen_patch_bundle,
+#endif
+	.patch_branch = xen_patch_branch,
+};
+
+/***************************************************************************
+ * pv_fsys_data
+ * addresses for fsys
+ */
+
+extern unsigned long xen_fsyscall_table[NR_syscalls];
+extern char xen_fsys_bubble_down[];
+struct pv_fsys_data xen_fsys_data __initdata = {
+	.fsyscall_table = (unsigned long *)xen_fsyscall_table,
+	.fsys_bubble_down = (void *)xen_fsys_bubble_down,
+};
+
+/***************************************************************************
+ * pv_patchdata
+ * patchdata addresses
+ */
+
+#define DECLARE(name)							\
+	extern unsigned long __xen_start_gate_##name##_patchlist[];	\
+	extern unsigned long __xen_end_gate_##name##_patchlist[]
+
+DECLARE(fsyscall);
+DECLARE(brl_fsys_bubble_down);
+DECLARE(vtop);
+DECLARE(mckinley_e9);
+
+extern unsigned long __xen_start_gate_section[];
+
+#define ASSIGN(name)							\
+	.start_##name##_patchlist =					\
+		(unsigned long)__xen_start_gate_##name##_patchlist,	\
+	.end_##name##_patchlist =					\
+		(unsigned long)__xen_end_gate_##name##_patchlist
+
+static struct pv_patchdata xen_patchdata __initdata = {
+	ASSIGN(fsyscall),
+	ASSIGN(brl_fsys_bubble_down),
+	ASSIGN(vtop),
+	ASSIGN(mckinley_e9),
+
+	.gate_section = (void*)__xen_start_gate_section,
 };
 
 /***************************************************************************
@@ -170,6 +225,76 @@ static const struct pv_init_ops xen_init
  * intrinsics hooks.
  */
 
+#ifndef ASM_SUPPORTED
+static void
+xen_set_itm_with_offset(unsigned long val)
+{
+	/* ia64_cpu_local_tick() calls this with interrupt enabled. */
+	/* WARN_ON(!irqs_disabled()); */
+	xen_set_itm(val - XEN_MAPPEDREGS->itc_offset);
+}
+
+static unsigned long
+xen_get_itm_with_offset(void)
+{
+	/* unused at this moment */
+	printk(KERN_DEBUG "%s is called.\n", __func__);
+
+	WARN_ON(!irqs_disabled());
+	return ia64_native_getreg(_IA64_REG_CR_ITM) +
+		XEN_MAPPEDREGS->itc_offset;
+}
+
+/* ia64_set_itc() is only called by
+ * cpu_init() with ia64_set_itc(0) and ia64_sync_itc().
+ * So XEN_MAPPEDRESG->itc_offset cal be considered as almost constant.
+ */
+static void
+xen_set_itc(unsigned long val)
+{
+	unsigned long mitc;
+
+	WARN_ON(!irqs_disabled());
+	mitc = ia64_native_getreg(_IA64_REG_AR_ITC);
+	XEN_MAPPEDREGS->itc_offset = val - mitc;
+	XEN_MAPPEDREGS->itc_last = val;
+}
+
+static unsigned long
+xen_get_itc(void)
+{
+	unsigned long res;
+	unsigned long itc_offset;
+	unsigned long itc_last;
+	unsigned long ret_itc_last;
+
+	itc_offset = XEN_MAPPEDREGS->itc_offset;
+	do {
+		itc_last = XEN_MAPPEDREGS->itc_last;
+		res = ia64_native_getreg(_IA64_REG_AR_ITC);
+		res += itc_offset;
+		if (itc_last >= res)
+			res = itc_last + 1;
+		ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last,
+				       itc_last, res);
+	} while (unlikely(ret_itc_last != itc_last));
+	return res;
+
+#if 0
+	/* ia64_itc_udelay() calls ia64_get_itc() with interrupt enabled.
+	   Should it be paravirtualized instead? */
+	WARN_ON(!irqs_disabled());
+	itc_offset = XEN_MAPPEDREGS->itc_offset;
+	itc_last = XEN_MAPPEDREGS->itc_last;
+	res = ia64_native_getreg(_IA64_REG_AR_ITC);
+	res += itc_offset;
+	if (itc_last >= res)
+		res = itc_last + 1;
+	XEN_MAPPEDREGS->itc_last = res;
+	return res;
+#endif
+}
+
 static void xen_setreg(int regnum, unsigned long val)
 {
 	switch (regnum) {
@@ -181,11 +306,14 @@ static void xen_setreg(int regnum, unsig
 		xen_set_eflag(val);
 		break;
 #endif
+	case _IA64_REG_AR_ITC:
+		xen_set_itc(val);
+		break;
 	case _IA64_REG_CR_TPR:
 		xen_set_tpr(val);
 		break;
 	case _IA64_REG_CR_ITM:
-		xen_set_itm(val);
+		xen_set_itm_with_offset(val);
 		break;
 	case _IA64_REG_CR_EOI:
 		xen_eoi(val);
@@ -209,6 +337,12 @@ static unsigned long xen_getreg(int regn
 		res = xen_get_eflag();
 		break;
 #endif
+	case _IA64_REG_AR_ITC:
+		res = xen_get_itc();
+		break;
+	case _IA64_REG_CR_ITM:
+		res = xen_get_itm_with_offset();
+		break;
 	case _IA64_REG_CR_IVR:
 		res = xen_get_ivr();
 		break;
@@ -259,8 +393,417 @@ xen_intrin_local_irq_restore(unsigned lo
 	else
 		xen_rsm_i();
 }
+#else
+#define __DEFINE_FUNC(name, code)					\
+	extern const char xen_ ## name ## _direct_start[];		\
+	extern const char xen_ ## name ## _direct_end[];		\
+	asm (".align 32\n"						\
+	     ".proc xen_" #name "\n"					\
+	     "xen_" #name ":\n"						\
+	     "xen_" #name "_direct_start:\n"				\
+	     code							\
+	     "xen_" #name "_direct_end:\n"				\
+	     "br.cond.sptk.many b6\n"					\
+	     ".endp xen_" #name "\n")
 
-static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+#define DEFINE_VOID_FUNC0(name, code)		\
+	extern void				\
+	xen_ ## name (void);			\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1(name, code)		\
+	extern void				\
+	xen_ ## name (unsigned long arg);	\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1_VOID(name, code)	\
+	extern void				\
+	xen_ ## name (void *arg);		\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC2(name, code)		\
+	extern void				\
+	xen_ ## name (unsigned long arg0,	\
+		      unsigned long arg1);	\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC0(name, code)		\
+	extern unsigned long			\
+	xen_ ## name (void);			\
+	__DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC1(name, type, code)		\
+	extern unsigned long			\
+	xen_ ## name (type arg);		\
+	__DEFINE_FUNC(name, code)
+
+#define XEN_PSR_I_ADDR_ADDR     (XSI_BASE + XSI_PSR_I_ADDR_OFS)
+
+/*
+ * static void xen_set_itm_with_offset(unsigned long val)
+ *        xen_set_itm(val - XEN_MAPPEDREGS->itc_offset);
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC1(set_itm_with_offset,
+		  "mov r2 = " __stringify(XSI_BASE) " + "
+		  __stringify(XSI_ITC_OFFSET_OFS) "\n"
+		  ";;\n"
+		  "ld8 r3 = [r2]\n"
+		  ";;\n"
+		  "sub r8 = r8, r3\n"
+		  "break " __stringify(HYPERPRIVOP_SET_ITM) "\n");
+
+/*
+ * static unsigned long xen_get_itm_with_offset(void)
+ *    return ia64_native_getreg(_IA64_REG_CR_ITM) + XEN_MAPPEDREGS->itc_offset;
+ */
+/* 2 bundles */
+DEFINE_FUNC0(get_itm_with_offset,
+	     "mov r2 = " __stringify(XSI_BASE) " + "
+	     __stringify(XSI_ITC_OFFSET_OFS) "\n"
+	     ";;\n"
+	     "ld8 r3 = [r2]\n"
+	     "mov r8 = cr.itm\n"
+	     ";;\n"
+	     "add r8 = r8, r2\n");
+
+/*
+ * static void xen_set_itc(unsigned long val)
+ *	unsigned long mitc;
+ *
+ *	WARN_ON(!irqs_disabled());
+ *	mitc = ia64_native_getreg(_IA64_REG_AR_ITC);
+ *	XEN_MAPPEDREGS->itc_offset = val - mitc;
+ *	XEN_MAPPEDREGS->itc_last = val;
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC1(set_itc,
+		  "mov r2 = " __stringify(XSI_BASE) " + "
+		  __stringify(XSI_ITC_LAST_OFS) "\n"
+		  "mov r3 = ar.itc\n"
+		  ";;\n"
+		  "sub r3 = r8, r3\n"
+		  "st8 [r2] = r8, "
+		  __stringify(XSI_ITC_LAST_OFS) " - "
+		  __stringify(XSI_ITC_OFFSET_OFS) "\n"
+		  ";;\n"
+		  "st8 [r2] = r3\n");
+
+/*
+ * static unsigned long xen_get_itc(void)
+ *	unsigned long res;
+ *	unsigned long itc_offset;
+ *	unsigned long itc_last;
+ *	unsigned long ret_itc_last;
+ *
+ *	itc_offset = XEN_MAPPEDREGS->itc_offset;
+ *	do {
+ *		itc_last = XEN_MAPPEDREGS->itc_last;
+ *		res = ia64_native_getreg(_IA64_REG_AR_ITC);
+ *		res += itc_offset;
+ *		if (itc_last >= res)
+ *			res = itc_last + 1;
+ *		ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last,
+ *				       itc_last, res);
+ *	} while (unlikely(ret_itc_last != itc_last));
+ *	return res;
+ */
+/* 5 bundles */
+DEFINE_FUNC0(get_itc,
+	     "mov r2 = " __stringify(XSI_BASE) " + "
+	     __stringify(XSI_ITC_OFFSET_OFS) "\n"
+	     ";;\n"
+	     "ld8 r9 = [r2], " __stringify(XSI_ITC_LAST_OFS) " - "
+	     __stringify(XSI_ITC_OFFSET_OFS) "\n"
+					/* r9 = itc_offset */
+					/* r2 = XSI_ITC_OFFSET */
+	     "888:\n"
+	     "mov r8 = ar.itc\n"	/* res = ar.itc */
+	     ";;\n"
+	     "ld8 r3 = [r2]\n"		/* r3 = itc_last */
+	     "add r8 = r8, r9\n"	/* res = ar.itc + itc_offset */
+	     ";;\n"
+	     "cmp.gtu p6, p0 = r3, r8\n"
+	     ";;\n"
+	     "(p6) add r8 = 1, r3\n"	/* if (itc_last > res) itc_last + 1 */
+	     ";;\n"
+	     "mov ar.ccv = r8\n"
+	     ";;\n"
+	     "cmpxchg8.acq r10 = [r2], r8, ar.ccv\n"
+	     ";;\n"
+	     "cmp.ne p6, p0 = r10, r3\n"
+	     "(p6) hint @pause\n"
+	     "(p6) br.cond.spnt 888b\n");
+
+DEFINE_VOID_FUNC1_VOID(fc,
+		       "break " __stringify(HYPERPRIVOP_FC) "\n");
+
+/*
+ * psr_i_addr_addr = XEN_PSR_I_ADDR_ADDR
+ * masked_addr = *psr_i_addr_addr
+ * pending_intr_addr = masked_addr - 1
+ * if (val & IA64_PSR_I) {
+ *   masked = *masked_addr
+ *   *masked_addr = 0:xen_set_virtual_psr_i(1)
+ *   compiler barrier
+ *   if (masked) {
+ *      uint8_t pending = *pending_intr_addr;
+ *      if (pending)
+ *              XEN_HYPER_SSM_I
+ *   }
+ * } else {
+ *   *masked_addr = 1:xen_set_virtual_psr_i(0)
+ * }
+ */
+/* 6 bundles */
+DEFINE_VOID_FUNC1(intrin_local_irq_restore,
+		  /* r8 = input value: 0 or IA64_PSR_I
+		   * p6 =  (flags & IA64_PSR_I)
+		   *    = if clause
+		   * p7 = !(flags & IA64_PSR_I)
+		   *    = else clause
+		   */
+		  "cmp.ne p6, p7 = r8, r0\n"
+		  "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+		  ";;\n"
+		  /* r9 = XEN_PSR_I_ADDR */
+		  "ld8 r9 = [r9]\n"
+		  ";;\n"
+
+		  /* r10 = masked previous value */
+		  "(p6)	ld1.acq r10 = [r9]\n"
+		  ";;\n"
+
+		  /* p8 = !masked interrupt masked previously? */
+		  "(p6)	cmp.ne.unc p8, p0 = r10, r0\n"
+
+		  /* p7 = else clause */
+		  "(p7)	mov r11 = 1\n"
+		  ";;\n"
+		  /* masked = 1 */
+		  "(p7)	st1.rel [r9] = r11\n"
+
+		  /* p6 = if clause */
+		  /* masked = 0
+		   * r9 = masked_addr - 1
+		   *    = pending_intr_addr
+		   */
+		  "(p8)	st1.rel [r9] = r0, -1\n"
+		  ";;\n"
+		  /* r8 = pending_intr */
+		  "(p8)	ld1.acq r11 = [r9]\n"
+		  ";;\n"
+		  /* p9 = interrupt pending? */
+		  "(p8)	cmp.ne.unc p9, p10 = r11, r0\n"
+		  ";;\n"
+		  "(p10) mf\n"
+		  /* issue hypercall to trigger interrupt */
+		  "(p9)	break " __stringify(HYPERPRIVOP_SSM_I) "\n");
+
+DEFINE_VOID_FUNC2(ptcga,
+		  "break " __stringify(HYPERPRIVOP_PTC_GA) "\n");
+DEFINE_VOID_FUNC2(set_rr,
+		  "break " __stringify(HYPERPRIVOP_SET_RR) "\n");
+
+/*
+ * tmp = XEN_MAPPEDREGS->interrupt_mask_addr = XEN_PSR_I_ADDR_ADDR;
+ * tmp = *tmp
+ * tmp = *tmp;
+ * psr_i = tmp? 0: IA64_PSR_I;
+ */
+/* 4 bundles */
+DEFINE_FUNC0(get_psr_i,
+	     "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+	     ";;\n"
+	     "ld8 r9 = [r9]\n"			/* r9 = XEN_PSR_I_ADDR */
+	     "mov r8 = 0\n"			/* psr_i = 0 */
+	     ";;\n"
+	     "ld1.acq r9 = [r9]\n"		/* r9 = XEN_PSR_I */
+	     ";;\n"
+	     "cmp.eq.unc p6, p0 = r9, r0\n"	/* p6 = (XEN_PSR_I != 0) */
+	     ";;\n"
+	     "(p6) mov r8 = " __stringify(1 << IA64_PSR_I_BIT) "\n");
+
+DEFINE_FUNC1(thash, unsigned long,
+	     "break " __stringify(HYPERPRIVOP_THASH) "\n");
+DEFINE_FUNC1(get_cpuid, int,
+	     "break " __stringify(HYPERPRIVOP_GET_CPUID) "\n");
+DEFINE_FUNC1(get_pmd, int,
+	     "break " __stringify(HYPERPRIVOP_GET_PMD) "\n");
+DEFINE_FUNC1(get_rr, unsigned long,
+	     "break " __stringify(HYPERPRIVOP_GET_RR) "\n");
+
+/*
+ * void xen_privop_ssm_i(void)
+ *
+ * int masked = !xen_get_virtual_psr_i();
+ *	// masked = *(*XEN_MAPPEDREGS->interrupt_mask_addr)
+ * xen_set_virtual_psr_i(1)
+ *	// *(*XEN_MAPPEDREGS->interrupt_mask_addr) = 0
+ * // compiler barrier
+ * if (masked) {
+ *	uint8_t* pend_int_addr =
+ *		(uint8_t*)(*XEN_MAPPEDREGS->interrupt_mask_addr) - 1;
+ *	uint8_t pending = *pend_int_addr;
+ *	if (pending)
+ *		XEN_HYPER_SSM_I
+ * }
+ */
+/* 4 bundles */
+DEFINE_VOID_FUNC0(ssm_i,
+		  "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+		  ";;\n"
+		  "ld8 r8 = [r8]\n"		/* r8 = XEN_PSR_I_ADDR */
+		  ";;\n"
+		  "ld1.acq r9 = [r8]\n"		/* r9 = XEN_PSR_I */
+		  ";;\n"
+		  "st1.rel [r8] = r0, -1\n"	/* psr_i = 0. enable interrupt
+						 * r8 = XEN_PSR_I_ADDR - 1
+						 *    = pend_int_addr
+						 */
+		  "cmp.eq.unc p0, p6 = r9, r0\n"/* p6 = !XEN_PSR_I
+						 * previously interrupt
+						 * masked?
+						 */
+		  ";;\n"
+		  "(p6) ld1.acq r8 = [r8]\n"	/* r8 = xen_pend_int */
+		  ";;\n"
+		  "(p6) cmp.eq.unc p6, p7 = r8, r0\n"	/*interrupt pending?*/
+		  ";;\n"
+		  /* issue hypercall to get interrupt */
+		  "(p7) break " __stringify(HYPERPRIVOP_SSM_I) "\n"
+		  ";;\n");
+
+/*
+ * psr_i_addr_addr = XEN_MAPPEDREGS->interrupt_mask_addr
+ *		   = XEN_PSR_I_ADDR_ADDR;
+ * psr_i_addr = *psr_i_addr_addr;
+ * *psr_i_addr = 1;
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC0(rsm_i,
+		  "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+						/* r8 = XEN_PSR_I_ADDR */
+		  "mov r9 = 1\n"
+		  ";;\n"
+		  "ld8 r8 = [r8]\n"		/* r8 = XEN_PSR_I */
+		  ";;\n"
+		  "st1.rel [r8] = r9\n");	/* XEN_PSR_I = 1 */
+
+extern void
+xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
+		   unsigned long val2, unsigned long val3,
+		   unsigned long val4);
+__DEFINE_FUNC(set_rr0_to_rr4,
+	      "break " __stringify(HYPERPRIVOP_SET_RR0_TO_RR4) "\n");
+
+
+extern unsigned long xen_getreg(int regnum);
+#define __DEFINE_GET_REG(id, privop)					\
+	"mov r2 = " __stringify(_IA64_REG_ ## id) "\n"			\
+	";;\n"								\
+	"cmp.eq p6, p0 = r2, r8\n"					\
+	";;\n"								\
+	"(p6) break " __stringify(HYPERPRIVOP_GET_ ## privop) "\n"	\
+	"(p6) br.cond.sptk.many b6\n"					\
+	";;\n"
+
+__DEFINE_FUNC(getreg,
+	      __DEFINE_GET_REG(PSR, PSR)
+#ifdef CONFIG_IA32_SUPPORT
+	      __DEFINE_GET_REG(AR_EFLAG, EFLAG)
+#endif
+
+	      /* get_itc */
+	      "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n"
+	      ";;\n"
+	      "cmp.eq p6, p0 = r2, r8\n"
+	      ";;\n"
+	      "(p6) br.cond.spnt xen_get_itc\n"
+	      ";;\n"
+
+	      /* get itm */
+	      "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n"
+	      ";;\n"
+	      "cmp.eq p6, p0 = r2, r8\n"
+	      ";;\n"
+	      "(p6) br.cond.spnt xen_get_itm_with_offset\n"
+	      ";;\n"
+
+	      __DEFINE_GET_REG(CR_IVR, IVR)
+	      __DEFINE_GET_REG(CR_TPR, TPR)
+
+	      /* fall back */
+	      "movl r2 = ia64_native_getreg_func\n"
+	      ";;\n"
+	      "mov b7 = r2\n"
+	      ";;\n"
+	      "br.cond.sptk.many b7\n");
+
+extern void xen_setreg(int regnum, unsigned long val);
+#define __DEFINE_SET_REG(id, privop)					\
+	"mov r2 = " __stringify(_IA64_REG_ ## id) "\n"			\
+	";;\n"								\
+	"cmp.eq p6, p0 = r2, r9\n"					\
+	";;\n"								\
+	"(p6) break " __stringify(HYPERPRIVOP_ ## privop) "\n"		\
+	"(p6) br.cond.sptk.many b6\n"					\
+	";;\n"
+
+__DEFINE_FUNC(setreg,
+	      /* kr0 .. kr 7*/
+	      /*
+	       * if (_IA64_REG_AR_KR0 <= regnum &&
+	       *     regnum <= _IA64_REG_AR_KR7) {
+	       *     register __index asm ("r8") = regnum - _IA64_REG_AR_KR0
+	       *     register __val asm ("r9") = val
+	       *    "break HYPERPRIVOP_SET_KR"
+	       * }
+	       */
+	      "mov r17 = r9\n"
+	      "mov r2 = " __stringify(_IA64_REG_AR_KR0) "\n"
+	      ";;\n"
+	      "cmp.ge p6, p0 = r9, r2\n"
+	      "sub r17 = r17, r2\n"
+	      ";;\n"
+	      "(p6) cmp.ge.unc p7, p0 = "
+	      __stringify(_IA64_REG_AR_KR7) " - " __stringify(_IA64_REG_AR_KR0)
+	      ", r17\n"
+	      ";;\n"
+	      "(p7) mov r9 = r8\n"
+	      ";;\n"
+	      "(p7) mov r8 = r17\n"
+	      "(p7) break " __stringify(HYPERPRIVOP_SET_KR) "\n"
+
+	      /* set itm */
+	      "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n"
+	      ";;\n"
+	      "cmp.eq p6, p0 = r2, r8\n"
+	      ";;\n"
+	      "(p6) br.cond.spnt xen_set_itm_with_offset\n"
+
+	      /* set itc */
+	      "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n"
+	      ";;\n"
+	      "cmp.eq p6, p0 = r2, r8\n"
+	      ";;\n"
+	      "(p6) br.cond.spnt xen_set_itc\n"
+
+#ifdef CONFIG_IA32_SUPPORT
+	      __DEFINE_SET_REG(AR_EFLAG, SET_EFLAG)
+#endif
+	      __DEFINE_SET_REG(CR_TPR, SET_TPR)
+	      __DEFINE_SET_REG(CR_EOI, EOI)
+
+	      /* fall back */
+	      "movl r2 = ia64_native_setreg_func\n"
+	      ";;\n"
+	      "mov b7 = r2\n"
+	      ";;\n"
+	      "br.cond.sptk.many b7\n");
+#endif
+
+static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 	.fc		= xen_fc,
 	.thash		= xen_thash,
 	.get_cpuid	= xen_get_cpuid,
@@ -337,7 +880,7 @@ xen_iosapic_write(char __iomem *iosapic,
 	HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
 }
 
-static const struct pv_iosapic_ops xen_iosapic_ops __initconst = {
+static struct pv_iosapic_ops xen_iosapic_ops __initdata = {
 	.pcat_compat_init = xen_pcat_compat_init,
 	.__get_irq_chip = xen_iosapic_get_irq_chip,
 
@@ -355,6 +898,8 @@ xen_setup_pv_ops(void)
 	xen_info_init();
 	pv_info = xen_info;
 	pv_init_ops = xen_init_ops;
+	pv_fsys_data = xen_fsys_data;
+	pv_patchdata = xen_patchdata;
 	pv_cpu_ops = xen_cpu_ops;
 	pv_iosapic_ops = xen_iosapic_ops;
 	pv_irq_ops = xen_irq_ops;
@@ -362,3 +907,252 @@ xen_setup_pv_ops(void)
 
 	paravirt_cpu_asm_init(&xen_cpu_asm_switch);
 }
+
+#ifdef ASM_SUPPORTED
+/***************************************************************************
+ * binary pacthing
+ * pv_init_ops.patch_bundle
+ */
+
+#define DEFINE_FUNC_GETREG(name, privop)				\
+	DEFINE_FUNC0(get_ ## name,					\
+		     "break "__stringify(HYPERPRIVOP_GET_ ## privop) "\n")
+
+DEFINE_FUNC_GETREG(psr, PSR);
+DEFINE_FUNC_GETREG(eflag, EFLAG);
+DEFINE_FUNC_GETREG(ivr, IVR);
+DEFINE_FUNC_GETREG(tpr, TPR);
+
+#define DEFINE_FUNC_SET_KR(n)						\
+	DEFINE_VOID_FUNC0(set_kr ## n,					\
+			  ";;\n"					\
+			  "mov r9 = r8\n"				\
+			  "mov r8 = " #n "\n"				\
+			  "break " __stringify(HYPERPRIVOP_SET_KR) "\n")
+
+DEFINE_FUNC_SET_KR(0);
+DEFINE_FUNC_SET_KR(1);
+DEFINE_FUNC_SET_KR(2);
+DEFINE_FUNC_SET_KR(3);
+DEFINE_FUNC_SET_KR(4);
+DEFINE_FUNC_SET_KR(5);
+DEFINE_FUNC_SET_KR(6);
+DEFINE_FUNC_SET_KR(7);
+
+#define __DEFINE_FUNC_SETREG(name, privop)				\
+	DEFINE_VOID_FUNC0(name,						\
+			  "break "__stringify(HYPERPRIVOP_ ## privop) "\n")
+
+#define DEFINE_FUNC_SETREG(name, privop)			\
+	__DEFINE_FUNC_SETREG(set_ ## name, SET_ ## privop)
+
+DEFINE_FUNC_SETREG(eflag, EFLAG);
+DEFINE_FUNC_SETREG(tpr, TPR);
+__DEFINE_FUNC_SETREG(eoi, EOI);
+
+extern const char xen_check_events[];
+extern const char __xen_intrin_local_irq_restore_direct_start[];
+extern const char __xen_intrin_local_irq_restore_direct_end[];
+extern const unsigned long __xen_intrin_local_irq_restore_direct_reloc;
+
+asm (
+	".align 32\n"
+	".proc xen_check_events\n"
+	"xen_check_events:\n"
+	/* masked = 0
+	 * r9 = masked_addr - 1
+	 *    = pending_intr_addr
+	 */
+	"st1.rel [r9] = r0, -1\n"
+	";;\n"
+	/* r8 = pending_intr */
+	"ld1.acq r11 = [r9]\n"
+	";;\n"
+	/* p9 = interrupt pending? */
+	"cmp.ne p9, p10 = r11, r0\n"
+	";;\n"
+	"(p10) mf\n"
+	/* issue hypercall to trigger interrupt */
+	"(p9) break " __stringify(HYPERPRIVOP_SSM_I) "\n"
+	"br.cond.sptk.many b6\n"
+	".endp xen_check_events\n"
+	"\n"
+	".align 32\n"
+	".proc __xen_intrin_local_irq_restore_direct\n"
+	"__xen_intrin_local_irq_restore_direct:\n"
+	"__xen_intrin_local_irq_restore_direct_start:\n"
+	"1:\n"
+	"{\n"
+	"cmp.ne p6, p7 = r8, r0\n"
+	"mov r17 = ip\n" /* get ip to calc return address */
+	"mov r9 = "__stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+	";;\n"
+	"}\n"
+	"{\n"
+	/* r9 = XEN_PSR_I_ADDR */
+	"ld8 r9 = [r9]\n"
+	";;\n"
+	/* r10 = masked previous value */
+	"(p6) ld1.acq r10 = [r9]\n"
+	"adds r17 =  1f - 1b, r17\n" /* calculate return address */
+	";;\n"
+	"}\n"
+	"{\n"
+	/* p8 = !masked interrupt masked previously? */
+	"(p6) cmp.ne.unc p8, p0 = r10, r0\n"
+	"\n"
+	/* p7 = else clause */
+	"(p7) mov r11 = 1\n"
+	";;\n"
+	"(p8) mov b6 = r17\n" /* set return address */
+	"}\n"
+	"{\n"
+	/* masked = 1 */
+	"(p7) st1.rel [r9] = r11\n"
+	"\n"
+	"[99:]\n"
+	"(p8) brl.cond.dptk.few xen_check_events\n"
+	"}\n"
+	/* pv calling stub is 5 bundles. fill nop to adjust return address */
+	"{\n"
+	"nop 0\n"
+	"nop 0\n"
+	"nop 0\n"
+	"}\n"
+	"1:\n"
+	"__xen_intrin_local_irq_restore_direct_end:\n"
+	".endp __xen_intrin_local_irq_restore_direct\n"
+	"\n"
+	".align 8\n"
+	"__xen_intrin_local_irq_restore_direct_reloc:\n"
+	"data8 99b\n"
+);
+
+static struct paravirt_patch_bundle_elem xen_patch_bundle_elems[]
+__initdata_or_module =
+{
+#define XEN_PATCH_BUNDLE_ELEM(name, type)		\
+	{						\
+		(void*)xen_ ## name ## _direct_start,	\
+		(void*)xen_ ## name ## _direct_end,	\
+		PARAVIRT_PATCH_TYPE_ ## type,		\
+	}
+
+	XEN_PATCH_BUNDLE_ELEM(fc, FC),
+	XEN_PATCH_BUNDLE_ELEM(thash, THASH),
+	XEN_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID),
+	XEN_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD),
+	XEN_PATCH_BUNDLE_ELEM(ptcga, PTCGA),
+	XEN_PATCH_BUNDLE_ELEM(get_rr, GET_RR),
+	XEN_PATCH_BUNDLE_ELEM(set_rr, SET_RR),
+	XEN_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4),
+	XEN_PATCH_BUNDLE_ELEM(ssm_i, SSM_I),
+	XEN_PATCH_BUNDLE_ELEM(rsm_i, RSM_I),
+	XEN_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I),
+	{
+		(void*)__xen_intrin_local_irq_restore_direct_start,
+		(void*)__xen_intrin_local_irq_restore_direct_end,
+		PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE,
+	},
+
+#define XEN_PATCH_BUNDLE_ELEM_GETREG(name, reg)			\
+	{							\
+		xen_get_ ## name ## _direct_start,		\
+		xen_get_ ## name ## _direct_end,		\
+		PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \
+	}
+
+	XEN_PATCH_BUNDLE_ELEM_GETREG(psr, PSR),
+	XEN_PATCH_BUNDLE_ELEM_GETREG(eflag, AR_EFLAG),
+
+	XEN_PATCH_BUNDLE_ELEM_GETREG(ivr, CR_IVR),
+	XEN_PATCH_BUNDLE_ELEM_GETREG(tpr, CR_TPR),
+
+	XEN_PATCH_BUNDLE_ELEM_GETREG(itc, AR_ITC),
+	XEN_PATCH_BUNDLE_ELEM_GETREG(itm_with_offset, CR_ITM),
+
+
+#define __XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg)		\
+	{							\
+		xen_ ## name ## _direct_start,			\
+		xen_ ## name ## _direct_end,			\
+		PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \
+	}
+
+#define XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg)			\
+	__XEN_PATCH_BUNDLE_ELEM_SETREG(set_ ## name, reg)
+
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr0, AR_KR0),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr1, AR_KR1),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr2, AR_KR2),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr3, AR_KR3),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr4, AR_KR4),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr5, AR_KR5),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr6, AR_KR6),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(kr7, AR_KR7),
+
+	XEN_PATCH_BUNDLE_ELEM_SETREG(eflag, AR_EFLAG),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(tpr, CR_TPR),
+	__XEN_PATCH_BUNDLE_ELEM_SETREG(eoi, CR_EOI),
+
+	XEN_PATCH_BUNDLE_ELEM_SETREG(itc, AR_ITC),
+	XEN_PATCH_BUNDLE_ELEM_SETREG(itm_with_offset, CR_ITM),
+};
+
+static unsigned long __init_or_module
+xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type)
+{
+	const unsigned long nelems = sizeof(xen_patch_bundle_elems) /
+		sizeof(xen_patch_bundle_elems[0]);
+	unsigned long used;
+	const struct paravirt_patch_bundle_elem *found;
+
+	used = __paravirt_patch_apply_bundle(sbundle, ebundle, type,
+					     xen_patch_bundle_elems, nelems,
+					     &found);
+
+	if (found == NULL)
+		/* fallback */
+		return ia64_native_patch_bundle(sbundle, ebundle, type);
+	if (used == 0)
+		return used;
+
+	/* relocation */
+	switch (type) {
+	case PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE: {
+		unsigned long reloc =
+			__xen_intrin_local_irq_restore_direct_reloc;
+		unsigned long reloc_offset = reloc - (unsigned long)
+			__xen_intrin_local_irq_restore_direct_start;
+		unsigned long tag = (unsigned long)sbundle + reloc_offset;
+		paravirt_patch_reloc_brl(tag, xen_check_events);
+		break;
+	}
+	default:
+		/* nothing */
+		break;
+	}
+	return used;
+}
+#endif /* ASM_SUPPOTED */
+
+const struct paravirt_patch_branch_target xen_branch_target[]
+__initconst = {
+#define PARAVIRT_BR_TARGET(name, type)			\
+	{						\
+		&xen_ ## name,				\
+		PARAVIRT_PATCH_TYPE_BR_ ## type,	\
+	}
+	PARAVIRT_BR_TARGET(switch_to, SWITCH_TO),
+	PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL),
+	PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL),
+	PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL),
+};
+
+static void __init
+xen_patch_branch(unsigned long tag, unsigned long type)
+{
+	const unsigned long nelem =
+		sizeof(xen_branch_target) / sizeof(xen_branch_target[0]);
+	__paravirt_patch_apply_branch(tag, type, xen_branch_target, nelem);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/ia64/xen/xensetup.S linux-libre-2.6.30-gnu1/arch/ia64/xen/xensetup.S
--- linux-libre-2.6.29-gnu1/arch/ia64/xen/xensetup.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/ia64/xen/xensetup.S	2009-06-09 23:05:27.000000000 -0400
@@ -54,8 +54,6 @@ END(startup_xen)
 
 #define isBP	p3	// are we the Bootstrap Processor?
 
-	.text
-
 GLOBAL_ENTRY(xen_setup_hook)
 	mov r8=XEN_PV_DOMAIN_ASM
 (isBP)	movl r9=xen_domain_type;;
diff -druNp linux-libre-2.6.29-gnu1/arch/Kconfig linux-libre-2.6.30-gnu1/arch/Kconfig
--- linux-libre-2.6.29-gnu1/arch/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@ config OPROFILE
 	tristate "OProfile system profiling (EXPERIMENTAL)"
 	depends on PROFILING
 	depends on HAVE_OPROFILE
+	depends on TRACING_SUPPORT
 	select TRACING
 	select RING_BUFFER
 	help
@@ -106,3 +107,8 @@ config HAVE_CLK
 	  The <linux/clk.h> calls support software clock gating and
 	  thus are a key power management tool on many systems.
 
+config HAVE_DMA_API_DEBUG
+	bool
+
+config HAVE_DEFAULT_NO_SPIN_MUTEXES
+	bool
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/boot/compressed/Makefile linux-libre-2.6.30-gnu1/arch/m32r/boot/compressed/Makefile
--- linux-libre-2.6.29-gnu1/arch/m32r/boot/compressed/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/boot/compressed/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,6 @@
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \
 		   piggy.o vmlinux.lds
-EXTRA_AFLAGS	:= -traditional
 
 OBJECTS = $(obj)/head.o $(obj)/misc.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/addrspace.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/addrspace.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/addrspace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/addrspace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * 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) 2001 by Hiroyuki Kondo
+ *
+ * Defitions for the address spaces of the M32R CPUs.
+ */
+#ifndef __ASM_M32R_ADDRSPACE_H
+#define __ASM_M32R_ADDRSPACE_H
+
+/*
+ * Memory segments (32bit kernel mode addresses)
+ */
+#define KUSEG                   0x00000000
+#define KSEG0                   0x80000000
+#define KSEG1                   0xa0000000
+#define KSEG2                   0xc0000000
+#define KSEG3                   0xe0000000
+
+#define K0BASE  KSEG0
+
+/*
+ * Returns the kernel segment base of a given address
+ */
+#ifndef __ASSEMBLY__
+#define KSEGX(a)                (((unsigned long)(a)) & 0xe0000000)
+#else
+#define KSEGX(a)                ((a) & 0xe0000000)
+#endif
+
+/*
+ * Returns the physical address of a KSEG0/KSEG1 address
+ */
+#ifndef __ASSEMBLY__
+#define PHYSADDR(a)		(((unsigned long)(a)) & 0x1fffffff)
+#else
+#define PHYSADDR(a)		((a) & 0x1fffffff)
+#endif
+
+/*
+ * Map an address to a certain kernel segment
+ */
+#ifndef __ASSEMBLY__
+#define KSEG0ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0))
+#define KSEG1ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1))
+#define KSEG2ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2))
+#define KSEG3ADDR(a)		((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3))
+#else
+#define KSEG0ADDR(a)		(((a) & 0x1fffffff) | KSEG0)
+#define KSEG1ADDR(a)		(((a) & 0x1fffffff) | KSEG1)
+#define KSEG2ADDR(a)		(((a) & 0x1fffffff) | KSEG2)
+#define KSEG3ADDR(a)		(((a) & 0x1fffffff) | KSEG3)
+#endif
+
+#endif /* __ASM_M32R_ADDRSPACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/assembler.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/assembler.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/assembler.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/assembler.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,230 @@
+#ifndef _ASM_M32R_ASSEMBLER_H
+#define _ASM_M32R_ASSEMBLER_H
+
+/*
+ * linux/asm-m32r/assembler.h
+ *
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ *
+ * This file contains M32R architecture specific macro definitions.
+ */
+
+#include <linux/stringify.h>
+
+#undef __STR
+
+#ifdef __ASSEMBLY__
+#define __STR(x) x
+#else
+#define __STR(x) __stringify(x)
+#endif
+
+#ifdef CONFIG_SMP
+#define M32R_LOCK	__STR(lock)
+#define M32R_UNLOCK	__STR(unlock)
+#else
+#define M32R_LOCK	__STR(ld)
+#define M32R_UNLOCK	__STR(st)
+#endif
+
+#ifdef __ASSEMBLY__
+#undef ENTRY
+#define ENTRY(name) ENTRY_M name
+	.macro  ENTRY_M name
+	.global \name
+	ALIGN
+\name:
+	.endm
+#endif
+
+
+/**
+ * LDIMM - load immediate value
+ * STI - enable interruption
+ * CLI - disable interruption
+ */
+
+#ifdef __ASSEMBLY__
+
+#define LDIMM(reg,x) LDIMM reg x
+	.macro LDIMM reg x
+	seth	\reg, #high(\x)
+	or3	\reg, \reg, #low(\x)
+	.endm
+
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
+#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
+	.macro ENABLE_INTERRUPTS reg
+	setpsw  #0x40	    ->	nop
+	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
+	.endm
+
+#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
+	.macro DISABLE_INTERRUPTS reg
+	clrpsw  #0x40	    ->	nop
+	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
+	.endm
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
+	.macro ENABLE_INTERRUPTS reg
+	mvfc	\reg, psw
+	or3	\reg, \reg, #0x0040
+	mvtc	\reg, psw
+	.endm
+
+#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
+	.macro DISABLE_INTERRUPTS reg
+	mvfc	\reg, psw
+	and3	\reg, \reg, #0xffbf
+	mvtc	\reg, psw
+	.endm
+#endif	/* CONFIG_CHIP_M32102 */
+
+	.macro	SAVE_ALL
+	push	r0		; orig_r0
+	push	sp		; spi (r15)
+	push	lr		; r14
+	push	r13
+	mvfc	r13, cr3	; spu
+	push	r13
+	mvfc	r13, bbpc
+	push	r13
+	mvfc	r13, bbpsw
+	push	r13
+	mvfc	r13, bpc
+	push	r13
+	mvfc	r13, psw
+	push	r13
+#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
+	mvfaclo	r13, a1
+	push	r13
+	mvfachi r13, a1
+	push	r13
+	mvfaclo	r13, a0
+	push	r13
+	mvfachi	r13, a0
+	push	r13
+#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+	mvfaclo	r13
+	push	r13
+	mvfachi	r13
+	push	r13
+	ldi	r13, #0
+	push	r13		; dummy push acc1h
+	push	r13		; dummy push acc1l
+#else
+#error unknown isa configuration
+#endif
+	ldi	r13, #-1
+	push	r13		; syscall_nr (default: -1)
+	push	r12
+	push	r11
+	push	r10
+	push	r9
+	push	r8
+	push	r7
+	push	r3
+	push	r2
+	push	r1
+	push	r0
+	addi	sp, #-4		; room for implicit pt_regs parameter
+	push	r6
+	push	r5
+	push	r4
+	.endm
+
+	.macro	RESTORE_ALL
+	pop	r4
+	pop	r5
+	pop	r6
+	addi	sp, #4
+	pop	r0
+	pop	r1
+	pop	r2
+	pop	r3
+	pop	r7
+	pop	r8
+	pop	r9
+	pop	r10
+	pop	r11
+	pop	r12
+	addi	r15, #4		; Skip syscall number
+#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
+	pop	r13
+	mvtachi	r13, a0
+	pop	r13
+	mvtaclo	r13, a0
+	pop	r13
+	mvtachi	r13, a1
+	pop	r13
+	mvtaclo	r13, a1
+#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+	pop	r13		; dummy pop acc1h
+	pop	r13		; dummy pop acc1l
+	pop	r13
+	mvtachi	r13
+	pop	r13
+	mvtaclo	r13
+#else
+#error unknown isa configuration
+#endif
+	pop	r14
+	mvtc	r14, psw
+	pop	r14
+	mvtc	r14, bpc
+	addi	sp, #8		; Skip bbpsw, bbpc
+	pop	r14
+	mvtc	r14, cr3	; spu
+	pop	r13
+	pop	lr		; r14
+	pop	sp		; spi (r15)
+	addi	sp, #4		; Skip orig_r0
+	.fillinsn
+1:	rte
+	.section .fixup,"ax"
+2:	bl	do_exit
+	.previous
+	.section __ex_table,"a"
+	ALIGN
+	.long	1b, 2b
+	.previous
+	.endm
+
+#define GET_CURRENT(reg)  get_current reg
+	.macro get_current reg
+	ldi  \reg, #-8192
+	and  \reg, sp
+	.endm
+
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
+	.macro	SWITCH_TO_KERNEL_STACK
+	; switch to kernel stack (spi)
+	clrpsw	#0x80	    ->	nop
+	.endm
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+	.macro	SWITCH_TO_KERNEL_STACK
+	push	r0		; save r0 for working
+	mvfc	r0, psw
+	and3	r0, r0, #0x00ff7f
+	mvtc	r0, psw
+	slli	r0, #16
+	bltz	r0, 1f		; check BSM-bit
+;
+	;; called from kernel context: previous stack = spi
+	pop	r0		; retrieve r0
+	bra	2f
+	.fillinsn
+1:
+	;; called from user context: previous stack = spu
+	mvfc	r0, cr3		; spu
+	addi	r0, #4
+	mvtc	r0, cr3		; spu
+	ld	r0, @(-4,r0)	; retrieve r0
+	.fillinsn
+2:
+	.endm
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_M32R_ASSEMBLER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/atomic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,318 @@
+#ifndef _ASM_M32R_ATOMIC_H
+#define _ASM_M32R_ATOMIC_H
+
+/*
+ *  linux/include/asm-m32r/atomic.h
+ *
+ *  M32R version:
+ *    Copyright (C) 2001, 2002  Hitoshi Yamamoto
+ *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <linux/types.h>
+#include <asm/assembler.h>
+#include <asm/system.h>
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+#define atomic_read(v)	((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+#define atomic_set(v,i)	(((v)->counter) = (i))
+
+/**
+ * atomic_add_return - add integer to atomic variable and return it
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and return (@i + @v).
+ */
+static __inline__ int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_add_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"add	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (result)
+		: "r" (&v->counter), "r" (i)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * atomic_sub_return - subtract integer from atomic variable and return it
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and return (@v - @i).
+ */
+static __inline__ int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_sub_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"sub	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (result)
+		: "r" (&v->counter), "r" (i)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+#define atomic_add(i,v) ((void) atomic_add_return((i), (v)))
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+#define atomic_sub(i,v) ((void) atomic_sub_return((i), (v)))
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+
+/**
+ * atomic_inc_return - increment atomic variable and return it
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1 and returns the result.
+ */
+static __inline__ int atomic_inc_return(atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_inc_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"addi	%0, #1;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (result)
+		: "r" (&v->counter)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * atomic_dec_return - decrement atomic variable and return it
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and returns the result.
+ */
+static __inline__ int atomic_dec_return(atomic_t *v)
+{
+	unsigned long flags;
+	int result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_dec_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"addi	%0, #-1;		\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (result)
+		: "r" (&v->counter)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) ((void)atomic_inc_return(v))
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) ((void)atomic_dec_return(v))
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all
+ * other cases.
+ */
+#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)
+
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+	c = atomic_read(v);
+	for (;;) {
+		if (unlikely(c == (u)))
+			break;
+		old = atomic_cmpxchg((v), c, c + (a));
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != (u);
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+static __inline__ void atomic_clear_mask(unsigned long  mask, atomic_t *addr)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_clear_mask		\n\t"
+		DCACHE_CLEAR("%0", "r5", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"and	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (tmp)
+		: "r" (addr), "r" (~mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r5"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+static __inline__ void atomic_set_mask(unsigned long  mask, atomic_t *addr)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# atomic_set_mask		\n\t"
+		DCACHE_CLEAR("%0", "r5", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"or	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (tmp)
+		: "r" (addr), "r" (mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r5"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+/* Atomic operations are already serializing on m32r */
+#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()
+
+#include <asm-generic/atomic.h>
+#endif	/* _ASM_M32R_ATOMIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/auxvec.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/auxvec.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/auxvec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/auxvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef _ASM_M32R__AUXVEC_H
+#define _ASM_M32R__AUXVEC_H
+
+#endif  /* _ASM_M32R__AUXVEC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,275 @@
+#ifndef _ASM_M32R_BITOPS_H
+#define _ASM_M32R_BITOPS_H
+
+/*
+ *  linux/include/asm-m32r/bitops.h
+ *
+ *  Copyright 1992, Linus Torvalds.
+ *
+ *  M32R version:
+ *    Copyright (C) 2001, 2002  Hitoshi Yamamoto
+ *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <linux/compiler.h>
+#include <asm/assembler.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+#include <asm/types.h>
+
+/*
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.  See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+	__u32 mask;
+	volatile __u32 *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "r6", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"or	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (tmp)
+		: "r" (a), "r" (mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.  However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
+ */
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	__u32 mask;
+	volatile __u32 *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "r6", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"and	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (tmp)
+		: "r" (a), "r" (~mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+	__u32  mask;
+	volatile __u32  *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "r6", "%1")
+		M32R_LOCK" %0, @%1;		\n\t"
+		"xor	%0, %2;			\n\t"
+		M32R_UNLOCK" %0, @%1;		\n\t"
+		: "=&r" (tmp)
+		: "r" (a), "r" (mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+	__u32 mask, oldbit;
+	volatile __u32 *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "%1", "%2")
+		M32R_LOCK" %0, @%2;		\n\t"
+		"mv	%1, %0;			\n\t"
+		"and	%0, %3;			\n\t"
+		"or	%1, %3;			\n\t"
+		M32R_UNLOCK" %1, @%2;		\n\t"
+		: "=&r" (oldbit), "=&r" (tmp)
+		: "r" (a), "r" (mask)
+		: "memory"
+	);
+	local_irq_restore(flags);
+
+	return (oldbit != 0);
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+	__u32 mask, oldbit;
+	volatile __u32 *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "%1", "%3")
+		M32R_LOCK" %0, @%3;		\n\t"
+		"mv	%1, %0;			\n\t"
+		"and	%0, %2;			\n\t"
+		"not	%2, %2;			\n\t"
+		"and	%1, %2;			\n\t"
+		M32R_UNLOCK" %1, @%3;		\n\t"
+		: "=&r" (oldbit), "=&r" (tmp), "+r" (mask)
+		: "r" (a)
+		: "memory"
+	);
+	local_irq_restore(flags);
+
+	return (oldbit != 0);
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+	__u32 mask, oldbit;
+	volatile __u32 *a = addr;
+	unsigned long flags;
+	unsigned long tmp;
+
+	a += (nr >> 5);
+	mask = (1 << (nr & 0x1F));
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		DCACHE_CLEAR("%0", "%1", "%2")
+		M32R_LOCK" %0, @%2;		\n\t"
+		"mv	%1, %0;			\n\t"
+		"and	%0, %3;			\n\t"
+		"xor	%1, %3;			\n\t"
+		M32R_UNLOCK" %1, @%2;		\n\t"
+		: "=&r" (oldbit), "=&r" (tmp)
+		: "r" (a), "r" (mask)
+		: "memory"
+	);
+	local_irq_restore(flags);
+
+	return (oldbit != 0);
+}
+
+#include <asm-generic/bitops/non-atomic.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#endif /* __KERNEL__ */
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_M32R_BITOPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bug.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bug.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef _M32R_BUG_H
+#define _M32R_BUG_H
+#include <asm-generic/bug.h>
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bugs.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bugs.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/bugs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/bugs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#ifndef _ASM_M32R_BUGS_H
+#define _ASM_M32R_BUGS_H
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *     void check_bugs(void);
+ */
+#include <asm/processor.h>
+
+static void __init check_bugs(void)
+{
+	extern unsigned long loops_per_jiffy;
+
+	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
+}
+
+#endif  /* _ASM_M32R_BUGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/byteorder.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/byteorder.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/byteorder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/byteorder.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _ASM_M32R_BYTEORDER_H
+#define _ASM_M32R_BYTEORDER_H
+
+#if defined(__LITTLE_ENDIAN__)
+#  include <linux/byteorder/little_endian.h>
+#else
+#  include <linux/byteorder/big_endian.h>
+#endif
+
+#endif /* _ASM_M32R_BYTEORDER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cachectl.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cachectl.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cachectl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cachectl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * cachectl.h -- defines for M32R cache control system calls
+ *
+ * Copyright (C) 2003 by Kazuhiro Inaoka
+ */
+#ifndef	__ASM_M32R_CACHECTL
+#define	__ASM_M32R_CACHECTL
+
+/*
+ * Options for cacheflush system call
+ *
+ * cacheflush() is currently fluch_cache_all().
+ */
+#define	ICACHE	(1<<0)		/* flush instruction cache        */
+#define	DCACHE	(1<<1)		/* writeback and flush data cache */
+#define	BCACHE	(ICACHE|DCACHE)	/* flush both caches              */
+
+/*
+ * Caching modes for the cachectl(2) call
+ *
+ * cachectl(2) is currently not supported and returns ENOSYS.
+ */
+#define CACHEABLE	0	/* make pages cacheable */
+#define UNCACHEABLE	1	/* make pages uncacheable */
+
+#endif	/* __ASM_M32R_CACHECTL */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cacheflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+#ifndef _ASM_M32R_CACHEFLUSH_H
+#define _ASM_M32R_CACHEFLUSH_H
+
+#include <linux/mm.h>
+
+extern void _flush_cache_all(void);
+extern void _flush_cache_copyback_all(void);
+
+#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#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 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)
+#ifndef CONFIG_SMP
+#define flush_icache_range(start, end)		_flush_cache_copyback_all()
+#define flush_icache_page(vma,pg)		_flush_cache_copyback_all()
+#define flush_icache_user_range(vma,pg,adr,len)	_flush_cache_copyback_all()
+#define flush_cache_sigtramp(addr)		_flush_cache_copyback_all()
+#else	/* CONFIG_SMP */
+extern void smp_flush_cache_all(void);
+#define flush_icache_range(start, end)		smp_flush_cache_all()
+#define flush_icache_page(vma,pg)		smp_flush_cache_all()
+#define flush_icache_user_range(vma,pg,adr,len)	smp_flush_cache_all()
+#define flush_cache_sigtramp(addr)		_flush_cache_copyback_all()
+#endif	/* CONFIG_SMP */
+#elif defined(CONFIG_CHIP_M32102)
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#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 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, end)		_flush_cache_all()
+#define flush_icache_page(vma,pg)		_flush_cache_all()
+#define flush_icache_user_range(vma,pg,adr,len)	_flush_cache_all()
+#define flush_cache_sigtramp(addr)		_flush_cache_all()
+#else
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#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 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, end)		do { } while (0)
+#define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+#define flush_cache_sigtramp(addr)		do { } while (0)
+#endif	/* CONFIG_CHIP_* */
+
+#define flush_cache_vmap(start, end)	do { } while (0)
+#define flush_cache_vunmap(start, end)	do { } while (0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
+do {								\
+	memcpy(dst, src, len);					\
+	flush_icache_user_range(vma, page, vaddr, len);		\
+} while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
+	memcpy(dst, src, len)
+
+#endif /* _ASM_M32R_CACHEFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef _ASM_M32R_CACHE_H
+#define _ASM_M32R_CACHE_H
+
+/* L1 cache line size */
+#define L1_CACHE_SHIFT		4
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#endif  /* _ASM_M32R_CACHE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/checksum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,204 @@
+#ifdef __KERNEL__
+#ifndef _ASM_M32R_CHECKSUM_H
+#define _ASM_M32R_CHECKSUM_H
+
+/*
+ * include/asm-m32r/checksum.h
+ *
+ * IP/TCP/UDP checksum routines
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Some code taken from mips and parisc architecture.
+ *
+ *    Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata
+ *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <linux/in6.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
+ */
+asmlinkage __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
+ */
+extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
+                                              int len, __wsum sum);
+
+/*
+ * This is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros thre rest of the buffer.
+ */
+extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+                                                int len, __wsum sum,
+                                                int *err_ptr);
+
+/*
+ *	Fold a partial checksum
+ */
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+	unsigned long tmpreg;
+	__asm__(
+		"	sll3	%1, %0, #16 \n"
+		"	cmp	%0, %0 \n"
+		"	addx	%0, %1 \n"
+		"	ldi	%1, #0 \n"
+		"	srli	%0, #16 \n"
+		"	addx	%0, %1 \n"
+		"	xor3	%0, %0, #0x0000ffff \n"
+		: "=r" (sum), "=&r" (tmpreg)
+		: "0"  (sum)
+		: "cbit"
+	);
+	return (__force __sum16)sum;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	unsigned long tmpreg0, tmpreg1;
+	__wsum sum;
+
+	__asm__ __volatile__(
+		"	ld	%0, @%1+ \n"
+		"	addi	%2, #-4 \n"
+		"#	bgez	%2, 2f \n"
+		"	cmp	%0, %0 \n"
+		"	ld	%3, @%1+ \n"
+		"	ld	%4, @%1+ \n"
+		"	addx	%0, %3 \n"
+		"	ld	%3, @%1+ \n"
+		"	addx	%0, %4 \n"
+		"	addx	%0, %3 \n"
+		"	.fillinsn\n"
+		"1: \n"
+		"	ld	%4, @%1+ \n"
+		"	addi	%2, #-1 \n"
+		"	addx	%0, %4 \n"
+		"	bgtz	%2, 1b \n"
+		"\n"
+		"	ldi	%3, #0 \n"
+		"	addx	%0, %3 \n"
+		"	.fillinsn\n"
+		"2: \n"
+	/* Since the input registers which are loaded with iph and ihl
+	   are modified, we must also specify them as outputs, or gcc
+	   will assume they contain their original values. */
+	: "=&r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmpreg0), "=&r" (tmpreg1)
+	: "1" (iph), "2" (ihl)
+	: "cbit", "memory");
+
+	return csum_fold(sum);
+}
+
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+					       unsigned short len,
+					       unsigned short proto,
+					       __wsum sum)
+{
+#if defined(__LITTLE_ENDIAN)
+	unsigned long len_proto = (proto + len) << 8;
+#else
+	unsigned long len_proto = proto + len;
+#endif
+	unsigned long tmpreg;
+
+	__asm__(
+		"	cmp	%0, %0 \n"
+		"	addx	%0, %2 \n"
+		"	addx	%0, %3 \n"
+		"	addx	%0, %4 \n"
+		"	ldi	%1, #0 \n"
+		"	addx	%0, %1 \n"
+		: "=r" (sum), "=&r" (tmpreg)
+		: "r" (daddr), "r" (saddr), "r" (len_proto), "0" (sum)
+		: "cbit"
+	);
+
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+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
+ */
+
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+	return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+				      const struct in6_addr *daddr,
+				      __u32 len, unsigned short proto,
+				      __wsum sum)
+{
+	unsigned long tmpreg0, tmpreg1, tmpreg2, tmpreg3;
+	__asm__(
+		"	ld	%1, @(%5) \n"
+		"	ld	%2, @(4,%5) \n"
+		"	ld	%3, @(8,%5) \n"
+		"	ld	%4, @(12,%5) \n"
+		"	add	%0, %1 \n"
+		"	addx	%0, %2 \n"
+		"	addx	%0, %3 \n"
+		"	addx	%0, %4 \n"
+		"	ld	%1, @(%6) \n"
+		"	ld	%2, @(4,%6) \n"
+		"	ld	%3, @(8,%6) \n"
+		"	ld	%4, @(12,%6) \n"
+		"	addx	%0, %1 \n"
+		"	addx	%0, %2 \n"
+		"	addx	%0, %3 \n"
+		"	addx	%0, %4 \n"
+		"	addx	%0, %7 \n"
+		"	addx	%0, %8 \n"
+		"	ldi	%1, #0 \n"
+		"	addx	%0, %1 \n"
+		: "=&r" (sum), "=&r" (tmpreg0), "=&r" (tmpreg1),
+		  "=&r" (tmpreg2), "=&r" (tmpreg3)
+		: "r" (saddr), "r" (daddr),
+		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+		: "cbit"
+	);
+
+	return csum_fold(sum);
+}
+
+#endif /* _ASM_M32R_CHECKSUM_H */
+#endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cputime.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cputime.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/cputime.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/cputime.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __M32R_CPUTIME_H
+#define __M32R_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __M32R_CPUTIME_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/current.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/current.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+#ifndef _ASM_M32R_CURRENT_H
+#define _ASM_M32R_CURRENT_H
+
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static __inline__ struct task_struct *get_current(void)
+{
+	return current_thread_info()->task;
+}
+
+#define current	(get_current())
+
+#endif	/* _ASM_M32R_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/delay.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/delay.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/delay.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/delay.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+#ifndef _ASM_M32R_DELAY_H
+#define _ASM_M32R_DELAY_H
+
+/*
+ * Copyright (C) 1993 Linus Torvalds
+ *
+ * Delay routines calling functions in arch/m32r/lib/delay.c
+ */
+
+extern void __bad_udelay(void);
+extern void __bad_ndelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __ndelay(unsigned long nsecs);
+extern void __const_udelay(unsigned long xloops);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) (__builtin_constant_p(n) ? \
+	((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
+	__udelay(n))
+
+#define ndelay(n) (__builtin_constant_p(n) ? \
+	((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
+	__ndelay(n))
+
+#endif /* _ASM_M32R_DELAY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/device.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/device.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/div64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_M32R_DMA_H
+#define _ASM_M32R_DMA_H
+
+#include <asm/io.h>
+
+/*
+ * The maximum address that we can perform a DMA transfer
+ * to on this platform
+ */
+#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x20000000)
+
+#endif /* _ASM_M32R_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/elf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,134 @@
+#ifndef _ASM_M32R__ELF_H
+#define _ASM_M32R__ELF_H
+
+/*
+ * ELF-specific definitions.
+ *
+ * Copyright (C) 1999-2004, Renesas Technology Corp.
+ *      Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <asm/page.h>
+
+/* M32R relocation types  */
+#define	R_M32R_NONE		0
+#define	R_M32R_16		1
+#define	R_M32R_32		2
+#define	R_M32R_24		3
+#define	R_M32R_10_PCREL		4
+#define	R_M32R_18_PCREL		5
+#define	R_M32R_26_PCREL		6
+#define	R_M32R_HI16_ULO		7
+#define	R_M32R_HI16_SLO		8
+#define	R_M32R_LO16		9
+#define	R_M32R_SDA16		10
+#define	R_M32R_GNU_VTINHERIT	11
+#define	R_M32R_GNU_VTENTRY	12
+
+#define R_M32R_16_RELA		33
+#define R_M32R_32_RELA		34
+#define R_M32R_24_RELA		35
+#define R_M32R_10_PCREL_RELA	36
+#define R_M32R_18_PCREL_RELA	37
+#define R_M32R_26_PCREL_RELA	38
+#define R_M32R_HI16_ULO_RELA	39
+#define R_M32R_HI16_SLO_RELA	40
+#define R_M32R_LO16_RELA	41
+#define R_M32R_SDA16_RELA	42
+#define	R_M32R_RELA_GNU_VTINHERIT	43
+#define	R_M32R_RELA_GNU_VTENTRY	44
+
+#define R_M32R_GOT24		48
+#define R_M32R_26_PLTREL	49
+#define R_M32R_COPY		50
+#define R_M32R_GLOB_DAT		51
+#define R_M32R_JMP_SLOT		52
+#define R_M32R_RELATIVE		53
+#define R_M32R_GOTOFF		54
+#define R_M32R_GOTPC24		55
+#define R_M32R_GOT16_HI_ULO	56
+#define R_M32R_GOT16_HI_SLO	57
+#define R_M32R_GOT16_LO		58
+#define R_M32R_GOTPC_HI_ULO	59
+#define R_M32R_GOTPC_HI_SLO	60
+#define R_M32R_GOTPC_LO		61
+#define R_M32R_GOTOFF_HI_ULO	62
+#define R_M32R_GOTOFF_HI_SLO	63
+#define R_M32R_GOTOFF_LO	64
+
+#define R_M32R_NUM		256
+
+/*
+ * ELF register definitions..
+ */
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* We have no FP mumumu.  */
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) \
+	(((x)->e_machine == EM_M32R) || ((x)->e_machine == EM_CYGNUS_M32R))
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#if defined(__LITTLE_ENDIAN)
+#define ELF_DATA	ELFDATA2LSB
+#elif defined(__BIG_ENDIAN)
+#define ELF_DATA	ELFDATA2MSB
+#else
+#error no endian defined
+#endif
+#define ELF_ARCH	EM_M32R
+
+/* r0 is set by ld.so to a pointer to a function which might be
+ * registered using 'atexit'.  This provides a mean for the dynamic
+ * linker to call DT_FINI functions for shared libraries that have
+ * been loaded before the code runs.
+ *
+ * So that we can use the same startup file with static executables,
+ * we start programs with a value of 0 to indicate that there is no
+ * such function.
+ */
+#define ELF_PLAT_INIT(_r, load_addr)	(_r)->r0 = 0
+
+#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 use of this is to invoke "./ld.so someprog" to test out a
+ * new version of the loader.  We need to make sure that it is out of
+ * the way of the program that it will "exec", and that there is
+ * sufficient room for the brk.
+ */
+#define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
+
+/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
+   now struct_user_regs, they are different) */
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)  \
+	memcpy((char *)pr_reg, (char *)regs, sizeof (struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this CPU supports.  */
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+#define ELF_PLATFORM	(NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
+#endif  /* _ASM_M32R__ELF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/emergency-restart.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/emergency-restart.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/emergency-restart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/emergency-restart.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/errno.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/errno.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/errno.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/errno.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_ERRNO_H
+#define _ASM_M32R_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_M32R_ERRNO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/fb.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/fb.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+}
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/fcntl.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/fcntl.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/fcntl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/fcntl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/flat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ * include/asm-m32r/flat.h
+ *
+ * uClinux flat-format executables
+ *
+ * Copyright (C) 2004  Kazuhiro Inaoka
+ *
+ * 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 __ASM_M32R_FLAT_H
+#define __ASM_M32R_FLAT_H
+
+#define	flat_argvp_envp_on_stack()		0
+#define	flat_old_ram_flag(flags)		(flags)
+#define	flat_set_persistent(relval, p)		0
+#define	flat_reloc_valid(reloc, size)		\
+	(((reloc) - textlen_for_m32r_lo16_data) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
+	m32r_flat_get_addr_from_rp(rp, relval, (text_len) )
+
+#define flat_put_addr_at_rp(rp, addr, relval) \
+	m32r_flat_put_addr_at_rp(rp, addr, relval)
+
+/* Convert a relocation entry into an address.  */
+static inline unsigned long
+flat_get_relocate_addr (unsigned long relval)
+{
+        return relval & 0x00ffffff; /* Mask out top 8-bits */
+}
+
+#define	flat_m32r_get_reloc_type(relval)	((relval) >> 24)
+
+#define M32R_SETH_OPCODE	0xd0c00000 /* SETH instruction code */
+
+#define FLAT_M32R_32		0x00	/* 32bits reloc */
+#define FLAT_M32R_24		0x01	/* unsigned 24bits reloc */
+#define FLAT_M32R_16		0x02	/* 16bits reloc */
+#define FLAT_M32R_LO16		0x03	/* signed low 16bits reloc (low()) */
+#define FLAT_M32R_LO16_DATA	0x04	/* signed low 16bits reloc (low())
+					   for a symbol in .data section */
+					/* High 16bits of an address used
+					   when the lower 16bbits are treated
+					   as unsigned.
+                                           To create SETH instruction only.
+					   0x1X: X means a number of register.
+					   0x10 - 0x3F are reserved. */
+#define FLAT_M32R_HI16_ULO	0x10	/* reloc for SETH Rn,#high(imm16) */
+					/* High 16bits of an address used
+					   when the lower 16bbits are treated
+					   as signed.
+                                           To create SETH instruction only.
+					   0x2X: X means a number of register.
+					   0x20 - 0x4F are reserved. */
+#define FLAT_M32R_HI16_SLO	0x20	/* reloc for SETH Rn,#shigh(imm16) */
+
+static unsigned long textlen_for_m32r_lo16_data = 0;
+
+static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp,
+                                                        unsigned long relval,
+						        unsigned long textlen)
+{
+        unsigned int reloc = flat_m32r_get_reloc_type (relval);
+	textlen_for_m32r_lo16_data = 0;
+	if (reloc & 0xf0) {
+		unsigned long addr = htonl(*rp);
+		switch (reloc & 0xf0)
+		{
+		case FLAT_M32R_HI16_ULO:
+		case FLAT_M32R_HI16_SLO:
+			if (addr == 0) {
+				/* put "seth Rn,#0x0" instead of 0 (addr). */
+				*rp = (M32R_SETH_OPCODE | ((reloc & 0x0f)<<24));
+			}
+			return addr;
+		default:
+			break;
+		}
+	} else {
+		switch (reloc)
+		{
+		case FLAT_M32R_LO16:
+			return htonl(*rp) & 0xFFFF;
+		case FLAT_M32R_LO16_DATA:
+                        /* FIXME: The return value will decrease by textlen
+			   at m32r_flat_put_addr_at_rp () */
+			textlen_for_m32r_lo16_data = textlen;
+			return (htonl(*rp) & 0xFFFF) + textlen;
+		case FLAT_M32R_16:
+			return htons(*(unsigned short *)rp) & 0xFFFF;
+		case FLAT_M32R_24:
+			return htonl(*rp) & 0xFFFFFF;
+		case FLAT_M32R_32:
+			return htonl(*rp);
+		default:
+			break;
+		}
+	}
+	return ~0;      /* bogus value */
+}
+
+static inline void m32r_flat_put_addr_at_rp (unsigned long *rp,
+					     unsigned long addr,
+                                             unsigned long relval)
+{
+        unsigned int reloc = flat_m32r_get_reloc_type (relval);
+	if (reloc & 0xf0) {
+		unsigned long Rn = reloc & 0x0f; /* get a number of register */
+		Rn <<= 24; /* 0x0R000000 */
+		reloc &= 0xf0;
+		switch (reloc)
+		{
+		case FLAT_M32R_HI16_ULO: /* To create SETH Rn,#high(imm16) */
+			*rp = (M32R_SETH_OPCODE | Rn
+			       | ((addr >> 16) & 0xFFFF));
+			break;
+		case FLAT_M32R_HI16_SLO: /* To create SETH Rn,#shigh(imm16) */
+			*rp = (M32R_SETH_OPCODE | Rn
+			       | (((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
+				  & 0xFFFF));
+			break;
+		}
+	} else {
+		switch (reloc) {
+		case FLAT_M32R_LO16_DATA:
+			addr -= textlen_for_m32r_lo16_data;
+			textlen_for_m32r_lo16_data = 0;
+		case FLAT_M32R_LO16:
+			*rp = (htonl(*rp) & 0xFFFF0000) | (addr & 0xFFFF);
+			break;
+		case FLAT_M32R_16:
+			*(unsigned short *)rp = addr & 0xFFFF;
+			break;
+		case FLAT_M32R_24:
+			*rp = (htonl(*rp) & 0xFF000000) | (addr & 0xFFFFFF);
+			break;
+		case FLAT_M32R_32:
+			*rp = addr;
+			break;
+		}
+	}
+}
+
+#endif /* __ASM_M32R_FLAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/futex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/hardirq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+#ifdef __KERNEL__
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+#if NR_IRQS > 256
+#define HARDIRQ_BITS	9
+#else
+#define HARDIRQ_BITS	8
+#endif
+
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+static inline void ack_bad_irq(int irq)
+{
+	printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
+	BUG();
+}
+
+#endif /* __ASM_HARDIRQ_H */
+#endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/hw_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef _ASM_M32R_HW_IRQ_H
+#define _ASM_M32R_HW_IRQ_H
+
+#endif /* _ASM_M32R_HW_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ioctl.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ioctl.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ioctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ioctls.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ioctls.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ioctls.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ioctls.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,87 @@
+#ifndef __ARCH_M32R_IOCTLS_H__
+#define __ARCH_M32R_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TCGETS2		_IOR('T',0x2A, struct termios2)
+#define TCSETS2		_IOW('T',0x2B, struct termios2)
+#define TCSETSW2	_IOW('T',0x2C, struct termios2)
+#define TCSETSF2	_IOW('T',0x2D, struct termios2)
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* __ARCH_M32R_IOCTLS_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/io.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,200 @@
+#ifndef _ASM_M32R_IO_H
+#define _ASM_M32R_IO_H
+
+#include <linux/string.h>
+#include <linux/compiler.h>
+#include <asm/page.h>  /* __va */
+
+#ifdef __KERNEL__
+
+#define IO_SPACE_LIMIT  0xFFFFFFFF
+
+/**
+ *	virt_to_phys	-	map virtual addresses to physical
+ *	@address: address to remap
+ *
+ *	The returned physical address is the physical (CPU) mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses directly mapped or allocated via kmalloc.
+ *
+ *	This function does not give bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+
+static inline unsigned long virt_to_phys(volatile void * address)
+{
+	return __pa(address);
+}
+
+/**
+ *	phys_to_virt	-	map physical address to virtual
+ *	@address: address to remap
+ *
+ *	The returned virtual address is a current CPU mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses that have a kernel mapping
+ *
+ *	This function does not handle bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+
+static inline void *phys_to_virt(unsigned long address)
+{
+	return __va(address);
+}
+
+extern void __iomem *
+__ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+/**
+ *	ioremap		-	map bus memory into CPU space
+ *	@offset:	bus address of the memory
+ *	@size:		size of the resource to map
+ *
+ *	ioremap performs a platform specific sequence of operations to
+ *	make bus memory CPU accessible via the readb/readw/readl/writeb/
+ *	writew/writel functions and the other mmio helpers. The returned
+ *	address is not guaranteed to be usable directly as a virtual
+ *	address.
+ */
+
+static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+extern void iounmap(volatile void __iomem *addr);
+#define ioremap_nocache(off,size) ioremap(off,size)
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+#define page_to_bus	page_to_phys
+#define virt_to_bus	virt_to_phys
+
+extern unsigned char _inb(unsigned long);
+extern unsigned short _inw(unsigned long);
+extern unsigned long _inl(unsigned long);
+extern unsigned char _inb_p(unsigned long);
+extern unsigned short _inw_p(unsigned long);
+extern unsigned long _inl_p(unsigned long);
+extern void _outb(unsigned char, unsigned long);
+extern void _outw(unsigned short, unsigned long);
+extern void _outl(unsigned long, unsigned long);
+extern void _outb_p(unsigned char, unsigned long);
+extern void _outw_p(unsigned short, unsigned long);
+extern void _outl_p(unsigned long, unsigned long);
+extern void _insb(unsigned int, void *, unsigned long);
+extern void _insw(unsigned int, void *, unsigned long);
+extern void _insl(unsigned int, void *, unsigned long);
+extern void _outsb(unsigned int, const void *, unsigned long);
+extern void _outsw(unsigned int, const void *, unsigned long);
+extern void _outsl(unsigned int, const void *, unsigned long);
+
+static inline unsigned char _readb(unsigned long addr)
+{
+	return *(volatile unsigned char __force *)addr;
+}
+
+static inline unsigned short _readw(unsigned long addr)
+{
+	return *(volatile unsigned short __force *)addr;
+}
+
+static inline unsigned long _readl(unsigned long addr)
+{
+	return *(volatile unsigned long __force *)addr;
+}
+
+static inline void _writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char __force *)addr = b;
+}
+
+static inline void _writew(unsigned short w, unsigned long addr)
+{
+	*(volatile unsigned short __force *)addr = w;
+}
+
+static inline void _writel(unsigned long l, unsigned long addr)
+{
+	*(volatile unsigned long __force *)addr = l;
+}
+
+#define inb     _inb
+#define inw     _inw
+#define inl     _inl
+#define outb    _outb
+#define outw    _outw
+#define outl    _outl
+
+#define inb_p   _inb_p
+#define inw_p   _inw_p
+#define inl_p   _inl_p
+#define outb_p  _outb_p
+#define outw_p  _outw_p
+#define outl_p  _outl_p
+
+#define insb    _insb
+#define insw    _insw
+#define insl    _insl
+#define outsb   _outsb
+#define outsw   _outsw
+#define outsl   _outsl
+
+#define readb(addr)   _readb((unsigned long)(addr))
+#define readw(addr)   _readw((unsigned long)(addr))
+#define readl(addr)   _readl((unsigned long)(addr))
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
+#define writeb(val, addr)  _writeb((val), (unsigned long)(addr))
+#define writew(val, addr)  _writew((val), (unsigned long)(addr))
+#define writel(val, addr)  _writel((val), (unsigned long)(addr))
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+#define mmiowb()
+
+#define flush_write_buffers() do { } while (0)  /* M32R_FIXME */
+
+static inline void
+memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+	memset((void __force *) addr, val, count);
+}
+
+static inline void
+memcpy_fromio(void *dst, volatile void __iomem *src, int count)
+{
+	memcpy(dst, (void __force *) src, count);
+}
+
+static inline void
+memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+	memcpy((void __force *) dst, src, count);
+}
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+#endif  /* __KERNEL__ */
+
+#endif  /* _ASM_M32R_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ipcbuf.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ipcbuf.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ipcbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ipcbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+#ifndef _ASM_M32R_IPCBUF_H
+#define _ASM_M32R_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for m32r architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* _ASM_M32R_IPCBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,90 @@
+#ifdef __KERNEL__
+#ifndef _ASM_M32R_IRQ_H
+#define _ASM_M32R_IRQ_H
+
+
+#if defined(CONFIG_PLAT_USRV)
+/*
+ * IRQ definitions for M32700UT
+ *  M32700 Chip: 64 interrupts
+ *  ICU of M32700UT-on-board PLD: 32 interrupts cascaded to INT1# chip pin
+ */
+#define	M32700UT_NUM_CPU_IRQ	(64)
+#define M32700UT_NUM_PLD_IRQ	(32)
+#define M32700UT_IRQ_BASE	0
+#define M32700UT_CPU_IRQ_BASE	M32700UT_IRQ_BASE
+#define M32700UT_PLD_IRQ_BASE	(M32700UT_CPU_IRQ_BASE + M32700UT_NUM_CPU_IRQ)
+
+#define NR_IRQS	(M32700UT_NUM_CPU_IRQ + M32700UT_NUM_PLD_IRQ)
+#elif defined(CONFIG_PLAT_M32700UT)
+/*
+ * IRQ definitions for M32700UT(Rev.C) + M32R-LAN
+ *  M32700 Chip: 64 interrupts
+ *  ICU of M32700UT-on-board PLD: 32 interrupts cascaded to INT1# chip pin
+ *  ICU of M32R-LCD-on-board PLD: 32 interrupts cascaded to INT2# chip pin
+ *  ICU of M32R-LAN-on-board PLD: 32 interrupts cascaded to INT0# chip pin
+ */
+#define M32700UT_NUM_CPU_IRQ		(64)
+#define M32700UT_NUM_PLD_IRQ		(32)
+#define M32700UT_NUM_LCD_PLD_IRQ	(32)
+#define M32700UT_NUM_LAN_PLD_IRQ	(32)
+#define M32700UT_IRQ_BASE		0
+#define M32700UT_CPU_IRQ_BASE		(M32700UT_IRQ_BASE)
+#define M32700UT_PLD_IRQ_BASE \
+	(M32700UT_CPU_IRQ_BASE + M32700UT_NUM_CPU_IRQ)
+#define M32700UT_LCD_PLD_IRQ_BASE \
+	(M32700UT_PLD_IRQ_BASE + M32700UT_NUM_PLD_IRQ)
+#define M32700UT_LAN_PLD_IRQ_BASE \
+	(M32700UT_LCD_PLD_IRQ_BASE + M32700UT_NUM_LCD_PLD_IRQ)
+
+#define NR_IRQS \
+	(M32700UT_NUM_CPU_IRQ + M32700UT_NUM_PLD_IRQ \
+	+ M32700UT_NUM_LCD_PLD_IRQ + M32700UT_NUM_LAN_PLD_IRQ)
+#elif defined(CONFIG_PLAT_OPSPUT)
+/*
+ * IRQ definitions for OPSPUT + M32R-LAN
+ *  OPSP Chip: 64 interrupts
+ *  ICU of OPSPUT-on-board PLD: 32 interrupts cascaded to INT1# chip pin
+ *  ICU of M32R-LCD-on-board PLD: 32 interrupts cascaded to INT2# chip pin
+ *  ICU of M32R-LAN-on-board PLD: 32 interrupts cascaded to INT0# chip pin
+ */
+#define OPSPUT_NUM_CPU_IRQ		(64)
+#define OPSPUT_NUM_PLD_IRQ		(32)
+#define OPSPUT_NUM_LCD_PLD_IRQ	(32)
+#define OPSPUT_NUM_LAN_PLD_IRQ	(32)
+#define OPSPUT_IRQ_BASE		0
+#define OPSPUT_CPU_IRQ_BASE		(OPSPUT_IRQ_BASE)
+#define OPSPUT_PLD_IRQ_BASE \
+	(OPSPUT_CPU_IRQ_BASE + OPSPUT_NUM_CPU_IRQ)
+#define OPSPUT_LCD_PLD_IRQ_BASE \
+	(OPSPUT_PLD_IRQ_BASE + OPSPUT_NUM_PLD_IRQ)
+#define OPSPUT_LAN_PLD_IRQ_BASE \
+	(OPSPUT_LCD_PLD_IRQ_BASE + OPSPUT_NUM_LCD_PLD_IRQ)
+
+#define NR_IRQS \
+	(OPSPUT_NUM_CPU_IRQ + OPSPUT_NUM_PLD_IRQ \
+	+ OPSPUT_NUM_LCD_PLD_IRQ + OPSPUT_NUM_LAN_PLD_IRQ)
+
+#elif defined(CONFIG_PLAT_M32104UT)
+/*
+ * IRQ definitions for M32104UT
+ *  M32104 Chip: 64 interrupts
+ *  ICU of M32104UT-on-board PLD: 32 interrupts cascaded to INT1# chip pin
+ */
+#define	M32104UT_NUM_CPU_IRQ	(64)
+#define M32104UT_NUM_PLD_IRQ	(32)
+#define M32104UT_IRQ_BASE	0
+#define M32104UT_CPU_IRQ_BASE	M32104UT_IRQ_BASE
+#define M32104UT_PLD_IRQ_BASE	(M32104UT_CPU_IRQ_BASE + M32104UT_NUM_CPU_IRQ)
+
+#define NR_IRQS	\
+    (M32104UT_NUM_CPU_IRQ + M32104UT_NUM_PLD_IRQ)
+
+#else
+#define NR_IRQS	64
+#endif
+
+#define irq_canonicalize(irq)	(irq)
+
+#endif /* _ASM_M32R_IRQ_H */
+#endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/irq_regs.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/irq_regs.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/irq_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/irq_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/Kbuild linux-libre-2.6.30-gnu1/arch/m32r/include/asm/Kbuild
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/Kbuild	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/Kbuild	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/kdebug.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/kdebug.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/kdebug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/kdebug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/kmap_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+#ifndef __M32R_KMAP_TYPES_H
+#define __M32R_KMAP_TYPES_H
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+# define D(n) __KM_FENCE_##n ,
+#else
+# define D(n)
+#endif
+
+enum km_type {
+D(0)	KM_BOUNCE_READ,
+D(1)	KM_SKB_SUNRPC_DATA,
+D(2)	KM_SKB_DATA_SOFTIRQ,
+D(3)	KM_USER0,
+D(4)	KM_USER1,
+D(5)	KM_BIO_SRC_IRQ,
+D(6)	KM_BIO_DST_IRQ,
+D(7)	KM_PTE0,
+D(8)	KM_PTE1,
+D(9)	KM_IRQ0,
+D(10)	KM_IRQ1,
+D(11)	KM_SOFTIRQ0,
+D(12)	KM_SOFTIRQ1,
+D(13)	KM_TYPE_NR
+};
+
+#undef D
+
+#endif /* __M32R_KMAP_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/linkage.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/linkage.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/linkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN		.balign 4
+#define __ALIGN_STR	".balign 4"
+
+#endif /* __ASM_LINKAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/local.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/local.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/local.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/local.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,366 @@
+#ifndef __M32R_LOCAL_H
+#define __M32R_LOCAL_H
+
+/*
+ *  linux/include/asm-m32r/local.h
+ *
+ *  M32R version:
+ *    Copyright (C) 2001, 2002  Hitoshi Yamamoto
+ *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ *    Copyright (C) 2007  Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#include <linux/percpu.h>
+#include <asm/assembler.h>
+#include <asm/system.h>
+#include <asm/local.h>
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+typedef struct { volatile int counter; } local_t;
+
+#define LOCAL_INIT(i)	{ (i) }
+
+/**
+ * local_read - read local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically reads the value of @l.
+ */
+#define local_read(l)	((l)->counter)
+
+/**
+ * local_set - set local variable
+ * @l: pointer of type local_t
+ * @i: required value
+ *
+ * Atomically sets the value of @l to @i.
+ */
+#define local_set(l, i)	(((l)->counter) = (i))
+
+/**
+ * local_add_return - add long to local variable and return it
+ * @i: long value to add
+ * @l: pointer of type local_t
+ *
+ * Atomically adds @i to @l and return (@i + @l).
+ */
+static inline long local_add_return(long i, local_t *l)
+{
+	unsigned long flags;
+	long result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_add_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		"ld %0, @%1;			\n\t"
+		"add	%0, %2;			\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (result)
+		: "r" (&l->counter), "r" (i)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * local_sub_return - subtract long from local variable and return it
+ * @i: long value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and return (@l - @i).
+ */
+static inline long local_sub_return(long i, local_t *l)
+{
+	unsigned long flags;
+	long result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_sub_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		"ld %0, @%1;			\n\t"
+		"sub	%0, %2;			\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (result)
+		: "r" (&l->counter), "r" (i)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * local_add - add long to local variable
+ * @i: long value to add
+ * @l: pointer of type local_t
+ *
+ * Atomically adds @i to @l.
+ */
+#define local_add(i, l) ((void) local_add_return((i), (l)))
+
+/**
+ * local_sub - subtract the local variable
+ * @i: long value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l.
+ */
+#define local_sub(i, l) ((void) local_sub_return((i), (l)))
+
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_sub_and_test(i, l) (local_sub_return((i), (l)) == 0)
+
+/**
+ * local_inc_return - increment local variable and return it
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1 and returns the result.
+ */
+static inline long local_inc_return(local_t *l)
+{
+	unsigned long flags;
+	long result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_inc_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		"ld %0, @%1;			\n\t"
+		"addi	%0, #1;			\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (result)
+		: "r" (&l->counter)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * local_dec_return - decrement local variable and return it
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and returns the result.
+ */
+static inline long local_dec_return(local_t *l)
+{
+	unsigned long flags;
+	long result;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_dec_return		\n\t"
+		DCACHE_CLEAR("%0", "r4", "%1")
+		"ld %0, @%1;			\n\t"
+		"addi	%0, #-1;		\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (result)
+		: "r" (&l->counter)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+
+	return result;
+}
+
+/**
+ * local_inc - increment local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1.
+ */
+#define local_inc(l) ((void)local_inc_return(l))
+
+/**
+ * local_dec - decrement local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1.
+ */
+#define local_dec(l) ((void)local_dec_return(l))
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all
+ * other cases.
+ */
+#define local_dec_and_test(l) (local_dec_return(l) == 0)
+
+/**
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define local_add_negative(i, l) (local_add_return((i), (l)) < 0)
+
+#define local_cmpxchg(l, o, n) (cmpxchg_local(&((l)->counter), (o), (n)))
+#define local_xchg(v, new) (xchg_local(&((l)->counter), new))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+static inline int local_add_unless(local_t *l, long a, long u)
+{
+	long c, old;
+	c = local_read(l);
+	for (;;) {
+		if (unlikely(c == (u)))
+			break;
+		old = local_cmpxchg((l), c, c + (a));
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != (u);
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+static inline void local_clear_mask(unsigned long  mask, local_t *addr)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_clear_mask		\n\t"
+		DCACHE_CLEAR("%0", "r5", "%1")
+		"ld %0, @%1;			\n\t"
+		"and	%0, %2;			\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (tmp)
+		: "r" (addr), "r" (~mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r5"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+static inline void local_set_mask(unsigned long  mask, local_t *addr)
+{
+	unsigned long flags;
+	unsigned long tmp;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+		"# local_set_mask		\n\t"
+		DCACHE_CLEAR("%0", "r5", "%1")
+		"ld %0, @%1;			\n\t"
+		"or	%0, %2;			\n\t"
+		"st %0, @%1;			\n\t"
+		: "=&r" (tmp)
+		: "r" (addr), "r" (mask)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r5"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+	local_irq_restore(flags);
+}
+
+/* Atomic operations are already serializing on m32r */
+#define smp_mb__before_local_dec()	barrier()
+#define smp_mb__after_local_dec()	barrier()
+#define smp_mb__before_local_inc()	barrier()
+#define smp_mb__after_local_inc()	barrier()
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations.  Note they take
+ * a variable, not an address.
+ */
+
+#define __local_inc(l)		((l)->a.counter++)
+#define __local_dec(l)		((l)->a.counter++)
+#define __local_add(i, l)	((l)->a.counter += (i))
+#define __local_sub(i, l)	((l)->a.counter -= (i))
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations.  Note they take
+ * a variable, not an address.
+ */
+
+/* Need to disable preemption for the cpu local counters otherwise we could
+   still access a variable of a previous CPU in a non local way. */
+#define cpu_local_wrap_v(l)	 	\
+	({ local_t res__;		\
+	   preempt_disable(); 		\
+	   res__ = (l);			\
+	   preempt_enable();		\
+	   res__; })
+#define cpu_local_wrap(l)		\
+	({ preempt_disable();		\
+	   l;				\
+	   preempt_enable(); })		\
+
+#define cpu_local_read(l)    cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i)  cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l)     cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l)     cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l)  cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l)  cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l)	cpu_local_inc(l)
+#define __cpu_local_dec(l)	cpu_local_dec(l)
+#define __cpu_local_add(i, l)	cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l)	cpu_local_sub((i), (l))
+
+#endif /* __M32R_LOCAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32102.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32102.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32102.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32102.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,314 @@
+#ifndef _M32102_H_
+#define _M32102_H_
+
+/*
+ * Renesas M32R 32102 group
+ *
+ * Copyright (c) 2001  Hitoshi Yamamoto
+ * Copyright (c) 2003, 2004  Renesas Technology Corp.
+ */
+
+/*======================================================================*
+ * Special Function Register
+ *======================================================================*/
+#if !defined(CONFIG_CHIP_M32104)
+#define M32R_SFR_OFFSET  (0x00E00000)  /* 0x00E00000-0x00EFFFFF 1[MB] */
+#else
+#define M32R_SFR_OFFSET  (0x00700000)  /* 0x00700000-0x007FFFFF 1[MB] */
+#endif
+
+/*
+ * Clock and Power Management registers.
+ */
+#define M32R_CPM_OFFSET          (0x000F4000+M32R_SFR_OFFSET)
+
+#define M32R_CPM_CPUCLKCR_PORTL  (0x00+M32R_CPM_OFFSET)
+#define M32R_CPM_CLKMOD_PORTL    (0x04+M32R_CPM_OFFSET)
+#define M32R_CPM_PLLCR_PORTL     (0x08+M32R_CPM_OFFSET)
+
+/*
+ * DMA Controller registers.
+ */
+#define M32R_DMA_OFFSET		(0x000F8000+M32R_SFR_OFFSET)
+
+#define M32R_DMAEN_PORTL	(0x000+M32R_DMA_OFFSET)
+#define M32R_DMAISTS_PORTL	(0x004+M32R_DMA_OFFSET)
+#define M32R_DMAEDET_PORTL	(0x008+M32R_DMA_OFFSET)
+#define M32R_DMAASTS_PORTL	(0x00c+M32R_DMA_OFFSET)
+
+#define M32R_DMA0CR0_PORTL	(0x100+M32R_DMA_OFFSET)
+#define M32R_DMA0CR1_PORTL	(0x104+M32R_DMA_OFFSET)
+#define M32R_DMA0CSA_PORTL	(0x108+M32R_DMA_OFFSET)
+#define M32R_DMA0RSA_PORTL	(0x10c+M32R_DMA_OFFSET)
+#define M32R_DMA0CDA_PORTL	(0x110+M32R_DMA_OFFSET)
+#define M32R_DMA0RDA_PORTL	(0x114+M32R_DMA_OFFSET)
+#define M32R_DMA0CBCUT_PORTL	(0x118+M32R_DMA_OFFSET)
+#define M32R_DMA0RBCUT_PORTL	(0x11c+M32R_DMA_OFFSET)
+
+#define M32R_DMA1CR0_PORTL	(0x200+M32R_DMA_OFFSET)
+#define M32R_DMA1CR1_PORTL	(0x204+M32R_DMA_OFFSET)
+#define M32R_DMA1CSA_PORTL	(0x208+M32R_DMA_OFFSET)
+#define M32R_DMA1RSA_PORTL	(0x20c+M32R_DMA_OFFSET)
+#define M32R_DMA1CDA_PORTL	(0x210+M32R_DMA_OFFSET)
+#define M32R_DMA1RDA_PORTL	(0x214+M32R_DMA_OFFSET)
+#define M32R_DMA1CBCUT_PORTL	(0x218+M32R_DMA_OFFSET)
+#define M32R_DMA1RBCUT_PORTL	(0x21c+M32R_DMA_OFFSET)
+
+/*
+ * Multi Function Timer registers.
+ */
+#define M32R_MFT_OFFSET        (0x000FC000+M32R_SFR_OFFSET)
+
+#define M32R_MFTCR_PORTL       (0x000+M32R_MFT_OFFSET)  /* MFT control */
+#define M32R_MFTRPR_PORTL      (0x004+M32R_MFT_OFFSET)  /* MFT real port */
+
+#define M32R_MFT0_OFFSET       (0x100+M32R_MFT_OFFSET)
+#define M32R_MFT0MOD_PORTL     (0x00+M32R_MFT0_OFFSET)  /* MFT0 mode */
+#define M32R_MFT0BOS_PORTL     (0x04+M32R_MFT0_OFFSET)  /* MFT0 b-port output status */
+#define M32R_MFT0CUT_PORTL     (0x08+M32R_MFT0_OFFSET)  /* MFT0 count */
+#define M32R_MFT0RLD_PORTL     (0x0C+M32R_MFT0_OFFSET)  /* MFT0 reload */
+#define M32R_MFT0CMPRLD_PORTL  (0x10+M32R_MFT0_OFFSET)  /* MFT0 compare reload */
+
+#define M32R_MFT1_OFFSET       (0x200+M32R_MFT_OFFSET)
+#define M32R_MFT1MOD_PORTL     (0x00+M32R_MFT1_OFFSET)  /* MFT1 mode */
+#define M32R_MFT1BOS_PORTL     (0x04+M32R_MFT1_OFFSET)  /* MFT1 b-port output status */
+#define M32R_MFT1CUT_PORTL     (0x08+M32R_MFT1_OFFSET)  /* MFT1 count */
+#define M32R_MFT1RLD_PORTL     (0x0C+M32R_MFT1_OFFSET)  /* MFT1 reload */
+#define M32R_MFT1CMPRLD_PORTL  (0x10+M32R_MFT1_OFFSET)  /* MFT1 compare reload */
+
+#define M32R_MFT2_OFFSET       (0x300+M32R_MFT_OFFSET)
+#define M32R_MFT2MOD_PORTL     (0x00+M32R_MFT2_OFFSET)  /* MFT2 mode */
+#define M32R_MFT2BOS_PORTL     (0x04+M32R_MFT2_OFFSET)  /* MFT2 b-port output status */
+#define M32R_MFT2CUT_PORTL     (0x08+M32R_MFT2_OFFSET)  /* MFT2 count */
+#define M32R_MFT2RLD_PORTL     (0x0C+M32R_MFT2_OFFSET)  /* MFT2 reload */
+#define M32R_MFT2CMPRLD_PORTL  (0x10+M32R_MFT2_OFFSET)  /* MFT2 compare reload */
+
+#define M32R_MFT3_OFFSET       (0x400+M32R_MFT_OFFSET)
+#define M32R_MFT3MOD_PORTL     (0x00+M32R_MFT3_OFFSET)  /* MFT3 mode */
+#define M32R_MFT3BOS_PORTL     (0x04+M32R_MFT3_OFFSET)  /* MFT3 b-port output status */
+#define M32R_MFT3CUT_PORTL     (0x08+M32R_MFT3_OFFSET)  /* MFT3 count */
+#define M32R_MFT3RLD_PORTL     (0x0C+M32R_MFT3_OFFSET)  /* MFT3 reload */
+#define M32R_MFT3CMPRLD_PORTL  (0x10+M32R_MFT3_OFFSET)  /* MFT3 compare reload */
+
+#define M32R_MFT4_OFFSET       (0x500+M32R_MFT_OFFSET)
+#define M32R_MFT4MOD_PORTL     (0x00+M32R_MFT4_OFFSET)  /* MFT4 mode */
+#define M32R_MFT4BOS_PORTL     (0x04+M32R_MFT4_OFFSET)  /* MFT4 b-port output status */
+#define M32R_MFT4CUT_PORTL     (0x08+M32R_MFT4_OFFSET)  /* MFT4 count */
+#define M32R_MFT4RLD_PORTL     (0x0C+M32R_MFT4_OFFSET)  /* MFT4 reload */
+#define M32R_MFT4CMPRLD_PORTL  (0x10+M32R_MFT4_OFFSET)  /* MFT4 compare reload */
+
+#define M32R_MFT5_OFFSET       (0x600+M32R_MFT_OFFSET)
+#define M32R_MFT5MOD_PORTL     (0x00+M32R_MFT5_OFFSET)  /* MFT4 mode */
+#define M32R_MFT5BOS_PORTL     (0x04+M32R_MFT5_OFFSET)  /* MFT4 b-port output status */
+#define M32R_MFT5CUT_PORTL     (0x08+M32R_MFT5_OFFSET)  /* MFT4 count */
+#define M32R_MFT5RLD_PORTL     (0x0C+M32R_MFT5_OFFSET)  /* MFT4 reload */
+#define M32R_MFT5CMPRLD_PORTL  (0x10+M32R_MFT5_OFFSET)  /* MFT4 compare reload */
+
+#if (defined(CONFIG_CHIP_M32700) && !defined(CONFIG_PLAT_MAPPI2)) \
+	|| defined(CONFIG_CHIP_M32104)
+#define M32R_MFTCR_MFT0MSK  (1UL<<31)  /* b0 */
+#define M32R_MFTCR_MFT1MSK  (1UL<<30)  /* b1 */
+#define M32R_MFTCR_MFT2MSK  (1UL<<29)  /* b2 */
+#define M32R_MFTCR_MFT3MSK  (1UL<<28)  /* b3 */
+#define M32R_MFTCR_MFT4MSK  (1UL<<27)  /* b4 */
+#define M32R_MFTCR_MFT5MSK  (1UL<<26)  /* b5 */
+#define M32R_MFTCR_MFT0EN   (1UL<<23)  /* b8 */
+#define M32R_MFTCR_MFT1EN   (1UL<<22)  /* b9 */
+#define M32R_MFTCR_MFT2EN   (1UL<<21)  /* b10 */
+#define M32R_MFTCR_MFT3EN   (1UL<<20)  /* b11 */
+#define M32R_MFTCR_MFT4EN   (1UL<<19)  /* b12 */
+#define M32R_MFTCR_MFT5EN   (1UL<<18)  /* b13 */
+#else
+#define M32R_MFTCR_MFT0MSK  (1UL<<15)  /* b16 */
+#define M32R_MFTCR_MFT1MSK  (1UL<<14)  /* b17 */
+#define M32R_MFTCR_MFT2MSK  (1UL<<13)  /* b18 */
+#define M32R_MFTCR_MFT3MSK  (1UL<<12)  /* b19 */
+#define M32R_MFTCR_MFT4MSK  (1UL<<11)  /* b20 */
+#define M32R_MFTCR_MFT5MSK  (1UL<<10)  /* b21 */
+#define M32R_MFTCR_MFT0EN   (1UL<<7)   /* b24 */
+#define M32R_MFTCR_MFT1EN   (1UL<<6)   /* b25 */
+#define M32R_MFTCR_MFT2EN   (1UL<<5)   /* b26 */
+#define M32R_MFTCR_MFT3EN   (1UL<<4)   /* b27 */
+#define M32R_MFTCR_MFT4EN   (1UL<<3)   /* b28 */
+#define M32R_MFTCR_MFT5EN   (1UL<<2)   /* b29 */
+#endif
+
+#define M32R_MFTMOD_CC_MASK    (1UL<<15)  /* b16 */
+#define M32R_MFTMOD_TCCR       (1UL<<13)  /* b18 */
+#define M32R_MFTMOD_GTSEL000   (0UL<<8)   /* b21-23 : 000 */
+#define M32R_MFTMOD_GTSEL001   (1UL<<8)   /* b21-23 : 001 */
+#define M32R_MFTMOD_GTSEL010   (2UL<<8)   /* b21-23 : 010 */
+#define M32R_MFTMOD_GTSEL011   (3UL<<8)   /* b21-23 : 011 */
+#define M32R_MFTMOD_GTSEL110   (6UL<<8)   /* b21-23 : 110 */
+#define M32R_MFTMOD_GTSEL111   (7UL<<8)   /* b21-23 : 111 */
+#define M32R_MFTMOD_CMSEL      (1UL<<3)   /* b28 */
+#define M32R_MFTMOD_CSSEL000   (0UL<<0)   /* b29-b31 : 000 */
+#define M32R_MFTMOD_CSSEL001   (1UL<<0)   /* b29-b31 : 001 */
+#define M32R_MFTMOD_CSSEL010   (2UL<<0)   /* b29-b31 : 010 */
+#define M32R_MFTMOD_CSSEL011   (3UL<<0)   /* b29-b31 : 011 */
+#define M32R_MFTMOD_CSSEL100   (4UL<<0)   /* b29-b31 : 100 */
+#define M32R_MFTMOD_CSSEL110   (6UL<<0)   /* b29-b31 : 110 */
+
+/*
+ * Serial I/O registers.
+ */
+#define M32R_SIO_OFFSET  (0x000FD000+M32R_SFR_OFFSET)
+
+#define M32R_SIO0_CR_PORTL    (0x000+M32R_SIO_OFFSET)
+#define M32R_SIO0_MOD0_PORTL  (0x004+M32R_SIO_OFFSET)
+#define M32R_SIO0_MOD1_PORTL  (0x008+M32R_SIO_OFFSET)
+#define M32R_SIO0_STS_PORTL   (0x00C+M32R_SIO_OFFSET)
+#define M32R_SIO0_TRCR_PORTL  (0x010+M32R_SIO_OFFSET)
+#define M32R_SIO0_BAUR_PORTL  (0x014+M32R_SIO_OFFSET)
+#define M32R_SIO0_RBAUR_PORTL (0x018+M32R_SIO_OFFSET)
+#define M32R_SIO0_TXB_PORTL   (0x01C+M32R_SIO_OFFSET)
+#define M32R_SIO0_RXB_PORTL   (0x020+M32R_SIO_OFFSET)
+
+/*
+ * Interrupt Control Unit registers.
+ */
+#define M32R_ICU_OFFSET       (0x000FF000+M32R_SFR_OFFSET)
+#define M32R_ICU_ISTS_PORTL   (0x004+M32R_ICU_OFFSET)
+#define M32R_ICU_IREQ0_PORTL  (0x008+M32R_ICU_OFFSET)
+#define M32R_ICU_IREQ1_PORTL  (0x00C+M32R_ICU_OFFSET)
+#define M32R_ICU_SBICR_PORTL  (0x018+M32R_ICU_OFFSET)
+#define M32R_ICU_IMASK_PORTL  (0x01C+M32R_ICU_OFFSET)
+#define M32R_ICU_CR1_PORTL    (0x200+M32R_ICU_OFFSET)  /* INT0 */
+#define M32R_ICU_CR2_PORTL    (0x204+M32R_ICU_OFFSET)  /* INT1 */
+#define M32R_ICU_CR3_PORTL    (0x208+M32R_ICU_OFFSET)  /* INT2 */
+#define M32R_ICU_CR4_PORTL    (0x20C+M32R_ICU_OFFSET)  /* INT3 */
+#define M32R_ICU_CR5_PORTL    (0x210+M32R_ICU_OFFSET)  /* INT4 */
+#define M32R_ICU_CR6_PORTL    (0x214+M32R_ICU_OFFSET)  /* INT5 */
+#define M32R_ICU_CR7_PORTL    (0x218+M32R_ICU_OFFSET)  /* INT6 */
+#define M32R_ICU_CR8_PORTL    (0x219+M32R_ICU_OFFSET)  /* INT7 */
+#define M32R_ICU_CR16_PORTL   (0x23C+M32R_ICU_OFFSET)  /* MFT0 */
+#define M32R_ICU_CR17_PORTL   (0x240+M32R_ICU_OFFSET)  /* MFT1 */
+#define M32R_ICU_CR18_PORTL   (0x244+M32R_ICU_OFFSET)  /* MFT2 */
+#define M32R_ICU_CR19_PORTL   (0x248+M32R_ICU_OFFSET)  /* MFT3 */
+#define M32R_ICU_CR20_PORTL   (0x24C+M32R_ICU_OFFSET)  /* MFT4 */
+#define M32R_ICU_CR21_PORTL   (0x250+M32R_ICU_OFFSET)  /* MFT5 */
+#define M32R_ICU_CR32_PORTL   (0x27C+M32R_ICU_OFFSET)  /* DMA0 */
+#define M32R_ICU_CR33_PORTL   (0x280+M32R_ICU_OFFSET)  /* DMA1 */
+#define M32R_ICU_CR48_PORTL   (0x2BC+M32R_ICU_OFFSET)  /* SIO0 */
+#define M32R_ICU_CR49_PORTL   (0x2C0+M32R_ICU_OFFSET)  /* SIO0 */
+#define M32R_ICU_CR50_PORTL   (0x2C4+M32R_ICU_OFFSET)  /* SIO1 */
+#define M32R_ICU_CR51_PORTL   (0x2C8+M32R_ICU_OFFSET)  /* SIO1 */
+#define M32R_ICU_CR52_PORTL   (0x2CC+M32R_ICU_OFFSET)  /* SIO2 */
+#define M32R_ICU_CR53_PORTL   (0x2D0+M32R_ICU_OFFSET)  /* SIO2 */
+#define M32R_ICU_CR54_PORTL   (0x2D4+M32R_ICU_OFFSET)  /* SIO3 */
+#define M32R_ICU_CR55_PORTL   (0x2D8+M32R_ICU_OFFSET)  /* SIO3 */
+#define M32R_ICU_CR56_PORTL   (0x2DC+M32R_ICU_OFFSET)  /* SIO4 */
+#define M32R_ICU_CR57_PORTL   (0x2E0+M32R_ICU_OFFSET)  /* SIO4 */
+
+#ifdef CONFIG_SMP
+#define M32R_ICU_IPICR0_PORTL (0x2dc+M32R_ICU_OFFSET)  /* IPI0 */
+#define M32R_ICU_IPICR1_PORTL (0x2e0+M32R_ICU_OFFSET)  /* IPI1 */
+#define M32R_ICU_IPICR2_PORTL (0x2e4+M32R_ICU_OFFSET)  /* IPI2 */
+#define M32R_ICU_IPICR3_PORTL (0x2e8+M32R_ICU_OFFSET)  /* IPI3 */
+#define M32R_ICU_IPICR4_PORTL (0x2ec+M32R_ICU_OFFSET)  /* IPI4 */
+#define M32R_ICU_IPICR5_PORTL (0x2f0+M32R_ICU_OFFSET)  /* IPI5 */
+#define M32R_ICU_IPICR6_PORTL (0x2f4+M32R_ICU_OFFSET)  /* IPI6 */
+#define M32R_ICU_IPICR7_PORTL (0x2f8+M32R_ICU_OFFSET)  /* IPI7 */
+#endif /* CONFIG_SMP */
+
+#define M32R_ICUIMASK_IMSK0  (0UL<<16)  /* b13-b15: Disable interrupt */
+#define M32R_ICUIMASK_IMSK1  (1UL<<16)  /* b13-b15: Enable level 0 interrupt */
+#define M32R_ICUIMASK_IMSK2  (2UL<<16)  /* b13-b15: Enable level 0,1 interrupt */
+#define M32R_ICUIMASK_IMSK3  (3UL<<16)  /* b13-b15: Enable level 0-2 interrupt */
+#define M32R_ICUIMASK_IMSK4  (4UL<<16)  /* b13-b15: Enable level 0-3 interrupt */
+#define M32R_ICUIMASK_IMSK5  (5UL<<16)  /* b13-b15: Enable level 0-4 interrupt */
+#define M32R_ICUIMASK_IMSK6  (6UL<<16)  /* b13-b15: Enable level 0-5 interrupt */
+#define M32R_ICUIMASK_IMSK7  (7UL<<16)  /* b13-b15: Enable level 0-6 interrupt */
+
+#define M32R_ICUCR_IEN      (1UL<<12)  /* b19: Interrupt enable */
+#define M32R_ICUCR_IRQ      (1UL<<8)   /* b23: Interrupt request */
+#define M32R_ICUCR_ISMOD00  (0UL<<4)   /* b26-b27: Interrupt sense mode Edge HtoL */
+#define M32R_ICUCR_ISMOD01  (1UL<<4)   /* b26-b27: Interrupt sense mode Level L */
+#define M32R_ICUCR_ISMOD10  (2UL<<4)   /* b26-b27: Interrupt sense mode Edge LtoH*/
+#define M32R_ICUCR_ISMOD11  (3UL<<4)   /* b26-b27: Interrupt sense mode Level H */
+#define M32R_ICUCR_ILEVEL0  (0UL<<0)   /* b29-b31: Interrupt priority level 0 */
+#define M32R_ICUCR_ILEVEL1  (1UL<<0)   /* b29-b31: Interrupt priority level 1 */
+#define M32R_ICUCR_ILEVEL2  (2UL<<0)   /* b29-b31: Interrupt priority level 2 */
+#define M32R_ICUCR_ILEVEL3  (3UL<<0)   /* b29-b31: Interrupt priority level 3 */
+#define M32R_ICUCR_ILEVEL4  (4UL<<0)   /* b29-b31: Interrupt priority level 4 */
+#define M32R_ICUCR_ILEVEL5  (5UL<<0)   /* b29-b31: Interrupt priority level 5 */
+#define M32R_ICUCR_ILEVEL6  (6UL<<0)   /* b29-b31: Interrupt priority level 6 */
+#define M32R_ICUCR_ILEVEL7  (7UL<<0)   /* b29-b31: Disable interrupt */
+
+#define M32R_IRQ_INT0    (1)   /* INT0 */
+#define M32R_IRQ_INT1    (2)   /* INT1 */
+#define M32R_IRQ_INT2    (3)   /* INT2 */
+#define M32R_IRQ_INT3    (4)   /* INT3 */
+#define M32R_IRQ_INT4    (5)   /* INT4 */
+#define M32R_IRQ_INT5    (6)   /* INT5 */
+#define M32R_IRQ_INT6    (7)   /* INT6 */
+#define M32R_IRQ_MFT0    (16)  /* MFT0 */
+#define M32R_IRQ_MFT1    (17)  /* MFT1 */
+#define M32R_IRQ_MFT2    (18)  /* MFT2 */
+#define M32R_IRQ_MFT3    (19)  /* MFT3 */
+#ifdef CONFIG_CHIP_M32104
+#define M32R_IRQ_MFTX0   (24)  /* MFTX0 */
+#define M32R_IRQ_MFTX1   (25)  /* MFTX1 */
+#define M32R_IRQ_DMA0    (32)  /* DMA0 */
+#define M32R_IRQ_DMA1    (33)  /* DMA1 */
+#define M32R_IRQ_DMA2    (34)  /* DMA2 */
+#define M32R_IRQ_DMA3    (35)  /* DMA3 */
+#define M32R_IRQ_SIO0_R  (40)  /* SIO0 send    */
+#define M32R_IRQ_SIO0_S  (41)  /* SIO0 receive */
+#define M32R_IRQ_SIO1_R  (42)  /* SIO1 send    */
+#define M32R_IRQ_SIO1_S  (43)  /* SIO1 receive */
+#define M32R_IRQ_SIO2_R  (44)  /* SIO2 send    */
+#define M32R_IRQ_SIO2_S  (45)  /* SIO2 receive */
+#define M32R_IRQ_SIO3_R  (46)  /* SIO3 send    */
+#define M32R_IRQ_SIO3_S  (47)  /* SIO3 receive */
+#define M32R_IRQ_ADC     (56)  /* ADC */
+#define M32R_IRQ_PC      (57)  /* PC */
+#else /* ! M32104 */
+#define M32R_IRQ_DMA0    (32)  /* DMA0 */
+#define M32R_IRQ_DMA1    (33)  /* DMA1 */
+#define M32R_IRQ_SIO0_R  (48)  /* SIO0 send    */
+#define M32R_IRQ_SIO0_S  (49)  /* SIO0 receive */
+#define M32R_IRQ_SIO1_R  (50)  /* SIO1 send    */
+#define M32R_IRQ_SIO1_S  (51)  /* SIO1 receive */
+#define M32R_IRQ_SIO2_R  (52)  /* SIO2 send    */
+#define M32R_IRQ_SIO2_S  (53)  /* SIO2 receive */
+#define M32R_IRQ_SIO3_R  (54)  /* SIO3 send    */
+#define M32R_IRQ_SIO3_S  (55)  /* SIO3 receive */
+#define M32R_IRQ_SIO4_R  (56)  /* SIO4 send    */
+#define M32R_IRQ_SIO4_S  (57)  /* SIO4 receive */
+#endif /* ! M32104 */
+
+#ifdef CONFIG_SMP
+#define M32R_IRQ_IPI0    (56)
+#define M32R_IRQ_IPI1    (57)
+#define M32R_IRQ_IPI2    (58)
+#define M32R_IRQ_IPI3    (59)
+#define M32R_IRQ_IPI4    (60)
+#define M32R_IRQ_IPI5    (61)
+#define M32R_IRQ_IPI6    (62)
+#define M32R_IRQ_IPI7    (63)
+#define M32R_CPUID_PORTL (0xffffffe0)
+
+#define M32R_FPGA_TOP (0x000F0000+M32R_SFR_OFFSET)
+
+#define M32R_FPGA_NUM_OF_CPUS_PORTL (0x00+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME0_PORTL   (0x10+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME1_PORTL   (0x14+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME2_PORTL   (0x18+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME3_PORTL   (0x1c+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID0_PORTL   (0x20+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID1_PORTL   (0x24+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID2_PORTL   (0x28+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID3_PORTL   (0x2c+M32R_FPGA_TOP)
+#define M32R_FPGA_VERSION0_PORTL    (0x30+M32R_FPGA_TOP)
+#define M32R_FPGA_VERSION1_PORTL    (0x34+M32R_FPGA_TOP)
+
+#endif /* CONFIG_SMP */
+
+#ifndef __ASSEMBLY__
+typedef struct {
+	unsigned long icucr;	/* ICU Control Register */
+} icu_data_t;
+#endif
+
+#endif /* _M32102_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32104ut/m32104ut_pld.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32104ut/m32104ut_pld.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32104ut/m32104ut_pld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32104ut/m32104ut_pld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,161 @@
+#ifndef _M32104UT_M32104UT_PLD_H
+#define _M32104UT_M32104UT_PLD_H
+
+/*
+ * include/asm-m32r/m32104ut/m32104ut_pld.h
+ *
+ * Definitions for Programable Logic Device(PLD) on M32104UT board.
+ * Based on m32700ut_pld.h
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ * Copyright (c) 2005	Naoto Sugai
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_PLAT_M32104UT)
+#define PLD_PLAT_BASE		0x02c00000
+#else
+#error "no platform configuration"
+#endif
+
+#ifndef __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define PLD_BASE		(PLD_PLAT_BASE /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(PLD_PLAT_BASE + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif /* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ */
+
+#define PLD_IRQ_INT0		(M32104UT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_CFIREQ		(M32104UT_PLD_IRQ_BASE + 3)	/* CF IREQ */
+#define PLD_IRQ_CFC_INSERT	(M32104UT_PLD_IRQ_BASE + 4)	/* CF Insert */
+#define PLD_IRQ_CFC_EJECT	(M32104UT_PLD_IRQ_BASE + 5)	/* CF Eject */
+#define PLD_IRQ_EXINT		(M32104UT_PLD_IRQ_BASE + 6)	/* EXINT */
+#define PLD_IRQ_MMCCARD		(M32104UT_PLD_IRQ_BASE + 11)	/* MMC Insert/Eject */
+#define PLD_IRQ_SC_ERROR	(M32104UT_PLD_IRQ_BASE + 13)	/* SC error */
+#define PLD_IRQ_SC_RCV		(M32104UT_PLD_IRQ_BASE + 14)	/* SC receive */
+#define PLD_IRQ_SC_SND		(M32104UT_PLD_IRQ_BASE + 15)	/* SC send */
+
+#define PLD_ICUISTS		__reg16(PLD_BASE + 0x8002)
+#define PLD_ICUISTS_VECB_MASK	(0xf000)
+#define PLD_ICUISTS_VECB(x)	((x) & PLD_ICUISTS_VECB_MASK)
+#define PLD_ICUISTS_ISN_MASK	(0x07c0)
+#define PLD_ICUISTS_ISN(x)	((x) & PLD_ICUISTS_ISN_MASK)
+#define PLD_ICUCR3		__reg16(PLD_BASE + 0x8104)
+#define PLD_ICUCR4		__reg16(PLD_BASE + 0x8106)
+#define PLD_ICUCR5		__reg16(PLD_BASE + 0x8108)
+#define PLD_ICUCR6		__reg16(PLD_BASE + 0x810a)
+#define PLD_ICUCR11		__reg16(PLD_BASE + 0x8114)
+#define PLD_ICUCR13		__reg16(PLD_BASE + 0x8118)
+#define PLD_ICUCR14		__reg16(PLD_BASE + 0x811a)
+#define PLD_ICUCR15		__reg16(PLD_BASE + 0x811c)
+#define PLD_ICUCR_IEN		(0x1000)
+#define PLD_ICUCR_IREQ		(0x0100)
+#define PLD_ICUCR_ISMOD00	(0x0000)	/* Low edge */
+#define PLD_ICUCR_ISMOD01	(0x0010)	/* Low level */
+#define PLD_ICUCR_ISMOD02	(0x0020)	/* High edge */
+#define PLD_ICUCR_ISMOD03	(0x0030)	/* High level */
+#define PLD_ICUCR_ILEVEL0	(0x0000)
+#define PLD_ICUCR_ILEVEL1	(0x0001)
+#define PLD_ICUCR_ILEVEL2	(0x0002)
+#define PLD_ICUCR_ILEVEL3	(0x0003)
+#define PLD_ICUCR_ILEVEL4	(0x0004)
+#define PLD_ICUCR_ILEVEL5	(0x0005)
+#define PLD_ICUCR_ILEVEL6	(0x0006)
+#define PLD_ICUCR_ILEVEL7	(0x0007)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+#define PLD_CPCR_CDP		0x0001
+
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif /* _M32104UT_M32104UT_PLD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lan.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lan.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lan.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,103 @@
+#ifndef _M32700UT_M32700UT_LAN_H
+#define _M32700UT_M32700UT_LAN_H
+
+/*
+ * include/asm-m32r/m32700ut/m32700ut_lan.h
+ *
+ * M32700UT-LAN board
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ *
+ * 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 __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define M32700UT_LAN_BASE	(0x10000000 /* + NONCACHE_OFFSET */)
+#else
+#define M32700UT_LAN_BASE	(0x10000000 + NONCACHE_OFFSET)
+#endif /* __ASSEMBLY__ */
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ *  ICUCR16:	control register for SIO0 receive interrupt
+ *  ICUCR17:	control register for SIO0 send interrupt
+ */
+#define M32700UT_LAN_IRQ_LAN	(M32700UT_LAN_PLD_IRQ_BASE + 1)	/* LAN */
+#define M32700UT_LAN_IRQ_I2C	(M32700UT_LAN_PLD_IRQ_BASE + 3)	/* I2C */
+
+#define M32700UT_LAN_ICUISTS	__reg16(M32700UT_LAN_BASE + 0xc0002)
+#define M32700UT_LAN_ICUISTS_VECB_MASK	(0xf000)
+#define M32700UT_LAN_VECB(x)	((x) & M32700UT_LAN_ICUISTS_VECB_MASK)
+#define M32700UT_LAN_ICUISTS_ISN_MASK	(0x07c0)
+#define M32700UT_LAN_ICUISTS_ISN(x)	((x) & M32700UT_LAN_ICUISTS_ISN_MASK)
+#define M32700UT_LAN_ICUIREQ0	__reg16(M32700UT_LAN_BASE + 0xc0004)
+#define M32700UT_LAN_ICUCR1	__reg16(M32700UT_LAN_BASE + 0xc0010)
+#define M32700UT_LAN_ICUCR3	__reg16(M32700UT_LAN_BASE + 0xc0014)
+
+/*
+ * AR register on PLD
+ */
+#define ARVCR0		__reg32(M32700UT_LAN_BASE + 0x40000)
+#define ARVCR0_VDS		0x00080000
+#define ARVCR0_RST		0x00010000
+#define ARVCR1		__reg32(M32700UT_LAN_BASE + 0x40004)
+#define ARVCR1_QVGA		0x02000000
+#define ARVCR1_NORMAL		0x01000000
+#define ARVCR1_HIEN		0x00010000
+#define ARVHCOUNT	__reg32(M32700UT_LAN_BASE + 0x40008)
+#define ARDATA		__reg32(M32700UT_LAN_BASE + 0x40010)
+#define ARINTSEL	__reg32(M32700UT_LAN_BASE + 0x40014)
+#define ARINTSEL_INT3		0x10000000	/* CPU INT3 */
+#define ARDATA32	__reg32(M32700UT_LAN_BASE + 0x04040010)	// Block 5
+/*
+#define ARINTSEL_SEL2		0x00002000
+#define ARINTSEL_SEL3		0x00001000
+#define ARINTSEL_SEL6		0x00000200
+#define ARINTSEL_SEL7		0x00000100
+#define ARINTSEL_SEL9		0x00000040
+#define ARINTSEL_SEL10		0x00000020
+#define ARINTSEL_SEL11		0x00000010
+#define ARINTSEL_SEL12		0x00000008
+*/
+
+/*
+ * I2C register on PLD
+ */
+#define PLDI2CCR	__reg32(M32700UT_LAN_BASE + 0x40040)
+#define	PLDI2CCR_ES0		0x00000001	/* enable I2C interface */
+#define PLDI2CMOD	__reg32(M32700UT_LAN_BASE + 0x40044)
+#define PLDI2CMOD_ACKCLK	0x00000200
+#define PLDI2CMOD_DTWD		0x00000100
+#define PLDI2CMOD_10BT		0x00000004
+#define PLDI2CMOD_ATM_NORMAL	0x00000000
+#define PLDI2CMOD_ATM_AUTO	0x00000003
+#define PLDI2CACK	__reg32(M32700UT_LAN_BASE + 0x40048)
+#define PLDI2CACK_ACK		0x00000001
+#define PLDI2CFREQ	__reg32(M32700UT_LAN_BASE + 0x4004c)
+#define PLDI2CCND	__reg32(M32700UT_LAN_BASE + 0x40050)
+#define PLDI2CCND_START		0x00000001
+#define PLDI2CCND_STOP		0x00000002
+#define PLDI2CSTEN	__reg32(M32700UT_LAN_BASE + 0x40054)
+#define PLDI2CSTEN_STEN		0x00000001
+#define PLDI2CDATA	__reg32(M32700UT_LAN_BASE + 0x40060)
+#define PLDI2CSTS	__reg32(M32700UT_LAN_BASE + 0x40064)
+#define PLDI2CSTS_TRX		0x00000020
+#define PLDI2CSTS_BB		0x00000010
+#define PLDI2CSTS_NOACK		0x00000001	/* 0:ack, 1:noack */
+
+#endif /* _M32700UT_M32700UT_LAN_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lcd.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lcd.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lcd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_lcd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+#ifndef _M32700UT_M32700UT_LCD_H
+#define _M32700UT_M32700UT_LCD_H
+
+/*
+ * include/asm-m32r/m32700ut/m32700ut_lcd.h
+ *
+ * M32700UT-LCD board
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ *
+ * 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 __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define M32700UT_LCD_BASE	(0x10000000 /* + NONCACHE_OFFSET */)
+#else
+#define M32700UT_LCD_BASE	(0x10000000 + NONCACHE_OFFSET)
+#endif /* __ASSEMBLY__ */
+
+/*
+ * ICU
+ */
+#define M32700UT_LCD_IRQ_BAT_INT	(M32700UT_LCD_PLD_IRQ_BASE + 1)
+#define M32700UT_LCD_IRQ_USB_INT1	(M32700UT_LCD_PLD_IRQ_BASE + 2)
+#define M32700UT_LCD_IRQ_AUDT0		(M32700UT_LCD_PLD_IRQ_BASE + 3)
+#define M32700UT_LCD_IRQ_AUDT2		(M32700UT_LCD_PLD_IRQ_BASE + 4)
+#define M32700UT_LCD_IRQ_BATSIO_RCV	(M32700UT_LCD_PLD_IRQ_BASE + 16)
+#define M32700UT_LCD_IRQ_BATSIO_SND	(M32700UT_LCD_PLD_IRQ_BASE + 17)
+#define M32700UT_LCD_IRQ_ASNDSIO_RCV	(M32700UT_LCD_PLD_IRQ_BASE + 18)
+#define M32700UT_LCD_IRQ_ASNDSIO_SND	(M32700UT_LCD_PLD_IRQ_BASE + 19)
+#define M32700UT_LCD_IRQ_ACNLSIO_SND	(M32700UT_LCD_PLD_IRQ_BASE + 21)
+
+#define M32700UT_LCD_ICUISTS	__reg16(M32700UT_LCD_BASE + 0x300002)
+#define M32700UT_LCD_ICUISTS_VECB_MASK	(0xf000)
+#define M32700UT_LCD_VECB(x)	((x) & M32700UT_LCD_ICUISTS_VECB_MASK)
+#define M32700UT_LCD_ICUISTS_ISN_MASK	(0x07c0)
+#define M32700UT_LCD_ICUISTS_ISN(x)	((x) & M32700UT_LCD_ICUISTS_ISN_MASK)
+#define M32700UT_LCD_ICUIREQ0	__reg16(M32700UT_LCD_BASE + 0x300004)
+#define M32700UT_LCD_ICUIREQ1	__reg16(M32700UT_LCD_BASE + 0x300006)
+#define M32700UT_LCD_ICUCR1	__reg16(M32700UT_LCD_BASE + 0x300020)
+#define M32700UT_LCD_ICUCR2	__reg16(M32700UT_LCD_BASE + 0x300022)
+#define M32700UT_LCD_ICUCR3	__reg16(M32700UT_LCD_BASE + 0x300024)
+#define M32700UT_LCD_ICUCR4	__reg16(M32700UT_LCD_BASE + 0x300026)
+#define M32700UT_LCD_ICUCR16	__reg16(M32700UT_LCD_BASE + 0x300030)
+#define M32700UT_LCD_ICUCR17	__reg16(M32700UT_LCD_BASE + 0x300032)
+#define M32700UT_LCD_ICUCR18	__reg16(M32700UT_LCD_BASE + 0x300034)
+#define M32700UT_LCD_ICUCR19	__reg16(M32700UT_LCD_BASE + 0x300036)
+#define M32700UT_LCD_ICUCR21	__reg16(M32700UT_LCD_BASE + 0x30003a)
+
+#endif /* _M32700UT_M32700UT_LCD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_pld.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_pld.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_pld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32700ut/m32700ut_pld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,259 @@
+#ifndef _M32700UT_M32700UT_PLD_H
+#define _M32700UT_M32700UT_PLD_H
+
+/*
+ * include/asm-m32r/m32700ut/m32700ut_pld.h
+ *
+ * Definitions for Programable Logic Device(PLD) on M32700UT board.
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ *
+ * 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.
+ */
+
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV)
+#define PLD_PLAT_BASE		0x04c00000
+#else
+#error "no platform configuration"
+#endif
+
+#ifndef __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define PLD_BASE		(PLD_PLAT_BASE /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(PLD_PLAT_BASE + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif /* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+#define PLD_CFVENCR		__reg16(PLD_BASE + 0x0008)
+#define PLD_CFCR0		__reg16(PLD_BASE + 0x000a)
+#define PLD_CFCR1		__reg16(PLD_BASE + 0x000c)
+#define PLD_IDERSTCR		__reg16(PLD_BASE + 0x0010)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ *  ICUCR16:	control register for SIO0 receive interrupt
+ *  ICUCR17:	control register for SIO0 send interrupt
+ */
+#if !defined(CONFIG_PLAT_USRV)
+#define PLD_IRQ_INT0		(M32700UT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_INT1		(M32700UT_PLD_IRQ_BASE + 1)	/* reserved */
+#define PLD_IRQ_INT2		(M32700UT_PLD_IRQ_BASE + 2)	/* reserved */
+#define PLD_IRQ_CFIREQ		(M32700UT_PLD_IRQ_BASE + 3)	/* CF IREQ */
+#define PLD_IRQ_CFC_INSERT	(M32700UT_PLD_IRQ_BASE + 4)	/* CF Insert */
+#define PLD_IRQ_CFC_EJECT	(M32700UT_PLD_IRQ_BASE + 5)	/* CF Eject */
+#define PLD_IRQ_EXINT		(M32700UT_PLD_IRQ_BASE + 6)	/* EXINT */
+#define PLD_IRQ_INT7		(M32700UT_PLD_IRQ_BASE + 7)	/* reserved */
+#define PLD_IRQ_INT8		(M32700UT_PLD_IRQ_BASE + 8)	/* reserved */
+#define PLD_IRQ_INT9		(M32700UT_PLD_IRQ_BASE + 9)	/* reserved */
+#define PLD_IRQ_INT10		(M32700UT_PLD_IRQ_BASE + 10)	/* reserved */
+#define PLD_IRQ_MMCCARD		(M32700UT_PLD_IRQ_BASE + 11)	/* MMC Insert/Eject */
+#define PLD_IRQ_INT12		(M32700UT_PLD_IRQ_BASE + 12)	/* reserved */
+#define PLD_IRQ_SC_ERROR	(M32700UT_PLD_IRQ_BASE + 13)	/* SC error */
+#define PLD_IRQ_SC_RCV		(M32700UT_PLD_IRQ_BASE + 14)	/* SC receive */
+#define PLD_IRQ_SC_SND		(M32700UT_PLD_IRQ_BASE + 15)	/* SC send */
+#define PLD_IRQ_SIO0_RCV	(M32700UT_PLD_IRQ_BASE + 16)	/* SIO receive */
+#define PLD_IRQ_SIO0_SND	(M32700UT_PLD_IRQ_BASE + 17)	/* SIO send */
+#define PLD_IRQ_INT18		(M32700UT_PLD_IRQ_BASE + 18)	/* reserved */
+#define PLD_IRQ_INT19		(M32700UT_PLD_IRQ_BASE + 19)	/* reserved */
+#define PLD_IRQ_INT20		(M32700UT_PLD_IRQ_BASE + 20)	/* reserved */
+#define PLD_IRQ_INT21		(M32700UT_PLD_IRQ_BASE + 21)	/* reserved */
+#define PLD_IRQ_INT22		(M32700UT_PLD_IRQ_BASE + 22)	/* reserved */
+#define PLD_IRQ_INT23		(M32700UT_PLD_IRQ_BASE + 23)	/* reserved */
+#define PLD_IRQ_INT24		(M32700UT_PLD_IRQ_BASE + 24)	/* reserved */
+#define PLD_IRQ_INT25		(M32700UT_PLD_IRQ_BASE + 25)	/* reserved */
+#define PLD_IRQ_INT26		(M32700UT_PLD_IRQ_BASE + 26)	/* reserved */
+#define PLD_IRQ_INT27		(M32700UT_PLD_IRQ_BASE + 27)	/* reserved */
+#define PLD_IRQ_INT28		(M32700UT_PLD_IRQ_BASE + 28)	/* reserved */
+#define PLD_IRQ_INT29		(M32700UT_PLD_IRQ_BASE + 29)	/* reserved */
+#define PLD_IRQ_INT30		(M32700UT_PLD_IRQ_BASE + 30)	/* reserved */
+#define PLD_IRQ_INT31		(M32700UT_PLD_IRQ_BASE + 31)	/* reserved */
+
+#else	/* CONFIG_PLAT_USRV */
+
+#define PLD_IRQ_INT0		(M32700UT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_INT1		(M32700UT_PLD_IRQ_BASE + 1)	/* reserved */
+#define PLD_IRQ_INT2		(M32700UT_PLD_IRQ_BASE + 2)	/* reserved */
+#define PLD_IRQ_CF0		(M32700UT_PLD_IRQ_BASE + 3)	/* CF0# */
+#define PLD_IRQ_CF1		(M32700UT_PLD_IRQ_BASE + 4)	/* CF1# */
+#define PLD_IRQ_CF2		(M32700UT_PLD_IRQ_BASE + 5)	/* CF2# */
+#define PLD_IRQ_CF3		(M32700UT_PLD_IRQ_BASE + 6)	/* CF3# */
+#define PLD_IRQ_CF4		(M32700UT_PLD_IRQ_BASE + 7)	/* CF4# */
+#define PLD_IRQ_INT8		(M32700UT_PLD_IRQ_BASE + 8)	/* reserved */
+#define PLD_IRQ_INT9		(M32700UT_PLD_IRQ_BASE + 9)	/* reserved */
+#define PLD_IRQ_INT10		(M32700UT_PLD_IRQ_BASE + 10)	/* reserved */
+#define PLD_IRQ_INT11		(M32700UT_PLD_IRQ_BASE + 11)	/* reserved */
+#define PLD_IRQ_UART0		(M32700UT_PLD_IRQ_BASE + 12)	/* UARTIRQ0 */
+#define PLD_IRQ_UART1		(M32700UT_PLD_IRQ_BASE + 13)	/* UARTIRQ1 */
+#define PLD_IRQ_INT14		(M32700UT_PLD_IRQ_BASE + 14)	/* reserved */
+#define PLD_IRQ_INT15		(M32700UT_PLD_IRQ_BASE + 15)	/* reserved */
+#define PLD_IRQ_SNDINT		(M32700UT_PLD_IRQ_BASE + 16)	/* SNDINT# */
+#define PLD_IRQ_INT17		(M32700UT_PLD_IRQ_BASE + 17)	/* reserved */
+#define PLD_IRQ_INT18		(M32700UT_PLD_IRQ_BASE + 18)	/* reserved */
+#define PLD_IRQ_INT19		(M32700UT_PLD_IRQ_BASE + 19)	/* reserved */
+#define PLD_IRQ_INT20		(M32700UT_PLD_IRQ_BASE + 20)	/* reserved */
+#define PLD_IRQ_INT21		(M32700UT_PLD_IRQ_BASE + 21)	/* reserved */
+#define PLD_IRQ_INT22		(M32700UT_PLD_IRQ_BASE + 22)	/* reserved */
+#define PLD_IRQ_INT23		(M32700UT_PLD_IRQ_BASE + 23)	/* reserved */
+#define PLD_IRQ_INT24		(M32700UT_PLD_IRQ_BASE + 24)	/* reserved */
+#define PLD_IRQ_INT25		(M32700UT_PLD_IRQ_BASE + 25)	/* reserved */
+#define PLD_IRQ_INT26		(M32700UT_PLD_IRQ_BASE + 26)	/* reserved */
+#define PLD_IRQ_INT27		(M32700UT_PLD_IRQ_BASE + 27)	/* reserved */
+#define PLD_IRQ_INT28		(M32700UT_PLD_IRQ_BASE + 28)	/* reserved */
+#define PLD_IRQ_INT29		(M32700UT_PLD_IRQ_BASE + 29)	/* reserved */
+#define PLD_IRQ_INT30		(M32700UT_PLD_IRQ_BASE + 30)	/* reserved */
+
+#endif	/* CONFIG_PLAT_USRV */
+
+#define PLD_ICUISTS		__reg16(PLD_BASE + 0x8002)
+#define PLD_ICUISTS_VECB_MASK	(0xf000)
+#define PLD_ICUISTS_VECB(x)	((x) & PLD_ICUISTS_VECB_MASK)
+#define PLD_ICUISTS_ISN_MASK	(0x07c0)
+#define PLD_ICUISTS_ISN(x)	((x) & PLD_ICUISTS_ISN_MASK)
+#define PLD_ICUIREQ0		__reg16(PLD_BASE + 0x8004)
+#define PLD_ICUIREQ1		__reg16(PLD_BASE + 0x8006)
+#define PLD_ICUCR1		__reg16(PLD_BASE + 0x8100)
+#define PLD_ICUCR2		__reg16(PLD_BASE + 0x8102)
+#define PLD_ICUCR3		__reg16(PLD_BASE + 0x8104)
+#define PLD_ICUCR4		__reg16(PLD_BASE + 0x8106)
+#define PLD_ICUCR5		__reg16(PLD_BASE + 0x8108)
+#define PLD_ICUCR6		__reg16(PLD_BASE + 0x810a)
+#define PLD_ICUCR7		__reg16(PLD_BASE + 0x810c)
+#define PLD_ICUCR8		__reg16(PLD_BASE + 0x810e)
+#define PLD_ICUCR9		__reg16(PLD_BASE + 0x8110)
+#define PLD_ICUCR10		__reg16(PLD_BASE + 0x8112)
+#define PLD_ICUCR11		__reg16(PLD_BASE + 0x8114)
+#define PLD_ICUCR12		__reg16(PLD_BASE + 0x8116)
+#define PLD_ICUCR13		__reg16(PLD_BASE + 0x8118)
+#define PLD_ICUCR14		__reg16(PLD_BASE + 0x811a)
+#define PLD_ICUCR15		__reg16(PLD_BASE + 0x811c)
+#define PLD_ICUCR16		__reg16(PLD_BASE + 0x811e)
+#define PLD_ICUCR17		__reg16(PLD_BASE + 0x8120)
+#define PLD_ICUCR_IEN		(0x1000)
+#define PLD_ICUCR_IREQ		(0x0100)
+#define PLD_ICUCR_ISMOD00	(0x0000)	/* Low edge */
+#define PLD_ICUCR_ISMOD01	(0x0010)	/* Low level */
+#define PLD_ICUCR_ISMOD02	(0x0020)	/* High edge */
+#define PLD_ICUCR_ISMOD03	(0x0030)	/* High level */
+#define PLD_ICUCR_ILEVEL0	(0x0000)
+#define PLD_ICUCR_ILEVEL1	(0x0001)
+#define PLD_ICUCR_ILEVEL2	(0x0002)
+#define PLD_ICUCR_ILEVEL3	(0x0003)
+#define PLD_ICUCR_ILEVEL4	(0x0004)
+#define PLD_ICUCR_ILEVEL5	(0x0005)
+#define PLD_ICUCR_ILEVEL6	(0x0006)
+#define PLD_ICUCR_ILEVEL7	(0x0007)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+#define PLD_CPCR_CF		0x0001
+#define PLD_CPCR_MMC		0x0002
+
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIO0 */
+#define PLD_ESIO0CR		__reg16(PLD_BASE + 0x20000)
+#define	PLD_ESIO0CR_TXEN	0x0001
+#define	PLD_ESIO0CR_RXEN	0x0002
+#define PLD_ESIO0MOD0		__reg16(PLD_BASE + 0x20002)
+#define	PLD_ESIO0MOD0_CTSS	0x0040
+#define	PLD_ESIO0MOD0_RTSS	0x0080
+#define PLD_ESIO0MOD1		__reg16(PLD_BASE + 0x20004)
+#define	PLD_ESIO0MOD1_LMFS	0x0010
+#define PLD_ESIO0STS		__reg16(PLD_BASE + 0x20006)
+#define	PLD_ESIO0STS_TEMP	0x0001
+#define	PLD_ESIO0STS_TXCP	0x0002
+#define	PLD_ESIO0STS_RXCP	0x0004
+#define	PLD_ESIO0STS_TXSC	0x0100
+#define	PLD_ESIO0STS_RXSC	0x0200
+#define PLD_ESIO0STS_TXREADY	(PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP)
+#define PLD_ESIO0INTCR		__reg16(PLD_BASE + 0x20008)
+#define	PLD_ESIO0INTCR_TXIEN	0x0002
+#define	PLD_ESIO0INTCR_RXCEN	0x0004
+#define PLD_ESIO0BAUR		__reg16(PLD_BASE + 0x2000a)
+#define PLD_ESIO0TXB		__reg16(PLD_BASE + 0x2000c)
+#define PLD_ESIO0RXB		__reg16(PLD_BASE + 0x2000e)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif /* _M32700UT_M32700UT_PLD.H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32r.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32r.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32r.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32r.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,160 @@
+#ifndef _ASM_M32R_M32R_H_
+#define _ASM_M32R_M32R_H_
+
+/*
+ * Renesas M32R processor
+ *
+ * Copyright (C) 2003, 2004  Renesas Technology Corp.
+ */
+
+
+/* Chip type */
+#if defined(CONFIG_CHIP_XNUX_MP) || defined(CONFIG_CHIP_XNUX2_MP)
+#include <asm/m32r_mp_fpga.h>
+#elif defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
+	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
+        || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
+#include <asm/m32102.h>
+#endif
+
+/* Platform type */
+#if defined(CONFIG_PLAT_M32700UT)
+#include <asm/m32700ut/m32700ut_pld.h>
+#include <asm/m32700ut/m32700ut_lan.h>
+#include <asm/m32700ut/m32700ut_lcd.h>
+/* for ei_handler:linux/arch/m32r/kernel/entry.S */
+#define M32R_INT1ICU_ISTS	PLD_ICUISTS
+#define M32R_INT1ICU_IRQ_BASE	M32700UT_PLD_IRQ_BASE
+#define M32R_INT0ICU_ISTS	M32700UT_LAN_ICUISTS
+#define M32R_INT0ICU_IRQ_BASE	M32700UT_LAN_PLD_IRQ_BASE
+#define M32R_INT2ICU_ISTS	M32700UT_LCD_ICUISTS
+#define M32R_INT2ICU_IRQ_BASE	M32700UT_LCD_PLD_IRQ_BASE
+#endif  /* CONFIG_PLAT_M32700UT */
+
+#if defined(CONFIG_PLAT_OPSPUT)
+#include <asm/opsput/opsput_pld.h>
+#include <asm/opsput/opsput_lan.h>
+#include <asm/opsput/opsput_lcd.h>
+/* for ei_handler:linux/arch/m32r/kernel/entry.S */
+#define M32R_INT1ICU_ISTS	PLD_ICUISTS
+#define M32R_INT1ICU_IRQ_BASE	OPSPUT_PLD_IRQ_BASE
+#define M32R_INT0ICU_ISTS	OPSPUT_LAN_ICUISTS
+#define M32R_INT0ICU_IRQ_BASE	OPSPUT_LAN_PLD_IRQ_BASE
+#define M32R_INT2ICU_ISTS	OPSPUT_LCD_ICUISTS
+#define M32R_INT2ICU_IRQ_BASE	OPSPUT_LCD_PLD_IRQ_BASE
+#endif  /* CONFIG_PLAT_OPSPUT */
+
+#if defined(CONFIG_PLAT_MAPPI2)
+#include <asm/mappi2/mappi2_pld.h>
+#endif	/* CONFIG_PLAT_MAPPI2 */
+
+#if defined(CONFIG_PLAT_MAPPI3)
+#include <asm/mappi3/mappi3_pld.h>
+#endif	/* CONFIG_PLAT_MAPPI3 */
+
+#if defined(CONFIG_PLAT_USRV)
+#include <asm/m32700ut/m32700ut_pld.h>
+/* for ei_handler:linux/arch/m32r/kernel/entry.S */
+#define M32R_INT1ICU_ISTS	PLD_ICUISTS
+#define M32R_INT1ICU_IRQ_BASE	M32700UT_PLD_IRQ_BASE
+#endif
+
+#if defined(CONFIG_PLAT_M32104UT)
+#include <asm/m32104ut/m32104ut_pld.h>
+/* for ei_handler:linux/arch/m32r/kernel/entry.S */
+#define M32R_INT1ICU_ISTS	PLD_ICUISTS
+#define M32R_INT1ICU_IRQ_BASE	M32104UT_PLD_IRQ_BASE
+#endif  /* CONFIG_PLAT_M32104 */
+
+/*
+ * M32R Register
+ */
+
+/*
+ * MMU Register
+ */
+
+#define MMU_REG_BASE	(0xffff0000)
+#define ITLB_BASE	(0xfe000000)
+#define DTLB_BASE	(0xfe000800)
+
+#define NR_TLB_ENTRIES	CONFIG_TLB_ENTRIES
+
+#define MATM	MMU_REG_BASE		/* MMU Address Translation Mode
+					   Register */
+#define MPSZ	(0x04 + MMU_REG_BASE)	/* MMU Page Size Designation Register */
+#define MASID	(0x08 + MMU_REG_BASE)	/* MMU Address Space ID Register */
+#define MESTS	(0x0c + MMU_REG_BASE)	/* MMU Exception Status Register */
+#define MDEVA	(0x10 + MMU_REG_BASE)	/* MMU Operand Exception Virtual
+					   Address Register */
+#define MDEVP	(0x14 + MMU_REG_BASE)	/* MMU Operand Exception Virtual Page
+					   Number Register */
+#define MPTB	(0x18 + MMU_REG_BASE)	/* MMU Page Table Base Register */
+#define MSVA	(0x20 + MMU_REG_BASE)	/* MMU Search Virtual Address
+					   Register */
+#define MTOP	(0x24 + MMU_REG_BASE)	/* MMU TLB Operation Register */
+#define MIDXI	(0x28 + MMU_REG_BASE)	/* MMU Index Register for
+					   Instruciton */
+#define MIDXD	(0x2c + MMU_REG_BASE)	/* MMU Index Register for Operand */
+
+#define MATM_offset	(MATM - MMU_REG_BASE)
+#define MPSZ_offset	(MPSZ - MMU_REG_BASE)
+#define MASID_offset	(MASID - MMU_REG_BASE)
+#define MESTS_offset	(MESTS - MMU_REG_BASE)
+#define MDEVA_offset	(MDEVA - MMU_REG_BASE)
+#define MDEVP_offset	(MDEVP - MMU_REG_BASE)
+#define MPTB_offset	(MPTB - MMU_REG_BASE)
+#define MSVA_offset	(MSVA - MMU_REG_BASE)
+#define MTOP_offset	(MTOP - MMU_REG_BASE)
+#define MIDXI_offset	(MIDXI - MMU_REG_BASE)
+#define MIDXD_offset	(MIDXD - MMU_REG_BASE)
+
+#define MESTS_IT	(1 << 0)	/* Instruction TLB miss */
+#define MESTS_IA	(1 << 1)	/* Instruction Access Exception */
+#define MESTS_DT	(1 << 4)	/* Operand TLB miss */
+#define MESTS_DA	(1 << 5)	/* Operand Access Exception */
+#define MESTS_DRW	(1 << 6)	/* Operand Write Exception Flag */
+
+/*
+ * PSW (Processor Status Word)
+ */
+
+/* PSW bit */
+#define M32R_PSW_BIT_SM   (7)    /* Stack Mode */
+#define M32R_PSW_BIT_IE   (6)    /* Interrupt Enable */
+#define M32R_PSW_BIT_PM   (3)    /* Processor Mode [0:Supervisor,1:User] */
+#define M32R_PSW_BIT_C    (0)    /* Condition */
+#define M32R_PSW_BIT_BSM  (7+8)  /* Backup Stack Mode */
+#define M32R_PSW_BIT_BIE  (6+8)  /* Backup Interrupt Enable */
+#define M32R_PSW_BIT_BPM  (3+8)  /* Backup Processor Mode */
+#define M32R_PSW_BIT_BC   (0+8)  /* Backup Condition */
+
+/* PSW bit map */
+#define M32R_PSW_SM   (1UL<< M32R_PSW_BIT_SM)   /* Stack Mode */
+#define M32R_PSW_IE   (1UL<< M32R_PSW_BIT_IE)   /* Interrupt Enable */
+#define M32R_PSW_PM   (1UL<< M32R_PSW_BIT_PM)   /* Processor Mode */
+#define M32R_PSW_C    (1UL<< M32R_PSW_BIT_C)    /* Condition */
+#define M32R_PSW_BSM  (1UL<< M32R_PSW_BIT_BSM)  /* Backup Stack Mode */
+#define M32R_PSW_BIE  (1UL<< M32R_PSW_BIT_BIE)  /* Backup Interrupt Enable */
+#define M32R_PSW_BPM  (1UL<< M32R_PSW_BIT_BPM)  /* Backup Processor Mode */
+#define M32R_PSW_BC   (1UL<< M32R_PSW_BIT_BC)   /* Backup Condition */
+
+/*
+ * Direct address to SFR
+ */
+
+#include <asm/page.h>
+#ifdef CONFIG_MMU
+#define NONCACHE_OFFSET  (__PAGE_OFFSET + 0x20000000)
+#else
+#define NONCACHE_OFFSET  __PAGE_OFFSET
+#endif /* CONFIG_MMU */
+
+#define M32R_ICU_ISTS_ADDR  M32R_ICU_ISTS_PORTL+NONCACHE_OFFSET
+#define M32R_ICU_IPICR_ADDR  M32R_ICU_IPICR0_PORTL+NONCACHE_OFFSET
+#define M32R_ICU_IMASK_ADDR  M32R_ICU_IMASK_PORTL+NONCACHE_OFFSET
+#define M32R_FPGA_CPU_NAME_ADDR  M32R_FPGA_CPU_NAME0_PORTL+NONCACHE_OFFSET
+#define M32R_FPGA_MODEL_ID_ADDR  M32R_FPGA_MODEL_ID0_PORTL+NONCACHE_OFFSET
+#define M32R_FPGA_VERSION_ADDR   M32R_FPGA_VERSION0_PORTL+NONCACHE_OFFSET
+
+#endif /* _ASM_M32R_M32R_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32r_mp_fpga.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32r_mp_fpga.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/m32r_mp_fpga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/m32r_mp_fpga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,313 @@
+#ifndef _ASM_M32R_M32R_MP_FPGA_
+#define _ASM_M32R_M32R_MP_FPGA_
+
+/*
+ * Renesas M32R-MP-FPGA
+ *
+ * Copyright (c) 2002  Hitoshi Yamamoto
+ * Copyright (c) 2003, 2004  Renesas Technology Corp.
+ */
+
+/*
+ * ========================================================
+ * M32R-MP-FPGA Memory Map
+ * ========================================================
+ * 0x00000000 : Block#0 : 64[MB]
+ *              0x03E00000 : SFR
+ *                           0x03E00000 : reserved
+ *                           0x03EF0000 : FPGA
+ *                           0x03EF1000 : reserved
+ *                           0x03EF4000 : CKM
+ *                           0x03EF4000 : BSELC
+ *                           0x03EF5000 : reserved
+ *                           0x03EFC000 : MFT
+ *                           0x03EFD000 : SIO
+ *                           0x03EFE000 : reserved
+ *                           0x03EFF000 : ICU
+ *              0x03F00000 : Internal SRAM 64[KB]
+ *              0x03F10000 : reserved
+ * --------------------------------------------------------
+ * 0x04000000 : Block#1 : 64[MB]
+ *              0x04000000 : Debug board SRAM 4[MB]
+ *              0x04400000 : reserved
+ * --------------------------------------------------------
+ * 0x08000000 : Block#2 : 64[MB]
+ * --------------------------------------------------------
+ * 0x0C000000 : Block#3 : 64[MB]
+ * --------------------------------------------------------
+ * 0x10000000 : Block#4 : 64[MB]
+ * --------------------------------------------------------
+ * 0x14000000 : Block#5 : 64[MB]
+ * --------------------------------------------------------
+ * 0x18000000 : Block#6 : 64[MB]
+ * --------------------------------------------------------
+ * 0x1C000000 : Block#7 : 64[MB]
+ * --------------------------------------------------------
+ * 0xFE000000 : TLB
+ *              0xFE000000 : ITLB
+ *              0xFE000080 : reserved
+ *              0xFE000800 : DTLB
+ *              0xFE000880 : reserved
+ * --------------------------------------------------------
+ * 0xFF000000 : System area
+ *              0xFFFF0000 : MMU
+ *              0xFFFF0030 : reserved
+ *              0xFFFF8000 : Debug function
+ *              0xFFFFA000 : reserved
+ *              0xFFFFC000 : CPU control
+ * 0xFFFFFFFF
+ * ========================================================
+ */
+
+/*======================================================================*
+ * Special Function Register
+ *======================================================================*/
+#define M32R_SFR_OFFSET  (0x00E00000)  /* 0x03E00000-0x03EFFFFF 1[MB] */
+
+/*
+ * FPGA registers.
+ */
+#define M32R_FPGA_TOP  (0x000F0000+M32R_SFR_OFFSET)
+
+#define M32R_FPGA_NUM_OF_CPUS_PORTL  (0x00+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME0_PORTL    (0x10+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME1_PORTL    (0x14+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME2_PORTL    (0x18+M32R_FPGA_TOP)
+#define M32R_FPGA_CPU_NAME3_PORTL    (0x1C+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID0_PORTL    (0x20+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID1_PORTL    (0x24+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID2_PORTL    (0x28+M32R_FPGA_TOP)
+#define M32R_FPGA_MODEL_ID3_PORTL    (0x2C+M32R_FPGA_TOP)
+#define M32R_FPGA_VERSION0_PORTL     (0x30+M32R_FPGA_TOP)
+#define M32R_FPGA_VERSION1_PORTL     (0x34+M32R_FPGA_TOP)
+
+/*
+ * Clock and Power Manager registers.
+ */
+#define M32R_CPM_OFFSET  (0x000F4000+M32R_SFR_OFFSET)
+
+#define M32R_CPM_CPUCLKCR_PORTL  (0x00+M32R_CPM_OFFSET)
+#define M32R_CPM_CLKMOD_PORTL    (0x04+M32R_CPM_OFFSET)
+#define M32R_CPM_PLLCR_PORTL     (0x08+M32R_CPM_OFFSET)
+
+/*
+ * Block SELect Controller registers.
+ */
+#define M32R_BSELC_OFFSET  (0x000F5000+M32R_SFR_OFFSET)
+
+#define M32R_BSEL0_CR0_PORTL  (0x000+M32R_BSELC_OFFSET)
+#define M32R_BSEL0_CR1_PORTL  (0x004+M32R_BSELC_OFFSET)
+#define M32R_BSEL1_CR0_PORTL  (0x100+M32R_BSELC_OFFSET)
+#define M32R_BSEL1_CR1_PORTL  (0x104+M32R_BSELC_OFFSET)
+#define M32R_BSEL2_CR0_PORTL  (0x200+M32R_BSELC_OFFSET)
+#define M32R_BSEL2_CR1_PORTL  (0x204+M32R_BSELC_OFFSET)
+#define M32R_BSEL3_CR0_PORTL  (0x300+M32R_BSELC_OFFSET)
+#define M32R_BSEL3_CR1_PORTL  (0x304+M32R_BSELC_OFFSET)
+#define M32R_BSEL4_CR0_PORTL  (0x400+M32R_BSELC_OFFSET)
+#define M32R_BSEL4_CR1_PORTL  (0x404+M32R_BSELC_OFFSET)
+#define M32R_BSEL5_CR0_PORTL  (0x500+M32R_BSELC_OFFSET)
+#define M32R_BSEL5_CR1_PORTL  (0x504+M32R_BSELC_OFFSET)
+#define M32R_BSEL6_CR0_PORTL  (0x600+M32R_BSELC_OFFSET)
+#define M32R_BSEL6_CR1_PORTL  (0x604+M32R_BSELC_OFFSET)
+#define M32R_BSEL7_CR0_PORTL  (0x700+M32R_BSELC_OFFSET)
+#define M32R_BSEL7_CR1_PORTL  (0x704+M32R_BSELC_OFFSET)
+
+/*
+ * Multi Function Timer registers.
+ */
+#define M32R_MFT_OFFSET        (0x000FC000+M32R_SFR_OFFSET)
+
+#define M32R_MFTCR_PORTL       (0x000+M32R_MFT_OFFSET)  /* MFT control */
+#define M32R_MFTRPR_PORTL      (0x004+M32R_MFT_OFFSET)  /* MFT real port */
+
+#define M32R_MFT0_OFFSET       (0x100+M32R_MFT_OFFSET)
+#define M32R_MFT0MOD_PORTL     (0x00+M32R_MFT0_OFFSET)  /* MFT0 mode */
+#define M32R_MFT0BOS_PORTL     (0x04+M32R_MFT0_OFFSET)  /* MFT0 b-port output status */
+#define M32R_MFT0CUT_PORTL     (0x08+M32R_MFT0_OFFSET)  /* MFT0 count */
+#define M32R_MFT0RLD_PORTL     (0x0C+M32R_MFT0_OFFSET)  /* MFT0 reload */
+#define M32R_MFT0CMPRLD_PORTL  (0x10+M32R_MFT0_OFFSET)  /* MFT0 compare reload */
+
+#define M32R_MFT1_OFFSET       (0x200+M32R_MFT_OFFSET)
+#define M32R_MFT1MOD_PORTL     (0x00+M32R_MFT1_OFFSET)  /* MFT1 mode */
+#define M32R_MFT1BOS_PORTL     (0x04+M32R_MFT1_OFFSET)  /* MFT1 b-port output status */
+#define M32R_MFT1CUT_PORTL     (0x08+M32R_MFT1_OFFSET)  /* MFT1 count */
+#define M32R_MFT1RLD_PORTL     (0x0C+M32R_MFT1_OFFSET)  /* MFT1 reload */
+#define M32R_MFT1CMPRLD_PORTL  (0x10+M32R_MFT1_OFFSET)  /* MFT1 compare reload */
+
+#define M32R_MFT2_OFFSET       (0x300+M32R_MFT_OFFSET)
+#define M32R_MFT2MOD_PORTL     (0x00+M32R_MFT2_OFFSET)  /* MFT2 mode */
+#define M32R_MFT2BOS_PORTL     (0x04+M32R_MFT2_OFFSET)  /* MFT2 b-port output status */
+#define M32R_MFT2CUT_PORTL     (0x08+M32R_MFT2_OFFSET)  /* MFT2 count */
+#define M32R_MFT2RLD_PORTL     (0x0C+M32R_MFT2_OFFSET)  /* MFT2 reload */
+#define M32R_MFT2CMPRLD_PORTL  (0x10+M32R_MFT2_OFFSET)  /* MFT2 compare reload */
+
+#define M32R_MFT3_OFFSET       (0x400+M32R_MFT_OFFSET)
+#define M32R_MFT3MOD_PORTL     (0x00+M32R_MFT3_OFFSET)  /* MFT3 mode */
+#define M32R_MFT3BOS_PORTL     (0x04+M32R_MFT3_OFFSET)  /* MFT3 b-port output status */
+#define M32R_MFT3CUT_PORTL     (0x08+M32R_MFT3_OFFSET)  /* MFT3 count */
+#define M32R_MFT3RLD_PORTL     (0x0C+M32R_MFT3_OFFSET)  /* MFT3 reload */
+#define M32R_MFT3CMPRLD_PORTL  (0x10+M32R_MFT3_OFFSET)  /* MFT3 compare reload */
+
+#define M32R_MFT4_OFFSET       (0x500+M32R_MFT_OFFSET)
+#define M32R_MFT4MOD_PORTL     (0x00+M32R_MFT4_OFFSET)  /* MFT4 mode */
+#define M32R_MFT4BOS_PORTL     (0x04+M32R_MFT4_OFFSET)  /* MFT4 b-port output status */
+#define M32R_MFT4CUT_PORTL     (0x08+M32R_MFT4_OFFSET)  /* MFT4 count */
+#define M32R_MFT4RLD_PORTL     (0x0C+M32R_MFT4_OFFSET)  /* MFT4 reload */
+#define M32R_MFT4CMPRLD_PORTL  (0x10+M32R_MFT4_OFFSET)  /* MFT4 compare reload */
+
+#define M32R_MFT5_OFFSET       (0x600+M32R_MFT_OFFSET)
+#define M32R_MFT5MOD_PORTL     (0x00+M32R_MFT5_OFFSET)  /* MFT4 mode */
+#define M32R_MFT5BOS_PORTL     (0x04+M32R_MFT5_OFFSET)  /* MFT4 b-port output status */
+#define M32R_MFT5CUT_PORTL     (0x08+M32R_MFT5_OFFSET)  /* MFT4 count */
+#define M32R_MFT5RLD_PORTL     (0x0C+M32R_MFT5_OFFSET)  /* MFT4 reload */
+#define M32R_MFT5CMPRLD_PORTL  (0x10+M32R_MFT5_OFFSET)  /* MFT4 compare reload */
+
+#define M32R_MFTCR_MFT0MSK  (1UL<<15)  /* b16 */
+#define M32R_MFTCR_MFT1MSK  (1UL<<14)  /* b17 */
+#define M32R_MFTCR_MFT2MSK  (1UL<<13)  /* b18 */
+#define M32R_MFTCR_MFT3MSK  (1UL<<12)  /* b19 */
+#define M32R_MFTCR_MFT4MSK  (1UL<<11)  /* b20 */
+#define M32R_MFTCR_MFT5MSK  (1UL<<10)  /* b21 */
+#define M32R_MFTCR_MFT0EN   (1UL<<7)   /* b24 */
+#define M32R_MFTCR_MFT1EN   (1UL<<6)   /* b25 */
+#define M32R_MFTCR_MFT2EN   (1UL<<5)   /* b26 */
+#define M32R_MFTCR_MFT3EN   (1UL<<4)   /* b27 */
+#define M32R_MFTCR_MFT4EN   (1UL<<3)   /* b28 */
+#define M32R_MFTCR_MFT5EN   (1UL<<2)   /* b29 */
+
+#define M32R_MFTMOD_CC_MASK    (1UL<<15)  /* b16 */
+#define M32R_MFTMOD_TCCR       (1UL<<13)  /* b18 */
+#define M32R_MFTMOD_GTSEL000   (0UL<<8)   /* b21-23 : 000 */
+#define M32R_MFTMOD_GTSEL001   (1UL<<8)   /* b21-23 : 001 */
+#define M32R_MFTMOD_GTSEL010   (2UL<<8)   /* b21-23 : 010 */
+#define M32R_MFTMOD_GTSEL011   (3UL<<8)   /* b21-23 : 011 */
+#define M32R_MFTMOD_GTSEL110   (6UL<<8)   /* b21-23 : 110 */
+#define M32R_MFTMOD_GTSEL111   (7UL<<8)   /* b21-23 : 111 */
+#define M32R_MFTMOD_CMSEL      (1UL<<3)   /* b28 */
+#define M32R_MFTMOD_CSSEL000   (0UL<<0)   /* b29-b31 : 000 */
+#define M32R_MFTMOD_CSSEL001   (1UL<<0)   /* b29-b31 : 001 */
+#define M32R_MFTMOD_CSSEL010   (2UL<<0)   /* b29-b31 : 010 */
+#define M32R_MFTMOD_CSSEL011   (3UL<<0)   /* b29-b31 : 011 */
+#define M32R_MFTMOD_CSSEL100   (4UL<<0)   /* b29-b31 : 100 */
+#define M32R_MFTMOD_CSSEL110   (6UL<<0)   /* b29-b31 : 110 */
+
+/*
+ * Serial I/O registers.
+ */
+#define M32R_SIO_OFFSET  (0x000FD000+M32R_SFR_OFFSET)
+
+#define M32R_SIO0_CR_PORTL     (0x000+M32R_SIO_OFFSET)
+#define M32R_SIO0_MOD0_PORTL   (0x004+M32R_SIO_OFFSET)
+#define M32R_SIO0_MOD1_PORTL   (0x008+M32R_SIO_OFFSET)
+#define M32R_SIO0_STS_PORTL    (0x00C+M32R_SIO_OFFSET)
+#define M32R_SIO0_TRCR_PORTL   (0x010+M32R_SIO_OFFSET)
+#define M32R_SIO0_BAUR_PORTL   (0x014+M32R_SIO_OFFSET)
+#define M32R_SIO0_RBAUR_PORTL  (0x018+M32R_SIO_OFFSET)
+#define M32R_SIO0_TXB_PORTL    (0x01C+M32R_SIO_OFFSET)
+#define M32R_SIO0_RXB_PORTL    (0x020+M32R_SIO_OFFSET)
+
+/*
+ * Interrupt Control Unit registers.
+ */
+#define M32R_ICU_OFFSET  (0x000FF000+M32R_SFR_OFFSET)
+
+#define M32R_ICU_ISTS_PORTL     (0x004+M32R_ICU_OFFSET)
+#define M32R_ICU_IREQ0_PORTL    (0x008+M32R_ICU_OFFSET)
+#define M32R_ICU_IREQ1_PORTL    (0x00C+M32R_ICU_OFFSET)
+#define M32R_ICU_SBICR_PORTL    (0x018+M32R_ICU_OFFSET)
+#define M32R_ICU_IMASK_PORTL    (0x01C+M32R_ICU_OFFSET)
+#define M32R_ICU_CR1_PORTL      (0x200+M32R_ICU_OFFSET)  /* INT0 */
+#define M32R_ICU_CR2_PORTL      (0x204+M32R_ICU_OFFSET)  /* INT1 */
+#define M32R_ICU_CR3_PORTL      (0x208+M32R_ICU_OFFSET)  /* INT2 */
+#define M32R_ICU_CR4_PORTL      (0x20C+M32R_ICU_OFFSET)  /* INT3 */
+#define M32R_ICU_CR5_PORTL      (0x210+M32R_ICU_OFFSET)  /* INT4 */
+#define M32R_ICU_CR6_PORTL      (0x214+M32R_ICU_OFFSET)  /* INT5 */
+#define M32R_ICU_CR7_PORTL      (0x218+M32R_ICU_OFFSET)  /* INT6 */
+#define M32R_ICU_CR8_PORTL      (0x218+M32R_ICU_OFFSET)  /* INT7 */
+#define M32R_ICU_CR32_PORTL     (0x27C+M32R_ICU_OFFSET)  /* SIO0 RX */
+#define M32R_ICU_CR33_PORTL     (0x280+M32R_ICU_OFFSET)  /* SIO0 TX */
+#define M32R_ICU_CR40_PORTL     (0x29C+M32R_ICU_OFFSET)  /* DMAC0 */
+#define M32R_ICU_CR41_PORTL     (0x2A0+M32R_ICU_OFFSET)  /* DMAC1 */
+#define M32R_ICU_CR48_PORTL     (0x2BC+M32R_ICU_OFFSET)  /* MFT0 */
+#define M32R_ICU_CR49_PORTL     (0x2C0+M32R_ICU_OFFSET)  /* MFT1 */
+#define M32R_ICU_CR50_PORTL     (0x2C4+M32R_ICU_OFFSET)  /* MFT2 */
+#define M32R_ICU_CR51_PORTL     (0x2C8+M32R_ICU_OFFSET)  /* MFT3 */
+#define M32R_ICU_CR52_PORTL     (0x2CC+M32R_ICU_OFFSET)  /* MFT4 */
+#define M32R_ICU_CR53_PORTL     (0x2D0+M32R_ICU_OFFSET)  /* MFT5 */
+#define M32R_ICU_IPICR0_PORTL   (0x2DC+M32R_ICU_OFFSET)  /* IPI0 */
+#define M32R_ICU_IPICR1_PORTL   (0x2E0+M32R_ICU_OFFSET)  /* IPI1 */
+#define M32R_ICU_IPICR2_PORTL   (0x2E4+M32R_ICU_OFFSET)  /* IPI2 */
+#define M32R_ICU_IPICR3_PORTL   (0x2E8+M32R_ICU_OFFSET)  /* IPI3 */
+#define M32R_ICU_IPICR4_PORTL   (0x2EC+M32R_ICU_OFFSET)  /* IPI4 */
+#define M32R_ICU_IPICR5_PORTL   (0x2F0+M32R_ICU_OFFSET)  /* IPI5 */
+#define M32R_ICU_IPICR6_PORTL   (0x2F4+M32R_ICU_OFFSET)  /* IPI6 */
+#define M32R_ICU_IPICR7_PORTL   (0x2FC+M32R_ICU_OFFSET)  /* IPI7 */
+
+#define M32R_ICUISTS_VECB(val)  ((val>>28) & 0xF)
+#define M32R_ICUISTS_ISN(val)   ((val>>22) & 0x3F)
+#define M32R_ICUISTS_PIML(val)  ((val>>16) & 0x7)
+
+#define M32R_ICUIMASK_IMSK0  (0UL<<16)  /* b13-b15: Disable interrupt */
+#define M32R_ICUIMASK_IMSK1  (1UL<<16)  /* b13-b15: Enable level 0 interrupt */
+#define M32R_ICUIMASK_IMSK2  (2UL<<16)  /* b13-b15: Enable level 0,1 interrupt */
+#define M32R_ICUIMASK_IMSK3  (3UL<<16)  /* b13-b15: Enable level 0-2 interrupt */
+#define M32R_ICUIMASK_IMSK4  (4UL<<16)  /* b13-b15: Enable level 0-3 interrupt */
+#define M32R_ICUIMASK_IMSK5  (5UL<<16)  /* b13-b15: Enable level 0-4 interrupt */
+#define M32R_ICUIMASK_IMSK6  (6UL<<16)  /* b13-b15: Enable level 0-5 interrupt */
+#define M32R_ICUIMASK_IMSK7  (7UL<<16)  /* b13-b15: Enable level 0-6 interrupt */
+
+#define M32R_ICUCR_IEN      (1UL<<12)  /* b19: Interrupt enable */
+#define M32R_ICUCR_IRQ      (1UL<<8)   /* b23: Interrupt request */
+#define M32R_ICUCR_ISMOD00  (0UL<<4)   /* b26-b27: Interrupt sense mode Edge HtoL */
+#define M32R_ICUCR_ISMOD01  (1UL<<4)   /* b26-b27: Interrupt sense mode Level L */
+#define M32R_ICUCR_ISMOD10  (2UL<<4)   /* b26-b27: Interrupt sense mode Edge LtoH*/
+#define M32R_ICUCR_ISMOD11  (3UL<<4)   /* b26-b27: Interrupt sense mode Level H */
+#define M32R_ICUCR_ILEVEL0  (0UL<<0)   /* b29-b31: Interrupt priority level 0 */
+#define M32R_ICUCR_ILEVEL1  (1UL<<0)   /* b29-b31: Interrupt priority level 1 */
+#define M32R_ICUCR_ILEVEL2  (2UL<<0)   /* b29-b31: Interrupt priority level 2 */
+#define M32R_ICUCR_ILEVEL3  (3UL<<0)   /* b29-b31: Interrupt priority level 3 */
+#define M32R_ICUCR_ILEVEL4  (4UL<<0)   /* b29-b31: Interrupt priority level 4 */
+#define M32R_ICUCR_ILEVEL5  (5UL<<0)   /* b29-b31: Interrupt priority level 5 */
+#define M32R_ICUCR_ILEVEL6  (6UL<<0)   /* b29-b31: Interrupt priority level 6 */
+#define M32R_ICUCR_ILEVEL7  (7UL<<0)   /* b29-b31: Disable interrupt */
+#define M32R_ICUCR_ILEVEL_MASK  (7UL)
+
+#define M32R_IRQ_INT0    (1)   /* INT0 */
+#define M32R_IRQ_INT1    (2)   /* INT1 */
+#define M32R_IRQ_INT2    (3)   /* INT2 */
+#define M32R_IRQ_INT3    (4)   /* INT3 */
+#define M32R_IRQ_INT4    (5)   /* INT4 */
+#define M32R_IRQ_INT5    (6)   /* INT5 */
+#define M32R_IRQ_INT6    (7)   /* INT6 */
+#define M32R_IRQ_INT7    (8)   /* INT7 */
+#define M32R_IRQ_MFT0    (16)  /* MFT0 */
+#define M32R_IRQ_MFT1    (17)  /* MFT1 */
+#define M32R_IRQ_MFT2    (18)  /* MFT2 */
+#define M32R_IRQ_MFT3    (19)  /* MFT3 */
+#define M32R_IRQ_MFT4    (20)  /* MFT4 */
+#define M32R_IRQ_MFT5    (21)  /* MFT5 */
+#define M32R_IRQ_DMAC0   (32)  /* DMAC0 */
+#define M32R_IRQ_DMAC1   (33)  /* DMAC1 */
+#define M32R_IRQ_SIO0_R  (48)  /* SIO0 receive */
+#define M32R_IRQ_SIO0_S  (49)  /* SIO0 send    */
+#define M32R_IRQ_SIO1_R  (50)  /* SIO1 send    */
+#define M32R_IRQ_SIO1_S  (51)  /* SIO1 receive */
+#define M32R_IRQ_IPI0    (56)  /* IPI0 */
+#define M32R_IRQ_IPI1    (57)  /* IPI1 */
+#define M32R_IRQ_IPI2    (58)  /* IPI2 */
+#define M32R_IRQ_IPI3    (59)  /* IPI3 */
+#define M32R_IRQ_IPI4    (60)  /* IPI4 */
+#define M32R_IRQ_IPI5    (61)  /* IPI5 */
+#define M32R_IRQ_IPI6    (62)  /* IPI6 */
+#define M32R_IRQ_IPI7    (63)  /* IPI7 */
+
+/*======================================================================*
+ * CPU
+ *======================================================================*/
+
+#define M32R_CPUID_PORTL   (0xFFFFFFE0)
+#define M32R_MCICAR_PORTL  (0xFFFFFFF0)
+#define M32R_MCDCAR_PORTL  (0xFFFFFFF4)
+#define M32R_MCCR_PORTL    (0xFFFFFFFC)
+
+#endif  /* _ASM_M32R_M32R_MP_FPGA_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mappi2/mappi2_pld.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mappi2/mappi2_pld.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mappi2/mappi2_pld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mappi2/mappi2_pld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,150 @@
+#ifndef _MAPPI2_PLD_H
+#define _MAPPI2_PLD_H
+
+/*
+ * include/asm-m32r/mappi2/mappi2_pld.h
+ *
+ * Definitions for Extended IO Logic on MAPPI2 board.
+ *  based on m32700ut_pld.h
+ *
+ * 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 __ASSEMBLY__
+/* FIXME:
+ * Some C functions use non-cache address, so can't define non-cache address.
+ */
+#define PLD_BASE		(0x10c00000 /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(0x10c00000 + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif /* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+#define PLD_CFCR0		__reg16(PLD_BASE + 0x000a)
+#define PLD_CFCR1		__reg16(PLD_BASE + 0x000c)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+
+
+/*==== ICU ====*/
+#define  M32R_IRQ_PC104        (5)   /* INT4(PC/104) */
+#define  M32R_IRQ_I2C          (28)  /* I2C-BUS     */
+#if 1
+#define  PLD_IRQ_CFIREQ       (40)  /* CFC Card Interrupt */
+#define  PLD_IRQ_CFC_INSERT   (41)  /* CFC Card Insert */
+#define  PLD_IRQ_CFC_EJECT    (42)  /* CFC Card Eject */
+#define  PLD_IRQ_MMCCARD      (43)  /* MMC Card Insert */
+#define  PLD_IRQ_MMCIRQ       (44)  /* MMC Transfer Done */
+#else
+#define  PLD_IRQ_CFIREQ       (34)  /* CFC Card Interrupt */
+#define  PLD_IRQ_CFC_INSERT   (35)  /* CFC Card Insert */
+#define  PLD_IRQ_CFC_EJECT    (36)  /* CFC Card Eject */
+#define  PLD_IRQ_MMCCARD      (37)  /* MMC Card Insert */
+#define  PLD_IRQ_MMCIRQ       (38)  /* MMC Transfer Done */
+#endif
+
+
+#if 0
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+#endif
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+
+#if 0
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIO0 */
+#define PLD_ESIO0CR		__reg16(PLD_BASE + 0x20000)
+#define	PLD_ESIO0CR_TXEN	0x0001
+#define	PLD_ESIO0CR_RXEN	0x0002
+#define PLD_ESIO0MOD0		__reg16(PLD_BASE + 0x20002)
+#define	PLD_ESIO0MOD0_CTSS	0x0040
+#define	PLD_ESIO0MOD0_RTSS	0x0080
+#define PLD_ESIO0MOD1		__reg16(PLD_BASE + 0x20004)
+#define	PLD_ESIO0MOD1_LMFS	0x0010
+#define PLD_ESIO0STS		__reg16(PLD_BASE + 0x20006)
+#define	PLD_ESIO0STS_TEMP	0x0001
+#define	PLD_ESIO0STS_TXCP	0x0002
+#define	PLD_ESIO0STS_RXCP	0x0004
+#define	PLD_ESIO0STS_TXSC	0x0100
+#define	PLD_ESIO0STS_RXSC	0x0200
+#define PLD_ESIO0STS_TXREADY	(PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP)
+#define PLD_ESIO0INTCR		__reg16(PLD_BASE + 0x20008)
+#define	PLD_ESIO0INTCR_TXIEN	0x0002
+#define	PLD_ESIO0INTCR_RXCEN	0x0004
+#define PLD_ESIO0BAUR		__reg16(PLD_BASE + 0x2000a)
+#define PLD_ESIO0TXB		__reg16(PLD_BASE + 0x2000c)
+#define PLD_ESIO0RXB		__reg16(PLD_BASE + 0x2000e)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif
+
+#endif /* _MAPPI2_PLD.H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mappi3/mappi3_pld.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mappi3/mappi3_pld.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mappi3/mappi3_pld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mappi3/mappi3_pld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,142 @@
+#ifndef _MAPPI3_PLD_H
+#define _MAPPI3_PLD_H
+
+/*
+ * include/asm-m32r/mappi3/mappi3_pld.h
+ *
+ * Definitions for Extended IO Logic on MAPPI3 board.
+ *  based on m32700ut_pld.h
+ *
+ * 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 __ASSEMBLY__
+/* FIXME:
+ * Some C functions use non-cache address, so can't define non-cache address.
+ */
+#define PLD_BASE		(0x1c000000 /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(0x1c000000 + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif /* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+#define PLD_CFCR0		__reg16(PLD_BASE + 0x000a)
+#define PLD_CFCR1		__reg16(PLD_BASE + 0x000c)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+
+/* ICU */
+#define M32R_IRQ_PC104		(5)	/* INT4(PC/104) */
+#define M32R_IRQ_I2C		(28)	/* I2C-BUS */
+#define PLD_IRQ_CFIREQ		(6)	/* INT5 CFC Card Interrupt */
+#define PLD_IRQ_CFC_INSERT	(7)	/* INT6 CFC Card Insert & Eject */
+#define PLD_IRQ_IDEIREQ		(8)	/* INT7 IDE Interrupt */
+#define PLD_IRQ_MMCCARD		(43)	/* MMC Card Insert */
+#define PLD_IRQ_MMCIRQ		(44)	/* MMC Transfer Done */
+
+#if 0
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+#endif
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+#if 0
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIO0 */
+#define PLD_ESIO0CR		__reg16(PLD_BASE + 0x20000)
+#define	PLD_ESIO0CR_TXEN	0x0001
+#define	PLD_ESIO0CR_RXEN	0x0002
+#define PLD_ESIO0MOD0		__reg16(PLD_BASE + 0x20002)
+#define	PLD_ESIO0MOD0_CTSS	0x0040
+#define	PLD_ESIO0MOD0_RTSS	0x0080
+#define PLD_ESIO0MOD1		__reg16(PLD_BASE + 0x20004)
+#define	PLD_ESIO0MOD1_LMFS	0x0010
+#define PLD_ESIO0STS		__reg16(PLD_BASE + 0x20006)
+#define	PLD_ESIO0STS_TEMP	0x0001
+#define	PLD_ESIO0STS_TXCP	0x0002
+#define	PLD_ESIO0STS_RXCP	0x0004
+#define	PLD_ESIO0STS_TXSC	0x0100
+#define	PLD_ESIO0STS_RXSC	0x0200
+#define PLD_ESIO0STS_TXREADY	(PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP)
+#define PLD_ESIO0INTCR		__reg16(PLD_BASE + 0x20008)
+#define	PLD_ESIO0INTCR_TXIEN	0x0002
+#define	PLD_ESIO0INTCR_RXCEN	0x0004
+#define PLD_ESIO0BAUR		__reg16(PLD_BASE + 0x2000a)
+#define PLD_ESIO0TXB		__reg16(PLD_BASE + 0x2000c)
+#define PLD_ESIO0RXB		__reg16(PLD_BASE + 0x2000e)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif
+
+/* Reset Control */
+#define PLD_REBOOT		__reg16(PLD_BASE + 0x38000)
+
+#endif /* _MAPPI3_PLD.H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mc146818rtc.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mc146818rtc.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mc146818rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mc146818rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)	((x))
+#define RTC_ALWAYS_BCD	1	/* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#define RTC_IRQ 8
+
+#endif /* _ASM_MC146818RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mman.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mman.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mman.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mman.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+#ifndef __M32R_MMAN_H__
+#define __M32R_MMAN_H__
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#endif /* __M32R_MMAN_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmu_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,164 @@
+#ifndef _ASM_M32R_MMU_CONTEXT_H
+#define _ASM_M32R_MMU_CONTEXT_H
+#ifdef __KERNEL__
+
+#include <asm/m32r.h>
+
+#define MMU_CONTEXT_ASID_MASK      (0x000000FF)
+#define MMU_CONTEXT_VERSION_MASK   (0xFFFFFF00)
+#define MMU_CONTEXT_FIRST_VERSION  (0x00000100)
+#define NO_CONTEXT                 (0x00000000)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/atomic.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu.h>
+#include <asm/tlbflush.h>
+#include <asm-generic/mm_hooks.h>
+
+/*
+ * Cache of MMU context last used.
+ */
+#ifndef CONFIG_SMP
+extern unsigned long mmu_context_cache_dat;
+#define mmu_context_cache	mmu_context_cache_dat
+#define mm_context(mm)		mm->context
+#else /* not CONFIG_SMP */
+extern unsigned long mmu_context_cache_dat[];
+#define mmu_context_cache	mmu_context_cache_dat[smp_processor_id()]
+#define mm_context(mm)		mm->context[smp_processor_id()]
+#endif /* not CONFIG_SMP */
+
+#define set_tlb_tag(entry, tag)		(*entry = (tag & PAGE_MASK)|get_asid())
+#define set_tlb_data(entry, data)	(*entry = (data | _PAGE_PRESENT))
+
+#ifdef CONFIG_MMU
+#define enter_lazy_tlb(mm, tsk)	do { } while (0)
+
+static inline void get_new_mmu_context(struct mm_struct *mm)
+{
+	unsigned long mc = ++mmu_context_cache;
+
+	if (!(mc & MMU_CONTEXT_ASID_MASK)) {
+		/* We exhaust ASID of this version.
+		   Flush all TLB and start new cycle. */
+		local_flush_tlb_all();
+		/* Fix version if needed.
+		   Note that we avoid version #0 to distingush NO_CONTEXT. */
+		if (!mc)
+			mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
+	}
+	mm_context(mm) = mc;
+}
+
+/*
+ * Get MMU context if needed.
+ */
+static inline void get_mmu_context(struct mm_struct *mm)
+{
+	if (mm) {
+		unsigned long mc = mmu_context_cache;
+
+		/* Check if we have old version of context.
+		   If it's old, we need to get new context with new version. */
+		if ((mm_context(mm) ^ mc) & MMU_CONTEXT_VERSION_MASK)
+			get_new_mmu_context(mm);
+	}
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+static inline int init_new_context(struct task_struct *tsk,
+	struct mm_struct *mm)
+{
+#ifndef CONFIG_SMP
+	mm->context = NO_CONTEXT;
+#else /* CONFIG_SMP */
+	int num_cpus = num_online_cpus();
+	int i;
+
+	for (i = 0 ; i < num_cpus ; i++)
+		mm->context[i] = NO_CONTEXT;
+#endif /* CONFIG_SMP */
+
+	return 0;
+}
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+#define destroy_context(mm)	do { } while (0)
+
+static inline void set_asid(unsigned long asid)
+{
+	*(volatile unsigned long *)MASID = (asid & MMU_CONTEXT_ASID_MASK);
+}
+
+static inline unsigned long get_asid(void)
+{
+	unsigned long asid;
+
+	asid = *(volatile long *)MASID;
+	asid &= MMU_CONTEXT_ASID_MASK;
+
+	return asid;
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static inline void activate_context(struct mm_struct *mm)
+{
+	get_mmu_context(mm);
+	set_asid(mm_context(mm) & MMU_CONTEXT_ASID_MASK);
+}
+
+static inline void switch_mm(struct mm_struct *prev,
+	struct mm_struct *next, struct task_struct *tsk)
+{
+#ifdef CONFIG_SMP
+	int cpu = smp_processor_id();
+#endif	/* CONFIG_SMP */
+
+	if (prev != next) {
+#ifdef CONFIG_SMP
+		cpu_set(cpu, next->cpu_vm_mask);
+#endif /* CONFIG_SMP */
+		/* Set MPTB = next->pgd */
+		*(volatile unsigned long *)MPTB = (unsigned long)next->pgd;
+		activate_context(next);
+	}
+#ifdef CONFIG_SMP
+	else
+		if (!cpu_test_and_set(cpu, next->cpu_vm_mask))
+			activate_context(next);
+#endif /* CONFIG_SMP */
+}
+
+#define deactivate_mm(tsk, mm)	do { } while (0)
+
+#define activate_mm(prev, next)	\
+	switch_mm((prev), (next), NULL)
+
+#else /* not CONFIG_MMU */
+#define get_mmu_context(mm)             do { } while (0)
+#define init_new_context(tsk,mm)        (0)
+#define destroy_context(mm)             do { } while (0)
+#define set_asid(asid)                  do { } while (0)
+#define get_asid()                      (0)
+#define activate_context(mm)            do { } while (0)
+#define switch_mm(prev,next,tsk)        do { } while (0)
+#define deactivate_mm(mm,tsk)           do { } while (0)
+#define activate_mm(prev,next)          do { } while (0)
+#define enter_lazy_tlb(mm,tsk)          do { } while (0)
+#endif /* not CONFIG_MMU */
+
+#endif /* not __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_M32R_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef _ASM_M32R_MMU_H
+#define _ASM_M32R_MMU_H
+
+#if !defined(CONFIG_MMU)
+
+typedef struct {
+	unsigned long		end_brk;
+} mm_context_t;
+
+#else /* CONFIG_MMU */
+
+/* Default "unsigned long" context */
+#ifndef CONFIG_SMP
+typedef unsigned long mm_context_t;
+#else
+typedef unsigned long mm_context_t[NR_CPUS];
+#endif
+
+#endif /* CONFIG_MMU */
+
+#endif /* _ASM_M32R_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmzone.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmzone.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mmzone.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mmzone.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * Written by Pat Gaughen (gone@us.ibm.com) Mar 2002
+ *
+ */
+
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <asm/smp.h>
+
+#ifdef CONFIG_DISCONTIGMEM
+
+extern struct pglist_data *node_data[];
+#define NODE_DATA(nid)		(node_data[nid])
+
+#define node_localnr(pfn, nid)	((pfn) - NODE_DATA(nid)->node_start_pfn)
+#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid)						\
+({									\
+	pg_data_t *__pgdat = NODE_DATA(nid);				\
+	__pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1;	\
+})
+
+#define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+/*
+ * pfn_valid should be made as fast as possible, and the current definition
+ * is valid for machines that are NUMA, but still contiguous, which is what
+ * is currently supported. A more generalised, but slower definition would
+ * be something like this - mbligh:
+ * ( pfn_to_pgdat(pfn) && ((pfn) < node_end_pfn(pfn_to_nid(pfn))) )
+ */
+#if 1	/* M32R_FIXME */
+#define pfn_valid(pfn)	(1)
+#else
+#define pfn_valid(pfn)	((pfn) < num_physpages)
+#endif
+
+/*
+ * generic node memory support, the following assumptions apply:
+ */
+
+static __inline__ int pfn_to_nid(unsigned long pfn)
+{
+	int node;
+
+	for (node = 0 ; node < MAX_NUMNODES ; node++)
+		if (pfn >= node_start_pfn(node) && pfn <= node_end_pfn(node))
+			break;
+
+	return node;
+}
+
+static __inline__ struct pglist_data *pfn_to_pgdat(unsigned long pfn)
+{
+	return(NODE_DATA(pfn_to_nid(pfn)));
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
+#endif /* _ASM_MMZONE_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/module.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/module.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _ASM_M32R_MODULE_H
+#define _ASM_M32R_MODULE_H
+
+struct mod_arch_specific { };
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+
+#endif /* _ASM_M32R_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/msgbuf.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/msgbuf.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/msgbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/msgbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+#ifndef _ASM_M32R_MSGBUF_H
+#define _ASM_M32R_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for m32r architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* _ASM_M32R_MSGBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mutex.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mutex.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/mutex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/mutex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_lan.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_lan.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_lan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_lan.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+#ifndef _OPSPUT_OPSPUT_LAN_H
+#define _OPSPUT_OPSPUT_LAN_H
+
+/*
+ * include/asm-m32r/opsput/opsput_lan.h
+ *
+ * OPSPUT-LAN board
+ *
+ * Copyright (c) 2002-2004	Takeo Takahashi, Mamoru Sakugawa
+ *
+ * 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 __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define OPSPUT_LAN_BASE	(0x10000000 /* + NONCACHE_OFFSET */)
+#else
+#define OPSPUT_LAN_BASE	(0x10000000 + NONCACHE_OFFSET)
+#endif /* __ASSEMBLY__ */
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ *  ICUCR16:	control register for SIO0 receive interrupt
+ *  ICUCR17:	control register for SIO0 send interrupt
+ */
+#define OPSPUT_LAN_IRQ_LAN	(OPSPUT_LAN_PLD_IRQ_BASE + 1)	/* LAN */
+#define OPSPUT_LAN_IRQ_I2C	(OPSPUT_LAN_PLD_IRQ_BASE + 3)	/* I2C */
+
+#define OPSPUT_LAN_ICUISTS	__reg16(OPSPUT_LAN_BASE + 0xc0002)
+#define OPSPUT_LAN_ICUISTS_VECB_MASK	(0xf000)
+#define OPSPUT_LAN_VECB(x)	((x) & OPSPUT_LAN_ICUISTS_VECB_MASK)
+#define OPSPUT_LAN_ICUISTS_ISN_MASK	(0x07c0)
+#define OPSPUT_LAN_ICUISTS_ISN(x)	((x) & OPSPUT_LAN_ICUISTS_ISN_MASK)
+#define OPSPUT_LAN_ICUIREQ0	__reg16(OPSPUT_LAN_BASE + 0xc0004)
+#define OPSPUT_LAN_ICUCR1	__reg16(OPSPUT_LAN_BASE + 0xc0010)
+#define OPSPUT_LAN_ICUCR3	__reg16(OPSPUT_LAN_BASE + 0xc0014)
+
+#endif /* _OPSPUT_OPSPUT_LAN_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_lcd.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_lcd.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_lcd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_lcd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+#ifndef _OPSPUT_OPSPUT_LCD_H
+#define _OPSPUT_OPSPUT_LCD_H
+
+/*
+ * include/asm-m32r/opsput/opsput_lcd.h
+ *
+ * OPSPUT-LCD board
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ *
+ * 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 __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define OPSPUT_LCD_BASE	(0x10000000 /* + NONCACHE_OFFSET */)
+#else
+#define OPSPUT_LCD_BASE	(0x10000000 + NONCACHE_OFFSET)
+#endif /* __ASSEMBLY__ */
+
+/*
+ * ICU
+ */
+#define OPSPUT_LCD_IRQ_BAT_INT	(OPSPUT_LCD_PLD_IRQ_BASE + 1)
+#define OPSPUT_LCD_IRQ_USB_INT1	(OPSPUT_LCD_PLD_IRQ_BASE + 2)
+#define OPSPUT_LCD_IRQ_AUDT0		(OPSPUT_LCD_PLD_IRQ_BASE + 3)
+#define OPSPUT_LCD_IRQ_AUDT2		(OPSPUT_LCD_PLD_IRQ_BASE + 4)
+#define OPSPUT_LCD_IRQ_BATSIO_RCV	(OPSPUT_LCD_PLD_IRQ_BASE + 16)
+#define OPSPUT_LCD_IRQ_BATSIO_SND	(OPSPUT_LCD_PLD_IRQ_BASE + 17)
+#define OPSPUT_LCD_IRQ_ASNDSIO_RCV	(OPSPUT_LCD_PLD_IRQ_BASE + 18)
+#define OPSPUT_LCD_IRQ_ASNDSIO_SND	(OPSPUT_LCD_PLD_IRQ_BASE + 19)
+#define OPSPUT_LCD_IRQ_ACNLSIO_SND	(OPSPUT_LCD_PLD_IRQ_BASE + 21)
+
+#define OPSPUT_LCD_ICUISTS	__reg16(OPSPUT_LCD_BASE + 0x300002)
+#define OPSPUT_LCD_ICUISTS_VECB_MASK	(0xf000)
+#define OPSPUT_LCD_VECB(x)	((x) & OPSPUT_LCD_ICUISTS_VECB_MASK)
+#define OPSPUT_LCD_ICUISTS_ISN_MASK	(0x07c0)
+#define OPSPUT_LCD_ICUISTS_ISN(x)	((x) & OPSPUT_LCD_ICUISTS_ISN_MASK)
+#define OPSPUT_LCD_ICUIREQ0	__reg16(OPSPUT_LCD_BASE + 0x300004)
+#define OPSPUT_LCD_ICUIREQ1	__reg16(OPSPUT_LCD_BASE + 0x300006)
+#define OPSPUT_LCD_ICUCR1	__reg16(OPSPUT_LCD_BASE + 0x300020)
+#define OPSPUT_LCD_ICUCR2	__reg16(OPSPUT_LCD_BASE + 0x300022)
+#define OPSPUT_LCD_ICUCR3	__reg16(OPSPUT_LCD_BASE + 0x300024)
+#define OPSPUT_LCD_ICUCR4	__reg16(OPSPUT_LCD_BASE + 0x300026)
+#define OPSPUT_LCD_ICUCR16	__reg16(OPSPUT_LCD_BASE + 0x300030)
+#define OPSPUT_LCD_ICUCR17	__reg16(OPSPUT_LCD_BASE + 0x300032)
+#define OPSPUT_LCD_ICUCR18	__reg16(OPSPUT_LCD_BASE + 0x300034)
+#define OPSPUT_LCD_ICUCR19	__reg16(OPSPUT_LCD_BASE + 0x300036)
+#define OPSPUT_LCD_ICUCR21	__reg16(OPSPUT_LCD_BASE + 0x30003a)
+
+#endif /* _OPSPUT_OPSPUT_LCD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_pld.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_pld.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/opsput/opsput_pld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/opsput/opsput_pld.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,255 @@
+#ifndef _OPSPUT_OPSPUT_PLD_H
+#define _OPSPUT_OPSPUT_PLD_H
+
+/*
+ * include/asm-m32r/opsput/opsput_pld.h
+ *
+ * Definitions for Programable Logic Device(PLD) on OPSPUT board.
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#define PLD_PLAT_BASE		0x1cc00000
+
+#ifndef __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define PLD_BASE		(PLD_PLAT_BASE /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(PLD_PLAT_BASE + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif /* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+#define PLD_CFVENCR		__reg16(PLD_BASE + 0x0008)
+#define PLD_CFCR0		__reg16(PLD_BASE + 0x000a)
+#define PLD_CFCR1		__reg16(PLD_BASE + 0x000c)
+#define PLD_IDERSTCR		__reg16(PLD_BASE + 0x0010)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ *  ICUCR16:	control register for SIO0 receive interrupt
+ *  ICUCR17:	control register for SIO0 send interrupt
+ */
+#if !defined(CONFIG_PLAT_USRV)
+#define PLD_IRQ_INT0		(OPSPUT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_INT1		(OPSPUT_PLD_IRQ_BASE + 1)	/* reserved */
+#define PLD_IRQ_INT2		(OPSPUT_PLD_IRQ_BASE + 2)	/* reserved */
+#define PLD_IRQ_CFIREQ		(OPSPUT_PLD_IRQ_BASE + 3)	/* CF IREQ */
+#define PLD_IRQ_CFC_INSERT	(OPSPUT_PLD_IRQ_BASE + 4)	/* CF Insert */
+#define PLD_IRQ_CFC_EJECT	(OPSPUT_PLD_IRQ_BASE + 5)	/* CF Eject */
+#define PLD_IRQ_EXINT		(OPSPUT_PLD_IRQ_BASE + 6)	/* EXINT */
+#define PLD_IRQ_INT7		(OPSPUT_PLD_IRQ_BASE + 7)	/* reserved */
+#define PLD_IRQ_INT8		(OPSPUT_PLD_IRQ_BASE + 8)	/* reserved */
+#define PLD_IRQ_INT9		(OPSPUT_PLD_IRQ_BASE + 9)	/* reserved */
+#define PLD_IRQ_INT10		(OPSPUT_PLD_IRQ_BASE + 10)	/* reserved */
+#define PLD_IRQ_MMCCARD		(OPSPUT_PLD_IRQ_BASE + 11)	/* MMC Insert/Eject */
+#define PLD_IRQ_INT12		(OPSPUT_PLD_IRQ_BASE + 12)	/* reserved */
+#define PLD_IRQ_SC_ERROR	(OPSPUT_PLD_IRQ_BASE + 13)	/* SC error */
+#define PLD_IRQ_SC_RCV		(OPSPUT_PLD_IRQ_BASE + 14)	/* SC receive */
+#define PLD_IRQ_SC_SND		(OPSPUT_PLD_IRQ_BASE + 15)	/* SC send */
+#define PLD_IRQ_SIO0_RCV	(OPSPUT_PLD_IRQ_BASE + 16)	/* SIO receive */
+#define PLD_IRQ_SIO0_SND	(OPSPUT_PLD_IRQ_BASE + 17)	/* SIO send */
+#define PLD_IRQ_INT18		(OPSPUT_PLD_IRQ_BASE + 18)	/* reserved */
+#define PLD_IRQ_INT19		(OPSPUT_PLD_IRQ_BASE + 19)	/* reserved */
+#define PLD_IRQ_INT20		(OPSPUT_PLD_IRQ_BASE + 20)	/* reserved */
+#define PLD_IRQ_INT21		(OPSPUT_PLD_IRQ_BASE + 21)	/* reserved */
+#define PLD_IRQ_INT22		(OPSPUT_PLD_IRQ_BASE + 22)	/* reserved */
+#define PLD_IRQ_INT23		(OPSPUT_PLD_IRQ_BASE + 23)	/* reserved */
+#define PLD_IRQ_INT24		(OPSPUT_PLD_IRQ_BASE + 24)	/* reserved */
+#define PLD_IRQ_INT25		(OPSPUT_PLD_IRQ_BASE + 25)	/* reserved */
+#define PLD_IRQ_INT26		(OPSPUT_PLD_IRQ_BASE + 26)	/* reserved */
+#define PLD_IRQ_INT27		(OPSPUT_PLD_IRQ_BASE + 27)	/* reserved */
+#define PLD_IRQ_INT28		(OPSPUT_PLD_IRQ_BASE + 28)	/* reserved */
+#define PLD_IRQ_INT29		(OPSPUT_PLD_IRQ_BASE + 29)	/* reserved */
+#define PLD_IRQ_INT30		(OPSPUT_PLD_IRQ_BASE + 30)	/* reserved */
+#define PLD_IRQ_INT31		(OPSPUT_PLD_IRQ_BASE + 31)	/* reserved */
+
+#else	/* CONFIG_PLAT_USRV */
+
+#define PLD_IRQ_INT0		(OPSPUT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_INT1		(OPSPUT_PLD_IRQ_BASE + 1)	/* reserved */
+#define PLD_IRQ_INT2		(OPSPUT_PLD_IRQ_BASE + 2)	/* reserved */
+#define PLD_IRQ_CF0		(OPSPUT_PLD_IRQ_BASE + 3)	/* CF0# */
+#define PLD_IRQ_CF1		(OPSPUT_PLD_IRQ_BASE + 4)	/* CF1# */
+#define PLD_IRQ_CF2		(OPSPUT_PLD_IRQ_BASE + 5)	/* CF2# */
+#define PLD_IRQ_CF3		(OPSPUT_PLD_IRQ_BASE + 6)	/* CF3# */
+#define PLD_IRQ_CF4		(OPSPUT_PLD_IRQ_BASE + 7)	/* CF4# */
+#define PLD_IRQ_INT8		(OPSPUT_PLD_IRQ_BASE + 8)	/* reserved */
+#define PLD_IRQ_INT9		(OPSPUT_PLD_IRQ_BASE + 9)	/* reserved */
+#define PLD_IRQ_INT10		(OPSPUT_PLD_IRQ_BASE + 10)	/* reserved */
+#define PLD_IRQ_INT11		(OPSPUT_PLD_IRQ_BASE + 11)	/* reserved */
+#define PLD_IRQ_UART0		(OPSPUT_PLD_IRQ_BASE + 12)	/* UARTIRQ0 */
+#define PLD_IRQ_UART1		(OPSPUT_PLD_IRQ_BASE + 13)	/* UARTIRQ1 */
+#define PLD_IRQ_INT14		(OPSPUT_PLD_IRQ_BASE + 14)	/* reserved */
+#define PLD_IRQ_INT15		(OPSPUT_PLD_IRQ_BASE + 15)	/* reserved */
+#define PLD_IRQ_SNDINT		(OPSPUT_PLD_IRQ_BASE + 16)	/* SNDINT# */
+#define PLD_IRQ_INT17		(OPSPUT_PLD_IRQ_BASE + 17)	/* reserved */
+#define PLD_IRQ_INT18		(OPSPUT_PLD_IRQ_BASE + 18)	/* reserved */
+#define PLD_IRQ_INT19		(OPSPUT_PLD_IRQ_BASE + 19)	/* reserved */
+#define PLD_IRQ_INT20		(OPSPUT_PLD_IRQ_BASE + 20)	/* reserved */
+#define PLD_IRQ_INT21		(OPSPUT_PLD_IRQ_BASE + 21)	/* reserved */
+#define PLD_IRQ_INT22		(OPSPUT_PLD_IRQ_BASE + 22)	/* reserved */
+#define PLD_IRQ_INT23		(OPSPUT_PLD_IRQ_BASE + 23)	/* reserved */
+#define PLD_IRQ_INT24		(OPSPUT_PLD_IRQ_BASE + 24)	/* reserved */
+#define PLD_IRQ_INT25		(OPSPUT_PLD_IRQ_BASE + 25)	/* reserved */
+#define PLD_IRQ_INT26		(OPSPUT_PLD_IRQ_BASE + 26)	/* reserved */
+#define PLD_IRQ_INT27		(OPSPUT_PLD_IRQ_BASE + 27)	/* reserved */
+#define PLD_IRQ_INT28		(OPSPUT_PLD_IRQ_BASE + 28)	/* reserved */
+#define PLD_IRQ_INT29		(OPSPUT_PLD_IRQ_BASE + 29)	/* reserved */
+#define PLD_IRQ_INT30		(OPSPUT_PLD_IRQ_BASE + 30)	/* reserved */
+
+#endif	/* CONFIG_PLAT_USRV */
+
+#define PLD_ICUISTS		__reg16(PLD_BASE + 0x8002)
+#define PLD_ICUISTS_VECB_MASK	(0xf000)
+#define PLD_ICUISTS_VECB(x)	((x) & PLD_ICUISTS_VECB_MASK)
+#define PLD_ICUISTS_ISN_MASK	(0x07c0)
+#define PLD_ICUISTS_ISN(x)	((x) & PLD_ICUISTS_ISN_MASK)
+#define PLD_ICUIREQ0		__reg16(PLD_BASE + 0x8004)
+#define PLD_ICUIREQ1		__reg16(PLD_BASE + 0x8006)
+#define PLD_ICUCR1		__reg16(PLD_BASE + 0x8100)
+#define PLD_ICUCR2		__reg16(PLD_BASE + 0x8102)
+#define PLD_ICUCR3		__reg16(PLD_BASE + 0x8104)
+#define PLD_ICUCR4		__reg16(PLD_BASE + 0x8106)
+#define PLD_ICUCR5		__reg16(PLD_BASE + 0x8108)
+#define PLD_ICUCR6		__reg16(PLD_BASE + 0x810a)
+#define PLD_ICUCR7		__reg16(PLD_BASE + 0x810c)
+#define PLD_ICUCR8		__reg16(PLD_BASE + 0x810e)
+#define PLD_ICUCR9		__reg16(PLD_BASE + 0x8110)
+#define PLD_ICUCR10		__reg16(PLD_BASE + 0x8112)
+#define PLD_ICUCR11		__reg16(PLD_BASE + 0x8114)
+#define PLD_ICUCR12		__reg16(PLD_BASE + 0x8116)
+#define PLD_ICUCR13		__reg16(PLD_BASE + 0x8118)
+#define PLD_ICUCR14		__reg16(PLD_BASE + 0x811a)
+#define PLD_ICUCR15		__reg16(PLD_BASE + 0x811c)
+#define PLD_ICUCR16		__reg16(PLD_BASE + 0x811e)
+#define PLD_ICUCR17		__reg16(PLD_BASE + 0x8120)
+#define PLD_ICUCR_IEN		(0x1000)
+#define PLD_ICUCR_IREQ		(0x0100)
+#define PLD_ICUCR_ISMOD00	(0x0000)	/* Low edge */
+#define PLD_ICUCR_ISMOD01	(0x0010)	/* Low level */
+#define PLD_ICUCR_ISMOD02	(0x0020)	/* High edge */
+#define PLD_ICUCR_ISMOD03	(0x0030)	/* High level */
+#define PLD_ICUCR_ILEVEL0	(0x0000)
+#define PLD_ICUCR_ILEVEL1	(0x0001)
+#define PLD_ICUCR_ILEVEL2	(0x0002)
+#define PLD_ICUCR_ILEVEL3	(0x0003)
+#define PLD_ICUCR_ILEVEL4	(0x0004)
+#define PLD_ICUCR_ILEVEL5	(0x0005)
+#define PLD_ICUCR_ILEVEL6	(0x0006)
+#define PLD_ICUCR_ILEVEL7	(0x0007)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+#define PLD_CPCR_CF		0x0001
+#define PLD_CPCR_MMC		0x0002
+
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIO0 */
+#define PLD_ESIO0CR		__reg16(PLD_BASE + 0x20000)
+#define	PLD_ESIO0CR_TXEN	0x0001
+#define	PLD_ESIO0CR_RXEN	0x0002
+#define PLD_ESIO0MOD0		__reg16(PLD_BASE + 0x20002)
+#define	PLD_ESIO0MOD0_CTSS	0x0040
+#define	PLD_ESIO0MOD0_RTSS	0x0080
+#define PLD_ESIO0MOD1		__reg16(PLD_BASE + 0x20004)
+#define	PLD_ESIO0MOD1_LMFS	0x0010
+#define PLD_ESIO0STS		__reg16(PLD_BASE + 0x20006)
+#define	PLD_ESIO0STS_TEMP	0x0001
+#define	PLD_ESIO0STS_TXCP	0x0002
+#define	PLD_ESIO0STS_RXCP	0x0004
+#define	PLD_ESIO0STS_TXSC	0x0100
+#define	PLD_ESIO0STS_RXSC	0x0200
+#define PLD_ESIO0STS_TXREADY	(PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP)
+#define PLD_ESIO0INTCR		__reg16(PLD_BASE + 0x20008)
+#define	PLD_ESIO0INTCR_TXIEN	0x0002
+#define	PLD_ESIO0INTCR_RXCEN	0x0004
+#define PLD_ESIO0BAUR		__reg16(PLD_BASE + 0x2000a)
+#define PLD_ESIO0TXB		__reg16(PLD_BASE + 0x2000c)
+#define PLD_ESIO0RXB		__reg16(PLD_BASE + 0x2000e)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif /* _OPSPUT_OPSPUT_PLD.H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/page.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/page.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,87 @@
+#ifndef _ASM_M32R_PAGE_H
+#define _ASM_M32R_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+extern void clear_page(void *to);
+extern void copy_page(void *to, void *from);
+
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+
+#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
+	alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+#define pte_val(x)	((x).pte)
+#define PTE_MASK	PAGE_MASK
+
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * This handles the memory map.. We could make this a config
+ * option, but too many people screw it up, and too few need
+ * it.
+ *
+ * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
+ * a virtual address space of one gigabyte, which limits the
+ * amount of physical memory you can use to about 950MB.
+ *
+ * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+ * and CONFIG_HIGHMEM64G options in the kernel configuration.
+ */
+
+#define __MEMORY_START  CONFIG_MEMORY_START
+#define __MEMORY_SIZE   CONFIG_MEMORY_SIZE
+
+#ifdef CONFIG_MMU
+#define __PAGE_OFFSET  (0x80000000)
+#else
+#define __PAGE_OFFSET  (0x00000000)
+#endif
+
+#define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
+#define __pa(x)			((unsigned long)(x) - PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long)(x) + PAGE_OFFSET))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define PFN_BASE		(CONFIG_MEMORY_START >> PAGE_SHIFT)
+#define ARCH_PFN_OFFSET		PFN_BASE
+#define pfn_valid(pfn)		(((pfn) - PFN_BASE) < max_mapnr)
+#endif  /* !CONFIG_DISCONTIGMEM */
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC )
+
+#define devmem_is_allowed(x) 1
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_M32R_PAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/param.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/param.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/param.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef _ASM_M32R_PARAM_H
+#define _ASM_M32R_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 */
+
+#endif /* _ASM_M32R_PARAM_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef _ASM_M32R_PCI_H
+#define _ASM_M32R_PCI_H
+
+#include <asm-generic/pci.h>
+
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+#endif /* _ASM_M32R_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/percpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __ARCH_M32R_PERCPU__
+#define __ARCH_M32R_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ARCH_M32R_PERCPU__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,76 @@
+#ifndef _ASM_M32R_PGALLOC_H
+#define _ASM_M32R_PGALLOC_H
+
+#include <linux/mm.h>
+
+#include <asm/io.h>
+
+#define pmd_populate_kernel(mm, pmd, pte)	\
+	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
+
+static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+	pgtable_t pte)
+{
+	set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Allocate and free page tables.
+ */
+static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+
+	return pgd;
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	free_page((unsigned long)pgd);
+}
+
+static __inline__ pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+	unsigned long address)
+{
+	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+
+	return pte;
+}
+
+static __inline__ pgtable_t pte_alloc_one(struct mm_struct *mm,
+	unsigned long address)
+{
+	struct page *pte = alloc_page(GFP_KERNEL|__GFP_ZERO);
+
+	pgtable_page_ctor(pte);
+	return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+	pgtable_page_dtor(pte);
+	__free_page(pte);
+}
+
+#define __pte_free_tlb(tlb, pte)	pte_free((tlb)->mm, (pte))
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+
+#define pmd_alloc_one(mm, addr)		({ BUG(); ((pmd_t *)2); })
+#define pmd_free(mm, x)			do { } while (0)
+#define __pmd_free_tlb(tlb, x)		do { } while (0)
+#define pgd_populate(mm, pmd, pte)	BUG()
+
+#define check_pgt_cache()	do { } while (0)
+
+#endif /* _ASM_M32R_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgtable-2level.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgtable-2level.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgtable-2level.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgtable-2level.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,78 @@
+#ifndef _ASM_M32R_PGTABLE_2LEVEL_H
+#define _ASM_M32R_PGTABLE_2LEVEL_H
+#ifdef __KERNEL__
+
+/*
+ * traditional M32R two-level paging structure:
+ */
+
+#define PGDIR_SHIFT	22
+#define PTRS_PER_PGD	1024
+
+/*
+ * the M32R is two-level, so we don't really have any
+ * PMD directory physically.
+ */
+#define PMD_SHIFT	22
+#define PTRS_PER_PMD	1
+
+#define PTRS_PER_PTE	1024
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd)	{ return 0; }
+static inline int pgd_bad(pgd_t pgd)	{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+#define pgd_clear(xp)				do { } while (0)
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+/*
+ * (pmds are folded into pgds so this doesnt get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+
+#define pgd_page_vaddr(pgd) \
+((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pgd_page(pgd)	(mem_map + ((pgd_val(pgd) >> PAGE_SHIFT) - PFN_BASE))
+#endif /* !CONFIG_DISCONTIGMEM */
+
+static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
+{
+	return (pmd_t *) dir;
+}
+
+#define ptep_get_and_clear(mm,addr,xp)	__pte(xchg(&(xp)->pte, 0))
+#define pte_same(a, b)		(pte_val(a) == pte_val(b))
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_none(x)		(!pte_val(x))
+#define pte_pfn(x)		(pte_val(x) >> PAGE_SHIFT)
+#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define PTE_FILE_MAX_BITS	29
+#define pte_to_pgoff(pte)	(((pte_val(pte) >> 2) & 0x7f) | (((pte_val(pte) >> 10)) << 7))
+#define pgoff_to_pte(off)	((pte_t) { (((off) & 0x7f) << 2) | (((off) >> 7) << 10) | _PAGE_FILE })
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_M32R_PGTABLE_2LEVEL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/pgtable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,363 @@
+#ifndef _ASM_M32R_PGTABLE_H
+#define _ASM_M32R_PGTABLE_H
+
+#include <asm-generic/4level-fixup.h>
+
+#ifdef __KERNEL__
+/*
+ * The Linux memory management assumes a three-level page table setup. On
+ * the M32R, we use that, but "fold" the mid level into the top-level page
+ * table, so that we physically have the same two-level page table as the
+ * M32R mmu expects.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the M32R page table tree.
+ */
+
+/* CAUTION!: If you change macro definitions in this file, you might have to
+ * change arch/m32r/mmu.S manually.
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/threads.h>
+#include <linux/bitops.h>
+#include <asm/processor.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+struct mm_struct;
+struct vm_area_struct;
+
+extern pgd_t swapper_pg_dir[1024];
+extern void paging_init(void);
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[1024];
+#define ZERO_PAGE(vaddr)	(virt_to_page(empty_zero_page))
+
+#endif /* !__ASSEMBLY__ */
+
+#ifndef __ASSEMBLY__
+#include <asm/pgtable-2level.h>
+#endif
+
+#define pgtable_cache_init()	do { } while (0)
+
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE - 1))
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
+
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS	0
+
+#ifndef __ASSEMBLY__
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_START		KSEG2
+#define VMALLOC_END		KSEG3
+
+/*
+ *     M32R TLB format
+ *
+ *     [0]    [1:19]           [20:23]       [24:31]
+ *     +-----------------------+----+-------------+
+ *     |          VPN          |0000|    ASID     |
+ *     +-----------------------+----+-------------+
+ *     +-+---------------------+----+-+---+-+-+-+-+
+ *     |0         PPN          |0000|N|AC |L|G|V| |
+ *     +-+---------------------+----+-+---+-+-+-+-+
+ *                                     RWX
+ */
+
+#define _PAGE_BIT_DIRTY		0	/* software: page changed */
+#define _PAGE_BIT_FILE		0	/* when !present: nonlinear file
+					   mapping */
+#define _PAGE_BIT_PRESENT	1	/* Valid: page is valid */
+#define _PAGE_BIT_GLOBAL	2	/* Global */
+#define _PAGE_BIT_LARGE		3	/* Large */
+#define _PAGE_BIT_EXEC		4	/* Execute */
+#define _PAGE_BIT_WRITE		5	/* Write */
+#define _PAGE_BIT_READ		6	/* Read */
+#define _PAGE_BIT_NONCACHABLE	7	/* Non cachable */
+#define _PAGE_BIT_ACCESSED	8	/* software: page referenced */
+#define _PAGE_BIT_PROTNONE	9	/* software: if not present */
+
+#define _PAGE_DIRTY		(1UL << _PAGE_BIT_DIRTY)
+#define _PAGE_FILE		(1UL << _PAGE_BIT_FILE)
+#define _PAGE_PRESENT		(1UL << _PAGE_BIT_PRESENT)
+#define _PAGE_GLOBAL		(1UL << _PAGE_BIT_GLOBAL)
+#define _PAGE_LARGE		(1UL << _PAGE_BIT_LARGE)
+#define _PAGE_EXEC		(1UL << _PAGE_BIT_EXEC)
+#define _PAGE_WRITE		(1UL << _PAGE_BIT_WRITE)
+#define _PAGE_READ		(1UL << _PAGE_BIT_READ)
+#define _PAGE_NONCACHABLE	(1UL << _PAGE_BIT_NONCACHABLE)
+#define _PAGE_ACCESSED		(1UL << _PAGE_BIT_ACCESSED)
+#define _PAGE_PROTNONE		(1UL << _PAGE_BIT_PROTNONE)
+
+#define _PAGE_TABLE	\
+	( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \
+	| _PAGE_DIRTY )
+#define _KERNPG_TABLE	\
+	( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \
+	| _PAGE_DIRTY )
+#define _PAGE_CHG_MASK	\
+	( PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY )
+
+#ifdef CONFIG_MMU
+#define PAGE_NONE	\
+	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED	\
+	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_SHARED_EXEC \
+	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ \
+		| _PAGE_ACCESSED)
+#define PAGE_COPY	\
+	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_COPY_EXEC	\
+	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_READONLY	\
+	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED)
+#define PAGE_READONLY_EXEC \
+	__pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED)
+
+#define __PAGE_KERNEL	\
+	( _PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ | _PAGE_DIRTY \
+	| _PAGE_ACCESSED )
+#define __PAGE_KERNEL_RO	( __PAGE_KERNEL & ~_PAGE_WRITE )
+#define __PAGE_KERNEL_NOCACHE	( __PAGE_KERNEL | _PAGE_NONCACHABLE)
+
+#define MAKE_GLOBAL(x)	__pgprot((x) | _PAGE_GLOBAL)
+
+#define PAGE_KERNEL		MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO		MAKE_GLOBAL(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+
+#else
+#define PAGE_NONE		__pgprot(0)
+#define PAGE_SHARED		__pgprot(0)
+#define PAGE_SHARED_EXEC	__pgprot(0)
+#define PAGE_COPY		__pgprot(0)
+#define PAGE_COPY_EXEC		__pgprot(0)
+#define PAGE_READONLY		__pgprot(0)
+#define PAGE_READONLY_EXEC	__pgprot(0)
+
+#define PAGE_KERNEL		__pgprot(0)
+#define PAGE_KERNEL_RO		__pgprot(0)
+#define PAGE_KERNEL_NOCACHE	__pgprot(0)
+#endif /* CONFIG_MMU */
+
+	/* xwr */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY_EXEC
+#define __P101	PAGE_READONLY_EXEC
+#define __P110	PAGE_COPY_EXEC
+#define __P111	PAGE_COPY_EXEC
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY_EXEC
+#define __S101	PAGE_READONLY_EXEC
+#define __S110	PAGE_SHARED_EXEC
+#define __S111	PAGE_SHARED_EXEC
+
+/* page table for 0-4MB for everybody */
+
+#define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
+#define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
+#define	pmd_bad(x)	((pmd_val(x) & ~PAGE_MASK) != _KERNPG_TABLE)
+
+#define pages_to_mb(x)	((x) >> (20 - PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_dirty(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_DIRTY;
+}
+
+static inline int pte_young(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_ACCESSED;
+}
+
+static inline int pte_write(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_WRITE;
+}
+
+/*
+ * The following only works if pte_present() is not true.
+ */
+static inline int pte_file(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_FILE;
+}
+
+static inline int pte_special(pte_t pte)
+{
+	return 0;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	pte_val(pte) &= ~_PAGE_DIRTY;
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	pte_val(pte) &= ~_PAGE_ACCESSED;
+	return pte;
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	pte_val(pte) &= ~_PAGE_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_DIRTY;
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_ACCESSED;
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+	return pte;
+}
+
+static inline  int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+{
+	return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+}
+
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	clear_bit(_PAGE_BIT_WRITE, ptep);
+}
+
+/*
+ * Macro and implementation to make a page protection as uncachable.
+ */
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+	unsigned long prot = pgprot_val(_prot);
+
+	prot |= _PAGE_NONCACHABLE;
+	return __pgprot(prot);
+}
+
+#define pgprot_writecombine(prot) pgprot_noncached(prot)
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), pgprot)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) \
+		| pgprot_val(newprot)));
+
+	return pte;
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{
+	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
+}
+
+#define pmd_page_vaddr(pmd)	\
+	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pmd_page(pmd)	(mem_map + ((pmd_val(pmd) >> PAGE_SHIFT) - PFN_BASE))
+#endif /* !CONFIG_DISCONTIGMEM */
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address)	\
+	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+
+#define pgd_offset(mm, address)	((mm)->pgd + pgd_index(address))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address)	pgd_offset(&init_mm, address)
+
+#define pmd_index(address)	\
+	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+
+#define pte_index(address)	\
+	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address)	\
+	((pte_t *)pmd_page_vaddr(*(dir)) + pte_index(address))
+#define pte_offset_map(dir, address)	\
+	((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_offset_map_nested(dir, address)	pte_offset_map(dir, address)
+#define pte_unmap(pte)		do { } while (0)
+#define pte_unmap_nested(pte)	do { } while (0)
+
+/* Encode and de-code a swap entry */
+#define __swp_type(x)			(((x).val >> 2) & 0x1f)
+#define __swp_offset(x)			((x).val >> 10)
+#define __swp_entry(type, offset)	\
+	((swp_entry_t) { ((type) << 2) | ((offset) << 10) })
+#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+#endif /* !__ASSEMBLY__ */
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
+		remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTE_SAME
+#include <asm-generic/pgtable.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_M32R_PGTABLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/poll.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/poll.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/poll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/poll.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/posix_types.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/posix_types.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/posix_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/posix_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,118 @@
+#ifndef _ASM_M32R_POSIX_TYPES_H
+#define _ASM_M32R_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef	__FD_SET
+static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef	__FD_CLR
+static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+
+#undef	__FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef	__FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
+{
+	unsigned long *__tmp = __p->fds_bits;
+	int __i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 16:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			__tmp[ 8] = 0; __tmp[ 9] = 0;
+			__tmp[10] = 0; __tmp[11] = 0;
+			__tmp[12] = 0; __tmp[13] = 0;
+			__tmp[14] = 0; __tmp[15] = 0;
+			return;
+
+		case 8:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			return;
+
+		case 4:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			return;
+		}
+	}
+	__i = __FDSET_LONGS;
+	while (__i) {
+		__i--;
+		*__tmp = 0;
+		__tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif  /* _ASM_M32R_POSIX_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/processor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,147 @@
+#ifndef _ASM_M32R_PROCESSOR_H
+#define _ASM_M32R_PROCESSOR_H
+
+/*
+ * include/asm-m32r/processor.h
+ *
+ * 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  Linus Torvalds
+ * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <linux/kernel.h>
+#include <asm/cache.h>
+#include <asm/ptrace.h>  /* pt_regs */
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ *  Members of this structure are referenced in head.S, so think twice
+ *  before touching them. [mj]
+ */
+
+struct cpuinfo_m32r {
+	unsigned long pgtable_cache_sz;
+	unsigned long cpu_clock;
+	unsigned long bus_clock;
+	unsigned long timer_divide;
+	unsigned long loops_per_jiffy;
+};
+
+/*
+ * capabilities of CPUs
+ */
+
+extern struct cpuinfo_m32r boot_cpu_data;
+
+#ifdef CONFIG_SMP
+extern struct cpuinfo_m32r cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+#endif
+
+/*
+ * User space process size: 2GB (default).
+ */
+#ifdef CONFIG_MMU
+#define TASK_SIZE  (0x80000000UL)
+#else
+#define TASK_SIZE  (0x00400000UL)
+#endif
+
+#ifdef __KERNEL__
+#define STACK_TOP	TASK_SIZE
+#define STACK_TOP_MAX	STACK_TOP
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE / 3)
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAX_TRAPS 10
+
+struct debug_trap {
+	int nr_trap;
+	unsigned long	addr[MAX_TRAPS];
+	unsigned long	insn[MAX_TRAPS];
+};
+
+struct thread_struct {
+	unsigned long address;
+	unsigned long trap_no;		/* Trap number  */
+	unsigned long error_code;	/* Error code of trap */
+	unsigned long lr;		/* saved pc */
+	unsigned long sp;		/* user stack pointer */
+	struct debug_trap debug_trap;
+};
+
+#define INIT_SP	(sizeof(init_stack) + (unsigned long) &init_stack)
+
+#define INIT_THREAD	{	\
+	.sp = INIT_SP,		\
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+
+/* User process Backup PSW */
+#define USERPS_BPSW (M32R_PSW_BSM|M32R_PSW_BIE|M32R_PSW_BPM)
+
+#define start_thread(regs, new_pc, new_spu) 				\
+	do {								\
+		set_fs(USER_DS); 					\
+		regs->psw = (regs->psw | USERPS_BPSW) & 0x0000FFFFUL;	\
+		regs->bpc = new_pc;					\
+		regs->spu = new_spu;					\
+	} while (0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+struct mm_struct;
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+#define prepare_to_copy(tsk)	do { } while (0)
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Copy and release all segment info associated with a VM */
+extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
+extern void release_segments(struct mm_struct * mm);
+
+extern unsigned long thread_saved_pc(struct task_struct *);
+
+/* Copy and release all segment info associated with a VM */
+#define copy_segments(p, mm)  do { } while (0)
+#define release_segments(mm)  do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+#define KSTK_EIP(tsk)  ((tsk)->thread.lr)
+#define KSTK_ESP(tsk)  ((tsk)->thread.sp)
+
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+#define cpu_relax()	barrier()
+
+#endif /* _ASM_M32R_PROCESSOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ptrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,148 @@
+#ifndef _ASM_M32R_PTRACE_H
+#define _ASM_M32R_PTRACE_H
+
+/*
+ * linux/include/asm-m32r/ptrace.h
+ *
+ * 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.
+ *
+ * M32R version:
+ *   Copyright (C) 2001-2002, 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+/* 0 - 13 are integer registers (general purpose registers).  */
+#define PT_R4		0
+#define PT_R5		1
+#define PT_R6		2
+#define PT_REGS 	3
+#define PT_R0		4
+#define PT_R1		5
+#define PT_R2		6
+#define PT_R3		7
+#define PT_R7		8
+#define PT_R8		9
+#define PT_R9		10
+#define PT_R10		11
+#define PT_R11		12
+#define PT_R12		13
+#define PT_SYSCNR	14
+#define PT_R13		PT_FP
+#define PT_R14		PT_LR
+#define PT_R15		PT_SP
+
+/* processor status and miscellaneous context registers.  */
+#define PT_ACC0H	15
+#define PT_ACC0L	16
+#define PT_ACC1H	17	/* ISA_DSP_LEVEL2 only */
+#define PT_ACC1L	18	/* ISA_DSP_LEVEL2 only */
+#define PT_PSW		19
+#define PT_BPC		20
+#define PT_BBPSW	21
+#define PT_BBPC		22
+#define PT_SPU		23
+#define PT_FP		24
+#define PT_LR		25
+#define PT_SPI		26
+#define PT_ORIGR0	27
+
+/* virtual pt_reg entry for gdb */
+#define PT_PC		30
+#define PT_CBR		31
+#define PT_EVB		32
+
+
+/* Control registers.  */
+#define SPR_CR0 PT_PSW
+#define SPR_CR1 PT_CBR		/* read only */
+#define SPR_CR2 PT_SPI
+#define SPR_CR3 PT_SPU
+#define SPR_CR4
+#define SPR_CR5 PT_EVB		/* part of M32R/E, M32R/I core only */
+#define SPR_CR6 PT_BPC
+#define SPR_CR7
+#define SPR_CR8 PT_BBPSW
+#define SPR_CR9
+#define SPR_CR10
+#define SPR_CR11
+#define SPR_CR12
+#define SPR_CR13 PT_WR
+#define SPR_CR14 PT_BBPC
+#define SPR_CR15
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+struct pt_regs {
+	/* Saved main processor registers. */
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	struct pt_regs *pt_regs;
+	unsigned long r0;
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long r10;
+	unsigned long r11;
+	unsigned long r12;
+	long syscall_nr;
+
+	/* Saved main processor status and miscellaneous context registers. */
+	unsigned long acc0h;
+	unsigned long acc0l;
+	unsigned long acc1h;	/* ISA_DSP_LEVEL2 only */
+	unsigned long acc1l;	/* ISA_DSP_LEVEL2 only */
+	unsigned long psw;
+	unsigned long bpc;		/* saved PC for TRAP syscalls */
+	unsigned long bbpsw;
+	unsigned long bbpc;
+	unsigned long spu;		/* saved user stack */
+	unsigned long fp;
+	unsigned long lr;		/* saved PC for JL syscalls */
+	unsigned long spi;		/* saved kernel stack */
+	unsigned long orig_r0;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+
+#define PTRACE_OLDSETOPTIONS	21
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD	0x00000001
+
+#ifdef __KERNEL__
+
+#include <asm/m32r.h>		/* M32R_PSW_BSM, M32R_PSW_BPM */
+
+struct task_struct;
+extern void init_debug_traps(struct task_struct *);
+#define arch_ptrace_attach(child) \
+	init_debug_traps(child)
+
+#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
+#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
+#elif defined(CONFIG_ISA_M32R)
+#define user_mode(regs) ((M32R_PSW_BSM & (regs)->psw) != 0)
+#else
+#error unknown isa configuration
+#endif
+
+#define instruction_pointer(regs) ((regs)->bpc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+extern void show_regs(struct pt_regs *);
+
+extern void withdraw_debug_trap(struct pt_regs *regs);
+
+#define task_pt_regs(task) \
+        ((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE) - 1)
+
+#endif /* __KERNEL */
+
+#endif /* _ASM_M32R_PTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/resource.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/resource.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/resource.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/resource.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_RESOURCE_H
+#define _ASM_M32R_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif  /* _ASM_M32R_RESOURCE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/rtc.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/rtc.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+#ifndef __RTC_H__
+#define __RTC_H__
+
+   /* Dallas DS1302 clock/calendar register numbers. */
+#  define RTC_SECONDS      0
+#  define RTC_MINUTES      1
+#  define RTC_HOURS        2
+#  define RTC_DAY_OF_MONTH 3
+#  define RTC_MONTH        4
+#  define RTC_WEEKDAY      5
+#  define RTC_YEAR         6
+#  define RTC_CONTROL      7
+
+   /* Bits in CONTROL register. */
+#  define RTC_CONTROL_WRITEPROTECT 	0x80
+#  define RTC_TRICKLECHARGER 		8
+
+  /* Bits in TRICKLECHARGER register TCS TCS TCS TCS DS DS RS RS. */
+#  define RTC_TCR_PATTERN 	0xA0	/* 1010xxxx */
+#  define RTC_TCR_1DIOD 	0x04	/* xxxx01xx */
+#  define RTC_TCR_2DIOD 	0x08	/* xxxx10xx */
+#  define RTC_TCR_DISABLED 	0x00	/* xxxxxx00 Disabled */
+#  define RTC_TCR_2KOHM 	0x01	/* xxxxxx01 2KOhm */
+#  define RTC_TCR_4KOHM 	0x02	/* xxxxxx10 4kOhm */
+#  define RTC_TCR_8KOHM 	0x03	/* xxxxxx11 8kOhm */
+
+#ifdef CONFIG_DS1302
+extern unsigned char ds1302_readreg(int reg);
+extern void ds1302_writereg(int reg, unsigned char val);
+extern int ds1302_init(void);
+#  define CMOS_READ(x) ds1302_readreg(x)
+#  define CMOS_WRITE(val,reg) ds1302_writereg(reg,val)
+#  define RTC_INIT() ds1302_init()
+#else
+  /* No RTC configured so we shouldn't try to access any. */
+#  define CMOS_READ(x) 42
+#  define CMOS_WRITE(x,y)
+#  define RTC_INIT() (-1)
+#endif
+
+/*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel
+ * source is self contained, allowing cross-compiles, etc. etc.
+ */
+struct rtc_time {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+};
+
+/* ioctl() calls that are permitted to the /dev/rtc interface. */
+#define RTC_MAGIC 'p'
+#define RTC_RD_TIME		_IOR(RTC_MAGIC, 0x09, struct rtc_time)	/* Read RTC time. */
+#define RTC_SET_TIME		_IOW(RTC_MAGIC, 0x0a, struct rtc_time)	/* Set RTC time. */
+#define RTC_SET_CHARGE  	_IOW(RTC_MAGIC, 0x0b, int)
+#define RTC_MAX_IOCTL 0x0b
+
+#endif /* __RTC_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/s1d13806.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/s1d13806.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/s1d13806.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/s1d13806.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,199 @@
+//----------------------------------------------------------------------------
+//
+//  File generated by S1D13806CFG.EXE
+//
+//  Copyright (c) 2000,2001 Epson Research and Development, Inc.
+//  All rights reserved.
+//
+//----------------------------------------------------------------------------
+
+// Panel:  (active)  640x480 77Hz STN Single 8-bit (PCLK=CLKI=25.175MHz)
+// Memory: Embedded SDRAM (MCLK=CLKI3=50.000MHz) (BUSCLK=33.333MHz)
+
+#define SWIVEL_VIEW		0	/* 0:none, 1:90 not completed */
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+
+    {0x0001,0x00},   // Miscellaneous Register
+    {0x01FC,0x00},   // Display Mode Register
+#if defined(CONFIG_PLAT_MAPPI)
+    {0x0004,0x00},   // General IO Pins Configuration Register 0
+    {0x0005,0x00},   // General IO Pins Configuration Register 1
+    {0x0008,0x00},   // General IO Pins Control Register 0
+    {0x0009,0x00},   // General IO Pins Control Register 1
+    {0x0010,0x00},   // Memory Clock Configuration Register
+    {0x0014,0x00},   // LCD Pixel Clock Configuration Register
+    {0x0018,0x00},   // CRT/TV Pixel Clock Configuration Register
+    {0x001C,0x00},   // MediaPlug Clock Configuration Register
+/*
+ * .. 10MHz: 0x00
+ * .. 30MHz: 0x01
+ * 30MHz ..: 0x02
+ */
+    {0x001E,0x02},   // CPU To Memory Wait State Select Register
+    {0x0021,0x02},   // DRAM Refresh Rate Register
+    {0x002A,0x11},   // DRAM Timings Control Register 0
+    {0x002B,0x13},   // DRAM Timings Control Register 1
+    {0x0020,0x80},   // Memory Configuration Register
+    {0x0030,0x25},   // Panel Type Register
+    {0x0031,0x00},   // MOD Rate Register
+    {0x0032,0x4F},   // LCD Horizontal Display Width Register
+    {0x0034,0x12},   // LCD Horizontal Non-Display Period Register
+    {0x0035,0x01},   // TFT FPLINE Start Position Register
+    {0x0036,0x0B},   // TFT FPLINE Pulse Width Register
+    {0x0038,0xDF},   // LCD Vertical Display Height Register 0
+    {0x0039,0x01},   // LCD Vertical Display Height Register 1
+    {0x003A,0x2C},   // LCD Vertical Non-Display Period Register
+    {0x003B,0x0A},   // TFT FPFRAME Start Position Register
+    {0x003C,0x01},   // TFT FPFRAME Pulse Width Register
+
+    {0x0041,0x00},   // LCD Miscellaneous Register
+    {0x0042,0x00},   // LCD Display Start Address Register 0
+    {0x0043,0x00},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0004,0x07},   // GPIO[0:7] direction
+    {0x0005,0x00},   // GPIO[8:12] direction
+    {0x0008,0x00},   // GPIO[0:7] data
+    {0x0009,0x00},   // GPIO[8:12] data
+    {0x0008,0x04},   // LCD panel Vcc on
+    {0x0008,0x05},   // LCD panel reset
+    {0x0010,0x01},   // Memory Clock Configuration Register
+    {0x0014,0x30},   // LCD Pixel Clock Configuration Register (CLKI 22MHz/4)
+    {0x0018,0x00},   // CRT/TV Pixel Clock Configuration Register
+    {0x001C,0x00},   // MediaPlug Clock Configuration Register(10MHz)
+    {0x001E,0x00},   // CPU To Memory Wait State Select Register
+    {0x0020,0x80},   // Memory Configuration Register
+    {0x0021,0x03},   // DRAM Refresh Rate Register
+    {0x002A,0x00},   // DRAM Timings Control Register 0
+    {0x002B,0x01},   // DRAM Timings Control Register 1
+    {0x0030,0x25},   // Panel Type Register
+    {0x0031,0x00},   // MOD Rate Register
+    {0x0032,0x1d},   // LCD Horizontal Display Width Register
+    {0x0034,0x05},   // LCD Horizontal Non-Display Period Register
+    {0x0035,0x01},   // TFT FPLINE Start Position Register
+    {0x0036,0x01},   // TFT FPLINE Pulse Width Register
+    {0x0038,0x3F},   // LCD Vertical Display Height Register 0
+    {0x0039,0x01},   // LCD Vertical Display Height Register 1
+    {0x003A,0x0b},   // LCD Vertical Non-Display Period Register
+    {0x003B,0x07},   // TFT FPFRAME Start Position Register
+    {0x003C,0x02},   // TFT FPFRAME Pulse Width Register
+
+    {0x0041,0x00},   // LCD Miscellaneous Register
+#if (SWIVEL_VIEW == 0)
+    {0x0042,0x00},   // LCD Display Start Address Register 0
+    {0x0043,0x00},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+
+#elif (SWIVEL_VIEW == 1)
+    // 1024 - W(320) = 0x2C0
+    {0x0042,0xC0},   // LCD Display Start Address Register 0
+    {0x0043,0x02},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+    // 1024
+    {0x0046,0x00},   // LCD Memory Address Offset Register 0
+    {0x0047,0x02},   // LCD Memory Address Offset Register 1
+#else
+#error unsupported SWIVEL_VIEW mode
+#endif
+#else
+#error no platform configuration
+#endif  /* CONFIG_PLAT_XXX */
+
+    {0x0048,0x00},   // LCD Pixel Panning Register
+    {0x004A,0x00},   // LCD Display FIFO High Threshold Control Register
+    {0x004B,0x00},   // LCD Display FIFO Low Threshold Control Register
+    {0x0050,0x4F},   // CRT/TV Horizontal Display Width Register
+    {0x0052,0x13},   // CRT/TV Horizontal Non-Display Period Register
+    {0x0053,0x01},   // CRT/TV HRTC Start Position Register
+    {0x0054,0x0B},   // CRT/TV HRTC Pulse Width Register
+    {0x0056,0xDF},   // CRT/TV Vertical Display Height Register 0
+    {0x0057,0x01},   // CRT/TV Vertical Display Height Register 1
+    {0x0058,0x2B},   // CRT/TV Vertical Non-Display Period Register
+    {0x0059,0x09},   // CRT/TV VRTC Start Position Register
+    {0x005A,0x01},   // CRT/TV VRTC Pulse Width Register
+    {0x005B,0x10},   // TV Output Control Register
+
+    {0x0062,0x00},   // CRT/TV Display Start Address Register 0
+    {0x0063,0x00},   // CRT/TV Display Start Address Register 1
+    {0x0064,0x00},   // CRT/TV Display Start Address Register 2
+
+    {0x0068,0x00},   // CRT/TV Pixel Panning Register
+    {0x006A,0x00},   // CRT/TV Display FIFO High Threshold Control Register
+    {0x006B,0x00},   // CRT/TV Display FIFO Low Threshold Control Register
+    {0x0070,0x00},   // LCD Ink/Cursor Control Register
+    {0x0071,0x01},   // LCD Ink/Cursor Start Address Register
+    {0x0072,0x00},   // LCD Cursor X Position Register 0
+    {0x0073,0x00},   // LCD Cursor X Position Register 1
+    {0x0074,0x00},   // LCD Cursor Y Position Register 0
+    {0x0075,0x00},   // LCD Cursor Y Position Register 1
+    {0x0076,0x00},   // LCD Ink/Cursor Blue Color 0 Register
+    {0x0077,0x00},   // LCD Ink/Cursor Green Color 0 Register
+    {0x0078,0x00},   // LCD Ink/Cursor Red Color 0 Register
+    {0x007A,0x1F},   // LCD Ink/Cursor Blue Color 1 Register
+    {0x007B,0x3F},   // LCD Ink/Cursor Green Color 1 Register
+    {0x007C,0x1F},   // LCD Ink/Cursor Red Color 1 Register
+    {0x007E,0x00},   // LCD Ink/Cursor FIFO Threshold Register
+    {0x0080,0x00},   // CRT/TV Ink/Cursor Control Register
+    {0x0081,0x01},   // CRT/TV Ink/Cursor Start Address Register
+    {0x0082,0x00},   // CRT/TV Cursor X Position Register 0
+    {0x0083,0x00},   // CRT/TV Cursor X Position Register 1
+    {0x0084,0x00},   // CRT/TV Cursor Y Position Register 0
+    {0x0085,0x00},   // CRT/TV Cursor Y Position Register 1
+    {0x0086,0x00},   // CRT/TV Ink/Cursor Blue Color 0 Register
+    {0x0087,0x00},   // CRT/TV Ink/Cursor Green Color 0 Register
+    {0x0088,0x00},   // CRT/TV Ink/Cursor Red Color 0 Register
+    {0x008A,0x1F},   // CRT/TV Ink/Cursor Blue Color 1 Register
+    {0x008B,0x3F},   // CRT/TV Ink/Cursor Green Color 1 Register
+    {0x008C,0x1F},   // CRT/TV Ink/Cursor Red Color 1 Register
+    {0x008E,0x00},   // CRT/TV Ink/Cursor FIFO Threshold Register
+    {0x0100,0x00},   // BitBlt Control Register 0
+    {0x0101,0x00},   // BitBlt Control Register 1
+    {0x0102,0x00},   // BitBlt ROP Code/Color Expansion Register
+    {0x0103,0x00},   // BitBlt Operation Register
+    {0x0104,0x00},   // BitBlt Source Start Address Register 0
+    {0x0105,0x00},   // BitBlt Source Start Address Register 1
+    {0x0106,0x00},   // BitBlt Source Start Address Register 2
+    {0x0108,0x00},   // BitBlt Destination Start Address Register 0
+    {0x0109,0x00},   // BitBlt Destination Start Address Register 1
+    {0x010A,0x00},   // BitBlt Destination Start Address Register 2
+    {0x010C,0x00},   // BitBlt Memory Address Offset Register 0
+    {0x010D,0x00},   // BitBlt Memory Address Offset Register 1
+    {0x0110,0x00},   // BitBlt Width Register 0
+    {0x0111,0x00},   // BitBlt Width Register 1
+    {0x0112,0x00},   // BitBlt Height Register 0
+    {0x0113,0x00},   // BitBlt Height Register 1
+    {0x0114,0x00},   // BitBlt Background Color Register 0
+    {0x0115,0x00},   // BitBlt Background Color Register 1
+    {0x0118,0x00},   // BitBlt Foreground Color Register 0
+    {0x0119,0x00},   // BitBlt Foreground Color Register 1
+    {0x01E0,0x00},   // Look-Up Table Mode Register
+    {0x01E2,0x00},   // Look-Up Table Address Register
+    {0x01F0,0x10},   // Power Save Configuration Register
+    {0x01F1,0x00},   // Power Save Status Register
+    {0x01F4,0x00},   // CPU-to-Memory Access Watchdog Timer Register
+#if (SWIVEL_VIEW == 0)
+    {0x01FC,0x01},   // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+#elif (SWIVEL_VIEW == 1)
+    {0x01FC,0x41},   // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+#else
+#error unsupported SWIVEL_VIEW mode
+#endif  /* SWIVEL_VIEW */
+
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0008,0x07},   // LCD panel Vdd & Vg on
+#endif
+
+    {0x0040,0x05},   // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+#if defined(CONFIG_PLAT_MAPPI)
+    {0x0046,0x80},   // LCD Memory Address Offset Register 0
+    {0x0047,0x02},   // LCD Memory Address Offset Register 1
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0046,0xf0},   // LCD Memory Address Offset Register 0
+    {0x0047,0x00},   // LCD Memory Address Offset Register 1
+#endif
+    {0x0060,0x05},   // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+    {0x0066,0x80},   // CRT/TV Memory Address Offset Register 0	// takeo
+    {0x0067,0x02},   // CRT/TV Memory Address Offset Register 1
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/scatterlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef _ASM_M32R_SCATTERLIST_H
+#define _ASM_M32R_SCATTERLIST_H
+
+#include <asm/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    char *  address;    /* Location data is to be transferred to, NULL for
+                         * highmem page */
+    unsigned long page_link;
+    unsigned int offset;/* for highmem, page offset */
+
+    dma_addr_t dma_address;
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x1fffffff)
+
+#endif /* _ASM_M32R_SCATTERLIST_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sections.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef _M32R_SECTIONS_H
+#define _M32R_SECTIONS_H
+
+/* nothing to see, move along */
+#include <asm-generic/sections.h>
+
+#endif	/* _M32R_SECTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/segment.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/segment.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/segment.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/segment.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _ASM_M32R_SEGMENT_H
+#define _ASM_M32R_SEGMENT_H
+
+#define __KERNEL_CS	0x10
+#define __KERNEL_DS	0x18
+
+#define __USER_CS	0x23
+#define __USER_DS	0x2B
+
+#endif  /* _ASM_M32R_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sembuf.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sembuf.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sembuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sembuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+#ifndef _ASM_M32R_SEMBUF_H
+#define _ASM_M32R_SEMBUF_H
+
+/*
+ * The semid64_ds structure for m32r architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_M32R_SEMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/serial.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/serial.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef _ASM_M32R_SERIAL_H
+#define _ASM_M32R_SERIAL_H
+
+/* include/asm-m32r/serial.h */
+
+
+#define BASE_BAUD	115200
+
+#endif  /* _ASM_M32R_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/setup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+#ifndef _ASM_M32R_SETUP_H
+#define _ASM_M32R_SETUP_H
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+
+#define COMMAND_LINE_SIZE       512
+
+#ifdef __KERNEL__
+
+#define PARAM			((unsigned char *)empty_zero_page)
+
+#define MOUNT_ROOT_RDONLY	(*(unsigned long *) (PARAM+0x000))
+#define RAMDISK_FLAGS		(*(unsigned long *) (PARAM+0x004))
+#define ORIG_ROOT_DEV		(*(unsigned long *) (PARAM+0x008))
+#define LOADER_TYPE		(*(unsigned long *) (PARAM+0x00c))
+#define INITRD_START		(*(unsigned long *) (PARAM+0x010))
+#define INITRD_SIZE		(*(unsigned long *) (PARAM+0x014))
+
+#define M32R_CPUCLK		(*(unsigned long *) (PARAM+0x018))
+#define M32R_BUSCLK		(*(unsigned long *) (PARAM+0x01c))
+#define M32R_TIMER_DIVIDE	(*(unsigned long *) (PARAM+0x020))
+
+#define COMMAND_LINE		((char *) (PARAM+0x100))
+
+#define SCREEN_INFO		(*(struct screen_info *) (PARAM+0x200))
+
+#define RAMDISK_IMAGE_START_MASK	(0x07FF)
+#define RAMDISK_PROMPT_FLAG		(0x8000)
+#define RAMDISK_LOAD_FLAG		(0x4000)
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+#endif  /*  __KERNEL__  */
+
+#endif /* _ASM_M32R_SETUP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/shmbuf.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/shmbuf.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/shmbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/shmbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+#ifndef _ASM_M32R_SHMBUF_H
+#define _ASM_M32R_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for M32R architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_M32R_SHMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/shmparam.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/shmparam.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/shmparam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/shmparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_SHMPARAM_H
+#define _ASM_M32R_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_M32R_SHMPARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sigcontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,39 @@
+#ifndef _ASM_M32R_SIGCONTEXT_H
+#define _ASM_M32R_SIGCONTEXT_H
+
+struct sigcontext {
+	/* CPU registers */
+	/* Saved main processor registers. */
+	unsigned long sc_r4;
+	unsigned long sc_r5;
+	unsigned long sc_r6;
+	struct pt_regs *sc_pt_regs;
+	unsigned long sc_r0;
+	unsigned long sc_r1;
+	unsigned long sc_r2;
+	unsigned long sc_r3;
+	unsigned long sc_r7;
+	unsigned long sc_r8;
+	unsigned long sc_r9;
+	unsigned long sc_r10;
+	unsigned long sc_r11;
+	unsigned long sc_r12;
+
+	/* Saved main processor status and miscellaneous context registers. */
+	unsigned long sc_acc0h;
+	unsigned long sc_acc0l;
+	unsigned long sc_acc1h;	/* ISA_DSP_LEVEL2 only */
+	unsigned long sc_acc1l;	/* ISA_DSP_LEVEL2 only */
+	unsigned long sc_psw;
+	unsigned long sc_bpc;		/* saved PC for TRAP syscalls */
+	unsigned long sc_bbpsw;
+	unsigned long sc_bbpc;
+	unsigned long sc_spu;		/* saved user stack */
+	unsigned long sc_fp;
+	unsigned long sc_lr;		/* saved PC for JL syscalls */
+	unsigned long sc_spi;		/* saved kernel stack */
+
+	unsigned long	oldmask;
+};
+
+#endif  /* _ASM_M32R_SIGCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/siginfo.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/siginfo.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/siginfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/siginfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _M32R_SIGINFO_H
+#define _M32R_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _M32R_SIGINFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/signal.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/signal.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/signal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/signal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,166 @@
+#ifndef _ASM_M32R_SIGNAL_H
+#define _ASM_M32R_SIGNAL_H
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/compiler.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	_NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001u
+#define SA_NOCLDWAIT	0x00000002u
+#define SA_SIGINFO	0x00000004u
+#define SA_ONSTACK	0x08000000u
+#define SA_RESTART	0x10000000u
+#define SA_NODEFER	0x40000000u
+#define SA_RESETHAND	0x80000000u
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void __user *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+#undef __HAVE_ARCH_SIG_BITOPS
+
+struct pt_regs;
+extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+#define ptrace_signal_deliver(regs, cookie)	do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif  /* _ASM_M32R_SIGNAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,119 @@
+#ifndef _ASM_M32R_SMP_H
+#define _ASM_M32R_SMP_H
+
+#ifdef CONFIG_SMP
+#ifndef __ASSEMBLY__
+
+#include <linux/cpumask.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <asm/m32r.h>
+
+#define PHYSID_ARRAY_SIZE       1
+
+struct physid_mask
+{
+	unsigned long mask[PHYSID_ARRAY_SIZE];
+};
+
+typedef struct physid_mask physid_mask_t;
+
+#define physid_set(physid, map)                 set_bit(physid, (map).mask)
+#define physid_clear(physid, map)               clear_bit(physid, (map).mask)
+#define physid_isset(physid, map)               test_bit(physid, (map).mask)
+#define physid_test_and_set(physid, map)        test_and_set_bit(physid, (map).mask)
+
+#define physids_and(dst, src1, src2)            bitmap_and((dst).mask, (src1).mask, (src2).mask, MAX_APICS)
+#define physids_or(dst, src1, src2)             bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_APICS)
+#define physids_clear(map)                      bitmap_zero((map).mask, MAX_APICS)
+#define physids_complement(dst, src)            bitmap_complement((dst).mask,(src).mask, MAX_APICS)
+#define physids_empty(map)                      bitmap_empty((map).mask, MAX_APICS)
+#define physids_equal(map1, map2)               bitmap_equal((map1).mask, (map2).mask, MAX_APICS)
+#define physids_weight(map)                     bitmap_weight((map).mask, MAX_APICS)
+#define physids_shift_right(d, s, n)            bitmap_shift_right((d).mask, (s).mask, n, MAX_APICS)
+#define physids_shift_left(d, s, n)             bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS)
+#define physids_coerce(map)                     ((map).mask[0])
+
+#define physids_promote(physids)					\
+	({								\
+		physid_mask_t __physid_mask = PHYSID_MASK_NONE;		\
+		__physid_mask.mask[0] = physids;			\
+		__physid_mask;						\
+	})
+
+#define physid_mask_of_physid(physid)					\
+	({								\
+		physid_mask_t __physid_mask = PHYSID_MASK_NONE;		\
+		physid_set(physid, __physid_mask);			\
+		__physid_mask;						\
+	})
+
+#define PHYSID_MASK_ALL         { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} }
+#define PHYSID_MASK_NONE        { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} }
+
+extern physid_mask_t phys_cpu_present_map;
+
+/*
+ * Some lowlevel functions might want to know about
+ * the real CPU ID <-> CPU # mapping.
+ */
+extern volatile int cpu_2_physid[NR_CPUS];
+#define cpu_to_physid(cpu_id)	cpu_2_physid[cpu_id]
+
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
+
+extern cpumask_t cpu_callout_map;
+
+static __inline__ int hard_smp_processor_id(void)
+{
+	return (int)*(volatile long *)M32R_CPUID_PORTL;
+}
+
+static __inline__ int cpu_logical_map(int cpu)
+{
+	return cpu;
+}
+
+static __inline__ int cpu_number_map(int cpu)
+{
+	return cpu;
+}
+
+static __inline__ unsigned int num_booting_cpus(void)
+{
+	return cpus_weight(cpu_callout_map);
+}
+
+extern void smp_send_timer(void);
+extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
+
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi(cpumask_t mask);
+
+#endif	/* not __ASSEMBLY__ */
+
+#define NO_PROC_ID (0xff)	/* No processor magic marker */
+
+#define PROC_CHANGE_PENALTY	(15)	/* Schedule penalty */
+
+/*
+ * M32R-mp IPI
+ */
+#define RESCHEDULE_IPI		(M32R_IRQ_IPI0-M32R_IRQ_IPI0)
+#define INVALIDATE_TLB_IPI	(M32R_IRQ_IPI1-M32R_IRQ_IPI0)
+#define CALL_FUNCTION_IPI	(M32R_IRQ_IPI2-M32R_IRQ_IPI0)
+#define LOCAL_TIMER_IPI		(M32R_IRQ_IPI3-M32R_IRQ_IPI0)
+#define INVALIDATE_CACHE_IPI	(M32R_IRQ_IPI4-M32R_IRQ_IPI0)
+#define CPU_BOOT_IPI		(M32R_IRQ_IPI5-M32R_IRQ_IPI0)
+#define CALL_FUNC_SINGLE_IPI	(M32R_IRQ_IPI6-M32R_IRQ_IPI0)
+
+#define IPI_SHIFT	(0)
+#define NR_IPIS		(8)
+
+#else	/* CONFIG_SMP */
+
+#define hard_smp_processor_id()		0
+
+#endif /* CONFIG_SMP */
+
+#endif	/* _ASM_M32R_SMP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/socket.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,60 @@
+#ifndef _ASM_M32R_SOCKET_H
+#define _ASM_M32R_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_SNDBUFFORCE	32
+#define SO_RCVBUFFORCE	33
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+#define SO_PEERSEC		31
+#define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
+
+#define SO_MARK			36
+
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
+#endif /* _ASM_M32R_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sockios.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sockios.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/sockios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/sockios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef _ASM_M32R_SOCKIOS_H
+#define _ASM_M32R_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) */
+
+#endif  /* _ASM_M32R_SOCKIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/spinlock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,326 @@
+#ifndef _ASM_M32R_SPINLOCK_H
+#define _ASM_M32R_SPINLOCK_H
+
+/*
+ *  linux/include/asm-m32r/spinlock.h
+ *
+ *  M32R version:
+ *    Copyright (C) 2001, 2002  Hitoshi Yamamoto
+ *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ *
+ * (the type definitions are in asm/spinlock_types.h)
+ *
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * 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))
+
+/**
+ * __raw_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.
+ * On the m32r, the result value is 1 (= Success) or 0 (= Failure).
+ */
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+	int oldval;
+	unsigned long tmp1, tmp2;
+
+	/*
+	 * lock->slock :  =1 : unlock
+	 *             : <=0 : lock
+	 * {
+	 *   oldval = lock->slock; <--+ need atomic operation
+	 *   lock->slock = 0;      <--+
+	 * }
+	 */
+	__asm__ __volatile__ (
+		"# __raw_spin_trylock		\n\t"
+		"ldi	%1, #0;			\n\t"
+		"mvfc	%2, psw;		\n\t"
+		"clrpsw	#0x40 -> nop;		\n\t"
+		DCACHE_CLEAR("%0", "r6", "%3")
+		"lock	%0, @%3;		\n\t"
+		"unlock	%1, @%3;		\n\t"
+		"mvtc	%2, psw;		\n\t"
+		: "=&r" (oldval), "=&r" (tmp1), "=&r" (tmp2)
+		: "r" (&lock->slock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+
+	return (oldval > 0);
+}
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+	unsigned long tmp0, tmp1;
+
+	/*
+	 * lock->slock :  =1 : unlock
+	 *             : <=0 : lock
+	 *
+	 * for ( ; ; ) {
+	 *   lock->slock -= 1;  <-- need atomic operation
+	 *   if (lock->slock == 0) break;
+	 *   for ( ; lock->slock <= 0 ; );
+	 * }
+	 */
+	__asm__ __volatile__ (
+		"# __raw_spin_lock		\n\t"
+		".fillinsn			\n"
+		"1:				\n\t"
+		"mvfc	%1, psw;		\n\t"
+		"clrpsw	#0x40 -> nop;		\n\t"
+		DCACHE_CLEAR("%0", "r6", "%2")
+		"lock	%0, @%2;		\n\t"
+		"addi	%0, #-1;		\n\t"
+		"unlock	%0, @%2;		\n\t"
+		"mvtc	%1, psw;		\n\t"
+		"bltz	%0, 2f;			\n\t"
+		LOCK_SECTION_START(".balign 4 \n\t")
+		".fillinsn			\n"
+		"2:				\n\t"
+		"ld	%0, @%2;		\n\t"
+		"bgtz	%0, 1b;			\n\t"
+		"bra	2b;			\n\t"
+		LOCK_SECTION_END
+		: "=&r" (tmp0), "=&r" (tmp1)
+		: "r" (&lock->slock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+}
+
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+	mb();
+	lock->slock = 1;
+}
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ *
+ * On x86, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "contended" bit.
+ *
+ * The inline assembly is non-obvious. Think about it.
+ *
+ * Changed to use the same technique as rw semaphores.  See
+ * semaphore.h for details.  -ben
+ */
+
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define __raw_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)
+
+static inline void __raw_read_lock(raw_rwlock_t *rw)
+{
+	unsigned long tmp0, tmp1;
+
+	/*
+	 * rw->lock :  >0 : unlock
+	 *          : <=0 : lock
+	 *
+	 * for ( ; ; ) {
+	 *   rw->lock -= 1;  <-- need atomic operation
+	 *   if (rw->lock >= 0) break;
+	 *   rw->lock += 1;  <-- need atomic operation
+	 *   for ( ; rw->lock <= 0 ; );
+	 * }
+	 */
+	__asm__ __volatile__ (
+		"# read_lock			\n\t"
+		".fillinsn			\n"
+		"1:				\n\t"
+		"mvfc	%1, psw;		\n\t"
+		"clrpsw	#0x40 -> nop;		\n\t"
+		DCACHE_CLEAR("%0", "r6", "%2")
+		"lock	%0, @%2;		\n\t"
+		"addi	%0, #-1;		\n\t"
+		"unlock	%0, @%2;		\n\t"
+		"mvtc	%1, psw;		\n\t"
+		"bltz	%0, 2f;			\n\t"
+		LOCK_SECTION_START(".balign 4 \n\t")
+		".fillinsn			\n"
+		"2:				\n\t"
+		"clrpsw	#0x40 -> nop;		\n\t"
+		DCACHE_CLEAR("%0", "r6", "%2")
+		"lock	%0, @%2;		\n\t"
+		"addi	%0, #1;			\n\t"
+		"unlock	%0, @%2;		\n\t"
+		"mvtc	%1, psw;		\n\t"
+		".fillinsn			\n"
+		"3:				\n\t"
+		"ld	%0, @%2;		\n\t"
+		"bgtz	%0, 1b;			\n\t"
+		"bra	3b;			\n\t"
+		LOCK_SECTION_END
+		: "=&r" (tmp0), "=&r" (tmp1)
+		: "r" (&rw->lock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+}
+
+static inline void __raw_write_lock(raw_rwlock_t *rw)
+{
+	unsigned long tmp0, tmp1, tmp2;
+
+	/*
+	 * rw->lock :  =RW_LOCK_BIAS_STR : unlock
+	 *          : !=RW_LOCK_BIAS_STR : lock
+	 *
+	 * for ( ; ; ) {
+	 *   rw->lock -= RW_LOCK_BIAS_STR;  <-- need atomic operation
+	 *   if (rw->lock == 0) break;
+	 *   rw->lock += RW_LOCK_BIAS_STR;  <-- need atomic operation
+	 *   for ( ; rw->lock != RW_LOCK_BIAS_STR ; ) ;
+	 * }
+	 */
+	__asm__ __volatile__ (
+		"# write_lock					\n\t"
+		"seth	%1, #high(" RW_LOCK_BIAS_STR ");	\n\t"
+		"or3	%1, %1, #low(" RW_LOCK_BIAS_STR ");	\n\t"
+		".fillinsn					\n"
+		"1:						\n\t"
+		"mvfc	%2, psw;				\n\t"
+		"clrpsw	#0x40 -> nop;				\n\t"
+		DCACHE_CLEAR("%0", "r7", "%3")
+		"lock	%0, @%3;				\n\t"
+		"sub	%0, %1;					\n\t"
+		"unlock	%0, @%3;				\n\t"
+		"mvtc	%2, psw;				\n\t"
+		"bnez	%0, 2f;					\n\t"
+		LOCK_SECTION_START(".balign 4 \n\t")
+		".fillinsn					\n"
+		"2:						\n\t"
+		"clrpsw	#0x40 -> nop;				\n\t"
+		DCACHE_CLEAR("%0", "r7", "%3")
+		"lock	%0, @%3;				\n\t"
+		"add	%0, %1;					\n\t"
+		"unlock	%0, @%3;				\n\t"
+		"mvtc	%2, psw;				\n\t"
+		".fillinsn					\n"
+		"3:						\n\t"
+		"ld	%0, @%3;				\n\t"
+		"beq	%0, %1, 1b;				\n\t"
+		"bra	3b;					\n\t"
+		LOCK_SECTION_END
+		: "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2)
+		: "r" (&rw->lock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r7"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+}
+
+static inline void __raw_read_unlock(raw_rwlock_t *rw)
+{
+	unsigned long tmp0, tmp1;
+
+	__asm__ __volatile__ (
+		"# read_unlock			\n\t"
+		"mvfc	%1, psw;		\n\t"
+		"clrpsw	#0x40 -> nop;		\n\t"
+		DCACHE_CLEAR("%0", "r6", "%2")
+		"lock	%0, @%2;		\n\t"
+		"addi	%0, #1;			\n\t"
+		"unlock	%0, @%2;		\n\t"
+		"mvtc	%1, psw;		\n\t"
+		: "=&r" (tmp0), "=&r" (tmp1)
+		: "r" (&rw->lock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r6"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+}
+
+static inline void __raw_write_unlock(raw_rwlock_t *rw)
+{
+	unsigned long tmp0, tmp1, tmp2;
+
+	__asm__ __volatile__ (
+		"# write_unlock					\n\t"
+		"seth	%1, #high(" RW_LOCK_BIAS_STR ");	\n\t"
+		"or3	%1, %1, #low(" RW_LOCK_BIAS_STR ");	\n\t"
+		"mvfc	%2, psw;				\n\t"
+		"clrpsw	#0x40 -> nop;				\n\t"
+		DCACHE_CLEAR("%0", "r7", "%3")
+		"lock	%0, @%3;				\n\t"
+		"add	%0, %1;					\n\t"
+		"unlock	%0, @%3;				\n\t"
+		"mvtc	%2, psw;				\n\t"
+		: "=&r" (tmp0), "=&r" (tmp1), "=&r" (tmp2)
+		: "r" (&rw->lock)
+		: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+		, "r7"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+	);
+}
+
+static inline int __raw_read_trylock(raw_rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t*)lock;
+	if (atomic_dec_return(count) >= 0)
+		return 1;
+	atomic_inc(count);
+	return 0;
+}
+
+static inline int __raw_write_trylock(raw_rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t *)lock;
+	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
+		return 1;
+	atomic_add(RW_LOCK_BIAS, count);
+	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 _raw_spin_relax(lock)	cpu_relax()
+#define _raw_read_relax(lock)	cpu_relax()
+#define _raw_write_relax(lock)	cpu_relax()
+
+#endif	/* _ASM_M32R_SPINLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/spinlock_types.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/spinlock_types.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/spinlock_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/spinlock_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+#ifndef _ASM_M32R_SPINLOCK_TYPES_H
+#define _ASM_M32R_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+	volatile int slock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED	{ 1 }
+
+typedef struct {
+	volatile int lock;
+} raw_rwlock_t;
+
+#define RW_LOCK_BIAS			0x01000000
+#define RW_LOCK_BIAS_STR		"0x01000000"
+
+#define __RAW_RW_LOCK_UNLOCKED		{ RW_LOCK_BIAS }
+
+#endif /* _ASM_M32R_SPINLOCK_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/statfs.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/statfs.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/statfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/statfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_STATFS_H
+#define _ASM_M32R_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif  /* _ASM_M32R_STATFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/stat.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/stat.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/stat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/stat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,87 @@
+#ifndef _ASM_M32R_STAT_H
+#define _ASM_M32R_STAT_H
+
+#include <asm/byteorder.h>
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+#define STAT_HAVE_NSEC	1
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long  st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  st_atime_nsec;
+	unsigned long  st_mtime;
+	unsigned long  st_mtime_nsec;
+	unsigned long  st_ctime;
+	unsigned long  st_ctime_nsec;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+#define STAT64_HAS_BROKEN_ST_INO
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+#if defined(__BIG_ENDIAN)
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+#elif defined(__LITTLE_ENDIAN)
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+#else
+#error no endian defined
+#endif
+	unsigned long	st_atime;
+	unsigned long	st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned long	st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long	st_ctime_nsec;
+
+	unsigned long long	st_ino;
+};
+
+#endif  /* _ASM_M32R_STAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/string.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/string.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/string.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/string.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef _ASM_M32R_STRING_H
+#define _ASM_M32R_STRING_H
+
+#define  __HAVE_ARCH_STRLEN
+extern size_t strlen(const char * s);
+
+#define  __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+#define  __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
+
+#endif  /* _ASM_M32R_STRING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/swab.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _ASM_M32R_SWAB_H
+#define _ASM_M32R_SWAB_H
+
+#include <linux/types.h>
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_M32R_SWAB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/syscall.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/syscall.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/syscall.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/syscall.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef _ASM_M32R_SYSCALL_H
+#define _ASM_M32R_SYSCALL_H
+
+/* Definitions for the system call vector.  */
+#define SYSCALL_VECTOR          "2"
+#define SYSCALL_VECTOR_ADDRESS  "0xa0"
+
+#endif /* _ASM_M32R_SYSCALL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/system.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,431 @@
+#ifndef _ASM_M32R_SYSTEM_H
+#define _ASM_M32R_SYSTEM_H
+
+/*
+ * 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) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
+ * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#include <linux/compiler.h>
+#include <asm/assembler.h>
+
+#ifdef __KERNEL__
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ *
+ * `next' and `prev' should be struct task_struct, but it isn't always defined
+ */
+
+#if defined(CONFIG_FRAME_POINTER) || \
+	!defined(CONFIG_SCHED_OMIT_FRAME_POINTER)
+#define M32R_PUSH_FP "	push fp\n"
+#define M32R_POP_FP  "	pop  fp\n"
+#else
+#define M32R_PUSH_FP ""
+#define M32R_POP_FP  ""
+#endif
+
+#define switch_to(prev, next, last)  do { \
+	__asm__ __volatile__ ( \
+		"	seth	lr, #high(1f)				\n" \
+		"	or3	lr, lr, #low(1f)			\n" \
+		"	st	lr, @%4  ; store old LR			\n" \
+		"	ld	lr, @%5  ; load new LR			\n" \
+			M32R_PUSH_FP \
+		"	st	sp, @%2  ; store old SP			\n" \
+		"	ld	sp, @%3  ; load new SP			\n" \
+		"	push	%1  ; store `prev' on new stack		\n" \
+		"	jmp	lr					\n" \
+		"	.fillinsn					\n" \
+		"1:							\n" \
+		"	pop	%0  ; restore `__last' from new stack	\n" \
+			M32R_POP_FP \
+		: "=r" (last) \
+		: "0" (prev), \
+		  "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \
+		  "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \
+		: "memory", "lr" \
+	); \
+} while(0)
+
+/* Interrupt Control */
+#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
+#define local_irq_enable() \
+	__asm__ __volatile__ ("setpsw #0x40 -> nop": : :"memory")
+#define local_irq_disable() \
+	__asm__ __volatile__ ("clrpsw #0x40 -> nop": : :"memory")
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+static inline void local_irq_enable(void)
+{
+	unsigned long tmpreg;
+	__asm__ __volatile__(
+		"mvfc	%0, psw;		\n\t"
+		"or3	%0, %0, #0x0040;	\n\t"
+		"mvtc	%0, psw;		\n\t"
+	: "=&r" (tmpreg) : : "cbit", "memory");
+}
+
+static inline void local_irq_disable(void)
+{
+	unsigned long tmpreg0, tmpreg1;
+	__asm__ __volatile__(
+		"ld24	%0, #0	; Use 32-bit insn. \n\t"
+		"mvfc	%1, psw	; No interrupt can be accepted here. \n\t"
+		"mvtc	%0, psw	\n\t"
+		"and3	%0, %1, #0xffbf	\n\t"
+		"mvtc	%0, psw	\n\t"
+	: "=&r" (tmpreg0), "=&r" (tmpreg1) : : "cbit", "memory");
+}
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+
+#define local_save_flags(x) \
+	__asm__ __volatile__("mvfc %0,psw" : "=r"(x) : /* no input */)
+
+#define local_irq_restore(x) \
+	__asm__ __volatile__("mvtc %0,psw" : /* no outputs */ \
+		: "r" (x) : "cbit", "memory")
+
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
+#define local_irq_save(x)				\
+	__asm__ __volatile__(				\
+  		"mvfc	%0, psw;		\n\t"	\
+	  	"clrpsw	#0x40 -> nop;		\n\t"	\
+  		: "=r" (x) : /* no input */ : "memory")
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+#define local_irq_save(x) 				\
+	({						\
+		unsigned long tmpreg;			\
+		__asm__ __volatile__( 			\
+			"ld24	%1, #0 \n\t" 		\
+			"mvfc	%0, psw \n\t"		\
+			"mvtc	%1, psw \n\t"		\
+			"and3	%1, %0, #0xffbf \n\t"	\
+			"mvtc	%1, psw \n\t" 		\
+			: "=r" (x), "=&r" (tmpreg)	\
+			: : "cbit", "memory");		\
+	})
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
+
+#define irqs_disabled()					\
+	({						\
+		unsigned long flags;			\
+		local_save_flags(flags);		\
+		!(flags & 0x40);			\
+	})
+
+#define nop()	__asm__ __volatile__ ("nop" : : )
+
+#define xchg(ptr, x)							\
+	((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg_local(ptr, x)						\
+	((__typeof__(*(ptr)))__xchg_local((unsigned long)(x), (ptr),	\
+			sizeof(*(ptr))))
+
+extern void  __xchg_called_with_bad_pointer(void);
+
+#ifdef CONFIG_CHIP_M32700_TS1
+#define DCACHE_CLEAR(reg0, reg1, addr)				\
+	"seth	"reg1", #high(dcache_dummy);		\n\t"	\
+	"or3	"reg1", "reg1", #low(dcache_dummy);	\n\t"	\
+	"lock	"reg0", @"reg1";			\n\t"	\
+	"add3	"reg0", "addr", #0x1000;		\n\t"	\
+	"ld	"reg0", @"reg0";			\n\t"	\
+	"add3	"reg0", "addr", #0x2000;		\n\t"	\
+	"ld	"reg0", @"reg0";			\n\t"	\
+	"unlock	"reg0", @"reg1";			\n\t"
+	/* FIXME: This workaround code cannot handle kernel modules
+	 * correctly under SMP environment.
+	 */
+#else	/* CONFIG_CHIP_M32700_TS1 */
+#define DCACHE_CLEAR(reg0, reg1, addr)
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+
+static __always_inline unsigned long
+__xchg(unsigned long x, volatile void *ptr, int size)
+{
+	unsigned long flags;
+	unsigned long tmp = 0;
+
+	local_irq_save(flags);
+
+	switch (size) {
+#ifndef CONFIG_SMP
+	case 1:
+		__asm__ __volatile__ (
+			"ldb	%0, @%2 \n\t"
+			"stb	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+	case 2:
+		__asm__ __volatile__ (
+			"ldh	%0, @%2 \n\t"
+			"sth	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+	case 4:
+		__asm__ __volatile__ (
+			"ld	%0, @%2 \n\t"
+			"st	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+#else  /* CONFIG_SMP */
+	case 4:
+		__asm__ __volatile__ (
+			DCACHE_CLEAR("%0", "r4", "%2")
+			"lock	%0, @%2;	\n\t"
+			"unlock	%1, @%2;	\n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr)
+			: "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+			, "r4"
+#endif	/* CONFIG_CHIP_M32700_TS1 */
+		);
+		break;
+#endif  /* CONFIG_SMP */
+	default:
+		__xchg_called_with_bad_pointer();
+	}
+
+	local_irq_restore(flags);
+
+	return (tmp);
+}
+
+static __always_inline unsigned long
+__xchg_local(unsigned long x, volatile void *ptr, int size)
+{
+	unsigned long flags;
+	unsigned long tmp = 0;
+
+	local_irq_save(flags);
+
+	switch (size) {
+	case 1:
+		__asm__ __volatile__ (
+			"ldb	%0, @%2 \n\t"
+			"stb	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+	case 2:
+		__asm__ __volatile__ (
+			"ldh	%0, @%2 \n\t"
+			"sth	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+	case 4:
+		__asm__ __volatile__ (
+			"ld	%0, @%2 \n\t"
+			"st	%1, @%2 \n\t"
+			: "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+		break;
+	default:
+		__xchg_called_with_bad_pointer();
+	}
+
+	local_irq_restore(flags);
+
+	return (tmp);
+}
+
+#define __HAVE_ARCH_CMPXCHG	1
+
+static inline unsigned long
+__cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
+{
+	unsigned long flags;
+	unsigned int retval;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+			DCACHE_CLEAR("%0", "r4", "%1")
+			M32R_LOCK" %0, @%1;	\n"
+		"	bne	%0, %2, 1f;	\n"
+			M32R_UNLOCK" %3, @%1;	\n"
+		"	bra	2f;		\n"
+                "       .fillinsn		\n"
+		"1:"
+			M32R_UNLOCK" %0, @%1;	\n"
+                "       .fillinsn		\n"
+		"2:"
+			: "=&r" (retval)
+			: "r" (p), "r" (old), "r" (new)
+			: "cbit", "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+			, "r4"
+#endif  /* CONFIG_CHIP_M32700_TS1 */
+		);
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+static inline unsigned long
+__cmpxchg_local_u32(volatile unsigned int *p, unsigned int old,
+			unsigned int new)
+{
+	unsigned long flags;
+	unsigned int retval;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+			DCACHE_CLEAR("%0", "r4", "%1")
+			"ld %0, @%1;		\n"
+		"	bne	%0, %2, 1f;	\n"
+			"st %3, @%1;		\n"
+		"	bra	2f;		\n"
+		"       .fillinsn		\n"
+		"1:"
+			"st %0, @%1;		\n"
+		"       .fillinsn		\n"
+		"2:"
+			: "=&r" (retval)
+			: "r" (p), "r" (old), "r" (new)
+			: "cbit", "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+			, "r4"
+#endif  /* CONFIG_CHIP_M32700_TS1 */
+		);
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32(ptr, old, new);
+#if 0	/* we don't have __cmpxchg_u64 */
+	case 8:
+		return __cmpxchg_u64(ptr, old, new);
+#endif /* 0 */
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#define cmpxchg(ptr, o, n)						 \
+	((__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)(o),	 \
+			(unsigned long)(n), sizeof(*(ptr))))
+
+#include <asm-generic/cmpxchg-local.h>
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+				      unsigned long old,
+				      unsigned long new, int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_local_u32(ptr, old, new);
+	default:
+		return __cmpxchg_local_generic(ptr, old, new, size);
+	}
+
+	return old;
+}
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n)				  	    \
+	((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o),	    \
+			(unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif  /* __KERNEL__ */
+
+/*
+ * Memory barrier.
+ *
+ * mb() prevents loads and stores being reordered across this point.
+ * rmb() prevents loads being reordered across this point.
+ * wmb() prevents stores being reordered across this point.
+ */
+#define mb()   barrier()
+#define rmb()  mb()
+#define wmb()  mb()
+
+/**
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier.  All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads.  This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies.  See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ *      CPU 0                           CPU 1
+ *
+ *      b = 2;
+ *      memory_barrier();
+ *      p = &b;                         q = p;
+ *                                      read_barrier_depends();
+ *                                      d = *q;
+ * </programlisting>
+ *
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends().  However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ *      CPU 0                           CPU 1
+ *
+ *      a = 2;
+ *      memory_barrier();
+ *      b = 3;                          y = b;
+ *                                      read_barrier_depends();
+ *                                      x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
+ * in cases like this where there are no data dependencies.
+ **/
+
+#define read_barrier_depends()	do { } while (0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#define smp_read_barrier_depends()	read_barrier_depends()
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#define smp_read_barrier_depends()	do { } while (0)
+#define set_mb(var, value) do { var = value; barrier(); } while (0)
+#endif
+
+#define arch_align_stack(x) (x)
+
+#endif /* _ASM_M32R_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/termbits.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/termbits.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/termbits.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/termbits.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,199 @@
+#ifndef _ASM_M32R_TERMBITS_H
+#define _ASM_M32R_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 CTVB	  004000000000		/* VisioBraille Terminal flow control */
+#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
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ASM_M32R_TERMBITS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/termios.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/termios.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/termios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/termios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,91 @@
+#ifndef _M32R_TERMIOS_H
+#define _M32R_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _M32R_TERMIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/thread_info.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,184 @@
+#ifndef _ASM_M32R_THREAD_INFO_H
+#define _ASM_M32R_THREAD_INFO_H
+
+/* thread_info.h: m32r low-level thread information
+ *
+ * Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#endif
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants must also be changed
+ */
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	unsigned long		status;		/* thread-synchronous flags */
+	__u32			cpu;		/* current CPU */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+
+	mm_segment_t		addr_limit;	/* thread address space:
+					 	   0-0xBFFFFFFF for user-thread
+						   0-0xFFFFFFFF for kernel-thread
+						*/
+	struct restart_block    restart_block;
+
+	__u8			supervisor_stack[0];
+};
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets into the thread_info struct for assembly code access */
+#define TI_TASK		0x00000000
+#define TI_EXEC_DOMAIN	0x00000004
+#define TI_FLAGS	0x00000008
+#define TI_STATUS	0x0000000C
+#define TI_CPU		0x00000010
+#define TI_PRE_COUNT	0x00000014
+#define TI_ADDR_LIMIT	0x00000018
+#define TI_RESTART_BLOCK 0x000001C
+
+#endif
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+#define THREAD_SIZE (2*PAGE_SIZE)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+
+	__asm__ __volatile__ (
+		"ldi	%0, #%1			\n\t"
+		"and	%0, sp			\n\t"
+		: "=r" (ti) : "i" (~(THREAD_SIZE - 1))
+	);
+
+	return ti;
+}
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+/* thread information allocation */
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk)					\
+	({							\
+		struct thread_info *ret;			\
+	 							\
+	 	ret = kzalloc(THREAD_SIZE, GFP_KERNEL);		\
+								\
+	 	ret;						\
+	 })
+#else
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+
+#define free_thread_info(info) kfree(info)
+
+#define TI_FLAG_FAULT_CODE_SHIFT	28
+
+static inline void set_thread_fault_code(unsigned int val)
+{
+	struct thread_info *ti = current_thread_info();
+	ti->flags = (ti->flags & (~0 >> (32 - TI_FLAG_FAULT_CODE_SHIFT)))
+		| (val << TI_FLAG_FAULT_CODE_SHIFT);
+}
+
+static inline unsigned int get_thread_fault_code(void)
+{
+	struct thread_info *ti = current_thread_info();
+	return ti->flags >> TI_FLAG_FAULT_CODE_SHIFT;
+}
+
+#else /* !__ASSEMBLY__ */
+
+#define THREAD_SIZE	8192
+
+/* how to get the thread information struct from ASM */
+#define GET_THREAD_INFO(reg)	GET_THREAD_INFO reg
+	.macro GET_THREAD_INFO reg
+	ldi	\reg, #-THREAD_SIZE
+	and	\reg, sp
+	.endm
+
+#endif
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_SIGPENDING		1	/* signal pending */
+#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
+#define TIF_SINGLESTEP		3	/* restore singlestep on return to user mode */
+#define TIF_IRET		4	/* return with iret */
+#define TIF_RESTORE_SIGMASK	8	/* restore signal mask in do_signal() */
+#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	/* OOM killer killed process */
+#define TIF_FREEZE		19	/* is freezing for suspend */
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
+#define _TIF_IRET		(1<<TIF_IRET)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		(1<<TIF_FREEZE)
+
+#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+#define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
+
+/*
+ * 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_USEDFPU		0x0001	/* FPU was used by this task this quantum (SMP) */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_M32R_THREAD_INFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+#ifndef _ASM_M32R_TIMEX_H
+#define _ASM_M32R_TIMEX_H
+
+/*
+ * linux/include/asm-m32r/timex.h
+ *
+ * m32r architecture timex specifications
+ */
+
+#define CLOCK_TICK_RATE	(CONFIG_BUS_CLOCK / CONFIG_TIMER_DIVIDE)
+#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
+
+#ifdef __KERNEL__
+/*
+ * Standard way to access the cycle counter.
+ * Currently only used on SMP.
+ */
+
+typedef unsigned long long cycles_t;
+
+static __inline__ cycles_t get_cycles (void)
+{
+	return 0;
+}
+#endif  /* __KERNEL__ */
+
+#endif  /* _ASM_M32R_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/tlbflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,97 @@
+#ifndef _ASM_M32R_TLBFLUSH_H
+#define _ASM_M32R_TLBFLUSH_H
+
+#include <asm/m32r.h>
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *);
+extern void local_flush_tlb_page(struct vm_area_struct *, unsigned long);
+extern void local_flush_tlb_range(struct vm_area_struct *, unsigned long,
+	unsigned long);
+
+#ifndef CONFIG_SMP
+#ifdef CONFIG_MMU
+#define flush_tlb_all()			local_flush_tlb_all()
+#define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
+#define flush_tlb_page(vma, page)	local_flush_tlb_page(vma, page)
+#define flush_tlb_range(vma, start, end)	\
+	local_flush_tlb_range(vma, start, end)
+#define flush_tlb_kernel_range(start, end)	local_flush_tlb_all()
+#else	/* CONFIG_MMU */
+#define flush_tlb_all()			do { } while (0)
+#define flush_tlb_mm(mm)		do { } while (0)
+#define flush_tlb_page(vma, vmaddr)	do { } while (0)
+#define flush_tlb_range(vma, start, end)	do { } while (0)
+#endif	/* CONFIG_MMU */
+#else	/* CONFIG_SMP */
+extern void smp_flush_tlb_all(void);
+extern void smp_flush_tlb_mm(struct mm_struct *);
+extern void smp_flush_tlb_page(struct vm_area_struct *, unsigned long);
+extern void smp_flush_tlb_range(struct vm_area_struct *, unsigned long,
+	unsigned long);
+
+#define flush_tlb_all()			smp_flush_tlb_all()
+#define flush_tlb_mm(mm)		smp_flush_tlb_mm(mm)
+#define flush_tlb_page(vma, page)	smp_flush_tlb_page(vma, page)
+#define flush_tlb_range(vma, start, end)	\
+	smp_flush_tlb_range(vma, start, end)
+#define flush_tlb_kernel_range(start, end)	smp_flush_tlb_all()
+#endif	/* CONFIG_SMP */
+
+static __inline__ void __flush_tlb_page(unsigned long page)
+{
+	unsigned int tmpreg0, tmpreg1, tmpreg2;
+
+	__asm__ __volatile__ (
+		"seth	%0, #high(%4)	\n\t"
+		"st	%3, @(%5, %0)	\n\t"
+		"ldi	%1, #1		\n\t"
+		"st	%1, @(%6, %0)	\n\t"
+		"add3	%1, %0, %7	\n\t"
+		".fillinsn		\n"
+		"1:			\n\t"
+		"ld	%2, @(%6, %0)	\n\t"
+		"bnez	%2, 1b		\n\t"
+		"ld	%0, @%1+	\n\t"
+		"ld	%1, @%1		\n\t"
+		"st	%2, @+%0	\n\t"
+		"st	%2, @+%1	\n\t"
+		: "=&r" (tmpreg0), "=&r" (tmpreg1), "=&r" (tmpreg2)
+		: "r" (page), "i" (MMU_REG_BASE), "i" (MSVA_offset),
+		"i" (MTOP_offset), "i" (MIDXI_offset)
+		: "memory"
+	);
+}
+
+static __inline__ void __flush_tlb_all(void)
+{
+	unsigned int tmpreg0, tmpreg1;
+
+	__asm__ __volatile__ (
+		"seth	%0, #high(%2)		\n\t"
+		"or3	%0, %0, #low(%2)	\n\t"
+		"ldi	%1, #0xc		\n\t"
+		"st	%1, @%0			\n\t"
+		".fillinsn			\n"
+		"1:				\n\t"
+		"ld	%1, @%0			\n\t"
+		"bnez	%1, 1b			\n\t"
+		: "=&r" (tmpreg0), "=&r" (tmpreg1)
+		: "i" (MTOP) : "memory"
+	);
+}
+
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+
+#endif	/* _ASM_M32R_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/tlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+#ifndef _M32R_TLB_H
+#define _M32R_TLB_H
+
+/*
+ * x86 doesn't need any special per-pte or
+ * per-vma handling..
+ */
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it
+ * fills up.
+ */
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _M32R_TLB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/topology.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_TOPOLOGY_H
+#define _ASM_M32R_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_M32R_TOPOLOGY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/types.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+#ifndef _ASM_M32R_TYPES_H
+#define _ASM_M32R_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+/* DMA addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+typedef u64 dma64_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_M32R_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/uaccess.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,693 @@
+#ifndef _ASM_M32R_UACCESS_H
+#define _ASM_M32R_UACCESS_H
+
+/*
+ *  linux/include/asm-m32r/uaccess.h
+ *
+ *  M32R version.
+ *    Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+/*
+ * User space memory access functions
+ */
+#include <linux/errno.h>
+#include <linux/thread_info.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#ifdef CONFIG_MMU
+
+#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
+#define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(current_thread_info()->addr_limit)
+#define set_fs(x)	(current_thread_info()->addr_limit = (x))
+
+#else /* not CONFIG_MMU */
+
+#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
+#define USER_DS		MAKE_MM_SEG(0xFFFFFFFF)
+#define get_ds()	(KERNEL_DS)
+
+static inline mm_segment_t get_fs(void)
+{
+	return USER_DS;
+}
+
+static inline void set_fs(mm_segment_t s)
+{
+}
+
+#endif /* not CONFIG_MMU */
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#define __addr_ok(addr) \
+	((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
+
+/*
+ * Test whether a block of memory is a valid user space address.
+ * Returns 0 if the range is valid, nonzero otherwise.
+ *
+ * This is equivalent to the following test:
+ * (u33)addr + (u33)size >= (u33)current->addr_limit.seg
+ *
+ * This needs 33-bit arithmetic. We have a carry...
+ */
+#define __range_ok(addr,size) ({					\
+	unsigned long flag, roksum; 					\
+	__chk_user_ptr(addr);						\
+	asm ( 								\
+		"	cmpu	%1, %1    ; clear cbit\n"		\
+		"	addx	%1, %3    ; set cbit if overflow\n"	\
+		"	subx	%0, %0\n"				\
+		"	cmpu	%4, %1\n"				\
+		"	subx	%0, %5\n"				\
+		: "=&r" (flag), "=r" (roksum)				\
+		: "1" (addr), "r" ((int)(size)), 			\
+		  "r" (current_thread_info()->addr_limit.seg), "r" (0)	\
+		: "cbit" );						\
+	flag; })
+
+/**
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
+ *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ *        to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+#ifdef CONFIG_MMU
+#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
+#else
+static inline int access_ok(int type, const void *addr, unsigned long size)
+{
+	unsigned long val = (unsigned long)addr;
+
+	return ((val >= memory_start) && ((val + size) < memory_end));
+}
+#endif /* CONFIG_MMU */
+
+/*
+ * 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
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ */
+
+/* Careful: we have to cast the result to the type of the pointer for sign
+   reasons */
+/**
+ * get_user: - Get a simple variable from user space.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define get_user(x,ptr)							\
+	__get_user_check((x),(ptr),sizeof(*(ptr)))
+
+/**
+ * put_user: - Write a simple value into user space.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define put_user(x,ptr)							\
+	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+/**
+ * __get_user: - Get a simple variable from user space, with less checking.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define __get_user(x,ptr) \
+	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+#define __get_user_nocheck(x,ptr,size)					\
+({									\
+	long __gu_err = 0;						\
+	unsigned long __gu_val;						\
+	might_sleep();							\
+	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+#define __get_user_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT;					\
+	unsigned long __gu_val = 0;					\
+	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
+	might_sleep();							\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)				\
+do {									\
+	retval = 0;							\
+	__chk_user_ptr(ptr);						\
+	switch (size) {							\
+	  case 1: __get_user_asm(x,ptr,retval,"ub"); break;		\
+	  case 2: __get_user_asm(x,ptr,retval,"uh"); break;		\
+	  case 4: __get_user_asm(x,ptr,retval,""); break;		\
+	  default: (x) = __get_user_bad();				\
+	}								\
+} while (0)
+
+#define __get_user_asm(x, addr, err, itype)				\
+	__asm__ __volatile__(						\
+		"	.fillinsn\n"					\
+		"1:	ld"itype" %1,@%2\n"				\
+		"	.fillinsn\n"					\
+		"2:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"	.balign 4\n"					\
+		"3:	ldi %0,%3\n"					\
+		"	seth r14,#high(2b)\n"				\
+		"	or3 r14,r14,#low(2b)\n"				\
+		"	jmp r14\n"					\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		"	.balign 4\n"					\
+		"	.long 1b,3b\n"					\
+		".previous"						\
+		: "=&r" (err), "=&r" (x)				\
+		: "r" (addr), "i" (-EFAULT), "0" (err)			\
+		: "r14", "memory")
+
+/**
+ * __put_user: - Write a simple value into user space, with less checking.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define __put_user(x,ptr) \
+	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+
+#define __put_user_nocheck(x,ptr,size)					\
+({									\
+	long __pu_err;							\
+	might_sleep();							\
+	__put_user_size((x),(ptr),(size),__pu_err);			\
+	__pu_err;							\
+})
+
+
+#define __put_user_check(x,ptr,size)					\
+({									\
+	long __pu_err = -EFAULT;					\
+	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
+	might_sleep();							\
+	if (access_ok(VERIFY_WRITE,__pu_addr,size))			\
+		__put_user_size((x),__pu_addr,(size),__pu_err);		\
+	__pu_err;							\
+})
+
+#if defined(__LITTLE_ENDIAN__)
+#define __put_user_u64(x, addr, err)					\
+        __asm__ __volatile__(						\
+                "       .fillinsn\n"					\
+                "1:     st %L1,@%2\n"					\
+                "       .fillinsn\n"					\
+                "2:     st %H1,@(4,%2)\n"				\
+                "       .fillinsn\n"					\
+                "3:\n"							\
+                ".section .fixup,\"ax\"\n"				\
+                "       .balign 4\n"					\
+                "4:     ldi %0,%3\n"					\
+                "       seth r14,#high(3b)\n"				\
+                "       or3 r14,r14,#low(3b)\n"				\
+                "       jmp r14\n"					\
+                ".previous\n"						\
+                ".section __ex_table,\"a\"\n"				\
+                "       .balign 4\n"					\
+                "       .long 1b,4b\n"					\
+                "       .long 2b,4b\n"					\
+                ".previous"						\
+                : "=&r" (err)						\
+                : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
+                : "r14", "memory")
+
+#elif defined(__BIG_ENDIAN__)
+#define __put_user_u64(x, addr, err)					\
+	__asm__ __volatile__(						\
+		"	.fillinsn\n"					\
+		"1:	st %H1,@%2\n"					\
+		"	.fillinsn\n"					\
+		"2:	st %L1,@(4,%2)\n"				\
+		"	.fillinsn\n"					\
+		"3:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"	.balign 4\n"					\
+		"4:	ldi %0,%3\n"					\
+		"	seth r14,#high(3b)\n"				\
+		"	or3 r14,r14,#low(3b)\n"				\
+		"	jmp r14\n"					\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		"	.balign 4\n"					\
+		"	.long 1b,4b\n"					\
+		"	.long 2b,4b\n"					\
+		".previous"						\
+		: "=&r" (err)						\
+		: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
+		: "r14", "memory")
+#else
+#error no endian defined
+#endif
+
+extern void __put_user_bad(void);
+
+#define __put_user_size(x,ptr,size,retval)				\
+do {									\
+	retval = 0;							\
+	__chk_user_ptr(ptr);						\
+	switch (size) {							\
+	  case 1: __put_user_asm(x,ptr,retval,"b"); break;		\
+	  case 2: __put_user_asm(x,ptr,retval,"h"); break;		\
+	  case 4: __put_user_asm(x,ptr,retval,""); break;		\
+	  case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\
+	  default: __put_user_bad();					\
+	}								\
+} while (0)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+#define __put_user_asm(x, addr, err, itype)				\
+	__asm__ __volatile__(						\
+		"	.fillinsn\n"					\
+		"1:	st"itype" %1,@%2\n"				\
+		"	.fillinsn\n"					\
+		"2:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"	.balign 4\n"					\
+		"3:	ldi %0,%3\n"					\
+		"	seth r14,#high(2b)\n"				\
+		"	or3 r14,r14,#low(2b)\n"				\
+		"	jmp r14\n"					\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		"	.balign 4\n"					\
+		"	.long 1b,3b\n"					\
+		".previous"						\
+		: "=&r" (err)						\
+		: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
+		: "r14", "memory")
+
+/*
+ * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault
+ * we return the initial request size (1, 2 or 4), as copy_*_user should do.
+ * If a store crosses a page boundary and gets a fault, the m32r will not write
+ * anything, so this is accurate.
+ */
+
+/*
+ * Copy To/From Userspace
+ */
+
+/* Generic arbitrary sized copy.  */
+/* Return the number of bytes NOT copied.  */
+#define __copy_user(to,from,size)					\
+do {									\
+	unsigned long __dst, __src, __c;				\
+	__asm__ __volatile__ (						\
+		"	mv	r14, %0\n"				\
+		"	or	r14, %1\n"				\
+		"	beq	%0, %1, 9f\n"				\
+		"	beqz	%2, 9f\n"				\
+		"	and3	r14, r14, #3\n"				\
+		"	bnez	r14, 2f\n"				\
+		"	and3	%2, %2, #3\n"				\
+		"	beqz	%3, 2f\n"				\
+		"	addi	%0, #-4		; word_copy \n"		\
+		"	.fillinsn\n"					\
+		"0:	ld	r14, @%1+\n"				\
+		"	addi	%3, #-1\n"				\
+		"	.fillinsn\n"					\
+		"1:	st	r14, @+%0\n"				\
+		"	bnez	%3, 0b\n"				\
+		"	beqz	%2, 9f\n"				\
+		"	addi	%0, #4\n"				\
+		"	.fillinsn\n"					\
+		"2:	ldb	r14, @%1	; byte_copy \n"		\
+		"	.fillinsn\n"					\
+		"3:	stb	r14, @%0\n"				\
+		"	addi	%1, #1\n"				\
+		"	addi	%2, #-1\n"				\
+		"	addi	%0, #1\n"				\
+		"	bnez	%2, 2b\n"				\
+		"	.fillinsn\n"					\
+		"9:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"	.balign 4\n"					\
+		"5:	addi	%3, #1\n"				\
+		"	addi	%1, #-4\n"				\
+		"	.fillinsn\n"					\
+		"6:	slli	%3, #2\n"				\
+		"	add	%2, %3\n"				\
+		"	addi	%0, #4\n"				\
+		"	.fillinsn\n"					\
+		"7:	seth	r14, #high(9b)\n"			\
+		"	or3	r14, r14, #low(9b)\n"			\
+		"	jmp	r14\n"					\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		"	.balign 4\n"					\
+		"	.long 0b,6b\n"					\
+		"	.long 1b,5b\n"					\
+		"	.long 2b,9b\n"					\
+		"	.long 3b,9b\n"					\
+		".previous\n"						\
+		: "=&r" (__dst), "=&r" (__src), "=&r" (size),		\
+		  "=&r" (__c)						\
+		: "0" (to), "1" (from), "2" (size), "3" (size / 4)	\
+		: "r14", "memory");					\
+} while (0)
+
+#define __copy_user_zeroing(to,from,size)				\
+do {									\
+	unsigned long __dst, __src, __c;				\
+	__asm__ __volatile__ (						\
+		"	mv	r14, %0\n"				\
+		"	or	r14, %1\n"				\
+		"	beq	%0, %1, 9f\n"				\
+		"	beqz	%2, 9f\n"				\
+		"	and3	r14, r14, #3\n"				\
+		"	bnez	r14, 2f\n"				\
+		"	and3	%2, %2, #3\n"				\
+		"	beqz	%3, 2f\n"				\
+		"	addi	%0, #-4		; word_copy \n"		\
+		"	.fillinsn\n"					\
+		"0:	ld	r14, @%1+\n"				\
+		"	addi	%3, #-1\n"				\
+		"	.fillinsn\n"					\
+		"1:	st	r14, @+%0\n"				\
+		"	bnez	%3, 0b\n"				\
+		"	beqz	%2, 9f\n"				\
+		"	addi	%0, #4\n"				\
+		"	.fillinsn\n"					\
+		"2:	ldb	r14, @%1	; byte_copy \n"		\
+		"	.fillinsn\n"					\
+		"3:	stb	r14, @%0\n"				\
+		"	addi	%1, #1\n"				\
+		"	addi	%2, #-1\n"				\
+		"	addi	%0, #1\n"				\
+		"	bnez	%2, 2b\n"				\
+		"	.fillinsn\n"					\
+		"9:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"	.balign 4\n"					\
+		"5:	addi	%3, #1\n"				\
+		"	addi	%1, #-4\n"				\
+		"	.fillinsn\n"					\
+		"6:	slli	%3, #2\n"				\
+		"	add	%2, %3\n"				\
+		"	addi	%0, #4\n"				\
+		"	.fillinsn\n"					\
+		"7:	ldi	r14, #0		; store zero \n"	\
+		"	.fillinsn\n"					\
+		"8:	addi	%2, #-1\n"				\
+		"	stb	r14, @%0	; ACE? \n"		\
+		"	addi	%0, #1\n"				\
+		"	bnez	%2, 8b\n"				\
+		"	seth	r14, #high(9b)\n"			\
+		"	or3	r14, r14, #low(9b)\n"			\
+		"	jmp	r14\n"					\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		"	.balign 4\n"					\
+		"	.long 0b,6b\n"					\
+		"	.long 1b,5b\n"					\
+		"	.long 2b,7b\n"					\
+		"	.long 3b,7b\n"					\
+		".previous\n"						\
+		: "=&r" (__dst), "=&r" (__src), "=&r" (size),		\
+		  "=&r" (__c)						\
+		: "0" (to), "1" (from), "2" (size), "3" (size / 4)	\
+		: "r14", "memory");					\
+} while (0)
+
+
+/* We let the __ versions of copy_from/to_user inline, because they're often
+ * used in fast paths and have only a small space overhead.
+ */
+static inline unsigned long __generic_copy_from_user_nocheck(void *to,
+	const void __user *from, unsigned long n)
+{
+	__copy_user_zeroing(to,from,n);
+	return n;
+}
+
+static inline unsigned long __generic_copy_to_user_nocheck(void __user *to,
+	const void *from, unsigned long n)
+{
+	__copy_user(to,from,n);
+	return n;
+}
+
+unsigned long __generic_copy_to_user(void __user *, const void *, unsigned long);
+unsigned long __generic_copy_from_user(void *, const void __user *, unsigned long);
+
+/**
+ * __copy_to_user: - Copy a block of data into user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from kernel space to user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+#define __copy_to_user(to,from,n)			\
+	__generic_copy_to_user_nocheck((to),(from),(n))
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+/**
+ * copy_to_user: - Copy a block of data into user space.
+ * @to:   Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from kernel space to user space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+#define copy_to_user(to,from,n)				\
+({							\
+	might_sleep();					\
+	__generic_copy_to_user((to),(from),(n));	\
+})
+
+/**
+ * __copy_from_user: - Copy a block of data from user space, with less checking. * @to:   Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from user space to kernel space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
+#define __copy_from_user(to,from,n)			\
+	__generic_copy_from_user_nocheck((to),(from),(n))
+
+/**
+ * copy_from_user: - Copy a block of data from user space.
+ * @to:   Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from user space to kernel space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
+#define copy_from_user(to,from,n)			\
+({							\
+	might_sleep();					\
+	__generic_copy_from_user((to),(from),(n));	\
+})
+
+long __must_check strncpy_from_user(char *dst, const char __user *src,
+				long count);
+long __must_check __strncpy_from_user(char *dst,
+				const char __user *src, long count);
+
+/**
+ * __clear_user: - Zero a block of memory in user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+unsigned long __clear_user(void __user *mem, unsigned long len);
+
+/**
+ * clear_user: - Zero a block of memory in user space.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+unsigned long clear_user(void __user *mem, unsigned long len);
+
+/**
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+long strnlen_user(const char __user *str, long n);
+
+#endif /* _ASM_M32R_UACCESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ucontext.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ucontext.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/ucontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/ucontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _ASM_M32R_UCONTEXT_H
+#define _ASM_M32R_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _ASM_M32R_UCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/unaligned.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/unaligned.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/unaligned.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/unaligned.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+#ifndef _ASM_M32R_UNALIGNED_H
+#define _ASM_M32R_UNALIGNED_H
+
+#if defined(__LITTLE_ENDIAN__)
+# include <linux/unaligned/le_memmove.h>
+# include <linux/unaligned/be_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned	__get_unaligned_le
+# define put_unaligned	__put_unaligned_le
+#else
+# include <linux/unaligned/be_memmove.h>
+# include <linux/unaligned/le_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned	__get_unaligned_be
+# define put_unaligned	__put_unaligned_be
+#endif
+
+#endif /* _ASM_M32R_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/unistd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,389 @@
+#ifndef _ASM_M32R_UNISTD_H
+#define _ASM_M32R_UNISTD_H
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall	  0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+/* 16 is unused */
+/* 17 is unused */
+/* 18 is unused */
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+/* 23 is unused */
+/* 24 is unused */
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+/* 28 is unused */
+#define __NR_pause		 29
+#define __NR_utime		 30
+/* 31 is unused */
+#define __NR_cachectl		 32 /* old #define __NR_gtty		 32*/
+#define __NR_access		 33
+/* 34 is unused */
+/* 35 is unused */
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+/* 44 is unused */
+#define __NR_brk		 45
+/* 46 is unused */
+/* 47 is unused (getgid16) */
+/* 48 is unused */
+/* 49 is unused */
+/* 50 is unused */
+#define __NR_acct		 51
+#define __NR_umount2		 52
+/* 53 is unused */
+#define __NR_ioctl		 54
+/* 55 is unused (fcntl) */
+/* 56 is unused */
+#define __NR_setpgid		 57
+/* 58 is unused */
+/* 59 is unused */
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+/* 67 is unused */
+/* 68 is unused*/
+/* 69 is unused*/
+/* 70 is unused */
+/* 71 is unused */
+/* 72 is unused */
+/* 73 is unused */
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+/* 76 is unused (old getrlimit) */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+/* 80 is unused */
+/* 81 is unused */
+/* 82 is unused */
+#define __NR_symlink		 83
+/* 84 is unused */
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+/* 89 is unused */
+/* 90 is unused */
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+/* 95 is unused */
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+/* 98 is unused */
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+/* 101 is unused */
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+/* 109 is unused */
+/* 110 is unused */
+#define __NR_vhangup		111
+/* 112 is unused */
+/* 113 is unused */
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+/* 119 is unused */
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+/* 123 is unused */
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+/* 126 is unused */
+/* 127 is unused */
+#define __NR_init_module	128
+#define __NR_delete_module	129
+/* 130 is unused */
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+/* 137 is unused */
+/* 138 is unused */
+/* 139 is unused */
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+/* 164 is unused */
+/* 165 is unused */
+#define __NR_tas		166
+/* 167 is unused */
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+/* 170 is unused */
+/* 171 is unused */
+#define __NR_prctl              172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64		180
+#define __NR_pwrite64		181
+/* 182 is unused */
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+/* 188 is unused */
+/* 189 is unused */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+/* 222 is unused */
+/* 223 is unused */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+/* 251 is unused */
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#define __NR_mq_timedreceive	(__NR_mq_open+3)
+#define __NR_mq_notify		(__NR_mq_open+4)
+#define __NR_mq_getsetattr	(__NR_mq_open+5)
+#define __NR_kexec_load		283
+#define __NR_waitid		284
+/* 285 is unused */
+#define __NR_add_key		286
+#define __NR_request_key	287
+#define __NR_keyctl		288
+#define __NR_ioprio_set		289
+#define __NR_ioprio_get		290
+#define __NR_inotify_init	291
+#define __NR_inotify_add_watch	292
+#define __NR_inotify_rm_watch	293
+#define __NR_migrate_pages	294
+#define __NR_openat		295
+#define __NR_mkdirat		296
+#define __NR_mknodat		297
+#define __NR_fchownat		298
+#define __NR_futimesat		299
+#define __NR_fstatat64		300
+#define __NR_unlinkat		301
+#define __NR_renameat		302
+#define __NR_linkat		303
+#define __NR_symlinkat		304
+#define __NR_readlinkat		305
+#define __NR_fchmodat		306
+#define __NR_faccessat		307
+#define __NR_pselect6		308
+#define __NR_ppoll		309
+#define __NR_unshare		310
+#define __NR_set_robust_list	311
+#define __NR_get_robust_list	312
+#define __NR_splice		313
+#define __NR_sync_file_range	314
+#define __NR_tee		315
+#define __NR_vmsplice		316
+#define __NR_move_pages		317
+#define __NR_getcpu		318
+#define __NR_epoll_pwait	319
+#define __NR_utimensat		320
+#define __NR_signalfd		321
+/* #define __NR_timerfd		322 removed */
+#define __NR_eventfd		323
+#define __NR_fallocate		324
+
+#ifdef __KERNEL__
+
+#define NR_syscalls 325
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_RT_SIGACTION
+
+#define __IGNORE_lchown
+#define __IGNORE_setuid
+#define __IGNORE_getuid
+#define __IGNORE_setgid
+#define __IGNORE_getgid
+#define __IGNORE_geteuid
+#define __IGNORE_getegid
+#define __IGNORE_fcntl
+#define __IGNORE_setreuid
+#define __IGNORE_setregid
+#define __IGNORE_getrlimit
+#define __IGNORE_getgroups
+#define __IGNORE_setgroups
+#define __IGNORE_select
+#define __IGNORE_mmap
+#define __IGNORE_fchown
+#define __IGNORE_setfsuid
+#define __IGNORE_setfsgid
+#define __IGNORE_setresuid
+#define __IGNORE_getresuid
+#define __IGNORE_setresgid
+#define __IGNORE_getresgid
+#define __IGNORE_chown
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#ifndef cond_syscall
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_M32R_UNISTD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/user.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/user.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/user.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+#ifndef _ASM_M32R_USER_H
+#define _ASM_M32R_USER_H
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd).
+ *
+ * The actual file contents are as follows:
+ * UPAGE: 1 page consisting of a user struct that tells gdb
+ *	what is present in the file.  Directly after this is a
+ *	copy of the task_struct, which is currently not used by gdb,
+ *	but it may come in handy at some point.  All of the registers
+ *	are stored as part of the upage.  The upage should always be
+ *	only one page.
+ * DATA: The data area is stored.  We use current->end_text to
+ *	current->brk to pick up all of the user variables, plus any memory
+ *	that may have been sbrk'ed.  No attempt is made to determine if a
+ *	page is demand-zero or if a page is totally unused, we just cover
+ *	the entire range.  All of the addresses are rounded in such a way
+ *	that an integral number of pages is written.
+ * STACK: We need the stack information in order to get a meaningful
+ *	backtrace.  We need to write the data from usp to
+ *	current->start_stack, so we round each of these off in order to be
+ *	able to write an integer number of pages.
+ */
+
+struct user {
+	struct pt_regs	regs;			/* entire machine state */
+	size_t		u_tsize;		/* text size (pages) */
+	size_t		u_dsize;		/* data size (pages) */
+	size_t		u_ssize;		/* stack size (pages) */
+	unsigned long	start_code;		/* text starting address */
+	unsigned long	start_data;		/* data starting address */
+	unsigned long	start_stack;		/* stack starting address */
+	long int	signal;			/* signal causing core dump */
+	unsigned long	u_ar0;			/* help gdb find registers */
+	unsigned long	magic;			/* identifies a core file */
+	char		u_comm[32];		/* user command name */
+};
+
+#define NBPG			PAGE_SIZE
+#define UPAGES			1
+#define HOST_TEXT_START_ADDR	(u.start_code)
+#define HOST_DATA_START_ADDR	(u.start_data)
+#define HOST_STACK_END_ADDR	(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _ASM_M32R_USER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/vga.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/vga.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/vga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+#ifndef _ASM_M32R_VGA_H
+#define _ASM_M32R_VGA_H
+
+/*
+ *	Access to VGA videoram
+ *
+ *	(c) 1998 Martin Mares <mj@ucw.cz>
+ */
+
+/*
+ *	On the PC, we can just recalculate addresses and then
+ *	access the videoram directly without any black magic.
+ */
+
+#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
+
+#define vga_readb(x) (*(x))
+#define vga_writeb(x,y) (*(y) = (x))
+
+#endif /* _ASM_M32R_VGA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/include/asm/xor.h linux-libre-2.6.30-gnu1/arch/m32r/include/asm/xor.h
--- linux-libre-2.6.29-gnu1/arch/m32r/include/asm/xor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m32r/include/asm/xor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_M32R_XOR_H
+#define _ASM_M32R_XOR_H
+
+#include <asm-generic/xor.h>
+
+#endif  /* _ASM_M32R_XOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/head.S linux-libre-2.6.30-gnu1/arch/m32r/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@ __INITDATA
 /*
  * References to members of the boot_cpu_data structure.
  */
-.section .text.head, "ax"
+__HEAD
 	.global	start_kernel
 	.global __bss_start
 	.global _end
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/irq.c linux-libre-2.6.30-gnu1/arch/m32r/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,7 +49,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/Makefile linux-libre-2.6.30-gnu1/arch/m32r/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,5 +9,3 @@ obj-y	:= process.o entry.o traps.o align
 
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o
 obj-$(CONFIG_MODULES)		+= module.o
-
-EXTRA_AFLAGS	:= -traditional
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/process.c linux-libre-2.6.30-gnu1/arch/m32r/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -225,7 +225,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 	return 0; /* Task didn't use the fpu at all. */
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
+int copy_thread(unsigned long clone_flags, unsigned long spu,
 	unsigned long unused, struct task_struct *tsk, struct pt_regs *regs)
 {
 	struct pt_regs *childregs = task_pt_regs(tsk);
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/time.c linux-libre-2.6.30-gnu1/arch/m32r/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -230,7 +230,6 @@ static irqreturn_t timer_interrupt(int i
 static struct irqaction irq0 = {
 	.handler = timer_interrupt,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "MFT2",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/m32r/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/m32r/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/m32r/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m32r/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@ SECTIONS
   _text = .;			/* Text and read-only data */
   .boot : { *(.boot) } = 0
   .text : {
-	*(.text.head)
+	HEAD_TEXT
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/amiga_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/amiga_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/amiga_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/amiga_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:42 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:47:52 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -140,12 +151,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -157,7 +169,7 @@ CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
 CONFIG_ZORRO=y
 CONFIG_AMIGA_PCMCIA=y
-# CONFIG_HEARTBEAT is not set
+CONFIG_HEARTBEAT=y
 CONFIG_PROC_HARDWARE=y
 CONFIG_ISA=y
 CONFIG_GENERIC_ISA_DMA=y
@@ -184,7 +196,10 @@ 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_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=m
 CONFIG_NET_IPGRE=m
 # CONFIG_ARPD is not set
@@ -258,6 +273,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -266,6 +282,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -276,6 +293,7 @@ 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
@@ -354,25 +372,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -394,8 +407,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -406,8 +421,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -453,15 +468,20 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -469,7 +489,6 @@ CONFIG_IDE_GD_ATA=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -478,7 +497,6 @@ CONFIG_IDE_PROC_FS=y
 #
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_GAYLE=y
-CONFIG_BLK_DEV_IDEDOUBLER=y
 CONFIG_BLK_DEV_BUDDHA=y
 # CONFIG_BLK_DEV_IDEDMA is not set
 
@@ -530,6 +548,8 @@ CONFIG_ISCSI_TCP=m
 # 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
@@ -547,6 +567,7 @@ CONFIG_GVP11_SCSI=y
 CONFIG_SCSI_A4000T=y
 CONFIG_SCSI_ZORRO7XX=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -554,7 +575,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -567,6 +588,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -577,14 +599,16 @@ CONFIG_VETH=m
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-CONFIG_ARIADNE=m
-CONFIG_A2065=m
-CONFIG_HYDRA=m
-CONFIG_ZORRO8390=m
-CONFIG_APNE=m
+CONFIG_ARIADNE=y
+CONFIG_A2065=y
+CONFIG_HYDRA=y
+CONFIG_ZORRO8390=y
+CONFIG_APNE=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_ETHOC 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
@@ -609,7 +633,10 @@ CONFIG_APNE=m
 #
 # 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_PLIP is not set
 CONFIG_PPP=m
@@ -719,7 +746,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_DEVKMEM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_A2232=m
+CONFIG_A2232=y
 
 #
 # Serial drivers
@@ -730,6 +757,7 @@ CONFIG_A2232=m
 # Non-8250 serial port support
 #
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_PRINTER=m
@@ -821,6 +849,7 @@ CONFIG_FB_FM2=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
 
 #
@@ -856,7 +885,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -867,14 +895,13 @@ CONFIG_HID_COMPAT=y
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
 #
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 CONFIG_MULTIFACE_III_TTY=m
-# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_SERIAL_CONSOLE=y
 
 #
 # File systems
@@ -883,6 +910,7 @@ 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
@@ -909,13 +937,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -924,6 +954,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -935,8 +970,8 @@ CONFIG_UDF_NLS=y
 #
 # DOS/FAT/NT Filesystems
 #
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
@@ -954,10 +989,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -966,6 +998,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -976,23 +1011,24 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=m
+CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=m
+CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
-CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
@@ -1067,11 +1103,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1092,13 +1123,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1113,7 +1152,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 # Block modes
 #
-CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_CTR=m
 CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
@@ -1132,7 +1171,7 @@ CONFIG_CRYPTO_XCBC=m
 #
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -1154,7 +1193,7 @@ CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_SALSA20=m
@@ -1168,6 +1207,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1175,11 +1215,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1191,10 +1233,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/apollo_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/apollo_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/apollo_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/apollo_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:43 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:47:54 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -140,12 +151,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -256,6 +268,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -264,6 +277,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -274,6 +288,7 @@ 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
@@ -352,25 +367,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -392,8 +402,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -404,8 +416,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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,9 +453,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -491,8 +507,11 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -500,7 +519,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -513,6 +532,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -522,6 +542,8 @@ CONFIG_VETH=m
 # 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
@@ -538,7 +560,10 @@ CONFIG_NET_ETHERNET=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -596,7 +621,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -636,6 +660,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -718,6 +743,7 @@ CONFIG_FB_APOLLO=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
 
 #
@@ -749,7 +775,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -757,9 +782,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -774,6 +799,7 @@ 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
@@ -800,13 +826,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -815,6 +843,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -845,10 +878,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -857,6 +887,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -867,6 +900,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -883,7 +917,6 @@ 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=m
@@ -958,11 +991,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -983,13 +1011,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1059,6 +1095,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1066,11 +1103,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1082,10 +1121,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/atari_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/atari_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/atari_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/atari_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:44 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:47:56 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -140,12 +151,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -180,7 +192,10 @@ 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_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=m
 CONFIG_NET_IPGRE=m
 # CONFIG_ARPD is not set
@@ -254,6 +269,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -262,6 +278,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -272,6 +289,7 @@ 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
@@ -350,25 +368,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -390,8 +403,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -402,8 +417,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -445,15 +460,20 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -461,7 +481,6 @@ CONFIG_IDE_GD_ATA=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -516,11 +535,14 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_ATARI_SCSI=y
 # CONFIG_ATARI_SCSI_TOSHIBA_DELAY is not set
 # CONFIG_ATARI_SCSI_RESET_BOOT is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -528,7 +550,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -541,6 +563,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -550,7 +573,9 @@ CONFIG_VETH=m
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-CONFIG_ATARILANCE=m
+CONFIG_ATARILANCE=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
@@ -568,7 +593,10 @@ CONFIG_ATARILANCE=m
 #
 # 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_PLIP is not set
 CONFIG_PPP=m
@@ -625,11 +653,10 @@ CONFIG_INPUT_KEYBOARD=y
 CONFIG_ATARI_KBD_CORE=y
 CONFIG_KEYBOARD_ATARI=y
 CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -649,7 +676,7 @@ CONFIG_INPUT_M68K_BEEP=m
 CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
@@ -673,6 +700,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_PRINTER=m
@@ -760,6 +788,7 @@ CONFIG_FB_ATARI=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
 
 #
@@ -794,7 +823,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -805,14 +833,14 @@ CONFIG_HID_COMPAT=y
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
 #
-CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_MIDI=m
+CONFIG_ATARI_MFPSER=y
+CONFIG_ATARI_MIDI=y
 CONFIG_ATARI_DSP56K=m
+CONFIG_SERIAL_CONSOLE=y
 
 #
 # File systems
@@ -821,6 +849,7 @@ 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
@@ -847,13 +876,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -862,6 +893,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -892,10 +928,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -904,6 +937,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -914,22 +950,24 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=m
+CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
+CONFIG_NFS_V4=y
+# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=m
+CONFIG_LOCKD=y
 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_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
@@ -1004,11 +1042,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1029,13 +1062,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1050,7 +1091,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 # Block modes
 #
-CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_CTR=m
 CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
@@ -1069,7 +1110,7 @@ CONFIG_CRYPTO_XCBC=m
 #
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -1091,7 +1132,7 @@ CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_SALSA20=m
@@ -1105,6 +1146,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1112,11 +1154,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=y
 CONFIG_CRC_T10DIF=y
@@ -1128,10 +1172,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/bvme6000_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/bvme6000_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/bvme6000_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/bvme6000_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:45 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:47:59 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -143,12 +154,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -258,6 +270,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -266,6 +279,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -276,6 +290,7 @@ 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
@@ -354,25 +369,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -394,8 +404,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -406,8 +418,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -443,9 +455,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -493,10 +509,13 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_BVME6000_SCSI=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -504,7 +523,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -517,6 +536,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -527,6 +547,8 @@ CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_BVME6000_NET=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
@@ -543,7 +565,10 @@ CONFIG_BVME6000_NET=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -601,7 +626,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -641,6 +665,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -717,7 +742,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -725,9 +749,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -742,6 +766,7 @@ 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
@@ -768,13 +793,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -783,6 +810,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -813,10 +845,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -825,6 +854,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -835,6 +867,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -851,7 +884,6 @@ 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=m
@@ -927,11 +959,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -952,13 +979,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1028,6 +1063,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1035,11 +1071,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=m
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
@@ -1051,10 +1089,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/hp300_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/hp300_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/hp300_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/hp300_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:46 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:01 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -141,12 +152,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -257,6 +269,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -265,6 +278,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -275,6 +289,7 @@ 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
@@ -353,25 +368,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -393,8 +403,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -405,8 +417,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -442,9 +454,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -492,8 +508,11 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -501,7 +520,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -514,6 +533,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -524,6 +544,8 @@ CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_HPLANCE=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
@@ -540,7 +562,10 @@ CONFIG_HPLANCE=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -600,7 +625,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -646,6 +670,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -728,6 +753,7 @@ CONFIG_FB_HP300=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
 
 #
@@ -759,7 +785,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -767,9 +792,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -782,6 +807,7 @@ 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
@@ -808,13 +834,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -823,6 +851,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -853,10 +886,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -865,6 +895,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -875,6 +908,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -891,7 +925,6 @@ 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=m
@@ -966,11 +999,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -991,13 +1019,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1067,6 +1103,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1074,11 +1111,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1090,10 +1129,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/mac_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/mac_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/mac_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/mac_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:47 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:03 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -142,12 +153,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -255,6 +267,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -263,6 +276,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -273,6 +287,7 @@ 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
@@ -351,25 +366,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -394,8 +404,10 @@ CONFIG_IPDDP_DECAP=y
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -406,8 +418,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -429,6 +441,7 @@ CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_SWIM=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
@@ -443,15 +456,20 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -459,7 +477,6 @@ CONFIG_IDE_GD_ATA=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -514,10 +531,13 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_MAC_SCSI=y
 CONFIG_SCSI_MAC_ESP=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -525,7 +545,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -547,6 +567,7 @@ CONFIG_ADB_CUDA=y
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -561,6 +582,8 @@ CONFIG_MAC89x0=m
 CONFIG_MACSONIC=m
 CONFIG_MACMACE=y
 # CONFIG_NET_VENDOR_SMC 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
@@ -577,7 +600,10 @@ CONFIG_MACMACE=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -635,7 +661,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -677,6 +702,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -760,6 +786,7 @@ CONFIG_FB_MAC=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
 
 #
@@ -793,7 +820,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -801,9 +827,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -819,6 +845,7 @@ 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
@@ -845,13 +872,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -860,6 +889,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -890,10 +924,7 @@ 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=m
 CONFIG_HFS_FS=y
@@ -902,6 +933,9 @@ CONFIG_HFSPLUS_FS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -912,6 +946,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
@@ -927,7 +962,6 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1003,11 +1037,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1028,13 +1057,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=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
@@ -1104,6 +1141,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1111,11 +1149,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1127,10 +1167,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/multi_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/multi_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/multi_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/multi_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:48 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:06 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -146,12 +157,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -268,6 +280,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -276,6 +289,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -286,6 +300,7 @@ 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
@@ -364,25 +379,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -408,8 +418,10 @@ CONFIG_IPDDP_DECAP=y
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -420,8 +432,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -454,6 +466,7 @@ CONFIG_PARPORT_NOT_PC=y
 CONFIG_BLK_DEV=y
 CONFIG_AMIGA_FLOPPY=y
 CONFIG_ATARI_FLOPPY=y
+CONFIG_BLK_DEV_SWIM=y
 CONFIG_AMIGA_Z2RAM=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -469,15 +482,20 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -485,7 +503,6 @@ CONFIG_IDE_GD_ATA=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -494,7 +511,6 @@ CONFIG_IDE_PROC_FS=y
 #
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_GAYLE=y
-CONFIG_BLK_DEV_IDEDOUBLER=y
 CONFIG_BLK_DEV_BUDDHA=y
 CONFIG_BLK_DEV_FALCON_IDE=y
 CONFIG_BLK_DEV_MAC_IDE=y
@@ -549,6 +565,8 @@ CONFIG_ISCSI_TCP=m
 # 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
@@ -575,6 +593,7 @@ CONFIG_MVME16x_SCSI=y
 CONFIG_BVME6000_SCSI=y
 CONFIG_SUN3X_ESP=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -582,7 +601,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -604,6 +623,7 @@ CONFIG_ADB_CUDA=y
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -614,24 +634,26 @@ CONFIG_VETH=m
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-CONFIG_ARIADNE=m
-CONFIG_A2065=m
-CONFIG_HYDRA=m
-CONFIG_ZORRO8390=m
-CONFIG_APNE=m
+CONFIG_ARIADNE=y
+CONFIG_A2065=y
+CONFIG_HYDRA=y
+CONFIG_ZORRO8390=y
+CONFIG_APNE=y
 CONFIG_MAC8390=y
-CONFIG_MAC89x0=m
-CONFIG_MACSONIC=m
+CONFIG_MAC89x0=y
+CONFIG_MACSONIC=y
 CONFIG_MACMACE=y
 CONFIG_MVME147_NET=y
 CONFIG_MVME16x_NET=y
 CONFIG_BVME6000_NET=y
-CONFIG_ATARILANCE=m
+CONFIG_ATARILANCE=y
 CONFIG_SUN3LANCE=y
 CONFIG_HPLANCE=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_ETHOC 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
@@ -657,7 +679,10 @@ CONFIG_NE2000=m
 #
 # 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_PLIP is not set
 CONFIG_PPP=m
@@ -717,11 +742,10 @@ CONFIG_KEYBOARD_ATARI=y
 CONFIG_KEYBOARD_HIL_OLD=y
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -732,7 +756,7 @@ CONFIG_MOUSE_SERIAL=m
 CONFIG_MOUSE_AMIGA=m
 CONFIG_MOUSE_ATARI=m
 # CONFIG_MOUSE_VSXXXAA is not set
-CONFIG_MOUSE_HIL=m
+CONFIG_MOUSE_HIL=y
 CONFIG_INPUT_JOYSTICK=y
 # CONFIG_JOYSTICK_ANALOG is not set
 # CONFIG_JOYSTICK_A3D is not set
@@ -763,18 +787,18 @@ CONFIG_JOYSTICK_AMIGA=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
 # CONFIG_INPUT_UINPUT is not set
-CONFIG_HP_SDC_RTC=m
+CONFIG_HP_SDC_RTC=y
 
 #
 # Hardware I/O ports
 #
 CONFIG_SERIO=y
 # CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_Q40KBD=m
+CONFIG_SERIO_Q40KBD=y
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_HP_SDC=y
 CONFIG_HIL_MLC=y
-CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_LIBPS2=m
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
@@ -788,7 +812,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_DEVKMEM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_A2232=m
+CONFIG_A2232=y
 
 #
 # Serial drivers
@@ -799,6 +823,7 @@ CONFIG_A2232=m
 # Non-8250 serial port support
 #
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_PRINTER=m
@@ -807,7 +832,7 @@ CONFIG_PRINTER=m
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_NVRAM=y
-CONFIG_GEN_RTC=m
+CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -898,6 +923,7 @@ CONFIG_FB_HP300=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
 
 #
@@ -937,7 +963,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -948,13 +973,12 @@ CONFIG_HID_COMPAT=y
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
 #
-CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_MIDI=m
+CONFIG_ATARI_MFPSER=y
+CONFIG_ATARI_MIDI=y
 CONFIG_ATARI_DSP56K=m
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 CONFIG_MULTIFACE_III_TTY=m
@@ -974,6 +998,7 @@ 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
@@ -1000,13 +1025,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -1015,6 +1042,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -1045,10 +1077,7 @@ 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=m
 CONFIG_HFS_FS=y
@@ -1057,6 +1086,9 @@ CONFIG_HFSPLUS_FS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -1067,6 +1099,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1083,7 +1116,6 @@ 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=m
@@ -1163,11 +1195,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1188,13 +1215,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1264,6 +1299,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1271,11 +1307,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=y
 CONFIG_CRC_T10DIF=y
@@ -1287,10 +1325,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/mvme147_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/mvme147_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/mvme147_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/mvme147_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:50 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:08 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -143,12 +154,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -258,6 +270,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -266,6 +279,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -276,6 +290,7 @@ 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
@@ -354,25 +369,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -394,8 +404,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -406,8 +418,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -443,9 +455,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -493,9 +509,12 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_MVME147_SCSI=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -503,7 +522,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -516,6 +535,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -526,6 +546,8 @@ CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MVME147_NET=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
@@ -542,7 +564,10 @@ CONFIG_MVME147_NET=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -600,7 +625,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -640,6 +664,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -716,7 +741,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -724,9 +748,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -741,6 +765,7 @@ 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
@@ -767,13 +792,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -782,6 +809,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -812,10 +844,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -824,6 +853,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -834,6 +866,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -850,7 +883,6 @@ 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=m
@@ -926,11 +958,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -951,13 +978,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1027,6 +1062,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1034,11 +1070,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1050,10 +1088,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/mvme16x_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/mvme16x_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/mvme16x_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/mvme16x_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:51 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:10 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -143,12 +154,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -258,6 +270,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -266,6 +279,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -276,6 +290,7 @@ 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
@@ -354,25 +369,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -394,8 +404,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -406,8 +418,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -443,9 +455,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -493,10 +509,13 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MVME16x_SCSI=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -504,7 +523,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -517,6 +536,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -527,6 +547,8 @@ CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_MVME16x_NET=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
@@ -543,7 +565,10 @@ CONFIG_MVME16x_NET=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -601,7 +626,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -641,6 +665,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -717,7 +742,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -725,9 +749,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -743,6 +767,7 @@ 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
@@ -769,13 +794,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -784,6 +811,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -814,10 +846,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -826,6 +855,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -836,6 +868,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -852,7 +885,6 @@ 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=m
@@ -928,11 +960,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -953,13 +980,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1029,6 +1064,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1036,11 +1072,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1052,10 +1090,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/q40_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/q40_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/q40_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/q40_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:52 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:13 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -140,12 +151,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -255,6 +267,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -263,6 +276,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -273,6 +287,7 @@ 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
@@ -351,25 +366,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -391,8 +401,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -403,8 +415,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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,15 +453,20 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -457,7 +474,6 @@ CONFIG_IDE_GD_ATA=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -516,6 +532,8 @@ CONFIG_ISCSI_TCP=m
 # 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
@@ -527,6 +545,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -534,7 +553,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -547,6 +566,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -559,7 +579,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_ETHOC 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
@@ -584,7 +606,10 @@ CONFIG_NE2000=m
 #
 # 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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -642,7 +667,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -688,6 +712,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -771,6 +796,7 @@ CONFIG_FB_Q40=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
 
 #
@@ -805,7 +831,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -813,9 +838,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -828,6 +853,7 @@ 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
@@ -854,13 +880,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -869,6 +897,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -899,10 +932,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -911,6 +941,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -921,6 +954,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -936,7 +970,6 @@ 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=m
@@ -1011,11 +1044,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -1036,13 +1064,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1112,6 +1148,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1119,11 +1156,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1135,10 +1174,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/sun3_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/sun3_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/sun3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/sun3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:53 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:16 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -138,12 +149,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -253,6 +265,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -261,6 +274,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -271,6 +285,7 @@ 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
@@ -349,25 +364,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -389,8 +399,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -401,8 +413,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -438,9 +450,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -488,9 +504,12 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_SUN3_SCSI=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -498,7 +517,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -511,6 +530,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -522,6 +542,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_SUN3LANCE=y
 CONFIG_SUN3_82586=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
@@ -537,7 +559,10 @@ CONFIG_SUN3_82586=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -595,7 +620,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -635,6 +659,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -710,6 +735,7 @@ CONFIG_FB=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
 
 #
@@ -741,16 +767,15 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # 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_CLASS is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -763,6 +788,7 @@ 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
@@ -789,13 +815,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -804,6 +832,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -834,10 +867,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -846,6 +876,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -856,6 +889,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -872,7 +906,6 @@ 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=m
@@ -948,11 +981,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -973,13 +1001,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1049,6 +1085,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1056,11 +1093,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1072,9 +1111,12 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/configs/sun3x_defconfig linux-libre-2.6.30-gnu1/arch/m68k/configs/sun3x_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68k/configs/sun3x_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/configs/sun3x_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Tue Dec  2 20:27:54 2008
+# Linux kernel version: 2.6.30-rc3
+# Wed Apr 22 20:48:20 2009
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -29,14 +29,24 @@ 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_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=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=y
 CONFIG_NAMESPACES=y
@@ -44,23 +54,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -68,15 +82,16 @@ 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_MARKERS 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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -84,11 +99,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=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -104,7 +116,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -140,12 +151,13 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=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_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # General setup
@@ -255,6 +267,7 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -263,6 +276,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -273,6 +287,7 @@ 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
@@ -351,25 +366,20 @@ 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_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+# CONFIG_IP_DCCP_CCID3 is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
@@ -391,8 +401,10 @@ CONFIG_ATALK=m
 # 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_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -403,8 +415,8 @@ CONFIG_NET_CLS_ROUTE=y
 # 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
 
@@ -440,9 +452,13 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_ATA_OVER_ETH=m
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -490,9 +506,12 @@ CONFIG_SCSI_SRP_ATTRS=m
 CONFIG_SCSI_SRP_TGT_ATTRS=y
 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_SUN3X_ESP=y
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -500,7 +519,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -513,6 +532,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -523,6 +543,8 @@ CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_SUN3LANCE=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
@@ -539,7 +561,10 @@ CONFIG_SUN3LANCE=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=m
 # CONFIG_PPP_MULTILINK is not set
@@ -597,7 +622,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -637,6 +661,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 # Non-8250 serial port support
 #
 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
@@ -718,6 +743,7 @@ CONFIG_FB=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
 
 #
@@ -749,7 +775,6 @@ CONFIG_HIDRAW=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -757,9 +782,9 @@ 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
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # Character devices
@@ -772,6 +797,7 @@ 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
@@ -798,13 +824,15 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
 # CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
-# CONFIG_OCFS2_COMPAT_JBD is not set
+# CONFIG_OCFS2_FS_POSIX_ACL is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
@@ -813,6 +841,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -843,10 +876,7 @@ 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=m
 CONFIG_HFS_FS=m
@@ -855,6 +885,9 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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=y
 # CONFIG_OMFS_FS is not set
@@ -865,6 +898,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -881,7 +915,6 @@ 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=m
@@ -957,11 +990,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -982,13 +1010,21 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=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_RNG=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
@@ -1058,6 +1094,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -1065,11 +1102,13 @@ CONFIG_CRYPTO_LZO=m
 #
 # 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=m
 CONFIG_CRC_T10DIF=y
@@ -1081,10 +1120,13 @@ 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_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,378 @@
-#ifdef __uClinux__
-#include "bootinfo_no.h"
-#else
-#include "bootinfo_mm.h"
+/*
+** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+**
+** Copyright 1992 by Greg Harp
+**
+** 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.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+**   Added bi_atari part of the machine dependent union bi_un; for now it
+**   contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+**   Renamed to setup.h; added some useful macros to allow gcc some
+**   optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+**   Redesign of the boot information structure; renamed to bootinfo.h again
+** 27/11/96 Geert Uytterhoeven:
+**   Backwards compatibility with bootinfo interface version 1.0
+*/
+
+#ifndef _M68K_BOOTINFO_H
+#define _M68K_BOOTINFO_H
+
+
+    /*
+     *  Bootinfo definitions
+     *
+     *  This is an easily parsable and extendable structure containing all
+     *  information to be passed from the bootstrap to the kernel.
+     *
+     *  This way I hope to keep all future changes back/forewards compatible.
+     *  Thus, keep your fingers crossed...
+     *
+     *  This structure is copied right after the kernel bss by the bootstrap
+     *  routine.
+     */
+
+#ifndef __ASSEMBLY__
+
+struct bi_record {
+    unsigned short tag;			/* tag ID */
+    unsigned short size;		/* size of record (in bytes) */
+    unsigned long data[0];		/* data */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+    /*
+     *  Tag Definitions
+     *
+     *  Machine independent tags start counting from 0x0000
+     *  Machine dependent tags start counting from 0x8000
+     */
+
+#define BI_LAST			0x0000	/* last record (sentinel) */
+#define BI_MACHTYPE		0x0001	/* machine type (u_long) */
+#define BI_CPUTYPE		0x0002	/* cpu type (u_long) */
+#define BI_FPUTYPE		0x0003	/* fpu type (u_long) */
+#define BI_MMUTYPE		0x0004	/* mmu type (u_long) */
+#define BI_MEMCHUNK		0x0005	/* memory chunk address and size */
+					/* (struct mem_info) */
+#define BI_RAMDISK		0x0006	/* ramdisk address and size */
+					/* (struct mem_info) */
+#define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
+					/* (string) */
+
+    /*
+     *  Amiga-specific tags
+     */
+
+#define BI_AMIGA_MODEL		0x8000	/* model (u_long) */
+#define BI_AMIGA_AUTOCON	0x8001	/* AutoConfig device */
+					/* (struct ConfigDev) */
+#define BI_AMIGA_CHIP_SIZE	0x8002	/* size of Chip RAM (u_long) */
+#define BI_AMIGA_VBLANK		0x8003	/* VBLANK frequency (u_char) */
+#define BI_AMIGA_PSFREQ		0x8004	/* power supply frequency (u_char) */
+#define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
+#define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
+#define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
+
+    /*
+     *  Atari-specific tags
+     */
+
+#define BI_ATARI_MCH_COOKIE	0x8000	/* _MCH cookie from TOS (u_long) */
+#define BI_ATARI_MCH_TYPE	0x8001	/* special machine type (u_long) */
+					/* (values are ATARI_MACH_* defines */
+
+/* mch_cookie values (upper word) */
+#define ATARI_MCH_ST		0
+#define ATARI_MCH_STE		1
+#define ATARI_MCH_TT		2
+#define ATARI_MCH_FALCON	3
+
+/* mch_type values */
+#define ATARI_MACH_NORMAL	0	/* no special machine type */
+#define ATARI_MACH_MEDUSA	1	/* Medusa 040 */
+#define ATARI_MACH_HADES	2	/* Hades 040 or 060 */
+#define ATARI_MACH_AB40		3	/* Afterburner040 on Falcon */
+
+    /*
+     *  VME-specific tags
+     */
+
+#define BI_VME_TYPE		0x8000	/* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO		0x8001	/* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define	VME_TYPE_TP34V		0x0034	/* Tadpole TP34V */
+#define VME_TYPE_MVME147	0x0147	/* Motorola MVME147 */
+#define VME_TYPE_MVME162	0x0162	/* Motorola MVME162 */
+#define VME_TYPE_MVME166	0x0166	/* Motorola MVME166 */
+#define VME_TYPE_MVME167	0x0167	/* Motorola MVME167 */
+#define VME_TYPE_MVME172	0x0172	/* Motorola MVME172 */
+#define VME_TYPE_MVME177	0x0177	/* Motorola MVME177 */
+#define VME_TYPE_BVME4000	0x4000	/* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000	0x6000	/* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards.  Contains board number, Bug version, board
+ * configuration options, etc.  See include/asm/mvme16xhw.h for details.
+ */
+
+
+    /*
+     *  Macintosh-specific tags (all u_long)
+     */
+
+#define BI_MAC_MODEL		0x8000	/* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR		0x8001	/* Mac video base address */
+#define BI_MAC_VDEPTH		0x8002	/* Mac video depth */
+#define BI_MAC_VROW		0x8003	/* Mac video rowbytes */
+#define BI_MAC_VDIM		0x8004	/* Mac video dimensions */
+#define BI_MAC_VLOGICAL		0x8005	/* Mac video logical base */
+#define BI_MAC_SCCBASE		0x8006	/* Mac SCC base address */
+#define BI_MAC_BTIME		0x8007	/* Mac boot time */
+#define BI_MAC_GMTBIAS		0x8008	/* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE		0x8009	/* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID		0x800a	/* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE		0x800b	/* Mac system ROM base address */
+
+    /*
+     *  Macintosh hardware profile data - unused, see macintosh.h for
+     *  resonable type values
+     */
+
+#define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE		0x8011	/* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE		0x8012	/* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE		0x8013	/* Mac ADB interface type */
+#define BI_MAC_ASCBASE		0x8014	/* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380		0x8015	/* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA		0x8016	/* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396		0x8017	/* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE		0x8018	/* Mac IDE interface type */
+#define BI_MAC_IDEBASE		0x8019	/* Mac IDE interface base address */
+#define BI_MAC_NUBUS		0x801a	/* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK		0x801b	/* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
+#define BI_MAC_PMU		0x801f	/* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
+
+    /*
+     * Mac: compatibility with old booter data format (temporarily)
+     * Fields unused with the new bootinfo can be deleted now; instead of
+     * adding new fields the struct might be splitted into a hardware address
+     * part and a hardware type part
+     */
+
+#ifndef __ASSEMBLY__
+
+struct mac_booter_data
+{
+	unsigned long videoaddr;
+	unsigned long videorow;
+	unsigned long videodepth;
+	unsigned long dimensions;
+	unsigned long args;
+	unsigned long boottime;
+	unsigned long gmtbias;
+	unsigned long bootver;
+	unsigned long videological;
+	unsigned long sccbase;
+	unsigned long id;
+	unsigned long memsize;
+	unsigned long serialmf;
+	unsigned long serialhsk;
+	unsigned long serialgpi;
+	unsigned long printmf;
+	unsigned long printhsk;
+	unsigned long printgpi;
+	unsigned long cpuid;
+	unsigned long rombase;
+	unsigned long adbdelay;
+	unsigned long timedbra;
+};
+
+extern struct mac_booter_data
+	mac_bi_data;
+
+#endif
+
+    /*
+     *  Apollo-specific tags
+     */
+
+#define BI_APOLLO_MODEL         0x8000  /* model (u_long) */
+
+    /*
+     *  HP300-specific tags
+     */
+
+#define BI_HP300_MODEL		0x8000	/* model (u_long) */
+#define BI_HP300_UART_SCODE	0x8001	/* UART select code (u_long) */
+#define BI_HP300_UART_ADDR	0x8002	/* phys. addr of UART (u_long) */
+
+    /*
+     * Stuff for bootinfo interface versioning
+     *
+     * At the start of kernel code, a 'struct bootversion' is located.
+     * bootstrap checks for a matching version of the interface before booting
+     * a kernel, to avoid user confusion if kernel and bootstrap don't work
+     * together :-)
+     *
+     * If incompatible changes are made to the bootinfo interface, the major
+     * number below should be stepped (and the minor reset to 0) for the
+     * appropriate machine. If a change is backward-compatible, the minor
+     * should be stepped. "Backwards-compatible" means that booting will work,
+     * but certain features may not.
+     */
+
+#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
+#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
+#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v)		((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+    unsigned short branch;
+    unsigned long magic;
+    struct {
+	unsigned long machtype;
+	unsigned long version;
+    } machversions[0];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
+#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
+#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
+#define MVME147_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
+#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
+#define HP300_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
+
+#ifdef BOOTINFO_COMPAT_1_0
+
+    /*
+     *  Backwards compatibility with bootinfo interface version 1.0
+     */
+
+#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
+
+#include <linux/zorro.h>
+
+#define COMPAT_NUM_AUTO    16
+
+struct compat_bi_Amiga {
+    int model;
+    int num_autocon;
+    struct ConfigDev autocon[COMPAT_NUM_AUTO];
+    unsigned long chip_size;
+    unsigned char vblank;
+    unsigned char psfreq;
+    unsigned long eclock;
+    unsigned long chipset;
+    unsigned long hw_present;
+};
+
+struct compat_bi_Atari {
+    unsigned long hw_present;
+    unsigned long mch_cookie;
+};
+
+#ifndef __ASSEMBLY__
+
+struct compat_bi_Macintosh
+{
+	unsigned long videoaddr;
+	unsigned long videorow;
+	unsigned long videodepth;
+	unsigned long dimensions;
+	unsigned long args;
+	unsigned long boottime;
+	unsigned long gmtbias;
+	unsigned long bootver;
+	unsigned long videological;
+	unsigned long sccbase;
+	unsigned long id;
+	unsigned long memsize;
+	unsigned long serialmf;
+	unsigned long serialhsk;
+	unsigned long serialgpi;
+	unsigned long printmf;
+	unsigned long printhsk;
+	unsigned long printgpi;
+	unsigned long cpuid;
+	unsigned long rombase;
+	unsigned long adbdelay;
+	unsigned long timedbra;
+};
+
 #endif
+
+struct compat_mem_info {
+    unsigned long addr;
+    unsigned long size;
+};
+
+#define COMPAT_NUM_MEMINFO  4
+
+#define COMPAT_CPUB_68020 0
+#define COMPAT_CPUB_68030 1
+#define COMPAT_CPUB_68040 2
+#define COMPAT_CPUB_68060 3
+#define COMPAT_FPUB_68881 5
+#define COMPAT_FPUB_68882 6
+#define COMPAT_FPUB_68040 7
+#define COMPAT_FPUB_68060 8
+
+#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
+#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
+#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
+#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
+#define COMPAT_CPU_MASK     (31)
+#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
+#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
+#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
+#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
+#define COMPAT_FPU_MASK     (0xfe0)
+
+#define COMPAT_CL_SIZE      (256)
+
+struct compat_bootinfo {
+    unsigned long machtype;
+    unsigned long cputype;
+    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
+    int num_memory;
+    unsigned long ramdisk_size;
+    unsigned long ramdisk_addr;
+    char command_line[COMPAT_CL_SIZE];
+    union {
+	struct compat_bi_Amiga     bi_ami;
+	struct compat_bi_Atari     bi_ata;
+	struct compat_bi_Macintosh bi_mac;
+    } bi_un;
+};
+
+#define bi_amiga	bi_un.bi_ami
+#define bi_atari	bi_un.bi_ata
+#define bi_mac		bi_un.bi_mac
+
+#endif /* BOOTINFO_COMPAT_1_0 */
+
+
+#endif /* _M68K_BOOTINFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,378 +0,0 @@
-/*
-** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
-**
-** Copyright 1992 by Greg Harp
-**
-** 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.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-**   Added bi_atari part of the machine dependent union bi_un; for now it
-**   contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-**   Renamed to setup.h; added some useful macros to allow gcc some
-**   optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-**   Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-**   Backwards compatibility with bootinfo interface version 1.0
-*/
-
-#ifndef _M68K_BOOTINFO_H
-#define _M68K_BOOTINFO_H
-
-
-    /*
-     *  Bootinfo definitions
-     *
-     *  This is an easily parsable and extendable structure containing all
-     *  information to be passed from the bootstrap to the kernel.
-     *
-     *  This way I hope to keep all future changes back/forewards compatible.
-     *  Thus, keep your fingers crossed...
-     *
-     *  This structure is copied right after the kernel bss by the bootstrap
-     *  routine.
-     */
-
-#ifndef __ASSEMBLY__
-
-struct bi_record {
-    unsigned short tag;			/* tag ID */
-    unsigned short size;		/* size of record (in bytes) */
-    unsigned long data[0];		/* data */
-};
-
-#endif /* __ASSEMBLY__ */
-
-
-    /*
-     *  Tag Definitions
-     *
-     *  Machine independent tags start counting from 0x0000
-     *  Machine dependent tags start counting from 0x8000
-     */
-
-#define BI_LAST			0x0000	/* last record (sentinel) */
-#define BI_MACHTYPE		0x0001	/* machine type (u_long) */
-#define BI_CPUTYPE		0x0002	/* cpu type (u_long) */
-#define BI_FPUTYPE		0x0003	/* fpu type (u_long) */
-#define BI_MMUTYPE		0x0004	/* mmu type (u_long) */
-#define BI_MEMCHUNK		0x0005	/* memory chunk address and size */
-					/* (struct mem_info) */
-#define BI_RAMDISK		0x0006	/* ramdisk address and size */
-					/* (struct mem_info) */
-#define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
-					/* (string) */
-
-    /*
-     *  Amiga-specific tags
-     */
-
-#define BI_AMIGA_MODEL		0x8000	/* model (u_long) */
-#define BI_AMIGA_AUTOCON	0x8001	/* AutoConfig device */
-					/* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE	0x8002	/* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK		0x8003	/* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ		0x8004	/* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
-#define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
-
-    /*
-     *  Atari-specific tags
-     */
-
-#define BI_ATARI_MCH_COOKIE	0x8000	/* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE	0x8001	/* special machine type (u_long) */
-					/* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST		0
-#define ATARI_MCH_STE		1
-#define ATARI_MCH_TT		2
-#define ATARI_MCH_FALCON	3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL	0	/* no special machine type */
-#define ATARI_MACH_MEDUSA	1	/* Medusa 040 */
-#define ATARI_MACH_HADES	2	/* Hades 040 or 060 */
-#define ATARI_MACH_AB40		3	/* Afterburner040 on Falcon */
-
-    /*
-     *  VME-specific tags
-     */
-
-#define BI_VME_TYPE		0x8000	/* VME sub-architecture (u_long) */
-#define BI_VME_BRDINFO		0x8001	/* VME board information (struct) */
-
-/* BI_VME_TYPE codes */
-#define	VME_TYPE_TP34V		0x0034	/* Tadpole TP34V */
-#define VME_TYPE_MVME147	0x0147	/* Motorola MVME147 */
-#define VME_TYPE_MVME162	0x0162	/* Motorola MVME162 */
-#define VME_TYPE_MVME166	0x0166	/* Motorola MVME166 */
-#define VME_TYPE_MVME167	0x0167	/* Motorola MVME167 */
-#define VME_TYPE_MVME172	0x0172	/* Motorola MVME172 */
-#define VME_TYPE_MVME177	0x0177	/* Motorola MVME177 */
-#define VME_TYPE_BVME4000	0x4000	/* BVM Ltd. BVME4000 */
-#define VME_TYPE_BVME6000	0x6000	/* BVM Ltd. BVME6000 */
-
-/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
- * Motorola VME boards.  Contains board number, Bug version, board
- * configuration options, etc.  See include/asm/mvme16xhw.h for details.
- */
-
-
-    /*
-     *  Macintosh-specific tags (all u_long)
-     */
-
-#define BI_MAC_MODEL		0x8000	/* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR		0x8001	/* Mac video base address */
-#define BI_MAC_VDEPTH		0x8002	/* Mac video depth */
-#define BI_MAC_VROW		0x8003	/* Mac video rowbytes */
-#define BI_MAC_VDIM		0x8004	/* Mac video dimensions */
-#define BI_MAC_VLOGICAL		0x8005	/* Mac video logical base */
-#define BI_MAC_SCCBASE		0x8006	/* Mac SCC base address */
-#define BI_MAC_BTIME		0x8007	/* Mac boot time */
-#define BI_MAC_GMTBIAS		0x8008	/* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE		0x8009	/* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID		0x800a	/* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE		0x800b	/* Mac system ROM base address */
-
-    /*
-     *  Macintosh hardware profile data - unused, see macintosh.h for
-     *  resonable type values
-     */
-
-#define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE		0x8011	/* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE		0x8012	/* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE		0x8013	/* Mac ADB interface type */
-#define BI_MAC_ASCBASE		0x8014	/* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380		0x8015	/* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA		0x8016	/* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396		0x8017	/* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE		0x8018	/* Mac IDE interface type */
-#define BI_MAC_IDEBASE		0x8019	/* Mac IDE interface base address */
-#define BI_MAC_NUBUS		0x801a	/* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK		0x801b	/* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
-#define BI_MAC_PMU		0x801f	/* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
-
-    /*
-     * Mac: compatibility with old booter data format (temporarily)
-     * Fields unused with the new bootinfo can be deleted now; instead of
-     * adding new fields the struct might be splitted into a hardware address
-     * part and a hardware type part
-     */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-};
-
-extern struct mac_booter_data
-	mac_bi_data;
-
-#endif
-
-    /*
-     *  Apollo-specific tags
-     */
-
-#define BI_APOLLO_MODEL         0x8000  /* model (u_long) */
-
-    /*
-     *  HP300-specific tags
-     */
-
-#define BI_HP300_MODEL		0x8000	/* model (u_long) */
-#define BI_HP300_UART_SCODE	0x8001	/* UART select code (u_long) */
-#define BI_HP300_UART_ADDR	0x8002	/* phys. addr of UART (u_long) */
-
-    /*
-     * Stuff for bootinfo interface versioning
-     *
-     * At the start of kernel code, a 'struct bootversion' is located.
-     * bootstrap checks for a matching version of the interface before booting
-     * a kernel, to avoid user confusion if kernel and bootstrap don't work
-     * together :-)
-     *
-     * If incompatible changes are made to the bootinfo interface, the major
-     * number below should be stepped (and the minor reset to 0) for the
-     * appropriate machine. If a change is backward-compatible, the minor
-     * should be stepped. "Backwards-compatible" means that booting will work,
-     * but certain features may not.
-     */
-
-#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v)		((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
-    unsigned short branch;
-    unsigned long magic;
-    struct {
-	unsigned long machtype;
-	unsigned long version;
-    } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define MVME147_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define HP300_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-
-#ifdef BOOTINFO_COMPAT_1_0
-
-    /*
-     *  Backwards compatibility with bootinfo interface version 1.0
-     */
-
-#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO    16
-
-struct compat_bi_Amiga {
-    int model;
-    int num_autocon;
-    struct ConfigDev autocon[COMPAT_NUM_AUTO];
-    unsigned long chip_size;
-    unsigned char vblank;
-    unsigned char psfreq;
-    unsigned long eclock;
-    unsigned long chipset;
-    unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
-    unsigned long hw_present;
-    unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-struct compat_bi_Macintosh
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-};
-
-#endif
-
-struct compat_mem_info {
-    unsigned long addr;
-    unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO  4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK     (31)
-#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK     (0xfe0)
-
-#define COMPAT_CL_SIZE      (256)
-
-struct compat_bootinfo {
-    unsigned long machtype;
-    unsigned long cputype;
-    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
-    int num_memory;
-    unsigned long ramdisk_size;
-    unsigned long ramdisk_addr;
-    char command_line[COMPAT_CL_SIZE];
-    union {
-	struct compat_bi_Amiga     bi_ami;
-	struct compat_bi_Atari     bi_ata;
-	struct compat_bi_Macintosh bi_mac;
-    } bi_un;
-};
-
-#define bi_amiga	bi_un.bi_ami
-#define bi_atari	bi_un.bi_ata
-#define bi_mac		bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
-
-
-#endif /* _M68K_BOOTINFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bootinfo_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bootinfo_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-
-/* Nothing for m68knommu */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "bug_no.h"
+#ifndef _M68K_BUG_H
+#define _M68K_BUG_H
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_SUN3
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	__builtin_trap(); \
+} while (0)
 #else
-#include "bug_mm.h"
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+	__builtin_trap(); \
+} while (0)
+#endif
+
+#define HAVE_ARCH_BUG
+#endif
+#endif /* CONFIG_MMU */
+
+#include <asm-generic/bug.h>
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-#ifndef _M68K_BUG_H
-#define _M68K_BUG_H
-
-
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#ifndef CONFIG_SUN3
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	__builtin_trap(); \
-} while (0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	panic("BUG!"); \
-} while (0)
-#endif
-#else
-#define BUG() do { \
-	__builtin_trap(); \
-} while (0)
-#endif
-
-#define HAVE_ARCH_BUG
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bug_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bug_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,4 +0,0 @@
-#ifndef _M68KNOMMU_BUG_H
-#define _M68KNOMMU_BUG_H
-#include <asm-generic/bug.h>
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,20 @@
-#ifdef __uClinux__
-#include "bugs_no.h"
+/*
+ *  include/asm-m68k/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+#ifdef CONFIG_MMU
+extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
 #else
-#include "bugs_mm.h"
+static void check_bugs(void)
+{
+}
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-/*
- *  include/asm-m68k/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/bugs_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/bugs_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/*
- *  include/asm-m68k/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-static void check_bugs(void)
-{
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "cache_no.h"
-#else
-#include "cache_mm.h"
+/*
+ * include/asm-m68k/cache.h
+ */
+#ifndef __ARCH_M68K_CACHE_H
+#define __ARCH_M68K_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_SHIFT  4
+#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-/*
- * include/asm-m68k/cache.h
- */
-#ifndef __ARCH_M68K_CACHE_H
-#define __ARCH_M68K_CACHE_H
-
-/* bytes per L1 cache line */
-#define        L1_CACHE_SHIFT  4
-#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/cache_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/cache_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef __ARCH_M68KNOMMU_CACHE_H
-#define __ARCH_M68KNOMMU_CACHE_H
-
-/* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  16	/* this need to be at least 1 */
-
-/* m68k-elf-gcc  2.95.2 doesn't like these */
-
-#define __cacheline_aligned
-#define ____cacheline_aligned
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,28 @@
-#ifdef __uClinux__
-#include "current_no.h"
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+#ifdef CONFIG_MMU
+
+register struct task_struct *current __asm__("%a2");
+
 #else
-#include "current_mm.h"
-#endif
+
+/*
+ *	Rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+	return(current_thread_info()->task);
+}
+
+#define	current	get_current()
+
+#endif /* CONFNIG_MMU */
+
+#endif /* !(_M68K_CURRENT_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef _M68K_CURRENT_H
-#define _M68K_CURRENT_H
-
-register struct task_struct *current __asm__("%a2");
-
-#endif /* !(_M68K_CURRENT_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/current_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/current_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-#ifndef _M68KNOMMU_CURRENT_H
-#define _M68KNOMMU_CURRENT_H
-/*
- *	current.h
- *	(C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
- *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
- *	rather than dedicate a register (as the m68k source does), we
- *	just keep a global,  we should probably just change it all to be
- *	current and lose _current_task.
- */
-
-#include <linux/thread_info.h>
-
-struct task_struct;
-
-static inline struct task_struct *get_current(void)
-{
-	return(current_thread_info()->task);
-}
-
-#define	current	get_current()
-
-#endif /* _M68KNOMMU_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,34 @@
-#ifdef __uClinux__
-#include "div64_no.h"
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+#ifdef CONFIG_MMU
+
+#include <linux/types.h>
+
+/* n = n / base; return rem; */
+
+#define do_div(n, base) ({					\
+	union {							\
+		unsigned long n32[2];				\
+		unsigned long long n64;				\
+	} __n;							\
+	unsigned long __rem, __upper;				\
+								\
+	__n.n64 = (n);						\
+	if ((__upper = __n.n32[0])) {				\
+		asm ("divul.l %2,%1:%0"				\
+			: "=d" (__n.n32[0]), "=d" (__upper)	\
+			: "d" (base), "0" (__n.n32[0]));	\
+	}							\
+	asm ("divu.l %2,%1:%0"					\
+		: "=d" (__n.n32[1]), "=d" (__rem)		\
+		: "d" (base), "1" (__upper), "0" (__n.n32[1]));	\
+	(n) = __n.n64;						\
+	__rem;							\
+})
+
 #else
-#include "div64_mm.h"
-#endif
+#include <asm-generic/div64.h>
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_DIV64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-#ifndef _M68K_DIV64_H
-#define _M68K_DIV64_H
-
-#include <linux/types.h>
-
-/* n = n / base; return rem; */
-
-#define do_div(n, base) ({					\
-	union {							\
-		unsigned long n32[2];				\
-		unsigned long long n64;				\
-	} __n;							\
-	unsigned long __rem, __upper;				\
-								\
-	__n.n64 = (n);						\
-	if ((__upper = __n.n32[0])) {				\
-		asm ("divul.l %2,%1:%0"				\
-			: "=d" (__n.n32[0]), "=d" (__upper)	\
-			: "d" (base), "0" (__n.n32[0]));	\
-	}							\
-	asm ("divu.l %2,%1:%0"					\
-		: "=d" (__n.n32[1]), "=d" (__rem)		\
-		: "d" (base), "1" (__upper), "0" (__n.n32[1]));	\
-	(n) = __n.n64;						\
-	__rem;							\
-})
-
-#endif /* _M68K_DIV64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/div64_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/div64_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include <asm-generic/div64.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,112 @@
-#ifdef __uClinux__
-#include "dma-mapping_no.h"
+#ifndef _M68K_DMA_MAPPING_H
+#define _M68K_DMA_MAPPING_H
+
+#include <asm/cache.h>
+
+struct scatterlist;
+
+#ifndef CONFIG_MMU_SUN3
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+	return 0;
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+	return 1 << L1_CACHE_SHIFT;
+}
+
+static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+extern void *dma_alloc_coherent(struct device *, size_t,
+				dma_addr_t *, gfp_t);
+extern void dma_free_coherent(struct device *, size_t,
+			      void *, dma_addr_t);
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+					  dma_addr_t *handle, gfp_t flag)
+{
+	return dma_alloc_coherent(dev, size, handle, flag);
+}
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+					void *addr, dma_addr_t handle)
+{
+	dma_free_coherent(dev, size, addr, handle);
+}
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+				  enum dma_data_direction dir)
+{
+	/* we use coherent allocation, so not much to do here. */
+}
+
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+				 enum dma_data_direction);
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+				    size_t size, enum dma_data_direction dir)
+{
+}
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+			       unsigned long, size_t size,
+			       enum dma_data_direction);
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
+				  size_t size, enum dma_data_direction dir)
+{
+}
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+		      enum dma_data_direction);
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+				int nhwentries, enum dma_data_direction dir)
+{
+}
+
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
+				       enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+				   enum dma_data_direction);
+
+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)
+{
+	/* just sync everything for now */
+	dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
+}
+
+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_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+				       int nents, enum dma_data_direction dir)
+{
+}
+
+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)
+{
+	/* just sync everything for now */
+	dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
+{
+	return 0;
+}
+
 #else
-#include "dma-mapping_mm.h"
+#include <asm-generic/dma-mapping-broken.h>
 #endif
+
+#endif  /* _M68K_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,112 +0,0 @@
-#ifndef _M68K_DMA_MAPPING_H
-#define _M68K_DMA_MAPPING_H
-
-#include <asm/cache.h>
-
-struct scatterlist;
-
-#ifndef CONFIG_MMU_SUN3
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-	return 0;
-}
-
-static inline int dma_get_cache_alignment(void)
-{
-	return 1 << L1_CACHE_SHIFT;
-}
-
-static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
-				dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
-			      void *, dma_addr_t);
-
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
-					  dma_addr_t *handle, gfp_t flag)
-{
-	return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
-					void *addr, dma_addr_t handle)
-{
-	dma_free_coherent(dev, size, addr, handle);
-}
-static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-				  enum dma_data_direction dir)
-{
-	/* we use coherent allocation, so not much to do here. */
-}
-
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
-				 enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
-				    size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
-			       unsigned long, size_t size,
-			       enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
-				  size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
-		      enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
-				       enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
-				   enum dma_data_direction);
-
-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)
-{
-	/* just sync everything for now */
-	dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-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_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-				       int nents, enum dma_data_direction dir)
-{
-}
-
-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)
-{
-	/* just sync everything for now */
-	dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
-	return 0;
-}
-
-#else
-#include <asm-generic/dma-mapping-broken.h>
-#endif
-
-#endif  /* _M68K_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/dma-mapping_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/dma-mapping_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef _M68KNOMMU_DMA_MAPPING_H
-#define _M68KNOMMU_DMA_MAPPING_H
-
-#include <asm-generic/dma-mapping-broken.h>
-
-#endif  /* _M68KNOMMU_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,119 @@
-#ifdef __uClinux__
-#include "elf_no.h"
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+   passed in %a1.  Although my copy of the ABI has no such statement, it
+   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
-#include "elf_mm.h"
+#define ELF_EXEC_PAGESIZE	8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE         0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE         0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	/* Bleech. */							\
+	pr_reg[0] = regs->d1;						\
+	pr_reg[1] = regs->d2;						\
+	pr_reg[2] = regs->d3;						\
+	pr_reg[3] = regs->d4;						\
+	pr_reg[4] = regs->d5;						\
+	pr_reg[7] = regs->a0;						\
+	pr_reg[8] = regs->a1;						\
+	pr_reg[9] = regs->a2;						\
+	pr_reg[14] = regs->d0;						\
+	pr_reg[15] = rdusp();						\
+	pr_reg[16] = regs->orig_d0;					\
+	pr_reg[17] = regs->sr;						\
+	pr_reg[18] = regs->pc;						\
+	pr_reg[19] = (regs->format << 12) | regs->vector;		\
+	{								\
+	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
+	  pr_reg[5] = sw->d6;						\
+	  pr_reg[6] = sw->d7;						\
+	  pr_reg[10] = sw->a3;						\
+	  pr_reg[11] = sw->a4;						\
+	  pr_reg[12] = sw->a5;						\
+	  pr_reg[13] = sw->a6;						\
+	}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,119 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE	0
-#define R_68K_32	1
-#define R_68K_16	2
-#define R_68K_8		3
-#define R_68K_PC32	4
-#define R_68K_PC16	5
-#define R_68K_PC8	6
-#define R_68K_GOT32	7
-#define R_68K_GOT16	8
-#define R_68K_GOT8	9
-#define R_68K_GOT32O	10
-#define R_68K_GOT16O	11
-#define R_68K_GOT8O	12
-#define R_68K_PLT32	13
-#define R_68K_PLT16	14
-#define R_68K_PLT8	15
-#define R_68K_PLT32O	16
-#define R_68K_PLT16O	17
-#define R_68K_PLT8O	18
-#define R_68K_COPY	19
-#define R_68K_GLOB_DAT	20
-#define R_68K_JMP_SLOT	21
-#define R_68K_RELATIVE	22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2MSB
-#define ELF_ARCH	EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
-   passed in %a1.  Although my copy of the ABI has no such statement, it
-   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
-#define ELF_EXEC_PAGESIZE	8192
-#endif
-
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#ifndef CONFIG_SUN3
-#define ELF_ET_DYN_BASE         0xD0000000UL
-#else
-#define ELF_ET_DYN_BASE         0x0D800000UL
-#endif
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
-	/* Bleech. */							\
-	pr_reg[0] = regs->d1;						\
-	pr_reg[1] = regs->d2;						\
-	pr_reg[2] = regs->d3;						\
-	pr_reg[3] = regs->d4;						\
-	pr_reg[4] = regs->d5;						\
-	pr_reg[7] = regs->a0;						\
-	pr_reg[8] = regs->a1;						\
-	pr_reg[9] = regs->a2;						\
-	pr_reg[14] = regs->d0;						\
-	pr_reg[15] = rdusp();						\
-	pr_reg[16] = regs->orig_d0;					\
-	pr_reg[17] = regs->sr;						\
-	pr_reg[18] = regs->pc;						\
-	pr_reg[19] = (regs->format << 12) | regs->vector;		\
-	{								\
-	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
-	  pr_reg[5] = sw->d6;						\
-	  pr_reg[6] = sw->d7;						\
-	  pr_reg[10] = sw->a3;						\
-	  pr_reg[11] = sw->a4;						\
-	  pr_reg[12] = sw->a5;						\
-	  pr_reg[13] = sw->a6;						\
-	}
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  */
-
-#define ELF_HWCAP	(0)
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.  */
-
-#define ELF_PLATFORM  (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/elf_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/elf_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,110 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE  0
-#define R_68K_32    1
-#define R_68K_16    2
-#define R_68K_8     3
-#define R_68K_PC32  4
-#define R_68K_PC16  5
-#define R_68K_PC8   6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8  9
-#define R_68K_GOT32O    10
-#define R_68K_GOT16O    11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8  15
-#define R_68K_PLT32O    16
-#define R_68K_PLT16O    17
-#define R_68K_PLT8O 18
-#define R_68K_COPY  19
-#define R_68K_GLOB_DAT  20
-#define R_68K_JMP_SLOT  21
-#define R_68K_RELATIVE  22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2MSB
-#define ELF_ARCH	EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
-   passed in %a1.  Although my copy of the ABI has no such statement, it
-   is actually used on ASV.  */
-#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 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
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE         0xD0000000UL
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
-	/* Bleech. */							\
-	pr_reg[0] = regs->d1;						\
-	pr_reg[1] = regs->d2;						\
-	pr_reg[2] = regs->d3;						\
-	pr_reg[3] = regs->d4;						\
-	pr_reg[4] = regs->d5;						\
-	pr_reg[7] = regs->a0;						\
-	pr_reg[8] = regs->a1;						\
-	pr_reg[14] = regs->d0;						\
-	pr_reg[15] = rdusp();						\
-	pr_reg[16] = 0 /* regs->orig_d0 */;				\
-	pr_reg[17] = regs->sr;						\
-	pr_reg[18] = regs->pc;						\
-	/* pr_reg[19] = (regs->format << 12) | regs->vector; */		\
-	{								\
-	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
-	  pr_reg[5] = sw->d6;						\
-	  pr_reg[6] = sw->d7;						\
-	  pr_reg[10] = sw->a3;						\
-	  pr_reg[11] = sw->a4;						\
-	  pr_reg[12] = sw->a5;						\
-	  pr_reg[13] = sw->a6;						\
-	}
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  */
-
-#define ELF_HWCAP	(0)
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.  */
-
-#define ELF_PLATFORM  (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,38 @@
-#ifdef __uClinux__
-#include "fb_no.h"
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_SUN3
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
+}
 #else
-#include "fb_mm.h"
-#endif
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	if (CPU_IS_020_OR_030)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
+	if (CPU_IS_040_OR_060) {
+		pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
+		/* Use no-cache mode, serialized */
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
+	}
+}
+#endif /* CONFIG_SUN3 */
+#else
+#define fb_pgprotect(...) do {} while (0)
+#endif /* CONFIG_MMU */
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#ifdef CONFIG_SUN3
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
-				unsigned long off)
-{
-	pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
-}
-#else
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
-				unsigned long off)
-{
-	if (CPU_IS_020_OR_030)
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
-	if (CPU_IS_040_OR_060) {
-		pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
-		/* Use no-cache mode, serialized */
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
-	}
-}
-#endif /* CONFIG_SUN3 */
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
-	return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fb_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fb_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-#include <linux/fb.h>
-
-#define fb_pgprotect(...) do {} while (0)
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
-	return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/flat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
 #ifndef __M68KNOMMU_FLAT_H__
 #define __M68KNOMMU_FLAT_H__
 
-#define	flat_stack_align(sp)			/* nothing needed */
 #define	flat_argvp_envp_on_stack()		1
 #define	flat_old_ram_flag(flags)		(flags)
 #define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "fpu_no.h"
+#ifndef __M68K_FPU_H
+#define __M68K_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216)
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96)
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28)
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12)
 #else
-#include "fpu_mm.h"
+#define FPSTATESIZE (0)
 #endif
+
+#endif /* __M68K_FPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-#ifndef __M68K_FPU_H
-#define __M68K_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216)
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96)
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28)
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12)
-#else
-#define FPSTATESIZE (0)
-#endif
-
-#endif /* __M68K_FPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/fpu_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/fpu_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-#ifndef __M68KNOMMU_FPU_H
-#define __M68KNOMMU_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216/sizeof(unsigned char))
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96/sizeof(unsigned char))
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28/sizeof(unsigned char))
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12/sizeof(unsigned char))
-#else
-/* Assume no FP unit present then... */
-#define FPSTATESIZE (2) /* dummy size */
-#endif
-
-#endif /* __M68K_FPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
-#ifdef __uClinux__
-#include "hw_irq_no.h"
-#else
-#include "hw_irq_mm.h"
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_HW_IRQ_H
-#define __ASM_M68K_HW_IRQ_H
-
-/* Dummy include. */
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/hw_irq_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/hw_irq_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,4 +0,0 @@
-#ifndef __M68KNOMMU_HW_IRQ_H__
-#define __M68KNOMMU_HW_IRQ_H__
-
-#endif /* __M68KNOMMU_HW_IRQ_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ide.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ide.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ide.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ide.h	2009-06-09 23:05:27.000000000 -0400
@@ -30,101 +30,28 @@
 #define _M68K_IDE_H
 
 #ifdef __KERNEL__
-
-
 #include <asm/setup.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#ifdef CONFIG_ATARI
-#include <linux/interrupt.h>
-#include <asm/atari_stdma.h>
-#endif
-
-#ifdef CONFIG_MAC
-#include <asm/macints.h>
-#endif
-
 /*
  * Get rid of defs from io.h - ide has its private and conflicting versions
  * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
  * always use the `raw' MMIO versions
  */
-#undef inb
-#undef inw
-#undef insw
-#undef inl
-#undef insl
-#undef outb
-#undef outw
-#undef outsw
-#undef outl
-#undef outsl
 #undef readb
 #undef readw
-#undef readl
 #undef writeb
 #undef writew
-#undef writel
 
-#define inb				in_8
-#define inw				in_be16
-#define insw(port, addr, n)		raw_insw((u16 *)port, addr, n)
-#define inl				in_be32
-#define insl(port, addr, n)		raw_insl((u32 *)port, addr, n)
-#define outb(val, port)			out_8(port, val)
-#define outw(val, port)			out_be16(port, val)
-#define outsw(port, addr, n)		raw_outsw((u16 *)port, addr, n)
-#define outl(val, port)			out_be32(port, val)
-#define outsl(port, addr, n)		raw_outsl((u32 *)port, addr, n)
 #define readb				in_8
 #define readw				in_be16
 #define __ide_mm_insw(port, addr, n)	raw_insw((u16 *)port, addr, n)
-#define readl				in_be32
 #define __ide_mm_insl(port, addr, n)	raw_insl((u32 *)port, addr, n)
 #define writeb(val, port)		out_8(port, val)
 #define writew(val, port)		out_be16(port, val)
 #define __ide_mm_outsw(port, addr, n)	raw_outsw((u16 *)port, addr, n)
-#define writel(val, port)		out_be32(port, val)
 #define __ide_mm_outsl(port, addr, n)	raw_outsl((u32 *)port, addr, n)
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-#define insw_swapw(port, addr, n)	raw_insw_swapw((u16 *)port, addr, n)
-#define outsw_swapw(port, addr, n)	raw_outsw_swapw((u16 *)port, addr, n)
-#endif
-
-#ifdef CONFIG_BLK_DEV_FALCON_IDE
-#define IDE_ARCH_LOCK
-
-extern int falconide_intr_lock;
-
-static __inline__ void ide_release_lock (void)
-{
-	if (MACH_IS_ATARI) {
-		if (falconide_intr_lock == 0) {
-			printk("ide_release_lock: bug\n");
-			return;
-		}
-		falconide_intr_lock = 0;
-		stdma_release();
-	}
-}
-
-static __inline__ void
-ide_get_lock(irq_handler_t handler, void *data)
-{
-	if (MACH_IS_ATARI) {
-		if (falconide_intr_lock == 0) {
-			if (in_interrupt() > 0)
-				panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
-			stdma_lock(handler, data);
-			falconide_intr_lock = 1;
-		}
-	}
-}
-#endif /* CONFIG_BLK_DEV_FALCON_IDE */
-
-#define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif)	((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
 
 #endif /* __KERNEL__ */
 #endif /* _M68K_IDE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/irq_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/irq_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/irq_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/irq_mm.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
 
 #include <linux/linkage.h>
 #include <linux/hardirq.h>
+#include <linux/irqreturn.h>
 #include <linux/spinlock_types.h>
 
 /*
@@ -80,7 +81,7 @@ struct pt_regs;
  * interrupt source (if it supports chaining).
  */
 typedef struct irq_node {
-	int		(*handler)(int, void *);
+	irqreturn_t	(*handler)(int, void *);
 	void		*dev_id;
 	struct irq_node *next;
 	unsigned long	flags;
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "kmap_types_no.h"
-#else
-#include "kmap_types_mm.h"
-#endif
+#ifndef __ASM_M68K_KMAP_TYPES_H
+#define __ASM_M68K_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif	/* __ASM_M68K_KMAP_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BIO_SRC_IRQ,
-	KM_BIO_DST_IRQ,
-	KM_PTE0,
-	KM_PTE1,
-	KM_IRQ0,
-	KM_IRQ1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#endif	/* __ASM_M68K_KMAP_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/kmap_types_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/kmap_types_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BIO_SRC_IRQ,
-	KM_BIO_DST_IRQ,
-	KM_PTE0,
-	KM_PTE1,
-	KM_IRQ0,
-	KM_IRQ1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/m532xsim.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/m532xsim.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/m532xsim.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/m532xsim.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 #define MCFINT_VECBASE      64
 #define MCFINT_UART0        26          /* Interrupt number for UART0 */
 #define MCFINT_UART1        27          /* Interrupt number for UART1 */
+#define MCFINT_UART2        28          /* Interrupt number for UART2 */
 
 #define MCF_WTM_WCR	MCF_REG16(0xFC098000)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/macintosh.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/macintosh.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/macintosh.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/macintosh.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,7 @@ struct mac_model
 	char scc_type;
 	char ether_type;
 	char nubus_type;
+	char floppy_type;
 };
 
 #define MAC_ADB_NONE		0
@@ -71,6 +72,12 @@ struct mac_model
 #define MAC_NO_NUBUS		0
 #define MAC_NUBUS		1
 
+#define MAC_FLOPPY_IWM		0
+#define MAC_FLOPPY_SWIM_ADDR1	1
+#define MAC_FLOPPY_SWIM_ADDR2	2
+#define MAC_FLOPPY_SWIM_IOP	3
+#define MAC_FLOPPY_AV		4
+
 /*
  *	Gestalt numbers
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,26 @@
-#ifdef __uClinux__
-#include "mc146818rtc_no.h"
-#else
-#include "mc146818rtc_mm.h"
-#endif
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#ifdef CONFIG_ATARI
+/* RTC in Atari machines */
+
+#include <asm/atarihw.h>
+
+#define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD	0
+
+#define CMOS_READ(addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_outb_p((val),RTC_PORT(1)); \
+})
+#endif /* CONFIG_ATARI */
+
+#endif /* _ASM_MC146818RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _ASM_MC146818RTC_H
-#define _ASM_MC146818RTC_H
-
-
-#ifdef CONFIG_ATARI
-/* RTC in Atari machines */
-
-#include <asm/atarihw.h>
-
-#define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
-#define RTC_ALWAYS_BCD	0
-
-#define CMOS_READ(addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_outb_p((val),RTC_PORT(1)); \
-})
-#endif /* CONFIG_ATARI */
-
-#endif /* _ASM_MC146818RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mc146818rtc_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mc146818rtc_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _M68KNOMMU_MC146818RTC_H
-#define _M68KNOMMU_MC146818RTC_H
-
-/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
-
-#endif /* _M68KNOMMU_MC146818RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mcfpci.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mcfpci.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mcfpci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mcfpci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,119 +0,0 @@
-/****************************************************************************/
-
-/*
- *	mcfpci.h -- PCI bridge on ColdFire eval boards.
- *
- *	(C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
- *	(C) Copyright 2000, Lineo Inc. (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef	mcfpci_h
-#define	mcfpci_h
-/****************************************************************************/
-
-
-#ifdef CONFIG_PCI
-
-/*
- *	Address regions in the PCI address space are not mapped into the
- *	normal memory space of the ColdFire. They must be accessed via
- *	handler routines. This is easy for I/O space (inb/outb/etc) but
- *	needs some code changes to support ordinary memory. Interrupts
- *	also need to be vectored through the PCI handler first, then it
- *	will call the actual driver sub-handlers.
- */
-
-/*
- *	Un-define all the standard I/O access routines.
- */
-#undef	inb
-#undef	inw
-#undef	inl
-#undef	inb_p
-#undef	inw_p
-#undef	insb
-#undef	insw
-#undef	insl
-#undef	outb
-#undef	outw
-#undef	outl
-#undef	outb_p
-#undef	outw_p
-#undef	outsb
-#undef	outsw
-#undef	outsl
-
-#undef	request_irq
-#undef	free_irq
-
-#undef	bus_to_virt
-#undef	virt_to_bus
-
-
-/*
- *	Re-direct all I/O memory accesses functions to PCI specific ones.
- */
-#define	inb	pci_inb
-#define	inw	pci_inw
-#define	inl	pci_inl
-#define	inb_p	pci_inb
-#define	inw_p	pci_inw
-#define	insb	pci_insb
-#define	insw	pci_insw
-#define	insl	pci_insl
-
-#define	outb	pci_outb
-#define	outw	pci_outw
-#define	outl	pci_outl
-#define	outb_p	pci_outb
-#define	outw_p	pci_outw
-#define	outsb	pci_outsb
-#define	outsw	pci_outsw
-#define	outsl	pci_outsl
-
-#define	request_irq	pci_request_irq
-#define	free_irq	pci_free_irq
-
-#define	virt_to_bus	pci_virt_to_bus
-#define	bus_to_virt	pci_bus_to_virt
-
-#define	CONFIG_COMEMPCI	1
-
-
-/*
- *	Prototypes of the real PCI functions (defined in bios32.c).
- */
-unsigned char	pci_inb(unsigned int addr);
-unsigned short	pci_inw(unsigned int addr);
-unsigned int	pci_inl(unsigned int addr);
-void		pci_insb(void *addr, void *buf, int len);
-void		pci_insw(void *addr, void *buf, int len);
-void		pci_insl(void *addr, void *buf, int len);
-
-void		pci_outb(unsigned char val, unsigned int addr);
-void		pci_outw(unsigned short val, unsigned int addr);
-void		pci_outl(unsigned int val, unsigned int addr);
-void		pci_outsb(void *addr, void *buf, int len);
-void		pci_outsw(void *addr, void *buf, int len);
-void		pci_outsl(void *addr, void *buf, int len);
-
-int		pci_request_irq(unsigned int irq,
-			void (*handler)(int, void *, struct pt_regs *),
-			unsigned long flags,
-			const char *device,
-			void *dev_id);
-void		pci_free_irq(unsigned int irq, void *dev_id);
-
-void		*pci_bmalloc(int size);
-void		pci_bmfree(void *bmp, int len);
-void		pci_copytoshmem(unsigned long bmp, void *src, int size);
-void		pci_copyfromshmem(void *dst, unsigned long bmp, int size);
-unsigned long	pci_virt_to_bus(volatile void *address);
-void		*pci_bus_to_virt(unsigned long address);
-void		pci_bmcpyto(void *dst, void *src, int len);
-void		pci_bmcpyfrom(void *dst, void *src, int len);
-
-#endif /* CONFIG_PCI */
-/****************************************************************************/
-#endif	/* mcfpci_h */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,175 @@
-#ifdef __uClinux__
-#include "mmu_context_no.h"
+#ifndef __M68K_MMU_CONTEXT_H
+#define __M68K_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline int init_new_context(struct task_struct *tsk,
+				   struct mm_struct *mm)
+{
+	mm->context = virt_to_phys(mm->pgd);
+	return 0;
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm_0230(struct mm_struct *mm)
+{
+	unsigned long crp[2] = {
+		0x80000000 | _PAGE_TABLE, mm->context
+	};
+	unsigned long tmp;
+
+	asm volatile (".chip 68030");
+
+	/* flush MC68030/MC68020 caches (they are virtually addressed) */
+	asm volatile (
+		"movec %%cacr,%0;"
+		"orw %1,%0; "
+		"movec %0,%%cacr"
+		: "=d" (tmp) : "di" (FLUSH_I_AND_D));
+
+	/* Switch the root pointer. For a 030-only kernel,
+	 * avoid flushing the whole ATC, we only need to
+	 * flush the user entries. The 68851 does this by
+	 * itself. Avoid a runtime check here.
+	 */
+	asm volatile (
+#ifdef CPU_M68030_ONLY
+		"pmovefd %0,%%crp; "
+		"pflush #0,#4"
 #else
-#include "mmu_context_mm.h"
+		"pmove %0,%%crp"
+#endif
+		: : "m" (crp[0]));
+
+	asm volatile (".chip 68k");
+}
+
+static inline void switch_mm_0460(struct mm_struct *mm)
+{
+	asm volatile (".chip 68040");
+
+	/* flush address translation cache (user entries) */
+	asm volatile ("pflushan");
+
+	/* switch the root pointer */
+	asm volatile ("movec %0,%%urp" : : "r" (mm->context));
+
+	if (CPU_IS_060) {
+		unsigned long tmp;
+
+		/* clear user entries in the branch cache */
+		asm volatile (
+			"movec %%cacr,%0; "
+		        "orl %1,%0; "
+		        "movec %0,%%cacr"
+			: "=d" (tmp): "di" (0x00200000));
+	}
+
+	asm volatile (".chip 68k");
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+	if (prev != next) {
+		if (CPU_IS_020_OR_030)
+			switch_mm_0230(next);
+		else
+			switch_mm_0460(next);
+	}
+}
+
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+	next_mm->context = virt_to_phys(next_mm->pgd);
+
+	if (CPU_IS_020_OR_030)
+		switch_mm_0230(next_mm);
+	else
+		switch_mm_0460(next_mm);
+}
+
+#else  /* CONFIG_SUN3 */
+#include <asm/sun3mmu.h>
+#include <linux/sched.h>
+
+extern unsigned long get_free_context(struct mm_struct *mm);
+extern void clear_context(unsigned long context);
+
+/* set the context for a new task to unmapped */
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = SUN3_INVALID_CONTEXT;
+	return 0;
+}
+
+/* find the context given to this process, and if it hasn't already
+   got one, go get one for it. */
+static inline void get_mmu_context(struct mm_struct *mm)
+{
+	if(mm->context == SUN3_INVALID_CONTEXT)
+		mm->context = get_free_context(mm);
+}
+
+/* flush context if allocated... */
+static inline void destroy_context(struct mm_struct *mm)
+{
+	if(mm->context != SUN3_INVALID_CONTEXT)
+		clear_context(mm->context);
+}
+
+static inline void activate_context(struct mm_struct *mm)
+{
+	get_mmu_context(mm);
+	sun3_put_context(mm->context);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+	activate_context(tsk->mm);
+}
+
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+	activate_context(next_mm);
+}
+
 #endif
+#else /* !CONFIG_MMU */
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	return 0;
+}
+
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+}
+
+#define destroy_context(mm)	do { } while (0)
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
+{
+}
+
+#endif /* CONFIG_MMU */
+#endif /* __M68K_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,154 +0,0 @@
-#ifndef __M68K_MMU_CONTEXT_H
-#define __M68K_MMU_CONTEXT_H
-
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-#ifndef CONFIG_SUN3
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-static inline int init_new_context(struct task_struct *tsk,
-				   struct mm_struct *mm)
-{
-	mm->context = virt_to_phys(mm->pgd);
-	return 0;
-}
-
-#define destroy_context(mm)		do { } while(0)
-
-static inline void switch_mm_0230(struct mm_struct *mm)
-{
-	unsigned long crp[2] = {
-		0x80000000 | _PAGE_TABLE, mm->context
-	};
-	unsigned long tmp;
-
-	asm volatile (".chip 68030");
-
-	/* flush MC68030/MC68020 caches (they are virtually addressed) */
-	asm volatile (
-		"movec %%cacr,%0;"
-		"orw %1,%0; "
-		"movec %0,%%cacr"
-		: "=d" (tmp) : "di" (FLUSH_I_AND_D));
-
-	/* Switch the root pointer. For a 030-only kernel,
-	 * avoid flushing the whole ATC, we only need to
-	 * flush the user entries. The 68851 does this by
-	 * itself. Avoid a runtime check here.
-	 */
-	asm volatile (
-#ifdef CPU_M68030_ONLY
-		"pmovefd %0,%%crp; "
-		"pflush #0,#4"
-#else
-		"pmove %0,%%crp"
-#endif
-		: : "m" (crp[0]));
-
-	asm volatile (".chip 68k");
-}
-
-static inline void switch_mm_0460(struct mm_struct *mm)
-{
-	asm volatile (".chip 68040");
-
-	/* flush address translation cache (user entries) */
-	asm volatile ("pflushan");
-
-	/* switch the root pointer */
-	asm volatile ("movec %0,%%urp" : : "r" (mm->context));
-
-	if (CPU_IS_060) {
-		unsigned long tmp;
-
-		/* clear user entries in the branch cache */
-		asm volatile (
-			"movec %%cacr,%0; "
-		        "orl %1,%0; "
-		        "movec %0,%%cacr"
-			: "=d" (tmp): "di" (0x00200000));
-	}
-
-	asm volatile (".chip 68k");
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-	if (prev != next) {
-		if (CPU_IS_020_OR_030)
-			switch_mm_0230(next);
-		else
-			switch_mm_0460(next);
-	}
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-	next_mm->context = virt_to_phys(next_mm->pgd);
-
-	if (CPU_IS_020_OR_030)
-		switch_mm_0230(next_mm);
-	else
-		switch_mm_0460(next_mm);
-}
-
-#else  /* CONFIG_SUN3 */
-#include <asm/sun3mmu.h>
-#include <linux/sched.h>
-
-extern unsigned long get_free_context(struct mm_struct *mm);
-extern void clear_context(unsigned long context);
-
-/* set the context for a new task to unmapped */
-static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-	mm->context = SUN3_INVALID_CONTEXT;
-	return 0;
-}
-
-/* find the context given to this process, and if it hasn't already
-   got one, go get one for it. */
-static inline void get_mmu_context(struct mm_struct *mm)
-{
-	if(mm->context == SUN3_INVALID_CONTEXT)
-		mm->context = get_free_context(mm);
-}
-
-/* flush context if allocated... */
-static inline void destroy_context(struct mm_struct *mm)
-{
-	if(mm->context != SUN3_INVALID_CONTEXT)
-		clear_context(mm->context);
-}
-
-static inline void activate_context(struct mm_struct *mm)
-{
-	get_mmu_context(mm);
-	sun3_put_context(mm->context);
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-	activate_context(tsk->mm);
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-	activate_context(next_mm);
-}
-
-#endif
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_context_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_context_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-#ifndef __M68KNOMMU_MMU_CONTEXT_H
-#define __M68KNOMMU_MMU_CONTEXT_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-	// mm->context = virt_to_phys(mm->pgd);
-	return(0);
-}
-
-#define destroy_context(mm)		do { } while(0)
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-}
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,13 @@
-#ifdef __uClinux__
-#include "mmu_no.h"
+#ifndef __MMU_H
+#define __MMU_H
+
+#ifdef CONFIG_MMU
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
 #else
-#include "mmu_mm.h"
+typedef struct {
+	unsigned long		end_brk;
+} mm_context_t;
+#endif
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/mmu_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/mmu_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-#ifndef __M68KNOMMU_MMU_H
-#define __M68KNOMMU_MMU_H
-
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
-
-typedef struct {
-	unsigned long		end_brk;
-} mm_context_t;
-
-#endif /* __M68KNOMMU_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,48 @@
-#ifdef __uClinux__
-#include "module_no.h"
+#ifndef _ASM_M68K_MODULE_H
+#define _ASM_M68K_MODULE_H
+
+#ifdef CONFIG_MMU
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+	m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};
+
+#define m68k_fixup(type, addr)			\
+	"	.section \".m68k_fixup\",\"aw\"\n"	\
+	"	.long " #type "," #addr "\n"	\
+	"	.previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+			 struct m68k_fixup_info *end);
+
 #else
-#include "module_mm.h"
-#endif
+
+struct mod_arch_specific {
+};
+
+#endif /* CONFIG_MMU */
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* _ASM_M68K_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-#ifndef _ASM_M68K_MODULE_H
-#define _ASM_M68K_MODULE_H
-
-struct mod_arch_specific {
-	struct m68k_fixup_info *fixup_start, *fixup_end;
-};
-
-#define MODULE_ARCH_INIT {				\
-	.fixup_start		= __start_fixup,	\
-	.fixup_end		= __stop_fixup,		\
-}
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-
-enum m68k_fixup_type {
-	m68k_fixup_memoffset,
-	m68k_fixup_vnode_shift,
-};
-
-struct m68k_fixup_info {
-	enum m68k_fixup_type type;
-	void *addr;
-};
-
-#define m68k_fixup(type, addr)			\
-	"	.section \".m68k_fixup\",\"aw\"\n"	\
-	"	.long " #type "," #addr "\n"	\
-	"	.previous\n"
-
-extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
-
-struct module;
-extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
-			 struct m68k_fixup_info *end);
-
-#endif /* _ASM_M68K_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/module_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/module_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#ifndef ASM_M68KNOMMU_MODULE_H
-#define ASM_M68KNOMMU_MODULE_H
-
-struct mod_arch_specific {
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* ASM_M68KNOMMU_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "page_offset_no.h"
+/* This handles the memory map.. */
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW		0x00000000
 #else
-#include "page_offset_mm.h"
+#define PAGE_OFFSET_RAW		0x0E000000
+#endif
+#else
+#define	PAGE_OFFSET_RAW		CONFIG_RAMBASE
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-
-/* This handles the memory map.. */
-#ifndef CONFIG_SUN3
-#define PAGE_OFFSET_RAW		0x00000000
-#else
-#define PAGE_OFFSET_RAW		0x0E000000
-#endif
-
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/page_offset_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/page_offset_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-
-
-/* This handles the memory map.. */
-#define	PAGE_OFFSET_RAW		CONFIG_RAMBASE
-
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,12 @@
-#ifdef __uClinux__
-#include "pci_no.h"
-#else
-#include "pci_mm.h"
-#endif
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+#include <asm-generic/pci-dma-compat.h>
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+#endif /* _ASM_M68K_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_M68K_PCI_H
-#define _ASM_M68K_PCI_H
-
-#include <asm-generic/pci-dma-compat.h>
-
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-#endif /* _ASM_M68K_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pci_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pci_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-#ifndef M68KNOMMU_PCI_H
-#define	M68KNOMMU_PCI_H
-
-#include <asm/pci_mm.h>
-
-#ifdef CONFIG_COMEMPCI
-/*
- *	These are pretty much arbitary with the CoMEM implementation.
- *	We have the whole address space to ourselves.
- */
-#define PCIBIOS_MIN_IO		0x100
-#define PCIBIOS_MIN_MEM		0x00010000
-
-#define pcibios_scan_all_fns(a, b)	0
-
-/*
- * Return whether the given PCI device DMA address mask can
- * be supported properly.  For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-	return 1;
-}
-
-#endif /* CONFIG_COMEMPCI */
-
-#endif /* M68KNOMMU_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,19 @@
-#ifdef __uClinux__
-#include "pgalloc_no.h"
+#ifndef M68K_PGALLOC_H
+#define M68K_PGALLOC_H
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#include <asm/virtconvert.h>
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgalloc.h>
 #else
-#include "pgalloc_mm.h"
+#include <asm/motorola_pgalloc.h>
 #endif
+
+extern void m68k_setup_node(int node);
+#endif
+
+#endif /* M68K_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-
-#ifndef M68K_PGALLOC_H
-#define M68K_PGALLOC_H
-
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <asm/setup.h>
-#include <asm/virtconvert.h>
-
-
-#ifdef CONFIG_SUN3
-#include <asm/sun3_pgalloc.h>
-#else
-#include <asm/motorola_pgalloc.h>
-#endif
-
-extern void m68k_setup_node(int node);
-
-#endif /* M68K_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgalloc_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgalloc_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#ifndef _M68KNOMMU_PGALLOC_H
-#define _M68KNOMMU_PGALLOC_H
-
-#include <asm/setup.h>
-
-#define check_pgt_cache()	do { } while (0)
-
-#endif /* _M68KNOMMU_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgtable_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgtable_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/pgtable_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/pgtable_no.h	2009-06-09 23:05:27.000000000 -0400
@@ -67,4 +67,6 @@ extern unsigned int kobjsize(const void
 
 #include <asm-generic/pgtable.h>
 
+#define check_pgt_cache()	do { } while (0)
+
 #endif /* _M68KNOMMU_PGTABLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/rtc.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/rtc.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/rtc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,13 +36,16 @@ static inline unsigned int get_rtc_time(
 	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
 	 * by the RTC when initially set to a non-zero value.
 	 */
-	mach_hwclk(0, time);
+	if (mach_hwclk)
+		mach_hwclk(0, time);
 	return RTC_24H;
 }
 
 static inline int set_rtc_time(struct rtc_time *time)
 {
-	return mach_hwclk(1, time);
+	if (mach_hwclk)
+		return mach_hwclk(1, time);
+	return -EINVAL;
 }
 
 static inline unsigned int get_rtc_ss(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,23 @@
-#ifdef __uClinux__
-#include "scatterlist_no.h"
-#else
-#include "scatterlist_mm.h"
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
 #endif
+	unsigned long page_link;
+	unsigned int offset;
+	unsigned int length;
+
+	dma_addr_t dma_address;	/* A place to hang host-specific addresses at. */
+};
+
+/* This is bogus and should go away. */
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#define sg_dma_address(sg)	((sg)->dma_address)
+#define sg_dma_len(sg)		((sg)->length)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-#ifndef _M68K_SCATTERLIST_H
-#define _M68K_SCATTERLIST_H
-
-#include <linux/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long sg_magic;
-#endif
-	unsigned long page_link;
-	unsigned int offset;
-	unsigned int length;
-
-	__u32 dma_address;	/* A place to hang host-specific addresses at. */
-};
-
-/* This is bogus and should go away. */
-#define ISA_DMA_THRESHOLD (0x00ffffff)
-
-#define sg_dma_address(sg)	((sg)->dma_address)
-#define sg_dma_len(sg)		((sg)->length)
-
-#endif /* !(_M68K_SCATTERLIST_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/scatterlist_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/scatterlist_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-#ifndef _M68KNOMMU_SCATTERLIST_H
-#define _M68KNOMMU_SCATTERLIST_H
-
-#include <linux/mm.h>
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long	sg_magic;
-#endif
-	unsigned long	page_link;
-	unsigned int	offset;
-	dma_addr_t	dma_address;
-	unsigned int	length;
-};
-
-#define sg_dma_address(sg)      ((sg)->dma_address)
-#define sg_dma_len(sg)          ((sg)->length)
-
-#define ISA_DMA_THRESHOLD	(0xffffffff)
-
-#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,63 @@
-#ifdef __uClinux__
-#include "segment_no.h"
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
+#endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+#ifdef CONFIG_MMU
+	mm_segment_t _v;
+	__asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
+
+	return _v;
 #else
-#include "segment_mm.h"
+	return USER_DS;
+#endif
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+#ifdef CONFIG_MMU
+	__asm__ __volatile__ ("movec %0,%/sfc\n\t"
+			      "movec %0,%/dfc\n\t"
+			      : /* no outputs */ : "r" (val.seg) : "memory");
 #endif
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,57 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA     (1)
-#ifndef __USER_DS
-#define __USER_DS     (USER_DATA)
-#endif
-#define USER_PROGRAM  (2)
-#define SUPER_DATA    (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS   (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE     (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
-#define USER_DS		MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
-	mm_segment_t _v;
-	__asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
-
-	return _v;
-}
-
-static inline mm_segment_t get_ds(void)
-{
-    /* return the supervisor data space code */
-    return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-	__asm__ __volatile__ ("movec %0,%/sfc\n\t"
-			      "movec %0,%/dfc\n\t"
-			      : /* no outputs */ : "r" (val.seg) : "memory");
-}
-
-#define segment_eq(a,b)	((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/segment_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/segment_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA     (1)
-#ifndef __USER_DS
-#define __USER_DS     (USER_DATA)
-#endif
-#define USER_PROGRAM  (2)
-#define SUPER_DATA    (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS   (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE     (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
-#define USER_DS		MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
-    return USER_DS;
-}
-
-static inline mm_segment_t get_ds(void)
-{
-    /* return the supervisor data space code */
-    return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-}
-
-#define segment_eq(a,b)	((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,18 @@
-#ifdef __uClinux__
-#include "timex_no.h"
-#else
-#include "timex_mm.h"
+/*
+ * linux/include/asm-m68k/timex.h
+ *
+ * m68k architecture timex specifications
+ */
+#ifndef _ASMm68k_TIMEX_H
+#define _ASMm68k_TIMEX_H
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/*
- * linux/include/asm-m68k/timex.h
- *
- * m68k architecture timex specifications
- */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
-
-#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
-	return 0;
-}
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/timex_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/timex_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-m68knommu/timex.h
- *
- * m68knommu architecture timex specifications
- */
-#ifndef _ASM_M68KNOMMU_TIMEX_H
-#define _ASM_M68KNOMMU_TIMEX_H
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#define CLOCK_TICK_RATE	MCF_CLK
-#else
-#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
-#endif
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
-	return 0;
-}
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,267 @@
-#ifdef __uClinux__
-#include "tlbflush_no.h"
+#ifndef _M68K_TLBFLUSH_H
+#define _M68K_TLBFLUSH_H
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/current.h>
+
+static inline void flush_tlb_kernel_page(void *addr)
+{
+	if (CPU_IS_040_OR_060) {
+		mm_segment_t old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflush (%0)\n\t"
+				     ".chip 68k"
+				     : : "a" (addr));
+		set_fs(old_fs);
+	} else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	if (CPU_IS_040_OR_060)
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflushan\n\t"
+				     ".chip 68k");
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb040_one(unsigned long addr)
+{
+	__asm__ __volatile__(".chip 68040\n\t"
+			     "pflush (%0)\n\t"
+			     ".chip 68k"
+			     : : "a" (addr));
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	if (CPU_IS_040_OR_060)
+		__flush_tlb040_one(addr);
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	if (CPU_IS_040_OR_060)
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflusha\n\t"
+				     ".chip 68k");
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm == current->active_mm)
+		__flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	if (vma->vm_mm == current->active_mm) {
+		mm_segment_t old_fs = get_fs();
+		set_fs(USER_DS);
+		__flush_tlb_one(addr);
+		set_fs(old_fs);
+	}
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+				   unsigned long start, unsigned long end)
+{
+	if (vma->vm_mm == current->active_mm)
+		__flush_tlb();
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	flush_tlb_all();
+}
+
 #else
-#include "tlbflush_mm.h"
+
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
+
+/* Flush all userspace mappings one by one...  (why no flush command,
+   sun?) */
+static inline void flush_tlb_all(void)
+{
+       unsigned long addr;
+       unsigned char ctx, oldctx;
+
+       oldctx = sun3_get_context();
+       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+	       for(ctx = 0; ctx < 8; ctx++) {
+		       sun3_put_context(ctx);
+		       sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+	       }
+       }
+
+       sun3_put_context(oldctx);
+       /* erase all of the userspace pmeg maps, we've clobbered them
+	  all anyway */
+       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+	       if(pmeg_alloc[addr] == 1) {
+		       pmeg_alloc[addr] = 0;
+		       pmeg_ctx[addr] = 0;
+		       pmeg_vaddr[addr] = 0;
+	       }
+       }
+
+}
+
+/* Clear user TLB entries within the context named in mm */
+static inline void flush_tlb_mm (struct mm_struct *mm)
+{
+     unsigned char oldctx;
+     unsigned char seg;
+     unsigned long i;
+
+     oldctx = sun3_get_context();
+     sun3_put_context(mm->context);
+
+     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+	     seg = sun3_get_segmap(i);
+	     if(seg == SUN3_INVALID_PMEG)
+		     continue;
+
+	     sun3_put_segmap(i, SUN3_INVALID_PMEG);
+	     pmeg_alloc[seg] = 0;
+	     pmeg_ctx[seg] = 0;
+	     pmeg_vaddr[seg] = 0;
+     }
+
+     sun3_put_context(oldctx);
+
+}
+
+/* Flush a single TLB page. In this case, we're limited to flushing a
+   single PMEG */
+static inline void flush_tlb_page (struct vm_area_struct *vma,
+				   unsigned long addr)
+{
+	unsigned char oldctx;
+	unsigned char i;
+
+	oldctx = sun3_get_context();
+	sun3_put_context(vma->vm_mm->context);
+	addr &= ~SUN3_PMEG_MASK;
+	if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
+	{
+		pmeg_alloc[i] = 0;
+		pmeg_ctx[i] = 0;
+		pmeg_vaddr[i] = 0;
+		sun3_put_segmap (addr,  SUN3_INVALID_PMEG);
+	}
+	sun3_put_context(oldctx);
+
+}
+/* Flush a range of pages from TLB. */
+
+static inline void flush_tlb_range (struct vm_area_struct *vma,
+		      unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned char seg, oldctx;
+
+	start &= ~SUN3_PMEG_MASK;
+
+	oldctx = sun3_get_context();
+	sun3_put_context(mm->context);
+
+	while(start < end)
+	{
+		if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
+		     goto next;
+		if(pmeg_ctx[seg] == mm->context) {
+			pmeg_alloc[seg] = 0;
+			pmeg_ctx[seg] = 0;
+			pmeg_vaddr[seg] = 0;
+		}
+		sun3_put_segmap(start, SUN3_INVALID_PMEG);
+	next:
+		start += SUN3_PMEG_SIZE;
+	}
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	flush_tlb_all();
+}
+
+/* Flush kernel page from TLB. */
+static inline void flush_tlb_kernel_page (unsigned long addr)
+{
+	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+}
+
 #endif
+
+#else /* !CONFIG_MMU */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,219 +0,0 @@
-#ifndef _M68K_TLBFLUSH_H
-#define _M68K_TLBFLUSH_H
-
-
-#ifndef CONFIG_SUN3
-
-#include <asm/current.h>
-
-static inline void flush_tlb_kernel_page(void *addr)
-{
-	if (CPU_IS_040_OR_060) {
-		mm_segment_t old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflush (%0)\n\t"
-				     ".chip 68k"
-				     : : "a" (addr));
-		set_fs(old_fs);
-	} else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
-	if (CPU_IS_040_OR_060)
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflushan\n\t"
-				     ".chip 68k");
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb040_one(unsigned long addr)
-{
-	__asm__ __volatile__(".chip 68040\n\t"
-			     "pflush (%0)\n\t"
-			     ".chip 68k"
-			     : : "a" (addr));
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
-	if (CPU_IS_040_OR_060)
-		__flush_tlb040_one(addr);
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
-	if (CPU_IS_040_OR_060)
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflusha\n\t"
-				     ".chip 68k");
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm == current->active_mm)
-		__flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	if (vma->vm_mm == current->active_mm) {
-		mm_segment_t old_fs = get_fs();
-		set_fs(USER_DS);
-		__flush_tlb_one(addr);
-		set_fs(old_fs);
-	}
-}
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-				   unsigned long start, unsigned long end)
-{
-	if (vma->vm_mm == current->active_mm)
-		__flush_tlb();
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	flush_tlb_all();
-}
-
-#else
-
-
-/* Reserved PMEGs. */
-extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
-
-/* Flush all userspace mappings one by one...  (why no flush command,
-   sun?) */
-static inline void flush_tlb_all(void)
-{
-       unsigned long addr;
-       unsigned char ctx, oldctx;
-
-       oldctx = sun3_get_context();
-       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
-	       for(ctx = 0; ctx < 8; ctx++) {
-		       sun3_put_context(ctx);
-		       sun3_put_segmap(addr, SUN3_INVALID_PMEG);
-	       }
-       }
-
-       sun3_put_context(oldctx);
-       /* erase all of the userspace pmeg maps, we've clobbered them
-	  all anyway */
-       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
-	       if(pmeg_alloc[addr] == 1) {
-		       pmeg_alloc[addr] = 0;
-		       pmeg_ctx[addr] = 0;
-		       pmeg_vaddr[addr] = 0;
-	       }
-       }
-
-}
-
-/* Clear user TLB entries within the context named in mm */
-static inline void flush_tlb_mm (struct mm_struct *mm)
-{
-     unsigned char oldctx;
-     unsigned char seg;
-     unsigned long i;
-
-     oldctx = sun3_get_context();
-     sun3_put_context(mm->context);
-
-     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
-	     seg = sun3_get_segmap(i);
-	     if(seg == SUN3_INVALID_PMEG)
-		     continue;
-
-	     sun3_put_segmap(i, SUN3_INVALID_PMEG);
-	     pmeg_alloc[seg] = 0;
-	     pmeg_ctx[seg] = 0;
-	     pmeg_vaddr[seg] = 0;
-     }
-
-     sun3_put_context(oldctx);
-
-}
-
-/* Flush a single TLB page. In this case, we're limited to flushing a
-   single PMEG */
-static inline void flush_tlb_page (struct vm_area_struct *vma,
-				   unsigned long addr)
-{
-	unsigned char oldctx;
-	unsigned char i;
-
-	oldctx = sun3_get_context();
-	sun3_put_context(vma->vm_mm->context);
-	addr &= ~SUN3_PMEG_MASK;
-	if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
-	{
-		pmeg_alloc[i] = 0;
-		pmeg_ctx[i] = 0;
-		pmeg_vaddr[i] = 0;
-		sun3_put_segmap (addr,  SUN3_INVALID_PMEG);
-	}
-	sun3_put_context(oldctx);
-
-}
-/* Flush a range of pages from TLB. */
-
-static inline void flush_tlb_range (struct vm_area_struct *vma,
-		      unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned char seg, oldctx;
-
-	start &= ~SUN3_PMEG_MASK;
-
-	oldctx = sun3_get_context();
-	sun3_put_context(mm->context);
-
-	while(start < end)
-	{
-		if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
-		     goto next;
-		if(pmeg_ctx[seg] == mm->context) {
-			pmeg_alloc[seg] = 0;
-			pmeg_ctx[seg] = 0;
-			pmeg_vaddr[seg] = 0;
-		}
-		sun3_put_segmap(start, SUN3_INVALID_PMEG);
-	next:
-		start += SUN3_PMEG_SIZE;
-	}
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	flush_tlb_all();
-}
-
-/* Flush kernel page from TLB. */
-static inline void flush_tlb_kernel_page (unsigned long addr)
-{
-	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
-}
-
-#endif
-
-#endif /* _M68K_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/tlbflush_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/tlbflush_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-#ifndef _M68KNOMMU_TLBFLUSH_H
-#define _M68KNOMMU_TLBFLUSH_H
-
-/*
- * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
- * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
- */
-
-#include <asm/setup.h>
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
-	BUG();
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
-	BUG();
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
-	BUG();
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-	BUG();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	BUG();
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
-				   unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
-static inline void flush_tlb_kernel_page(unsigned long addr)
-{
-	BUG();
-}
-
-#endif /* _M68KNOMMU_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "ucontext_no.h"
-#else
-#include "ucontext_mm.h"
+#ifndef _M68K_UCONTEXT_H
+#define _M68K_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+typedef struct fpregset {
+	int f_fpcntl[3];
+	int f_fpregs[8*3];
+} fpregset_t;
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+	fpregset_t fpregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+	unsigned long	  uc_filler[80];
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-#ifndef _M68K_UCONTEXT_H
-#define _M68K_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	int f_fpcntl[3];
-	int f_fpregs[8*3];
-} fpregset_t;
-
-struct mcontext {
-	int version;
-	gregset_t gregs;
-	fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct mcontext	  uc_mcontext;
-	unsigned long	  uc_filler[80];
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/ucontext_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/ucontext_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-#ifndef _M68KNOMMU_UCONTEXT_H
-#define _M68KNOMMU_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	int f_pcr;
-	int f_psr;
-	int f_fpiaddr;
-	int f_fpregs[8][3];
-} fpregset_t;
-
-struct mcontext {
-	int version;
-	gregset_t gregs;
-	fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct mcontext	  uc_mcontext;
-	unsigned long	  uc_filler[80];
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,25 @@
-#ifdef __uClinux__
-#include "unaligned_no.h"
+#ifndef _ASM_M68K_UNALIGNED_H
+#define _ASM_M68K_UNALIGNED_H
+
+
+#ifdef CONFIG_COLDFIRE
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
 #else
-#include "unaligned_mm.h"
+/*
+ * The m68k can do unaligned accesses itself. 
+ */
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
 #endif
+
+#endif /* _ASM_M68K_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned_mm.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned_mm.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned_mm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned_mm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef _ASM_M68K_UNALIGNED_H
-#define _ASM_M68K_UNALIGNED_H
-
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#endif /* _ASM_M68K_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned_no.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned_no.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unaligned_no.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unaligned_no.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-#ifndef _ASM_M68KNOMMU_UNALIGNED_H
-#define _ASM_M68KNOMMU_UNALIGNED_H
-
-
-#ifdef CONFIG_COLDFIRE
-#include <linux/unaligned/be_struct.h>
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#else
-/*
- * The m68k can do unaligned accesses itself. 
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#endif
-
-#endif /* _ASM_M68KNOMMU_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/m68k/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -332,10 +332,12 @@
 #define __NR_dup3		326
 #define __NR_pipe2		327
 #define __NR_inotify_init1	328
+#define __NR_preadv		329
+#define __NR_pwritev		330
 
 #ifdef __KERNEL__
 
-#define NR_syscalls		329
+#define NR_syscalls		331
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/install.sh linux-libre-2.6.30-gnu1/arch/m68k/install.sh
--- linux-libre-2.6.29-gnu1/arch/m68k/install.sh	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m68k/install.sh	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# 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) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+#
+# "make install" script for m68k architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+verify () {
+	if [ ! -f "$1" ]; then
+		echo ""                                                   1>&2
+		echo " *** Missing file: $1"                              1>&2
+		echo ' *** You need to run "make" before "make install".' 1>&2
+		echo ""                                                   1>&2
+		exit 1
+	fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
+
+# Default install - same as make zlilo
+
+if [ -f $4/vmlinuz ]; then
+	mv $4/vmlinuz $4/vmlinuz.old
+fi
+
+if [ -f $4/System.map ]; then
+	mv $4/System.map $4/System.old
+fi
+
+cat $2 > $4/vmlinuz
+cp $3 $4/System.map
+
+sync
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/entry.S linux-libre-2.6.30-gnu1/arch/m68k/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -753,4 +753,6 @@ sys_call_table:
 	.long sys_dup3
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev		/* 330 */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/head.S linux-libre-2.6.30-gnu1/arch/m68k/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -577,7 +577,7 @@ func_define	putn,1
 #endif
 .endm
 
-.section ".text.head","ax"
+__HEAD
 ENTRY(_stext)
 /*
  * Version numbers of the bootinfo interface
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/process.c linux-libre-2.6.30-gnu1/arch/m68k/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -233,7 +233,7 @@ asmlinkage int m68k_clone(struct pt_regs
 		       parent_tidptr, child_tidptr);
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		 unsigned long unused,
 		 struct task_struct * p, struct pt_regs * regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/sun3-head.S linux-libre-2.6.30-gnu1/arch/m68k/kernel/sun3-head.S
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/sun3-head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/sun3-head.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/linkage.h>
+#include <linux/init.h>
 
 #include <asm/entry.h>
 #include <asm/page.h>
@@ -29,7 +30,7 @@ kernel_pmd_table:              .skip 0x2
 .globl kernel_pg_dir
 .equ    kernel_pg_dir,kernel_pmd_table
 
-	.section .text.head
+	__HEAD
 ENTRY(_stext)
 ENTRY(_start)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/time.c linux-libre-2.6.30-gnu1/arch/m68k/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/rtc.h>
+#include <linux/platform_device.h>
 
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -159,3 +160,20 @@ int do_settimeofday(struct timespec *tv)
 }
 
 EXPORT_SYMBOL(do_settimeofday);
+
+
+static int __init rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	if (!mach_hwclk)
+		return -ENODEV;
+
+	pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+module_init(rtc_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/vmlinux-std.lds linux-libre-2.6.30-gnu1/arch/m68k/kernel/vmlinux-std.lds
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/vmlinux-std.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/vmlinux-std.lds	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@ SECTIONS
   . = 0x1000;
   _text = .;			/* Text and read-only data */
   .text : {
-	*(.text.head)
+	HEAD_TEXT
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/kernel/vmlinux-sun3.lds linux-libre-2.6.30-gnu1/arch/m68k/kernel/vmlinux-sun3.lds
--- linux-libre-2.6.29-gnu1/arch/m68k/kernel/vmlinux-sun3.lds	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/kernel/vmlinux-sun3.lds	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@ SECTIONS
   . = 0xE002000;
   _text = .;			/* Text and read-only data */
   .text : {
-	*(.text.head)
+	HEAD_TEXT
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/mac/config.c linux-libre-2.6.30-gnu1/arch/m68k/mac/config.c
--- linux-libre-2.6.29-gnu1/arch/m68k/mac/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/mac/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 /* keyb */
 #include <linux/init.h>
 #include <linux/vt_kern.h>
+#include <linux/platform_device.h>
 
 #define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
@@ -43,6 +44,10 @@
 #include <asm/mac_oss.h>
 #include <asm/mac_psc.h>
 
+/* platform device info */
+
+#define SWIM_IO_SIZE 0x2000	/* SWIM IO resource size */
+
 /* Mac bootinfo struct */
 
 struct mac_booter_data mac_bi_data;
@@ -224,7 +229,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_II,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_IWM
 	},
 
 	/*
@@ -239,7 +245,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_II,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_IWM
 	}, {
 		.ident		= MAC_MODEL_IIX,
 		.name		= "IIx",
@@ -247,7 +254,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_II,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_IICX,
 		.name		= "IIcx",
@@ -255,7 +263,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_II,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_SE30,
 		.name		= "SE/30",
@@ -263,7 +272,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_II,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -280,7 +290,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_IIFX,
 		.name		= "IIfx",
@@ -288,7 +299,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_IOP,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_IOP
 	}, {
 		.ident		= MAC_MODEL_IISI,
 		.name		= "IIsi",
@@ -296,7 +308,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_IIVI,
 		.name		= "IIvi",
@@ -304,7 +317,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_IIVX,
 		.name		= "IIvx",
@@ -312,7 +326,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -326,7 +341,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_CCL,
 		.name		= "Color Classic",
@@ -334,7 +350,9 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS},
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
+	},
 
 	/*
 	 *	Some Mac LC machines. Basically the same as the IIci, ADB like IIsi
@@ -347,7 +365,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_LCII,
 		.name		= "LC II",
@@ -355,7 +374,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_LCIII,
 		.name		= "LC III",
@@ -363,7 +383,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -383,7 +404,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q605_ACC,
 		.name		= "Quadra 605",
@@ -391,7 +413,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q610,
 		.name		= "Quadra 610",
@@ -400,7 +423,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q630,
 		.name		= "Quadra 630",
@@ -410,7 +434,8 @@ static struct mac_model mac_data_table[]
 		.ide_type	= MAC_IDE_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q650,
 		.name		= "Quadra 650",
@@ -419,7 +444,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	},
 	/*	The Q700 does have a NS Sonic */
 	{
@@ -430,7 +456,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA2,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q800,
 		.name		= "Quadra 800",
@@ -439,7 +466,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_Q840,
 		.name		= "Quadra 840AV",
@@ -448,7 +476,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA3,
 		.scc_type	= MAC_SCC_PSC,
 		.ether_type	= MAC_ETHER_MACE,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_AV
 	}, {
 		.ident		= MAC_MODEL_Q900,
 		.name		= "Quadra 900",
@@ -457,7 +486,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA2,
 		.scc_type	= MAC_SCC_IOP,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_IOP
 	}, {
 		.ident		= MAC_MODEL_Q950,
 		.name		= "Quadra 950",
@@ -466,7 +496,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA2,
 		.scc_type	= MAC_SCC_IOP,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_IOP
 	},
 
 	/*
@@ -480,7 +511,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_P475,
 		.name		=  "Performa 475",
@@ -488,7 +520,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_P475F,
 		.name		=  "Performa 475",
@@ -496,7 +529,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_P520,
 		.name		=  "Performa 520",
@@ -504,7 +538,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_P550,
 		.name		=  "Performa 550",
@@ -512,7 +547,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 	/* These have the comm slot, and therefore the possibility of SONIC ethernet */
 	{
@@ -523,7 +559,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_II,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_P588,
 		.name		= "Performa 588",
@@ -533,7 +570,8 @@ static struct mac_model mac_data_table[]
 		.ide_type	= MAC_IDE_QUADRA,
 		.scc_type	= MAC_SCC_II,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type	= MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_TV,
 		.name		= "TV",
@@ -541,7 +579,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_P600,
 		.name		= "Performa 600",
@@ -549,7 +588,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_II,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -565,7 +605,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_C650,
 		.name		= "Centris 650",
@@ -574,7 +615,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR1
 	}, {
 		.ident		= MAC_MODEL_C660,
 		.name		= "Centris 660AV",
@@ -583,7 +625,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_QUADRA3,
 		.scc_type	= MAC_SCC_PSC,
 		.ether_type	= MAC_ETHER_MACE,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_AV
 	},
 
 	/*
@@ -599,7 +642,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB145,
 		.name		= "PowerBook 145",
@@ -607,7 +651,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB150,
 		.name		= "PowerBook 150",
@@ -616,7 +661,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.ide_type	= MAC_IDE_PB,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB160,
 		.name		= "PowerBook 160",
@@ -624,7 +670,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB165,
 		.name		= "PowerBook 165",
@@ -632,7 +679,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB165C,
 		.name		= "PowerBook 165c",
@@ -640,7 +688,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB170,
 		.name		= "PowerBook 170",
@@ -648,7 +697,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB180,
 		.name		= "PowerBook 180",
@@ -656,7 +706,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB180C,
 		.name		= "PowerBook 180c",
@@ -664,7 +715,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_QUADRA,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB190,
 		.name		= "PowerBook 190",
@@ -673,7 +725,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.ide_type	= MAC_IDE_BABOON,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB520,
 		.name		= "PowerBook 520",
@@ -682,7 +735,8 @@ static struct mac_model mac_data_table[]
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
 		.ether_type	= MAC_ETHER_SONIC,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -702,7 +756,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB230,
 		.name		= "PowerBook Duo 230",
@@ -710,7 +765,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB250,
 		.name		= "PowerBook Duo 250",
@@ -718,7 +774,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB270C,
 		.name		= "PowerBook Duo 270c",
@@ -726,7 +783,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB280,
 		.name		= "PowerBook Duo 280",
@@ -734,7 +792,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	}, {
 		.ident		= MAC_MODEL_PB280C,
 		.name		= "PowerBook Duo 280c",
@@ -742,7 +801,8 @@ static struct mac_model mac_data_table[]
 		.via_type	= MAC_VIA_IIci,
 		.scsi_type	= MAC_SCSI_OLD,
 		.scc_type	= MAC_SCC_QUADRA,
-		.nubus_type	= MAC_NUBUS
+		.nubus_type	= MAC_NUBUS,
+		.floppy_type    = MAC_FLOPPY_SWIM_ADDR2
 	},
 
 	/*
@@ -815,3 +875,42 @@ static void mac_get_model(char *str)
 	strcpy(str, "Macintosh ");
 	strcat(str, macintosh_config->name);
 }
+
+static struct resource swim_resources[1];
+
+static struct platform_device swim_device = {
+	.name		= "swim",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(swim_resources),
+	.resource	= swim_resources,
+};
+
+static struct platform_device *mac_platform_devices[] __initdata = {
+	&swim_device
+};
+
+int __init mac_platform_init(void)
+{
+	u8 *swim_base;
+
+	switch (macintosh_config->floppy_type) {
+	case MAC_FLOPPY_SWIM_ADDR1:
+		swim_base = (u8 *)(VIA1_BASE + 0x1E000);
+		break;
+	case MAC_FLOPPY_SWIM_ADDR2:
+		swim_base = (u8 *)(VIA1_BASE + 0x16000);
+		break;
+	default:
+		return 0;
+	}
+
+	swim_resources[0].name = "swim-regs";
+	swim_resources[0].start = (resource_size_t)swim_base;
+	swim_resources[0].end = (resource_size_t)(swim_base + SWIM_IO_SIZE);
+	swim_resources[0].flags = IORESOURCE_MEM;
+
+	return platform_add_devices(mac_platform_devices,
+				    ARRAY_SIZE(mac_platform_devices));
+}
+
+arch_initcall(mac_platform_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/mac/via.c linux-libre-2.6.30-gnu1/arch/m68k/mac/via.c
--- linux-libre-2.6.29-gnu1/arch/m68k/mac/via.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/mac/via.c	2009-06-09 23:05:27.000000000 -0400
@@ -645,3 +645,12 @@ int via_irq_pending(int irq)
 	}
 	return 0;
 }
+
+void via1_set_head(int head)
+{
+	if (head == 0)
+		via1[vBufA] &= ~VIA1A_vHeadSel;
+	else
+		via1[vBufA] |= VIA1A_vHeadSel;
+}
+EXPORT_SYMBOL(via1_set_head);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68k/Makefile linux-libre-2.6.30-gnu1/arch/m68k/Makefile
--- linux-libre-2.6.29-gnu1/arch/m68k/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68k/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -117,3 +117,6 @@ endif
 
 archclean:
 	rm -f vmlinux.gz vmlinux.bz2
+
+install:
+	sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5208evb_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5208evb_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5208evb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5208evb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc1
+# Linux kernel version: 2.6.30-rc2
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
@@ -15,9 +15,10 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_TIME_LOW_RES=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_NO_IOPORT=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -33,53 +34,55 @@ CONFIG_LOCALVERSION_AUTO=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 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_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_EMBEDDED=y
-# CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+# CONFIG_COMPAT_BRK is not set
+# 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 is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_BASE_SMALL=0
-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 is not set
+# CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -93,7 +96,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Processor type and features
@@ -145,44 +148,39 @@ CONFIG_RAM16BIT=y
 # CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=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_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 is not set
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_ZFLAT is not set
 # CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_AOUT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -223,6 +221,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
@@ -232,7 +231,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
@@ -243,14 +244,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -289,10 +284,8 @@ CONFIG_MTD_BLOCK=y
 #
 # RAM/ROM/Flash chip drivers
 #
-CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI is not set
 # 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
@@ -303,10 +296,6 @@ 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=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -315,7 +304,6 @@ CONFIG_MTD_RAM=y
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_PLATRAM is not set
 
@@ -337,6 +325,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
@@ -351,6 +344,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_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -364,7 +358,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK 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
@@ -374,10 +368,15 @@ 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
 # 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_FEC=y
 # CONFIG_FEC2 is not set
@@ -389,8 +388,10 @@ CONFIG_FEC=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI 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
@@ -415,7 +416,7 @@ CONFIG_FEC=y
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -428,7 +429,6 @@ CONFIG_FEC=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_COLDFIRE is not set
 CONFIG_SERIAL_MCF=y
 CONFIG_SERIAL_MCF_BAUDRATE=115200
 CONFIG_SERIAL_MCF_CONSOLE=y
@@ -447,19 +447,23 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_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
@@ -470,11 +474,12 @@ CONFIG_SSB_POSSIBLE=y
 #
 # 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_DAB=y
 
 #
 # Graphics support
@@ -488,10 +493,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
@@ -499,7 +500,10 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 
 #
 # File systems
@@ -507,11 +511,13 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_EXT2_FS=y
 # 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_FILE_LOCKING is not set
 # CONFIG_XFS_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
@@ -520,6 +526,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -540,10 +551,7 @@ CONFIG_PROC_SYSCTL=y
 # CONFIG_SYSFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE 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
@@ -553,13 +561,20 @@ CONFIG_PROC_SYSCTL=y
 # 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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -581,10 +596,14 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # 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=y
 # CONFIG_SAMPLES is not set
 CONFIG_FULLDEBUG=y
 # CONFIG_HIGHPROFILE is not set
-# CONFIG_BOOTPARAM is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
 # CONFIG_NO_KERNEL_MSG is not set
 # CONFIG_BDM_DISABLE is not set
 
@@ -592,19 +611,23 @@ CONFIG_FULLDEBUG=y
 # Security options
 #
 # CONFIG_KEYS 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_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5249evb_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5249evb_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5249evb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5249evb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc1
+# Linux kernel version: 2.6.30-rc2
+# Wed Apr 22 17:32:41 2009
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
@@ -15,9 +16,10 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_NO_IOPORT=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -29,11 +31,23 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SYSVIPC is not set
+# 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=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
@@ -41,44 +55,37 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-# CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+# CONFIG_SLUB_DEBUG 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 is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_BASE_SMALL=0
-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 is not set
+# CONFIG_MODULES is not set
 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
@@ -92,7 +99,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Processor type and features
@@ -144,45 +151,103 @@ CONFIG_RAMAUTOBIT=y
 # CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT 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=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 is not set
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_ZFLAT is not set
 # CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_AOUT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
+CONFIG_NET=y
 
 #
-# Networking
+# Networking options
 #
-# CONFIG_NET is not set
+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 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_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_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
@@ -194,6 +259,7 @@ CONFIG_BINFMT_FLAT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # 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
@@ -259,6 +325,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
@@ -266,14 +337,15 @@ 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_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_ENCLOSURE_SERVICES 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
 
@@ -285,6 +357,56 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK 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 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_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=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# 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
 
 #
@@ -302,7 +424,7 @@ CONFIG_HAVE_IDE=y
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -315,7 +437,6 @@ CONFIG_HAVE_IDE=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_COLDFIRE is not set
 CONFIG_SERIAL_MCF=y
 CONFIG_SERIAL_MCF_BAUDRATE=19200
 CONFIG_SERIAL_MCF_CONSOLE=y
@@ -323,7 +444,8 @@ CONFIG_SERIAL_MCF_CONSOLE=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -334,19 +456,23 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_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
@@ -356,11 +482,13 @@ CONFIG_SSB_POSSIBLE=y
 # 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_DAB=y
 
 #
 # Graphics support
@@ -374,10 +502,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
@@ -385,7 +509,10 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 
 #
 # File systems
@@ -393,19 +520,28 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_EXT2_FS=y
 # 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_FILE_LOCKING is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY 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 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
@@ -427,10 +563,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
@@ -440,13 +573,21 @@ CONFIG_SYSFS=y
 # 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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
 # Partition Types
@@ -454,6 +595,7 @@ CONFIG_ROMFS_FS=y
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
@@ -468,10 +610,14 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # 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_SAMPLES is not set
 # CONFIG_FULLDEBUG is not set
 # CONFIG_HIGHPROFILE is not set
-# CONFIG_BOOTPARAM is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
 # CONFIG_NO_KERNEL_MSG is not set
 # CONFIG_BDM_DISABLE is not set
 
@@ -480,18 +626,22 @@ CONFIG_FRAME_WARN=1024
 #
 # 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_FIRST_BIT is not set
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5272c3_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5272c3_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5272c3_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5272c3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,645 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc2
+# Wed Apr 22 17:17:30 2009
+#
+CONFIG_M68K=y
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_ZONE_DMA=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=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_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_NO_IOPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SYSVIPC is not set
+# 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=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 is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG 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_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES 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 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 is not set
+
+#
+# Processor type and features
+#
+# CONFIG_M68328 is not set
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68VZ328 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+# CONFIG_M520x is not set
+# CONFIG_M523x is not set
+# CONFIG_M5249 is not set
+# CONFIG_M5271 is not set
+CONFIG_M5272=y
+# CONFIG_M5275 is not set
+# CONFIG_M528x is not set
+# CONFIG_M5307 is not set
+# CONFIG_M532x is not set
+# CONFIG_M5407 is not set
+CONFIG_COLDFIRE=y
+CONFIG_CLOCK_SET=y
+CONFIG_CLOCK_FREQ=66666666
+CONFIG_CLOCK_DIV=1
+
+#
+# Platform
+#
+# CONFIG_UC5272 is not set
+CONFIG_M5272C3=y
+# CONFIG_COBRA5272 is not set
+# CONFIG_CANCam is not set
+# CONFIG_SCALES is not set
+# CONFIG_NETtel is not set
+# CONFIG_CPU16B is not set
+# CONFIG_MOD5272 is not set
+CONFIG_FREESCALE=y
+CONFIG_4KSTACKS=y
+CONFIG_HZ=100
+
+#
+# RAM configuration
+#
+CONFIG_RAMBASE=0x00000000
+CONFIG_RAMSIZE=0x00800000
+CONFIG_VECTORBASE=0x00000000
+CONFIG_KERNELBASE=0x00020000
+CONFIG_RAMAUTOBIT=y
+# CONFIG_RAM8BIT is not set
+# CONFIG_RAM16BIT is not set
+# CONFIG_RAM32BIT is not set
+
+#
+# ROM configuration
+#
+# CONFIG_ROM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT 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_UNEVICTABLE_LRU is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# 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_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 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_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_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_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# 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_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_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=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=y
+# 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_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 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_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 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_FEC=y
+# CONFIG_FEC2 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
+
+#
+# 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_MCF=y
+CONFIG_SERIAL_MCF_BAUDRATE=19200
+CONFIG_SERIAL_MCF_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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 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
+
+#
+# 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
+
+#
+# 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 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_CLASS 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 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 is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_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
+
+#
+# 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_SYSFS=y
+# CONFIG_TMPFS 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 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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_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
+# 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_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_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
+# CONFIG_FULLDEBUG is not set
+# CONFIG_HIGHPROFILE is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
+# CONFIG_NO_KERNEL_MSG is not set
+# CONFIG_BDM_DISABLE 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_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_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5275evb_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5275evb_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5275evb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5275evb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc1
+# Linux kernel version: 2.6.30-rc2
+# Wed Apr 22 23:29:01 2009
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
@@ -15,9 +16,10 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_TIME_LOW_RES=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_NO_IOPORT=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -33,10 +35,19 @@ CONFIG_LOCALVERSION_AUTO=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 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_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -44,44 +55,37 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-# CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+# CONFIG_SLUB_DEBUG 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 is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_BASE_SMALL=0
-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 is not set
+# CONFIG_MODULES is not set
 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
@@ -95,7 +99,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Processor type and features
@@ -148,44 +152,39 @@ CONFIG_RAMAUTOBIT=y
 # CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=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_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 is not set
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_ZFLAT is not set
 # CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_AOUT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -226,6 +225,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
@@ -235,7 +235,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
@@ -246,14 +248,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -333,6 +329,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
@@ -347,6 +348,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_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -360,7 +362,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK 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
@@ -370,10 +372,15 @@ 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
 # 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_FEC=y
 CONFIG_FEC2=y
@@ -385,8 +392,10 @@ CONFIG_FEC2=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI 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=y
 # CONFIG_PPP_MULTILINK is not set
@@ -421,7 +430,7 @@ CONFIG_SLHC=y
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -434,7 +443,6 @@ CONFIG_SLHC=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_COLDFIRE is not set
 CONFIG_SERIAL_MCF=y
 CONFIG_SERIAL_MCF_BAUDRATE=19200
 CONFIG_SERIAL_MCF_CONSOLE=y
@@ -442,7 +450,8 @@ CONFIG_SERIAL_MCF_CONSOLE=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
@@ -453,19 +462,23 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_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
@@ -476,6 +489,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -494,10 +508,6 @@ CONFIG_DAB=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
@@ -505,7 +515,10 @@ CONFIG_DAB=y
 # 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
 
 #
 # File systems
@@ -513,12 +526,14 @@ CONFIG_DAB=y
 CONFIG_EXT2_FS=y
 # 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_FILE_LOCKING is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -527,6 +542,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -548,10 +568,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
@@ -561,21 +578,21 @@ CONFIG_SYSFS=y
 # 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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_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
+# CONFIG_NILFS2_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
 # Partition Types
@@ -598,10 +615,14 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # 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=y
 # CONFIG_SAMPLES is not set
 # CONFIG_FULLDEBUG is not set
 # CONFIG_HIGHPROFILE is not set
-# CONFIG_BOOTPARAM is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
 # CONFIG_NO_KERNEL_MSG is not set
 # CONFIG_BDM_DISABLE is not set
 
@@ -610,18 +631,22 @@ CONFIG_FRAME_WARN=1024
 #
 # 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_FIRST_BIT is not set
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5307c3_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5307c3_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5307c3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5307c3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc1
+# Linux kernel version: 2.6.30-rc2
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
@@ -15,9 +15,10 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_NO_IOPORT=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -33,10 +34,21 @@ CONFIG_LOCALVERSION_AUTO=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 is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_USER_SCHED is not set
+# 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
@@ -44,44 +56,37 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-# CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+# CONFIG_SLUB_DEBUG 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 is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_SLABINFO=y
-CONFIG_TINY_SHMEM=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_BASE_SMALL=0
-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 is not set
+# CONFIG_MODULES is not set
 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
@@ -95,7 +100,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Processor type and features
@@ -127,12 +132,11 @@ CONFIG_CLOCK_DIV=2
 #
 # CONFIG_ARN5307 is not set
 CONFIG_M5307C3=y
-# CONFIG_eLIA is not set
 # CONFIG_SECUREEDGEMP3 is not set
 # CONFIG_CLEOPATRA is not set
 # CONFIG_NETtel is not set
 CONFIG_FREESCALE=y
-# CONFIG_4KSTACKS is not set
+CONFIG_4KSTACKS=y
 CONFIG_HZ=100
 
 #
@@ -153,45 +157,36 @@ CONFIG_RAMAUTOBIT=y
 # CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT 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=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 is not set
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-# CONFIG_COMEMPCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_ZFLAT is not set
 # CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_AOUT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -232,6 +227,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
@@ -241,7 +237,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
@@ -252,14 +250,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -274,7 +266,79 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+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
+# 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=y
+# 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
@@ -286,6 +350,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_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -299,7 +364,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK 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
@@ -309,10 +374,15 @@ 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
 # 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
@@ -322,8 +392,10 @@ CONFIG_NET_ETHERNET=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI 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=y
 # CONFIG_PPP_MULTILINK is not set
@@ -381,7 +453,7 @@ CONFIG_INPUT=y
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -394,13 +466,12 @@ CONFIG_INPUT=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_COLDFIRE is not set
 CONFIG_SERIAL_MCF=y
 CONFIG_SERIAL_MCF_BAUDRATE=19200
 CONFIG_SERIAL_MCF_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# 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_GEN_RTC is not set
@@ -413,19 +484,23 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_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
@@ -436,6 +511,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -454,10 +530,6 @@ CONFIG_DAB=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
@@ -466,7 +538,10 @@ CONFIG_DAB=y
 # 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
 
 #
 # File systems
@@ -474,12 +549,14 @@ CONFIG_DAB=y
 CONFIG_EXT2_FS=y
 # 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_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -488,6 +565,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -509,10 +591,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
@@ -520,14 +599,22 @@ 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_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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -551,10 +638,14 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # 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=y
 # CONFIG_SAMPLES is not set
 CONFIG_FULLDEBUG=y
 # CONFIG_HIGHPROFILE is not set
-# CONFIG_BOOTPARAM is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
 # CONFIG_NO_KERNEL_MSG is not set
 # CONFIG_BDM_DISABLE is not set
 
@@ -563,18 +654,22 @@ CONFIG_FULLDEBUG=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 is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5407c3_defconfig linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5407c3_defconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/configs/m5407c3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/configs/m5407c3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc1
-# Wed May  7 10:25:16 2008
+# Linux kernel version: 2.6.30-rc2
+# Thu Apr 23 09:21:40 2009
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
@@ -16,9 +16,10 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
 CONFIG_NO_IOPORT=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -34,10 +35,19 @@ CONFIG_LOCALVERSION_AUTO=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 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_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -45,44 +55,43 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
-# CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SIGNALFD is not set
 # CONFIG_TIMERFD is not set
 # CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+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 is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS 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
 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 is not set
 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 +105,7 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Processor type and features
@@ -149,45 +158,36 @@ CONFIG_RAMAUTOBIT=y
 # CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT 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=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 is not set
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-# CONFIG_PCI is not set
-# CONFIG_COMEMPCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_ZFLAT is not set
 # CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_AOUT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -228,6 +228,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
@@ -237,7 +238,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
@@ -248,14 +251,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -274,6 +271,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -335,6 +333,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
@@ -349,6 +352,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_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -362,7 +366,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_SCSI_NETLINK 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
@@ -372,10 +376,15 @@ 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
 # 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
@@ -385,8 +394,10 @@ CONFIG_NET_ETHERNET=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI 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=y
 # CONFIG_PPP_MULTILINK is not set
@@ -409,39 +420,22 @@ CONFIG_SLHC=y
 #
 # 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 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
+# CONFIG_INPUT is not set
 
 #
 # Hardware I/O ports
 #
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
 
 #
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -454,7 +448,6 @@ CONFIG_INPUT=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_COLDFIRE is not set
 CONFIG_SERIAL_MCF=y
 CONFIG_SERIAL_MCF_BAUDRATE=19200
 CONFIG_SERIAL_MCF_CONSOLE=y
@@ -473,19 +466,23 @@ CONFIG_LEGACY_PTY_COUNT=256
 # 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_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
@@ -496,6 +493,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
 
 #
 # Multimedia drivers
@@ -514,19 +512,17 @@ CONFIG_DAB=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # 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_CLASS 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
@@ -534,12 +530,14 @@ CONFIG_DAB=y
 CONFIG_EXT2_FS=y
 # 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_FILE_LOCKING is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -548,6 +546,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -569,10 +572,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
@@ -582,13 +582,20 @@ CONFIG_SYSFS=y
 # 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 is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -611,11 +618,17 @@ CONFIG_FRAME_WARN=1024
 # 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_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 # CONFIG_FULLDEBUG is not set
 # CONFIG_HIGHPROFILE is not set
-# CONFIG_BOOTPARAM is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
 # CONFIG_NO_KERNEL_MSG is not set
 # CONFIG_BDM_DISABLE is not set
 
@@ -624,18 +637,22 @@ CONFIG_FRAME_WARN=1024
 #
 # 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_FIRST_BIT is not set
+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_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/Kconfig linux-libre-2.6.30-gnu1/arch/m68knommu/Kconfig
--- linux-libre-2.6.29-gnu1/arch/m68knommu/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@ config MMU
 
 config NO_DMA
 	bool
+	depends on !COLDFIRE
 	default y
 
 config FPU
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/asm-offsets.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,9 +30,6 @@ int main(void)
 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
 	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
 
-	/* offsets into the kernel_stat struct */
-	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
-
 	/* offsets into the irq_cpustat_t struct */
 	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
 
@@ -69,9 +66,6 @@ int main(void)
 	DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
 #endif
 
-	/* offsets into the kernel_stat struct */
-	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
-
 	/* signal defines */
 	DEFINE(SIGSEGV, SIGSEGV);
 	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/dma.c linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/dma.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,12 +7,12 @@
 
 #include <linux/types.h>
 #include <linux/mm.h>
-#include <linux/string.h>
 #include <linux/device.h>
-#include <asm/io.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle, int gfp)
+			   dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
 	/* ignore region specifiers */
@@ -34,3 +34,40 @@ void dma_free_coherent(struct device *de
 {
 	free_pages((unsigned long)vaddr, get_order(size));
 }
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
+				size_t size, enum dma_data_direction dir)
+{
+	switch (dir) {
+	case DMA_TO_DEVICE:
+		flush_dcache_range(handle, size);
+		break;
+	case DMA_FROM_DEVICE:
+		/* Should be clear already */
+		break;
+	default:
+		if (printk_ratelimit())
+			printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
+		break;
+	}
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
+			  enum dma_data_direction dir)
+{
+	dma_addr_t handle = virt_to_phys(addr);
+	flush_dcache_range(handle, size);
+	return handle;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction dir)
+{
+	dma_addr_t handle = page_to_phys(page) + offset;
+	dma_sync_single_for_device(dev, handle, size, dir);
+	return handle;
+}
+EXPORT_SYMBOL(dma_map_page);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/irq.c linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@ asmlinkage void do_IRQ(int irq, struct p
 	struct pt_regs *oldregs = set_irq_regs(regs);
 
 	irq_enter();
-	__do_IRQ(irq);
+	generic_handle_irq(irq);
 	irq_exit();
 
 	set_irq_regs(oldregs);
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/process.c linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -199,7 +199,7 @@ asmlinkage int m68k_clone(struct pt_regs
         return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
 }
 
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
 		unsigned long usp, unsigned long topstk,
 		struct task_struct * p, struct pt_regs * regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/syscalltable.S linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/syscalltable.S
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/syscalltable.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/syscalltable.S	2009-06-09 23:05:27.000000000 -0400
@@ -347,6 +347,8 @@ ENTRY(sys_call_table)
 	.long sys_dup3
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev		/* 330 */
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/m68knommu/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -147,6 +147,8 @@ SECTIONS {
 		. = ALIGN(4);
 		_sdata = . ;
 		DATA_DATA
+		. = ALIGN(32);
+		*(.data.cacheline_aligned)
 		. = ALIGN(8192) ;
 		*(.data.init_task)
 		_edata = . ;
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/Makefile linux-libre-2.6.30-gnu1/arch/m68knommu/Makefile
--- linux-libre-2.6.29-gnu1/arch/m68knommu/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -88,18 +88,18 @@ export PLATFORM BOARD MODEL CPUCLASS
 #
 # Some CFLAG additions based on specific CPU type.
 #
-cflags-$(CONFIG_M5206)		:= -m5200
-cflags-$(CONFIG_M5206e)		:= -m5200
-cflags-$(CONFIG_M520x)		:= -m5307
+cflags-$(CONFIG_M5206)		:= $(call cc-option,-mcpu=5206,-m5200)
+cflags-$(CONFIG_M5206e)		:= $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M520x)		:= $(call cc-option,-mcpu=5208,-m5200)
 cflags-$(CONFIG_M523x)		:= $(call cc-option,-mcpu=523x,-m5307)
-cflags-$(CONFIG_M5249)		:= -m5200
+cflags-$(CONFIG_M5249)		:= $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)		:= $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)		:= -m5307
+cflags-$(CONFIG_M5272)		:= $(call cc-option,-mcpu=5271,-m5200)
 cflags-$(CONFIG_M5275)		:= $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)		:= $(call cc-option,-m528x,-m5307)
-cflags-$(CONFIG_M5307)		:= -m5307
+cflags-$(CONFIG_M5307)		:= $(call cc-option,-m5307,-m5200)
 cflags-$(CONFIG_M532x)		:= $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407)		:= -m5200
+cflags-$(CONFIG_M5407)		:= $(call cc-option,-m5407,-m5200)
 cflags-$(CONFIG_M68328)		:= -m68000
 cflags-$(CONFIG_M68EZ328)	:= -m68000
 cflags-$(CONFIG_M68VZ328)	:= -m68000
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/mm/init.c linux-libre-2.6.30-gnu1/arch/m68knommu/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -111,11 +111,7 @@ void __init paging_init(void)
 	{
 		unsigned long zones_size[MAX_NR_ZONES] = {0, };
 
-		zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
-		zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
-		zones_size[ZONE_HIGHMEM] = 0;
-#endif
+		zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
 		free_area_init(zones_size);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/520x/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/520x/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/520x/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/520x/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,8 +49,39 @@ static struct platform_device m520x_uart
 	.dev.platform_data	= m520x_uart_platform,
 };
 
+static struct resource m520x_fec_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x30000,
+		.end		= MCF_MBAR + 0x30000 + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 64 + 36,
+		.end		= 64 + 36,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 40,
+		.end		= 64 + 40,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 42,
+		.end		= 64 + 42,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m520x_fec = {
+	.name			= "fec",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m520x_fec_resources),
+	.resource		= m520x_fec_resources,
+};
+
 static struct platform_device *m520x_devices[] __initdata = {
 	&m520x_uart,
+	&m520x_fec,
 };
 
 /***************************************************************************/
@@ -103,6 +134,30 @@ static void __init m520x_uarts_init(void
 
 /***************************************************************************/
 
+static void __init m520x_fec_init(void)
+{
+	u32 imr;
+	u8 v;
+
+	/* Unmask FEC interrupts at ColdFire interrupt controller */
+	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
+	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
+	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
+
+	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	imr &= ~0x0001FFF0;
+	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+
+	/* Set multi-function pins to ethernet mode */
+	v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
+	writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
+
+	v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+	writeb(v | 0x0f, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+}
+
+/***************************************************************************/
+
 /*
  *  Program the vector to be an auto-vectored.
  */
@@ -118,6 +173,7 @@ void __init config_BSP(char *commandp, i
 {
 	mach_reset = coldfire_reset;
 	m520x_uarts_init();
+	m520x_fec_init();
 }
 
 /***************************************************************************/
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/523x/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/523x/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/523x/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/523x/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,8 +50,39 @@ static struct platform_device m523x_uart
 	.dev.platform_data	= m523x_uart_platform,
 };
 
+static struct resource m523x_fec_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x1000,
+		.end		= MCF_MBAR + 0x1000 + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 64 + 23,
+		.end		= 64 + 23,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 27,
+		.end		= 64 + 27,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 29,
+		.end		= 64 + 29,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m523x_fec = {
+	.name			= "fec",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m523x_fec_resources),
+	.resource		= m523x_fec_resources,
+};
+
 static struct platform_device *m523x_devices[] __initdata = {
 	&m523x_uart,
+	&m523x_fec,
 };
 
 /***************************************************************************/
@@ -83,6 +114,25 @@ static void __init m523x_uarts_init(void
 
 /***************************************************************************/
 
+static void __init m523x_fec_init(void)
+{
+	u32 imr;
+
+	/* Unmask FEC interrupts at ColdFire interrupt controller */
+	writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
+	writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
+	writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
+
+	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	imr &= ~0xf;
+	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+	imr &= ~0xff800001;
+	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+}
+
+/***************************************************************************/
+
 void mcf_disableall(void)
 {
 	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -103,6 +153,7 @@ void __init config_BSP(char *commandp, i
 	mcf_disableall();
 	mach_reset = coldfire_reset;
 	m523x_uarts_init();
+	m523x_fec_init();
 }
 
 /***************************************************************************/
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5249/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5249/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5249/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5249/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,8 @@ static struct mcf_platform_uart m5249_ua
 	{
 		.mapbase 	= MCF_MBAR + MCFUART_BASE2,
 		.irq		= 74,
-	}
+	},
+	{ },
 };
 
 static struct platform_device m5249_uart = {
@@ -50,12 +51,12 @@ static struct platform_device *m5249_dev
 static void __init m5249_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5272/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5272/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5272/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5272/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,8 +55,39 @@ static struct platform_device m5272_uart
 	.dev.platform_data	= m5272_uart_platform,
 };
 
+static struct resource m5272_fec_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x840,
+		.end		= MCF_MBAR + 0x840 + 0x1cf,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 86,
+		.end		= 86,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 87,
+		.end		= 87,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 88,
+		.end		= 88,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m5272_fec = {
+	.name			= "fec",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m5272_fec_resources),
+	.resource		= m5272_fec_resources,
+};
+
 static struct platform_device *m5272_devices[] __initdata = {
 	&m5272_uart,
+	&m5272_fec,
 };
 
 /***************************************************************************/
@@ -91,6 +122,22 @@ static void __init m5272_uarts_init(void
 
 /***************************************************************************/
 
+static void __init m5272_fec_init(void)
+{
+	u32 imr;
+
+	/* Unmask FEC interrupts at ColdFire interrupt controller */
+	imr = readl(MCF_MBAR + MCFSIM_ICR3);
+	imr = (imr & ~0x00000fff) | 0x00000ddd;
+	writel(imr, MCF_MBAR + MCFSIM_ICR3);
+
+	imr = readl(MCF_MBAR + MCFSIM_ICR1);
+	imr = (imr & ~0x0f000000) | 0x0d000000;
+	writel(imr, MCF_MBAR + MCFSIM_ICR1);
+}
+
+/***************************************************************************/
+
 void mcf_disableall(void)
 {
 	volatile unsigned long	*icrp;
@@ -155,6 +202,7 @@ void __init config_BSP(char *commandp, i
 static int __init init_BSP(void)
 {
 	m5272_uarts_init();
+	m5272_fec_init();
 	platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/527x/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/527x/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/527x/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/527x/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,8 +50,73 @@ static struct platform_device m527x_uart
 	.dev.platform_data	= m527x_uart_platform,
 };
 
+static struct resource m527x_fec0_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x1000,
+		.end		= MCF_MBAR + 0x1000 + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 64 + 23,
+		.end		= 64 + 23,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 27,
+		.end		= 64 + 27,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 29,
+		.end		= 64 + 29,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource m527x_fec1_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x1800,
+		.end		= MCF_MBAR + 0x1800 + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 128 + 23,
+		.end		= 128 + 23,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 128 + 27,
+		.end		= 128 + 27,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 128 + 29,
+		.end		= 128 + 29,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m527x_fec[] = {
+	{
+		.name		= "fec",
+		.id		= 0,
+		.num_resources	= ARRAY_SIZE(m527x_fec0_resources),
+		.resource	= m527x_fec0_resources,
+	},
+	{
+		.name		= "fec",
+		.id		= 1,
+		.num_resources	= ARRAY_SIZE(m527x_fec1_resources),
+		.resource	= m527x_fec1_resources,
+	},
+};
+
 static struct platform_device *m527x_devices[] __initdata = {
 	&m527x_uart,
+	&m527x_fec[0],
+#ifdef CONFIG_FEC2
+	&m527x_fec[1],
+#endif
 };
 
 /***************************************************************************/
@@ -97,6 +162,56 @@ static void __init m527x_uarts_init(void
 
 /***************************************************************************/
 
+static void __init m527x_fec_irq_init(int nr)
+{
+	unsigned long base;
+	u32 imr;
+
+	base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
+
+	writeb(0x28, base + MCFINTC_ICR0 + 23);
+	writeb(0x27, base + MCFINTC_ICR0 + 27);
+	writeb(0x26, base + MCFINTC_ICR0 + 29);
+
+	imr = readl(base + MCFINTC_IMRH);
+	imr &= ~0xf;
+	writel(imr, base + MCFINTC_IMRH);
+	imr = readl(base + MCFINTC_IMRL);
+	imr &= ~0xff800001;
+	writel(imr, base + MCFINTC_IMRL);
+}
+
+static void __init m527x_fec_init(void)
+{
+	u16 par;
+	u8 v;
+
+	m527x_fec_irq_init(0);
+
+	/* Set multi-function pins to ethernet mode for fec0 */
+#if defined(CONFIG_M5271)
+	v = readb(MCF_IPSBAR + 0x100047);
+	writeb(v | 0xf0, MCF_IPSBAR + 0x100047);
+#else
+	par = readw(MCF_IPSBAR + 0x100082);
+	writew(par | 0xf00, MCF_IPSBAR + 0x100082);
+	v = readb(MCF_IPSBAR + 0x100078);
+	writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
+#endif
+
+#ifdef CONFIG_FEC2
+	m527x_fec_irq_init(1);
+
+	/* Set multi-function pins to ethernet mode for fec1 */
+	par = readw(MCF_IPSBAR + 0x100082);
+	writew(par | 0xa0, MCF_IPSBAR + 0x100082);
+	v = readb(MCF_IPSBAR + 0x100079);
+	writeb(v | 0xc0, MCF_IPSBAR + 0x100079);
+#endif
+}
+
+/***************************************************************************/
+
 void mcf_disableall(void)
 {
 	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -116,13 +231,14 @@ void __init config_BSP(char *commandp, i
 {
 	mcf_disableall();
 	mach_reset = coldfire_reset;
+	m527x_uarts_init();
+	m527x_fec_init();
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-	m527x_uarts_init();
 	platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/528x/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/528x/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/528x/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/528x/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,8 +57,40 @@ static struct platform_device m528x_uart
 	.dev.platform_data	= m528x_uart_platform,
 };
 
+static struct resource m528x_fec_resources[] = {
+	{
+		.start		= MCF_MBAR + 0x1000,
+		.end		= MCF_MBAR + 0x1000 + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 64 + 23,
+		.end		= 64 + 23,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 27,
+		.end		= 64 + 27,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 29,
+		.end		= 64 + 29,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m528x_fec = {
+	.name			= "fec",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m528x_fec_resources),
+	.resource		= m528x_fec_resources,
+};
+
+
 static struct platform_device *m528x_devices[] __initdata = {
 	&m528x_uart,
+	&m528x_fec,
 };
 
 /***************************************************************************/
@@ -99,6 +131,31 @@ static void __init m528x_uarts_init(void
 
 /***************************************************************************/
 
+static void __init m528x_fec_init(void)
+{
+	u32 imr;
+	u16 v16;
+
+	/* Unmask FEC interrupts at ColdFire interrupt controller */
+	writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
+	writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
+	writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
+
+	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	imr &= ~0xf;
+	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+	imr &= ~0xff800001;
+	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+
+	/* Set multi-function pins to ethernet mode for fec0 */
+	v16 = readw(MCF_IPSBAR + 0x100056);
+	writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
+	writeb(0xc0, MCF_IPSBAR + 0x100058);
+}
+
+/***************************************************************************/
+
 void mcf_disableall(void)
 {
 	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -158,6 +215,7 @@ void __init config_BSP(char *commandp, i
 static int __init init_BSP(void)
 {
 	m528x_uarts_init();
+	m528x_fec_init();
 	platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5307/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5307/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5307/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5307/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,12 +65,12 @@ static struct platform_device *m5307_dev
 static void __init m5307_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/532x/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/532x/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/532x/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/532x/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,8 +61,38 @@ static struct platform_device m532x_uart
 	.dev.platform_data	= m532x_uart_platform,
 };
 
+static struct resource m532x_fec_resources[] = {
+	{
+		.start		= 0xfc030000,
+		.end		= 0xfc0307ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 64 + 36,
+		.end		= 64 + 36,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 40,
+		.end		= 64 + 40,
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= 64 + 42,
+		.end		= 64 + 42,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m532x_fec = {
+	.name			= "fec",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m532x_fec_resources),
+	.resource		= m532x_fec_resources,
+};
 static struct platform_device *m532x_devices[] __initdata = {
 	&m532x_uart,
+	&m532x_fec,
 };
 
 /***************************************************************************/
@@ -93,6 +123,24 @@ static void __init m532x_uarts_init(void
 	for (line = 0; (line < nrlines); line++)
 		m532x_uart_init_line(line, m532x_uart_platform[line].irq);
 }
+/***************************************************************************/
+
+static void __init m532x_fec_init(void)
+{
+	/* Unmask FEC interrupts at ColdFire interrupt controller */
+	MCF_INTC0_ICR36 = 0x2;
+	MCF_INTC0_ICR40 = 0x2;
+	MCF_INTC0_ICR42 = 0x2;
+
+	MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
+		MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
+
+	/* Set multi-function pins to ethernet mode for fec0 */
+	MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
+		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
+	MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
+		MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
+}
 
 /***************************************************************************/
 
@@ -150,6 +198,7 @@ void __init config_BSP(char *commandp, i
 static int __init init_BSP(void)
 {
 	m532x_uarts_init();
+	m532x_fec_init();
 	platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5407/config.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5407/config.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/5407/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/5407/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,12 +56,12 @@ static struct platform_device *m5407_dev
 static void __init m5407_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/68328/timers.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/68328/timers.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/68328/timers.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/68328/timers.c	2009-06-09 23:05:27.000000000 -0400
@@ -75,7 +75,7 @@ static struct irqaction m68328_timer_irq
 
 /***************************************************************************/
 
-static cycle_t m68328_read_clk(void)
+static cycle_t m68328_read_clk(struct clocksource *cs)
 {
 	unsigned long flags;
 	u32 cycles;
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/clk.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/clk.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/clk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/clk.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,40 @@
+/***************************************************************************/
+
+/*
+ *	clk.c -- general ColdFire CPU kernel clk handling
+ *
+ *	Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/coldfire.h>
+
+/***************************************************************************/
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	return NULL;
+}
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return MCF_CLK;
+}
+
+/***************************************************************************/
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/dma_timer.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/dma_timer.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/dma_timer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/dma_timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@
 #define DMA_DTMR_CLK_DIV_16	(2 << 1)
 #define DMA_DTMR_ENABLE		(1 << 0)
 
-static cycle_t cf_dt_get_cycles(void)
+static cycle_t cf_dt_get_cycles(struct clocksource *cs)
 {
 	return __raw_readl(DTCN0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/Makefile linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/Makefile
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,7 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-$(CONFIG_COLDFIRE)	+= dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE)	+= clk.o dma.o entry.o vectors.o
 obj-$(CONFIG_M5206)	+= timers.o
 obj-$(CONFIG_M5206e)	+= timers.o
 obj-$(CONFIG_M520x)	+= pit.o
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/pit.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/pit.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/pit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/pit.c	2009-06-09 23:05:27.000000000 -0400
@@ -125,7 +125,7 @@ static struct irqaction pit_irq = {
 
 /***************************************************************************/
 
-static cycle_t pit_read_clk(void)
+static cycle_t pit_read_clk(struct clocksource *cs)
 {
 	unsigned long flags;
 	u32 cycles;
diff -druNp linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/timers.c linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/timers.c
--- linux-libre-2.6.29-gnu1/arch/m68knommu/platform/coldfire/timers.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/m68knommu/platform/coldfire/timers.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,7 +78,7 @@ static struct irqaction mcftmr_timer_irq
 
 /***************************************************************************/
 
-static cycle_t mcftmr_read_clk(void)
+static cycle_t mcftmr_read_clk(struct clocksource *cs)
 {
 	unsigned long flags;
 	u32 cycles;
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/boot/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/boot/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+#
+# arch/microblaze/boot/Makefile
+#
+
+targets := linux.bin linux.bin.gz
+
+OBJCOPYFLAGS_linux.bin  := -O binary
+
+$(obj)/linux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
+	$(call if_changed,gzip)
+	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+clean-kernel += linux.bin linux.bin.gz
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/configs/nommu_defconfig linux-libre-2.6.30-gnu1/arch/microblaze/configs/nommu_defconfig
--- linux-libre-2.6.29-gnu1/arch/microblaze/configs/nommu_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/configs/nommu_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,818 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc5
+# Mon May 11 09:01:02 2009
+#
+CONFIG_MICROBLAZE=y
+# CONFIG_SWAP 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_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_GENERIC_TIME_VSYSCALL is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_PCI is not set
+# CONFIG_NO_DMA is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=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_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=17
+# 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=y
+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=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_HOTPLUG is not set
+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_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_MARKERS 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_BASE_SMALL=1
+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_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=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
+
+#
+# Platform options
+#
+CONFIG_PLATFORM_GENERIC=y
+# CONFIG_SELFMOD is not set
+# CONFIG_OPT_LIB_FUNCTION is not set
+# CONFIG_ALLOW_EDIT_AUTO is not set
+CONFIG_KERNEL_BASE_ADDR=0x90000000
+CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5"
+CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1
+CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
+CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
+CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2
+CONFIG_XILINX_MICROBLAZE0_USE_FPU=2
+CONFIG_XILINX_MICROBLAZE0_HW_VER="7.10.d"
+
+#
+# Processor type and features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_MMU is not set
+CONFIG_NO_MMU=y
+
+#
+# Boot options
+#
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyUL0,115200"
+# CONFIG_CMDLINE_FORCE is not set
+CONFIG_OF=y
+CONFIG_OF_DEVICE=y
+CONFIG_PROC_DEVICETREE=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_UNEVICTABLE_LRU=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+
+#
+# Exectuable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT 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 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 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_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=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
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD 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_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_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=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
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_UCLINUX=y
+# 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_NBD=y
+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_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# 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_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_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_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# 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
+
+#
+# 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_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=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC 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 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
+
+#
+# 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
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# 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
+
+#
+# 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 is not set
+# 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
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR 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_OCFS2_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
+
+#
+# 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_SYSFS=y
+# CONFIG_TMPFS 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 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=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
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# 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_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_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+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=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+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_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_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+# 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_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_HEART_BEAT=y
+# CONFIG_DEBUG_BOOTMEM 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=y
+# 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/atomic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_ATOMIC_H
+#define _ASM_MICROBLAZE_ATOMIC_H
+
+#include <linux/types.h>
+#include <linux/compiler.h> /* likely */
+#include <asm/system.h> /* local_irq_XXX and friends */
+
+#define ATOMIC_INIT(i)		{ (i) }
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = (i))
+
+#define atomic_inc(v)		(atomic_add_return(1, (v)))
+#define atomic_dec(v)		(atomic_sub_return(1, (v)))
+
+#define atomic_add(i, v)	(atomic_add_return(i, (v)))
+#define atomic_sub(i, v)	(atomic_sub_return(i, (v)))
+
+#define atomic_inc_return(v)	(atomic_add_return(1, (v)))
+#define atomic_dec_return(v)	(atomic_sub_return(1, (v)))
+
+#define atomic_inc_and_test(v)	(atomic_add_return(1, (v)) == 0)
+#define atomic_dec_and_test(v)	(atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc_not_zero(v)	(atomic_add_unless((v), 1, 0))
+
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+
+	c = atomic_read(v);
+	while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+		c = old;
+	return c != u;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*addr &= ~mask;
+	local_irq_restore(flags);
+}
+
+/**
+ * atomic_add_return - add and return
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long flags;
+	int val;
+
+	local_irq_save(flags);
+	val = v->counter;
+	v->counter = val += i;
+	local_irq_restore(flags);
+
+	return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	return atomic_add_return(-i, v);
+}
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+	unsigned long flags;
+	int res;
+
+	local_irq_save(flags);
+	res = v->counter - 1;
+	if (res >= 0)
+		v->counter = res;
+	local_irq_restore(flags);
+
+	return res;
+}
+
+#define atomic_add_negative(a, v)	(atomic_add_return((a), (v)) < 0)
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+/* Atomic operations are already serializing */
+#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()
+
+#include <asm-generic/atomic.h>
+
+#endif /* _ASM_MICROBLAZE_ATOMIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/auxvec.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/auxvec.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/auxvec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/auxvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_BITOPS_H
+#define _ASM_MICROBLAZE_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+#include <asm-generic/bitops.h>
+#include <asm-generic/bitops/__fls.h>
+
+#endif /* _ASM_MICROBLAZE_BITOPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bug.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bug.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_BUG_H
+#define _ASM_MICROBLAZE_BUG_H
+
+#include <linux/kernel.h>
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_MICROBLAZE_BUG_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bugs.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bugs.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/bugs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/bugs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_BUGS_H
+#define _ASM_MICROBLAZE_BUGS_H
+
+static inline void check_bugs(void)
+{
+	/* nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_BUGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/byteorder.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/byteorder.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/byteorder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/byteorder.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_BYTEORDER_H
+#define _ASM_MICROBLAZE_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cacheflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 PetaLogix
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * based on v850 version which was
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * 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 _ASM_MICROBLAZE_CACHEFLUSH_H
+#define _ASM_MICROBLAZE_CACHEFLUSH_H
+
+/* Somebody depends on this; sigh... */
+#include <linux/mm.h>
+
+/*
+ * Cache handling functions.
+ * Microblaze has a write-through data cache, meaning that the data cache
+ * never needs to be flushed.  The only flushing operations that are
+ * implemented are to invalidate the instruction cache.  These are called
+ * after loading a user application into memory, we must invalidate the
+ * 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)
+
+#define flush_cache_vmap(start, end)		do { } while (0)
+#define flush_cache_vunmap(start, end)		do { } while (0)
+
+struct page;
+struct mm_struct;
+struct vm_area_struct;
+
+/* 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);
+
+extern inline void __invalidate_cache_all(void)
+{
+	__invalidate_icache_all();
+	__invalidate_dcache_all();
+}
+
+#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))
+
+#endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Cache operations
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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 _ASM_MICROBLAZE_CACHE_H
+#define _ASM_MICROBLAZE_CACHE_H
+
+#include <asm/registers.h>
+
+#define L1_CACHE_SHIFT	2
+/* word-granular cache in microblaze */
+#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
+
+#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.29-gnu1/arch/microblaze/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/checksum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_CHECKSUM_H
+#define _ASM_MICROBLAZE_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * 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,
+		   unsigned short proto, __wsum sum)
+{
+	__asm__("add %0, %0, %1\n\t"
+		"addc %0, %0, %2\n\t"
+		"addc %0, %0, %3\n\t"
+		"addc %0, %0, r0\n\t"
+		: "+&d" (sum)
+		: "d" (saddr), "d" (daddr), "d" (len + proto));
+
+	return sum;
+}
+
+/*
+ * 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
+ */
+extern __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
+ */
+extern __wsum csum_partial_copy(const char *src, char *dst, int len, int 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 char *src, char *dst,
+					int len, int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum)	\
+	csum_partial_copy((src), (dst), (len), (sum))
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ */
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/*
+ *	Fold a partial checksum
+ */
+static inline __sum16 csum_fold(unsigned int sum)
+{
+	sum = (sum & 0xffff) + (sum >> 16);
+	sum = (sum & 0xffff) + (sum >> 16);
+	return ~sum;
+}
+
+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 unsigned char *buff, int len);
+
+#endif /* _ASM_MICROBLAZE_CHECKSUM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/clinkage.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/clinkage.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/clinkage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/clinkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <linux/linkage.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cpuinfo.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cpuinfo.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cpuinfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cpuinfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,102 @@
+/*
+ * Generic support for queying CPU info
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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 _ASM_MICROBLAZE_CPUINFO_H
+#define _ASM_MICROBLAZE_CPUINFO_H
+
+#include <asm/prom.h>
+
+/* CPU Version and FPGA Family code conversion table type */
+struct cpu_ver_key {
+	const char *s;
+	const unsigned k;
+};
+
+extern const struct cpu_ver_key cpu_ver_lookup[];
+
+struct family_string_key {
+	const char *s;
+	const unsigned k;
+};
+
+extern const struct family_string_key family_string_lookup[];
+
+struct cpuinfo {
+	/* Core CPU configuration */
+	u32 use_instr;
+	u32 use_mult;
+	u32 use_fpu;
+	u32 use_exc;
+	u32 ver_code;
+	u32 mmu;
+
+	/* CPU caches */
+	u32 use_icache;
+	u32 icache_tagbits;
+	u32 icache_write;
+	u32 icache_line;
+	u32 icache_size;
+	unsigned long icache_base;
+	unsigned long icache_high;
+
+	u32 use_dcache;
+	u32 dcache_tagbits;
+	u32 dcache_write;
+	u32 dcache_line;
+	u32 dcache_size;
+	unsigned long dcache_base;
+	unsigned long dcache_high;
+
+	/* Bus connections */
+	u32 use_dopb;
+	u32 use_iopb;
+	u32 use_dlmb;
+	u32 use_ilmb;
+	u32 num_fsl;
+
+	/* CPU interrupt line info */
+	u32 irq_edge;
+	u32 irq_positive;
+
+	u32 area_optimised;
+
+	/* HW debug support */
+	u32 hw_debug;
+	u32 num_pc_brk;
+	u32 num_rd_brk;
+	u32 num_wr_brk;
+	u32 cpu_clock_freq; /* store real freq of cpu */
+	u32 freq_div_hz; /* store freq/HZ */
+
+	/* FPGA family */
+	u32 fpga_family_code;
+
+	/* User define */
+	u32 pvr_user1;
+	u32 pvr_user2;
+};
+
+extern struct cpuinfo cpuinfo;
+
+/* fwd declarations of the various CPUinfo populators */
+void setup_cpuinfo(void);
+
+void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
+
+static inline unsigned int fcpu(struct device_node *cpu, char *n)
+{
+	int *val;
+	return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
+}
+
+#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cputable.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cputable.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cputable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cputable.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cputime.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cputime.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/cputime.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/cputime.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/current.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/current.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_CURRENT_H
+#define _ASM_MICROBLAZE_CURRENT_H
+
+# ifndef __ASSEMBLY__
+/*
+ * Dedicate r31 to keeping the current task pointer
+ */
+register struct task_struct *current asm("r31");
+
+# define get_current()	current
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/delay.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/delay.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/delay.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/delay.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * include/asm-microblaze/delay.h
+ *
+ * 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) 2008 Michal Simek
+ * Copyright (C) 2007 John Williams
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ */
+
+#ifndef _ASM_MICROBLAZE_DELAY_H
+#define _ASM_MICROBLAZE_DELAY_H
+
+extern inline void __delay(unsigned long loops)
+{
+	asm volatile ("# __delay		\n\t"		\
+			"1: addi	%0, %0, -1\t\n"		\
+			"bneid	%0, 1b		\t\n"		\
+			"nop			\t\n"
+			: "=r" (loops)
+			: "0" (loops));
+}
+
+/*
+ * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so
+ * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32.
+ *
+ * The mul instruction gives us loops = (a * b) / 2^32.
+ * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226
+ * because this lets us support a wide range of HZ and
+ * loops_per_jiffy values without either a or b overflowing 2^32.
+ * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and
+ * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280
+ * (which corresponds to ~3800 bogomips at HZ = 100).
+ * -- paulus
+ */
+#define __MAX_UDELAY	(226050910UL/HZ)	/* maximum udelay argument */
+#define __MAX_NDELAY	(4294967295UL/HZ)	/* maximum ndelay argument */
+
+extern unsigned long loops_per_jiffy;
+
+extern inline void __udelay(unsigned int x)
+{
+
+	unsigned long long tmp =
+		(unsigned long long)x * (unsigned long long)loops_per_jiffy \
+			* 226LL;
+	unsigned loops = tmp >> 32;
+
+/*
+	__asm__("mulxuu %0,%1,%2" : "=r" (loops) :
+		"r" (x), "r" (loops_per_jiffy * 226));
+*/
+	__delay(loops);
+}
+
+extern void __bad_udelay(void);		/* deliberately undefined */
+extern void __bad_ndelay(void);		/* deliberately undefined */
+
+#define udelay(n) (__builtin_constant_p(n) ? \
+	((n) > __MAX_UDELAY ? __bad_udelay() : __udelay((n) * (19 * HZ))) : \
+	__udelay((n) * (19 * HZ)))
+
+#define ndelay(n) (__builtin_constant_p(n) ? \
+	((n) > __MAX_NDELAY ? __bad_ndelay() : __udelay((n) * HZ)) : \
+	__udelay((n) * HZ))
+
+#define muldiv(a, b, c)		(((a)*(b))/(c))
+
+#endif /* _ASM_MICROBLAZE_DELAY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/device.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/device.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License v2. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_DEVICE_H
+#define _ASM_MICROBLAZE_DEVICE_H
+
+struct device_node;
+
+struct dev_archdata {
+	/* Optional pointer to an OF device node */
+	struct device_node	*of_node;
+};
+
+#endif /* _ASM_MICROBLAZE_DEVICE_H */
+
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/div64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_DMA_H
+#define _ASM_MICROBLAZE_DMA_H
+
+/* we don't have dma address limit. define it as zero to be
+ * unlimited. */
+#define MAX_DMA_ADDRESS		(0)
+
+#endif /* _ASM_MICROBLAZE_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/dma-mapping.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_DMA_MAPPING_H
+#define _ASM_MICROBLAZE_DMA_MAPPING_H
+
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+struct scatterlist;
+
+#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)
+
+/* FIXME */
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+	unsigned long offset, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG();
+	return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	enum dma_data_direction direction)
+{
+	BUG();
+	return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+		size_t size, enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		enum dma_data_direction direction)
+{
+	BUG();
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, int flag)
+{
+	return NULL; /* consistent_alloc(flag, size, dma_handle); */
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+			void *vaddr, dma_addr_t dma_handle)
+{
+	BUG();
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	return virt_to_bus(ptr);
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+				    size_t size,
+				    enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_FROM_DEVICE:
+		flush_dcache_range((unsigned)dma_addr,
+			(unsigned)dma_addr + size);
+			/* Fall through */
+	case DMA_TO_DEVICE:
+		break;
+	default:
+		BUG();
+	}
+}
+
+#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/elf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_ELF_H
+#define _ASM_MICROBLAZE_ELF_H
+
+/*
+ * Note there is no "official" ELF designation for Microblaze.
+ * I've snaffled the value from the microblaze binutils source code
+ * /binutils/microblaze/include/elf/microblaze.h
+ */
+#define EM_XILINX_MICROBLAZE	0xbaab
+#define ELF_ARCH		EM_XILINX_MICROBLAZE
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)	((x)->e_machine == EM_XILINX_MICROBLAZE)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+
+#endif /* _ASM_MICROBLAZE_ELF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/emergency-restart.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/emergency-restart.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/emergency-restart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/emergency-restart.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/entry.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/entry.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/entry.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/entry.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * Definitions used by low-level trap handlers
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2007 - 2008 PetaLogix
+ * Copyright (C) 2007 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
+ * archive for more details.
+ */
+
+#ifndef _ASM_MICROBLAZE_ENTRY_H
+#define _ASM_MICROBLAZE_ENTRY_H
+
+#include <asm/percpu.h>
+#include <asm/ptrace.h>
+
+/*
+ * These are per-cpu variables required in entry.S, among other
+ * places
+ */
+
+#define PER_CPU(var) per_cpu__##var
+
+# ifndef __ASSEMBLY__
+DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */
+DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */
+DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */
+DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
+DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
+# endif /* __ASSEMBLY__ */
+
+/* noMMU hasn't any space for args */
+# define STATE_SAVE_ARG_SPACE	(0)
+
+#endif /* _ASM_MICROBLAZE_ENTRY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/errno.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/errno.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/errno.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/errno.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/exceptions.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/exceptions.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/exceptions.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/exceptions.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,99 @@
+/*
+ * Preliminary support for HW exception handing for Microblaze
+ *
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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 _ASM_MICROBLAZE_EXCEPTIONS_H
+#define _ASM_MICROBLAZE_EXCEPTIONS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/* Macros to enable and disable HW exceptions in the MSR */
+/* Define MSR enable bit for HW exceptions */
+#define HWEX_MSR_BIT (1 << 8)
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+#define __enable_hw_exceptions()					\
+	__asm__ __volatile__ ("	msrset	r0, %0;				\
+				nop;"					\
+				:					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory")
+
+#define __disable_hw_exceptions()					\
+	__asm__ __volatile__ ("	msrclr r0, %0;				\
+				nop;"					\
+				:					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory")
+#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+#define __enable_hw_exceptions()					\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				nop;					\
+				ori	r12, r12, %0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				:					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory", "r12")
+
+#define __disable_hw_exceptions()					\
+	__asm__ __volatile__ ("						\
+				mfs	r12, rmsr;			\
+				nop;					\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop;"					\
+				:					\
+				: "i" (HWEX_MSR_BIT)			\
+				: "memory", "r12")
+#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+							int fsr, int addr);
+
+void die(const char *str, struct pt_regs *fp, long err);
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
+
+#if defined(CONFIG_XMON)
+extern void xmon(struct pt_regs *regs);
+extern int xmon_bpt(struct pt_regs *regs);
+extern int xmon_sstep(struct pt_regs *regs);
+extern int xmon_iabr_match(struct pt_regs *regs);
+extern int xmon_dabr_match(struct pt_regs *regs);
+extern void (*xmon_fault_handler)(struct pt_regs *regs);
+
+void (*debugger)(struct pt_regs *regs) = xmon;
+int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
+int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep;
+int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match;
+int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#elif defined(CONFIG_KGDB)
+void (*debugger)(struct pt_regs *regs);
+int (*debugger_bpt)(struct pt_regs *regs);
+int (*debugger_sstep)(struct pt_regs *regs);
+int (*debugger_iabr_match)(struct pt_regs *regs);
+int (*debugger_dabr_match)(struct pt_regs *regs);
+void (*debugger_fault_handler)(struct pt_regs *regs);
+#else
+#define debugger(regs)			do { } while (0)
+#define debugger_bpt(regs)		0
+#define debugger_sstep(regs)		0
+#define debugger_iabr_match(regs)	0
+#define debugger_dabr_match(regs)	0
+#define debugger_fault_handler		((void (*)(struct pt_regs *))0)
+#endif
+
+#endif /*__ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_EXCEPTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/fcntl.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/fcntl.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/fcntl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/fcntl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/flat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ * uClinux flat-format executables
+ *
+ * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au>
+ *
+ * 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 _ASM_MICROBLAZE_FLAT_H
+#define _ASM_MICROBLAZE_FLAT_H
+
+#include <asm/unaligned.h>
+
+#define	flat_stack_align(sp) /* nothing needed */
+#define	flat_argvp_envp_on_stack()	0
+#define	flat_old_ram_flag(flags)	(flags)
+#define	flat_reloc_valid(reloc, size)	((reloc) <= (size))
+#define	flat_set_persistent(relval, p)		0
+
+/*
+ * Microblaze works a little differently from other arches, because
+ * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
+ * over two instructions, an 'imm' instruction which provides the top
+ * 16 bits, then the instruction "proper" which provides the low 16
+ * bits.
+ */
+
+/*
+ * Crack open a symbol reference and extract the address to be
+ * relocated. rp is a potentially unaligned pointer to the
+ * reference
+ */
+
+static inline unsigned long
+flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
+			unsigned long flags, unsigned long *persistent)
+{
+	unsigned long addr;
+	(void)flags;
+
+	/* Is it a split 64/32 reference? */
+	if (relval & 0x80000000) {
+		/* Grab the two halves of the reference */
+		unsigned long val_hi, val_lo;
+
+		val_hi = get_unaligned(rp);
+		val_lo = get_unaligned(rp+1);
+
+		/* Crack the address out */
+		addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
+	} else {
+		/* Get the address straight out */
+		addr = get_unaligned(rp);
+	}
+
+	return addr;
+}
+
+/*
+ * Insert an address into the symbol reference at rp. rp is potentially
+ * unaligned.
+ */
+
+static inline void
+flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
+{
+	/* Is this a split 64/32 reloc? */
+	if (relval & 0x80000000) {
+		/* Get the two "halves" */
+		unsigned long val_hi = get_unaligned(rp);
+		unsigned long val_lo = get_unaligned(rp + 1);
+
+		/* insert the address */
+		val_hi = (val_hi & 0xffff0000) | addr >> 16;
+		val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
+
+		/* store the two halves back into memory */
+		put_unaligned(val_hi, rp);
+		put_unaligned(val_lo, rp+1);
+	} else {
+		/* Put it straight in, no messing around */
+		put_unaligned(addr, rp);
+	}
+}
+
+#define	flat_get_relocate_addr(rel)	(rel & 0x7fffffff)
+
+#endif /* _ASM_MICROBLAZE_FLAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/futex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/gpio.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/gpio.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for PowerPC.
+ *
+ * Copyright (c) 2007-2008  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.
+ */
+
+#ifndef __ASM_POWERPC_GPIO_H
+#define __ASM_POWERPC_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * We don't (yet) implement inlined/rapid versions for on-chip gpios.
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_POWERPC_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/hardirq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_HARDIRQ_H
+#define _ASM_MICROBLAZE_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/current.h>
+#include <linux/ptrace.h>
+
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(struct pt_regs *regs);
+
+typedef struct {
+	unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+void ack_bad_irq(unsigned int irq);
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/hw_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ioctl.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ioctl.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ioctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ioctls.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ioctls.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ioctls.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ioctls.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_IOCTLS_H
+#define _ASM_MICROBLAZE_IOCTLS_H
+
+#include <linux/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426 /* For debugging only */
+#define TIOCSBRK	0x5427 /* BSD compatibility */
+#define TIOCCBRK	0x5428 /* BSD compatibility */
+#define TIOCGSID	0x5429 /* Return the session ID of FD */
+/* Get Pty Number (of pty-mux device) */
+#define TIOCGPTN	_IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK	_IOW('T', 0x31, int) /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450 /* these numbers need to be adjusted. */
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR	0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D /* read serial port inline interrupt counts */
+
+#define	FIOQSIZE	0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		0
+#define TIOCPKT_FLUSHREAD	1
+#define TIOCPKT_FLUSHWRITE	2
+#define TIOCPKT_STOP		4
+#define TIOCPKT_START		8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT	0x01 /* Transmitter physically empty */
+
+#endif /* _ASM_MICROBLAZE_IOCTLS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/io.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_IO_H
+#define _ASM_MICROBLAZE_IO_H
+
+#include <asm/byteorder.h>
+#include <asm/page.h>
+#include <linux/types.h>
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned short __force *)addr;
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned int __force *)addr;
+}
+static inline unsigned long __raw_readq(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned long __force *)addr;
+}
+static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+{
+	*(volatile unsigned char __force *)addr = v;
+}
+static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
+{
+	*(volatile unsigned short __force *)addr = v;
+}
+static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
+{
+	*(volatile unsigned int __force *)addr = v;
+}
+static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
+{
+	*(volatile unsigned long __force *)addr = v;
+}
+
+/*
+ * read (readb, readw, readl, readq) and write (writeb, writew,
+ * writel, writeq) accessors are for PCI and thus littel endian.
+ * Linux 2.4 for Microblaze had this wrong.
+ */
+static inline unsigned char readb(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned char __force *)addr;
+}
+static inline unsigned short readw(const volatile void __iomem *addr)
+{
+	return le16_to_cpu(*(volatile unsigned short __force *)addr);
+}
+static inline unsigned int readl(const volatile void __iomem *addr)
+{
+	return le32_to_cpu(*(volatile unsigned int __force *)addr);
+}
+static inline void writeb(unsigned char v, volatile void __iomem *addr)
+{
+	*(volatile unsigned char __force *)addr = v;
+}
+static inline void writew(unsigned short v, volatile void __iomem *addr)
+{
+	*(volatile unsigned short __force *)addr = cpu_to_le16(v);
+}
+static inline void writel(unsigned int v, volatile void __iomem *addr)
+{
+	*(volatile unsigned int __force *)addr = cpu_to_le32(v);
+}
+
+/* ioread and iowrite variants. thease are for now same as __raw_
+ * variants of accessors. we might check for endianess in the feature
+ */
+#define ioread8(addr)		__raw_readb((u8 *)(addr))
+#define ioread16(addr)		__raw_readw((u16 *)(addr))
+#define ioread32(addr)		__raw_readl((u32 *)(addr))
+#define iowrite8(v, addr)	__raw_writeb((u8)(v), (u8 *)(addr))
+#define iowrite16(v, addr)	__raw_writew((u16)(v), (u16 *)(addr))
+#define iowrite32(v, addr)	__raw_writel((u32)(v), (u32 *)(addr))
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+#define inb(port)		readb((u8 *)((port)))
+#define outb(val, port)		writeb((val), (u8 *)((unsigned long)(port)))
+#define inw(port)		readw((u16 *)((port)))
+#define outw(val, port)		writew((val), (u16 *)((unsigned long)(port)))
+#define inl(port)		readl((u32 *)((port)))
+#define outl(val, port)		writel((val), (u32 *)((unsigned long)(port)))
+
+#define inb_p(port)		inb((port))
+#define outb_p(val, port)	outb((val), (port))
+#define inw_p(port)		inw((port))
+#define outw_p(val, port)	outw((val), (port))
+#define inl_p(port)		inl((port))
+#define outl_p(val, port)	outl((val), (port))
+
+#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))
+
+/**
+ *	virt_to_phys - map virtual addresses to physical
+ *	@address: address to remap
+ *
+ *	The returned physical address is the physical (CPU) mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses directly mapped or allocated via kmalloc.
+ *
+ *	This function does not give bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+static inline unsigned long __iomem virt_to_phys(volatile void *address)
+{
+	return __pa((unsigned long)address);
+}
+
+#define virt_to_bus virt_to_phys
+
+/**
+ *	phys_to_virt - map physical address to virtual
+ *	@address: address to remap
+ *
+ *	The returned virtual address is a current CPU mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses that have a kernel mapping
+ *
+ *	This function does not handle bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+static inline void *phys_to_virt(unsigned long address)
+{
+	return (void *)__va(address);
+}
+
+#define bus_to_virt(a) phys_to_virt(a)
+
+static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
+			unsigned long flags)
+{
+	return (void *)address;
+}
+
+#define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
+#define iounmap(addr)		((void)0)
+#define ioremap_nocache(physaddr, size)	ioremap(physaddr, size)
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+/*
+ * Big Endian
+ */
+#define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a))
+#define out_be16(a, v) __raw_writew((v), (a))
+
+#define in_be32(a) __raw_readl((const void __iomem __force *)(a))
+#define in_be16(a) __raw_readw(a)
+
+/*
+ * Little endian
+ */
+
+#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))
+#define in_le16(a) __le16_to_cpu(__raw_readw(a))
+
+/* Byte ops */
+#define out_8(a, v) __raw_writeb((v), (a))
+#define in_8(a) __raw_readb(a)
+
+/* FIXME */
+static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+	return (void __iomem *) (port);
+}
+
+static inline void ioport_unmap(void __iomem *addr)
+{
+	/* Nothing to do */
+}
+
+#endif /* _ASM_MICROBLAZE_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ipcbuf.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ipcbuf.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ipcbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ipcbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_IPCBUF_H
+#define _ASM_MICROBLAZE_IPCBUF_H
+
+/*
+ * The user_ipc_perm structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm {
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* _ASM_MICROBLAZE_IPCBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ipc.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ipc.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ipc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ipc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irqflags.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irqflags.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irqflags.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irqflags.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_IRQFLAGS_H
+#define _ASM_MICROBLAZE_IRQFLAGS_H
+
+#include <linux/irqflags.h>
+
+# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+
+# define local_irq_save(flags)				\
+	do {						\
+		asm volatile ("# local_irq_save	\n\t"	\
+				"msrclr %0, %1	\n\t"	\
+				"nop	\n\t"		\
+				: "=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");			\
+	} 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");			\
+	} while (0)
+
+# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
+
+# define 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"			\
+				: "=r"(flags), "=r" (tmp)	\
+				: "i"(~MSR_IE)			\
+				: "memory");			\
+	} while (0)
+
+# define 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"			\
+				: "=r"(tmp)			\
+				: "i"(~MSR_IE)			\
+				: "memory");			\
+	} while (0)
+
+# define 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"			\
+				: "=r"(tmp)			\
+				: "i"(MSR_IE)			\
+				: "memory");			\
+	} while (0)
+
+# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
+
+#define local_save_flags(flags)					\
+	do {							\
+		asm volatile ("# local_save_flags \n\t"		\
+				"mfs	%0, rmsr \n\t"		\
+				"nop	\n\t"			\
+				: "=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)
+{
+	unsigned long flags;
+
+	local_save_flags(flags);
+	return ((flags & MSR_IE) == 0);
+}
+
+#define raw_irqs_disabled irqs_disabled
+#define raw_irqs_disabled_flags(flags)	((flags) == 0)
+
+#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_IRQ_H
+#define _ASM_MICROBLAZE_IRQ_H
+
+#define NR_IRQS 32
+
+#include <linux/interrupt.h>
+
+extern unsigned int nr_irq;
+
+#define NO_IRQ (-1)
+
+static inline int irq_canonicalize(int irq)
+{
+	return irq;
+}
+
+struct pt_regs;
+extern void do_IRQ(struct pt_regs *regs);
+
+/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
+ * @device: Device node of the device whose interrupt is to be mapped
+ * @index: Index of the interrupt to map
+ *
+ * This function is a wrapper that chains of_irq_map_one() and
+ * irq_create_of_mapping() to make things easier to callers
+ */
+struct device_node;
+extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
+
+/** FIXME - not implement
+ * irq_dispose_mapping - Unmap an interrupt
+ * @virq: linux virq number of the interrupt to unmap
+ */
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+	return;
+}
+
+#endif /* _ASM_MICROBLAZE_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irq_regs.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irq_regs.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/irq_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/irq_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/Kbuild linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/Kbuild
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/Kbuild	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/Kbuild	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += linkage.h
+header-y += msgbuf.h
+header-y += poll.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += socket.h
+header-y += sockios.h
+header-y += statfs.h
+header-y += stat.h
+header-y += termbits.h
+header-y += ucontext.h
+
+unifdef-y += cputable.h
+unifdef-y += elf.h
+unifdef-y += termios.h
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/kdebug.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/kdebug.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/kdebug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/kdebug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/kmap_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_KMAP_TYPES_H
+#define _ASM_MICROBLAZE_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR,
+};
+
+#endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/linkage.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/linkage.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/linkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_LINKAGE_H
+#define _ASM_MICROBLAZE_LINKAGE_H
+
+#define __ALIGN		.align 4
+#define __ALIGN_STR	".align 4"
+
+#endif /* _ASM_MICROBLAZE_LINKAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/lmb.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/lmb.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/lmb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/lmb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * 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 _ASM_MICROBLAZE_LMB_H
+#define _ASM_MICROBLAZE_LMB_H
+
+/* LMB limit is OFF */
+#define LMB_REAL_LIMIT	0xFFFFFFFF
+
+#endif /* _ASM_MICROBLAZE_LMB_H */
+
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/local.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/local.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/local.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/local.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mman.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mman.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mman.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mman.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_MMAN_H
+#define _ASM_MICROBLAZE_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN	0x0100 /* stack-like segment */
+#define MAP_DENYWRITE	0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000 /* mark it as an executable */
+#define MAP_LOCKED	0x2000 /* pages are locked */
+#define MAP_NORESERVE	0x4000 /* don't check for reservations */
+#define MAP_POPULATE	0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000 /* do not block on IO */
+
+#define MCL_CURRENT	1 /* lock all current mappings */
+#define MCL_FUTURE	2 /* lock all future mappings */
+
+#endif /* _ASM_MICROBLAZE_MMAN_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mmu_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_MMU_CONTEXT_H
+#define _ASM_MICROBLAZE_MMU_CONTEXT_H
+
+# define init_new_context(tsk, mm)		({ 0; })
+
+# define enter_lazy_tlb(mm, tsk)		do {} while (0)
+# define change_mm_context(old, ctx, _pml4)	do {} while (0)
+# define destroy_context(mm)			do {} while (0)
+# define deactivate_mm(tsk, mm)			do {} while (0)
+# define switch_mm(prev, next, tsk)		do {} while (0)
+# define activate_mm(prev, next)		do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_MMU_H
+#define _ASM_MICROBLAZE_MMU_H
+
+#ifndef __ASSEMBLY__
+typedef struct {
+	struct vm_list_struct	*vmlist;
+	unsigned long		end_brk;
+} mm_context_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/module.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/module.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_MODULE_H
+#define _ASM_MICROBLAZE_MODULE_H
+
+/* Microblaze Relocations */
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+/* Keep this the last entry. */
+#define R_MICROBLAZE_NUM 11
+
+struct mod_arch_specific {
+	int foo;
+};
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+
+typedef struct { volatile int counter; } module_t;
+
+#endif /* _ASM_MICROBLAZE_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/msgbuf.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/msgbuf.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/msgbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/msgbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+#ifndef _ASM_MICROBLAZE_MSGBUF_H
+#define _ASM_MICROBLAZE_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+	__kernel_time_t msg_stime; /* last msgsnd time */
+	unsigned long __unused1;
+	__kernel_time_t msg_rtime; /* last msgrcv time */
+	unsigned long __unused2;
+	__kernel_time_t msg_ctime; /* last change time */
+	unsigned long __unused3;
+	unsigned long msg_cbytes; /* current number of bytes on queue */
+	unsigned long msg_qnum; /* number of messages in queue */
+	unsigned long msg_qbytes; /* max number of bytes on queue */
+	__kernel_pid_t msg_lspid; /* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid; /* last receive pid */
+	unsigned long __unused4;
+	unsigned long __unused5;
+};
+
+#endif /* _ASM_MICROBLAZE_MSGBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mutex.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mutex.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/mutex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/mutex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/mutex-dec.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/namei.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/namei.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/namei.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/namei.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_NAMEI_H
+#define _ASM_MICROBLAZE_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+#define __emul_prefix() NULL
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_NAMEI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/of_device.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/of_device.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/of_device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/of_device.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on PowerPC of_device.h
+ *
+ * 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 _ASM_MICROBLAZE_OF_DEVICE_H
+#define _ASM_MICROBLAZE_OF_DEVICE_H
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+#include <linux/of.h>
+
+/*
+ * The of_device is a kind of "base class" that is a superset of
+ * struct device for use by devices attached to an OF node and
+ * probed using OF properties.
+ */
+struct of_device {
+	struct device_node	*node; /* to be obsoleted */
+	u64			dma_mask; /* DMA mask */
+	struct device		dev; /* Generic device interface */
+};
+
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+					char *str, ssize_t len);
+
+extern struct of_device *of_device_alloc(struct device_node *np,
+					 const char *bus_id,
+					 struct device *parent);
+
+extern int of_device_uevent(struct device *dev,
+			    struct kobj_uevent_env *env);
+
+extern void of_device_make_bus_id(struct of_device *dev);
+
+/* This is just here during the transition */
+#include <linux/of_device.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/of_platform.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/of_platform.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/of_platform.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/of_platform.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *			<benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H
+#define _ASM_MICROBLAZE_OF_PLATFORM_H
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+/*
+ * The list of OF IDs below is used for matching bus types in the
+ * system whose devices are to be exposed as of_platform_devices.
+ *
+ * This is the default list valid for most platforms. This file provides
+ * functions who can take an explicit list if necessary though
+ *
+ * The search is always performed recursively looking for children of
+ * the provided device_node and recursively if such a children matches
+ * a bus type in the list
+ */
+
+static const struct of_device_id of_default_bus_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "soc", },
+	{ .type = "plb5", },
+	{ .type = "plb4", },
+	{ .type = "opb", },
+	{ .type = "simple", },
+	{},
+};
+
+/* Platform devices and busses creation */
+extern struct of_device *of_platform_device_create(struct device_node *np,
+						const char *bus_id,
+						struct device *parent);
+/* pseudo "matches" value to not do deep probe */
+#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
+
+extern int of_platform_bus_probe(struct device_node *root,
+				const struct of_device_id *matches,
+				struct device *parent);
+
+extern struct of_device *of_find_device_by_phandle(phandle ph);
+
+extern void of_instantiate_rtc(void);
+
+#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/page.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/page.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ * Changes for MMU support:
+ *    Copyright (C) 2007 Xilinx, Inc.  All rights reserved.
+ *
+ * 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 _ASM_MICROBLAZE_PAGE_H
+#define _ASM_MICROBLAZE_PAGE_H
+
+#include <linux/pfn.h>
+#include <asm/setup.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define PAGE_UP(addr)	(((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
+#define PAGE_DOWN(addr)	((addr)&(~((PAGE_SIZE)-1)))
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr, size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size)	((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size)	_ALIGN_UP(addr, size)
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. When not
+ * using MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+extern unsigned int __page_offset;
+#define PAGE_OFFSET __page_offset
+
+#define copy_page(to, from)			memcpy((to), (from), PAGE_SIZE)
+#define get_user_page(vaddr)			__get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr)		free_page(addr)
+
+#define clear_page(pgaddr)			memset((pgaddr), 0, PAGE_SIZE)
+
+
+#define clear_user_page(pgaddr, vaddr, page)	memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) \
+			memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct page *pgtable_t;
+typedef struct { unsigned long	pte; }		pte_t;
+typedef struct { unsigned long	pgprot; }	pgprot_t;
+typedef struct { unsigned long	ste[64]; }	pmd_t;
+typedef struct { pmd_t		pue[1]; }	pud_t;
+typedef struct { pud_t		pge[1]; }	pgd_t;
+
+
+#define pte_val(x)	((x).pte)
+#define pgprot_val(x)	((x).pgprot)
+#define pmd_val(x)	((x).ste[0])
+#define pud_val(x)	((x).pue[0])
+#define pgd_val(x)	((x).pge[0])
+
+#define __pte(x)	((pte_t) { (x) })
+#define __pmd(x)	((pmd_t) { (x) })
+#define __pgd(x)	((pgd_t) { (x) })
+#define __pgprot(x)	((pgprot_t) { (x) })
+
+/**
+ * Conversions for virtual address, physical address, pfn, and struct
+ * page are defined in the following files.
+ *
+ * virt -+
+ *	 | asm-microblaze/page.h
+ * phys -+
+ *	 | linux/pfn.h
+ *  pfn -+
+ *	 | asm-generic/memory_model.h
+ * page -+
+ *
+ */
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#define __pa(vaddr)		((unsigned long) (vaddr))
+#define __va(paddr)		((void *) (paddr))
+
+#define phys_to_pfn(phys)	(PFN_DOWN(phys))
+#define pfn_to_phys(pfn)	(PFN_PHYS(pfn))
+
+#define virt_to_pfn(vaddr)	(phys_to_pfn((__pa(vaddr))))
+#define pfn_to_virt(pfn)	__va(pfn_to_phys((pfn)))
+
+#define virt_to_page(vaddr)	(pfn_to_page(virt_to_pfn(vaddr)))
+#define page_to_virt(page)	(pfn_to_virt(page_to_pfn(page)))
+
+#define page_to_phys(page)	(pfn_to_phys(page_to_pfn(page)))
+#define page_to_bus(page)	(page_to_phys(page))
+#define phys_to_page(paddr)	(pfn_to_page(phys_to_pfn(paddr)))
+
+extern unsigned int memory_start;
+extern unsigned int memory_end;
+extern unsigned int memory_size;
+
+#define pfn_valid(pfn)		((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+
+#define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
+
+#else
+#define tophys(rd, rs)	(addik rd, rs, 0)
+#define tovirt(rd, rs)	(addik rd, rs, 0)
+#endif /* __ASSEMBLY__ */
+
+#define virt_addr_valid(vaddr)	(pfn_valid(virt_to_pfn(vaddr)))
+
+/* Convert between virtual and physical address for MMU.  */
+/* Handle MicroBlaze processor with virtual memory.  */
+#define __virt_to_phys(addr)	addr
+#define __phys_to_virt(addr)	addr
+
+#define TOPHYS(addr)  __virt_to_phys(addr)
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _ASM_MICROBLAZE_PAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/param.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/param.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/param.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_PARAM_H
+#define _ASM_MICROBLAZE_PARAM_H
+
+#ifdef __KERNEL__
+#define HZ		CONFIG_HZ	/* internal kernel timer frequency */
+#define USER_HZ		100		/* for user interfaces in "ticks" */
+#define CLOCKS_PER_SEC	(USER_HZ)	/* frequency at which times() counts */
+#endif /* __KERNEL__ */
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* _ASM_MICROBLAZE_PARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pci-bridge.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pci-bridge.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pci-bridge.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pci-bridge.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <linux/pci.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <linux/io.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/percpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/percpu.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pgalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_PGALLOC_H
+#define _ASM_MICROBLAZE_PGALLOC_H
+
+#define check_pgt_cache()	do {} while (0)
+
+#endif /* _ASM_MICROBLAZE_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pgtable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_PGTABLE_H
+#define _ASM_MICROBLAZE_PGTABLE_H
+
+#include <asm/setup.h>
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+		remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define pgd_present(pgd)	(1) /* pages are always present on non MMU */
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr)	(1)
+#define	pmd_offset(a, b)	((void *) 0)
+
+#define PAGE_NONE		__pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_SHARED		__pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_COPY		__pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_READONLY		__pgprot(0) /* these mean nothing to non MMU */
+#define PAGE_KERNEL		__pgprot(0) /* these mean nothing to non MMU */
+
+#define __swp_type(x)		(0)
+#define __swp_offset(x)		(0)
+#define __swp_entry(typ, off)	((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif /* __ASSEMBLY__ */
+
+#define ZERO_PAGE(vaddr)	({ BUG(); NULL; })
+
+#define swapper_pg_dir ((pgd_t *) NULL)
+
+#define pgtable_cache_init()	do {} while (0)
+
+#define arch_enter_lazy_cpu_mode()	do {} while (0)
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/pgtable.h>
+
+void setup_memory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PGTABLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/poll.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/poll.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/poll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/poll.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/posix_types.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/posix_types.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/posix_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/posix_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_POSIX_TYPES_H
+#define _ASM_MICROBLAZE_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned int	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned int	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char 		*__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned int	__kernel_old_uid_t;
+typedef unsigned int	__kernel_old_gid_t;
+typedef unsigned int	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef	__FD_CLR
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef	__FD_ISSET
+#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
+
+#undef	__FD_ZERO
+#define __FD_ZERO(fdsetp) (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* _ASM_MICROBLAZE_POSIX_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/processor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_PROCESSOR_H
+#define _ASM_MICROBLAZE_PROCESSOR_H
+
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+#include <asm/registers.h>
+#include <asm/segment.h>
+#include <asm/entry.h>
+#include <asm/current.h>
+
+# ifndef __ASSEMBLY__
+/* from kernel/cpu/mb.c */
+extern const struct seq_operations cpuinfo_op;
+
+# define cpu_relax()		barrier()
+# define cpu_sleep()		do {} while (0)
+# define prepare_to_copy(tsk)	do {} while (0)
+
+# endif /* __ASSEMBLY__ */
+
+#define task_pt_regs(tsk) \
+		(((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
+
+/* Do necessary setup to start up a newly executed thread. */
+void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp);
+
+/*
+ * User space process size: memory size
+ *
+ * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both
+ * user processes and the kernel is on the same memory region. They
+ * both share the memory space and that is limited by the amount of
+ * physical memory. thus, we set TASK_SIZE == amount of total memory.
+ */
+# define TASK_SIZE	(0x81000000 - 0x80000000)
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+# define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's. We won't be using it
+ */
+# define TASK_UNMAPPED_BASE	0
+
+/* definition in include/linux/sched.h */
+struct task_struct;
+
+/* thread_struct is gone. use thread_info instead. */
+struct thread_struct { };
+# define INIT_THREAD	{ }
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Free all resources held by a thread. */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+# define KSTK_EIP(tsk)	(0)
+# define KSTK_ESP(tsk)	(0)
+
+#endif /* _ASM_MICROBLAZE_PROCESSOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/prom.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/prom.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/prom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/prom.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,313 @@
+/*
+ * Definitions for talking to the Open Firmware PROM on
+ * Power Macintosh computers.
+ *
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MICROBLAZE_PROM_H
+#define _ASM_MICROBLAZE_PROM_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT	1
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT	1
+
+#define of_compat_cmp(s1, s2, l)	strncasecmp((s1), (s2), (l))
+#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 *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);
+extern int release_OF_resource(struct device_node *node, int index);
+
+/*
+ * 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);
+
+/* Extract an address from a device, returns the region size and
+ * the address space flags too. The PCI version uses a BAR number
+ * instead of an absolute index
+ */
+extern const u32 *of_get_address(struct device_node *dev, int index,
+			u64 *size, unsigned int *flags);
+extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
+			u64 *size, unsigned int *flags);
+
+/* Get an address as a resource. Note that if your address is
+ * a PIO address, the conversion will fail if the physical address
+ * can't be internally converted to an IO token with
+ * pci_address_to_pio(), that is because it's either called to early
+ * or it can't be matched to any host bridge IO space
+ */
+extern int of_address_to_resource(struct device_node *dev, int index,
+				struct resource *r);
+extern int of_pci_address_to_resource(struct device_node *dev, int bar,
+				struct resource *r);
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/*
+ * OF interrupt mapping
+ */
+
+/* This structure is returned when an interrupt is mapped. The controller
+ * field needs to be put() after use
+ */
+
+#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
+
+struct of_irq {
+	struct device_node *controller; /* Interrupt controller node */
+	u32 size; /* Specifier size */
+	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+};
+
+/**
+ * of_irq_map_init - Initialize the irq remapper
+ * @flags:	flags defining workarounds to enable
+ *
+ * Some machines have bugs in the device-tree which require certain workarounds
+ * to be applied. Call this before any interrupt mapping attempts to enable
+ * those workarounds.
+ */
+#define OF_IMAP_OLDWORLD_MAC	0x00000001
+#define OF_IMAP_NO_PHANDLE	0x00000002
+
+extern void of_irq_map_init(unsigned int flags);
+
+/**
+ * of_irq_map_raw - Low level interrupt tree parsing
+ * @parent:	the device interrupt parent
+ * @intspec:	interrupt specifier ("interrupts" property of the device)
+ * @ointsize:	size of the passed in interrupt specifier
+ * @addr:	address specifier (start of "reg" property of the device)
+ * @out_irq:	structure of_irq filled by this function
+ *
+ * Returns 0 on success and a negative number on error
+ *
+ * This function is a low-level interrupt tree walking function. It
+ * can be used to do a partial walk with synthetized reg and interrupts
+ * properties, for example when resolving PCI interrupts when no device
+ * node exist for the parent.
+ *
+ */
+
+extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
+			u32 ointsize, const u32 *addr,
+			struct of_irq *out_irq);
+
+/**
+ * of_irq_map_one - Resolve an interrupt for a device
+ * @device:	the device whose interrupt is to be resolved
+ * @index:	index of the interrupt to resolve
+ * @out_irq:	structure of_irq filled by this function
+ *
+ * This function resolves an interrupt, walking the tree, for a given
+ * device-tree node. It's the high level pendant to of_irq_map_raw().
+ * It also implements the workarounds for OldWolrd Macs.
+ */
+extern int of_irq_map_one(struct device_node *device, int index,
+			struct of_irq *out_irq);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev:	the device whose interrupt is to be resolved
+ * @out_irq:	structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+extern int of_irq_to_resource(struct device_node *dev, int index,
+			struct resource *r);
+
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device:	the device whose io range will be mapped
+ * @index:	index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+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 /* _ASM_MICROBLAZE_PROM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ptrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_PTRACE_H
+#define _ASM_MICROBLAZE_PTRACE_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+typedef unsigned long microblaze_reg_t;
+
+struct pt_regs {
+	microblaze_reg_t r0;
+	microblaze_reg_t r1;
+	microblaze_reg_t r2;
+	microblaze_reg_t r3;
+	microblaze_reg_t r4;
+	microblaze_reg_t r5;
+	microblaze_reg_t r6;
+	microblaze_reg_t r7;
+	microblaze_reg_t r8;
+	microblaze_reg_t r9;
+	microblaze_reg_t r10;
+	microblaze_reg_t r11;
+	microblaze_reg_t r12;
+	microblaze_reg_t r13;
+	microblaze_reg_t r14;
+	microblaze_reg_t r15;
+	microblaze_reg_t r16;
+	microblaze_reg_t r17;
+	microblaze_reg_t r18;
+	microblaze_reg_t r19;
+	microblaze_reg_t r20;
+	microblaze_reg_t r21;
+	microblaze_reg_t r22;
+	microblaze_reg_t r23;
+	microblaze_reg_t r24;
+	microblaze_reg_t r25;
+	microblaze_reg_t r26;
+	microblaze_reg_t r27;
+	microblaze_reg_t r28;
+	microblaze_reg_t r29;
+	microblaze_reg_t r30;
+	microblaze_reg_t r31;
+	microblaze_reg_t pc;
+	microblaze_reg_t msr;
+	microblaze_reg_t ear;
+	microblaze_reg_t esr;
+	microblaze_reg_t fsr;
+	int pt_mode;
+};
+
+#define kernel_mode(regs)		((regs)->pt_mode)
+#define user_mode(regs)			(!kernel_mode(regs))
+
+#define instruction_pointer(regs)	((regs)->pc)
+#define profile_pc(regs)		instruction_pointer(regs)
+
+void show_regs(struct pt_regs *);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_MICROBLAZE_PTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pvr.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pvr.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/pvr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/pvr.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ * Support for the MicroBlaze PVR (Processor Version Register)
+ *
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
+ * Copyright (C) 2007 - 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.
+ */
+
+#ifndef _ASM_MICROBLAZE_PVR_H
+#define _ASM_MICROBLAZE_PVR_H
+
+#define PVR_MSR_BIT 0x400
+
+struct pvr_s {
+	unsigned pvr[16];
+};
+
+/* The following taken from Xilinx's standalone BSP pvr.h */
+
+/* Basic PVR mask */
+#define PVR0_PVR_FULL_MASK		0x80000000
+#define PVR0_USE_BARREL_MASK		0x40000000
+#define PVR0_USE_DIV_MASK		0x20000000
+#define PVR0_USE_HW_MUL_MASK		0x10000000
+#define PVR0_USE_FPU_MASK		0x08000000
+#define PVR0_USE_EXC_MASK		0x04000000
+#define PVR0_USE_ICACHE_MASK		0x02000000
+#define PVR0_USE_DCACHE_MASK		0x01000000
+#define PVR0_USE_MMU			0x00800000	/* new */
+#define PVR0_VERSION_MASK		0x0000FF00
+#define PVR0_USER1_MASK			0x000000FF
+
+/* User 2 PVR mask */
+#define PVR1_USER2_MASK			0xFFFFFFFF
+
+/* Configuration PVR masks */
+#define PVR2_D_OPB_MASK			0x80000000
+#define PVR2_D_LMB_MASK			0x40000000
+#define PVR2_I_OPB_MASK			0x20000000
+#define PVR2_I_LMB_MASK			0x10000000
+#define PVR2_INTERRUPT_IS_EDGE_MASK	0x08000000
+#define PVR2_EDGE_IS_POSITIVE_MASK	0x04000000
+#define PVR2_D_PLB_MASK			0x02000000	/* new */
+#define PVR2_I_PLB_MASK			0x01000000	/* new */
+#define PVR2_INTERCONNECT		0x00800000	/* new */
+#define PVR2_USE_EXTEND_FSL		0x00080000	/* new */
+#define PVR2_USE_FSL_EXC		0x00040000	/* new */
+#define PVR2_USE_MSR_INSTR		0x00020000
+#define PVR2_USE_PCMP_INSTR		0x00010000
+#define PVR2_AREA_OPTIMISED		0x00008000
+#define PVR2_USE_BARREL_MASK		0x00004000
+#define PVR2_USE_DIV_MASK		0x00002000
+#define PVR2_USE_HW_MUL_MASK		0x00001000
+#define PVR2_USE_FPU_MASK		0x00000800
+#define PVR2_USE_MUL64_MASK		0x00000400
+#define PVR2_USE_FPU2_MASK		0x00000200	/* new */
+#define PVR2_USE_IPLBEXC 		0x00000100
+#define PVR2_USE_DPLBEXC		0x00000080
+#define PVR2_OPCODE_0x0_ILL_MASK	0x00000040
+#define PVR2_UNALIGNED_EXC_MASK		0x00000020
+#define PVR2_ILL_OPCODE_EXC_MASK	0x00000010
+#define PVR2_IOPB_BUS_EXC_MASK		0x00000008
+#define PVR2_DOPB_BUS_EXC_MASK		0x00000004
+#define PVR2_DIV_ZERO_EXC_MASK		0x00000002
+#define PVR2_FPU_EXC_MASK		0x00000001
+
+/* Debug and exception PVR masks */
+#define PVR3_DEBUG_ENABLED_MASK		0x80000000
+#define PVR3_NUMBER_OF_PC_BRK_MASK	0x1E000000
+#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK	0x00380000
+#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK	0x0000E000
+#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
+
+/* 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
+
+/* ICache base address PVR mask */
+#define PVR6_ICACHE_BASEADDR_MASK	0xFFFFFFFF
+
+/* ICache high address PVR mask */
+#define PVR7_ICACHE_HIGHADDR_MASK	0xFFFFFFFF
+
+/* DCache base address PVR mask */
+#define PVR8_DCACHE_BASEADDR_MASK	0xFFFFFFFF
+
+/* DCache high address PVR mask */
+#define PVR9_DCACHE_HIGHADDR_MASK	0xFFFFFFFF
+
+/* Target family PVR mask */
+#define PVR10_TARGET_FAMILY_MASK	0xFF000000
+
+/* MMU descrtiption */
+#define PVR11_USE_MMU			0xC0000000
+#define PVR11_MMU_ITLB_SIZE		0x38000000
+#define PVR11_MMU_DTLB_SIZE		0x07000000
+#define PVR11_MMU_TLB_ACCESS		0x00C00000
+#define PVR11_MMU_ZONES			0x003C0000
+/* MSR Reset value PVR mask */
+#define PVR11_MSR_RESET_VALUE_MASK	0x000007FF
+
+
+/* PVR access macros */
+#define PVR_IS_FULL(pvr)		(pvr.pvr[0] & PVR0_PVR_FULL_MASK)
+#define PVR_USE_BARREL(pvr)		(pvr.pvr[0] & PVR0_USE_BARREL_MASK)
+#define PVR_USE_DIV(pvr)		(pvr.pvr[0] & PVR0_USE_DIV_MASK)
+#define PVR_USE_HW_MUL(pvr)		(pvr.pvr[0] & PVR0_USE_HW_MUL_MASK)
+#define PVR_USE_FPU(pvr)		(pvr.pvr[0] & PVR0_USE_FPU_MASK)
+#define PVR_USE_FPU2(pvr)		(pvr.pvr[2] & PVR2_USE_FPU2_MASK)
+#define PVR_USE_ICACHE(pvr)		(pvr.pvr[0] & PVR0_USE_ICACHE_MASK)
+#define PVR_USE_DCACHE(pvr)		(pvr.pvr[0] & PVR0_USE_DCACHE_MASK)
+#define PVR_VERSION(pvr)	((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8)
+#define PVR_USER1(pvr)			(pvr.pvr[0] & PVR0_USER1_MASK)
+#define PVR_USER2(pvr)			(pvr.pvr[1] & PVR1_USER2_MASK)
+
+#define PVR_D_OPB(pvr)			(pvr.pvr[2] & PVR2_D_OPB_MASK)
+#define PVR_D_LMB(pvr)			(pvr.pvr[2] & PVR2_D_LMB_MASK)
+#define PVR_I_OPB(pvr)			(pvr.pvr[2] & PVR2_I_OPB_MASK)
+#define PVR_I_LMB(pvr)			(pvr.pvr[2] & PVR2_I_LMB_MASK)
+#define PVR_INTERRUPT_IS_EDGE(pvr) \
+			(pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK)
+#define PVR_EDGE_IS_POSITIVE(pvr) \
+			(pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK)
+#define PVR_USE_MSR_INSTR(pvr)		(pvr.pvr[2] & PVR2_USE_MSR_INSTR)
+#define PVR_USE_PCMP_INSTR(pvr)		(pvr.pvr[2] & PVR2_USE_PCMP_INSTR)
+#define PVR_AREA_OPTIMISED(pvr)		(pvr.pvr[2] & PVR2_AREA_OPTIMISED)
+#define PVR_USE_MUL64(pvr)		(pvr.pvr[2] & PVR2_USE_MUL64_MASK)
+#define PVR_OPCODE_0x0_ILLEGAL(pvr) \
+			(pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK)
+#define PVR_UNALIGNED_EXCEPTION(pvr) \
+			(pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK)
+#define PVR_ILL_OPCODE_EXCEPTION(pvr) \
+			(pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK)
+#define PVR_IOPB_BUS_EXCEPTION(pvr) \
+			(pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK)
+#define PVR_DOPB_BUS_EXCEPTION(pvr) \
+			(pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK)
+#define PVR_DIV_ZERO_EXCEPTION(pvr) \
+			(pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK)
+#define PVR_FPU_EXCEPTION(pvr)		(pvr.pvr[2] & PVR2_FPU_EXC_MASK)
+#define PVR_FSL_EXCEPTION(pvr)		(pvr.pvr[2] & PVR2_USE_EXTEND_FSL)
+
+#define PVR_DEBUG_ENABLED(pvr)		(pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK)
+#define PVR_NUMBER_OF_PC_BRK(pvr) \
+			((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25)
+#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \
+			((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19)
+#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \
+			((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13)
+#define PVR_FSL_LINKS(pvr)	((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7)
+
+#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \
+			((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26)
+#define PVR_ICACHE_USE_FSL(pvr)		(pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK)
+#define PVR_ICACHE_ALLOW_WR(pvr)	(pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK)
+#define PVR_ICACHE_LINE_LEN(pvr) \
+			(1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21))
+#define PVR_ICACHE_BYTE_SIZE(pvr) \
+			(1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16))
+
+#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \
+			((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)
+#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_ICACHE_BASEADDR(pvr)	(pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK)
+#define PVR_ICACHE_HIGHADDR(pvr)	(pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK)
+
+#define PVR_DCACHE_BASEADDR(pvr)	(pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK)
+#define PVR_DCACHE_HIGHADDR(pvr)	(pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK)
+
+#define PVR_TARGET_FAMILY(pvr)	((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24)
+
+#define PVR_MSR_RESET_VALUE(pvr) \
+				(pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK)
+
+/* mmu */
+#define PVR_USE_MMU(pvr)	((pvr.pvr[11] & PVR11_USE_MMU) >> 30)
+#define PVR_MMU_ITLB_SIZE(pvr)	(pvr.pvr[11] & PVR11_MMU_ITLB_SIZE)
+#define PVR_MMU_DTLB_SIZE(pvr)	(pvr.pvr[11] & PVR11_MMU_DTLB_SIZE)
+#define PVR_MMU_TLB_ACCESS(pvr)	(pvr.pvr[11] & PVR11_MMU_TLB_ACCESS)
+#define PVR_MMU_ZONES(pvr)	(pvr.pvr[11] & PVR11_MMU_ZONES)
+
+
+int cpu_has_pvr(void);
+void get_pvr(struct pvr_s *pvr);
+
+#endif /* _ASM_MICROBLAZE_PVR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/registers.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/registers.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/registers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/registers.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_REGISTERS_H
+#define _ASM_MICROBLAZE_REGISTERS_H
+
+#define MSR_BE	(1<<0) /* 0x001 */
+#define MSR_IE	(1<<1) /* 0x002 */
+#define MSR_C	(1<<2) /* 0x004 */
+#define MSR_BIP	(1<<3) /* 0x008 */
+#define MSR_FSL	(1<<4) /* 0x010 */
+#define MSR_ICE	(1<<5) /* 0x020 */
+#define MSR_DZ	(1<<6) /* 0x040 */
+#define MSR_DCE	(1<<7) /* 0x080 */
+#define MSR_EE	(1<<8) /* 0x100 */
+#define MSR_EIP	(1<<9) /* 0x200 */
+#define MSR_CC	(1<<31)
+
+/* Floating Point Status Register (FSR) Bits */
+#define FSR_IO		(1<<4) /* Invalid operation */
+#define FSR_DZ		(1<<3) /* Divide-by-zero */
+#define FSR_OF		(1<<2) /* Overflow */
+#define FSR_UF		(1<<1) /* Underflow */
+#define FSR_DO		(1<<0) /* Denormalized operand error */
+
+#endif /* _ASM_MICROBLAZE_REGISTERS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/resource.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/resource.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/resource.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/resource.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/scatterlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SCATTERLIST_H
+#define _ASM_MICROBLAZE_SCATTERLIST_H
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
+	dma_addr_t	dma_address;
+	unsigned int	offset;
+	unsigned int	length;
+};
+
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* _ASM_MICROBLAZE_SCATTERLIST_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sections.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SECTIONS_H
+#define _ASM_MICROBLAZE_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+# ifndef __ASSEMBLY__
+extern char _ssbss[], _esbss[];
+extern unsigned long __ivt_start[], __ivt_end[];
+
+#  ifdef CONFIG_MTD_UCLINUX
+extern char *_ebss;
+#  endif
+
+extern u32 _fdt_start[], _fdt_end[];
+
+# endif /* !__ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SECTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/segment.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/segment.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/segment.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/segment.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 Michal Simek
+ * Copyright (C) 2008 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SEGMENT_H
+#define _ASM_MICROBLAZE_SEGMENT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+/*
+ * On Microblaze the fs value is actually the top of the corresponding
+ * address space.
+ *
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ *
+ * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal.
+ */
+#  define KERNEL_DS	((mm_segment_t){0})
+#  define USER_DS	KERNEL_DS
+
+# define get_ds()	(KERNEL_DS)
+# define get_fs()	(current_thread_info()->addr_limit)
+# define set_fs(x) \
+		do { current_thread_info()->addr_limit = (x); } while (0)
+
+# define segment_eq(a, b)		((a).seg == (b).seg)
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SEGMENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/selfmod.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/selfmod.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/selfmod.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/selfmod.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ *
+ * 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 _ASM_MICROBLAZE_SELFMOD_H
+#define _ASM_MICROBLAZE_SELFMOD_H
+
+/*
+ * BARRIER_BASE_ADDR is constant address for selfmod function.
+ * do not change this value - selfmod function is in
+ * arch/microblaze/kernel/selfmod.c: selfmod_function()
+ *
+ * last 16 bits is used for storing register offset
+ */
+
+#define BARRIER_BASE_ADDR	0x1234ff00
+
+void selfmod_function(const int *arr_fce, const unsigned int base);
+
+#endif /* _ASM_MICROBLAZE_SELFMOD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sembuf.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sembuf.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sembuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sembuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SEMBUF_H
+#define _ASM_MICROBLAZE_SEMBUF_H
+
+/*
+ * The semid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime; /* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime; /* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems; /* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+
+#endif /* _ASM_MICROBLAZE_SEMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/serial.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/serial.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ *
+ * 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 _ASM_MICROBLAZE_SERIAL_H
+#define _ASM_MICROBLAZE_SERIAL_H
+
+# define BASE_BAUD (1843200 / 16)
+
+#endif /* _ASM_MICROBLAZE_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/setup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SETUP_H
+#define _ASM_MICROBLAZE_SETUP_H
+
+#define COMMAND_LINE_SIZE	256
+
+# ifndef __ASSEMBLY__
+
+#  ifdef __KERNEL__
+extern unsigned int boot_cpuid; /* move to smp.h */
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+#  endif/* __KERNEL__ */
+
+void early_printk(const char *fmt, ...);
+
+int setup_early_printk(char *opt);
+void disable_early_printk(void);
+
+void heartbeat(void);
+void setup_heartbeat(void);
+
+unsigned long long sched_clock(void);
+
+void time_init(void);
+void init_IRQ(void);
+void machine_early_init(const char *cmdline, unsigned int ram,
+						unsigned int fdt);
+
+void machine_restart(char *cmd);
+void machine_shutdown(void);
+void machine_halt(void);
+void machine_power_off(void);
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SETUP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/shmbuf.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/shmbuf.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/shmbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/shmbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+#ifndef _ASM_MICROBLAZE_SHMBUF_H
+#define _ASM_MICROBLAZE_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for microblaze architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm; /* operation perms */
+	size_t			shm_segsz; /* size of segment (bytes) */
+	__kernel_time_t		shm_atime; /* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime; /* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime; /* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid; /* pid of creator */
+	__kernel_pid_t		shm_lpid; /* pid of last operator */
+	unsigned long		shm_nattch; /* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_MICROBLAZE_SHMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/shmparam.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/shmparam.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/shmparam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/shmparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_MICROBLAZE_SHMPARAM_H
+#define _ASM_MICROBLAZE_SHMPARAM_H
+
+#define SHMLBA	PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_MICROBLAZE_SHMPARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sigcontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SIGCONTEXT_H
+#define _ASM_MICROBLAZE_SIGCONTEXT_H
+
+/* FIXME should be linux/ptrace.h */
+#include <asm/ptrace.h>
+
+struct sigcontext {
+	struct pt_regs regs;
+	unsigned long oldmask;
+};
+
+#endif /* _ASM_MICROBLAZE_SIGCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/siginfo.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/siginfo.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/siginfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/siginfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SIGINFO_H
+#define _ASM_MICROBLAZE_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_MICROBLAZE_SIGINFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/signal.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/signal.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/signal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/signal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *	Yasushi SHOJI <yashi@atmark-techno.com>
+ *	Tetsuya OHKAWA <tetsuya@atmark-techno.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.
+ */
+
+#ifndef _ASM_MICROBLAZE_SIGNAL_H
+#define _ASM_MICROBLAZE_SIGNAL_H
+
+#define SIGHUP		1
+#define SIGINT		2
+#define SIGQUIT		3
+#define SIGILL		4
+#define SIGTRAP		5
+#define SIGABRT		6
+#define SIGIOT		6
+#define SIGBUS		7
+#define SIGFPE		8
+#define SIGKILL		9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN	32
+#define SIGRTMAX	_NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+# ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm-generic/signal.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#  ifdef __KERNEL__
+/*
+ * Most things should be clean enough to redefine this at will, if care
+ * is taken to make libc match.
+ */
+#  define _NSIG		64
+#  define _NSIG_BPW	32
+#  define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#  include <asm/sigcontext.h>
+#  undef __HAVE_ARCH_SIG_BITOPS
+
+#  define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#  else /* !__KERNEL__ */
+
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#  define NSIG		32
+typedef unsigned long sigset_t;
+
+struct sigaction {
+	union {
+	__sighandler_t _sa_handler;
+	void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#  define sa_handler	_u._sa_handler
+#  define sa_sigaction	_u._sa_sigaction
+
+#  endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_SIGNAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/socket.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SOCKET_H
+#define _ASM_MICROBLAZE_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_SNDBUFFORCE	32
+#define SO_RCVBUFFORCE	33
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER	26
+#define SO_DETACH_FILTER	27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+#define SO_PEERSEC		31
+#define SO_PASSSEC		34
+
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
+
+#define SO_MARK			36
+
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
+#endif /* _ASM_MICROBLAZE_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sockios.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sockios.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/sockios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/sockios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SOCKIOS_H
+#define _ASM_MICROBLAZE_SOCKIOS_H
+
+#include <linux/ioctl.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) */
+
+#endif /* _ASM_MICROBLAZE_SOCKIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/statfs.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/statfs.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/statfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/statfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/stat.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/stat.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/stat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/stat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Microblaze stat structure
+ *
+ * Copyright (C) 2001,02,03 NEC Electronics Corporation
+ * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
+ *
+ * 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.
+ *
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#ifndef _ASM_MICROBLAZE_STAT_H
+#define _ASM_MICROBLAZE_STAT_H
+
+#include <linux/posix_types.h>
+
+struct stat {
+	unsigned int	st_dev;
+	unsigned long	st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	st_rdev;
+	unsigned long	st_size;
+	unsigned long	st_blksize;
+	unsigned long	st_blocks;
+	unsigned long	st_atime;
+	unsigned long	__unused1; /* unsigned long  st_atime_nsec */
+	unsigned long	st_mtime;
+	unsigned long	__unused2; /* unsigned long  st_mtime_nsec */
+	unsigned long	st_ctime;
+	unsigned long	__unused3; /* unsigned long  st_ctime_nsec */
+	unsigned long	__unused4;
+	unsigned long	__unused5;
+};
+
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned long	__unused1;
+
+	unsigned long long	st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned long	__unused3;
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks; /* No. of 512-byte blocks allocated */
+	unsigned long	__unused4; /* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned long	st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long	st_ctime_nsec;
+
+	unsigned long	__unused8;
+};
+
+#endif /* _ASM_MICROBLAZE_STAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/string.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/string.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/string.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/string.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_STRING_H
+#define _ASM_MICROBLAZE_STRING_H
+
+#ifndef __KERNEL__
+
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_STRING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/swab.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef _ASM_MICROBLAZE_SWAB_H
+#define _ASM_MICROBLAZE_SWAB_H
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_MICROBLAZE_SWAB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/syscalls.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/syscalls.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/syscalls.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/syscalls.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+#ifndef __ASM_MICROBLAZE_SYSCALLS_H
+#define __ASM_MICROBLAZE_SYSCALLS_H
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/signal.h>
+
+/* FIXME will be removed */
+asmlinkage int sys_ipc(uint call, int first, int second,
+				int third, void *ptr, long fifth);
+
+struct pt_regs;
+asmlinkage int sys_vfork(struct pt_regs *regs);
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+			char __user *__user *envp, struct pt_regs *regs);
+
+asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff);
+
+asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, off_t offset);
+
+/* from signal.c */
+asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+		struct pt_regs *regs);
+
+asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act,
+		struct old_sigaction *oact);
+
+asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+		struct pt_regs *regs);
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs);
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_MICROBLAZE_SYSCALLS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/system.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_SYSTEM_H
+#define _ASM_MICROBLAZE_SYSTEM_H
+
+#include <asm/registers.h>
+#include <asm/setup.h>
+#include <asm/irqflags.h>
+
+struct task_struct;
+struct thread_info;
+
+extern struct task_struct *_switch_to(struct thread_info *prev,
+					struct thread_info *next);
+
+#define switch_to(prev, next, last)					\
+	do {								\
+		(last) = _switch_to(task_thread_info(prev),		\
+					task_thread_info(next));	\
+	} while (0)
+
+#define smp_read_barrier_depends()	do {} while (0)
+#define read_barrier_depends()		do {} while (0)
+
+#define nop()			asm volatile ("nop")
+#define mb()			barrier()
+#define rmb()			mb()
+#define wmb()			mb()
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
+
+#define smp_mb()		mb()
+#define smp_rmb()		rmb()
+#define smp_wmb()		wmb()
+
+void show_trace(struct task_struct *task, unsigned long *stack);
+void __bad_xchg(volatile void *ptr, int size);
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+								int size)
+{
+	unsigned long ret;
+	unsigned long flags;
+
+	switch (size) {
+	case 1:
+		local_irq_save(flags);
+		ret = *(volatile unsigned char *)ptr;
+		*(volatile unsigned char *)ptr = x;
+		local_irq_restore(flags);
+		break;
+
+	case 4:
+		local_irq_save(flags);
+		ret = *(volatile unsigned long *)ptr;
+		*(volatile unsigned long *)ptr = x;
+		local_irq_restore(flags);
+		break;
+	default:
+		__bad_xchg(ptr, size), ret = 0;
+		break;
+	}
+
+	return ret;
+}
+
+void disable_hlt(void);
+void enable_hlt(void);
+void default_idle(void);
+
+#define xchg(ptr, x) \
+	((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end);
+void free_initmem(void);
+extern char *klimit;
+extern void ret_from_fork(void);
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *of_debugfs_root;
+#endif
+
+#define arch_align_stack(x) (x)
+
+#endif /* _ASM_MICROBLAZE_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/termbits.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/termbits.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/termbits.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/termbits.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TERMBITS_H
+#define _ASM_MICROBLAZE_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 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 B57600	0010001
+#define B115200	0010002
+#define B230400	0010003
+#define B460800	0010004
+#define B500000	0010005
+#define B576000	0010006
+#define B921600	0010007
+#define BOTHER		0010000
+#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 (not used) */
+#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
+
+/* tcsetattr uses these */
+
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ASM_MICROBLAZE_TERMBITS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/termios.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/termios.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/termios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/termios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TERMIOS_H
+#define _ASM_MICROBLAZE_TERMIOS_H
+
+#include <linux/string.h>
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag; /* input mode flags */
+	unsigned short c_oflag; /* output mode flags */
+	unsigned short c_cflag; /* control mode flags */
+	unsigned short c_lflag; /* local mode flags */
+	unsigned char c_line; /* line discipline */
+	unsigned char c_cc[NCC]; /* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* Modem lines */
+
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* Line disciplines */
+
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6 /* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8 /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9 /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10 /* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11 /* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12 /* SMS block mode - for talking to GSM data cards
+				about SMS messages */
+#define N_HDLC		13 /* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15 /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+#include <asm-generic/termios.h>
+
+#endif	/* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_TERMIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/thread_info.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_THREAD_INFO_H
+#define _ASM_MICROBLAZE_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+/* we have 8k stack */
+#define THREAD_SHIFT		13
+#define THREAD_SIZE		(1 << THREAD_SHIFT)
+#define THREAD_SIZE_ORDER	1
+
+#ifndef __ASSEMBLY__
+# include <linux/types.h>
+# include <asm/processor.h>
+# include <asm/segment.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *	 must also be changed
+ */
+
+struct cpu_context {
+	__u32	r1; /* stack pointer */
+	__u32	r2;
+	/* dedicated registers */
+	__u32	r13;
+	__u32	r14;
+	__u32	r15;
+	__u32	r16;
+	__u32	r17;
+	__u32	r18;
+	/* non-volatile registers */
+	__u32	r19;
+	__u32	r20;
+	__u32	r21;
+	__u32	r22;
+	__u32	r23;
+	__u32	r24;
+	__u32	r25;
+	__u32	r26;
+	__u32	r27;
+	__u32	r28;
+	__u32	r29;
+	__u32	r30;
+	/* r31 is used as current task pointer */
+	/* special purpose registers */
+	__u32	msr;
+	__u32	ear;
+	__u32	esr;
+	__u32	fsr;
+};
+
+struct thread_info {
+	struct task_struct	*task; /* main task structure */
+	struct exec_domain	*exec_domain; /* execution domain */
+	unsigned long		flags; /* low level flags */
+	unsigned long		status; /* thread-synchronous flags */
+	__u32			cpu; /* current CPU */
+	__s32			preempt_count; /* 0 => preemptable,< 0 => BUG*/
+	mm_segment_t		addr_limit; /* thread address space */
+	struct restart_block	restart_block;
+
+	struct cpu_context	cpu_context;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+	register unsigned long sp asm("r1");
+
+	return (struct thread_info *)(sp & ~(THREAD_SIZE-1));
+}
+
+/* thread information allocation */
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may
+ *   need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME	1 /* resumption notification requested */
+#define TIF_SIGPENDING		2 /* signal pending */
+#define TIF_NEED_RESCHED	3 /* rescheduling necessary */
+/* restore singlestep on return to user mode */
+#define TIF_SINGLESTEP		4
+#define TIF_IRET		5 /* return with iret */
+#define TIF_MEMDIE		6
+#define TIF_FREEZE		14	/* Freezing for suspend */
+
+/* FIXME change in entry.S */
+#define TIF_KERNEL_TRACE	8	/* kernel trace active */
+
+/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG	16
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
+#define _TIF_IRET		(1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		(1<<TIF_FREEZE)
+#define _TIF_KERNEL_TRACE	(1 << TIF_KERNEL_TRACE)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK		0x0000FFFE
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK	0x0000FFFF
+
+/*
+ * 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.
+ */
+/* FPU was used by this task this quantum (SMP) */
+#define TS_USEDFPU		0x0001
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_THREAD_INFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TIMEX_H
+#define _ASM_MICROBLAZE_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
+
+typedef unsigned long cycles_t;
+
+#define get_cycles()	(0)
+
+#endif /* _ASM_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/tlbflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TLBFLUSH_H
+#define _ASM_MICROBLAZE_TLBFLUSH_H
+
+#define flush_tlb()				BUG()
+#define flush_tlb_all()				BUG()
+#define flush_tlb_mm(mm)			BUG()
+#define flush_tlb_page(vma, addr)		BUG()
+#define flush_tlb_range(mm, start, end)		BUG()
+#define flush_tlb_pgtables(mm, start, end)	BUG()
+#define flush_tlb_kernel_range(start, end)	BUG()
+
+#endif /* _ASM_MICROBLAZE_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/tlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TLB_H
+#define _ASM_MICROBLAZE_TLB_H
+
+#define tlb_flush(tlb)	do {} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_MICROBLAZE_TLB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/topology.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+#include <asm-generic/topology.h>
+
+#ifndef _ASM_MICROBLAZE_TOPOLOGY_H
+#define _ASM_MICROBLAZE_TOPOLOGY_H
+
+struct device_node;
+static inline int of_node_to_nid(struct device_node *device)
+{
+	return 0;
+}
+#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/types.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_TYPES_H
+#define _ASM_MICROBLAZE_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+
+#include <asm-generic/int-ll64.h>
+
+# ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#  ifdef __KERNEL__
+#  define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+#  endif/* __KERNEL__ */
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_MICROBLAZE_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/uaccess.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_UACCESS_H
+#define _ASM_MICROBLAZE_UACCESS_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h> /* RLIMIT_FSIZE */
+#include <linux/mm.h>
+
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+#include <linux/string.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+extern int ___range_ok(unsigned long addr, unsigned long size);
+
+#define __range_ok(addr, size) \
+		___range_ok((unsigned long)(addr), (unsigned long)(size))
+
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(add, size) (__range_ok((addr), (size)) == 0)
+
+extern inline int bad_user_access_length(void)
+{
+	return 0;
+}
+/* FIXME this is function for optimalization -> memcpy */
+#define __get_user(var, ptr)					\
+	({							\
+		int __gu_err = 0;				\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+		case 2:						\
+		case 4:						\
+			(var) = *(ptr);				\
+			break;					\
+		case 8:						\
+			memcpy((void *) &(var), (ptr), 8);	\
+			break;					\
+		default:					\
+			(var) = 0;				\
+			__gu_err = __get_user_bad();		\
+			break;					\
+		}						\
+		__gu_err;					\
+	})
+
+#define __get_user_bad()	(bad_user_access_length(), (-EFAULT))
+
+#define __put_user(var, ptr)					\
+	({							\
+		int __pu_err = 0;				\
+		switch (sizeof(*(ptr))) {			\
+		case 1:						\
+		case 2:						\
+		case 4:						\
+			*(ptr) = (var);				\
+			break;					\
+		case 8: {					\
+			typeof(*(ptr)) __pu_val = var;		\
+			memcpy(ptr, &__pu_val, sizeof(__pu_val));\
+			}					\
+			break;					\
+		default:					\
+			__pu_err = __put_user_bad();		\
+			break;					\
+		}							\
+		__pu_err;						\
+	})
+
+#define __put_user_bad()	(bad_user_access_length(), (-EFAULT))
+
+#define put_user(x, ptr)	__put_user(x, ptr)
+#define get_user(x, ptr)	__get_user(x, ptr)
+
+#define copy_to_user(to, from, n)		(memcpy(to, from, n), 0)
+#define copy_from_user(to, from, n)		(memcpy(to, from, n), 0)
+
+#define __copy_to_user(to, from, n)		(copy_to_user(to, from, n))
+#define __copy_from_user(to, from, n)		(copy_from_user(to, from, n))
+#define __copy_to_user_inatomic(to, from, n)	(__copy_to_user(to, from, n))
+#define __copy_from_user_inatomic(to, from, n)	(__copy_from_user(to, from, n))
+
+#define __clear_user(addr, n)	(memset((void *)addr, 0, n), 0)
+
+static inline unsigned long clear_user(void *addr, unsigned long size)
+{
+	if (access_ok(VERIFY_WRITE, addr, size))
+		size = __clear_user(addr, size);
+	return size;
+}
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *src, long count);
+extern long __strncpy_from_user(char *dst, const char __user *src, long count);
+
+/*
+ * 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
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+struct exception_table_entry {
+	unsigned long insn, fixup;
+};
+
+#endif  /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_MICROBLAZE_UACCESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ucontext.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ucontext.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/ucontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/ucontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_UCONTEXT_H
+#define _ASM_MICROBLAZE_UCONTEXT_H
+
+#include <asm/sigcontext.h>
+
+struct ucontext {
+	unsigned long		uc_flags;
+	struct ucontext		*uc_link;
+	stack_t			uc_stack;
+	struct sigcontext	uc_mcontext;
+	sigset_t		uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _ASM_MICROBLAZE_UCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/unaligned.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/unaligned.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/unaligned.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/unaligned.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_UNALIGNED_H
+#define _ASM_MICROBLAZE_UNALIGNED_H
+
+# ifdef __KERNEL__
+
+# include <linux/unaligned/access_ok.h>
+# include <linux/unaligned/generic.h>
+
+# define get_unaligned	__get_unaligned_be
+# define put_unaligned	__put_unaligned_be
+
+# endif	/* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/unistd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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 _ASM_MICROBLAZE_UNISTD_H
+#define _ASM_MICROBLAZE_UNISTD_H
+
+#define __NR_restart_syscall	0 /* ok */
+#define __NR_exit		1 /* ok */
+#define __NR_fork		2 /* not for no MMU - weird */
+#define __NR_read		3 /* ok */
+#define __NR_write		4 /* ok */
+#define __NR_open		5 /* openat */
+#define __NR_close		6 /* ok */
+#define __NR_waitpid		7 /* waitid */
+#define __NR_creat		8 /* openat */
+#define __NR_link		9 /* linkat */
+#define __NR_unlink		10 /* unlinkat */
+#define __NR_execve		11 /* ok */
+#define __NR_chdir		12 /* ok */
+#define __NR_time		13 /* obsolete -> sys_gettimeofday */
+#define __NR_mknod		14 /* mknodat */
+#define __NR_chmod		15 /* fchmodat */
+#define __NR_lchown		16 /* ok */
+#define __NR_break		17 /* don't know */
+#define __NR_oldstat		18 /* remove */
+#define __NR_lseek		19 /* ok */
+#define __NR_getpid		20 /* ok */
+#define __NR_mount		21 /* ok */
+#define __NR_umount		22 /* ok */  /* use only umount2 */
+#define __NR_setuid		23 /* ok */
+#define __NR_getuid		24 /* ok */
+#define __NR_stime		25 /* obsolete -> sys_settimeofday */
+#define __NR_ptrace		26 /* ok */
+#define __NR_alarm		27 /* obsolete -> sys_setitimer */
+#define __NR_oldfstat		28 /* remove */
+#define __NR_pause		29 /* obsolete -> sys_rt_sigtimedwait */
+#define __NR_utime		30 /* obsolete -> sys_utimesat */
+#define __NR_stty		31 /* remove */
+#define __NR_gtty		32 /* remove */
+#define __NR_access		33 /* faccessat */
+/* can be implemented by sys_setpriority */
+#define __NR_nice		34
+#define __NR_ftime		35 /* remove */
+#define __NR_sync		36 /* ok */
+#define __NR_kill		37 /* ok */
+#define __NR_rename		38 /* renameat */
+#define __NR_mkdir		39 /* mkdirat */
+#define __NR_rmdir		40 /* unlinkat */
+#define __NR_dup		41 /* ok */
+#define __NR_pipe		42 /* ok */
+#define __NR_times		43 /* ok */
+#define __NR_prof		44 /* remove */
+#define __NR_brk		45 /* ok -mmu, nommu specific */
+#define __NR_setgid		46 /* ok */
+#define __NR_getgid		47 /* ok */
+#define __NR_signal		48 /* obsolete -> sys_rt_sigaction */
+#define __NR_geteuid		49 /* ok */
+#define __NR_getegid		50 /* ok */
+#define __NR_acct		51 /* add it and then I can disable it */
+#define __NR_umount2		52 /* remove */
+#define __NR_lock		53 /* remove */
+#define __NR_ioctl		54 /* ok */
+#define __NR_fcntl		55 /* ok -> 64bit version*/
+#define __NR_mpx		56 /* remove */
+#define __NR_setpgid		57 /* ok */
+#define __NR_ulimit		58 /* remove */
+#define __NR_oldolduname	59 /* remove */
+#define __NR_umask		60 /* ok */
+#define __NR_chroot		61 /* ok */
+#define __NR_ustat		62 /* obsolete -> statfs64 */
+#define __NR_dup2		63 /* ok */
+#define __NR_getppid		64 /* ok */
+#define __NR_getpgrp		65 /* obsolete -> sys_getpgid */
+#define __NR_setsid		66 /* ok */
+#define __NR_sigaction		67 /* obsolete -> rt_sigaction */
+#define __NR_sgetmask		68 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_ssetmask		69 /* obsolete ->sys_rt_sigprocmask */
+#define __NR_setreuid		70 /* ok */
+#define __NR_setregid		71 /* ok */
+#define __NR_sigsuspend		72 /* obsolete -> rt_sigsuspend */
+#define __NR_sigpending		73 /* obsolete -> sys_rt_sigpending */
+#define __NR_sethostname	74 /* ok */
+#define __NR_setrlimit		75 /* ok */
+#define __NR_getrlimit		76 /* ok Back compatible 2G limited rlimit */
+#define __NR_getrusage		77 /* ok */
+#define __NR_gettimeofday	78 /* ok */
+#define __NR_settimeofday	79 /* ok */
+#define __NR_getgroups		80 /* ok */
+#define __NR_setgroups		81 /* ok */
+#define __NR_select		82 /* obsolete -> sys_pselect7 */
+#define __NR_symlink		83 /* symlinkat */
+#define __NR_oldlstat		84 /* remove */
+#define __NR_readlink		85 /* obsolete -> sys_readlinkat */
+#define __NR_uselib		86 /* remove */
+#define __NR_swapon		87 /* ok */
+#define __NR_reboot		88 /* ok */
+#define __NR_readdir		89 /* remove ? */
+#define __NR_mmap		90 /* obsolete -> sys_mmap2 */
+#define __NR_munmap		91 /* ok - mmu and nommu */
+#define __NR_truncate		92 /* ok or truncate64 */
+#define __NR_ftruncate		93 /* ok or ftruncate64 */
+#define __NR_fchmod		94 /* ok */
+#define __NR_fchown		95 /* ok */
+#define __NR_getpriority	96 /* ok */
+#define __NR_setpriority	97 /* ok */
+#define __NR_profil		98 /* remove */
+#define __NR_statfs		99 /* ok or statfs64 */
+#define __NR_fstatfs		100  /* ok or fstatfs64 */
+#define __NR_ioperm		101 /* remove */
+#define __NR_socketcall		102 /* remove */
+#define __NR_syslog		103 /* ok */
+#define __NR_setitimer		104 /* ok */
+#define __NR_getitimer		105 /* ok */
+#define __NR_stat		106 /* remove */
+#define __NR_lstat		107 /* remove */
+#define __NR_fstat		108 /* remove */
+#define __NR_olduname		109 /* remove */
+#define __NR_iopl		110 /* remove */
+#define __NR_vhangup		111 /* ok */
+#define __NR_idle		112 /* remove */
+#define __NR_vm86old		113 /* remove */
+#define __NR_wait4		114 /* obsolete -> waitid */
+#define __NR_swapoff		115 /* ok */
+#define __NR_sysinfo		116 /* ok */
+#define __NR_ipc		117 /* remove - direct call */
+#define __NR_fsync		118 /* ok */
+#define __NR_sigreturn		119 /* obsolete -> sys_rt_sigreturn */
+#define __NR_clone		120 /* ok */
+#define __NR_setdomainname	121 /* ok */
+#define __NR_uname		122 /* remove */
+#define __NR_modify_ldt		123 /* remove */
+#define __NR_adjtimex		124 /* ok */
+#define __NR_mprotect		125 /* remove */
+#define __NR_sigprocmask	126 /* obsolete -> sys_rt_sigprocmask */
+#define __NR_create_module	127 /* remove */
+#define __NR_init_module	128 /* ok */
+#define __NR_delete_module	129 /* ok */
+#define __NR_get_kernel_syms	130 /* remove */
+#define __NR_quotactl		131 /* ok */
+#define __NR_getpgid		132 /* ok */
+#define __NR_fchdir		133 /* ok */
+#define __NR_bdflush		134 /* remove */
+#define __NR_sysfs		135 /* needed for busybox */
+#define __NR_personality	136 /* ok */
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138 /* ok */
+#define __NR_setfsgid		139 /* ok */
+#define __NR__llseek		140 /* remove only lseek */
+#define __NR_getdents		141 /* ok or getdents64 */
+#define __NR__newselect		142 /* remove */
+#define __NR_flock		143 /* ok */
+#define __NR_msync		144 /* remove */
+#define __NR_readv		145 /* ok */
+#define __NR_writev		146 /* ok */
+#define __NR_getsid		147 /* ok */
+#define __NR_fdatasync		148 /* ok */
+#define __NR__sysctl		149 /* remove */
+#define __NR_mlock		150 /* ok - nommu or mmu */
+#define __NR_munlock		151 /* ok - nommu or mmu */
+#define __NR_mlockall		152 /* ok - nommu or mmu */
+#define __NR_munlockall		153 /* ok - nommu or mmu */
+#define __NR_sched_setparam		154 /* ok */
+#define __NR_sched_getparam		155 /* ok */
+#define __NR_sched_setscheduler		156 /* ok */
+#define __NR_sched_getscheduler		157 /* ok */
+#define __NR_sched_yield		158 /* ok */
+#define __NR_sched_get_priority_max	159 /* ok */
+#define __NR_sched_get_priority_min	160 /* ok */
+#define __NR_sched_rr_get_interval	161 /* ok */
+#define __NR_nanosleep		162 /* ok */
+#define __NR_mremap		163 /* ok - nommu or mmu */
+#define __NR_setresuid		164 /* ok */
+#define __NR_getresuid		165 /* ok */
+#define __NR_vm86		166 /* remove */
+#define __NR_query_module	167 /* ok */
+#define __NR_poll		168 /* obsolete -> sys_ppoll */
+#define __NR_nfsservctl		169 /* ok */
+#define __NR_setresgid		170 /* ok */
+#define __NR_getresgid		171 /* ok */
+#define __NR_prctl		172 /* ok */
+#define __NR_rt_sigreturn	173 /* ok */
+#define __NR_rt_sigaction	174 /* ok */
+#define __NR_rt_sigprocmask	175 /* ok */
+#define __NR_rt_sigpending	176 /* ok */
+#define __NR_rt_sigtimedwait	177 /* ok */
+#define __NR_rt_sigqueueinfo	178 /* ok */
+#define __NR_rt_sigsuspend	179 /* ok */
+#define __NR_pread64		180 /* ok */
+#define __NR_pwrite64		181 /* ok */
+#define __NR_chown		182 /* obsolete -> fchownat */
+#define __NR_getcwd		183 /* ok */
+#define __NR_capget		184 /* ok */
+#define __NR_capset		185 /* ok */
+#define __NR_sigaltstack	186 /* remove */
+#define __NR_sendfile		187 /* ok -> exist 64bit version*/
+#define __NR_getpmsg		188 /* remove */
+/* remove - some people actually want streams */
+#define __NR_putpmsg		189
+/* for noMMU - group with clone -> maybe remove */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191 /* remove - SuS compliant getrlimit */
+#define __NR_mmap2		192 /* ok */
+#define __NR_truncate64		193 /* ok */
+#define __NR_ftruncate64	194 /* ok */
+#define __NR_stat64		195 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lstat64		196 /* remove _ARCH_WANT_STAT64 */
+#define __NR_fstat64		197 /* remove _ARCH_WANT_STAT64 */
+#define __NR_lchown32		198 /* ok - without 32 */
+#define __NR_getuid32		199 /* ok - without 32 */
+#define __NR_getgid32		200 /* ok - without 32 */
+#define __NR_geteuid32		201 /* ok - without 32 */
+#define __NR_getegid32		202 /* ok - without 32 */
+#define __NR_setreuid32		203 /* ok - without 32 */
+#define __NR_setregid32		204 /* ok - without 32 */
+#define __NR_getgroups32	205 /* ok - without 32 */
+#define __NR_setgroups32	206 /* ok - without 32 */
+#define __NR_fchown32		207 /* ok - without 32 */
+#define __NR_setresuid32	208 /* ok - without 32 */
+#define __NR_getresuid32	209 /* ok - without 32 */
+#define __NR_setresgid32	210 /* ok - without 32 */
+#define __NR_getresgid32	211 /* ok - without 32 */
+#define __NR_chown32		212 /* ok - without 32 -obsolete -> fchownat */
+#define __NR_setuid32		213 /* ok - without 32 */
+#define __NR_setgid32		214 /* ok - without 32 */
+#define __NR_setfsuid32		215 /* ok - without 32 */
+#define __NR_setfsgid32		216 /* ok - without 32 */
+#define __NR_pivot_root		217 /* ok */
+#define __NR_mincore		218 /* ok */
+#define __NR_madvise		219 /* ok */
+#define __NR_getdents64		220 /* ok */
+#define __NR_fcntl64		221 /* ok */
+/* 223 is unused */
+#define __NR_gettid		224 /* ok */
+#define __NR_readahead		225 /* ok */
+#define __NR_setxattr		226 /* ok */
+#define __NR_lsetxattr		227 /* ok */
+#define __NR_fsetxattr		228 /* ok */
+#define __NR_getxattr		229 /* ok */
+#define __NR_lgetxattr		230 /* ok */
+#define __NR_fgetxattr		231 /* ok */
+#define __NR_listxattr		232 /* ok */
+#define __NR_llistxattr		233 /* ok */
+#define __NR_flistxattr		234 /* ok */
+#define __NR_removexattr	235 /* ok */
+#define __NR_lremovexattr	236 /* ok */
+#define __NR_fremovexattr	237 /* ok */
+#define __NR_tkill		238 /* ok */
+#define __NR_sendfile64		239 /* ok */
+#define __NR_futex		240 /* ok */
+#define __NR_sched_setaffinity	241 /* ok */
+#define __NR_sched_getaffinity	242 /* ok */
+#define __NR_set_thread_area	243 /* remove */
+#define __NR_get_thread_area	244 /* remove */
+#define __NR_io_setup		245 /* ok */
+#define __NR_io_destroy		246 /* ok */
+#define __NR_io_getevents	247 /* ok */
+#define __NR_io_submit		248 /* ok */
+#define __NR_io_cancel		249 /* ok */
+#define __NR_fadvise64		250 /* remove -> sys_fadvise64_64 */
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
+#define __NR_exit_group		252 /* ok */
+#define __NR_lookup_dcookie	253 /* ok */
+#define __NR_epoll_create	254 /* ok */
+#define __NR_epoll_ctl		255 /* ok */
+#define __NR_epoll_wait		256 /* obsolete -> sys_epoll_pwait */
+#define __NR_remap_file_pages	257 /* only for mmu */
+#define __NR_set_tid_address	258 /* ok */
+#define __NR_timer_create	259 /* ok */
+#define __NR_timer_settime	(__NR_timer_create+1) /* 260 */ /* ok */
+#define __NR_timer_gettime	(__NR_timer_create+2) /* 261 */ /* ok */
+#define __NR_timer_getoverrun	(__NR_timer_create+3) /* 262 */ /* ok */
+#define __NR_timer_delete	(__NR_timer_create+4) /* 263 */ /* ok */
+#define __NR_clock_settime	(__NR_timer_create+5) /* 264 */ /* ok */
+#define __NR_clock_gettime	(__NR_timer_create+6) /* 265 */ /* ok */
+#define __NR_clock_getres	(__NR_timer_create+7) /* 266 */ /* ok */
+#define __NR_clock_nanosleep	(__NR_timer_create+8) /* 267 */ /* ok */
+#define __NR_statfs64		268 /* ok */
+#define __NR_fstatfs64		269 /* ok */
+#define __NR_tgkill		270 /* ok */
+#define __NR_utimes		271 /* obsolete -> sys_futimesat */
+#define __NR_fadvise64_64	272 /* ok */
+#define __NR_vserver		273 /* ok */
+#define __NR_mbind		274 /* only for mmu */
+#define __NR_get_mempolicy	275 /* only for mmu */
+#define __NR_set_mempolicy	276 /* only for mmu */
+#define __NR_mq_open		277 /* ok */
+#define __NR_mq_unlink		(__NR_mq_open+1) /* 278 */ /* ok */
+#define __NR_mq_timedsend	(__NR_mq_open+2) /* 279 */ /* ok */
+#define __NR_mq_timedreceive	(__NR_mq_open+3) /* 280 */ /* ok */
+#define __NR_mq_notify		(__NR_mq_open+4) /* 281 */ /* ok */
+#define __NR_mq_getsetattr	(__NR_mq_open+5) /* 282 */ /* ok */
+#define __NR_kexec_load		283 /* ok */
+#define __NR_waitid		284 /* ok */
+/* #define __NR_sys_setaltroot	285 */
+#define __NR_add_key		286 /* ok */
+#define __NR_request_key	287 /* ok */
+#define __NR_keyctl		288 /* ok */
+#define __NR_ioprio_set		289 /* ok */
+#define __NR_ioprio_get		290 /* ok */
+#define __NR_inotify_init	291 /* ok */
+#define __NR_inotify_add_watch	292 /* ok */
+#define __NR_inotify_rm_watch	293 /* ok */
+#define __NR_migrate_pages	294 /* mmu */
+#define __NR_openat		295 /* ok */
+#define __NR_mkdirat		296 /* ok */
+#define __NR_mknodat		297 /* ok */
+#define __NR_fchownat		298 /* ok */
+#define __NR_futimesat		299 /* obsolete -> sys_utimesat */
+#define __NR_fstatat64		300 /* stat64 */
+#define __NR_unlinkat		301 /* ok */
+#define __NR_renameat		302 /* ok */
+#define __NR_linkat		303 /* ok */
+#define __NR_symlinkat		304 /* ok */
+#define __NR_readlinkat		305 /* ok */
+#define __NR_fchmodat		306 /* ok */
+#define __NR_faccessat		307 /* ok */
+#define __NR_pselect6		308 /* obsolete -> sys_pselect7 */
+#define __NR_ppoll		309 /* ok */
+#define __NR_unshare		310 /* ok */
+#define __NR_set_robust_list	311 /* ok */
+#define __NR_get_robust_list	312 /* ok */
+#define __NR_splice		313 /* ok */
+#define __NR_sync_file_range	314 /* ok */
+#define __NR_tee		315 /* ok */
+#define __NR_vmsplice		316 /* ok */
+#define __NR_move_pages		317 /* mmu */
+#define __NR_getcpu		318 /* ok */
+#define __NR_epoll_pwait	319 /* ok */
+#define __NR_utimensat		320 /* ok */
+#define __NR_signalfd		321 /* ok */
+#define __NR_timerfd_create	322 /* ok */
+#define __NR_eventfd		323 /* ok */
+#define __NR_fallocate		324 /* ok */
+#define __NR_semtimedop		325 /* ok - semaphore group */
+#define __NR_timerfd_settime	326 /* ok */
+#define __NR_timerfd_gettime	327 /* ok */
+/* sysv ipc syscalls */
+#define __NR_semctl		328 /* ok */
+#define __NR_semget		329 /* ok */
+#define __NR_semop		330 /* ok */
+#define __NR_msgctl		331 /* ok */
+#define __NR_msgget		332 /* ok */
+#define __NR_msgrcv		333 /* ok */
+#define __NR_msgsnd		334 /* ok */
+#define __NR_shmat		335 /* ok */
+#define __NR_shmctl		336 /* ok */
+#define __NR_shmdt		337 /* ok */
+#define __NR_shmget		338 /* ok */
+
+
+#define __NR_signalfd4		339 /* new */
+#define __NR_eventfd2		340 /* new */
+#define __NR_epoll_create1	341 /* new */
+#define __NR_dup3		342 /* new */
+#define __NR_pipe2		343 /* new */
+#define __NR_inotify_init1	344 /* new */
+#define __NR_socket		345 /* new */
+#define __NR_socketpair		346 /* new */
+#define __NR_bind		347 /* new */
+#define __NR_listen		348 /* new */
+#define __NR_accept		349 /* new */
+#define __NR_connect		350 /* new */
+#define __NR_getsockname	351 /* new */
+#define __NR_getpeername	352 /* new */
+#define __NR_sendto		353 /* new */
+#define __NR_send		354 /* new */
+#define __NR_recvfrom		355 /* new */
+#define __NR_recv		356 /* new */
+#define __NR_setsockopt		357 /* new */
+#define __NR_getsockopt		358 /* new */
+#define __NR_shutdown		359 /* new */
+#define __NR_sendmsg		360 /* new */
+#define __NR_recvmsg		361 /* new */
+#define __NR_accept04		362 /* new */
+#define __NR_preadv		363 /* new */
+#define __NR_pwritev		364 /* new */
+
+#define __NR_syscalls		365
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+/* #define __ARCH_WANT_OLD_READDIR */
+/* #define __ARCH_WANT_OLD_STAT */
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_MICROBLAZE_UNISTD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/user.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/user.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/user.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/vga.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/vga.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/vga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/xor.h linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/xor.h
--- linux-libre-2.6.29-gnu1/arch/microblaze/include/asm/xor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/include/asm/xor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/Kconfig linux-libre-2.6.30-gnu1/arch/microblaze/Kconfig
--- linux-libre-2.6.29-gnu1/arch/microblaze/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,141 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+mainmenu "Linux/Microblaze Kernel Configuration"
+
+config MICROBLAZE
+	def_bool y
+	select HAVE_LMB
+
+config SWAP
+	def_bool n
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+
+config ARCH_HAS_ILOG2_U32
+	def_bool n
+
+config ARCH_HAS_ILOG2_U64
+	def_bool n
+
+config GENERIC_FIND_NEXT_BIT
+	def_bool y
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config GENERIC_HARDIRQS
+	def_bool y
+
+config GENERIC_IRQ_PROBE
+	def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+	def_bool y
+
+config GENERIC_TIME
+	def_bool y
+
+config GENERIC_TIME_VSYSCALL
+	def_bool n
+
+config GENERIC_CLOCKEVENTS
+	def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+	def_bool y
+
+config PCI
+	depends on !MMU
+	def_bool n
+
+config NO_DMA
+	depends on !MMU
+	def_bool n
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+source "arch/microblaze/platform/Kconfig.platform"
+
+menu "Processor type and features"
+
+source kernel/time/Kconfig
+
+source "kernel/Kconfig.preempt"
+
+source "kernel/Kconfig.hz"
+
+config MMU
+	def_bool n
+
+config NO_MMU
+	bool
+	depends on !MMU
+	default y
+
+comment "Boot options"
+
+config CMDLINE_BOOL
+	bool "Default bootloader kernel arguments"
+
+config CMDLINE
+	string "Default kernel command string"
+	depends on CMDLINE_BOOL
+	default "console=ttyUL0,115200"
+	help
+	  On some architectures there is currently no way for the boot loader
+	  to pass arguments to the kernel. For these architectures, you should
+	  supply some command-line options at build time by entering them
+	  here.
+
+config CMDLINE_FORCE
+	bool "Force default kernel command string"
+	depends on CMDLINE_BOOL
+	default n
+	help
+	  Set this to have arguments from the default kernel command string
+	  override those passed by the boot loader.
+
+config OF
+	def_bool y
+
+config OF_DEVICE
+	def_bool y
+
+config PROC_DEVICETREE
+	bool "Support for device tree in /proc"
+	depends on PROC_FS
+	help
+	  This option adds a device-tree directory under /proc which contains
+	  an image of the device tree that the kernel copies from Open
+	  Firmware or other boot firmware. If unsure, say Y here.
+
+endmenu
+
+source "mm/Kconfig"
+
+menu "Exectuable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/microblaze/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/Kconfig.debug linux-libre-2.6.30-gnu1/arch/microblaze/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/microblaze/Kconfig.debug	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,26 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+	bool "Early printk function for kernel"
+	default n
+	help
+	  This option turns on/off early printk messages to console.
+	  First Uartlite node is taken.
+
+config HEART_BEAT
+	bool "Heart beat function for kernel"
+	default n
+	help
+	  This option turns on/off heart beat kernel functionality.
+	  First GPIO node is taken.
+
+config DEBUG_BOOTMEM
+	depends on DEBUG_KERNEL
+	bool "Debug BOOTMEM initialization"
+
+endmenu
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/asm-offsets.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <linux/thread_info.h>
+#include <linux/kbuild.h>
+
+int main(int argc, char *argv[])
+{
+	/* struct pt_regs */
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	DEFINE(PT_MSR, offsetof(struct pt_regs, msr));
+	DEFINE(PT_EAR, offsetof(struct pt_regs, ear));
+	DEFINE(PT_ESR, offsetof(struct pt_regs, esr));
+	DEFINE(PT_FSR, offsetof(struct pt_regs, fsr));
+	DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+	DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+	DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+	DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+	DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+	DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+	DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+	DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+	DEFINE(PT_R8, offsetof(struct pt_regs, r8));
+	DEFINE(PT_R9, offsetof(struct pt_regs, r9));
+	DEFINE(PT_R10, offsetof(struct pt_regs, r10));
+	DEFINE(PT_R11, offsetof(struct pt_regs, r11));
+	DEFINE(PT_R12, offsetof(struct pt_regs, r12));
+	DEFINE(PT_R13, offsetof(struct pt_regs, r13));
+	DEFINE(PT_R14, offsetof(struct pt_regs, r14));
+	DEFINE(PT_R15, offsetof(struct pt_regs, r15));
+	DEFINE(PT_R16, offsetof(struct pt_regs, r16));
+	DEFINE(PT_R17, offsetof(struct pt_regs, r17));
+	DEFINE(PT_R18, offsetof(struct pt_regs, r18));
+	DEFINE(PT_R19, offsetof(struct pt_regs, r19));
+	DEFINE(PT_R20, offsetof(struct pt_regs, r20));
+	DEFINE(PT_R21, offsetof(struct pt_regs, r21));
+	DEFINE(PT_R22, offsetof(struct pt_regs, r22));
+	DEFINE(PT_R23, offsetof(struct pt_regs, r23));
+	DEFINE(PT_R24, offsetof(struct pt_regs, r24));
+	DEFINE(PT_R25, offsetof(struct pt_regs, r25));
+	DEFINE(PT_R26, offsetof(struct pt_regs, r26));
+	DEFINE(PT_R27, offsetof(struct pt_regs, r27));
+	DEFINE(PT_R28, offsetof(struct pt_regs, r28));
+	DEFINE(PT_R29, offsetof(struct pt_regs, r29));
+	DEFINE(PT_R30, offsetof(struct pt_regs, r30));
+	DEFINE(PT_R31, offsetof(struct pt_regs, r31));
+	DEFINE(PT_MODE, offsetof(struct pt_regs, pt_mode));
+	BLANK();
+
+	/* Magic offsets for PTRACE PEEK/POKE etc */
+	DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1);
+	DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2);
+	DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3);
+	BLANK();
+
+	/* struct task_struct */
+	DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack));
+
+	/* struct thread_info */
+	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+	DEFINE(TI_STATUS, offsetof(struct thread_info, status));
+	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+	DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+	DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+	DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block));
+	DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
+	BLANK();
+
+	/* struct cpu_context */
+	DEFINE(CC_R1, offsetof(struct cpu_context, r1)); /* r1 */
+	DEFINE(CC_R2, offsetof(struct cpu_context, r2));
+	/* dedicated registers */
+	DEFINE(CC_R13, offsetof(struct cpu_context, r13));
+	DEFINE(CC_R14, offsetof(struct cpu_context, r14));
+	DEFINE(CC_R15, offsetof(struct cpu_context, r15));
+	DEFINE(CC_R16, offsetof(struct cpu_context, r16));
+	DEFINE(CC_R17, offsetof(struct cpu_context, r17));
+	DEFINE(CC_R18, offsetof(struct cpu_context, r18));
+	/* non-volatile registers */
+	DEFINE(CC_R19, offsetof(struct cpu_context, r19));
+	DEFINE(CC_R20, offsetof(struct cpu_context, r20));
+	DEFINE(CC_R21, offsetof(struct cpu_context, r21));
+	DEFINE(CC_R22, offsetof(struct cpu_context, r22));
+	DEFINE(CC_R23, offsetof(struct cpu_context, r23));
+	DEFINE(CC_R24, offsetof(struct cpu_context, r24));
+	DEFINE(CC_R25, offsetof(struct cpu_context, r25));
+	DEFINE(CC_R26, offsetof(struct cpu_context, r26));
+	DEFINE(CC_R27, offsetof(struct cpu_context, r27));
+	DEFINE(CC_R28, offsetof(struct cpu_context, r28));
+	DEFINE(CC_R29, offsetof(struct cpu_context, r29));
+	DEFINE(CC_R30, offsetof(struct cpu_context, r30));
+	/* special purpose registers */
+	DEFINE(CC_MSR, offsetof(struct cpu_context, msr));
+	DEFINE(CC_EAR, offsetof(struct cpu_context, ear));
+	DEFINE(CC_ESR, offsetof(struct cpu_context, esr));
+	DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
+	BLANK();
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cache.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cache.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cache.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cache.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,255 @@
+/*
+ * Cache control for MicroBlaze cache memories
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 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
+ * archive for more details.
+ */
+
+#include <asm/cacheflush.h>
+#include <linux/cache.h>
+#include <asm/cpuinfo.h>
+
+/* Exported functions */
+
+void _enable_icache(void)
+{
+	if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrset	r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "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)
+{
+	if (cpuinfo.use_icache) {
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+		__asm__ __volatile__ ("					\
+				msrclr r0, %0;				\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory");
+#else
+		__asm__ __volatile__ ("					\
+				mfs	r12, rmsr;			\
+				nop;					\
+				andi	r12, r12, ~%0;			\
+				mts	rmsr, r12;			\
+				nop; "					\
+				:					\
+				: "i" (MSR_ICE)				\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _invalidate_icache(unsigned int addr)
+{
+	if (cpuinfo.use_icache) {
+		__asm__ __volatile__ ("					\
+				wic	%0, r0"				\
+				:					\
+				: "r" (addr));
+	}
+}
+
+void _enable_dcache(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)			\
+				: "memory", "r12");
+#endif
+	}
+}
+
+void _disable_dcache(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)			\
+				: "memory", "r12");
+#endif
+}
+
+void _invalidate_dcache(unsigned int addr)
+{
+		__asm__ __volatile__ ("					\
+				wdc	%0, r0"				\
+				:					\
+				: "r" (addr));
+}
+
+void __invalidate_icache_all(void)
+{
+	unsigned int i;
+	unsigned flags;
+
+	if (cpuinfo.use_icache) {
+		local_irq_save(flags);
+		__disable_icache();
+
+		/* 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);
+
+		__enable_icache();
+		local_irq_restore(flags);
+	}
+}
+
+void __invalidate_icache_range(unsigned long start, unsigned long end)
+{
+	unsigned int i;
+	unsigned flags;
+	unsigned int align;
+
+	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);
+
+		local_irq_save(flags);
+		__disable_icache();
+
+		for (i = start; i < end; i += cpuinfo.icache_line)
+			__invalidate_icache(i);
+
+		__enable_icache();
+		local_irq_restore(flags);
+	}
+}
+
+void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	__invalidate_icache_all();
+}
+
+void __invalidate_icache_user_range(struct vm_area_struct *vma,
+				struct page *page, unsigned long adr,
+				int len)
+{
+	__invalidate_icache_all();
+}
+
+void __invalidate_cache_sigtramp(unsigned long addr)
+{
+	__invalidate_icache_range(addr, addr + 8);
+}
+
+void __invalidate_dcache_all(void)
+{
+	unsigned int i;
+	unsigned flags;
+
+	if (cpuinfo.use_dcache) {
+		local_irq_save(flags);
+		__disable_dcache();
+
+		/*
+		 * 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);
+
+		__enable_dcache();
+		local_irq_restore(flags);
+	}
+}
+
+void __invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+	unsigned int i;
+	unsigned flags;
+	unsigned int align;
+
+	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();
+
+		for (i = start; i < end; i += cpuinfo.dcache_line)
+			__invalidate_dcache(i);
+
+		__enable_dcache();
+		local_irq_restore(flags);
+	}
+}
+
+void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page)
+{
+	__invalidate_dcache_all();
+}
+
+void __invalidate_dcache_user_range(struct vm_area_struct *vma,
+				struct page *page, unsigned long adr,
+				int len)
+{
+	__invalidate_dcache_all();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 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 archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+const struct cpu_ver_key cpu_ver_lookup[] = {
+	/* These key value are as per MBV field in PVR0 */
+	{"5.00.a", 0x01},
+	{"5.00.b", 0x02},
+	{"5.00.c", 0x03},
+	{"6.00.a", 0x04},
+	{"6.00.b", 0x06},
+	{"7.00.a", 0x05},
+	{"7.00.b", 0x07},
+	{"7.10.a", 0x08},
+	{"7.10.b", 0x09},
+	{"7.10.c", 0x0a},
+	{"7.10.d", 0x0b},
+	/* 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},
+	{NULL, 0},
+};
+
+/*
+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
+ */
+const struct family_string_key family_string_lookup[] = {
+	{"virtex2", 0x4},
+	{"virtex2pro", 0x5},
+	{"spartan3", 0x6},
+	{"virtex4", 0x7},
+	{"virtex5", 0x8},
+	{"spartan3e", 0x9},
+	{"spartan3a", 0xa},
+	{"spartan3an", 0xb},
+	{"spartan3adsp", 0xc},
+	/* FIXME There is no key code defined for spartan2 */
+	{"spartan2", 0xf0},
+	{NULL, 0},
+};
+
+struct cpuinfo cpuinfo;
+
+void __init setup_cpuinfo(void)
+{
+	struct device_node *cpu = NULL;
+
+	cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
+	if (!cpu)
+		printk(KERN_ERR "You don't have cpu!!!\n");
+
+	printk(KERN_INFO "%s: initialising\n", __func__);
+
+	switch (cpu_has_pvr()) {
+	case 0:
+		printk(KERN_WARNING
+			"%s: No PVR support. Using static CPU info from FDT\n",
+			__func__);
+		set_cpuinfo_static(&cpuinfo, cpu);
+		break;
+/* FIXME I found weird behavior with MB 7.00.a/b 7.10.a
+ * please do not use FULL PVR with MMU */
+	case 1:
+		printk(KERN_INFO "%s: Using full CPU PVR support\n",
+			__func__);
+		set_cpuinfo_static(&cpuinfo, cpu);
+		set_cpuinfo_pvr_full(&cpuinfo, cpu);
+		break;
+	default:
+		printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__);
+		set_cpuinfo_static(&cpuinfo, cpu);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 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 archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/pvr.h>
+#include <asm/cpuinfo.h>
+
+/*
+ * Helper macro to map between fields in our struct cpuinfo, and
+ * the PVR macros in pvr.h.
+ */
+
+#define CI(c, p) { ci->c = PVR_##p(pvr); }
+#define err_printk(x) \
+	early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n");
+
+void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
+{
+	struct pvr_s pvr;
+	int temp; /* for saving temp value */
+	get_pvr(&pvr);
+
+	CI(ver_code, VERSION);
+	if (!ci->ver_code) {
+		printk(KERN_ERR "ERROR: MB has broken PVR regs "
+						"-> use DTS setting\n");
+		return;
+	}
+
+	temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\
+		PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr);
+	if (ci->use_instr != temp)
+		err_printk("BARREL, MSR, PCMP or DIV");
+	ci->use_instr = temp;
+
+	temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr);
+	if (ci->use_mult != temp)
+		err_printk("HW_MUL");
+	ci->use_mult = temp;
+
+	temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr);
+	if (ci->use_fpu != temp)
+		err_printk("HW_FPU");
+	ci->use_fpu = temp;
+
+	ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\
+			PVR_UNALIGNED_EXCEPTION(pvr) |\
+			PVR_ILL_OPCODE_EXCEPTION(pvr) |\
+			PVR_IOPB_BUS_EXCEPTION(pvr) |\
+			PVR_DOPB_BUS_EXCEPTION(pvr) |\
+			PVR_DIV_ZERO_EXCEPTION(pvr) |\
+			PVR_FPU_EXCEPTION(pvr) |\
+			PVR_FSL_EXCEPTION(pvr);
+
+	CI(pvr_user1, USER1);
+	CI(pvr_user2, USER2);
+
+	CI(mmu, USE_MMU);
+
+	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_size, ICACHE_BYTE_SIZE);
+	CI(icache_base, ICACHE_BASEADDR);
+	CI(icache_high, ICACHE_HIGHADDR);
+
+	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_size, DCACHE_BYTE_SIZE);
+	CI(dcache_base, DCACHE_BASEADDR);
+	CI(dcache_high, DCACHE_HIGHADDR);
+
+	CI(use_dopb, D_OPB);
+	CI(use_iopb, I_OPB);
+	CI(use_dlmb, D_LMB);
+	CI(use_ilmb, I_LMB);
+	CI(num_fsl, FSL_LINKS);
+
+	CI(irq_edge, INTERRUPT_IS_EDGE);
+	CI(irq_positive, EDGE_IS_POSITIVE);
+
+	CI(area_optimised, AREA_OPTIMISED);
+
+	CI(hw_debug, DEBUG_ENABLED);
+	CI(num_pc_brk, NUMBER_OF_PC_BRK);
+	CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK);
+	CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
+
+	CI(fpga_family_code, TARGET_FAMILY);
+
+	/* take timebase-frequency from DTS */
+	ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/cpuinfo-static.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 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 archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/cpuinfo.h>
+#include <asm/pvr.h>
+
+static const char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
+static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
+
+#define err_printk(x) \
+	early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n");
+
+void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
+{
+	int i = 0;
+
+	ci->use_instr =
+		(fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) |
+		(fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) |
+		(fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) |
+		(fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0);
+	if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL)
+		i |= PVR0_USE_BARREL_MASK;
+	if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR)
+		i |= PVR2_USE_MSR_INSTR;
+	if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR)
+		i |= PVR2_USE_PCMP_INSTR;
+	if (CONFIG_XILINX_MICROBLAZE0_USE_DIV)
+		i |= PVR0_USE_DIV_MASK;
+	if (ci->use_instr != i)
+		err_printk("BARREL, MSR, PCMP or DIV");
+
+	ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul");
+	if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)
+		err_printk("HW_MUL");
+	ci->use_mult =
+		(ci->use_mult > 1 ?
+				(PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) :
+				(ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0));
+
+	ci->use_fpu = fcpu(cpu, "xlnx,use-fpu");
+	if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU)
+		err_printk("HW_FPU");
+	ci->use_fpu = (ci->use_fpu > 1 ?
+				(PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) :
+				(ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0));
+
+	ci->use_exc =
+		(fcpu(cpu, "xlnx,unaligned-exceptions") ?
+				PVR2_UNALIGNED_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,ill-opcode-exception") ?
+				PVR2_ILL_OPCODE_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,iopb-bus-exception") ?
+				PVR2_IOPB_BUS_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,dopb-bus-exception") ?
+				PVR2_DOPB_BUS_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,div-zero-exception") ?
+				PVR2_DIV_ZERO_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) |
+		(fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0);
+
+	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) {
+		if (fcpu(cpu, "xlnx,icache-use-fsl"))
+			ci->icache_line = 4 << 2;
+		else
+			ci->icache_line = 1 << 2;
+	}
+	ci->icache_size = fcpu(cpu, "i-cache-size");
+	ci->icache_base = fcpu(cpu, "i-cache-baseaddr");
+	ci->icache_high = fcpu(cpu, "i-cache-highaddr");
+
+	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) {
+		if (fcpu(cpu, "xlnx,dcache-use-fsl"))
+			ci->dcache_line = 4 << 2;
+		else
+			ci->dcache_line = 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->use_dopb = fcpu(cpu, "xlnx,d-opb");
+	ci->use_iopb = fcpu(cpu, "xlnx,i-opb");
+	ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb");
+	ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb");
+
+	ci->num_fsl = fcpu(cpu, "xlnx,fsl-links");
+	ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge");
+	ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive");
+	ci->area_optimised = 0;
+
+	ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled");
+	ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk");
+	ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
+	ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
+
+	ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+
+	ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
+	ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
+
+	ci->mmu = fcpu(cpu, "xlnx,use-mmu");
+
+	ci->ver_code = 0;
+	ci->fpga_family_code = 0;
+
+	/* Do various fixups based on CPU version and FPGA family strings */
+
+	/* Resolved the CPU version code */
+	for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+		if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0)
+			ci->ver_code = cpu_ver_lookup[i].k;
+	}
+
+	/* Resolved the fpga family code */
+	for (i = 0; family_string_lookup[i].s != NULL; i++) {
+		if (strcmp(family_string_lookup[i].s, family_string) == 0)
+			ci->fpga_family_code = family_string_lookup[i].k;
+	}
+
+	/* FIXME - mb3 and spartan2 do not exist in PVR */
+	/* This is mb3 and on a non Spartan2 */
+	if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0)
+		/* Hardware Multiplier in use */
+		ci->use_mult = 1;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#
+# Build the appropriate CPU version support
+#
+
+EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
+		-DCPU_REV=$(CPU_REV)
+
+obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/mb.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/mb.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/mb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/mb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * CPU-version specific code
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006-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/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+
+#include <linux/bug.h>
+#include <asm/cpuinfo.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <linux/param.h>
+#include <asm/pvr.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	int count = 0;
+	char *fpga_family = "Unknown";
+	char *cpu_ver = "Unknown";
+	int i;
+
+	/* Denormalised to get the fpga family string */
+	for (i = 0; family_string_lookup[i].s != NULL; i++) {
+		if (cpuinfo.fpga_family_code == family_string_lookup[i].k) {
+			fpga_family = (char *)family_string_lookup[i].s;
+			break;
+		}
+	}
+
+	/* Denormalised to get the hw version string */
+	for (i = 0; cpu_ver_lookup[i].s != NULL; i++) {
+		if (cpuinfo.ver_code == cpu_ver_lookup[i].k) {
+			cpu_ver = (char *)cpu_ver_lookup[i].s;
+			break;
+		}
+	}
+
+	count = seq_printf(m,
+			"CPU-Family:	MicroBlaze\n"
+			"FPGA-Arch:	%s\n"
+			"CPU-Ver:	%s\n"
+			"CPU-MHz:	%d.%02d\n"
+			"BogoMips:	%lu.%02lu\n",
+			fpga_family,
+			cpu_ver,
+			cpuinfo.cpu_clock_freq /
+			1000000,
+			cpuinfo.cpu_clock_freq %
+			1000000,
+			loops_per_jiffy / (500000 / HZ),
+			(loops_per_jiffy / (5000 / HZ)) % 100);
+
+	count += seq_printf(m,
+		"HW:\n Shift:\t\t%s\n"
+		" MSR:\t\t%s\n"
+		" PCMP:\t\t%s\n"
+		" DIV:\t\t%s\n",
+		(cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no",
+		(cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no",
+		(cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no",
+		(cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no");
+
+	count += seq_printf(m,
+			" MMU:\t\t%x\n",
+			cpuinfo.mmu);
+
+	count += seq_printf(m,
+		" MUL:\t\t%s\n"
+		" FPU:\t\t%s\n",
+		(cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" :
+			(cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no",
+		(cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" :
+			(cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no");
+
+	count += seq_printf(m,
+		" Exc:\t\t%s%s%s%s%s%s%s%s\n",
+		(cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "",
+		(cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "",
+		(cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "",
+		(cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "",
+		(cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "",
+		(cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "",
+		(cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "",
+		(cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : "");
+
+	if (cpuinfo.use_icache)
+		count += seq_printf(m,
+				"Icache:\t\t%ukB\n",
+				cpuinfo.icache_size >> 10);
+	else
+		count += seq_printf(m, "Icache:\t\tno\n");
+
+	if (cpuinfo.use_dcache)
+		count += seq_printf(m,
+				"Dcache:\t\t%ukB\n",
+				cpuinfo.dcache_size >> 10);
+	else
+		count += seq_printf(m, "Dcache:\t\tno\n");
+
+	count += seq_printf(m,
+			"HW-Debug:\t%s\n",
+			cpuinfo.hw_debug ? "yes" : "no");
+
+	count += seq_printf(m,
+			"PVR-USR1:\t%02x\n"
+			"PVR-USR2:\t%08x\n",
+			cpuinfo.pvr_user1,
+			cpuinfo.pvr_user2);
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	int i = *pos;
+
+	return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+	.start = c_start,
+	.next = c_next,
+	.stop = c_stop,
+	.show = show_cpuinfo,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/pvr.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/pvr.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/cpu/pvr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/cpu/pvr.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,81 @@
+/*
+ * Support for MicroBlaze PVR (processor version register)
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2007 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 archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <asm/system.h>
+#include <asm/exceptions.h>
+#include <asm/pvr.h>
+
+/*
+ * Until we get an assembler that knows about the pvr registers,
+ * this horrible cruft will have to do.
+ * That hardcoded opcode is mfs r3, rpvrNN
+ */
+
+#define get_single_pvr(pvrid, val)				\
+{								\
+	register unsigned tmp __asm__("r3");			\
+	tmp = 0x0;	/* Prevent warning about unused */	\
+	__asm__ __volatile__ (					\
+			".byte 0x94,0x60,0xa0, " #pvrid "\n\t"	\
+			: "=r" (tmp) : : "memory"); 		\
+	val = tmp;						\
+}
+
+/*
+ * Does the CPU support the PVR register?
+ * return value:
+ * 0: no PVR
+ * 1: simple PVR
+ * 2: full PVR
+ *
+ * This must work on all CPU versions, including those before the
+ * PVR was even an option.
+ */
+
+int cpu_has_pvr(void)
+{
+	unsigned flags;
+	unsigned pvr0;
+
+	local_save_flags(flags);
+
+	/* PVR bit in MSR tells us if there is any support */
+	if (!(flags & PVR_MSR_BIT))
+		return 0;
+
+	get_single_pvr(0x00, pvr0);
+	pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
+
+	if (pvr0 & PVR0_PVR_FULL_MASK)
+		return 1;
+
+	/* for partial PVR use static cpuinfo */
+	return 2;
+}
+
+void get_pvr(struct pvr_s *p)
+{
+	get_single_pvr(0, p->pvr[0]);
+	get_single_pvr(1, p->pvr[1]);
+	get_single_pvr(2, p->pvr[2]);
+	get_single_pvr(3, p->pvr[3]);
+	get_single_pvr(4, p->pvr[4]);
+	get_single_pvr(5, p->pvr[5]);
+	get_single_pvr(6, p->pvr[6]);
+	get_single_pvr(7, p->pvr[7]);
+	get_single_pvr(8, p->pvr[8]);
+	get_single_pvr(9, p->pvr[9]);
+	get_single_pvr(10, p->pvr[10]);
+	get_single_pvr(11, p->pvr[11]);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/early_printk.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/early_printk.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/early_printk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/early_printk.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * Early printk support for Microblaze.
+ *
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.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/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/io.h>
+#include <asm/processor.h>
+#include <linux/fcntl.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+
+static u32 early_console_initialized;
+static u32 base_addr;
+
+static void early_printk_putc(char c)
+{
+	/*
+	 * Limit how many times we'll spin waiting for TX FIFO status.
+	 * This will prevent lockups if the base address is incorrectly
+	 * set, or any other issue on the UARTLITE.
+	 * This limit is pretty arbitrary, unless we are at about 10 baud
+	 * we'll never timeout on a working UART.
+	 */
+
+	unsigned retries = 10000;
+	/* read status bit - 0x8 offset */
+	while (--retries && (in_be32(base_addr + 8) & (1 << 3)))
+		;
+
+	/* Only attempt the iowrite if we didn't timeout */
+	/* write to TX_FIFO - 0x4 offset */
+	if (retries)
+		out_be32(base_addr + 4, c & 0xff);
+}
+
+static void early_printk_write(struct console *unused,
+					const char *s, unsigned n)
+{
+	while (*s && n-- > 0) {
+		early_printk_putc(*s);
+		if (*s == '\n')
+			early_printk_putc('\r');
+		s++;
+	}
+}
+
+static struct console early_serial_console = {
+	.name = "earlyser",
+	.write = early_printk_write,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+};
+
+static struct console *early_console = &early_serial_console;
+
+void early_printk(const char *fmt, ...)
+{
+	char buf[512];
+	int n;
+	va_list ap;
+
+	if (early_console_initialized) {
+		va_start(ap, fmt);
+		n = vscnprintf(buf, 512, fmt, ap);
+		early_console->write(early_console, buf, n);
+		va_end(ap);
+	}
+}
+
+int __init setup_early_printk(char *opt)
+{
+	if (early_console_initialized)
+		return 1;
+
+	base_addr = early_uartlite_console();
+	if (base_addr) {
+		early_console_initialized = 1;
+		early_printk("early_printk_console is enabled at 0x%08x\n",
+							base_addr);
+
+		/* register_console(early_console); */
+
+		return 0;
+	} else
+		return 1;
+}
+
+void __init disable_early_printk(void)
+{
+	if (!early_console_initialized || !early_console)
+		return;
+	printk(KERN_WARNING "disabling early console\n");
+	unregister_console(early_console);
+	early_console_initialized = 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/entry-nommu.S linux-libre-2.6.30-gnu1/arch/microblaze/kernel/entry-nommu.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/entry-nommu.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/entry-nommu.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/entry.h>
+#include <asm/asm-offsets.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+#include <asm/percpu.h>
+#include <asm/signal.h>
+
+#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
+	.macro	disable_irq
+	msrclr r0, MSR_IE
+	.endm
+
+	.macro	enable_irq
+	msrset r0, MSR_IE
+	.endm
+
+	.macro	clear_bip
+	msrclr r0, MSR_BIP
+	.endm
+#else
+	.macro	disable_irq
+	mfs r11, rmsr
+	andi r11, r11, ~MSR_IE
+	mts rmsr, r11
+	.endm
+
+	.macro	enable_irq
+	mfs r11, rmsr
+	ori r11, r11, MSR_IE
+	mts rmsr, r11
+	.endm
+
+	.macro	clear_bip
+	mfs r11, rmsr
+	andi r11, r11, ~MSR_BIP
+	mts rmsr, r11
+	.endm
+#endif
+
+ENTRY(_interrupt)
+	swi	r1, r0, PER_CPU(ENTRY_SP)	/* save the current sp */
+	swi	r11, r0, PER_CPU(R11_SAVE)	/* temporarily save r11 */
+	lwi	r11, r0, PER_CPU(KM)		/* load mode indicator */
+	beqid	r11, 1f
+	nop
+	brid	2f				/* jump over */
+	addik	r1, r1, (-PT_SIZE)	/* room for pt_regs (delay slot) */
+1:						/* switch to kernel stack */
+	lwi	r1, r0, PER_CPU(CURRENT_SAVE)	/* get the saved current */
+	lwi	r1, r1, TS_THREAD_INFO		/* get the thread info */
+	/* calculate kernel stack pointer */
+	addik	r1, r1, THREAD_SIZE - PT_SIZE
+2:
+	swi	r11, r1, PT_MODE		/* store the mode */
+	lwi	r11, r0, PER_CPU(R11_SAVE)	/* reload r11 */
+	swi	r2, r1, PT_R2
+	swi	r3, r1, PT_R3
+	swi	r4, r1, PT_R4
+	swi	r5, r1, PT_R5
+	swi	r6, r1, PT_R6
+	swi	r7, r1, PT_R7
+	swi	r8, r1, PT_R8
+	swi	r9, r1, PT_R9
+	swi	r10, r1, PT_R10
+	swi	r11, r1, PT_R11
+	swi	r12, r1, PT_R12
+	swi	r13, r1, PT_R13
+	swi	r14, r1, PT_R14
+	swi	r14, r1, PT_PC
+	swi	r15, r1, PT_R15
+	swi	r16, r1, PT_R16
+	swi	r17, r1, PT_R17
+	swi	r18, r1, PT_R18
+	swi	r19, r1, PT_R19
+	swi	r20, r1, PT_R20
+	swi	r21, r1, PT_R21
+	swi	r22, r1, PT_R22
+	swi	r23, r1, PT_R23
+	swi	r24, r1, PT_R24
+	swi	r25, r1, PT_R25
+	swi	r26, r1, PT_R26
+	swi	r27, r1, PT_R27
+	swi	r28, r1, PT_R28
+	swi	r29, r1, PT_R29
+	swi	r30, r1, PT_R30
+	swi	r31, r1, PT_R31
+	/* special purpose registers */
+	mfs	r11, rmsr
+	swi	r11, r1, PT_MSR
+	mfs	r11, rear
+	swi	r11, r1, PT_EAR
+	mfs	r11, resr
+	swi	r11, r1, PT_ESR
+	mfs	r11, rfsr
+	swi	r11, r1, PT_FSR
+	/* reload original stack pointer and save it */
+	lwi	r11, r0, PER_CPU(ENTRY_SP)
+	swi	r11, r1, PT_R1
+	/* update mode indicator we are in kernel mode */
+	addik	r11, r0, 1
+	swi	r11, r0, PER_CPU(KM)
+	/* restore r31 */
+	lwi	r31, r0, PER_CPU(CURRENT_SAVE)
+	/* prepare the link register, the argument and jump */
+	la	r15, r0, ret_from_intr - 8
+	addk	r6, r0, r15
+	braid	do_IRQ
+	add	r5, r0, r1
+
+ret_from_intr:
+	lwi	r11, r1, PT_MODE
+	bneid	r11, 3f
+
+	lwi	r6, r31, TS_THREAD_INFO	/* get thread info */
+	lwi	r19, r6, TI_FLAGS	/* get flags in thread info */
+				/* do an extra work if any bits are set */
+
+	andi	r11, r19, _TIF_NEED_RESCHED
+	beqi	r11, 1f
+	bralid	r15, schedule
+	nop
+1:	andi	r11, r19, _TIF_SIGPENDING
+	beqid	r11, no_intr_reshed
+	addk	r5, r1, r0
+	addk	r7, r0, r0
+	bralid	r15, do_signal
+	addk	r6, r0, r0
+
+no_intr_reshed:
+	/* save mode indicator */
+	lwi	r11, r1, PT_MODE
+3:
+	swi	r11, r0, PER_CPU(KM)
+
+	/* save r31 */
+	swi	r31, r0, PER_CPU(CURRENT_SAVE)
+restore_context:
+	/* special purpose registers */
+	lwi	r11, r1, PT_FSR
+	mts	rfsr, r11
+	lwi	r11, r1, PT_ESR
+	mts	resr, r11
+	lwi	r11, r1, PT_EAR
+	mts	rear, r11
+	lwi	r11, r1, PT_MSR
+	mts	rmsr, r11
+
+	lwi	r31, r1, PT_R31
+	lwi	r30, r1, PT_R30
+	lwi	r29, r1, PT_R29
+	lwi	r28, r1, PT_R28
+	lwi	r27, r1, PT_R27
+	lwi	r26, r1, PT_R26
+	lwi	r25, r1, PT_R25
+	lwi	r24, r1, PT_R24
+	lwi	r23, r1, PT_R23
+	lwi	r22, r1, PT_R22
+	lwi	r21, r1, PT_R21
+	lwi	r20, r1, PT_R20
+	lwi	r19, r1, PT_R19
+	lwi	r18, r1, PT_R18
+	lwi	r17, r1, PT_R17
+	lwi	r16, r1, PT_R16
+	lwi	r15, r1, PT_R15
+	lwi	r14, r1, PT_PC
+	lwi	r13, r1, PT_R13
+	lwi	r12, r1, PT_R12
+	lwi	r11, r1, PT_R11
+	lwi	r10, r1, PT_R10
+	lwi	r9, r1, PT_R9
+	lwi	r8, r1, PT_R8
+	lwi	r7, r1, PT_R7
+	lwi	r6, r1, PT_R6
+	lwi	r5, r1, PT_R5
+	lwi	r4, r1, PT_R4
+	lwi	r3, r1, PT_R3
+	lwi	r2, r1, PT_R2
+	lwi	r1, r1, PT_R1
+	rtid	r14, 0
+	nop
+
+ENTRY(_reset)
+	brai	0;
+
+ENTRY(_user_exception)
+	swi	r1, r0, PER_CPU(ENTRY_SP)	/* save the current sp */
+	swi	r11, r0, PER_CPU(R11_SAVE)	/* temporarily save r11 */
+	lwi	r11, r0, PER_CPU(KM)		/* load mode indicator */
+	beqid	r11, 1f				/* Already in kernel mode? */
+	nop
+	brid	2f				/* jump over */
+	addik	r1, r1, (-PT_SIZE)	/* Room for pt_regs (delay slot) */
+1:						/* Switch to kernel stack */
+	lwi	r1, r0, PER_CPU(CURRENT_SAVE)	/* get the saved current */
+	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 */
+	/* save them on stack */
+	swi	r2, r1, PT_R2
+	swi	r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+	swi	r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+	swi	r5, r1, PT_R5
+	swi	r6, r1, PT_R6
+	swi	r7, r1, PT_R7
+	swi	r8, r1, PT_R8
+	swi	r9, r1, PT_R9
+	swi	r10, r1, PT_R10
+	swi	r11, r1, PT_R11
+	/* r12: _always_ in clobber list; see unistd.h */
+	swi	r12, r1, PT_R12
+	swi	r13, r1, PT_R13
+	/* r14: _always_ in clobber list; see unistd.h */
+	swi	r14, r1, PT_R14
+	/* but we want to return to the next inst. */
+	addik	r14, r14, 0x4
+	swi	r14, r1, PT_PC		/* increment by 4 and store in pc */
+	swi	r15, r1, PT_R15
+	swi	r16, r1, PT_R16
+	swi	r17, r1, PT_R17
+	swi	r18, r1, PT_R18
+	swi	r19, r1, PT_R19
+	swi	r20, r1, PT_R20
+	swi	r21, r1, PT_R21
+	swi	r22, r1, PT_R22
+	swi	r23, r1, PT_R23
+	swi	r24, r1, PT_R24
+	swi	r25, r1, PT_R25
+	swi	r26, r1, PT_R26
+	swi	r27, r1, PT_R27
+	swi	r28, r1, PT_R28
+	swi	r29, r1, PT_R29
+	swi	r30, r1, PT_R30
+	swi	r31, r1, PT_R31
+
+	disable_irq
+	nop		/* make sure IE bit is in effect */
+	clear_bip	/* once IE is in effect it is safe to clear BIP */
+	nop
+
+	/* special purpose registers */
+	mfs	r11, rmsr
+	swi	r11, r1, PT_MSR
+	mfs	r11, rear
+	swi	r11, r1, PT_EAR
+	mfs	r11, resr
+	swi	r11, r1, PT_ESR
+	mfs	r11, rfsr
+	swi	r11, r1, PT_FSR
+	/* reload original stack pointer and save it */
+	lwi	r11, r0, PER_CPU(ENTRY_SP)
+	swi	r11, r1, PT_R1
+	/* update mode indicator we are in kernel mode */
+	addik	r11, r0, 1
+	swi	r11, r0, PER_CPU(KM)
+	/* restore r31 */
+	lwi	r31, r0, PER_CPU(CURRENT_SAVE)
+	/* re-enable interrupts now we are in kernel mode */
+	enable_irq
+
+	/* See if the system call number is valid. */
+	addi	r11, r12, -__NR_syscalls
+	bgei	r11, 1f			/* return to user if not valid */
+	/* Figure out which function to use for this system call. */
+	/* Note Microblaze barrel shift is optional, so don't rely on it */
+	add	r12, r12, r12			/* convert num -> ptr */
+	add	r12, r12, r12
+	lwi	r12, r12, sys_call_table	/* Get function pointer */
+	la	r15, r0, ret_to_user-8		/* set return address */
+	bra	r12				/* Make the system call. */
+	bri	0				/* won't reach here */
+1:
+	brid	ret_to_user			/* jump to syscall epilogue */
+	addi	r3, r0, -ENOSYS			/* set errno in delay slot */
+
+/*
+ * Debug traps are like a system call, but entered via brki r14, 0x60
+ * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
+ * will handle the rest
+ */
+ENTRY(_debug_exception)
+	swi	r1, r0, PER_CPU(ENTRY_SP)	/* save the current sp */
+	lwi	r1, r0, PER_CPU(CURRENT_SAVE)	/* get the saved current */
+	lwi	r1, r1, TS_THREAD_INFO		/* get the thread info */
+	addik	r1, r1, THREAD_SIZE - PT_SIZE	/* get the kernel stack */
+	swi	r11, r0, PER_CPU(R11_SAVE)	/* temporarily save r11 */
+	lwi	r11, r0, PER_CPU(KM)		/* load mode indicator */
+//save_context:
+	swi	r11, r1, PT_MODE	/* store the mode */
+	lwi	r11, r0, PER_CPU(R11_SAVE)	/* reload r11 */
+	/* save them on stack */
+	swi	r2, r1, PT_R2
+	swi	r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
+	swi	r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
+	swi	r5, r1, PT_R5
+	swi	r6, r1, PT_R6
+	swi	r7, r1, PT_R7
+	swi	r8, r1, PT_R8
+	swi	r9, r1, PT_R9
+	swi	r10, r1, PT_R10
+	swi	r11, r1, PT_R11
+	/* r12: _always_ in clobber list; see unistd.h */
+	swi	r12, r1, PT_R12
+	swi	r13, r1, PT_R13
+	/* r14: _always_ in clobber list; see unistd.h */
+	swi	r14, r1, PT_R14
+	swi	r14, r1, PT_PC /* Will return to interrupted instruction */
+	swi	r15, r1, PT_R15
+	swi	r16, r1, PT_R16
+	swi	r17, r1, PT_R17
+	swi	r18, r1, PT_R18
+	swi	r19, r1, PT_R19
+	swi	r20, r1, PT_R20
+	swi	r21, r1, PT_R21
+	swi	r22, r1, PT_R22
+	swi	r23, r1, PT_R23
+	swi	r24, r1, PT_R24
+	swi	r25, r1, PT_R25
+	swi	r26, r1, PT_R26
+	swi	r27, r1, PT_R27
+	swi	r28, r1, PT_R28
+	swi	r29, r1, PT_R29
+	swi	r30, r1, PT_R30
+	swi	r31, r1, PT_R31
+
+	disable_irq
+	nop		/* make sure IE bit is in effect */
+	clear_bip	/* once IE is in effect it is safe to clear BIP */
+	nop
+
+	/* special purpose registers */
+	mfs	r11, rmsr
+	swi	r11, r1, PT_MSR
+	mfs	r11, rear
+	swi	r11, r1, PT_EAR
+	mfs	r11, resr
+	swi	r11, r1, PT_ESR
+	mfs	r11, rfsr
+	swi	r11, r1, PT_FSR
+	/* reload original stack pointer and save it */
+	lwi	r11, r0, PER_CPU(ENTRY_SP)
+	swi	r11, r1, PT_R1
+	/* update mode indicator we are in kernel mode */
+	addik	r11, r0, 1
+	swi	r11, r0, PER_CPU(KM)
+	/* restore r31 */
+	lwi	r31, r0, PER_CPU(CURRENT_SAVE)
+	/* re-enable interrupts now we are in kernel mode */
+	enable_irq
+
+	addi	r5, r0, SIGTRAP			/* sending the trap signal */
+	add	r6, r0, r31			/* to current */
+	bralid	r15, send_sig
+	add	r7, r0, r0			/* 3rd param zero */
+
+	/* Restore r3/r4 to work around how ret_to_user works */
+	lwi	r3, r1, PT_R3
+	lwi	r4, r1, PT_R4
+	bri	ret_to_user
+
+ENTRY(_break)
+	bri	0
+
+/* struct task_struct *_switch_to(struct thread_info *prev,
+					struct thread_info *next); */
+ENTRY(_switch_to)
+	/* prepare return value */
+	addk	r3, r0, r31
+
+	/* save registers in cpu_context */
+	/* use r11 and r12, volatile registers, as temp register */
+	addik	r11, r5, TI_CPU_CONTEXT
+	swi	r1, r11, CC_R1
+	swi	r2, r11, CC_R2
+	/* skip volatile registers.
+	 * they are saved on stack when we jumped to _switch_to() */
+	/* dedicated registers */
+	swi	r13, r11, CC_R13
+	swi	r14, r11, CC_R14
+	swi	r15, r11, CC_R15
+	swi	r16, r11, CC_R16
+	swi	r17, r11, CC_R17
+	swi	r18, r11, CC_R18
+	/* save non-volatile registers */
+	swi	r19, r11, CC_R19
+	swi	r20, r11, CC_R20
+	swi	r21, r11, CC_R21
+	swi	r22, r11, CC_R22
+	swi	r23, r11, CC_R23
+	swi	r24, r11, CC_R24
+	swi	r25, r11, CC_R25
+	swi	r26, r11, CC_R26
+	swi	r27, r11, CC_R27
+	swi	r28, r11, CC_R28
+	swi	r29, r11, CC_R29
+	swi	r30, r11, CC_R30
+	/* special purpose registers */
+	mfs	r12, rmsr
+	swi	r12, r11, CC_MSR
+	mfs	r12, rear
+	swi	r12, r11, CC_EAR
+	mfs	r12, resr
+	swi	r12, r11, CC_ESR
+	mfs	r12, rfsr
+	swi	r12, r11, CC_FSR
+
+	/* update r31, the current */
+	lwi	r31, r6, TI_TASK
+	swi	r31, r0, PER_CPU(CURRENT_SAVE)
+
+	/* get new process' cpu context and restore */
+	addik	r11, r6, TI_CPU_CONTEXT
+
+	/* special purpose registers */
+	lwi	r12, r11, CC_FSR
+	mts	rfsr, r12
+	lwi	r12, r11, CC_ESR
+	mts	resr, r12
+	lwi	r12, r11, CC_EAR
+	mts	rear, r12
+	lwi	r12, r11, CC_MSR
+	mts	rmsr, r12
+	/* non-volatile registers */
+	lwi	r30, r11, CC_R30
+	lwi	r29, r11, CC_R29
+	lwi	r28, r11, CC_R28
+	lwi	r27, r11, CC_R27
+	lwi	r26, r11, CC_R26
+	lwi	r25, r11, CC_R25
+	lwi	r24, r11, CC_R24
+	lwi	r23, r11, CC_R23
+	lwi	r22, r11, CC_R22
+	lwi	r21, r11, CC_R21
+	lwi	r20, r11, CC_R20
+	lwi	r19, r11, CC_R19
+	/* dedicated registers */
+	lwi	r18, r11, CC_R18
+	lwi	r17, r11, CC_R17
+	lwi	r16, r11, CC_R16
+	lwi	r15, r11, CC_R15
+	lwi	r14, r11, CC_R14
+	lwi	r13, r11, CC_R13
+	/* skip volatile registers */
+	lwi	r2, r11, CC_R2
+	lwi	r1, r11, CC_R1
+
+	rtsd	r15, 8
+	nop
+
+ENTRY(ret_from_fork)
+	addk	r5, r0, r3
+	addk	r6, r0, r1
+	brlid	r15, schedule_tail
+	nop
+	swi	r31, r1, PT_R31		/* save r31 in user context. */
+			/* will soon be restored to r31 in ret_to_user */
+	addk	r3, r0, r0
+	brid	ret_to_user
+	nop
+
+work_pending:
+	andi	r11, r19, _TIF_NEED_RESCHED
+	beqi	r11, 1f
+	bralid	r15, schedule
+	nop
+1:	andi	r11, r19, _TIF_SIGPENDING
+	beqi	r11, no_work_pending
+	addk	r5, r1, r0
+	addik	r7, r0, 1
+	bralid	r15, do_signal
+	addk	r6, r0, r0
+	bri	no_work_pending
+
+ENTRY(ret_to_user)
+	disable_irq
+
+	swi	r4, r1, PT_R4		/* return val */
+	swi	r3, r1, PT_R3		/* return val */
+
+	lwi	r6, r31, TS_THREAD_INFO /* get thread info */
+	lwi	r19, r6, TI_FLAGS /* get flags in thread info */
+	bnei	r19, work_pending /* do an extra work if any bits are set */
+no_work_pending:
+	disable_irq
+
+	/* save r31 */
+	swi	r31, r0, PER_CPU(CURRENT_SAVE)
+	/* save mode indicator */
+	lwi	r18, r1, PT_MODE
+	swi	r18, r0, PER_CPU(KM)
+//restore_context:
+	/* special purpose registers */
+	lwi	r18, r1, PT_FSR
+	mts	rfsr, r18
+	lwi	r18, r1, PT_ESR
+	mts	resr, r18
+	lwi	r18, r1, PT_EAR
+	mts	rear, r18
+	lwi	r18, r1, PT_MSR
+	mts	rmsr, r18
+
+	lwi	r31, r1, PT_R31
+	lwi	r30, r1, PT_R30
+	lwi	r29, r1, PT_R29
+	lwi	r28, r1, PT_R28
+	lwi	r27, r1, PT_R27
+	lwi	r26, r1, PT_R26
+	lwi	r25, r1, PT_R25
+	lwi	r24, r1, PT_R24
+	lwi	r23, r1, PT_R23
+	lwi	r22, r1, PT_R22
+	lwi	r21, r1, PT_R21
+	lwi	r20, r1, PT_R20
+	lwi	r19, r1, PT_R19
+	lwi	r18, r1, PT_R18
+	lwi	r17, r1, PT_R17
+	lwi	r16, r1, PT_R16
+	lwi	r15, r1, PT_R15
+	lwi	r14, r1, PT_PC
+	lwi	r13, r1, PT_R13
+	lwi	r12, r1, PT_R12
+	lwi	r11, r1, PT_R11
+	lwi	r10, r1, PT_R10
+	lwi	r9, r1, PT_R9
+	lwi	r8, r1, PT_R8
+	lwi	r7, r1, PT_R7
+	lwi	r6, r1, PT_R6
+	lwi	r5, r1, PT_R5
+	lwi	r4, r1, PT_R4		/* return val */
+	lwi	r3, r1, PT_R3		/* return val */
+	lwi	r2, r1, PT_R2
+	lwi	r1, r1, PT_R1
+
+	rtid	r14, 0
+	nop
+
+sys_vfork_wrapper:
+	brid	sys_vfork
+	addk	r5, r1, r0
+
+sys_clone_wrapper:
+	brid	sys_clone
+	addk	r7, r1, r0
+
+sys_execve_wrapper:
+	brid	sys_execve
+	addk	r8, r1, r0
+
+sys_sigreturn_wrapper:
+	brid	sys_sigreturn
+	addk	r5, r1, r0
+
+sys_rt_sigreturn_wrapper:
+	brid	sys_rt_sigreturn
+	addk	r5, r1, r0
+
+sys_sigsuspend_wrapper:
+	brid	sys_rt_sigsuspend
+	addk	r6, r1, r0
+
+sys_rt_sigsuspend_wrapper:
+	brid	sys_rt_sigsuspend
+	addk	r7, r1, r0
+
+	/* Interrupt vector table */
+	.section	.init.ivt, "ax"
+	.org 0x0
+	brai	_reset
+	brai	_user_exception
+	brai	_interrupt
+	brai	_break
+	brai	_hw_exception_handler
+	.org 0x60
+	brai	_debug_exception
+
+.section .rodata,"a"
+#include "syscall_table.S"
+
+syscall_table_size=(.-sys_call_table)
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/exceptions.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/exceptions.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/exceptions.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/exceptions.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * HW exception handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 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.
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+
+#include <asm/exceptions.h>
+#include <asm/entry.h>		/* For KM CPU var */
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+
+#define MICROBLAZE_ILL_OPCODE_EXCEPTION	0x02
+#define MICROBLAZE_IBUS_EXCEPTION	0x03
+#define MICROBLAZE_DBUS_EXCEPTION	0x04
+#define MICROBLAZE_DIV_ZERO_EXCEPTION	0x05
+#define MICROBLAZE_FPU_EXCEPTION	0x06
+#define MICROBLAZE_PRIVILEG_EXCEPTION	0x07
+
+static DEFINE_SPINLOCK(die_lock);
+
+void die(const char *str, struct pt_regs *fp, long err)
+{
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err);
+	show_regs(fp);
+	spin_unlock_irq(&die_lock);
+	/* do_exit() should take care of panic'ing from an interrupt
+	 * context so we don't handle it here
+	 */
+	do_exit(err);
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+	siginfo_t info;
+
+	if (kernel_mode(regs)) {
+		debugger(regs);
+		die("Exception in kernel mode", regs, signr);
+	}
+	info.si_signo = signr;
+	info.si_errno = 0;
+	info.si_code = code;
+	info.si_addr = (void __user *) addr;
+	force_sig_info(signr, &info, current);
+}
+
+asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
+							int fsr, int addr)
+{
+#if 0
+	printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n",
+			type, user_mode(regs) ? "user" : "kernel", fsr,
+			(unsigned int) regs->pc, (unsigned int) regs->esr);
+#endif
+
+	switch (type & 0x1F) {
+	case MICROBLAZE_ILL_OPCODE_EXCEPTION:
+		_exception(SIGILL, regs, ILL_ILLOPC, addr);
+		break;
+	case MICROBLAZE_IBUS_EXCEPTION:
+		if (user_mode(regs)) {
+			printk(KERN_WARNING "Instruction bus error exception in user mode.\n");
+			_exception(SIGBUS, regs, BUS_ADRERR, addr);
+			return;
+		}
+		printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n");
+		die("bus exception", regs, SIGBUS);
+		break;
+	case MICROBLAZE_DBUS_EXCEPTION:
+		if (user_mode(regs)) {
+			printk(KERN_WARNING "Data bus error exception in user mode.\n");
+			_exception(SIGBUS, regs, BUS_ADRERR, addr);
+			return;
+		}
+		printk(KERN_WARNING "Data bus error exception in kernel mode.\n");
+		die("bus exception", regs, SIGBUS);
+		break;
+	case MICROBLAZE_DIV_ZERO_EXCEPTION:
+		printk(KERN_WARNING "Divide by zero exception\n");
+		_exception(SIGILL, regs, ILL_ILLOPC, addr);
+		break;
+
+	case MICROBLAZE_FPU_EXCEPTION:
+		/* IEEE FP exception */
+		/* I removed fsr variable and use code var for storing fsr */
+		if (fsr & FSR_IO)
+			fsr = FPE_FLTINV;
+		else if (fsr & FSR_OF)
+			fsr = FPE_FLTOVF;
+		else if (fsr & FSR_UF)
+			fsr = FPE_FLTUND;
+		else if (fsr & FSR_DZ)
+			fsr = FPE_FLTDIV;
+		else if (fsr & FSR_DO)
+			fsr = FPE_FLTRES;
+		_exception(SIGFPE, regs, fsr, addr);
+		break;
+
+	default:
+		printk(KERN_WARNING "Unexpected exception %02x "
+			"PC=%08x in %s mode\n", type, (unsigned int) addr,
+			kernel_mode(regs) ? "kernel" : "user");
+	}
+	return;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/head.S linux-libre-2.6.30-gnu1/arch/microblaze/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/head.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+
+	.text
+ENTRY(_start)
+	mfs	r1, rmsr
+	andi	r1, r1, ~2
+	mts	rmsr, r1
+
+/* save fdt to kernel location */
+/* r7 stores pointer to fdt blob */
+	beqi	r7, no_fdt_arg
+	or	r11, r0, r0 /* incremment */
+	ori	r4, r0, TOPHYS(_fdt_start) /* save bram context */
+	ori	r3, r0, (0x4000 - 4)
+_copy_fdt:
+	lw	r12, r7, r11 /* r12 = r7 + r11 */
+	sw	r12, r4, r11 /* addr[r4 + r11] = r12 */
+	addik	r11, r11, 4 /* increment counting */
+	bgtid	r3, _copy_fdt /* loop for all entries */
+	addik	r3, r3, -4 /* descrement loop */
+no_fdt_arg:
+
+	/* Initialize small data anchors */
+	la	r13, r0, _KERNEL_SDA_BASE_
+	la	r2, r0, _KERNEL_SDA2_BASE_
+
+	/* Initialize stack pointer */
+	la	r1, r0, init_thread_union + THREAD_SIZE - 4
+
+	/* Initialize r31 with current task address */
+	la	r31, r0, init_task
+
+	/*
+	 * Call platform dependent initialize function.
+	 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
+	 * the function.
+	 */
+	la	r8, r0, machine_early_init
+	brald	r15, r8
+	nop
+
+	la	r15, r0, machine_halt
+	braid	start_kernel
+	nop
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/heartbeat.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/heartbeat.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/heartbeat.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/heartbeat.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/io.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+
+static unsigned int base_addr;
+
+void heartbeat(void)
+{
+	static unsigned int cnt, period, dist;
+
+	if (base_addr) {
+		if (cnt == 0 || cnt == dist)
+			out_be32(base_addr, 1);
+		else if (cnt == 7 || cnt == dist + 7)
+			out_be32(base_addr, 0);
+
+		if (++cnt > period) {
+			cnt = 0;
+			/*
+			 * The hyperbolic function below modifies the heartbeat
+			 * period length in dependency of the current (5min)
+			 * load. It goes through the points f(0)=126, f(1)=86,
+			 * f(5)=51, f(inf)->30.
+			 */
+			period = ((672 << FSHIFT) / (5 * avenrun[0] +
+						(7 << FSHIFT))) + 30;
+			dist = period / 4;
+		}
+	}
+}
+
+void setup_heartbeat(void)
+{
+	struct device_node *gpio = NULL;
+	int j;
+	char *gpio_list[] = {
+				"xlnx,xps-gpio-1.00.a",
+				"xlnx,opb-gpio-1.00.a",
+				NULL
+			};
+
+	for (j = 0; gpio_list[j] != NULL; j++) {
+		gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
+		if (gpio)
+			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 (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL))
+		out_be32(base_addr + 4, 0); /* GPIO is configured as output */
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/hw_exception_handler.S linux-libre-2.6.30-gnu1/arch/microblaze/kernel/hw_exception_handler.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/hw_exception_handler.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/hw_exception_handler.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,458 @@
+/*
+ * Exception handling for Microblaze
+ *
+ * Rewriten interrupt handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * uClinux customisation (C) 2005 John Williams
+ *
+ * MMU code derived from arch/ppc/kernel/head_4xx.S:
+ *	Copyright (C) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ *		Initial PowerPC version.
+ *	Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *		Rewritten for PReP
+ *	Copyright (C) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *		Low-level exception handers, MMU support, and rewrite.
+ *	Copyright (C) 1997 Dan Malek <dmalek@jlc.net>
+ *		PowerPC 8xx modifications.
+ *	Copyright (C) 1998-1999 TiVo, Inc.
+ *		PowerPC 403GCX modifications.
+ *	Copyright (C) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *		PowerPC 403GCX/405GP modifications.
+ *	Copyright 2000 MontaVista Software Inc.
+ *		PPC405 modifications
+ *	PowerPC 403GCX/405GP modifications.
+ *		Author: MontaVista Software, Inc.
+ *		frank_rowand@mvista.com or source@mvista.com
+ *		debbie_chu@mvista.com
+ *
+ * Original code
+ * Copyright (C) 2004 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+/*
+ * Here are the handlers which don't require enabling translation
+ * and calling other kernel code thus we can keep their design very simple
+ * and do all processing in real mode. All what they need is a valid current
+ * (that is an issue for the CONFIG_REGISTER_TASK_PTR case)
+ * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore
+ * these registers are saved/restored
+ * The handlers which require translation are in entry.S --KAA
+ *
+ * Microblaze HW Exception Handler
+ * - Non self-modifying exception handler for the following exception conditions
+ *   - Unalignment
+ *   - Instruction bus error
+ *   - Data bus error
+ *   - Illegal instruction opcode
+ *   - Divide-by-zero
+ *
+ * Note we disable interrupts during exception handling, otherwise we will
+ * possibly get multiple re-entrancy if interrupt handles themselves cause
+ * exceptions. JW
+ */
+
+#include <asm/exceptions.h>
+#include <asm/unistd.h>
+#include <asm/page.h>
+
+#include <asm/entry.h>
+#include <asm/current.h>
+#include <linux/linkage.h>
+
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/asm-offsets.h>
+
+/* Helpful Macros */
+#define EX_HANDLER_STACK_SIZ	(4*19)
+#define NUM_TO_REG(num)		r ## num
+
+#define LWREG_NOP			\
+	bri	ex_handler_unhandled;	\
+	nop;
+
+#define SWREG_NOP			\
+	bri	ex_handler_unhandled;	\
+	nop;
+
+/* FIXME this is weird - for noMMU kernel is not possible to use brid
+ * instruction which can shorten executed time
+ */
+
+/* r3 is the source */
+#define R3_TO_LWREG_V(regnum)				\
+	swi	r3, r1, 4 * regnum;				\
+	bri	ex_handler_done;
+
+/* r3 is the source */
+#define R3_TO_LWREG(regnum)				\
+	or	NUM_TO_REG (regnum), r0, r3;		\
+	bri	ex_handler_done;
+
+/* r3 is the target */
+#define SWREG_TO_R3_V(regnum)				\
+	lwi	r3, r1, 4 * regnum;				\
+	bri	ex_sw_tail;
+
+/* r3 is the target */
+#define SWREG_TO_R3(regnum)				\
+	or	r3, r0, NUM_TO_REG (regnum);		\
+	bri	ex_sw_tail;
+
+.extern other_exception_handler /* Defined in exception.c */
+
+/*
+ * hw_exception_handler - Handler for exceptions
+ *
+ * Exception handler notes:
+ * - Handles all exceptions
+ * - Does not handle unaligned exceptions during load into r17, r1, r0.
+ * - Does not handle unaligned exceptions during store from r17 (cannot be
+ *   done) and r1 (slows down common case)
+ *
+ *  Relevant register structures
+ *
+ *  EAR - |----|----|----|----|----|----|----|----|
+ *      - <  ##   32 bit faulting address     ##  >
+ *
+ *  ESR - |----|----|----|----|----| - | - |-----|-----|
+ *      -                            W   S   REG   EXC
+ *
+ *
+ * STACK FRAME STRUCTURE (for NO_MMU)
+ * ---------------------------------
+ *
+ *      +-------------+         + 0
+ *      |     MSR     |
+ *      +-------------+         + 4
+ *      |     r1      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |      .      |
+ *      |     r18     |
+ *      +-------------+         + 76
+ *      |      .      |
+ *      |      .      |
+ *
+ * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S
+ * which is used for storing register values - old style was, that value were
+ * stored in stack but in case of failure you lost information about register.
+ * Currently you can see register value in memory in specific place.
+ * In compare to with previous solution the speed should be the same.
+ *
+ * MMU exception handler has different handling compare to no MMU kernel.
+ * Exception handler use jump table for directing of what happen. For MMU kernel
+ * is this approach better because MMU relate exception are handled by asm code
+ * in this file. In compare to with MMU expect of unaligned exception
+ * is everything handled by C code.
+ */
+
+/*
+ * every of these handlers is entered having R3/4/5/6/11/current saved on stack
+ * and clobbered so care should be taken to restore them if someone is going to
+ * return from exception
+ */
+
+/* wrappers to restore state before coming to entry.S */
+
+.global _hw_exception_handler
+.section .text
+.align 4
+.ent _hw_exception_handler
+_hw_exception_handler:
+	addik	r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
+	swi	r3, r1, PT_R3
+	swi	r4, r1, PT_R4
+	swi	r5, r1, PT_R5
+	swi	r6, r1, PT_R6
+
+	mfs	r5, rmsr;
+	nop
+	swi	r5, r1, 0;
+	mfs	r4, rbtr	/* Save BTR before jumping to handler */
+	nop
+	mfs	r3, resr
+	nop
+
+	andi	r5, r3, 0x1000;		/* Check ESR[DS] */
+	beqi	r5, not_in_delay_slot;	/* Branch if ESR[DS] not set */
+	mfs	r17, rbtr;	/* ESR[DS] set - return address in BTR */
+	nop
+not_in_delay_slot:
+	swi	r17, r1, PT_R17
+
+	andi	r5, r3, 0x1F;		/* Extract ESR[EXC] */
+
+	/* Exceptions enabled here. This will allow nested exceptions */
+	mfs	r6, rmsr;
+	nop
+	swi	r6, r1, 0; /* RMSR_OFFSET */
+	ori	r6, r6, 0x100; /* Turn ON the EE bit */
+	andi	r6, r6, ~2; /* Disable interrupts */
+	mts	rmsr, r6;
+	nop
+
+	xori	r6, r5, 1; /* 00001 = Unaligned Exception */
+	/* Jump to unalignment exception handler */
+	beqi	r6, handle_unaligned_ex;
+
+handle_other_ex: /* Handle Other exceptions here */
+	/* Save other volatiles before we make procedure calls below */
+	swi	r7, r1, PT_R7
+	swi	r8, r1, PT_R8
+	swi	r9, r1, PT_R9
+	swi	r10, r1, PT_R10
+	swi	r11, r1, PT_R11
+	swi	r12, r1, PT_R12
+	swi	r14, r1, PT_R14
+	swi	r15, r1, PT_R15
+	swi	r18, r1, PT_R18
+
+	or	r5, r1, r0
+	andi	r6, r3, 0x1F; /* Load ESR[EC] */
+	lwi	r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */
+	swi	r7, r1, PT_MODE
+	mfs	r7, rfsr
+	nop
+	addk	r8, r17, r0; /* Load exception address */
+	bralid	r15, full_exception; /* Branch to the handler */
+	nop;
+
+	/*
+	 * Trigger execution of the signal handler by enabling
+	 * interrupts and calling an invalid syscall.
+	 */
+	mfs	r5, rmsr;
+	nop
+	ori	r5, r5, 2;
+	mts	rmsr, r5; /* enable interrupt */
+	nop
+	addi	r12, r0, __NR_syscalls;
+	brki	r14, 0x08;
+	mfs	r5, rmsr; /* disable interrupt */
+	nop
+	andi	r5, r5, ~2;
+	mts	rmsr, r5;
+	nop
+
+	lwi	r7, r1, PT_R7
+	lwi	r8, r1, PT_R8
+	lwi	r9, r1, PT_R9
+	lwi	r10, r1, PT_R10
+	lwi	r11, r1, PT_R11
+	lwi	r12, r1, PT_R12
+	lwi	r14, r1, PT_R14
+	lwi	r15, r1, PT_R15
+	lwi	r18, r1, PT_R18
+
+	bri	ex_handler_done; /* Complete exception handling */
+
+/* 0x01 - Unaligned data access exception
+ * This occurs when a word access is not aligned on a word boundary,
+ * or when a 16-bit access is not aligned on a 16-bit boundary.
+ * This handler perform the access, and returns, except for MMU when
+ * the unaligned address is last on a 4k page or the physical address is
+ * not found in the page table, in which case unaligned_data_trap is called.
+ */
+handle_unaligned_ex:
+	/* Working registers already saved: R3, R4, R5, R6
+	 *  R3 = ESR
+	 *  R4 = BTR
+	 */
+	mfs	r4, rear;
+	nop
+
+	andi	r6, r3, 0x3E0; /* Mask and extract the register operand */
+	srl	r6, r6; /* r6 >> 5 */
+	srl	r6, r6;
+	srl	r6, r6;
+	srl	r6, r6;
+	srl	r6, r6;
+	/* Store the register operand in a temporary location */
+	sbi	r6, r0, TOPHYS(ex_reg_op);
+
+	andi	r6, r3, 0x400; /* Extract ESR[S] */
+	bnei	r6, ex_sw;
+ex_lw:
+	andi	r6, r3, 0x800; /* Extract ESR[W] */
+	beqi	r6, ex_lhw;
+	lbui	r5, r4, 0; /* Exception address in r4 */
+	/* Load a word, byte-by-byte from destination address
+		and save it in tmp space */
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_0);
+	lbui	r5, r4, 1;
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_1);
+	lbui	r5, r4, 2;
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_2);
+	lbui	r5, r4, 3;
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_3);
+	/* Get the destination register value into r3 */
+	lwi	r3, r0, TOPHYS(ex_tmp_data_loc_0);
+	bri	ex_lw_tail;
+ex_lhw:
+	lbui	r5, r4, 0; /* Exception address in r4 */
+	/* Load a half-word, byte-by-byte from destination
+		address and save it in tmp space */
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_0);
+	lbui	r5, r4, 1;
+	sbi	r5, r0, TOPHYS(ex_tmp_data_loc_1);
+	/* Get the destination register value into r3 */
+	lhui	r3, r0, TOPHYS(ex_tmp_data_loc_0);
+ex_lw_tail:
+	/* Get the destination register number into r5 */
+	lbui	r5, r0, TOPHYS(ex_reg_op);
+	/* Form load_word jump table offset (lw_table + (8 * regnum)) */
+	la	r6, r0, TOPHYS(lw_table);
+	addk	r5, r5, r5;
+	addk	r5, r5, r5;
+	addk	r5, r5, r5;
+	addk	r5, r5, r6;
+	bra	r5;
+ex_lw_end: /* Exception handling of load word, ends */
+ex_sw:
+	/* Get the destination register number into r5 */
+	lbui	r5, r0, TOPHYS(ex_reg_op);
+	/* Form store_word jump table offset (sw_table + (8 * regnum)) */
+	la	r6, r0, TOPHYS(sw_table);
+	add	r5, r5, r5;
+	add	r5, r5, r5;
+	add	r5, r5, r5;
+	add	r5, r5, r6;
+	bra	r5;
+ex_sw_tail:
+	mfs	r6, resr;
+	nop
+	andi	r6, r6, 0x800; /* Extract ESR[W] */
+	beqi	r6, ex_shw;
+	/* Get the word - delay slot */
+	swi	r3, r0, TOPHYS(ex_tmp_data_loc_0);
+	/* Store the word, byte-by-byte into destination address */
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_0);
+	sbi	r3, r4, 0;
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_1);
+	sbi	r3, r4, 1;
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_2);
+	sbi	r3, r4, 2;
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_3);
+	sbi	r3, r4, 3;
+	bri	ex_handler_done;
+
+ex_shw:
+	/* Store the lower half-word, byte-by-byte into destination address */
+	swi	r3, r0, TOPHYS(ex_tmp_data_loc_0);
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_2);
+	sbi	r3, r4, 0;
+	lbui	r3, r0, TOPHYS(ex_tmp_data_loc_3);
+	sbi	r3, r4, 1;
+ex_sw_end: /* Exception handling of store word, ends. */
+
+ex_handler_done:
+	lwi	r5, r1, 0 /* RMSR */
+	mts	rmsr, r5
+	nop
+	lwi	r3, r1, PT_R3
+	lwi	r4, r1, PT_R4
+	lwi	r5, r1, PT_R5
+	lwi	r6, r1, PT_R6
+	lwi	r17, r1, PT_R17
+
+	rted	r17, 0
+	addik	r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */
+
+.end _hw_exception_handler
+
+ex_handler_unhandled:
+/* FIXME add handle function for unhandled exception - dump register */
+	bri 0
+
+.section .text
+.align 4
+lw_table:
+lw_r0:		R3_TO_LWREG	(0);
+lw_r1:		LWREG_NOP;
+lw_r2:		R3_TO_LWREG	(2);
+lw_r3:		R3_TO_LWREG_V	(3);
+lw_r4:		R3_TO_LWREG_V	(4);
+lw_r5:		R3_TO_LWREG_V	(5);
+lw_r6:		R3_TO_LWREG_V	(6);
+lw_r7:		R3_TO_LWREG	(7);
+lw_r8:		R3_TO_LWREG	(8);
+lw_r9:		R3_TO_LWREG	(9);
+lw_r10:		R3_TO_LWREG	(10);
+lw_r11:		R3_TO_LWREG	(11);
+lw_r12:		R3_TO_LWREG	(12);
+lw_r13:		R3_TO_LWREG	(13);
+lw_r14:		R3_TO_LWREG	(14);
+lw_r15:		R3_TO_LWREG	(15);
+lw_r16:		R3_TO_LWREG	(16);
+lw_r17:		LWREG_NOP;
+lw_r18:		R3_TO_LWREG	(18);
+lw_r19:		R3_TO_LWREG	(19);
+lw_r20:		R3_TO_LWREG	(20);
+lw_r21:		R3_TO_LWREG	(21);
+lw_r22:		R3_TO_LWREG	(22);
+lw_r23:		R3_TO_LWREG	(23);
+lw_r24:		R3_TO_LWREG	(24);
+lw_r25:		R3_TO_LWREG	(25);
+lw_r26:		R3_TO_LWREG	(26);
+lw_r27:		R3_TO_LWREG	(27);
+lw_r28:		R3_TO_LWREG	(28);
+lw_r29:		R3_TO_LWREG	(29);
+lw_r30:		R3_TO_LWREG	(30);
+lw_r31:		R3_TO_LWREG	(31);
+
+sw_table:
+sw_r0:		SWREG_TO_R3	(0);
+sw_r1:		SWREG_NOP;
+sw_r2:		SWREG_TO_R3	(2);
+sw_r3:		SWREG_TO_R3_V	(3);
+sw_r4:		SWREG_TO_R3_V	(4);
+sw_r5:		SWREG_TO_R3_V	(5);
+sw_r6:		SWREG_TO_R3_V	(6);
+sw_r7:		SWREG_TO_R3	(7);
+sw_r8:		SWREG_TO_R3	(8);
+sw_r9:		SWREG_TO_R3	(9);
+sw_r10:		SWREG_TO_R3	(10);
+sw_r11:		SWREG_TO_R3	(11);
+sw_r12:		SWREG_TO_R3	(12);
+sw_r13:		SWREG_TO_R3	(13);
+sw_r14:		SWREG_TO_R3	(14);
+sw_r15:		SWREG_TO_R3	(15);
+sw_r16:		SWREG_TO_R3	(16);
+sw_r17:		SWREG_NOP;
+sw_r18:		SWREG_TO_R3	(18);
+sw_r19:		SWREG_TO_R3	(19);
+sw_r20:		SWREG_TO_R3	(20);
+sw_r21:		SWREG_TO_R3	(21);
+sw_r22:		SWREG_TO_R3	(22);
+sw_r23:		SWREG_TO_R3	(23);
+sw_r24:		SWREG_TO_R3	(24);
+sw_r25:		SWREG_TO_R3	(25);
+sw_r26:		SWREG_TO_R3	(26);
+sw_r27:		SWREG_TO_R3	(27);
+sw_r28:		SWREG_TO_R3	(28);
+sw_r29:		SWREG_TO_R3	(29);
+sw_r30:		SWREG_TO_R3	(30);
+sw_r31:		SWREG_TO_R3	(31);
+
+/* Temporary data structures used in the handler */
+.section .data
+.align 4
+ex_tmp_data_loc_0:
+	.byte 0
+ex_tmp_data_loc_1:
+	.byte 0
+ex_tmp_data_loc_2:
+	.byte 0
+ex_tmp_data_loc_3:
+	.byte 0
+ex_reg_op:
+	.byte 0
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/init_task.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/init_task.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/init_task.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/init_task.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"))) =
+{ INIT_THREAD_INFO(init_task) };
+
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/intc.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/intc.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/intc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/intc.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/irq.h>
+#include <asm/page.h>
+#include <linux/io.h>
+
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_SELFMOD_INTC
+#include <asm/selfmod.h>
+#define INTC_BASE	BARRIER_BASE_ADDR
+#else
+static unsigned int intc_baseaddr;
+#define INTC_BASE	intc_baseaddr
+#endif
+
+unsigned int nr_irq;
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0x00			/* Interrupt Status Register */
+#define IPR 0x04			/* Interrupt Pending Register */
+#define IER 0x08			/* Interrupt Enable Register */
+#define IAR 0x0c			/* Interrupt Acknowledge Register */
+#define SIE 0x10			/* Set Interrupt Enable bits */
+#define CIE 0x14			/* Clear Interrupt Enable bits */
+#define IVR 0x18			/* Interrupt Vector Register */
+#define MER 0x1c			/* Master Enable Register */
+
+#define MER_ME (1<<0)
+#define MER_HIE (1<<1)
+
+static void intc_enable_or_unmask(unsigned int irq)
+{
+	pr_debug("enable_or_unmask: %d\n", irq);
+	out_be32(INTC_BASE + SIE, 1 << irq);
+}
+
+static void intc_disable_or_mask(unsigned int irq)
+{
+	pr_debug("disable: %d\n", irq);
+	out_be32(INTC_BASE + CIE, 1 << irq);
+}
+
+static void intc_ack(unsigned int irq)
+{
+	pr_debug("ack: %d\n", irq);
+	out_be32(INTC_BASE + IAR, 1 << irq);
+}
+
+static void intc_mask_ack(unsigned int irq)
+{
+	unsigned long mask = 1 << irq;
+	pr_debug("disable_and_ack: %d\n", irq);
+	out_be32(INTC_BASE + CIE, mask);
+	out_be32(INTC_BASE + IAR, mask);
+}
+
+static void intc_end(unsigned int irq)
+{
+	unsigned long mask = 1 << irq;
+	pr_debug("end: %d\n", irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		out_be32(INTC_BASE + SIE, mask);
+		/* ack level sensitive intr */
+		if (irq_desc[irq].status & IRQ_LEVEL)
+			out_be32(INTC_BASE + IAR, mask);
+	}
+}
+
+static struct irq_chip intc_dev = {
+	.name = "Xilinx INTC",
+	.unmask = intc_enable_or_unmask,
+	.mask = intc_disable_or_mask,
+	.ack = intc_ack,
+	.mask_ack = intc_mask_ack,
+	.end = intc_end,
+};
+
+unsigned int get_irq(struct pt_regs *regs)
+{
+	int irq;
+
+	/*
+	 * NOTE: This function is the one that needs to be improved in
+	 * order to handle multiple interrupt controllers. It currently
+	 * is hardcoded to check for interrupts only on the first INTC.
+	 */
+	irq = in_be32(INTC_BASE + IVR);
+	pr_debug("get_irq: %d\n", irq);
+
+	return irq;
+}
+
+void __init init_IRQ(void)
+{
+	u32 i, j, intr_type;
+	struct device_node *intc = NULL;
+#ifdef CONFIG_SELFMOD_INTC
+	unsigned int intc_baseaddr = 0;
+	static int arr_func[] = {
+				(int)&get_irq,
+				(int)&intc_enable_or_unmask,
+				(int)&intc_disable_or_mask,
+				(int)&intc_mask_ack,
+				(int)&intc_ack,
+				(int)&intc_end,
+				0
+			};
+#endif
+	static char *intc_list[] = {
+				"xlnx,xps-intc-1.00.a",
+				"xlnx,opb-intc-1.00.c",
+				"xlnx,opb-intc-1.00.b",
+				"xlnx,opb-intc-1.00.a",
+				NULL
+			};
+
+	for (j = 0; intc_list[j] != NULL; j++) {
+		intc = of_find_compatible_node(NULL, NULL, intc_list[j]);
+		if (intc)
+			break;
+	}
+
+	intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
+	intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
+	nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
+
+	intr_type =
+		*(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
+	if (intr_type >= (1 << (nr_irq + 1)))
+		printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
+
+#ifdef CONFIG_SELFMOD_INTC
+	selfmod_function((int *) arr_func, intc_baseaddr);
+#endif
+	printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
+		intc_list[j], intc_baseaddr, nr_irq, intr_type);
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicity requested.
+	 */
+	out_be32(intc_baseaddr + IER, 0);
+
+	/* Acknowledge any pending interrupts just in case. */
+	out_be32(intc_baseaddr + IAR, 0xffffffff);
+
+	/* Turn on the Master Enable. */
+	out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
+
+	for (i = 0; i < nr_irq; ++i) {
+		if (intr_type & (0x00000001 << i)) {
+			set_irq_chip_and_handler_name(i, &intc_dev,
+				handle_edge_irq, intc_dev.name);
+			irq_desc[i].status &= ~IRQ_LEVEL;
+		} else {
+			set_irq_chip_and_handler_name(i, &intc_dev,
+				handle_level_irq, intc_dev.name);
+			irq_desc[i].status |= IRQ_LEVEL;
+		}
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/irq.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/kernel.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/irqflags.h>
+#include <linux/seq_file.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+
+#include <asm/prom.h>
+
+unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+{
+	struct of_irq oirq;
+
+	if (of_irq_map_one(dev, index, &oirq))
+		return NO_IRQ;
+
+	return oirq.specifier[0];
+}
+EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+
+/*
+ * '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(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
+}
+
+static u32 concurrent_irq;
+
+void do_IRQ(struct pt_regs *regs)
+{
+	unsigned int irq;
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	irq_enter();
+	irq = get_irq(regs);
+next_irq:
+	BUG_ON(irq == -1U);
+	generic_handle_irq(irq);
+
+	irq = get_irq(regs);
+	if (irq != -1U) {
+		pr_debug("next irq: %d\n", irq);
+		++concurrent_irq;
+		goto next_irq;
+	}
+
+	irq_exit();
+	set_irq_regs(old_regs);
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v, j;
+	struct irqaction *action;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_printf(p, "		");
+		for_each_online_cpu(j)
+			seq_printf(p, "CPU%-8d", j);
+		seq_putc(p, '\n');
+	}
+
+	if (i < nr_irq) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action)
+			goto skip;
+		seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+		seq_printf(p, " %8s", irq_desc[i].status &
+					IRQ_LEVEL ? "level" : "edge");
+		seq_printf(p, " %8s", irq_desc[i].chip->name);
+		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(&irq_desc[i].lock, flags);
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#
+# Makefile
+#
+
+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
+
+obj-y += cpu/
+
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_SELFMOD)		+= selfmod.o
+obj-$(CONFIG_HEART_BEAT)	+= heartbeat.o
+obj-$(CONFIG_MODULES)		+= microblaze_ksyms.o module.o
+
+obj-y	+= entry$(MMUEXT).o
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/microblaze_ksyms.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/microblaze_ksyms.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/microblaze_ksyms.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ *
+ * This program is free software; you can 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/string.h>
+#include <linux/cryptohash.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/syscalls.h>
+
+#include <asm/checksum.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <linux/uaccess.h>
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+EXPORT_SYMBOL(__ashldi3);
+extern void __ashrdi3(void);
+EXPORT_SYMBOL(__ashrdi3);
+extern void __divsi3(void);
+EXPORT_SYMBOL(__divsi3);
+extern void __lshrdi3(void);
+EXPORT_SYMBOL(__lshrdi3);
+extern void __modsi3(void);
+EXPORT_SYMBOL(__modsi3);
+extern void __mulsi3(void);
+EXPORT_SYMBOL(__mulsi3);
+extern void __muldi3(void);
+EXPORT_SYMBOL(__muldi3);
+extern void __ucmpdi2(void);
+EXPORT_SYMBOL(__ucmpdi2);
+extern void __udivsi3(void);
+EXPORT_SYMBOL(__udivsi3);
+extern void __umodsi3(void);
+EXPORT_SYMBOL(__umodsi3);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/module.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/module.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/module.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/module.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ *
+ * This program is free software; you can 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/moduleloader.h>
+#include <linux/kernel.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+
+#include <asm/pgtable.h>
+
+void *module_alloc(unsigned long size)
+{
+	void *ret;
+	ret = (size == 0) ? NULL : vmalloc(size);
+	pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
+	return ret;
+}
+
+void module_free(struct module *module, void *region)
+{
+	pr_debug("module_free(%s,%08lx)\n", module->name,
+					(unsigned long)region);
+	vfree(region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+				Elf_Shdr *sechdrs,
+				char *secstrings,
+				struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
+	unsigned int symindex, unsigned int relsec, struct module *module)
+{
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+		module->name);
+	return -ENOEXEC;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+	unsigned int symindex, unsigned int relsec, struct module *module)
+{
+
+	unsigned int i;
+	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	unsigned long int *location;
+	unsigned long int locoffs;
+	unsigned long int value;
+#if __GNUC__ < 4
+	unsigned long int old_value;
+#endif
+
+	pr_debug("Applying add relocation section %u to %u\n",
+		relsec, sechdrs[relsec].sh_info);
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
+				rela[i].r_offset;
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
+			ELF32_R_SYM(rela[i].r_info);
+		value = sym->st_value + rela[i].r_addend;
+
+		switch (ELF32_R_TYPE(rela[i].r_info)) {
+
+		/*
+		 * Be careful! mb-gcc / mb-ld splits the relocs between the
+		 * text and the reloc table. In general this means we must
+		 * read the current contents of (*location), add any offset
+		 * then store the result back in
+		 */
+
+		case R_MICROBLAZE_32:
+#if __GNUC__ < 4
+			old_value = *location;
+			*location = value + old_value;
+
+			pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n",
+				old_value, value);
+#else
+			*location = value;
+#endif
+			break;
+
+		case R_MICROBLAZE_64:
+#if __GNUC__ < 4
+			/* Split relocs only required/used pre gcc4.1.1 */
+			old_value = ((location[0] & 0x0000FFFF) << 16) |
+					(location[1] & 0x0000FFFF);
+			value += old_value;
+#endif
+			location[0] = (location[0] & 0xFFFF0000) |
+					(value >> 16);
+			location[1] = (location[1] & 0xFFFF0000) |
+					(value & 0xFFFF);
+#if __GNUC__ < 4
+			pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n",
+				old_value, value);
+#endif
+			break;
+
+		case R_MICROBLAZE_64_PCREL:
+			locoffs = (location[0] & 0xFFFF) << 16 |
+				(location[1] & 0xFFFF);
+			value -= (unsigned long int)(location) + 4 +
+				locoffs;
+			location[0] = (location[0] & 0xFFFF0000) |
+					(value >> 16);
+			location[1] = (location[1] & 0xFFFF0000) |
+					(value & 0xFFFF);
+			pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n",
+				value);
+			break;
+
+		case R_MICROBLAZE_NONE:
+			pr_debug("R_MICROBLAZE_NONE\n");
+			break;
+
+		default:
+			printk(KERN_ERR "module %s: "
+				"Unknown relocation: %u\n",
+				module->name,
+				ELF32_R_TYPE(rela->r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+		struct module *module)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/of_device.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/of_device.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/of_device.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/of_device.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,113 @@
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+
+#include <linux/errno.h>
+
+void of_device_make_bus_id(struct of_device *dev)
+{
+	static atomic_t bus_no_reg_magic;
+	struct device_node *node = dev->node;
+	const u32 *reg;
+	u64 addr;
+	int magic;
+
+	/*
+	 * For MMIO, get the physical address
+	 */
+	reg = of_get_property(node, "reg", NULL);
+	if (reg) {
+		addr = of_translate_address(node, reg);
+		if (addr != OF_BAD_ADDR) {
+			dev_set_name(&dev->dev, "%llx.%s",
+				     (unsigned long long)addr, node->name);
+			return;
+		}
+	}
+
+	/*
+	 * No BusID, use the node name and add a globally incremented
+	 * counter (and pray...)
+	 */
+	magic = atomic_add_return(1, &bus_no_reg_magic);
+	dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
+}
+EXPORT_SYMBOL(of_device_make_bus_id);
+
+struct of_device *of_device_alloc(struct device_node *np,
+				  const char *bus_id,
+				  struct device *parent)
+{
+	struct of_device *dev;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	dev->node = of_node_get(np);
+	dev->dev.dma_mask = &dev->dma_mask;
+	dev->dev.parent = parent;
+	dev->dev.release = of_release_dev;
+	dev->dev.archdata.of_node = np;
+
+	if (bus_id)
+		dev_set_name(&dev->dev, bus_id);
+	else
+		of_device_make_bus_id(dev);
+
+	return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
+int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct of_device *ofdev;
+	const char *compat;
+	int seen = 0, cplen, sl;
+
+	if (!dev)
+		return -ENODEV;
+
+	ofdev = to_of_device(dev);
+
+	if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
+		return -ENOMEM;
+
+	if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
+		return -ENOMEM;
+
+	/* Since the compatible field can contain pretty much anything
+	 * it's not really legal to split it out with commas. We split it
+	 * up using a number of environment variables instead. */
+
+	compat = of_get_property(ofdev->node, "compatible", &cplen);
+	while (compat && *compat && cplen > 0) {
+		if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
+			return -ENOMEM;
+
+		sl = strlen(compat) + 1;
+		compat += sl;
+		cplen -= sl;
+		seen++;
+	}
+
+	if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
+		return -ENOMEM;
+
+	/* modalias is trickier, we add it in 2 steps */
+	if (add_uevent_var(env, "MODALIAS="))
+		return -ENOMEM;
+	sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
+				    sizeof(env->buf) - env->buflen);
+	if (sl >= (sizeof(env->buf) - env->buflen))
+		return -ENOMEM;
+	env->buflen += sl;
+
+	return 0;
+}
+EXPORT_SYMBOL(of_device_uevent);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/of_platform.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/of_platform.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/of_platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/of_platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,201 @@
+/*
+ *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *			 <benh@kernel.crashing.org>
+ *    and		 Arnd Bergmann, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/errno.h>
+#include <linux/topology.h>
+#include <asm/atomic.h>
+
+struct bus_type of_platform_bus_type = {
+       .uevent	= of_device_uevent,
+};
+EXPORT_SYMBOL(of_platform_bus_type);
+
+static int __init of_bus_driver_init(void)
+{
+	return of_bus_type_init(&of_platform_bus_type, "of_platform");
+}
+postcore_initcall(of_bus_driver_init);
+
+struct of_device *of_platform_device_create(struct device_node *np,
+					    const char *bus_id,
+					    struct device *parent)
+{
+	struct of_device *dev;
+
+	dev = of_device_alloc(np, bus_id, parent);
+	if (!dev)
+		return NULL;
+
+	dev->dma_mask = 0xffffffffUL;
+	dev->dev.bus = &of_platform_bus_type;
+
+	/* We do not fill the DMA ops for platform devices by default.
+	 * This is currently the responsibility of the platform code
+	 * to do such, possibly using a device notifier
+	 */
+
+	if (of_device_register(dev) != 0) {
+		of_device_free(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL(of_platform_device_create);
+
+/**
+ * of_platform_bus_create - Create an OF device for a bus node and all its
+ * children. Optionally recursively instanciate matching busses.
+ * @bus: device node of the bus to instanciate
+ * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
+ * disallow recursive creation of child busses
+ */
+static int of_platform_bus_create(const struct device_node *bus,
+				  const struct of_device_id *matches,
+				  struct device *parent)
+{
+	struct device_node *child;
+	struct of_device *dev;
+	int rc = 0;
+
+	for_each_child_of_node(bus, child) {
+		pr_debug("   create child: %s\n", child->full_name);
+		dev = of_platform_device_create(child, NULL, parent);
+		if (dev == NULL)
+			rc = -ENOMEM;
+		else if (!of_match_node(matches, child))
+			continue;
+		if (rc == 0) {
+			pr_debug("   and sub busses\n");
+			rc = of_platform_bus_create(child, matches, &dev->dev);
+		}
+		if (rc) {
+			of_node_put(child);
+			break;
+		}
+	}
+	return rc;
+}
+
+
+/**
+ * of_platform_bus_probe - Probe the device-tree for platform busses
+ * @root: parent of the first level to probe or NULL for the root of the tree
+ * @matches: match table, NULL to use the default
+ * @parent: parent to hook devices from, NULL for toplevel
+ *
+ * Note that children of the provided root are not instanciated as devices
+ * unless the specified root itself matches the bus list and is not NULL.
+ */
+
+int of_platform_bus_probe(struct device_node *root,
+			  const struct of_device_id *matches,
+			  struct device *parent)
+{
+	struct device_node *child;
+	struct of_device *dev;
+	int rc = 0;
+
+	if (matches == NULL)
+		matches = of_default_bus_ids;
+	if (matches == OF_NO_DEEP_PROBE)
+		return -EINVAL;
+	if (root == NULL)
+		root = of_find_node_by_path("/");
+	else
+		of_node_get(root);
+
+	pr_debug("of_platform_bus_probe()\n");
+	pr_debug(" starting at: %s\n", root->full_name);
+
+	/* Do a self check of bus type, if there's a match, create
+	 * children
+	 */
+	if (of_match_node(matches, root)) {
+		pr_debug(" root match, create all sub devices\n");
+		dev = of_platform_device_create(root, NULL, parent);
+		if (dev == NULL) {
+			rc = -ENOMEM;
+			goto bail;
+		}
+		pr_debug(" create all sub busses\n");
+		rc = of_platform_bus_create(root, matches, &dev->dev);
+		goto bail;
+	}
+	for_each_child_of_node(root, child) {
+		if (!of_match_node(matches, child))
+			continue;
+
+		pr_debug("  match: %s\n", child->full_name);
+		dev = of_platform_device_create(child, NULL, parent);
+		if (dev == NULL)
+			rc = -ENOMEM;
+		else
+			rc = of_platform_bus_create(child, matches, &dev->dev);
+		if (rc) {
+			of_node_put(child);
+			break;
+		}
+	}
+ bail:
+	of_node_put(root);
+	return rc;
+}
+EXPORT_SYMBOL(of_platform_bus_probe);
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return to_of_device(dev)->node == data;
+}
+
+struct of_device *of_find_device_by_node(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&of_platform_bus_type,
+			      NULL, np, of_dev_node_match);
+	if (dev)
+		return to_of_device(dev);
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_node);
+
+static int of_dev_phandle_match(struct device *dev, void *data)
+{
+	phandle *ph = data;
+	return to_of_device(dev)->node->linux_phandle == *ph;
+}
+
+struct of_device *of_find_device_by_phandle(phandle ph)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&of_platform_bus_type,
+			      NULL, &ph, of_dev_phandle_match);
+	if (dev)
+		return to_of_device(dev);
+	return NULL;
+}
+EXPORT_SYMBOL(of_find_device_by_phandle);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/process.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/process.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/tick.h>
+#include <linux/bitops.h>
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+
+void show_regs(struct pt_regs *regs)
+{
+	printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->pt_mode);
+	printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n",
+				regs->r1, regs->r2, regs->r3, regs->r4);
+	printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n",
+				regs->r5, regs->r6, regs->r7, regs->r8);
+	printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n",
+				regs->r9, regs->r10, regs->r11, regs->r12);
+	printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n",
+				regs->r13, regs->r14, regs->r15, regs->r16);
+	printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n",
+				regs->r17, regs->r18, regs->r19, regs->r20);
+	printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n",
+				regs->r21, regs->r22, regs->r23, regs->r24);
+	printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n",
+				regs->r25, regs->r26, regs->r27, regs->r28);
+	printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n",
+				regs->r29, regs->r30, regs->r31, regs->pc);
+	printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n",
+				regs->msr, regs->ear, regs->esr, regs->fsr);
+}
+
+void (*pm_idle)(void);
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+static int hlt_counter = 1;
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+EXPORT_SYMBOL(enable_hlt);
+
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 1;
+}
+__setup("hlt", hlt_setup);
+
+void default_idle(void)
+{
+	if (!hlt_counter) {
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+		smp_mb__after_clear_bit();
+		local_irq_disable();
+		while (!need_resched())
+			cpu_sleep();
+		local_irq_enable();
+		set_thread_flag(TIF_POLLING_NRFLAG);
+	} else
+		while (!need_resched())
+			cpu_relax();
+}
+
+void cpu_idle(void)
+{
+	set_thread_flag(TIF_POLLING_NRFLAG);
+
+	/* endless idle loop with no priority at all */
+	while (1) {
+		void (*idle)(void) = pm_idle;
+
+		if (!idle)
+			idle = default_idle;
+
+		tick_nohz_stop_sched_tick(1);
+		while (!need_resched())
+			idle();
+		tick_nohz_restart_sched_tick();
+
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+		check_pgt_cache();
+	}
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+		unsigned long unused,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs = task_pt_regs(p);
+	struct thread_info *ti = task_thread_info(p);
+
+	*childregs = *regs;
+	if (user_mode(regs))
+		childregs->r1 = usp;
+	else
+		childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
+
+	memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
+	ti->cpu_context.r1 = (unsigned long)childregs;
+	ti->cpu_context.msr = (unsigned long)childregs->msr;
+	ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
+
+	if (clone_flags & CLONE_SETTLS)
+		;
+
+	return 0;
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	struct cpu_context *ctx =
+		&(((struct thread_info *)(tsk->stack))->cpu_context);
+
+	/* Check whether the thread is blocked in resume() */
+	if (in_sched_functions(ctx->r15))
+		return (unsigned long)ctx->r15;
+	else
+		return ctx->r14;
+}
+
+static void kernel_thread_helper(int (*fn)(void *), void *arg)
+{
+	fn(arg);
+	do_exit(-1);
+}
+
+int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+	/* store them in non-volatile registers */
+	regs.r5 = (unsigned long)fn;
+	regs.r6 = (unsigned long)arg;
+	local_save_flags(regs.msr);
+	regs.pc = (unsigned long)kernel_thread_helper;
+	regs.pt_mode = 1;
+
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+			&regs, 0, NULL, NULL);
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+/* TBD (used by procfs) */
+	return 0;
+}
+
+/* Set up a thread for executing a new program */
+void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
+{
+	set_fs(USER_DS);
+	regs->pc = pc;
+	regs->r1 = usp;
+	regs->pt_mode = 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/prom.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/prom.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/prom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/prom.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1146 @@
+/*
+ * Procedures for creating, accessing and interpreting the device tree.
+ *
+ * Paul Mackerras	August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ *    {engebret|bergner}@us.ibm.com
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/debugfs.h>
+#include <linux/irq.h>
+#include <linux/lmb.h>
+
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/pci-bridge.h>
+
+static int __initdata dt_root_addr_cells;
+static int __initdata dt_root_size_cells;
+
+typedef u32 cell_t;
+
+static struct boot_param_header *initial_boot_params;
+
+/* export that to outside world */
+struct device_node *of_chosen;
+
+static inline char *find_flat_dt_string(u32 offset)
+{
+	return ((char *)initial_boot_params) +
+		initial_boot_params->off_dt_strings + offset;
+}
+
+/**
+ * This function is used to scan the flattened device-tree, it is
+ * used to extract the memory informations at boot before we can
+ * unflatten the tree
+ */
+int __init of_scan_flat_dt(int (*it)(unsigned long node,
+				     const char *uname, int depth,
+				     void *data),
+			   void *data)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		initial_boot_params->off_dt_struct;
+	int rc = 0;
+	int depth = -1;
+
+	do {
+		u32 tag = *((u32 *)p);
+		char *pathp;
+
+		p += 4;
+		if (tag == OF_DT_END_NODE) {
+			depth--;
+			continue;
+		}
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag == OF_DT_END)
+			break;
+		if (tag == OF_DT_PROP) {
+			u32 sz = *((u32 *)p);
+			p += 8;
+			if (initial_boot_params->version < 0x10)
+				p = _ALIGN(p, sz >= 8 ? 8 : 4);
+			p += sz;
+			p = _ALIGN(p, 4);
+			continue;
+		}
+		if (tag != OF_DT_BEGIN_NODE) {
+			printk(KERN_WARNING "Invalid tag %x scanning flattened"
+				" device tree !\n", tag);
+			return -EINVAL;
+		}
+		depth++;
+		pathp = (char *)p;
+		p = _ALIGN(p + strlen(pathp) + 1, 4);
+		if ((*pathp) == '/') {
+			char *lp, *np;
+			for (lp = NULL, np = pathp; *np; np++)
+				if ((*np) == '/')
+					lp = np+1;
+			if (lp != NULL)
+				pathp = lp;
+		}
+		rc = it(p, pathp, depth, data);
+		if (rc != 0)
+			break;
+	} while (1);
+
+	return rc;
+}
+
+unsigned long __init of_get_flat_dt_root(void)
+{
+	unsigned long p = ((unsigned long)initial_boot_params) +
+		initial_boot_params->off_dt_struct;
+
+	while (*((u32 *)p) == OF_DT_NOP)
+		p += 4;
+	BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
+	p += 4;
+	return _ALIGN(p + strlen((char *)p) + 1, 4);
+}
+
+/**
+ * This function can be used within scan_flattened_dt callback to get
+ * access to properties
+ */
+void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
+				unsigned long *size)
+{
+	unsigned long p = node;
+
+	do {
+		u32 tag = *((u32 *)p);
+		u32 sz, noff;
+		const char *nstr;
+
+		p += 4;
+		if (tag == OF_DT_NOP)
+			continue;
+		if (tag != OF_DT_PROP)
+			return NULL;
+
+		sz = *((u32 *)p);
+		noff = *((u32 *)(p + 4));
+		p += 8;
+		if (initial_boot_params->version < 0x10)
+			p = _ALIGN(p, sz >= 8 ? 8 : 4);
+
+		nstr = find_flat_dt_string(noff);
+		if (nstr == NULL) {
+			printk(KERN_WARNING "Can't find property index"
+				" name !\n");
+			return NULL;
+		}
+		if (strcmp(name, nstr) == 0) {
+			if (size)
+				*size = sz;
+			return (void *)p;
+		}
+		p += sz;
+		p = _ALIGN(p, 4);
+	} while (1);
+}
+
+int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
+{
+	const char *cp;
+	unsigned long cplen, l;
+
+	cp = of_get_flat_dt_prop(node, "compatible", &cplen);
+	if (cp == NULL)
+		return 0;
+	while (cplen > 0) {
+		if (strncasecmp(cp, compat, strlen(compat)) == 0)
+			return 1;
+		l = strlen(cp) + 1;
+		cp += l;
+		cplen -= l;
+	}
+
+	return 0;
+}
+
+static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
+					unsigned long align)
+{
+	void *res;
+
+	*mem = _ALIGN(*mem, align);
+	res = (void *)*mem;
+	*mem += size;
+
+	return res;
+}
+
+static unsigned long __init unflatten_dt_node(unsigned long mem,
+					unsigned long *p,
+					struct device_node *dad,
+					struct device_node ***allnextpp,
+					unsigned long fpsize)
+{
+	struct device_node *np;
+	struct property *pp, **prev_pp = NULL;
+	char *pathp;
+	u32 tag;
+	unsigned int l, allocl;
+	int has_name = 0;
+	int new_format = 0;
+
+	tag = *((u32 *)(*p));
+	if (tag != OF_DT_BEGIN_NODE) {
+		printk("Weird tag at start of node: %x\n", tag);
+		return mem;
+	}
+	*p += 4;
+	pathp = (char *)*p;
+	l = allocl = strlen(pathp) + 1;
+	*p = _ALIGN(*p + l, 4);
+
+	/* version 0x10 has a more compact unit name here instead of the full
+	 * path. we accumulate the full path size using "fpsize", we'll rebuild
+	 * it later. We detect this because the first character of the name is
+	 * not '/'.
+	 */
+	if ((*pathp) != '/') {
+		new_format = 1;
+		if (fpsize == 0) {
+			/* root node: special case. fpsize accounts for path
+			 * plus terminating zero. root node only has '/', so
+			 * fpsize should be 2, but we want to avoid the first
+			 * level nodes to have two '/' so we use fpsize 1 here
+			 */
+			fpsize = 1;
+			allocl = 2;
+		} else {
+			/* account for '/' and path size minus terminal 0
+			 * already in 'l'
+			 */
+			fpsize += l;
+			allocl = fpsize;
+		}
+	}
+
+	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
+				__alignof__(struct device_node));
+	if (allnextpp) {
+		memset(np, 0, sizeof(*np));
+		np->full_name = ((char *)np) + sizeof(struct device_node);
+		if (new_format) {
+			char *p2 = np->full_name;
+			/* rebuild full path for new format */
+			if (dad && dad->parent) {
+				strcpy(p2, dad->full_name);
+#ifdef DEBUG
+				if ((strlen(p2) + l + 1) != allocl) {
+					pr_debug("%s: p: %d, l: %d, a: %d\n",
+						pathp, (int)strlen(p2),
+						l, allocl);
+				}
+#endif
+				p2 += strlen(p2);
+			}
+			*(p2++) = '/';
+			memcpy(p2, pathp, l);
+		} else
+			memcpy(np->full_name, pathp, l);
+		prev_pp = &np->properties;
+		**allnextpp = np;
+		*allnextpp = &np->allnext;
+		if (dad != NULL) {
+			np->parent = dad;
+			/* we temporarily use the next field as `last_child'*/
+			if (dad->next == NULL)
+				dad->child = np;
+			else
+				dad->next->sibling = np;
+			dad->next = np;
+		}
+		kref_init(&np->kref);
+	}
+	while (1) {
+		u32 sz, noff;
+		char *pname;
+
+		tag = *((u32 *)(*p));
+		if (tag == OF_DT_NOP) {
+			*p += 4;
+			continue;
+		}
+		if (tag != OF_DT_PROP)
+			break;
+		*p += 4;
+		sz = *((u32 *)(*p));
+		noff = *((u32 *)((*p) + 4));
+		*p += 8;
+		if (initial_boot_params->version < 0x10)
+			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
+
+		pname = find_flat_dt_string(noff);
+		if (pname == NULL) {
+			printk(KERN_INFO
+				"Can't find property name in list !\n");
+			break;
+		}
+		if (strcmp(pname, "name") == 0)
+			has_name = 1;
+		l = strlen(pname) + 1;
+		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
+					__alignof__(struct property));
+		if (allnextpp) {
+			if (strcmp(pname, "linux,phandle") == 0) {
+				np->node = *((u32 *)*p);
+				if (np->linux_phandle == 0)
+					np->linux_phandle = np->node;
+			}
+			if (strcmp(pname, "ibm,phandle") == 0)
+				np->linux_phandle = *((u32 *)*p);
+			pp->name = pname;
+			pp->length = sz;
+			pp->value = (void *)*p;
+			*prev_pp = pp;
+			prev_pp = &pp->next;
+		}
+		*p = _ALIGN((*p) + sz, 4);
+	}
+	/* with version 0x10 we may not have the name property, recreate
+	 * it here from the unit name if absent
+	 */
+	if (!has_name) {
+		char *p1 = pathp, *ps = pathp, *pa = NULL;
+		int sz;
+
+		while (*p1) {
+			if ((*p1) == '@')
+				pa = p1;
+			if ((*p1) == '/')
+				ps = p1 + 1;
+			p1++;
+		}
+		if (pa < ps)
+			pa = p1;
+		sz = (pa - ps) + 1;
+		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
+					__alignof__(struct property));
+		if (allnextpp) {
+			pp->name = "name";
+			pp->length = sz;
+			pp->value = pp + 1;
+			*prev_pp = pp;
+			prev_pp = &pp->next;
+			memcpy(pp->value, ps, sz - 1);
+			((char *)pp->value)[sz - 1] = 0;
+			pr_debug("fixed up name for %s -> %s\n", pathp,
+				(char *)pp->value);
+		}
+	}
+	if (allnextpp) {
+		*prev_pp = NULL;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+
+		if (!np->name)
+			np->name = "<NULL>";
+		if (!np->type)
+			np->type = "<NULL>";
+	}
+	while (tag == OF_DT_BEGIN_NODE) {
+		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+		tag = *((u32 *)(*p));
+	}
+	if (tag != OF_DT_END_NODE) {
+		printk(KERN_INFO "Weird tag at end of node: %x\n", tag);
+		return mem;
+	}
+	*p += 4;
+	return mem;
+}
+
+/**
+ * unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used (this used to be done by finish_device_tree)
+ */
+void __init unflatten_device_tree(void)
+{
+	unsigned long start, mem, size;
+	struct device_node **allnextp = &allnodes;
+
+	pr_debug(" -> unflatten_device_tree()\n");
+
+	/* First pass, scan for size */
+	start = ((unsigned long)initial_boot_params) +
+		initial_boot_params->off_dt_struct;
+	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
+	size = (size | 3) + 1;
+
+	pr_debug("  size is %lx, allocating...\n", size);
+
+	/* Allocate memory for the expanded device tree */
+	mem = lmb_alloc(size + 4, __alignof__(struct device_node));
+	mem = (unsigned long) __va(mem);
+
+	((u32 *)mem)[size / 4] = 0xdeadbeef;
+
+	pr_debug("  unflattening %lx...\n", mem);
+
+	/* Second pass, do actual unflattening */
+	start = ((unsigned long)initial_boot_params) +
+		initial_boot_params->off_dt_struct;
+	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
+	if (*((u32 *)start) != OF_DT_END)
+		printk(KERN_WARNING "Weird tag at end of tree: %08x\n",
+			*((u32 *)start));
+	if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+		printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
+			((u32 *)mem)[size / 4]);
+	*allnextp = NULL;
+
+	/* Get pointer to OF "/chosen" node for use everywhere */
+	of_chosen = of_find_node_by_path("/chosen");
+	if (of_chosen == NULL)
+		of_chosen = of_find_node_by_path("/chosen@0");
+
+	pr_debug(" <- unflatten_device_tree()\n");
+}
+
+#define early_init_dt_scan_drconf_memory(node) 0
+
+static int __init early_init_dt_scan_cpus(unsigned long node,
+					  const char *uname, int depth,
+					  void *data)
+{
+	static int logical_cpuid;
+	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+	const u32 *intserv;
+	int i, nthreads;
+	int found = 0;
+
+	/* We are scanning "cpu" nodes only */
+	if (type == NULL || strcmp(type, "cpu") != 0)
+		return 0;
+
+	/* Get physical cpuid */
+	intserv = of_get_flat_dt_prop(node, "reg", NULL);
+	nthreads = 1;
+
+	/*
+	 * Now see if any of these threads match our boot cpu.
+	 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
+	 */
+	for (i = 0; i < nthreads; i++) {
+		/*
+		 * version 2 of the kexec param format adds the phys cpuid of
+		 * booted proc.
+		 */
+		if (initial_boot_params && initial_boot_params->version >= 2) {
+			if (intserv[i] ==
+					initial_boot_params->boot_cpuid_phys) {
+				found = 1;
+				break;
+			}
+		} else {
+			/*
+			 * Check if it's the boot-cpu, set it's hw index now,
+			 * unfortunately this format did not support booting
+			 * off secondary threads.
+			 */
+			if (of_get_flat_dt_prop(node,
+					"linux,boot-cpu", NULL) != NULL) {
+				found = 1;
+				break;
+			}
+		}
+
+#ifdef CONFIG_SMP
+		/* logical cpu id is always 0 on UP kernels */
+		logical_cpuid++;
+#endif
+	}
+
+	if (found) {
+		pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
+			intserv[i]);
+		boot_cpuid = logical_cpuid;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+	unsigned long l;
+	u32 *prop;
+
+	pr_debug("Looking for initrd properties... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
+	if (prop) {
+		initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
+
+		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
+		if (prop) {
+			initrd_end = (unsigned long)
+					__va(of_read_ulong(prop, l/4));
+			initrd_below_start_ok = 1;
+		} else {
+			initrd_start = 0;
+		}
+	}
+
+	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
+					initrd_start, initrd_end);
+}
+#else
+static inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+static int __init early_init_dt_scan_chosen(unsigned long node,
+				const char *uname, int depth, void *data)
+{
+	unsigned long l;
+	char *p;
+
+	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+	if (depth != 1 ||
+		(strcmp(uname, "chosen") != 0 &&
+				strcmp(uname, "chosen@0") != 0))
+		return 0;
+
+#ifdef CONFIG_KEXEC
+	lprop = (u64 *)of_get_flat_dt_prop(node,
+				"linux,crashkernel-base", NULL);
+	if (lprop)
+		crashk_res.start = *lprop;
+
+	lprop = (u64 *)of_get_flat_dt_prop(node,
+				"linux,crashkernel-size", NULL);
+	if (lprop)
+		crashk_res.end = crashk_res.start + *lprop - 1;
+#endif
+
+	early_init_dt_check_for_initrd(node);
+
+	/* Retreive command line */
+	p = of_get_flat_dt_prop(node, "bootargs", &l);
+	if (p != NULL && l > 0)
+		strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
+
+#ifdef CONFIG_CMDLINE
+	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+	pr_debug("Command line is: %s\n", cmd_line);
+
+	/* break now */
+	return 1;
+}
+
+static int __init early_init_dt_scan_root(unsigned long node,
+				const char *uname, int depth, void *data)
+{
+	u32 *prop;
+
+	if (depth != 0)
+		return 0;
+
+	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+	/* break now */
+	return 1;
+}
+
+static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
+{
+	cell_t *p = *cellp;
+
+	*cellp = p + s;
+	return of_read_number(p, s);
+}
+
+static int __init early_init_dt_scan_memory(unsigned long node,
+				const char *uname, int depth, void *data)
+{
+	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+	cell_t *reg, *endp;
+	unsigned long l;
+
+	/* Look for the ibm,dynamic-reconfiguration-memory node */
+/*	if (depth == 1 &&
+		strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
+		return early_init_dt_scan_drconf_memory(node);
+*/
+	/* We are scanning "memory" nodes only */
+	if (type == NULL) {
+		/*
+		 * The longtrail doesn't have a device_type on the
+		 * /memory node, so look for the node called /memory@0.
+		 */
+		if (depth != 1 || strcmp(uname, "memory@0") != 0)
+			return 0;
+	} else if (strcmp(type, "memory") != 0)
+		return 0;
+
+	reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+	if (reg == NULL)
+		reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+	if (reg == NULL)
+		return 0;
+
+	endp = reg + (l / sizeof(cell_t));
+
+	pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
+		uname, l, reg[0], reg[1], reg[2], reg[3]);
+
+	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+		u64 base, size;
+
+		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+		if (size == 0)
+			continue;
+		pr_debug(" - %llx ,  %llx\n", (unsigned long long)base,
+			(unsigned long long)size);
+
+		lmb_add(base, size);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PHYP_DUMP
+/**
+ * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg
+ *
+ * Function to find the largest size we need to reserve
+ * during early boot process.
+ *
+ * It either looks for boot param and returns that OR
+ * returns larger of 256 or 5% rounded down to multiples of 256MB.
+ *
+ */
+static inline unsigned long phyp_dump_calculate_reserve_size(void)
+{
+	unsigned long tmp;
+
+	if (phyp_dump_info->reserve_bootvar)
+		return phyp_dump_info->reserve_bootvar;
+
+	/* divide by 20 to get 5% of value */
+	tmp = lmb_end_of_DRAM();
+	do_div(tmp, 20);
+
+	/* round it down in multiples of 256 */
+	tmp = tmp & ~0x0FFFFFFFUL;
+
+	return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END);
+}
+
+/**
+ * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory
+ *
+ * This routine may reserve memory regions in the kernel only
+ * if the system is supported and a dump was taken in last
+ * boot instance or if the hardware is supported and the
+ * scratch area needs to be setup. In other instances it returns
+ * without reserving anything. The memory in case of dump being
+ * active is freed when the dump is collected (by userland tools).
+ */
+static void __init phyp_dump_reserve_mem(void)
+{
+	unsigned long base, size;
+	unsigned long variable_reserve_size;
+
+	if (!phyp_dump_info->phyp_dump_configured) {
+		printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
+		return;
+	}
+
+	if (!phyp_dump_info->phyp_dump_at_boot) {
+		printk(KERN_INFO "Phyp-dump disabled at boot time\n");
+		return;
+	}
+
+	variable_reserve_size = phyp_dump_calculate_reserve_size();
+
+	if (phyp_dump_info->phyp_dump_is_active) {
+		/* Reserve *everything* above RMR.Area freed by userland tools*/
+		base = variable_reserve_size;
+		size = lmb_end_of_DRAM() - base;
+
+		/* XXX crashed_ram_end is wrong, since it may be beyond
+		 * the memory_limit, it will need to be adjusted. */
+		lmb_reserve(base, size);
+
+		phyp_dump_info->init_reserve_start = base;
+		phyp_dump_info->init_reserve_size = size;
+	} else {
+		size = phyp_dump_info->cpu_state_size +
+			phyp_dump_info->hpte_region_size +
+			variable_reserve_size;
+		base = lmb_end_of_DRAM() - size;
+		lmb_reserve(base, size);
+		phyp_dump_info->init_reserve_start = base;
+		phyp_dump_info->init_reserve_size = size;
+	}
+}
+#else
+static inline void __init phyp_dump_reserve_mem(void) {}
+#endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
+
+#ifdef CONFIG_EARLY_PRINTK
+/* MS this is Microblaze specifig function */
+static int __init early_init_dt_scan_serial(unsigned long node,
+				const char *uname, int depth, void *data)
+{
+	unsigned long l;
+	char *p;
+	int *addr;
+
+	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+/* find all serial nodes */
+	if (strncmp(uname, "serial", 6) != 0)
+		return 0;
+
+	early_init_dt_check_for_initrd(node);
+
+/* find compatible node with uartlite */
+	p = of_get_flat_dt_prop(node, "compatible", &l);
+	if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
+			(strncmp(p, "xlnx,opb-uartlite", 17) != 0))
+		return 0;
+
+	addr = of_get_flat_dt_prop(node, "reg", &l);
+	return *addr; /* return address */
+}
+
+/* this function is looking for early uartlite console - Microblaze specific */
+int __init early_uartlite_console(void)
+{
+	return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
+}
+#endif
+
+void __init early_init_devtree(void *params)
+{
+	pr_debug(" -> early_init_devtree(%p)\n", params);
+
+	/* Setup flat device-tree pointer */
+	initial_boot_params = params;
+
+#ifdef CONFIG_PHYP_DUMP
+	/* scan tree to see if dump occured during last boot */
+	of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
+#endif
+
+	/* Retrieve various informations from the /chosen node of the
+	 * device-tree, including the platform type, initrd location and
+	 * size, TCE reserve, and more ...
+	 */
+	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+	/* Scan memory nodes and rebuild LMBs */
+	lmb_init();
+	of_scan_flat_dt(early_init_dt_scan_root, NULL);
+	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+	/* Save command line for /proc/cmdline and then parse parameters */
+	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+	parse_early_param();
+
+	lmb_analyze();
+
+	pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
+
+	pr_debug("Scanning CPUs ...\n");
+
+	/* Retreive CPU related informations from the flat tree
+	 * (altivec support, boot CPU ID, ...)
+	 */
+	of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+	pr_debug(" <- early_init_devtree()\n");
+}
+
+/**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+	struct device_node *root;
+	int rc = 0;
+
+	root = of_find_node_by_path("/");
+	if (root) {
+		rc = of_device_is_compatible(root, compat);
+		of_node_put(root);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/*******
+ *
+ * New implementation of the OF "find" APIs, return a refcounted
+ * object, call of_node_put() when done.  The device tree and list
+ * are protected by a rw_lock.
+ *
+ * Note that property management will need some locking as well,
+ * this isn't dealt with yet.
+ *
+ *******/
+
+/**
+ *	of_find_node_by_phandle - Find a node given a phandle
+ *	@handle:	phandle of the node to find
+ *
+ *	Returns a node pointer with refcount incremented, use
+ *	of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+	struct device_node *np;
+
+	read_lock(&devtree_lock);
+	for (np = allnodes; np != NULL; np = np->allnext)
+		if (np->linux_phandle == handle)
+			break;
+	of_node_get(np);
+	read_unlock(&devtree_lock);
+	return np;
+}
+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
+ *
+ *	Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+	if (node)
+		kref_get(&node->kref);
+	return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node *kref_to_device_node(struct kref *kref)
+{
+	return container_of(kref, struct device_node, kref);
+}
+
+/**
+ *	of_node_release - release a dynamically allocated node
+ *	@kref:  kref element of the node to be released
+ *
+ *	In of_node_put() this function is passed to kref_put()
+ *	as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+	struct device_node *node = kref_to_device_node(kref);
+	struct property *prop = node->properties;
+
+	/* We should never be releasing nodes that haven't been detached. */
+	if (!of_node_check_flag(node, OF_DETACHED)) {
+		printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
+			node->full_name);
+		dump_stack();
+		kref_init(&node->kref);
+		return;
+	}
+
+	if (!of_node_check_flag(node, OF_DYNAMIC))
+		return;
+
+	while (prop) {
+		struct property *next = prop->next;
+		kfree(prop->name);
+		kfree(prop->value);
+		kfree(prop);
+		prop = next;
+
+		if (!prop) {
+			prop = node->deadprops;
+			node->deadprops = NULL;
+		}
+	}
+	kfree(node->full_name);
+	kfree(node->data);
+	kfree(node);
+}
+
+/**
+ *	of_node_put - Decrement refcount of a node
+ *	@node:	Node to dec refcount, NULL is supported to
+ *		simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+	if (node)
+		kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+
+/*
+ * Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&devtree_lock, flags);
+	np->sibling = np->parent->child;
+	np->allnext = allnodes;
+	np->parent->child = np;
+	allnodes = np;
+	write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * "Unplug" a node from the device tree.  The caller must hold
+ * a reference to the node.  The memory associated with the node
+ * is not freed until its refcount goes to zero.
+ */
+void of_detach_node(struct device_node *np)
+{
+	struct device_node *parent;
+	unsigned long flags;
+
+	write_lock_irqsave(&devtree_lock, flags);
+
+	parent = np->parent;
+	if (!parent)
+		goto out_unlock;
+
+	if (allnodes == np)
+		allnodes = np->allnext;
+	else {
+		struct device_node *prev;
+		for (prev = allnodes;
+		     prev->allnext != np;
+		     prev = prev->allnext)
+			;
+		prev->allnext = np->allnext;
+	}
+
+	if (parent->child == np)
+		parent->child = np->sibling;
+	else {
+		struct device_node *prevsib;
+		for (prevsib = np->parent->child;
+		     prevsib->sibling != np;
+		     prevsib = prevsib->sibling)
+			;
+		prevsib->sibling = np->sibling;
+	}
+
+	of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
+	write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/*
+ * Add a property to a node
+ */
+int prom_add_property(struct device_node *np, struct property *prop)
+{
+	struct property **next;
+	unsigned long flags;
+
+	prop->next = NULL;
+	write_lock_irqsave(&devtree_lock, flags);
+	next = &np->properties;
+	while (*next) {
+		if (strcmp(prop->name, (*next)->name) == 0) {
+			/* duplicate ! don't insert it */
+			write_unlock_irqrestore(&devtree_lock, flags);
+			return -1;
+		}
+		next = &(*next)->next;
+	}
+	*next = prop;
+	write_unlock_irqrestore(&devtree_lock, flags);
+
+#ifdef CONFIG_PROC_DEVICETREE
+	/* try to add to proc as well if it was initialized */
+	if (np->pde)
+		proc_device_tree_add_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+	return 0;
+}
+
+/*
+ * Remove a property from a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, so it won't be found any more.
+ */
+int prom_remove_property(struct device_node *np, struct property *prop)
+{
+	struct property **next;
+	unsigned long flags;
+	int found = 0;
+
+	write_lock_irqsave(&devtree_lock, flags);
+	next = &np->properties;
+	while (*next) {
+		if (*next == prop) {
+			/* found the node */
+			*next = prop->next;
+			prop->next = np->deadprops;
+			np->deadprops = prop;
+			found = 1;
+			break;
+		}
+		next = &(*next)->next;
+	}
+	write_unlock_irqrestore(&devtree_lock, flags);
+
+	if (!found)
+		return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+	/* try to remove the proc node as well */
+	if (np->pde)
+		proc_device_tree_remove_prop(np->pde, prop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+	return 0;
+}
+
+/*
+ * Update a property in a node.  Note that we don't actually
+ * remove it, since we have given out who-knows-how-many pointers
+ * to the data using get-property.  Instead we just move the property
+ * to the "dead properties" list, and add the new property to the
+ * property list
+ */
+int prom_update_property(struct device_node *np,
+			 struct property *newprop,
+			 struct property *oldprop)
+{
+	struct property **next;
+	unsigned long flags;
+	int found = 0;
+
+	write_lock_irqsave(&devtree_lock, flags);
+	next = &np->properties;
+	while (*next) {
+		if (*next == oldprop) {
+			/* found the node */
+			newprop->next = oldprop->next;
+			*next = newprop;
+			oldprop->next = np->deadprops;
+			np->deadprops = oldprop;
+			found = 1;
+			break;
+		}
+		next = &(*next)->next;
+	}
+	write_unlock_irqrestore(&devtree_lock, flags);
+
+	if (!found)
+		return -ENODEV;
+
+#ifdef CONFIG_PROC_DEVICETREE
+	/* try to add to proc as well if it was initialized */
+	if (np->pde)
+		proc_device_tree_update_prop(np->pde, newprop, oldprop);
+#endif /* CONFIG_PROC_DEVICETREE */
+
+	return 0;
+}
+
+#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
+static struct debugfs_blob_wrapper flat_dt_blob;
+
+static int __init export_flat_device_tree(void)
+{
+	struct dentry *d;
+
+	flat_dt_blob.data = initial_boot_params;
+	flat_dt_blob.size = initial_boot_params->totalsize;
+
+	d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
+				of_debugfs_root, &flat_dt_blob);
+	if (!d)
+		return 1;
+
+	return 0;
+}
+device_initcall(export_flat_device_tree);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/prom_parse.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/prom_parse.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/prom_parse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/prom_parse.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1025 @@
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci_regs.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/etherdevice.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PRu64	"%llx"
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS	4
+#define OF_CHECK_COUNTS(na, ns)	((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+			(ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+static int __of_address_to_resource(struct device_node *dev,
+		const u32 *addrp, u64 size, unsigned int flags,
+		struct resource *r);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const u32 *addr, int na)
+{
+	printk(KERN_INFO "%s", s);
+	while (na--)
+		printk(KERN_INFO " %08x", *(addr++));
+	printk(KERN_INFO "\n");
+}
+#else
+static void of_dump_addr(const char *s, const u32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+	const char	*name;
+	const char	*addresses;
+	int		(*match)(struct device_node *parent);
+	void		(*count_cells)(struct device_node *child,
+					int *addrc, int *sizec);
+	u64		(*map)(u32 *addr, const u32 *range,
+				int na, int ns, int pna);
+	int		(*translate)(u32 *addr, u64 offset, int na);
+	unsigned int	(*get_flags)(const u32 *addr);
+};
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_bus_default_count_cells(struct device_node *dev,
+					int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = of_n_addr_cells(dev);
+	if (sizec)
+		*sizec = of_n_size_cells(dev);
+}
+
+static u64 of_bus_default_map(u32 *addr, const u32 *range,
+		int na, int ns, int pna)
+{
+	u64 cp, s, da;
+
+	cp = of_read_number(range, na);
+	s  = of_read_number(range + na + pna, ns);
+	da = of_read_number(addr, na);
+
+	pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
+		cp, s, da);
+
+	if (da < cp || da >= (cp + s))
+		return OF_BAD_ADDR;
+	return da - cp;
+}
+
+static int of_bus_default_translate(u32 *addr, u64 offset, int na)
+{
+	u64 a = of_read_number(addr, na);
+	memset(addr, 0, na * 4);
+	a += offset;
+	if (na > 1)
+		addr[na - 2] = a >> 32;
+	addr[na - 1] = a & 0xffffffffu;
+
+	return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const u32 *addr)
+{
+	return IORESOURCE_MEM;
+}
+
+#ifdef CONFIG_PCI
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+	/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
+	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+				int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 3;
+	if (sizec)
+		*sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+	u64 cp, s, da;
+
+	/* Check address type match */
+	if ((addr[0] ^ range[0]) & 0x03000000)
+		return OF_BAD_ADDR;
+
+	/* Read address values, skipping high cell */
+	cp = of_read_number(range + 1, na - 1);
+	s  = of_read_number(range + na + pna, ns);
+	da = of_read_number(addr + 1, na - 1);
+
+	pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+	if (da < cp || da >= (cp + s))
+		return OF_BAD_ADDR;
+	return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+	return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_pci_get_flags(const u32 *addr)
+{
+	unsigned int flags = 0;
+	u32 w = addr[0];
+
+	switch ((w >> 24) & 0x03) {
+	case 0x01:
+		flags |= IORESOURCE_IO;
+		break;
+	case 0x02: /* 32 bits */
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM;
+		break;
+	}
+	if (w & 0x40000000)
+		flags |= IORESOURCE_PREFETCH;
+	return flags;
+}
+
+const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
+			unsigned int *flags)
+{
+	const u32 *prop;
+	unsigned int psize;
+	struct device_node *parent;
+	struct of_bus *bus;
+	int onesize, i, na, ns;
+
+	/* Get parent & match bus type */
+	parent = of_get_parent(dev);
+	if (parent == NULL)
+		return NULL;
+	bus = of_match_bus(parent);
+	if (strcmp(bus->name, "pci")) {
+		of_node_put(parent);
+		return NULL;
+	}
+	bus->count_cells(dev, &na, &ns);
+	of_node_put(parent);
+	if (!OF_CHECK_COUNTS(na, ns))
+		return NULL;
+
+	/* Get "reg" or "assigned-addresses" property */
+	prop = of_get_property(dev, bus->addresses, &psize);
+	if (prop == NULL)
+		return NULL;
+	psize /= 4;
+
+	onesize = na + ns;
+	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+		if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
+			if (size)
+				*size = of_read_number(prop + na, ns);
+			if (flags)
+				*flags = bus->get_flags(prop);
+			return prop;
+		}
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_address);
+
+int of_pci_address_to_resource(struct device_node *dev, int bar,
+				struct resource *r)
+{
+	const u32	*addrp;
+	u64		size;
+	unsigned int	flags;
+
+	addrp = of_get_pci_address(dev, bar, &size, &flags);
+	if (addrp == NULL)
+		return -EINVAL;
+	return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
+{
+	return (((pin - 1) + slot) % 4) + 1;
+}
+
+int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	u32 lspec;
+	u32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/* Check if we have a device node, if yes, fallback to standard OF
+	 * parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn)
+		return of_irq_map_one(dn, 0, out_irq);
+
+	/* Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		return rc;
+	/* No pin, exit */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	lspec = pin;
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			struct pci_controller *host;
+			host = pci_bus_to_host(pdev->bus);
+			ppnode = host ? host->arch_data : NULL;
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL)
+				return -EINVAL;
+		} else
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+
+		/* Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship  a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/* We can only get here if we hit a P2P bridge with no node,
+		 * let's do standard swizzling and try again
+		 */
+		lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
+		pdev = ppdev;
+	}
+
+	laddr[0] = (pdev->bus->number << 16)
+		| (pdev->devfn << 8);
+	laddr[1]  = laddr[2] = 0;
+	return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
+}
+EXPORT_SYMBOL_GPL(of_irq_map_pci);
+#endif /* CONFIG_PCI */
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+	return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+				int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 2;
+	if (sizec)
+		*sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+{
+	u64 cp, s, da;
+
+	/* Check address type match */
+	if ((addr[0] ^ range[0]) & 0x00000001)
+		return OF_BAD_ADDR;
+
+	/* Read address values, skipping high cell */
+	cp = of_read_number(range + 1, na - 1);
+	s  = of_read_number(range + na + pna, ns);
+	da = of_read_number(addr + 1, na - 1);
+
+	pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
+
+	if (da < cp || da >= (cp + s))
+		return OF_BAD_ADDR;
+	return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+	return of_bus_default_translate(addr + 1, offset, na - 1);
+}
+
+static unsigned int of_bus_isa_get_flags(const u32 *addr)
+{
+	unsigned int flags = 0;
+	u32 w = addr[0];
+
+	if (w & 1)
+		flags |= IORESOURCE_IO;
+	else
+		flags |= IORESOURCE_MEM;
+	return flags;
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+#ifdef CONFIG_PCI
+	/* PCI */
+	{
+		.name = "pci",
+		.addresses = "assigned-addresses",
+		.match = of_bus_pci_match,
+		.count_cells = of_bus_pci_count_cells,
+		.map = of_bus_pci_map,
+		.translate = of_bus_pci_translate,
+		.get_flags = of_bus_pci_get_flags,
+	},
+#endif /* CONFIG_PCI */
+	/* ISA */
+	{
+		.name = "isa",
+		.addresses = "reg",
+		.match = of_bus_isa_match,
+		.count_cells = of_bus_isa_count_cells,
+		.map = of_bus_isa_map,
+		.translate = of_bus_isa_translate,
+		.get_flags = of_bus_isa_get_flags,
+	},
+	/* Default */
+	{
+		.name = "default",
+		.addresses = "reg",
+		.match = NULL,
+		.count_cells = of_bus_default_count_cells,
+		.map = of_bus_default_map,
+		.translate = of_bus_default_translate,
+		.get_flags = of_bus_default_get_flags,
+	},
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+		if (!of_busses[i].match || of_busses[i].match(np))
+			return &of_busses[i];
+	BUG();
+	return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+			struct of_bus *pbus, u32 *addr,
+			int na, int ns, int pna)
+{
+	const u32 *ranges;
+	unsigned int rlen;
+	int rone;
+	u64 offset = OF_BAD_ADDR;
+
+	/* Normally, an absence of a "ranges" property means we are
+	 * crossing a non-translatable boundary, and thus the addresses
+	 * below the current not cannot be converted to CPU physical ones.
+	 * Unfortunately, while this is very clear in the spec, it's not
+	 * what Apple understood, and they do have things like /uni-n or
+	 * /ht nodes with no "ranges" property and a lot of perfectly
+	 * useable mapped devices below them. Thus we treat the absence of
+	 * "ranges" as equivalent to an empty "ranges" property which means
+	 * a 1:1 translation at that level. It's up to the caller not to try
+	 * to translate addresses that aren't supposed to be translated in
+	 * the first place. --BenH.
+	 */
+	ranges = of_get_property(parent, "ranges", (int *) &rlen);
+	if (ranges == NULL || rlen == 0) {
+		offset = of_read_number(addr, na);
+		memset(addr, 0, pna * 4);
+		pr_debug("OF: no ranges, 1:1 translation\n");
+		goto finish;
+	}
+
+	pr_debug("OF: walking ranges...\n");
+
+	/* Now walk through the ranges */
+	rlen /= 4;
+	rone = na + pna + ns;
+	for (; rlen >= rone; rlen -= rone, ranges += rone) {
+		offset = bus->map(addr, ranges, na, ns, pna);
+		if (offset != OF_BAD_ADDR)
+			break;
+	}
+	if (offset == OF_BAD_ADDR) {
+		pr_debug("OF: not found !\n");
+		return 1;
+	}
+	memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+	of_dump_addr("OF: parent translation for:", addr, pna);
+	pr_debug("OF: with offset: "PRu64"\n", offset);
+
+	/* Translate it into parent bus space */
+	return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+	struct device_node *parent = NULL;
+	struct of_bus *bus, *pbus;
+	u32 addr[OF_MAX_ADDR_CELLS];
+	int na, ns, pna, pns;
+	u64 result = OF_BAD_ADDR;
+
+	pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+
+	/* Increase refcount at current level */
+	of_node_get(dev);
+
+	/* Get parent & match bus type */
+	parent = of_get_parent(dev);
+	if (parent == NULL)
+		goto bail;
+	bus = of_match_bus(parent);
+
+	/* Cound address cells & copy address locally */
+	bus->count_cells(dev, &na, &ns);
+	if (!OF_CHECK_COUNTS(na, ns)) {
+		printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+			dev->full_name);
+		goto bail;
+	}
+	memcpy(addr, in_addr, na * 4);
+
+	pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+		bus->name, na, ns, parent->full_name);
+	of_dump_addr("OF: translating address:", addr, na);
+
+	/* Translate */
+	for (;;) {
+		/* Switch to parent bus */
+		of_node_put(dev);
+		dev = parent;
+		parent = of_get_parent(dev);
+
+		/* If root, we have finished */
+		if (parent == NULL) {
+			pr_debug("OF: reached root node\n");
+			result = of_read_number(addr, na);
+			break;
+		}
+
+		/* Get new parent bus and counts */
+		pbus = of_match_bus(parent);
+		pbus->count_cells(dev, &pna, &pns);
+		if (!OF_CHECK_COUNTS(pna, pns)) {
+			printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+				dev->full_name);
+			break;
+		}
+
+		pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+			pbus->name, pna, pns, parent->full_name);
+
+		/* Apply bus translation */
+		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+			break;
+
+		/* Complete the move up one level */
+		na = pna;
+		ns = pns;
+		bus = pbus;
+
+		of_dump_addr("OF: one level translation:", addr, na);
+	}
+ bail:
+	of_node_put(parent);
+	of_node_put(dev);
+
+	return result;
+}
+EXPORT_SYMBOL(of_translate_address);
+
+const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
+			unsigned int *flags)
+{
+	const u32 *prop;
+	unsigned int psize;
+	struct device_node *parent;
+	struct of_bus *bus;
+	int onesize, i, na, ns;
+
+	/* Get parent & match bus type */
+	parent = of_get_parent(dev);
+	if (parent == NULL)
+		return NULL;
+	bus = of_match_bus(parent);
+	bus->count_cells(dev, &na, &ns);
+	of_node_put(parent);
+	if (!OF_CHECK_COUNTS(na, ns))
+		return NULL;
+
+	/* Get "reg" or "assigned-addresses" property */
+	prop = of_get_property(dev, bus->addresses, (int *) &psize);
+	if (prop == NULL)
+		return NULL;
+	psize /= 4;
+
+	onesize = na + ns;
+	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+		if (i == index) {
+			if (size)
+				*size = of_read_number(prop + na, ns);
+			if (flags)
+				*flags = bus->get_flags(prop);
+			return prop;
+		}
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
+				u64 size, unsigned int flags,
+				struct resource *r)
+{
+	u64 taddr;
+
+	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+		return -EINVAL;
+	taddr = of_translate_address(dev, addrp);
+	if (taddr == OF_BAD_ADDR)
+		return -EINVAL;
+	memset(r, 0, sizeof(struct resource));
+	if (flags & IORESOURCE_IO) {
+		unsigned long port;
+		port = -1; /* pci_address_to_pio(taddr); */
+		if (port == (unsigned long)-1)
+			return -EINVAL;
+		r->start = port;
+		r->end = port + size - 1;
+	} else {
+		r->start = taddr;
+		r->end = taddr + size - 1;
+	}
+	r->flags = flags;
+	r->name = dev->name;
+	return 0;
+}
+
+int of_address_to_resource(struct device_node *dev, int index,
+			struct resource *r)
+{
+	const u32	*addrp;
+	u64		size;
+	unsigned int	flags;
+
+	addrp = of_get_address(dev, index, &size, &flags);
+	if (addrp == NULL)
+		return -EINVAL;
+	return __of_address_to_resource(dev, addrp, size, flags, r);
+}
+EXPORT_SYMBOL_GPL(of_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+	const u32 *dma_window;
+	u32 cells;
+	const unsigned char *prop;
+
+	dma_window = dma_window_prop;
+
+	/* busno is always one cell */
+	*busno = *(dma_window++);
+
+	prop = of_get_property(dn, "ibm,#dma-address-cells", NULL);
+	if (!prop)
+		prop = of_get_property(dn, "#address-cells", NULL);
+
+	cells = prop ? *(u32 *)prop : of_n_addr_cells(dn);
+	*phys = of_read_number(dma_window, cells);
+
+	dma_window += cells;
+
+	prop = of_get_property(dn, "ibm,#dma-size-cells", NULL);
+	cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
+	*size = of_read_number(dma_window, cells);
+}
+
+/*
+ * Interrupt remapper
+ */
+
+static unsigned int of_irq_workarounds;
+static struct device_node *of_irq_dflt_pic;
+
+static struct device_node *of_irq_find_parent(struct device_node *child)
+{
+	struct device_node *p;
+	const phandle *parp;
+
+	if (!of_node_get(child))
+		return NULL;
+
+	do {
+		parp = of_get_property(child, "interrupt-parent", NULL);
+		if (parp == NULL)
+			p = of_get_parent(child);
+		else {
+			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+				p = of_node_get(of_irq_dflt_pic);
+			else
+				p = of_find_node_by_phandle(*parp);
+		}
+		of_node_put(child);
+		child = p;
+	} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+	return p;
+}
+
+/* This doesn't need to be called if you don't have any special workaround
+ * flags to pass
+ */
+void of_irq_map_init(unsigned int flags)
+{
+	of_irq_workarounds = flags;
+
+	/* OldWorld, don't bother looking at other things */
+	if (flags & OF_IMAP_OLDWORLD_MAC)
+		return;
+
+	/* If we don't have phandles, let's try to locate a default interrupt
+	 * controller (happens when booting with BootX). We do a first match
+	 * here, hopefully, that only ever happens on machines with one
+	 * controller.
+	 */
+	if (flags & OF_IMAP_NO_PHANDLE) {
+		struct device_node *np;
+
+		for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
+			if (of_get_property(np, "interrupt-controller", NULL)
+				== NULL)
+				continue;
+			/* Skip /chosen/interrupt-controller */
+			if (strcmp(np->name, "chosen") == 0)
+				continue;
+			/* It seems like at least one person on this planet
+			 * wants to use BootX on a machine with an AppleKiwi
+			 * controller which happens to pretend to be an
+			 * interrupt controller too.
+			 */
+			if (strcmp(np->name, "AppleKiwi") == 0)
+				continue;
+			/* I think we found one ! */
+			of_irq_dflt_pic = np;
+			break;
+		}
+	}
+
+}
+
+int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
+		const u32 *addr, struct of_irq *out_irq)
+{
+	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+	const u32 *tmp, *imap, *imask;
+	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+	int imaplen, match, i;
+
+	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
+		"ointsize=%d\n",
+		parent->full_name, intspec[0], intspec[1], ointsize);
+
+	ipar = of_node_get(parent);
+
+	/* First get the #interrupt-cells property of the current cursor
+	 * that tells us how to interpret the passed-in intspec. If there
+	 * is none, we are nice and just walk up the tree
+	 */
+	do {
+		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
+		if (tmp != NULL) {
+			intsize = *tmp;
+			break;
+		}
+		tnode = ipar;
+		ipar = of_irq_find_parent(ipar);
+		of_node_put(tnode);
+	} while (ipar);
+	if (ipar == NULL) {
+		pr_debug(" -> no parent found !\n");
+		goto fail;
+	}
+
+	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
+			ipar->full_name, intsize);
+
+	if (ointsize != intsize)
+		return -EINVAL;
+
+	/* Look for this #address-cells. We have to implement the old linux
+	 * trick of looking for the parent here as some device-trees rely on it
+	 */
+	old = of_node_get(ipar);
+	do {
+		tmp = of_get_property(old, "#address-cells", NULL);
+		tnode = of_get_parent(old);
+		of_node_put(old);
+		old = tnode;
+	} while (old && tmp == NULL);
+	of_node_put(old);
+	old = NULL;
+	addrsize = (tmp == NULL) ? 2 : *tmp;
+
+	pr_debug(" -> addrsize=%d\n", addrsize);
+
+	/* Now start the actual "proper" walk of the interrupt tree */
+	while (ipar != NULL) {
+		/* Now check if cursor is an interrupt-controller and if it is
+		 * then we are done
+		 */
+		if (of_get_property(ipar, "interrupt-controller", NULL) !=
+				NULL) {
+			pr_debug(" -> got it !\n");
+			memcpy(out_irq->specifier, intspec,
+				intsize * sizeof(u32));
+			out_irq->size = intsize;
+			out_irq->controller = ipar;
+			of_node_put(old);
+			return 0;
+		}
+
+		/* Now look for an interrupt-map */
+		imap = of_get_property(ipar, "interrupt-map", &imaplen);
+		/* No interrupt map, check for an interrupt parent */
+		if (imap == NULL) {
+			pr_debug(" -> no map, getting parent\n");
+			newpar = of_irq_find_parent(ipar);
+			goto skiplevel;
+		}
+		imaplen /= sizeof(u32);
+
+		/* Look for a mask */
+		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+
+		/* If we were passed no "reg" property and we attempt to parse
+		 * an interrupt-map, then #address-cells must be 0.
+		 * Fail if it's not.
+		 */
+		if (addr == NULL && addrsize != 0) {
+			pr_debug(" -> no reg passed in when needed !\n");
+			goto fail;
+		}
+
+		/* Parse interrupt-map */
+		match = 0;
+		while (imaplen > (addrsize + intsize + 1) && !match) {
+			/* Compare specifiers */
+			match = 1;
+			for (i = 0; i < addrsize && match; ++i) {
+				u32 mask = imask ? imask[i] : 0xffffffffu;
+				match = ((addr[i] ^ imap[i]) & mask) == 0;
+			}
+			for (; i < (addrsize + intsize) && match; ++i) {
+				u32 mask = imask ? imask[i] : 0xffffffffu;
+				match =
+					((intspec[i-addrsize] ^ imap[i])
+						& mask) == 0;
+			}
+			imap += addrsize + intsize;
+			imaplen -= addrsize + intsize;
+
+			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+
+			/* Get the interrupt parent */
+			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
+				newpar = of_node_get(of_irq_dflt_pic);
+			else
+				newpar =
+					of_find_node_by_phandle((phandle)*imap);
+			imap++;
+			--imaplen;
+
+			/* Check if not found */
+			if (newpar == NULL) {
+				pr_debug(" -> imap parent not found !\n");
+				goto fail;
+			}
+
+			/* Get #interrupt-cells and #address-cells of new
+			 * parent
+			 */
+			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
+			if (tmp == NULL) {
+				pr_debug(" -> parent lacks "
+						"#interrupt-cells!\n");
+				goto fail;
+			}
+			newintsize = *tmp;
+			tmp = of_get_property(newpar, "#address-cells", NULL);
+			newaddrsize = (tmp == NULL) ? 0 : *tmp;
+
+			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
+				newintsize, newaddrsize);
+
+			/* Check for malformed properties */
+			if (imaplen < (newaddrsize + newintsize))
+				goto fail;
+
+			imap += newaddrsize + newintsize;
+			imaplen -= newaddrsize + newintsize;
+
+			pr_debug(" -> imaplen=%d\n", imaplen);
+		}
+		if (!match)
+			goto fail;
+
+		of_node_put(old);
+		old = of_node_get(newpar);
+		addrsize = newaddrsize;
+		intsize = newintsize;
+		intspec = imap - intsize;
+		addr = intspec - addrsize;
+
+skiplevel:
+		/* Iterate again with new parent */
+		pr_debug(" -> new parent: %s\n",
+				newpar ? newpar->full_name : "<>");
+		of_node_put(ipar);
+		ipar = newpar;
+		newpar = NULL;
+	}
+fail:
+	of_node_put(ipar);
+	of_node_put(old);
+	of_node_put(newpar);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_raw);
+
+int of_irq_map_one(struct device_node *device,
+			int index, struct of_irq *out_irq)
+{
+	struct device_node *p;
+	const u32 *intspec, *tmp, *addr;
+	u32 intsize, intlen;
+	int res;
+
+	pr_debug("of_irq_map_one: dev=%s, index=%d\n",
+			device->full_name, index);
+
+	/* Get the interrupts property */
+	intspec = of_get_property(device, "interrupts", (int *) &intlen);
+	if (intspec == NULL)
+		return -EINVAL;
+	intlen /= sizeof(u32);
+
+	pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
+
+	/* Get the reg property (if any) */
+	addr = of_get_property(device, "reg", NULL);
+
+	/* Look for the interrupt parent. */
+	p = of_irq_find_parent(device);
+	if (p == NULL)
+		return -EINVAL;
+
+	/* Get size of interrupt specifier */
+	tmp = of_get_property(p, "#interrupt-cells", NULL);
+	if (tmp == NULL) {
+		of_node_put(p);
+		return -EINVAL;
+	}
+	intsize = *tmp;
+
+	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
+
+	/* Check index */
+	if ((index + 1) * intsize > intlen)
+		return -EINVAL;
+
+	/* Get new specifier and map it */
+	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+				addr, out_irq);
+	of_node_put(p);
+	return res;
+}
+EXPORT_SYMBOL_GPL(of_irq_map_one);
+
+/**
+ * Search the device tree for the best MAC address to use.  'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address.  If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot.  For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+const void *of_get_mac_address(struct device_node *np)
+{
+	struct property *pp;
+
+	pp = of_find_property(np, "mac-address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	pp = of_find_property(np, "local-mac-address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	pp = of_find_property(np, "address", NULL);
+	if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
+		return pp->value;
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_mac_address);
+
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+	struct of_irq out_irq;
+	int irq;
+	int res;
+
+	res = of_irq_map_one(dev, index, &out_irq);
+
+	/* Get irq for the device */
+	if (res) {
+		pr_debug("IRQ not found... code = %d", res);
+		return NO_IRQ;
+	}
+	/* Assuming single interrupt controller... */
+	irq = out_irq.specifier[0];
+
+	pr_debug("IRQ found = %d", irq);
+
+	/* Only dereference the resource if both the
+	 * resource and the irq are valid. */
+	if (r && irq != NO_IRQ) {
+		r->start = r->end = irq;
+		r->flags = IORESOURCE_IRQ;
+	}
+
+	return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+	struct resource res;
+
+	if (of_address_to_resource(np, index, &res))
+		return NULL;
+
+	return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/ptrace.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/ptrace.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/ptrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/ptrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,181 @@
+/*
+ * `ptrace' system call
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2004-2007 John Williams <john.williams@petalogix.com>
+ *
+ * derived from arch/v850/kernel/ptrace.c
+ *
+ * Copyright (C) 2002,03 NEC Electronics Corporation
+ * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
+ *
+ * Derived from arch/mips/kernel/ptrace.c:
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ *
+ * 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/mm.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ptrace.h>
+#include <linux/signal.h>
+
+#include <linux/errno.h>
+#include <asm/processor.h>
+#include <linux/uaccess.h>
+#include <asm/asm-offsets.h>
+
+/* Returns the address where the register at REG_OFFS in P is stashed away. */
+static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
+					struct task_struct *t)
+{
+	struct pt_regs *regs;
+
+	/*
+	 * Three basic cases:
+	 *
+	 * (1)	A register normally saved before calling the scheduler, is
+	 *	available in the kernel entry pt_regs structure at the top
+	 *	of the kernel stack. The kernel trap/irq exit path takes
+	 *	care to save/restore almost all registers for ptrace'd
+	 *	processes.
+	 *
+	 * (2)	A call-clobbered register, where the process P entered the
+	 *	kernel via [syscall] trap, is not stored anywhere; that's
+	 *	OK, because such registers are not expected to be preserved
+	 *	when the trap returns anyway (so we don't actually bother to
+	 *	test for this case).
+	 *
+	 * (3)	A few registers not used at all by the kernel, and so
+	 *	normally never saved except by context-switches, are in the
+	 *	context switch state.
+	 */
+
+	/* Register saved during kernel entry (or not available). */
+	regs = task_pt_regs(t);
+
+	return (microblaze_reg_t *)((char *)regs + reg_offs);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+	int rval;
+	unsigned long val = 0;
+	unsigned long copied;
+
+	switch (request) {
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+		pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr);
+		copied = access_process_vm(child, addr, &val, sizeof(val), 0);
+		rval = -EIO;
+		if (copied != sizeof(val))
+			break;
+		rval = put_user(val, (unsigned long *)data);
+		break;
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		pr_debug("POKETEXT/POKEDATA to %08lX\n", addr);
+		rval = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		rval = -EIO;
+		break;
+
+	/* Read/write the word at location ADDR in the registers. */
+	case PTRACE_PEEKUSR:
+	case PTRACE_POKEUSR:
+		pr_debug("PEEKUSR/POKEUSR : 0x%08lx\n", addr);
+		rval = 0;
+		if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+			/*
+			 * Special requests that don't actually correspond
+			 * to offsets in struct pt_regs.
+			 */
+			if (addr == PT_TEXT_ADDR) {
+				val = child->mm->start_code;
+			} else if (addr == PT_DATA_ADDR) {
+				val = child->mm->start_data;
+			} else if (addr == PT_TEXT_LEN) {
+				val = child->mm->end_code
+					- child->mm->start_code;
+			} else {
+				rval = -EIO;
+			}
+		} else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
+			if (request == PTRACE_PEEKUSR)
+				val = *reg_addr;
+			else
+				*reg_addr = data;
+		} else
+			rval = -EIO;
+
+		if (rval == 0 && request == PTRACE_PEEKUSR)
+			rval = put_user(val, (unsigned long *)data);
+		break;
+	/* Continue and stop at next (return from) syscall */
+	case PTRACE_SYSCALL:
+		pr_debug("PTRACE_SYSCALL\n");
+	case PTRACE_SINGLESTEP:
+		pr_debug("PTRACE_SINGLESTEP\n");
+	/* Restart after a signal.  */
+	case PTRACE_CONT:
+		pr_debug("PTRACE_CONT\n");
+		rval = -EIO;
+		if (!valid_signal(data))
+			break;
+
+		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;
+		pr_debug("wakeup_process\n");
+		wake_up_process(child);
+		rval = 0;
+		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:
+		pr_debug("PTRACE_KILL\n");
+		rval = 0;
+		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		pr_debug("PTRACE_DETACH\n");
+		rval = ptrace_detach(child, data);
+		break;
+	default:
+		/* rval = ptrace_request(child, request, addr, data); noMMU */
+		rval = -EIO;
+	}
+	return rval;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+	/* nothing to do */
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/selfmod.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/selfmod.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/selfmod.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/selfmod.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-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/interrupt.h>
+#include <asm/selfmod.h>
+
+#undef DEBUG
+
+#if __GNUC__ > 3
+#error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig.
+#endif
+
+#define OPCODE_IMM		0xB0000000
+#define OPCODE_LWI		0xE8000000
+#define OPCODE_LWI_MASK		0xEC000000
+#define OPCODE_RTSD		0xB60F0008 /* return from func: rtsd r15, 8 */
+#define OPCODE_ADDIK		0x30000000
+#define OPCODE_ADDIK_MASK	0xFC000000
+
+#define IMM_BASE	(OPCODE_IMM | (BARRIER_BASE_ADDR >> 16))
+#define LWI_BASE	(OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define LWI_BASE_MASK	(OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE	(OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00))
+#define ADDIK_BASE_MASK	(OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
+
+#define MODIFY_INSTR {						\
+	pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n",		\
+		__func__, i, addr[i], i + 1, addr[i + 1]);		\
+	addr[i] = OPCODE_IMM + (base >> 16);				\
+	/* keep instruction opcode and add only last 16bits */		\
+	addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff);	\
+	__invalidate_icache(addr[i]);					\
+	__invalidate_icache(addr[i + 1]);				\
+	pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n",		\
+		__func__, i, addr[i], i + 1, addr[i + 1]); }
+
+/* NOTE
+ * self-modified part of code for improvement of interrupt controller
+ * save instruction in interrupt rutine
+ */
+void selfmod_function(const int *arr_fce, const unsigned int base)
+{
+	unsigned int flags, i, j, *addr = NULL;
+
+	local_irq_save(flags);
+	__disable_icache();
+
+	/* zero terminated array */
+	for (j = 0; arr_fce[j] != 0; j++) {
+		/* get start address of function */
+		addr = (unsigned int *) arr_fce[j];
+		pr_debug("%s: func(%d) at 0x%x\n",
+					__func__, j, (unsigned int) addr);
+		for (i = 0; ; i++) {
+			pr_debug("%s: instruction code at %d: 0x%x\n",
+						__func__, i, addr[i]);
+			if (addr[i] == IMM_BASE) {
+				/* detecting of lwi (0xE8) or swi (0xF8) instr
+				 * I can detect both opcode with one mask */
+				if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) {
+					MODIFY_INSTR;
+				} else /* detection addik for ack */
+				if ((addr[i + 1] & ADDIK_BASE_MASK) ==
+								ADDIK_BASE) {
+					MODIFY_INSTR;
+				}
+			} else if (addr[i] == OPCODE_RTSD) {
+				/* return from function means end of function */
+				pr_debug("%s: end of array %d\n", __func__, i);
+				break;
+			}
+		}
+	}
+	local_irq_restore(flags);
+} /* end of self-modified code */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/setup.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/string.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+#include <linux/debugfs.h>
+
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+#include <linux/param.h>
+#include <linux/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/entry.h>
+#include <asm/cpuinfo.h>
+
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+
+DEFINE_PER_CPU(unsigned int, KSP);	/* Saved kernel stack pointer */
+DEFINE_PER_CPU(unsigned int, KM);	/* Kernel/user mode */
+DEFINE_PER_CPU(unsigned int, ENTRY_SP);	/* Saved SP on kernel entry */
+DEFINE_PER_CPU(unsigned int, R11_SAVE);	/* Temp variable for entry */
+DEFINE_PER_CPU(unsigned int, CURRENT_SAVE);	/* Saved current pointer */
+
+unsigned int boot_cpuid;
+char cmd_line[COMMAND_LINE_SIZE];
+
+void __init setup_arch(char **cmdline_p)
+{
+#ifdef CONFIG_CMDLINE_FORCE
+	strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+	strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif
+	*cmdline_p = cmd_line;
+
+	console_verbose();
+
+	unflatten_device_tree();
+
+	/* NOTE I think that this function is not necessary to call */
+	/* irq_early_init(); */
+	setup_cpuinfo();
+
+	__invalidate_icache_all();
+	__enable_icache();
+
+	__invalidate_dcache_all();
+	__enable_dcache();
+
+	panic_timeout = 120;
+
+	setup_memory();
+
+#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
+	printk(KERN_NOTICE "Self modified code enable\n");
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_XILINX_CONSOLE)
+	conswitchp = &xil_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+}
+
+#ifdef CONFIG_MTD_UCLINUX
+/* Handle both romfs and cramfs types, without generating unnecessary
+ code (ie no point checking for CRAMFS if it's not even enabled) */
+inline unsigned get_romfs_len(unsigned *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+	if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */
+		return be32_to_cpu(addr[2]);
+#endif
+
+#ifdef CONFIG_CRAMFS
+	if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */
+		return le32_to_cpu(addr[1]);
+#endif
+	return 0;
+}
+#endif	/* CONFIG_MTD_UCLINUX_EBSS */
+
+void __init machine_early_init(const char *cmdline, unsigned int ram,
+		unsigned int fdt)
+{
+	unsigned long *src, *dst = (unsigned long *)0x0;
+
+/* clearing bss section */
+	memset(__bss_start, 0, __bss_stop-__bss_start);
+	memset(_ssbss, 0, _esbss-_ssbss);
+
+	/*
+	 * Copy command line passed from bootloader, or use default
+	 * if none provided, or forced
+	 */
+#ifndef CONFIG_CMDLINE_BOOL
+	if (cmdline && cmdline[0] != '\0')
+		strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE);
+#endif
+
+/* initialize device tree for usage in early_printk */
+	early_init_devtree((void *)_fdt_start);
+
+#ifdef CONFIG_EARLY_PRINTK
+	setup_early_printk(NULL);
+#endif
+
+	early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt);
+	printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt);
+
+#ifdef CONFIG_MTD_UCLINUX
+	{
+		int size;
+		unsigned int romfs_base;
+		romfs_base = (ram ? ram : (unsigned int)&__init_end);
+		/* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the
+		 * end of kernel, which is ROMFS_LOCATION defined above. */
+		size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
+		early_printk("Found romfs @ 0x%08x (0x%08x)\n",
+				romfs_base, size);
+		early_printk("#### klimit %p ####\n", klimit);
+		BUG_ON(size < 0); /* What else can we do? */
+
+		/* Use memmove to handle likely case of memory overlap */
+		early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n",
+			size, romfs_base, (unsigned)&_ebss);
+		memmove(&_ebss, (int *)romfs_base, size);
+
+		/* update klimit */
+		klimit += PAGE_ALIGN(size);
+		early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
+	}
+#endif
+
+	for (src = __ivt_start; src < __ivt_end; src++, dst++)
+		*dst = *src;
+
+	/* Initialize global data */
+	per_cpu(KM, 0) = 0x1;	/* We start in kernel mode */
+	per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
+}
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *of_debugfs_root;
+
+static int microblaze_debugfs_init(void)
+{
+	of_debugfs_root = debugfs_create_dir("microblaze", NULL);
+
+	return of_debugfs_root == NULL;
+}
+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.29-gnu1/arch/microblaze/kernel/signal.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/signal.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/signal.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/signal.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,543 @@
+/*
+ * Signal handling
+ *
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2001 NEC Corporation
+ * Copyright (C) 2001 Miles Bader <miles@gnu.org>
+ * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 1991,1992 Linus Torvalds
+ *
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
+ *
+ * This file was was derived from the sh version, arch/sh/kernel/signal.c
+ *
+ * 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/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/percpu.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/ucontext.h>
+#include <linux/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <linux/syscalls.h>
+#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int
+sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r3 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset, 1))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
+		struct pt_regs *regs)
+{
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's. */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r3 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset, 1))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+		struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+			__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+			__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+			__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+			__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+		struct pt_regs *regs)
+{
+	return do_sigaltstack(uss, uoss, regs->r1);
+}
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe {
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+struct rt_sigframe {
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned long tramp[2];	/* signal trampoline */
+};
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p)
+{
+	unsigned int err = 0;
+
+#define COPY(x)		{err |= __get_user(regs->x, &sc->regs.x); }
+	COPY(r0);
+	COPY(r1);
+	COPY(r2);	COPY(r3);	COPY(r4);	COPY(r5);
+	COPY(r6);	COPY(r7);	COPY(r8);	COPY(r9);
+	COPY(r10);	COPY(r11);	COPY(r12);	COPY(r13);
+	COPY(r14);	COPY(r15);	COPY(r16);	COPY(r17);
+	COPY(r18);	COPY(r19);	COPY(r20);	COPY(r21);
+	COPY(r22);	COPY(r23);	COPY(r24);	COPY(r25);
+	COPY(r26);	COPY(r27);	COPY(r28);	COPY(r29);
+	COPY(r30);	COPY(r31);
+	COPY(pc);	COPY(ear);	COPY(esr);	COPY(fsr);
+#undef COPY
+
+	*rval_p = regs->r3;
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame =
+			(struct sigframe *)(regs->r1 + STATE_SAVE_ARG_SPACE);
+
+	sigset_t set;
+	int rval;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+		|| (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+					sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->sc, &rval))
+		goto badframe;
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame =
+			(struct rt_sigframe *)(regs->r1 + STATE_SAVE_ARG_SPACE);
+
+	sigset_t set;
+	stack_t st;
+	int rval;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
+		goto badframe;
+
+	if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	 call it and ignore errors. */
+	do_sigaltstack(&st, NULL, regs->r1);
+
+	return rval;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+		unsigned long mask)
+{
+	int err = 0;
+
+#define COPY(x)		{err |= __put_user(regs->x, &sc->regs.x); }
+	COPY(r0);
+	COPY(r1);
+	COPY(r2);	COPY(r3);	COPY(r4);	COPY(r5);
+	COPY(r6);	COPY(r7);	COPY(r8);	COPY(r9);
+	COPY(r10);	COPY(r11);	COPY(r12);	COPY(r13);
+	COPY(r14);	COPY(r15);	COPY(r16);	COPY(r17);
+	COPY(r18);	COPY(r19);	COPY(r20);	COPY(r21);
+	COPY(r22);	COPY(r23);	COPY(r24);	COPY(r25);
+	COPY(r26);	COPY(r27);	COPY(r28);	COPY(r29);
+	COPY(r30);	COPY(r31);
+	COPY(pc);	COPY(ear);	COPY(esr);	COPY(fsr);
+#undef COPY
+
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	/* Default to using normal stack */
+	unsigned long sp = regs->r1;
+
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -8UL);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+					sizeof(frame->extramask));
+	}
+
+	/* Set up to return from userspace. If provided, use a stub
+	 already in userspace. */
+	/* minus 8 is offset to cater for "rtsd r15,8" offset */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+	} else {
+		/* Note, these encodings are _big endian_! */
+
+		/* addi r12, r0, __NR_sigreturn */
+		err |= __put_user(0x31800000 | __NR_sigreturn ,
+				frame->tramp + 0);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+		/* Return from sighandler will jump to the tramp.
+		 Negative 8 offset because return is rtsd r15, 8 */
+		regs->r15 = ((unsigned long)frame->tramp)-8;
+
+		__invalidate_cache_sigtramp((unsigned long)frame->tramp);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->r1 = (unsigned long) frame - STATE_SAVE_ARG_SPACE;
+
+	/* Signal handler args: */
+	regs->r5 = signal; /* Arg 0: signum */
+	regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */
+
+	/* Offset of 4 to handle microblaze rtid r14, 0 */
+	regs->pc = (unsigned long)ka->sa.sa_handler;
+
+	set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+	printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+		current->comm, current->pid, frame, regs->pc);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext. */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			&frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->r1),
+			&frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext,
+			regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Set up to return from userspace. If provided, use a stub
+	 already in userspace. */
+	/* minus 8 is offset to cater for "rtsd r15,8" */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
+	} else {
+		/* addi r12, r0, __NR_sigreturn */
+		err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
+				frame->tramp + 0);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
+
+		/* Return from sighandler will jump to the tramp.
+		 Negative 8 offset because return is rtsd r15, 8 */
+		regs->r15 = ((unsigned long)frame->tramp)-8;
+
+		__invalidate_cache_sigtramp((unsigned long)frame->tramp);
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	regs->r1 = (unsigned long) frame - STATE_SAVE_ARG_SPACE;
+
+	/* Signal handler args: */
+	regs->r5 = signal; /* arg 0: signum */
+	regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
+	regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
+	/* Offset to handle microblaze rtid r14, 0 */
+	regs->pc = (unsigned long)ka->sa.sa_handler;
+
+	set_fs(USER_DS);
+
+#ifdef DEBUG_SIG
+	printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+		current->comm, current->pid, frame, regs->pc);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+/* Handle restarting system calls */
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+	switch (regs->r3) {
+	case -ERESTART_RESTARTBLOCK:
+	case -ERESTARTNOHAND:
+		if (!has_handler)
+			goto do_restart;
+		regs->r3 = -EINTR;
+		break;
+	case -ERESTARTSYS:
+		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+			regs->r3 = -EINTR;
+			break;
+	}
+	/* fallthrough */
+	case -ERESTARTNOINTR:
+do_restart:
+		/* offset of 4 bytes to re-execute trap (brki) instruction */
+		regs->pc -= 4;
+		break;
+	}
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+		siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+{
+	/* Set up the stack frame */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,
+				&current->blocked, &ka->sa.sa_mask);
+		sigaddset(&current->blocked, sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
+{
+	siginfo_t info;
+	int signr;
+	struct k_sigaction ka;
+#ifdef DEBUG_SIG
+	printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall);
+	printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
+			regs->r12, current_thread_info()->flags);
+#endif
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (kernel_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		/* Whee! Actually deliver the signal. */
+		if (in_syscall)
+			handle_restart(regs, &ka, 1);
+		handle_signal(signr, &ka, &info, oldset, regs);
+		return 1;
+	}
+
+	if (in_syscall)
+		handle_restart(regs, NULL, 0);
+
+	/* Did we come from a system call? */
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/syscall_table.S linux-libre-2.6.30-gnu1/arch/microblaze/kernel/syscall_table.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/syscall_table.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/syscall_table.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,367 @@
+ENTRY(sys_call_table)
+	.long sys_restart_syscall	/* 0 - old "setup()" system call,
+					 * used for restarting */
+	.long sys_exit
+	.long sys_ni_syscall		/* was fork */
+	.long sys_read
+	.long sys_write
+	.long sys_open			/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink		/* 10 */
+	.long sys_execve_wrapper
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod			/* 15 */
+	.long sys_lchown
+	.long sys_ni_syscall		/* old break syscall holder */
+	.long sys_ni_syscall		/* old stat */
+	.long sys_lseek
+	.long sys_getpid		/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid
+	.long sys_getuid
+	.long sys_stime			/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_ni_syscall		/* oldfstat */
+	.long sys_pause
+	.long sys_utime			/* 30 */
+	.long sys_ni_syscall		/* old stty syscall holder */
+	.long sys_ni_syscall		/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall		/* 35 - old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir			/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall		/* old prof syscall holder */
+	.long sys_brk			/* 45 */
+	.long sys_setgid
+	.long sys_getgid
+	.long sys_signal
+	.long sys_geteuid
+	.long sys_getegid		/* 50 */
+	.long sys_acct
+	.long sys_umount		/* recycled never used phys() */
+	.long sys_ni_syscall		/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl			/* 55 */
+	.long sys_ni_syscall		/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall		/* old ulimit syscall holder */
+	.long sys_ni_syscall		/* olduname */
+	.long sys_umask			/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp		/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid		/* 70 */
+	.long sys_setregid
+	.long sys_sigsuspend_wrapper
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit		/* 75 */
+	.long sys_ni_syscall		/* old_getrlimit */
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups		/* 80 */
+	.long sys_setgroups
+	.long sys_ni_syscall		/* old_select */
+	.long sys_symlink
+	.long sys_ni_syscall		/* oldlstat */
+	.long sys_readlink		/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long sys_ni_syscall		/* old_readdir */
+	.long sys_mmap			/* 90 */ /* old_mmap */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown		/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall		/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs		/* 100 */
+	.long sys_ni_syscall		/* ioperm */
+	.long sys_socketcall
+	.long sys_syslog		/* operation with system console */
+	.long sys_setitimer
+	.long sys_getitimer		/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_ni_syscall		/* uname */
+	.long sys_ni_syscall		/* 110 */ /* iopl */
+	.long sys_vhangup
+	.long sys_ni_syscall		/* old "idle" system call */
+	.long sys_ni_syscall		/* old sys_vm86old */
+	.long sys_wait4
+	.long sys_swapoff		/* 115 */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn_wrapper
+	.long sys_clone_wrapper		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_ni_syscall		/* modify_ldt */
+	.long sys_adjtimex
+	.long sys_mprotect		/* 125:	sys_mprotect */
+	.long sys_sigprocmask
+	.long sys_ni_syscall		/* old "create_module" */
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_ni_syscall		/* 130:	old "get_kernel_syms" */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs			/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall		/* reserved for afs_syscall */
+	.long sys_setfsuid
+	.long sys_setfsgid
+	.long sys_llseek		/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_msync
+	.long sys_readv			/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150:	sys_mlock */
+	.long sys_munlock
+	.long sys_mlockall
+	.long sys_munlockall
+	.long sys_sched_setparam
+	.long sys_sched_getparam	/* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min	/* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_mremap
+	.long sys_setresuid
+	.long sys_getresuid		/* 165 */
+	.long sys_ni_syscall		/* sys_vm86 */
+	.long sys_ni_syscall		/* Old sys_query_module */
+	.long sys_poll
+	.long sys_nfsservctl
+	.long sys_setresgid		/* 170 */
+	.long sys_getresgid
+	.long sys_prctl
+	.long sys_rt_sigreturn_wrapper
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask	/* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend_wrapper
+	.long sys_pread64		/* 180 */
+	.long sys_pwrite64
+	.long sys_chown
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset		/* 185 */
+	.long sys_ni_syscall		/* sigaltstack */
+	.long sys_sendfile
+	.long sys_ni_syscall		/* reserved for streams1 */
+	.long sys_ni_syscall		/* reserved for streams2 */
+	.long sys_vfork_wrapper		/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2			/* mmap2 */
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64		/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_lchown
+	.long sys_getuid
+	.long sys_getgid		/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups		/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid		/* 210 */
+	.long sys_getresgid
+	.long sys_chown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid		/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_mincore
+	.long sys_madvise
+	.long sys_getdents64		/* 220 */
+	.long sys_fcntl64
+	.long sys_ni_syscall		/* reserved for TUX */
+	.long sys_ni_syscall
+	.long sys_gettid
+	.long sys_readahead		/* 225 */
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr
+	.long sys_getxattr
+	.long sys_lgetxattr		/* 230 */
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr
+	.long sys_flistxattr
+	.long sys_removexattr		/* 235 */
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_tkill
+	.long sys_sendfile64
+	.long sys_futex			/* 240 */
+	.long sys_sched_setaffinity
+	.long sys_sched_getaffinity
+	.long sys_ni_syscall		/* set_thread_area */
+	.long sys_ni_syscall		/* get_thread_area */
+	.long sys_io_setup		/* 245 */
+	.long sys_io_destroy
+	.long sys_io_getevents
+	.long sys_io_submit
+	.long sys_io_cancel
+	.long sys_fadvise64		/* 250 */
+	.long sys_ni_syscall
+	.long sys_exit_group
+	.long sys_lookup_dcookie
+	.long sys_epoll_create
+	.long sys_epoll_ctl		/* 255 */
+	.long sys_epoll_wait
+	.long sys_remap_file_pages
+	.long sys_set_tid_address
+	.long sys_timer_create
+	.long sys_timer_settime		/* 260 */
+	.long sys_timer_gettime
+	.long sys_timer_getoverrun
+	.long sys_timer_delete
+	.long sys_clock_settime
+	.long sys_clock_gettime		/* 265 */
+	.long sys_clock_getres
+	.long sys_clock_nanosleep
+	.long sys_statfs64
+	.long sys_fstatfs64
+	.long sys_tgkill		/* 270 */
+	.long sys_utimes
+	.long sys_fadvise64_64
+	.long sys_ni_syscall		/* sys_vserver */
+	.long sys_mbind
+	.long sys_get_mempolicy
+	.long sys_set_mempolicy
+	.long sys_mq_open
+	.long sys_mq_unlink
+	.long sys_mq_timedsend
+	.long sys_mq_timedreceive	/* 280 */
+	.long sys_mq_notify
+	.long sys_mq_getsetattr
+	.long sys_kexec_load
+	.long sys_waitid
+	.long sys_ni_syscall		/* 285 */ /* available */
+	.long sys_add_key
+	.long sys_request_key
+	.long sys_keyctl
+	.long sys_ioprio_set
+	.long sys_ioprio_get		/* 290 */
+	.long sys_inotify_init
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch
+	.long sys_ni_syscall		/* sys_migrate_pages */
+	.long sys_openat	/* 295 */
+	.long sys_mkdirat
+	.long sys_mknodat
+	.long sys_fchownat
+	.long sys_ni_syscall
+	.long sys_fstatat64		/* 300 */
+	.long sys_unlinkat
+	.long sys_renameat
+	.long sys_linkat
+	.long sys_symlinkat
+	.long sys_readlinkat		/* 305 */
+	.long sys_fchmodat
+	.long sys_faccessat
+	.long sys_ni_syscall /* pselect6 */
+	.long sys_ni_syscall /* sys_ppoll */
+	.long sys_unshare		/* 310 */
+	.long sys_set_robust_list
+	.long sys_get_robust_list
+	.long sys_splice
+	.long sys_sync_file_range
+	.long sys_tee 			/* 315 */
+	.long sys_vmsplice
+	.long sys_move_pages
+	.long sys_getcpu
+	.long sys_epoll_pwait
+	.long sys_utimensat		/* 320 */
+	.long sys_signalfd
+	.long sys_timerfd_create
+	.long sys_eventfd
+	.long sys_fallocate
+	.long sys_semtimedop		/* 325 */
+	.long sys_timerfd_settime
+	.long sys_timerfd_gettime
+	.long sys_semctl
+	.long sys_semget
+	.long sys_semop			/* 330 */
+	.long sys_msgctl
+	.long sys_msgget
+	.long sys_msgrcv
+	.long sys_msgsnd
+	.long sys_shmat			/* 335 */
+	.long sys_shmctl
+	.long sys_shmdt
+	.long sys_shmget
+	.long sys_signalfd4	/* new syscall */
+	.long sys_eventfd2		/* 340 */
+	.long sys_epoll_create1
+	.long sys_dup3
+	.long sys_pipe2
+	.long sys_inotify_init1
+	.long sys_socket		/* 345 */
+	.long sys_socketpair
+	.long sys_bind
+	.long sys_listen
+	.long sys_accept
+	.long sys_connect		/* 350 */
+	.long sys_getsockname
+	.long sys_getpeername
+	.long sys_sendto
+	.long sys_send
+	.long sys_recvfrom		/* 355 */
+	.long sys_recv
+	.long sys_setsockopt
+	.long sys_getsockopt
+	.long sys_shutdown
+	.long sys_sendmsg		/* 360 */
+	.long sys_recvmsg
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_ni_syscall
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/sys_microblaze.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/sys_microblaze.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/sys_microblaze.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/sys_microblaze.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,225 @@
+/*
+ * 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) 2006 Atmark Techno, Inc.
+ *	Yasushi SHOJI <yashi@atmark-techno.com>
+ *	Tetsuya OHKAWA <tetsuya@atmark-techno.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/errno.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/syscalls.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/mman.h>
+#include <linux/sys.h>
+#include <linux/ipc.h>
+#include <linux/utsname.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/unistd.h>
+
+#include <asm/syscalls.h>
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. This will be remove with new toolchain.
+ */
+asmlinkage int
+sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	ret = -EINVAL;
+	switch (call) {
+	case SEMOP:
+		ret = sys_semop(first, (struct sembuf *)ptr, second);
+		break;
+	case SEMGET:
+		ret = sys_semget(first, second, third);
+		break;
+	case SEMCTL:
+	{
+		union semun fourth;
+
+		if (!ptr)
+			break;
+		ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
+				|| (get_user(fourth.__pad, (void **)ptr)) ;
+		if (ret)
+			break;
+		ret = sys_semctl(first, second, third, fourth);
+		break;
+	}
+	case MSGSND:
+		ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third);
+		break;
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+
+			if (!ptr)
+				break;
+			ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp))
+				? 0 : -EFAULT) || copy_from_user(&tmp,
+				(struct ipc_kludge *) ptr, sizeof(tmp));
+			if (ret)
+				break;
+			ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp,
+					third);
+			break;
+			}
+		default:
+			ret = sys_msgrcv(first, (struct msgbuf *) ptr,
+					second, fifth, third);
+			break;
+		}
+		break;
+	case MSGGET:
+		ret = sys_msgget((key_t) first, second);
+		break;
+	case MSGCTL:
+		ret = sys_msgctl(first, second, (struct msqid_ds *) ptr);
+		break;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = access_ok(VERIFY_WRITE, (ulong *) third,
+					sizeof(ulong)) ? 0 : -EFAULT;
+			if (ret)
+				break;
+			ret = do_shmat(first, (char *) ptr, second, &raddr);
+			if (ret)
+				break;
+			ret = put_user(raddr, (ulong *) third);
+			break;
+			}
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				break;
+			ret = do_shmat(first, (char *) ptr, second,
+					(ulong *) third);
+			break;
+		}
+		break;
+	case SHMDT:
+		ret = sys_shmdt((char *)ptr);
+		break;
+	case SHMGET:
+		ret = sys_shmget(first, second, third);
+		break;
+	case SHMCTL:
+		ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
+		break;
+	}
+	return ret;
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
+						regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
+{
+	if (!stack)
+		stack = regs->r1;
+	return do_fork(flags, stack, regs, 0, NULL, NULL);
+}
+
+asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+			char __user *__user *envp, struct pt_regs *regs)
+{
+	int error;
+	char *filename;
+
+	filename = getname(filenamei);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+out:
+	return error;
+}
+
+asmlinkage unsigned long
+sys_mmap2(unsigned long addr, size_t 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 unsigned long sys_mmap(unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, off_t offset)
+{
+	int err = -EINVAL;
+
+	if (offset & ~PAGE_MASK) {
+		printk(KERN_INFO "no pagemask in mmap\r\n");
+		goto out;
+	}
+
+	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+	return err;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register const char *__a __asm__("r5") = filename;
+	register const void *__b __asm__("r6") = argv;
+	register const void *__c __asm__("r7") = envp;
+	register unsigned long __syscall __asm__("r12") = __NR_execve;
+	register unsigned long __ret __asm__("r3");
+	__asm__ __volatile__ ("brki r14, 0x8"
+			: "=r" (__ret), "=r" (__syscall)
+			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
+			: "r4", "r8", "r9",
+			"r10", "r11", "r14", "cc", "memory");
+	return __ret;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/timer.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/timer.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/kernel.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/cpuinfo.h>
+#include <asm/setup.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SELFMOD_TIMER
+#include <asm/selfmod.h>
+#define TIMER_BASE	BARRIER_BASE_ADDR
+#else
+static unsigned int timer_baseaddr;
+#define TIMER_BASE	timer_baseaddr
+#endif
+
+#define TCSR0	(0x00)
+#define TLR0	(0x04)
+#define TCR0	(0x08)
+#define TCSR1	(0x10)
+#define TLR1	(0x14)
+#define TCR1	(0x18)
+
+#define TCSR_MDT	(1<<0)
+#define TCSR_UDT	(1<<1)
+#define TCSR_GENT	(1<<2)
+#define TCSR_CAPT	(1<<3)
+#define TCSR_ARHT	(1<<4)
+#define TCSR_LOAD	(1<<5)
+#define TCSR_ENIT	(1<<6)
+#define TCSR_ENT	(1<<7)
+#define TCSR_TINT	(1<<8)
+#define TCSR_PWMA	(1<<9)
+#define TCSR_ENALL	(1<<10)
+
+static inline void microblaze_timer0_stop(void)
+{
+	out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT);
+}
+
+static inline void microblaze_timer0_start_periodic(unsigned long load_val)
+{
+	if (!load_val)
+		load_val = 1;
+	out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+	/* load the initial value */
+	out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+	/* see timer data sheet for detail
+	 * !ENALL - don't enable 'em all
+	 * !PWMA - disable pwm
+	 * TINT - clear interrupt status
+	 * ENT- enable timer itself
+	 * EINT - enable interrupt
+	 * !LOAD - clear the bit to let go
+	 * ARHT - auto reload
+	 * !CAPT - no external trigger
+	 * !GENT - no external signal
+	 * UDT - set the timer as down counter
+	 * !MDT0 - generate mode
+	 */
+	out_be32(TIMER_BASE + TCSR0,
+			TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static inline void microblaze_timer0_start_oneshot(unsigned long load_val)
+{
+	if (!load_val)
+		load_val = 1;
+	out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+
+	/* load the initial value */
+	out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+
+	out_be32(TIMER_BASE + TCSR0,
+			TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+}
+
+static int microblaze_timer_set_next_event(unsigned long delta,
+					struct clock_event_device *dev)
+{
+	pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
+	microblaze_timer0_start_oneshot(delta);
+	return 0;
+}
+
+static void microblaze_timer_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		printk(KERN_INFO "%s: periodic\n", __func__);
+		microblaze_timer0_start_periodic(cpuinfo.freq_div_hz);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		printk(KERN_INFO "%s: oneshot\n", __func__);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+		printk(KERN_INFO "%s: unused\n", __func__);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		printk(KERN_INFO "%s: shutdown\n", __func__);
+		microblaze_timer0_stop();
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		printk(KERN_INFO "%s: resume\n", __func__);
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_microblaze_timer = {
+	.name		= "microblaze_clockevent",
+	.features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 24,
+	.rating		= 300,
+	.set_next_event	= microblaze_timer_set_next_event,
+	.set_mode	= microblaze_timer_set_mode,
+};
+
+static inline void timer_ack(void)
+{
+	out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0));
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_microblaze_timer;
+#ifdef CONFIG_HEART_BEAT
+	heartbeat();
+#endif
+	timer_ack();
+	evt->event_handler(evt);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction timer_irqaction = {
+	.handler = timer_interrupt,
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.name = "timer",
+	.dev_id = &clockevent_microblaze_timer,
+};
+
+static __init void microblaze_clockevent_init(void)
+{
+	clockevent_microblaze_timer.mult =
+		div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC,
+				clockevent_microblaze_timer.shift);
+	clockevent_microblaze_timer.max_delta_ns =
+		clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
+	clockevent_microblaze_timer.min_delta_ns =
+		clockevent_delta2ns(1, &clockevent_microblaze_timer);
+	clockevent_microblaze_timer.cpumask = cpumask_of(0);
+	clockevents_register_device(&clockevent_microblaze_timer);
+}
+
+static cycle_t microblaze_read(struct clocksource *cs)
+{
+	/* reading actual value of timer 1 */
+	return (cycle_t) (in_be32(TIMER_BASE + TCR1));
+}
+
+static struct clocksource clocksource_microblaze = {
+	.name		= "microblaze_clocksource",
+	.rating		= 300,
+	.read		= microblaze_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 24, /* I can shift it */
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init microblaze_clocksource_init(void)
+{
+	clocksource_microblaze.mult =
+			clocksource_hz2mult(cpuinfo.cpu_clock_freq,
+						clocksource_microblaze.shift);
+	if (clocksource_register(&clocksource_microblaze))
+		panic("failed to register clocksource");
+
+	/* stop timer1 */
+	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);
+	return 0;
+}
+
+void __init time_init(void)
+{
+	u32 irq, i = 0;
+	u32 timer_num = 1;
+	struct device_node *timer = NULL;
+#ifdef CONFIG_SELFMOD_TIMER
+	unsigned int timer_baseaddr = 0;
+	int arr_func[] = {
+				(int)&microblaze_read,
+				(int)&timer_interrupt,
+				(int)&microblaze_clocksource_init,
+				(int)&microblaze_timer_set_mode,
+				(int)&microblaze_timer_set_next_event,
+				0
+			};
+#endif
+	char *timer_list[] = {
+				"xlnx,xps-timer-1.00.a",
+				"xlnx,opb-timer-1.00.b",
+				"xlnx,opb-timer-1.00.a",
+				NULL
+			};
+
+	for (i = 0; timer_list[i] != NULL; i++) {
+		timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
+		if (timer)
+			break;
+	}
+
+	timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
+	timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
+	irq = *(int *) of_get_property(timer, "interrupts", NULL);
+	timer_num =
+		*(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
+	if (timer_num) {
+		printk(KERN_EMERG "Please enable two timers in HW\n");
+		BUG();
+	}
+
+#ifdef CONFIG_SELFMOD_TIMER
+	selfmod_function((int *) arr_func, timer_baseaddr);
+#endif
+	printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
+		timer_list[i], timer_baseaddr, irq);
+
+	cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ;
+
+	setup_irq(irq, &timer_irqaction);
+#ifdef CONFIG_HEART_BEAT
+	setup_heartbeat();
+#endif
+	microblaze_clocksource_init();
+	microblaze_clockevent_init();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/traps.c linux-libre-2.6.30-gnu1/arch/microblaze/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/traps.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/kallsyms.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/debug_locks.h>
+
+#include <asm/exceptions.h>
+#include <asm/system.h>
+
+void trap_init(void)
+{
+	__enable_hw_exceptions();
+}
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+	printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+		__builtin_return_address(0), ptr, size);
+	BUG();
+}
+EXPORT_SYMBOL(__bad_xchg);
+
+static int kstack_depth_to_print = 24;
+
+static int __init kstack_setup(char *s)
+{
+	kstack_depth_to_print = strict_strtoul(s, 0, NULL);
+
+	return 1;
+}
+__setup("kstack=", kstack_setup);
+
+void show_trace(struct task_struct *task, unsigned long *stack)
+{
+	unsigned long addr;
+
+	if (!stack)
+		stack = (unsigned long *)&stack;
+
+	printk(KERN_NOTICE "Call Trace: ");
+#ifdef CONFIG_KALLSYMS
+	printk(KERN_NOTICE "\n");
+#endif
+	while (!kstack_end(stack)) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (kernel_text_address(addr))
+			print_ip_sym(addr);
+	}
+	printk(KERN_NOTICE "\n");
+
+	if (!task)
+		task = current;
+
+	debug_show_held_locks(task);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	unsigned long *stack;
+	int i;
+
+	if (sp == NULL) {
+		if (task)
+			sp = (unsigned long *) ((struct thread_info *)
+						(task->stack))->cpu_context.r1;
+		else
+			sp = (unsigned long *)&sp;
+	}
+
+	stack = sp;
+
+	printk(KERN_INFO "\nStack:\n  ");
+
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (kstack_end(sp))
+			break;
+		if (i && ((i % 8) == 0))
+			printk("\n  ");
+		printk("%08lx ", *sp++);
+	}
+	printk("\n");
+	show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+	show_stack(NULL, NULL);
+}
+EXPORT_SYMBOL(dump_stack);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/microblaze/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/kernel/vmlinux.lds.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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.
+ */
+
+OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+#include <asm-generic/vmlinux.lds.h>
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+	. = CONFIG_KERNEL_BASE_ADDR;
+
+	.text : {
+		_text = . ;
+		_stext = . ;
+		*(.text .text.*)
+		*(.fixup)
+
+		*(.exitcall.exit)
+		SCHED_TEXT
+		LOCK_TEXT
+		KPROBES_TEXT
+		. = ALIGN (4) ;
+		_etext = . ;
+	}
+
+	. = ALIGN (4) ;
+	_fdt_start = . ; /* place for fdt blob */
+	. = . + 0x4000;
+	_fdt_end = . ;
+
+	. = ALIGN(16);
+	RODATA
+	. = ALIGN(16);
+	__ex_table : {
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+	}
+
+	/*
+	 * sdata2 section can go anywhere, but must be word aligned
+	 * and SDA2_BASE must point to the middle of it
+	 */
+	.sdata2 : {
+		_ssrw = .;
+		. = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */
+		*(.sdata2)
+	. = ALIGN(8);
+	_essrw = .;
+	_ssrw_size = _essrw - _ssrw;
+	_KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
+	}
+
+	_sdata = . ;
+	.data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */
+		*(.data)
+	}
+	. = ALIGN(32);
+	.data.cacheline_aligned : { *(.data.cacheline_aligned) }
+	_edata = . ;
+
+	/* Reserve some low RAM for r0 based memory references */
+	. = ALIGN(0x4) ;
+	r0_ram = . ;
+	. = . +  4096;	/* a page should be enough */
+
+	/* The initial task */
+	. = ALIGN(8192);
+	.data.init_task : { *(.data.init_task) }
+
+	/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
+	. = ALIGN(8);
+	.sdata : {
+		_ssro = .;
+		*(.sdata)
+	}
+
+	.sbss :	{
+		_ssbss = .;
+		*(.sbss)
+		_esbss = .;
+		_essro = .;
+		_ssro_size = _essro - _ssro ;
+		_KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
+	}
+
+	__init_begin = .;
+
+	. = ALIGN(4096);
+	.init.text : {
+		_sinittext = . ;
+		*(.init.text)
+		*(.exit.text)
+		*(.exit.data)
+		_einittext = .;
+	}
+
+	.init.data : { *(.init.data) }
+
+	. = ALIGN(4);
+	.init.ivt : {
+		__ivt_start = .;
+		*(.init.ivt)
+		__ivt_end = .;
+	}
+
+	.init.setup : {
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+	}
+
+	.initcall.init : {
+		__initcall_start = .;
+		INITCALLS
+		__initcall_end = .;
+	}
+
+	.con_initcall.init : {
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+	}
+
+	__init_end_before_initramfs = .;
+
+	.init.ramfs ALIGN(4096) : {
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+		. = ALIGN(4);
+		LONG(0);
+/*
+ * FIXME this can break initramfs for MMU.
+ * Pad init.ramfs up to page boundary,
+ * so that __init_end == __bss_start. This will make image.elf
+ * consistent with the image.bin
+ */
+		/* . = ALIGN(4096); */
+	}
+	__init_end = .;
+
+	.bss ALIGN (4096) : { /* page aligned when MMU used */
+		__bss_start = . ;
+			*(.bss*)
+			*(COMMON)
+		. = ALIGN (4) ;
+		__bss_stop = . ;
+		_ebss = . ;
+	}
+	. = ALIGN(4096);
+	_end = .;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/checksum.c linux-libre-2.6.30-gnu1/arch/microblaze/lib/checksum.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/checksum.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/checksum.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ *
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
+ *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *		Tom May, <ftom@netcom.com>
+ *		Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
+ *		Lots of code moved from tcp.c and ip.c; see those files
+ *		for more names.
+ *
+ * 03/02/96	Jes Sorensen, Andreas Schwab, Roman Hodek:
+ *		Fixed some nasty bugs, causing some horrible crashes.
+ *		A: At some points, the sum (%0) was used as
+ *		length-counter instead of the length counter
+ *		(%1). Thanks to Roman Hodek for pointing this out.
+ *		B: GCC seems to mess up if one uses too many
+ *		data-registers to hold input values and one tries to
+ *		specify d0 and d1 as scratch registers. Letting gcc
+ *		choose these registers itself solves the problem.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
+ kills, so most of the assembly has to go. */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+#include <linux/module.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+static unsigned int do_csum(const unsigned char *buff, int len)
+{
+	int odd, count;
+	unsigned long result = 0;
+
+	if (len <= 0)
+		goto out;
+	odd = 1 & (unsigned long) buff;
+	if (odd) {
+		result = *buff;
+		len--;
+		buff++;
+	}
+	count = len >> 1;		/* nr of 16-bit words.. */
+	if (count) {
+		if (2 & (unsigned long) buff) {
+			result += *(unsigned short *) buff;
+			count--;
+			len -= 2;
+			buff += 2;
+		}
+		count >>= 1;		/* nr of 32-bit words.. */
+		if (count) {
+			unsigned long carry = 0;
+			do {
+				unsigned long w = *(unsigned long *) buff;
+				count--;
+				buff += 4;
+				result += carry;
+				result += w;
+				carry = (w > result);
+			} while (count);
+			result += carry;
+			result = (result & 0xffff) + (result >> 16);
+		}
+		if (len & 2) {
+			result += *(unsigned short *) buff;
+			buff += 2;
+		}
+	}
+	if (len & 1)
+		result += (*buff << 8);
+	result = from32to16(result);
+	if (odd)
+		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+	return result;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	return (__force __sum16)~do_csum(iph, ihl*4);
+}
+
+/*
+ * 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)
+{
+	unsigned int result = do_csum(buff, len);
+
+	/* add in old sum, and carry.. */
+	result += sum;
+	if (sum > result)
+		result += 1;
+	return result;
+}
+EXPORT_SYMBOL(csum_partial);
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+__sum16 ip_compute_csum(const unsigned char *buff, int len)
+{
+	return ~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 char __user *src, char *dst, int len,
+						int sum, int *csum_err)
+{
+	if (csum_err)
+		*csum_err = 0;
+	memcpy(dst, 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 char *src, char *dst, int len, int sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+EXPORT_SYMBOL(csum_partial_copy);
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/fastcopy.S linux-libre-2.6.30-gnu1/arch/microblaze/lib/fastcopy.S
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/fastcopy.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/fastcopy.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,662 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2008 Jim Law - Iris LP  All rights reserved.
+ *
+ * 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.
+ *
+ * Written by Jim Law <jlaw@irispower.com>
+ *
+ * intended to replace:
+ *	memcpy in memcpy.c and
+ *	memmove in memmove.c
+ * ... in arch/microblaze/lib
+ *
+ *
+ * assly_fastcopy.S
+ *
+ * Attempt at quicker memcpy and memmove for MicroBlaze
+ *	Input :	Operand1 in Reg r5 - destination address
+ *		Operand2 in Reg r6 - source address
+ *		Operand3 in Reg r7 - number of bytes to transfer
+ *	Output: Result in Reg r3 - starting destinaition address
+ *
+ *
+ * Explanation:
+ *	Perform (possibly unaligned) copy of a block of memory
+ *	between mem locations with size of xfer spec'd in bytes
+ */
+
+#include <linux/linkage.h>
+
+	.globl	memcpy
+	.ent	memcpy
+
+memcpy:
+fast_memcpy_ascending:
+	/* move d to return register as value of function */
+	addi	r3, r5, 0
+
+	addi	r4, r0, 4	/* n = 4 */
+	cmpu	r4, r4, r7	/* n = c - n  (unsigned) */
+	blti	r4, a_xfer_end	/* if n < 0, less than one word to transfer */
+
+	/* transfer first 0~3 bytes to get aligned dest address */
+	andi	r4, r5, 3		/* n = d & 3 */
+	/* if zero, destination already aligned */
+	beqi	r4, a_dalign_done
+	/* n = 4 - n (yields 3, 2, 1 transfers for 1, 2, 3 addr offset) */
+	rsubi	r4, r4, 4
+	rsub	r7, r4, r7		/* c = c - n adjust c */
+
+a_xfer_first_loop:
+	/* if no bytes left to transfer, transfer the bulk */
+	beqi	r4, a_dalign_done
+	lbui	r11, r6, 0		/* h = *s */
+	sbi	r11, r5, 0		/* *d = h */
+	addi	r6, r6, 1		/* s++ */
+	addi	r5, r5, 1		/* d++ */
+	brid	a_xfer_first_loop	/* loop */
+	addi	r4, r4, -1		/* n-- (IN DELAY SLOT) */
+
+a_dalign_done:
+	addi	r4, r0, 32		/* n = 32 */
+	cmpu	r4, r4, r7		/* n = c - n  (unsigned) */
+	/* if n < 0, less than one block to transfer */
+	blti	r4, a_block_done
+
+a_block_xfer:
+	andi	r4, r7, 0xffffffe0	/* n = c & ~31 */
+	rsub	r7, r4, r7		/* c = c - n */
+
+	andi	r9, r6, 3		/* t1 = s & 3 */
+	/* if temp != 0, unaligned transfers needed */
+	bnei	r9, a_block_unaligned
+
+a_block_aligned:
+	lwi	r9, r6, 0		/* t1 = *(s + 0) */
+	lwi	r10, r6, 4		/* t2 = *(s + 4) */
+	lwi	r11, r6, 8		/* t3 = *(s + 8) */
+	lwi	r12, r6, 12		/* t4 = *(s + 12) */
+	swi	r9, r5, 0		/* *(d + 0) = t1 */
+	swi	r10, r5, 4		/* *(d + 4) = t2 */
+	swi	r11, r5, 8		/* *(d + 8) = t3 */
+	swi	r12, r5, 12		/* *(d + 12) = t4 */
+	lwi	r9, r6, 16		/* t1 = *(s + 16) */
+	lwi	r10, r6, 20		/* t2 = *(s + 20) */
+	lwi	r11, r6, 24		/* t3 = *(s + 24) */
+	lwi	r12, r6, 28		/* t4 = *(s + 28) */
+	swi	r9, r5, 16		/* *(d + 16) = t1 */
+	swi	r10, r5, 20		/* *(d + 20) = t2 */
+	swi	r11, r5, 24		/* *(d + 24) = t3 */
+	swi	r12, r5, 28		/* *(d + 28) = t4 */
+	addi	r6, r6, 32		/* s = s + 32 */
+	addi	r4, r4, -32		/* n = n - 32 */
+	bneid	r4, a_block_aligned	/* while (n) loop */
+	addi	r5, r5, 32		/* d = d + 32 (IN DELAY SLOT) */
+	bri	a_block_done
+
+a_block_unaligned:
+	andi	r8, r6, 0xfffffffc	/* as = s & ~3 */
+	add	r6, r6, r4		/* s = s + n */
+	lwi	r11, r8, 0		/* h = *(as + 0) */
+
+	addi	r9, r9, -1
+	beqi	r9, a_block_u1		/* t1 was 1 => 1 byte offset */
+	addi	r9, r9, -1
+	beqi	r9, a_block_u2		/* t1 was 2 => 2 byte offset */
+
+a_block_u3:
+	bslli	r11, r11, 24	/* h = h << 24 */
+a_bu3_loop:
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 12) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	lwi	r12, r8, 32	/* v = *(as + 32) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	addi	r8, r8, 32	/* as = as + 32 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, a_bu3_loop	/* while (n) loop */
+	addi	r5, r5, 32	/* d = d + 32 (IN DELAY SLOT) */
+	bri	a_block_done
+
+a_block_u1:
+	bslli	r11, r11, 8	/* h = h << 8 */
+a_bu1_loop:
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 12) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	lwi	r12, r8, 32	/* v = *(as + 32) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	addi	r8, r8, 32	/* as = as + 32 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, a_bu1_loop	/* while (n) loop */
+	addi	r5, r5, 32	/* d = d + 32 (IN DELAY SLOT) */
+	bri	a_block_done
+
+a_block_u2:
+	bslli	r11, r11, 16	/* h = h << 16 */
+a_bu2_loop:
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 12) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	lwi	r12, r8, 32	/* v = *(as + 32) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	addi	r8, r8, 32	/* as = as + 32 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, a_bu2_loop	/* while (n) loop */
+	addi	r5, r5, 32	/* d = d + 32 (IN DELAY SLOT) */
+
+a_block_done:
+	addi	r4, r0, 4	/* n = 4 */
+	cmpu	r4, r4, r7	/* n = c - n  (unsigned) */
+	blti	r4, a_xfer_end	/* if n < 0, less than one word to transfer */
+
+a_word_xfer:
+	andi	r4, r7, 0xfffffffc	/* n = c & ~3 */
+	addi	r10, r0, 0		/* offset = 0 */
+
+	andi	r9, r6, 3		/* t1 = s & 3 */
+	/* if temp != 0, unaligned transfers needed */
+	bnei	r9, a_word_unaligned
+
+a_word_aligned:
+	lw	r9, r6, r10		/* t1 = *(s+offset) */
+	sw	r9, r5, r10		/* *(d+offset) = t1 */
+	addi	r4, r4,-4		/* n-- */
+	bneid	r4, a_word_aligned	/* loop */
+	addi	r10, r10, 4		/* offset++ (IN DELAY SLOT) */
+
+	bri	a_word_done
+
+a_word_unaligned:
+	andi	r8, r6, 0xfffffffc	/* as = s & ~3 */
+	lwi	r11, r8, 0		/* h = *(as + 0) */
+	addi	r8, r8, 4		/* as = as + 4 */
+
+	addi	r9, r9, -1
+	beqi	r9, a_word_u1		/* t1 was 1 => 1 byte offset */
+	addi	r9, r9, -1
+	beqi	r9, a_word_u2		/* t1 was 2 => 2 byte offset */
+
+a_word_u3:
+	bslli	r11, r11, 24	/* h = h << 24 */
+a_wu3_loop:
+	lw	r12, r8, r10	/* v = *(as + offset) */
+	bsrli	r9, r12, 8	/* t1 = v >> 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r10	/* *(d + offset) = t1 */
+	bslli	r11, r12, 24	/* h = v << 24 */
+	addi	r4, r4,-4	/* n = n - 4 */
+	bneid	r4, a_wu3_loop	/* while (n) loop */
+	addi	r10, r10, 4	/* offset = ofset + 4 (IN DELAY SLOT) */
+
+	bri	a_word_done
+
+a_word_u1:
+	bslli	r11, r11, 8	/* h = h << 8 */
+a_wu1_loop:
+	lw	r12, r8, r10	/* v = *(as + offset) */
+	bsrli	r9, r12, 24	/* t1 = v >> 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r10	/* *(d + offset) = t1 */
+	bslli	r11, r12, 8	/* h = v << 8 */
+	addi	r4, r4,-4	/* n = n - 4 */
+	bneid	r4, a_wu1_loop	/* while (n) loop */
+	addi	r10, r10, 4	/* offset = ofset + 4 (IN DELAY SLOT) */
+
+	bri	a_word_done
+
+a_word_u2:
+	bslli	r11, r11, 16	/* h = h << 16 */
+a_wu2_loop:
+	lw	r12, r8, r10	/* v = *(as + offset) */
+	bsrli	r9, r12, 16	/* t1 = v >> 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r10	/* *(d + offset) = t1 */
+	bslli	r11, r12, 16	/* h = v << 16 */
+	addi	r4, r4,-4	/* n = n - 4 */
+	bneid	r4, a_wu2_loop	/* while (n) loop */
+	addi	r10, r10, 4	/* offset = ofset + 4 (IN DELAY SLOT) */
+
+a_word_done:
+	add	r5, r5, r10	/* d = d + offset */
+	add	r6, r6, r10	/* s = s + offset */
+	rsub	r7, r10, r7	/* c = c - offset */
+
+a_xfer_end:
+a_xfer_end_loop:
+	beqi	r7, a_done		/* while (c) */
+	lbui	r9, r6, 0		/* t1 = *s */
+	addi	r6, r6, 1		/* s++ */
+	sbi	r9, r5, 0		/* *d = t1 */
+	addi	r7, r7, -1		/* c-- */
+	brid	a_xfer_end_loop		/* loop */
+	addi	r5, r5, 1		/* d++ (IN DELAY SLOT) */
+
+a_done:
+	rtsd	r15, 8
+	nop
+
+.end memcpy
+/*----------------------------------------------------------------------------*/
+	.globl	memmove
+	.ent	memmove
+
+memmove:
+	cmpu	r4, r5, r6	/* n = s - d */
+	bgei	r4,fast_memcpy_ascending
+
+fast_memcpy_descending:
+	/* move d to return register as value of function */
+	addi	r3, r5, 0
+
+	add	r5, r5, r7	/* d = d + c */
+	add	r6, r6, r7	/* s = s + c */
+
+	addi	r4, r0, 4	/* n = 4 */
+	cmpu	r4, r4, r7	/* n = c - n  (unsigned) */
+	blti	r4,d_xfer_end	/* if n < 0, less than one word to transfer */
+
+	/* transfer first 0~3 bytes to get aligned dest address */
+	andi	r4, r5, 3		/* n = d & 3 */
+	/* if zero, destination already aligned */
+	beqi	r4,d_dalign_done
+	rsub	r7, r4, r7		/* c = c - n adjust c */
+
+d_xfer_first_loop:
+	/* if no bytes left to transfer, transfer the bulk */
+	beqi	r4,d_dalign_done
+	addi	r6, r6, -1		/* s-- */
+	addi	r5, r5, -1		/* d-- */
+	lbui	r11, r6, 0		/* h = *s */
+	sbi	r11, r5, 0		/* *d = h */
+	brid	d_xfer_first_loop	/* loop */
+	addi	r4, r4, -1		/* n-- (IN DELAY SLOT) */
+
+d_dalign_done:
+	addi	r4, r0, 32	/* n = 32 */
+	cmpu	r4, r4, r7	/* n = c - n  (unsigned) */
+	/* if n < 0, less than one block to transfer */
+	blti	r4, d_block_done
+
+d_block_xfer:
+	andi	r4, r7, 0xffffffe0	/* n = c & ~31 */
+	rsub	r7, r4, r7		/* c = c - n */
+
+	andi	r9, r6, 3		/* t1 = s & 3 */
+	/* if temp != 0, unaligned transfers needed */
+	bnei	r9, d_block_unaligned
+
+d_block_aligned:
+	addi	r6, r6, -32		/* s = s - 32 */
+	addi	r5, r5, -32		/* d = d - 32 */
+	lwi	r9, r6, 28		/* t1 = *(s + 28) */
+	lwi	r10, r6, 24		/* t2 = *(s + 24) */
+	lwi	r11, r6, 20		/* t3 = *(s + 20) */
+	lwi	r12, r6, 16		/* t4 = *(s + 16) */
+	swi	r9, r5, 28		/* *(d + 28) = t1 */
+	swi	r10, r5, 24		/* *(d + 24) = t2 */
+	swi	r11, r5, 20		/* *(d + 20) = t3 */
+	swi	r12, r5, 16		/* *(d + 16) = t4 */
+	lwi	r9, r6, 12		/* t1 = *(s + 12) */
+	lwi	r10, r6, 8		/* t2 = *(s + 8) */
+	lwi	r11, r6, 4		/* t3 = *(s + 4) */
+	lwi	r12, r6, 0		/* t4 = *(s + 0) */
+	swi	r9, r5, 12		/* *(d + 12) = t1 */
+	swi	r10, r5, 8		/* *(d + 8) = t2 */
+	swi	r11, r5, 4		/* *(d + 4) = t3 */
+	addi	r4, r4, -32		/* n = n - 32 */
+	bneid	r4, d_block_aligned	/* while (n) loop */
+	swi	r12, r5, 0		/* *(d + 0) = t4 (IN DELAY SLOT) */
+	bri	d_block_done
+
+d_block_unaligned:
+	andi	r8, r6, 0xfffffffc	/* as = s & ~3 */
+	rsub	r6, r4, r6		/* s = s - n */
+	lwi	r11, r8, 0		/* h = *(as + 0) */
+
+	addi	r9, r9, -1
+	beqi	r9,d_block_u1		/* t1 was 1 => 1 byte offset */
+	addi	r9, r9, -1
+	beqi	r9,d_block_u2		/* t1 was 2 => 2 byte offset */
+
+d_block_u3:
+	bsrli	r11, r11, 8	/* h = h >> 8 */
+d_bu3_loop:
+	addi	r8, r8, -32	/* as = as - 32 */
+	addi	r5, r5, -32	/* d = d - 32 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 112) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bsrli	r11, r12, 8	/* h = v >> 8 */
+	lwi	r12, r8, 0	/* v = *(as + 0) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, d_bu3_loop	/* while (n) loop */
+	bsrli	r11, r12, 8	/* h = v >> 8 (IN DELAY SLOT) */
+	bri	d_block_done
+
+d_block_u1:
+	bsrli	r11, r11, 24	/* h = h >> 24 */
+d_bu1_loop:
+	addi	r8, r8, -32	/* as = as - 32 */
+	addi	r5, r5, -32	/* d = d - 32 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 112) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bsrli	r11, r12, 24	/* h = v >> 24 */
+	lwi	r12, r8, 0	/* v = *(as + 0) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, d_bu1_loop	/* while (n) loop */
+	bsrli	r11, r12, 24	/* h = v >> 24 (IN DELAY SLOT) */
+	bri	d_block_done
+
+d_block_u2:
+	bsrli	r11, r11, 16	/* h = h >> 16 */
+d_bu2_loop:
+	addi	r8, r8, -32	/* as = as - 32 */
+	addi	r5, r5, -32	/* d = d - 32 */
+	lwi	r12, r8, 28	/* v = *(as + 28) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 28	/* *(d + 28) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 24	/* v = *(as + 24) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 24	/* *(d + 24) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 20	/* v = *(as + 20) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 20	/* *(d + 20) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 16	/* v = *(as + 16) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 16	/* *(d + 16) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 12	/* v = *(as + 12) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 12	/* *(d + 112) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 8	/* v = *(as + 8) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 8	/* *(d + 8) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 4	/* v = *(as + 4) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 4	/* *(d + 4) = t1 */
+	bsrli	r11, r12, 16	/* h = v >> 16 */
+	lwi	r12, r8, 0	/* v = *(as + 0) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	swi	r9, r5, 0	/* *(d + 0) = t1 */
+	addi	r4, r4, -32	/* n = n - 32 */
+	bneid	r4, d_bu2_loop	/* while (n) loop */
+	bsrli	r11, r12, 16	/* h = v >> 16 (IN DELAY SLOT) */
+
+d_block_done:
+	addi	r4, r0, 4	/* n = 4 */
+	cmpu	r4, r4, r7	/* n = c - n  (unsigned) */
+	blti	r4,d_xfer_end	/* if n < 0, less than one word to transfer */
+
+d_word_xfer:
+	andi	r4, r7, 0xfffffffc	/* n = c & ~3 */
+	rsub	r5, r4, r5		/* d = d - n */
+	rsub	r6, r4, r6		/* s = s - n */
+	rsub	r7, r4, r7		/* c = c - n */
+
+	andi	r9, r6, 3		/* t1 = s & 3 */
+	/* if temp != 0, unaligned transfers needed */
+	bnei	r9, d_word_unaligned
+
+d_word_aligned:
+	addi	r4, r4,-4		/* n-- */
+	lw	r9, r6, r4		/* t1 = *(s+n) */
+	bneid	r4, d_word_aligned	/* loop */
+	sw	r9, r5, r4		/* *(d+n) = t1 (IN DELAY SLOT) */
+
+	bri	d_word_done
+
+d_word_unaligned:
+	andi	r8, r6, 0xfffffffc	/* as = s & ~3 */
+	lw	r11, r8, r4		/* h = *(as + n) */
+
+	addi	r9, r9, -1
+	beqi	r9,d_word_u1		/* t1 was 1 => 1 byte offset */
+	addi	r9, r9, -1
+	beqi	r9,d_word_u2		/* t1 was 2 => 2 byte offset */
+
+d_word_u3:
+	bsrli	r11, r11, 8	/* h = h >> 8 */
+d_wu3_loop:
+	addi	r4, r4,-4	/* n = n - 4 */
+	lw	r12, r8, r4	/* v = *(as + n) */
+	bslli	r9, r12, 24	/* t1 = v << 24 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r4	/* *(d + n) = t1 */
+	bneid	r4, d_wu3_loop	/* while (n) loop */
+	bsrli	r11, r12, 8	/* h = v >> 8 (IN DELAY SLOT) */
+
+	bri	d_word_done
+
+d_word_u1:
+	bsrli	r11, r11, 24	/* h = h >> 24 */
+d_wu1_loop:
+	addi	r4, r4,-4	/* n = n - 4 */
+	lw	r12, r8, r4	/* v = *(as + n) */
+	bslli	r9, r12, 8	/* t1 = v << 8 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r4	/* *(d + n) = t1 */
+	bneid	r4, d_wu1_loop	/* while (n) loop */
+	bsrli	r11, r12, 24	/* h = v >> 24 (IN DELAY SLOT) */
+
+	bri	d_word_done
+
+d_word_u2:
+	bsrli	r11, r11, 16	/* h = h >> 16 */
+d_wu2_loop:
+	addi	r4, r4,-4	/* n = n - 4 */
+	lw	r12, r8, r4	/* v = *(as + n) */
+	bslli	r9, r12, 16	/* t1 = v << 16 */
+	or	r9, r11, r9	/* t1 = h | t1 */
+	sw	r9, r5, r4	/* *(d + n) = t1 */
+	bneid	r4, d_wu2_loop	/* while (n) loop */
+	bsrli	r11, r12, 16	/* h = v >> 16 (IN DELAY SLOT) */
+
+d_word_done:
+
+d_xfer_end:
+d_xfer_end_loop:
+	beqi	r7, a_done		/* while (c) */
+	addi	r6, r6, -1		/* s-- */
+	lbui	r9, r6, 0		/* t1 = *s */
+	addi	r5, r5, -1		/* d-- */
+	sbi	r9, r5, 0		/* *d = t1 */
+	brid	d_xfer_end_loop		/* loop */
+	addi	r7, r7, -1		/* c-- (IN DELAY SLOT) */
+
+d_done:
+	rtsd	r15, 8
+	nop
+
+.end memmove
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/lib/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#
+# Makefile
+#
+
+lib-y :=  memset.o checksum.o
+
+ifeq ($(CONFIG_OPT_LIB_ASM),y)
+lib-y += fastcopy.o
+else
+lib-y += memcpy.o memmove.o
+endif
+
+lib-y +=  uaccess.o
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/memcpy.c linux-libre-2.6.30-gnu1/arch/microblaze/lib/memcpy.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/memcpy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/memcpy.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * 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
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+#include <linux/string.h>
+#include <asm/system.h>
+
+#ifdef __HAVE_ARCH_MEMCPY
+void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+	const char *src = v_src;
+	char *dst = v_dst;
+#ifndef CONFIG_OPT_LIB_FUNCTION
+	/* Simple, byte oriented memcpy. */
+	while (c--)
+		*dst++ = *src++;
+
+	return v_dst;
+#else
+	/* The following code tries to optimize the copy by using unsigned
+	 * alignment. This will work fine if both source and destination are
+	 * aligned on the same boundary. However, if they are aligned on
+	 * different boundaries shifts will be necessary. This might result in
+	 * bad performance on MicroBlaze systems without a barrel shifter.
+	 */
+	const uint32_t *i_src;
+	uint32_t *i_dst;
+
+	if (c >= 4) {
+		unsigned  value, buf_hold;
+
+		/* Align the dstination to a word boundry. */
+		/* This is done in an endian independant manner. */
+		switch ((unsigned long)dst & 3) {
+		case 1:
+			*dst++ = *src++;
+			--c;
+		case 2:
+			*dst++ = *src++;
+			--c;
+		case 3:
+			*dst++ = *src++;
+			--c;
+		}
+
+		i_dst = (void *)dst;
+
+		/* Choose a copy scheme based on the source */
+		/* alignment relative to dstination. */
+		switch ((unsigned long)src & 3) {
+		case 0x0:	/* Both byte offsets are aligned */
+			i_src  = (const void *)src;
+
+			for (; c >= 4; c -= 4)
+				*i_dst++ = *i_src++;
+
+			src  = (const void *)i_src;
+			break;
+		case 0x1:	/* Unaligned - Off by 1 */
+			/* Word align the source */
+			i_src = (const void *) ((unsigned)src & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *i_src++ << 8;
+
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | value >> 24;
+				buf_hold = value << 8;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src -= 3;
+			break;
+		case 0x2:	/* Unaligned - Off by 2 */
+			/* Word align the source */
+			i_src = (const void *) ((unsigned)src & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *i_src++ << 16;
+
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | value >> 16;
+				buf_hold = value << 16;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src -= 2;
+			break;
+		case 0x3:	/* Unaligned - Off by 3 */
+			/* Word align the source */
+			i_src = (const void *) ((unsigned)src & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *i_src++ << 24;
+
+			for (; c >= 4; c -= 4) {
+				value = *i_src++;
+				*i_dst++ = buf_hold | value >> 8;
+				buf_hold = value << 24;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src -= 1;
+			break;
+		}
+		dst = (void *)i_dst;
+	}
+
+	/* Finish off any remaining bytes */
+	/* simple fast copy, ... unless a cache boundry is crossed */
+	switch (c) {
+	case 3:
+		*dst++ = *src++;
+	case 2:
+		*dst++ = *src++;
+	case 1:
+		*dst++ = *src++;
+	}
+
+	return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memcpy);
+#endif /* __HAVE_ARCH_MEMCPY */
+
+void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c)
+{
+	return memcpy(d, s, c);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/memmove.c linux-libre-2.6.30-gnu1/arch/microblaze/lib/memmove.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/memmove.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/memmove.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memcpy on Microblaze
+ * This is generic C code to do efficient, alignment-aware memmove.
+ *
+ * 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
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void *memmove(void *v_dst, const void *v_src, __kernel_size_t c)
+{
+	const char *src = v_src;
+	char *dst = v_dst;
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+	const uint32_t *i_src;
+	uint32_t *i_dst;
+#endif
+
+	if (!c)
+		return v_dst;
+
+	/* Use memcpy when source is higher than dest */
+	if (v_dst <= v_src)
+		return memcpy(v_dst, v_src, c);
+
+#ifndef CONFIG_OPT_LIB_FUNCTION
+	/* copy backwards, from end to beginning */
+	src += c;
+	dst += c;
+
+	/* Simple, byte oriented memmove. */
+	while (c--)
+		*--dst = *--src;
+
+	return v_dst;
+#else
+	/* The following code tries to optimize the copy by using unsigned
+	 * alignment. This will work fine if both source and destination are
+	 * aligned on the same boundary. However, if they are aligned on
+	 * different boundaries shifts will be necessary. This might result in
+	 * bad performance on MicroBlaze systems without a barrel shifter.
+	 */
+	/* FIXME this part needs more test */
+	/* Do a descending copy - this is a bit trickier! */
+	dst += c;
+	src += c;
+
+	if (c >= 4) {
+		unsigned  value, buf_hold;
+
+		/* Align the destination to a word boundry. */
+		/* This is done in an endian independant manner. */
+
+		switch ((unsigned long)dst & 3) {
+		case 3:
+			*--dst = *--src;
+			--c;
+		case 2:
+			*--dst = *--src;
+			--c;
+		case 1:
+			*--dst = *--src;
+			--c;
+		}
+
+		i_dst = (void *)dst;
+		/* Choose a copy scheme based on the source */
+		/* alignment relative to dstination. */
+		switch ((unsigned long)src & 3) {
+		case 0x0:	/* Both byte offsets are aligned */
+
+			i_src  = (const void *)src;
+
+			for (; c >= 4; c -= 4)
+				*--i_dst = *--i_src;
+
+			src  = (const void *)i_src;
+			break;
+		case 0x1:	/* Unaligned - Off by 1 */
+			/* Word align the source */
+			i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *--i_src >> 24;
+
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold << 8 | value;
+				buf_hold = value >> 24;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src += 1;
+			break;
+		case 0x2:	/* Unaligned - Off by 2 */
+			/* Word align the source */
+			i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *--i_src >> 16;
+
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold << 16 | value;
+				buf_hold = value >> 16;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src += 2;
+			break;
+		case 0x3:	/* Unaligned - Off by 3 */
+			/* Word align the source */
+			i_src = (const void *) (((unsigned)src + 4) & ~3);
+
+			/* Load the holding buffer */
+			buf_hold = *--i_src >> 8;
+
+			for (; c >= 4; c -= 4) {
+				value = *--i_src;
+				*--i_dst = buf_hold << 24 | value;
+				buf_hold = value >> 8;
+			}
+
+			/* Realign the source */
+			src = (const void *)i_src;
+			src += 3;
+			break;
+		}
+		dst = (void *)i_dst;
+	}
+
+	/* simple fast copy, ... unless a cache boundry is crossed */
+	/* Finish off any remaining bytes */
+	switch (c) {
+	case 4:
+		*--dst = *--src;
+	case 3:
+		*--dst = *--src;
+	case 2:
+		*--dst = *--src;
+	case 1:
+		*--dst = *--src;
+	}
+	return v_dst;
+#endif
+}
+EXPORT_SYMBOL(memmove);
+#endif /* __HAVE_ARCH_MEMMOVE */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/memset.c linux-libre-2.6.30-gnu1/arch/microblaze/lib/memset.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/memset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/memset.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008-2009 PetaLogix
+ * Copyright (C) 2007 John Williams
+ *
+ * Reasonably optimised generic C-code for memset on Microblaze
+ * This is generic C code to do efficient, alignment-aware memcpy.
+ *
+ * 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
+ * author of this code (Michael Morrow, Intel).  Below is the original
+ * copyright notice.
+ *
+ * This software has been developed by Intel Corporation.
+ * Intel specifically disclaims all warranties, express or
+ * implied, and all liability, including consequential and
+ * other indirect damages, for the use of this program, including
+ * liability for infringement of any proprietary rights,
+ * and including the warranties of merchantability and fitness
+ * for a particular purpose. Intel does not assume any
+ * responsibility for and errors which may appear in this program
+ * not any responsibility to update it.
+ */
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#ifdef __HAVE_ARCH_MEMSET
+void *memset(void *v_src, int c, __kernel_size_t n)
+{
+
+	char *src = v_src;
+#ifdef CONFIG_OPT_LIB_FUNCTION
+	uint32_t *i_src;
+	uint32_t w32;
+#endif
+	/* Truncate c to 8 bits */
+	c = (c & 0xFF);
+
+#ifdef CONFIG_OPT_LIB_FUNCTION
+	/* Make a repeating word out of it */
+	w32 = c;
+	w32 |= w32 << 8;
+	w32 |= w32 << 16;
+
+	if (n >= 4) {
+		/* Align the destination to a word boundary */
+		/* This is done in an endian independant manner */
+		switch ((unsigned) src & 3) {
+		case 1:
+			*src++ = c;
+			--n;
+		case 2:
+			*src++ = c;
+			--n;
+		case 3:
+			*src++ = c;
+			--n;
+		}
+
+		i_src  = (void *)src;
+
+		/* Do as many full-word copies as we can */
+		for (; n >= 4; n -= 4)
+			*i_src++ = w32;
+
+		src  = (void *)i_src;
+	}
+#endif
+	/* Simple, byte oriented memset or the rest of count. */
+	while (n--)
+		*src++ = c;
+
+	return v_src;
+}
+EXPORT_SYMBOL(memset);
+#endif /* __HAVE_ARCH_MEMSET */
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/lib/uaccess.c linux-libre-2.6.30-gnu1/arch/microblaze/lib/uaccess.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/lib/uaccess.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/lib/uaccess.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/string.h>
+#include <asm/uaccess.h>
+
+#include <asm/bug.h>
+
+long strnlen_user(const char __user *src, long count)
+{
+	return strlen(src) + 1;
+}
+
+#define __do_strncpy_from_user(dst, src, count, res)			\
+	do {								\
+		char *tmp;						\
+		strncpy(dst, src, count);				\
+		for (tmp = dst; *tmp && count > 0; tmp++, count--)	\
+			;						\
+		res = (tmp - dst);					\
+	} while (0)
+
+long __strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	long res;
+	__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
+
+long strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	long res = -EFAULT;
+	if (access_ok(VERIFY_READ, src, 1))
+		__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
+
+# What CPU vesion are we building for, and crack it open
+# as major.minor.rev
+CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) )
+CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1)
+CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2)
+CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3)
+
+export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV
+
+# Use cpu-related CONFIG_ vars to set compile options.
+
+# Work out HW multipler support.  This is icky.
+# 1. Spartan2 has no HW multiplers.
+# 2. MicroBlaze v3.x always uses them, except in Spartan 2
+# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings
+ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY)))
+  ifeq ($(CPU_MAJOR),3)
+    CPUFLAGS-1 += -mno-xl-soft-mul
+  else
+    # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support.
+    CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high
+    CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul
+  endif
+endif
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift
+CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare
+
+CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
+
+# The various CONFIG_XILINX cpu features options are integers 0/1/2...
+# rather than bools y/n
+
+# r31 holds current when in kernel mode
+CFLAGS_KERNEL += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
+
+LDFLAGS_BLOB := --format binary --oformat elf32-microblaze
+
+LIBGCC := $(shell $(CC) $(CFLAGS_KERNEL) -print-libgcc-file-name)
+
+head-y		:= arch/microblaze/kernel/head.o
+libs-y		+= arch/microblaze/lib/ $(LIBGCC)
+core-y		+= arch/microblaze/kernel/ arch/microblaze/mm/ \
+		   arch/microblaze/platform/
+
+boot := arch/$(ARCH)/boot
+
+# defines filename extension depending memory management type
+ifeq ($(CONFIG_MMU),)
+MMUEXT		:= -nommu
+endif
+export	MMUEXT
+
+all: linux.bin
+
+archclean:
+	$(Q)$(MAKE) $(clean)=$(boot)
+
+linux.bin linux.bin.gz: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+define archhelp
+  echo  '* linux.bin    - Create raw binary'
+  echo  '  linux.bin.gz - Create compressed raw binary'
+endef
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/mm/init.c linux-libre-2.6.30-gnu1/arch/microblaze/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/mm/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2006 Atmark Techno, Inc.
+ *
+ * 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/bootmem.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/lmb.h>
+#include <linux/mm.h> /* mem_init */
+#include <linux/initrd.h>
+#include <linux/pagemap.h>
+#include <linux/pfn.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+unsigned int __page_offset;
+/* EXPORT_SYMBOL(__page_offset); */
+
+char *klimit = _end;
+
+/*
+ * Initialize the bootmem system and give it all the memory we
+ * have available.
+ */
+unsigned int memory_start;
+unsigned int memory_end; /* due to mm/nommu.c */
+unsigned int memory_size;
+
+/*
+ * paging_init() sets up the page tables - in fact we've already done this.
+ */
+static void __init paging_init(void)
+{
+	int i;
+	unsigned long zones_size[MAX_NR_ZONES];
+
+	/*
+	 * old: we can DMA to/from any address.put all page into ZONE_DMA
+	 * We use only ZONE_NORMAL
+	 */
+	zones_size[ZONE_NORMAL] = max_mapnr;
+
+	/* every other zones are empty */
+	for (i = 1; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+	free_area_init(zones_size);
+}
+
+void __init setup_memory(void)
+{
+	int i;
+	unsigned long map_size;
+	u32 kernel_align_start, kernel_align_size;
+
+	/* Find main memory where is the kernel */
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		memory_start = (u32) lmb.memory.region[i].base;
+		memory_end = (u32) lmb.memory.region[i].base
+				+ (u32) lmb.memory.region[i].size;
+		if ((memory_start <= (u32)_text) &&
+					((u32)_text <= memory_end)) {
+			memory_size = memory_end - memory_start;
+			PAGE_OFFSET = memory_start;
+			printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, "
+				"size 0x%08x\n", __func__, memory_start,
+						memory_end, memory_size);
+			break;
+		}
+	}
+
+	if (!memory_start || !memory_end) {
+		panic("%s: Missing memory setting 0x%08x-0x%08x\n",
+			__func__, memory_start, memory_end);
+	}
+
+	/* reservation of region where is the kernel */
+	kernel_align_start = PAGE_DOWN((u32)_text);
+	/* ALIGN can be remove because _end in vmlinux.lds.S is align */
+	kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start;
+	lmb_reserve(kernel_align_start, kernel_align_size);
+	printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n",
+		__func__, kernel_align_start, kernel_align_start
+			+ kernel_align_size, kernel_align_size);
+
+	/*
+	 * Kernel:
+	 * start: base phys address of kernel - page align
+	 * end: base phys address of kernel - page align
+	 *
+	 * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
+	 * max_low_pfn
+	 * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
+	 * num_physpages - number of all pages
+	 */
+
+	/* memory start is from the kernel end (aligned) to higher addr */
+	min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
+	/* RAM is assumed contiguous */
+	num_physpages = max_mapnr = memory_size >> PAGE_SHIFT;
+	max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT;
+
+	printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr);
+	printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
+	printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
+
+	/*
+	 * Find an area to use for the bootmem bitmap.
+	 * We look for the first area which is at least
+	 * 128kB in length (128kB is enough for a bitmap
+	 * for 4GB of memory, using 4kB pages), plus 1 page
+	 * (in case the address isn't page-aligned).
+	 */
+	map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)_end)),
+					min_low_pfn, max_low_pfn);
+
+	lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size);
+
+	/* free bootmem is whole main memory */
+	free_bootmem(memory_start, memory_size);
+
+	/* reserve allocate blocks */
+	for (i = 0; i < lmb.reserved.cnt; i++) {
+		pr_debug("reserved %d - 0x%08x-0x%08x\n", i,
+			(u32) lmb.reserved.region[i].base,
+			(u32) lmb_size_bytes(&lmb.reserved, i));
+		reserve_bootmem(lmb.reserved.region[i].base,
+			lmb_size_bytes(&lmb.reserved, i) - 1, BOOTMEM_DEFAULT);
+	}
+	paging_init();
+}
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+	unsigned long addr;
+
+	for (addr = begin; addr < end; addr += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		init_page_count(virt_to_page(addr));
+		memset((void *)addr, 0xcc, PAGE_SIZE);
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	int pages = 0;
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		init_page_count(virt_to_page(start));
+		free_page(start);
+		totalram_pages++;
+		pages++;
+	}
+	printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+	free_init_pages("unused kernel memory",
+			(unsigned long)(&__init_begin),
+			(unsigned long)(&__init_end));
+}
+
+/* FIXME from arch/powerpc/mm/mem.c*/
+void show_mem(void)
+{
+	printk(KERN_NOTICE "%s\n", __func__);
+}
+
+void __init mem_init(void)
+{
+	high_memory = (void *)__va(memory_end);
+	/* this will put all memory onto the freelists */
+	totalram_pages += free_all_bootmem();
+
+	printk(KERN_INFO "Memory: %luk/%luk available\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       num_physpages << (PAGE_SHIFT-10));
+}
+
+/* Check against bounds of physical memory */
+int ___range_ok(unsigned long addr, unsigned long size)
+{
+	return ((addr < memory_start) ||
+		((addr + size) > memory_end));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/mm/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/mm/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/mm/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/mm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,5 @@
+#
+# Makefile
+#
+
+obj-y := init.o
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/Kconfig.auto linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/Kconfig.auto
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/Kconfig.auto	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/Kconfig.auto	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+#
+# (C) Copyright 2007 Michal Simek
+#
+# Michal SIMEK <monstr@monstr.eu>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU 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
+#
+
+# Definitions for MICROBLAZE0
+comment "Definitions for MICROBLAZE0"
+	depends on ALLOW_EDIT_AUTO
+
+config KERNEL_BASE_ADDR
+	hex "Physical address where Linux Kernel is"
+	default "0x90000000"
+	help
+	  BASE Address for kernel
+
+config XILINX_MICROBLAZE0_FAMILY
+	string "Targetted FPGA family" if ALLOW_EDIT_AUTO
+	default "virtex5"
+
+config XILINX_MICROBLAZE0_USE_MSR_INSTR
+	int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+	default 1
+
+config XILINX_MICROBLAZE0_USE_PCMP_INSTR
+	int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO
+	default 1
+
+config XILINX_MICROBLAZE0_USE_BARREL
+	int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO
+	default 1
+
+config XILINX_MICROBLAZE0_USE_DIV
+	int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO
+	default 1
+
+config XILINX_MICROBLAZE0_USE_HW_MUL
+	int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO
+	default 2
+
+config XILINX_MICROBLAZE0_USE_FPU
+	int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO
+	default 2
+
+config XILINX_MICROBLAZE0_HW_VER
+	string "Core version number" if ALLOW_EDIT_AUTO
+	default 7.10.d
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+#
+# Empty Makefile to keep make clean happy
+#
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/system.dts linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/system.dts
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/generic/system.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/generic/system.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,332 @@
+/*
+ * Device Tree Generator version: 1.1
+ *
+ * (C) Copyright 2007-2008 Xilinx, Inc.
+ * (C) Copyright 2007-2009 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6
+ *
+ * XPS project directory: Xilinx-ML505-ll_temac-sgdma-MMU-FDT-edk101
+ */
+
+/dts-v1/;
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,microblaze";
+	model = "testing";
+	DDR2_SDRAM: memory@90000000 {
+		device_type = "memory";
+		reg = < 0x90000000 0x10000000 >;
+	} ;
+	chosen {
+		bootargs = "console=ttyUL0,115200 highres=on";
+		linux,stdout-path = "/plb@0/serial@84000000";
+	} ;
+	cpus {
+		#address-cells = <1>;
+		#cpus = <0x1>;
+		#size-cells = <0>;
+		microblaze_0: cpu@0 {
+			clock-frequency = <125000000>;
+			compatible = "xlnx,microblaze-7.10.d";
+			d-cache-baseaddr = <0x90000000>;
+			d-cache-highaddr = <0x9fffffff>;
+			d-cache-line-size = <0x10>;
+			d-cache-size = <0x2000>;
+			device_type = "cpu";
+			i-cache-baseaddr = <0x90000000>;
+			i-cache-highaddr = <0x9fffffff>;
+			i-cache-line-size = <0x10>;
+			i-cache-size = <0x2000>;
+			model = "microblaze,7.10.d";
+			reg = <0>;
+			timebase-frequency = <125000000>;
+			xlnx,addr-tag-bits = <0xf>;
+			xlnx,allow-dcache-wr = <0x1>;
+			xlnx,allow-icache-wr = <0x1>;
+			xlnx,area-optimized = <0x0>;
+			xlnx,cache-byte-size = <0x2000>;
+			xlnx,d-lmb = <0x1>;
+			xlnx,d-opb = <0x0>;
+			xlnx,d-plb = <0x1>;
+			xlnx,data-size = <0x20>;
+			xlnx,dcache-addr-tag = <0xf>;
+			xlnx,dcache-always-used = <0x1>;
+			xlnx,dcache-byte-size = <0x2000>;
+			xlnx,dcache-line-len = <0x4>;
+			xlnx,dcache-use-fsl = <0x1>;
+			xlnx,debug-enabled = <0x1>;
+			xlnx,div-zero-exception = <0x1>;
+			xlnx,dopb-bus-exception = <0x0>;
+			xlnx,dynamic-bus-sizing = <0x1>;
+			xlnx,edge-is-positive = <0x1>;
+			xlnx,family = "virtex5";
+			xlnx,fpu-exception = <0x1>;
+			xlnx,fsl-data-size = <0x20>;
+			xlnx,fsl-exception = <0x0>;
+			xlnx,fsl-links = <0x0>;
+			xlnx,i-lmb = <0x1>;
+			xlnx,i-opb = <0x0>;
+			xlnx,i-plb = <0x1>;
+			xlnx,icache-always-used = <0x1>;
+			xlnx,icache-line-len = <0x4>;
+			xlnx,icache-use-fsl = <0x1>;
+			xlnx,ill-opcode-exception = <0x1>;
+			xlnx,instance = "microblaze_0";
+			xlnx,interconnect = <0x1>;
+			xlnx,interrupt-is-edge = <0x0>;
+			xlnx,iopb-bus-exception = <0x0>;
+			xlnx,mmu-dtlb-size = <0x4>;
+			xlnx,mmu-itlb-size = <0x2>;
+			xlnx,mmu-tlb-access = <0x3>;
+			xlnx,mmu-zones = <0x10>;
+			xlnx,number-of-pc-brk = <0x1>;
+			xlnx,number-of-rd-addr-brk = <0x0>;
+			xlnx,number-of-wr-addr-brk = <0x0>;
+			xlnx,opcode-0x0-illegal = <0x1>;
+			xlnx,pvr = <0x2>;
+			xlnx,pvr-user1 = <0x0>;
+			xlnx,pvr-user2 = <0x0>;
+			xlnx,reset-msr = <0x0>;
+			xlnx,sco = <0x0>;
+			xlnx,unaligned-exceptions = <0x1>;
+			xlnx,use-barrel = <0x1>;
+			xlnx,use-dcache = <0x1>;
+			xlnx,use-div = <0x1>;
+			xlnx,use-ext-brk = <0x1>;
+			xlnx,use-ext-nm-brk = <0x1>;
+			xlnx,use-extended-fsl-instr = <0x0>;
+			xlnx,use-fpu = <0x2>;
+			xlnx,use-hw-mul = <0x2>;
+			xlnx,use-icache = <0x1>;
+			xlnx,use-interrupt = <0x1>;
+			xlnx,use-mmu = <0x3>;
+			xlnx,use-msr-instr = <0x1>;
+			xlnx,use-pcmp-instr = <0x1>;
+		} ;
+	} ;
+	mb_plb: plb@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+		ranges ;
+		FLASH: flash@a0000000 {
+			bank-width = <2>;
+			compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+			reg = < 0xa0000000 0x2000000 >;
+			xlnx,family = "virtex5";
+			xlnx,include-datawidth-matching-0 = <0x1>;
+			xlnx,include-datawidth-matching-1 = <0x0>;
+			xlnx,include-datawidth-matching-2 = <0x0>;
+			xlnx,include-datawidth-matching-3 = <0x0>;
+			xlnx,include-negedge-ioregs = <0x0>;
+			xlnx,include-plb-ipif = <0x1>;
+			xlnx,include-wrbuf = <0x1>;
+			xlnx,max-mem-width = <0x10>;
+			xlnx,mch-native-dwidth = <0x20>;
+			xlnx,mch-plb-clk-period-ps = <0x1f40>;
+			xlnx,mch-splb-awidth = <0x20>;
+			xlnx,mch0-accessbuf-depth = <0x10>;
+			xlnx,mch0-protocol = <0x0>;
+			xlnx,mch0-rddatabuf-depth = <0x10>;
+			xlnx,mch1-accessbuf-depth = <0x10>;
+			xlnx,mch1-protocol = <0x0>;
+			xlnx,mch1-rddatabuf-depth = <0x10>;
+			xlnx,mch2-accessbuf-depth = <0x10>;
+			xlnx,mch2-protocol = <0x0>;
+			xlnx,mch2-rddatabuf-depth = <0x10>;
+			xlnx,mch3-accessbuf-depth = <0x10>;
+			xlnx,mch3-protocol = <0x0>;
+			xlnx,mch3-rddatabuf-depth = <0x10>;
+			xlnx,mem0-width = <0x10>;
+			xlnx,mem1-width = <0x20>;
+			xlnx,mem2-width = <0x20>;
+			xlnx,mem3-width = <0x20>;
+			xlnx,num-banks-mem = <0x1>;
+			xlnx,num-channels = <0x0>;
+			xlnx,priority-mode = <0x0>;
+			xlnx,synch-mem-0 = <0x0>;
+			xlnx,synch-mem-1 = <0x0>;
+			xlnx,synch-mem-2 = <0x0>;
+			xlnx,synch-mem-3 = <0x0>;
+			xlnx,synch-pipedelay-0 = <0x2>;
+			xlnx,synch-pipedelay-1 = <0x2>;
+			xlnx,synch-pipedelay-2 = <0x2>;
+			xlnx,synch-pipedelay-3 = <0x2>;
+			xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+			xlnx,tavdv-ps-mem-1 = <0x3a98>;
+			xlnx,tavdv-ps-mem-2 = <0x3a98>;
+			xlnx,tavdv-ps-mem-3 = <0x3a98>;
+			xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+			xlnx,tcedv-ps-mem-1 = <0x3a98>;
+			xlnx,tcedv-ps-mem-2 = <0x3a98>;
+			xlnx,tcedv-ps-mem-3 = <0x3a98>;
+			xlnx,thzce-ps-mem-0 = <0x88b8>;
+			xlnx,thzce-ps-mem-1 = <0x1b58>;
+			xlnx,thzce-ps-mem-2 = <0x1b58>;
+			xlnx,thzce-ps-mem-3 = <0x1b58>;
+			xlnx,thzoe-ps-mem-0 = <0x1b58>;
+			xlnx,thzoe-ps-mem-1 = <0x1b58>;
+			xlnx,thzoe-ps-mem-2 = <0x1b58>;
+			xlnx,thzoe-ps-mem-3 = <0x1b58>;
+			xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+			xlnx,tlzwe-ps-mem-1 = <0x0>;
+			xlnx,tlzwe-ps-mem-2 = <0x0>;
+			xlnx,tlzwe-ps-mem-3 = <0x0>;
+			xlnx,twc-ps-mem-0 = <0x2af8>;
+			xlnx,twc-ps-mem-1 = <0x3a98>;
+			xlnx,twc-ps-mem-2 = <0x3a98>;
+			xlnx,twc-ps-mem-3 = <0x3a98>;
+			xlnx,twp-ps-mem-0 = <0x11170>;
+			xlnx,twp-ps-mem-1 = <0x2ee0>;
+			xlnx,twp-ps-mem-2 = <0x2ee0>;
+			xlnx,twp-ps-mem-3 = <0x2ee0>;
+			xlnx,xcl0-linesize = <0x4>;
+			xlnx,xcl0-writexfer = <0x1>;
+			xlnx,xcl1-linesize = <0x4>;
+			xlnx,xcl1-writexfer = <0x1>;
+			xlnx,xcl2-linesize = <0x4>;
+			xlnx,xcl2-writexfer = <0x1>;
+			xlnx,xcl3-linesize = <0x4>;
+			xlnx,xcl3-writexfer = <0x1>;
+		} ;
+		Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,compound";
+			ethernet@81c00000 {
+				compatible = "xlnx,xps-ll-temac-1.01.b";
+				device_type = "network";
+				interrupt-parent = <&xps_intc_0>;
+				interrupts = < 5 2 >;
+				llink-connected = <&PIM3>;
+				local-mac-address = [ 02 00 00 00 00 00 ];
+				reg = < 0x81c00000 0x40 >;
+				xlnx,bus2core-clk-ratio = <0x1>;
+				xlnx,phy-type = <0x1>;
+				xlnx,phyaddr = <0x1>;
+				xlnx,rxcsum = <0x0>;
+				xlnx,rxfifo = <0x1000>;
+				xlnx,temac-type = <0x0>;
+				xlnx,txcsum = <0x0>;
+				xlnx,txfifo = <0x1000>;
+			} ;
+		} ;
+		IIC_EEPROM: i2c@81600000 {
+			compatible = "xlnx,xps-iic-2.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 6 2 >;
+			reg = < 0x81600000 0x10000 >;
+			xlnx,clk-freq = <0x7735940>;
+			xlnx,family = "virtex5";
+			xlnx,gpo-width = <0x1>;
+			xlnx,iic-freq = <0x186a0>;
+			xlnx,scl-inertial-delay = <0x0>;
+			xlnx,sda-inertial-delay = <0x0>;
+			xlnx,ten-bit-adr = <0x0>;
+		} ;
+		LEDs_8Bit: gpio@81400000 {
+			compatible = "xlnx,xps-gpio-1.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 7 2 >;
+			reg = < 0x81400000 0x10000 >;
+			xlnx,all-inputs = <0x0>;
+			xlnx,all-inputs-2 = <0x0>;
+			xlnx,dout-default = <0x0>;
+			xlnx,dout-default-2 = <0x0>;
+			xlnx,family = "virtex5";
+			xlnx,gpio-width = <0x8>;
+			xlnx,interrupt-present = <0x1>;
+			xlnx,is-bidir = <0x1>;
+			xlnx,is-bidir-2 = <0x1>;
+			xlnx,is-dual = <0x0>;
+			xlnx,tri-default = <0xffffffff>;
+			xlnx,tri-default-2 = <0xffffffff>;
+		} ;
+		RS232_Uart_1: serial@84000000 {
+			clock-frequency = <125000000>;
+			compatible = "xlnx,xps-uartlite-1.00.a";
+			current-speed = <115200>;
+			device_type = "serial";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 8 0 >;
+			port-number = <0>;
+			reg = < 0x84000000 0x10000 >;
+			xlnx,baudrate = <0x1c200>;
+			xlnx,data-bits = <0x8>;
+			xlnx,family = "virtex5";
+			xlnx,odd-parity = <0x0>;
+			xlnx,use-parity = <0x0>;
+		} ;
+		SysACE_CompactFlash: sysace@83600000 {
+			compatible = "xlnx,xps-sysace-1.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 4 2 >;
+			reg = < 0x83600000 0x10000 >;
+			xlnx,family = "virtex5";
+			xlnx,mem-width = <0x10>;
+		} ;
+		debug_module: debug@84400000 {
+			compatible = "xlnx,mdm-1.00.d";
+			reg = < 0x84400000 0x10000 >;
+			xlnx,family = "virtex5";
+			xlnx,interconnect = <0x1>;
+			xlnx,jtag-chain = <0x2>;
+			xlnx,mb-dbg-ports = <0x1>;
+			xlnx,uart-width = <0x8>;
+			xlnx,use-uart = <0x1>;
+			xlnx,write-fsl-ports = <0x0>;
+		} ;
+		mpmc@90000000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "xlnx,mpmc-4.02.a";
+			PIM3: sdma@84600180 {
+				compatible = "xlnx,ll-dma-1.00.a";
+				interrupt-parent = <&xps_intc_0>;
+				interrupts = < 2 2 1 2 >;
+				reg = < 0x84600180 0x80 >;
+			} ;
+		} ;
+		xps_intc_0: interrupt-controller@81800000 {
+			#interrupt-cells = <0x2>;
+			compatible = "xlnx,xps-intc-1.00.a";
+			interrupt-controller ;
+			reg = < 0x81800000 0x10000 >;
+			xlnx,kind-of-intr = <0x100>;
+			xlnx,num-intr-inputs = <0x9>;
+		} ;
+		xps_timer_1: timer@83c00000 {
+			compatible = "xlnx,xps-timer-1.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 3 2 >;
+			reg = < 0x83c00000 0x10000 >;
+			xlnx,count-width = <0x20>;
+			xlnx,family = "virtex5";
+			xlnx,gen0-assert = <0x1>;
+			xlnx,gen1-assert = <0x1>;
+			xlnx,one-timer-only = <0x0>;
+			xlnx,trig0-assert = <0x1>;
+			xlnx,trig1-assert = <0x1>;
+		} ;
+	} ;
+}  ;
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/Kconfig.platform linux-libre-2.6.30-gnu1/arch/microblaze/platform/Kconfig.platform
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/Kconfig.platform	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/Kconfig.platform	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,85 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Platform selection Kconfig menu for MicroBlaze targets
+#
+
+menu "Platform options"
+choice
+	prompt "Platform"
+	default PLATFORM_MICROBLAZE_AUTO
+	help
+	  Choose which hardware board/platform you are targeting.
+
+config PLATFORM_GENERIC
+	bool "Generic"
+	help
+	  Choose this option for the Generic platform.
+
+endchoice
+
+config SELFMOD
+	bool "Use self modified code for intc/timer"
+	depends on EXPERIMENTAL && NO_MMU
+	default n
+	help
+	  This choice enables self-modified code for interrupt controller
+	  and timer.
+
+config SELFMOD_INTC
+	bool "Use self modified code for intc"
+	depends on SELFMOD
+	default y
+	help
+	  This choice enables self-modified code for interrupt controller.
+
+config SELFMOD_TIMER
+	bool "Use self modified code for timer"
+	depends on SELFMOD
+	default y
+	help
+	  This choice enables self-modified code for timer.
+
+config OPT_LIB_FUNCTION
+	bool "Optimalized lib function"
+	default y
+	help
+	  Allows turn on optimalized library function (memcpy and memmove).
+	  They are optimized by using word alignment. This will work
+	  fine if both source and destination are aligned on the same
+	  boundary. However, if they are aligned on different boundaries
+	  shifts will be necessary. This might result in bad performance
+	  on MicroBlaze systems without a barrel shifter.
+
+config OPT_LIB_ASM
+	bool "Optimalized lib function ASM"
+	depends on OPT_LIB_FUNCTION
+	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
+
+endmenu
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/Makefile linux-libre-2.6.30-gnu1/arch/microblaze/platform/Makefile
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#
+# Makefile for arch/microblaze/platform directory
+#
+#obj-$(CONFIG_PLATFORM_GENERIC) += generic/
+
+obj-y	+= platform.o
diff -druNp linux-libre-2.6.29-gnu1/arch/microblaze/platform/platform.c linux-libre-2.6.30-gnu1/arch/microblaze/platform/platform.c
--- linux-libre-2.6.29-gnu1/arch/microblaze/platform/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/microblaze/platform/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on virtex.c file
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * 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/init.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+static struct of_device_id xilinx_of_bus_ids[] __initdata = {
+	{ .compatible = "simple-bus", },
+	{ .compatible = "xlnx,plb-v46-1.00.a", },
+	{ .compatible = "xlnx,opb-v20-1.10.c", },
+	{ .compatible = "xlnx,opb-v20-1.10.b", },
+	{ .compatible = "xlnx,compound", },
+	{}
+};
+
+static int __init microblaze_device_probe(void)
+{
+	of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+	return 0;
+}
+device_initcall(microblaze_device_probe);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/gpio.c linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/gpio.c
--- linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
  *  	Architecture specific GPIO support
  *
  *  This program is free software; you can redistribute	 it and/or modify it
@@ -27,122 +27,175 @@
  * 	others have a second one : GPIO2
  */
 
+#include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
 
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/gpio.h>
 
-#define gpio1 sys
-#if !defined(CONFIG_SOC_AU1000)
-
-static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE;
-#define GPIO2_OUTPUT_ENABLE_MASK 	0x00010000
+struct au1000_gpio_chip {
+	struct gpio_chip	chip;
+	void __iomem		*regbase;
+};
 
-static int au1xxx_gpio2_read(unsigned gpio)
+#if !defined(CONFIG_SOC_AU1000)
+static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
 {
-	gpio -= AU1XXX_GPIO_BASE;
-	return ((gpio2->pinstate >> gpio) & 0x01);
+	u32 mask = 1 << offset;
+	struct au1000_gpio_chip *gpch;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+	return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
 }
 
-static void au1xxx_gpio2_write(unsigned gpio, int value)
+static void au1000_gpio2_set(struct gpio_chip *chip,
+				unsigned offset, int value)
 {
-	gpio -= AU1XXX_GPIO_BASE;
+	u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
+	struct au1000_gpio_chip *gpch;
+	unsigned long flags;
 
-	gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
+	local_irq_save(flags);
+	writel(mask, gpch->regbase + AU1000_GPIO2_OUT);
+	local_irq_restore(flags);
 }
 
-static int au1xxx_gpio2_direction_input(unsigned gpio)
+static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
 {
-	gpio -= AU1XXX_GPIO_BASE;
-	gpio2->dir &= ~(0x01 << gpio);
+	u32 mask = 1 << offset;
+	u32 tmp;
+	struct au1000_gpio_chip *gpch;
+	unsigned long flags;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
+	local_irq_save(flags);
+	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
+	tmp &= ~mask;
+	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
+	local_irq_restore(flags);
+
 	return 0;
 }
 
-static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
+static int au1000_gpio2_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
 {
-	gpio -= AU1XXX_GPIO_BASE;
-	gpio2->dir |= 0x01 << gpio;
-	gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
+	u32 mask = 1 << offset;
+	u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
+	u32 tmp;
+	struct au1000_gpio_chip *gpch;
+	unsigned long flags;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
+	local_irq_save(flags);
+	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
+	tmp |= mask;
+	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
+	writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT);
+	local_irq_restore(flags);
+
 	return 0;
 }
-
 #endif /* !defined(CONFIG_SOC_AU1000) */
 
-static int au1xxx_gpio1_read(unsigned gpio)
+static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
 {
-	return (gpio1->pinstaterd >> gpio) & 0x01;
+	u32 mask = 1 << offset;
+	struct au1000_gpio_chip *gpch;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+	return readl(gpch->regbase + AU1000_GPIO1_ST) & mask;
 }
 
-static void au1xxx_gpio1_write(unsigned gpio, int value)
+static void au1000_gpio1_set(struct gpio_chip *chip,
+				unsigned offset, int value)
 {
+	u32 mask = 1 << offset;
+	u32 reg_offset;
+	struct au1000_gpio_chip *gpch;
+	unsigned long flags;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
 	if (value)
-		gpio1->outputset = (0x01 << gpio);
+		reg_offset = AU1000_GPIO1_OUT;
 	else
-		/* Output a zero */
-		gpio1->outputclr = (0x01 << gpio);
-}
+		reg_offset = AU1000_GPIO1_CLR;
 
-static int au1xxx_gpio1_direction_input(unsigned gpio)
-{
-	gpio1->pininputen = (0x01 << gpio);
-	return 0;
+	local_irq_save(flags);
+	writel(mask, gpch->regbase + reg_offset);
+	local_irq_restore(flags);
 }
 
-static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
+static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
 {
-	gpio1->trioutclr = (0x01 & gpio);
-	au1xxx_gpio1_write(gpio, value);
+	u32 mask = 1 << offset;
+	struct au1000_gpio_chip *gpch;
+
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
+	writel(mask, gpch->regbase + AU1000_GPIO1_ST);
+
 	return 0;
 }
 
-int au1xxx_gpio_get_value(unsigned gpio)
+static int au1000_gpio1_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
 {
-	if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
-		return 0;
-#else
-		return au1xxx_gpio2_read(gpio);
-#endif
-	else
-		return au1xxx_gpio1_read(gpio);
-}
-EXPORT_SYMBOL(au1xxx_gpio_get_value);
+	u32 mask = 1 << offset;
+	struct au1000_gpio_chip *gpch;
 
-void au1xxx_gpio_set_value(unsigned gpio, int value)
-{
-	if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
-		;
-#else
-		au1xxx_gpio2_write(gpio, value);
-#endif
-	else
-		au1xxx_gpio1_write(gpio, value);
-}
-EXPORT_SYMBOL(au1xxx_gpio_set_value);
+	gpch = container_of(chip, struct au1000_gpio_chip, chip);
 
-int au1xxx_gpio_direction_input(unsigned gpio)
-{
-	if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
-		return -ENODEV;
-#else
-		return au1xxx_gpio2_direction_input(gpio);
-#endif
+	writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT);
+	au1000_gpio1_set(chip, offset, value);
 
-	return au1xxx_gpio1_direction_input(gpio);
+	return 0;
 }
-EXPORT_SYMBOL(au1xxx_gpio_direction_input);
 
-int au1xxx_gpio_direction_output(unsigned gpio, int value)
+struct au1000_gpio_chip au1000_gpio_chip[] = {
+	[0] = {
+		.regbase			= (void __iomem *)SYS_BASE,
+		.chip = {
+			.label			= "au1000-gpio1",
+			.direction_input	= au1000_gpio1_direction_input,
+			.direction_output	= au1000_gpio1_direction_output,
+			.get			= au1000_gpio1_get,
+			.set			= au1000_gpio1_set,
+			.base			= 0,
+			.ngpio			= 32,
+		},
+	},
+#if !defined(CONFIG_SOC_AU1000)
+	[1] = {
+		.regbase                        = (void __iomem *)GPIO2_BASE,
+		.chip = {
+			.label                  = "au1000-gpio2",
+			.direction_input        = au1000_gpio2_direction_input,
+			.direction_output       = au1000_gpio2_direction_output,
+			.get                    = au1000_gpio2_get,
+			.set                    = au1000_gpio2_set,
+			.base                   = AU1XXX_GPIO_BASE,
+			.ngpio                  = 32,
+		},
+	},
+#endif
+};
+
+static int __init au1000_gpio_init(void)
 {
-	if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
-		return -ENODEV;
-#else
-		return au1xxx_gpio2_direction_output(gpio, value);
+	gpiochip_add(&au1000_gpio_chip[0].chip);
+#if !defined(CONFIG_SOC_AU1000)
+	gpiochip_add(&au1000_gpio_chip[1].chip);
 #endif
 
-	return au1xxx_gpio1_direction_output(gpio, value);
+	return 0;
 }
-EXPORT_SYMBOL(au1xxx_gpio_direction_output);
+arch_initcall(au1000_gpio_init);
+
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/platform.c linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/platform.c
--- linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,14 +80,14 @@ static struct resource au1xxx_usb_ohci_r
 };
 
 /* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = DMA_32BIT_MASK;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1xxx_usb_ohci_device = {
 	.name		= "au1xxx-ohci",
 	.id		= 0,
 	.dev = {
 		.dma_mask		= &ohci_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(au1xxx_usb_ohci_resources),
 	.resource	= au1xxx_usb_ohci_resources,
@@ -109,14 +109,14 @@ static struct resource au1100_lcd_resour
 	}
 };
 
-static u64 au1100_lcd_dmamask = DMA_32BIT_MASK;
+static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1100_lcd_device = {
 	.name           = "au1100-lcd",
 	.id             = 0,
 	.dev = {
 		.dma_mask               = &au1100_lcd_dmamask,
-		.coherent_dma_mask      = DMA_32BIT_MASK,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
 	},
 	.num_resources  = ARRAY_SIZE(au1100_lcd_resources),
 	.resource       = au1100_lcd_resources,
@@ -138,14 +138,14 @@ static struct resource au1xxx_usb_ehci_r
 	},
 };
 
-static u64 ehci_dmamask = DMA_32BIT_MASK;
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1xxx_usb_ehci_device = {
 	.name		= "au1xxx-ehci",
 	.id		= 0,
 	.dev = {
 		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(au1xxx_usb_ehci_resources),
 	.resource	= au1xxx_usb_ehci_resources,
@@ -165,14 +165,14 @@ static struct resource au1xxx_usb_gdt_re
 	},
 };
 
-static u64 udc_dmamask = DMA_32BIT_MASK;
+static u64 udc_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1xxx_usb_gdt_device = {
 	.name		= "au1xxx-udc",
 	.id		= 0,
 	.dev = {
 		.dma_mask		= &udc_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(au1xxx_usb_gdt_resources),
 	.resource	= au1xxx_usb_gdt_resources,
@@ -192,14 +192,14 @@ static struct resource au1xxx_usb_otg_re
 	},
 };
 
-static u64 uoc_dmamask = DMA_32BIT_MASK;
+static u64 uoc_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1xxx_usb_otg_device = {
 	.name		= "au1xxx-uoc",
 	.id		= 0,
 	.dev = {
 		.dma_mask		= &uoc_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(au1xxx_usb_otg_resources),
 	.resource	= au1xxx_usb_otg_resources,
@@ -218,20 +218,20 @@ static struct resource au1200_lcd_resour
 	}
 };
 
-static u64 au1200_lcd_dmamask = DMA_32BIT_MASK;
+static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device au1200_lcd_device = {
 	.name           = "au1200-lcd",
 	.id             = 0,
 	.dev = {
 		.dma_mask               = &au1200_lcd_dmamask,
-		.coherent_dma_mask      = DMA_32BIT_MASK,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
 	},
 	.num_resources  = ARRAY_SIZE(au1200_lcd_resources),
 	.resource       = au1200_lcd_resources,
 };
 
-static u64 au1xxx_mmc_dmamask =  DMA_32BIT_MASK;
+static u64 au1xxx_mmc_dmamask =  DMA_BIT_MASK(32);
 
 extern struct au1xmmc_platform_data au1xmmc_platdata[2];
 
@@ -263,7 +263,7 @@ static struct platform_device au1200_mmc
 	.id = 0,
 	.dev = {
 		.dma_mask		= &au1xxx_mmc_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.platform_data		= &au1xmmc_platdata[0],
 	},
 	.num_resources	= ARRAY_SIZE(au1200_mmc0_resources),
@@ -299,7 +299,7 @@ static struct platform_device au1200_mmc
 	.id = 1,
 	.dev = {
 		.dma_mask		= &au1xxx_mmc_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.platform_data		= &au1xmmc_platdata[1],
 	},
 	.num_resources	= ARRAY_SIZE(au1200_mmc1_resources),
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/time.c linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/time.c
--- linux-libre-2.6.29-gnu1/arch/mips/alchemy/common/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/alchemy/common/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,7 @@
 
 extern int allow_au1k_wait; /* default off for CP0 Counter */
 
-static cycle_t au1x_counter1_read(void)
+static cycle_t au1x_counter1_read(struct clocksource *cs)
 {
 	return au_readl(SYS_RTCREAD);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c linux-libre-2.6.30-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c
--- linux-libre-2.6.29-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/alchemy/devboards/pb1200/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
+#include <linux/smc91x.h>
 
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1100_mmc.h>
@@ -118,19 +119,25 @@ static struct resource ide_resources[] =
 	}
 };
 
-static u64 ide_dmamask = DMA_32BIT_MASK;
+static u64 ide_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device ide_device = {
 	.name		= "au1200-ide",
 	.id		= 0,
 	.dev = {
 		.dma_mask 		= &ide_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(ide_resources),
 	.resource	= ide_resources
 };
 
+static struct smc91x_platdata smc_data = {
+	.flags	= SMC91X_NOWAIT | SMC91X_USE_16BIT,
+	.leda	= RPC_LED_100_10,
+	.ledb	= RPC_LED_TX_RX,
+};
+
 static struct resource smc91c111_resources[] = {
 	[0] = {
 		.name	= "smc91x-regs",
@@ -146,6 +153,9 @@ static struct resource smc91c111_resourc
 };
 
 static struct platform_device smc91c111_device = {
+	.dev	= {
+		.platform_data	= &smc_data,
+	},
 	.name		= "smc91x",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(smc91c111_resources),
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/alchemy/Kconfig linux-libre-2.6.30-gnu1/arch/mips/alchemy/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mips/alchemy/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/alchemy/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -134,4 +134,4 @@ config SOC_AU1X00
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_APM_EMULATION
-	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select ARCH_REQUIRE_GPIOLIB
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/basler/excite/excite_iodev.c linux-libre-2.6.30-gnu1/arch/mips/basler/excite/excite_iodev.c
--- linux-libre-2.6.29-gnu1/arch/mips/basler/excite/excite_iodev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/basler/excite/excite_iodev.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,8 +33,8 @@
 
 
 static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
-static int __init iodev_probe(struct device *);
-static int __exit iodev_remove(struct device *);
+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 *);
@@ -65,13 +65,13 @@ static struct miscdevice miscdev =
 	.fops		= &fops
 };
 
-static struct device_driver iodev_driver =
-{
-	.name		= (char *) iodev_name,
-	.bus		= &platform_bus_type,
-	.owner		= THIS_MODULE,
+static struct platform_driver iodev_driver = {
+	.driver = {
+		.name		= iodev_name,
+		.owner		= THIS_MODULE,
+	},
 	.probe		= iodev_probe,
-	.remove		= __exit_p(iodev_remove)
+	.remove		= __devexit_p(iodev_remove),
 };
 
 
@@ -89,11 +89,10 @@ iodev_get_resource(struct platform_devic
 
 
 /* No hotplugging on the platform bus - use __init */
-static int __init iodev_probe(struct device *dev)
+static int __init iodev_probe(struct platform_device *dev)
 {
-	struct platform_device * const pdv = to_platform_device(dev);
 	const struct resource * const ri =
-		iodev_get_resource(pdv, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
+		iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
 
 	if (unlikely(!ri))
 		return -ENXIO;
@@ -104,7 +103,7 @@ static int __init iodev_probe(struct dev
 
 
 
-static int __exit iodev_remove(struct device *dev)
+static int __exit iodev_remove(struct platform_device *dev)
 {
 	return misc_deregister(&miscdev);
 }
@@ -160,14 +159,14 @@ static irqreturn_t iodev_irqhdl(int irq,
 
 static int __init iodev_init_module(void)
 {
-	return driver_register(&iodev_driver);
+	return platform_driver_register(&iodev_driver);
 }
 
 
 
 static void __exit iodev_cleanup_module(void)
 {
-	driver_unregister(&iodev_driver);
+	platform_driver_unregister(&iodev_driver);
 }
 
 module_init(iodev_init_module);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/csrc-octeon.c linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/csrc-octeon.c
--- linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/csrc-octeon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/csrc-octeon.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@ void octeon_init_cvmcount(void)
 	local_irq_restore(flags);
 }
 
-static cycle_t octeon_cvmcount_read(void)
+static cycle_t octeon_cvmcount_read(struct clocksource *cs)
 {
 	return read_c0_cvmcount();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/flash_setup.c linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/flash_setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/flash_setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/flash_setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@ static int __init flash_init(void)
 		flash_map.bankwidth = 1;
 		flash_map.virt = ioremap(flash_map.phys, flash_map.size);
 		pr_notice("Bootbus flash: Setting flash for %luMB flash at "
-			  "0x%08lx\n", flash_map.size >> 20, flash_map.phys);
+			  "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
 		simple_map_init(&flash_map);
 		mymtd = do_map_probe("cfi_probe", &flash_map);
 		if (mymtd) {
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/Makefile linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/Makefile
--- linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,3 +14,5 @@ obj-y += dma-octeon.o flash_setup.o
 obj-y += octeon-memcpy.o
 
 obj-$(CONFIG_SMP)                     += smp.o
+
+EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/octeon-irq.c linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/octeon-irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/cavium-octeon/octeon-irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/cavium-octeon/octeon-irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ static void octeon_irq_core_ack(unsigned
 
 static void octeon_irq_core_eoi(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+	struct irq_desc *desc = irq_desc + irq;
 	unsigned int bit = irq - OCTEON_IRQ_SW0;
 	/*
 	 * If an IRQ is being processed while we are disabling it the
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/cobalt/irq.c linux-libre-2.6.30-gnu1/arch/mips/cobalt/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/cobalt/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/cobalt/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -47,7 +47,6 @@ asmlinkage void plat_irq_dispatch(void)
 
 static struct irqaction cascade = {
 	.handler	= no_action,
-	.mask		= CPU_MASK_NONE,
 	.name		= "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/emma/markeins/irq.c linux-libre-2.6.30-gnu1/arch/mips/emma/markeins/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/emma/markeins/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/emma/markeins/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,9 +80,9 @@ void emma2rh_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ; i++)
-		set_irq_chip_and_handler(EMMA2RH_IRQ_BASE + i,
-					 &emma2rh_irq_controller,
-					 handle_level_irq);
+		set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
+					      &emma2rh_irq_controller,
+					      handle_level_irq, "level");
 }
 
 static void emma2rh_sw_irq_enable(unsigned int irq)
@@ -120,9 +120,9 @@ void emma2rh_sw_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++)
-		set_irq_chip_and_handler(EMMA2RH_SW_IRQ_BASE + i,
-					 &emma2rh_sw_irq_controller,
-					 handle_level_irq);
+		set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
+					      &emma2rh_sw_irq_controller,
+					      handle_level_irq, "level");
 }
 
 static void emma2rh_gpio_irq_enable(unsigned int irq)
@@ -149,37 +149,28 @@ static void emma2rh_gpio_irq_disable(uns
 
 static void emma2rh_gpio_irq_ack(unsigned int irq)
 {
-	u32 reg;
-
 	irq -= EMMA2RH_GPIO_IRQ_BASE;
 	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
-
-	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
-	reg &= ~(1 << irq);
-	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
-static void emma2rh_gpio_irq_end(unsigned int irq)
+static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
 {
 	u32 reg;
 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-
-		irq -= EMMA2RH_GPIO_IRQ_BASE;
+	irq -= EMMA2RH_GPIO_IRQ_BASE;
+	emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
 
-		reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
-		reg |= 1 << irq;
-		emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
-	}
+	reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+	reg &= ~(1 << irq);
+	emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
 }
 
 struct irq_chip emma2rh_gpio_irq_controller = {
 	.name = "emma2rh_gpio_irq",
 	.ack = emma2rh_gpio_irq_ack,
 	.mask = emma2rh_gpio_irq_disable,
-	.mask_ack = emma2rh_gpio_irq_ack,
+	.mask_ack = emma2rh_gpio_irq_mask_ack,
 	.unmask = emma2rh_gpio_irq_enable,
-	.end = emma2rh_gpio_irq_end,
 };
 
 void emma2rh_gpio_irq_init(void)
@@ -187,14 +178,14 @@ void emma2rh_gpio_irq_init(void)
 	u32 i;
 
 	for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++)
-		set_irq_chip(EMMA2RH_GPIO_IRQ_BASE + i,
-			     &emma2rh_gpio_irq_controller);
+		set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
+					      &emma2rh_gpio_irq_controller,
+					      handle_edge_irq, "edge");
 }
 
 static struct irqaction irq_cascade = {
 	   .handler = no_action,
 	   .flags = 0,
-	   .mask = CPU_MASK_NONE,
 	   .name = "cascade",
 	   .dev_id = NULL,
 	   .next = NULL,
@@ -213,8 +204,7 @@ void emma2rh_irq_dispatch(void)
 		    emma2rh_in32(EMMA2RH_BHIF_INT_EN_0);
 
 #ifdef EMMA2RH_SW_CASCADE
-	if (intStatus &
-	    (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+	if (intStatus & (1UL << EMMA2RH_SW_CASCADE)) {
 		u32 swIntStatus;
 		swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT)
 		    & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
@@ -225,6 +215,8 @@ void emma2rh_irq_dispatch(void)
 			}
 		}
 	}
+	/* Skip S/W interrupt */
+	intStatus &= ~(1UL << EMMA2RH_SW_CASCADE);
 #endif
 
 	for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
@@ -238,8 +230,7 @@ void emma2rh_irq_dispatch(void)
 		    emma2rh_in32(EMMA2RH_BHIF_INT_EN_1);
 
 #ifdef EMMA2RH_GPIO_CASCADE
-	if (intStatus &
-	    (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+	if (intStatus & (1UL << (EMMA2RH_GPIO_CASCADE % 32))) {
 		u32 gpioIntStatus;
 		gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST)
 		    & emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
@@ -250,6 +241,8 @@ void emma2rh_irq_dispatch(void)
 			}
 		}
 	}
+	/* Skip GPIO interrupt */
+	intStatus &= ~(1UL << (EMMA2RH_GPIO_CASCADE % 32));
 #endif
 
 	for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/emma/markeins/platform.c linux-libre-2.6.30-gnu1/arch/mips/emma/markeins/platform.c
--- linux-libre-2.6.29-gnu1/arch/mips/emma/markeins/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/emma/markeins/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -110,6 +110,7 @@ struct platform_device i2c_emma_devices[
 static struct  plat_serial8250_port platform_serial_ports[] = {
 	[0] = {
 		.membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+		.mapbase = EMMA2RH_PFUR0_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR0,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
@@ -117,6 +118,7 @@ static struct  plat_serial8250_port plat
 		.flags = EMMA2RH_SERIAL_FLAGS,
        }, [1] = {
 		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+		.mapbase = EMMA2RH_PFUR1_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR1,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
@@ -124,6 +126,7 @@ static struct  plat_serial8250_port plat
 		.flags = EMMA2RH_SERIAL_FLAGS,
        }, [2] = {
 		.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+		.mapbase = EMMA2RH_PFUR2_BASE + 3,
 		.irq = EMMA2RH_IRQ_PFUR2,
 		.uartclk = EMMA2RH_SERIAL_CLOCK,
 		.regshift = 4,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/bitops.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -567,7 +567,7 @@ static inline unsigned long __fls(unsign
 	int num;
 
 	if (BITS_PER_LONG == 32 &&
-	    __builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r) {
+	    __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
 		__asm__(
 		"	.set	push					\n"
 		"	.set	mips32					\n"
@@ -644,7 +644,7 @@ static inline int fls(int x)
 {
 	int r;
 
-	if (__builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r) {
+	if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
 		__asm__("clz %0, %1" : "=r" (x) : "r" (x));
 
 		return 32 - x;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/checksum.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,7 +40,7 @@ static inline
 __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len,
 				   __wsum sum, int *err_ptr)
 {
-	might_sleep();
+	might_fault();
 	return __csum_partial_copy_user((__force void *)src, dst,
 					len, sum, err_ptr);
 }
@@ -53,7 +53,7 @@ static inline
 __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
 			     __wsum sum, int *err_ptr)
 {
-	might_sleep();
+	might_fault();
 	if (access_ok(VERIFY_WRITE, dst, len))
 		return __csum_partial_copy_user(src, (__force void *)dst,
 						len, sum, err_ptr);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/compat.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/compat.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/compat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/compat.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,6 @@
 /*
  * Architecture specific compatibility types
  */
-#include <linux/seccomp.h>
 #include <linux/thread_info.h>
 #include <linux/types.h>
 #include <asm/page.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu-features.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu-features.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu-features.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu-features.h	2009-06-09 23:05:27.000000000 -0400
@@ -147,6 +147,15 @@
 #define cpu_has_mips_r	(cpu_has_mips32r1 | cpu_has_mips32r2 | \
 			 cpu_has_mips64r1 | cpu_has_mips64r2)
 
+/*
+ * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
+ * pre-MIPS32/MIPS53 processors have CLO, CLZ.  For 64-bit kernels
+ * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
+ */
+# ifndef cpu_has_clo_clz
+# define cpu_has_clo_clz	cpu_has_mips_r
+# endif
+
 #ifndef cpu_has_dsp
 #define cpu_has_dsp		(cpu_data[0].ases & MIPS_ASE_DSP)
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -209,8 +209,7 @@ enum cpu_type_enum {
 	 * MIPS32 class processors
 	 */
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
-	CPU_AU1000, CPU_AU1100, CPU_AU1200, CPU_AU1210, CPU_AU1250, CPU_AU1500,
-	CPU_AU1550, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
+	CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
 
 	/*
 	 * MIPS64 class processors
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu-info.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu-info.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/cpu-info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/cpu-info.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,8 +39,8 @@ struct cache_desc {
 #define MIPS_CACHE_PINDEX	0x00000020	/* Physically indexed cache */
 
 struct cpuinfo_mips {
-	unsigned long		udelay_val;
-	unsigned long		asid_cache;
+	unsigned int		udelay_val;
+	unsigned int		asid_cache;
 
 	/*
 	 * Capability and feature descriptor structure for MIPS CPU
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/delay.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/delay.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/delay.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/delay.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,94 +11,12 @@
 #ifndef _ASM_DELAY_H
 #define _ASM_DELAY_H
 
-#include <linux/param.h>
-#include <linux/smp.h>
-
-#include <asm/compiler.h>
-#include <asm/war.h>
-
-static inline void __delay(unsigned long loops)
-{
-	if (sizeof(long) == 4)
-		__asm__ __volatile__ (
-		"	.set	noreorder				\n"
-		"	.align	3					\n"
-		"1:	bnez	%0, 1b					\n"
-		"	subu	%0, 1					\n"
-		"	.set	reorder					\n"
-		: "=r" (loops)
-		: "0" (loops));
-	else if (sizeof(long) == 8 && !DADDI_WAR)
-		__asm__ __volatile__ (
-		"	.set	noreorder				\n"
-		"	.align	3					\n"
-		"1:	bnez	%0, 1b					\n"
-		"	dsubu	%0, 1					\n"
-		"	.set	reorder					\n"
-		: "=r" (loops)
-		: "0" (loops));
-	else if (sizeof(long) == 8 && DADDI_WAR)
-		__asm__ __volatile__ (
-		"	.set	noreorder				\n"
-		"	.align	3					\n"
-		"1:	bnez	%0, 1b					\n"
-		"	dsubu	%0, %2					\n"
-		"	.set	reorder					\n"
-		: "=r" (loops)
-		: "0" (loops), "r" (1));
-}
-
-
-/*
- * Division by multiplication: you don't have to worry about
- * loss of precision.
- *
- * Use only for very small delays ( < 1 msec).  Should probably use a
- * lookup table, really, as the multiplications take much too long with
- * short delays.  This is a "reasonable" implementation, though (and the
- * first constant multiplications gets optimized away if the delay is
- * a constant)
- */
-
-static inline void __udelay(unsigned long usecs, unsigned long lpj)
-{
-	unsigned long hi, lo;
-
-	/*
-	 * The rates of 128 is rounded wrongly by the catchall case
-	 * for 64-bit.  Excessive precission?  Probably ...
-	 */
-#if defined(CONFIG_64BIT) && (HZ == 128)
-	usecs *= 0x0008637bd05af6c7UL;		/* 2**64 / (1000000 / HZ) */
-#elif defined(CONFIG_64BIT)
-	usecs *= (0x8000000000000000UL / (500000 / HZ));
-#else /* 32-bit junk follows here */
-	usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
-	                           0x80000000ULL) >> 32);
-#endif
-
-	if (sizeof(long) == 4)
-		__asm__("multu\t%2, %3"
-		: "=h" (usecs), "=l" (lo)
-		: "r" (usecs), "r" (lpj)
-		: GCC_REG_ACCUM);
-	else if (sizeof(long) == 8 && !R4000_WAR)
-		__asm__("dmultu\t%2, %3"
-		: "=h" (usecs), "=l" (lo)
-		: "r" (usecs), "r" (lpj)
-		: GCC_REG_ACCUM);
-	else if (sizeof(long) == 8 && R4000_WAR)
-		__asm__("dmultu\t%3, %4\n\tmfhi\t%0"
-		: "=r" (usecs), "=h" (hi), "=l" (lo)
-		: "r" (usecs), "r" (lpj)
-		: GCC_REG_ACCUM);
-
-	__delay(usecs);
-}
-
-#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val
+extern void __delay(unsigned int loops);
+extern void __ndelay(unsigned int ns);
+extern void __udelay(unsigned int us);
 
-#define udelay(usecs) __udelay((usecs), __udelay_val)
+#define ndelay(ns) __udelay(ns)
+#define udelay(us) __udelay(us)
 
 /* make sure "usecs *= ..." in udelay do not overflow. */
 #if HZ >= 1000
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/div64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,105 +6,63 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-#ifndef _ASM_DIV64_H
-#define _ASM_DIV64_H
+#ifndef __ASM_DIV64_H
+#define __ASM_DIV64_H
 
-#include <linux/types.h>
+#include <asm-generic/div64.h>
 
-#if (_MIPS_SZLONG == 32)
+#if BITS_PER_LONG == 64
 
-#include <asm/compiler.h>
+#include <linux/types.h>
 
 /*
  * No traps on overflows for any of these...
  */
 
-#define do_div64_32(res, high, low, base) ({ \
-	unsigned long __quot32, __mod32; \
-	unsigned long __cf, __tmp, __tmp2, __i; \
-	\
-	__asm__(".set	push\n\t" \
-		".set	noat\n\t" \
-		".set	noreorder\n\t" \
-		"move	%2, $0\n\t" \
-		"move	%3, $0\n\t" \
-		"b	1f\n\t" \
-		" li	%4, 0x21\n" \
-		"0:\n\t" \
-		"sll	$1, %0, 0x1\n\t" \
-		"srl	%3, %0, 0x1f\n\t" \
-		"or	%0, $1, %5\n\t" \
-		"sll	%1, %1, 0x1\n\t" \
-		"sll	%2, %2, 0x1\n" \
-		"1:\n\t" \
-		"bnez	%3, 2f\n\t" \
-		" sltu	%5, %0, %z6\n\t" \
-		"bnez	%5, 3f\n" \
-		"2:\n\t" \
-		" addiu	%4, %4, -1\n\t" \
-		"subu	%0, %0, %z6\n\t" \
-		"addiu	%2, %2, 1\n" \
-		"3:\n\t" \
-		"bnez	%4, 0b\n\t" \
-		" srl	%5, %1, 0x1f\n\t" \
-		".set	pop" \
-		: "=&r" (__mod32), "=&r" (__tmp), \
-		  "=&r" (__quot32), "=&r" (__cf), \
-		  "=&r" (__i), "=&r" (__tmp2) \
-		: "Jr" (base), "0" (high), "1" (low)); \
-	\
-	(res) = __quot32; \
-	__mod32; })
-
-#define do_div(n, base) ({ \
-	unsigned long long __quot; \
-	unsigned long __mod; \
-	unsigned long long __div; \
-	unsigned long __upper, __low, __high, __base; \
-	\
-	__div = (n); \
-	__base = (base); \
-	\
-	__high = __div >> 32; \
-	__low = __div; \
-	__upper = __high; \
-	\
-	if (__high) \
-		__asm__("divu	$0, %z2, %z3" \
-			: "=h" (__upper), "=l" (__high) \
-			: "Jr" (__high), "Jr" (__base) \
-			: GCC_REG_ACCUM); \
-	\
-	__mod = do_div64_32(__low, __upper, __low, __base); \
-	\
-	__quot = __high; \
-	__quot = __quot << 32 | __low; \
-	(n) = __quot; \
-	__mod; })
-
-#endif /* (_MIPS_SZLONG == 32) */
-
-#if (_MIPS_SZLONG == 64)
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n, base) ({ \
-	unsigned long __quot; \
-	unsigned int __mod; \
-	unsigned long __div; \
-	unsigned int __base; \
-	\
-	__div = (n); \
-	__base = (base); \
-	\
-	__mod = __div % __base; \
-	__quot = __div / __base; \
-	\
-	(n) = __quot; \
-	__mod; })
+#define __div64_32(n, base)						\
+({									\
+	unsigned long __cf, __tmp, __tmp2, __i;				\
+	unsigned long __quot32, __mod32;				\
+	unsigned long __high, __low;					\
+	unsigned long long __n;						\
+									\
+	__high = *__n >> 32;						\
+	__low = __n;							\
+	__asm__(							\
+	"	.set	push					\n"	\
+	"	.set	noat					\n"	\
+	"	.set	noreorder				\n"	\
+	"	move	%2, $0					\n"	\
+	"	move	%3, $0					\n"	\
+	"	b	1f					\n"	\
+	"	 li	%4, 0x21				\n"	\
+	"0:							\n"	\
+	"	sll	$1, %0, 0x1				\n"	\
+	"	srl	%3, %0, 0x1f				\n"	\
+	"	or	%0, $1, %5				\n"	\
+	"	sll	%1, %1, 0x1				\n"	\
+	"	sll	%2, %2, 0x1				\n"	\
+	"1:							\n"	\
+	"	bnez	%3, 2f					\n"	\
+	"	 sltu	%5, %0, %z6				\n"	\
+	"	bnez	%5, 3f					\n"	\
+	"2:							\n"	\
+	"	 addiu	%4, %4, -1				\n"	\
+	"	subu	%0, %0, %z6				\n"	\
+	"	addiu	%2, %2, 1				\n"	\
+	"3:							\n"	\
+	"	bnez	%4, 0b\n\t"					\
+	"	 srl	%5, %1, 0x1f\n\t"				\
+	"	.set	pop"						\
+	: "=&r" (__mod32), "=&r" (__tmp),				\
+	  "=&r" (__quot32), "=&r" (__cf),				\
+	  "=&r" (__i), "=&r" (__tmp2)					\
+	: "Jr" (base), "0" (__high), "1" (__low));			\
+									\
+	(__n) = __quot32;						\
+	__mod32;							\
+})
 
-#endif /* (_MIPS_SZLONG == 64) */
+#endif /* BITS_PER_LONG == 64 */
 
-#endif /* _ASM_DIV64_H */
+#endif /* __ASM_DIV64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,13 @@ extern int dma_map_sg(struct device *dev
 	enum dma_data_direction direction);
 extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
 	unsigned long offset, size_t size, enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-	size_t size, enum dma_data_direction direction);
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+	size_t size, enum dma_data_direction direction)
+{
+	dma_unmap_single(dev, dma_address, size, direction);
+}
+
 extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 	int nhwentries, enum dma_data_direction direction);
 extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/fixmap.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/fixmap.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/fixmap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/fixmap.h	2009-06-09 23:05:27.000000000 -0400
@@ -108,6 +108,9 @@ static inline unsigned long virt_to_fix(
 	return __virt_to_fix(vaddr);
 }
 
+#define kmap_get_fixmap_pte(vaddr)					\
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
 /*
  * Called from pgtable_init()
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/hazards.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/hazards.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/hazards.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/hazards.h	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,7 @@ do {									\
 	: "=r" (tmp));							\
 } while (0)
 
-#elif defined(CONFIG_CPU_MIPSR1)
+#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MACH_ALCHEMY)
 
 /*
  * These are slightly complicated by the fact that we guarantee R1 kernels to
@@ -138,7 +138,8 @@ do {									\
 		__instruction_hazard();					\
 } while (0)
 
-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
+#elif defined(CONFIG_MACH_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
+      defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
       defined(CONFIG_CPU_R5500)
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/highmem.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -30,8 +30,6 @@
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
 
-extern pte_t *kmap_pte;
-extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
 /*
@@ -62,6 +60,10 @@ extern struct page *__kmap_atomic_to_pag
 
 #define flush_cache_kmaps()	flush_cache_all()
 
+extern void kmap_init(void);
+
+#define kmap_prot PAGE_KERNEL
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/ioctl.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/ioctl.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/ioctl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/ioctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -60,12 +60,16 @@
 	 ((nr)   << _IOC_NRSHIFT) | \
 	 ((size) << _IOC_SIZESHIFT))
 
+#ifdef __KERNEL__
 /* provoke compile error for invalid uses of size argument */
 extern unsigned int __invalid_size_argument_for_IOC;
 #define _IOC_TYPECHECK(t) \
 	((sizeof(t) == sizeof(t[1]) && \
 	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
 	  sizeof(t) : __invalid_size_argument_for_IOC)
+#else
+#define _IOC_TYPECHECK(t)	(sizeof(t))
+#endif
 
 /* used to create numbers */
 #define _IO(type, nr)		_IOC(_IOC_NONE, (type), (nr), 0)
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -66,7 +66,7 @@ extern void smtc_forward_irq(unsigned in
  */
 #define IRQ_AFFINITY_HOOK(irq)						\
 do {									\
-    if (!cpu_isset(smp_processor_id(), irq_desc[irq].affinity)) {	\
+    if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\
 	smtc_forward_irq(irq);						\
 	irq_exit();							\
 	return;								\
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/au1000.h	2009-06-09 23:05:27.000000000 -0400
@@ -715,7 +715,7 @@ enum soc_au1500_ints {
 #ifdef CONFIG_SOC_AU1100
 enum soc_au1100_ints {
 	AU1100_FIRST_INT	= MIPS_CPU_IRQ_BASE + 8,
-	AU1100_UART0_INT,
+	AU1100_UART0_INT	= AU1100_FIRST_INT,
 	AU1100_UART1_INT,
 	AU1100_SD_INT,
 	AU1100_UART3_INT,
@@ -902,8 +902,8 @@ enum soc_au1200_ints {
 	AU1000_RTC_MATCH0_INT,
 	AU1000_RTC_MATCH1_INT,
 	AU1000_RTC_MATCH2_INT,
-
-	AU1200_NAND_INT		= AU1200_FIRST_INT + 23,
+	AU1200_GPIO_203,
+	AU1200_NAND_INT,
 	AU1200_GPIO_204,
 	AU1200_GPIO_205,
 	AU1200_GPIO_206,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h	2009-06-09 23:05:27.000000000 -0400
@@ -46,20 +46,6 @@
 #define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON	0
 #endif
 
-#ifdef CONFIG_PM
-/*
- * This will enable the device to be powered up when write() or read()
- * is called. If this is not defined, the driver will return -EBUSY.
- */
-#define WAKE_ON_ACCESS 1
-
-typedef struct {
-	spinlock_t		lock;	/* Used to block on state transitions */
-	au1xxx_power_dev_t	*dev;	/* Power Managers device structure */
-	unsigned		stopped; /* Used to signal device is stopped */
-} pm_state;
-#endif
-
 typedef struct {
 	u32			tx_dev_id, rx_dev_id, target_dev_id;
 	u32			tx_chan, rx_chan;
@@ -72,9 +58,6 @@ typedef struct {
 #endif
 	int			irq;
 	u32			regbase;
-#ifdef CONFIG_PM
-	pm_state		pm;
-#endif
 } _auide_hwif;
 
 /******************************************************************************/
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ * 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 __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb			1
+#define cpu_has_4kex			1
+#define cpu_has_3k_cache		0
+#define cpu_has_4k_cache		1
+#define cpu_has_tx39_cache		0
+#define cpu_has_fpu			0
+#define cpu_has_counter			1
+#define cpu_has_watch			1
+#define cpu_has_divec			1
+#define cpu_has_vce			0
+#define cpu_has_cache_cdex_p		0
+#define cpu_has_cache_cdex_s		0
+#define cpu_has_mcheck			1
+#define cpu_has_ejtag			1
+#define cpu_has_llsc			1
+#define cpu_has_mips16			0
+#define cpu_has_mdmx			0
+#define cpu_has_mips3d			0
+#define cpu_has_smartmips		0
+#define cpu_has_vtag_icache		0
+#define cpu_has_dc_aliases		0
+#define cpu_has_ic_fills_f_dc		1
+#define cpu_has_mips32r1		1
+#define cpu_has_mips32r2		0
+#define cpu_has_mips64r1		0
+#define cpu_has_mips64r2		0
+#define cpu_has_dsp			0
+#define cpu_has_mipsmt			0
+#define cpu_has_userlocal		0
+#define cpu_has_nofpuex			0
+#define cpu_has_64bits			0
+#define cpu_has_64bit_zero_reg		0
+#define cpu_has_vint			0
+#define cpu_has_veic			0
+#define cpu_has_inclusive_pcaches	0
+
+#define cpu_dcache_line_size()		32
+#define cpu_icache_line_size()		32
+
+#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-au1x00/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,65 +5,29 @@
 
 #define AU1XXX_GPIO_BASE	200
 
-struct au1x00_gpio2 {
-	u32	dir;
-	u32	reserved;
-	u32	output;
-	u32	pinstate;
-	u32	inten;
-	u32	enable;
-};
-
-extern int au1xxx_gpio_get_value(unsigned gpio);
-extern void au1xxx_gpio_set_value(unsigned gpio, int value);
-extern int au1xxx_gpio_direction_input(unsigned gpio);
-extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
-
-
-/* Wrappers for the arch-neutral GPIO API */
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-	/* Not yet implemented */
-	return 0;
-}
-
-static inline void gpio_free(unsigned gpio)
-{
-	/* Not yet implemented */
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-	return au1xxx_gpio_direction_input(gpio);
-}
+/* GPIO bank 1 offsets */
+#define AU1000_GPIO1_TRI_OUT	0x0100
+#define AU1000_GPIO1_OUT	0x0108
+#define AU1000_GPIO1_ST		0x0110
+#define AU1000_GPIO1_CLR	0x010C
 
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-	return au1xxx_gpio_direction_output(gpio, value);
-}
+/* GPIO bank 2 offsets */
+#define AU1000_GPIO2_DIR	0x00
+#define AU1000_GPIO2_RSVD	0x04
+#define AU1000_GPIO2_OUT	0x08
+#define AU1000_GPIO2_ST		0x0C
+#define AU1000_GPIO2_INT	0x10
+#define AU1000_GPIO2_EN		0x14
 
-static inline int gpio_get_value(unsigned gpio)
-{
-	return au1xxx_gpio_get_value(gpio);
-}
+#define GPIO2_OUT_EN_MASK	0x00010000
 
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	au1xxx_gpio_set_value(gpio, value);
-}
+#define gpio_to_irq(gpio)	NULL
 
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return gpio;
-}
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
 
-static inline int irq_to_gpio(unsigned irq)
-{
-	return irq;
-}
+#define gpio_cansleep __gpio_cansleep
 
-/* For cansleep */
 #include <asm-generic/gpio.h>
 
 #endif /* _AU1XXX_GPIO_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-bcm47xx/gpio.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-bcm47xx/gpio.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-bcm47xx/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-bcm47xx/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,24 +31,28 @@ static inline void gpio_set_value(unsign
 
 static inline int gpio_direction_input(unsigned gpio)
 {
-	return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+	return 0;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-	return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+	return 0;
 }
 
-static int gpio_intmask(unsigned gpio, int value)
+static inline int gpio_intmask(unsigned gpio, int value)
 {
-	return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
-				value ? 1 << gpio : 0);
+	ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
+			 value ? 1 << gpio : 0);
+	return 0;
 }
 
-static int gpio_polarity(unsigned gpio, int value)
+static inline int gpio_polarity(unsigned gpio, int value)
 {
-	return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
-				 value ? 1 << gpio : 0);
+	ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
+			  value ? 1 << gpio : 0);
+	return 0;
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-ip27/topology.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-ip27/topology.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-ip27/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-ip27/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@ extern struct cpuinfo_ip27 sn_cpu_info[N
 #define parent_node(node)	(node)
 #define node_to_cpumask(node)	(hub_data(node)->h_cpus)
 #define cpumask_of_node(node)	(&hub_data(node)->h_cpus)
-#define node_to_first_cpu(node)	(cpumask_first(cpumask_of_node(node)))
 struct pci_bus;
 extern int pcibus_to_node(struct pci_bus *);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * 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 Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * reference: /proc/cpuinfo,
+ * 	arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
+ * 	arch/mips/kernel/proc.c(show_cpuinfo),
+ *      loongson2f user manual.
+ */
+
+#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+#define cpu_scache_line_size()	32
+
+
+#define cpu_has_32fpr		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_4kex		1
+#define cpu_has_64bits		1
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_counter		1
+#define cpu_has_dc_aliases	1
+#define cpu_has_divec		0
+#define cpu_has_dsp		0
+#define cpu_has_ejtag		0
+#define cpu_has_fpu		1
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_inclusive_pcaches	1
+#define cpu_has_llsc 		1
+#define cpu_has_mcheck		0
+#define cpu_has_mdmx		0
+#define cpu_has_mips16		0
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips3d		0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+#define cpu_has_mipsmt		0
+#define cpu_has_prefetch	0
+#define cpu_has_smartmips	0
+#define cpu_has_tlb		1
+#define cpu_has_tx39_cache	0
+#define cpu_has_userlocal	0
+#define cpu_has_vce		0
+#define cpu_has_vtag_icache	0
+#define cpu_has_watch		1
+#define cpu_icache_snoops_remote_store	1
+
+#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-rc32434/gpio.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-rc32434/gpio.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mach-rc32434/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mach-rc32434/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,6 +80,9 @@ struct rb532_gpio_reg {
 /* Compact Flash GPIO pin */
 #define CF_GPIO_NUM		13
 
+/* S1 button GPIO (shared with UART0_SIN) */
+#define GPIO_BTN_S1		1
+
 extern void rb532_gpio_set_ilevel(int bit, unsigned gpio);
 extern void rb532_gpio_set_istat(int bit, unsigned gpio);
 extern void rb532_gpio_set_func(unsigned gpio);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mips-boards/generic.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mips-boards/generic.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mips-boards/generic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mips-boards/generic.h	2009-06-09 23:05:27.000000000 -0400
@@ -71,8 +71,6 @@
 
 #define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f)
 
-extern int mips_revision_corid;
-
 #define MIPS_REVISION_SCON_OTHER	   0
 #define MIPS_REVISION_SCON_SOCITSC	   1
 #define MIPS_REVISION_SCON_SOCITSCP	   2
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/mipsregs.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/mipsregs.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/mipsregs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/mipsregs.h	2009-06-09 23:05:27.000000000 -0400
@@ -184,12 +184,19 @@
 #else
 
 #define PM_4K		0x00000000
+#define PM_8K		0x00002000
 #define PM_16K		0x00006000
+#define PM_32K		0x0000e000
 #define PM_64K		0x0001e000
+#define PM_128K		0x0003e000
 #define PM_256K		0x0007e000
+#define PM_512K		0x000fe000
 #define PM_1M		0x001fe000
+#define PM_2M		0x003fe000
 #define PM_4M		0x007fe000
+#define PM_8M		0x00ffe000
 #define PM_16M		0x01ffe000
+#define PM_32M		0x03ffe000
 #define PM_64M		0x07ffe000
 #define PM_256M		0x1fffe000
 #define PM_1G		0x7fffe000
@@ -201,8 +208,12 @@
  */
 #ifdef CONFIG_PAGE_SIZE_4KB
 #define PM_DEFAULT_MASK	PM_4K
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+#define PM_DEFAULT_MASK	PM_8K
 #elif defined(CONFIG_PAGE_SIZE_16KB)
 #define PM_DEFAULT_MASK	PM_16K
+#elif defined(CONFIG_PAGE_SIZE_32KB)
+#define PM_DEFAULT_MASK	PM_32K
 #elif defined(CONFIG_PAGE_SIZE_64KB)
 #define PM_DEFAULT_MASK	PM_64K
 #else
@@ -717,8 +728,8 @@ do {									\
 			".set\tmips64\n\t"				\
 			"dmfc0\t%M0, " #source "\n\t"			\
 			"dsll\t%L0, %M0, 32\n\t"			\
-			"dsrl\t%M0, %M0, 32\n\t"			\
-			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsra\t%M0, %M0, 32\n\t"			\
+			"dsra\t%L0, %L0, 32\n\t"			\
 			".set\tmips0"					\
 			: "=r" (__val));				\
 	else								\
@@ -726,8 +737,8 @@ do {									\
 			".set\tmips64\n\t"				\
 			"dmfc0\t%M0, " #source ", " #sel "\n\t"		\
 			"dsll\t%L0, %M0, 32\n\t"			\
-			"dsrl\t%M0, %M0, 32\n\t"			\
-			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsra\t%M0, %M0, 32\n\t"			\
+			"dsra\t%L0, %L0, 32\n\t"			\
 			".set\tmips0"					\
 			: "=r" (__val));				\
 	local_irq_restore(__flags);					\
@@ -1391,11 +1402,11 @@ static inline void tlb_write_random(void
 static inline unsigned int					\
 set_c0_##name(unsigned int set)					\
 {								\
-	unsigned int res;					\
+	unsigned int res, new;					\
 								\
 	res = read_c0_##name();					\
-	res |= set;						\
-	write_c0_##name(res);					\
+	new = res | set;					\
+	write_c0_##name(new);					\
 								\
 	return res;						\
 }								\
@@ -1403,24 +1414,24 @@ set_c0_##name(unsigned int set)					\
 static inline unsigned int					\
 clear_c0_##name(unsigned int clear)				\
 {								\
-	unsigned int res;					\
+	unsigned int res, new;					\
 								\
 	res = read_c0_##name();					\
-	res &= ~clear;						\
-	write_c0_##name(res);					\
+	new = res & ~clear;					\
+	write_c0_##name(new);					\
 								\
 	return res;						\
 }								\
 								\
 static inline unsigned int					\
-change_c0_##name(unsigned int change, unsigned int new)		\
+change_c0_##name(unsigned int change, unsigned int val)		\
 {								\
-	unsigned int res;					\
+	unsigned int res, new;					\
 								\
 	res = read_c0_##name();					\
-	res &= ~change;						\
-	res |= (new & change);					\
-	write_c0_##name(res);					\
+	new = res & ~change;					\
+	new |= (val & change);					\
+	write_c0_##name(new);					\
 								\
 	return res;						\
 }
@@ -1484,14 +1495,15 @@ static inline unsigned int					\
 set_c0_##name(unsigned int set)					\
 {								\
 	unsigned int res;					\
+	unsigned int new;					\
 	unsigned int omt;					\
 	unsigned long flags;					\
 								\
 	local_irq_save(flags);					\
 	omt = __dmt();						\
 	res = read_c0_##name();					\
-	res |= set;						\
-	write_c0_##name(res);					\
+	new = res | set;					\
+	write_c0_##name(new);					\
 	__emt(omt);						\
 	local_irq_restore(flags);				\
 								\
@@ -1502,14 +1514,15 @@ static inline unsigned int					\
 clear_c0_##name(unsigned int clear)				\
 {								\
 	unsigned int res;					\
+	unsigned int new;					\
 	unsigned int omt;					\
 	unsigned long flags;					\
 								\
 	local_irq_save(flags);					\
 	omt = __dmt();						\
 	res = read_c0_##name();					\
-	res &= ~clear;						\
-	write_c0_##name(res);					\
+	new = res & ~clear;					\
+	write_c0_##name(new);					\
 	__emt(omt);						\
 	local_irq_restore(flags);				\
 								\
@@ -1517,9 +1530,10 @@ clear_c0_##name(unsigned int clear)				\
 }								\
 								\
 static inline unsigned int					\
-change_c0_##name(unsigned int change, unsigned int new)		\
+change_c0_##name(unsigned int change, unsigned int newbits)	\
 {								\
 	unsigned int res;					\
+	unsigned int new;					\
 	unsigned int omt;					\
 	unsigned long flags;					\
 								\
@@ -1527,9 +1541,9 @@ change_c0_##name(unsigned int change, un
 								\
 	omt = __dmt();						\
 	res = read_c0_##name();					\
-	res &= ~change;						\
-	res |= (new & change);					\
-	write_c0_##name(res);					\
+	new = res & ~change;					\
+	new |= (newbits & change);				\
+	write_c0_##name(new);					\
 	__emt(omt);						\
 	local_irq_restore(flags);				\
 								\
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/page.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,9 @@
 #ifdef CONFIG_PAGE_SIZE_16KB
 #define PAGE_SHIFT	14
 #endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PAGE_SHIFT	15
+#endif
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PAGE_SHIFT	16
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/pgtable-64.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/pgtable-64.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/pgtable-64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/pgtable-64.h	2009-06-09 23:05:27.000000000 -0400
@@ -83,6 +83,12 @@
 #define PMD_ORDER		0
 #define PTE_ORDER		0
 #endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PGD_ORDER		0
+#define PUD_ORDER		aieeee_attempt_to_allocate_pud
+#define PMD_ORDER		0
+#define PTE_ORDER		0
+#endif
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PGD_ORDER		0
 #define PUD_ORDER		aieeee_attempt_to_allocate_pud
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/sigcontext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 #ifndef _ASM_SIGCONTEXT_H
 #define _ASM_SIGCONTEXT_H
 
+#include <linux/types.h>
 #include <asm/sgidefs.h>
 
 #if _MIPS_SIM == _MIPS_SIM_ABI32
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/smp-ops.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/smp-ops.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/smp-ops.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/smp-ops.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,8 @@
 
 #include <linux/cpumask.h>
 
+struct task_struct;
+
 struct plat_smp_ops {
 	void (*send_ipi_single)(int cpu, unsigned int action);
 	void (*send_ipi_mask)(cpumask_t mask, unsigned int action);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/sn/addrs.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/sn/addrs.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/sn/addrs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/sn/addrs.h	2009-06-09 23:05:27.000000000 -0400
@@ -359,11 +359,11 @@
 	TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice))
 #define LAUNCH_SIZE(nasid)	KLD_LAUNCH(nasid)->size
 
-#define NMI_OFFSET(nasid, slice)					\
+#define SN_NMI_OFFSET(nasid, slice)					\
 	(KLD_NMI(nasid)->offset +					\
 	 KLD_NMI(nasid)->stride * (slice))
 #define NMI_ADDR(nasid, slice)						\
-	TO_NODE_UNCAC((nasid), NMI_OFFSET(nasid, slice))
+	TO_NODE_UNCAC((nasid), SN_NMI_OFFSET(nasid, slice))
 #define NMI_SIZE(nasid)	KLD_NMI(nasid)->size
 
 #define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/sn/nmi.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/sn/nmi.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/sn/nmi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/sn/nmi.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,13 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
+ * Derived from IRIX <sys/SN/nmi.h>, Revision 1.5.
+ *
  * Copyright (C) 1992 - 1997 Silicon Graphics, Inc.
  */
 #ifndef __ASM_SN_NMI_H
 #define __ASM_SN_NMI_H
 
-#ident "$Revision: 1.5 $"
-
 #include <asm/sn/addrs.h>
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -75,6 +75,9 @@ To add: #define SO_REUSEPORT 0x0200	/* A
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #ifdef __KERNEL__
 
 /** sock_type - Socket types
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,7 @@ static inline void __raw_spin_lock(raw_s
 		"2:							\n"
 		"	.subsection 2					\n"
 		"4:	andi	%[ticket], %[ticket], 0x1fff		\n"
-		"5:	sll	%[ticket], 5				\n"
+		"	sll	%[ticket], 5				\n"
 		"							\n"
 		"6:	bnez	%[ticket], 6b				\n"
 		"	 subu	%[ticket], 1				\n"
@@ -85,7 +85,7 @@ static inline void __raw_spin_lock(raw_s
 		"	andi	%[ticket], %[ticket], 0x1fff		\n"
 		"	beq	%[ticket], %[my_ticket], 2b		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
-		"	b	5b					\n"
+		"	b	4b					\n"
 		"	 subu	%[ticket], %[ticket], 1			\n"
 		"	.previous					\n"
 		"	.set pop					\n"
@@ -113,7 +113,7 @@ static inline void __raw_spin_lock(raw_s
 		"	 ll	%[ticket], %[ticket_ptr]		\n"
 		"							\n"
 		"4:	andi	%[ticket], %[ticket], 0x1fff		\n"
-		"5:	sll	%[ticket], 5				\n"
+		"	sll	%[ticket], 5				\n"
 		"							\n"
 		"6:	bnez	%[ticket], 6b				\n"
 		"	 subu	%[ticket], 1				\n"
@@ -122,7 +122,7 @@ static inline void __raw_spin_lock(raw_s
 		"	andi	%[ticket], %[ticket], 0x1fff		\n"
 		"	beq	%[ticket], %[my_ticket], 2b		\n"
 		"	 subu	%[ticket], %[my_ticket], %[ticket]	\n"
-		"	b	5b					\n"
+		"	b	4b					\n"
 		"	 subu	%[ticket], %[ticket], 1			\n"
 		"	.previous					\n"
 		"	.set pop					\n"
@@ -480,6 +480,8 @@ 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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@
 #define _ASM_SWAB_H
 
 #include <linux/compiler.h>
-#include <asm/types.h>
+#include <linux/types.h>
 
 #define __SWAB_64_THRU_32__
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/thread_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -75,6 +75,9 @@ register struct thread_info *__current_t
 #ifdef CONFIG_PAGE_SIZE_16KB
 #define THREAD_SIZE_ORDER (0)
 #endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define THREAD_SIZE_ORDER (0)
+#endif
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define THREAD_SIZE_ORDER (0)
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/time.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/time.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/time.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/time.h	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,11 @@ extern int r4k_clockevent_init(void);
 
 static inline int mips_clockevent_init(void)
 {
-#ifdef CONFIG_CEVT_R4K
+#ifdef CONFIG_MIPS_MT_SMTC
+	extern int smtc_clockevent_init(void);
+
+	return smtc_clockevent_init();
+#elif defined(CONFIG_CEVT_R4K)
 	return r4k_clockevent_init();
 #else
 	return -ENXIO;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/ndfmc.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/ndfmc.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/ndfmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/ndfmc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2007
+ */
+#ifndef __ASM_TXX9_NDFMC_H
+#define __ASM_TXX9_NDFMC_H
+
+#define NDFMC_PLAT_FLAG_USE_BSPRT	0x01
+#define NDFMC_PLAT_FLAG_NO_RSTR		0x02
+#define NDFMC_PLAT_FLAG_HOLDADD		0x04
+#define NDFMC_PLAT_FLAG_DUMMYWRITE	0x08
+
+struct txx9ndfmc_platform_data {
+	unsigned int shift;
+	unsigned int gbus_clock;
+	unsigned int hold;		/* hold time in nanosecond */
+	unsigned int spw;		/* strobe pulse width in nanosecond */
+	unsigned int flags;
+	unsigned char ch_mask;		/* available channel bitmask */
+	unsigned char wp_mask;		/* write-protect bitmask */
+	unsigned char wide_mask;	/* 16bit-nand bitmask */
+};
+
+void txx9_ndfmc_init(unsigned long baseaddr,
+		     const struct txx9ndfmc_platform_data *plat_data);
+
+#endif /* __ASM_TXX9_NDFMC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/rbtx4939.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/rbtx4939.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/rbtx4939.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/rbtx4939.h	2009-06-09 23:05:27.000000000 -0400
@@ -130,4 +130,13 @@
 void rbtx4939_prom_init(void);
 void rbtx4939_irq_setup(void);
 
+struct mtd_partition;
+struct map_info;
+struct rbtx4939_flash_data {
+	unsigned int width;
+	unsigned int nr_parts;
+	struct mtd_partition *parts;
+	void (*map_init)(struct map_info *map);
+};
+
 #endif /* __ASM_TXX9_RBTX4939_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/tx4938.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/tx4938.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/tx4938.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/tx4938.h	2009-06-09 23:05:27.000000000 -0400
@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pc
 void tx4938_setup_pcierr_irq(void);
 void tx4938_irq_init(void);
 void tx4938_mtd_init(int ch);
+void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
 
 struct tx4938ide_platform_info {
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/tx4939.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/tx4939.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/txx9/tx4939.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/txx9/tx4939.h	2009-06-09 23:05:27.000000000 -0400
@@ -542,5 +542,7 @@ int tx4939_irq(void);
 void tx4939_mtd_init(int ch);
 void tx4939_ata_init(void);
 void tx4939_rtc_init(void);
+void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+		       unsigned char ch_mask, unsigned char wide_mask);
 
 #endif /* __ASM_TXX9_TX4939_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/types.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/types.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,12 +4,18 @@
  * for more details.
  *
  * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 2008 Wind River Systems,
+ *   written by Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #ifndef _ASM_TYPES_H
 #define _ASM_TYPES_H
 
-#if _MIPS_SZLONG == 64
+/*
+ * We don't use int-l64.h for the kernel anymore but still use it for
+ * userspace to avoid code changes.
+ */
+#if (_MIPS_SZLONG == 64) && !defined(__KERNEL__)
 # include <asm-generic/int-l64.h>
 #else
 # include <asm-generic/int-ll64.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/uaccess.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -105,10 +105,20 @@
 #define __access_mask get_fs().seg
 
 #define __access_ok(addr, size, mask)					\
-	(((signed long)((mask) & ((addr) | ((addr) + (size)) | __ua_size(size)))) == 0)
+({									\
+	unsigned long __addr = (unsigned long) (addr);			\
+	unsigned long __size = size;					\
+	unsigned long __mask = mask;					\
+	unsigned long __ok;						\
+									\
+	__chk_user_ptr(addr);						\
+	__ok = (signed long)(__mask & (__addr | (__addr + __size) |	\
+		__ua_size(__size)));					\
+	__ok == 0;							\
+})
 
 #define access_ok(type, addr, size)					\
-	likely(__access_ok((unsigned long)(addr), (size), __access_mask))
+	likely(__access_ok((addr), (size), __access_mask))
 
 /*
  * put_user: - Write a simple value into user space.
@@ -225,6 +235,7 @@ do {									\
 ({									\
 	int __gu_err;							\
 									\
+	__chk_user_ptr(ptr);						\
 	__get_user_common((x), size, ptr);				\
 	__gu_err;							\
 })
@@ -234,6 +245,7 @@ do {									\
 	int __gu_err = -EFAULT;						\
 	const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);		\
 									\
+	might_fault();							\
 	if (likely(access_ok(VERIFY_READ,  __gu_ptr, size)))		\
 		__get_user_common((x), size, __gu_ptr);			\
 									\
@@ -305,6 +317,7 @@ do {									\
 	__typeof__(*(ptr)) __pu_val;					\
 	int __pu_err = 0;						\
 									\
+	__chk_user_ptr(ptr);						\
 	__pu_val = (x);							\
 	switch (size) {							\
 	case 1: __put_user_asm("sb", ptr); break;			\
@@ -322,6 +335,7 @@ do {									\
 	__typeof__(*(ptr)) __pu_val = (x);				\
 	int __pu_err = -EFAULT;						\
 									\
+	might_fault();							\
 	if (likely(access_ok(VERIFY_WRITE,  __pu_addr, size))) {	\
 		switch (size) {						\
 		case 1: __put_user_asm("sb", __pu_addr); break;		\
@@ -696,10 +710,10 @@ extern size_t __copy_user(void *__to, co
 	const void *__cu_from;						\
 	long __cu_len;							\
 									\
-	might_sleep();							\
 	__cu_to = (to);							\
 	__cu_from = (from);						\
 	__cu_len = (n);							\
+	might_fault();							\
 	__cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len);	\
 	__cu_len;							\
 })
@@ -752,13 +766,14 @@ extern size_t __copy_user_inatomic(void
 	const void *__cu_from;						\
 	long __cu_len;							\
 									\
-	might_sleep();							\
 	__cu_to = (to);							\
 	__cu_from = (from);						\
 	__cu_len = (n);							\
-	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len))			\
+	if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) {		\
+		might_fault();						\
 		__cu_len = __invoke_copy_to_user(__cu_to, __cu_from,	\
 		                                 __cu_len);		\
+	}								\
 	__cu_len;							\
 })
 
@@ -831,10 +846,10 @@ extern size_t __copy_user_inatomic(void
 	const void __user *__cu_from;					\
 	long __cu_len;							\
 									\
-	might_sleep();							\
 	__cu_to = (to);							\
 	__cu_from = (from);						\
 	__cu_len = (n);							\
+	might_fault();							\
 	__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,		\
 	                                   __cu_len);			\
 	__cu_len;							\
@@ -862,17 +877,31 @@ extern size_t __copy_user_inatomic(void
 	const void __user *__cu_from;					\
 	long __cu_len;							\
 									\
-	might_sleep();							\
 	__cu_to = (to);							\
 	__cu_from = (from);						\
 	__cu_len = (n);							\
-	if (access_ok(VERIFY_READ, __cu_from, __cu_len))		\
+	if (access_ok(VERIFY_READ, __cu_from, __cu_len)) {		\
+		might_fault();						\
 		__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,	\
 		                                   __cu_len);		\
+	}								\
 	__cu_len;							\
 })
 
-#define __copy_in_user(to, from, n)	__copy_from_user(to, from, n)
+#define __copy_in_user(to, from, n)					\
+({									\
+	void __user *__cu_to;						\
+	const void __user *__cu_from;					\
+	long __cu_len;							\
+									\
+	__cu_to = (to);							\
+	__cu_from = (from);						\
+	__cu_len = (n);							\
+	might_fault();							\
+	__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,		\
+	                                   __cu_len);			\
+	__cu_len;							\
+})
 
 #define copy_in_user(to, from, n)					\
 ({									\
@@ -880,14 +909,15 @@ extern size_t __copy_user_inatomic(void
 	const void __user *__cu_from;					\
 	long __cu_len;							\
 									\
-	might_sleep();							\
 	__cu_to = (to);							\
 	__cu_from = (from);						\
 	__cu_len = (n);							\
 	if (likely(access_ok(VERIFY_READ, __cu_from, __cu_len) &&	\
-	           access_ok(VERIFY_WRITE, __cu_to, __cu_len)))		\
+	           access_ok(VERIFY_WRITE, __cu_to, __cu_len))) {	\
+		might_fault();						\
 		__cu_len = __invoke_copy_from_user(__cu_to, __cu_from,	\
 		                                   __cu_len);		\
+	}								\
 	__cu_len;							\
 })
 
@@ -907,7 +937,7 @@ __clear_user(void __user *addr, __kernel
 {
 	__kernel_size_t res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, $0\n\t"
@@ -926,7 +956,7 @@ __clear_user(void __user *addr, __kernel
 	void __user * __cl_addr = (addr);				\
 	unsigned long __cl_size = (n);					\
 	if (__cl_size && access_ok(VERIFY_WRITE,			\
-		((unsigned long)(__cl_addr)), __cl_size))		\
+					__cl_addr, __cl_size))		\
 		__cl_size = __clear_user(__cl_addr, __cl_size);		\
 	__cl_size;							\
 })
@@ -956,7 +986,7 @@ __strncpy_from_user(char *__to, const ch
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
@@ -993,7 +1023,7 @@ strncpy_from_user(char *__to, const char
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
@@ -1012,7 +1042,7 @@ static inline long __strlen_user(const c
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		__MODULE_JAL(__strlen_user_nocheck_asm)
@@ -1042,7 +1072,7 @@ static inline long strlen_user(const cha
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		__MODULE_JAL(__strlen_user_asm)
@@ -1059,7 +1089,7 @@ static inline long __strnlen_user(const
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
@@ -1090,7 +1120,7 @@ static inline long strnlen_user(const ch
 {
 	long res;
 
-	might_sleep();
+	might_fault();
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/mips/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/mips/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -350,16 +350,18 @@
 #define __NR_dup3			(__NR_Linux + 327)
 #define __NR_pipe2			(__NR_Linux + 328)
 #define __NR_inotify_init1		(__NR_Linux + 329)
+#define __NR_preadv			(__NR_Linux + 330)
+#define __NR_pwritev			(__NR_Linux + 331)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		329
+#define __NR_Linux_syscalls		331
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		329
+#define __NR_O32_Linux_syscalls		331
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -656,16 +658,18 @@
 #define __NR_dup3			(__NR_Linux + 286)
 #define __NR_pipe2			(__NR_Linux + 287)
 #define __NR_inotify_init1		(__NR_Linux + 288)
+#define __NR_preadv			(__NR_Linux + 289)
+#define __NR_pwritev			(__NR_Linux + 290)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		288
+#define __NR_Linux_syscalls		290
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		288
+#define __NR_64_Linux_syscalls		290
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -966,16 +970,18 @@
 #define __NR_dup3			(__NR_Linux + 290)
 #define __NR_pipe2			(__NR_Linux + 291)
 #define __NR_inotify_init1		(__NR_Linux + 292)
+#define __NR_preadv			(__NR_Linux + 293)
+#define __NR_pwritev			(__NR_Linux + 294)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		292
+#define __NR_Linux_syscalls		294
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		292
+#define __NR_N32_Linux_syscalls		294
 
 #ifdef __KERNEL__
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/jazz/irq.c linux-libre-2.6.30-gnu1/arch/mips/jazz/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/jazz/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/jazz/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -134,7 +134,6 @@ static irqreturn_t r4030_timer_interrupt
 static struct irqaction r4030_timer_irqaction = {
 	.handler	= r4030_timer_interrupt,
 	.flags		= IRQF_DISABLED,
-	.mask		= CPU_MASK_CPU0,
 	.name		= "R4030 timer",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/jazz/jazzdma.c linux-libre-2.6.30-gnu1/arch/mips/jazz/jazzdma.c
--- linux-libre-2.6.29-gnu1/arch/mips/jazz/jazzdma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/jazz/jazzdma.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,8 +68,7 @@ static int __init vdma_init(void)
 	 */
 	pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
 						    get_order(VDMA_PGTBL_SIZE));
-	if (!pgtbl)
-		BUG();
+	BUG_ON(!pgtbl);
 	dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
 	pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/Kconfig linux-libre-2.6.30-gnu1/arch/mips/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mips/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -72,12 +72,12 @@ config MIPS_COBALT
 	select IRQ_CPU
 	select IRQ_GT641XX
 	select PCI_GT64XXX_PCI0
+	select PCI
 	select SYS_HAS_CPU_NEVADA
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 
 config MACH_DECSTATION
 	bool "DECstations"
@@ -132,11 +132,10 @@ config MACH_JAZZ
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select SYS_SUPPORTS_100HZ
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
 	 This a family of machines based on the MIPS R4030 chipset which was
 	 used by several vendors to build RISC/os and Windows NT workstations.
-	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
 	 Olivetti M700-10 workstations.
 
 config LASAT
@@ -154,7 +153,6 @@ config LASAT
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 
 config LEMOTE_FULONG
 	bool "Lemote Fulong mini-PC"
@@ -175,7 +173,6 @@ config LEMOTE_FULONG
 	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
@@ -250,7 +247,6 @@ config MACH_VR41XX
 	select CEVT_R4K
 	select CSRC_R4K
 	select SYS_HAS_CPU_VR41XX
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 
 config NXP_STB220
 	bool "NXP STB220 board"
@@ -364,7 +360,6 @@ config SGI_IP27
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_NUMA
 	select SYS_SUPPORTS_SMP
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
 	  This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
 	  workstations.  To compile a Linux kernel that runs on these, say Y
@@ -563,7 +558,6 @@ config MIKROTIK_RB532
 	select CEVT_R4K
 	select CSRC_R4K
 	select DMA_NONCOHERENT
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 	select HW_HAS_PCI
 	select IRQ_CPU
 	select SYS_HAS_CPU_MIPS32_R1
@@ -600,7 +594,7 @@ config WR_PPMC
 	  board, which is based on GT64120 bridge chip.
 
 config CAVIUM_OCTEON_SIMULATOR
-	bool "Support for the Cavium Networks Octeon Simulator"
+	bool "Cavium Networks Octeon Simulator"
 	select CEVT_R4K
 	select 64BIT_PHYS_ADDR
 	select DMA_COHERENT
@@ -614,7 +608,7 @@ config CAVIUM_OCTEON_SIMULATOR
 	  hardware.
 
 config CAVIUM_OCTEON_REFERENCE_BOARD
-	bool "Support for the Cavium Networks Octeon reference board"
+	bool "Cavium Networks Octeon reference board"
 	select CEVT_R4K
 	select 64BIT_PHYS_ADDR
 	select DMA_COHERENT
@@ -700,8 +694,7 @@ config SCHED_OMIT_FRAME_POINTER
 	default y
 
 config GENERIC_HARDIRQS_NO__DO_IRQ
-	bool
-	default n
+	def_bool y
 
 #
 # Select some configuration options automatically based on user selections.
@@ -920,7 +913,6 @@ config SOC_PNX833X
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 	select GENERIC_GPIO
 	select CPU_MIPSR2_IRQ_VI
 
@@ -939,7 +931,6 @@ config SOC_PNX8550
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 	select GENERIC_GPIO
 
 config SWAP_IO_SPACE
@@ -1421,13 +1412,12 @@ config PAGE_SIZE_4KB
 
 config PAGE_SIZE_8KB
 	bool "8kB"
-	depends on EXPERIMENTAL && CPU_R8000
+	depends on (EXPERIMENTAL && CPU_R8000) || CPU_CAVIUM_OCTEON
 	help
 	  Using 8kB page size will result in higher performance kernel at
 	  the price of higher memory consumption.  This option is available
-	  only on the R8000 processor.  Not that at the time of this writing
-	  this option is still high experimental; there are also issues with
-	  compatibility of user applications.
+	  only on R8000 and cnMIPS processors.  Note that you will need a
+	  suitable Linux distribution to support this.
 
 config PAGE_SIZE_16KB
 	bool "16kB"
@@ -1438,6 +1428,15 @@ config PAGE_SIZE_16KB
 	  all non-R3000 family processors.  Note that you will need a suitable
 	  Linux distribution to support this.
 
+config PAGE_SIZE_32KB
+	bool "32kB"
+	depends on CPU_CAVIUM_OCTEON
+	help
+	  Using 32kB page size will result in higher performance kernel at
+	  the price of higher memory consumption.  This option is available
+	  only on cnMIPS cores.  Note that you will need a suitable Linux
+	  distribution to support this.
+
 config PAGE_SIZE_64KB
 	bool "64kB"
 	depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX
@@ -1968,10 +1967,6 @@ config SECCOMP
 
 endmenu
 
-config RWSEM_GENERIC_SPINLOCK
-	bool
-	default y
-
 config LOCKDEP_SUPPORT
 	bool
 	default y
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-bcm1480.c linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-bcm1480.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-bcm1480.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-bcm1480.c	2009-06-09 23:05:27.000000000 -0400
@@ -144,7 +144,6 @@ void __cpuinit sb1480_clockevent_init(vo
 
 	action->handler	= sibyte_counter_handler;
 	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
-	action->mask	= cpumask_of_cpu(cpu);
 	action->name	= name;
 	action->dev_id	= cd;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-sb1250.c linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-sb1250.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-sb1250.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-sb1250.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,7 +143,6 @@ void __cpuinit sb1250_clockevent_init(vo
 
 	action->handler	= sibyte_counter_handler;
 	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
-	action->mask	= cpumask_of_cpu(cpu);
 	action->name	= name;
 	action->dev_id	= cd;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-smtc.c linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-smtc.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-smtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-smtc.c	2009-06-09 23:05:27.000000000 -0400
@@ -245,7 +245,7 @@ irqreturn_t c0_compare_interrupt(int irq
 }
 
 
-int __cpuinit mips_clockevent_init(void)
+int __cpuinit smtc_clockevent_init(void)
 {
 	uint64_t mips_freq = mips_hpt_frequency;
 	unsigned int cpu = smp_processor_id();
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-txx9.c linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-txx9.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/cevt-txx9.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/cevt-txx9.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
 
 static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
 
-static cycle_t txx9_cs_read(void)
+static cycle_t txx9_cs_read(struct clocksource *cs)
 {
 	return __raw_readl(&txx9_cs_tmrptr->trr);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/cpu-probe.c linux-libre-2.6.30-gnu1/arch/mips/kernel/cpu-probe.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/cpu-probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/cpu-probe.c	2009-06-09 23:05:27.000000000 -0400
@@ -183,13 +183,7 @@ void __init check_wait(void)
 	case CPU_TX49XX:
 		cpu_wait = r4k_wait_irqoff;
 		break;
-	case CPU_AU1000:
-	case CPU_AU1100:
-	case CPU_AU1500:
-	case CPU_AU1550:
-	case CPU_AU1200:
-	case CPU_AU1210:
-	case CPU_AU1250:
+	case CPU_ALCHEMY:
 		cpu_wait = au1k_wait;
 		break;
 	case CPU_20KC:
@@ -783,37 +777,30 @@ static inline void cpu_probe_alchemy(str
 	switch (c->processor_id & 0xff00) {
 	case PRID_IMP_AU1_REV1:
 	case PRID_IMP_AU1_REV2:
+		c->cputype = CPU_ALCHEMY;
 		switch ((c->processor_id >> 24) & 0xff) {
 		case 0:
-			c->cputype = CPU_AU1000;
 			__cpu_name[cpu] = "Au1000";
 			break;
 		case 1:
-			c->cputype = CPU_AU1500;
 			__cpu_name[cpu] = "Au1500";
 			break;
 		case 2:
-			c->cputype = CPU_AU1100;
 			__cpu_name[cpu] = "Au1100";
 			break;
 		case 3:
-			c->cputype = CPU_AU1550;
 			__cpu_name[cpu] = "Au1550";
 			break;
 		case 4:
-			c->cputype = CPU_AU1200;
 			__cpu_name[cpu] = "Au1200";
-			if ((c->processor_id & 0xff) == 2) {
-				c->cputype = CPU_AU1250;
+			if ((c->processor_id & 0xff) == 2)
 				__cpu_name[cpu] = "Au1250";
-			}
 			break;
 		case 5:
-			c->cputype = CPU_AU1210;
 			__cpu_name[cpu] = "Au1210";
 			break;
 		default:
-			panic("Unknown Au Core!");
+			__cpu_name[cpu] = "Au1xxx";
 			break;
 		}
 		break;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-bcm1480.c linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-bcm1480.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-bcm1480.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-bcm1480.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@
 
 #include <asm/sibyte/sb1250.h>
 
-static cycle_t bcm1480_hpt_read(void)
+static cycle_t bcm1480_hpt_read(struct clocksource *cs)
 {
 	return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-ioasic.c linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-ioasic.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-ioasic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-ioasic.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
 #include <asm/dec/ioasic.h>
 #include <asm/dec/ioasic_addrs.h>
 
-static cycle_t dec_ioasic_hpt_read(void)
+static cycle_t dec_ioasic_hpt_read(struct clocksource *cs)
 {
 	return ioasic_read(IO_REG_FCTR);
 }
@@ -47,13 +47,13 @@ void __init dec_ioasic_clocksource_init(
 	while (!ds1287_timer_state())
 		;
 
-	start = dec_ioasic_hpt_read();
+	start = dec_ioasic_hpt_read(&clocksource_dec);
 
 	while (i--)
 		while (!ds1287_timer_state())
 			;
 
-	end = dec_ioasic_hpt_read();
+	end = dec_ioasic_hpt_read(&clocksource_dec);
 
 	freq = (end - start) * 10;
 	printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-r4k.c linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-r4k.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-r4k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-r4k.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@
 
 #include <asm/time.h>
 
-static cycle_t c0_hpt_read(void)
+static cycle_t c0_hpt_read(struct clocksource *cs)
 {
 	return read_c0_count();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-sb1250.c linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-sb1250.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/csrc-sb1250.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/csrc-sb1250.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,7 @@
  * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
  * again.
  */
-static cycle_t sb1250_hpt_read(void)
+static cycle_t sb1250_hpt_read(struct clocksource *cs)
 {
 	unsigned int count;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/i8253.c linux-libre-2.6.30-gnu1/arch/mips/kernel/i8253.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/i8253.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/i8253.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,7 +98,6 @@ static irqreturn_t timer_interrupt(int i
 static struct irqaction irq0  = {
 	.handler = timer_interrupt,
 	.flags = IRQF_DISABLED | IRQF_NOBALANCING,
-	.mask = CPU_MASK_NONE,
 	.name = "timer"
 };
 
@@ -121,7 +120,6 @@ void __init setup_pit_timer(void)
 	cd->min_delta_ns = clockevent_delta2ns(0xF, cd);
 	clockevents_register_device(cd);
 
-	irq0.mask = cpumask_of_cpu(cpu);
 	setup_irq(0, &irq0);
 }
 
@@ -130,7 +128,7 @@ void __init setup_pit_timer(void)
  * to just read by itself. So use jiffies to emulate a free
  * running counter:
  */
-static cycle_t pit_read(void)
+static cycle_t pit_read(struct clocksource *cs)
 {
 	unsigned long flags;
 	int count;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/i8259.c linux-libre-2.6.30-gnu1/arch/mips/kernel/i8259.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/i8259.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/i8259.c	2009-06-09 23:05:27.000000000 -0400
@@ -306,7 +306,6 @@ static void init_8259A(int auto_eoi)
  */
 static struct irqaction irq2 = {
 	.handler = no_action,
-	.mask = CPU_MASK_NONE,
 	.name = "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/irq.c linux-libre-2.6.30-gnu1/arch/mips/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,7 +108,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "  %s", action->name);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/irq_cpu.c linux-libre-2.6.30-gnu1/arch/mips/kernel/irq_cpu.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/irq_cpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/irq_cpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,8 @@ void __init mips_cpu_irq_init(void)
 	 */
 	if (cpu_has_mipsmt)
 		for (i = irq_base; i < irq_base + 2; i++)
-			set_irq_chip(i, &mips_mt_cpu_irq_controller);
+			set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller,
+						 handle_percpu_irq);
 
 	for (i = irq_base + 2; i < irq_base + 8; i++)
 		set_irq_chip_and_handler(i, &mips_cpu_irq_controller,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/irq-gic.c linux-libre-2.6.30-gnu1/arch/mips/kernel/irq-gic.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/irq-gic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/irq-gic.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,7 @@ static void gic_set_affinity(unsigned in
 		set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
 
 	}
-	irq_desc[irq].affinity = *cpumask;
+	cpumask_copy(irq_desc[irq].affinity, cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/irq-msc01.c linux-libre-2.6.30-gnu1/arch/mips/kernel/irq-msc01.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/irq-msc01.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/irq-msc01.c	2009-06-09 23:05:27.000000000 -0400
@@ -140,14 +140,16 @@ void __init init_msc_irqs(unsigned long
 
 		switch (imp->im_type) {
 		case MSC01_IRQ_EDGE:
-			set_irq_chip(irqbase+n, &msc_edgeirq_type);
+			set_irq_chip_and_handler_name(irqbase + n,
+				&msc_edgeirq_type, handle_edge_irq, "edge");
 			if (cpu_has_veic)
 				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
 			else
 				MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
 			break;
 		case MSC01_IRQ_LEVEL:
-			set_irq_chip(irqbase+n, &msc_levelirq_type);
+			set_irq_chip_and_handler_name(irqbase+n,
+				&msc_levelirq_type, handle_level_irq, "level");
 			if (cpu_has_veic)
 				MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
 			else
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/linux32.c linux-libre-2.6.30-gnu1/arch/mips/kernel/linux32.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/linux32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/linux32.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/module.h>
 #include <linux/binfmts.h>
 #include <linux/security.h>
-#include <linux/syscalls.h>
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/ipc.h>
@@ -134,9 +133,9 @@ SYSCALL_DEFINE4(32_ftruncate64, unsigned
 	return sys_ftruncate(fd, merge_64(a2, a3));
 }
 
-SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high,
-	unsigned long, offset_low, loff_t __user *, result,
-	unsigned long, origin)
+SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
+		unsigned int, offset_low, loff_t __user *, result,
+		unsigned int, origin)
 {
 	return sys_llseek(fd, offset_high, offset_low, result, origin);
 }
@@ -356,40 +355,6 @@ SYSCALL_DEFINE1(32_personality, unsigned
 	return ret;
 }
 
-/* ustat compatibility */
-struct ustat32 {
-	compat_daddr_t	f_tfree;
-	compat_ino_t	f_tinode;
-	char		f_fname[6];
-	char		f_fpack[6];
-};
-
-extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
-
-SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32)
-{
-	int err;
-	struct ustat tmp;
-	struct ustat32 tmp32;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	err = sys_ustat(dev, (struct ustat __user *)&tmp);
-	set_fs(old_fs);
-
-	if (err)
-		goto out;
-
-	memset(&tmp32, 0, sizeof(struct ustat32));
-	tmp32.f_tfree = tmp.f_tfree;
-	tmp32.f_tinode = tmp.f_tinode;
-
-	err = copy_to_user(ubuf32, &tmp32, sizeof(struct ustat32)) ? -EFAULT : 0;
-
-out:
-	return err;
-}
-
 SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
 	compat_off_t __user *, offset, s32, count)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/proc.c linux-libre-2.6.30-gnu1/arch/mips/kernel/proc.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ static int show_cpuinfo(struct seq_file
 	seq_printf(m, fmt, __cpu_name[n],
 	                           (version >> 4) & 0x0f, version & 0x0f,
 	                           (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
-	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+	seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
 	              cpu_data[n].udelay_val / (500000/HZ),
 	              (cpu_data[n].udelay_val / (5000/HZ)) % 100);
 	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/process.c linux-libre-2.6.30-gnu1/arch/mips/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,7 +99,7 @@ void flush_thread(void)
 {
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 	unsigned long unused, struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *ti = task_thread_info(p);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/scall32-o32.S linux-libre-2.6.30-gnu1/arch/mips/kernel/scall32-o32.S
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/scall32-o32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/scall32-o32.S	2009-06-09 23:05:27.000000000 -0400
@@ -650,6 +650,8 @@ einval:	li	v0, -ENOSYS
 	sys	sys_dup3		3
 	sys	sys_pipe2		2
 	sys	sys_inotify_init1	1
+	sys	sys_preadv		6	/* 4330 */
+	sys	sys_pwritev		6
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-64.S linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-64.S
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-64.S	2009-06-09 23:05:27.000000000 -0400
@@ -487,4 +487,6 @@ sys_call_table:
 	PTR	sys_dup3
 	PTR	sys_pipe2
 	PTR	sys_inotify_init1
+	PTR	sys_preadv
+	PTR	sys_pwritev			/* 5390 */
 	.size	sys_call_table,.-sys_call_table
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-n32.S linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-n32.S
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-n32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-n32.S	2009-06-09 23:05:27.000000000 -0400
@@ -253,7 +253,7 @@ EXPORT(sysn32_call_table)
 	PTR	compat_sys_utime		/* 6130 */
 	PTR	sys_mknod
 	PTR	sys_32_personality
-	PTR	sys_32_ustat
+	PTR	compat_sys_ustat
 	PTR	compat_sys_statfs
 	PTR	compat_sys_fstatfs		/* 6135 */
 	PTR	sys_sysfs
@@ -405,12 +405,14 @@ EXPORT(sysn32_call_table)
 	PTR	sys_eventfd
 	PTR	sys_fallocate
 	PTR	sys_timerfd_create
-	PTR	sys_timerfd_gettime		/* 5285 */
-	PTR	sys_timerfd_settime
+	PTR	compat_sys_timerfd_gettime	/* 5285 */
+	PTR	compat_sys_timerfd_settime
 	PTR	sys_signalfd4
 	PTR	sys_eventfd2
 	PTR	sys_epoll_create1
 	PTR	sys_dup3			/* 5290 */
 	PTR	sys_pipe2
 	PTR	sys_inotify_init1
+	PTR	sys_preadv
+	PTR	sys_pwritev
 	.size	sysn32_call_table,.-sysn32_call_table
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-o32.S linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-o32.S
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/scall64-o32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/scall64-o32.S	2009-06-09 23:05:27.000000000 -0400
@@ -265,7 +265,7 @@ sys_call_table:
 	PTR	sys_olduname
 	PTR	sys_umask			/* 4060 */
 	PTR	sys_chroot
-	PTR	sys_32_ustat
+	PTR	compat_sys_ustat
 	PTR	sys_dup2
 	PTR	sys_getppid
 	PTR	sys_getpgrp			/* 4065 */
@@ -525,12 +525,14 @@ sys_call_table:
 	PTR	sys_eventfd
 	PTR	sys32_fallocate			/* 4320 */
 	PTR	sys_timerfd_create
-	PTR	sys_timerfd_gettime
-	PTR	sys_timerfd_settime
+	PTR	compat_sys_timerfd_gettime
+	PTR	compat_sys_timerfd_settime
 	PTR	compat_sys_signalfd4
 	PTR	sys_eventfd2			/* 4325 */
 	PTR	sys_epoll_create1
 	PTR	sys_dup3
 	PTR	sys_pipe2
 	PTR	sys_inotify_init1
+	PTR	compat_sys_preadv		/* 4330 */
+	PTR	compat_sys_pwritev
 	.size	sys_call_table,.-sys_call_table
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/setup.c linux-libre-2.6.30-gnu1/arch/mips/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -277,7 +277,8 @@ static void __init bootmem_init(void)
 	 * not selected. Once that done we can determine the low bound
 	 * of usable memory.
 	 */
-	reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end)));
+	reserved_end = max(init_initrd(),
+			   (unsigned long) PFN_UP(__pa_symbol(&_end)));
 
 	/*
 	 * max_low_pfn is not a number of pages. The number of pages
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/smp.c linux-libre-2.6.30-gnu1/arch/mips/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,7 @@
 #include <asm/mipsmtregs.h>
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
+static volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
 int __cpu_number_map[NR_CPUS];		/* Map physical to logical */
 int __cpu_logical_map[NR_CPUS];		/* Map logical to physical */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/smp-up.c linux-libre-2.6.30-gnu1/arch/mips/kernel/smp-up.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/smp-up.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/smp-up.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@
 /*
  * Send inter-processor interrupt
  */
-void up_send_ipi_single(int cpu, unsigned int action)
+static void up_send_ipi_single(int cpu, unsigned int action)
 {
 	panic(KERN_ERR "%s called", __func__);
 }
@@ -27,31 +27,31 @@ static inline void up_send_ipi_mask(cpum
  *  After we've done initial boot, this function is called to allow the
  *  board code to clean up state, if needed
  */
-void __cpuinit up_init_secondary(void)
+static void __cpuinit up_init_secondary(void)
 {
 }
 
-void __cpuinit up_smp_finish(void)
+static void __cpuinit up_smp_finish(void)
 {
 }
 
 /* Hook for after all CPUs are online */
-void up_cpus_done(void)
+static void up_cpus_done(void)
 {
 }
 
 /*
  * Firmware CPU startup hook
  */
-void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
+static void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
 {
 }
 
-void __init up_smp_setup(void)
+static void __init up_smp_setup(void)
 {
 }
 
-void __init up_prepare_cpus(unsigned int max_cpus)
+static void __init up_prepare_cpus(unsigned int max_cpus)
 {
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/smtc.c linux-libre-2.6.30-gnu1/arch/mips/kernel/smtc.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/smtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/smtc.c	2009-06-09 23:05:27.000000000 -0400
@@ -686,7 +686,7 @@ void smtc_forward_irq(unsigned int irq)
 	 * and efficiency, we just pick the easiest one to find.
 	 */
 
-	target = first_cpu(irq_desc[irq].affinity);
+	target = cpumask_first(irq_desc[irq].affinity);
 
 	/*
 	 * We depend on the platform code to have correctly processed
@@ -921,11 +921,13 @@ void ipi_decode(struct smtc_ipi *pipi)
 	struct clock_event_device *cd;
 	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_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++;
+		kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 		cd = &per_cpu(mips_clockevent_device, cpu);
 		cd->event_handler(cd);
 		irq_exit();
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/traps.c linux-libre-2.6.30-gnu1/arch/mips/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -1277,8 +1277,7 @@ static void *set_vi_srs_handler(int n, v
 	u32 *w;
 	unsigned char *b;
 
-	if (!cpu_has_veic && !cpu_has_vint)
-		BUG();
+	BUG_ON(!cpu_has_veic && !cpu_has_vint);
 
 	if (addr == NULL) {
 		handler = (unsigned long) do_default_vi;
@@ -1520,7 +1519,9 @@ void __cpuinit per_cpu_trap_init(void)
 #endif /* CONFIG_MIPS_MT_SMTC */
 
 	if (cpu_has_veic || cpu_has_vint) {
+		unsigned long sr = set_c0_status(ST0_BEV);
 		write_c0_ebase(ebase);
+		write_c0_status(sr);
 		/* Setting vector spacing enables EI/VI mode  */
 		change_c0_intctl(0x3e0, VECTORSPACING);
 	}
@@ -1602,8 +1603,6 @@ void __cpuinit set_uncached_handler(unsi
 #ifdef CONFIG_64BIT
 	unsigned long uncached_ebase = TO_UNCAC(ebase);
 #endif
-	if (cpu_has_mips_r2)
-		uncached_ebase += (read_c0_ebase() & 0x3ffff000);
 
 	if (!addr)
 		panic(panic_null_cerr);
@@ -1635,9 +1634,11 @@ void __init trap_init(void)
 		return;	/* Already done */
 #endif
 
-	if (cpu_has_veic || cpu_has_vint)
-		ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64);
-	else {
+	if (cpu_has_veic || cpu_has_vint) {
+		unsigned long size = 0x200 + VECTORSPACING*64;
+		ebase = (unsigned long)
+			__alloc_bootmem(size, 1 << fls(size), 0);
+	} else {
 		ebase = CAC_BASE;
 		if (cpu_has_mips_r2)
 			ebase += (read_c0_ebase() & 0x3ffff000);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/kernel/unaligned.c linux-libre-2.6.30-gnu1/arch/mips/kernel/unaligned.c
--- linux-libre-2.6.29-gnu1/arch/mips/kernel/unaligned.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/kernel/unaligned.c	2009-06-09 23:05:27.000000000 -0400
@@ -482,19 +482,19 @@ fault:
 		return;
 
 	die_if_kernel("Unhandled kernel unaligned access", regs);
-	send_sig(SIGSEGV, current, 1);
+	force_sig(SIGSEGV, current);
 
 	return;
 
 sigbus:
 	die_if_kernel("Unhandled kernel unaligned access", regs);
-	send_sig(SIGBUS, current, 1);
+	force_sig(SIGBUS, current);
 
 	return;
 
 sigill:
 	die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
-	send_sig(SIGILL, current, 1);
+	force_sig(SIGILL, current);
 }
 
 asmlinkage void do_ade(struct pt_regs *regs)
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/lasat/interrupt.c linux-libre-2.6.30-gnu1/arch/mips/lasat/interrupt.c
--- linux-libre-2.6.29-gnu1/arch/mips/lasat/interrupt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/lasat/interrupt.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,6 @@ asmlinkage void plat_irq_dispatch(void)
 
 static struct irqaction cascade = {
 	.handler	= no_action,
-	.mask		= CPU_MASK_NONE,
 	.name		= "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/lemote/lm2e/irq.c linux-libre-2.6.30-gnu1/arch/mips/lemote/lm2e/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/lemote/lm2e/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/lemote/lm2e/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,7 +92,6 @@ asmlinkage void plat_irq_dispatch(void)
 
 static struct irqaction cascade_irqaction = {
 	.handler = no_action,
-	.mask = CPU_MASK_NONE,
 	.name = "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/lib/delay.c linux-libre-2.6.30-gnu1/arch/mips/lib/delay.c
--- linux-libre-2.6.29-gnu1/arch/mips/lib/delay.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mips/lib/delay.c	2009-06-09 23:05:27.000000000 -0400
@@ -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 by Waldorf Electronics
+ * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007  Maciej W. Rozycki
+ */
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/smp.h>
+
+#include <asm/compiler.h>
+#include <asm/war.h>
+
+inline void __delay(unsigned int loops)
+{
+	__asm__ __volatile__ (
+	"	.set	noreorder				\n"
+	"	.align	3					\n"
+	"1:	bnez	%0, 1b					\n"
+	"	subu	%0, 1					\n"
+	"	.set	reorder					\n"
+	: "=r" (loops)
+	: "0" (loops));
+}
+EXPORT_SYMBOL(__delay);
+
+/*
+ * Division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+void __udelay(unsigned long us)
+{
+	unsigned int lpj = current_cpu_data.udelay_val;
+
+	__delay((us * 0x000010c7 * HZ * lpj) >> 32);
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long ns)
+{
+	unsigned int lpj = current_cpu_data.udelay_val;
+
+	__delay((us * 0x00000005 * HZ * lpj) >> 32);
+}
+EXPORT_SYMBOL(__ndelay);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/lib/dump_tlb.c linux-libre-2.6.30-gnu1/arch/mips/lib/dump_tlb.c
--- linux-libre-2.6.29-gnu1/arch/mips/lib/dump_tlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/lib/dump_tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,15 @@ static inline const char *msk2str(unsign
 	case PM_16K:	return "16kb";
 	case PM_64K:	return "64kb";
 	case PM_256K:	return "256kb";
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+	case PM_8K:	return "8kb";
+	case PM_32K:	return "32kb";
+	case PM_128K:	return "128kb";
+	case PM_512K:	return "512kb";
+	case PM_2M:	return "2Mb";
+	case PM_8M:	return "8Mb";
+	case PM_32M:	return "32Mb";
+#endif
 #ifndef CONFIG_CPU_VR41XX
 	case PM_1M:	return "1Mb";
 	case PM_4M:	return "4Mb";
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/lib/Makefile linux-libre-2.6.30-gnu1/arch/mips/lib/Makefile
--- linux-libre-2.6.29-gnu1/arch/mips/lib/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/lib/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,8 +2,8 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y	+= csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \
-	   strncpy_user.o strnlen_user.o uncached.o
+lib-y	+= csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \
+	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o
 
 obj-y			+= iomap.o
 obj-$(CONFIG_PCI)	+= iomap-pci.o
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/Makefile linux-libre-2.6.30-gnu1/arch/mips/Makefile
--- linux-libre-2.6.29-gnu1/arch/mips/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,8 +14,6 @@
 
 KBUILD_DEFCONFIG := ip22_defconfig
 
-cflags-y := -ffunction-sections
-
 #
 # Select the object file format to substitute into the linker script.
 #
@@ -50,6 +48,9 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
+cflags-y := -ffunction-sections
+cflags-y += $(call cc-option, -mno-check-zero-division)
+
 ifdef CONFIG_32BIT
 ld-emul			= $(32bit-emul)
 vmlinux-32		= vmlinux
@@ -472,12 +473,12 @@ endif
 # Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
 #
 ifdef CONFIG_SGI_IP28
-  ifeq ($(call cc-option-yn,-mr10k-cache-barrier=1), n)
-      $(error gcc doesn't support needed option -mr10k-cache-barrier=1)
+  ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
+      $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
   endif
 endif
 core-$(CONFIG_SGI_IP28)		+= arch/mips/sgi-ip22/
-cflags-$(CONFIG_SGI_IP28)	+= -mr10k-cache-barrier=1 -I$(srctree)/arch/mips/include/asm/mach-ip28
+cflags-$(CONFIG_SGI_IP28)	+= -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
 load-$(CONFIG_SGI_IP28)		+= 0xa800000020004000
 
 #
@@ -720,11 +721,17 @@ ifdef CONFIG_MIPS32_O32
 	$(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32"
 endif
 
+install:
+	$(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(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/lasat
 
 define archhelp
+	echo '  install              - install kernel into $(INSTALL_PATH)'
 	echo '  vmlinux.ecoff        - ECOFF boot image'
 	echo '  vmlinux.bin          - Raw binary boot image'
 	echo '  vmlinux.srec         - SREC boot image'
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/c-r4k.c linux-libre-2.6.30-gnu1/arch/mips/mm/c-r4k.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/c-r4k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/c-r4k.c	2009-06-09 23:05:27.000000000 -0400
@@ -780,7 +780,7 @@ static void __cpuinit probe_pcache(void)
 		c->dcache.ways = 2;
 		c->dcache.waybit = 0;
 
-		c->options |= MIPS_CPU_CACHE_CDEX_P;
+		c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
 		break;
 
 	case CPU_TX49XX:
@@ -1026,13 +1026,7 @@ static void __cpuinit probe_pcache(void)
 		c->icache.flags |= MIPS_CACHE_VTAG;
 		break;
 
-	case CPU_AU1000:
-	case CPU_AU1500:
-	case CPU_AU1100:
-	case CPU_AU1550:
-	case CPU_AU1200:
-	case CPU_AU1210:
-	case CPU_AU1250:
+	case CPU_ALCHEMY:
 		c->icache.flags |= MIPS_CACHE_IC_F_DC;
 		break;
 	}
@@ -1047,7 +1041,7 @@ static void __cpuinit probe_pcache(void)
 
 	printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
 	       icache_size >> 10,
-	       cpu_has_vtag_icache ? "VIVT" : "VIPT",
+	       c->icache.flags & MIPS_CACHE_VTAG ? "VIVT" : "VIPT",
 	       way_string[c->icache.ways], c->icache.linesz);
 
 	printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n",
@@ -1244,7 +1238,7 @@ void au1x00_fixup_config_od(void)
 	/*
 	 * Au1100 errata actually keeps silence about this bit, so we set it
 	 * just in case for those revisions that require it to be set according
-	 * to arch/mips/au1000/common/cputable.c
+	 * to the (now gone) cpu table.
 	 */
 	case 0x02030200: /* Au1100 AB */
 	case 0x02030201: /* Au1100 BA */
@@ -1314,11 +1308,10 @@ static void __cpuinit coherency_setup(vo
 		break;
 	/*
 	 * We need to catch the early Alchemy SOCs with
-	 * the write-only co_config.od bit and set it back to one...
+	 * the write-only co_config.od bit and set it back to one on:
+	 * Au1000 rev DA, HA, HB;  Au1100 AB, BA, BC, Au1500 AB
 	 */
-	case CPU_AU1000: /* rev. DA, HA, HB */
-	case CPU_AU1100: /* rev. AB, BA, BC ?? */
-	case CPU_AU1500: /* rev. AB */
+	case CPU_ALCHEMY:
 		au1x00_fixup_config_od();
 		break;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/dma-default.c linux-libre-2.6.30-gnu1/arch/mips/mm/dma-default.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/dma-default.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/dma-default.c	2009-06-09 23:05:27.000000000 -0400
@@ -209,7 +209,7 @@ dma_addr_t dma_map_page(struct device *d
 		unsigned long addr;
 
 		addr = (unsigned long) page_address(page) + offset;
-		dma_cache_wback_inv(addr, size);
+		__dma_sync(addr, size, direction);
 	}
 
 	return plat_map_dma_mem_page(dev, page) + offset;
@@ -217,23 +217,6 @@ dma_addr_t dma_map_page(struct device *d
 
 EXPORT_SYMBOL(dma_map_page);
 
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-	enum dma_data_direction direction)
-{
-	BUG_ON(direction == DMA_NONE);
-
-	if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) {
-		unsigned long addr;
-
-		addr = plat_dma_addr_to_phys(dma_address);
-		dma_cache_wback_inv(addr, size);
-	}
-
-	plat_unmap_dma_mem(dev, dma_address);
-}
-
-EXPORT_SYMBOL(dma_unmap_page);
-
 void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 	enum dma_data_direction direction)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/highmem.c linux-libre-2.6.30-gnu1/arch/mips/mm/highmem.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/highmem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/highmem.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,12 @@
 #include <linux/module.h>
 #include <linux/highmem.h>
+#include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 
+static pte_t *kmap_pte;
+
+unsigned long highstart_pfn, highend_pfn;
+
 void *__kmap(struct page *page)
 {
 	void *addr;
@@ -14,15 +19,16 @@ void *__kmap(struct page *page)
 
 	return addr;
 }
+EXPORT_SYMBOL(__kmap);
 
 void __kunmap(struct page *page)
 {
-	if (in_interrupt())
-		BUG();
+	BUG_ON(in_interrupt());
 	if (!PageHighMem(page))
 		return;
 	kunmap_high(page);
 }
+EXPORT_SYMBOL(__kunmap);
 
 /*
  * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
@@ -43,17 +49,18 @@ void *__kmap_atomic(struct page *page, e
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
-	if (!pte_none(*(kmap_pte-idx)))
-		BUG();
+	BUG_ON(!pte_none(*(kmap_pte - idx)));
 #endif
-	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+	set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
 	local_flush_tlb_one((unsigned long)vaddr);
 
 	return (void*) vaddr;
 }
+EXPORT_SYMBOL(__kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr, enum km_type type)
 {
@@ -66,8 +73,7 @@ void __kunmap_atomic(void *kvaddr, enum
 		return;
 	}
 
-	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
-		BUG();
+	BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 
 	/*
 	 * force other mappings to Oops if they'll try to access
@@ -79,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum
 
 	pagefault_enable();
 }
+EXPORT_SYMBOL(__kunmap_atomic);
 
 /*
  * This is the same as kmap_atomic() but can map memory that doesn't
@@ -91,9 +98,10 @@ void *kmap_atomic_pfn(unsigned long pfn,
 
 	pagefault_disable();
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+	set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
 	flush_tlb_one(vaddr);
 
 	return (void*) vaddr;
@@ -112,7 +120,11 @@ struct page *__kmap_atomic_to_page(void
 	return pte_page(*pte);
 }
 
-EXPORT_SYMBOL(__kmap);
-EXPORT_SYMBOL(__kunmap);
-EXPORT_SYMBOL(__kmap_atomic);
-EXPORT_SYMBOL(__kunmap_atomic);
+void __init kmap_init(void)
+{
+	unsigned long kmap_vstart;
+
+	/* cache the first kmap pte */
+	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/init.c linux-libre-2.6.30-gnu1/arch/mips/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,14 +104,6 @@ unsigned long setup_zero_pages(void)
 	return 1UL << order;
 }
 
-/*
- * These are almost like kmap_atomic / kunmap_atmic except they take an
- * additional address argument as the hint.
- */
-
-#define kmap_get_fixmap_pte(vaddr)					\
-	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
-
 #ifdef CONFIG_MIPS_MT_SMTC
 static pte_t *kmap_coherent_pte;
 static void __init kmap_coherent_init(void)
@@ -264,24 +256,6 @@ void copy_from_user_page(struct vm_area_
 	}
 }
 
-#ifdef CONFIG_HIGHMEM
-unsigned long highstart_pfn, highend_pfn;
-
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
-
-static void __init kmap_init(void)
-{
-	unsigned long kmap_vstart;
-
-	/* cache the first kmap pte */
-	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-
-	kmap_prot = PAGE_KERNEL;
-}
-#endif /* CONFIG_HIGHMEM */
-
 void __init fixrange_init(unsigned long start, unsigned long end,
 	pgd_t *pgd_base)
 {
@@ -307,8 +281,7 @@ void __init fixrange_init(unsigned long
 				if (pmd_none(*pmd)) {
 					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
 					set_pmd(pmd, __pmd((unsigned long)pte));
-					if (pte != pte_offset_kernel(pmd, 0))
-						BUG();
+					BUG_ON(pte != pte_offset_kernel(pmd, 0));
 				}
 				vaddr += PMD_SIZE;
 			}
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/ioremap.c linux-libre-2.6.30-gnu1/arch/mips/mm/ioremap.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/ioremap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/ioremap.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,8 +27,7 @@ static inline void remap_area_pte(pte_t
 	end = address + size;
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	pfn = phys_addr >> PAGE_SHIFT;
 	do {
 		if (!pte_none(*pte)) {
@@ -52,8 +51,7 @@ static inline int remap_area_pmd(pmd_t *
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
 	phys_addr -= address;
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	do {
 		pte_t * pte = pte_alloc_kernel(pmd, address);
 		if (!pte)
@@ -75,8 +73,7 @@ static int remap_area_pages(unsigned lon
 	phys_addr -= address;
 	dir = pgd_offset(&init_mm, address);
 	flush_cache_all();
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	do {
 		pud_t *pud;
 		pmd_t *pmd;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/sc-rm7k.c linux-libre-2.6.30-gnu1/arch/mips/mm/sc-rm7k.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/sc-rm7k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/sc-rm7k.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@ extern unsigned long icache_way_size, dc
 
 #include <asm/r4kcache.h>
 
-int rm7k_tcache_enabled;
+static int rm7k_tcache_enabled;
 
 /*
  * Writeback and invalidate the primary cache dcache before DMA.
@@ -121,7 +121,7 @@ static void rm7k_sc_disable(void)
 	clear_c0_config(RM7K_CONF_SE);
 }
 
-struct bcache_ops rm7k_sc_ops = {
+static struct bcache_ops rm7k_sc_ops = {
 	.bc_enable = rm7k_sc_enable,
 	.bc_disable = rm7k_sc_disable,
 	.bc_wback_inv = rm7k_sc_wback_inv,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/tlbex.c linux-libre-2.6.30-gnu1/arch/mips/mm/tlbex.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/tlbex.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/tlbex.c	2009-06-09 23:05:27.000000000 -0400
@@ -292,13 +292,6 @@ static void __cpuinit build_tlb_write_en
 	case CPU_R4300:
 	case CPU_5KC:
 	case CPU_TX49XX:
-	case CPU_AU1000:
-	case CPU_AU1100:
-	case CPU_AU1500:
-	case CPU_AU1550:
-	case CPU_AU1200:
-	case CPU_AU1210:
-	case CPU_AU1250:
 	case CPU_PR4450:
 		uasm_i_nop(p);
 		tlbw(p);
@@ -321,6 +314,7 @@ static void __cpuinit build_tlb_write_en
 	case CPU_R5500:
 		if (m4kc_tlbp_war())
 			uasm_i_nop(p);
+	case CPU_ALCHEMY:
 		tlbw(p);
 		break;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r3k.c linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r3k.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r3k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r3k.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,8 +82,7 @@ void local_flush_tlb_range(struct vm_are
 	int cpu = smp_processor_id();
 
 	if (cpu_context(cpu, mm) != 0) {
-		unsigned long flags;
-		int size;
+		unsigned long size, flags;
 
 #ifdef DEBUG_TLB
 		printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
@@ -121,8 +120,7 @@ void local_flush_tlb_range(struct vm_are
 
 void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
-	unsigned long flags;
-	int size;
+	unsigned long size, flags;
 
 #ifdef DEBUG_TLB
 	printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r4k.c linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r4k.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r4k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r4k.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,8 +117,7 @@ void local_flush_tlb_range(struct vm_are
 	int cpu = smp_processor_id();
 
 	if (cpu_context(cpu, mm) != 0) {
-		unsigned long flags;
-		int size;
+		unsigned long size, flags;
 
 		ENTER_CRITICAL(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
@@ -160,8 +159,7 @@ void local_flush_tlb_range(struct vm_are
 
 void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
-	unsigned long flags;
-	int size;
+	unsigned long size, flags;
 
 	ENTER_CRITICAL(flags);
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r8k.c linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r8k.c
--- linux-libre-2.6.29-gnu1/arch/mips/mm/tlb-r8k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mm/tlb-r8k.c	2009-06-09 23:05:27.000000000 -0400
@@ -111,8 +111,7 @@ out_restore:
 /* Usable for KV1 addresses only! */
 void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
-	unsigned long flags;
-	int size;
+	unsigned long size, flags;
 
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 	size = (size + 1) >> 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mti-malta/malta-init.c linux-libre-2.6.30-gnu1/arch/mips/mti-malta/malta-init.c
--- linux-libre-2.6.29-gnu1/arch/mips/mti-malta/malta-init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mti-malta/malta-init.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,7 +48,7 @@ int *_prom_argv, *_prom_envp;
 
 int init_debug = 0;
 
-int mips_revision_corid;
+static int mips_revision_corid;
 int mips_revision_sconid;
 
 /* Bonito64 system controller register base. */
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/mti-malta/malta-smtc.c linux-libre-2.6.30-gnu1/arch/mips/mti-malta/malta-smtc.c
--- linux-libre-2.6.29-gnu1/arch/mips/mti-malta/malta-smtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/mti-malta/malta-smtc.c	2009-06-09 23:05:27.000000000 -0400
@@ -116,7 +116,7 @@ struct plat_smp_ops msmtc_smp_ops = {
 
 void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
 {
-	cpumask_t tmask = *affinity;
+	cpumask_t tmask;
 	int cpu = 0;
 	void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);
 
@@ -139,11 +139,12 @@ void plat_set_irq_affinity(unsigned int
 	 * be made to forward to an offline "CPU".
 	 */
 
+	cpumask_copy(&tmask, affinity);
 	for_each_cpu(cpu, affinity) {
 		if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
 			cpu_clear(cpu, tmask);
 	}
-	irq_desc[irq].affinity = tmask;
+	cpumask_copy(irq_desc[irq].affinity, &tmask);
 
 	if (cpus_empty(tmask))
 		/*
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx833x/common/platform.c linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx833x/common/platform.c
--- linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx833x/common/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx833x/common/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@
 #include <irq-mapping.h>
 #include <pnx833x.h>
 
-static u64 uart_dmamask     = DMA_32BIT_MASK;
+static u64 uart_dmamask     = DMA_BIT_MASK(32);
 
 static struct resource pnx833x_uart_resources[] = {
 	[0] = {
@@ -101,14 +101,14 @@ static struct platform_device pnx833x_ua
 	.id		= -1,
 	.dev = {
 		.dma_mask		= &uart_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.platform_data		= pnx8xxx_ports,
 	},
 	.num_resources	= ARRAY_SIZE(pnx833x_uart_resources),
 	.resource	= pnx833x_uart_resources,
 };
 
-static u64 ehci_dmamask     = DMA_32BIT_MASK;
+static u64 ehci_dmamask     = DMA_BIT_MASK(32);
 
 static struct resource pnx833x_usb_ehci_resources[] = {
 	[0] = {
@@ -128,7 +128,7 @@ static struct platform_device pnx833x_us
 	.id		= -1,
 	.dev = {
 		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(pnx833x_usb_ehci_resources),
 	.resource	= pnx833x_usb_ehci_resources,
@@ -198,7 +198,7 @@ static struct platform_device pnx833x_i2
 };
 #endif
 
-static u64 ethernet_dmamask = DMA_32BIT_MASK;
+static u64 ethernet_dmamask = DMA_BIT_MASK(32);
 
 static struct resource pnx833x_ethernet_resources[] = {
 	[0] = {
@@ -218,7 +218,7 @@ static struct platform_device pnx833x_et
 	.id   = -1,
 	.dev  = {
 		.dma_mask          = &ethernet_dmamask,
-		.coherent_dma_mask = DMA_32BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.num_resources = ARRAY_SIZE(pnx833x_ethernet_resources),
 	.resource      = pnx833x_ethernet_resources,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx8550/common/platform.c linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx8550/common/platform.c
--- linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx8550/common/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx8550/common/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,16 +92,16 @@ struct pnx8xxx_port pnx8xxx_ports[] = {
 };
 
 /* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = DMA_32BIT_MASK;
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
 
-static u64 uart_dmamask = DMA_32BIT_MASK;
+static u64 uart_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device pnx8550_usb_ohci_device = {
 	.name		= "pnx8550-ohci",
 	.id		= -1,
 	.dev = {
 		.dma_mask		= &ohci_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(pnx8550_usb_ohci_resources),
 	.resource	= pnx8550_usb_ohci_resources,
@@ -112,7 +112,7 @@ static struct platform_device pnx8550_ua
 	.id		= -1,
 	.dev = {
 		.dma_mask		= &uart_dmamask,
-		.coherent_dma_mask	= DMA_32BIT_MASK,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 		.platform_data = pnx8xxx_ports,
 	},
 	.num_resources	= ARRAY_SIZE(pnx8550_uart_resources),
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx8550/common/time.c linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx8550/common/time.c
--- linux-libre-2.6.29-gnu1/arch/mips/nxp/pnx8550/common/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/nxp/pnx8550/common/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,7 @@
 
 static unsigned long cpj;
 
-static cycle_t hpt_read(void)
+static cycle_t hpt_read(struct clocksource *cs)
 {
 	return read_c0_count2();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/Kconfig linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -36,18 +36,6 @@ config PMC_MSP7120_FPGA
 
 endchoice
 
-menu "Options for PMC-Sierra MSP chipsets"
-	depends on PMC_MSP
-
-config PMC_MSP_EMBEDDED_ROOTFS
-	bool "Root filesystem embedded in kernel image"
-	select MTD
-	select MTD_BLOCK
-	select MTD_PMC_MSP_RAMROOT
-	select MTD_RAM
-
-endmenu
-
 config HYPERTRANSPORT
 	bool "Hypertransport Support for PMC-Sierra Yosemite"
 	depends on PMC_YOSEMITE
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c
--- linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_prom.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,12 +40,6 @@
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
-#ifdef CONFIG_CRAMFS
-#include <linux/cramfs_fs.h>
-#endif
-#ifdef CONFIG_SQUASHFS
-#include <linux/squashfs_fs.h>
-#endif
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -435,10 +429,6 @@ struct prom_pmemblock *__init prom_getmd
 	char		*str;
 	unsigned int	memsize;
 	unsigned int	heaptop;
-#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
-	void		*ramroot_start;
-	unsigned long	ramroot_size;
-#endif
 	int i;
 
 	str = prom_getenv(memsz_env);
@@ -506,19 +496,7 @@ struct prom_pmemblock *__init prom_getmd
 	i++;			/* 3 */
 	mdesc[i].type = BOOT_MEM_RESERVED;
 	mdesc[i].base = CPHYSADDR((u32)_text);
-#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
-	if (get_ramroot(&ramroot_start, &ramroot_size)) {
-		/*
-		 * Rootfs in RAM -- follows kernel
-		 * Combine rootfs image with kernel block so a
-		 * page (4k) isn't wasted between memory blocks
-		 */
-		mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
-			(u32)ramroot_start + ramroot_size)) - mdesc[i].base;
-	} else
-#endif
-		mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
-			(u32)_end)) - mdesc[i].base;
+	mdesc[i].size = CPHYSADDR(PAGE_ALIGN((u32)_end)) - mdesc[i].base;
 
 	/* Remainder of RAM -- under memsize */
 	i++;			/* 5 */
@@ -528,39 +506,3 @@ struct prom_pmemblock *__init prom_getmd
 
 	return &mdesc[0];
 }
-
-/* rootfs functions */
-#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
-bool get_ramroot(void **start, unsigned long *size)
-{
-	extern char _end[];
-
-	/* Check for start following the end of the kernel */
-	void *check_start = (void *)_end;
-
-	/* Check for supported rootfs types */
-#ifdef CONFIG_CRAMFS
-	if (*(__u32 *)check_start == CRAMFS_MAGIC) {
-		/* Get CRAMFS size */
-		*start = check_start;
-		*size = PAGE_ALIGN(((struct cramfs_super *)
-				   check_start)->size);
-
-		return true;
-	}
-#endif
-#ifdef CONFIG_SQUASHFS
-	if (*((unsigned int *)check_start) == SQUASHFS_MAGIC) {
-		/* Get SQUASHFS size */
-		*start = check_start;
-		*size = PAGE_ALIGN(((struct squashfs_super_block *)
-				   check_start)->bytes_used);
-
-		return true;
-	}
-#endif
-
-	return false;
-}
-EXPORT_SYMBOL(get_ramroot);
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_setup.c linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,6 @@
 
 #if defined(CONFIG_PMC_MSP7120_GW)
 #include <msp_regops.h>
-#include <msp_gpio.h>
 #define MSP_BOARD_RESET_GPIO	9
 #endif
 
@@ -88,11 +87,8 @@ void msp7120_reset(void)
 	 * as GPIO char driver may not be enabled and it would look up
 	 * data inRAM!
 	 */
-	set_value_reg32(GPIO_CFG3_REG,
-			basic_mode_mask(MSP_BOARD_RESET_GPIO),
-			basic_mode(MSP_GPIO_OUTPUT, MSP_BOARD_RESET_GPIO));
-	set_reg32(GPIO_DATA3_REG,
-			basic_data_mask(MSP_BOARD_RESET_GPIO));
+	set_value_reg32(GPIO_CFG3_REG, 0xf000, 0x8000);
+	set_reg32(GPIO_DATA3_REG, 8);
 
 	/*
 	 * In case GPIO9 doesn't reset the board (jumper configurable!)
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_time.c linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_time.c
--- linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_time.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,10 +81,7 @@ void __init plat_time_init(void)
 	mips_hpt_frequency = cpu_rate/2;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
+unsigned int __init get_c0_compare_int(void)
 {
-#ifdef CONFIG_IRQ_MSP_CIC
-	/* we are using the vpe0 counter for timer interrupts */
-	setup_irq(MSP_INT_VPE0_TIMER, irq);
-#endif
+	return MSP_INT_VPE0_TIMER;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_usb.c linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_usb.c
--- linux-libre-2.6.29-gnu1/arch/mips/pmc-sierra/msp71xx/msp_usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/pmc-sierra/msp71xx/msp_usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,14 +49,14 @@ static struct resource msp_usbhost_resou
 	},
 };
 
-static u64 msp_usbhost_dma_mask = DMA_32BIT_MASK;
+static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32);
 
 static struct platform_device msp_usbhost_device = {
 	.name	= "pmcmsp-ehci",
 	.id	= 0,
 	.dev	= {
 		.dma_mask = &msp_usbhost_dma_mask,
-		.coherent_dma_mask = DMA_32BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.num_resources 	= ARRAY_SIZE(msp_usbhost_resources),
 	.resource	= msp_usbhost_resources,
@@ -77,14 +77,14 @@ static struct resource msp_usbdev_resour
 	},
 };
 
-static u64 msp_usbdev_dma_mask = DMA_32BIT_MASK;
+static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32);
 
 static struct platform_device msp_usbdev_device = {
 	.name	= "msp71xx_udc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask = &msp_usbdev_dma_mask,
-		.coherent_dma_mask = DMA_32BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(msp_usbdev_resources),
 	.resource	= msp_usbdev_resources,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/rb532/devices.c linux-libre-2.6.30-gnu1/arch/mips/rb532/devices.c
--- linux-libre-2.6.29-gnu1/arch/mips/rb532/devices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/rb532/devices.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,26 +200,9 @@ static struct platform_device rb532_led
 	.id = -1,
 };
 
-static struct gpio_keys_button rb532_gpio_btn[] = {
-	{
-		.gpio = 1,
-		.code = BTN_0,
-		.desc = "S1",
-		.active_low = 1,
-	}
-};
-
-static struct gpio_keys_platform_data rb532_gpio_btn_data = {
-	.buttons = rb532_gpio_btn,
-	.nbuttons = ARRAY_SIZE(rb532_gpio_btn),
-};
-
 static struct platform_device rb532_button = {
-	.name 	= "gpio-keys",
+	.name	= "rb532-button",
 	.id	= -1,
-	.dev	= {
-		.platform_data = &rb532_gpio_btn_data,
-	}
 };
 
 static struct resource rb532_wdt_res[] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-int.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-int.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-int.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-int.c	2009-06-09 23:05:27.000000000 -0400
@@ -155,7 +155,7 @@ static void indy_buserror_irq(void)
 	int irq = SGI_BUSERR_IRQ;
 
 	irq_enter();
-	kstat_this_cpu.irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 	ip22_be_interrupt(irq);
 	irq_exit();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-reset.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-reset.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-reset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-reset.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,7 +148,7 @@ static irqreturn_t panel_int(int irq, vo
 
 	if (sgint->istat1 & SGINT_ISTAT1_PWR) {
 		/* Wait until interrupt goes away */
-		disable_irq(SGI_PANEL_IRQ);
+		disable_irq_nosync(SGI_PANEL_IRQ);
 		init_timer(&debounce_timer);
 		debounce_timer.function = debounce;
 		debounce_timer.expires = jiffies + 5;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-time.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-time.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip22/ip22-time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip22/ip22-time.c	2009-06-09 23:05:27.000000000 -0400
@@ -122,7 +122,7 @@ void indy_8254timer_irq(void)
 	char c;
 
 	irq_enter();
-	kstat_this_cpu.irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 	printk(KERN_ALERT "Oops, got 8254 interrupt.\n");
 	ArcRead(0, &c, 1, &cnt);
 	ArcEnterInteractiveMode();
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-berr.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-berr.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-berr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-berr.c	2009-06-09 23:05:27.000000000 -0400
@@ -66,7 +66,7 @@ int ip27_be_handler(struct pt_regs *regs
 	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
 	       regs->cp0_epc);
 	printk("Hub information:\n");
-	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+	printk("ERR_INT_PEND = 0x%06llx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
 	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
 	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
 	dump_hub_information(errst0, errst1);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-nmi.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-nmi.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-nmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-nmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,8 +143,8 @@ void nmi_dump_hub_irq(nasid_t nasid, int
 	pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
 	pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
 
-	printk("PI_INT_MASK0: %16lx PI_INT_MASK1: %16lx\n", mask0, mask1);
-	printk("PI_INT_PEND0: %16lx PI_INT_PEND1: %16lx\n", pend0, pend1);
+	printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1);
+	printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1);
 	printk("\n\n");
 }
 
@@ -219,7 +219,7 @@ cont_nmi_dump(void)
 		if (i == 1000) {
 			for_each_online_node(node)
 				if (NODEPDA(node)->dump_count == 0) {
-					cpu = node_to_first_cpu(node);
+					cpu = cpumask_first(cpumask_of_node(node));
 					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
 						CPUMASK_SETB(nmied_cpus, cpu);
 						/*
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-smp.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-smp.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -221,7 +221,7 @@ static void __init ip27_smp_setup(void)
 	 * Assumption to be fixed: we're always booted on logical / physical
 	 * processor 0.  While we're always running on logical processor 0
 	 * this still means this is physical processor zero; it might for
-	 * example be disabled in the firwware.
+	 * example be disabled in the firmware.
 	 */
 	alloc_cpupda(0, 0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-timer.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-timer.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip27/ip27-timer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip27/ip27-timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,7 +159,7 @@ static void __init hub_rt_clock_event_gl
 	setup_irq(irq, &hub_rt_irqaction);
 }
 
-static cycle_t hub_rt_read(void)
+static cycle_t hub_rt_read(struct clocksource *cs)
 {
 	return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-berr.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-berr.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-berr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-berr.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #include <asm/ptrace.h>
 #include <asm/tlbdebug.h>
 
-int ip32_be_handler(struct pt_regs *regs, int is_fixup)
+static int ip32_be_handler(struct pt_regs *regs, int is_fixup)
 {
 	int data = regs->cp0_cause & 4;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-irq.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,17 +112,15 @@ static void inline flush_mace_bus(void)
 extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
 extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
 
-struct irqaction memerr_irq = {
+static struct irqaction memerr_irq = {
 	.handler = crime_memerr_intr,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "CRIME memory error",
 };
 
-struct irqaction cpuerr_irq = {
+static struct irqaction cpuerr_irq = {
 	.handler = crime_cpuerr_intr,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "CRIME CPU error",
 };
 
@@ -325,16 +323,11 @@ static void mask_and_ack_maceisa_irq(uns
 {
 	unsigned long mace_int;
 
-	switch (irq) {
-	case MACEISA_PARALLEL_IRQ:
-	case MACEISA_SERIAL1_TDMAPR_IRQ:
-	case MACEISA_SERIAL2_TDMAPR_IRQ:
-		/* edge triggered */
-		mace_int = mace->perif.ctrl.istat;
-		mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
-		mace->perif.ctrl.istat = mace_int;
-		break;
-	}
+	/* edge triggered */
+	mace_int = mace->perif.ctrl.istat;
+	mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
+	mace->perif.ctrl.istat = mace_int;
+
 	disable_maceisa_irq(irq);
 }
 
@@ -344,7 +337,16 @@ static void end_maceisa_irq(unsigned irq
 		enable_maceisa_irq(irq);
 }
 
-static struct irq_chip ip32_maceisa_interrupt = {
+static struct irq_chip ip32_maceisa_level_interrupt = {
+	.name		= "IP32 MACE ISA",
+	.ack		= disable_maceisa_irq,
+	.mask		= disable_maceisa_irq,
+	.mask_ack	= disable_maceisa_irq,
+	.unmask		= enable_maceisa_irq,
+	.end		= end_maceisa_irq,
+};
+
+static struct irq_chip ip32_maceisa_edge_interrupt = {
 	.name		= "IP32 MACE ISA",
 	.ack		= mask_and_ack_maceisa_irq,
 	.mask		= disable_maceisa_irq,
@@ -500,27 +502,50 @@ void __init arch_init_irq(void)
 	for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
 		switch (irq) {
 		case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
-			set_irq_chip(irq, &ip32_mace_interrupt);
+			set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt,
+				handle_level_irq, "level");
 			break;
+
 		case MACEPCI_SCSI0_IRQ ...  MACEPCI_SHARED2_IRQ:
-			set_irq_chip(irq, &ip32_macepci_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&ip32_macepci_interrupt, handle_level_irq,
+				"level");
 			break;
+
 		case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
-			set_irq_chip(irq, &crime_edge_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&crime_edge_interrupt, handle_edge_irq, "edge");
 			break;
 		case CRIME_CPUERR_IRQ:
 		case CRIME_MEMERR_IRQ:
-			set_irq_chip(irq, &crime_level_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&crime_level_interrupt, handle_level_irq,
+				"level");
 			break;
+
 		case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
 		case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
-			set_irq_chip(irq, &crime_edge_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&crime_edge_interrupt, handle_edge_irq, "edge");
 			break;
+
 		case CRIME_VICE_IRQ:
-			set_irq_chip(irq, &crime_edge_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&crime_edge_interrupt, handle_edge_irq, "edge");
 			break;
+
+		case MACEISA_PARALLEL_IRQ:
+		case MACEISA_SERIAL1_TDMAPR_IRQ:
+		case MACEISA_SERIAL2_TDMAPR_IRQ:
+			set_irq_chip_and_handler_name(irq,
+				&ip32_maceisa_edge_interrupt, handle_edge_irq,
+				"edge");
+			break;
+
 		default:
-			set_irq_chip(irq, &ip32_maceisa_interrupt);
+			set_irq_chip_and_handler_name(irq,
+				&ip32_maceisa_level_interrupt, handle_level_irq,
+				"level");
 			break;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-memory.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-memory.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-memory.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-memory.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,7 @@ void __init prom_meminit(void)
 		if (base + size > (256 << 20))
 			base += CRIME_HI_MEM_BASE;
 
-		printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
+		printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n",
 			bank, base, size >> 20);
 		add_memory_region(base, size, BOOT_MEM_RAM);
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-reset.c linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-reset.c
--- linux-libre-2.6.29-gnu1/arch/mips/sgi-ip32/ip32-reset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sgi-ip32/ip32-reset.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,7 +53,7 @@ static inline void ip32_machine_halt(voi
 
 static void ip32_machine_power_off(void)
 {
-	volatile unsigned char reg_a, xctrl_a, xctrl_b;
+	unsigned char reg_a, xctrl_a, xctrl_b;
 
 	disable_irq(MACEISA_RTC_IRQ);
 	reg_a = CMOS_READ(RTC_REG_A);
@@ -91,9 +91,10 @@ static void blink_timeout(unsigned long
 
 static void debounce(unsigned long data)
 {
-	volatile unsigned char reg_a, reg_c, xctrl_a;
+	unsigned char reg_a, reg_c, xctrl_a;
 
 	reg_c = CMOS_READ(RTC_INTR_FLAGS);
+	reg_a = CMOS_READ(RTC_REG_A);
 	CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
 	wbflush();
 	xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
@@ -137,7 +138,7 @@ static inline void ip32_power_button(voi
 
 static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
 {
-	volatile unsigned char reg_c;
+	unsigned char reg_c;
 
 	reg_c = CMOS_READ(RTC_INTR_FLAGS);
 	if (!(reg_c & RTC_IRQF)) {
@@ -145,7 +146,7 @@ static irqreturn_t ip32_rtc_int(int irq,
 			"%s: RTC IRQ without RTC_IRQF\n", __func__);
 	}
 	/* Wait until interrupt goes away */
-	disable_irq(MACEISA_RTC_IRQ);
+	disable_irq_nosync(MACEISA_RTC_IRQ);
 	init_timer(&debounce_timer);
 	debounce_timer.function = debounce;
 	debounce_timer.expires = jiffies + 50;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sibyte/bcm1480/irq.c linux-libre-2.6.30-gnu1/arch/mips/sibyte/bcm1480/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/sibyte/bcm1480/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sibyte/bcm1480/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,6 @@ static void bcm1480_set_affinity(unsigne
 {
 	int i = 0, old_cpu, cpu, int_on, k;
 	u64 cur_ints;
-	struct irq_desc *desc = irq_desc + irq;
 	unsigned long flags;
 	unsigned int irq_dirty;
 
@@ -127,8 +126,7 @@ static void bcm1480_set_affinity(unsigne
 	cpu = cpu_logical_map(i);
 
 	/* Protect against other affinity changers and IMR manipulation */
-	spin_lock_irqsave(&desc->lock, flags);
-	spin_lock(&bcm1480_imr_lock);
+	spin_lock_irqsave(&bcm1480_imr_lock, flags);
 
 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
 	old_cpu = bcm1480_irq_owner[irq];
@@ -153,8 +151,7 @@ static void bcm1480_set_affinity(unsigne
 			____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
 		}
 	}
-	spin_unlock(&bcm1480_imr_lock);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
 }
 #endif
 
@@ -236,7 +233,7 @@ void __init init_bcm1480_irqs(void)
 	int i;
 
 	for (i = 0; i < BCM1480_NR_IRQS; i++) {
-		set_irq_chip(i, &bcm1480_irq_type);
+		set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq);
 		bcm1480_irq_owner[i] = 0;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sibyte/bcm1480/smp.c linux-libre-2.6.30-gnu1/arch/mips/sibyte/bcm1480/smp.c
--- linux-libre-2.6.29-gnu1/arch/mips/sibyte/bcm1480/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sibyte/bcm1480/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -178,9 +178,10 @@ struct plat_smp_ops bcm1480_smp_ops = {
 void bcm1480_mailbox_interrupt(void)
 {
 	int cpu = smp_processor_id();
+	int irq = K_BCM1480_INT_MBOX_0_0;
 	unsigned int action;
 
-	kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++;
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 	/* Load the mailbox register to figure out what we're supposed to do */
 	action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sibyte/cfe/setup.c linux-libre-2.6.30-gnu1/arch/mips/sibyte/cfe/setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/sibyte/cfe/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sibyte/cfe/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -288,13 +288,7 @@ void __init prom_init(void)
 	 */
 	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
 	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) {
-		if (argc < 0) {
-			/*
-			 * It's OK for direct boot to not provide a
-			 *  command line
-			 */
-			strcpy(arcs_cmdline, "root=/dev/ram0 ");
-		} else {
+		if (argc >= 0) {
 			/* The loader should have set the command line */
 			/* too early for panic to do any good */
 			printk("LINUX_CMDLINE not defined in cfe.");
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sibyte/sb1250/irq.c linux-libre-2.6.30-gnu1/arch/mips/sibyte/sb1250/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/sibyte/sb1250/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sibyte/sb1250/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,7 +107,6 @@ static void sb1250_set_affinity(unsigned
 {
 	int i = 0, old_cpu, cpu, int_on;
 	u64 cur_ints;
-	struct irq_desc *desc = irq_desc + irq;
 	unsigned long flags;
 
 	i = cpumask_first(mask);
@@ -121,8 +120,7 @@ static void sb1250_set_affinity(unsigned
 	cpu = cpu_logical_map(i);
 
 	/* Protect against other affinity changers and IMR manipulation */
-	spin_lock_irqsave(&desc->lock, flags);
-	spin_lock(&sb1250_imr_lock);
+	spin_lock_irqsave(&sb1250_imr_lock, flags);
 
 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
 	old_cpu = sb1250_irq_owner[irq];
@@ -144,8 +142,7 @@ static void sb1250_set_affinity(unsigned
 		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
 					R_IMR_INTERRUPT_MASK));
 	}
-	spin_unlock(&sb1250_imr_lock);
-	spin_unlock_irqrestore(&desc->lock, flags);
+	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
 }
 #endif
 
@@ -220,7 +217,7 @@ void __init init_sb1250_irqs(void)
 	int i;
 
 	for (i = 0; i < SB1250_NR_IRQS; i++) {
-		set_irq_chip(i, &sb1250_irq_type);
+		set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq);
 		sb1250_irq_owner[i] = 0;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sibyte/sb1250/smp.c linux-libre-2.6.30-gnu1/arch/mips/sibyte/sb1250/smp.c
--- linux-libre-2.6.29-gnu1/arch/mips/sibyte/sb1250/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sibyte/sb1250/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -166,9 +166,10 @@ struct plat_smp_ops sb_smp_ops = {
 void sb1250_mailbox_interrupt(void)
 {
 	int cpu = smp_processor_id();
+	int irq = K_INT_MBOX_0;
 	unsigned int action;
 
-	kstat_this_cpu.irqs[K_INT_MBOX_0]++;
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 	/* Load the mailbox register to figure out what we're supposed to do */
 	action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sni/a20r.c linux-libre-2.6.30-gnu1/arch/mips/sni/a20r.c
--- linux-libre-2.6.29-gnu1/arch/mips/sni/a20r.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sni/a20r.c	2009-06-09 23:05:27.000000000 -0400
@@ -219,7 +219,7 @@ void __init sni_a20r_irq_init(void)
 	int i;
 
 	for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
-		set_irq_chip(i, &a20r_irq_type);
+		set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq);
 	sni_hwint = a20r_hwint;
 	change_c0_status(ST0_IM, IE_IRQ0);
 	setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sni/pcimt.c linux-libre-2.6.30-gnu1/arch/mips/sni/pcimt.c
--- linux-libre-2.6.29-gnu1/arch/mips/sni/pcimt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sni/pcimt.c	2009-06-09 23:05:27.000000000 -0400
@@ -304,7 +304,7 @@ void __init sni_pcimt_irq_init(void)
 	mips_cpu_irq_init();
 	/* Actually we've got more interrupts to handle ...  */
 	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
-		set_irq_chip(i, &pcimt_irq_type);
+		set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
 	sni_hwint = sni_pcimt_hwint;
 	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sni/pcit.c linux-libre-2.6.30-gnu1/arch/mips/sni/pcit.c
--- linux-libre-2.6.29-gnu1/arch/mips/sni/pcit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sni/pcit.c	2009-06-09 23:05:27.000000000 -0400
@@ -246,7 +246,7 @@ void __init sni_pcit_irq_init(void)
 
 	mips_cpu_irq_init();
 	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
-		set_irq_chip(i, &pcit_irq_type);
+		set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
 	*(volatile u32 *)SNI_PCIT_INT_REG = 0;
 	sni_hwint = sni_pcit_hwint;
 	change_c0_status(ST0_IM, IE_IRQ1);
@@ -259,7 +259,7 @@ void __init sni_pcit_cplus_irq_init(void
 
 	mips_cpu_irq_init();
 	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
-		set_irq_chip(i, &pcit_irq_type);
+		set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
 	*(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
 	sni_hwint = sni_pcit_hwint_cplus;
 	change_c0_status(ST0_IM, IE_IRQ0);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/sni/rm200.c linux-libre-2.6.30-gnu1/arch/mips/sni/rm200.c
--- linux-libre-2.6.29-gnu1/arch/mips/sni/rm200.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/sni/rm200.c	2009-06-09 23:05:27.000000000 -0400
@@ -359,7 +359,8 @@ void sni_rm200_init_8259A(void)
  * IRQ2 is cascade interrupt to second interrupt controller
  */
 static struct irqaction sni_rm200_irq2 = {
-	no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
+	.handler = no_action,
+	.name = "cascade",
 };
 
 static struct resource sni_rm200_pic1_resource = {
@@ -487,7 +488,7 @@ void __init sni_rm200_irq_init(void)
 	mips_cpu_irq_init();
 	/* Actually we've got more interrupts to handle ...  */
 	for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
-		set_irq_chip(i, &rm200_irq_type);
+		set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
 	sni_hwint = sni_rm200_hwint;
 	change_c0_status(ST0_IM, IE_IRQ0);
 	setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup.c linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #include <asm/txx9/generic.h>
 #include <asm/txx9/pci.h>
 #include <asm/txx9tmr.h>
+#include <asm/txx9/ndfmc.h>
 #ifdef CONFIG_CPU_TX49XX
 #include <asm/txx9/tx4938.h>
 #endif
@@ -686,6 +687,26 @@ void __init txx9_physmap_flash_init(int
 	if (!pdev ||
 	    platform_device_add_resources(pdev, &res, 1) ||
 	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+	    platform_device_add(pdev))
+		platform_device_put(pdev);
+#endif
+}
+
+void __init txx9_ndfmc_init(unsigned long baseaddr,
+			    const struct txx9ndfmc_platform_data *pdata)
+{
+#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
+	defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
+	struct resource res = {
+		.start = baseaddr,
+		.end = baseaddr + 0x1000 - 1,
+		.flags = IORESOURCE_MEM,
+	};
+	struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
+
+	if (!pdev ||
+	    platform_device_add_resources(pdev, &res, 1) ||
+	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
 	    platform_device_add(pdev))
 		platform_device_put(pdev);
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4927.c linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4927.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4927.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4927.c	2009-06-09 23:05:27.000000000 -0400
@@ -88,7 +88,7 @@ void __init tx4927_setup(void)
 {
 	int i;
 	__u32 divmode;
-	int cpuclk = 0;
+	unsigned int cpuclk = 0;
 	u64 ccfg;
 
 	txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4938.c linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4938.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4938.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4938.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <asm/txx9tmr.h>
 #include <asm/txx9pio.h>
 #include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
 #include <asm/txx9/tx4938.h>
 
 static void __init tx4938_wdr_init(void)
@@ -92,7 +93,7 @@ void __init tx4938_setup(void)
 {
 	int i;
 	__u32 divmode;
-	int cpuclk = 0;
+	unsigned int cpuclk = 0;
 	u64 ccfg;
 
 	txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int
 		platform_device_put(pdev);
 }
 
+void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
+{
+	struct txx9ndfmc_platform_data plat_data = {
+		.shift = 1,
+		.gbus_clock = txx9_gbus_clock,
+		.hold = hold,
+		.spw = spw,
+		.ch_mask = 1,
+	};
+	unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
+
+#ifdef __BIG_ENDIAN
+	baseaddr += 4;
+#endif
+	if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
+	     (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
+	    TX4938_PCFG_NDF_SEL)
+		txx9_ndfmc_init(baseaddr, &plat_data);
+}
+
 static void __init tx4938_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4939.c linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4939.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/generic/setup_tx4939.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/generic/setup_tx4939.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@
 #include <asm/txx9irq.h>
 #include <asm/txx9tmr.h>
 #include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
 #include <asm/txx9/tx4939.h>
 
 static void __init tx4939_wdr_init(void)
@@ -113,7 +114,7 @@ void __init tx4939_setup(void)
 	int i;
 	__u32 divmode;
 	__u64 pcfg;
-	int cpuclk = 0;
+	unsigned int cpuclk = 0;
 
 	txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE,
 			  TX4939_REG_SIZE);
@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void)
 	platform_device_register(&rtc_dev);
 }
 
+void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+			      unsigned char ch_mask, unsigned char wide_mask)
+{
+	struct txx9ndfmc_platform_data plat_data = {
+		.shift = 1,
+		.gbus_clock = txx9_gbus_clock,
+		.hold = hold,
+		.spw = spw,
+		.flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
+			 NDFMC_PLAT_FLAG_DUMMYWRITE,
+		.ch_mask = ch_mask,
+		.wide_mask = wide_mask,
+	};
+	txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
+}
+
 static void __init tx4939_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/Kconfig linux-libre-2.6.30-gnu1/arch/mips/txx9/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@ config MACH_TXX9
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select GENERIC_HARDIRQS_NO__DO_IRQ
 
 config TOSHIBA_JMR3927
 	bool "Toshiba JMR-TX3927 board"
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/rbtx4938/setup.c linux-libre-2.6.30-gnu1/arch/mips/txx9/rbtx4938/setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/rbtx4938/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/rbtx4938/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(
 	rbtx4938_ne_init();
 	tx4938_wdt_init();
 	rbtx4938_mtd_init();
+	/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+	tx4938_ndfmc_init(10, 35);
 	tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
 	txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/txx9/rbtx4939/setup.c linux-libre-2.6.30-gnu1/arch/mips/txx9/rbtx4939/setup.c
--- linux-libre-2.6.29-gnu1/arch/mips/txx9/rbtx4939/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/txx9/rbtx4939/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,9 @@
 #include <linux/leds.h>
 #include <linux/interrupt.h>
 #include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
 #include <asm/reboot.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/pci.h>
@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsign
 	__rbtx4939_7segled_putc(pos, val);
 }
 
+#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
+/* special mapping for boot rom */
+static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
+{
+	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+	unsigned char shift;
+
+	if (bdipsw & 8) {
+		/* BOOT Mode: USER ROM1 / USER ROM2 */
+		shift = bdipsw & 3;
+		/* rotate A[23:22] */
+		return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
+	}
+#ifdef __BIG_ENDIAN
+	if (bdipsw == 0)
+		/* BOOT Mode: Monitor ROM */
+		ofs ^= 0x400000;	/* swap A[22] */
+#endif
+	return ofs;
+}
+
+static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
+{
+	map_word r;
+
+	ofs = rbtx4939_flash_fixup_ofs(ofs);
+	r.x[0] = __raw_readw(map->virt + ofs);
+	return r;
+}
+
+static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
+				   unsigned long ofs)
+{
+	ofs = rbtx4939_flash_fixup_ofs(ofs);
+	__raw_writew(datum.x[0], map->virt + ofs);
+	mb();	/* see inline_map_write() in mtd/map.h */
+}
+
+static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
+				     unsigned long from, ssize_t len)
+{
+	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+	unsigned char shift;
+	ssize_t curlen;
+
+	from += (unsigned long)map->virt;
+	if (bdipsw & 8) {
+		/* BOOT Mode: USER ROM1 / USER ROM2 */
+		shift = bdipsw & 3;
+		while (len) {
+			curlen = min_t(unsigned long, len,
+				     0x400000 -	(from & (0x400000 - 1)));
+			memcpy(to,
+			       (void *)((from & ~0xc00000) |
+					((((from >> 22) + shift) & 3) << 22)),
+			       curlen);
+			len -= curlen;
+			from += curlen;
+			to += curlen;
+		}
+		return;
+	}
+#ifdef __BIG_ENDIAN
+	if (bdipsw == 0) {
+		/* BOOT Mode: Monitor ROM */
+		while (len) {
+			curlen = min_t(unsigned long, len,
+				     0x400000 - (from & (0x400000 - 1)));
+			memcpy(to, (void *)(from ^ 0x400000), curlen);
+			len -= curlen;
+			from += curlen;
+			to += curlen;
+		}
+		return;
+	}
+#endif
+	memcpy(to, (void *)from, len);
+}
+
+static void rbtx4939_flash_map_init(struct map_info *map)
+{
+	map->read = rbtx4939_flash_read16;
+	map->write = rbtx4939_flash_write16;
+	map->copy_from = rbtx4939_flash_copy_from;
+}
+
+static void __init rbtx4939_mtd_init(void)
+{
+	static struct {
+		struct platform_device dev;
+		struct resource res;
+		struct rbtx4939_flash_data data;
+	} pdevs[4];
+	int i;
+	static char names[4][8];
+	static struct mtd_partition parts[4];
+	struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
+	u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+
+	if (bdipsw & 8) {
+		/* BOOT Mode: USER ROM1 / USER ROM2 */
+		boot_pdata->nr_parts = 4;
+		for (i = 0; i < boot_pdata->nr_parts; i++) {
+			sprintf(names[i], "img%d", 4 - i);
+			parts[i].name = names[i];
+			parts[i].size = 0x400000;
+			parts[i].offset = MTDPART_OFS_NXTBLK;
+		}
+	} else if (bdipsw == 0) {
+		/* BOOT Mode: Monitor ROM */
+		boot_pdata->nr_parts = 2;
+		strcpy(names[0], "big");
+		strcpy(names[1], "little");
+		for (i = 0; i < boot_pdata->nr_parts; i++) {
+			parts[i].name = names[i];
+			parts[i].size = 0x400000;
+			parts[i].offset = MTDPART_OFS_NXTBLK;
+		}
+	} else {
+		/* BOOT Mode: ROM Emulator */
+		boot_pdata->nr_parts = 2;
+		parts[0].name = "boot";
+		parts[0].offset = 0xc00000;
+		parts[0].size = 0x400000;
+		parts[1].name = "user";
+		parts[1].offset = 0;
+		parts[1].size = 0xc00000;
+	}
+	boot_pdata->parts = parts;
+	boot_pdata->map_init = rbtx4939_flash_map_init;
+
+	for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
+		struct resource *r = &pdevs[i].res;
+		struct platform_device *dev = &pdevs[i].dev;
+
+		r->start = 0x1f000000 - i * 0x1000000;
+		r->end = r->start + 0x1000000 - 1;
+		r->flags = IORESOURCE_MEM;
+		pdevs[i].data.width = 2;
+		dev->num_resources = 1;
+		dev->resource = r;
+		dev->id = i;
+		dev->name = "rbtx4939-flash";
+		dev->dev.platform_data = &pdevs[i].data;
+		platform_device_register(dev);
+	}
+}
+#else
+static void __init rbtx4939_mtd_init(void)
+{
+}
+#endif
+
 static void __init rbtx4939_arch_init(void)
 {
 	rbtx4939_pci_setup();
@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(
 	    platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
 	    platform_device_add(pdev))
 		platform_device_put(pdev);
+	rbtx4939_mtd_init();
+	/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+	tx4939_ndfmc_init(10, 35,
+			  (1 << 1) | (1 << 2),
+			  (1 << 2)); /* ch1:8bit, ch2:16bit */
 	rbtx4939_led_setup();
 	tx4939_wdt_init();
 	tx4939_ata_init();
@@ -375,7 +536,7 @@ static void __init rbtx4939_setup(void)
 }
 
 struct txx9_board_vec rbtx4939_vec __initdata = {
-	.system = "Tothiba RBTX4939",
+	.system = "Toshiba RBTX4939",
 	.prom_init = rbtx4939_prom_init,
 	.mem_setup = rbtx4939_setup,
 	.irq_setup = rbtx4939_irq_setup,
diff -druNp linux-libre-2.6.29-gnu1/arch/mips/vr41xx/common/irq.c linux-libre-2.6.30-gnu1/arch/mips/vr41xx/common/irq.c
--- linux-libre-2.6.29-gnu1/arch/mips/vr41xx/common/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mips/vr41xx/common/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,6 @@ static irq_cascade_t irq_cascade[NR_IRQS
 
 static struct irqaction cascade_irqaction = {
 	.handler	= no_action,
-	.mask		= CPU_MASK_NONE,
 	.name		= "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/configs/asb2303_defconfig linux-libre-2.6.30-gnu1/arch/mn10300/configs/asb2303_defconfig
--- linux-libre-2.6.29-gnu1/arch/mn10300/configs/asb2303_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/configs/asb2303_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc2
-# Tue Feb 19 18:52:24 2008
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 11:13:22 2009
 #
 CONFIG_MN10300=y
 CONFIG_AM33=y
@@ -18,7 +18,6 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_BUG=y
 CONFIG_QUICKLIST=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
-# CONFIG_ARCH_SUPPORTS_AOUT is not set
 CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HOTPLUG_CPU is not set
 CONFIG_HZ=1000
@@ -40,52 +39,58 @@ 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_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=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
-# CONFIG_USER_SCHED is not set
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED 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 is not set
 CONFIG_SYSCTL=y
+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
 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_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_OPROFILE=y
-# CONFIG_HAVE_OPROFILE is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_PROC_PAGE_MONITOR 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 is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
-CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_FREEZER is not set
 
 #
 # Matsushita MN10300 system setup
@@ -107,7 +112,6 @@ CONFIG_INTERRUPT_VECTOR_BASE=0x90000000
 CONFIG_KERNEL_TEXT_ADDRESS=0x90001000
 CONFIG_KERNEL_ZIMAGE_BASE_ADDRESS=0x90700000
 CONFIG_PREEMPT=y
-CONFIG_PREEMPT_BKL=y
 CONFIG_MN10300_CURRENT_IN_E2=y
 CONFIG_MN10300_USING_JTAG=y
 CONFIG_MN10300_RTC=y
@@ -135,13 +139,15 @@ 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=1
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Power management options
@@ -152,11 +158,9 @@ CONFIG_VIRT_TO_BUS=y
 # Executable 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
 
 #
@@ -194,8 +198,6 @@ 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_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -203,6 +205,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
@@ -212,7 +215,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
@@ -223,14 +228,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -255,6 +254,7 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -297,9 +297,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
 
 #
@@ -319,14 +317,23 @@ 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
 # CONFIG_PARPORT is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 
 #
 # SCSI device support
@@ -334,7 +341,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK 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
@@ -345,10 +352,15 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=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_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -358,6 +370,10 @@ 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
@@ -382,6 +398,7 @@ CONFIG_SMC91X=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -403,6 +420,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=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
@@ -411,34 +429,43 @@ CONFIG_RTC=y
 # CONFIG_R3964 is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER 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_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
 
 #
@@ -453,21 +480,17 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND 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_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -481,20 +504,23 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE 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
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -506,19 +532,17 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_ROMFS_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_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_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -535,12 +559,16 @@ CONFIG_SUNRPC=y
 # 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_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_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
 
 #
@@ -548,26 +576,26 @@ 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_CRYPTO 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_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-
-#
-# Profiling support
-#
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/atomic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,157 @@
+/* MN10300 Atomic counter operations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#ifdef CONFIG_SMP
+#error not SMP safe
+#endif
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ */
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#ifdef __KERNEL__
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_read(v)	((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_set(v, i) (((v)->counter) = (i))
+
+#include <asm/system.h>
+
+/**
+ * atomic_add_return - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v and returns the result
+ * Note that the guaranteed useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	unsigned long flags;
+	int temp;
+
+	local_irq_save(flags);
+	temp = v->counter;
+	temp += i;
+	v->counter = temp;
+	local_irq_restore(flags);
+
+	return temp;
+}
+
+/**
+ * atomic_sub_return - subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns the result
+ * Note that the guaranteed useful range of an atomic_t is only 24 bits.
+ */
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+	unsigned long flags;
+	int temp;
+
+	local_irq_save(flags);
+	temp = v->counter;
+	temp -= i;
+	v->counter = temp;
+	local_irq_restore(flags);
+
+	return temp;
+}
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+	return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+	atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+	atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v)		atomic_sub_return(1, (v))
+#define atomic_inc_return(v)		atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i, v)	(atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v)		(atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v)		(atomic_add_return(1, (v)) == 0)
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags;
+
+	mask = ~mask;
+	local_irq_save(flags);
+	*addr &= mask;
+	local_irq_restore(flags);
+}
+
+#define atomic_xchg(ptr, v)		(xchg(&(ptr)->counter, (v)))
+#define atomic_cmpxchg(v, old, new)	(cmpxchg(&((v)->counter), (old), (new)))
+
+/* Atomic operations are already serializing on MN10300??? */
+#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()
+
+#include <asm-generic/atomic.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_ATOMIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/auxvec.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/auxvec.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/auxvec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/auxvec.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+#ifndef _ASM_AUXVEC_H
+#define _ASM_AUXVEC_H
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,240 @@
+/* MN10300 bit operations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+#ifndef __ASM_BITOPS_H
+#define __ASM_BITOPS_H
+
+#include <asm/cpu-regs.h>
+
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+/*
+ * set bit
+ */
+#define __set_bit(nr, addr)					\
+({								\
+	volatile unsigned char *_a = (unsigned char *)(addr);	\
+	const unsigned shift = (nr) & 7;			\
+	_a += (nr) >> 3;					\
+								\
+	asm volatile("bset %2,(%1) # set_bit reg"		\
+		     : "=m"(*_a)				\
+		     : "a"(_a), "d"(1 << shift),  "m"(*_a)	\
+		     : "memory", "cc");				\
+})
+
+#define set_bit(nr, addr) __set_bit((nr), (addr))
+
+/*
+ * clear bit
+ */
+#define ___clear_bit(nr, addr)					\
+({								\
+	volatile unsigned char *_a = (unsigned char *)(addr);	\
+	const unsigned shift = (nr) & 7;			\
+	_a += (nr) >> 3;					\
+								\
+	asm volatile("bclr %2,(%1) # clear_bit reg"		\
+		     : "=m"(*_a)				\
+		     : "a"(_a), "d"(1 << shift), "m"(*_a)	\
+		     : "memory", "cc");				\
+})
+
+#define clear_bit(nr, addr) ___clear_bit((nr), (addr))
+
+
+static inline void __clear_bit(int nr, volatile void *addr)
+{
+	unsigned int *a = (unsigned int *) addr;
+	int mask;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a &= ~mask;
+}
+
+/*
+ * test bit
+ */
+static inline int test_bit(int nr, const volatile void *addr)
+{
+	return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
+}
+
+/*
+ * change bit
+ */
+static inline void __change_bit(int nr, volatile void *addr)
+{
+	int	mask;
+	unsigned int *a = (unsigned int *) addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	*a ^= mask;
+}
+
+extern void change_bit(int nr, volatile void *addr);
+
+/*
+ * test and set bit
+ */
+#define __test_and_set_bit(nr,addr)				\
+({								\
+	volatile unsigned char *_a = (unsigned char *)(addr);	\
+	const unsigned shift = (nr) & 7;			\
+	unsigned epsw;						\
+	_a += (nr) >> 3;					\
+								\
+	asm volatile("bset %3,(%2) # test_set_bit reg\n"	\
+		     "mov epsw,%1"				\
+		     : "=m"(*_a), "=d"(epsw)			\
+		     : "a"(_a), "d"(1 << shift), "m"(*_a)	\
+		     : "memory", "cc");				\
+								\
+	!(epsw & EPSW_FLAG_Z);					\
+})
+
+#define test_and_set_bit(nr, addr) __test_and_set_bit((nr), (addr))
+
+/*
+ * test and clear bit
+ */
+#define __test_and_clear_bit(nr, addr)				\
+({								\
+        volatile unsigned char *_a = (unsigned char *)(addr);	\
+	const unsigned shift = (nr) & 7;			\
+	unsigned epsw;						\
+	_a += (nr) >> 3;					\
+								\
+	asm volatile("bclr %3,(%2) # test_clear_bit reg\n"	\
+		     "mov epsw,%1"				\
+		     : "=m"(*_a), "=d"(epsw)			\
+		     : "a"(_a), "d"(1 << shift), "m"(*_a)	\
+		     : "memory", "cc");				\
+								\
+	!(epsw & EPSW_FLAG_Z);					\
+})
+
+#define test_and_clear_bit(nr, addr) __test_and_clear_bit((nr), (addr))
+
+/*
+ * test and change bit
+ */
+static inline int __test_and_change_bit(int nr, volatile void *addr)
+{
+	int	mask, retval;
+	unsigned int *a = (unsigned int *)addr;
+
+	a += nr >> 5;
+	mask = 1 << (nr & 0x1f);
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+
+	return retval;
+}
+
+extern int test_and_change_bit(int nr, volatile void *addr);
+
+#include <asm-generic/bitops/lock.h>
+
+#ifdef __KERNEL__
+
+/**
+ * __ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 31..0 to indicate bit 31..0 most least significant bit set
+ * - if no bits are set in x, the result is undefined
+ */
+static inline __attribute__((const))
+unsigned long __ffs(unsigned long x)
+{
+	int bit;
+	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x));
+	return bit;
+}
+
+/*
+ * special slimline version of fls() for calculating ilog2_u32()
+ * - note: no protection against n == 0
+ */
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+	int bit;
+	asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n));
+	return bit;
+}
+
+/**
+ * fls - find last bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs:
+ * - return 32..1 to indicate bit 31..0 most significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int fls(int x)
+{
+	return (x != 0) ? __ilog2_u32(x) + 1 : 0;
+}
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+	return __ilog2_u32(word);
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 32..1 to indicate bit 31..0 most least significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int ffs(int x)
+{
+	/* Note: (x & -x) gives us a mask that is the least significant
+	 * (rightmost) 1-bit of the value in x.
+	 */
+	return fls(x & -x);
+}
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+
+#define ext2_set_bit_atomic(lock, nr, addr) \
+	test_and_set_bit((nr) ^ 0x18, (addr))
+#define ext2_clear_bit_atomic(lock, nr, addr) \
+	test_and_clear_bit((nr) ^ 0x18, (addr))
+
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/minix-le.h>
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_BITOPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bug.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bug.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/* MN10300 Kernel bug reporting
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#ifdef CONFIG_BUG
+
+/*
+ * Tell the user there is some problem.
+ */
+#define BUG()							\
+do {								\
+	asm volatile(						\
+		"	syscall 15			\n"	\
+		"0:					\n"	\
+		"	.section __bug_table,\"a\"	\n"	\
+		"	.long 0b,%0,%1			\n"	\
+		"	.previous			\n"	\
+		:						\
+		: "i"(__FILE__), "i"(__LINE__)			\
+		);						\
+} while (1)
+
+#define HAVE_ARCH_BUG
+#endif /* CONFIG_BUG */
+
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_BUG_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bugs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bugs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/bugs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/bugs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/* MN10300 Checks for architecture-dependent bugs
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_BUGS_H
+#define _ASM_BUGS_H
+
+#include <asm/processor.h>
+
+static inline void __init check_bugs(void)
+{
+}
+
+#endif /* _ASM_BUGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/busctl-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/busctl-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/busctl-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/busctl-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,151 @@
+/* AM33v2 on-board bus controller registers
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_BUSCTL_REGS_H
+#define _ASM_BUSCTL_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+/* bus controller registers */
+#define BCCR			__SYSREG(0xc0002000, u32)	/* bus controller control reg */
+#define BCCR_B0AD		0x00000003	/* block 0 (80000000-83ffffff) bus allocation */
+#define BCCR_B1AD		0x0000000c	/* block 1 (84000000-87ffffff) bus allocation */
+#define BCCR_B2AD		0x00000030	/* block 2 (88000000-8bffffff) bus allocation */
+#define BCCR_B3AD		0x000000c0	/* block 3 (8c000000-8fffffff) bus allocation */
+#define BCCR_B4AD		0x00000300	/* block 4 (90000000-93ffffff) bus allocation */
+#define BCCR_B5AD		0x00000c00	/* block 5 (94000000-97ffffff) bus allocation */
+#define BCCR_B6AD		0x00003000	/* block 6 (98000000-9bffffff) bus allocation */
+#define BCCR_B7AD		0x0000c000	/* block 7 (9c000000-9fffffff) bus allocation */
+#define BCCR_BxAD_EXBUS		0x0		/* - direct to system bus controller */
+#define BCCR_BxAD_OPEXBUS	0x1		/* - direct to memory bus controller */
+#define BCCR_BxAD_OCMBUS	0x2		/* - direct to on chip memory */
+#define BCCR_API		0x00070000	/* bus arbitration priority */
+#define BCCR_API_DMACICD	0x00000000	/* - DMA > CI > CD */
+#define BCCR_API_DMACDCI	0x00010000	/* - DMA > CD > CI */
+#define BCCR_API_CICDDMA	0x00020000	/* - CI > CD > DMA */
+#define BCCR_API_CDCIDMA	0x00030000	/* - CD > CI > DMA */
+#define BCCR_API_ROUNDROBIN	0x00040000	/* - round robin */
+#define BCCR_BEPRI_DMACICD	0x00c00000	/* bus error address priority */
+#define BCCR_BEPRI_DMACDCI	0x00000000	/* - DMA > CI > CD */
+#define BCCR_BEPRI_CICDDMA	0x00400000	/* - DMA > CD > CI */
+#define BCCR_BEPRI_CDCIDMA	0x00800000	/* - CI > CD > DMA */
+#define BCCR_BEPRI		0x00c00000	/* - CD > CI > DMA */
+#define BCCR_TMON		0x03000000	/* timeout value settings */
+#define BCCR_TMON_16IOCLK	0x00000000	/* - 16 IOCLK cycles */
+#define BCCR_TMON_256IOCLK	0x01000000	/* - 256 IOCLK cycles */
+#define BCCR_TMON_4096IOCLK	0x02000000	/* - 4096 IOCLK cycles */
+#define BCCR_TMON_65536IOCLK	0x03000000	/* - 65536 IOCLK cycles */
+#define BCCR_TMOE		0x10000000	/* timeout detection enable */
+
+#define BCBERR			__SYSREG(0xc0002010, u32)	/* bus error source reg */
+#define BCBERR_BESB		0x0000001f	/* erroneous access destination space */
+#define BCBERR_BESB_MON		0x00000001	/* - monitor space */
+#define BCBERR_BESB_IO		0x00000002	/* - IO bus */
+#define BCBERR_BESB_EX		0x00000004	/* - EX bus */
+#define BCBERR_BESB_OPEX	0x00000008	/* - OpEX bus */
+#define BCBERR_BESB_OCM		0x00000010	/* - on chip memory */
+#define BCBERR_BERW		0x00000100	/* type of access */
+#define BCBERR_BERW_WRITE	0x00000000	/* - write */
+#define BCBERR_BERW_READ	0x00000100	/* - read */
+#define BCBERR_BESD		0x00000200	/* error detector */
+#define BCBERR_BESD_BCU		0x00000000	/* - BCU detected error */
+#define BCBERR_BESD_SLAVE_BUS	0x00000200	/* - slave bus detected error */
+#define BCBERR_BEBST		0x00000400	/* type of access */
+#define BCBERR_BEBST_SINGLE	0x00000000	/* - single */
+#define BCBERR_BEBST_BURST	0x00000400	/* - burst */
+#define BCBERR_BEME		0x00000800	/* multiple bus error flag */
+#define BCBERR_BEMR		0x00007000	/* master bus that caused the error */
+#define BCBERR_BEMR_NOERROR	0x00000000	/* - no error */
+#define BCBERR_BEMR_CI		0x00001000	/* - CPU instruction fetch bus caused error */
+#define BCBERR_BEMR_CD		0x00002000	/* - CPU data bus caused error */
+#define BCBERR_BEMR_DMA		0x00004000	/* - DMA bus caused error */
+
+#define BCBEAR			__SYSREGC(0xc0002020, u32)	/* bus error address reg */
+
+/* system bus controller registers */
+#define SBBASE(X)		__SYSREG(0xd8c00100 + (X) * 0x10, u32)	/* SBC base addr regs */
+#define SBBASE_BE		0x00000001	/* bank enable */
+#define SBBASE_BAM		0x0000fffe	/* bank address mask [31:17] */
+#define SBBASE_BBA		0xfffe0000	/* bank base address [31:17] */
+
+#define SBCNTRL0(X)		__SYSREG(0xd8c00200 + (X) * 0x10, u32)	/* SBC bank ctrl0 regs */
+#define SBCNTRL0_WEH		0x00000f00	/* write enable hold */
+#define SBCNTRL0_REH		0x0000f000	/* read enable hold */
+#define SBCNTRL0_RWH		0x000f0000	/* SRW signal hold */
+#define SBCNTRL0_CSH		0x00f00000	/* chip select hold */
+#define SBCNTRL0_DAH		0x0f000000	/* data hold */
+#define SBCNTRL0_ADH		0xf0000000	/* address hold */
+
+#define SBCNTRL1(X)		__SYSREG(0xd8c00204 + (X) * 0x10, u32)	/* SBC bank ctrl1 regs */
+#define SBCNTRL1_WED		0x00000f00	/* write enable delay */
+#define SBCNTRL1_RED		0x0000f000	/* read enable delay */
+#define SBCNTRL1_RWD		0x000f0000	/* SRW signal delay */
+#define SBCNTRL1_ASW		0x00f00000	/* address strobe width */
+#define SBCNTRL1_CSD		0x0f000000	/* chip select delay */
+#define SBCNTRL1_ASD		0xf0000000	/* address strobe delay */
+
+#define SBCNTRL2(X)		__SYSREG(0xd8c00208 + (X) * 0x10, u32)	/* SBC bank ctrl2 regs */
+#define SBCNTRL2_WC		0x000000ff	/* wait count */
+#define SBCNTRL2_BWC		0x00000f00	/* burst wait count */
+#define SBCNTRL2_WM		0x01000000	/* wait mode setting */
+#define SBCNTRL2_WM_FIXEDWAIT	0x00000000	/* - fixed wait access */
+#define SBCNTRL2_WM_HANDSHAKE	0x01000000	/* - handshake access */
+#define SBCNTRL2_BM		0x02000000	/* bus synchronisation mode */
+#define SBCNTRL2_BM_SYNC	0x00000000	/* - synchronous mode */
+#define SBCNTRL2_BM_ASYNC	0x02000000	/* - asynchronous mode */
+#define SBCNTRL2_BW		0x04000000	/* bus width */
+#define SBCNTRL2_BW_32		0x00000000	/* - 32 bits */
+#define SBCNTRL2_BW_16		0x04000000	/* - 16 bits */
+#define SBCNTRL2_RWINV		0x08000000	/* R/W signal invert polarity */
+#define SBCNTRL2_RWINV_NORM	0x00000000	/* - normal (read high) */
+#define SBCNTRL2_RWINV_INV	0x08000000	/* - inverted (read low) */
+#define SBCNTRL2_BT		0x70000000	/* bus type setting */
+#define SBCNTRL2_BT_SRAM	0x00000000	/* - SRAM interface */
+#define SBCNTRL2_BT_ADMUX	0x00000000	/* - addr/data multiplexed interface */
+#define SBCNTRL2_BT_BROM	0x00000000	/* - burst ROM interface */
+#define SBCNTRL2_BTSE		0x80000000	/* burst enable */
+
+/* memory bus controller */
+#define SDBASE(X)		__SYSREG(0xda000008 + (X) * 0x4, u32)	/* MBC base addr regs */
+#define SDBASE_CE		0x00000001	/* chip enable */
+#define SDBASE_CBAM		0x0000fff0	/* chip base address mask [31:20] */
+#define SDBASE_CBAM_SHIFT	16
+#define SDBASE_CBA		0xfff00000	/* chip base address [31:20] */
+
+#define SDRAMBUS		__SYSREG(0xda000000, u32)	/* bus mode control reg */
+#define SDRAMBUS_REFEN		0x00000004	/* refresh enable */
+#define SDRAMBUS_TRC		0x00000018	/* refresh command delay time */
+#define SDRAMBUS_BSTPT		0x00000020	/* burst stop command enable */
+#define SDRAMBUS_PONSEQ		0x00000040	/* power on sequence */
+#define SDRAMBUS_SELFREQ	0x00000080	/* self-refresh mode request */
+#define SDRAMBUS_SELFON		0x00000100	/* self-refresh mode on */
+#define SDRAMBUS_SIZE		0x00030000	/* SDRAM size */
+#define SDRAMBUS_SIZE_64Mbit	0x00010000	/* 64Mbit SDRAM (x16) */
+#define SDRAMBUS_SIZE_128Mbit	0x00020000	/* 128Mbit SDRAM (x16) */
+#define SDRAMBUS_SIZE_256Mbit	0x00030000	/* 256Mbit SDRAM (x16) */
+#define SDRAMBUS_TRASWAIT	0x000c0000	/* row address precharge command cycle number */
+#define SDRAMBUS_REFNUM		0x00300000	/* refresh command number */
+#define SDRAMBUS_BSTWAIT	0x00c00000	/* burst stop command cycle */
+#define SDRAMBUS_SETWAIT	0x03000000	/* mode register setting command cycle */
+#define SDRAMBUS_PREWAIT	0x0c000000	/* precharge command cycle */
+#define SDRAMBUS_RASLATE	0x30000000	/* RAS latency */
+#define SDRAMBUS_CASLATE	0xc0000000	/* CAS latency */
+
+#define SDREFCNT		__SYSREG(0xda000004, u32)	/* refresh period reg */
+#define SDREFCNT_PERI		0x00000fff	/* refresh period */
+
+#define SDSHDW			__SYSREG(0xda000010, u32)	/* test reg */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BUSCTL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/byteorder.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/byteorder.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/byteorder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/byteorder.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cacheflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+/* MN10300 Cache flushing
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+#ifndef __ASSEMBLY__
+
+/* Keep includes the same across arches.  */
+#include <linux/mm.h>
+
+/*
+ * virtually-indexed cache managment (our cache is physically indexed)
+ */
+#define flush_cache_all()			do {} while (0)
+#define flush_cache_mm(mm)			do {} while (0)
+#define flush_cache_dup_mm(mm)			do {} while (0)
+#define flush_cache_range(mm, start, end)	do {} while (0)
+#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 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)
+
+/*
+ * physically-indexed cache managment
+ */
+#ifndef CONFIG_MN10300_CACHE_DISABLED
+
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
+
+#else
+
+#define flush_icache_range(start, end)		do {} while (0)
+#define flush_icache_page(vma, pg)		do {} while (0)
+
+#endif
+
+#define flush_icache_user_range(vma, pg, adr, len) \
+	flush_icache_range(adr, adr + len)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+	do {					\
+		memcpy(dst, src, len);		\
+		flush_icache_page(vma, page);	\
+	} while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+/*
+ * primitive routines
+ */
+#ifndef CONFIG_MN10300_CACHE_DISABLED
+extern void mn10300_icache_inv(void);
+extern void mn10300_dcache_inv(void);
+extern void mn10300_dcache_inv_page(unsigned start);
+extern void mn10300_dcache_inv_range(unsigned start, unsigned end);
+extern void mn10300_dcache_inv_range2(unsigned start, unsigned size);
+#ifdef CONFIG_MN10300_CACHE_WBACK
+extern void mn10300_dcache_flush(void);
+extern void mn10300_dcache_flush_page(unsigned start);
+extern void mn10300_dcache_flush_range(unsigned start, unsigned end);
+extern void mn10300_dcache_flush_range2(unsigned start, unsigned size);
+extern void mn10300_dcache_flush_inv(void);
+extern void mn10300_dcache_flush_inv_page(unsigned start);
+extern void mn10300_dcache_flush_inv_range(unsigned start, unsigned end);
+extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size);
+#else
+#define mn10300_dcache_flush()				do {} while (0)
+#define mn10300_dcache_flush_page(start)		do {} while (0)
+#define mn10300_dcache_flush_range(start, end)		do {} while (0)
+#define mn10300_dcache_flush_range2(start, size)	do {} while (0)
+#define mn10300_dcache_flush_inv()			mn10300_dcache_inv()
+#define mn10300_dcache_flush_inv_page(start) \
+	mn10300_dcache_inv_page((start))
+#define mn10300_dcache_flush_inv_range(start, end) \
+	mn10300_dcache_inv_range((start), (end))
+#define mn10300_dcache_flush_inv_range2(start, size) \
+	mn10300_dcache_inv_range2((start), (size))
+#endif /* CONFIG_MN10300_CACHE_WBACK */
+#else
+#define mn10300_icache_inv()				do {} while (0)
+#define mn10300_dcache_inv()				do {} while (0)
+#define mn10300_dcache_inv_page(start)			do {} while (0)
+#define mn10300_dcache_inv_range(start, end)		do {} while (0)
+#define mn10300_dcache_inv_range2(start, size)		do {} while (0)
+#define mn10300_dcache_flush()				do {} while (0)
+#define mn10300_dcache_flush_inv_page(start)		do {} while (0)
+#define mn10300_dcache_flush_inv()			do {} while (0)
+#define mn10300_dcache_flush_inv_range(start, end)	do {} while (0)
+#define mn10300_dcache_flush_inv_range2(start, size)	do {} while (0)
+#define mn10300_dcache_flush_page(start)		do {} while (0)
+#define mn10300_dcache_flush_range(start, end)		do {} while (0)
+#define mn10300_dcache_flush_range2(start, size)	do {} while (0)
+#endif /* CONFIG_MN10300_CACHE_DISABLED */
+
+/*
+ * internal debugging function
+ */
+#ifdef CONFIG_DEBUG_PAGEALLOC
+extern void kernel_map_pages(struct page *page, int numpages, int enable);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_CACHEFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cache.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cache.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+/* MN10300 cache management registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
+
+#include <asm/cpu-regs.h>
+#include <proc/cache.h>
+
+#ifndef __ASSEMBLY__
+#define L1_CACHE_DISPARITY	(L1_CACHE_NENTRIES * L1_CACHE_BYTES)
+#else
+#define L1_CACHE_DISPARITY	L1_CACHE_NENTRIES * L1_CACHE_BYTES
+#endif
+
+/* data cache purge registers
+ * - read from the register to unconditionally purge that cache line
+ * - write address & 0xffffff00 to conditionally purge that cache line
+ *   - clear LSB to request invalidation as well
+ */
+#define DCACHE_PURGE(WAY, ENTRY) \
+	__SYSREG(0xc8400000 + (WAY) * L1_CACHE_WAYDISP + \
+		 (ENTRY) * L1_CACHE_BYTES, u32)
+
+#define DCACHE_PURGE_WAY0(ENTRY) \
+	__SYSREG(0xc8400000 + 0 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32)
+#define DCACHE_PURGE_WAY1(ENTRY) \
+	__SYSREG(0xc8400000 + 1 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32)
+#define DCACHE_PURGE_WAY2(ENTRY) \
+	__SYSREG(0xc8400000 + 2 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32)
+#define DCACHE_PURGE_WAY3(ENTRY) \
+	__SYSREG(0xc8400000 + 3 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32)
+
+/* instruction cache access registers */
+#define ICACHE_DATA(WAY, ENTRY, OFF) \
+	__SYSREG(0xc8000000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32)
+#define ICACHE_TAG(WAY, ENTRY)	 \
+	__SYSREG(0xc8100000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32)
+
+/* instruction cache access registers */
+#define DCACHE_DATA(WAY, ENTRY, OFF) \
+	__SYSREG(0xc8200000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32)
+#define DCACHE_TAG(WAY, ENTRY)	 \
+	__SYSREG(0xc8300000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32)
+
+#endif /* _ASM_CACHE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/checksum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/* MN10300 Optimised checksumming code
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
+					int len, __wsum sum);
+extern __wsum csum_partial_copy_from_user(const void *src, void *dst,
+					  int len, __wsum sum,
+					  int *err_ptr);
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+extern __sum16 ip_compute_csum(const void *buff, int len);
+
+#define csum_partial_copy_fromuser csum_partial_copy
+extern __wsum csum_partial_copy(const void *src, void *dst, int len,
+				__wsum sum);
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+	asm(
+		"	add	%1,%0		\n"
+		"	addc	0xffff,%0	\n"
+		: "=r" (sum)
+		: "r" (sum << 16), "0" (sum & 0xffff0000)
+		: "cc"
+	    );
+	return (~sum) >> 16;
+}
+
+static inline __wsum csum_tcpudp_nofold(unsigned long saddr,
+					unsigned long daddr,
+					unsigned short len,
+					unsigned short proto,
+					__wsum sum)
+{
+	__wsum tmp;
+
+	tmp = (__wsum) ntohs(len) << 16;
+	tmp += (__wsum) proto << 8;
+
+	asm(
+		"	add	%1,%0		\n"
+		"	addc	%2,%0		\n"
+		"	addc	%3,%0		\n"
+		"	addc	0,%0		\n"
+		: "=r" (sum)
+		: "r" (daddr), "r"(saddr), "r"(tmp), "0"(sum)
+		: "cc"
+	    );
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(unsigned long saddr,
+					unsigned long daddr,
+					unsigned short len,
+					unsigned short proto,
+					__wsum sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+#undef _HAVE_ARCH_IPV6_CSUM
+
+/*
+ *	Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+extern __wsum csum_and_copy_to_user(const void *src, void *dst, int len,
+				    __wsum sum, int *err_ptr);
+
+
+#endif /* _ASM_CHECKSUM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cpu-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cpu-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cpu-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cpu-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,290 @@
+/* MN10300 Core system registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_CPU_REGS_H
+#define _ASM_CPU_REGS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
+
+#ifdef CONFIG_MN10300_CPU_AM33V2
+/* we tell the compiler to pretend to be AM33 so that it doesn't try and use
+ * the FP regs, but tell the assembler that we're actually allowed AM33v2
+ * instructions */
+#ifndef __ASSEMBLY__
+asm(" .am33_2\n");
+#else
+.am33_2
+#endif
+#endif
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#define __SYSREG(ADDR, TYPE) (*(volatile TYPE *)(ADDR))
+#define __SYSREGC(ADDR, TYPE) (*(const volatile TYPE *)(ADDR))
+#else
+#define __SYSREG(ADDR, TYPE) ADDR
+#define __SYSREGC(ADDR, TYPE) ADDR
+#endif
+
+/* CPU registers */
+#define EPSW_FLAG_Z		0x00000001	/* zero flag */
+#define EPSW_FLAG_N		0x00000002	/* negative flag */
+#define EPSW_FLAG_C		0x00000004	/* carry flag */
+#define EPSW_FLAG_V		0x00000008	/* overflow flag */
+#define EPSW_IM			0x00000700	/* interrupt mode */
+#define EPSW_IM_0		0x00000000	/* interrupt mode 0 */
+#define EPSW_IM_1		0x00000100	/* interrupt mode 1 */
+#define EPSW_IM_2		0x00000200	/* interrupt mode 2 */
+#define EPSW_IM_3		0x00000300	/* interrupt mode 3 */
+#define EPSW_IM_4		0x00000400	/* interrupt mode 4 */
+#define EPSW_IM_5		0x00000500	/* interrupt mode 5 */
+#define EPSW_IM_6		0x00000600	/* interrupt mode 6 */
+#define EPSW_IM_7		0x00000700	/* interrupt mode 7 */
+#define EPSW_IE			0x00000800	/* interrupt enable */
+#define EPSW_S			0x00003000	/* software auxilliary bits */
+#define EPSW_T			0x00008000	/* trace enable */
+#define EPSW_nSL		0x00010000	/* not supervisor level */
+#define EPSW_NMID		0x00020000	/* nonmaskable interrupt disable */
+#define EPSW_nAR		0x00040000	/* register bank control */
+#define EPSW_ML			0x00080000	/* monitor level */
+#define EPSW_FE			0x00100000	/* FPU enable */
+
+/* FPU registers */
+#define FPCR_EF_I		0x00000001	/* inexact result FPU exception flag */
+#define FPCR_EF_U		0x00000002	/* underflow FPU exception flag */
+#define FPCR_EF_O		0x00000004	/* overflow FPU exception flag */
+#define FPCR_EF_Z		0x00000008	/* zero divide FPU exception flag */
+#define FPCR_EF_V		0x00000010	/* invalid operand FPU exception flag */
+#define FPCR_EE_I		0x00000020	/* inexact result FPU exception enable */
+#define FPCR_EE_U		0x00000040	/* underflow FPU exception enable */
+#define FPCR_EE_O		0x00000080	/* overflow FPU exception enable */
+#define FPCR_EE_Z		0x00000100	/* zero divide FPU exception enable */
+#define FPCR_EE_V		0x00000200	/* invalid operand FPU exception enable */
+#define FPCR_EC_I		0x00000400	/* inexact result FPU exception cause */
+#define FPCR_EC_U		0x00000800	/* underflow FPU exception cause */
+#define FPCR_EC_O		0x00001000	/* overflow FPU exception cause */
+#define FPCR_EC_Z		0x00002000	/* zero divide FPU exception cause */
+#define FPCR_EC_V		0x00004000	/* invalid operand FPU exception cause */
+#define FPCR_RM			0x00030000	/* rounding mode */
+#define FPCR_RM_NEAREST		0x00000000	/* - round to nearest value */
+#define FPCR_FCC_U		0x00040000	/* FPU unordered condition code */
+#define FPCR_FCC_E		0x00080000	/* FPU equal condition code */
+#define FPCR_FCC_G		0x00100000	/* FPU greater than condition code */
+#define FPCR_FCC_L		0x00200000	/* FPU less than condition code */
+#define FPCR_INIT		0x00000000	/* no exceptions, rounding to nearest */
+
+/* CPU control registers */
+#define CPUP			__SYSREG(0xc0000020, u16)	/* CPU pipeline register */
+#define CPUP_DWBD		0x0020		/* write buffer disable flag */
+#define CPUP_IPFD		0x0040		/* instruction prefetch disable flag */
+#define CPUP_EXM		0x0080		/* exception operation mode */
+#define CPUP_EXM_AM33V1		0x0000		/* - AM33 v1 exception mode */
+#define CPUP_EXM_AM33V2		0x0080		/* - AM33 v2 exception mode */
+
+#define CPUM			__SYSREG(0xc0000040, u16)	/* CPU mode register */
+#define CPUM_SLEEP		0x0004		/* set to enter sleep state */
+#define CPUM_HALT		0x0008		/* set to enter halt state */
+#define CPUM_STOP		0x0010		/* set to enter stop state */
+
+#define CPUREV			__SYSREGC(0xc0000050, u32)	/* CPU revision register */
+#define CPUREV_TYPE		0x0000000f	/* CPU type */
+#define CPUREV_TYPE_S		0
+#define CPUREV_TYPE_AM33V1	0x00000000	/* - AM33 V1 core, AM33/1.00 arch */
+#define CPUREV_TYPE_AM33V2	0x00000001	/* - AM33 V2 core, AM33/2.00 arch */
+#define CPUREV_TYPE_AM34V1	0x00000002	/* - AM34 V1 core, AM33/2.00 arch */
+#define CPUREV_REVISION		0x000000f0	/* CPU revision */
+#define CPUREV_REVISION_S	4
+#define CPUREV_ICWAY		0x00000f00	/* number of instruction cache ways */
+#define CPUREV_ICWAY_S		8
+#define CPUREV_ICSIZE		0x0000f000	/* instruction cache way size */
+#define CPUREV_ICSIZE_S		12
+#define CPUREV_DCWAY		0x000f0000	/* number of data cache ways */
+#define CPUREV_DCWAY_S		16
+#define CPUREV_DCSIZE		0x00f00000	/* data cache way size */
+#define CPUREV_DCSIZE_S		20
+#define CPUREV_FPUTYPE		0x0f000000	/* FPU core type */
+#define CPUREV_FPUTYPE_NONE	0x00000000	/* - no FPU core implemented */
+#define CPUREV_OCDCTG		0xf0000000	/* on-chip debug function category */
+
+#define DCR			__SYSREG(0xc0000030, u16)	/* Debug control register */
+
+/* interrupt/exception control registers */
+#define IVAR0			__SYSREG(0xc0000000, u16)	/* interrupt vector 0 */
+#define IVAR1			__SYSREG(0xc0000004, u16)	/* interrupt vector 1 */
+#define IVAR2			__SYSREG(0xc0000008, u16)	/* interrupt vector 2 */
+#define IVAR3			__SYSREG(0xc000000c, u16)	/* interrupt vector 3 */
+#define IVAR4			__SYSREG(0xc0000010, u16)	/* interrupt vector 4 */
+#define IVAR5			__SYSREG(0xc0000014, u16)	/* interrupt vector 5 */
+#define IVAR6			__SYSREG(0xc0000018, u16)	/* interrupt vector 6 */
+
+#define TBR			__SYSREG(0xc0000024, u32)	/* Trap table base */
+#define TBR_TB			0xff000000	/* table base address bits 31-24 */
+#define TBR_INT_CODE		0x00ffffff	/* interrupt code */
+
+#define DEAR			__SYSREG(0xc0000038, u32)	/* Data access exception address */
+
+#define sISR			__SYSREG(0xc0000044, u32)	/* Supervisor interrupt status */
+#define	sISR_IRQICE		0x00000001	/* ICE interrupt */
+#define	sISR_ISTEP		0x00000002	/* single step interrupt */
+#define	sISR_MISSA		0x00000004	/* memory access address misalignment fault */
+#define	sISR_UNIMP		0x00000008	/* unimplemented instruction execution fault */
+#define	sISR_PIEXE		0x00000010	/* program interrupt */
+#define	sISR_MEMERR		0x00000020	/* illegal memory access fault */
+#define	sISR_IBREAK		0x00000040	/* instraction break interrupt */
+#define	sISR_DBSRL		0x00000080	/* debug serial interrupt */
+#define	sISR_PERIDB		0x00000100	/* peripheral debug interrupt */
+#define	sISR_EXUNIMP		0x00000200	/* unimplemented ex-instruction execution fault */
+#define	sISR_OBREAK		0x00000400	/* operand break interrupt */
+#define	sISR_PRIV		0x00000800	/* privileged instruction execution fault */
+#define	sISR_BUSERR		0x00001000	/* bus error fault */
+#define	sISR_DBLFT		0x00002000	/* double fault */
+#define	sISR_DBG		0x00008000	/* debug reserved interrupt */
+#define sISR_ITMISS		0x00010000	/* instruction TLB miss */
+#define sISR_DTMISS		0x00020000	/* data TLB miss */
+#define sISR_ITEX		0x00040000	/* instruction TLB access exception */
+#define sISR_DTEX		0x00080000	/* data TLB access exception */
+#define sISR_ILGIA		0x00100000	/* illegal instruction access exception */
+#define sISR_ILGDA		0x00200000	/* illegal data access exception */
+#define sISR_IOIA		0x00400000	/* internal I/O space instruction access excep */
+#define sISR_PRIVA		0x00800000	/* privileged space instruction access excep */
+#define sISR_PRIDA		0x01000000	/* privileged space data access excep */
+#define sISR_DISA		0x02000000	/* data space instruction access excep */
+#define sISR_SYSC		0x04000000	/* system call instruction excep */
+#define sISR_FPUD		0x08000000	/* FPU disabled excep */
+#define sISR_FPUUI		0x10000000	/* FPU unimplemented instruction excep */
+#define sISR_FPUOP		0x20000000	/* FPU operation excep */
+#define sISR_NE			0x80000000	/* multiple synchronous exceptions excep */
+
+/* cache control registers */
+#define CHCTR			__SYSREG(0xc0000070, u16)	/* cache control */
+#define CHCTR_ICEN		0x0001		/* instruction cache enable */
+#define CHCTR_DCEN		0x0002		/* data cache enable */
+#define CHCTR_ICBUSY		0x0004		/* instruction cache busy */
+#define CHCTR_DCBUSY		0x0008		/* data cache busy */
+#define CHCTR_ICINV		0x0010		/* instruction cache invalidate */
+#define CHCTR_DCINV		0x0020		/* data cache invalidate */
+#define CHCTR_DCWTMD		0x0040		/* data cache writing mode */
+#define CHCTR_DCWTMD_WRBACK	0x0000		/* - write back mode */
+#define CHCTR_DCWTMD_WRTHROUGH	0x0040		/* - write through mode */
+#define CHCTR_DCALMD		0x0080		/* data cache allocation mode */
+#define CHCTR_ICWMD		0x0f00		/* instruction cache way mode */
+#define CHCTR_DCWMD		0xf000		/* data cache way mode */
+
+/* MMU control registers */
+#define MMUCTR			__SYSREG(0xc0000090, u32)	/* MMU control register */
+#define MMUCTR_IRP		0x0000003f	/* instruction TLB replace pointer */
+#define MMUCTR_ITE		0x00000040	/* instruction TLB enable */
+#define MMUCTR_IIV		0x00000080	/* instruction TLB invalidate */
+#define MMUCTR_ITL		0x00000700	/* instruction TLB lock pointer */
+#define MMUCTR_ITL_NOLOCK	0x00000000	/* - no lock */
+#define MMUCTR_ITL_LOCK0	0x00000100	/* - entry 0 locked */
+#define MMUCTR_ITL_LOCK0_1	0x00000200	/* - entry 0-1 locked */
+#define MMUCTR_ITL_LOCK0_3	0x00000300	/* - entry 0-3 locked */
+#define MMUCTR_ITL_LOCK0_7	0x00000400	/* - entry 0-7 locked */
+#define MMUCTR_ITL_LOCK0_15	0x00000500	/* - entry 0-15 locked */
+#define MMUCTR_CE		0x00008000	/* cacheable bit enable */
+#define MMUCTR_DRP		0x003f0000	/* data TLB replace pointer */
+#define MMUCTR_DTE		0x00400000	/* data TLB enable */
+#define MMUCTR_DIV		0x00800000	/* data TLB invalidate */
+#define MMUCTR_DTL		0x07000000	/* data TLB lock pointer */
+#define MMUCTR_DTL_NOLOCK	0x00000000	/* - no lock */
+#define MMUCTR_DTL_LOCK0	0x01000000	/* - entry 0 locked */
+#define MMUCTR_DTL_LOCK0_1	0x02000000	/* - entry 0-1 locked */
+#define MMUCTR_DTL_LOCK0_3	0x03000000	/* - entry 0-3 locked */
+#define MMUCTR_DTL_LOCK0_7	0x04000000	/* - entry 0-7 locked */
+#define MMUCTR_DTL_LOCK0_15	0x05000000	/* - entry 0-15 locked */
+
+#define PIDR			__SYSREG(0xc0000094, u16)	/* PID register */
+#define PIDR_PID		0x00ff		/* process identifier */
+
+#define PTBR			__SYSREG(0xc0000098, unsigned long) /* Page table base register */
+
+#define IPTEL			__SYSREG(0xc00000a0, u32)	/* instruction TLB entry */
+#define DPTEL			__SYSREG(0xc00000b0, u32)	/* data TLB entry */
+#define xPTEL_V			0x00000001	/* TLB entry valid */
+#define xPTEL_UNUSED1		0x00000002	/* unused bit */
+#define xPTEL_UNUSED2		0x00000004	/* unused bit */
+#define xPTEL_C			0x00000008	/* cached if set */
+#define xPTEL_PV		0x00000010	/* page valid */
+#define xPTEL_D			0x00000020	/* dirty */
+#define xPTEL_PR		0x000001c0	/* page protection */
+#define xPTEL_PR_ROK		0x00000000	/* - R/O kernel */
+#define xPTEL_PR_RWK		0x00000100	/* - R/W kernel */
+#define xPTEL_PR_ROK_ROU	0x00000080	/* - R/O kernel and R/O user */
+#define xPTEL_PR_RWK_ROU	0x00000180	/* - R/W kernel and R/O user */
+#define xPTEL_PR_RWK_RWU	0x000001c0	/* - R/W kernel and R/W user */
+#define xPTEL_G			0x00000200	/* global (use PID if 0) */
+#define xPTEL_PS		0x00000c00	/* page size */
+#define xPTEL_PS_4Kb		0x00000000	/* - 4Kb page */
+#define xPTEL_PS_128Kb		0x00000400	/* - 128Kb page */
+#define xPTEL_PS_1Kb		0x00000800	/* - 1Kb page */
+#define xPTEL_PS_4Mb		0x00000c00	/* - 4Mb page */
+#define xPTEL_PPN		0xfffff006	/* physical page number */
+
+#define xPTEL_V_BIT		0	/* bit numbers corresponding to above masks */
+#define xPTEL_UNUSED1_BIT	1
+#define xPTEL_UNUSED2_BIT	2
+#define xPTEL_C_BIT		3
+#define xPTEL_PV_BIT		4
+#define xPTEL_D_BIT		5
+#define xPTEL_G_BIT		9
+
+#define IPTEU			__SYSREG(0xc00000a4, u32)	/* instruction TLB virtual addr */
+#define DPTEU			__SYSREG(0xc00000b4, u32)	/* data TLB virtual addr */
+#define xPTEU_VPN		0xfffffc00	/* virtual page number */
+#define xPTEU_PID		0x000000ff	/* process identifier to which applicable */
+
+#define IPTEL2			__SYSREG(0xc00000a8, u32)	/* instruction TLB entry */
+#define DPTEL2			__SYSREG(0xc00000b8, u32)	/* data TLB entry */
+#define xPTEL2_V		0x00000001	/* TLB entry valid */
+#define xPTEL2_C		0x00000002	/* cacheable */
+#define xPTEL2_PV		0x00000004	/* page valid */
+#define xPTEL2_D		0x00000008	/* dirty */
+#define xPTEL2_PR		0x00000070	/* page protection */
+#define xPTEL2_PR_ROK		0x00000000	/* - R/O kernel */
+#define xPTEL2_PR_RWK		0x00000040	/* - R/W kernel */
+#define xPTEL2_PR_ROK_ROU	0x00000020	/* - R/O kernel and R/O user */
+#define xPTEL2_PR_RWK_ROU	0x00000060	/* - R/W kernel and R/O user */
+#define xPTEL2_PR_RWK_RWU	0x00000070	/* - R/W kernel and R/W user */
+#define xPTEL2_G		0x00000080	/* global (use PID if 0) */
+#define xPTEL2_PS		0x00000300	/* page size */
+#define xPTEL2_PS_4Kb		0x00000000	/* - 4Kb page */
+#define xPTEL2_PS_128Kb		0x00000100	/* - 128Kb page */
+#define xPTEL2_PS_1Kb		0x00000200	/* - 1Kb page */
+#define xPTEL2_PS_4Mb		0x00000300	/* - 4Mb page */
+#define xPTEL2_PPN		0xfffffc00	/* physical page number */
+
+#define MMUFCR			__SYSREGC(0xc000009c, u32)	/* MMU exception cause */
+#define MMUFCR_IFC		__SYSREGC(0xc000009c, u16)	/* MMU instruction excep cause */
+#define MMUFCR_DFC		__SYSREGC(0xc000009e, u16)	/* MMU data exception cause */
+#define MMUFCR_xFC_TLBMISS	0x0001		/* TLB miss flag */
+#define MMUFCR_xFC_INITWR	0x0002		/* initial write excep flag */
+#define MMUFCR_xFC_PGINVAL	0x0004		/* page invalid excep flag */
+#define MMUFCR_xFC_PROTVIOL	0x0008		/* protection violation excep flag */
+#define MMUFCR_xFC_ACCESS	0x0010		/* access level flag */
+#define MMUFCR_xFC_ACCESS_USR	0x0000		/* - user mode */
+#define MMUFCR_xFC_ACCESS_SR	0x0010		/* - supervisor mode */
+#define MMUFCR_xFC_TYPE		0x0020		/* access type flag */
+#define MMUFCR_xFC_TYPE_READ	0x0000		/* - read */
+#define MMUFCR_xFC_TYPE_WRITE	0x0020		/* - write */
+#define MMUFCR_xFC_PR		0x01c0		/* page protection flag */
+#define MMUFCR_xFC_PR_ROK	0x0000		/* - R/O kernel */
+#define MMUFCR_xFC_PR_RWK	0x0100		/* - R/W kernel */
+#define MMUFCR_xFC_PR_ROK_ROU	0x0080		/* - R/O kernel and R/O user */
+#define MMUFCR_xFC_PR_RWK_ROU	0x0180		/* - R/W kernel and R/O user */
+#define MMUFCR_xFC_PR_RWK_RWU	0x01c0		/* - R/W kernel and R/W user */
+#define MMUFCR_xFC_ILLADDR	0x0200		/* illegal address excep flag */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_CPU_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cputime.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cputime.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/cputime.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/cputime.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/current.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/current.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+/* MN10300 Current task structure accessor
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#include <linux/thread_info.h>
+
+/*
+ * dedicate E2 to keeping the current task pointer
+ */
+#ifdef CONFIG_MN10300_CURRENT_IN_E2
+
+register struct task_struct *const current asm("e2") __attribute__((used));
+
+#define get_current() current
+
+extern struct task_struct *__current;
+
+#else
+static inline __attribute__((const))
+struct task_struct *get_current(void)
+{
+	return current_thread_info()->task;
+}
+
+#define current get_current()
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/delay.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/delay.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/delay.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/delay.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+/* MN10300 Uninterruptible delay routines
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+extern void __udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) __udelay(n)
+
+#endif /* _ASM_DELAY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/device.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/device.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/device.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/div64.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/div64.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/div64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/div64.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,100 @@
+/* MN10300 64-bit division
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_DIV64
+#define _ASM_DIV64
+
+#include <linux/types.h>
+
+extern void ____unhandled_size_in_do_div___(void);
+
+/*
+ * divide n by base, leaving the result in n and returning the remainder
+ * - we can do this quite efficiently on the MN10300 by cascading the divides
+ *   through the MDR register
+ */
+#define do_div(n, base)							\
+({									\
+	unsigned __rem = 0;						\
+	if (sizeof(n) <= 4) {						\
+		asm("mov	%1,mdr	\n"				\
+		    "divu	%2,%0	\n"				\
+		    "mov	mdr,%1	\n"				\
+		    : "+r"(n), "=d"(__rem)				\
+		    : "r"(base), "1"(__rem)				\
+		    : "cc"						\
+		    );							\
+	} else if (sizeof(n) <= 8) {					\
+		union {							\
+			unsigned long long l;				\
+			u32 w[2];					\
+		} __quot;						\
+		__quot.l = n;						\
+		asm("mov	%0,mdr	\n"	/* MDR = 0 */		\
+		    "divu	%3,%1	\n"				\
+		    /* __quot.MSL = __div.MSL / base, */		\
+		    /* MDR = MDR:__div.MSL % base */			\
+		    "divu	%3,%2	\n"				\
+		    /* __quot.LSL = MDR:__div.LSL / base, */		\
+		    /* MDR = MDR:__div.LSL % base */			\
+		    "mov	mdr,%0	\n"				\
+		    : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0])	\
+		    : "r"(base), "0"(__rem), "1"(__quot.w[1]),		\
+		      "2"(__quot.w[0])					\
+		    : "cc"						\
+		    );							\
+		n = __quot.l;						\
+	} else {							\
+		____unhandled_size_in_do_div___();			\
+	}								\
+	__rem;								\
+})
+
+/*
+ * do an unsigned 32-bit multiply and divide with intermediate 64-bit product
+ * so as not to lose accuracy
+ * - we use the MDR register to hold the MSW of the product
+ */
+static inline __attribute__((const))
+unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
+{
+	unsigned result;
+
+	asm("mulu	%2,%0	\n"	/* MDR:val = val*mult */
+	    "divu	%3,%0	\n"	/* val = MDR:val/div;
+					 * MDR = MDR:val%div */
+	    : "=r"(result)
+	    : "0"(val), "ir"(mult), "r"(div)
+	    );
+
+	return result;
+}
+
+/*
+ * do a signed 32-bit multiply and divide with intermediate 64-bit product so
+ * as not to lose accuracy
+ * - we use the MDR register to hold the MSW of the product
+ */
+static inline __attribute__((const))
+signed __muldiv64s(signed val, signed mult, signed div)
+{
+	signed result;
+
+	asm("mul	%2,%0	\n"	/* MDR:val = val*mult */
+	    "div	%3,%0	\n"	/* val = MDR:val/div;
+					 * MDR = MDR:val%div */
+	    : "=r"(result)
+	    : "0"(val), "ir"(mult), "r"(div)
+	    );
+
+	return result;
+}
+
+#endif /* _ASM_DIV64 */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dmactl-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dmactl-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dmactl-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dmactl-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,101 @@
+/* MN10300 on-board DMA controller registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_DMACTL_REGS_H
+#define _ASM_DMACTL_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+/* DMA registers */
+#define	DMxCTR(N)		__SYSREG(0xd2000000 + ((N) * 0x100), u32)	/* control reg */
+#define	DMxCTR_BG		0x0000001f	/* transfer request source */
+#define	DMxCTR_BG_SOFT		0x00000000	/* - software source */
+#define	DMxCTR_BG_SC0TX		0x00000002	/* - serial port 0 transmission */
+#define	DMxCTR_BG_SC0RX		0x00000003	/* - serial port 0 reception */
+#define	DMxCTR_BG_SC1TX		0x00000004	/* - serial port 1 transmission */
+#define	DMxCTR_BG_SC1RX		0x00000005	/* - serial port 1 reception */
+#define	DMxCTR_BG_SC2TX		0x00000006	/* - serial port 2 transmission */
+#define	DMxCTR_BG_SC2RX		0x00000007	/* - serial port 2 reception */
+#define	DMxCTR_BG_TM0UFLOW	0x00000008	/* - timer 0 underflow */
+#define	DMxCTR_BG_TM1UFLOW	0x00000009	/* - timer 1 underflow */
+#define	DMxCTR_BG_TM2UFLOW	0x0000000a	/* - timer 2 underflow */
+#define	DMxCTR_BG_TM3UFLOW	0x0000000b	/* - timer 3 underflow */
+#define	DMxCTR_BG_TM6ACMPCAP	0x0000000c	/* - timer 6A compare/capture */
+#define	DMxCTR_BG_AFE		0x0000000d	/* - analogue front-end interrupt source */
+#define	DMxCTR_BG_ADC		0x0000000e	/* - A/D conversion end interrupt source */
+#define	DMxCTR_BG_IRDA		0x0000000f	/* - IrDA interrupt source */
+#define	DMxCTR_BG_RTC		0x00000010	/* - RTC interrupt source */
+#define	DMxCTR_BG_XIRQ0		0x00000011	/* - XIRQ0 pin interrupt source */
+#define	DMxCTR_BG_XIRQ1		0x00000012	/* - XIRQ1 pin interrupt source */
+#define	DMxCTR_BG_XDMR0		0x00000013	/* - external request 0 source (XDMR0 pin) */
+#define	DMxCTR_BG_XDMR1		0x00000014	/* - external request 1 source (XDMR1 pin) */
+#define	DMxCTR_SAM		0x000000e0	/* DMA transfer src addr mode */
+#define	DMxCTR_SAM_INCR		0x00000000	/* - increment */
+#define	DMxCTR_SAM_DECR		0x00000020	/* - decrement */
+#define	DMxCTR_SAM_FIXED	0x00000040	/* - fixed */
+#define	DMxCTR_DAM		0x00000000	/* DMA transfer dest addr mode */
+#define	DMxCTR_DAM_INCR		0x00000000	/* - increment */
+#define	DMxCTR_DAM_DECR		0x00000100	/* - decrement */
+#define	DMxCTR_DAM_FIXED	0x00000200	/* - fixed */
+#define	DMxCTR_TM		0x00001800	/* DMA transfer mode */
+#define	DMxCTR_TM_BATCH		0x00000000	/* - batch transfer */
+#define	DMxCTR_TM_INTERM	0x00001000	/* - intermittent transfer */
+#define	DMxCTR_UT		0x00006000	/* DMA transfer unit */
+#define	DMxCTR_UT_1		0x00000000	/* - 1 byte */
+#define	DMxCTR_UT_2		0x00002000	/* - 2 byte */
+#define	DMxCTR_UT_4		0x00004000	/* - 4 byte */
+#define	DMxCTR_UT_16		0x00006000	/* - 16 byte */
+#define	DMxCTR_TEN		0x00010000	/* DMA channel transfer enable */
+#define	DMxCTR_RQM		0x00060000	/* external request input source mode */
+#define	DMxCTR_RQM_FALLEDGE	0x00000000	/* - falling edge */
+#define	DMxCTR_RQM_RISEEDGE	0x00020000	/* - rising edge */
+#define	DMxCTR_RQM_LOLEVEL	0x00040000	/* - low level */
+#define	DMxCTR_RQM_HILEVEL	0x00060000	/* - high level */
+#define	DMxCTR_RQF		0x01000000	/* DMA transfer request flag */
+#define	DMxCTR_XEND		0x80000000	/* DMA transfer end flag */
+
+#define	DMxSRC(N)		__SYSREG(0xd2000004 + ((N) * 0x100), u32)	/* control reg */
+
+#define	DMxDST(N)		__SYSREG(0xd2000008 + ((N) * 0x100), u32)	/* src addr reg */
+
+#define	DMxSIZ(N)		__SYSREG(0xd200000c + ((N) * 0x100), u32)	/* dest addr reg */
+#define DMxSIZ_CT		0x000fffff	/* number of bytes to transfer */
+
+#define	DMxCYC(N)		__SYSREG(0xd2000010 + ((N) * 0x100), u32)	/* intermittent
+										 * size reg */
+#define DMxCYC_CYC		0x000000ff	/* number of interrmittent transfers -1 */
+
+#define DM0IRQ			16		/* DMA channel 0 complete IRQ */
+#define DM1IRQ			17		/* DMA channel 1 complete IRQ */
+#define DM2IRQ			18		/* DMA channel 2 complete IRQ */
+#define DM3IRQ			19		/* DMA channel 3 complete IRQ */
+
+#define	DM0ICR			GxICR(DM0IRQ)	/* DMA channel 0 complete intr ctrl reg */
+#define	DM1ICR			GxICR(DM0IR1)	/* DMA channel 1 complete intr ctrl reg */
+#define	DM2ICR			GxICR(DM0IR2)	/* DMA channel 2 complete intr ctrl reg */
+#define	DM3ICR			GxICR(DM0IR3)	/* DMA channel 3 complete intr ctrl reg */
+
+#ifndef __ASSEMBLY__
+
+struct mn10300_dmactl_regs {
+	u32		ctr;
+	const void	*src;
+	void		*dst;
+	u32		siz;
+	u32		cyc;
+} __attribute__((aligned(0x100)));
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_DMACTL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,118 @@
+/* MN10300 ISA DMA handlers and definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <asm/system.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+
+#undef MAX_DMA_CHANNELS		/* switch off linux/kernel/dma.c */
+#define MAX_DMA_ADDRESS		0xbfffffff
+
+extern spinlock_t dma_spin_lock;
+
+static inline unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static inline void enable_dma(unsigned int dmanr)
+{
+}
+
+static inline void disable_dma(unsigned int dmanr)
+{
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static inline void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static inline void set_dma_mode(unsigned int dmanr, char mode)
+{
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static inline void set_dma_page(unsigned int dmanr, char pagenr)
+{
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static inline void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static inline int get_dma_residue(unsigned int dmanr)
+{
+	return 0;
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char *device_id);
+extern void free_dma(unsigned int dmanr);
+
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/dma-mapping.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,234 @@
+/* DMA mapping routines for the MN10300 arch
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+extern void *dma_alloc_coherent(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, int flag);
+
+extern void dma_free_coherent(struct device *dev, size_t size,
+			      void *vaddr, dma_addr_t dma_handle);
+
+#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))
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.  The
+ * 32-bit bus address to use is returned.
+ *
+ * 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.
+ */
+static inline
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+			  enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	mn10300_dcache_flush_inv();
+	return virt_to_bus(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 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		      enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+/*
+ * 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 dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
+	       enum dma_data_direction direction)
+{
+	struct scatterlist *sg;
+	int i;
+
+	BUG_ON(!valid_dma_direction(direction));
+	WARN_ON(nents == 0 || sglist[0].length == 0);
+
+	for_each_sg(sglist, sg, nents, i) {
+		BUG_ON(!sg_page(sg));
+
+		sg->dma_address = sg_phys(sg);
+	}
+
+	mn10300_dcache_flush_inv();
+	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 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+		  enum dma_data_direction direction)
+{
+	BUG_ON(!valid_dma_direction(direction));
+}
+
+/*
+ * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
+ * to pci_map_single, but takes a struct page instead of a virtual address
+ */
+static inline
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+			unsigned long offset, size_t size,
+			enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	return page_to_bus(page) + offset;
+}
+
+static inline
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+		    enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+/*
+ * 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 dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+			     size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+				size_t size, enum dma_data_direction direction)
+{
+	mn10300_dcache_flush_inv();
+}
+
+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)
+{
+}
+
+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)
+{
+	mn10300_dcache_flush_inv();
+}
+
+
+/*
+ * 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 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			 int nelems, enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			    int nelems, enum dma_data_direction direction)
+{
+	mn10300_dcache_flush_inv();
+}
+
+static inline
+int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+/*
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits during
+ * PCI bus mastering, then you would pass 0x00ffffff as the mask to this
+ * function.
+ */
+static inline
+int 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 < 0x00ffffff)
+		return 0;
+	return 1;
+}
+
+static inline
+int dma_set_mask(struct device *dev, u64 mask)
+{
+	if (!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+	return 0;
+}
+
+static inline
+int dma_get_cache_alignment(void)
+{
+	return 1 << L1_CACHE_SHIFT;
+}
+
+#define dma_is_consistent(d)	(1)
+
+static inline
+void dma_cache_sync(void *vaddr, size_t size,
+		    enum dma_data_direction direction)
+{
+	mn10300_dcache_flush_inv();
+}
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/elf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,147 @@
+/* MN10300 ELF constant and register definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_ELF_H
+#define _ASM_ELF_H
+
+#include <linux/utsname.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/*
+ * AM33 relocations
+ */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+
+/*
+ * ELF register definitions..
+ */
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#define ELF_NFPREG 32
+typedef float elf_fpreg_t;
+
+typedef struct {
+	elf_fpreg_t	fpregs[ELF_NFPREG];
+	u_int32_t	fpcr;
+} elf_fpregset_t;
+
+extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture
+ */
+#define elf_check_arch(x) \
+	(((x)->e_machine == EM_CYGNUS_MN10300) ||	\
+	 ((x)->e_machine == EM_MN10300))
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_MN10300
+
+/*
+ * ELF process initialiser
+ */
+#define ELF_PLAT_INIT(_r, load_addr)					\
+do {									\
+	struct pt_regs *_ur = current->thread.uregs;			\
+	_ur->a3   = 0;	_ur->a2   = 0;	_ur->d3   = 0;	_ur->d2   = 0;	\
+	_ur->mcvf = 0;	_ur->mcrl = 0;	_ur->mcrh = 0;	_ur->mdrq = 0;	\
+	_ur->e1   = 0;	_ur->e0   = 0;	_ur->e7   = 0;	_ur->e6   = 0;	\
+	_ur->e5   = 0;	_ur->e4   = 0;	_ur->e3   = 0;	_ur->e2   = 0;	\
+	_ur->lar  = 0;	_ur->lir  = 0;	_ur->mdr  = 0;			\
+	_ur->a1   = 0;	_ur->a0   = 0;	_ur->d1   = 0;	_ur->d0   = 0;	\
+} while (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
+ * use of this is to invoke "./ld.so someprog" to test out a new version of
+ * the loader.  We need to make sure that it is out of the way of the program
+ * that it will "exec", and that there is sufficient room for the brk.
+ * - must clear the VMALLOC area
+ */
+#define ELF_ET_DYN_BASE         0x04000000
+
+/*
+ * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
+ * now struct user_regs, they are different)
+ * - ELF_CORE_COPY_REGS has been guessed, and may be wrong
+ */
+#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
+do {						\
+	pr_reg[0]	= regs->a3;		\
+	pr_reg[1]	= regs->a2;		\
+	pr_reg[2]	= regs->d3;		\
+	pr_reg[3]	= regs->d2;		\
+	pr_reg[4]	= regs->mcvf;		\
+	pr_reg[5]	= regs->mcrl;		\
+	pr_reg[6]	= regs->mcrh;		\
+	pr_reg[7]	= regs->mdrq;		\
+	pr_reg[8]	= regs->e1;		\
+	pr_reg[9]	= regs->e0;		\
+	pr_reg[10]	= regs->e7;		\
+	pr_reg[11]	= regs->e6;		\
+	pr_reg[12]	= regs->e5;		\
+	pr_reg[13]	= regs->e4;		\
+	pr_reg[14]	= regs->e3;		\
+	pr_reg[15]	= regs->e2;		\
+	pr_reg[16]	= regs->sp;		\
+	pr_reg[17]	= regs->lar;		\
+	pr_reg[18]	= regs->lir;		\
+	pr_reg[19]	= regs->mdr;		\
+	pr_reg[20]	= regs->a1;		\
+	pr_reg[21]	= regs->a0;		\
+	pr_reg[22]	= regs->d1;		\
+	pr_reg[23]	= regs->d0;		\
+	pr_reg[24]	= regs->orig_d0;	\
+	pr_reg[25]	= regs->epsw;		\
+	pr_reg[26]	= regs->pc;		\
+} while (0);
+
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this CPU supports.  This could be done in user space,
+ * but it's not easy, and we've already done it here.
+ */
+#define ELF_HWCAP	(0)
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ *
+ * For the moment, we have only optimizations for the Intel generations,
+ * but that could change...
+ */
+#define ELF_PLATFORM  (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#endif
+
+#endif /* _ASM_ELF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/emergency-restart.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/emergency-restart.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/emergency-restart.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/emergency-restart.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/errno.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/errno.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/errno.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/errno.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/exceptions.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/exceptions.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/exceptions.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/exceptions.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,121 @@
+/* MN10300 Microcontroller core exceptions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_EXCEPTIONS_H
+#define _ASM_EXCEPTIONS_H
+
+#include <linux/linkage.h>
+
+/*
+ * define the breakpoint instruction opcode to use
+ * - note that the JTAG unit steals 0xFF, so we want to avoid that if we can
+ *   (can use 0xF7)
+ */
+#define GDBSTUB_BKPT		0xFF
+
+#ifndef __ASSEMBLY__
+
+/*
+ * enumeration of exception codes (as extracted from TBR MSW)
+ */
+enum exception_code {
+	EXCEP_RESET		= 0x000000,	/* reset */
+
+	/* MMU exceptions */
+	EXCEP_ITLBMISS		= 0x000100,	/* instruction TLB miss */
+	EXCEP_DTLBMISS		= 0x000108,	/* data TLB miss */
+	EXCEP_IAERROR		= 0x000110,	/* instruction address */
+	EXCEP_DAERROR		= 0x000118,	/* data address */
+
+	/* system exceptions */
+	EXCEP_TRAP		= 0x000128,	/* program interrupt (PI instruction) */
+	EXCEP_ISTEP		= 0x000130,	/* single step */
+	EXCEP_IBREAK		= 0x000150,	/* instruction breakpoint */
+	EXCEP_OBREAK		= 0x000158,	/* operand breakpoint */
+	EXCEP_PRIVINS		= 0x000160,	/* privileged instruction execution */
+	EXCEP_UNIMPINS		= 0x000168,	/* unimplemented instruction execution */
+	EXCEP_UNIMPEXINS	= 0x000170,	/* unimplemented extended instruction execution */
+	EXCEP_MEMERR		= 0x000178,	/* illegal memory access */
+	EXCEP_MISALIGN		= 0x000180,	/* misalignment */
+	EXCEP_BUSERROR		= 0x000188,	/* bus error */
+	EXCEP_ILLINSACC		= 0x000190,	/* illegal instruction access */
+	EXCEP_ILLDATACC		= 0x000198,	/* illegal data access */
+	EXCEP_IOINSACC		= 0x0001a0,	/* I/O space instruction access */
+	EXCEP_PRIVINSACC	= 0x0001a8,	/* privileged space instruction access */
+	EXCEP_PRIVDATACC	= 0x0001b0,	/* privileged space data access */
+	EXCEP_DATINSACC		= 0x0001b8,	/* data space instruction access */
+	EXCEP_DOUBLE_FAULT	= 0x000200,	/* double fault */
+
+	/* FPU exceptions */
+	EXCEP_FPU_DISABLED	= 0x0001c0,	/* FPU disabled */
+	EXCEP_FPU_UNIMPINS	= 0x0001c8,	/* FPU unimplemented operation */
+	EXCEP_FPU_OPERATION	= 0x0001d0,	/* FPU operation */
+
+	/* interrupts */
+	EXCEP_WDT		= 0x000240,	/* watchdog timer overflow */
+	EXCEP_NMI		= 0x000248,	/* non-maskable interrupt */
+	EXCEP_IRQ_LEVEL0	= 0x000280,	/* level 0 maskable interrupt */
+	EXCEP_IRQ_LEVEL1	= 0x000288,	/* level 1 maskable interrupt */
+	EXCEP_IRQ_LEVEL2	= 0x000290,	/* level 2 maskable interrupt */
+	EXCEP_IRQ_LEVEL3	= 0x000298,	/* level 3 maskable interrupt */
+	EXCEP_IRQ_LEVEL4	= 0x0002a0,	/* level 4 maskable interrupt */
+	EXCEP_IRQ_LEVEL5	= 0x0002a8,	/* level 5 maskable interrupt */
+	EXCEP_IRQ_LEVEL6	= 0x0002b0,	/* level 6 maskable interrupt */
+
+	/* system calls */
+	EXCEP_SYSCALL0		= 0x000300,	/* system call 0 */
+	EXCEP_SYSCALL1		= 0x000308,	/* system call 1 */
+	EXCEP_SYSCALL2		= 0x000310,	/* system call 2 */
+	EXCEP_SYSCALL3		= 0x000318,	/* system call 3 */
+	EXCEP_SYSCALL4		= 0x000320,	/* system call 4 */
+	EXCEP_SYSCALL5		= 0x000328,	/* system call 5 */
+	EXCEP_SYSCALL6		= 0x000330,	/* system call 6 */
+	EXCEP_SYSCALL7		= 0x000338,	/* system call 7 */
+	EXCEP_SYSCALL8		= 0x000340,	/* system call 8 */
+	EXCEP_SYSCALL9		= 0x000348,	/* system call 9 */
+	EXCEP_SYSCALL10		= 0x000350,	/* system call 10 */
+	EXCEP_SYSCALL11		= 0x000358,	/* system call 11 */
+	EXCEP_SYSCALL12		= 0x000360,	/* system call 12 */
+	EXCEP_SYSCALL13		= 0x000368,	/* system call 13 */
+	EXCEP_SYSCALL14		= 0x000370,	/* system call 14 */
+	EXCEP_SYSCALL15		= 0x000378,	/* system call 15 */
+};
+
+extern void __set_intr_stub(enum exception_code code, void *handler);
+extern void set_intr_stub(enum exception_code code, void *handler);
+extern void set_jtag_stub(enum exception_code code, void *handler);
+
+struct pt_regs;
+
+extern asmlinkage void __common_exception(void);
+extern asmlinkage void itlb_miss(void);
+extern asmlinkage void dtlb_miss(void);
+extern asmlinkage void itlb_aerror(void);
+extern asmlinkage void dtlb_aerror(void);
+extern asmlinkage void raw_bus_error(void);
+extern asmlinkage void double_fault(void);
+extern asmlinkage int  system_call(struct pt_regs *);
+extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
+extern asmlinkage void nmi(struct pt_regs *, enum exception_code);
+extern asmlinkage void uninitialised_exception(struct pt_regs *,
+					       enum exception_code);
+extern asmlinkage void irq_handler(void);
+extern asmlinkage void profile_handler(void);
+extern asmlinkage void nmi_handler(void);
+extern asmlinkage void misalignment(struct pt_regs *, enum exception_code);
+
+extern void die(const char *, struct pt_regs *, enum exception_code)
+	ATTRIB_NORET;
+
+extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_EXCEPTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fb.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fb.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/* MN10300 Frame buffer stuff
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_FB_H
+#define _ASM_FB_H
+
+#include <linux/fb.h>
+
+#define fb_pgprotect(...) do {} while (0)
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* _ASM_FB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fcntl.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fcntl.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fcntl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fcntl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fpu.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fpu.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/fpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/fpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,85 @@
+/* MN10300 FPU definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * Derived from include/asm-i386/i387.h: Copyright (C) 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_FPU_H
+#define _ASM_FPU_H
+
+#include <asm/processor.h>
+#include <asm/sigcontext.h>
+#include <asm/user.h>
+
+#ifdef __KERNEL__
+
+/* the task that owns the FPU state */
+extern struct task_struct *fpu_state_owner;
+
+#define set_using_fpu(tsk)				\
+do {							\
+	(tsk)->thread.fpu_flags |= THREAD_USING_FPU;	\
+} while (0)
+
+#define clear_using_fpu(tsk)				\
+do {							\
+	(tsk)->thread.fpu_flags &= ~THREAD_USING_FPU;	\
+} while (0)
+
+#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU)
+
+#define unlazy_fpu(tsk)					\
+do {							\
+	preempt_disable();				\
+	if (fpu_state_owner == (tsk))			\
+		fpu_save(&tsk->thread.fpu_state);	\
+	preempt_enable();				\
+} while (0)
+
+#define exit_fpu()				\
+do {						\
+	struct task_struct *__tsk = current;	\
+	preempt_disable();			\
+	if (fpu_state_owner == __tsk)		\
+		fpu_state_owner = NULL;		\
+	preempt_enable();			\
+} while (0)
+
+#define flush_fpu()					\
+do {							\
+	struct task_struct *__tsk = current;		\
+	preempt_disable();				\
+	if (fpu_state_owner == __tsk) {			\
+		fpu_state_owner = NULL;			\
+		__tsk->thread.uregs->epsw &= ~EPSW_FE;	\
+	}						\
+	preempt_enable();				\
+	clear_using_fpu(__tsk);				\
+} while (0)
+
+extern asmlinkage void fpu_init_state(void);
+extern asmlinkage void fpu_kill_state(struct task_struct *);
+extern asmlinkage void fpu_disabled(struct pt_regs *, enum exception_code);
+extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
+
+#ifdef CONFIG_FPU
+extern asmlinkage void fpu_save(struct fpu_state_struct *);
+extern asmlinkage void fpu_restore(struct fpu_state_struct *);
+#else
+#define fpu_save(a)
+#define fpu_restore(a)
+#endif /* CONFIG_FPU  */
+
+/*
+ * signal frame handlers
+ */
+extern int fpu_setup_sigcontext(struct fpucontext *buf);
+extern int fpu_restore_sigcontext(struct fpucontext *buf);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_FPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/frame.inc linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/frame.inc
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/frame.inc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/frame.inc	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,91 @@
+/* MN10300 Microcontroller core system register definitions -*- asm -*-
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_FRAME_INC
+#define _ASM_FRAME_INC
+
+#ifndef __ASSEMBLY__
+#error not for use in C files
+#endif
+
+#ifndef __ASM_OFFSETS_H__
+#include <asm/asm-offsets.h>
+#endif
+
+#define pi break
+
+#define fp a3
+
+###############################################################################
+#
+# build a stack frame from the registers
+# - the caller has subtracted 4 from SP before coming here
+#
+###############################################################################
+.macro SAVE_ALL
+	add	-4,sp				# next exception frame ptr save area
+	movm	[other],(sp)
+	mov	usp,a1
+	mov	a1,(sp)				# USP in MOVM[other] dummy slot
+	movm	[d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
+	mov	sp,fp				# FRAME pointer in A3
+	add	-12,sp				# allow for calls to be made
+	mov	(__frame),a1
+	mov	a1,(REG_NEXT,fp)
+	mov	fp,(__frame)
+
+	and	~EPSW_FE,epsw			# disable the FPU inside the kernel
+
+	# we may be holding current in E2
+#ifdef CONFIG_MN10300_CURRENT_IN_E2
+	mov	(__current),e2
+#endif
+.endm
+
+###############################################################################
+#
+# restore the registers from a stack frame
+#
+###############################################################################
+.macro RESTORE_ALL
+	# peel back the stack to the calling frame
+	# - this permits execve() to discard extra frames due to kernel syscalls
+	mov	(__frame),fp
+	mov	fp,sp
+	mov	(REG_NEXT,fp),d0                # userspace has regs->next == 0
+	mov	d0,(__frame)
+
+#ifndef CONFIG_MN10300_USING_JTAG
+	mov	(REG_EPSW,fp),d0
+	btst	EPSW_T,d0
+	beq	99f
+
+	or	EPSW_NMID,epsw
+	movhu	(DCR),d1
+	or	0x0001, d1
+	movhu	d1,(DCR)
+
+99:
+#endif
+	movm	(sp),[d2,d3,a2,a3,exreg0,exreg1,exother]
+
+	# must restore usp even if returning to kernel space,
+	# when CONFIG_PREEMPT is enabled.
+	mov	(sp),a1				# USP in MOVM[other] dummy slot
+	mov	a1,usp
+
+	movm	(sp),[other]
+	add	8,sp
+	rti
+
+.endm
+
+
+#endif /* _ASM_FRAME_INC */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/futex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/futex.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/gdb-stub.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/gdb-stub.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/gdb-stub.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/gdb-stub.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,183 @@
+/* MN10300 Kernel GDB stub definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_GDB_STUB_H
+#define _ASM_GDB_STUB_H
+
+#include <asm/exceptions.h>
+
+/*
+ * register ID numbers in GDB remote protocol
+ */
+
+#define GDB_REGID_PC		9
+#define GDB_REGID_FP		7
+#define GDB_REGID_SP		8
+
+/*
+ * virtual stack layout for the GDB exception handler
+ */
+#define NUMREGS			64
+
+#define GDB_FR_D0		(0 * 4)
+#define GDB_FR_D1		(1 * 4)
+#define GDB_FR_D2		(2 * 4)
+#define GDB_FR_D3		(3 * 4)
+#define GDB_FR_A0		(4 * 4)
+#define GDB_FR_A1		(5 * 4)
+#define GDB_FR_A2		(6 * 4)
+#define GDB_FR_A3		(7 * 4)
+
+#define GDB_FR_SP		(8 * 4)
+#define GDB_FR_PC		(9 * 4)
+#define GDB_FR_MDR		(10 * 4)
+#define GDB_FR_EPSW		(11 * 4)
+#define GDB_FR_LIR		(12 * 4)
+#define GDB_FR_LAR		(13 * 4)
+#define GDB_FR_MDRQ		(14 * 4)
+
+#define GDB_FR_E0		(15 * 4)
+#define GDB_FR_E1		(16 * 4)
+#define GDB_FR_E2		(17 * 4)
+#define GDB_FR_E3		(18 * 4)
+#define GDB_FR_E4		(19 * 4)
+#define GDB_FR_E5		(20 * 4)
+#define GDB_FR_E6		(21 * 4)
+#define GDB_FR_E7		(22 * 4)
+
+#define GDB_FR_SSP		(23 * 4)
+#define GDB_FR_MSP		(24 * 4)
+#define GDB_FR_USP		(25 * 4)
+#define GDB_FR_MCRH		(26 * 4)
+#define GDB_FR_MCRL		(27 * 4)
+#define GDB_FR_MCVF		(28 * 4)
+
+#define GDB_FR_FPCR		(29 * 4)
+#define GDB_FR_DUMMY0		(30 * 4)
+#define GDB_FR_DUMMY1		(31 * 4)
+
+#define GDB_FR_FS0		(32 * 4)
+
+#define GDB_FR_SIZE		(NUMREGS * 4)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This is the same as above, but for the high-level
+ * part of the GDB stub.
+ */
+
+struct gdb_regs {
+	/* saved main processor registers */
+	u32	d0, d1, d2, d3, a0, a1, a2, a3;
+	u32	sp, pc, mdr, epsw, lir, lar, mdrq;
+	u32	e0, e1, e2, e3, e4, e5, e6, e7;
+	u32	ssp, msp, usp, mcrh, mcrl, mcvf;
+
+	/* saved floating point registers */
+	u32	fpcr, _dummy0, _dummy1;
+	u32	fs0,  fs1,  fs2,  fs3,  fs4,  fs5,  fs6,  fs7;
+	u32	fs8,  fs9,  fs10, fs11, fs12, fs13, fs14, fs15;
+	u32	fs16, fs17, fs18, fs19, fs20, fs21, fs22, fs23;
+	u32	fs24, fs25, fs26, fs27, fs28, fs29, fs30, fs31;
+};
+
+/*
+ * Prototypes
+ */
+extern void show_registers_only(struct pt_regs *regs);
+
+extern asmlinkage void gdbstub_init(void);
+extern asmlinkage void gdbstub_exit(int status);
+extern asmlinkage void gdbstub_io_init(void);
+extern asmlinkage void gdbstub_io_set_baud(unsigned baud);
+extern asmlinkage int  gdbstub_io_rx_char(unsigned char *_ch, int nonblock);
+extern asmlinkage void gdbstub_io_tx_char(unsigned char ch);
+extern asmlinkage void gdbstub_io_tx_flush(void);
+
+extern asmlinkage void gdbstub_io_rx_handler(void);
+extern asmlinkage void gdbstub_rx_irq(struct pt_regs *, enum exception_code);
+extern asmlinkage int  gdbstub_intercept(struct pt_regs *, enum exception_code);
+extern asmlinkage void gdbstub_exception(struct pt_regs *, enum exception_code);
+extern asmlinkage void __gdbstub_bug_trap(void);
+extern asmlinkage void __gdbstub_pause(void);
+extern asmlinkage void start_kernel(void);
+
+#ifndef CONFIG_MN10300_CACHE_DISABLED
+extern asmlinkage void gdbstub_purge_cache(void);
+#else
+#define gdbstub_purge_cache()	do {} while (0)
+#endif
+
+/* Used to prevent crashes in memory access */
+extern asmlinkage int  gdbstub_read_byte(const u8 *, u8 *);
+extern asmlinkage int  gdbstub_read_word(const u8 *, u8 *);
+extern asmlinkage int  gdbstub_read_dword(const u8 *, u8 *);
+extern asmlinkage int  gdbstub_write_byte(u32, u8 *);
+extern asmlinkage int  gdbstub_write_word(u32, u8 *);
+extern asmlinkage int  gdbstub_write_dword(u32, u8 *);
+
+extern asmlinkage void gdbstub_read_byte_guard(void);
+extern asmlinkage void gdbstub_read_byte_cont(void);
+extern asmlinkage void gdbstub_read_word_guard(void);
+extern asmlinkage void gdbstub_read_word_cont(void);
+extern asmlinkage void gdbstub_read_dword_guard(void);
+extern asmlinkage void gdbstub_read_dword_cont(void);
+extern asmlinkage void gdbstub_write_byte_guard(void);
+extern asmlinkage void gdbstub_write_byte_cont(void);
+extern asmlinkage void gdbstub_write_word_guard(void);
+extern asmlinkage void gdbstub_write_word_cont(void);
+extern asmlinkage void gdbstub_write_dword_guard(void);
+extern asmlinkage void gdbstub_write_dword_cont(void);
+
+extern u8	gdbstub_rx_buffer[PAGE_SIZE];
+extern u32	gdbstub_rx_inp;
+extern u32	gdbstub_rx_outp;
+extern u8	gdbstub_rx_overflow;
+extern u8	gdbstub_busy;
+extern u8	gdbstub_rx_unget;
+
+#ifdef CONFIG_GDBSTUB_DEBUGGING
+extern void gdbstub_printk(const char *fmt, ...)
+	__attribute__((format(printf, 1, 2)));
+#else
+static inline __attribute__((format(printf, 1, 2)))
+void gdbstub_printk(const char *fmt, ...)
+{
+}
+#endif
+
+#ifdef CONFIG_GDBSTUB_DEBUG_ENTRY
+#define gdbstub_entry(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_entry(FMT, ...) ({ 0; })
+#endif
+
+#ifdef CONFIG_GDBSTUB_DEBUG_PROTOCOL
+#define gdbstub_proto(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_proto(FMT, ...) ({ 0; })
+#endif
+
+#ifdef CONFIG_GDBSTUB_DEBUG_IO
+#define gdbstub_io(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_io(FMT, ...) ({ 0; })
+#endif
+
+#ifdef CONFIG_GDBSTUB_DEBUG_BREAKPOINT
+#define gdbstub_bkpt(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_bkpt(FMT, ...) ({ 0; })
+#endif
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_GDB_STUB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/hardirq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+/* MN10300 Hardware IRQ statistics and management
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Modified by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_HARDIRQ_H
+#define _ASM_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+#include <asm/exceptions.h>
+
+/* assembly code in softirq.h is sensitive to the offsets of these fields */
+typedef struct {
+	unsigned int	__softirq_pending;
+	unsigned long	idle_timestamp;
+	unsigned int	__nmi_count;	/* arch dependent */
+	unsigned int	__irq_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(int irq);
+
+/*
+ * manipulate stubs in the MN10300 CPU Trap/Interrupt Vector table
+ * - these should jump to __common_exception in entry.S unless there's a good
+ *   reason to do otherwise (see trap_preinit() in traps.c)
+ */
+typedef void (*intr_stub_fnx)(struct pt_regs *regs,
+			      enum exception_code intcode);
+
+/*
+ * manipulate pointers in the Exception table (see entry.S)
+ * - these are indexed by decoding the lower 24 bits of the TBR register
+ * - note that the MN103E010 doesn't always trap through the correct vector,
+ *   but does always set the TBR correctly
+ */
+extern asmlinkage void set_excp_vector(enum exception_code code,
+				       intr_stub_fnx handler);
+
+#endif /* _ASM_HARDIRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/highmem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+/* MN10300 Virtual kernel memory mappings for high memory
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-i386/highmem.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+/* undef for production */
+#undef HIGHMEM_DEBUG
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+extern pte_t *pkmap_page_table;
+
+extern void __init kmap_init(void);
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define PKMAP_BASE	0xfe000000UL
+#define LAST_PKMAP	1024
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt)  ((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern unsigned long kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+static inline unsigned long kmap(struct page *page)
+{
+	if (in_interrupt())
+		BUG();
+	if (page < highmem_start_page)
+		return page_address(page);
+	return kmap_high(page);
+}
+
+static inline void kunmap(struct page *page)
+{
+	if (in_interrupt())
+		BUG();
+	if (page < highmem_start_page)
+		return;
+	kunmap_high(page);
+}
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+static inline unsigned long kmap_atomic(struct page *page, enum km_type type)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	if (page < highmem_start_page)
+		return page_address(page);
+
+	debug_kmap_atomic(type);
+	idx = type + KM_TYPE_NR * smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#if HIGHMEM_DEBUG
+	if (!pte_none(*(kmap_pte - idx)))
+		BUG();
+#endif
+	set_pte(kmap_pte - idx, mk_pte(page, kmap_prot));
+	__flush_tlb_one(vaddr);
+
+	return vaddr;
+}
+
+static inline void kunmap_atomic(unsigned long vaddr, enum km_type type)
+{
+#if HIGHMEM_DEBUG
+	enum fixed_addresses idx = type + KM_TYPE_NR * smp_processor_id();
+
+	if (vaddr < FIXADDR_START) /* FIXME */
+		return;
+
+	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx))
+		BUG();
+
+	/*
+	 * force other mappings to Oops if they'll try to access
+	 * this pte without first remap it
+	 */
+	pte_clear(kmap_pte - idx);
+	__flush_tlb_one(vaddr);
+#endif
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/hw_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/* MN10300 Hardware interrupt definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+#endif /* _ASM_HW_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/intctl-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/intctl-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/intctl-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/intctl-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/* MN10300 On-board interrupt controller registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_INTCTL_REGS_H
+#define _ASM_INTCTL_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+/* interrupt controller registers */
+#define GxICR(X)		__SYSREG(0xd4000000 + (X) * 4, u16)	/* group irq ctrl regs */
+
+#define IAGR			__SYSREG(0xd4000100, u16)	/* intr acceptance group reg */
+#define IAGR_GN			0x00fc		/* group number register
+						 * (documentation _has_ to be wrong)
+						 */
+
+#define EXTMD			__SYSREG(0xd4000200, u16)	/* external pin intr spec reg */
+#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3)
+
+#define SET_XIRQ_TRIGGER(X,Y)			\
+do {						\
+	u16 x = EXTMD;				\
+	x &= ~(3 << ((X) * 2));			\
+	x |= ((Y) & 3) << ((X) * 2);		\
+	EXTMD = x;				\
+} while (0)
+
+#define XIRQ_TRIGGER_LOWLEVEL	0
+#define XIRQ_TRIGGER_HILEVEL	1
+#define XIRQ_TRIGGER_NEGEDGE	2
+#define XIRQ_TRIGGER_POSEDGE	3
+
+/* non-maskable interrupt control */
+#define NMIIRQ			0
+#define NMICR			GxICR(NMIIRQ)	/* NMI control register */
+#define NMICR_NMIF		0x0001		/* NMI pin interrupt flag */
+#define NMICR_WDIF		0x0002		/* watchdog timer overflow flag */
+#define NMICR_ABUSERR		0x0008		/* async bus error flag */
+
+/* maskable interrupt control */
+#define GxICR_DETECT		0x0001		/* interrupt detect flag */
+#define GxICR_REQUEST		0x0010		/* interrupt request flag */
+#define GxICR_ENABLE		0x0100		/* interrupt enable flag */
+#define GxICR_LEVEL		0x7000		/* interrupt priority level */
+#define GxICR_LEVEL_0		0x0000		/* - level 0 */
+#define GxICR_LEVEL_1		0x1000		/* - level 1 */
+#define GxICR_LEVEL_2		0x2000		/* - level 2 */
+#define GxICR_LEVEL_3		0x3000		/* - level 3 */
+#define GxICR_LEVEL_4		0x4000		/* - level 4 */
+#define GxICR_LEVEL_5		0x5000		/* - level 5 */
+#define GxICR_LEVEL_6		0x6000		/* - level 6 */
+#define GxICR_LEVEL_SHIFT	12
+
+#ifndef __ASSEMBLY__
+extern void set_intr_level(int irq, u16 level);
+extern void set_intr_postackable(int irq);
+#endif
+
+/* external interrupts */
+#define XIRQxICR(X)		GxICR((X))	/* external interrupt control regs */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_INTCTL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ioctl.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ioctl.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ioctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ioctls.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ioctls.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ioctls.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ioctls.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,88 @@
+#ifndef _ASM_IOCTLS_H
+#define _ASM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
+#define TIOCSBRK	0x5427  /* BSD compatibility */
+#define TIOCCBRK	0x5428  /* BSD compatibility */
+#define TIOCGSID	0x5429  /* Return the session ID of FD */
+#define TCGETS2		_IOR('T', 0x2A, struct termios2)
+#define TCSETS2		_IOW('T', 0x2B, struct termios2)
+#define TCSETSW2	_IOW('T', 0x2C, struct termios2)
+#define TCSETSF2	_IOW('T', 0x2D, struct termios2)
+#define TIOCGPTN	_IOR('T', 0x30, unsigned int) /* Get Pty Number
+						       * (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T', 0x31, int)  /* Lock/unlock Pty */
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+#endif /* _ASM_IOCTLS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/io.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/io.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,301 @@
+/* MN10300 I/O port emulation and memory-mapped I/O
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <asm/page.h> /* I/O is all done through memory accesses */
+#include <asm/cpu-regs.h>
+#include <asm/cacheflush.h>
+
+#define mmiowb() do {} while (0)
+
+/*****************************************************************************/
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the x86 architecture, we just read/write the
+ * memory location directly.
+ */
+static inline u8 readb(const volatile void __iomem *addr)
+{
+	return *(const volatile u8 *) addr;
+}
+
+static inline u16 readw(const volatile void __iomem *addr)
+{
+	return *(const volatile u16 *) addr;
+}
+
+static inline u32 readl(const volatile void __iomem *addr)
+{
+	return *(const volatile u32 *) addr;
+}
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
+static inline void writeb(u8 b, volatile void __iomem *addr)
+{
+	*(volatile u8 *) addr = b;
+}
+
+static inline void writew(u16 b, volatile void __iomem *addr)
+{
+	*(volatile u16 *) addr = b;
+}
+
+static inline void writel(u32 b, volatile void __iomem *addr)
+{
+	*(volatile u32 *) addr = b;
+}
+
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+
+/*****************************************************************************/
+/*
+ * traditional input/output functions
+ */
+static inline u8 inb_local(unsigned long addr)
+{
+	return readb((volatile void __iomem *) addr);
+}
+
+static inline void outb_local(u8 b, unsigned long addr)
+{
+	return writeb(b, (volatile void __iomem *) addr);
+}
+
+static inline u8 inb(unsigned long addr)
+{
+	return readb((volatile void __iomem *) addr);
+}
+
+static inline u16 inw(unsigned long addr)
+{
+	return readw((volatile void __iomem *) addr);
+}
+
+static inline u32 inl(unsigned long addr)
+{
+	return readl((volatile void __iomem *) addr);
+}
+
+static inline void outb(u8 b, unsigned long addr)
+{
+	return writeb(b, (volatile void __iomem *) addr);
+}
+
+static inline void outw(u16 b, unsigned long addr)
+{
+	return writew(b, (volatile void __iomem *) addr);
+}
+
+static inline void outl(u32 b, unsigned long addr)
+{
+	return writel(b, (volatile void __iomem *) addr);
+}
+
+#define inb_p(addr)	inb(addr)
+#define inw_p(addr)	inw(addr)
+#define inl_p(addr)	inl(addr)
+#define outb_p(x, addr)	outb((x), (addr))
+#define outw_p(x, addr)	outw((x), (addr))
+#define outl_p(x, addr)	outl((x), (addr))
+
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+	if (count) {
+		u8 *buf = buffer;
+		do {
+			u8 x = inb(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+	if (count) {
+		u16 *buf = buffer;
+		do {
+			u16 x = inw(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+	if (count) {
+		u32 *buf = buffer;
+		do {
+			u32 x = inl(addr);
+			*buf++ = x;
+		} while (--count);
+	}
+}
+
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+	if (count) {
+		const u8 *buf = buffer;
+		do {
+			outb(*buf++, addr);
+		} while (--count);
+	}
+}
+
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+	if (count) {
+		const u16 *buf = buffer;
+		do {
+			outw(*buf++, addr);
+		} while (--count);
+	}
+}
+
+extern void __outsl(unsigned long addr, const void *buffer, int count);
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+	if ((unsigned long) buffer & 0x3)
+		return __outsl(addr, buffer, count);
+
+	if (count) {
+		const u32 *buf = buffer;
+		do {
+			outl(*buf++, addr);
+		} while (--count);
+	}
+}
+
+#define ioread8(addr)		readb(addr)
+#define ioread16(addr)		readw(addr)
+#define ioread32(addr)		readl(addr)
+
+#define iowrite8(v, addr)	writeb((v), (addr))
+#define iowrite16(v, addr)	writew((v), (addr))
+#define iowrite32(v, addr)	writel((v), (addr))
+
+#define ioread8_rep(p, dst, count) \
+	insb((unsigned long) (p), (dst), (count))
+#define ioread16_rep(p, dst, count) \
+	insw((unsigned long) (p), (dst), (count))
+#define ioread32_rep(p, dst, count) \
+	insl((unsigned long) (p), (dst), (count))
+
+#define iowrite8_rep(p, src, count) \
+	outsb((unsigned long) (p), (src), (count))
+#define iowrite16_rep(p, src, count) \
+	outsw((unsigned long) (p), (src), (count))
+#define iowrite32_rep(p, src, count) \
+	outsl((unsigned long) (p), (src), (count))
+
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#ifdef __KERNEL__
+
+#include <linux/vmalloc.h>
+#define __io_virt(x) ((void *) (x))
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
+{
+}
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are pretty trivial
+ */
+static inline unsigned long virt_to_phys(volatile void *address)
+{
+	return __pa(address);
+}
+
+static inline void *phys_to_virt(unsigned long address)
+{
+	return __va(address);
+}
+
+/*
+ * Change "struct page" to physical address.
+ */
+static inline void *__ioremap(unsigned long offset, unsigned long size,
+			      unsigned long flags)
+{
+	return (void *) offset;
+}
+
+static inline void *ioremap(unsigned long offset, unsigned long size)
+{
+	return (void *) offset;
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that
+ * area.  it's useful if some control registers are in such an area and write
+ * combining or read caching is not desirable:
+ */
+static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+{
+	return (void *) (offset | 0x20000000);
+}
+
+#define ioremap_wc ioremap_nocache
+
+static inline void iounmap(void *addr)
+{
+}
+
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) port;
+}
+
+static inline void ioport_unmap(void __iomem *p)
+{
+}
+
+#define xlate_dev_kmem_ptr(p)	((void *) (p))
+#define xlate_dev_mem_ptr(p)	((void *) (p))
+
+/*
+ * PCI bus iomem addresses must be in the region 0x80000000-0x9fffffff
+ */
+static inline unsigned long virt_to_bus(volatile void *address)
+{
+	return ((unsigned long) address) & ~0x20000000;
+}
+
+static inline void *bus_to_virt(unsigned long address)
+{
+	return (void *) address;
+}
+
+#define page_to_bus page_to_phys
+
+#define memset_io(a, b, c)	memset(__io_virt(a), (b), (c))
+#define memcpy_fromio(a, b, c)	memcpy((a), __io_virt(b), (c))
+#define memcpy_toio(a, b, c)	memcpy(__io_virt(a), (b), (c))
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ipcbuf.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ipcbuf.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ipcbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ipcbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+#ifndef _ASM_IPCBUF_H
+#define _ASM_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for MN10300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned short		__pad2;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* _ASM_IPCBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ipc.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ipc.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ipc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ipc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,32 @@
+/* MN10300 Hardware interrupt definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Modified by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-i386/irq.h:
+ *   - (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+#include <asm/intctl-regs.h>
+#include <asm/reset-regs.h>
+#include <proc/irq.h>
+
+/* this number is used when no interrupt has been assigned */
+#define NO_IRQ		INT_MAX
+
+/* hardware irq numbers */
+#define NR_IRQS		GxICR_NUM_IRQS
+
+/* external hardware irq numbers */
+#define NR_XIRQS	GxICR_NUM_XIRQS
+
+#define irq_canonicalize(IRQ) (IRQ)
+
+#endif /* _ASM_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/irq_regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/irq_regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/irq_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/irq_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+/* MN10300 IRQ registers pointer definition
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_IRQ_REGS_H
+#define _ASM_IRQ_REGS_H
+
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack
+ */
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#ifndef __ASSEMBLY__
+#define get_irq_regs() (__frame)
+#endif
+
+#endif /* _ASM_IRQ_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/Kbuild linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/Kbuild
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/Kbuild	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/Kbuild	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kdebug.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kdebug.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kdebug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kdebug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/* MN10300 In-kernel death knells
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_KDEBUG_H
+#define _ASM_KDEBUG_H
+
+/* Grossly misnamed. */
+enum die_val {
+	DIE_OOPS = 1,
+	DIE_BREAKPOINT,
+	DIE_GPF,
+};
+
+#endif /* _ASM_KDEBUG_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kmap_types.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kmap_types.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kmap_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kmap_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/* MN10300 kmap_atomic() slot IDs
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif /* _ASM_KMAP_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kprobes.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kprobes.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/kprobes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/kprobes.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+/* MN10300 Kernel Probes support
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by Mark Salter (msalter@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public Licence as published by
+ * the Free Software Foundation; either version 2 of the Licence, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public Licence
+ * 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_KPROBES_H
+#define _ASM_KPROBES_H
+
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+struct kprobe;
+
+typedef unsigned char kprobe_opcode_t;
+#define BREAKPOINT_INSTRUCTION	0xff
+#define MAX_INSN_SIZE 8
+#define MAX_STACK_SIZE 128
+
+/* Architecture specific copy of original instruction */
+struct arch_specific_insn {
+	/*  copy of original instruction
+	 */
+	kprobe_opcode_t insn[MAX_INSN_SIZE];
+};
+
+extern const int kretprobe_blacklist_size;
+
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+				    unsigned long val, void *data);
+
+#define flush_insn_slot(p)  do {} while (0)
+
+extern void arch_remove_kprobe(struct kprobe *p);
+
+#endif /* _ASM_KPROBES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/linkage.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/linkage.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/linkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/* MN10300 Linkage and calling-convention overrides
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_LINKAGE_H
+#define _ASM_LINKAGE_H
+
+/* don't override anything */
+#define asmlinkage
+
+#define __ALIGN		.align 4,0xcb
+#define __ALIGN_STR	".align 4,0xcb"
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/local.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/local.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/local.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/local.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mc146818rtc.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mc146818rtc.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mc146818rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mc146818rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm/rtc-regs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mman.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mman.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mman.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mman.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+/* MN10300 Constants for mmap and co.
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * - Derived from asm-x86/mman.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_MMAN_H
+#define _ASM_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+#define MAP_LOCKED	0x2000		/* pages are locked */
+#define MAP_NORESERVE	0x4000		/* don't check for reservations */
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#endif /* _ASM_MMAN_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mmu_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,138 @@
+/* MN10300 MMU context management
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Modified by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m32r/mmu_context.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ *
+ * This implements an algorithm to provide TLB PID mappings to provide
+ * selective access to the TLB for processes, thus reducing the number of TLB
+ * flushes required.
+ *
+ * Note, however, that the M32R algorithm is technically broken as it does not
+ * handle version wrap-around, and could, theoretically, have a problem with a
+ * very long lived program that sleeps long enough for the version number to
+ * wrap all the way around so that its TLB mappings appear valid once again.
+ */
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <asm/atomic.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm-generic/mm_hooks.h>
+
+#define MMU_CONTEXT_TLBPID_MASK		0x000000ffUL
+#define MMU_CONTEXT_VERSION_MASK	0xffffff00UL
+#define MMU_CONTEXT_FIRST_VERSION	0x00000100UL
+#define MMU_NO_CONTEXT			0x00000000UL
+
+extern unsigned long mmu_context_cache[NR_CPUS];
+#define mm_context(mm)	(mm->context.tlbpid[smp_processor_id()])
+
+#define enter_lazy_tlb(mm, tsk)	do {} while (0)
+
+#ifdef CONFIG_SMP
+#define cpu_ran_vm(cpu, task) \
+	cpu_set((cpu), (task)->cpu_vm_mask)
+#define cpu_maybe_ran_vm(cpu, task) \
+	cpu_test_and_set((cpu), (task)->cpu_vm_mask)
+#else
+#define cpu_ran_vm(cpu, task)		do {} while (0)
+#define cpu_maybe_ran_vm(cpu, task)	true
+#endif /* CONFIG_SMP */
+
+/*
+ * allocate an MMU context
+ */
+static inline unsigned long allocate_mmu_context(struct mm_struct *mm)
+{
+	unsigned long *pmc = &mmu_context_cache[smp_processor_id()];
+	unsigned long mc = ++(*pmc);
+
+	if (!(mc & MMU_CONTEXT_TLBPID_MASK)) {
+		/* we exhausted the TLB PIDs of this version on this CPU, so we
+		 * flush this CPU's TLB in its entirety and start new cycle */
+		flush_tlb_all();
+
+		/* fix the TLB version if needed (we avoid version #0 so as to
+		 * distingush MMU_NO_CONTEXT) */
+		if (!mc)
+			*pmc = mc = MMU_CONTEXT_FIRST_VERSION;
+	}
+	mm_context(mm) = mc;
+	return mc;
+}
+
+/*
+ * get an MMU context if one is needed
+ */
+static inline unsigned long get_mmu_context(struct mm_struct *mm)
+{
+	unsigned long mc = MMU_NO_CONTEXT, cache;
+
+	if (mm) {
+		cache = mmu_context_cache[smp_processor_id()];
+		mc = mm_context(mm);
+
+		/* if we have an old version of the context, replace it */
+		if ((mc ^ cache) & MMU_CONTEXT_VERSION_MASK)
+			mc = allocate_mmu_context(mm);
+	}
+	return mc;
+}
+
+/*
+ * initialise the context related info for a new mm_struct instance
+ */
+static inline int init_new_context(struct task_struct *tsk,
+				   struct mm_struct *mm)
+{
+	int num_cpus = NR_CPUS, i;
+
+	for (i = 0; i < num_cpus; i++)
+		mm->context.tlbpid[i] = MMU_NO_CONTEXT;
+	return 0;
+}
+
+/*
+ * destroy context related info for an mm_struct that is about to be put to
+ * rest
+ */
+#define destroy_context(mm)	do { } while (0)
+
+/*
+ * after we have set current->mm to a new value, this activates the context for
+ * the new mm so we see the new mappings.
+ */
+static inline void activate_context(struct mm_struct *mm, int cpu)
+{
+	PIDR = get_mmu_context(mm) & MMU_CONTEXT_TLBPID_MASK;
+}
+
+/*
+ * change between virtual memory sets
+ */
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			     struct task_struct *tsk)
+{
+	int cpu = smp_processor_id();
+
+	if (prev != next) {
+		cpu_ran_vm(cpu, next);
+		activate_context(next, cpu);
+		PTBR = (unsigned long) next->pgd;
+	} else if (!cpu_maybe_ran_vm(cpu, next)) {
+		activate_context(next, cpu);
+	}
+}
+
+#define deactivate_mm(tsk, mm)	do {} while (0)
+#define activate_mm(prev, next)	switch_mm((prev), (next), NULL)
+
+#endif /* _ASM_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+/* MN10300 Memory management context
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-frv/mmu.h
+ */
+
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+/*
+ * MMU context
+ */
+typedef struct {
+	unsigned long	tlbpid[NR_CPUS];	/* TLB PID for this process on
+						 * each CPU */
+} mm_context_t;
+
+#endif /* _ASM_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/module.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/module.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+/* MN10300 Arch-specific module definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by Mark Salter (msalter@redhat.com)
+ * Derived from include/asm-i386/module.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+struct mod_arch_specific {
+};
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+
+/*
+ * Include the MN10300 architecture version.
+ */
+#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
+
+#endif /* _ASM_MODULE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/msgbuf.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/msgbuf.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/msgbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/msgbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for MN10300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+	struct ipc64_perm	msg_perm;
+	__kernel_time_t		msg_stime;	/* last msgsnd time */
+	unsigned long		__unused1;
+	__kernel_time_t		msg_rtime;	/* last msgrcv time */
+	unsigned long		__unused2;
+	__kernel_time_t		msg_ctime;	/* last change time */
+	unsigned long		__unused3;
+	unsigned long		msg_cbytes;	/* current number of bytes on queue */
+	unsigned long		msg_qnum;	/* number of messages in queue */
+	unsigned long		msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t		msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t		msg_lrpid;	/* last receive pid */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+#endif /* _ASM_MSGBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mutex.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mutex.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/mutex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/mutex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/* MN10300 Mutex fastpath
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+#include <asm-generic/mutex-null.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/nmi.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/nmi.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/nmi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/nmi.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+/* MN10300 NMI handling
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_NMI_H
+#define _ASM_NMI_H
+
+#endif /* _ASM_NMI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/page.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/page.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,128 @@
+/* MN10300 Page table definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+
+#ifndef __ASSEMBLY__
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
+#else
+#define PAGE_SIZE	+(1 << PAGE_SHIFT)	/* unary plus marks an
+						 * immediate val not an addr */
+#define PAGE_MASK	+(~(PAGE_SIZE - 1))
+#endif
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to, from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
+#define clear_user_page(addr, vaddr, page)	clear_page(addr)
+#define copy_user_page(vto, vfrom, vaddr, to)	copy_page(vto, vfrom)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define PTE_MASK	PAGE_MASK
+#define HPAGE_SHIFT	22
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define HPAGE_SIZE		((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+#endif
+
+#define pte_val(x)	((x).pte)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) })
+#define __pgd(x)	((pgd_t) { (x) })
+#define __pgprot(x)	((pgprot_t) { (x) })
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * This handles the memory map.. We could make this a config
+ * option, but too many people screw it up, and too few need
+ * it.
+ *
+ * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
+ * a virtual address space of one gigabyte, which limits the
+ * amount of physical memory you can use to about 950MB.
+ */
+
+#ifndef __ASSEMBLY__
+
+/* Pure 2^n version of get_order */
+static inline int get_order(unsigned long size) __attribute__((const));
+static inline int get_order(unsigned long size)
+{
+	int order;
+
+	size = (size - 1) >> (PAGE_SHIFT - 1);
+	order = -1;
+	do {
+		size >>= 1;
+		order++;
+	} while (size);
+	return order;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+
+#define __PAGE_OFFSET		(PAGE_OFFSET_RAW)
+#define PAGE_OFFSET		((unsigned long) __PAGE_OFFSET)
+
+/*
+ * main RAM and kernel working space are coincident at 0x90000000, but to make
+ * life more interesting, there's also an uncached virtual shadow at 0xb0000000
+ * - these mappings are fixed in the MMU
+ */
+#define __pfn_disp		(CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT)
+
+#define __pa(x)			((unsigned long)(x))
+#define __va(x)			((void *)(unsigned long)(x))
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+#define pfn_to_page(pfn)	(mem_map + ((pfn) - __pfn_disp))
+#define page_to_pfn(page)	((unsigned long)((page) - mem_map) + __pfn_disp)
+
+#define pfn_valid(pfn)					\
+({							\
+	unsigned long __pfn = (pfn) - __pfn_disp;	\
+	__pfn < max_mapnr;				\
+})
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_phys(page)	(page_to_pfn(page) << 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 /* __KERNEL__ */
+
+#endif /* _ASM_PAGE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/page_offset.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/page_offset.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/page_offset.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/page_offset.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+/* MN10300 Kernel base address
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+#ifndef _ASM_PAGE_OFFSET_H
+#define _ASM_PAGE_OFFSET_H
+
+#define PAGE_OFFSET_RAW CONFIG_KERNEL_RAM_BASE_ADDRESS
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/param.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/param.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/param.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+/* MN10300 Kernel parameters
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PARAM_H
+#define _ASM_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 */
+#define COMMAND_LINE_SIZE 256
+
+#endif /* _ASM_PARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,129 @@
+/* MN10300 PCI definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PCI_H
+#define _ASM_PCI_H
+
+#ifdef __KERNEL__
+#include <linux/mm.h>		/* for struct page */
+
+#if 0
+#define __pcbdebug(FMT, ADDR, ...) \
+	printk(KERN_DEBUG "PCIBRIDGE[%08x]: "FMT"\n", \
+	       (u32)(ADDR), ##__VA_ARGS__)
+
+#define __pcidebug(FMT, BUS, DEVFN, WHERE,...)		\
+do {							\
+	printk(KERN_DEBUG "PCI[%02x:%02x.%x + %02x]: "FMT"\n",	\
+	       (BUS)->number,					\
+	       PCI_SLOT(DEVFN),					\
+	       PCI_FUNC(DEVFN),					\
+	       (u32)(WHERE), ##__VA_ARGS__);			\
+} while (0)
+
+#else
+#define __pcbdebug(FMT, ADDR, ...)		do {} while (0)
+#define __pcidebug(FMT, BUS, DEVFN, WHERE, ...)	do {} while (0)
+#endif
+
+/* 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 */
+
+#ifdef CONFIG_PCI
+#define pcibios_assign_all_busses()	1
+extern void unit_pci_init(void);
+#else
+#define pcibios_assign_all_busses()	0
+#endif
+
+extern unsigned long pci_mem_start;
+#define PCIBIOS_MIN_IO		0xBE000004
+#define PCIBIOS_MIN_MEM		0xB8000000
+
+void pcibios_set_master(struct pci_dev *dev);
+void pcibios_penalize_isa_irq(int irq);
+
+/* Dynamic DMA mapping stuff.
+ * i386 has everything mapped statically.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+
+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+/* Return the index of the PCI controller for device. */
+static inline int pci_controller_num(struct pci_dev *dev)
+{
+	return 0;
+}
+
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			       enum pci_mmap_state mmap_state,
+			       int write_combine);
+
+#endif /* __KERNEL__ */
+
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/**
+ * pcibios_resource_to_bus - convert resource to PCI bus address
+ * @dev: device which owns this resource
+ * @region: converted bus-centric region (start,end)
+ * @res: resource to convert
+ *
+ * Convert a resource to a PCI device bus address or bus window.
+ */
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+				    struct pci_bus_region *region,
+				    struct resource *res);
+
+extern void pcibios_bus_to_resource(struct pci_dev *dev,
+				    struct resource *res,
+				    struct pci_bus_region *region);
+
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+	struct resource *root = NULL;
+
+	if (res->flags & IORESOURCE_IO)
+		root = &ioport_resource;
+	if (res->flags & IORESOURCE_MEM)
+		root = &iomem_resource;
+
+	return root;
+}
+
+#define pcibios_scan_all_fns(a, b)	0
+
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+	return channel ? 15 : 14;
+}
+
+#endif /* _ASM_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/percpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/percpu.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pgalloc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,56 @@
+/* MN10300 Page and page table/directory allocation
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <linux/threads.h>
+#include <linux/mm.h>		/* for struct page */
+
+struct mm_struct;
+struct page;
+
+/* attach a page table to a PMD entry */
+#define pmd_populate_kernel(mm, pmd, pte) \
+	set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE))
+
+static inline
+void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
+{
+	set_pmd(pmd, __pmd((page_to_pfn(pte) << PAGE_SHIFT) | _PAGE_TABLE));
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Allocate and free page tables.
+ */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *, pgd_t *);
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	free_page((unsigned long) pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, struct page *pte)
+{
+	__free_page(pte);
+}
+
+
+#define __pte_free_tlb(tlb, pte) tlb_remove_page((tlb), (pte))
+
+#endif /* _ASM_PGALLOC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pgtable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,492 @@
+/* MN10300 Page table manipulators and constants
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ *
+ *
+ * The Linux memory management assumes a three-level page table setup. On
+ * the i386, we use that, but "fold" the mid level into the top-level page
+ * table, so that we physically have the same two-level page table as the
+ * i386 mmu expects.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the i386 page table tree for the purposes of the MN10300 TLB handler
+ * functions.
+ */
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <asm/cpu-regs.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <linux/threads.h>
+
+#include <asm/bitops.h>
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+extern unsigned long empty_zero_page[1024];
+extern spinlock_t pgd_lock;
+extern struct page *pgd_list;
+
+extern void pmd_ctor(void *, struct kmem_cache *, unsigned long);
+extern void pgtable_cache_init(void);
+extern void paging_init(void);
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The Linux mn10300 paging architecture only implements both the traditional
+ * 2-level page tables
+ */
+#define PGDIR_SHIFT	22
+#define PTRS_PER_PGD	1024
+#define PTRS_PER_PUD	1	/* we don't really have any PUD physically */
+#define PTRS_PER_PMD	1	/* we don't really have any PMD physically */
+#define PTRS_PER_PTE	1024
+
+#define PGD_SIZE	PAGE_SIZE
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
+
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS	0
+
+#define USER_PGD_PTRS		(PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS		(PTRS_PER_PGD - USER_PGD_PTRS)
+
+#define TWOLEVEL_PGDIR_SHIFT	22
+#define BOOT_USER_PGD_PTRS	(__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_KERNEL_PGD_PTRS	(1024 - BOOT_USER_PGD_PTRS)
+
+#ifndef __ASSEMBLY__
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+#endif
+
+/*
+ * Unfortunately, due to the way the MMU works on the MN10300, the vmalloc VM
+ * area has to be in the lower half of the virtual address range (the upper
+ * half is not translated through the TLB).
+ *
+ * So in this case, the vmalloc area goes at the bottom of the address map
+ * (leaving a hole at the very bottom to catch addressing errors), and
+ * userspace starts immediately above.
+ *
+ * The vmalloc() routines also leaves a hole of 4kB between each vmalloced
+ * area to catch addressing errors.
+ */
+#define VMALLOC_OFFSET	(8 * 1024 * 1024)
+#define VMALLOC_START	(0x70000000)
+#define VMALLOC_END	(0x7C000000)
+
+#ifndef __ASSEMBLY__
+extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE];
+#endif
+
+/* IPTEL/DPTEL bit assignments */
+#define _PAGE_BIT_VALID		xPTEL_V_BIT
+#define _PAGE_BIT_ACCESSED	xPTEL_UNUSED1_BIT	/* mustn't be loaded into IPTEL/DPTEL */
+#define _PAGE_BIT_NX		xPTEL_UNUSED2_BIT	/* mustn't be loaded into IPTEL/DPTEL */
+#define _PAGE_BIT_CACHE		xPTEL_C_BIT
+#define _PAGE_BIT_PRESENT	xPTEL_PV_BIT
+#define _PAGE_BIT_DIRTY		xPTEL_D_BIT
+#define _PAGE_BIT_GLOBAL	xPTEL_G_BIT
+
+#define _PAGE_VALID		xPTEL_V
+#define _PAGE_ACCESSED		xPTEL_UNUSED1
+#define _PAGE_NX		xPTEL_UNUSED2		/* no-execute bit */
+#define _PAGE_CACHE		xPTEL_C
+#define _PAGE_PRESENT		xPTEL_PV
+#define _PAGE_DIRTY		xPTEL_D
+#define _PAGE_PROT		xPTEL_PR
+#define _PAGE_PROT_RKNU		xPTEL_PR_ROK
+#define _PAGE_PROT_WKNU		xPTEL_PR_RWK
+#define _PAGE_PROT_RKRU		xPTEL_PR_ROK_ROU
+#define _PAGE_PROT_WKRU		xPTEL_PR_RWK_ROU
+#define _PAGE_PROT_WKWU		xPTEL_PR_RWK_RWU
+#define _PAGE_GLOBAL		xPTEL_G
+#define _PAGE_PSE		xPTEL_PS_4Mb		/* 4MB page */
+
+#define _PAGE_FILE		xPTEL_UNUSED1_BIT	/* set:pagecache unset:swap */
+
+#define __PAGE_PROT_UWAUX	0x040
+#define __PAGE_PROT_USER	0x080
+#define __PAGE_PROT_WRITE	0x100
+
+#define _PAGE_PRESENTV		(_PAGE_PRESENT|_PAGE_VALID)
+#define _PAGE_PROTNONE		0x000	/* If not present */
+
+#ifndef __ASSEMBLY__
+
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+#define _PAGE_TABLE	(_PAGE_PRESENTV | _PAGE_PROT_WKNU | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define __PAGE_NONE	(_PAGE_PRESENTV | _PAGE_PROT_RKNU | _PAGE_ACCESSED | _PAGE_CACHE)
+#define __PAGE_SHARED	(_PAGE_PRESENTV | _PAGE_PROT_WKWU | _PAGE_ACCESSED | _PAGE_CACHE)
+#define __PAGE_COPY	(_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE)
+#define __PAGE_READONLY	(_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE)
+
+#define PAGE_NONE		__pgprot(__PAGE_NONE     | _PAGE_NX)
+#define PAGE_SHARED_NOEXEC	__pgprot(__PAGE_SHARED   | _PAGE_NX)
+#define PAGE_COPY_NOEXEC	__pgprot(__PAGE_COPY     | _PAGE_NX)
+#define PAGE_READONLY_NOEXEC	__pgprot(__PAGE_READONLY | _PAGE_NX)
+#define PAGE_SHARED_EXEC	__pgprot(__PAGE_SHARED)
+#define PAGE_COPY_EXEC		__pgprot(__PAGE_COPY)
+#define PAGE_READONLY_EXEC	__pgprot(__PAGE_READONLY)
+#define PAGE_COPY		PAGE_COPY_NOEXEC
+#define PAGE_READONLY		PAGE_READONLY_NOEXEC
+#define PAGE_SHARED		PAGE_SHARED_EXEC
+
+#define __PAGE_KERNEL_BASE (_PAGE_PRESENTV | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
+
+#define __PAGE_KERNEL		(__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_CACHE | _PAGE_NX)
+#define __PAGE_KERNEL_NOCACHE	(__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_NX)
+#define __PAGE_KERNEL_EXEC	(__PAGE_KERNEL & ~_PAGE_NX)
+#define __PAGE_KERNEL_RO	(__PAGE_KERNEL_BASE | _PAGE_PROT_RKNU | _PAGE_CACHE | _PAGE_NX)
+#define __PAGE_KERNEL_LARGE	(__PAGE_KERNEL | _PAGE_PSE)
+#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
+
+#define PAGE_KERNEL		__pgprot(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO		__pgprot(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_EXEC	__pgprot(__PAGE_KERNEL_EXEC)
+#define PAGE_KERNEL_NOCACHE	__pgprot(__PAGE_KERNEL_NOCACHE)
+#define PAGE_KERNEL_LARGE	__pgprot(__PAGE_KERNEL_LARGE)
+#define PAGE_KERNEL_LARGE_EXEC	__pgprot(__PAGE_KERNEL_LARGE_EXEC)
+
+/*
+ * Whilst the MN10300 can do page protection for execute (given separate data
+ * and insn TLBs), we are not supporting it at the moment. Write permission,
+ * however, always implies read permission (but not execute permission).
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY_NOEXEC
+#define __P010	PAGE_COPY_NOEXEC
+#define __P011	PAGE_COPY_NOEXEC
+#define __P100	PAGE_READONLY_EXEC
+#define __P101	PAGE_READONLY_EXEC
+#define __P110	PAGE_COPY_EXEC
+#define __P111	PAGE_COPY_EXEC
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY_NOEXEC
+#define __S010	PAGE_SHARED_NOEXEC
+#define __S011	PAGE_SHARED_NOEXEC
+#define __S100	PAGE_READONLY_EXEC
+#define __S101	PAGE_READONLY_EXEC
+#define __S110	PAGE_SHARED_EXEC
+#define __S111	PAGE_SHARED_EXEC
+
+/*
+ * Define this to warn about kernel memory accesses that are
+ * done without a 'verify_area(VERIFY_WRITE,..)'
+ */
+#undef TEST_VERIFY_AREA
+
+#define pte_present(x)	(pte_val(x) & _PAGE_VALID)
+#define pte_clear(mm, addr, xp)				\
+do {							\
+	set_pte_at((mm), (addr), (xp), __pte(0));	\
+} while (0)
+
+#define pmd_none(x)	(!pmd_val(x))
+#define pmd_present(x)	(!pmd_none(x))
+#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
+#define	pmd_bad(x)	0
+
+
+#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_user(pte_t pte)	{ return pte_val(pte) & __PAGE_PROT_USER; }
+static inline int pte_read(pte_t pte)	{ return pte_val(pte) & __PAGE_PROT_USER; }
+static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)	{ return pte_val(pte) & __PAGE_PROT_WRITE; }
+static inline int pte_special(pte_t pte){ return 0; }
+
+/*
+ * The following only works if pte_present() is not true.
+ */
+static inline int pte_file(pte_t pte)	{ return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(__PAGE_PROT_USER|__PAGE_PROT_UWAUX); return pte;
+}
+static inline pte_t pte_exprotect(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_NX; return pte;
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX); return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkexec(pte_t pte)	{ pte_val(pte) &= ~_PAGE_NX; return pte; }
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+	pte_val(pte) |= __PAGE_PROT_USER;
+	if (pte_write(pte))
+		pte_val(pte) |= __PAGE_PROT_UWAUX;
+	return pte;
+}
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	pte_val(pte) |= __PAGE_PROT_WRITE;
+	if (pte_val(pte) & __PAGE_PROT_USER)
+		pte_val(pte) |= __PAGE_PROT_UWAUX;
+	return pte;
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
+
+#define pte_ERROR(e) \
+	printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \
+	       __FILE__, __LINE__, pte_val(e))
+#define pgd_ERROR(e) \
+	printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \
+	       __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+#define pgd_clear(xp)				do { } while (0)
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval)			(*(pteptr) = pteval)
+#define set_pte_at(mm, addr, ptep, pteval)	set_pte((ptep), (pteval))
+#define set_pte_atomic(pteptr, pteval)		set_pte((pteptr), (pteval))
+
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+
+#define ptep_get_and_clear(mm, addr, ptep) \
+	__pte(xchg(&(ptep)->pte, 0))
+#define pte_same(a, b)		(pte_val(a) == pte_val(b))
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_none(x)		(!pte_val(x))
+#define pte_pfn(x)		((unsigned long) (pte_val(x) >> PAGE_SHIFT))
+#define __pfn_addr(pfn)		((pfn) << PAGE_SHIFT)
+#define pfn_pte(pfn, prot)	__pte(__pfn_addr(pfn) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot)	__pmd(__pfn_addr(pfn) | pgprot_val(prot))
+
+/*
+ * All present user pages are user-executable:
+ */
+static inline int pte_exec(pte_t pte)
+{
+	return pte_user(pte);
+}
+
+/*
+ * All present pages are kernel-executable:
+ */
+static inline int pte_exec_kernel(pte_t pte)
+{
+	return 1;
+}
+
+/*
+ * Bits 0 and 1 are taken, split up the 29 bits of offset
+ * into this range:
+ */
+#define PTE_FILE_MAX_BITS	29
+
+#define pte_to_pgoff(pte)	(pte_val(pte) >> 2)
+#define pgoff_to_pte(off)	__pte((off) << 2 | _PAGE_FILE)
+
+/* Encode and de-code a swap entry */
+#define __swp_type(x)			(((x).val >> 2) & 0x3f)
+#define __swp_offset(x)			((x).val >> 8)
+#define __swp_entry(type, offset) \
+	((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
+#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)		__pte((x).val)
+
+static inline
+int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr,
+			      pte_t *ptep)
+{
+	if (!pte_dirty(*ptep))
+		return 0;
+	return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte);
+}
+
+static inline
+int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
+			      pte_t *ptep)
+{
+	if (!pte_young(*ptep))
+		return 0;
+	return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte);
+}
+
+static inline
+void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	pte_val(*ptep) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX);
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	set_bit(_PAGE_BIT_DIRTY, &ptep->pte);
+}
+
+/*
+ * Macro to mark a page protection value as "uncacheable".  On processors which
+ * do not support it, this is a no-op.
+ */
+#define pgprot_noncached(prot)	__pgprot(pgprot_val(prot) | _PAGE_CACHE)
+
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+#define mk_pte_huge(entry) \
+	((entry).pte |= _PAGE_PRESENT | _PAGE_PSE | _PAGE_VALID)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte_val(pte) &= _PAGE_CHG_MASK;
+	pte_val(pte) |= pgprot_val(newprot);
+	return pte;
+}
+
+#define page_pte(page)	page_pte_prot((page), __pgprot(0))
+
+#define pmd_page_kernel(pmd) \
+	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#define pmd_page(pmd)	pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+
+#define pmd_large(pmd) \
+	((pmd_val(pmd) & (_PAGE_PSE | _PAGE_PRESENT)) == \
+	 (_PAGE_PSE | _PAGE_PRESENT))
+
+/*
+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
+ *
+ * this macro returns the index of the entry in the pgd page which would
+ * control the given virtual address
+ */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
+#define pgd_offset(mm, address)	((mm)->pgd + pgd_index(address))
+
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
+#define pgd_offset_k(address)	pgd_offset(&init_mm, address)
+
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
+#define pmd_index(address) \
+	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define pte_index(address) \
+	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+#define pte_offset_kernel(dir, address) \
+	((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
+
+/*
+ * Make a given kernel text page executable/non-executable.
+ * Returns the previous executability setting of that page (which
+ * is used to restore the previous state). Used by the SMP bootup code.
+ * NOTE: this is an __init function for security reasons.
+ */
+static inline int set_kernel_exec(unsigned long vaddr, int enable)
+{
+	return 0;
+}
+
+#define pte_offset_map(dir, address) \
+	((pte_t *) page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
+#define pte_unmap(pte)		do {} while (0)
+#define pte_unmap_nested(pte)	do {} while (0)
+
+/*
+ * The MN10300 has external MMU info in the form of a TLB: this is adapted from
+ * the kernel page tables containing the necessary information by tlb-mn10300.S
+ */
+extern void update_mmu_cache(struct vm_area_struct *vma,
+			     unsigned long address, pte_t pte);
+
+#endif /* !__ASSEMBLY__ */
+
+#define kern_addr_valid(addr)	(1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+	remap_pfn_range((vma), (vaddr), (pfn), (size), (prot))
+
+#define MK_IOSPACE_PFN(space, pfn)	(pfn)
+#define GET_IOSPACE(pfn)		0
+#define GET_PFN(pfn)			(pfn)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTEP_MKDIRTY
+#define __HAVE_ARCH_PTE_SAME
+#include <asm-generic/pgtable.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pio-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pio-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/pio-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/pio-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,233 @@
+/* MN10300 On-board I/O port module registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PIO_REGS_H
+#define _ASM_PIO_REGS_H
+
+#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
+
+#ifdef __KERNEL__
+
+/* I/O port 0 */
+#define	P0MD			__SYSREG(0xdb000000, u16)	/* mode reg */
+#define P0MD_0			0x0003	/* mask */
+#define P0MD_0_IN		0x0000	/* input mode */
+#define P0MD_0_OUT		0x0001	/* output mode */
+#define P0MD_0_TM0IO		0x0002	/* timer 0 I/O mode */
+#define P0MD_0_EYECLK		0x0003	/* test signal output (clock) */
+#define P0MD_1			0x000c
+#define P0MD_1_IN		0x0000
+#define P0MD_1_OUT		0x0004
+#define P0MD_1_TM1IO		0x0008	/* timer 1 I/O mode */
+#define P0MD_1_EYED		0x000c	/* test signal output (data) */
+#define P0MD_2			0x0030
+#define P0MD_2_IN		0x0000
+#define P0MD_2_OUT		0x0010
+#define P0MD_2_TM2IO		0x0020	/* timer 2 I/O mode */
+#define P0MD_3			0x00c0
+#define P0MD_3_IN		0x0000
+#define P0MD_3_OUT		0x0040
+#define P0MD_3_TM3IO		0x0080	/* timer 3 I/O mode */
+#define P0MD_4			0x0300
+#define P0MD_4_IN		0x0000
+#define P0MD_4_OUT		0x0100
+#define P0MD_4_TM4IO		0x0200	/* timer 4 I/O mode */
+#define P0MD_4_XCTS		0x0300	/* XCTS input for serial port 2 */
+#define P0MD_5			0x0c00
+#define P0MD_5_IN		0x0000
+#define P0MD_5_OUT		0x0400
+#define P0MD_5_TM5IO		0x0800	/* timer 5 I/O mode */
+#define P0MD_6			0x3000
+#define P0MD_6_IN		0x0000
+#define P0MD_6_OUT		0x1000
+#define P0MD_6_TM6IOA		0x2000	/* timer 6 I/O mode A */
+#define P0MD_7			0xc000
+#define P0MD_7_IN		0x0000
+#define P0MD_7_OUT		0x4000
+#define P0MD_7_TM6IOB		0x8000	/* timer 6 I/O mode B */
+
+#define	P0IN			__SYSREG(0xdb000004, u8)	/* in reg */
+#define	P0OUT			__SYSREG(0xdb000008, u8)	/* out reg */
+
+#define	P0TMIO			__SYSREG(0xdb00000c, u8)	/* TM pin I/O control reg */
+#define P0TMIO_TM0_IN		0x00
+#define P0TMIO_TM0_OUT		0x01
+#define P0TMIO_TM1_IN		0x00
+#define P0TMIO_TM1_OUT		0x02
+#define P0TMIO_TM2_IN		0x00
+#define P0TMIO_TM2_OUT		0x04
+#define P0TMIO_TM3_IN		0x00
+#define P0TMIO_TM3_OUT		0x08
+#define P0TMIO_TM4_IN		0x00
+#define P0TMIO_TM4_OUT		0x10
+#define P0TMIO_TM5_IN		0x00
+#define P0TMIO_TM5_OUT		0x20
+#define P0TMIO_TM6A_IN		0x00
+#define P0TMIO_TM6A_OUT		0x40
+#define P0TMIO_TM6B_IN		0x00
+#define P0TMIO_TM6B_OUT		0x80
+
+/* I/O port 1 */
+#define	P1MD			__SYSREG(0xdb000100, u16)	/* mode reg */
+#define P1MD_0			0x0003	/* mask */
+#define P1MD_0_IN		0x0000	/* input mode */
+#define P1MD_0_OUT		0x0001	/* output mode */
+#define P1MD_0_TM7IO		0x0002	/* timer 7 I/O mode */
+#define P1MD_0_ADTRG		0x0003	/* A/D converter trigger mode */
+#define P1MD_1			0x000c
+#define P1MD_1_IN		0x0000
+#define P1MD_1_OUT		0x0004
+#define P1MD_1_TM8IO		0x0008	/* timer 8 I/O mode */
+#define P1MD_1_XDMR0		0x000c	/* DMA request input 0 mode */
+#define P1MD_2			0x0030
+#define P1MD_2_IN		0x0000
+#define P1MD_2_OUT		0x0010
+#define P1MD_2_TM9IO		0x0020	/* timer 9 I/O mode */
+#define P1MD_2_XDMR1		0x0030	/* DMA request input 1 mode */
+#define P1MD_3			0x00c0
+#define P1MD_3_IN		0x0000
+#define P1MD_3_OUT		0x0040
+#define P1MD_3_TM10IO		0x0080	/* timer 10 I/O mode */
+#define P1MD_3_FRQS0		0x00c0	/* CPU clock multiplier setting input 0 mode */
+#define P1MD_4			0x0300
+#define P1MD_4_IN		0x0000
+#define P1MD_4_OUT		0x0100
+#define P1MD_4_TM11IO		0x0200	/* timer 11 I/O mode */
+#define P1MD_4_FRQS1		0x0300	/* CPU clock multiplier setting input 1 mode */
+
+#define	P1IN			__SYSREG(0xdb000104, u8)	/* in reg */
+#define	P1OUT			__SYSREG(0xdb000108, u8)	/* out reg */
+#define	P1TMIO			__SYSREG(0xdb00010c, u8)	/* TM pin I/O control reg */
+#define P1TMIO_TM11_IN		0x00
+#define P1TMIO_TM11_OUT		0x01
+#define P1TMIO_TM10_IN		0x00
+#define P1TMIO_TM10_OUT		0x02
+#define P1TMIO_TM9_IN		0x00
+#define P1TMIO_TM9_OUT		0x04
+#define P1TMIO_TM8_IN		0x00
+#define P1TMIO_TM8_OUT		0x08
+#define P1TMIO_TM7_IN		0x00
+#define P1TMIO_TM7_OUT		0x10
+
+/* I/O port 2 */
+#define	P2MD			__SYSREG(0xdb000200, u16)	/* mode reg */
+#define P2MD_0			0x0003	/* mask */
+#define P2MD_0_IN		0x0000	/* input mode */
+#define P2MD_0_OUT		0x0001	/* output mode */
+#define P2MD_0_BOOTBW		0x0003	/* boot bus width selector mode */
+#define P2MD_1			0x000c
+#define P2MD_1_IN		0x0000
+#define P2MD_1_OUT		0x0004
+#define P2MD_1_BOOTSEL		0x000c	/* boot device selector mode */
+#define P2MD_2			0x0030
+#define P2MD_2_IN		0x0000
+#define P2MD_2_OUT		0x0010
+#define P2MD_3			0x00c0
+#define P2MD_3_IN		0x0000
+#define P2MD_3_OUT		0x0040
+#define P2MD_3_CKIO		0x00c0	/* mode */
+#define P2MD_4			0x0300
+#define P2MD_4_IN		0x0000
+#define P2MD_4_OUT		0x0100
+#define P2MD_4_CMOD		0x0300	/* mode */
+
+#define	P2IN			__SYSREG(0xdb000204, u8)	/* in reg */
+#define	P2OUT			__SYSREG(0xdb000208, u8)	/* out reg */
+#define	P2TMIO			__SYSREG(0xdb00020c, u8)	/* TM pin I/O control reg */
+
+/* I/O port 3 */
+#define	P3MD			__SYSREG(0xdb000300, u16)	/* mode reg */
+#define P3MD_0			0x0003	/* mask */
+#define P3MD_0_IN		0x0000	/* input mode */
+#define P3MD_0_OUT		0x0001	/* output mode */
+#define P3MD_0_AFRXD		0x0002	/* AFR interface mode */
+#define P3MD_1			0x000c
+#define P3MD_1_IN		0x0000
+#define P3MD_1_OUT		0x0004
+#define P3MD_1_AFTXD		0x0008	/* AFR interface mode */
+#define P3MD_2			0x0030
+#define P3MD_2_IN		0x0000
+#define P3MD_2_OUT		0x0010
+#define P3MD_2_AFSCLK		0x0020	/* AFR interface mode */
+#define P3MD_3			0x00c0
+#define P3MD_3_IN		0x0000
+#define P3MD_3_OUT		0x0040
+#define P3MD_3_AFFS		0x0080	/* AFR interface mode */
+#define P3MD_4			0x0300
+#define P3MD_4_IN		0x0000
+#define P3MD_4_OUT		0x0100
+#define P3MD_4_AFEHC		0x0200	/* AFR interface mode */
+
+#define	P3IN			__SYSREG(0xdb000304, u8)	/* in reg */
+#define	P3OUT			__SYSREG(0xdb000308, u8)	/* out reg */
+
+/* I/O port 4 */
+#define	P4MD			__SYSREG(0xdb000400, u16)	/* mode reg */
+#define P4MD_0			0x0003	/* mask */
+#define P4MD_0_IN		0x0000	/* input mode */
+#define P4MD_0_OUT		0x0001	/* output mode */
+#define P4MD_0_SCL0		0x0002	/* I2C/serial mode */
+#define P4MD_1			0x000c
+#define P4MD_1_IN		0x0000
+#define P4MD_1_OUT		0x0004
+#define P4MD_1_SDA0		0x0008
+#define P4MD_2			0x0030
+#define P4MD_2_IN		0x0000
+#define P4MD_2_OUT		0x0010
+#define P4MD_2_SCL1		0x0020
+#define P4MD_3			0x00c0
+#define P4MD_3_IN		0x0000
+#define P4MD_3_OUT		0x0040
+#define P4MD_3_SDA1		0x0080
+#define P4MD_4			0x0300
+#define P4MD_4_IN		0x0000
+#define P4MD_4_OUT		0x0100
+#define P4MD_4_SBO0		0x0200
+#define P4MD_5			0x0c00
+#define P4MD_5_IN		0x0000
+#define P4MD_5_OUT		0x0400
+#define P4MD_5_SBO1		0x0800
+#define P4MD_6			0x3000
+#define P4MD_6_IN		0x0000
+#define P4MD_6_OUT		0x1000
+#define P4MD_6_SBT0		0x2000
+#define P4MD_7			0xc000
+#define P4MD_7_IN		0x0000
+#define P4MD_7_OUT		0x4000
+#define P4MD_7_SBT1		0x8000
+
+#define	P4IN			__SYSREG(0xdb000404, u8)	/* in reg */
+#define	P4OUT			__SYSREG(0xdb000408, u8)	/* out reg */
+
+/* I/O port 5 */
+#define	P5MD			__SYSREG(0xdb000500, u16)	/* mode reg */
+#define P5MD_0			0x0003	/* mask */
+#define P5MD_0_IN		0x0000	/* input mode */
+#define P5MD_0_OUT		0x0001	/* output mode */
+#define P5MD_0_IRTXD		0x0002	/* IrDA mode */
+#define P5MD_0_SOUT		0x0004	/* serial mode */
+#define P5MD_1			0x000c
+#define P5MD_1_IN		0x0000
+#define P5MD_1_OUT		0x0004
+#define P5MD_1_IRRXDS		0x0008	/* IrDA mode */
+#define P5MD_1_SIN		0x000c	/* serial mode */
+#define P5MD_2			0x0030
+#define P5MD_2_IN		0x0000
+#define P5MD_2_OUT		0x0010
+#define P5MD_2_IRRXDF		0x0020	/* IrDA mode */
+
+#define	P5IN			__SYSREG(0xdb000504, u8)	/* in reg */
+#define	P5OUT			__SYSREG(0xdb000508, u8)	/* out reg */
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PIO_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/poll.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/poll.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/poll.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/poll.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/posix_types.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/posix_types.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/posix_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/posix_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,132 @@
+/* MN10300 POSIX types
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+	int	val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+	int	__val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef	__FD_SET
+static inline void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef	__FD_CLR
+static inline void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+
+#undef	__FD_ISSET
+static inline int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{
+	unsigned long __tmp = __fd / __NFDBITS;
+	unsigned long __rem = __fd % __NFDBITS;
+	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef	__FD_ZERO
+static inline void __FD_ZERO(__kernel_fd_set *__p)
+{
+	unsigned long *__tmp = __p->fds_bits;
+	int __i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 16:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			__tmp[ 8] = 0; __tmp[ 9] = 0;
+			__tmp[10] = 0; __tmp[11] = 0;
+			__tmp[12] = 0; __tmp[13] = 0;
+			__tmp[14] = 0; __tmp[15] = 0;
+			return;
+
+		case 8:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			__tmp[ 4] = 0; __tmp[ 5] = 0;
+			__tmp[ 6] = 0; __tmp[ 7] = 0;
+			return;
+
+		case 4:
+			__tmp[ 0] = 0; __tmp[ 1] = 0;
+			__tmp[ 2] = 0; __tmp[ 3] = 0;
+			return;
+		}
+	}
+	__i = __FDSET_LONGS;
+	while (__i) {
+		__i--;
+		*__tmp = 0;
+		__tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif /* _ASM_POSIX_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/processor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,186 @@
+/* MN10300 Processor specifics
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/cpu-regs.h>
+#include <linux/threads.h>
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+struct mm_struct;
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()			\
+({						\
+	void *__pc;				\
+	asm("mov pc,%0" : "=a"(__pc));		\
+	__pc;					\
+})
+
+extern void show_registers(struct pt_regs *regs);
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ *  Members of this structure are referenced in head.S, so think twice
+ *  before touching them. [mj]
+ */
+
+struct mn10300_cpuinfo {
+	int		type;
+	unsigned long	loops_per_sec;
+	char		hard_math;
+	unsigned long	*pgd_quick;
+	unsigned long	*pte_quick;
+	unsigned long	pgtable_cache_sz;
+};
+
+extern struct mn10300_cpuinfo boot_cpu_data;
+
+#define cpu_data &boot_cpu_data
+#define current_cpu_data boot_cpu_data
+
+extern void identify_cpu(struct mn10300_cpuinfo *);
+extern void print_cpu_info(struct mn10300_cpuinfo *);
+extern void dodgy_tsc(void);
+#define cpu_relax() barrier()
+
+/*
+ * User space process size: 1.75GB (default).
+ */
+#define TASK_SIZE		0x70000000
+
+/*
+ * Where to put the userspace stack by default
+ */
+#define STACK_TOP		0x70000000
+#define STACK_TOP_MAX		STACK_TOP
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	0x30000000
+
+typedef struct {
+	unsigned long	seg;
+} mm_segment_t;
+
+struct fpu_state_struct {
+	unsigned long	fs[32];		/* fpu registers */
+	unsigned long	fpcr;		/* fpu control register */
+};
+
+struct thread_struct {
+	struct pt_regs		*uregs;		/* userspace register frame */
+	unsigned long		pc;		/* kernel PC */
+	unsigned long		sp;		/* kernel SP */
+	unsigned long		a3;		/* kernel FP */
+	unsigned long		wchan;
+	unsigned long		usp;
+	struct pt_regs		*__frame;
+	unsigned long		fpu_flags;
+#define THREAD_USING_FPU	0x00000001	/* T if this task is using the FPU */
+	struct fpu_state_struct	fpu_state;
+};
+
+#define INIT_THREAD				\
+{						\
+	.uregs		= init_uregs,		\
+	.pc		= 0,			\
+	.sp		= 0,			\
+	.a3		= 0,			\
+	.wchan		= 0,			\
+	.__frame	= NULL,			\
+}
+
+#define INIT_MMAP \
+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \
+  NULL, NULL }
+
+/*
+ * do necessary setup to start up a newly executed thread
+ * - need to discard the frame stacked by the kernel thread invoking the execve
+ *   syscall (see RESTORE_ALL macro)
+ */
+#define start_thread(regs, new_pc, new_sp) do {		\
+	set_fs(USER_DS);				\
+	__frame = current->thread.uregs;		\
+	__frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;	\
+	__frame->pc = new_pc;				\
+	__frame->sp = new_sp;				\
+} while (0)
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+extern void prepare_to_copy(struct task_struct *tsk);
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define task_pt_regs(task)						\
+({									\
+       struct pt_regs *__regs__;					\
+       __regs__ = (struct pt_regs *) (KSTK_TOP(task_stack_page(task)) - 8); \
+       __regs__ - 1;							\
+})
+
+#define KSTK_EIP(task) (task_pt_regs(task)->pc)
+#define KSTK_ESP(task) (task_pt_regs(task)->sp)
+
+#define KSTK_TOP(info)				\
+({						\
+	(unsigned long)(info) + THREAD_SIZE;	\
+})
+
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+
+static inline void prefetch(const void *x)
+{
+#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_PROC_MN103E010
+	asm volatile ("nop; nop; dcpf (%0)" : : "r"(x));
+#else
+	asm volatile ("dcpf (%0)" : : "r"(x));
+#endif
+#endif
+}
+
+static inline void prefetchw(const void *x)
+{
+#ifndef CONFIG_MN10300_CACHE_DISABLED
+#ifdef CONFIG_MN10300_PROC_MN103E010
+	asm volatile ("nop; nop; dcpf (%0)" : : "r"(x));
+#else
+	asm volatile ("dcpf (%0)" : : "r"(x));
+#endif
+#endif
+}
+
+#endif /* _ASM_PROCESSOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ptrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,103 @@
+/* MN10300 Exception frame layout and ptrace constants
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#define PT_A3		0
+#define PT_A2		1
+#define PT_D3		2
+#define	PT_D2		3
+#define PT_MCVF		4
+#define	PT_MCRL		5
+#define PT_MCRH		6
+#define	PT_MDRQ		7
+#define	PT_E1		8
+#define	PT_E0		9
+#define	PT_E7		10
+#define	PT_E6		11
+#define	PT_E5		12
+#define	PT_E4		13
+#define	PT_E3		14
+#define	PT_E2		15
+#define	PT_SP		16
+#define	PT_LAR		17
+#define	PT_LIR		18
+#define	PT_MDR		19
+#define	PT_A1		20
+#define	PT_A0		21
+#define	PT_D1		22
+#define	PT_D0		23
+#define PT_ORIG_D0	24
+#define	PT_EPSW		25
+#define	PT_PC		26
+#define NR_PTREGS	27
+
+#ifndef __ASSEMBLY__
+/*
+ * This defines the way registers are stored in the event of an exception
+ * - the strange order is due to the MOVM instruction
+ */
+struct pt_regs {
+	unsigned long		a3;		/* syscall arg 3 */
+	unsigned long		a2;		/* syscall arg 4 */
+	unsigned long		d3;		/* syscall arg 5 */
+	unsigned long		d2;		/* syscall arg 6 */
+	unsigned long		mcvf;
+	unsigned long		mcrl;
+	unsigned long		mcrh;
+	unsigned long		mdrq;
+	unsigned long		e1;
+	unsigned long		e0;
+	unsigned long		e7;
+	unsigned long		e6;
+	unsigned long		e5;
+	unsigned long		e4;
+	unsigned long		e3;
+	unsigned long		e2;
+	unsigned long		sp;
+	unsigned long		lar;
+	unsigned long		lir;
+	unsigned long		mdr;
+	unsigned long		a1;
+	unsigned long		a0;		/* syscall arg 1 */
+	unsigned long		d1;		/* syscall arg 2 */
+	unsigned long		d0;		/* syscall ret */
+	struct pt_regs		*next;		/* next frame pointer */
+	unsigned long		orig_d0;	/* syscall number */
+	unsigned long		epsw;
+	unsigned long		pc;
+};
+#endif
+
+extern struct pt_regs *__frame; /* current frame pointer */
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+
+/* options set using PTRACE_SETOPTIONS */
+#define PTRACE_O_TRACESYSGOOD     0x00000001
+
+#if defined(__KERNEL__)
+
+#if !defined(__ASSEMBLY__)
+#define user_mode(regs)			(((regs)->epsw & EPSW_nSL) == EPSW_nSL)
+#define instruction_pointer(regs)	((regs)->pc)
+extern void show_regs(struct pt_regs *);
+#endif  /*  !__ASSEMBLY  */
+
+#define profile_pc(regs) ((regs)->pc)
+
+#endif  /*  __KERNEL__  */
+
+#endif /* _ASM_PTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/reset-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/reset-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/reset-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/reset-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,64 @@
+/* MN10300 Reset controller and watchdog timer definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_RESET_REGS_H
+#define _ASM_RESET_REGS_H
+
+#include <asm/cpu-regs.h>
+#include <asm/exceptions.h>
+
+#ifdef __KERNEL__
+
+#ifdef CONFIG_MN10300_WD_TIMER
+#define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
+#endif
+
+/*
+ * watchdog timer registers
+ */
+#define WDBC			__SYSREGC(0xc0001000, u8) /* watchdog binary counter reg */
+
+#define WDCTR			__SYSREG(0xc0001002, u8)  /* watchdog timer control reg */
+#define WDCTR_WDCK		0x07	/* clock source selection */
+#define WDCTR_WDCK_256th	0x00	/* - OSCI/256 */
+#define WDCTR_WDCK_1024th	0x01	/* - OSCI/1024 */
+#define WDCTR_WDCK_2048th	0x02	/* - OSCI/2048 */
+#define WDCTR_WDCK_16384th	0x03	/* - OSCI/16384 */
+#define WDCTR_WDCK_65536th	0x04	/* - OSCI/65536 */
+#define WDCTR_WDRST		0x40	/* binary counter reset */
+#define WDCTR_WDCNE		0x80	/* watchdog timer enable */
+
+#define RSTCTR			__SYSREG(0xc0001004, u8) /* reset control reg */
+#define RSTCTR_CHIPRST		0x01	/* chip reset */
+#define RSTCTR_DBFRST		0x02	/* double fault reset flag */
+#define RSTCTR_WDTRST		0x04	/* watchdog timer reset flag */
+#define RSTCTR_WDREN		0x08	/* watchdog timer reset enable */
+
+#ifndef __ASSEMBLY__
+
+static inline void mn10300_proc_hard_reset(void)
+{
+	RSTCTR &= ~RSTCTR_CHIPRST;
+	RSTCTR |= RSTCTR_CHIPRST;
+}
+
+extern unsigned int watchdog_alert_counter;
+
+extern void watchdog_go(void);
+extern asmlinkage void watchdog_handler(void);
+extern asmlinkage
+void watchdog_interrupt(struct pt_regs *, enum exception_code);
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_RESET_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/resource.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/resource.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/resource.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/resource.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/rtc.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/rtc.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/rtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/rtc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,41 @@
+/* MN10300 Real time clock definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_RTC_H
+#define _ASM_RTC_H
+
+#ifdef CONFIG_MN10300_RTC
+
+#include <linux/init.h>
+
+extern void check_rtc_time(void);
+extern void __init calibrate_clock(void);
+extern unsigned long __init get_initial_rtc_time(void);
+
+#else /* !CONFIG_MN10300_RTC */
+
+static inline void check_rtc_time(void)
+{
+}
+
+static inline void calibrate_clock(void)
+{
+}
+
+static inline unsigned long get_initial_rtc_time(void)
+{
+	return 0;
+}
+
+#endif /* !CONFIG_MN10300_RTC */
+
+#include <asm-generic/rtc.h>
+
+#endif /* _ASM_RTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/rtc-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/rtc-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/rtc-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/rtc-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,86 @@
+/* MN10300 on-chip Real-Time Clock registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_RTC_REGS_H
+#define _ASM_RTC_REGS_H
+
+#include <asm/intctl-regs.h>
+
+#ifdef __KERNEL__
+
+#define RTSCR			__SYSREG(0xd8600000, u8) /* RTC seconds count reg */
+#define RTSAR			__SYSREG(0xd8600001, u8) /* RTC seconds alarm reg */
+#define RTMCR			__SYSREG(0xd8600002, u8) /* RTC minutes count reg */
+#define RTMAR			__SYSREG(0xd8600003, u8) /* RTC minutes alarm reg */
+#define RTHCR			__SYSREG(0xd8600004, u8) /* RTC hours count reg */
+#define RTHAR			__SYSREG(0xd8600005, u8) /* RTC hours alarm reg */
+#define RTDWCR			__SYSREG(0xd8600006, u8) /* RTC day of the week count reg */
+#define RTDMCR			__SYSREG(0xd8600007, u8) /* RTC days count reg */
+#define RTMTCR			__SYSREG(0xd8600008, u8) /* RTC months count reg */
+#define RTYCR			__SYSREG(0xd8600009, u8) /* RTC years count reg */
+
+#define RTCRA			__SYSREG(0xd860000a, u8)/* RTC control reg A */
+#define RTCRA_RS		0x0f	/* periodic timer interrupt cycle setting */
+#define RTCRA_RS_NONE		0x00	/* - off */
+#define RTCRA_RS_3_90625ms	0x01	/* - 3.90625ms	(1/256s) */
+#define RTCRA_RS_7_8125ms	0x02	/* - 7.8125ms	(1/128s) */
+#define RTCRA_RS_122_070us	0x03	/* - 122.070us	(1/8192s) */
+#define RTCRA_RS_244_141us	0x04	/* - 244.141us	(1/4096s) */
+#define RTCRA_RS_488_281us	0x05	/* - 488.281us	(1/2048s) */
+#define RTCRA_RS_976_5625us	0x06	/* - 976.5625us	(1/1024s) */
+#define RTCRA_RS_1_953125ms	0x07	/* - 1.953125ms	(1/512s) */
+#define RTCRA_RS_3_90624ms	0x08	/* - 3.90624ms	(1/256s) */
+#define RTCRA_RS_7_8125ms_b	0x09	/* - 7.8125ms	(1/128s) */
+#define RTCRA_RS_15_625ms	0x0a	/* - 15.625ms	(1/64s) */
+#define RTCRA_RS_31_25ms	0x0b	/* - 31.25ms	(1/32s) */
+#define RTCRA_RS_62_5ms		0x0c	/* - 62.5ms	(1/16s) */
+#define RTCRA_RS_125ms		0x0d	/* - 125ms	(1/8s) */
+#define RTCRA_RS_250ms		0x0e	/* - 250ms	(1/4s) */
+#define RTCRA_RS_500ms		0x0f	/* - 500ms	(1/2s) */
+#define RTCRA_DVR		0x40	/* divider reset */
+#define RTCRA_UIP		0x80	/* clock update flag */
+
+#define RTCRB			__SYSREG(0xd860000b, u8) /* RTC control reg B */
+#define RTCRB_DSE		0x01	/* daylight savings time enable */
+#define RTCRB_TM		0x02	/* time format */
+#define RTCRB_TM_12HR		0x00	/* - 12 hour format */
+#define RTCRB_TM_24HR		0x02	/* - 24 hour format */
+#define RTCRB_DM		0x04	/* numeric value format */
+#define RTCRB_DM_BCD		0x00	/* - BCD */
+#define RTCRB_DM_BINARY		0x04	/* - binary */
+#define RTCRB_UIE		0x10	/* update interrupt disable */
+#define RTCRB_AIE		0x20	/* alarm interrupt disable */
+#define RTCRB_PIE		0x40	/* periodic interrupt disable */
+#define RTCRB_SET		0x80	/* clock update enable */
+
+#define RTSRC			__SYSREG(0xd860000c, u8) /* RTC status reg C */
+#define RTSRC_UF		0x10	/* update end interrupt flag */
+#define RTSRC_AF		0x20	/* alarm interrupt flag */
+#define RTSRC_PF		0x40	/* periodic interrupt flag */
+#define RTSRC_IRQF		0x80	/* interrupt flag */
+
+#define RTIRQ			32
+#define RTICR			GxICR(RTIRQ)
+
+/*
+ * MC146818 RTC compatibility defs for the MN10300 on-chip RTC
+ */
+#define RTC_PORT(x)		0xd8600000
+#define RTC_ALWAYS_BCD		1	/* RTC operates in binary mode */
+
+#define CMOS_READ(addr)		__SYSREG(0xd8600000 + (addr), u8)
+#define CMOS_WRITE(val, addr)	\
+	do { __SYSREG(0xd8600000 + (addr), u8) = val; } while (0)
+
+#define RTC_IRQ			RTIRQ
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_RTC_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/scatterlist.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+/* MN10300 Scatterlist definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+#include <asm/types.h>
+
+/*
+ * Drivers must set either ->address or (preferred) page and ->offset
+ * to indicate where data must be transferred to/from.
+ *
+ * Using page is recommended since it handles highmem data as well as
+ * low mem. ->address is restricted to data which has a virtual mapping, and
+ * it will go away in the future. Updating to page can be automated very
+ * easily -- something like
+ *
+ * sg->address = some_ptr;
+ *
+ * can be rewritten as
+ *
+ * sg_set_page(virt_to_page(some_ptr));
+ * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ *
+ * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
+ */
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
+	unsigned int	offset;		/* for highmem, page offset */
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns.
+ */
+#define sg_dma_address(sg)	((sg)->dma_address)
+#define sg_dma_len(sg)		((sg)->length)
+
+#endif /* _ASM_SCATTERLIST_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sections.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/sections.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sembuf.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sembuf.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sembuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sembuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for MN10300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SEMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/serial.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/serial.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+/* Standard UART definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+/*
+ * The ASB2305 has an 18.432 MHz clock the UART
+ */
+#define BASE_BAUD	(18432000 / 16)
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS	(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+#define STD_COM4_FLAGS	(ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS	(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM4_FLAGS	ASYNC_BOOT_AUTOCONF
+#endif
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define FOURPORT_FLAGS	ASYNC_FOURPORT
+#define ACCENT_FLAGS	0
+#define BOCA_FLAGS	0
+#define HUB6_FLAGS	0
+#define RS_TABLE_SIZE	64
+#else
+#define RS_TABLE_SIZE
+#endif
+
+#include <unit/serial.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/serial-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/serial-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/serial-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/serial-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,160 @@
+/* MN10300 on-board serial port module registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SERIAL_REGS_H
+#define _ASM_SERIAL_REGS_H
+
+#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
+
+#ifdef __KERNEL__
+
+/* serial port 0 */
+#define	SC0CTR			__SYSREG(0xd4002000, u16)	/* control reg */
+#define	SC01CTR_CK		0x0007	/* clock source select */
+#define	SC0CTR_CK_TM8UFLOW_8	0x0000	/* - 1/8 timer 8 underflow (serial port 0 only) */
+#define	SC1CTR_CK_TM9UFLOW_8	0x0000	/* - 1/8 timer 9 underflow (serial port 1 only) */
+#define	SC01CTR_CK_IOCLK_8	0x0001	/* - 1/8 IOCLK */
+#define	SC01CTR_CK_IOCLK_32	0x0002	/* - 1/32 IOCLK */
+#define	SC0CTR_CK_TM2UFLOW_2	0x0003	/* - 1/2 timer 2 underflow (serial port 0 only) */
+#define	SC1CTR_CK_TM3UFLOW_2	0x0003	/* - 1/2 timer 3 underflow (serial port 1 only) */
+#define	SC0CTR_CK_TM0UFLOW_8	0x0004	/* - 1/8 timer 1 underflow (serial port 0 only) */
+#define	SC1CTR_CK_TM1UFLOW_8	0x0004	/* - 1/8 timer 2 underflow (serial port 1 only) */
+#define	SC0CTR_CK_TM2UFLOW_8	0x0005	/* - 1/8 timer 2 underflow (serial port 0 only) */
+#define	SC1CTR_CK_TM3UFLOW_8	0x0005	/* - 1/8 timer 3 underflow (serial port 1 only) */
+#define	SC01CTR_CK_EXTERN_8	0x0006	/* - 1/8 external closk */
+#define	SC01CTR_CK_EXTERN	0x0007	/* - external closk */
+#define	SC01CTR_STB		0x0008	/* stop bit select */
+#define	SC01CTR_STB_1BIT	0x0000	/* - 1 stop bit */
+#define	SC01CTR_STB_2BIT	0x0008	/* - 2 stop bits */
+#define	SC01CTR_PB		0x0070	/* parity bit select */
+#define	SC01CTR_PB_NONE		0x0000	/* - no parity */
+#define	SC01CTR_PB_FIXED0	0x0040	/* - fixed at 0 */
+#define	SC01CTR_PB_FIXED1	0x0050	/* - fixed at 1 */
+#define	SC01CTR_PB_EVEN		0x0060	/* - even parity */
+#define	SC01CTR_PB_ODD		0x0070	/* - odd parity */
+#define	SC01CTR_CLN		0x0080	/* character length */
+#define	SC01CTR_CLN_7BIT	0x0000	/* - 7 bit chars */
+#define	SC01CTR_CLN_8BIT	0x0080	/* - 8 bit chars */
+#define	SC01CTR_TOE		0x0100	/* T input output enable */
+#define	SC01CTR_OD		0x0200	/* bit order select */
+#define	SC01CTR_OD_LSBFIRST	0x0000	/* - LSB first */
+#define	SC01CTR_OD_MSBFIRST	0x0200	/* - MSB first */
+#define	SC01CTR_MD		0x0c00	/* mode select */
+#define SC01CTR_MD_STST_SYNC	0x0000	/* - start-stop synchronous */
+#define SC01CTR_MD_CLOCK_SYNC1	0x0400	/* - clock synchronous 1 */
+#define SC01CTR_MD_I2C		0x0800	/* - I2C mode */
+#define SC01CTR_MD_CLOCK_SYNC2	0x0c00	/* - clock synchronous 2 */
+#define	SC01CTR_IIC		0x1000	/* I2C mode select */
+#define	SC01CTR_BKE		0x2000	/* break transmit enable */
+#define	SC01CTR_RXE		0x4000	/* receive enable */
+#define	SC01CTR_TXE		0x8000	/* transmit enable */
+
+#define	SC0ICR			__SYSREG(0xd4002004, u8)	/* interrupt control reg */
+#define SC01ICR_DMD		0x80	/* output data mode */
+#define SC01ICR_TD		0x20	/* transmit DMA trigger cause */
+#define SC01ICR_TI		0x10	/* transmit interrupt cause */
+#define SC01ICR_RES		0x04	/* receive error select */
+#define SC01ICR_RI		0x01	/* receive interrupt cause */
+
+#define	SC0TXB			__SYSREG(0xd4002008, u8)	/* transmit buffer reg */
+#define	SC0RXB			__SYSREG(0xd4002009, u8)	/* receive buffer reg */
+
+#define	SC0STR			__SYSREG(0xd400200c, u16)	/* status reg */
+#define SC01STR_OEF		0x0001	/* overrun error found */
+#define SC01STR_PEF		0x0002	/* parity error found */
+#define SC01STR_FEF		0x0004	/* framing error found */
+#define SC01STR_RBF		0x0010	/* receive buffer status */
+#define SC01STR_TBF		0x0020	/* transmit buffer status */
+#define SC01STR_RXF		0x0040	/* receive status */
+#define SC01STR_TXF		0x0080	/* transmit status */
+#define SC01STR_STF		0x0100	/* I2C start sequence found */
+#define SC01STR_SPF		0x0200	/* I2C stop sequence found */
+
+#define SC0RXIRQ		20	/* timer 0 Receive IRQ */
+#define SC0TXIRQ		21	/* timer 0 Transmit IRQ */
+
+#define	SC0RXICR		GxICR(SC0RXIRQ)	/* serial 0 receive intr ctrl reg */
+#define	SC0TXICR		GxICR(SC0TXIRQ)	/* serial 0 transmit intr ctrl reg */
+
+/* serial port 1 */
+#define	SC1CTR			__SYSREG(0xd4002010, u16)	/* serial port 1 control */
+#define	SC1ICR			__SYSREG(0xd4002014, u8)	/* interrupt control reg */
+#define	SC1TXB			__SYSREG(0xd4002018, u8)	/* transmit buffer reg */
+#define	SC1RXB			__SYSREG(0xd4002019, u8)	/* receive buffer reg */
+#define	SC1STR			__SYSREG(0xd400201c, u16)	/* status reg */
+
+#define SC1RXIRQ		22	/* timer 1 Receive IRQ */
+#define SC1TXIRQ		23	/* timer 1 Transmit IRQ */
+
+#define	SC1RXICR		GxICR(SC1RXIRQ)	/* serial 1 receive intr ctrl reg */
+#define	SC1TXICR		GxICR(SC1TXIRQ)	/* serial 1 transmit intr ctrl reg */
+
+/* serial port 2 */
+#define	SC2CTR			__SYSREG(0xd4002020, u16)	/* control reg */
+#define	SC2CTR_CK		0x0003	/* clock source select */
+#define	SC2CTR_CK_TM10UFLOW	0x0000	/* - timer 10 underflow */
+#define	SC2CTR_CK_TM2UFLOW	0x0001	/* - timer 2 underflow */
+#define	SC2CTR_CK_EXTERN	0x0002	/* - external closk */
+#define	SC2CTR_CK_TM3UFLOW	0x0003	/* - timer 3 underflow */
+#define	SC2CTR_STB		0x0008	/* stop bit select */
+#define	SC2CTR_STB_1BIT		0x0000	/* - 1 stop bit */
+#define	SC2CTR_STB_2BIT		0x0008	/* - 2 stop bits */
+#define	SC2CTR_PB		0x0070	/* parity bit select */
+#define	SC2CTR_PB_NONE		0x0000	/* - no parity */
+#define	SC2CTR_PB_FIXED0	0x0040	/* - fixed at 0 */
+#define	SC2CTR_PB_FIXED1	0x0050	/* - fixed at 1 */
+#define	SC2CTR_PB_EVEN		0x0060	/* - even parity */
+#define	SC2CTR_PB_ODD		0x0070	/* - odd parity */
+#define	SC2CTR_CLN		0x0080	/* character length */
+#define	SC2CTR_CLN_7BIT		0x0000	/* - 7 bit chars */
+#define	SC2CTR_CLN_8BIT		0x0080	/* - 8 bit chars */
+#define	SC2CTR_TWE		0x0100	/* transmit wait enable (enable XCTS control) */
+#define	SC2CTR_OD		0x0200	/* bit order select */
+#define	SC2CTR_OD_LSBFIRST	0x0000	/* - LSB first */
+#define	SC2CTR_OD_MSBFIRST	0x0200	/* - MSB first */
+#define	SC2CTR_TWS		0x1000	/* transmit wait select */
+#define	SC2CTR_TWS_XCTS_HIGH	0x0000	/* - interrupt TX when XCTS high */
+#define	SC2CTR_TWS_XCTS_LOW	0x1000	/* - interrupt TX when XCTS low */
+#define	SC2CTR_BKE		0x2000	/* break transmit enable */
+#define	SC2CTR_RXE		0x4000	/* receive enable */
+#define	SC2CTR_TXE		0x8000	/* transmit enable */
+
+#define	SC2ICR			__SYSREG(0xd4002024, u8)	/* interrupt control reg */
+#define SC2ICR_TD		0x20	/* transmit DMA trigger cause */
+#define SC2ICR_TI		0x10	/* transmit interrupt cause */
+#define SC2ICR_RES		0x04	/* receive error select */
+#define SC2ICR_RI		0x01	/* receive interrupt cause */
+
+#define	SC2TXB			__SYSREG(0xd4002018, u8)	/* transmit buffer reg */
+#define	SC2RXB			__SYSREG(0xd4002019, u8)	/* receive buffer reg */
+#define	SC2STR			__SYSREG(0xd400201c, u8)	/* status reg */
+#define SC2STR_OEF		0x0001	/* overrun error found */
+#define SC2STR_PEF		0x0002	/* parity error found */
+#define SC2STR_FEF		0x0004	/* framing error found */
+#define SC2STR_CTS		0x0008	/* XCTS input pin status (0 means high) */
+#define SC2STR_RBF		0x0010	/* receive buffer status */
+#define SC2STR_TBF		0x0020	/* transmit buffer status */
+#define SC2STR_RXF		0x0040	/* receive status */
+#define SC2STR_TXF		0x0080	/* transmit status */
+
+#define	SC2TIM			__SYSREG(0xd400202d, u8)	/* status reg */
+
+#define SC2RXIRQ		24	/* serial 2 Receive IRQ */
+#define SC2TXIRQ		25	/* serial 2 Transmit IRQ */
+
+#define	SC2RXICR		GxICR(SC2RXIRQ)	/* serial 2 receive intr ctrl reg */
+#define	SC2TXICR		GxICR(SC2TXIRQ)	/* serial 2 transmit intr ctrl reg */
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SERIAL_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/setup.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* MN10300 Setup declarations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+extern void __init unit_setup(void);
+extern void __init unit_init_IRQ(void);
+
+#endif /* _ASM_SETUP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/shmbuf.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/shmbuf.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/shmbuf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/shmbuf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for MN10300 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/shmparam.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/shmparam.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/shmparam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/shmparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sigcontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,52 @@
+/* MN10300 Userspace signal context
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+struct fpucontext {
+	/* Regular FPU environment */
+	unsigned long	fs[32];		/* fpu registers */
+	unsigned long	fpcr;		/* fpu control register */
+};
+
+struct sigcontext {
+	unsigned long	d0;
+	unsigned long	d1;
+	unsigned long	d2;
+	unsigned long	d3;
+	unsigned long	a0;
+	unsigned long	a1;
+	unsigned long	a2;
+	unsigned long	a3;
+	unsigned long	e0;
+	unsigned long	e1;
+	unsigned long	e2;
+	unsigned long	e3;
+	unsigned long	e4;
+	unsigned long	e5;
+	unsigned long	e6;
+	unsigned long	e7;
+	unsigned long	lar;
+	unsigned long	lir;
+	unsigned long	mdr;
+	unsigned long	mcvf;
+	unsigned long	mcrl;
+	unsigned long	mcrh;
+	unsigned long	mdrq;
+	unsigned long	sp;
+	unsigned long	epsw;
+	unsigned long	pc;
+	struct fpucontext *fpucontext;
+	unsigned long	oldmask;
+};
+
+
+#endif /* _ASM_SIGCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/siginfo.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/siginfo.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/siginfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/siginfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/siginfo.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/signal.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/signal.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/signal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/signal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,171 @@
+/* MN10300 Signal definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long	sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001U
+#define SA_NOCLDWAIT	0x00000002U
+#define SA_SIGINFO	0x00000004U
+#define SA_ONSTACK	0x08000000U
+#define SA_RESTART	0x10000000U
+#define SA_NODEFER	0x40000000U
+#define SA_RESETHAND	0x80000000U
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	__sigrestore_t sa_restorer;
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void __user	*ss_sp;
+	int		ss_flags;
+	size_t		ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+
+struct pt_regs;
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SIGNAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/* MN10300 SMP support
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SMP_H
+#define _ASM_SMP_H
+
+#ifdef CONFIG_SMP
+#error SMP not yet supported for MN10300
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/socket.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,60 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockopt(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_SNDBUFFORCE	32
+#define SO_RCVBUFFORCE	33
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+
+#define SO_PEERSEC		31
+#define SO_PASSSEC		34
+#define SO_TIMESTAMPNS		35
+#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
+
+#define SO_MARK			36
+
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
+#endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sockios.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sockios.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/sockios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/sockios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef _ASM_SOCKIOS_H
+#define _ASM_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 */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
+
+#endif /* _ASM_SOCKIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/spinlock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/* MN10300 spinlock support
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#error SMP spinlocks not implemented for MN10300
+
+#endif /* _ASM_SPINLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/statfs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/statfs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/statfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/statfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/stat.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/stat.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/stat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/stat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,78 @@
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct stat {
+	unsigned long  st_dev;
+	unsigned long  st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned long  st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  st_atime_nsec;
+	unsigned long  st_mtime;
+	unsigned long  st_mtime_nsec;
+	unsigned long  st_ctime;
+	unsigned long  st_ctime_nsec;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long	st_dev;
+	unsigned char	__pad0[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long	st_size;
+	unsigned long	st_blksize;
+
+	unsigned long	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long	__pad4;		/* future possible st_blocks high bits */
+
+	unsigned long	st_atime;
+	unsigned long	st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned int	st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long	st_ctime_nsec;
+
+	unsigned long long	st_ino;
+};
+
+#define STAT_HAVE_NSEC 1
+
+#endif /* _ASM_STAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/string.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/string.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/string.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/string.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,32 @@
+/* MN10300 Optimised string functions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Modified by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_STRING_H
+#define _ASM_STRING_H
+
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+
+extern void *memset(void *dest, int ch, size_t count);
+extern void *memcpy(void *dest, const void *src, size_t count);
+extern void *memmove(void *dest, const void *src, size_t count);
+
+
+extern void __struct_cpy_bug(void);
+#define struct_cpy(x, y)			\
+({                                              \
+	if (sizeof(*(x)) != sizeof(*(y)))       \
+		__struct_cpy_bug;               \
+	memcpy(x, y, sizeof(*(x)));             \
+})
+
+#endif /* _ASM_STRING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/swab.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/* MN10300 Byte-order primitive construction
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+#include <linux/types.h>
+
+#ifdef __GNUC__
+
+static inline __attribute__((const))
+__u32 __arch_swab32(__u32 x)
+{
+	__u32 ret;
+	asm("swap %1,%0" : "=r" (ret) : "r" (x));
+	return ret;
+}
+#define __arch_swab32 __arch_swab32
+
+static inline __attribute__((const))
+__u16 __arch_swab16(__u16 x)
+{
+	__u16 ret;
+	asm("swaph %1,%0" : "=r" (ret) : "r" (x));
+	return ret;
+}
+#define __arch_swab32 __arch_swab32
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __GNUC__ */
+
+#endif /* _ASM_SWAB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/system.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/system.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,237 @@
+/* MN10300 System definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+
+struct task_struct;
+struct thread_struct;
+
+extern asmlinkage
+struct task_struct *__switch_to(struct thread_struct *prev,
+				struct thread_struct *next,
+				struct task_struct *prev_task);
+
+/* context switching is now performed out-of-line in switch_to.S */
+#define switch_to(prev, next, last)					\
+do {									\
+	current->thread.wchan = (u_long) __builtin_return_address(0);	\
+	(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev));	\
+	mb();								\
+	current->thread.wchan = 0;					\
+} while (0)
+
+#define arch_align_stack(x) (x)
+
+#define nop() asm volatile ("nop")
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ *
+ * For now, "wmb()" doesn't actually do anything, as all
+ * Intel CPU's follow what Intel calls a *Processor Order*,
+ * in which all writes are seen in the program order even
+ * outside the CPU.
+ *
+ * I expect future Intel CPU's to have a weaker ordering,
+ * but I'd also expect them to finally get their act together
+ * and add some real memory barriers if so.
+ *
+ * Some non intel clones support out of order store. wmb() ceases to be a
+ * nop for these.
+ */
+
+#define mb()	asm volatile ("": : :"memory")
+#define rmb()	mb()
+#define wmb()	asm volatile ("": : :"memory")
+
+#ifdef CONFIG_SMP
+#define smp_mb()	mb()
+#define smp_rmb()	rmb()
+#define smp_wmb()	wmb()
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define set_mb(var, value)  do { var = value;  mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#define read_barrier_depends()		do {} while (0)
+#define smp_read_barrier_depends()	do {} while (0)
+
+/*****************************************************************************/
+/*
+ * interrupt control
+ * - "disabled": run in IM1/2
+ *   - level 0 - GDB stub
+ *   - level 1 - virtual serial DMA (if present)
+ *   - level 5 - normal interrupt priority
+ *   - level 6 - timer interrupt
+ * - "enabled":  run in IM7
+ */
+#ifdef CONFIG_MN10300_TTYSM
+#define MN10300_CLI_LEVEL	EPSW_IM_2
+#else
+#define MN10300_CLI_LEVEL	EPSW_IM_1
+#endif
+
+#define local_save_flags(x)			\
+do {						\
+	typecheck(unsigned long, x);		\
+	asm volatile(				\
+		"	mov epsw,%0	\n"	\
+		: "=d"(x)			\
+		);				\
+} while (0)
+
+#define local_irq_disable()						\
+do {									\
+	asm volatile(							\
+		"	and %0,epsw	\n"				\
+		"	or %1,epsw	\n"				\
+		"	nop		\n"				\
+		"	nop		\n"				\
+		"	nop		\n"				\
+		:							\
+		: "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL)	\
+		);							\
+} while (0)
+
+#define local_irq_save(x)			\
+do {						\
+	local_save_flags(x);			\
+	local_irq_disable();			\
+} while (0)
+
+/*
+ * we make sure local_irq_enable() doesn't cause priority inversion
+ */
+#ifndef __ASSEMBLY__
+
+extern unsigned long __mn10300_irq_enabled_epsw;
+
+#endif
+
+#define local_irq_enable()						\
+do {									\
+	unsigned long tmp;						\
+									\
+	asm volatile(							\
+		"	mov	epsw,%0		\n"			\
+		"	and	%1,%0		\n"			\
+		"	or	%2,%0		\n"			\
+		"	mov	%0,epsw		\n"			\
+		: "=&d"(tmp)						\
+		: "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw)	\
+		);							\
+} while (0)
+
+#define local_irq_restore(x)			\
+do {						\
+	typecheck(unsigned long, x);		\
+	asm volatile(				\
+		"	mov %0,epsw	\n"	\
+		"	nop		\n"	\
+		"	nop		\n"	\
+		"	nop		\n"	\
+		:				\
+		: "d"(x)			\
+		: "memory", "cc"		\
+		);				\
+} while (0)
+
+#define irqs_disabled()				\
+({						\
+	unsigned long flags;			\
+	local_save_flags(flags);		\
+	(flags & EPSW_IM) <= MN10300_CLI_LEVEL;	\
+})
+
+/* hook to save power by halting the CPU
+ * - called from the idle loop
+ * - must reenable interrupts (which takes three instruction cycles to complete)
+ */
+#define safe_halt()							\
+do {									\
+	asm volatile("	or	%0,epsw	\n"				\
+		     "	nop		\n"				\
+		     "	nop		\n"				\
+		     "	bset	%2,(%1)	\n"				\
+		     :							\
+		     : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)\
+		     : "cc"						\
+		     );							\
+} while (0)
+
+#define STI	or EPSW_IE|EPSW_IM,epsw
+#define CLI	and ~EPSW_IM,epsw; or EPSW_IE|MN10300_CLI_LEVEL,epsw; nop; nop; nop
+
+/*****************************************************************************/
+/*
+ * MN10300 doesn't actually have an exchange instruction
+ */
+#ifndef __ASSEMBLY__
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+static inline
+unsigned long __xchg(volatile unsigned long *m, unsigned long val)
+{
+	unsigned long retval;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = *m;
+	*m = val;
+	local_irq_restore(flags);
+	return retval;
+}
+
+#define xchg(ptr, v)						\
+	((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr),	\
+				     (unsigned long)(v)))
+
+static inline unsigned long __cmpxchg(volatile unsigned long *m,
+				      unsigned long old, unsigned long new)
+{
+	unsigned long retval;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = *m;
+	if (retval == old)
+		*m = new;
+	local_irq_restore(flags);
+	return retval;
+}
+
+#define cmpxchg(ptr, o, n)					\
+	((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
+					(unsigned long)(o),	\
+					(unsigned long)(n)))
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_SYSTEM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/termbits.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/termbits.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/termbits.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/termbits.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,200 @@
+#ifndef _ASM_TERMBITS_H
+#define _ASM_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 (not used) */
+#define CTVB	  004000000000		/* VisioBraille Terminal flow control */
+#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
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _ASM_TERMBITS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/termios.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/termios.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/termios.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/termios.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,92 @@
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#ifdef __KERNEL__
+/*	intr=^C		quit=^|		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+#define TIOCM_MODEM_BITS       TIOCM_OUT2      /* IRDA support */
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp, &(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) \
+	copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) \
+	copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) \
+	copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) \
+	copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* _ASM_TERMIOS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/thread_info.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,170 @@
+/* MN10300 Low-level thread information
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#endif
+
+#define PREEMPT_ACTIVE		0x10000000
+
+#ifdef CONFIG_4KSTACKS
+#define THREAD_SIZE		(4096)
+#else
+#define THREAD_SIZE		(8192)
+#endif
+
+#define STACK_WARN		(THREAD_SIZE / 8)
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	__u32			cpu;		/* current CPU */
+	__s32			preempt_count;	/* 0 => preemptable, <0 => BUG */
+
+	mm_segment_t		addr_limit;	/* thread address space:
+						   0-0xBFFFFFFF for user-thead
+						   0-0xFFFFFFFF for kernel-thread
+						*/
+	struct restart_block    restart_block;
+
+	__u8			supervisor_stack[0];
+};
+
+#else /* !__ASSEMBLY__ */
+
+#ifndef __ASM_OFFSETS_H__
+#include <asm/asm-offsets.h>
+#endif
+
+#endif
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+#define init_uregs							\
+	((struct pt_regs *)						\
+	 ((unsigned long) init_stack + THREAD_SIZE - sizeof(struct pt_regs)))
+
+extern struct thread_info *__current_ti;
+
+/* how to get the thread information struct from C */
+static inline __attribute__((const))
+struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+	asm("mov sp,%0\n"
+	    "and %1,%0\n"
+	    : "=d" (ti)
+	    : "i" (~(THREAD_SIZE - 1))
+	    : "cc");
+	return ti;
+}
+
+/* how to get the current stack pointer from C */
+static inline unsigned long current_stack_pointer(void)
+{
+	unsigned long sp;
+	asm("mov sp,%0; ":"=r" (sp));
+	return sp;
+}
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+/* thread information allocation */
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
+#else
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+
+#define free_thread_info(ti)	kfree((ti))
+#define get_thread_info(ti)	get_task_struct((ti)->task)
+#define put_thread_info(ti)	put_task_struct((ti)->task)
+
+#else /* !__ASSEMBLY__ */
+
+#ifndef __VMLINUX_LDS__
+/* how to get the thread information struct from ASM */
+.macro GET_THREAD_INFO reg
+	mov	sp,\reg
+	and	-THREAD_SIZE,\reg
+.endm
+#endif
+#endif
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to
+ *   access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
+#define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
+#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		17	/* OOM killer killed process */
+#define TIF_FREEZE		18	/* freezing for suspend */
+
+#define _TIF_SYSCALL_TRACE	+(1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	+(1 << TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		+(1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	+(1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		+(1 << TIF_SINGLESTEP)
+#define _TIF_RESTORE_SIGMASK	+(1 << TIF_RESTORE_SIGMASK)
+#define _TIF_POLLING_NRFLAG	+(1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE		+(1 << TIF_FREEZE)
+
+#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+#define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/timer-regs.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/timer-regs.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/timer-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/timer-regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,293 @@
+/* AM33v2 on-board timer module registers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+#include <asm/cpu-regs.h>
+#include <asm/intctl-regs.h>
+
+#ifdef __KERNEL__
+
+/* timer prescalar control */
+#define	TMPSCNT			__SYSREG(0xd4003071, u8) /* timer prescaler control */
+#define	TMPSCNT_ENABLE		0x80	/* timer prescaler enable */
+#define	TMPSCNT_DISABLE		0x00	/* timer prescaler disable */
+
+/* 8 bit timers */
+#define	TM0MD			__SYSREG(0xd4003000, u8) /* timer 0 mode register */
+#define	TM0MD_SRC		0x07	/* timer source */
+#define	TM0MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM0MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM0MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM0MD_SRC_TM2IO		0x03	/* - TM2IO pin input */
+#define	TM0MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM0MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM0MD_SRC_TM0IO		0x07	/* - TM0IO pin input */
+#define	TM0MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM0MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM1MD			__SYSREG(0xd4003001, u8) /* timer 1 mode register */
+#define	TM1MD_SRC		0x07	/* timer source */
+#define	TM1MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM1MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM1MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM1MD_SRC_TM0CASCADE	0x03	/* - cascade with timer 0 */
+#define	TM1MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM1MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM1MD_SRC_TM1IO		0x07	/* - TM1IO pin input */
+#define	TM1MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM1MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM2MD			__SYSREG(0xd4003002, u8) /* timer 2 mode register */
+#define	TM2MD_SRC		0x07	/* timer source */
+#define	TM2MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM2MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM2MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM2MD_SRC_TM1CASCADE	0x03	/* - cascade with timer 1 */
+#define	TM2MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM2MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM2MD_SRC_TM2IO		0x07	/* - TM2IO pin input */
+#define	TM2MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM2MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM3MD			__SYSREG(0xd4003003, u8) /* timer 3 mode register */
+#define	TM3MD_SRC		0x07	/* timer source */
+#define	TM3MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM3MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM3MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM3MD_SRC_TM1CASCADE	0x03	/* - cascade with timer 2 */
+#define	TM3MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM3MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM3MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM3MD_SRC_TM3IO		0x07	/* - TM3IO pin input */
+#define	TM3MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM3MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM01MD			__SYSREG(0xd4003000, u16)  /* timer 0:1 mode register */
+
+#define	TM0BR			__SYSREG(0xd4003010, u8)   /* timer 0 base register */
+#define	TM1BR			__SYSREG(0xd4003011, u8)   /* timer 1 base register */
+#define	TM2BR			__SYSREG(0xd4003012, u8)   /* timer 2 base register */
+#define	TM3BR			__SYSREG(0xd4003013, u8)   /* timer 3 base register */
+#define	TM01BR			__SYSREG(0xd4003010, u16)  /* timer 0:1 base register */
+
+#define	TM0BC			__SYSREGC(0xd4003020, u8)  /* timer 0 binary counter */
+#define	TM1BC			__SYSREGC(0xd4003021, u8)  /* timer 1 binary counter */
+#define	TM2BC			__SYSREGC(0xd4003022, u8)  /* timer 2 binary counter */
+#define	TM3BC			__SYSREGC(0xd4003023, u8)  /* timer 3 binary counter */
+#define	TM01BC			__SYSREGC(0xd4003020, u16) /* timer 0:1 binary counter */
+
+#define TM0IRQ			2	/* timer 0 IRQ */
+#define TM1IRQ			3	/* timer 1 IRQ */
+#define TM2IRQ			4	/* timer 2 IRQ */
+#define TM3IRQ			5	/* timer 3 IRQ */
+
+#define	TM0ICR			GxICR(TM0IRQ)	/* timer 0 uflow intr ctrl reg */
+#define	TM1ICR			GxICR(TM1IRQ)	/* timer 1 uflow intr ctrl reg */
+#define	TM2ICR			GxICR(TM2IRQ)	/* timer 2 uflow intr ctrl reg */
+#define	TM3ICR			GxICR(TM3IRQ)	/* timer 3 uflow intr ctrl reg */
+
+/* 16-bit timers 4,5 & 7-11 */
+#define	TM4MD			__SYSREG(0xd4003080, u8)   /* timer 4 mode register */
+#define	TM4MD_SRC		0x07	/* timer source */
+#define	TM4MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM4MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM4MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM4MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM4MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM4MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM4MD_SRC_TM4IO		0x07	/* - TM4IO pin input */
+#define	TM4MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM4MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM5MD			__SYSREG(0xd4003082, u8)   /* timer 5 mode register */
+#define	TM5MD_SRC		0x07	/* timer source */
+#define	TM5MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM5MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM5MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM5MD_SRC_TM4CASCADE	0x03	/* - cascade with timer 4 */
+#define	TM5MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM5MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM5MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM5MD_SRC_TM5IO		0x07	/* - TM5IO pin input */
+#define	TM5MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM5MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM7MD			__SYSREG(0xd4003086, u8)   /* timer 7 mode register */
+#define	TM7MD_SRC		0x07	/* timer source */
+#define	TM7MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM7MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM7MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM7MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM7MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM7MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM7MD_SRC_TM7IO		0x07	/* - TM7IO pin input */
+#define	TM7MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM7MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM8MD			__SYSREG(0xd4003088, u8)   /* timer 8 mode register */
+#define	TM8MD_SRC		0x07	/* timer source */
+#define	TM8MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM8MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM8MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM8MD_SRC_TM7CASCADE	0x03	/* - cascade with timer 7 */
+#define	TM8MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM8MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM8MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM8MD_SRC_TM8IO		0x07	/* - TM8IO pin input */
+#define	TM8MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM8MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM9MD			__SYSREG(0xd400308a, u8)   /* timer 9 mode register */
+#define	TM9MD_SRC		0x07	/* timer source */
+#define	TM9MD_SRC_IOCLK		0x00	/* - IOCLK */
+#define	TM9MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM9MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM9MD_SRC_TM8CASCADE	0x03	/* - cascade with timer 8 */
+#define	TM9MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM9MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM9MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM9MD_SRC_TM9IO		0x07	/* - TM9IO pin input */
+#define	TM9MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM9MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM10MD			__SYSREG(0xd400308c, u8)   /* timer 10 mode register */
+#define	TM10MD_SRC		0x07	/* timer source */
+#define	TM10MD_SRC_IOCLK	0x00	/* - IOCLK */
+#define	TM10MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM10MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM10MD_SRC_TM9CASCADE	0x03	/* - cascade with timer 9 */
+#define	TM10MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM10MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM10MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM10MD_SRC_TM10IO	0x07	/* - TM10IO pin input */
+#define	TM10MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM10MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM11MD			__SYSREG(0xd400308e, u8)   /* timer 11 mode register */
+#define	TM11MD_SRC		0x07	/* timer source */
+#define	TM11MD_SRC_IOCLK	0x00	/* - IOCLK */
+#define	TM11MD_SRC_IOCLK_8	0x01	/* - 1/8 IOCLK */
+#define	TM11MD_SRC_IOCLK_32	0x02	/* - 1/32 IOCLK */
+#define	TM11MD_SRC_TM7CASCADE	0x03	/* - cascade with timer 7 */
+#define	TM11MD_SRC_TM0UFLOW	0x04	/* - timer 0 underflow */
+#define	TM11MD_SRC_TM1UFLOW	0x05	/* - timer 1 underflow */
+#define	TM11MD_SRC_TM2UFLOW	0x06	/* - timer 2 underflow */
+#define	TM11MD_SRC_TM11IO	0x07	/* - TM11IO pin input */
+#define	TM11MD_INIT_COUNTER	0x40	/* initialize TMnBC = TMnBR */
+#define	TM11MD_COUNT_ENABLE	0x80	/* timer count enable */
+
+#define	TM4BR			__SYSREG(0xd4003090, u16)  /* timer 4 base register */
+#define	TM5BR			__SYSREG(0xd4003092, u16)  /* timer 5 base register */
+#define	TM7BR			__SYSREG(0xd4003096, u16)  /* timer 7 base register */
+#define	TM8BR			__SYSREG(0xd4003098, u16)  /* timer 8 base register */
+#define	TM9BR			__SYSREG(0xd400309a, u16)  /* timer 9 base register */
+#define	TM10BR			__SYSREG(0xd400309c, u16)  /* timer 10 base register */
+#define	TM11BR			__SYSREG(0xd400309e, u16)  /* timer 11 base register */
+#define	TM45BR			__SYSREG(0xd4003090, u32)  /* timer 4:5 base register */
+
+#define	TM4BC			__SYSREG(0xd40030a0, u16)  /* timer 4 binary counter */
+#define	TM5BC			__SYSREG(0xd40030a2, u16)  /* timer 5 binary counter */
+#define	TM45BC			__SYSREG(0xd40030a0, u32)  /* timer 4:5 binary counter */
+
+#define	TM7BC			__SYSREG(0xd40030a6, u16)  /* timer 7 binary counter */
+#define	TM8BC			__SYSREG(0xd40030a8, u16)  /* timer 8 binary counter */
+#define	TM9BC			__SYSREG(0xd40030aa, u16)  /* timer 9 binary counter */
+#define	TM10BC			__SYSREG(0xd40030ac, u16)  /* timer 10 binary counter */
+#define	TM11BC			__SYSREG(0xd40030ae, u16)  /* timer 11 binary counter */
+
+#define TM4IRQ			6	/* timer 4 IRQ */
+#define TM5IRQ			7	/* timer 5 IRQ */
+#define TM7IRQ			11	/* timer 7 IRQ */
+#define TM8IRQ			12	/* timer 8 IRQ */
+#define TM9IRQ			13	/* timer 9 IRQ */
+#define TM10IRQ			14	/* timer 10 IRQ */
+#define TM11IRQ			15	/* timer 11 IRQ */
+
+#define	TM4ICR			GxICR(TM4IRQ)	/* timer 4 uflow intr ctrl reg */
+#define	TM5ICR			GxICR(TM5IRQ)	/* timer 5 uflow intr ctrl reg */
+#define	TM7ICR			GxICR(TM7IRQ)	/* timer 7 uflow intr ctrl reg */
+#define	TM8ICR			GxICR(TM8IRQ)	/* timer 8 uflow intr ctrl reg */
+#define	TM9ICR			GxICR(TM9IRQ)	/* timer 9 uflow intr ctrl reg */
+#define	TM10ICR			GxICR(TM10IRQ)	/* timer 10 uflow intr ctrl reg */
+#define	TM11ICR			GxICR(TM11IRQ)	/* timer 11 uflow intr ctrl reg */
+
+/* 16-bit timer 6 */
+#define	TM6MD			__SYSREG(0xd4003084, u16)  /* timer6 mode register */
+#define	TM6MD_SRC		0x0007	/* timer source */
+#define	TM6MD_SRC_IOCLK		0x0000	/* - IOCLK */
+#define	TM6MD_SRC_IOCLK_8	0x0001	/* - 1/8 IOCLK */
+#define	TM6MD_SRC_IOCLK_32	0x0002	/* - 1/32 IOCLK */
+#define	TM6MD_SRC_TM0UFLOW	0x0004	/* - timer 0 underflow */
+#define	TM6MD_SRC_TM1UFLOW	0x0005	/* - timer 1 underflow */
+#define	TM6MD_SRC_TM6IOB_BOTH	0x0006	/* - TM6IOB pin input (both edges) */
+#define	TM6MD_SRC_TM6IOB_SINGLE	0x0007	/* - TM6IOB pin input (single edge) */
+#define	TM6MD_CLR_ENABLE	0x0010	/* clear count enable */
+#define	TM6MD_ONESHOT_ENABLE	0x0040	/* oneshot count */
+#define	TM6MD_TRIG_ENABLE	0x0080	/* TM6IOB pin trigger enable */
+#define TM6MD_PWM		0x3800	/* PWM output mode */
+#define TM6MD_PWM_DIS		0x0000	/* - disabled */
+#define	TM6MD_PWM_10BIT		0x1000	/* - 10 bits mode */
+#define	TM6MD_PWM_11BIT		0x1800	/* - 11 bits mode */
+#define	TM6MD_PWM_12BIT		0x3000	/* - 12 bits mode */
+#define	TM6MD_PWM_14BIT		0x3800	/* - 14 bits mode */
+#define	TM6MD_INIT_COUNTER	0x4000	/* initialize TMnBC to zero */
+#define	TM6MD_COUNT_ENABLE	0x8000	/* timer count enable */
+
+#define	TM6MDA			__SYSREG(0xd40030b4, u8)   /* timer6 cmp/cap A mode reg */
+#define TM6MDA_OUT		0x07	/* output select */
+#define	TM6MDA_OUT_SETA_RESETB	0x00	/* - set at match A, reset at match B */
+#define	TM6MDA_OUT_SETA_RESETOV	0x01	/* - set at match A, reset at overflow */
+#define	TM6MDA_OUT_SETA		0x02	/* - set at match A */
+#define	TM6MDA_OUT_RESETA	0x03	/* - reset at match A */
+#define	TM6MDA_OUT_TOGGLE	0x04	/* - toggle on match A */
+#define TM6MDA_MODE		0xc0	/* compare A register mode */
+#define	TM6MDA_MODE_CMP_SINGLE	0x00	/* - compare, single buffer mode */
+#define	TM6MDA_MODE_CMP_DOUBLE	0x40	/* - compare, double buffer mode */
+#define	TM6MDA_MODE_CAP_S_EDGE	0x80	/* - capture, single edge mode */
+#define	TM6MDA_MODE_CAP_D_EDGE	0xc0	/* - capture, double edge mode */
+#define TM6MDA_EDGE		0x20	/* compare A edge select */
+#define	TM6MDA_EDGE_FALLING	0x00	/* capture on falling edge */
+#define	TM6MDA_EDGE_RISING	0x20	/* capture on rising edge */
+#define	TM6MDA_CAPTURE_ENABLE	0x10	/* capture enable */
+
+#define	TM6MDB			__SYSREG(0xd40030b5, u8)   /* timer6 cmp/cap B mode reg */
+#define TM6MDB_OUT		0x07	/* output select */
+#define	TM6MDB_OUT_SETB_RESETA	0x00	/* - set at match B, reset at match A */
+#define	TM6MDB_OUT_SETB_RESETOV	0x01	/* - set at match B */
+#define	TM6MDB_OUT_RESETB	0x03	/* - reset at match B */
+#define	TM6MDB_OUT_TOGGLE	0x04	/* - toggle on match B */
+#define TM6MDB_MODE		0xc0	/* compare B register mode */
+#define	TM6MDB_MODE_CMP_SINGLE	0x00	/* - compare, single buffer mode */
+#define	TM6MDB_MODE_CMP_DOUBLE	0x40	/* - compare, double buffer mode */
+#define	TM6MDB_MODE_CAP_S_EDGE	0x80	/* - capture, single edge mode */
+#define	TM6MDB_MODE_CAP_D_EDGE	0xc0	/* - capture, double edge mode */
+#define TM6MDB_EDGE		0x20	/* compare B edge select */
+#define	TM6MDB_EDGE_FALLING	0x00	/* capture on falling edge */
+#define	TM6MDB_EDGE_RISING	0x20	/* capture on rising edge */
+#define	TM6MDB_CAPTURE_ENABLE	0x10	/* capture enable */
+
+#define	TM6CA			__SYSREG(0xd40030c4, u16)   /* timer6 cmp/capture reg A */
+#define	TM6CB			__SYSREG(0xd40030d4, u16)   /* timer6 cmp/capture reg B */
+#define	TM6BC			__SYSREG(0xd40030a4, u16)   /* timer6 binary counter */
+
+#define TM6IRQ			6	/* timer 6 IRQ */
+#define TM6AIRQ			9	/* timer 6A IRQ */
+#define TM6BIRQ			10	/* timer 6B IRQ */
+
+#define	TM6ICR			GxICR(TM6IRQ)	/* timer 6 uflow intr ctrl reg */
+#define	TM6AICR			GxICR(TM6AIRQ)	/* timer 6A intr control reg */
+#define	TM6BICR			GxICR(TM6BIRQ)	/* timer 6B intr control reg */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TIMER_REGS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+/* MN10300 Architecture time management specifications
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#include <asm/hardirq.h>
+#include <unit/timex.h>
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+#define CLOCK_TICK_RATE 1193180 /* Underlying HZ - this should probably be set
+				 * to something appropriate, but what? */
+
+extern cycles_t cacheflush_time;
+
+#ifdef __KERNEL__
+
+static inline cycles_t get_cycles(void)
+{
+	return read_timestamp_counter();
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/tlbflush.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,80 @@
+/* MN10300 TLB flushing functions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#include <asm/processor.h>
+
+#define __flush_tlb()						\
+do {								\
+	int w;							\
+	__asm__ __volatile__					\
+		("	mov %1,%0		\n"		\
+		 "	or %2,%0		\n"		\
+		 "	mov %0,%1		\n"		\
+		 : "=d"(w)					\
+		 : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV)	\
+		 : "memory"					\
+		 );						\
+} while (0)
+
+#define __flush_tlb_all() __flush_tlb()
+#define __flush_tlb_one(addr) __flush_tlb()
+
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ */
+#define flush_tlb_all()				\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_all();			\
+	preempt_enable();			\
+} while (0)
+
+#define flush_tlb_mm(mm)			\
+do {						\
+	preempt_disable();			\
+	__flush_tlb_all();			\
+	preempt_enable();			\
+} while (0)
+
+#define flush_tlb_range(vma, start, end)			\
+do {								\
+	unsigned long __s __attribute__((unused)) = (start);	\
+	unsigned long __e __attribute__((unused)) = (end);	\
+	preempt_disable();					\
+	__flush_tlb_all();					\
+	preempt_enable();					\
+} while (0)
+
+
+#define __flush_tlb_global()			flush_tlb_all()
+#define flush_tlb()				flush_tlb_all()
+#define flush_tlb_kernel_range(start, end)			\
+do {								\
+	unsigned long __s __attribute__((unused)) = (start);	\
+	unsigned long __e __attribute__((unused)) = (end);	\
+	flush_tlb_all();					\
+} while (0)
+
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
+
+#define flush_tlb_pgtables(mm, start, end)	do {} while (0)
+
+#endif /* _ASM_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/tlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+/* MN10300 TLB definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#include <asm/tlbflush.h>
+
+extern void check_pgt_cache(void);
+
+/*
+ * we don't need any special per-pte or per-vma handling...
+ */
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up
+ */
+#define tlb_flush(tlb)	flush_tlb_mm((tlb)->mm)
+
+/* for now, just use the generic stuff */
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TLB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/topology.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/topology.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/types.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/types.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/* MN10300 Basic type definitions
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+/* Dma addresses are 32-bits wide.  */
+typedef u32 dma_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/uaccess.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,490 @@
+/* MN10300 userspace access functions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/errno.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not.  If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+
+#define KERNEL_XDS	MAKE_MM_SEG(0xBFFFFFFF)
+#define KERNEL_DS	MAKE_MM_SEG(0x9FFFFFFF)
+#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(current_thread_info()->addr_limit)
+#define set_fs(x)	(current_thread_info()->addr_limit = (x))
+#define __kernel_ds_p() (current_thread_info()->addr_limit.seg == 0x9FFFFFFF)
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+#define __addr_ok(addr) \
+	((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
+
+/*
+ * check that a range of addresses falls within the current address limit
+ */
+static inline int ___range_ok(unsigned long addr, unsigned int size)
+{
+	int flag = 1, tmp;
+
+	asm("	add	%3,%1	\n"	/* set C-flag if addr + size > 4Gb */
+	    "	bcs	0f	\n"
+	    "	cmp	%4,%1	\n"	/* jump if addr+size>limit (error) */
+	    "	bhi	0f	\n"
+	    "	clr	%0	\n"	/* mark okay */
+	    "0:			\n"
+	    : "=r"(flag), "=&r"(tmp)
+	    : "1"(addr), "ir"(size),
+	      "r"(current_thread_info()->addr_limit.seg), "0"(flag)
+	    : "cc"
+	    );
+
+	return flag;
+}
+
+#define __range_ok(addr, size) ___range_ok((unsigned long)(addr), (u32)(size))
+
+#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
+#define __access_ok(addr, size)     (__range_ok((addr), (size)) == 0)
+
+static inline int verify_area(int type, const void *addr, unsigned long size)
+{
+	return access_ok(type, addr, size) ? 0 : -EFAULT;
+}
+
+
+/*
+ * 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
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern int fixup_exception(struct pt_regs *regs);
+
+#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
+#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * The "xxx_ret" versions return constant specified in third argument, if
+ * something bad happens. These macros can be optimized for the
+ * case of just returning from the function xxx_ret is used.
+ */
+
+#define put_user_ret(x, ptr, ret) \
+	({ if (put_user((x), (ptr)))	return (ret); })
+#define get_user_ret(x, ptr, ret) \
+	({ if (get_user((x), (ptr)))	return (ret); })
+#define __put_user_ret(x, ptr, ret) \
+	({ if (__put_user((x), (ptr)))	return (ret); })
+#define __get_user_ret(x, ptr, ret) \
+	({ if (__get_user((x), (ptr)))	return (ret); })
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct *)(x))
+
+#define __get_user_nocheck(x, ptr, size)	\
+({						\
+	__typeof(*(ptr)) __gu_val;		\
+	unsigned long __gu_addr;		\
+	int __gu_err;				\
+	__gu_addr = (unsigned long) (ptr);	\
+	switch (size) {				\
+	case 1:  __get_user_asm("bu"); break;	\
+	case 2:  __get_user_asm("hu"); break;	\
+	case 4:  __get_user_asm(""  ); break;	\
+	default: __get_user_unknown(); break;	\
+	}					\
+	x = (__typeof__(*(ptr))) __gu_val;	\
+	__gu_err;				\
+})
+
+#define __get_user_check(x, ptr, size)			\
+({							\
+	__typeof__(*(ptr)) __gu_val;			\
+	unsigned long __gu_addr;			\
+	int __gu_err;					\
+	__gu_addr = (unsigned long) (ptr);		\
+	if (likely(__access_ok(__gu_addr,size))) {	\
+		switch (size) {				\
+		case 1:  __get_user_asm("bu"); break;	\
+		case 2:  __get_user_asm("hu"); break;	\
+		case 4:  __get_user_asm(""  ); break;	\
+		default: __get_user_unknown(); break;	\
+		}					\
+	}						\
+	else {						\
+		__gu_err = -EFAULT;			\
+		__gu_val = 0;				\
+	}						\
+	x = (__typeof__(*(ptr))) __gu_val;		\
+	__gu_err;					\
+})
+
+#define __get_user_asm(INSN)					\
+({								\
+	asm volatile(					\
+		"1:\n"						\
+		"	mov"INSN"	%2,%1\n"		\
+		"	mov		0,%0\n"			\
+		"2:\n"						\
+		"	.section	.fixup,\"ax\"\n"	\
+		"3:\n\t"					\
+		"	mov		%3,%0\n"		\
+		"	jmp		2b\n"			\
+		"	.previous\n"				\
+		"	.section	__ex_table,\"a\"\n"	\
+		"	.balign		4\n"			\
+		"	.long		1b, 3b\n"		\
+		"	.previous"				\
+		: "=&r" (__gu_err), "=&r" (__gu_val)		\
+		: "m" (__m(__gu_addr)), "i" (-EFAULT));		\
+})
+
+extern int __get_user_unknown(void);
+
+#define __put_user_nocheck(x, ptr, size)			\
+({								\
+	union {							\
+		__typeof__(*(ptr)) val;				\
+		u32 bits[2];					\
+	} __pu_val;						\
+	unsigned long __pu_addr;				\
+	int __pu_err;						\
+	__pu_val.val = (x);					\
+	__pu_addr = (unsigned long) (ptr);			\
+	switch (size) {						\
+	case 1:  __put_user_asm("bu"); break;			\
+	case 2:  __put_user_asm("hu"); break;			\
+	case 4:  __put_user_asm(""  ); break;			\
+	case 8:  __put_user_asm8();    break;			\
+	default: __pu_err = __put_user_unknown(); break;	\
+	}							\
+	__pu_err;						\
+})
+
+#define __put_user_check(x, ptr, size)					\
+({									\
+	union {								\
+		__typeof__(*(ptr)) val;					\
+		u32 bits[2];						\
+	} __pu_val;							\
+	unsigned long __pu_addr;					\
+	int __pu_err;							\
+	__pu_val.val = (x);						\
+	__pu_addr = (unsigned long) (ptr);				\
+	if (likely(__access_ok(__pu_addr, size))) {			\
+		switch (size) {						\
+		case 1:  __put_user_asm("bu"); break;			\
+		case 2:  __put_user_asm("hu"); break;			\
+		case 4:  __put_user_asm(""  ); break;			\
+		case 8:  __put_user_asm8();    break;			\
+		default: __pu_err = __put_user_unknown(); break;	\
+		}							\
+	}								\
+	else {								\
+		__pu_err = -EFAULT;					\
+	}								\
+	__pu_err;							\
+})
+
+#define __put_user_asm(INSN)					\
+({								\
+	asm volatile(						\
+		"1:\n"						\
+		"	mov"INSN"	%1,%2\n"		\
+		"	mov		0,%0\n"			\
+		"2:\n"						\
+		"	.section	.fixup,\"ax\"\n"	\
+		"3:\n"						\
+		"	mov		%3,%0\n"		\
+		"	jmp		2b\n"			\
+		"	.previous\n"				\
+		"	.section	__ex_table,\"a\"\n"	\
+		"	.balign		4\n"			\
+		"	.long		1b, 3b\n"		\
+		"	.previous"				\
+		: "=&r" (__pu_err)				\
+		: "r" (__pu_val.val), "m" (__m(__pu_addr)),	\
+		  "i" (-EFAULT)					\
+		);						\
+})
+
+#define __put_user_asm8()						\
+({									\
+	asm volatile(							\
+		"1:	mov		%1,%3		\n"		\
+		"2:	mov		%2,%4		\n"		\
+		"	mov		0,%0		\n"		\
+		"3:					\n"		\
+		"	.section	.fixup,\"ax\"	\n"		\
+		"4:					\n"		\
+		"	mov		%5,%0		\n"		\
+		"	jmp		3b		\n"		\
+		"	.previous			\n"		\
+		"	.section	__ex_table,\"a\"\n"		\
+		"	.balign		4		\n"		\
+		"	.long		1b, 4b		\n"		\
+		"	.long		2b, 4b		\n"		\
+		"	.previous			\n"		\
+		: "=&r" (__pu_err)					\
+		: "r" (__pu_val.bits[0]), "r" (__pu_val.bits[1]),	\
+		  "m" (__m(__pu_addr)), "m" (__m(__pu_addr+4)),		\
+		  "i" (-EFAULT)						\
+		);							\
+})
+
+extern int __put_user_unknown(void);
+
+
+/*
+ * Copy To/From Userspace
+ */
+/* Generic arbitrary sized copy.  */
+#define __copy_user(to, from, size)					\
+do {									\
+	if (size) {							\
+		void *__to = to;					\
+		const void *__from = from;				\
+		int w;							\
+		asm volatile(						\
+			"0:     movbu	(%0),%3;\n"			\
+			"1:     movbu	%3,(%1);\n"			\
+			"	inc	%0;\n"				\
+			"	inc	%1;\n"				\
+			"       add	-1,%2;\n"			\
+			"       bne	0b;\n"				\
+			"2:\n"						\
+			"	.section .fixup,\"ax\"\n"		\
+			"3:	jmp	2b\n"				\
+			"	.previous\n"				\
+			"	.section __ex_table,\"a\"\n"		\
+			"       .balign	4\n"				\
+			"       .long	0b,3b\n"			\
+			"       .long	1b,3b\n"			\
+			"	.previous\n"				\
+			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
+			: "0"(__from), "1"(__to), "2"(size)		\
+			: "memory");					\
+	}								\
+} while (0)
+
+#define __copy_user_zeroing(to, from, size)				\
+do {									\
+	if (size) {							\
+		void *__to = to;					\
+		const void *__from = from;				\
+		int w;							\
+		asm volatile(						\
+			"0:     movbu	(%0),%3;\n"			\
+			"1:     movbu	%3,(%1);\n"			\
+			"	inc	%0;\n"				\
+			"	inc	%1;\n"				\
+			"       add	-1,%2;\n"			\
+			"       bne	0b;\n"				\
+			"2:\n"						\
+			"	.section .fixup,\"ax\"\n"		\
+			"3:\n"						\
+			"	mov	%2,%0\n"			\
+			"	clr	%3\n"				\
+			"4:     movbu	%3,(%1);\n"			\
+			"	inc	%1;\n"				\
+			"       add	-1,%2;\n"			\
+			"       bne	4b;\n"				\
+			"	mov	%0,%2\n"			\
+			"	jmp	2b\n"				\
+			"	.previous\n"				\
+			"	.section __ex_table,\"a\"\n"		\
+			"       .balign	4\n"				\
+			"       .long	0b,3b\n"			\
+			"       .long	1b,3b\n"			\
+			"	.previous\n"				\
+			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
+			: "0"(__from), "1"(__to), "2"(size)		\
+			: "memory");					\
+	}								\
+} while (0)
+
+/* We let the __ versions of copy_from/to_user inline, because they're often
+ * used in fast paths and have only a small space overhead.
+ */
+static inline
+unsigned long __generic_copy_from_user_nocheck(void *to, const void *from,
+					       unsigned long n)
+{
+	__copy_user_zeroing(to, from, n);
+	return n;
+}
+
+static inline
+unsigned long __generic_copy_to_user_nocheck(void *to, const void *from,
+					     unsigned long n)
+{
+	__copy_user(to, from, n);
+	return n;
+}
+
+
+#if 0
+#error don't use - these macros don't increment to & from pointers
+/* Optimize just a little bit when we know the size of the move. */
+#define __constant_copy_user(to, from, size)	\
+do {						\
+	asm volatile(				\
+		"       mov %0,a0;\n"		\
+		"0:     movbu (%1),d3;\n"	\
+		"1:     movbu d3,(%2);\n"	\
+		"       add -1,a0;\n"		\
+		"       bne 0b;\n"		\
+		"2:;"				\
+		".section .fixup,\"ax\"\n"	\
+		"3:	jmp 2b\n"		\
+		".previous\n"			\
+		".section __ex_table,\"a\"\n"	\
+		"       .balign 4\n"		\
+		"       .long 0b,3b\n"		\
+		"       .long 1b,3b\n"		\
+		".previous"			\
+		:				\
+		: "d"(size), "d"(to), "d"(from)	\
+		: "d3", "a0");			\
+} while (0)
+
+/* Optimize just a little bit when we know the size of the move. */
+#define __constant_copy_user_zeroing(to, from, size)	\
+do {							\
+	asm volatile(					\
+		"       mov %0,a0;\n"			\
+		"0:     movbu (%1),d3;\n"		\
+		"1:     movbu d3,(%2);\n"		\
+		"       add -1,a0;\n"			\
+		"       bne 0b;\n"			\
+		"2:;"					\
+		".section .fixup,\"ax\"\n"		\
+		"3:	jmp 2b\n"			\
+		".previous\n"				\
+		".section __ex_table,\"a\"\n"		\
+		"       .balign 4\n"			\
+		"       .long 0b,3b\n"			\
+		"       .long 1b,3b\n"			\
+		".previous"				\
+		:					\
+		: "d"(size), "d"(to), "d"(from)		\
+		: "d3", "a0");				\
+} while (0)
+
+static inline
+unsigned long __constant_copy_to_user(void *to, const void *from,
+				      unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		__constant_copy_user(to, from, n);
+	return n;
+}
+
+static inline
+unsigned long __constant_copy_from_user(void *to, const void *from,
+					unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		__constant_copy_user_zeroing(to, from, n);
+	return n;
+}
+
+static inline
+unsigned long __constant_copy_to_user_nocheck(void *to, const void *from,
+					      unsigned long n)
+{
+	__constant_copy_user(to, from, n);
+	return n;
+}
+
+static inline
+unsigned long __constant_copy_from_user_nocheck(void *to, const void *from,
+						unsigned long n)
+{
+	__constant_copy_user_zeroing(to, from, n);
+	return n;
+}
+#endif
+
+extern unsigned long __generic_copy_to_user(void __user *, const void *,
+					    unsigned long);
+extern unsigned long __generic_copy_from_user(void *, const void __user *,
+					      unsigned long);
+
+#define __copy_to_user_inatomic(to, from, n) \
+	__generic_copy_to_user_nocheck((to), (from), (n))
+#define __copy_from_user_inatomic(to, from, n) \
+	__generic_copy_from_user_nocheck((to), (from), (n))
+
+#define __copy_to_user(to, from, n)			\
+({							\
+	might_sleep();					\
+	__copy_to_user_inatomic((to), (from), (n));	\
+})
+
+#define __copy_from_user(to, from, n)			\
+({							\
+	might_sleep();					\
+	__copy_from_user_inatomic((to), (from), (n));	\
+})
+
+
+#define copy_to_user(to, from, n)   __generic_copy_to_user((to), (from), (n))
+#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long __strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *str, long n);
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+extern unsigned long clear_user(void __user *mem, unsigned long len);
+extern unsigned long __clear_user(void __user *mem, unsigned long len);
+
+#endif /* _ASM_UACCESS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ucontext.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ucontext.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/ucontext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/ucontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/* MN10300 User context
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _ASM_UCONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/unaligned.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/unaligned.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/unaligned.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/unaligned.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,20 @@
+/* MN10300 Unaligned memory access handling
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_MN10300_UNALIGNED_H
+#define _ASM_MN10300_UNALIGNED_H
+
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_le
+#define put_unaligned	__put_unaligned_le
+
+#endif /* _ASM_MN10300_UNALIGNED_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/unistd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,392 @@
+/* MN10300 System call number list
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UNISTD_H
+#define _ASM_UNISTD_H
+
+#define __NR_restart_syscall      0
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_umount2		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76	/* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86old		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_getsid		147
+#define __NR_fdatasync		148
+#define __NR__sysctl		149
+#define __NR_mlock		150
+#define __NR_munlock		151
+#define __NR_mlockall		152
+#define __NR_munlockall		153
+#define __NR_sched_setparam		154
+#define __NR_sched_getparam		155
+#define __NR_sched_setscheduler		156
+#define __NR_sched_getscheduler		157
+#define __NR_sched_yield		158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep		162
+#define __NR_mremap		163
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_vm86		166
+#define __NR_query_module	167
+#define __NR_poll		168
+#define __NR_nfsservctl		169
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_prctl              172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64		180
+#define __NR_pwrite64		181
+#define __NR_chown		182
+#define __NR_getcwd		183
+#define __NR_capget		184
+#define __NR_capset		185
+#define __NR_sigaltstack	186
+#define __NR_sendfile		187
+#define __NR_getpmsg		188	/* some people actually want streams */
+#define __NR_putpmsg		189	/* some people actually want streams */
+#define __NR_vfork		190
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_pivot_root		217
+#define __NR_mincore		218
+#define __NR_madvise		219
+#define __NR_madvise1		219	/* delete when C lib stub is removed */
+#define __NR_getdents64		220
+#define __NR_fcntl64		221
+/* 223 is unused */
+#define __NR_gettid		224
+#define __NR_readahead		225
+#define __NR_setxattr		226
+#define __NR_lsetxattr		227
+#define __NR_fsetxattr		228
+#define __NR_getxattr		229
+#define __NR_lgetxattr		230
+#define __NR_fgetxattr		231
+#define __NR_listxattr		232
+#define __NR_llistxattr		233
+#define __NR_flistxattr		234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill		238
+#define __NR_sendfile64		239
+#define __NR_futex		240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_fadvise64		250
+
+#define __NR_exit_group		252
+#define __NR_lookup_dcookie	253
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+#define __NR_remap_file_pages	257
+#define __NR_set_tid_address	258
+#define __NR_timer_create	259
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+#define __NR_statfs64		268
+#define __NR_fstatfs64		269
+#define __NR_tgkill		270
+#define __NR_utimes		271
+#define __NR_fadvise64_64	272
+#define __NR_vserver		273
+#define __NR_mbind		274
+#define __NR_get_mempolicy	275
+#define __NR_set_mempolicy	276
+#define __NR_mq_open 		277
+#define __NR_mq_unlink		(__NR_mq_open+1)
+#define __NR_mq_timedsend	(__NR_mq_open+2)
+#define __NR_mq_timedreceive	(__NR_mq_open+3)
+#define __NR_mq_notify		(__NR_mq_open+4)
+#define __NR_mq_getsetattr	(__NR_mq_open+5)
+#define __NR_kexec_load		283
+#define __NR_waitid		284
+#define __NR_add_key		286
+#define __NR_request_key	287
+#define __NR_keyctl		288
+#define __NR_cacheflush		289
+#define __NR_ioprio_set		290
+#define __NR_ioprio_get		291
+#define __NR_inotify_init	292
+#define __NR_inotify_add_watch	293
+#define __NR_inotify_rm_watch	294
+#define __NR_migrate_pages	295
+#define __NR_openat		296
+#define __NR_mkdirat		297
+#define __NR_mknodat		298
+#define __NR_fchownat		299
+#define __NR_futimesat		300
+#define __NR_fstatat64		301
+#define __NR_unlinkat		302
+#define __NR_renameat		303
+#define __NR_linkat		304
+#define __NR_symlinkat		305
+#define __NR_readlinkat		306
+#define __NR_fchmodat		307
+#define __NR_faccessat		308
+#define __NR_pselect6		309
+#define __NR_ppoll		310
+#define __NR_unshare		311
+#define __NR_set_robust_list	312
+#define __NR_get_robust_list	313
+#define __NR_splice		314
+#define __NR_sync_file_range	315
+#define __NR_tee		316
+#define __NR_vmsplice		317
+#define __NR_move_pages		318
+#define __NR_getcpu		319
+#define __NR_epoll_pwait	320
+#define __NR_utimensat		321
+#define __NR_signalfd		322
+#define __NR_timerfd_create	323
+#define __NR_eventfd		324
+#define __NR_fallocate		325
+#define __NR_timerfd_settime	326
+#define __NR_timerfd_gettime	327
+#define __NR_signalfd4		328
+#define __NR_eventfd2		329
+#define __NR_epoll_create1	330
+#define __NR_dup3		331
+#define __NR_pipe2		332
+#define __NR_inotify_init1	333
+#define __NR_preadv		334
+#define __NR_pwritev		335
+
+#ifdef __KERNEL__
+
+#define NR_syscalls 326
+
+/*
+ * specify the deprecated syscalls we want to support on this arch
+ */
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#ifndef cond_syscall
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_UNISTD_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/user.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/user.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/user.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,53 @@
+/* MN10300 User process data
+ *
+ * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
+ * Copyright (C) 2007 Red Hat, 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 Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <linux/ptrace.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * When the kernel dumps core, it starts by dumping the user struct - this will
+ * be used by gdb to figure out where the data and stack segments are within
+ * the file, and what virtual addresses to use.
+ */
+struct user {
+	/* We start with the registers, to mimic the way that "memory" is
+	 * returned from the ptrace(3,...) function.
+	 */
+	struct pt_regs regs;		/* Where the registers are actually stored */
+
+	/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long int u_tsize;	/* Text segment size (pages). */
+	unsigned long int u_dsize;	/* Data segment size (pages). */
+	unsigned long int u_ssize;	/* Stack segment size (pages). */
+	unsigned long start_code;	/* Starting virtual address of text. */
+	unsigned long start_stack;	/* Starting virtual address of stack area.
+					   This is actually the bottom of the stack,
+					   the top of the stack is always found in the
+					   esp register.  */
+	long int signal;		/* Signal that caused the core dump. */
+	int reserved;			/* No longer used */
+	struct user_pt_regs *u_ar0;	/* Used by gdb to help find the values for */
+
+	/* the registers */
+	unsigned long magic;		/* To uniquely identify a core file */
+	char u_comm[32];		/* User command that was responsible */
+};
+#endif
+
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR	+(u.start_code)
+#define HOST_STACK_END_ADDR	+(u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _ASM_USER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/vga.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/vga.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/vga.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* MN10300 VGA register definitions
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_VGA_H
+#define _ASM_VGA_H
+
+
+
+#endif /* _ASM_VGA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/xor.h linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/xor.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/include/asm/xor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/include/asm/xor.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/Kconfig linux-libre-2.6.30-gnu1/arch/mn10300/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mn10300/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -370,5 +370,3 @@ source "security/Kconfig"
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
-
-source "arch/mn10300/oprofile/Kconfig"
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/entry.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@
 #include <asm/intctl-regs.h>
 #include <asm/busctl-regs.h>
 #include <asm/timer-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/errno.h>
@@ -723,6 +723,8 @@ ENTRY(sys_call_table)
 	.long sys_dup3
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev		/* 335 */
 
 
 nr_syscalls=(.-sys_call_table)/4
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-serial.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-serial.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/exceptions.h>
 #include <asm/serial-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
 
 /*
  * initialise the GDB stub
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-serial-low.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-serial-low.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-serial-low.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-serial-low.S	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/thread_info.h>
 #include <asm/frame.inc>
 #include <asm/intctl-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
 
 	.text
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-ttysm.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-ttysm.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-ttysm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-ttysm.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@
 #include <asm/system.h>
 #include <asm/gdb-stub.h>
 #include <asm/exceptions.h>
-#include <asm/unit/clock.h>
+#include <unit/clock.h>
 #include "mn10300-serial.h"
 
 #if defined(CONFIG_GDBSTUB_ON_TTYSM0)
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-ttysm-low.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-ttysm-low.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-io-ttysm-low.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-io-ttysm-low.S	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/cpu-regs.h>
 #include <asm/frame.inc>
 #include <asm/intctl-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
 #include "mn10300-serial.h"
 
 	.text
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-stub.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-stub.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/gdb-stub.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/gdb-stub.c	2009-06-09 23:05:27.000000000 -0400
@@ -136,8 +136,8 @@
 #include <asm/cacheflush.h>
 #include <asm/serial-regs.h>
 #include <asm/busctl-regs.h>
-#include <asm/unit/leds.h>
-#include <asm/unit/serial.h>
+#include <unit/leds.h>
+#include <unit/serial.h>
 
 /* define to use F7F7 rather than FF which is subverted by JTAG debugger */
 #undef GDBSTUB_USE_F7F7_AS_BREAKPOINT
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/head.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <linux/linkage.h>
 #include <linux/serial_reg.h>
@@ -17,9 +18,9 @@
 #include <asm/pgtable.h>
 #include <asm/frame.inc>
 #include <asm/param.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
 
-	.section .text.head,"ax"
+	__HEAD
 
 ###############################################################################
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/irq.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -140,7 +140,7 @@ void __init init_IRQ(void)
 	int irq;
 
 	for (irq = 0; irq < NR_IRQS; irq++)
-		if (irq_desc[irq].chip == &no_irq_type)
+		if (irq_desc[irq].chip == &no_irq_chip)
 			/* due to the PIC latching interrupt requests, even
 			 * when the IRQ is disabled, IRQ_PENDING is superfluous
 			 * and we can use handle_level_irq() for edge-triggered
@@ -221,7 +221,7 @@ int show_interrupts(struct seq_file *p,
 		if (action) {
 			seq_printf(p, "%3d: ", i);
 			for_each_present_cpu(cpu)
-				seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+				seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
 			seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
 				   (GxICR(i) & GxICR_LEVEL) >>
 				   GxICR_LEVEL_SHIFT);
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-serial.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-serial.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@ static const char serial_revdate[] = "20
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/serial-regs.h>
-#include <asm/unit/timex.h>
+#include <unit/timex.h>
 #include "mn10300-serial.h"
 
 static inline __attribute__((format(printf, 1, 2)))
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-serial-low.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-serial-low.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-serial-low.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-serial-low.S	2009-06-09 23:05:27.000000000 -0400
@@ -18,8 +18,8 @@
 #include <asm/cpu-regs.h>
 #include <asm/frame.inc>
 #include <asm/timer-regs.h>
-#include <asm/proc/cache.h>
-#include <asm/unit/timex.h>
+#include <proc/cache.h>
+#include <unit/timex.h>
 #include "mn10300-serial.h"
 
 #define	SCxCTR	0x00
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-watchdog.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-watchdog.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/mn10300-watchdog.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/mn10300-watchdog.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
 #include <asm/div64.h>
 #include <asm/smp.h>
 #include <asm/gdb-stub.h>
-#include <asm/proc/clock.h>
+#include <proc/clock.h>
 
 static DEFINE_SPINLOCK(watchdog_print_lock);
 static unsigned int watchdog;
@@ -130,6 +130,7 @@ void watchdog_interrupt(struct pt_regs *
 	 * the stack NMI-atomically, it's safe to use smp_processor_id().
 	 */
 	int sum, cpu = smp_processor_id();
+	int irq = NMIIRQ;
 	u8 wdt, tmp;
 
 	wdt = WDCTR & ~WDCTR_WDCNE;
@@ -138,7 +139,7 @@ void watchdog_interrupt(struct pt_regs *
 	NMICR = NMICR_WDIF;
 
 	nmi_count(cpu)++;
-	kstat_this_cpu.irqs[NMIIRQ]++;
+	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 	sum = irq_stat[cpu].__irq_count;
 
 	if (last_irq_sums[cpu] == sum) {
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/process.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ void prepare_to_copy(struct task_struct
  * set up the kernel stack for a new thread and copy arch-specific thread
  * control information
  */
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
 		unsigned long c_usp, unsigned long ustk_size,
 		struct task_struct *p, struct pt_regs *kregs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/setup.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,7 +30,7 @@
 #include <asm/setup.h>
 #include <asm/io.h>
 #include <asm/smp.h>
-#include <asm/proc/proc.h>
+#include <proc/proc.h>
 #include <asm/busctl-regs.h>
 #include <asm/fpu.h>
 #include <asm/sections.h>
@@ -136,10 +136,6 @@ void __init setup_arch(char **cmdline_p)
 	data_resource.start = virt_to_bus(&_etext);
 	data_resource.end = virt_to_bus(&_edata)-1;
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
 	start_pfn = (CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT);
 	kstart_pfn = PFN_UP(__pa(&_text));
 	free_pfn = PFN_UP(__pa(&_end));
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/time.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,6 @@ static irqreturn_t timer_interrupt(int i
 static struct irqaction timer_irq = {
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 	.name		= "timer",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/traps.c linux-libre-2.6.30-gnu1/arch/mn10300/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cpu-regs.h>
 #include <asm/busctl-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
 #include <asm/fpu.h>
 #include <asm/gdb-stub.h>
 #include <asm/sections.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/mn10300/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/mn10300/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -27,10 +27,7 @@ SECTIONS
   _stext = .;
   _text = .;			/* Text and read-only data */
   .text : {
-	*(
-	.text.head
-	.text
-	)
+	HEAD_TEXT
 	TEXT_TEXT
 	SCHED_TEXT
 	LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/Makefile linux-libre-2.6.30-gnu1/arch/mn10300/Makefile
--- linux-libre-2.6.29-gnu1/arch/mn10300/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -94,42 +94,8 @@ ifdef CONFIG_DEBUG_INFO
 KBUILD_AFLAGS	+= -Wa,--gdwarf2
 endif
 
-###################################################################################################
-#
-# juggle some symlinks in the MN10300 asm include dir
 #
-#	Update machine proc and unit symlinks if something which affects
-#	them changed.  We use .proc / .unit to indicate when they were
-#	updated last, otherwise make uses the target directory mtime.
+# include the appropriate processor- and unit-specific headers
 #
-###################################################################################################
-
-# processor specific definitions
-include/asm-mn10300/.proc: $(wildcard include/config/proc/*.h) include/config/auto.conf
-	@echo '  SYMLINK include/asm-mn10300/proc -> include/asm-mn10300/proc-$(PROCESSOR)'
-ifneq ($(KBUILD_SRC),)
-	$(Q)mkdir -p include/asm-mn10300
-	$(Q)ln -fsn $(srctree)/include/asm-mn10300/proc-$(PROCESSOR) include/asm-mn10300/proc
-else
-	$(Q)ln -fsn proc-$(PROCESSOR) include/asm-mn10300/proc
-endif
-	@touch $@
-
-CLEAN_FILES += include/asm-mn10300/proc include/asm-mn10300/.proc
-
-prepare: include/asm-mn10300/.proc
-
-# unit specific definitions
-include/asm-mn10300/.unit: $(wildcard include/config/unit/*.h) include/config/auto.conf
-	@echo '  SYMLINK include/asm-mn10300/unit -> include/asm-mn10300/unit-$(UNIT)'
-ifneq ($(KBUILD_SRC),)
-	$(Q)mkdir -p include/asm-mn10300
-	$(Q)ln -fsn $(srctree)/include/asm-mn10300/unit-$(UNIT) include/asm-mn10300/unit
-else
-	$(Q)ln -fsn unit-$(UNIT) include/asm-mn10300/unit
-endif
-	@touch $@
-
-CLEAN_FILES += include/asm-mn10300/unit include/asm-mn10300/.unit
-
-prepare: include/asm-mn10300/.unit
+KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/proc-$(PROCESSOR)/include
+KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/unit-$(UNIT)/include
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/oprofile/Kconfig linux-libre-2.6.30-gnu1/arch/mn10300/oprofile/Kconfig
--- linux-libre-2.6.29-gnu1/arch/mn10300/oprofile/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/oprofile/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/cache.h linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/cache.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/cache.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+/* MN103E010 Cache specification
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PROC_CACHE_H
+#define _ASM_PROC_CACHE_H
+
+/* L1 cache */
+
+#define L1_CACHE_NWAYS		4	/* number of ways in caches */
+#define L1_CACHE_NENTRIES	256	/* number of entries in each way */
+#define L1_CACHE_BYTES		16	/* bytes per entry */
+#define L1_CACHE_SHIFT		4	/* shift for bytes per entry */
+#define L1_CACHE_WAYDISP	0x1000	/* displacement of one way from the next */
+
+#define L1_CACHE_TAG_VALID	0x00000001	/* cache tag valid bit */
+#define L1_CACHE_TAG_DIRTY	0x00000008	/* data cache tag dirty bit */
+#define L1_CACHE_TAG_ENTRY	0x00000ff0	/* cache tag entry address mask */
+#define L1_CACHE_TAG_ADDRESS	0xfffff000	/* cache tag line address mask */
+
+/*
+ * specification of the interval between interrupt checking intervals whilst
+ * managing the cache with the interrupts disabled
+ */
+#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL	4
+
+#endif /* _ASM_PROC_CACHE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/clock.h linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/clock.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/* MN103E010-specific clocks
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_PROC_CLOCK_H
+#define _ASM_PROC_CLOCK_H
+
+#include <unit/clock.h>
+
+#define MN10300_WDCLK		MN10300_IOCLK
+
+#endif /* _ASM_PROC_CLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/irq.h linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/irq.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,34 @@
+/* MN103E010 On-board interrupt controller numbers
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROC_IRQ_H
+#define _ASM_PROC_IRQ_H
+
+#ifdef __KERNEL__
+
+#define GxICR_NUM_IRQS		42
+
+#define GxICR_NUM_XIRQS		8
+
+#define XIRQ0		34
+#define XIRQ1		35
+#define XIRQ2		36
+#define XIRQ3		37
+#define XIRQ4		38
+#define XIRQ5		39
+#define XIRQ6		40
+#define XIRQ7		41
+
+#define XIRQ2IRQ(num)	(XIRQ0 + num)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_PROC_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/proc.h linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/proc.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/proc-mn103e010/include/proc/proc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/proc-mn103e010/include/proc/proc.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+/* MN103E010 Processor description
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROC_PROC_H
+#define _ASM_PROC_PROC_H
+
+#define PROCESSOR_VENDOR_NAME	"Matsushita"
+#define PROCESSOR_MODEL_NAME	"mn103e010"
+
+#endif /* _ASM_PROC_PROC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/clock.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/clock.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/* ASB2303-specific clocks
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_CLOCK_H
+#define _ASM_UNIT_CLOCK_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MN10300_RTC
+
+extern unsigned long mn10300_ioclk;	/* IOCLK (crystal speed) in HZ */
+extern unsigned long mn10300_iobclk;
+extern unsigned long mn10300_tsc_per_HZ;
+
+#define MN10300_IOCLK		((unsigned long)mn10300_ioclk)
+/* If this processors has a another clock, uncomment the below. */
+/* #define MN10300_IOBCLK	((unsigned long)mn10300_iobclk) */
+
+#else /* !CONFIG_MN10300_RTC */
+
+#define MN10300_IOCLK		33333333UL
+/* #define MN10300_IOBCLK	66666666UL */
+
+#endif /* !CONFIG_MN10300_RTC */
+
+#define MN10300_JCCLK		MN10300_IOCLK
+#define MN10300_TSCCLK		MN10300_IOCLK
+
+#ifdef CONFIG_MN10300_RTC
+#define MN10300_TSC_PER_HZ	((unsigned long)mn10300_tsc_per_HZ)
+#else /* !CONFIG_MN10300_RTC */
+#define MN10300_TSC_PER_HZ	(MN10300_TSCCLK/HZ)
+#endif /* !CONFIG_MN10300_RTC */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_CLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/leds.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/leds.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/leds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/leds.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/* ASB2303-specific LEDs
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_LEDS_H
+#define _ASM_UNIT_LEDS_H
+
+#include <asm/pio-regs.h>
+#include <asm/cpu-regs.h>
+#include <asm/exceptions.h>
+
+#define ASB2303_GPIO0DEF	__SYSREG(0xDB000000, u32)
+#define ASB2303_7SEGLEDS	__SYSREG(0xDB000008, u32)
+
+/*
+ * use the 7-segment LEDs to indicate states
+ */
+
+/* flip the 7-segment LEDs between "G" and "-" */
+#define mn10300_set_gdbleds(ONOFF)			\
+do {							\
+	ASB2303_7SEGLEDS = (ONOFF) ? 0x85 : 0x7f;	\
+} while (0)
+
+/* indicate double-fault by displaying "d" on the LEDs */
+#define mn10300_set_dbfleds			\
+	mov	0x43,d0			;	\
+	movbu	d0,(ASB2303_7SEGLEDS)
+
+#ifndef __ASSEMBLY__
+extern void peripheral_leds_display_exception(enum exception_code code);
+extern void peripheral_leds_led_chase(void);
+extern void debug_to_serial(const char *p, int n);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_LEDS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/serial.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/serial.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,136 @@
+/* ASB2303-specific 8250 serial ports
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_SERIAL_H
+#define _ASM_UNIT_SERIAL_H
+
+#include <asm/cpu-regs.h>
+#include <proc/irq.h>
+#include <linux/serial_reg.h>
+
+#define SERIAL_PORT0_BASE_ADDRESS	0xA6FB0000
+#define SERIAL_PORT1_BASE_ADDRESS	0xA6FC0000
+
+#define SERIAL_IRQ	XIRQ0	/* Dual serial (PC16552)	(Hi) */
+
+/*
+ * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
+ */
+#ifndef CONFIG_GDBSTUB_ON_TTYSx
+
+#define SERIAL_PORT_DFNS						\
+	{								\
+	.baud_base		= BASE_BAUD,				\
+	.irq			= SERIAL_IRQ,				\
+	.flags			= STD_COM_FLAGS,			\
+	.iomem_base		= (u8 *) SERIAL_PORT0_BASE_ADDRESS,	\
+	.iomem_reg_shift	= 2,					\
+	.io_type		= SERIAL_IO_MEM,			\
+	},								\
+	{								\
+	.baud_base		= BASE_BAUD,				\
+	.irq			= SERIAL_IRQ,				\
+	.flags			= STD_COM_FLAGS,			\
+	.iomem_base		= (u8 *) SERIAL_PORT1_BASE_ADDRESS,	\
+	.iomem_reg_shift	= 2,					\
+	.io_type		= SERIAL_IO_MEM,			\
+	},
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_PORT_DFNS /* both stolen by gdb-stub because they share an IRQ */
+
+#if defined(CONFIG_GDBSTUB_ON_TTYS0)
+#define GDBPORT_SERIAL_RX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX  * 4, u8)
+#define GDBPORT_SERIAL_TX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX  * 4, u8)
+#define GDBPORT_SERIAL_DLL	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8)
+#define GDBPORT_SERIAL_DLM	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8)
+#define GDBPORT_SERIAL_IER	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8)
+#define GDBPORT_SERIAL_IIR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8)
+#define GDBPORT_SERIAL_FCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8)
+#define GDBPORT_SERIAL_LCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8)
+#define GDBPORT_SERIAL_MCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8)
+#define GDBPORT_SERIAL_LSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8)
+#define GDBPORT_SERIAL_MSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8)
+#define GDBPORT_SERIAL_SCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8)
+#define GDBPORT_SERIAL_IRQ	SERIAL_IRQ
+
+#elif defined(CONFIG_GDBSTUB_ON_TTYS1)
+#define GDBPORT_SERIAL_RX	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_RX  * 4, u8)
+#define GDBPORT_SERIAL_TX	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_TX  * 4, u8)
+#define GDBPORT_SERIAL_DLL	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLL * 4, u8)
+#define GDBPORT_SERIAL_DLM	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLM * 4, u8)
+#define GDBPORT_SERIAL_IER	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IER * 4, u8)
+#define GDBPORT_SERIAL_IIR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IIR * 4, u8)
+#define GDBPORT_SERIAL_FCR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_FCR * 4, u8)
+#define GDBPORT_SERIAL_LCR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LCR * 4, u8)
+#define GDBPORT_SERIAL_MCR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MCR * 4, u8)
+#define GDBPORT_SERIAL_LSR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LSR * 4, u8)
+#define GDBPORT_SERIAL_MSR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MSR * 4, u8)
+#define GDBPORT_SERIAL_SCR	__SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_SCR * 4, u8)
+#define GDBPORT_SERIAL_IRQ	SERIAL_IRQ
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define LSR_WAIT_FOR(STATE)					\
+do {								\
+	while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE)) {}	\
+} while (0)
+#define FLOWCTL_WAIT_FOR(LINE)					\
+do {								\
+	while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE)) {}	\
+} while (0)
+#define FLOWCTL_CLEAR(LINE)			\
+do {						\
+	GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE;	\
+} while (0)
+#define FLOWCTL_SET(LINE)			\
+do {						\
+	GDBPORT_SERIAL_MCR |= UART_MCR_##LINE;	\
+} while (0)
+#define FLOWCTL_QUERY(LINE)	({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; })
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+	char ch;
+
+	FLOWCTL_SET(DTR);
+
+	for (; n > 0; n--) {
+		LSR_WAIT_FOR(THRE);
+		FLOWCTL_WAIT_FOR(CTS);
+
+		ch = *p++;
+		if (ch == 0x0a) {
+			GDBPORT_SERIAL_TX = 0x0d;
+			LSR_WAIT_FOR(THRE);
+			FLOWCTL_WAIT_FOR(CTS);
+		}
+		GDBPORT_SERIAL_TX = ch;
+	}
+
+	FLOWCTL_CLEAR(DTR);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#endif /* _ASM_UNIT_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/smc91111.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/smc91111.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/smc91111.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/smc91111.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+/* Support for the SMC91C111 NIC on an ASB2303
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UNIT_SMC91111_H
+#define _ASM_UNIT_SMC91111_H
+
+#include <asm/intctl-regs.h>
+
+#define SMC91111_BASE		0xAA000300UL
+#define SMC91111_BASE_END	0xAA000400UL
+#define SMC91111_IRQ		XIRQ3
+
+#define SMC_CAN_USE_8BIT	0
+#define SMC_CAN_USE_16BIT	1
+#define SMC_CAN_USE_32BIT	0
+#define SMC_NOWAIT		1
+#define SMC_IRQ_FLAGS		(0)
+
+#if SMC_CAN_USE_8BIT
+#define SMC_inb(a, r)		inb((unsigned long) ((a) + (r)))
+#define SMC_outb(v, a, r)	outb(v, (unsigned long) ((a) + (r)))
+#endif
+
+#if SMC_CAN_USE_16BIT
+#define SMC_inw(a, r)		inw((unsigned long) ((a) + (r)))
+#define SMC_outw(v, a, r)	outw(v, (unsigned long) ((a) + (r)))
+#define SMC_insw(a, r, p, l)	insw((unsigned long) ((a) + (r)), (p), (l))
+#define SMC_outsw(a, r, p, l)	outsw((unsigned long) ((a) + (r)), (p), (l))
+#endif
+
+#if SMC_CAN_USE_32BIT
+#define SMC_inl(a, r)		inl((unsigned long) ((a) + (r)))
+#define SMC_outl(v, a, r)	outl(v, (unsigned long) ((a) + (r)))
+#define SMC_insl(a, r, p, l)	insl((unsigned long) ((a) + (r)), (p), (l))
+#define SMC_outsl(a, r, p, l)	outsl((unsigned long) ((a) + (r)), (p), (l))
+#endif
+
+#define RPC_LSA_DEFAULT		RPC_LED_100_10
+#define RPC_LSB_DEFAULT		RPC_LED_TX_RX
+
+#define set_irq_type(irq, type)
+
+#endif /*  _ASM_UNIT_SMC91111_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/timex.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/timex.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/include/unit/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/include/unit/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,135 @@
+/* ASB2303-specific timer specifcations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UNIT_TIMEX_H
+#define _ASM_UNIT_TIMEX_H
+
+#ifndef __ASSEMBLY__
+#include <linux/irq.h>
+#endif /* __ASSEMBLY__ */
+
+#include <asm/timer-regs.h>
+#include <unit/clock.h>
+
+/*
+ * jiffies counter specifications
+ */
+
+#define	TMJCBR_MAX		0xffff
+#define	TMJCBC			TM01BC
+
+#define	TMJCMD			TM01MD
+#define	TMJCBR			TM01BR
+#define	TMJCIRQ			TM1IRQ
+#define	TMJCICR			TM1ICR
+#define	TMJCICR_LEVEL		GxICR_LEVEL_5
+
+#ifndef __ASSEMBLY__
+
+static inline void startup_jiffies_counter(void)
+{
+	unsigned rate;
+	u16 md, t16;
+
+	/* use as little prescaling as possible to avoid losing accuracy */
+	md = TM0MD_SRC_IOCLK;
+	rate = MN10300_JCCLK / HZ;
+
+	if (rate > TMJCBR_MAX) {
+		md = TM0MD_SRC_IOCLK_8;
+		rate = MN10300_JCCLK / 8 / HZ;
+
+		if (rate > TMJCBR_MAX) {
+			md = TM0MD_SRC_IOCLK_32;
+			rate = MN10300_JCCLK / 32 / HZ;
+
+			if (rate > TMJCBR_MAX)
+				BUG();
+		}
+	}
+
+	TMJCBR = rate - 1;
+	t16 = TMJCBR;
+
+	TMJCMD =
+		md |
+		TM1MD_SRC_TM0CASCADE << 8 |
+		TM0MD_INIT_COUNTER |
+		TM1MD_INIT_COUNTER << 8;
+
+	TMJCMD =
+		md |
+		TM1MD_SRC_TM0CASCADE << 8 |
+		TM0MD_COUNT_ENABLE |
+		TM1MD_COUNT_ENABLE << 8;
+
+	t16 = TMJCMD;
+
+	TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
+	t16 = TMJCICR;
+}
+
+static inline void shutdown_jiffies_counter(void)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+
+/*
+ * timestamp counter specifications
+ */
+
+#define	TMTSCBR_MAX		0xffffffff
+#define	TMTSCBC			TM45BC
+
+#ifndef __ASSEMBLY__
+
+static inline void startup_timestamp_counter(void)
+{
+	/* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
+	 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate
+	 */
+	TM45BR = TMTSCBR_MAX;
+
+	TM4MD = TM4MD_SRC_IOCLK;
+	TM4MD |= TM4MD_INIT_COUNTER;
+	TM4MD &= ~TM4MD_INIT_COUNTER;
+	TM4ICR = 0;
+
+	TM5MD = TM5MD_SRC_TM4CASCADE;
+	TM5MD |= TM5MD_INIT_COUNTER;
+	TM5MD &= ~TM5MD_INIT_COUNTER;
+	TM5ICR = 0;
+
+	TM5MD |= TM5MD_COUNT_ENABLE;
+	TM4MD |= TM4MD_COUNT_ENABLE;
+}
+
+static inline void shutdown_timestamp_counter(void)
+{
+	TM4MD = 0;
+	TM5MD = 0;
+}
+
+/*
+ * we use a cascaded pair of 16-bit down-counting timers to count I/O
+ * clock cycles for the purposes of time keeping
+ */
+typedef unsigned long cycles_t;
+
+static inline cycles_t read_timestamp_counter(void)
+{
+	return (cycles_t)TMTSCBC;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/leds.c linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/leds.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/leds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/leds.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@
 #include <asm/processor.h>
 #include <asm/intctl-regs.h>
 #include <asm/rtc-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
 
 #if 0
 static const u8 asb2303_led_hex_tbl[16] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/smc91111.c linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/smc91111.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2303/smc91111.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2303/smc91111.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/timex.h>
 #include <asm/processor.h>
 #include <asm/intctl-regs.h>
-#include <asm/unit/smc91111.h>
+#include <unit/smc91111.h>
 
 static struct resource smc91c111_resources[] = {
 	[0] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/clock.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/clock.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/clock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/* ASB2305-specific clocks
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_CLOCK_H
+#define _ASM_UNIT_CLOCK_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MN10300_RTC
+
+extern unsigned long mn10300_ioclk;	/* IOCLK (crystal speed) in HZ */
+extern unsigned long mn10300_iobclk;
+extern unsigned long mn10300_tsc_per_HZ;
+
+#define MN10300_IOCLK		((unsigned long)mn10300_ioclk)
+/* If this processors has a another clock, uncomment the below. */
+/* #define MN10300_IOBCLK	((unsigned long)mn10300_iobclk) */
+
+#else /* !CONFIG_MN10300_RTC */
+
+#define MN10300_IOCLK		33333333UL
+/* #define MN10300_IOBCLK	66666666UL */
+
+#endif /* !CONFIG_MN10300_RTC */
+
+#define MN10300_JCCLK		MN10300_IOCLK
+#define MN10300_TSCCLK		MN10300_IOCLK
+
+#ifdef CONFIG_MN10300_RTC
+#define MN10300_TSC_PER_HZ	((unsigned long)mn10300_tsc_per_HZ)
+#else /* !CONFIG_MN10300_RTC */
+#define MN10300_TSC_PER_HZ	(MN10300_TSCCLK/HZ)
+#endif /* !CONFIG_MN10300_RTC */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_CLOCK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/leds.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/leds.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/leds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/leds.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,51 @@
+/* ASB2305-specific LEDs
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNIT_LEDS_H
+#define _ASM_UNIT_LEDS_H
+
+#include <asm/pio-regs.h>
+#include <asm/cpu-regs.h>
+#include <asm/exceptions.h>
+
+#define ASB2305_7SEGLEDS	__SYSREG(0xA6F90000, u32)
+
+/* perform a hard reset by driving PIO06 low */
+#define mn10300_unit_hard_reset()		\
+do {						\
+	P0OUT &= 0xbf;				\
+	P0MD = (P0MD & P0MD_6) | P0MD_6_OUT;	\
+} while (0)
+
+/*
+ * use the 7-segment LEDs to indicate states
+ */
+/* indicate double-fault by displaying "db-f" on the LEDs */
+#define mn10300_set_dbfleds			\
+	mov	0x43077f1d,d0		;	\
+	mov	d0,(ASB2305_7SEGLEDS)
+
+/* flip the 7-segment LEDs between "Gdb-" and "----" */
+#define mn10300_set_gdbleds(ONOFF)				\
+do {								\
+	ASB2305_7SEGLEDS = (ONOFF) ? 0x8543077f : 0x7f7f7f7f;	\
+} while (0)
+
+#ifndef __ASSEMBLY__
+extern void peripheral_leds_display_exception(enum exception_code);
+extern void peripheral_leds_led_chase(void);
+extern void peripheral_leds7x4_display_dec(unsigned int, unsigned int);
+extern void peripheral_leds7x4_display_hex(unsigned int, unsigned int);
+extern void peripheral_leds7x4_display_minssecs(unsigned int, unsigned int);
+extern void peripheral_leds7x4_display_rtc(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_LEDS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,120 @@
+/* ASB2305-specific 8250 serial ports
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UNIT_SERIAL_H
+#define _ASM_UNIT_SERIAL_H
+
+#include <asm/cpu/cpu-regs.h>
+#include <proc/irq.h>
+#include <linux/serial_reg.h>
+
+#define SERIAL_PORT0_BASE_ADDRESS	0xA6FB0000
+#define ASB2305_DEBUG_MCR	__SYSREG(0xA6FB0000 + UART_MCR * 2, u8)
+
+#define SERIAL_IRQ	XIRQ0	/* Dual serial (PC16552)	(Hi) */
+
+/*
+ * dispose of the /dev/ttyS0 serial port
+ */
+#ifndef CONFIG_GDBSTUB_ON_TTYSx
+
+#define SERIAL_PORT_DFNS						\
+	{								\
+	.baud_base		= BASE_BAUD,				\
+	.irq			= SERIAL_IRQ,				\
+	.flags			= STD_COM_FLAGS,			\
+	.iomem_base		= (u8 *) SERIAL_PORT0_BASE_ADDRESS,	\
+	.iomem_reg_shift	= 2,					\
+	.io_type		= SERIAL_IO_MEM,			\
+	},
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_PORT_DFNS /* stolen by gdb-stub */
+
+#if defined(CONFIG_GDBSTUB_ON_TTYS0)
+#define GDBPORT_SERIAL_RX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX  * 4, u8)
+#define GDBPORT_SERIAL_TX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX  * 4, u8)
+#define GDBPORT_SERIAL_DLL	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8)
+#define GDBPORT_SERIAL_DLM	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8)
+#define GDBPORT_SERIAL_IER	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8)
+#define GDBPORT_SERIAL_IIR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8)
+#define GDBPORT_SERIAL_FCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8)
+#define GDBPORT_SERIAL_LCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8)
+#define GDBPORT_SERIAL_MCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8)
+#define GDBPORT_SERIAL_LSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8)
+#define GDBPORT_SERIAL_MSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8)
+#define GDBPORT_SERIAL_SCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8)
+#define GDBPORT_SERIAL_IRQ	SERIAL_IRQ
+
+#elif defined(CONFIG_GDBSTUB_ON_TTYS1)
+#error The ASB2305 doesnt have a /dev/ttyS1
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define TTYS0_TX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX  * 4, u8)
+#define TTYS0_MCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8)
+#define TTYS0_LSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8)
+#define TTYS0_MSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8)
+
+#define LSR_WAIT_FOR(STATE)				\
+do {							\
+	while (!(TTYS0_LSR & UART_LSR_##STATE)) {}	\
+} while (0)
+#define FLOWCTL_WAIT_FOR(LINE)				\
+do {							\
+	while (!(TTYS0_MSR & UART_MSR_##LINE)) {}	\
+} while (0)
+#define FLOWCTL_CLEAR(LINE)			\
+do {						\
+	TTYS0_MCR &= ~UART_MCR_##LINE;		\
+} while (0)
+#define FLOWCTL_SET(LINE)			\
+do {						\
+	TTYS0_MCR |= UART_MCR_##LINE;		\
+} while (0)
+#define FLOWCTL_QUERY(LINE)	({ TTYS0_MSR & UART_MSR_##LINE; })
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+	char ch;
+
+	FLOWCTL_SET(DTR);
+
+	for (; n > 0; n--) {
+		LSR_WAIT_FOR(THRE);
+		FLOWCTL_WAIT_FOR(CTS);
+
+		ch = *p++;
+		if (ch == 0x0a) {
+			TTYS0_TX = 0x0d;
+			LSR_WAIT_FOR(THRE);
+			FLOWCTL_WAIT_FOR(CTS);
+		}
+		TTYS0_TX = ch;
+	}
+
+	FLOWCTL_CLEAR(DTR);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#endif /* _ASM_UNIT_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/include/unit/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,135 @@
+/* ASB2305 timer specifcations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _ASM_UNIT_TIMEX_H
+#define _ASM_UNIT_TIMEX_H
+
+#ifndef __ASSEMBLY__
+#include <linux/irq.h>
+#endif /* __ASSEMBLY__ */
+
+#include <asm/cpu/timer-regs.h>
+#include <unit/clock.h>
+
+/*
+ * jiffies counter specifications
+ */
+
+#define	TMJCBR_MAX		0xffff
+#define	TMJCBC			TM01BC
+
+#define	TMJCMD			TM01MD
+#define	TMJCBR			TM01BR
+#define	TMJCIRQ			TM1IRQ
+#define	TMJCICR			TM1ICR
+#define	TMJCICR_LEVEL		GxICR_LEVEL_5
+
+#ifndef __ASSEMBLY__
+
+static inline void startup_jiffies_counter(void)
+{
+	unsigned rate;
+	u16 md, t16;
+
+	/* use as little prescaling as possible to avoid losing accuracy */
+	md = TM0MD_SRC_IOCLK;
+	rate = MN10300_JCCLK / HZ;
+
+	if (rate > TMJCBR_MAX) {
+		md = TM0MD_SRC_IOCLK_8;
+		rate = MN10300_JCCLK / 8 / HZ;
+
+		if (rate > TMJCBR_MAX) {
+			md = TM0MD_SRC_IOCLK_32;
+			rate = MN10300_JCCLK / 32 / HZ;
+
+			if (rate > TMJCBR_MAX)
+				BUG();
+		}
+	}
+
+	TMJCBR = rate - 1;
+	t16 = TMJCBR;
+
+	TMJCMD =
+		md |
+		TM1MD_SRC_TM0CASCADE << 8 |
+		TM0MD_INIT_COUNTER |
+		TM1MD_INIT_COUNTER << 8;
+
+	TMJCMD =
+		md |
+		TM1MD_SRC_TM0CASCADE << 8 |
+		TM0MD_COUNT_ENABLE |
+		TM1MD_COUNT_ENABLE << 8;
+
+	t16 = TMJCMD;
+
+	TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
+	t16 = TMJCICR;
+}
+
+static inline void shutdown_jiffies_counter(void)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+
+/*
+ * timestamp counter specifications
+ */
+
+#define	TMTSCBR_MAX		0xffffffff
+#define	TMTSCBC			TM45BC
+
+#ifndef __ASSEMBLY__
+
+static inline void startup_timestamp_counter(void)
+{
+	/* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
+	 * - count down from 4Gig-1 to 0 and wrap at IOCLK rate
+	 */
+	TM45BR = TMTSCBR_MAX;
+
+	TM4MD = TM4MD_SRC_IOCLK;
+	TM4MD |= TM4MD_INIT_COUNTER;
+	TM4MD &= ~TM4MD_INIT_COUNTER;
+	TM4ICR = 0;
+
+	TM5MD = TM5MD_SRC_TM4CASCADE;
+	TM5MD |= TM5MD_INIT_COUNTER;
+	TM5MD &= ~TM5MD_INIT_COUNTER;
+	TM5ICR = 0;
+
+	TM5MD |= TM5MD_COUNT_ENABLE;
+	TM4MD |= TM4MD_COUNT_ENABLE;
+}
+
+static inline void shutdown_timestamp_counter(void)
+{
+	TM4MD = 0;
+	TM5MD = 0;
+}
+
+/*
+ * we use a cascaded pair of 16-bit down-counting timers to count I/O
+ * clock cycles for the purposes of time keeping
+ */
+typedef unsigned long cycles_t;
+
+static inline cycles_t read_timestamp_counter(void)
+{
+	return (cycles_t) TMTSCBC;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_TIMEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/leds.c linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/leds.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/leds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/leds.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,7 @@
 #include <asm/processor.h>
 #include <asm/cpu/intctl-regs.h>
 #include <asm/cpu/rtc-regs.h>
-#include <asm/unit/leds.h>
+#include <unit/leds.h>
 
 static const u8 asb2305_led_hex_tbl[16] = {
 	0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0,
diff -druNp linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/unit-init.c linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/unit-init.c
--- linux-libre-2.6.29-gnu1/arch/mn10300/unit-asb2305/unit-init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/mn10300/unit-asb2305/unit-init.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/cpu/intctl-regs.h>
 #include <asm/cpu/rtc-regs.h>
 #include <asm/cpu/serial-regs.h>
-#include <asm/unit/serial.h>
+#include <unit/serial.h>
 
 /*
  * initialise some of the unit hardware before gdbstub is set up
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/atomic.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/atomic.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/atomic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/atomic.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
  * Since "a" is usually an address, use one spinlock per cacheline.
  */
 #  define ATOMIC_HASH_SIZE 4
-#  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
+#  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;
 
@@ -222,13 +222,13 @@ static __inline__ int atomic_add_unless(
 
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-#define atomic_add(i,v)	((void)(__atomic_add_return( ((int)i),(v))))
-#define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)i),(v))))
+#define atomic_add(i,v)	((void)(__atomic_add_return( ((int)(i)),(v))))
+#define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)(i)),(v))))
 #define atomic_inc(v)	((void)(__atomic_add_return(   1,(v))))
 #define atomic_dec(v)	((void)(__atomic_add_return(  -1,(v))))
 
-#define atomic_add_return(i,v)	(__atomic_add_return( ((int)i),(v)))
-#define atomic_sub_return(i,v)	(__atomic_add_return(-((int)i),(v)))
+#define atomic_add_return(i,v)	(__atomic_add_return( ((int)(i)),(v)))
+#define atomic_sub_return(i,v)	(__atomic_add_return(-((int)(i)),(v)))
 #define atomic_inc_return(v)	(__atomic_add_return(   1,(v)))
 #define atomic_dec_return(v)	(__atomic_add_return(  -1,(v)))
 
@@ -289,13 +289,13 @@ atomic64_read(const atomic64_t *v)
 	return v->counter;
 }
 
-#define atomic64_add(i,v)	((void)(__atomic64_add_return( ((s64)i),(v))))
-#define atomic64_sub(i,v)	((void)(__atomic64_add_return(-((s64)i),(v))))
+#define atomic64_add(i,v)	((void)(__atomic64_add_return( ((s64)(i)),(v))))
+#define atomic64_sub(i,v)	((void)(__atomic64_add_return(-((s64)(i)),(v))))
 #define atomic64_inc(v)		((void)(__atomic64_add_return(   1,(v))))
 #define atomic64_dec(v)		((void)(__atomic64_add_return(  -1,(v))))
 
-#define atomic64_add_return(i,v)	(__atomic64_add_return( ((s64)i),(v)))
-#define atomic64_sub_return(i,v)	(__atomic64_add_return(-((s64)i),(v)))
+#define atomic64_add_return(i,v)	(__atomic64_add_return( ((s64)(i)),(v)))
+#define atomic64_sub_return(i,v)	(__atomic64_add_return(-((s64)(i)),(v)))
 #define atomic64_inc_return(v)		(__atomic64_add_return(   1,(v)))
 #define atomic64_dec_return(v)		(__atomic64_add_return(  -1,(v)))
 
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/cacheflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,6 +97,9 @@ void mark_rodata_ro(void);
 
 #ifdef CONFIG_PA8X00
 /* Only pa8800, pa8900 needs this */
+
+#include <asm/kmap_types.h>
+
 #define ARCH_HAS_KMAP
 
 void kunmap_parisc(void *addr);
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/elf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -168,6 +168,16 @@ typedef struct elf64_fdesc {
 	__u64	gp;
 } Elf64_Fdesc;
 
+#ifdef __KERNEL__
+
+#ifdef CONFIG_64BIT
+#define Elf_Fdesc	Elf64_Fdesc
+#else
+#define Elf_Fdesc	Elf32_Fdesc
+#endif /*CONFIG_64BIT*/
+
+#endif /*__KERNEL__*/
+
 /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
 
 #define PT_HP_TLS		(PT_LOOS + 0x0)
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+#ifndef _ASM_PARISC_FTRACE_H
+#define _ASM_PARISC_FTRACE_H
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+
+/*
+ * Stack of return addresses for functions of a thread.
+ * Used in struct thread_info
+ */
+struct ftrace_ret_stack {
+	unsigned long ret;
+	unsigned long func;
+	unsigned long long calltime;
+};
+
+/*
+ * Primary handler of a function return.
+ * It relays on ftrace_return_to_handler.
+ * Defined in entry.S
+ */
+extern void return_to_handler(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PARISC_FTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/page.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,16 +36,7 @@ void clear_user_page(void *page, unsigne
  */
 #define STRICT_MM_TYPECHECKS
 #ifdef STRICT_MM_TYPECHECKS
-typedef struct { unsigned long pte;
-#if !defined(CONFIG_64BIT)
-                 unsigned long future_flags;
- /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY
-	 to 2, but then strangely the identical 32bit kernel boots on a
-	 c3000(pa20), but not any longer on a 715(pa11).
-	 Still investigating... HelgeD.
-  */
-#endif
-} pte_t; /* either 32 or 64bit */
+typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
 
 /* NOTE: even on 64 bits, these entries are __u32 because we allocate
  * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
@@ -111,7 +102,7 @@ extern int npmem_ranges;
 #define BITS_PER_PMD_ENTRY	2
 #define BITS_PER_PGD_ENTRY	2
 #else
-#define BITS_PER_PTE_ENTRY	3
+#define BITS_PER_PTE_ENTRY	2
 #define BITS_PER_PMD_ENTRY	2
 #define BITS_PER_PGD_ENTRY	BITS_PER_PMD_ENTRY
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/pdc.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/pdc.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/pdc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/pdc.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,6 +49,8 @@
 #define PDC_MODEL_CPU_ID	6	/* returns cpu-id (only newer machines!) */
 #define PDC_MODEL_CAPABILITIES	7	/* returns OS32/OS64-flags	*/
 /* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define  PDC_MODEL_OS64			(1 << 0)
+#define  PDC_MODEL_OS32			(1 << 1)
 #define  PDC_MODEL_IOPDIR_FDC		(1 << 2)
 #define  PDC_MODEL_NVA_MASK		(3 << 4)
 #define  PDC_MODEL_NVA_SUPPORTED	(0 << 4)
@@ -336,10 +338,13 @@
 #define NUM_PDC_RESULT	32
 
 #if !defined(__ASSEMBLY__)
-#ifdef __KERNEL__
 
 #include <linux/types.h>
 
+#ifdef __KERNEL__
+
+#include <asm/page.h> /* for __PAGE_OFFSET */
+
 extern int pdc_type;
 
 /* Values for pdc_type */
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/pgtable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,11 +50,7 @@
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
 /* This is the size of the initially mapped kernel memory */
-#ifdef CONFIG_64BIT
 #define KERNEL_INITIAL_ORDER	24	/* 0 to 1<<24 = 16MB */
-#else
-#define KERNEL_INITIAL_ORDER	23	/* 0 to 1<<23 = 8MB */
-#endif
 #define KERNEL_INITIAL_SIZE	(1 << KERNEL_INITIAL_ORDER)
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
@@ -91,16 +87,25 @@
 
 /* Definitions for 1st level */
 #define PGDIR_SHIFT	(PMD_SHIFT + BITS_PER_PMD)
+#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
+#define BITS_PER_PGD	(BITS_PER_LONG - PGDIR_SHIFT)
+#else
 #define BITS_PER_PGD	(PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY)
+#endif
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD    (1UL << BITS_PER_PGD)
 #define USER_PTRS_PER_PGD       PTRS_PER_PGD
 
+#ifdef CONFIG_64BIT
 #define MAX_ADDRBITS	(PGDIR_SHIFT + BITS_PER_PGD)
 #define MAX_ADDRESS	(1UL << MAX_ADDRBITS)
-
 #define SPACEID_SHIFT	(MAX_ADDRBITS - 32)
+#else
+#define MAX_ADDRBITS	(BITS_PER_LONG)
+#define MAX_ADDRESS	(1UL << MAX_ADDRBITS)
+#define SPACEID_SHIFT	0
+#endif
 
 /* This calculates the number of initial pages we need for the initial
  * page tables */
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,8 @@ extern void smp_send_reschedule(int cpu)
 extern void smp_send_all_nop(void);
 
 extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
 
 #endif /* !ASSEMBLY */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,6 +54,9 @@
 
 #define SO_MARK			0x401f
 
+#define SO_TIMESTAMPING		0x4020
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 /* 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.29-gnu1/arch/parisc/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -187,6 +187,9 @@ static __inline__ int __raw_write_can_lo
 	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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/parisc/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/parisc/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _PARISC_SWAB_H
 #define _PARISC_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 #define __SWAB_64_THRU_32__
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/Kconfig linux-libre-2.6.30-gnu1/arch/parisc/Kconfig
--- linux-libre-2.6.29-gnu1/arch/parisc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -9,9 +9,13 @@ config PARISC
 	def_bool y
 	select HAVE_IDE
 	select HAVE_OPROFILE
+	select HAVE_FUNCTION_TRACER if 64BIT
+	select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT
 	select RTC_CLASS
-	select RTC_DRV_PARISC
+	select RTC_DRV_GENERIC
 	select INIT_ALL_POSSIBLE
+	select BUG
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
 	  in many of their workstations & servers (HP9000 700 and 800 series,
@@ -75,6 +79,9 @@ config GENERIC_HARDIRQS
 config GENERIC_IRQ_PROBE
 	def_bool y
 
+config HAVE_LATENCYTOP_SUPPORT
+        def_bool y
+
 config IRQ_PER_CPU
 	bool
 	default y
@@ -83,6 +90,9 @@ config IRQ_PER_CPU
 config PM
 	bool
 
+config STACKTRACE_SUPPORT
+	def_bool y
+
 config ISA_DMA_API
 	bool
 
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/entry.S linux-libre-2.6.30-gnu1/arch/parisc/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -505,6 +505,18 @@
 	STREG		\pte,0(\ptep)
 	.endm
 
+	/* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+	 * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+	#define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
+
+	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+	.macro		convert_for_tlb_insert20 pte
+	extrd,u		\pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+				64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
+				(63-58)+PAGE_ADD_SHIFT,\pte
+	.endm
+
 	/* Convert the pte and prot to tlb insertion values.  How
 	 * this happens is quite subtle, read below */
 	.macro		make_insert_tlb	spc,pte,prot
@@ -544,8 +556,7 @@
 	depi		1,12,1,\prot
 
 	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
-	extrd,u		\pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
-	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
+	convert_for_tlb_insert20 \pte
 	.endm
 
 	/* Identical macro to make_insert_tlb above, except it
@@ -563,8 +574,8 @@
 
 	/* Get rid of prot bits and convert to page addr for iitlba */
 
-	depi		_PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
-	extru		\pte,24,25,\pte
+	depi		0,31,ASM_PFN_PTE_SHIFT,\pte
+	SHRREG		\pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
 	.endm
 
 	/* This is for ILP32 PA2.0 only.  The TLB insertion needs
@@ -1244,10 +1255,9 @@ nadtlb_check_flush_20w:
 	depdi,z         7,7,3,prot
 	depdi           1,10,1,prot
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+	/* Drop prot bits from pte and convert to page addr for idtlbt */
+	convert_for_tlb_insert20 pte
 
-	depdi		0,63,12,pte
-	extrd,u         pte,56,52,pte
 	idtlbt          pte,prot
 
 	rfir
@@ -1337,8 +1347,8 @@ nadtlb_check_flush_11:
 
 	/* Get rid of prot bits and convert to page addr for idtlba */
 
-	depi		0,31,12,pte
-	extru		pte,24,25,pte
+	depi		0,31,ASM_PFN_PTE_SHIFT,pte
+	SHRREG		pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
 
 	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
@@ -1403,10 +1413,9 @@ nadtlb_check_flush_20:
 	depdi,z         7,7,3,prot
 	depdi           1,10,1,prot
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+	/* Drop prot bits from pte and convert to page addr for idtlbt */
+	convert_for_tlb_insert20 pte
 
-	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
 	idtlbt          pte,prot
 
 	rfir
@@ -2176,6 +2185,33 @@ syscall_do_resched:
 ENDPROC(syscall_exit)
 
 
+#ifdef CONFIG_FUNCTION_TRACER
+	.import ftrace_function_trampoline,code
+ENTRY(_mcount)
+	copy	%r3, %arg2
+	b	ftrace_function_trampoline
+	nop
+ENDPROC(_mcount)
+
+ENTRY(return_to_handler)
+	load32	return_trampoline, %rp
+	copy	%ret0, %arg0
+	copy	%ret1, %arg1
+	b	ftrace_return_to_handler
+	nop
+return_trampoline:
+	copy	%ret0, %rp
+	copy	%r23, %ret0
+	copy	%r24, %ret1
+
+.globl ftrace_stub
+ftrace_stub:
+	bv	%r0(%rp)
+	nop
+ENDPROC(return_to_handler)
+#endif	/* CONFIG_FUNCTION_TRACER */
+
+
 get_register:
 	/*
 	 * get_register is used by the non access tlb miss handlers to
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/firmware.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/firmware.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/firmware.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/firmware.c	2009-06-09 23:05:27.000000000 -0400
@@ -527,7 +527,11 @@ int pdc_model_capabilities(unsigned long
         pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
-        *capabilities = pdc_result[0];
+        if (retval == PDC_OK) {
+                *capabilities = pdc_result[0];
+        } else {
+                *capabilities = PDC_MODEL_OS32;
+        }
         spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/ftrace.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/ftrace.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/ftrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/ftrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,185 @@
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * 	- add CONFIG_DYNAMIC_FTRACE
+ *	- add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Add a function return address to the trace stack on thread info.*/
+static int push_return_trace(unsigned long ret, unsigned long long time,
+				unsigned long func, int *depth)
+{
+	int index;
+
+	if (!current->ret_stack)
+		return -EBUSY;
+
+	/* The return trace stack is full */
+	if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
+		atomic_inc(&current->trace_overrun);
+		return -EBUSY;
+	}
+
+	index = ++current->curr_ret_stack;
+	barrier();
+	current->ret_stack[index].ret = ret;
+	current->ret_stack[index].func = func;
+	current->ret_stack[index].calltime = time;
+	*depth = index;
+
+	return 0;
+}
+
+/* Retrieve a function return address to the trace stack on thread info.*/
+static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
+{
+	int index;
+
+	index = current->curr_ret_stack;
+
+	if (unlikely(index < 0)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		/* Might as well panic, otherwise we have no where to go */
+		*ret = (unsigned long)
+			dereference_function_descriptor(&panic);
+		return;
+	}
+
+	*ret = current->ret_stack[index].ret;
+	trace->func = current->ret_stack[index].func;
+	trace->calltime = current->ret_stack[index].calltime;
+	trace->overrun = atomic_read(&current->trace_overrun);
+	trace->depth = index;
+	barrier();
+	current->curr_ret_stack--;
+
+}
+
+/*
+ * Send the trace to the ring-buffer.
+ * @return the original return address.
+ */
+unsigned long ftrace_return_to_handler(unsigned long retval0,
+				       unsigned long retval1)
+{
+	struct ftrace_graph_ret trace;
+	unsigned long ret;
+
+	pop_return_trace(&trace, &ret);
+	trace.rettime = cpu_clock(raw_smp_processor_id());
+	ftrace_graph_return(&trace);
+
+	if (unlikely(!ret)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		/* Might as well panic. What else to do? */
+		ret = (unsigned long)
+			dereference_function_descriptor(&panic);
+	}
+
+	/* HACK: we hand over the old functions' return values
+	   in %r23 and %r24. Assembly in entry.S will take care
+	   and move those to their final registers %ret0 and %ret1 */
+	asm( "copy %0, %%r23 \n\t"
+	     "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) );
+
+	return ret;
+}
+
+/*
+ * 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;
+	unsigned long long calltime;
+	struct ftrace_graph_ent trace;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	old = *parent;
+	*parent = (unsigned long)
+		  dereference_function_descriptor(&return_to_handler);
+
+	if (unlikely(!__kernel_text_address(old))) {
+		ftrace_graph_stop();
+		*parent = old;
+		WARN_ON(1);
+		return;
+	}
+
+	calltime = cpu_clock(raw_smp_processor_id());
+
+	if (push_return_trace(old, calltime,
+				self_addr, &trace.depth) == -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 */
+
+
+void ftrace_function_trampoline(unsigned long parent,
+				unsigned long self_addr,
+				unsigned long org_sp_gr3)
+{
+	extern ftrace_func_t ftrace_trace_function;
+
+	if (function_trace_stop)
+		return;
+
+	if (ftrace_trace_function != ftrace_stub) {
+		ftrace_trace_function(parent, self_addr);
+		return;
+	}
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	if (ftrace_graph_entry && ftrace_graph_return) {
+		unsigned long sp;
+		unsigned long *parent_rp;
+
+                asm volatile ("copy %%r30, %0" : "=r"(sp));
+		/* sanity check: is stack pointer which we got from
+		   assembler function in entry.S in a reasonable
+		   range compared to current stack pointer? */
+		if ((sp - org_sp_gr3) > 0x400)
+			return;
+
+		/* calculate pointer to %rp in stack */
+		parent_rp = (unsigned long *) org_sp_gr3 - 0x10;
+		/* sanity check: parent_rp should hold parent */
+		if (*parent_rp != parent)
+			return;
+		
+		prepare_ftrace_return(parent_rp, self_addr);
+		return;
+	}
+#endif
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/irq.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -138,7 +138,7 @@ static void cpu_set_affinity_irq(unsigne
 	if (cpu_dest < 0)
 		return;
 
-	cpumask_copy(&irq_desc[irq].affinity, &cpumask_of_cpu(cpu_dest));
+	cpumask_copy(&irq_desc[irq].affinity, dest);
 }
 #endif
 
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
@@ -311,12 +311,12 @@ unsigned long txn_alloc_addr(unsigned in
 	next_cpu++; /* assign to "next" CPU we want this bugger on */
 
 	/* validate entry */
-	while ((next_cpu < NR_CPUS) &&
+	while ((next_cpu < nr_cpu_ids) &&
 		(!per_cpu(cpu_data, next_cpu).txn_addr ||
 		 !cpu_online(next_cpu)))
 		next_cpu++;
 
-	if (next_cpu >= NR_CPUS) 
+	if (next_cpu >= nr_cpu_ids) 
 		next_cpu = 0;	/* nothing else, assign monarch */
 
 	return txn_affinity_addr(virt_irq, next_cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/Makefile linux-libre-2.6.30-gnu1/arch/parisc/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -11,10 +11,25 @@ obj-y	     	:= cache.o pacache.o setup.o
 		   process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
 		   topology.o
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_cache.o = -pg
+CFLAGS_REMOVE_irq.o = -pg
+CFLAGS_REMOVE_pacache.o = -pg
+CFLAGS_REMOVE_perf.o = -pg
+CFLAGS_REMOVE_traps.o = -pg
+CFLAGS_REMOVE_unaligned.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
+endif
+
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_PA11)	+= pci-dma.o
 obj-$(CONFIG_PCI)	+= pci.o
 obj-$(CONFIG_MODULES)	+= module.o
 obj-$(CONFIG_64BIT)	+= binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_STACKTRACE)+= stacktrace.o
 # only supported for PCX-W/U in 64-bit mode at the moment
 obj-$(CONFIG_64BIT)	+= perf.o perf_asm.o
+obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/module.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/module.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/module.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,9 +61,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
-#include <linux/uaccess.h>
 
-#include <asm/sections.h>
 #include <asm/unwind.h>
 
 #if 0
@@ -115,8 +113,6 @@ struct got_entry {
 	Elf32_Addr addr;
 };
 
-#define Elf_Fdesc	Elf32_Fdesc
-
 struct stub_entry {
 	Elf32_Word insns[2]; /* each stub entry has two insns */
 };
@@ -125,8 +121,6 @@ struct got_entry {
 	Elf64_Addr addr;
 };
 
-#define Elf_Fdesc	Elf64_Fdesc
-
 struct stub_entry {
 	Elf64_Word insns[4]; /* each stub entry has four insns */
 };
@@ -916,15 +910,3 @@ void module_arch_cleanup(struct module *
 	deregister_unwind_table(mod);
 	module_bug_cleanup(mod);
 }
-
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
-	Elf64_Fdesc *desc = ptr;
-	void *p;
-
-	if (!probe_kernel_address(&desc->addr, p))
-		ptr = p;
-	return ptr;
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/parisc_ksyms.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/parisc_ksyms.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/parisc_ksyms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/parisc_ksyms.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,5 +153,10 @@ EXPORT_SYMBOL(node_data);
 EXPORT_SYMBOL(pfnnid_map);
 #endif
 
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
+
 /* from pacache.S -- needed for copy_page */
 EXPORT_SYMBOL(copy_user_page_asm);
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/process.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,14 +46,15 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/kallsyms.h>
+#include <linux/uaccess.h>
 
 #include <asm/io.h>
 #include <asm/asm-offsets.h>
 #include <asm/pdc.h>
 #include <asm/pdc_chassis.h>
 #include <asm/pgalloc.h>
-#include <asm/uaccess.h>
 #include <asm/unwind.h>
+#include <asm/sections.h>
 
 /*
  * The idle thread. There's no useful work to be
@@ -231,8 +232,8 @@ sys_clone(unsigned long clone_flags, uns
 	   
 	   However, these last 3 args are only examined
 	   if the proper flags are set. */
-	int __user *child_tidptr;
-	int __user *parent_tidptr;
+	int __user *parent_tidptr = (int __user *)regs->gr[24];
+	int __user *child_tidptr  = (int __user *)regs->gr[22];
 
 	/* usp must be word aligned.  This also prevents users from
 	 * passing in the value 1 (which is the signal for a special
@@ -243,16 +244,6 @@ sys_clone(unsigned long clone_flags, uns
 	if (usp == 0)
 	  usp = regs->gr[30];
 
-	if (clone_flags & CLONE_PARENT_SETTID)
-	  parent_tidptr = (int __user *)regs->gr[24];
-	else
-	  parent_tidptr = NULL;
-	
-	if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
-	  child_tidptr = (int __user *)regs->gr[22];
-	else
-	  child_tidptr = NULL;
-
 	return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
 }
 
@@ -263,7 +254,7 @@ sys_vfork(struct pt_regs *regs)
 }
 
 int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
 	    unsigned long unused,	/* in ia64 this is "user_stack_size" */
 	    struct task_struct * p, struct pt_regs * pregs)
 {
@@ -400,3 +391,15 @@ get_wchan(struct task_struct *p)
 	} while (count++ < 16);
 	return 0;
 }
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+	Elf64_Fdesc *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->addr, p))
+		ptr = p;
+	return ptr;
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/processor.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/processor.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/processor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/processor.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,8 +100,8 @@ static int __cpuinit processor_probe(str
 	struct cpuinfo_parisc *p;
 
 #ifdef CONFIG_SMP
-	if (num_online_cpus() >= NR_CPUS) {
-		printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+	if (num_online_cpus() >= nr_cpu_ids) {
+		printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n");
 		return 1;
 	}
 #else
@@ -214,7 +214,7 @@ static int __cpuinit processor_probe(str
 	 */
 #ifdef CONFIG_SMP
 	if (cpuid) {
-		cpu_set(cpuid, cpu_present_map);
+		set_cpu_present(cpuid, true);
 		cpu_up(cpuid);
 	}
 #endif
@@ -364,6 +364,13 @@ show_cpuinfo (struct seq_file *m, void *
 				 boot_cpu_data.cpu_hz / 1000000,
 				 boot_cpu_data.cpu_hz % 1000000  );
 
+		seq_printf(m, "capabilities\t:");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
+			seq_printf(m, " os32");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
+			seq_printf(m, " os64");
+		seq_printf(m, "\n");
+
 		seq_printf(m, "model\t\t: %s\n"
 				"model name\t: %s\n",
 				 boot_cpu_data.pdc.sys_model_name,
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/smp.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/ftrace.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -113,14 +114,14 @@ halt_processor(void)
 {
 	/* REVISIT : redirect I/O Interrupts to another CPU? */
 	/* REVISIT : does PM *know* this CPU isn't available? */
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 	local_irq_disable();
 	for (;;)
 		;
 }
 
 
-irqreturn_t
+irqreturn_t __irq_entry
 ipi_interrupt(int irq, void *dev_id) 
 {
 	int this_cpu = smp_processor_id();
@@ -214,11 +215,11 @@ ipi_send(int cpu, enum ipi_message_type
 }
 
 static void
-send_IPI_mask(cpumask_t mask, enum ipi_message_type op)
+send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op)
 {
 	int cpu;
 
-	for_each_cpu_mask(cpu, mask)
+	for_each_cpu(cpu, mask)
 		ipi_send(cpu, op);
 }
 
@@ -257,7 +258,7 @@ smp_send_all_nop(void)
 	send_IPI_allbutself(IPI_NOP);
 }
 
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	send_IPI_mask(mask, IPI_CALL_FUNC);
 }
@@ -296,13 +297,14 @@ smp_cpu_init(int cpunum)
 	mb();
 
 	/* Well, support 2.4 linux scheme as well. */
-	if (cpu_test_and_set(cpunum, cpu_online_map))
+	if (cpu_isset(cpunum, cpu_online_map))
 	{
 		extern void machine_halt(void); /* arch/parisc.../process.c */
 
 		printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
 		machine_halt();
 	}  
+	set_cpu_online(cpunum, true);
 
 	/* Initialise the idle task for this CPU */
 	atomic_inc(&init_mm.mm_count);
@@ -424,8 +426,8 @@ void __init smp_prepare_boot_cpu(void)
 	/* Setup BSP mappings */
 	printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
 
-	cpu_set(bootstrap_processor, cpu_online_map);
-	cpu_set(bootstrap_processor, cpu_present_map);
+	set_cpu_online(bootstrap_processor, true);
+	set_cpu_present(bootstrap_processor, true);
 }
 
 
@@ -436,8 +438,7 @@ void __init smp_prepare_boot_cpu(void)
 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-	cpus_clear(cpu_present_map);
-	cpu_set(0, cpu_present_map);
+	init_cpu_present(cpumask_of(0));
 
 	parisc_max_cpus = max_cpus;
 	if (!max_cpus)
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/stacktrace.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/stacktrace.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/stacktrace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/stacktrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *  based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
+ *  and parisc unwind functions by Randolph Chung <tausq@debian.org>
+ *
+ *  TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
+ */
+#include <linux/module.h>
+#include <linux/stacktrace.h>
+
+#include <asm/unwind.h>
+
+static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+{
+	struct unwind_frame_info info;
+
+	/* initialize unwind info */
+	if (task == current) {
+		unsigned long sp;
+		struct pt_regs r;
+HERE:
+		asm volatile ("copy %%r30, %0" : "=r"(sp));
+		memset(&r, 0, sizeof(struct pt_regs));
+		r.iaoq[0] = (unsigned long)&&HERE;
+		r.gr[2] = (unsigned long)__builtin_return_address(0);
+		r.gr[30] = sp;
+		unwind_frame_init(&info, task, &r);
+	} else {
+		unwind_frame_init_from_blocked_task(&info, task);
+	}
+
+	/* unwind stack and save entries in stack_trace struct */
+	trace->nr_entries = 0;
+	while (trace->nr_entries < trace->max_entries) {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			break;
+
+		if (__kernel_text_address(info.ip))
+			trace->entries[trace->nr_entries++] = info.ip;
+	}
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+	dump_trace(current, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+	dump_trace(tsk, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/syscall.S linux-libre-2.6.30-gnu1/arch/parisc/kernel/syscall.S
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/syscall.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/syscall.S	2009-06-09 23:05:27.000000000 -0400
@@ -365,17 +365,51 @@ tracesys_sigexit:
 
 
 	/*********************************************************
-		Light-weight-syscall code
+		32/64-bit Light-Weight-Syscall ABI
 
-		r20 - lws number
-		r26,r25,r24,r23,r22 - Input registers
-		r28 - Function return register
-		r21 - Error code.
+		* - Indicates a hint for userspace inline asm
+		implementations.
 
-		Scracth: Any of the above that aren't being
-		currently used, including r1. 
+		Syscall number (caller-saves)
+	        - %r20
+	        * In asm clobber.
 
-		Return pointer: r31 (Not usable)
+		Argument registers (caller-saves)
+	        - %r26, %r25, %r24, %r23, %r22
+	        * In asm input.
+
+		Return registers (caller-saves)
+	        - %r28 (return), %r21 (errno)
+	        * In asm output.
+
+		Caller-saves registers
+	        - %r1, %r27, %r29
+	        - %r2 (return pointer)
+	        - %r31 (ble link register)
+	        * In asm clobber.
+
+		Callee-saves registers
+	        - %r3-%r18
+	        - %r30 (stack pointer)
+	        * Not in asm clobber.
+
+		If userspace is 32-bit:
+		Callee-saves registers
+	        - %r19 (32-bit PIC register)
+
+		Differences from 32-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r19.
+
+		If userspace is 64-bit:
+		Callee-saves registers
+		- %r27 (64-bit PIC register)
+
+		Differences from 64-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r27.
 
 		Error codes returned by entry path:
 
@@ -473,7 +507,8 @@ lws_compare_and_swap64:
 	b,n	lws_compare_and_swap
 #else
 	/* If we are not a 64-bit kernel, then we don't
-	 * implement having 64-bit input registers
+	 * have 64-bit input registers, and calling
+	 * the 64-bit LWS CAS returns ENOSYS.
 	 */
 	b,n	lws_exit_nosys
 #endif
@@ -635,12 +670,15 @@ END(sys_call_table64)
 	/*
 		All light-weight-syscall atomic operations 
 		will use this set of locks 
+
+		NOTE: The lws_lock_start symbol must be
+		at least 16-byte aligned for safe use
+		with ldcw.
 	*/
 	.section .data
 	.align	PAGE_SIZE
 ENTRY(lws_lock_start)
 	/* lws locks */
-	.align 16
 	.rept 16
 	/* Keep locks aligned at 16-bytes */
 	.word 1
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/syscall_table.S linux-libre-2.6.30-gnu1/arch/parisc/kernel/syscall_table.S
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/syscall_table.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/syscall_table.S	2009-06-09 23:05:27.000000000 -0400
@@ -130,7 +130,7 @@
 	ENTRY_OURS(newuname)
 	ENTRY_SAME(umask)		/* 60 */
 	ENTRY_SAME(chroot)
-	ENTRY_SAME(ustat)
+	ENTRY_COMP(ustat)
 	ENTRY_SAME(dup2)
 	ENTRY_SAME(getppid)
 	ENTRY_SAME(getpgrp)		/* 65 */
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/time.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/profile.h>
 #include <linux/clocksource.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -53,7 +54,7 @@ static unsigned long clocktick __read_mo
  * held off for an arbitrarily long period of time by interrupts being
  * disabled, so we may miss one or more ticks.
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
 {
 	unsigned long now;
 	unsigned long next_tick;
@@ -216,17 +217,14 @@ void __init start_cpu_itimer(void)
 	per_cpu(cpu_data, cpu).it_value = next_tick;
 }
 
-struct platform_device rtc_parisc_dev = {
-	.name = "rtc-parisc",
+static struct platform_device rtc_generic_dev = {
+	.name = "rtc-generic",
 	.id = -1,
 };
 
 static int __init rtc_init(void)
 {
-	int ret;
-
-	ret = platform_device_register(&rtc_parisc_dev);
-	if (ret < 0)
+	if (platform_device_register(&rtc_generic_dev) < 0)
 		printk(KERN_ERR "unable to register rtc device...\n");
 
 	/* not necessarily an error */
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/traps.c linux-libre-2.6.30-gnu1/arch/parisc/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -247,6 +247,8 @@ void die_if_kernel(char *str, struct pt_
 
 	oops_in_progress = 1;
 
+	oops_enter();
+
 	/* Amuse the user in a SPARC fashion */
 	if (err) printk(
 KERN_CRIT "      _______________________________ \n"
@@ -293,6 +295,7 @@ KERN_CRIT "                     ||     |
 		panic("Fatal exception");
 	}
 
+	oops_exit();
 	do_exit(SIGSEGV);
 }
 
@@ -494,7 +497,7 @@ void parisc_terminate(char *msg, struct
 	panic(msg);
 }
 
-void handle_interruption(int code, struct pt_regs *regs)
+void notrace handle_interruption(int code, struct pt_regs *regs)
 {
 	unsigned long fault_address = 0;
 	unsigned long fault_space = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/parisc/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/parisc/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -54,6 +54,8 @@ SECTIONS
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
+		KPROBES_TEXT
+		IRQENTRY_TEXT
 		*(.text.do_softirq)
 		*(.text.sys_exit)
 		*(.text.do_sigaltstack)
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/Makefile linux-libre-2.6.30-gnu1/arch/parisc/Makefile
--- linux-libre-2.6.29-gnu1/arch/parisc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -56,7 +56,9 @@ cflags-y	+= -mdisable-fpregs
 
 # Without this, "ld -r" results in .text sections that are too big
 # (> 0x40000) for branches to reach stubs.
-cflags-y	+= -ffunction-sections
+ifndef CONFIG_FUNCTION_TRACER
+  cflags-y	+= -ffunction-sections
+endif
 
 # select which processor to optimise for
 cflags-$(CONFIG_PA7100)		+= -march=1.1 -mschedule=7100
diff -druNp linux-libre-2.6.29-gnu1/arch/parisc/mm/init.c linux-libre-2.6.30-gnu1/arch/parisc/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/parisc/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/parisc/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -456,6 +456,13 @@ void __init mem_init(void)
 {
 	int codesize, reservedpages, datasize, initsize;
 
+	/* Do sanity checks on page table constants */
+	BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
+	BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
+	BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t));
+	BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD
+			> BITS_PER_LONG);
+
 	high_memory = __va((max_pfn << PAGE_SHIFT));
 
 #ifndef CONFIG_DISCONTIGMEM
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/4xx.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/4xx.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/4xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/4xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,21 +158,33 @@ void ibm440spe_fixup_memsize(void)
 
 #define DDR_GET_VAL(val, mask, shift)	(((val) >> (shift)) & (mask))
 
-void ibm4xx_denali_fixup_memsize(void)
+/*
+ * Some U-Boot versions set the number of chipselects to two
+ * for Sequoia/Rainier boards while they only have one chipselect
+ * hardwired. Hardcode the number of chipselects to one
+ * for sequioa/rainer board models or read the actual value
+ * from the memory controller register DDR0_10 otherwise.
+ */
+static inline u32 ibm4xx_denali_get_cs(void)
 {
-	u32 val, max_cs, max_col, max_row;
-	u32 cs, col, row, bank, dpath;
-	unsigned long memsize;
+	void *devp;
+	char model[64];
+	u32 val, cs;
 
-	val = SDRAM0_READ(DDR0_02);
-	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
-		fatal("DDR controller is not initialized\n");
+	devp = finddevice("/");
+	if (!devp)
+		goto read_cs;
 
-	/* get maximum cs col and row values */
-	max_cs  = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT);
-	max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT);
-	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
+	if (getprop(devp, "model", model, sizeof(model)) <= 0)
+		goto read_cs;
+
+	model[sizeof(model)-1] = 0;
 
+	if (!strcmp(model, "amcc,sequoia") ||
+	    !strcmp(model, "amcc,rainier"))
+		return 1;
+
+read_cs:
 	/* get CS value */
 	val = SDRAM0_READ(DDR0_10);
 
@@ -183,7 +195,25 @@ void ibm4xx_denali_fixup_memsize(void)
 			cs++;
 		val = val >> 1;
 	}
+	return cs;
+}
+
+void ibm4xx_denali_fixup_memsize(void)
+{
+	u32 val, max_cs, max_col, max_row;
+	u32 cs, col, row, bank, dpath;
+	unsigned long memsize;
 
+	val = SDRAM0_READ(DDR0_02);
+	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
+		fatal("DDR controller is not initialized\n");
+
+	/* get maximum cs col and row values */
+	max_cs  = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT);
+	max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT);
+	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
+
+	cs = ibm4xx_denali_get_cs();
 	if (!cs)
 		fatal("No memory installed\n");
 	if (cs > max_cs)
@@ -193,9 +223,9 @@ void ibm4xx_denali_fixup_memsize(void)
 	val = SDRAM0_READ(DDR0_14);
 
 	if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT))
-		dpath = 8; /* 64 bits */
-	else
 		dpath = 4; /* 32 bits */
+	else
+		dpath = 8; /* 64 bits */
 
 	/* get address pins (rows) */
  	val = SDRAM0_READ(DDR0_42);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/cuboot-amigaone.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/cuboot-amigaone.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/cuboot-amigaone.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/cuboot-amigaone.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * Old U-boot compatibility for AmigaOne
+ *
+ * Author: Gerhard Pircher (gerhard_pircher@gmx.net)
+ *
+ *   Based on cuboot-83xx.c
+ * Copyright (c) 2007 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 "ops.h"
+#include "stdio.h"
+#include "cuboot.h"
+
+#include "ppcboot.h"
+
+static bd_t bd;
+
+static void platform_fixups(void)
+{
+	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+	dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+                   unsigned long r6, unsigned long r7)
+{
+	CUBOOT_INIT();
+	fdt_init(_dtb_start);
+	serial_console_init();
+	platform_ops.fixups = platform_fixups;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/checks.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/checks.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/checks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/checks.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,587 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2007.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU 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 "dtc.h"
-
-#ifdef TRACE_CHECKS
-#define TRACE(c, ...) \
-	do { \
-		fprintf(stderr, "=== %s: ", (c)->name); \
-		fprintf(stderr, __VA_ARGS__); \
-		fprintf(stderr, "\n"); \
-	} while (0)
-#else
-#define TRACE(c, fmt, ...)	do { } while (0)
-#endif
-
-enum checklevel {
-	IGNORE = 0,
-	WARN = 1,
-	ERROR = 2,
-};
-
-enum checkstatus {
-	UNCHECKED = 0,
-	PREREQ,
-	PASSED,
-	FAILED,
-};
-
-struct check;
-
-typedef void (*tree_check_fn)(struct check *c, struct node *dt);
-typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
-typedef void (*prop_check_fn)(struct check *c, struct node *dt,
-			      struct node *node, struct property *prop);
-
-struct check {
-	const char *name;
-	tree_check_fn tree_fn;
-	node_check_fn node_fn;
-	prop_check_fn prop_fn;
-	void *data;
-	enum checklevel level;
-	enum checkstatus status;
-	int inprogress;
-	int num_prereqs;
-	struct check **prereq;
-};
-
-#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
-	static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
-	static struct check nm = { \
-		.name = #nm, \
-		.tree_fn = (tfn), \
-		.node_fn = (nfn), \
-		.prop_fn = (pfn), \
-		.data = (d), \
-		.level = (lvl), \
-		.status = UNCHECKED, \
-		.num_prereqs = ARRAY_SIZE(nm##_prereqs), \
-		.prereq = nm##_prereqs, \
-	};
-
-#define TREE_CHECK(nm, d, lvl, ...) \
-	CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
-#define NODE_CHECK(nm, d, lvl, ...) \
-	CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
-#define PROP_CHECK(nm, d, lvl, ...) \
-	CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
-#define BATCH_CHECK(nm, lvl, ...) \
-	CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
-
-#ifdef __GNUC__
-static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
-#endif
-static inline void check_msg(struct check *c, const char *fmt, ...)
-{
-	va_list ap;
-	va_start(ap, fmt);
-
-	if ((c->level < WARN) || (c->level <= quiet))
-		return; /* Suppress message */
-
-	fprintf(stderr, "%s (%s): ",
-		(c->level == ERROR) ? "ERROR" : "Warning", c->name);
-	vfprintf(stderr, fmt, ap);
-	fprintf(stderr, "\n");
-}
-
-#define FAIL(c, ...) \
-	do { \
-		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
-		(c)->status = FAILED; \
-		check_msg((c), __VA_ARGS__); \
-	} while (0)
-
-static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
-{
-	struct node *child;
-	struct property *prop;
-
-	TRACE(c, "%s", node->fullpath);
-	if (c->node_fn)
-		c->node_fn(c, dt, node);
-
-	if (c->prop_fn)
-		for_each_property(node, prop) {
-			TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
-			c->prop_fn(c, dt, node, prop);
-		}
-
-	for_each_child(node, child)
-		check_nodes_props(c, dt, child);
-}
-
-static int run_check(struct check *c, struct node *dt)
-{
-	int error = 0;
-	int i;
-
-	assert(!c->inprogress);
-
-	if (c->status != UNCHECKED)
-		goto out;
-
-	c->inprogress = 1;
-
-	for (i = 0; i < c->num_prereqs; i++) {
-		struct check *prq = c->prereq[i];
-		error |= run_check(prq, dt);
-		if (prq->status != PASSED) {
-			c->status = PREREQ;
-			check_msg(c, "Failed prerequisite '%s'",
-				  c->prereq[i]->name);
-		}
-	}
-
-	if (c->status != UNCHECKED)
-		goto out;
-
-	if (c->node_fn || c->prop_fn)
-		check_nodes_props(c, dt, dt);
-
-	if (c->tree_fn)
-		c->tree_fn(c, dt);
-	if (c->status == UNCHECKED)
-		c->status = PASSED;
-
-	TRACE(c, "\tCompleted, status %d", c->status);
-
-out:
-	c->inprogress = 0;
-	if ((c->status != PASSED) && (c->level == ERROR))
-		error = 1;
-	return error;
-}
-
-/*
- * Utility check functions
- */
-
-static void check_is_string(struct check *c, struct node *root,
-			    struct node *node)
-{
-	struct property *prop;
-	char *propname = c->data;
-
-	prop = get_property(node, propname);
-	if (!prop)
-		return; /* Not present, assumed ok */
-
-	if (!data_is_one_string(prop->val))
-		FAIL(c, "\"%s\" property in %s is not a string",
-		     propname, node->fullpath);
-}
-#define CHECK_IS_STRING(nm, propname, lvl) \
-	CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
-
-static void check_is_cell(struct check *c, struct node *root,
-			  struct node *node)
-{
-	struct property *prop;
-	char *propname = c->data;
-
-	prop = get_property(node, propname);
-	if (!prop)
-		return; /* Not present, assumed ok */
-
-	if (prop->val.len != sizeof(cell_t))
-		FAIL(c, "\"%s\" property in %s is not a single cell",
-		     propname, node->fullpath);
-}
-#define CHECK_IS_CELL(nm, propname, lvl) \
-	CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
-
-/*
- * Structural check functions
- */
-
-static void check_duplicate_node_names(struct check *c, struct node *dt,
-				       struct node *node)
-{
-	struct node *child, *child2;
-
-	for_each_child(node, child)
-		for (child2 = child->next_sibling;
-		     child2;
-		     child2 = child2->next_sibling)
-			if (streq(child->name, child2->name))
-				FAIL(c, "Duplicate node name %s",
-				     child->fullpath);
-}
-NODE_CHECK(duplicate_node_names, NULL, ERROR);
-
-static void check_duplicate_property_names(struct check *c, struct node *dt,
-					   struct node *node)
-{
-	struct property *prop, *prop2;
-
-	for_each_property(node, prop)
-		for (prop2 = prop->next; prop2; prop2 = prop2->next)
-			if (streq(prop->name, prop2->name))
-				FAIL(c, "Duplicate property name %s in %s",
-				     prop->name, node->fullpath);
-}
-NODE_CHECK(duplicate_property_names, NULL, ERROR);
-
-#define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
-#define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-#define DIGITS		"0123456789"
-#define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
-
-static void check_node_name_chars(struct check *c, struct node *dt,
-				  struct node *node)
-{
-	int n = strspn(node->name, c->data);
-
-	if (n < strlen(node->name))
-		FAIL(c, "Bad character '%c' in node %s",
-		     node->name[n], node->fullpath);
-}
-NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
-
-static void check_node_name_format(struct check *c, struct node *dt,
-				   struct node *node)
-{
-	if (strchr(get_unitname(node), '@'))
-		FAIL(c, "Node %s has multiple '@' characters in name",
-		     node->fullpath);
-}
-NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
-
-static void check_property_name_chars(struct check *c, struct node *dt,
-				      struct node *node, struct property *prop)
-{
-	int n = strspn(prop->name, c->data);
-
-	if (n < strlen(prop->name))
-		FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
-		     prop->name[n], prop->name, node->fullpath);
-}
-PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
-
-static void check_explicit_phandles(struct check *c, struct node *root,
-					  struct node *node)
-{
-	struct property *prop;
-	struct node *other;
-	cell_t phandle;
-
-	prop = get_property(node, "linux,phandle");
-	if (! prop)
-		return; /* No phandle, that's fine */
-
-	if (prop->val.len != sizeof(cell_t)) {
-		FAIL(c, "%s has bad length (%d) linux,phandle property",
-		     node->fullpath, prop->val.len);
-		return;
-	}
-
-	phandle = propval_cell(prop);
-	if ((phandle == 0) || (phandle == -1)) {
-		FAIL(c, "%s has invalid linux,phandle value 0x%x",
-		     node->fullpath, phandle);
-		return;
-	}
-
-	other = get_node_by_phandle(root, phandle);
-	if (other) {
-		FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
-		     node->fullpath, phandle, other->fullpath);
-		return;
-	}
-
-	node->phandle = phandle;
-}
-NODE_CHECK(explicit_phandles, NULL, ERROR);
-
-static void check_name_properties(struct check *c, struct node *root,
-				  struct node *node)
-{
-	struct property **pp, *prop = NULL;
-
-	for (pp = &node->proplist; *pp; pp = &((*pp)->next))
-		if (streq((*pp)->name, "name")) {
-			prop = *pp;
-			break;
-		}
-
-	if (!prop)
-		return; /* No name property, that's fine */
-
-	if ((prop->val.len != node->basenamelen+1)
-	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
-		FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
-		     " of base node name)", node->fullpath, prop->val.val);
-	} else {
-		/* The name property is correct, and therefore redundant.
-		 * Delete it */
-		*pp = prop->next;
-		free(prop->name);
-		data_free(prop->val);
-		free(prop);
-	}
-}
-CHECK_IS_STRING(name_is_string, "name", ERROR);
-NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
-
-/*
- * Reference fixup functions
- */
-
-static void fixup_phandle_references(struct check *c, struct node *dt,
-				     struct node *node, struct property *prop)
-{
-	struct marker *m = prop->val.markers;
-	struct node *refnode;
-	cell_t phandle;
-
-	for_each_marker_of_type(m, REF_PHANDLE) {
-		assert(m->offset + sizeof(cell_t) <= prop->val.len);
-
-		refnode = get_node_by_ref(dt, m->ref);
-		if (! refnode) {
-			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-			     m->ref);
-			continue;
-		}
-
-		phandle = get_node_phandle(dt, refnode);
-		*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
-	}
-}
-CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
-      &duplicate_node_names, &explicit_phandles);
-
-static void fixup_path_references(struct check *c, struct node *dt,
-				  struct node *node, struct property *prop)
-{
-	struct marker *m = prop->val.markers;
-	struct node *refnode;
-	char *path;
-
-	for_each_marker_of_type(m, REF_PATH) {
-		assert(m->offset <= prop->val.len);
-
-		refnode = get_node_by_ref(dt, m->ref);
-		if (!refnode) {
-			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-			     m->ref);
-			continue;
-		}
-
-		path = refnode->fullpath;
-		prop->val = data_insert_at_marker(prop->val, m, path,
-						  strlen(path) + 1);
-	}
-}
-CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
-      &duplicate_node_names);
-
-/*
- * Semantic checks
- */
-CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
-CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
-CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
-
-CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
-CHECK_IS_STRING(model_is_string, "model", WARN);
-CHECK_IS_STRING(status_is_string, "status", WARN);
-
-static void fixup_addr_size_cells(struct check *c, struct node *dt,
-				  struct node *node)
-{
-	struct property *prop;
-
-	node->addr_cells = -1;
-	node->size_cells = -1;
-
-	prop = get_property(node, "#address-cells");
-	if (prop)
-		node->addr_cells = propval_cell(prop);
-
-	prop = get_property(node, "#size-cells");
-	if (prop)
-		node->size_cells = propval_cell(prop);
-}
-CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
-      &address_cells_is_cell, &size_cells_is_cell);
-
-#define node_addr_cells(n) \
-	(((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
-#define node_size_cells(n) \
-	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
-
-static void check_reg_format(struct check *c, struct node *dt,
-			     struct node *node)
-{
-	struct property *prop;
-	int addr_cells, size_cells, entrylen;
-
-	prop = get_property(node, "reg");
-	if (!prop)
-		return; /* No "reg", that's fine */
-
-	if (!node->parent) {
-		FAIL(c, "Root node has a \"reg\" property");
-		return;
-	}
-
-	if (prop->val.len == 0)
-		FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
-
-	addr_cells = node_addr_cells(node->parent);
-	size_cells = node_size_cells(node->parent);
-	entrylen = (addr_cells + size_cells) * sizeof(cell_t);
-
-	if ((prop->val.len % entrylen) != 0)
-		FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
-		     "(#address-cells == %d, #size-cells == %d)",
-		     node->fullpath, prop->val.len, addr_cells, size_cells);
-}
-NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
-
-static void check_ranges_format(struct check *c, struct node *dt,
-				struct node *node)
-{
-	struct property *prop;
-	int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
-
-	prop = get_property(node, "ranges");
-	if (!prop)
-		return;
-
-	if (!node->parent) {
-		FAIL(c, "Root node has a \"ranges\" property");
-		return;
-	}
-
-	p_addr_cells = node_addr_cells(node->parent);
-	p_size_cells = node_size_cells(node->parent);
-	c_addr_cells = node_addr_cells(node);
-	c_size_cells = node_size_cells(node);
-	entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
-
-	if (prop->val.len == 0) {
-		if (p_addr_cells != c_addr_cells)
-			FAIL(c, "%s has empty \"ranges\" property but its "
-			     "#address-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_addr_cells, node->parent->fullpath,
-			     p_addr_cells);
-		if (p_size_cells != c_size_cells)
-			FAIL(c, "%s has empty \"ranges\" property but its "
-			     "#size-cells (%d) differs from %s (%d)",
-			     node->fullpath, c_size_cells, node->parent->fullpath,
-			     p_size_cells);
-	} else if ((prop->val.len % entrylen) != 0) {
-		FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
-		     "(parent #address-cells == %d, child #address-cells == %d, "
-		     "#size-cells == %d)", node->fullpath, prop->val.len,
-		     p_addr_cells, c_addr_cells, c_size_cells);
-	}
-}
-NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
-
-/*
- * Style checks
- */
-static void check_avoid_default_addr_size(struct check *c, struct node *dt,
-					  struct node *node)
-{
-	struct property *reg, *ranges;
-
-	if (!node->parent)
-		return; /* Ignore root node */
-
-	reg = get_property(node, "reg");
-	ranges = get_property(node, "ranges");
-
-	if (!reg && !ranges)
-		return;
-
-	if ((node->parent->addr_cells == -1))
-		FAIL(c, "Relying on default #address-cells value for %s",
-		     node->fullpath);
-
-	if ((node->parent->size_cells == -1))
-		FAIL(c, "Relying on default #size-cells value for %s",
-		     node->fullpath);
-}
-NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
-
-static void check_obsolete_chosen_interrupt_controller(struct check *c,
-						       struct node *dt)
-{
-	struct node *chosen;
-	struct property *prop;
-
-	chosen = get_node_by_path(dt, "/chosen");
-	if (!chosen)
-		return;
-
-	prop = get_property(chosen, "interrupt-controller");
-	if (prop)
-		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
-		     "property");
-}
-TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
-
-static struct check *check_table[] = {
-	&duplicate_node_names, &duplicate_property_names,
-	&node_name_chars, &node_name_format, &property_name_chars,
-	&name_is_string, &name_properties,
-	&explicit_phandles,
-	&phandle_references, &path_references,
-
-	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
-	&device_type_is_string, &model_is_string, &status_is_string,
-
-	&addr_size_cells, &reg_format, &ranges_format,
-
-	&avoid_default_addr_size,
-	&obsolete_chosen_interrupt_controller,
-};
-
-void process_checks(int force, struct boot_info *bi)
-{
-	struct node *dt = bi->dt;
-	int i;
-	int error = 0;
-
-	for (i = 0; i < ARRAY_SIZE(check_table); i++) {
-		struct check *c = check_table[i];
-
-		if (c->level != IGNORE)
-			error = error || run_check(c, dt);
-	}
-
-	if (error) {
-		if (!force) {
-			fprintf(stderr, "ERROR: Input tree has errors, aborting "
-				"(use -f to force output)\n");
-			exit(2);
-		} else if (quiet < 3) {
-			fprintf(stderr, "Warning: Input tree has errors, "
-				"output forced\n");
-		}
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/data.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/data.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/data.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,321 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-
-void data_free(struct data d)
-{
-	struct marker *m, *nm;
-
-	m = d.markers;
-	while (m) {
-		nm = m->next;
-		free(m->ref);
-		free(m);
-		m = nm;
-	}
-
-	if (d.val)
-		free(d.val);
-}
-
-struct data data_grow_for(struct data d, int xlen)
-{
-	struct data nd;
-	int newsize;
-
-	if (xlen == 0)
-		return d;
-
-	nd = d;
-
-	newsize = xlen;
-
-	while ((d.len + xlen) > newsize)
-		newsize *= 2;
-
-	nd.val = xrealloc(d.val, newsize);
-
-	return nd;
-}
-
-struct data data_copy_mem(const char *mem, int len)
-{
-	struct data d;
-
-	d = data_grow_for(empty_data, len);
-
-	d.len = len;
-	memcpy(d.val, mem, len);
-
-	return d;
-}
-
-static char get_oct_char(const char *s, int *i)
-{
-	char x[4];
-	char *endx;
-	long val;
-
-	x[3] = '\0';
-	strncpy(x, s + *i, 3);
-
-	val = strtol(x, &endx, 8);
-
-	assert(endx > x);
-
-	(*i) += endx - x;
-	return val;
-}
-
-static char get_hex_char(const char *s, int *i)
-{
-	char x[3];
-	char *endx;
-	long val;
-
-	x[2] = '\0';
-	strncpy(x, s + *i, 2);
-
-	val = strtol(x, &endx, 16);
-	if (!(endx  > x))
-		die("\\x used with no following hex digits\n");
-
-	(*i) += endx - x;
-	return val;
-}
-
-struct data data_copy_escape_string(const char *s, int len)
-{
-	int i = 0;
-	struct data d;
-	char *q;
-
-	d = data_grow_for(empty_data, strlen(s)+1);
-
-	q = d.val;
-	while (i < len) {
-		char c = s[i++];
-
-		if (c != '\\') {
-			q[d.len++] = c;
-			continue;
-		}
-
-		c = s[i++];
-		assert(c);
-		switch (c) {
-		case 'a':
-			q[d.len++] = '\a';
-			break;
-		case 'b':
-			q[d.len++] = '\b';
-			break;
-		case 't':
-			q[d.len++] = '\t';
-			break;
-		case 'n':
-			q[d.len++] = '\n';
-			break;
-		case 'v':
-			q[d.len++] = '\v';
-			break;
-		case 'f':
-			q[d.len++] = '\f';
-			break;
-		case 'r':
-			q[d.len++] = '\r';
-			break;
-		case '0':
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-		case '5':
-		case '6':
-		case '7':
-			i--; /* need to re-read the first digit as
-			      * part of the octal value */
-			q[d.len++] = get_oct_char(s, &i);
-			break;
-		case 'x':
-			q[d.len++] = get_hex_char(s, &i);
-			break;
-		default:
-			q[d.len++] = c;
-		}
-	}
-
-	q[d.len++] = '\0';
-	return d;
-}
-
-struct data data_copy_file(FILE *f, size_t maxlen)
-{
-	struct data d = empty_data;
-
-	while (!feof(f) && (d.len < maxlen)) {
-		size_t chunksize, ret;
-
-		if (maxlen == -1)
-			chunksize = 4096;
-		else
-			chunksize = maxlen - d.len;
-
-		d = data_grow_for(d, chunksize);
-		ret = fread(d.val + d.len, 1, chunksize, f);
-
-		if (ferror(f))
-			die("Error reading file into data: %s", strerror(errno));
-
-		if (d.len + ret < d.len)
-			die("Overflow reading file into data\n");
-
-		d.len += ret;
-	}
-
-	return d;
-}
-
-struct data data_append_data(struct data d, const void *p, int len)
-{
-	d = data_grow_for(d, len);
-	memcpy(d.val + d.len, p, len);
-	d.len += len;
-	return d;
-}
-
-struct data data_insert_at_marker(struct data d, struct marker *m,
-				  const void *p, int len)
-{
-	d = data_grow_for(d, len);
-	memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
-	memcpy(d.val + m->offset, p, len);
-	d.len += len;
-
-	/* Adjust all markers after the one we're inserting at */
-	m = m->next;
-	for_each_marker(m)
-		m->offset += len;
-	return d;
-}
-
-struct data data_append_markers(struct data d, struct marker *m)
-{
-	struct marker **mp = &d.markers;
-
-	/* Find the end of the markerlist */
-	while (*mp)
-		mp = &((*mp)->next);
-	*mp = m;
-	return d;
-}
-
-struct data data_merge(struct data d1, struct data d2)
-{
-	struct data d;
-	struct marker *m2 = d2.markers;
-
-	d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
-
-	/* Adjust for the length of d1 */
-	for_each_marker(m2)
-		m2->offset += d1.len;
-
-	d2.markers = NULL; /* So data_free() doesn't clobber them */
-	data_free(d2);
-
-	return d;
-}
-
-struct data data_append_cell(struct data d, cell_t word)
-{
-	cell_t beword = cpu_to_fdt32(word);
-
-	return data_append_data(d, &beword, sizeof(beword));
-}
-
-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
-{
-	struct fdt_reserve_entry bere;
-
-	bere.address = cpu_to_fdt64(re->address);
-	bere.size = cpu_to_fdt64(re->size);
-
-	return data_append_data(d, &bere, sizeof(bere));
-}
-
-struct data data_append_addr(struct data d, uint64_t addr)
-{
-	uint64_t beaddr = cpu_to_fdt64(addr);
-
-	return data_append_data(d, &beaddr, sizeof(beaddr));
-}
-
-struct data data_append_byte(struct data d, uint8_t byte)
-{
-	return data_append_data(d, &byte, 1);
-}
-
-struct data data_append_zeroes(struct data d, int len)
-{
-	d = data_grow_for(d, len);
-
-	memset(d.val + d.len, 0, len);
-	d.len += len;
-	return d;
-}
-
-struct data data_append_align(struct data d, int align)
-{
-	int newlen = ALIGN(d.len, align);
-	return data_append_zeroes(d, newlen - d.len);
-}
-
-struct data data_add_marker(struct data d, enum markertype type, char *ref)
-{
-	struct marker *m;
-
-	m = xmalloc(sizeof(*m));
-	m->offset = d.len;
-	m->type = type;
-	m->ref = ref;
-	m->next = NULL;
-
-	return data_append_markers(d, m);
-}
-
-int data_is_one_string(struct data d)
-{
-	int i;
-	int len = d.len;
-
-	if (len == 0)
-		return 0;
-
-	for (i = 0; i < len-1; i++)
-		if (d.val[i] == '\0')
-			return 0;
-
-	if (d.val[len-1] != '\0')
-		return 0;
-
-	return 1;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,226 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-#include "srcpos.h"
-
-#include "version_gen.h"
-
-/*
- * Command line options
- */
-int quiet;		/* Level of quietness */
-int reservenum;		/* Number of memory reservation slots */
-int minsize;		/* Minimum blob size */
-int padsize;		/* Additional padding to blob */
-
-char *join_path(const char *path, const char *name)
-{
-	int lenp = strlen(path);
-	int lenn = strlen(name);
-	int len;
-	int needslash = 1;
-	char *str;
-
-	len = lenp + lenn + 2;
-	if ((lenp > 0) && (path[lenp-1] == '/')) {
-		needslash = 0;
-		len--;
-	}
-
-	str = xmalloc(len);
-	memcpy(str, path, lenp);
-	if (needslash) {
-		str[lenp] = '/';
-		lenp++;
-	}
-	memcpy(str+lenp, name, lenn+1);
-	return str;
-}
-
-static void fill_fullpaths(struct node *tree, const char *prefix)
-{
-	struct node *child;
-	const char *unit;
-
-	tree->fullpath = join_path(prefix, tree->name);
-
-	unit = strchr(tree->name, '@');
-	if (unit)
-		tree->basenamelen = unit - tree->name;
-	else
-		tree->basenamelen = strlen(tree->name);
-
-	for_each_child(tree, child)
-		fill_fullpaths(child, tree->fullpath);
-}
-
-static void  __attribute__ ((noreturn)) usage(void)
-{
-	fprintf(stderr, "Usage:\n");
-	fprintf(stderr, "\tdtc [options] <input file>\n");
-	fprintf(stderr, "\nOptions:\n");
-	fprintf(stderr, "\t-h\n");
-	fprintf(stderr, "\t\tThis help text\n");
-	fprintf(stderr, "\t-q\n");
-	fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n");
-	fprintf(stderr, "\t-I <input format>\n");
-	fprintf(stderr, "\t\tInput formats are:\n");
-	fprintf(stderr, "\t\t\tdts - device tree source text\n");
-	fprintf(stderr, "\t\t\tdtb - device tree blob\n");
-	fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
-	fprintf(stderr, "\t-o <output file>\n");
-	fprintf(stderr, "\t-O <output format>\n");
-	fprintf(stderr, "\t\tOutput formats are:\n");
-	fprintf(stderr, "\t\t\tdts - device tree source text\n");
-	fprintf(stderr, "\t\t\tdtb - device tree blob\n");
-	fprintf(stderr, "\t\t\tasm - assembler source\n");
-	fprintf(stderr, "\t-V <output version>\n");
-	fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
-	fprintf(stderr, "\t-R <number>\n");
-	fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
-	fprintf(stderr, "\t-S <bytes>\n");
-	fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n");
-	fprintf(stderr, "\t-p <bytes>\n");
-	fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n");
-	fprintf(stderr, "\t-b <number>\n");
-	fprintf(stderr, "\t\tSet the physical boot cpu\n");
-	fprintf(stderr, "\t-f\n");
-	fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
-	fprintf(stderr, "\t-v\n");
-	fprintf(stderr, "\t\tPrint DTC version and exit\n");
-	exit(3);
-}
-
-int main(int argc, char *argv[])
-{
-	struct boot_info *bi;
-	const char *inform = "dts";
-	const char *outform = "dts";
-	const char *outname = "-";
-	int force = 0, check = 0;
-	const char *arg;
-	int opt;
-	FILE *outf = NULL;
-	int outversion = DEFAULT_FDT_VERSION;
-	long long cmdline_boot_cpuid = -1;
-
-	quiet      = 0;
-	reservenum = 0;
-	minsize    = 0;
-	padsize    = 0;
-
-	while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
-		switch (opt) {
-		case 'I':
-			inform = optarg;
-			break;
-		case 'O':
-			outform = optarg;
-			break;
-		case 'o':
-			outname = optarg;
-			break;
-		case 'V':
-			outversion = strtol(optarg, NULL, 0);
-			break;
-		case 'R':
-			reservenum = strtol(optarg, NULL, 0);
-			break;
-		case 'S':
-			minsize = strtol(optarg, NULL, 0);
-			break;
-		case 'p':
-			padsize = strtol(optarg, NULL, 0);
-			break;
-		case 'f':
-			force = 1;
-			break;
-		case 'c':
-			check = 1;
-			break;
-		case 'q':
-			quiet++;
-			break;
-		case 'b':
-			cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
-			break;
-		case 'v':
-			printf("Version: %s\n", DTC_VERSION);
-			exit(0);
-		case 'h':
-		default:
-			usage();
-		}
-	}
-
-	if (argc > (optind+1))
-		usage();
-	else if (argc < (optind+1))
-		arg = "-";
-	else
-		arg = argv[optind];
-
-	/* minsize and padsize are mutually exclusive */
-	if (minsize && padsize)
-		die("Can't set both -p and -S\n");
-
-	fprintf(stderr, "DTC: %s->%s  on file \"%s\"\n",
-		inform, outform, arg);
-
-	if (streq(inform, "dts"))
-		bi = dt_from_source(arg);
-	else if (streq(inform, "fs"))
-		bi = dt_from_fs(arg);
-	else if(streq(inform, "dtb"))
-		bi = dt_from_blob(arg);
-	else
-		die("Unknown input format \"%s\"\n", inform);
-
-	if (cmdline_boot_cpuid != -1)
-		bi->boot_cpuid_phys = cmdline_boot_cpuid;
-
-	fill_fullpaths(bi->dt, "");
-	process_checks(force, bi);
-
-
-	if (streq(outname, "-")) {
-		outf = stdout;
-	} else {
-		outf = fopen(outname, "w");
-		if (! outf)
-			die("Couldn't open output file %s: %s\n",
-			    outname, strerror(errno));
-	}
-
-	if (streq(outform, "dts")) {
-		dt_to_source(outf, bi);
-	} else if (streq(outform, "dtb")) {
-		dt_to_blob(outf, bi, outversion);
-	} else if (streq(outform, "asm")) {
-		dt_to_asm(outf, bi, outversion);
-	} else if (streq(outform, "null")) {
-		/* do nothing */
-	} else {
-		die("Unknown output format \"%s\"\n", outform);
-	}
-
-	exit(0);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,246 +0,0 @@
-#ifndef _DTC_H
-#define _DTC_H
-
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <libfdt_env.h>
-#include <fdt.h>
-
-#define DEFAULT_FDT_VERSION	17
-/*
- * Command line options
- */
-extern int quiet;		/* Level of quietness */
-extern int reservenum;		/* Number of memory reservation slots */
-extern int minsize;		/* Minimum blob size */
-extern int padsize;		/* Additional padding to blob */
-
-static inline void __attribute__((noreturn)) die(char * str, ...)
-{
-	va_list ap;
-
-	va_start(ap, str);
-	fprintf(stderr, "FATAL ERROR: ");
-	vfprintf(stderr, str, ap);
-	exit(1);
-}
-
-static inline void *xmalloc(size_t len)
-{
-	void *new = malloc(len);
-
-	if (! new)
-		die("malloc() failed\n");
-
-	return new;
-}
-
-static inline void *xrealloc(void *p, size_t len)
-{
-	void *new = realloc(p, len);
-
-	if (! new)
-		die("realloc() failed (len=%d)\n", len);
-
-	return new;
-}
-
-typedef uint32_t cell_t;
-
-
-#define streq(a, b)	(strcmp((a), (b)) == 0)
-#define strneq(a, b, n)	(strncmp((a), (b), (n)) == 0)
-
-#define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-/* Data blobs */
-enum markertype {
-	REF_PHANDLE,
-	REF_PATH,
-	LABEL,
-};
-
-struct  marker {
-	enum markertype type;
-	int offset;
-	char *ref;
-	struct marker *next;
-};
-
-struct data {
-	int len;
-	char *val;
-	struct marker *markers;
-};
-
-
-#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
-
-#define for_each_marker(m) \
-	for (; (m); (m) = (m)->next)
-#define for_each_marker_of_type(m, t) \
-	for_each_marker(m) \
-		if ((m)->type == (t))
-
-void data_free(struct data d);
-
-struct data data_grow_for(struct data d, int xlen);
-
-struct data data_copy_mem(const char *mem, int len);
-struct data data_copy_escape_string(const char *s, int len);
-struct data data_copy_file(FILE *f, size_t len);
-
-struct data data_append_data(struct data d, const void *p, int len);
-struct data data_insert_at_marker(struct data d, struct marker *m,
-				  const void *p, int len);
-struct data data_merge(struct data d1, struct data d2);
-struct data data_append_cell(struct data d, cell_t word);
-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
-struct data data_append_addr(struct data d, uint64_t addr);
-struct data data_append_byte(struct data d, uint8_t byte);
-struct data data_append_zeroes(struct data d, int len);
-struct data data_append_align(struct data d, int align);
-
-struct data data_add_marker(struct data d, enum markertype type, char *ref);
-
-int data_is_one_string(struct data d);
-
-/* DT constraints */
-
-#define MAX_PROPNAME_LEN	31
-#define MAX_NODENAME_LEN	31
-
-/* Live trees */
-struct property {
-	char *name;
-	struct data val;
-
-	struct property *next;
-
-	char *label;
-};
-
-struct node {
-	char *name;
-	struct property *proplist;
-	struct node *children;
-
-	struct node *parent;
-	struct node *next_sibling;
-
-	char *fullpath;
-	int basenamelen;
-
-	cell_t phandle;
-	int addr_cells, size_cells;
-
-	char *label;
-};
-
-#define for_each_property(n, p) \
-	for ((p) = (n)->proplist; (p); (p) = (p)->next)
-
-#define for_each_child(n, c)	\
-	for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
-
-struct property *build_property(char *name, struct data val, char *label);
-struct property *chain_property(struct property *first, struct property *list);
-struct property *reverse_properties(struct property *first);
-
-struct node *build_node(struct property *proplist, struct node *children);
-struct node *name_node(struct node *node, char *name, char *label);
-struct node *chain_node(struct node *first, struct node *list);
-
-void add_property(struct node *node, struct property *prop);
-void add_child(struct node *parent, struct node *child);
-
-const char *get_unitname(struct node *node);
-struct property *get_property(struct node *node, const char *propname);
-cell_t propval_cell(struct property *prop);
-struct node *get_subnode(struct node *node, const char *nodename);
-struct node *get_node_by_path(struct node *tree, const char *path);
-struct node *get_node_by_label(struct node *tree, const char *label);
-struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
-struct node *get_node_by_ref(struct node *tree, const char *ref);
-cell_t get_node_phandle(struct node *root, struct node *node);
-
-/* Boot info (tree plus memreserve information */
-
-struct reserve_info {
-	struct fdt_reserve_entry re;
-
-	struct reserve_info *next;
-
-	char *label;
-};
-
-struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
-struct reserve_info *chain_reserve_entry(struct reserve_info *first,
-					 struct reserve_info *list);
-struct reserve_info *add_reserve_entry(struct reserve_info *list,
-				       struct reserve_info *new);
-
-
-struct boot_info {
-	struct reserve_info *reservelist;
-	struct node *dt;		/* the device tree */
-	uint32_t boot_cpuid_phys;
-};
-
-struct boot_info *build_boot_info(struct reserve_info *reservelist,
-				  struct node *tree, uint32_t boot_cpuid_phys);
-
-/* Checks */
-
-void process_checks(int force, struct boot_info *bi);
-
-/* Flattened trees */
-
-void dt_to_blob(FILE *f, struct boot_info *bi, int version);
-void dt_to_asm(FILE *f, struct boot_info *bi, int version);
-
-struct boot_info *dt_from_blob(const char *fname);
-
-/* Tree source */
-
-void dt_to_source(FILE *f, struct boot_info *bi);
-struct boot_info *dt_from_source(const char *f);
-
-/* FS trees */
-
-struct boot_info *dt_from_fs(const char *dirname);
-
-/* misc */
-
-char *join_path(const char *path, const char *name);
-
-#endif /* _DTC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.l linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.l
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.l	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.l	1969-12-31 19:00:00.000000000 -0500
@@ -1,320 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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
- */
-
-%option noyywrap nounput yylineno
-
-%x INCLUDE
-%x BYTESTRING
-%x PROPNODENAME
-%s V1
-
-PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
-PATHCHAR	({PROPNODECHAR}|[/])
-LABEL		[a-zA-Z_][a-zA-Z0-9_]*
-STRING		\"([^\\"]|\\.)*\"
-WS		[[:space:]]
-COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
-LINECOMMENT	"//".*\n
-
-%{
-#include "dtc.h"
-#include "srcpos.h"
-#include "dtc-parser.tab.h"
-
-
-/*#define LEXDEBUG	1*/
-
-#ifdef LEXDEBUG
-#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
-#else
-#define DPRINT(fmt, ...)	do { } while (0)
-#endif
-
-static int dts_version; /* = 0 */
-
-#define BEGIN_DEFAULT()	if (dts_version == 0) { \
-				DPRINT("<INITIAL>\n"); \
-				BEGIN(INITIAL); \
-			} else { \
-				DPRINT("<V1>\n"); \
-				BEGIN(V1); \
-			}
-
-static void push_input_file(const char *filename);
-static int pop_input_file(void);
-%}
-
-%%
-<*>"/include/"{WS}*{STRING} {
-			char *name = strchr(yytext, '\"') + 1;
-			yytext[yyleng-1] = '\0';
-			push_input_file(name);
-		}
-
-<*><<EOF>>		{
-			if (!pop_input_file()) {
-				yyterminate();
-			}
-		}
-
-<*>{STRING}	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("String: %s\n", yytext);
-			yylval.data = data_copy_escape_string(yytext+1,
-					yyleng-2);
-			yylloc.first_line = yylineno;
-			return DT_STRING;
-		}
-
-<*>"/dts-v1/"	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Keyword: /dts-v1/\n");
-			dts_version = 1;
-			BEGIN_DEFAULT();
-			return DT_V1;
-		}
-
-<*>"/memreserve/"	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Keyword: /memreserve/\n");
-			BEGIN_DEFAULT();
-			return DT_MEMRESERVE;
-		}
-
-<*>{LABEL}:	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Label: %s\n", yytext);
-			yylval.labelref = strdup(yytext);
-			yylval.labelref[yyleng-1] = '\0';
-			return DT_LABEL;
-		}
-
-<INITIAL>[bodh]# {
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			if (*yytext == 'b')
-				yylval.cbase = 2;
-			else if (*yytext == 'o')
-				yylval.cbase = 8;
-			else if (*yytext == 'd')
-				yylval.cbase = 10;
-			else
-				yylval.cbase = 16;
-			DPRINT("Base: %d\n", yylval.cbase);
-			return DT_BASE;
-		}
-
-<INITIAL>[0-9a-fA-F]+	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
-			DPRINT("Literal: '%s'\n", yylval.literal);
-			return DT_LEGACYLITERAL;
-		}
-
-<V1>[0-9]+|0[xX][0-9a-fA-F]+      {
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
-			DPRINT("Literal: '%s'\n", yylval.literal);
-			return DT_LITERAL;
-		}
-
-\&{LABEL}	{	/* label reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
-			return DT_REF;
-		}
-
-"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yytext[yyleng-1] = '\0';
-			DPRINT("Ref: %s\n", yytext+2);
-			yylval.labelref = strdup(yytext+2);
-			return DT_REF;
-		}
-
-<INITIAL>"&/"{PATHCHAR}+ {	/* old-style path reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
-			return DT_REF;
-		}
-
-<BYTESTRING>[0-9a-fA-F]{2} {
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.byte = strtol(yytext, NULL, 16);
-			DPRINT("Byte: %02x\n", (int)yylval.byte);
-			return DT_BYTE;
-		}
-
-<BYTESTRING>"]"	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("/BYTESTRING\n");
-			BEGIN_DEFAULT();
-			return ']';
-		}
-
-<PROPNODENAME>{PROPNODECHAR}+ {
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("PropNodeName: %s\n", yytext);
-			yylval.propnodename = strdup(yytext);
-			BEGIN_DEFAULT();
-			return DT_PROPNODENAME;
-		}
-
-"/incbin/"	{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Binary Include\n");
-			return DT_INCBIN;
-		}
-
-<*>{WS}+	/* eat whitespace */
-<*>{COMMENT}+	/* eat C-style comments */
-<*>{LINECOMMENT}+ /* eat C++-style comments */
-
-<*>.		{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
-				(unsigned)yytext[0]);
-			if (yytext[0] == '[') {
-				DPRINT("<BYTESTRING>\n");
-				BEGIN(BYTESTRING);
-			}
-			if ((yytext[0] == '{')
-			    || (yytext[0] == ';')) {
-				DPRINT("<PROPNODENAME>\n");
-				BEGIN(PROPNODENAME);
-			}
-			return yytext[0];
-		}
-
-%%
-
-
-/*
- * Stack of nested include file contexts.
- */
-
-struct incl_file {
-	struct dtc_file *file;
-	YY_BUFFER_STATE yy_prev_buf;
-	int yy_prev_lineno;
-	struct incl_file *prev;
-};
-
-static struct incl_file *incl_file_stack;
-
-
-/*
- * Detect infinite include recursion.
- */
-#define MAX_INCLUDE_DEPTH	(100)
-
-static int incl_depth = 0;
-
-
-static void push_input_file(const char *filename)
-{
-	struct incl_file *incl_file;
-	struct dtc_file *newfile;
-	struct search_path search, *searchptr = NULL;
-
-	assert(filename);
-
-	if (incl_depth++ >= MAX_INCLUDE_DEPTH)
-		die("Includes nested too deeply");
-
-	if (srcpos_file) {
-		search.dir = srcpos_file->dir;
-		search.next = NULL;
-		search.prev = NULL;
-		searchptr = &search;
-	}
-
-	newfile = dtc_open_file(filename, searchptr);
-
-	incl_file = xmalloc(sizeof(struct incl_file));
-
-	/*
-	 * Save current context.
-	 */
-	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
-	incl_file->yy_prev_lineno = yylineno;
-	incl_file->file = srcpos_file;
-	incl_file->prev = incl_file_stack;
-
-	incl_file_stack = incl_file;
-
-	/*
-	 * Establish new context.
-	 */
-	srcpos_file = newfile;
-	yylineno = 1;
-	yyin = newfile->file;
-	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-}
-
-
-static int pop_input_file(void)
-{
-	struct incl_file *incl_file;
-
-	if (incl_file_stack == 0)
-		return 0;
-
-	dtc_close_file(srcpos_file);
-
-	/*
-	 * Pop.
-	 */
-	--incl_depth;
-	incl_file = incl_file_stack;
-	incl_file_stack = incl_file->prev;
-
-	/*
-	 * Recover old context.
-	 */
-	yy_delete_buffer(YY_CURRENT_BUFFER);
-	yy_switch_to_buffer(incl_file->yy_prev_buf);
-	yylineno = incl_file->yy_prev_lineno;
-	srcpos_file = incl_file->file;
-	yyin = incl_file->file ? incl_file->file->file : NULL;
-
-	/*
-	 * Free old state.
-	 */
-	free(incl_file);
-
-	return 1;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped	1969-12-31 19:00:00.000000000 -0500
@@ -1,2187 +0,0 @@
-#line 2 "dtc-lexer.lex.c"
-
-#line 4 "dtc-lexer.lex.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 34
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
-     *       access to the local variable yy_act. Since yyless() is a macro, it would break
-     *       existing scanners that call yyless() from OUTSIDE yylex. 
-     *       One obvious solution it to make yy_act a global. I tried that, and saw
-     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
-     *       normally declared as a register variable-- so it is not worth it.
-     */
-    #define  YY_LESS_LINENO(n) \
-            do { \
-                int yyl;\
-                for ( yyl = n; yyl < yyleng; ++yyl )\
-                    if ( yytext[yyl] == '\n' )\
-                        --yylineno;\
-            }while(0)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		*yy_cp = (yy_hold_char); \
-		YY_RESTORE_YY_MORE_OFFSET \
-		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-		} \
-	while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- * Given that the standard has decreed that size_t exists since 1989,
- * I guess we can afford to depend on it. Manoj.
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	yy_size_t yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-	/* When an EOF's been seen but there's still some text to process
-	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-	 * shouldn't try reading from the input source any more.  We might
-	 * still have a bunch of tokens to match, though, because of
-	 * possible backing-up.
-	 *
-	 * When we actually see the EOF, we change the status to "new"
-	 * (via yyrestart()), so that the user can continue scanning by
-	 * just pointing yyin at a new input file.
-	 */
-#define YY_BUFFER_EOF_PENDING 2
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;		/* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0;		/* whether we need to initialize */
-static int yy_start = 0;	/* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-	}
-
-#define yy_set_bol(at_bol) \
-	{ \
-	if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-	} \
-	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-	}
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-	(yytext_ptr) = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
-	(yy_hold_char) = *yy_cp; \
-	*yy_cp = '\0'; \
-	(yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 20
-#define YY_END_OF_BUFFER 21
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-	{
-	flex_int32_t yy_verify;
-	flex_int32_t yy_nxt;
-	};
-static yyconst flex_int16_t yy_accept[104] =
-    {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       21,   19,   16,   16,   19,   19,   19,    7,    7,   19,
-        7,   19,   19,   19,   19,   13,   14,   14,   19,    8,
-        8,   16,    0,    2,    0,    0,    9,    0,    0,    0,
-        0,    0,    0,    7,    7,    5,    0,    6,    0,   12,
-       12,   14,   14,    8,    0,   11,    9,    0,    0,    0,
-        0,   18,    0,    0,    0,    0,    8,    0,   17,    0,
-        0,    0,    0,    0,   10,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    3,   15,
-        0,    0,    0,    0,    0,    0,    0,    0,    1,    0,
-
-        0,    4,    0
-    } ;
-
-static yyconst flex_int32_t yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    5,    1,    1,    6,    1,    1,
-        1,    7,    8,    8,    9,    8,   10,   11,   12,   13,
-       13,   13,   13,   13,   13,   13,   13,   14,    1,    1,
-        1,    1,    8,    8,   15,   15,   15,   15,   15,   15,
-       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,
-       16,   16,   16,   16,   16,   16,   16,   17,   16,   16,
-        1,   18,   19,    1,   16,    1,   15,   20,   21,   22,
-
-       23,   15,   16,   24,   25,   16,   16,   26,   27,   28,
-       24,   16,   16,   29,   30,   31,   32,   33,   16,   17,
-       16,   16,   34,    1,   35,    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,    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,    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,    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,    1,    1
-    } ;
-
-static yyconst flex_int32_t yy_meta[36] =
-    {   0,
-        1,    1,    1,    1,    2,    1,    2,    2,    2,    3,
-        4,    4,    4,    5,    6,    7,    7,    1,    1,    6,
-        6,    6,    6,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    8,    1
-    } ;
-
-static yyconst flex_int16_t yy_base[117] =
-    {   0,
-        0,    0,   30,    0,   44,    0,   67,    0,   97,  105,
-      302,  303,   35,   44,   40,   94,  112,    0,  129,  152,
-      296,  295,  159,    0,  176,  303,    0,  116,   95,  165,
-       49,   46,  102,  303,  296,    0,    0,  288,  290,  293,
-      264,  266,  270,    0,    0,  303,    0,  303,  264,  303,
-        0,    0,  195,  101,    0,    0,    0,    0,  284,  125,
-      277,  265,  225,  230,  216,  218,    0,  202,  224,  221,
-      217,  107,  196,  188,  303,  206,  179,  186,  178,  185,
-      183,  162,  161,  150,  169,  160,  145,  125,  303,  303,
-      137,  109,  190,  103,  203,  167,  108,  197,  303,  123,
-
-       29,  303,  303,  215,  221,  226,  229,  234,  240,  246,
-      250,  257,  265,  270,  275,  282
-    } ;
-
-static yyconst flex_int16_t yy_def[117] =
-    {   0,
-      103,    1,    1,    3,    3,    5,  103,    7,    3,    3,
-      103,  103,  103,  103,  104,  105,  103,  106,  103,   19,
-       19,   20,  103,  107,   20,  103,  108,  109,  105,  103,
-      103,  103,  104,  103,  104,  110,  111,  103,  112,  113,
-      103,  103,  103,  106,   19,  103,   20,  103,  103,  103,
-       20,  108,  109,  103,  114,  110,  111,  115,  112,  112,
-      113,  103,  103,  103,  103,  103,  114,  115,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  116,  103,  116,  103,  116,
-
-      103,  103,    0,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103
-    } ;
-
-static yyconst flex_int16_t yy_nxt[339] =
-    {   0,
-       12,   13,   14,   15,   12,   16,   12,   12,   12,   17,
-       18,   18,   18,   12,   19,   20,   20,   12,   12,   21,
-       19,   21,   19,   22,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   12,   12,   12,   32,   32,  102,   23,
-       12,   12,   12,   34,   20,   32,   32,   32,   32,   20,
-       20,   20,   20,   20,   24,   24,   24,   35,   25,   54,
-       54,   54,   26,   25,   25,   25,   25,   12,   13,   14,
-       15,   27,   12,   27,   27,   27,   23,   27,   27,   27,
-       12,   28,   28,   28,   12,   12,   28,   28,   28,   28,
-       28,   28,   28,   28,   28,   28,   28,   28,   28,   28,
-
-       12,   12,   29,   36,  103,   34,   17,   30,   31,   31,
-       29,   54,   54,   54,   17,   30,   31,   31,   39,   35,
-       52,   40,   52,   52,   52,  103,   78,   38,   38,   46,
-      101,   60,   79,   41,   69,   97,   42,   94,   43,   45,
-       45,   45,   46,   45,   47,   47,   93,   92,   45,   45,
-       45,   45,   47,   47,   47,   47,   47,   47,   47,   47,
-       47,   47,   47,   47,   47,   39,   47,   91,   40,   90,
-       99,   47,   47,   47,   47,   54,   54,   54,   89,   88,
-       41,   55,   87,   49,  100,   43,   51,   51,   51,   86,
-       51,   95,   95,   96,   85,   51,   51,   51,   51,   52,
-
-       99,   52,   52,   52,   95,   95,   96,   84,   46,   83,
-       82,   81,   39,   79,  100,   33,   33,   33,   33,   33,
-       33,   33,   33,   37,   80,   77,   37,   37,   37,   44,
-       40,   44,   50,   76,   50,   52,   75,   52,   74,   52,
-       52,   53,   73,   53,   53,   53,   53,   56,   56,   56,
-       72,   56,   56,   57,   71,   57,   57,   59,   59,   59,
-       59,   59,   59,   59,   59,   61,   61,   61,   61,   61,
-       61,   61,   61,   67,   70,   67,   68,   68,   68,   62,
-       68,   68,   98,   98,   98,   98,   98,   98,   98,   98,
-       60,   66,   65,   64,   63,   62,   60,   58,  103,   48,
-
-       48,  103,   11,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103
-    } ;
-
-static yyconst flex_int16_t yy_chk[339] =
-    {   0,
-        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,    1,    1,    1,    3,   13,   13,  101,    3,
-        3,    3,    3,   15,    3,   14,   14,   32,   32,    3,
-        3,    3,    3,    3,    5,    5,    5,   15,    5,   31,
-       31,   31,    5,    5,    5,    5,    5,    7,    7,    7,
-        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-
-        7,    7,    9,   16,   29,   33,    9,    9,    9,    9,
-       10,   54,   54,   54,   10,   10,   10,   10,   17,   33,
-       28,   17,   28,   28,   28,  100,   72,   16,   29,   28,
-       97,   60,   72,   17,   60,   94,   17,   92,   17,   19,
-       19,   19,   19,   19,   19,   19,   91,   88,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   20,   20,   20,   23,   20,   87,   23,   86,
-       96,   20,   20,   20,   20,   30,   30,   30,   85,   84,
-       23,   30,   83,   23,   96,   23,   25,   25,   25,   82,
-       25,   93,   93,   93,   81,   25,   25,   25,   25,   53,
-
-       98,   53,   53,   53,   95,   95,   95,   80,   53,   79,
-       78,   77,   76,   74,   98,  104,  104,  104,  104,  104,
-      104,  104,  104,  105,   73,   71,  105,  105,  105,  106,
-       70,  106,  107,   69,  107,  108,   68,  108,   66,  108,
-      108,  109,   65,  109,  109,  109,  109,  110,  110,  110,
-       64,  110,  110,  111,   63,  111,  111,  112,  112,  112,
-      112,  112,  112,  112,  112,  113,  113,  113,  113,  113,
-      113,  113,  113,  114,   62,  114,  115,  115,  115,   61,
-      115,  115,  116,  116,  116,  116,  116,  116,  116,  116,
-       59,   49,   43,   42,   41,   40,   39,   38,   35,   22,
-
-       21,   11,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103
-    } ;
-
-/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[21] =
-    {   0,
-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 
-    0,     };
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "dtc-lexer.l"
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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
- */
-
-
-
-
-#line 37 "dtc-lexer.l"
-#include "dtc.h"
-#include "srcpos.h"
-#include "dtc-parser.tab.h"
-
-
-/*#define LEXDEBUG	1*/
-
-#ifdef LEXDEBUG
-#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
-#else
-#define DPRINT(fmt, ...)	do { } while (0)
-#endif
-
-static int dts_version; /* = 0 */
-
-#define BEGIN_DEFAULT()	if (dts_version == 0) { \
-				DPRINT("<INITIAL>\n"); \
-				BEGIN(INITIAL); \
-			} else { \
-				DPRINT("<V1>\n"); \
-				BEGIN(V1); \
-			}
-
-static void push_input_file(const char *filename);
-static int pop_input_file(void);
-#line 638 "dtc-lexer.lex.c"
-
-#define INITIAL 0
-#define INCLUDE 1
-#define BYTESTRING 2
-#define PROPNODENAME 3
-#define V1 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-		{ \
-		int c = '*'; \
-		int n; \
-		for ( n = 0; n < max_size && \
-			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-			buf[n] = (char) c; \
-		if ( c == '\n' ) \
-			buf[n++] = (char) c; \
-		if ( c == EOF && ferror( yyin ) ) \
-			YY_FATAL_ERROR( "input in flex scanner failed" ); \
-		result = n; \
-		} \
-	else \
-		{ \
-		errno=0; \
-		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-			{ \
-			if( errno != EINTR) \
-				{ \
-				YY_FATAL_ERROR( "input in flex scanner failed" ); \
-				break; \
-				} \
-			errno=0; \
-			clearerr(yyin); \
-			} \
-		}\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-	YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
-    
-#line 64 "dtc-lexer.l"
-
-#line 795 "dtc-lexer.lex.c"
-
-	if ( !(yy_init) )
-		{
-		(yy_init) = 1;
-
-#ifdef YY_USER_INIT
-		YY_USER_INIT;
-#endif
-
-		if ( ! (yy_start) )
-			(yy_start) = 1;	/* first start state */
-
-		if ( ! yyin )
-			yyin = stdin;
-
-		if ( ! yyout )
-			yyout = stdout;
-
-		if ( ! YY_CURRENT_BUFFER ) {
-			yyensure_buffer_stack ();
-			YY_CURRENT_BUFFER_LVALUE =
-				yy_create_buffer(yyin,YY_BUF_SIZE );
-		}
-
-		yy_load_buffer_state( );
-		}
-
-	while ( 1 )		/* loops until end-of-file is reached */
-		{
-		yy_cp = (yy_c_buf_p);
-
-		/* Support of yytext. */
-		*yy_cp = (yy_hold_char);
-
-		/* yy_bp points to the position in yy_ch_buf of the start of
-		 * the current run.
-		 */
-		yy_bp = yy_cp;
-
-		yy_current_state = (yy_start);
-yy_match:
-		do
-			{
-			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
-			if ( yy_accept[yy_current_state] )
-				{
-				(yy_last_accepting_state) = yy_current_state;
-				(yy_last_accepting_cpos) = yy_cp;
-				}
-			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-				{
-				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 104 )
-					yy_c = yy_meta[(unsigned int) yy_c];
-				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-			++yy_cp;
-			}
-		while ( yy_base[yy_current_state] != 303 );
-
-yy_find_action:
-		yy_act = yy_accept[yy_current_state];
-		if ( yy_act == 0 )
-			{ /* have to back up */
-			yy_cp = (yy_last_accepting_cpos);
-			yy_current_state = (yy_last_accepting_state);
-			yy_act = yy_accept[yy_current_state];
-			}
-
-		YY_DO_BEFORE_ACTION;
-
-		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
-			{
-			int yyl;
-			for ( yyl = 0; yyl < yyleng; ++yyl )
-				if ( yytext[yyl] == '\n' )
-					   
-    yylineno++;
-;
-			}
-
-do_action:	/* This label is used only to access EOF actions. */
-
-		switch ( yy_act )
-	{ /* beginning of action switch */
-			case 0: /* must back up */
-			/* undo the effects of YY_DO_BEFORE_ACTION */
-			*yy_cp = (yy_hold_char);
-			yy_cp = (yy_last_accepting_cpos);
-			yy_current_state = (yy_last_accepting_state);
-			goto yy_find_action;
-
-case 1:
-/* rule 1 can match eol */
-YY_RULE_SETUP
-#line 65 "dtc-lexer.l"
-{
-			char *name = strchr(yytext, '\"') + 1;
-			yytext[yyleng-1] = '\0';
-			push_input_file(name);
-		}
-	YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(INCLUDE):
-case YY_STATE_EOF(BYTESTRING):
-case YY_STATE_EOF(PROPNODENAME):
-case YY_STATE_EOF(V1):
-#line 71 "dtc-lexer.l"
-{
-			if (!pop_input_file()) {
-				yyterminate();
-			}
-		}
-	YY_BREAK
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-#line 77 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("String: %s\n", yytext);
-			yylval.data = data_copy_escape_string(yytext+1,
-					yyleng-2);
-			yylloc.first_line = yylineno;
-			return DT_STRING;
-		}
-	YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 87 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Keyword: /dts-v1/\n");
-			dts_version = 1;
-			BEGIN_DEFAULT();
-			return DT_V1;
-		}
-	YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 96 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Keyword: /memreserve/\n");
-			BEGIN_DEFAULT();
-			return DT_MEMRESERVE;
-		}
-	YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 104 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Label: %s\n", yytext);
-			yylval.labelref = strdup(yytext);
-			yylval.labelref[yyleng-1] = '\0';
-			return DT_LABEL;
-		}
-	YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 113 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			if (*yytext == 'b')
-				yylval.cbase = 2;
-			else if (*yytext == 'o')
-				yylval.cbase = 8;
-			else if (*yytext == 'd')
-				yylval.cbase = 10;
-			else
-				yylval.cbase = 16;
-			DPRINT("Base: %d\n", yylval.cbase);
-			return DT_BASE;
-		}
-	YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 128 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
-			DPRINT("Literal: '%s'\n", yylval.literal);
-			return DT_LEGACYLITERAL;
-		}
-	YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 136 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
-			DPRINT("Literal: '%s'\n", yylval.literal);
-			return DT_LITERAL;
-		}
-	YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 144 "dtc-lexer.l"
-{	/* label reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
-			return DT_REF;
-		}
-	YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 152 "dtc-lexer.l"
-{	/* new-style path reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yytext[yyleng-1] = '\0';
-			DPRINT("Ref: %s\n", yytext+2);
-			yylval.labelref = strdup(yytext+2);
-			return DT_REF;
-		}
-	YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 161 "dtc-lexer.l"
-{	/* old-style path reference */
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
-			return DT_REF;
-		}
-	YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 169 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			yylval.byte = strtol(yytext, NULL, 16);
-			DPRINT("Byte: %02x\n", (int)yylval.byte);
-			return DT_BYTE;
-		}
-	YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 177 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("/BYTESTRING\n");
-			BEGIN_DEFAULT();
-			return ']';
-		}
-	YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 185 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("PropNodeName: %s\n", yytext);
-			yylval.propnodename = strdup(yytext);
-			BEGIN_DEFAULT();
-			return DT_PROPNODENAME;
-		}
-	YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 194 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Binary Include\n");
-			return DT_INCBIN;
-		}
-	YY_BREAK
-case 16:
-/* rule 16 can match eol */
-YY_RULE_SETUP
-#line 201 "dtc-lexer.l"
-/* eat whitespace */
-	YY_BREAK
-case 17:
-/* rule 17 can match eol */
-YY_RULE_SETUP
-#line 202 "dtc-lexer.l"
-/* eat C-style comments */
-	YY_BREAK
-case 18:
-/* rule 18 can match eol */
-YY_RULE_SETUP
-#line 203 "dtc-lexer.l"
-/* eat C++-style comments */
-	YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 205 "dtc-lexer.l"
-{
-			yylloc.file = srcpos_file;
-			yylloc.first_line = yylineno;
-			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
-				(unsigned)yytext[0]);
-			if (yytext[0] == '[') {
-				DPRINT("<BYTESTRING>\n");
-				BEGIN(BYTESTRING);
-			}
-			if ((yytext[0] == '{')
-			    || (yytext[0] == ';')) {
-				DPRINT("<PROPNODENAME>\n");
-				BEGIN(PROPNODENAME);
-			}
-			return yytext[0];
-		}
-	YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 222 "dtc-lexer.l"
-ECHO;
-	YY_BREAK
-#line 1120 "dtc-lexer.lex.c"
-
-	case YY_END_OF_BUFFER:
-		{
-		/* Amount of text matched not including the EOB char. */
-		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-		/* Undo the effects of YY_DO_BEFORE_ACTION. */
-		*yy_cp = (yy_hold_char);
-		YY_RESTORE_YY_MORE_OFFSET
-
-		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-			{
-			/* We're scanning a new file or input source.  It's
-			 * possible that this happened because the user
-			 * just pointed yyin at a new source and called
-			 * yylex().  If so, then we have to assure
-			 * consistency between YY_CURRENT_BUFFER and our
-			 * globals.  Here is the right place to do so, because
-			 * this is the first action (other than possibly a
-			 * back-up) that will match for the new input source.
-			 */
-			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-			}
-
-		/* Note that here we test for yy_c_buf_p "<=" to the position
-		 * of the first EOB in the buffer, since yy_c_buf_p will
-		 * already have been incremented past the NUL character
-		 * (since all states make transitions on EOB to the
-		 * end-of-buffer state).  Contrast this with the test
-		 * in input().
-		 */
-		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			{ /* This was really a NUL. */
-			yy_state_type yy_next_state;
-
-			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-			yy_current_state = yy_get_previous_state(  );
-
-			/* Okay, we're now positioned to make the NUL
-			 * transition.  We couldn't have
-			 * yy_get_previous_state() go ahead and do it
-			 * for us because it doesn't know how to deal
-			 * with the possibility of jamming (and we don't
-			 * want to build jamming into it because then it
-			 * will run more slowly).
-			 */
-
-			yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-			if ( yy_next_state )
-				{
-				/* Consume the NUL. */
-				yy_cp = ++(yy_c_buf_p);
-				yy_current_state = yy_next_state;
-				goto yy_match;
-				}
-
-			else
-				{
-				yy_cp = (yy_c_buf_p);
-				goto yy_find_action;
-				}
-			}
-
-		else switch ( yy_get_next_buffer(  ) )
-			{
-			case EOB_ACT_END_OF_FILE:
-				{
-				(yy_did_buffer_switch_on_eof) = 0;
-
-				if ( yywrap( ) )
-					{
-					/* Note: because we've taken care in
-					 * yy_get_next_buffer() to have set up
-					 * yytext, we can now set up
-					 * yy_c_buf_p so that if some total
-					 * hoser (like flex itself) wants to
-					 * call the scanner after we return the
-					 * YY_NULL, it'll still work - another
-					 * YY_NULL will get returned.
-					 */
-					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-					yy_act = YY_STATE_EOF(YY_START);
-					goto do_action;
-					}
-
-				else
-					{
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-					}
-				break;
-				}
-
-			case EOB_ACT_CONTINUE_SCAN:
-				(yy_c_buf_p) =
-					(yytext_ptr) + yy_amount_of_matched_text;
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_match;
-
-			case EOB_ACT_LAST_MATCH:
-				(yy_c_buf_p) =
-				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-				yy_current_state = yy_get_previous_state(  );
-
-				yy_cp = (yy_c_buf_p);
-				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-				goto yy_find_action;
-			}
-		break;
-		}
-
-	default:
-		YY_FATAL_ERROR(
-			"fatal flex scanner internal error--no action found" );
-	} /* end of action switch */
-		} /* end of scanning one token */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *	EOB_ACT_LAST_MATCH -
- *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *	EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = (yytext_ptr);
-	register int number_to_move, i;
-	int ret_val;
-
-	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-		YY_FATAL_ERROR(
-		"fatal flex scanner internal error--end of buffer missed" );
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-		{ /* Don't try to fill the buffer, so this is an EOF. */
-		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-			{
-			/* We matched a single character, the EOB, so
-			 * treat this as a final EOF.
-			 */
-			return EOB_ACT_END_OF_FILE;
-			}
-
-		else
-			{
-			/* We matched some text prior to the EOB, first
-			 * process it.
-			 */
-			return EOB_ACT_LAST_MATCH;
-			}
-		}
-
-	/* Try to read more data. */
-
-	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
-	for ( i = 0; i < number_to_move; ++i )
-		*(dest++) = *(source++);
-
-	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-		/* don't do the read, it's not guaranteed to return an EOF,
-		 * just force an EOF
-		 */
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-	else
-		{
-			int num_to_read =
-			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-		while ( num_to_read <= 0 )
-			{ /* Not enough room in the buffer - grow it. */
-
-			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
-			int yy_c_buf_p_offset =
-				(int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-			if ( b->yy_is_our_buffer )
-				{
-				int new_size = b->yy_buf_size * 2;
-
-				if ( new_size <= 0 )
-					b->yy_buf_size += b->yy_buf_size / 8;
-				else
-					b->yy_buf_size *= 2;
-
-				b->yy_ch_buf = (char *)
-					/* Include room in for 2 EOB chars. */
-					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
-				}
-			else
-				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
-
-			if ( ! b->yy_ch_buf )
-				YY_FATAL_ERROR(
-				"fatal error - scanner input buffer overflow" );
-
-			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-						number_to_move - 1;
-
-			}
-
-		if ( num_to_read > YY_READ_BUF_SIZE )
-			num_to_read = YY_READ_BUF_SIZE;
-
-		/* Read in more data. */
-		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			(yy_n_chars), (size_t) num_to_read );
-
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	if ( (yy_n_chars) == 0 )
-		{
-		if ( number_to_move == YY_MORE_ADJ )
-			{
-			ret_val = EOB_ACT_END_OF_FILE;
-			yyrestart(yyin  );
-			}
-
-		else
-			{
-			ret_val = EOB_ACT_LAST_MATCH;
-			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-				YY_BUFFER_EOF_PENDING;
-			}
-		}
-
-	else
-		ret_val = EOB_ACT_CONTINUE_SCAN;
-
-	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
-		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-	}
-
-	(yy_n_chars) += number_to_move;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-	return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
-    
-	yy_current_state = (yy_start);
-
-	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-		{
-		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-		if ( yy_accept[yy_current_state] )
-			{
-			(yy_last_accepting_state) = yy_current_state;
-			(yy_last_accepting_cpos) = yy_cp;
-			}
-		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-			{
-			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 104 )
-				yy_c = yy_meta[(unsigned int) yy_c];
-			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-		}
-
-	return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *	next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
-
-	register YY_CHAR yy_c = 1;
-	if ( yy_accept[yy_current_state] )
-		{
-		(yy_last_accepting_state) = yy_current_state;
-		(yy_last_accepting_cpos) = yy_cp;
-		}
-	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-		{
-		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 104 )
-			yy_c = yy_meta[(unsigned int) yy_c];
-		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 103);
-
-	return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-	int c;
-    
-	*(yy_c_buf_p) = (yy_hold_char);
-
-	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-		{
-		/* yy_c_buf_p now points to the character we want to return.
-		 * If this occurs *before* the EOB characters, then it's a
-		 * valid NUL; if not, then we've hit the end of the buffer.
-		 */
-		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-			/* This was really a NUL. */
-			*(yy_c_buf_p) = '\0';
-
-		else
-			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
-			++(yy_c_buf_p);
-
-			switch ( yy_get_next_buffer(  ) )
-				{
-				case EOB_ACT_LAST_MATCH:
-					/* This happens because yy_g_n_b()
-					 * sees that we've accumulated a
-					 * token and flags that we need to
-					 * try matching the token before
-					 * proceeding.  But for input(),
-					 * there's no matching to consider.
-					 * So convert the EOB_ACT_LAST_MATCH
-					 * to EOB_ACT_END_OF_FILE.
-					 */
-
-					/* Reset buffer status. */
-					yyrestart(yyin );
-
-					/*FALLTHROUGH*/
-
-				case EOB_ACT_END_OF_FILE:
-					{
-					if ( yywrap( ) )
-						return EOF;
-
-					if ( ! (yy_did_buffer_switch_on_eof) )
-						YY_NEW_FILE;
-#ifdef __cplusplus
-					return yyinput();
-#else
-					return input();
-#endif
-					}
-
-				case EOB_ACT_CONTINUE_SCAN:
-					(yy_c_buf_p) = (yytext_ptr) + offset;
-					break;
-				}
-			}
-		}
-
-	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
-	*(yy_c_buf_p) = '\0';	/* preserve yytext */
-	(yy_hold_char) = *++(yy_c_buf_p);
-
-	if ( c == '\n' )
-		   
-    yylineno++;
-;
-
-	return c;
-}
-#endif	/* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-	if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-		YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
-	}
-
-	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-	yy_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-	/* TODO. We should be able to replace this entire function body
-	 * with
-	 *		yypop_buffer_state();
-	 *		yypush_buffer_state(new_buffer);
-     */
-	yyensure_buffer_stack ();
-	if ( YY_CURRENT_BUFFER == new_buffer )
-		return;
-
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	yy_load_buffer_state( );
-
-	/* We don't actually know whether we did this switch during
-	 * EOF (yywrap()) processing, but the only time this flag
-	 * is looked at is after yywrap() is called, so it's safe
-	 * to go ahead and always set it.
-	 */
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state  (void)
-{
-    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-	(yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
-	YY_BUFFER_STATE b;
-    
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_buf_size = size;
-
-	/* yy_ch_buf has to be 2 characters longer than the size given because
-	 * we need to put in 2 end-of-buffer characters.
-	 */
-	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
-	if ( ! b->yy_ch_buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-	b->yy_is_our_buffer = 1;
-
-	yy_init_buffer(b,file );
-
-	return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
-	if ( ! b )
-		return;
-
-	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-	if ( b->yy_is_our_buffer )
-		yyfree((void *) b->yy_ch_buf  );
-
-	yyfree((void *) b  );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-	int oerrno = errno;
-    
-	yy_flush_buffer(b );
-
-	b->yy_input_file = file;
-	b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-	errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-    	if ( ! b )
-		return;
-
-	b->yy_n_chars = 0;
-
-	/* We always need two end-of-buffer characters.  The first causes
-	 * a transition to the end-of-buffer state.  The second causes
-	 * a jam in that state.
-	 */
-	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-	b->yy_buf_pos = &b->yy_ch_buf[0];
-
-	b->yy_at_bol = 1;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	if ( b == YY_CURRENT_BUFFER )
-		yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-    	if (new_buffer == NULL)
-		return;
-
-	yyensure_buffer_stack();
-
-	/* This block is copied from yy_switch_to_buffer. */
-	if ( YY_CURRENT_BUFFER )
-		{
-		/* Flush out information for old buffer. */
-		*(yy_c_buf_p) = (yy_hold_char);
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-		}
-
-	/* Only push if top exists. Otherwise, replace top. */
-	if (YY_CURRENT_BUFFER)
-		(yy_buffer_stack_top)++;
-	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-	/* copied from yy_switch_to_buffer. */
-	yy_load_buffer_state( );
-	(yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-    	if (!YY_CURRENT_BUFFER)
-		return;
-
-	yy_delete_buffer(YY_CURRENT_BUFFER );
-	YY_CURRENT_BUFFER_LVALUE = NULL;
-	if ((yy_buffer_stack_top) > 0)
-		--(yy_buffer_stack_top);
-
-	if (YY_CURRENT_BUFFER) {
-		yy_load_buffer_state( );
-		(yy_did_buffer_switch_on_eof) = 1;
-	}
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-	int num_to_alloc;
-    
-	if (!(yy_buffer_stack)) {
-
-		/* First allocation is just for 2 elements, since we don't know if this
-		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
-		 * immediate realloc on the next call.
-         */
-		num_to_alloc = 1;
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-								(num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-								  
-		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
-		(yy_buffer_stack_max) = num_to_alloc;
-		(yy_buffer_stack_top) = 0;
-		return;
-	}
-
-	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
-
-		num_to_alloc = (yy_buffer_stack_max) + grow_size;
-		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-								((yy_buffer_stack),
-								num_to_alloc * sizeof(struct yy_buffer_state*)
-								);
-		if ( ! (yy_buffer_stack) )
-			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-		/* zero only the new slots.*/
-		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-		(yy_buffer_stack_max) = num_to_alloc;
-	}
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
-	YY_BUFFER_STATE b;
-    
-	if ( size < 2 ||
-	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
-	     base[size-1] != YY_END_OF_BUFFER_CHAR )
-		/* They forgot to leave room for the EOB's. */
-		return 0;
-
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
-	if ( ! b )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
-	b->yy_buf_pos = b->yy_ch_buf = base;
-	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
-	b->yy_n_chars = b->yy_buf_size;
-	b->yy_is_interactive = 0;
-	b->yy_at_bol = 1;
-	b->yy_fill_buffer = 0;
-	b->yy_buffer_status = YY_BUFFER_NEW;
-
-	yy_switch_to_buffer(b  );
-
-	return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
-{
-    
-	return yy_scan_bytes(yystr,strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
-{
-	YY_BUFFER_STATE b;
-	char *buf;
-	yy_size_t n;
-	int i;
-    
-	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
-	buf = (char *) yyalloc(n  );
-	if ( ! buf )
-		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-	for ( i = 0; i < _yybytes_len; ++i )
-		buf[i] = yybytes[i];
-
-	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-	b = yy_scan_buffer(buf,n );
-	if ( ! b )
-		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-	/* It's okay to grow etc. this buffer, and we should throw it
-	 * away when we're done.
-	 */
-	b->yy_is_our_buffer = 1;
-
-	return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
-    	(void) fprintf( stderr, "%s\n", msg );
-	exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-	do \
-		{ \
-		/* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-		yytext[yyleng] = (yy_hold_char); \
-		(yy_c_buf_p) = yytext + yyless_macro_arg; \
-		(yy_hold_char) = *(yy_c_buf_p); \
-		*(yy_c_buf_p) = '\0'; \
-		yyleng = yyless_macro_arg; \
-		} \
-	while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-        
-    return yylineno;
-}
-
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
-
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
-
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
-
-/** Get the current token.
- * 
- */
-
-char *yyget_text  (void)
-{
-        return yytext;
-}
-
-/** Set the current line number.
- * @param line_number
- * 
- */
-void yyset_lineno (int  line_number )
-{
-    
-    yylineno = line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str )
-{
-        yyin = in_str ;
-}
-
-void yyset_out (FILE *  out_str )
-{
-        yyout = out_str ;
-}
-
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
-
-void yyset_debug (int  bdebug )
-{
-        yy_flex_debug = bdebug ;
-}
-
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    /* We do not touch yylineno unless the option is enabled. */
-    yylineno =  1;
-    
-    (yy_buffer_stack) = 0;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-	while(YY_CURRENT_BUFFER){
-		yy_delete_buffer(YY_CURRENT_BUFFER  );
-		YY_CURRENT_BUFFER_LVALUE = NULL;
-		yypop_buffer_state();
-	}
-
-	/* Destroy the stack itself. */
-	yyfree((yy_buffer_stack) );
-	(yy_buffer_stack) = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
-	register int i;
-	for ( i = 0; i < n; ++i )
-		s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
-	register int n;
-	for ( n = 0; s[n]; ++n )
-		;
-
-	return n;
-}
-#endif
-
-void *yyalloc (yy_size_t  size )
-{
-	return (void *) malloc( size );
-}
-
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
-	/* The cast to (char *) in the following accommodates both
-	 * implementations that use char* generic pointers, and those
-	 * that use void* generic pointers.  It works with the latter
-	 * because both ANSI C and C++ allow castless assignment from
-	 * any pointer type to void*, and deal with argument conversions
-	 * as though doing an assignment.
-	 */
-	return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
-	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 222 "dtc-lexer.l"
-
-
-
-
-/*
- * Stack of nested include file contexts.
- */
-
-struct incl_file {
-	struct dtc_file *file;
-	YY_BUFFER_STATE yy_prev_buf;
-	int yy_prev_lineno;
-	struct incl_file *prev;
-};
-
-static struct incl_file *incl_file_stack;
-
-
-/*
- * Detect infinite include recursion.
- */
-#define MAX_INCLUDE_DEPTH	(100)
-
-static int incl_depth = 0;
-
-
-static void push_input_file(const char *filename)
-{
-	struct incl_file *incl_file;
-	struct dtc_file *newfile;
-	struct search_path search, *searchptr = NULL;
-
-	assert(filename);
-
-	if (incl_depth++ >= MAX_INCLUDE_DEPTH)
-		die("Includes nested too deeply");
-
-	if (srcpos_file) {
-		search.dir = srcpos_file->dir;
-		search.next = NULL;
-		search.prev = NULL;
-		searchptr = &search;
-	}
-
-	newfile = dtc_open_file(filename, searchptr);
-
-	incl_file = xmalloc(sizeof(struct incl_file));
-
-	/*
-	 * Save current context.
-	 */
-	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
-	incl_file->yy_prev_lineno = yylineno;
-	incl_file->file = srcpos_file;
-	incl_file->prev = incl_file_stack;
-
-	incl_file_stack = incl_file;
-
-	/*
-	 * Establish new context.
-	 */
-	srcpos_file = newfile;
-	yylineno = 1;
-	yyin = newfile->file;
-	yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
-}
-
-
-static int pop_input_file(void)
-{
-	struct incl_file *incl_file;
-
-	if (incl_file_stack == 0)
-		return 0;
-
-	dtc_close_file(srcpos_file);
-
-	/*
-	 * Pop.
-	 */
-	--incl_depth;
-	incl_file = incl_file_stack;
-	incl_file_stack = incl_file->prev;
-
-	/*
-	 * Recover old context.
-	 */
-	yy_delete_buffer(YY_CURRENT_BUFFER);
-	yy_switch_to_buffer(incl_file->yy_prev_buf);
-	yylineno = incl_file->yy_prev_lineno;
-	srcpos_file = incl_file->file;
-	yyin = incl_file->file ? incl_file->file->file : NULL;
-
-	/*
-	 * Free old state.
-	 */
-	free(incl_file);
-
-	return 1;
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped	1969-12-31 19:00:00.000000000 -0500
@@ -1,2040 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.3.  */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, 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, 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.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "2.3"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Using locations.  */
-#define YYLSP_NEEDED 1
-
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     DT_V1 = 258,
-     DT_MEMRESERVE = 259,
-     DT_PROPNODENAME = 260,
-     DT_LITERAL = 261,
-     DT_LEGACYLITERAL = 262,
-     DT_BASE = 263,
-     DT_BYTE = 264,
-     DT_STRING = 265,
-     DT_LABEL = 266,
-     DT_REF = 267,
-     DT_INCBIN = 268
-   };
-#endif
-/* Tokens.  */
-#define DT_V1 258
-#define DT_MEMRESERVE 259
-#define DT_PROPNODENAME 260
-#define DT_LITERAL 261
-#define DT_LEGACYLITERAL 262
-#define DT_BASE 263
-#define DT_BYTE 264
-#define DT_STRING 265
-#define DT_LABEL 266
-#define DT_REF 267
-#define DT_INCBIN 268
-
-
-
-
-/* Copy the first part of user declarations.  */
-#line 23 "dtc-parser.y"
-
-#include <stdio.h>
-
-#include "dtc.h"
-#include "srcpos.h"
-
-extern int yylex(void);
-
-extern struct boot_info *the_boot_info;
-extern int treesource_error;
-
-static unsigned long long eval_literal(const char *s, int base, int bits);
-
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 37 "dtc-parser.y"
-{
-	char *propnodename;
-	char *literal;
-	char *labelref;
-	unsigned int cbase;
-	uint8_t byte;
-	struct data data;
-
-	uint64_t addr;
-	cell_t cell;
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-}
-/* Line 187 of yacc.c.  */
-#line 153 "dtc-parser.tab.c"
-	YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-/* Copy the second part of user declarations.  */
-
-
-/* Line 216 of yacc.c.  */
-#line 178 "dtc-parser.tab.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions.  */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int i)
-#else
-static int
-YYID (i)
-    int i;
-#endif
-{
-  return i;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
-       && ! ((defined YYMALLOC || defined malloc) \
-	     && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss;
-  YYSTYPE yyvs;
-    YYLTYPE yyls;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
-      + 2 * YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)		\
-      do					\
-	{					\
-	  YYSIZE_T yyi;				\
-	  for (yyi = 0; yyi < (Count); yyi++)	\
-	    (To)[yyi] = (From)[yyi];		\
-	}					\
-      while (YYID (0))
-#  endif
-# endif
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack)					\
-    do									\
-      {									\
-	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack, Stack, yysize);				\
-	Stack = &yyptr->Stack;						\
-	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-	yyptr += yynewbytes / sizeof (*yyptr);				\
-      }									\
-    while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  9
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   73
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  27
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  20
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  45
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  76
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   268
-
-#define YYTRANSLATE(YYX)						\
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      24,    26,     2,     2,    25,    15,     2,    16,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    14,
-      20,    19,    21,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    22,     2,    23,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    17,     2,    18,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint8 yyprhs[] =
-{
-       0,     0,     3,     8,    11,    12,    15,    21,    22,    25,
-      27,    34,    36,    38,    41,    47,    48,    51,    57,    61,
-      64,    69,    74,    77,    87,    93,    96,    97,   100,   103,
-     104,   107,   110,   113,   114,   116,   118,   121,   122,   125,
-     128,   129,   132,   135,   139,   140
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int8 yyrhs[] =
-{
-      28,     0,    -1,     3,    14,    29,    34,    -1,    31,    34,
-      -1,    -1,    30,    29,    -1,    46,     4,    33,    33,    14,
-      -1,    -1,    32,    31,    -1,    30,    -1,    46,     4,    33,
-      15,    33,    14,    -1,     6,    -1,     7,    -1,    16,    35,
-      -1,    17,    36,    44,    18,    14,    -1,    -1,    36,    37,
-      -1,    46,     5,    19,    38,    14,    -1,    46,     5,    14,
-      -1,    39,    10,    -1,    39,    20,    40,    21,    -1,    39,
-      22,    43,    23,    -1,    39,    12,    -1,    39,    13,    24,
-      10,    25,    33,    25,    33,    26,    -1,    39,    13,    24,
-      10,    26,    -1,    38,    11,    -1,    -1,    38,    25,    -1,
-      39,    11,    -1,    -1,    40,    42,    -1,    40,    12,    -1,
-      40,    11,    -1,    -1,     8,    -1,     6,    -1,    41,     7,
-      -1,    -1,    43,     9,    -1,    43,    11,    -1,    -1,    45,
-      44,    -1,    45,    37,    -1,    46,     5,    35,    -1,    -1,
-      11,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,    89,    89,    93,   101,   104,   111,   119,   122,   129,
-     133,   140,   144,   151,   158,   166,   169,   176,   180,   187,
-     191,   195,   199,   203,   220,   231,   239,   242,   246,   254,
-     257,   261,   266,   274,   277,   281,   285,   293,   296,   300,
-     308,   311,   315,   323,   331,   334
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
-  "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
-  "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'",
-  "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','",
-  "')'", "$accept", "sourcefile", "memreserves", "memreserve",
-  "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef",
-  "proplist", "propdef", "propdata", "propdataprefix", "celllist",
-  "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,    59,    45,    47,   123,   125,    61,
-      60,    62,    91,    93,    40,    44,    41
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
-{
-       0,    27,    28,    28,    29,    29,    30,    31,    31,    32,
-      32,    33,    33,    34,    35,    36,    36,    37,    37,    38,
-      38,    38,    38,    38,    38,    38,    39,    39,    39,    40,
-      40,    40,    40,    41,    41,    42,    42,    43,    43,    43,
-      44,    44,    44,    45,    46,    46
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     4,     2,     0,     2,     5,     0,     2,     1,
-       6,     1,     1,     2,     5,     0,     2,     5,     3,     2,
-       4,     4,     2,     9,     5,     2,     0,     2,     2,     0,
-       2,     2,     2,     0,     1,     1,     2,     0,     2,     2,
-       0,     2,     2,     3,     0,     1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
-   means the default is an error.  */
-static const yytype_uint8 yydefact[] =
-{
-       7,     0,    45,     0,     9,     0,     7,     0,     4,     1,
-       0,     3,     8,     0,     0,     4,     0,    15,    13,    11,
-      12,     0,     2,     5,     0,    40,     0,     0,     0,    16,
-       0,    40,     0,     0,     6,     0,    42,    41,     0,    10,
-      14,    18,    26,    43,     0,     0,    25,    17,    27,    19,
-      28,    22,     0,    29,    37,     0,    33,     0,     0,    35,
-      34,    32,    31,    20,     0,    30,    38,    39,    21,     0,
-      24,    36,     0,     0,     0,    23
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
-{
-      -1,     3,    14,     4,     5,     6,    27,    11,    18,    25,
-      29,    44,    45,    56,    64,    65,    57,    30,    31,     7
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -14
-static const yytype_int8 yypact[] =
-{
-      30,   -11,   -14,     7,   -14,    -1,    27,    13,    27,   -14,
-       8,   -14,   -14,    40,    -1,    27,    35,   -14,   -14,   -14,
-     -14,    21,   -14,   -14,    40,    24,    40,    28,    40,   -14,
-      32,    24,    46,    38,   -14,    39,   -14,   -14,    26,   -14,
-     -14,   -14,   -14,   -14,    -9,    10,   -14,   -14,   -14,   -14,
-     -14,   -14,    31,   -14,   -14,    44,    -2,     3,    23,   -14,
-     -14,   -14,   -14,   -14,    50,   -14,   -14,   -14,   -14,    40,
-     -14,   -14,    33,    40,    36,   -14
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -14,   -14,    48,    29,    53,   -14,   -13,    47,    34,   -14,
-      37,   -14,   -14,   -14,   -14,   -14,   -14,    42,   -14,    -7
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -45
-static const yytype_int8 yytable[] =
-{
-      21,    16,    46,     8,    59,    47,    60,     9,    16,    61,
-      62,    28,    66,    33,    67,    10,    48,    13,    32,    63,
-      49,    50,    51,    52,    32,    17,    68,    19,    20,   -44,
-      53,   -44,    54,     1,   -44,     2,    26,    15,     2,    24,
-      41,     2,    34,    17,    15,    42,    19,    20,    69,    70,
-      35,    38,    39,    40,    58,    55,    72,    71,    73,    12,
-      74,    22,    75,    23,     0,     0,     0,     0,    36,     0,
-       0,     0,    43,    37
-};
-
-static const yytype_int8 yycheck[] =
-{
-      13,     8,    11,    14,     6,    14,     8,     0,    15,    11,
-      12,    24,     9,    26,    11,    16,    25,     4,    25,    21,
-      10,    11,    12,    13,    31,    17,    23,     6,     7,     5,
-      20,     4,    22,     3,     4,    11,    15,     8,    11,     4,
-      14,    11,    14,    17,    15,    19,     6,     7,    25,    26,
-      18,     5,    14,    14,    10,    24,    69,     7,    25,     6,
-      73,    14,    26,    15,    -1,    -1,    -1,    -1,    31,    -1,
-      -1,    -1,    38,    31
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
-{
-       0,     3,    11,    28,    30,    31,    32,    46,    14,     0,
-      16,    34,    31,     4,    29,    30,    46,    17,    35,     6,
-       7,    33,    34,    29,     4,    36,    15,    33,    33,    37,
-      44,    45,    46,    33,    14,    18,    37,    44,     5,    14,
-      14,    14,    19,    35,    38,    39,    11,    14,    25,    10,
-      11,    12,    13,    20,    22,    24,    40,    43,    10,     6,
-       8,    11,    12,    21,    41,    42,     9,    11,    23,    25,
-      26,     7,    33,    25,    33,    26
-};
-
-#define yyerrok		(yyerrstatus = 0)
-#define yyclearin	(yychar = YYEMPTY)
-#define YYEMPTY		(-2)
-#define YYEOF		0
-
-#define YYACCEPT	goto yyacceptlab
-#define YYABORT		goto yyabortlab
-#define YYERROR		goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
-
-#define YYFAIL		goto yyerrlab
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)					\
-do								\
-  if (yychar == YYEMPTY && yylen == 1)				\
-    {								\
-      yychar = (Token);						\
-      yylval = (Value);						\
-      yytoken = YYTRANSLATE (yychar);				\
-      YYPOPSTACK (1);						\
-      goto yybackup;						\
-    }								\
-  else								\
-    {								\
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;							\
-    }								\
-while (YYID (0))
-
-
-#define YYTERROR	1
-#define YYERRCODE	256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)				\
-    do									\
-      if (YYID (N))                                                    \
-	{								\
-	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
-	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
-	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
-	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
-	}								\
-      else								\
-	{								\
-	  (Current).first_line   = (Current).last_line   =		\
-	    YYRHSLOC (Rhs, 0).last_line;				\
-	  (Current).first_column = (Current).last_column =		\
-	    YYRHSLOC (Rhs, 0).last_column;				\
-	}								\
-    while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)			\
-     fprintf (File, "%d.%d-%d.%d",			\
-	      (Loc).first_line, (Loc).first_column,	\
-	      (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments.  */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (YYLEX_PARAM)
-#else
-# define YYLEX yylex ()
-#endif
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)			\
-do {						\
-  if (yydebug)					\
-    YYFPRINTF Args;				\
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
-do {									  \
-  if (yydebug)								  \
-    {									  \
-      YYFPRINTF (stderr, "%s ", Title);					  \
-      yy_symbol_print (stderr,						  \
-		  Type, Value, Location); \
-      YYFPRINTF (stderr, "\n");						  \
-    }									  \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    YYLTYPE const * const yylocationp;
-#endif
-{
-  if (!yyvaluep)
-    return;
-  YYUSE (yylocationp);
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
-# endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    YYLTYPE const * const yylocationp;
-#endif
-{
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
-  YY_LOCATION_PRINT (yyoutput, *yylocationp);
-  YYFPRINTF (yyoutput, ": ");
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-#else
-static void
-yy_stack_print (bottom, top)
-    yytype_int16 *bottom;
-    yytype_int16 *top;
-#endif
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; bottom <= top; ++bottom)
-    YYFPRINTF (stderr, " %d", *bottom);
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)				\
-do {								\
-  if (yydebug)							\
-    yy_stack_print ((Bottom), (Top));				\
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yylsp, yyrule)
-    YYSTYPE *yyvsp;
-    YYLTYPE *yylsp;
-    int yyrule;
-#endif
-{
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  unsigned long int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-	     yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      fprintf (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-		       &(yyvsp[(yyi + 1) - (yynrhs)])
-		       , &(yylsp[(yyi + 1) - (yynrhs)])		       );
-      fprintf (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)		\
-do {					\
-  if (yydebug)				\
-    yy_reduce_print (yyvsp, yylsp, Rule); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef	YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
-    const char *yystr;
-#endif
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
-    char *yydest;
-    const char *yysrc;
-#endif
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-	switch (*++yyp)
-	  {
-	  case '\'':
-	  case ',':
-	    goto do_not_strip_quotes;
-
-	  case '\\':
-	    if (*++yyp != '\\')
-	      goto do_not_strip_quotes;
-	    /* Fall through.  */
-	  default:
-	    if (yyres)
-	      yyres[yyn] = *yyp;
-	    yyn++;
-	    break;
-
-	  case '"':
-	    if (yyres)
-	      yyres[yyn] = '\0';
-	    return yyn;
-	  }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
-
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
-    {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-	 constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-		    + sizeof yyexpecting - 1
-		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-		       * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-	 YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-	  {
-	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-	      {
-		yycount = 1;
-		yysize = yysize0;
-		yyformat[sizeof yyunexpected - 1] = '\0';
-		break;
-	      }
-	    yyarg[yycount++] = yytname[yyx];
-	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-	    yysize_overflow |= (yysize1 < yysize);
-	    yysize = yysize1;
-	    yyfmt = yystpcpy (yyfmt, yyprefix);
-	    yyprefix = yyor;
-	  }
-
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
-
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
-
-      if (yyresult)
-	{
-	  /* Avoid sprintf, as that infringes on the user's name space.
-	     Don't have undefined behavior even if the translation
-	     produced a string with the wrong number of "%s"s.  */
-	  char *yyp = yyresult;
-	  int yyi = 0;
-	  while ((*yyp = *yyf) != '\0')
-	    {
-	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		{
-		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-		  yyf += 2;
-		}
-	      else
-		{
-		  yyp++;
-		  yyf++;
-		}
-	    }
-	}
-      return yysize;
-    }
-}
-#endif /* YYERROR_VERBOSE */
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    YYLTYPE *yylocationp;
-#endif
-{
-  YYUSE (yyvaluep);
-  YYUSE (yylocationp);
-
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
-}
-
-
-/* Prevent warnings from -Wmissing-prototypes.  */
-
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-/* The look-ahead symbol.  */
-int yychar;
-
-/* The semantic value of the look-ahead symbol.  */
-YYSTYPE yylval;
-
-/* Number of syntax errors so far.  */
-int yynerrs;
-/* Location data for the look-ahead symbol.  */
-YYLTYPE yylloc;
-
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
-    void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
-int
-yyparse ()
-
-#endif
-#endif
-{
-  
-  int yystate;
-  int yyn;
-  int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Look-ahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
-
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
-
-  /* The state stack.  */
-  yytype_int16 yyssa[YYINITDEPTH];
-  yytype_int16 *yyss = yyssa;
-  yytype_int16 *yyssp;
-
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
-  YYSTYPE *yyvsp;
-
-  /* The location stack.  */
-  YYLTYPE yylsa[YYINITDEPTH];
-  YYLTYPE *yyls = yylsa;
-  YYLTYPE *yylsp;
-  /* The locations where the error started and ended.  */
-  YYLTYPE yyerror_range[2];
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
-  YYSIZE_T yystacksize = YYINITDEPTH;
-
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-  YYLTYPE yyloc;
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY;		/* Cause a token to be read.  */
-
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-
-  yyssp = yyss;
-  yyvsp = yyvs;
-  yylsp = yyls;
-#if YYLTYPE_IS_TRIVIAL
-  /* Initialize the default location before parsing starts.  */
-  yylloc.first_line   = yylloc.last_line   = 1;
-  yylloc.first_column = yylloc.last_column = 0;
-#endif
-
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-	/* Give user a chance to reallocate the stack.  Use copies of
-	   these so that the &'s don't force the real ones into
-	   memory.  */
-	YYSTYPE *yyvs1 = yyvs;
-	yytype_int16 *yyss1 = yyss;
-	YYLTYPE *yyls1 = yyls;
-
-	/* Each stack pointer address is followed by the size of the
-	   data in use in that stack, in bytes.  This used to be a
-	   conditional around just the two extra args, but that might
-	   be undefined if yyoverflow is a macro.  */
-	yyoverflow (YY_("memory exhausted"),
-		    &yyss1, yysize * sizeof (*yyssp),
-		    &yyvs1, yysize * sizeof (*yyvsp),
-		    &yyls1, yysize * sizeof (*yylsp),
-		    &yystacksize);
-	yyls = yyls1;
-	yyss = yyss1;
-	yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-	goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-	yystacksize = YYMAXDEPTH;
-
-      {
-	yytype_int16 *yyss1 = yyss;
-	union yyalloc *yyptr =
-	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-	if (! yyptr)
-	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss);
-	YYSTACK_RELOCATE (yyvs);
-	YYSTACK_RELOCATE (yyls);
-#  undef YYSTACK_RELOCATE
-	if (yyss1 != yyssa)
-	  YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-      yylsp = yyls + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-		  (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-	YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     look-ahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to look-ahead token.  */
-  yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
-    goto yydefault;
-
-  /* Not known => get a look-ahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the look-ahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token unless it is eof.  */
-  if (yychar != YYEOF)
-    yychar = YYEMPTY;
-
-  yystate = yyn;
-  *++yyvsp = yylval;
-  *++yylsp = yylloc;
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-  /* Default location.  */
-  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 2:
-#line 90 "dtc-parser.y"
-    {
-			the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0);
-		;}
-    break;
-
-  case 3:
-#line 94 "dtc-parser.y"
-    {
-			the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0);
-		;}
-    break;
-
-  case 4:
-#line 101 "dtc-parser.y"
-    {
-			(yyval.re) = NULL;
-		;}
-    break;
-
-  case 5:
-#line 105 "dtc-parser.y"
-    {
-			(yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
-		;}
-    break;
-
-  case 6:
-#line 112 "dtc-parser.y"
-    {
-			(yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
-		;}
-    break;
-
-  case 7:
-#line 119 "dtc-parser.y"
-    {
-			(yyval.re) = NULL;
-		;}
-    break;
-
-  case 8:
-#line 123 "dtc-parser.y"
-    {
-			(yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
-		;}
-    break;
-
-  case 9:
-#line 130 "dtc-parser.y"
-    {
-			(yyval.re) = (yyvsp[(1) - (1)].re);
-		;}
-    break;
-
-  case 10:
-#line 134 "dtc-parser.y"
-    {
-			(yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
-		;}
-    break;
-
-  case 11:
-#line 141 "dtc-parser.y"
-    {
-			(yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
-		;}
-    break;
-
-  case 12:
-#line 145 "dtc-parser.y"
-    {
-			(yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
-		;}
-    break;
-
-  case 13:
-#line 152 "dtc-parser.y"
-    {
-			(yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
-		;}
-    break;
-
-  case 14:
-#line 159 "dtc-parser.y"
-    {
-			(yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
-		;}
-    break;
-
-  case 15:
-#line 166 "dtc-parser.y"
-    {
-			(yyval.proplist) = NULL;
-		;}
-    break;
-
-  case 16:
-#line 170 "dtc-parser.y"
-    {
-			(yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
-		;}
-    break;
-
-  case 17:
-#line 177 "dtc-parser.y"
-    {
-			(yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
-		;}
-    break;
-
-  case 18:
-#line 181 "dtc-parser.y"
-    {
-			(yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
-		;}
-    break;
-
-  case 19:
-#line 188 "dtc-parser.y"
-    {
-			(yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
-		;}
-    break;
-
-  case 20:
-#line 192 "dtc-parser.y"
-    {
-			(yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
-		;}
-    break;
-
-  case 21:
-#line 196 "dtc-parser.y"
-    {
-			(yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
-		;}
-    break;
-
-  case 22:
-#line 200 "dtc-parser.y"
-    {
-			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
-		;}
-    break;
-
-  case 23:
-#line 204 "dtc-parser.y"
-    {
-			struct search_path path = { srcpos_file->dir, NULL, NULL };
-			struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path);
-			struct data d = empty_data;
-
-			if ((yyvsp[(6) - (9)].addr) != 0)
-				if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
-					yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
-						 (unsigned long long)(yyvsp[(6) - (9)].addr),
-						 (yyvsp[(4) - (9)].data).val, strerror(errno));
-
-			d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr));
-
-			(yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
-			dtc_close_file(file);
-		;}
-    break;
-
-  case 24:
-#line 221 "dtc-parser.y"
-    {
-			struct search_path path = { srcpos_file->dir, NULL, NULL };
-			struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path);
-			struct data d = empty_data;
-
-			d = data_copy_file(file->file, -1);
-
-			(yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
-			dtc_close_file(file);
-		;}
-    break;
-
-  case 25:
-#line 232 "dtc-parser.y"
-    {
-			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-		;}
-    break;
-
-  case 26:
-#line 239 "dtc-parser.y"
-    {
-			(yyval.data) = empty_data;
-		;}
-    break;
-
-  case 27:
-#line 243 "dtc-parser.y"
-    {
-			(yyval.data) = (yyvsp[(1) - (2)].data);
-		;}
-    break;
-
-  case 28:
-#line 247 "dtc-parser.y"
-    {
-			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-		;}
-    break;
-
-  case 29:
-#line 254 "dtc-parser.y"
-    {
-			(yyval.data) = empty_data;
-		;}
-    break;
-
-  case 30:
-#line 258 "dtc-parser.y"
-    {
-			(yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
-		;}
-    break;
-
-  case 31:
-#line 262 "dtc-parser.y"
-    {
-			(yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
-							      (yyvsp[(2) - (2)].labelref)), -1);
-		;}
-    break;
-
-  case 32:
-#line 267 "dtc-parser.y"
-    {
-			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-		;}
-    break;
-
-  case 33:
-#line 274 "dtc-parser.y"
-    {
-			(yyval.cbase) = 16;
-		;}
-    break;
-
-  case 35:
-#line 282 "dtc-parser.y"
-    {
-			(yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
-		;}
-    break;
-
-  case 36:
-#line 286 "dtc-parser.y"
-    {
-			(yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
-		;}
-    break;
-
-  case 37:
-#line 293 "dtc-parser.y"
-    {
-			(yyval.data) = empty_data;
-		;}
-    break;
-
-  case 38:
-#line 297 "dtc-parser.y"
-    {
-			(yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
-		;}
-    break;
-
-  case 39:
-#line 301 "dtc-parser.y"
-    {
-			(yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-		;}
-    break;
-
-  case 40:
-#line 308 "dtc-parser.y"
-    {
-			(yyval.nodelist) = NULL;
-		;}
-    break;
-
-  case 41:
-#line 312 "dtc-parser.y"
-    {
-			(yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
-		;}
-    break;
-
-  case 42:
-#line 316 "dtc-parser.y"
-    {
-			yyerror("syntax error: properties must precede subnodes");
-			YYERROR;
-		;}
-    break;
-
-  case 43:
-#line 324 "dtc-parser.y"
-    {
-			(yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
-		;}
-    break;
-
-  case 44:
-#line 331 "dtc-parser.y"
-    {
-			(yyval.labelref) = NULL;
-		;}
-    break;
-
-  case 45:
-#line 335 "dtc-parser.y"
-    {
-			(yyval.labelref) = (yyvsp[(1) - (1)].labelref);
-		;}
-    break;
-
-
-/* Line 1267 of yacc.c.  */
-#line 1780 "dtc-parser.tab.c"
-      default: break;
-    }
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-  *++yylsp = yyloc;
-
-  /* Now `shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (YY_("syntax error"));
-#else
-      {
-	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-	  {
-	    YYSIZE_T yyalloc = 2 * yysize;
-	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-	    if (yymsg != yymsgbuf)
-	      YYSTACK_FREE (yymsg);
-	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-	    if (yymsg)
-	      yymsg_alloc = yyalloc;
-	    else
-	      {
-		yymsg = yymsgbuf;
-		yymsg_alloc = sizeof yymsgbuf;
-	      }
-	  }
-
-	if (0 < yysize && yysize <= yymsg_alloc)
-	  {
-	    (void) yysyntax_error (yymsg, yystate, yychar);
-	    yyerror (yymsg);
-	  }
-	else
-	  {
-	    yyerror (YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
-      }
-#endif
-    }
-
-  yyerror_range[0] = yylloc;
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse look-ahead token after an
-	 error, discard it.  */
-
-      if (yychar <= YYEOF)
-	{
-	  /* Return failure if at end of input.  */
-	  if (yychar == YYEOF)
-	    YYABORT;
-	}
-      else
-	{
-	  yydestruct ("Error: discarding",
-		      yytoken, &yylval, &yylloc);
-	  yychar = YYEMPTY;
-	}
-    }
-
-  /* Else will try to reuse look-ahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  yyerror_range[0] = yylsp[1-yylen];
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
-	{
-	  yyn += YYTERROR;
-	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-	    {
-	      yyn = yytable[yyn];
-	      if (0 < yyn)
-		break;
-	    }
-	}
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-	YYABORT;
-
-      yyerror_range[0] = *yylsp;
-      yydestruct ("Error: popping",
-		  yystos[yystate], yyvsp, yylsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
-  *++yyvsp = yylval;
-
-  yyerror_range[1] = yylloc;
-  /* Using YYLLOC is tempting, but would change the location of
-     the look-ahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
-  *++yylsp = yyloc;
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#ifndef yyoverflow
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEOF && yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, &yylloc);
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-		  yystos[*yyssp], yyvsp, yylsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
-}
-
-
-#line 340 "dtc-parser.y"
-
-
-void yyerrorf(char const *s, ...)
-{
-	const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
-	va_list va;
-	va_start(va, s);
-
-	if (strcmp(fname, "-") == 0)
-		fname = "stdin";
-
-	fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
-	vfprintf(stderr, s, va);
-	fprintf(stderr, "\n");
-
-	treesource_error = 1;
-	va_end(va);
-}
-
-void yyerror (char const *s)
-{
-	yyerrorf("%s", s);
-}
-
-static unsigned long long eval_literal(const char *s, int base, int bits)
-{
-	unsigned long long val;
-	char *e;
-
-	errno = 0;
-	val = strtoull(s, &e, base);
-	if (*e)
-		yyerror("bad characters in literal");
-	else if ((errno == ERANGE)
-		 || ((bits < 64) && (val >= (1ULL << bits))))
-		yyerror("literal out of range");
-	else if (errno != 0)
-		yyerror("bad literal");
-	return val;
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped	1969-12-31 19:00:00.000000000 -0500
@@ -1,113 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.3.  */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, 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, 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.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     DT_V1 = 258,
-     DT_MEMRESERVE = 259,
-     DT_PROPNODENAME = 260,
-     DT_LITERAL = 261,
-     DT_LEGACYLITERAL = 262,
-     DT_BASE = 263,
-     DT_BYTE = 264,
-     DT_STRING = 265,
-     DT_LABEL = 266,
-     DT_REF = 267,
-     DT_INCBIN = 268
-   };
-#endif
-/* Tokens.  */
-#define DT_V1 258
-#define DT_MEMRESERVE 259
-#define DT_PROPNODENAME 260
-#define DT_LITERAL 261
-#define DT_LEGACYLITERAL 262
-#define DT_BASE 263
-#define DT_BYTE 264
-#define DT_STRING 265
-#define DT_LABEL 266
-#define DT_REF 267
-#define DT_INCBIN 268
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-#line 37 "dtc-parser.y"
-{
-	char *propnodename;
-	char *literal;
-	char *labelref;
-	unsigned int cbase;
-	uint8_t byte;
-	struct data data;
-
-	uint64_t addr;
-	cell_t cell;
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-}
-/* Line 1489 of yacc.c.  */
-#line 92 "dtc-parser.tab.h"
-	YYSTYPE;
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYSTYPE yylval;
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-extern YYLTYPE yylloc;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.y linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.y
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.y	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/dtc-parser.y	1969-12-31 19:00:00.000000000 -0500
@@ -1,379 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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
- */
-
-%locations
-
-%{
-#include <stdio.h>
-
-#include "dtc.h"
-#include "srcpos.h"
-
-extern int yylex(void);
-
-extern struct boot_info *the_boot_info;
-extern int treesource_error;
-
-static unsigned long long eval_literal(const char *s, int base, int bits);
-%}
-
-%union {
-	char *propnodename;
-	char *literal;
-	char *labelref;
-	unsigned int cbase;
-	uint8_t byte;
-	struct data data;
-
-	uint64_t addr;
-	cell_t cell;
-	struct property *prop;
-	struct property *proplist;
-	struct node *node;
-	struct node *nodelist;
-	struct reserve_info *re;
-}
-
-%token DT_V1
-%token DT_MEMRESERVE
-%token <propnodename> DT_PROPNODENAME
-%token <literal> DT_LITERAL
-%token <literal> DT_LEGACYLITERAL
-%token <cbase> DT_BASE
-%token <byte> DT_BYTE
-%token <data> DT_STRING
-%token <labelref> DT_LABEL
-%token <labelref> DT_REF
-%token DT_INCBIN
-
-%type <data> propdata
-%type <data> propdataprefix
-%type <re> memreserve
-%type <re> memreserves
-%type <re> v0_memreserve
-%type <re> v0_memreserves
-%type <addr> addr
-%type <data> celllist
-%type <cbase> cellbase
-%type <cell> cellval
-%type <data> bytestring
-%type <prop> propdef
-%type <proplist> proplist
-
-%type <node> devicetree
-%type <node> nodedef
-%type <node> subnode
-%type <nodelist> subnodes
-%type <labelref> label
-
-%%
-
-sourcefile:
-	  DT_V1 ';' memreserves devicetree
-		{
-			the_boot_info = build_boot_info($3, $4, 0);
-		}
-	| v0_memreserves devicetree
-		{
-			the_boot_info = build_boot_info($1, $2, 0);
-		}
-	;
-
-memreserves:
-	  /* empty */
-		{
-			$$ = NULL;
-		}
-	| memreserve memreserves
-		{
-			$$ = chain_reserve_entry($1, $2);
-		}
-	;
-
-memreserve:
-	  label DT_MEMRESERVE addr addr ';'
-		{
-			$$ = build_reserve_entry($3, $4, $1);
-		}
-	;
-
-v0_memreserves:
-	  /* empty */
-		{
-			$$ = NULL;
-		}
-	| v0_memreserve v0_memreserves
-		{
-			$$ = chain_reserve_entry($1, $2);
-		};
-	;
-
-v0_memreserve:
-	  memreserve
-		{
-			$$ = $1;
-		}
-	| label DT_MEMRESERVE addr '-' addr ';'
-		{
-			$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
-		}
-	;
-
-addr:
-	  DT_LITERAL
-		{
-			$$ = eval_literal($1, 0, 64);
-		}
-	| DT_LEGACYLITERAL
-		{
-			$$ = eval_literal($1, 16, 64);
-		}
-	  ;
-
-devicetree:
-	  '/' nodedef
-		{
-			$$ = name_node($2, "", NULL);
-		}
-	;
-
-nodedef:
-	  '{' proplist subnodes '}' ';'
-		{
-			$$ = build_node($2, $3);
-		}
-	;
-
-proplist:
-	  /* empty */
-		{
-			$$ = NULL;
-		}
-	| proplist propdef
-		{
-			$$ = chain_property($2, $1);
-		}
-	;
-
-propdef:
-	  label DT_PROPNODENAME '=' propdata ';'
-		{
-			$$ = build_property($2, $4, $1);
-		}
-	| label DT_PROPNODENAME ';'
-		{
-			$$ = build_property($2, empty_data, $1);
-		}
-	;
-
-propdata:
-	  propdataprefix DT_STRING
-		{
-			$$ = data_merge($1, $2);
-		}
-	| propdataprefix '<' celllist '>'
-		{
-			$$ = data_merge($1, $3);
-		}
-	| propdataprefix '[' bytestring ']'
-		{
-			$$ = data_merge($1, $3);
-		}
-	| propdataprefix DT_REF
-		{
-			$$ = data_add_marker($1, REF_PATH, $2);
-		}
-	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
-		{
-			struct search_path path = { srcpos_file->dir, NULL, NULL };
-			struct dtc_file *file = dtc_open_file($4.val, &path);
-			struct data d = empty_data;
-
-			if ($6 != 0)
-				if (fseek(file->file, $6, SEEK_SET) != 0)
-					yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
-						 (unsigned long long)$6,
-						 $4.val, strerror(errno));
-
-			d = data_copy_file(file->file, $8);
-
-			$$ = data_merge($1, d);
-			dtc_close_file(file);
-		}
-	| propdataprefix DT_INCBIN '(' DT_STRING ')'
-		{
-			struct search_path path = { srcpos_file->dir, NULL, NULL };
-			struct dtc_file *file = dtc_open_file($4.val, &path);
-			struct data d = empty_data;
-
-			d = data_copy_file(file->file, -1);
-
-			$$ = data_merge($1, d);
-			dtc_close_file(file);
-		}
-	| propdata DT_LABEL
-		{
-			$$ = data_add_marker($1, LABEL, $2);
-		}
-	;
-
-propdataprefix:
-	  /* empty */
-		{
-			$$ = empty_data;
-		}
-	| propdata ','
-		{
-			$$ = $1;
-		}
-	| propdataprefix DT_LABEL
-		{
-			$$ = data_add_marker($1, LABEL, $2);
-		}
-	;
-
-celllist:
-	  /* empty */
-		{
-			$$ = empty_data;
-		}
-	| celllist cellval
-		{
-			$$ = data_append_cell($1, $2);
-		}
-	| celllist DT_REF
-		{
-			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
-							      $2), -1);
-		}
-	| celllist DT_LABEL
-		{
-			$$ = data_add_marker($1, LABEL, $2);
-		}
-	;
-
-cellbase:
-	  /* empty */
-		{
-			$$ = 16;
-		}
-	| DT_BASE
-	;
-
-cellval:
-	  DT_LITERAL
-		{
-			$$ = eval_literal($1, 0, 32);
-		}
-	| cellbase DT_LEGACYLITERAL
-		{
-			$$ = eval_literal($2, $1, 32);
-		}
-	;
-
-bytestring:
-	  /* empty */
-		{
-			$$ = empty_data;
-		}
-	| bytestring DT_BYTE
-		{
-			$$ = data_append_byte($1, $2);
-		}
-	| bytestring DT_LABEL
-		{
-			$$ = data_add_marker($1, LABEL, $2);
-		}
-	;
-
-subnodes:
-	  /* empty */
-		{
-			$$ = NULL;
-		}
-	|  subnode subnodes
-		{
-			$$ = chain_node($1, $2);
-		}
-	| subnode propdef
-		{
-			yyerror("syntax error: properties must precede subnodes");
-			YYERROR;
-		}
-	;
-
-subnode:
-	  label DT_PROPNODENAME nodedef
-		{
-			$$ = name_node($3, $2, $1);
-		}
-	;
-
-label:
-	  /* empty */
-		{
-			$$ = NULL;
-		}
-	| DT_LABEL
-		{
-			$$ = $1;
-		}
-	;
-
-%%
-
-void yyerrorf(char const *s, ...)
-{
-	const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
-	va_list va;
-	va_start(va, s);
-
-	if (strcmp(fname, "-") == 0)
-		fname = "stdin";
-
-	fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
-	vfprintf(stderr, s, va);
-	fprintf(stderr, "\n");
-
-	treesource_error = 1;
-	va_end(va);
-}
-
-void yyerror (char const *s)
-{
-	yyerrorf("%s", s);
-}
-
-static unsigned long long eval_literal(const char *s, int base, int bits)
-{
-	unsigned long long val;
-	char *e;
-
-	errno = 0;
-	val = strtoull(s, &e, base);
-	if (*e)
-		yyerror("bad characters in literal");
-	else if ((errno == ERANGE)
-		 || ((bits < 64) && (val >= (1ULL << bits))))
-		yyerror("literal out of range");
-	else if (errno != 0)
-		yyerror("bad literal");
-	return val;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/flattree.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/flattree.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/flattree.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/flattree.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,906 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-#include "srcpos.h"
-
-#define FTF_FULLPATH	0x1
-#define FTF_VARALIGN	0x2
-#define FTF_NAMEPROPS	0x4
-#define FTF_BOOTCPUID	0x8
-#define FTF_STRTABSIZE	0x10
-#define FTF_STRUCTSIZE	0x20
-#define FTF_NOPS	0x40
-
-static struct version_info {
-	int version;
-	int last_comp_version;
-	int hdr_size;
-	int flags;
-} version_table[] = {
-	{1, 1, FDT_V1_SIZE,
-	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
-	{2, 1, FDT_V2_SIZE,
-	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
-	{3, 1, FDT_V3_SIZE,
-	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
-	{16, 16, FDT_V3_SIZE,
-	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
-	{17, 16, FDT_V17_SIZE,
-	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
-};
-
-struct emitter {
-	void (*cell)(void *, cell_t);
-	void (*string)(void *, char *, int);
-	void (*align)(void *, int);
-	void (*data)(void *, struct data);
-	void (*beginnode)(void *, const char *);
-	void (*endnode)(void *, const char *);
-	void (*property)(void *, const char *);
-};
-
-static void bin_emit_cell(void *e, cell_t val)
-{
-	struct data *dtbuf = e;
-
-	*dtbuf = data_append_cell(*dtbuf, val);
-}
-
-static void bin_emit_string(void *e, char *str, int len)
-{
-	struct data *dtbuf = e;
-
-	if (len == 0)
-		len = strlen(str);
-
-	*dtbuf = data_append_data(*dtbuf, str, len);
-	*dtbuf = data_append_byte(*dtbuf, '\0');
-}
-
-static void bin_emit_align(void *e, int a)
-{
-	struct data *dtbuf = e;
-
-	*dtbuf = data_append_align(*dtbuf, a);
-}
-
-static void bin_emit_data(void *e, struct data d)
-{
-	struct data *dtbuf = e;
-
-	*dtbuf = data_append_data(*dtbuf, d.val, d.len);
-}
-
-static void bin_emit_beginnode(void *e, const char *label)
-{
-	bin_emit_cell(e, FDT_BEGIN_NODE);
-}
-
-static void bin_emit_endnode(void *e, const char *label)
-{
-	bin_emit_cell(e, FDT_END_NODE);
-}
-
-static void bin_emit_property(void *e, const char *label)
-{
-	bin_emit_cell(e, FDT_PROP);
-}
-
-static struct emitter bin_emitter = {
-	.cell = bin_emit_cell,
-	.string = bin_emit_string,
-	.align = bin_emit_align,
-	.data = bin_emit_data,
-	.beginnode = bin_emit_beginnode,
-	.endnode = bin_emit_endnode,
-	.property = bin_emit_property,
-};
-
-static void emit_label(FILE *f, const char *prefix, const char *label)
-{
-	fprintf(f, "\t.globl\t%s_%s\n", prefix, label);
-	fprintf(f, "%s_%s:\n", prefix, label);
-	fprintf(f, "_%s_%s:\n", prefix, label);
-}
-
-static void emit_offset_label(FILE *f, const char *label, int offset)
-{
-	fprintf(f, "\t.globl\t%s\n", label);
-	fprintf(f, "%s\t= . + %d\n", label, offset);
-}
-
-static void asm_emit_cell(void *e, cell_t val)
-{
-	FILE *f = e;
-
-	fprintf(f, "\t.long\t0x%x\n", val);
-}
-
-static void asm_emit_string(void *e, char *str, int len)
-{
-	FILE *f = e;
-	char c = 0;
-
-	if (len != 0) {
-		/* XXX: ewww */
-		c = str[len];
-		str[len] = '\0';
-	}
-
-	fprintf(f, "\t.string\t\"%s\"\n", str);
-
-	if (len != 0) {
-		str[len] = c;
-	}
-}
-
-static void asm_emit_align(void *e, int a)
-{
-	FILE *f = e;
-
-	fprintf(f, "\t.balign\t%d\n", a);
-}
-
-static void asm_emit_data(void *e, struct data d)
-{
-	FILE *f = e;
-	int off = 0;
-	struct marker *m = d.markers;
-
-	for_each_marker_of_type(m, LABEL)
-		emit_offset_label(f, m->ref, m->offset);
-
-	while ((d.len - off) >= sizeof(uint32_t)) {
-		fprintf(f, "\t.long\t0x%x\n",
-			fdt32_to_cpu(*((uint32_t *)(d.val+off))));
-		off += sizeof(uint32_t);
-	}
-
-	while ((d.len - off) >= 1) {
-		fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
-		off += 1;
-	}
-
-	assert(off == d.len);
-}
-
-static void asm_emit_beginnode(void *e, const char *label)
-{
-	FILE *f = e;
-
-	if (label) {
-		fprintf(f, "\t.globl\t%s\n", label);
-		fprintf(f, "%s:\n", label);
-	}
-	fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
-}
-
-static void asm_emit_endnode(void *e, const char *label)
-{
-	FILE *f = e;
-
-	fprintf(f, "\t.long\tFDT_END_NODE\n");
-	if (label) {
-		fprintf(f, "\t.globl\t%s_end\n", label);
-		fprintf(f, "%s_end:\n", label);
-	}
-}
-
-static void asm_emit_property(void *e, const char *label)
-{
-	FILE *f = e;
-
-	if (label) {
-		fprintf(f, "\t.globl\t%s\n", label);
-		fprintf(f, "%s:\n", label);
-	}
-	fprintf(f, "\t.long\tFDT_PROP\n");
-}
-
-static struct emitter asm_emitter = {
-	.cell = asm_emit_cell,
-	.string = asm_emit_string,
-	.align = asm_emit_align,
-	.data = asm_emit_data,
-	.beginnode = asm_emit_beginnode,
-	.endnode = asm_emit_endnode,
-	.property = asm_emit_property,
-};
-
-static int stringtable_insert(struct data *d, const char *str)
-{
-	int i;
-
-	/* FIXME: do this more efficiently? */
-
-	for (i = 0; i < d->len; i++) {
-		if (streq(str, d->val + i))
-			return i;
-	}
-
-	*d = data_append_data(*d, str, strlen(str)+1);
-	return i;
-}
-
-static void flatten_tree(struct node *tree, struct emitter *emit,
-			 void *etarget, struct data *strbuf,
-			 struct version_info *vi)
-{
-	struct property *prop;
-	struct node *child;
-	int seen_name_prop = 0;
-
-	emit->beginnode(etarget, tree->label);
-
-	if (vi->flags & FTF_FULLPATH)
-		emit->string(etarget, tree->fullpath, 0);
-	else
-		emit->string(etarget, tree->name, 0);
-
-	emit->align(etarget, sizeof(cell_t));
-
-	for_each_property(tree, prop) {
-		int nameoff;
-
-		if (streq(prop->name, "name"))
-			seen_name_prop = 1;
-
-		nameoff = stringtable_insert(strbuf, prop->name);
-
-		emit->property(etarget, prop->label);
-		emit->cell(etarget, prop->val.len);
-		emit->cell(etarget, nameoff);
-
-		if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
-			emit->align(etarget, 8);
-
-		emit->data(etarget, prop->val);
-		emit->align(etarget, sizeof(cell_t));
-	}
-
-	if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
-		emit->property(etarget, NULL);
-		emit->cell(etarget, tree->basenamelen+1);
-		emit->cell(etarget, stringtable_insert(strbuf, "name"));
-
-		if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8))
-			emit->align(etarget, 8);
-
-		emit->string(etarget, tree->name, tree->basenamelen);
-		emit->align(etarget, sizeof(cell_t));
-	}
-
-	for_each_child(tree, child) {
-		flatten_tree(child, emit, etarget, strbuf, vi);
-	}
-
-	emit->endnode(etarget, tree->label);
-}
-
-static struct data flatten_reserve_list(struct reserve_info *reservelist,
-				 struct version_info *vi)
-{
-	struct reserve_info *re;
-	struct data d = empty_data;
-	static struct fdt_reserve_entry null_re = {0,0};
-	int    j;
-
-	for (re = reservelist; re; re = re->next) {
-		d = data_append_re(d, &re->re);
-	}
-	/*
-	 * Add additional reserved slots if the user asked for them.
-	 */
-	for (j = 0; j < reservenum; j++) {
-		d = data_append_re(d, &null_re);
-	}
-
-	return d;
-}
-
-static void make_fdt_header(struct fdt_header *fdt,
-			    struct version_info *vi,
-			    int reservesize, int dtsize, int strsize,
-			    int boot_cpuid_phys)
-{
-	int reserve_off;
-
-	reservesize += sizeof(struct fdt_reserve_entry);
-
-	memset(fdt, 0xff, sizeof(*fdt));
-
-	fdt->magic = cpu_to_fdt32(FDT_MAGIC);
-	fdt->version = cpu_to_fdt32(vi->version);
-	fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
-
-	/* Reserve map should be doubleword aligned */
-	reserve_off = ALIGN(vi->hdr_size, 8);
-
-	fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off);
-	fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize);
-	fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize
-					  + dtsize);
-	fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize);
-
-	if (vi->flags & FTF_BOOTCPUID)
-		fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys);
-	if (vi->flags & FTF_STRTABSIZE)
-		fdt->size_dt_strings = cpu_to_fdt32(strsize);
-	if (vi->flags & FTF_STRUCTSIZE)
-		fdt->size_dt_struct = cpu_to_fdt32(dtsize);
-}
-
-void dt_to_blob(FILE *f, struct boot_info *bi, int version)
-{
-	struct version_info *vi = NULL;
-	int i;
-	struct data blob       = empty_data;
-	struct data reservebuf = empty_data;
-	struct data dtbuf      = empty_data;
-	struct data strbuf     = empty_data;
-	struct fdt_header fdt;
-	int padlen = 0;
-
-	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
-		if (version_table[i].version == version)
-			vi = &version_table[i];
-	}
-	if (!vi)
-		die("Unknown device tree blob version %d\n", version);
-
-	flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
-	bin_emit_cell(&dtbuf, FDT_END);
-
-	reservebuf = flatten_reserve_list(bi->reservelist, vi);
-
-	/* Make header */
-	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
-			bi->boot_cpuid_phys);
-
-	/*
-	 * If the user asked for more space than is used, adjust the totalsize.
-	 */
-	if (minsize > 0) {
-		padlen = minsize - fdt32_to_cpu(fdt.totalsize);
-		if ((padlen < 0) && (quiet < 1))
-			fprintf(stderr,
-				"Warning: blob size %d >= minimum size %d\n",
-				fdt32_to_cpu(fdt.totalsize), minsize);
-	}
-
-	if (padsize > 0)
-		padlen = padsize;
-
-	if (padlen > 0) {
-		int tsize = fdt32_to_cpu(fdt.totalsize);
-		tsize += padlen;
-		fdt.totalsize = cpu_to_fdt32(tsize);
-	}
-
-	/*
-	 * Assemble the blob: start with the header, add with alignment
-	 * the reserve buffer, add the reserve map terminating zeroes,
-	 * the device tree itself, and finally the strings.
-	 */
-	blob = data_append_data(blob, &fdt, vi->hdr_size);
-	blob = data_append_align(blob, 8);
-	blob = data_merge(blob, reservebuf);
-	blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
-	blob = data_merge(blob, dtbuf);
-	blob = data_merge(blob, strbuf);
-
-	/*
-	 * If the user asked for more space than is used, pad out the blob.
-	 */
-	if (padlen > 0)
-		blob = data_append_zeroes(blob, padlen);
-
-	fwrite(blob.val, blob.len, 1, f);
-
-	if (ferror(f))
-		die("Error writing device tree blob: %s\n", strerror(errno));
-
-	/*
-	 * data_merge() frees the right-hand element so only the blob
-	 * remains to be freed.
-	 */
-	data_free(blob);
-}
-
-static void dump_stringtable_asm(FILE *f, struct data strbuf)
-{
-	const char *p;
-	int len;
-
-	p = strbuf.val;
-
-	while (p < (strbuf.val + strbuf.len)) {
-		len = strlen(p);
-		fprintf(f, "\t.string \"%s\"\n", p);
-		p += len+1;
-	}
-}
-
-void dt_to_asm(FILE *f, struct boot_info *bi, int version)
-{
-	struct version_info *vi = NULL;
-	int i;
-	struct data strbuf = empty_data;
-	struct reserve_info *re;
-	const char *symprefix = "dt";
-
-	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
-		if (version_table[i].version == version)
-			vi = &version_table[i];
-	}
-	if (!vi)
-		die("Unknown device tree blob version %d\n", version);
-
-	fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
-	fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
-	fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
-	fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
-	fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
-	fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
-	fprintf(f, "\n");
-
-	emit_label(f, symprefix, "blob_start");
-	emit_label(f, symprefix, "header");
-	fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
-	fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
-		symprefix, symprefix);
-	fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
-		symprefix, symprefix);
-	fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
-		symprefix, symprefix);
-	fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
-		symprefix, symprefix);
-	fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
-	fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
-		vi->last_comp_version);
-
-	if (vi->flags & FTF_BOOTCPUID)
-		fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
-			bi->boot_cpuid_phys);
-
-	if (vi->flags & FTF_STRTABSIZE)
-		fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
-			symprefix, symprefix);
-
-	if (vi->flags & FTF_STRUCTSIZE)
-		fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
-			symprefix, symprefix);
-
-	/*
-	 * Reserve map entries.
-	 * Align the reserve map to a doubleword boundary.
-	 * Each entry is an (address, size) pair of u64 values.
-	 * Always supply a zero-sized temination entry.
-	 */
-	asm_emit_align(f, 8);
-	emit_label(f, symprefix, "reserve_map");
-
-	fprintf(f, "/* Memory reserve map from source file */\n");
-
-	/*
-	 * Use .long on high and low halfs of u64s to avoid .quad
-	 * as it appears .quad isn't available in some assemblers.
-	 */
-	for (re = bi->reservelist; re; re = re->next) {
-		if (re->label) {
-			fprintf(f, "\t.globl\t%s\n", re->label);
-			fprintf(f, "%s:\n", re->label);
-		}
-		fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
-			(unsigned int)(re->re.address >> 32),
-			(unsigned int)(re->re.address & 0xffffffff));
-		fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
-			(unsigned int)(re->re.size >> 32),
-			(unsigned int)(re->re.size & 0xffffffff));
-	}
-	for (i = 0; i < reservenum; i++) {
-		fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
-	}
-
-	fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
-
-	emit_label(f, symprefix, "struct_start");
-	flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
-	fprintf(f, "\t.long\tFDT_END\n");
-	emit_label(f, symprefix, "struct_end");
-
-	emit_label(f, symprefix, "strings_start");
-	dump_stringtable_asm(f, strbuf);
-	emit_label(f, symprefix, "strings_end");
-
-	emit_label(f, symprefix, "blob_end");
-
-	/*
-	 * If the user asked for more space than is used, pad it out.
-	 */
-	if (minsize > 0) {
-		fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
-			minsize, symprefix, symprefix);
-	}
-	if (padsize > 0) {
-		fprintf(f, "\t.space\t%d, 0\n", padsize);
-	}
-	emit_label(f, symprefix, "blob_abs_end");
-
-	data_free(strbuf);
-}
-
-struct inbuf {
-	char *base, *limit, *ptr;
-};
-
-static void inbuf_init(struct inbuf *inb, void *base, void *limit)
-{
-	inb->base = base;
-	inb->limit = limit;
-	inb->ptr = inb->base;
-}
-
-static void flat_read_chunk(struct inbuf *inb, void *p, int len)
-{
-	if ((inb->ptr + len) > inb->limit)
-		die("Premature end of data parsing flat device tree\n");
-
-	memcpy(p, inb->ptr, len);
-
-	inb->ptr += len;
-}
-
-static uint32_t flat_read_word(struct inbuf *inb)
-{
-	uint32_t val;
-
-	assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
-
-	flat_read_chunk(inb, &val, sizeof(val));
-
-	return fdt32_to_cpu(val);
-}
-
-static void flat_realign(struct inbuf *inb, int align)
-{
-	int off = inb->ptr - inb->base;
-
-	inb->ptr = inb->base + ALIGN(off, align);
-	if (inb->ptr > inb->limit)
-		die("Premature end of data parsing flat device tree\n");
-}
-
-static char *flat_read_string(struct inbuf *inb)
-{
-	int len = 0;
-	const char *p = inb->ptr;
-	char *str;
-
-	do {
-		if (p >= inb->limit)
-			die("Premature end of data parsing flat device tree\n");
-		len++;
-	} while ((*p++) != '\0');
-
-	str = strdup(inb->ptr);
-
-	inb->ptr += len;
-
-	flat_realign(inb, sizeof(uint32_t));
-
-	return str;
-}
-
-static struct data flat_read_data(struct inbuf *inb, int len)
-{
-	struct data d = empty_data;
-
-	if (len == 0)
-		return empty_data;
-
-	d = data_grow_for(d, len);
-	d.len = len;
-
-	flat_read_chunk(inb, d.val, len);
-
-	flat_realign(inb, sizeof(uint32_t));
-
-	return d;
-}
-
-static char *flat_read_stringtable(struct inbuf *inb, int offset)
-{
-	const char *p;
-
-	p = inb->base + offset;
-	while (1) {
-		if (p >= inb->limit || p < inb->base)
-			die("String offset %d overruns string table\n",
-			    offset);
-
-		if (*p == '\0')
-			break;
-
-		p++;
-	}
-
-	return strdup(inb->base + offset);
-}
-
-static struct property *flat_read_property(struct inbuf *dtbuf,
-					   struct inbuf *strbuf, int flags)
-{
-	uint32_t proplen, stroff;
-	char *name;
-	struct data val;
-
-	proplen = flat_read_word(dtbuf);
-	stroff = flat_read_word(dtbuf);
-
-	name = flat_read_stringtable(strbuf, stroff);
-
-	if ((flags & FTF_VARALIGN) && (proplen >= 8))
-		flat_realign(dtbuf, 8);
-
-	val = flat_read_data(dtbuf, proplen);
-
-	return build_property(name, val, NULL);
-}
-
-
-static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
-{
-	struct reserve_info *reservelist = NULL;
-	struct reserve_info *new;
-	const char *p;
-	struct fdt_reserve_entry re;
-
-	/*
-	 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
-	 * List terminates at an entry with size equal to zero.
-	 *
-	 * First pass, count entries.
-	 */
-	p = inb->ptr;
-	while (1) {
-		flat_read_chunk(inb, &re, sizeof(re));
-		re.address  = fdt64_to_cpu(re.address);
-		re.size = fdt64_to_cpu(re.size);
-		if (re.size == 0)
-			break;
-
-		new = build_reserve_entry(re.address, re.size, NULL);
-		reservelist = add_reserve_entry(reservelist, new);
-	}
-
-	return reservelist;
-}
-
-
-static char *nodename_from_path(const char *ppath, const char *cpath)
-{
-	int plen;
-
-	plen = strlen(ppath);
-
-	if (!strneq(ppath, cpath, plen))
-		die("Path \"%s\" is not valid as a child of \"%s\"\n",
-		    cpath, ppath);
-
-	/* root node is a special case */
-	if (!streq(ppath, "/"))
-		plen++;
-
-	return strdup(cpath + plen);
-}
-
-static struct node *unflatten_tree(struct inbuf *dtbuf,
-				   struct inbuf *strbuf,
-				   const char *parent_flatname, int flags)
-{
-	struct node *node;
-	char *flatname;
-	uint32_t val;
-
-	node = build_node(NULL, NULL);
-
-	flatname = flat_read_string(dtbuf);
-
-	if (flags & FTF_FULLPATH)
-		node->name = nodename_from_path(parent_flatname, flatname);
-	else
-		node->name = flatname;
-
-	do {
-		struct property *prop;
-		struct node *child;
-
-		val = flat_read_word(dtbuf);
-		switch (val) {
-		case FDT_PROP:
-			if (node->children)
-				fprintf(stderr, "Warning: Flat tree input has "
-					"subnodes preceding a property.\n");
-			prop = flat_read_property(dtbuf, strbuf, flags);
-			add_property(node, prop);
-			break;
-
-		case FDT_BEGIN_NODE:
-			child = unflatten_tree(dtbuf,strbuf, flatname, flags);
-			add_child(node, child);
-			break;
-
-		case FDT_END_NODE:
-			break;
-
-		case FDT_END:
-			die("Premature FDT_END in device tree blob\n");
-			break;
-
-		case FDT_NOP:
-			if (!(flags & FTF_NOPS))
-				fprintf(stderr, "Warning: NOP tag found in flat tree"
-					" version <16\n");
-
-			/* Ignore */
-			break;
-
-		default:
-			die("Invalid opcode word %08x in device tree blob\n",
-			    val);
-		}
-	} while (val != FDT_END_NODE);
-
-	return node;
-}
-
-
-struct boot_info *dt_from_blob(const char *fname)
-{
-	struct dtc_file *dtcf;
-	uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
-	uint32_t off_dt, off_str, off_mem_rsvmap;
-	int rc;
-	char *blob;
-	struct fdt_header *fdt;
-	char *p;
-	struct inbuf dtbuf, strbuf;
-	struct inbuf memresvbuf;
-	int sizeleft;
-	struct reserve_info *reservelist;
-	struct node *tree;
-	uint32_t val;
-	int flags = 0;
-
-	dtcf = dtc_open_file(fname, NULL);
-
-	rc = fread(&magic, sizeof(magic), 1, dtcf->file);
-	if (ferror(dtcf->file))
-		die("Error reading DT blob magic number: %s\n",
-		    strerror(errno));
-	if (rc < 1) {
-		if (feof(dtcf->file))
-			die("EOF reading DT blob magic number\n");
-		else
-			die("Mysterious short read reading magic number\n");
-	}
-
-	magic = fdt32_to_cpu(magic);
-	if (magic != FDT_MAGIC)
-		die("Blob has incorrect magic number\n");
-
-	rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
-	if (ferror(dtcf->file))
-		die("Error reading DT blob size: %s\n", strerror(errno));
-	if (rc < 1) {
-		if (feof(dtcf->file))
-			die("EOF reading DT blob size\n");
-		else
-			die("Mysterious short read reading blob size\n");
-	}
-
-	totalsize = fdt32_to_cpu(totalsize);
-	if (totalsize < FDT_V1_SIZE)
-		die("DT blob size (%d) is too small\n", totalsize);
-
-	blob = xmalloc(totalsize);
-
-	fdt = (struct fdt_header *)blob;
-	fdt->magic = cpu_to_fdt32(magic);
-	fdt->totalsize = cpu_to_fdt32(totalsize);
-
-	sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
-	p = blob + sizeof(magic)  + sizeof(totalsize);
-
-	while (sizeleft) {
-		if (feof(dtcf->file))
-			die("EOF before reading %d bytes of DT blob\n",
-			    totalsize);
-
-		rc = fread(p, 1, sizeleft, dtcf->file);
-		if (ferror(dtcf->file))
-			die("Error reading DT blob: %s\n",
-			    strerror(errno));
-
-		sizeleft -= rc;
-		p += rc;
-	}
-
-	off_dt = fdt32_to_cpu(fdt->off_dt_struct);
-	off_str = fdt32_to_cpu(fdt->off_dt_strings);
-	off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap);
-	version = fdt32_to_cpu(fdt->version);
-	boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys);
-
-	if (off_mem_rsvmap >= totalsize)
-		die("Mem Reserve structure offset exceeds total size\n");
-
-	if (off_dt >= totalsize)
-		die("DT structure offset exceeds total size\n");
-
-	if (off_str > totalsize)
-		die("String table offset exceeds total size\n");
-
-	if (version >= 3) {
-		uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings);
-		if (off_str+size_str > totalsize)
-			die("String table extends past total size\n");
-		inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
-	} else {
-		inbuf_init(&strbuf, blob + off_str, blob + totalsize);
-	}
-
-	if (version >= 17) {
-		size_dt = fdt32_to_cpu(fdt->size_dt_struct);
-		if (off_dt+size_dt > totalsize)
-			die("Structure block extends past total size\n");
-	}
-
-	if (version < 16) {
-		flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
-	} else {
-		flags |= FTF_NOPS;
-	}
-
-	inbuf_init(&memresvbuf,
-		   blob + off_mem_rsvmap, blob + totalsize);
-	inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
-
-	reservelist = flat_read_mem_reserve(&memresvbuf);
-
-	val = flat_read_word(&dtbuf);
-
-	if (val != FDT_BEGIN_NODE)
-		die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
-
-	tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
-
-	val = flat_read_word(&dtbuf);
-	if (val != FDT_END)
-		die("Device tree blob doesn't end with FDT_END\n");
-
-	free(blob);
-
-	dtc_close_file(dtcf);
-
-	return build_boot_info(reservelist, tree, boot_cpuid_phys);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/fstree.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/fstree.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/fstree.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/fstree.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,92 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-
-#include <dirent.h>
-#include <sys/stat.h>
-
-static struct node *read_fstree(const char *dirname)
-{
-	DIR *d;
-	struct dirent *de;
-	struct stat st;
-	struct node *tree;
-
-	d = opendir(dirname);
-	if (!d)
-		die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
-
-	tree = build_node(NULL, NULL);
-
-	while ((de = readdir(d)) != NULL) {
-		char *tmpnam;
-
-		if (streq(de->d_name, ".")
-		    || streq(de->d_name, ".."))
-			continue;
-
-		tmpnam = join_path(dirname, de->d_name);
-
-		if (lstat(tmpnam, &st) < 0)
-			die("stat(%s): %s\n", tmpnam, strerror(errno));
-
-		if (S_ISREG(st.st_mode)) {
-			struct property *prop;
-			FILE *pfile;
-
-			pfile = fopen(tmpnam, "r");
-			if (! pfile) {
-				fprintf(stderr,
-					"WARNING: Cannot open %s: %s\n",
-					tmpnam, strerror(errno));
-			} else {
-				prop = build_property(strdup(de->d_name),
-						      data_copy_file(pfile,
-								     st.st_size),
-						      NULL);
-				add_property(tree, prop);
-				fclose(pfile);
-			}
-		} else if (S_ISDIR(st.st_mode)) {
-			struct node *newchild;
-
-			newchild = read_fstree(tmpnam);
-			newchild = name_node(newchild, strdup(de->d_name),
-					     NULL);
-			add_child(tree, newchild);
-		}
-
-		free(tmpnam);
-	}
-
-	return tree;
-}
-
-struct boot_info *dt_from_fs(const char *dirname)
-{
-	struct node *tree;
-
-	tree = read_fstree(dirname);
-	tree = name_node(tree, "", NULL);
-
-	return build_boot_info(NULL, tree, 0);
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/libfdt_env.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/libfdt_env.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/libfdt_env.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/libfdt_env.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-#ifndef _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#define _B(n)	((unsigned long long)((uint8_t *)&x)[n])
-static inline uint32_t fdt32_to_cpu(uint32_t x)
-{
-	return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
-}
-#define cpu_to_fdt32(x) fdt32_to_cpu(x)
-
-static inline uint64_t fdt64_to_cpu(uint64_t x)
-{
-	return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
-		| (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
-}
-#define cpu_to_fdt64(x) fdt64_to_cpu(x)
-#undef _B
-
-#endif /* _LIBFDT_ENV_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/livetree.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/livetree.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/livetree.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/livetree.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,308 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-
-/*
- * Tree building functions
- */
-
-struct property *build_property(char *name, struct data val, char *label)
-{
-	struct property *new = xmalloc(sizeof(*new));
-
-	new->name = name;
-	new->val = val;
-
-	new->next = NULL;
-
-	new->label = label;
-
-	return new;
-}
-
-struct property *chain_property(struct property *first, struct property *list)
-{
-	assert(first->next == NULL);
-
-	first->next = list;
-	return first;
-}
-
-struct property *reverse_properties(struct property *first)
-{
-	struct property *p = first;
-	struct property *head = NULL;
-	struct property *next;
-
-	while (p) {
-		next = p->next;
-		p->next = head;
-		head = p;
-		p = next;
-	}
-	return head;
-}
-
-struct node *build_node(struct property *proplist, struct node *children)
-{
-	struct node *new = xmalloc(sizeof(*new));
-	struct node *child;
-
-	memset(new, 0, sizeof(*new));
-
-	new->proplist = reverse_properties(proplist);
-	new->children = children;
-
-	for_each_child(new, child) {
-		child->parent = new;
-	}
-
-	return new;
-}
-
-struct node *name_node(struct node *node, char *name, char * label)
-{
-	assert(node->name == NULL);
-
-	node->name = name;
-
-	node->label = label;
-
-	return node;
-}
-
-struct node *chain_node(struct node *first, struct node *list)
-{
-	assert(first->next_sibling == NULL);
-
-	first->next_sibling = list;
-	return first;
-}
-
-void add_property(struct node *node, struct property *prop)
-{
-	struct property **p;
-
-	prop->next = NULL;
-
-	p = &node->proplist;
-	while (*p)
-		p = &((*p)->next);
-
-	*p = prop;
-}
-
-void add_child(struct node *parent, struct node *child)
-{
-	struct node **p;
-
-	child->next_sibling = NULL;
-	child->parent = parent;
-
-	p = &parent->children;
-	while (*p)
-		p = &((*p)->next_sibling);
-
-	*p = child;
-}
-
-struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
-					 char *label)
-{
-	struct reserve_info *new = xmalloc(sizeof(*new));
-
-	new->re.address = address;
-	new->re.size = size;
-
-	new->next = NULL;
-
-	new->label = label;
-
-	return new;
-}
-
-struct reserve_info *chain_reserve_entry(struct reserve_info *first,
-					struct reserve_info *list)
-{
-	assert(first->next == NULL);
-
-	first->next = list;
-	return first;
-}
-
-struct reserve_info *add_reserve_entry(struct reserve_info *list,
-				      struct reserve_info *new)
-{
-	struct reserve_info *last;
-
-	new->next = NULL;
-
-	if (! list)
-		return new;
-
-	for (last = list; last->next; last = last->next)
-		;
-
-	last->next = new;
-
-	return list;
-}
-
-struct boot_info *build_boot_info(struct reserve_info *reservelist,
-				  struct node *tree, uint32_t boot_cpuid_phys)
-{
-	struct boot_info *bi;
-
-	bi = xmalloc(sizeof(*bi));
-	bi->reservelist = reservelist;
-	bi->dt = tree;
-	bi->boot_cpuid_phys = boot_cpuid_phys;
-
-	return bi;
-}
-
-/*
- * Tree accessor functions
- */
-
-const char *get_unitname(struct node *node)
-{
-	if (node->name[node->basenamelen] == '\0')
-		return "";
-	else
-		return node->name + node->basenamelen + 1;
-}
-
-struct property *get_property(struct node *node, const char *propname)
-{
-	struct property *prop;
-
-	for_each_property(node, prop)
-		if (streq(prop->name, propname))
-			return prop;
-
-	return NULL;
-}
-
-cell_t propval_cell(struct property *prop)
-{
-	assert(prop->val.len == sizeof(cell_t));
-	return fdt32_to_cpu(*((cell_t *)prop->val.val));
-}
-
-struct node *get_subnode(struct node *node, const char *nodename)
-{
-	struct node *child;
-
-	for_each_child(node, child)
-		if (streq(child->name, nodename))
-			return child;
-
-	return NULL;
-}
-
-struct node *get_node_by_path(struct node *tree, const char *path)
-{
-	const char *p;
-	struct node *child;
-
-	if (!path || ! (*path))
-		return tree;
-
-	while (path[0] == '/')
-		path++;
-
-	p = strchr(path, '/');
-
-	for_each_child(tree, child) {
-		if (p && strneq(path, child->name, p-path))
-			return get_node_by_path(child, p+1);
-		else if (!p && streq(path, child->name))
-			return child;
-	}
-
-	return NULL;
-}
-
-struct node *get_node_by_label(struct node *tree, const char *label)
-{
-	struct node *child, *node;
-
-	assert(label && (strlen(label) > 0));
-
-	if (tree->label && streq(tree->label, label))
-		return tree;
-
-	for_each_child(tree, child) {
-		node = get_node_by_label(child, label);
-		if (node)
-			return node;
-	}
-
-	return NULL;
-}
-
-struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
-{
-	struct node *child, *node;
-
-	assert((phandle != 0) && (phandle != -1));
-
-	if (tree->phandle == phandle)
-		return tree;
-
-	for_each_child(tree, child) {
-		node = get_node_by_phandle(child, phandle);
-		if (node)
-			return node;
-	}
-
-	return NULL;
-}
-
-struct node *get_node_by_ref(struct node *tree, const char *ref)
-{
-	if (ref[0] == '/')
-		return get_node_by_path(tree, ref);
-	else
-		return get_node_by_label(tree, ref);
-}
-
-cell_t get_node_phandle(struct node *root, struct node *node)
-{
-	static cell_t phandle = 1; /* FIXME: ick, static local */
-
-	if ((node->phandle != 0) && (node->phandle != -1))
-		return node->phandle;
-
-	assert(! get_property(node, "linux,phandle"));
-
-	while (get_node_by_phandle(root, phandle))
-		phandle++;
-
-	node->phandle = phandle;
-	add_property(node,
-		     build_property("linux,phandle",
-				    data_append_cell(empty_data, phandle),
-				    NULL));
-
-	return node->phandle;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/Makefile.dtc linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/Makefile.dtc
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/Makefile.dtc	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/Makefile.dtc	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-# Makefile.dtc
-#
-# This is not a complete Makefile of itself.  Instead, it is designed to
-# be easily embeddable into other systems of Makefiles.
-#
-DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
-	checks.c
-DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
-DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/srcpos.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/srcpos.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/srcpos.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/srcpos.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- * Copyright 2007 Jon Loeliger, 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.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You 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 "dtc.h"
-#include "srcpos.h"
-
-/*
- * Like yylineno, this is the current open file pos.
- */
-
-struct dtc_file *srcpos_file;
-
-static int dtc_open_one(struct dtc_file *file,
-                        const char *search,
-                        const char *fname)
-{
-	char *fullname;
-
-	if (search) {
-		fullname = xmalloc(strlen(search) + strlen(fname) + 2);
-
-		strcpy(fullname, search);
-		strcat(fullname, "/");
-		strcat(fullname, fname);
-	} else {
-		fullname = strdup(fname);
-	}
-
-	file->file = fopen(fullname, "r");
-	if (!file->file) {
-		free(fullname);
-		return 0;
-	}
-
-	file->name = fullname;
-	return 1;
-}
-
-
-struct dtc_file *dtc_open_file(const char *fname,
-                               const struct search_path *search)
-{
-	static const struct search_path default_search = { NULL, NULL, NULL };
-
-	struct dtc_file *file;
-	const char *slash;
-
-	file = xmalloc(sizeof(struct dtc_file));
-
-	slash = strrchr(fname, '/');
-	if (slash) {
-		char *dir = xmalloc(slash - fname + 1);
-
-		memcpy(dir, fname, slash - fname);
-		dir[slash - fname] = 0;
-		file->dir = dir;
-	} else {
-		file->dir = NULL;
-	}
-
-	if (streq(fname, "-")) {
-		file->name = "stdin";
-		file->file = stdin;
-		return file;
-	}
-
-	if (fname[0] == '/') {
-		file->file = fopen(fname, "r");
-		if (!file->file)
-			goto fail;
-
-		file->name = strdup(fname);
-		return file;
-	}
-
-	if (!search)
-		search = &default_search;
-
-	while (search) {
-		if (dtc_open_one(file, search->dir, fname))
-			return file;
-
-		if (errno != ENOENT)
-			goto fail;
-
-		search = search->next;
-	}
-
-fail:
-	die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
-}
-
-void dtc_close_file(struct dtc_file *file)
-{
-	if (fclose(file->file))
-		die("Error closing \"%s\": %s\n", file->name, strerror(errno));
-
-	free(file->dir);
-	free(file);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/srcpos.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/srcpos.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/srcpos.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/srcpos.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * Copyright 2007 Jon Loeliger, 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.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You 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
- */
-
-/*
- * Augment the standard YYLTYPE with a filenum index into an
- * array of all opened filenames.
- */
-
-#include <stdio.h>
-
-struct dtc_file {
-	char *dir;
-	const char *name;
-	FILE *file;
-};
-
-#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
-typedef struct YYLTYPE {
-    int first_line;
-    int first_column;
-    int last_line;
-    int last_column;
-    struct dtc_file *file;
-} YYLTYPE;
-
-#define YYLTYPE_IS_DECLARED	1
-#define YYLTYPE_IS_TRIVIAL	1
-#endif
-
-/* Cater to old parser templates. */
-#ifndef YYID
-#define YYID(n)	(n)
-#endif
-
-#define YYLLOC_DEFAULT(Current, Rhs, N)					\
-    do									\
-      if (YYID (N))							\
-	{								\
-	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
-	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
-	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
-	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
-	  (Current).file         = YYRHSLOC (Rhs, N).file;		\
-	}								\
-      else								\
-	{								\
-	  (Current).first_line   = (Current).last_line   =		\
-	    YYRHSLOC (Rhs, 0).last_line;				\
-	  (Current).first_column = (Current).last_column =		\
-	    YYRHSLOC (Rhs, 0).last_column;				\
-	  (Current).file         = YYRHSLOC (Rhs, 0).file;		\
-	}								\
-    while (YYID (0))
-
-
-
-extern void yyerror(char const *);
-extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
-
-extern struct dtc_file *srcpos_file;
-
-struct search_path {
-	const char *dir; /* NULL for current directory */
-	struct search_path *prev, *next;
-};
-
-extern struct dtc_file *dtc_open_file(const char *fname,
-                                      const struct search_path *search);
-extern void dtc_close_file(struct dtc_file *file);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/treesource.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/treesource.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/treesource.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/treesource.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,278 +0,0 @@
-/*
- * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 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 "dtc.h"
-#include "srcpos.h"
-
-extern FILE *yyin;
-extern int yyparse(void);
-
-struct boot_info *the_boot_info;
-int treesource_error;
-
-struct boot_info *dt_from_source(const char *fname)
-{
-	the_boot_info = NULL;
-	treesource_error = 0;
-
-	srcpos_file = dtc_open_file(fname, NULL);
-	yyin = srcpos_file->file;
-
-	if (yyparse() != 0)
-		die("Unable to parse input tree\n");
-
-	if (treesource_error)
-		die("Syntax error parsing input tree\n");
-
-	return the_boot_info;
-}
-
-static void write_prefix(FILE *f, int level)
-{
-	int i;
-
-	for (i = 0; i < level; i++)
-		fputc('\t', f);
-}
-
-int isstring(char c)
-{
-	return (isprint(c)
-		|| (c == '\0')
-		|| strchr("\a\b\t\n\v\f\r", c));
-}
-
-static void write_propval_string(FILE *f, struct data val)
-{
-	const char *str = val.val;
-	int i;
-	int newchunk = 1;
-	struct marker *m = val.markers;
-
-	assert(str[val.len-1] == '\0');
-
-	for (i = 0; i < (val.len-1); i++) {
-		char c = str[i];
-
-		if (newchunk) {
-			while (m && (m->offset <= i)) {
-				if (m->type == LABEL) {
-					assert(m->offset == i);
-					fprintf(f, "%s: ", m->ref);
-				}
-				m = m->next;
-			}
-			fprintf(f, "\"");
-			newchunk = 0;
-		}
-
-		switch (c) {
-		case '\a':
-			fprintf(f, "\\a");
-			break;
-		case '\b':
-			fprintf(f, "\\b");
-			break;
-		case '\t':
-			fprintf(f, "\\t");
-			break;
-		case '\n':
-			fprintf(f, "\\n");
-			break;
-		case '\v':
-			fprintf(f, "\\v");
-			break;
-		case '\f':
-			fprintf(f, "\\f");
-			break;
-		case '\r':
-			fprintf(f, "\\r");
-			break;
-		case '\\':
-			fprintf(f, "\\\\");
-			break;
-		case '\"':
-			fprintf(f, "\\\"");
-			break;
-		case '\0':
-			fprintf(f, "\", ");
-			newchunk = 1;
-			break;
-		default:
-			if (isprint(c))
-				fprintf(f, "%c", c);
-			else
-				fprintf(f, "\\x%02hhx", c);
-		}
-	}
-	fprintf(f, "\"");
-
-	/* Wrap up any labels at the end of the value */
-	for_each_marker_of_type(m, LABEL) {
-		assert (m->offset == val.len);
-		fprintf(f, " %s:", m->ref);
-	}
-}
-
-static void write_propval_cells(FILE *f, struct data val)
-{
-	void *propend = val.val + val.len;
-	cell_t *cp = (cell_t *)val.val;
-	struct marker *m = val.markers;
-
-	fprintf(f, "<");
-	for (;;) {
-		while (m && (m->offset <= ((char *)cp - val.val))) {
-			if (m->type == LABEL) {
-				assert(m->offset == ((char *)cp - val.val));
-				fprintf(f, "%s: ", m->ref);
-			}
-			m = m->next;
-		}
-
-		fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
-		if ((void *)cp >= propend)
-			break;
-		fprintf(f, " ");
-	}
-
-	/* Wrap up any labels at the end of the value */
-	for_each_marker_of_type(m, LABEL) {
-		assert (m->offset == val.len);
-		fprintf(f, " %s:", m->ref);
-	}
-	fprintf(f, ">");
-}
-
-static void write_propval_bytes(FILE *f, struct data val)
-{
-	void *propend = val.val + val.len;
-	const char *bp = val.val;
-	struct marker *m = val.markers;
-
-	fprintf(f, "[");
-	for (;;) {
-		while (m && (m->offset == (bp-val.val))) {
-			if (m->type == LABEL)
-				fprintf(f, "%s: ", m->ref);
-			m = m->next;
-		}
-
-		fprintf(f, "%02hhx", *bp++);
-		if ((const void *)bp >= propend)
-			break;
-		fprintf(f, " ");
-	}
-
-	/* Wrap up any labels at the end of the value */
-	for_each_marker_of_type(m, LABEL) {
-		assert (m->offset == val.len);
-		fprintf(f, " %s:", m->ref);
-	}
-	fprintf(f, "]");
-}
-
-static void write_propval(FILE *f, struct property *prop)
-{
-	int len = prop->val.len;
-	const char *p = prop->val.val;
-	struct marker *m = prop->val.markers;
-	int nnotstring = 0, nnul = 0;
-	int nnotstringlbl = 0, nnotcelllbl = 0;
-	int i;
-
-	if (len == 0) {
-		fprintf(f, ";\n");
-		return;
-	}
-
-	for (i = 0; i < len; i++) {
-		if (! isstring(p[i]))
-			nnotstring++;
-		if (p[i] == '\0')
-			nnul++;
-	}
-
-	for_each_marker_of_type(m, LABEL) {
-		if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
-			nnotstringlbl++;
-		if ((m->offset % sizeof(cell_t)) != 0)
-			nnotcelllbl++;
-	}
-
-	fprintf(f, " = ");
-	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
-	    && (nnotstringlbl == 0)) {
-		write_propval_string(f, prop->val);
-	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
-		write_propval_cells(f, prop->val);
-	} else {
-		write_propval_bytes(f, prop->val);
-	}
-
-	fprintf(f, ";\n");
-}
-
-static void write_tree_source_node(FILE *f, struct node *tree, int level)
-{
-	struct property *prop;
-	struct node *child;
-
-	write_prefix(f, level);
-	if (tree->label)
-		fprintf(f, "%s: ", tree->label);
-	if (tree->name && (*tree->name))
-		fprintf(f, "%s {\n", tree->name);
-	else
-		fprintf(f, "/ {\n");
-
-	for_each_property(tree, prop) {
-		write_prefix(f, level+1);
-		if (prop->label)
-			fprintf(f, "%s: ", prop->label);
-		fprintf(f, "%s", prop->name);
-		write_propval(f, prop);
-	}
-	for_each_child(tree, child) {
-		fprintf(f, "\n");
-		write_tree_source_node(f, child, level+1);
-	}
-	write_prefix(f, level);
-	fprintf(f, "};\n");
-}
-
-
-void dt_to_source(FILE *f, struct boot_info *bi)
-{
-	struct reserve_info *re;
-
-	fprintf(f, "/dts-v1/;\n\n");
-
-	for (re = bi->reservelist; re; re = re->next) {
-		if (re->label)
-			fprintf(f, "%s: ", re->label);
-		fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
-			(unsigned long long)re->re.address,
-			(unsigned long long)re->re.size);
-	}
-
-	write_tree_source_node(f, bi->dt, 0);
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/version_gen.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/version_gen.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dtc-src/version_gen.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dtc-src/version_gen.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#define DTC_VERSION "DTC 1.2.0"
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/amigaone.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/amigaone.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/amigaone.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/amigaone.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,173 @@
+/*
+ * AmigaOne Device Tree Source
+ *
+ * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.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.
+ */
+
+/dts-v1/;
+
+/ {
+	model = "AmigaOne";
+	compatible = "eyetech,amigaone";
+	coherency-off;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <32768>;		// L1, 32K
+			i-cache-size = <32768>;		// L1, 32K
+			timebase-frequency = <0>;	// 33.3 MHz, from U-boot
+			clock-frequency = <0>;		// From U-boot
+			bus-frequency = <0>;		// From U-boot
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0>;				// From U-boot
+	};
+
+	pci@80000000 {
+		device_type = "pci";
+		compatible = "mai-logic,articia-s";
+		bus-frequency = <33333333>;
+		bus-range = <0 0xff>;
+		ranges = <0x01000000 0 0x00000000 0xfe000000 0 0x00c00000	// PCI I/O
+		          0x02000000 0 0x80000000 0x80000000 0 0x7d000000	// PCI memory
+		          0x02000000 0 0x00000000 0xfd000000 0 0x01000000>;	// PCI alias memory (ISA)
+		// Configuration address and data register.
+		reg = <0xfec00cf8 4
+		       0xfee00cfc 4>;
+		8259-interrupt-acknowledge = <0xfef00000>;
+		// Do not define a interrupt-parent here, if there is no
+		// interrupt-map property.
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		isa@7 {
+			device_type = "isa";
+			compatible = "pciclass,0601";
+			vendor-id = <0x00001106>;
+			device-id = <0x00000686>;
+			revision-id = <0x00000010>;
+			class-code = <0x00060100>;
+			subsystem-id = <0>;
+			subsystem-vendor-id = <0>;
+			devsel-speed = <0x00000001>;
+			min-grant = <0>;
+			max-latency = <0>;
+			/* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */
+			ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>;
+			interrupt-parent = <&i8259>;
+			#interrupt-cells = <2>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+
+			dma-controller@0 {
+				compatible = "pnpPNP,200";
+				reg = <1 0x00000000 0x00000020
+				       1 0x00000080 0x00000010
+				       1 0x000000c0 0x00000020>;
+			};
+
+			i8259: interrupt-controller@20 {
+				device_type = "interrupt-controller";
+				compatible = "pnpPNP,000";
+				interrupt-controller;
+				reg = <1 0x00000020 0x00000002
+				       1 0x000000a0 0x00000002
+				       1 0x000004d0 0x00000002>;
+				reserved-interrupts = <2>;
+				#interrupt-cells = <2>;
+			};
+
+			timer@40 {
+				// Also adds pcspkr to platform devices.
+				compatible = "pnpPNP,100";
+				reg = <1 0x00000040 0x00000020>;
+			};
+
+			8042@60 {
+				device_type = "8042";
+				reg = <1 0x00000060 0x00000001
+				       1 0x00000064 0x00000001>;
+				interrupts = <1 3 12 3>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				keyboard@0 {
+					compatible = "pnpPNP,303";
+					reg = <0>;
+				};
+
+				mouse@1 {
+					compatible = "pnpPNP,f03";
+					reg = <1>;
+				};
+			};
+
+			rtc@70 {
+				compatible = "pnpPNP,b00";
+				reg = <1 0x00000070 0x00000002>;
+				interrupts = <8 3>;
+			};
+
+			serial@3f8 {
+				device_type = "serial";
+				compatible = "pnpPNP,501","pnpPNP,500";
+				reg = <1 0x000003f8 0x00000008>;
+				interrupts = <4 3>;
+				clock-frequency = <1843200>;
+				current-speed = <115200>;
+			};
+
+			serial@2f8 {
+				device_type = "serial";
+				compatible = "pnpPNP,501","pnpPNP,500";
+				reg = <1 0x000002f8 0x00000008>;
+				interrupts = <3 3>;
+				clock-frequency = <1843200>;
+				current-speed = <115200>;
+			};
+
+			parallel@378 {
+				device_type = "parallel";
+				// No ECP support for now, otherwise add "pnpPNP,401".
+				compatible = "pnpPNP,400";
+				reg = <1 0x00000378 0x00000003
+				       1 0x00000778 0x00000003>;
+			};
+
+			fdc@3f0 {
+				device_type = "fdc";
+				compatible = "pnpPNP,700";
+				reg = <1 0x000003f0 0x00000008>;
+				interrupts = <6 3>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				disk@0 {
+					reg = <0>;
+				};
+			};
+		};
+	};
+
+	chosen {
+		linux,stdout-path = "/pci@80000000/isa@7/serial@3f8";
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts	2009-06-09 23:05:27.000000000 -0400
@@ -181,70 +181,76 @@
 			phy_type = "ulpi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 08 e5 11 32 33 ];
 			interrupts = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			linux,network-index = <0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				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 = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 08 e5 11 32 34 ];
 			interrupts = <35 0x8 36 0x8 37 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
 			linux,network-index = <1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/canyonlands.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/canyonlands.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/canyonlands.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/canyonlands.dts	2009-06-09 23:05:27.000000000 -0400
@@ -127,6 +127,13 @@
 			dcr-reg = <0x010 0x002>;
 		};
 
+		CRYPTO: crypto@180000 {
+			compatible = "amcc,ppc460ex-crypto", "amcc,ppc4xx-crypto";
+			reg = <4 0x00180000 0x80400>;
+			interrupt-parent = <&UIC0>;
+			interrupts = <0x1d 0x4>;
+		};
+
 		MAL0: mcmal {
 			compatible = "ibm,mcmal-460ex", "ibm,mcmal2";
 			dcr-reg = <0x180 0x062>;
@@ -142,6 +149,20 @@
 					/*RXDE*/  0x5 0x4>;
 		};
 
+                USB0: ehci@bffd0400 {
+                        compatible = "ibm,usb-ehci-460ex", "usb-ehci";
+                        interrupt-parent = <&UIC2>;
+                        interrupts = <0x1d 4>;
+                        reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
+                };
+
+                USB1: usb@bffd0000 {
+                        compatible = "ohci-le";
+                        reg = <4 0xbffd0000 0x60>;
+                        interrupt-parent = <&UIC2>;
+                        interrupts = <0x1e 4>;
+                };
+
 		POB0: opb {
 			compatible = "ibm,opb-460ex", "ibm,opb";
 			#address-cells = <1>;
@@ -245,6 +266,20 @@
 				reg = <0xef600700 0x00000014>;
 				interrupt-parent = <&UIC0>;
 				interrupts = <0x2 0x4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+                                rtc@68 {
+                                        compatible = "stm,m41t80";
+                                        reg = <0x68>;
+					interrupt-parent = <&UIC2>;
+					interrupts = <0x19 0x8>;
+                                };
+                                sttm@48 {
+                                        compatible = "ad,ad7414";
+                                        reg = <0x48>;
+					interrupt-parent = <&UIC1>;
+					interrupts = <0x14 0x8>;
+                                };
 			};
 
 			IIC1: i2c@ef600800 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/cm5200.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/cm5200.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/cm5200.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/cm5200.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 	compatible = "schindler,cm5200";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -66,7 +67,6 @@
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x600 0x10>;
 			interrupts = <1 9 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl,has-wdt;
 		};
 
@@ -74,84 +74,76 @@
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x610 0x10>;
 			interrupts = <1 10 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@620 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x620 0x10>;
 			interrupts = <1 11 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@630 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x630 0x10>;
 			interrupts = <1 12 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@640 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x640 0x10>;
 			interrupts = <1 13 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@650 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x650 0x10>;
 			interrupts = <1 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@660 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x660 0x10>;
 			interrupts = <1 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@670 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x670 0x10>;
 			interrupts = <1 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
 			reg = <0x800 0x100>;
 			interrupts = <1 5 0 1 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
-		gpio@b00 {
+		gpio_simple: gpio@b00 {
 			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
 			interrupts = <1 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
-		gpio@c00 {
+		gpio_wkup: gpio@c00 {
 			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
 			reg = <0xc00 0x40>;
 			interrupts = <1 8 0 0 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		spi@f00 {
 			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
 			reg = <0xf00 0x20>;
 			interrupts = <2 13 0 2 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
 			interrupts = <2 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		dma-controller@1200 {
@@ -161,7 +153,6 @@
 			              3 4 0  3 5 0  3 6 0  3 7 0
 			              3 8 0  3 9 0  3 10 0  3 11 0
 			              3 12 0  3 13 0  3 14 0  3 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		xlb@1f00 {
@@ -170,48 +161,34 @@
 		};
 
 		serial@2000 {		// PSC1
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <0>;  // Logical port assignment
 			reg = <0x2000 0x100>;
 			interrupts = <2 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		serial@2200 {		// PSC2
-			device_type = "serial";
-			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <1>;  // Logical port assignment
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
 			reg = <0x2200 0x100>;
 			interrupts = <2 2 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		serial@2400 {		// PSC3
-			device_type = "serial";
-			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <2>;  // Logical port assignment
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
 			reg = <0x2400 0x100>;
 			interrupts = <2 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		serial@2c00 {		// PSC6
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <5>;  // Logical port assignment
 			reg = <0x2c00 0x100>;
 			interrupts = <2 4 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <2 5 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			phy-handle = <&phy0>;
 		};
 
@@ -221,10 +198,8 @@
 			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
 			reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
 			interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
-			interrupt-parent = <&mpc5200_pic>;
 
 			phy0: ethernet-phy@0 {
-				device_type = "ethernet-phy";
 				reg = <0>;
 			};
 		};
@@ -235,7 +210,6 @@
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
 			reg = <0x3d40 0x40>;
 			interrupts = <2 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 		};
 
@@ -245,9 +219,8 @@
 		};
 	};
 
-	lpb {
-		model = "fsl,lpb";
-		compatible = "fsl,lpb";
+	localbus {
+		compatible = "fsl,mpc5200b-lpb","simple-bus";
 		#address-cells = <2>;
 		#size-cells = <1>;
 		ranges = <0 0 0xfc000000 0x2000000>;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/digsy_mtc.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/digsy_mtc.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/digsy_mtc.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/digsy_mtc.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,254 @@
+/*
+ * Digsy MTC board Device Tree Source
+ *
+ * Copyright (C) 2009 Semihalf
+ *
+ * Based on the CM5200 by M. Balakowicz
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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 = "intercontrol,digsy-mtc";
+	compatible = "intercontrol,digsy-mtc";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,5200@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x4000>;		// L1, 16K
+			i-cache-size = <0x4000>;		// L1, 16K
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x02000000>;	// 32MB
+	};
+
+	soc5200@f0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc5200b-immr";
+		ranges = <0 0xf0000000 0x0000c000>;
+		reg = <0xf0000000 0x00000100>;
+		bus-frequency = <0>;		// from bootloader
+		system-frequency = <0>;		// from bootloader
+
+		cdm@200 {
+			compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+			reg = <0x200 0x38>;
+		};
+
+		mpc5200_pic: interrupt-controller@500 {
+			// 5200 interrupts are encoded into two levels;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+			reg = <0x500 0x80>;
+		};
+
+		timer@600 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x600 0x10>;
+			interrupts = <1 9 0>;
+			fsl,has-wdt;
+		};
+
+		timer@610 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x610 0x10>;
+			interrupts = <1 10 0>;
+		};
+
+		timer@620 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x620 0x10>;
+			interrupts = <1 11 0>;
+		};
+
+		timer@630 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x630 0x10>;
+			interrupts = <1 12 0>;
+		};
+
+		timer@640 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x640 0x10>;
+			interrupts = <1 13 0>;
+		};
+
+		timer@650 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x650 0x10>;
+			interrupts = <1 14 0>;
+		};
+
+		timer@660 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x660 0x10>;
+			interrupts = <1 15 0>;
+		};
+
+		timer@670 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x670 0x10>;
+			interrupts = <1 16 0>;
+		};
+
+		gpio_simple: gpio@b00 {
+			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+			reg = <0xb00 0x40>;
+			interrupts = <1 7 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpio_wkup: gpio@c00 {
+			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+			reg = <0xc00 0x40>;
+			interrupts = <1 8 0 0 3 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		spi@f00 {
+			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+			reg = <0xf00 0x20>;
+			interrupts = <2 13 0 2 14 0>;
+		};
+
+		usb@1000 {
+			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+			reg = <0x1000 0xff>;
+			interrupts = <2 6 0>;
+		};
+
+		dma-controller@1200 {
+			compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+			reg = <0x1200 0x80>;
+			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+			              3 4 0  3 5 0  3 6 0  3 7 0
+			              3 8 0  3 9 0  3 10 0  3 11 0
+			              3 12 0  3 13 0  3 14 0  3 15 0>;
+		};
+
+		xlb@1f00 {
+			compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+			reg = <0x1f00 0x100>;
+		};
+
+		serial@2600 {		// PSC4
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+			reg = <0x2600 0x100>;
+			interrupts = <2 11 0>;
+		};
+
+		serial@2800 {		// PSC5
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+			reg = <0x2800 0x100>;
+			interrupts = <2 12 0>;
+		};
+
+		ethernet@3000 {
+			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+			reg = <0x3000 0x400>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <2 5 0>;
+			phy-handle = <&phy0>;
+		};
+
+		mdio@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+			reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
+			interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
+
+			phy0: ethernet-phy@0 {
+				reg = <0>;
+			};
+		};
+
+		ata@3a00 {
+			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+			reg = <0x3a00 0x100>;
+			interrupts = <2 7 0>;
+		};
+
+		i2c@3d00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+			reg = <0x3d00 0x40>;
+			interrupts = <2 15 0>;
+			fsl5200-clocking;
+
+			rtc@50 {
+				compatible = "at,24c08";
+				reg = <0x50>;
+			};
+
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		sram@8000 {
+			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+			reg = <0x8000 0x4000>;
+		};
+	};
+
+	lpb {
+		compatible = "fsl,mpc5200b-lpb","simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0xff000000 0x1000000>;
+
+		// 16-bit flash device at LocalPlus Bus CS0
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x1000000>;
+			bank-width = <2>;
+			device-width = <2>;
+			#size-cells = <1>;
+			#address-cells = <1>;
+
+			partition@0 {
+				label = "kernel";
+				reg = <0x0 0x00200000>;
+			};
+			partition@200000 {
+				label = "root";
+				reg = <0x00200000 0x00300000>;
+			};
+			partition@500000 {
+				label = "user";
+				reg = <0x00500000 0x00a00000>;
+			};
+			partition@f00000 {
+				label = "u-boot";
+				reg = <0x00f00000 0x100000>;
+			};
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_ppc9a.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,368 @@
+/*
+ * GE Fanuc PPC9A Device Tree Source
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
+ */
+
+/dts-v1/;
+
+/ {
+	model = "GEF_PPC9A";
+	compatible = "gef,ppc9a";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8641@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <32768>;		// L1, 32K
+			i-cache-size = <32768>;		// L1, 32K
+			timebase-frequency = <0>;	// From uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+		};
+		PowerPC,8641@1 {
+			device_type = "cpu";
+			reg = <1>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <32768>;		// L1, 32K
+			i-cache-size = <32768>;		// L1, 32K
+			timebase-frequency = <0>;	// From uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;	// set by uboot
+	};
+
+	localbus@fef05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8641-localbus", "simple-bus";
+		reg = <0xfef05000 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		ranges = <0 0 0xff000000 0x01000000	// 16MB Boot flash
+			  1 0 0xe8000000 0x08000000	// Paged Flash 0
+			  2 0 0xe0000000 0x08000000	// Paged Flash 1
+			  3 0 0xfc100000 0x00020000	// NVRAM
+			  4 0 0xfc000000 0x00008000	// FPGA
+			  5 0 0xfc008000 0x00008000	// AFIX FPGA
+			  6 0 0xfd000000 0x00800000	// IO FPGA (8-bit)
+			  7 0 0xfd800000 0x00800000>;	// IO FPGA (32-bit)
+
+		/* flash@0,0 is a mirror of part of the memory in flash@1,0
+		flash@0,0 {
+			compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <4>;
+			device-width = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "firmware";
+				reg = <0x0 0x1000000>;
+				read-only;
+			};
+		};
+		*/
+
+		flash@1,0 {
+			compatible = "gef,ppc9a-paged-flash", "cfi-flash";
+			reg = <0x1 0x0 0x8000000>;
+			bank-width = <4>;
+			device-width = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "user";
+				reg = <0x0 0x7800000>;
+			};
+			partition@7800000 {
+				label = "firmware";
+				reg = <0x7800000 0x800000>;
+				read-only;
+			};
+		};
+
+		fpga@4,0 {
+			compatible = "gef,ppc9a-fpga-regs";
+			reg = <0x4 0x0 0x40>;
+		};
+
+		wdt@4,2000 {
+			compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+				"gef,fpga-wdt";
+			reg = <0x4 0x2000 0x8>;
+			interrupts = <0x1a 0x4>;
+			interrupt-parent = <&gef_pic>;
+		};
+		/* Second watchdog available, driver currently supports one.
+		wdt@4,2010 {
+			compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+				"gef,fpga-wdt";
+			reg = <0x4 0x2010 0x8>;
+			interrupts = <0x1b 0x4>;
+			interrupt-parent = <&gef_pic>;
+		};
+		*/
+		gef_pic: pic@4,4000 {
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
+			reg = <0x4 0x4000 0x20>;
+			interrupts = <0x8
+				      0x9>;
+			interrupt-parent = <&mpic>;
+
+		};
+		gef_gpio: gpio@7,14000 {
+			#gpio-cells = <2>;
+			compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
+			reg = <0x7 0x14000 0x24>;
+			gpio-controller;
+		};
+	};
+
+	soc@fef00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		compatible = "fsl,mpc8641-soc", "simple-bus";
+		ranges = <0x0 0xfef00000 0x00100000>;
+		reg = <0xfef00000 0x100000>;	// CCSRBAR 1M
+		bus-frequency = <33333333>;
+
+		i2c1: i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <0x2b 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+
+			hwmon@48 {
+				compatible = "national,lm92";
+				reg = <0x48>;
+			};
+
+			hwmon@4c {
+				compatible = "adi,adt7461";
+				reg = <0x4c>;
+			};
+
+			rtc@51 {
+				compatible = "epson,rx8581";
+				reg = <0x00000051>;
+			};
+
+			eti@6b {
+				compatible = "dallas,ds1682";
+				reg = <0x6b>;
+			};
+		};
+
+		i2c2: i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <0x2b 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "gmii";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x9 0x4>;
+					reg = <1>;
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x8 0x4>;
+					reg = <3>;
+				};
+			};
+		};
+
+		enet1: ethernet@26000 {
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
+			phy-connection-type = "gmii";
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <0x2a 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <0x1c 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		mpic: pic@40000 {
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		global-utilities@e0000 {
+			compatible = "fsl,mpc8641-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@fef08000 {
+		compatible = "fsl,mpc8641-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xfef08000 0x1000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+			  0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <0x18 0x2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
+		>;
+
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0x0 0x80000000
+				  0x02000000 0x0 0x80000000
+				  0x0 0x40000000
+
+				  0x01000000 0x0 0x00000000
+				  0x01000000 0x0 0x00000000
+				  0x0 0x00400000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_sbc310.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ * GE Fanuc SBC310 Device Tree Source
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
+ */
+
+/dts-v1/;
+
+/ {
+	model = "GEF_SBC310";
+	compatible = "gef,sbc310";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8641@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <32768>;		// L1, 32K
+			i-cache-size = <32768>;		// L1, 32K
+			timebase-frequency = <0>;	// From uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+		};
+		PowerPC,8641@1 {
+			device_type = "cpu";
+			reg = <1>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <32768>;		// L1, 32K
+			i-cache-size = <32768>;		// L1, 32K
+			timebase-frequency = <0>;	// From uboot
+			bus-frequency = <0>;		// From uboot
+			clock-frequency = <0>;		// From uboot
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;	// set by uboot
+	};
+
+	localbus@fef05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8641-localbus", "simple-bus";
+		reg = <0xfef05000 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		ranges = <0 0 0xff000000 0x01000000	// 16MB Boot flash
+			  1 0 0xe0000000 0x08000000	// Paged Flash 0
+			  2 0 0xe8000000 0x08000000	// Paged Flash 1
+			  3 0 0xfc100000 0x00020000	// NVRAM
+			  4 0 0xfc000000 0x00010000>;	// FPGA
+
+		/* flash@0,0 is a mirror of part of the memory in flash@1,0
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x01000000>;
+			bank-width = <2>;
+			device-width = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "firmware";
+				reg = <0x00000000 0x01000000>;
+				read-only;
+			};
+		};
+		*/
+
+		flash@1,0 {
+			compatible = "cfi-flash";
+			reg = <1 0 0x8000000>;
+			bank-width = <2>;
+			device-width = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "user";
+				reg = <0x00000000 0x07800000>;
+			};
+			partition@7800000 {
+				label = "firmware";
+				reg = <0x07800000 0x00800000>;
+				read-only;
+			};
+		};
+
+		fpga@4,0 {
+			compatible = "gef,fpga-regs";
+			reg = <0x4 0x0 0x40>;
+		};
+
+		wdt@4,2000 {
+			#interrupt-cells = <2>;
+			device_type = "watchdog";
+			compatible = "gef,fpga-wdt";
+			reg = <0x4 0x2000 0x8>;
+			interrupts = <0x1a 0x4>;
+			interrupt-parent = <&gef_pic>;
+		};
+/*
+		wdt@4,2010 {
+			#interrupt-cells = <2>;
+			device_type = "watchdog";
+			compatible = "gef,fpga-wdt";
+			reg = <0x4 0x2010 0x8>;
+			interrupts = <0x1b 0x4>;
+			interrupt-parent = <&gef_pic>;
+		};
+*/
+		gef_pic: pic@4,4000 {
+			#interrupt-cells = <1>;
+			interrupt-controller;
+			compatible = "gef,fpga-pic";
+			reg = <0x4 0x4000 0x20>;
+			interrupts = <0x8
+				      0x9>;
+			interrupt-parent = <&mpic>;
+
+		};
+		gef_gpio: gpio@4,8000 {
+			#gpio-cells = <2>;
+			compatible = "gef,sbc310-gpio";
+			reg = <0x4 0x8000 0x24>;
+			gpio-controller;
+		};
+	};
+
+	soc@fef00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0x0 0xfef00000 0x00100000>;
+		reg = <0xfef00000 0x100000>;	// CCSRBAR 1M
+		bus-frequency = <33333333>;
+
+		i2c1: i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <0x2b 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+
+			rtc@51 {
+				compatible = "epson,rx8581";
+				reg = <0x00000051>;
+			};
+		};
+
+		i2c2: i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <0x2b 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+
+			hwmon@48 {
+				compatible = "national,lm92";
+				reg = <0x48>;
+			};
+
+			hwmon@4c {
+				compatible = "adi,adt7461";
+				reg = <0x4c>;
+			};
+
+			eti@6b {
+				compatible = "dallas,ds1682";
+				reg = <0x6b>;
+			};
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8641-dma-channel",
+					   "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "gmii";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x9 0x4>;
+					reg = <1>;
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x8 0x4>;
+					reg = <3>;
+				};
+			};
+		};
+
+		enet1: ethernet@26000 {
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
+			phy-connection-type = "gmii";
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <0x2a 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <0x1c 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		mpic: pic@40000 {
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		global-utilities@e0000 {
+			compatible = "fsl,mpc8641-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@fef08000 {
+		compatible = "fsl,mpc8641-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xfef08000 0x1000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+			  0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <0x18 0x2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
+			0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
+			0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
+			0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
+		>;
+
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0x0 0x80000000
+				  0x02000000 0x0 0x80000000
+				  0x0 0x40000000
+
+				  0x01000000 0x0 0x00000000
+				  0x01000000 0x0 0x00000000
+				  0x0 0x00400000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/gef_sbc610.dts	2009-06-09 23:05:27.000000000 -0400
@@ -71,7 +71,7 @@
 		#address-cells = <2>;
 		#size-cells = <1>;
 		compatible = "fsl,mpc8641-localbus", "simple-bus";
-		reg = <0xf8005000 0x1000>;
+		reg = <0xfef05000 0x1000>;
 		interrupts = <19 2>;
 		interrupt-parent = <&mpic>;
 
@@ -202,34 +202,37 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&gef_pic>;
-				interrupts = <0x9 0x4>;
-				reg = <1>;
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&gef_pic>;
-				interrupts = <0x8 0x4>;
-				reg = <3>;
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "gmii";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x9 0x4>;
+					reg = <1>;
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&gef_pic>;
+					interrupts = <0x8 0x4>;
+					reg = <3>;
+				};
+			};
 		};
 
 		enet1: ethernet@26000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/kilauea.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/kilauea.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/kilauea.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/kilauea.dts	2009-06-09 23:05:27.000000000 -0400
@@ -97,6 +97,13 @@
 				      0x6 0x4>;	/* ECC SEC Error */ 
 		};
 
+		CRYPTO: crypto@ef700000 {
+			compatible = "amcc,ppc405ex-crypto", "amcc,ppc4xx-crypto";
+			reg = <0xef700000 0x80400>;
+			interrupt-parent = <&UIC0>;
+			interrupts = <0x17 0x2>;
+		};
+
 		MAL0: mcmal {
 			compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
 			dcr-reg = <0x180 0x062>;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/ksi8560.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/ksi8560.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/ksi8560.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/ksi8560.dts	2009-06-09 23:05:27.000000000 -0400
@@ -57,14 +57,14 @@
 		bus-frequency = <0>;				/* Fixed by bootwrapper */
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <0x12 0x2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <0x20>;		/* 32 bytes */
 			cache-size = <0x40000>;			/* L2, 256K */
@@ -124,67 +124,72 @@
 			};
 		};
 
-		mdio@24520 {					/* For TSECs */
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			PHY1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-
-			PHY2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			/* Mac address filled in by bootwrapper */
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&PHY1>;
+
+			mdio@520 {					/* For TSECs */
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				PHY1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+
+				PHY2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			/* Mac address filled in by bootwrapper */
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&PHY2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		mpic: pic@40000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/lite5200b.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/lite5200b.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/lite5200b.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/lite5200b.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 	compatible = "fsl,lite5200b";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -58,136 +59,112 @@
 			// 5200 interrupts are encoded into two levels;
 			interrupt-controller;
 			#interrupt-cells = <3>;
-			device_type = "interrupt-controller";
 			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
 			reg = <0x500 0x80>;
 		};
 
 		timer@600 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <0>;
 			reg = <0x600 0x10>;
 			interrupts = <1 9 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl,has-wdt;
 		};
 
 		timer@610 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <1>;
 			reg = <0x610 0x10>;
 			interrupts = <1 10 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@620 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <2>;
 			reg = <0x620 0x10>;
 			interrupts = <1 11 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@630 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <3>;
 			reg = <0x630 0x10>;
 			interrupts = <1 12 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@640 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <4>;
 			reg = <0x640 0x10>;
 			interrupts = <1 13 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@650 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <5>;
 			reg = <0x650 0x10>;
 			interrupts = <1 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@660 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <6>;
 			reg = <0x660 0x10>;
 			interrupts = <1 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@670 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <7>;
 			reg = <0x670 0x10>;
 			interrupts = <1 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
 			reg = <0x800 0x100>;
 			interrupts = <1 5 0 1 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		can@900 {
 			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
-			cell-index = <0>;
 			interrupts = <2 17 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x900 0x80>;
 		};
 
 		can@980 {
 			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
-			cell-index = <1>;
 			interrupts = <2 18 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x980 0x80>;
 		};
 
-		gpio@b00 {
+		gpio_simple: gpio@b00 {
 			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
 			interrupts = <1 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
-		gpio@c00 {
+		gpio_wkup: gpio@c00 {
 			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
 			reg = <0xc00 0x40>;
 			interrupts = <1 8 0 0 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		spi@f00 {
 			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
 			reg = <0xf00 0x20>;
 			interrupts = <2 13 0 2 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
 			interrupts = <2 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		dma-controller@1200 {
-			device_type = "dma-controller";
 			compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
 			reg = <0x1200 0x80>;
 			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
 			              3 4 0  3 5 0  3 6 0  3 7 0
 			              3 8 0  3 9 0  3 10 0  3 11 0
 			              3 12 0  3 13 0  3 14 0  3 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		xlb@1f00 {
@@ -196,13 +173,10 @@
 		};
 
 		serial@2000 {		// PSC1
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <0>;  // Logical port assignment
 			cell-index = <0>;
 			reg = <0x2000 0x100>;
 			interrupts = <2 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		// PSC2 in ac97 mode example
@@ -211,7 +185,6 @@
 		//	cell-index = <1>;
 		//	reg = <0x2200 0x100>;
 		//	interrupts = <2 2 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC3 in CODEC mode example
@@ -220,27 +193,22 @@
 		//	cell-index = <2>;
 		//	reg = <0x2400 0x100>;
 		//	interrupts = <2 3 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC4 in uart mode example
 		//serial@2600 {		// PSC4
-		//	device_type = "serial";
 		//	compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
 		//	cell-index = <3>;
 		//	reg = <0x2600 0x100>;
 		//	interrupts = <2 11 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC5 in uart mode example
 		//serial@2800 {		// PSC5
-		//	device_type = "serial";
 		//	compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
 		//	cell-index = <4>;
 		//	reg = <0x2800 0x100>;
 		//	interrupts = <2 12 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC6 in spi mode example
@@ -249,49 +217,40 @@
 		//	cell-index = <5>;
 		//	reg = <0x2c00 0x100>;
 		//	interrupts = <2 4 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <2 5 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			phy-handle = <&phy0>;
 		};
 
 		mdio@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio";
+			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
 			reg = <0x3000 0x400>;	// fec range, since we need to setup fec interrupts
 			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
-			interrupt-parent = <&mpc5200_pic>;
 
 			phy0: ethernet-phy@0 {
-				device_type = "ethernet-phy";
 				reg = <0>;
 			};
 		};
 
 		ata@3a00 {
-			device_type = "ata";
 			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
 			reg = <0x3a00 0x100>;
 			interrupts = <2 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		i2c@3d00 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <0>;
 			reg = <0x3d00 0x40>;
 			interrupts = <2 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 		};
 
@@ -299,14 +258,13 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <1>;
 			reg = <0x3d40 0x40>;
 			interrupts = <2 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 		};
+
 		sram@8000 {
-			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram";
+			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
 			reg = <0x8000 0x4000>;
 		};
 	};
@@ -330,10 +288,48 @@
 				 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
 		clock-frequency = <0>; // From boot loader
 		interrupts = <2 8 0 2 9 0 2 10 0>;
-		interrupt-parent = <&mpc5200_pic>;
 		bus-range = <0 0>;
 		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
 			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
 			  0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
 	};
+
+	localbus {
+		compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		ranges = <0 0 0xfe000000 0x02000000>;
+
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x02000000>;
+			bank-width = <1>;
+			#size-cells = <1>;
+			#address-cells = <1>;
+
+			partition@0 {
+				label = "kernel";
+				reg = <0x00000000 0x00200000>;
+			};
+			partition@200000 {
+				label = "rootfs";
+				reg = <0x00200000 0x01d00000>;
+			};
+			partition@1f00000 {
+				label = "u-boot";
+				reg = <0x01f00000 0x00060000>;
+			};
+			partition@1f60000 {
+				label = "u-boot-env";
+				reg = <0x01f60000 0x00020000>;
+			};
+			partition@1f80000 {
+				label = "dtb";
+				reg = <0x01f80000 0x00080000>;
+			};
+		};
+	};
+
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/lite5200.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/lite5200.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/lite5200.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/lite5200.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 	compatible = "fsl,lite5200";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -58,96 +59,74 @@
 			// 5200 interrupts are encoded into two levels;
 			interrupt-controller;
 			#interrupt-cells = <3>;
-			device_type = "interrupt-controller";
 			compatible = "fsl,mpc5200-pic";
 			reg = <0x500 0x80>;
 		};
 
 		timer@600 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <0>;
 			reg = <0x600 0x10>;
 			interrupts = <1 9 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl,has-wdt;
 		};
 
 		timer@610 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <1>;
 			reg = <0x610 0x10>;
 			interrupts = <1 10 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@620 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <2>;
 			reg = <0x620 0x10>;
 			interrupts = <1 11 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@630 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <3>;
 			reg = <0x630 0x10>;
 			interrupts = <1 12 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@640 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <4>;
 			reg = <0x640 0x10>;
 			interrupts = <1 13 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@650 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <5>;
 			reg = <0x650 0x10>;
 			interrupts = <1 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@660 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <6>;
 			reg = <0x660 0x10>;
 			interrupts = <1 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@670 {	// General Purpose Timer
 			compatible = "fsl,mpc5200-gpt";
-			cell-index = <7>;
 			reg = <0x670 0x10>;
 			interrupts = <1 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200-rtc";
 			reg = <0x800 0x100>;
 			interrupts = <1 5 0 1 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		can@900 {
 			compatible = "fsl,mpc5200-mscan";
-			cell-index = <0>;
 			interrupts = <2 17 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x900 0x80>;
 		};
 
 		can@980 {
 			compatible = "fsl,mpc5200-mscan";
-			cell-index = <1>;
 			interrupts = <2 18 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x980 0x80>;
 		};
 
@@ -155,39 +134,33 @@
 			compatible = "fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
 			interrupts = <1 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		gpio@c00 {
 			compatible = "fsl,mpc5200-gpio-wkup";
 			reg = <0xc00 0x40>;
 			interrupts = <1 8 0 0 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		spi@f00 {
 			compatible = "fsl,mpc5200-spi";
 			reg = <0xf00 0x20>;
 			interrupts = <2 13 0 2 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
 			interrupts = <2 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		dma-controller@1200 {
-			device_type = "dma-controller";
 			compatible = "fsl,mpc5200-bestcomm";
 			reg = <0x1200 0x80>;
 			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
 			              3 4 0  3 5 0  3 6 0  3 7 0
 			              3 8 0  3 9 0  3 10 0  3 11 0
 			              3 12 0  3 13 0  3 14 0  3 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		xlb@1f00 {
@@ -196,13 +169,10 @@
 		};
 
 		serial@2000 {		// PSC1
-			device_type = "serial";
 			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <0>;  // Logical port assignment
 			cell-index = <0>;
 			reg = <0x2000 0x100>;
 			interrupts = <2 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		// PSC2 in ac97 mode example
@@ -211,7 +181,6 @@
 		//	cell-index = <1>;
 		//	reg = <0x2200 0x100>;
 		//	interrupts = <2 2 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC3 in CODEC mode example
@@ -220,27 +189,22 @@
 		//	cell-index = <2>;
 		//	reg = <0x2400 0x100>;
 		//	interrupts = <2 3 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC4 in uart mode example
 		//serial@2600 {		// PSC4
-		//	device_type = "serial";
 		//	compatible = "fsl,mpc5200-psc-uart";
 		//	cell-index = <3>;
 		//	reg = <0x2600 0x100>;
 		//	interrupts = <2 11 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC5 in uart mode example
 		//serial@2800 {		// PSC5
-		//	device_type = "serial";
 		//	compatible = "fsl,mpc5200-psc-uart";
 		//	cell-index = <4>;
 		//	reg = <0x2800 0x100>;
 		//	interrupts = <2 12 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		// PSC6 in spi mode example
@@ -249,16 +213,13 @@
 		//	cell-index = <5>;
 		//	reg = <0x2c00 0x100>;
 		//	interrupts = <2 4 0>;
-		//	interrupt-parent = <&mpc5200_pic>;
 		//};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <2 5 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			phy-handle = <&phy0>;
 		};
 
@@ -268,30 +229,24 @@
 			compatible = "fsl,mpc5200-mdio";
 			reg = <0x3000 0x400>;	// fec range, since we need to setup fec interrupts
 			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
-			interrupt-parent = <&mpc5200_pic>;
 
 			phy0: ethernet-phy@1 {
-				device_type = "ethernet-phy";
 				reg = <1>;
 			};
 		};
 
 		ata@3a00 {
-			device_type = "ata";
 			compatible = "fsl,mpc5200-ata";
 			reg = <0x3a00 0x100>;
 			interrupts = <2 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		i2c@3d00 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <0>;
 			reg = <0x3d00 0x40>;
 			interrupts = <2 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 		};
 
@@ -299,14 +254,12 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <1>;
 			reg = <0x3d40 0x40>;
 			interrupts = <2 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 		};
 		sram@8000 {
-			compatible = "fsl,mpc5200-sram","sram";
+			compatible = "fsl,mpc5200-sram";
 			reg = <0x8000 0x4000>;
 		};
 	};
@@ -325,7 +278,6 @@
 				 0xc000 0 0 4 &mpc5200_pic 0 0 3>;
 		clock-frequency = <0>; // From boot loader
 		interrupts = <2 8 0 2 9 0 2 10 0>;
-		interrupt-parent = <&mpc5200_pic>;
 		bus-range = <0 0>;
 		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
 			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/media5200.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/media5200.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/media5200.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/media5200.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,318 @@
+/*
+ * Freescale Media5200 board Device Tree Source
+ *
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ * Grant Likely <grant.likely@secretlab.ca>
+ * Steven Cavanagh <scavanagh@secretlab.ca>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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,media5200";
+	compatible = "fsl,media5200";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
+
+	aliases {
+		console = &console;
+		ethernet0 = &eth0;
+	};
+
+	chosen {
+		linux,stdout-path = &console;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,5200@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x4000>;		// L1, 16K
+			i-cache-size = <0x4000>;		// L1, 16K
+			timebase-frequency = <33000000>;	// 33 MHz, these were configured by U-Boot
+			bus-frequency = <132000000>;		// 132 MHz
+			clock-frequency = <396000000>;		// 396 MHz
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x08000000>;	// 128MB RAM
+	};
+
+	soc@f0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc5200b-immr";
+		ranges = <0 0xf0000000 0x0000c000>;
+		reg = <0xf0000000 0x00000100>;
+		bus-frequency = <132000000>;// 132 MHz
+		system-frequency = <0>;		// from bootloader
+
+		cdm@200 {
+			compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+			reg = <0x200 0x38>;
+		};
+
+		mpc5200_pic: interrupt-controller@500 {
+			// 5200 interrupts are encoded into two levels;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+			reg = <0x500 0x80>;
+		};
+
+		timer@600 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x600 0x10>;
+			interrupts = <1 9 0>;
+			fsl,has-wdt;
+		};
+
+		timer@610 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x610 0x10>;
+			interrupts = <1 10 0>;
+		};
+
+		timer@620 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x620 0x10>;
+			interrupts = <1 11 0>;
+		};
+
+		timer@630 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x630 0x10>;
+			interrupts = <1 12 0>;
+		};
+
+		timer@640 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x640 0x10>;
+			interrupts = <1 13 0>;
+		};
+
+		timer@650 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x650 0x10>;
+			interrupts = <1 14 0>;
+		};
+
+		timer@660 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x660 0x10>;
+			interrupts = <1 15 0>;
+		};
+
+		timer@670 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x670 0x10>;
+			interrupts = <1 16 0>;
+		};
+
+		rtc@800 {	// Real time clock
+			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
+			reg = <0x800 0x100>;
+			interrupts = <1 5 0 1 6 0>;
+		};
+
+		can@900 {
+			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+			interrupts = <2 17 0>;
+			reg = <0x900 0x80>;
+		};
+
+		can@980 {
+			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+			interrupts = <2 18 0>;
+			reg = <0x980 0x80>;
+		};
+
+		gpio_simple: gpio@b00 {
+			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+			reg = <0xb00 0x40>;
+			interrupts = <1 7 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpio_wkup: gpio@c00 {
+			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+			reg = <0xc00 0x40>;
+			interrupts = <1 8 0 0 3 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		spi@f00 {
+			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+			reg = <0xf00 0x20>;
+			interrupts = <2 13 0 2 14 0>;
+		};
+
+		usb@1000 {
+			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+			reg = <0x1000 0x100>;
+			interrupts = <2 6 0>;
+		};
+
+		dma-controller@1200 {
+			compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+			reg = <0x1200 0x80>;
+			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+			              3 4 0  3 5 0  3 6 0  3 7 0
+			              3 8 0  3 9 0  3 10 0  3 11 0
+			              3 12 0  3 13 0  3 14 0  3 15 0>;
+		};
+
+		xlb@1f00 {
+			compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+			reg = <0x1f00 0x100>;
+		};
+
+		// PSC6 in uart mode
+		console: serial@2c00 {		// PSC6
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+			cell-index = <5>;
+			port-number = <0>;  // Logical port assignment
+			reg = <0x2c00 0x100>;
+			interrupts = <2 4 0>;
+		};
+
+		eth0: ethernet@3000 {
+			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+			reg = <0x3000 0x400>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <2 5 0>;
+			phy-handle = <&phy0>;
+		};
+
+		mdio@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+			reg = <0x3000 0x400>;	// fec range, since we need to setup fec interrupts
+			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
+
+			phy0: ethernet-phy@0 {
+				reg = <0>;
+			};
+		};
+
+		ata@3a00 {
+			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+			reg = <0x3a00 0x100>;
+			interrupts = <2 7 0>;
+		};
+
+		i2c@3d00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+			reg = <0x3d00 0x40>;
+			interrupts = <2 15 0>;
+			fsl5200-clocking;
+		};
+
+		i2c@3d40 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+			reg = <0x3d40 0x40>;
+			interrupts = <2 16 0>;
+			fsl5200-clocking;
+		};
+
+		sram@8000 {
+			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+			reg = <0x8000 0x4000>;
+		};
+	};
+
+	pci@f0000d00 {
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+		reg = <0xf0000d00 0x100>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0xc000 0 0 1 &media5200_fpga 0 2 // 1st slot
+				 0xc000 0 0 2 &media5200_fpga 0 3
+				 0xc000 0 0 3 &media5200_fpga 0 4
+				 0xc000 0 0 4 &media5200_fpga 0 5
+
+				 0xc800 0 0 1 &media5200_fpga 0 3 // 2nd slot
+				 0xc800 0 0 2 &media5200_fpga 0 4
+				 0xc800 0 0 3 &media5200_fpga 0 5
+				 0xc800 0 0 4 &media5200_fpga 0 2
+
+				 0xd000 0 0 1 &media5200_fpga 0 4 // miniPCI
+				 0xd000 0 0 2 &media5200_fpga 0 5
+
+				 0xe000 0 0 1 &media5200_fpga 0 5 // CoralIP
+				>;
+		clock-frequency = <0>; // From boot loader
+		interrupts = <2 8 0 2 9 0 2 10 0>;
+		interrupt-parent = <&mpc5200_pic>;
+		bus-range = <0 0>;
+		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
+	};
+
+	localbus {
+		compatible = "fsl,mpc5200b-lpb","simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		ranges = < 0 0 0xfc000000 0x02000000
+			   1 0 0xfe000000 0x02000000
+			   2 0 0xf0010000 0x00010000
+			   3 0 0xf0020000 0x00010000 >;
+
+		flash@0,0 {
+			compatible = "amd,am29lv28ml", "cfi-flash";
+			reg = <0 0x0 0x2000000>;		// 32 MB
+			bank-width = <4>;			// Width in bytes of the flash bank
+			device-width = <2>;			// Two devices on each bank
+		};
+
+		flash@1,0 {
+			compatible = "amd,am29lv28ml", "cfi-flash";
+			reg = <1 0 0x2000000>;			// 32 MB
+			bank-width = <4>;			// Width in bytes of the flash bank
+			device-width = <2>;			// Two devices on each bank
+		};
+
+		media5200_fpga: fpga@2,0 {
+			compatible = "fsl,media5200-fpga";
+			interrupt-controller;
+			#interrupt-cells = <2>;	// 0:bank 1:id; no type field
+			reg = <2 0 0x10000>;
+
+			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <0 0 3	// IRQ bank 0
+			              1 1 3>;	// IRQ bank 1
+		};
+
+		uart@3,0 {
+			compatible = "ti,tl16c752bpt";
+			reg = <3 0 0x10000>;
+			interrupt-parent = <&media5200_fpga>;
+			interrupts = <0 0  0 1>; // 2 irqs
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/motionpro.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/motionpro.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/motionpro.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/motionpro.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 	compatible = "promess,motionpro";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -66,7 +67,6 @@
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x600 0x10>;
 			interrupts = <1 9 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl,has-wdt;
 		};
 
@@ -74,35 +74,30 @@
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x610 0x10>;
 			interrupts = <1 10 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@620 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x620 0x10>;
 			interrupts = <1 11 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@630 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x630 0x10>;
 			interrupts = <1 12 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@640 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x640 0x10>;
 			interrupts = <1 13 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		timer@650 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			reg = <0x650 0x10>;
 			interrupts = <1 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		motionpro-led@660 {	// Motion-PRO status LED
@@ -110,7 +105,6 @@
 			label = "motionpro-statusled";
 			reg = <0x660 0x10>;
 			interrupts = <1 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			blink-delay = <100>; // 100 msec
 		};
 
@@ -119,49 +113,46 @@
 			label = "motionpro-readyled";
 			reg = <0x670 0x10>;
 			interrupts = <1 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
 			reg = <0x800 0x100>;
 			interrupts = <1 5 0 1 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		can@980 {
 			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
 			interrupts = <2 18 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x980 0x80>;
 		};
 
-		gpio@b00 {
+		gpio_simple: gpio@b00 {
 			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
 			interrupts = <1 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
-		gpio@c00 {
+		gpio_wkup: gpio@c00 {
 			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
 			reg = <0xc00 0x40>;
 			interrupts = <1 8 0 0 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		spi@f00 {
 			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
 			reg = <0xf00 0x20>;
 			interrupts = <2 13 0 2 14 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
 			interrupts = <2 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		dma-controller@1200 {
@@ -171,7 +162,6 @@
 			              3 4 0  3 5 0  3 6 0  3 7 0
 			              3 8 0  3 9 0  3 10 0  3 11 0
 			              3 12 0  3 13 0  3 14 0  3 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		xlb@1f00 {
@@ -180,12 +170,9 @@
 		};
 
 		serial@2000 {		// PSC1
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <0>;  // Logical port assignment
 			reg = <0x2000 0x100>;
 			interrupts = <2 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		// PSC2 in spi master mode 
@@ -194,26 +181,20 @@
 			cell-index = <1>;
 			reg = <0x2200 0x100>;
 			interrupts = <2 2 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		// PSC5 in uart mode
 		serial@2800 {		// PSC5
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <4>;  // Logical port assignment
 			reg = <0x2800 0x100>;
 			interrupts = <2 12 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <2 5 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			phy-handle = <&phy0>;
 		};
 
@@ -223,10 +204,8 @@
 			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
 			reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
 			interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
-			interrupt-parent = <&mpc5200_pic>;
 
 			phy0: ethernet-phy@2 {
-				device_type = "ethernet-phy";
 				reg = <2>;
 			};
 		};
@@ -235,7 +214,6 @@
 			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
 			reg = <0x3a00 0x100>;
 			interrupts = <2 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		i2c@3d40 {
@@ -244,7 +222,6 @@
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
 			reg = <0x3d40 0x40>;
 			interrupts = <2 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 
 			rtc@68 {
@@ -259,8 +236,8 @@
 		};
 	};
 
-	lpb {
-		compatible = "fsl,lpb";
+	localbus {
+		compatible = "fsl,mpc5200b-lpb","simple-bus";
 		#address-cells = <2>;
 		#size-cells = <1>;
 		ranges = <0 0 0xff000000 0x01000000
@@ -273,7 +250,6 @@
 			compatible = "promess,motionpro-kollmorgen";
 			reg = <1 0 0x10000>;
 			interrupts = <1 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		// 8-bit board CPLD on LocalPlus Bus CS2
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8313erdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8313erdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8313erdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8313erdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -180,7 +180,7 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 			sleep = <&pmc 0x20000000>;
-			ranges;
+			ranges = <0x0 0x24000 0x1000>;
 
 			cell-index = <0>;
 			device_type = "network";
@@ -195,11 +195,11 @@
 			fixed-link = <1 1 1000 0 0>;
 			fsl,magic-packet;
 
-			mdio@24520 {
+			mdio@520 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,gianfar-mdio";
-				reg = <0x24520 0x20>;
+				reg = <0x520 0x20>;
 				phy4: ethernet-phy@4 {
 					interrupt-parent = <&ipic>;
 					interrupts = <20 0x8>;
@@ -221,6 +221,7 @@
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <34 0x8 33 0x8 32 0x8>;
 			interrupt-parent = <&ipic>;
@@ -229,11 +230,11 @@
 			sleep = <&pmc 0x10000000>;
 			fsl,magic-packet;
 
-			mdio@25520 {
+			mdio@520 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,gianfar-tbi";
-				reg = <0x25520 0x20>;
+				reg = <0x520 0x20>;
 
 				tbi1: tbi-phy@11 {
 					reg = <0x11>;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8315erdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,8 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
 	};
 
 	cpus {
@@ -188,66 +190,74 @@
 			phy_type = "utmi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&ipic>;
-				interrupts = <20 0x8>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&ipic>;
-				interrupts = <19 0x8>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		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 = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = < &phy0 >;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&ipic>;
+					interrupts = <20 0x8>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&ipic>;
+					interrupts = <19 0x8>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = < &phy1 >;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -349,4 +359,66 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb1000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa0000000
+				  0x02000000 0 0xa0000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc0000000 0xc0000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd1000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc0000000
+				  0x02000000 0 0xc0000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc832x_rdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -152,10 +152,21 @@
 		};
 
 		par_io@1400 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			reg = <0x1400 0x100>;
+			ranges = <3 0x1448 0x18>;
+			compatible = "fsl,mpc8323-qe-pario";
 			device_type = "par_io";
 			num-ports = <7>;
 
+			qe_pio_d: gpio-controller@1448 {
+				#gpio-cells = <2>;
+				compatible = "fsl,mpc8323-qe-pario-bank";
+				reg = <3 0x18>;
+				gpio-controller;
+			};
+
 			ucc2pio:ucc_pin@02 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
@@ -225,12 +236,25 @@
 		};
 
 		spi@4c0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
 			cell-index = <0>;
 			compatible = "fsl,spi";
 			reg = <0x4c0 0x40>;
 			interrupts = <2>;
 			interrupt-parent = <&qeic>;
+			gpios = <&qe_pio_d 13 0>;
 			mode = "cpu-qe";
+
+			mmc-slot@0 {
+				compatible = "fsl,mpc8323rdb-mmc-slot",
+					     "mmc-spi-slot";
+				reg = <0>;
+				gpios = <&qe_pio_d 14 1
+					 &qe_pio_d 15 0>;
+				voltage-ranges = <3300 3300>;
+				spi-max-frequency = <50000000>;
+			};
 		};
 
 		spi@500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2009-06-09 23:05:27.000000000 -0400
@@ -170,57 +170,52 @@
 			phy_type = "ulpi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			/* Vitesse 8201 */
-			phy1c: ethernet-phy@1c {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x1c>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy1c>;
 			linux,network-index = <0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				/* Vitesse 8201 */
+				phy1c: ethernet-phy@1c {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x1c>;
+					device_type = "ethernet-phy";
+				};
+
+				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 = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <35 0x8 36 0x8 37 0x8>;
 			interrupt-parent = <&ipic>;
@@ -228,6 +223,18 @@
 			fixed-link = <1 1 1000 0 0>;
 			linux,network-index = <1>;
 			tbi-handle = <&tbi1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8349emitxgp.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitxgp.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8349emitxgp.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitxgp.dts	2009-06-09 23:05:27.000000000 -0400
@@ -149,37 +149,41 @@
 			phy_type = "ulpi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			/* Vitesse 8201 */
-			phy1c: ethernet-phy@1c {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x1c>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy1c>;
 			linux,network-index = <0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				/* Vitesse 8201 */
+				phy1c: ethernet-phy@1c {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x1c>;
+					device_type = "ethernet-phy";
+				};
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -167,69 +167,76 @@
 			phy_type = "ulpi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			linux,network-index = <0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+
+				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 = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <35 0x8 36 0x8 37 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
 			linux,network-index = <1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8377_mds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8377_mds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8377_mds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8377_mds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,8 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
 	};
 
 	cpus {
@@ -127,21 +129,38 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
+		sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
-			interrupt-parent = <&ipic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
-				interrupts = <19 0x8>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
 				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <19 0x8>;
+					interrupt-parent = <&ipic>;
+				};
+			};
+
+			sdhci@2e000 {
+				compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -174,70 +193,83 @@
 			interrupts = <38 0x8>;
 			dr_mode = "host";
 			phy_type = "ulpi";
+			sleep = <&pmc 0x00c00000>;
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy3>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -309,14 +341,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
-
-		sdhc@2e000 {
-			model = "eSDHC";
-			compatible = "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <42 0x8>;
-			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		sata@18000 {
@@ -324,6 +349,7 @@
 			reg = <0x18000 0x1000>;
 			interrupts = <44 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x000000c0>;
 		};
 
 		sata@19000 {
@@ -331,6 +357,7 @@
 			reg = <0x19000 0x1000>;
 			interrupts = <45 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000030>;
 		};
 
 		/* IPIC
@@ -346,6 +373,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -400,6 +434,7 @@
 		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
 		clock-frequency = <0>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -409,4 +444,68 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		sleep = <&pmc 0x00300000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa8000000
+				  0x02000000 0 0xa8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		sleep = <&pmc 0x000c0000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc8000000
+				  0x02000000 0 0xc8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8377_rdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8377_rdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8377_rdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8377_rdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,8 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
 	};
 
 	cpus {
@@ -107,26 +109,72 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
+		gpio1: gpio-controller@c00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+			reg = <0xc00 0x100>;
+			interrupts = <74 0x8>;
 			interrupt-parent = <&ipic>;
-			dfsrr;
-			rtc@68 {
-				compatible = "dallas,ds1339";
-				reg = <0x68>;
+			gpio-controller;
+		};
+
+		gpio2: gpio-controller@d00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+			reg = <0xd00 0x100>;
+			interrupts = <75 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
+
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
+				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				dtt@48 {
+					compatible = "national,lm75";
+					reg = <0x48>;
+				};
+
+				at24@50 {
+					compatible = "at24,24c256";
+					reg = <0x50>;
+				};
+
+				rtc@68 {
+					compatible = "dallas,ds1339";
+					reg = <0x68>;
+				};
+
+				mcu_pio: mcu@a {
+					#gpio-cells = <2>;
+					compatible = "fsl,mc9s08qg8-mpc8377erdb",
+						     "fsl,mcu-mpc8349emitx";
+					reg = <0x0a>;
+					gpio-controller;
+				};
 			};
 
-			mcu_pio: mcu@a {
-				#gpio-cells = <2>;
-				compatible = "fsl,mc9s08qg8-mpc8377erdb",
-					     "fsl,mcu-mpc8349emitx";
-				reg = <0x0a>;
-				gpio-controller;
+			sdhci@2e000 {
+				compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -197,64 +245,76 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <38 0x8>;
 			phy_type = "ulpi";
+			sleep = <&pmc 0x00c00000>;
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			fixed-link = <1 1 1000 0 0>;
 			tbi-handle = <&tbi1>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -287,6 +347,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		sata@18000 {
@@ -294,6 +355,7 @@
 			reg = <0x18000 0x1000>;
 			interrupts = <44 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x000000c0>;
 		};
 
 		sata@19000 {
@@ -301,6 +363,7 @@
 			reg = <0x19000 0x1000>;
 			interrupts = <45 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000030>;
 		};
 
 		/* IPIC
@@ -316,6 +379,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -341,6 +411,7 @@
 		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -350,4 +421,68 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		sleep = <&pmc 0x00300000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa8000000
+				  0x02000000 0 0xa8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		sleep = <&pmc 0x000c0000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc8000000
+				  0x02000000 0 0xc8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8378_mds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8378_mds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8378_mds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8378_mds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,8 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
 	};
 
 	cpus {
@@ -127,21 +129,38 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
+		sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
-			interrupt-parent = <&ipic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
-				interrupts = <19 0x8>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
 				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <19 0x8>;
+					interrupt-parent = <&ipic>;
+				};
+			};
+
+			sdhci@2e000 {
+				compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -213,70 +232,83 @@
 			interrupts = <38 0x8>;
 			dr_mode = "host";
 			phy_type = "ulpi";
+			sleep = <&pmc 0x00c00000>;
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy3>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -309,14 +341,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
-
-		sdhc@2e000 {
-			model = "eSDHC";
-			compatible = "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <42 0x8>;
-			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		/* IPIC
@@ -332,6 +357,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -387,6 +419,7 @@
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
 		clock-frequency = <0>;
+		sleep = <&pmc 0x00010000>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
 		#address-cells = <3>;
@@ -395,4 +428,68 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		sleep = <&pmc 0x00300000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa8000000
+				  0x02000000 0 0xa8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		sleep = <&pmc 0x000c0000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc8000000
+				  0x02000000 0 0xc8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8378_rdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8378_rdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8378_rdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8378_rdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,8 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
 	};
 
 	cpus {
@@ -107,26 +109,72 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
+		gpio1: gpio-controller@c00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio";
+			reg = <0xc00 0x100>;
+			interrupts = <74 0x8>;
 			interrupt-parent = <&ipic>;
-			dfsrr;
-			rtc@68 {
-				compatible = "dallas,ds1339";
-				reg = <0x68>;
+			gpio-controller;
+		};
+
+		gpio2: gpio-controller@d00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio";
+			reg = <0xd00 0x100>;
+			interrupts = <75 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
+
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
+				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				dtt@48 {
+					compatible = "national,lm75";
+					reg = <0x48>;
+				};
+
+				at24@50 {
+					compatible = "at24,24c256";
+					reg = <0x50>;
+				};
+
+				rtc@68 {
+					compatible = "dallas,ds1339";
+					reg = <0x68>;
+				};
+
+				mcu_pio: mcu@a {
+					#gpio-cells = <2>;
+					compatible = "fsl,mc9s08qg8-mpc8378erdb",
+						     "fsl,mcu-mpc8349emitx";
+					reg = <0x0a>;
+					gpio-controller;
+				};
 			};
 
-			mcu_pio: mcu@a {
-				#gpio-cells = <2>;
-				compatible = "fsl,mc9s08qg8-mpc8378erdb",
-					     "fsl,mcu-mpc8349emitx";
-				reg = <0x0a>;
-				gpio-controller;
+			sdhci@2e000 {
+				compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -197,62 +245,76 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <38 0x8>;
 			phy_type = "ulpi";
+			sleep = <&pmc 0x00c00000>;
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
+			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			fixed-link = <1 1 1000 0 0>;
+			tbi-handle = <&tbi1>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -285,6 +347,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		/* IPIC
@@ -300,6 +363,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -325,6 +395,7 @@
 		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
@@ -334,4 +405,68 @@
 		compatible = "fsl,mpc8349-pci";
 		device_type = "pci";
 	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		sleep = <&pmc 0x00300000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa8000000
+				  0x02000000 0 0xa8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		sleep = <&pmc 0x000c0000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc8000000
+				  0x02000000 0 0xc8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8379_mds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8379_mds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8379_mds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8379_mds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -127,21 +127,38 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
+		sleep-nexus {
 			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
-			interrupt-parent = <&ipic>;
-			dfsrr;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
 
-			rtc@68 {
-				compatible = "dallas,ds1374";
-				reg = <0x68>;
-				interrupts = <19 0x8>;
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
 				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				rtc@68 {
+					compatible = "dallas,ds1374";
+					reg = <0x68>;
+					interrupts = <19 0x8>;
+					interrupt-parent = <&ipic>;
+				};
+			};
+
+			sdhci@2e000 {
+				compatible = "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -213,69 +230,83 @@
 			interrupts = <38 0x8>;
 			dr_mode = "host";
 			phy_type = "ulpi";
-		};
-
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&ipic>;
-				interrupts = <18 0x8>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
+			sleep = <&pmc 0x00c00000>;
 		};
 
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy3>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -308,14 +339,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
-
-		sdhc@2e000 {
-			model = "eSDHC";
-			compatible = "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <42 0x8>;
-			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		sata@18000 {
@@ -323,6 +347,7 @@
 			reg = <0x18000 0x1000>;
 			interrupts = <44 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x000000c0>;
 		};
 
 		sata@19000 {
@@ -330,6 +355,7 @@
 			reg = <0x19000 0x1000>;
 			interrupts = <45 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000030>;
 		};
 
 		sata@1a000 {
@@ -337,6 +363,7 @@
 			reg = <0x1a000 0x1000>;
 			interrupts = <46 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x0000000c>;
 		};
 
 		sata@1b000 {
@@ -344,6 +371,7 @@
 			reg = <0x1b000 0x1000>;
 			interrupts = <47 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000003>;
 		};
 
 		/* IPIC
@@ -359,6 +387,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -413,6 +448,7 @@
 		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
 		clock-frequency = <0>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8379_rdb.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8379_rdb.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8379_rdb.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8379_rdb.dts	2009-06-09 23:05:27.000000000 -0400
@@ -107,26 +107,72 @@
 			reg = <0x200 0x100>;
 		};
 
-		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <14 0x8>;
+		gpio1: gpio-controller@c00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio";
+			reg = <0xc00 0x100>;
+			interrupts = <74 0x8>;
 			interrupt-parent = <&ipic>;
-			dfsrr;
-			rtc@68 {
-				compatible = "dallas,ds1339";
-				reg = <0x68>;
+			gpio-controller;
+		};
+
+		gpio2: gpio-controller@d00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio";
+			reg = <0xd00 0x100>;
+			interrupts = <75 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
+
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
+				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				dtt@48 {
+					compatible = "national,lm75";
+					reg = <0x48>;
+				};
+
+				at24@50 {
+					compatible = "at24,24c256";
+					reg = <0x50>;
+				};
+
+				rtc@68 {
+					compatible = "dallas,ds1339";
+					reg = <0x68>;
+				};
+
+				mcu_pio: mcu@a {
+					#gpio-cells = <2>;
+					compatible = "fsl,mc9s08qg8-mpc8379erdb",
+						     "fsl,mcu-mpc8349emitx";
+					reg = <0x0a>;
+					gpio-controller;
+				};
 			};
 
-			mcu_pio: mcu@a {
-				#gpio-cells = <2>;
-				compatible = "fsl,mc9s08qg8-mpc8379erdb",
-					     "fsl,mcu-mpc8349emitx";
-				reg = <0x0a>;
-				gpio-controller;
+			sdhci@2e000 {
+				compatible = "fsl,mpc8379-esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				/* Filled in by U-Boot */
+				clock-frequency = <0>;
 			};
 		};
 
@@ -197,63 +243,76 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <38 0x8>;
 			phy_type = "ulpi";
-		};
-
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&ipic>;
-				interrupts = <17 0x8>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
+			sleep = <&pmc 0x00c00000>;
 		};
 
 		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 = <32 0x8 33 0x8 34 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				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 0x8 36 0x8 37 0x8>;
 			phy-connection-type = "mii";
 			interrupt-parent = <&ipic>;
 			fixed-link = <1 1 1000 0 0>;
 			tbi-handle = <&tbi1>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -286,6 +345,7 @@
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x9fe>;
 			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x03000000>;
 		};
 
 		sata@18000 {
@@ -293,6 +353,7 @@
 			reg = <0x18000 0x1000>;
 			interrupts = <44 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x000000c0>;
 		};
 
 		sata@19000 {
@@ -300,6 +361,7 @@
 			reg = <0x19000 0x1000>;
 			interrupts = <45 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000030>;
 		};
 
 		sata@1a000 {
@@ -307,6 +369,7 @@
 			reg = <0x1a000 0x1000>;
 			interrupts = <46 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x0000000c>;
 		};
 
 		sata@1b000 {
@@ -314,6 +377,7 @@
 			reg = <0x1b000 0x1000>;
 			interrupts = <47 0x8>;
 			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000003>;
 		};
 
 		/* IPIC
@@ -329,6 +393,13 @@
 			#interrupt-cells = <2>;
 			reg = <0x700 0x100>;
 		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
 	};
 
 	pci0: pci@e0008500 {
@@ -354,6 +425,7 @@
 		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
 		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
 		          0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8536ds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8536ds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8536ds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8536ds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -137,42 +137,6 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 0x1>;
-				reg = <0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 0x1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		usb@22000 {
 			compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph";
 			reg = <0x22000 0x1000>;
@@ -194,31 +158,73 @@
 		};
 
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 0x1>;
+					reg = <0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 0x1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet1: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <1>;
 			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>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		usb@2b000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8540ads.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8540ads.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8540ads.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8540ads.dts	2009-06-09 23:05:27.000000000 -0400
@@ -126,97 +126,106 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <7 1>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <7 1>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <2>;
 			device_type = "network";
 			model = "FEC";
 			compatible = "gianfar";
 			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <41 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy3>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8541cds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8541cds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8541cds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8541cds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -126,66 +126,72 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8544ds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8544ds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8544ds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8544ds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -98,44 +98,6 @@
 			dfsrr;
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		dma@21300 {
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -178,31 +140,74 @@
 		};
 
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			phy-handle = <&phy0>;
 			tbi-handle = <&tbi0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet1: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <1>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi1>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8548cds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8548cds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8548cds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8548cds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -142,129 +142,141 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+				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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 /* eTSEC 3/4 are currently broken
 		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>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
 			phy-handle = <&phy3>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
  */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8555cds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8555cds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8555cds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8555cds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -126,66 +126,72 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8560ads.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8560ads.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8560ads.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8560ads.dts	2009-06-09 23:05:27.000000000 -0400
@@ -115,78 +115,84 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <7 1>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <7 1>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <7 1>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <7 1>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		mpic: pic@40000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8568mds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -149,78 +149,84 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@7 {
-				interrupt-parent = <&mpic>;
-				interrupts = <1 1>;
-				reg = <0x7>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <2 1>;
-				reg = <0x1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <1 1>;
-				reg = <0x2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <2 1>;
-				reg = <0x3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@7 {
+					interrupt-parent = <&mpic>;
+					interrupts = <1 1>;
+					reg = <0x7>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <2 1>;
+					reg = <0x1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <1 1>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <2 1>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+				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 = <&tbi1>;
 			phy-handle = <&phy3>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_36b.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_36b.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_36b.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_36b.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,799 @@
+/*
+ * MPC8572 DS Device Tree Source
+ *
+ * Copyright 2007-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,MPC8572DS";
+	compatible = "fsl,MPC8572DS";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		ethernet3 = &enet3;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8572@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <0x8000>;		// L1, 32K
+			i-cache-size = <0x8000>;		// L1, 32K
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,8572@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			d-cache-line-size = <32>;	// 32 bytes
+			i-cache-line-size = <32>;	// 32 bytes
+			d-cache-size = <0x8000>;		// L1, 32K
+			i-cache-size = <0x8000>;		// L1, 32K
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@fffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus";
+		reg = <0xf 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
+			  0x1 0x0 0xf 0xe0000000 0x08000000
+			  0x2 0x0 0xf 0xffa00000 0x00040000
+			  0x3 0x0 0xf 0xffdf0000 0x00008000
+			  0x4 0x0 0xf 0xffa40000 0x00040000
+			  0x5 0x0 0xf 0xffa80000 0x00040000
+			  0x6 0x0 0xf 0xffac0000 0x00040000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x8000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			ramdisk@0 {
+				reg = <0x0 0x03000000>;
+				read-only;
+			};
+
+			diagnostic@3000000 {
+				reg = <0x03000000 0x00e00000>;
+				read-only;
+			};
+
+			dink@3e00000 {
+				reg = <0x03e00000 0x00200000>;
+				read-only;
+			};
+
+			kernel@4000000 {
+				reg = <0x04000000 0x00400000>;
+				read-only;
+			};
+
+			jffs2@4400000 {
+				reg = <0x04400000 0x03b00000>;
+			};
+
+			dtb@7f00000 {
+				reg = <0x07f00000 0x00080000>;
+				read-only;
+			};
+
+			u-boot@7f80000 {
+				reg = <0x07f80000 0x00080000>;
+				read-only;
+			};
+		};
+
+		nand@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8572-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x2 0x0 0x40000>;
+
+			u-boot@0 {
+				reg = <0x0 0x02000000>;
+				read-only;
+			};
+
+			jffs2@2000000 {
+				reg = <0x02000000 0x10000000>;
+			};
+
+			ramdisk@12000000 {
+				reg = <0x12000000 0x08000000>;
+				read-only;
+			};
+
+			kernel@1a000000 {
+				reg = <0x1a000000 0x04000000>;
+			};
+
+			dtb@1e000000 {
+				reg = <0x1e000000 0x01000000>;
+				read-only;
+			};
+
+			empty@1f000000 {
+				reg = <0x1f000000 0x21000000>;
+			};
+		};
+
+		nand@4,0 {
+			compatible = "fsl,mpc8572-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x4 0x0 0x40000>;
+		};
+
+		nand@5,0 {
+			compatible = "fsl,mpc8572-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x5 0x0 0x40000>;
+		};
+
+		nand@6,0 {
+			compatible = "fsl,mpc8572-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x6 0x0 0x40000>;
+		};
+	};
+
+	soc8572@fffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0x0 0xf 0xffe00000 0x100000>;
+		reg = <0xf 0xffe00000 0 0x1000>;	// CCSRBAR & soc regs, remove once parse code for immrbase fixed
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		memory-controller@2000 {
+			compatible = "fsl,mpc8572-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		memory-controller@6000 {
+			compatible = "fsl,mpc8572-memory-controller";
+			reg = <0x6000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,mpc8572-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x100000>; // L2, 1M
+			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;
+		};
+
+		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@c300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+			reg = <0xc300 0x4>;
+			ranges = <0x0 0xc100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <76 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <77 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <78 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <79 2>;
+			};
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8572-dma-channel",
+						"fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		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>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x1>;
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x2>;
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x3>;
+				};
+
+				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 = <&tbi1>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		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>;
+			tbi-handle = <&tbi2>;
+			phy-handle = <&phy2>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <3>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <37 2 38 2 39 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi3>;
+			phy-handle = <&phy3>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		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,mpc8572-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+
+		msi@41600 {
+			compatible = "fsl,mpc8572-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>;
+		};
+
+		crypto@30000 {
+			compatible = "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 = <0x9fe>;
+			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";
+		};
+	};
+
+	pci0: pcie@fffe08000 {
+		cell-index = <0>;
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe08000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <24 2>;
+		interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x11 func 0 - PCI slot 1 */
+			0x8800 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8800 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8800 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 1 - PCI slot 1 */
+			0x8900 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8900 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8900 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8900 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 2 - PCI slot 1 */
+			0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 3 - PCI slot 1 */
+			0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 4 - PCI slot 1 */
+			0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 5 - PCI slot 1 */
+			0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 6 - PCI slot 1 */
+			0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x11 func 7 - PCI slot 1 */
+			0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1
+			0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1
+			0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1
+			0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+			/* IDSEL 0x12 func 0 - PCI slot 2 */
+			0x9000 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9000 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9000 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 1 - PCI slot 2 */
+			0x9100 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9100 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9100 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9100 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 2 - PCI slot 2 */
+			0x9200 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9200 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9200 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9200 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 3 - PCI slot 2 */
+			0x9300 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9300 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9300 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9300 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 4 - PCI slot 2 */
+			0x9400 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9400 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9400 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9400 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 5 - PCI slot 2 */
+			0x9500 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9500 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9500 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9500 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 6 - PCI slot 2 */
+			0x9600 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9600 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9600 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9600 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			/* IDSEL 0x12 func 7 - PCI slot 2 */
+			0x9700 0x0 0x0 0x1 &mpic 0x3 0x1
+			0x9700 0x0 0x0 0x2 &mpic 0x4 0x1
+			0x9700 0x0 0x0 0x3 &mpic 0x1 0x1
+			0x9700 0x0 0x0 0x4 &mpic 0x2 0x1
+
+			// IDSEL 0x1c  USB
+			0xe000 0x0 0x0 0x1 &i8259 0xc 0x2
+			0xe100 0x0 0x0 0x2 &i8259 0x9 0x2
+			0xe200 0x0 0x0 0x3 &i8259 0xa 0x2
+			0xe300 0x0 0x0 0x4 &i8259 0xb 0x2
+
+			// IDSEL 0x1d  Audio
+			0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+			// IDSEL 0x1e Legacy
+			0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+			0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+			// IDSEL 0x1f IDE/SATA
+			0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+			0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+
+			>;
+
+		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 0x10000>;
+			uli1575@0 {
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				#size-cells = <2>;
+				#address-cells = <3>;
+				ranges = <0x2000000 0x0 0xc0000000
+					  0x2000000 0x0 0xc0000000
+					  0x0 0x20000000
+
+					  0x1000000 0x0 0x0
+					  0x1000000 0x0 0x0
+					  0x0 0x10000>;
+				isa@1e {
+					device_type = "isa";
+					#interrupt-cells = <2>;
+					#size-cells = <1>;
+					#address-cells = <2>;
+					reg = <0xf000 0x0 0x0 0x0 0x0>;
+					ranges = <0x1 0x0 0x1000000 0x0 0x0
+						  0x1000>;
+					interrupt-parent = <&i8259>;
+
+					i8259: interrupt-controller@20 {
+						reg = <0x1 0x20 0x2
+						       0x1 0xa0 0x2
+						       0x1 0x4d0 0x2>;
+						interrupt-controller;
+						device_type = "interrupt-controller";
+						#address-cells = <0>;
+						#interrupt-cells = <2>;
+						compatible = "chrp,iic";
+						interrupts = <9 2>;
+						interrupt-parent = <&mpic>;
+					};
+
+					i8042@60 {
+						#size-cells = <0>;
+						#address-cells = <1>;
+						reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+						interrupts = <1 3 12 3>;
+						interrupt-parent =
+							<&i8259>;
+
+						keyboard@0 {
+							reg = <0x0>;
+							compatible = "pnpPNP,303";
+						};
+
+						mouse@1 {
+							reg = <0x1>;
+							compatible = "pnpPNP,f03";
+						};
+					};
+
+					rtc@70 {
+						compatible = "pnpPNP,b00";
+						reg = <0x1 0x70 0x2>;
+					};
+
+					gpio@400 {
+						reg = <0x1 0x400 0x80>;
+					};
+				};
+			};
+		};
+
+	};
+
+	pci1: pcie@fffe09000 {
+		cell-index = <1>;
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
+		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 0x10000>;
+		};
+	};
+
+	pci2: pcie@fffe0a000 {
+		cell-index = <2>;
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
+		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 0x10000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  * This dts file allows core0 to have memory, l2, i2c, dma1, global-util, eth0,
  * eth1, crypto, pci0, pci1.
  *
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-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
@@ -148,35 +148,38 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x0>;
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x1>;
-			};
-		};
-
 		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>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x1>;
+				};
+			};
 		};
 
 		enet1: ethernet@25000 {
@@ -227,7 +230,7 @@
 			device_type = "open-pic";
 			protected-sources = <
 			31 32 33 37 38 39       /* enet2 enet3 */
-			76 77 78 79 27 42	/* dma2 pci2 serial*/
+			76 77 78 79 26 42	/* dma2 pci2 serial*/
 			0xe0 0xe1 0xe2 0xe3     /* msi */
 			0xe4 0xe5 0xe6 0xe7
 			>;
@@ -376,7 +379,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 			uli1575@0 {
 				reg = <0x0 0x0 0x0 0x0 0x0>;
 				#size-cells = <2>;
@@ -387,7 +390,7 @@
 
 					  0x1000000 0x0 0x0
 					  0x1000000 0x0 0x0
-					  0x0 0x100000>;
+					  0x0 0x10000>;
 				isa@1e {
 					device_type = "isa";
 					#interrupt-cells = <2>;
@@ -477,7 +480,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 		};
 	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
  *
  * Please note to add "-b 1" for core1's dts compiling.
  *
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-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
@@ -186,7 +186,7 @@
 			protected-sources = <
 			18 16 10 42 45 58	/* MEM L2 mdio serial crypto */
 			29 30 34 35 36 40	/* enet0 enet1 */
-			24 26 20 21 22 23	/* pcie0 pcie1 dma1 */
+			24 25 20 21 22 23	/* pci0 pci1 dma1 */
 			43			/* i2c */
 			0x1 0x2 0x3 0x4         /* pci slot */
 			0x9 0xa 0xb 0xc         /* usb */
@@ -228,7 +228,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 		};
 	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8572ds.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8572ds.dts	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * MPC8572 DS Device Tree Source
  *
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-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
@@ -312,129 +312,141 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x0>;
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x1>;
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x2>;
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x3>;
-			};
-
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x1>;
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x2>;
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x3>;
+				};
+
+				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 = <&tbi1>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		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>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy2>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
 			phy-handle = <&phy3>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -643,7 +655,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 			uli1575@0 {
 				reg = <0x0 0x0 0x0 0x0 0x0>;
 				#size-cells = <2>;
@@ -654,7 +666,7 @@
 
 					  0x1000000 0x0 0x0
 					  0x1000000 0x0 0x0
-					  0x0 0x100000>;
+					  0x0 0x10000>;
 				isa@1e {
 					device_type = "isa";
 					#interrupt-cells = <2>;
@@ -744,7 +756,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 		};
 	};
 
@@ -781,7 +793,7 @@
 
 				  0x1000000 0x0 0x0
 				  0x1000000 0x0 0x0
-				  0x0 0x100000>;
+				  0x0 0x10000>;
 		};
 	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8610_hpcd.dts	2009-06-09 23:05:27.000000000 -0400
@@ -217,6 +217,7 @@
 			codec-handle = <&cs4270>;
 			fsl,playback-dma = <&dma00>;
 			fsl,capture-dma = <&dma01>;
+			fsl,fifo-depth = <8>;
 		};
 
 		ssi@16100 {
@@ -225,6 +226,7 @@
 			reg = <0x16100 0x100>;
 			interrupt-parent = <&mpic>;
 			interrupts = <63 2>;
+			fsl,fifo-depth = <8>;
 		};
 
 		dma@21300 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8641_hpcn.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8641_hpcn.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/mpc8641_hpcn.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8641_hpcn.dts	2009-06-09 23:05:27.000000000 -0400
@@ -180,133 +180,144 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 		
 		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <2>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy2>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
 			phy-handle = <&phy3>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pcm030.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pcm030.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pcm030.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pcm030.dts	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 	compatible = "phytec,pcm030";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -29,26 +30,26 @@
 			reg = <0>;
 			d-cache-line-size = <32>;
 			i-cache-line-size = <32>;
-			d-cache-size = <0x4000>;	/* L1, 16K          */
-			i-cache-size = <0x4000>;	/* L1, 16K          */
-			timebase-frequency = <0>;	/* From Bootloader  */
-			bus-frequency = <0>;		/* From Bootloader  */
-			clock-frequency = <0>;		/* From Bootloader  */
+			d-cache-size = <0x4000>;	// L1, 16K
+			i-cache-size = <0x4000>;	// L1, 16K
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
 		};
 	};
 
 	memory {
 		device_type = "memory";
-		reg = <0x00000000 0x04000000>;	/* 64MB */
+		reg = <0x00000000 0x04000000>;	// 64MB
 	};
 
 	soc5200@f0000000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "fsl,mpc5200b-immr";
-		ranges = <0x0 0xf0000000 0x0000c000>;
-		bus-frequency = <0>;		/* From bootloader */
-		system-frequency = <0>;		/* From bootloader */
+		ranges = <0 0xf0000000 0x0000c000>;
+		bus-frequency = <0>;		// from bootloader
+		system-frequency = <0>;		// from bootloader
 
 		cdm@200 {
 			compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
@@ -56,87 +57,70 @@
 		};
 
 		mpc5200_pic: interrupt-controller@500 {
-			/* 5200 interrupts are encoded into two levels; */
+			// 5200 interrupts are encoded into two levels;
 			interrupt-controller;
 			#interrupt-cells = <3>;
-			device_type = "interrupt-controller";
 			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
 			reg = <0x500 0x80>;
 		};
 
-		timer@600 {	/* General Purpose Timer */
+		timer@600 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <0>;
 			reg = <0x600 0x10>;
-			interrupts = <0x1 0x9 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 9 0>;
 			fsl,has-wdt;
 		};
 
-		timer@610 {	/* General Purpose Timer */
+		timer@610 {	// General Purpose Timer
 			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
-			cell-index = <1>;
 			reg = <0x610 0x10>;
-			interrupts = <0x1 0xa 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 10 0>;
 		};
 
-		gpt2: timer@620 { /* General Purpose Timer in GPIO mode */
+		gpt2: timer@620 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <2>;
 			reg = <0x620 0x10>;
-			interrupts = <0x1 0xb 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 11 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpt3: timer@630 { /* General Purpose Timer in GPIO mode */
+		gpt3: timer@630 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <3>;
 			reg = <0x630 0x10>;
-			interrupts = <0x1 0xc 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 12 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpt4: timer@640 { /* General Purpose Timer in GPIO mode */
+		gpt4: timer@640 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <4>;
 			reg = <0x640 0x10>;
-			interrupts = <0x1 0xd 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 13 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpt5: timer@650 { /* General Purpose Timer in GPIO mode */
+		gpt5: timer@650 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <5>;
 			reg = <0x650 0x10>;
-			interrupts = <0x1 0xe 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 14 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpt6: timer@660 { /* General Purpose Timer in GPIO mode */
+		gpt6: timer@660 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <6>;
 			reg = <0x660 0x10>;
-			interrupts = <0x1 0xf 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 15 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpt7: timer@670 { /* General Purpose Timer in GPIO mode */
+		gpt7: timer@670 {	// General Purpose Timer in GPIO mode
 			compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
-			cell-index = <7>;
 			reg = <0x670 0x10>;
-			interrupts = <0x1 0x10 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 16 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
@@ -144,40 +128,33 @@
 		rtc@800 {	// Real time clock
 			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
 			reg = <0x800 0x100>;
-			interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 5 0 1 6 0>;
 		};
 
 		can@900 {
 			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
-			cell-index = <0>;
-			interrupts = <0x2 0x11 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 17 0>;
 			reg = <0x900 0x80>;
 		};
 
 		can@980 {
 			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
-			cell-index = <1>;
-			interrupts = <0x2 0x12 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 18 0>;
 			reg = <0x980 0x80>;
 		};
 
 		gpio_simple: gpio@b00 {
 			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
-			interrupts = <0x1 0x7 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 7 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
 
-		gpio_wkup: gpio-wkup@c00 {
+		gpio_wkup: gpio@c00 {
 			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
 			reg = <0xc00 0x40>;
-			interrupts = <0x1 0x8 0x0 0x0 0x3 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <1 8 0 0 3 0>;
 			gpio-controller;
 			#gpio-cells = <2>;
 		};
@@ -185,26 +162,22 @@
 		spi@f00 {
 			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
 			reg = <0xf00 0x20>;
-			interrupts = <0x2 0xd 0x0 0x2 0xe 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 13 0 2 14 0>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
-			interrupts = <0x2 0x6 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 6 0>;
 		};
 
 		dma-controller@1200 {
-			device_type = "dma-controller";
 			compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
 			reg = <0x1200 0x80>;
-			interrupts = <0x3 0x0 0x0  0x3 0x1 0x0  0x3 0x2 0x0  0x3 0x3 0x0
-			              0x3 0x4 0x0  0x3 0x5 0x0  0x3 0x6 0x0  0x3 0x7 0x0
-			              0x3 0x8 0x0  0x3 0x9 0x0  0x3 0xa 0x0  0x3 0xb 0x0
-			              0x3 0xc 0x0  0x3 0xd 0x0  0x3 0xe 0x0  0x3 0xf 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+			              3 4 0  3 5 0  3 6 0  3 7 0
+			              3 8 0  3 9 0  3 10 0  3 11 0
+			              3 12 0  3 13 0  3 14 0  3 15 0>;
 		};
 
 		xlb@1f00 {
@@ -213,24 +186,19 @@
 		};
 
 		ac97@2000 { /* PSC1 in ac97 mode */
-			device_type = "sound";
 			compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
 			cell-index = <0>;
 			reg = <0x2000 0x100>;
-			interrupts = <0x2 0x2 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 1 0>;
 		};
 
 		/* PSC2 port is used by CAN1/2 */
 
 		serial@2400 { /* PSC3 in UART mode */
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <0>;
 			cell-index = <2>;
 			reg = <0x2400 0x100>;
-			interrupts = <0x2 0x3 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 3 0>;
 		};
 
 		/* PSC4 is ??? */
@@ -238,55 +206,44 @@
 		/* PSC5 is ??? */
 
 		serial@2c00 { /* PSC6 in UART mode */
-			device_type = "serial";
 			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
-			port-number = <1>;
 			cell-index = <5>;
 			reg = <0x2c00 0x100>;
-			interrupts = <0x2 0x4 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 4 0>;
 		};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
-			local-mac-address = [00 00 00 00 00 00];
-			interrupts = <0x2 0x5 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <2 5 0>;
 			phy-handle = <&phy0>;
 		};
 
 		mdio@3000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio";
-			reg = <0x3000 0x400>;	/* fec range, since we need to setup fec interrupts */
-			interrupts = <0x2 0x5 0x0>;	/* these are for "mii command finished", not link changes & co. */
-			interrupt-parent = <&mpc5200_pic>;
+			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+			reg = <0x3000 0x400>;	// fec range, since we need to setup fec interrupts
+			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
 
-			phy0:ethernet-phy@0 {
-				device_type = "ethernet-phy";
-				reg = <0x0>;
+			phy0: ethernet-phy@0 {
+				reg = <0>;
 			};
 		};
 
 		ata@3a00 {
-			device_type = "ata";
 			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
 			reg = <0x3a00 0x100>;
-			interrupts = <0x2 0x7 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 7 0>;
 		};
 
 		i2c@3d00 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <0>;
 			reg = <0x3d00 0x40>;
-			interrupts = <0x2 0xf 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 15 0>;
 			fsl5200-clocking;
 		};
 
@@ -294,10 +251,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
-			cell-index = <1>;
 			reg = <0x3d40 0x40>;
-			interrupts = <0x2 0x10 0x0>;
-			interrupt-parent = <&mpc5200_pic>;
+			interrupts = <2 16 0>;
 			fsl5200-clocking;
 			rtc@51 {
 				compatible = "nxp,pcf8563";
@@ -307,7 +262,7 @@
 		};
 
 		sram@8000 {
-			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram";
+			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
 			reg = <0x8000 0x4000>;
 		};
 
@@ -340,22 +295,21 @@
 		device_type = "pci";
 		compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
 		reg = <0xf0000d00 0x100>;
-		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
-		interrupt-map = <0xc000 0x0 0x0 0x1 &mpc5200_pic 0x0 0x0 0x3 /* 1st slot */
-				 0xc000 0x0 0x0 0x2 &mpc5200_pic 0x1 0x1 0x3
-				 0xc000 0x0 0x0 0x3 &mpc5200_pic 0x1 0x2 0x3
-				 0xc000 0x0 0x0 0x4 &mpc5200_pic 0x1 0x3 0x3
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
+				 0xc000 0 0 2 &mpc5200_pic 1 1 3
+				 0xc000 0 0 3 &mpc5200_pic 1 2 3
+				 0xc000 0 0 4 &mpc5200_pic 1 3 3
 
-				 0xc800 0x0 0x0 0x1 &mpc5200_pic 0x1 0x1 0x3 /* 2nd slot */
-				 0xc800 0x0 0x0 0x2 &mpc5200_pic 0x1 0x2 0x3
-				 0xc800 0x0 0x0 0x3 &mpc5200_pic 0x1 0x3 0x3
-				 0xc800 0x0 0x0 0x4 &mpc5200_pic 0x0 0x0 0x3>;
+				 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
+				 0xc800 0 0 2 &mpc5200_pic 1 2 3
+				 0xc800 0 0 3 &mpc5200_pic 1 3 3
+				 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
 		clock-frequency = <0>; // From boot loader
-		interrupts = <0x2 0x8 0x0 0x2 0x9 0x0 0x2 0xa 0x0>;
-		interrupt-parent = <&mpc5200_pic>;
+		interrupts = <2 8 0 2 9 0 2 10 0>;
 		bus-range = <0 0>;
-		ranges = <0x42000000 0x0 0x80000000 0x80000000 0x0 0x20000000
-			  0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
-			  0x01000000 0x0 0x00000000 0xb0000000 0x0 0x01000000>;
+		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
 	};
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pcm032.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pcm032.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pcm032.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pcm032.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,392 @@
+/*
+ * phyCORE-MPC5200B-IO (pcm032) board Device Tree Source
+ *
+ * Copyright (C) 2006-2009 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ * Juergen Beisert <j.beisert@pengutronix.de>
+ * Wolfram Sang <w.sang@pengutronix.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.
+ */
+
+/dts-v1/;
+
+/ {
+	model = "phytec,pcm032";
+	compatible = "phytec,pcm032";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,5200@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x4000>;	// L1, 16K
+			i-cache-size = <0x4000>;	// L1, 16K
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x08000000>;	// 128MB
+	};
+
+	soc5200@f0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc5200b-immr";
+		ranges = <0 0xf0000000 0x0000c000>;
+		bus-frequency = <0>;		// from bootloader
+		system-frequency = <0>;		// from bootloader
+
+		cdm@200 {
+			compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+			reg = <0x200 0x38>;
+		};
+
+		mpc5200_pic: interrupt-controller@500 {
+			// 5200 interrupts are encoded into two levels;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+			reg = <0x500 0x80>;
+		};
+
+		timer@600 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x600 0x10>;
+			interrupts = <1 9 0>;
+			fsl,has-wdt;
+		};
+
+		timer@610 {	// General Purpose Timer
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x610 0x10>;
+			interrupts = <1 10 0>;
+		};
+
+		gpt2: timer@620 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x620 0x10>;
+			interrupts = <1 11 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpt3: timer@630 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x630 0x10>;
+			interrupts = <1 12 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpt4: timer@640 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x640 0x10>;
+			interrupts = <1 13 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpt5: timer@650 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x650 0x10>;
+			interrupts = <1 14 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpt6: timer@660 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x660 0x10>;
+			interrupts = <1 15 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpt7: timer@670 {	// General Purpose Timer in GPIO mode
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+			reg = <0x670 0x10>;
+			interrupts = <1 16 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		rtc@800 {	// Real time clock
+			compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
+			reg = <0x800 0x100>;
+			interrupts = <1 5 0 1 6 0>;
+		};
+
+		can@900 {
+			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+			interrupts = <2 17 0>;
+			reg = <0x900 0x80>;
+		};
+
+		can@980 {
+			compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+			interrupts = <2 18 0>;
+			reg = <0x980 0x80>;
+		};
+
+		gpio_simple: gpio@b00 {
+			compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+			reg = <0xb00 0x40>;
+			interrupts = <1 7 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpio_wkup: gpio@c00 {
+			compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+			reg = <0xc00 0x40>;
+			interrupts = <1 8 0 0 3 0>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		spi@f00 {
+			compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+			reg = <0xf00 0x20>;
+			interrupts = <2 13 0 2 14 0>;
+		};
+
+		usb@1000 {
+			compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+			reg = <0x1000 0xff>;
+			interrupts = <2 6 0>;
+		};
+
+		dma-controller@1200 {
+			compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+			reg = <0x1200 0x80>;
+			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+			              3 4 0  3 5 0  3 6 0  3 7 0
+			              3 8 0  3 9 0  3 10 0  3 11 0
+			              3 12 0  3 13 0  3 14 0  3 15 0>;
+		};
+
+		xlb@1f00 {
+			compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+			reg = <0x1f00 0x100>;
+		};
+
+		ac97@2000 {	/* PSC1 is ac97 */
+			compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97";
+			cell-index = <0>;
+			reg = <0x2000 0x100>;
+			interrupts = <2 1 0>;
+		};
+
+		/* PSC2 port is used by CAN1/2 */
+
+		serial@2400 { /* PSC3 in UART mode */
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+			cell-index = <2>;
+			reg = <0x2400 0x100>;
+			interrupts = <2 3 0>;
+		};
+
+		/* PSC4 is ??? */
+
+		/* PSC5 is ??? */
+
+		serial@2c00 { /* PSC6 in UART mode */
+			compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+			cell-index = <5>;
+			reg = <0x2c00 0x100>;
+			interrupts = <2 4 0>;
+		};
+
+		ethernet@3000 {
+			compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+			reg = <0x3000 0x400>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <2 5 0>;
+			phy-handle = <&phy0>;
+		};
+
+		mdio@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+			reg = <0x3000 0x400>;	// fec range, since we need to setup fec interrupts
+			interrupts = <2 5 0>;	// these are for "mii command finished", not link changes & co.
+
+			phy0: ethernet-phy@0 {
+				reg = <0>;
+			};
+		};
+
+		ata@3a00 {
+			compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+			reg = <0x3a00 0x100>;
+			interrupts = <2 7 0>;
+		};
+
+		i2c@3d00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+			reg = <0x3d00 0x40>;
+			interrupts = <2 15 0>;
+			fsl5200-clocking;
+		};
+
+		i2c@3d40 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+			reg = <0x3d40 0x40>;
+			interrupts = <2 16 0>;
+			fsl5200-clocking;
+			rtc@51 {
+				compatible = "nxp,pcf8563";
+				reg = <0x51>;
+			};
+			eeprom@52 {
+				compatible = "at24,24c32";
+				reg = <0x52>;
+			};
+		};
+
+		sram@8000 {
+			compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+			reg = <0x8000 0x4000>;
+		};
+	};
+
+	pci@f0000d00 {
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+		reg = <0xf0000d00 0x100>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
+				 0xc000 0 0 2 &mpc5200_pic 1 1 3
+				 0xc000 0 0 3 &mpc5200_pic 1 2 3
+				 0xc000 0 0 4 &mpc5200_pic 1 3 3
+
+				 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
+				 0xc800 0 0 2 &mpc5200_pic 1 2 3
+				 0xc800 0 0 3 &mpc5200_pic 1 3 3
+				 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
+		clock-frequency = <0>; // From boot loader
+		interrupts = <2 8 0 2 9 0 2 10 0>;
+		bus-range = <0 0>;
+		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+			  0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
+	};
+
+	localbus {
+		compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		ranges = <0 0 0xfe000000 0x02000000
+			  1 0 0xfc000000 0x02000000
+			  2 0 0xfbe00000 0x00200000
+			  3 0 0xf9e00000 0x02000000
+			  4 0 0xf7e00000 0x02000000
+			  5 0 0xe6000000 0x02000000
+			  6 0 0xe8000000 0x02000000
+			  7 0 0xea000000 0x02000000>;
+
+		flash@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x02000000>;
+			bank-width = <4>;
+			#size-cells = <1>;
+			#address-cells = <1>;
+
+			partition@0 {
+				label = "ubootl";
+				reg = <0x00000000 0x00040000>;
+			};
+			partition@40000 {
+				label = "kernel";
+				reg = <0x00040000 0x001c0000>;
+			};
+			partition@200000 {
+				label = "jffs2";
+				reg = <0x00200000 0x01d00000>;
+			};
+			partition@1f00000 {
+				label = "uboot";
+				reg = <0x01f00000 0x00040000>;
+			};
+			partition@1f40000 {
+				label = "env";
+				reg = <0x01f40000 0x00040000>;
+			};
+			partition@1f80000 {
+				label = "oftree";
+				reg = <0x01f80000 0x00040000>;
+			};
+			partition@1fc0000 {
+				label = "space";
+				reg = <0x01fc0000 0x00040000>;
+			};
+		};
+
+		sram@2,0 {
+			compatible = "mtd-ram";
+			reg = <2 0 0x00200000>;
+			bank-width = <2>;
+		};
+
+                /*
+		 * example snippets for FPGA
+		 *
+		 * fpga@3,0 {
+		 *         compatible = "fpga_driver";
+		 *         reg = <3 0 0x02000000>;
+		 *         bank-width = <4>;
+		 * };
+		 *
+		 * fpga@4,0 {
+		 *         compatible = "fpga_driver";
+		 *         reg = <4 0 0x02000000>;
+		 *         bank-width = <4>;
+		 * };
+                 */
+
+                /*
+		 * example snippets for free chipselects
+                 *
+		 * device@5,0 {
+		 *         compatible = "custom_driver";
+		 *         reg = <5 0 0x02000000>;
+		 * };
+                 *
+		 * device@6,0 {
+		 *         compatible = "custom_driver";
+		 *         reg = <6 0 0x02000000>;
+		 * };
+                 *
+		 * device@7,0 {
+		 *         compatible = "custom_driver";
+		 *         reg = <7 0 0x02000000>;
+		 * };
+                 */
+	};
+};
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pq2fads.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pq2fads.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/pq2fads.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/pq2fads.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,14 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -45,7 +53,7 @@
 		#size-cells = <1>;
 		reg = <0xf0010100 0x60>;
 
-		ranges = <0x0 0x0 0xfe000000 0x800000
+		ranges = <0x0 0x0 0xff800000 0x800000
 		          0x1 0x0 0xf4500000 0x8000
 		          0x8 0x0 0xf8200000 0x8000>;
 
@@ -71,7 +79,7 @@
 		};
 	};
 
-	pci@f0010800 {
+	pci0: pci@f0010800 {
 		device_type = "pci";
 		reg = <0xf0010800 0x10c 0xf00101ac 0x8 0xf00101c4 0x8>;
 		compatible = "fsl,mpc8280-pci", "fsl,pq2-pci";
@@ -142,7 +150,7 @@
 				reg = <0x119f0 0x10 0x115f0 0x10>;
 			};
 
-			serial@11a00 {
+			serial0: serial@11a00 {
 				device_type = "serial";
 				compatible = "fsl,mpc8280-scc-uart",
 				             "fsl,cpm2-scc-uart";
@@ -153,7 +161,7 @@
 				fsl,cpm-command = <0x800000>;
 			};
 
-			serial@11a20 {
+			serial1: serial@11a20 {
 				device_type = "serial";
 				compatible = "fsl,mpc8280-scc-uart",
 				             "fsl,cpm2-scc-uart";
@@ -164,7 +172,7 @@
 				fsl,cpm-command = <0x4a00000>;
 			};
 
-			ethernet@11320 {
+			enet0: ethernet@11320 {
 				device_type = "network";
 				compatible = "fsl,mpc8280-fcc-enet",
 				             "fsl,cpm2-fcc-enet";
@@ -176,7 +184,7 @@
 				fsl,cpm-command = <0x16200300>;
 			};
 
-			ethernet@11340 {
+			enet1: ethernet@11340 {
 				device_type = "network";
 				compatible = "fsl,mpc8280-fcc-enet",
 				             "fsl,cpm2-fcc-enet";
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/redwood.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/redwood.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/redwood.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/redwood.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,244 @@
+/*
+ * Device Tree Source for AMCC Redwood(460SX)
+ *
+ * Copyright 2008 AMCC <tmarri@amcc.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	model = "amcc,redwood";
+	compatible = "amcc,redwood";
+	dcr-parent = <&{/cpus/cpu@0}>;
+
+	aliases {
+		ethernet0 = &EMAC0;
+		serial0 = &UART0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,460SX";
+			reg = <0x00000000>;
+			clock-frequency = <0>; /* Filled in by U-Boot */
+			timebase-frequency = <0>; /* Filled in by U-Boot */
+			i-cache-line-size = <32>;
+			d-cache-line-size = <32>;
+			i-cache-size = <32768>;
+			d-cache-size = <32768>;
+			dcr-controller;
+			dcr-access-method = "native";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
+	};
+
+	UIC0: interrupt-controller0 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0x0c0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+
+	UIC1: interrupt-controller1 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <1>;
+		dcr-reg = <0x0d0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC2: interrupt-controller2 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <2>;
+		dcr-reg = <0x0e0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC3: interrupt-controller3 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <3>;
+		dcr-reg = <0x0f0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	SDR0: sdr {
+		compatible = "ibm,sdr-460sx";
+		dcr-reg = <0x00e 0x002>;
+	};
+
+	CPR0: cpr {
+		compatible = "ibm,cpr-460sx";
+		dcr-reg = <0x00c 0x002>;
+	};
+
+	plb {
+		compatible = "ibm,plb-460sx", "ibm,plb4";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+		clock-frequency = <0>; /* Filled in by U-Boot */
+
+		SDRAM0: sdram {
+			compatible = "ibm,sdram-460sx", "ibm,sdram-405gp";
+			dcr-reg = <0x010 0x002>;
+		};
+
+		MAL0: mcmal {
+			compatible = "ibm,mcmal-460sx", "ibm,mcmal2";
+			dcr-reg = <0x180 0x62>;
+			num-tx-chans = <4>;
+			num-rx-chans = <32>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			interrupt-parent = <&UIC1>;
+			interrupts = <	/*TXEOB*/ 0x6 0x4
+					/*RXEOB*/ 0x7 0x4
+					/*SERR*/  0x1 0x4
+					/*TXDE*/  0x2 0x4
+					/*RXDE*/  0x3 0x4
+					/*COAL TX0*/ 0x18 0x2
+					/*COAL TX1*/ 0x19 0x2
+					/*COAL TX2*/ 0x1a 0x2
+					/*COAL TX3*/ 0x1b 0x2
+					/*COAL RX0*/ 0x1c 0x2
+					/*COAL RX1*/ 0x1d 0x2
+					/*COAL RX2*/ 0x1e 0x2
+					/*COAL RX3*/ 0x1f 0x2>;
+		};
+
+		POB0: opb {
+			compatible = "ibm,opb-460sx", "ibm,opb";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
+			clock-frequency = <0>; /* Filled in by U-Boot */
+
+			EBC0: ebc {
+				compatible = "ibm,ebc-460sx", "ibm,ebc";
+				dcr-reg = <0x012 0x002>;
+				#address-cells = <2>;
+				#size-cells = <1>;
+				clock-frequency = <0>; /* Filled in by U-Boot */
+				/* ranges property is supplied by U-Boot */
+				interrupts = <0x6 0x4>;
+				interrupt-parent = <&UIC1>;
+
+				nor_flash@0,0 {
+					compatible = "amd,s29gl512n", "cfi-flash";
+					bank-width = <2>;
+					reg = <0x0000000 0x00000000 0x04000000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "kernel";
+						reg = <0x00000000 0x001e0000>;
+					};
+					partition@1e0000 {
+						label = "dtb";
+						reg = <0x001e0000 0x00020000>;
+					};
+					partition@200000 {
+						label = "ramdisk";
+						reg = <0x00200000 0x01400000>;
+					};
+					partition@1600000 {
+						label = "jffs2";
+						reg = <0x01600000 0x00400000>;
+					};
+					partition@1a00000 {
+						label = "user";
+						reg = <0x01a00000 0x02560000>;
+					};
+					partition@3f60000 {
+						label = "env";
+						reg = <0x03f60000 0x00040000>;
+					};
+					partition@3fa0000 {
+						label = "u-boot";
+						reg = <0x03fa0000 0x00060000>;
+					};
+				};
+			};
+
+			UART0: serial@ef600200 {
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0xef600200 0x00000008>;
+				virtual-reg = <0xef600200>;
+				clock-frequency = <0>; /* Filled in by U-Boot */
+				current-speed = <0>; /* Filled in by U-Boot */
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x0 0x4>;
+			};
+
+			RGMII0: emac-rgmii@ef600900 {
+				compatible = "ibm,rgmii-460sx", "ibm,rgmii";
+				reg = <0xef600900 0x00000008>;
+			};
+
+			EMAC0: ethernet@ef600a00 {
+				device_type = "network";
+				compatible = "ibm,emac-460sx", "ibm,emac4";
+				interrupt-parent = <&EMAC0>;
+				interrupts = <0x0 0x1>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x13 0x4
+						 /*Wake*/   0x1 &UIC2 0x1d 0x4>;
+				reg = <0xef600a00 0x00000070>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <0>;
+				mal-rx-channel = <0>;
+				cell-index = <0>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+			};
+
+		};
+
+	};
+	chosen {
+		linux,stdout-path = "/plb/opb/serial@ef600200";
+	};
+
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8349.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8349.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8349.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8349.dts	2009-06-09 23:05:27.000000000 -0400
@@ -159,68 +159,76 @@
 			phy_type = "ulpi";
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@19 {
-				interrupt-parent = <&ipic>;
-				interrupts = <20 0x8>;
-				reg = <0x19>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1a {
-				interrupt-parent = <&ipic>;
-				interrupts = <21 0x8>;
-				reg = <0x1a>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <32 0x8 33 0x8 34 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			linux,network-index = <0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@19 {
+					interrupt-parent = <&ipic>;
+					interrupts = <20 0x8>;
+					reg = <0x19>;
+					device_type = "ethernet-phy";
+				};
+
+				phy1: ethernet-phy@1a {
+					interrupt-parent = <&ipic>;
+					interrupts = <21 0x8>;
+					reg = <0x1a>;
+					device_type = "ethernet-phy";
+				};
+
+				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 = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <35 0x8 36 0x8 37 0x8>;
 			interrupt-parent = <&ipic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
 			linux,network-index = <1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8548.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8548.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8548.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8548.dts	2009-06-09 23:05:27.000000000 -0400
@@ -156,14 +156,14 @@
 		compatible = "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8548-memory-controller";
+			compatible = "fsl,mpc8548-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <0x12 0x2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8548-l2-cache-controller";
+			compatible = "fsl,mpc8548-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <0x20>;	// 32 bytes
 			cache-size = <0x80000>;	// L2, 512K
@@ -234,66 +234,72 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@19 {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x6 0x1>;
-				reg = <0x19>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1a {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x7 0x1>;
-				reg = <0x1a>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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 = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@19 {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x6 0x1>;
+					reg = <0x19>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1a {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x7 0x1>;
+					reg = <0x1a>;
+					device_type = "ethernet-phy";
+				};
+				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 = <0x23 0x2 0x24 0x2 0x28 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8560.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8560.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8560.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8560.dts	2009-06-09 23:05:27.000000000 -0400
@@ -61,14 +61,14 @@
 		clock-frequency = <0>;
 
 		memory-controller@2000 {
-			compatible = "fsl,8560-memory-controller";
+			compatible = "fsl,mpc8560-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <0x12 0x2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8560-l2-cache-controller";
+			compatible = "fsl,mpc8560-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <0x20>;	// 32 bytes
 			cache-size = <0x40000>;		// L2, 256K
@@ -139,77 +139,83 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-			phy0: ethernet-phy@19 {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x6 0x1>;
-				reg = <0x19>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@1a {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x7 0x1>;
-				reg = <0x1a>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@1b {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x8 0x1>;
-				reg = <0x1b>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@1c {
-				interrupt-parent = <&mpic>;
-				interrupts = <0x8 0x1>;
-				reg = <0x1c>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+				phy0: ethernet-phy@19 {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x6 0x1>;
+					reg = <0x19>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1a {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x7 0x1>;
+					reg = <0x1a>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@1b {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x8 0x1>;
+					reg = <0x1b>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@1c {
+					interrupt-parent = <&mpic>;
+					interrupts = <0x8 0x1>;
+					reg = <0x1c>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			compatible = "gianfar";
 			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		mpic: pic@40000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8641d.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8641d.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/sbc8641d.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8641d.dts	2009-06-09 23:05:27.000000000 -0400
@@ -192,132 +192,144 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy0: ethernet-phy@1f {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0x1f>;
-				device_type = "ethernet-phy";
-			};
-			phy1: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <0>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <10 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@1f {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0x1f>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <0>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <2>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy2>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "TSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
 			phy-handle = <&phy3>;
 			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/socrates.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/socrates.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/socrates.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/socrates.dts	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,339 @@
+/*
+ * Device Tree Source for the Socrates board (MPC8544).
+ *
+ * Copyright (c) 2008 Emcraft Systems.
+ * Sergei Poselenov, <sposelenov@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.
+ */
+
+/dts-v1/;
+
+/ {
+	model = "abb,socrates";
+	compatible = "abb,socrates";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8544@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x8000>;	// L1, 32K
+			i-cache-size = <0x8000>;	// L1, 32K
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000>;	// Filled in by U-Boot
+	};
+
+	soc8544@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+
+		ranges = <0x00000000 0xe0000000 0x00100000>;
+		reg = <0xe0000000 0x00001000>;	// CCSRBAR 1M
+		bus-frequency = <0>;		// Filled in by U-Boot
+		compatible = "fsl,mpc8544-immr", "simple-bus";
+
+		memory-controller@2000 {
+			compatible = "fsl,mpc8544-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,mpc8544-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;
+			cache-size = <0x40000>;	// L2, 256K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl,mpc8544-i2c", "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			fsl,preserve-clocking;
+
+			dtt@28 {
+				compatible = "winbond,w83782d";
+				reg = <0x28>;
+			};
+			rtc@32 {
+				compatible = "epson,rx8025";
+				reg = <0x32>;
+				interrupts = <7 1>;
+				interrupt-parent = <&mpic>;
+			};
+			dtt@4c {
+				compatible = "dallas,ds75";
+				reg = <0x4c>;
+			};
+			ts@4a {
+				compatible = "ti,tsc2003";
+				reg = <0x4a>;
+				interrupt-parent = <&mpic>;
+				interrupts = <8 1>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl,mpc8544-i2c", "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			fsl,preserve-clocking;
+		};
+
+		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>;
+			phy-handle = <&phy0>;
+			tbi-handle = <&tbi0>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <0 1>;
+					reg = <0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <0 1>;
+					reg = <1>;
+				};
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+				};
+			};
+		};
+
+		enet1: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			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>;
+			tbi-handle = <&tbi1>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+				};
+			};
+		};
+
+		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";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+	};
+
+
+	localbus {
+		compatible = "fsl,mpc8544-localbus",
+		             "fsl,pq3-localbus",
+			     "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		reg = <0xe0005000 0x40>;
+
+		ranges = <0 0 0xfc000000 0x04000000
+			  2 0 0xc8000000 0x04000000
+			  3 0 0xc0000000 0x00100000
+			>; /* Overwritten by U-Boot */
+
+		nor_flash@0,0 {
+			compatible = "amd,s29gl256n", "cfi-flash";
+			bank-width = <2>;
+			reg = <0x0 0x000000 0x4000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition@0 {
+				label = "kernel";
+				reg = <0x0 0x1e0000>;
+				read-only;
+			};
+			partition@1e0000 {
+				label = "dtb";
+				reg = <0x1e0000 0x20000>;
+			};
+			partition@200000 {
+				label = "root";
+				reg = <0x200000 0x200000>;
+			};
+			partition@400000 {
+				label = "user";
+				reg = <0x400000 0x3b80000>;
+			};
+			partition@3f80000 {
+				label = "env";
+				reg = <0x3f80000 0x40000>;
+				read-only;
+			};
+			partition@3fc0000 {
+				label = "u-boot";
+				reg = <0x3fc0000 0x40000>;
+				read-only;
+			};
+		};
+
+		display@2,0 {
+			compatible = "fujitsu,lime";
+			reg = <2 0x0 0x4000000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <6 1>;
+		};
+
+		fpga_pic: fpga-pic@3,10 {
+			compatible = "abb,socrates-fpga-pic";
+			reg = <3 0x10 0x10>;
+			interrupt-controller;
+			/* IRQs 2, 10, 11, active low, level-sensitive */
+			interrupts = <2 1 10 1 11 1>;
+			interrupt-parent = <&mpic>;
+			#interrupt-cells = <3>;
+		};
+
+		spi@3,60 {
+			compatible = "abb,socrates-spi";
+			reg = <3 0x60 0x10>;
+			interrupts = <8 4 0>;	// number, type, routing
+			interrupt-parent = <&fpga_pic>;
+		};
+
+		nand@3,70 {
+			compatible = "abb,socrates-nand";
+			reg = <3 0x70 0x04>;
+			bank-width = <1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			data@0 {
+				label = "data";
+				reg = <0x0 0x40000000>;
+			};
+		};
+
+		can@3,100 {
+			compatible = "philips,sja1000";
+			reg = <3 0x100 0x80>;
+			interrupts = <2 8 1>;	// number, type, routing
+			interrupt-parent = <&fpga_pic>;
+		};
+	};
+
+	pci0: pci@e0008000 {
+		cell-index = <0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		compatible = "fsl,mpc8540-pci";
+		device_type = "pci";
+		reg = <0xe0008000 0x1000>;
+		clock-frequency = <66666666>;
+
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+				/* IDSEL 0x11 */
+				 0x8800 0x0 0x0 1 &mpic 5 1
+				/* IDSEL 0x12 */
+				 0x9000 0x0 0x0 1 &mpic 4 1>;
+		interrupt-parent = <&mpic>;
+		interrupts = <24 2>;
+		bus-range = <0x0 0x0>;
+		ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+			  0x01000000 0x0 0x00000000 0xe2000000 0x0 0x01000000>;
+	};
+
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/stx_gp3_8560.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/stx_gp3_8560.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/stx_gp3_8560.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/stx_gp3_8560.dts	2009-06-09 23:05:27.000000000 -0400
@@ -57,14 +57,14 @@
 		compatible = "fsl,mpc8560-immr", "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;
 			cache-size = <0x40000>;	// L2, 256K
@@ -124,66 +124,72 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 4>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy4: ethernet-phy@4 {
-				interrupt-parent = <&mpic>;
-				interrupts = <5 4>;
-				reg = <4>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 4>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy4: ethernet-phy@4 {
+					interrupt-parent = <&mpic>;
+					interrupts = <5 4>;
+					reg = <4>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy4>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		mpic: pic@40000 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm5200.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm5200.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm5200.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm5200.dts	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 	compatible = "tqc,tqm5200";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	interrupt-parent = <&mpc5200_pic>;
 
 	cpus {
 		#address-cells = <1>;
@@ -66,36 +67,33 @@
 			compatible = "fsl,mpc5200-gpt";
 			reg = <0x600 0x10>;
 			interrupts = <1 9 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl,has-wdt;
 		};
 
 		can@900 {
 			compatible = "fsl,mpc5200-mscan";
 			interrupts = <2 17 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x900 0x80>;
 		};
 
 		can@980 {
 			compatible = "fsl,mpc5200-mscan";
 			interrupts = <2 18 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			reg = <0x980 0x80>;
 		};
 
-		gpio@b00 {
+		gpio_simple: gpio@b00 {
 			compatible = "fsl,mpc5200-gpio";
 			reg = <0xb00 0x40>;
 			interrupts = <1 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		usb@1000 {
 			compatible = "fsl,mpc5200-ohci","ohci-be";
 			reg = <0x1000 0xff>;
 			interrupts = <2 6 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		dma-controller@1200 {
@@ -105,7 +103,6 @@
 			              3 4 0  3 5 0  3 6 0  3 7 0
 			              3 8 0  3 9 0  3 10 0  3 11 0
 			              3 12 0  3 13 0  3 14 0  3 15 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		xlb@1f00 {
@@ -114,39 +111,28 @@
 		};
 
 		serial@2000 {		// PSC1
-			device_type = "serial";
 			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <0>;  // Logical port assignment
 			reg = <0x2000 0x100>;
 			interrupts = <2 1 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		serial@2200 {		// PSC2
-			device_type = "serial";
 			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <1>;  // Logical port assignment
 			reg = <0x2200 0x100>;
 			interrupts = <2 2 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		serial@2400 {		// PSC3
-			device_type = "serial";
 			compatible = "fsl,mpc5200-psc-uart";
-			port-number = <2>;  // Logical port assignment
 			reg = <0x2400 0x100>;
 			interrupts = <2 3 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		ethernet@3000 {
-			device_type = "network";
 			compatible = "fsl,mpc5200-fec";
 			reg = <0x3000 0x400>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <2 5 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			phy-handle = <&phy0>;
 		};
 
@@ -156,10 +142,8 @@
 			compatible = "fsl,mpc5200-mdio";
 			reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
 			interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
-			interrupt-parent = <&mpc5200_pic>;
 
 			phy0: ethernet-phy@0 {
-				device_type = "ethernet-phy";
 				reg = <0>;
 			};
 		};
@@ -168,7 +152,6 @@
 			compatible = "fsl,mpc5200-ata";
 			reg = <0x3a00 0x100>;
 			interrupts = <2 7 0>;
-			interrupt-parent = <&mpc5200_pic>;
 		};
 
 		i2c@3d40 {
@@ -177,7 +160,6 @@
 			compatible = "fsl,mpc5200-i2c","fsl-i2c";
 			reg = <0x3d40 0x40>;
 			interrupts = <2 16 0>;
-			interrupt-parent = <&mpc5200_pic>;
 			fsl5200-clocking;
 
 			 rtc@68 {
@@ -192,9 +174,8 @@
 		};
 	};
 
-	lpb {
-		model = "fsl,lpb";
-		compatible = "fsl,lpb";
+	localbus {
+		compatible = "fsl,mpc5200-lpb","simple-bus";
 		#address-cells = <2>;
 		#size-cells = <1>;
 		ranges = <0 0 0xfc000000 0x02000000>;
@@ -223,7 +204,6 @@
 				 0xc000 0 0 4 &mpc5200_pic 0 0 3>;
 		clock-frequency = <0>; // From boot loader
 		interrupts = <2 8 0 2 9 0 2 10 0>;
-		interrupt-parent = <&mpc5200_pic>;
 		bus-range = <0 0>;
 		ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
 			  0x02000000 0 0x90000000 0x90000000 0 0x10000000
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8540.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8540.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8540.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8540.dts	2009-06-09 23:05:27.000000000 -0400
@@ -59,14 +59,14 @@
 		compatible = "fsl,mpc8540-immr", "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;
 			cache-size = <0x40000>;	// L2, 256K
@@ -84,6 +84,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -131,94 +136,103 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <2>;
 			device_type = "network";
 			model = "FEC";
 			compatible = "gianfar";
 			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <41 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8541.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8541.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8541.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8541.dts	2009-06-09 23:05:27.000000000 -0400
@@ -58,14 +58,14 @@
 		compatible = "fsl,mpc8541-immr", "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;
 			cache-size = <0x40000>;	// L2, 256K
@@ -83,6 +83,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -130,72 +135,78 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8548-bigflash.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8548-bigflash.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8548-bigflash.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8548-bigflash.dts	2009-06-09 23:05:27.000000000 -0400
@@ -85,6 +85,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -143,134 +148,146 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			phy4: ethernet-phy@4 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <4>;
-				device_type = "ethernet-phy";
-			};
-			phy5: ethernet-phy@5 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <5>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				phy4: ethernet-phy@4 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <4>;
+					device_type = "ethernet-phy";
+				};
+				phy5: ethernet-phy@5 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <5>;
+					device_type = "ethernet-phy";
+				};
+				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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		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>;
 			tbi-handle = <&tbi2>;
-			phy-handle = <&phy3>;
+			phy-handle = <&phy4>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
-			phy-handle = <&phy4>;
+			phy-handle = <&phy5>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -365,14 +382,14 @@
 		can0@2,0 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x0 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 
 		can1@2,100 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x100 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 
@@ -380,10 +397,13 @@
 		upm@3,0 {
 			#address-cells = <0>;
 			#size-cells = <0>;
-			compatible = "fsl,upm-nand";
+			compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
 			reg = <3 0x0 0x800>;
 			fsl,upm-addr-offset = <0x10>;
 			fsl,upm-cmd-offset = <0x08>;
+			/* Micron MT29F8G08FAB multi-chip device */
+			fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+			fsl,upm-wait-flags = <0x5>;
 			chip-delay = <25>; // in micro-seconds
 
 			nand@0 {
@@ -392,7 +412,7 @@
 
 				partition@0 {
 					    label = "fs";
-					    reg = <0x00000000 0x01000000>;
+					    reg = <0x00000000 0x10000000>;
 				};
 			};
 		};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8548.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8548.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8548.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8548.dts	2009-06-09 23:05:27.000000000 -0400
@@ -85,6 +85,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -143,134 +148,146 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@0 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			phy4: ethernet-phy@4 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <4>;
-				device_type = "ethernet-phy";
-			};
-			phy5: ethernet-phy@5 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <5>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@26520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
-			tbi2: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@27520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x27520 0x20>;
-
-			tbi3: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				phy4: ethernet-phy@4 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <4>;
+					device_type = "ethernet-phy";
+				};
+				phy5: ethernet-phy@5 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <5>;
+					device_type = "ethernet-phy";
+				};
+				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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		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>;
 			tbi-handle = <&tbi2>;
-			phy-handle = <&phy3>;
+			phy-handle = <&phy4>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi2: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		enet3: ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <3>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
 			reg = <0x27000 0x1000>;
+			ranges = <0x0 0x27000 0x1000>;
 			local-mac-address = [ 00 00 00 00 00 00 ];
 			interrupts = <37 2 38 2 39 2>;
 			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi3>;
-			phy-handle = <&phy4>;
+			phy-handle = <&phy5>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi3: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
@@ -365,14 +382,14 @@
 		can0@2,0 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x0 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 
 		can1@2,100 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x100 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 
@@ -380,10 +397,13 @@
 		upm@3,0 {
 			#address-cells = <0>;
 			#size-cells = <0>;
-			compatible = "fsl,upm-nand";
+			compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
 			reg = <3 0x0 0x800>;
 			fsl,upm-addr-offset = <0x10>;
 			fsl,upm-cmd-offset = <0x08>;
+			/* Micron MT29F8G08FAB multi-chip device */
+			fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+			fsl,upm-wait-flags = <0x5>;
 			chip-delay = <25>; // in micro-seconds
 
 			nand@0 {
@@ -392,7 +412,7 @@
 
 				partition@0 {
 					    label = "fs";
-					    reg = <0x00000000 0x01000000>;
+					    reg = <0x00000000 0x10000000>;
 				};
 			};
 		};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8555.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8555.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8555.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8555.dts	2009-06-09 23:05:27.000000000 -0400
@@ -58,14 +58,14 @@
 		compatible = "fsl,mpc8555-immr", "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;
 			cache-size = <0x40000>;	// L2, 256K
@@ -83,6 +83,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -130,72 +135,78 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		serial0: serial@4500 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8560.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8560.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/tqm8560.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/tqm8560.dts	2009-06-09 23:05:27.000000000 -0400
@@ -60,14 +60,14 @@
 		compatible = "fsl,mpc8560-immr", "simple-bus";
 
 		memory-controller@2000 {
-			compatible = "fsl,8540-memory-controller";
+			compatible = "fsl,mpc8540-memory-controller";
 			reg = <0x2000 0x1000>;
 			interrupt-parent = <&mpic>;
 			interrupts = <18 2>;
 		};
 
 		L2: l2-cache-controller@20000 {
-			compatible = "fsl,8540-l2-cache-controller";
+			compatible = "fsl,mpc8540-l2-cache-controller";
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;
 			cache-size = <0x40000>;	// L2, 256K
@@ -85,6 +85,11 @@
 			interrupt-parent = <&mpic>;
 			dfsrr;
 
+			dtt@48 {
+				compatible = "national,lm75";
+				reg = <0x48>;
+			};
+
 			rtc@68 {
 				compatible = "dallas,ds1337";
 				reg = <0x68>;
@@ -132,72 +137,78 @@
 			};
 		};
 
-		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
-
-			phy1: ethernet-phy@1 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <1>;
-				device_type = "ethernet-phy";
-			};
-			phy2: ethernet-phy@2 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <2>;
-				device_type = "ethernet-phy";
-			};
-			phy3: ethernet-phy@3 {
-				interrupt-parent = <&mpic>;
-				interrupts = <8 1>;
-				reg = <3>;
-				device_type = "ethernet-phy";
-			};
-			tbi0: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
-		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x25520 0x20>;
-
-			tbi1: tbi-phy@11 {
-				reg = <0x11>;
-				device_type = "tbi-phy";
-			};
-		};
-
 		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			cell-index = <0>;
 			device_type = "network";
 			model = "TSEC";
 			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>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy2>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <2>;
+					device_type = "ethernet-phy";
+				};
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&mpic>;
+					interrupts = <8 1>;
+					reg = <3>;
+					device_type = "ethernet-phy";
+				};
+				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 = "TSEC";
 			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 = <&tbi1>;
 			phy-handle = <&phy1>;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
 		};
 
 		mpic: pic@40000 {
@@ -335,14 +346,14 @@
 		can0@2,0 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x0 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 
 		can1@2,100 {
 			compatible = "intel,82527"; // Bosch CC770
 			reg = <2 0x100 0x100>;
-			interrupts = <4 0>;
+			interrupts = <4 1>;
 			interrupt-parent = <&mpic>;
 		};
 	};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/virtex440-ml507.dts linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/virtex440-ml507.dts
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/dts/virtex440-ml507.dts	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/virtex440-ml507.dts	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,15 @@
  * 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.
+ *
+ * ---
+ *
+ * Device Tree Generator version: 1.1
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6
+ *
+ * XPS project directory: ml507_ppc440_emb_ref
  */
 
 /dts-v1/;
@@ -22,8 +31,8 @@
 		reg = < 0 0x10000000 >;
 	} ;
 	chosen {
-		bootargs = "console=ttyS0 ip=on root=/dev/ram";
-		linux,stdout-path = "/plb@0/serial@83e00000";
+		bootargs = "console=ttyS0 root=/dev/ram";
+		linux,stdout-path = &RS232_Uart_1;
 	} ;
 	cpus {
 		#address-cells = <1>;
@@ -136,19 +145,19 @@
 				compatible = "xlnx,ll-dma-1.00.a";
 				dcr-reg = < 0x80 0x11 >;
 				interrupt-parent = <&xps_intc_0>;
-				interrupts = < 9 2 0xa 2 >;
+				interrupts = < 10 2 11 2 >;
 			} ;
 		} ;
 	} ;
 	plb_v46_0: plb@0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "xlnx,plb-v46-1.02.a", "simple-bus";
+		compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
 		ranges ;
 		DIP_Switches_8Bit: gpio@81460000 {
 			compatible = "xlnx,xps-gpio-1.00.a";
 			interrupt-parent = <&xps_intc_0>;
-			interrupts = < 6 2 >;
+			interrupts = < 7 2 >;
 			reg = < 0x81460000 0x10000 >;
 			xlnx,all-inputs = <1>;
 			xlnx,all-inputs-2 = <0>;
@@ -163,6 +172,86 @@
 			xlnx,tri-default = <0xffffffff>;
 			xlnx,tri-default-2 = <0xffffffff>;
 		} ;
+		FLASH: flash@fc000000 {
+			bank-width = <2>;
+			compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+			reg = < 0xfc000000 0x2000000 >;
+			xlnx,family = "virtex5";
+			xlnx,include-datawidth-matching-0 = <0x1>;
+			xlnx,include-datawidth-matching-1 = <0x0>;
+			xlnx,include-datawidth-matching-2 = <0x0>;
+			xlnx,include-datawidth-matching-3 = <0x0>;
+			xlnx,include-negedge-ioregs = <0x0>;
+			xlnx,include-plb-ipif = <0x1>;
+			xlnx,include-wrbuf = <0x1>;
+			xlnx,max-mem-width = <0x10>;
+			xlnx,mch-native-dwidth = <0x20>;
+			xlnx,mch-plb-clk-period-ps = <0x2710>;
+			xlnx,mch-splb-awidth = <0x20>;
+			xlnx,mch0-accessbuf-depth = <0x10>;
+			xlnx,mch0-protocol = <0x0>;
+			xlnx,mch0-rddatabuf-depth = <0x10>;
+			xlnx,mch1-accessbuf-depth = <0x10>;
+			xlnx,mch1-protocol = <0x0>;
+			xlnx,mch1-rddatabuf-depth = <0x10>;
+			xlnx,mch2-accessbuf-depth = <0x10>;
+			xlnx,mch2-protocol = <0x0>;
+			xlnx,mch2-rddatabuf-depth = <0x10>;
+			xlnx,mch3-accessbuf-depth = <0x10>;
+			xlnx,mch3-protocol = <0x0>;
+			xlnx,mch3-rddatabuf-depth = <0x10>;
+			xlnx,mem0-width = <0x10>;
+			xlnx,mem1-width = <0x20>;
+			xlnx,mem2-width = <0x20>;
+			xlnx,mem3-width = <0x20>;
+			xlnx,num-banks-mem = <0x1>;
+			xlnx,num-channels = <0x2>;
+			xlnx,priority-mode = <0x0>;
+			xlnx,synch-mem-0 = <0x0>;
+			xlnx,synch-mem-1 = <0x0>;
+			xlnx,synch-mem-2 = <0x0>;
+			xlnx,synch-mem-3 = <0x0>;
+			xlnx,synch-pipedelay-0 = <0x2>;
+			xlnx,synch-pipedelay-1 = <0x2>;
+			xlnx,synch-pipedelay-2 = <0x2>;
+			xlnx,synch-pipedelay-3 = <0x2>;
+			xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+			xlnx,tavdv-ps-mem-1 = <0x3a98>;
+			xlnx,tavdv-ps-mem-2 = <0x3a98>;
+			xlnx,tavdv-ps-mem-3 = <0x3a98>;
+			xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+			xlnx,tcedv-ps-mem-1 = <0x3a98>;
+			xlnx,tcedv-ps-mem-2 = <0x3a98>;
+			xlnx,tcedv-ps-mem-3 = <0x3a98>;
+			xlnx,thzce-ps-mem-0 = <0x88b8>;
+			xlnx,thzce-ps-mem-1 = <0x1b58>;
+			xlnx,thzce-ps-mem-2 = <0x1b58>;
+			xlnx,thzce-ps-mem-3 = <0x1b58>;
+			xlnx,thzoe-ps-mem-0 = <0x1b58>;
+			xlnx,thzoe-ps-mem-1 = <0x1b58>;
+			xlnx,thzoe-ps-mem-2 = <0x1b58>;
+			xlnx,thzoe-ps-mem-3 = <0x1b58>;
+			xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+			xlnx,tlzwe-ps-mem-1 = <0x0>;
+			xlnx,tlzwe-ps-mem-2 = <0x0>;
+			xlnx,tlzwe-ps-mem-3 = <0x0>;
+			xlnx,twc-ps-mem-0 = <0x2af8>;
+			xlnx,twc-ps-mem-1 = <0x3a98>;
+			xlnx,twc-ps-mem-2 = <0x3a98>;
+			xlnx,twc-ps-mem-3 = <0x3a98>;
+			xlnx,twp-ps-mem-0 = <0x11170>;
+			xlnx,twp-ps-mem-1 = <0x2ee0>;
+			xlnx,twp-ps-mem-2 = <0x2ee0>;
+			xlnx,twp-ps-mem-3 = <0x2ee0>;
+			xlnx,xcl0-linesize = <0x4>;
+			xlnx,xcl0-writexfer = <0x1>;
+			xlnx,xcl1-linesize = <0x4>;
+			xlnx,xcl1-writexfer = <0x1>;
+			xlnx,xcl2-linesize = <0x4>;
+			xlnx,xcl2-writexfer = <0x1>;
+			xlnx,xcl3-linesize = <0x4>;
+			xlnx,xcl3-writexfer = <0x1>;
+		} ;
 		Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -185,6 +274,19 @@
 				xlnx,txfifo = <0x1000>;
 			} ;
 		} ;
+		IIC_EEPROM: i2c@81600000 {
+			compatible = "xlnx,xps-iic-2.00.a";
+			interrupt-parent = <&xps_intc_0>;
+			interrupts = < 6 2 >;
+			reg = < 0x81600000 0x10000 >;
+			xlnx,clk-freq = <0x5f5e100>;
+			xlnx,family = "virtex5";
+			xlnx,gpo-width = <0x1>;
+			xlnx,iic-freq = <0x186a0>;
+			xlnx,scl-inertial-delay = <0x0>;
+			xlnx,sda-inertial-delay = <0x0>;
+			xlnx,ten-bit-adr = <0x0>;
+		} ;
 		LEDs_8Bit: gpio@81400000 {
 			compatible = "xlnx,xps-gpio-1.00.a";
 			reg = < 0x81400000 0x10000 >;
@@ -220,7 +322,7 @@
 		Push_Buttons_5Bit: gpio@81440000 {
 			compatible = "xlnx,xps-gpio-1.00.a";
 			interrupt-parent = <&xps_intc_0>;
-			interrupts = < 7 2 >;
+			interrupts = < 8 2 >;
 			reg = < 0x81440000 0x10000 >;
 			xlnx,all-inputs = <1>;
 			xlnx,all-inputs-2 = <0>;
@@ -237,13 +339,13 @@
 		} ;
 		RS232_Uart_1: serial@83e00000 {
 			clock-frequency = <100000000>;
-			compatible = "xlnx,xps-uart16550-2.00.a", "ns16550";
-			current-speed = <0x2580>;
+			compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";
+			current-speed = <9600>;
 			device_type = "serial";
 			interrupt-parent = <&xps_intc_0>;
-			interrupts = < 8 2 >;
+			interrupts = < 9 2 >;
 			reg = < 0x83e00000 0x10000 >;
-			reg-offset = <3>;
+			reg-offset = <0x1003>;
 			reg-shift = <2>;
 			xlnx,family = "virtex5";
 			xlnx,has-external-rclk = <0>;
@@ -268,7 +370,7 @@
 			compatible = "xlnx,xps-intc-1.00.a";
 			interrupt-controller ;
 			reg = < 0x81800000 0x10000 >;
-			xlnx,num-intr-inputs = <0xb>;
+			xlnx,num-intr-inputs = <0xc>;
 		} ;
 		xps_timebase_wdt_1: xps-timebase-wdt@83a00000 {
 			compatible = "xlnx,xps-timebase-wdt-1.00.b";
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,201 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_check_header(const void *fdt)
-{
-	if (fdt_magic(fdt) == FDT_MAGIC) {
-		/* Complete tree */
-		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
-			return -FDT_ERR_BADVERSION;
-		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
-			return -FDT_ERR_BADVERSION;
-	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
-		/* Unfinished sequential-write blob */
-		if (fdt_size_dt_struct(fdt) == 0)
-			return -FDT_ERR_BADSTATE;
-	} else {
-		return -FDT_ERR_BADMAGIC;
-	}
-
-	return 0;
-}
-
-const void *fdt_offset_ptr(const void *fdt, int offset, int len)
-{
-	const char *p;
-
-	if (fdt_version(fdt) >= 0x11)
-		if (((offset + len) < offset)
-		    || ((offset + len) > fdt_size_dt_struct(fdt)))
-			return NULL;
-
-	p = _fdt_offset_ptr(fdt, offset);
-
-	if (p + len < p)
-		return NULL;
-	return p;
-}
-
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
-{
-	const uint32_t *tagp, *lenp;
-	uint32_t tag;
-	const char *p;
-
-	if (offset % FDT_TAGSIZE)
-		return -1;
-
-	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
-	if (! tagp)
-		return FDT_END; /* premature end */
-	tag = fdt32_to_cpu(*tagp);
-	offset += FDT_TAGSIZE;
-
-	switch (tag) {
-	case FDT_BEGIN_NODE:
-		/* skip name */
-		do {
-			p = fdt_offset_ptr(fdt, offset++, 1);
-		} while (p && (*p != '\0'));
-		if (! p)
-			return FDT_END;
-		break;
-	case FDT_PROP:
-		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
-		if (! lenp)
-			return FDT_END;
-		/* skip name offset, length and value */
-		offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
-		break;
-	}
-
-	if (nextoffset)
-		*nextoffset = FDT_TAGALIGN(offset);
-
-	return tag;
-}
-
-int _fdt_check_node_offset(const void *fdt, int offset)
-{
-	if ((offset < 0) || (offset % FDT_TAGSIZE)
-	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
-		return -FDT_ERR_BADOFFSET;
-
-	return offset;
-}
-
-int fdt_next_node(const void *fdt, int offset, int *depth)
-{
-	int nextoffset = 0;
-	uint32_t tag;
-
-	if (offset >= 0)
-		if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
-			return nextoffset;
-
-	do {
-		offset = nextoffset;
-		tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-		switch (tag) {
-		case FDT_PROP:
-		case FDT_NOP:
-			break;
-
-		case FDT_BEGIN_NODE:
-			if (depth)
-				(*depth)++;
-			break;
-
-		case FDT_END_NODE:
-			if (depth)
-				(*depth)--;
-			break;
-
-		case FDT_END:
-			return -FDT_ERR_NOTFOUND;
-
-		default:
-			return -FDT_ERR_BADSTRUCTURE;
-		}
-	} while (tag != FDT_BEGIN_NODE);
-
-	return offset;
-}
-
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
-{
-	int len = strlen(s) + 1;
-	const char *last = strtab + tabsize - len;
-	const char *p;
-
-	for (p = strtab; p <= last; p++)
-		if (memcmp(p, s, len) == 0)
-			return p;
-	return NULL;
-}
-
-int fdt_move(const void *fdt, void *buf, int bufsize)
-{
-	FDT_CHECK_HEADER(fdt);
-
-	if (fdt_totalsize(fdt) > bufsize)
-		return -FDT_ERR_NOSPACE;
-
-	memmove(buf, fdt, fdt_totalsize(fdt));
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-#ifndef _FDT_H
-#define _FDT_H
-
-#ifndef __ASSEMBLY__
-
-struct fdt_header {
-	uint32_t magic;			 /* magic word FDT_MAGIC */
-	uint32_t totalsize;		 /* total size of DT block */
-	uint32_t off_dt_struct;		 /* offset to structure */
-	uint32_t off_dt_strings;	 /* offset to strings */
-	uint32_t off_mem_rsvmap;	 /* offset to memory reserve map */
-	uint32_t version;		 /* format version */
-	uint32_t last_comp_version;	 /* last compatible version */
-
-	/* version 2 fields below */
-	uint32_t boot_cpuid_phys;	 /* Which physical CPU id we're
-					    booting on */
-	/* version 3 fields below */
-	uint32_t size_dt_strings;	 /* size of the strings block */
-
-	/* version 17 fields below */
-	uint32_t size_dt_struct;	 /* size of the structure block */
-};
-
-struct fdt_reserve_entry {
-	uint64_t address;
-	uint64_t size;
-};
-
-struct fdt_node_header {
-	uint32_t tag;
-	char name[0];
-};
-
-struct fdt_property {
-	uint32_t tag;
-	uint32_t len;
-	uint32_t nameoff;
-	char data[0];
-};
-
-#endif /* !__ASSEMBLY */
-
-#define FDT_MAGIC	0xd00dfeed	/* 4: version, 4: total size */
-#define FDT_TAGSIZE	sizeof(uint32_t)
-
-#define FDT_BEGIN_NODE	0x1		/* Start node: full name */
-#define FDT_END_NODE	0x2		/* End node */
-#define FDT_PROP	0x3		/* Property: name off,
-					   size, content */
-#define FDT_NOP		0x4		/* nop */
-#define FDT_END		0x9
-
-#define FDT_V1_SIZE	(7*sizeof(uint32_t))
-#define FDT_V2_SIZE	(FDT_V1_SIZE + sizeof(uint32_t))
-#define FDT_V3_SIZE	(FDT_V2_SIZE + sizeof(uint32_t))
-#define FDT_V16_SIZE	FDT_V3_SIZE
-#define FDT_V17_SIZE	(FDT_V16_SIZE + sizeof(uint32_t))
-
-#endif /* _FDT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_ro.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_ro.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_ro.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_ro.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,469 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_nodename_eq(const void *fdt, int offset,
-			    const char *s, int len)
-{
-	const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
-
-	if (! p)
-		/* short match */
-		return 0;
-
-	if (memcmp(p, s, len) != 0)
-		return 0;
-
-	if (p[len] == '\0')
-		return 1;
-	else if (!memchr(s, '@', len) && (p[len] == '@'))
-		return 1;
-	else
-		return 0;
-}
-
-const char *fdt_string(const void *fdt, int stroffset)
-{
-	return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
-}
-
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
-{
-	FDT_CHECK_HEADER(fdt);
-	*address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
-	*size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
-	return 0;
-}
-
-int fdt_num_mem_rsv(const void *fdt)
-{
-	int i = 0;
-
-	while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
-		i++;
-	return i;
-}
-
-int fdt_subnode_offset_namelen(const void *fdt, int offset,
-			       const char *name, int namelen)
-{
-	int depth;
-
-	FDT_CHECK_HEADER(fdt);
-
-	for (depth = 0, offset = fdt_next_node(fdt, offset, &depth);
-	     (offset >= 0) && (depth > 0);
-	     offset = fdt_next_node(fdt, offset, &depth)) {
-		if (depth < 0)
-			return -FDT_ERR_NOTFOUND;
-		else if ((depth == 1)
-			 && _fdt_nodename_eq(fdt, offset, name, namelen))
-			return offset;
-	}
-
-	if (offset < 0)
-		return offset; /* error */
-	else
-		return -FDT_ERR_NOTFOUND;
-}
-
-int fdt_subnode_offset(const void *fdt, int parentoffset,
-		       const char *name)
-{
-	return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_path_offset(const void *fdt, const char *path)
-{
-	const char *end = path + strlen(path);
-	const char *p = path;
-	int offset = 0;
-
-	FDT_CHECK_HEADER(fdt);
-
-	if (*path != '/')
-		return -FDT_ERR_BADPATH;
-
-	while (*p) {
-		const char *q;
-
-		while (*p == '/')
-			p++;
-		if (! *p)
-			return offset;
-		q = strchr(p, '/');
-		if (! q)
-			q = end;
-
-		offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
-		if (offset < 0)
-			return offset;
-
-		p = q;
-	}
-
-	return offset;
-}
-
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
-{
-	const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
-	int err;
-
-	if (((err = fdt_check_header(fdt)) != 0)
-	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
-			goto fail;
-
-	if (len)
-		*len = strlen(nh->name);
-
-	return nh->name;
-
- fail:
-	if (len)
-		*len = err;
-	return NULL;
-}
-
-const struct fdt_property *fdt_get_property(const void *fdt,
-					    int nodeoffset,
-					    const char *name, int *lenp)
-{
-	uint32_t tag;
-	const struct fdt_property *prop;
-	int namestroff;
-	int offset, nextoffset;
-	int err;
-
-	if (((err = fdt_check_header(fdt)) != 0)
-	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
-			goto fail;
-
-	nextoffset = err;
-	do {
-		offset = nextoffset;
-
-		tag = fdt_next_tag(fdt, offset, &nextoffset);
-		switch (tag) {
-		case FDT_END:
-			err = -FDT_ERR_TRUNCATED;
-			goto fail;
-
-		case FDT_BEGIN_NODE:
-		case FDT_END_NODE:
-		case FDT_NOP:
-			break;
-
-		case FDT_PROP:
-			err = -FDT_ERR_BADSTRUCTURE;
-			prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
-			if (! prop)
-				goto fail;
-			namestroff = fdt32_to_cpu(prop->nameoff);
-			if (strcmp(fdt_string(fdt, namestroff), name) == 0) {
-				/* Found it! */
-				int len = fdt32_to_cpu(prop->len);
-				prop = fdt_offset_ptr(fdt, offset,
-						      sizeof(*prop)+len);
-				if (! prop)
-					goto fail;
-
-				if (lenp)
-					*lenp = len;
-
-				return prop;
-			}
-			break;
-
-		default:
-			err = -FDT_ERR_BADSTRUCTURE;
-			goto fail;
-		}
-	} while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
-
-	err = -FDT_ERR_NOTFOUND;
- fail:
-	if (lenp)
-		*lenp = err;
-	return NULL;
-}
-
-const void *fdt_getprop(const void *fdt, int nodeoffset,
-		  const char *name, int *lenp)
-{
-	const struct fdt_property *prop;
-
-	prop = fdt_get_property(fdt, nodeoffset, name, lenp);
-	if (! prop)
-		return NULL;
-
-	return prop->data;
-}
-
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
-{
-	const uint32_t *php;
-	int len;
-
-	php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
-	if (!php || (len != sizeof(*php)))
-		return 0;
-
-	return fdt32_to_cpu(*php);
-}
-
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
-{
-	int pdepth = 0, p = 0;
-	int offset, depth, namelen;
-	const char *name;
-
-	FDT_CHECK_HEADER(fdt);
-
-	if (buflen < 2)
-		return -FDT_ERR_NOSPACE;
-
-	for (offset = 0, depth = 0;
-	     (offset >= 0) && (offset <= nodeoffset);
-	     offset = fdt_next_node(fdt, offset, &depth)) {
-		if (pdepth < depth)
-			continue; /* overflowed buffer */
-
-		while (pdepth > depth) {
-			do {
-				p--;
-			} while (buf[p-1] != '/');
-			pdepth--;
-		}
-
-		name = fdt_get_name(fdt, offset, &namelen);
-		if (!name)
-			return namelen;
-		if ((p + namelen + 1) <= buflen) {
-			memcpy(buf + p, name, namelen);
-			p += namelen;
-			buf[p++] = '/';
-			pdepth++;
-		}
-
-		if (offset == nodeoffset) {
-			if (pdepth < (depth + 1))
-				return -FDT_ERR_NOSPACE;
-
-			if (p > 1) /* special case so that root path is "/", not "" */
-				p--;
-			buf[p] = '\0';
-			return p;
-		}
-	}
-
-	if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
-		return -FDT_ERR_BADOFFSET;
-	else if (offset == -FDT_ERR_BADOFFSET)
-		return -FDT_ERR_BADSTRUCTURE;
-
-	return offset; /* error from fdt_next_node() */
-}
-
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
-				 int supernodedepth, int *nodedepth)
-{
-	int offset, depth;
-	int supernodeoffset = -FDT_ERR_INTERNAL;
-
-	FDT_CHECK_HEADER(fdt);
-
-	if (supernodedepth < 0)
-		return -FDT_ERR_NOTFOUND;
-
-	for (offset = 0, depth = 0;
-	     (offset >= 0) && (offset <= nodeoffset);
-	     offset = fdt_next_node(fdt, offset, &depth)) {
-		if (depth == supernodedepth)
-			supernodeoffset = offset;
-
-		if (offset == nodeoffset) {
-			if (nodedepth)
-				*nodedepth = depth;
-
-			if (supernodedepth > depth)
-				return -FDT_ERR_NOTFOUND;
-			else
-				return supernodeoffset;
-		}
-	}
-
-	if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
-		return -FDT_ERR_BADOFFSET;
-	else if (offset == -FDT_ERR_BADOFFSET)
-		return -FDT_ERR_BADSTRUCTURE;
-
-	return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_depth(const void *fdt, int nodeoffset)
-{
-	int nodedepth;
-	int err;
-
-	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
-	if (err)
-		return (err < 0) ? err : -FDT_ERR_INTERNAL;
-	return nodedepth;
-}
-
-int fdt_parent_offset(const void *fdt, int nodeoffset)
-{
-	int nodedepth = fdt_node_depth(fdt, nodeoffset);
-
-	if (nodedepth < 0)
-		return nodedepth;
-	return fdt_supernode_atdepth_offset(fdt, nodeoffset,
-					    nodedepth - 1, NULL);
-}
-
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
-				  const char *propname,
-				  const void *propval, int proplen)
-{
-	int offset;
-	const void *val;
-	int len;
-
-	FDT_CHECK_HEADER(fdt);
-
-	/* FIXME: The algorithm here is pretty horrible: we scan each
-	 * property of a node in fdt_getprop(), then if that didn't
-	 * find what we want, we scan over them again making our way
-	 * to the next node.  Still it's the easiest to implement
-	 * approach; performance can come later. */
-	for (offset = fdt_next_node(fdt, startoffset, NULL);
-	     offset >= 0;
-	     offset = fdt_next_node(fdt, offset, NULL)) {
-		val = fdt_getprop(fdt, offset, propname, &len);
-		if (val && (len == proplen)
-		    && (memcmp(val, propval, len) == 0))
-			return offset;
-	}
-
-	return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
-{
-	if ((phandle == 0) || (phandle == -1))
-		return -FDT_ERR_BADPHANDLE;
-	phandle = cpu_to_fdt32(phandle);
-	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
-					     &phandle, sizeof(phandle));
-}
-
-int _stringlist_contains(const char *strlist, int listlen, const char *str)
-{
-	int len = strlen(str);
-	const char *p;
-
-	while (listlen >= len) {
-		if (memcmp(str, strlist, len+1) == 0)
-			return 1;
-		p = memchr(strlist, '\0', listlen);
-		if (!p)
-			return 0; /* malformed strlist.. */
-		listlen -= (p-strlist) + 1;
-		strlist = p + 1;
-	}
-	return 0;
-}
-
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
-			      const char *compatible)
-{
-	const void *prop;
-	int len;
-
-	prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
-	if (!prop)
-		return len;
-	if (_stringlist_contains(prop, len, compatible))
-		return 0;
-	else
-		return 1;
-}
-
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
-				  const char *compatible)
-{
-	int offset, err;
-
-	FDT_CHECK_HEADER(fdt);
-
-	/* FIXME: The algorithm here is pretty horrible: we scan each
-	 * property of a node in fdt_node_check_compatible(), then if
-	 * that didn't find what we want, we scan over them again
-	 * making our way to the next node.  Still it's the easiest to
-	 * implement approach; performance can come later. */
-	for (offset = fdt_next_node(fdt, startoffset, NULL);
-	     offset >= 0;
-	     offset = fdt_next_node(fdt, offset, NULL)) {
-		err = fdt_node_check_compatible(fdt, offset, compatible);
-		if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
-			return err;
-		else if (err == 0)
-			return offset;
-	}
-
-	return offset; /* error from fdt_next_node() */
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_rw.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_rw.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_rw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_rw.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,463 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_blocks_misordered(const void *fdt,
-			      int mem_rsv_size, int struct_size)
-{
-	return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
-		|| (fdt_off_dt_struct(fdt) <
-		    (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
-		|| (fdt_off_dt_strings(fdt) <
-		    (fdt_off_dt_struct(fdt) + struct_size))
-		|| (fdt_totalsize(fdt) <
-		    (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
-}
-
-static int _fdt_rw_check_header(void *fdt)
-{
-	FDT_CHECK_HEADER(fdt);
-
-	if (fdt_version(fdt) < 17)
-		return -FDT_ERR_BADVERSION;
-	if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
-				   fdt_size_dt_struct(fdt)))
-		return -FDT_ERR_BADLAYOUT;
-	if (fdt_version(fdt) > 17)
-		fdt_set_version(fdt, 17);
-
-	return 0;
-}
-
-#define FDT_RW_CHECK_HEADER(fdt) \
-	{ \
-		int err; \
-		if ((err = _fdt_rw_check_header(fdt)) != 0) \
-			return err; \
-	}
-
-static inline int _fdt_data_size(void *fdt)
-{
-	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
-}
-
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
-{
-	char *p = splicepoint;
-	char *end = (char *)fdt + _fdt_data_size(fdt);
-
-	if (((p + oldlen) < p) || ((p + oldlen) > end))
-		return -FDT_ERR_BADOFFSET;
-	if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
-		return -FDT_ERR_NOSPACE;
-	memmove(p + newlen, p + oldlen, end - p - oldlen);
-	return 0;
-}
-
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
-			       int oldn, int newn)
-{
-	int delta = (newn - oldn) * sizeof(*p);
-	int err;
-	err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
-	if (err)
-		return err;
-	fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
-	fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
-	return 0;
-}
-
-static int _fdt_splice_struct(void *fdt, void *p,
-			      int oldlen, int newlen)
-{
-	int delta = newlen - oldlen;
-	int err;
-
-	if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
-		return err;
-
-	fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
-	fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
-	return 0;
-}
-
-static int _fdt_splice_string(void *fdt, int newlen)
-{
-	void *p = (char *)fdt
-		+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
-	int err;
-
-	if ((err = _fdt_splice(fdt, p, 0, newlen)))
-		return err;
-
-	fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
-	return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
-	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
-	const char *p;
-	char *new;
-	int len = strlen(s) + 1;
-	int err;
-
-	p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
-	if (p)
-		/* found it */
-		return (p - strtab);
-
-	new = strtab + fdt_size_dt_strings(fdt);
-	err = _fdt_splice_string(fdt, len);
-	if (err)
-		return err;
-
-	memcpy(new, s, len);
-	return (new - strtab);
-}
-
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
-{
-	struct fdt_reserve_entry *re;
-	int err;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
-	err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
-	if (err)
-		return err;
-
-	re->address = cpu_to_fdt64(address);
-	re->size = cpu_to_fdt64(size);
-	return 0;
-}
-
-int fdt_del_mem_rsv(void *fdt, int n)
-{
-	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
-	int err;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	if (n >= fdt_num_mem_rsv(fdt))
-		return -FDT_ERR_NOTFOUND;
-
-	err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
-	if (err)
-		return err;
-	return 0;
-}
-
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
-				int len, struct fdt_property **prop)
-{
-	int oldlen;
-	int err;
-
-	*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
-	if (! (*prop))
-		return oldlen;
-
-	if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
-				      FDT_TAGALIGN(len))))
-		return err;
-
-	(*prop)->len = cpu_to_fdt32(len);
-	return 0;
-}
-
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
-			     int len, struct fdt_property **prop)
-{
-	int proplen;
-	int nextoffset;
-	int namestroff;
-	int err;
-
-	if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
-		return nextoffset;
-
-	namestroff = _fdt_find_add_string(fdt, name);
-	if (namestroff < 0)
-		return namestroff;
-
-	*prop = _fdt_offset_ptr_w(fdt, nextoffset);
-	proplen = sizeof(**prop) + FDT_TAGALIGN(len);
-
-	err = _fdt_splice_struct(fdt, *prop, 0, proplen);
-	if (err)
-		return err;
-
-	(*prop)->tag = cpu_to_fdt32(FDT_PROP);
-	(*prop)->nameoff = cpu_to_fdt32(namestroff);
-	(*prop)->len = cpu_to_fdt32(len);
-	return 0;
-}
-
-int fdt_set_name(void *fdt, int nodeoffset, const char *name)
-{
-	char *namep;
-	int oldlen, newlen;
-	int err;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
-	if (!namep)
-		return oldlen;
-
-	newlen = strlen(name);
-
-	err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
-				 FDT_TAGALIGN(newlen+1));
-	if (err)
-		return err;
-
-	memcpy(namep, name, newlen+1);
-	return 0;
-}
-
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
-		const void *val, int len)
-{
-	struct fdt_property *prop;
-	int err;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
-	if (err == -FDT_ERR_NOTFOUND)
-		err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
-	if (err)
-		return err;
-
-	memcpy(prop->data, val, len);
-	return 0;
-}
-
-int fdt_delprop(void *fdt, int nodeoffset, const char *name)
-{
-	struct fdt_property *prop;
-	int len, proplen;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
-	if (! prop)
-		return len;
-
-	proplen = sizeof(*prop) + FDT_TAGALIGN(len);
-	return _fdt_splice_struct(fdt, prop, proplen, 0);
-}
-
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
-			    const char *name, int namelen)
-{
-	struct fdt_node_header *nh;
-	int offset, nextoffset;
-	int nodelen;
-	int err;
-	uint32_t tag;
-	uint32_t *endtag;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
-	if (offset >= 0)
-		return -FDT_ERR_EXISTS;
-	else if (offset != -FDT_ERR_NOTFOUND)
-		return offset;
-
-	/* Try to place the new node after the parent's properties */
-	fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
-	do {
-		offset = nextoffset;
-		tag = fdt_next_tag(fdt, offset, &nextoffset);
-	} while ((tag == FDT_PROP) || (tag == FDT_NOP));
-
-	nh = _fdt_offset_ptr_w(fdt, offset);
-	nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
-
-	err = _fdt_splice_struct(fdt, nh, 0, nodelen);
-	if (err)
-		return err;
-
-	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
-	memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
-	memcpy(nh->name, name, namelen);
-	endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
-	*endtag = cpu_to_fdt32(FDT_END_NODE);
-
-	return offset;
-}
-
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
-{
-	return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_del_node(void *fdt, int nodeoffset)
-{
-	int endoffset;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
-	if (endoffset < 0)
-		return endoffset;
-
-	return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
-				  endoffset - nodeoffset, 0);
-}
-
-static void _fdt_packblocks(const char *old, char *new,
-			    int mem_rsv_size, int struct_size)
-{
-	int mem_rsv_off, struct_off, strings_off;
-
-	mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
-	struct_off = mem_rsv_off + mem_rsv_size;
-	strings_off = struct_off + struct_size;
-
-	memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
-	fdt_set_off_mem_rsvmap(new, mem_rsv_off);
-
-	memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
-	fdt_set_off_dt_struct(new, struct_off);
-	fdt_set_size_dt_struct(new, struct_size);
-
-	memmove(new + strings_off, old + fdt_off_dt_strings(old),
-		fdt_size_dt_strings(old));
-	fdt_set_off_dt_strings(new, strings_off);
-	fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
-}
-
-int fdt_open_into(const void *fdt, void *buf, int bufsize)
-{
-	int err;
-	int mem_rsv_size, struct_size;
-	int newsize;
-	const char *fdtstart = fdt;
-	const char *fdtend = fdtstart + fdt_totalsize(fdt);
-	char *tmp;
-
-	FDT_CHECK_HEADER(fdt);
-
-	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
-		* sizeof(struct fdt_reserve_entry);
-
-	if (fdt_version(fdt) >= 17) {
-		struct_size = fdt_size_dt_struct(fdt);
-	} else {
-		struct_size = 0;
-		while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
-			;
-	}
-
-	if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
-		/* no further work necessary */
-		err = fdt_move(fdt, buf, bufsize);
-		if (err)
-			return err;
-		fdt_set_version(buf, 17);
-		fdt_set_size_dt_struct(buf, struct_size);
-		fdt_set_totalsize(buf, bufsize);
-		return 0;
-	}
-
-	/* Need to reorder */
-	newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
-		+ struct_size + fdt_size_dt_strings(fdt);
-
-	if (bufsize < newsize)
-		return -FDT_ERR_NOSPACE;
-
-	/* First attempt to build converted tree at beginning of buffer */
-	tmp = buf;
-	/* But if that overlaps with the old tree... */
-	if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
-		/* Try right after the old tree instead */
-		tmp = (char *)(uintptr_t)fdtend;
-		if ((tmp + newsize) > ((char *)buf + bufsize))
-			return -FDT_ERR_NOSPACE;
-	}
-
-	_fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
-	memmove(buf, tmp, newsize);
-
-	fdt_set_magic(buf, FDT_MAGIC);
-	fdt_set_totalsize(buf, bufsize);
-	fdt_set_version(buf, 17);
-	fdt_set_last_comp_version(buf, 16);
-	fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
-
-	return 0;
-}
-
-int fdt_pack(void *fdt)
-{
-	int mem_rsv_size;
-
-	FDT_RW_CHECK_HEADER(fdt);
-
-	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
-		* sizeof(struct fdt_reserve_entry);
-	_fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
-	fdt_set_totalsize(fdt, _fdt_data_size(fdt));
-
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_strerror.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_strerror.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_strerror.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_strerror.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-struct fdt_errtabent {
-	const char *str;
-};
-
-#define FDT_ERRTABENT(val) \
-	[(val)] = { .str = #val, }
-
-static struct fdt_errtabent fdt_errtable[] = {
-	FDT_ERRTABENT(FDT_ERR_NOTFOUND),
-	FDT_ERRTABENT(FDT_ERR_EXISTS),
-	FDT_ERRTABENT(FDT_ERR_NOSPACE),
-
-	FDT_ERRTABENT(FDT_ERR_BADOFFSET),
-	FDT_ERRTABENT(FDT_ERR_BADPATH),
-	FDT_ERRTABENT(FDT_ERR_BADSTATE),
-
-	FDT_ERRTABENT(FDT_ERR_TRUNCATED),
-	FDT_ERRTABENT(FDT_ERR_BADMAGIC),
-	FDT_ERRTABENT(FDT_ERR_BADVERSION),
-	FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
-	FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
-};
-#define FDT_ERRTABSIZE	(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-
-const char *fdt_strerror(int errval)
-{
-	if (errval > 0)
-		return "<valid offset/length>";
-	else if (errval == 0)
-		return "<no error>";
-	else if (errval > -FDT_ERRTABSIZE) {
-		const char *s = fdt_errtable[-errval].str;
-
-		if (s)
-			return s;
-	}
-
-	return "<unknown error>";
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_sw.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_sw.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_sw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_sw.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,257 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_sw_check_header(void *fdt)
-{
-	if (fdt_magic(fdt) != FDT_SW_MAGIC)
-		return -FDT_ERR_BADMAGIC;
-	/* FIXME: should check more details about the header state */
-	return 0;
-}
-
-#define FDT_SW_CHECK_HEADER(fdt) \
-	{ \
-		int err; \
-		if ((err = _fdt_sw_check_header(fdt)) != 0) \
-			return err; \
-	}
-
-static void *_fdt_grab_space(void *fdt, int len)
-{
-	int offset = fdt_size_dt_struct(fdt);
-	int spaceleft;
-
-	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
-		- fdt_size_dt_strings(fdt);
-
-	if ((offset + len < offset) || (offset + len > spaceleft))
-		return NULL;
-
-	fdt_set_size_dt_struct(fdt, offset + len);
-	return fdt_offset_ptr_w(fdt, offset, len);
-}
-
-int fdt_create(void *buf, int bufsize)
-{
-	void *fdt = buf;
-
-	if (bufsize < sizeof(struct fdt_header))
-		return -FDT_ERR_NOSPACE;
-
-	memset(buf, 0, bufsize);
-
-	fdt_set_magic(fdt, FDT_SW_MAGIC);
-	fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
-	fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
-	fdt_set_totalsize(fdt,  bufsize);
-
-	fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
-					      sizeof(struct fdt_reserve_entry)));
-	fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
-	fdt_set_off_dt_strings(fdt, bufsize);
-
-	return 0;
-}
-
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
-{
-	struct fdt_reserve_entry *re;
-	int offset;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	if (fdt_size_dt_struct(fdt))
-		return -FDT_ERR_BADSTATE;
-
-	offset = fdt_off_dt_struct(fdt);
-	if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
-		return -FDT_ERR_NOSPACE;
-
-	re = (struct fdt_reserve_entry *)((char *)fdt + offset);
-	re->address = cpu_to_fdt64(addr);
-	re->size = cpu_to_fdt64(size);
-
-	fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
-
-	return 0;
-}
-
-int fdt_finish_reservemap(void *fdt)
-{
-	return fdt_add_reservemap_entry(fdt, 0, 0);
-}
-
-int fdt_begin_node(void *fdt, const char *name)
-{
-	struct fdt_node_header *nh;
-	int namelen = strlen(name) + 1;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
-	if (! nh)
-		return -FDT_ERR_NOSPACE;
-
-	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
-	memcpy(nh->name, name, namelen);
-	return 0;
-}
-
-int fdt_end_node(void *fdt)
-{
-	uint32_t *en;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	en = _fdt_grab_space(fdt, FDT_TAGSIZE);
-	if (! en)
-		return -FDT_ERR_NOSPACE;
-
-	*en = cpu_to_fdt32(FDT_END_NODE);
-	return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
-	char *strtab = (char *)fdt + fdt_totalsize(fdt);
-	const char *p;
-	int strtabsize = fdt_size_dt_strings(fdt);
-	int len = strlen(s) + 1;
-	int struct_top, offset;
-
-	p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
-	if (p)
-		return p - strtab;
-
-	/* Add it */
-	offset = -strtabsize - len;
-	struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
-	if (fdt_totalsize(fdt) + offset < struct_top)
-		return 0; /* no more room :( */
-
-	memcpy(strtab + offset, s, len);
-	fdt_set_size_dt_strings(fdt, strtabsize + len);
-	return offset;
-}
-
-int fdt_property(void *fdt, const char *name, const void *val, int len)
-{
-	struct fdt_property *prop;
-	int nameoff;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	nameoff = _fdt_find_add_string(fdt, name);
-	if (nameoff == 0)
-		return -FDT_ERR_NOSPACE;
-
-	prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
-	if (! prop)
-		return -FDT_ERR_NOSPACE;
-
-	prop->tag = cpu_to_fdt32(FDT_PROP);
-	prop->nameoff = cpu_to_fdt32(nameoff);
-	prop->len = cpu_to_fdt32(len);
-	memcpy(prop->data, val, len);
-	return 0;
-}
-
-int fdt_finish(void *fdt)
-{
-	char *p = (char *)fdt;
-	uint32_t *end;
-	int oldstroffset, newstroffset;
-	uint32_t tag;
-	int offset, nextoffset;
-
-	FDT_SW_CHECK_HEADER(fdt);
-
-	/* Add terminator */
-	end = _fdt_grab_space(fdt, sizeof(*end));
-	if (! end)
-		return -FDT_ERR_NOSPACE;
-	*end = cpu_to_fdt32(FDT_END);
-
-	/* Relocate the string table */
-	oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
-	newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
-	memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
-	fdt_set_off_dt_strings(fdt, newstroffset);
-
-	/* Walk the structure, correcting string offsets */
-	offset = 0;
-	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
-		if (tag == FDT_PROP) {
-			struct fdt_property *prop =
-				fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
-			int nameoff;
-
-			if (! prop)
-				return -FDT_ERR_BADSTRUCTURE;
-
-			nameoff = fdt32_to_cpu(prop->nameoff);
-			nameoff += fdt_size_dt_strings(fdt);
-			prop->nameoff = cpu_to_fdt32(nameoff);
-		}
-		offset = nextoffset;
-	}
-
-	/* Finally, adjust the header */
-	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
-	fdt_set_magic(fdt, FDT_MAGIC);
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_wip.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_wip.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/fdt_wip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/fdt_wip.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
-			const void *val, int len)
-{
-	void *propval;
-	int proplen;
-
-	propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
-	if (! propval)
-		return proplen;
-
-	if (proplen != len)
-		return -FDT_ERR_NOSPACE;
-
-	memcpy(propval, val, len);
-	return 0;
-}
-
-static void _fdt_nop_region(void *start, int len)
-{
-	uint32_t *p;
-
-	for (p = start; (char *)p < ((char *)start + len); p++)
-		*p = cpu_to_fdt32(FDT_NOP);
-}
-
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
-{
-	struct fdt_property *prop;
-	int len;
-
-	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
-	if (! prop)
-		return len;
-
-	_fdt_nop_region(prop, len + sizeof(*prop));
-
-	return 0;
-}
-
-int _fdt_node_end_offset(void *fdt, int nodeoffset)
-{
-	int level = 0;
-	uint32_t tag;
-	int offset, nextoffset;
-
-	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
-	if (tag != FDT_BEGIN_NODE)
-		return -FDT_ERR_BADOFFSET;
-	do {
-		offset = nextoffset;
-		tag = fdt_next_tag(fdt, offset, &nextoffset);
-
-		switch (tag) {
-		case FDT_END:
-			return offset;
-
-		case FDT_BEGIN_NODE:
-			level++;
-			break;
-
-		case FDT_END_NODE:
-			level--;
-			break;
-
-		case FDT_PROP:
-		case FDT_NOP:
-			break;
-
-		default:
-			return -FDT_ERR_BADSTRUCTURE;
-		}
-	} while (level >= 0);
-
-	return nextoffset;
-}
-
-int fdt_nop_node(void *fdt, int nodeoffset)
-{
-	int endoffset;
-
-	endoffset = _fdt_node_end_offset(fdt, nodeoffset);
-	if (endoffset < 0)
-		return endoffset;
-
-	_fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
-			endoffset - nodeoffset);
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/libfdt.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/libfdt.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/libfdt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/libfdt.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1076 +0,0 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <libfdt_env.h>
-#include <fdt.h>
-
-#define FDT_FIRST_SUPPORTED_VERSION	0x10
-#define FDT_LAST_SUPPORTED_VERSION	0x11
-
-/* Error codes: informative error codes */
-#define FDT_ERR_NOTFOUND	1
-	/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
-#define FDT_ERR_EXISTS		2
-	/* FDT_ERR_EXISTS: Attemped to create a node or property which
-	 * already exists */
-#define FDT_ERR_NOSPACE		3
-	/* FDT_ERR_NOSPACE: Operation needed to expand the device
-	 * tree, but its buffer did not have sufficient space to
-	 * contain the expanded tree. Use fdt_open_into() to move the
-	 * device tree to a buffer with more space. */
-
-/* Error codes: codes for bad parameters */
-#define FDT_ERR_BADOFFSET	4
-	/* FDT_ERR_BADOFFSET: Function was passed a structure block
-	 * offset which is out-of-bounds, or which points to an
-	 * unsuitable part of the structure for the operation. */
-#define FDT_ERR_BADPATH		5
-	/* FDT_ERR_BADPATH: Function was passed a badly formatted path
-	 * (e.g. missing a leading / for a function which requires an
-	 * absolute path) */
-#define FDT_ERR_BADPHANDLE	6
-	/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
-	 * value.  phandle values of 0 and -1 are not permitted. */
-#define FDT_ERR_BADSTATE	7
-	/* FDT_ERR_BADSTATE: Function was passed an incomplete device
-	 * tree created by the sequential-write functions, which is
-	 * not sufficiently complete for the requested operation. */
-
-/* Error codes: codes for bad device tree blobs */
-#define FDT_ERR_TRUNCATED	8
-	/* FDT_ERR_TRUNCATED: Structure block of the given device tree
-	 * ends without an FDT_END tag. */
-#define FDT_ERR_BADMAGIC	9
-	/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
-	 * device tree at all - it is missing the flattened device
-	 * tree magic number. */
-#define FDT_ERR_BADVERSION	10
-	/* FDT_ERR_BADVERSION: Given device tree has a version which
-	 * can't be handled by the requested operation.  For
-	 * read-write functions, this may mean that fdt_open_into() is
-	 * required to convert the tree to the expected version. */
-#define FDT_ERR_BADSTRUCTURE	11
-	/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
-	 * structure block or other serious error (e.g. misnested
-	 * nodes, or subnodes preceding properties). */
-#define FDT_ERR_BADLAYOUT	12
-	/* FDT_ERR_BADLAYOUT: For read-write functions, the given
-	 * device tree has it's sub-blocks in an order that the
-	 * function can't handle (memory reserve map, then structure,
-	 * then strings).  Use fdt_open_into() to reorganize the tree
-	 * into a form suitable for the read-write operations. */
-
-/* "Can't happen" error indicating a bug in libfdt */
-#define FDT_ERR_INTERNAL	13
-	/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
-	 * Should never be returned, if it is, it indicates a bug in
-	 * libfdt itself. */
-
-#define FDT_ERR_MAX		13
-
-/**********************************************************************/
-/* Low-level functions (you probably don't need these)                */
-/**********************************************************************/
-
-const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
-static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
-{
-	return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
-}
-
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
-
-/**********************************************************************/
-/* Traversal functions                                                */
-/**********************************************************************/
-
-int fdt_next_node(const void *fdt, int offset, int *depth);
-
-/**********************************************************************/
-/* General functions                                                  */
-/**********************************************************************/
-
-#define fdt_get_header(fdt, field) \
-	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
-#define fdt_magic(fdt) 			(fdt_get_header(fdt, magic))
-#define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
-#define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
-#define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
-#define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
-#define fdt_version(fdt)		(fdt_get_header(fdt, version))
-#define fdt_last_comp_version(fdt) 	(fdt_get_header(fdt, last_comp_version))
-#define fdt_boot_cpuid_phys(fdt) 	(fdt_get_header(fdt, boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt) 	(fdt_get_header(fdt, size_dt_strings))
-#define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
-
-#define __fdt_set_hdr(name) \
-	static inline void fdt_set_##name(void *fdt, uint32_t val) \
-	{ \
-		struct fdt_header *fdth = fdt; \
-		fdth->name = cpu_to_fdt32(val); \
-	}
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
-#undef __fdt_set_hdr
-
-/**
- * fdt_check_header - sanity check a device tree or possible device tree
- * @fdt: pointer to data which might be a flattened device tree
- *
- * fdt_check_header() checks that the given buffer contains what
- * appears to be a flattened device tree with sane information in its
- * header.
- *
- * returns:
- *     0, if the buffer appears to contain a valid device tree
- *     -FDT_ERR_BADMAGIC,
- *     -FDT_ERR_BADVERSION,
- *     -FDT_ERR_BADSTATE, standard meanings, as above
- */
-int fdt_check_header(const void *fdt);
-
-/**
- * fdt_move - move a device tree around in memory
- * @fdt: pointer to the device tree to move
- * @buf: pointer to memory where the device is to be moved
- * @bufsize: size of the memory space at buf
- *
- * fdt_move() relocates, if possible, the device tree blob located at
- * fdt to the buffer at buf of size bufsize.  The buffer may overlap
- * with the existing device tree blob at fdt.  Therefore,
- *     fdt_move(fdt, fdt, fdt_totalsize(fdt))
- * should always succeed.
- *
- * returns:
- *     0, on success
- *     -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
- *     -FDT_ERR_BADMAGIC,
- *     -FDT_ERR_BADVERSION,
- *     -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_move(const void *fdt, void *buf, int bufsize);
-
-/**********************************************************************/
-/* Read-only functions                                                */
-/**********************************************************************/
-
-/**
- * fdt_string - retrieve a string from the strings block of a device tree
- * @fdt: pointer to the device tree blob
- * @stroffset: offset of the string within the strings block (native endian)
- *
- * fdt_string() retrieves a pointer to a single string from the
- * strings block of the device tree blob at fdt.
- *
- * returns:
- *     a pointer to the string, on success
- *     NULL, if stroffset is out of bounds
- */
-const char *fdt_string(const void *fdt, int stroffset);
-
-/**
- * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
- * @fdt: pointer to the device tree blob
- *
- * Returns the number of entries in the device tree blob's memory
- * reservation map.  This does not include the terminating 0,0 entry
- * or any other (0,0) entries reserved for expansion.
- *
- * returns:
- *     the number of entries
- */
-int fdt_num_mem_rsv(const void *fdt);
-
-/**
- * fdt_get_mem_rsv - retrieve one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: pointers to 64-bit variables
- *
- * On success, *address and *size will contain the address and size of
- * the n-th reserve map entry from the device tree blob, in
- * native-endian format.
- *
- * returns:
- *     0, on success
- *     -FDT_ERR_BADMAGIC,
- *     -FDT_ERR_BADVERSION,
- *     -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
-
-/**
- * fdt_subnode_offset_namelen - find a subnode based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_subnode_offset(), but only examine the first
- * namelen characters of name for matching the subnode name.  This is
- * useful for finding subnodes based on a portion of a larger string,
- * such as a full path.
- */
-int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
-			       const char *name, int namelen);
-/**
- * fdt_subnode_offset - find a subnode of a given node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_subnode_offset() finds a subnode of the node at structure block
- * offset parentoffset with the given name.  name may include a unit
- * address, in which case fdt_subnode_offset() will find the subnode
- * with that unit address, or the unit address may be omitted, in
- * which case fdt_subnode_offset() will find an arbitrary subnode
- * whose name excluding unit address matches the given name.
- *
- * returns:
- *	structure block offset of the requested subnode (>=0), on success
- *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
- *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- *      -FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_path_offset - find a tree node by its full path
- * @fdt: pointer to the device tree blob
- * @path: full path of the node to locate
- *
- * fdt_path_offset() finds a node of a given path in the device tree.
- * Each path component may omit the unit address portion, but the
- * results of this are undefined if any such path component is
- * ambiguous (that is if there are multiple nodes at the relevant
- * level matching the given component, differentiated only by unit
- * address).
- *
- * returns:
- *	structure block offset of the node with the requested path (>=0), on success
- *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
- *	-FDT_ERR_NOTFOUND, if the requested node does not exist
- *      -FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_path_offset(const void *fdt, const char *path);
-
-/**
- * fdt_get_name - retrieve the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the starting node
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_name() retrieves the name (including unit address) of the
- * device tree node at structure block offset nodeoffset.  If lenp is
- * non-NULL, the length of this name is also returned, in the integer
- * pointed to by lenp.
- *
- * returns:
- *	pointer to the node's name, on success
- *		If lenp is non-NULL, *lenp contains the length of that name (>=0)
- *	NULL, on error
- *		if lenp is non-NULL *lenp contains an error code (<0):
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *		-FDT_ERR_BADMAGIC,
- *		-FDT_ERR_BADVERSION,
- *		-FDT_ERR_BADSTATE, standard meanings
- */
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
-
-/**
- * fdt_get_property - find a given property in a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_property() retrieves a pointer to the fdt_property
- * structure within the device tree blob corresponding to the property
- * named 'name' of the node at offset nodeoffset.  If lenp is
- * non-NULL, the length of the property value is also returned, in the
- * integer pointed to by lenp.
- *
- * returns:
- *	pointer to the structure representing the property
- *		if lenp is non-NULL, *lenp contains the length of the property
- *		value (>=0)
- *	NULL, on error
- *		if lenp is non-NULL, *lenp contains an error code (<0):
- *		-FDT_ERR_NOTFOUND, node does not have named property
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *		-FDT_ERR_BADMAGIC,
- *		-FDT_ERR_BADVERSION,
- *		-FDT_ERR_BADSTATE,
- *		-FDT_ERR_BADSTRUCTURE,
- *		-FDT_ERR_TRUNCATED, standard meanings
- */
-const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
-					    const char *name, int *lenp);
-static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
-						      const char *name,
-						      int *lenp)
-{
-	return (struct fdt_property *)(uintptr_t)
-		fdt_get_property(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_getprop - retrieve the value of a given property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_getprop() retrieves a pointer to the value of the property
- * named 'name' of the node at offset nodeoffset (this will be a
- * pointer to within the device blob itself, not a copy of the value).
- * If lenp is non-NULL, the length of the property value is also
- * returned, in the integer pointed to by lenp.
- *
- * returns:
- *	pointer to the property's value
- *		if lenp is non-NULL, *lenp contains the length of the property
- *		value (>=0)
- *	NULL, on error
- *		if lenp is non-NULL, *lenp contains an error code (<0):
- *		-FDT_ERR_NOTFOUND, node does not have named property
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *		-FDT_ERR_BADMAGIC,
- *		-FDT_ERR_BADVERSION,
- *		-FDT_ERR_BADSTATE,
- *		-FDT_ERR_BADSTRUCTURE,
- *		-FDT_ERR_TRUNCATED, standard meanings
- */
-const void *fdt_getprop(const void *fdt, int nodeoffset,
-			const char *name, int *lenp);
-static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
-				  const char *name, int *lenp)
-{
-	return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_get_phandle - retrieve the phandle of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the node
- *
- * fdt_get_phandle() retrieves the phandle of the device tree node at
- * structure block offset nodeoffset.
- *
- * returns:
- *	the phandle of the node at nodeoffset, on success (!= 0, != -1)
- *	0, if the node has no phandle, or another error occurs
- */
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
-
-/**
- * fdt_get_path - determine the full path of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose path to find
- * @buf: character buffer to contain the returned path (will be overwritten)
- * @buflen: size of the character buffer at buf
- *
- * fdt_get_path() computes the full path of the node at offset
- * nodeoffset, and records that path in the buffer at buf.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- *	0, on success
- *		buf contains the absolute path of the node at
- *		nodeoffset, as a NUL-terminated string.
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
- *		characters and will not fit in the given buffer.
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
-
-/**
- * fdt_supernode_atdepth_offset - find a specific ancestor of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- * @supernodedepth: depth of the ancestor to find
- * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_supernode_atdepth_offset() finds an ancestor of the given node
- * at a specific depth from the root (where the root itself has depth
- * 0, its immediate subnodes depth 1 and so forth).  So
- *	fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
- * will always return 0, the offset of the root node.  If the node at
- * nodeoffset has depth D, then:
- *	fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
- * will return nodeoffset itself.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
-
- *	structure block offset of the node at node offset's ancestor
- *		of depth supernodedepth (>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
-*	-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
-				 int supernodedepth, int *nodedepth);
-
-/**
- * fdt_node_depth - find the depth of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_node_depth() finds the depth of a given node.  The root node
- * has depth 0, its immediate subnodes depth 1 and so forth.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- *	depth of the node at nodeoffset (>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_depth(const void *fdt, int nodeoffset);
-
-/**
- * fdt_parent_offset - find the parent of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_parent_offset() locates the parent node of a given node (that
- * is, it finds the offset of the node which contains the node at
- * nodeoffset as a subnode).
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset, *twice*.
- *
- * returns:
- *	structure block offset of the parent of the node at nodeoffset
- *		(>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_parent_offset(const void *fdt, int nodeoffset);
-
-/**
- * fdt_node_offset_by_prop_value - find nodes with a given property value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @propname: property name to check
- * @propval: property value to search for
- * @proplen: length of the value in propval
- *
- * fdt_node_offset_by_prop_value() returns the offset of the first
- * node after startoffset, which has a property named propname whose
- * value is of length proplen and has value equal to propval; or if
- * startoffset is -1, the very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- *	offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
- *					       propval, proplen);
- *	while (offset != -FDT_ERR_NOTFOUND) {
- *		// other code here
- *		offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
- *						       propval, proplen);
- *	}
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- *	structure block offset of the located node (>= 0, >startoffset),
- *		 on success
- *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- *		tree after startoffset
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
-				  const char *propname,
-				  const void *propval, int proplen);
-
-/**
- * fdt_node_offset_by_phandle - find the node with a given phandle
- * @fdt: pointer to the device tree blob
- * @phandle: phandle value
- *
- * fdt_node_offset_by_phandle() returns the offset of the node
- * which has the given phandle value.  If there is more than one node
- * in the tree with the given phandle (an invalid tree), results are
- * undefined.
- *
- * returns:
- *	structure block offset of the located node (>= 0), on success
- *	-FDT_ERR_NOTFOUND, no node with that phandle exists
- *	-FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
-
-/**
- * fdt_node_check_compatible: check a node's compatible property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of a tree node
- * @compatible: string to match against
- *
- *
- * fdt_node_check_compatible() returns 0 if the given node contains a
- * 'compatible' property with the given string as one of its elements,
- * it returns non-zero otherwise, or on error.
- *
- * returns:
- *	0, if the node has a 'compatible' property listing the given string
- *	1, if the node has a 'compatible' property, but it does not list
- *		the given string
- *	-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
- * 	-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
-			      const char *compatible);
-
-/**
- * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @compatible: 'compatible' string to match against
- *
- * fdt_node_offset_by_compatible() returns the offset of the first
- * node after startoffset, which has a 'compatible' property which
- * lists the given compatible string; or if startoffset is -1, the
- * very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- *	offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
- *	while (offset != -FDT_ERR_NOTFOUND) {
- *		// other code here
- *		offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
- *	}
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- *	structure block offset of the located node (>= 0, >startoffset),
- *		 on success
- *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- *		tree after startoffset
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
-				  const char *compatible);
-
-/**********************************************************************/
-/* Write-in-place functions                                           */
-/**********************************************************************/
-
-/**
- * fdt_setprop_inplace - change a property's value, but not its size
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to replace the property value with
- * @len: length of the property value
- *
- * fdt_setprop_inplace() replaces the value of a given property with
- * the data in val, of length len.  This function cannot change the
- * size of a property, and so will only work if len is equal to the
- * current length of the property.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, if len is not equal to the property's current length
- *	-FDT_ERR_NOTFOUND, node does not have the named property
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
-			const void *val, int len);
-
-/**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: cell (32-bit integer) value to replace the property with
- *
- * fdt_setprop_inplace_cell() replaces the value of a given property
- * with the 32-bit integer cell value in val, converting val to
- * big-endian if necessary.  This function cannot change the size of a
- * property, and so will only work if the property already exists and
- * has length 4.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, if the property's length is not equal to 4
-  *	-FDT_ERR_NOTFOUND, node does not have the named property
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
-					   const char *name, uint32_t val)
-{
-	val = cpu_to_fdt32(val);
-	return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_nop_property - replace a property with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_nop_property() will replace a given property's representation
- * in the blob with FDT_NOP tags, effectively removing it from the
- * tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the property, and will not alter or move any other part of the
- * tree.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOTFOUND, node does not have the named property
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_nop_node - replace a node (subtree) with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_nop_node() will replace a given node's representation in the
- * blob, including all its subnodes, if any, with FDT_NOP tags,
- * effectively removing it from the tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the node and its properties and subnodes, and will not alter or
- * move any other part of the tree.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Sequential write functions                                         */
-/**********************************************************************/
-
-int fdt_create(void *buf, int bufsize);
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
-int fdt_finish_reservemap(void *fdt);
-int fdt_begin_node(void *fdt, const char *name);
-int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
-{
-	val = cpu_to_fdt32(val);
-	return fdt_property(fdt, name, &val, sizeof(val));
-}
-#define fdt_property_string(fdt, name, str) \
-	fdt_property(fdt, name, str, strlen(str)+1)
-int fdt_end_node(void *fdt);
-int fdt_finish(void *fdt);
-
-/**********************************************************************/
-/* Read-write functions                                               */
-/**********************************************************************/
-
-int fdt_open_into(const void *fdt, void *buf, int bufsize);
-int fdt_pack(void *fdt);
-
-/**
- * fdt_add_mem_rsv - add one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: 64-bit values (native endian)
- *
- * Adds a reserve map entry to the given blob reserving a region at
- * address address of length size.
- *
- * This function will insert data into the reserve map and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- *		contain the new reservation entry
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
-
-/**
- * fdt_del_mem_rsv - remove a memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @n: entry to remove
- *
- * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
- * the blob.
- *
- * This function will delete data from the reservation table and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
- *		are less than n+1 reserve map entries)
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_mem_rsv(void *fdt, int n);
-
-/**
- * fdt_set_name - change the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of a node
- * @name: name to give the node
- *
- * fdt_set_name() replaces the name (including unit address, if any)
- * of the given node with the given string.  NOTE: this function can't
- * efficiently check if the new name is unique amongst the given
- * node's siblings; results are undefined if this function is invoked
- * with a name equal to one of the given node's siblings.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob
- *		to contain the new name
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_set_name(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_setprop - create or change a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to set the property value to
- * @len: length of the property value
- *
- * fdt_setprop() sets the value of the named property in the given
- * node to the given value and length, creating the property if it
- * does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- *		contain the new property value
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
-		const void *val, int len);
-
-/**
- * fdt_setprop_cell - set a property to a single cell value
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value for the property (native endian)
- *
- * fdt_setprop_cell() sets the value of the named property in the
- * given node to the given cell value (converting to big-endian if
- * necessary), or creates a new property with that value if it does
- * not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- *		contain the new property value
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
-				   uint32_t val)
-{
-	val = cpu_to_fdt32(val);
-	return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_setprop_string - set a property to a string value
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @str: string value for the property
- *
- * fdt_setprop_string() sets the value of the named property in the
- * given node to the given string value (using the length of the
- * string to determine the new length of the property), or creates a
- * new property with that value if it does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- *		contain the new property value
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-#define fdt_setprop_string(fdt, nodeoffset, name, str) \
-	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-
-/**
- * fdt_delprop - delete a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_del_property() will delete the given property.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_NOTFOUND, node does not have the named property
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_delprop(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_add_subnode_namelen - creates a new node based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_add_subnode(), but use only the first namelen
- * characters of name as the name of the new node.  This is useful for
- * creating subnodes based on a portion of a larger string, such as a
- * full path.
- */
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
-			    const char *name, int namelen);
-
-/**
- * fdt_add_subnode - creates a new node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_add_subnode() creates a new node as a subnode of the node at
- * structure block offset parentoffset, with the given name (which
- * should include the unit address, if any).
- *
- * This function will insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
-
- * returns:
- *	structure block offset of the created nodeequested subnode (>=0), on success
- *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
- *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- *	-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
- *		the given name
- *	-FDT_ERR_NOSPACE, if there is insufficient free space in the
- *		blob to contain the new node
- *	-FDT_ERR_NOSPACE
- *	-FDT_ERR_BADLAYOUT
- *      -FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_del_node - delete a node (subtree)
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_del_node() will remove the given node, including all its
- * subnodes if any, from the blob.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- *	0, on success
- *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- *	-FDT_ERR_BADLAYOUT,
- *	-FDT_ERR_BADMAGIC,
- *	-FDT_ERR_BADVERSION,
- *	-FDT_ERR_BADSTATE,
- *	-FDT_ERR_BADSTRUCTURE,
- *	-FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Debugging / informational functions                                */
-/**********************************************************************/
-
-const char *fdt_strerror(int errval);
-
-#endif /* _LIBFDT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/libfdt_internal.h linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/libfdt_internal.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/libfdt_internal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/libfdt_internal.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this library; if not, write to the Free
- *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- *     MA 02110-1301 USA
- *
- * Alternatively,
- *
- *  b) Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *     1. Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *     2. Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <fdt.h>
-
-#define FDT_ALIGN(x, a)		(((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x)		(FDT_ALIGN((x), FDT_TAGSIZE))
-
-#define FDT_CHECK_HEADER(fdt) \
-	{ \
-		int err; \
-		if ((err = fdt_check_header(fdt)) != 0) \
-			return err; \
-	}
-
-uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
-int _fdt_check_node_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
-
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
-{
-	return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
-}
-
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
-{
-	return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
-}
-
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
-{
-	const struct fdt_reserve_entry *rsv_table =
-		(const struct fdt_reserve_entry *)
-		((const char *)fdt + fdt_off_mem_rsvmap(fdt));
-
-	return rsv_table + n;
-}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
-{
-	return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
-}
-
-#define FDT_SW_MAGIC		(~FDT_MAGIC)
-
-#endif /* _LIBFDT_INTERNAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/Makefile.libfdt linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/Makefile.libfdt
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/libfdt/Makefile.libfdt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/libfdt/Makefile.libfdt	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-# Makefile.libfdt
-#
-# This is not a complete Makefile of itself.  Instead, it is designed to
-# be easily embeddable into other systems of Makefiles.
-#
-LIBFDT_INCLUDES = fdt.h libfdt.h
-LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
-LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,7 @@ ifeq ($(call cc-option-yn, -fstack-prote
 BOOTCFLAGS	+= -fno-stack-protector
 endif
 
-BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
+BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(obj)
 
 DTS_FLAGS	?= -p 1024
 
@@ -53,9 +53,14 @@ zliblinuxheader := zlib.h zconf.h zutil.
 $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \
 	$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 
-src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+libfdt       := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+libfdtheader := fdt.h libfdt.h libfdt_internal.h
+
+$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o): \
+	$(addprefix $(obj)/,$(libfdtheader))
+
 src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \
-		$(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
+		$(libfdt) libfdt-wrapper.c \
 		ns16550.c serial.c simple_alloc.c div64.S util.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 \
@@ -70,7 +75,7 @@ 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-acadia.c cuboot-amigaone.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -96,6 +101,12 @@ $(addprefix $(obj)/,$(zlibheader)): $(ob
 $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/%
 	$(call cmd,copy_zliblinuxheader)
 
+quiet_cmd_copy_libfdt = COPY    $@
+      cmd_copy_libfdt = cp $< $@
+
+$(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
+	$(call cmd,copy_libfdt)
+
 $(obj)/empty.c:
 	@touch $@
 
@@ -103,6 +114,7 @@ $(obj)/zImage.lds $(obj)/zImage.coff.lds
 	@cp $< $@
 
 clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
+		$(libfdt) $(libfdtheader) \
 		empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
 
 quiet_cmd_bootcc = BOOTCC  $@
@@ -114,6 +126,8 @@ quiet_cmd_bootas = BOOTAS  $@
 quiet_cmd_bootar = BOOTAR  $@
       cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
 
+$(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE
+	$(call if_changed_dep,bootcc)
 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
 	$(Q)mkdir -p $(dir $@)
 	$(call if_changed_dep,bootcc)
@@ -124,7 +138,7 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-
 $(obj)/wrapper.a: $(obj-wlib) FORCE
 	$(call if_changed,bootar)
 
-hostprogs-y	:= addnote addRamDisk hack-coff mktree dtc
+hostprogs-y	:= addnote addRamDisk hack-coff mktree
 
 targets		+= $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
 extra-y		:= $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
@@ -133,47 +147,10 @@ extra-y		:= $(obj)/wrapper.a $(obj-plat)
 dtstree		:= $(srctree)/$(src)/dts
 
 wrapper		:=$(srctree)/$(src)/wrapper
-wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
+wrapperbits	:= $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
 			$(wrapper) FORCE
 
 #############
-# Bits for building dtc
-# DTC_GENPARSER      := 1    # Uncomment to rebuild flex/bison output
-
-dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o srcpos.o checks.o
-dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
-dtc-objs := $(addprefix dtc-src/, $(dtc-objs))
-
-# prerequisites on generated files needs to be explicit
-$(obj)/dtc-src/dtc-parser.tab.o: $(obj)/dtc-src/dtc-parser.tab.c $(obj)/dtc-src/dtc-parser.tab.h
-$(obj)/dtc-src/dtc-lexer.lex.o:  $(obj)/dtc-src/dtc-lexer.lex.c $(obj)/dtc-src/dtc-parser.tab.h
-
-HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
-
-targets += dtc-src/dtc-parser.tab.c
-targets += dtc-src/dtc-lexer.lex.c
-
-clean-files += dtc-src/dtc-parser.tab.h
-
-ifdef DTC_GENPARSER
-BISON = bison
-FLEX = flex
-
-quiet_cmd_bison = BISON   $@
-      cmd_bison = $(BISON) -o$@ -d $<; cp $@ $@_shipped
-quiet_cmd_flex = FLEX    $@
-      cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped
-
-$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
-	$(call if_changed,bison)
-
-$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
-
-$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
-	$(call if_changed,flex)
-endif
-
-#############
 # Bits for building various flavours of zImage
 
 ifneq ($(CROSS32_COMPILE),)
@@ -235,7 +212,9 @@ image-$(CONFIG_PPC_ADDER875)		+= cuImage
 					   dtbImage.adder875-redboot
 
 # Board ports in arch/powerpc/platform/52xx/Kconfig
-image-$(CONFIG_PPC_LITE5200)		+= cuImage.lite5200 cuImage.lite5200b
+image-$(CONFIG_PPC_LITE5200)		+= cuImage.lite5200 lite5200.dtb
+image-$(CONFIG_PPC_LITE5200)		+= cuImage.lite5200b lite5200b.dtb
+image-$(CONFIG_PPC_MEDIA5200)		+= cuImage.media5200 media5200.dtb
 
 # Board ports in arch/powerpc/platform/82xx/Kconfig
 image-$(CONFIG_MPC8272_ADS)		+= cuImage.mpc8272ads
@@ -274,6 +253,9 @@ image-$(CONFIG_STORCENTER)		+= cuImage.s
 image-$(CONFIG_MPC7448HPC2)		+= cuImage.mpc7448hpc2
 image-$(CONFIG_PPC_C2K)			+= cuImage.c2k
 
+# Board port in arch/powerpc/platform/amigaone/Kconfig
+image-$(CONFIG_AMIGAONE)		+= cuImage.amigaone
+
 # For 32-bit powermacs, build the COFF and miboot images
 # as well as the ELF images.
 ifeq ($(CONFIG_PPC32),y)
@@ -342,8 +324,10 @@ $(obj)/treeImage.%: vmlinux $(obj)/%.dtb
 	$(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb)
 
 # Rule to build device tree blobs
-$(obj)/%.dtb: $(dtstree)/%.dts $(obj)/dtc
-	$(obj)/dtc -O dtb -o $(obj)/$*.dtb -b 0 $(DTS_FLAGS) $(dtstree)/$*.dts
+DTC = $(objtree)/scripts/dtc/dtc
+
+$(obj)/%.dtb: $(dtstree)/%.dts
+	$(DTC) -O dtb -o $(obj)/$*.dtb -b 0 $(DTS_FLAGS) $(dtstree)/$*.dts
 
 # If there isn't a platform selected then just strip the vmlinux.
 ifeq (,$(image-y))
@@ -362,7 +346,7 @@ install: $(CONFIGURE) $(addprefix $(obj)
 clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \
 	zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \
 	zImage.iseries zImage.miboot zImage.pmac zImage.pseries \
-	otheros.bld *.dtb
+	simpleImage.* otheros.bld *.dtb
 
 # clean up files cached by wrapper
 clean-kernel := vmlinux.strip vmlinux.bin
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/mktree.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/mktree.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/mktree.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/mktree.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
 {
 	int	in_fd, out_fd;
 	int	nblks, i;
-	uint	cksum, *cp;
+	unsigned int	cksum, *cp;
 	struct	stat	st;
 	boot_block_t	bt;
 
@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
 
 	cksum = 0;
 	cp = (void *)&bt;
-	for (i=0; i<sizeof(bt)/sizeof(uint); i++)
+	for (i = 0; i < sizeof(bt) / sizeof(unsigned int); i++)
 		cksum += *cp++;
 
 	/* Assume zImage is an ELF file, and skip the 64K header.
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
 		exit(4);
 	}
 
-	if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
+	if ((*(unsigned int *)tmpbuf) != htonl(0x7f454c46)) {
 		fprintf(stderr, "%s is not an ELF image\n", argv[1]);
 		exit(4);
 	}
@@ -125,8 +125,8 @@ int main(int argc, char *argv[])
 			perror("zImage read");
 			exit(5);
 		}
-		cp = (uint *)tmpbuf;
-		for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
+		cp = (unsigned int *)tmpbuf;
+		for (i = 0; i < sizeof(tmpbuf) / sizeof(unsigned int); i++)
 			cksum += *cp++;
 		if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
 			perror("boot-image write");
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/serial.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/serial.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,8 @@ int serial_console_init(void)
 	if (devp == NULL)
 		goto err_out;
 
-	if (dt_is_compatible(devp, "ns16550"))
+	if (dt_is_compatible(devp, "ns16550") ||
+	    dt_is_compatible(devp, "pnpPNP,501"))
 		rc = ns16550_console_init(devp, &serial_cd);
 	else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
 		rc = mpsc_console_init(devp, &serial_cd);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/simpleboot.c linux-libre-2.6.30-gnu1/arch/powerpc/boot/simpleboot.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/simpleboot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/simpleboot.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@
 #include "types.h"
 #include "io.h"
 #include "stdio.h"
-#include "libfdt/libfdt.h"
+#include <libfdt.h>
 
 BSS_STACK(4*1024);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/boot/wrapper linux-libre-2.6.30-gnu1/arch/powerpc/boot/wrapper
--- linux-libre-2.6.29-gnu1/arch/powerpc/boot/wrapper	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/boot/wrapper	2009-06-09 23:05:27.000000000 -0400
@@ -186,6 +186,9 @@ cuboot*)
     *-mpc85*|*-tqm85*|*-sbc85*)
         platformo=$object/cuboot-85xx.o
         ;;
+    *-amigaone)
+        link_address='0x800000'
+        ;;
     esac
     ;;
 ps3)
@@ -211,11 +214,11 @@ simpleboot-virtex405-*)
     binary=y
     ;;
 simpleboot-virtex440-*)
-    platformo="$object/simpleboot.o $object/virtex.o"
+    platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o"
     binary=y
     ;;
 simpleboot-*)
-    platformo="$object/simpleboot.o"
+    platformo="$object/fixed-head.o $object/simpleboot.o"
     binary=y
     ;;
 asp834x-redboot)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/44x/canyonlands_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:35 2009
+# Linux kernel version: 2.6.29-rc3
+# Mon Feb  2 13:13:04 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -74,6 +74,15 @@ CONFIG_POSIX_MQUEUE=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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -147,11 +156,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -373,6 +377,7 @@ CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
 # CONFIG_MTD is not set
 CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -384,6 +389,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_LOOP 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=35000
@@ -466,6 +472,15 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # 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
@@ -533,13 +548,136 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=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_IBM_IIC=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
+# 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_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
 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_HWMON=y
+# CONFIG_HWMON_VID is not set
+CONFIG_SENSORS_AD7414=y
+# 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_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_I5K_AMB 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_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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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 is not set
@@ -556,7 +694,12 @@ CONFIG_SSB_POSSIBLE=y
 # 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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -574,6 +717,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multimedia drivers
 #
 CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -590,7 +734,109 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 #
 # CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
-# CONFIG_USB_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=y
+
+#
+# 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=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=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED 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_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_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+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 information
+#
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 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_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_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/44x/redwood_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/44x/redwood_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/44x/redwood_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/44x/redwood_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1176 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Wed Feb  4 14:31:09 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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
+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=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# 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_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=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_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=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_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_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=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_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE 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=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
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+CONFIG_REDWOOD=y
+# CONFIG_YOSEMITE is not set
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+CONFIG_PPC44x_SIMPLE=y
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_460SX=y
+# 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_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+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_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+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_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER 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_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=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+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
+# 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=y
+# 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 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=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_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_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_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
+# 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=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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
+# 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 is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# 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 is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE 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=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=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
+# 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=y
+# 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_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 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_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# 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
+# 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
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_FUSION=y
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LOGGING is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+CONFIG_I2O=y
+CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
+CONFIG_I2O_EXT_ADAPTEC=y
+# CONFIG_I2O_CONFIG is not set
+# CONFIG_I2O_BUS is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC 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_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII 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_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=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_NET_PCI is not set
+# CONFIG_B44 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=y
+# CONFIG_IP1000 is not set
+# CONFIG_IGB 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_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E 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
+
+#
+# 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_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=y
+# 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=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+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_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC 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_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_IBM_IIC=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
+
+#
+# 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_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
+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
+
+#
+# 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_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_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=y
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# 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
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT 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_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# 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 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_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_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
+
+#
+# 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 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 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_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
+# 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
+
+#
+# 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# 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_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=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_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 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=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+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
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_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_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=y
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C 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=y
+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 is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE 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_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/cm5200_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:41:58 2009
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 00:47:44 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -94,19 +96,22 @@ 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 is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -115,10 +120,12 @@ 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -126,6 +133,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -133,7 +141,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -154,8 +161,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -163,6 +168,7 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
 # CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
 # CONFIG_PPC_PMAC is not set
@@ -173,6 +179,8 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -232,9 +240,12 @@ 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_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
@@ -275,7 +286,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -331,6 +341,7 @@ 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
 
@@ -343,7 +354,6 @@ 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
@@ -440,7 +450,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
@@ -505,10 +514,12 @@ CONFIG_CHR_DEV_SG=y
 # 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_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
@@ -537,6 +548,8 @@ CONFIG_LXT_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -555,7 +568,6 @@ CONFIG_FEC_MPC52xx_MDIO=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
@@ -657,7 +669,6 @@ CONFIG_I2C_MPC=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
@@ -786,11 +797,11 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=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
@@ -831,7 +842,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
@@ -846,6 +856,7 @@ CONFIG_USB_STORAGE=y
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -853,6 +864,7 @@ CONFIG_USB_STORAGE=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
 # CONFIG_STAGING is not set
 
@@ -863,6 +875,7 @@ 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
@@ -885,6 +898,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
@@ -941,6 +959,7 @@ 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
@@ -953,7 +972,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1024,6 +1042,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
@@ -1039,11 +1058,12 @@ 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
 
 #
 # Kernel hacking
@@ -1061,6 +1081,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
@@ -1089,9 +1112,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1099,17 +1125,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1140,10 +1168,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
 
@@ -1211,6 +1241,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.29-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/lite5200b_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:41:14 2009
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 00:48:04 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -55,6 +56,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -95,19 +97,22 @@ 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 is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -117,10 +122,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -128,6 +135,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -140,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -161,8 +168,6 @@ CONFIG_FREEZER=y
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -170,6 +175,7 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
 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_PMAC is not set
@@ -180,6 +186,8 @@ CONFIG_PPC_LITE5200=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -241,9 +249,12 @@ 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_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
@@ -272,6 +283,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 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
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -294,7 +306,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +361,7 @@ 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
 
@@ -362,7 +374,6 @@ 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
@@ -412,6 +423,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -477,9 +489,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -502,6 +516,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -578,6 +593,7 @@ CONFIG_PATA_MPC52xx=y
 # 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
@@ -611,6 +627,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_ZMII is not set
@@ -632,6 +650,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
@@ -642,10 +661,10 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-# CONFIG_MV643XX_ETH 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
@@ -655,6 +674,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
@@ -664,6 +684,7 @@ 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
 
 #
@@ -671,7 +692,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -795,7 +815,6 @@ CONFIG_I2C_MPC=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
@@ -876,7 +895,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
 
@@ -892,6 +911,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -902,6 +922,7 @@ 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
@@ -924,6 +945,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
@@ -966,6 +992,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -978,7 +1005,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -994,6 +1020,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1007,11 +1034,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1029,6 +1058,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
@@ -1057,9 +1089,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1067,17 +1102,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1108,10 +1145,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
@@ -1180,6 +1219,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.29-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/motionpro_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:42:29 2009
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 00:48:22 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -94,19 +96,22 @@ 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 is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -115,10 +120,12 @@ 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -126,6 +133,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -133,7 +141,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -154,8 +161,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -163,6 +168,7 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
 # CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
 # CONFIG_PPC_PMAC is not set
@@ -173,6 +179,8 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -233,9 +241,12 @@ 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_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,7 +287,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -332,6 +342,7 @@ 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
 
@@ -344,7 +355,6 @@ 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
@@ -441,7 +451,6 @@ CONFIG_MTD_ROM=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -466,6 +475,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 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
 
 #
@@ -516,8 +526,10 @@ CONFIG_CHR_DEV_SG=y
 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=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -528,6 +540,7 @@ CONFIG_PATA_MPC52xx=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
@@ -556,6 +569,8 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_MDIO_BITBANG=y
 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
@@ -574,7 +589,6 @@ CONFIG_FEC_MPC52xx_MDIO=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
@@ -665,7 +679,6 @@ CONFIG_I2C_MPC=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
@@ -696,6 +709,7 @@ CONFIG_HWMON=y
 # 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
@@ -710,11 +724,14 @@ 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_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_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -800,7 +817,9 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_LP5521 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -810,6 +829,10 @@ CONFIG_LEDS_TRIGGER_TIMER=y
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT 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_EDAC is not set
 CONFIG_RTC_LIB=y
@@ -866,8 +889,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -878,6 +902,7 @@ 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
@@ -900,6 +925,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
@@ -956,6 +986,7 @@ 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
@@ -968,7 +999,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1039,6 +1069,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
@@ -1054,11 +1085,12 @@ 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
 
 #
 # Kernel hacking
@@ -1076,6 +1108,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
@@ -1104,9 +1139,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1114,17 +1152,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1155,10 +1195,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
 
@@ -1226,6 +1268,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.29-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/pcm030_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:41:33 2009
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 00:48:42 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -69,6 +71,7 @@ CONFIG_LOCALVERSION="trunk"
 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
@@ -97,18 +100,18 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 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=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
@@ -117,10 +120,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -129,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -141,7 +147,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -162,8 +167,6 @@ CONFIG_DEFAULT_IOSCHED="noop"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -171,6 +174,7 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
 # CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_MEDIA5200 is not set
 # CONFIG_PPC_MPC5200_BUGFIX is not set
 # CONFIG_PPC_MPC5200_GPIO is not set
 # CONFIG_PPC_PMAC is not set
@@ -181,6 +185,8 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -242,9 +248,12 @@ 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_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
@@ -268,6 +277,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY=y
 # 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
@@ -290,7 +300,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -340,6 +349,7 @@ 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
 
@@ -352,7 +362,6 @@ 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
@@ -451,7 +460,6 @@ CONFIG_MTD_PHYSMAP=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -504,6 +512,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=m
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -580,6 +589,7 @@ CONFIG_PATA_MPC52xx=m
 # 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
@@ -613,6 +623,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_ZMII is not set
@@ -636,7 +648,6 @@ CONFIG_FEC_MPC52xx_MDIO=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
@@ -702,6 +713,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -767,7 +779,6 @@ CONFIG_I2C_MPC=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
@@ -889,11 +900,11 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=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
@@ -934,7 +945,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
@@ -949,6 +959,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
@@ -1007,8 +1018,9 @@ CONFIG_RTC_DRV_PCF8563=m
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1019,6 +1031,7 @@ CONFIG_EXT2_FS=m
 # 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
@@ -1040,6 +1053,11 @@ CONFIG_FILE_LOCKING=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1096,6 +1114,7 @@ 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
@@ -1107,7 +1126,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
@@ -1162,6 +1180,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
@@ -1177,11 +1196,11 @@ 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
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1200,13 +1219,25 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_FUNCTION_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/52xx/tqm5200_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:42:58 2009
+# Linux kernel version: 2.6.30-rc2
+# Sat Apr 18 00:48:57 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -94,19 +96,22 @@ 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 is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -115,10 +120,12 @@ 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -126,6 +133,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -138,7 +146,6 @@ CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -159,8 +166,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -168,6 +173,7 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
 # CONFIG_PPC_LITE5200 is not set
+# CONFIG_PPC_MEDIA5200 is not set
 CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_MPC5200_GPIO is not set
 # CONFIG_PPC_PMAC is not set
@@ -178,6 +184,8 @@ CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -238,9 +246,12 @@ 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_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
@@ -281,7 +292,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -337,6 +347,7 @@ 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
 
@@ -349,7 +360,6 @@ 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
@@ -447,7 +457,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
@@ -514,8 +523,10 @@ 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=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -527,6 +538,7 @@ CONFIG_PATA_PLATFORM=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
@@ -555,6 +567,8 @@ CONFIG_LXT_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -573,7 +587,6 @@ CONFIG_FEC_MPC52xx_MDIO=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
@@ -675,7 +688,6 @@ CONFIG_I2C_MPC=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
@@ -706,6 +718,7 @@ CONFIG_HWMON=y
 # 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
@@ -720,11 +733,14 @@ 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_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_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -857,11 +873,11 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=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
@@ -902,7 +918,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
@@ -917,6 +932,7 @@ CONFIG_USB_STORAGE=y
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -976,8 +992,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -988,6 +1005,7 @@ 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
@@ -1010,6 +1028,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
@@ -1066,6 +1089,7 @@ 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
@@ -1078,7 +1102,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1149,6 +1172,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
@@ -1164,11 +1188,12 @@ 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
 
 #
 # Kernel hacking
@@ -1186,6 +1211,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
@@ -1214,9 +1242,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1224,17 +1255,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1265,10 +1298,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
@@ -1337,6 +1372,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.29-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/asp8347_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:47 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:05 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_ALTIVEC is not set
@@ -57,6 +58,7 @@ CONFIG_REDBOOT=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -74,6 +76,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -88,19 +99,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -110,16 +124,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +149,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,18 +164,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -184,6 +193,8 @@ CONFIG_ASP834x=y
 CONFIG_PPC_MPC834x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -245,9 +256,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -469,7 +483,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
@@ -499,13 +512,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -532,6 +552,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -565,6 +586,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_ZMII is not set
@@ -584,6 +607,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,11 +618,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -608,7 +633,6 @@ CONFIG_GIANFAR=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
@@ -759,12 +783,9 @@ CONFIG_I2C_MPC=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
@@ -796,6 +817,7 @@ CONFIG_HWMON=y
 # 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
@@ -810,11 +832,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -959,11 +984,11 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 
@@ -991,7 +1016,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1006,6 +1030,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1067,8 +1092,9 @@ CONFIG_RTC_DRV_DS1374=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1079,6 +1105,7 @@ 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
@@ -1101,6 +1128,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
@@ -1154,6 +1186,7 @@ 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
@@ -1166,7 +1199,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1233,6 +1265,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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
@@ -1248,11 +1281,12 @@ 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
 
 #
 # Kernel hacking
@@ -1274,13 +1308,24 @@ CONFIG_FRAME_WARN=1024
 # 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
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1309,10 +1354,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
@@ -1381,6 +1428,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.29-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:48 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:06 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC831x_RDB=y
 CONFIG_PPC_MPC831x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -481,7 +495,6 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -512,13 +525,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -576,9 +597,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -600,6 +623,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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=y
@@ -626,6 +650,7 @@ CONFIG_MD_RAID1=y
 # 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
@@ -660,6 +685,8 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_ENC28J60 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
@@ -697,6 +724,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
@@ -707,11 +735,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -721,6 +750,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
@@ -730,6 +760,7 @@ 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
 
 #
@@ -737,7 +768,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -815,6 +845,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -827,6 +858,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -889,12 +921,9 @@ CONFIG_I2C_MPC=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
@@ -914,7 +943,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # 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
@@ -942,6 +970,7 @@ CONFIG_HWMON=y
 # 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
@@ -957,12 +986,15 @@ 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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -981,6 +1013,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_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -1077,7 +1110,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1135,11 +1167,11 @@ CONFIG_USB_UHCI_HCD=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
@@ -1181,7 +1213,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
@@ -1228,6 +1259,7 @@ CONFIG_USB_ETH_RNDIS=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
@@ -1296,8 +1328,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1308,6 +1341,7 @@ 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
@@ -1330,6 +1364,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
@@ -1383,6 +1422,7 @@ 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
@@ -1395,7 +1435,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1427,6 +1466,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1442,11 +1482,12 @@ 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
 
 #
 # Kernel hacking
@@ -1464,6 +1505,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
@@ -1493,9 +1537,12 @@ CONFIG_SCHED_DEBUG=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1503,17 +1550,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1544,10 +1593,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
@@ -1616,6 +1667,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.29-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:49 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:06 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC831x_RDB=y
 CONFIG_PPC_MPC831x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -481,7 +495,6 @@ CONFIG_MTD_NAND_IDS=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -512,13 +525,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -576,9 +597,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -601,6 +624,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -687,6 +711,7 @@ CONFIG_MD_RAID1=y
 # 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
@@ -721,6 +746,8 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_ENC28J60 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
@@ -758,6 +785,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
@@ -768,11 +796,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -782,6 +811,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
@@ -791,6 +821,7 @@ 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
 
 #
@@ -798,7 +829,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -876,6 +906,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -888,6 +919,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -950,12 +982,9 @@ CONFIG_I2C_MPC=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
@@ -975,7 +1004,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # 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
@@ -1003,6 +1031,7 @@ CONFIG_HWMON=y
 # 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
@@ -1018,12 +1047,15 @@ 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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1042,6 +1074,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_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -1138,7 +1171,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1196,11 +1228,11 @@ CONFIG_USB_UHCI_HCD=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
@@ -1242,7 +1274,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
@@ -1289,6 +1320,7 @@ CONFIG_USB_ETH_RNDIS=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
@@ -1357,8 +1389,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1369,6 +1402,7 @@ 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
@@ -1391,6 +1425,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
@@ -1444,6 +1483,7 @@ 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
@@ -1456,7 +1496,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1488,6 +1527,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1503,11 +1543,12 @@ 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
 
 #
 # Kernel hacking
@@ -1525,6 +1566,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
@@ -1554,9 +1598,12 @@ CONFIG_SCHED_DEBUG=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1564,17 +1611,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1605,10 +1654,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
@@ -1677,6 +1728,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.29-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc832x_mds_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:50 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:07 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC832x_MDS=y
 CONFIG_PPC_MPC832x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -245,9 +256,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -411,13 +425,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -475,9 +496,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -499,6 +522,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -515,6 +539,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -548,6 +573,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_ZMII is not set
@@ -567,6 +594,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
@@ -577,14 +605,15 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 # CONFIG_GIANFAR is not set
 CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
-# CONFIG_MV643XX_ETH 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
@@ -594,6 +623,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
@@ -603,6 +633,7 @@ 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
 
 #
@@ -610,7 +641,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -692,6 +722,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -753,12 +784,9 @@ CONFIG_I2C_MPC=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
@@ -790,6 +818,7 @@ CONFIG_HWMON=y
 # 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
@@ -804,11 +833,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -906,7 +938,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -920,7 +951,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
 
@@ -988,8 +1019,9 @@ CONFIG_RTC_DRV_DS1374=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1000,6 +1032,7 @@ 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
@@ -1022,6 +1055,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
@@ -1064,6 +1102,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1076,7 +1115,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1106,6 +1144,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_DLM is not set
 CONFIG_UCC_FAST=y
 CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1119,11 +1158,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1145,13 +1186,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1180,10 +1232,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
@@ -1252,6 +1306,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.29-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:52 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:08 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC832x_RDB=y
 CONFIG_PPC_MPC832x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -245,9 +256,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -413,13 +427,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -477,9 +499,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -501,6 +525,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -517,6 +542,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -551,6 +577,8 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_ENC28J60 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
@@ -570,6 +598,7 @@ CONFIG_E1000=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
@@ -580,14 +609,15 @@ CONFIG_E1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 # CONFIG_GIANFAR is not set
 CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
-# CONFIG_MV643XX_ETH 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
@@ -597,6 +627,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
@@ -606,6 +637,7 @@ 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
 
 #
@@ -613,7 +645,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -691,6 +722,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -704,6 +736,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -768,12 +801,9 @@ CONFIG_I2C_MPC=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
@@ -792,7 +822,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # 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
@@ -820,6 +849,7 @@ CONFIG_HWMON=y
 # 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
@@ -835,12 +865,15 @@ 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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -859,6 +892,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_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -955,7 +989,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1012,11 +1045,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1058,7 +1091,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
@@ -1074,6 +1106,7 @@ CONFIG_USB_STORAGE=y
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
@@ -1101,6 +1134,7 @@ CONFIG_MMC_SPI=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
 # CONFIG_STAGING is not set
 
@@ -1111,6 +1145,7 @@ 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
@@ -1133,6 +1168,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
@@ -1178,6 +1218,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1190,7 +1231,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1264,6 +1304,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_DLM is not set
 CONFIG_UCC_FAST=y
 CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1277,11 +1318,13 @@ CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
 CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1303,13 +1346,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1338,10 +1392,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
@@ -1410,6 +1466,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.29-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_itx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:53 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:09 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC834x_ITX=y
 CONFIG_PPC_MPC834x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -272,6 +286,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
@@ -294,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +364,7 @@ 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
 
@@ -362,7 +377,6 @@ 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
@@ -465,7 +479,6 @@ CONFIG_MTD_PHYSMAP=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -496,13 +509,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -608,9 +629,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -633,6 +656,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -720,6 +744,7 @@ CONFIG_MD_RAID1=y
 # 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
@@ -755,6 +780,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
@@ -765,11 +791,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -779,6 +806,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
@@ -788,6 +816,7 @@ 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
 
 #
@@ -795,7 +824,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -853,6 +881,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -865,6 +894,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -927,12 +957,9 @@ CONFIG_I2C_MPC=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=y
 # 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
@@ -951,7 +978,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # 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
@@ -1083,11 +1109,11 @@ CONFIG_USB_UHCI_HCD=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
@@ -1128,7 +1154,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
@@ -1144,6 +1169,7 @@ CONFIG_USB_STORAGE=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
@@ -1212,8 +1238,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1224,6 +1251,7 @@ 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
@@ -1246,6 +1274,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
@@ -1292,6 +1325,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1304,7 +1338,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1375,6 +1408,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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
@@ -1388,11 +1422,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1414,13 +1450,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1449,10 +1496,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
@@ -1521,6 +1570,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.29-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:55 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:10 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC834x_ITX=y
 CONFIG_PPC_MPC834x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -272,6 +286,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
@@ -294,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +364,7 @@ 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
 
@@ -362,7 +377,6 @@ 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
@@ -465,7 +479,6 @@ CONFIG_MTD_PHYSMAP=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -496,13 +509,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -560,9 +581,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -584,6 +607,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -600,6 +624,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -635,6 +660,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
@@ -645,11 +671,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -659,6 +686,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
@@ -668,6 +696,7 @@ 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
 
 #
@@ -675,7 +704,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -733,6 +761,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -745,6 +774,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -807,12 +837,9 @@ CONFIG_I2C_MPC=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=y
 # 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
@@ -831,7 +858,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # 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
@@ -963,11 +989,11 @@ CONFIG_USB_UHCI_HCD=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
@@ -1008,7 +1034,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
@@ -1023,6 +1048,7 @@ CONFIG_USB_STORAGE=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
@@ -1091,8 +1117,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1103,6 +1130,7 @@ 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
@@ -1125,6 +1153,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
@@ -1171,6 +1204,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1183,7 +1217,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1254,6 +1287,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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
@@ -1267,11 +1301,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1293,13 +1329,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1328,10 +1375,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
@@ -1400,6 +1449,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.29-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc834x_mds_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:56 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:11 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC834x_MDS=y
 CONFIG_PPC_MPC834x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -272,6 +286,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
@@ -294,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +364,7 @@ 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
 
@@ -362,7 +377,6 @@ 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
@@ -410,13 +424,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -443,6 +464,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -476,6 +498,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_ZMII is not set
@@ -513,6 +537,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
@@ -523,11 +548,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -537,6 +563,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
@@ -546,6 +573,7 @@ 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
 
 #
@@ -553,7 +581,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -694,12 +721,9 @@ CONFIG_I2C_MPC=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
@@ -731,6 +755,7 @@ CONFIG_HWMON=y
 # 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
@@ -745,11 +770,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -847,7 +875,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -861,7 +888,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
 
@@ -929,8 +956,9 @@ CONFIG_RTC_DRV_DS1374=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -941,6 +969,7 @@ 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
@@ -963,6 +992,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
@@ -1005,6 +1039,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1017,7 +1052,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1045,6 +1079,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1058,11 +1093,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1084,13 +1121,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1119,10 +1167,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
@@ -1191,6 +1241,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.29-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc836x_mds_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:58 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:12 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,16 +123,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +163,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -182,6 +191,8 @@ CONFIG_MPC836x_MDS=y
 # CONFIG_ASP834x is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -243,9 +254,12 @@ 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_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
@@ -271,6 +285,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
@@ -293,7 +308,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -349,6 +363,7 @@ 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
 
@@ -361,7 +376,6 @@ 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
@@ -464,7 +478,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
@@ -493,13 +506,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -557,9 +577,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -581,6 +603,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -597,6 +620,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -630,6 +654,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_ZMII is not set
@@ -649,6 +675,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
@@ -659,14 +686,15 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 # CONFIG_GIANFAR is not set
 CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
-# CONFIG_MV643XX_ETH 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
@@ -676,6 +704,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
@@ -685,6 +714,7 @@ 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
 
 #
@@ -692,7 +722,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -774,6 +803,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -835,12 +865,9 @@ CONFIG_I2C_MPC=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
@@ -872,6 +899,7 @@ CONFIG_HWMON=y
 # 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
@@ -886,11 +914,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -988,7 +1019,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1002,7 +1032,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
 
@@ -1070,8 +1100,9 @@ CONFIG_RTC_DRV_DS1374=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1082,6 +1113,7 @@ 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
@@ -1104,6 +1136,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
@@ -1147,6 +1184,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1159,7 +1197,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1189,6 +1226,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_DLM is not set
 CONFIG_UCC_FAST=y
 CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1202,11 +1240,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1228,13 +1268,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1263,10 +1314,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
@@ -1335,6 +1388,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.29-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:01 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:13 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -57,6 +58,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -74,6 +76,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -88,19 +99,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -110,16 +124,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +149,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,18 +164,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,6 +192,8 @@ CONFIG_MPC836x_RDK=y
 # CONFIG_ASP834x is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -243,9 +254,12 @@ 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_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
@@ -273,6 +287,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
@@ -295,7 +310,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +365,7 @@ 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
 
@@ -363,7 +378,6 @@ 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
@@ -475,7 +489,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
@@ -506,13 +519,21 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +560,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -574,6 +596,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
@@ -584,14 +607,15 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 # CONFIG_GIANFAR is not set
 CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
-# CONFIG_MV643XX_ETH 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
@@ -601,7 +625,6 @@ CONFIG_UCC_GETH=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
@@ -673,6 +696,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -686,6 +710,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -749,12 +774,9 @@ CONFIG_I2C_MPC=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
@@ -774,7 +796,6 @@ CONFIG_SPI_MPC83xx=y
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 CONFIG_SPI_SPIDEV=y
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
@@ -924,6 +945,7 @@ CONFIG_FB_OF=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
 
 #
@@ -956,7 +978,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
@@ -967,6 +988,7 @@ CONFIG_HID_COMPAT=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
 # CONFIG_STAGING is not set
 
@@ -977,6 +999,7 @@ 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
@@ -999,6 +1022,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
@@ -1052,6 +1080,7 @@ 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
@@ -1064,7 +1093,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1095,6 +1123,7 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_UCC_SLOW=y
 CONFIG_UCC_FAST=y
 CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1110,11 +1139,12 @@ 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
 
 #
 # Kernel hacking
@@ -1136,13 +1166,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1182,10 +1223,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
@@ -1254,6 +1297,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.29-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc837x_mds_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:59 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:12 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,20 +98,23 @@ 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_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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +123,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +136,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +149,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,18 +164,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -184,6 +193,8 @@ CONFIG_MPC837x_MDS=y
 CONFIG_PPC_MPC837x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -272,6 +286,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
@@ -294,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +364,7 @@ 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
 
@@ -362,7 +377,6 @@ 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
@@ -410,13 +424,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -474,9 +495,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -499,6 +522,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -575,6 +599,7 @@ CONFIG_ATA_SFF=y
 # 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
@@ -608,6 +633,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_ZMII is not set
@@ -627,6 +654,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
@@ -637,11 +665,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -651,6 +680,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
@@ -660,6 +690,7 @@ 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
 
 #
@@ -667,7 +698,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -811,12 +841,9 @@ CONFIG_I2C_MPC=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
@@ -848,6 +875,7 @@ CONFIG_HWMON=y
 # 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
@@ -862,11 +890,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -964,7 +995,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -978,7 +1008,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
 
@@ -994,6 +1024,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1004,6 +1035,7 @@ 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
@@ -1026,6 +1058,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
@@ -1068,6 +1105,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1080,7 +1118,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1112,6 +1149,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1125,11 +1163,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1149,13 +1189,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1184,10 +1235,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
@@ -1256,6 +1309,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.29-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:01 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:14 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,20 +98,23 @@ 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_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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +123,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +136,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +149,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,18 +164,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -184,6 +193,8 @@ CONFIG_MPC837x_RDB=y
 CONFIG_PPC_MPC837x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +255,12 @@ 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_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
@@ -272,6 +286,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
@@ -294,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -345,6 +359,7 @@ 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
 
@@ -357,7 +372,6 @@ 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
@@ -406,13 +420,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -469,9 +490,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -494,6 +517,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -563,7 +587,7 @@ CONFIG_MD_AUTODETECT=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=y
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -581,6 +605,7 @@ CONFIG_MD_RAID5_RESHAPE=y
 # 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
@@ -614,6 +639,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_ZMII is not set
@@ -633,6 +660,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
@@ -643,11 +671,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -657,7 +686,6 @@ CONFIG_GIANFAR=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
@@ -811,12 +839,9 @@ CONFIG_I2C_MPC=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
@@ -848,6 +873,7 @@ CONFIG_HWMON=y
 # 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
@@ -862,11 +888,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -976,15 +1005,17 @@ 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_DRAGONRISE_FF 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
@@ -1050,11 +1081,11 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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 is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -1084,7 +1115,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1099,6 +1129,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1108,6 +1139,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 # CONFIG_STAGING is not set
 
@@ -1118,6 +1150,7 @@ 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
@@ -1140,6 +1173,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
@@ -1182,6 +1220,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1194,7 +1233,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1226,6 +1264,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1239,11 +1278,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1263,13 +1304,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1302,10 +1354,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
@@ -1374,6 +1428,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.29-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/83xx/sbc834x_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:02 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:15 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -56,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -87,19 +98,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -108,16 +122,19 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,7 +147,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -146,18 +162,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -182,6 +191,8 @@ CONFIG_SBC834x=y
 CONFIG_PPC_MPC834x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -242,9 +253,12 @@ 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_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
@@ -270,6 +284,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
@@ -292,7 +307,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -348,6 +362,7 @@ 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
 
@@ -360,7 +375,6 @@ 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
@@ -408,13 +422,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -441,6 +462,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -474,6 +496,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_ZMII is not set
@@ -493,6 +517,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
@@ -503,11 +528,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -517,7 +543,6 @@ CONFIG_GIANFAR=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
@@ -660,12 +685,9 @@ CONFIG_I2C_MPC=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
@@ -697,6 +719,7 @@ CONFIG_HWMON=y
 # 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
@@ -711,11 +734,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -813,7 +839,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
@@ -824,6 +849,7 @@ CONFIG_HID_COMPAT=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
 # CONFIG_STAGING is not set
 
@@ -849,6 +875,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
@@ -891,6 +922,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -903,7 +935,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -919,6 +950,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -932,11 +964,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -956,13 +990,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -991,10 +1036,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
@@ -1063,6 +1110,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.29-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/ksi8560_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:03 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:16 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
@@ -86,21 +97,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +123,12 @@ 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -120,6 +136,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -127,7 +144,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,11 +159,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -163,6 +174,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 CONFIG_KSI8560=y
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -231,9 +243,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -264,17 +279,17 @@ CONFIG_PPC_PCI_CHOICE=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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -330,6 +345,7 @@ 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
 
@@ -342,7 +358,6 @@ 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
@@ -444,7 +459,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
@@ -467,9 +481,13 @@ 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_EEPROM_93CX6 is not set
 # 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=y
 
@@ -502,6 +520,7 @@ CONFIG_IDE_PROC_FS=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
@@ -531,6 +550,8 @@ CONFIG_MDIO_BITBANG=y
 # CONFIG_MDIO_GPIO 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
@@ -544,6 +565,7 @@ CONFIG_FS_ENET=y
 CONFIG_FS_ENET_HAS_FCC=y
 CONFIG_FS_ENET_MDIO_FCC=y
 CONFIG_NETDEV_1000=y
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
 CONFIG_NETDEV_10000=y
 
@@ -552,7 +574,6 @@ CONFIG_NETDEV_10000=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
@@ -624,6 +645,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -663,6 +685,7 @@ CONFIG_HWMON=y
 # 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
@@ -726,7 +749,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -739,7 +761,7 @@ CONFIG_USB_SUPPORT=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
 
@@ -753,6 +775,7 @@ CONFIG_USB_SUPPORT=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
 # CONFIG_STAGING is not set
 
@@ -763,6 +786,7 @@ 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
@@ -786,6 +810,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
@@ -829,6 +858,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -838,7 +868,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -866,6 +895,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -879,11 +909,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -901,6 +933,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
@@ -931,9 +966,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -941,17 +979,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1045,6 +1086,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/mpc8536_ds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8536_ds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8536_ds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8536_ds_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1802 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:04 2009
-#
-# CONFIG_PPC64 is not set
-
-#
-# Processor support
-#
-# CONFIG_6xx is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_E500=y
-# CONFIG_PPC_E500MC is not set
-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
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
-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_HAVE_SETUP_PER_CPU_AREA is not set
-CONFIG_IRQ_PER_CPU=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_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
-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=y
-# CONFIG_GENERIC_TBSYNC is not set
-CONFIG_AUDIT_ARCH=y
-CONFIG_GENERIC_BUG=y
-CONFIG_DEFAULT_UIMAGE=y
-# CONFIG_PPC_DCR_NATIVE is not set
-# CONFIG_PPC_DCR_MMIO is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# 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_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-CONFIG_AUDIT=y
-# CONFIG_AUDITSYSCALL is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=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_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=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=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE 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_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_FREEZER is not set
-
-#
-# Platform support
-#
-# CONFIG_PPC_CELL is not set
-# CONFIG_PPC_CELL_NATIVE is not set
-# CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-# CONFIG_MPC85xx_MDS is not set
-CONFIG_MPC8536_DS=y
-# CONFIG_MPC85xx_DS is not set
-# CONFIG_KSI8560 is not set
-# CONFIG_STX_GP3 is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_SBC8548 is not set
-# CONFIG_SBC8560 is not set
-# CONFIG_IPIC is not set
-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_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_QUICC_ENGINE is not set
-# CONFIG_CPM2 is not set
-# CONFIG_FSL_ULI1575 is not set
-# CONFIG_MPC8xxx_GPIO is not set
-# CONFIG_SIMPLE_GPIO is not set
-
-#
-# Kernel options
-#
-CONFIG_HIGHMEM=y
-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_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_SCHED_HRTICK=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_MATH_EMULATION=y
-# CONFIG_IOMMU_HELPER is not set
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_HAS_WALK_MEMORY=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=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_MIGRATION=y
-# 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_PPC_4K_PAGES=y
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_64K_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=y
-CONFIG_ISA_DMA_API=y
-
-#
-# Bus options
-#
-CONFIG_ZONE_DMA=y
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_PCI=y
-CONFIG_PPC_PCI_CHOICE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS 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_PCCARD is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HAS_RAPIDIO is not set
-
-#
-# Advanced setup
-#
-# CONFIG_ADVANCED_OPTIONS is not set
-
-#
-# Default settings for advanced configuration options are used
-#
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_KERNEL_START=0xc0000000
-CONFIG_PHYSICAL_START=0x00000000
-CONFIG_PHYSICAL_ALIGN=0x10000000
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_COMPAT_NET_DEV_OPS=y
-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 is not set
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=m
-# 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=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=y
-CONFIG_NET_IPGRE=y
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-# 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=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_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 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=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 is not set
-# CONFIG_IP_DCCP 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_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_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_PHONET is not set
-CONFIG_FIB_RULES=y
-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
-# 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 is not set
-CONFIG_OF_DEVICE=y
-CONFIG_OF_I2C=y
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_FD is not set
-# 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=y
-# 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=524288
-# 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_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_C2PORT 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=y
-# CONFIG_CHR_DEV_OSST is not set
-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=y
-# CONFIG_SCSI_CONSTANTS is not set
-CONFIG_SCSI_LOGGING=y
-# 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_CXGB3_ISCSI 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 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_HPTIOP is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_LIBFC is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# 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_IPR 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
-# CONFIG_SCSI_DH 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=y
-CONFIG_SATA_FSL=y
-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=y
-# 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
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# 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_DUMMY=y
-# 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=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
-# 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_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM 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_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_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=y
-# CONFIG_SKGE_DEBUG is not set
-CONFIG_SKY2=y
-# CONFIG_SKY2_DEBUG is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-CONFIG_GIANFAR=y
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E 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_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_TR is not set
-
-#
-# Wireless LAN
-#
-# 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
-#
-# 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=m
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# 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=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# 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=y
-# 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=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-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_UARTLITE is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_HVC_UDBG is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM 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_CHARDEV is not set
-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_MPC=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_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI 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=y
-# 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_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_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=m
-CONFIG_VIDEO_MEDIA=m
-
-#
-# 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_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-# CONFIG_TTPCI_EEPROM is not set
-# CONFIG_DVB_BUDGET_CORE is not set
-
-#
-# Supported USB Adapters
-#
-# CONFIG_DVB_USB is not set
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-# CONFIG_DVB_SIANO_SMS1XXX is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_FLEXCOP is not set
-
-#
-# Supported BT878 Adapters
-#
-
-#
-# Supported Pluto2 Adapters
-#
-# CONFIG_DVB_PLUTO2 is not set
-
-#
-# Supported SDMC DM1105 Adapters
-#
-# CONFIG_DVB_DM1105 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# 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=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=y
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=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_VMASTER=y
-CONFIG_SND_AC97_CODEC=y
-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_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 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_CS5530 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_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=y
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 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_PPC=y
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=y
-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 is not set
-
-#
-# 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_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_TOPSEED is not set
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
-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=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=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_FSL=y
-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_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_PCI=y
-CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
-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 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_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_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_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# 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_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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=y
-# 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_PPC is not set
-CONFIG_DMADEVICES=y
-
-#
-# DMA Devices
-#
-CONFIG_FSL_DMA=y
-CONFIG_DMA_ENGINE=y
-
-#
-# DMA Clients
-#
-# CONFIG_NET_DMA is not set
-# CONFIG_DMATEST 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_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 is not set
-# CONFIG_GFS2_FS 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 is not set
-# CONFIG_FUSE_FS 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=m
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=y
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW 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=m
-# CONFIG_ADFS_FS_RW is not set
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-CONFIG_VXFS_FS=m
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-# CONFIG_ROMFS_FS is not set
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-# 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=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-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
-# 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=y
-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 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=m
-# CONFIG_DLM 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=m
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_HAVE_LMB=y
-
-#
-# 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_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_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_HIGHMEM 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_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=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-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
-# CONFIG_XMON is not set
-# CONFIG_IRQSTACKS is not set
-# CONFIG_VIRQ_DEBUG is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_PPC_EARLY_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_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# 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=m
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=m
-# 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=m
-# 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_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_CRYPTO_DEV_TALITOS=y
-# CONFIG_PPC_CLOCK is not set
-# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:05 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:17 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,21 +100,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,16 +126,19 @@ 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -129,7 +146,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -145,11 +161,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -165,6 +176,7 @@ CONFIG_MPC8540_ADS=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -233,9 +245,12 @@ 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_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
@@ -266,17 +281,17 @@ CONFIG_PPC_PCI_CHOICE=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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -332,6 +347,7 @@ 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
 
@@ -344,7 +360,6 @@ 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
@@ -387,9 +402,13 @@ 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_EEPROM_93CX6 is not set
 # 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
 
@@ -404,6 +423,7 @@ CONFIG_HAVE_IDE=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
@@ -432,6 +452,8 @@ CONFIG_PHYLIB=y
 # CONFIG_MDIO_BITBANG 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
@@ -441,6 +463,7 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
 CONFIG_NETDEV_10000=y
 
@@ -449,7 +472,6 @@ CONFIG_NETDEV_10000=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
@@ -607,7 +629,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -620,7 +641,7 @@ CONFIG_USB_SUPPORT=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
 
@@ -634,6 +655,7 @@ CONFIG_USB_SUPPORT=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
 # CONFIG_STAGING is not set
 
@@ -644,6 +666,7 @@ 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
@@ -666,6 +689,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
@@ -708,6 +736,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -717,7 +746,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -745,6 +773,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -758,11 +787,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -780,6 +811,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
@@ -809,9 +843,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -819,17 +856,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -922,6 +961,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/mpc8544_ds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8544_ds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8544_ds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8544_ds_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1802 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:07 2009
-#
-# CONFIG_PPC64 is not set
-
-#
-# Processor support
-#
-# CONFIG_6xx is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_E500=y
-# CONFIG_PPC_E500MC is not set
-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
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
-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_HAVE_SETUP_PER_CPU_AREA is not set
-CONFIG_IRQ_PER_CPU=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_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
-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=y
-# CONFIG_GENERIC_TBSYNC is not set
-CONFIG_AUDIT_ARCH=y
-CONFIG_GENERIC_BUG=y
-CONFIG_DEFAULT_UIMAGE=y
-# CONFIG_PPC_DCR_NATIVE is not set
-# CONFIG_PPC_DCR_MMIO is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# 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_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-CONFIG_AUDIT=y
-# CONFIG_AUDITSYSCALL is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=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_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=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=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE 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_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_FREEZER is not set
-
-#
-# Platform support
-#
-# CONFIG_PPC_CELL is not set
-# CONFIG_PPC_CELL_NATIVE is not set
-# CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-# CONFIG_MPC85xx_MDS is not set
-# CONFIG_MPC8536_DS is not set
-CONFIG_MPC85xx_DS=y
-# CONFIG_KSI8560 is not set
-# CONFIG_STX_GP3 is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_SBC8548 is not set
-# CONFIG_SBC8560 is not set
-# CONFIG_IPIC is not set
-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_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_QUICC_ENGINE is not set
-# CONFIG_CPM2 is not set
-CONFIG_FSL_ULI1575=y
-# CONFIG_MPC8xxx_GPIO is not set
-# CONFIG_SIMPLE_GPIO is not set
-
-#
-# Kernel options
-#
-CONFIG_HIGHMEM=y
-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_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_SCHED_HRTICK=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_MATH_EMULATION=y
-# CONFIG_IOMMU_HELPER is not set
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_HAS_WALK_MEMORY=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=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_MIGRATION=y
-# 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_PPC_4K_PAGES=y
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_64K_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=y
-CONFIG_ISA_DMA_API=y
-
-#
-# Bus options
-#
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_PCI=y
-CONFIG_PPC_PCI_CHOICE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS 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_PCCARD is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HAS_RAPIDIO is not set
-
-#
-# Advanced setup
-#
-# CONFIG_ADVANCED_OPTIONS is not set
-
-#
-# Default settings for advanced configuration options are used
-#
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_KERNEL_START=0xc0000000
-CONFIG_PHYSICAL_START=0x00000000
-CONFIG_PHYSICAL_ALIGN=0x10000000
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_COMPAT_NET_DEV_OPS=y
-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 is not set
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=m
-# 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=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=y
-CONFIG_NET_IPGRE=y
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-# 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=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_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 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=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 is not set
-# CONFIG_IP_DCCP 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_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_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_PHONET is not set
-CONFIG_FIB_RULES=y
-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
-# 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 is not set
-CONFIG_OF_DEVICE=y
-CONFIG_OF_I2C=y
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_FD is not set
-# 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=y
-# 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=131072
-# 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_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_C2PORT 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=y
-# CONFIG_CHR_DEV_OSST is not set
-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=y
-# CONFIG_SCSI_CONSTANTS is not set
-CONFIG_SCSI_LOGGING=y
-# 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_CXGB3_ISCSI 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 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_HPTIOP is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_LIBFC is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# 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_IPR 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
-# CONFIG_SCSI_DH is not set
-CONFIG_ATA=y
-# CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
-CONFIG_SATA_AHCI=y
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_FSL 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=y
-# 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
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# 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_DUMMY=y
-# 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=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
-# 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_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM 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_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_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_GIANFAR=y
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E 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_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_TR is not set
-
-#
-# Wireless LAN
-#
-# 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
-#
-# 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=m
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# 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=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# 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=y
-# 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=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-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_UARTLITE is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_HVC_UDBG is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-CONFIG_NVRAM=y
-# 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_CHARDEV is not set
-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_MPC=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_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI 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
-
-#
-# 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_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_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=m
-CONFIG_VIDEO_MEDIA=m
-
-#
-# 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_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-# CONFIG_TTPCI_EEPROM is not set
-# CONFIG_DVB_BUDGET_CORE is not set
-
-#
-# Supported USB Adapters
-#
-# CONFIG_DVB_USB is not set
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-# CONFIG_DVB_SIANO_SMS1XXX is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_FLEXCOP is not set
-
-#
-# Supported BT878 Adapters
-#
-
-#
-# Supported Pluto2 Adapters
-#
-# CONFIG_DVB_PLUTO2 is not set
-
-#
-# Supported SDMC DM1105 Adapters
-#
-# CONFIG_DVB_DM1105 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# 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=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-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 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_AC97_CODEC=y
-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_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 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_CS5530 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_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=y
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 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_PPC=y
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=y
-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 is not set
-
-#
-# 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_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_TOPSEED is not set
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
-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=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_EHCI_FSL 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_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_PCI=y
-CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
-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 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_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_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_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# 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_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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=y
-# 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_PPC is not set
-CONFIG_DMADEVICES=y
-
-#
-# DMA Devices
-#
-CONFIG_FSL_DMA=y
-CONFIG_DMA_ENGINE=y
-
-#
-# DMA Clients
-#
-# CONFIG_NET_DMA is not set
-# CONFIG_DMATEST 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_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_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_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
-
-#
-# 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=m
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=y
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW 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=m
-# CONFIG_ADFS_FS_RW is not set
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-CONFIG_VXFS_FS=m
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-# CONFIG_ROMFS_FS is not set
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-# 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=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-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
-# 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=y
-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 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=m
-# CONFIG_DLM 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=m
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_HAVE_LMB=y
-
-#
-# 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 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_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_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_HIGHMEM 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_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=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-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
-# CONFIG_XMON is not set
-# CONFIG_IRQSTACKS is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_PPC_EARLY_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_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# 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=m
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=m
-# 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=m
-# 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_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_CRYPTO_DEV_TALITOS=y
-# CONFIG_PPC_CLOCK is not set
-# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:09 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:17 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -90,21 +101,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -114,10 +128,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -125,6 +141,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +149,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,11 +164,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -168,6 +179,7 @@ CONFIG_MPC8560_ADS=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -236,9 +248,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -264,6 +279,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # 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
@@ -277,17 +293,17 @@ CONFIG_PCI_DEBUG=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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -343,6 +359,7 @@ 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
 
@@ -355,7 +372,6 @@ 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
@@ -405,12 +421,16 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -437,6 +457,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -470,6 +491,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_ZMII is not set
@@ -493,6 +516,7 @@ CONFIG_E1000=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
@@ -503,10 +527,12 @@ CONFIG_E1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -516,6 +542,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
@@ -525,6 +552,7 @@ 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
 
 #
@@ -532,7 +560,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -608,6 +635,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -651,6 +679,7 @@ CONFIG_HWMON=y
 # 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_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -719,7 +748,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -733,7 +761,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
 
@@ -749,6 +777,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -759,6 +788,7 @@ 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
@@ -781,6 +811,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
@@ -823,6 +858,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -832,7 +868,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -860,6 +895,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -873,11 +909,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -895,6 +933,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
@@ -924,9 +965,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -934,17 +978,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1037,6 +1083,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/mpc8568mds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8568mds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8568mds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8568mds_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1309 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:10 2009
-#
-# CONFIG_PPC64 is not set
-
-#
-# Processor support
-#
-# CONFIG_6xx is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_E500=y
-# CONFIG_PPC_E500MC is not set
-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
-# CONFIG_PPC_MM_SLICES is not set
-# CONFIG_SMP is not set
-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_HAVE_SETUP_PER_CPU_AREA is not set
-CONFIG_IRQ_PER_CPU=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_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
-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=y
-# CONFIG_GENERIC_TBSYNC is not set
-CONFIG_AUDIT_ARCH=y
-CONFIG_GENERIC_BUG=y
-CONFIG_DEFAULT_UIMAGE=y
-# CONFIG_PPC_DCR_NATIVE is not set
-# CONFIG_PPC_DCR_MMIO is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# 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
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-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 is not set
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=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_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE 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=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_FREEZER is not set
-
-#
-# Platform support
-#
-# CONFIG_PPC_CELL is not set
-# CONFIG_PPC_CELL_NATIVE is not set
-# CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-CONFIG_MPC85xx_MDS=y
-# CONFIG_MPC8536_DS is not set
-# CONFIG_MPC85xx_DS is not set
-# CONFIG_KSI8560 is not set
-# CONFIG_STX_GP3 is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_SBC8548 is not set
-# CONFIG_SBC8560 is not set
-# CONFIG_IPIC is not set
-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_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_QUICC_ENGINE=y
-# CONFIG_QE_GPIO is not set
-# CONFIG_CPM2 is not set
-# CONFIG_FSL_ULI1575 is not set
-# CONFIG_MPC8xxx_GPIO is not set
-# CONFIG_SIMPLE_GPIO is not set
-
-#
-# Kernel options
-#
-# CONFIG_HIGHMEM is not set
-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_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_SCHED_HRTICK=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-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_MATH_EMULATION=y
-# CONFIG_IOMMU_HELPER is not set
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_HAS_WALK_MEMORY=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=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_MIGRATION=y
-# 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_PPC_4K_PAGES=y
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_64K_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=y
-CONFIG_ISA_DMA_API=y
-
-#
-# Bus options
-#
-CONFIG_ZONE_DMA=y
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_PCI=y
-CONFIG_PPC_PCI_CHOICE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS 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_PCCARD is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HAS_RAPIDIO is not set
-
-#
-# Advanced setup
-#
-# CONFIG_ADVANCED_OPTIONS is not set
-
-#
-# Default settings for advanced configuration options are used
-#
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_KERNEL_START=0xc0000000
-CONFIG_PHYSICAL_START=0x00000000
-CONFIG_PHYSICAL_ALIGN=0x10000000
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_COMPAT_NET_DEV_OPS=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=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=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_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_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_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
-# 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_OF_DEVICE=y
-CONFIG_OF_I2C=y
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_FD is not set
-# 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_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=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_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_C2PORT 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 is not set
-# 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_SCSI_CXGB3_ISCSI 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 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_HPTIOP is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_LIBFC is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# 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
-# 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
-# CONFIG_SCSI_DH is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# 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_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=y
-# 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_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM 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_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_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_GIANFAR=y
-# CONFIG_UCC_GETH is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E 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_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_TR is not set
-
-#
-# Wireless LAN
-#
-# 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_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 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 is not set
-CONFIG_DEVKMEM=y
-# 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=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_UARTLITE is not set
-CONFIG_SERIAL_CORE=y
-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_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_HVC_UDBG is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM 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_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_MPC=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
-
-#
-# 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_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
-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_AD7414 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_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_I5K_AMB 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_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_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SIS5595 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_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 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_ALIM7101_WDT is not set
-# CONFIG_BOOKE_WDT is not set
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI 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_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_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=y
-
-#
-# Graphics support
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# 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
-# 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
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-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
-
-#
-# Enable Host or Gadget support to see Inventra options
-#
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# 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_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=y
-# 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
-
-#
-# 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_PPC is not set
-# CONFIG_DMADEVICES 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_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_FILE_LOCKING=y
-# CONFIG_XFS_FS 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 is not set
-# CONFIG_FUSE_FS 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_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_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_SUNRPC_REGISTER_V4 is not set
-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 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 is not set
-# CONFIG_DLM 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_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_HAVE_LMB=y
-
-#
-# 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 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_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_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 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=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-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
-# CONFIG_XMON is not set
-# CONFIG_IRQSTACKS is not set
-# CONFIG_BDI_SWITCH 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
-
-#
-# 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_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-# 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=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
-
-#
-# 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 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_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_CRYPTO_DEV_TALITOS is not set
-# CONFIG_PPC_CLOCK is not set
-CONFIG_PPC_LIB_RHEAP=y
-# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8572_ds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8572_ds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc8572_ds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc8572_ds_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,1794 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:12 2009
-#
-# CONFIG_PPC64 is not set
-
-#
-# Processor support
-#
-# CONFIG_6xx is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_E200 is not set
-CONFIG_E500=y
-# CONFIG_PPC_E500MC is not set
-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
-# CONFIG_PPC_MM_SLICES is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-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_HAVE_SETUP_PER_CPU_AREA is not set
-CONFIG_IRQ_PER_CPU=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_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
-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=y
-CONFIG_GENERIC_TBSYNC=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_GENERIC_BUG=y
-CONFIG_DEFAULT_UIMAGE=y
-# CONFIG_PPC_DCR_NATIVE is not set
-# CONFIG_PPC_DCR_MMIO is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=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=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-CONFIG_AUDIT=y
-# CONFIG_AUDITSYSCALL is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# 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_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=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_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_USE_GENERIC_SMP_HELPERS=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=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE 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_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_FREEZER is not set
-
-#
-# Platform support
-#
-# CONFIG_PPC_CELL is not set
-# CONFIG_PPC_CELL_NATIVE is not set
-# CONFIG_PQ2ADS is not set
-CONFIG_MPC85xx=y
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-# CONFIG_MPC85xx_MDS is not set
-# CONFIG_MPC8536_DS is not set
-CONFIG_MPC85xx_DS=y
-# CONFIG_KSI8560 is not set
-# CONFIG_STX_GP3 is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_SBC8548 is not set
-# CONFIG_SBC8560 is not set
-# CONFIG_IPIC is not set
-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_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_QUICC_ENGINE is not set
-# CONFIG_CPM2 is not set
-CONFIG_FSL_ULI1575=y
-# CONFIG_MPC8xxx_GPIO is not set
-# CONFIG_SIMPLE_GPIO is not set
-
-#
-# Kernel options
-#
-CONFIG_HIGHMEM=y
-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_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_SCHED_HRTICK=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_MATH_EMULATION=y
-# CONFIG_IOMMU_HELPER is not set
-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_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=y
-# 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_PPC_4K_PAGES=y
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_64K_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=y
-CONFIG_ISA_DMA_API=y
-
-#
-# Bus options
-#
-CONFIG_ZONE_DMA=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_PCI=y
-CONFIG_PPC_PCI_CHOICE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS 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_PCCARD is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HAS_RAPIDIO is not set
-
-#
-# Advanced setup
-#
-# CONFIG_ADVANCED_OPTIONS is not set
-
-#
-# Default settings for advanced configuration options are used
-#
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_KERNEL_START=0xc0000000
-CONFIG_PHYSICAL_START=0x00000000
-CONFIG_PHYSICAL_ALIGN=0x10000000
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_COMPAT_NET_DEV_OPS=y
-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 is not set
-# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=m
-# 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=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=y
-CONFIG_NET_IPGRE=y
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-# 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=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-CONFIG_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 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=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 is not set
-# CONFIG_IP_DCCP 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_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_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_PHONET is not set
-CONFIG_FIB_RULES=y
-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
-# 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 is not set
-CONFIG_OF_DEVICE=y
-CONFIG_OF_I2C=y
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_FD is not set
-# 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=y
-# 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=131072
-# 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_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_C2PORT 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=y
-# CONFIG_CHR_DEV_OSST is not set
-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=y
-# CONFIG_SCSI_CONSTANTS is not set
-CONFIG_SCSI_LOGGING=y
-# 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_CXGB3_ISCSI 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 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_HPTIOP is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_LIBFC is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# 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_IPR 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
-# CONFIG_SCSI_DH is not set
-CONFIG_ATA=y
-# CONFIG_ATA_NONSTANDARD is not set
-CONFIG_SATA_PMP=y
-CONFIG_SATA_AHCI=y
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_FSL 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=y
-# 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
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# 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_DUMMY=y
-# 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=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
-# 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_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM 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_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_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_GIANFAR=y
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E 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_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_TR is not set
-
-#
-# Wireless LAN
-#
-# 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
-#
-# 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=m
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# 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=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# 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=y
-# 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=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-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_UARTLITE is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_HVC_UDBG is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-CONFIG_NVRAM=y
-# 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_CHARDEV is not set
-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_MPC=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_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI 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
-
-#
-# 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_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_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=m
-CONFIG_VIDEO_MEDIA=m
-
-#
-# 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_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-# CONFIG_TTPCI_EEPROM is not set
-# CONFIG_DVB_BUDGET_CORE is not set
-
-#
-# Supported USB Adapters
-#
-# CONFIG_DVB_USB is not set
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-# CONFIG_DVB_SIANO_SMS1XXX is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_FLEXCOP is not set
-
-#
-# Supported BT878 Adapters
-#
-
-#
-# Supported Pluto2 Adapters
-#
-# CONFIG_DVB_PLUTO2 is not set
-
-#
-# Supported SDMC DM1105 Adapters
-#
-# CONFIG_DVB_DM1105 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# 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=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-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 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_AC97_CODEC=y
-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_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 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_CS5530 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_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=y
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 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_PPC=y
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=y
-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 is not set
-
-#
-# 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_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_TOPSEED is not set
-CONFIG_THRUSTMASTER_FF=m
-CONFIG_ZEROPLUS_FF=m
-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=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_EHCI_FSL 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_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_PCI=y
-CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
-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 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_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_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_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# 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_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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=y
-# 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_PPC is not set
-# CONFIG_DMADEVICES 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_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_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_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
-
-#
-# 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=m
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=y
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW 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=m
-# CONFIG_ADFS_FS_RW is not set
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=y
-# CONFIG_SQUASHFS is not set
-CONFIG_VXFS_FS=m
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-# CONFIG_ROMFS_FS is not set
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-# 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=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_V4 is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-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
-# 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=y
-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 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=m
-# CONFIG_DLM 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=m
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_HAVE_LMB=y
-
-#
-# 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 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_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_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_HIGHMEM 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_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=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-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
-# CONFIG_XMON is not set
-# CONFIG_IRQSTACKS is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_PPC_EARLY_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_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# 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=m
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=m
-# 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=m
-# 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_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_CRYPTO_DEV_TALITOS=y
-# CONFIG_PPC_CLOCK is not set
-# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:13 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:18 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,21 +100,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -113,16 +127,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,7 +147,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -146,11 +162,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -166,6 +177,7 @@ CONFIG_MPC85xx_CDS=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -234,9 +246,12 @@ 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_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
@@ -262,6 +277,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,17 +291,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 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 +357,7 @@ 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
 
@@ -353,7 +370,6 @@ 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
@@ -402,18 +418,23 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_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
@@ -488,6 +509,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -521,6 +543,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_ZMII is not set
@@ -540,6 +564,7 @@ CONFIG_E1000=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
@@ -550,10 +575,12 @@ CONFIG_E1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -563,6 +590,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
@@ -572,6 +600,7 @@ 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
 
 #
@@ -579,7 +608,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -750,7 +778,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -764,7 +791,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
 
@@ -780,6 +807,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -790,6 +818,7 @@ 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
@@ -812,6 +841,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
@@ -854,6 +888,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -863,7 +898,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -891,6 +925,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -904,11 +939,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -926,6 +963,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
@@ -955,9 +995,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -965,17 +1008,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1068,6 +1113,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/sbc8548_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:15 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:19 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,20 +100,23 @@ 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_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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -111,16 +125,19 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -128,7 +145,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -144,11 +160,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -164,6 +175,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -231,9 +243,12 @@ 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_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 +273,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
@@ -271,17 +287,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -337,6 +353,7 @@ 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
 
@@ -349,7 +366,6 @@ 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
@@ -396,12 +412,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -428,6 +448,7 @@ CONFIG_HAVE_IDE=y
 # 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
@@ -461,6 +482,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_ZMII is not set
@@ -480,6 +503,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
@@ -490,10 +514,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -503,6 +529,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
@@ -512,6 +539,7 @@ 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
 
 #
@@ -519,7 +547,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -692,6 +719,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=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
 # CONFIG_STAGING is not set
 
@@ -717,6 +745,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
@@ -759,6 +792,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -768,7 +802,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -784,6 +817,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
@@ -797,11 +831,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -821,13 +857,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -918,6 +965,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/sbc8560_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:17 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:20 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,21 +100,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -111,16 +125,19 @@ 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -128,7 +145,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -144,11 +160,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -164,6 +175,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -231,9 +243,12 @@ 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_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,17 +279,17 @@ CONFIG_PPC_PCI_CHOICE=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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -330,6 +345,7 @@ 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
 
@@ -342,7 +358,6 @@ 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
@@ -385,9 +400,13 @@ 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_EEPROM_93CX6 is not set
 # 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
 
@@ -402,6 +421,7 @@ CONFIG_HAVE_IDE=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
@@ -430,6 +450,8 @@ CONFIG_BROADCOM_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -439,6 +461,7 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
 CONFIG_NETDEV_10000=y
 
@@ -447,7 +470,6 @@ CONFIG_NETDEV_10000=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
@@ -603,7 +625,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -616,7 +637,7 @@ CONFIG_USB_SUPPORT=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,8 +686,9 @@ CONFIG_RTC_DRV_M48T59=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -692,6 +714,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
@@ -734,6 +761,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -743,7 +771,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -771,6 +798,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -784,11 +812,13 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -806,6 +836,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
@@ -834,9 +867,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -844,17 +880,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -958,6 +996,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/socrates_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/socrates_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/socrates_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1617 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:21 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_E500=y
+# CONFIG_PPC_E500MC is not set
+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
+CONFIG_PPC_BOOK3E_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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
+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=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# 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"
+
+#
+# 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_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=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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+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_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+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_SLOW_WORK is not set
+# 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=y
+# CONFIG_MODVERSIONS is not set
+# 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=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_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_MPC85xx=y
+# CONFIG_MPC8540_ADS is not set
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_MPC85xx_CDS is not set
+# CONFIG_MPC85xx_MDS is not set
+# CONFIG_MPC8536_DS is not set
+# CONFIG_MPC85xx_DS is not set
+CONFIG_SOCRATES=y
+# CONFIG_KSI8560 is not set
+# CONFIG_STX_GP3 is not set
+# CONFIG_TQM8540 is not set
+# CONFIG_TQM8541 is not set
+# CONFIG_TQM8548 is not set
+# CONFIG_TQM8555 is not set
+# CONFIG_TQM8560 is not set
+# CONFIG_SBC8548 is not set
+# CONFIG_SBC8560 is not set
+# CONFIG_IPIC is not set
+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_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_QUICC_ENGINE is not set
+# CONFIG_CPM2 is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_MPC8xxx_GPIO 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=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+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_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=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_MIGRATION=y
+# 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_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 is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# 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_PHYSICAL_ALIGN=0x04000000
+CONFIG_TASK_SIZE=0xc0000000
+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=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_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=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES 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_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 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_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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
+# 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 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 is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# 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 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_NAND_FSL_ELBC is not set
+# CONFIG_MTD_NAND_FSL_UPM is not set
+CONFIG_MTD_NAND_SOCRATES=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_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_OF_SPI=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# 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=y
+# CONFIG_PHANTOM 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_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_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
+
+#
+# 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_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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
+# 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=y
+# 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_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ENC28J60 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_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_FSL_PQ_MDIO=y
+CONFIG_GIANFAR=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
+
+#
+# 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_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=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# 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 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_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_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
+# CONFIG_NOZOMI 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=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_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_NVRAM 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_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_MPC=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_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=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG 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 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# 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_I5K_AMB 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_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+CONFIG_SENSORS_W83781D=y
+# 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_HWMON_DEBUG_CHIP=y
+# 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_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_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=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# 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=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_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_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 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_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_FSL_DIU 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=y
+# CONFIG_FB_MB862XX_PCI_GDC is not set
+CONFIG_FB_MB862XX_LIME=y
+# CONFIG_FB_PRE_INIT_FB 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=y
+# CONFIG_FONT_8x8 is not set
+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 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 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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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=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=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_EHCI_FSL 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_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_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+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 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_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
+
+#
+# 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_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 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 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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 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_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=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 is not set
+# CONFIG_DLM 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_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# 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 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_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
+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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_PPC_EARLY_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_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_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_TALITOS is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/stx_gp3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:18 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:22 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -90,21 +101,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -114,10 +128,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -126,6 +142,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -137,7 +154,6 @@ CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -153,11 +169,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -173,6 +184,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 CONFIG_STX_GP3=y
 # CONFIG_TQM8540 is not set
@@ -241,9 +253,12 @@ 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_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
@@ -269,6 +284,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,17 +298,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -353,6 +369,7 @@ CONFIG_NETFILTER_XTABLES=m
 # 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
@@ -389,6 +406,7 @@ CONFIG_IP_NF_FILTER=m
 # 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 is not set
 # CONFIG_IP_DCCP is not set
@@ -406,6 +424,7 @@ CONFIG_IP_NF_FILTER=m
 # 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
 
@@ -418,7 +437,6 @@ CONFIG_NET_PKTGEN=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
@@ -476,13 +494,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -591,9 +616,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -617,6 +644,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -633,6 +661,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -666,6 +695,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_ZMII is not set
@@ -687,6 +718,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
@@ -697,10 +729,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -710,6 +744,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
@@ -719,6 +754,7 @@ 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
 
 #
@@ -726,7 +762,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -778,7 +813,6 @@ 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_TOUCHKIT is not set
@@ -837,6 +871,7 @@ CONFIG_PRINTER=m
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -903,12 +938,9 @@ CONFIG_I2C_ALGOBIT=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
@@ -964,6 +996,7 @@ CONFIG_HWMON=y
 # 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
@@ -978,11 +1011,15 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1075,7 +1112,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1089,7 +1125,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
 
@@ -1116,6 +1152,7 @@ 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
@@ -1138,6 +1175,11 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=m
@@ -1186,6 +1228,7 @@ CONFIG_CRAMFS=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
@@ -1197,7 +1240,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=m
@@ -1253,6 +1295,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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
@@ -1266,12 +1309,13 @@ CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1289,6 +1333,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
@@ -1319,9 +1366,12 @@ CONFIG_SCHED_DEBUG=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1329,17 +1379,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1433,6 +1485,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8540_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:19 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:23 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,19 +100,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -111,16 +125,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -128,7 +145,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -144,11 +160,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -164,6 +175,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 CONFIG_TQM8540=y
@@ -232,9 +244,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -259,6 +274,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_HAS_RAPIDIO is not set
 
 #
@@ -270,17 +286,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -336,6 +352,7 @@ 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
 
@@ -348,7 +365,6 @@ 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
@@ -448,7 +464,6 @@ CONFIG_MTD_CFI_UTIL=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -477,19 +492,27 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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
@@ -564,6 +587,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -597,6 +621,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_ZMII is not set
@@ -634,6 +660,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,10 +671,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -657,6 +686,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
@@ -666,6 +696,7 @@ 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
 
 #
@@ -673,7 +704,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -754,6 +784,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -816,12 +847,9 @@ CONFIG_I2C_MPC=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
@@ -853,6 +881,7 @@ CONFIG_HWMON=y
 # 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
@@ -867,11 +896,14 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -955,7 +987,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -969,7 +1000,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
 
@@ -985,6 +1016,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -995,6 +1027,7 @@ 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
@@ -1017,6 +1050,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
@@ -1070,6 +1108,7 @@ 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 is not set
@@ -1079,7 +1118,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1107,6 +1145,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1122,11 +1161,12 @@ 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
 
 #
 # Kernel hacking
@@ -1148,13 +1188,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1245,6 +1296,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8541_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:20 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:23 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -90,19 +101,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,10 +126,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -123,6 +139,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,7 +147,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -146,11 +162,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -166,6 +177,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -235,9 +247,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -262,6 +277,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_HAS_RAPIDIO is not set
 
 #
@@ -273,17 +289,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +355,7 @@ 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
 
@@ -351,7 +368,6 @@ 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
@@ -451,7 +467,6 @@ CONFIG_MTD_CFI_UTIL=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -481,19 +496,27 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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
@@ -568,6 +591,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -601,6 +625,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_ZMII is not set
@@ -639,6 +665,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
@@ -649,10 +676,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -662,6 +691,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
@@ -671,6 +701,7 @@ 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
 
 #
@@ -678,7 +709,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -761,6 +791,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -825,12 +856,9 @@ CONFIG_I2C_MPC=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
@@ -885,6 +913,7 @@ CONFIG_HWMON=y
 # 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
@@ -899,11 +928,15 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -988,7 +1021,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1002,7 +1034,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
 
@@ -1018,6 +1050,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1028,6 +1061,7 @@ 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
@@ -1050,6 +1084,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
@@ -1103,6 +1142,7 @@ 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 is not set
@@ -1112,7 +1152,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1140,6 +1179,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1155,11 +1195,12 @@ 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
 
 #
 # Kernel hacking
@@ -1181,13 +1222,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1278,6 +1330,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8548_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:20 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:24 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,21 +100,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -113,10 +127,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -124,6 +140,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -136,7 +153,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -152,11 +168,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -172,6 +183,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -202,7 +214,7 @@ CONFIG_MPIC=y
 #
 # Kernel options
 #
-# CONFIG_HIGHMEM is not set
+CONFIG_HIGHMEM=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -241,9 +253,12 @@ 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_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
@@ -259,6 +274,7 @@ CONFIG_ZONE_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
+CONFIG_FSL_LBC=y
 CONFIG_PPC_PCI_CHOICE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
@@ -271,6 +287,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
@@ -284,17 +301,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +367,7 @@ 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
 
@@ -362,13 +380,7 @@ 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
+# CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -471,27 +483,18 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_NAND_FSL_ELBC is not set
-# CONFIG_MTD_NAND_FSL_UPM is not set
+CONFIG_MTD_NAND_FSL_UPM=y
 # CONFIG_MTD_ONENAND is not set
 
 #
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
 #
-CONFIG_MTD_UBI=m
-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_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -515,69 +518,22 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
 
 #
-# Please see Documentation/ide/ide.txt for help/info on IDE drives
-#
-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 is not set
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_PLATFORM is not set
-CONFIG_BLK_DEV_IDEDMA_SFF=y
-
-#
-# PCI IDE chipsets support
+# EEPROM support
 #
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# 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 is not set
-# 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_SL82C105 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-# CONFIG_BLK_DEV_TC86C001 is not set
-CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
@@ -602,6 +558,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -635,6 +592,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_ZMII is not set
@@ -650,10 +609,11 @@ CONFIG_MII=y
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
-CONFIG_E1000=y
+# 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
@@ -664,10 +624,12 @@ CONFIG_E1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -677,6 +639,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
@@ -686,6 +649,7 @@ 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
 
 #
@@ -693,7 +657,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -835,12 +798,9 @@ CONFIG_I2C_MPC=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
@@ -872,6 +832,7 @@ CONFIG_HWMON=y
 # 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
@@ -886,11 +847,14 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -974,27 +938,7 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
-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
-
-#
-# Enable Host or Gadget support to see Inventra options
-#
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
+# CONFIG_USB_SUPPORT is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1056,24 +1000,18 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # 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_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS 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
@@ -1090,6 +1028,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 +1065,17 @@ CONFIG_MISC_FILESYSTEMS=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_UBIFS_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
@@ -1134,6 +1086,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -1143,7 +1096,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1171,6 +1123,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1184,11 +1137,14 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=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_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1206,6 +1162,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
@@ -1219,6 +1178,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
@@ -1235,9 +1195,12 @@ CONFIG_DEBUG_MUTEXES=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1245,17 +1208,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1349,6 +1314,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8555_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:21 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:25 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -90,19 +101,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,10 +126,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -123,6 +139,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,7 +147,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -146,11 +162,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -166,6 +177,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -235,9 +247,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -262,6 +277,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_HAS_RAPIDIO is not set
 
 #
@@ -273,17 +289,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +355,7 @@ 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
 
@@ -351,7 +368,6 @@ 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
@@ -451,7 +467,6 @@ CONFIG_MTD_CFI_UTIL=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -481,19 +496,27 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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
@@ -568,6 +591,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -601,6 +625,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_ZMII is not set
@@ -639,6 +665,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
@@ -649,10 +676,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -662,6 +691,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
@@ -671,6 +701,7 @@ 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
 
 #
@@ -678,7 +709,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -761,6 +791,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -825,12 +856,9 @@ CONFIG_I2C_MPC=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
@@ -885,6 +913,7 @@ CONFIG_HWMON=y
 # 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
@@ -899,11 +928,15 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -988,7 +1021,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1002,7 +1034,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
 
@@ -1018,6 +1050,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1028,6 +1061,7 @@ 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
@@ -1050,6 +1084,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
@@ -1103,6 +1142,7 @@ 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 is not set
@@ -1112,7 +1152,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1140,6 +1179,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1155,11 +1195,12 @@ 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
 
 #
 # Kernel hacking
@@ -1181,13 +1222,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1278,6 +1330,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/85xx/tqm8560_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:22 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:26 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -76,6 +78,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -90,19 +101,22 @@ 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,10 +126,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -123,6 +139,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,7 +147,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -146,11 +162,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -166,6 +177,7 @@ CONFIG_MPC85xx=y
 # CONFIG_MPC85xx_MDS is not set
 # CONFIG_MPC8536_DS is not set
 # CONFIG_MPC85xx_DS is not set
+# CONFIG_SOCRATES is not set
 # CONFIG_KSI8560 is not set
 # CONFIG_STX_GP3 is not set
 # CONFIG_TQM8540 is not set
@@ -235,9 +247,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -262,6 +277,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_HAS_RAPIDIO is not set
 
 #
@@ -273,17 +289,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +355,7 @@ 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
 
@@ -351,7 +368,6 @@ 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
@@ -451,7 +467,6 @@ CONFIG_MTD_CFI_UTIL=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -481,19 +496,27 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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
@@ -568,6 +591,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # 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
@@ -601,6 +625,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_ZMII is not set
@@ -639,6 +665,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
@@ -649,10 +676,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -662,6 +691,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
@@ -671,6 +701,7 @@ 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
 
 #
@@ -678,7 +709,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -761,6 +791,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -825,12 +856,9 @@ CONFIG_I2C_MPC=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
@@ -885,6 +913,7 @@ CONFIG_HWMON=y
 # 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
@@ -899,11 +928,15 @@ CONFIG_SENSORS_LM75=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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -988,7 +1021,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1002,7 +1034,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
 
@@ -1018,6 +1050,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1028,6 +1061,7 @@ 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
@@ -1050,6 +1084,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
@@ -1103,6 +1142,7 @@ 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 is not set
@@ -1112,7 +1152,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1140,6 +1179,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1155,11 +1195,12 @@ 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
 
 #
 # Kernel hacking
@@ -1181,13 +1222,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1278,6 +1330,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_ppc9a_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1937 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:31 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=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_PPC_FPU=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_LOCKBREAK=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
+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=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# 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"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=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=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_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=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 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_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_MARKERS is not set
+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_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
+# 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_STOP_MACHINE=y
+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=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
+
+#
+# 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=y
+# CONFIG_MPC8641_HPCN is not set
+# CONFIG_SBC8641D is not set
+# CONFIG_MPC8610_HPCD is not set
+CONFIG_GEF_PPC9A=y
+# CONFIG_GEF_SBC310 is not set
+# CONFIG_GEF_SBC610 is not set
+CONFIG_MPC8641=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+# CONFIG_IPIC is not set
+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_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_QUICC_ENGINE is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_MPC8xxx_GPIO is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=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_MIGRATION=y
+# 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_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 is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# 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=y
+# 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
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# 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=m
+# 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=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+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=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 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=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+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 is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE 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
+CONFIG_BRIDGE_NETFILTER=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_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL 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_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP 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=m
+# 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 is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV 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=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+# CONFIG_IP_NF_MATCH_AH is not set
+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_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+# CONFIG_IP_NF_SECURITY is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+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 is not set
+CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+# CONFIG_IP6_NF_SECURITY is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP 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_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_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=m
+# CONFIG_PHONET 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 is not set
+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 is not set
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+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 is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# 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_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 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_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_OF_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=y
+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=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 is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# 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 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_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_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=m
+CONFIG_BLK_DEV_NBD=m
+# 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=131072
+# 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO 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_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=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# 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
+# 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_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 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
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# 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_IPR 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
+# 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_SATA_FSL 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=y
+# 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
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# 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=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# 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_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_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_FSL_PQ_MDIO=y
+CONFIG_GIANFAR=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
+
+#
+# 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_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+# CONFIG_ATM_TCP is not set
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+# CONFIG_ATM_FORE200E is not set
+# CONFIG_ATM_HE is not set
+# CONFIG_ATM_SOLOS is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 is not set
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC 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=m
+# 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 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
+# 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=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_NVRAM=y
+# 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_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_MPC=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=y
+# 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
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# 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:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# 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_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_I5K_AMB 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_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=y
+CONFIG_SENSORS_LM92=y
+# 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_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_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_ALIM7101_WDT is not set
+CONFIG_GEF_WDT=y
+# CONFIG_8xxx_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI 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_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_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=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# 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=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+# 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 is not set
+
+#
+# Special HID drivers
+#
+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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+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 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_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PPC_OF 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_HCD_PPC_OF is not set
+# 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 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_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_ATM 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_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 is not set
+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=y
+
+#
+# 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 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=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
+# 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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 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_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 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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+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=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# 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=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM 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=m
+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_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# 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_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_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 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_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
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE 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_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+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_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO 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=m
+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=m
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+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=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# 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
+
+#
+# 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 is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_sbc310_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1661 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:29 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=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_PPC_FPU=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_LOCKBREAK=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
+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=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# 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"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=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=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_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=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_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_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_MARKERS is not set
+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_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
+# 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_STOP_MACHINE=y
+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=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
+CONFIG_PPC_MSI_BITMAP=y
+
+#
+# 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=y
+# CONFIG_MPC8641_HPCN is not set
+# CONFIG_SBC8641D is not set
+# CONFIG_MPC8610_HPCD is not set
+# CONFIG_GEF_PPC9A is not set
+CONFIG_GEF_SBC310=y
+# CONFIG_GEF_SBC610 is not set
+CONFIG_MPC8641=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+# CONFIG_IPIC is not set
+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_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_QUICC_ENGINE is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_MPC8xxx_GPIO is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=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_MIGRATION=y
+# 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_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 is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# 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
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# 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=m
+# 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=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+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=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 is not set
+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=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 is not set
+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 is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE 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=m
+# 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 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_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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 is not set
+CONFIG_MTD_OF_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=y
+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=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 is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# 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 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_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_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=m
+CONFIG_BLK_DEV_NBD=m
+# 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=131072
+# 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO 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_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=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# 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
+# 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_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 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
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# 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_IPR 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
+# 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=y
+# CONFIG_SATA_FSL is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# 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=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# 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_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_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_FSL_PQ_MDIO=y
+CONFIG_GIANFAR=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
+
+#
+# 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_FDDI is not set
+# CONFIG_HIPPI 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 is not set
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC 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=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 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
+# 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=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_NVRAM=y
+# 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_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_MPC=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=y
+# 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
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+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:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# 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_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_I5K_AMB 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_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=y
+CONFIG_SENSORS_LM92=y
+# 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_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_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_ALIM7101_WDT is not set
+CONFIG_GEF_WDT=y
+# CONFIG_8xxx_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI 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_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_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=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# 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=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+# 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 is not set
+
+#
+# Special HID drivers
+#
+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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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 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_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PPC_OF 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_HCD_PPC_OF is not set
+# 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 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_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_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 is not set
+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=y
+
+#
+# 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 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=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
+# 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_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 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=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# 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 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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+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=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# 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=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM 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 is not set
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+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_HAVE_LMB=y
+CONFIG_NLATTR=y
+
+#
+# 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_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_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
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_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_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_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=m
+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=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# 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=m
+# 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=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 is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/gef_sbc610_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:26 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:30 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_ALTIVEC=y
@@ -58,6 +59,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -72,10 +74,20 @@ 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_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
@@ -91,21 +103,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -114,10 +129,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -126,6 +143,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -139,7 +157,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -155,18 +172,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -181,8 +191,11 @@ CONFIG_PPC_86xx=y
 # CONFIG_MPC8641_HPCN is not set
 # CONFIG_SBC8641D is not set
 # CONFIG_MPC8610_HPCD is not set
+# CONFIG_GEF_PPC9A is not set
+# CONFIG_GEF_SBC310 is not set
 CONFIG_GEF_SBC610=y
 CONFIG_MPC8641=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -244,9 +257,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -275,6 +291,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # 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=y
@@ -298,7 +315,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -378,9 +394,11 @@ CONFIG_BRIDGE_NETFILTER=y
 # CONFIG_NETFILTER_NETLINK_QUEUE is not set
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL 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
@@ -393,6 +411,7 @@ CONFIG_NETFILTER_XTABLES=m
 # 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=m
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
 # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
@@ -451,11 +470,11 @@ CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 # CONFIG_IP6_NF_MATCH_MH is not set
 CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 # CONFIG_IP6_NF_TARGET_REJECT is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
 # CONFIG_IP6_NF_SECURITY is not set
 # CONFIG_BRIDGE_NF_EBTABLES is not set
@@ -490,6 +509,7 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 CONFIG_WAN_ROUTER=m
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -540,7 +560,6 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -651,7 +670,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
@@ -682,13 +700,20 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -746,9 +771,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -771,6 +798,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -847,6 +875,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 # CONFIG_MACVLAN is not set
@@ -880,6 +909,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_ZMII is not set
@@ -899,6 +930,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
@@ -909,11 +941,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -923,7 +956,6 @@ CONFIG_GIANFAR=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
@@ -1050,6 +1082,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -1113,12 +1146,9 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 CONFIG_DS1682=y
-# 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
@@ -1174,6 +1204,7 @@ CONFIG_HWMON=y
 # 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
@@ -1188,11 +1219,15 @@ CONFIG_HWMON=y
 CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_LM92=y
 # 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1311,15 +1346,17 @@ 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_DRAGONRISE_FF 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
@@ -1389,11 +1426,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1435,7 +1472,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
@@ -1452,6 +1488,7 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1513,8 +1550,9 @@ CONFIG_RTC_DRV_RX8581=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1527,6 +1565,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
@@ -1549,6 +1588,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
@@ -1595,6 +1639,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1607,7 +1652,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1668,6 +1712,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1681,13 +1726,14 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=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
 
 #
 # Kernel hacking
@@ -1705,6 +1751,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
@@ -1733,9 +1782,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1744,17 +1796,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1776,6 +1830,7 @@ CONFIG_SECURITY_NETWORK=y
 # 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
 
 #
@@ -1791,10 +1846,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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
@@ -1864,6 +1921,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:24 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:28 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_ALTIVEC=y
@@ -55,6 +56,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -72,6 +74,15 @@ CONFIG_SYSVIPC_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
@@ -87,21 +98,24 @@ 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 is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# 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=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -111,10 +125,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -122,6 +138,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -134,7 +151,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -150,18 +166,11 @@ 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_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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -176,9 +185,13 @@ CONFIG_PPC_86xx=y
 # CONFIG_MPC8641_HPCN is not set
 # CONFIG_SBC8641D is not set
 CONFIG_MPC8610_HPCD=y
+# CONFIG_GEF_PPC9A is not set
+# CONFIG_GEF_SBC310 is not set
 # CONFIG_GEF_SBC610 is not set
 CONFIG_MPC8610=y
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -238,9 +251,12 @@ 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_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=12
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -269,6 +285,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # 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
@@ -291,7 +308,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -364,6 +380,7 @@ 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_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -376,7 +393,6 @@ 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
@@ -492,7 +508,6 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -521,13 +536,20 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -632,9 +654,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -657,6 +681,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -733,6 +758,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -747,6 +773,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=y
 # CONFIG_DE2104X is not set
 # CONFIG_TULIP is not set
@@ -774,7 +802,6 @@ CONFIG_ULI526X=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
@@ -929,12 +956,9 @@ CONFIG_I2C_MPC=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
@@ -1049,6 +1073,7 @@ CONFIG_FB_FSL_DIU=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
 
 #
@@ -1069,6 +1094,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
@@ -1116,6 +1142,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1165,7 +1193,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1179,7 +1206,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
 
@@ -1247,8 +1274,9 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1259,6 +1287,7 @@ 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
@@ -1280,6 +1309,11 @@ CONFIG_FILE_LOCKING=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1323,6 +1357,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1337,7 +1372,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1409,6 +1443,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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
@@ -1422,11 +1457,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1444,6 +1481,9 @@ 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
@@ -1474,9 +1514,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1484,17 +1527,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1589,6 +1634,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:25 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:28 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_ALTIVEC=y
@@ -56,6 +57,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -70,11 +72,21 @@ 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=y
 # CONFIG_AUDITSYSCALL 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
@@ -90,22 +102,24 @@ 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_STRIP_ASM_SYMS is not set
 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
@@ -115,10 +129,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -127,6 +143,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -140,7 +157,6 @@ CONFIG_MODVERSIONS=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -156,18 +172,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -182,8 +191,11 @@ CONFIG_PPC_86xx=y
 CONFIG_MPC8641_HPCN=y
 # CONFIG_SBC8641D is not set
 # CONFIG_MPC8610_HPCD is not set
+# CONFIG_GEF_PPC9A is not set
+# CONFIG_GEF_SBC310 is not set
 # CONFIG_GEF_SBC610 is not set
 CONFIG_MPC8641=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -245,9 +257,12 @@ 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_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
@@ -274,6 +289,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=y
@@ -297,7 +313,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -385,6 +400,7 @@ CONFIG_SCTP_HMAC_MD5=y
 # 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
 
@@ -397,7 +413,6 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -451,13 +466,20 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -516,9 +538,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -541,6 +565,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -617,6 +642,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -650,6 +676,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_ZMII is not set
@@ -669,6 +697,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
@@ -679,11 +708,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -693,6 +723,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
@@ -702,6 +733,7 @@ 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
 
 #
@@ -709,7 +741,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -875,12 +906,9 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
@@ -933,7 +961,7 @@ CONFIG_VIDEO_MEDIA=m
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=m
 CONFIG_MEDIA_TUNER_TDA8290=m
 CONFIG_MEDIA_TUNER_TDA9887=m
@@ -942,6 +970,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
 CONFIG_MEDIA_TUNER_MT20XX=m
 CONFIG_MEDIA_TUNER_XC2028=m
 CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
 # CONFIG_DVB_DYNAMIC_MINORS is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
@@ -981,103 +1010,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
 # CONFIG_USB_DABUSB is not set
 
@@ -1157,6 +1090,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1211,15 +1146,17 @@ 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_DRAGONRISE_FF 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
@@ -1292,11 +1229,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1338,7 +1275,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
@@ -1354,6 +1290,7 @@ CONFIG_USB_STORAGE=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
@@ -1415,8 +1352,9 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1427,6 +1365,7 @@ 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
@@ -1450,6 +1389,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
@@ -1504,6 +1448,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1519,7 +1464,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1590,6 +1534,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1604,11 +1549,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 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
 
 #
 # Kernel hacking
@@ -1626,6 +1572,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
@@ -1656,9 +1605,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1666,17 +1618,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1707,10 +1661,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
@@ -1779,6 +1735,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.29-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/86xx/sbc8641d_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:36:23 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:27 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_ALTIVEC=y
@@ -57,6 +58,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -71,10 +73,20 @@ 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_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
@@ -90,21 +102,24 @@ 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 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -113,10 +128,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -125,6 +142,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -138,7 +156,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -154,18 +171,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -180,8 +190,11 @@ CONFIG_PPC_86xx=y
 # CONFIG_MPC8641_HPCN is not set
 CONFIG_SBC8641D=y
 # CONFIG_MPC8610_HPCD is not set
+# CONFIG_GEF_PPC9A is not set
+# CONFIG_GEF_SBC310 is not set
 # CONFIG_GEF_SBC610 is not set
 CONFIG_MPC8641=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -243,9 +256,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -274,6 +290,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
@@ -296,7 +313,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -376,9 +392,11 @@ CONFIG_BRIDGE_NETFILTER=y
 # CONFIG_NETFILTER_NETLINK_QUEUE is not set
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL 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
@@ -391,6 +409,7 @@ CONFIG_NETFILTER_XTABLES=m
 # 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=m
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
 # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
@@ -449,11 +468,11 @@ CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 # CONFIG_IP6_NF_MATCH_MH is not set
 CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 # CONFIG_IP6_NF_TARGET_REJECT is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
 # CONFIG_IP6_NF_SECURITY is not set
 # CONFIG_BRIDGE_NF_EBTABLES is not set
@@ -488,6 +507,7 @@ CONFIG_LLC=m
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 CONFIG_WAN_ROUTER=m
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -538,7 +558,6 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -649,7 +668,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
@@ -678,13 +696,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -729,6 +754,7 @@ CONFIG_DM_ZERO=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 # CONFIG_MACVLAN is not set
@@ -762,6 +788,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_ZMII is not set
@@ -781,6 +809,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
@@ -791,11 +820,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -805,7 +835,6 @@ CONFIG_GIANFAR=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
@@ -923,6 +952,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -985,12 +1015,9 @@ CONFIG_I2C_MPC=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
@@ -1022,6 +1049,7 @@ CONFIG_HWMON=y
 # 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
@@ -1036,11 +1064,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1145,7 +1176,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1159,7 +1189,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
 
@@ -1175,6 +1205,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1187,6 +1218,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
@@ -1228,6 +1260,11 @@ 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
@@ -1269,8 +1306,13 @@ CONFIG_MINIX_FS=m
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_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_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1283,7 +1325,6 @@ CONFIG_LOCKD_V4=y
 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=m
@@ -1346,6 +1387,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1359,13 +1401,14 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=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
 
 #
 # Kernel hacking
@@ -1383,6 +1426,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
@@ -1411,9 +1457,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1422,17 +1471,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1454,6 +1506,7 @@ CONFIG_SECURITY_NETWORK=y
 # 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
 
 #
@@ -1469,10 +1522,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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
@@ -1542,6 +1597,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/adder875_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/adder875_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/adder875_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/adder875_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:24 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:50 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -53,6 +53,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_REDBOOT=y
 # 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"
 
 #
@@ -70,6 +71,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -85,19 +95,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 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 is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -106,10 +116,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -117,13 +129,13 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -139,11 +151,6 @@ 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_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_FREEZER is not set
 
 #
@@ -233,9 +240,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -270,14 +280,11 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0x80000000
-CONFIG_CONSISTENT_START=0xfd000000
-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
@@ -328,6 +335,7 @@ 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
 
@@ -340,7 +348,6 @@ 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
@@ -439,7 +446,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 +469,7 @@ CONFIG_HAVE_IDE=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
@@ -491,6 +498,8 @@ CONFIG_DAVICOM_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -511,7 +520,6 @@ CONFIG_FS_ENET_MDIO_FEC=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
@@ -558,7 +566,6 @@ 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_TOUCHKIT is not set
@@ -606,6 +613,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -675,6 +683,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=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
 # CONFIG_STAGING is not set
 
@@ -699,6 +708,11 @@ CONFIG_FILE_LOCKING=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -742,6 +756,7 @@ 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
@@ -753,7 +768,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
@@ -785,6 +799,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -802,6 +817,7 @@ CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -819,6 +835,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
@@ -845,9 +864,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -855,17 +877,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/amigaone_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/amigaone_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/amigaone_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/amigaone_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1636 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Sun Feb  1 14:22:42 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=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_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_CHECK_CACHE_COHERENCY=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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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
+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=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# 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_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=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=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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+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_PCSPKR_PLATFORM=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
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=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_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=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=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_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_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# 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 is not set
+CONFIG_AMIGAONE=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# 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=y
+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_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_IOMMU_HELPER 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_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+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_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_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=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS 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_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+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
+# 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 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=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=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=m
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_STATE 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_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 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_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_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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# 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 is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_SERIAL is not set
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+# CONFIG_PARPORT_1284 is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=y
+# CONFIG_PARIDE is not set
+# 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=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_PHANTOM 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=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=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# 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 is not set
+# 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=y
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# 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=y
+# 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 is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# 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_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 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_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_MMIO 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
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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_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=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON 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=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH 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=y
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# 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_VIA_RHINE is not set
+# CONFIG_SC92031 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
+
+#
+# Wireless LAN
+#
+# 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
+#
+# 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_PLIP 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_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# 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_SUNKBD is not set
+# 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_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_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_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=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=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# 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=y
+# 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=y
+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_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+# 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_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_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=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_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT is not set
+# 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_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
+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
+
+#
+# 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_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_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
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_DDC=y
+# 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=y
+CONFIG_FB_BACKLIGHT=y
+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_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 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=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG 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_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+CONFIG_FB_3DFX=y
+# CONFIG_FB_3DFX_ACCEL 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_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=m
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK 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 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 is not set
+
+#
+# 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_NTRIG=y
+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_TOPSEED=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF 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_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_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# 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=y
+# 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 information
+#
+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_USS720 is not set
+# 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_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 is not set
+
+#
+# OTG and related infrastructure
+#
+# 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_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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# 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_PPC 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 is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+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
+CONFIG_JBD=y
+CONFIG_JBD2=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_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_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
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS 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_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=m
+# 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 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
+# 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 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=y
+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
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+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_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# 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_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_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=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM 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_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=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+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
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_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=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_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# 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=m
+# 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
+
+#
+# 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=m
+# 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=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_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.29-gnu1/arch/powerpc/configs/c2k_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/c2k_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/c2k_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/c2k_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:26 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:51 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -56,6 +57,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -70,12 +72,22 @@ 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=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# 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=y
@@ -92,23 +104,27 @@ CONFIG_NAMESPACES=y
 # 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_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -118,6 +134,7 @@ CONFIG_AIO=y
 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
@@ -133,6 +150,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -145,7 +163,6 @@ CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -161,18 +178,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -192,6 +202,8 @@ CONFIG_EMBEDDED6xx=y
 # CONFIG_PPC_PRPMC2800 is not set
 CONFIG_PPC_C2K=y
 CONFIG_MV64X60=y
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -268,9 +280,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -295,6 +310,7 @@ CONFIG_PCI_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=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -315,15 +331,11 @@ 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_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -364,7 +376,7 @@ 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=m
+CONFIG_INET_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -403,9 +415,11 @@ CONFIG_BRIDGE_NETFILTER=y
 # CONFIG_NETFILTER_NETLINK_QUEUE is not set
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL 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
@@ -419,6 +433,7 @@ CONFIG_NETFILTER_XTABLES=m
 # 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=m
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
 # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
@@ -508,11 +523,11 @@ CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 # CONFIG_IP6_NF_MATCH_MH is not set
 CONFIG_IP6_NF_MATCH_RT=m
+# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 # CONFIG_IP6_NF_TARGET_REJECT is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
 # CONFIG_IP6_NF_SECURITY is not set
 CONFIG_BRIDGE_NF_EBTABLES=m
@@ -544,6 +559,7 @@ 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=m
 CONFIG_ATM_CLIP=m
@@ -566,6 +582,7 @@ 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_NET_SCHED=y
 
 #
@@ -612,6 +629,7 @@ CONFIG_NET_SCH_FIFO=y
 #
 # 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
@@ -638,7 +656,6 @@ CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBFUSB=m
 CONFIG_BT_HCIVHCI=m
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -748,7 +765,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
@@ -846,9 +862,11 @@ CONFIG_MEGARAID_MM=m
 CONFIG_MEGARAID_MAILBOX=m
 # CONFIG_MEGARAID_LEGACY is not set
 CONFIG_MEGARAID_SAS=m
+# 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
@@ -875,6 +893,7 @@ CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -891,6 +910,7 @@ CONFIG_SCSI_LPFC=m
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 # CONFIG_MACVLAN is not set
@@ -924,6 +944,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_ZMII is not set
@@ -943,6 +965,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
@@ -957,6 +980,7 @@ 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
@@ -966,7 +990,6 @@ CONFIG_MV643XX_ETH=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
@@ -1084,6 +1107,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_NVRAM=m
 CONFIG_GEN_RTC=m
 # CONFIG_GEN_RTC_X is not set
@@ -1150,12 +1174,9 @@ CONFIG_I2C_MV64XXX=m
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=m
 CONFIG_SENSORS_PCF8574=m
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-CONFIG_SENSORS_PCF8591=m
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -1187,6 +1208,7 @@ CONFIG_SENSORS_DS1621=m
 # 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=m
 # CONFIG_SENSORS_GL520SM is not set
 CONFIG_SENSORS_IT87=m
@@ -1201,11 +1223,14 @@ CONFIG_SENSORS_LM87=m
 CONFIG_SENSORS_LM90=m
 # 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_MAX1619=m
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+CONFIG_SENSORS_PCF8591=m
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 CONFIG_SENSORS_SMSC47M1=m
@@ -1363,21 +1388,21 @@ CONFIG_USB_PRINTER=m
 # 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=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
 # CONFIG_USB_STORAGE_USBAT is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
@@ -1402,7 +1427,7 @@ CONFIG_USB_SERIAL_BELKIN=m
 # CONFIG_USB_SERIAL_CH341 is not set
 CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1438,12 +1463,14 @@ CONFIG_USB_SERIAL_MCT_U232=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # 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=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
 # 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=m
 CONFIG_USB_SERIAL_XIRCOM=m
@@ -1466,7 +1493,6 @@ CONFIG_USB_LCD=m
 CONFIG_USB_LED=m
 # 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
@@ -1487,6 +1513,7 @@ CONFIG_USB_SPEEDTOUCH=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
@@ -1516,6 +1543,7 @@ CONFIG_DMADEVICES=y
 #
 # DMA Devices
 #
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1524,6 +1552,7 @@ CONFIG_DMADEVICES=y
 #
 # CONFIG_EXT2_FS 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=y
 CONFIG_EXT3_FS_SECURITY=y
@@ -1554,6 +1583,11 @@ 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
@@ -1612,6 +1646,7 @@ CONFIG_VXFS_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
@@ -1626,7 +1661,6 @@ CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_SUNRPC_XPRT_RDMA=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
@@ -1637,6 +1671,7 @@ CONFIG_CIFS=m
 CONFIG_CIFS_XATTR=y
 CONFIG_CIFS_POSIX=y
 # CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_DFS_UPCALL is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1704,6 +1739,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
@@ -1719,12 +1755,15 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=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_CHECK_SIGNATURE=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1742,6 +1781,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
@@ -1775,12 +1817,15 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 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_RING_BUFFER=y
 CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1788,18 +1833,21 @@ CONFIG_TRACING=y
 # 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_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG 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_PRINT_STACK_DEPTH=64
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
-# 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
@@ -1830,6 +1878,7 @@ CONFIG_SECURITY_SELINUX_DEVELOP=y
 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_CRYPTO=y
 
 #
@@ -1845,10 +1894,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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1918,6 +1969,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/ep8248e_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/ep8248e_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/ep8248e_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/ep8248e_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:27 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:52 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -55,6 +56,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -71,6 +73,15 @@ CONFIG_SYSVIPC_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
@@ -82,20 +93,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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
@@ -104,10 +114,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -115,6 +127,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -122,7 +135,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -137,18 +149,11 @@ 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_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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -167,6 +172,8 @@ CONFIG_8272=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -222,9 +229,12 @@ 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_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
@@ -250,6 +260,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,7 +283,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -353,6 +363,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -364,7 +375,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
@@ -468,7 +478,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
@@ -517,6 +526,7 @@ CONFIG_HAVE_IDE=y
 # 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_EQUALIZER is not set
@@ -550,6 +560,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_ZMII is not set
@@ -572,6 +584,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_R8169 is not set
@@ -581,8 +594,8 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
-# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_JME is not set
@@ -594,6 +607,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
@@ -603,6 +617,7 @@ 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
 
 #
@@ -610,7 +625,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -662,6 +676,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -751,8 +766,10 @@ CONFIG_DAB=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
+# 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
 # CONFIG_STAGING is not set
 
@@ -763,6 +780,7 @@ 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
@@ -781,6 +799,10 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -894,6 +916,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -907,11 +930,11 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -927,6 +950,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 # CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -955,9 +979,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -965,16 +992,18 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=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
@@ -1005,9 +1034,11 @@ 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_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -1071,6 +1102,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.29-gnu1/arch/powerpc/configs/ep88xc_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/ep88xc_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/ep88xc_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/ep88xc_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:28 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:53 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -52,6 +52,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -69,6 +70,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,19 +94,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 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 is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -105,10 +115,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -116,13 +128,13 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -138,11 +150,6 @@ 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_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_FREEZER is not set
 
 #
@@ -233,9 +240,12 @@ 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_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
@@ -270,14 +280,11 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0x80000000
-CONFIG_CONSISTENT_START=0xfd000000
-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
@@ -328,6 +335,7 @@ 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
 
@@ -340,7 +348,6 @@ 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
@@ -439,7 +446,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 +469,7 @@ CONFIG_HAVE_IDE=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
@@ -491,6 +498,8 @@ CONFIG_LXT_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -511,7 +520,6 @@ CONFIG_FS_ENET_MDIO_FEC=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
@@ -562,6 +570,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -631,6 +640,7 @@ CONFIG_DAB=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
 # CONFIG_STAGING is not set
 
@@ -655,6 +665,11 @@ CONFIG_FILE_LOCKING=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -698,6 +713,7 @@ 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
@@ -709,7 +725,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
@@ -741,6 +756,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -758,6 +774,7 @@ CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -775,6 +792,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
@@ -801,9 +821,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -811,17 +834,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/linkstation_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/linkstation_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/linkstation_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/linkstation_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc6
-# Fri Mar  6 00:07:38 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:54 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -68,6 +70,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
@@ -100,21 +103,24 @@ CONFIG_NAMESPACES=y
 # 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_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_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
@@ -124,10 +130,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=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 is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -135,6 +143,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -147,7 +156,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -168,8 +176,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -191,6 +197,8 @@ CONFIG_LINKSTATION=y
 CONFIG_MPC10X_BRIDGE=y
 CONFIG_MPC10X_OPENPIC=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -250,9 +258,12 @@ 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_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
@@ -277,6 +288,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
@@ -299,7 +311,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -371,6 +382,7 @@ CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # 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_MARK is not set
 # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 # CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
@@ -379,6 +391,7 @@ CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_TRACE is not set
 # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
 # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
 # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
 # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
 # CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
@@ -389,6 +402,7 @@ CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_MATCH_ESP is not set
 # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 # CONFIG_NETFILTER_XT_MATCH_HELPER 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
@@ -465,6 +479,7 @@ CONFIG_IP_NF_ARP_MANGLE=m
 # 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
 
@@ -477,7 +492,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
 # 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
@@ -625,6 +639,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -690,9 +705,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -715,6 +732,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -791,6 +809,7 @@ CONFIG_PATA_SIL680=y
 # 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
@@ -805,6 +824,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=y
 # CONFIG_DE2104X is not set
 CONFIG_TULIP=y
@@ -833,6 +854,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
@@ -843,8 +865,8 @@ CONFIG_R8169=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
-# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -858,6 +880,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
@@ -867,6 +890,7 @@ 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
 
 #
@@ -874,7 +898,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -985,6 +1008,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -1050,7 +1074,6 @@ CONFIG_I2C_MPC=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
@@ -1082,6 +1105,7 @@ CONFIG_HWMON=y
 # 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
@@ -1096,11 +1120,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1195,7 +1222,6 @@ CONFIG_HID=m
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1250,11 +1276,11 @@ CONFIG_USB_PRINTER=m
 # 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
@@ -1290,7 +1316,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
 # 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_CP2101 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
@@ -1314,11 +1340,13 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # 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
@@ -1341,7 +1369,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
@@ -1357,6 +1384,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=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
@@ -1418,8 +1446,9 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1430,6 +1459,7 @@ 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
@@ -1456,6 +1486,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
@@ -1507,6 +1542,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1524,7 +1560,6 @@ CONFIG_NFS_ACL_SUPPORT=y
 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
@@ -1584,6 +1619,7 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1597,15 +1633,18 @@ CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1623,6 +1662,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
@@ -1652,9 +1694,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1662,17 +1707,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1703,10 +1750,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
@@ -1776,6 +1825,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/mgcoge_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mgcoge_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mgcoge_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mgcoge_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:30 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:55 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -57,6 +58,7 @@ CONFIG_HIBERNATE_32=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -73,6 +75,15 @@ CONFIG_SYSVIPC_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
@@ -83,23 +94,25 @@ 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=y
 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_PCSPKR_PLATFORM=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
@@ -108,10 +121,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -119,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -126,7 +142,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -141,18 +156,11 @@ 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_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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 CONFIG_PPC_CHRP=y
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -171,7 +179,9 @@ CONFIG_8272=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
 CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_UDBG_RTAS_CONSOLE is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
@@ -231,9 +241,12 @@ 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_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
@@ -260,6 +273,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,7 +296,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -344,6 +357,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -355,7 +369,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
@@ -464,7 +477,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
@@ -517,6 +529,7 @@ CONFIG_HAVE_IDE=y
 # 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_EQUALIZER is not set
@@ -551,6 +564,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_ZMII is not set
@@ -576,7 +591,6 @@ CONFIG_FS_ENET_HAS_SCC=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
@@ -631,6 +645,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_RTAS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -720,8 +735,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
+# 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
 # CONFIG_STAGING is not set
 
@@ -732,6 +749,7 @@ 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
@@ -751,6 +769,10 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -872,6 +894,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -887,11 +910,12 @@ 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
 
 #
 # Kernel hacking
@@ -907,6 +931,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 # CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -935,9 +960,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -945,16 +973,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=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
@@ -986,9 +1017,11 @@ 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_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -1052,6 +1085,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.29-gnu1/arch/powerpc/configs/mgsuvd_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mgsuvd_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mgsuvd_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:32 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:55 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -51,6 +51,7 @@ CONFIG_AUDIT_ARCH=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"
 
 #
@@ -68,6 +69,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_GROUP_SCHED=y
@@ -82,20 +92,23 @@ 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 is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -103,10 +116,12 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 # 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -114,6 +129,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -121,7 +137,6 @@ CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -137,11 +152,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -232,9 +242,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -268,14 +281,11 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0x80000000
-CONFIG_CONSISTENT_START=0xfd000000
-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
@@ -331,6 +341,7 @@ 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
 
@@ -343,7 +354,6 @@ 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
@@ -447,7 +457,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
@@ -483,6 +492,7 @@ CONFIG_HAVE_IDE=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
@@ -511,6 +521,8 @@ CONFIG_FIXED_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -531,7 +543,6 @@ CONFIG_FS_ENET_HAS_SCC=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
@@ -582,6 +593,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -651,6 +663,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -663,6 +676,7 @@ CONFIG_EXT2_FS_XATTR=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 is not set
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -686,6 +700,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
@@ -739,6 +758,7 @@ 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
@@ -750,7 +770,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
@@ -782,6 +801,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -797,11 +817,12 @@ 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
 
 #
 # Kernel hacking
@@ -819,13 +840,25 @@ CONFIG_DEBUG_FS=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -917,6 +950,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/mpc5200_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc5200_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc5200_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc5200_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:40:44 2009
+# Linux kernel version: 2.6.30-rc2
+# Mon Apr 20 11:06:25 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -39,6 +40,7 @@ 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
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
@@ -55,6 +57,7 @@ CONFIG_DEFAULT_UIMAGE=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -91,19 +94,22 @@ 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 is not set
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -113,10 +119,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -124,6 +132,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -136,7 +145,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -157,8 +165,6 @@ CONFIG_FREEZER=y
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -166,8 +172,9 @@ CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 CONFIG_PPC_EFIKA=y
 CONFIG_PPC_LITE5200=y
+CONFIG_PPC_MEDIA5200=y
 CONFIG_PPC_MPC5200_BUGFIX=y
-# CONFIG_PPC_MPC5200_GPIO is not set
+CONFIG_PPC_MPC5200_GPIO=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
@@ -176,7 +183,9 @@ CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
 CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_UDBG_RTAS_CONSOLE is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -241,9 +250,12 @@ 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_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
@@ -272,6 +284,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 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
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -294,7 +307,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -350,6 +362,7 @@ 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
 
@@ -362,7 +375,6 @@ 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
@@ -390,7 +402,7 @@ 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
+CONFIG_MTD_OF_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
 
 #
@@ -444,6 +456,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
+# 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
@@ -462,14 +476,23 @@ 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
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=m
+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_OF_DEVICE=y
+CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
+CONFIG_OF_SPI=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -497,12 +520,14 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
 # EEPROM support
 #
-# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
@@ -561,9 +586,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -586,6 +613,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -663,6 +691,7 @@ CONFIG_PATA_PLATFORM=y
 # 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
@@ -678,7 +707,7 @@ CONFIG_PHYLIB=y
 # 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_LXT_PHY=y
 # CONFIG_CICADA_PHY is not set
 # CONFIG_VITESSE_PHY is not set
 # CONFIG_SMSC_PHY is not set
@@ -696,6 +725,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ENC28J60 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
@@ -719,7 +751,6 @@ CONFIG_FEC_MPC52xx_MDIO=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
@@ -799,6 +830,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -815,8 +847,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -853,6 +883,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_GPIO is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -882,22 +913,63 @@ CONFIG_I2C_MPC=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
 # 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 is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_MPC52xx_PSC=m
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-# CONFIG_GPIOLIB 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:
+#
+# 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:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# 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
@@ -914,10 +986,12 @@ CONFIG_HWMON=y
 # 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
@@ -928,11 +1002,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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -951,6 +1030,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_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -988,6 +1068,7 @@ 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_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
@@ -1083,9 +1164,13 @@ 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=m
+# 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=y
 CONFIG_BACKLIGHT_GENERIC=y
@@ -1126,15 +1211,17 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 # CONFIG_HID_APPLE is not set
 CONFIG_HID_BELKIN=y
 CONFIG_HID_CHERRY=y
 # CONFIG_HID_CHICONY is not set
 CONFIG_HID_CYPRESS=y
+# CONFIG_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
+# 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
@@ -1203,11 +1290,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1249,7 +1336,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
@@ -1264,6 +1350,8 @@ CONFIG_USB_STORAGE=y
 #
 # 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
@@ -1281,8 +1369,70 @@ CONFIG_NEW_LEDS=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC 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
+
+#
+# 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
+
+#
+# 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_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 is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1293,6 +1443,7 @@ 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
@@ -1315,6 +1466,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
@@ -1361,6 +1517,12 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=m
+# 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
@@ -1371,6 +1533,7 @@ 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
@@ -1383,7 +1546,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1438,6 +1600,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
@@ -1445,7 +1608,7 @@ CONFIG_NLS_ISO8859_1=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=m
 # CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
@@ -1453,11 +1616,14 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1475,6 +1641,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
@@ -1503,9 +1672,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1513,17 +1685,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1554,10 +1728,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
@@ -1625,8 +1801,9 @@ CONFIG_CRYPTO_DES=y
 #
 # Compression
 #
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=m
 
 #
 # Random Number Generation
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc7448_hpc2_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:33 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:56 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -71,6 +73,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -85,20 +96,23 @@ 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_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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -108,16 +122,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -125,7 +142,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -141,18 +157,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -172,6 +181,8 @@ CONFIG_MPC7448HPC2=y
 # CONFIG_PPC_PRPMC2800 is not set
 # CONFIG_PPC_C2K is not set
 CONFIG_TSI108_BRIDGE=y
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 CONFIG_MPIC_WEIRD=y
@@ -230,9 +241,12 @@ 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_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 +269,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
@@ -277,7 +292,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -333,6 +347,7 @@ 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
 
@@ -345,7 +360,6 @@ 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
@@ -392,12 +406,16 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -454,9 +472,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -479,6 +499,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -554,6 +575,7 @@ CONFIG_SATA_MV=y
 # 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
@@ -587,6 +609,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_ZMII is not set
@@ -628,6 +652,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
@@ -639,10 +664,10 @@ CONFIG_NETDEV_1000=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_TSI108_ETH=y
-# CONFIG_MV643XX_ETH 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
@@ -652,6 +677,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
@@ -661,6 +687,7 @@ 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
 
 #
@@ -668,7 +695,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -839,7 +865,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -853,7 +878,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
 
@@ -869,6 +894,7 @@ 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
 # CONFIG_STAGING is not set
 
@@ -879,6 +905,7 @@ 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
@@ -902,6 +929,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
@@ -944,6 +976,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -953,7 +986,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -985,6 +1017,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -998,11 +1031,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1024,13 +1059,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1122,6 +1168,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc8272_ads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:35 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:57 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -55,6 +56,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -71,6 +73,15 @@ CONFIG_SYSVIPC_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
@@ -82,20 +93,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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
@@ -105,10 +115,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -116,6 +128,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -123,7 +136,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -138,18 +150,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -169,6 +174,8 @@ CONFIG_PQ2_ADS_PCI_PIC=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -225,9 +232,12 @@ 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_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
@@ -253,6 +263,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,7 +286,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -356,6 +366,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -367,7 +378,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
@@ -472,7 +482,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
@@ -521,6 +530,7 @@ CONFIG_HAVE_IDE=y
 # 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_EQUALIZER is not set
@@ -554,6 +564,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_ZMII is not set
@@ -576,6 +588,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_R8169 is not set
@@ -585,8 +598,8 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
-# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_JME is not set
@@ -598,6 +611,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
@@ -607,6 +621,7 @@ 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
 
 #
@@ -614,7 +629,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -668,7 +682,6 @@ 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_TOUCHKIT is not set
@@ -719,6 +732,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -809,8 +823,10 @@ CONFIG_DAB=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
+# 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
 # CONFIG_STAGING is not set
 
@@ -821,6 +837,7 @@ 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
@@ -842,6 +859,10 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -956,6 +977,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -971,11 +993,11 @@ 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
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -993,6 +1015,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
@@ -1022,9 +1047,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1032,16 +1060,18 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=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
@@ -1072,9 +1102,11 @@ 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_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -1138,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.29-gnu1/arch/powerpc/configs/mpc83xx_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc83xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc83xx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:36 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:21:58 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_FSL_EMB_PERFMON is not set
 # CONFIG_ALTIVEC is not set
@@ -58,6 +59,7 @@ CONFIG_REDBOOT=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -75,6 +77,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -89,20 +100,23 @@ 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_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_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -111,10 +125,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -122,6 +138,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -134,7 +151,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -150,18 +166,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -189,6 +198,8 @@ CONFIG_PPC_MPC834x=y
 CONFIG_PPC_MPC837x=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 CONFIG_IPIC=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -251,9 +262,12 @@ 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_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
@@ -281,6 +295,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
@@ -303,7 +318,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -359,6 +373,7 @@ 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
 
@@ -371,7 +386,6 @@ 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
@@ -485,7 +499,6 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -516,13 +529,20 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -580,9 +600,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -605,6 +627,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -681,6 +704,7 @@ CONFIG_ATA_SFF=y
 # 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
@@ -714,6 +738,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_ZMII is not set
@@ -733,6 +759,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
@@ -743,14 +770,15 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
 CONFIG_UCC_GETH=y
 # CONFIG_UGETH_MAGIC_PACKET is not set
 # CONFIG_UGETH_TX_ON_DEMAND is not set
-# CONFIG_MV643XX_ETH 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
@@ -760,6 +788,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
@@ -769,6 +798,7 @@ 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
 
 #
@@ -776,7 +806,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -867,6 +896,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -932,12 +962,9 @@ CONFIG_I2C_MPC=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
@@ -992,6 +1019,7 @@ CONFIG_HWMON=y
 # 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
@@ -1006,11 +1034,15 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1121,15 +1153,17 @@ 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_DRAGONRISE_FF 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
@@ -1181,6 +1215,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_OHCI_HCD is not set
 # CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_FHCI_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
@@ -1195,11 +1230,11 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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 is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -1229,7 +1264,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
@@ -1245,6 +1279,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # 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
@@ -1254,6 +1289,7 @@ CONFIG_USB_EHCI_HCD_PPC_OF=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
 # CONFIG_STAGING is not set
 
@@ -1264,6 +1300,7 @@ 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
@@ -1286,6 +1323,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
@@ -1329,6 +1371,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1341,7 +1384,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1375,6 +1417,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_DLM is not set
 CONFIG_UCC_FAST=y
 CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1388,11 +1431,13 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 
 #
 # Kernel hacking
@@ -1412,13 +1457,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1448,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=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1520,6 +1578,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.29-gnu1/arch/powerpc/configs/mpc85xx_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc85xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc85xx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:37 2009
+# Linux kernel version: 2.6.30-rc2
+# Tue Apr 21 15:40:23 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -22,6 +22,7 @@ CONFIG_FSL_EMB_PERFMON=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_BOOK3E_MMU=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
@@ -59,6 +60,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -73,11 +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=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 CONFIG_AUDIT=y
 # CONFIG_AUDITSYSCALL 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
@@ -93,22 +105,24 @@ 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_STRIP_ASM_SYMS is not set
 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
@@ -118,10 +132,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -130,6 +146,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -142,7 +159,6 @@ CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -158,11 +174,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -178,8 +189,9 @@ CONFIG_MPC85xx_CDS=y
 CONFIG_MPC85xx_MDS=y
 CONFIG_MPC8536_DS=y
 CONFIG_MPC85xx_DS=y
+CONFIG_SOCRATES=y
 CONFIG_KSI8560=y
-# CONFIG_STX_GP3 is not set
+CONFIG_STX_GP3=y
 CONFIG_TQM8540=y
 CONFIG_TQM8541=y
 CONFIG_TQM8548=y
@@ -200,11 +212,11 @@ CONFIG_PPC_I8259=y
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
 CONFIG_QUICC_ENGINE=y
-# CONFIG_QE_GPIO is not set
+CONFIG_QE_GPIO=y
 CONFIG_CPM2=y
 CONFIG_FSL_ULI1575=y
 CONFIG_CPM=y
-# CONFIG_MPC8xxx_GPIO is not set
+CONFIG_MPC8xxx_GPIO=y
 # CONFIG_SIMPLE_GPIO is not set
 
 #
@@ -249,9 +261,12 @@ 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_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
@@ -278,6 +293,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
@@ -291,17 +307,17 @@ 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_PHYSICAL_ALIGN=0x10000000
+CONFIG_PHYSICAL_ALIGN=0x04000000
 CONFIG_TASK_SIZE=0xc0000000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -389,6 +405,7 @@ CONFIG_SCTP_HMAC_MD5=y
 # 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
 
@@ -401,7 +418,6 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -456,13 +472,20 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -521,9 +544,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -546,6 +571,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -622,6 +648,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -634,11 +661,11 @@ CONFIG_PHYLIB=y
 #
 # MII PHY device drivers
 #
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
 # CONFIG_QSEMI_PHY is not set
 # CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
+CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
@@ -647,7 +674,7 @@ CONFIG_VITESSE_PHY=y
 # 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_FIXED_PHY=y
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
@@ -655,6 +682,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_ZMII is not set
@@ -667,7 +696,10 @@ CONFIG_MII=y
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_ATL2 is not set
-# CONFIG_FS_ENET is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_HAS_SCC=y
+CONFIG_FS_ENET_HAS_FCC=y
+# CONFIG_FS_ENET_MDIO_FCC is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -675,6 +707,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
@@ -685,11 +718,15 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_UCC_GETH is not set
+CONFIG_UCC_GETH=y
+# CONFIG_UGETH_MAGIC_PACKET is not set
+# CONFIG_UGETH_TX_ON_DEMAND 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
@@ -699,6 +736,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
@@ -708,6 +746,7 @@ 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
 
 #
@@ -715,7 +754,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -813,14 +851,15 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_CPM is not set
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
-# CONFIG_SERIAL_QE is not set
+CONFIG_SERIAL_QE=m
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_NVRAM=y
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -857,7 +896,7 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_I2C_CPM is not set
+CONFIG_I2C_CPM=m
 # CONFIG_I2C_GPIO is not set
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
@@ -885,12 +924,9 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
@@ -969,7 +1005,7 @@ CONFIG_VIDEO_MEDIA=m
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=m
 CONFIG_MEDIA_TUNER_TDA8290=m
 CONFIG_MEDIA_TUNER_TDA9887=m
@@ -978,6 +1014,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
 CONFIG_MEDIA_TUNER_MT20XX=m
 CONFIG_MEDIA_TUNER_XC2028=m
 CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
 # CONFIG_DVB_DYNAMIC_MINORS is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
@@ -1017,103 +1054,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
 # CONFIG_USB_DABUSB is not set
 
@@ -1193,6 +1134,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1247,15 +1190,17 @@ 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_DRAGONRISE_FF 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
@@ -1314,6 +1259,7 @@ CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_FHCI_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
@@ -1329,11 +1275,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1375,7 +1321,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
@@ -1392,6 +1337,7 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1406,6 +1352,8 @@ CONFIG_EDAC=y
 # CONFIG_EDAC_DEBUG is not set
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_MPC85XX=y
+# CONFIG_EDAC_AMD8131 is not set
+# CONFIG_EDAC_AMD8111 is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HCTOSYS=y
@@ -1460,7 +1408,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # on-CPU RTC drivers
 #
-# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
 
 #
@@ -1473,7 +1421,9 @@ 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
 # CONFIG_STAGING is not set
 
@@ -1484,6 +1434,7 @@ 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
@@ -1508,6 +1459,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
@@ -1562,6 +1518,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1577,7 +1534,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1648,6 +1604,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+CONFIG_UCC_SLOW=y
+CONFIG_UCC_FAST=y
+CONFIG_UCC=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1662,11 +1622,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 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
 
 #
 # Kernel hacking
@@ -1684,6 +1645,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
@@ -1714,9 +1678,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1724,17 +1691,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1759,18 +1729,21 @@ CONFIG_CRYPTO=y
 # 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 is not set
+CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
 
 #
@@ -1837,6 +1810,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1845,7 +1819,7 @@ 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_TALITOS is not set
+CONFIG_CRYPTO_DEV_TALITOS=y
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
 # CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc85xx_smp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1829 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc2
+# Tue Apr 21 15:41:18 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_E500=y
+# CONFIG_PPC_E500MC is not set
+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
+CONFIG_PPC_BOOK3E_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=8
+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_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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
+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=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# 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"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=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=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=y
+# CONFIG_AUDITSYSCALL 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 is not set
+# 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=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_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_MARKERS is not set
+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_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
+# 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=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBD=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
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_MPC85xx=y
+CONFIG_MPC8540_ADS=y
+CONFIG_MPC8560_ADS=y
+CONFIG_MPC85xx_CDS=y
+CONFIG_MPC85xx_MDS=y
+CONFIG_MPC8536_DS=y
+CONFIG_MPC85xx_DS=y
+CONFIG_SOCRATES=y
+CONFIG_KSI8560=y
+CONFIG_STX_GP3=y
+CONFIG_TQM8540=y
+CONFIG_TQM8541=y
+CONFIG_TQM8548=y
+CONFIG_TQM8555=y
+CONFIG_TQM8560=y
+CONFIG_SBC8548=y
+# CONFIG_SBC8560 is not set
+CONFIG_TQM85xx=y
+# CONFIG_IPIC is not set
+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_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_QUICC_ENGINE=y
+CONFIG_QE_GPIO=y
+CONFIG_CPM2=y
+CONFIG_FSL_ULI1575=y
+CONFIG_CPM=y
+CONFIG_MPC8xxx_GPIO=y
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+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_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+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_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=y
+# 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_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=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS 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
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# 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_PHYSICAL_ALIGN=0x04000000
+CONFIG_TASK_SIZE=0xc0000000
+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 is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=m
+# 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=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+# 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=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_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 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=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 is not set
+# CONFIG_IP_DCCP 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_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_FIB_RULES=y
+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
+# 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 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_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=y
+# 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=131072
+# 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_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# 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=y
+# CONFIG_CHR_DEV_OSST is not set
+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=y
+# CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_LOGGING=y
+# 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_CXGB3_ISCSI 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 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
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# 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_IPR 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
+# 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=y
+# CONFIG_SATA_SIL24 is not set
+CONFIG_SATA_FSL=y
+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=y
+# 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
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# 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=y
+# 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=y
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_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
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_FIXED_PHY=y
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# 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_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_ATL2 is not set
+CONFIG_FS_ENET=y
+CONFIG_FS_ENET_HAS_SCC=y
+CONFIG_FS_ENET_HAS_FCC=y
+# CONFIG_FS_ENET_MDIO_FCC 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_FSL_PQ_MDIO=y
+CONFIG_GIANFAR=y
+CONFIG_UCC_GETH=y
+# CONFIG_UGETH_MAGIC_PACKET is not set
+# CONFIG_UGETH_TX_ON_DEMAND 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 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=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# 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=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# 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=y
+# 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=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+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_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_CPM is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_SERIAL_QE=m
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_NVRAM=y
+# 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_CHARDEV is not set
+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_CPM=m
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MPC=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_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
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# 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:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# 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_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_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=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMISE 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_MEDIA_TUNER_MC44S803=m
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+# CONFIG_TTPCI_EEPROM is not set
+# CONFIG_DVB_BUDGET_CORE is not set
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+# CONFIG_DVB_TTUSB_BUDGET is not set
+# CONFIG_DVB_TTUSB_DEC is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported BT878 Adapters
+#
+
+#
+# Supported Pluto2 Adapters
+#
+# CONFIG_DVB_PLUTO2 is not set
+
+#
+# Supported SDMC DM1105 Adapters
+#
+# CONFIG_DVB_DM1105 is not set
+
+#
+# Supported DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+# 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=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+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 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_AC97_CODEC=y
+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_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 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_CS5530 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=y
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 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_PPC=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+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 is not set
+
+#
+# Special HID drivers
+#
+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_DRAGONRISE_FF 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_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+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=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=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_FSL=y
+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_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_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_FHCI_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_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_MPC85XX=y
+# CONFIG_EDAC_AMD8131 is not set
+# CONFIG_EDAC_AMD8111 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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# 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 is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_FSL_DMA=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
+# 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 is not set
+# CONFIG_GFS2_FS 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 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=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW 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=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+CONFIG_VXFS_FS=m
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+# CONFIG_ROMFS_FS is not set
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG 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_ROOT_NFS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=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=y
+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 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=m
+# CONFIG_DLM is not set
+CONFIG_UCC_SLOW=y
+CONFIG_UCC_FAST=y
+CONFIG_UCC=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=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+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
+
+#
+# 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 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_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM 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_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=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
+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_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE 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=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_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=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# 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=m
+# 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_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_CRYPTO_DEV_TALITOS=y
+CONFIG_PPC_CLOCK=y
+CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc866_ads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc866_ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc866_ads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:38 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:00 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -51,6 +51,7 @@ CONFIG_AUDIT_ARCH=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"
 
 #
@@ -68,6 +69,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -83,18 +93,18 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -103,10 +113,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -114,6 +126,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -121,7 +134,6 @@ CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -137,11 +149,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -232,9 +239,12 @@ 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_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 is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -268,14 +278,11 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0x80000000
-CONFIG_CONSISTENT_START=0xfd000000
-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
@@ -331,6 +338,7 @@ 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
 
@@ -343,7 +351,6 @@ 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
@@ -379,9 +386,13 @@ CONFIG_BLK_DEV_LOOP=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -396,6 +407,7 @@ CONFIG_HAVE_IDE=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
@@ -424,6 +436,8 @@ CONFIG_FIXED_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -437,6 +451,7 @@ CONFIG_FS_ENET_HAS_SCC=y
 CONFIG_FS_ENET_HAS_FEC=y
 CONFIG_FS_ENET_MDIO_FEC=y
 CONFIG_NETDEV_1000=y
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
 CONFIG_NETDEV_10000=y
 
@@ -445,7 +460,6 @@ CONFIG_NETDEV_10000=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
@@ -492,7 +506,6 @@ 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_TOUCHKIT is not set
@@ -540,6 +553,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -622,7 +636,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -635,7 +648,7 @@ CONFIG_USB_SUPPORT=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
 
@@ -649,6 +662,7 @@ CONFIG_USB_SUPPORT=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
 # CONFIG_STAGING is not set
 
@@ -661,6 +675,7 @@ CONFIG_EXT2_FS_XATTR=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 is not set
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -683,6 +698,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
@@ -725,6 +745,7 @@ 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
@@ -736,7 +757,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
@@ -768,6 +788,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -782,11 +803,11 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -806,13 +827,24 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -903,6 +935,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/mpc86xx_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc86xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc86xx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:39 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:00 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_PHYS_64BIT is not set
 CONFIG_ALTIVEC=y
@@ -57,6 +58,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -71,11 +73,21 @@ 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=y
 # CONFIG_AUDITSYSCALL 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
@@ -91,22 +103,24 @@ 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_STRIP_ASM_SYMS is not set
 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
@@ -116,10 +130,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -128,6 +144,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -141,7 +158,6 @@ CONFIG_MODVERSIONS=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -157,18 +173,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -183,9 +192,12 @@ CONFIG_PPC_86xx=y
 CONFIG_MPC8641_HPCN=y
 CONFIG_SBC8641D=y
 CONFIG_MPC8610_HPCD=y
+# CONFIG_GEF_PPC9A is not set
+# CONFIG_GEF_SBC310 is not set
 CONFIG_GEF_SBC610=y
 CONFIG_MPC8641=y
 CONFIG_MPC8610=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -247,9 +259,12 @@ 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_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 +291,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=y
@@ -299,7 +315,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -387,6 +402,7 @@ CONFIG_SCTP_HMAC_MD5=y
 # 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
 
@@ -399,7 +415,6 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -454,13 +469,20 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -519,9 +541,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -544,6 +568,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -620,6 +645,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -653,6 +679,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_ZMII is not set
@@ -672,6 +700,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
@@ -682,11 +711,12 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+CONFIG_FSL_PQ_MDIO=y
 CONFIG_GIANFAR=y
-# CONFIG_MV643XX_ETH 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
@@ -696,6 +726,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
@@ -705,6 +736,7 @@ 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
 
 #
@@ -712,7 +744,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -879,12 +910,9 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=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
@@ -963,7 +991,7 @@ CONFIG_VIDEO_MEDIA=m
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=m
 CONFIG_MEDIA_TUNER_TDA8290=m
 CONFIG_MEDIA_TUNER_TDA9887=m
@@ -972,6 +1000,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
 CONFIG_MEDIA_TUNER_MT20XX=m
 CONFIG_MEDIA_TUNER_XC2028=m
 CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
 # CONFIG_DVB_DYNAMIC_MINORS is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
@@ -1011,103 +1040,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # 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 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_TDA8261 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TUNER_CX24113 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_LGDT3304 is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# ISDB-T (terrestrial) frontends
-#
-# CONFIG_DVB_S921 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
 # CONFIG_USB_DABUSB is not set
 
@@ -1187,6 +1120,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1241,15 +1176,17 @@ 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_DRAGONRISE_FF 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
@@ -1322,11 +1259,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1368,7 +1305,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
@@ -1385,6 +1321,7 @@ CONFIG_USB_STORAGE=y
 # 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
@@ -1446,8 +1383,9 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1458,6 +1396,7 @@ 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
@@ -1481,6 +1420,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
@@ -1535,6 +1479,7 @@ CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
 # CONFIG_UFS_DEBUG is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1550,7 +1495,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1621,6 +1565,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1635,11 +1580,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 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
 
 #
 # Kernel hacking
@@ -1657,6 +1603,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
@@ -1687,9 +1636,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1697,17 +1649,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
@@ -1738,10 +1692,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
@@ -1810,6 +1766,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.29-gnu1/arch/powerpc/configs/mpc885_ads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc885_ads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/mpc885_ads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:41 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:01 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -52,6 +52,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -69,6 +70,15 @@ CONFIG_SYSVIPC_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 is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,19 +94,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 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 is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -105,10 +115,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 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_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -116,13 +128,13 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -138,11 +150,6 @@ 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_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_FREEZER is not set
 
 #
@@ -240,9 +247,12 @@ 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_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
@@ -277,14 +287,11 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0x80000000
-CONFIG_CONSISTENT_START=0xfd000000
-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
@@ -335,6 +342,7 @@ 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
 
@@ -347,7 +355,6 @@ 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
@@ -450,7 +457,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
@@ -474,6 +480,7 @@ CONFIG_HAVE_IDE=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
@@ -502,6 +509,8 @@ CONFIG_DAVICOM_PHY=y
 # CONFIG_MDIO_BITBANG 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
@@ -522,7 +531,6 @@ CONFIG_FS_ENET_MDIO_FEC=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
@@ -573,6 +581,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -642,6 +651,7 @@ CONFIG_DAB=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
 # CONFIG_STAGING is not set
 
@@ -666,6 +676,11 @@ CONFIG_FILE_LOCKING=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -709,6 +724,7 @@ 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
@@ -720,7 +736,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
@@ -752,6 +767,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -769,6 +785,7 @@ CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -786,6 +803,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
@@ -812,9 +832,12 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -822,17 +845,19 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 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
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/pmac32_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/pmac32_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/pmac32_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/pmac32_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc3
-# Tue Nov 11 19:36:51 2008
+# Linux kernel version: 2.6.30-rc7
+# Mon May 25 14:53:25 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
@@ -43,7 +44,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -52,12 +53,14 @@ CONFIG_OF=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_HIBERNATE_32=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
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -72,14 +75,24 @@ 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_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=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -88,23 +101,27 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=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=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
@@ -114,10 +131,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=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_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
@@ -127,10 +146,10 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=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 is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -138,11 +157,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=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -158,14 +174,11 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 CONFIG_FREEZER=y
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -178,7 +191,9 @@ CONFIG_PPC_PMAC=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
 CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -212,11 +227,12 @@ CONFIG_CPU_FREQ_PMAC=y
 CONFIG_PPC601_SYNC_FIX=y
 # 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_HIGHMEM=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -239,6 +255,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -250,12 +267,17 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_MIGRATION is not set
-# CONFIG_RESOURCES_64BIT 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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=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
@@ -288,6 +310,8 @@ 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=m
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=m
@@ -397,6 +421,8 @@ 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 is not set
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -405,6 +431,7 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -415,6 +442,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 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
@@ -478,17 +506,15 @@ CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
-CONFIG_IP_DCCP_CCID2=m
 # CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_CCID3=y
 # CONFIG_IP_DCCP_CCID3_DEBUG is not set
 CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+CONFIG_IP_DCCP_TFRC_LIB=y
 
 #
 # DCCP Kernel Hacking
@@ -508,13 +534,16 @@ CONFIG_IP_DCCP_TFRC_LIB=m
 # 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_NET_CLS_ROUTE=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=m
@@ -577,8 +606,6 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
-CONFIG_BT_HCIUSB=m
-# CONFIG_BT_HCIUSB_SCO is not set
 # CONFIG_BT_HCIBTUSB is not set
 # CONFIG_BT_HCIUART is not set
 CONFIG_BT_HCIBCM203X=m
@@ -590,31 +617,27 @@ CONFIG_BT_HCIBFUSB=m
 # CONFIG_BT_HCIBTUART is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
-CONFIG_NL80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
 
 #
 # 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_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_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU 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_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -662,17 +685,27 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
@@ -684,7 +717,6 @@ CONFIG_BLK_DEV_IDECS=m
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -714,6 +746,7 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # 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
@@ -728,7 +761,6 @@ CONFIG_BLK_DEV_SL82C105=y
 # CONFIG_BLK_DEV_TC86C001 is not set
 CONFIG_BLK_DEV_IDE_PMAC=y
 CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
 CONFIG_BLK_DEV_IDEDMA=y
 
 #
@@ -772,6 +804,7 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI 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
@@ -791,8 +824,12 @@ CONFIG_SCSI_AIC7XXX_OLD=m
 # 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
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -822,6 +859,7 @@ CONFIG_SCSI_MAC53C94=y
 # CONFIG_SCSI_SRP 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 is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
@@ -881,6 +919,7 @@ CONFIG_THERM_ADT746X=m
 # CONFIG_ANSLCD is not set
 CONFIG_PMAC_RACKMETER=m
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -898,6 +937,8 @@ CONFIG_BMAC=y
 CONFIG_SUNGEM=y
 # 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_ZMII is not set
@@ -913,7 +954,6 @@ CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -923,6 +963,7 @@ CONFIG_PCNET32=y
 # 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_VIA_RHINE is not set
@@ -935,6 +976,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
@@ -945,18 +987,20 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-# CONFIG_MV643XX_ETH 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
@@ -966,6 +1010,7 @@ CONFIG_NETDEV_10000=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
 
 #
@@ -974,20 +1019,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 # CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 # CONFIG_LIBERTAS is not set
 # CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AIRO is not set
-CONFIG_HERMES=m
-CONFIG_APPLE_AIRPORT=m
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_NORTEL_HERMES is not set
-CONFIG_PCI_HERMES=m
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM 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_PRISM54=m
@@ -997,15 +1033,17 @@ CONFIG_PRISM54=m
 # CONFIG_RTL8187 is not set
 # CONFIG_ADM8211 is not set
 # CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
 CONFIG_P54_COMMON=m
 # CONFIG_P54_USB is not set
 # CONFIG_P54_PCI is not set
+CONFIG_P54_LEDS=y
 # CONFIG_ATH5K is not set
 # CONFIG_ATH9K is not set
-# CONFIG_IWLCORE is not set
-# CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_IWLAGN is not set
-# CONFIG_IWL3945 is not set
+# CONFIG_AR9170_USB is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
 # CONFIG_HOSTAP is not set
 CONFIG_B43=m
 CONFIG_B43_PCI_AUTOSELECT=y
@@ -1025,6 +1063,19 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
 # CONFIG_B43LEGACY_PIO_MODE is not set
 # CONFIG_ZD1211RW is not set
 # CONFIG_RT2X00 is not set
+CONFIG_HERMES=m
+CONFIG_HERMES_CACHE_FW_ON_INIT=y
+CONFIG_APPLE_AIRPORT=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
+CONFIG_PCI_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -1036,6 +1087,7 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
 CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
 CONFIG_USB_NET_CDCETHER=m
+# 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
@@ -1099,7 +1151,7 @@ CONFIG_INPUT_KEYBOARD=y
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
+CONFIG_MOUSE_APPLETOUCH=y
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
@@ -1150,10 +1202,13 @@ CONFIG_SERIAL_PMACZILOG_TTYS=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_NVRAM=y
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -1232,12 +1287,9 @@ CONFIG_I2C_POWERMAC=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
@@ -1259,11 +1311,11 @@ CONFIG_BATTERY_PMU=y
 # 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=m
 CONFIG_SSB_SPROM=y
 CONFIG_SSB_PCIHOST_POSSIBLE=y
@@ -1281,18 +1333,13 @@ CONFIG_SSB_DRIVER_PCICORE=y
 # 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
-
-#
-# Voltage and Current regulators
-#
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
 
 #
 # Multimedia devices
@@ -1390,6 +1437,7 @@ CONFIG_FB_ATY_BACKLIGHT=y
 # CONFIG_FB_KYRO is not set
 CONFIG_FB_3DFX=y
 # CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_3DFX_I2C=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
@@ -1399,12 +1447,14 @@ CONFIG_FB_3DFX=y
 # 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=y
 CONFIG_LCD_CLASS_DEVICE=m
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
 
 #
 # Display device support
@@ -1444,11 +1494,13 @@ CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 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 is not set
 # CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
 CONFIG_SND_DRIVERS=y
 CONFIG_SND_DUMMY=m
 # CONFIG_SND_VIRMIDI is not set
@@ -1486,6 +1538,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1551,28 +1605,31 @@ 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_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=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_NTRIG=y
 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_TOPSEED=y
 # CONFIG_THRUSTMASTER_FF is not set
 # CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
@@ -1603,6 +1660,7 @@ CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_EHCI_HCD_PPC_OF 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
@@ -1625,24 +1683,23 @@ CONFIG_USB_PRINTER=m
 # 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=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
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
-CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_ONETOUCH=m
 # CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -1665,7 +1722,7 @@ CONFIG_USB_EZUSB=y
 # 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_CP2101 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
@@ -1701,15 +1758,19 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # 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
 
 #
@@ -1726,7 +1787,6 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=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=m
@@ -1738,6 +1798,11 @@ CONFIG_USB_APPLEDISPLAY=m
 # 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
@@ -1748,7 +1813,9 @@ CONFIG_LEDS_CLASS=y
 # LED drivers
 #
 # CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_LP5521 is not set
 # CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
 
 #
 # LED Triggers
@@ -1759,11 +1826,16 @@ CONFIG_LEDS_TRIGGER_IDE_DISK=y
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # 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
 # CONFIG_STAGING is not set
 
@@ -1774,6 +1846,7 @@ 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=y
 # CONFIG_EXT3_FS_SECURITY is not set
@@ -1783,7 +1856,9 @@ CONFIG_EXT4_FS_XATTR=y
 # CONFIG_EXT4_FS_POSIX_ACL is not set
 # CONFIG_EXT4_FS_SECURITY 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
@@ -1792,6 +1867,7 @@ 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1801,6 +1877,11 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=y
@@ -1831,10 +1912,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=m
@@ -1843,6 +1921,7 @@ CONFIG_HFSPLUS_FS=m
 # 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
@@ -1851,6 +1930,7 @@ CONFIG_HFSPLUS_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
@@ -1868,7 +1948,6 @@ CONFIG_NFS_ACL_SUPPORT=y
 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=m
@@ -1940,11 +2019,13 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 # 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=y
@@ -1954,15 +2035,18 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+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_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1973,13 +2057,16 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # 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=y
 # CONFIG_TIMER_STATS is not set
@@ -1994,6 +2081,7 @@ CONFIG_SCHEDSTATS=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
@@ -2001,6 +2089,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=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_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -2009,7 +2098,14 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_FAULT_INJECTION is not set
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+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_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -2017,12 +2113,19 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # 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_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_FTRACE_STARTUP_TEST 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_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
@@ -2033,6 +2136,7 @@ CONFIG_XMON_DEFAULT=y
 CONFIG_XMON_DISASSEMBLY=y
 CONFIG_DEBUGGER=y
 CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
 # CONFIG_BDI_SWITCH is not set
 CONFIG_BOOTX_TEXT=y
 # CONFIG_PPC_EARLY_DEBUG is not set
@@ -2051,13 +2155,20 @@ CONFIG_CRYPTO=y
 #
 # 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_RNG=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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -2127,6 +2238,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/ppc64_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/ppc64_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/ppc64_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/ppc64_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -2067,9 +2067,9 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 # CONFIG_DEBUG_PAGEALLOC is not set
 # 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
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 # CONFIG_XMON_DEFAULT is not set
 CONFIG_XMON_DISASSEMBLY=y
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/pq2fads_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/pq2fads_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/pq2fads_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/pq2fads_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:42 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:02 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -55,6 +56,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
 # 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"
 
 #
@@ -71,6 +73,15 @@ CONFIG_SYSVIPC_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
@@ -81,22 +92,24 @@ 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=y
 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 is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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
@@ -106,10 +119,12 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -117,6 +132,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -124,7 +140,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -139,18 +154,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -169,6 +177,8 @@ CONFIG_PQ2_ADS_PCI_PIC=y
 # CONFIG_PPC_83xx is not set
 # CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -225,9 +235,12 @@ 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_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
@@ -254,6 +267,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,7 +290,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -357,6 +370,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -368,7 +382,6 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_OLD_REGULATORY=y
@@ -473,7 +486,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,10 +510,14 @@ CONFIG_BLK_DEV_LOOP=y
 # 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_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -573,6 +589,7 @@ CONFIG_IDE_PROC_FS=y
 # 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_EQUALIZER is not set
@@ -606,6 +623,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_ZMII is not set
@@ -628,6 +647,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_R8169 is not set
@@ -637,8 +657,8 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
-# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_JME is not set
@@ -650,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
@@ -659,6 +680,7 @@ 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
 
 #
@@ -666,7 +688,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -720,7 +741,6 @@ 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_TOUCHKIT is not set
@@ -773,6 +793,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
@@ -868,7 +889,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # 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
@@ -907,13 +928,16 @@ CONFIG_USB_ETH_RNDIS=y
 # 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_INFINIBAND is not set
+# 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
 # CONFIG_STAGING is not set
 
@@ -924,6 +948,7 @@ 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
@@ -945,6 +970,10 @@ CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -1059,6 +1088,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1074,11 +1104,12 @@ 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
 
 #
 # Kernel hacking
@@ -1096,6 +1127,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 is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1125,9 +1159,12 @@ CONFIG_DEBUG_INFO=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1135,16 +1172,18 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=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
@@ -1175,9 +1214,11 @@ 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_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -1241,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
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/prpmc2800_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/prpmc2800_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/prpmc2800_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 15:35:44 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:03 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
@@ -56,6 +57,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -70,9 +72,19 @@ 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_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=14
 CONFIG_GROUP_SCHED=y
@@ -89,22 +101,26 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
 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=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
@@ -114,16 +130,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -131,7 +150,6 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,18 +165,11 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -178,6 +189,8 @@ CONFIG_EMBEDDED6xx=y
 CONFIG_PPC_PRPMC2800=y
 # CONFIG_PPC_C2K is not set
 CONFIG_MV64X60=y
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -237,9 +250,12 @@ 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_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
@@ -262,6 +278,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
@@ -279,15 +296,11 @@ 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_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -318,7 +331,7 @@ CONFIG_SYN_COOKIES=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_LRO=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -343,6 +356,7 @@ 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
 
@@ -355,7 +369,6 @@ 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
@@ -459,7 +472,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
@@ -489,19 +501,27 @@ CONFIG_BLK_DEV_RAM_SIZE=131072
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
 CONFIG_IDE_GD_ATA=y
@@ -605,9 +625,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -630,6 +652,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -707,6 +730,7 @@ CONFIG_MACINTOSH_DRIVERS=y
 # CONFIG_MAC_EMUMOUSEBTN is not set
 # CONFIG_WINDFARM 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
@@ -740,6 +764,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_ZMII is not set
@@ -781,6 +807,7 @@ CONFIG_E1000=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
@@ -795,6 +822,7 @@ 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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -804,6 +832,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
@@ -813,6 +842,7 @@ 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
 
 #
@@ -820,7 +850,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -975,12 +1004,9 @@ CONFIG_I2C_MV64XXX=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
@@ -1012,6 +1038,7 @@ CONFIG_HWMON=y
 # 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
@@ -1026,11 +1053,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -1127,15 +1157,17 @@ 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_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1202,11 +1234,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 is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -1236,7 +1268,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
@@ -1252,6 +1283,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
@@ -1313,8 +1345,9 @@ CONFIG_RTC_DRV_MAX6900=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1325,6 +1358,7 @@ 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
@@ -1348,6 +1382,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
@@ -1391,6 +1430,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -1400,7 +1440,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1432,6 +1471,7 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SYSV68_PARTITION is not set
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1445,11 +1485,15 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+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
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1471,13 +1515,24 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
@@ -1569,6 +1624,7 @@ CONFIG_CRYPTO=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.29-gnu1/arch/powerpc/configs/ps3_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/ps3_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/ps3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/ps3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc8
-# Fri Mar 13 09:28:45 2009
+# Linux kernel version: 2.6.30-rc5
+# Fri May 15 10:37:00 2009
 #
 CONFIG_PPC64=y
 
 #
 # Processor support
 #
+CONFIG_PPC_BOOK3S=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
 CONFIG_POWER4=y
@@ -55,9 +56,11 @@ CONFIG_OF=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_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"
 
 #
@@ -72,6 +75,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
@@ -88,8 +92,7 @@ CONFIG_CLASSIC_RCU=y
 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
@@ -99,6 +102,9 @@ CONFIG_NAMESPACES=y
 # CONFIG_NET_NS 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
@@ -107,6 +113,7 @@ 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
@@ -138,6 +145,7 @@ CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -150,7 +158,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
@@ -172,7 +179,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_ISERIES is not set
 # CONFIG_PPC_PMAC is not set
@@ -209,6 +215,7 @@ CONFIG_SPU_FS_64K_LS=y
 # CONFIG_SPU_TRACE is not set
 CONFIG_SPU_BASE=y
 # CONFIG_PQ2ADS 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
@@ -279,11 +286,14 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=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=13
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
@@ -316,7 +326,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -389,6 +398,7 @@ 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_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -396,6 +406,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # 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
@@ -419,11 +430,9 @@ CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
 # CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
@@ -602,6 +611,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=y
 # CONFIG_BLK_DEV_MD is not set
@@ -616,6 +626,7 @@ CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_UEVENT 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
@@ -625,6 +636,8 @@ CONFIG_NETDEVICES=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
+# 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
@@ -646,12 +659,13 @@ CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=
 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_IWLWIFI_LEDS is not set
+# CONFIG_AR9170_USB is not set
 # CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
@@ -673,6 +687,7 @@ CONFIG_USB_PEGASUS=m
 CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
 # CONFIG_USB_NET_CDCETHER is not set
+# 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
@@ -724,28 +739,7 @@ CONFIG_INPUT_EVDEV=m
 #
 # CONFIG_INPUT_KEYBOARD 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_JOYSTICK_XPAD 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
@@ -864,6 +858,7 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=9
 # 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
 
 #
@@ -934,15 +929,17 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
-# CONFIG_HID_COMPAT is not set
 # 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_DRAGONRISE_FF 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
@@ -950,7 +947,7 @@ CONFIG_USB_HIDDEV=y
 # 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_SONY=m
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_GREENASIA_FF is not set
 # CONFIG_HID_TOPSEED is not set
@@ -1012,11 +1009,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
@@ -1058,7 +1055,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
@@ -1074,6 +1070,7 @@ CONFIG_USB_STORAGE=m
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1113,8 +1110,10 @@ CONFIG_RTC_INTF_DEV=y
 #
 # on-CPU RTC drivers
 #
-CONFIG_RTC_DRV_PPC=m
+# CONFIG_RTC_DRV_GENERIC is not set
+CONFIG_RTC_DRV_PS3=m
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1125,6 +1124,7 @@ CONFIG_EXT2_FS=m
 # 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
@@ -1161,6 +1161,11 @@ CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=m
@@ -1211,6 +1216,7 @@ 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
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1223,7 +1229,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -1283,6 +1288,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=y
 
 #
 # Library routines
@@ -1296,15 +1302,16 @@ CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
+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
 
 #
 # Kernel hacking
@@ -1322,6 +1329,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
@@ -1357,12 +1367,15 @@ CONFIG_DEBUG_LIST=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 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_RING_BUFFER=y
 CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1371,18 +1384,21 @@ CONFIG_TRACING=y
 # 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_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG 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_PRINT_STACK_DEPTH=64
 CONFIG_DEBUG_STACKOVERFLOW=y
 # 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
@@ -1415,10 +1431,12 @@ 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 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
@@ -1487,6 +1505,7 @@ CONFIG_CRYPTO_SALSA20=m
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=m
 
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/pseries_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/pseries_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/pseries_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/pseries_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -95,7 +95,7 @@ CONFIG_CGROUP_CPUACCT=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_PROC_PID_CPUSET=y
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/configs/storcenter_defconfig linux-libre-2.6.30-gnu1/arch/powerpc/configs/storcenter_defconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/configs/storcenter_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/configs/storcenter_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc6
-# Fri Mar  6 00:09:08 2009
+# Linux kernel version: 2.6.30-rc3
+# Wed May 13 17:22:04 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 # CONFIG_40x is not set
 # CONFIG_44x is not set
 # CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
@@ -54,6 +55,7 @@ CONFIG_GENERIC_BUG=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"
 
 #
@@ -95,17 +97,17 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
 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
@@ -115,16 +117,19 @@ CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 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_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -137,7 +142,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -158,8 +162,6 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 #
 # Platform support
 #
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
 # CONFIG_MPC5121_ADS is not set
 # CONFIG_MPC5121_GENERIC is not set
@@ -181,6 +183,8 @@ CONFIG_STORCENTER=y
 CONFIG_MPC10X_BRIDGE=y
 CONFIG_MPC10X_OPENPIC=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
+# CONFIG_AMIGAONE is not set
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
@@ -239,9 +243,12 @@ 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_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
@@ -266,6 +273,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
@@ -288,7 +296,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=m
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +346,7 @@ 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
 
@@ -351,7 +359,6 @@ 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
@@ -486,6 +493,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
 
 #
@@ -500,6 +508,7 @@ 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
@@ -604,9 +613,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -628,6 +639,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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=y
@@ -637,7 +649,7 @@ CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=y
-CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6_PQ=y
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -655,6 +667,7 @@ CONFIG_MD_RAID5_RESHAPE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -671,6 +684,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
@@ -681,8 +695,8 @@ CONFIG_R8169=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_FSL_PQ_MDIO is not set
 # CONFIG_GIANFAR is not set
-# CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -696,7 +710,6 @@ CONFIG_R8169=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
@@ -766,6 +779,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_NVRAM=y
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -831,7 +845,6 @@ CONFIG_I2C_MPC=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
@@ -952,11 +965,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=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -997,7 +1010,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
@@ -1013,6 +1025,7 @@ CONFIG_USB_STORAGE=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
@@ -1074,8 +1087,9 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # 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
 # CONFIG_STAGING is not set
 
@@ -1086,6 +1100,7 @@ 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
@@ -1113,6 +1128,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
@@ -1166,6 +1186,7 @@ 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 is not set
 CONFIG_EXPORTFS=m
 
@@ -1231,6 +1252,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1246,11 +1268,11 @@ 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
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -1272,13 +1294,24 @@ CONFIG_FRAME_WARN=1024
 # 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
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# 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_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_PRINT_STACK_DEPTH=64
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/bootx.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/bootx.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/bootx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/bootx.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@
 #ifndef __ASM_BOOTX_H__
 #define __ASM_BOOTX_H__
 
-#include <asm/types.h>
+#include <linux/types.h>
 
 #ifdef macintosh
 #include <Types.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/code-patching.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/code-patching.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/code-patching.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/code-patching.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,9 +11,7 @@
  */
 
 #include <asm/types.h>
-
-#define PPC_NOP_INSTR		0x60000000
-#define PPC_LWSYNC_INSTR	0x7c2004ac
+#include <asm/ppc-opcode.h>
 
 /* Flags for create_branch:
  * "b"   == create_branch(addr, target, 0);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/cputable.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/cputable.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/cputable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/cputable.h	2009-06-09 23:05:27.000000000 -0400
@@ -145,6 +145,7 @@ extern const char *powerpc_base_platform
 #define CPU_FTR_USE_TB			ASM_CONST(0x0000000000000040)
 #define CPU_FTR_L2CSR			ASM_CONST(0x0000000000000080)
 #define CPU_FTR_601			ASM_CONST(0x0000000000000100)
+#define CPU_FTR_DBELL			ASM_CONST(0x0000000000000200)
 #define CPU_FTR_CAN_NAP			ASM_CONST(0x0000000000000400)
 #define CPU_FTR_L3CR			ASM_CONST(0x0000000000000800)
 #define CPU_FTR_L3_DISABLE_NAP		ASM_CONST(0x0000000000001000)
@@ -375,7 +376,8 @@ extern const char *powerpc_base_platform
 	    CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_E500MC	(CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
 	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
-	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE)
+	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
+	    CPU_FTR_DBELL)
 #define CPU_FTRS_GENERIC_32	(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/dbell.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/dbell.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/dbell.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/dbell.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Freescale Semicondutor, 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.
+ *
+ * provides masks and opcode images for use by code generation, emulation
+ * and for instructions that older assemblers might not know about
+ */
+#ifndef _ASM_POWERPC_DBELL_H
+#define _ASM_POWERPC_DBELL_H
+
+#include <linux/smp.h>
+#include <linux/threads.h>
+
+#include <asm/ppc-opcode.h>
+
+#define PPC_DBELL_MSG_BRDCAST	(0x04000000)
+#define PPC_DBELL_TYPE(x)	(((x) & 0xf) << 28)
+enum ppc_dbell {
+	PPC_DBELL = 0,		/* doorbell */
+	PPC_DBELL_CRIT = 1,	/* critical doorbell */
+	PPC_G_DBELL = 2,	/* guest doorbell */
+	PPC_G_DBELL_CRIT = 3,	/* guest critical doorbell */
+	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
+};
+
+#ifdef CONFIG_SMP
+extern unsigned long dbell_smp_message[NR_CPUS];
+extern void smp_dbell_message_pass(int target, int msg);
+#endif
+
+static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
+{
+	u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) |
+			(tag & 0x07ffffff);
+
+	__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+}
+
+#endif /* _ASM_POWERPC_DBELL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,9 @@
  * allocate the space "normally" and use the cache management functions
  * to ensure it is consistent.
  */
-extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
+struct device;
+extern void *__dma_alloc_coherent(struct device *dev, size_t size,
+				  dma_addr_t *handle, gfp_t gfp);
 extern void __dma_free_coherent(size_t size, void *vaddr);
 extern void __dma_sync(void *vaddr, size_t size, int direction);
 extern void __dma_sync_page(struct page *page, unsigned long offset,
@@ -37,7 +39,7 @@ extern void __dma_sync_page(struct page
  * Cache coherent cores.
  */
 
-#define __dma_alloc_coherent(gfp, size, handle)	NULL
+#define __dma_alloc_coherent(dev, gfp, size, handle)	NULL
 #define __dma_free_coherent(size, addr)		((void)0)
 #define __dma_sync(addr, size, rw)		((void)0)
 #define __dma_sync_page(pg, off, sz, rw)	((void)0)
@@ -109,18 +111,8 @@ static inline struct dma_mapping_ops *ge
 	 * only ISA DMA device we support is the floppy and we have a hack
 	 * in the floppy driver directly to get a device for us.
 	 */
-
-	if (unlikely(dev == NULL) || dev->archdata.dma_ops == NULL) {
-#ifdef CONFIG_PPC64
+	if (unlikely(dev == NULL))
 		return NULL;
-#else
-		/* Use default on 32-bit if dma_ops is not set up */
-		/* TODO: Long term, we should fix drivers so that dev and
-		 * archdata dma_ops are set up for all buses.
-		 */
-		return &dma_direct_ops;
-#endif
-	}
 
 	return dev->archdata.dma_ops;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/elf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,8 @@
 #include <asm/string.h>
 #endif
 
-#include <asm/types.h>
+#include <linux/types.h>
+
 #include <asm/ptrace.h>
 #include <asm/cputable.h>
 #include <asm/auxvec.h>
@@ -178,7 +179,8 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
    the loader.  We need to make sure that it is out of the way of the program
    that it will "exec", and that there is sufficient room for the brk.  */
 
-#define ELF_ET_DYN_BASE         (0x20000000)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE		(randomize_et_dyn(0x20000000))
 
 /*
  * Our registers are always unsigned longs, whether we're a 32 bit
@@ -256,7 +258,9 @@ do {								\
 # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
 		(exec_stk != EXSTACK_DISABLE_X) : 0)
 #else 
-# define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+# define SET_PERSONALITY(ex) \
+  set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
+# define elf_read_implies_exec(ex, exec_stk) (exec_stk != EXSTACK_DISABLE_X)
 #endif /* __powerpc64__ */
 
 extern int dcache_bsize;
@@ -270,6 +274,14 @@ extern int arch_setup_additional_pages(s
 				       int uses_interp);
 #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
 
+/* 1GB for 64bit, 8MB for 32bit */
+#define STACK_RND_MASK (is_32bit_task() ? \
+	(0x7ff >> (PAGE_SHIFT - 12)) : \
+	(0x3ffff >> (PAGE_SHIFT - 12)))
+
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
 #endif /* __KERNEL__ */
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/fixmap.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/fixmap.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/fixmap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/fixmap.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,8 +14,6 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
-extern unsigned long FIXADDR_TOP;
-
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
 #include <asm/page.h>
@@ -24,6 +22,8 @@ extern unsigned long FIXADDR_TOP;
 #include <asm/kmap_types.h>
 #endif
 
+#define FIXADDR_TOP	((unsigned long)(-PAGE_SIZE))
+
 /*
  * Here we define all the compile-time 'special' virtual
  * addresses. The point is to have a constant address at
@@ -61,7 +61,7 @@ extern void __set_fixmap (enum fixed_add
  * Some hardware wants to get fixmapped without caching.
  */
 #define set_fixmap_nocache(idx, phys) \
-		__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+		__set_fixmap(idx, phys, PAGE_KERNEL_NCG)
 
 #define clear_fixmap(idx) \
 		__set_fixmap(idx, 0, __pgprot(0))
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ftrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,44 @@
 #define MCOUNT_ADDR		((long)(_mcount))
 #define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
 
-#ifndef __ASSEMBLY__
+#ifdef __ASSEMBLY__
+
+/* Based off of objdump optput from glibc */
+
+#define MCOUNT_SAVE_FRAME			\
+	stwu	r1,-48(r1);			\
+	stw	r3, 12(r1);			\
+	stw	r4, 16(r1);			\
+	stw	r5, 20(r1);			\
+	stw	r6, 24(r1);			\
+	mflr	r3;				\
+	lwz	r4, 52(r1);			\
+	mfcr	r5;				\
+	stw	r7, 28(r1);			\
+	stw	r8, 32(r1);			\
+	stw	r9, 36(r1);			\
+	stw	r10,40(r1);			\
+	stw	r3, 44(r1);			\
+	stw	r5, 8(r1)
+
+#define MCOUNT_RESTORE_FRAME			\
+	lwz	r6, 8(r1);			\
+	lwz	r0, 44(r1);			\
+	lwz	r3, 12(r1);			\
+	mtctr	r0;				\
+	lwz	r4, 16(r1);			\
+	mtcr	r6;				\
+	lwz	r5, 20(r1);			\
+	lwz	r6, 24(r1);			\
+	lwz	r0, 52(r1);			\
+	lwz	r7, 28(r1);			\
+	lwz	r8, 32(r1);			\
+	mtlr	r0;				\
+	lwz	r9, 36(r1);			\
+	lwz	r10,40(r1);			\
+	addi	r1, r1, 48
+
+#else /* !__ASSEMBLY__ */
 extern void _mcount(void);
 
 #ifdef CONFIG_DYNAMIC_FTRACE
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/futex.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/futex.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/futex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/futex.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@
 	PPC_LONG "1b,4b,2b,4b\n" \
 	".previous" \
 	: "=&r" (oldval), "=&r" (ret) \
-	: "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
+	: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
 	: "cr0", "memory")
 
 static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
@@ -47,19 +47,19 @@ static inline int futex_atomic_op_inuser
 
 	switch (op) {
 	case FUTEX_OP_SET:
-		__futex_atomic_op("", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("mr %1,%4\n", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ADD:
-		__futex_atomic_op("add %1,%0,%1\n", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("add %1,%0,%4\n", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_OR:
-		__futex_atomic_op("or %1,%0,%1\n", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("or %1,%0,%4\n", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_atomic_op("andc %1,%0,%1\n", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("andc %1,%0,%4\n", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_XOR:
-		__futex_atomic_op("xor %1,%0,%1\n", ret, oldval, uaddr, oparg);
+		__futex_atomic_op("xor %1,%0,%4\n", ret, oldval, uaddr, oparg);
 		break;
 	default:
 		ret = -ENOSYS;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/highmem.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/highmem.h>
 #include <asm/kmap_types.h>
 #include <asm/tlbflush.h>
 #include <asm/page.h>
@@ -39,15 +40,15 @@ extern pte_t *pkmap_page_table;
  * chunk of RAM.
  */
 /*
- * We use one full pte table with 4K pages. And with 16K/64K pages pte
- * table covers enough memory (32MB and 512MB resp.) that both FIXMAP
- * and PKMAP can be placed in single pte table. We use 1024 pages for
- * PKMAP in case of 16K/64K pages.
+ * We use one full pte table with 4K pages. And with 16K/64K/256K pages pte
+ * table covers enough memory (32MB/512MB/2GB resp.), so that both FIXMAP
+ * and PKMAP can be placed in a single pte table. We use 512 pages for PKMAP
+ * in case of 16K/64K/256K page sizes.
  */
 #ifdef CONFIG_PPC_4K_PAGES
 #define PKMAP_ORDER	PTE_SHIFT
 #else
-#define PKMAP_ORDER	10
+#define PKMAP_ORDER	9
 #endif
 #define LAST_PKMAP	(1 << PKMAP_ORDER)
 #ifndef CONFIG_PPC_4K_PAGES
@@ -94,12 +95,13 @@ static inline void *kmap_atomic_prot(str
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
 	BUG_ON(!pte_none(*(kmap_pte-idx)));
 #endif
-	__set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+	__set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
 	local_flush_tlb_page(NULL, vaddr);
 
 	return (void*) vaddr;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/hw_irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,7 @@ static inline int irqs_disabled_flags(un
  * interrupt-retrigger: should we handle this via lost interrupts and IPIs
  * or should we not care like we do now ? --BenH.
  */
-struct hw_interrupt_type;
+struct irq_chip;
 
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_HW_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/io.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -632,6 +632,9 @@ static inline void iosync(void)
  *   ioremap_flags and cannot be hooked (but can be used by a hook on one
  *   of the previous ones)
  *
+ * * __ioremap_caller is the same as above but takes an explicit caller
+ *   reference rather than using __builtin_return_address(0)
+ *
  * * __iounmap, is the low level implementation used by iounmap and cannot
  *   be hooked (but can be used by a hook on iounmap)
  *
@@ -646,6 +649,9 @@ extern void iounmap(volatile void __iome
 
 extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
 			       unsigned long flags);
+extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
+				      unsigned long flags, void *caller);
+
 extern void __iounmap(volatile void __iomem *addr);
 
 extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/iseries/iommu.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/iseries/iommu.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/iseries/iommu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/iseries/iommu.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,10 +26,6 @@ struct vio_dev;
 struct device_node;
 struct iommu_table;
 
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct pci_dev *pdev,
-				       struct device_node *dn);
-
 /* Get table parameters from HV */
 extern void iommu_table_getparms_iSeries(unsigned long busno,
 		unsigned char slotno, unsigned char virtbus,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_44x.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_44x.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_44x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_44x.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,6 +28,13 @@
  * need to find some way of advertising it. */
 #define KVM44x_GUEST_TLB_SIZE 64
 
+struct kvmppc_44x_tlbe {
+	u32 tid; /* Only the low 8 bits are used. */
+	u32 word0;
+	u32 word1;
+	u32 word2;
+};
+
 struct kvmppc_44x_shadow_ref {
 	struct page *page;
 	u16 gtlb_index;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_asm.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_asm.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_asm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_asm.h	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,12 @@
 #define BOOKE_INTERRUPT_DTLB_MISS 13
 #define BOOKE_INTERRUPT_ITLB_MISS 14
 #define BOOKE_INTERRUPT_DEBUG 15
-#define BOOKE_MAX_INTERRUPT 15
+
+/* E500 */
+#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
+#define BOOKE_INTERRUPT_SPE_FP_DATA 33
+#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
+#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
 
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_e500.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_e500.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_e500.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_e500.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/include/asm/kvm_44x.h,
+ * 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.
+ */
+
+#ifndef __ASM_KVM_E500_H__
+#define __ASM_KVM_E500_H__
+
+#include <linux/kvm_host.h>
+
+#define BOOKE_INTERRUPT_SIZE 36
+
+#define E500_PID_NUM   3
+#define E500_TLB_NUM   2
+
+struct tlbe{
+	u32 mas1;
+	u32 mas2;
+	u32 mas3;
+	u32 mas7;
+};
+
+struct kvmppc_vcpu_e500 {
+	/* Unmodified copy of the guest's TLB. */
+	struct tlbe *guest_tlb[E500_TLB_NUM];
+	/* TLB that's actually used when the guest is running. */
+	struct tlbe *shadow_tlb[E500_TLB_NUM];
+	/* Pages which are referenced in the shadow TLB. */
+	struct page **shadow_pages[E500_TLB_NUM];
+
+	unsigned int guest_tlb_size[E500_TLB_NUM];
+	unsigned int shadow_tlb_size[E500_TLB_NUM];
+	unsigned int guest_tlb_nv[E500_TLB_NUM];
+
+	u32 host_pid[E500_PID_NUM];
+	u32 pid[E500_PID_NUM];
+
+	u32 mas0;
+	u32 mas1;
+	u32 mas2;
+	u32 mas3;
+	u32 mas4;
+	u32 mas5;
+	u32 mas6;
+	u32 mas7;
+	u32 l1csr1;
+	u32 hid0;
+	u32 hid1;
+
+	struct kvm_vcpu vcpu;
+};
+
+static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
+{
+	return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
+}
+
+#endif /* __ASM_KVM_E500_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@
 #ifndef __LINUX_KVM_POWERPC_H
 #define __LINUX_KVM_POWERPC_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 
 struct kvm_regs {
 	__u64 pc;
@@ -52,4 +52,11 @@ struct kvm_fpu {
 	__u64 fpr[32];
 };
 
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
 #endif /* __LINUX_KVM_POWERPC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_host.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_host.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_host.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,13 +64,6 @@ struct kvm_vcpu_stat {
 	u32 halt_wakeup;
 };
 
-struct kvmppc_44x_tlbe {
-	u32 tid; /* Only the low 8 bits are used. */
-	u32 word0;
-	u32 word1;
-	u32 word2;
-};
-
 enum kvm_exit_types {
 	MMIO_EXITS,
 	DCR_EXITS,
@@ -118,11 +111,6 @@ struct kvm_arch {
 struct kvm_vcpu_arch {
 	u32 host_stack;
 	u32 host_pid;
-	u32 host_dbcr0;
-	u32 host_dbcr1;
-	u32 host_dbcr2;
-	u32 host_iac[4];
-	u32 host_msr;
 
 	u64 fpr[32];
 	ulong gpr[32];
@@ -157,7 +145,7 @@ struct kvm_vcpu_arch {
 	u32 tbu;
 	u32 tcr;
 	u32 tsr;
-	u32 ivor[16];
+	u32 ivor[64];
 	ulong ivpr;
 	u32 pir;
 
@@ -170,6 +158,7 @@ struct kvm_vcpu_arch {
 	u32 ccr1;
 	u32 dbcr0;
 	u32 dbcr1;
+	u32 dbsr;
 
 #ifdef CONFIG_KVM_EXIT_TIMING
 	struct kvmppc_exit_timing timing_exit;
@@ -200,10 +189,4 @@ struct kvm_vcpu_arch {
 	unsigned long pending_exceptions;
 };
 
-struct kvm_guest_debug {
-	int enabled;
-	unsigned long bp[4];
-	int singlestep;
-};
-
 #endif /* __POWERPC_KVM_HOST_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_ppc.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_ppc.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/kvm_ppc.h	2009-06-09 23:05:27.000000000 -0400
@@ -52,13 +52,19 @@ extern int kvmppc_emulate_instruction(st
 extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
 extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu);
 
+/* Core-specific hooks */
+
 extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
-                           u64 asid, u32 flags, u32 max_bytes,
                            unsigned int gtlb_idx);
 extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
 extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
-
-/* Core-specific hooks */
+extern void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu);
+extern int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
+extern int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
+extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
+                              gva_t eaddr);
+extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu);
+extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu);
 
 extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm,
                                                 unsigned int id);
@@ -71,9 +77,6 @@ extern int kvmppc_core_vcpu_translate(st
 extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
 extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
 
-extern void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu);
-extern void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu);
-
 extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
 extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/lppaca.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/lppaca.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/lppaca.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/lppaca.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,7 +97,7 @@ struct lppaca {
 	u64	saved_gpr4;		// Saved GPR4                   x28-x2F
 	u64	saved_gpr5;		// Saved GPR5                   x30-x37
 
-	u8	reserved4;		// Reserved			x38-x38
+	u8	dtl_enable_mask;	// Dispatch Trace Log mask	x38-x38
 	u8	donate_dedicated_cpu;	// Donate dedicated CPU cycles  x39-x39
 	u8	fpregs_in_use;		// FP regs in use               x3A-x3A
 	u8	pmcregs_in_use;		// PMC regs in use              x3B-x3B
@@ -125,7 +125,7 @@ struct lppaca {
 	// NOTE: This value will ALWAYS be zero for dedicated processors and
 	// will NEVER be zero for shared processors (ie, initialized to a 1).
 	volatile u32 yield_count;	// PLIC increments each dispatchx00-x03
-	u32 reserved6;
+	volatile u32 dispersion_count;	// dispatch changed phys cpu    x04-x07
 	volatile u64 cmo_faults;	// CMO page fault count         x08-x0F
 	volatile u64 cmo_fault_time;	// CMO page fault time          x10-x17
 	u8	reserved7[104];		// Reserved                     x18-x7F
@@ -133,8 +133,10 @@ struct lppaca {
 //=============================================================================
 // CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
 //=============================================================================
-	u32	page_ins;			// CMO Hint - # page ins by OS  x00-x04
-	u8	pmc_save_area[252];	// PMC interrupt Area           x04-xFF
+	u32	page_ins;		// CMO Hint - # page ins by OS  x00-x03
+	u8	reserved8[148];		// Reserved                     x04-x97
+	volatile u64 dtl_idx;		// Dispatch Trace Log head idx	x98-x9F
+	u8	reserved9[96];		// Reserved                     xA0-xFF
 } __attribute__((__aligned__(0x400)));
 
 extern struct lppaca lppaca[];
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/machdep.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/machdep.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/machdep.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/machdep.h	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,7 @@ struct machdep_calls {
 	void		(*tce_flush)(struct iommu_table *tbl);
 
 	void __iomem *	(*ioremap)(phys_addr_t addr, unsigned long size,
-				   unsigned long flags);
+				   unsigned long flags, void *caller);
 	void		(*iounmap)(volatile void __iomem *token);
 
 #ifdef CONFIG_PM
@@ -327,8 +327,6 @@ extern void __devinit smp_generic_take_t
  */
 /* Print a boot progress message. */
 void ppc64_boot_msg(unsigned int src, const char *msg);
-/* Print a termination message (print only -- does not stop the kernel) */
-void ppc64_terminate_msg(unsigned int src, const char *msg);
 
 static inline void log_error(char *buf, unsigned int err_type, int fatal)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-44x.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-44x.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-44x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-44x.h	2009-06-09 23:05:27.000000000 -0400
@@ -83,6 +83,8 @@ typedef struct {
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_16K
 #elif (PAGE_SHIFT == 16)
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_64K
+#elif (PAGE_SHIFT == 18)
+#define PPC44x_TLBE_SIZE	PPC44x_TLB_256K
 #else
 #error "Unsupported PAGE_SIZE"
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-book3e.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-book3e.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-book3e.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-book3e.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,105 @@
+#ifndef _ASM_POWERPC_MMU_BOOK3E_H_
+#define _ASM_POWERPC_MMU_BOOK3E_H_
+/*
+ * Freescale Book-E/Book-3e (ISA 2.06+) MMU support
+ */
+
+/* Book-3e defined page sizes */
+#define BOOK3E_PAGESZ_1K	0
+#define BOOK3E_PAGESZ_2K	1
+#define BOOK3E_PAGESZ_4K	2
+#define BOOK3E_PAGESZ_8K	3
+#define BOOK3E_PAGESZ_16K	4
+#define BOOK3E_PAGESZ_32K	5
+#define BOOK3E_PAGESZ_64K	6
+#define BOOK3E_PAGESZ_128K	7
+#define BOOK3E_PAGESZ_256K	8
+#define BOOK3E_PAGESZ_512K	9
+#define BOOK3E_PAGESZ_1M	10
+#define BOOK3E_PAGESZ_2M	11
+#define BOOK3E_PAGESZ_4M	12
+#define BOOK3E_PAGESZ_8M	13
+#define BOOK3E_PAGESZ_16M	14
+#define BOOK3E_PAGESZ_32M	15
+#define BOOK3E_PAGESZ_64M	16
+#define BOOK3E_PAGESZ_128M	17
+#define BOOK3E_PAGESZ_256M	18
+#define BOOK3E_PAGESZ_512M	19
+#define BOOK3E_PAGESZ_1GB	20
+#define BOOK3E_PAGESZ_2GB	21
+#define BOOK3E_PAGESZ_4GB	22
+#define BOOK3E_PAGESZ_8GB	23
+#define BOOK3E_PAGESZ_16GB	24
+#define BOOK3E_PAGESZ_32GB	25
+#define BOOK3E_PAGESZ_64GB	26
+#define BOOK3E_PAGESZ_128GB	27
+#define BOOK3E_PAGESZ_256GB	28
+#define BOOK3E_PAGESZ_512GB	29
+#define BOOK3E_PAGESZ_1TB	30
+#define BOOK3E_PAGESZ_2TB	31
+
+#define MAS0_TLBSEL(x)	((x << 28) & 0x30000000)
+#define MAS0_ESEL(x)	((x << 16) & 0x0FFF0000)
+#define MAS0_NV(x)	((x) & 0x00000FFF)
+
+#define MAS1_VALID 	0x80000000
+#define MAS1_IPROT	0x40000000
+#define MAS1_TID(x)	((x << 16) & 0x3FFF0000)
+#define MAS1_IND	0x00002000
+#define MAS1_TS		0x00001000
+#define MAS1_TSIZE(x)	((x << 7) & 0x00000F80)
+
+#define MAS2_EPN	0xFFFFF000
+#define MAS2_X0		0x00000040
+#define MAS2_X1		0x00000020
+#define MAS2_W		0x00000010
+#define MAS2_I		0x00000008
+#define MAS2_M		0x00000004
+#define MAS2_G		0x00000002
+#define MAS2_E		0x00000001
+#define MAS2_EPN_MASK(size)		(~0 << (size + 10))
+#define MAS2_VAL(addr, size, flags)	((addr) & MAS2_EPN_MASK(size) | (flags))
+
+#define MAS3_RPN	0xFFFFF000
+#define MAS3_U0		0x00000200
+#define MAS3_U1		0x00000100
+#define MAS3_U2		0x00000080
+#define MAS3_U3		0x00000040
+#define MAS3_UX		0x00000020
+#define MAS3_SX		0x00000010
+#define MAS3_UW		0x00000008
+#define MAS3_SW		0x00000004
+#define MAS3_UR		0x00000002
+#define MAS3_SR		0x00000001
+
+#define MAS4_TLBSELD(x) MAS0_TLBSEL(x)
+#define MAS4_INDD	0x00008000
+#define MAS4_TSIZED(x)	MAS1_TSIZE(x)
+#define MAS4_X0D	0x00000040
+#define MAS4_X1D	0x00000020
+#define MAS4_WD		0x00000010
+#define MAS4_ID		0x00000008
+#define MAS4_MD		0x00000004
+#define MAS4_GD		0x00000002
+#define MAS4_ED		0x00000001
+
+#define MAS6_SPID0	0x3FFF0000
+#define MAS6_SPID1	0x00007FFE
+#define MAS6_ISIZE(x)	MAS1_TSIZE(x)
+#define MAS6_SAS	0x00000001
+#define MAS6_SPID	MAS6_SPID0
+
+#define MAS7_RPN	0xFFFFFFFF
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int tlbcam_index;
+
+typedef struct {
+	unsigned int	id;
+	unsigned int	active;
+	unsigned long	vdso_base;
+} mm_context_t;
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ static inline void switch_mm(struct mm_s
 			     struct task_struct *tsk)
 {
 	/* Mark this context has been used on the new CPU */
-	cpu_set(smp_processor_id(), next->cpu_vm_mask);
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
 
 	/* 32-bit keeps track of the current PGDIR in the thread struct */
 #ifdef CONFIG_PPC32
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-fsl-booke.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-fsl-booke.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-fsl-booke.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-fsl-booke.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-#ifndef _ASM_POWERPC_MMU_FSL_BOOKE_H_
-#define _ASM_POWERPC_MMU_FSL_BOOKE_H_
-/*
- * Freescale Book-E MMU support
- */
-
-/* Book-E defined page sizes */
-#define BOOKE_PAGESZ_1K		0
-#define BOOKE_PAGESZ_4K		1
-#define BOOKE_PAGESZ_16K	2
-#define BOOKE_PAGESZ_64K	3
-#define BOOKE_PAGESZ_256K	4
-#define BOOKE_PAGESZ_1M		5
-#define BOOKE_PAGESZ_4M		6
-#define BOOKE_PAGESZ_16M	7
-#define BOOKE_PAGESZ_64M	8
-#define BOOKE_PAGESZ_256M	9
-#define BOOKE_PAGESZ_1GB	10
-#define BOOKE_PAGESZ_4GB	11
-#define BOOKE_PAGESZ_16GB	12
-#define BOOKE_PAGESZ_64GB	13
-#define BOOKE_PAGESZ_256GB	14
-#define BOOKE_PAGESZ_1TB	15
-
-#define MAS0_TLBSEL(x)	((x << 28) & 0x30000000)
-#define MAS0_ESEL(x)	((x << 16) & 0x0FFF0000)
-#define MAS0_NV(x)	((x) & 0x00000FFF)
-
-#define MAS1_VALID 	0x80000000
-#define MAS1_IPROT	0x40000000
-#define MAS1_TID(x)	((x << 16) & 0x3FFF0000)
-#define MAS1_TS		0x00001000
-#define MAS1_TSIZE(x)	((x << 8) & 0x00000F00)
-
-#define MAS2_EPN	0xFFFFF000
-#define MAS2_X0		0x00000040
-#define MAS2_X1		0x00000020
-#define MAS2_W		0x00000010
-#define MAS2_I		0x00000008
-#define MAS2_M		0x00000004
-#define MAS2_G		0x00000002
-#define MAS2_E		0x00000001
-#define MAS2_EPN_MASK(size)		(~0 << (2*(size) + 10))
-#define MAS2_VAL(addr, size, flags)	((addr) & MAS2_EPN_MASK(size) | (flags))
-
-#define MAS3_RPN	0xFFFFF000
-#define MAS3_U0		0x00000200
-#define MAS3_U1		0x00000100
-#define MAS3_U2		0x00000080
-#define MAS3_U3		0x00000040
-#define MAS3_UX		0x00000020
-#define MAS3_SX		0x00000010
-#define MAS3_UW		0x00000008
-#define MAS3_SW		0x00000004
-#define MAS3_UR		0x00000002
-#define MAS3_SR		0x00000001
-
-#define MAS4_TLBSELD(x) MAS0_TLBSEL(x)
-#define MAS4_TIDDSEL	0x000F0000
-#define MAS4_TSIZED(x)	MAS1_TSIZE(x)
-#define MAS4_X0D	0x00000040
-#define MAS4_X1D	0x00000020
-#define MAS4_WD		0x00000010
-#define MAS4_ID		0x00000008
-#define MAS4_MD		0x00000004
-#define MAS4_GD		0x00000002
-#define MAS4_ED		0x00000001
-
-#define MAS6_SPID0	0x3FFF0000
-#define MAS6_SPID1	0x00007FFE
-#define MAS6_SAS	0x00000001
-#define MAS6_SPID	MAS6_SPID0
-
-#define MAS7_RPN	0xFFFFFFFF
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-	unsigned int	id;
-	unsigned int	active;
-	unsigned long	vdso_base;
-} mm_context_t;
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _ASM_POWERPC_MMU_FSL_BOOKE_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,9 +36,9 @@
  */
 #define MMU_FTR_USE_TLBIVAX_BCAST	ASM_CONST(0x00040000)
 
-/* Enable use of tlbilx invalidate-by-PID variant.
+/* Enable use of tlbilx invalidate instructions.
  */
-#define MMU_FTR_USE_TLBILX_PID		ASM_CONST(0x00080000)
+#define MMU_FTR_USE_TLBILX		ASM_CONST(0x00080000)
 
 /* This indicates that the processor cannot handle multiple outstanding
  * broadcast tlbivax or tlbsync. This makes the code use a spinlock
@@ -46,6 +46,12 @@
  */
 #define MMU_FTR_LOCK_BCAST_INVAL	ASM_CONST(0x00100000)
 
+/* This indicates that the processor doesn't handle way selection
+ * properly and needs SW to track and update the LRU state.  This
+ * is specific to an errata on e300c2/c3/c4 class parts
+ */
+#define MMU_FTR_NEED_DTLB_SW_LRU	ASM_CONST(0x00200000)
+
 #ifndef __ASSEMBLY__
 #include <asm/cputable.h>
 
@@ -56,6 +62,10 @@ static inline int mmu_has_feature(unsign
 
 extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
 
+/* MMU initialization (64-bit only fo now) */
+extern void early_init_mmu(void);
+extern void early_init_mmu_secondary(void);
+
 #endif /* !__ASSEMBLY__ */
 
 
@@ -71,9 +81,9 @@ extern unsigned int __start___mmu_ftr_fi
 #elif defined(CONFIG_44x)
 /* 44x-style software loaded TLB */
 #  include <asm/mmu-44x.h>
-#elif defined(CONFIG_FSL_BOOKE)
-/* Freescale Book-E software loaded TLB */
-#  include <asm/mmu-fsl-booke.h>
+#elif defined(CONFIG_PPC_BOOK3E_MMU)
+/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
+#  include <asm/mmu-book3e.h>
 #elif defined (CONFIG_PPC_8xx)
 /* Motorola/Freescale 8xx software loaded TLB */
 #  include <asm/mmu-8xx.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-hash64.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-hash64.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2009-06-09 23:05:27.000000000 -0400
@@ -284,8 +284,6 @@ extern void add_gpage(unsigned long addr
 			  unsigned long number_of_pages);
 extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
 
-extern void htab_initialize(void);
-extern void htab_initialize_secondary(void);
 extern void hpte_init_native(void);
 extern void hpte_init_lpar(void);
 extern void hpte_init_iSeries(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmzone.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmzone.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mmzone.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmzone.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,7 @@
 #define _ASM_MMZONE_H_
 #ifdef __KERNEL__
 
+#include <linux/cpumask.h>
 
 /*
  * generic non-linear memory support:
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mpc52xx.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mpc52xx.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mpc52xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mpc52xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -273,6 +273,7 @@ extern void mpc5200_setup_xlb_arbiter(vo
 extern void mpc52xx_declare_of_platform_devices(void);
 extern void mpc52xx_map_common_devices(void);
 extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
+extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
 extern void mpc52xx_restart(char *cmd);
 
 /* mpc52xx_pic.c */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mpic.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mpic.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/mpic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mpic.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,14 @@
 #define MPIC_GREG_FEATURE_1		0x00010
 #define MPIC_GREG_GLOBAL_CONF_0		0x00020
 #define		MPIC_GREG_GCONF_RESET			0x80000000
+/* On the FSL mpic implementations the Mode field is expand to be
+ * 2 bits wide:
+ *	0b00 = pass through (interrupts routed to IRQ0)
+ *	0b01 = Mixed mode
+ *	0b10 = reserved
+ *	0b11 = External proxy / coreint
+ */
+#define		MPIC_GREG_GCONF_COREINT			0x60000000
 #define		MPIC_GREG_GCONF_8259_PTHROU_DIS		0x20000000
 #define		MPIC_GREG_GCONF_NO_BIAS			0x10000000
 #define		MPIC_GREG_GCONF_BASE_MASK		0x000fffff
@@ -357,6 +365,8 @@ struct mpic
 #define MPIC_BROKEN_FRR_NIRQS		0x00000800
 /* Destination only supports a single CPU at a time */
 #define MPIC_SINGLE_DEST_CPU		0x00001000
+/* Enable CoreInt delivery of interrupts */
+#define MPIC_ENABLE_COREINT		0x00002000
 
 /* MPIC HW modification ID */
 #define MPIC_REGSET_MASK		0xf0000000
@@ -470,6 +480,8 @@ extern void mpic_end_irq(unsigned int ir
 extern unsigned int mpic_get_one_irq(struct mpic *mpic);
 /* This one gets from the primary mpic */
 extern unsigned int mpic_get_irq(void);
+/* This one gets from the primary mpic via CoreInt*/
+extern unsigned int mpic_get_coreint_irq(void);
 /* Fetch Machine Check interrupt from primary mpic */
 extern unsigned int mpic_get_mcirq(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/of_platform.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/of_platform.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/of_platform.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/of_platform.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,16 +11,6 @@
  *
  */
 
-/* Platform drivers register/unregister */
-static inline int of_register_platform_driver(struct of_platform_driver *drv)
-{
-	return of_register_driver(drv, &of_platform_bus_type);
-}
-static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
-{
-	of_unregister_driver(drv);
-}
-
 /* Platform devices and busses creation */
 extern struct of_device *of_platform_device_create(struct device_node *np,
 						   const char *bus_id,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/page_32.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/page_32.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/page_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/page_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,11 @@
 #define PTE_FLAGS_OFFSET	0
 #endif
 
+#ifdef CONFIG_PPC_256K_PAGES
+#define PTE_SHIFT	(PAGE_SHIFT - PTE_T_LOG2 - 2)	/* 1/4 of a page */
+#else
 #define PTE_SHIFT	(PAGE_SHIFT - PTE_T_LOG2)	/* full page */
+#endif
 
 #ifndef __ASSEMBLY__
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/page.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,12 +19,14 @@
 #include <asm/kdump.h>
 
 /*
- * On regular PPC32 page size is 4K (but we support 4K/16K/64K pages
+ * On regular PPC32 page size is 4K (but we support 4K/16K/64K/256K pages
  * on PPC44x). For PPC64 we support either 4K or 64K software
  * page size. When using 64K pages however, whether we are really supporting
  * 64K pages in HW or not is irrelevant to those definitions.
  */
-#if defined(CONFIG_PPC_64K_PAGES)
+#if defined(CONFIG_PPC_256K_PAGES)
+#define PAGE_SHIFT		18
+#elif defined(CONFIG_PPC_64K_PAGES)
 #define PAGE_SHIFT		16
 #elif defined(CONFIG_PPC_16K_PAGES)
 #define PAGE_SHIFT		14
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/parport.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/parport.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/parport.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/parport.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@ static int __devinit parport_pc_find_non
 		prop = of_get_property(np, "interrupts", NULL);
 		if (!prop)
 			continue;
-		if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL) != NULL)
+		if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL, 0) != NULL)
 			count++;
 	}
 	return count;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -114,6 +114,10 @@ extern int pci_domain_nr(struct pci_bus
 /* Decide whether to display the domain number in /proc */
 extern int pci_proc_domain(struct pci_bus *bus);
 
+/* MSI arch hooks */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+#define arch_teardown_msi_irqs arch_teardown_msi_irqs
+#define arch_msi_check_device arch_msi_check_device
 
 struct vm_area_struct;
 /* Map a range of PCI memory or I/O space for a device into user space */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-4k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-4k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-4k.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-4k.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,117 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_4K_H
-#define _ASM_POWERPC_PGTABLE_4K_H
-/*
- * Entries per page directory level.  The PTE level must use a 64b record
- * for each page table entry.  The PMD and PGD level use a 32b record for
- * each entry by assuming that each entry is page aligned.
- */
-#define PTE_INDEX_SIZE  9
-#define PMD_INDEX_SIZE  7
-#define PUD_INDEX_SIZE  7
-#define PGD_INDEX_SIZE  9
-
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE	(sizeof(pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE	(sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PUD_TABLE_SIZE	(sizeof(pud_t) << PUD_INDEX_SIZE)
-#define PGD_TABLE_SIZE	(sizeof(pgd_t) << PGD_INDEX_SIZE)
-#endif	/* __ASSEMBLY__ */
-
-#define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PUD	(1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT	(PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
-
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT	PMD_SHIFT
-
-/* PUD_SHIFT determines what a third-level page table entry can map */
-#define PUD_SHIFT	(PMD_SHIFT + PMD_INDEX_SIZE)
-#define PUD_SIZE	(1UL << PUD_SHIFT)
-#define PUD_MASK	(~(PUD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
-#define PGDIR_SHIFT	(PUD_SHIFT + PUD_INDEX_SIZE)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK	(~(PGDIR_SIZE-1))
-
-/* PTE bits */
-#define _PAGE_HASHPTE	0x0400 /* software: pte has an associated HPTE */
-#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
-#define _PAGE_GROUP_IX  0x7000 /* software: HPTE index within group */
-#define _PAGE_F_SECOND  _PAGE_SECONDARY
-#define _PAGE_F_GIX     _PAGE_GROUP_IX
-#define _PAGE_SPECIAL	0x10000 /* software: special page */
-#define __HAVE_ARCH_PTE_SPECIAL
-
-/* PTE flags to conserve for HPTE identification */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
-			 _PAGE_SECONDARY | _PAGE_GROUP_IX)
-
-/* There is no 4K PFN hack on 4K pages */
-#define _PAGE_4K_PFN	0
-
-/* PAGE_MASK gives the right answer below, but only by accident */
-/* It should be preserving the high 48 bits and then specifically */
-/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
-#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
-                         _PAGE_HPTEFLAGS | _PAGE_SPECIAL)
-
-/* Bits to mask out from a PMD to get to the PTE page */
-#define PMD_MASKED_BITS		0
-/* Bits to mask out from a PUD to get to the PMD page */
-#define PUD_MASKED_BITS		0
-/* Bits to mask out from a PGD to get to the PUD page */
-#define PGD_MASKED_BITS		0
-
-/* shift to put page number into pte */
-#define PTE_RPN_SHIFT	(17)
-
-#ifdef STRICT_MM_TYPECHECKS
-#define __real_pte(e,p)		((real_pte_t){(e)})
-#define __rpte_to_pte(r)	((r).pte)
-#else
-#define __real_pte(e,p)		(e)
-#define __rpte_to_pte(r)	(__pte(r))
-#endif
-#define __rpte_to_hidx(r,index)	(pte_val(__rpte_to_pte(r)) >> 12)
-
-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
-	do {							         \
-		index = 0;					         \
-		shift = mmu_psize_defs[psize].shift;		         \
-
-#define pte_iterate_hashed_end() } while(0)
-
-#ifdef CONFIG_PPC_HAS_HASH_64K
-#define pte_pagesize_index(mm, addr, pte)	get_slice_psize(mm, addr)
-#else
-#define pte_pagesize_index(mm, addr, pte)	MMU_PAGE_4K
-#endif
-
-/*
- * 4-level page tables related bits
- */
-
-#define pgd_none(pgd)		(!pgd_val(pgd))
-#define pgd_bad(pgd)		(pgd_val(pgd) == 0)
-#define pgd_present(pgd)	(pgd_val(pgd) != 0)
-#define pgd_clear(pgdp)		(pgd_val(*(pgdp)) = 0)
-#define pgd_page_vaddr(pgd)	(pgd_val(pgd) & ~PGD_MASKED_BITS)
-#define pgd_page(pgd)		virt_to_page(pgd_page_vaddr(pgd))
-
-#define pud_offset(pgdp, addr)	\
-  (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
-    (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
-
-#define pud_ERROR(e) \
-	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
-
-#define remap_4k_pfn(vma, addr, pfn, prot)	\
-	remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
-#endif /* _ASM_POWERPC_PGTABLE_4K_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-64k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-64k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-64k.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-64k.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,155 +0,0 @@
-#ifndef _ASM_POWERPC_PGTABLE_64K_H
-#define _ASM_POWERPC_PGTABLE_64K_H
-
-#include <asm-generic/pgtable-nopud.h>
-
-
-#define PTE_INDEX_SIZE  12
-#define PMD_INDEX_SIZE  12
-#define PUD_INDEX_SIZE	0
-#define PGD_INDEX_SIZE  4
-
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE	(sizeof(real_pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE	(sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PGD_TABLE_SIZE	(sizeof(pgd_t) << PGD_INDEX_SIZE)
-
-#define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
-
-#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__ */
-
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT	PAGE_SHIFT
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT	(PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT	(PMD_SHIFT + PMD_INDEX_SIZE)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK	(~(PGDIR_SIZE-1))
-
-/* Additional PTE bits (don't change without checking asm in hash_low.S) */
-#define __HAVE_ARCH_PTE_SPECIAL
-#define _PAGE_SPECIAL	0x00000400 /* software: special page */
-#define _PAGE_HPTE_SUB	0x0ffff000 /* combo only: sub pages HPTE bits */
-#define _PAGE_HPTE_SUB0	0x08000000 /* combo only: first sub page */
-#define _PAGE_COMBO	0x10000000 /* this is a combo 4k page */
-#define _PAGE_4K_PFN	0x20000000 /* PFN is for a single 4k page */
-
-/* For 64K page, we don't have a separate _PAGE_HASHPTE bit. Instead,
- * we set that to be the whole sub-bits mask. The C code will only
- * test this, so a multi-bit mask will work. For combo pages, this
- * is equivalent as effectively, the old _PAGE_HASHPTE was an OR of
- * all the sub bits. For real 64k pages, we now have the assembly set
- * _PAGE_HPTE_SUB0 in addition to setting the HIDX bits which overlap
- * that mask. This is fine as long as the HIDX bits are never set on
- * a PTE that isn't hashed, which is the case today.
- *
- * A little nit is for the huge page C code, which does the hashing
- * in C, we need to provide which bit to use.
- */
-#define _PAGE_HASHPTE	_PAGE_HPTE_SUB
-
-/* Note the full page bits must be in the same location as for normal
- * 4k pages as the same asssembly will be used to insert 64K pages
- * wether the kernel has CONFIG_PPC_64K_PAGES or not
- */
-#define _PAGE_F_SECOND  0x00008000 /* full page: hidx bits */
-#define _PAGE_F_GIX     0x00007000 /* full page: hidx bits */
-
-/* PTE flags to conserve for HPTE identification */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO)
-
-/* Shift to put page number into pte.
- *
- * That gives us a max RPN of 34 bits, which means a max of 50 bits
- * of addressable physical space, or 46 bits for the special 4k PFNs.
- */
-#define PTE_RPN_SHIFT	(30)
-#define PTE_RPN_MAX	(1UL << (64 - PTE_RPN_SHIFT))
-#define PTE_RPN_MASK	(~((1UL<<PTE_RPN_SHIFT)-1))
-
-/* _PAGE_CHG_MASK masks of bits that are to be preserved accross
- * pgprot changes
- */
-#define _PAGE_CHG_MASK	(PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
-                         _PAGE_ACCESSED | _PAGE_SPECIAL)
-
-/* Bits to mask out from a PMD to get to the PTE page */
-#define PMD_MASKED_BITS		0x1ff
-/* Bits to mask out from a PGD/PUD to get to the PMD page */
-#define PUD_MASKED_BITS		0x1ff
-
-/* Manipulate "rpte" values */
-#define __real_pte(e,p) 	((real_pte_t) { \
-	(e), pte_val(*((p) + PTRS_PER_PTE)) })
-#define __rpte_to_hidx(r,index)	((pte_val((r).pte) & _PAGE_COMBO) ? \
-        (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
-#define __rpte_to_pte(r)	((r).pte)
-#define __rpte_sub_valid(rpte, index) \
-	(pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))
-
-
-/* Trick: we set __end to va + 64k, which happens works for
- * a 16M page as well as we want only one iteration
- */
-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)	    \
-        do {                                                                \
-                unsigned long __end = va + PAGE_SIZE;                       \
-                unsigned __split = (psize == MMU_PAGE_4K ||                 \
-				    psize == MMU_PAGE_64K_AP);              \
-                shift = mmu_psize_defs[psize].shift;                        \
-		for (index = 0; va < __end; index++, va += (1L << shift)) { \
-		        if (!__split || __rpte_sub_valid(rpte, index)) do { \
-
-#define pte_iterate_hashed_end() } while(0); } } while(0)
-
-#define pte_pagesize_index(mm, addr, pte)	\
-	(((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
-
-#define remap_4k_pfn(vma, addr, pfn, prot)				\
-	remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE,		\
-			__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
-
-#endif /* _ASM_POWERPC_PGTABLE_64K_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,17 @@
 #include <asm/processor.h>		/* For TASK_SIZE */
 #include <asm/mmu.h>
 #include <asm/page.h>
+
 struct mm_struct;
+
+#ifdef CONFIG_DEBUG_VM
+extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr);
+#else /* CONFIG_DEBUG_VM */
+static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+}
+#endif /* !CONFIG_DEBUG_VM */
+
 #endif /* !__ASSEMBLY__ */
 
 #if defined(CONFIG_PPC64)
@@ -17,6 +27,130 @@ struct mm_struct;
 
 #ifndef __ASSEMBLY__
 
+/* Generic accessors to PTE bits */
+static inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
+static inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
+static inline int pte_special(pte_t pte)	{ return pte_val(pte) & _PAGE_SPECIAL; }
+static inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
+static inline int pte_none(pte_t pte)		{ return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
+static inline pgprot_t pte_pgprot(pte_t pte)	{ return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
+
+/* Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * Even if PTEs can be unsigned long long, a PFN is always an unsigned
+ * long for now.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) {
+	return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) |
+		     pgprot_val(pgprot)); }
+static inline unsigned long pte_pfn(pte_t pte)	{
+	return pte_val(pte) >> PTE_RPN_SHIFT; }
+
+/* Keep these as a macros to avoid include dependency mess */
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+
+/* Generic modifiers for PTE bits */
+static inline pte_t pte_wrprotect(pte_t pte) {
+	pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+	pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+	pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+	pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+	pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+	pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkspecial(pte_t pte) {
+	pte_val(pte) |= _PAGE_SPECIAL; return pte; }
+static inline pte_t pte_mkhuge(pte_t pte) {
+	return pte; }
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+	return pte;
+}
+
+
+/* Insert a PTE, top-level function is out of line. It uses an inline
+ * low level function in the respective pgtable-* files
+ */
+extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+		       pte_t pte);
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+				pte_t *ptep, pte_t pte, int percpu)
+{
+#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
+	/* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
+	 * helper pte_update() which does an atomic update. We need to do that
+	 * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
+	 * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
+	 * the hash bits instead (ie, same as the non-SMP case)
+	 */
+	if (percpu)
+		*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+			      | (pte_val(pte) & ~_PAGE_HASHPTE));
+	else
+		pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
+
+#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+	/* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we
+	 * can just store as long as we do the two halves in the right order
+	 * with a barrier in between. This is possible because we take care,
+	 * in the hash code, to pre-invalidate if the PTE was already hashed,
+	 * which synchronizes us with any concurrent invalidation.
+	 * In the percpu case, we also fallback to the simple update preserving
+	 * the hash bits
+	 */
+	if (percpu) {
+		*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+			      | (pte_val(pte) & ~_PAGE_HASHPTE));
+		return;
+	}
+#if _PAGE_HASHPTE != 0
+	if (pte_val(*ptep) & _PAGE_HASHPTE)
+		flush_hash_entry(mm, ptep, addr);
+#endif
+	__asm__ __volatile__("\
+		stw%U0%X0 %2,%0\n\
+		eieio\n\
+		stw%U0%X0 %L2,%1"
+	: "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+	: "r" (pte) : "memory");
+
+#elif defined(CONFIG_PPC_STD_MMU_32)
+	/* Third case is 32-bit hash table in UP mode, we need to preserve
+	 * the _PAGE_HASHPTE bit since we may not have invalidated the previous
+	 * translation in the hash yet (done in a subsequent flush_tlb_xxx())
+	 * and see we need to keep track that this PTE needs invalidating
+	 */
+	*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+		      | (pte_val(pte) & ~_PAGE_HASHPTE));
+
+#else
+	/* Anything else just stores the PTE normally. That covers all 64-bit
+	 * cases, and 32-bit non-hash with 64-bit PTEs in UP mode
+	 */
+	*ptep = pte;
+#endif
+}
+
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+				 pte_t *ptep, pte_t entry, int dirty);
+
 /*
  * Macro to mark a page protection value as "uncacheable".
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc32.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc32.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc32.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
-extern unsigned long ioremap_bot, ioremap_base;
+extern unsigned long ioremap_bot;
 
 #ifdef CONFIG_44x
 extern int icache_44x_need_flush;
@@ -19,55 +19,6 @@ extern int icache_44x_need_flush;
 #endif /* __ASSEMBLY__ */
 
 /*
- * The PowerPC MMU uses a hash table containing PTEs, together with
- * a set of 16 segment registers (on 32-bit implementations), to define
- * the virtual to physical address mapping.
- *
- * We use the hash table as an extended TLB, i.e. a cache of currently
- * active mappings.  We maintain a two-level page table tree, much
- * like that used by the i386, for the sake of the Linux memory
- * management code.  Low-level assembler code in hashtable.S
- * (procedure hash_page) is responsible for extracting ptes from the
- * tree and putting them into the hash table when necessary, and
- * updating the accessed and modified bits in the page table tree.
- */
-
-/*
- * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
- * We also use the two level tables, but we can put the real bits in them
- * needed for the TLB and tablewalk.  These definitions require Mx_CTR.PPM = 0,
- * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1.  The level 2 descriptor has
- * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
- * based upon user/super access.  The TLB does not have accessed nor write
- * protect.  We assume that if the TLB get loaded with an entry it is
- * accessed, and overload the changed bit for write protect.  We use
- * two bits in the software pte that are supposed to be set to zero in
- * the TLB entry (24 and 25) for these indicators.  Although the level 1
- * descriptor contains the guarded and writethrough/copyback bits, we can
- * set these at the page level since they get copied from the Mx_TWC
- * register when the TLB entry is loaded.  We will use bit 27 for guard, since
- * that is where it exists in the MD_TWC, and bit 26 for writethrough.
- * These will get masked from the level 2 descriptor at TLB load time, and
- * copied to the MD_TWC before it gets loaded.
- * Large page sizes added.  We currently support two sizes, 4K and 8M.
- * This also allows a TLB hander optimization because we can directly
- * load the PMD into MD_TWC.  The 8M pages are only used for kernel
- * mapping of well known areas.  The PMD (PGD) entries contain control
- * flags in addition to the address, so care must be taken that the
- * software no longer assumes these are only pointers.
- */
-
-/*
- * At present, all PowerPC 400-class processors share a similar TLB
- * architecture. The instruction and data sides share a unified,
- * 64-entry, fully-associative TLB which is maintained totally under
- * software control. In addition, the instruction side has a
- * hardware-managed, 4-entry, fully-associative TLB which serves as a
- * first level to the shared TLB. These two TLBs are known as the UTLB
- * and ITLB, respectively (see "mmu.h" for definitions).
- */
-
-/*
  * The normal case is that PTEs are 32-bits and we have a 1-page
  * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages.  -- paulus
  *
@@ -105,8 +56,30 @@ extern int icache_44x_need_flush;
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
 /*
+ * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
+ * value (for now) on others, from where we can start layout kernel
+ * virtual space that goes below PKMAP and FIXMAP
+ */
+#ifdef CONFIG_HIGHMEM
+#define KVIRT_TOP	PKMAP_BASE
+#else
+#define KVIRT_TOP	(0xfe000000UL)	/* for now, could be FIXMAP_BASE ? */
+#endif
+
+/*
+ * ioremap_bot starts at that address. Early ioremaps move down from there,
+ * until mem_init() at which point this becomes the top of the vmalloc
+ * and ioremap space
+ */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define IOREMAP_TOP	((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK)
+#else
+#define IOREMAP_TOP	KVIRT_TOP
+#endif
+
+/*
  * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 64MB value just means that there will be a 64MB "hole" after the
+ * current 16MB value just means that there will be a 64MB "hole" after the
  * physical memory until the kernel virtual memory starts.  That means that
  * any out-of-bounds memory accesses will hopefully be caught.
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
@@ -135,409 +108,22 @@ extern int icache_44x_need_flush;
  */
 
 #if defined(CONFIG_40x)
-
-/* There are several potential gotchas here.  The 40x hardware TLBLO
-   field looks like this:
-
-   0  1  2  3  4  ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
-   RPN.....................  0  0 EX WR ZSEL.......  W  I  M  G
-
-   Where possible we make the Linux PTE bits match up with this
-
-   - bits 20 and 21 must be cleared, because we use 4k pages (40x can
-     support down to 1k pages), this is done in the TLBMiss exception
-     handler.
-   - We use only zones 0 (for kernel pages) and 1 (for user pages)
-     of the 16 available.  Bit 24-26 of the TLB are cleared in the TLB
-     miss handler.  Bit 27 is PAGE_USER, thus selecting the correct
-     zone.
-   - PRESENT *must* be in the bottom two bits because swap cache
-     entries use the top 30 bits.  Because 40x doesn't support SMP
-     anyway, M is irrelevant so we borrow it for PAGE_PRESENT.  Bit 30
-     is cleared in the TLB miss handler before the TLB entry is loaded.
-   - All other bits of the PTE are loaded into TLBLO without
-     modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
-     software PTE bits.  We actually use use bits 21, 24, 25, and
-     30 respectively for the software bits: ACCESSED, DIRTY, RW, and
-     PRESENT.
-*/
-
-/* Definitions for 40x embedded chips. */
-#define	_PAGE_GUARDED	0x001	/* G: page is guarded from prefetch */
-#define _PAGE_FILE	0x001	/* when !present: nonlinear file mapping */
-#define _PAGE_PRESENT	0x002	/* software: PTE contains a translation */
-#define	_PAGE_NO_CACHE	0x004	/* I: caching is inhibited */
-#define	_PAGE_WRITETHRU	0x008	/* W: caching is write-through */
-#define	_PAGE_USER	0x010	/* matches one of the zone permission bits */
-#define	_PAGE_RW	0x040	/* software: Writes permitted */
-#define	_PAGE_DIRTY	0x080	/* software: dirty page */
-#define _PAGE_HWWRITE	0x100	/* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC	0x200	/* hardware: EX permission */
-#define _PAGE_ACCESSED	0x400	/* software: R: page referenced */
-
-#define _PMD_PRESENT	0x400	/* PMD points to page of PTEs */
-#define _PMD_BAD	0x802
-#define _PMD_SIZE	0x0e0	/* size field, != 0 for large-page PMD entry */
-#define _PMD_SIZE_4M	0x0c0
-#define _PMD_SIZE_16M	0x0e0
-#define PMD_PAGE_SIZE(pmdval)	(1024 << (((pmdval) & _PMD_SIZE) >> 4))
-
-/* Until my rework is finished, 40x still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES	1
-
+#include <asm/pte-40x.h>
 #elif defined(CONFIG_44x)
-/*
- * Definitions for PPC440
- *
- * Because of the 3 word TLB entries to support 36-bit addressing,
- * the attribute are difficult to map in such a fashion that they
- * are easily loaded during exception processing.  I decided to
- * organize the entry so the ERPN is the only portion in the
- * upper word of the PTE and the attribute bits below are packed
- * in as sensibly as they can be in the area below a 4KB page size
- * oriented RPN.  This at least makes it easy to load the RPN and
- * ERPN fields in the TLB. -Matt
- *
- * Note that these bits preclude future use of a page size
- * less than 4KB.
- *
- *
- * PPC 440 core has following TLB attribute fields;
- *
- *   TLB1:
- *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- *   RPN.................................  -  -  -  -  -  - ERPN.......
- *
- *   TLB2:
- *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
- *
- * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
- * TLB2 storage attibute fields. Those are:
- *
- *   TLB2:
- *   0...10    11   12   13   14   15   16...31
- *   no change WL1  IL1I IL1D IL2I IL2D no change
- *
- * There are some constrains and options, to decide mapping software bits
- * into TLB entry.
- *
- *   - PRESENT *must* be in the bottom three bits because swap cache
- *     entries use the top 29 bits for TLB2.
- *
- *   - FILE *must* be in the bottom three bits because swap cache
- *     entries use the top 29 bits for TLB2.
- *
- *   - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
- *     because it doesn't support SMP. However, some later 460 variants
- *     have -some- form of SMP support and so I keep the bit there for
- *     future use
- *
- * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
- * for memory protection related functions (see PTE structure in
- * include/asm-ppc/mmu.h).  The _PAGE_XXX definitions in this file map to the
- * above bits.  Note that the bit values are CPU specific, not architecture
- * specific.
- *
- * The kernel PTE entry holds an arch-dependent swp_entry structure under
- * certain situations. In other words, in such situations some portion of
- * the PTE bits are used as a swp_entry. In the PPC implementation, the
- * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
- * hold protection values. That means the three protection bits are
- * reserved for both PTE and SWAP entry at the most significant three
- * LSBs.
- *
- * There are three protection bits available for SWAP entry:
- *	_PAGE_PRESENT
- *	_PAGE_FILE
- *	_PAGE_HASHPTE (if HW has)
- *
- * So those three bits have to be inside of 0-2nd LSB of PTE.
- *
- */
-
-#define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
-#define _PAGE_RW	0x00000002		/* S: Write permission */
-#define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
-#define _PAGE_HWEXEC	0x00000004		/* H: Execute permission */
-#define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
-#define _PAGE_DIRTY	0x00000010		/* S: Page dirty */
-#define _PAGE_SPECIAL	0x00000020		/* S: Special page */
-#define _PAGE_USER	0x00000040		/* S: User page */
-#define _PAGE_ENDIAN	0x00000080		/* H: E bit */
-#define _PAGE_GUARDED	0x00000100		/* H: G bit */
-#define _PAGE_COHERENT	0x00000200		/* H: M bit */
-#define _PAGE_NO_CACHE	0x00000400		/* H: I bit */
-#define _PAGE_WRITETHRU	0x00000800		/* H: W bit */
-
-/* TODO: Add large page lowmem mapping support */
-#define _PMD_PRESENT	0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD	(~PAGE_MASK)
-
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK	0xffffffff00000000ULL
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
+#include <asm/pte-44x.h>
 #elif defined(CONFIG_FSL_BOOKE)
-/*
-   MMU Assist Register 3:
-
-   32 33 34 35 36  ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
-   RPN......................  0  0 U0 U1 U2 U3 UX SX UW SW UR SR
-
-   - PRESENT *must* be in the bottom three bits because swap cache
-     entries use the top 29 bits.
-
-   - FILE *must* be in the bottom three bits because swap cache
-     entries use the top 29 bits.
-*/
-
-/* Definitions for FSL Book-E Cores */
-#define _PAGE_PRESENT	0x00001	/* S: PTE contains a translation */
-#define _PAGE_USER	0x00002	/* S: User page (maps to UR) */
-#define _PAGE_FILE	0x00002	/* S: when !present: nonlinear file mapping */
-#define _PAGE_RW	0x00004	/* S: Write permission (SW) */
-#define _PAGE_DIRTY	0x00008	/* S: Page dirty */
-#define _PAGE_HWEXEC	0x00010	/* H: SX permission */
-#define _PAGE_ACCESSED	0x00020	/* S: Page referenced */
-
-#define _PAGE_ENDIAN	0x00040	/* H: E bit */
-#define _PAGE_GUARDED	0x00080	/* H: G bit */
-#define _PAGE_COHERENT	0x00100	/* H: M bit */
-#define _PAGE_NO_CACHE	0x00200	/* H: I bit */
-#define _PAGE_WRITETHRU	0x00400	/* H: W bit */
-#define _PAGE_SPECIAL	0x00800 /* S: Special page */
-
-#ifdef CONFIG_PTE_64BIT
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK	0xffffffffffff0000ULL
-#endif
-
-#define _PMD_PRESENT	0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD	(~PAGE_MASK)
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
+#include <asm/pte-fsl-booke.h>
 #elif defined(CONFIG_8xx)
-/* Definitions for 8xx embedded chips. */
-#define _PAGE_PRESENT	0x0001	/* Page is valid */
-#define _PAGE_FILE	0x0002	/* when !present: nonlinear file mapping */
-#define _PAGE_NO_CACHE	0x0002	/* I: cache inhibit */
-#define _PAGE_SHARED	0x0004	/* No ASID (context) compare */
-
-/* These five software bits must be masked out when the entry is loaded
- * into the TLB.
- */
-#define _PAGE_EXEC	0x0008	/* software: i-cache coherency required */
-#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 */
-
-/* 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 _PMD_PRESENT	0x0001
-#define _PMD_BAD	0x0ff0
-#define _PMD_PAGE_MASK	0x000c
-#define _PMD_PAGE_8M	0x000c
-
-#define _PTE_NONE_MASK _PAGE_ACCESSED
-
-/* Until my rework is finished, 8xx still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES	1
-
+#include <asm/pte-8xx.h>
 #else /* CONFIG_6xx */
-/* Definitions for 60x, 740/750, etc. */
-#define _PAGE_PRESENT	0x001	/* software: pte contains a translation */
-#define _PAGE_HASHPTE	0x002	/* hash_page has made an HPTE for this pte */
-#define _PAGE_FILE	0x004	/* when !present: nonlinear file mapping */
-#define _PAGE_USER	0x004	/* usermode access allowed */
-#define _PAGE_GUARDED	0x008	/* G: prohibit speculative access */
-#define _PAGE_COHERENT	0x010	/* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE	0x020	/* I: cache inhibit */
-#define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
-#define _PAGE_DIRTY	0x080	/* C: page changed */
-#define _PAGE_ACCESSED	0x100	/* R: page referenced */
-#define _PAGE_EXEC	0x200	/* software: i-cache coherency required */
-#define _PAGE_RW	0x400	/* software: user write access allowed */
-#define _PAGE_SPECIAL	0x800	/* software: Special page */
-
-#ifdef CONFIG_PTE_64BIT
-/* We never clear the high word of the pte */
-#define _PTE_NONE_MASK	(0xffffffff00000000ULL | _PAGE_HASHPTE)
-#else
-#define _PTE_NONE_MASK	_PAGE_HASHPTE
-#endif
-
-#define _PMD_PRESENT	0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD	(~PAGE_MASK)
-
-/* Hash table based platforms need atomic updates of the linux PTE */
-#define PTE_ATOMIC_UPDATES	1
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
-#endif
-
-/*
- * Some bits are only used on some cpu families...
- */
-#ifndef _PAGE_HASHPTE
-#define _PAGE_HASHPTE	0
-#endif
-#ifndef _PTE_NONE_MASK
-#define _PTE_NONE_MASK 0
-#endif
-#ifndef _PAGE_SHARED
-#define _PAGE_SHARED	0
-#endif
-#ifndef _PAGE_HWWRITE
-#define _PAGE_HWWRITE	0
-#endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC	0
-#endif
-#ifndef _PAGE_EXEC
-#define _PAGE_EXEC	0
-#endif
-#ifndef _PAGE_ENDIAN
-#define _PAGE_ENDIAN	0
-#endif
-#ifndef _PAGE_COHERENT
-#define _PAGE_COHERENT	0
-#endif
-#ifndef _PAGE_WRITETHRU
-#define _PAGE_WRITETHRU	0
-#endif
-#ifndef _PAGE_SPECIAL
-#define _PAGE_SPECIAL	0
-#endif
-#ifndef _PMD_PRESENT_MASK
-#define _PMD_PRESENT_MASK	_PMD_PRESENT
-#endif
-#ifndef _PMD_SIZE
-#define _PMD_SIZE	0
-#define PMD_PAGE_SIZE(pmd)	bad_call_to_PMD_PAGE_SIZE()
-#endif
-
-#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
-			 _PAGE_SPECIAL)
-
-
-#define PAGE_PROT_BITS	(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
-			 _PAGE_WRITETHRU | _PAGE_ENDIAN | \
-			 _PAGE_USER | _PAGE_ACCESSED | \
-			 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
-			 _PAGE_EXEC | _PAGE_HWEXEC)
-
-/*
- * We define 2 sets of base prot bits, one for basic pages (ie,
- * cacheable kernel and user pages) and one for non cacheable
- * pages. We always set _PAGE_COHERENT when SMP is enabled or
- * the processor might need it for DMA coherency.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
-#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-#else
-#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED)
-#endif
-#define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE)
-
-#define _PAGE_WRENABLE	(_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
-#define _PAGE_KERNEL	(_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
-#define _PAGE_KERNEL_NC	(_PAGE_BASE_NC | _PAGE_SHARED | _PAGE_WRENABLE)
-
-#ifdef CONFIG_PPC_STD_MMU
-/* On standard PPC MMU, no user access implies kernel read/write access,
- * so to write-protect kernel memory we must turn on user access */
-#define _PAGE_KERNEL_RO	(_PAGE_BASE | _PAGE_SHARED | _PAGE_USER)
-#else
-#define _PAGE_KERNEL_RO	(_PAGE_BASE | _PAGE_SHARED)
-#endif
-
-#define _PAGE_IO	(_PAGE_KERNEL_NC | _PAGE_GUARDED)
-#define _PAGE_RAM	(_PAGE_KERNEL | _PAGE_HWEXEC)
-
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
-	defined(CONFIG_KPROBES)
-/* We want the debuggers to be able to set breakpoints anywhere, so
- * don't write protect the kernel text */
-#define _PAGE_RAM_TEXT	_PAGE_RAM
-#else
-#define _PAGE_RAM_TEXT	(_PAGE_KERNEL_RO | _PAGE_HWEXEC)
+#include <asm/pte-hash32.h>
 #endif
 
-#define PAGE_NONE	__pgprot(_PAGE_BASE)
-#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
-#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
-#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-
-#define PAGE_KERNEL		__pgprot(_PAGE_RAM)
-#define PAGE_KERNEL_NOCACHE	__pgprot(_PAGE_IO)
-
-/*
- * The PowerPC can only do execute protection on a segment (256MB) basis,
- * not on a page basis.  So we consider execute permission the same as read.
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- */
-#define __P000	PAGE_NONE
-#define __P001	PAGE_READONLY_X
-#define __P010	PAGE_COPY
-#define __P011	PAGE_COPY_X
-#define __P100	PAGE_READONLY
-#define __P101	PAGE_READONLY_X
-#define __P110	PAGE_COPY
-#define __P111	PAGE_COPY_X
-
-#define __S000	PAGE_NONE
-#define __S001	PAGE_READONLY_X
-#define __S010	PAGE_SHARED
-#define __S011	PAGE_SHARED_X
-#define __S100	PAGE_READONLY
-#define __S101	PAGE_READONLY_X
-#define __S110	PAGE_SHARED
-#define __S111	PAGE_SHARED_X
+/* And here we include common definitions */
+#include <asm/pte-common.h>
 
 #ifndef __ASSEMBLY__
-/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
- * kernel without large page PMD support */
-extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 
-/*
- * Conversions between PTE values and page frame numbers.
- */
-
-/* in some case we want to additionaly adjust where the pfn is in the pte to
- * allow room for more flags */
-#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
-#define PFN_SHIFT_OFFSET	(PAGE_SHIFT + 8)
-#else
-#define PFN_SHIFT_OFFSET	(PAGE_SHIFT)
-#endif
-
-#define pte_pfn(x)		(pte_val(x) >> PFN_SHIFT_OFFSET)
-#define pte_page(x)		pfn_to_page(pte_pfn(x))
-
-#define pfn_pte(pfn, prot)	__pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\
-					pgprot_val(prot))
-#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
-#endif /* __ASSEMBLY__ */
-
-#define pte_none(pte)		((pte_val(pte) & ~_PTE_NONE_MASK) == 0)
-#define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
 #define pte_clear(mm, addr, ptep) \
 	do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
 
@@ -546,43 +132,6 @@ extern unsigned long bad_call_to_PMD_PAG
 #define	pmd_present(pmd)	(pmd_val(pmd) & _PMD_PRESENT_MASK)
 #define	pmd_clear(pmdp)		do { pmd_val(*(pmdp)) = 0; } while (0)
 
-#ifndef __ASSEMBLY__
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
-static inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
-static inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
-static inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
-static inline int pte_special(pte_t pte)	{ return pte_val(pte) & _PAGE_SPECIAL; }
-
-static inline pte_t pte_wrprotect(pte_t pte) {
-	pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
-	pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
-	pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-
-static inline pte_t pte_mkwrite(pte_t pte) {
-	pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
-	pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
-	pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) {
-	pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline pgprot_t pte_pgprot(pte_t pte)
-{
-	return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
-}
-
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
-	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
-	return pte;
-}
-
 /*
  * When flushing the tlb entry for a page, we also need to flush the hash
  * table entry.  flush_hash_pages is assembler (for speed) in hashtable.S.
@@ -599,11 +148,19 @@ extern void flush_hash_entry(struct mm_s
 			     unsigned long address);
 
 /*
- * Atomic PTE updates.
+ * PTE updates. This function is called whenever an existing
+ * valid PTE is updated. This does -not- include set_pte_at()
+ * which nowadays only sets a new PTE.
  *
- * pte_update clears and sets bit atomically, and returns
- * the old pte value.  In the 64-bit PTE case we lock around the
- * low PTE word since we expect ALL flag bits to be there
+ * Depending on the type of MMU, we may need to use atomic updates
+ * and the PTE may be either 32 or 64 bit wide. In the later case,
+ * when using atomic updates, only the low part of the PTE is
+ * accessed atomically.
+ *
+ * In addition, on 44x, we also maintain a global flag indicating
+ * that an executable user mapping was modified, which is needed
+ * to properly flush the virtually tagged instruction cache of
+ * those implementations.
  */
 #ifndef CONFIG_PTE_64BIT
 static inline unsigned long pte_update(pte_t *p,
@@ -668,44 +225,6 @@ static inline unsigned long long pte_upd
 #endif /* CONFIG_PTE_64BIT */
 
 /*
- * set_pte stores a linux PTE into the linux page table.
- * On machines which use an MMU hash table we avoid changing the
- * _PAGE_HASHPTE bit.
- */
-
-static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep, pte_t pte)
-{
-#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
-	pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
-#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
-#if _PAGE_HASHPTE != 0
-	if (pte_val(*ptep) & _PAGE_HASHPTE)
-		flush_hash_entry(mm, ptep, addr);
-#endif
-	__asm__ __volatile__("\
-		stw%U0%X0 %2,%0\n\
-		eieio\n\
-		stw%U0%X0 %L2,%1"
-	: "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
-	: "r" (pte) : "memory");
-#else
-	*ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
-		      | (pte_val(pte) & ~_PAGE_HASHPTE));
-#endif
-}
-
-
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep, pte_t pte)
-{
-#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_DEBUG_VM)
-	WARN_ON(pte_present(*ptep));
-#endif
-	__set_pte_at(mm, addr, ptep, pte);
-}
-
-/*
  * 2.6 calls this without flushing the TLB entry; this is wrong
  * for our hash-based implementation, we fix that up here.
  */
@@ -745,24 +264,14 @@ static inline void huge_ptep_set_wrprote
 }
 
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
 	unsigned long bits = pte_val(entry) &
-		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
+		 _PAGE_HWEXEC | _PAGE_EXEC);
 	pte_update(ptep, 0, bits);
 }
 
-#define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({									   \
-	int __changed = !pte_same(*(__ptep), __entry);			   \
-	if (__changed) {						   \
-		__ptep_set_access_flags(__ptep, __entry, __dirty);         \
-		flush_tlb_page_nohash(__vma, __address);		   \
-	}								   \
-	__changed;							   \
-})
-
 #define __HAVE_ARCH_PTE_SAME
 #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64-4k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64-4k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64-4k.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64-4k.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,74 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_4K_H
+#define _ASM_POWERPC_PGTABLE_PPC64_4K_H
+/*
+ * Entries per page directory level.  The PTE level must use a 64b record
+ * for each page table entry.  The PMD and PGD level use a 32b record for
+ * each entry by assuming that each entry is page aligned.
+ */
+#define PTE_INDEX_SIZE  9
+#define PMD_INDEX_SIZE  7
+#define PUD_INDEX_SIZE  7
+#define PGD_INDEX_SIZE  9
+
+#ifndef __ASSEMBLY__
+#define PTE_TABLE_SIZE	(sizeof(pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE	(sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PUD_TABLE_SIZE	(sizeof(pud_t) << PUD_INDEX_SIZE)
+#define PGD_TABLE_SIZE	(sizeof(pgd_t) << PGD_INDEX_SIZE)
+#endif	/* __ASSEMBLY__ */
+
+#define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PUD	(1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT	(PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT	PMD_SHIFT
+
+/* PUD_SHIFT determines what a third-level page table entry can map */
+#define PUD_SHIFT	(PMD_SHIFT + PMD_INDEX_SIZE)
+#define PUD_SIZE	(1UL << PUD_SHIFT)
+#define PUD_MASK	(~(PUD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
+#define PGDIR_SHIFT	(PUD_SHIFT + PUD_INDEX_SIZE)
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS		0
+/* Bits to mask out from a PUD to get to the PMD page */
+#define PUD_MASKED_BITS		0
+/* Bits to mask out from a PGD to get to the PUD page */
+#define PGD_MASKED_BITS		0
+
+
+/*
+ * 4-level page tables related bits
+ */
+
+#define pgd_none(pgd)		(!pgd_val(pgd))
+#define pgd_bad(pgd)		(pgd_val(pgd) == 0)
+#define pgd_present(pgd)	(pgd_val(pgd) != 0)
+#define pgd_clear(pgdp)		(pgd_val(*(pgdp)) = 0)
+#define pgd_page_vaddr(pgd)	(pgd_val(pgd) & ~PGD_MASKED_BITS)
+#define pgd_page(pgd)		virt_to_page(pgd_page_vaddr(pgd))
+
+#define pud_offset(pgdp, addr)	\
+  (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
+    (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
+
+#define pud_ERROR(e) \
+	printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+
+/*
+ * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */
+#define remap_4k_pfn(vma, addr, pfn, prot)	\
+	remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_4K_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64-64k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64-64k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64-64k.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64-64k.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_64K_H
+#define _ASM_POWERPC_PGTABLE_PPC64_64K_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+
+#define PTE_INDEX_SIZE  12
+#define PMD_INDEX_SIZE  12
+#define PUD_INDEX_SIZE	0
+#define PGD_INDEX_SIZE  4
+
+#ifndef __ASSEMBLY__
+
+#define PTE_TABLE_SIZE	(sizeof(real_pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE	(sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PGD_TABLE_SIZE	(sizeof(pgd_t) << PGD_INDEX_SIZE)
+
+#define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD	(1 << PGD_INDEX_SIZE)
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT	PAGE_SHIFT
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT	(PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	(PMD_SHIFT + PMD_INDEX_SIZE)
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+#endif	/* __ASSEMBLY__ */
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS		0x1ff
+/* Bits to mask out from a PGD/PUD to get to the PMD page */
+#define PUD_MASKED_BITS		0x1ff
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pgtable-ppc64.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,9 +11,9 @@
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pgtable-64k.h>
+#include <asm/pgtable-ppc64-64k.h>
 #else
-#include <asm/pgtable-4k.h>
+#include <asm/pgtable-ppc64-4k.h>
 #endif
 
 #define FIRST_USER_ADDRESS	0
@@ -25,6 +25,8 @@
                 	    PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
 #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
 
+
+/* Some sanity checking */
 #if TASK_SIZE_USER64 > PGTABLE_RANGE
 #error TASK_SIZE_USER64 exceeds pagetable range
 #endif
@@ -33,7 +35,6 @@
 #error TASK_SIZE_USER64 exceeds user VSID range
 #endif
 
-
 /*
  * Define the address range of the vmalloc VM area.
  */
@@ -76,82 +77,11 @@
 
 
 /*
- * Common bits in a linux-style PTE.  These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible. Additional
- * bits may be defined in pgtable-*.h
- */
-#define _PAGE_PRESENT	0x0001 /* software: pte contains a translation */
-#define _PAGE_USER	0x0002 /* matches one of the PP bits */
-#define _PAGE_FILE	0x0002 /* (!present only) software: pte holds file offset */
-#define _PAGE_EXEC	0x0004 /* No execute on POWER4 and newer (we invert) */
-#define _PAGE_GUARDED	0x0008
-#define _PAGE_COHERENT	0x0010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE	0x0020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU	0x0040 /* W: cache write-through */
-#define _PAGE_DIRTY	0x0080 /* C: page changed */
-#define _PAGE_ACCESSED	0x0100 /* R: page referenced */
-#define _PAGE_RW	0x0200 /* software: user write access allowed */
-#define _PAGE_BUSY	0x0800 /* software: PTE & hash are busy */
-
-/* Strong Access Ordering */
-#define _PAGE_SAO	(_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
-
-#define _PAGE_BASE	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-
-#define _PAGE_WRENABLE	(_PAGE_RW | _PAGE_DIRTY)
-
-/* __pgprot defined in arch/powerpc/include/asm/page.h */
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-
-#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
-#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_KERNEL	__pgprot(_PAGE_BASE | _PAGE_WRENABLE)
-#define PAGE_KERNEL_CI	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
-			       _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
-
-#define PAGE_AGP	__pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
-#define HAVE_PAGE_AGP
-
-#define PAGE_PROT_BITS	(_PAGE_GUARDED | _PAGE_COHERENT | \
-			 _PAGE_NO_CACHE | _PAGE_WRITETHRU |		\
-			 _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER |		\
-			 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC)
-/* PTEIDX nibble */
-#define _PTEIDX_SECONDARY	0x8
-#define _PTEIDX_GROUP_IX	0x7
-
-
-/*
- * POWER4 and newer have per page execute protection, older chips can only
- * do this on a segment (256MB) basis.
- *
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- *
- * Note due to the way vm flags are laid out, the bits are XWR
+ * Include the PTE bits definitions
  */
-#define __P000	PAGE_NONE
-#define __P001	PAGE_READONLY
-#define __P010	PAGE_COPY
-#define __P011	PAGE_COPY
-#define __P100	PAGE_READONLY_X
-#define __P101	PAGE_READONLY_X
-#define __P110	PAGE_COPY_X
-#define __P111	PAGE_COPY_X
+#include <asm/pte-hash64.h>
+#include <asm/pte-common.h>
 
-#define __S000	PAGE_NONE
-#define __S001	PAGE_READONLY
-#define __S010	PAGE_SHARED
-#define __S011	PAGE_SHARED
-#define __S100	PAGE_READONLY_X
-#define __S101	PAGE_READONLY_X
-#define __S110	PAGE_SHARED_X
-#define __S111	PAGE_SHARED_X
 
 #ifdef CONFIG_PPC_MM_SLICES
 #define HAVE_ARCH_UNMAPPED_AREA
@@ -161,32 +91,38 @@
 #ifndef __ASSEMBLY__
 
 /*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- *
- * mk_pte takes a (struct page *) as input
+ * This is the default implementation of various PTE accessors, it's
+ * used in all cases except Book3S with 64K pages where we have a
+ * concept of sub-pages
  */
-#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
+#ifndef __real_pte
 
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
-	pte_t pte;
+#ifdef STRICT_MM_TYPECHECKS
+#define __real_pte(e,p)		((real_pte_t){(e)})
+#define __rpte_to_pte(r)	((r).pte)
+#else
+#define __real_pte(e,p)		(e)
+#define __rpte_to_pte(r)	(__pte(r))
+#endif
+#define __rpte_to_hidx(r,index)	(pte_val(__rpte_to_pte(r)) >> 12)
 
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)       \
+	do {							         \
+		index = 0;					         \
+		shift = mmu_psize_defs[psize].shift;		         \
 
-	pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
-	return pte;
-}
+#define pte_iterate_hashed_end() } while(0)
 
-#define pte_modify(_pte, newprot) \
-  (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+#ifdef CONFIG_PPC_HAS_HASH_64K
+#define pte_pagesize_index(mm, addr, pte)	get_slice_psize(mm, addr)
+#else
+#define pte_pagesize_index(mm, addr, pte)	MMU_PAGE_4K
+#endif
 
-#define pte_none(pte)		((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
-#define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+#endif /* __real_pte */
 
-/* pte_clear moved to later in this file */
 
-#define pte_pfn(x)		((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
-#define pte_page(x)		pfn_to_page(pte_pfn(x))
+/* pte_clear moved to later in this file */
 
 #define PMD_BAD_BITS		(PTE_TABLE_SIZE-1)
 #define PUD_BAD_BITS		(PMD_TABLE_SIZE-1)
@@ -235,36 +171,6 @@ static inline pte_t pfn_pte(unsigned lon
 /* This now only contains the vmalloc pages */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
-static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
-
-static inline pte_t pte_wrprotect(pte_t pte) {
-	pte_val(pte) &= ~(_PAGE_RW); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
-	pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
-	pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkwrite(pte_t pte) {
-	pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
-	pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
-	pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkhuge(pte_t pte) {
-	return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) {
-	pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline pgprot_t pte_pgprot(pte_t pte)
-{
-	return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
-}
 
 /* Atomic PTE updates */
 static inline unsigned long pte_update(struct mm_struct *mm,
@@ -272,6 +178,7 @@ static inline unsigned long pte_update(s
 				       pte_t *ptep, unsigned long clr,
 				       int huge)
 {
+#ifdef PTE_ATOMIC_UPDATES
 	unsigned long old, tmp;
 
 	__asm__ __volatile__(
@@ -284,6 +191,13 @@ static inline unsigned long pte_update(s
 	: "=&r" (old), "=&r" (tmp), "=m" (*ptep)
 	: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
 	: "cc" );
+#else
+	unsigned long old = pte_val(*ptep);
+	*ptep = __pte(old & ~clr);
+#endif
+	/* huge pages use the old page table lock */
+	if (!huge)
+		assert_pte_locked(mm, addr);
 
 	if (old & _PAGE_HASHPTE)
 		hpte_need_flush(mm, addr, ptep, old, huge);
@@ -359,26 +273,17 @@ static inline void pte_clear(struct mm_s
 	pte_update(mm, addr, ptep, ~0UL, 0);
 }
 
-/*
- * set_pte stores a linux PTE into the linux page table.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep, pte_t pte)
-{
-	if (pte_present(*ptep))
-		pte_clear(mm, addr, ptep);
-	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
-	*ptep = pte;
-}
 
 /* Set the dirty and/or accessed bits atomically in a linux PTE, this
  * function doesn't need to flush the hash entry
  */
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
 	unsigned long bits = pte_val(entry) &
-		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
+		 _PAGE_EXEC | _PAGE_HWEXEC);
+
+#ifdef PTE_ATOMIC_UPDATES
 	unsigned long old, tmp;
 
 	__asm__ __volatile__(
@@ -391,16 +296,11 @@ static inline void __ptep_set_access_fla
 	:"=&r" (old), "=&r" (tmp), "=m" (*ptep)
 	:"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
 	:"cc");
+#else
+	unsigned long old = pte_val(*ptep);
+	*ptep = __pte(old | bits);
+#endif
 }
-#define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({									   \
-	int __changed = !pte_same(*(__ptep), __entry);			   \
-	if (__changed) {						   \
-		__ptep_set_access_flags(__ptep, __entry, __dirty);    	   \
-		flush_tlb_page_nohash(__vma, __address);		   \
-	}								   \
-	__changed;							   \
-})
 
 #define __HAVE_ARCH_PTE_SAME
 #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ppc_asm.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ppc_asm.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ppc_asm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ppc_asm.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,9 +4,11 @@
 #ifndef _ASM_POWERPC_PPC_ASM_H
 #define _ASM_POWERPC_PPC_ASM_H
 
+#include <linux/init.h>
 #include <linux/stringify.h>
 #include <asm/asm-compat.h>
 #include <asm/processor.h>
+#include <asm/ppc-opcode.h>
 
 #ifndef __ASSEMBLY__
 #error __FILE__ should only be used in assembler files
@@ -167,11 +169,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
 #define HMT_MEDIUM_HIGH or	5,5,5		# medium high priority
 #define HMT_HIGH	or	3,3,3
 
-/* handle instructions that older assemblers may not know */
-#define RFCI		.long 0x4c000066	/* rfci instruction */
-#define RFDI		.long 0x4c00004e	/* rfdi instruction */
-#define RFMCI		.long 0x4c00004c	/* rfmci instruction */
-
 #ifdef __KERNEL__
 #ifdef CONFIG_PPC64
 
@@ -193,7 +190,7 @@ name: \
 GLUE(.,name):
 
 #define _INIT_GLOBAL(name) \
-	.section ".text.init.refok"; \
+	__REF; \
 	.align 2 ; \
 	.globl name; \
 	.globl GLUE(.,name); \
@@ -233,7 +230,7 @@ name: \
 GLUE(.,name):
 
 #define _INIT_STATIC(name) \
-	.section ".text.init.refok"; \
+	__REF; \
 	.align 2 ; \
 	.section ".opd","aw"; \
 name: \
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ppc-opcode.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ppc-opcode.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ppc-opcode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ppc-opcode.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009 Freescale Semicondutor, 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.
+ *
+ * provides masks and opcode images for use by code generation, emulation
+ * and for instructions that older assemblers might not know about
+ */
+#ifndef _ASM_POWERPC_PPC_OPCODE_H
+#define _ASM_POWERPC_PPC_OPCODE_H
+
+#include <linux/stringify.h>
+#include <asm/asm-compat.h>
+
+/* sorted alphabetically */
+#define PPC_INST_DCBA			0x7c0005ec
+#define PPC_INST_DCBA_MASK		0xfc0007fe
+#define PPC_INST_DCBAL			0x7c2005ec
+#define PPC_INST_DCBZL			0x7c2007ec
+#define PPC_INST_ISEL			0x7c00001e
+#define PPC_INST_ISEL_MASK		0xfc00003e
+#define PPC_INST_LSWI			0x7c0004aa
+#define PPC_INST_LSWX			0x7c00042a
+#define PPC_INST_LWSYNC			0x7c2004ac
+#define PPC_INST_MCRXR			0x7c000400
+#define PPC_INST_MCRXR_MASK		0xfc0007fe
+#define PPC_INST_MFSPR_PVR		0x7c1f42a6
+#define PPC_INST_MFSPR_PVR_MASK		0xfc1fffff
+#define PPC_INST_MSGSND			0x7c00019c
+#define PPC_INST_NOP			0x60000000
+#define PPC_INST_POPCNTB		0x7c0000f4
+#define PPC_INST_POPCNTB_MASK		0xfc0007fe
+#define PPC_INST_RFCI			0x4c000066
+#define PPC_INST_RFDI			0x4c00004e
+#define PPC_INST_RFMCI			0x4c00004c
+
+#define PPC_INST_STRING			0x7c00042a
+#define PPC_INST_STRING_MASK		0xfc0007fe
+#define PPC_INST_STRING_GEN_MASK	0xfc00067e
+
+#define PPC_INST_STSWI			0x7c0005aa
+#define PPC_INST_STSWX			0x7c00052a
+#define PPC_INST_TLBILX			0x7c000024
+#define PPC_INST_WAIT			0x7c00007c
+
+/* macros to insert fields into opcodes */
+#define __PPC_RA(a)	((a & 0x1f) << 16)
+#define __PPC_RB(b)	((b & 0x1f) << 11)
+#define __PPC_T_TLB(t)	((t & 0x3) << 21)
+#define __PPC_WC(w)	((w & 0x3) << 21)
+
+/* Deal with instructions that older assemblers aren't aware of */
+#define	PPC_DCBAL(a, b)		stringify_in_c(.long PPC_INST_DCBAL | \
+					__PPC_RA(a) | __PPC_RB(b))
+#define	PPC_DCBZL(a, b)		stringify_in_c(.long PPC_INST_DCBZL | \
+					__PPC_RA(a) | __PPC_RB(b))
+#define PPC_MSGSND(b)		stringify_in_c(.long PPC_INST_MSGSND | \
+					__PPC_RB(b))
+#define PPC_RFCI		stringify_in_c(.long PPC_INST_RFCI)
+#define PPC_RFDI		stringify_in_c(.long PPC_INST_RFDI)
+#define PPC_RFMCI		stringify_in_c(.long PPC_INST_RFMCI)
+#define PPC_TLBILX(t, a, b)	stringify_in_c(.long PPC_INST_TLBILX | \
+					__PPC_T_TLB(t) | __PPC_RA(a) | __PPC_RB(b))
+#define PPC_TLBILX_ALL(a, b)	PPC_TLBILX(0, a, b)
+#define PPC_TLBILX_PID(a, b)	PPC_TLBILX(1, a, b)
+#define PPC_TLBILX_VA(a, b)	PPC_TLBILX(3, a, b)
+#define PPC_WAIT(w)		stringify_in_c(.long PPC_INST_WAIT | \
+					__PPC_WC(w))
+
+#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/processor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -313,6 +313,25 @@ static inline void prefetchw(const void
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 #endif
 
+#ifdef CONFIG_PPC64
+static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+{
+	unsigned long sp;
+
+	if (is_32)
+		sp = regs->gpr[1] & 0x0ffffffffUL;
+	else
+		sp = regs->gpr[1];
+
+	return sp;
+}
+#else
+static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+{
+	return regs->gpr[1];
+}
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PROCESSOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3av.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3av.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3av.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3av.h	2009-06-09 23:05:27.000000000 -0400
@@ -730,7 +730,7 @@ extern int ps3av_cmd_av_get_hw_conf(stru
 extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
 					    u32);
 
-extern int ps3av_set_video_mode(u32);
+extern int ps3av_set_video_mode(int);
 extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
 extern int ps3av_get_auto_mode(void);
 extern int ps3av_get_mode(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3fb.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3fb.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3fb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3fb.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #ifndef _ASM_POWERPC_PS3FB_H_
 #define _ASM_POWERPC_PS3FB_H_
 
+#include <linux/types.h>
 #include <linux/ioctl.h>
 
 /* ioctl */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/ps3.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/ps3.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,9 @@ enum ps3_param_av_multi_out {
 
 enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
 
+extern u64 ps3_os_area_get_rtc_diff(void);
+extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
+
 /* dma routines */
 
 enum ps3_dma_page_size {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-40x.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-40x.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-40x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-40x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,64 @@
+#ifndef _ASM_POWERPC_PTE_40x_H
+#define _ASM_POWERPC_PTE_40x_H
+#ifdef __KERNEL__
+
+/*
+ * At present, all PowerPC 400-class processors share a similar TLB
+ * architecture. The instruction and data sides share a unified,
+ * 64-entry, fully-associative TLB which is maintained totally under
+ * software control. In addition, the instruction side has a
+ * hardware-managed, 4-entry, fully-associative TLB which serves as a
+ * first level to the shared TLB. These two TLBs are known as the UTLB
+ * and ITLB, respectively (see "mmu.h" for definitions).
+ *
+ * There are several potential gotchas here.  The 40x hardware TLBLO
+ * field looks like this:
+ *
+ * 0  1  2  3  4  ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN.....................  0  0 EX WR ZSEL.......  W  I  M  G
+ *
+ * Where possible we make the Linux PTE bits match up with this
+ *
+ * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
+ *   support down to 1k pages), this is done in the TLBMiss exception
+ *   handler.
+ * - We use only zones 0 (for kernel pages) and 1 (for user pages)
+ *   of the 16 available.  Bit 24-26 of the TLB are cleared in the TLB
+ *   miss handler.  Bit 27 is PAGE_USER, thus selecting the correct
+ *   zone.
+ * - PRESENT *must* be in the bottom two bits because swap cache
+ *   entries use the top 30 bits.  Because 40x doesn't support SMP
+ *   anyway, M is irrelevant so we borrow it for PAGE_PRESENT.  Bit 30
+ *   is cleared in the TLB miss handler before the TLB entry is loaded.
+ * - All other bits of the PTE are loaded into TLBLO without
+ *   modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
+ *   software PTE bits.  We actually use use bits 21, 24, 25, and
+ *   30 respectively for the software bits: ACCESSED, DIRTY, RW, and
+ *   PRESENT.
+ */
+
+#define	_PAGE_GUARDED	0x001	/* G: page is guarded from prefetch */
+#define _PAGE_FILE	0x001	/* when !present: nonlinear file mapping */
+#define _PAGE_PRESENT	0x002	/* software: PTE contains a translation */
+#define	_PAGE_NO_CACHE	0x004	/* I: caching is inhibited */
+#define	_PAGE_WRITETHRU	0x008	/* W: caching is write-through */
+#define	_PAGE_USER	0x010	/* matches one of the zone permission bits */
+#define	_PAGE_RW	0x040	/* software: Writes permitted */
+#define	_PAGE_DIRTY	0x080	/* software: dirty page */
+#define _PAGE_HWWRITE	0x100	/* hardware: Dirty & RW, set in exception */
+#define _PAGE_HWEXEC	0x200	/* hardware: EX permission */
+#define _PAGE_ACCESSED	0x400	/* software: R: page referenced */
+
+#define _PMD_PRESENT	0x400	/* PMD points to page of PTEs */
+#define _PMD_BAD	0x802
+#define _PMD_SIZE	0x0e0	/* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M	0x0c0
+#define _PMD_SIZE_16M	0x0e0
+
+#define PMD_PAGE_SIZE(pmdval)	(1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES	1
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_40x_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-44x.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-44x.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-44x.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-44x.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,102 @@
+#ifndef _ASM_POWERPC_PTE_44x_H
+#define _ASM_POWERPC_PTE_44x_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing.  I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN.  This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * This isn't entirely true anymore, at least some bits are now
+ * easier to move into the TLB from the PTE. -BenH.
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ *   TLB1:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   RPN.................................  -  -  -  -  -  - ERPN.......
+ *
+ *   TLB2:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
+ *
+ * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
+ * TLB2 storage attibute fields. Those are:
+ *
+ *   TLB2:
+ *   0...10    11   12   13   14   15   16...31
+ *   no change WL1  IL1I IL1D IL2I IL2D no change
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ *   - PRESENT *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - FILE *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
+ *     because it doesn't support SMP. However, some later 460 variants
+ *     have -some- form of SMP support and so I keep the bit there for
+ *     future use
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h).  The _PAGE_XXX definitions in this file map to the
+ * above bits.  Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ *	_PAGE_PRESENT
+ *	_PAGE_FILE
+ *	_PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
+ */
+
+#define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
+#define _PAGE_RW	0x00000002		/* S: Write permission */
+#define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
+#define _PAGE_HWEXEC	0x00000004		/* H: Execute permission */
+#define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
+#define _PAGE_DIRTY	0x00000010		/* S: Page dirty */
+#define _PAGE_SPECIAL	0x00000020		/* S: Special page */
+#define _PAGE_USER	0x00000040		/* S: User page */
+#define _PAGE_ENDIAN	0x00000080		/* H: E bit */
+#define _PAGE_GUARDED	0x00000100		/* H: G bit */
+#define _PAGE_COHERENT	0x00000200		/* H: M bit */
+#define _PAGE_NO_CACHE	0x00000400		/* H: I bit */
+#define _PAGE_WRITETHRU	0x00000800		/* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT	0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD	(~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK	0xffffffff00000000ULL
+
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_44x_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-8xx.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-8xx.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-8xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-8xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+#ifndef _ASM_POWERPC_PTE_8xx_H
+#define _ASM_POWERPC_PTE_8xx_H
+#ifdef __KERNEL__
+
+/*
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk.  These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1.  The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access.  The TLB does not have accessed nor write
+ * protect.  We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect.  We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators.  Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded.  We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ * Large page sizes added.  We currently support two sizes, 4K and 8M.
+ * This also allows a TLB hander optimization because we can directly
+ * load the PMD into MD_TWC.  The 8M pages are only used for kernel
+ * mapping of well known areas.  The PMD (PGD) entries contain control
+ * flags in addition to the address, so care must be taken that the
+ * software no longer assumes these are only pointers.
+ */
+
+/* Definitions for 8xx embedded chips. */
+#define _PAGE_PRESENT	0x0001	/* Page is valid */
+#define _PAGE_FILE	0x0002	/* when !present: nonlinear file mapping */
+#define _PAGE_NO_CACHE	0x0002	/* I: cache inhibit */
+#define _PAGE_SHARED	0x0004	/* No ASID (context) compare */
+
+/* These five software bits must be masked out when the entry is loaded
+ * into the TLB.
+ */
+#define _PAGE_EXEC	0x0008	/* software: i-cache coherency required */
+#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 */
+
+/* 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 _PMD_PRESENT	0x0001
+#define _PMD_BAD	0x0ff0
+#define _PMD_PAGE_MASK	0x000c
+#define _PMD_PAGE_8M	0x000c
+
+#define _PTE_NONE_MASK _PAGE_ACCESSED
+
+/* Until my rework is finished, 8xx still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES	1
+
+/* We need to add _PAGE_SHARED to kernel pages */
+#define _PAGE_KERNEL_RO	(_PAGE_SHARED)
+#define _PAGE_KERNEL_RW	(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_8xx_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-common.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-common.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-common.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,182 @@
+/* Included from asm/pgtable-*.h only ! */
+
+/*
+ * Some bits are only used on some cpu families... Make sure that all
+ * the undefined gets a sensible default
+ */
+#ifndef _PAGE_HASHPTE
+#define _PAGE_HASHPTE	0
+#endif
+#ifndef _PAGE_SHARED
+#define _PAGE_SHARED	0
+#endif
+#ifndef _PAGE_HWWRITE
+#define _PAGE_HWWRITE	0
+#endif
+#ifndef _PAGE_HWEXEC
+#define _PAGE_HWEXEC	0
+#endif
+#ifndef _PAGE_EXEC
+#define _PAGE_EXEC	0
+#endif
+#ifndef _PAGE_ENDIAN
+#define _PAGE_ENDIAN	0
+#endif
+#ifndef _PAGE_COHERENT
+#define _PAGE_COHERENT	0
+#endif
+#ifndef _PAGE_WRITETHRU
+#define _PAGE_WRITETHRU	0
+#endif
+#ifndef _PAGE_SPECIAL
+#define _PAGE_SPECIAL	0
+#endif
+#ifndef _PAGE_4K_PFN
+#define _PAGE_4K_PFN		0
+#endif
+#ifndef _PAGE_PSIZE
+#define _PAGE_PSIZE		0
+#endif
+#ifndef _PMD_PRESENT_MASK
+#define _PMD_PRESENT_MASK	_PMD_PRESENT
+#endif
+#ifndef _PMD_SIZE
+#define _PMD_SIZE	0
+#define PMD_PAGE_SIZE(pmd)	bad_call_to_PMD_PAGE_SIZE()
+#endif
+#ifndef _PAGE_KERNEL_RO
+#define _PAGE_KERNEL_RO	0
+#endif
+#ifndef _PAGE_KERNEL_RW
+#define _PAGE_KERNEL_RW	(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_HPTEFLAGS
+#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
+#endif
+#ifndef _PTE_NONE_MASK
+#define _PTE_NONE_MASK	_PAGE_HPTEFLAGS
+#endif
+
+/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
+ * kernel without large page PMD support
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
+#endif /* __ASSEMBLY__ */
+
+/* Location of the PFN in the PTE. Most 32-bit platforms use the same
+ * as _PAGE_SHIFT here (ie, naturally aligned).
+ * Platform who don't just pre-define the value so we don't override it here
+ */
+#ifndef PTE_RPN_SHIFT
+#define PTE_RPN_SHIFT	(PAGE_SHIFT)
+#endif
+
+/* The mask convered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs
+ */
+#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+#define PTE_RPN_MAX	(1ULL << (64 - PTE_RPN_SHIFT))
+#define PTE_RPN_MASK	(~((1ULL<<PTE_RPN_SHIFT)-1))
+#else
+#define PTE_RPN_MAX	(1UL << (32 - PTE_RPN_SHIFT))
+#define PTE_RPN_MASK	(~((1UL<<PTE_RPN_SHIFT)-1))
+#endif
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved accross
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK	(PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
+                         _PAGE_ACCESSED | _PAGE_SPECIAL)
+
+/* Mask of bits returned by pte_pgprot() */
+#define PAGE_PROT_BITS	(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+			 _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
+			 _PAGE_USER | _PAGE_ACCESSED | \
+			 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
+			 _PAGE_EXEC | _PAGE_HWEXEC)
+
+/*
+ * We define 2 sets of base prot bits, one for basic pages (ie,
+ * cacheable kernel and user pages) and one for non cacheable
+ * pages. We always set _PAGE_COHERENT when SMP is enabled or
+ * the processor might need it for DMA coherency.
+ */
+#define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
+#define _PAGE_BASE	(_PAGE_BASE_NC | _PAGE_COHERENT)
+#else
+#define _PAGE_BASE	(_PAGE_BASE_NC)
+#endif
+
+/* Permission masks used to generate the __P and __S table,
+ *
+ * Note:__pgprot is defined in arch/powerpc/include/asm/page.h
+ *
+ * Write permissions imply read permissions for now (we could make write-only
+ * pages on BookE but we don't bother for now). Execute permission control is
+ * possible on platforms that define _PAGE_EXEC
+ *
+ * Note due to the way vm flags are laid out, the bits are XWR
+ */
+#define PAGE_NONE	__pgprot(_PAGE_BASE)
+#define PAGE_SHARED	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
+#define PAGE_COPY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY	__pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X	__pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY_X
+#define __P101	PAGE_READONLY_X
+#define __P110	PAGE_COPY_X
+#define __P111	PAGE_COPY_X
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY_X
+#define __S101	PAGE_READONLY_X
+#define __S110	PAGE_SHARED_X
+#define __S111	PAGE_SHARED_X
+
+/* Permission masks used for kernel mappings */
+#define PAGE_KERNEL	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
+#define PAGE_KERNEL_NC	__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+				 _PAGE_NO_CACHE)
+#define PAGE_KERNEL_NCG	__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+				 _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_X	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
+				 _PAGE_HWEXEC)
+#define PAGE_KERNEL_RO	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
+#define PAGE_KERNEL_ROX	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
+				 _PAGE_HWEXEC)
+
+/* Protection used for kernel text. We want the debuggers to be able to
+ * set breakpoints anywhere, so don't write protect the kernel text
+ * on platforms where such control is possible.
+ */
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
+	defined(CONFIG_KPROBES)
+#define PAGE_KERNEL_TEXT	PAGE_KERNEL_X
+#else
+#define PAGE_KERNEL_TEXT	PAGE_KERNEL_ROX
+#endif
+
+/* Make modules code happy. We don't set RO yet */
+#define PAGE_KERNEL_EXEC	PAGE_KERNEL_X
+
+/* Advertise special mapping type for AGP */
+#define PAGE_AGP		(PAGE_KERNEL_NC)
+#define HAVE_PAGE_AGP
+
+/* Advertise support for _PAGE_SPECIAL */
+#ifdef _PAGE_SPECIAL
+#define __HAVE_ARCH_PTE_SPECIAL
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-fsl-booke.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-fsl-booke.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-fsl-booke.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-fsl-booke.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+#ifndef _ASM_POWERPC_PTE_FSL_BOOKE_H
+#define _ASM_POWERPC_PTE_FSL_BOOKE_H
+#ifdef __KERNEL__
+
+/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based
+ * processors
+ *
+   MMU Assist Register 3:
+
+   32 33 34 35 36  ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+   RPN......................  0  0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+   - PRESENT *must* be in the bottom three bits because swap cache
+     entries use the top 29 bits.
+
+   - FILE *must* be in the bottom three bits because swap cache
+     entries use the top 29 bits.
+*/
+
+/* Definitions for FSL Book-E Cores */
+#define _PAGE_PRESENT	0x00001	/* S: PTE contains a translation */
+#define _PAGE_USER	0x00002	/* S: User page (maps to UR) */
+#define _PAGE_FILE	0x00002	/* S: when !present: nonlinear file mapping */
+#define _PAGE_RW	0x00004	/* S: Write permission (SW) */
+#define _PAGE_DIRTY	0x00008	/* S: Page dirty */
+#define _PAGE_HWEXEC	0x00010	/* H: SX permission */
+#define _PAGE_ACCESSED	0x00020	/* S: Page referenced */
+
+#define _PAGE_ENDIAN	0x00040	/* H: E bit */
+#define _PAGE_GUARDED	0x00080	/* H: G bit */
+#define _PAGE_COHERENT	0x00100	/* H: M bit */
+#define _PAGE_NO_CACHE	0x00200	/* H: I bit */
+#define _PAGE_WRITETHRU	0x00400	/* H: W bit */
+#define _PAGE_SPECIAL	0x00800 /* S: Special page */
+
+#ifdef CONFIG_PTE_64BIT
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK	0xffffffffffff0000ULL
+/* We extend the size of the PTE flags area when using 64-bit PTEs */
+#define PTE_RPN_SHIFT	(PAGE_SHIFT + 8)
+#endif
+
+#define _PMD_PRESENT	0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD	(~PAGE_MASK)
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash32.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash32.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash32.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash32.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+#ifndef _ASM_POWERPC_PTE_HASH32_H
+#define _ASM_POWERPC_PTE_HASH32_H
+#ifdef __KERNEL__
+
+/*
+ * The "classic" 32-bit implementation of the PowerPC MMU uses a hash
+ * table containing PTEs, together with a set of 16 segment registers,
+ * to define the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings.  We maintain a two-level page table tree, much
+ * like that used by the i386, for the sake of the Linux memory
+ * management code.  Low-level assembler code in hash_low_32.S
+ * (procedure hash_page) is responsible for extracting ptes from the
+ * tree and putting them into the hash table when necessary, and
+ * updating the accessed and modified bits in the page table tree.
+ */
+
+#define _PAGE_PRESENT	0x001	/* software: pte contains a translation */
+#define _PAGE_HASHPTE	0x002	/* hash_page has made an HPTE for this pte */
+#define _PAGE_FILE	0x004	/* when !present: nonlinear file mapping */
+#define _PAGE_USER	0x004	/* usermode access allowed */
+#define _PAGE_GUARDED	0x008	/* G: prohibit speculative access */
+#define _PAGE_COHERENT	0x010	/* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE	0x020	/* I: cache inhibit */
+#define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
+#define _PAGE_DIRTY	0x080	/* C: page changed */
+#define _PAGE_ACCESSED	0x100	/* R: page referenced */
+#define _PAGE_EXEC	0x200	/* software: i-cache coherency required */
+#define _PAGE_RW	0x400	/* software: user write access allowed */
+#define _PAGE_SPECIAL	0x800	/* software: Special page */
+
+#ifdef CONFIG_PTE_64BIT
+/* We never clear the high word of the pte */
+#define _PTE_NONE_MASK	(0xffffffff00000000ULL | _PAGE_HASHPTE)
+#else
+#define _PTE_NONE_MASK	_PAGE_HASHPTE
+#endif
+
+#define _PMD_PRESENT	0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD	(~PAGE_MASK)
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES	1
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_HASH32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash64-4k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64-4k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash64-4k.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64-4k.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* To be include by pgtable-hash64.h only */
+
+/* PTE bits */
+#define _PAGE_HASHPTE	0x0400 /* software: pte has an associated HPTE */
+#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
+#define _PAGE_GROUP_IX  0x7000 /* software: HPTE index within group */
+#define _PAGE_F_SECOND  _PAGE_SECONDARY
+#define _PAGE_F_GIX     _PAGE_GROUP_IX
+#define _PAGE_SPECIAL	0x10000 /* software: special page */
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
+			 _PAGE_SECONDARY | _PAGE_GROUP_IX)
+
+/* shift to put page number into pte */
+#define PTE_RPN_SHIFT	(17)
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64-64k.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,115 @@
+/* To be include by pgtable-hash64.h only */
+
+/* Additional PTE bits (don't change without checking asm in hash_low.S) */
+#define _PAGE_SPECIAL	0x00000400 /* software: special page */
+#define _PAGE_HPTE_SUB	0x0ffff000 /* combo only: sub pages HPTE bits */
+#define _PAGE_HPTE_SUB0	0x08000000 /* combo only: first sub page */
+#define _PAGE_COMBO	0x10000000 /* this is a combo 4k page */
+#define _PAGE_4K_PFN	0x20000000 /* PFN is for a single 4k page */
+
+/* For 64K page, we don't have a separate _PAGE_HASHPTE bit. Instead,
+ * we set that to be the whole sub-bits mask. The C code will only
+ * test this, so a multi-bit mask will work. For combo pages, this
+ * is equivalent as effectively, the old _PAGE_HASHPTE was an OR of
+ * all the sub bits. For real 64k pages, we now have the assembly set
+ * _PAGE_HPTE_SUB0 in addition to setting the HIDX bits which overlap
+ * that mask. This is fine as long as the HIDX bits are never set on
+ * a PTE that isn't hashed, which is the case today.
+ *
+ * A little nit is for the huge page C code, which does the hashing
+ * in C, we need to provide which bit to use.
+ */
+#define _PAGE_HASHPTE	_PAGE_HPTE_SUB
+
+/* Note the full page bits must be in the same location as for normal
+ * 4k pages as the same asssembly will be used to insert 64K pages
+ * wether the kernel has CONFIG_PPC_64K_PAGES or not
+ */
+#define _PAGE_F_SECOND  0x00008000 /* full page: hidx bits */
+#define _PAGE_F_GIX     0x00007000 /* full page: hidx bits */
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO)
+
+/* Shift to put page number into pte.
+ *
+ * That gives us a max RPN of 34 bits, which means a max of 50 bits
+ * of addressable physical space, or 46 bits for the special 4k PFNs.
+ */
+#define PTE_RPN_SHIFT	(30)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * With 64K pages on hash table, we have a special PTE format that
+ * uses a second "half" of the page table to encode sub-page information
+ * in order to deal with 64K made of 4K HW pages. Thus we override the
+ * generic accessors and iterators here
+ */
+#define __real_pte(e,p) 	((real_pte_t) { \
+	(e), pte_val(*((p) + PTRS_PER_PTE)) })
+#define __rpte_to_hidx(r,index)	((pte_val((r).pte) & _PAGE_COMBO) ? \
+        (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
+#define __rpte_to_pte(r)	((r).pte)
+#define __rpte_sub_valid(rpte, index) \
+	(pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))
+
+/* Trick: we set __end to va + 64k, which happens works for
+ * a 16M page as well as we want only one iteration
+ */
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift)	    \
+        do {                                                                \
+                unsigned long __end = va + PAGE_SIZE;                       \
+                unsigned __split = (psize == MMU_PAGE_4K ||                 \
+				    psize == MMU_PAGE_64K_AP);              \
+                shift = mmu_psize_defs[psize].shift;                        \
+		for (index = 0; va < __end; index++, va += (1L << shift)) { \
+		        if (!__split || __rpte_sub_valid(rpte, index)) do { \
+
+#define pte_iterate_hashed_end() } while(0); } } while(0)
+
+#define pte_pagesize_index(mm, addr, pte)	\
+	(((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
+
+#define remap_4k_pfn(vma, addr, pfn, prot)				\
+	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.29-gnu1/arch/powerpc/include/asm/pte-hash64.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/pte-hash64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-hash64.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+#ifndef _ASM_POWERPC_PTE_HASH64_H
+#define _ASM_POWERPC_PTE_HASH64_H
+#ifdef __KERNEL__
+
+/*
+ * Common bits between 4K and 64K pages in a linux-style PTE.
+ * These match the bits in the (hardware-defined) PowerPC PTE as closely
+ * as possible. Additional bits may be defined in pgtable-hash64-*.h
+ *
+ * Note: We only support user read/write permissions. Supervisor always
+ * have full read/write to pages above PAGE_OFFSET (pages below that
+ * always use the user access permissions).
+ *
+ * We could create separate kernel read-only if we used the 3 PP bits
+ * combinations that newer processors provide but we currently don't.
+ */
+#define _PAGE_PRESENT		0x0001 /* software: pte contains a translation */
+#define _PAGE_USER		0x0002 /* matches one of the PP bits */
+#define _PAGE_FILE		0x0002 /* (!present only) software: pte holds file offset */
+#define _PAGE_EXEC		0x0004 /* No execute on POWER4 and newer (we invert) */
+#define _PAGE_GUARDED		0x0008
+#define _PAGE_COHERENT		0x0010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE		0x0020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU		0x0040 /* W: cache write-through */
+#define _PAGE_DIRTY		0x0080 /* C: page changed */
+#define _PAGE_ACCESSED		0x0100 /* R: page referenced */
+#define _PAGE_RW		0x0200 /* software: user write access allowed */
+#define _PAGE_BUSY		0x0800 /* software: PTE & hash are busy */
+
+/* No separate kernel read-only */
+#define _PAGE_KERNEL_RW		(_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
+#define _PAGE_KERNEL_RO		 _PAGE_KERNEL_RW
+
+/* Strong Access Ordering */
+#define _PAGE_SAO		(_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
+
+/* No page size encoding in the linux PTE */
+#define _PAGE_PSIZE		0
+
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY	0x8
+#define _PTEIDX_GROUP_IX	0x7
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES	1
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/pte-hash64-64k.h>
+#else
+#include <asm/pte-hash64-4k.h>
+#endif
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_HASH64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/reg_booke.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/reg_booke.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/reg_booke.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/reg_booke.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
 #define __ASM_POWERPC_REG_BOOKE_H__
 
 /* Machine State Register (MSR) Fields */
+#define MSR_GS		(1<<28) /* Guest state */
 #define MSR_UCLE	(1<<26)	/* User-mode cache lock enable */
 #define MSR_SPE		(1<<25)	/* Enable SPE */
 #define MSR_DWE		(1<<10)	/* Debug Wait Enable */
@@ -110,6 +111,7 @@
 #define SPRN_L1CSR0	0x3F2	/* L1 Cache Control and Status Register 0 */
 #define SPRN_L1CSR1	0x3F3	/* L1 Cache Control and Status Register 1 */
 #define SPRN_MMUCSR0	0x3F4	/* MMU Control and Status Register 0 */
+#define SPRN_MMUCFG	0x3F7	/* MMU Configuration Register */
 #define SPRN_PIT	0x3DB	/* Programmable Interval Timer */
 #define SPRN_BUCSR	0x3F5	/* Branch Unit Control and Status */
 #define SPRN_L2CSR0	0x3F9	/* L2 Data Cache Control and Status Register 0 */
@@ -421,36 +423,6 @@
 #define SGR_NORMAL	0		/* Speculative fetching allowed. */
 #define SGR_GUARDED	1		/* Speculative fetching disallowed. */
 
-/* Bit definitions for SPEFSCR. */
-#define SPEFSCR_SOVH	0x80000000	/* Summary integer overflow high */
-#define SPEFSCR_OVH	0x40000000	/* Integer overflow high */
-#define SPEFSCR_FGH	0x20000000	/* Embedded FP guard bit high */
-#define SPEFSCR_FXH	0x10000000	/* Embedded FP sticky bit high */
-#define SPEFSCR_FINVH	0x08000000	/* Embedded FP invalid operation high */
-#define SPEFSCR_FDBZH	0x04000000	/* Embedded FP div by zero high */
-#define SPEFSCR_FUNFH	0x02000000	/* Embedded FP underflow high */
-#define SPEFSCR_FOVFH	0x01000000	/* Embedded FP overflow high */
-#define SPEFSCR_FINXS	0x00200000	/* Embedded FP inexact sticky */
-#define SPEFSCR_FINVS	0x00100000	/* Embedded FP invalid op. sticky */
-#define SPEFSCR_FDBZS	0x00080000	/* Embedded FP div by zero sticky */
-#define SPEFSCR_FUNFS	0x00040000	/* Embedded FP underflow sticky */
-#define SPEFSCR_FOVFS	0x00020000	/* Embedded FP overflow sticky */
-#define SPEFSCR_MODE	0x00010000	/* Embedded FP mode */
-#define SPEFSCR_SOV	0x00008000	/* Integer summary overflow */
-#define SPEFSCR_OV	0x00004000	/* Integer overflow */
-#define SPEFSCR_FG	0x00002000	/* Embedded FP guard bit */
-#define SPEFSCR_FX	0x00001000	/* Embedded FP sticky bit */
-#define SPEFSCR_FINV	0x00000800	/* Embedded FP invalid operation */
-#define SPEFSCR_FDBZ	0x00000400	/* Embedded FP div by zero */
-#define SPEFSCR_FUNF	0x00000200	/* Embedded FP underflow */
-#define SPEFSCR_FOVF	0x00000100	/* Embedded FP overflow */
-#define SPEFSCR_FINXE	0x00000040	/* Embedded FP inexact enable */
-#define SPEFSCR_FINVE	0x00000020	/* Embedded FP invalid op. enable */
-#define SPEFSCR_FDBZE	0x00000010	/* Embedded FP div by zero enable */
-#define SPEFSCR_FUNFE	0x00000008	/* Embedded FP underflow enable */
-#define SPEFSCR_FOVFE	0x00000004	/* Embedded FP overflow enable */
-#define SPEFSCR_FRMC 	0x00000003	/* Embedded FP rounding mode control */
-
 /*
  * The IBM-403 is an even more odd special case, as it is much
  * older than the IBM-405 series.  We put these down here incase someone
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/reg.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/reg.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -143,6 +143,36 @@
 #define FPSCR_NI	0x00000004	/* FPU non IEEE-Mode */
 #define FPSCR_RN	0x00000003	/* FPU rounding control */
 
+/* Bit definitions for SPEFSCR. */
+#define SPEFSCR_SOVH	0x80000000	/* Summary integer overflow high */
+#define SPEFSCR_OVH	0x40000000	/* Integer overflow high */
+#define SPEFSCR_FGH	0x20000000	/* Embedded FP guard bit high */
+#define SPEFSCR_FXH	0x10000000	/* Embedded FP sticky bit high */
+#define SPEFSCR_FINVH	0x08000000	/* Embedded FP invalid operation high */
+#define SPEFSCR_FDBZH	0x04000000	/* Embedded FP div by zero high */
+#define SPEFSCR_FUNFH	0x02000000	/* Embedded FP underflow high */
+#define SPEFSCR_FOVFH	0x01000000	/* Embedded FP overflow high */
+#define SPEFSCR_FINXS	0x00200000	/* Embedded FP inexact sticky */
+#define SPEFSCR_FINVS	0x00100000	/* Embedded FP invalid op. sticky */
+#define SPEFSCR_FDBZS	0x00080000	/* Embedded FP div by zero sticky */
+#define SPEFSCR_FUNFS	0x00040000	/* Embedded FP underflow sticky */
+#define SPEFSCR_FOVFS	0x00020000	/* Embedded FP overflow sticky */
+#define SPEFSCR_MODE	0x00010000	/* Embedded FP mode */
+#define SPEFSCR_SOV	0x00008000	/* Integer summary overflow */
+#define SPEFSCR_OV	0x00004000	/* Integer overflow */
+#define SPEFSCR_FG	0x00002000	/* Embedded FP guard bit */
+#define SPEFSCR_FX	0x00001000	/* Embedded FP sticky bit */
+#define SPEFSCR_FINV	0x00000800	/* Embedded FP invalid operation */
+#define SPEFSCR_FDBZ	0x00000400	/* Embedded FP div by zero */
+#define SPEFSCR_FUNF	0x00000200	/* Embedded FP underflow */
+#define SPEFSCR_FOVF	0x00000100	/* Embedded FP overflow */
+#define SPEFSCR_FINXE	0x00000040	/* Embedded FP inexact enable */
+#define SPEFSCR_FINVE	0x00000020	/* Embedded FP invalid op. enable */
+#define SPEFSCR_FDBZE	0x00000010	/* Embedded FP div by zero enable */
+#define SPEFSCR_FUNFE	0x00000008	/* Embedded FP underflow enable */
+#define SPEFSCR_FOVFE	0x00000004	/* Embedded FP overflow enable */
+#define SPEFSCR_FRMC 	0x00000003	/* Embedded FP rounding mode control */
+
 /* Special Purpose Registers (SPRNs)*/
 #define SPRN_CTR	0x009	/* Count Register */
 #define SPRN_DSCR	0x11
@@ -155,6 +185,8 @@
 #define   CTRL_RUNLATCH	0x1
 #define SPRN_DABR	0x3F5	/* Data Address Breakpoint Register */
 #define   DABR_TRANSLATION	(1UL << 2)
+#define   DABR_DATA_WRITE	(1UL << 1)
+#define   DABR_DATA_READ	(1UL << 0)
 #define SPRN_DABR2	0x13D	/* e300 */
 #define SPRN_DABRX	0x3F7	/* Data Address Breakpoint Register Extension */
 #define   DABRX_USER	(1UL << 0)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/rtas.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/rtas.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/rtas.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/rtas.h	2009-06-09 23:05:27.000000000 -0400
@@ -68,7 +68,8 @@ struct rtas_t {
 #define RTAS_EPOW_WARNING		0x40000000 /* set bit 1 */
 #define RTAS_POWERMGM_EVENTS		0x20000000 /* set bit 2 */
 #define RTAS_HOTPLUG_EVENTS		0x10000000 /* set bit 3 */
-#define RTAS_EVENT_SCAN_ALL_EVENTS	0xf0000000
+#define RTAS_IO_EVENTS			0x08000000 /* set bit 4 */
+#define RTAS_EVENT_SCAN_ALL_EVENTS	0xffffffff
 
 /* RTAS event severity */
 #define RTAS_SEVERITY_FATAL		0x5
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/sfp-machine.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/sfp-machine.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/sfp-machine.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/sfp-machine.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,9 +29,9 @@
 
 /* basic word size definitions */
 #define _FP_W_TYPE_SIZE		32
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
 
 #define __ll_B			((UWtype) 1 << (W_TYPE_SIZE / 2))
 #define __ll_lowpart(t)		((UWtype) (t) & (__ll_B - 1))
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,4 +61,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -287,6 +287,9 @@ static inline void __raw_write_unlock(ra
 	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 _raw_spin_relax(lock)	__spin_yield(lock)
 #define _raw_read_relax(lock)	__rw_yield(lock)
 #define _raw_write_relax(lock)	__rw_yield(lock)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/spu_info.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/spu_info.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/spu_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/spu_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,9 +23,10 @@
 #ifndef _SPU_INFO_H
 #define _SPU_INFO_H
 
+#include <linux/types.h>
+
 #ifdef __KERNEL__
 #include <asm/spu.h>
-#include <linux/types.h>
 #else
 struct mfc_cq_sr {
 	__u64 mfc_cq_data0_RW;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/suspend.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/suspend.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/suspend.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/suspend.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,4 @@
 
 static inline int arch_prepare_suspend(void) { return 0; }
 
-void save_processor_state(void);
-void restore_processor_state(void);
-
 #endif /* __ASM_POWERPC_SUSPEND_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 #ifdef __GNUC__
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/systbl.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/systbl.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/systbl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/systbl.h	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,7 @@ SYSCALL(ni_syscall)
 SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
 COMPAT_SYS_SPU(umask)
 SYSCALL_SPU(chroot)
-SYSCALL(ustat)
+COMPAT_SYS(ustat)
 SYSCALL_SPU(dup2)
 SYSCALL_SPU(getppid)
 SYSCALL_SPU(getpgrp)
@@ -322,3 +322,6 @@ SYSCALL_SPU(epoll_create1)
 SYSCALL_SPU(dup3)
 SYSCALL_SPU(pipe2)
 SYSCALL(inotify_init1)
+SYSCALL(ni_syscall)
+COMPAT_SYS_SPU(preadv)
+COMPAT_SYS_SPU(pwritev)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/system.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -212,7 +212,7 @@ extern struct task_struct *_switch(struc
 extern unsigned int rtas_data;
 extern int mem_init_done;	/* set on boot once kmalloc can be called */
 extern int init_bootmem_done;	/* set on !NUMA once bootmem is available */
-extern unsigned long memory_limit;
+extern phys_addr_t memory_limit;
 extern unsigned long klimit;
 
 extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
@@ -531,7 +531,7 @@ __cmpxchg_local(volatile void *ptr, unsi
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 #endif
 
-#define arch_align_stack(x) (x)
+extern unsigned long arch_align_stack(unsigned long sp);
 
 /* Used in very early kernel initialization. */
 extern unsigned long reloc_offset(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/thread_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -12,8 +12,10 @@
 
 /* We have 8k stacks on ppc32 and 16k on ppc64 */
 
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64)
 #define THREAD_SHIFT		14
+#elif defined(CONFIG_PPC_256K_PAGES)
+#define THREAD_SHIFT		15
 #else
 #define THREAD_SHIFT		13
 #endif
@@ -154,6 +156,13 @@ static inline void set_restore_sigmask(v
 	ti->local_flags |= _TLF_RESTORE_SIGMASK;
 	set_bit(TIF_SIGPENDING, &ti->flags);
 }
+
+#ifdef CONFIG_PPC64
+#define is_32bit_task()	(test_thread_flag(TIF_32BIT))
+#else
+#define is_32bit_task()	(1)
+#endif
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,11 +24,6 @@ static inline cpumask_t node_to_cpumask(
 
 #define cpumask_of_node(node) (&numa_cpumask_lookup_table[node])
 
-static inline int node_to_first_cpu(int node)
-{
-	return cpumask_first(cpumask_of_node(node));
-}
-
 int of_node_to_nid(struct device_node *device);
 
 struct pci_bus;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/udbg.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/udbg.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/udbg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/udbg.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 
 extern void (*udbg_putc)(char c);
+extern void (*udbg_flush)(void);
 extern int (*udbg_getc)(void);
 extern int (*udbg_getc_poll)(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -341,10 +341,12 @@
 #define __NR_dup3		316
 #define __NR_pipe2		317
 #define __NR_inotify_init1	318
+#define __NR_preadv		320
+#define __NR_pwritev		321
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		319
+#define __NR_syscalls		322
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -111,6 +111,7 @@ config PPC
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_GRAPH_TRACER
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select HAVE_IDE
 	select HAVE_IOREMAP_PROT
@@ -180,6 +181,10 @@ config SYS_SUPPORTS_APM_EMULATION
 	default y if PMAC_APM_EMU
 	bool
 
+config DTC
+       bool
+       default y
+
 config DEFAULT_UIMAGE
 	bool
 	help
@@ -227,6 +232,9 @@ config PPC_OF_PLATFORM_PCI
 	depends on PPC64 # not supported on 32 bits yet
 	default n
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
@@ -312,7 +320,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
 
 config KEXEC
 	bool "kexec system call (EXPERIMENTAL)"
-	depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL
+	depends on PPC_BOOK3S && EXPERIMENTAL
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
@@ -342,7 +350,7 @@ config PHYP_DUMP
 	help
 	  Hypervisor-assisted dump is meant to be a kdump replacement
 	  offering robustness and speed not possible without system
-	  hypervisor assistence.
+	  hypervisor assistance.
 
 	  If unsure, say "N"
 
@@ -409,6 +417,18 @@ config PPC_HAS_HASH_64K
 	depends on PPC64
 	default n
 
+config STDBINUTILS
+	bool "Using standard binutils settings"
+	depends on 44x
+	default y
+	help
+	  Turning this option off allows you to select 256KB PAGE_SIZE on 44x.
+	  Note, that kernel will be able to run only those applications,
+	  which had been compiled using binutils later than 2.17.50.0.3 with
+	  '-zmax-page-size' set to 256K (the default is 64K). Or, if using
+	  the older binutils, you can patch them with a trivial patch, which
+	  changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000.
+
 choice
 	prompt "Page size"
 	default PPC_4K_PAGES
@@ -444,6 +464,19 @@ config PPC_64K_PAGES
 	bool "64k page size" if 44x || PPC_STD_MMU_64
 	select PPC_HAS_HASH_64K if PPC_STD_MMU_64
 
+config PPC_256K_PAGES
+	bool "256k page size" if 44x
+	depends on !STDBINUTILS
+	help
+	  Make the page size 256k.
+
+	  As the ELF standard only requires alignment to support page
+	  sizes up to 64k, you will need to compile all of your user
+	  space applications with a non-standard binutils settings
+	  (see the STDBINUTILS description for details).
+
+	  Say N unless you know what you are doing.
+
 endchoice
 
 config FORCE_MAX_ZONEORDER
@@ -456,6 +489,8 @@ config FORCE_MAX_ZONEORDER
 	default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES
 	range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES
 	default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES
+	range 5 64 if PPC_STD_MMU_32 && PPC_256K_PAGES
+	default "5" if PPC_STD_MMU_32 && PPC_256K_PAGES
 	range 11 64
 	default "11"
 	help
@@ -594,6 +629,7 @@ config FSL_SOC
 config FSL_PCI
  	bool
 	select PPC_INDIRECT_PCI
+	select PCI_QUIRKS
 
 config 4xx_SOC
 	bool
@@ -730,6 +766,23 @@ config LOWMEM_SIZE
 	hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
 	default "0x30000000"
 
+config LOWMEM_CAM_NUM_BOOL
+	bool "Set number of CAMs to use to map low memory"
+	depends on ADVANCED_OPTIONS && FSL_BOOKE
+	help
+	  This option allows you to set the maximum number of CAM slots that
+	  will be used to map low memory.  There are a limited number of slots
+	  available and even more limited number that will fit in the L1 MMU.
+	  However, using more entries will allow mapping more low memory.  This
+	  can be useful in optimizing the layout of kernel virtual memory.
+
+	  Say N here unless you know what you are doing.
+
+config LOWMEM_CAM_NUM
+	depends on FSL_BOOKE
+	int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL
+	default 3
+
 config RELOCATABLE
 	bool "Build a relocatable kernel (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
@@ -794,7 +847,7 @@ config PHYSICAL_START
 
 config PHYSICAL_ALIGN
 	hex
-	default "0x10000000" if FSL_BOOKE
+	default "0x04000000" if FSL_BOOKE
 	help
 	  This value puts the alignment restrictions on physical address
 	  where kernel is loaded and run from. Kernel is compiled for an
@@ -815,19 +868,6 @@ config TASK_SIZE
 	default "0x80000000" if PPC_PREP || PPC_8xx
 	default "0xc0000000"
 
-config CONSISTENT_START_BOOL
-	bool "Set custom consistent memory pool address"
-	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
-	help
-	  This option allows you to set the base virtual address
-	  of the consistent memory pool.  This pool of virtual
-	  memory is used to make consistent memory allocations.
-
-config CONSISTENT_START
-	hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
-	default "0xfd000000" if (NOT_COHERENT_CACHE && 8xx)
-	default "0xff100000" if NOT_COHERENT_CACHE
-
 config CONSISTENT_SIZE_BOOL
 	bool "Set custom consistent memory pool size"
 	depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/Kconfig.debug linux-libre-2.6.30-gnu1/arch/powerpc/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/powerpc/Kconfig.debug	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -27,15 +27,6 @@ config DEBUG_STACK_USAGE
 
 	  This option will slow down process creation somewhat.
 
-config DEBUG_PAGEALLOC
-        bool "Debug page memory allocations"
-        depends on DEBUG_KERNEL && !HIBERNATION
-        help
-          Unmap pages from the kernel linear mapping after free_pages().
-          This results in a large slowdown, but helps to find certain types
-          of memory corruptions.
-
-
 config HCALL_STATS
 	bool "Hypervisor call instrumentation"
 	depends on PPC_PSERIES && DEBUG_FS
@@ -129,7 +120,7 @@ config BDI_SWITCH
 
 config BOOTX_TEXT
 	bool "Support for early boot text console (BootX or OpenFirmware only)"
-	depends on PPC_OF && PPC_MULTIPLATFORM
+	depends on PPC_OF && PPC_BOOK3S
 	help
 	  Say Y here to see progress messages from the boot firmware in text
 	  mode. Requires either BootX or Open Firmware.
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/align.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/align.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/align.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/align.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,7 @@ static struct aligninfo aligninfo[128] =
 	{ 4, ST+F+S+U },	/* 11 1 1010: stfsux */
 	{ 8, ST+F+U },		/* 11 1 1011: stfdux */
 	INVALID,		/* 11 1 1100 */
-	INVALID,		/* 11 1 1101 */
+	{ 4, LD+F },		/* 11 1 1101: lfiwzx */
 	INVALID,		/* 11 1 1110 */
 	INVALID,		/* 11 1 1111 */
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/asm-offsets.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,7 +49,7 @@
 #include <asm/iseries/alpaca.h>
 #endif
 #ifdef CONFIG_KVM
-#include <asm/kvm_44x.h>
+#include <linux/kvm_host.h>
 #endif
 
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
@@ -284,9 +284,6 @@ int main(void)
 #endif /* ! CONFIG_PPC64 */
 
 	/* About the CPU features table */
-	DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
-	DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
-	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
 	DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
@@ -361,8 +358,6 @@ int main(void)
 	DEFINE(PTE_SIZE, sizeof(pte_t));
 
 #ifdef CONFIG_KVM
-	DEFINE(TLBE_BYTES, sizeof(struct kvmppc_44x_tlbe));
-
 	DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
 	DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
 	DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_44x.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_44x.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_44x.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_44x.S	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,7 @@ _GLOBAL(__setup_cpu_440grx)
 	blr
 _GLOBAL(__setup_cpu_460ex)
 _GLOBAL(__setup_cpu_460gt)
+_GLOBAL(__setup_cpu_460sx)
 	mflr	r4
 	bl	__init_fpu_44x
 	bl	__fixup_440A_mcheck
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S	2009-06-09 23:05:27.000000000 -0400
@@ -15,9 +15,14 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
+#include <asm/mmu.h>
 
 _GLOBAL(__setup_cpu_603)
 	mflr	r4
+BEGIN_MMU_FTR_SECTION
+	li	r10,0
+	mtspr	SPRN_SPRG4,r10		/* init SW LRU tracking */
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 BEGIN_FTR_SECTION
 	bl	__init_fpu_registers
 END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_fsl_booke.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_fsl_booke.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cpu_setup_fsl_booke.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cpu_setup_fsl_booke.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * This file contains low level CPU setup functions.
+ * Kumar Gala <galak@kernel.crashing.org>
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * Based on cpu_setup_6xx code by
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(__setup_cpu_e200)
+	/* enable dedicated debug exception handling resources (Debug APU) */
+	mfspr	r3,SPRN_HID0
+	ori	r3,r3,HID0_DAPUEN@l
+	mtspr	SPRN_HID0,r3
+	b	__setup_e200_ivors
+_GLOBAL(__setup_cpu_e500v1)
+_GLOBAL(__setup_cpu_e500v2)
+	b	__setup_e500_ivors
+_GLOBAL(__setup_cpu_e500mc)
+	b	__setup_e500mc_ivors
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cputable.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cputable.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/cputable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/cputable.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,10 @@ const char *powerpc_base_platform;
  * and ppc64
  */
 #ifdef CONFIG_PPC32
+extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
@@ -43,6 +47,7 @@ extern void __setup_cpu_440spe(unsigned
 extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec);
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -377,7 +382,8 @@ static struct cpu_spec __initdata cpu_sp
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.machine_check		= machine_check_generic,
-		.oprofile_cpu_type	= "ppc64/compat-power5+",
+		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "power5+",
 	},
 	{	/* Power6 */
@@ -411,7 +417,8 @@ static struct cpu_spec __initdata cpu_sp
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.machine_check		= machine_check_generic,
-		.oprofile_cpu_type	= "ppc64/compat-power6",
+		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.platform		= "power6",
 	},
 	{	/* 2.06-compliant processor, i.e. Power7 "architected" mode */
@@ -424,7 +431,8 @@ static struct cpu_spec __initdata cpu_sp
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.machine_check		= machine_check_generic,
-		.oprofile_cpu_type	= "ppc64/compat-power7",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
 		.platform		= "power7",
 	},
 	{	/* Power7 */
@@ -726,6 +734,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_setup		= __setup_cpu_750,
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
+		.oprofile_cpu_type      = "ppc/750",
+		.oprofile_type		= PPC_OPROFILE_G4,
 	},
 	{	/* 750FX rev 2.0 must disable HID0[DPM] */
 		.pvr_mask		= 0xffffffff,
@@ -741,6 +751,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_setup		= __setup_cpu_750,
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
+		.oprofile_cpu_type      = "ppc/750",
+		.oprofile_type		= PPC_OPROFILE_G4,
 	},
 	{	/* 750FX (All revs except 2.0) */
 		.pvr_mask		= 0xffff0000,
@@ -756,6 +768,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_setup		= __setup_cpu_750fx,
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
+		.oprofile_cpu_type      = "ppc/750",
+		.oprofile_type		= PPC_OPROFILE_G4,
 	},
 	{	/* 750GX */
 		.pvr_mask		= 0xffff0000,
@@ -771,6 +785,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_setup		= __setup_cpu_750fx,
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
+		.oprofile_cpu_type      = "ppc/750",
+		.oprofile_type		= PPC_OPROFILE_G4,
 	},
 	{	/* 740/750 (L2CR bit need fixup for 740) */
 		.pvr_mask		= 0xffff0000,
@@ -1077,7 +1093,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_name		= "e300c2",
 		.cpu_features		= CPU_FTRS_E300C2,
 		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
-		.mmu_features		= MMU_FTR_USE_HIGH_BATS,
+		.mmu_features		= MMU_FTR_USE_HIGH_BATS |
+			MMU_FTR_NEED_DTLB_SW_LRU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.cpu_setup		= __setup_cpu_603,
@@ -1090,7 +1107,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_name		= "e300c3",
 		.cpu_features		= CPU_FTRS_E300,
 		.cpu_user_features	= COMMON_USER,
-		.mmu_features		= MMU_FTR_USE_HIGH_BATS,
+		.mmu_features		= MMU_FTR_USE_HIGH_BATS |
+			MMU_FTR_NEED_DTLB_SW_LRU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.cpu_setup		= __setup_cpu_603,
@@ -1105,7 +1123,8 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_name		= "e300c4",
 		.cpu_features		= CPU_FTRS_E300,
 		.cpu_user_features	= COMMON_USER,
-		.mmu_features		= MMU_FTR_USE_HIGH_BATS,
+		.mmu_features		= MMU_FTR_USE_HIGH_BATS |
+			MMU_FTR_NEED_DTLB_SW_LRU,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
 		.cpu_setup		= __setup_cpu_603,
@@ -1634,6 +1653,19 @@ static struct cpu_spec __initdata cpu_sp
 		.machine_check		= machine_check_440A,
 		.platform		= "ppc440",
 	},
+	{ /* 460SX */
+		.pvr_mask		= 0xffffff00,
+		.pvr_value		= 0x13541800,
+		.cpu_name		= "460SX",
+		.cpu_features		= CPU_FTRS_44X,
+		.cpu_user_features	= COMMON_USER_BOOKE,
+		.mmu_features		= MMU_FTR_TYPE_44x,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_460sx,
+		.machine_check		= machine_check_440A,
+		.platform		= "ppc440",
+	},
 	{	/* default match */
 		.pvr_mask		= 0x00000000,
 		.pvr_value		= 0x00000000,
@@ -1687,6 +1719,7 @@ static struct cpu_spec __initdata cpu_sp
 			PPC_FEATURE_UNIFIED_CACHE,
 		.mmu_features		= MMU_FTR_TYPE_FSL_E,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_e200,
 		.machine_check		= machine_check_e200,
 		.platform		= "ppc5554",
 	}
@@ -1706,6 +1739,7 @@ static struct cpu_spec __initdata cpu_sp
 		.num_pmcs		= 4,
 		.oprofile_cpu_type	= "ppc/e500",
 		.oprofile_type		= PPC_OPROFILE_FSL_EMB,
+		.cpu_setup		= __setup_cpu_e500v1,
 		.machine_check		= machine_check_e500,
 		.platform		= "ppc8540",
 	},
@@ -1724,6 +1758,7 @@ static struct cpu_spec __initdata cpu_sp
 		.num_pmcs		= 4,
 		.oprofile_cpu_type	= "ppc/e500",
 		.oprofile_type		= PPC_OPROFILE_FSL_EMB,
+		.cpu_setup		= __setup_cpu_e500v2,
 		.machine_check		= machine_check_e500,
 		.platform		= "ppc8548",
 	},
@@ -1733,12 +1768,14 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_name		= "e500mc",
 		.cpu_features		= CPU_FTRS_E500MC,
 		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
-		.mmu_features		= MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS,
+		.mmu_features		= MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
+			MMU_FTR_USE_TLBILX,
 		.icache_bsize		= 64,
 		.dcache_bsize		= 64,
 		.num_pmcs		= 4,
 		.oprofile_cpu_type	= "ppc/e500", /* xxx - galak, e500mc? */
 		.oprofile_type		= PPC_OPROFILE_FSL_EMB,
+		.cpu_setup		= __setup_cpu_e500mc,
 		.machine_check		= machine_check_e500,
 		.platform		= "ppce500mc",
 	},
@@ -1762,74 +1799,86 @@ static struct cpu_spec __initdata cpu_sp
 
 static struct cpu_spec the_cpu_spec;
 
-struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
+static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s)
 {
-	struct cpu_spec *s = cpu_specs;
 	struct cpu_spec *t = &the_cpu_spec;
-	int i;
+	struct cpu_spec old;
 
-	s = PTRRELOC(s);
 	t = PTRRELOC(t);
+	old = *t;
 
-	for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
-		if ((pvr & s->pvr_mask) == s->pvr_value) {
-			/*
-			 * If we are overriding a previous value derived
-			 * from the real PVR with a new value obtained
-			 * using a logical PVR value, don't modify the
-			 * performance monitor fields.
-			 */
-			if (t->num_pmcs && !s->num_pmcs) {
-				t->cpu_name = s->cpu_name;
-				t->cpu_features = s->cpu_features;
-				t->cpu_user_features = s->cpu_user_features;
-				t->icache_bsize = s->icache_bsize;
-				t->dcache_bsize = s->dcache_bsize;
-				t->cpu_setup = s->cpu_setup;
-				t->cpu_restore = s->cpu_restore;
-				t->platform = s->platform;
-				/*
-				 * If we have passed through this logic once
-				 * before and have pulled the default case
-				 * because the real PVR was not found inside
-				 * cpu_specs[], then we are possibly running in
-				 * compatibility mode. In that case, let the
-				 * oprofiler know which set of compatibility
-				 * counters to pull from by making sure the
-				 * oprofile_cpu_type string is set to that of
-				 * compatibility mode. If the oprofile_cpu_type
-				 * already has a value, then we are possibly
-				 * overriding a real PVR with a logical one, and,
-				 * in that case, keep the current value for
-				 * oprofile_cpu_type.
-				 */
-				if (t->oprofile_cpu_type == NULL)
-					t->oprofile_cpu_type = s->oprofile_cpu_type;
-			} else
-				*t = *s;
-			*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+	/* Copy everything, then do fixups */
+	*t = *s;
 
-			/*
-			 * Set the base platform string once; assumes
-			 * we're called with real pvr first.
-			 */
-			if (*PTRRELOC(&powerpc_base_platform) == NULL)
-				*PTRRELOC(&powerpc_base_platform) = t->platform;
+	/*
+	 * If we are overriding a previous value derived from the real
+	 * PVR with a new value obtained using a logical PVR value,
+	 * don't modify the performance monitor fields.
+	 */
+	if (old.num_pmcs && !s->num_pmcs) {
+		t->num_pmcs = old.num_pmcs;
+		t->pmc_type = old.pmc_type;
+		t->oprofile_type = old.oprofile_type;
+		t->oprofile_mmcra_sihv = old.oprofile_mmcra_sihv;
+		t->oprofile_mmcra_sipr = old.oprofile_mmcra_sipr;
+		t->oprofile_mmcra_clear = old.oprofile_mmcra_clear;
+
+		/*
+		 * If we have passed through this logic once before and
+		 * have pulled the default case because the real PVR was
+		 * not found inside cpu_specs[], then we are possibly
+		 * running in compatibility mode. In that case, let the
+		 * oprofiler know which set of compatibility counters to
+		 * pull from by making sure the oprofile_cpu_type string
+		 * is set to that of compatibility mode. If the
+		 * oprofile_cpu_type already has a value, then we are
+		 * possibly overriding a real PVR with a logical one,
+		 * and, in that case, keep the current value for
+		 * oprofile_cpu_type.
+		 */
+		if (old.oprofile_cpu_type != NULL) {
+			t->oprofile_cpu_type = old.oprofile_cpu_type;
+			t->oprofile_type = old.oprofile_type;
+		}
+	}
+
+	*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+
+	/*
+	 * Set the base platform string once; assumes
+	 * we're called with real pvr first.
+	 */
+	if (*PTRRELOC(&powerpc_base_platform) == NULL)
+		*PTRRELOC(&powerpc_base_platform) = t->platform;
 
 #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
-			/* ppc64 and booke expect identify_cpu to also call
-			 * setup_cpu for that processor. I will consolidate
-			 * that at a later time, for now, just use #ifdef.
-			 * we also don't need to PTRRELOC the function pointer
-			 * on ppc64 and booke as we are running at 0 in real
-			 * mode on ppc64 and reloc_offset is always 0 on booke.
-			 */
-			if (s->cpu_setup) {
-				s->cpu_setup(offset, s);
-			}
+	/* ppc64 and booke expect identify_cpu to also call setup_cpu for
+	 * that processor. I will consolidate that at a later time, for now,
+	 * just use #ifdef. We also don't need to PTRRELOC the function
+	 * pointer on ppc64 and booke as we are running at 0 in real mode
+	 * on ppc64 and reloc_offset is always 0 on booke.
+	 */
+	if (s->cpu_setup) {
+		s->cpu_setup(offset, s);
+	}
 #endif /* CONFIG_PPC64 || CONFIG_BOOKE */
+}
+
+struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
+{
+	struct cpu_spec *s = cpu_specs;
+	int i;
+
+	s = PTRRELOC(s);
+
+	for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
+		if ((pvr & s->pvr_mask) == s->pvr_value) {
+			setup_cpu_spec(offset, s);
 			return s;
 		}
+	}
+
 	BUG();
+
 	return NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/crash_dump.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/crash_dump.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/crash_dump.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/crash_dump.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,7 +48,7 @@ static void __init create_trampoline(uns
 	 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires
 	 * two instructions it doesn't require any registers.
 	 */
-	patch_instruction(p, PPC_NOP_INSTR);
+	patch_instruction(p, PPC_INST_NOP);
 	patch_branch(++p, addr + PHYSICAL_START, 0);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/dbell.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/dbell.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/dbell.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/dbell.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Author: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+
+#include <asm/dbell.h>
+
+#ifdef CONFIG_SMP
+unsigned long dbell_smp_message[NR_CPUS];
+
+void smp_dbell_message_pass(int target, int msg)
+{
+	int i;
+
+	if(target < NR_CPUS) {
+		set_bit(msg, &dbell_smp_message[target]);
+		ppc_msgsnd(PPC_DBELL, 0, target);
+	}
+	else if(target == MSG_ALL_BUT_SELF) {
+		for_each_online_cpu(i) {
+			if (i == smp_processor_id())
+				continue;
+			set_bit(msg, &dbell_smp_message[i]);
+			ppc_msgsnd(PPC_DBELL, 0, i);
+		}
+	}
+	else { /* target == MSG_ALL */
+		for_each_online_cpu(i)
+			set_bit(msg, &dbell_smp_message[i]);
+		ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0);
+	}
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/dma.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/dma.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ void *dma_direct_alloc_coherent(struct d
 {
 	void *ret;
 #ifdef CONFIG_NOT_COHERENT_CACHE
-	ret = __dma_alloc_coherent(size, dma_handle, flag);
+	ret = __dma_alloc_coherent(dev, size, dma_handle, flag);
 	if (ret == NULL)
 		return NULL;
 	*dma_handle += get_dma_direct_offset(dev);
@@ -94,7 +94,7 @@ static int dma_direct_dma_supported(stru
 	 * done via some global so platforms can set the limit in case
 	 * they have limited DMA windows
 	 */
-	return mask >= DMA_32BIT_MASK;
+	return mask >= DMA_BIT_MASK(32);
 #else
 	return 1;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/entry_32.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/entry_32.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/entry_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/entry_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -63,7 +63,7 @@ debug_transfer_to_handler:
 
 	.globl	crit_transfer_to_handler
 crit_transfer_to_handler:
-#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_PPC_BOOK3E_MMU
 	mfspr	r0,SPRN_MAS0
 	stw	r0,MAS0(r11)
 	mfspr	r0,SPRN_MAS1
@@ -78,7 +78,7 @@ crit_transfer_to_handler:
 	mfspr	r0,SPRN_MAS7
 	stw	r0,MAS7(r11)
 #endif /* CONFIG_PHYS_64BIT */
-#endif /* CONFIG_FSL_BOOKE */
+#endif /* CONFIG_PPC_BOOK3E_MMU */
 #ifdef CONFIG_44x
 	mfspr	r0,SPRN_MMUCR
 	stw	r0,MMUCR(r11)
@@ -914,7 +914,7 @@ exc_exit_restart_end:
 	mtspr	SPRN_##exc_lvl_srr0,r9;					\
 	mtspr	SPRN_##exc_lvl_srr1,r10;
 
-#if defined(CONFIG_FSL_BOOKE)
+#if defined(CONFIG_PPC_BOOK3E_MMU)
 #ifdef CONFIG_PHYS_64BIT
 #define	RESTORE_MAS7							\
 	lwz	r11,MAS7(r1);						\
@@ -956,7 +956,7 @@ ret_from_crit_exc:
 	lwz	r10,crit_srr1@l(r10);
 	mtspr	SPRN_SRR0,r9;
 	mtspr	SPRN_SRR1,r10;
-	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
 #endif /* CONFIG_40x */
 
 #ifdef CONFIG_BOOKE
@@ -967,7 +967,7 @@ ret_from_crit_exc:
 	stw	r10,KSP_LIMIT(r9)
 	RESTORE_xSRR(SRR0,SRR1);
 	RESTORE_MMU_REGS;
-	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
 
 	.globl	ret_from_debug_exc
 ret_from_debug_exc:
@@ -981,7 +981,7 @@ ret_from_debug_exc:
 	RESTORE_xSRR(SRR0,SRR1);
 	RESTORE_xSRR(CSRR0,CSRR1);
 	RESTORE_MMU_REGS;
-	RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
+	RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI)
 
 	.globl	ret_from_mcheck_exc
 ret_from_mcheck_exc:
@@ -992,7 +992,7 @@ ret_from_mcheck_exc:
 	RESTORE_xSRR(CSRR0,CSRR1);
 	RESTORE_xSRR(DSRR0,DSRR1);
 	RESTORE_MMU_REGS;
-	RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
+	RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
 #endif /* CONFIG_BOOKE */
 
 /*
@@ -1176,59 +1176,27 @@ _GLOBAL(_mcount)
 	bctr
 
 _GLOBAL(ftrace_caller)
-	/* Based off of objdump optput from glibc */
-	stwu	r1,-48(r1)
-	stw	r3, 12(r1)
-	stw	r4, 16(r1)
-	stw	r5, 20(r1)
-	stw	r6, 24(r1)
-	mflr	r3
-	lwz	r4, 52(r1)
-	mfcr	r5
-	stw	r7, 28(r1)
-	stw	r8, 32(r1)
-	stw	r9, 36(r1)
-	stw	r10,40(r1)
-	stw	r3, 44(r1)
-	stw	r5, 8(r1)
+	MCOUNT_SAVE_FRAME
+	/* r3 ends up with link register */
 	subi	r3, r3, MCOUNT_INSN_SIZE
 .globl ftrace_call
 ftrace_call:
 	bl	ftrace_stub
 	nop
-	lwz	r6, 8(r1)
-	lwz	r0, 44(r1)
-	lwz	r3, 12(r1)
-	mtctr	r0
-	lwz	r4, 16(r1)
-	mtcr	r6
-	lwz	r5, 20(r1)
-	lwz	r6, 24(r1)
-	lwz	r0, 52(r1)
-	lwz	r7, 28(r1)
-	lwz	r8, 32(r1)
-	mtlr	r0
-	lwz	r9, 36(r1)
-	lwz	r10,40(r1)
-	addi	r1, r1, 48
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+.globl ftrace_graph_call
+ftrace_graph_call:
+	b	ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+#endif
+	MCOUNT_RESTORE_FRAME
+	/* old link register ends up in ctr reg */
 	bctr
 #else
 _GLOBAL(mcount)
 _GLOBAL(_mcount)
-	stwu	r1,-48(r1)
-	stw	r3, 12(r1)
-	stw	r4, 16(r1)
-	stw	r5, 20(r1)
-	stw	r6, 24(r1)
-	mflr	r3
-	lwz	r4, 52(r1)
-	mfcr	r5
-	stw	r7, 28(r1)
-	stw	r8, 32(r1)
-	stw	r9, 36(r1)
-	stw	r10,40(r1)
-	stw	r3, 44(r1)
-	stw	r5, 8(r1)
+
+	MCOUNT_SAVE_FRAME
 
 	subi	r3, r3, MCOUNT_INSN_SIZE
 	LOAD_REG_ADDR(r5, ftrace_trace_function)
@@ -1236,28 +1204,55 @@ _GLOBAL(_mcount)
 
 	mtctr	r5
 	bctrl
-
 	nop
 
-	lwz	r6, 8(r1)
-	lwz	r0, 44(r1)
-	lwz	r3, 12(r1)
-	mtctr	r0
-	lwz	r4, 16(r1)
-	mtcr	r6
-	lwz	r5, 20(r1)
-	lwz	r6, 24(r1)
-	lwz	r0, 52(r1)
-	lwz	r7, 28(r1)
-	lwz	r8, 32(r1)
-	mtlr	r0
-	lwz	r9, 36(r1)
-	lwz	r10,40(r1)
-	addi	r1, r1, 48
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	b	ftrace_graph_caller
+#endif
+	MCOUNT_RESTORE_FRAME
 	bctr
 #endif
 
 _GLOBAL(ftrace_stub)
 	blr
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+_GLOBAL(ftrace_graph_caller)
+	/* load r4 with local address */
+	lwz	r4, 44(r1)
+	subi	r4, r4, MCOUNT_INSN_SIZE
+
+	/* get the parent address */
+	addi	r3, r1, 52
+
+	bl	prepare_ftrace_return
+	nop
+
+	MCOUNT_RESTORE_FRAME
+	/* old link register ends up in ctr reg */
+	bctr
+
+_GLOBAL(return_to_handler)
+	/* need to save return values */
+	stwu	r1, -32(r1)
+	stw	r3, 20(r1)
+	stw	r4, 16(r1)
+	stw	r31, 12(r1)
+	mr	r31, r1
+
+	bl	ftrace_return_to_handler
+	nop
+
+	/* return value has real return address */
+	mtlr	r3
+
+	lwz	r3, 20(r1)
+	lwz	r4, 16(r1)
+	lwz	r31,12(r1)
+	lwz	r1, 0(r1)
+
+	/* Jump back to real return address */
+	blr
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
 #endif /* CONFIG_MCOUNT */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/entry_64.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/entry_64.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/entry_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/entry_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -908,6 +908,12 @@ _GLOBAL(ftrace_caller)
 ftrace_call:
 	bl	ftrace_stub
 	nop
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+.globl ftrace_graph_call
+ftrace_graph_call:
+	b	ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+#endif
 	ld	r0, 128(r1)
 	mtlr	r0
 	addi	r1, r1, 112
@@ -931,13 +937,90 @@ _GLOBAL(_mcount)
 	ld	r5,0(r5)
 	mtctr	r5
 	bctrl
-
 	nop
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	b	ftrace_graph_caller
+#endif
 	ld	r0, 128(r1)
 	mtlr	r0
 	addi	r1, r1, 112
 _GLOBAL(ftrace_stub)
 	blr
 
-#endif
-#endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+_GLOBAL(ftrace_graph_caller)
+	/* load r4 with local address */
+	ld	r4, 128(r1)
+	subi	r4, r4, MCOUNT_INSN_SIZE
+
+	/* get the parent address */
+	ld	r11, 112(r1)
+	addi	r3, r11, 16
+
+	bl	.prepare_ftrace_return
+	nop
+
+	ld	r0, 128(r1)
+	mtlr	r0
+	addi	r1, r1, 112
+	blr
+
+_GLOBAL(return_to_handler)
+	/* need to save return values */
+	std	r4,  -24(r1)
+	std	r3,  -16(r1)
+	std	r31, -8(r1)
+	mr	r31, r1
+	stdu	r1, -112(r1)
+
+	bl	.ftrace_return_to_handler
+	nop
+
+	/* return value has real return address */
+	mtlr	r3
+
+	ld	r1, 0(r1)
+	ld	r4,  -24(r1)
+	ld	r3,  -16(r1)
+	ld	r31, -8(r1)
+
+	/* Jump back to real return address */
+	blr
+
+_GLOBAL(mod_return_to_handler)
+	/* need to save return values */
+	std	r4,  -32(r1)
+	std	r3,  -24(r1)
+	/* save TOC */
+	std	r2,  -16(r1)
+	std	r31, -8(r1)
+	mr	r31, r1
+	stdu	r1, -112(r1)
+
+	/*
+	 * We are in a module using the module's TOC.
+	 * Switch to our TOC to run inside the core kernel.
+	 */
+	LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
+	ld	r2, 8(r4)
+
+	bl	.ftrace_return_to_handler
+	nop
+
+	/* return value has real return address */
+	mtlr	r3
+
+	ld	r1, 0(r1)
+	ld	r4,  -32(r1)
+	ld	r3,  -24(r1)
+	ld	r2,  -16(r1)
+	ld	r31, -8(r1)
+
+	/* Jump back to real return address */
+	blr
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/fpu.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/fpu.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/fpu.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/fpu.S	2009-06-09 23:05:27.000000000 -0400
@@ -145,6 +145,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 	beq	1f
 	PPC_LL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 	li	r3,MSR_FP|MSR_FE0|MSR_FE1
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+	oris	r3,r3,MSR_VSX@h
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
 	andc	r4,r4,r3		/* disable FP for previous task */
 	PPC_STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/ftrace.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/ftrace.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/ftrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/ftrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,9 @@
  *
  * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box.
  *
+ * Added function graph tracer code, taken from x86 that was written
+ * by Frederic Weisbecker, and ported to PPC by Steven Rostedt.
+ *
  */
 
 #include <linux/spinlock.h>
@@ -20,14 +23,6 @@
 #include <asm/code-patching.h>
 #include <asm/ftrace.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt , ...)	do { } while (0)
-#endif
-
-static unsigned int ftrace_nop = PPC_NOP_INSTR;
-
 #ifdef CONFIG_PPC32
 # define GET_ADDR(addr) addr
 #else
@@ -35,37 +30,23 @@ static unsigned int ftrace_nop = PPC_NOP
 # define GET_ADDR(addr) (*(unsigned long *)addr)
 #endif
 
-
-static unsigned int ftrace_calc_offset(long ip, long addr)
-{
-	return (int)(addr - ip);
-}
-
-static unsigned char *ftrace_nop_replace(void)
+#ifdef CONFIG_DYNAMIC_FTRACE
+static unsigned int ftrace_nop_replace(void)
 {
-	return (char *)&ftrace_nop;
+	return PPC_INST_NOP;
 }
 
-static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+static unsigned int
+ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
-	static unsigned int op;
+	unsigned int op;
 
-	/*
-	 * It would be nice to just use create_function_call, but that will
-	 * update the code itself. Here we need to just return the
-	 * instruction that is going to be modified, without modifying the
-	 * code.
-	 */
 	addr = GET_ADDR(addr);
 
-	/* Set to "bl addr" */
-	op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);
+	/* if (link) set op to 'bl' else 'b' */
+	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
 
-	/*
-	 * No locking needed, this must be called via kstop_machine
-	 * which in essence is like running on a uniprocessor machine.
-	 */
-	return (unsigned char *)&op;
+	return op;
 }
 
 #ifdef CONFIG_PPC64
@@ -77,10 +58,9 @@ static unsigned char *ftrace_call_replac
 #endif
 
 static int
-ftrace_modify_code(unsigned long ip, unsigned char *old_code,
-		   unsigned char *new_code)
+ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
 {
-	unsigned char replaced[MCOUNT_INSN_SIZE];
+	unsigned int replaced;
 
 	/*
 	 * Note: Due to modules and __init, code can
@@ -93,15 +73,15 @@ ftrace_modify_code(unsigned long ip, uns
 	 */
 
 	/* read the text we want to modify */
-	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+	if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
 		return -EFAULT;
 
 	/* Make sure it is what we expect it to be */
-	if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+	if (replaced != old)
 		return -EINVAL;
 
 	/* replace the text with the new text */
-	if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
+	if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE))
 		return -EPERM;
 
 	flush_icache_range(ip, ip + 8);
@@ -119,6 +99,8 @@ static int test_24bit_addr(unsigned long
 	return create_branch((unsigned int *)ip, addr, 0);
 }
 
+#ifdef CONFIG_MODULES
+
 static int is_bl_op(unsigned int op)
 {
 	return (op & 0xfc000003) == 0x48000001;
@@ -175,7 +157,7 @@ __ftrace_make_nop(struct module *mod,
 	 * 0xe8, 0x4c, 0x00, 0x28,    ld      r2,40(r12)
 	 */
 
-	DEBUGP("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
+	pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
 
 	/* Find where the trampoline jumps to */
 	if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -183,7 +165,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EFAULT;
 	}
 
-	DEBUGP(" %08x %08x", jmp[0], jmp[1]);
+	pr_devel(" %08x %08x", jmp[0], jmp[1]);
 
 	/* verify that this is what we expect it to be */
 	if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
@@ -199,18 +181,18 @@ __ftrace_make_nop(struct module *mod,
 	offset = ((unsigned)((unsigned short)jmp[0]) << 16) +
 		(int)((short)jmp[1]);
 
-	DEBUGP(" %x ", offset);
+	pr_devel(" %x ", offset);
 
 	/* get the address this jumps too */
 	tramp = mod->arch.toc + offset + 32;
-	DEBUGP("toc: %lx", tramp);
+	pr_devel("toc: %lx", tramp);
 
 	if (probe_kernel_read(jmp, (void *)tramp, 8)) {
 		printk(KERN_ERR "Failed to read %lx\n", tramp);
 		return -EFAULT;
 	}
 
-	DEBUGP(" %08x %08x\n", jmp[0], jmp[1]);
+	pr_devel(" %08x %08x\n", jmp[0], jmp[1]);
 
 	ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
 
@@ -287,7 +269,7 @@ __ftrace_make_nop(struct module *mod,
 	 *  0x4e, 0x80, 0x04, 0x20  bctr
 	 */
 
-	DEBUGP("ip:%lx jumps to %lx", ip, tramp);
+	pr_devel("ip:%lx jumps to %lx", ip, tramp);
 
 	/* Find where the trampoline jumps to */
 	if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -295,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EFAULT;
 	}
 
-	DEBUGP(" %08x %08x ", jmp[0], jmp[1]);
+	pr_devel(" %08x %08x ", jmp[0], jmp[1]);
 
 	/* verify that this is what we expect it to be */
 	if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
@@ -311,7 +293,7 @@ __ftrace_make_nop(struct module *mod,
 	if (tramp & 0x8000)
 		tramp -= 0x10000;
 
-	DEBUGP(" %x ", tramp);
+	pr_devel(" %lx ", tramp);
 
 	if (tramp != addr) {
 		printk(KERN_ERR
@@ -320,7 +302,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EINVAL;
 	}
 
-	op = PPC_NOP_INSTR;
+	op = PPC_INST_NOP;
 
 	if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
 		return -EPERM;
@@ -330,12 +312,13 @@ __ftrace_make_nop(struct module *mod,
 	return 0;
 }
 #endif /* PPC64 */
+#endif /* CONFIG_MODULES */
 
 int ftrace_make_nop(struct module *mod,
 		    struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned char *old, *new;
 	unsigned long ip = rec->ip;
+	unsigned int old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -344,11 +327,12 @@ int ftrace_make_nop(struct module *mod,
 	 */
 	if (test_24bit_addr(ip, addr)) {
 		/* within range */
-		old = ftrace_call_replace(ip, addr);
+		old = ftrace_call_replace(ip, addr, 1);
 		new = ftrace_nop_replace();
 		return ftrace_modify_code(ip, old, new);
 	}
 
+#ifdef CONFIG_MODULES
 	/*
 	 * Out of range jumps are called from modules.
 	 * We should either already have a pointer to the module
@@ -373,9 +357,13 @@ int ftrace_make_nop(struct module *mod,
 		mod = rec->arch.mod;
 
 	return __ftrace_make_nop(mod, rec, addr);
-
+#else
+	/* We should not get here without modules */
+	return -EINVAL;
+#endif /* CONFIG_MODULES */
 }
 
+#ifdef CONFIG_MODULES
 #ifdef CONFIG_PPC64
 static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
@@ -392,7 +380,7 @@ __ftrace_make_call(struct dyn_ftrace *re
 	 *  b +8; ld r2,40(r1)
 	 */
 	if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
-	    ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) {
+	    ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
 		printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
 		return -EINVAL;
 	}
@@ -414,7 +402,7 @@ __ftrace_make_call(struct dyn_ftrace *re
 	/* ld r2,40(r1) */
 	op[1] = 0xe8410028;
 
-	DEBUGP("write to %lx\n", rec->ip);
+	pr_devel("write to %lx\n", rec->ip);
 
 	if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
 		return -EPERM;
@@ -435,7 +423,7 @@ __ftrace_make_call(struct dyn_ftrace *re
 		return -EFAULT;
 
 	/* It should be pointing to a nop */
-	if (op != PPC_NOP_INSTR) {
+	if (op != PPC_INST_NOP) {
 		printk(KERN_ERR "Expected NOP but have %x\n", op);
 		return -EINVAL;
 	}
@@ -454,7 +442,7 @@ __ftrace_make_call(struct dyn_ftrace *re
 		return -EINVAL;
 	}
 
-	DEBUGP("write to %lx\n", rec->ip);
+	pr_devel("write to %lx\n", rec->ip);
 
 	if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
 		return -EPERM;
@@ -464,11 +452,12 @@ __ftrace_make_call(struct dyn_ftrace *re
 	return 0;
 }
 #endif /* CONFIG_PPC64 */
+#endif /* CONFIG_MODULES */
 
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned char *old, *new;
 	unsigned long ip = rec->ip;
+	unsigned int old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -478,10 +467,11 @@ int ftrace_make_call(struct dyn_ftrace *
 	if (test_24bit_addr(ip, addr)) {
 		/* within range */
 		old = ftrace_nop_replace();
-		new = ftrace_call_replace(ip, addr);
+		new = ftrace_call_replace(ip, addr, 1);
 		return ftrace_modify_code(ip, old, new);
 	}
 
+#ifdef CONFIG_MODULES
 	/*
 	 * Out of range jumps are called from modules.
 	 * Being that we are converting from nop, it had better
@@ -493,16 +483,20 @@ int ftrace_make_call(struct dyn_ftrace *
 	}
 
 	return __ftrace_make_call(rec, addr);
+#else
+	/* We should not get here without modules */
+	return -EINVAL;
+#endif /* CONFIG_MODULES */
 }
 
 int ftrace_update_ftrace_func(ftrace_func_t func)
 {
 	unsigned long ip = (unsigned long)(&ftrace_call);
-	unsigned char old[MCOUNT_INSN_SIZE], *new;
+	unsigned int old, new;
 	int ret;
 
-	memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
-	new = ftrace_call_replace(ip, (unsigned long)func);
+	old = *(unsigned int *)&ftrace_call;
+	new = ftrace_call_replace(ip, (unsigned long)func, 1);
 	ret = ftrace_modify_code(ip, old, new);
 
 	return ret;
@@ -517,3 +511,111 @@ int __init ftrace_dyn_arch_init(void *da
 
 	return 0;
 }
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+extern void ftrace_graph_stub(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
+	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
+	unsigned int old, new;
+
+	old = ftrace_call_replace(ip, stub, 0);
+	new = ftrace_call_replace(ip, addr, 0);
+
+	return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
+	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
+	unsigned int old, new;
+
+	old = ftrace_call_replace(ip, addr, 0);
+	new = ftrace_call_replace(ip, stub, 0);
+
+	return ftrace_modify_code(ip, old, new);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_PPC64
+extern void mod_return_to_handler(void);
+#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 old;
+	int faulted;
+	struct ftrace_graph_ent trace;
+	unsigned long return_hooker = (unsigned long)&return_to_handler;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+#ifdef CONFIG_PPC64
+	/* non core kernel code needs to save and restore the TOC */
+	if (REGION_ID(self_addr) != KERNEL_REGION_ID)
+		return_hooker = (unsigned long)&mod_return_to_handler;
+#endif
+
+	return_hooker = GET_ADDR(return_hooker);
+
+	/*
+	 * Protect against fault, even if it shouldn't
+	 * happen. This tool is too much intrusive to
+	 * ignore such a protection.
+	 */
+	asm volatile(
+		"1: " PPC_LL "%[old], 0(%[parent])\n"
+		"2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
+		"   li %[faulted], 0\n"
+		"3:\n"
+
+		".section .fixup, \"ax\"\n"
+		"4: li %[faulted], 1\n"
+		"   b 3b\n"
+		".previous\n"
+
+		".section __ex_table,\"a\"\n"
+			PPC_LONG_ALIGN "\n"
+			PPC_LONG "1b,4b\n"
+			PPC_LONG "2b,4b\n"
+		".previous"
+
+		: [old] "=&r" (old), [faulted] "=r" (faulted)
+		: [parent] "r" (parent), [return_hooker] "r" (return_hooker)
+		: "memory"
+	);
+
+	if (unlikely(faulted)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		return;
+	}
+
+	if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -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 */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_32.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_32.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <asm/reg.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
@@ -50,7 +51,7 @@
 	mtspr	SPRN_DBAT##n##L,RB;	\
 1:
 
-	.section	.text.head, "ax"
+	__HEAD
 	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
 	.stabs	"head_32.S",N_SO,0,0,0f
 0:
@@ -108,18 +109,21 @@ __start:
  * because OF may have I/O devices mapped into that area
  * (particularly on CHRP).
  */
-#ifdef CONFIG_PPC_MULTIPLATFORM
 	cmpwi	0,r5,0
 	beq	1f
 
+#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
 	/* find out where we are now */
 	bcl	20,31,$+4
 0:	mflr	r8			/* r8 = runtime addr here */
 	addis	r8,r8,(_stext - 0b)@ha
 	addi	r8,r8,(_stext - 0b)@l	/* current runtime base addr */
 	bl	prom_init
+#endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */
+
+	/* We never return. We also hit that trap if trying to boot
+	 * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
 	trap
-#endif
 
 /*
  * Check for BootX signature when supporting PowerMac and branch to
@@ -472,12 +476,11 @@ SystemCall:
 	. = 0x1000
 InstructionTLBMiss:
 /*
- * r0:	stored ctr
+ * r0:	scratch
  * r1:	linux style pte ( later becomes ppc hardware pte )
  * r2:	ptr to linux-style pte
  * r3:	scratch
  */
-	mfctr	r0
 	/* Get PTE (linux-style) and check access */
 	mfspr	r3,SPRN_IMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
@@ -496,28 +499,27 @@ InstructionTLBMiss:
 	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
 	beq-	InstructionAddressInvalid	/* return if no mapping */
 	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
-	lwz	r3,0(r2)		/* get linux-style pte */
-	andc.	r1,r1,r3		/* check access & ~permission */
+	lwz	r0,0(r2)		/* get linux-style pte */
+	andc.	r1,r1,r0		/* check access & ~permission */
 	bne-	InstructionAddressInvalid /* return if access not permitted */
-	ori	r3,r3,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
+	ori	r0,r0,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
 	/*
 	 * NOTE! We are assuming this is not an SMP system, otherwise
 	 * we would need to update the pte atomically with lwarx/stwcx.
 	 */
-	stw	r3,0(r2)		/* update PTE (accessed bit) */
+	stw	r0,0(r2)		/* update PTE (accessed bit) */
 	/* Convert linux-style PTE to low word of PPC-style PTE */
-	rlwinm	r1,r3,32-10,31,31	/* _PAGE_RW -> PP lsb */
-	rlwinm	r2,r3,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
+	rlwinm	r1,r0,32-10,31,31	/* _PAGE_RW -> PP lsb */
+	rlwinm	r2,r0,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
 	and	r1,r1,r2		/* writable if _RW and _DIRTY */
-	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
-	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
+	rlwimi	r0,r0,32-1,30,30	/* _PAGE_USER -> PP msb */
+	rlwimi	r0,r0,32-1,31,31	/* _PAGE_USER -> PP lsb */
 	ori	r1,r1,0xe04		/* clear out reserved bits */
-	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
+	andc	r1,r0,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
 BEGIN_FTR_SECTION
 	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtspr	SPRN_RPA,r1
-	mfspr	r3,SPRN_IMISS
 	tlbli	r3
 	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
 	mtcrf	0x80,r3
@@ -528,7 +530,6 @@ InstructionAddressInvalid:
 
 	addis	r1,r1,0x2000
 	mtspr	SPRN_DSISR,r1	/* (shouldn't be needed) */
-	mtctr	r0		/* Restore CTR */
 	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
 	or	r2,r2,r1
 	mtspr	SPRN_SRR1,r2
@@ -549,12 +550,11 @@ InstructionAddressInvalid:
 	. = 0x1100
 DataLoadTLBMiss:
 /*
- * r0:	stored ctr
+ * r0:	scratch
  * r1:	linux style pte ( later becomes ppc hardware pte )
  * r2:	ptr to linux-style pte
  * r3:	scratch
  */
-	mfctr	r0
 	/* Get PTE (linux-style) and check access */
 	mfspr	r3,SPRN_DMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
@@ -573,38 +573,48 @@ DataLoadTLBMiss:
 	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
 	beq-	DataAddressInvalid	/* return if no mapping */
 	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
-	lwz	r3,0(r2)		/* get linux-style pte */
-	andc.	r1,r1,r3		/* check access & ~permission */
+	lwz	r0,0(r2)		/* get linux-style pte */
+	andc.	r1,r1,r0		/* check access & ~permission */
 	bne-	DataAddressInvalid	/* return if access not permitted */
-	ori	r3,r3,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
+	ori	r0,r0,_PAGE_ACCESSED	/* set _PAGE_ACCESSED in pte */
 	/*
 	 * NOTE! We are assuming this is not an SMP system, otherwise
 	 * we would need to update the pte atomically with lwarx/stwcx.
 	 */
-	stw	r3,0(r2)		/* update PTE (accessed bit) */
+	stw	r0,0(r2)		/* update PTE (accessed bit) */
 	/* Convert linux-style PTE to low word of PPC-style PTE */
-	rlwinm	r1,r3,32-10,31,31	/* _PAGE_RW -> PP lsb */
-	rlwinm	r2,r3,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
+	rlwinm	r1,r0,32-10,31,31	/* _PAGE_RW -> PP lsb */
+	rlwinm	r2,r0,32-7,31,31	/* _PAGE_DIRTY -> PP lsb */
 	and	r1,r1,r2		/* writable if _RW and _DIRTY */
-	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
-	rlwimi	r3,r3,32-1,31,31	/* _PAGE_USER -> PP lsb */
+	rlwimi	r0,r0,32-1,30,30	/* _PAGE_USER -> PP msb */
+	rlwimi	r0,r0,32-1,31,31	/* _PAGE_USER -> PP lsb */
 	ori	r1,r1,0xe04		/* clear out reserved bits */
-	andc	r1,r3,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
+	andc	r1,r0,r1		/* PP = user? (rw&dirty? 2: 3): 0 */
 BEGIN_FTR_SECTION
 	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtspr	SPRN_RPA,r1
-	mfspr	r3,SPRN_DMISS
+	mfspr	r2,SPRN_SRR1		/* Need to restore CR0 */
+	mtcrf	0x80,r2
+BEGIN_MMU_FTR_SECTION
+	li	r0,1
+	mfspr	r1,SPRN_SPRG4
+	rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
+	slw	r0,r0,r2
+	xor	r1,r0,r1
+	srw	r0,r1,r2
+	mtspr   SPRN_SPRG4,r1
+	mfspr	r2,SPRN_SRR1
+	rlwimi	r2,r0,31-14,14,14
+	mtspr   SPRN_SRR1,r2
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 	tlbld	r3
-	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
-	mtcrf	0x80,r3
 	rfi
 DataAddressInvalid:
 	mfspr	r3,SPRN_SRR1
 	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
 	addis	r1,r1,0x2000
 	mtspr	SPRN_DSISR,r1
-	mtctr	r0		/* Restore CTR */
 	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
 	mtspr	SPRN_SRR1,r2
 	mfspr	r1,SPRN_DMISS	/* Get failing address */
@@ -624,12 +634,11 @@ DataAddressInvalid:
 	. = 0x1200
 DataStoreTLBMiss:
 /*
- * r0:	stored ctr
+ * r0:	scratch
  * r1:	linux style pte ( later becomes ppc hardware pte )
  * r2:	ptr to linux-style pte
  * r3:	scratch
  */
-	mfctr	r0
 	/* Get PTE (linux-style) and check access */
 	mfspr	r3,SPRN_DMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
@@ -648,27 +657,38 @@ DataStoreTLBMiss:
 	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
 	beq-	DataAddressInvalid	/* return if no mapping */
 	rlwimi	r2,r3,22,20,29		/* insert next 10 bits of address */
-	lwz	r3,0(r2)		/* get linux-style pte */
-	andc.	r1,r1,r3		/* check access & ~permission */
+	lwz	r0,0(r2)		/* get linux-style pte */
+	andc.	r1,r1,r0		/* check access & ~permission */
 	bne-	DataAddressInvalid	/* return if access not permitted */
-	ori	r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
+	ori	r0,r0,_PAGE_ACCESSED|_PAGE_DIRTY
 	/*
 	 * NOTE! We are assuming this is not an SMP system, otherwise
 	 * we would need to update the pte atomically with lwarx/stwcx.
 	 */
-	stw	r3,0(r2)		/* update PTE (accessed/dirty bits) */
+	stw	r0,0(r2)		/* update PTE (accessed/dirty bits) */
 	/* Convert linux-style PTE to low word of PPC-style PTE */
-	rlwimi	r3,r3,32-1,30,30	/* _PAGE_USER -> PP msb */
+	rlwimi	r0,r0,32-1,30,30	/* _PAGE_USER -> PP msb */
 	li	r1,0xe05		/* clear out reserved bits & PP lsb */
-	andc	r1,r3,r1		/* PP = user? 2: 0 */
+	andc	r1,r0,r1		/* PP = user? 2: 0 */
 BEGIN_FTR_SECTION
 	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtspr	SPRN_RPA,r1
-	mfspr	r3,SPRN_DMISS
+	mfspr	r2,SPRN_SRR1		/* Need to restore CR0 */
+	mtcrf	0x80,r2
+BEGIN_MMU_FTR_SECTION
+	li	r0,1
+	mfspr	r1,SPRN_SPRG4
+	rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
+	slw	r0,r0,r2
+	xor	r1,r0,r1
+	srw	r0,r1,r2
+	mtspr   SPRN_SPRG4,r1
+	mfspr	r2,SPRN_SRR1
+	rlwimi	r2,r0,31-14,14,14
+	mtspr   SPRN_SRR1,r2
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 	tlbld	r3
-	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
-	mtcrf	0x80,r3
 	rfi
 
 #ifndef CONFIG_ALTIVEC
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_40x.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_40x.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_40x.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_40x.S	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
@@ -52,7 +53,7 @@
  *
  * This is all going to change RSN when we add bi_recs.......  -- Dan
  */
-	.section	.text.head, "ax"
+	__HEAD
 _ENTRY(_stext);
 _ENTRY(_start);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_44x.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_44x.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_44x.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_44x.S	2009-06-09 23:05:27.000000000 -0400
@@ -28,6 +28,7 @@
  * option) any later version.
  */
 
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
@@ -50,7 +51,7 @@
  *   r7 - End of kernel command line string
  *
  */
-	.section	.text.head, "ax"
+	__HEAD
 _ENTRY(_stext);
 _ENTRY(_start);
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_64.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_64.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -1360,6 +1360,7 @@ _GLOBAL(__start_initialization_multiplat
 	b	.__after_prom_start
 
 _INIT_STATIC(__boot_from_prom)
+#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
 	/* Save parameters */
 	mr	r31,r3
 	mr	r30,r4
@@ -1390,7 +1391,10 @@ _INIT_STATIC(__boot_from_prom)
 	/* Do all of the interaction with OF client interface */
 	mr	r8,r26
 	bl	.prom_init
-	/* We never return */
+#endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */
+
+	/* We never return. We also hit that trap if trying to boot
+	 * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
 	trap
 
 _STATIC(__after_prom_start)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_8xx.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_8xx.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_8xx.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_8xx.S	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
@@ -38,7 +39,7 @@
 #else
 #define DO_8xx_CPU6(val, reg)
 #endif
-	.section	.text.head, "ax"
+	__HEAD
 _ENTRY(_stext);
 _ENTRY(_start);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_booke.h linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_booke.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_booke.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_booke.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,15 @@
 		mtspr	SPRN_IVOR##vector_number,r26;	\
 		sync
 
+#if (THREAD_SHIFT < 15)
+#define ALLOC_STACK_FRAME(reg, val)			\
+	addi reg,reg,val
+#else
+#define ALLOC_STACK_FRAME(reg, val)			\
+	addis	reg,reg,val@ha;				\
+	addi	reg,reg,val@l
+#endif
+
 #define NORMAL_EXCEPTION_PROLOG						     \
 	mtspr	SPRN_SPRG0,r10;		/* save two registers to work with */\
 	mtspr	SPRN_SPRG1,r11;						     \
@@ -20,7 +29,7 @@
 	beq	1f;							     \
 	mfspr	r1,SPRN_SPRG3;		/* if from user, start at top of   */\
 	lwz	r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
-	addi	r1,r1,THREAD_SIZE;					     \
+	ALLOC_STACK_FRAME(r1, THREAD_SIZE);				     \
 1:	subi	r1,r1,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
 	mr	r11,r1;							     \
 	stw	r10,_CCR(r11);          /* save various registers	   */\
@@ -70,10 +79,10 @@
 
 /* only on e500mc/e200 */
 #define DEBUG_STACK_BASE	dbgirq_ctx
-#ifdef CONFIG_PPC_E500MC
-#define DEBUG_SPRG		SPRN_SPRG9
-#else
+#ifdef CONFIG_E200
 #define DEBUG_SPRG		SPRN_SPRG6W
+#else
+#define DEBUG_SPRG		SPRN_SPRG9
 #endif
 
 #define EXC_LVL_FRAME_OVERHEAD	(THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
@@ -279,7 +288,7 @@ label:
 	lwz	r11,GPR11(r8);						      \
 	mfspr	r8,DEBUG_SPRG;						      \
 									      \
-	RFDI;								      \
+	PPC_RFDI;								      \
 	b	.;							      \
 									      \
 	/* continue normal handling for a debug exception... */		      \
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_fsl_booke.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_fsl_booke.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,7 @@
  * option) any later version.
  */
 
+#include <linux/init.h>
 #include <linux/threads.h>
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -53,7 +54,7 @@
  *   r7 - End of kernel command line string
  *
  */
-	.section	.text.head, "ax"
+	__HEAD
 _ENTRY(_stext);
 _ENTRY(_start);
 	/*
@@ -103,10 +104,15 @@ invstr:	mflr	r6				/* Make it accessible
 	or	r7,r7,r4
 	mtspr	SPRN_MAS6,r7
 	tlbsx	0,r6				/* search MSR[IS], SPID=PID0 */
-#ifndef CONFIG_E200
 	mfspr	r7,SPRN_MAS1
 	andis.	r7,r7,MAS1_VALID@h
 	bne	match_TLB
+
+	mfspr	r7,SPRN_MMUCFG
+	rlwinm	r7,r7,21,28,31			/* extract MMUCFG[NPIDS] */
+	cmpwi	r7,3
+	bne	match_TLB			/* skip if NPIDS != 3 */
+
 	mfspr	r7,SPRN_PID1
 	slwi	r7,r7,16
 	or	r7,r7,r4
@@ -120,7 +126,7 @@ invstr:	mflr	r6				/* Make it accessible
 	or	r7,r7,r4
 	mtspr	SPRN_MAS6,r7
 	tlbsx	0,r6				/* Fall through, we had to match */
-#endif
+
 match_TLB:
 	mfspr	r7,SPRN_MAS0
 	rlwinm	r3,r7,16,20,31			/* Extract MAS0(Entry) */
@@ -168,7 +174,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 
 	/* grab and fixup the RPN */
 	mfspr	r6,SPRN_MAS1	/* extract MAS1[SIZE] */
-	rlwinm	r6,r6,25,27,30
+	rlwinm	r6,r6,25,27,31
 	li	r8,-1
 	addi	r6,r6,10
 	slw	r6,r8,r6	/* convert to mask */
@@ -194,7 +200,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	xori	r6,r4,1		/* Setup TMP mapping in the other Address space */
 	slwi	r6,r6,12
 	oris	r6,r6,(MAS1_VALID|MAS1_IPROT)@h
-	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
 	mtspr	SPRN_MAS1,r6
 	mfspr	r6,SPRN_MAS2
 	li	r7,0		/* temp EPN = 0 */
@@ -215,14 +221,19 @@ skpinv:	addi	r6,r6,1				/* Increment */
 
 /* 4. Clear out PIDs & Search info */
 	li	r6,0
+	mtspr   SPRN_MAS6,r6
 	mtspr	SPRN_PID0,r6
-#ifndef CONFIG_E200
+
+	mfspr	r7,SPRN_MMUCFG
+	rlwinm	r7,r7,21,28,31			/* extract MMUCFG[NPIDS] */
+	cmpwi	r7,3
+	bne	2f				/* skip if NPIDS != 3 */
+
 	mtspr	SPRN_PID1,r6
 	mtspr	SPRN_PID2,r6
-#endif
-	mtspr	SPRN_MAS6,r6
 
 /* 5. Invalidate mapping we started in */
+2:
 	lis	r7,0x1000	/* Set MAS0(TLBSEL) = 1 */
 	rlwimi	r7,r3,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r3) */
 	mtspr	SPRN_MAS0,r7
@@ -247,10 +258,10 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	lis	r6,0x1000		/* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
 	mtspr	SPRN_MAS0,r6
 	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
-	ori	r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
+	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
 	mtspr	SPRN_MAS1,r6
-	lis	r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h
-	ori	r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l
+	lis	r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
+	ori	r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
 	mtspr	SPRN_MAS2,r6
 	mtspr	SPRN_MAS3,r8
 	tlbwe
@@ -298,26 +309,14 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	SET_IVOR(12, WatchdogTimer);
 	SET_IVOR(13, DataTLBError);
 	SET_IVOR(14, InstructionTLBError);
-	SET_IVOR(15, DebugDebug);
-#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
 	SET_IVOR(15, DebugCrit);
-#endif
-	SET_IVOR(32, SPEUnavailable);
-	SET_IVOR(33, SPEFloatingPointData);
-	SET_IVOR(34, SPEFloatingPointRound);
-#ifndef CONFIG_E200
-	SET_IVOR(35, PerformanceMonitor);
-#endif
-#ifdef CONFIG_PPC_E500MC
-	SET_IVOR(36, Doorbell);
-#endif
 
 	/* Establish the interrupt vector base */
 	lis	r4,interrupt_base@h	/* IVPR only uses the high 16-bits */
 	mtspr	SPRN_IVPR,r4
 
 	/* Setup the defaults for TLB entries */
-	li	r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+	li	r2,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
 #ifdef CONFIG_E200
 	oris	r2,r2,MAS4_TLBSELD(1)@h
 #endif
@@ -329,12 +328,6 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	oris	r2,r2,HID0_DOZE@h
 	mtspr	SPRN_HID0, r2
 #endif
-#ifdef CONFIG_E200
-	/* enable dedicated debug exception handling resources (Debug APU) */
-	mfspr	r2,SPRN_HID0
-	ori	r2,r2,HID0_DAPUEN@l
-	mtspr	SPRN_HID0,r2
-#endif
 
 #if !defined(CONFIG_BDI_SWITCH)
 	/*
@@ -706,15 +699,13 @@ interrupt_base:
 	/* Performance Monitor */
 	EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
 
-#ifdef CONFIG_PPC_E500MC
-	EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD)
-#endif
+	EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD)
+
+	CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception)
 
 	/* Debug Interrupt */
 	DEBUG_DEBUG_EXCEPTION
-#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
 	DEBUG_CRIT_EXCEPTION
-#endif
 
 /*
  * Local functions
@@ -897,6 +888,47 @@ KernelSPE:
  * Global functions
  */
 
+/* Adjust or setup IVORs for e200 */
+_GLOBAL(__setup_e200_ivors)
+	li	r3,DebugDebug@l
+	mtspr	SPRN_IVOR15,r3
+	li	r3,SPEUnavailable@l
+	mtspr	SPRN_IVOR32,r3
+	li	r3,SPEFloatingPointData@l
+	mtspr	SPRN_IVOR33,r3
+	li	r3,SPEFloatingPointRound@l
+	mtspr	SPRN_IVOR34,r3
+	sync
+	blr
+
+/* Adjust or setup IVORs for e500v1/v2 */
+_GLOBAL(__setup_e500_ivors)
+	li	r3,DebugCrit@l
+	mtspr	SPRN_IVOR15,r3
+	li	r3,SPEUnavailable@l
+	mtspr	SPRN_IVOR32,r3
+	li	r3,SPEFloatingPointData@l
+	mtspr	SPRN_IVOR33,r3
+	li	r3,SPEFloatingPointRound@l
+	mtspr	SPRN_IVOR34,r3
+	li	r3,PerformanceMonitor@l
+	mtspr	SPRN_IVOR35,r3
+	sync
+	blr
+
+/* Adjust or setup IVORs for e500mc */
+_GLOBAL(__setup_e500mc_ivors)
+	li	r3,DebugDebug@l
+	mtspr	SPRN_IVOR15,r3
+	li	r3,PerformanceMonitor@l
+	mtspr	SPRN_IVOR35,r3
+	li	r3,Doorbell@l
+	mtspr	SPRN_IVOR36,r3
+	li	r3,CriticalDoorbell@l
+	mtspr	SPRN_IVOR37,r3
+	sync
+	blr
+
 /*
  * extern void loadcam_entry(unsigned int index)
  *
@@ -1089,7 +1121,7 @@ __secondary_start:
 	mtspr	SPRN_SPRG3,r4
 
 	/* Setup the defaults for TLB entries */
-	li	r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+	li	r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
 	mtspr	SPRN_MAS4,r4
 
 	/* Jump to start_secondary */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/irq.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -171,7 +171,7 @@ int show_interrupts(struct seq_file *p,
 {
 	int i = *(loff_t *)v, j;
 	struct irqaction *action;
-	irq_desc_t *desc;
+	struct irq_desc *desc;
 	unsigned long flags;
 
 	if (i == 0) {
@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
@@ -231,7 +231,7 @@ void fixup_irqs(cpumask_t map)
 		if (irq_desc[irq].status & IRQ_PER_CPU)
 			continue;
 
-		cpus_and(mask, irq_desc[irq].affinity, map);
+		cpumask_and(&mask, irq_desc[irq].affinity, &map);
 		if (any_online_cpu(mask) == NR_CPUS) {
 			printk("Breaking affinity for irq %i\n", irq);
 			mask = map;
@@ -672,11 +672,13 @@ unsigned int irq_create_mapping(struct i
 			return NO_IRQ;
 		}
 	}
-	pr_debug("irq: -> obtained virq %d\n", virq);
 
 	if (irq_setup_virq(host, virq, hwirq))
 		return NO_IRQ;
 
+	printk(KERN_DEBUG "irq: irq %lu on host %s mapped to virtual irq %u\n",
+		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
+
 	return virq;
 }
 EXPORT_SYMBOL_GPL(irq_create_mapping);
@@ -1038,7 +1040,7 @@ arch_initcall(irq_late_init);
 static int virq_debug_show(struct seq_file *m, void *private)
 {
 	unsigned long flags;
-	irq_desc_t *desc;
+	struct irq_desc *desc;
 	const char *p;
 	char none[] = "none";
 	int i;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/lparcfg.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/lparcfg.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/lparcfg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/lparcfg.c	2009-06-09 23:05:27.000000000 -0400
@@ -434,6 +434,21 @@ static void pseries_cmo_data(struct seq_
 	seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size());
 }
 
+static void splpar_dispatch_data(struct seq_file *m)
+{
+	int cpu;
+	unsigned long dispatches = 0;
+	unsigned long dispatch_dispersions = 0;
+
+	for_each_possible_cpu(cpu) {
+		dispatches += lppaca[cpu].yield_count;
+		dispatch_dispersions += lppaca[cpu].dispersion_count;
+	}
+
+	seq_printf(m, "dispatches=%lu\n", dispatches);
+	seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions);
+}
+
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
 	int partition_potential_processors;
@@ -460,6 +475,7 @@ static int pseries_lparcfg_data(struct s
 		parse_ppp_data(m);
 		parse_mpp_data(m);
 		pseries_cmo_data(m);
+		splpar_dispatch_data(m);
 
 		seq_printf(m, "purr=%ld\n", get_purr());
 	} else {		/* non SPLPAR case */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/machine_kexec.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/machine_kexec.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/machine_kexec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/machine_kexec.c	2009-06-09 23:05:27.000000000 -0400
@@ -125,8 +125,8 @@ void __init reserve_crashkernel(void)
 	/* Crash kernel trumps memory limit */
 	if (memory_limit && memory_limit <= crashk_res.end) {
 		memory_limit = crashk_res.end + 1;
-		printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
-				memory_limit);
+		printk("Adjusted memory limit for crashkernel, now 0x%llx\n",
+		       (unsigned long long)memory_limit);
 	}
 
 	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -18,12 +18,10 @@ CFLAGS_REMOVE_cputable.o = -pg -mno-sche
 CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
 CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
 CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
-
-ifdef CONFIG_DYNAMIC_FTRACE
-# dynamic ftrace setup.
+# do not trace tracer code
 CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
-endif
-
+# timers used by tracing
+CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog
 endif
 
 obj-y				:= cputable.o ptrace.o syscalls.o \
@@ -61,6 +59,7 @@ obj-$(CONFIG_HIBERNATION)	+= swsusp.o su
 obj64-$(CONFIG_HIBERNATION)	+= swsusp_asm64.o
 obj-$(CONFIG_MODULES)		+= module.o module_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_44x)		+= cpu_setup_44x.o
+obj-$(CONFIG_FSL_BOOKE)		+= cpu_setup_fsl_booke.o dbell.o
 
 extra-$(CONFIG_PPC_STD_MMU)	:= head_32.o
 extra-$(CONFIG_PPC64)		:= head_64.o
@@ -76,7 +75,7 @@ obj-y				+= time.o prom.o traps.o setup-
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o
 obj-$(CONFIG_PPC64)		+= dma-iommu.o iommu.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
-obj-$(CONFIG_PPC_MULTIPLATFORM)	+= prom_init.o
+obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE)	+= prom_init.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 obj-$(CONFIG_SMP)		+= smp.o
@@ -94,6 +93,7 @@ obj-$(CONFIG_AUDIT)		+= audit.o
 obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
 
 obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/misc_64.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/misc_64.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/misc_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/misc_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -495,7 +495,15 @@ _GLOBAL(giveup_altivec)
 	stvx	vr0,r4,r3
 	beq	1f
 	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+	lis	r3,(MSR_VEC|MSR_VSX)@h
+FTR_SECTION_ELSE
 	lis	r3,MSR_VEC@h
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
+#else
+	lis	r3,MSR_VEC@h
+#endif
 	andc	r4,r4,r3		/* disable FP for previous task */
 	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/module_64.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/module_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/module_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/module_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -329,7 +329,7 @@ static unsigned long stub_for_addr(Elf64
    restore r2. */
 static int restore_r2(u32 *instruction, struct module *me)
 {
-	if (*instruction != PPC_NOP_INSTR) {
+	if (*instruction != PPC_INST_NOP) {
 		printk("%s: Expect noop after relocate, got %08x\n",
 		       me->name, *instruction);
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/msi.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/msi.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/msi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/msi.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/msi.h>
+#include <linux/pci.h>
 
 #include <asm/machdep.h>
 
@@ -19,6 +20,10 @@ int arch_msi_check_device(struct pci_dev
 		return -ENOSYS;
 	}
 
+	/* PowerPC doesn't support multiple MSI yet */
+	if (type == PCI_CAP_ID_MSI && nvec > 1)
+		return 1;
+
 	if (ppc_md.msi_check_device) {
 		pr_debug("msi: Using platform check routine.\n");
 		return ppc_md.msi_check_device(dev, nvec, type);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/of_platform.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/of_platform.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/of_platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/of_platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,7 @@ struct of_device* of_platform_device_cre
 		return NULL;
 
 	dev->dma_mask = 0xffffffffUL;
-	dev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+	dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 	dev->dev.bus = &of_platform_bus_type;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci_32.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci_32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/prom.h>
 #include <asm/sections.h>
 #include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
 #include <asm/machdep.h>
@@ -43,8 +44,6 @@ static u8* pci_to_OF_bus_map;
  */
 static int pci_assign_all_buses;
 
-LIST_HEAD(hose_list);
-
 static int pci_bus_count;
 
 /* This will remain NULL for now, until isa-bridge.c is made common
@@ -219,16 +218,23 @@ scan_OF_pci_childs(struct device_node *p
 static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
 					       unsigned int devfn)
 {
-	struct device_node *np;
+	struct device_node *np, *cnp;
 	const u32 *reg;
 	unsigned int psize;
 
 	for_each_child_of_node(parent, np) {
 		reg = of_get_property(np, "reg", &psize);
-		if (reg == NULL || psize < 4)
-			continue;
-		if (((reg[0] >> 8) & 0xff) == devfn)
+                if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
 			return np;
+
+		/* Note: some OFs create a parent node "multifunc-device" as
+		 * a fake root for all functions of a multi-function device,
+		 * we go down them as well. */
+                if (!strcmp(np->name, "multifunc-device")) {
+                        cnp = scan_OF_for_pci_dev(np, devfn);
+                        if (cnp)
+                                return cnp;
+                }
 	}
 	return NULL;
 }
@@ -491,24 +497,6 @@ long sys_pciconfig_iobase(long which, un
 	return result;
 }
 
-unsigned long pci_address_to_pio(phys_addr_t address)
-{
-	struct pci_controller *hose, *tmp;
-
-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
-		unsigned int size = hose->io_resource.end -
-			hose->io_resource.start + 1;
-		if (address >= hose->io_base_phys &&
-		    address < (hose->io_base_phys + size)) {
-			unsigned long base =
-				(unsigned long)hose->io_base_virt - _IO_BASE;
-			return base + (address - hose->io_base_phys);
-		}
-	}
-	return (unsigned int)-1;
-}
-EXPORT_SYMBOL(pci_address_to_pio);
-
 /*
  * Null PCI config access functions, for the case when we can't
  * find a hose.
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci_64.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,8 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-LIST_HEAD(hose_list);
-
 static void fixup_broken_pcnet32(struct pci_dev* dev)
 {
 	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
@@ -66,7 +64,7 @@ static u32 get_int_prop(struct device_no
 	return def;
 }
 
-static unsigned int pci_parse_of_flags(u32 addr0)
+static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
 {
 	unsigned int flags = 0;
 
@@ -77,8 +75,17 @@ static unsigned int pci_parse_of_flags(u
 		if (addr0 & 0x40000000)
 			flags |= IORESOURCE_PREFETCH
 				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
+		/* Note: We don't know whether the ROM has been left enabled
+		 * by the firmware or not. We mark it as disabled (ie, we do
+		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
+		 * do a config space read, it will be force-enabled if needed
+		 */
+		if (!bridge && (addr0 & 0xff) == 0x30)
+			flags |= IORESOURCE_READONLY;
 	} else if (addr0 & 0x01000000)
 		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+	if (flags)
+		flags |= IORESOURCE_SIZEALIGN;
 	return flags;
 }
 
@@ -97,7 +104,7 @@ static void pci_parse_of_addrs(struct de
 		return;
 	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
 	for (; proplen >= 20; proplen -= 20, addrs += 5) {
-		flags = pci_parse_of_flags(addrs[0]);
+		flags = pci_parse_of_flags(addrs[0], 0);
 		if (!flags)
 			continue;
 		base = of_read_number(&addrs[1], 2);
@@ -295,7 +302,7 @@ void __devinit of_scan_pci_bridge(struct
 	}
 	i = 1;
 	for (; len >= 32; len -= 32, ranges += 8) {
-		flags = pci_parse_of_flags(ranges[0]);
+		flags = pci_parse_of_flags(ranges[0], 1);
 		size = of_read_number(&ranges[6], 2);
 		if (flags == 0 || size == 0)
 			continue;
@@ -524,23 +531,6 @@ int __devinit pcibios_map_io_space(struc
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
-unsigned long pci_address_to_pio(phys_addr_t address)
-{
-	struct pci_controller *hose, *tmp;
-
-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
-		if (address >= hose->io_base_phys &&
-		    address < (hose->io_base_phys + hose->pci_io_size)) {
-			unsigned long base =
-				(unsigned long)hose->io_base_virt - _IO_BASE;
-			return base + (address - hose->io_base_phys);
-		}
-	}
-	return (unsigned int)-1;
-}
-EXPORT_SYMBOL_GPL(pci_address_to_pio);
-
-
 #define IOBASE_BRIDGE_NUMBER	0
 #define IOBASE_MEMORY		1
 #define IOBASE_IO		2
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci-common.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci-common.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/pci-common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/pci-common.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@
 #include <asm/eeh.h>
 
 static DEFINE_SPINLOCK(hose_spinlock);
+LIST_HEAD(hose_list);
 
 /* XXX kill that some day ... */
 static int global_phb_number;		/* Global phb counter */
@@ -49,7 +50,7 @@ resource_size_t isa_mem_base;
 unsigned int ppc_pci_flags = 0;
 
 
-static struct dma_mapping_ops *pci_dma_ops;
+static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops;
 
 void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
 {
@@ -113,19 +114,24 @@ void pcibios_free_controller(struct pci_
 		kfree(phb);
 }
 
+static resource_size_t pcibios_io_size(const struct pci_controller *hose)
+{
+#ifdef CONFIG_PPC64
+	return hose->pci_io_size;
+#else
+	return hose->io_resource.end - hose->io_resource.start + 1;
+#endif
+}
+
 int pcibios_vaddr_is_ioport(void __iomem *address)
 {
 	int ret = 0;
 	struct pci_controller *hose;
-	unsigned long size;
+	resource_size_t size;
 
 	spin_lock(&hose_spinlock);
 	list_for_each_entry(hose, &hose_list, list_node) {
-#ifdef CONFIG_PPC64
-		size = hose->pci_io_size;
-#else
-		size = hose->io_resource.end - hose->io_resource.start + 1;
-#endif
+		size = pcibios_io_size(hose);
 		if (address >= hose->io_base_virt &&
 		    address < (hose->io_base_virt + size)) {
 			ret = 1;
@@ -136,6 +142,29 @@ int pcibios_vaddr_is_ioport(void __iomem
 	return ret;
 }
 
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+	struct pci_controller *hose;
+	resource_size_t size;
+	unsigned long ret = ~0;
+
+	spin_lock(&hose_spinlock);
+	list_for_each_entry(hose, &hose_list, list_node) {
+		size = pcibios_io_size(hose);
+		if (address >= hose->io_base_phys &&
+		    address < (hose->io_base_phys + size)) {
+			unsigned long base =
+				(unsigned long)hose->io_base_virt - _IO_BASE;
+			ret = base + (address - hose->io_base_phys);
+			break;
+		}
+	}
+	spin_unlock(&hose_spinlock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
 /*
  * Return the domain number for this bus.
  */
@@ -1337,12 +1366,17 @@ static void __init pcibios_allocate_reso
 
 	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for (idx = 0; idx < 6; idx++) {
+		for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
 			r = &dev->resource[idx];
 			if (r->parent)		/* Already allocated */
 				continue;
 			if (!r->flags || (r->flags & IORESOURCE_UNSET))
 				continue;	/* Not assigned at all */
+			/* We only allocate ROMs on pass 1 just in case they
+			 * have been screwed up by firmware
+			 */
+			if (idx == PCI_ROM_RESOURCE )
+				disabled = 1;
 			if (r->flags & IORESOURCE_IO)
 				disabled = !(command & PCI_COMMAND_IO);
 			else
@@ -1353,17 +1387,19 @@ static void __init pcibios_allocate_reso
 		if (pass)
 			continue;
 		r = &dev->resource[PCI_ROM_RESOURCE];
-		if (r->flags & IORESOURCE_ROM_ENABLE) {
+		if (r->flags) {
 			/* Turn the ROM off, leave the resource region,
 			 * but keep it unregistered.
 			 */
 			u32 reg;
-			pr_debug("PCI: Switching off ROM of %s\n",
-				 pci_name(dev));
-			r->flags &= ~IORESOURCE_ROM_ENABLE;
 			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
-			pci_write_config_dword(dev, dev->rom_base_reg,
-					       reg & ~PCI_ROM_ADDRESS_ENABLE);
+			if (reg & PCI_ROM_ADDRESS_ENABLE) {
+				pr_debug("PCI: Switching off ROM of %s\n",
+					 pci_name(dev));
+				r->flags &= ~IORESOURCE_ROM_ENABLE;
+				pci_write_config_dword(dev, dev->rom_base_reg,
+						       reg & ~PCI_ROM_ADDRESS_ENABLE);
+			}
 		}
 	}
 }
@@ -1453,7 +1489,7 @@ void __init pcibios_resource_survey(void
 	 * we proceed to assigning things that were left unassigned
 	 */
 	if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
-		pr_debug("PCI: Assigning unassigned resouces...\n");
+		pr_debug("PCI: Assigning unassigned resources...\n");
 		pci_assign_unassigned_resources();
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/process.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,10 @@
 #include <linux/mqueue.h>
 #include <linux/hardirq.h>
 #include <linux/utsname.h>
+#include <linux/ftrace.h>
 #include <linux/kernel_stat.h>
+#include <linux/personality.h>
+#include <linux/random.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -595,7 +598,7 @@ void prepare_to_copy(struct task_struct
 /*
  * Copy a thread..
  */
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused, struct task_struct *p,
 		struct pt_regs *regs)
 {
@@ -1008,6 +1011,14 @@ void show_stack(struct task_struct *tsk,
 	unsigned long sp, ip, lr, newsp;
 	int count = 0;
 	int firstframe = 1;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	int curr_frame = current->curr_ret_stack;
+	extern void return_to_handler(void);
+	unsigned long addr = (unsigned long)return_to_handler;
+#ifdef CONFIG_PPC64
+	addr = *(unsigned long*)addr;
+#endif
+#endif
 
 	sp = (unsigned long) stack;
 	if (tsk == NULL)
@@ -1030,6 +1041,13 @@ void show_stack(struct task_struct *tsk,
 		ip = stack[STACK_FRAME_LR_SAVE];
 		if (!firstframe || ip != lr) {
 			printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+			if (ip == addr && curr_frame >= 0) {
+				printk(" (%pS)",
+				       (void *)current->ret_stack[curr_frame].ret);
+				curr_frame--;
+			}
+#endif
 			if (firstframe)
 				printk(" (unreliable)");
 			printk("\n");
@@ -1122,3 +1140,43 @@ void thread_info_cache_init(void)
 }
 
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+		sp -= get_random_int() & ~PAGE_MASK;
+	return sp & ~0xf;
+}
+
+static inline unsigned long brk_rnd(void)
+{
+        unsigned long rnd = 0;
+
+	/* 8MB for 32bit, 1GB for 64bit */
+	if (is_32bit_task())
+		rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+	else
+		rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+
+	return rnd << PAGE_SHIFT;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+
+	if (ret < mm->brk)
+		return mm->brk;
+
+	return ret;
+}
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+	unsigned long ret = PAGE_ALIGN(base + brk_rnd());
+
+	if (ret < base)
+		return base;
+
+	return ret;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom.c	2009-06-09 23:05:27.000000000 -0400
@@ -426,7 +426,7 @@ static int __init early_parse_mem(char *
 		return 1;
 
 	memory_limit = PAGE_ALIGN(memparse(p, &p));
-	DBG("memory limit = 0x%lx\n", memory_limit);
+	DBG("memory limit = 0x%llx\n", (unsigned long long)memory_limit);
 
 	return 0;
 }
@@ -1075,11 +1075,6 @@ static void __init early_reserve_mem(voi
 		DBG("reserving: %llx -> %llx\n", base, size);
 		lmb_reserve(base, size);
 	}
-
-#if 0
-	DBG("memory reserved, lmbs :\n");
-      	lmb_dump_all();
-#endif
 }
 
 #ifdef CONFIG_PHYP_DUMP
@@ -1165,7 +1160,7 @@ static inline void __init phyp_dump_rese
 
 void __init early_init_devtree(void *params)
 {
-	unsigned long limit;
+	phys_addr_t limit;
 
 	DBG(" -> early_init_devtree(%p)\n", params);
 
@@ -1209,7 +1204,7 @@ void __init early_init_devtree(void *par
 
 	limit = memory_limit;
 	if (! limit) {
-		unsigned long memsize;
+		phys_addr_t memsize;
 
 		/* Ensure that total memory size is page-aligned, because
 		 * otherwise mark_bootmem() gets upset. */
@@ -1221,8 +1216,9 @@ void __init early_init_devtree(void *par
 	lmb_enforce_memory_limit(limit);
 
 	lmb_analyze();
+	lmb_dump_all();
 
-	DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+	DBG("Phys. mem: %llx\n", lmb_phys_mem_size());
 
 	/* We may need to relocate the flat tree, do it now.
 	 * FIXME .. and the initrd too? */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_init.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_init.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_init.c	2009-06-09 23:05:27.000000000 -0400
@@ -614,7 +614,7 @@ static unsigned char ibm_architecture_ve
 	W(0xffffffff),			/* virt_base */
 	W(0xffffffff),			/* virt_size */
 	W(0xffffffff),			/* load_base */
-	W(64),				/* 128MB min RMA */
+	W(64),				/* 64MB min RMA */
 	W(0xffffffff),			/* full client load */
 	0,				/* min RMA percentage of total RAM */
 	48,				/* max log_2(hash table size) */
@@ -732,15 +732,17 @@ static void __init prom_send_capabilitie
 	root = call_prom("open", 1, 1, ADDR("/"));
 	if (root != 0) {
 		/* try calling the ibm,client-architecture-support method */
+		prom_printf("Calling ibm,client-architecture...");
 		if (call_prom_ret("call-method", 3, 2, &ret,
 				  ADDR("ibm,client-architecture-support"),
 				  root,
 				  ADDR(ibm_architecture_vec)) == 0) {
 			/* the call exists... */
 			if (ret)
-				prom_printf("WARNING: ibm,client-architecture"
+				prom_printf("\nWARNING: ibm,client-architecture"
 					    "-support call FAILED!\n");
 			call_prom("close", 1, 0, root);
+			prom_printf(" done\n");
 			return;
 		}
 		call_prom("close", 1, 0, root);
@@ -1083,7 +1085,7 @@ static void __init prom_instantiate_rtas
 		return;
 	}
 
-	prom_printf("instantiating rtas at 0x%x ...", base);
+	prom_printf("instantiating rtas at 0x%x...", base);
 
 	if (call_prom_ret("call-method", 3, 2, &entry,
 			  ADDR("instantiate-rtas"),
@@ -1495,7 +1497,7 @@ static int __init prom_find_machine_type
 		return PLATFORM_GENERIC;
 	x = prom_getproplen(rtas, "ibm,hypertas-functions");
 	if (x != PROM_ERROR) {
-		prom_printf("Hypertas detected, assuming LPAR !\n");
+		prom_debug("Hypertas detected, assuming LPAR !\n");
 		return PLATFORM_PSERIES_LPAR;
 	}
 	return PLATFORM_PSERIES;
@@ -1544,7 +1546,7 @@ static void __init prom_check_displays(v
 	};
 	const unsigned char *clut;
 
-	prom_printf("Looking for displays\n");
+	prom_debug("Looking for displays\n");
 	for (node = 0; prom_next_node(&node); ) {
 		memset(type, 0, sizeof(type));
 		prom_getprop(node, "device_type", type, sizeof(type));
@@ -1562,7 +1564,7 @@ static void __init prom_check_displays(v
 		if (call_prom("package-to-path", 3, 1, node, path,
 			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)
 			continue;
-		prom_printf("found display   : %s, opening ... ", path);
+		prom_printf("found display   : %s, opening... ", path);
 		
 		ih = call_prom("open", 1, 1, path);
 		if (ih == 0) {
@@ -2283,6 +2285,8 @@ unsigned long __init prom_init(unsigned
 	 */
 	prom_init_stdout();
 
+	prom_printf("Preparing to boot %s", RELOC(linux_banner));
+
 	/*
 	 * Get default machine type. At this point, we do not differentiate
 	 * between pSeries SMP and pSeries LPAR
@@ -2385,7 +2389,7 @@ unsigned long __init prom_init(unsigned
 	/*
 	 * Now finally create the flattened device-tree
 	 */
-	prom_printf("copying OF device tree ...\n");
+	prom_printf("copying OF device tree...\n");
 	flatten_device_tree();
 
 	/*
@@ -2400,7 +2404,7 @@ unsigned long __init prom_init(unsigned
 	 * Call OF "quiesce" method to shut down pending DMA's from
 	 * devices etc...
 	 */
-	prom_printf("Calling quiesce ...\n");
+	prom_printf("Calling quiesce...\n");
 	call_prom("quiesce", 0, 0);
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_init_check.sh linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_init_check.sh
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_init_check.sh	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_init_check.sh	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start
 _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr memstart_addr"
+reloc_got2 kernstart_addr memstart_addr linux_banner"
 
 NM="$1"
 OBJ="$2"
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_parse.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_parse.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/prom_parse.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/prom_parse.c	2009-06-09 23:05:27.000000000 -0400
@@ -971,7 +971,7 @@ int of_irq_map_one(struct device_node *d
 	struct device_node *p;
 	const u32 *intspec, *tmp, *addr;
 	u32 intsize, intlen;
-	int res;
+	int res = -EINVAL;
 
 	DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
 
@@ -995,21 +995,20 @@ int of_irq_map_one(struct device_node *d
 
 	/* Get size of interrupt specifier */
 	tmp = of_get_property(p, "#interrupt-cells", NULL);
-	if (tmp == NULL) {
-		of_node_put(p);
-		return -EINVAL;
-	}
+	if (tmp == NULL)
+		goto out;
 	intsize = *tmp;
 
 	DBG(" intsize=%d intlen=%d\n", intsize, intlen);
 
 	/* Check index */
 	if ((index + 1) * intsize > intlen)
-		return -EINVAL;
+		goto out;
 
 	/* Get new specifier and map it */
 	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
 			     addr, out_irq);
+out:
 	of_node_put(p);
 	return res;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/ptrace32.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/ptrace32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/ptrace32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/ptrace32.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,7 +67,8 @@ static long compat_ptrace_old(struct tas
 /* Macros to workout the correct index for the FPR in the thread struct */
 #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
 #define FPRHALF(i) (((i) - PT_FPR0) & 1)
-#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) + FPRHALF(i)
+#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
+#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
 
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
@@ -168,8 +169,9 @@ long compat_arch_ptrace(struct task_stru
 		CHECK_FULL_REGS(child->thread.regs);
 		if (numReg >= PT_FPR0) {
 			flush_fp_to_thread(child);
-			tmp = ((unsigned long int *)child->thread.fpr)
-				[FPRINDEX(numReg)];
+			/* get 64 bit FPR */
+			tmp = ((u64 *)child->thread.fpr)
+				[FPRINDEX_3264(numReg)];
 		} else { /* register within PT_REGS struct */
 			tmp = ptrace_get_reg(child, numReg);
 		} 
@@ -262,8 +264,13 @@ long compat_arch_ptrace(struct task_stru
 				freg = (freg & 0xfffffffful) | (data << 32);
 			ret = ptrace_put_reg(child, numReg, freg);
 		} else {
+			u64 *tmp;
 			flush_fp_to_thread(child);
-			((unsigned int *)child->thread.regs)[index] = data;
+			/* get 64 bit FPR ... */
+			tmp = &(((u64 *)child->thread.fpr)
+				[FPRINDEX_3264(numReg)]);
+			/* ... write the 32 bit part we want */
+			((u32 *)tmp)[index % 2] = data;
 			ret = 0;
 		}
 		break;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/rtas.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/rtas.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,7 @@ EXPORT_SYMBOL(rtas);
 
 struct rtas_suspend_me_data {
 	atomic_t working; /* number of cpus accessing this struct */
+	atomic_t done;
 	int token; /* ibm,suspend-me */
 	int error;
 	struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_U
 #ifdef CONFIG_PPC_PSERIES
 static void rtas_percpu_suspend_me(void *info)
 {
-	long rc;
+	long rc = H_SUCCESS;
 	unsigned long msr_save;
 	int cpu;
 	struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void
 	msr_save = mfmsr();
 	mtmsr(msr_save & ~(MSR_EE));
 
-	rc = plpar_hcall_norets(H_JOIN);
+	while (rc == H_SUCCESS && !atomic_read(&data->done))
+		rc = plpar_hcall_norets(H_JOIN);
 
 	mtmsr(msr_save);
 
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void
 		       smp_processor_id(), rc);
 		data->error = rc;
 	}
+
+	atomic_set(&data->done, 1);
+
 	/* This cpu did the suspend or got an error; in either case,
 	 * we need to prod all other other cpus out of join state.
 	 * Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rt
 	}
 
 	atomic_set(&data.working, 0);
+	atomic_set(&data.done, 0);
 	data.token = rtas_token("ibm,suspend-me");
 	data.error = 0;
 	data.complete = &done;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/rtas_flash.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas_flash.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/rtas_flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas_flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -669,7 +669,6 @@ static void remove_flash_pde(struct proc
 {
 	if (dp) {
 		kfree(dp->data);
-		dp->owner = NULL;
 		remove_proc_entry(dp->name, dp->parent);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/setup_64.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/setup_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/setup_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/setup_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -202,8 +202,6 @@ void __init early_setup(unsigned long dt
 
 	/* Fix up paca fields required for the boot cpu */
 	get_paca()->cpu_start = 1;
-	get_paca()->stab_real = __pa((u64)&initial_stab);
-	get_paca()->stab_addr = (u64)&initial_stab;
 
 	/* Probe the machine type */
 	probe_machine();
@@ -212,20 +210,8 @@ void __init early_setup(unsigned long dt
 
 	DBG("Found, Initializing memory management...\n");
 
-	/*
-	 * Initialize the MMU Hash table and create the linear mapping
-	 * of memory. Has to be done before stab/slb initialization as
-	 * this is currently where the page size encoding is obtained
-	 */
-	htab_initialize();
-
-	/*
-	 * Initialize stab / SLB management except on iSeries
-	 */
-	if (cpu_has_feature(CPU_FTR_SLB))
-		slb_initialize();
-	else if (!firmware_has_feature(FW_FEATURE_ISERIES))
-		stab_initialize(get_paca()->stab_real);
+	/* Initialize the hash table or TLB handling */
+	early_init_mmu();
 
 	DBG(" <- early_setup()\n");
 }
@@ -233,22 +219,11 @@ void __init early_setup(unsigned long dt
 #ifdef CONFIG_SMP
 void early_setup_secondary(void)
 {
-	struct paca_struct *lpaca = get_paca();
-
 	/* Mark interrupts enabled in PACA */
-	lpaca->soft_enabled = 0;
-
-	/* Initialize hash table for that CPU */
-	htab_initialize_secondary();
+	get_paca()->soft_enabled = 0;
 
-	/* Initialize STAB/SLB. We use a virtual address as it works
-	 * in real mode on pSeries and we want a virutal address on
-	 * iSeries anyway
-	 */
-	if (cpu_has_feature(CPU_FTR_SLB))
-		slb_initialize();
-	else
-		stab_initialize(lpaca->stab_addr);
+	/* Initialize the hash table or TLB handling */
+	early_init_mmu_secondary();
 }
 
 #endif /* CONFIG_SMP */
@@ -578,13 +553,6 @@ void ppc64_boot_msg(unsigned int src, co
 	printk("[boot]%04x %s\n", src, msg);
 }
 
-/* Print a termination message (print only -- does not stop the kernel) */
-void ppc64_terminate_msg(unsigned int src, const char *msg)
-{
-	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
-	printk("[terminate]%04x %s\n", src, msg);
-}
-
 void cpu_die(void)
 {
 	if (ppc_md.cpu_die)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/setup-common.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/setup-common.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/setup-common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/setup-common.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/debugfs.h>
 #include <linux/percpu.h>
 #include <linux/lmb.h>
+#include <linux/of_platform.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
@@ -669,3 +670,37 @@ static int powerpc_debugfs_init(void)
 }
 arch_initcall(powerpc_debugfs_init);
 #endif
+
+static int ppc_dflt_bus_notify(struct notifier_block *nb,
+				unsigned long action, void *data)
+{
+	struct device *dev = data;
+
+	/* We are only intereted in device addition */
+	if (action != BUS_NOTIFY_ADD_DEVICE)
+		return 0;
+
+	set_dma_ops(dev, &dma_direct_ops);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_dflt_plat_bus_notifier = {
+	.notifier_call = ppc_dflt_bus_notify,
+	.priority = INT_MAX,
+};
+
+static struct notifier_block ppc_dflt_of_bus_notifier = {
+	.notifier_call = ppc_dflt_bus_notify,
+	.priority = INT_MAX,
+};
+
+static int __init setup_bus_notifier(void)
+{
+	bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier);
+	bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier);
+
+	return 0;
+}
+
+arch_initcall(setup_bus_notifier);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal_32.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal_32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig
 
 	/* Set up Signal Frame */
 	/* Put a Real Time Context onto stack */
-	rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf));
+	rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1);
 	addr = rt_sf;
 	if (unlikely(rt_sf == NULL))
 		goto badframe;
@@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, s
 	unsigned long newsp = 0;
 
 	/* Set up Signal Frame */
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame), 1);
 	if (unlikely(frame == NULL))
 		goto badframe;
 	sc = (struct sigcontext __user *) &frame->sctx;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal_64.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct
 	unsigned long newsp = 0;
 	long err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame), 0);
 	if (unlikely(frame == NULL))
 		goto badframe;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,12 +26,12 @@ int show_unhandled_signals = 0;
  * Allocate space for the signal frame
  */
 void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-			   size_t frame_size)
+			   size_t frame_size, int is_32)
 {
         unsigned long oldsp, newsp;
 
         /* Default to using normal stack */
-        oldsp = regs->gpr[1];
+        oldsp = get_clean_sp(regs, is_32);
 
 	/* Check for alt stack */
 	if ((ka->sa.sa_flags & SA_ONSTACK) &&
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal.h linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/signal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/signal.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,7 @@
 extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
 
 extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-				  size_t frame_size);
+				  size_t frame_size, int is_32);
 extern void restore_sigmask(sigset_t *set);
 
 extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
@@ -39,22 +39,12 @@ extern unsigned long copy_vsx_from_user(
 
 #ifdef CONFIG_PPC64
 
-static inline int is_32bit_task(void)
-{
-	return test_thread_flag(TIF_32BIT);
-}
-
 extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
 			      siginfo_t *info, sigset_t *set,
 			      struct pt_regs *regs);
 
 #else /* CONFIG_PPC64 */
 
-static inline int is_32bit_task(void)
-{
-	return 1;
-}
-
 static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
 				     siginfo_t *info, sigset_t *set,
 				     struct pt_regs *regs)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/sysfs.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/sysfs.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -134,44 +134,23 @@ void ppc_enable_pmcs(void)
 }
 EXPORT_SYMBOL(ppc_enable_pmcs);
 
-#if defined(CONFIG_6xx) || defined(CONFIG_PPC64)
-/* XXX convert to rusty's on_one_cpu */
-static unsigned long run_on_cpu(unsigned long cpu,
-			        unsigned long (*func)(unsigned long),
-				unsigned long arg)
-{
-	cpumask_t old_affinity = current->cpus_allowed;
-	unsigned long ret;
-
-	/* should return -EINVAL to userspace */
-	if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
-		return 0;
-
-	ret = func(arg);
-
-	set_cpus_allowed(current, old_affinity);
-
-	return ret;
-}
-#endif
-
 #define SYSFS_PMCSETUP(NAME, ADDRESS) \
-static unsigned long read_##NAME(unsigned long junk) \
+static void read_##NAME(void *val) \
 { \
-	return mfspr(ADDRESS); \
+	*(unsigned long *)val = mfspr(ADDRESS);	\
 } \
-static unsigned long write_##NAME(unsigned long val) \
+static void write_##NAME(void *val) \
 { \
 	ppc_enable_pmcs(); \
-	mtspr(ADDRESS, val); \
-	return 0; \
+	mtspr(ADDRESS, *(unsigned long *)val);	\
 } \
 static ssize_t show_##NAME(struct sys_device *dev, \
 			struct sysdev_attribute *attr, \
 			char *buf) \
 { \
 	struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
-	unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
+	unsigned long val; \
+	smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1);	\
 	return sprintf(buf, "%lx\n", val); \
 } \
 static ssize_t __used \
@@ -183,7 +162,7 @@ static ssize_t __used \
 	int ret = sscanf(buf, "%lx", &val); \
 	if (ret != 1) \
 		return -EINVAL; \
-	run_on_cpu(cpu->sysdev.id, write_##NAME, val); \
+	smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \
 	return count; \
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/time.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -77,7 +77,7 @@
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
 
-static cycle_t rtc_read(void);
+static cycle_t rtc_read(struct clocksource *);
 static struct clocksource clocksource_rtc = {
 	.name         = "rtc",
 	.rating       = 400,
@@ -88,7 +88,7 @@ static struct clocksource clocksource_rt
 	.read         = rtc_read,
 };
 
-static cycle_t timebase_read(void);
+static cycle_t timebase_read(struct clocksource *);
 static struct clocksource clocksource_timebase = {
 	.name         = "timebase",
 	.rating       = 400,
@@ -766,12 +766,12 @@ unsigned long read_persistent_clock(void
 }
 
 /* clocksource code */
-static cycle_t rtc_read(void)
+static cycle_t rtc_read(struct clocksource *cs)
 {
 	return (cycle_t)get_rtc();
 }
 
-static cycle_t timebase_read(void)
+static cycle_t timebase_read(struct clocksource *cs)
 {
 	return (cycle_t)get_tb();
 }
@@ -1127,3 +1127,19 @@ void div128_by_32(u64 dividend_high, u64
 	dr->result_low  = ((u64)y << 32) + z;
 
 }
+
+static int __init rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	if (!ppc_md.get_rtc_time)
+		return -ENODEV;
+
+	pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+module_init(rtc_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/traps.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,10 @@
 #include <asm/processor.h>
 #endif
 #include <asm/kexec.h>
+#include <asm/ppc-opcode.h>
+#ifdef CONFIG_FSL_BOOKE
+#include <asm/dbell.h>
+#endif
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
 int (*__debugger)(struct pt_regs *regs);
@@ -637,29 +641,6 @@ static void parse_fpe(struct pt_regs *re
  * bits is faster and easier.
  *
  */
-#define INST_MFSPR_PVR		0x7c1f42a6
-#define INST_MFSPR_PVR_MASK	0xfc1fffff
-
-#define INST_DCBA		0x7c0005ec
-#define INST_DCBA_MASK		0xfc0007fe
-
-#define INST_MCRXR		0x7c000400
-#define INST_MCRXR_MASK		0xfc0007fe
-
-#define INST_STRING		0x7c00042a
-#define INST_STRING_MASK	0xfc0007fe
-#define INST_STRING_GEN_MASK	0xfc00067e
-#define INST_LSWI		0x7c0004aa
-#define INST_LSWX		0x7c00042a
-#define INST_STSWI		0x7c0005aa
-#define INST_STSWX		0x7c00052a
-
-#define INST_POPCNTB		0x7c0000f4
-#define INST_POPCNTB_MASK	0xfc0007fe
-
-#define INST_ISEL		0x7c00001e
-#define INST_ISEL_MASK		0xfc00003e
-
 static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 {
 	u8 rT = (instword >> 21) & 0x1f;
@@ -670,20 +651,20 @@ static int emulate_string_inst(struct pt
 	int pos = 0;
 
 	/* Early out if we are an invalid form of lswx */
-	if ((instword & INST_STRING_MASK) == INST_LSWX)
+	if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX)
 		if ((rT == rA) || (rT == NB_RB))
 			return -EINVAL;
 
 	EA = (rA == 0) ? 0 : regs->gpr[rA];
 
-	switch (instword & INST_STRING_MASK) {
-		case INST_LSWX:
-		case INST_STSWX:
+	switch (instword & PPC_INST_STRING_MASK) {
+		case PPC_INST_LSWX:
+		case PPC_INST_STSWX:
 			EA += NB_RB;
 			num_bytes = regs->xer & 0x7f;
 			break;
-		case INST_LSWI:
-		case INST_STSWI:
+		case PPC_INST_LSWI:
+		case PPC_INST_STSWI:
 			num_bytes = (NB_RB == 0) ? 32 : NB_RB;
 			break;
 		default:
@@ -695,9 +676,9 @@ static int emulate_string_inst(struct pt
 		u8 val;
 		u32 shift = 8 * (3 - (pos & 0x3));
 
-		switch ((instword & INST_STRING_MASK)) {
-			case INST_LSWX:
-			case INST_LSWI:
+		switch ((instword & PPC_INST_STRING_MASK)) {
+			case PPC_INST_LSWX:
+			case PPC_INST_LSWI:
 				if (get_user(val, (u8 __user *)EA))
 					return -EFAULT;
 				/* first time updating this reg,
@@ -706,8 +687,8 @@ static int emulate_string_inst(struct pt
 					regs->gpr[rT] = 0;
 				regs->gpr[rT] |= val << shift;
 				break;
-			case INST_STSWI:
-			case INST_STSWX:
+			case PPC_INST_STSWI:
+			case PPC_INST_STSWX:
 				val = regs->gpr[rT] >> shift;
 				if (put_user(val, (u8 __user *)EA))
 					return -EFAULT;
@@ -775,18 +756,18 @@ static int emulate_instruction(struct pt
 		return -EFAULT;
 
 	/* Emulate the mfspr rD, PVR. */
-	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+	if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
 		rd = (instword >> 21) & 0x1f;
 		regs->gpr[rd] = mfspr(SPRN_PVR);
 		return 0;
 	}
 
 	/* Emulating the dcba insn is just a no-op.  */
-	if ((instword & INST_DCBA_MASK) == INST_DCBA)
+	if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
 		return 0;
 
 	/* Emulate the mcrxr insn.  */
-	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+	if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
 		int shift = (instword >> 21) & 0x1c;
 		unsigned long msk = 0xf0000000UL >> shift;
 
@@ -796,16 +777,16 @@ static int emulate_instruction(struct pt
 	}
 
 	/* Emulate load/store string insn. */
-	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
+	if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
 		return emulate_string_inst(regs, instword);
 
 	/* Emulate the popcntb (Population Count Bytes) instruction. */
-	if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+	if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
 		return emulate_popcntb_inst(regs, instword);
 	}
 
 	/* Emulate isel (Integer Select) instruction */
-	if ((instword & INST_ISEL_MASK) == INST_ISEL) {
+	if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
 		return emulate_isel(regs, instword);
 	}
 
@@ -1144,6 +1125,24 @@ void vsx_assist_exception(struct pt_regs
 #endif /* CONFIG_VSX */
 
 #ifdef CONFIG_FSL_BOOKE
+
+void doorbell_exception(struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+	int cpu = smp_processor_id();
+	int msg;
+
+	if (num_online_cpus() < 2)
+		return;
+
+	for (msg = 0; msg < 4; msg++)
+		if (test_and_clear_bit(msg, &dbell_smp_message[cpu]))
+			smp_message_recv(msg);
+#else
+	printk(KERN_WARNING "Received doorbell on non-smp system\n");
+#endif
+}
+
 void CacheLockingException(struct pt_regs *regs, unsigned long address,
 			   unsigned long error_code)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/udbg_16550.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/udbg_16550.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/udbg_16550.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/udbg_16550.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,14 +48,21 @@ struct NS16550 {
 
 static struct NS16550 __iomem *udbg_comport;
 
-static void udbg_550_putc(char c)
+static void udbg_550_flush(void)
 {
 	if (udbg_comport) {
 		while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
 			/* wait for idle */;
-		out_8(&udbg_comport->thr, c);
+	}
+}
+
+static void udbg_550_putc(char c)
+{
+	if (udbg_comport) {
 		if (c == '\n')
 			udbg_550_putc('\r');
+		udbg_550_flush();
+		out_8(&udbg_comport->thr, c);
 	}
 }
 
@@ -108,6 +115,7 @@ void udbg_init_uart(void __iomem *compor
 		/* Clear & enable FIFOs */
 		out_8(&udbg_comport->fcr ,0x07);
 		udbg_putc = udbg_550_putc;
+		udbg_flush = udbg_550_flush;
 		udbg_getc = udbg_550_getc;
 		udbg_getc_poll = udbg_550_getc_poll;
 	}
@@ -149,14 +157,21 @@ unsigned int udbg_probe_uart_speed(void
 }
 
 #ifdef CONFIG_PPC_MAPLE
-void udbg_maple_real_putc(char c)
+void udbg_maple_real_flush(void)
 {
 	if (udbg_comport) {
 		while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
 			/* wait for idle */;
-		real_writeb(c, &udbg_comport->thr); eieio();
+	}
+}
+
+void udbg_maple_real_putc(char c)
+{
+	if (udbg_comport) {
 		if (c == '\n')
 			udbg_maple_real_putc('\r');
+		udbg_maple_real_flush();
+		real_writeb(c, &udbg_comport->thr); eieio();
 	}
 }
 
@@ -165,20 +180,28 @@ void __init udbg_init_maple_realmode(voi
 	udbg_comport = (struct NS16550 __iomem *)0xf40003f8;
 
 	udbg_putc = udbg_maple_real_putc;
+	udbg_flush = udbg_maple_real_flush;
 	udbg_getc = NULL;
 	udbg_getc_poll = NULL;
 }
 #endif /* CONFIG_PPC_MAPLE */
 
 #ifdef CONFIG_PPC_PASEMI
-void udbg_pas_real_putc(char c)
+void udbg_pas_real_flush(void)
 {
 	if (udbg_comport) {
 		while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
 			/* wait for idle */;
-		real_205_writeb(c, &udbg_comport->thr); eieio();
+	}
+}
+
+void udbg_pas_real_putc(char c)
+{
+	if (udbg_comport) {
 		if (c == '\n')
 			udbg_pas_real_putc('\r');
+		udbg_pas_real_flush();
+		real_205_writeb(c, &udbg_comport->thr); eieio();
 	}
 }
 
@@ -187,6 +210,7 @@ void udbg_init_pas_realmode(void)
 	udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL;
 
 	udbg_putc = udbg_pas_real_putc;
+	udbg_flush = udbg_pas_real_flush;
 	udbg_getc = NULL;
 	udbg_getc_poll = NULL;
 }
@@ -195,14 +219,21 @@ void udbg_init_pas_realmode(void)
 #ifdef CONFIG_PPC_EARLY_DEBUG_44x
 #include <platforms/44x/44x.h>
 
-static void udbg_44x_as1_putc(char c)
+static int udbg_44x_as1_flush(void)
 {
 	if (udbg_comport) {
 		while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
 			/* wait for idle */;
-		as1_writeb(c, &udbg_comport->thr); eieio();
+	}
+}
+
+static void udbg_44x_as1_putc(char c)
+{
+	if (udbg_comport) {
 		if (c == '\n')
 			udbg_44x_as1_putc('\r');
+		udbg_44x_as1_flush();
+		as1_writeb(c, &udbg_comport->thr); eieio();
 	}
 }
 
@@ -222,19 +253,27 @@ void __init udbg_init_44x_as1(void)
 		(struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
 
 	udbg_putc = udbg_44x_as1_putc;
+	udbg_flush = udbg_44x_as1_flush;
 	udbg_getc = udbg_44x_as1_getc;
 }
 #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
 
 #ifdef CONFIG_PPC_EARLY_DEBUG_40x
-static void udbg_40x_real_putc(char c)
+static void udbg_40x_real_flush(void)
 {
 	if (udbg_comport) {
 		while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
 			/* wait for idle */;
-		real_writeb(c, &udbg_comport->thr); eieio();
+	}
+}
+
+static void udbg_40x_real_putc(char c)
+{
+	if (udbg_comport) {
 		if (c == '\n')
 			udbg_40x_real_putc('\r');
+		udbg_40x_real_flush();
+		real_writeb(c, &udbg_comport->thr); eieio();
 	}
 }
 
@@ -254,6 +293,7 @@ void __init udbg_init_40x_realmode(void)
 		CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR;
 
 	udbg_putc = udbg_40x_real_putc;
+	udbg_flush = udbg_40x_real_flush;
 	udbg_getc = udbg_40x_real_getc;
 	udbg_getc_poll = NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/udbg.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/udbg.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/udbg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/udbg.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/udbg.h>
 
 void (*udbg_putc)(char c);
+void (*udbg_flush)(void);
 int (*udbg_getc)(void);
 int (*udbg_getc_poll)(void);
 
@@ -76,6 +77,9 @@ void udbg_puts(const char *s)
 			while ((c = *s++) != '\0')
 				udbg_putc(c);
 		}
+
+		if (udbg_flush)
+			udbg_flush();
 	}
 #if 0
 	else {
@@ -98,6 +102,9 @@ int udbg_write(const char *s, int n)
 		}
 	}
 
+	if (udbg_flush)
+		udbg_flush();
+
 	return n - remain;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/vio.c linux-libre-2.6.30-gnu1/arch/powerpc/kernel/vio.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/vio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/vio.c	2009-06-09 23:05:27.000000000 -0400
@@ -482,7 +482,7 @@ static void vio_cmo_balance(struct work_
 	cmo->excess.size = cmo->entitled - cmo->reserve.size;
 	cmo->excess.free = cmo->excess.size - need;
 
-	cancel_delayed_work(container_of(work, struct delayed_work, work));
+	cancel_delayed_work(to_delayed_work(work));
 	spin_unlock_irqrestore(&vio_cmo.lock, flags);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/powerpc/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -52,12 +52,14 @@ SECTIONS
 	/* Text and gots */
 	.text : AT(ADDR(.text) - LOAD_OFFSET) {
 		ALIGN_FUNCTION();
-		*(.text.head)
+		HEAD_TEXT
 		_text = .;
-		*(.text .fixup .text.init.refok .exit.text.refok __ftr_alt_*)
+		/* careful! __ftr_alt_* sections need to be close to .text */
+		*(.text .fixup __ftr_alt_* .ref.text)
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
+		IRQENTRY_TEXT
 
 #ifdef CONFIG_PPC32
 		*(.got1)
@@ -181,13 +183,7 @@ SECTIONS
 		__initramfs_end = .;
 	}
 #endif
-	. = ALIGN(PAGE_SIZE);
-	.data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
-		__per_cpu_start = .;
-		*(.data.percpu)
-		*(.data.percpu.shared_aligned)
-		__per_cpu_end = .;
-	}
+	PERCPU(PAGE_SIZE)
 
 	. = ALIGN(8);
 	.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
@@ -268,6 +264,7 @@ SECTIONS
 		*(.data.page_aligned)
 	}
 
+	. = ALIGN(L1_CACHE_BYTES);
 	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
 		*(.data.cacheline_aligned)
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,72 +28,6 @@
 
 #include "44x_tlb.h"
 
-/* Note: clearing MSR[DE] just means that the debug interrupt will not be
- * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits.
- * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt
- * will be delivered as an "imprecise debug event" (which is indicated by
- * DBSR[IDE].
- */
-static void kvm44x_disable_debug_interrupts(void)
-{
-	mtmsr(mfmsr() & ~MSR_DE);
-}
-
-void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
-{
-	kvm44x_disable_debug_interrupts();
-
-	mtspr(SPRN_IAC1, vcpu->arch.host_iac[0]);
-	mtspr(SPRN_IAC2, vcpu->arch.host_iac[1]);
-	mtspr(SPRN_IAC3, vcpu->arch.host_iac[2]);
-	mtspr(SPRN_IAC4, vcpu->arch.host_iac[3]);
-	mtspr(SPRN_DBCR1, vcpu->arch.host_dbcr1);
-	mtspr(SPRN_DBCR2, vcpu->arch.host_dbcr2);
-	mtspr(SPRN_DBCR0, vcpu->arch.host_dbcr0);
-	mtmsr(vcpu->arch.host_msr);
-}
-
-void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
-{
-	struct kvm_guest_debug *dbg = &vcpu->guest_debug;
-	u32 dbcr0 = 0;
-
-	vcpu->arch.host_msr = mfmsr();
-	kvm44x_disable_debug_interrupts();
-
-	/* Save host debug register state. */
-	vcpu->arch.host_iac[0] = mfspr(SPRN_IAC1);
-	vcpu->arch.host_iac[1] = mfspr(SPRN_IAC2);
-	vcpu->arch.host_iac[2] = mfspr(SPRN_IAC3);
-	vcpu->arch.host_iac[3] = mfspr(SPRN_IAC4);
-	vcpu->arch.host_dbcr0 = mfspr(SPRN_DBCR0);
-	vcpu->arch.host_dbcr1 = mfspr(SPRN_DBCR1);
-	vcpu->arch.host_dbcr2 = mfspr(SPRN_DBCR2);
-
-	/* set registers up for guest */
-
-	if (dbg->bp[0]) {
-		mtspr(SPRN_IAC1, dbg->bp[0]);
-		dbcr0 |= DBCR0_IAC1 | DBCR0_IDM;
-	}
-	if (dbg->bp[1]) {
-		mtspr(SPRN_IAC2, dbg->bp[1]);
-		dbcr0 |= DBCR0_IAC2 | DBCR0_IDM;
-	}
-	if (dbg->bp[2]) {
-		mtspr(SPRN_IAC3, dbg->bp[2]);
-		dbcr0 |= DBCR0_IAC3 | DBCR0_IDM;
-	}
-	if (dbg->bp[3]) {
-		mtspr(SPRN_IAC4, dbg->bp[3]);
-		dbcr0 |= DBCR0_IAC4 | DBCR0_IDM;
-	}
-
-	mtspr(SPRN_DBCR0, dbcr0);
-	mtspr(SPRN_DBCR1, 0);
-	mtspr(SPRN_DBCR2, 0);
-}
-
 void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	kvmppc_44x_tlb_load(vcpu);
@@ -149,8 +83,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vc
 int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
                                struct kvm_translation *tr)
 {
-	struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
-	struct kvmppc_44x_tlbe *gtlbe;
 	int index;
 	gva_t eaddr;
 	u8 pid;
@@ -166,9 +98,7 @@ int kvmppc_core_vcpu_translate(struct kv
 		return 0;
 	}
 
-	gtlbe = &vcpu_44x->guest_tlb[index];
-
-	tr->physical_address = tlb_xlate(gtlbe, eaddr);
+	tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
 	/* XXX what does "writeable" and "usermode" even mean? */
 	tr->valid = 1;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_emulate.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_emulate.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_emulate.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_emulate.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,25 +27,12 @@
 #include "booke.h"
 #include "44x_tlb.h"
 
-#define OP_RFI      19
-
-#define XOP_RFI     50
-#define XOP_MFMSR   83
-#define XOP_WRTEE   131
-#define XOP_MTMSR   146
-#define XOP_WRTEEI  163
 #define XOP_MFDCR   323
 #define XOP_MTDCR   451
 #define XOP_TLBSX   914
 #define XOP_ICCCI   966
 #define XOP_TLBWE   978
 
-static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
-{
-	vcpu->arch.pc = vcpu->arch.srr0;
-	kvmppc_set_msr(vcpu, vcpu->arch.srr1);
-}
-
 int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                            unsigned int inst, int *advance)
 {
@@ -59,48 +46,9 @@ int kvmppc_core_emulate_op(struct kvm_ru
 	int ws;
 
 	switch (get_op(inst)) {
-	case OP_RFI:
-		switch (get_xop(inst)) {
-		case XOP_RFI:
-			kvmppc_emul_rfi(vcpu);
-			kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
-			*advance = 0;
-			break;
-
-		default:
-			emulated = EMULATE_FAIL;
-			break;
-		}
-		break;
-
 	case 31:
 		switch (get_xop(inst)) {
 
-		case XOP_MFMSR:
-			rt = get_rt(inst);
-			vcpu->arch.gpr[rt] = vcpu->arch.msr;
-			kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
-			break;
-
-		case XOP_MTMSR:
-			rs = get_rs(inst);
-			kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
-			kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
-			break;
-
-		case XOP_WRTEE:
-			rs = get_rs(inst);
-			vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
-							 | (vcpu->arch.gpr[rs] & MSR_EE);
-			kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
-			break;
-
-		case XOP_WRTEEI:
-			vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
-							 | (inst & MSR_EE);
-			kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
-			break;
-
 		case XOP_MFDCR:
 			dcrn = get_dcrn(inst);
 			rt = get_rt(inst);
@@ -186,186 +134,51 @@ int kvmppc_core_emulate_op(struct kvm_ru
 		emulated = EMULATE_FAIL;
 	}
 
+	if (emulated == EMULATE_FAIL)
+		emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
+
 	return emulated;
 }
 
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
+	int emulated = EMULATE_DONE;
+
 	switch (sprn) {
-	case SPRN_MMUCR:
-		vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
 	case SPRN_PID:
 		kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+	case SPRN_MMUCR:
+		vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
 	case SPRN_CCR0:
 		vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
 	case SPRN_CCR1:
 		vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
-	case SPRN_DEAR:
-		vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
-	case SPRN_ESR:
-		vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
-	case SPRN_DBCR0:
-		vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
-	case SPRN_DBCR1:
-		vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
-	case SPRN_TSR:
-		vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
-	case SPRN_TCR:
-		vcpu->arch.tcr = vcpu->arch.gpr[rs];
-		kvmppc_emulate_dec(vcpu);
-		break;
-
-	/* Note: SPRG4-7 are user-readable. These values are
-	 * loaded into the real SPRGs when resuming the
-	 * guest. */
-	case SPRN_SPRG4:
-		vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
-	case SPRN_SPRG5:
-		vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
-	case SPRN_SPRG6:
-		vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
-	case SPRN_SPRG7:
-		vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
-
-	case SPRN_IVPR:
-		vcpu->arch.ivpr = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR0:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR1:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR2:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR3:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR4:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR5:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR6:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR7:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR8:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR9:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR10:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR11:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR12:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR13:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR14:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
-		break;
-	case SPRN_IVOR15:
-		vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
-		break;
-
 	default:
-		return EMULATE_FAIL;
+		emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
 	}
 
 	kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
-	return EMULATE_DONE;
+	return emulated;
 }
 
 int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 {
+	int emulated = EMULATE_DONE;
+
 	switch (sprn) {
-	/* 440 */
+	case SPRN_PID:
+		vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
 	case SPRN_MMUCR:
 		vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
 	case SPRN_CCR0:
 		vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
 	case SPRN_CCR1:
 		vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
-
-	/* Book E */
-	case SPRN_PID:
-		vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
-	case SPRN_IVPR:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
-	case SPRN_DEAR:
-		vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
-	case SPRN_ESR:
-		vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
-	case SPRN_DBCR0:
-		vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
-	case SPRN_DBCR1:
-		vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
-
-	case SPRN_IVOR0:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
-		break;
-	case SPRN_IVOR1:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
-		break;
-	case SPRN_IVOR2:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
-		break;
-	case SPRN_IVOR3:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
-		break;
-	case SPRN_IVOR4:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
-		break;
-	case SPRN_IVOR5:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
-		break;
-	case SPRN_IVOR6:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
-		break;
-	case SPRN_IVOR7:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
-		break;
-	case SPRN_IVOR8:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
-		break;
-	case SPRN_IVOR9:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
-		break;
-	case SPRN_IVOR10:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
-		break;
-	case SPRN_IVOR11:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
-		break;
-	case SPRN_IVOR12:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
-		break;
-	case SPRN_IVOR13:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
-		break;
-	case SPRN_IVOR14:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
-		break;
-	case SPRN_IVOR15:
-		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
-		break;
-
 	default:
-		return EMULATE_FAIL;
+		emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
 	}
 
 	kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
-	return EMULATE_DONE;
+	return emulated;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_tlb.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_tlb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_tlb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -208,20 +208,38 @@ int kvmppc_44x_tlb_index(struct kvm_vcpu
 	return -1;
 }
 
-int kvmppc_44x_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
+                       gva_t eaddr)
+{
+	struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
+	struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
+	unsigned int pgmask = get_tlb_bytes(gtlbe) - 1;
+
+	return get_tlb_raddr(gtlbe) | (eaddr & pgmask);
+}
+
+int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
 {
 	unsigned int as = !!(vcpu->arch.msr & MSR_IS);
 
 	return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
 }
 
-int kvmppc_44x_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
 {
 	unsigned int as = !!(vcpu->arch.msr & MSR_DS);
 
 	return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
 }
 
+void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
+{
+}
+
 static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
                                       unsigned int stlb_index)
 {
@@ -248,7 +266,7 @@ static void kvmppc_44x_shadow_release(st
 	KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler);
 }
 
-void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu)
+void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
 {
 	struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
 	int i;
@@ -269,15 +287,19 @@ void kvmppc_core_destroy_mmu(struct kvm_
  * Caller must ensure that the specified guest TLB entry is safe to insert into
  * the shadow TLB.
  */
-void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, u64 asid,
-                    u32 flags, u32 max_bytes, unsigned int gtlb_index)
+void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
+                    unsigned int gtlb_index)
 {
 	struct kvmppc_44x_tlbe stlbe;
 	struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
+	struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
 	struct kvmppc_44x_shadow_ref *ref;
 	struct page *new_page;
 	hpa_t hpaddr;
 	gfn_t gfn;
+	u32 asid = gtlbe->tid;
+	u32 flags = gtlbe->word2;
+	u32 max_bytes = get_tlb_bytes(gtlbe);
 	unsigned int victim;
 
 	/* Select TLB entry to clobber. Indirectly guard against races with the TLB
@@ -448,10 +470,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcp
 	}
 
 	if (tlbe_is_host_safe(vcpu, tlbe)) {
-		u64 asid;
 		gva_t eaddr;
 		gpa_t gpaddr;
-		u32 flags;
 		u32 bytes;
 
 		eaddr = get_tlb_eaddr(tlbe);
@@ -462,10 +482,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcp
 		eaddr &= ~(bytes - 1);
 		gpaddr &= ~(bytes - 1);
 
-		asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
-		flags = tlbe->word2 & 0xffff;
-
-		kvmppc_mmu_map(vcpu, eaddr, gpaddr, asid, flags, bytes, gtlb_index);
+		kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
 	}
 
 	KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_tlb.h linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_tlb.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/44x_tlb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/44x_tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,8 +25,6 @@
 
 extern int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr,
                                 unsigned int pid, unsigned int as);
-extern int kvmppc_44x_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
-extern int kvmppc_44x_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
 
 extern int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb,
                                  u8 rc);
@@ -85,11 +83,4 @@ static inline unsigned int get_mmucr_sts
 	return (vcpu->arch.mmucr >> 16) & 0x1;
 }
 
-static inline gpa_t tlb_xlate(struct kvmppc_44x_tlbe *tlbe, gva_t eaddr)
-{
-	unsigned int pgmask = get_tlb_bytes(tlbe) - 1;
-
-	return get_tlb_raddr(tlbe) | (eaddr & pgmask);
-}
-
 #endif /* __KVM_POWERPC_TLB_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,10 +30,8 @@
 #include <asm/kvm_ppc.h>
 #include "timing.h"
 #include <asm/cacheflush.h>
-#include <asm/kvm_44x.h>
 
 #include "booke.h"
-#include "44x_tlb.h"
 
 unsigned long kvmppc_booke_handlers;
 
@@ -120,6 +118,9 @@ static int kvmppc_booke_irqprio_deliver(
 	case BOOKE_IRQPRIO_DATA_STORAGE:
 	case BOOKE_IRQPRIO_INST_STORAGE:
 	case BOOKE_IRQPRIO_FP_UNAVAIL:
+	case BOOKE_IRQPRIO_SPE_UNAVAIL:
+	case BOOKE_IRQPRIO_SPE_FP_DATA:
+	case BOOKE_IRQPRIO_SPE_FP_ROUND:
 	case BOOKE_IRQPRIO_AP_UNAVAIL:
 	case BOOKE_IRQPRIO_ALIGNMENT:
 		allowed = 1;
@@ -165,7 +166,7 @@ void kvmppc_core_deliver_interrupts(stru
 	unsigned int priority;
 
 	priority = __ffs(*pending);
-	while (priority <= BOOKE_MAX_INTERRUPT) {
+	while (priority <= BOOKE_IRQPRIO_MAX) {
 		if (kvmppc_booke_irqprio_deliver(vcpu, priority))
 			break;
 
@@ -263,6 +264,21 @@ int kvmppc_handle_exit(struct kvm_run *r
 		r = RESUME_GUEST;
 		break;
 
+	case BOOKE_INTERRUPT_SPE_UNAVAIL:
+		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_UNAVAIL);
+		r = RESUME_GUEST;
+		break;
+
+	case BOOKE_INTERRUPT_SPE_FP_DATA:
+		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA);
+		r = RESUME_GUEST;
+		break;
+
+	case BOOKE_INTERRUPT_SPE_FP_ROUND:
+		kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND);
+		r = RESUME_GUEST;
+		break;
+
 	case BOOKE_INTERRUPT_DATA_STORAGE:
 		vcpu->arch.dear = vcpu->arch.fault_dear;
 		vcpu->arch.esr = vcpu->arch.fault_esr;
@@ -284,29 +300,27 @@ int kvmppc_handle_exit(struct kvm_run *r
 		r = RESUME_GUEST;
 		break;
 
-	/* XXX move to a 440-specific file. */
 	case BOOKE_INTERRUPT_DTLB_MISS: {
-		struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
-		struct kvmppc_44x_tlbe *gtlbe;
 		unsigned long eaddr = vcpu->arch.fault_dear;
 		int gtlb_index;
+		gpa_t gpaddr;
 		gfn_t gfn;
 
 		/* Check the guest TLB. */
-		gtlb_index = kvmppc_44x_dtlb_index(vcpu, eaddr);
+		gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
 		if (gtlb_index < 0) {
 			/* The guest didn't have a mapping for it. */
 			kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
 			vcpu->arch.dear = vcpu->arch.fault_dear;
 			vcpu->arch.esr = vcpu->arch.fault_esr;
+			kvmppc_mmu_dtlb_miss(vcpu);
 			kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
 			r = RESUME_GUEST;
 			break;
 		}
 
-		gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
-		vcpu->arch.paddr_accessed = tlb_xlate(gtlbe, eaddr);
-		gfn = vcpu->arch.paddr_accessed >> PAGE_SHIFT;
+		gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
+		gfn = gpaddr >> PAGE_SHIFT;
 
 		if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
 			/* The guest TLB had a mapping, but the shadow TLB
@@ -315,13 +329,13 @@ int kvmppc_handle_exit(struct kvm_run *r
 			 * b) the guest used a large mapping which we're faking
 			 * Either way, we need to satisfy the fault without
 			 * invoking the guest. */
-			kvmppc_mmu_map(vcpu, eaddr, vcpu->arch.paddr_accessed, gtlbe->tid,
-			               gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index);
+			kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
 			kvmppc_account_exit(vcpu, DTLB_VIRT_MISS_EXITS);
 			r = RESUME_GUEST;
 		} else {
 			/* Guest has mapped and accessed a page which is not
 			 * actually RAM. */
+			vcpu->arch.paddr_accessed = gpaddr;
 			r = kvmppc_emulate_mmio(run, vcpu);
 			kvmppc_account_exit(vcpu, MMIO_EXITS);
 		}
@@ -329,10 +343,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 		break;
 	}
 
-	/* XXX move to a 440-specific file. */
 	case BOOKE_INTERRUPT_ITLB_MISS: {
-		struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
-		struct kvmppc_44x_tlbe *gtlbe;
 		unsigned long eaddr = vcpu->arch.pc;
 		gpa_t gpaddr;
 		gfn_t gfn;
@@ -341,18 +352,18 @@ int kvmppc_handle_exit(struct kvm_run *r
 		r = RESUME_GUEST;
 
 		/* Check the guest TLB. */
-		gtlb_index = kvmppc_44x_itlb_index(vcpu, eaddr);
+		gtlb_index = kvmppc_mmu_itlb_index(vcpu, eaddr);
 		if (gtlb_index < 0) {
 			/* The guest didn't have a mapping for it. */
 			kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS);
+			kvmppc_mmu_itlb_miss(vcpu);
 			kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
 			break;
 		}
 
 		kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
 
-		gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
-		gpaddr = tlb_xlate(gtlbe, eaddr);
+		gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
 		gfn = gpaddr >> PAGE_SHIFT;
 
 		if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
@@ -362,8 +373,7 @@ int kvmppc_handle_exit(struct kvm_run *r
 			 * b) the guest used a large mapping which we're faking
 			 * Either way, we need to satisfy the fault without
 			 * invoking the guest. */
-			kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlbe->tid,
-			               gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index);
+			kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
 		} else {
 			/* Guest mapped and leaped at non-RAM! */
 			kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke_emulate.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke_emulate.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke_emulate.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke_emulate.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * This program is free software; you can 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 IBM Corp. 2008
+ *
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/disassemble.h>
+
+#include "booke.h"
+
+#define OP_19_XOP_RFI     50
+
+#define OP_31_XOP_MFMSR   83
+#define OP_31_XOP_WRTEE   131
+#define OP_31_XOP_MTMSR   146
+#define OP_31_XOP_WRTEEI  163
+
+static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.pc = vcpu->arch.srr0;
+	kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+}
+
+int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                            unsigned int inst, int *advance)
+{
+	int emulated = EMULATE_DONE;
+	int rs;
+	int rt;
+
+	switch (get_op(inst)) {
+	case 19:
+		switch (get_xop(inst)) {
+		case OP_19_XOP_RFI:
+			kvmppc_emul_rfi(vcpu);
+			kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
+			*advance = 0;
+			break;
+
+		default:
+			emulated = EMULATE_FAIL;
+			break;
+		}
+		break;
+
+	case 31:
+		switch (get_xop(inst)) {
+
+		case OP_31_XOP_MFMSR:
+			rt = get_rt(inst);
+			vcpu->arch.gpr[rt] = vcpu->arch.msr;
+			kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
+			break;
+
+		case OP_31_XOP_MTMSR:
+			rs = get_rs(inst);
+			kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
+			kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
+			break;
+
+		case OP_31_XOP_WRTEE:
+			rs = get_rs(inst);
+			vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+							 | (vcpu->arch.gpr[rs] & MSR_EE);
+			kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
+			break;
+
+		case OP_31_XOP_WRTEEI:
+			vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+							 | (inst & MSR_EE);
+			kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
+			break;
+
+		default:
+			emulated = EMULATE_FAIL;
+		}
+
+		break;
+
+	default:
+		emulated = EMULATE_FAIL;
+	}
+
+	return emulated;
+}
+
+int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_DEAR:
+		vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
+	case SPRN_ESR:
+		vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
+	case SPRN_DBCR0:
+		vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
+	case SPRN_DBCR1:
+		vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+	case SPRN_DBSR:
+		vcpu->arch.dbsr &= ~vcpu->arch.gpr[rs]; break;
+	case SPRN_TSR:
+		vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
+	case SPRN_TCR:
+		vcpu->arch.tcr = vcpu->arch.gpr[rs];
+		kvmppc_emulate_dec(vcpu);
+		break;
+
+	/* Note: SPRG4-7 are user-readable. These values are
+	 * loaded into the real SPRGs when resuming the
+	 * guest. */
+	case SPRN_SPRG4:
+		vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
+	case SPRN_SPRG5:
+		vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
+	case SPRN_SPRG6:
+		vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
+	case SPRN_SPRG7:
+		vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
+
+	case SPRN_IVPR:
+		vcpu->arch.ivpr = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR0:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR1:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR2:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR3:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR4:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR5:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR6:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR7:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR8:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR9:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR10:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR11:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR12:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR13:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR14:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR15:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
+		break;
+
+	default:
+		emulated = EMULATE_FAIL;
+	}
+
+	return emulated;
+}
+
+int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_IVPR:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
+	case SPRN_DEAR:
+		vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
+	case SPRN_ESR:
+		vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
+	case SPRN_DBCR0:
+		vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
+	case SPRN_DBCR1:
+		vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+	case SPRN_DBSR:
+		vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
+
+	case SPRN_IVOR0:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+		break;
+	case SPRN_IVOR1:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+		break;
+	case SPRN_IVOR2:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+		break;
+	case SPRN_IVOR3:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+		break;
+	case SPRN_IVOR4:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+		break;
+	case SPRN_IVOR5:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+		break;
+	case SPRN_IVOR6:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+		break;
+	case SPRN_IVOR7:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+		break;
+	case SPRN_IVOR8:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+		break;
+	case SPRN_IVOR9:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+		break;
+	case SPRN_IVOR10:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+		break;
+	case SPRN_IVOR11:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+		break;
+	case SPRN_IVOR12:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+		break;
+	case SPRN_IVOR13:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+		break;
+	case SPRN_IVOR14:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+		break;
+	case SPRN_IVOR15:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+		break;
+
+	default:
+		emulated = EMULATE_FAIL;
+	}
+
+	return emulated;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke.h linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/types.h>
 #include <linux/kvm_host.h>
+#include <asm/kvm_ppc.h>
 #include "timing.h"
 
 /* interrupt priortity ordering */
@@ -30,17 +31,24 @@
 #define BOOKE_IRQPRIO_ALIGNMENT 2
 #define BOOKE_IRQPRIO_PROGRAM 3
 #define BOOKE_IRQPRIO_FP_UNAVAIL 4
-#define BOOKE_IRQPRIO_SYSCALL 5
-#define BOOKE_IRQPRIO_AP_UNAVAIL 6
-#define BOOKE_IRQPRIO_DTLB_MISS 7
-#define BOOKE_IRQPRIO_ITLB_MISS 8
-#define BOOKE_IRQPRIO_MACHINE_CHECK 9
-#define BOOKE_IRQPRIO_DEBUG 10
-#define BOOKE_IRQPRIO_CRITICAL 11
-#define BOOKE_IRQPRIO_WATCHDOG 12
-#define BOOKE_IRQPRIO_EXTERNAL 13
-#define BOOKE_IRQPRIO_FIT 14
-#define BOOKE_IRQPRIO_DECREMENTER 15
+#define BOOKE_IRQPRIO_SPE_UNAVAIL 5
+#define BOOKE_IRQPRIO_SPE_FP_DATA 6
+#define BOOKE_IRQPRIO_SPE_FP_ROUND 7
+#define BOOKE_IRQPRIO_SYSCALL 8
+#define BOOKE_IRQPRIO_AP_UNAVAIL 9
+#define BOOKE_IRQPRIO_DTLB_MISS 10
+#define BOOKE_IRQPRIO_ITLB_MISS 11
+#define BOOKE_IRQPRIO_MACHINE_CHECK 12
+#define BOOKE_IRQPRIO_DEBUG 13
+#define BOOKE_IRQPRIO_CRITICAL 14
+#define BOOKE_IRQPRIO_WATCHDOG 15
+#define BOOKE_IRQPRIO_EXTERNAL 16
+#define BOOKE_IRQPRIO_FIT 17
+#define BOOKE_IRQPRIO_DECREMENTER 18
+#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
+#define BOOKE_IRQPRIO_MAX 19
+
+extern unsigned long kvmppc_booke_handlers;
 
 /* Helper function for "full" MSR writes. No need to call this if only EE is
  * changing. */
@@ -57,4 +65,9 @@ static inline void kvmppc_set_msr(struct
 	};
 }
 
+int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                            unsigned int inst, int *advance);
+int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt);
+int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs);
+
 #endif /* __KVM_BOOKE_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke_interrupts.S linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke_interrupts.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/booke_interrupts.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/booke_interrupts.S	2009-06-09 23:05:27.000000000 -0400
@@ -86,6 +86,9 @@ KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG
 KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS
 KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS
 KVM_HANDLER BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND
 
 _GLOBAL(kvmppc_handler_len)
 	.long kvmppc_handler_1 - kvmppc_handler_0
@@ -347,7 +350,9 @@ lightweight_exit:
 	lwz	r3, VCPU_SHADOW_PID(r4)
 	mtspr	SPRN_PID, r3
 
+#ifdef CONFIG_44x
 	iccci	0, 0 /* XXX hack */
+#endif
 
 	/* Load some guest volatiles. */
 	lwz	r0, VCPU_GPR(r0)(r4)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * 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/tlbflush.h>
+#include <asm/kvm_e500.h>
+#include <asm/kvm_ppc.h>
+
+#include "booke.h"
+#include "e500_tlb.h"
+
+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)
+{
+	kvmppc_e500_tlb_load(vcpu, cpu);
+}
+
+void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
+{
+	kvmppc_e500_tlb_put(vcpu);
+}
+
+int kvmppc_core_check_processor_compat(void)
+{
+	int r;
+
+	if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0)
+		r = 0;
+	else
+		r = -ENOTSUPP;
+
+	return r;
+}
+
+int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	kvmppc_e500_tlb_setup(vcpu_e500);
+
+	/* Use the same core vertion as host's */
+	vcpu->arch.pvr = mfspr(SPRN_PVR);
+
+	return 0;
+}
+
+/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
+int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
+                               struct kvm_translation *tr)
+{
+	int index;
+	gva_t eaddr;
+	u8 pid;
+	u8 as;
+
+	eaddr = tr->linear_address;
+	pid = (tr->linear_address >> 32) & 0xff;
+	as = (tr->linear_address >> 40) & 0x1;
+
+	index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
+	if (index < 0) {
+		tr->valid = 0;
+		return 0;
+	}
+
+	tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
+	/* XXX what does "writeable" and "usermode" even mean? */
+	tr->valid = 1;
+
+	return 0;
+}
+
+struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500;
+	struct kvm_vcpu *vcpu;
+	int err;
+
+	vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
+	if (!vcpu_e500) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	vcpu = &vcpu_e500->vcpu;
+	err = kvm_vcpu_init(vcpu, kvm, id);
+	if (err)
+		goto free_vcpu;
+
+	err = kvmppc_e500_tlb_init(vcpu_e500);
+	if (err)
+		goto uninit_vcpu;
+
+	return vcpu;
+
+uninit_vcpu:
+	kvm_vcpu_uninit(vcpu);
+free_vcpu:
+	kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
+out:
+	return ERR_PTR(err);
+}
+
+void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	kvmppc_e500_tlb_uninit(vcpu_e500);
+	kvm_vcpu_uninit(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
+}
+
+static int kvmppc_e500_init(void)
+{
+	int r, i;
+	unsigned long ivor[3];
+	unsigned long max_ivor = 0;
+
+	r = kvmppc_booke_init();
+	if (r)
+		return r;
+
+	/* copy extra E500 exception handlers */
+	ivor[0] = mfspr(SPRN_IVOR32);
+	ivor[1] = mfspr(SPRN_IVOR33);
+	ivor[2] = mfspr(SPRN_IVOR34);
+	for (i = 0; i < 3; i++) {
+		if (ivor[i] > max_ivor)
+			max_ivor = ivor[i];
+
+		memcpy((void *)kvmppc_booke_handlers + ivor[i],
+		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
+		       kvmppc_handler_len);
+	}
+	flush_icache_range(kvmppc_booke_handlers,
+			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+
+	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
+}
+
+static void kvmppc_e500_exit(void)
+{
+	kvmppc_booke_exit();
+}
+
+module_init(kvmppc_e500_init);
+module_exit(kvmppc_e500_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_emulate.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_emulate.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_emulate.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_emulate.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x_emulate.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 <asm/kvm_ppc.h>
+#include <asm/disassemble.h>
+#include <asm/kvm_e500.h>
+
+#include "booke.h"
+#include "e500_tlb.h"
+
+#define XOP_TLBIVAX 786
+#define XOP_TLBSX   914
+#define XOP_TLBRE   946
+#define XOP_TLBWE   978
+
+int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+                           unsigned int inst, int *advance)
+{
+	int emulated = EMULATE_DONE;
+	int ra;
+	int rb;
+
+	switch (get_op(inst)) {
+	case 31:
+		switch (get_xop(inst)) {
+
+		case XOP_TLBRE:
+			emulated = kvmppc_e500_emul_tlbre(vcpu);
+			break;
+
+		case XOP_TLBWE:
+			emulated = kvmppc_e500_emul_tlbwe(vcpu);
+			break;
+
+		case XOP_TLBSX:
+			rb = get_rb(inst);
+			emulated = kvmppc_e500_emul_tlbsx(vcpu,rb);
+			break;
+
+		case XOP_TLBIVAX:
+			ra = get_ra(inst);
+			rb = get_rb(inst);
+			emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb);
+			break;
+
+		default:
+			emulated = EMULATE_FAIL;
+		}
+
+		break;
+
+	default:
+		emulated = EMULATE_FAIL;
+	}
+
+	if (emulated == EMULATE_FAIL)
+		emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
+
+	return emulated;
+}
+
+int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_PID:
+		vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
+			vcpu->arch.pid = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_PID1:
+		vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
+	case SPRN_PID2:
+		vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS0:
+		vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS1:
+		vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS2:
+		vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS3:
+		vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS4:
+		vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS6:
+		vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
+	case SPRN_MAS7:
+		vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
+	case SPRN_L1CSR1:
+		vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
+	case SPRN_HID0:
+		vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
+	case SPRN_HID1:
+		vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
+
+	case SPRN_MMUCSR0:
+		emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
+				vcpu->arch.gpr[rs]);
+		break;
+
+	/* extra exceptions */
+	case SPRN_IVOR32:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR33:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR34:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
+		break;
+	case SPRN_IVOR35:
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
+		break;
+
+	default:
+		emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
+	}
+
+	return emulated;
+}
+
+int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int emulated = EMULATE_DONE;
+
+	switch (sprn) {
+	case SPRN_PID:
+		vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
+	case SPRN_PID1:
+		vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
+	case SPRN_PID2:
+		vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
+	case SPRN_MAS0:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
+	case SPRN_MAS1:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
+	case SPRN_MAS2:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
+	case SPRN_MAS3:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
+	case SPRN_MAS4:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
+	case SPRN_MAS6:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
+	case SPRN_MAS7:
+		vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
+
+	case SPRN_TLB0CFG:
+		vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
+		vcpu->arch.gpr[rt] &= ~0xfffUL;
+		vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[0];
+		break;
+
+	case SPRN_TLB1CFG:
+		vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
+		vcpu->arch.gpr[rt] &= ~0xfffUL;
+		vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[1];
+		break;
+
+	case SPRN_L1CSR1:
+		vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
+	case SPRN_HID0:
+		vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
+	case SPRN_HID1:
+		vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
+
+	case SPRN_MMUCSR0:
+		vcpu->arch.gpr[rt] = 0; break;
+
+	/* extra exceptions */
+	case SPRN_IVOR32:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+		break;
+	case SPRN_IVOR33:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+		break;
+	case SPRN_IVOR34:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
+		break;
+	case SPRN_IVOR35:
+		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+		break;
+	default:
+		emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
+	}
+
+	return emulated;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_tlb.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_tlb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_tlb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,757 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu.liu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.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/types.h>
+#include <linux/string.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/highmem.h>
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_e500.h>
+
+#include "../mm/mmu_decl.h"
+#include "e500_tlb.h"
+
+#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
+
+static unsigned int tlb1_entry_num;
+
+void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	struct tlbe *tlbe;
+	int i, tlbsel;
+
+	printk("| %8s | %8s | %8s | %8s | %8s |\n",
+			"nr", "mas1", "mas2", "mas3", "mas7");
+
+	for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+		printk("Guest TLB%d:\n", tlbsel);
+		for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++) {
+			tlbe = &vcpu_e500->guest_tlb[tlbsel][i];
+			if (tlbe->mas1 & MAS1_VALID)
+				printk(" G[%d][%3d] |  %08X | %08X | %08X | %08X |\n",
+					tlbsel, i, tlbe->mas1, tlbe->mas2,
+					tlbe->mas3, tlbe->mas7);
+		}
+	}
+
+	for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+		printk("Shadow TLB%d:\n", tlbsel);
+		for (i = 0; i < vcpu_e500->shadow_tlb_size[tlbsel]; i++) {
+			tlbe = &vcpu_e500->shadow_tlb[tlbsel][i];
+			if (tlbe->mas1 & MAS1_VALID)
+				printk(" S[%d][%3d] |  %08X | %08X | %08X | %08X |\n",
+					tlbsel, i, tlbe->mas1, tlbe->mas2,
+					tlbe->mas3, tlbe->mas7);
+		}
+	}
+}
+
+static inline unsigned int tlb0_get_next_victim(
+		struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	unsigned int victim;
+
+	victim = vcpu_e500->guest_tlb_nv[0]++;
+	if (unlikely(vcpu_e500->guest_tlb_nv[0] >= KVM_E500_TLB0_WAY_NUM))
+		vcpu_e500->guest_tlb_nv[0] = 0;
+
+	return victim;
+}
+
+static inline unsigned int tlb1_max_shadow_size(void)
+{
+	return tlb1_entry_num - tlbcam_index;
+}
+
+static inline int tlbe_is_writable(struct tlbe *tlbe)
+{
+	return tlbe->mas3 & (MAS3_SW|MAS3_UW);
+}
+
+static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
+{
+	/* Mask off reserved bits. */
+	mas3 &= MAS3_ATTRIB_MASK;
+
+	if (!usermode) {
+		/* Guest is in supervisor mode,
+		 * so we need to translate guest
+		 * supervisor permissions into user permissions. */
+		mas3 &= ~E500_TLB_USER_PERM_MASK;
+		mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1;
+	}
+
+	return mas3 | E500_TLB_SUPER_PERM_MASK;
+}
+
+static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
+{
+#ifdef CONFIG_SMP
+	return (mas2 & MAS2_ATTRIB_MASK) | MAS2_M;
+#else
+	return mas2 & MAS2_ATTRIB_MASK;
+#endif
+}
+
+/*
+ * writing shadow tlb entry to host TLB
+ */
+static inline void __write_host_tlbe(struct tlbe *stlbe)
+{
+	mtspr(SPRN_MAS1, stlbe->mas1);
+	mtspr(SPRN_MAS2, stlbe->mas2);
+	mtspr(SPRN_MAS3, stlbe->mas3);
+	mtspr(SPRN_MAS7, stlbe->mas7);
+	__asm__ __volatile__ ("tlbwe\n" : : );
+}
+
+static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel, int esel)
+{
+	struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+	local_irq_disable();
+	if (tlbsel == 0) {
+		__write_host_tlbe(stlbe);
+	} else {
+		unsigned register mas0;
+
+		mas0 = mfspr(SPRN_MAS0);
+
+		mtspr(SPRN_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(to_htlb1_esel(esel)));
+		__write_host_tlbe(stlbe);
+
+		mtspr(SPRN_MAS0, mas0);
+	}
+	local_irq_enable();
+}
+
+void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int i;
+	unsigned register mas0;
+
+	/* Load all valid TLB1 entries to reduce guest tlb miss fault */
+	local_irq_disable();
+	mas0 = mfspr(SPRN_MAS0);
+	for (i = 0; i < tlb1_max_shadow_size(); i++) {
+		struct tlbe *stlbe = &vcpu_e500->shadow_tlb[1][i];
+
+		if (get_tlb_v(stlbe)) {
+			mtspr(SPRN_MAS0, MAS0_TLBSEL(1)
+					| MAS0_ESEL(to_htlb1_esel(i)));
+			__write_host_tlbe(stlbe);
+		}
+	}
+	mtspr(SPRN_MAS0, mas0);
+	local_irq_enable();
+}
+
+void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu)
+{
+	_tlbil_all();
+}
+
+/* Search the guest TLB for a matching entry. */
+static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
+		gva_t eaddr, int tlbsel, unsigned int pid, int as)
+{
+	int i;
+
+	/* XXX Replace loop with fancy data structures. */
+	for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++) {
+		struct tlbe *tlbe = &vcpu_e500->guest_tlb[tlbsel][i];
+		unsigned int tid;
+
+		if (eaddr < get_tlb_eaddr(tlbe))
+			continue;
+
+		if (eaddr > get_tlb_end(tlbe))
+			continue;
+
+		tid = get_tlb_tid(tlbe);
+		if (tid && (tid != pid))
+			continue;
+
+		if (!get_tlb_v(tlbe))
+			continue;
+
+		if (get_tlb_ts(tlbe) != as && as != -1)
+			continue;
+
+		return i;
+	}
+
+	return -1;
+}
+
+static void kvmppc_e500_shadow_release(struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel, int esel)
+{
+	struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+	struct page *page = vcpu_e500->shadow_pages[tlbsel][esel];
+
+	if (page) {
+		vcpu_e500->shadow_pages[tlbsel][esel] = NULL;
+
+		if (get_tlb_v(stlbe)) {
+			if (tlbe_is_writable(stlbe))
+				kvm_release_page_dirty(page);
+			else
+				kvm_release_page_clean(page);
+		}
+	}
+}
+
+static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel, int esel)
+{
+	struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+	kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
+	stlbe->mas1 = 0;
+	KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel),
+			stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
+			handler);
+}
+
+static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+		gva_t eaddr, gva_t eend, u32 tid)
+{
+	unsigned int pid = tid & 0xff;
+	unsigned int i;
+
+	/* XXX Replace loop with fancy data structures. */
+	for (i = 0; i < vcpu_e500->guest_tlb_size[1]; i++) {
+		struct tlbe *stlbe = &vcpu_e500->shadow_tlb[1][i];
+		unsigned int tid;
+
+		if (!get_tlb_v(stlbe))
+			continue;
+
+		if (eend < get_tlb_eaddr(stlbe))
+			continue;
+
+		if (eaddr > get_tlb_end(stlbe))
+			continue;
+
+		tid = get_tlb_tid(stlbe);
+		if (tid && (tid != pid))
+			continue;
+
+		kvmppc_e500_stlbe_invalidate(vcpu_e500, 1, i);
+		write_host_tlbe(vcpu_e500, 1, i);
+	}
+}
+
+static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
+		unsigned int eaddr, int as)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	unsigned int victim, pidsel, tsized;
+	int tlbsel;
+
+	/* since we only have two TLBs, only lower bit is used. */
+	tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
+	victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
+	pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
+	tsized = (vcpu_e500->mas4 >> 8) & 0xf;
+
+	vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
+		| MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+	vcpu_e500->mas1 = MAS1_VALID | (as ? MAS1_TS : 0)
+		| MAS1_TID(vcpu_e500->pid[pidsel])
+		| MAS1_TSIZE(tsized);
+	vcpu_e500->mas2 = (eaddr & MAS2_EPN)
+		| (vcpu_e500->mas4 & MAS2_ATTRIB_MASK);
+	vcpu_e500->mas3 &= MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3;
+	vcpu_e500->mas6 = (vcpu_e500->mas6 & MAS6_SPID1)
+		| (get_cur_pid(vcpu) << 16)
+		| (as ? MAS6_SAS : 0);
+	vcpu_e500->mas7 = 0;
+}
+
+static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+	u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, int tlbsel, int esel)
+{
+	struct page *new_page;
+	struct tlbe *stlbe;
+	hpa_t hpaddr;
+
+	stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+	/* Get reference to new page. */
+	new_page = gfn_to_page(vcpu_e500->vcpu.kvm, gfn);
+	if (is_error_page(new_page)) {
+		printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn);
+		kvm_release_page_clean(new_page);
+		return;
+	}
+	hpaddr = page_to_phys(new_page);
+
+	/* Drop reference to old page. */
+	kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
+
+	vcpu_e500->shadow_pages[tlbsel][esel] = new_page;
+
+	/* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */
+	stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K)
+		| MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
+	stlbe->mas2 = (gvaddr & MAS2_EPN)
+		| e500_shadow_mas2_attrib(gtlbe->mas2,
+				vcpu_e500->vcpu.arch.msr & MSR_PR);
+	stlbe->mas3 = (hpaddr & MAS3_RPN)
+		| e500_shadow_mas3_attrib(gtlbe->mas3,
+				vcpu_e500->vcpu.arch.msr & MSR_PR);
+	stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
+
+	KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel),
+			stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
+			handler);
+}
+
+/* XXX only map the one-one case, for now use TLB0 */
+static int kvmppc_e500_stlbe_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel, int esel)
+{
+	struct tlbe *gtlbe;
+
+	gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+	kvmppc_e500_shadow_map(vcpu_e500, get_tlb_eaddr(gtlbe),
+			get_tlb_raddr(gtlbe) >> PAGE_SHIFT,
+			gtlbe, tlbsel, esel);
+
+	return esel;
+}
+
+/* Caller must ensure that the specified guest TLB entry is safe to insert into
+ * the shadow TLB. */
+/* XXX for both one-one and one-to-many , for now use TLB1 */
+static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+		u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe)
+{
+	unsigned int victim;
+
+	victim = vcpu_e500->guest_tlb_nv[1]++;
+
+	if (unlikely(vcpu_e500->guest_tlb_nv[1] >= tlb1_max_shadow_size()))
+		vcpu_e500->guest_tlb_nv[1] = 0;
+
+	kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, victim);
+
+	return victim;
+}
+
+/* Invalidate all guest kernel mappings when enter usermode,
+ * so that when they fault back in they will get the
+ * proper permission bits. */
+void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
+{
+	if (usermode) {
+		struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+		int i;
+
+		/* XXX Replace loop with fancy data structures. */
+		for (i = 0; i < tlb1_max_shadow_size(); i++)
+			kvmppc_e500_stlbe_invalidate(vcpu_e500, 1, i);
+
+		_tlbil_all();
+	}
+}
+
+static int kvmppc_e500_gtlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel, int esel)
+{
+	struct tlbe *gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+	if (unlikely(get_tlb_iprot(gtlbe)))
+		return -1;
+
+	if (tlbsel == 1) {
+		kvmppc_e500_tlb1_invalidate(vcpu_e500, get_tlb_eaddr(gtlbe),
+				get_tlb_end(gtlbe),
+				get_tlb_tid(gtlbe));
+	} else {
+		kvmppc_e500_stlbe_invalidate(vcpu_e500, tlbsel, esel);
+	}
+
+	gtlbe->mas1 = 0;
+
+	return 0;
+}
+
+int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500, ulong value)
+{
+	int esel;
+
+	if (value & MMUCSR0_TLB0FI)
+		for (esel = 0; esel < vcpu_e500->guest_tlb_size[0]; esel++)
+			kvmppc_e500_gtlbe_invalidate(vcpu_e500, 0, esel);
+	if (value & MMUCSR0_TLB1FI)
+		for (esel = 0; esel < vcpu_e500->guest_tlb_size[1]; esel++)
+			kvmppc_e500_gtlbe_invalidate(vcpu_e500, 1, esel);
+
+	_tlbil_all();
+
+	return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	unsigned int ia;
+	int esel, tlbsel;
+	gva_t ea;
+
+	ea = ((ra) ? vcpu->arch.gpr[ra] : 0) + vcpu->arch.gpr[rb];
+
+	ia = (ea >> 2) & 0x1;
+
+	/* since we only have two TLBs, only lower bit is used. */
+	tlbsel = (ea >> 3) & 0x1;
+
+	if (ia) {
+		/* invalidate all entries */
+		for (esel = 0; esel < vcpu_e500->guest_tlb_size[tlbsel]; esel++)
+			kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
+	} else {
+		ea &= 0xfffff000;
+		esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel,
+				get_cur_pid(vcpu), -1);
+		if (esel >= 0)
+			kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
+	}
+
+	_tlbil_all();
+
+	return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int tlbsel, esel;
+	struct tlbe *gtlbe;
+
+	tlbsel = get_tlb_tlbsel(vcpu_e500);
+	esel = get_tlb_esel(vcpu_e500, tlbsel);
+
+	gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+	vcpu_e500->mas0 &= ~MAS0_NV(~0);
+	vcpu_e500->mas0 |= MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+	vcpu_e500->mas1 = gtlbe->mas1;
+	vcpu_e500->mas2 = gtlbe->mas2;
+	vcpu_e500->mas3 = gtlbe->mas3;
+	vcpu_e500->mas7 = gtlbe->mas7;
+
+	return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int as = !!get_cur_sas(vcpu_e500);
+	unsigned int pid = get_cur_spid(vcpu_e500);
+	int esel, tlbsel;
+	struct tlbe *gtlbe = NULL;
+	gva_t ea;
+
+	ea = vcpu->arch.gpr[rb];
+
+	for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+		esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);
+		if (esel >= 0) {
+			gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+			break;
+		}
+	}
+
+	if (gtlbe) {
+		vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(esel)
+			| MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+		vcpu_e500->mas1 = gtlbe->mas1;
+		vcpu_e500->mas2 = gtlbe->mas2;
+		vcpu_e500->mas3 = gtlbe->mas3;
+		vcpu_e500->mas7 = gtlbe->mas7;
+	} else {
+		int victim;
+
+		/* since we only have two TLBs, only lower bit is used. */
+		tlbsel = vcpu_e500->mas4 >> 28 & 0x1;
+		victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
+
+		vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
+			| MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+		vcpu_e500->mas1 = (vcpu_e500->mas6 & MAS6_SPID0)
+			| (vcpu_e500->mas6 & (MAS6_SAS ? MAS1_TS : 0))
+			| (vcpu_e500->mas4 & MAS4_TSIZED(~0));
+		vcpu_e500->mas2 &= MAS2_EPN;
+		vcpu_e500->mas2 |= vcpu_e500->mas4 & MAS2_ATTRIB_MASK;
+		vcpu_e500->mas3 &= MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3;
+		vcpu_e500->mas7 = 0;
+	}
+
+	return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	u64 eaddr;
+	u64 raddr;
+	u32 tid;
+	struct tlbe *gtlbe;
+	int tlbsel, esel, stlbsel, sesel;
+
+	tlbsel = get_tlb_tlbsel(vcpu_e500);
+	esel = get_tlb_esel(vcpu_e500, tlbsel);
+
+	gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+	if (get_tlb_v(gtlbe) && tlbsel == 1) {
+		eaddr = get_tlb_eaddr(gtlbe);
+		tid = get_tlb_tid(gtlbe);
+		kvmppc_e500_tlb1_invalidate(vcpu_e500, eaddr,
+				get_tlb_end(gtlbe), tid);
+	}
+
+	gtlbe->mas1 = vcpu_e500->mas1;
+	gtlbe->mas2 = vcpu_e500->mas2;
+	gtlbe->mas3 = vcpu_e500->mas3;
+	gtlbe->mas7 = vcpu_e500->mas7;
+
+	KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0,
+			gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7,
+			handler);
+
+	/* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
+	if (tlbe_is_host_safe(vcpu, gtlbe)) {
+		switch (tlbsel) {
+		case 0:
+			/* TLB0 */
+			gtlbe->mas1 &= ~MAS1_TSIZE(~0);
+			gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K);
+
+			stlbsel = 0;
+			sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel);
+
+			break;
+
+		case 1:
+			/* TLB1 */
+			eaddr = get_tlb_eaddr(gtlbe);
+			raddr = get_tlb_raddr(gtlbe);
+
+			/* Create a 4KB mapping on the host.
+			 * If the guest wanted a large page,
+			 * only the first 4KB is mapped here and the rest
+			 * are mapped on the fly. */
+			stlbsel = 1;
+			sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr,
+					raddr >> PAGE_SHIFT, gtlbe);
+			break;
+
+		default:
+			BUG();
+		}
+		write_host_tlbe(vcpu_e500, stlbsel, sesel);
+	}
+
+	return EMULATE_DONE;
+}
+
+int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+{
+	unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+
+	return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
+}
+
+int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+{
+	unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+
+	return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
+}
+
+void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
+{
+	unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+
+	kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.pc, as);
+}
+
+void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
+{
+	unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+
+	kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.fault_dear, as);
+}
+
+gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int index,
+			gva_t eaddr)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	struct tlbe *gtlbe =
+		&vcpu_e500->guest_tlb[tlbsel_of(index)][esel_of(index)];
+	u64 pgmask = get_tlb_bytes(gtlbe) - 1;
+
+	return get_tlb_raddr(gtlbe) | (eaddr & pgmask);
+}
+
+void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int tlbsel, i;
+
+	for (tlbsel = 0; tlbsel < 2; tlbsel++)
+		for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++)
+			kvmppc_e500_shadow_release(vcpu_e500, tlbsel, i);
+
+	/* discard all guest mapping */
+	_tlbil_all();
+}
+
+void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
+			unsigned int index)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int tlbsel = tlbsel_of(index);
+	int esel = esel_of(index);
+	int stlbsel, sesel;
+
+	switch (tlbsel) {
+	case 0:
+		stlbsel = 0;
+		sesel = esel;
+		break;
+
+	case 1: {
+		gfn_t gfn = gpaddr >> PAGE_SHIFT;
+		struct tlbe *gtlbe
+			= &vcpu_e500->guest_tlb[tlbsel][esel];
+
+		stlbsel = 1;
+		sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr, gfn, gtlbe);
+		break;
+	}
+
+	default:
+		BUG();
+		break;
+	}
+	write_host_tlbe(vcpu_e500, stlbsel, sesel);
+}
+
+int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
+				gva_t eaddr, unsigned int pid, int as)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	int esel, tlbsel;
+
+	for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+		esel = kvmppc_e500_tlb_index(vcpu_e500, eaddr, tlbsel, pid, as);
+		if (esel >= 0)
+			return index_of(tlbsel, esel);
+	}
+
+	return -1;
+}
+
+void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	struct tlbe *tlbe;
+
+	/* Insert large initial mapping for guest. */
+	tlbe = &vcpu_e500->guest_tlb[1][0];
+	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M);
+	tlbe->mas2 = 0;
+	tlbe->mas3 = E500_TLB_SUPER_PERM_MASK;
+	tlbe->mas7 = 0;
+
+	/* 4K map for serial output. Used by kernel wrapper. */
+	tlbe = &vcpu_e500->guest_tlb[1][1];
+	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K);
+	tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
+	tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
+	tlbe->mas7 = 0;
+}
+
+int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	tlb1_entry_num = mfspr(SPRN_TLB1CFG) & 0xFFF;
+
+	vcpu_e500->guest_tlb_size[0] = KVM_E500_TLB0_SIZE;
+	vcpu_e500->guest_tlb[0] =
+		kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+	if (vcpu_e500->guest_tlb[0] == NULL)
+		goto err_out;
+
+	vcpu_e500->shadow_tlb_size[0] = KVM_E500_TLB0_SIZE;
+	vcpu_e500->shadow_tlb[0] =
+		kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+	if (vcpu_e500->shadow_tlb[0] == NULL)
+		goto err_out_guest0;
+
+	vcpu_e500->guest_tlb_size[1] = KVM_E500_TLB1_SIZE;
+	vcpu_e500->guest_tlb[1] =
+		kzalloc(sizeof(struct tlbe) * KVM_E500_TLB1_SIZE, GFP_KERNEL);
+	if (vcpu_e500->guest_tlb[1] == NULL)
+		goto err_out_shadow0;
+
+	vcpu_e500->shadow_tlb_size[1] = tlb1_entry_num;
+	vcpu_e500->shadow_tlb[1] =
+		kzalloc(sizeof(struct tlbe) * tlb1_entry_num, GFP_KERNEL);
+	if (vcpu_e500->shadow_tlb[1] == NULL)
+		goto err_out_guest1;
+
+	vcpu_e500->shadow_pages[0] = (struct page **)
+		kzalloc(sizeof(struct page *) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+	if (vcpu_e500->shadow_pages[0] == NULL)
+		goto err_out_shadow1;
+
+	vcpu_e500->shadow_pages[1] = (struct page **)
+		kzalloc(sizeof(struct page *) * tlb1_entry_num, GFP_KERNEL);
+	if (vcpu_e500->shadow_pages[1] == NULL)
+		goto err_out_page0;
+
+	return 0;
+
+err_out_page0:
+	kfree(vcpu_e500->shadow_pages[0]);
+err_out_shadow1:
+	kfree(vcpu_e500->shadow_tlb[1]);
+err_out_guest1:
+	kfree(vcpu_e500->guest_tlb[1]);
+err_out_shadow0:
+	kfree(vcpu_e500->shadow_tlb[0]);
+err_out_guest0:
+	kfree(vcpu_e500->guest_tlb[0]);
+err_out:
+	return -1;
+}
+
+void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	kfree(vcpu_e500->shadow_pages[1]);
+	kfree(vcpu_e500->shadow_pages[0]);
+	kfree(vcpu_e500->shadow_tlb[1]);
+	kfree(vcpu_e500->guest_tlb[1]);
+	kfree(vcpu_e500->shadow_tlb[0]);
+	kfree(vcpu_e500->guest_tlb[0]);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_tlb.h linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_tlb.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/e500_tlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/e500_tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu.liu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.h,
+ * 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.
+ */
+
+#ifndef __KVM_E500_TLB_H__
+#define __KVM_E500_TLB_H__
+
+#include <linux/kvm_host.h>
+#include <asm/mmu-fsl-booke.h>
+#include <asm/tlb.h>
+#include <asm/kvm_e500.h>
+
+#define KVM_E500_TLB0_WAY_SIZE_BIT	7	/* Fixed */
+#define KVM_E500_TLB0_WAY_SIZE		(1UL << KVM_E500_TLB0_WAY_SIZE_BIT)
+#define KVM_E500_TLB0_WAY_SIZE_MASK	(KVM_E500_TLB0_WAY_SIZE - 1)
+
+#define KVM_E500_TLB0_WAY_NUM_BIT	1	/* No greater than 7 */
+#define KVM_E500_TLB0_WAY_NUM		(1UL << KVM_E500_TLB0_WAY_NUM_BIT)
+#define KVM_E500_TLB0_WAY_NUM_MASK	(KVM_E500_TLB0_WAY_NUM - 1)
+
+#define KVM_E500_TLB0_SIZE  (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
+#define KVM_E500_TLB1_SIZE  16
+
+#define index_of(tlbsel, esel)	(((tlbsel) << 16) | ((esel) & 0xFFFF))
+#define tlbsel_of(index)	((index) >> 16)
+#define esel_of(index)		((index) & 0xFFFF)
+
+#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
+#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
+#define MAS2_ATTRIB_MASK \
+	  (MAS2_X0 | MAS2_X1)
+#define MAS3_ATTRIB_MASK \
+	  (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
+	   | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)
+
+extern void kvmppc_dump_tlbs(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *, ulong);
+extern int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_tlbre(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *, int, int);
+extern int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *, int);
+extern int kvmppc_e500_tlb_search(struct kvm_vcpu *, gva_t, unsigned int, int);
+extern void kvmppc_e500_tlb_put(struct kvm_vcpu *);
+extern void kvmppc_e500_tlb_load(struct kvm_vcpu *, int);
+extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *);
+extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *);
+extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
+
+/* TLB helper functions */
+static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
+{
+	return (tlbe->mas1 >> 8) & 0xf;
+}
+
+static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
+{
+	return tlbe->mas2 & 0xfffff000;
+}
+
+static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
+{
+	unsigned int pgsize = get_tlb_size(tlbe);
+	return 1ULL << 10 << (pgsize << 1);
+}
+
+static inline gva_t get_tlb_end(const struct tlbe *tlbe)
+{
+	u64 bytes = get_tlb_bytes(tlbe);
+	return get_tlb_eaddr(tlbe) + bytes - 1;
+}
+
+static inline u64 get_tlb_raddr(const struct tlbe *tlbe)
+{
+	u64 rpn = tlbe->mas7;
+	return (rpn << 32) | (tlbe->mas3 & 0xfffff000);
+}
+
+static inline unsigned int get_tlb_tid(const struct tlbe *tlbe)
+{
+	return (tlbe->mas1 >> 16) & 0xff;
+}
+
+static inline unsigned int get_tlb_ts(const struct tlbe *tlbe)
+{
+	return (tlbe->mas1 >> 12) & 0x1;
+}
+
+static inline unsigned int get_tlb_v(const struct tlbe *tlbe)
+{
+	return (tlbe->mas1 >> 31) & 0x1;
+}
+
+static inline unsigned int get_tlb_iprot(const struct tlbe *tlbe)
+{
+	return (tlbe->mas1 >> 30) & 0x1;
+}
+
+static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.pid & 0xff;
+}
+
+static inline unsigned int get_cur_spid(
+		const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	return (vcpu_e500->mas6 >> 16) & 0xff;
+}
+
+static inline unsigned int get_cur_sas(
+		const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	return vcpu_e500->mas6 & 0x1;
+}
+
+static inline unsigned int get_tlb_tlbsel(
+		const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	/*
+	 * Manual says that tlbsel has 2 bits wide.
+	 * Since we only have two TLBs, only lower bit is used.
+	 */
+	return (vcpu_e500->mas0 >> 28) & 0x1;
+}
+
+static inline unsigned int get_tlb_nv_bit(
+		const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	return vcpu_e500->mas0 & 0xfff;
+}
+
+static inline unsigned int get_tlb_esel_bit(
+		const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+	return (vcpu_e500->mas0 >> 16) & 0xfff;
+}
+
+static inline unsigned int get_tlb_esel(
+		const struct kvmppc_vcpu_e500 *vcpu_e500,
+		int tlbsel)
+{
+	unsigned int esel = get_tlb_esel_bit(vcpu_e500);
+
+	if (tlbsel == 0) {
+		esel &= KVM_E500_TLB0_WAY_NUM_MASK;
+		esel |= ((vcpu_e500->mas2 >> 12) & KVM_E500_TLB0_WAY_SIZE_MASK)
+				<< KVM_E500_TLB0_WAY_NUM_BIT;
+	} else {
+		esel &= KVM_E500_TLB1_SIZE - 1;
+	}
+
+	return esel;
+}
+
+static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
+			const struct tlbe *tlbe)
+{
+	gpa_t gpa;
+
+	if (!get_tlb_v(tlbe))
+		return 0;
+
+	/* Does it match current guest AS? */
+	/* XXX what about IS != DS? */
+	if (get_tlb_ts(tlbe) != !!(vcpu->arch.msr & MSR_IS))
+		return 0;
+
+	gpa = get_tlb_raddr(tlbe);
+	if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
+		/* Mapping is not for RAM. */
+		return 0;
+
+	return 1;
+}
+
+#endif /* __KVM_E500_TLB_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/emulate.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/emulate.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/emulate.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/emulate.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,39 @@
 #include <asm/disassemble.h>
 #include "timing.h"
 
+#define OP_TRAP 3
+
+#define OP_31_XOP_LWZX      23
+#define OP_31_XOP_LBZX      87
+#define OP_31_XOP_STWX      151
+#define OP_31_XOP_STBX      215
+#define OP_31_XOP_STBUX     247
+#define OP_31_XOP_LHZX      279
+#define OP_31_XOP_LHZUX     311
+#define OP_31_XOP_MFSPR     339
+#define OP_31_XOP_STHX      407
+#define OP_31_XOP_STHUX     439
+#define OP_31_XOP_MTSPR     467
+#define OP_31_XOP_DCBI      470
+#define OP_31_XOP_LWBRX     534
+#define OP_31_XOP_TLBSYNC   566
+#define OP_31_XOP_STWBRX    662
+#define OP_31_XOP_LHBRX     790
+#define OP_31_XOP_STHBRX    918
+
+#define OP_LWZ  32
+#define OP_LWZU 33
+#define OP_LBZ  34
+#define OP_LBZU 35
+#define OP_STW  36
+#define OP_STWU 37
+#define OP_STB  38
+#define OP_STBU 39
+#define OP_LHZ  40
+#define OP_LHZU 41
+#define OP_STH  44
+#define OP_STHU 45
+
 void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
 {
 	if (vcpu->arch.tcr & TCR_DIE) {
@@ -78,7 +111,7 @@ int kvmppc_emulate_instruction(struct kv
 	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
 
 	switch (get_op(inst)) {
-	case 3:                                             /* trap */
+	case OP_TRAP:
 		vcpu->arch.esr |= ESR_PTR;
 		kvmppc_core_queue_program(vcpu);
 		advance = 0;
@@ -87,31 +120,31 @@ int kvmppc_emulate_instruction(struct kv
 	case 31:
 		switch (get_xop(inst)) {
 
-		case 23:                                        /* lwzx */
+		case OP_31_XOP_LWZX:
 			rt = get_rt(inst);
 			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
 			break;
 
-		case 87:                                        /* lbzx */
+		case OP_31_XOP_LBZX:
 			rt = get_rt(inst);
 			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
 			break;
 
-		case 151:                                       /* stwx */
+		case OP_31_XOP_STWX:
 			rs = get_rs(inst);
 			emulated = kvmppc_handle_store(run, vcpu,
 			                               vcpu->arch.gpr[rs],
 			                               4, 1);
 			break;
 
-		case 215:                                       /* stbx */
+		case OP_31_XOP_STBX:
 			rs = get_rs(inst);
 			emulated = kvmppc_handle_store(run, vcpu,
 			                               vcpu->arch.gpr[rs],
 			                               1, 1);
 			break;
 
-		case 247:                                       /* stbux */
+		case OP_31_XOP_STBUX:
 			rs = get_rs(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -126,12 +159,12 @@ int kvmppc_emulate_instruction(struct kv
 			vcpu->arch.gpr[rs] = ea;
 			break;
 
-		case 279:                                       /* lhzx */
+		case OP_31_XOP_LHZX:
 			rt = get_rt(inst);
 			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
 			break;
 
-		case 311:                                       /* lhzux */
+		case OP_31_XOP_LHZUX:
 			rt = get_rt(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -144,7 +177,7 @@ int kvmppc_emulate_instruction(struct kv
 			vcpu->arch.gpr[ra] = ea;
 			break;
 
-		case 339:                                       /* mfspr */
+		case OP_31_XOP_MFSPR:
 			sprn = get_sprn(inst);
 			rt = get_rt(inst);
 
@@ -185,7 +218,7 @@ int kvmppc_emulate_instruction(struct kv
 			}
 			break;
 
-		case 407:                                       /* sthx */
+		case OP_31_XOP_STHX:
 			rs = get_rs(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -195,7 +228,7 @@ int kvmppc_emulate_instruction(struct kv
 			                               2, 1);
 			break;
 
-		case 439:                                       /* sthux */
+		case OP_31_XOP_STHUX:
 			rs = get_rs(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -210,7 +243,7 @@ int kvmppc_emulate_instruction(struct kv
 			vcpu->arch.gpr[ra] = ea;
 			break;
 
-		case 467:                                       /* mtspr */
+		case OP_31_XOP_MTSPR:
 			sprn = get_sprn(inst);
 			rs = get_rs(inst);
 			switch (sprn) {
@@ -246,7 +279,7 @@ int kvmppc_emulate_instruction(struct kv
 			}
 			break;
 
-		case 470:                                       /* dcbi */
+		case OP_31_XOP_DCBI:
 			/* Do nothing. The guest is performing dcbi because
 			 * hardware DMA is not snooped by the dcache, but
 			 * emulated DMA either goes through the dcache as
@@ -254,15 +287,15 @@ int kvmppc_emulate_instruction(struct kv
 			 * coherence. */
 			break;
 
-		case 534:                                       /* lwbrx */
+		case OP_31_XOP_LWBRX:
 			rt = get_rt(inst);
 			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
 			break;
 
-		case 566:                                       /* tlbsync */
+		case OP_31_XOP_TLBSYNC:
 			break;
 
-		case 662:                                       /* stwbrx */
+		case OP_31_XOP_STWBRX:
 			rs = get_rs(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -272,12 +305,12 @@ int kvmppc_emulate_instruction(struct kv
 			                               4, 0);
 			break;
 
-		case 790:                                       /* lhbrx */
+		case OP_31_XOP_LHBRX:
 			rt = get_rt(inst);
 			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
 			break;
 
-		case 918:                                       /* sthbrx */
+		case OP_31_XOP_STHBRX:
 			rs = get_rs(inst);
 			ra = get_ra(inst);
 			rb = get_rb(inst);
@@ -293,37 +326,37 @@ int kvmppc_emulate_instruction(struct kv
 		}
 		break;
 
-	case 32:                                                /* lwz */
+	case OP_LWZ:
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
 		break;
 
-	case 33:                                                /* lwzu */
+	case OP_LWZU:
 		ra = get_ra(inst);
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
 		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
 		break;
 
-	case 34:                                                /* lbz */
+	case OP_LBZ:
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
 		break;
 
-	case 35:                                                /* lbzu */
+	case OP_LBZU:
 		ra = get_ra(inst);
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
 		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
 		break;
 
-	case 36:                                                /* stw */
+	case OP_STW:
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
 		                               4, 1);
 		break;
 
-	case 37:                                                /* stwu */
+	case OP_STWU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
@@ -331,13 +364,13 @@ int kvmppc_emulate_instruction(struct kv
 		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
 		break;
 
-	case 38:                                                /* stb */
+	case OP_STB:
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
 		                               1, 1);
 		break;
 
-	case 39:                                                /* stbu */
+	case OP_STBU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
@@ -345,25 +378,25 @@ int kvmppc_emulate_instruction(struct kv
 		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
 		break;
 
-	case 40:                                                /* lhz */
+	case OP_LHZ:
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
 		break;
 
-	case 41:                                                /* lhzu */
+	case OP_LHZU:
 		ra = get_ra(inst);
 		rt = get_rt(inst);
 		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
 		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
 		break;
 
-	case 44:                                                /* sth */
+	case OP_STH:
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
 		                               2, 1);
 		break;
 
-	case 45:                                                /* sthu */
+	case OP_STHU:
 		ra = get_ra(inst);
 		rs = get_rs(inst);
 		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/kvm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,9 @@
 # KVM configuration
 #
 
+config HAVE_KVM_IRQCHIP
+       bool
+
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
 	---help---
@@ -43,6 +46,19 @@ config KVM_EXIT_TIMING
 
 	  If unsure, say N.
 
+config KVM_E500
+	bool "KVM support for PowerPC E500 processors"
+	depends on EXPERIMENTAL && E500
+	select KVM
+	---help---
+	  Support running unmodified E500 guest kernels in virtual machines on
+	  E500 host processors.
+
+	  This module provides access to the hardware capabilities through
+	  a character device node named /dev/kvm.
+
+	  If unsure, say N.
+
 config KVM_TRACE
 	bool "KVM trace support"
 	depends on KVM && MARKERS && SYSFS
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/kvm/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -16,8 +16,18 @@ AFLAGS_booke_interrupts.o := -I$(obj)
 
 kvm-440-objs := \
 	booke.o \
+	booke_emulate.o \
 	booke_interrupts.o \
 	44x.o \
 	44x_tlb.o \
 	44x_emulate.o
 obj-$(CONFIG_KVM_440) += kvm-440.o
+
+kvm-e500-objs := \
+	booke.o \
+	booke_emulate.o \
+	booke_interrupts.o \
+	e500.o \
+	e500_tlb.o \
+	e500_emulate.o
+obj-$(CONFIG_KVM_E500) += kvm-e500.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/kvm/powerpc.c linux-libre-2.6.30-gnu1/arch/powerpc/kvm/powerpc.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/kvm/powerpc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/kvm/powerpc.c	2009-06-09 23:05:27.000000000 -0400
@@ -216,46 +216,23 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 
 void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
-	kvmppc_core_destroy_mmu(vcpu);
+	kvmppc_mmu_destroy(vcpu);
 }
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
-	if (vcpu->guest_debug.enabled)
-		kvmppc_core_load_guest_debugstate(vcpu);
-
 	kvmppc_core_vcpu_load(vcpu, cpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
-	if (vcpu->guest_debug.enabled)
-		kvmppc_core_load_host_debugstate(vcpu);
-
-	/* Don't leave guest TLB entries resident when being de-scheduled. */
-	/* XXX It would be nice to differentiate between heavyweight exit and
-	 * sched_out here, since we could avoid the TLB flush for heavyweight
-	 * exits. */
-	_tlbil_all();
 	kvmppc_core_vcpu_put(vcpu);
 }
 
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
-                                    struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+                                        struct kvm_guest_debug *dbg)
 {
-	int i;
-
-	vcpu->guest_debug.enabled = dbg->enabled;
-	if (vcpu->guest_debug.enabled) {
-		for (i=0; i < ARRAY_SIZE(vcpu->guest_debug.bp); i++) {
-			if (dbg->breakpoints[i].enabled)
-				vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
-			else
-				vcpu->guest_debug.bp[i] = 0;
-		}
-	}
-
-	return 0;
+	return -EINVAL;
 }
 
 static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/lib/dma-noncoherent.c linux-libre-2.6.30-gnu1/arch/powerpc/lib/dma-noncoherent.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/lib/dma-noncoherent.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/lib/dma-noncoherent.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,426 +0,0 @@
-/*
- *  PowerPC version derived from arch/arm/mm/consistent.c
- *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
- *
- *  Copyright (C) 2000 Russell King
- *
- * Consistent memory allocators.  Used for DMA devices that want to
- * share uncached memory with the processor core.  The function return
- * is the virtual address and 'dma_handle' is the physical address.
- * Mostly stolen from the ARM port, with some changes for PowerPC.
- *						-- Dan
- *
- * Reorganized to get rid of the arch-specific consistent_* functions
- * and provide non-coherent implementations for the DMA API. -Matt
- *
- * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent()
- * implementation. This is pulled straight from ARM and barely
- * modified. -Matt
- *
- * This program is free software; you can 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/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/highmem.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/tlbflush.h>
-
-/*
- * This address range defaults to a value that is safe for all
- * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It
- * can be further configured for specific applications under
- * the "Advanced Setup" menu. -Matt
- */
-#define CONSISTENT_BASE	(CONFIG_CONSISTENT_START)
-#define CONSISTENT_END	(CONFIG_CONSISTENT_START + CONFIG_CONSISTENT_SIZE)
-#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
-
-/*
- * This is the page table (2MB) covering uncached, DMA consistent allocations
- */
-static pte_t *consistent_pte;
-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().
- */
-struct ppc_vm_region {
-	struct list_head	vm_list;
-	unsigned long		vm_start;
-	unsigned long		vm_end;
-};
-
-static struct ppc_vm_region consistent_head = {
-	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
-	.vm_start	= CONSISTENT_BASE,
-	.vm_end		= CONSISTENT_END,
-};
-
-static struct ppc_vm_region *
-ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp)
-{
-	unsigned long addr = head->vm_start, end = head->vm_end - size;
-	unsigned long flags;
-	struct ppc_vm_region *c, *new;
-
-	new = kmalloc(sizeof(struct ppc_vm_region), gfp);
-	if (!new)
-		goto out;
-
-	spin_lock_irqsave(&consistent_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;
-
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	return new;
-
- nospc:
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	kfree(new);
- out:
-	return NULL;
-}
-
-static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr)
-{
-	struct ppc_vm_region *c;
-
-	list_for_each_entry(c, &head->vm_list, vm_list) {
-		if (c->vm_start == addr)
-			goto out;
-	}
-	c = NULL;
- out:
-	return c;
-}
-
-/*
- * Allocate DMA-coherent memory space and return both the kernel remapped
- * virtual and bus address for that space.
- */
-void *
-__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
-{
-	struct page *page;
-	struct ppc_vm_region *c;
-	unsigned long order;
-	u64 mask = 0x00ffffff, limit; /* ISA default */
-
-	if (!consistent_pte) {
-		printk(KERN_ERR "%s: not initialised\n", __func__);
-		dump_stack();
-		return NULL;
-	}
-
-	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 %#Lx)\n",
-		       size, mask);
-		return NULL;
-	}
-
-	order = get_order(size);
-
-	if (mask != 0xffffffff)
-		gfp |= GFP_DMA;
-
-	page = alloc_pages(gfp, order);
-	if (!page)
-		goto no_page;
-
-	/*
-	 * Invalidate any data that might be lurking in the
-	 * kernel direct-mapped region for device DMA.
-	 */
-	{
-		unsigned long kaddr = (unsigned long)page_address(page);
-		memset(page_address(page), 0, size);
-		flush_dcache_range(kaddr, kaddr + size);
-	}
-
-	/*
-	 * Allocate a virtual address in the consistent mapping region.
-	 */
-	c = ppc_vm_region_alloc(&consistent_head, size,
-			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
-	if (c) {
-		unsigned long vaddr = c->vm_start;
-		pte_t *pte = consistent_pte + CONSISTENT_OFFSET(vaddr);
-		struct page *end = page + (1 << order);
-
-		split_page(page, order);
-
-		/*
-		 * Set the "dma handle"
-		 */
-		*handle = page_to_phys(page);
-
-		do {
-			BUG_ON(!pte_none(*pte));
-
-			SetPageReserved(page);
-			set_pte_at(&init_mm, vaddr,
-				   pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL)));
-			page++;
-			pte++;
-			vaddr += PAGE_SIZE;
-		} 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:
-	return NULL;
-}
-EXPORT_SYMBOL(__dma_alloc_coherent);
-
-/*
- * free a page as defined by the above mapping.
- */
-void __dma_free_coherent(size_t size, void *vaddr)
-{
-	struct ppc_vm_region *c;
-	unsigned long flags, addr;
-	pte_t *ptep;
-
-	size = PAGE_ALIGN(size);
-
-	spin_lock_irqsave(&consistent_lock, flags);
-
-	c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr);
-	if (!c)
-		goto no_area;
-
-	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;
-	}
-
-	ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
-	addr = c->vm_start;
-	do {
-		pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
-		unsigned long pfn;
-
-		ptep++;
-		addr += PAGE_SIZE;
-
-		if (!pte_none(pte) && pte_present(pte)) {
-			pfn = pte_pfn(pte);
-
-			if (pfn_valid(pfn)) {
-				struct page *page = pfn_to_page(pfn);
-				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);
-
-	list_del(&c->vm_list);
-
-	spin_unlock_irqrestore(&consistent_lock, flags);
-
-	kfree(c);
-	return;
-
- no_area:
-	spin_unlock_irqrestore(&consistent_lock, flags);
-	printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
-	       __func__, vaddr);
-	dump_stack();
-}
-EXPORT_SYMBOL(__dma_free_coherent);
-
-/*
- * Initialise the consistent memory allocation.
- */
-static int __init dma_alloc_init(void)
-{
-	pgd_t *pgd;
-	pud_t *pud;
-	pmd_t *pmd;
-	pte_t *pte;
-	int ret = 0;
-
-	do {
-		pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
-		pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE);
-		pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE);
-		if (!pmd) {
-			printk(KERN_ERR "%s: no pmd tables\n", __func__);
-			ret = -ENOMEM;
-			break;
-		}
-
-		pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
-		if (!pte) {
-			printk(KERN_ERR "%s: no pte tables\n", __func__);
-			ret = -ENOMEM;
-			break;
-		}
-
-		consistent_pte = pte;
-	} while (0);
-
-	return ret;
-}
-
-core_initcall(dma_alloc_init);
-
-/*
- * make an area consistent.
- */
-void __dma_sync(void *vaddr, size_t size, int direction)
-{
-	unsigned long start = (unsigned long)vaddr;
-	unsigned long end   = start + size;
-
-	switch (direction) {
-	case DMA_NONE:
-		BUG();
-	case DMA_FROM_DEVICE:
-		/*
-		 * invalidate only when cache-line aligned otherwise there is
-		 * the potential for discarding uncommitted data from the cache
-		 */
-		if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
-			flush_dcache_range(start, end);
-		else
-			invalidate_dcache_range(start, end);
-		break;
-	case DMA_TO_DEVICE:		/* writeback only */
-		clean_dcache_range(start, end);
-		break;
-	case DMA_BIDIRECTIONAL:	/* writeback and invalidate */
-		flush_dcache_range(start, end);
-		break;
-	}
-}
-EXPORT_SYMBOL(__dma_sync);
-
-#ifdef CONFIG_HIGHMEM
-/*
- * __dma_sync_page() implementation for systems using highmem.
- * In this case, each page of a buffer must be kmapped/kunmapped
- * in order to have a virtual address for __dma_sync(). This must
- * not sleep so kmap_atomic()/kunmap_atomic() are used.
- *
- * Note: yes, it is possible and correct to have a buffer extend
- * beyond the first page.
- */
-static inline void __dma_sync_page_highmem(struct page *page,
-		unsigned long offset, size_t size, int direction)
-{
-	size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
-	size_t cur_size = seg_size;
-	unsigned long flags, start, seg_offset = offset;
-	int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
-	int seg_nr = 0;
-
-	local_irq_save(flags);
-
-	do {
-		start = (unsigned long)kmap_atomic(page + seg_nr,
-				KM_PPC_SYNC_PAGE) + seg_offset;
-
-		/* Sync this buffer segment */
-		__dma_sync((void *)start, seg_size, direction);
-		kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE);
-		seg_nr++;
-
-		/* Calculate next buffer segment size */
-		seg_size = min((size_t)PAGE_SIZE, size - cur_size);
-
-		/* Add the segment size to our running total */
-		cur_size += seg_size;
-		seg_offset = 0;
-	} while (seg_nr < nr_segs);
-
-	local_irq_restore(flags);
-}
-#endif /* CONFIG_HIGHMEM */
-
-/*
- * __dma_sync_page makes memory consistent. identical to __dma_sync, but
- * takes a struct page instead of a virtual address
- */
-void __dma_sync_page(struct page *page, unsigned long offset,
-	size_t size, int direction)
-{
-#ifdef CONFIG_HIGHMEM
-	__dma_sync_page_highmem(page, offset, size, direction);
-#else
-	unsigned long start = (unsigned long)page_address(page) + offset;
-	__dma_sync((void *)start, size, direction);
-#endif
-}
-EXPORT_SYMBOL(__dma_sync_page);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/lib/feature-fixups.c linux-libre-2.6.30-gnu1/arch/powerpc/lib/feature-fixups.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/lib/feature-fixups.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/lib/feature-fixups.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,7 +85,7 @@ static int patch_feature_section(unsigne
 	}
 
 	for (; dest < end; dest++)
-		patch_instruction(dest, PPC_NOP_INSTR);
+		patch_instruction(dest, PPC_INST_NOP);
 
 	return 0;
 }
@@ -122,7 +122,7 @@ void do_lwsync_fixups(unsigned long valu
 
 	for (; start < end; start++) {
 		dest = (void *)start + *start;
-		patch_instruction(dest, PPC_LWSYNC_INSTR);
+		patch_instruction(dest, PPC_INST_LWSYNC);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/lib/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/lib/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/lib/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/lib/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,6 @@ obj-$(CONFIG_PPC64)	+= copypage_64.o cop
 			   memcpy_64.o usercopy_64.o mem_64.o string.o
 obj-$(CONFIG_XMON)	+= sstep.o
 obj-$(CONFIG_KPROBES)	+= sstep.o
-obj-$(CONFIG_NOT_COHERENT_CACHE)	+= dma-noncoherent.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -147,8 +147,8 @@ core-y				+= arch/powerpc/kernel/ \
 				   arch/powerpc/mm/ \
 				   arch/powerpc/lib/ \
 				   arch/powerpc/sysdev/ \
-				   arch/powerpc/platforms/
-core-$(CONFIG_MATH_EMULATION)	+= arch/powerpc/math-emu/
+				   arch/powerpc/platforms/ \
+				   arch/powerpc/math-emu/
 core-$(CONFIG_XMON)		+= arch/powerpc/xmon/
 core-$(CONFIG_KVM) 		+= arch/powerpc/kvm/
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/math-emu/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/math-emu/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/math-emu/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/math-emu/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,4 @@
 
-obj-y				:= math.o fmr.o lfd.o stfd.o
-
 obj-$(CONFIG_MATH_EMULATION)	+= fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
 					fctiw.o fctiwz.o fdiv.o fdivs.o \
 					fmadd.o fmadds.o fmsub.o fmsubs.o \
@@ -9,7 +7,8 @@ obj-$(CONFIG_MATH_EMULATION)	+= fabs.o f
 					fres.o frsp.o frsqrte.o fsel.o lfs.o \
 					fsqrt.o	fsqrts.o fsub.o fsubs.o \
 					mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
-					mtfsf.o mtfsfi.o stfiwx.o stfs.o
+					mtfsf.o mtfsfi.o stfiwx.o stfs.o \
+					math.o fmr.o lfd.o stfd.o
 
 obj-$(CONFIG_SPE)		+= math_efp.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/dma-noncoherent.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/dma-noncoherent.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/dma-noncoherent.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/dma-noncoherent.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,400 @@
+/*
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  The function return
+ * is the virtual address and 'dma_handle' is the physical address.
+ * Mostly stolen from the ARM port, with some changes for PowerPC.
+ *						-- Dan
+ *
+ * Reorganized to get rid of the arch-specific consistent_* functions
+ * and provide non-coherent implementations for the DMA API. -Matt
+ *
+ * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent()
+ * implementation. This is pulled straight from ARM and barely
+ * modified. -Matt
+ *
+ * This program is free software; you can 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/highmem.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/tlbflush.h>
+
+#include "mmu_decl.h"
+
+/*
+ * This address range defaults to a value that is safe for all
+ * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It
+ * can be further configured for specific applications under
+ * the "Advanced Setup" menu. -Matt
+ */
+#define CONSISTENT_BASE		(IOREMAP_TOP)
+#define CONSISTENT_END 		(CONSISTENT_BASE + CONFIG_CONSISTENT_SIZE)
+#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+
+/*
+ * This is the page table (2MB) covering uncached, DMA consistent allocations
+ */
+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().
+ */
+struct ppc_vm_region {
+	struct list_head	vm_list;
+	unsigned long		vm_start;
+	unsigned long		vm_end;
+};
+
+static struct ppc_vm_region consistent_head = {
+	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list),
+	.vm_start	= CONSISTENT_BASE,
+	.vm_end		= CONSISTENT_END,
+};
+
+static struct ppc_vm_region *
+ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp)
+{
+	unsigned long addr = head->vm_start, end = head->vm_end - size;
+	unsigned long flags;
+	struct ppc_vm_region *c, *new;
+
+	new = kmalloc(sizeof(struct ppc_vm_region), gfp);
+	if (!new)
+		goto out;
+
+	spin_lock_irqsave(&consistent_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;
+
+	spin_unlock_irqrestore(&consistent_lock, flags);
+	return new;
+
+ nospc:
+	spin_unlock_irqrestore(&consistent_lock, flags);
+	kfree(new);
+ out:
+	return NULL;
+}
+
+static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr)
+{
+	struct ppc_vm_region *c;
+
+	list_for_each_entry(c, &head->vm_list, vm_list) {
+		if (c->vm_start == addr)
+			goto out;
+	}
+	c = NULL;
+ out:
+	return c;
+}
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+	struct page *page;
+	struct ppc_vm_region *c;
+	unsigned long order;
+	u64 mask = ISA_DMA_THRESHOLD, limit;
+
+	if (dev) {
+		mask = dev->coherent_dma_mask;
+
+		/*
+		 * Sanity check the DMA mask - it must be non-zero, and
+		 * must be able to be satisfied by a DMA allocation.
+		 */
+		if (mask == 0) {
+			dev_warn(dev, "coherent DMA mask is unset\n");
+			goto no_page;
+		}
+
+		if ((~mask) & ISA_DMA_THRESHOLD) {
+			dev_warn(dev, "coherent DMA mask %#llx is smaller "
+				 "than system GFP_DMA mask %#llx\n",
+				 mask, (unsigned long long)ISA_DMA_THRESHOLD);
+			goto no_page;
+		}
+	}
+
+
+	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 %#Lx)\n",
+		       size, mask);
+		return NULL;
+	}
+
+	order = get_order(size);
+
+	/* Might be useful if we ever have a real legacy DMA zone... */
+	if (mask != 0xffffffff)
+		gfp |= GFP_DMA;
+
+	page = alloc_pages(gfp, order);
+	if (!page)
+		goto no_page;
+
+	/*
+	 * Invalidate any data that might be lurking in the
+	 * kernel direct-mapped region for device DMA.
+	 */
+	{
+		unsigned long kaddr = (unsigned long)page_address(page);
+		memset(page_address(page), 0, size);
+		flush_dcache_range(kaddr, kaddr + size);
+	}
+
+	/*
+	 * Allocate a virtual address in the consistent mapping region.
+	 */
+	c = ppc_vm_region_alloc(&consistent_head, size,
+			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
+	if (c) {
+		unsigned long vaddr = c->vm_start;
+		struct page *end = page + (1 << order);
+
+		split_page(page, order);
+
+		/*
+		 * Set the "dma handle"
+		 */
+		*handle = page_to_phys(page);
+
+		do {
+			SetPageReserved(page);
+			map_page(vaddr, page_to_phys(page),
+				 pgprot_noncached(PAGE_KERNEL));
+			page++;
+			vaddr += PAGE_SIZE;
+		} 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:
+	return NULL;
+}
+EXPORT_SYMBOL(__dma_alloc_coherent);
+
+/*
+ * free a page as defined by the above mapping.
+ */
+void __dma_free_coherent(size_t size, void *vaddr)
+{
+	struct ppc_vm_region *c;
+	unsigned long flags, addr;
+	
+	size = PAGE_ALIGN(size);
+
+	spin_lock_irqsave(&consistent_lock, flags);
+
+	c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr);
+	if (!c)
+		goto no_area;
+
+	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;
+	}
+
+	addr = c->vm_start;
+	do {
+		pte_t *ptep;
+		unsigned long pfn;
+
+		ptep = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(addr),
+							       addr),
+						    addr),
+					 addr);
+		if (!pte_none(*ptep) && pte_present(*ptep)) {
+			pfn = pte_pfn(*ptep);
+			pte_clear(&init_mm, addr, ptep);
+			if (pfn_valid(pfn)) {
+				struct page *page = pfn_to_page(pfn);
+
+				ClearPageReserved(page);
+				__free_page(page);
+			}
+		}
+		addr += PAGE_SIZE;
+	} while (size -= PAGE_SIZE);
+
+	flush_tlb_kernel_range(c->vm_start, c->vm_end);
+
+	list_del(&c->vm_list);
+
+	spin_unlock_irqrestore(&consistent_lock, flags);
+
+	kfree(c);
+	return;
+
+ no_area:
+	spin_unlock_irqrestore(&consistent_lock, flags);
+	printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+	       __func__, vaddr);
+	dump_stack();
+}
+EXPORT_SYMBOL(__dma_free_coherent);
+
+/*
+ * make an area consistent.
+ */
+void __dma_sync(void *vaddr, size_t size, int direction)
+{
+	unsigned long start = (unsigned long)vaddr;
+	unsigned long end   = start + size;
+
+	switch (direction) {
+	case DMA_NONE:
+		BUG();
+	case DMA_FROM_DEVICE:
+		/*
+		 * invalidate only when cache-line aligned otherwise there is
+		 * the potential for discarding uncommitted data from the cache
+		 */
+		if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
+			flush_dcache_range(start, end);
+		else
+			invalidate_dcache_range(start, end);
+		break;
+	case DMA_TO_DEVICE:		/* writeback only */
+		clean_dcache_range(start, end);
+		break;
+	case DMA_BIDIRECTIONAL:	/* writeback and invalidate */
+		flush_dcache_range(start, end);
+		break;
+	}
+}
+EXPORT_SYMBOL(__dma_sync);
+
+#ifdef CONFIG_HIGHMEM
+/*
+ * __dma_sync_page() implementation for systems using highmem.
+ * In this case, each page of a buffer must be kmapped/kunmapped
+ * in order to have a virtual address for __dma_sync(). This must
+ * not sleep so kmap_atomic()/kunmap_atomic() are used.
+ *
+ * Note: yes, it is possible and correct to have a buffer extend
+ * beyond the first page.
+ */
+static inline void __dma_sync_page_highmem(struct page *page,
+		unsigned long offset, size_t size, int direction)
+{
+	size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
+	size_t cur_size = seg_size;
+	unsigned long flags, start, seg_offset = offset;
+	int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
+	int seg_nr = 0;
+
+	local_irq_save(flags);
+
+	do {
+		start = (unsigned long)kmap_atomic(page + seg_nr,
+				KM_PPC_SYNC_PAGE) + seg_offset;
+
+		/* Sync this buffer segment */
+		__dma_sync((void *)start, seg_size, direction);
+		kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE);
+		seg_nr++;
+
+		/* Calculate next buffer segment size */
+		seg_size = min((size_t)PAGE_SIZE, size - cur_size);
+
+		/* Add the segment size to our running total */
+		cur_size += seg_size;
+		seg_offset = 0;
+	} while (seg_nr < nr_segs);
+
+	local_irq_restore(flags);
+}
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * __dma_sync_page makes memory consistent. identical to __dma_sync, but
+ * takes a struct page instead of a virtual address
+ */
+void __dma_sync_page(struct page *page, unsigned long offset,
+	size_t size, int direction)
+{
+#ifdef CONFIG_HIGHMEM
+	__dma_sync_page_highmem(page, offset, size, direction);
+#else
+	unsigned long start = (unsigned long)page_address(page) + offset;
+	__dma_sync((void *)start, size, direction);
+#endif
+}
+EXPORT_SYMBOL(__dma_sync_page);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/fault.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/fault.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/fault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/fault.c	2009-06-09 23:05:27.000000000 -0400
@@ -253,45 +253,33 @@ good_area:
 #endif /* CONFIG_8xx */
 
 	if (is_exec) {
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
-		/* protection fault */
+#ifdef CONFIG_PPC_STD_MMU
+		/* Protection fault on exec go straight to failure on
+		 * Hash based MMUs as they either don't support per-page
+		 * execute permission, or if they do, it's handled already
+		 * at the hash level. This test would probably have to
+		 * be removed if we change the way this works to make hash
+		 * processors use the same I/D cache coherency mechanism
+		 * as embedded.
+		 */
 		if (error_code & DSISR_PROTFAULT)
 			goto bad_area;
+#endif /* CONFIG_PPC_STD_MMU */
+
 		/*
 		 * Allow execution from readable areas if the MMU does not
 		 * provide separate controls over reading and executing.
+		 *
+		 * Note: That code used to not be enabled for 4xx/BookE.
+		 * It is now as I/D cache coherency for these is done at
+		 * set_pte_at() time and I see no reason why the test
+		 * below wouldn't be valid on those processors. This -may-
+		 * break programs compiled with a really old ABI though.
 		 */
 		if (!(vma->vm_flags & VM_EXEC) &&
 		    (cpu_has_feature(CPU_FTR_NOEXECUTE) ||
 		     !(vma->vm_flags & (VM_READ | VM_WRITE))))
 			goto bad_area;
-#else
-		pte_t *ptep;
-		pmd_t *pmdp;
-
-		/* Since 4xx/Book-E supports per-page execute permission,
-		 * we lazily flush dcache to icache. */
-		ptep = NULL;
-		if (get_pteptr(mm, address, &ptep, &pmdp)) {
-			spinlock_t *ptl = pte_lockptr(mm, pmdp);
-			spin_lock(ptl);
-			if (pte_present(*ptep)) {
-				struct page *page = pte_page(*ptep);
-
-				if (!test_bit(PG_arch_1, &page->flags)) {
-					flush_dcache_icache_page(page);
-					set_bit(PG_arch_1, &page->flags);
-				}
-				pte_update(ptep, 0, _PAGE_HWEXEC |
-					   _PAGE_ACCESSED);
-				local_flush_tlb_page(vma, address);
-				pte_unmap_unlock(ptep, ptl);
-				up_read(&mm->mmap_sem);
-				return 0;
-			}
-			pte_unmap_unlock(ptep, ptl);
-		}
-#endif
 	/* a write */
 	} else if (is_write) {
 		if (!(vma->vm_flags & VM_WRITE))
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/fsl_booke_mmu.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/fsl_booke_mmu.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,10 +56,14 @@
 
 extern void loadcam_entry(unsigned int index);
 unsigned int tlbcam_index;
-static unsigned long __cam0, __cam1, __cam2;
+static unsigned long cam[CONFIG_LOWMEM_CAM_NUM];
 
 #define NUM_TLBCAMS	(16)
 
+#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 tlbcamrange {
@@ -107,7 +111,7 @@ void settlbcam(int index, unsigned long
 	unsigned int tsize, lz;
 
 	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
-	tsize = (21 - lz) / 2;
+	tsize = 21 - lz;
 
 #ifdef CONFIG_SMP
 	if ((flags & _PAGE_NO_CACHE) == 0)
@@ -152,19 +156,19 @@ void invalidate_tlbcam_entry(int index)
 	loadcam_entry(index);
 }
 
-void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
-		unsigned long cam2)
+unsigned long __init mmu_mapin_ram(void)
 {
-	settlbcam(0, PAGE_OFFSET, memstart_addr, cam0, _PAGE_KERNEL, 0);
-	tlbcam_index++;
-	if (cam1) {
-		tlbcam_index++;
-		settlbcam(1, PAGE_OFFSET+cam0, memstart_addr+cam0, cam1, _PAGE_KERNEL, 0);
-	}
-	if (cam2) {
+	unsigned long virt = PAGE_OFFSET;
+	phys_addr_t phys = memstart_addr;
+
+	while (cam[tlbcam_index] && tlbcam_index < ARRAY_SIZE(cam)) {
+		settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], PAGE_KERNEL_X, 0);
+		virt += cam[tlbcam_index];
+		phys += cam[tlbcam_index];
 		tlbcam_index++;
-		settlbcam(2, PAGE_OFFSET+cam0+cam1, memstart_addr+cam0+cam1, cam2, _PAGE_KERNEL, 0);
 	}
+
+	return virt - PAGE_OFFSET;
 }
 
 /*
@@ -175,51 +179,46 @@ void __init MMU_init_hw(void)
 	flush_instruction_cache();
 }
 
-unsigned long __init mmu_mapin_ram(void)
-{
-	cam_mapin_ram(__cam0, __cam1, __cam2);
-
-	return __cam0 + __cam1 + __cam2;
-}
-
-
 void __init
 adjust_total_lowmem(void)
 {
-	phys_addr_t max_lowmem_size = __max_low_memory;
-	phys_addr_t cam_max_size = 0x10000000;
 	phys_addr_t ram;
+	unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff;
+	char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
+	int i;
+	unsigned long virt = PAGE_OFFSET & 0xffffffffUL;
+	unsigned long phys = memstart_addr & 0xffffffffUL;
 
-	/* adjust CAM size to max_lowmem_size */
-	if (max_lowmem_size < cam_max_size)
-		cam_max_size = max_lowmem_size;
+	/* Convert (4^max) kB to (2^max) bytes */
+	max_cam = max_cam * 2 + 10;
 
-	/* adjust lowmem size to max_lowmem_size */
-	ram = min(max_lowmem_size, total_lowmem);
+	/* adjust lowmem size to __max_low_memory */
+	ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
 
 	/* Calculate CAM values */
-	__cam0 = 1UL << 2 * (__ilog2(ram) / 2);
-	if (__cam0 > cam_max_size)
-		__cam0 = cam_max_size;
-	ram -= __cam0;
-	if (ram) {
-		__cam1 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam1 > cam_max_size)
-			__cam1 = cam_max_size;
-		ram -= __cam1;
-	}
-	if (ram) {
-		__cam2 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam2 > cam_max_size)
-			__cam2 = cam_max_size;
-		ram -= __cam2;
+	__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';
 
-	printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
-			" CAM2=%ldMb residual: %ldMb\n",
-			__cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
-			(long int)((total_lowmem - __cam0 - __cam1 - __cam2)
-				   >> 20));
-	__max_low_memory = __cam0 + __cam1 + __cam2;
+	pr_info("Memory CAM mapping: %s Mb, residual: %dMb\n", buf,
+	        (unsigned int)((total_lowmem - __max_low_memory) >> 20));
 	__initial_memory_limit_addr = memstart_addr + __max_low_memory;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/gup.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/gup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/gup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/gup.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,8 @@
 #include <linux/rwsem.h>
 #include <asm/pgtable.h>
 
+#ifdef __HAVE_ARCH_PTE_SPECIAL
+
 /*
  * The performance critical leaf functions are made noinline otherwise gcc
  * inlines everything into a single function which results in too much
@@ -151,8 +153,11 @@ int get_user_pages_fast(unsigned long st
 	unsigned long addr, len, end;
 	unsigned long next;
 	pgd_t *pgdp;
-	int psize, nr = 0;
+	int nr = 0;
+#ifdef CONFIG_PPC64
 	unsigned int shift;
+	int psize;
+#endif
 
 	pr_debug("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
 
@@ -205,8 +210,13 @@ 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])) {
@@ -236,7 +246,9 @@ int get_user_pages_fast(unsigned long st
 		do {
 			pgd_t pgd = *pgdp;
 
+#ifdef CONFIG_PPC64
 			VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
+#endif
 			pr_debug("  %016lx: normal pgd %p\n", addr,
 				 (void *)pgd_val(pgd));
 			next = pgd_addr_end(addr, end);
@@ -279,3 +291,5 @@ slow_irqon:
 		return ret;
 	}
 }
+
+#endif /* __HAVE_ARCH_PTE_SPECIAL */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/hash_utils_64.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/hash_utils_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/hash_utils_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/hash_utils_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -516,7 +516,7 @@ static int __init htab_dt_scan_pftsize(u
 
 static unsigned long __init htab_get_table_size(void)
 {
-	unsigned long mem_size, rnd_mem_size, pteg_count;
+	unsigned long mem_size, rnd_mem_size, pteg_count, psize;
 
 	/* If hash size isn't already provided by the platform, we try to
 	 * retrieve it from the device-tree. If it's not there neither, we
@@ -534,7 +534,8 @@ static unsigned long __init htab_get_tab
 		rnd_mem_size <<= 1;
 
 	/* # pages / 2 */
-	pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
+	psize = mmu_psize_defs[mmu_virtual_psize].shift;
+	pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11);
 
 	return pteg_count << 7;
 }
@@ -589,7 +590,7 @@ static void __init htab_finish_init(void
 	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
 }
 
-void __init htab_initialize(void)
+static void __init htab_initialize(void)
 {
 	unsigned long table;
 	unsigned long pteg_count;
@@ -731,11 +732,43 @@ void __init htab_initialize(void)
 #undef KB
 #undef MB
 
-void htab_initialize_secondary(void)
+void __init early_init_mmu(void)
 {
+	/* Setup initial STAB address in the PACA */
+	get_paca()->stab_real = __pa((u64)&initial_stab);
+	get_paca()->stab_addr = (u64)&initial_stab;
+
+	/* Initialize the MMU Hash table and create the linear mapping
+	 * of memory. Has to be done before stab/slb initialization as
+	 * this is currently where the page size encoding is obtained
+	 */
+	htab_initialize();
+
+	/* Initialize stab / SLB management except on iSeries
+	 */
+	if (cpu_has_feature(CPU_FTR_SLB))
+		slb_initialize();
+	else if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		stab_initialize(get_paca()->stab_real);
+}
+
+#ifdef CONFIG_SMP
+void __cpuinit early_init_mmu_secondary(void)
+{
+	/* Initialize hash table for that CPU */
 	if (!firmware_has_feature(FW_FEATURE_LPAR))
 		mtspr(SPRN_SDR1, _SDR1);
+
+	/* Initialize STAB/SLB. We use a virtual address as it works
+	 * in real mode on pSeries and we want a virutal address on
+	 * iSeries anyway
+	 */
+	if (cpu_has_feature(CPU_FTR_SLB))
+		slb_initialize();
+	else
+		stab_initialize(get_paca()->stab_addr);
 }
+#endif /* CONFIG_SMP */
 
 /*
  * Called by asm hashtable.S for doing lazy icache flush
@@ -858,7 +891,7 @@ int hash_page(unsigned long ea, unsigned
 	unsigned long vsid;
 	struct mm_struct *mm;
 	pte_t *ptep;
-	cpumask_t tmp;
+	const struct cpumask *tmp;
 	int rc, user_region = 0, local = 0;
 	int psize, ssize;
 
@@ -906,8 +939,8 @@ int hash_page(unsigned long ea, unsigned
 		return 1;
 
 	/* Check CPU locality */
-	tmp = cpumask_of_cpu(smp_processor_id());
-	if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+	tmp = cpumask_of(smp_processor_id());
+	if (user_region && cpumask_equal(mm_cpumask(mm), tmp))
 		local = 1;
 
 #ifdef CONFIG_HUGETLB_PAGE
@@ -1023,7 +1056,6 @@ void hash_preload(struct mm_struct *mm,
 	unsigned long vsid;
 	void *pgdir;
 	pte_t *ptep;
-	cpumask_t mask;
 	unsigned long flags;
 	int local = 0;
 	int ssize;
@@ -1066,8 +1098,7 @@ void hash_preload(struct mm_struct *mm,
 	local_irq_save(flags);
 
 	/* Is that local to this CPU ? */
-	mask = cpumask_of_cpu(smp_processor_id());
-	if (cpus_equal(mm->cpu_vm_mask, mask))
+	if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
 		local = 1;
 
 	/* Hash it in */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/init_32.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/init_32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/init_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/init_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,12 +168,8 @@ void __init MMU_init(void)
 		ppc_md.progress("MMU:mapin", 0x301);
 	mapin_ram();
 
-#ifdef CONFIG_HIGHMEM
-	ioremap_base = PKMAP_BASE;
-#else
-	ioremap_base = 0xfe000000UL;	/* for now, could be 0xfffff000 */
-#endif /* CONFIG_HIGHMEM */
-	ioremap_bot = ioremap_base;
+	/* Initialize early top-down ioremap allocator */
+	ioremap_bot = IOREMAP_TOP;
 
 	/* Map in I/O resources */
 	if (ppc_md.progress)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/mm/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@ ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS	+= -mno-minimal-toc
 endif
 
-obj-y				:= fault.o mem.o pgtable.o \
+obj-y				:= fault.o mem.o pgtable.o gup.o \
 				   init_$(CONFIG_WORD_SIZE).o \
 				   pgtable_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_context_nohash.o tlb_nohash.o \
@@ -14,7 +14,7 @@ obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_cont
 hash-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 obj-$(CONFIG_PPC64)		+= hash_utils_64.o \
 				   slb_low.o slb.o stab.o \
-				   gup.o mmap.o $(hash-y)
+				   mmap_64.o $(hash-y)
 obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o
 obj-$(CONFIG_PPC_STD_MMU)	+= hash_low_$(CONFIG_WORD_SIZE).o \
 				   tlb_hash$(CONFIG_WORD_SIZE).o \
@@ -26,3 +26,4 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += num
 obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PPC_SUBPAGE_PROT)	+= subpage-prot.o
+obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/mem.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/mem.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/mem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/mem.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@
 
 int init_bootmem_done;
 int mem_init_done;
-unsigned long memory_limit;
+phys_addr_t memory_limit;
 
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
@@ -380,6 +380,23 @@ void __init mem_init(void)
 		bsssize >> 10,
 		initsize >> 10);
 
+#ifdef CONFIG_PPC32
+	pr_info("Kernel virtual memory layout:\n");
+	pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
+#ifdef CONFIG_HIGHMEM
+	pr_info("  * 0x%08lx..0x%08lx  : highmem PTEs\n",
+		PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
+#endif /* CONFIG_HIGHMEM */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+	pr_info("  * 0x%08lx..0x%08lx  : consistent mem\n",
+		IOREMAP_TOP, IOREMAP_TOP + CONFIG_CONSISTENT_SIZE);
+#endif /* CONFIG_NOT_COHERENT_CACHE */
+	pr_info("  * 0x%08lx..0x%08lx  : early ioremap\n",
+		ioremap_bot, IOREMAP_TOP);
+	pr_info("  * 0x%08lx..0x%08lx  : vmalloc & ioremap\n",
+		VMALLOC_START, VMALLOC_END);
+#endif /* CONFIG_PPC32 */
+
 	mem_init_done = 1;
 }
 
@@ -472,40 +489,7 @@ void update_mmu_cache(struct vm_area_str
 {
 #ifdef CONFIG_PPC_STD_MMU
 	unsigned long access = 0, trap;
-#endif
-	unsigned long pfn = pte_pfn(pte);
-
-	/* handle i-cache coherency */
-	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
-	    !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
-	    pfn_valid(pfn)) {
-		struct page *page = pfn_to_page(pfn);
-#ifdef CONFIG_8xx
-		/* On 8xx, cache control instructions (particularly
-		 * "dcbst" from flush_dcache_icache) fault as write
-		 * operation if there is an unpopulated TLB entry
-		 * for the address in question. To workaround that,
-		 * we invalidate the TLB here, thus avoiding dcbst
-		 * misbehaviour.
-		 */
-		_tlbil_va(address, 0 /* 8xx doesn't care about PID */);
-#endif
-		/* The _PAGE_USER test should really be _PAGE_EXEC, but
-		 * older glibc versions execute some code from no-exec
-		 * pages, which for now we are supporting.  If exec-only
-		 * pages are ever implemented, this will have to change.
-		 */
-		if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER)
-		    && !test_bit(PG_arch_1, &page->flags)) {
-			if (vma->vm_mm == current->active_mm) {
-				__flush_dcache_icache((void *) address);
-			} else
-				flush_dcache_icache_page(page);
-			set_bit(PG_arch_1, &page->flags);
-		}
-	}
 
-#ifdef CONFIG_PPC_STD_MMU
 	/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
 	if (!pte_young(pte) || address >= TASK_SIZE)
 		return;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmap_64.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmap_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmap_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmap_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,109 @@
+/*
+ *  flexible mmap layout support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Started by Ingo Molnar <mingo@elte.hu>
+ */
+
+#include <linux/personality.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave at least a ~128 MB hole on 32bit applications.
+ *
+ * On 64bit applications we randomise the stack by 1GB so we need to
+ * space our mmap start address by a further 1GB, otherwise there is a
+ * chance the mmap area will end up closer to the stack than our ulimit
+ * requires.
+ */
+#define MIN_GAP32 (128*1024*1024)
+#define MIN_GAP64 ((128 + 1024)*1024*1024UL)
+#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline int mmap_is_legacy(void)
+{
+	if (current->personality & ADDR_COMPAT_LAYOUT)
+		return 1;
+
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+		return 1;
+
+	return sysctl_legacy_va_layout;
+}
+
+/*
+ * Since get_random_int() returns the same value within a 1 jiffy window,
+ * we will almost always get the same randomisation for the stack and mmap
+ * region. This will mean the relative distance between stack and mmap will
+ * be the same.
+ *
+ * To avoid this we can shift the randomness by 1 bit.
+ */
+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	if (current->flags & PF_RANDOMIZE) {
+		/* 8MB for 32bit, 1GB for 64bit */
+		if (is_32bit_task())
+			rnd = (long)(get_random_int() % (1<<(22-PAGE_SHIFT)));
+		else
+			rnd = (long)(get_random_int() % (1<<(29-PAGE_SHIFT)));
+	}
+	return (rnd << PAGE_SHIFT) * 2;
+}
+
+static inline unsigned long mmap_base(void)
+{
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	/*
+	 * Fall back to the standard layout if the personality
+	 * bit is set, or if the expected stack growth is unlimited:
+	 */
+	if (mmap_is_legacy()) {
+		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+		mm->unmap_area = arch_unmap_area;
+	} else {
+		mm->mmap_base = mmap_base();
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		mm->unmap_area = arch_unmap_area_topdown;
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmap.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmap.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmap.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- *  flexible mmap layout support
- *
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *
- * Started by Ingo Molnar <mingo@elte.hu>
- */
-
-#include <linux/personality.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-
-/*
- * Top of mmap area (just below the process stack).
- *
- * Leave an at least ~128 MB hole.
- */
-#define MIN_GAP (128*1024*1024)
-#define MAX_GAP (TASK_SIZE/6*5)
-
-static inline unsigned long mmap_base(void)
-{
-	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return TASK_SIZE - (gap & PAGE_MASK);
-}
-
-static inline int mmap_is_legacy(void)
-{
-	/*
-	 * Force standard allocation for 64 bit programs.
-	 */
-	if (!test_thread_flag(TIF_32BIT))
-		return 1;
-
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-/*
- * This function, called very early during the creation of a new
- * process VM image, sets up which VM layout function to use:
- */
-void arch_pick_mmap_layout(struct mm_struct *mm)
-{
-	/*
-	 * Fall back to the standard layout if the personality
-	 * bit is set, or if the expected stack growth is unlimited:
-	 */
-	if (mmap_is_legacy()) {
-		mm->mmap_base = TASK_UNMAPPED_BASE;
-		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
-	} else {
-		mm->mmap_base = mmap_base();
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmu_context_nohash.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmu_context_nohash.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/mmu_context_nohash.c	2009-06-09 23:05:27.000000000 -0400
@@ -97,7 +97,7 @@ static unsigned int steal_context_smp(un
 		mm->context.id = MMU_NO_CONTEXT;
 
 		/* Mark it stale on all CPUs that used this mm */
-		for_each_cpu_mask_nr(cpu, mm->cpu_vm_mask)
+		for_each_cpu(cpu, mm_cpumask(mm))
 			__set_bit(id, stale_map[cpu]);
 		return id;
 	}
@@ -127,12 +127,12 @@ static unsigned int steal_context_up(uns
 
 	pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm);
 
-	/* Mark this mm has having no context anymore */
-	mm->context.id = MMU_NO_CONTEXT;
-
 	/* Flush the TLB for that context */
 	local_flush_tlb_mm(mm);
 
+	/* Mark this mm has having no context anymore */
+	mm->context.id = MMU_NO_CONTEXT;
+
 	/* XXX This clear should ultimately be part of local_flush_tlb_mm */
 	__clear_bit(id, stale_map[cpu]);
 
@@ -380,7 +380,7 @@ void __init mmu_context_init(void)
 #endif
 
 	printk(KERN_INFO
-	       "MMU: Allocated %d bytes of context maps for %d contexts\n",
+	       "MMU: Allocated %zu bytes of context maps for %d contexts\n",
 	       2 * CTX_MAP_SIZE + (sizeof(void *) * (last_context + 1)),
 	       last_context - first_context + 1);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/numa.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/numa.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/numa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/numa.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,35 +158,6 @@ static void unmap_cpu_from_node(unsigned
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
-{
-	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
-	struct device_node *cpu_node = NULL;
-	const unsigned int *interrupt_server, *reg;
-	int len;
-
-	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
-		/* Try interrupt server first */
-		interrupt_server = of_get_property(cpu_node,
-					"ibm,ppc-interrupt-server#s", &len);
-
-		len = len / sizeof(u32);
-
-		if (interrupt_server && (len > 0)) {
-			while (len--) {
-				if (interrupt_server[len] == hw_cpuid)
-					return cpu_node;
-			}
-		} else {
-			reg = of_get_property(cpu_node, "reg", &len);
-			if (reg && (len > 0) && (reg[0] == hw_cpuid))
-				return cpu_node;
-		}
-	}
-
-	return NULL;
-}
-
 /* must hold reference to node during call */
 static const int *of_get_associativity(struct device_node *dev)
 {
@@ -290,7 +261,7 @@ static int __init find_min_common_depth(
 	ref_points = of_get_property(rtas_root,
 			"ibm,associativity-reference-points", &len);
 
-	if ((len >= 1) && ref_points) {
+	if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
 		depth = ref_points[1];
 	} else {
 		dbg("NUMA: ibm,associativity-reference-points not found.\n");
@@ -470,7 +441,7 @@ static int of_drconf_to_nid_single(struc
 static int __cpuinit numa_setup_cpu(unsigned long lcpu)
 {
 	int nid = 0;
-	struct device_node *cpu = find_cpu_node(lcpu);
+	struct device_node *cpu = of_get_cpu_node(lcpu, NULL);
 
 	if (!cpu) {
 		WARN_ON(1);
@@ -652,7 +623,7 @@ static int __init parse_numa_properties(
 	for_each_present_cpu(i) {
 		int nid;
 
-		cpu = find_cpu_node(i);
+		cpu = of_get_cpu_node(i, NULL);
 		BUG_ON(!cpu);
 		nid = of_node_to_nid_single(cpu);
 		of_node_put(cpu);
@@ -1041,57 +1012,32 @@ early_param("numa", early_numa);
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
- * Validate the node associated with the memory section we are
- * trying to add.
- */
-int valid_hot_add_scn(int *nid, unsigned long start, u32 lmb_size,
-		      unsigned long scn_addr)
-{
-	nodemask_t nodes;
-
-	if (*nid < 0 || !node_online(*nid))
-		*nid = any_online_node(NODE_MASK_ALL);
-
-	if ((scn_addr >= start) && (scn_addr < (start + lmb_size))) {
-		nodes_setall(nodes);
-		while (NODE_DATA(*nid)->node_spanned_pages == 0) {
-			node_clear(*nid, nodes);
-			*nid = any_online_node(nodes);
-		}
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * Find the node associated with a hot added memory section represented
- * by the ibm,dynamic-reconfiguration-memory node.
+ * Find the node associated with a hot added memory section for
+ * memory represented in the device tree by the property
+ * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory.
  */
 static int hot_add_drconf_scn_to_nid(struct device_node *memory,
 				     unsigned long scn_addr)
 {
 	const u32 *dm;
-	unsigned int n, rc;
+	unsigned int drconf_cell_cnt, rc;
 	unsigned long lmb_size;
-	int default_nid = any_online_node(NODE_MASK_ALL);
-	int nid;
 	struct assoc_arrays aa;
+	int nid = -1;
 
-	n = of_get_drconf_memory(memory, &dm);
-	if (!n)
-		return default_nid;;
+	drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
+	if (!drconf_cell_cnt)
+		return -1;
 
 	lmb_size = of_get_lmb_size(memory);
 	if (!lmb_size)
-		return default_nid;
+		return -1;
 
 	rc = of_get_assoc_arrays(memory, &aa);
 	if (rc)
-		return default_nid;
+		return -1;
 
-	for (; n != 0; --n) {
+	for (; drconf_cell_cnt != 0; --drconf_cell_cnt) {
 		struct of_drconf_cell drmem;
 
 		read_drconf_cell(&drmem, &dm);
@@ -1102,15 +1048,57 @@ static int hot_add_drconf_scn_to_nid(str
 		    || !(drmem.flags & DRCONF_MEM_ASSIGNED))
 			continue;
 
+		if ((scn_addr < drmem.base_addr)
+		    || (scn_addr >= (drmem.base_addr + lmb_size)))
+			continue;
+
 		nid = of_drconf_to_nid_single(&drmem, &aa);
+		break;
+	}
 
-		if (valid_hot_add_scn(&nid, drmem.base_addr, lmb_size,
-				      scn_addr))
-			return nid;
+	return nid;
+}
+
+/*
+ * Find the node associated with a hot added memory section for memory
+ * represented in the device tree as a node (i.e. memory@XXXX) for
+ * each lmb.
+ */
+int hot_add_node_scn_to_nid(unsigned long scn_addr)
+{
+	struct device_node *memory = NULL;
+	int nid = -1;
+
+	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+		unsigned long start, size;
+		int ranges;
+		const unsigned int *memcell_buf;
+		unsigned int len;
+
+		memcell_buf = of_get_property(memory, "reg", &len);
+		if (!memcell_buf || len <= 0)
+			continue;
+
+		/* ranges in cell */
+		ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
+
+		while (ranges--) {
+			start = read_n_cells(n_mem_addr_cells, &memcell_buf);
+			size = read_n_cells(n_mem_size_cells, &memcell_buf);
+
+			if ((scn_addr < start) || (scn_addr >= (start + size)))
+				continue;
+
+			nid = of_node_to_nid_single(memory);
+			break;
+		}
+
+		of_node_put(memory);
+		if (nid >= 0)
+			break;
 	}
 
-	BUG();	/* section address should be found above */
-	return 0;
+	return nid;
 }
 
 /*
@@ -1121,7 +1109,7 @@ static int hot_add_drconf_scn_to_nid(str
 int hot_add_scn_to_nid(unsigned long scn_addr)
 {
 	struct device_node *memory = NULL;
-	int nid;
+	int nid, found = 0;
 
 	if (!numa_enabled || (min_common_depth < 0))
 		return any_online_node(NODE_MASK_ALL);
@@ -1130,35 +1118,25 @@ int hot_add_scn_to_nid(unsigned long scn
 	if (memory) {
 		nid = hot_add_drconf_scn_to_nid(memory, scn_addr);
 		of_node_put(memory);
-		return nid;
+	} else {
+		nid = hot_add_node_scn_to_nid(scn_addr);
 	}
 
-	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
-		unsigned long start, size;
-		int ranges;
-		const unsigned int *memcell_buf;
-		unsigned int len;
-
-		memcell_buf = of_get_property(memory, "reg", &len);
-		if (!memcell_buf || len <= 0)
-			continue;
+	if (nid < 0 || !node_online(nid))
+		nid = any_online_node(NODE_MASK_ALL);
 
-		/* ranges in cell */
-		ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
-ha_new_range:
-		start = read_n_cells(n_mem_addr_cells, &memcell_buf);
-		size = read_n_cells(n_mem_size_cells, &memcell_buf);
-		nid = of_node_to_nid_single(memory);
+	if (NODE_DATA(nid)->node_spanned_pages)
+		return nid;
 
-		if (valid_hot_add_scn(&nid, start, size, scn_addr)) {
-			of_node_put(memory);
-			return nid;
+	for_each_online_node(nid) {
+		if (NODE_DATA(nid)->node_spanned_pages) {
+			found = 1;
+			break;
 		}
-
-		if (--ranges)		/* process all ranges in cell */
-			goto ha_new_range;
 	}
-	BUG();	/* section address should be found above */
-	return 0;
+
+	BUG_ON(!found);
+	return nid;
 }
+
 #endif /* CONFIG_MEMORY_HOTPLUG */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable_32.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable_32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,8 @@ pgtable_t pte_alloc_one(struct mm_struct
 void __iomem *
 ioremap(phys_addr_t addr, unsigned long size)
 {
-	return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+	return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED,
+				__builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap);
 
@@ -143,20 +144,27 @@ ioremap_flags(phys_addr_t addr, unsigned
 	/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
 	flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
 
-	return __ioremap(addr, size, flags);
+	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_flags);
 
 void __iomem *
 __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
 {
+	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
+
+void __iomem *
+__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
+		 void *caller)
+{
 	unsigned long v, i;
 	phys_addr_t p;
 	int err;
 
 	/* Make sure we have the base flags */
 	if ((flags & _PAGE_PRESENT) == 0)
-		flags |= _PAGE_KERNEL;
+		flags |= PAGE_KERNEL;
 
 	/* Non-cacheable page cannot be coherent */
 	if (flags & _PAGE_NO_CACHE)
@@ -212,7 +220,7 @@ __ioremap(phys_addr_t addr, unsigned lon
 
 	if (mem_init_done) {
 		struct vm_struct *area;
-		area = get_vm_area(size, VM_IOREMAP);
+		area = get_vm_area_caller(size, VM_IOREMAP, caller);
 		if (area == 0)
 			return NULL;
 		v = (unsigned long) area->addr;
@@ -288,7 +296,7 @@ void __init mapin_ram(void)
 	p = memstart_addr + s;
 	for (; s < total_lowmem; s += PAGE_SIZE) {
 		ktext = ((char *) v >= _stext && (char *) v < etext);
-		f = ktext ?_PAGE_RAM_TEXT : _PAGE_RAM;
+		f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL;
 		map_page(v, p, f);
 #ifdef CONFIG_PPC_STD_MMU_32
 		if (ktext)
@@ -391,8 +399,6 @@ void kernel_map_pages(struct page *page,
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
 static int fixmaps;
-unsigned long FIXADDR_TOP = (-PAGE_SIZE);
-EXPORT_SYMBOL(FIXADDR_TOP);
 
 void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable_64.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -144,8 +144,8 @@ void __iounmap_at(void *ea, unsigned lon
 	unmap_kernel_range((unsigned long)ea, size);
 }
 
-void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
-			 unsigned long flags)
+void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
+				unsigned long flags, void *caller)
 {
 	phys_addr_t paligned;
 	void __iomem *ret;
@@ -168,8 +168,9 @@ void __iomem * __ioremap(phys_addr_t add
 	if (mem_init_done) {
 		struct vm_struct *area;
 
-		area = __get_vm_area(size, VM_IOREMAP,
-				     ioremap_bot, IOREMAP_END);
+		area = __get_vm_area_caller(size, VM_IOREMAP,
+					    ioremap_bot, IOREMAP_END,
+					    caller);
 		if (area == NULL)
 			return NULL;
 		ret = __ioremap_at(paligned, area->addr, size, flags);
@@ -186,19 +187,27 @@ void __iomem * __ioremap(phys_addr_t add
 	return ret;
 }
 
+void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
+			 unsigned long flags)
+{
+	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
 
 void __iomem * ioremap(phys_addr_t addr, unsigned long size)
 {
 	unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
+	void *caller = __builtin_return_address(0);
 
 	if (ppc_md.ioremap)
-		return ppc_md.ioremap(addr, size, flags);
-	return __ioremap(addr, size, flags);
+		return ppc_md.ioremap(addr, size, flags, caller);
+	return __ioremap_caller(addr, size, flags, caller);
 }
 
 void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
 			     unsigned long flags)
 {
+	void *caller = __builtin_return_address(0);
+
 	/* writeable implies dirty for kernel addresses */
 	if (flags & _PAGE_RW)
 		flags |= _PAGE_DIRTY;
@@ -207,8 +216,8 @@ void __iomem * ioremap_flags(phys_addr_t
 	flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
 	if (ppc_md.ioremap)
-		return ppc_md.ioremap(addr, size, flags);
-	return __ioremap(addr, size, flags);
+		return ppc_md.ioremap(addr, size, flags, caller);
+	return __ioremap_caller(addr, size, flags, caller);
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/pgtable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 /*
  * This file contains common routines for dealing with free of page tables
+ * Along with common page table handling code
  *
  *  Derived from arch/powerpc/mm/tlb_64.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -81,11 +82,10 @@ static void pte_free_submit(struct pte_f
 void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
 {
 	/* This is safe since tlb_gather_mmu has disabled preemption */
-        cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
 	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
 
 	if (atomic_read(&tlb->mm->mm_users) < 2 ||
-	    cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
+	    cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))){
 		pgtable_free(pgf);
 		return;
 	}
@@ -115,3 +115,134 @@ void pte_free_finish(void)
 	pte_free_submit(*batchp);
 	*batchp = NULL;
 }
+
+/*
+ * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
+ */
+static pte_t do_dcache_icache_coherency(pte_t pte)
+{
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
+
+	if (unlikely(!pfn_valid(pfn)))
+		return pte;
+	page = pfn_to_page(pfn);
+
+	if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
+		pr_debug("do_dcache_icache_coherency... flushing\n");
+		flush_dcache_icache_page(page);
+		set_bit(PG_arch_1, &page->flags);
+	}
+	else
+		pr_debug("do_dcache_icache_coherency... already clean\n");
+	return __pte(pte_val(pte) | _PAGE_HWEXEC);
+}
+
+static inline int is_exec_fault(void)
+{
+	return current->thread.regs && TRAP(current->thread.regs) == 0x400;
+}
+
+/* We only try to do i/d cache coherency on stuff that looks like
+ * reasonably "normal" PTEs. We currently require a PTE to be present
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ */
+static inline int pte_looks_normal(pte_t pte)
+{
+	return (pte_val(pte) &
+		(_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
+		(_PAGE_PRESENT);
+}
+
+#if defined(CONFIG_PPC_STD_MMU)
+/* Server-style MMU handles coherency when hashing if HW exec permission
+ * is supposed per page (currently 64-bit only). Else, we always flush
+ * valid PTEs in set_pte.
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+	return set_pte && pte_looks_normal(pte) &&
+		!(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+		  cpu_has_feature(CPU_FTR_NOEXECUTE));
+}
+#elif _PAGE_HWEXEC == 0
+/* Embedded type MMU without HW exec support (8xx only so far), we flush
+ * the cache for any present PTE
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+	return set_pte && pte_looks_normal(pte);
+}
+#else
+/* Other embedded CPUs with HW exec support per-page, we flush on exec
+ * fault if HWEXEC is not set
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+	return pte_looks_normal(pte) && is_exec_fault() &&
+		!(pte_val(pte) & _PAGE_HWEXEC);
+}
+#endif
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ */
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+#ifdef CONFIG_DEBUG_VM
+	WARN_ON(pte_present(*ptep));
+#endif
+	/* Note: mm->context.id might not yet have been assigned as
+	 * this context might not have been activated yet when this
+	 * is called.
+	 */
+	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+	if (pte_need_exec_flush(pte, 1))
+		pte = do_dcache_icache_coherency(pte);
+
+	/* Perform the setting of the PTE */
+	__set_pte_at(mm, addr, ptep, pte, 0);
+}
+
+/*
+ * This is called when relaxing access to a PTE. It's also called in the page
+ * fault path when we don't hit any of the major fault cases, ie, a minor
+ * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have
+ * handled those two for us, we additionally deal with missing execute
+ * permission here on some processors
+ */
+int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+			  pte_t *ptep, pte_t entry, int dirty)
+{
+	int changed;
+	if (!dirty && pte_need_exec_flush(entry, 0))
+		entry = do_dcache_icache_coherency(entry);
+	changed = !pte_same(*(ptep), entry);
+	if (changed) {
+		if (!(vma->vm_flags & VM_HUGETLB))
+			assert_pte_locked(vma->vm_mm, address);
+		__ptep_set_access_flags(ptep, entry);
+		flush_tlb_page_nohash(vma, address);
+	}
+	return changed;
+}
+
+#ifdef CONFIG_DEBUG_VM
+void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+
+	if (mm == &init_mm)
+		return;
+	pgd = mm->pgd + pgd_index(addr);
+	BUG_ON(pgd_none(*pgd));
+	pud = pud_offset(pgd, addr);
+	BUG_ON(pud_none(*pud));
+	pmd = pmd_offset(pud, addr);
+	BUG_ON(!pmd_present(*pmd));
+	BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
+}
+#endif /* CONFIG_DEBUG_VM */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/ppc_mmu_32.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/ppc_mmu_32.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/ppc_mmu_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/ppc_mmu_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,9 +74,6 @@ unsigned long p_mapped_by_bats(phys_addr
 
 unsigned long __init mmu_mapin_ram(void)
 {
-#ifdef CONFIG_POWER4
-	return 0;
-#else
 	unsigned long tot, bl, done;
 	unsigned long max_size = (256<<20);
 
@@ -95,7 +92,7 @@ unsigned long __init mmu_mapin_ram(void)
 			break;
 	}
 
-	setbat(2, PAGE_OFFSET, 0, bl, _PAGE_RAM);
+	setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X);
 	done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
 	if ((done < tot) && !bat_addrs[3].limit) {
 		/* use BAT3 to cover a bit more */
@@ -103,12 +100,11 @@ unsigned long __init mmu_mapin_ram(void)
 		for (bl = 128<<10; bl < max_size; bl <<= 1)
 			if (bl * 2 > tot)
 				break;
-		setbat(3, PAGE_OFFSET+done, done, bl, _PAGE_RAM);
+		setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
 		done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
 	}
 
 	return done;
-#endif
 }
 
 /*
@@ -136,9 +132,7 @@ void __init setbat(int index, unsigned l
 		wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
 		bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
 		bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp;
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
 		if (flags & _PAGE_USER)
-#endif
 			bat[1].batu |= 1; 	/* Vp = 1 */
 		if (flags & _PAGE_GUARDED) {
 			/* G bit must be zero in IBATs */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_hash64.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_hash64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_hash64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_hash64.c	2009-06-09 23:05:27.000000000 -0400
@@ -139,12 +139,12 @@ void hpte_need_flush(struct mm_struct *m
  */
 void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
 {
-	cpumask_t tmp;
+	const struct cpumask *tmp;
 	int i, local = 0;
 
 	i = batch->index;
-	tmp = cpumask_of_cpu(smp_processor_id());
-	if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
+	tmp = cpumask_of(smp_processor_id());
+	if (cpumask_equal(mm_cpumask(batch->mm), tmp))
 		local = 1;
 	if (i == 1)
 		flush_hash_page(batch->vaddr[0], batch->pte[0],
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_nohash.c linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_nohash.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_nohash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_nohash.c	2009-06-09 23:05:27.000000000 -0400
@@ -125,18 +125,17 @@ static void do_flush_tlb_page_ipi(void *
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
-	cpumask_t cpu_mask;
 	unsigned int pid;
 
 	preempt_disable();
 	pid = mm->context.id;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto no_context;
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-	if (!cpus_empty(cpu_mask)) {
+	if (!cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
 		struct tlb_flush_param p = { .pid = pid };
-		smp_call_function_mask(cpu_mask, do_flush_tlb_mm_ipi, &p, 1);
+		/* Ignores smp_processor_id() even if set. */
+		smp_call_function_many(mm_cpumask(mm),
+				       do_flush_tlb_mm_ipi, &p, 1);
 	}
 	_tlbil_pid(pid);
  no_context:
@@ -146,16 +145,15 @@ EXPORT_SYMBOL(flush_tlb_mm);
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
 {
-	cpumask_t cpu_mask;
+	struct cpumask *cpu_mask;
 	unsigned int pid;
 
 	preempt_disable();
 	pid = vma ? vma->vm_mm->context.id : 0;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto bail;
-	cpu_mask = vma->vm_mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-	if (!cpus_empty(cpu_mask)) {
+	cpu_mask = mm_cpumask(vma->vm_mm);
+	if (!cpumask_equal(cpu_mask, cpumask_of(smp_processor_id()))) {
 		/* If broadcast tlbivax is supported, use it */
 		if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
 			int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
@@ -167,7 +165,8 @@ void flush_tlb_page(struct vm_area_struc
 			goto bail;
 		} else {
 			struct tlb_flush_param p = { .pid = pid, .addr = vmaddr };
-			smp_call_function_mask(cpu_mask,
+			/* Ignores smp_processor_id() even if set in cpu_mask */
+			smp_call_function_many(cpu_mask,
 					       do_flush_tlb_page_ipi, &p, 1);
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_nohash_low.S linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_nohash_low.S
--- linux-libre-2.6.29-gnu1/arch/powerpc/mm/tlb_nohash_low.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/mm/tlb_nohash_low.S	2009-06-09 23:05:27.000000000 -0400
@@ -118,25 +118,50 @@ _GLOBAL(_tlbil_pid)
 
 #elif defined(CONFIG_FSL_BOOKE)
 /*
- * FSL BookE implementations. Currently _pid and _all are the
- * same. This will change when tlbilx is actually supported and
- * performs invalidate-by-PID. This change will be driven by
- * mmu_features conditional
+ * FSL BookE implementations.
+ *
+ * Since feature sections are using _SECTION_ELSE we need
+ * to have the larger code path before the _SECTION_ELSE
  */
 
+#define MMUCSR0_TLBFI	(MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
+			 MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
 /*
  * Flush MMU TLB on the local processor
  */
-_GLOBAL(_tlbil_pid)
 _GLOBAL(_tlbil_all)
-#define MMUCSR0_TLBFI	(MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
-			 MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
+BEGIN_MMU_FTR_SECTION
+	li	r3,(MMUCSR0_TLBFI)@l
+	mtspr	SPRN_MMUCSR0, r3
+1:
+	mfspr	r3,SPRN_MMUCSR0
+	andi.	r3,r3,MMUCSR0_TLBFI@l
+	bne	1b
+MMU_FTR_SECTION_ELSE
+	PPC_TLBILX_ALL(0,0)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
+	msync
+	isync
+	blr
+
+_GLOBAL(_tlbil_pid)
+BEGIN_MMU_FTR_SECTION
+	slwi	r3,r3,16
+	mfmsr	r10
+	wrteei	0
+	mfspr	r4,SPRN_MAS6	/* save MAS6 */
+	mtspr	SPRN_MAS6,r3
+	PPC_TLBILX_PID(0,0)
+	mtspr	SPRN_MAS6,r4	/* restore MAS6 */
+	wrtee	r10
+MMU_FTR_SECTION_ELSE
 	li	r3,(MMUCSR0_TLBFI)@l
 	mtspr	SPRN_MMUCSR0, r3
 1:
 	mfspr	r3,SPRN_MMUCSR0
 	andi.	r3,r3,MMUCSR0_TLBFI@l
 	bne	1b
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX)
 	msync
 	isync
 	blr
@@ -149,7 +174,9 @@ _GLOBAL(_tlbil_va)
 	mfmsr	r10
 	wrteei	0
 	slwi	r4,r4,16
+	ori	r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l
 	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
+BEGIN_MMU_FTR_SECTION
 	tlbsx	0,r3
 	mfspr	r4,SPRN_MAS1		/* check valid */
 	andis.	r3,r4,MAS1_VALID@h
@@ -157,10 +184,13 @@ _GLOBAL(_tlbil_va)
 	rlwinm	r4,r4,0,1,31
 	mtspr	SPRN_MAS1,r4
 	tlbwe
+MMU_FTR_SECTION_ELSE
+	PPC_TLBILX_VA(0,r3)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
 	msync
 	isync
 1:	wrtee	r10
 	blr
-#elif
+#else
 #error Unsupported processor type !
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/oprofile/op_model_7450.c linux-libre-2.6.30-gnu1/arch/powerpc/oprofile/op_model_7450.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/oprofile/op_model_7450.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/oprofile/op_model_7450.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 static unsigned long reset_value[OP_MAX_COUNTER];
 
 static int oprofile_running;
-static u32 mmcr0_val, mmcr1_val, mmcr2_val;
+static u32 mmcr0_val, mmcr1_val, mmcr2_val, num_pmcs;
 
 #define MMCR0_PMC1_SHIFT	6
 #define MMCR0_PMC2_SHIFT	0
@@ -88,13 +88,12 @@ static int fsl7450_cpu_setup(struct op_c
 
 	mtspr(SPRN_MMCR0, mmcr0_val);
 	mtspr(SPRN_MMCR1, mmcr1_val);
-	mtspr(SPRN_MMCR2, mmcr2_val);
+	if (num_pmcs > 4)
+		mtspr(SPRN_MMCR2, mmcr2_val);
 
 	return 0;
 }
 
-#define NUM_CTRS 6
-
 /* Configures the global settings for the countes on all CPUs. */
 static int fsl7450_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
@@ -102,12 +101,13 @@ static int fsl7450_reg_setup(struct op_c
 {
 	int i;
 
+	num_pmcs = num_ctrs;
 	/* Our counters count up, and "count" refers to
 	 * how much before the next interrupt, and we interrupt
 	 * on overflow.  So we calculate the starting value
 	 * which will give us "count" until overflow.
 	 * Then we set the events on the enabled counters */
-	for (i = 0; i < NUM_CTRS; ++i)
+	for (i = 0; i < num_ctrs; ++i)
 		reset_value[i] = 0x80000000UL - ctr[i].count;
 
 	/* Set events for Counters 1 & 2 */
@@ -123,9 +123,10 @@ static int fsl7450_reg_setup(struct op_c
 
 	/* Set events for Counters 3-6 */
 	mmcr1_val = mmcr1_event3(ctr[2].event)
-		| mmcr1_event4(ctr[3].event)
-		| mmcr1_event5(ctr[4].event)
-		| mmcr1_event6(ctr[5].event);
+		| mmcr1_event4(ctr[3].event);
+	if (num_ctrs > 4)
+		mmcr1_val |= mmcr1_event5(ctr[4].event)
+			| mmcr1_event6(ctr[5].event);
 
 	mmcr2_val = 0;
 
@@ -139,7 +140,7 @@ static int fsl7450_start(struct op_count
 
 	mtmsr(mfmsr() | MSR_PMM);
 
-	for (i = 0; i < NUM_CTRS; ++i) {
+	for (i = 0; i < num_pmcs; ++i) {
 		if (ctr[i].enabled)
 			classic_ctr_write(i, reset_value[i]);
 		else
@@ -184,7 +185,7 @@ static void fsl7450_handle_interrupt(str
 	pc = mfspr(SPRN_SIAR);
 	is_kernel = is_kernel_addr(pc);
 
-	for (i = 0; i < NUM_CTRS; ++i) {
+	for (i = 0; i < num_pmcs; ++i) {
 		val = classic_ctr_read(i);
 		if (val < 0) {
 			if (oprofile_running && ctr[i].enabled) {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/oprofile/op_model_power4.c linux-libre-2.6.30-gnu1/arch/powerpc/oprofile/op_model_power4.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/oprofile/op_model_power4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/oprofile/op_model_power4.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@
 static unsigned long reset_value[OP_MAX_COUNTER];
 
 static int oprofile_running;
+static int use_slot_nums;
 
 /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
 static u32 mmcr0_val;
@@ -61,6 +62,12 @@ static int power4_reg_setup(struct op_co
 	else
 		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
 
+	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
+	    __is_processor(PV_970) || __is_processor(PV_970FX) ||
+	    __is_processor(PV_970MP) || __is_processor(PV_970GX) ||
+	    __is_processor(PV_POWER5) || __is_processor(PV_POWER5p))
+		use_slot_nums = 1;
+
 	return 0;
 }
 
@@ -206,7 +213,7 @@ static unsigned long get_pc(struct pt_re
 
 	mmcra = mfspr(SPRN_MMCRA);
 
-	if (mmcra & MMCRA_SAMPLE_ENABLE) {
+	if (use_slot_nums && (mmcra & MMCRA_SAMPLE_ENABLE)) {
 		slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT);
 		if (slot > 1)
 			pc += 4 * (slot - 1);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/40x/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/40x/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/40x/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/40x/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,7 @@ config 405GPR
 
 config XILINX_VIRTEX
 	bool
+	select DEFAULT_UIMAGE
 
 config XILINX_VIRTEX_II_PRO
 	bool
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/44x/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/44x/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/44x/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/44x/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -118,6 +118,17 @@ config GLACIER
 	help
 	  This option enables support for the AMCC PPC460GT evaluation board.
 
+config REDWOOD
+	bool "Redwood"
+	depends on 44x
+	default n
+	select PPC44x_SIMPLE
+	select 460SX
+	select PCI
+	select PPC4xx_PCI_EXPRESS
+	help
+	  This option enables support for the AMCC PPC460SX Redwood board.
+
 config YOSEMITE
 	bool "Yosemite"
 	depends on 44x
@@ -220,6 +231,14 @@ config 460EX
 	select IBM_NEW_EMAC_EMAC4
 	select IBM_NEW_EMAC_TAH
 
+config 460SX
+	bool
+	select PPC_FPU
+	select IBM_NEW_EMAC_EMAC4
+	select IBM_NEW_EMAC_RGMII
+	select IBM_NEW_EMAC_ZMII
+	select IBM_NEW_EMAC_TAH
+
 # 44x errata/workaround config symbols, selected by the CPU models above
 config IBM440EP_ERR42
 	bool
@@ -227,6 +246,7 @@ config IBM440EP_ERR42
 # Xilinx specific config options.
 config XILINX_VIRTEX
 	bool
+	select DEFAULT_UIMAGE
 
 # Xilinx Virtex 5 FXT FPGA architecture, selected by a Xilinx board above
 config XILINX_VIRTEX_5_FXT
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/44x/ppc44x_simple.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/44x/ppc44x_simple.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/44x/ppc44x_simple.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/44x/ppc44x_simple.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,6 +57,7 @@ static char *board[] __initdata = {
 	"ibm,ebony",
 	"amcc,katmai",
 	"amcc,rainier",
+	"amcc,redwood",
 	"amcc,sequoia",
 	"amcc,taishan",
 	"amcc,yosemite"
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/512x/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/512x/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/512x/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/512x/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@ config PPC_MPC5121
 
 config MPC5121_ADS
 	bool "Freescale MPC5121E ADS"
-	depends on PPC_MULTIPLATFORM && PPC32
+	depends on 6xx
 	select DEFAULT_UIMAGE
 	select PPC_MPC5121
 	select MPC5121_ADS_CPLD
@@ -21,7 +21,7 @@ config MPC5121_ADS
 
 config MPC5121_GENERIC
 	bool "Generic support for simple MPC5121 based boards"
-	depends on PPC_MULTIPLATFORM && PPC32
+	depends on 6xx
 	select DEFAULT_UIMAGE
 	select PPC_MPC5121
 	help
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_MPC52xx
 	bool "52xx-based boards"
-	depends on PPC_MULTIPLATFORM && PPC32
+	depends on 6xx
 	select PPC_CLOCK
 	select PPC_PCI_CHOICE
 
@@ -21,7 +21,13 @@ config PPC_MPC5200_SIMPLE
 	    and if there is a PCI bus node defined in the device tree.
 
 	  Boards that are compatible with this generic platform support
-	  are: 'tqc,tqm5200', 'promess,motionpro', 'schindler,cm5200'.
+	  are:
+	     intercontrol,digsy-mtc
+	     phytec,pcm030
+	     phytec,pcm032
+	     promess,motionpro
+	     schindler,cm5200
+	     tqc,tqm5200
 
 config PPC_EFIKA
 	bool "bPlan Efika 5k2. MPC5200B based computer"
@@ -35,6 +41,11 @@ config PPC_LITE5200
 	depends on PPC_MPC52xx
 	select DEFAULT_UIMAGE
 
+config PPC_MEDIA5200
+	bool "Freescale Media5200 Eval Board"
+	depends on PPC_MPC52xx
+	select DEFAULT_UIMAGE
+
 config PPC_MPC5200_BUGFIX
 	bool "MPC5200 (L25R) bugfix support"
 	depends on PPC_MPC52xx
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,12 +1,13 @@
 #
 # Makefile for 52xx based boards
 #
-obj-y				+= mpc52xx_pic.o mpc52xx_common.o
+obj-y				+= mpc52xx_pic.o mpc52xx_common.o mpc52xx_gpt.o
 obj-$(CONFIG_PCI)		+= mpc52xx_pci.o
 
 obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
+obj-$(CONFIG_PPC_MEDIA5200)	+= media5200.o
 
 obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
 ifeq ($(CONFIG_PPC_LITE5200),y)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/media5200.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/media5200.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/media5200.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/media5200.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,273 @@
+/*
+ * Support for 'media5200-platform' compatible boards.
+ *
+ * Copyright (C) 2008 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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Description:
+ * This code implements support for the Freescape Media5200 platform
+ * (built around the MPC5200 SoC).
+ *
+ * Notable characteristic of the Media5200 is the presence of an FPGA
+ * that has all external IRQ lines routed through it.  This file implements
+ * a cascaded interrupt controller driver which attaches itself to the
+ * Virtual IRQ subsystem after the primary mpc5200 interrupt controller
+ * is initialized.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <asm/time.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/mpc52xx.h>
+
+static struct of_device_id mpc5200_gpio_ids[] __initdata = {
+	{ .compatible = "fsl,mpc5200-gpio", },
+	{ .compatible = "mpc5200-gpio", },
+	{}
+};
+
+/* FPGA register set */
+#define MEDIA5200_IRQ_ENABLE (0x40c)
+#define MEDIA5200_IRQ_STATUS (0x410)
+#define MEDIA5200_NUM_IRQS   (6)
+#define MEDIA5200_IRQ_SHIFT  (32 - MEDIA5200_NUM_IRQS)
+
+struct media5200_irq {
+	void __iomem *regs;
+	spinlock_t lock;
+	struct irq_host *irqhost;
+};
+struct media5200_irq media5200_irq;
+
+static void media5200_irq_unmask(unsigned int virq)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&media5200_irq.lock, flags);
+	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
+	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
+	spin_unlock_irqrestore(&media5200_irq.lock, flags);
+}
+
+static void media5200_irq_mask(unsigned int virq)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&media5200_irq.lock, flags);
+	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
+	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
+	spin_unlock_irqrestore(&media5200_irq.lock, flags);
+}
+
+static struct irq_chip media5200_irq_chip = {
+	.typename = "Media5200 FPGA",
+	.unmask = media5200_irq_unmask,
+	.mask = media5200_irq_mask,
+	.mask_ack = media5200_irq_mask,
+};
+
+void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
+{
+	int sub_virq, val;
+	u32 status, enable;
+
+	/* Mask off the cascaded IRQ */
+	spin_lock(&desc->lock);
+	desc->chip->mask(virq);
+	spin_unlock(&desc->lock);
+
+	/* Ask the FPGA for IRQ status.  If 'val' is 0, then no irqs
+	 * are pending.  'ffs()' is 1 based */
+	status = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+	enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS);
+	val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT);
+	if (val) {
+		sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1);
+		/* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n",
+		 *          __func__, virq, status, enable, val - 1, sub_virq);
+		 */
+		generic_handle_irq(sub_virq);
+	}
+
+	/* Processing done; can reenable the cascade now */
+	spin_lock(&desc->lock);
+	desc->chip->ack(virq);
+	if (!(desc->status & IRQ_DISABLED))
+		desc->chip->unmask(virq);
+	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);
+
+	pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
+	set_irq_chip_data(virq, &media5200_irq);
+	set_irq_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq);
+	set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+	desc->status |= IRQ_TYPE_LEVEL_LOW | IRQ_LEVEL;
+
+	return 0;
+}
+
+static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
+				 u32 *intspec, unsigned int intsize,
+				 irq_hw_number_t *out_hwirq,
+				 unsigned int *out_flags)
+{
+	if (intsize != 2)
+		return -1;
+
+	pr_debug("%s: bank=%i, number=%i\n", __func__, intspec[0], intspec[1]);
+	*out_hwirq = intspec[1];
+	*out_flags = IRQ_TYPE_NONE;
+	return 0;
+}
+
+static struct irq_host_ops media5200_irq_ops = {
+	.map = media5200_irq_map,
+	.xlate = media5200_irq_xlate,
+};
+
+/*
+ * Setup Media5200 IRQ mapping
+ */
+static void __init media5200_init_irq(void)
+{
+	struct device_node *fpga_np;
+	int cascade_virq;
+
+	/* First setup the regular MPC5200 interrupt controller */
+	mpc52xx_init_irq();
+
+	/* Now find the FPGA IRQ */
+	fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga");
+	if (!fpga_np)
+		goto out;
+	pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name);
+
+	media5200_irq.regs = of_iomap(fpga_np, 0);
+	if (!media5200_irq.regs)
+		goto out;
+	pr_debug("%s: mapped to %p\n", __func__, media5200_irq.regs);
+
+	cascade_virq = irq_of_parse_and_map(fpga_np, 0);
+	if (!cascade_virq)
+		goto out;
+	pr_debug("%s: cascaded on virq=%i\n", __func__, cascade_virq);
+
+	/* Disable all FPGA IRQs */
+	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, 0);
+
+	spin_lock_init(&media5200_irq.lock);
+
+	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
+					       MEDIA5200_NUM_IRQS,
+					       &media5200_irq_ops, -1);
+	if (!media5200_irq.irqhost)
+		goto out;
+	pr_debug("%s: allocated irqhost\n", __func__);
+
+	media5200_irq.irqhost->host_data = &media5200_irq;
+
+	set_irq_data(cascade_virq, &media5200_irq);
+	set_irq_chained_handler(cascade_virq, media5200_irq_cascade);
+
+	return;
+
+ out:
+	pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n");
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init media5200_setup_arch(void)
+{
+
+	struct device_node *np;
+	struct mpc52xx_gpio __iomem *gpio;
+	u32 port_config;
+
+	if (ppc_md.progress)
+		ppc_md.progress("media5200_setup_arch()", 0);
+
+	/* Map important registers from the internal memory map */
+	mpc52xx_map_common_devices();
+
+	/* Some mpc5200 & mpc5200b related configuration */
+	mpc5200_setup_xlb_arbiter();
+
+	mpc52xx_setup_pci();
+
+	np = of_find_matching_node(NULL, mpc5200_gpio_ids);
+	gpio = of_iomap(np, 0);
+	of_node_put(np);
+	if (!gpio) {
+		printk(KERN_ERR "%s() failed. expect abnormal behavior\n",
+		       __func__);
+		return;
+	}
+
+	/* Set port config */
+	port_config = in_be32(&gpio->port_config);
+
+	port_config &= ~0x03000000;	/* ATA CS is on csb_4/5		*/
+	port_config |=  0x01000000;
+
+	out_be32(&gpio->port_config, port_config);
+
+	/* Unmap zone */
+	iounmap(gpio);
+
+}
+
+/* list of the supported boards */
+static char *board[] __initdata = {
+	"fsl,media5200",
+	NULL
+};
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init media5200_probe(void)
+{
+	unsigned long node = of_get_flat_dt_root();
+	int i = 0;
+
+	while (board[i]) {
+		if (of_flat_dt_is_compatible(node, board[i]))
+			break;
+		i++;
+	}
+
+	return (board[i] != NULL);
+}
+
+define_machine(media5200_platform) {
+	.name		= "media5200-platform",
+	.probe		= media5200_probe,
+	.setup_arch	= media5200_setup_arch,
+	.init		= mpc52xx_declare_of_platform_devices,
+	.init_IRQ	= media5200_init_irq,
+	.get_irq	= mpc52xx_get_irq,
+	.restart	= mpc52xx_restart,
+	.calibrate_decr	= generic_calibrate_decr,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc5200_simple.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc5200_simple.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc5200_simple.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc5200_simple.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,8 +50,10 @@ static void __init mpc5200_simple_setup_
 
 /* list of the supported boards */
 static char *board[] __initdata = {
-	"promess,motionpro",
+	"intercontrol,digsy-mtc",
 	"phytec,pcm030",
+	"phytec,pcm032",
+	"promess,motionpro",
 	"schindler,cm5200",
 	"tqc,tqm5200",
 	NULL
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_common.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_common.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,9 +28,10 @@ static struct of_device_id mpc52xx_xlb_i
 static struct of_device_id mpc52xx_bus_ids[] __initdata = {
 	{ .compatible = "fsl,mpc5200-immr", },
 	{ .compatible = "fsl,mpc5200b-immr", },
-	{ .compatible = "fsl,lpb", },
+	{ .compatible = "simple-bus", },
 
 	/* depreciated matches; shouldn't be used in new device trees */
+	{ .compatible = "fsl,lpb", },
 	{ .type = "builtin", .compatible = "mpc5200", }, /* efika */
 	{ .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
 	{}
@@ -205,6 +206,43 @@ int mpc52xx_set_psc_clkdiv(int psc_id, i
 EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
 
 /**
+ * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device
+ *
+ * @node: device node
+ *
+ * Returns the frequency of the external oscillator clock connected
+ * to the SYS_XTAL_IN pin, or 0 if it cannot be determined.
+ */
+unsigned int mpc52xx_get_xtal_freq(struct device_node *node)
+{
+	u32 val;
+	unsigned int freq;
+
+	if (!mpc52xx_cdm)
+		return 0;
+
+	freq = mpc52xx_find_ipb_freq(node);
+	if (!freq)
+		return 0;
+
+	if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1)
+		freq *= 2;
+
+	val  = in_be32(&mpc52xx_cdm->rstcfg);
+	if (val & (1 << 5))
+		freq *= 8;
+	else
+		freq *= 4;
+	if (val & (1 << 6))
+		freq /= 12;
+	else
+		freq /= 16;
+
+	return freq;
+}
+EXPORT_SYMBOL(mpc52xx_get_xtal_freq);
+
+/**
  * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
  */
 void
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -354,88 +354,6 @@ static struct of_platform_driver mpc52xx
 	.remove = mpc52xx_gpiochip_remove,
 };
 
-/*
- * GPIO LIB API implementation for gpt GPIOs.
- *
- * Each gpt only has a single GPIO.
- */
-static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
-	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
-	struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
-	return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
-}
-
-static void
-mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
-	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
-	struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
-	if (val)
-		out_be32(&regs->mode, 0x34);
-	else
-		out_be32(&regs->mode, 0x24);
-
-	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-}
-
-static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
-	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
-	struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
-	out_be32(&regs->mode, 0x04);
-
-	return 0;
-}
-
-static int
-mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
-	mpc52xx_gpt_gpio_set(gc, gpio, val);
-	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-
-	return 0;
-}
-
-static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
-					const struct of_device_id *match)
-{
-	struct of_mm_gpio_chip *mmchip;
-	struct of_gpio_chip *chip;
-
-	mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
-	if (!mmchip)
-		return -ENOMEM;
-
-	chip = &mmchip->of_gc;
-
-	chip->gpio_cells          = 2;
-	chip->gc.ngpio            = 1;
-	chip->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
-	chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
-	chip->gc.get              = mpc52xx_gpt_gpio_get;
-	chip->gc.set              = mpc52xx_gpt_gpio_set;
-
-	return of_mm_gpiochip_add(ofdev->node, mmchip);
-}
-
-static const struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
-	{
-		.compatible = "fsl,mpc5200-gpt-gpio",
-	},
-	{}
-};
-
-static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
-	.name = "gpio_gpt",
-	.match_table = mpc52xx_gpt_gpiochip_match,
-	.probe = mpc52xx_gpt_gpiochip_probe,
-	.remove = mpc52xx_gpiochip_remove,
-};
-
 static int __init mpc52xx_gpio_init(void)
 {
 	if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
@@ -444,9 +362,6 @@ static int __init mpc52xx_gpio_init(void
 	if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
 		printk(KERN_ERR "Unable to register simple GPIO driver\n");
 
-	if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
-		printk(KERN_ERR "Unable to register gpt GPIO driver\n");
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_gpt.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,396 @@
+/*
+ * MPC5200 General Purpose Timer device driver
+ *
+ * Copyright (c) 2009 Secret Lab Technologies Ltd.
+ * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, 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 file is a driver for the the General Purpose Timer (gpt) devices
+ * found on the MPC5200 SoC.  Each timer has an IO pin which can be used
+ * for GPIO or can be used to raise interrupts.  The timer function can
+ * be used independently from the IO pin, or it can be used to control
+ * 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.
+ *
+ * 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
+ * for the board):
+ * 	gpio-controller;
+ * 	#gpio-cells = < 2 >;
+ * This driver will register the GPIO pin if it finds the gpio-controller
+ * property in the device tree.
+ *
+ * To use the IRQ controller function, the following two properties must
+ * be added to the device tree node for the gpt device:
+ * 	interrupt-controller;
+ * 	#interrupt-cells = < 1 >;
+ * The IRQ controller binding only uses one cell to specify the interrupt,
+ * and the IRQ flags are encoded in the cell.  A cell is not used to encode
+ * the IRQ number because the GPT only has a single IRQ source.  For flags,
+ * a value of '1' means rising edge sensitive and '2' means falling edge.
+ *
+ * The GPIO and the IRQ controller functions can be used at the same time,
+ * but in this use case the IO line will only work as an input.  Trying to
+ * use it as a GPIO output will not work.
+ *
+ * When using the GPIO line as an output, it can either be driven as normal
+ * IO, or it can be an Open Collector (OC) output.  At the moment it is the
+ * responsibility of either the bootloader or the platform setup code to set
+ * the output mode.  This driver does not change the output mode setting.
+ */
+
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/kernel.h>
+#include <asm/mpc52xx.h>
+
+MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
+MODULE_AUTHOR("Sascha Hauer, Grant Likely");
+MODULE_LICENSE("GPL");
+
+/**
+ * struct mpc52xx_gpt - Private data structure for MPC52xx GPT driver
+ * @dev: pointer to device structure
+ * @regs: virtual address of GPT registers
+ * @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
+ */
+struct mpc52xx_gpt_priv {
+	struct device *dev;
+	struct mpc52xx_gpt __iomem *regs;
+	spinlock_t lock;
+	struct irq_host *irqhost;
+
+#if defined(CONFIG_GPIOLIB)
+	struct of_gpio_chip of_gc;
+#endif
+};
+
+#define MPC52xx_GPT_MODE_MS_MASK	(0x07)
+#define MPC52xx_GPT_MODE_MS_IC		(0x01)
+#define MPC52xx_GPT_MODE_MS_OC		(0x02)
+#define MPC52xx_GPT_MODE_MS_PWM		(0x03)
+#define MPC52xx_GPT_MODE_MS_GPIO	(0x04)
+
+#define MPC52xx_GPT_MODE_GPIO_MASK	(0x30)
+#define MPC52xx_GPT_MODE_GPIO_OUT_LOW	(0x20)
+#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH	(0x30)
+
+#define MPC52xx_GPT_MODE_IRQ_EN		(0x0100)
+
+#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_STATUS_IRQMASK	(0x000f)
+
+/* ---------------------------------------------------------------------
+ * Cascaded interrupt controller hooks
+ */
+
+static void mpc52xx_gpt_irq_unmask(unsigned int virq)
+{
+	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static void mpc52xx_gpt_irq_mask(unsigned int virq)
+{
+	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static void mpc52xx_gpt_irq_ack(unsigned int virq)
+{
+	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+
+	out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
+}
+
+static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
+{
+	struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+	unsigned long flags;
+	u32 reg;
+
+	dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
+	if (flow_type & IRQF_TRIGGER_RISING)
+		reg |= MPC52xx_GPT_MODE_ICT_RISING;
+	if (flow_type & IRQF_TRIGGER_FALLING)
+		reg |= MPC52xx_GPT_MODE_ICT_FALLING;
+	out_be32(&gpt->regs->mode, reg);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip mpc52xx_gpt_irq_chip = {
+	.typename = "MPC52xx GPT",
+	.unmask = mpc52xx_gpt_irq_unmask,
+	.mask = mpc52xx_gpt_irq_mask,
+	.ack = mpc52xx_gpt_irq_ack,
+	.set_type = mpc52xx_gpt_irq_set_type,
+};
+
+void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
+{
+	struct mpc52xx_gpt_priv *gpt = get_irq_data(virq);
+	int sub_virq;
+	u32 status;
+
+	status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK;
+	if (status) {
+		sub_virq = irq_linear_revmap(gpt->irqhost, 0);
+		generic_handle_irq(sub_virq);
+	}
+}
+
+static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
+			       irq_hw_number_t hw)
+{
+	struct mpc52xx_gpt_priv *gpt = h->host_data;
+
+	dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq);
+	set_irq_chip_data(virq, gpt);
+	set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
+
+	return 0;
+}
+
+static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
+				 u32 *intspec, unsigned int intsize,
+				 irq_hw_number_t *out_hwirq,
+				 unsigned int *out_flags)
+{
+	struct mpc52xx_gpt_priv *gpt = h->host_data;
+
+	dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
+
+	if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) {
+		dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name);
+		return -EINVAL;
+	}
+
+	*out_hwirq = 0; /* The GPT only has 1 IRQ line */
+	*out_flags = intspec[0];
+
+	return 0;
+}
+
+static struct irq_host_ops mpc52xx_gpt_irq_ops = {
+	.map = mpc52xx_gpt_irq_map,
+	.xlate = mpc52xx_gpt_irq_xlate,
+};
+
+static void
+mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
+{
+	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;
+
+	cascade_virq = irq_of_parse_and_map(node, 0);
+
+	gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
+				      &mpc52xx_gpt_irq_ops, -1);
+	if (!gpt->irqhost) {
+		dev_err(gpt->dev, "irq_alloc_host() failed\n");
+		return;
+	}
+
+	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 */
+	spin_lock_irqsave(&gpt->lock, flags);
+	clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
+			MPC52xx_GPT_MODE_MS_IC);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+
+	dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
+}
+
+
+/* ---------------------------------------------------------------------
+ * GPIOLIB hooks
+ */
+#if defined(CONFIG_GPIOLIB)
+static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
+{
+	return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
+}
+
+static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+
+	return (in_be32(&gpt->regs->status) >> 8) & 1;
+}
+
+static void
+mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
+{
+	struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+	unsigned long flags;
+	u32 r;
+
+	dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
+	r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+	unsigned long flags;
+
+	dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
+
+	spin_lock_irqsave(&gpt->lock, flags);
+	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
+	spin_unlock_irqrestore(&gpt->lock, flags);
+
+	return 0;
+}
+
+static int
+mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	mpc52xx_gpt_gpio_set(gc, gpio, val);
+	return 0;
+}
+
+static void
+mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
+{
+	int rc;
+
+	/* Only setup GPIO if the device tree claims the GPT is
+	 * a GPIO controller */
+	if (!of_find_property(node, "gpio-controller", NULL))
+		return;
+
+	gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
+	if (!gpt->of_gc.gc.label) {
+		dev_err(gpt->dev, "out of memory\n");
+		return;
+	}
+
+	gpt->of_gc.gpio_cells = 2;
+	gpt->of_gc.gc.ngpio = 1;
+	gpt->of_gc.gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
+	gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
+	gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
+	gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
+	gpt->of_gc.gc.base = -1;
+	gpt->of_gc.xlate = of_gpio_simple_xlate;
+	node->data = &gpt->of_gc;
+	of_node_get(node);
+
+	/* Setup external pin in GPIO mode */
+	clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
+			MPC52xx_GPT_MODE_MS_GPIO);
+
+	rc = gpiochip_add(&gpt->of_gc.gc);
+	if (rc)
+		dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
+
+	dev_dbg(gpt->dev, "%s() complete.\n", __func__);
+}
+#else /* defined(CONFIG_GPIOLIB) */
+static void
+mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { }
+#endif /* defined(CONFIG_GPIOLIB) */
+
+/* ---------------------------------------------------------------------
+ * of_platform bus binding code
+ */
+static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
+				       const struct of_device_id *match)
+{
+	struct mpc52xx_gpt_priv *gpt;
+
+	gpt = kzalloc(sizeof *gpt, GFP_KERNEL);
+	if (!gpt)
+		return -ENOMEM;
+
+	spin_lock_init(&gpt->lock);
+	gpt->dev = &ofdev->dev;
+	gpt->regs = of_iomap(ofdev->node, 0);
+	if (!gpt->regs) {
+		kfree(gpt);
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(&ofdev->dev, gpt);
+
+	mpc52xx_gpt_gpio_setup(gpt, ofdev->node);
+	mpc52xx_gpt_irq_setup(gpt, ofdev->node);
+
+	return 0;
+}
+
+static int mpc52xx_gpt_remove(struct of_device *ofdev)
+{
+	return -EBUSY;
+}
+
+static const struct of_device_id mpc52xx_gpt_match[] = {
+	{ .compatible = "fsl,mpc5200-gpt", },
+
+	/* Depreciated compatible values; don't use for new dts files */
+	{ .compatible = "fsl,mpc5200-gpt-gpio", },
+	{ .compatible = "mpc5200-gpt", },
+	{}
+};
+
+static struct of_platform_driver mpc52xx_gpt_driver = {
+	.name = "mpc52xx-gpt",
+	.match_table = mpc52xx_gpt_match,
+	.probe = mpc52xx_gpt_probe,
+	.remove = mpc52xx_gpt_remove,
+};
+
+static int __init mpc52xx_gpt_init(void)
+{
+	if (of_register_platform_driver(&mpc52xx_gpt_driver))
+		pr_err("error registering MPC52xx GPT driver\n");
+
+	return 0;
+}
+
+/* Make sure GPIOs and IRQs get set up before anyone tries to use them */
+subsys_initcall(mpc52xx_gpt_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,8 +163,6 @@ static void mpc52xx_extirq_mask(unsigned
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
 }
 
@@ -176,8 +174,6 @@ static void mpc52xx_extirq_unmask(unsign
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_setbit(&intr->ctrl, 11 - l2irq);
 }
 
@@ -189,17 +185,15 @@ static void mpc52xx_extirq_ack(unsigned
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_setbit(&intr->ctrl, 27-l2irq);
 }
 
 static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
 {
-	struct irq_desc *desc = get_irq_desc(virq);
 	u32 ctrl_reg, type;
 	int irq;
 	int l2irq;
+	void *handler = handle_level_irq;
 
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
@@ -207,32 +201,21 @@ static int mpc52xx_extirq_set_type(unsig
 	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
 
 	switch (flow_type) {
-	case IRQF_TRIGGER_HIGH:
-		type = 0;
-		break;
-	case IRQF_TRIGGER_RISING:
-		type = 1;
-		break;
-	case IRQF_TRIGGER_FALLING:
-		type = 2;
-		break;
-	case IRQF_TRIGGER_LOW:
-		type = 3;
-		break;
+	case IRQF_TRIGGER_HIGH: type = 0; break;
+	case IRQF_TRIGGER_RISING: type = 1; handler = handle_edge_irq; break;
+	case IRQF_TRIGGER_FALLING: type = 2; handler = handle_edge_irq; break;
+	case IRQF_TRIGGER_LOW: type = 3; break;
 	default:
 		type = 0;
 	}
 
-	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
-	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
-	if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
-		desc->status |= IRQ_LEVEL;
-
 	ctrl_reg = in_be32(&intr->ctrl);
 	ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
 	ctrl_reg |= (type << (22 - (l2irq * 2)));
 	out_be32(&intr->ctrl, ctrl_reg);
 
+	__set_irq_handler_unlocked(virq, handler);
+
 	return 0;
 }
 
@@ -247,6 +230,11 @@ static struct irq_chip mpc52xx_extirq_ir
 /*
  * Main interrupt irq_chip
  */
+static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
+{
+	return 0; /* Do nothing so that the sense mask will get updated */
+}
+
 static void mpc52xx_main_mask(unsigned int virq)
 {
 	int irq;
@@ -255,8 +243,6 @@ static void mpc52xx_main_mask(unsigned i
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
@@ -268,8 +254,6 @@ static void mpc52xx_main_unmask(unsigned
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_clrbit(&intr->main_mask, 16 - l2irq);
 }
 
@@ -278,6 +262,7 @@ static struct irq_chip mpc52xx_main_irqc
 	.mask = mpc52xx_main_mask,
 	.mask_ack = mpc52xx_main_mask,
 	.unmask = mpc52xx_main_unmask,
+	.set_type = mpc52xx_null_set_type,
 };
 
 /*
@@ -291,8 +276,6 @@ static void mpc52xx_periph_mask(unsigned
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_setbit(&intr->per_mask, 31 - l2irq);
 }
 
@@ -304,8 +287,6 @@ static void mpc52xx_periph_unmask(unsign
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_clrbit(&intr->per_mask, 31 - l2irq);
 }
 
@@ -314,6 +295,7 @@ static struct irq_chip mpc52xx_periph_ir
 	.mask = mpc52xx_periph_mask,
 	.mask_ack = mpc52xx_periph_mask,
 	.unmask = mpc52xx_periph_unmask,
+	.set_type = mpc52xx_null_set_type,
 };
 
 /*
@@ -327,8 +309,6 @@ static void mpc52xx_sdma_mask(unsigned i
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_setbit(&sdma->IntMask, l2irq);
 }
 
@@ -340,8 +320,6 @@ static void mpc52xx_sdma_unmask(unsigned
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	io_be_clrbit(&sdma->IntMask, l2irq);
 }
 
@@ -353,8 +331,6 @@ static void mpc52xx_sdma_ack(unsigned in
 	irq = irq_map[virq].hwirq;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
 	out_be32(&sdma->IntPend, 1 << l2irq);
 }
 
@@ -363,9 +339,19 @@ static struct irq_chip mpc52xx_sdma_irqc
 	.mask = mpc52xx_sdma_mask,
 	.unmask = mpc52xx_sdma_unmask,
 	.ack = mpc52xx_sdma_ack,
+	.set_type = mpc52xx_null_set_type,
 };
 
 /**
+ * mpc52xx_is_extirq - Returns true if hwirq number is for an external IRQ
+ */
+static int mpc52xx_is_extirq(int l1, int l2)
+{
+	return ((l1 == 0) && (l2 == 0)) ||
+	       ((l1 == 1) && (l2 >= 1) && (l2 <= 3));
+}
+
+/**
  * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
  */
 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
@@ -383,38 +369,23 @@ static int mpc52xx_irqhost_xlate(struct
 
 	intrvect_l1 = (int)intspec[0];
 	intrvect_l2 = (int)intspec[1];
-	intrvect_type = (int)intspec[2];
+	intrvect_type = (int)intspec[2] & 0x3;
 
 	intrvect_linux = (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) &
 			 MPC52xx_IRQ_L1_MASK;
 	intrvect_linux |= intrvect_l2 & MPC52xx_IRQ_L2_MASK;
 
-	pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
-		 intrvect_l2);
-
 	*out_hwirq = intrvect_linux;
-	*out_flags = mpc52xx_map_senses[intrvect_type];
+	*out_flags = IRQ_TYPE_LEVEL_LOW;
+	if (mpc52xx_is_extirq(intrvect_l1, intrvect_l2))
+		*out_flags = mpc52xx_map_senses[intrvect_type];
 
+	pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
+		 intrvect_l2);
 	return 0;
 }
 
 /**
- * mpc52xx_irqx_gettype - determine the IRQ sense type (level/edge)
- *
- * Only external IRQs need this.
- */
-static int mpc52xx_irqx_gettype(int irq)
-{
-	int type;
-	u32 ctrl_reg;
-
-	ctrl_reg = in_be32(&intr->ctrl);
-	type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
-
-	return mpc52xx_map_senses[type];
-}
-
-/**
  * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
  */
 static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
@@ -422,68 +393,46 @@ static int mpc52xx_irqhost_map(struct ir
 {
 	int l1irq;
 	int l2irq;
-	struct irq_chip *good_irqchip;
-	void *good_handle;
+	struct irq_chip *irqchip;
+	void *hndlr;
 	int type;
+	u32 reg;
 
 	l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
 	l2irq = irq & MPC52xx_IRQ_L2_MASK;
 
 	/*
-	 * Most of ours IRQs will be level low
-	 * Only external IRQs on some platform may be others
+	 * External IRQs are handled differently by the hardware so they are
+	 * handled by a dedicated irq_chip structure.
 	 */
-	type = IRQ_TYPE_LEVEL_LOW;
-
-	switch (l1irq) {
-	case MPC52xx_IRQ_L1_CRIT:
-		pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
-
-		BUG_ON(l2irq != 0);
-
-		type = mpc52xx_irqx_gettype(l2irq);
-		good_irqchip = &mpc52xx_extirq_irqchip;
-		break;
-
-	case MPC52xx_IRQ_L1_MAIN:
-		pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
-
-		if ((l2irq >= 1) && (l2irq <= 3)) {
-			type = mpc52xx_irqx_gettype(l2irq);
-			good_irqchip = &mpc52xx_extirq_irqchip;
-		} else {
-			good_irqchip = &mpc52xx_main_irqchip;
-		}
-		break;
-
-	case MPC52xx_IRQ_L1_PERP:
-		pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
-		good_irqchip = &mpc52xx_periph_irqchip;
-		break;
-
-	case MPC52xx_IRQ_L1_SDMA:
-		pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
-		good_irqchip = &mpc52xx_sdma_irqchip;
-		break;
+	if (mpc52xx_is_extirq(l1irq, l2irq)) {
+		reg = in_be32(&intr->ctrl);
+		type = mpc52xx_map_senses[(reg >> (22 - l2irq * 2)) & 0x3];
+		if ((type == IRQ_TYPE_EDGE_FALLING) ||
+		    (type == IRQ_TYPE_EDGE_RISING))
+			hndlr = handle_edge_irq;
+		else
+			hndlr = handle_level_irq;
 
-	default:
-		pr_err("%s: invalid virq requested (0x%x)\n", __func__, virq);
-		return -EINVAL;
+		set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr);
+		pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n",
+			 __func__, l2irq, virq, (int)irq, type);
+		return 0;
 	}
 
-	switch (type) {
-	case IRQ_TYPE_EDGE_FALLING:
-	case IRQ_TYPE_EDGE_RISING:
-		good_handle = handle_edge_irq;
-		break;
+	/* It is an internal SOC irq.  Choose the correct irq_chip */
+	switch (l1irq) {
+	case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
+	case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
+	case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
 	default:
-		good_handle = handle_level_irq;
+		pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
+		       __func__, virq, l1irq, l2irq);
+		return -EINVAL;
 	}
 
-	set_irq_chip_and_handler(virq, good_irqchip, good_handle);
-
-	pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
-		 (int)irq, type);
+	set_irq_chip_and_handler(virq, irqchip, handle_level_irq);
+	pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq);
 
 	return 0;
 }
@@ -522,6 +471,8 @@ void __init mpc52xx_init_irq(void)
 		panic(__FILE__	": find_and_map failed on 'mpc5200-bestcomm'. "
 				"Check node !");
 
+	pr_debug("MPC5200 IRQ controller mapped to 0x%p\n", intr);
+
 	/* Disable all interrupt sources. */
 	out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
 	out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
@@ -613,8 +564,5 @@ unsigned int mpc52xx_get_irq(void)
 		}
 	}
 
-	pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
-		 irq_linear_revmap(mpc52xx_irqhost, irq));
-
 	return irq_linear_revmap(mpc52xx_irqhost, irq);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/82xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/82xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/82xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/82xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 menuconfig PPC_82xx
 	bool "82xx-based boards (PQ II)"
-	depends on 6xx && PPC_MULTIPLATFORM
+	depends on 6xx
 
 if PPC_82xx
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/asp834x.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/asp834x.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/asp834x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/asp834x.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,6 +58,7 @@ static struct __initdata of_device_id as
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 menuconfig PPC_83xx
 	bool "83xx-based boards"
-	depends on 6xx && PPC_MULTIPLATFORM
+	depends on 6xx
 	select PPC_UDBG_16550
 	select PPC_PCI_CHOICE
 	select FSL_PCI if PCI
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc831x_rdb.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc831x_rdb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc831x_rdb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc831x_rdb.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,8 @@ static void __init mpc831x_rdb_setup_arc
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
 		mpc83xx_add_bridge(np);
+	for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
+		mpc83xx_add_bridge(np);
 #endif
 	mpc831x_usb_cfg();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc832x_rdb.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/spi/mmc_spi.h>
 #include <linux/mmc/host.h>
 #include <linux/of_platform.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/time.h>
 #include <asm/ipic.h>
@@ -39,16 +40,116 @@
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
-static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity)
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+				   struct spi_board_info *board_infos,
+				   unsigned int num_board_infos,
+				   void (*cs_control)(struct spi_device *dev,
+						      bool on))
 {
-	pr_debug("%s %d %d\n", __func__, cs, polarity);
-	par_io_data_set(3, 13, polarity);
+	struct device_node *np;
+	unsigned int i = 0;
+
+	for_each_compatible_node(np, type, compatible) {
+		int ret;
+		unsigned int j;
+		const void *prop;
+		struct resource res[2];
+		struct platform_device *pdev;
+		struct fsl_spi_platform_data pdata = {
+			.cs_control = cs_control,
+		};
+
+		memset(res, 0, sizeof(res));
+
+		pdata.sysclk = sysclk;
+
+		prop = of_get_property(np, "reg", NULL);
+		if (!prop)
+			goto err;
+		pdata.bus_num = *(u32 *)prop;
+
+		prop = of_get_property(np, "cell-index", NULL);
+		if (prop)
+			i = *(u32 *)prop;
+
+		prop = of_get_property(np, "mode", NULL);
+		if (prop && !strcmp(prop, "cpu-qe"))
+			pdata.qe_mode = 1;
+
+		for (j = 0; j < num_board_infos; j++) {
+			if (board_infos[j].bus_num == pdata.bus_num)
+				pdata.max_chipselect++;
+		}
+
+		if (!pdata.max_chipselect)
+			continue;
+
+		ret = of_address_to_resource(np, 0, &res[0]);
+		if (ret)
+			goto err;
+
+		ret = of_irq_to_resource(np, 0, &res[1]);
+		if (ret == NO_IRQ)
+			goto err;
+
+		pdev = platform_device_alloc("mpc83xx_spi", i);
+		if (!pdev)
+			goto err;
+
+		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add_resources(pdev, res,
+						    ARRAY_SIZE(res));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add(pdev);
+		if (ret)
+			goto unreg;
+
+		goto next;
+unreg:
+		platform_device_del(pdev);
+err:
+		pr_err("%s: registration failed\n", np->full_name);
+next:
+		i++;
+	}
+
+	return i;
 }
 
-static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity)
+static int __init fsl_spi_init(struct spi_board_info *board_infos,
+			       unsigned int num_board_infos,
+			       void (*cs_control)(struct spi_device *spi,
+						  bool on))
 {
-	pr_debug("%s %d %d\n", __func__, cs, polarity);
-	par_io_data_set(3, 13, !polarity);
+	u32 sysclk = -1;
+	int ret;
+
+	/* SPI controller is either clocked from QE or SoC clock */
+	sysclk = get_brgfreq();
+	if (sysclk == -1) {
+		sysclk = fsl_get_sys_freq();
+		if (sysclk == -1)
+			return -ENODEV;
+	}
+
+	ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+			       num_board_infos, cs_control);
+	if (!ret)
+		of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+				 num_board_infos, cs_control);
+
+	return spi_register_board_info(board_infos, num_board_infos);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+	pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
+	par_io_data_set(3, 13, on);
 }
 
 static struct mmc_spi_platform_data mpc832x_mmc_pdata = {
@@ -74,9 +175,13 @@ static int __init mpc832x_spi_init(void)
 	par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */
 	par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */
 
-	return fsl_spi_init(&mpc832x_spi_boardinfo, 1,
-			    mpc83xx_spi_activate_cs,
-			    mpc83xx_spi_deactivate_cs);
+	/*
+	 * Don't bother with legacy stuff when device tree contains
+	 * mmc-spi-slot node.
+	 */
+	if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot"))
+		return 0;
+	return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control);
 }
 machine_device_initcall(mpc832x_rdb, mpc832x_spi_init);
 #endif /* CONFIG_QUICC_ENGINE */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc834x_itx.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc834x_itx.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc834x_itx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc834x_itx.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,7 @@
 static struct of_device_id __initdata mpc834x_itx_ids[] = {
 	{ .compatible = "fsl,pq2pro-localbus", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc834x_mds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc834x_mds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc834x_mds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc834x_mds.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,6 +112,7 @@ static struct of_device_id mpc834x_ids[]
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc837x_mds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc837x_mds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc837x_mds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc837x_mds.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,14 +84,10 @@ static void __init mpc837x_mds_setup_arc
 		ppc_md.progress("mpc837x_mds_setup_arch()", 0);
 
 #ifdef CONFIG_PCI
-	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") {
-		if (!of_device_is_available(np)) {
-			pr_warning("%s: disabled by the firmware.\n",
-				   np->full_name);
-			continue;
-		}
+	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+		mpc83xx_add_bridge(np);
+	for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
 		mpc83xx_add_bridge(np);
-	}
 #endif
 	mpc837xmds_usb_cfg();
 }
@@ -100,6 +96,7 @@ static struct of_device_id mpc837x_ids[]
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc837x_rdb.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc837x_rdb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/mpc837x_rdb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc837x_rdb.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,8 @@ static void __init mpc837x_rdb_setup_arc
 #ifdef CONFIG_PCI
 	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
 		mpc83xx_add_bridge(np);
+	for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
+		mpc83xx_add_bridge(np);
 #endif
 	mpc837x_usb_cfg();
 }
@@ -46,6 +48,7 @@ static struct of_device_id mpc837x_ids[]
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/sbc834x.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/sbc834x.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/sbc834x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/sbc834x.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,6 +84,7 @@ static struct __initdata of_device_id sb
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/usb.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/usb.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/83xx/usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/of.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -210,7 +211,7 @@ int mpc837x_usb_cfg(void)
 	int ret = 0;
 
 	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
-	if (!np)
+	if (!np || !of_device_is_available(np))
 		return -ENODEV;
 	prop = of_get_property(np, "phy_type", NULL);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,12 @@ config MPC85xx_DS
 	help
 	  This option enables support for the MPC85xx DS (MPC8544 DS) board
 
+config SOCRATES
+	bool "Socrates"
+	select DEFAULT_UIMAGE
+	help
+	  This option enables support for the Socrates board.
+
 config KSI8560
         bool "Emerson KSI8560"
         select DEFAULT_UIMAGE
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/ksi8560.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/ksi8560.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/ksi8560.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/ksi8560.c	2009-06-09 23:05:27.000000000 -0400
@@ -106,8 +106,6 @@ static void __init ksi8560_pic_init(void
 	cpm2_pic_init(np);
 	of_node_put(np);
 	set_irq_chained_handler(irq, cpm2_cascade);
-
-	setup_irq(0, NULL);
 #endif
 }
 
@@ -221,6 +219,7 @@ static struct of_device_id __initdata of
 	{ .type = "simple-bus", },
 	{ .name = "cpm", },
 	{ .name = "localbus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -13,4 +13,5 @@ obj-$(CONFIG_STX_GP3)	  += stx_gp3.o
 obj-$(CONFIG_TQM85xx)	  += tqm85xx.o
 obj-$(CONFIG_SBC8560)     += sbc8560.o
 obj-$(CONFIG_SBC8548)     += sbc8548.o
+obj-$(CONFIG_SOCRATES)    += socrates.o socrates_fpga_pic.o
 obj-$(CONFIG_KSI8560)	  += ksi8560.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc8536_ds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc8536_ds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc8536_ds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc8536_ds.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,6 +92,7 @@ static struct of_device_id __initdata mp
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ads.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ads.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2009-06-09 23:05:27.000000000 -0400
@@ -226,6 +226,7 @@ static struct of_device_id __initdata of
 	{ .name = "cpm", },
 	{ .name = "localbus", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_cds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_cds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_cds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_cds.c	2009-06-09 23:05:27.000000000 -0400
@@ -179,7 +179,6 @@ static irqreturn_t mpc85xx_8259_cascade_
 static struct irqaction mpc85xxcds_8259_irqaction = {
 	.handler = mpc85xx_8259_cascade_action,
 	.flags = IRQF_SHARED,
-	.mask = CPU_MASK_NONE,
 	.name = "8259 cascade",
 };
 #endif /* PPC_I8259 */
@@ -336,6 +335,7 @@ static struct of_device_id __initdata of
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_ds.c	2009-06-09 23:05:27.000000000 -0400
@@ -204,6 +204,7 @@ static struct of_device_id __initdata mp
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/mpc85xx_mds.c	2009-06-09 23:05:27.000000000 -0400
@@ -265,6 +265,7 @@ static struct of_device_id mpc85xx_ids[]
 	{ .compatible = "simple-bus", },
 	{ .type = "qe", },
 	{ .compatible = "fsl,qe", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/sbc8548.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/sbc8548.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/sbc8548.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/sbc8548.c	2009-06-09 23:05:27.000000000 -0400
@@ -154,6 +154,7 @@ static struct of_device_id __initdata of
 	{ .name = "soc", },
 	{ .type = "soc", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/sbc8560.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/sbc8560.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/sbc8560.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/sbc8560.c	2009-06-09 23:05:27.000000000 -0400
@@ -213,6 +213,7 @@ static struct of_device_id __initdata of
 	{ .name = "cpm", },
 	{ .name = "localbus", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/smp.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/smp.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <asm/page.h>
 #include <asm/mpic.h>
 #include <asm/cacheflush.h>
+#include <asm/dbell.h>
 
 #include <sysdev/fsl_soc.h>
 
@@ -80,10 +81,8 @@ smp_85xx_kick_cpu(int nr)
 }
 
 static void __init
-smp_85xx_setup_cpu(int cpu_nr)
+smp_85xx_basic_setup(int cpu_nr)
 {
-	mpic_setup_this_cpu();
-
 	/* Clear any pending timer interrupts */
 	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
 
@@ -91,15 +90,43 @@ smp_85xx_setup_cpu(int cpu_nr)
 	mtspr(SPRN_TCR, TCR_DIE);
 }
 
+static void __init
+smp_85xx_setup_cpu(int cpu_nr)
+{
+	mpic_setup_this_cpu();
+
+	smp_85xx_basic_setup(cpu_nr);
+}
+
 struct smp_ops_t smp_85xx_ops = {
-	.message_pass = smp_mpic_message_pass,
-	.probe = smp_mpic_probe,
 	.kick_cpu = smp_85xx_kick_cpu,
-	.setup_cpu = smp_85xx_setup_cpu,
 };
 
-void __init
-mpc85xx_smp_init(void)
+static int __init smp_dummy_probe(void)
 {
+	return NR_CPUS;
+}
+
+void __init mpc85xx_smp_init(void)
+{
+	struct device_node *np;
+
+	smp_85xx_ops.message_pass = NULL;
+
+	np = of_find_node_by_type(NULL, "open-pic");
+	if (np) {
+		smp_85xx_ops.probe = smp_mpic_probe;
+		smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
+		smp_85xx_ops.message_pass = smp_mpic_message_pass;
+	} else {
+		smp_85xx_ops.probe = smp_dummy_probe;
+		smp_85xx_ops.setup_cpu = smp_85xx_basic_setup;
+	}
+
+	if (cpu_has_feature(CPU_FTR_DBELL))
+		smp_85xx_ops.message_pass = smp_dbell_message_pass;
+
+	BUG_ON(!smp_85xx_ops.message_pass);
+
 	smp_ops = &smp_85xx_ops;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2008 Emcraft Systems
+ * Sergei Poselenov <sposelenov@emcraft.com>
+ *
+ * Based on MPC8560 ADS and arch/ppc tqm85xx ports
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2008 Freescale Semiconductor Inc.
+ *
+ * Copyright (c) 2005-2006 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ * 	Kumar Gala <kumar.gala@freescale.com>
+ *      Copyright 2004 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/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "socrates_fpga_pic.h"
+
+static void __init socrates_pic_init(void)
+{
+	struct mpic *mpic;
+	struct resource r;
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "open-pic");
+	if (!np) {
+		printk(KERN_ERR "Could not find open-pic node\n");
+		return;
+	}
+
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "Could not map mpic register space\n");
+		of_node_put(np);
+		return;
+	}
+
+	mpic = mpic_alloc(np, r.start,
+			MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+			0, 256, " OpenPIC  ");
+	BUG_ON(mpic == NULL);
+	of_node_put(np);
+
+	mpic_init(mpic);
+
+	np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic");
+	if (!np) {
+		printk(KERN_ERR "Could not find socrates-fpga-pic node\n");
+		return;
+	}
+	socrates_fpga_pic_init(np);
+	of_node_put(np);
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init socrates_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+	struct device_node *np;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("socrates_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+	for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
+		fsl_add_bridge(np, 1);
+#endif
+}
+
+static struct of_device_id __initdata socrates_of_bus_ids[] = {
+	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
+	{},
+};
+
+static void __init socrates_init(void)
+{
+	of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init socrates_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "abb,socrates"))
+		return 1;
+
+	return 0;
+}
+
+define_machine(socrates) {
+	.name			= "Socrates",
+	.probe			= socrates_probe,
+	.setup_arch		= socrates_setup_arch,
+	.init			= socrates_init,
+	.init_IRQ		= socrates_pic_init,
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,327 @@
+/*
+ *  Copyright (C) 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+/*
+ * The FPGA supports 9 interrupt sources, which can be routed to 3
+ * interrupt request lines of the MPIC. The line to be used can be
+ * specified through the third cell of FDT property  "interrupts".
+ */
+
+#define SOCRATES_FPGA_NUM_IRQS	9
+
+#define FPGA_PIC_IRQCFG		(0x0)
+#define FPGA_PIC_IRQMASK(n)	(0x4 + 0x4 * (n))
+
+#define SOCRATES_FPGA_IRQ_MASK	((1 << SOCRATES_FPGA_NUM_IRQS) - 1)
+
+struct socrates_fpga_irq_info {
+	unsigned int irq_line;
+	int type;
+};
+
+/*
+ * Interrupt routing and type table
+ *
+ * IRQ_TYPE_NONE means the interrupt type is configurable,
+ * otherwise it's fixed to the specified value.
+ */
+static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
+	[0] = {0, IRQ_TYPE_NONE},
+	[1] = {0, IRQ_TYPE_LEVEL_HIGH},
+	[2] = {0, IRQ_TYPE_LEVEL_LOW},
+	[3] = {0, IRQ_TYPE_NONE},
+	[4] = {0, IRQ_TYPE_NONE},
+	[5] = {0, IRQ_TYPE_NONE},
+	[6] = {0, IRQ_TYPE_NONE},
+	[7] = {0, IRQ_TYPE_NONE},
+	[8] = {0, IRQ_TYPE_LEVEL_HIGH},
+};
+
+#define socrates_fpga_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
+
+static DEFINE_SPINLOCK(socrates_fpga_pic_lock);
+
+static void __iomem *socrates_fpga_pic_iobase;
+static struct irq_host *socrates_fpga_pic_irq_host;
+static unsigned int socrates_fpga_irqs[3];
+
+static inline uint32_t socrates_fpga_pic_read(int reg)
+{
+	return in_be32(socrates_fpga_pic_iobase + reg);
+}
+
+static inline void socrates_fpga_pic_write(int reg, uint32_t val)
+{
+	out_be32(socrates_fpga_pic_iobase + reg, val);
+}
+
+static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
+{
+	uint32_t cause;
+	unsigned long flags;
+	int i;
+
+	/* Check irq line routed to the MPIC */
+	for (i = 0; i < 3; i++) {
+		if (irq == socrates_fpga_irqs[i])
+			break;
+	}
+	if (i == 3)
+		return NO_IRQ;
+
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i));
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+	for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
+		if (cause >> (i + 16))
+			break;
+	}
+	return irq_linear_revmap(socrates_fpga_pic_irq_host,
+			(irq_hw_number_t)i);
+}
+
+void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned int cascade_irq;
+
+	/*
+	 * See if we actually have an interrupt, call generic handling code if
+	 * we do.
+	 */
+	cascade_irq = socrates_fpga_pic_get_irq(irq);
+
+	if (cascade_irq != NO_IRQ)
+		generic_handle_irq(cascade_irq);
+	desc->chip->eoi(irq);
+
+}
+
+static void socrates_fpga_pic_ack(unsigned int virq)
+{
+	unsigned long flags;
+	unsigned int hwirq, irq_line;
+	uint32_t mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	irq_line = fpga_irqs[hwirq].irq_line;
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+		& SOCRATES_FPGA_IRQ_MASK;
+	mask |= (1 << (hwirq + 16));
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_mask(unsigned int virq)
+{
+	unsigned long flags;
+	unsigned int hwirq;
+	int irq_line;
+	u32 mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	irq_line = fpga_irqs[hwirq].irq_line;
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+		& SOCRATES_FPGA_IRQ_MASK;
+	mask &= ~(1 << hwirq);
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_mask_ack(unsigned int virq)
+{
+	unsigned long flags;
+	unsigned int hwirq;
+	int irq_line;
+	u32 mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	irq_line = fpga_irqs[hwirq].irq_line;
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+		& SOCRATES_FPGA_IRQ_MASK;
+	mask &= ~(1 << hwirq);
+	mask |= (1 << (hwirq + 16));
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_unmask(unsigned int virq)
+{
+	unsigned long flags;
+	unsigned int hwirq;
+	int irq_line;
+	u32 mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	irq_line = fpga_irqs[hwirq].irq_line;
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+		& SOCRATES_FPGA_IRQ_MASK;
+	mask |= (1 << hwirq);
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_eoi(unsigned int virq)
+{
+	unsigned long flags;
+	unsigned int hwirq;
+	int irq_line;
+	u32 mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	irq_line = fpga_irqs[hwirq].irq_line;
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+		& SOCRATES_FPGA_IRQ_MASK;
+	mask |= (1 << (hwirq + 16));
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static int socrates_fpga_pic_set_type(unsigned int virq,
+		unsigned int flow_type)
+{
+	unsigned long flags;
+	unsigned int hwirq;
+	int polarity;
+	u32 mask;
+
+	hwirq = socrates_fpga_irq_to_hw(virq);
+
+	if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
+		return -EINVAL;
+
+	switch (flow_type & IRQ_TYPE_SENSE_MASK) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		polarity = 1;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		polarity = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG);
+	if (polarity)
+		mask |= (1 << hwirq);
+	else
+		mask &= ~(1 << hwirq);
+	socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+	return 0;
+}
+
+static struct irq_chip socrates_fpga_pic_chip = {
+	.typename       = " FPGA-PIC ",
+	.ack		= socrates_fpga_pic_ack,
+	.mask           = socrates_fpga_pic_mask,
+	.mask_ack       = socrates_fpga_pic_mask_ack,
+	.unmask         = socrates_fpga_pic_unmask,
+	.eoi		= socrates_fpga_pic_eoi,
+	.set_type	= socrates_fpga_pic_set_type,
+};
+
+static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
+		irq_hw_number_t hwirq)
+{
+	/* All interrupts are LEVEL sensitive */
+	get_irq_desc(virq)->status |= IRQ_LEVEL;
+	set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip,
+			handle_fasteoi_irq);
+
+	return 0;
+}
+
+static int socrates_fpga_pic_host_xlate(struct irq_host *h,
+		struct device_node *ct,	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]];
+
+	*out_hwirq = intspec[0];
+	if  (fpga_irq->type == IRQ_TYPE_NONE) {
+		/* type is configurable */
+		if (intspec[1] != IRQ_TYPE_LEVEL_LOW &&
+		    intspec[1] != IRQ_TYPE_LEVEL_HIGH) {
+			pr_warning("FPGA PIC: invalid irq type, "
+				   "setting default active low\n");
+			*out_flags = IRQ_TYPE_LEVEL_LOW;
+		} else {
+			*out_flags = intspec[1];
+		}
+	} else {
+		/* type is fixed */
+		*out_flags = fpga_irq->type;
+	}
+
+	/* Use specified interrupt routing */
+	if (intspec[2] <= 2)
+		fpga_irq->irq_line = intspec[2];
+	else
+		pr_warning("FPGA PIC: invalid irq routing\n");
+
+	return 0;
+}
+
+static struct irq_host_ops socrates_fpga_pic_host_ops = {
+	.map    = socrates_fpga_pic_host_map,
+	.xlate  = socrates_fpga_pic_host_xlate,
+};
+
+void socrates_fpga_pic_init(struct device_node *pic)
+{
+	unsigned long flags;
+	int i;
+
+	/* Setup an irq_host structure */
+	socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR,
+			SOCRATES_FPGA_NUM_IRQS,	&socrates_fpga_pic_host_ops,
+			SOCRATES_FPGA_NUM_IRQS);
+	if (socrates_fpga_pic_irq_host == NULL) {
+		pr_err("FPGA PIC: Unable to allocate host\n");
+		return;
+	}
+
+	for (i = 0; i < 3; i++) {
+		socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i);
+		if (socrates_fpga_irqs[i] == NO_IRQ) {
+			pr_warning("FPGA PIC: can't get irq%d.\n", i);
+			continue;
+		}
+		set_irq_chained_handler(socrates_fpga_irqs[i],
+				socrates_fpga_pic_cascade);
+	}
+
+	socrates_fpga_pic_iobase = of_iomap(pic, 0);
+
+	spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0),
+			SOCRATES_FPGA_IRQ_MASK << 16);
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1),
+			SOCRATES_FPGA_IRQ_MASK << 16);
+	socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2),
+			SOCRATES_FPGA_IRQ_MASK << 16);
+	spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+
+	pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.h linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/socrates_fpga_pic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (C) 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can 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 SOCRATES_FPGA_PIC_H
+#define SOCRATES_FPGA_PIC_H
+
+void socrates_fpga_pic_init(struct device_node *pic);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/stx_gp3.c	2009-06-09 23:05:27.000000000 -0400
@@ -145,6 +145,7 @@ static void stx_gp3_show_cpuinfo(struct
 
 static struct of_device_id __initdata of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/tqm85xx.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/tqm85xx.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/85xx/tqm85xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/85xx/tqm85xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,7 @@ static void tqm85xx_show_cpuinfo(struct
 
 static struct of_device_id __initdata of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,8 +37,6 @@
 #define GEF_GPIO_OVERRUN	0x1C
 #define GEF_GPIO_MODE		0x20
 
-#define NUM_GPIO 19
-
 static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
 {
 	unsigned int data;
@@ -103,10 +101,10 @@ static void gef_gpio_set(struct gpio_chi
 static int __init gef_gpio_init(void)
 {
 	struct device_node *np;
+	int retval;
+	struct of_mm_gpio_chip *gef_gpio_chip;
 
 	for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
-		int retval;
-		struct of_mm_gpio_chip *gef_gpio_chip;
 
 		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
 
@@ -120,7 +118,35 @@ static int __init gef_gpio_init(void)
 
 		/* Setup pointers to chip functions */
 		gef_gpio_chip->of_gc.gpio_cells = 2;
-		gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO;
+		gef_gpio_chip->of_gc.gc.ngpio = 19;
+		gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
+		gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
+		gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
+		gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+
+		/* This function adds a memory mapped GPIO chip */
+		retval = of_mm_gpiochip_add(np, gef_gpio_chip);
+		if (retval) {
+			kfree(gef_gpio_chip);
+			pr_err("%s: Unable to add GPIO\n", np->full_name);
+		}
+	}
+
+	for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
+
+		pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
+
+		/* Allocate chip structure */
+		gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
+		if (!gef_gpio_chip) {
+			pr_err("%s: Unable to allocate structure\n",
+				np->full_name);
+			continue;
+		}
+
+		/* Setup pointers to chip functions */
+		gef_gpio_chip->of_gc.gpio_cells = 2;
+		gef_gpio_chip->of_gc.gc.ngpio = 6;
 		gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
 		gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
 		gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_ppc9a.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * GE Fanuc PPC9A board support
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_pci.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "gef_pic.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG (fmt...) do { printk(KERN_ERR "PPC9A: " fmt); } while (0)
+#else
+#define DBG (fmt...) do { } while (0)
+#endif
+
+void __iomem *ppc9a_regs;
+
+static void __init gef_ppc9a_init_irq(void)
+{
+	struct device_node *cascade_node = NULL;
+
+	mpc86xx_init_irq();
+
+	/*
+	 * There is a simple interrupt handler in the main FPGA, this needs
+	 * to be cascaded into the MPIC
+	 */
+	cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic-1.00");
+	if (!cascade_node) {
+		printk(KERN_WARNING "PPC9A: No FPGA PIC\n");
+		return;
+	}
+
+	gef_pic_init(cascade_node);
+	of_node_put(cascade_node);
+}
+
+static void __init gef_ppc9a_setup_arch(void)
+{
+	struct device_node *regs;
+#ifdef CONFIG_PCI
+	struct device_node *np;
+
+	for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
+		fsl_add_bridge(np, 1);
+	}
+#endif
+
+	printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n");
+
+#ifdef CONFIG_SMP
+	mpc86xx_smp_init();
+#endif
+
+	/* Remap basic board registers */
+	regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs");
+	if (regs) {
+		ppc9a_regs = of_iomap(regs, 0);
+		if (ppc9a_regs == NULL)
+			printk(KERN_WARNING "Unable to map board registers\n");
+		of_node_put(regs);
+	}
+}
+
+/* Return the PCB revision */
+static unsigned int gef_ppc9a_get_pcb_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(ppc9a_regs);
+	return (reg >> 8) & 0xff;
+}
+
+/* Return the board (software) revision */
+static unsigned int gef_ppc9a_get_board_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(ppc9a_regs);
+	return (reg >> 16) & 0xff;
+}
+
+/* Return the FPGA revision */
+static unsigned int gef_ppc9a_get_fpga_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(ppc9a_regs);
+	return (reg >> 24) & 0xf;
+}
+
+static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
+{
+	uint svid = mfspr(SPRN_SVR);
+
+	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+
+	seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
+		('A' + gef_ppc9a_get_board_rev() - 1));
+	seq_printf(m, "FPGA Revision\t: %u\n", gef_ppc9a_get_fpga_rev());
+
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+}
+
+static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+
+	/* Do not do the fixup on other platforms! */
+	if (!machine_is(gef_ppc9a))
+		return;
+
+	printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
+
+	/* Ensure ports 1, 2, 3, 4 & 5 are enabled */
+	pci_read_config_dword(pdev, 0xe0, &val);
+	pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5);
+
+	/* System clock is 48-MHz Oscillator and EHCI Enabled. */
+	pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+	gef_ppc9a_nec_fixup);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+ * board. It is expected thati, in the future, a kernel may support multiple
+ * boards.
+ */
+static int __init gef_ppc9a_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "gef,ppc9a"))
+		return 1;
+
+	return 0;
+}
+
+static long __init mpc86xx_time_init(void)
+{
+	unsigned int temp;
+
+	/* Set the time base to zero */
+	mtspr(SPRN_TBWL, 0);
+	mtspr(SPRN_TBWU, 0);
+
+	temp = mfspr(SPRN_HID0);
+	temp |= HID0_TBEN;
+	mtspr(SPRN_HID0, temp);
+	asm volatile("isync");
+
+	return 0;
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
+	{},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+	printk(KERN_DEBUG "Probe platform devices\n");
+	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+	return 0;
+}
+machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
+
+define_machine(gef_ppc9a) {
+	.name			= "GE Fanuc PPC9A",
+	.probe			= gef_ppc9a_probe,
+	.setup_arch		= gef_ppc9a_setup_arch,
+	.init_IRQ		= gef_ppc9a_init_irq,
+	.show_cpuinfo		= gef_ppc9a_show_cpuinfo,
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.time_init		= mpc86xx_time_init,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_sbc310.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * GE Fanuc SBC310 board support
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_pci.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "gef_pic.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG (fmt...) do { printk(KERN_ERR "SBC310: " fmt); } while (0)
+#else
+#define DBG (fmt...) do { } while (0)
+#endif
+
+void __iomem *sbc310_regs;
+
+static void __init gef_sbc310_init_irq(void)
+{
+	struct device_node *cascade_node = NULL;
+
+	mpc86xx_init_irq();
+
+	/*
+	 * There is a simple interrupt handler in the main FPGA, this needs
+	 * to be cascaded into the MPIC
+	 */
+	cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic");
+	if (!cascade_node) {
+		printk(KERN_WARNING "SBC310: No FPGA PIC\n");
+		return;
+	}
+
+	gef_pic_init(cascade_node);
+	of_node_put(cascade_node);
+}
+
+static void __init gef_sbc310_setup_arch(void)
+{
+	struct device_node *regs;
+#ifdef CONFIG_PCI
+	struct device_node *np;
+
+	for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
+		fsl_add_bridge(np, 1);
+	}
+#endif
+
+	printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n");
+
+#ifdef CONFIG_SMP
+	mpc86xx_smp_init();
+#endif
+
+	/* Remap basic board registers */
+	regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
+	if (regs) {
+		sbc310_regs = of_iomap(regs, 0);
+		if (sbc310_regs == NULL)
+			printk(KERN_WARNING "Unable to map board registers\n");
+		of_node_put(regs);
+	}
+}
+
+/* Return the PCB revision */
+static unsigned int gef_sbc310_get_board_id(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(sbc310_regs);
+	return reg & 0xff;
+}
+
+/* Return the PCB revision */
+static unsigned int gef_sbc310_get_pcb_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(sbc310_regs);
+	return (reg >> 8) & 0xff;
+}
+
+/* Return the board (software) revision */
+static unsigned int gef_sbc310_get_board_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(sbc310_regs);
+	return (reg >> 16) & 0xff;
+}
+
+/* Return the FPGA revision */
+static unsigned int gef_sbc310_get_fpga_rev(void)
+{
+	unsigned int reg;
+
+	reg = ioread32(sbc310_regs);
+	return (reg >> 24) & 0xf;
+}
+
+static void gef_sbc310_show_cpuinfo(struct seq_file *m)
+{
+	uint svid = mfspr(SPRN_SVR);
+
+	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+
+	seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id());
+	seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(),
+		('A' + gef_sbc310_get_board_rev() - 1));
+	seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc310_get_fpga_rev());
+
+	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+}
+
+static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+
+	/* Do not do the fixup on other platforms! */
+	if (!machine_is(gef_sbc310))
+		return;
+
+	printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
+
+	/* Ensure only ports 1 & 2 are enabled */
+	pci_read_config_dword(pdev, 0xe0, &val);
+	pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2);
+
+	/* System clock is 48-MHz Oscillator and EHCI Enabled. */
+	pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+	gef_sbc310_nec_fixup);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+ * board. It is expected thati, in the future, a kernel may support multiple
+ * boards.
+ */
+static int __init gef_sbc310_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "gef,sbc310"))
+		return 1;
+
+	return 0;
+}
+
+static long __init mpc86xx_time_init(void)
+{
+	unsigned int temp;
+
+	/* Set the time base to zero */
+	mtspr(SPRN_TBWL, 0);
+	mtspr(SPRN_TBWU, 0);
+
+	temp = mfspr(SPRN_HID0);
+	temp |= HID0_TBEN;
+	mtspr(SPRN_HID0, temp);
+	asm volatile("isync");
+
+	return 0;
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
+	{},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+	printk(KERN_DEBUG "Probe platform devices\n");
+	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+	return 0;
+}
+machine_device_initcall(gef_sbc310, declare_of_platform_devices);
+
+define_machine(gef_sbc310) {
+	.name			= "GE Fanuc SBC310",
+	.probe			= gef_sbc310_probe,
+	.setup_arch		= gef_sbc310_setup_arch,
+	.init_IRQ		= gef_sbc310_init_irq,
+	.show_cpuinfo		= gef_sbc310_show_cpuinfo,
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.time_init		= mpc86xx_time_init,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/gef_sbc610.c	2009-06-09 23:05:27.000000000 -0400
@@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(voi
 
 static __initdata struct of_device_id of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 config PPC_86xx
 menuconfig PPC_86xx
 	bool "86xx-based boards"
-	depends on 6xx && PPC_MULTIPLATFORM
+	depends on 6xx
 	select FSL_SOC
 	select ALTIVEC
 	help
@@ -31,6 +31,22 @@ config MPC8610_HPCD
 	help
 	  This option enables support for the MPC8610 HPCD board.
 
+config GEF_PPC9A
+	bool "GE Fanuc PPC9A"
+	select DEFAULT_UIMAGE
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  This option enables support for GE Fanuc's PPC9A.
+
+config GEF_SBC310
+	bool "GE Fanuc SBC310"
+	select DEFAULT_UIMAGE
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  This option enables support for GE Fanuc's SBC310.
+
 config GEF_SBC610
 	bool "GE Fanuc SBC610"
 	select DEFAULT_UIMAGE
@@ -48,7 +64,7 @@ config MPC8641
 	select FSL_PCI if PCI
 	select PPC_UDBG_16550
 	select MPIC
-	default y if MPC8641_HPCN || SBC8641D || GEF_SBC610
+	default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
 
 config MPC8610
 	bool
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,3 +9,5 @@ obj-$(CONFIG_SBC8641D)		+= sbc8641d.o
 obj-$(CONFIG_MPC8610_HPCD)	+= mpc8610_hpcd.o
 gef-gpio-$(CONFIG_GPIOLIB)	+= gef_gpio.o
 obj-$(CONFIG_GEF_SBC610)	+= gef_sbc610.o gef_pic.o $(gef-gpio-y)
+obj-$(CONFIG_GEF_SBC310)	+= gef_sbc310.o gef_pic.o $(gef-gpio-y)
+obj-$(CONFIG_GEF_PPC9A)		+= gef_ppc9a.o gef_pic.o $(gef-gpio-y)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,7 @@ static unsigned char *pixis_bdcfg0, *pix
 static struct of_device_id __initdata mpc8610_ids[] = {
 	{ .compatible = "fsl,mpc8610-immr", },
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{}
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,6 +148,7 @@ mpc86xx_time_init(void)
 static __initdata struct of_device_id of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
 	{ .compatible = "fsl,rapidio-delta", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/sbc8641d.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/sbc8641d.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/86xx/sbc8641d.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/86xx/sbc8641d.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,6 +103,7 @@ mpc86xx_time_init(void)
 
 static __initdata struct of_device_id of_bus_ids[] = {
 	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
 	{},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/8xx/m8xx_setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,6 @@ static irqreturn_t timebase_interrupt(in
 
 static struct irqaction tbint_irqaction = {
 	.handler = timebase_interrupt,
-	.mask = CPU_MASK_NONE,
 	.name = "tbint",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+config AMIGAONE
+	bool "Eyetech AmigaOne/MAI Teron"
+	depends on 6xx && BROKEN_ON_SMP
+	select PPC_I8259
+	select PPC_INDIRECT_PCI
+	select PPC_UDBG_16550
+	select PCI
+	select NOT_COHERENT_CACHE
+	select CHECK_CACHE_COHERENCY
+	select DEFAULT_UIMAGE
+	select PCSPKR_PLATFORM
+	help
+	Select AmigaOne for the following machines:
+	- AmigaOne SE/Teron CX (G3 only)
+	- AmigaOne XE/Teron PX
+	- uA1/Teron mini
+	  More information is available at:
+	  <http://amigaone-linux.sourceforge.net/>.
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+obj-y	+= setup.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/amigaone/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/amigaone/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,170 @@
+/*
+ * AmigaOne platform setup
+ *
+ * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net)
+ *
+ *   Based on original amigaone_setup.c source code
+ * Copyright 2003 by Hans-Joerg Frieden and Thomas Frieden
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/seq_file.h>
+#include <linux/utsrelease.h>
+
+#include <asm/machdep.h>
+#include <asm/cputable.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/i8259.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+extern void __flush_disable_L1(void);
+
+void amigaone_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: Eyetech Ltd.\n");
+}
+
+static int __init amigaone_add_bridge(struct device_node *dev)
+{
+	const u32 *cfg_addr, *cfg_data;
+	int len;
+	const int *bus_range;
+	struct pci_controller *hose;
+
+	printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name);
+
+	cfg_addr = of_get_address(dev, 0, NULL, NULL);
+	cfg_data = of_get_address(dev, 1, NULL, NULL);
+	if ((cfg_addr == NULL) || (cfg_data == NULL))
+		return -ENODEV;
+
+	bus_range = of_get_property(dev, "bus-range", &len);
+	if ((bus_range == NULL) || (len < 2 * sizeof(int)))
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", dev->full_name);
+
+	hose = pcibios_alloc_controller(dev);
+	if (hose == NULL)
+		return -ENOMEM;
+
+	hose->first_busno = bus_range ? bus_range[0] : 0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+	setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0);
+
+	/* Interpret the "ranges" property */
+	/* This also maps the I/O region and sets isa_io/mem_base */
+	pci_process_bridge_OF_ranges(hose, dev, 1);
+
+	return 0;
+}
+
+void __init amigaone_setup_arch(void)
+{
+	struct device_node *np;
+	int phb = -ENODEV;
+
+	/* Lookup PCI host bridges. */
+	for_each_compatible_node(np, "pci", "mai-logic,articia-s")
+		phb = amigaone_add_bridge(np);
+
+	BUG_ON(phb != 0);
+
+	if (ppc_md.progress)
+		ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0);
+}
+
+void __init amigaone_init_IRQ(void)
+{
+	struct device_node *pic, *np = NULL;
+	const unsigned long *prop = NULL;
+	unsigned long int_ack = 0;
+
+	/* Search for ISA interrupt controller. */
+	pic = of_find_compatible_node(NULL, "interrupt-controller",
+	                              "pnpPNP,000");
+	BUG_ON(pic == NULL);
+
+	/* Look for interrupt acknowledge address in the PCI root node. */
+	np = of_find_compatible_node(NULL, "pci", "mai-logic,articia-s");
+	if (np) {
+		prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
+		if (prop)
+			int_ack = prop[0];
+		of_node_put(np);
+	}
+
+	if (int_ack == 0)
+		printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
+		       " address, polling\n");
+
+	i8259_init(pic, int_ack);
+	ppc_md.get_irq = i8259_irq;
+	irq_set_default_host(i8259_get_host());
+}
+
+void __init amigaone_init(void)
+{
+	request_region(0x00, 0x20, "dma1");
+	request_region(0x40, 0x20, "timer");
+	request_region(0x80, 0x10, "dma page reg");
+	request_region(0xc0, 0x20, "dma2");
+}
+
+void amigaone_restart(char *cmd)
+{
+	local_irq_disable();
+
+	/* Flush and disable caches. */
+	__flush_disable_L1();
+
+        /* Set SRR0 to the reset vector and turn on MSR_IP. */
+	mtspr(SPRN_SRR0, 0xfff00100);
+	mtspr(SPRN_SRR1, MSR_IP);
+
+	/* Do an rfi to jump back to firmware. */
+	__asm__ __volatile__("rfi" : : : "memory");
+
+	/* Not reached. */
+	while (1);
+}
+
+static int __init amigaone_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "eyetech,amigaone")) {
+		/*
+		 * Coherent memory access cause complete system lockup! Thus
+		 * disable this CPU feature, even if the CPU needs it.
+		 */
+		cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
+
+		ISA_DMA_THRESHOLD = 0x00ffffff;
+		DMA_MODE_READ = 0x44;
+		DMA_MODE_WRITE = 0x48;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+define_machine(amigaone) {
+	.name			= "AmigaOne",
+	.probe			= amigaone_probe,
+	.setup_arch		= amigaone_setup_arch,
+	.init			= amigaone_init,
+	.show_cpuinfo		= amigaone_show_cpuinfo,
+	.init_IRQ		= amigaone_init_IRQ,
+	.restart		= amigaone_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/interrupt.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/interrupt.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/interrupt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/interrupt.c	2009-06-09 23:05:27.000000000 -0400
@@ -237,8 +237,6 @@ extern int noirqdebug;
 
 static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
 {
-	const unsigned int cpu = smp_processor_id();
-
 	spin_lock(&desc->lock);
 
 	desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -254,7 +252,7 @@ static void handle_iic_irq(unsigned int
 		goto out_eoi;
 	}
 
-	kstat_cpu(cpu).irqs[irq]++;
+	kstat_incr_irqs_this_cpu(irq, desc);
 
 	/* Mark the IRQ currently in progress.*/
 	desc->status |= IRQ_INPROGRESS;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/iommu.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/iommu.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,7 +74,7 @@
 #define IOC_IO_ExcpStat_V		0x8000000000000000ul
 #define IOC_IO_ExcpStat_SPF_Mask	0x6000000000000000ul
 #define IOC_IO_ExcpStat_SPF_S		0x6000000000000000ul
-#define IOC_IO_ExcpStat_SPF_P		0x4000000000000000ul
+#define IOC_IO_ExcpStat_SPF_P		0x2000000000000000ul
 #define IOC_IO_ExcpStat_ADDR_Mask	0x00000007fffff000ul
 #define IOC_IO_ExcpStat_RW_Mask		0x0000000000000800ul
 #define IOC_IO_ExcpStat_IOID_Mask	0x00000000000007fful
@@ -247,17 +247,18 @@ static void tce_free_cell(struct iommu_t
 
 static irqreturn_t ioc_interrupt(int irq, void *data)
 {
-	unsigned long stat;
+	unsigned long stat, spf;
 	struct cbe_iommu *iommu = data;
 
 	stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
+	spf = stat & IOC_IO_ExcpStat_SPF_Mask;
 
 	/* Might want to rate limit it */
 	printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat);
 	printk(KERN_ERR "  V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n",
 	       !!(stat & IOC_IO_ExcpStat_V),
-	       (stat & IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
-	       (stat & IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
+	       (spf == IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
+	       (spf == IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
 	       (stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write",
 	       (unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask));
 	printk(KERN_ERR "  page=0x%016lx\n",
@@ -643,7 +644,7 @@ static void dma_fixed_unmap_sg(struct de
 
 static int dma_fixed_dma_supported(struct device *dev, u64 mask)
 {
-	return mask == DMA_64BIT_MASK;
+	return mask == DMA_BIT_MASK(64);
 }
 
 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/io-workarounds.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/io-workarounds.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/io-workarounds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/io-workarounds.c	2009-06-09 23:05:27.000000000 -0400
@@ -131,10 +131,10 @@ static const struct ppc_pci_io __devinit
 };
 
 static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
-						unsigned long flags)
+				  unsigned long flags, void *caller)
 {
 	struct iowa_bus *bus;
-	void __iomem *res = __ioremap(addr, size, flags);
+	void __iomem *res = __ioremap_caller(addr, size, flags, caller);
 	int busno;
 
 	bus = iowa_pci_find(0, (unsigned long)addr);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@ config PPC_CELL_COMMON
 config PPC_CELL_NATIVE
 	bool
 	select PPC_CELL_COMMON
-	select PPC_OF_PLATFORM_PCI
 	select MPIC
 	select IBM_NEW_EMAC_EMAC4
 	select IBM_NEW_EMAC_RGMII
@@ -23,16 +22,20 @@ config PPC_CELL_NATIVE
 
 config PPC_IBM_CELL_BLADE
 	bool "IBM Cell Blade"
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	select PPC_CELL_NATIVE
+	select PPC_OF_PLATFORM_PCI
+	select PCI
 	select MMIO_NVRAM
 	select PPC_UDBG_16550
 	select UDBG_RTAS_CONSOLE
 
 config PPC_CELLEB
 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	select PPC_CELL_NATIVE
+	select PPC_OF_PLATFORM_PCI
+	select PCI
 	select HAS_TXX9_SERIAL
 	select PPC_UDBG_BEAT
 	select USB_OHCI_BIG_ENDIAN_MMIO
@@ -40,9 +43,14 @@ config PPC_CELLEB
 
 config PPC_CELL_QPACE
 	bool "IBM Cell - QPACE"
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	select PPC_CELL_COMMON
 
+config AXON_MSI
+	bool
+	depends on PPC_IBM_CELL_BLADE && PCI_MSI
+	default y
+
 menu "Cell Broadband Engine options"
 	depends on PPC_CELL
 
@@ -98,7 +106,7 @@ config PPC_IBM_CELL_RESETBUTTON
 
 config PPC_IBM_CELL_POWERBUTTON
 	tristate "IBM Cell Blade power button"
-	depends on PPC_IBM_CELL_BLADE && PPC_PMI && INPUT_EVDEV
+	depends on PPC_IBM_CELL_BLADE && INPUT_EVDEV
 	default y
 	help
 	  Support Powerbutton on IBM Cell blades.
@@ -118,9 +126,9 @@ config CBE_CPUFREQ
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 	  If you don't have such processor, say N
 
-config CBE_CPUFREQ_PMI
-	tristate "CBE frequency scaling using PMI interface"
-	depends on CBE_CPUFREQ && PPC_PMI && EXPERIMENTAL
+config CBE_CPUFREQ_PMI_ENABLE
+	bool "CBE frequency scaling using PMI interface"
+	depends on CBE_CPUFREQ && EXPERIMENTAL
 	default n
 	help
 	  Select this, if you want to use the PMI interface
@@ -128,6 +136,20 @@ config CBE_CPUFREQ_PMI
 	  processor will not only be able to run at lower speed,
 	  but also at lower core voltage.
 
+config CBE_CPUFREQ_PMI
+	tristate
+	depends on CBE_CPUFREQ_PMI_ENABLE
+	default CBE_CPUFREQ
+
+config PPC_PMI
+	tristate
+	default y
+	depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON
+	help
+	  PMI (Platform Management Interrupt) is a way to
+	  communicate with the BMC (Baseboard Management Controller).
+	  It is used in some IBM Cell blades.
+
 config CBE_CPUFREQ_SPU_GOVERNOR
 	tristate "CBE frequency scaling based on SPU usage"
 	depends on SPU_FS && CPU_FREQ
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ obj-$(CONFIG_SPU_BASE)			+= spu_callback
 					   $(spu-manage-y) \
 					   spufs/
 
-obj-$(CONFIG_PCI_MSI)			+= axon_msi.o
+obj-$(CONFIG_AXON_MSI)			+= axon_msi.o
 
 # qpace setup
 obj-$(CONFIG_PPC_CELL_QPACE)		+= qpace_setup.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/qpace_setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/qpace_setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/qpace_setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/qpace_setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,16 +81,6 @@ static int __init qpace_publish_devices(
 }
 machine_subsys_initcall(qpace, qpace_publish_devices);
 
-extern int qpace_notify(struct device *dev)
-{
-	/* set dma_ops for of_platform bus */
-	if (dev->bus && dev->bus->name
-			&& !strcmp(dev->bus->name, "of_platform"))
-		set_dma_ops(dev, &dma_direct_ops);
-
-	return 0;
-}
-
 static void __init qpace_setup_arch(void)
 {
 #ifdef CONFIG_SPU_BASE
@@ -115,9 +105,6 @@ static void __init qpace_setup_arch(void
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
-
-	/* set notifier function */
-	platform_notify = &qpace_notify;
 }
 
 static int __init qpace_probe(void)
@@ -141,6 +128,8 @@ define_machine(qpace) {
 	.power_off		= rtas_power_off,
 	.halt			= rtas_halt,
 	.get_boot_time		= rtas_get_boot_time,
+	.get_rtc_time		= rtas_get_rtc_time,
+	.set_rtc_time		= rtas_set_rtc_time,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= qpace_progress,
 	.init_IRQ		= iic_init_IRQ,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/ras.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/ras.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/ras.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/ras.c	2009-06-09 23:05:27.000000000 -0400
@@ -122,12 +122,23 @@ static int __init cbe_ptcal_enable_on_no
 
 	area->nid = nid;
 	area->order = order;
-	area->pages = alloc_pages_node(area->nid, GFP_KERNEL, area->order);
+	area->pages = alloc_pages_node(area->nid, GFP_KERNEL | GFP_THISNODE,
+					area->order);
 
-	if (!area->pages)
+	if (!area->pages) {
+		printk(KERN_WARNING "%s: no page on node %d\n",
+			__func__, area->nid);
 		goto out_free_area;
+	}
 
-	addr = __pa(page_address(area->pages));
+	/*
+	 * We move the ptcal area to the middle of the allocated
+	 * page, in order to avoid prefetches in memcpy and similar
+	 * functions stepping on it.
+	 */
+	addr = __pa(page_address(area->pages)) + (PAGE_SIZE >> 1);
+	printk(KERN_DEBUG "%s: enabling PTCAL on node %d address=0x%016lx\n",
+			__func__, area->nid, addr);
 
 	ret = -EIO;
 	if (rtas_call(ptcal_start_tok, 3, 1, NULL, area->nid,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spu_base.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spu_base.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spu_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spu_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -114,7 +114,7 @@ static inline void mm_needs_global_tlbie
 	int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
 
 	/* Global TLBIE broadcast required with SPEs. */
-	__cpus_setall(&mm->cpu_vm_mask, nr);
+	bitmap_fill(cpumask_bits(mm_cpumask(mm)), nr);
 }
 
 void spu_associate_mm(struct spu *spu, struct mm_struct *mm)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spu_fault.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spu_fault.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spu_fault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spu_fault.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,60 +39,56 @@ int spu_handle_mm_fault(struct mm_struct
 	unsigned long is_write;
 	int ret;
 
-#if 0
-	if (!IS_VALID_EA(ea)) {
-		return -EFAULT;
-	}
-#endif /* XXX */
-	if (mm == NULL) {
+	if (mm == NULL)
 		return -EFAULT;
-	}
-	if (mm->pgd == NULL) {
+
+	if (mm->pgd == NULL)
 		return -EFAULT;
-	}
 
 	down_read(&mm->mmap_sem);
+	ret = -EFAULT;
 	vma = find_vma(mm, ea);
 	if (!vma)
-		goto bad_area;
-	if (vma->vm_start <= ea)
-		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN))
-		goto bad_area;
-	if (expand_stack(vma, ea))
-		goto bad_area;
-good_area:
+		goto out_unlock;
+
+	if (ea < vma->vm_start) {
+		if (!(vma->vm_flags & VM_GROWSDOWN))
+			goto out_unlock;
+		if (expand_stack(vma, ea))
+			goto out_unlock;
+	}
+
 	is_write = dsisr & MFC_DSISR_ACCESS_PUT;
 	if (is_write) {
 		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
+			goto out_unlock;
 	} else {
 		if (dsisr & MFC_DSISR_ACCESS_DENIED)
-			goto bad_area;
+			goto out_unlock;
 		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-			goto bad_area;
+			goto out_unlock;
 	}
+
 	ret = 0;
 	*flt = handle_mm_fault(mm, vma, ea, is_write);
 	if (unlikely(*flt & VM_FAULT_ERROR)) {
 		if (*flt & VM_FAULT_OOM) {
 			ret = -ENOMEM;
-			goto bad_area;
+			goto out_unlock;
 		} else if (*flt & VM_FAULT_SIGBUS) {
 			ret = -EFAULT;
-			goto bad_area;
+			goto out_unlock;
 		}
 		BUG();
 	}
+
 	if (*flt & VM_FAULT_MAJOR)
 		current->maj_flt++;
 	else
 		current->min_flt++;
-	up_read(&mm->mmap_sem);
-	return ret;
 
-bad_area:
+out_unlock:
 	up_read(&mm->mmap_sem);
-	return -EFAULT;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/context.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/context.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/context.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/context.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,8 @@ atomic_t nr_spu_contexts = ATOMIC_INIT(0
 struct spu_context *alloc_spu_context(struct spu_gang *gang)
 {
 	struct spu_context *ctx;
+	struct timespec ts;
+
 	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
 	if (!ctx)
 		goto out;
@@ -64,6 +66,8 @@ struct spu_context *alloc_spu_context(st
 	__spu_update_sched_info(ctx);
 	spu_set_timeslice(ctx);
 	ctx->stats.util_state = SPU_UTIL_IDLE_LOADED;
+	ktime_get_ts(&ts);
+	ctx->stats.tstamp = timespec_to_ns(&ts);
 
 	atomic_inc(&nr_spu_contexts);
 	goto out;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/file.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/file.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/file.c	2009-06-09 23:05:27.000000000 -0400
@@ -568,16 +568,17 @@ spufs_regs_write(struct file *file, cons
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	int ret;
 
-	size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
-	if (size <= 0)
+	if (*pos >= sizeof(lscsa->gprs))
 		return -EFBIG;
+
+	size = min_t(ssize_t, sizeof(lscsa->gprs) - *pos, size);
 	*pos += size;
 
 	ret = spu_acquire_saved(ctx);
 	if (ret)
 		return ret;
 
-	ret = copy_from_user(lscsa->gprs + *pos - size,
+	ret = copy_from_user((char *)lscsa->gprs + *pos - size,
 			     buffer, size) ? -EFAULT : size;
 
 	spu_release_saved(ctx);
@@ -623,10 +624,11 @@ spufs_fpcr_write(struct file *file, cons
 	struct spu_lscsa *lscsa = ctx->csa.lscsa;
 	int ret;
 
-	size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
-	if (size <= 0)
+	if (*pos >= sizeof(lscsa->fpcr))
 		return -EFBIG;
 
+	size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
+
 	ret = spu_acquire_saved(ctx);
 	if (ret)
 		return ret;
@@ -2665,7 +2667,7 @@ static const struct file_operations spuf
 	.release        = single_release,
 };
 
-struct spufs_tree_descr spufs_dir_contents[] = {
+const struct spufs_tree_descr spufs_dir_contents[] = {
 	{ "capabilities", &spufs_caps_fops, 0444, },
 	{ "mem",  &spufs_mem_fops,  0666, LS_SIZE, },
 	{ "regs", &spufs_regs_fops,  0666, sizeof(struct spu_reg128[128]), },
@@ -2706,7 +2708,7 @@ struct spufs_tree_descr spufs_dir_conten
 	{},
 };
 
-struct spufs_tree_descr spufs_dir_nosched_contents[] = {
+const struct spufs_tree_descr spufs_dir_nosched_contents[] = {
 	{ "capabilities", &spufs_caps_fops, 0444, },
 	{ "mem",  &spufs_mem_fops,  0666, LS_SIZE, },
 	{ "mbox", &spufs_mbox_fops, 0444, },
@@ -2731,12 +2733,12 @@ struct spufs_tree_descr spufs_dir_nosche
 	{},
 };
 
-struct spufs_tree_descr spufs_dir_debug_contents[] = {
+const struct spufs_tree_descr spufs_dir_debug_contents[] = {
 	{ ".ctx", &spufs_ctx_fops, 0444, },
 	{},
 };
 
-struct spufs_coredump_reader spufs_coredump_read[] = {
+const struct spufs_coredump_reader spufs_coredump_read[] = {
 	{ "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])},
 	{ "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) },
 	{ "lslr", NULL, spufs_lslr_get, 19 },
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/inode.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/inode.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/inode.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/inode.c	2009-06-09 23:05:27.000000000 -0400
@@ -186,8 +186,9 @@ static int spufs_rmdir(struct inode *par
 	return simple_rmdir(parent, dir);
 }
 
-static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files,
-			  int mode, struct spu_context *ctx)
+static int spufs_fill_dir(struct dentry *dir,
+		const struct spufs_tree_descr *files, int mode,
+		struct spu_context *ctx)
 {
 	struct dentry *dentry, *tmp;
 	int ret;
@@ -634,7 +635,7 @@ long spufs_create(struct nameidata *nd,
 	if (dentry->d_inode)
 		goto out_dput;
 
-	mode &= ~current->fs->umask;
+	mode &= ~current_umask();
 
 	if (flags & SPU_CREATE_GANG)
 		ret = spufs_create_gang(nd->path.dentry->d_inode,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/run.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/run.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/run.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/run.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,6 +117,9 @@ static int spu_setup_isolated(struct spu
 		cond_resched();
 	}
 
+	/* clear purge status */
+	out_be64(mfc_cntl, 0);
+
 	/* put the SPE in kernel mode to allow access to the loader */
 	sr1 = spu_mfc_sr1_get(ctx->spu);
 	sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/sched.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/sched.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/sched.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/sched.c	2009-06-09 23:05:27.000000000 -0400
@@ -508,7 +508,7 @@ static void __spu_add_to_rq(struct spu_c
 		list_add_tail(&ctx->rq, &spu_prio->runq[ctx->prio]);
 		set_bit(ctx->prio, spu_prio->bitmap);
 		if (!spu_prio->nr_waiting++)
-			__mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
+			mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/spufs.h linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/spufs.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/cell/spufs/spufs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/cell/spufs/spufs.h	2009-06-09 23:05:27.000000000 -0400
@@ -241,9 +241,9 @@ struct spufs_tree_descr {
 	size_t size;
 };
 
-extern struct spufs_tree_descr spufs_dir_contents[];
-extern struct spufs_tree_descr spufs_dir_nosched_contents[];
-extern struct spufs_tree_descr spufs_dir_debug_contents[];
+extern const struct spufs_tree_descr spufs_dir_contents[];
+extern const struct spufs_tree_descr spufs_dir_nosched_contents[];
+extern const struct spufs_tree_descr spufs_dir_debug_contents[];
 
 /* system call implementation */
 extern struct spufs_calls spufs_calls;
@@ -358,7 +358,7 @@ struct spufs_coredump_reader {
 	u64 (*get)(struct spu_context *ctx);
 	size_t size;
 };
-extern struct spufs_coredump_reader spufs_coredump_read[];
+extern const struct spufs_coredump_reader spufs_coredump_read[];
 extern int spufs_coredump_num_notes;
 
 extern int spu_init_csa(struct spu_state *csa);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_CHRP
 	bool "Common Hardware Reference Platform (CHRP) based machines"
-	depends on PPC_MULTIPLATFORM && PPC32
+	depends on 6xx
 	select MPIC
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/pegasos_eth.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/pegasos_eth.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/pegasos_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/pegasos_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,8 +21,8 @@
 #define PEGASOS2_SRAM_BASE 			(0xf2000000)
 #define PEGASOS2_SRAM_SIZE			(256*1024)
 
-#define PEGASOS2_SRAM_BASE_ETH0			(PEGASOS2_SRAM_BASE)
-#define PEGASOS2_SRAM_BASE_ETH1			(PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+#define PEGASOS2_SRAM_BASE_ETH_PORT0			(PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH_PORT1			(PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) )
 
 
 #define PEGASOS2_SRAM_RXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
@@ -47,75 +47,42 @@ static struct platform_device mv643xx_et
 	.resource	= mv643xx_eth_shared_resources,
 };
 
-static struct resource mv643xx_eth0_resources[] = {
-	[0] = {
-		.name	= "eth0 irq",
-		.start	= 9,
-		.end	= 9,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-
-static struct mv643xx_eth_platform_data eth0_pd = {
-	.shared		= &mv643xx_eth_shared_device,
-	.port_number	= 0,
-
-	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
-	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
-	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
-
-	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
-	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
-	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
-};
-
-static struct platform_device eth0_device = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(mv643xx_eth0_resources),
-	.resource	= mv643xx_eth0_resources,
-	.dev = {
-		.platform_data = &eth0_pd,
-	},
-};
-
-static struct resource mv643xx_eth1_resources[] = {
+static struct resource mv643xx_eth_port1_resources[] = {
 	[0] = {
-		.name	= "eth1 irq",
+		.name	= "eth port1 irq",
 		.start	= 9,
 		.end	= 9,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
 
-static struct mv643xx_eth_platform_data eth1_pd = {
+static struct mv643xx_eth_platform_data eth_port1_pd = {
 	.shared		= &mv643xx_eth_shared_device,
 	.port_number	= 1,
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(7),
 
-	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1,
 	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
 	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
 
-	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE,
 	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
 	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
 };
 
-static struct platform_device eth1_device = {
+static struct platform_device eth_port1_device = {
 	.name		= MV643XX_ETH_NAME,
 	.id		= 1,
-	.num_resources	= ARRAY_SIZE(mv643xx_eth1_resources),
-	.resource	= mv643xx_eth1_resources,
+	.num_resources	= ARRAY_SIZE(mv643xx_eth_port1_resources),
+	.resource	= mv643xx_eth_port1_resources,
 	.dev = {
-		.platform_data = &eth1_pd,
+		.platform_data = &eth_port1_pd,
 	},
 };
 
 static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
 	&mv643xx_eth_shared_device,
-	&eth0_device,
-	&eth1_device,
+	&eth_port1_device,
 };
 
 /***********/
@@ -191,15 +158,10 @@ static int __init mv643xx_eth_add_pds(vo
 
 		if ( Enable_SRAM() < 0)
 		{
-			eth0_pd.tx_sram_addr = 0;
-			eth0_pd.tx_sram_size = 0;
-			eth0_pd.rx_sram_addr = 0;
-			eth0_pd.rx_sram_size = 0;
-
-			eth1_pd.tx_sram_addr = 0;
-			eth1_pd.tx_sram_size = 0;
-			eth1_pd.rx_sram_addr = 0;
-			eth1_pd.rx_sram_size = 0;
+			eth_port1_pd.tx_sram_addr = 0;
+			eth_port1_pd.tx_sram_size = 0;
+			eth_port1_pd.rx_sram_addr = 0;
+			eth_port1_pd.rx_sram_size = 0;
 
 #ifdef BE_VERBOSE
 			printk("Pegasos II/Marvell MV64361: Can't enable the "
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/chrp/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/chrp/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -472,7 +472,6 @@ static void __init chrp_find_openpic(voi
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON)
 static struct irqaction xmon_irqaction = {
 	.handler = xmon_irq,
-	.mask = CPU_MASK_NONE,
 	.name = "XMON break",
 };
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/embedded6xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config EMBEDDED6xx
 	bool "Embedded 6xx/7xx/7xxx-based boards"
-	depends on PPC32 && BROKEN_ON_SMP && PPC_MULTIPLATFORM
+	depends on 6xx && BROKEN_ON_SMP
 
 config LINKSTATION
 	bool "Linkstation / Kurobox(HG) from Buffalo"
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/fsl_uli1575.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/fsl_uli1575.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/fsl_uli1575.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/fsl_uli1575.c	2009-06-09 23:05:27.000000000 -0400
@@ -275,11 +275,6 @@ static void __devinit hpcd_quirk_uli5288
 	if (!machine_is(mpc86xx_hpcd))
 		return;
 
-	/* Interrupt Disable, Needed when SATA disabled */
-	pci_read_config_word(dev, PCI_COMMAND, &temp);
-	temp |= 1<<10;
-	pci_write_config_word(dev, PCI_COMMAND, temp);
-
 	pci_read_config_byte(dev, 0x83, &c);
 	c |= 0x80;
 	pci_write_config_byte(dev, 0x83, c);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/iommu.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/iommu.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -174,9 +174,10 @@ static struct iommu_table *iommu_table_f
 }
 
 
-void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
+static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
 {
 	struct iommu_table *tbl;
+	struct device_node *dn = pdev->sysdata;
 	struct pci_dn *pdn = PCI_DN(dn);
 	const u32 *lsn = of_get_property(dn, "linux,logical-slot-number", NULL);
 
@@ -194,6 +195,8 @@ void iommu_devnode_init_iSeries(struct p
 		kfree(tbl);
 	pdev->dev.archdata.dma_data = pdn->iommu_table;
 }
+#else
+#define pci_dma_dev_setup_iseries	NULL
 #endif
 
 static struct iommu_table veth_iommu_table;
@@ -202,7 +205,7 @@ static struct iommu_table vio_iommu_tabl
 void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
 {
 	return iommu_alloc_coherent(NULL, &vio_iommu_table, size, dma_handle,
-				DMA_32BIT_MASK, flag, -1);
+				DMA_BIT_MASK(32), flag, -1);
 }
 EXPORT_SYMBOL_GPL(iseries_hv_alloc);
 
@@ -217,7 +220,7 @@ dma_addr_t iseries_hv_map(void *vaddr, s
 {
 	return iommu_map_page(NULL, &vio_iommu_table, virt_to_page(vaddr),
 			      (unsigned long)vaddr % PAGE_SIZE, size,
-			      DMA_32BIT_MASK, direction, NULL);
+			      DMA_BIT_MASK(32), direction, NULL);
 }
 
 void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
@@ -251,5 +254,6 @@ void iommu_init_early_iSeries(void)
 	ppc_md.tce_build = tce_build_iSeries;
 	ppc_md.tce_free  = tce_free_iSeries;
 
+	ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_iseries;
 	set_pci_dma_ops(&dma_iommu_ops);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/irq.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/irq.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -214,7 +214,7 @@ void __init iSeries_activate_IRQs()
 	unsigned long flags;
 
 	for_each_irq (irq) {
-		irq_desc_t *desc = get_irq_desc(irq);
+		struct irq_desc *desc = get_irq_desc(irq);
 
 		if (desc && desc->chip && desc->chip->startup) {
 			spin_lock_irqsave(&desc->lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_ISERIES
 	bool "IBM Legacy iSeries"
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	select PPC_INDIRECT_IO
 	select PPC_PCI_CHOICE if EMBEDDED
 
@@ -17,6 +17,7 @@ config VIODASD
 
 config VIOCD
 	tristate "iSeries Virtual I/O CD support"
+	depends on BLOCK
 	select VIOPATH
 	help
 	  If you are running Linux on an IBM iSeries system and you want to
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/pci.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/pci.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -444,7 +444,6 @@ void __init iSeries_pcibios_fixup_resour
 	pdev->sysdata = node;
 	allocate_device_bars(pdev);
 	iseries_device_information(pdev, bus, *sub_bus);
-	iommu_devnode_init_iSeries(pdev, node);
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/iseries/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/iseries/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -617,7 +617,7 @@ static void iseries_dedicated_idle(void)
 }
 
 static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
-				     unsigned long flags)
+				     unsigned long flags, void *caller)
 {
 	return (void __iomem *)address;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,5 @@
 menu "Platform support"
 
-config PPC_MULTIPLATFORM
-	bool
-	depends on PPC64 || 6xx
-	default y
-
-config CLASSIC32
-	def_bool y
-	depends on 6xx && PPC_MULTIPLATFORM
-
 source "arch/powerpc/platforms/pseries/Kconfig"
 source "arch/powerpc/platforms/iseries/Kconfig"
 source "arch/powerpc/platforms/chrp/Kconfig"
@@ -28,15 +19,28 @@ source "arch/powerpc/platforms/86xx/Kcon
 source "arch/powerpc/platforms/embedded6xx/Kconfig"
 source "arch/powerpc/platforms/44x/Kconfig"
 source "arch/powerpc/platforms/40x/Kconfig"
+source "arch/powerpc/platforms/amigaone/Kconfig"
 
 config PPC_NATIVE
 	bool
-	depends on PPC_MULTIPLATFORM
+	depends on 6xx || PPC64
 	help
 	  Support for running natively on the hardware, i.e. without
 	  a hypervisor. This option is not user-selectable but should
 	  be selected by all platforms that need it.
 
+config PPC_OF_BOOT_TRAMPOLINE
+	bool "Support booting from Open Firmware or yaboot"
+	depends on 6xx || PPC64
+	default y
+	help
+	  Support from booting from Open Firmware or yaboot using an
+	  Open Firmware client interface. This enables the kernel to
+	  communicate with open firmware to retrieve system informations
+	  such as the device tree.
+
+	  In case of doubt, say Y
+
 config UDBG_RTAS_CONSOLE
 	bool "RTAS based debug console"
 	depends on PPC_RTAS
@@ -70,7 +74,7 @@ config PPC_I8259
 
 config U3_DART
 	bool
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64
 	default n
 
 config PPC_RTAS
@@ -91,15 +95,6 @@ config RTAS_FLASH
 	tristate "Firmware flash interface"
 	depends on PPC64 && RTAS_PROC
 
-config PPC_PMI
-	tristate "Support for PMI"
-	depends on PPC_IBM_CELL_BLADE
-	help
-	  PMI (Platform Management Interrupt) is a way to
-	  communicate with the BMC (Baseboard Management Controller).
-	  It is used in some IBM Cell blades.
-	default m
-
 config MMIO_NVRAM
 	bool
 	default n
@@ -196,7 +191,7 @@ config PPC601_SYNC_FIX
 
 config TAU
 	bool "On-chip CPU temperature sensor support"
-	depends on CLASSIC32
+	depends on 6xx
 	help
 	  G3 and G4 processors have an on-chip temperature sensor called the
 	  'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
@@ -274,7 +269,7 @@ config CPM2
 
 config AXON_RAM
 	tristate "Axon DDR2 memory device driver"
-	depends on PPC_IBM_CELL_BLADE
+	depends on PPC_IBM_CELL_BLADE && BLOCK
 	default m
 	help
 	  It registers one block device per Axon's DDR2 memory bank found
@@ -298,7 +293,7 @@ config CPM
 config OF_RTC
 	bool
 	help
-	  Uses information from the OF or flattened device tree to instatiate
+	  Uses information from the OF or flattened device tree to instantiate
 	  platform devices for direct mapped RTC chips like the DS1742 or DS1743.
 
 source "arch/powerpc/sysdev/bestcomm/Kconfig"
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Kconfig.cputype linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Kconfig.cputype
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Kconfig.cputype	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Kconfig.cputype	2009-06-09 23:05:27.000000000 -0400
@@ -57,9 +57,17 @@ config E200
 
 endchoice
 
+# Until we have a choice of exclusive CPU types on 64-bit, we always
+# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is
+# "classic" MMU
+
+config PPC_BOOK3S
+       def_bool y
+       depends on PPC64 || 6xx
+
 config POWER4_ONLY
 	bool "Optimize for POWER4"
-	depends on PPC64
+	depends on PPC64 && PPC_BOOK3S
 	default n
 	---help---
 	  Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
@@ -68,16 +76,16 @@ config POWER4_ONLY
 
 config POWER3
 	bool
-	depends on PPC64
+	depends on PPC64 && PPC_BOOK3S
 	default y if !POWER4_ONLY
 
 config POWER4
-	depends on PPC64
+	depends on PPC64 && PPC_BOOK3S
 	def_bool y
 
 config TUNE_CELL
 	bool "Optimize for Cell Broadband Engine"
-	depends on PPC64
+	depends on PPC64 && PPC_BOOK3S
 	help
 	  Cause the compiler to optimize for the PPE of the Cell Broadband
 	  Engine. This will make the code run considerably faster on Cell
@@ -147,7 +155,7 @@ config PHYS_64BIT
 
 config ALTIVEC
 	bool "AltiVec Support"
-	depends on CLASSIC32 || POWER4
+	depends on 6xx || POWER4
 	---help---
 	  This option enables kernel support for the Altivec extensions to the
 	  PowerPC processor. The kernel currently supports saving and restoring
@@ -210,6 +218,10 @@ config PPC_MMU_NOHASH
 	def_bool y
 	depends on !PPC_STD_MMU
 
+config PPC_BOOK3E_MMU
+	def_bool y
+	depends on FSL_BOOKE
+
 config PPC_MM_SLICES
 	bool
 	default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -19,3 +19,4 @@ obj-$(CONFIG_PPC_PASEMI)	+= pasemi/
 obj-$(CONFIG_PPC_CELL)		+= cell/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
+obj-$(CONFIG_AMIGAONE)		+= amigaone/
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/maple/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/maple/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/maple/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/maple/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 config PPC_MAPLE
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	bool "Maple 970FX Evaluation Board"
 	select PCI
 	select MPIC
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/maple/pci.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/maple/pci.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/maple/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/maple/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -592,3 +592,17 @@ int maple_pci_get_legacy_ide_irq(struct
 	}
 	return irq;
 }
+
+static void __devinit quirk_ipr_msi(struct pci_dev *dev)
+{
+	/* Something prevents MSIs from the IPR from working on Bimini,
+	 * and the driver has no smarts to recover. So disable MSI
+	 * on it for now. */
+
+	if (machine_is(maple)) {
+		dev->no_msi = 1;
+		dev_info(&dev->dev, "Quirk disabled MSI\n");
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
+			quirk_ipr_msi);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pasemi/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pasemi/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pasemi/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pasemi/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 config PPC_PASEMI
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	bool "PA Semi SoC-based platforms"
 	default n
 	select MPIC
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pasemi/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pasemi/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pasemi/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pasemi/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,10 +44,6 @@
 
 #include "pasemi.h"
 
-#if !defined(CONFIG_SMP)
-static void smp_send_stop(void) {}
-#endif
-
 /* SDC reset register, must be pre-mapped at reset time */
 static void __iomem *reset_reg;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/cpufreq_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,6 +86,7 @@ static int (*g5_query_freq)(void);
 
 static DEFINE_MUTEX(g5_switch_mutex);
 
+static unsigned long transition_latency;
 
 #ifdef CONFIG_PMAC_SMU
 
@@ -357,7 +358,7 @@ static unsigned int g5_cpufreq_get_speed
 
 static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cpuinfo.transition_latency = transition_latency;
 	policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
 	/* secondary CPUs are tied to the primary one by the
 	 * cpufreq core if in the secondary policy we tell it that
@@ -500,6 +501,7 @@ static int __init g5_neo2_cpufreq_init(s
 	g5_cpu_freqs[1].frequency = max_freq/2;
 
 	/* Set callbacks */
+	transition_latency = 12000;
 	g5_switch_freq = g5_scom_switch_freq;
 	g5_query_freq = g5_scom_query_freq;
 	freq_method = "SCOM";
@@ -675,6 +677,7 @@ static int __init g5_pm72_cpufreq_init(s
 	g5_cpu_freqs[1].frequency = min_freq;
 
 	/* Set callbacks */
+	transition_latency = CPUFREQ_ETERNAL;
 	g5_switch_volt = g5_pfunc_switch_volt;
 	g5_switch_freq = g5_pfunc_switch_freq;
 	g5_query_freq = g5_pfunc_query_freq;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_PMAC
 	bool "Apple PowerMac based machines"
-	depends on PPC_MULTIPLATFORM
+	depends on PPC_BOOK3S
 	select MPIC
 	select PCI
 	select PPC_INDIRECT_PCI if PPC32
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/pic.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/pic.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/pic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/pic.c	2009-06-09 23:05:27.000000000 -0400
@@ -266,7 +266,6 @@ static unsigned int pmac_pic_get_irq(voi
 static struct irqaction xmon_action = {
 	.handler	= xmon_irq,
 	.flags		= 0,
-	.mask		= CPU_MASK_NONE,
 	.name		= "NMI - XMON"
 };
 #endif
@@ -274,7 +273,6 @@ static struct irqaction xmon_action = {
 static struct irqaction gatwick_cascade_action = {
 	.handler	= gatwick_action,
 	.flags		= IRQF_DISABLED,
-	.mask		= CPU_MASK_NONE,
 	.name		= "cascade",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/pic.h linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/pic.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/pic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/pic.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 
 #include <linux/irq.h>
 
-extern struct hw_interrupt_type pmac_pic;
+extern struct irq_chip pmac_pic;
 
 extern void pmac_pic_init(void);
 extern int pmac_get_irq(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -746,4 +746,7 @@ define_machine(powermac) {
 #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
 	.cpu_die		= pmac_cpu_die,
 #endif
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+	.cpu_die		= generic_mach_cpu_die,
+#endif
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/smp.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/smp.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/powermac/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/powermac/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -385,7 +385,6 @@ static void __init psurge_dual_sync_tb(i
 static struct irqaction psurge_irqaction = {
 	.handler = psurge_primary_intr,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "primary IPI",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/prep/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/prep/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/prep/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/prep/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_PREP
 	bool "PowerPC Reference Platform (PReP) based machines"
-	depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
+	depends on 6xx && BROKEN
 	select MPIC
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config PPC_PS3
 	bool "Sony PS3"
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	select PPC_CELL
 	select USB_ARCH_HAS_OHCI
 	select USB_OHCI_LITTLE_ENDIAN
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/mm.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/mm.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/mm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/mm.c	2009-06-09 23:05:27.000000000 -0400
@@ -311,7 +311,7 @@ static int __init ps3_mm_add_memory(void
 	result = add_memory(0, start_addr, map.r1.size);
 
 	if (result) {
-		DBG("%s:%d: add_memory failed: (%d)\n",
+		pr_err("%s:%d: add_memory failed: (%d)\n",
 			__func__, __LINE__, result);
 		return result;
 	}
@@ -322,7 +322,7 @@ static int __init ps3_mm_add_memory(void
 	result = online_pages(start_pfn, nr_pages);
 
 	if (result)
-		DBG("%s:%d: online_pages failed: (%d)\n",
+		pr_err("%s:%d: online_pages failed: (%d)\n",
 			__func__, __LINE__, result);
 
 	return result;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/os-area.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/os-area.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/os-area.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/os-area.c	2009-06-09 23:05:27.000000000 -0400
@@ -578,7 +578,7 @@ static void os_area_db_init(struct os_ar
  *
  */
 
-static void update_flash_db(void)
+static void __maybe_unused update_flash_db(void)
 {
 	int result;
 	int file;
@@ -808,6 +808,7 @@ u64 ps3_os_area_get_rtc_diff(void)
 {
 	return saved_params.rtc_diff;
 }
+EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
 
 /**
  * ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -823,6 +824,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_di
 		os_area_queue_work();
 	}
 }
+EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
 
 /**
  * ps3_os_area_get_av_multi_out - Returns the default video mode.
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/platform.h linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/platform.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/platform.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/platform.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,8 +64,6 @@ int ps3_set_rtc_time(struct rtc_time *ti
 
 void __init ps3_os_area_save_params(void);
 void __init ps3_os_area_init(void);
-u64 ps3_os_area_get_rtc_diff(void);
-void ps3_os_area_set_rtc_diff(u64 rtc_diff);
 
 /* spu */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/setup.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/setup.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,10 +45,6 @@
 DEFINE_MUTEX(ps3_gpu_mutex);
 EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
 
-#if !defined(CONFIG_SMP)
-static void smp_send_stop(void) {}
-#endif
-
 static union ps3_firmware_version ps3_firmware_version;
 
 void ps3_get_firmware_version(union ps3_firmware_version *v)
@@ -270,8 +266,6 @@ define_machine(ps3) {
 	.init_IRQ			= ps3_init_IRQ,
 	.panic				= ps3_panic,
 	.get_boot_time			= ps3_get_boot_time,
-	.set_rtc_time			= ps3_set_rtc_time,
-	.get_rtc_time			= ps3_get_rtc_time,
 	.set_dabr			= ps3_set_dabr,
 	.calibrate_decr			= ps3_calibrate_decr,
 	.progress			= ps3_progress,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/system-bus.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/system-bus.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/system-bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/system-bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -376,7 +376,7 @@ static int ps3_system_bus_probe(struct d
 	struct ps3_system_bus_driver *drv;
 
 	BUG_ON(!dev);
-	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
 
 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
 	BUG_ON(!drv);
@@ -398,7 +398,7 @@ static int ps3_system_bus_remove(struct
 	struct ps3_system_bus_driver *drv;
 
 	BUG_ON(!dev);
-	pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+	dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
 
 	drv = ps3_system_bus_dev_to_system_bus_drv(dev);
 	BUG_ON(!drv);
@@ -689,7 +689,7 @@ static void ps3_ioc0_unmap_sg(struct dev
 
 static int ps3_dma_supported(struct device *_dev, u64 mask)
 {
-	return mask >= DMA_32BIT_MASK;
+	return mask >= DMA_BIT_MASK(32);
 }
 
 static struct dma_mapping_ops ps3_sb_dma_ops = {
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/time.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/time.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/ps3/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <asm/rtc.h>
 #include <asm/lv1call.h>
@@ -74,23 +75,20 @@ static u64 read_rtc(void)
 	return rtc_val;
 }
 
-int ps3_set_rtc_time(struct rtc_time *tm)
+unsigned long __init ps3_get_boot_time(void)
 {
-	u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-		tm->tm_hour, tm->tm_min, tm->tm_sec);
-
-	ps3_os_area_set_rtc_diff(now - read_rtc());
-	return 0;
+	return read_rtc() + ps3_os_area_get_rtc_diff();
 }
 
-void ps3_get_rtc_time(struct rtc_time *tm)
+static int __init ps3_rtc_init(void)
 {
-	to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
-	tm->tm_year -= 1900;
-	tm->tm_mon -= 1;
-}
+	struct platform_device *pdev;
 
-unsigned long __init ps3_get_boot_time(void)
-{
-	return read_rtc() + ps3_os_area_get_rtc_diff();
+	pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
 }
+
+module_init(ps3_rtc_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/dtl.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/dtl.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/dtl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/dtl.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,279 @@
+/*
+ * Virtual Processor Dispatch Trace Log
+ *
+ * (C) Copyright IBM Corporation 2009
+ *
+ * Author: Jeremy Kerr <jk@ozlabs.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, 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/debugfs.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/firmware.h>
+
+#include "plpar_wrappers.h"
+
+/*
+ * Layout of entries in the hypervisor's DTL buffer. Although we don't
+ * actually access the internals of an entry (we only need to know the size),
+ * we might as well define it here for reference.
+ */
+struct dtl_entry {
+	u8	dispatch_reason;
+	u8	preempt_reason;
+	u16	processor_id;
+	u32	enqueue_to_dispatch_time;
+	u32	ready_to_enqueue_time;
+	u32	waiting_to_ready_time;
+	u64	timebase;
+	u64	fault_addr;
+	u64	srr0;
+	u64	srr1;
+};
+
+struct dtl {
+	struct dtl_entry	*buf;
+	struct dentry		*file;
+	int			cpu;
+	int			buf_entries;
+	u64			last_idx;
+};
+static DEFINE_PER_CPU(struct dtl, dtl);
+
+/*
+ * Dispatch trace log event mask:
+ * 0x7: 0x1: voluntary virtual processor waits
+ *      0x2: time-slice preempts
+ *      0x4: virtual partition memory page faults
+ */
+static u8 dtl_event_mask = 0x7;
+
+
+/*
+ * Size of per-cpu log buffers. Default is just under 16 pages worth.
+ */
+static int dtl_buf_entries = (16 * 85);
+
+
+static int dtl_enable(struct dtl *dtl)
+{
+	unsigned long addr;
+	int ret, hwcpu;
+
+	/* only allow one reader */
+	if (dtl->buf)
+		return -EBUSY;
+
+	/* we need to store the original allocation size for use during read */
+	dtl->buf_entries = dtl_buf_entries;
+
+	dtl->buf = kmalloc_node(dtl->buf_entries * sizeof(struct dtl_entry),
+			GFP_KERNEL, cpu_to_node(dtl->cpu));
+	if (!dtl->buf) {
+		printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
+				__func__, dtl->cpu);
+		return -ENOMEM;
+	}
+
+	/* Register our dtl buffer with the hypervisor. The HV expects the
+	 * buffer size to be passed in the second word of the buffer */
+	((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry);
+
+	hwcpu = get_hard_smp_processor_id(dtl->cpu);
+	addr = __pa(dtl->buf);
+	ret = register_dtl(hwcpu, addr);
+	if (ret) {
+		printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) "
+		       "failed with %d\n", __func__, dtl->cpu, hwcpu, ret);
+		kfree(dtl->buf);
+		return -EIO;
+	}
+
+	/* set our initial buffer indices */
+	dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0;
+
+	/* ensure that our updates to the lppaca fields have occurred before
+	 * we actually enable the logging */
+	smp_wmb();
+
+	/* enable event logging */
+	lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask;
+
+	return 0;
+}
+
+static void dtl_disable(struct dtl *dtl)
+{
+	int hwcpu = get_hard_smp_processor_id(dtl->cpu);
+
+	lppaca[dtl->cpu].dtl_enable_mask = 0x0;
+
+	unregister_dtl(hwcpu, __pa(dtl->buf));
+
+	kfree(dtl->buf);
+	dtl->buf = NULL;
+	dtl->buf_entries = 0;
+}
+
+/* file interface */
+
+static int dtl_file_open(struct inode *inode, struct file *filp)
+{
+	struct dtl *dtl = inode->i_private;
+	int rc;
+
+	rc = dtl_enable(dtl);
+	if (rc)
+		return rc;
+
+	filp->private_data = dtl;
+	return 0;
+}
+
+static int dtl_file_release(struct inode *inode, struct file *filp)
+{
+	struct dtl *dtl = inode->i_private;
+	dtl_disable(dtl);
+	return 0;
+}
+
+static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
+		loff_t *pos)
+{
+	int rc, cur_idx, last_idx, n_read, n_req, read_size;
+	struct dtl *dtl;
+
+	if ((len % sizeof(struct dtl_entry)) != 0)
+		return -EINVAL;
+
+	dtl = filp->private_data;
+
+	/* requested number of entries to read */
+	n_req = len / sizeof(struct dtl_entry);
+
+	/* actual number of entries read */
+	n_read = 0;
+
+	cur_idx = lppaca[dtl->cpu].dtl_idx;
+	last_idx = dtl->last_idx;
+
+	if (cur_idx - last_idx > dtl->buf_entries) {
+		pr_debug("%s: hv buffer overflow for cpu %d, samples lost\n",
+				__func__, dtl->cpu);
+	}
+
+	cur_idx  %= dtl->buf_entries;
+	last_idx %= dtl->buf_entries;
+
+	/* read the tail of the buffer if we've wrapped */
+	if (last_idx > cur_idx) {
+		read_size = min(n_req, dtl->buf_entries - last_idx);
+
+		rc = copy_to_user(buf, &dtl->buf[last_idx],
+				read_size * sizeof(struct dtl_entry));
+		if (rc)
+			return -EFAULT;
+
+		last_idx = 0;
+		n_req -= read_size;
+		n_read += read_size;
+		buf += read_size * sizeof(struct dtl_entry);
+	}
+
+	/* .. and now the head */
+	read_size = min(n_req, cur_idx - last_idx);
+	rc = copy_to_user(buf, &dtl->buf[last_idx],
+			read_size * sizeof(struct dtl_entry));
+	if (rc)
+		return -EFAULT;
+
+	n_read += read_size;
+	dtl->last_idx += n_read;
+
+	return n_read * sizeof(struct dtl_entry);
+}
+
+static struct file_operations dtl_fops = {
+	.open		= dtl_file_open,
+	.release	= dtl_file_release,
+	.read		= dtl_file_read,
+	.llseek		= no_llseek,
+};
+
+static struct dentry *dtl_dir;
+
+static int dtl_setup_file(struct dtl *dtl)
+{
+	char name[10];
+
+	sprintf(name, "cpu-%d", dtl->cpu);
+
+	dtl->file = debugfs_create_file(name, 0400, dtl_dir, dtl, &dtl_fops);
+	if (!dtl->file)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int dtl_init(void)
+{
+	struct dentry *event_mask_file, *buf_entries_file;
+	int rc, i;
+
+	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+		return -ENODEV;
+
+	/* set up common debugfs structure */
+
+	rc = -ENOMEM;
+	dtl_dir = debugfs_create_dir("dtl", powerpc_debugfs_root);
+	if (!dtl_dir) {
+		printk(KERN_WARNING "%s: can't create dtl root dir\n",
+				__func__);
+		goto err;
+	}
+
+	event_mask_file = debugfs_create_x8("dtl_event_mask", 0600,
+				dtl_dir, &dtl_event_mask);
+	buf_entries_file = debugfs_create_u32("dtl_buf_entries", 0600,
+				dtl_dir, &dtl_buf_entries);
+
+	if (!event_mask_file || !buf_entries_file) {
+		printk(KERN_WARNING "%s: can't create dtl files\n", __func__);
+		goto err_remove_dir;
+	}
+
+	/* set up the per-cpu log structures */
+	for_each_possible_cpu(i) {
+		struct dtl *dtl = &per_cpu(dtl, i);
+		dtl->cpu = i;
+
+		rc = dtl_setup_file(dtl);
+		if (rc)
+			goto err_remove_dir;
+	}
+
+	return 0;
+
+err_remove_dir:
+	debugfs_remove_recursive(dtl_dir);
+err:
+	return rc;
+}
+arch_initcall(dtl_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/eeh_driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,6 +79,40 @@ static int irq_in_use(unsigned int irq)
 	return rc;
 }
 
+/**
+ * eeh_disable_irq - disable interrupt for the recovering device
+ */
+static void eeh_disable_irq(struct pci_dev *dev)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+
+	/* Don't disable MSI and MSI-X interrupts. They are
+	 * effectively disabled by the DMA Stopped state
+	 * when an EEH error occurs.
+	*/
+	if (dev->msi_enabled || dev->msix_enabled)
+		return;
+
+	if (!irq_in_use(dev->irq))
+		return;
+
+	PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
+	disable_irq_nosync(dev->irq);
+}
+
+/**
+ * eeh_enable_irq - enable interrupt for the recovering device
+ */
+static void eeh_enable_irq(struct pci_dev *dev)
+{
+	struct device_node *dn = pci_device_to_OF_node(dev);
+
+	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
+		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
+		enable_irq(dev->irq);
+	}
+}
+
 /* ------------------------------------------------------- */
 /**
  * eeh_report_error - report pci error to each device driver
@@ -98,11 +132,8 @@ static void eeh_report_error(struct pci_
 	if (!driver)
 		return;
 
-	if (irq_in_use (dev->irq)) {
-		struct device_node *dn = pci_device_to_OF_node(dev);
-		PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
-		disable_irq_nosync(dev->irq);
-	}
+	eeh_disable_irq(dev);
+
 	if (!driver->err_handler ||
 	    !driver->err_handler->error_detected)
 		return;
@@ -147,15 +178,14 @@ static void eeh_report_reset(struct pci_
 {
 	enum pci_ers_result rc, *res = userdata;
 	struct pci_driver *driver = dev->driver;
-	struct device_node *dn = pci_device_to_OF_node(dev);
 
 	if (!driver)
 		return;
 
-	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
-		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
-		enable_irq(dev->irq);
-	}
+	dev->error_state = pci_channel_io_normal;
+
+	eeh_enable_irq(dev);
+
 	if (!driver->err_handler ||
 	    !driver->err_handler->slot_reset)
 		return;
@@ -174,17 +204,14 @@ static void eeh_report_reset(struct pci_
 static void eeh_report_resume(struct pci_dev *dev, void *userdata)
 {
 	struct pci_driver *driver = dev->driver;
-	struct device_node *dn = pci_device_to_OF_node(dev);
 
 	dev->error_state = pci_channel_io_normal;
 
 	if (!driver)
 		return;
 
-	if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
-		PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
-		enable_irq(dev->irq);
-	}
+	eeh_enable_irq(dev);
+
 	if (!driver->err_handler ||
 	    !driver->err_handler->resume)
 		return;
@@ -208,15 +235,12 @@ static void eeh_report_failure(struct pc
 	if (!driver)
 		return;
 
-	if (irq_in_use (dev->irq)) {
-		struct device_node *dn = pci_device_to_OF_node(dev);
-		PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
-		disable_irq_nosync(dev->irq);
-	}
-	if (!driver->err_handler)
-		return;
-	if (!driver->err_handler->error_detected)
+	eeh_disable_irq(dev);
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->error_detected)
 		return;
+
 	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 config PPC_PSERIES
-	depends on PPC_MULTIPLATFORM && PPC64
+	depends on PPC64 && PPC_BOOK3S
 	bool "IBM pSeries & new (POWER5-based) iSeries"
 	select MPIC
 	select PPC_I8259
@@ -25,6 +25,11 @@ config EEH
 	depends on PPC_PSERIES && PCI
 	default y if !EMBEDDED
 
+config PSERIES_MSI
+       bool
+       depends on PCI_MSI && EEH
+       default y
+
 config SCANLOG
 	tristate "Scanlog dump interface"
 	depends on RTAS_PROC && PPC_PSERIES
@@ -63,3 +68,13 @@ config CMM
 	  makes sense for a system running in an LPAR where the unused pages
 	  will be reused for other LPARs. The interface allows firmware to
 	  balance memory across many LPARs.
+
+config DTL
+	bool "Dispatch Trace Log"
+	depends on PPC_SPLPAR && DEBUG_FS
+	help
+	  SPLPAR machines can log hypervisor preempt & dispatch events to a
+	  kernel buffer. Saying Y here will enable logging these events,
+	  which are accessible through a debugfs file.
+
+	  Say N if you are unsure.
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/Makefile linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/Makefile
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,7 @@ obj-$(CONFIG_SCANLOG)	+= scanlog.o
 obj-$(CONFIG_EEH)	+= eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
 obj-$(CONFIG_KEXEC)	+= kexec.o
 obj-$(CONFIG_PCI)	+= pci.o pci_dlpar.o
-obj-$(CONFIG_PCI_MSI)	+= msi.o
+obj-$(CONFIG_PSERIES_MSI)	+= msi.o
 
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug-cpu.o
 obj-$(CONFIG_MEMORY_HOTPLUG)	+= hotplug-memory.o
@@ -25,3 +25,4 @@ obj-$(CONFIG_HVCS)		+= hvcserver.o
 obj-$(CONFIG_HCALL_STATS)	+= hvCall_inst.o
 obj-$(CONFIG_PHYP_DUMP)	+= phyp_dump.o
 obj-$(CONFIG_CMM)		+= cmm.o
+obj-$(CONFIG_DTL)		+= dtl.o
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/msi.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/msi.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/msi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/msi.c	2009-06-09 23:05:27.000000000 -0400
@@ -71,11 +71,13 @@ static int rtas_change_msi(struct pci_dn
 	} while (rtas_busy_delay(rc));
 
 	/*
-	 * If the RTAS call succeeded, check the number of irqs is actually
-	 * what we asked for. If not, return an error.
+	 * If the RTAS call succeeded, return the number of irqs allocated.
+	 * If not, make sure we return a negative error code.
 	 */
-	if (rc == 0 && rtas_ret[0] != num_irqs)
-		rc = -ENOSPC;
+	if (rc == 0)
+		rc = rtas_ret[0];
+	else if (rc > 0)
+		rc = -rc;
 
 	pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n",
 		 func, num_irqs, rtas_ret[0], rc);
@@ -91,7 +93,7 @@ static void rtas_disable_msi(struct pci_
 	if (!pdn)
 		return;
 
-	if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0))
+	if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
 		pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
 }
 
@@ -132,7 +134,7 @@ static void rtas_teardown_msi_irqs(struc
 	rtas_disable_msi(pdev);
 }
 
-static int check_req_msi(struct pci_dev *pdev, int nvec)
+static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
 {
 	struct device_node *dn;
 	struct pci_dn *pdn;
@@ -144,26 +146,235 @@ static int check_req_msi(struct pci_dev
 
 	dn = pdn->node;
 
-	req_msi = of_get_property(dn, "ibm,req#msi", NULL);
+	req_msi = of_get_property(dn, prop_name, NULL);
 	if (!req_msi) {
-		pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name);
+		pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name);
 		return -ENOENT;
 	}
 
 	if (*req_msi < nvec) {
-		pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec);
-		return -ENOSPC;
+		pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
+
+		if (*req_msi == 0) /* Be paranoid */
+			return -ENOSPC;
+
+		return *req_msi;
 	}
 
 	return 0;
 }
 
+static int check_req_msi(struct pci_dev *pdev, int nvec)
+{
+	return check_req(pdev, nvec, "ibm,req#msi");
+}
+
+static int check_req_msix(struct pci_dev *pdev, int nvec)
+{
+	return check_req(pdev, nvec, "ibm,req#msi-x");
+}
+
+/* Quota calculation */
+
+static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
+{
+	struct device_node *dn;
+	const u32 *p;
+
+	dn = of_node_get(pci_device_to_OF_node(dev));
+	while (dn) {
+		p = of_get_property(dn, "ibm,pe-total-#msi", NULL);
+		if (p) {
+			pr_debug("rtas_msi: found prop on dn %s\n",
+				dn->full_name);
+			*total = *p;
+			return dn;
+		}
+
+		dn = of_get_next_parent(dn);
+	}
+
+	return NULL;
+}
+
+static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
+{
+	struct device_node *dn;
+
+	/* Found our PE and assume 8 at that point. */
+
+	dn = pci_device_to_OF_node(dev);
+	if (!dn)
+		return NULL;
+
+	dn = find_device_pe(dn);
+	if (!dn)
+		return NULL;
+
+	/* We actually want the parent */
+	dn = of_get_parent(dn);
+	if (!dn)
+		return NULL;
+
+	/* Hardcode of 8 for old firmwares */
+	*total = 8;
+	pr_debug("rtas_msi: using PE dn %s\n", dn->full_name);
+
+	return dn;
+}
+
+struct msi_counts {
+	struct device_node *requestor;
+	int num_devices;
+	int request;
+	int quota;
+	int spare;
+	int over_quota;
+};
+
+static void *count_non_bridge_devices(struct device_node *dn, void *data)
+{
+	struct msi_counts *counts = data;
+	const u32 *p;
+	u32 class;
+
+	pr_debug("rtas_msi: counting %s\n", dn->full_name);
+
+	p = of_get_property(dn, "class-code", NULL);
+	class = p ? *p : 0;
+
+	if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
+		counts->num_devices++;
+
+	return NULL;
+}
+
+static void *count_spare_msis(struct device_node *dn, void *data)
+{
+	struct msi_counts *counts = data;
+	const u32 *p;
+	int req;
+
+	if (dn == counts->requestor)
+		req = counts->request;
+	else {
+		/* We don't know if a driver will try to use MSI or MSI-X,
+		 * so we just have to punt and use the larger of the two. */
+		req = 0;
+		p = of_get_property(dn, "ibm,req#msi", NULL);
+		if (p)
+			req = *p;
+
+		p = of_get_property(dn, "ibm,req#msi-x", NULL);
+		if (p)
+			req = max(req, (int)*p);
+	}
+
+	if (req < counts->quota)
+		counts->spare += counts->quota - req;
+	else if (req > counts->quota)
+		counts->over_quota++;
+
+	return NULL;
+}
+
+static int msi_quota_for_device(struct pci_dev *dev, int request)
+{
+	struct device_node *pe_dn;
+	struct msi_counts counts;
+	int total;
+
+	pr_debug("rtas_msi: calc quota for %s, request %d\n", pci_name(dev),
+		  request);
+
+	pe_dn = find_pe_total_msi(dev, &total);
+	if (!pe_dn)
+		pe_dn = find_pe_dn(dev, &total);
+
+	if (!pe_dn) {
+		pr_err("rtas_msi: couldn't find PE for %s\n", pci_name(dev));
+		goto out;
+	}
+
+	pr_debug("rtas_msi: found PE %s\n", pe_dn->full_name);
+
+	memset(&counts, 0, sizeof(struct msi_counts));
+
+	/* Work out how many devices we have below this PE */
+	traverse_pci_devices(pe_dn, count_non_bridge_devices, &counts);
+
+	if (counts.num_devices == 0) {
+		pr_err("rtas_msi: found 0 devices under PE for %s\n",
+			pci_name(dev));
+		goto out;
+	}
+
+	counts.quota = total / counts.num_devices;
+	if (request <= counts.quota)
+		goto out;
+
+	/* else, we have some more calculating to do */
+	counts.requestor = pci_device_to_OF_node(dev);
+	counts.request = request;
+	traverse_pci_devices(pe_dn, count_spare_msis, &counts);
+
+	/* If the quota isn't an integer multiple of the total, we can
+	 * use the remainder as spare MSIs for anyone that wants them. */
+	counts.spare += total % counts.num_devices;
+
+	/* Divide any spare by the number of over-quota requestors */
+	if (counts.over_quota)
+		counts.quota += counts.spare / counts.over_quota;
+
+	/* And finally clamp the request to the possibly adjusted quota */
+	request = min(counts.quota, request);
+
+	pr_debug("rtas_msi: request clamped to quota %d\n", request);
+out:
+	of_node_put(pe_dn);
+
+	return request;
+}
+
 static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 {
+	int quota, rc;
+
 	if (type == PCI_CAP_ID_MSIX)
-		pr_debug("rtas_msi: MSI-X untested, trying anyway.\n");
+		rc = check_req_msix(pdev, nvec);
+	else
+		rc = check_req_msi(pdev, nvec);
 
-	return check_req_msi(pdev, nvec);
+	if (rc)
+		return rc;
+
+	quota = msi_quota_for_device(pdev, nvec);
+
+	if (quota && quota < nvec)
+		return quota;
+
+	return 0;
+}
+
+static int check_msix_entries(struct pci_dev *pdev)
+{
+	struct msi_desc *entry;
+	int expected;
+
+	/* There's no way for us to express to firmware that we want
+	 * a discontiguous, or non-zero based, range of MSI-X entries.
+	 * So we must reject such requests. */
+
+	expected = 0;
+	list_for_each_entry(entry, &pdev->msi_list, list) {
+		if (entry->msi_attrib.entry_nr != expected) {
+			pr_debug("rtas_msi: bad MSI-X entries.\n");
+			return -EINVAL;
+		}
+		expected++;
+	}
+
+	return 0;
 }
 
 static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
@@ -177,6 +388,9 @@ static int rtas_setup_msi_irqs(struct pc
 	if (!pdn)
 		return -ENODEV;
 
+	if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
+		return -EINVAL;
+
 	/*
 	 * Try the new more explicit firmware interface, if that fails fall
 	 * back to the old interface. The old interface is known to never
@@ -185,21 +399,21 @@ static int rtas_setup_msi_irqs(struct pc
 	if (type == PCI_CAP_ID_MSI) {
 		rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
 
-		if (rc) {
+		if (rc < 0) {
 			pr_debug("rtas_msi: trying the old firmware call.\n");
 			rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
 		}
 	} else
 		rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
 
-	if (rc) {
+	if (rc != nvec) {
 		pr_debug("rtas_msi: rtas_change_msi() failed\n");
 		return rc;
 	}
 
 	i = 0;
 	list_for_each_entry(entry, &pdev->msi_list, list) {
-		hwirq = rtas_query_irq_number(pdn, i);
+		hwirq = rtas_query_irq_number(pdn, i++);
 		if (hwirq < 0) {
 			pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
 			return hwirq;
@@ -234,8 +448,8 @@ static void rtas_msi_pci_irq_fixup(struc
 	}
 
 	/* No MSI -> MSIs can't have been assigned by fw, leave LSI */
-	if (check_req_msi(pdev, 1)) {
-		dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n");
+	if (check_req_msi(pdev, 1) && check_req_msix(pdev, 1)) {
+		dev_dbg(&pdev->dev, "rtas_msi: no req#msi/x, nothing to do.\n");
 		return;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/pci_dlpar.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,11 +137,9 @@ EXPORT_SYMBOL_GPL(pcibios_add_pci_device
 struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
 {
 	struct pci_controller *phb;
-	int primary;
 
 	pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
 
-	primary = list_empty(&hose_list);
 	phb = pcibios_alloc_controller(dn);
 	if (!phb)
 		return NULL;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,16 @@ static inline long register_slb_shadow(u
 	return vpa_call(0x3, cpu, vpa);
 }
 
+static inline long unregister_dtl(unsigned long cpu, unsigned long vpa)
+{
+	return vpa_call(0x6, cpu, vpa);
+}
+
+static inline long register_dtl(unsigned long cpu, unsigned long vpa)
+{
+	return vpa_call(0x2, cpu, vpa);
+}
+
 static inline long plpar_page_set_loaned(unsigned long vpa)
 {
 	unsigned long cmo_page_sz = cmo_get_page_size();
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/reconfig.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/reconfig.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2009-06-09 23:05:27.000000000 -0400
@@ -468,9 +468,13 @@ static int do_update_property(char *buf,
 
 		rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
 						  action, value);
+		if (rc == NOTIFY_BAD) {
+			rc = prom_update_property(np, oldprop, newprop);
+			return -ENOMEM;
+		}
 	}
 
-	return rc;
+	return 0;
 }
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/xics.c linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/xics.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/platforms/pseries/xics.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/xics.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,9 +153,10 @@ static int get_irq_server(unsigned int v
 {
 	int server;
 	/* For the moment only implement delivery to all cpus or one cpu */
-	cpumask_t cpumask = irq_desc[virq].affinity;
+	cpumask_t cpumask;
 	cpumask_t tmp = CPU_MASK_NONE;
 
+	cpumask_copy(&cpumask, irq_desc[virq].affinity);
 	if (!distribute_irqs)
 		return default_server;
 
@@ -869,7 +870,7 @@ void xics_migrate_irqs_away(void)
 		       virq, cpu);
 
 		/* Reset affinity to all cpus */
-		irq_desc[virq].affinity = CPU_MASK_ALL;
+		cpumask_setall(irq_desc[virq].affinity);
 		desc->chip->set_affinity(virq, cpu_all_mask);
 unlock:
 		spin_unlock_irqrestore(&desc->lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/bestcomm/Kconfig linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/bestcomm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/bestcomm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/bestcomm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -9,8 +9,8 @@ config PPC_BESTCOMM
 	select PPC_LIB_RHEAP
 	help
 	  BestComm is the name of the communication coprocessor found
-	  on the Freescale MPC5200 family of processor. It's usage is
-	  optionnal for some drivers (like ATA), but required for
+	  on the Freescale MPC5200 family of processor.  Its usage is
+	  optional for some drivers (like ATA), but required for
 	  others (like FEC).
 
 	  If you want to use drivers that require DMA operations,
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm1.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm1.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm1.c	2009-06-09 23:05:27.000000000 -0400
@@ -119,7 +119,6 @@ static irqreturn_t cpm_error_interrupt(i
 
 static struct irqaction cpm_error_irqaction = {
 	.handler = cpm_error_interrupt,
-	.mask = CPU_MASK_NONE,
 	.name = "error",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm2.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm2.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm2.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,7 @@ cpm_cpm2_t __iomem *cpmp; /* Pointer to
  * the communication processor devices.
  */
 cpm2_map_t __iomem *cpm2_immr;
+EXPORT_SYMBOL(cpm2_immr);
 
 #define CPM_MAP_SIZE	(0x40000)	/* 256k - the PQ3 reserve this amount
 					   of space for CPM as it is larger
@@ -129,7 +130,8 @@ void __cpm2_setbrg(uint brg, uint rate,
 		brg -= 4;
 	}
 	bp += brg;
-	val = (((clk / rate) - 1) << 1) | CPM_BRG_EN | src;
+	/* Round the clock divider to the nearest integer. */
+	val = (((clk * 2 / rate) - 1) & ~1) | CPM_BRG_EN | src;
 	if (div16)
 		val |= CPM_BRG_DIV16;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm_common.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm_common.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/cpm_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/cpm_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,7 +56,7 @@ void __init udbg_init_cpm(void)
 {
 	if (cpm_udbg_txdesc) {
 #ifdef CONFIG_CPM2
-		setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO);
+		setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
 #endif
 		udbg_putc = udbg_putc_cpm;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_lbc.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_lbc.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_lbc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_lbc.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *
 
 	spin_lock_irqsave(&fsl_lbc_lock, flags);
 
-	out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
+	out_be32(&fsl_lbc_regs->mar, mar);
 
 	switch (upm->width) {
 	case 8:
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_pci.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_pci.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,12 +1,16 @@
 /*
  * MPC83xx/85xx/86xx PCI/PCIE support routing.
  *
- * Copyright 2007,2008 Freescale Semiconductor, Inc
+ * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ * Copyright 2008-2009 MontaVista Software, Inc.
  *
  * Initial author: Xianghua Xiao <x.xiao@freescale.com>
  * Recode: ZHANG WEI <wei.zhang@freescale.com>
  * Rewrite the routing for Frescale PCI and PCI Express
  * 	Roy Zang <tie-fei.zang@freescale.com>
+ * MPC83xx PCI-Express support:
+ * 	Tony Li <tony.li@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
@@ -27,6 +31,29 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
+static int fsl_pcie_bus_fixup;
+
+static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
+{
+	/* if we aren't a PCIe don't bother */
+	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
+		return;
+
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+	fsl_pcie_bus_fixup = 1;
+	return;
+}
+
+static int __init fsl_pcie_check_link(struct pci_controller *hose)
+{
+	u32 val;
+
+	early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
+	if (val < PCIE_LTSSM_L0)
+		return 1;
+	return 0;
+}
+
 #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
 static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
 	unsigned int index, const struct resource *res,
@@ -159,28 +186,6 @@ static void __init setup_pci_pcsrbar(str
 #endif
 }
 
-static int fsl_pcie_bus_fixup;
-
-static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
-{
-	/* if we aren't a PCIe don't bother */
-	if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
-		return ;
-
-	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
-	fsl_pcie_bus_fixup = 1;
-	return ;
-}
-
-static int __init fsl_pcie_check_link(struct pci_controller *hose)
-{
-	u32 val;
-	early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
-	if (val < PCIE_LTSSM_L0)
-		return 1;
-	return 0;
-}
-
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -294,8 +299,184 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEV
 #endif /* CONFIG_PPC_85xx || 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);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378, quirk_fsl_pcie_header);
+
+struct mpc83xx_pcie_priv {
+	void __iomem *cfg_type0;
+	void __iomem *cfg_type1;
+	u32 dev_base;
+};
+
+/*
+ * With the convention of u-boot, the PCIE outbound window 0 serves
+ * as configuration transactions outbound.
+ */
+#define PEX_OUTWIN0_BAR		0xCA4
+#define PEX_OUTWIN0_TAL		0xCA8
+#define PEX_OUTWIN0_TAH		0xCAC
+
+static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
+{
+	struct pci_controller *hose = bus->sysdata;
+
+	if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	/*
+	 * Workaround for the HW bug: for Type 0 configure transactions the
+	 * PCI-E controller does not check the device number bits and just
+	 * assumes that the device number bits are 0.
+	 */
+	if (bus->number == hose->first_busno ||
+			bus->primary == hose->first_busno) {
+		if (devfn & 0xf8)
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (ppc_md.pci_exclude_device) {
+		if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
+					    unsigned int devfn, int offset)
+{
+	struct pci_controller *hose = bus->sysdata;
+	struct mpc83xx_pcie_priv *pcie = hose->dn->data;
+	u8 bus_no = bus->number - hose->first_busno;
+	u32 dev_base = bus_no << 24 | devfn << 16;
+	int ret;
+
+	ret = mpc83xx_pcie_exclude_device(bus, devfn);
+	if (ret)
+		return NULL;
+
+	offset &= 0xfff;
+
+	/* Type 0 */
+	if (bus->number == hose->first_busno)
+		return pcie->cfg_type0 + offset;
+
+	if (pcie->dev_base == dev_base)
+		goto mapped;
+
+	out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base);
+
+	pcie->dev_base = dev_base;
+mapped:
+	return pcie->cfg_type1 + offset;
+}
+
+static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+				    int offset, int len, u32 *val)
+{
+	void __iomem *cfg_addr;
+
+	cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
+	if (!cfg_addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (len) {
+	case 1:
+		*val = in_8(cfg_addr);
+		break;
+	case 2:
+		*val = in_le16(cfg_addr);
+		break;
+	default:
+		*val = in_le32(cfg_addr);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+				     int offset, int len, u32 val)
+{
+	void __iomem *cfg_addr;
+
+	cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
+	if (!cfg_addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (len) {
+	case 1:
+		out_8(cfg_addr, val);
+		break;
+	case 2:
+		out_le16(cfg_addr, val);
+		break;
+	default:
+		out_le32(cfg_addr, val);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops mpc83xx_pcie_ops = {
+	.read = mpc83xx_pcie_read_config,
+	.write = mpc83xx_pcie_write_config,
+};
+
+static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
+				     struct resource *reg)
+{
+	struct mpc83xx_pcie_priv *pcie;
+	u32 cfg_bar;
+	int ret = -ENOMEM;
+
+	pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return ret;
+
+	pcie->cfg_type0 = ioremap(reg->start, resource_size(reg));
+	if (!pcie->cfg_type0)
+		goto err0;
+
+	cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR);
+	if (!cfg_bar) {
+		/* PCI-E isn't configured. */
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	pcie->cfg_type1 = ioremap(cfg_bar, 0x1000);
+	if (!pcie->cfg_type1)
+		goto err1;
+
+	WARN_ON(hose->dn->data);
+	hose->dn->data = pcie;
+	hose->ops = &mpc83xx_pcie_ops;
+
+	out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
+	out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
+
+	if (fsl_pcie_check_link(hose))
+		hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+
+	return 0;
+err1:
+	iounmap(pcie->cfg_type0);
+err0:
+	kfree(pcie);
+	return ret;
+
+}
+
 int __init mpc83xx_add_bridge(struct device_node *dev)
 {
+	int ret;
 	int len;
 	struct pci_controller *hose;
 	struct resource rsrc_reg;
@@ -303,6 +484,11 @@ int __init mpc83xx_add_bridge(struct dev
 	const int *bus_range;
 	int primary;
 
+	if (!of_device_is_available(dev)) {
+		pr_warning("%s: disabled by the firmware.\n",
+			   dev->full_name);
+		return -ENODEV;
+	}
 	pr_debug("Adding PCI host bridge %s\n", dev->full_name);
 
 	/* Fetch host bridge registers address */
@@ -350,7 +536,14 @@ int __init mpc83xx_add_bridge(struct dev
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
-	setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0);
+	if (of_device_is_compatible(dev, "fsl,mpc8314-pcie")) {
+		ret = mpc83xx_pcie_setup(hose, &rsrc_reg);
+		if (ret)
+			goto err0;
+	} else {
+		setup_indirect_pci(hose, rsrc_cfg.start,
+				   rsrc_cfg.start + 4, 0);
+	}
 
 	printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
 	       "Firmware bus number: %d->%d\n",
@@ -365,5 +558,8 @@ int __init mpc83xx_add_bridge(struct dev
 	pci_process_bridge_OF_ranges(hose, dev, primary);
 
 	return 0;
+err0:
+	pcibios_free_controller(hose);
+	return ret;
 }
 #endif /* CONFIG_PPC_83xx */
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_rio.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_rio.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_rio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_rio.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
 #include <linux/of_platform.h>
@@ -159,6 +160,7 @@ struct rio_msg_rx_ring {
 };
 
 struct rio_priv {
+	struct device *dev;
 	void __iomem *regs_win;
 	struct rio_atmu_regs __iomem *atmu_regs;
 	struct rio_atmu_regs __iomem *maint_atmu_regs;
@@ -484,13 +486,13 @@ int rio_open_outb_mbox(struct rio_mport
 
 	for (i = 0; i < priv->msg_tx_ring.size; i++) {
 		priv->msg_tx_ring.virt_buffer[i] =
-			dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+			dma_alloc_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
 				&priv->msg_tx_ring.phys_buffer[i], GFP_KERNEL);
 		if (!priv->msg_tx_ring.virt_buffer[i]) {
 			rc = -ENOMEM;
 			for (j = 0; j < priv->msg_tx_ring.size; j++)
 				if (priv->msg_tx_ring.virt_buffer[j])
-					dma_free_coherent(NULL,
+					dma_free_coherent(priv->dev,
 							RIO_MSG_BUFFER_SIZE,
 							priv->msg_tx_ring.
 							virt_buffer[j],
@@ -501,7 +503,7 @@ int rio_open_outb_mbox(struct rio_mport
 	}
 
 	/* Initialize outbound message descriptor ring */
-	priv->msg_tx_ring.virt = dma_alloc_coherent(NULL,
+	priv->msg_tx_ring.virt = dma_alloc_coherent(priv->dev,
 				priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
 				&priv->msg_tx_ring.phys, GFP_KERNEL);
 	if (!priv->msg_tx_ring.virt) {
@@ -549,12 +551,13 @@ int rio_open_outb_mbox(struct rio_mport
 	return rc;
 
       out_irq:
-	dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+	dma_free_coherent(priv->dev,
+			  priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
 			  priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
 
       out_dma:
 	for (i = 0; i < priv->msg_tx_ring.size; i++)
-		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+		dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
 				  priv->msg_tx_ring.virt_buffer[i],
 				  priv->msg_tx_ring.phys_buffer[i]);
 
@@ -576,7 +579,8 @@ void rio_close_outb_mbox(struct rio_mpor
 	out_be32(&priv->msg_regs->omr, 0);
 
 	/* Free ring */
-	dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+	dma_free_coherent(priv->dev,
+			  priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
 			  priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
 
 	/* Free interrupt */
@@ -654,7 +658,7 @@ int rio_open_inb_mbox(struct rio_mport *
 		priv->msg_rx_ring.virt_buffer[i] = NULL;
 
 	/* Initialize inbound message ring */
-	priv->msg_rx_ring.virt = dma_alloc_coherent(NULL,
+	priv->msg_rx_ring.virt = dma_alloc_coherent(priv->dev,
 				priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
 				&priv->msg_rx_ring.phys, GFP_KERNEL);
 	if (!priv->msg_rx_ring.virt) {
@@ -673,7 +677,7 @@ int rio_open_inb_mbox(struct rio_mport *
 	rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0,
 			 "msg_rx", (void *)mport);
 	if (rc < 0) {
-		dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+		dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
 				  priv->msg_tx_ring.virt_buffer[i],
 				  priv->msg_tx_ring.phys_buffer[i]);
 		goto out;
@@ -713,7 +717,7 @@ void rio_close_inb_mbox(struct rio_mport
 	out_be32(&priv->msg_regs->imr, 0);
 
 	/* Free ring */
-	dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+	dma_free_coherent(priv->dev, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
 			  priv->msg_rx_ring.virt, priv->msg_rx_ring.phys);
 
 	/* Free interrupt */
@@ -890,7 +894,7 @@ static int fsl_rio_doorbell_init(struct
 	}
 
 	/* Initialize inbound doorbells */
-	priv->dbell_ring.virt = dma_alloc_coherent(NULL, 512 *
+	priv->dbell_ring.virt = dma_alloc_coherent(priv->dev, 512 *
 		    DOORBELL_MESSAGE_SIZE, &priv->dbell_ring.phys, GFP_KERNEL);
 	if (!priv->dbell_ring.virt) {
 		printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
@@ -911,7 +915,7 @@ static int fsl_rio_doorbell_init(struct
 			 "dbell_rx", (void *)mport);
 	if (rc < 0) {
 		iounmap(priv->dbell_win);
-		dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
+		dma_free_coherent(priv->dev, 512 * DOORBELL_MESSAGE_SIZE,
 				  priv->dbell_ring.virt, priv->dbell_ring.phys);
 		printk(KERN_ERR
 		       "MPC85xx RIO: unable to request inbound doorbell irq");
@@ -1087,6 +1091,8 @@ int fsl_rio_setup(struct of_device *dev)
 	rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
 	strcpy(port->name, "RIO0 mport");
 
+	priv->dev = &dev->dev;
+
 	port->ops = ops;
 	port->host_deviceid = fsl_rio_get_hdid(port->id);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_soc.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_soc.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_soc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_soc.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
@@ -207,52 +208,6 @@ static int __init of_add_fixed_phys(void
 arch_initcall(of_add_fixed_phys);
 #endif /* CONFIG_FIXED_PHY */
 
-#ifdef CONFIG_PPC_83xx
-static int __init mpc83xx_wdt_init(void)
-{
-	struct resource r;
-	struct device_node *np;
-	struct platform_device *dev;
-	u32 freq = fsl_get_sys_freq();
-	int ret;
-
-	np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
-
-	if (!np) {
-		ret = -ENODEV;
-		goto nodev;
-	}
-
-	memset(&r, 0, sizeof(r));
-
-	ret = of_address_to_resource(np, 0, &r);
-	if (ret)
-		goto err;
-
-	dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
-	if (IS_ERR(dev)) {
-		ret = PTR_ERR(dev);
-		goto err;
-	}
-
-	ret = platform_device_add_data(dev, &freq, sizeof(freq));
-	if (ret)
-		goto unreg;
-
-	of_node_put(np);
-	return 0;
-
-unreg:
-	platform_device_unregister(dev);
-err:
-	of_node_put(np);
-nodev:
-	return ret;
-}
-
-arch_initcall(mpc83xx_wdt_init);
-#endif
-
 static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
 {
 	if (!phy_type)
@@ -328,6 +283,9 @@ static int __init fsl_usb_of_init(void)
 		struct fsl_usb2_platform_data usb_data;
 		const unsigned char *prop = NULL;
 
+		if (!of_device_is_available(np))
+			continue;
+
 		memset(&r, 0, sizeof(r));
 		memset(&usb_data, 0, sizeof(usb_data));
 
@@ -413,115 +371,6 @@ err:
 
 arch_initcall(fsl_usb_of_init);
 
-static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
-				   struct spi_board_info *board_infos,
-				   unsigned int num_board_infos,
-				   void (*activate_cs)(u8 cs, u8 polarity),
-				   void (*deactivate_cs)(u8 cs, u8 polarity))
-{
-	struct device_node *np;
-	unsigned int i = 0;
-
-	for_each_compatible_node(np, type, compatible) {
-		int ret;
-		unsigned int j;
-		const void *prop;
-		struct resource res[2];
-		struct platform_device *pdev;
-		struct fsl_spi_platform_data pdata = {
-			.activate_cs = activate_cs,
-			.deactivate_cs = deactivate_cs,
-		};
-
-		memset(res, 0, sizeof(res));
-
-		pdata.sysclk = sysclk;
-
-		prop = of_get_property(np, "reg", NULL);
-		if (!prop)
-			goto err;
-		pdata.bus_num = *(u32 *)prop;
-
-		prop = of_get_property(np, "cell-index", NULL);
-		if (prop)
-			i = *(u32 *)prop;
-
-		prop = of_get_property(np, "mode", NULL);
-		if (prop && !strcmp(prop, "cpu-qe"))
-			pdata.qe_mode = 1;
-
-		for (j = 0; j < num_board_infos; j++) {
-			if (board_infos[j].bus_num == pdata.bus_num)
-				pdata.max_chipselect++;
-		}
-
-		if (!pdata.max_chipselect)
-			continue;
-
-		ret = of_address_to_resource(np, 0, &res[0]);
-		if (ret)
-			goto err;
-
-		ret = of_irq_to_resource(np, 0, &res[1]);
-		if (ret == NO_IRQ)
-			goto err;
-
-		pdev = platform_device_alloc("mpc83xx_spi", i);
-		if (!pdev)
-			goto err;
-
-		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
-		if (ret)
-			goto unreg;
-
-		ret = platform_device_add_resources(pdev, res,
-						    ARRAY_SIZE(res));
-		if (ret)
-			goto unreg;
-
-		ret = platform_device_add(pdev);
-		if (ret)
-			goto unreg;
-
-		goto next;
-unreg:
-		platform_device_del(pdev);
-err:
-		pr_err("%s: registration failed\n", np->full_name);
-next:
-		i++;
-	}
-
-	return i;
-}
-
-int __init fsl_spi_init(struct spi_board_info *board_infos,
-			unsigned int num_board_infos,
-			void (*activate_cs)(u8 cs, u8 polarity),
-			void (*deactivate_cs)(u8 cs, u8 polarity))
-{
-	u32 sysclk = -1;
-	int ret;
-
-#ifdef CONFIG_QUICC_ENGINE
-	/* SPI controller is either clocked from QE or SoC clock */
-	sysclk = get_brgfreq();
-#endif
-	if (sysclk == -1) {
-		sysclk = fsl_get_sys_freq();
-		if (sysclk == -1)
-			return -ENODEV;
-	}
-
-	ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
-			       num_board_infos, activate_cs, deactivate_cs);
-	if (!ret)
-		of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
-				 num_board_infos, activate_cs, deactivate_cs);
-
-	return spi_register_board_info(board_infos, num_board_infos);
-}
-
 #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
 static __be32 __iomem *rstcr;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_soc.h linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_soc.h
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/fsl_soc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/fsl_soc.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,8 @@
 
 #include <asm/mmu.h>
 
+struct spi_device;
+
 extern phys_addr_t get_immrbase(void);
 #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
 extern u32 get_brgfreq(void);
@@ -17,11 +19,6 @@ extern u32 fsl_get_sys_freq(void);
 struct spi_board_info;
 struct device_node;
 
-extern int fsl_spi_init(struct spi_board_info *board_infos,
-			unsigned int num_board_infos,
-			void (*activate_cs)(u8 cs, u8 polarity),
-			void (*deactivate_cs)(u8 cs, u8 polarity));
-
 extern void fsl_rstcr_restart(char *cmd);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/ipic.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/ipic.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/ipic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/ipic.c	2009-06-09 23:05:27.000000000 -0400
@@ -568,8 +568,7 @@ static void ipic_ack_irq(unsigned int vi
 
 	spin_lock_irqsave(&ipic_lock, flags);
 
-	temp = ipic_read(ipic->regs, ipic_info[src].ack);
-	temp |= (1 << (31 - ipic_info[src].bit));
+	temp = 1 << (31 - ipic_info[src].bit);
 	ipic_write(ipic->regs, ipic_info[src].ack, temp);
 
 	/* mb() can't guarantee that ack is finished.  But it does finish
@@ -592,8 +591,7 @@ static void ipic_mask_irq_and_ack(unsign
 	temp &= ~(1 << (31 - ipic_info[src].bit));
 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
 
-	temp = ipic_read(ipic->regs, ipic_info[src].ack);
-	temp |= (1 << (31 - ipic_info[src].bit));
+	temp = 1 << (31 - ipic_info[src].bit);
 	ipic_write(ipic->regs, ipic_info[src].ack, temp);
 
 	/* mb() can't guarantee that ack is finished.  But it does finish
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/mpic.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/mpic.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/mpic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/mpic.c	2009-06-09 23:05:27.000000000 -0400
@@ -566,9 +566,10 @@ static void __init mpic_scan_ht_pics(str
 #ifdef CONFIG_SMP
 static int irq_choose_cpu(unsigned int virt_irq)
 {
-	cpumask_t mask = irq_desc[virt_irq].affinity;
+	cpumask_t mask;
 	int cpuid;
 
+	cpumask_copy(&mask, irq_desc[virt_irq].affinity);
 	if (cpus_equal(mask, CPU_MASK_ALL)) {
 		static int irq_rover;
 		static DEFINE_SPINLOCK(irq_rover_lock);
@@ -1056,13 +1057,6 @@ struct mpic * __init mpic_alloc(struct d
 	memset(mpic, 0, sizeof(struct mpic));
 	mpic->name = name;
 
-	mpic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
-				       isu_size, &mpic_host_ops,
-				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
-	if (mpic->irqhost == NULL)
-		return NULL;
-
-	mpic->irqhost->host_data = mpic;
 	mpic->hc_irq = mpic_irq_chip;
 	mpic->hc_irq.typename = name;
 	if (flags & MPIC_PRIMARY)
@@ -1169,6 +1163,12 @@ struct mpic * __init mpic_alloc(struct d
 			mb();
 	}
 
+	/* CoreInt */
+	if (flags & MPIC_ENABLE_COREINT)
+		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
+			   | MPIC_GREG_GCONF_COREINT);
+
 	if (flags & MPIC_ENABLE_MCK)
 		mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
 			   mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
@@ -1206,6 +1206,15 @@ struct mpic * __init mpic_alloc(struct d
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
 	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
 
+	mpic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
+				       isu_size ? isu_size : mpic->num_sources,
+				       &mpic_host_ops,
+				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
+	if (mpic->irqhost == NULL)
+		return NULL;
+
+	mpic->irqhost->host_data = mpic;
+
 	/* Display version */
 	switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
 	case 1:
@@ -1524,6 +1533,34 @@ unsigned int mpic_get_irq(void)
 	return mpic_get_one_irq(mpic);
 }
 
+unsigned int mpic_get_coreint_irq(void)
+{
+#ifdef CONFIG_BOOKE
+	struct mpic *mpic = mpic_primary;
+	u32 src;
+
+	BUG_ON(mpic == NULL);
+
+	src = mfspr(SPRN_EPR);
+
+	if (unlikely(src == mpic->spurious_vec)) {
+		if (mpic->flags & MPIC_SPV_EOI)
+			mpic_eoi(mpic);
+		return NO_IRQ;
+	}
+	if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING "%s: Got protected source %d !\n",
+			       mpic->name, (int)src);
+		return NO_IRQ;
+	}
+
+	return irq_linear_revmap(mpic->irqhost, src);
+#else
+	return NO_IRQ;
+#endif
+}
+
 unsigned int mpic_get_mcirq(void)
 {
 	struct mpic *mpic = mpic_primary;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/msi_bitmap.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/msi_bitmap.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/msi_bitmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/msi_bitmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -141,7 +141,7 @@ void msi_bitmap_free(struct msi_bitmap *
 #define check(x)	\
 	if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__);
 
-void test_basics(void)
+void __init test_basics(void)
 {
 	struct msi_bitmap bmp;
 	int i, size = 512;
@@ -186,7 +186,7 @@ void test_basics(void)
 	kfree(bmp.bitmap);
 }
 
-void test_of_node(void)
+void __init test_of_node(void)
 {
 	u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 };
 	const char *expected_str = "0-9,20-24,28-39,41-99,220-255";
@@ -234,7 +234,7 @@ void test_of_node(void)
 	kfree(bmp.bitmap);
 }
 
-int msi_bitmap_selftest(void)
+int __init msi_bitmap_selftest(void)
 {
 	printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n");
 
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/pmi.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/pmi.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/pmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/pmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ struct pmi_data {
 
 static struct pmi_data *data;
 
-static int pmi_irq_handler(int irq, void *dev_id)
+static irqreturn_t pmi_irq_handler(int irq, void *dev_id)
 {
 	u8 type;
 	int rc;
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/ppc4xx_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1839,6 +1839,8 @@ static int __init ppc4xx_pci_find_bridge
 {
 	struct device_node *np;
 
+	ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
+
 #ifdef CONFIG_PPC4xx_PCI_EXPRESS
 	for_each_compatible_node(np, NULL, "ibm,plb-pciex")
 		ppc4xx_probe_pciex_bridge(np);
diff -druNp linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/xilinx_intc.c linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/xilinx_intc.c
--- linux-libre-2.6.29-gnu1/arch/powerpc/sysdev/xilinx_intc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/xilinx_intc.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,8 +41,32 @@
 
 static struct irq_host *master_irqhost;
 
+#define XILINX_INTC_MAXIRQS	(32)
+
+/* The following table allows the interrupt type, edge or level,
+ * to be cached after being read from the device tree until the interrupt
+ * is mapped
+ */
+static int xilinx_intc_typetable[XILINX_INTC_MAXIRQS];
+
+/* Map the interrupt type from the device tree to the interrupt types
+ * used by the interrupt subsystem
+ */
+static unsigned char xilinx_intc_map_senses[] = {
+	IRQ_TYPE_EDGE_RISING,
+	IRQ_TYPE_EDGE_FALLING,
+	IRQ_TYPE_LEVEL_HIGH,
+	IRQ_TYPE_LEVEL_LOW,
+};
+
 /*
- * IRQ Chip operations
+ * The interrupt controller is setup such that it doesn't work well with
+ * the level interrupt handler in the kernel because the handler acks the
+ * interrupt before calling the application interrupt handler. To deal with
+ * that, we use 2 different irq chips so that different functions can be
+ * used for level and edge type interrupts.
+ *
+ * IRQ Chip common (across level and edge) operations
  */
 static void xilinx_intc_mask(unsigned int virq)
 {
@@ -52,15 +76,54 @@ static void xilinx_intc_mask(unsigned in
 	out_be32(regs + XINTC_CIE, 1 << irq);
 }
 
-static void xilinx_intc_unmask(unsigned int virq)
+static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
+{
+	struct irq_desc *desc = get_irq_desc(virq);
+
+	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+	if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+		desc->status |= IRQ_LEVEL;
+	return 0;
+}
+
+/*
+ * IRQ Chip level operations
+ */
+static void xilinx_intc_level_unmask(unsigned int virq)
 {
 	int irq = virq_to_hw(virq);
 	void * regs = get_irq_chip_data(virq);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
+
+	/* ack level irqs because they can't be acked during
+	 * ack function since the handle_level_irq function
+	 * acks the irq before calling the inerrupt handler
+	 */
+	out_be32(regs + XINTC_IAR, 1 << irq);
 }
 
-static void xilinx_intc_ack(unsigned int virq)
+static struct irq_chip xilinx_intc_level_irqchip = {
+	.typename = "Xilinx Level INTC",
+	.mask = xilinx_intc_mask,
+	.mask_ack = xilinx_intc_mask,
+	.unmask = xilinx_intc_level_unmask,
+	.set_type = xilinx_intc_set_type,
+};
+
+/*
+ * IRQ Chip edge operations
+ */
+static void xilinx_intc_edge_unmask(unsigned int virq)
+{
+	int irq = virq_to_hw(virq);
+	void *regs = get_irq_chip_data(virq);
+	pr_debug("unmask: %d\n", irq);
+	out_be32(regs + XINTC_SIE, 1 << irq);
+}
+
+static void xilinx_intc_edge_ack(unsigned int virq)
 {
 	int irq = virq_to_hw(virq);
 	void * regs = get_irq_chip_data(virq);
@@ -68,27 +131,60 @@ static void xilinx_intc_ack(unsigned int
 	out_be32(regs + XINTC_IAR, 1 << irq);
 }
 
-static struct irq_chip xilinx_intc_irqchip = {
-	.typename = "Xilinx INTC",
+static struct irq_chip xilinx_intc_edge_irqchip = {
+	.typename = "Xilinx Edge  INTC",
 	.mask = xilinx_intc_mask,
-	.unmask = xilinx_intc_unmask,
-	.ack = xilinx_intc_ack,
+	.unmask = xilinx_intc_edge_unmask,
+	.ack = xilinx_intc_edge_ack,
+	.set_type = xilinx_intc_set_type,
 };
 
 /*
  * IRQ Host operations
  */
+
+/**
+ * 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,
+				irq_hw_number_t *out_hwirq,
+				unsigned int *out_flags)
+{
+	if ((intsize < 2) || (intspec[0] >= XILINX_INTC_MAXIRQS))
+		return -EINVAL;
+
+	/* keep a copy of the interrupt type til the interrupt is mapped
+	 */
+	xilinx_intc_typetable[intspec[0]] = xilinx_intc_map_senses[intspec[1]];
+
+	/* Xilinx uses 2 interrupt entries, the 1st being the h/w
+	 * interrupt number, the 2nd being the interrupt type, edge or level
+	 */
+	*out_hwirq = intspec[0];
+	*out_flags = xilinx_intc_map_senses[intspec[1]];
+
+	return 0;
+}
 static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
 				  irq_hw_number_t irq)
 {
 	set_irq_chip_data(virq, h->host_data);
-	set_irq_chip_and_handler(virq, &xilinx_intc_irqchip, handle_level_irq);
-	set_irq_type(virq, IRQ_TYPE_NONE);
+
+	if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH ||
+	    xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) {
+		set_irq_chip_and_handler(virq, &xilinx_intc_level_irqchip,
+			handle_level_irq);
+	} else {
+		set_irq_chip_and_handler(virq, &xilinx_intc_edge_irqchip,
+			handle_edge_irq);
+	}
 	return 0;
 }
 
 static struct irq_host_ops xilinx_intc_ops = {
 	.map = xilinx_intc_map,
+	.xlate = xilinx_intc_xlate,
 };
 
 struct irq_host * __init
@@ -116,7 +212,8 @@ xilinx_intc_init(struct device_node *np)
 	out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
 
 	/* Allocate and initialize an irq_host structure. */
-	irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 32, &xilinx_intc_ops, -1);
+	irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS,
+			     &xilinx_intc_ops, -1);
 	if (!irq)
 		panic(__FILE__ ": Cannot allocate IRQ host\n");
 	irq->host_data = regs;
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/appldata/appldata_base.c linux-libre-2.6.30-gnu1/arch/s390/appldata/appldata_base.c
--- linux-libre-2.6.29-gnu1/arch/s390/appldata/appldata_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/appldata/appldata_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,7 +98,7 @@ static DECLARE_WORK(appldata_work, appld
 /*
  * Ops list
  */
-static DEFINE_SPINLOCK(appldata_ops_lock);
+static DEFINE_MUTEX(appldata_ops_mutex);
 static LIST_HEAD(appldata_ops_list);
 
 
@@ -129,14 +129,14 @@ static void appldata_work_fn(struct work
 
 	i = 0;
 	get_online_cpus();
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	list_for_each(lh, &appldata_ops_list) {
 		ops = list_entry(lh, struct appldata_ops, list);
 		if (ops->active == 1) {
 			ops->callback(ops->data);
 		}
 	}
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 	put_online_cpus();
 }
 
@@ -176,7 +176,7 @@ static void __appldata_mod_vtimer_wrap(v
 		struct vtimer_list *timer;
 		u64    expires;
 	} *args = p;
-	mod_virt_timer(args->timer, args->expires);
+	mod_virt_timer_periodic(args->timer, args->expires);
 }
 
 #define APPLDATA_ADD_TIMER	0
@@ -338,7 +338,7 @@ appldata_generic_handler(ctl_table *ctl,
 	struct list_head *lh;
 
 	found = 0;
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	list_for_each(lh, &appldata_ops_list) {
 		tmp_ops = list_entry(lh, struct appldata_ops, list);
 		if (&tmp_ops->ctl_table[2] == ctl) {
@@ -346,15 +346,15 @@ appldata_generic_handler(ctl_table *ctl,
 		}
 	}
 	if (!found) {
-		spin_unlock(&appldata_ops_lock);
+		mutex_unlock(&appldata_ops_mutex);
 		return -ENODEV;
 	}
 	ops = ctl->data;
 	if (!try_module_get(ops->owner)) {	// protect this function
-		spin_unlock(&appldata_ops_lock);
+		mutex_unlock(&appldata_ops_mutex);
 		return -ENODEV;
 	}
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 
 	if (!*lenp || *ppos) {
 		*lenp = 0;
@@ -378,11 +378,11 @@ appldata_generic_handler(ctl_table *ctl,
 		return -EFAULT;
 	}
 
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	if ((buf[0] == '1') && (ops->active == 0)) {
 		// protect work queue callback
 		if (!try_module_get(ops->owner)) {
-			spin_unlock(&appldata_ops_lock);
+			mutex_unlock(&appldata_ops_mutex);
 			module_put(ops->owner);
 			return -ENODEV;
 		}
@@ -407,7 +407,7 @@ appldata_generic_handler(ctl_table *ctl,
 			       "failed with rc=%d\n", ops->name, rc);
 		module_put(ops->owner);
 	}
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 out:
 	*lenp = len;
 	*ppos += len;
@@ -433,9 +433,9 @@ int appldata_register_ops(struct appldat
 	if (!ops->ctl_table)
 		return -ENOMEM;
 
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	list_add(&ops->list, &appldata_ops_list);
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 
 	ops->ctl_table[0].procname = appldata_proc_name;
 	ops->ctl_table[0].maxlen   = 0;
@@ -452,9 +452,9 @@ int appldata_register_ops(struct appldat
 		goto out;
 	return 0;
 out:
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	list_del(&ops->list);
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 	kfree(ops->ctl_table);
 	return -ENOMEM;
 }
@@ -466,9 +466,9 @@ out:
  */
 void appldata_unregister_ops(struct appldata_ops *ops)
 {
-	spin_lock(&appldata_ops_lock);
+	mutex_lock(&appldata_ops_mutex);
 	list_del(&ops->list);
-	spin_unlock(&appldata_ops_lock);
+	mutex_unlock(&appldata_ops_mutex);
 	unregister_sysctl_table(ops->sysctl_header);
 	kfree(ops->ctl_table);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/appldata/appldata_mem.c linux-libre-2.6.30-gnu1/arch/s390/appldata/appldata_mem.c
--- linux-libre-2.6.29-gnu1/arch/s390/appldata/appldata_mem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/appldata/appldata_mem.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,7 +78,7 @@ static void appldata_get_mem_data(void *
 {
 	/*
 	 * don't put large structures on the stack, we are
-	 * serialized through the appldata_ops_lock and can use static
+	 * serialized through the appldata_ops_mutex and can use static
 	 */
 	static struct sysinfo val;
 	unsigned long ev[NR_VM_EVENT_ITEMS];
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/prng.c linux-libre-2.6.30-gnu1/arch/s390/crypto/prng.c
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/prng.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/prng.c	2009-06-09 23:05:27.000000000 -0400
@@ -201,8 +201,7 @@ out_free:
 static void __exit prng_exit(void)
 {
 	/* wipe me */
-	memset(p->buf, 0, prng_chunk_size);
-	kfree(p->buf);
+	kzfree(p->buf);
 	kfree(p);
 
 	misc_deregister(&prng_dev);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/sha1_s390.c linux-libre-2.6.30-gnu1/arch/s390/crypto/sha1_s390.c
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/sha1_s390.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/sha1_s390.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,17 +23,17 @@
  * any later version.
  *
  */
+#include <crypto/internal/hash.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/crypto.h>
 #include <crypto/sha.h>
 
 #include "crypt_s390.h"
 #include "sha.h"
 
-static void sha1_init(struct crypto_tfm *tfm)
+static int sha1_init(struct shash_desc *desc)
 {
-	struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm);
+	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
 	sctx->state[0] = SHA1_H0;
 	sctx->state[1] = SHA1_H1;
@@ -42,34 +42,36 @@ static void sha1_init(struct crypto_tfm
 	sctx->state[4] = SHA1_H4;
 	sctx->count = 0;
 	sctx->func = KIMD_SHA_1;
+
+	return 0;
 }
 
-static struct crypto_alg alg = {
-	.cra_name	=	"sha1",
-	.cra_driver_name=	"sha1-s390",
-	.cra_priority	=	CRYPT_S390_PRIORITY,
-	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
-	.cra_blocksize	=	SHA1_BLOCK_SIZE,
-	.cra_ctxsize	=	sizeof(struct s390_sha_ctx),
-	.cra_module	=	THIS_MODULE,
-	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
-	.cra_u		=	{ .digest = {
-	.dia_digestsize	=	SHA1_DIGEST_SIZE,
-	.dia_init	=	sha1_init,
-	.dia_update	=	s390_sha_update,
-	.dia_final	=	s390_sha_final } }
+static struct shash_alg alg = {
+	.digestsize	=	SHA1_DIGEST_SIZE,
+	.init		=	sha1_init,
+	.update		=	s390_sha_update,
+	.final		=	s390_sha_final,
+	.descsize	=	sizeof(struct s390_sha_ctx),
+	.base		=	{
+		.cra_name	=	"sha1",
+		.cra_driver_name=	"sha1-s390",
+		.cra_priority	=	CRYPT_S390_PRIORITY,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA1_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
 };
 
 static int __init sha1_s390_init(void)
 {
 	if (!crypt_s390_func_available(KIMD_SHA_1))
 		return -EOPNOTSUPP;
-	return crypto_register_alg(&alg);
+	return crypto_register_shash(&alg);
 }
 
 static void __exit sha1_s390_fini(void)
 {
-	crypto_unregister_alg(&alg);
+	crypto_unregister_shash(&alg);
 }
 
 module_init(sha1_s390_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/sha256_s390.c linux-libre-2.6.30-gnu1/arch/s390/crypto/sha256_s390.c
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/sha256_s390.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/sha256_s390.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,17 +16,17 @@
  * any later version.
  *
  */
+#include <crypto/internal/hash.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/crypto.h>
 #include <crypto/sha.h>
 
 #include "crypt_s390.h"
 #include "sha.h"
 
-static void sha256_init(struct crypto_tfm *tfm)
+static int sha256_init(struct shash_desc *desc)
 {
-	struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm);
+	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
 	sctx->state[0] = SHA256_H0;
 	sctx->state[1] = SHA256_H1;
@@ -38,22 +38,24 @@ static void sha256_init(struct crypto_tf
 	sctx->state[7] = SHA256_H7;
 	sctx->count = 0;
 	sctx->func = KIMD_SHA_256;
+
+	return 0;
 }
 
-static struct crypto_alg alg = {
-	.cra_name	=	"sha256",
-	.cra_driver_name =	"sha256-s390",
-	.cra_priority	=	CRYPT_S390_PRIORITY,
-	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
-	.cra_blocksize	=	SHA256_BLOCK_SIZE,
-	.cra_ctxsize	=	sizeof(struct s390_sha_ctx),
-	.cra_module	=	THIS_MODULE,
-	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
-	.cra_u		=	{ .digest = {
-	.dia_digestsize	=	SHA256_DIGEST_SIZE,
-	.dia_init	=	sha256_init,
-	.dia_update	=	s390_sha_update,
-	.dia_final	=	s390_sha_final } }
+static struct shash_alg alg = {
+	.digestsize	=	SHA256_DIGEST_SIZE,
+	.init		=	sha256_init,
+	.update		=	s390_sha_update,
+	.final		=	s390_sha_final,
+	.descsize	=	sizeof(struct s390_sha_ctx),
+	.base		=	{
+		.cra_name	=	"sha256",
+		.cra_driver_name=	"sha256-s390",
+		.cra_priority	=	CRYPT_S390_PRIORITY,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA256_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
 };
 
 static int sha256_s390_init(void)
@@ -61,12 +63,12 @@ static int sha256_s390_init(void)
 	if (!crypt_s390_func_available(KIMD_SHA_256))
 		return -EOPNOTSUPP;
 
-	return crypto_register_alg(&alg);
+	return crypto_register_shash(&alg);
 }
 
 static void __exit sha256_s390_fini(void)
 {
-	crypto_unregister_alg(&alg);
+	crypto_unregister_shash(&alg);
 }
 
 module_init(sha256_s390_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/sha512_s390.c linux-libre-2.6.30-gnu1/arch/s390/crypto/sha512_s390.c
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/sha512_s390.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/sha512_s390.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,16 +12,16 @@
  * any later version.
  *
  */
+#include <crypto/internal/hash.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/crypto.h>
 
 #include "sha.h"
 #include "crypt_s390.h"
 
-static void sha512_init(struct crypto_tfm *tfm)
+static int sha512_init(struct shash_desc *desc)
 {
-	struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
 
 	*(__u64 *)&ctx->state[0] = 0x6a09e667f3bcc908ULL;
 	*(__u64 *)&ctx->state[2] = 0xbb67ae8584caa73bULL;
@@ -33,29 +33,31 @@ static void sha512_init(struct crypto_tf
 	*(__u64 *)&ctx->state[14] = 0x5be0cd19137e2179ULL;
 	ctx->count = 0;
 	ctx->func = KIMD_SHA_512;
+
+	return 0;
 }
 
-static struct crypto_alg sha512_alg = {
-	.cra_name	=	"sha512",
-	.cra_driver_name =	"sha512-s390",
-	.cra_priority	=	CRYPT_S390_PRIORITY,
-	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
-	.cra_blocksize	=	SHA512_BLOCK_SIZE,
-	.cra_ctxsize	=	sizeof(struct s390_sha_ctx),
-	.cra_module	=	THIS_MODULE,
-	.cra_list	=	LIST_HEAD_INIT(sha512_alg.cra_list),
-	.cra_u		=	{ .digest = {
-	.dia_digestsize	=	SHA512_DIGEST_SIZE,
-	.dia_init	=	sha512_init,
-	.dia_update	=	s390_sha_update,
-	.dia_final	=	s390_sha_final } }
+static struct shash_alg sha512_alg = {
+	.digestsize	=	SHA512_DIGEST_SIZE,
+	.init		=	sha512_init,
+	.update		=	s390_sha_update,
+	.final		=	s390_sha_final,
+	.descsize	=	sizeof(struct s390_sha_ctx),
+	.base		=	{
+		.cra_name	=	"sha512",
+		.cra_driver_name=	"sha512-s390",
+		.cra_priority	=	CRYPT_S390_PRIORITY,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA512_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
 };
 
 MODULE_ALIAS("sha512");
 
-static void sha384_init(struct crypto_tfm *tfm)
+static int sha384_init(struct shash_desc *desc)
 {
-	struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
 
 	*(__u64 *)&ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
 	*(__u64 *)&ctx->state[2] = 0x629a292a367cd507ULL;
@@ -67,22 +69,25 @@ static void sha384_init(struct crypto_tf
 	*(__u64 *)&ctx->state[14] = 0x47b5481dbefa4fa4ULL;
 	ctx->count = 0;
 	ctx->func = KIMD_SHA_512;
+
+	return 0;
 }
 
-static struct crypto_alg sha384_alg = {
-	.cra_name	=	"sha384",
-	.cra_driver_name =	"sha384-s390",
-	.cra_priority	=	CRYPT_S390_PRIORITY,
-	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
-	.cra_blocksize	=	SHA384_BLOCK_SIZE,
-	.cra_ctxsize	=	sizeof(struct s390_sha_ctx),
-	.cra_module	=	THIS_MODULE,
-	.cra_list	=	LIST_HEAD_INIT(sha384_alg.cra_list),
-	.cra_u		=	{ .digest = {
-	.dia_digestsize	=	SHA384_DIGEST_SIZE,
-	.dia_init	=	sha384_init,
-	.dia_update	=	s390_sha_update,
-	.dia_final	=	s390_sha_final } }
+static struct shash_alg sha384_alg = {
+	.digestsize	=	SHA384_DIGEST_SIZE,
+	.init		=	sha384_init,
+	.update		=	s390_sha_update,
+	.final		=	s390_sha_final,
+	.descsize	=	sizeof(struct s390_sha_ctx),
+	.base		=	{
+		.cra_name	=	"sha384",
+		.cra_driver_name=	"sha384-s390",
+		.cra_priority	=	CRYPT_S390_PRIORITY,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA384_BLOCK_SIZE,
+		.cra_ctxsize	=	sizeof(struct s390_sha_ctx),
+		.cra_module	=	THIS_MODULE,
+	}
 };
 
 MODULE_ALIAS("sha384");
@@ -93,18 +98,18 @@ static int __init init(void)
 
 	if (!crypt_s390_func_available(KIMD_SHA_512))
 		return -EOPNOTSUPP;
-	if ((ret = crypto_register_alg(&sha512_alg)) < 0)
+	if ((ret = crypto_register_shash(&sha512_alg)) < 0)
 		goto out;
-	if ((ret = crypto_register_alg(&sha384_alg)) < 0)
-		crypto_unregister_alg(&sha512_alg);
+	if ((ret = crypto_register_shash(&sha384_alg)) < 0)
+		crypto_unregister_shash(&sha512_alg);
 out:
 	return ret;
 }
 
 static void __exit fini(void)
 {
-	crypto_unregister_alg(&sha512_alg);
-	crypto_unregister_alg(&sha384_alg);
+	crypto_unregister_shash(&sha512_alg);
+	crypto_unregister_shash(&sha384_alg);
 }
 
 module_init(init);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/sha_common.c linux-libre-2.6.30-gnu1/arch/s390/crypto/sha_common.c
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/sha_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/sha_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,14 +13,14 @@
  *
  */
 
-#include <linux/crypto.h>
+#include <crypto/internal/hash.h>
 #include "sha.h"
 #include "crypt_s390.h"
 
-void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
 {
-	struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
-	unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
+	unsigned int bsize = crypto_shash_blocksize(desc->tfm);
 	unsigned int index;
 	int ret;
 
@@ -51,13 +51,15 @@ void s390_sha_update(struct crypto_tfm *
 store:
 	if (len)
 		memcpy(ctx->buf + index , data, len);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(s390_sha_update);
 
-void s390_sha_final(struct crypto_tfm *tfm, u8 *out)
+int s390_sha_final(struct shash_desc *desc, u8 *out)
 {
-	struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
-	unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
+	unsigned int bsize = crypto_shash_blocksize(desc->tfm);
 	u64 bits;
 	unsigned int index, end, plen;
 	int ret;
@@ -87,9 +89,11 @@ void s390_sha_final(struct crypto_tfm *t
 	BUG_ON(ret != end);
 
 	/* copy digest to out */
-	memcpy(out, ctx->state, crypto_hash_digestsize(crypto_hash_cast(tfm)));
+	memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
 	/* wipe context */
 	memset(ctx, 0, sizeof *ctx);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(s390_sha_final);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/crypto/sha.h linux-libre-2.6.30-gnu1/arch/s390/crypto/sha.h
--- linux-libre-2.6.29-gnu1/arch/s390/crypto/sha.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/crypto/sha.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,9 @@ struct s390_sha_ctx {
 	int func;		/* KIMD function to use */
 };
 
-void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len);
-void s390_sha_final(struct crypto_tfm *tfm, u8 *out);
+struct shash_desc;
+
+int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len);
+int s390_sha_final(struct shash_desc *desc, u8 *out);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/defconfig linux-libre-2.6.30-gnu1/arch/s390/defconfig
--- linux-libre-2.6.29-gnu1/arch/s390/defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Wed Feb 11 10:07:16 2009
+# Linux kernel version: 2.6.30-rc3
+# Thu Apr 23 09:29:52 2009
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_NO_DMA=y
 CONFIG_GENERIC_LOCKBREAK=y
 CONFIG_PGSTE=y
 CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_S390=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -37,6 +38,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=y
@@ -77,21 +79,24 @@ CONFIG_IPC_NS=y
 # 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 is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EMBEDDED is not set
 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_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
@@ -99,10 +104,12 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 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=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -111,6 +118,8 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -124,7 +133,6 @@ CONFIG_MODVERSIONS=y
 CONFIG_INIT_ALL_POSSIBLE=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
@@ -211,11 +219,12 @@ 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
 
 #
 # I/O subsystem configuration
 #
-CONFIG_MACHCHK_WARNING=y
 CONFIG_QDIO=y
 CONFIG_CHSC_SCH=m
 
@@ -247,12 +256,12 @@ CONFIG_S390_HYPFS_FS=y
 CONFIG_KEXEC=y
 # CONFIG_ZFCPDUMP is not set
 CONFIG_S390_GUEST=y
+CONFIG_SECCOMP=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -374,6 +383,7 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -438,7 +448,6 @@ CONFIG_CAN_BCM=m
 CONFIG_CAN_VCAN=m
 # CONFIG_CAN_DEBUG_DEVICES is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -537,6 +546,7 @@ CONFIG_SCSI_FC_ATTRS=y
 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_ZFCP=y
 CONFIG_SCSI_DH=m
@@ -544,6 +554,10 @@ 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_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_AUTODETECT=y
@@ -564,6 +578,7 @@ CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 # CONFIG_DM_UEVENT is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_IFB is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -667,6 +682,7 @@ CONFIG_S390_VMUR=m
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 CONFIG_ACCESSIBILITY=y
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_STAGING is not set
 
 #
@@ -676,6 +692,7 @@ 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
@@ -701,6 +718,11 @@ CONFIG_INOTIFY_USER=y
 CONFIG_GENERIC_ACL=y
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -744,6 +766,8 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_EXOFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -758,7 +782,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -806,6 +829,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_HUNG_TASK is not set
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -830,7 +854,6 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
@@ -840,7 +863,9 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # 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_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -850,14 +875,17 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # 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_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_SAMPLES=y
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 
 #
 # Security options
@@ -882,10 +910,12 @@ CONFIG_CRYPTO_HASH=m
 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 is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -954,6 +984,7 @@ CONFIG_CRYPTO_SEED=m
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 
 #
@@ -969,6 +1000,7 @@ CONFIG_CRYPTO_SHA512_S390=m
 # CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_AES_S390 is not set
 CONFIG_S390_PRNG=m
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -982,9 +1014,14 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=m
 CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
 CONFIG_LZO_DECOMPRESS=m
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_NLATTR=y
 CONFIG_HAVE_KVM=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/hypfs/hypfs_diag.c linux-libre-2.6.30-gnu1/arch/s390/hypfs/hypfs_diag.c
--- linux-libre-2.6.29-gnu1/arch/s390/hypfs/hypfs_diag.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/hypfs/hypfs_diag.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,8 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <asm/ebcdic.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/bitops.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/bitops.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/bitops.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/bitops.h	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@
  * with operation of the form "set_bit(bitnr, flags)".
  */
 
-/* bitmap tables from arch/S390/kernel/bitmap.S */
+/* bitmap tables from arch/s390/kernel/bitmap.c */
 extern const char _oi_bitmap[];
 extern const char _ni_bitmap[];
 extern const char _zb_findmap[];
@@ -525,16 +525,16 @@ static inline unsigned long __ffs_word_l
 static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
 {
 #ifdef __s390x__
-	if (likely((word & 0xffffffff) == 0xffffffff)) {
+	if ((word & 0xffffffff) == 0xffffffff) {
 		word >>= 32;
 		nr += 32;
 	}
 #endif
-	if (likely((word & 0xffff) == 0xffff)) {
+	if ((word & 0xffff) == 0xffff) {
 		word >>= 16;
 		nr += 16;
 	}
-	if (likely((word & 0xff) == 0xff)) {
+	if ((word & 0xff) == 0xff) {
 		word >>= 8;
 		nr += 8;
 	}
@@ -549,16 +549,16 @@ static inline unsigned long __ffz_word(u
 static inline unsigned long __ffs_word(unsigned long nr, unsigned long word)
 {
 #ifdef __s390x__
-	if (likely((word & 0xffffffff) == 0)) {
+	if ((word & 0xffffffff) == 0) {
 		word >>= 32;
 		nr += 32;
 	}
 #endif
-	if (likely((word & 0xffff) == 0)) {
+	if ((word & 0xffff) == 0) {
 		word >>= 16;
 		nr += 16;
 	}
-	if (likely((word & 0xff) == 0)) {
+	if ((word & 0xff) == 0) {
 		word >>= 8;
 		nr += 8;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/cio.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/cio.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/cio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/cio.h	2009-06-09 23:05:27.000000000 -0400
@@ -456,6 +456,8 @@ struct ciw {
 #define CIO_OPER       0x0004
 /* Sick revalidation of device. */
 #define CIO_REVALIDATE 0x0008
+/* Device did not respond in time. */
+#define CIO_BOXED      0x0010
 
 /**
  * struct ccw_dev_id - unique identifier for ccw devices
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/cpuid.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/cpuid.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/cpuid.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/cpuid.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Hartmut Penner <hp@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Christian Ehrhardt <ehrhardt@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_CPUID_H_
+#define _ASM_S390_CPUID_H_
+
+/*
+ *  CPU type and hardware bug flags. Kept separately for each CPU.
+ *  Members of this structure are referenced in head.S, so think twice
+ *  before touching them. [mj]
+ */
+
+typedef struct
+{
+	unsigned int version :	8;
+	unsigned int ident   : 24;
+	unsigned int machine : 16;
+	unsigned int unused  : 16;
+} __attribute__ ((packed)) cpuid_t;
+
+#endif /* _ASM_S390_CPUID_H_ */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/cputime.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/cputime.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/cputime.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/cputime.h	2009-06-09 23:05:27.000000000 -0400
@@ -174,4 +174,8 @@ cputime64_to_clock_t(cputime64_t cputime
        return __div(cputime, 4096000000ULL / USER_HZ);
 }
 
+cputime64_t s390_get_idle_time(int cpu);
+
+#define arch_idle_time(cpu) s390_get_idle_time(cpu)
+
 #endif /* _S390_CPUTIME_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/crw.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/crw.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/crw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/crw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ *   Data definitions for channel report processing
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_CRW_H
+#define _ASM_S390_CRW_H
+
+#include <linux/types.h>
+
+/*
+ * Channel Report Word
+ */
+struct crw {
+	__u32 res1 :  1;   /* reserved zero */
+	__u32 slct :  1;   /* solicited */
+	__u32 oflw :  1;   /* overflow */
+	__u32 chn  :  1;   /* chained */
+	__u32 rsc  :  4;   /* reporting source code */
+	__u32 anc  :  1;   /* ancillary report */
+	__u32 res2 :  1;   /* reserved zero */
+	__u32 erc  :  6;   /* error-recovery code */
+	__u32 rsid : 16;   /* reporting-source ID */
+} __attribute__ ((packed));
+
+typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
+
+extern int crw_register_handler(int rsc, crw_handler_t handler);
+extern void crw_unregister_handler(int rsc);
+extern void crw_handle_channel_report(void);
+
+#define NR_RSCS 16
+
+#define CRW_RSC_MONITOR  0x2  /* monitoring facility */
+#define CRW_RSC_SCH	 0x3  /* subchannel */
+#define CRW_RSC_CPATH	 0x4  /* channel path */
+#define CRW_RSC_CONFIG	 0x9  /* configuration-alert facility */
+#define CRW_RSC_CSS	 0xB  /* channel subsystem */
+
+#define CRW_ERC_EVENT	 0x00 /* event information pending */
+#define CRW_ERC_AVAIL	 0x01 /* available */
+#define CRW_ERC_INIT	 0x02 /* initialized */
+#define CRW_ERC_TERROR	 0x03 /* temporary error */
+#define CRW_ERC_IPARM	 0x04 /* installed parm initialized */
+#define CRW_ERC_TERM	 0x05 /* terminal */
+#define CRW_ERC_PERRN	 0x06 /* perm. error, fac. not init */
+#define CRW_ERC_PERRI	 0x07 /* perm. error, facility init */
+#define CRW_ERC_PMOD	 0x08 /* installed parameters modified */
+
+static inline int stcrw(struct crw *pcrw)
+{
+	int ccode;
+
+	asm volatile(
+		"	stcrw	0(%2)\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: "=d" (ccode), "=m" (*pcrw)
+		: "a" (pcrw)
+		: "cc" );
+	return ccode;
+}
+
+#endif /* _ASM_S390_CRW_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/dasd.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/dasd.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/dasd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/dasd.h	2009-06-09 23:05:27.000000000 -0400
@@ -162,15 +162,15 @@ typedef struct dasd_profile_info_t {
         unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
 } dasd_profile_info_t;
 
-/* 
+/*
  * struct format_data_t
  * represents all data necessary to format a dasd
  */
 typedef struct format_data_t {
-	int start_unit; /* from track */
-	int stop_unit;  /* to track */
-	int blksize;    /* sectorsize */
-        int intensity;  
+	unsigned int start_unit; /* from track */
+	unsigned int stop_unit;  /* to track */
+	unsigned int blksize;	 /* sectorsize */
+	unsigned int intensity;
 } format_data_t;
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/idals.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/idals.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/idals.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/idals.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,24 +44,18 @@ idal_is_needed(void *vaddr, unsigned int
 /*
  * Return the number of idal words needed for an address/length pair.
  */
-static inline unsigned int
-idal_nr_words(void *vaddr, unsigned int length)
+static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
 {
-#ifdef __s390x__
-	if (idal_is_needed(vaddr, length))
-		return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length + 
-			(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
-#endif
-	return 0;
+	return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
+		(IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
 }
 
 /*
  * Create the list of idal words for an address/length pair.
  */
-static inline unsigned long *
-idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
+static inline unsigned long *idal_create_words(unsigned long *idaws,
+					       void *vaddr, unsigned int length)
 {
-#ifdef __s390x__
 	unsigned long paddr;
 	unsigned int cidaw;
 
@@ -74,7 +68,6 @@ idal_create_words(unsigned long *idaws,
 		paddr += IDA_BLOCK_SIZE;
 		*idaws++ = paddr;
 	}
-#endif
 	return idaws;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/kvm.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/kvm.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/kvm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/kvm.h	2009-06-09 23:05:27.000000000 -0400
@@ -42,4 +42,11 @@ struct kvm_fpu {
 	__u64 fprs[16];
 };
 
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/kvm_host.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/kvm_host.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/kvm_host.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,15 +15,13 @@
 #define ASM_KVM_HOST_H
 #include <linux/kvm_host.h>
 #include <asm/debug.h>
+#include <asm/cpuid.h>
 
 #define KVM_MAX_VCPUS 64
 #define KVM_MEMORY_SLOTS 32
 /* memory slots that does not exposed to userspace */
 #define KVM_PRIVATE_MEM_SLOTS 4
 
-struct kvm_guest_debug {
-};
-
 struct sca_entry {
 	atomic_t scn;
 	__u64	reserved;
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/lowcore.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/lowcore.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/lowcore.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/lowcore.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,136 +11,127 @@
 #ifndef _ASM_S390_LOWCORE_H
 #define _ASM_S390_LOWCORE_H
 
-#ifndef __s390x__
-#define __LC_EXT_OLD_PSW                0x018
-#define __LC_SVC_OLD_PSW                0x020
-#define __LC_PGM_OLD_PSW                0x028
-#define __LC_MCK_OLD_PSW                0x030
-#define __LC_IO_OLD_PSW                 0x038
-#define __LC_EXT_NEW_PSW                0x058
-#define __LC_SVC_NEW_PSW                0x060
-#define __LC_PGM_NEW_PSW                0x068
-#define __LC_MCK_NEW_PSW                0x070
-#define __LC_IO_NEW_PSW                 0x078
-#else /* !__s390x__ */
-#define __LC_EXT_OLD_PSW                0x0130
-#define __LC_SVC_OLD_PSW                0x0140
-#define __LC_PGM_OLD_PSW                0x0150
-#define __LC_MCK_OLD_PSW                0x0160
-#define __LC_IO_OLD_PSW                 0x0170
-#define __LC_EXT_NEW_PSW                0x01b0
-#define __LC_SVC_NEW_PSW                0x01c0
-#define __LC_PGM_NEW_PSW                0x01d0
-#define __LC_MCK_NEW_PSW                0x01e0
-#define __LC_IO_NEW_PSW                 0x01f0
-#endif /* !__s390x__ */
-
-#define __LC_IPL_PARMBLOCK_PTR		0x014
-#define __LC_EXT_PARAMS                 0x080
-#define __LC_CPU_ADDRESS                0x084
-#define __LC_EXT_INT_CODE               0x086
-
-#define __LC_SVC_ILC                    0x088
-#define __LC_SVC_INT_CODE               0x08A
-#define __LC_PGM_ILC                    0x08C
-#define __LC_PGM_INT_CODE               0x08E
-
-#define __LC_PER_ATMID			0x096
-#define __LC_PER_ADDRESS		0x098
-#define __LC_PER_ACCESS_ID		0x0A1
-#define __LC_AR_MODE_ID			0x0A3
-
-#define __LC_SUBCHANNEL_ID              0x0B8
-#define __LC_SUBCHANNEL_NR              0x0BA
-#define __LC_IO_INT_PARM                0x0BC
-#define __LC_IO_INT_WORD                0x0C0
-#define __LC_MCCK_CODE                  0x0E8
-
-#define __LC_LAST_BREAK 		0x110
+#define __LC_IPL_PARMBLOCK_PTR		0x0014
+#define __LC_EXT_PARAMS			0x0080
+#define __LC_CPU_ADDRESS		0x0084
+#define __LC_EXT_INT_CODE		0x0086
 
-#define __LC_RETURN_PSW                 0x200
+#define __LC_SVC_ILC			0x0088
+#define __LC_SVC_INT_CODE		0x008a
+#define __LC_PGM_ILC			0x008c
+#define __LC_PGM_INT_CODE		0x008e
 
-#define __LC_SAVE_AREA                  0xC00
+#define __LC_PER_ATMID			0x0096
+#define __LC_PER_ADDRESS		0x0098
+#define __LC_PER_ACCESS_ID		0x00a1
+#define __LC_AR_MODE_ID			0x00a3
 
-#ifndef __s390x__
-#define __LC_IRB			0x208
-#define __LC_SYNC_ENTER_TIMER		0x248
-#define __LC_ASYNC_ENTER_TIMER		0x250
-#define __LC_EXIT_TIMER			0x258
-#define __LC_USER_TIMER			0x260
-#define __LC_SYSTEM_TIMER		0x268
-#define __LC_STEAL_TIMER		0x270
-#define __LC_LAST_UPDATE_TIMER		0x278
-#define __LC_LAST_UPDATE_CLOCK		0x280
-#define __LC_RETURN_MCCK_PSW            0x288
-#define __LC_KERNEL_STACK               0xC40
-#define __LC_THREAD_INFO		0xC44
-#define __LC_ASYNC_STACK                0xC48
-#define __LC_KERNEL_ASCE		0xC4C
-#define __LC_USER_ASCE			0xC50
-#define __LC_PANIC_STACK                0xC54
-#define __LC_CPUID                      0xC60
-#define __LC_CPUADDR                    0xC68
-#define __LC_IPLDEV                     0xC7C
-#define __LC_CURRENT			0xC90
-#define __LC_INT_CLOCK			0xC98
-#else /* __s390x__ */
-#define __LC_IRB			0x210
-#define __LC_SYNC_ENTER_TIMER		0x250
-#define __LC_ASYNC_ENTER_TIMER		0x258
-#define __LC_EXIT_TIMER			0x260
-#define __LC_USER_TIMER			0x268
-#define __LC_SYSTEM_TIMER		0x270
-#define __LC_STEAL_TIMER		0x278
-#define __LC_LAST_UPDATE_TIMER		0x280
-#define __LC_LAST_UPDATE_CLOCK		0x288
-#define __LC_RETURN_MCCK_PSW            0x290
-#define __LC_KERNEL_STACK               0xD40
-#define __LC_THREAD_INFO		0xD48
-#define __LC_ASYNC_STACK                0xD50
-#define __LC_KERNEL_ASCE		0xD58
-#define __LC_USER_ASCE			0xD60
-#define __LC_PANIC_STACK                0xD68
-#define __LC_CPUID			0xD80
-#define __LC_CPUADDR			0xD88
-#define __LC_IPLDEV                     0xDB8
-#define __LC_CURRENT			0xDD8
-#define __LC_INT_CLOCK			0xDE8
-#define __LC_VDSO_PER_CPU		0xE38
-#endif /* __s390x__ */
+#define __LC_SUBCHANNEL_ID		0x00b8
+#define __LC_SUBCHANNEL_NR		0x00ba
+#define __LC_IO_INT_PARM		0x00bc
+#define __LC_IO_INT_WORD		0x00c0
+#define __LC_MCCK_CODE			0x00e8
 
-#define __LC_PASTE			0xE40
+#define __LC_DUMP_REIPL			0x0e00
 
-#define __LC_PANIC_MAGIC		0xE00
 #ifndef __s390x__
-#define __LC_PFAULT_INTPARM             0x080
-#define __LC_CPU_TIMER_SAVE_AREA        0x0D8
-#define __LC_CLOCK_COMP_SAVE_AREA	0x0E0
-#define __LC_PSW_SAVE_AREA		0x100
-#define __LC_PREFIX_SAVE_AREA		0x108
-#define __LC_AREGS_SAVE_AREA            0x120
-#define __LC_FPREGS_SAVE_AREA		0x160
-#define __LC_GPREGS_SAVE_AREA           0x180
-#define __LC_CREGS_SAVE_AREA            0x1C0
+#define __LC_EXT_OLD_PSW		0x0018
+#define __LC_SVC_OLD_PSW		0x0020
+#define __LC_PGM_OLD_PSW		0x0028
+#define __LC_MCK_OLD_PSW		0x0030
+#define __LC_IO_OLD_PSW			0x0038
+#define __LC_EXT_NEW_PSW		0x0058
+#define __LC_SVC_NEW_PSW		0x0060
+#define __LC_PGM_NEW_PSW		0x0068
+#define __LC_MCK_NEW_PSW		0x0070
+#define __LC_IO_NEW_PSW			0x0078
+#define __LC_SAVE_AREA			0x0200
+#define __LC_RETURN_PSW			0x0240
+#define __LC_RETURN_MCCK_PSW		0x0248
+#define __LC_SYNC_ENTER_TIMER		0x0250
+#define __LC_ASYNC_ENTER_TIMER		0x0258
+#define __LC_EXIT_TIMER			0x0260
+#define __LC_USER_TIMER			0x0268
+#define __LC_SYSTEM_TIMER		0x0270
+#define __LC_STEAL_TIMER		0x0278
+#define __LC_LAST_UPDATE_TIMER		0x0280
+#define __LC_LAST_UPDATE_CLOCK		0x0288
+#define __LC_CURRENT			0x0290
+#define __LC_THREAD_INFO		0x0294
+#define __LC_KERNEL_STACK		0x0298
+#define __LC_ASYNC_STACK		0x029c
+#define __LC_PANIC_STACK		0x02a0
+#define __LC_KERNEL_ASCE		0x02a4
+#define __LC_USER_ASCE			0x02a8
+#define __LC_USER_EXEC_ASCE		0x02ac
+#define __LC_CPUID			0x02b0
+#define __LC_INT_CLOCK			0x02c8
+#define __LC_MACHINE_FLAGS		0x02d8
+#define __LC_IRB			0x0300
+#define __LC_PFAULT_INTPARM		0x0080
+#define __LC_CPU_TIMER_SAVE_AREA	0x00d8
+#define __LC_CLOCK_COMP_SAVE_AREA	0x00e0
+#define __LC_PSW_SAVE_AREA		0x0100
+#define __LC_PREFIX_SAVE_AREA		0x0108
+#define __LC_AREGS_SAVE_AREA		0x0120
+#define __LC_FPREGS_SAVE_AREA		0x0160
+#define __LC_GPREGS_SAVE_AREA		0x0180
+#define __LC_CREGS_SAVE_AREA		0x01c0
 #else /* __s390x__ */
-#define __LC_PFAULT_INTPARM             0x11B8
+#define __LC_LAST_BREAK			0x0110
+#define __LC_EXT_OLD_PSW		0x0130
+#define __LC_SVC_OLD_PSW		0x0140
+#define __LC_PGM_OLD_PSW		0x0150
+#define __LC_MCK_OLD_PSW		0x0160
+#define __LC_IO_OLD_PSW			0x0170
+#define __LC_EXT_NEW_PSW		0x01b0
+#define __LC_SVC_NEW_PSW		0x01c0
+#define __LC_PGM_NEW_PSW		0x01d0
+#define __LC_MCK_NEW_PSW		0x01e0
+#define __LC_IO_NEW_PSW			0x01f0
+#define __LC_SAVE_AREA			0x0200
+#define __LC_RETURN_PSW			0x0280
+#define __LC_RETURN_MCCK_PSW		0x0290
+#define __LC_SYNC_ENTER_TIMER		0x02a0
+#define __LC_ASYNC_ENTER_TIMER		0x02a8
+#define __LC_EXIT_TIMER			0x02b0
+#define __LC_USER_TIMER			0x02b8
+#define __LC_SYSTEM_TIMER		0x02c0
+#define __LC_STEAL_TIMER		0x02c8
+#define __LC_LAST_UPDATE_TIMER		0x02d0
+#define __LC_LAST_UPDATE_CLOCK		0x02d8
+#define __LC_CURRENT			0x02e0
+#define __LC_THREAD_INFO		0x02e8
+#define __LC_KERNEL_STACK		0x02f0
+#define __LC_ASYNC_STACK		0x02f8
+#define __LC_PANIC_STACK		0x0300
+#define __LC_KERNEL_ASCE		0x0308
+#define __LC_USER_ASCE			0x0310
+#define __LC_USER_EXEC_ASCE		0x0318
+#define __LC_CPUID			0x0320
+#define __LC_INT_CLOCK			0x0340
+#define __LC_VDSO_PER_CPU		0x0350
+#define __LC_MACHINE_FLAGS		0x0358
+#define __LC_IRB			0x0380
+#define __LC_PASTE			0x03c0
+#define __LC_PFAULT_INTPARM		0x11b8
 #define __LC_FPREGS_SAVE_AREA		0x1200
-#define __LC_GPREGS_SAVE_AREA           0x1280
+#define __LC_GPREGS_SAVE_AREA		0x1280
 #define __LC_PSW_SAVE_AREA		0x1300
 #define __LC_PREFIX_SAVE_AREA		0x1318
-#define __LC_FP_CREG_SAVE_AREA		0x131C
+#define __LC_FP_CREG_SAVE_AREA		0x131c
 #define __LC_TODREG_SAVE_AREA		0x1324
-#define __LC_CPU_TIMER_SAVE_AREA        0x1328
+#define __LC_CPU_TIMER_SAVE_AREA	0x1328
 #define __LC_CLOCK_COMP_SAVE_AREA	0x1331
-#define __LC_AREGS_SAVE_AREA            0x1340
-#define __LC_CREGS_SAVE_AREA            0x1380
+#define __LC_AREGS_SAVE_AREA		0x1340
+#define __LC_CREGS_SAVE_AREA		0x1380
 #endif /* __s390x__ */
 
 #ifndef __ASSEMBLY__
 
-#include <asm/processor.h>
+#include <asm/cpuid.h>
+#include <asm/ptrace.h>
 #include <linux/types.h>
-#include <asm/sigp.h>
 
 void restart_int_handler(void);
 void ext_int_handler(void);
@@ -198,222 +189,242 @@ union save_area {
 struct _lowcore
 {
 #ifndef __s390x__
-        /* prefix area: defined by architecture */
-	psw_t        restart_psw;              /* 0x000 */
-	__u32        ccw2[4];                  /* 0x008 */
-	psw_t        external_old_psw;         /* 0x018 */
-	psw_t        svc_old_psw;              /* 0x020 */
-	psw_t        program_old_psw;          /* 0x028 */
-	psw_t        mcck_old_psw;             /* 0x030 */
-	psw_t        io_old_psw;               /* 0x038 */
-	__u8         pad1[0x58-0x40];          /* 0x040 */
-	psw_t        external_new_psw;         /* 0x058 */
-	psw_t        svc_new_psw;              /* 0x060 */
-	psw_t        program_new_psw;          /* 0x068 */
-	psw_t        mcck_new_psw;             /* 0x070 */
-	psw_t        io_new_psw;               /* 0x078 */
-	__u32        ext_params;               /* 0x080 */
-	__u16        cpu_addr;                 /* 0x084 */
-	__u16        ext_int_code;             /* 0x086 */
-        __u16        svc_ilc;                  /* 0x088 */
-        __u16        svc_code;                 /* 0x08a */
-        __u16        pgm_ilc;                  /* 0x08c */
-        __u16        pgm_code;                 /* 0x08e */
-	__u32        trans_exc_code;           /* 0x090 */
-	__u16        mon_class_num;            /* 0x094 */
-	__u16        per_perc_atmid;           /* 0x096 */
-	__u32        per_address;              /* 0x098 */
-	__u32        monitor_code;             /* 0x09c */
-	__u8         exc_access_id;            /* 0x0a0 */
-	__u8         per_access_id;            /* 0x0a1 */
-	__u8         pad2[0xB8-0xA2];          /* 0x0a2 */
-	__u16        subchannel_id;            /* 0x0b8 */
-	__u16        subchannel_nr;            /* 0x0ba */
-	__u32        io_int_parm;              /* 0x0bc */
-	__u32        io_int_word;              /* 0x0c0 */
-	__u8	     pad3[0xc8-0xc4];	       /* 0x0c4 */
-	__u32	     stfl_fac_list;	       /* 0x0c8 */
-	__u8	     pad4[0xd4-0xcc];	       /* 0x0cc */
-	__u32        extended_save_area_addr;  /* 0x0d4 */
-	__u32        cpu_timer_save_area[2];   /* 0x0d8 */
-	__u32        clock_comp_save_area[2];  /* 0x0e0 */
-	__u32        mcck_interruption_code[2]; /* 0x0e8 */
-	__u8	     pad5[0xf4-0xf0];	       /* 0x0f0 */
-	__u32        external_damage_code;     /* 0x0f4 */
-	__u32        failing_storage_address;  /* 0x0f8 */
-	__u8	     pad6[0x100-0xfc];	       /* 0x0fc */
-	__u32        st_status_fixed_logout[4];/* 0x100 */
-	__u8	     pad7[0x120-0x110];        /* 0x110 */
-	__u32        access_regs_save_area[16];/* 0x120 */
-	__u32        floating_pt_save_area[8]; /* 0x160 */
-	__u32        gpregs_save_area[16];     /* 0x180 */
-	__u32        cregs_save_area[16];      /* 0x1c0 */	
+	/* 0x0000 - 0x01ff: defined by architecture */
+	psw_t	restart_psw;			/* 0x0000 */
+	__u32	ccw2[4];			/* 0x0008 */
+	psw_t	external_old_psw;		/* 0x0018 */
+	psw_t	svc_old_psw;			/* 0x0020 */
+	psw_t	program_old_psw;		/* 0x0028 */
+	psw_t	mcck_old_psw;			/* 0x0030 */
+	psw_t	io_old_psw;			/* 0x0038 */
+	__u8	pad_0x0040[0x0058-0x0040];	/* 0x0040 */
+	psw_t	external_new_psw;		/* 0x0058 */
+	psw_t	svc_new_psw;			/* 0x0060 */
+	psw_t	program_new_psw;		/* 0x0068 */
+	psw_t	mcck_new_psw;			/* 0x0070 */
+	psw_t	io_new_psw;			/* 0x0078 */
+	__u32	ext_params;			/* 0x0080 */
+	__u16	cpu_addr;			/* 0x0084 */
+	__u16	ext_int_code;			/* 0x0086 */
+	__u16	svc_ilc;			/* 0x0088 */
+	__u16	svc_code;			/* 0x008a */
+	__u16	pgm_ilc;			/* 0x008c */
+	__u16	pgm_code;			/* 0x008e */
+	__u32	trans_exc_code;			/* 0x0090 */
+	__u16	mon_class_num;			/* 0x0094 */
+	__u16	per_perc_atmid;			/* 0x0096 */
+	__u32	per_address;			/* 0x0098 */
+	__u32	monitor_code;			/* 0x009c */
+	__u8	exc_access_id;			/* 0x00a0 */
+	__u8	per_access_id;			/* 0x00a1 */
+	__u8	pad_0x00a2[0x00b8-0x00a2];	/* 0x00a2 */
+	__u16	subchannel_id;			/* 0x00b8 */
+	__u16	subchannel_nr;			/* 0x00ba */
+	__u32	io_int_parm;			/* 0x00bc */
+	__u32	io_int_word;			/* 0x00c0 */
+	__u8	pad_0x00c4[0x00c8-0x00c4];	/* 0x00c4 */
+	__u32	stfl_fac_list;			/* 0x00c8 */
+	__u8	pad_0x00cc[0x00d4-0x00cc];	/* 0x00cc */
+	__u32	extended_save_area_addr;	/* 0x00d4 */
+	__u32	cpu_timer_save_area[2];		/* 0x00d8 */
+	__u32	clock_comp_save_area[2];	/* 0x00e0 */
+	__u32	mcck_interruption_code[2];	/* 0x00e8 */
+	__u8	pad_0x00f0[0x00f4-0x00f0];	/* 0x00f0 */
+	__u32	external_damage_code;		/* 0x00f4 */
+	__u32	failing_storage_address;	/* 0x00f8 */
+	__u8	pad_0x00fc[0x0100-0x00fc];	/* 0x00fc */
+	__u32	st_status_fixed_logout[4];	/* 0x0100 */
+	__u8	pad_0x0110[0x0120-0x0110];	/* 0x0110 */
 
-        psw_t        return_psw;               /* 0x200 */
-	__u8	     irb[64];		       /* 0x208 */
-	__u64        sync_enter_timer;         /* 0x248 */
-	__u64        async_enter_timer;        /* 0x250 */
-	__u64        exit_timer;               /* 0x258 */
-	__u64	     user_timer;	       /* 0x260 */
-	__u64	     system_timer;	       /* 0x268 */
-	__u64	     steal_timer;	       /* 0x270 */
-	__u64	     last_update_timer;        /* 0x278 */
-	__u64	     last_update_clock;        /* 0x280 */
-        psw_t        return_mcck_psw;          /* 0x288 */
-	__u8         pad8[0xc00-0x290];        /* 0x290 */
+	/* CPU register save area: defined by architecture */
+	__u32	access_regs_save_area[16];	/* 0x0120 */
+	__u32	floating_pt_save_area[8];	/* 0x0160 */
+	__u32	gpregs_save_area[16];		/* 0x0180 */
+	__u32	cregs_save_area[16];		/* 0x01c0 */
 
-        /* System info area */
-	__u32        save_area[16];            /* 0xc00 */
-	__u32        kernel_stack;             /* 0xc40 */
-	__u32        thread_info;              /* 0xc44 */
-	__u32        async_stack;              /* 0xc48 */
-	__u32        kernel_asce;              /* 0xc4c */
-	__u32        user_asce;                /* 0xc50 */
-	__u32        panic_stack;              /* 0xc54 */
-	__u32	     user_exec_asce;	       /* 0xc58 */
-	__u8	     pad10[0xc60-0xc5c];       /* 0xc5c */
-	/* entry.S sensitive area start */
-	struct       cpuinfo_S390 cpu_data;    /* 0xc60 */
-	__u32        ipl_device;               /* 0xc7c */
-	/* entry.S sensitive area end */
+	/* Return psws. */
+	__u32	save_area[16];			/* 0x0200 */
+	psw_t	return_psw;			/* 0x0240 */
+	psw_t	return_mcck_psw;		/* 0x0248 */
 
-        /* SMP info area: defined by DJB */
-	__u64	     clock_comparator;	       /* 0xc80 */
-	__u32        ext_call_fast;            /* 0xc88 */
-	__u32        percpu_offset;            /* 0xc8c */
-	__u32        current_task;	       /* 0xc90 */
-	__u32        softirq_pending;	       /* 0xc94 */
-	__u64        int_clock;                /* 0xc98 */
-        __u8         pad11[0xe00-0xca0];       /* 0xca0 */
+	/* CPU time accounting values */
+	__u64	sync_enter_timer;		/* 0x0250 */
+	__u64	async_enter_timer;		/* 0x0258 */
+	__u64	exit_timer;			/* 0x0260 */
+	__u64	user_timer;			/* 0x0268 */
+	__u64	system_timer;			/* 0x0270 */
+	__u64	steal_timer;			/* 0x0278 */
+	__u64	last_update_timer;		/* 0x0280 */
+	__u64	last_update_clock;		/* 0x0288 */
 
-        /* 0xe00 is used as indicator for dump tools */
-        /* whether the kernel died with panic() or not */
-        __u32        panic_magic;              /* 0xe00 */
+	/* Current process. */
+	__u32	current_task;			/* 0x0290 */
+	__u32	thread_info;			/* 0x0294 */
+	__u32	kernel_stack;			/* 0x0298 */
 
-        /* Align to the top 1k of prefix area */
-	__u8         pad12[0x1000-0xe04];      /* 0xe04 */
+	/* Interrupt and panic stack. */
+	__u32	async_stack;			/* 0x029c */
+	__u32	panic_stack;			/* 0x02a0 */
+
+	/* Address space pointer. */
+	__u32	kernel_asce;			/* 0x02a4 */
+	__u32	user_asce;			/* 0x02a8 */
+	__u32	user_exec_asce;			/* 0x02ac */
+
+	/* SMP info area */
+	cpuid_t	cpu_id;				/* 0x02b0 */
+	__u32	cpu_nr;				/* 0x02b8 */
+	__u32	softirq_pending;		/* 0x02bc */
+	__u32	percpu_offset;			/* 0x02c0 */
+	__u32	ext_call_fast;			/* 0x02c4 */
+	__u64	int_clock;			/* 0x02c8 */
+	__u64	clock_comparator;		/* 0x02d0 */
+	__u32	machine_flags;			/* 0x02d8 */
+	__u8	pad_0x02dc[0x0300-0x02dc];	/* 0x02dc */
+
+	/* Interrupt response block */
+	__u8	irb[64];			/* 0x0300 */
+
+	__u8	pad_0x0400[0x0e00-0x0400];	/* 0x0400 */
+
+	/*
+	 * 0xe00 contains the address of the IPL Parameter Information
+	 * block. Dump tools need IPIB for IPL after dump.
+	 * Note: do not change the position of any fields in 0x0e00-0x0f00
+	 */
+	__u32	ipib;				/* 0x0e00 */
+	__u32	ipib_checksum;			/* 0x0e04 */
+
+	/* Align to the top 1k of prefix area */
+	__u8	pad_0x0e08[0x1000-0x0e08];	/* 0x0e08 */
 #else /* !__s390x__ */
-        /* prefix area: defined by architecture */
-	__u32        ccw1[2];                  /* 0x000 */
-	__u32        ccw2[4];                  /* 0x008 */
-	__u8         pad1[0x80-0x18];          /* 0x018 */
-	__u32        ext_params;               /* 0x080 */
-	__u16        cpu_addr;                 /* 0x084 */
-	__u16        ext_int_code;             /* 0x086 */
-        __u16        svc_ilc;                  /* 0x088 */
-        __u16        svc_code;                 /* 0x08a */
-        __u16        pgm_ilc;                  /* 0x08c */
-        __u16        pgm_code;                 /* 0x08e */
-	__u32        data_exc_code;            /* 0x090 */
-	__u16        mon_class_num;            /* 0x094 */
-	__u16        per_perc_atmid;           /* 0x096 */
-	addr_t       per_address;              /* 0x098 */
-	__u8         exc_access_id;            /* 0x0a0 */
-	__u8         per_access_id;            /* 0x0a1 */
-	__u8         op_access_id;             /* 0x0a2 */
-	__u8         ar_access_id;             /* 0x0a3 */
-	__u8         pad2[0xA8-0xA4];          /* 0x0a4 */
-	addr_t       trans_exc_code;           /* 0x0A0 */
-	addr_t       monitor_code;             /* 0x09c */
-	__u16        subchannel_id;            /* 0x0b8 */
-	__u16        subchannel_nr;            /* 0x0ba */
-	__u32        io_int_parm;              /* 0x0bc */
-	__u32        io_int_word;              /* 0x0c0 */
-	__u8         pad3[0xc8-0xc4];          /* 0x0c4 */
-	__u32        stfl_fac_list;            /* 0x0c8 */
-	__u8         pad4[0xe8-0xcc];          /* 0x0cc */
-	__u32        mcck_interruption_code[2]; /* 0x0e8 */
-	__u8         pad5[0xf4-0xf0];          /* 0x0f0 */
-	__u32        external_damage_code;     /* 0x0f4 */
-	addr_t       failing_storage_address;  /* 0x0f8 */
-	__u8         pad6[0x120-0x100];        /* 0x100 */
-	psw_t        restart_old_psw;          /* 0x120 */
-	psw_t        external_old_psw;         /* 0x130 */
-	psw_t        svc_old_psw;              /* 0x140 */
-	psw_t        program_old_psw;          /* 0x150 */
-	psw_t        mcck_old_psw;             /* 0x160 */
-	psw_t        io_old_psw;               /* 0x170 */
-	__u8         pad7[0x1a0-0x180];        /* 0x180 */
-	psw_t        restart_psw;              /* 0x1a0 */
-	psw_t        external_new_psw;         /* 0x1b0 */
-	psw_t        svc_new_psw;              /* 0x1c0 */
-	psw_t        program_new_psw;          /* 0x1d0 */
-	psw_t        mcck_new_psw;             /* 0x1e0 */
-	psw_t        io_new_psw;               /* 0x1f0 */
-        psw_t        return_psw;               /* 0x200 */
-	__u8	     irb[64];		       /* 0x210 */
-	__u64        sync_enter_timer;         /* 0x250 */
-	__u64        async_enter_timer;        /* 0x258 */
-	__u64        exit_timer;               /* 0x260 */
-	__u64	     user_timer;	       /* 0x268 */
-	__u64	     system_timer;	       /* 0x270 */
-	__u64	     steal_timer;	       /* 0x278 */
-	__u64	     last_update_timer;        /* 0x280 */
-	__u64	     last_update_clock;        /* 0x288 */
-        psw_t        return_mcck_psw;          /* 0x290 */
-        __u8         pad8[0xc00-0x2a0];        /* 0x2a0 */
-        /* System info area */
-	__u64        save_area[16];            /* 0xc00 */
-        __u8         pad9[0xd40-0xc80];        /* 0xc80 */
- 	__u64        kernel_stack;             /* 0xd40 */
-	__u64        thread_info;              /* 0xd48 */
-	__u64        async_stack;              /* 0xd50 */
-	__u64        kernel_asce;              /* 0xd58 */
-	__u64        user_asce;                /* 0xd60 */
-	__u64        panic_stack;              /* 0xd68 */
-	__u64	     user_exec_asce;	       /* 0xd70 */
-	__u8	     pad10[0xd80-0xd78];       /* 0xd78 */
-	/* entry.S sensitive area start */
-	struct       cpuinfo_S390 cpu_data;    /* 0xd80 */
-	__u32        ipl_device;               /* 0xdb8 */
-	__u32        pad11;                    /* 0xdbc */
-	/* entry.S sensitive area end */
+	/* 0x0000 - 0x01ff: defined by architecture */
+	__u32	ccw1[2];			/* 0x0000 */
+	__u32	ccw2[4];			/* 0x0008 */
+	__u8	pad_0x0018[0x0080-0x0018];	/* 0x0018 */
+	__u32	ext_params;			/* 0x0080 */
+	__u16	cpu_addr;			/* 0x0084 */
+	__u16	ext_int_code;			/* 0x0086 */
+	__u16	svc_ilc;			/* 0x0088 */
+	__u16	svc_code;			/* 0x008a */
+	__u16	pgm_ilc;			/* 0x008c */
+	__u16	pgm_code;			/* 0x008e */
+	__u32	data_exc_code;			/* 0x0090 */
+	__u16	mon_class_num;			/* 0x0094 */
+	__u16	per_perc_atmid;			/* 0x0096 */
+	addr_t	per_address;			/* 0x0098 */
+	__u8	exc_access_id;			/* 0x00a0 */
+	__u8	per_access_id;			/* 0x00a1 */
+	__u8	op_access_id;			/* 0x00a2 */
+	__u8	ar_access_id;			/* 0x00a3 */
+	__u8	pad_0x00a4[0x00a8-0x00a4];	/* 0x00a4 */
+	addr_t	trans_exc_code;			/* 0x00a8 */
+	addr_t	monitor_code;			/* 0x00b0 */
+	__u16	subchannel_id;			/* 0x00b8 */
+	__u16	subchannel_nr;			/* 0x00ba */
+	__u32	io_int_parm;			/* 0x00bc */
+	__u32	io_int_word;			/* 0x00c0 */
+	__u8	pad_0x00c4[0x00c8-0x00c4];	/* 0x00c4 */
+	__u32	stfl_fac_list;			/* 0x00c8 */
+	__u8	pad_0x00cc[0x00e8-0x00cc];	/* 0x00cc */
+	__u32	mcck_interruption_code[2];	/* 0x00e8 */
+	__u8	pad_0x00f0[0x00f4-0x00f0];	/* 0x00f0 */
+	__u32	external_damage_code;		/* 0x00f4 */
+	addr_t	failing_storage_address;	/* 0x00f8 */
+	__u8	pad_0x0100[0x0120-0x0100];	/* 0x0100 */
+	psw_t	restart_old_psw;		/* 0x0120 */
+	psw_t	external_old_psw;		/* 0x0130 */
+	psw_t	svc_old_psw;			/* 0x0140 */
+	psw_t	program_old_psw;		/* 0x0150 */
+	psw_t	mcck_old_psw;			/* 0x0160 */
+	psw_t	io_old_psw;			/* 0x0170 */
+	__u8	pad_0x0180[0x01a0-0x0180];	/* 0x0180 */
+	psw_t	restart_psw;			/* 0x01a0 */
+	psw_t	external_new_psw;		/* 0x01b0 */
+	psw_t	svc_new_psw;			/* 0x01c0 */
+	psw_t	program_new_psw;		/* 0x01d0 */
+	psw_t	mcck_new_psw;			/* 0x01e0 */
+	psw_t	io_new_psw;			/* 0x01f0 */
 
-        /* SMP info area: defined by DJB */
-	__u64	     clock_comparator;	       /* 0xdc0 */
-	__u64        ext_call_fast;            /* 0xdc8 */
-	__u64        percpu_offset;            /* 0xdd0 */
-	__u64        current_task;	       /* 0xdd8 */
-	__u32	     softirq_pending;	       /* 0xde0 */
-	__u32	     pad_0x0de4;	       /* 0xde4 */
-	__u64        int_clock;                /* 0xde8 */
-        __u8         pad12[0xe00-0xdf0];       /* 0xdf0 */
+	/* Entry/exit save area & return psws. */
+	__u64	save_area[16];			/* 0x0200 */
+	psw_t	return_psw;			/* 0x0280 */
+	psw_t	return_mcck_psw;		/* 0x0290 */
 
-        /* 0xe00 is used as indicator for dump tools */
-        /* whether the kernel died with panic() or not */
-        __u32        panic_magic;              /* 0xe00 */
+	/* CPU accounting and timing values. */
+	__u64	sync_enter_timer;		/* 0x02a0 */
+	__u64	async_enter_timer;		/* 0x02a8 */
+	__u64	exit_timer;			/* 0x02b0 */
+	__u64	user_timer;			/* 0x02b8 */
+	__u64	system_timer;			/* 0x02c0 */
+	__u64	steal_timer;			/* 0x02c8 */
+	__u64	last_update_timer;		/* 0x02d0 */
+	__u64	last_update_clock;		/* 0x02d8 */
 
-	/* Per cpu primary space access list */
-	__u8	     pad_0xe04[0xe38-0xe04];   /* 0xe04 */
-	__u64	     vdso_per_cpu_data;	       /* 0xe38 */
-	__u32	     paste[16];		       /* 0xe40 */
+	/* Current process. */
+	__u64	current_task;			/* 0x02e0 */
+	__u64	thread_info;			/* 0x02e8 */
+	__u64	kernel_stack;			/* 0x02f0 */
 
-	__u8	     pad13[0x11b8-0xe80];      /* 0xe80 */
+	/* Interrupt and panic stack. */
+	__u64	async_stack;			/* 0x02f8 */
+	__u64	panic_stack;			/* 0x0300 */
 
-	/* 64 bit extparam used for pfault, diag 250 etc  */
-	__u64        ext_params2;               /* 0x11B8 */
+	/* Address space pointer. */
+	__u64	kernel_asce;			/* 0x0308 */
+	__u64	user_asce;			/* 0x0310 */
+	__u64	user_exec_asce;			/* 0x0318 */
 
-	__u8         pad14[0x1200-0x11C0];      /* 0x11C0 */
+	/* SMP info area */
+	cpuid_t	cpu_id;				/* 0x0320 */
+	__u32	cpu_nr;				/* 0x0328 */
+	__u32	softirq_pending;		/* 0x032c */
+	__u64	percpu_offset;			/* 0x0330 */
+	__u64	ext_call_fast;			/* 0x0338 */
+	__u64	int_clock;			/* 0x0340 */
+	__u64	clock_comparator;		/* 0x0348 */
+	__u64	vdso_per_cpu_data;		/* 0x0350 */
+	__u64	machine_flags;			/* 0x0358 */
+	__u8	pad_0x0360[0x0380-0x0360];	/* 0x0360 */
 
-        /* System info area */ 
+	/* Interrupt response block. */
+	__u8	irb[64];			/* 0x0380 */
 
-	__u64        floating_pt_save_area[16]; /* 0x1200 */
-	__u64        gpregs_save_area[16];      /* 0x1280 */
-	__u32        st_status_fixed_logout[4]; /* 0x1300 */
-	__u8         pad15[0x1318-0x1310];      /* 0x1310 */
-	__u32        prefixreg_save_area;       /* 0x1318 */
-	__u32        fpt_creg_save_area;        /* 0x131c */
-	__u8         pad16[0x1324-0x1320];      /* 0x1320 */
-	__u32        tod_progreg_save_area;     /* 0x1324 */
-	__u32        cpu_timer_save_area[2];    /* 0x1328 */
-	__u32        clock_comp_save_area[2];   /* 0x1330 */
-	__u8         pad17[0x1340-0x1338];      /* 0x1338 */
-	__u32        access_regs_save_area[16]; /* 0x1340 */ 
-	__u64        cregs_save_area[16];       /* 0x1380 */
+	/* Per cpu primary space access list */
+	__u32	paste[16];			/* 0x03c0 */
 
-	/* align to the top of the prefix area */
+	__u8	pad_0x0400[0x0e00-0x0400];	/* 0x0400 */
 
-	__u8         pad18[0x2000-0x1400];      /* 0x1400 */
+	/*
+	 * 0xe00 contains the address of the IPL Parameter Information
+	 * block. Dump tools need IPIB for IPL after dump.
+	 * Note: do not change the position of any fields in 0x0e00-0x0f00
+	 */
+	__u64	ipib;				/* 0x0e00 */
+	__u32	ipib_checksum;			/* 0x0e08 */
+	__u8	pad_0x0e0c[0x11b8-0x0e0c];	/* 0x0e0c */
+
+	/* 64 bit extparam used for pfault/diag 250: defined by architecture */
+	__u64	ext_params2;			/* 0x11B8 */
+	__u8	pad_0x11c0[0x1200-0x11C0];	/* 0x11C0 */
+
+	/* CPU register save area: defined by architecture */
+	__u64	floating_pt_save_area[16];	/* 0x1200 */
+	__u64	gpregs_save_area[16];		/* 0x1280 */
+	__u32	st_status_fixed_logout[4];	/* 0x1300 */
+	__u8	pad_0x1310[0x1318-0x1310];	/* 0x1310 */
+	__u32	prefixreg_save_area;		/* 0x1318 */
+	__u32	fpt_creg_save_area;		/* 0x131c */
+	__u8	pad_0x1320[0x1324-0x1320];	/* 0x1320 */
+	__u32	tod_progreg_save_area;		/* 0x1324 */
+	__u32	cpu_timer_save_area[2];		/* 0x1328 */
+	__u32	clock_comp_save_area[2];	/* 0x1330 */
+	__u8	pad_0x1338[0x1340-0x1338];	/* 0x1338 */
+	__u32	access_regs_save_area[16];	/* 0x1340 */
+	__u64	cregs_save_area[16];		/* 0x1380 */
+
+	/* align to the top of the prefix area */
+	__u8	pad_0x1400[0x2000-0x1400];	/* 0x1400 */
 #endif /* !__s390x__ */
 } __attribute__((packed)); /* End structure*/
 
@@ -433,8 +444,6 @@ static inline __u32 store_prefix(void)
 	return address;
 }
 
-#define __PANIC_MAGIC           0xDEADC0DE
-
 #endif
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -74,7 +74,7 @@ static inline void update_mm(struct mm_s
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 			     struct task_struct *tsk)
 {
-	cpu_set(smp_processor_id(), next->cpu_vm_mask);
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
 	update_mm(next, tsk);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/nmi.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/nmi.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/nmi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/nmi.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ *   Machine check handler definitions
+ *
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_NMI_H
+#define _ASM_S390_NMI_H
+
+#include <linux/types.h>
+
+struct mci {
+	__u32 sd :  1; /* 00 system damage */
+	__u32 pd :  1; /* 01 instruction-processing damage */
+	__u32 sr :  1; /* 02 system recovery */
+	__u32	 :  1; /* 03 */
+	__u32 cd :  1; /* 04 timing-facility damage */
+	__u32 ed :  1; /* 05 external damage */
+	__u32	 :  1; /* 06 */
+	__u32 dg :  1; /* 07 degradation */
+	__u32 w  :  1; /* 08 warning pending */
+	__u32 cp :  1; /* 09 channel-report pending */
+	__u32 sp :  1; /* 10 service-processor damage */
+	__u32 ck :  1; /* 11 channel-subsystem damage */
+	__u32	 :  2; /* 12-13 */
+	__u32 b  :  1; /* 14 backed up */
+	__u32	 :  1; /* 15 */
+	__u32 se :  1; /* 16 storage error uncorrected */
+	__u32 sc :  1; /* 17 storage error corrected */
+	__u32 ke :  1; /* 18 storage-key error uncorrected */
+	__u32 ds :  1; /* 19 storage degradation */
+	__u32 wp :  1; /* 20 psw mwp validity */
+	__u32 ms :  1; /* 21 psw mask and key validity */
+	__u32 pm :  1; /* 22 psw program mask and cc validity */
+	__u32 ia :  1; /* 23 psw instruction address validity */
+	__u32 fa :  1; /* 24 failing storage address validity */
+	__u32	 :  1; /* 25 */
+	__u32 ec :  1; /* 26 external damage code validity */
+	__u32 fp :  1; /* 27 floating point register validity */
+	__u32 gr :  1; /* 28 general register validity */
+	__u32 cr :  1; /* 29 control register validity */
+	__u32	 :  1; /* 30 */
+	__u32 st :  1; /* 31 storage logical validity */
+	__u32 ie :  1; /* 32 indirect storage error */
+	__u32 ar :  1; /* 33 access register validity */
+	__u32 da :  1; /* 34 delayed access exception */
+	__u32	 :  7; /* 35-41 */
+	__u32 pr :  1; /* 42 tod programmable register validity */
+	__u32 fc :  1; /* 43 fp control register validity */
+	__u32 ap :  1; /* 44 ancillary report */
+	__u32	 :  1; /* 45 */
+	__u32 ct :  1; /* 46 cpu timer validity */
+	__u32 cc :  1; /* 47 clock comparator validity */
+	__u32	 : 16; /* 47-63 */
+};
+
+struct pt_regs;
+
+extern void s390_handle_mcck(void);
+extern void s390_do_machine_check(struct pt_regs *regs);
+
+#endif /* _ASM_S390_NMI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/processor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,10 @@
 #define __ASM_S390_PROCESSOR_H
 
 #include <linux/linkage.h>
+#include <asm/cpuid.h>
+#include <asm/page.h>
 #include <asm/ptrace.h>
+#include <asm/setup.h>
 
 #ifdef __KERNEL__
 /*
@@ -23,41 +26,13 @@
  */
 #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
 
-/*
- *  CPU type and hardware bug flags. Kept separately for each CPU.
- *  Members of this structure are referenced in head.S, so think twice
- *  before touching them. [mj]
- */
-
-typedef struct
-{
-        unsigned int version :  8;
-        unsigned int ident   : 24;
-        unsigned int machine : 16;
-        unsigned int unused  : 16;
-} __attribute__ ((packed)) cpuid_t;
-
 static inline void get_cpu_id(cpuid_t *ptr)
 {
 	asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
 }
 
-struct cpuinfo_S390
-{
-        cpuid_t  cpu_id;
-        __u16    cpu_addr;
-        __u16    cpu_nr;
-        unsigned long loops_per_jiffy;
-        unsigned long *pgd_quick;
-#ifdef __s390x__
-        unsigned long *pmd_quick;
-#endif /* __s390x__ */
-        unsigned long *pte_quick;
-        unsigned long pgtable_cache_sz;
-};
-
 extern void s390_adjust_jiffies(void);
-extern void print_cpu_info(struct cpuinfo_S390 *);
+extern void print_cpu_info(void);
 extern int get_cpu_capability(unsigned int *);
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -172,6 +172,8 @@
 #define NUM_CRS		16
 #define NUM_ACRS	16
 
+#define NUM_CR_WORDS	3
+
 #define FPR_SIZE	8
 #define FPC_SIZE	4
 #define FPC_PAD_SIZE	4 /* gcc insists on aligning the fpregs */
@@ -311,8 +313,6 @@ typedef struct
 
 
 #ifdef __KERNEL__
-#include <asm/setup.h>
-#include <asm/page.h>
 
 /*
  * The pt_regs struct defines the way the registers are stored on
@@ -334,7 +334,7 @@ struct pt_regs
  */
 typedef struct
 {
-	unsigned long cr[3];
+	unsigned long cr[NUM_CR_WORDS];
 } per_cr_words;
 
 #define PER_EM_MASK 0xE8000000UL
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/qdio.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/qdio.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/qdio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/qdio.h	2009-06-09 23:05:27.000000000 -0400
@@ -314,6 +314,7 @@ typedef void qdio_handler_t(struct ccw_d
 			    int, int, unsigned long);
 
 /* qdio errors reported to the upper-layer program */
+#define QDIO_ERROR_SIGA_TARGET			0x02
 #define QDIO_ERROR_SIGA_ACCESS_EXCEPTION	0x10
 #define QDIO_ERROR_SIGA_BUSY			0x20
 #define QDIO_ERROR_ACTIVATE_CHECK_CONDITION	0x40
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/setup.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 
 #ifdef __KERNEL__
 
+#include <asm/lowcore.h>
 #include <asm/types.h>
 
 #define PARMAREA		0x10400
@@ -63,7 +64,6 @@ extern unsigned int s390_noexec;
 /*
  * Machine features detected in head.S
  */
-extern unsigned long machine_flags;
 
 #define MACHINE_FLAG_VM		(1UL << 0)
 #define MACHINE_FLAG_IEEE	(1UL << 1)
@@ -77,28 +77,28 @@ extern unsigned long machine_flags;
 #define MACHINE_FLAG_HPAGE	(1UL << 10)
 #define MACHINE_FLAG_PFMF	(1UL << 11)
 
-#define MACHINE_IS_VM		(machine_flags & MACHINE_FLAG_VM)
-#define MACHINE_IS_KVM		(machine_flags & MACHINE_FLAG_KVM)
-#define MACHINE_HAS_DIAG9C	(machine_flags & MACHINE_FLAG_DIAG9C)
+#define MACHINE_IS_VM		(S390_lowcore.machine_flags & MACHINE_FLAG_VM)
+#define MACHINE_IS_KVM		(S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
+#define MACHINE_HAS_DIAG9C	(S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
 
 #ifndef __s390x__
-#define MACHINE_HAS_IEEE	(machine_flags & MACHINE_FLAG_IEEE)
-#define MACHINE_HAS_CSP		(machine_flags & MACHINE_FLAG_CSP)
+#define MACHINE_HAS_IEEE	(S390_lowcore.machine_flags & MACHINE_FLAG_IEEE)
+#define MACHINE_HAS_CSP		(S390_lowcore.machine_flags & MACHINE_FLAG_CSP)
 #define MACHINE_HAS_IDTE	(0)
 #define MACHINE_HAS_DIAG44	(1)
-#define MACHINE_HAS_MVPG	(machine_flags & MACHINE_FLAG_MVPG)
+#define MACHINE_HAS_MVPG	(S390_lowcore.machine_flags & MACHINE_FLAG_MVPG)
 #define MACHINE_HAS_MVCOS	(0)
 #define MACHINE_HAS_HPAGE	(0)
 #define MACHINE_HAS_PFMF	(0)
 #else /* __s390x__ */
 #define MACHINE_HAS_IEEE	(1)
 #define MACHINE_HAS_CSP		(1)
-#define MACHINE_HAS_IDTE	(machine_flags & MACHINE_FLAG_IDTE)
-#define MACHINE_HAS_DIAG44	(machine_flags & MACHINE_FLAG_DIAG44)
+#define MACHINE_HAS_IDTE	(S390_lowcore.machine_flags & MACHINE_FLAG_IDTE)
+#define MACHINE_HAS_DIAG44	(S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44)
 #define MACHINE_HAS_MVPG	(1)
-#define MACHINE_HAS_MVCOS	(machine_flags & MACHINE_FLAG_MVCOS)
-#define MACHINE_HAS_HPAGE	(machine_flags & MACHINE_FLAG_HPAGE)
-#define MACHINE_HAS_PFMF	(machine_flags & MACHINE_FLAG_PFMF)
+#define MACHINE_HAS_MVCOS	(S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
+#define MACHINE_HAS_HPAGE	(S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
+#define MACHINE_HAS_PFMF	(S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE	(32UL<<20)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,12 +50,7 @@ extern void machine_power_off_smp(void);
  
 #define PROC_CHANGE_PENALTY	20		/* Schedule penalty */
 
-#define raw_smp_processor_id()	(S390_lowcore.cpu_data.cpu_nr)
-
-static inline __u16 hard_smp_processor_id(void)
-{
-	return stap();
-}
+#define raw_smp_processor_id()	(S390_lowcore.cpu_nr)
 
 /*
  * returns 1 if cpu is in stopped/check stopped state or not operational
@@ -97,12 +92,6 @@ extern void arch_send_call_function_ipi(
 #endif
 
 #ifndef CONFIG_SMP
-static inline void smp_send_stop(void)
-{
-	/* Disable all interrupts/machine checks */
-	__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-}
-
 #define hard_smp_processor_id()		0
 #define smp_cpu_not_running(cpu)	1
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -62,4 +62,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -172,6 +172,9 @@ static inline int __raw_write_trylock(ra
 	return _raw_write_trylock_retry(rw);
 }
 
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/string.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/string.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/string.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/string.h	2009-06-09 23:05:27.000000000 -0400
@@ -100,6 +100,7 @@ static inline char *strcat(char *dst, co
 
 static inline char *strcpy(char *dst, const char *src)
 {
+#if __GNUC__ < 4
 	register int r0 asm("0") = 0;
 	char *ret = dst;
 
@@ -109,10 +110,14 @@ static inline char *strcpy(char *dst, co
 		: "+&a" (dst), "+&a" (src) : "d" (r0)
 		: "cc", "memory");
 	return ret;
+#else
+	return __builtin_strcpy(dst, src);
+#endif
 }
 
 static inline size_t strlen(const char *s)
 {
+#if __GNUC__ < 4
 	register unsigned long r0 asm("0") = 0;
 	const char *tmp = s;
 
@@ -121,6 +126,9 @@ static inline size_t strlen(const char *
 		"	jo	0b"
 		: "+d" (r0), "+a" (tmp) :  : "cc");
 	return r0 - (unsigned long) s;
+#else
+	return __builtin_strlen(s);
+#endif
 }
 
 static inline size_t strnlen(const char * s, size_t n)
@@ -135,7 +143,13 @@ static inline size_t strnlen(const char
 		: "+a" (end), "+a" (tmp) : "d" (r0)  : "cc");
 	return end - s;
 }
-
+#else /* IN_ARCH_STRING_C */
+void *memchr(const void * s, int c, size_t n);
+void *memscan(void *s, int c, size_t n);
+char *strcat(char *dst, const char *src);
+char *strcpy(char *dst, const char *src);
+size_t strlen(const char *s);
+size_t strnlen(const char * s, size_t n);
 #endif /* !IN_ARCH_STRING_C */
 
 #endif /* __KERNEL__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/sysinfo.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/sysinfo.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/sysinfo.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/sysinfo.h	2009-06-09 23:05:27.000000000 -0400
@@ -100,6 +100,7 @@ struct sysinfo_3_2_2 {
 		char reserved_1[24];
 
 	} vm[8];
+	char reserved_544[3552];
 };
 
 static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/thread_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,8 +31,9 @@
 #define ASYNC_SIZE  (PAGE_SIZE << ASYNC_ORDER)
 
 #ifndef __ASSEMBLY__
-#include <asm/processor.h>
 #include <asm/lowcore.h>
+#include <asm/page.h>
+#include <asm/processor.h>
 
 /*
  * low level task data that entry.S needs immediate access to
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/timer.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/timer.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,7 @@ extern void init_virt_timer(struct vtime
 extern void add_virt_timer(void *new);
 extern void add_virt_timer_periodic(void *new);
 extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires);
+extern int mod_virt_timer_periodic(struct vtimer_list *timer, __u64 expires);
 extern int del_virt_timer(struct vtimer_list *timer);
 
 extern void init_cpu_vtimer(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/timex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,9 @@
 #ifndef _ASM_S390_TIMEX_H
 #define _ASM_S390_TIMEX_H
 
+/* The value of the TOD clock for 1.1.1970. */
+#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
+
 /* Inline functions for clock register access. */
 static inline int set_clock(__u64 time)
 {
@@ -85,4 +88,6 @@ int get_sync_clock(unsigned long long *c
 void init_cpu_timer(void);
 unsigned long long monotonic_clock(void);
 
+extern u64 sched_clock_base_cc;
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/tlbflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,7 @@ static inline void __tlb_flush_full(stru
 	 * If the process only ran on the local cpu, do a local flush.
 	 */
 	local_cpumask = cpumask_of_cpu(smp_processor_id());
-	if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
+	if (cpumask_equal(mm_cpumask(mm), &local_cpumask))
 		__tlb_flush_local();
 	else
 		__tlb_flush_global();
@@ -73,7 +73,7 @@ static inline void __tlb_flush_idte(unsi
 
 static inline void __tlb_flush_mm(struct mm_struct * mm)
 {
-	if (unlikely(cpus_empty(mm->cpu_vm_mask)))
+	if (unlikely(cpumask_empty(mm_cpumask(mm))))
 		return;
 	/*
 	 * If the machine has IDTE we prefer to do a per mm flush
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
 
 #define mc_capable()	(1)
 
-cpumask_t cpu_coregroup_map(unsigned int cpu);
 const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
 
 extern cpumask_t cpu_core_map[NR_CPUS];
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -265,7 +265,9 @@
 #define __NR_pipe2		325
 #define __NR_dup3		326
 #define __NR_epoll_create1	327
-#define NR_syscalls 328
+#define	__NR_preadv		328
+#define	__NR_pwritev		329
+#define NR_syscalls 330
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/include/asm/vtoc.h linux-libre-2.6.30-gnu1/arch/s390/include/asm/vtoc.h
--- linux-libre-2.6.29-gnu1/arch/s390/include/asm/vtoc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/include/asm/vtoc.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@ struct vtoc_labeldate
 	__u16 day;
 } __attribute__ ((packed));
 
-struct vtoc_volume_label
+struct vtoc_volume_label_cdl
 {
 	char volkey[4];		/* volume key = volume label */
 	char vollbl[4];		/* volume label */
@@ -56,6 +56,14 @@ struct vtoc_volume_label
 	char res3[29];		/* reserved */
 } __attribute__ ((packed));
 
+struct vtoc_volume_label_ldl {
+	char vollbl[4];		/* volume label */
+	char volid[6];		/* volume identifier */
+	char res3[69];		/* reserved */
+	char ldl_version;	/* version number, valid for ldl format */
+	__u64 formatted_blocks; /* valid when ldl_version >= f2  */
+} __attribute__ ((packed));
+
 struct vtoc_extent
 {
 	__u8 typeind;			/* extent type indicator */
@@ -140,7 +148,11 @@ struct vtoc_format4_label
 	char res2[10];		/* reserved */
 	__u8 DS4EFLVL;		/* extended free-space management level */
 	struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
-	char res3[9];		/* reserved */
+	char res3;		/* reserved */
+	__u32 DS4DCYL;		/* number of logical cyls */
+	char res4[2];		/* reserved */
+	__u8 DS4DEVF2;		/* device flags */
+	char res5;		/* reserved */
 } __attribute__ ((packed));
 
 struct vtoc_ds5ext
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/Kconfig linux-libre-2.6.30-gnu1/arch/s390/Kconfig
--- linux-libre-2.6.29-gnu1/arch/s390/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -72,6 +72,9 @@ config PGSTE
 config VIRT_CPU_ACCOUNTING
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 mainmenu "Linux Kernel Configuration"
 
 config S390
@@ -79,6 +82,7 @@ config S390
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_SYSCALL_WRAPPERS
 	select HAVE_FUNCTION_TRACER
+	select HAVE_DEFAULT_NO_SPIN_MUTEXES
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
@@ -343,13 +347,6 @@ source "mm/Kconfig"
 
 comment "I/O subsystem configuration"
 
-config MACHCHK_WARNING
-	bool "Process warning machine checks"
-	help
-	  Select this option if you want the machine check handler on IBM S/390 or
-	  zSeries to process warning machine checks (e.g. on power failures).
-	  If unsure, say "Y".
-
 config QDIO
 	tristate "QDIO support"
 	---help---
@@ -521,7 +518,7 @@ config APPLDATA_OS
 
 config APPLDATA_NET_SUM
 	tristate "Monitor overall network statistics"
-	depends on APPLDATA_BASE
+	depends on APPLDATA_BASE && NET
 	help
 	  This provides network related data to the Linux - VM Monitor Stream,
 	  currently there is only a total sum of network I/O statistics, no
@@ -552,7 +549,7 @@ config KEXEC
 	  but is independent of hardware/microcode support.
 
 config ZFCPDUMP
-	tristate "zfcpdump support"
+	bool "zfcpdump support"
 	select SMP
 	default n
 	help
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/Kconfig.debug linux-libre-2.6.30-gnu1/arch/s390/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/s390/Kconfig.debug	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -6,12 +6,4 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
-config DEBUG_PAGEALLOC
-	bool "Debug page memory allocations"
-	depends on DEBUG_KERNEL
-	help
-	  Unmap pages from the kernel linear mapping after free_pages().
-	  This results in a slowdown, but helps to find certain types of
-	  memory corruptions.
-
 endmenu
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/s390/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/asm-offsets.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,8 @@ int main(void)
 	DEFINE(__TI_flags, offsetof(struct thread_info, flags));
 	DEFINE(__TI_cpu, offsetof(struct thread_info, cpu));
 	DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
+	DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));
+	DEFINE(__TI_system_timer, offsetof(struct thread_info, system_timer));
 	BLANK();
 	DEFINE(__PT_ARGS, offsetof(struct pt_regs, args));
 	DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/bitmap.c linux-libre-2.6.30-gnu1/arch/s390/kernel/bitmap.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/bitmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/bitmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ *    Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
+ *    See include/asm/{bitops.h|posix_types.h} for details
+ *
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ */
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+EXPORT_SYMBOL(_oi_bitmap);
+
+const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+EXPORT_SYMBOL(_ni_bitmap);
+
+const char _zb_findmap[] = {
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+	0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 };
+EXPORT_SYMBOL(_zb_findmap);
+
+const char _sb_findmap[] = {
+	8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+	4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 };
+EXPORT_SYMBOL(_sb_findmap);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/bitmap.S linux-libre-2.6.30-gnu1/arch/s390/kernel/bitmap.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/bitmap.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/bitmap.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- *  arch/s390/kernel/bitmap.S
- *    Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
- *    See include/asm-s390/{bitops.h|posix_types.h} for details
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-
-         .globl _oi_bitmap
-_oi_bitmap:
-         .byte  0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-
-         .globl _ni_bitmap
-_ni_bitmap:
-         .byte  0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
-
-         .globl _zb_findmap
-_zb_findmap:
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4 
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
-         .byte  0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
-
-         .globl _sb_findmap
-_sb_findmap:
-         .byte  8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-         .byte  4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_linux.c linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_linux.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_linux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_linux.c	2009-06-09 23:05:27.000000000 -0400
@@ -702,20 +702,12 @@ asmlinkage long sys32_fstatat64(unsigned
 				struct stat64_emu31 __user* statbuf, int flag)
 {
 	struct kstat stat;
-	int error = -EINVAL;
-
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-		goto out;
-
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
-	else
-		error = vfs_stat_fd(dfd, filename, &stat);
+	int error;
 
-	if (!error)
-		error = cp_stat64(statbuf, &stat);
-out:
-	return error;
+	error = vfs_fstatat(dfd, filename, &stat, flag);
+	if (error)
+		return error;
+	return cp_stat64(statbuf, &stat);
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_ptrace.h linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_ptrace.h
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,11 @@
 #ifndef _PTRACE32_H
 #define _PTRACE32_H
 
+#include <asm/ptrace.h>    /* needed for NUM_CR_WORDS */
 #include "compat_linux.h"  /* needed for psw_compat_t */
 
 typedef struct {
-	__u32 cr[3];
+	__u32 cr[NUM_CR_WORDS];
 } per_cr_words32;
 
 typedef struct {
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_wrapper.S linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_wrapper.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/compat_wrapper.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/compat_wrapper.S	2009-06-09 23:05:27.000000000 -0400
@@ -252,7 +252,7 @@ sys32_chroot_wrapper:
 sys32_ustat_wrapper:
 	llgfr	%r2,%r2			# dev_t
 	llgtr	%r3,%r3			# struct ustat *
-	jg	sys_ustat
+	jg	compat_sys_ustat
 
 	.globl	sys32_dup2_wrapper
 sys32_dup2_wrapper:
@@ -1805,3 +1805,21 @@ compat_sys_keyctl_wrapper:
 	llgfr	%r5,%r5			# u32
 	llgfr	%r6,%r6			# u32
 	jg	compat_sys_keyctl	# branch to system call
+
+	.globl	compat_sys_preadv_wrapper
+compat_sys_preadv_wrapper:
+	llgfr	%r2,%r2			# unsigned long
+	llgtr	%r3,%r3			# compat_iovec *
+	llgfr	%r4,%r4			# unsigned long
+	llgfr	%r5,%r5			# u32
+	llgfr	%r6,%r6			# u32
+	jg	compat_sys_preadv	# branch to system call
+
+	.globl	compat_sys_pwritev_wrapper
+compat_sys_pwritev_wrapper:
+	llgfr	%r2,%r2			# unsigned long
+	llgtr	%r3,%r3			# compat_iovec *
+	llgfr	%r4,%r4			# unsigned long
+	llgfr	%r5,%r5			# u32
+	llgfr	%r6,%r6			# u32
+	jg	compat_sys_pwritev	# branch to system call
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/debug.c linux-libre-2.6.30-gnu1/arch/s390/kernel/debug.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -603,7 +603,7 @@ debug_input(struct file *file, const cha
 static int
 debug_open(struct inode *inode, struct file *file)
 {
-	int i = 0, rc = 0;
+	int i, rc = 0;
 	file_private_info_t *p_info;
 	debug_info_t *debug_info, *debug_info_snapshot;
 
@@ -642,8 +642,7 @@ found:
 	p_info = kmalloc(sizeof(file_private_info_t),
 						GFP_KERNEL);
 	if(!p_info){
-		if(debug_info_snapshot)
-			debug_info_free(debug_info_snapshot);
+		debug_info_free(debug_info_snapshot);
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -698,8 +697,7 @@ debug_info_t *debug_register_mode(const
 	if ((uid != 0) || (gid != 0))
 		pr_warning("Root becomes the owner of all s390dbf files "
 			   "in sysfs\n");
-	if (!initialized)
-		BUG();
+	BUG_ON(!initialized);
 	mutex_lock(&debug_mutex);
 
         /* create new debug_info */
@@ -1156,7 +1154,6 @@ debug_unregister_view(debug_info_t * id,
 	else {
 		debugfs_remove(id->debugfs_entries[i]);
 		id->views[i] = NULL;
-		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
 out:
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/early.c linux-libre-2.6.30-gnu1/arch/s390/kernel/early.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/early.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/early.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -20,6 +21,7 @@
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
+#include <asm/sysinfo.h>
 #include <asm/cpcmd.h>
 #include <asm/sclp.h>
 #include "entry.h"
@@ -32,8 +34,25 @@
 
 char kernel_nss_name[NSS_NAME_SIZE + 1];
 
+static unsigned long machine_flags;
+
 static void __init setup_boot_command_line(void);
 
+/*
+ * Get the TOD clock running.
+ */
+static void __init reset_tod_clock(void)
+{
+	u64 time;
+
+	if (store_clock(&time) == 0)
+		return;
+	/* TOD clock not running. Set the clock to Unix Epoch. */
+	if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0)
+		disabled_wait(0);
+
+	sched_clock_base_cc = TOD_UNIX_EPOCH;
+}
 
 #ifdef CONFIG_SHARED_KERNEL
 int __init savesys_ipl_nss(char *cmd, const int cmdlen);
@@ -173,19 +192,21 @@ static noinline __init void init_kernel_
 		page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
 }
 
+static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
+
 static noinline __init void detect_machine_type(void)
 {
-	struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
-
-	get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
-
-	/* Running under z/VM ? */
-	if (cpuinfo->cpu_id.version == 0xff)
-		machine_flags |= MACHINE_FLAG_VM;
+	/* No VM information? Looks like LPAR */
+	if (stsi(&vmms, 3, 2, 2) == -ENOSYS)
+		return;
+	if (!vmms.count)
+		return;
 
-	/* Running under KVM ? */
-	if (cpuinfo->cpu_id.version == 0xfe)
+	/* Running under KVM? If not we assume z/VM */
+	if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3))
 		machine_flags |= MACHINE_FLAG_KVM;
+	else
+		machine_flags |= MACHINE_FLAG_VM;
 }
 
 static __init void early_pgm_check_handler(void)
@@ -348,7 +369,6 @@ static void __init setup_boot_command_li
 
 	/* copy arch command line */
 	strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
-	boot_command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0;
 
 	/* append IPL PARM data to the boot command line */
 	if (MACHINE_IS_VM) {
@@ -367,6 +387,7 @@ static void __init setup_boot_command_li
  */
 void __init startup_init(void)
 {
+	reset_tod_clock();
 	ipl_save_parameters();
 	rescue_initrd();
 	clear_bss_section();
@@ -388,5 +409,6 @@ void __init startup_init(void)
 	setup_hpage();
 	sclp_facilities_detect();
 	detect_memory_layout(memory_chunk);
+	S390_lowcore.machine_flags = machine_flags;
 	lockdep_on();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/entry64.S linux-libre-2.6.30-gnu1/arch/s390/kernel/entry64.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/entry64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/entry64.S	2009-06-09 23:05:27.000000000 -0400
@@ -831,14 +831,27 @@ mcck_return:
 	__CPUINIT
 	.globl restart_int_handler
 restart_int_handler:
+	basr	%r1,0
+restart_base:
+	spt	restart_vtime-restart_base(%r1)
+	stck	__LC_LAST_UPDATE_CLOCK
+	mvc	__LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
+	mvc	__LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
 	lg	%r15,__LC_SAVE_AREA+120 # load ksp
 	lghi	%r10,__LC_CREGS_SAVE_AREA
 	lctlg	%c0,%c15,0(%r10) # get new ctl regs
 	lghi	%r10,__LC_AREGS_SAVE_AREA
 	lam	%a0,%a15,0(%r10)
 	lmg	%r6,%r15,__SF_GPRS(%r15) # load registers from clone
+	lg	%r1,__LC_THREAD_INFO
+	mvc	__LC_USER_TIMER(8),__TI_user_timer(%r1)
+	mvc	__LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
+	xc	__LC_STEAL_TIMER(8),__LC_STEAL_TIMER
 	stosm	__SF_EMPTY(%r15),0x04	# now we can turn dat on
 	jg	start_secondary
+	.align	8
+restart_vtime:
+	.long	0x7fffffff,0xffffffff
 	.previous
 #else
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/entry.S linux-libre-2.6.30-gnu1/arch/s390/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -837,16 +837,29 @@ mcck_return:
 	__CPUINIT
 	.globl restart_int_handler
 restart_int_handler:
+	basr	%r1,0
+restart_base:
+	spt	restart_vtime-restart_base(%r1)
+	stck	__LC_LAST_UPDATE_CLOCK
+	mvc	__LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
+	mvc	__LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
 	l	%r15,__LC_SAVE_AREA+60	# load ksp
 	lctl	%c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
 	lam	%a0,%a15,__LC_AREGS_SAVE_AREA
 	lm	%r6,%r15,__SF_GPRS(%r15) # load registers from clone
+	l	%r1,__LC_THREAD_INFO
+	mvc	__LC_USER_TIMER(8),__TI_user_timer(%r1)
+	mvc	__LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
+	xc	__LC_STEAL_TIMER(8),__LC_STEAL_TIMER
 	stosm	__SF_EMPTY(%r15),0x04	# now we can turn dat on
 	basr	%r14,0
 	l	%r14,restart_addr-.(%r14)
 	br	%r14			# branch to start_secondary
 restart_addr:
 	.long	start_secondary
+	.align	8
+restart_vtime:
+	.long	0x7fffffff,0xffffffff
 	.previous
 #else
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/head31.S linux-libre-2.6.30-gnu1/arch/s390/kernel/head31.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/head31.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/head31.S	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@ startup_continue:
 	lctl	%c0,%c15,.Lctl-.LPG1(%r13) # load control registers
 	l	%r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
 					# move IPL device to lowcore
-	mvc	__LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
 #
 # Setup stack
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/head64.S linux-libre-2.6.30-gnu1/arch/s390/kernel/head64.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/head64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/head64.S	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,6 @@ startup_continue:
 	lctlg	%c0,%c15,.Lctl-.LPG1(%r13)	# load control registers
 	lg	%r12,.Lparmaddr-.LPG1(%r13)	# pointer to parameter area
 					# move IPL device to lowcore
-	mvc	__LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
 	lghi	%r0,__LC_PASTE
 	stg	%r0,__LC_VDSO_PER_CPU
 #
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/head.S linux-libre-2.6.30-gnu1/arch/s390/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
  *
  */
 
+#include <linux/init.h>
 #include <asm/setup.h>
 #include <asm/lowcore.h>
 #include <asm/asm-offsets.h>
@@ -35,7 +36,7 @@
 #define ARCH_OFFSET	0
 #endif
 
-.section ".text.head","ax"
+__HEAD
 #ifndef CONFIG_IPL
 	.org   0
 	.long  0x00080000,0x80000000+startup	# Just a restart PSW
@@ -469,7 +470,14 @@ start:
 	.org	0x10000
 startup:basr	%r13,0			# get base
 .LPG0:
-
+	xc	0x200(256),0x200	# partially clear lowcore
+	xc	0x300(256),0x300
+	l	%r1,5f-.LPG0(%r13)
+	stck	0(%r1)
+	spt	6f-.LPG0(%r13)
+	mvc	__LC_LAST_UPDATE_CLOCK(8),0(%r1)
+	mvc	__LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
+	mvc	__LC_EXIT_TIMER(8),5f-.LPG0(%r13)
 #ifndef CONFIG_MARCH_G5
 	# check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
 	stidp	__LC_CPUID		# store cpuid
@@ -494,9 +502,13 @@ startup:basr	%r13,0			# get base
 	brct	%r0,0b
 #endif
 
-	l	%r13,0f-.LPG0(%r13)
+	l	%r13,4f-.LPG0(%r13)
 	b	0(%r13)
-0:	.long	startup_continue
+	.align	4
+4:	.long	startup_continue
+5:	.long	sched_clock_base_cc
+	.align	8
+6:	.long	0x7fffffff,0xffffffff
 
 #
 # params at 10400 (setup.h)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/ipl.c linux-libre-2.6.30-gnu1/arch/s390/kernel/ipl.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/ipl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/ipl.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,8 @@
 #include <asm/ebcdic.h>
 #include <asm/reset.h>
 #include <asm/sclp.h>
-#include <asm/setup.h>
+#include <asm/sigp.h>
+#include <asm/checksum.h>
 
 #define IPL_PARM_BLOCK_VERSION 0
 
@@ -56,13 +57,14 @@ struct shutdown_trigger {
 };
 
 /*
- * Five shutdown action types are supported:
+ * The following shutdown action types are supported:
  */
 #define SHUTDOWN_ACTION_IPL_STR		"ipl"
 #define SHUTDOWN_ACTION_REIPL_STR	"reipl"
 #define SHUTDOWN_ACTION_DUMP_STR	"dump"
 #define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
 #define SHUTDOWN_ACTION_STOP_STR	"stop"
+#define SHUTDOWN_ACTION_DUMP_REIPL_STR	"dump_reipl"
 
 struct shutdown_action {
 	char *name;
@@ -146,6 +148,7 @@ static enum ipl_method reipl_method = RE
 static struct ipl_parameter_block *reipl_block_fcp;
 static struct ipl_parameter_block *reipl_block_ccw;
 static struct ipl_parameter_block *reipl_block_nss;
+static struct ipl_parameter_block *reipl_block_actual;
 
 static int dump_capabilities = DUMP_TYPE_NONE;
 static enum dump_type dump_type = DUMP_TYPE_NONE;
@@ -835,6 +838,7 @@ static int reipl_set_type(enum ipl_type
 			reipl_method = REIPL_METHOD_CCW_VM;
 		else
 			reipl_method = REIPL_METHOD_CCW_CIO;
+		reipl_block_actual = reipl_block_ccw;
 		break;
 	case IPL_TYPE_FCP:
 		if (diag308_set_works)
@@ -843,6 +847,7 @@ static int reipl_set_type(enum ipl_type
 			reipl_method = REIPL_METHOD_FCP_RO_VM;
 		else
 			reipl_method = REIPL_METHOD_FCP_RO_DIAG;
+		reipl_block_actual = reipl_block_fcp;
 		break;
 	case IPL_TYPE_FCP_DUMP:
 		reipl_method = REIPL_METHOD_FCP_DUMP;
@@ -852,6 +857,7 @@ static int reipl_set_type(enum ipl_type
 			reipl_method = REIPL_METHOD_NSS_DIAG;
 		else
 			reipl_method = REIPL_METHOD_NSS;
+		reipl_block_actual = reipl_block_nss;
 		break;
 	case IPL_TYPE_UNKNOWN:
 		reipl_method = REIPL_METHOD_DEFAULT;
@@ -960,7 +966,6 @@ static void reipl_run(struct shutdown_tr
 		diag308(DIAG308_IPL, NULL);
 		break;
 	case REIPL_METHOD_FCP_DUMP:
-	default:
 		break;
 	}
 	disabled_wait((unsigned long) __builtin_return_address(0));
@@ -1069,10 +1074,12 @@ static int __init reipl_fcp_init(void)
 {
 	int rc;
 
-	if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP))
-		return 0;
-	if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP))
-		make_attrs_ro(reipl_fcp_attrs);
+	if (!diag308_set_works) {
+		if (ipl_info.type == IPL_TYPE_FCP)
+			make_attrs_ro(reipl_fcp_attrs);
+		else
+			return 0;
+	}
 
 	reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!reipl_block_fcp)
@@ -1253,7 +1260,6 @@ static void dump_run(struct shutdown_tri
 		diag308(DIAG308_DUMP, NULL);
 		break;
 	case DUMP_METHOD_NONE:
-	default:
 		return;
 	}
 	printk(KERN_EMERG "Dump failed!\n");
@@ -1332,6 +1338,49 @@ static struct shutdown_action __refdata
 	.init	= dump_init,
 };
 
+static void dump_reipl_run(struct shutdown_trigger *trigger)
+{
+	preempt_disable();
+	/*
+	 * Bypass dynamic address translation (DAT) when storing IPL parameter
+	 * information block address and checksum into the prefix area
+	 * (corresponding to absolute addresses 0-8191).
+	 * When enhanced DAT applies and the STE format control in one,
+	 * the absolute address is formed without prefixing. In this case a
+	 * normal store (stg/st) into the prefix area would no more match to
+	 * absolute addresses 0-8191.
+	 */
+#ifdef CONFIG_64BIT
+	asm volatile("sturg %0,%1"
+		:: "a" ((unsigned long) reipl_block_actual),
+		"a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#else
+	asm volatile("stura %0,%1"
+		:: "a" ((unsigned long) reipl_block_actual),
+		"a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#endif
+	asm volatile("stura %0,%1"
+		:: "a" (csum_partial(reipl_block_actual,
+				     reipl_block_actual->hdr.len, 0)),
+		"a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum));
+	preempt_enable();
+	dump_run(trigger);
+}
+
+static int __init dump_reipl_init(void)
+{
+	if (!diag308_set_works)
+		return -EOPNOTSUPP;
+	else
+		return 0;
+}
+
+static struct shutdown_action __refdata dump_reipl_action = {
+	.name	= SHUTDOWN_ACTION_DUMP_REIPL_STR,
+	.fn	= dump_reipl_run,
+	.init	= dump_reipl_init,
+};
+
 /*
  * vmcmd shutdown action: Trigger vm command on shutdown.
  */
@@ -1421,7 +1470,8 @@ static struct shutdown_action stop_actio
 /* action list */
 
 static struct shutdown_action *shutdown_actions_list[] = {
-	&ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
+	&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
+	&vmcmd_action, &stop_action};
 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
 
 /*
@@ -1434,11 +1484,11 @@ static int set_trigger(const char *buf,
 		       size_t len)
 {
 	int i;
+
 	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
 		if (!shutdown_actions_list[i])
 			continue;
-		if (strncmp(buf, shutdown_actions_list[i]->name,
-			    strlen(shutdown_actions_list[i]->name)) == 0) {
+		if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
 			trigger->action = shutdown_actions_list[i];
 			return len;
 		}
@@ -1672,7 +1722,7 @@ static int on_panic_notify(struct notifi
 
 static struct notifier_block on_panic_nb = {
 	.notifier_call = on_panic_notify,
-	.priority = 0,
+	.priority = INT_MIN,
 };
 
 void __init setup_ipl(void)
@@ -1696,7 +1746,6 @@ void __init setup_ipl(void)
 			sizeof(ipl_info.data.nss.name));
 		break;
 	case IPL_TYPE_UNKNOWN:
-	default:
 		/* We have no info to copy */
 		break;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/Makefile linux-libre-2.6.30-gnu1/arch/s390/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -17,10 +17,12 @@ CFLAGS_smp.o	:= -Wno-nonnull
 #
 CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
 
+CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
+
 obj-y	:=  bitmap.o traps.o time.o process.o base.o early.o setup.o \
 	    processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
 	    s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
-	    vdso.o vtime.o
+	    vdso.o vtime.o sysinfo.o nmi.o
 
 obj-y	+= $(if $(CONFIG_64BIT),entry64.o,entry.o)
 obj-y	+= $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/module.c linux-libre-2.6.30-gnu1/arch/s390/kernel/module.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/module.c	2009-06-09 23:05:27.000000000 -0400
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 			info->plt_initialized = 1;
 		}
 		if (r_type == R_390_PLTOFF16 ||
-		    r_type == R_390_PLTOFF32
-		    || r_type == R_390_PLTOFF64
-			)
+		    r_type == R_390_PLTOFF32 ||
+		    r_type == R_390_PLTOFF64)
 			val = me->arch.plt_offset - me->arch.got_offset +
 				info->plt_offset + rela->r_addend;
-		else
-			val =  (Elf_Addr) me->module_core +
-				me->arch.plt_offset + info->plt_offset + 
-				rela->r_addend - loc;
+		else {
+			if (!((r_type == R_390_PLT16DBL &&
+			       val - loc + 0xffffUL < 0x1ffffeUL) ||
+			      (r_type == R_390_PLT32DBL &&
+			       val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+				val = (Elf_Addr) me->module_core +
+					me->arch.plt_offset +
+					info->plt_offset;
+			val += rela->r_addend - loc;
+		}
 		if (r_type == R_390_PLT16DBL)
 			*(unsigned short *) loc = val >> 1;
 		else if (r_type == R_390_PLTOFF16)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/nmi.c linux-libre-2.6.30-gnu1/arch/s390/kernel/nmi.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/nmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/nmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,377 @@
+/*
+ *   Machine check handler
+ *
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/hardirq.h>
+#include <linux/time.h>
+#include <linux/module.h>
+#include <asm/lowcore.h>
+#include <asm/smp.h>
+#include <asm/etr.h>
+#include <asm/cpu.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
+
+struct mcck_struct {
+	int kill_task;
+	int channel_report;
+	int warning;
+	unsigned long long mcck_code;
+};
+
+static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
+
+static NORET_TYPE void s390_handle_damage(char *msg)
+{
+	smp_send_stop();
+	disabled_wait((unsigned long) __builtin_return_address(0));
+	while (1);
+}
+
+/*
+ * Main machine check handler function. Will be called with interrupts enabled
+ * or disabled and machine checks enabled or disabled.
+ */
+void s390_handle_mcck(void)
+{
+	unsigned long flags;
+	struct mcck_struct mcck;
+
+	/*
+	 * Disable machine checks and get the current state of accumulated
+	 * machine checks. Afterwards delete the old state and enable machine
+	 * checks again.
+	 */
+	local_irq_save(flags);
+	local_mcck_disable();
+	mcck = __get_cpu_var(cpu_mcck);
+	memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
+	clear_thread_flag(TIF_MCCK_PENDING);
+	local_mcck_enable();
+	local_irq_restore(flags);
+
+	if (mcck.channel_report)
+		crw_handle_channel_report();
+	/*
+	 * A warning may remain for a prolonged period on the bare iron.
+	 * (actually until the machine is powered off, or the problem is gone)
+	 * So we just stop listening for the WARNING MCH and avoid continuously
+	 * being interrupted.  One caveat is however, that we must do this per
+	 * processor and cannot use the smp version of ctl_clear_bit().
+	 * On VM we only get one interrupt per virtally presented machinecheck.
+	 * Though one suffices, we may get one interrupt per (virtual) cpu.
+	 */
+	if (mcck.warning) {	/* WARNING pending ? */
+		static int mchchk_wng_posted = 0;
+
+		/* Use single cpu clear, as we cannot handle smp here. */
+		__ctl_clear_bit(14, 24);	/* Disable WARNING MCH */
+		if (xchg(&mchchk_wng_posted, 1) == 0)
+			kill_cad_pid(SIGPWR, 1);
+	}
+	if (mcck.kill_task) {
+		local_irq_enable();
+		printk(KERN_EMERG "mcck: Terminating task because of machine "
+		       "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
+		       current->comm, current->pid);
+		do_exit(SIGSEGV);
+	}
+}
+EXPORT_SYMBOL_GPL(s390_handle_mcck);
+
+/*
+ * returns 0 if all registers could be validated
+ * returns 1 otherwise
+ */
+static int notrace s390_revalidate_registers(struct mci *mci)
+{
+	int kill_task;
+	u64 tmpclock;
+	u64 zero;
+	void *fpt_save_area, *fpt_creg_save_area;
+
+	kill_task = 0;
+	zero = 0;
+
+	if (!mci->gr) {
+		/*
+		 * General purpose registers couldn't be restored and have
+		 * unknown contents. Process needs to be terminated.
+		 */
+		kill_task = 1;
+	}
+	if (!mci->fp) {
+		/*
+		 * Floating point registers can't be restored and
+		 * therefore the process needs to be terminated.
+		 */
+		kill_task = 1;
+	}
+#ifndef CONFIG_64BIT
+	asm volatile(
+		"	ld	0,0(%0)\n"
+		"	ld	2,8(%0)\n"
+		"	ld	4,16(%0)\n"
+		"	ld	6,24(%0)"
+		: : "a" (&S390_lowcore.floating_pt_save_area));
+#endif
+
+	if (MACHINE_HAS_IEEE) {
+#ifdef CONFIG_64BIT
+		fpt_save_area = &S390_lowcore.floating_pt_save_area;
+		fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
+#else
+		fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
+		fpt_creg_save_area = fpt_save_area + 128;
+#endif
+		if (!mci->fc) {
+			/*
+			 * Floating point control register can't be restored.
+			 * Task will be terminated.
+			 */
+			asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
+			kill_task = 1;
+
+		} else
+			asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
+
+		asm volatile(
+			"	ld	0,0(%0)\n"
+			"	ld	1,8(%0)\n"
+			"	ld	2,16(%0)\n"
+			"	ld	3,24(%0)\n"
+			"	ld	4,32(%0)\n"
+			"	ld	5,40(%0)\n"
+			"	ld	6,48(%0)\n"
+			"	ld	7,56(%0)\n"
+			"	ld	8,64(%0)\n"
+			"	ld	9,72(%0)\n"
+			"	ld	10,80(%0)\n"
+			"	ld	11,88(%0)\n"
+			"	ld	12,96(%0)\n"
+			"	ld	13,104(%0)\n"
+			"	ld	14,112(%0)\n"
+			"	ld	15,120(%0)\n"
+			: : "a" (fpt_save_area));
+	}
+	/* Revalidate access registers */
+	asm volatile(
+		"	lam	0,15,0(%0)"
+		: : "a" (&S390_lowcore.access_regs_save_area));
+	if (!mci->ar) {
+		/*
+		 * Access registers have unknown contents.
+		 * Terminating task.
+		 */
+		kill_task = 1;
+	}
+	/* Revalidate control registers */
+	if (!mci->cr) {
+		/*
+		 * Control registers have unknown contents.
+		 * Can't recover and therefore stopping machine.
+		 */
+		s390_handle_damage("invalid control registers.");
+	} else {
+#ifdef CONFIG_64BIT
+		asm volatile(
+			"	lctlg	0,15,0(%0)"
+			: : "a" (&S390_lowcore.cregs_save_area));
+#else
+		asm volatile(
+			"	lctl	0,15,0(%0)"
+			: : "a" (&S390_lowcore.cregs_save_area));
+#endif
+	}
+	/*
+	 * We don't even try to revalidate the TOD register, since we simply
+	 * can't write something sensible into that register.
+	 */
+#ifdef CONFIG_64BIT
+	/*
+	 * See if we can revalidate the TOD programmable register with its
+	 * old contents (should be zero) otherwise set it to zero.
+	 */
+	if (!mci->pr)
+		asm volatile(
+			"	sr	0,0\n"
+			"	sckpf"
+			: : : "0", "cc");
+	else
+		asm volatile(
+			"	l	0,0(%0)\n"
+			"	sckpf"
+			: : "a" (&S390_lowcore.tod_progreg_save_area)
+			: "0", "cc");
+#endif
+	/* Revalidate clock comparator register */
+	asm volatile(
+		"	stck	0(%1)\n"
+		"	sckc	0(%1)"
+		: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+
+	/* Check if old PSW is valid */
+	if (!mci->wp)
+		/*
+		 * Can't tell if we come from user or kernel mode
+		 * -> stopping machine.
+		 */
+		s390_handle_damage("old psw invalid.");
+
+	if (!mci->ms || !mci->pm || !mci->ia)
+		kill_task = 1;
+
+	return kill_task;
+}
+
+#define MAX_IPD_COUNT	29
+#define MAX_IPD_TIME	(5 * 60 * USEC_PER_SEC) /* 5 minutes */
+
+#define ED_STP_ISLAND	6	/* External damage STP island check */
+#define ED_STP_SYNC	7	/* External damage STP sync check */
+#define ED_ETR_SYNC	12	/* External damage ETR sync check */
+#define ED_ETR_SWITCH	13	/* External damage ETR switch to local */
+
+/*
+ * machine check handler.
+ */
+void notrace s390_do_machine_check(struct pt_regs *regs)
+{
+	static int ipd_count;
+	static DEFINE_SPINLOCK(ipd_lock);
+	static unsigned long long last_ipd;
+	struct mcck_struct *mcck;
+	unsigned long long tmp;
+	struct mci *mci;
+	int umode;
+
+	nmi_enter();
+	s390_idle_check();
+
+	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+	mcck = &__get_cpu_var(cpu_mcck);
+	umode = user_mode(regs);
+
+	if (mci->sd) {
+		/* System damage -> stopping machine */
+		s390_handle_damage("received system damage machine check.");
+	}
+	if (mci->pd) {
+		if (mci->b) {
+			/* Processing backup -> verify if we can survive this */
+			u64 z_mcic, o_mcic, t_mcic;
+#ifdef CONFIG_64BIT
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
+				  1ULL<<16);
+#else
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
+				  1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
+#endif
+			t_mcic = *(u64 *)mci;
+
+			if (((t_mcic & z_mcic) != 0) ||
+			    ((t_mcic & o_mcic) != o_mcic)) {
+				s390_handle_damage("processing backup machine "
+						   "check with damage.");
+			}
+
+			/*
+			 * Nullifying exigent condition, therefore we might
+			 * retry this instruction.
+			 */
+			spin_lock(&ipd_lock);
+			tmp = get_clock();
+			if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
+				ipd_count++;
+			else
+				ipd_count = 1;
+			last_ipd = tmp;
+			if (ipd_count == MAX_IPD_COUNT)
+				s390_handle_damage("too many ipd retries.");
+			spin_unlock(&ipd_lock);
+		} else {
+			/* Processing damage -> stopping machine */
+			s390_handle_damage("received instruction processing "
+					   "damage machine check.");
+		}
+	}
+	if (s390_revalidate_registers(mci)) {
+		if (umode) {
+			/*
+			 * Couldn't restore all register contents while in
+			 * user mode -> mark task for termination.
+			 */
+			mcck->kill_task = 1;
+			mcck->mcck_code = *(unsigned long long *) mci;
+			set_thread_flag(TIF_MCCK_PENDING);
+		} else {
+			/*
+			 * Couldn't restore all register contents while in
+			 * kernel mode -> stopping machine.
+			 */
+			s390_handle_damage("unable to revalidate registers.");
+		}
+	}
+	if (mci->cd) {
+		/* Timing facility damage */
+		s390_handle_damage("TOD clock damaged");
+	}
+	if (mci->ed && mci->ec) {
+		/* External damage */
+		if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
+			etr_sync_check();
+		if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
+			etr_switch_to_local();
+		if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
+			stp_sync_check();
+		if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
+			stp_island_check();
+	}
+	if (mci->se)
+		/* Storage error uncorrected */
+		s390_handle_damage("received storage error uncorrected "
+				   "machine check.");
+	if (mci->ke)
+		/* Storage key-error uncorrected */
+		s390_handle_damage("received storage key-error uncorrected "
+				   "machine check.");
+	if (mci->ds && mci->fa)
+		/* Storage degradation */
+		s390_handle_damage("received storage degradation machine "
+				   "check.");
+	if (mci->cp) {
+		/* Channel report word pending */
+		mcck->channel_report = 1;
+		set_thread_flag(TIF_MCCK_PENDING);
+	}
+	if (mci->w) {
+		/* Warning pending */
+		mcck->warning = 1;
+		set_thread_flag(TIF_MCCK_PENDING);
+	}
+	nmi_exit();
+}
+
+static int __init machine_check_init(void)
+{
+	ctl_set_bit(14, 25);	/* enable external damage MCH */
+	ctl_set_bit(14, 27);	/* enable system recovery MCH */
+	ctl_set_bit(14, 24);	/* enable warning MCH */
+	return 0;
+}
+arch_initcall(machine_check_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/process.c linux-libre-2.6.30-gnu1/arch/s390/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,18 +1,10 @@
 /*
- *  arch/s390/kernel/process.c
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Hartmut Penner (hp@de.ibm.com),
- *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ * This file handles the architecture dependent parts of process handling.
  *
- *  Derived from "arch/i386/kernel/process.c"
- *    Copyright (C) 1995, Linus Torvalds
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
+ *    Copyright IBM Corp. 1999,2009
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Hartmut Penner <hp@de.ibm.com>,
+ *		 Denis Joseph Barrow,
  */
 
 #include <linux/compiler.h>
@@ -47,6 +39,7 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/timer.h>
+#include <asm/nmi.h>
 #include "entry.h"
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -76,7 +69,6 @@ unsigned long thread_saved_pc(struct tas
 	return sf->gprs[8];
 }
 
-extern void s390_handle_mcck(void);
 /*
  * The idle loop on a S390...
  */
@@ -149,6 +141,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..
@@ -167,35 +160,36 @@ void release_thread(struct task_struct *
 {
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
-	unsigned long unused,
-        struct task_struct * p, struct pt_regs * regs)
+int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
+		unsigned long unused,
+		struct task_struct *p, struct pt_regs *regs)
 {
-        struct fake_frame
-          {
-	    struct stack_frame sf;
-            struct pt_regs childregs;
-          } *frame;
+	struct thread_info *ti;
+	struct fake_frame
+	{
+		struct stack_frame sf;
+		struct pt_regs childregs;
+	} *frame;
 
-        frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
-        p->thread.ksp = (unsigned long) frame;
+	frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
+	p->thread.ksp = (unsigned long) frame;
 	/* Store access registers to kernel stack of new process. */
-        frame->childregs = *regs;
+	frame->childregs = *regs;
 	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
-        frame->childregs.gprs[15] = new_stackp;
-        frame->sf.back_chain = 0;
+	frame->childregs.gprs[15] = new_stackp;
+	frame->sf.back_chain = 0;
 
-        /* new return point is ret_from_fork */
-        frame->sf.gprs[8] = (unsigned long) ret_from_fork;
+	/* new return point is ret_from_fork */
+	frame->sf.gprs[8] = (unsigned long) ret_from_fork;
 
-        /* fake return stack for resume(), don't go back to schedule */
-        frame->sf.gprs[9] = (unsigned long) frame;
+	/* fake return stack for resume(), don't go back to schedule */
+	frame->sf.gprs[9] = (unsigned long) frame;
 
 	/* Save access registers to new thread structure. */
 	save_access_regs(&p->thread.acrs[0]);
 
 #ifndef CONFIG_64BIT
-        /*
+	/*
 	 * save fprs to current->thread.fp_regs to merge them with
 	 * the emulated registers and then copy the result to the child.
 	 */
@@ -220,10 +214,13 @@ int copy_thread(int nr, unsigned long cl
 #endif /* CONFIG_64BIT */
 	/* start new process with ar4 pointing to the correct address space */
 	p->thread.mm_segment = get_fs();
-        /* Don't copy debug registers */
-        memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
-
-        return 0;
+	/* Don't copy debug registers */
+	memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
+	/* Initialize per thread user and system timer values */
+	ti = task_thread_info(p);
+	ti->user_timer = 0;
+	ti->system_timer = 0;
+	return 0;
 }
 
 SYSCALL_DEFINE0(fork)
@@ -311,7 +308,7 @@ out:
 int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
 {
 #ifndef CONFIG_64BIT
-        /*
+	/*
 	 * save fprs to current->thread.fp_regs to merge them with
 	 * the emulated registers and then copy the result to the dump.
 	 */
@@ -322,6 +319,7 @@ int dump_fpu (struct pt_regs * regs, s39
 #endif /* CONFIG_64BIT */
 	return 1;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 unsigned long get_wchan(struct task_struct *p)
 {
@@ -346,4 +344,3 @@ unsigned long get_wchan(struct task_stru
 	}
 	return 0;
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/processor.c linux-libre-2.6.30-gnu1/arch/s390/kernel/processor.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/processor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/processor.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,10 +18,11 @@
 #include <asm/lowcore.h>
 #include <asm/param.h>
 
-void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+void __cpuinit print_cpu_info(void)
 {
 	pr_info("Processor %d started, address %d, identification %06X\n",
-		cpuinfo->cpu_nr, cpuinfo->cpu_addr, cpuinfo->cpu_id.ident);
+		S390_lowcore.cpu_nr, S390_lowcore.cpu_addr,
+		S390_lowcore.cpu_id.ident);
 }
 
 /*
@@ -30,48 +31,46 @@ void __cpuinit print_cpu_info(struct cpu
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-	static const char *hwcap_str[8] = {
+	static const char *hwcap_str[9] = {
 		"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
-		"edat"
+		"edat", "etf3eh"
 	};
-       struct cpuinfo_S390 *cpuinfo;
-       unsigned long n = (unsigned long) v - 1;
-       int i;
+	struct _lowcore *lc;
+	unsigned long n = (unsigned long) v - 1;
+	int i;
 
-       s390_adjust_jiffies();
-       preempt_disable();
-       if (!n) {
-	       seq_printf(m, "vendor_id       : IBM/S390\n"
-			  "# processors    : %i\n"
-			  "bogomips per cpu: %lu.%02lu\n",
-			  num_online_cpus(), loops_per_jiffy/(500000/HZ),
-			  (loops_per_jiffy/(5000/HZ))%100);
-	       seq_puts(m, "features\t: ");
-	       for (i = 0; i < 8; i++)
-		       if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
-			       seq_printf(m, "%s ", hwcap_str[i]);
-	       seq_puts(m, "\n");
-       }
+	s390_adjust_jiffies();
+	preempt_disable();
+	if (!n) {
+		seq_printf(m, "vendor_id       : IBM/S390\n"
+			   "# processors    : %i\n"
+			   "bogomips per cpu: %lu.%02lu\n",
+			   num_online_cpus(), loops_per_jiffy/(500000/HZ),
+			   (loops_per_jiffy/(5000/HZ))%100);
+		seq_puts(m, "features\t: ");
+		for (i = 0; i < 9; i++)
+			if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
+				seq_printf(m, "%s ", hwcap_str[i]);
+		seq_puts(m, "\n");
+	}
 
-       if (cpu_online(n)) {
+	if (cpu_online(n)) {
 #ifdef CONFIG_SMP
-	       if (smp_processor_id() == n)
-		       cpuinfo = &S390_lowcore.cpu_data;
-	       else
-		       cpuinfo = &lowcore_ptr[n]->cpu_data;
+		lc = (smp_processor_id() == n) ?
+			&S390_lowcore : lowcore_ptr[n];
 #else
-	       cpuinfo = &S390_lowcore.cpu_data;
+		lc = &S390_lowcore;
 #endif
-	       seq_printf(m, "processor %li: "
-			  "version = %02X,  "
-			  "identification = %06X,  "
-			  "machine = %04X\n",
-			  n, cpuinfo->cpu_id.version,
-			  cpuinfo->cpu_id.ident,
-			  cpuinfo->cpu_id.machine);
-       }
-       preempt_enable();
-       return 0;
+		seq_printf(m, "processor %li: "
+			   "version = %02X,  "
+			   "identification = %06X,  "
+			   "machine = %04X\n",
+			   n, lc->cpu_id.version,
+			   lc->cpu_id.ident,
+			   lc->cpu_id.machine);
+	}
+	preempt_enable();
+	return 0;
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/reipl64.S linux-libre-2.6.30-gnu1/arch/s390/kernel/reipl64.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/reipl64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/reipl64.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,7 @@
 /*
- *  arch/s390/kernel/reipl.S
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
-		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *    Copyright IBM Corp 2000,2009
+ *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ *		 Denis Joseph Barrow,
  */
 
 #include <asm/lowcore.h>
@@ -30,7 +27,7 @@ do_reipl_asm:	basr	%r13,0
 		mvc	__LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
 		stfpc	__LC_FP_CREG_SAVE_AREA-0x1000(%r1)
 		stckc	.Lclkcmp-.Lpg0(%r13)
-		mvc	__LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
+		mvc	__LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
 		stpt	__LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
 		stg	%r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/s390_ksyms.c linux-libre-2.6.30-gnu1/arch/s390/kernel/s390_ksyms.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/s390_ksyms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/s390_ksyms.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,49 +1,5 @@
-/*
- *  arch/s390/kernel/s390_ksyms.c
- *
- *  S390 version
- */
-#include <linux/highuid.h>
 #include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/syscalls.h>
-#include <linux/interrupt.h>
-#include <asm/checksum.h>
-#include <asm/cpcmd.h>
-#include <asm/delay.h>
-#include <asm/pgalloc.h>
-#include <asm/setup.h>
 #include <asm/ftrace.h>
-#ifdef CONFIG_IP_MULTICAST
-#include <net/arp.h>
-#endif
-
-/*
- * memory management
- */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(_sb_findmap);
-
-/*
- * binfmt_elf loader 
- */
-extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(empty_zero_page);
-
-/*
- * misc.
- */
-EXPORT_SYMBOL(machine_flags);
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(csum_fold);
-EXPORT_SYMBOL(console_mode);
-EXPORT_SYMBOL(console_devno);
-EXPORT_SYMBOL(console_irq);
 
 #ifdef CONFIG_FUNCTION_TRACER
 EXPORT_SYMBOL(_mcount);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/setup.c linux-libre-2.6.30-gnu1/arch/s390/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,9 +74,14 @@ EXPORT_SYMBOL(uaccess);
  * Machine setup..
  */
 unsigned int console_mode = 0;
+EXPORT_SYMBOL(console_mode);
+
 unsigned int console_devno = -1;
+EXPORT_SYMBOL(console_devno);
+
 unsigned int console_irq = -1;
-unsigned long machine_flags;
+EXPORT_SYMBOL(console_irq);
+
 unsigned long elf_hwcap = 0;
 char elf_platform[ELF_PLATFORM_SIZE];
 
@@ -86,6 +91,10 @@ volatile int __cpu_logical_map[NR_CPUS];
 int __initdata memory_end_set;
 unsigned long __initdata memory_end;
 
+/* An array with a pointer to the lowcore of every CPU. */
+struct _lowcore *lowcore_ptr[NR_CPUS];
+EXPORT_SYMBOL(lowcore_ptr);
+
 /*
  * This is set up by the setup-routine at boot-time
  * for S390 need to find out, what we have to setup
@@ -109,13 +118,10 @@ static struct resource data_resource = {
  */
 void __cpuinit cpu_init(void)
 {
-        int addr = hard_smp_processor_id();
-
         /*
          * Store processor id in lowcore (used e.g. in timer_interrupt)
          */
-	get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
-        S390_lowcore.cpu_data.cpu_addr = addr;
+	get_cpu_id(&S390_lowcore.cpu_id);
 
         /*
          * Force FPU initialization:
@@ -125,8 +131,7 @@ void __cpuinit cpu_init(void)
 
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
-        if (current->mm)
-                BUG();
+	BUG_ON(current->mm);
         enter_lazy_tlb(&init_mm, current);
 }
 
@@ -217,7 +222,7 @@ static void __init conmode_default(void)
 	}
 }
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
 static void __init setup_zfcpdump(unsigned int console_devno)
 {
 	static char str[41];
@@ -289,11 +294,7 @@ static int __init early_parse_mem(char *
 early_param("mem", early_parse_mem);
 
 #ifdef CONFIG_S390_SWITCH_AMODE
-#ifdef CONFIG_PGSTE
-unsigned int switch_amode = 1;
-#else
 unsigned int switch_amode = 0;
-#endif
 EXPORT_SYMBOL_GPL(switch_amode);
 
 static int set_amode_and_uaccess(unsigned long user_amode,
@@ -414,7 +415,6 @@ setup_lowcore(void)
 		PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
 	lc->io_new_psw.mask = psw_kernel_bits;
 	lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
-	lc->ipl_device = S390_lowcore.ipl_device;
 	lc->clock_comparator = -1ULL;
 	lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
 	lc->async_stack = (unsigned long)
@@ -423,6 +423,7 @@ setup_lowcore(void)
 		__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
 	lc->current_task = (unsigned long) init_thread_union.thread_info.task;
 	lc->thread_info = (unsigned long) &init_thread_union;
+	lc->machine_flags = S390_lowcore.machine_flags;
 #ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE) {
 		lc->extended_save_area_addr = (__u32)
@@ -433,7 +434,16 @@ setup_lowcore(void)
 #else
 	lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
 #endif
+	lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
+	lc->async_enter_timer = S390_lowcore.async_enter_timer;
+	lc->exit_timer = S390_lowcore.exit_timer;
+	lc->user_timer = S390_lowcore.user_timer;
+	lc->system_timer = S390_lowcore.system_timer;
+	lc->steal_timer = S390_lowcore.steal_timer;
+	lc->last_update_timer = S390_lowcore.last_update_timer;
+	lc->last_update_clock = S390_lowcore.last_update_clock;
 	set_prefix((u32)(unsigned long) lc);
+	lowcore_ptr[0] = lc;
 }
 
 static void __init
@@ -510,7 +520,7 @@ static void __init setup_memory_end(void
 	unsigned long max_mem;
 	int i;
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
 	if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
 		memory_end = ZFCPDUMP_HSA_SIZE;
 		memory_end_set = 1;
@@ -677,7 +687,6 @@ setup_memory(void)
 static void __init setup_hwcaps(void)
 {
 	static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
-	struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
 	unsigned long long facility_list_extended;
 	unsigned int facility_list;
 	int i;
@@ -693,15 +702,22 @@ static void __init setup_hwcaps(void)
 	 *   Bit 17: the message-security assist is installed
 	 *   Bit 19: the long-displacement facility is installed
 	 *   Bit 21: the extended-immediate facility is installed
+	 *   Bit 22: extended-translation facility 3 is installed
+	 *   Bit 30: extended-translation facility 3 enhancement facility
 	 * These get translated to:
 	 *   HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1,
 	 *   HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3,
-	 *   HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5.
+	 *   HWCAP_S390_LDISP bit 4, HWCAP_S390_EIMM bit 5 and
+	 *   HWCAP_S390_ETF3EH bit 8 (22 && 30).
 	 */
 	for (i = 0; i < 6; i++)
 		if (facility_list & (1UL << (31 - stfl_bits[i])))
 			elf_hwcap |= 1UL << i;
 
+	if ((facility_list & (1UL << (31 - 22)))
+	    && (facility_list & (1UL << (31 - 30))))
+		elf_hwcap |= 1UL << 8;
+
 	/*
 	 * Check for additional facilities with store-facility-list-extended.
 	 * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0
@@ -710,20 +726,22 @@ static void __init setup_hwcaps(void)
 	 * How many facility words are stored depends on the number of
 	 * doublewords passed to the instruction. The additional facilites
 	 * are:
-	 *   Bit 43: decimal floating point facility is installed
+	 *   Bit 42: decimal floating point facility is installed
+	 *   Bit 44: perform floating point operation facility is installed
 	 * translated to:
-	 *   HWCAP_S390_DFP bit 6.
+	 *   HWCAP_S390_DFP bit 6 (42 && 44).
 	 */
 	if ((elf_hwcap & (1UL << 2)) &&
 	    __stfle(&facility_list_extended, 1) > 0) {
-		if (facility_list_extended & (1ULL << (64 - 43)))
+		if ((facility_list_extended & (1ULL << (63 - 42)))
+		    && (facility_list_extended & (1ULL << (63 - 44))))
 			elf_hwcap |= 1UL << 6;
 	}
 
 	if (MACHINE_HAS_HPAGE)
 		elf_hwcap |= 1UL << 7;
 
-	switch (cpuinfo->cpu_id.machine) {
+	switch (S390_lowcore.cpu_id.machine) {
 	case 0x9672:
 #if !defined(CONFIG_64BIT)
 	default:	/* Use "g5" as default for 31 bit kernels. */
@@ -816,7 +834,7 @@ setup_arch(char **cmdline_p)
 	setup_lowcore();
 
         cpu_init();
-        __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
+	__cpu_logical_map[0] = stap();
 	s390_init_cpu_topology();
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/smp.c linux-libre-2.6.30-gnu1/arch/s390/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/cache.h>
 #include <linux/interrupt.h>
+#include <linux/irqflags.h>
 #include <linux/cpu.h>
 #include <linux/timex.h>
 #include <linux/bootmem.h>
@@ -50,12 +51,6 @@
 #include <asm/vdso.h>
 #include "entry.h"
 
-/*
- * An array with a pointer the lowcore of every CPU.
- */
-struct _lowcore *lowcore_ptr[NR_CPUS];
-EXPORT_SYMBOL(lowcore_ptr);
-
 static struct task_struct *current_set[NR_CPUS];
 
 static u8 smp_cpu_type;
@@ -81,9 +76,7 @@ void smp_send_stop(void)
 
 	/* Disable all interrupts/machine checks */
 	__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-
-	/* write magic number to zero page (absolute 0) */
-	lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
+	trace_hardirqs_off();
 
 	/* stop all processors */
 	for_each_online_cpu(cpu) {
@@ -233,7 +226,7 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
  */
 #define CPU_INIT_NO	1
 
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
 
 /*
  * zfcpdump_prefix_array holds prefix registers for the following scenario:
@@ -274,7 +267,7 @@ EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
 
 static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
 
-#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
+#endif /* CONFIG_ZFCPDUMP */
 
 static int cpu_stopped(int cpu)
 {
@@ -304,8 +297,8 @@ static int smp_rescan_cpus_sigp(cpumask_
 {
 	int cpu_id, logical_cpu;
 
-	logical_cpu = first_cpu(avail);
-	if (logical_cpu == NR_CPUS)
+	logical_cpu = cpumask_first(&avail);
+	if (logical_cpu >= nr_cpu_ids)
 		return 0;
 	for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
 		if (cpu_known(cpu_id))
@@ -316,8 +309,8 @@ static int smp_rescan_cpus_sigp(cpumask_
 			continue;
 		cpu_set(logical_cpu, cpu_present_map);
 		smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-		logical_cpu = next_cpu(logical_cpu, avail);
-		if (logical_cpu == NR_CPUS)
+		logical_cpu = cpumask_next(logical_cpu, &avail);
+		if (logical_cpu >= nr_cpu_ids)
 			break;
 	}
 	return 0;
@@ -329,8 +322,8 @@ static int smp_rescan_cpus_sclp(cpumask_
 	int cpu_id, logical_cpu, cpu;
 	int rc;
 
-	logical_cpu = first_cpu(avail);
-	if (logical_cpu == NR_CPUS)
+	logical_cpu = cpumask_first(&avail);
+	if (logical_cpu >= nr_cpu_ids)
 		return 0;
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
@@ -351,8 +344,8 @@ static int smp_rescan_cpus_sclp(cpumask_
 			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
 		else
 			smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-		logical_cpu = next_cpu(logical_cpu, avail);
-		if (logical_cpu == NR_CPUS)
+		logical_cpu = cpumask_next(logical_cpu, &avail);
+		if (logical_cpu >= nr_cpu_ids)
 			break;
 	}
 out:
@@ -379,7 +372,7 @@ static void __init smp_detect_cpus(void)
 
 	c_cpus = 1;
 	s_cpus = 0;
-	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+	boot_cpu_addr = __cpu_logical_map[0];
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		panic("smp_detect_cpus failed to allocate memory\n");
@@ -453,7 +446,7 @@ int __cpuinit start_secondary(void *cpuv
 	/* Switch on interrupts */
 	local_irq_enable();
 	/* Print info about this processor */
-	print_cpu_info(&S390_lowcore.cpu_data);
+	print_cpu_info();
 	/* cpu_idle will call schedule for us */
 	cpu_idle();
 	return 0;
@@ -515,7 +508,6 @@ out:
 	return -ENOMEM;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 static void smp_free_lowcore(int cpu)
 {
 	struct _lowcore *lowcore;
@@ -534,7 +526,6 @@ static void smp_free_lowcore(int cpu)
 	free_pages((unsigned long) lowcore, lc_order);
 	lowcore_ptr[cpu] = NULL;
 }
-#endif /* CONFIG_HOTPLUG_CPU */
 
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu)
@@ -543,16 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	struct _lowcore *cpu_lowcore;
 	struct stack_frame *sf;
 	sigp_ccode ccode;
+	u32 lowcore;
 
 	if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
 		return -EIO;
 	if (smp_alloc_lowcore(cpu))
 		return -ENOMEM;
+	do {
+		ccode = signal_processor(cpu, sigp_initial_cpu_reset);
+		if (ccode == sigp_busy)
+			udelay(10);
+		if (ccode == sigp_not_operational)
+			goto err_out;
+	} while (ccode == sigp_busy);
 
-	ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
-				   cpu, sigp_set_prefix);
-	if (ccode)
-		return -EIO;
+	lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
+	while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
+		udelay(10);
 
 	idle = current_set[cpu];
 	cpu_lowcore = lowcore_ptr[cpu];
@@ -571,9 +569,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
 		: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
 	cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
 	cpu_lowcore->current_task = (unsigned long) idle;
-	cpu_lowcore->cpu_data.cpu_nr = cpu;
+	cpu_lowcore->cpu_nr = cpu;
 	cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
-	cpu_lowcore->ipl_device = S390_lowcore.ipl_device;
+	cpu_lowcore->machine_flags = S390_lowcore.machine_flags;
 	eieio();
 
 	while (signal_processor(cpu, sigp_restart) == sigp_busy)
@@ -582,6 +580,10 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	while (!cpu_online(cpu))
 		cpu_relax();
 	return 0;
+
+err_out:
+	smp_free_lowcore(cpu);
+	return -EIO;
 }
 
 static int __init setup_possible_cpus(char *s)
@@ -589,9 +591,9 @@ static int __init setup_possible_cpus(ch
 	int pcpus, cpu;
 
 	pcpus = simple_strtoul(s, NULL, 0);
-	cpu_possible_map = cpumask_of_cpu(0);
-	for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
-		cpu_set(cpu, cpu_possible_map);
+	init_cpu_possible(cpumask_of(0));
+	for (cpu = 1; cpu < pcpus && cpu < nr_cpu_ids; cpu++)
+		set_cpu_possible(cpu, true);
 	return 0;
 }
 early_param("possible_cpus", setup_possible_cpus);
@@ -663,7 +665,7 @@ void __init smp_prepare_cpus(unsigned in
 	/* request the 0x1201 emergency signal external interrupt */
 	if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
 		panic("Couldn't request external interrupt 0x1201");
-	print_cpu_info(&S390_lowcore.cpu_data);
+	print_cpu_info();
 
 	/* Reallocate current lowcore, but keep its contents. */
 	lc_order = sizeof(long) == 8 ? 1 : 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/syscalls.S linux-libre-2.6.30-gnu1/arch/s390/kernel/syscalls.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/syscalls.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/syscalls.S	2009-06-09 23:05:27.000000000 -0400
@@ -336,3 +336,5 @@ SYSCALL(sys_inotify_init1,sys_inotify_in
 SYSCALL(sys_pipe2,sys_pipe2,sys_pipe2_wrapper) /* 325 */
 SYSCALL(sys_dup3,sys_dup3,sys_dup3_wrapper)
 SYSCALL(sys_epoll_create1,sys_epoll_create1,sys_epoll_create1_wrapper)
+SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
+SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/sysinfo.c linux-libre-2.6.30-gnu1/arch/s390/kernel/sysinfo.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/sysinfo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/sysinfo.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,428 @@
+/*
+ *  Copyright IBM Corp. 2001, 2009
+ *  Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
+ *	       Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <asm/ebcdic.h>
+#include <asm/sysinfo.h>
+#include <asm/cpcmd.h>
+
+/* Sigh, math-emu. Don't ask. */
+#include <asm/sfp-util.h>
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+
+static inline int stsi_0(void)
+{
+	int rc = stsi(NULL, 0, 0, 0);
+	return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
+}
+
+static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
+{
+	if (stsi(info, 1, 1, 1) == -ENOSYS)
+		return len;
+
+	EBCASC(info->manufacturer, sizeof(info->manufacturer));
+	EBCASC(info->type, sizeof(info->type));
+	EBCASC(info->model, sizeof(info->model));
+	EBCASC(info->sequence, sizeof(info->sequence));
+	EBCASC(info->plant, sizeof(info->plant));
+	EBCASC(info->model_capacity, sizeof(info->model_capacity));
+	EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
+	EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
+	len += sprintf(page + len, "Manufacturer:         %-16.16s\n",
+		       info->manufacturer);
+	len += sprintf(page + len, "Type:                 %-4.4s\n",
+		       info->type);
+	if (info->model[0] != '\0')
+		/*
+		 * Sigh: the model field has been renamed with System z9
+		 * to model_capacity and a new model field has been added
+		 * after the plant field. To avoid confusing older programs
+		 * the "Model:" prints "model_capacity model" or just
+		 * "model_capacity" if the model string is empty .
+		 */
+		len += sprintf(page + len,
+			       "Model:                %-16.16s %-16.16s\n",
+			       info->model_capacity, info->model);
+	else
+		len += sprintf(page + len, "Model:                %-16.16s\n",
+			       info->model_capacity);
+	len += sprintf(page + len, "Sequence Code:        %-16.16s\n",
+		       info->sequence);
+	len += sprintf(page + len, "Plant:                %-4.4s\n",
+		       info->plant);
+	len += sprintf(page + len, "Model Capacity:       %-16.16s %08u\n",
+		       info->model_capacity, *(u32 *) info->model_cap_rating);
+	if (info->model_perm_cap[0] != '\0')
+		len += sprintf(page + len,
+			       "Model Perm. Capacity: %-16.16s %08u\n",
+			       info->model_perm_cap,
+			       *(u32 *) info->model_perm_cap_rating);
+	if (info->model_temp_cap[0] != '\0')
+		len += sprintf(page + len,
+			       "Model Temp. Capacity: %-16.16s %08u\n",
+			       info->model_temp_cap,
+			       *(u32 *) info->model_temp_cap_rating);
+	return len;
+}
+
+static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
+{
+	struct sysinfo_1_2_2_extension *ext;
+	int i;
+
+	if (stsi(info, 1, 2, 2) == -ENOSYS)
+		return len;
+	ext = (struct sysinfo_1_2_2_extension *)
+		((unsigned long) info + info->acc_offset);
+
+	len += sprintf(page + len, "\n");
+	len += sprintf(page + len, "CPUs Total:           %d\n",
+		       info->cpus_total);
+	len += sprintf(page + len, "CPUs Configured:      %d\n",
+		       info->cpus_configured);
+	len += sprintf(page + len, "CPUs Standby:         %d\n",
+		       info->cpus_standby);
+	len += sprintf(page + len, "CPUs Reserved:        %d\n",
+		       info->cpus_reserved);
+
+	if (info->format == 1) {
+		/*
+		 * Sigh 2. According to the specification the alternate
+		 * capability field is a 32 bit floating point number
+		 * if the higher order 8 bits are not zero. Printing
+		 * a floating point number in the kernel is a no-no,
+		 * always print the number as 32 bit unsigned integer.
+		 * The user-space needs to know about the strange
+		 * encoding of the alternate cpu capability.
+		 */
+		len += sprintf(page + len, "Capability:           %u %u\n",
+			       info->capability, ext->alt_capability);
+		for (i = 2; i <= info->cpus_total; i++)
+			len += sprintf(page + len,
+				       "Adjustment %02d-way:    %u %u\n",
+				       i, info->adjustment[i-2],
+				       ext->alt_adjustment[i-2]);
+
+	} else {
+		len += sprintf(page + len, "Capability:           %u\n",
+			       info->capability);
+		for (i = 2; i <= info->cpus_total; i++)
+			len += sprintf(page + len,
+				       "Adjustment %02d-way:    %u\n",
+				       i, info->adjustment[i-2]);
+	}
+
+	if (info->secondary_capability != 0)
+		len += sprintf(page + len, "Secondary Capability: %d\n",
+			       info->secondary_capability);
+	return len;
+}
+
+static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
+{
+	if (stsi(info, 2, 2, 2) == -ENOSYS)
+		return len;
+
+	EBCASC(info->name, sizeof(info->name));
+
+	len += sprintf(page + len, "\n");
+	len += sprintf(page + len, "LPAR Number:          %d\n",
+		       info->lpar_number);
+
+	len += sprintf(page + len, "LPAR Characteristics: ");
+	if (info->characteristics & LPAR_CHAR_DEDICATED)
+		len += sprintf(page + len, "Dedicated ");
+	if (info->characteristics & LPAR_CHAR_SHARED)
+		len += sprintf(page + len, "Shared ");
+	if (info->characteristics & LPAR_CHAR_LIMITED)
+		len += sprintf(page + len, "Limited ");
+	len += sprintf(page + len, "\n");
+
+	len += sprintf(page + len, "LPAR Name:            %-8.8s\n",
+		       info->name);
+
+	len += sprintf(page + len, "LPAR Adjustment:      %d\n",
+		       info->caf);
+
+	len += sprintf(page + len, "LPAR CPUs Total:      %d\n",
+		       info->cpus_total);
+	len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
+		       info->cpus_configured);
+	len += sprintf(page + len, "LPAR CPUs Standby:    %d\n",
+		       info->cpus_standby);
+	len += sprintf(page + len, "LPAR CPUs Reserved:   %d\n",
+		       info->cpus_reserved);
+	len += sprintf(page + len, "LPAR CPUs Dedicated:  %d\n",
+		       info->cpus_dedicated);
+	len += sprintf(page + len, "LPAR CPUs Shared:     %d\n",
+		       info->cpus_shared);
+	return len;
+}
+
+static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
+{
+	int i;
+
+	if (stsi(info, 3, 2, 2) == -ENOSYS)
+		return len;
+	for (i = 0; i < info->count; i++) {
+		EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
+		EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
+		len += sprintf(page + len, "\n");
+		len += sprintf(page + len, "VM%02d Name:            %-8.8s\n",
+			       i, info->vm[i].name);
+		len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
+			       i, info->vm[i].cpi);
+
+		len += sprintf(page + len, "VM%02d Adjustment:      %d\n",
+			       i, info->vm[i].caf);
+
+		len += sprintf(page + len, "VM%02d CPUs Total:      %d\n",
+			       i, info->vm[i].cpus_total);
+		len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
+			       i, info->vm[i].cpus_configured);
+		len += sprintf(page + len, "VM%02d CPUs Standby:    %d\n",
+			       i, info->vm[i].cpus_standby);
+		len += sprintf(page + len, "VM%02d CPUs Reserved:   %d\n",
+			       i, info->vm[i].cpus_reserved);
+	}
+	return len;
+}
+
+static int proc_read_sysinfo(char *page, char **start,
+			     off_t off, int count,
+			     int *eof, void *data)
+{
+	unsigned long info = get_zeroed_page(GFP_KERNEL);
+	int level, len;
+
+	if (!info)
+		return 0;
+
+	len = 0;
+	level = stsi_0();
+	if (level >= 1)
+		len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
+
+	if (level >= 1)
+		len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
+
+	if (level >= 2)
+		len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
+
+	if (level >= 3)
+		len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
+
+	free_page(info);
+	return len;
+}
+
+static __init int create_proc_sysinfo(void)
+{
+	create_proc_read_entry("sysinfo", 0444, NULL,
+			       proc_read_sysinfo, NULL);
+	return 0;
+}
+device_initcall(create_proc_sysinfo);
+
+/*
+ * Service levels interface.
+ */
+
+static DECLARE_RWSEM(service_level_sem);
+static LIST_HEAD(service_level_list);
+
+int register_service_level(struct service_level *slr)
+{
+	struct service_level *ptr;
+
+	down_write(&service_level_sem);
+	list_for_each_entry(ptr, &service_level_list, list)
+		if (ptr == slr) {
+			up_write(&service_level_sem);
+			return -EEXIST;
+		}
+	list_add_tail(&slr->list, &service_level_list);
+	up_write(&service_level_sem);
+	return 0;
+}
+EXPORT_SYMBOL(register_service_level);
+
+int unregister_service_level(struct service_level *slr)
+{
+	struct service_level *ptr, *next;
+	int rc = -ENOENT;
+
+	down_write(&service_level_sem);
+	list_for_each_entry_safe(ptr, next, &service_level_list, list) {
+		if (ptr != slr)
+			continue;
+		list_del(&ptr->list);
+		rc = 0;
+		break;
+	}
+	up_write(&service_level_sem);
+	return rc;
+}
+EXPORT_SYMBOL(unregister_service_level);
+
+static void *service_level_start(struct seq_file *m, loff_t *pos)
+{
+	down_read(&service_level_sem);
+	return seq_list_start(&service_level_list, *pos);
+}
+
+static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	return seq_list_next(p, &service_level_list, pos);
+}
+
+static void service_level_stop(struct seq_file *m, void *p)
+{
+	up_read(&service_level_sem);
+}
+
+static int service_level_show(struct seq_file *m, void *p)
+{
+	struct service_level *slr;
+
+	slr = list_entry(p, struct service_level, list);
+	slr->seq_print(m, slr);
+	return 0;
+}
+
+static const struct seq_operations service_level_seq_ops = {
+	.start		= service_level_start,
+	.next		= service_level_next,
+	.stop		= service_level_stop,
+	.show		= service_level_show
+};
+
+static int service_level_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &service_level_seq_ops);
+}
+
+static const struct file_operations service_level_ops = {
+	.open		= service_level_open,
+	.read		= seq_read,
+	.llseek 	= seq_lseek,
+	.release	= seq_release
+};
+
+static void service_level_vm_print(struct seq_file *m,
+				   struct service_level *slr)
+{
+	char *query_buffer, *str;
+
+	query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
+	if (!query_buffer)
+		return;
+	cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
+	str = strchr(query_buffer, '\n');
+	if (str)
+		*str = 0;
+	seq_printf(m, "VM: %s\n", query_buffer);
+	kfree(query_buffer);
+}
+
+static struct service_level service_level_vm = {
+	.seq_print = service_level_vm_print
+};
+
+static __init int create_proc_service_level(void)
+{
+	proc_create("service_levels", 0, NULL, &service_level_ops);
+	if (MACHINE_IS_VM)
+		register_service_level(&service_level_vm);
+	return 0;
+}
+subsys_initcall(create_proc_service_level);
+
+/*
+ * Bogomips calculation based on cpu capability.
+ */
+int get_cpu_capability(unsigned int *capability)
+{
+	struct sysinfo_1_2_2 *info;
+	int rc;
+
+	info = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	rc = stsi(info, 1, 2, 2);
+	if (rc == -ENOSYS)
+		goto out;
+	rc = 0;
+	*capability = info->capability;
+out:
+	free_page((unsigned long) info);
+	return rc;
+}
+
+/*
+ * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
+ */
+void s390_adjust_jiffies(void)
+{
+	struct sysinfo_1_2_2 *info;
+	const unsigned int fmil = 0x4b189680;	/* 1e7 as 32-bit float. */
+	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+	FP_DECL_EX;
+	unsigned int capability;
+
+	info = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!info)
+		return;
+
+	if (stsi(info, 1, 2, 2) != -ENOSYS) {
+		/*
+		 * Major sigh. The cpu capability encoding is "special".
+		 * If the first 9 bits of info->capability are 0 then it
+		 * is a 32 bit unsigned integer in the range 0 .. 2^23.
+		 * If the first 9 bits are != 0 then it is a 32 bit float.
+		 * In addition a lower value indicates a proportionally
+		 * higher cpu capacity. Bogomips are the other way round.
+		 * To get to a halfway suitable number we divide 1e7
+		 * by the cpu capability number. Yes, that means a floating
+		 * point division .. math-emu here we come :-)
+		 */
+		FP_UNPACK_SP(SA, &fmil);
+		if ((info->capability >> 23) == 0)
+			FP_FROM_INT_S(SB, info->capability, 32, int);
+		else
+			FP_UNPACK_SP(SB, &info->capability);
+		FP_DIV_S(SR, SA, SB);
+		FP_TO_INT_S(capability, SR, 32, 0);
+	} else
+		/*
+		 * Really old machine without stsi block for basic
+		 * cpu information. Report 42.0 bogomips.
+		 */
+		capability = 42;
+	loops_per_jiffy = capability * (500000/HZ);
+	free_page((unsigned long) info);
+}
+
+/*
+ * calibrate the delay loop
+ */
+void __cpuinit calibrate_delay(void)
+{
+	s390_adjust_jiffies();
+	/* Print the good old Bogomips line .. */
+	printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
+	       "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
+	       (loops_per_jiffy/(5000/HZ)) % 100);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/time.c linux-libre-2.6.30-gnu1/arch/s390/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,9 +52,6 @@
 #define USECS_PER_JIFFY     ((unsigned long) 1000000/HZ)
 #define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
 
-/* The value of the TOD clock for 1.1.1970. */
-#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
-
 /*
  * Create a small time difference between the timer interrupts
  * on the different cpus to avoid lock contention.
@@ -63,9 +60,10 @@
 
 #define TICK_SIZE tick
 
+u64 sched_clock_base_cc = -1;	/* Force to data section. */
+
 static ext_int_info_t ext_int_info_cc;
 static ext_int_info_t ext_int_etr_cc;
-static u64 sched_clock_base_cc;
 
 static DEFINE_PER_CPU(struct clock_event_device, comparators);
 
@@ -195,25 +193,15 @@ static void timing_alert_interrupt(__u16
 static void etr_reset(void);
 static void stp_reset(void);
 
-/*
- * Get the TOD clock running.
- */
-static u64 __init reset_tod_clock(void)
+unsigned long read_persistent_clock(void)
 {
-	u64 time;
-
-	etr_reset();
-	stp_reset();
-	if (store_clock(&time) == 0)
-		return time;
-	/* TOD clock not running. Set the clock to Unix Epoch. */
-	if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0)
-		panic("TOD clock not operational.");
+	struct timespec ts;
 
-	return TOD_UNIX_EPOCH;
+	tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts);
+	return ts.tv_sec;
 }
 
-static cycle_t read_tod_clock(void)
+static cycle_t read_tod_clock(struct clocksource *cs)
 {
 	return get_clock();
 }
@@ -265,12 +253,13 @@ void update_vsyscall_tz(void)
  */
 void __init time_init(void)
 {
-	sched_clock_base_cc = reset_tod_clock();
+	struct timespec ts;
+	unsigned long flags;
+	cycle_t now;
 
-	/* set xtime */
-	tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);
-        set_normalized_timespec(&wall_to_monotonic,
-                                -xtime.tv_sec, -xtime.tv_nsec);
+	/* Reset time synchronization interfaces. */
+	etr_reset();
+	stp_reset();
 
 	/* request the clock comparator external interrupt */
 	if (register_early_external_interrupt(0x1004,
@@ -278,17 +267,38 @@ void __init time_init(void)
 					      &ext_int_info_cc) != 0)
                 panic("Couldn't request external interrupt 0x1004");
 
-	if (clocksource_register(&clocksource_tod) != 0)
-		panic("Could not register TOD clock source");
-
 	/* request the timing alert external interrupt */
 	if (register_early_external_interrupt(0x1406,
 					      timing_alert_interrupt,
 					      &ext_int_etr_cc) != 0)
 		panic("Couldn't request external interrupt 0x1406");
 
+	if (clocksource_register(&clocksource_tod) != 0)
+		panic("Could not register TOD clock source");
+
+	/*
+	 * The TOD clock is an accurate clock. The xtime should be
+	 * initialized in a way that the difference between TOD and
+	 * xtime is reasonably small. Too bad that timekeeping_init
+	 * sets xtime.tv_nsec to zero. In addition the clock source
+	 * change from the jiffies clock source to the TOD clock
+	 * source add another error of up to 1/HZ second. The same
+	 * function sets wall_to_monotonic to a value that is too
+	 * small for /proc/uptime to be accurate.
+	 * Reset xtime and wall_to_monotonic to sane values.
+	 */
+	write_seqlock_irqsave(&xtime_lock, flags);
+	now = get_clock();
+	tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
+	clocksource_tod.cycle_last = now;
+	clocksource_tod.raw_time = xtime;
+	tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
+	set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
 	/* Enable TOD clock interrupts on the boot cpu. */
 	init_cpu_timer();
+
 	/* Enable cpu timer interrupts on the boot cpu. */
 	vtime_init();
 }
@@ -331,6 +341,7 @@ static unsigned long long adjust_time(un
 }
 
 static DEFINE_PER_CPU(atomic_t, clock_sync_word);
+static DEFINE_MUTEX(clock_sync_mutex);
 static unsigned long clock_sync_flags;
 
 #define CLOCK_SYNC_HAS_ETR	0
@@ -394,6 +405,20 @@ static void enable_sync_clock(void)
 	atomic_set_mask(0x80000000, sw_ptr);
 }
 
+/*
+ * Function to check if the clock is in sync.
+ */
+static inline int check_sync_clock(void)
+{
+	atomic_t *sw_ptr;
+	int rc;
+
+	sw_ptr = &get_cpu_var(clock_sync_word);
+	rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
+	put_cpu_var(clock_sync_sync);
+	return rc;
+}
+
 /* Single threaded workqueue used for etr and stp sync events */
 static struct workqueue_struct *time_sync_wq;
 
@@ -485,6 +510,8 @@ static void etr_reset(void)
 	if (etr_setr(&etr_eacr) == 0) {
 		etr_tolec = get_clock();
 		set_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags);
+		if (etr_port0_online && etr_port1_online)
+			set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 	} else if (etr_port0_online || etr_port1_online) {
 		pr_warning("The real or virtual hardware system does "
 			   "not provide an ETR interface\n");
@@ -533,8 +560,7 @@ void etr_switch_to_local(void)
 {
 	if (!etr_eacr.sl)
 		return;
-	if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-		disable_sync_clock(NULL);
+	disable_sync_clock(NULL);
 	set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
 	queue_work(time_sync_wq, &etr_work);
 }
@@ -549,8 +575,7 @@ void etr_sync_check(void)
 {
 	if (!etr_eacr.es)
 		return;
-	if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-		disable_sync_clock(NULL);
+	disable_sync_clock(NULL);
 	set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
 	queue_work(time_sync_wq, &etr_work);
 }
@@ -914,7 +939,7 @@ static struct etr_eacr etr_handle_update
 	 * Do not try to get the alternate port aib if the clock
 	 * is not in sync yet.
 	 */
-	if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags) && !eacr.es)
+	if (!check_sync_clock())
 		return eacr;
 
 	/*
@@ -997,7 +1022,6 @@ static void etr_work_fn(struct work_stru
 		on_each_cpu(disable_sync_clock, NULL, 1);
 		del_timer_sync(&etr_timer);
 		etr_update_eacr(eacr);
-		clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 		goto out_unlock;
 	}
 
@@ -1071,18 +1095,13 @@ static void etr_work_fn(struct work_stru
 		/* Both ports not usable. */
 		eacr.es = eacr.sl = 0;
 		sync_port = -1;
-		clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 	}
 
-	if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-		eacr.es = 0;
-
 	/*
 	 * If the clock is in sync just update the eacr and return.
 	 * If there is no valid sync port wait for a port update.
 	 */
-	if (test_bit(CLOCK_SYNC_STP, &clock_sync_flags) ||
-	    eacr.es || sync_port < 0) {
+	if (check_sync_clock() || sync_port < 0) {
 		etr_update_eacr(eacr);
 		etr_set_tolec_timeout(now);
 		goto out_unlock;
@@ -1103,13 +1122,11 @@ static void etr_work_fn(struct work_stru
 	 * and set up a timer to try again after 0.5 seconds
 	 */
 	etr_update_eacr(eacr);
-	set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 	if (now < etr_tolec + (1600000 << 12) ||
 	    etr_sync_clock_stop(&aib, sync_port) != 0) {
 		/* Sync failed. Try again in 1/2 second. */
 		eacr.es = 0;
 		etr_update_eacr(eacr);
-		clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 		etr_set_sync_timeout();
 	} else
 		etr_set_tolec_timeout(now);
@@ -1191,19 +1208,30 @@ static ssize_t etr_online_store(struct s
 		return -EINVAL;
 	if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags))
 		return -EOPNOTSUPP;
+	mutex_lock(&clock_sync_mutex);
 	if (dev == &etr_port0_dev) {
 		if (etr_port0_online == value)
-			return count;	/* Nothing to do. */
+			goto out;	/* Nothing to do. */
 		etr_port0_online = value;
+		if (etr_port0_online && etr_port1_online)
+			set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+		else
+			clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 		set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
 		queue_work(time_sync_wq, &etr_work);
 	} else {
 		if (etr_port1_online == value)
-			return count;	/* Nothing to do. */
+			goto out;	/* Nothing to do. */
 		etr_port1_online = value;
+		if (etr_port0_online && etr_port1_online)
+			set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+		else
+			clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
 		set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
 		queue_work(time_sync_wq, &etr_work);
 	}
+out:
+	mutex_unlock(&clock_sync_mutex);
 	return count;
 }
 
@@ -1405,6 +1433,7 @@ static void *stp_page;
 static void stp_work_fn(struct work_struct *work);
 static DEFINE_MUTEX(stp_work_mutex);
 static DECLARE_WORK(stp_work, stp_work_fn);
+static struct timer_list stp_timer;
 
 static int __init early_parse_stp(char *p)
 {
@@ -1436,10 +1465,16 @@ static void __init stp_reset(void)
 	}
 }
 
+static void stp_timeout(unsigned long dummy)
+{
+	queue_work(time_sync_wq, &stp_work);
+}
+
 static int __init stp_init(void)
 {
 	if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
 		return 0;
+	setup_timer(&stp_timer, stp_timeout, 0UL);
 	time_init_wq();
 	if (!stp_online)
 		return 0;
@@ -1471,8 +1506,6 @@ static void stp_timing_alert(struct stp_
  */
 void stp_sync_check(void)
 {
-	if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
-		return;
 	disable_sync_clock(NULL);
 	queue_work(time_sync_wq, &stp_work);
 }
@@ -1485,8 +1518,6 @@ void stp_sync_check(void)
  */
 void stp_island_check(void)
 {
-	if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
-		return;
 	disable_sync_clock(NULL);
 	queue_work(time_sync_wq, &stp_work);
 }
@@ -1513,10 +1544,6 @@ static int stp_sync_clock(void *data)
 
 	enable_sync_clock();
 
-	set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
-	if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
-		queue_work(time_sync_wq, &etr_work);
-
 	rc = 0;
 	if (stp_info.todoff[0] || stp_info.todoff[1] ||
 	    stp_info.todoff[2] || stp_info.todoff[3] ||
@@ -1535,9 +1562,6 @@ static int stp_sync_clock(void *data)
 	if (rc) {
 		disable_sync_clock(NULL);
 		stp_sync->in_sync = -EAGAIN;
-		clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
-		if (etr_port0_online || etr_port1_online)
-			queue_work(time_sync_wq, &etr_work);
 	} else
 		stp_sync->in_sync = 1;
 	xchg(&first, 0);
@@ -1558,6 +1582,7 @@ static void stp_work_fn(struct work_stru
 
 	if (!stp_online) {
 		chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000);
+		del_timer_sync(&stp_timer);
 		goto out_unlock;
 	}
 
@@ -1569,12 +1594,23 @@ static void stp_work_fn(struct work_stru
 	if (rc || stp_info.c == 0)
 		goto out_unlock;
 
+	/* Skip synchronization if the clock is already in sync. */
+	if (check_sync_clock())
+		goto out_unlock;
+
 	memset(&stp_sync, 0, sizeof(stp_sync));
 	get_online_cpus();
 	atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
 	stop_machine(stp_sync_clock, &stp_sync, &cpu_online_map);
 	put_online_cpus();
 
+	if (!check_sync_clock())
+		/*
+		 * There is a usable clock but the synchonization failed.
+		 * Retry after a second.
+		 */
+		mod_timer(&stp_timer, jiffies + HZ);
+
 out_unlock:
 	mutex_unlock(&stp_work_mutex);
 }
@@ -1684,8 +1720,14 @@ static ssize_t stp_online_store(struct s
 		return -EINVAL;
 	if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
 		return -EOPNOTSUPP;
+	mutex_lock(&clock_sync_mutex);
 	stp_online = value;
+	if (stp_online)
+		set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
+	else
+		clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
 	queue_work(time_sync_wq, &stp_work);
+	mutex_unlock(&clock_sync_mutex);
 	return count;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/topology.c linux-libre-2.6.30-gnu1/arch/s390/kernel/topology.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/topology.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/topology.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,7 +74,7 @@ static DEFINE_SPINLOCK(topology_lock);
 
 cpumask_t cpu_core_map[NR_CPUS];
 
-cpumask_t cpu_coregroup_map(unsigned int cpu)
+static cpumask_t cpu_coregroup_map(unsigned int cpu)
 {
 	struct core_info *core = &core_info;
 	unsigned long flags;
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/traps.c linux-libre-2.6.30-gnu1/arch/s390/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,9 +61,11 @@ extern pgm_check_handler_t do_asce_excep
 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
 
 #ifndef CONFIG_64BIT
+#define LONG "%08lx "
 #define FOURLONG "%08lx %08lx %08lx %08lx\n"
 static int kstack_depth_to_print = 12;
 #else /* CONFIG_64BIT */
+#define LONG "%016lx "
 #define FOURLONG "%016lx %016lx %016lx %016lx\n"
 static int kstack_depth_to_print = 20;
 #endif /* CONFIG_64BIT */
@@ -155,7 +157,7 @@ void show_stack(struct task_struct *task
 			break;
 		if (i && ((i * sizeof (long) % 32) == 0))
 			printk("\n       ");
-		printk("%p ", (void *)*stack++);
+		printk(LONG, *stack++);
 	}
 	printk("\n");
 	show_trace(task, sp);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/vdso.c linux-libre-2.6.30-gnu1/arch/s390/kernel/vdso.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/vdso.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/vdso.c	2009-06-09 23:05:27.000000000 -0400
@@ -144,7 +144,6 @@ out:
 	return -ENOMEM;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
 {
 	unsigned long segment_table, page_table, page_frame;
@@ -163,7 +162,6 @@ void vdso_free_per_cpu(int cpu, struct _
 	free_page(page_table);
 	free_pages(segment_table, SEGMENT_ORDER);
 }
-#endif /* CONFIG_HOTPLUG_CPU */
 
 static void __vdso_init_cr5(void *dummy)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/s390/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -29,8 +29,8 @@ SECTIONS
 	. = 0x00000000;
 	.text : {
 	_text = .;		/* Text and read-only data */
-		*(.text.head)
-	TEXT_TEXT
+		HEAD_TEXT
+		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
@@ -108,6 +108,8 @@ SECTIONS
 		EXIT_TEXT
 	}
 
+	/* early.c uses stsi, which requires page aligned data. */
+	. = ALIGN(PAGE_SIZE);
 	.init.data : {
 		INIT_DATA
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kernel/vtime.c linux-libre-2.6.30-gnu1/arch/s390/kernel/vtime.c
--- linux-libre-2.6.29-gnu1/arch/s390/kernel/vtime.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kernel/vtime.c	2009-06-09 23:05:27.000000000 -0400
@@ -134,6 +134,8 @@ void vtime_start_cpu(void)
 	/* Account time spent with enabled wait psw loaded as idle time. */
 	idle_time = S390_lowcore.int_clock - idle->idle_enter;
 	account_idle_time(idle_time);
+	S390_lowcore.steal_timer +=
+		idle->idle_enter - S390_lowcore.last_update_clock;
 	S390_lowcore.last_update_clock = S390_lowcore.int_clock;
 
 	/* Account system time spent going idle. */
@@ -238,6 +240,22 @@ void vtime_stop_cpu(void)
 	}
 }
 
+cputime64_t s390_get_idle_time(int cpu)
+{
+	struct s390_idle_data *idle;
+	unsigned long long now, idle_time, idle_enter;
+
+	idle = &per_cpu(s390_idle, cpu);
+	spin_lock(&idle->lock);
+	now = get_clock();
+	idle_time = 0;
+	idle_enter = idle->idle_enter;
+	if (idle_enter != 0ULL && idle_enter < now)
+		idle_time = now - idle_enter;
+	spin_unlock(&idle->lock);
+	return idle_time;
+}
+
 /*
  * Sorted add to a list. List is linear searched until first bigger
  * element is found.
@@ -425,17 +443,7 @@ void add_virt_timer_periodic(void *new)
 }
 EXPORT_SYMBOL(add_virt_timer_periodic);
 
-/*
- * If we change a pending timer the function must be called on the CPU
- * where the timer is running on, e.g. by smp_call_function_single()
- *
- * The original mod_timer adds the timer if it is not pending. For
- * compatibility we do the same. The timer will be added on the current
- * CPU as a oneshot timer.
- *
- * returns whether it has modified a pending timer (1) or not (0)
- */
-int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
+int __mod_vtimer(struct vtimer_list *timer, __u64 expires, int periodic)
 {
 	struct vtimer_queue *vq;
 	unsigned long flags;
@@ -444,39 +452,35 @@ int mod_virt_timer(struct vtimer_list *t
 	BUG_ON(!timer->function);
 	BUG_ON(!expires || expires > VTIMER_MAX_SLICE);
 
-	/*
-	 * This is a common optimization triggered by the
-	 * networking code - if the timer is re-modified
-	 * to be the same thing then just return:
-	 */
 	if (timer->expires == expires && vtimer_pending(timer))
 		return 1;
 
 	cpu = get_cpu();
 	vq = &per_cpu(virt_cpu_timer, cpu);
 
-	/* check if we run on the right CPU */
-	BUG_ON(timer->cpu != cpu);
-
 	/* disable interrupts before test if timer is pending */
 	spin_lock_irqsave(&vq->lock, flags);
 
 	/* if timer isn't pending add it on the current CPU */
 	if (!vtimer_pending(timer)) {
 		spin_unlock_irqrestore(&vq->lock, flags);
-		/* we do not activate an interval timer with mod_virt_timer */
-		timer->interval = 0;
+
+		if (periodic)
+			timer->interval = expires;
+		else
+			timer->interval = 0;
 		timer->expires = expires;
 		timer->cpu = cpu;
 		internal_add_vtimer(timer);
 		return 0;
 	}
 
+	/* check if we run on the right CPU */
+	BUG_ON(timer->cpu != cpu);
+
 	list_del_init(&timer->entry);
 	timer->expires = expires;
-
-	/* also change the interval if we have an interval timer */
-	if (timer->interval)
+	if (periodic)
 		timer->interval = expires;
 
 	/* the timer can't expire anymore so we can release the lock */
@@ -484,9 +488,32 @@ int mod_virt_timer(struct vtimer_list *t
 	internal_add_vtimer(timer);
 	return 1;
 }
+
+/*
+ * If we change a pending timer the function must be called on the CPU
+ * where the timer is running on.
+ *
+ * returns whether it has modified a pending timer (1) or not (0)
+ */
+int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
+{
+	return __mod_vtimer(timer, expires, 0);
+}
 EXPORT_SYMBOL(mod_virt_timer);
 
 /*
+ * If we change a pending timer the function must be called on the CPU
+ * where the timer is running on.
+ *
+ * returns whether it has modified a pending timer (1) or not (0)
+ */
+int mod_virt_timer_periodic(struct vtimer_list *timer, __u64 expires)
+{
+	return __mod_vtimer(timer, expires, 1);
+}
+EXPORT_SYMBOL(mod_virt_timer_periodic);
+
+/*
  * delete a virtual timer
  *
  * returns whether the deleted timer was pending (1) or not (0)
@@ -516,16 +543,8 @@ EXPORT_SYMBOL(del_virt_timer);
  */
 void init_cpu_vtimer(void)
 {
-	struct thread_info *ti = current_thread_info();
 	struct vtimer_queue *vq;
 
-	S390_lowcore.user_timer = ti->user_timer;
-	S390_lowcore.system_timer = ti->system_timer;
-
-	/* kick the virtual timer */
-	asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
-	asm volatile ("STPT %0" : "=m" (S390_lowcore.last_update_timer));
-
 	/* initialize per cpu vtimer structure */
 	vq = &__get_cpu_var(virt_cpu_timer);
 	INIT_LIST_HEAD(&vq->list);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/intercept.c linux-libre-2.6.30-gnu1/arch/s390/kvm/intercept.c
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/intercept.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/intercept.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ static int handle_lctl(struct kvm_vcpu *
 static intercept_handler_t instruction_handlers[256] = {
 	[0x83] = kvm_s390_handle_diag,
 	[0xae] = kvm_s390_handle_sigp,
-	[0xb2] = kvm_s390_handle_priv,
+	[0xb2] = kvm_s390_handle_b2,
 	[0xb7] = handle_lctl,
 	[0xeb] = handle_lctlg,
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/interrupt.c linux-libre-2.6.30-gnu1/arch/s390/kvm/interrupt.c
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/interrupt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/interrupt.c	2009-06-09 23:05:27.000000000 -0400
@@ -555,9 +555,14 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu
 		VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)",
 			   s390int->parm);
 		break;
+	case KVM_S390_SIGP_SET_PREFIX:
+		inti->prefix.address = s390int->parm;
+		inti->type = s390int->type;
+		VCPU_EVENT(vcpu, 3, "inject: set prefix to %x (from user)",
+			   s390int->parm);
+		break;
 	case KVM_S390_SIGP_STOP:
 	case KVM_S390_RESTART:
-	case KVM_S390_SIGP_SET_PREFIX:
 	case KVM_S390_INT_EMERGENCY:
 		VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type);
 		inti->type = s390int->type;
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/Kconfig linux-libre-2.6.30-gnu1/arch/s390/kvm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,9 @@
 config HAVE_KVM
        bool
 
+config HAVE_KVM_IRQCHIP
+       bool
+
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
 	default y
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/kvm-s390.c linux-libre-2.6.30-gnu1/arch/s390/kvm/kvm-s390.c
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/kvm-s390.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/kvm-s390.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@
 #include <linux/timer.h>
 #include <asm/lowcore.h>
 #include <asm/pgtable.h>
-
+#include <asm/nmi.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 
@@ -286,7 +286,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
 	setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup,
 		 (unsigned long) vcpu);
 	get_cpu_id(&vcpu->arch.cpu_id);
-	vcpu->arch.cpu_id.version = 0xfe;
+	vcpu->arch.cpu_id.version = 0xff;
 	return 0;
 }
 
@@ -422,8 +422,8 @@ int kvm_arch_vcpu_ioctl_translate(struct
 	return -EINVAL; /* not implemented yet */
 }
 
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
-				    struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					struct kvm_guest_debug *dbg)
 {
 	return -EINVAL; /* not implemented yet */
 }
@@ -440,8 +440,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(stru
 	return -EINVAL; /* not implemented yet */
 }
 
-extern void s390_handle_mcck(void);
-
 static void __vcpu_run(struct kvm_vcpu *vcpu)
 {
 	memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/kvm-s390.h linux-libre-2.6.30-gnu1/arch/s390/kvm/kvm-s390.h
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/kvm-s390.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/kvm-s390.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu
 int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
 
 /* implemented in priv.c */
-int kvm_s390_handle_priv(struct kvm_vcpu *vcpu);
+int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
 
 /* implemented in sigp.c */
 int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/priv.c linux-libre-2.6.30-gnu1/arch/s390/kvm/priv.c
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/priv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/priv.c	2009-06-09 23:05:27.000000000 -0400
@@ -304,12 +304,24 @@ static intercept_handler_t priv_handlers
 	[0xb1] = handle_stfl,
 };
 
-int kvm_s390_handle_priv(struct kvm_vcpu *vcpu)
+int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
 {
 	intercept_handler_t handler;
 
+	/*
+	 * a lot of B2 instructions are priviledged. We first check for
+	 * the priviledges ones, that we can handle in the kernel. If the
+	 * kernel can handle this instruction, we check for the problem
+	 * state bit and (a) handle the instruction or (b) send a code 2
+	 * program check.
+	 * Anything else goes to userspace.*/
 	handler = priv_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler)
-		return handler(vcpu);
+	if (handler) {
+		if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+			return kvm_s390_inject_program_int(vcpu,
+						   PGM_PRIVILEGED_OPERATION);
+		else
+			return handler(vcpu);
+	}
 	return -ENOTSUPP;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/kvm/sigp.c linux-libre-2.6.30-gnu1/arch/s390/kvm/sigp.c
--- linux-libre-2.6.29-gnu1/arch/s390/kvm/sigp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/kvm/sigp.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,8 +153,6 @@ static int __sigp_set_arch(struct kvm_vc
 
 	switch (parameter & 0xff) {
 	case 0:
-		printk(KERN_WARNING "kvm: request to switch to ESA/390 mode"
-							" not supported");
 		rc = 3; /* not operational */
 		break;
 	case 1:
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/lib/delay.c linux-libre-2.6.30-gnu1/arch/s390/lib/delay.c
--- linux-libre-2.6.29-gnu1/arch/s390/lib/delay.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/lib/delay.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/timex.h>
+#include <linux/module.h>
 #include <linux/irqflags.h>
 #include <linux/interrupt.h>
 
@@ -92,6 +93,7 @@ out:
 	local_irq_restore(flags);
 	preempt_enable();
 }
+EXPORT_SYMBOL(__udelay);
 
 /*
  * Simple udelay variant. To be used on startup and reboot
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/lib/string.c linux-libre-2.6.30-gnu1/arch/s390/lib/string.c
--- linux-libre-2.6.29-gnu1/arch/s390/lib/string.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/lib/string.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,11 @@ static inline char *__strnend(const char
  */
 size_t strlen(const char *s)
 {
+#if __GNUC__ < 4
 	return __strend(s) - s;
+#else
+	return __builtin_strlen(s);
+#endif
 }
 EXPORT_SYMBOL(strlen);
 
@@ -70,6 +74,7 @@ EXPORT_SYMBOL(strnlen);
  */
 char *strcpy(char *dest, const char *src)
 {
+#if __GNUC__ < 4
 	register int r0 asm("0") = 0;
 	char *ret = dest;
 
@@ -78,6 +83,9 @@ char *strcpy(char *dest, const char *src
 		      : "+&a" (dest), "+&a" (src) : "d" (r0)
 		      : "cc", "memory" );
 	return ret;
+#else
+	return __builtin_strcpy(dest, src);
+#endif
 }
 EXPORT_SYMBOL(strcpy);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/mm/fault.c linux-libre-2.6.30-gnu1/arch/s390/mm/fault.c
--- linux-libre-2.6.29-gnu1/arch/s390/mm/fault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/mm/fault.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,29 +200,6 @@ static void do_low_address(struct pt_reg
 	do_no_context(regs, error_code, 0);
 }
 
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
-			    unsigned long address)
-{
-	struct task_struct *tsk = current;
-	struct mm_struct *mm = tsk->mm;
-
-	up_read(&mm->mmap_sem);
-	if (is_global_init(tsk)) {
-		yield();
-		down_read(&mm->mmap_sem);
-		return 1;
-	}
-	printk("VM: killing process %s\n", tsk->comm);
-	if (regs->psw.mask & PSW_MASK_PSTATE)
-		do_group_exit(SIGKILL);
-	do_no_context(regs, error_code, address);
-	return 0;
-}
-
 static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
 		      unsigned long address)
 {
@@ -367,7 +344,6 @@ good_area:
 			goto bad_area;
 	}
 
-survive:
 	if (is_vm_hugetlb_page(vma))
 		address &= HPAGE_MASK;
 	/*
@@ -378,8 +354,8 @@ survive:
 	fault = handle_mm_fault(mm, vma, address, write);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM) {
-			if (do_out_of_memory(regs, error_code, address))
-				goto survive;
+			up_read(&mm->mmap_sem);
+			pagefault_out_of_memory();
 			return;
 		} else if (fault & VM_FAULT_SIGBUS) {
 			do_sigbus(regs, error_code, address);
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/mm/init.c linux-libre-2.6.30-gnu1/arch/s390/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/s390/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,7 +40,9 @@
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
+
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+EXPORT_SYMBOL(empty_zero_page);
 
 /*
  * paging_init() sets up the page tables
diff -druNp linux-libre-2.6.29-gnu1/arch/s390/mm/pgtable.c linux-libre-2.6.30-gnu1/arch/s390/mm/pgtable.c
--- linux-libre-2.6.29-gnu1/arch/s390/mm/pgtable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/s390/mm/pgtable.c	2009-06-09 23:05:27.000000000 -0400
@@ -258,6 +258,10 @@ int s390_enable_sie(void)
 	struct task_struct *tsk = current;
 	struct mm_struct *mm, *old_mm;
 
+	/* Do we have switched amode? If no, we cannot do sie */
+	if (!switch_amode)
+		return -EINVAL;
+
 	/* Do we have pgstes? if yes, we are done */
 	if (tsk->mm->context.has_pgste)
 		return 0;
@@ -292,7 +296,7 @@ int s390_enable_sie(void)
 	tsk->mm = tsk->active_mm = mm;
 	preempt_disable();
 	update_mm(mm, tsk);
-	cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
 	preempt_enable();
 	task_unlock(tsk);
 	mmput(old_mm);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/board-ap325rxa.c linux-libre-2.6.30-gnu1/arch/sh/boards/board-ap325rxa.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/board-ap325rxa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/board-ap325rxa.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #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>
@@ -166,6 +167,16 @@ static void ap320_wvga_power_on(void *bo
 	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] = {
@@ -191,6 +202,7 @@ static struct sh_mobile_lcdc_info lcdc_i
 		},
 		.board_cfg = {
 			.display_on = ap320_wvga_power_on,
+			.display_off = ap320_wvga_power_off,
 		},
 	}
 };
@@ -224,6 +236,7 @@ static void camera_power(int val)
 }
 
 #ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
 static unsigned char camera_ncm03j_magic[] =
 {
 	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
@@ -244,6 +257,26 @@ static unsigned char camera_ncm03j_magic
 	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)
 {
@@ -295,11 +328,38 @@ static struct platform_device camera_dev
 		.platform_data	= &camera_info,
 	},
 };
+
+static int __init camera_setup(void)
+{
+	if (camera_probe() > 0)
+		platform_device_register(&camera_device);
+
+	return 0;
+}
+late_initcall(camera_setup);
+
 #endif /* CONFIG_I2C */
 
+static int ov7725_power(struct device *dev, int mode)
+{
+	camera_power(0);
+	if (mode)
+		camera_power(1);
+
+	return 0;
+}
+
+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 = {
+		.power  = ov7725_power,
+	},
+};
+
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
 };
 
 static struct resource ceu_resources[] = {
@@ -347,9 +407,6 @@ static struct platform_device *ap325rxa_
 	&ap325rxa_nor_flash_device,
 	&lcdc_device,
 	&ceu_device,
-#ifdef CONFIG_I2C
-	&camera_device,
-#endif
 	&nand_flash_device,
 	&sdcard_cn3_device,
 };
@@ -358,6 +415,10 @@ static struct i2c_board_info __initdata
 	{
 		I2C_BOARD_INFO("pcf8563", 0x51),
 	},
+	{
+		I2C_BOARD_INFO("ov772x", 0x21),
+		.platform_data = &ov7725_info,
+	},
 };
 
 static struct spi_board_info ap325rxa_spi_devices[] = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/board-espt.c linux-libre-2.6.30-gnu1/arch/sh/boards/board-espt.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/board-espt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/board-espt.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,102 @@
+/*
+ * Data Technology Inc. ESPT-GIGA board suport
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@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/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <asm/sizes.h>
+#include <asm/sh_eth.h>
+
+/* NOR Flash */
+static struct mtd_partition espt_nor_flash_partitions[] = {
+	{
+		.name = "U-Boot",
+		.offset = 0,
+		.size = (2 * SZ_128K),
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+	}, {
+		.name = "Linux-Kernel",
+		.offset = MTDPART_OFS_APPEND,
+		.size = (20 * SZ_128K),
+	}, {
+		.name = "Root Filesystem",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data espt_nor_flash_data = {
+	.width = 2,
+	.parts = espt_nor_flash_partitions,
+	.nr_parts = ARRAY_SIZE(espt_nor_flash_partitions),
+};
+
+static struct resource espt_nor_flash_resources[] = {
+	[0] = {
+		.name = "NOR Flash",
+		.start = 0,
+		.end = SZ_8M - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device espt_nor_flash_device = {
+	.name = "physmap-flash",
+	.resource = espt_nor_flash_resources,
+	.num_resources = ARRAY_SIZE(espt_nor_flash_resources),
+	.dev = {
+		.platform_data = &espt_nor_flash_data,
+	},
+};
+
+/* SH-Ether */
+static struct resource sh_eth_resources[] = {
+	{
+		.start  = 0xFEE00800,   /* use eth1 */
+		.end    = 0xFEE00F7C - 1,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = 57,   /* irq number */
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct sh_eth_plat_data sh7763_eth_pdata = {
+	.phy = 0,
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device espt_eth_device = {
+	.name       = "sh-eth",
+	.resource   = sh_eth_resources,
+	.num_resources  = ARRAY_SIZE(sh_eth_resources),
+	.dev        = {
+		.platform_data = &sh7763_eth_pdata,
+	},
+};
+
+static struct platform_device *espt_devices[] __initdata = {
+	&espt_nor_flash_device,
+	&espt_eth_device,
+};
+
+static int __init espt_devices_setup(void)
+{
+	return platform_add_devices(espt_devices,
+				    ARRAY_SIZE(espt_devices));
+}
+device_initcall(espt_devices_setup);
+
+static struct sh_machine_vector mv_espt __initmv = {
+	.mv_name = "ESPT-GIGA",
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/board-polaris.c linux-libre-2.6.30-gnu1/arch/sh/boards/board-polaris.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/board-polaris.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/board-polaris.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,149 @@
+/*
+ * June 2006 steve.glendinning@smsc.com
+ *
+ * Polaris-specific resource declaration
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <cpu/gpio.h>
+#include <mach-se/mach/se.h>
+
+#define BCR2		(0xFFFFFF62)
+#define WCR2		(0xFFFFFF66)
+#define AREA5_WAIT_CTRL	(0x1C00)
+#define WAIT_STATES_10	(0x7)
+
+static struct resource smsc911x_resources[] = {
+	[0] = {
+		.name		= "smsc911x-memory",
+		.start		= PA_EXT5,
+		.end		= PA_EXT5 + 0x1fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name		= "smsc911x-irq",
+		.start		= IRQ0_IRQ,
+		.end		= IRQ0_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct smsc911x_platform_config 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 smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+	},
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+	.bit_pos	= heartbeat_bit_pos,
+	.nr_bits	= ARRAY_SIZE(heartbeat_bit_pos),
+	.regsize	= 8,
+};
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= PORT_PCDR,
+		.end	= PORT_PCDR,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= &heartbeat_data,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+static struct platform_device *polaris_devices[] __initdata = {
+	&smsc911x_device,
+	&heartbeat_device,
+};
+
+static int __init polaris_initialise(void)
+{
+	u16 wcr, bcr_mask;
+
+	printk(KERN_INFO "Configuring Polaris external bus\n");
+
+	/* Configure area 5 with 2 wait states */
+	wcr = ctrl_inw(WCR2);
+	wcr &= (~AREA5_WAIT_CTRL);
+	wcr |= (WAIT_STATES_10 << 10);
+	ctrl_outw(wcr, WCR2);
+
+	/* Configure area 5 for 32-bit access */
+	bcr_mask = ctrl_inw(BCR2);
+	bcr_mask |= 1 << 10;
+	ctrl_outw(bcr_mask, BCR2);
+
+	return platform_add_devices(polaris_devices,
+				    ARRAY_SIZE(polaris_devices));
+}
+arch_initcall(polaris_initialise);
+
+static struct ipr_data ipr_irq_table[] = {
+	/* External IRQs */
+	{ IRQ0_IRQ, 0,  0,  1, },	/* IRQ0 */
+	{ IRQ1_IRQ, 0,  4,  1, },	/* IRQ1 */
+};
+
+static unsigned long ipr_offsets[] = {
+	INTC_IPRC
+};
+
+static struct ipr_desc ipr_irq_desc = {
+	.ipr_offsets	= ipr_offsets,
+	.nr_offsets	= ARRAY_SIZE(ipr_offsets),
+
+	.ipr_data	= ipr_irq_table,
+	.nr_irqs	= ARRAY_SIZE(ipr_irq_table),
+	.chip = {
+		.name	= "sh7709-ext",
+	},
+};
+
+static void __init init_polaris_irq(void)
+{
+	/* Disable all interrupts */
+	ctrl_outw(0, BCR_ILCRA);
+	ctrl_outw(0, BCR_ILCRB);
+	ctrl_outw(0, BCR_ILCRC);
+	ctrl_outw(0, BCR_ILCRD);
+	ctrl_outw(0, BCR_ILCRE);
+	ctrl_outw(0, BCR_ILCRF);
+	ctrl_outw(0, BCR_ILCRG);
+
+	register_ipr_controller(&ipr_irq_desc);
+}
+
+static struct sh_machine_vector mv_polaris __initmv = {
+	.mv_name		= "Polaris",
+	.mv_nr_irqs		= 61,
+	.mv_init_irq		= init_polaris_irq,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/board-sh7785lcr.c linux-libre-2.6.30-gnu1/arch/sh/boards/board-sh7785lcr.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/board-sh7785lcr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/board-sh7785lcr.c	2009-06-09 23:05:27.000000000 -0400
@@ -229,7 +229,7 @@ static struct resource i2c_resources[] =
 static struct i2c_pca9564_pf_platform_data i2c_platform_data = {
 	.gpio			= 0,
 	.i2c_clock_speed	= I2C_PCA_CON_330kHz,
-	.timeout		= 100,
+	.timeout		= HZ,
 };
 
 static struct platform_device i2c_device = {
@@ -275,7 +275,18 @@ void __init init_sh7785lcr_IRQ(void)
 
 static void sh7785lcr_power_off(void)
 {
-	ctrl_outb(0x01, P2SEGADDR(PLD_POFCR));
+	unsigned char *p;
+
+	p = ioremap(PLD_POFCR, PLD_POFCR + 1);
+	if (!p) {
+		printk(KERN_ERR "%s: ioremap error.\n", __func__);
+		return;
+	}
+	*p = 0x01;
+	iounmap(p);
+	set_bl_bit();
+	while (1)
+		cpu_relax();
 }
 
 /* Initialize the board */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/board-urquell.c linux-libre-2.6.30-gnu1/arch/sh/boards/board-urquell.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/board-urquell.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/board-urquell.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,196 @@
+/*
+ * Renesas Technology Corp. SH7786 Urquell Support.
+ *
+ * Copyright (C) 2008  Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on board-sh7785lcr.c
+ * Copyright (C) 2008  Yoshihiro Shimoda
+ *
+ * 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/platform_device.h>
+#include <linux/fb.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <mach/urquell.h>
+#include <cpu/sh7786.h>
+#include <asm/heartbeat.h>
+#include <asm/sizes.h>
+
+/*
+ * bit  1234 5678
+ *----------------------------
+ * SW1  0101 0010  -> Pck 33MHz version
+ *     (1101 0010)    Pck 66MHz version
+ * SW2  0x1x xxxx  -> little endian
+ *                    29bit mode
+ * SW47 0001 1000  -> CS0 : on-board flash
+ *                    CS1 : SRAM, registers, LAN, PCMCIA
+ *                    38400 bps for SCIF1
+ *
+ * Address
+ * 0x00000000 - 0x04000000  (CS0)     Nor Flash
+ * 0x04000000 - 0x04200000  (CS1)     SRAM
+ * 0x05000000 - 0x05800000  (CS1)     on board register
+ * 0x05800000 - 0x06000000  (CS1)     LAN91C111
+ * 0x06000000 - 0x06400000  (CS1)     PCMCIA
+ * 0x08000000 - 0x10000000  (CS2-CS3) DDR3
+ * 0x10000000 - 0x14000000  (CS4)     PCIe
+ * 0x14000000 - 0x14800000  (CS5)     Core0 LRAM/URAM
+ * 0x14800000 - 0x15000000  (CS5)     Core1 LRAM/URAM
+ * 0x18000000 - 0x1C000000  (CS6)     ATA/NAND-Flash
+ * 0x1C000000 -             (CS7)     SH7786 Control register
+ */
+
+/* HeartBeat */
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start	= BOARDREG(SLEDR),
+		.end	= BOARDREG(SLEDR),
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct heartbeat_data heartbeat_data = {
+	.regsize = 16,
+};
+
+static struct platform_device heartbeat_device = {
+	.name		= "heartbeat",
+	.id		= -1,
+	.dev	= {
+		.platform_data	= &heartbeat_data,
+	},
+	.num_resources	= ARRAY_SIZE(heartbeat_resources),
+	.resource	= heartbeat_resources,
+};
+
+/* LAN91C111 */
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+	[0] = {
+		.name   = "SMC91C111" ,
+		.start  = 0x05800300,
+		.end    = 0x0580030f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 11,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_eth_device = {
+	.name           = "smc91x",
+	.num_resources  = ARRAY_SIZE(smc91x_eth_resources),
+	.resource       = smc91x_eth_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
+};
+
+/* Nor Flash */
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name		= "loader",
+		.offset		= 0x00000000,
+		.size		= SZ_512K,
+		.mask_flags	= MTD_WRITEABLE,	/* Read-only */
+	},
+	{
+		.name		= "bootenv",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_512K,
+		.mask_flags	= MTD_WRITEABLE,	/* Read-only */
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+	},
+	{
+		.name		= "data",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0] = {
+		.start	= NOR_FLASH_ADDR,
+		.end	= NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device nor_flash_device = {
+	.name		= "physmap-flash",
+	.dev		= {
+		.platform_data	= &nor_flash_data,
+	},
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+	.resource	= nor_flash_resources,
+};
+
+static struct platform_device *urquell_devices[] __initdata = {
+	&heartbeat_device,
+	&smc91x_eth_device,
+	&nor_flash_device,
+};
+
+static int __init urquell_devices_setup(void)
+{
+	/* USB */
+	gpio_request(GPIO_FN_USB_OVC0,  NULL);
+	gpio_request(GPIO_FN_USB_PENC0, NULL);
+
+	/* enable LAN */
+	__raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001,
+		  UBOARDREG(IRL2MSKR));
+
+	return platform_add_devices(urquell_devices,
+				    ARRAY_SIZE(urquell_devices));
+}
+device_initcall(urquell_devices_setup);
+
+static void urquell_power_off(void)
+{
+	__raw_writew(0xa5a5, UBOARDREG(SRSTR));
+}
+
+static void __init urquell_init_irq(void)
+{
+	plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
+
+/* Initialize the board */
+static void __init urquell_setup(char **cmdline_p)
+{
+	printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n");
+
+	pm_power_off = urquell_power_off;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_urquell __initmv = {
+	.mv_name	= "Urquell",
+	.mv_setup	= urquell_setup,
+	.mv_init_irq	= urquell_init_irq,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/Kconfig linux-libre-2.6.30-gnu1/arch/sh/boards/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/boards/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -155,17 +155,22 @@ config SH_SH7785LCR
 
 config SH_SH7785LCR_29BIT_PHYSMAPS
 	bool "SH7785LCR 29bit physmaps"
-	depends on SH_SH7785LCR
+	depends on SH_SH7785LCR && 29BIT
 	default y
 	help
 	  This board has 2 physical memory maps. It can be changed with
 	  DIP switch(S2-5). If you set the DIP switch for S2-5 = ON,
 	  you can access all on-board device in 29bit address mode.
 
+config SH_URQUELL
+	bool "Urquell"
+	depends on CPU_SUBTYPE_SH7786
+	select ARCH_REQUIRE_GPIOLIB
+
 config SH_MIGOR
 	bool "Migo-R"
 	depends on CPU_SUBTYPE_SH7722
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Select Migo-R if configuring for the SH7722 Migo-R platform
           by Renesas System Solutions Asia Pte. Ltd.
@@ -173,7 +178,7 @@ config SH_MIGOR
 config SH_AP325RXA
 	bool "AP-325RXA"
 	depends on CPU_SUBTYPE_SH7723
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Renesas "AP-325RXA" support.
 	  Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
@@ -185,6 +190,13 @@ config SH_SH7763RDP
 	  Select SH7763RDP if configuring for a Renesas SH7763
 	  evaluation board.
 
+config SH_ESPT
+	bool "ESPT"
+	depends on CPU_SUBTYPE_SH7763
+	help
+	  Select ESPT if configuring for a Renesas SH7763
+	  with gigabit ether evaluation board.
+
 config SH_EDOSK7705
 	bool "EDOSK7705"
 	depends on CPU_SUBTYPE_SH7705
@@ -240,7 +252,7 @@ config SH_X3PROTO
 config SH_MAGIC_PANEL_R2
 	bool "Magic Panel R2"
 	depends on CPU_SUBTYPE_SH7720
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Select Magic Panel R2 if configuring for Magic Panel R2.
 
@@ -249,6 +261,13 @@ config SH_CAYMAN
 	depends on CPU_SUBTYPE_SH5_101 || CPU_SUBTYPE_SH5_103
 	select SYS_SUPPORTS_PCI
 
+config SH_POLARIS
+	bool "SMSC Polaris"
+	select CPU_HAS_IPR_IRQ
+	depends on CPU_SUBTYPE_SH7709
+	help
+	  Select if configuring for an SMSC Polaris development board
+
 endmenu
 
 source "arch/sh/boards/mach-r2d/Kconfig"
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-highlander/Kconfig linux-libre-2.6.30-gnu1/arch/sh/boards/mach-highlander/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-highlander/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-highlander/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@ config SH_R7780MP
 config SH_R7785RP
 	bool "R7785RP board support"
 	depends on CPU_SUBTYPE_SH7785
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 
 endchoice
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-hp6xx/pm_wakeup.S linux-libre-2.6.30-gnu1/arch/sh/boards/mach-hp6xx/pm_wakeup.S
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-hp6xx/pm_wakeup.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-hp6xx/pm_wakeup.S	2009-06-09 23:05:27.000000000 -0400
@@ -10,47 +10,32 @@
 #include <linux/linkage.h>
 #include <cpu/mmu_context.h>
 
-#define k0	r0
-#define k1	r1
-#define k2	r2
-#define k3	r3
-#define k4	r4
-
 /*
  * Kernel mode register usage:
  *	k0	scratch
  *	k1	scratch
- *	k2	scratch (Exception code)
- *	k3	scratch (Return address)
- *	k4	scratch
- *	k5	reserved
- *	k6	Global Interrupt Mask (0--15 << 4)
- *	k7	CURRENT_THREAD_INFO (pointer to current thread info)
+ * For more details, please have a look at entry.S
  */
 
+#define k0	r0
+#define k1	r1
+
 ENTRY(wakeup_start)
 ! clear STBY bit
-	mov	#-126, k2
+	mov	#-126, k1
    	and	#127, k0
-	mov.b	k0, @k2
+	mov.b	k0, @k1
 ! enable refresh
 	mov.l	5f, k1
 	mov.w	6f, k0
   	mov.w	k0, @k1
 ! jump to handler
-	mov.l	2f, k2
-	mov.l	3f, k3
-	mov.l	@k2, k2
-
 	mov.l	4f, k1
 	jmp	@k1
-	nop
+	 nop
 
 	.align	2
-1:	.long	EXPEVT
-2:	.long	INTEVT
-3:	.long	ret_from_irq
-4:	.long	handle_exception
+4:	.long	handle_interrupt
 5:	.long	0xffffff68
 6:	.word	0x0524
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-hp6xx/setup.c linux-libre-2.6.30-gnu1/arch/sh/boards/mach-hp6xx/setup.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-hp6xx/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx
 	.mv_setup = hp6xx_setup,
 	/* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */
 	.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6,
-	.mv_irq_demux = hd64461_irq_demux,
 	/* Enable IRQ0 -> IRQ3 in IRQ_MODE */
 	.mv_init_irq = hp6xx_init_irq,
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-migor/setup.c linux-libre-2.6.30-gnu1/arch/sh/boards/mach-migor/setup.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-migor/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-migor/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -352,8 +352,7 @@ static int tw9910_power(struct device *d
 }
 
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \
-	| SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH,
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
 };
 
 static struct resource migor_ceu_resources[] = {
@@ -450,6 +449,14 @@ static struct spi_board_info migor_spi_d
 
 static int __init migor_devices_setup(void)
 {
+
+#ifdef CONFIG_PM
+	/* Let D11 LED show STATUS0 */
+	gpio_request(GPIO_FN_STATUS0, NULL);
+
+	/* Lit D12 LED show PDSTATUS */
+	gpio_request(GPIO_FN_PDSTATUS, NULL);
+#else
 	/* Lit D11 LED */
 	gpio_request(GPIO_PTJ7, NULL);
 	gpio_direction_output(GPIO_PTJ7, 1);
@@ -459,6 +466,7 @@ static int __init migor_devices_setup(vo
 	gpio_request(GPIO_PTJ5, NULL);
 	gpio_direction_output(GPIO_PTJ5, 1);
 	gpio_export(GPIO_PTJ5, 0);
+#endif
 
 	/* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
 	gpio_request(GPIO_FN_IRQ0, NULL);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-rsk/Kconfig linux-libre-2.6.30-gnu1/arch/sh/boards/mach-rsk/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-rsk/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-rsk/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@ config SH_RSK7201
 
 config SH_RSK7203
 	bool "RSK7203"
-	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	depends on CPU_SUBTYPE_SH7203
 
 endchoice
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c linux-libre-2.6.30-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c
--- linux-libre-2.6.29-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/mach-sh7763rdp/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,15 +63,19 @@ static struct platform_device sh7763rdp_
 	},
 };
 
-/* SH-Ether */
+/*
+ * SH-Ether
+ *
+ * SH Ether of SH7763 has multi IRQ handling.
+ * (57,58,59 -> 57)
+ */
 static struct resource sh_eth_resources[] = {
 	{
 		.start  = 0xFEE00800,   /* use eth1 */
 		.end    = 0xFEE00F7C - 1,
 		.flags  = IORESOURCE_MEM,
 	}, {
-		.start  = 58,   /* irq number */
-		.end    = 58,
+		.start  = 57,   /* irq number */
 		.flags  = IORESOURCE_IRQ,
 	},
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boards/Makefile linux-libre-2.6.30-gnu1/arch/sh/boards/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/boards/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boards/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,5 +4,8 @@
 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
 obj-$(CONFIG_SH_SHMIN)		+= board-shmin.o
 obj-$(CONFIG_SH_EDOSK7760)	+= board-edosk7760.o
+obj-$(CONFIG_SH_ESPT)		+= board-espt.o
+obj-$(CONFIG_SH_POLARIS)	+= board-polaris.o
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/boot/Makefile linux-libre-2.6.30-gnu1/arch/sh/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/boot/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -33,20 +33,24 @@ $(obj)/zImage: $(obj)/compressed/vmlinux
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
-ifeq ($(CONFIG_32BIT),y)
-KERNEL_LOAD	:= $(shell /bin/bash -c 'printf "0x%08x" \
-		     $$[$(CONFIG_PAGE_OFFSET)  + \
-			$(CONFIG_ZERO_PAGE_OFFSET)]')
-else
+KERNEL_MEMORY := 0x00000000
+ifeq ($(CONFIG_PMB_FIXED),y)
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+		     $$[$(CONFIG_MEMORY_START) & 0x1fffffff]')
+endif
+ifeq ($(CONFIG_29BIT),y)
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+		     $$[$(CONFIG_MEMORY_START)]')
+endif
+
 KERNEL_LOAD	:= $(shell /bin/bash -c 'printf "0x%08x" \
 		     $$[$(CONFIG_PAGE_OFFSET)  + \
-			$(CONFIG_MEMORY_START) + \
+			$(KERNEL_MEMORY) + \
 			$(CONFIG_ZERO_PAGE_OFFSET)]')
-endif
 
 KERNEL_ENTRY	:= $(shell /bin/bash -c 'printf "0x%08x" \
 		     $$[$(CONFIG_PAGE_OFFSET)  + \
-			$(CONFIG_MEMORY_START) + \
+			$(KERNEL_MEMORY) + \
 			$(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]')
 
 quiet_cmd_uimage = UIMAGE  $@
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/cchips/hd6446x/hd64461.c linux-libre-2.6.30-gnu1/arch/sh/cchips/hd6446x/hd64461.c
--- linux-libre-2.6.29-gnu1/arch/sh/cchips/hd6446x/hd64461.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/cchips/hd6446x/hd64461.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip
 	.unmask		= hd64461_unmask_irq,
 };
 
-int hd64461_irq_demux(int irq)
+static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	if (irq == CONFIG_HD64461_IRQ) {
-		unsigned short bit;
-		unsigned short nirr = inw(HD64461_NIRR);
-		unsigned short nimr = inw(HD64461_NIMR);
-		int i;
+	unsigned short intv = ctrl_inw(HD64461_NIRR);
+	struct irq_desc *ext_desc;
+	unsigned int ext_irq = HD64461_IRQBASE;
 
-		nirr &= ~nimr;
-		for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
-			if (nirr & bit)
-				break;
-		irq = HD64461_IRQBASE + i;
+	intv &= (1 << HD64461_IRQ_NUM) - 1;
+
+	while (intv) {
+		if (intv & 1) {
+			ext_desc = irq_desc + ext_irq;
+			handle_level_irq(ext_irq, ext_desc);
+		}
+		intv >>= 1;
+		ext_irq++;
 	}
-	return irq;
 }
 
 int __init setup_hd64461(void)
@@ -93,6 +94,9 @@ int __init setup_hd64461(void)
 		set_irq_chip_and_handler(i, &hd64461_irq_chip,
 					 handle_level_irq);
 
+	set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
+	set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
+
 #ifdef CONFIG_HD64461_ENABLER
 	printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
 	__raw_writeb(0x4c, HD64461_PCC1CSCIER);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/ap325rxa_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/ap325rxa_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/ap325rxa_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/ap325rxa_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 27 11:45:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:46:53 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,6 +45,15 @@ 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_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=14
 CONFIG_GROUP_SCHED=y
@@ -58,6 +69,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -66,10 +78,8 @@ 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
@@ -77,6 +87,7 @@ 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
@@ -115,11 +126,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -128,6 +134,7 @@ CONFIG_CLASSIC_RCU=y
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -156,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7723=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -228,6 +237,7 @@ CONFIG_SH_AP325RXA=y
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -304,7 +314,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -359,6 +368,7 @@ 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
 
@@ -371,7 +381,6 @@ 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 is not set
@@ -483,7 +492,6 @@ CONFIG_MTD_NAND_SH_FLCTL=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -510,10 +518,18 @@ 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_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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -559,9 +575,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC 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
@@ -594,8 +612,10 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -612,7 +632,6 @@ CONFIG_SMSC911X=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
@@ -687,6 +706,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -723,12 +743,9 @@ CONFIG_I2C_SH_MOBILE=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_AT24 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
@@ -748,7 +765,6 @@ CONFIG_SPI_GPIO=y
 #
 # SPI Protocol Masters
 #
-# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
@@ -822,7 +838,7 @@ CONFIG_VIDEO_MEDIA=y
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -831,6 +847,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEOBUF_GEN=y
 CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -886,6 +903,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -995,6 +1013,7 @@ CONFIG_RTC_DRV_PCF8563=y
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
@@ -1096,7 +1115,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1177,7 +1195,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1204,10 +1221,12 @@ 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
@@ -1276,6 +1295,7 @@ CONFIG_CRYPTO_CBC=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1296,7 +1316,7 @@ CONFIG_CRC_ITU_T=y
 CONFIG_CRC32=y
 CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/cayman_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/cayman_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/cayman_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/cayman_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 18:04:52 2008
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:49:14 2009
 #
 CONFIG_SUPERH=y
 # CONFIG_SUPERH32 is not set
@@ -16,6 +16,8 @@ CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_GPIO is not set
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -23,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -40,10 +43,19 @@ CONFIG_POSIX_MQUEUE=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 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
@@ -51,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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=y
@@ -61,10 +74,8 @@ 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
@@ -73,18 +84,18 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=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
@@ -92,11 +103,9 @@ 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
 
@@ -112,7 +121,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 is not set
 
 #
@@ -120,6 +128,7 @@ CONFIG_CLASSIC_RCU=y
 #
 CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -146,6 +155,7 @@ CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -188,16 +198,16 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_CACHE_WRITEBACK is not set
 # CONFIG_CACHE_WRITETHROUGH is not set
 CONFIG_CACHE_OFF=y
@@ -256,7 +266,6 @@ CONFIG_HZ=250
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
 
 #
 # Boot options
@@ -272,9 +281,12 @@ CONFIG_PCI=y
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
 # 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
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -285,6 +297,12 @@ 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
 #
@@ -344,7 +362,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
@@ -355,13 +375,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 is not set
 # CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 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
 
@@ -400,11 +420,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -447,6 +476,7 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI 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
@@ -459,7 +489,10 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC 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
@@ -478,6 +511,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -493,6 +527,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -510,7 +545,10 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
+# CONFIG_SMSC911X 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
@@ -543,9 +581,11 @@ CONFIG_NETDEV_1000=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=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
@@ -554,11 +594,13 @@ CONFIG_NETDEV_10000=y
 # 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
 
 #
@@ -566,7 +608,10 @@ CONFIG_NETDEV_10000=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -636,10 +681,12 @@ CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_SH_SCI is not set
 # 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=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -700,12 +747,9 @@ CONFIG_I2C_HELPER_AUTO=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
@@ -725,8 +769,10 @@ CONFIG_HWMON=y
 # 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_I5K_AMB is not set
@@ -747,10 +793,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -786,11 +836,11 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -802,6 +852,8 @@ CONFIG_SSB_POSSIBLE=y
 # 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_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -822,7 +874,7 @@ CONFIG_VIDEO_MEDIA=m
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=m
 CONFIG_MEDIA_TUNER_TDA8290=m
 CONFIG_MEDIA_TUNER_TDA9887=m
@@ -831,6 +883,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
 CONFIG_MEDIA_TUNER_MT20XX=m
 CONFIG_MEDIA_TUNER_XC2028=m
 CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
 CONFIG_VIDEO_V4L2=m
 CONFIG_VIDEO_V4L1=m
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -853,6 +906,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 # CONFIG_VIDEO_CAFE_CCIC is not set
 # CONFIG_SOC_CAMERA is not set
 # CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
 #
@@ -884,89 +938,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
 #
 # Supported DVB Frontends
 #
-
-#
-# Customise DVB Frontends
-#
 # CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# DVB-S (satellite) frontends
-#
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# 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=y
 
 #
@@ -979,15 +951,16 @@ 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=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
+# 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_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
 # CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -1025,6 +998,8 @@ CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -1081,9 +1056,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk 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_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1091,6 +1071,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -1114,6 +1095,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1148,10 +1130,7 @@ CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=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
@@ -1160,6 +1139,7 @@ CONFIG_HUGETLB_PAGE=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1179,7 +1159,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
@@ -1252,6 +1231,7 @@ 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_FRAME_POINTER=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1260,17 +1240,25 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+
+#
+# Tracers
+#
+# 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES 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_SH64_PROC_ASIDS=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
 CONFIG_SH64_SR_WATCH=y
 # CONFIG_POOR_MANS_STRACE is not set
-# CONFIG_SH_ALPHANUMERIC is not set
-# CONFIG_SH_NO_BSS_INIT is not set
 
 #
 # Security options
@@ -1286,6 +1274,7 @@ CONFIG_CRYPTO=y
 #
 # 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
@@ -1356,6 +1345,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1369,6 +1359,7 @@ CONFIG_CRYPTO_HW=y
 # 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
@@ -1376,7 +1367,7 @@ CONFIG_BITREVERSE=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/dreamcast_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/dreamcast_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/dreamcast_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/dreamcast_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:54:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:51:48 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,10 +45,19 @@ 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_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=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
@@ -55,6 +65,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -64,10 +75,8 @@ 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
@@ -76,6 +85,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7091=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -202,11 +208,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -263,9 +270,12 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 CONFIG_NR_DMA_CHANNELS_BOOL=y
 CONFIG_NR_DMA_CHANNELS=9
+# CONFIG_PVR2_DMA is not set
+# CONFIG_G2_DMA is not set
 
 #
 # Companion Chips
@@ -314,6 +324,8 @@ CONFIG_PCI_AUTO=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 is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -335,7 +347,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -387,6 +398,7 @@ 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
 
@@ -399,13 +411,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -439,12 +451,16 @@ CONFIG_GDROM=y
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -470,6 +486,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -487,8 +504,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -532,7 +551,10 @@ CONFIG_8139TOO=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -628,6 +650,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -746,6 +769,7 @@ CONFIG_FB_PVR2=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
 
 #
@@ -802,9 +826,13 @@ 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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -813,6 +841,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -828,6 +857,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -871,6 +901,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -920,7 +951,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1012,6 +1042,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1033,7 +1064,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/edosk7705_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/edosk7705_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/edosk7705_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/edosk7705_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:55:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:54:02 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -35,6 +36,15 @@ CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT 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_CGROUPS is not set
@@ -50,7 +60,6 @@ CONFIG_EMBEDDED=y
 # CONFIG_PRINTK is not set
 # CONFIG_BUG is not set
 # CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
@@ -60,6 +69,7 @@ CONFIG_EMBEDDED=y
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -74,11 +84,6 @@ CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
-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_FREEZER is not set
 
 #
@@ -113,6 +118,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -157,12 +163,13 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
 CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,7 +250,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 # 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 is not set
@@ -361,6 +367,7 @@ CONFIG_SSB_POSSIBLE=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
 # CONFIG_STAGING is not set
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/edosk7760_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/edosk7760_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/edosk7760_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/edosk7760_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:55:48 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:54:57 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,34 +44,45 @@ 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_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=17
-# 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_INITRAMFS_COMPRESSION_NONE=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_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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
@@ -79,6 +91,7 @@ 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
@@ -118,11 +131,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -157,6 +165,7 @@ CONFIG_CPU_SUBTYPE_SH7760=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +207,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -245,7 +255,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 # CONFIG_SH_DMABRG is not set
 
@@ -310,7 +320,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -360,6 +369,7 @@ 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
 
@@ -372,13 +382,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -402,6 +412,7 @@ CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
 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_AR7_PARTS is not set
@@ -454,9 +465,7 @@ CONFIG_MTD_ABSENT=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -477,6 +486,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # 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
@@ -506,6 +520,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
@@ -518,8 +533,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# 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
@@ -536,7 +553,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
@@ -607,6 +627,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -643,12 +664,9 @@ CONFIG_I2C_SH7760=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=y
@@ -680,6 +698,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 # CONFIG_REGULATOR is not set
 
 #
@@ -732,6 +751,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -750,6 +770,7 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
@@ -781,6 +802,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=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
 # CONFIG_STAGING is not set
 
@@ -806,6 +828,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -851,6 +874,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -868,7 +892,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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 +997,7 @@ CONFIG_DEBUG_INFO=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -989,7 +1013,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1095,6 +1118,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1115,7 +1139,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=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.29-gnu1/arch/sh/configs/espt_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/espt_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/espt_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/espt_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1199 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:58:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=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=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# 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_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=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+# 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=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+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
+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_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=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 is not set
+# CONFIG_MODULE_UNLOAD is not set
+# 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_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_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7763=y
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+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_ENTRY_OFFSET=0x00001000
+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
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_SH7763RDP is not set
+CONFIG_SH_ESPT=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_SH_PCLK_FREQ=66666666
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# 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_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/nfs ip=bootp"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE 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=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_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_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_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_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_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=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 is not set
+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 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=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT 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_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_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=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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC 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 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=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# CONFIG_SMC91X 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
+#
+
+#
+# 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 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_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=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
+# 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
+
+#
+# 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=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=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_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_SH_MOBILE_LCDC is not set
+CONFIG_FB_SH7760=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=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_LOGO_SUPERH_MONO=y
+CONFIG_LOGO_SUPERH_VGA16=y
+CONFIG_LOGO_SUPERH_CLUT224=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 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_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_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
+
+#
+# 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_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_CLASS 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 is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+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=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS 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=y
+CONFIG_AUTOFS4_FS=y
+# 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_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=y
+# CONFIG_HUGETLBFS 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 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=y
+# 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=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# 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 is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_DEBUG is not set
+# 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_MORE_COMPILE_OPTIONS 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=y
+
+#
+# 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_ZLIB_INFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/hp6xx_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/hp6xx_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/hp6xx_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/hp6xx_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:56:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:01:05 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -39,11 +40,20 @@ CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 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=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=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -51,6 +61,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -60,10 +71,8 @@ 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
@@ -71,6 +80,7 @@ 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
@@ -104,11 +114,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER=y
 
 #
@@ -143,6 +148,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -184,11 +190,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -208,6 +215,7 @@ CONFIG_CPU_HAS_SR_RB=y
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 CONFIG_SH_HP6XX=y
+# CONFIG_SH_POLARIS is not set
 
 #
 # Timer and clock configuration
@@ -229,7 +237,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
@@ -302,6 +310,7 @@ CONFIG_PM=y
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
 CONFIG_APM_EMULATION=y
 # CONFIG_CPU_IDLE is not set
 # CONFIG_NET is not set
@@ -329,9 +338,13 @@ CONFIG_BLK_DEV=y
 # CONFIG_CDROM_PKTCDVD 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -375,6 +388,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -471,6 +485,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 
 #
@@ -554,12 +569,13 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
 CONFIG_BACKLIGHT_HP680=y
 
 #
@@ -631,6 +647,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -647,6 +664,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -692,6 +710,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -771,7 +790,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -799,10 +817,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
 
@@ -870,6 +890,7 @@ CONFIG_CRYPTO_MD5=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -890,7 +911,6 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/landisk_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/landisk_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/landisk_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/landisk_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:58:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:02:54 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_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 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
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -62,10 +73,8 @@ 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
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -290,6 +297,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
@@ -329,7 +338,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -410,6 +418,7 @@ CONFIG_ATALK=m
 # 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
 
@@ -422,13 +431,13 @@ CONFIG_ATALK=m
 # 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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -468,18 +477,23 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_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_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
@@ -585,6 +599,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -607,6 +622,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_SRP 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 is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
@@ -631,6 +647,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -648,8 +665,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -700,6 +719,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -718,6 +738,7 @@ 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
 
 #
@@ -725,7 +746,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -814,6 +838,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -898,6 +923,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
 CONFIG_V4L_USB_DRIVERS=y
 # CONFIG_USB_VIDEO_CLASS is not set
 # CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_HDPVR is not set
 CONFIG_VIDEO_USBVIDEO=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_IBMCAM=m
@@ -911,6 +937,7 @@ CONFIG_USB_STV680=m
 # CONFIG_USB_ZC0301 is not set
 CONFIG_USB_PWC=m
 # CONFIG_USB_PWC_DEBUG 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
@@ -1020,6 +1047,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_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
@@ -1041,22 +1069,21 @@ CONFIG_USB_PRINTER=m
 # 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=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
 # CONFIG_USB_STORAGE_USBAT is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
@@ -1081,7 +1108,7 @@ CONFIG_USB_SERIAL=m
 # 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_CP2101 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=m
@@ -1105,15 +1132,19 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # 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
 
 #
@@ -1130,7 +1161,6 @@ CONFIG_USB_EMI26=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
@@ -1143,6 +1173,11 @@ CONFIG_USB_SISUSBVGA_CON=y
 # 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
@@ -1151,6 +1186,7 @@ CONFIG_USB_SISUSBVGA_CON=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -1176,6 +1212,7 @@ CONFIG_REISERFS_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1226,6 +1263,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -1250,7 +1288,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
@@ -1331,7 +1368,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1424,6 +1460,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1445,7 +1482,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/lboxre2_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/lboxre2_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/lboxre2_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/lboxre2_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:02:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:06:51 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_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 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
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -62,10 +73,8 @@ 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
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -291,6 +298,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
@@ -329,7 +338,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -408,6 +416,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # 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
 
@@ -420,13 +429,13 @@ CONFIG_NETFILTER_ADVANCED=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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -465,12 +474,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -526,6 +539,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -549,6 +563,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_SRP 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=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -624,6 +639,7 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -641,8 +657,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -697,6 +715,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -715,6 +734,7 @@ 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
 
 #
@@ -722,7 +742,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -810,6 +833,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -921,9 +945,13 @@ 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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -968,6 +996,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -990,6 +1019,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1036,6 +1066,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -1124,7 +1155,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1217,6 +1247,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1238,7 +1269,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/magicpanelr2_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/magicpanelr2_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/magicpanelr2_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/magicpanelr2_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:03:37 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:07:39 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,33 +44,44 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
 CONFIG_AUDIT=y
 # CONFIG_AUDITSYSCALL 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_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_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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
@@ -77,6 +89,7 @@ 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
@@ -116,11 +129,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -155,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7720=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +205,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -309,7 +319,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -359,6 +368,7 @@ 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
 
@@ -371,13 +381,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -402,6 +412,7 @@ 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=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -452,9 +463,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -475,6 +484,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # 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
@@ -491,9 +505,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65536
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -507,6 +525,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
@@ -538,8 +557,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -556,7 +577,10 @@ CONFIG_SMSC911X=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
@@ -778,6 +802,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -797,6 +822,7 @@ CONFIG_JBD=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -849,6 +875,7 @@ 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
@@ -868,7 +895,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
@@ -970,6 +996,7 @@ CONFIG_FRAME_POINTER=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -984,7 +1011,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1025,7 +1051,8 @@ CONFIG_CRC32=y
 CONFIG_AUDIT_GENERIC=y
 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/microdev_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/microdev_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/microdev_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/microdev_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:06:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:11:13 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,18 +43,32 @@ 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_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=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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -63,10 +78,8 @@ 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
@@ -74,6 +87,7 @@ 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
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +203,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -239,7 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
@@ -304,7 +315,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 CONFIG_XFRM=y
@@ -358,6 +368,7 @@ 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
 
@@ -370,13 +381,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -407,9 +418,13 @@ 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -443,6 +458,7 @@ CONFIG_IDE_PROC_FS=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
@@ -455,8 +471,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# 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
@@ -473,7 +491,10 @@ CONFIG_NETDEV_10000=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
@@ -520,6 +541,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -601,15 +623,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -632,6 +659,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -678,6 +706,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -698,7 +727,6 @@ CONFIG_LOCKD_V4=y
 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
@@ -778,7 +806,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -806,10 +833,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
 
@@ -877,6 +906,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -897,7 +927,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=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.29-gnu1/arch/sh/configs/migor_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/migor_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/migor_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/migor_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc1
-# Thu Jan 22 09:16:16 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:14:03 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,14 +44,19 @@ CONFIG_SYSVIPC_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 is not set
-
-#
-# Control Group support
-#
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -57,8 +64,13 @@ 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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -68,10 +80,8 @@ 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
@@ -79,6 +89,7 @@ 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
@@ -120,11 +131,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -134,6 +140,7 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -162,6 +169,7 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 CONFIG_CPU_SUBTYPE_SH7722=y
@@ -209,11 +217,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,6 +252,7 @@ CONFIG_SH_MIGOR_QVGA=y
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 # CONFIG_NO_HZ is not set
@@ -318,7 +328,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -373,6 +382,7 @@ 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
 
@@ -380,12 +390,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -495,7 +505,6 @@ CONFIG_MTD_NAND_PLATFORM=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -514,10 +523,17 @@ 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -563,9 +579,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC 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
@@ -578,8 +596,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# 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
@@ -596,7 +616,6 @@ 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
@@ -679,6 +698,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -715,12 +735,9 @@ CONFIG_I2C_SH_MOBILE=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
@@ -797,7 +814,7 @@ CONFIG_VIDEO_MEDIA=y
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -806,6 +823,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEOBUF_GEN=y
 CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -866,7 +884,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # 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_FILES is not set
@@ -905,6 +923,7 @@ CONFIG_USB_G_SERIAL=y
 # 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
@@ -964,6 +983,7 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
@@ -1045,7 +1065,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1090,7 +1109,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1117,10 +1136,12 @@ CONFIG_CRYPTO_AEAD2=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
@@ -1189,6 +1210,7 @@ CONFIG_CRYPTO_MANAGER2=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1209,7 +1231,9 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=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.29-gnu1/arch/sh/configs/polaris_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/polaris_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/polaris_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/polaris_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,972 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:16:48 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=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=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+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 is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL 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=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 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=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
+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_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=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 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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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=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_CPU_SH3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+CONFIG_CPU_SUBTYPE_SH7709=y
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0C000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+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_ENTRY_OFFSET=0x00001000
+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=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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU_EMU=y
+CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Board support
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_HP6XX is not set
+CONFIG_SH_POLARIS=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=33000000
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+CONFIG_SH_DMA_API=y
+CONFIG_SH_DMA=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
+# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/mtdblock2 rootfstype=jffs2 mem=63M mtdparts=physmap-flash.0:0x00100000(bootloader)ro,0x00500000(Kernel)ro,0x00A00000(Filesystem)"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# 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 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 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=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_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=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=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=y
+# CONFIG_MTD_JEDECPROBE is not set
+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 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_OTP 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=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x01000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# 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_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_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_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=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_STNIC is not set
+# CONFIG_SMC91X 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_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
+
+#
+# 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 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=y
+CONFIG_DEVKMEM=y
+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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_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 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_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
+
+#
+# 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_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=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_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_SH=y
+# 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 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 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_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
+
+#
+# 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_HUGETLBFS 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 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_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 is not set
+# CONFIG_DLM 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=1024
+# 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=y
+CONFIG_DEBUG_SHIRQ=y
+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_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 is not set
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP 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=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=y
+# CONFIG_DEBUG_NOTIFIERS 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_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_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_SAMPLES is not set
+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=0x00000000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_BOOTMEM is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+CONFIG_DUMP_CODE=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS 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
+
+#
+# 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_AUDIT_GENERIC=y
+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.29-gnu1/arch/sh/configs/r7780mp_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/r7780mp_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/r7780mp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/r7780mp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:10:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:20:17 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -45,15 +46,24 @@ 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_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=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
@@ -61,6 +71,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -71,10 +82,8 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -124,11 +134,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -164,6 +169,7 @@ CONFIG_CPU_SH4A=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -179,8 +185,11 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -212,11 +221,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -309,6 +319,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -330,7 +342,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -392,6 +403,7 @@ 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_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -399,12 +411,12 @@ CONFIG_LLC=m
 # 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_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -412,6 +424,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -451,13 +464,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
 # 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -513,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -535,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -609,6 +631,7 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -627,8 +650,10 @@ CONFIG_AX88796_93CX6=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -684,6 +709,7 @@ CONFIG_R8169=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -702,6 +728,7 @@ 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
 
 #
@@ -709,7 +736,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -796,6 +826,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -857,12 +888,9 @@ CONFIG_I2C_HIGHLANDER=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
@@ -885,6 +913,7 @@ 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_I5K_AMB is not set
@@ -905,10 +934,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -949,6 +982,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 # CONFIG_REGULATOR is not set
 
 #
@@ -1007,9 +1041,13 @@ 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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1071,6 +1109,7 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1094,6 +1133,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1142,6 +1182,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1166,7 +1207,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1269,6 +1309,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT 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_HAVE_DYNAMIC_FTRACE=y
@@ -1288,7 +1329,7 @@ CONFIG_TRACING=y
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1325,10 +1366,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
@@ -1397,6 +1440,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1421,3 +1465,4 @@ CONFIG_CRC32=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/r7785rp_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/r7785rp_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/r7785rp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/r7785rp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:14:41 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:24:35 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -48,11 +49,21 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 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=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -60,21 +71,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -126,12 +136,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_FREEZER is not set
 
 #
@@ -168,6 +172,7 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -183,8 +188,11 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
@@ -222,11 +230,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -334,6 +343,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -355,7 +366,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -417,6 +427,7 @@ 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_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -425,12 +436,12 @@ CONFIG_LLC=m
 #
 # 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=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -438,6 +449,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -477,13 +489,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
 # 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +558,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -561,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -635,6 +656,7 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -653,8 +675,10 @@ CONFIG_AX88796_93CX6=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -687,6 +711,7 @@ CONFIG_R8169=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -705,6 +730,7 @@ 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
 
 #
@@ -712,7 +738,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -800,6 +829,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -862,12 +892,9 @@ CONFIG_I2C_HIGHLANDER=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
@@ -914,6 +941,7 @@ 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_I5K_AMB is not set
@@ -934,10 +962,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -979,6 +1011,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 # CONFIG_REGULATOR is not set
 
 #
@@ -1055,6 +1088,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -1089,9 +1123,13 @@ 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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1153,6 +1191,7 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1176,6 +1215,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1224,6 +1264,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1248,7 +1289,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1354,6 +1394,7 @@ CONFIG_FRAME_POINTER=y
 # 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_HAVE_DYNAMIC_FTRACE=y
@@ -1373,7 +1414,7 @@ CONFIG_TRACING=y
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1410,10 +1451,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
@@ -1482,6 +1525,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1504,7 +1548,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_AUDIT_GENERIC=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.29-gnu1/arch/sh/configs/rsk7201_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/rsk7201_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/rsk7201_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/rsk7201_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:19:04 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:29:08 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -24,6 +24,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -38,11 +39,20 @@ 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=y
 # CONFIG_IKCONFIG_PROC 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_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
@@ -52,8 +62,13 @@ CONFIG_USER_NS=y
 CONFIG_PID_NS=y
 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_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -63,16 +78,15 @@ 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_AIO 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
@@ -112,11 +126,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -152,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7201=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -190,11 +200,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -217,7 +227,6 @@ CONFIG_SH_RSK7201=y
 #
 # Timer and clock configuration
 #
-# CONFIG_SH_CMT is not set
 CONFIG_SH_MTU2=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=40000000
@@ -251,7 +260,6 @@ CONFIG_SH_CLK_MD=0
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -308,6 +316,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -358,9 +367,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # 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=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -381,6 +388,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # 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
@@ -392,9 +404,13 @@ CONFIG_BLK_DEV=y
 # CONFIG_CDROM_PKTCDVD 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -562,6 +578,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -577,6 +594,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_XFS_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
@@ -626,6 +644,7 @@ 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
@@ -671,7 +690,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -701,7 +720,7 @@ 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
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/rsk7203_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/rsk7203_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/rsk7203_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/rsk7203_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:20:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:30:34 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_GPIO=y
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,11 +43,20 @@ 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_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 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_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
@@ -53,31 +64,35 @@ CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS 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_INITRAMFS_COMPRESSION_NONE=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_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -117,11 +132,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -157,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7203=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -195,11 +206,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -271,7 +282,6 @@ CONFIG_HEARTBEAT=y
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -315,8 +325,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 # CONFIG_NET_KEY is not set
@@ -364,6 +372,7 @@ 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
 
@@ -371,18 +380,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET 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
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -405,6 +415,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -455,9 +466,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # 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=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -478,6 +487,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # 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
@@ -492,9 +506,13 @@ CONFIG_BLK_DEV=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -508,6 +526,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
@@ -539,8 +558,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -557,7 +578,10 @@ CONFIG_SMSC911X=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
@@ -777,7 +801,9 @@ 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_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_HWA_HCD is not set
@@ -791,11 +817,11 @@ CONFIG_USB_R8A66597_HCD=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
 
@@ -823,7 +849,6 @@ CONFIG_USB_R8A66597_HCD=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
@@ -834,6 +859,12 @@ CONFIG_USB_R8A66597_HCD=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_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=y
@@ -852,6 +883,10 @@ CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=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
@@ -891,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -906,6 +942,7 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -945,6 +982,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -962,7 +1000,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1018,6 +1055,7 @@ CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 CONFIG_DEBUG_WRITECOUNT=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_DEBUG_LIST=y
@@ -1031,6 +1069,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1048,7 +1087,7 @@ CONFIG_TRACING=y
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1086,7 +1125,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/rts7751r2d1_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/rts7751r2d1_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/rts7751r2d1_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:23:15 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:33:25 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_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 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
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -63,10 +74,8 @@ 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
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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 is not set
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +384,7 @@ 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
 
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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,8 +627,10 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X 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_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ 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
 
 #
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=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
 
 #
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
 #
 # 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_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ 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=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
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=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
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
 # 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
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/rts7751r2dplus_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/rts7751r2dplus_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/rts7751r2dplus_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:26:10 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:34:12 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_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 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
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -63,10 +74,8 @@ 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
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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 is not set
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +384,7 @@ 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
 
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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,8 +627,10 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X 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_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ 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
 
 #
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=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
 
 #
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
 # 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
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
 #
 # 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_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ 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=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
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=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
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
 # 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
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/sdk7780_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sdk7780_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sdk7780_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sdk7780_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:26:40 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:34:43 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,11 +45,20 @@ 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_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=18
-# 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
@@ -56,21 +66,19 @@ CONFIG_RELAY=y
 # 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=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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
@@ -80,6 +88,7 @@ CONFIG_AIO=y
 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
@@ -119,11 +128,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -159,6 +163,7 @@ CONFIG_CPU_SH4A=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -174,8 +179,11 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -207,11 +215,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -257,6 +266,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=12
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -306,6 +316,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 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
@@ -348,7 +360,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -427,6 +438,7 @@ 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_NET_SCHED=y
 
 #
@@ -471,13 +483,13 @@ CONFIG_NET_SCH_FIFO=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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -631,6 +643,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -654,6 +667,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_SRP 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=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -739,6 +753,7 @@ CONFIG_BLK_DEV_DM=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -756,8 +771,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -780,7 +797,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
+#
 
 #
 # USB Network Adapters
@@ -840,7 +860,6 @@ 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_TOUCHKIT is not set
@@ -899,6 +918,7 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_PPDEV 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_APPLICOM is not set
 
@@ -1023,6 +1043,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -1123,6 +1144,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_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
@@ -1141,18 +1163,17 @@ CONFIG_USB_PRINTER=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
@@ -1189,7 +1210,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
@@ -1201,6 +1221,11 @@ 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_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1243,7 +1268,9 @@ CONFIG_FS_MBCACHE=y
 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1295,6 +1322,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1318,7 +1346,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1424,6 +1451,7 @@ CONFIG_DEBUG_INFO=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1439,7 +1467,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1544,6 +1571,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1565,7 +1593,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7206_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7206_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7206_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7206_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:31:27 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:39:37 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,18 +45,28 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_TASKSTATS is not set
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
 # CONFIG_CGROUP_FREEZER is not set
 CONFIG_CGROUP_DEVICE=y
-# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_MM_OWNER=y
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
@@ -62,31 +74,35 @@ CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS 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_INITRAMFS_COMPRESSION_NONE=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_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-# 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_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -127,12 +143,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_FREEZER is not set
 
 #
@@ -168,6 +178,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -206,11 +217,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -280,7 +291,6 @@ CONFIG_HEARTBEAT=y
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
@@ -322,8 +332,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -378,6 +386,7 @@ 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
 
@@ -385,18 +394,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET 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
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -419,6 +429,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -466,9 +477,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -489,6 +498,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
 # 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
@@ -506,9 +520,13 @@ 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=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -522,6 +540,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
@@ -534,8 +553,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# 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
@@ -552,7 +573,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
@@ -696,6 +720,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -712,6 +737,7 @@ CONFIG_EXT2_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -752,6 +778,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS 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
@@ -771,7 +798,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
@@ -824,6 +850,7 @@ CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_DEBUG_LIST=y
@@ -835,6 +862,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT 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_HAVE_DYNAMIC_FTRACE=y
@@ -852,7 +880,7 @@ CONFIG_TRACING=y
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -955,6 +983,7 @@ CONFIG_CRYPTO_CRC32C=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=y
 
 #
@@ -980,7 +1009,8 @@ 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.29-gnu1/arch/sh/configs/se7343_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7343_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7343_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7343_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:33:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:42:00 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +43,23 @@ CONFIG_POSIX_MQUEUE=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 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
@@ -56,6 +67,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -65,10 +77,8 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -76,6 +86,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 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
@@ -114,11 +125,6 @@ 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_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_FREEZER is not set
 
 #
@@ -127,6 +133,7 @@ CONFIG_CLASSIC_RCU=y
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -155,6 +162,7 @@ CONFIG_CPU_SH4AL_DSP=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 CONFIG_CPU_SUBTYPE_SH7343=y
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +204,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -227,6 +236,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 # CONFIG_NO_HZ is not set
@@ -302,7 +312,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -353,6 +362,7 @@ 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
 
@@ -365,13 +375,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -394,6 +404,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -441,9 +452,7 @@ CONFIG_MTD_RAM=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -464,6 +473,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # 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
@@ -520,9 +534,11 @@ 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_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -539,7 +555,10 @@ CONFIG_MII=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
@@ -633,6 +652,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -669,12 +689,9 @@ CONFIG_I2C_SH_MOBILE=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
@@ -706,6 +723,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 # CONFIG_REGULATOR is not set
 
 #
@@ -727,7 +745,7 @@ CONFIG_VIDEO_MEDIA=y
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -736,6 +754,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEO_V4L1=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -757,6 +776,7 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_GSPCA_ETOMS is not set
 # CONFIG_USB_GSPCA_FINEPIX 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
@@ -769,6 +789,8 @@ CONFIG_USB_GSPCA=m
 # 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
@@ -776,6 +798,7 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_GSPCA_VC032X is not set
 # CONFIG_USB_GSPCA_ZC3XX is not set
 # CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
 # CONFIG_VIDEO_EM28XX is not set
 # CONFIG_VIDEO_USBVISION is not set
 # CONFIG_USB_VICAM is not set
@@ -833,6 +856,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -940,7 +964,9 @@ CONFIG_USB_DEVICE_CLASS=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 CONFIG_USB_ISP116X_HCD=y
+# 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
@@ -954,11 +980,11 @@ CONFIG_USB_ISP116X_HCD=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 is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -988,7 +1014,6 @@ CONFIG_USB_ISP116X_HCD=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
@@ -999,12 +1024,18 @@ CONFIG_USB_ISP116X_HCD=y
 # 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_MMC is not set
 # 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=y
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
@@ -1031,6 +1062,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -1084,6 +1116,7 @@ CONFIG_JFFS2_ZLIB=y
 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
@@ -1105,7 +1138,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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
@@ -1146,7 +1178,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1240,6 +1271,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1265,3 +1297,4 @@ 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.29-gnu1/arch/sh/configs/se7619_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7619_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7619_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7619_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:36:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:44:53 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -36,15 +38,25 @@ CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT 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=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS 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 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -53,16 +65,15 @@ CONFIG_EMBEDDED=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -93,11 +104,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -132,6 +138,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -170,11 +177,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_CACHE_WRITEBACK is not set
 CONFIG_CACHE_WRITETHROUGH=y
 # CONFIG_CACHE_OFF is not set
@@ -228,7 +235,6 @@ CONFIG_HZ_100=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -329,9 +335,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_SOLUTIONENGINE is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -353,6 +357,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
@@ -364,9 +373,13 @@ CONFIG_BLK_DEV=y
 # CONFIG_CDROM_PKTCDVD 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -514,15 +527,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -537,6 +555,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_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
@@ -575,6 +594,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -614,7 +634,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7705_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7705_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7705_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7705_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:37:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:45:56 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,16 +42,30 @@ CONFIG_LOCALVERSION_AUTO=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 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_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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -59,10 +74,8 @@ CONFIG_UID16=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
@@ -70,6 +83,7 @@ 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
@@ -106,11 +120,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -145,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -186,12 +196,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
 CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -292,7 +303,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -347,6 +357,7 @@ 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
 
@@ -359,13 +370,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -384,6 +395,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -451,6 +463,11 @@ CONFIG_MTD_CFI_UTIL=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
@@ -467,9 +484,13 @@ 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_EEPROM_93CX6 is not set
 # 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
 
@@ -483,6 +504,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
@@ -495,8 +517,10 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X 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
@@ -513,7 +537,10 @@ CONFIG_NETDEV_10000=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=y
 # CONFIG_PPP_MULTILINK is not set
@@ -593,6 +620,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
@@ -684,15 +712,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -709,6 +742,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -761,6 +795,7 @@ 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
@@ -778,7 +813,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -817,7 +851,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -908,6 +941,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -930,7 +964,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7712_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7712_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7712_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7712_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:40:12 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:48:18 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,10 +42,19 @@ 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_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=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
@@ -52,21 +62,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +82,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 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
@@ -112,11 +121,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -151,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7712=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,7 +306,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -364,6 +369,7 @@ 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=y
 
 #
@@ -411,7 +417,6 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -419,6 +424,7 @@ CONFIG_WIRELESS=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -443,6 +449,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -510,6 +517,11 @@ CONFIG_MTD_CFI_UTIL=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
@@ -523,9 +535,13 @@ CONFIG_BLK_DEV=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -571,6 +587,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG 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
@@ -579,6 +596,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # 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
@@ -611,8 +629,10 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 CONFIG_SH_ETH=y
 # CONFIG_SMC91X 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
@@ -629,7 +649,10 @@ CONFIG_NETDEV_10000=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
@@ -675,6 +698,7 @@ CONFIG_UNIX98_PTYS=y
 # 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
@@ -744,9 +768,13 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -764,9 +792,14 @@ CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT 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_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -791,6 +824,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -844,6 +878,7 @@ CONFIG_JFFS2_ZLIB=y
 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
@@ -861,7 +896,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -923,6 +957,7 @@ CONFIG_FRAME_POINTER=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -937,7 +972,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -974,10 +1008,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=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1046,6 +1082,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1068,7 +1105,7 @@ 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
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7721_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7721_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7721_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7721_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:43:33 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:51:44 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +42,23 @@ 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_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=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
@@ -56,21 +66,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -78,6 +86,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 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
@@ -116,11 +125,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -155,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +201,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -303,7 +309,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -367,6 +372,7 @@ 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=y
 
 #
@@ -414,7 +420,6 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -422,6 +427,7 @@ CONFIG_WIRELESS=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -446,6 +452,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -513,6 +520,11 @@ CONFIG_MTD_CFI_UTIL=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
@@ -527,9 +539,13 @@ CONFIG_BLK_DEV=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -572,6 +588,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
@@ -580,6 +597,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # 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
@@ -595,7 +613,10 @@ CONFIG_NETDEV_10000=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
@@ -805,7 +826,9 @@ 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_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -823,18 +846,17 @@ 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=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
@@ -870,7 +892,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
@@ -880,6 +901,11 @@ 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_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -897,9 +923,14 @@ CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT 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_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -924,6 +955,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -980,6 +1012,7 @@ CONFIG_JFFS2_ZLIB=y
 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
@@ -1082,6 +1115,7 @@ CONFIG_FRAME_POINTER=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1096,7 +1130,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1133,10 +1166,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=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1205,6 +1240,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1227,7 +1263,7 @@ 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
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7722_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7722_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7722_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7722_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:46:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:55:10 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,19 +46,33 @@ 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_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=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_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ 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
@@ -78,6 +92,7 @@ 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
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 CONFIG_CPU_SUBTYPE_SH7722=y
@@ -213,11 +225,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -246,6 +259,7 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -321,7 +335,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -373,6 +386,7 @@ 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
 
@@ -385,13 +399,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -422,9 +436,13 @@ 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -470,6 +488,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG 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
@@ -478,6 +497,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # 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
@@ -490,8 +510,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# 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
@@ -508,7 +530,10 @@ CONFIG_NETDEV_10000=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
@@ -589,6 +614,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -680,9 +706,13 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -725,6 +755,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -748,6 +779,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -791,6 +823,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -843,7 +876,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -936,6 +969,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -956,7 +990,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=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.29-gnu1/arch/sh/configs/se7750_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7750_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7750_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7750_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:49:22 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:57:31 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,11 +43,20 @@ 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_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=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -63,10 +74,8 @@ CONFIG_KALLSYMS=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
@@ -74,6 +83,7 @@ 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
@@ -112,11 +122,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -151,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7750=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -355,6 +361,7 @@ 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
 
@@ -367,13 +374,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -392,6 +399,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -459,6 +467,11 @@ CONFIG_MTD_ROM=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
@@ -472,9 +485,13 @@ CONFIG_BLK_DEV=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -538,9 +555,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC 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
@@ -553,8 +572,10 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X 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
@@ -571,7 +592,10 @@ CONFIG_NETDEV_10000=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
@@ -622,6 +646,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -711,15 +736,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -735,6 +765,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -789,6 +820,7 @@ 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
@@ -806,7 +838,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -859,7 +890,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -951,6 +981,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -973,7 +1004,7 @@ 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
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7751_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7751_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7751_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7751_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:51:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:59:59 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,18 +43,32 @@ 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_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=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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -63,10 +78,8 @@ CONFIG_KALLSYMS=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
@@ -74,6 +87,7 @@ 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
@@ -112,11 +126,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -151,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -301,7 +312,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +386,7 @@ CONFIG_IP_NF_QUEUE=y
 # 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
 
@@ -388,13 +399,13 @@ CONFIG_IP_NF_QUEUE=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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -413,6 +424,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -480,6 +492,11 @@ CONFIG_MTD_RAM=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
@@ -496,9 +513,13 @@ 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -512,6 +533,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
@@ -524,8 +546,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -542,7 +566,10 @@ CONFIG_NETDEV_10000=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
@@ -585,6 +612,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -673,15 +701,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -699,6 +732,7 @@ CONFIG_EXT2_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -753,6 +787,7 @@ 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
@@ -802,7 +837,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -894,6 +928,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -916,7 +951,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/se7780_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/se7780_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/se7780_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/se7780_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:53:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:02:05 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,6 +42,15 @@ CONFIG_SYSVIPC_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
@@ -52,6 +62,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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
@@ -60,10 +71,8 @@ CONFIG_SYSCTL_SYSCALL=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 is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -72,6 +81,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -108,11 +118,6 @@ 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_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_FREEZER is not set
 
 #
@@ -148,6 +153,7 @@ CONFIG_CPU_SH4A=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -283,6 +290,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
 
 #
 # Executable file formats
@@ -296,7 +305,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +359,7 @@ CONFIG_IPV6=y
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -362,13 +371,13 @@ CONFIG_IPV6=y
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET 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
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 
 #
@@ -386,6 +395,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -460,6 +470,11 @@ CONFIG_MTD_ROM=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
@@ -479,10 +494,14 @@ CONFIG_BLK_DEV_LOOP=y
 # 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_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -536,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -557,6 +577,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -565,6 +586,7 @@ CONFIG_SATA_PMP=y
 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
@@ -619,6 +641,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -654,8 +677,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -693,7 +718,10 @@ CONFIG_NET_PCI=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
@@ -885,6 +913,7 @@ CONFIG_FB_SH_MOBILE_LCDC=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
 
 #
@@ -978,6 +1007,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -996,18 +1026,17 @@ 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=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
@@ -1043,7 +1072,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
@@ -1055,6 +1083,11 @@ 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_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1062,6 +1095,7 @@ CONFIG_USB_STORAGE=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -1120,6 +1154,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_JFFS2_FS 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
@@ -1214,7 +1249,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1301,6 +1336,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1323,7 +1359,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=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.29-gnu1/arch/sh/configs/sh03_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sh03_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sh03_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sh03_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:56:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:04:59 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,18 +45,32 @@ 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_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=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_INITRAMFS_COMPRESSION_NONE=y
 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
@@ -65,10 +80,8 @@ 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
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -119,11 +133,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -158,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -199,11 +209,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -294,6 +305,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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 is not set
 CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -318,7 +331,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -375,6 +387,7 @@ 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
 
@@ -382,18 +395,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET 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
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -430,12 +444,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -541,6 +559,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -562,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -577,6 +597,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -594,8 +615,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -646,6 +669,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -664,6 +688,7 @@ 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
 
 #
@@ -671,7 +696,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -754,6 +782,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -872,9 +901,13 @@ 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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -883,6 +916,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -908,6 +942,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -957,6 +992,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -981,7 +1017,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1081,7 +1116,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1110,10 +1145,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
@@ -1182,6 +1219,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1205,7 +1243,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/sh7710voipgw_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sh7710voipgw_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sh7710voipgw_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sh7710voipgw_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:00:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:09:01 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +42,23 @@ CONFIG_POSIX_MQUEUE=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 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
@@ -56,6 +66,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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 is not set
@@ -65,10 +76,8 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 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
@@ -114,11 +124,6 @@ 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_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_FREEZER is not set
 
 #
@@ -153,6 +158,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -194,11 +200,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -369,6 +375,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -418,13 +425,13 @@ CONFIG_NET_SCH_FIFO=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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -447,6 +454,7 @@ 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -514,6 +522,11 @@ CONFIG_MTD_RAM=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
@@ -527,9 +540,13 @@ CONFIG_BLK_DEV=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -543,6 +560,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
@@ -556,8 +574,10 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_STNIC is not set
 # CONFIG_SH_ETH is not set
 # CONFIG_SMC91X 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
@@ -574,7 +594,10 @@ CONFIG_NETDEV_10000=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
@@ -640,6 +663,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -718,15 +742,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -742,6 +771,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -795,6 +825,7 @@ 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
@@ -844,7 +875,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -936,6 +967,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -961,3 +993,4 @@ 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.29-gnu1/arch/sh/configs/sh7763rdp_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sh7763rdp_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sh7763rdp_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sh7763rdp_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:02:28 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:10:57 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,15 +42,24 @@ CONFIG_SYSVIPC_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_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
@@ -58,9 +68,11 @@ CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 # 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=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -70,10 +82,8 @@ 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
@@ -81,6 +91,7 @@ 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
@@ -122,11 +133,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -162,6 +168,7 @@ CONFIG_CPU_SUBTYPE_SH7763=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -207,11 +214,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -231,6 +239,7 @@ CONFIG_CPU_HAS_FPU=y
 # Board support
 #
 CONFIG_SH_SH7763RDP=y
+# CONFIG_SH_ESPT is not set
 
 #
 # Timer and clock configuration
@@ -311,8 +320,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -367,6 +374,7 @@ 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
 
@@ -374,12 +382,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -387,6 +395,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -409,6 +418,7 @@ 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
@@ -462,9 +472,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -485,6 +493,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
@@ -544,9 +557,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC 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
@@ -579,8 +594,10 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 CONFIG_SH_ETH=y
 # CONFIG_SMC91X 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
@@ -597,7 +614,10 @@ CONFIG_SH_ETH=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
@@ -677,6 +697,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -756,6 +777,7 @@ CONFIG_FB_SH7760=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
 
 #
@@ -807,7 +829,9 @@ 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_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -825,18 +849,17 @@ 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=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
@@ -872,7 +895,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
@@ -882,6 +904,11 @@ 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_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -903,6 +930,7 @@ CONFIG_MMC_BLOCK_BOUNCE=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
 # CONFIG_STAGING is not set
 
@@ -926,6 +954,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -974,6 +1003,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -991,7 +1021,6 @@ CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=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
@@ -1075,7 +1104,7 @@ CONFIG_TRACING=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1167,6 +1196,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1187,7 +1217,7 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sh7785lcr_32bit_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1561 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:12:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=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=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_IO_TRAPPED=y
+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=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_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 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
+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=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=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 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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x20000000
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
+# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=2
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+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_ENTRY_OFFSET=0x00001000
+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
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_HIGHLANDER is not set
+CONFIG_SH_SH7785LCR=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_SH_PCLK_FREQ=50000000
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# 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_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
+# 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
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE 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=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_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_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=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 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_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_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_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 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_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 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=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 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
+
+#
+# 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=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=y
+# 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
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O 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_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+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_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_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
+
+#
+# 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=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=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_SUNKBD is not set
+# 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_SH_KEYSC 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
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+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=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM 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_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOPCA=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_OCORES is not set
+# CONFIG_I2C_SH_MOBILE 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=y
+# CONFIG_I2C_STUB is not set
+
+#
+# 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
+# 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=y
+# 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_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
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
+# 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_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_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_SH_MOBILE_LCDC=m
+CONFIG_FB_SM501=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=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=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+# CONFIG_LOGO_SUPERH_CLUT224 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 is not set
+
+#
+# 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_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_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+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=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=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=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_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=y
+# 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 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 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=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=y
+# 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
+
+#
+# SPI RTC drivers
+#
+
+#
+# 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_SH 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 is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+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=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 is not set
+# CONFIG_FUSE_FS 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=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# 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_HUGETLBFS 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 is not set
+# CONFIG_CRAMFS is not set
+# 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_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=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 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=y
+# 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_TRACE_IRQFLAGS_SUPPORT=y
+# 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 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_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_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 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 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_FRAME_POINTER 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=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=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_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_SAMPLES is not set
+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_DEBUG_BOOTMEM is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_DUMP_CODE is not set
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS 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_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 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 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 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/sh7785lcr_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/sh7785lcr_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/sh7785lcr_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/sh7785lcr_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:05:18 2009
+# Linux kernel version: 2.6.30-rc2
+# Wed Apr 22 19:17:56 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
 CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
@@ -17,7 +18,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +27,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -46,15 +48,24 @@ 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_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=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
@@ -62,20 +73,20 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # 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_STRIP_ASM_SYMS is not set
 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
@@ -84,10 +95,12 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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=y
+# CONFIG_MARKERS is not set
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -96,6 +109,8 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
+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
@@ -108,7 +123,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -124,11 +138,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -161,16 +170,16 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7760 is not set
 # CONFIG_CPU_SUBTYPE_SH4_202 is not set
 # CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
 # CONFIG_CPU_SUBTYPE_SH7763 is not set
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
 # CONFIG_CPU_SUBTYPE_SH7366 is not set
-# CONFIG_CPU_SUBTYPE_SH5_101 is not set
-# CONFIG_CPU_SUBTYPE_SH5_103 is not set
 
 #
 # Memory management options
@@ -181,43 +190,40 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB is not set
+# CONFIG_PMB_ENABLE is not set
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
-CONFIG_MAX_ACTIVE_REGIONS=2
+CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 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_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
-CONFIG_SPARSEMEM_MANUAL=y
-CONFIG_SPARSEMEM=y
-CONFIG_HAVE_MEMORY_PRESENT=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_MEMORY_HOTPLUG is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -307,6 +313,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -328,7 +336,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -388,6 +395,7 @@ 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
 
@@ -400,7 +408,6 @@ 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 is not set
@@ -408,6 +415,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -430,6 +438,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -477,9 +486,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -502,6 +509,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # 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
@@ -565,6 +577,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
@@ -639,6 +652,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -655,6 +669,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
@@ -668,6 +683,7 @@ CONFIG_R8169=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
@@ -677,7 +693,10 @@ CONFIG_R8169=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
@@ -772,6 +791,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -834,12 +854,9 @@ CONFIG_I2C_PCA_PLATFORM=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
@@ -871,6 +888,7 @@ CONFIG_MFD_SM501=y
 # 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
 # CONFIG_REGULATOR is not set
 
 #
@@ -948,6 +966,7 @@ CONFIG_FB_SM501=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
 
 #
@@ -988,15 +1007,17 @@ 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_DRAGONRISE_FF 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
@@ -1041,6 +1062,7 @@ 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_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
@@ -1062,18 +1084,17 @@ CONFIG_USB_R8A66597_HCD=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
@@ -1109,7 +1130,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
@@ -1121,6 +1141,11 @@ CONFIG_USB_TEST=m
 # 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
@@ -1182,6 +1207,7 @@ CONFIG_RTC_DRV_RS5C372=y
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1192,6 +1218,7 @@ 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
@@ -1204,6 +1231,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1213,6 +1241,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
@@ -1253,6 +1286,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=y
 # CONFIG_OMFS_FS is not set
@@ -1261,6 +1295,7 @@ CONFIG_MINIX_FS=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
@@ -1277,7 +1312,6 @@ CONFIG_EXPORTFS=y
 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
@@ -1350,6 +1384,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
@@ -1382,9 +1419,11 @@ CONFIG_DEBUG_PREEMPT=y
 # 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_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1394,10 +1433,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # 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_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
@@ -1433,10 +1476,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
@@ -1505,6 +1550,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1512,6 +1558,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1525,7 +1572,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/shmin_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/shmin_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/shmin_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/shmin_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:09:00 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:19:03 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -39,15 +40,25 @@ CONFIG_LOCALVERSION_AUTO=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 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_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 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -56,10 +67,8 @@ CONFIG_EMBEDDED=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -67,6 +76,7 @@ CONFIG_EVENTFD=y
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -97,11 +107,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -136,6 +141,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -177,11 +183,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -267,7 +274,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 ro
 # 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
 
@@ -281,7 +287,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
@@ -335,6 +340,7 @@ 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
 
@@ -347,13 +353,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -419,9 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -442,6 +446,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # 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
@@ -456,9 +465,13 @@ CONFIG_BLK_DEV_LOOP=y
 # 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -472,6 +485,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
@@ -484,8 +498,10 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -502,7 +518,10 @@ CONFIG_NETDEV_10000=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
@@ -549,6 +568,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -618,15 +638,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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,6 +666,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_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
@@ -683,6 +709,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS 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
@@ -702,7 +729,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
@@ -740,7 +766,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -831,6 +856,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -855,3 +881,4 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/shx3_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/shx3_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/shx3_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/shx3_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:10:57 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:20:54 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -19,7 +19,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 CONFIG_GENERIC_LOCKBREAK=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -27,6 +27,7 @@ CONFIG_LOCKDEP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -47,24 +48,35 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 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=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 # CONFIG_CPUSETS is not set
-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_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
@@ -73,24 +85,23 @@ CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS 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=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 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
@@ -98,6 +109,7 @@ CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -142,12 +154,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 CONFIG_FREEZER=y
 
 #
@@ -184,6 +190,7 @@ CONFIG_CPU_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 CONFIG_CPU_SUBTYPE_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -240,11 +247,12 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -361,8 +369,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 CONFIG_XFRM=y
@@ -434,6 +440,7 @@ 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_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -442,6 +449,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 #
 # 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=m
 CONFIG_CAN_RAW=m
@@ -455,8 +463,8 @@ CONFIG_CAN_VCAN=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_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -490,10 +498,18 @@ 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_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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG 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
@@ -547,6 +564,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # 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
@@ -560,8 +578,10 @@ CONFIG_MII=y
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
 # 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
@@ -578,7 +598,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
+#
 
 #
 # USB Network Adapters
@@ -670,12 +693,9 @@ CONFIG_I2C_HELPER_AUTO=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
@@ -695,7 +715,6 @@ CONFIG_SPI_MASTER=y
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -732,6 +751,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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_REGULATOR is not set
 
 #
@@ -788,7 +808,9 @@ 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_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=m
 # CONFIG_USB_HWA_HCD is not set
@@ -803,11 +825,11 @@ CONFIG_USB_R8A66597_HCD=m
 # 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 is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -837,7 +859,6 @@ CONFIG_USB_R8A66597_HCD=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
@@ -860,10 +881,12 @@ CONFIG_USB_GADGET_SELECTED=y
 # 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=y
 CONFIG_USB_M66592=y
 # 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
@@ -876,6 +899,11 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # 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_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -942,6 +970,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=m
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
@@ -969,6 +998,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -1012,6 +1042,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -1086,6 +1117,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION 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
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1105,7 +1137,7 @@ CONFIG_TRACING=y
 # 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_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1205,6 +1237,7 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1226,7 +1259,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_AUDIT_GENERIC=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.29-gnu1/arch/sh/configs/snapgear_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/snapgear_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/snapgear_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/snapgear_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:14:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:21:39 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,18 +42,32 @@ CONFIG_LOCALVERSION_AUTO=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 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_INITRAMFS_COMPRESSION_NONE=y
 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
@@ -62,10 +77,8 @@ CONFIG_KALLSYMS=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
@@ -74,6 +87,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -187,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -239,6 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -288,6 +300,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
 
 #
 # Executable file formats
@@ -307,7 +321,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 # CONFIG_NET_KEY is not set
@@ -352,6 +365,7 @@ 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
 
@@ -364,13 +378,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 is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -464,6 +478,11 @@ CONFIG_MTD_PLATRAM=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
@@ -509,6 +528,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -526,8 +546,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -571,7 +593,10 @@ CONFIG_8139TOO_PIO=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_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -711,6 +736,7 @@ CONFIG_SSB_POSSIBLE=y
 # 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
 # CONFIG_STAGING is not set
 
@@ -728,6 +754,7 @@ CONFIG_EXT2_FS=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_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
@@ -771,6 +798,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS 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
@@ -820,7 +848,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -849,7 +876,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/systemh_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/systemh_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/systemh_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/systemh_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:15:56 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:23:31 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -38,18 +39,32 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT 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=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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -59,10 +74,8 @@ CONFIG_KALLSYMS=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
@@ -70,6 +83,7 @@ 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
@@ -109,11 +123,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -148,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -189,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -318,9 +329,13 @@ CONFIG_BLK_DEV_RAM_SIZE=1024
 # CONFIG_CDROM_PKTCDVD 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -372,6 +387,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # 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
@@ -452,15 +468,20 @@ CONFIG_USB_ARCH_HAS_HCD=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
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # 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
 
@@ -475,6 +496,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -518,6 +540,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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 is not set
 # CONFIG_OMFS_FS is not set
@@ -558,7 +581,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -587,7 +609,7 @@ 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
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/titan_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/titan_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/titan_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/titan_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:17:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:24:55 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,19 +43,33 @@ CONFIG_POSIX_MQUEUE=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=16
-# 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_INITRAMFS_COMPRESSION_NONE=y
 # 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
@@ -65,10 +80,8 @@ 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
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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
@@ -116,11 +130,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -155,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -248,6 +259,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -299,6 +311,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=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
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -323,7 +337,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -406,6 +419,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -418,6 +432,7 @@ CONFIG_NETFILTER_XT_MATCH_DCCP=m
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+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
@@ -475,11 +490,11 @@ CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 # CONFIG_IP6_NF_MATCH_MH is not set
 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
 # CONFIG_BRIDGE_NF_EBTABLES is not set
 # CONFIG_IP_DCCP is not set
@@ -500,6 +515,7 @@ CONFIG_LLC=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -565,7 +581,6 @@ CONFIG_NET_SCH_FIFO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -574,6 +589,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -599,6 +615,7 @@ CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
 # CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
 
 #
 # User Modules And Translation Layers
@@ -675,6 +692,11 @@ CONFIG_MTD_NAND_IDS=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
@@ -698,12 +720,16 @@ CONFIG_ATA_OVER_ETH=m
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -760,6 +786,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -781,6 +808,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP 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
@@ -796,6 +824,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -832,8 +861,10 @@ CONFIG_MII=y
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X 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
@@ -888,6 +919,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -906,6 +938,7 @@ 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
 
 #
@@ -913,7 +946,10 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -1025,6 +1061,7 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1174,6 +1211,7 @@ CONFIG_USB_MON=y
 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_OHCI_HCD=y
@@ -1195,18 +1233,17 @@ CONFIG_USB_PRINTER=m
 # 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
@@ -1235,7 +1272,7 @@ CONFIG_USB_SERIAL_ARK3116=m
 # 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_CP2101 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
@@ -1259,15 +1296,19 @@ CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # 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
 
 #
@@ -1284,7 +1325,6 @@ CONFIG_USB_SERIAL_PL2303=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
@@ -1296,6 +1336,11 @@ CONFIG_USB_SERIAL_PL2303=m
 # 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
@@ -1337,6 +1382,7 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SH=m
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1363,6 +1409,7 @@ 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1413,6 +1460,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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
@@ -1436,7 +1484,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=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=m
@@ -1559,6 +1606,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT 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_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1573,7 +1621,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1610,10 +1657,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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1683,6 +1732,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1706,11 +1756,12 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=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.29-gnu1/arch/sh/configs/ul2_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/ul2_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/ul2_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/ul2_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:22:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:30:27 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,19 +46,33 @@ 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_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=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_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ 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
@@ -78,6 +92,7 @@ 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
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-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_FREEZER is not set
 
 #
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -213,11 +225,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,6 +256,7 @@ CONFIG_CPU_HAS_DSP=y
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -319,7 +333,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -374,6 +387,7 @@ 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
 
@@ -386,15 +400,14 @@ 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=y
 # CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
 # 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=y
 
 #
@@ -408,6 +421,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
 # 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
 
@@ -430,6 +444,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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 is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -497,6 +512,11 @@ CONFIG_MTD_RAM=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
@@ -514,9 +534,13 @@ 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_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -562,6 +586,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG 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
@@ -570,6 +595,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_PLATFORM=y
 # 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
@@ -582,8 +608,10 @@ CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X 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
@@ -605,12 +633,13 @@ CONFIG_LIBERTAS=m
 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_IWLWIFI_LEDS is not set
+# CONFIG_AR9170_USB is not set
 # CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
@@ -618,6 +647,10 @@ CONFIG_LIBERTAS_DEBUG=y
 # CONFIG_RT2X00 is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -794,7 +827,9 @@ 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_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_SUPERH_ON_CHIP_R8A66597 is not set
@@ -809,18 +844,17 @@ CONFIG_USB_R8A66597_HCD=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
@@ -856,7 +890,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
@@ -866,6 +899,11 @@ 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_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -887,6 +925,7 @@ CONFIG_MMC_BLOCK_BOUNCE=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
 # CONFIG_STAGING is not set
 
@@ -909,6 +948,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -956,6 +996,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS 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
@@ -976,7 +1017,6 @@ CONFIG_LOCKD=y
 CONFIG_EXPORTFS=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
@@ -1059,7 +1099,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1087,10 +1126,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
@@ -1159,6 +1200,7 @@ CONFIG_CRYPTO_ARC4=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1180,7 +1222,8 @@ 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_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/configs/urquell_defconfig linux-libre-2.6.30-gnu1/arch/sh/configs/urquell_defconfig
--- linux-libre-2.6.29-gnu1/arch/sh/configs/urquell_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/configs/urquell_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1341 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:33:39 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+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=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_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 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_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
+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_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=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 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_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+CONFIG_CPU_SUBTYPE_SH7786=y
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+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_ENTRY_OFFSET=0x00001000
+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
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+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_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEAEX=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_URQUELL=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# 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_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1, 38400 earlyprintk=serial ip=on ignore_loglevel root=/dev/nfs ip=dhcp memchunk.vpu=4m"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE 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=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_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_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=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 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_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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 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_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_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=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 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
+
+#
+# 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=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM 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_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SMC91X=y
+# 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
+#
+
+#
+# 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=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=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_SUNKBD is not set
+# 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_SH_KEYSC 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_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_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=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_CHARDEV is not set
+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_SH_MOBILE 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_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
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# 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_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=y
+# CONFIG_MFD_SM501_GPIO 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_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
+
+#
+# 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=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
+# 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_SH_MOBILE_LCDC=m
+CONFIG_FB_SM501=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=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=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+# CONFIG_LOGO_SUPERH_CLUT224 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 is not set
+
+#
+# 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_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_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+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=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=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_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
+
+#
+# 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_CLASS 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 is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+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=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS 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 is not set
+# CONFIG_FUSE_FS 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=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# 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_HUGETLBFS 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 is not set
+# CONFIG_CRAMFS is not set
+# 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_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=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 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=y
+# 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_TRACE_IRQFLAGS_SUPPORT=y
+# 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 is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# 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_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# 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_MORE_COMPILE_OPTIONS 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_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 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 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 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/dma-sh.c linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/dma-sh.c
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/dma-sh.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/dma-sh.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,28 +17,16 @@
 #include <mach-dreamcast/mach/dma.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-#include "dma-sh.h"
+#include <asm/dma-sh.h>
 
-static int dmte_irq_map[] = {
-	DMTE0_IRQ,
-	DMTE1_IRQ,
-	DMTE2_IRQ,
-	DMTE3_IRQ,
-#if defined(CONFIG_CPU_SUBTYPE_SH7720)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7721)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7709)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7780)
-	DMTE4_IRQ,
-	DMTE5_IRQ,
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7780)
-	DMTE6_IRQ,
-	DMTE7_IRQ,
+#if defined(DMAE1_IRQ)
+#define NR_DMAE		2
+#else
+#define NR_DMAE		1
 #endif
+
+static const char *dmae_name[] = {
+	"DMAC Address Error0", "DMAC Address Error1"
 };
 
 static inline unsigned int get_dmte_irq(unsigned int chan)
@@ -46,7 +34,14 @@ static inline unsigned int get_dmte_irq(
 	unsigned int irq = 0;
 	if (chan < ARRAY_SIZE(dmte_irq_map))
 		irq = dmte_irq_map[chan];
+
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+	if (irq > DMTE6_IRQ)
+		return DMTE6_IRQ;
+	return DMTE0_IRQ;
+#else
 	return irq;
+#endif
 }
 
 /*
@@ -59,7 +54,7 @@ static inline unsigned int get_dmte_irq(
  */
 static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
 {
-	u32 chcr = ctrl_inl(CHCR[chan->chan]);
+	u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 
 	return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
 }
@@ -75,13 +70,13 @@ static irqreturn_t dma_tei(int irq, void
 	struct dma_channel *chan = dev_id;
 	u32 chcr;
 
-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 
 	if (!(chcr & CHCR_TE))
 		return IRQ_NONE;
 
 	chcr &= ~(CHCR_IE | CHCR_DE);
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	wake_up(&chan->wait_queue);
 
@@ -94,7 +89,12 @@ static int sh_dmac_request_dma(struct dm
 		return 0;
 
 	return request_irq(get_dmte_irq(chan->chan), dma_tei,
-			   IRQF_DISABLED, chan->dev_id, chan);
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+				IRQF_SHARED,
+#else
+				IRQF_DISABLED,
+#endif
+				chan->dev_id, chan);
 }
 
 static void sh_dmac_free_dma(struct dma_channel *chan)
@@ -115,7 +115,7 @@ sh_dmac_configure_channel(struct dma_cha
 		chan->flags &= ~DMA_TEI_CAPABLE;
 	}
 
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	chan->flags |= DMA_CONFIGURED;
 	return 0;
@@ -126,13 +126,13 @@ static void sh_dmac_enable_dma(struct dm
 	int irq;
 	u32 chcr;
 
-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 	chcr |= CHCR_DE;
 
 	if (chan->flags & DMA_TEI_CAPABLE)
 		chcr |= CHCR_IE;
 
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
 
 	if (chan->flags & DMA_TEI_CAPABLE) {
 		irq = get_dmte_irq(chan->chan);
@@ -150,9 +150,9 @@ static void sh_dmac_disable_dma(struct d
 		disable_irq(irq);
 	}
 
-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
 }
 
 static int sh_dmac_xfer_dma(struct dma_channel *chan)
@@ -183,12 +183,13 @@ static int sh_dmac_xfer_dma(struct dma_c
 	 */
 	if (chan->sar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->sar, SAR[chan->chan]);
+		ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR));
 	if (chan->dar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->dar, DAR[chan->chan]);
+		ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR));
 
-	ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
+	ctrl_outl(chan->count >> calc_xmit_shift(chan),
+		(dma_base_addr[chan->chan] + TCR));
 
 	sh_dmac_enable_dma(chan);
 
@@ -197,36 +198,26 @@ static int sh_dmac_xfer_dma(struct dma_c
 
 static int sh_dmac_get_dma_residue(struct dma_channel *chan)
 {
-	if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
+	if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
 		return 0;
 
-	return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
+	return ctrl_inl(dma_base_addr[chan->chan] + TCR)
+		 << calc_xmit_shift(chan);
 }
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7780) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define dmaor_read_reg()	ctrl_inw(DMAOR)
-#define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
-#else
-#define dmaor_read_reg()	ctrl_inl(DMAOR)
-#define dmaor_write_reg(data)	ctrl_outl(data, DMAOR)
-#endif
-
-static inline int dmaor_reset(void)
+static inline int dmaor_reset(int no)
 {
-	unsigned long dmaor = dmaor_read_reg();
+	unsigned long dmaor = dmaor_read_reg(no);
 
 	/* Try to clear the error flags first, incase they are set */
 	dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
-	dmaor_write_reg(dmaor);
+	dmaor_write_reg(no, dmaor);
 
 	dmaor |= DMAOR_INIT;
-	dmaor_write_reg(dmaor);
+	dmaor_write_reg(no, dmaor);
 
 	/* See if we got an error again */
-	if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) {
+	if ((dmaor_read_reg(no) & (DMAOR_AE | DMAOR_NMIF))) {
 		printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
 		return -EINVAL;
 	}
@@ -237,10 +228,33 @@ static inline int dmaor_reset(void)
 #if defined(CONFIG_CPU_SH4)
 static irqreturn_t dma_err(int irq, void *dummy)
 {
-	dmaor_reset();
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+	int cnt = 0;
+	switch (irq) {
+#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
+	case DMTE6_IRQ:
+		cnt++;
+#endif
+	case DMTE0_IRQ:
+		if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) {
+			disable_irq(irq);
+			/* DMA multi and error IRQ */
+			return IRQ_HANDLED;
+		}
+	default:
+		return IRQ_NONE;
+	}
+#else
+	dmaor_reset(0);
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7785)
+	dmaor_reset(1);
+#endif
 	disable_irq(irq);
 
 	return IRQ_HANDLED;
+#endif
 }
 #endif
 
@@ -259,24 +273,59 @@ static struct dma_info sh_dmac_info = {
 	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
 };
 
+#ifdef CONFIG_CPU_SH4
+static unsigned int get_dma_error_irq(int n)
+{
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+	return (n == 0) ? get_dmte_irq(0) : get_dmte_irq(6);
+#else
+	return (n == 0) ? DMAE0_IRQ :
+#if defined(DMAE1_IRQ)
+				DMAE1_IRQ;
+#else
+				-1;
+#endif
+#endif
+}
+#endif
+
 static int __init sh_dmac_init(void)
 {
 	struct dma_info *info = &sh_dmac_info;
 	int i;
 
 #ifdef CONFIG_CPU_SH4
-	i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
-	if (unlikely(i < 0))
-		return i;
+	int n;
+
+	for (n = 0; n < NR_DMAE; n++) {
+		i = request_irq(get_dma_error_irq(n), dma_err,
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+				IRQF_SHARED,
+#else
+				IRQF_DISABLED,
 #endif
+				dmae_name[n], (void *)dmae_name[n]);
+		if (unlikely(i < 0)) {
+			printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]);
+			return i;
+		}
+	}
+#endif /* CONFIG_CPU_SH4 */
 
 	/*
 	 * Initialize DMAOR, and clean up any error flags that may have
 	 * been set.
 	 */
-	i = dmaor_reset();
+	i = dmaor_reset(0);
+	if (unlikely(i != 0))
+		return i;
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7785)
+	i = dmaor_reset(1);
 	if (unlikely(i != 0))
 		return i;
+#endif
 
 	return register_dmac(info);
 }
@@ -284,8 +333,12 @@ static int __init sh_dmac_init(void)
 static void __exit sh_dmac_exit(void)
 {
 #ifdef CONFIG_CPU_SH4
-	free_irq(DMAE_IRQ, 0);
-#endif
+	int n;
+
+	for (n = 0; n < NR_DMAE; n++) {
+		free_irq(get_dma_error_irq(n), (void *)dmae_name[n]);
+	}
+#endif /* CONFIG_CPU_SH4 */
 	unregister_dmac(&sh_dmac_info);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/dma-sh.h linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/dma-sh.h
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/dma-sh.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/dma-sh.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/*
- * arch/sh/drivers/dma/dma-sh.h
- *
- * Copyright (C) 2000  Takashi YOSHII
- * Copyright (C) 2003  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.
- */
-#ifndef __DMA_SH_H
-#define __DMA_SH_H
-
-#include <cpu/dma.h>
-
-/* Definitions for the SuperH DMAC */
-#define REQ_L	0x00000000
-#define REQ_E	0x00080000
-#define RACK_H	0x00000000
-#define RACK_L	0x00040000
-#define ACK_R	0x00000000
-#define ACK_W	0x00020000
-#define ACK_H	0x00000000
-#define ACK_L	0x00010000
-#define DM_INC	0x00004000
-#define DM_DEC	0x00008000
-#define SM_INC	0x00001000
-#define SM_DEC	0x00002000
-#define RS_IN	0x00000200
-#define RS_OUT	0x00000300
-#define TS_BLK	0x00000040
-#define TM_BUR	0x00000020
-#define CHCR_DE 0x00000001
-#define CHCR_TE 0x00000002
-#define CHCR_IE 0x00000004
-
-/* DMAOR definitions */
-#define DMAOR_AE	0x00000004
-#define DMAOR_NMIF	0x00000002
-#define DMAOR_DME	0x00000001
-
-/*
- * Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- */
-#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
-
-#define MAX_DMAC_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
-
-/*
- * Subtypes that have fewer channels than this simply need to change
- * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number
- * of channels should expand on this.
- *
- * For most subtypes we can easily figure these values out with some
- * basic calculation, unfortunately on other subtypes these are more
- * scattered, so we just leave it unrolled for simplicity.
- */
-#define SAR	((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
-				   SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \
-				   SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60})
-#define DAR	((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
-				   SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \
-				   SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64})
-#define DMATCR	((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
-				   SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \
-				   SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68})
-#define CHCR	((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
-				   SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \
-				   SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c})
-
-#define DMAOR	(SH_DMAC_BASE + 0x40)
-
-#endif /* __DMA_SH_H */
-
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/Kconfig linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -9,16 +9,28 @@ config SH_DMA
 	select SH_DMA_API
 	default n
 
+config SH_DMA_IRQ_MULTI
+	bool
+	depends on SH_DMA
+	default y if CPU_SUBTYPE_SH7750  || CPU_SUBTYPE_SH7751  || \
+		     CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
+		     CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091  || \
+		     CPU_SUBTYPE_SH7763  || CPU_SUBTYPE_SH7764  || \
+		     CPU_SUBTYPE_SH7780  || CPU_SUBTYPE_SH7785
+
 config NR_ONCHIP_DMA_CHANNELS
 	int
 	depends on SH_DMA
-	default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
-	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
-	default "12" if CPU_SUBTYPE_SH7780
-	default "4"
+	default "4" if CPU_SUBTYPE_SH7750  || CPU_SUBTYPE_SH7751  || \
+		       CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
+		       CPU_SUBTYPE_SH7760
+	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780  || \
+			CPU_SUBTYPE_SH7785
+	default "6"
 	help
 	  This allows you to specify the number of channels that the on-chip
-	  DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
+	  DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
 	  SH7750R/SH7751R.
 
 config NR_DMA_CHANNELS_BOOL
@@ -46,4 +58,28 @@ config SH_DMABRG
 	  of the SH7760.
 	  Say Y if you want to use Audio/USB DMA on your SH7760 board.
 
+config PVR2_DMA
+	tristate "PowerVR 2 DMAC support"
+	depends on SH_DREAMCAST && SH_DMA
+	help
+	  Selecting this will enable support for the PVR2 DMA controller.
+	  As this chains off of the on-chip DMAC, that must also be
+	  enabled by default.
+
+	  This is primarily used by the pvr2fb framebuffer driver for
+	  certain optimizations, but is not necessary for functionality.
+
+	  If in doubt, say N.
+
+config G2_DMA
+	tristate "G2 Bus DMA support"
+	depends on SH_DREAMCAST
+	select SH_DMA_API
+	help
+	  This enables support for the DMA controller for the Dreamcast's
+	  G2 bus. Drivers that want this will generally enable this on
+	  their own.
+
+	  If in doubt, say N.
+
 endmenu
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/Makefile linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/dma/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/dma/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_SH_DMA_API)	+= dma-api.o dma-sysfs.o
 obj-$(CONFIG_SH_DMA)		+= dma-sh.o
-obj-$(CONFIG_SH_DREAMCAST)	+= dma-pvr2.o dma-g2.o
+obj-$(CONFIG_PVR2_DMA)		+= dma-pvr2.o
+obj-$(CONFIG_G2_DMA)		+= dma-g2.o
 obj-$(CONFIG_SH_DMABRG)		+= dmabrg.o
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/ops-sh7785lcr.c linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/ops-sh7785lcr.c
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/ops-sh7785lcr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/ops-sh7785lcr.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,13 +48,13 @@ EXPORT_SYMBOL(board_pci_channels);
 
 static struct sh4_pci_address_map sh7785_pci_map = {
 	.window0	= {
-		.base	= SH7780_CS2_BASE_ADDR,
-		.size	= 0x04000000,
-	},
-
-	.window1	= {
-		.base	= SH7780_CS3_BASE_ADDR,
-		.size	= 0x04000000,
+#if defined(CONFIG_32BIT)
+		.base	= SH7780_32BIT_DDR_BASE_ADDR,
+		.size	= 0x40000000,
+#else
+		.base	= SH7780_CS0_BASE_ADDR,
+		.size	= 0x20000000,
+#endif
 	},
 
 	.flags	= SH4_PCIC_NO_RESET,
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci.c linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci.c
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/dma-debug.h>
 #include <asm/io.h>
 
 static int __init pcibios_init(void)
@@ -43,6 +44,8 @@ static int __init pcibios_init(void)
 
 	pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
 
+	dma_debug_add_bus(&pci_bus_type);
+
 	return 0;
 }
 subsys_initcall(pcibios_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci-sh7780.c linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci-sh7780.c
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci-sh7780.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci-sh7780.c	2009-06-09 23:05:27.000000000 -0400
@@ -120,19 +120,15 @@ int __init sh7780_pcic_init(struct sh4_p
 
 	/* Set IO and Mem windows to local address
 	 * Make PCI and local address the same for easy 1 to 1 mapping
-	 * Window0 = map->window0.size @ non-cached area base = SDRAM
-	 * Window1 = map->window1.size @ cached area base = SDRAM
 	 */
-	word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
-	pci_write_reg(word, SH4_PCILSR0);
-	pci_write_reg(0x00000001, SH4_PCILSR1);
+	pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0);
+	pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1);
 	/* Set the values on window 0 PCI config registers */
-	word = (CONFIG_MEMORY_SIZE > 0x08000000) ? 0x10000000 : 0x08000000;
-	pci_write_reg(word | 0xa0000000, SH4_PCILAR0);
-	pci_write_reg(word, SH7780_PCIMBAR0);
+	pci_write_reg(map->window0.base, SH4_PCILAR0);
+	pci_write_reg(map->window0.base, SH7780_PCIMBAR0);
 	/* Set the values on window 1 PCI config registers */
-	pci_write_reg(0x00000000, SH4_PCILAR1);
-	pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+	pci_write_reg(map->window1.base, SH4_PCILAR1);
+	pci_write_reg(map->window1.base, SH7780_PCIMBAR1);
 
 	/* Map IO space into PCI IO window
 	 * The IO window is 64K-PCIBIOS_MIN_IO in size
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci-sh7780.h linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci-sh7780.h
--- linux-libre-2.6.29-gnu1/arch/sh/drivers/pci/pci-sh7780.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/drivers/pci/pci-sh7780.h	2009-06-09 23:05:27.000000000 -0400
@@ -104,6 +104,8 @@
 #define SH7780_CS5_BASE_ADDR	(SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
 #define SH7780_CS6_BASE_ADDR	(SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
 
+#define SH7780_32BIT_DDR_BASE_ADDR	0x40000000
+
 struct sh4_pci_address_map;
 
 /* arch/sh/drivers/pci/pci-sh7780.c */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/addrspace.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/addrspace.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/addrspace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/addrspace.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@
 /* Returns the physical address of a PnSEG (n=1,2) address   */
 #define PHYSADDR(a)	(((unsigned long)(a)) & 0x1fffffff)
 
-#ifdef CONFIG_29BIT
+#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
 /*
  * Map an address to a certain privileged segment
  */
@@ -43,7 +43,7 @@
 	((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
 #define P4SEGADDR(a)	\
 	((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
-#endif /* 29BIT */
+#endif /* 29BIT || PMB_FIXED */
 #endif /* P1SEG */
 
 /* Check if an address can be reached in 29 bits */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/atomic-irq.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/atomic-irq.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/atomic-irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/atomic-irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,7 @@ static inline void atomic_add(int i, ato
 	unsigned long flags;
 
 	local_irq_save(flags);
-	*(long *)v += i;
+	v->counter += i;
 	local_irq_restore(flags);
 }
 
@@ -20,7 +20,7 @@ static inline void atomic_sub(int i, ato
 	unsigned long flags;
 
 	local_irq_save(flags);
-	*(long *)v -= i;
+	v->counter -= i;
 	local_irq_restore(flags);
 }
 
@@ -29,9 +29,9 @@ static inline int atomic_add_return(int
 	unsigned long temp, flags;
 
 	local_irq_save(flags);
-	temp = *(long *)v;
+	temp = v->counter;
 	temp += i;
-	*(long *)v = temp;
+	v->counter = temp;
 	local_irq_restore(flags);
 
 	return temp;
@@ -42,9 +42,9 @@ static inline int atomic_sub_return(int
 	unsigned long temp, flags;
 
 	local_irq_save(flags);
-	temp = *(long *)v;
+	temp = v->counter;
 	temp -= i;
-	*(long *)v = temp;
+	v->counter = temp;
 	local_irq_restore(flags);
 
 	return temp;
@@ -55,7 +55,7 @@ static inline void atomic_clear_mask(uns
 	unsigned long flags;
 
 	local_irq_save(flags);
-	*(long *)v &= ~mask;
+	v->counter &= ~mask;
 	local_irq_restore(flags);
 }
 
@@ -64,7 +64,7 @@ static inline void atomic_set_mask(unsig
 	unsigned long flags;
 
 	local_irq_save(flags);
-	*(long *)v |= mask;
+	v->counter |= mask;
 	local_irq_restore(flags);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/bitops-llsc.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/bitops-llsc.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/bitops-llsc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/bitops-llsc.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef __ASM_SH_BITOPS_LLSC_H
 #define __ASM_SH_BITOPS_LLSC_H
 
-static inline void set_bit(int nr, volatile void * addr)
+static inline void set_bit(int nr, volatile void *addr)
 {
 	int	mask;
 	volatile unsigned int *a = addr;
@@ -13,16 +13,16 @@ static inline void set_bit(int nr, volat
 	__asm__ __volatile__ (
 		"1:						\n\t"
 		"movli.l	@%1, %0	! set_bit		\n\t"
-		"or		%3, %0				\n\t"
+		"or		%2, %0				\n\t"
 		"movco.l	%0, @%1				\n\t"
 		"bf		1b				\n\t"
-		: "=&z" (tmp), "=r" (a)
-		: "1" (a), "r" (mask)
+		: "=&z" (tmp)
+		: "r" (a), "r" (mask)
 		: "t", "memory"
 	);
 }
 
-static inline void clear_bit(int nr, volatile void * addr)
+static inline void clear_bit(int nr, volatile void *addr)
 {
 	int	mask;
 	volatile unsigned int *a = addr;
@@ -34,16 +34,16 @@ static inline void clear_bit(int nr, vol
 	__asm__ __volatile__ (
 		"1:						\n\t"
 		"movli.l	@%1, %0	! clear_bit		\n\t"
-		"and		%3, %0				\n\t"
+		"and		%2, %0				\n\t"
 		"movco.l	%0, @%1				\n\t"
 		"bf		1b				\n\t"
-		: "=&z" (tmp), "=r" (a)
-		: "1" (a), "r" (~mask)
+		: "=&z" (tmp)
+		: "r" (a), "r" (~mask)
 		: "t", "memory"
 	);
 }
 
-static inline void change_bit(int nr, volatile void * addr)
+static inline void change_bit(int nr, volatile void *addr)
 {
 	int	mask;
 	volatile unsigned int *a = addr;
@@ -55,16 +55,16 @@ static inline void change_bit(int nr, vo
 	__asm__ __volatile__ (
 		"1:						\n\t"
 		"movli.l	@%1, %0	! change_bit		\n\t"
-		"xor		%3, %0				\n\t"
+		"xor		%2, %0				\n\t"
 		"movco.l	%0, @%1				\n\t"
 		"bf		1b				\n\t"
-		: "=&z" (tmp), "=r" (a)
-		: "1" (a), "r" (mask)
+		: "=&z" (tmp)
+		: "r" (a), "r" (mask)
 		: "t", "memory"
 	);
 }
 
-static inline int test_and_set_bit(int nr, volatile void * addr)
+static inline int test_and_set_bit(int nr, volatile void *addr)
 {
 	int	mask, retval;
 	volatile unsigned int *a = addr;
@@ -75,21 +75,21 @@ static inline int test_and_set_bit(int n
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! test_and_set_bit	\n\t"
-		"mov		%0, %2				\n\t"
-		"or		%4, %0				\n\t"
-		"movco.l	%0, @%1				\n\t"
+		"movli.l	@%2, %0	! test_and_set_bit	\n\t"
+		"mov		%0, %1				\n\t"
+		"or		%3, %0				\n\t"
+		"movco.l	%0, @%2				\n\t"
 		"bf		1b				\n\t"
-		"and		%4, %2				\n\t"
-		: "=&z" (tmp), "=r" (a), "=&r" (retval)
-		: "1" (a), "r" (mask)
+		"and		%3, %1				\n\t"
+		: "=&z" (tmp), "=&r" (retval)
+		: "r" (a), "r" (mask)
 		: "t", "memory"
 	);
 
 	return retval != 0;
 }
 
-static inline int test_and_clear_bit(int nr, volatile void * addr)
+static inline int test_and_clear_bit(int nr, volatile void *addr)
 {
 	int	mask, retval;
 	volatile unsigned int *a = addr;
@@ -100,22 +100,22 @@ static inline int test_and_clear_bit(int
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! test_and_clear_bit	\n\t"
-		"mov		%0, %2				\n\t"
-		"and		%5, %0				\n\t"
-		"movco.l	%0, @%1				\n\t"
+		"movli.l	@%2, %0	! test_and_clear_bit	\n\t"
+		"mov		%0, %1				\n\t"
+		"and		%4, %0				\n\t"
+		"movco.l	%0, @%2				\n\t"
 		"bf		1b				\n\t"
-		"and		%4, %2				\n\t"
+		"and		%3, %1				\n\t"
 		"synco						\n\t"
-		: "=&z" (tmp), "=r" (a), "=&r" (retval)
-		: "1" (a), "r" (mask), "r" (~mask)
+		: "=&z" (tmp), "=&r" (retval)
+		: "r" (a), "r" (mask), "r" (~mask)
 		: "t", "memory"
 	);
 
 	return retval != 0;
 }
 
-static inline int test_and_change_bit(int nr, volatile void * addr)
+static inline int test_and_change_bit(int nr, volatile void *addr)
 {
 	int	mask, retval;
 	volatile unsigned int *a = addr;
@@ -126,15 +126,15 @@ static inline int test_and_change_bit(in
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! test_and_change_bit	\n\t"
-		"mov		%0, %2				\n\t"
-		"xor		%4, %0				\n\t"
-		"movco.l	%0, @%1				\n\t"
+		"movli.l	@%2, %0	! test_and_change_bit	\n\t"
+		"mov		%0, %1				\n\t"
+		"xor		%3, %0				\n\t"
+		"movco.l	%0, @%2				\n\t"
 		"bf		1b				\n\t"
-		"and		%4, %2				\n\t"
+		"and		%3, %1				\n\t"
 		"synco						\n\t"
-		: "=&z" (tmp), "=r" (a), "=&r" (retval)
-		: "1" (a), "r" (mask)
+		: "=&z" (tmp), "=&r" (retval)
+		: "r" (a), "r" (mask)
 		: "t", "memory"
 	);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/clock.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/clock.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/clock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/clock.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@ struct clk_ops {
 	void (*disable)(struct clk *clk);
 	void (*recalc)(struct clk *clk);
 	int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
+	int (*set_parent)(struct clk *clk, struct clk *parent);
 	long (*round_rate)(struct clk *clk, unsigned long rate);
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/cmpxchg-llsc.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/cmpxchg-llsc.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/cmpxchg-llsc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/cmpxchg-llsc.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,14 +8,14 @@ static inline unsigned long xchg_u32(vol
 
 	__asm__ __volatile__ (
 		"1:					\n\t"
-		"movli.l	@%1, %0	! xchg_u32	\n\t"
-		"mov		%0, %2			\n\t"
-		"mov		%4, %0			\n\t"
-		"movco.l	%0, @%1			\n\t"
+		"movli.l	@%2, %0	! xchg_u32	\n\t"
+		"mov		%0, %1			\n\t"
+		"mov		%3, %0			\n\t"
+		"movco.l	%0, @%2			\n\t"
 		"bf		1b			\n\t"
 		"synco					\n\t"
-		: "=&z"(tmp), "=r" (m), "=&r" (retval)
-		: "1" (m), "r" (val)
+		: "=&z"(tmp), "=&r" (retval)
+		: "r" (m), "r" (val)
 		: "t", "memory"
 	);
 
@@ -29,14 +29,14 @@ static inline unsigned long xchg_u8(vola
 
 	__asm__ __volatile__ (
 		"1:					\n\t"
-		"movli.l	@%1, %0	! xchg_u8	\n\t"
-		"mov		%0, %2			\n\t"
-		"mov		%4, %0			\n\t"
-		"movco.l	%0, @%1			\n\t"
+		"movli.l	@%2, %0	! xchg_u8	\n\t"
+		"mov		%0, %1			\n\t"
+		"mov		%3, %0			\n\t"
+		"movco.l	%0, @%2			\n\t"
 		"bf		1b			\n\t"
 		"synco					\n\t"
-		: "=&z"(tmp), "=r" (m), "=&r" (retval)
-		: "1" (m), "r" (val & 0xff)
+		: "=&z"(tmp), "=&r" (retval)
+		: "r" (m), "r" (val & 0xff)
 		: "t", "memory"
 	);
 
@@ -51,17 +51,17 @@ __cmpxchg_u32(volatile int *m, unsigned
 
 	__asm__ __volatile__ (
 		"1:						\n\t"
-		"movli.l	@%1, %0	! __cmpxchg_u32		\n\t"
-		"mov		%0, %2				\n\t"
-		"cmp/eq		%2, %4				\n\t"
+		"movli.l	@%2, %0	! __cmpxchg_u32		\n\t"
+		"mov		%0, %1				\n\t"
+		"cmp/eq		%1, %3				\n\t"
 		"bf		2f				\n\t"
-		"mov		%5, %0				\n\t"
+		"mov		%3, %0				\n\t"
 		"2:						\n\t"
-		"movco.l	%0, @%1				\n\t"
+		"movco.l	%0, @%2				\n\t"
 		"bf		1b				\n\t"
 		"synco						\n\t"
-		: "=&z" (tmp), "=r" (m), "=&r" (retval)
-		: "1" (m), "r" (old), "r" (new)
+		: "=&z" (tmp), "=&r" (retval)
+		: "r" (m), "r" (old), "r" (new)
 		: "t", "memory"
 	);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/cpu-features.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/cpu-features.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/cpu-features.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/cpu-features.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,5 +21,6 @@
 #define CPU_HAS_LLSC		0x0040	/* movli.l/movco.l */
 #define CPU_HAS_L2_CACHE	0x0080	/* Secondary cache / URAM */
 #define CPU_HAS_OP32		0x0100	/* 32-bit instruction support */
+#define CPU_HAS_PTEAEX		0x0200	/* PTE ASID Extension support */
 
 #endif /* __ASM_SH_CPU_FEATURES_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,9 +25,9 @@
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET+0x10000000)
 
 #ifdef CONFIG_NR_DMA_CHANNELS
-#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
+#  define MAX_DMA_CHANNELS   (CONFIG_NR_DMA_CHANNELS)
 #else
-#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
+#  define MAX_DMA_CHANNELS   (CONFIG_NR_ONCHIP_DMA_CHANNELS)
 #endif
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
 
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 #include <asm-generic/dma-coherent.h>
@@ -38,16 +39,26 @@ static inline dma_addr_t dma_map_single(
 					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 virt_to_phys(ptr);
+		return addr;
 #endif
 	dma_cache_sync(dev, ptr, size, dir);
 
-	return virt_to_phys(ptr);
+	debug_dma_map_page(dev, virt_to_page(ptr),
+			   (unsigned long)ptr & ~PAGE_MASK, size,
+			   dir, addr, true);
+
+	return addr;
 }
 
-#define dma_unmap_single(dev, addr, size, dir)	do { } while (0)
+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)
@@ -59,12 +70,19 @@ static inline int dma_map_sg(struct devi
 		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;
 	}
 
+	debug_dma_map_sg(dev, sg, nents, i, dir);
+
 	return nents;
 }
 
-#define dma_unmap_sg(dev, sg, nents, dir)	do { } while (0)
+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,
@@ -111,6 +129,7 @@ static inline void dma_sync_sg(struct de
 		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;
 	}
 }
 
@@ -119,6 +138,7 @@ static inline void dma_sync_single_for_c
 					   enum dma_data_direction dir)
 {
 	dma_sync_single(dev, dma_handle, size, dir);
+	debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
 }
 
 static inline void dma_sync_single_for_device(struct device *dev,
@@ -127,6 +147,7 @@ static inline void dma_sync_single_for_d
 					      enum dma_data_direction dir)
 {
 	dma_sync_single(dev, dma_handle, size, dir);
+	debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
 }
 
 static inline void dma_sync_single_range_for_cpu(struct device *dev,
@@ -136,6 +157,8 @@ static inline void dma_sync_single_range
 						 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);
 }
 
 static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -145,6 +168,8 @@ static inline void dma_sync_single_range
 						    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);
 }
 
 
@@ -153,6 +178,7 @@ static inline void dma_sync_sg_for_cpu(s
 				       enum dma_data_direction dir)
 {
 	dma_sync_sg(dev, sg, nelems, dir);
+	debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
 }
 
 static inline void dma_sync_sg_for_device(struct device *dev,
@@ -160,9 +186,9 @@ static inline void dma_sync_sg_for_devic
 					  enum dma_data_direction dir)
 {
 	dma_sync_sg(dev, sg, nelems, dir);
+	debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
 }
 
-
 static inline int dma_get_cache_alignment(void)
 {
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma-sh.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma-sh.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/dma-sh.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/dma-sh.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,118 @@
+/*
+ * arch/sh/include/asm/dma-sh.h
+ *
+ * Copyright (C) 2000  Takashi YOSHII
+ * Copyright (C) 2003  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.
+ */
+#ifndef __DMA_SH_H
+#define __DMA_SH_H
+
+#include <asm/dma.h>
+#include <cpu/dma.h>
+
+/* DMAOR contorl: The DMAOR access size is different by CPU.*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7785)
+#define dmaor_read_reg(n) \
+    (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \
+	: ctrl_inw(SH_DMAC_BASE0 + DMAOR))
+#define dmaor_write_reg(n, data) \
+    (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \
+    : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR))
+#else /* Other CPU */
+#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)
+#endif
+
+static int dmte_irq_map[] __maybe_unused = {
+#if (MAX_DMA_CHANNELS >= 4)
+    DMTE0_IRQ,
+    DMTE0_IRQ + 1,
+    DMTE0_IRQ + 2,
+    DMTE0_IRQ + 3,
+#endif
+#if (MAX_DMA_CHANNELS >= 6)
+    DMTE4_IRQ,
+    DMTE4_IRQ + 1,
+#endif
+#if (MAX_DMA_CHANNELS >= 8)
+    DMTE6_IRQ,
+    DMTE6_IRQ + 1,
+#endif
+#if (MAX_DMA_CHANNELS >= 12)
+    DMTE8_IRQ,
+    DMTE9_IRQ,
+    DMTE10_IRQ,
+    DMTE11_IRQ,
+#endif
+};
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L	0x00000000
+#define REQ_E	0x00080000
+#define RACK_H	0x00000000
+#define RACK_L	0x00040000
+#define ACK_R	0x00000000
+#define ACK_W	0x00020000
+#define ACK_H	0x00000000
+#define ACK_L	0x00010000
+#define DM_INC	0x00004000
+#define DM_DEC	0x00008000
+#define SM_INC	0x00001000
+#define SM_DEC	0x00002000
+#define RS_IN	0x00000200
+#define RS_OUT	0x00000300
+#define TS_BLK	0x00000040
+#define TM_BUR	0x00000020
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+/* DMAOR definitions */
+#define DMAOR_AE	0x00000004
+#define DMAOR_NMIF	0x00000002
+#define DMAOR_DME	0x00000001
+
+/*
+ * Define the default configuration for dual address memory-memory transfer.
+ * The 0x400 value represents auto-request, external->external.
+ */
+#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
+
+/* DMA base address */
+static u32 dma_base_addr[] __maybe_unused = {
+#if (MAX_DMA_CHANNELS >= 4)
+	SH_DMAC_BASE0 + 0x00,	/* channel 0 */
+	SH_DMAC_BASE0 + 0x10,
+	SH_DMAC_BASE0 + 0x20,
+	SH_DMAC_BASE0 + 0x30,
+#endif
+#if (MAX_DMA_CHANNELS >= 6)
+	SH_DMAC_BASE0 + 0x50,
+	SH_DMAC_BASE0 + 0x60,
+#endif
+#if (MAX_DMA_CHANNELS >= 8)
+	SH_DMAC_BASE1 + 0x00,
+	SH_DMAC_BASE1 + 0x10,
+#endif
+#if (MAX_DMA_CHANNELS >= 12)
+	SH_DMAC_BASE1 + 0x20,
+	SH_DMAC_BASE1 + 0x30,
+	SH_DMAC_BASE1 + 0x50,
+	SH_DMAC_BASE1 + 0x60, /* channel 11 */
+#endif
+};
+
+/* DMA register */
+#define SAR     0x00
+#define DAR     0x04
+#define TCR     0x08
+#define CHCR    0x0C
+#define DMAOR	0x40
+
+#endif /* __DMA_SH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/entry-macros.S linux-libre-2.6.30-gnu1/arch/sh/include/asm/entry-macros.S
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/entry-macros.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/entry-macros.S	2009-06-09 23:05:27.000000000 -0400
@@ -31,3 +31,8 @@
 #endif	
 	.endm
 
+#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
+# define PREF(x)	pref	@x
+#else
+# define PREF(x)	nop
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/flat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,6 @@
 #ifndef __ASM_SH_FLAT_H
 #define __ASM_SH_FLAT_H
 
-#define	flat_stack_align(sp)			/* nothing needed */
 #define	flat_argvp_envp_on_stack()		0
 #define	flat_old_ram_flag(flags)		(flags)
 #define	flat_reloc_valid(reloc, size)		((reloc) <= (size))
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/gpio.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/gpio.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,8 +19,42 @@
 #include <cpu/gpio.h>
 #endif
 
+#define ARCH_NR_GPIOS 512
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+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)
+{
+	WARN_ON(1);
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
 typedef unsigned short pinmux_enum_t;
-typedef unsigned char pinmux_flag_t;
+typedef unsigned short pinmux_flag_t;
 
 #define PINMUX_TYPE_NONE            0
 #define PINMUX_TYPE_FUNCTION        1
@@ -34,6 +68,11 @@ typedef unsigned char pinmux_flag_t;
 #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;
@@ -54,7 +93,7 @@ struct pinmux_cfg_reg {
 	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
 
 struct pinmux_data_reg {
-	unsigned long reg, reg_width;
+	unsigned long reg, reg_width, reg_shadow;
 	pinmux_enum_t *enum_ids;
 };
 
@@ -89,34 +128,9 @@ struct pinmux_info {
 	unsigned int gpio_data_size;
 
 	unsigned long *gpio_in_use;
+	struct gpio_chip chip;
 };
 
 int register_pinmux(struct pinmux_info *pip);
 
-int __gpio_request(unsigned gpio);
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-	return __gpio_request(gpio);
-}
-void gpio_free(unsigned gpio);
-int gpio_direction_input(unsigned gpio);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
-void gpio_set_value(unsigned gpio, int value);
-
-/* IRQ modes are unspported */
-static inline int gpio_to_irq(unsigned gpio)
-{
-	WARN_ON(1);
-	return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-	WARN_ON(1);
-	return -EINVAL;
-}
-
-#include <asm-generic/gpio.h>
-
 #endif /* __ASM_SH_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/hd64461.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/hd64461.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/hd64461.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/hd64461.h	2009-06-09 23:05:27.000000000 -0400
@@ -242,7 +242,6 @@
 #include <asm/io_generic.h>
 
 /* arch/sh/cchips/hd6446x/hd64461/setup.c */
-int hd64461_irq_demux(int irq);
 void hd64461_register_irq_demux(int irq,
 				int (*demux) (int irq, void *dev), void *dev);
 void hd64461_unregister_irq_demux(int irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/io.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -238,7 +238,7 @@ extern void onchip_unmap(unsigned long v
 static inline void __iomem *
 __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 {
-#ifdef CONFIG_SUPERH32
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
 	unsigned long last_addr = offset + size - 1;
 #endif
 	void __iomem *ret;
@@ -247,7 +247,7 @@ __ioremap_mode(unsigned long offset, uns
 	if (ret)
 		return ret;
 
-#ifdef CONFIG_SUPERH32
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
 	/*
 	 * For P1 and P2 space this is trivial, as everything is already
 	 * mapped. Uncached access for P1 addresses are done through P2.
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/kprobes.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/kprobes.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/kprobes.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/kprobes.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,7 @@ typedef u16 kprobe_opcode_t;
 	? (MAX_STACK_SIZE) \
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
-#define regs_return_value(regs)		((regs)->regs[0])
+#define regs_return_value(_regs)		((_regs)->regs[0])
 #define flush_insn_slot(p)		do { } while (0)
 #define kretprobe_blacklist_size	0
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu_context_32.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu_context_32.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu_context_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu_context_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,17 @@ static inline void destroy_context(struc
 	/* Do nothing */
 }
 
+#ifdef CONFIG_CPU_HAS_PTEAEX
+static inline void set_asid(unsigned long asid)
+{
+	__raw_writel(asid, MMU_PTEAEX);
+}
+
+static inline unsigned long get_asid(void)
+{
+	return __raw_readl(MMU_PTEAEX) & MMU_CONTEXT_ASID_MASK;
+}
+#else
 static inline void set_asid(unsigned long asid)
 {
 	unsigned long __dummy;
@@ -33,6 +44,7 @@ static inline unsigned long get_asid(voi
 	asid &= MMU_CONTEXT_ASID_MASK;
 	return asid;
 }
+#endif /* CONFIG_CPU_HAS_PTEAEX */
 
 /* MMU_TTB is used for optimizing the fault handling. */
 static inline void set_TTB(pgd_t *pgd)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,13 +19,18 @@
  *    (a) TLB cache version (or round, cycle whatever expression you like)
  *    (b) ASID (Address Space IDentifier)
  */
+#ifdef CONFIG_CPU_HAS_PTEAEX
+#define MMU_CONTEXT_ASID_MASK		0x0000ffff
+#else
 #define MMU_CONTEXT_ASID_MASK		0x000000ff
-#define MMU_CONTEXT_VERSION_MASK	0xffffff00
-#define MMU_CONTEXT_FIRST_VERSION	0x00000100
-#define NO_CONTEXT			0UL
+#endif
 
-/* ASID is 8-bit value, so it can't be 0x100 */
-#define MMU_NO_ASID			0x100
+#define MMU_CONTEXT_VERSION_MASK	(~0UL & ~MMU_CONTEXT_ASID_MASK)
+#define MMU_CONTEXT_FIRST_VERSION	(MMU_CONTEXT_ASID_MASK + 1)
+
+/* Impossible ASID value, to differentiate from NO_CONTEXT. */
+#define MMU_NO_ASID			MMU_CONTEXT_FIRST_VERSION
+#define NO_CONTEXT			0UL
 
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,22 +1,6 @@
 #ifndef __MMU_H
 #define __MMU_H
 
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_id_t[NR_CPUS];
-
-typedef struct {
-#ifdef CONFIG_MMU
-	mm_context_id_t		id;
-	void			*vdso;
-#else
-	unsigned long		end_brk;
-#endif
-#ifdef CONFIG_BINFMT_ELF_FDPIC
-	unsigned long		exec_fdpic_loadmap;
-	unsigned long		interp_fdpic_loadmap;
-#endif
-} mm_context_t;
-
 /*
  * Privileged Space Mapping Buffer (PMB) definitions
  */
@@ -41,6 +25,24 @@ typedef struct {
 
 #define PMB_NO_ENTRY		(-1)
 
+#ifndef __ASSEMBLY__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_id_t[NR_CPUS];
+
+typedef struct {
+#ifdef CONFIG_MMU
+	mm_context_id_t		id;
+	void			*vdso;
+#else
+	unsigned long		end_brk;
+#endif
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+	unsigned long		exec_fdpic_loadmap;
+	unsigned long		interp_fdpic_loadmap;
+#endif
+} mm_context_t;
+
 struct pmb_entry;
 
 struct pmb_entry {
@@ -70,6 +72,7 @@ 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);
+#endif /* __ASSEMBLY__ */
 
 #endif /* __MMU_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/page.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,12 @@ typedef struct page *pgtable_t;
  * is not visible (it is part of the PMB mapping) and so needs to be
  * added or subtracted as required.
  */
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_PMB_FIXED)
+/* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */
+#define PMB_OFFSET	(PAGE_OFFSET - PXSEG(__MEMORY_START))
+#define __pa(x)	((unsigned long)(x) - PMB_OFFSET)
+#define __va(x)	((void *)((unsigned long)(x) + PMB_OFFSET))
+#elif defined(CONFIG_32BIT)
 #define __pa(x)	((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
 #define __va(x)	((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
 #else
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor_32.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor_32.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,6 +58,14 @@ asmlinkage void __init sh_cpu_init(void)
 #define SR_FD		0x00008000
 
 /*
+ * DSP structure and data
+ */
+struct sh_dsp_struct {
+	unsigned long dsp_regs[14];
+	long status;
+};
+
+/*
  * FPU structure and data
  */
 
@@ -96,6 +104,11 @@ struct thread_struct {
 
 	/* floating point info */
 	union sh_fpu_union fpu;
+
+#ifdef CONFIG_SH_DSP
+	/* Dsp status information */
+	struct sh_dsp_struct dsp_status;
+#endif
 };
 
 /* Count of active tasks with UBC settings */
@@ -108,12 +121,12 @@ extern int ubc_usercnt;
 /*
  * Do necessary setup to start up a newly executed thread.
  */
-#define start_thread(regs, new_pc, new_sp)	 \
+#define start_thread(_regs, new_pc, new_sp)	 \
 	set_fs(USER_DS);			 \
-	regs->pr = 0;				 \
-	regs->sr = SR_FD;	/* User mode. */ \
-	regs->pc = new_pc;			 \
-	regs->regs[15] = new_sp
+	_regs->pr = 0;				 \
+	_regs->sr = SR_FD;	/* User mode. */ \
+	_regs->pc = new_pc;			 \
+	_regs->regs[15] = new_sp
 
 /* Forward declaration, a strange C thing */
 struct task_struct;
@@ -189,10 +202,9 @@ extern unsigned long get_wchan(struct ta
 #define KSTK_EIP(tsk)  (task_pt_regs(tsk)->pc)
 #define KSTK_ESP(tsk)  (task_pt_regs(tsk)->regs[15])
 
-#define user_stack_pointer(regs)	((regs)->regs[15])
+#define user_stack_pointer(_regs)	((_regs)->regs[15])
 
-#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \
-    defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
 #define PREFETCH_STRIDE		L1_CACHE_BYTES
 #define ARCH_HAS_PREFETCH
 #define ARCH_HAS_PREFETCHW
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor_64.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor_64.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -145,13 +145,13 @@ struct thread_struct {
  */
 #define SR_USER (SR_MMU | SR_FD)
 
-#define start_thread(regs, new_pc, new_sp)			\
+#define start_thread(_regs, new_pc, new_sp)			\
 	set_fs(USER_DS);					\
-	regs->sr = SR_USER;	/* User mode. */		\
-	regs->pc = new_pc - 4;	/* Compensate syscall exit */	\
-	regs->pc |= 1;		/* Set SHmedia ! */		\
-	regs->regs[18] = 0;					\
-	regs->regs[15] = new_sp
+	_regs->sr = SR_USER;	/* User mode. */		\
+	_regs->pc = new_pc - 4;	/* Compensate syscall exit */	\
+	_regs->pc |= 1;		/* Set SHmedia ! */		\
+	_regs->regs[18] = 0;					\
+	_regs->regs[15] = new_sp
 
 /* Forward declaration, a strange C thing */
 struct task_struct;
@@ -226,7 +226,7 @@ extern unsigned long get_wchan(struct ta
 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
 #define KSTK_ESP(tsk)  ((tsk)->thread.sp)
 
-#define user_stack_pointer(regs)	((regs)->regs[15])
+#define user_stack_pointer(_regs)	((_regs)->regs[15])
 
 #endif	/* __ASSEMBLY__ */
 #endif /* __ASM_SH_PROCESSOR_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/processor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ enum cpu_type {
 	CPU_SH7760, CPU_SH4_202, CPU_SH4_501,
 
 	/* SH-4A types */
-	CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785,
+	CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
 	CPU_SH7723, CPU_SHX3,
 
 	/* SH4AL-DSP types */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@
 struct pt_regs {
 	unsigned long long pc;
 	unsigned long long sr;
-	unsigned long long syscall_nr;
+	long long syscall_nr;
 	unsigned long long regs[63];
 	unsigned long long tregs[8];
 	unsigned long long pad[2];
@@ -119,18 +119,8 @@ struct task_struct;
 extern void user_enable_single_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
-#ifdef CONFIG_SH_DSP
-#define task_pt_regs(task) \
-	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
-		 - sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1)
-#define task_pt_dspregs(task) \
-	((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE \
-		 - sizeof(unsigned long)) - 1)
-#else
 #define task_pt_regs(task) \
-	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
-		 - sizeof(unsigned long)) - 1)
-#endif
+	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
 
 static inline unsigned long profile_pc(struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/scatterlist.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/scatterlist.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/scatterlist.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/scatterlist.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,12 +5,13 @@
 
 struct scatterlist {
 #ifdef CONFIG_DEBUG_SG
-    unsigned long sg_magic;
+	unsigned long	sg_magic;
 #endif
-    unsigned long page_link;
-    unsigned int offset;/* for highmem, page offset */
-    dma_addr_t dma_address;
-    unsigned int length;
+	unsigned long	page_link;
+	unsigned int	offset;		/* for highmem, page offset */
+	unsigned int	length;
+	dma_addr_t	dma_address;
+	unsigned int	dma_length;
 };
 
 #define ISA_DMA_THRESHOLD	PHYS_ADDR_MASK
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/sections.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
 
 #include <asm-generic/sections.h>
 
+extern void __nosave_begin, __nosave_end;
 extern long __machvec_start, __machvec_end;
 extern char __uncached_start, __uncached_end;
 extern char _ebss[];
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* __ASM_SH_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -216,6 +216,9 @@ 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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/suspend.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/suspend.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/suspend.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/suspend.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+#ifndef _ASM_SH_SUSPEND_H
+#define _ASM_SH_SUSPEND_H
+
+#ifndef __ASSEMBLY__
+static inline int arch_prepare_suspend(void) { return 0; }
+
+#include <asm/ptrace.h>
+
+struct swsusp_arch_regs {
+	struct pt_regs user_regs;
+	unsigned long bank1_regs[8];
+};
+#endif
+
+/* flags passed to assembly suspend code */
+#define SUSP_SH_SLEEP		(1 << 0) /* Regular sleep mode */
+#define SUSP_SH_STANDBY		(1 << 1) /* SH-Mobile Software standby mode */
+#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 */
+
+#endif /* _ASM_SH_SUSPEND_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/system_32.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/system_32.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/system_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/system_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,59 +3,135 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_SH_DSP
+
+#define is_dsp_enabled(tsk)						\
+	(!!(tsk->thread.dsp_status.status & SR_DSP))
+
+#define __restore_dsp(tsk)						\
+do {									\
+	register u32 *__ts2 __asm__ ("r2") =				\
+			(u32 *)&tsk->thread.dsp_status;			\
+	__asm__ __volatile__ (						\
+		".balign 4\n\t"						\
+		"movs.l	@r2+, a1\n\t"					\
+		"movs.l	@r2+, a0g\n\t"					\
+		"movs.l	@r2+, a1g\n\t"					\
+		"movs.l	@r2+, m0\n\t"					\
+		"movs.l	@r2+, m1\n\t"					\
+		"movs.l	@r2+, a0\n\t"					\
+		"movs.l	@r2+, x0\n\t"					\
+		"movs.l	@r2+, x1\n\t"					\
+		"movs.l	@r2+, y0\n\t"					\
+		"movs.l	@r2+, y1\n\t"					\
+		"lds.l	@r2+, dsr\n\t"					\
+		"ldc.l	@r2+, rs\n\t"					\
+		"ldc.l	@r2+, re\n\t"					\
+		"ldc.l	@r2+, mod\n\t"					\
+		: : "r" (__ts2));					\
+} while (0)
+
+
+#define __save_dsp(tsk)							\
+do {									\
+	register u32 *__ts2 __asm__ ("r2") =				\
+			(u32 *)&tsk->thread.dsp_status + 14;		\
+									\
+	__asm__ __volatile__ (						\
+		".balign 4\n\t"						\
+		"stc.l	mod, @-r2\n\t"				\
+		"stc.l	re, @-r2\n\t"					\
+		"stc.l	rs, @-r2\n\t"					\
+		"sts.l	dsr, @-r2\n\t"				\
+		"sts.l	y1, @-r2\n\t"					\
+		"sts.l	y0, @-r2\n\t"					\
+		"sts.l	x1, @-r2\n\t"					\
+		"sts.l	x0, @-r2\n\t"					\
+		"sts.l	a0, @-r2\n\t"					\
+		".word	0xf653		! movs.l	a1, @-r2\n\t"	\
+		".word	0xf6f3		! movs.l	a0g, @-r2\n\t"	\
+		".word	0xf6d3		! movs.l	a1g, @-r2\n\t"	\
+		".word	0xf6c3		! movs.l        m0, @-r2\n\t"	\
+		".word	0xf6e3		! movs.l        m1, @-r2\n\t"	\
+		: : "r" (__ts2));					\
+} while (0)
+
+#else
+
+#define is_dsp_enabled(tsk)	(0)
+#define __save_dsp(tsk)		do { } while (0)
+#define __restore_dsp(tsk)	do { } while (0)
+#endif
+
 struct task_struct *__switch_to(struct task_struct *prev,
 				struct task_struct *next);
 
 /*
  *	switch_to() should switch tasks to task nr n, first
  */
-#define switch_to(prev, next, last)					\
-do {									\
-	register u32 *__ts1 __asm__ ("r1") = (u32 *)&prev->thread.sp;	\
-	register u32 *__ts2 __asm__ ("r2") = (u32 *)&prev->thread.pc;	\
-	register u32 *__ts4 __asm__ ("r4") = (u32 *)prev;		\
-	register u32 *__ts5 __asm__ ("r5") = (u32 *)next;		\
-	register u32 *__ts6 __asm__ ("r6") = (u32 *)&next->thread.sp;	\
-	register u32 __ts7 __asm__ ("r7") = next->thread.pc;		\
-	struct task_struct *__last;					\
-									\
-	__asm__ __volatile__ (						\
-		".balign 4\n\t"						\
-		"stc.l	gbr, @-r15\n\t"					\
-		"sts.l	pr, @-r15\n\t"					\
-		"mov.l	r8, @-r15\n\t"					\
-		"mov.l	r9, @-r15\n\t"					\
-		"mov.l	r10, @-r15\n\t"					\
-		"mov.l	r11, @-r15\n\t"					\
-		"mov.l	r12, @-r15\n\t"					\
-		"mov.l	r13, @-r15\n\t"					\
-		"mov.l	r14, @-r15\n\t"					\
-		"mov.l	r15, @r1\t! save SP\n\t"			\
-		"mov.l	@r6, r15\t! change to new stack\n\t"		\
-		"mova	1f, %0\n\t"					\
-		"mov.l	%0, @r2\t! save PC\n\t"				\
-		"mov.l	2f, %0\n\t"					\
-		"jmp	@%0\t! call __switch_to\n\t"			\
-		" lds	r7, pr\t!  with return to new PC\n\t"		\
-		".balign	4\n"					\
-		"2:\n\t"						\
-		".long	__switch_to\n"					\
-		"1:\n\t"						\
-		"mov.l	@r15+, r14\n\t"					\
-		"mov.l	@r15+, r13\n\t"					\
-		"mov.l	@r15+, r12\n\t"					\
-		"mov.l	@r15+, r11\n\t"					\
-		"mov.l	@r15+, r10\n\t"					\
-		"mov.l	@r15+, r9\n\t"					\
-		"mov.l	@r15+, r8\n\t"					\
-		"lds.l	@r15+, pr\n\t"					\
-		"ldc.l	@r15+, gbr\n\t"					\
-		: "=z" (__last)						\
-		: "r" (__ts1), "r" (__ts2), "r" (__ts4),		\
-		  "r" (__ts5), "r" (__ts6), "r" (__ts7)			\
-		: "r3", "t");						\
-									\
-	last = __last;							\
+#define switch_to(prev, next, last)				\
+do {								\
+	register u32 *__ts1 __asm__ ("r1");			\
+	register u32 *__ts2 __asm__ ("r2");			\
+	register u32 *__ts4 __asm__ ("r4");			\
+	register u32 *__ts5 __asm__ ("r5");			\
+	register u32 *__ts6 __asm__ ("r6");			\
+	register u32 __ts7 __asm__ ("r7");			\
+	struct task_struct *__last;				\
+								\
+	if (is_dsp_enabled(prev))				\
+		__save_dsp(prev);				\
+								\
+	__ts1 = (u32 *)&prev->thread.sp;			\
+	__ts2 = (u32 *)&prev->thread.pc;			\
+	__ts4 = (u32 *)prev;					\
+	__ts5 = (u32 *)next;					\
+	__ts6 = (u32 *)&next->thread.sp;			\
+	__ts7 = next->thread.pc;				\
+								\
+	__asm__ __volatile__ (					\
+		".balign 4\n\t"					\
+		"stc.l	gbr, @-r15\n\t"				\
+		"sts.l	pr, @-r15\n\t"				\
+		"mov.l	r8, @-r15\n\t"				\
+		"mov.l	r9, @-r15\n\t"				\
+		"mov.l	r10, @-r15\n\t"				\
+		"mov.l	r11, @-r15\n\t"				\
+		"mov.l	r12, @-r15\n\t"				\
+		"mov.l	r13, @-r15\n\t"				\
+		"mov.l	r14, @-r15\n\t"				\
+		"mov.l	r15, @r1\t! save SP\n\t"		\
+		"mov.l	@r6, r15\t! change to new stack\n\t"	\
+		"mova	1f, %0\n\t"				\
+		"mov.l	%0, @r2\t! save PC\n\t"			\
+		"mov.l	2f, %0\n\t"				\
+		"jmp	@%0\t! call __switch_to\n\t"		\
+		" lds	r7, pr\t!  with return to new PC\n\t"	\
+		".balign	4\n"				\
+		"2:\n\t"					\
+		".long	__switch_to\n"				\
+		"1:\n\t"					\
+		"mov.l	@r15+, r14\n\t"				\
+		"mov.l	@r15+, r13\n\t"				\
+		"mov.l	@r15+, r12\n\t"				\
+		"mov.l	@r15+, r11\n\t"				\
+		"mov.l	@r15+, r10\n\t"				\
+		"mov.l	@r15+, r9\n\t"				\
+		"mov.l	@r15+, r8\n\t"				\
+		"lds.l	@r15+, pr\n\t"				\
+		"ldc.l	@r15+, gbr\n\t"				\
+		: "=z" (__last)					\
+		: "r" (__ts1), "r" (__ts2), "r" (__ts4),	\
+		  "r" (__ts5), "r" (__ts6), "r" (__ts7)		\
+		: "r3", "t");					\
+								\
+	last = __last;						\
+} while (0)
+
+#define finish_arch_switch(prev)				\
+do {								\
+	if (is_dsp_enabled(prev))				\
+		__restore_dsp(prev);				\
 } while (0)
 
 #define __uses_jump_to_uncached \
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/system.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,7 @@ extern unsigned long cached_to_uncached;
 extern struct dentry *sh_debugfs_root;
 
 void per_cpu_trap_init(void);
+void default_idle(void);
 
 asmlinkage void break_point_trap(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/timer.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/timer.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,6 @@ struct sys_timer_ops {
 	int (*init)(void);
 	int (*start)(void);
 	int (*stop)(void);
-	cycle_t (*read)(void);
 #ifndef CONFIG_GENERIC_TIME
 	unsigned long (*get_offset)(void);
 #endif
@@ -39,6 +38,7 @@ struct sys_timer *get_sys_timer(void);
 
 /* arch/sh/kernel/time.c */
 void handle_timer_tick(void);
-extern unsigned long sh_hpt_frequency;
+
+extern struct clocksource clocksource_sh;
 
 #endif /* __ASM_SH_TIMER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/tlb.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/tlb.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/tlb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/tlb.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,22 +6,106 @@
 #endif
 
 #ifndef __ASSEMBLY__
+#include <linux/pagemap.h>
 
-#define tlb_start_vma(tlb, vma) \
-	flush_cache_range(vma, vma->vm_start, vma->vm_end)
+#ifdef CONFIG_MMU
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
 
-#define tlb_end_vma(tlb, vma)	\
-	flush_tlb_range(vma, vma->vm_start, vma->vm_end)
+/*
+ * TLB handling.  This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+struct mmu_gather {
+	struct mm_struct	*mm;
+	unsigned int		fullmm;
+	unsigned long		start, end;
+};
 
-#define __tlb_remove_tlb_entry(tlb, pte, address)	do { } while (0)
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline void init_tlb_gather(struct mmu_gather *tlb)
+{
+	tlb->start = TASK_SIZE;
+	tlb->end = 0;
+
+	if (tlb->fullmm) {
+		tlb->start = 0;
+		tlb->end = TASK_SIZE;
+	}
+}
+
+static inline struct mmu_gather *
+tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+	tlb->mm = mm;
+	tlb->fullmm = full_mm_flush;
+
+	init_tlb_gather(tlb);
+
+	return tlb;
+}
+
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+	if (tlb->fullmm)
+		flush_tlb_mm(tlb->mm);
+
+	/* keep the page table cache within bounds */
+	check_pgt_cache();
+
+	put_cpu_var(mmu_gathers);
+}
+
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long address)
+{
+	if (tlb->start > address)
+		tlb->start = address;
+	if (tlb->end < address + PAGE_SIZE)
+		tlb->end = address + PAGE_SIZE;
+}
 
 /*
- * Flush whole TLBs for MM
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush.  When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
  */
-#define tlb_flush(tlb)				flush_tlb_mm((tlb)->mm)
+static inline void
+tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+	if (!tlb->fullmm)
+		flush_cache_range(vma, vma->vm_start, vma->vm_end);
+}
+
+static inline void
+tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+	if (!tlb->fullmm && tlb->end) {
+		flush_tlb_range(vma, tlb->start, tlb->end);
+		init_tlb_gather(tlb);
+	}
+}
+
+#define tlb_remove_page(tlb,page)	free_page_and_swap_cache(page)
+#define pte_free_tlb(tlb, ptep)		pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp)		pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp)		pud_free((tlb)->mm, pudp)
+
+#define tlb_migrate_finish(mm)		do { } while (0)
+
+#else /* CONFIG_MMU */
+
+#define tlb_start_vma(tlb, vma)				do { } while (0)
+#define tlb_end_vma(tlb, vma)				do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, pte, address)	do { } while (0)
+#define tlb_flush(tlb)					do { } while (0)
 
-#include <linux/pagemap.h>
 #include <asm-generic/tlb.h>
 
+#endif /* CONFIG_MMU */
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_SH_TLB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,13 +33,15 @@
 
 #define node_to_cpumask(node)	((void)node, cpu_online_map)
 #define cpumask_of_node(node)	((void)node, cpu_online_mask)
-#define node_to_first_cpu(node)	((void)(node),0)
 
 #define pcibus_to_node(bus)	((void)(bus), -1)
 #define pcibus_to_cpumask(bus)	(pcibus_to_node(bus) == -1 ? \
 					CPU_MASK_ALL : \
-					node_to_cpumask(pcibus_to_node(bus)) \
-				)
+					node_to_cpumask(pcibus_to_node(bus)))
+#define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ? \
+					CPU_MASK_ALL_PTR : \
+					cpumask_of_node(pcibus_to_node(bus)))
+
 #endif
 
 #include <asm-generic/topology.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/unistd_32.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/unistd_32.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/unistd_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/unistd_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -341,8 +341,10 @@
 #define __NR_dup3		330
 #define __NR_pipe2		331
 #define __NR_inotify_init1	332
+#define __NR_preadv		333
+#define __NR_pwritev		334
 
-#define NR_syscalls 333
+#define NR_syscalls 335
 
 #ifdef __KERNEL__
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/asm/unistd_64.h linux-libre-2.6.30-gnu1/arch/sh/include/asm/unistd_64.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/asm/unistd_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/asm/unistd_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -381,10 +381,12 @@
 #define __NR_dup3		358
 #define __NR_pipe2		359
 #define __NR_inotify_init1	360
+#define __NR_preadv		361
+#define __NR_pwritev		362
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 361
+#define NR_syscalls 363
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh3/cpu/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,22 +1,17 @@
 #ifndef __ASM_CPU_SH3_DMA_H
 #define __ASM_CPU_SH3_DMA_H
 
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SH_DMAC_BASE	0xa4010020
-#else
-#define SH_DMAC_BASE	0xa4000020
+    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7710) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SH_DMAC_BASE0	0xa4010020
+#else /* SH7705/06/07/09 */
+#define SH_DMAC_BASE0	0xa4000020
 #endif
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 #define DMTE0_IRQ	48
-#define DMTE1_IRQ	49
-#define DMTE2_IRQ	50
-#define DMTE3_IRQ	51
 #define DMTE4_IRQ	76
-#define DMTE5_IRQ	77
-#endif
 
 /* Definitions for the SuperH DMAC */
 #define TM_BURST	0x00000020
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,31 +1,29 @@
 #ifndef __ASM_CPU_SH4_DMA_H
 #define __ASM_CPU_SH4_DMA_H
 
-#define DMAOR_INIT	( 0x8000 | DMAOR_DME )
-
 /* SH7751/7760/7780 DMA IRQ sources */
-#define DMTE0_IRQ	34
-#define DMTE1_IRQ	35
-#define DMTE2_IRQ	36
-#define DMTE3_IRQ	37
-#define DMTE4_IRQ	44
-#define DMTE5_IRQ	45
-#define DMTE6_IRQ	46
-#define DMTE7_IRQ	47
-#define DMAE_IRQ	38
 
 #ifdef CONFIG_CPU_SH4A
-#define SH_DMAC_BASE	0xfc808020
 
+#define DMAOR_INIT	(DMAOR_DME)
 #define CHCR_TS_MASK	0x18
 #define CHCR_TS_SHIFT	3
 
-#include <cpu/dma-sh7780.h>
-#else
-#define SH_DMAC_BASE	0xffa00000
+#include <cpu/dma-sh4a.h>
+#else /* CONFIG_CPU_SH4A */
+/*
+ * SH7750/SH7751/SH7760
+ */
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMTE6_IRQ	46
+#define DMAE0_IRQ	38
 
+#define DMAOR_INIT	(0x8000|DMAOR_DME)
+#define SH_DMAC_BASE0	0xffa00000
+#define SH_DMAC_BASE1	0xffa00070
 /* Definitions for the SuperH DMAC */
-#define TM_BURST	0x0000080
+#define TM_BURST	0x00000080
 #define TS_8		0x00000010
 #define TS_16		0x00000020
 #define TS_32		0x00000030
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,94 @@
+#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
+#define __ASM_SH_CPU_SH4_DMA_SH7780_H
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7730)
+#define DMTE0_IRQ	48
+#define DMTE4_IRQ	76
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMARS_BASE	0xFE009000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7764)
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMAE0_IRQ	38
+#define SH_DMAC_BASE0	0xFF608020
+#define SH_DMARS_BASE	0xFF609000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define DMTE0_IRQ	48	/* DMAC0A*/
+#define DMTE4_IRQ	40	/* DMAC0B */
+#define DMTE6_IRQ	42
+#define DMTE8_IRQ	76	/* DMAC1A */
+#define DMTE9_IRQ	77
+#define DMTE10_IRQ	72	/* DMAC1B */
+#define DMTE11_IRQ	73
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define DMAE1_IRQ	74	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMAC_BASE1	0xFDC08020
+#define SH_DMARS_BASE	0xFDC09000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMTE6_IRQ	46
+#define DMTE8_IRQ	92
+#define DMTE9_IRQ	93
+#define DMTE10_IRQ	94
+#define DMTE11_IRQ	95
+#define DMAE0_IRQ	38	/* DMA Error IRQ */
+#define SH_DMAC_BASE0	0xFC808020
+#define SH_DMAC_BASE1	0xFC818020
+#define SH_DMARS_BASE	0xFC809000
+#else /* SH7785 */
+#define DMTE0_IRQ	33
+#define DMTE4_IRQ	37
+#define DMTE6_IRQ	52
+#define DMTE8_IRQ	54
+#define DMTE9_IRQ	55
+#define DMTE10_IRQ	56
+#define DMTE11_IRQ	57
+#define DMAE0_IRQ	39	/* DMA Error IRQ0 */
+#define DMAE1_IRQ	58	/* DMA Error IRQ1 */
+#define SH_DMAC_BASE0	0xFC808020
+#define SH_DMAC_BASE1	0xFCC08020
+#define SH_DMARS_BASE	0xFC809000
+#endif
+
+#define REQ_HE	0x000000C0
+#define REQ_H	0x00000080
+#define REQ_LE	0x00000040
+#define TM_BURST 0x0000020
+#define TS_8	0x00000000
+#define TS_16	0x00000008
+#define TS_32	0x00000010
+#define TS_16BLK	0x00000018
+#define TS_32BLK	0x00100000
+
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ *
+ * Defaults to a 64-bit transfer size.
+ */
+enum {
+	XMIT_SZ_8BIT,
+	XMIT_SZ_16BIT,
+	XMIT_SZ_32BIT,
+	XMIT_SZ_128BIT,
+	XMIT_SZ_256BIT,
+};
+
+/*
+ * The DMA count is defined as the number of bytes to transfer.
+ */
+static unsigned int ts_shift[] __maybe_unused = {
+	[XMIT_SZ_8BIT]		= 0,
+	[XMIT_SZ_16BIT]		= 1,
+	[XMIT_SZ_32BIT]		= 2,
+	[XMIT_SZ_128BIT]	= 4,
+	[XMIT_SZ_256BIT]	= 5,
+};
+
+#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
-#define __ASM_SH_CPU_SH4_DMA_SH7780_H
-
-#define REQ_HE	0x000000C0
-#define REQ_H	0x00000080
-#define REQ_LE	0x00000040
-#define TM_BURST 0x0000020
-#define TS_8	0x00000000
-#define TS_16	0x00000008
-#define TS_32	0x00000010
-#define TS_16BLK	0x00000018
-#define TS_32BLK	0x00100000
-
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-enum {
-	XMIT_SZ_8BIT,
-	XMIT_SZ_16BIT,
-	XMIT_SZ_32BIT,
-	XMIT_SZ_128BIT,
-	XMIT_SZ_256BIT,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-static unsigned int ts_shift[] __maybe_unused = {
-	[XMIT_SZ_8BIT]		= 0,
-	[XMIT_SZ_16BIT]		= 1,
-	[XMIT_SZ_32BIT]		= 2,
-	[XMIT_SZ_128BIT]	= 4,
-	[XMIT_SZ_256BIT]	= 5,
-};
-
-#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/freq.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/freq.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/freq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/freq.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,10 @@
 #define FRQCR0			0xffc80000
 #define FRQCR1			0xffc80004
 #define FRQMR1			0xffc80014
+#elif defined(CONFIG_CPU_SUBTYPE_SH7786)
+#define FRQCR0			0xffc40000
+#define FRQCR1			0xffc40004
+#define FRQMR1			0xffc40014
 #elif defined(CONFIG_CPU_SUBTYPE_SHX3)
 #define FRQCR			0xffc00014
 #else
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,28 +14,35 @@
 #define MMU_PTEL	0xFF000004	/* Page table entry register LOW */
 #define MMU_TTB		0xFF000008	/* Translation table base register */
 #define MMU_TEA		0xFF00000C	/* TLB Exception Address */
-#define MMU_PTEA	0xFF000034	/* Page table entry assistance register */
+#define MMU_PTEA	0xFF000034	/* PTE assistance register */
+#define MMU_PTEAEX	0xFF00007C	/* PTE ASID extension register */
 
 #define MMUCR		0xFF000010	/* MMU Control Register */
 
-#define MMU_ITLB_ADDRESS_ARRAY	0xF2000000
 #define MMU_UTLB_ADDRESS_ARRAY	0xF6000000
+#define MMU_UTLB_ADDRESS_ARRAY2	0xF6800000
 #define MMU_PAGE_ASSOC_BIT	0x80
 
 #define MMUCR_TI		(1<<2)
 
-#ifdef CONFIG_X2TLB
-#define MMUCR_ME		(1 << 7)
-#else
-#define MMUCR_ME		(0)
-#endif
-
 #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
 #define MMUCR_SE		(1 << 4)
 #else
 #define MMUCR_SE		(0)
 #endif
 
+#ifdef CONFIG_CPU_HAS_PTEAEX
+#define MMUCR_AEX		(1 << 6)
+#else
+#define MMUCR_AEX		(0)
+#endif
+
+#ifdef CONFIG_X2TLB
+#define MMUCR_ME		(1 << 7)
+#else
+#define MMUCR_ME		(0)
+#endif
+
 #ifdef CONFIG_SH_STORE_QUEUES
 #define MMUCR_SQMD		(1 << 9)
 #else
@@ -43,17 +50,7 @@
 #endif
 
 #define MMU_NTLB_ENTRIES	64
-#define MMU_CONTROL_INIT	(0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE)
-
-#define MMU_ITLB_DATA_ARRAY	0xF3000000
-#define MMU_UTLB_DATA_ARRAY	0xF7000000
-
-#define MMU_UTLB_ENTRIES	   64
-#define MMU_U_ENTRY_SHIFT	    8
-#define MMU_UTLB_VALID		0x100
-#define MMU_ITLB_ENTRIES	    4
-#define MMU_I_ENTRY_SHIFT	    8
-#define MMU_ITLB_VALID		0x100
+#define MMU_CONTROL_INIT	(0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE|MMUCR_AEX)
 
 #define TRA	0xff000020
 #define EXPEVT	0xff000024
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/sh7786.h linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/sh7786.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/cpu-sh4/cpu/sh7786.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/include/cpu-sh4/cpu/sh7786.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,136 @@
+/*
+ * SH7786 Pinmux
+ *
+ * Copyright (C) 2008, 2009  Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ *  Based on sh7785.h
+ *
+ * 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 __CPU_SH7786_H__
+#define __CPU_SH7786_H__
+
+enum {
+	/* PA */
+	GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+	GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+	/* PB */
+	GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+	GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+	/* PC */
+	GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+	GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+	/* PD */
+	GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+	GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+	/* PE */
+	GPIO_PE5, GPIO_PE4, GPIO_PE3, GPIO_PE2,
+	GPIO_PE1, GPIO_PE0,
+
+	/* PF */
+	GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+	GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+	/* PG */
+	GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
+	GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
+
+	/* PH */
+	GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
+	GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+
+	/* PJ */
+	GPIO_PJ7, GPIO_PJ6, GPIO_PJ5, GPIO_PJ4,
+	GPIO_PJ3, GPIO_PJ2, GPIO_PJ1, GPIO_PJ0,
+
+	/* DU */
+	GPIO_FN_DCLKIN, GPIO_FN_DCLKOUT, GPIO_FN_ODDF,
+	GPIO_FN_VSYNC, GPIO_FN_HSYNC, GPIO_FN_CDE, GPIO_FN_DISP,
+	GPIO_FN_DR0, GPIO_FN_DG0, GPIO_FN_DB0,
+	GPIO_FN_DR1, GPIO_FN_DG1, GPIO_FN_DB1,
+	GPIO_FN_DR2, GPIO_FN_DG2, GPIO_FN_DB2,
+	GPIO_FN_DR3, GPIO_FN_DG3, GPIO_FN_DB3,
+	GPIO_FN_DR4, GPIO_FN_DG4, GPIO_FN_DB4,
+	GPIO_FN_DR5, GPIO_FN_DG5, GPIO_FN_DB5,
+
+	/* Eth */
+	GPIO_FN_ETH_MAGIC, GPIO_FN_ETH_LINK, GPIO_FN_ETH_TX_ER,
+	GPIO_FN_ETH_TX_EN, GPIO_FN_ETH_MDIO, GPIO_FN_ETH_RX_CLK,
+	GPIO_FN_ETH_MDC, GPIO_FN_ETH_COL, GPIO_FN_ETH_TX_CLK,
+	GPIO_FN_ETH_CRS, GPIO_FN_ETH_RX_DV, GPIO_FN_ETH_RX_ER,
+	GPIO_FN_ETH_TXD3, GPIO_FN_ETH_TXD2, GPIO_FN_ETH_TXD1, GPIO_FN_ETH_TXD0,
+	GPIO_FN_ETH_RXD3, GPIO_FN_ETH_RXD2, GPIO_FN_ETH_RXD1, GPIO_FN_ETH_RXD0,
+
+	/* HSPI */
+	GPIO_FN_HSPI_CLK, GPIO_FN_HSPI_CS, GPIO_FN_HSPI_RX, GPIO_FN_HSPI_TX,
+
+	/* SCIF0 */
+	GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_SCK,
+	GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_TXD,
+
+	/* SCIF1 */
+	GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD,
+
+	/* SCIF3 */
+	GPIO_FN_SCIF3_SCK, GPIO_FN_SCIF3_RXD, GPIO_FN_SCIF3_TXD,
+
+	/* SCIF4 */
+	GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD,
+
+	/* SCIF5 */
+	GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD,
+
+	/* LBSC */
+	GPIO_FN_BREQ, GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+	/* FLCTL */
+	GPIO_FN_FALE, GPIO_FN_FRB, GPIO_FN_FSTATUS,
+	GPIO_FN_FSE, GPIO_FN_FCLE,
+
+	/* DMAC */
+	GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+	GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+	GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+	GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+	/* USB */
+	GPIO_FN_USB_OVC0, GPIO_FN_USB_PENC0,
+	GPIO_FN_USB_OVC1, GPIO_FN_USB_PENC1,
+
+	/* HAC */
+	GPIO_FN_HAC_RES,
+	GPIO_FN_HAC0_SDOUT, GPIO_FN_HAC0_SDIN,
+	GPIO_FN_HAC0_SYNC, GPIO_FN_HAC0_BITCLK,
+	GPIO_FN_HAC1_SDOUT, GPIO_FN_HAC1_SDIN,
+	GPIO_FN_HAC1_SYNC, GPIO_FN_HAC1_BITCLK,
+
+	/* SSI */
+	GPIO_FN_SSI0_SDATA, GPIO_FN_SSI0_SCK, GPIO_FN_SSI0_WS, GPIO_FN_SSI0_CLK,
+	GPIO_FN_SSI1_SDATA, GPIO_FN_SSI1_SCK, GPIO_FN_SSI1_WS, GPIO_FN_SSI1_CLK,
+	GPIO_FN_SSI2_SDATA, GPIO_FN_SSI2_SCK, GPIO_FN_SSI2_WS,
+	GPIO_FN_SSI3_SDATA, GPIO_FN_SSI3_SCK, GPIO_FN_SSI3_WS,
+
+	/* SDIF1 */
+	GPIO_FN_SDIF1CMD, GPIO_FN_SDIF1CD, GPIO_FN_SDIF1WP, GPIO_FN_SDIF1CLK,
+	GPIO_FN_SDIF1D3, GPIO_FN_SDIF1D2, GPIO_FN_SDIF1D1, GPIO_FN_SDIF1D0,
+
+	/* SDIF0 */
+	GPIO_FN_SDIF0CMD, GPIO_FN_SDIF0CD, GPIO_FN_SDIF0WP, GPIO_FN_SDIF0CLK,
+	GPIO_FN_SDIF0D3, GPIO_FN_SDIF0D2, GPIO_FN_SDIF0D1, GPIO_FN_SDIF0D0,
+
+	/* TMU */
+	GPIO_FN_TCLK,
+
+	/* INTC */
+	GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4,
+};
+
+#endif /* __CPU_SH7786_H__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/include/mach-common/mach/urquell.h linux-libre-2.6.30-gnu1/arch/sh/include/mach-common/mach/urquell.h
--- linux-libre-2.6.29-gnu1/arch/sh/include/mach-common/mach/urquell.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/include/mach-common/mach/urquell.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,68 @@
+#ifndef __MACH_URQUELL_H
+#define __MACH_URQUELL_H
+
+/*
+ * ------ 0x00000000 ------------------------------------
+ *  CS0 | (SW1,SW47)    EEPROM, SRAM, NOR FLASH
+ * -----+ 0x04000000 ------------------------------------
+ *  CS1 | (SW47)        SRAM, SRAM-LAN-PCMCIA, NOR FLASH
+ * -----+ 0x08000000 ------------------------------------
+ *  CS2 |               DDR3
+ *  CS3 |
+ * -----+ 0x10000000 ------------------------------------
+ *  CS4 |               PCIe
+ * -----+ 0x14000000 ------------------------------------
+ *  CS5 | (SW47)        LRAM/URAM, SRAM-LAN-PCMCIA
+ * -----+ 0x18000000 ------------------------------------
+ *  CS6 |               ATA, NAND FLASH
+ * -----+ 0x1c000000 ------------------------------------
+ *  CS7 |               SH7786 register
+ * -----+------------------------------------------------
+ */
+
+#define NOR_FLASH_ADDR	0x00000000
+#define NOR_FLASH_SIZE	0x04000000
+
+#define CS1_BASE	0x05000000
+#define CS5_BASE	0x15000000
+#define FPGA_BASE	CS1_BASE
+
+#define BOARDREG(ofs)	(FPGA_BASE + ofs##_OFS)
+#define UBOARDREG(ofs)	(0xa0000000 + FPGA_BASE + ofs##_OFS)
+
+#define SRSTR_OFS	0x0000 /* System reset register */
+#define BDMR_OFS	0x0010 /* Board operating mode resister */
+#define IRL0SR_OFS	0x0020 /* IRL0 Status register */
+#define IRL0MSKR_OFS	0x0030 /* IRL0 Mask register */
+#define IRL1SR_OFS	0x0040 /* IRL1 Status register */
+#define IRL1MSKR_OFS	0x0050 /* IRL1 Mask register */
+#define IRL2SR_OFS	0x0060 /* IRL2 Status register */
+#define IRL2MSKR_OFS	0x0070 /* IRL2 Mask register */
+#define IRL3SR_OFS	0x0080 /* IRL3 Status register */
+#define IRL3MSKR_OFS	0x0090 /* IRL3 Mask register */
+#define SOFTINTR_OFS	0x0120 /* Softwear Interrupt register */
+#define SLEDR_OFS	0x0130 /* LED control resister */
+#define MAPSCIFSWR_OFS	0x0140 /* Map/SCIF Switch register */
+#define FPVERR_OFS	0x0150 /* FPGA Version register */
+#define FPDATER_OFS	0x0160 /* FPGA Date register */
+#define FPYEARR_OFS	0x0170 /* FPGA Year register */
+#define TCLKCR_OFS	0x0180 /* TCLK Control register */
+#define DIPSWMR_OFS	0x1000 /* DIPSW monitor register */
+#define FPODR_OFS	0x1010 /* Output port data register */
+#define ATACNR_OFS	0x1020 /* ATA-CN Control/status register */
+#define FPINDR_OFS	0x1030 /* Input port data register */
+#define MDSWMR_OFS	0x1040 /* MODE SW monitor register */
+#define DDR3BUPCR_OFS	0x1050 /* DDR3 Backup control register */
+#define SSICODECCR_OFS	0x1060 /* SSI-CODEC control register */
+#define PCIESLOTSR_OFS	0x1070 /* PCIexpress Slot status register */
+#define ETHERPORTSR_OFS	0x1080 /* EtherPhy Port status register */
+#define LATCHCR_OFS	0x3000 /* Latch control register */
+#define LATCUAR_OFS	0x3010 /* Latch upper address register */
+#define LATCLAR_OFS	0x3012 /* Latch lower address register */
+#define LATCLUDR_OFS	0x3024 /* Latch D31-16 register */
+#define LATCLLDR_OFS	0x3026 /* Latch D15-0 register */
+
+#define CHARLED_OFS	0x2000 /* Character LED */
+
+#endif  /* __MACH_URQUELL_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/Kconfig linux-libre-2.6.30-gnu1/arch/sh/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@ config SUPERH
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_DMA_API_DEBUG
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
@@ -21,16 +22,17 @@ config SUPERH
 	  <http://www.linux-sh.org/>.
 
 config SUPERH32
-	def_bool !SUPERH64
+	def_bool ARCH = "sh"
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_ARCH_KGDB
+	select ARCH_HIBERNATION_POSSIBLE if MMU
 
 config SUPERH64
-	def_bool y if CPU_SH5
+	def_bool ARCH = "sh64"
 
 config ARCH_DEFCONFIG
 	string
@@ -107,6 +109,9 @@ config SYS_SUPPORTS_NUMA
 config SYS_SUPPORTS_PCI
 	bool
 
+config SYS_SUPPORTS_CMT
+	bool
+
 config STACKTRACE_SUPPORT
 	def_bool y
 
@@ -126,6 +131,9 @@ config ARCH_HAS_ILOG2_U64
 config ARCH_NO_VIRT_TO_BUS
 	def_bool y
 
+config ARCH_HAS_DEFAULT_IDLE
+	def_bool y
+
 config IO_TRAPPED
 	bool
 
@@ -176,6 +184,12 @@ config CPU_SHX2
 config CPU_SHX3
 	bool
 
+config ARCH_SHMOBILE
+	bool
+	select ARCH_SUSPEND_POSSIBLE
+
+if SUPERH32
+
 choice
 	prompt "Processor sub-type selection"
 
@@ -188,6 +202,7 @@ choice
 config CPU_SUBTYPE_SH7619
 	bool "Support SH7619 processor"
 	select CPU_SH2
+	select SYS_SUPPORTS_CMT
 
 # SH-2A Processor Support
 
@@ -200,15 +215,18 @@ config CPU_SUBTYPE_SH7203
 	bool "Support SH7203 processor"
 	select CPU_SH2A
 	select CPU_HAS_FPU
+	select SYS_SUPPORTS_CMT
 
 config CPU_SUBTYPE_SH7206
 	bool "Support SH7206 processor"
 	select CPU_SH2A
+	select SYS_SUPPORTS_CMT
 
 config CPU_SUBTYPE_SH7263
 	bool "Support SH7263 processor"
 	select CPU_SH2A
 	select CPU_HAS_FPU
+	select SYS_SUPPORTS_CMT
 
 config CPU_SUBTYPE_MXG
 	bool "Support MX-G processor"
@@ -323,7 +341,9 @@ config CPU_SUBTYPE_SH7723
 	bool "Support SH7723 processor"
 	select CPU_SH4A
 	select CPU_SHX2
+	select ARCH_SHMOBILE
 	select ARCH_SPARSEMEM_ENABLE
+	select SYS_SUPPORTS_CMT
 	help
 	  Select SH7723 if you have an SH-MobileR2 CPU.
 
@@ -348,6 +368,14 @@ config CPU_SUBTYPE_SH7785
 	select ARCH_SPARSEMEM_ENABLE
 	select SYS_SUPPORTS_NUMA
 
+config CPU_SUBTYPE_SH7786
+	bool "Support SH7786 processor"
+	select CPU_SH4A
+	select CPU_SHX3
+	select CPU_HAS_PTEAEX
+	select ARCH_SPARSEMEM_ENABLE
+	select SYS_SUPPORTS_NUMA
+
 config CPU_SUBTYPE_SHX3
 	bool "Support SH-X3 processor"
 	select CPU_SH4A
@@ -362,20 +390,35 @@ config CPU_SUBTYPE_SHX3
 config CPU_SUBTYPE_SH7343
 	bool "Support SH7343 processor"
 	select CPU_SH4AL_DSP
+	select ARCH_SHMOBILE
+	select SYS_SUPPORTS_CMT
 
 config CPU_SUBTYPE_SH7722
 	bool "Support SH7722 processor"
 	select CPU_SH4AL_DSP
 	select CPU_SHX2
+	select ARCH_SHMOBILE
 	select ARCH_SPARSEMEM_ENABLE
 	select SYS_SUPPORTS_NUMA
+	select SYS_SUPPORTS_CMT
 
 config CPU_SUBTYPE_SH7366
 	bool "Support SH7366 processor"
 	select CPU_SH4AL_DSP
 	select CPU_SHX2
+	select ARCH_SHMOBILE
 	select ARCH_SPARSEMEM_ENABLE
 	select SYS_SUPPORTS_NUMA
+	select SYS_SUPPORTS_CMT
+
+endchoice
+
+endif
+
+if SUPERH64
+
+choice
+	prompt "Processor sub-type selection"
 
 # SH-5 Processor Support
 
@@ -389,6 +432,8 @@ config CPU_SUBTYPE_SH5_103
 
 endchoice
 
+endif
+
 source "arch/sh/mm/Kconfig"
  
 source "arch/sh/Kconfig.cpu"
@@ -398,25 +443,34 @@ source "arch/sh/boards/Kconfig"
 menu "Timer and clock configuration"
 
 config SH_TMU
-	def_bool y
-	prompt "TMU timer support"
+	bool "TMU timer support"
 	depends on CPU_SH3 || CPU_SH4
+	default y
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	help
 	  This enables the use of the TMU as the system timer.
 
 config SH_CMT
-	def_bool y
-	prompt "CMT timer support"
-	depends on CPU_SH2 && !CPU_SUBTYPE_MXG
+	bool "CMT timer support"
+	depends on SYS_SUPPORTS_CMT && CPU_SH2
+	default y
 	help
 	  This enables the use of the CMT as the system timer.
 
+#
+# Support for the new-style CMT driver. This will replace SH_CMT
+# once its other dependencies are merged.
+#
+config SH_TIMER_CMT
+	bool "CMT clockevents driver"
+	depends on SYS_SUPPORTS_CMT && !SH_CMT
+	select GENERIC_CLOCKEVENTS
+
 config SH_MTU2
-	def_bool n
-	prompt "MTU2 timer support"
+	bool "MTU2 timer support"
 	depends on CPU_SH2A
+	default y
 	help
 	  This enables the use of the MTU2 as the system timer.
 
@@ -426,7 +480,8 @@ config SH_TIMER_IRQ
 			CPU_SUBTYPE_SH7763
 	default "86" if CPU_SUBTYPE_SH7619
 	default "140" if CPU_SUBTYPE_SH7206
-	default "142" if CPU_SUBTYPE_SH7203
+	default "142" if CPU_SUBTYPE_SH7203 && SH_CMT
+	default "153" if CPU_SUBTYPE_SH7203 && SH_MTU2
 	default "238" if CPU_SUBTYPE_MXG
 	default "16"
 
@@ -438,7 +493,8 @@ config SH_PCLK_FREQ
 	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_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"
@@ -492,7 +548,7 @@ source kernel/Kconfig.hz
 
 config KEXEC
 	bool "kexec system call (EXPERIMENTAL)"
-	depends on SUPERH32 && EXPERIMENTAL
+	depends on SUPERH32 && EXPERIMENTAL && MMU
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
@@ -521,6 +577,13 @@ config CRASH_DUMP
 
 	  For more details see Documentation/kdump/kdump.txt
 
+config KEXEC_JUMP
+	bool "kexec jump (EXPERIMENTAL)"
+	depends on SUPERH32 && KEXEC && HIBERNATION && EXPERIMENTAL
+	help
+	  Jump between original kernel and kexeced kernel and invoke
+	  code via KEXEC
+
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
@@ -595,10 +658,10 @@ config GUSA_RB
 	depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A)
 	help
 	  Enabling this option will allow the kernel to implement some
-	  atomic operations using a software implemention of load-locked/
+	  atomic operations using a software implementation of load-locked/
 	  store-conditional (LLSC). On machines which do not have hardware
 	  LLSC, this should be more efficient than the other alternative of
-	  disabling insterrupts around the atomic sequence.
+	  disabling interrupts around the atomic sequence.
 
 endmenu
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/Kconfig.cpu linux-libre-2.6.30-gnu1/arch/sh/Kconfig.cpu
--- linux-libre-2.6.29-gnu1/arch/sh/Kconfig.cpu	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/Kconfig.cpu	2009-06-09 23:05:27.000000000 -0400
@@ -104,6 +104,9 @@ config CPU_HAS_SR_RB
 config CPU_HAS_PTEA
 	bool
 
+config CPU_HAS_PTEAEX
+	bool
+
 config CPU_HAS_DSP
 	bool
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/asm-offsets.c linux-libre-2.6.30-gnu1/arch/sh/kernel/asm-offsets.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/asm-offsets.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/asm-offsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,8 +12,10 @@
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/kbuild.h>
+#include <linux/suspend.h>
 
 #include <asm/thread_info.h>
+#include <asm/suspend.h>
 
 int main(void)
 {
@@ -25,5 +27,11 @@ int main(void)
 	DEFINE(TI_PRE_COUNT,	offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
 
+#ifdef CONFIG_HIBERNATION
+	DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
+	DEFINE(PBE_ORIG_ADDRESS, offsetof(struct pbe, orig_address));
+	DEFINE(PBE_NEXT, offsetof(struct pbe, next));
+	DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
+#endif
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/clock.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/clock.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,8 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/kref.h>
+#include <linux/kobject.h>
+#include <linux/sysdev.h>
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
@@ -239,6 +241,35 @@ void clk_recalc_rate(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_recalc_rate);
 
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -EINVAL;
+	struct clk *old;
+
+	if (!parent || !clk)
+		return ret;
+
+	old = clk->parent;
+	if (likely(clk->ops && clk->ops->set_parent)) {
+		unsigned long flags;
+		spin_lock_irqsave(&clock_lock, flags);
+		ret = clk->ops->set_parent(clk, parent);
+		spin_unlock_irqrestore(&clock_lock, flags);
+		clk->parent = (ret ? old : parent);
+	}
+
+	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+		propagate_rate(clk);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	if (likely(clk->ops && clk->ops->round_rate)) {
@@ -329,6 +360,70 @@ static int show_clocks(char *buf, char *
 	return p - buf;
 }
 
+#ifdef CONFIG_PM
+static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
+{
+	static pm_message_t prev_state;
+	struct clk *clkp;
+
+	switch (state.event) {
+	case PM_EVENT_ON:
+		/* Resumeing from hibernation */
+		if (prev_state.event == PM_EVENT_FREEZE) {
+			list_for_each_entry(clkp, &clock_list, node)
+				if (likely(clkp->ops)) {
+					unsigned long rate = clkp->rate;
+
+					if (likely(clkp->ops->set_parent))
+						clkp->ops->set_parent(clkp,
+							clkp->parent);
+					if (likely(clkp->ops->set_rate))
+						clkp->ops->set_rate(clkp,
+							rate, NO_CHANGE);
+					else if (likely(clkp->ops->recalc))
+						clkp->ops->recalc(clkp);
+					}
+		}
+		break;
+	case PM_EVENT_FREEZE:
+		break;
+	case PM_EVENT_SUSPEND:
+		break;
+	}
+
+	prev_state = state;
+	return 0;
+}
+
+static int clks_sysdev_resume(struct sys_device *dev)
+{
+	return clks_sysdev_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_class clks_sysdev_class = {
+	.name = "clks",
+};
+
+static struct sysdev_driver clks_sysdev_driver = {
+	.suspend = clks_sysdev_suspend,
+	.resume = clks_sysdev_resume,
+};
+
+static struct sys_device clks_sysdev_dev = {
+	.cls = &clks_sysdev_class,
+};
+
+static int __init clk_sysdev_init(void)
+{
+	sysdev_class_register(&clks_sysdev_class);
+	sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
+	sysdev_register(&clks_sysdev_dev);
+
+	return 0;
+}
+subsys_initcall(clk_sysdev_init);
+#endif
+
 int __init clk_init(void)
 {
 	int i, ret = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/Makefile linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_SH5)		= sh5/
 # Special cases for family ancestry.
 
 obj-$(CONFIG_CPU_SH4A)		+= sh4a/
+obj-$(CONFIG_ARCH_SHMOBILE)	+= shmobile/
 
 # Common interfaces.
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  * SH7619 Setup
  *
  *  Copyright (C) 2006  Yoshinori Sato
+ *  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
@@ -18,15 +19,10 @@ enum {
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
 	WDT, EDMAC, CMT0, CMT1,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
-	SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
+	SCIF0, SCIF1, SCIF2,
 	HIF_HIFI, HIF_HIFBI,
 	DMAC0, DMAC1, DMAC2, DMAC3,
 	SIOF,
-
-	/* interrupt groups */
-	SCIF0, SCIF1, SCIF2,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -36,24 +32,18 @@ static struct intc_vect vectors[] __init
 	INTC_IRQ(IRQ6, 82), INTC_IRQ(IRQ7, 83),
 	INTC_IRQ(WDT, 84), INTC_IRQ(EDMAC, 85),
 	INTC_IRQ(CMT0, 86), INTC_IRQ(CMT1, 87),
-	INTC_IRQ(SCIF0_ERI, 88), INTC_IRQ(SCIF0_RXI, 89),
-	INTC_IRQ(SCIF0_BRI, 90), INTC_IRQ(SCIF0_TXI, 91),
-	INTC_IRQ(SCIF1_ERI, 92), INTC_IRQ(SCIF1_RXI, 93),
-	INTC_IRQ(SCIF1_BRI, 94), INTC_IRQ(SCIF1_TXI, 95),
-	INTC_IRQ(SCIF2_ERI, 96), INTC_IRQ(SCIF2_RXI, 97),
-	INTC_IRQ(SCIF2_BRI, 98), INTC_IRQ(SCIF2_TXI, 99),
+	INTC_IRQ(SCIF0, 88), INTC_IRQ(SCIF0, 89),
+	INTC_IRQ(SCIF0, 90), INTC_IRQ(SCIF0, 91),
+	INTC_IRQ(SCIF1, 92), INTC_IRQ(SCIF1, 93),
+	INTC_IRQ(SCIF1, 94), INTC_IRQ(SCIF1, 95),
+	INTC_IRQ(SCIF2, 96), INTC_IRQ(SCIF2, 97),
+	INTC_IRQ(SCIF2, 98), INTC_IRQ(SCIF2, 99),
 	INTC_IRQ(HIF_HIFI, 100), INTC_IRQ(HIF_HIFBI, 101),
 	INTC_IRQ(DMAC0, 104), INTC_IRQ(DMAC1, 105),
 	INTC_IRQ(DMAC2, 106), INTC_IRQ(DMAC3, 107),
 	INTC_IRQ(SIOF, 108),
 };
 
-static struct intc_group groups[] __initdata = {
-	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),
-};
-
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ 0xf8140006, 0, 16, 4, /* IPRA */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
 	{ 0xf8140008, 0, 16, 4, /* IPRB */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
@@ -64,7 +54,7 @@ static struct intc_prio_reg prio_registe
 	{ 0xf8080008, 0, 16, 4, /* IPRG */ { SIOF } },
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
 static struct plat_sci_port sci_platform_data[] = {
@@ -72,17 +62,17 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xf8400000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 88, 89, 91, 90},
+		.irqs		= { 88, 88, 88, 88 },
 	}, {
 		.mapbase	= 0xf8410000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 92, 93, 95, 94},
+		.irqs		= { 92, 92, 92, 92 },
 	}, {
 		.mapbase	= 0xf8420000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 96, 97, 99, 98},
+		.irqs		= { 96, 96, 96, 96 },
 	}, {
 		.flags = 0,
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-mxg.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Renesas MX-G (R8A03022BG) Setup
  *
- *  Copyright (C) 2008  Paul Mundt
+ *  Copyright (C) 2008, 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
@@ -20,23 +20,15 @@ enum {
 	IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15,
 
 	PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
-
 	SINT8, SINT7, SINT6, SINT5, SINT4, SINT3, SINT2, SINT1,
 
-	SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
-	SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
+	SCIF0, SCIF1,
 
-	MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
-	MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
-	MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
-	MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
-	MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
-	MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
-	MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
+	MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+	MTU2_TGI3B, MTU2_TGI3C,
 
 	/* interrupt groups */
-	PINT, SCIF0, SCIF1,
-	MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+	PINT,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -59,47 +51,36 @@ static struct intc_vect vectors[] __init
 	INTC_IRQ(SINT4, 98), INTC_IRQ(SINT3, 99),
 	INTC_IRQ(SINT2, 100), INTC_IRQ(SINT1, 101),
 
-	INTC_IRQ(SCIF0_RXI, 220), INTC_IRQ(SCIF0_TXI, 221),
-	INTC_IRQ(SCIF0_BRI, 222), INTC_IRQ(SCIF0_ERI, 223),
-	INTC_IRQ(SCIF1_RXI, 224), INTC_IRQ(SCIF1_TXI, 225),
-	INTC_IRQ(SCIF1_BRI, 226), INTC_IRQ(SCIF1_ERI, 227),
+	INTC_IRQ(SCIF0, 220), INTC_IRQ(SCIF0, 221),
+	INTC_IRQ(SCIF0, 222), INTC_IRQ(SCIF0, 223),
+	INTC_IRQ(SCIF1, 224), INTC_IRQ(SCIF1, 225),
+	INTC_IRQ(SCIF1, 226), INTC_IRQ(SCIF1, 227),
 
-	INTC_IRQ(MTU2_TGI0A, 228), INTC_IRQ(MTU2_TGI0B, 229),
-	INTC_IRQ(MTU2_TGI0C, 230), INTC_IRQ(MTU2_TGI0D, 231),
-	INTC_IRQ(MTU2_TCI0V, 232), INTC_IRQ(MTU2_TGI0E, 233),
+	INTC_IRQ(MTU2_GROUP1, 228), INTC_IRQ(MTU2_GROUP1, 229),
+	INTC_IRQ(MTU2_GROUP1, 230), INTC_IRQ(MTU2_GROUP1, 231),
+	INTC_IRQ(MTU2_GROUP1, 232), INTC_IRQ(MTU2_GROUP1, 233),
 
-	INTC_IRQ(MTU2_TGI0F, 234), INTC_IRQ(MTU2_TGI1A, 235),
-	INTC_IRQ(MTU2_TGI1B, 236), INTC_IRQ(MTU2_TCI1V, 237),
-	INTC_IRQ(MTU2_TCI1U, 238), INTC_IRQ(MTU2_TGI2A, 239),
+	INTC_IRQ(MTU2_GROUP2, 234), INTC_IRQ(MTU2_GROUP2, 235),
+	INTC_IRQ(MTU2_GROUP2, 236), INTC_IRQ(MTU2_GROUP2, 237),
+	INTC_IRQ(MTU2_GROUP2, 238), INTC_IRQ(MTU2_GROUP2, 239),
 
-	INTC_IRQ(MTU2_TGI2B, 240), INTC_IRQ(MTU2_TCI2V, 241),
-	INTC_IRQ(MTU2_TCI2U, 242), INTC_IRQ(MTU2_TGI3A, 243),
+	INTC_IRQ(MTU2_GROUP3, 240), INTC_IRQ(MTU2_GROUP3, 241),
+	INTC_IRQ(MTU2_GROUP3, 242), INTC_IRQ(MTU2_GROUP3, 243),
 
 	INTC_IRQ(MTU2_TGI3B, 244),
 	INTC_IRQ(MTU2_TGI3C, 245),
 
-	INTC_IRQ(MTU2_TGI3D, 246), INTC_IRQ(MTU2_TCI3V, 247),
-	INTC_IRQ(MTU2_TGI4A, 248), INTC_IRQ(MTU2_TGI4B, 249),
-	INTC_IRQ(MTU2_TGI4C, 250), INTC_IRQ(MTU2_TGI4D, 251),
+	INTC_IRQ(MTU2_GROUP4, 246), INTC_IRQ(MTU2_GROUP4, 247),
+	INTC_IRQ(MTU2_GROUP4, 248), INTC_IRQ(MTU2_GROUP4, 249),
+	INTC_IRQ(MTU2_GROUP4, 250), INTC_IRQ(MTU2_GROUP4, 251),
 
-	INTC_IRQ(MTU2_TCI4V, 252), INTC_IRQ(MTU2_TGI5U, 253),
-	INTC_IRQ(MTU2_TGI5V, 254), INTC_IRQ(MTU2_TGI5W, 255),
+	INTC_IRQ(MTU2_GROUP5, 252), INTC_IRQ(MTU2_GROUP5, 253),
+	INTC_IRQ(MTU2_GROUP5, 254), INTC_IRQ(MTU2_GROUP5, 255),
 };
 
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
 		   PINT4, PINT5, PINT6, PINT7),
-	INTC_GROUP(MTU2_GROUP1, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
-		   MTU2_TCI0V, MTU2_TGI0E),
-	INTC_GROUP(MTU2_GROUP2, MTU2_TGI0F, MTU2_TGI1A, MTU2_TGI1B,
-		   MTU2_TCI1V, MTU2_TCI1U, MTU2_TGI2A),
-	INTC_GROUP(MTU2_GROUP3, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
-		   MTU2_TGI3A),
-	INTC_GROUP(MTU2_GROUP4, MTU2_TGI3D, MTU2_TCI3V, MTU2_TGI4A,
-		   MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
-	INTC_GROUP(MTU2_GROUP5, MTU2_TCI4V, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
-	INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -137,7 +118,7 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xff804000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 223, 220, 221, 222 },
+		.irqs		= { 220, 220, 220, 220 },
 	}, {
 		.flags = 0,
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7201.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  *  SH7201 setup
  *
  *  Copyright (C) 2008  Peter Griffin pgriffin@mpc-data.co.uk
+ *  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
@@ -18,57 +19,32 @@ enum {
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
 	PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
+
 	ADC_ADI,
-	MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
-	MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
-	MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
-	MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
-	MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
-	MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
-	MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
-	RTC_ARM, RTC_PRD, RTC_CUP,
-	WDT,
-	IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
-	IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
-	IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
+
+	MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
+	MTU23_ABCD, MTU24_ABCD, MTU25_UVW, MTU2_TCI3V, MTU2_TCI4V,
+
+	RTC, WDT,
+
+	IIC30, IIC31, IIC32,
 
 	DMAC0_DMINT0, DMAC1_DMINT1,
 	DMAC2_DMINT2, DMAC3_DMINT3,
 
-	SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
-	SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
-	SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
-	SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
-	SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI,
-	SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI,
-	SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI,
-	SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI,
+	SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
 
 	DMAC0_DMINTA, DMAC4_DMINT4, DMAC5_DMINT5, DMAC6_DMINT6,
 	DMAC7_DMINT7,
 
-	RCAN0_ERS, RCAN0_OVR,
-	RCAN0_SLE,
-	RCAN0_RM0, RCAN0_RM1,
-
-	RCAN1_ERS, RCAN1_OVR,
-	RCAN1_SLE,
-	RCAN1_RM0, RCAN1_RM1,
+	RCAN0, RCAN1,
 
 	SSI0_SSII, SSI1_SSII,
 
-	TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0,
-	TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1,
+	TMR0, TMR1,
 
 	/* interrupt groups */
-
-	IRQ, PINT, ADC,
-	MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
-	MTU23_ABCD, MTU24_ABCD, MTU25_UVW,
-	RTC, IIC30, IIC31, IIC32,
-	SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
-	RCAN0, RCAN1, TMR0, TMR1
-
+	PINT,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -76,6 +52,7 @@ static struct intc_vect vectors[] __init
 	INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
 	INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
 	INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
+
 	INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
 	INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
 	INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
@@ -83,123 +60,92 @@ static struct intc_vect vectors[] __init
 
 	INTC_IRQ(ADC_ADI, 92),
 
-	INTC_IRQ(MTU2_TGI0A, 108), INTC_IRQ(MTU2_TGI0B, 109),
-	INTC_IRQ(MTU2_TGI0C, 110), INTC_IRQ(MTU2_TGI0D, 111),
-	INTC_IRQ(MTU2_TCI0V, 112),
-	INTC_IRQ(MTU2_TGI0E, 113), INTC_IRQ(MTU2_TGI0F, 114),
+	INTC_IRQ(MTU20_ABCD, 108), INTC_IRQ(MTU20_ABCD, 109),
+	INTC_IRQ(MTU20_ABCD, 110), INTC_IRQ(MTU20_ABCD, 111),
 
-	INTC_IRQ(MTU2_TGI1A, 116), INTC_IRQ(MTU2_TGI1B, 117),
-	INTC_IRQ(MTU2_TCI1V, 120), INTC_IRQ(MTU2_TCI1U, 121),
+	INTC_IRQ(MTU20_VEF, 112), INTC_IRQ(MTU20_VEF, 113),
+	INTC_IRQ(MTU20_VEF, 114),
 
-	INTC_IRQ(MTU2_TGI2A, 124), INTC_IRQ(MTU2_TGI2B, 125),
-	INTC_IRQ(MTU2_TCI2V, 128), INTC_IRQ(MTU2_TCI2U, 129),
+	INTC_IRQ(MTU21_AB, 116), INTC_IRQ(MTU21_AB, 117),
+	INTC_IRQ(MTU21_VU, 120), INTC_IRQ(MTU21_VU, 121),
+
+	INTC_IRQ(MTU22_AB, 124), INTC_IRQ(MTU22_AB, 125),
+	INTC_IRQ(MTU22_VU, 128), INTC_IRQ(MTU22_VU, 129),
+
+	INTC_IRQ(MTU23_ABCD, 132), INTC_IRQ(MTU23_ABCD, 133),
+	INTC_IRQ(MTU23_ABCD, 134), INTC_IRQ(MTU23_ABCD, 135),
 
-	INTC_IRQ(MTU2_TGI3A, 132), INTC_IRQ(MTU2_TGI3B, 133),
-	INTC_IRQ(MTU2_TGI3C, 134), INTC_IRQ(MTU2_TGI3D, 135),
 	INTC_IRQ(MTU2_TCI3V, 136),
 
-	INTC_IRQ(MTU2_TGI4A, 140), INTC_IRQ(MTU2_TGI4B, 141),
-	INTC_IRQ(MTU2_TGI4C, 142), INTC_IRQ(MTU2_TGI4D, 143),
+	INTC_IRQ(MTU24_ABCD, 140), INTC_IRQ(MTU24_ABCD, 141),
+	INTC_IRQ(MTU24_ABCD, 142), INTC_IRQ(MTU24_ABCD, 143),
+
 	INTC_IRQ(MTU2_TCI4V, 144),
 
-	INTC_IRQ(MTU2_TGI5U, 148), INTC_IRQ(MTU2_TGI5V, 149),
-	INTC_IRQ(MTU2_TGI5W, 150),
+	INTC_IRQ(MTU25_UVW, 148), INTC_IRQ(MTU25_UVW, 149),
+	INTC_IRQ(MTU25_UVW, 150),
 
-	INTC_IRQ(RTC_ARM, 152), INTC_IRQ(RTC_PRD, 153),
-	INTC_IRQ(RTC_CUP, 154), INTC_IRQ(WDT, 156),
+	INTC_IRQ(RTC, 152), INTC_IRQ(RTC, 153),
+	INTC_IRQ(RTC, 154),
 
-	INTC_IRQ(IIC30_STPI, 157), INTC_IRQ(IIC30_NAKI, 158),
-	INTC_IRQ(IIC30_RXI, 159), INTC_IRQ(IIC30_TXI, 160),
-	INTC_IRQ(IIC30_TEI, 161),
+	INTC_IRQ(WDT, 156),
 
-	INTC_IRQ(IIC31_STPI, 164), INTC_IRQ(IIC31_NAKI, 165),
-	INTC_IRQ(IIC31_RXI, 166), INTC_IRQ(IIC31_TXI, 167),
-	INTC_IRQ(IIC31_TEI, 168),
+	INTC_IRQ(IIC30, 157), INTC_IRQ(IIC30, 158),
+	INTC_IRQ(IIC30, 159), INTC_IRQ(IIC30, 160),
+	INTC_IRQ(IIC30, 161),
 
-	INTC_IRQ(IIC32_STPI, 170), INTC_IRQ(IIC32_NAKI, 171),
-	INTC_IRQ(IIC32_RXI, 172), INTC_IRQ(IIC32_TXI, 173),
-	INTC_IRQ(IIC32_TEI, 174),
+	INTC_IRQ(IIC31, 164), INTC_IRQ(IIC31, 165),
+	INTC_IRQ(IIC31, 166), INTC_IRQ(IIC31, 167),
+	INTC_IRQ(IIC31, 168),
+
+	INTC_IRQ(IIC32, 170), INTC_IRQ(IIC32, 171),
+	INTC_IRQ(IIC32, 172), INTC_IRQ(IIC32, 173),
+	INTC_IRQ(IIC32, 174),
 
 	INTC_IRQ(DMAC0_DMINT0, 176), INTC_IRQ(DMAC1_DMINT1, 177),
 	INTC_IRQ(DMAC2_DMINT2, 178), INTC_IRQ(DMAC3_DMINT3, 179),
 
-	INTC_IRQ(SCIF0_BRI, 180), INTC_IRQ(SCIF0_ERI, 181),
-	INTC_IRQ(SCIF0_RXI, 182), INTC_IRQ(SCIF0_TXI, 183),
-	INTC_IRQ(SCIF1_BRI, 184), INTC_IRQ(SCIF1_ERI, 185),
-	INTC_IRQ(SCIF1_RXI, 186), INTC_IRQ(SCIF1_TXI, 187),
-	INTC_IRQ(SCIF2_BRI, 188), INTC_IRQ(SCIF2_ERI, 189),
-	INTC_IRQ(SCIF2_RXI, 190), INTC_IRQ(SCIF2_TXI, 191),
-	INTC_IRQ(SCIF3_BRI, 192), INTC_IRQ(SCIF3_ERI, 193),
-	INTC_IRQ(SCIF3_RXI, 194), INTC_IRQ(SCIF3_TXI, 195),
-	INTC_IRQ(SCIF4_BRI, 196), INTC_IRQ(SCIF4_ERI, 197),
-	INTC_IRQ(SCIF4_RXI, 198), INTC_IRQ(SCIF4_TXI, 199),
-	INTC_IRQ(SCIF5_BRI, 200), INTC_IRQ(SCIF5_ERI, 201),
-	INTC_IRQ(SCIF5_RXI, 202), INTC_IRQ(SCIF5_TXI, 203),
-	INTC_IRQ(SCIF6_BRI, 204), INTC_IRQ(SCIF6_ERI, 205),
-	INTC_IRQ(SCIF6_RXI, 206), INTC_IRQ(SCIF6_TXI, 207),
-	INTC_IRQ(SCIF7_BRI, 208), INTC_IRQ(SCIF7_ERI, 209),
-	INTC_IRQ(SCIF7_RXI, 210), INTC_IRQ(SCIF7_TXI, 211),
+	INTC_IRQ(SCIF0, 180), INTC_IRQ(SCIF0, 181),
+	INTC_IRQ(SCIF0, 182), INTC_IRQ(SCIF0, 183),
+	INTC_IRQ(SCIF1, 184), INTC_IRQ(SCIF1, 185),
+	INTC_IRQ(SCIF1, 186), INTC_IRQ(SCIF1, 187),
+	INTC_IRQ(SCIF2, 188), INTC_IRQ(SCIF2, 189),
+	INTC_IRQ(SCIF2, 190), INTC_IRQ(SCIF2, 191),
+	INTC_IRQ(SCIF3, 192), INTC_IRQ(SCIF3, 193),
+	INTC_IRQ(SCIF3, 194), INTC_IRQ(SCIF3, 195),
+	INTC_IRQ(SCIF4, 196), INTC_IRQ(SCIF4, 197),
+	INTC_IRQ(SCIF4, 198), INTC_IRQ(SCIF4, 199),
+	INTC_IRQ(SCIF5, 200), INTC_IRQ(SCIF5, 201),
+	INTC_IRQ(SCIF5, 202), INTC_IRQ(SCIF5, 203),
+	INTC_IRQ(SCIF6, 204), INTC_IRQ(SCIF6, 205),
+	INTC_IRQ(SCIF6, 206), INTC_IRQ(SCIF6, 207),
+	INTC_IRQ(SCIF7, 208), INTC_IRQ(SCIF7, 209),
+	INTC_IRQ(SCIF7, 210), INTC_IRQ(SCIF7, 211),
 
 	INTC_IRQ(DMAC0_DMINTA, 212), INTC_IRQ(DMAC4_DMINT4, 216),
 	INTC_IRQ(DMAC5_DMINT5, 217), INTC_IRQ(DMAC6_DMINT6, 218),
 	INTC_IRQ(DMAC7_DMINT7, 219),
 
-	INTC_IRQ(RCAN0_ERS, 228), INTC_IRQ(RCAN0_OVR, 229),
-	INTC_IRQ(RCAN0_SLE, 230),
-	INTC_IRQ(RCAN0_RM0, 231), INTC_IRQ(RCAN0_RM1, 232),
+	INTC_IRQ(RCAN0, 228), INTC_IRQ(RCAN0, 229),
+	INTC_IRQ(RCAN0, 230),
+	INTC_IRQ(RCAN0, 231), INTC_IRQ(RCAN0, 232),
 
-	INTC_IRQ(RCAN1_ERS, 234), INTC_IRQ(RCAN1_OVR, 235),
-	INTC_IRQ(RCAN1_SLE, 236),
-	INTC_IRQ(RCAN1_RM0, 237), INTC_IRQ(RCAN1_RM1, 238),
+	INTC_IRQ(RCAN1, 234), INTC_IRQ(RCAN1, 235),
+	INTC_IRQ(RCAN1, 236),
+	INTC_IRQ(RCAN1, 237), INTC_IRQ(RCAN1, 238),
 
 	INTC_IRQ(SSI0_SSII, 244), INTC_IRQ(SSI1_SSII, 245),
 
-	INTC_IRQ(TMR0_CMIA0, 246), INTC_IRQ(TMR0_CMIB0, 247),
-	INTC_IRQ(TMR0_OVI0, 248),
-
-	INTC_IRQ(TMR1_CMIA1, 252), INTC_IRQ(TMR1_CMIB1, 253),
-	INTC_IRQ(TMR1_OVI1, 254),
+	INTC_IRQ(TMR0, 246), INTC_IRQ(TMR0, 247),
+	INTC_IRQ(TMR0, 248),
 
+	INTC_IRQ(TMR1, 252), INTC_IRQ(TMR1, 253),
+	INTC_IRQ(TMR1, 254),
 };
 
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
 		   PINT4, PINT5, PINT6, PINT7),
-	INTC_GROUP(MTU20_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
-	INTC_GROUP(MTU20_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
-
-	INTC_GROUP(MTU21_AB, MTU2_TGI1A, MTU2_TGI1B),
-	INTC_GROUP(MTU21_VU, MTU2_TCI1V, MTU2_TCI1U),
-	INTC_GROUP(MTU22_AB, MTU2_TGI2A, MTU2_TGI2B),
-	INTC_GROUP(MTU22_VU, MTU2_TCI2V, MTU2_TCI2U),
-	INTC_GROUP(MTU23_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
-	INTC_GROUP(MTU24_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
-	INTC_GROUP(MTU25_UVW, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
-	INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP ),
-
-	INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
-		   IIC30_TEI),
-	INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
-		   IIC31_TEI),
-	INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
-		   IIC32_TEI),
-
-	INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
-	INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
-	INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
-	INTC_GROUP(SCIF4, SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI),
-	INTC_GROUP(SCIF5, SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI),
-	INTC_GROUP(SCIF6, SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI),
-	INTC_GROUP(SCIF7, SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI),
-
-	INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
-		   RCAN0_SLE),
-	INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
-		   RCAN1_SLE),
-
-	INTC_GROUP(TMR0, TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0),
-	INTC_GROUP(TMR1, TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1),
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -212,7 +158,7 @@ static struct intc_prio_reg prio_registe
 
 	{ 0xfffe9806, 0, 16, 4, /* IPR09 */ { RTC, WDT, IIC30, 0 } },
 	{ 0xfffe9808, 0, 16, 4, /* IPR10 */ { IIC31, IIC32, DMAC0_DMINT0, DMAC1_DMINT1 } },
-	{ 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0 , SCIF1 } },
+	{ 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0, SCIF1 } },
 	{ 0xfffe980c, 0, 16, 4, /* IPR12 */ { SCIF2, SCIF3, SCIF4, SCIF5 } },
 	{ 0xfffe980e, 0, 16, 4, /* IPR13 */ { SCIF6, SCIF7, DMAC0_DMINTA, DMAC4_DMINT4  } },
 	{ 0xfffe9810, 0, 16, 4, /* IPR14 */ { DMAC5_DMINT5, DMAC6_DMINT6, DMAC7_DMINT7, 0 } },
@@ -234,42 +180,42 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xfffe8000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 181, 182, 183, 180}
+		.irqs		= { 180, 180, 180, 180 }
 	}, {
 		.mapbase	= 0xfffe8800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 185, 186, 187, 184}
+		.irqs		= { 184, 184, 184, 184 }
 	}, {
 		.mapbase	= 0xfffe9000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 189, 186, 187, 188}
+		.irqs		= { 188, 188, 188, 188 }
 	}, {
 		.mapbase	= 0xfffe9800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 193, 194, 195, 192}
+		.irqs		= { 192, 192, 192, 192 }
 	}, {
 		.mapbase	= 0xfffea000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 196, 198, 199, 196}
+		.irqs		= { 196, 196, 196, 196 }
 	}, {
 		.mapbase	= 0xfffea800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 201, 202, 203, 200}
+		.irqs		= { 200, 200, 200, 200 }
 	}, {
 		.mapbase	= 0xfffeb000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 205, 206, 207, 204}
+		.irqs		= { 204, 204, 204, 204 }
 	}, {
 		.mapbase	= 0xfffeb800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 209, 210, 211, 208}
+		.irqs		= { 208, 208, 208, 208 }
 	}, {
 		.flags = 0,
 	}
@@ -290,17 +236,7 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 153,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 154,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
+		/* Shared Period/Carry/Alarm IRQ */
 		.start	= 152,
 		.flags	= IORESOURCE_IRQ,
 	},
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7203.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * SH7203 and SH7263 Setup
  *
- *  Copyright (C) 2007  Paul Mundt
+ *  Copyright (C) 2007 - 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
@@ -18,50 +18,27 @@ enum {
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
 	PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
-	DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
-	DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
-	DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
-	DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
+	DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
 	USB, LCDC, CMT0, CMT1, BSC, WDT,
-	MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
-	MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
-	MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
-	MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
-	MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
-	MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
-	ADC_ADI,
-	IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
-	IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
-	IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
-	IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI, IIC33_TEI,
-	SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
-	SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
-	SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
-	SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
-	SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI,
-	SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI,
-	SSI0_SSII, SSI1_SSII, SSI2_SSII, SSI3_SSII,
 
-	/* ROM-DEC, SDHI, SRC, and IEB are SH7263 specific */
-	ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG, ROMDEC_ISEC, ROMDEC_IBUF,
-	ROMDEC_IREADY,
+	MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
+	MTU3_ABCD, MTU4_ABCD, MTU2_TCI3V, MTU2_TCI4V,
 
-	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+	ADC_ADI,
 
-	SDHI3, SDHI0, SDHI1,
+	IIC30, IIC31, IIC32, IIC33,
+	SCIF0, SCIF1, SCIF2, SCIF3,
 
-	RTC_ARM, RTC_PRD, RTC_CUP,
-	RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1, RCAN0_SLE,
-	RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1, RCAN1_SLE,
+	SSU0, SSU1,
 
-	SRC_OVF, SRC_ODFI, SRC_IDEI, IEBI,
+	SSI0_SSII, SSI1_SSII, SSI2_SSII, SSI3_SSII,
+
+	/* ROM-DEC, SDHI, SRC, and IEB are SH7263 specific */
+	ROMDEC, FLCTL, SDHI, RTC, RCAN0, RCAN1,
+	SRC, IEBI,
 
 	/* interrupt groups */
-	PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
-	MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
-	MTU3_ABCD, MTU4_ABCD,
-	IIC30, IIC31, IIC32, IIC33, SCIF0, SCIF1, SCIF2, SCIF3,
-	SSU0, SSU1, ROMDEC, SDHI, FLCTL, RTC, RCAN0, RCAN1, SRC
+	PINT,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -73,79 +50,80 @@ static struct intc_vect vectors[] __init
 	INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
 	INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
 	INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
-	INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
-	INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
-	INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
-	INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
-	INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
-	INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
-	INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
-	INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
+	INTC_IRQ(DMAC0, 108), INTC_IRQ(DMAC0, 109),
+	INTC_IRQ(DMAC1, 112), INTC_IRQ(DMAC1, 113),
+	INTC_IRQ(DMAC2, 116), INTC_IRQ(DMAC2, 117),
+	INTC_IRQ(DMAC3, 120), INTC_IRQ(DMAC3, 121),
+	INTC_IRQ(DMAC4, 124), INTC_IRQ(DMAC4, 125),
+	INTC_IRQ(DMAC5, 128), INTC_IRQ(DMAC5, 129),
+	INTC_IRQ(DMAC6, 132), INTC_IRQ(DMAC6, 133),
+	INTC_IRQ(DMAC7, 136), INTC_IRQ(DMAC7, 137),
 	INTC_IRQ(USB, 140), INTC_IRQ(LCDC, 141),
 	INTC_IRQ(CMT0, 142), INTC_IRQ(CMT1, 143),
 	INTC_IRQ(BSC, 144), INTC_IRQ(WDT, 145),
-	INTC_IRQ(MTU2_TGI0A, 146), INTC_IRQ(MTU2_TGI0B, 147),
-	INTC_IRQ(MTU2_TGI0C, 148), INTC_IRQ(MTU2_TGI0D, 149),
-	INTC_IRQ(MTU2_TCI0V, 150),
-	INTC_IRQ(MTU2_TGI0E, 151), INTC_IRQ(MTU2_TGI0F, 152),
-	INTC_IRQ(MTU2_TGI1A, 153), INTC_IRQ(MTU2_TGI1B, 154),
-	INTC_IRQ(MTU2_TCI1V, 155), INTC_IRQ(MTU2_TCI1U, 156),
-	INTC_IRQ(MTU2_TGI2A, 157), INTC_IRQ(MTU2_TGI2B, 158),
-	INTC_IRQ(MTU2_TCI2V, 159), INTC_IRQ(MTU2_TCI2U, 160),
-	INTC_IRQ(MTU2_TGI3A, 161), INTC_IRQ(MTU2_TGI3B, 162),
-	INTC_IRQ(MTU2_TGI3C, 163), INTC_IRQ(MTU2_TGI3D, 164),
+	INTC_IRQ(MTU0_ABCD, 146), INTC_IRQ(MTU0_ABCD, 147),
+	INTC_IRQ(MTU0_ABCD, 148), INTC_IRQ(MTU0_ABCD, 149),
+	INTC_IRQ(MTU0_VEF, 150),
+	INTC_IRQ(MTU0_VEF, 151), INTC_IRQ(MTU0_VEF, 152),
+	INTC_IRQ(MTU1_AB, 153), INTC_IRQ(MTU1_AB, 154),
+	INTC_IRQ(MTU1_VU, 155), INTC_IRQ(MTU1_VU, 156),
+	INTC_IRQ(MTU2_AB, 157), INTC_IRQ(MTU2_AB, 158),
+	INTC_IRQ(MTU2_VU, 159), INTC_IRQ(MTU2_VU, 160),
+	INTC_IRQ(MTU3_ABCD, 161), INTC_IRQ(MTU3_ABCD, 162),
+	INTC_IRQ(MTU3_ABCD, 163), INTC_IRQ(MTU3_ABCD, 164),
 	INTC_IRQ(MTU2_TCI3V, 165),
-	INTC_IRQ(MTU2_TGI4A, 166), INTC_IRQ(MTU2_TGI4B, 167),
-	INTC_IRQ(MTU2_TGI4C, 168), INTC_IRQ(MTU2_TGI4D, 169),
+	INTC_IRQ(MTU4_ABCD, 166), INTC_IRQ(MTU4_ABCD, 167),
+	INTC_IRQ(MTU4_ABCD, 168), INTC_IRQ(MTU4_ABCD, 169),
 	INTC_IRQ(MTU2_TCI4V, 170),
 	INTC_IRQ(ADC_ADI, 171),
-	INTC_IRQ(IIC30_STPI, 172), INTC_IRQ(IIC30_NAKI, 173),
-	INTC_IRQ(IIC30_RXI, 174), INTC_IRQ(IIC30_TXI, 175),
-	INTC_IRQ(IIC30_TEI, 176),
-	INTC_IRQ(IIC31_STPI, 177), INTC_IRQ(IIC31_NAKI, 178),
-	INTC_IRQ(IIC31_RXI, 179), INTC_IRQ(IIC31_TXI, 180),
-	INTC_IRQ(IIC31_TEI, 181),
-	INTC_IRQ(IIC32_STPI, 182), INTC_IRQ(IIC32_NAKI, 183),
-	INTC_IRQ(IIC32_RXI, 184), INTC_IRQ(IIC32_TXI, 185),
-	INTC_IRQ(IIC32_TEI, 186),
-	INTC_IRQ(IIC33_STPI, 187), INTC_IRQ(IIC33_NAKI, 188),
-	INTC_IRQ(IIC33_RXI, 189), INTC_IRQ(IIC33_TXI, 190),
-	INTC_IRQ(IIC33_TEI, 191),
-	INTC_IRQ(SCIF0_BRI, 192), INTC_IRQ(SCIF0_ERI, 193),
-	INTC_IRQ(SCIF0_RXI, 194), INTC_IRQ(SCIF0_TXI, 195),
-	INTC_IRQ(SCIF1_BRI, 196), INTC_IRQ(SCIF1_ERI, 197),
-	INTC_IRQ(SCIF1_RXI, 198), INTC_IRQ(SCIF1_TXI, 199),
-	INTC_IRQ(SCIF2_BRI, 200), INTC_IRQ(SCIF2_ERI, 201),
-	INTC_IRQ(SCIF2_RXI, 202), INTC_IRQ(SCIF2_TXI, 203),
-	INTC_IRQ(SCIF3_BRI, 204), INTC_IRQ(SCIF3_ERI, 205),
-	INTC_IRQ(SCIF3_RXI, 206), INTC_IRQ(SCIF3_TXI, 207),
-	INTC_IRQ(SSU0_SSERI, 208), INTC_IRQ(SSU0_SSRXI, 209),
-	INTC_IRQ(SSU0_SSTXI, 210),
-	INTC_IRQ(SSU1_SSERI, 211), INTC_IRQ(SSU1_SSRXI, 212),
-	INTC_IRQ(SSU1_SSTXI, 213),
+	INTC_IRQ(IIC30, 172), INTC_IRQ(IIC30, 173),
+	INTC_IRQ(IIC30, 174), INTC_IRQ(IIC30, 175),
+	INTC_IRQ(IIC30, 176),
+	INTC_IRQ(IIC31, 177), INTC_IRQ(IIC31, 178),
+	INTC_IRQ(IIC31, 179), INTC_IRQ(IIC31, 180),
+	INTC_IRQ(IIC31, 181),
+	INTC_IRQ(IIC32, 182), INTC_IRQ(IIC32, 183),
+	INTC_IRQ(IIC32, 184), INTC_IRQ(IIC32, 185),
+	INTC_IRQ(IIC32, 186),
+	INTC_IRQ(IIC33, 187), INTC_IRQ(IIC33, 188),
+	INTC_IRQ(IIC33, 189), INTC_IRQ(IIC33, 190),
+	INTC_IRQ(IIC33, 191),
+	INTC_IRQ(SCIF0, 192), INTC_IRQ(SCIF0, 193),
+	INTC_IRQ(SCIF0, 194), INTC_IRQ(SCIF0, 195),
+	INTC_IRQ(SCIF1, 196), INTC_IRQ(SCIF1, 197),
+	INTC_IRQ(SCIF1, 198), INTC_IRQ(SCIF1, 199),
+	INTC_IRQ(SCIF2, 200), INTC_IRQ(SCIF2, 201),
+	INTC_IRQ(SCIF2, 202), INTC_IRQ(SCIF2, 203),
+	INTC_IRQ(SCIF3, 204), INTC_IRQ(SCIF3, 205),
+	INTC_IRQ(SCIF3, 206), INTC_IRQ(SCIF3, 207),
+	INTC_IRQ(SSU0, 208), INTC_IRQ(SSU0, 209),
+	INTC_IRQ(SSU0, 210),
+	INTC_IRQ(SSU1, 211), INTC_IRQ(SSU1, 212),
+	INTC_IRQ(SSU1, 213),
 	INTC_IRQ(SSI0_SSII, 214), INTC_IRQ(SSI1_SSII, 215),
 	INTC_IRQ(SSI2_SSII, 216), INTC_IRQ(SSI3_SSII, 217),
-	INTC_IRQ(FLCTL_FLSTEI, 224), INTC_IRQ(FLCTL_FLTENDI, 225),
-	INTC_IRQ(FLCTL_FLTREQ0I, 226), INTC_IRQ(FLCTL_FLTREQ1I, 227),
-	INTC_IRQ(RTC_ARM, 231), INTC_IRQ(RTC_PRD, 232),
-	INTC_IRQ(RTC_CUP, 233),
-	INTC_IRQ(RCAN0_ERS, 234), INTC_IRQ(RCAN0_OVR, 235),
-	INTC_IRQ(RCAN0_RM0, 236), INTC_IRQ(RCAN0_RM1, 237),
-	INTC_IRQ(RCAN0_SLE, 238),
-	INTC_IRQ(RCAN1_ERS, 239), INTC_IRQ(RCAN1_OVR, 240),
-	INTC_IRQ(RCAN1_RM0, 241), INTC_IRQ(RCAN1_RM1, 242),
-	INTC_IRQ(RCAN1_SLE, 243),
+	INTC_IRQ(FLCTL, 224), INTC_IRQ(FLCTL, 225),
+	INTC_IRQ(FLCTL, 226), INTC_IRQ(FLCTL, 227),
+	INTC_IRQ(RTC, 231), INTC_IRQ(RTC, 232),
+	INTC_IRQ(RTC, 233),
+	INTC_IRQ(RCAN0, 234), INTC_IRQ(RCAN0, 235),
+	INTC_IRQ(RCAN0, 236), INTC_IRQ(RCAN0, 237),
+	INTC_IRQ(RCAN0, 238),
+	INTC_IRQ(RCAN1, 239), INTC_IRQ(RCAN1, 240),
+	INTC_IRQ(RCAN1, 241), INTC_IRQ(RCAN1, 242),
+	INTC_IRQ(RCAN1, 243),
 
 	/* SH7263-specific trash */
 #ifdef CONFIG_CPU_SUBTYPE_SH7263
-	INTC_IRQ(ROMDEC_ISY, 218), INTC_IRQ(ROMDEC_IERR, 219),
-	INTC_IRQ(ROMDEC_IARG, 220), INTC_IRQ(ROMDEC_ISEC, 221),
-	INTC_IRQ(ROMDEC_IBUF, 222), INTC_IRQ(ROMDEC_IREADY, 223),
+	INTC_IRQ(ROMDEC, 218), INTC_IRQ(ROMDEC, 219),
+	INTC_IRQ(ROMDEC, 220), INTC_IRQ(ROMDEC, 221),
+	INTC_IRQ(ROMDEC, 222), INTC_IRQ(ROMDEC, 223),
 
-	INTC_IRQ(SDHI3, 228), INTC_IRQ(SDHI0, 229), INTC_IRQ(SDHI1, 230),
+	INTC_IRQ(SDHI, 228), INTC_IRQ(SDHI, 229),
+	INTC_IRQ(SDHI, 230),
 
-	INTC_IRQ(SRC_OVF, 244), INTC_IRQ(SRC_ODFI, 245),
-	INTC_IRQ(SRC_IDEI, 246),
+	INTC_IRQ(SRC, 244), INTC_IRQ(SRC, 245),
+	INTC_IRQ(SRC, 246),
 
 	INTC_IRQ(IEBI, 247),
 #endif
@@ -154,50 +132,6 @@ static struct intc_vect vectors[] __init
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
 		   PINT4, PINT5, PINT6, PINT7),
-	INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
-	INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
-	INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
-	INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
-	INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
-	INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
-	INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
-	INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
-	INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
-	INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
-	INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
-	INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
-	INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
-	INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
-	INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
-	INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
-	INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
-		   IIC30_TEI),
-	INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
-		   IIC31_TEI),
-	INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
-		   IIC32_TEI),
-	INTC_GROUP(IIC33, IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI,
-		   IIC33_TEI),
-	INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
-	INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
-	INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
-	INTC_GROUP(SSU0, SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI),
-	INTC_GROUP(SSU1, SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI),
-	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I,
-		   FLCTL_FLTREQ1I),
-	INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP),
-	INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
-		   RCAN0_SLE),
-	INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
-		   RCAN1_SLE),
-
-#ifdef CONFIG_CPU_SUBTYPE_SH7263
-	INTC_GROUP(ROMDEC, ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG,
-		   ROMDEC_ISEC, ROMDEC_IBUF, ROMDEC_IREADY),
-	INTC_GROUP(SDHI, SDHI3, SDHI0, SDHI1),
-	INTC_GROUP(SRC, SRC_OVF, SRC_ODFI, SRC_IDEI),
-#endif
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -242,22 +176,22 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xfffe8000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 193, 194, 195, 192 },
+		.irqs		=  { 192, 192, 192, 192 },
 	}, {
 		.mapbase	= 0xfffe8800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 197, 198, 199, 196 },
+		.irqs		=  { 196, 196, 196, 196 },
 	}, {
 		.mapbase	= 0xfffe9000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 201, 202, 203, 200 },
+		.irqs		=  { 200, 200, 200, 200 },
 	}, {
 		.mapbase	= 0xfffe9800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 205, 206, 207, 204 },
+		.irqs		=  { 204, 204, 204, 204 },
 	}, {
 		.flags = 0,
 	}
@@ -278,17 +212,7 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 232,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 233,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
+		/* Shared Period/Carry/Alarm IRQ */
 		.start	= 231,
 		.flags	= IORESOURCE_IRQ,
 	},
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh2a/setup-sh7206.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  * SH7206 Setup
  *
  *  Copyright (C) 2006  Yoshinori Sato
+ *  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
@@ -19,34 +20,23 @@ enum {
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
 	PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
 	ADC_ADI0, ADC_ADI1,
-	DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
-	DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
-	DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
-	DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
+
+	DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
+
+	MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
+	MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
+	IIC3,
+
 	CMT0, CMT1, BSC, WDT,
-	MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
-	MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
-	MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
-	MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
-	MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
-	MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
-	MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
-	POE2_OEI1, POE2_OEI2,
-	MTU2S_TGI3A, MTU2S_TGI3B, MTU2S_TGI3C, MTU2S_TGI3D, MTU2S_TCI3V,
-	MTU2S_TGI4A, MTU2S_TGI4B, MTU2S_TGI4C, MTU2S_TGI4D, MTU2S_TCI4V,
-	MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W,
+
+	MTU2_TCI3V, MTU2_TCI4V, MTU2S_TCI3V, MTU2S_TCI4V,
+
 	POE2_OEI3,
-	IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI,
-	SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
-	SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
-	SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
-	SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
+
+	SCIF0, SCIF1, SCIF2, SCIF3,
 
 	/* interrupt groups */
-	PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
-	MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
-	MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
-	IIC3, SCIF0, SCIF1, SCIF2, SCIF3,
+	PINT,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -59,86 +49,58 @@ static struct intc_vect vectors[] __init
 	INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
 	INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
 	INTC_IRQ(ADC_ADI0, 92), INTC_IRQ(ADC_ADI1, 96),
-	INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
-	INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
-	INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
-	INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
-	INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
-	INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
-	INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
-	INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
+	INTC_IRQ(DMAC0, 108), INTC_IRQ(DMAC0, 109),
+	INTC_IRQ(DMAC1, 112), INTC_IRQ(DMAC1, 113),
+	INTC_IRQ(DMAC2, 116), INTC_IRQ(DMAC2, 117),
+	INTC_IRQ(DMAC3, 120), INTC_IRQ(DMAC3, 121),
+	INTC_IRQ(DMAC4, 124), INTC_IRQ(DMAC4, 125),
+	INTC_IRQ(DMAC5, 128), INTC_IRQ(DMAC5, 129),
+	INTC_IRQ(DMAC6, 132), INTC_IRQ(DMAC6, 133),
+	INTC_IRQ(DMAC7, 136), INTC_IRQ(DMAC7, 137),
 	INTC_IRQ(CMT0, 140), INTC_IRQ(CMT1, 144),
 	INTC_IRQ(BSC, 148), INTC_IRQ(WDT, 152),
-	INTC_IRQ(MTU2_TGI0A, 156), INTC_IRQ(MTU2_TGI0B, 157),
-	INTC_IRQ(MTU2_TGI0C, 158), INTC_IRQ(MTU2_TGI0D, 159),
-	INTC_IRQ(MTU2_TCI0V, 160),
-	INTC_IRQ(MTU2_TGI0E, 161), INTC_IRQ(MTU2_TGI0F, 162),
-	INTC_IRQ(MTU2_TGI1A, 164), INTC_IRQ(MTU2_TGI1B, 165),
-	INTC_IRQ(MTU2_TCI1V, 168), INTC_IRQ(MTU2_TCI1U, 169),
-	INTC_IRQ(MTU2_TGI2A, 172), INTC_IRQ(MTU2_TGI2B, 173),
-	INTC_IRQ(MTU2_TCI2V, 176), INTC_IRQ(MTU2_TCI2U, 177),
-	INTC_IRQ(MTU2_TGI3A, 180), INTC_IRQ(MTU2_TGI3B, 181),
-	INTC_IRQ(MTU2_TGI3C, 182), INTC_IRQ(MTU2_TGI3D, 183),
+	INTC_IRQ(MTU0_ABCD, 156), INTC_IRQ(MTU0_ABCD, 157),
+	INTC_IRQ(MTU0_ABCD, 158), INTC_IRQ(MTU0_ABCD, 159),
+	INTC_IRQ(MTU0_VEF, 160), INTC_IRQ(MTU0_VEF, 161),
+	INTC_IRQ(MTU0_VEF, 162),
+	INTC_IRQ(MTU1_AB, 164), INTC_IRQ(MTU1_AB, 165),
+	INTC_IRQ(MTU1_VU, 168), INTC_IRQ(MTU1_VU, 169),
+	INTC_IRQ(MTU2_AB, 172), INTC_IRQ(MTU2_AB, 173),
+	INTC_IRQ(MTU2_VU, 176), INTC_IRQ(MTU2_VU, 177),
+	INTC_IRQ(MTU3_ABCD, 180), INTC_IRQ(MTU3_ABCD, 181),
+	INTC_IRQ(MTU3_ABCD, 182), INTC_IRQ(MTU3_ABCD, 183),
 	INTC_IRQ(MTU2_TCI3V, 184),
-	INTC_IRQ(MTU2_TGI4A, 188), INTC_IRQ(MTU2_TGI4B, 189),
-	INTC_IRQ(MTU2_TGI4C, 190), INTC_IRQ(MTU2_TGI4D, 191),
+	INTC_IRQ(MTU4_ABCD, 188), INTC_IRQ(MTU4_ABCD, 189),
+	INTC_IRQ(MTU4_ABCD, 190), INTC_IRQ(MTU4_ABCD, 191),
 	INTC_IRQ(MTU2_TCI4V, 192),
-	INTC_IRQ(MTU2_TGI5U, 196), INTC_IRQ(MTU2_TGI5V, 197),
-	INTC_IRQ(MTU2_TGI5W, 198),
-	INTC_IRQ(POE2_OEI1, 200), INTC_IRQ(POE2_OEI2, 201),
-	INTC_IRQ(MTU2S_TGI3A, 204), INTC_IRQ(MTU2S_TGI3B, 205),
-	INTC_IRQ(MTU2S_TGI3C, 206), INTC_IRQ(MTU2S_TGI3D, 207),
+	INTC_IRQ(MTU5, 196), INTC_IRQ(MTU5, 197),
+	INTC_IRQ(MTU5, 198),
+	INTC_IRQ(POE2_12, 200), INTC_IRQ(POE2_12, 201),
+	INTC_IRQ(MTU3S_ABCD, 204), INTC_IRQ(MTU3S_ABCD, 205),
+	INTC_IRQ(MTU3S_ABCD, 206), INTC_IRQ(MTU3S_ABCD, 207),
 	INTC_IRQ(MTU2S_TCI3V, 208),
-	INTC_IRQ(MTU2S_TGI4A, 212), INTC_IRQ(MTU2S_TGI4B, 213),
-	INTC_IRQ(MTU2S_TGI4C, 214), INTC_IRQ(MTU2S_TGI4D, 215),
+	INTC_IRQ(MTU4S_ABCD, 212), INTC_IRQ(MTU4S_ABCD, 213),
+	INTC_IRQ(MTU4S_ABCD, 214), INTC_IRQ(MTU4S_ABCD, 215),
 	INTC_IRQ(MTU2S_TCI4V, 216),
-	INTC_IRQ(MTU2S_TGI5U, 220), INTC_IRQ(MTU2S_TGI5V, 221),
-	INTC_IRQ(MTU2S_TGI5W, 222),
+	INTC_IRQ(MTU5S, 220), INTC_IRQ(MTU5S, 221),
+	INTC_IRQ(MTU5S, 222),
 	INTC_IRQ(POE2_OEI3, 224),
-	INTC_IRQ(IIC3_STPI, 228), INTC_IRQ(IIC3_NAKI, 229),
-	INTC_IRQ(IIC3_RXI, 230), INTC_IRQ(IIC3_TXI, 231),
-	INTC_IRQ(IIC3_TEI, 232),
-	INTC_IRQ(SCIF0_BRI, 240), INTC_IRQ(SCIF0_ERI, 241),
-	INTC_IRQ(SCIF0_RXI, 242), INTC_IRQ(SCIF0_TXI, 243),
-	INTC_IRQ(SCIF1_BRI, 244), INTC_IRQ(SCIF1_ERI, 245),
-	INTC_IRQ(SCIF1_RXI, 246), INTC_IRQ(SCIF1_TXI, 247),
-	INTC_IRQ(SCIF2_BRI, 248), INTC_IRQ(SCIF2_ERI, 249),
-	INTC_IRQ(SCIF2_RXI, 250), INTC_IRQ(SCIF2_TXI, 251),
-	INTC_IRQ(SCIF3_BRI, 252), INTC_IRQ(SCIF3_ERI, 253),
-	INTC_IRQ(SCIF3_RXI, 254), INTC_IRQ(SCIF3_TXI, 255),
+	INTC_IRQ(IIC3, 228), INTC_IRQ(IIC3, 229),
+	INTC_IRQ(IIC3, 230), INTC_IRQ(IIC3, 231),
+	INTC_IRQ(IIC3, 232),
+	INTC_IRQ(SCIF0, 240), INTC_IRQ(SCIF0, 241),
+	INTC_IRQ(SCIF0, 242), INTC_IRQ(SCIF0, 243),
+	INTC_IRQ(SCIF1, 244), INTC_IRQ(SCIF1, 245),
+	INTC_IRQ(SCIF1, 246), INTC_IRQ(SCIF1, 247),
+	INTC_IRQ(SCIF2, 248), INTC_IRQ(SCIF2, 249),
+	INTC_IRQ(SCIF2, 250), INTC_IRQ(SCIF2, 251),
+	INTC_IRQ(SCIF3, 252), INTC_IRQ(SCIF3, 253),
+	INTC_IRQ(SCIF3, 254), INTC_IRQ(SCIF3, 255),
 };
 
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
 		   PINT4, PINT5, PINT6, PINT7),
-	INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
-	INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
-	INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
-	INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
-	INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
-	INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
-	INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
-	INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
-	INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
-	INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
-	INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
-	INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
-	INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
-	INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
-	INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
-	INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
-	INTC_GROUP(MTU5, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
-	INTC_GROUP(POE2_12, POE2_OEI1, POE2_OEI2),
-	INTC_GROUP(MTU3S_ABCD, MTU2S_TGI3A, MTU2S_TGI3B,
-		   MTU2S_TGI3C, MTU2S_TGI3D),
-	INTC_GROUP(MTU4S_ABCD, MTU2S_TGI4A, MTU2S_TGI4B,
-		   MTU2S_TGI4C, MTU2S_TGI4D),
-	INTC_GROUP(MTU5S, MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W),
-	INTC_GROUP(IIC3, IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI),
-	INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
-	INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
-	INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -174,22 +136,22 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xfffe8000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 241, 242, 243, 240 },
+		.irqs		= { 240, 240, 240, 240 },
 	}, {
 		.mapbase	= 0xfffe8800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 245, 246, 247, 244 },
+		.irqs		= { 244, 244, 244, 244 },
 	}, {
 		.mapbase	= 0xfffe9000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 249, 250, 251, 248 },
+		.irqs		= { 248, 248, 248, 248 },
 	}, {
 		.mapbase	= 0xfffe9800,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		=  { 253, 254, 255, 252 },
+		.irqs		= { 252, 252, 252, 252 },
 	}, {
 		.flags = 0,
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/entry.S linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/entry.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 #include <asm/unistd.h>
 #include <cpu/mmu_context.h>
 #include <asm/page.h>
+#include <asm/cache.h>
 
 ! NOTE:
 ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -187,44 +188,35 @@ call_dae:
 #if defined(CONFIG_SH_STANDARD_BIOS)
 	/* Unwind the stack and jmp to the debug entry */
 ENTRY(sh_bios_handler)
-	mov.l	@r15+, r0
-	mov.l	@r15+, r1
-	mov.l	@r15+, r2
-	mov.l	@r15+, r3
-	mov.l	@r15+, r4
-	mov.l	@r15+, r5
-	mov.l	@r15+, r6
-	mov.l	@r15+, r7
-	stc	sr, r8
-	mov.l	1f, r9			! BL =1, RB=1, IMASK=0x0F
-	or	r9, r8
-	ldc	r8, sr			! here, change the register bank
-	mov.l	@r15+, r8
-	mov.l	@r15+, r9
-	mov.l	@r15+, r10
-	mov.l	@r15+, r11
-	mov.l	@r15+, r12
-	mov.l	@r15+, r13
-	mov.l	@r15+, r14
-	mov.l	@r15+, k0
-	ldc.l	@r15+, spc
-	lds.l	@r15+, pr
-	mov.l	@r15+, k1
-	ldc.l	@r15+, gbr
-	lds.l	@r15+, mach
-	lds.l	@r15+, macl
-	mov	k0, r15
+	mov.l	1f, r8
+	bsr	restore_regs
+	 nop
+
+	lds	k2, pr			! restore pr
+	mov	k4, r15
 	!
 	mov.l	2f, k0
 	mov.l	@k0, k0
 	jmp	@k0
-	 ldc	k1, ssr
+	 ldc	k3, ssr
 	.align	2
 1:	.long	0x300000f0
 2:	.long	gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
 
-restore_all:
+! restore_regs()
+! - restore r0, r1, r2, r3, r4, r5, r6, r7 from the stack
+! - switch bank
+! - restore r8, r9, r10, r11, r12, r13, r14, r15 from the stack
+! - restore spc, pr*, ssr, gbr, mach, macl, skip default tra
+! k2 returns original pr
+! k3 returns original sr
+! k4 returns original stack pointer
+! r8 passes SR bitmask, overwritten with restored data on return
+! r9 trashed
+! BL=0 on entry, on exit BL=1 (depending on r8).
+
+ENTRY(restore_regs)
 	mov.l	@r15+, r0
 	mov.l	@r15+, r1
 	mov.l	@r15+, r2
@@ -234,10 +226,9 @@ restore_all:
 	mov.l	@r15+, r6
 	mov.l	@r15+, r7
 	!
-	stc	sr, r8
-	mov.l	7f, r9
-	or	r9, r8			! BL =1, RB=1
-	ldc	r8, sr			! here, change the register bank
+	stc	sr, r9
+	or	r8, r9
+	ldc	r9, sr
 	!
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
@@ -248,53 +239,27 @@ restore_all:
 	mov.l	@r15+, r14
 	mov.l	@r15+, k4		! original stack pointer
 	ldc.l	@r15+, spc
-	lds.l	@r15+, pr
+	mov.l	@r15+, k2		! original PR
 	mov.l	@r15+, k3		! original SR
 	ldc.l	@r15+, gbr
 	lds.l	@r15+, mach
 	lds.l	@r15+, macl
-	add	#4, r15			! Skip syscall number
-	!
-#ifdef CONFIG_SH_DSP
-	mov.l	@r15+, k0		! DSP mode marker
-	mov.l	5f, k1
-	cmp/eq	k0, k1			! Do we have a DSP stack frame?
-	bf	skip_restore
-
-	stc	sr, k0			! Enable CPU DSP mode
-	or	k1, k0			! (within kernel it may be disabled)
-	ldc	k0, sr
-	mov	r2, k0			! Backup r2
-
-	! Restore DSP registers from stack
-	mov	r15, r2
-	movs.l	@r2+, a1
-	movs.l	@r2+, a0g
-	movs.l	@r2+, a1g
-	movs.l	@r2+, m0
-	movs.l	@r2+, m1
-	mov	r2, r15
+	rts
+	 add	#4, r15			! Skip syscall number
 
-	lds.l	@r15+, a0
-	lds.l	@r15+, x0
-	lds.l	@r15+, x1
-	lds.l	@r15+, y0
-	lds.l	@r15+, y1
-	lds.l	@r15+, dsr
-	ldc.l	@r15+, rs
-	ldc.l	@r15+, re
-	ldc.l	@r15+, mod
+restore_all:
+	mov.l	7f, r8
+	bsr	restore_regs
+	 nop
 
-	mov	k0, r2			! Restore r2
-skip_restore:
-#endif
+	lds	k2, pr			! restore pr
 	!
 	! Calculate new SR value
 	mov	k3, k2			! original SR value
 	mov	#0xf0, k1
 	extu.b	k1, k1
 	not	k1, k1
-	and	k1, k2			! Mask orignal SR value
+	and	k1, k2			! Mask original SR value
 	!
 	mov	k3, k0			! Calculate IMASK-bits
 	shlr2	k0
@@ -313,7 +278,6 @@ skip_restore:
 	mov	#0, k1
 	mov.b	k1, @k0
 #endif
-	mov.l	@r15+, k2		! restore EXPEVT
 	mov	k4, r15
 	rte
 	 nop
@@ -336,81 +300,54 @@ skip_restore:
 ENTRY(vbr_base)
 	.long	0
 !
+! 0x100: General exception vector
+!
 	.balign 	256,0,256
 general_exception:
-	mov.l	1f, k2
-	mov.l	2f, k3
-#ifdef CONFIG_CPU_SUBTYPE_SHX3
-	mov.l	@k2, k2
+#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, k2
+	cmp/hs	k0, k4
 	bf	0f
 
 	! then add 0x580 (k2 is 0xd80 or 0xda0)
 	mov	#0x58, k0
 	shll2	k0
 	shll2	k0
-	add	k0, k2
+	add	k0, k4
 0:
-	bra	handle_exception
+	! Setup stack and save DSP context (k0 contains original r15 on return)
+	bsr	prepare_stack
 	 nop
-#else
-	bra	handle_exception
-	 mov.l	@k2, k2
-#endif
-	.align	2
-1:	.long	EXPEVT
-2:	.long	ret_from_exception
-!
-!
 
-	.balign 	1024,0,1024
-tlb_miss:
-	mov.l	1f, k2
-	mov.l	4f, k3
-	bra	handle_exception
-	 mov.l	@k2, k2
-!
-	.balign 	512,0,512
-interrupt:
-	mov.l	3f, k3
-#if defined(CONFIG_KGDB)
-	mov.l	2f, k2
-	! Debounce (filter nested NMI)
-	mov.l	@k2, k0
-	mov.l	5f, k1
-	cmp/eq	k1, k0
-	bf	0f
-	mov.l	6f, k1
-	tas.b	@k1
-	bt	0f
-	rte
+	! 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
-2:	.long	INTEVT
-5:	.long	NMI_VEC
-6:	.long	in_nmi
-0:
-#endif /* defined(CONFIG_KGDB) */
-	bra	handle_exception
-	 mov	#-1, k2		! interrupt exception marker
 
 	.align	2
 1:	.long	EXPEVT
-3:	.long	ret_from_irq
-4:	.long	ret_from_exception
+#endif
 
-!
-!
-	.align	2
-ENTRY(handle_exception)
-	! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
-	! save all registers onto stack.
-	!
+! prepare_stack()
+! - roll back gRB
+! - switch to kernel stack
+! k0 returns original sp (after roll back)
+! k1 trashed
+! k2 trashed
 
+prepare_stack:
 #ifdef CONFIG_GUSA
 	! Check for roll back gRB (User and Kernel)
 	mov	r15, k0
@@ -430,7 +367,7 @@ ENTRY(handle_exception)
 2:	mov	k1, r15		! SP = r1
 1:
 #endif
-
+	! Switch to kernel stack if needed
 	stc	ssr, k0		! Is it from kernel space?
 	shll	k0		! Check MD bit (bit30) by shifting it into...
 	shll	k0		!       ...the T bit
@@ -443,65 +380,65 @@ ENTRY(handle_exception)
 	add	current, k1
 	mov	k1, r15		! change to kernel stack
 	!
-1:	mov.l	2f, k1
-	!
-#ifdef CONFIG_SH_DSP
-	mov.l	r2, @-r15		! Save r2, we need another reg
-	stc	sr, k4
-	mov.l	1f, r2
-	tst	r2, k4			! Check if in DSP mode
-	mov.l	@r15+, r2		! Restore r2 now
-	bt/s	skip_save
-	 mov	#0, k4			! Set marker for no stack frame
+1:
+	rts
+	 nop
 
-	mov	r2, k4			! Backup r2 (in k4) for later
+!
+! 0x400: Instruction and Data TLB miss exception vector
+!
+	.balign 	1024,0,1024
+tlb_miss:
+	sts	pr, k3		! save original pr value in k3
 
-	! Save DSP registers on stack
-	stc.l	mod, @-r15
-	stc.l	re, @-r15
-	stc.l	rs, @-r15
-	sts.l	dsr, @-r15
-	sts.l	y1, @-r15
-	sts.l	y0, @-r15
-	sts.l	x1, @-r15
-	sts.l	x0, @-r15
-	sts.l	a0, @-r15
+handle_exception:
+	mova	exception_data, k0
 
-	! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
+	! Setup stack and save DSP context (k0 contains original r15 on return)
+	bsr	prepare_stack
+	 PREF(k0)
 
-	! FIXME: Make sure that this is still the case with newer toolchains,
-	! as we're not at all interested in supporting ancient toolchains at
-	! this point. -- PFM.
+	! Save registers / Switch to bank 0
+	mov.l	5f, k2		! vector register address
+	mov.l	1f, k4		! SR bits to clear in k4
+	bsr	save_regs	! needs original pr value in k3
+	 mov.l	@k2, k2		! read out vector and keep in k2
 
-	mov	r15, r2
-	.word	0xf653			! movs.l	a1, @-r2
-	.word	0xf6f3			! movs.l	a0g, @-r2
-	.word	0xf6d3			! movs.l	a1g, @-r2
-	.word	0xf6c3			! movs.l	m0, @-r2
-	.word	0xf6e3			! movs.l	m1, @-r2
-	mov	r2, r15
+handle_exception_special:
+	! Setup return address and jump to exception handler
+	mov.l	7f, r9		! fetch return address
+	stc	r2_bank, r0	! k2 (vector)
+	mov.l	6f, r10
+	shlr2	r0
+	shlr	r0
+	mov.l	@(r0, r10), r10
+	jmp	@r10
+	 lds	r9, pr		! put return address in pr
 
-	mov	k4, r2			! Restore r2
-	mov.l	1f, k4			! Force DSP stack frame
-skip_save:
-	mov.l	k4, @-r15		! Push DSP mode marker onto stack
-#endif
-	! Save the user registers on the stack.
-	mov.l	k2, @-r15	! EXPEVT
+	.align	L1_CACHE_SHIFT
 
-	mov	#-1, k4
-	mov.l	k4, @-r15	! set TRA (default: -1)
-	!
+! save_regs()
+! - save default tra, macl, mach, gbr, ssr, pr* and spc on the stack
+! - save r15*, r14, r13, r12, r11, r10, r9, r8 on the stack
+! - switch bank
+! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack
+! k0 contains original stack pointer*
+! k1 trashed
+! k3 passes original pr*
+! k4 passes SR bitmask
+! BL=1 on entry, on exit BL=0.
+
+ENTRY(save_regs)
+	mov	#-1, r1
+	mov.l	k1, @-r15	! set TRA (default: -1)
 	sts.l	macl, @-r15
 	sts.l	mach, @-r15
 	stc.l	gbr, @-r15
 	stc.l	ssr, @-r15
-	sts.l	pr, @-r15
+	mov.l	k3, @-r15	! original pr in k3
 	stc.l	spc, @-r15
-	!
-	lds	k3, pr		! Set the return address to pr
-	!
-	mov.l	k0, @-r15	! save orignal stack
+
+	mov.l	k0, @-r15	! original stack pointer in k0
 	mov.l	r14, @-r15
 	mov.l	r13, @-r15
 	mov.l	r12, @-r15
@@ -509,13 +446,23 @@ skip_save:
 	mov.l	r10, @-r15
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
-	!
-	stc	sr, r8		! Back to normal register bank, and
-	or	k1, r8		! Block all interrupts
-	mov.l	3f, k1
-	and	k1, r8		! ...
-	ldc	r8, sr		! ...changed here.
-	!
+
+	mov.l	0f, k3		! SR bits to set in k3
+
+	! fall-through
+
+! save_low_regs()
+! - modify SR for bank switch
+! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack
+! k3 passes bits to set in SR
+! k4 passes bits to clear in SR
+
+ENTRY(save_low_regs)
+	stc	sr, r8
+	or	k3, r8
+	and	k4, r8
+	ldc	r8, sr
+
 	mov.l	r7, @-r15
 	mov.l	r6, @-r15
 	mov.l	r5, @-r15
@@ -523,52 +470,63 @@ skip_save:
 	mov.l	r3, @-r15
 	mov.l	r2, @-r15
 	mov.l	r1, @-r15
-	mov.l	r0, @-r15
-
-	/*
-	 * This gets a bit tricky.. in the INTEVT case we don't want to use
-	 * the VBR offset as a destination in the jump call table, since all
-	 * of the destinations are the same. In this case, (interrupt) sets
-	 * a marker in r2 (now r2_bank since SR.RB changed), which we check
-	 * to determine the exception type. For all other exceptions, we
-	 * forcibly read EXPEVT from memory and fix up the jump address, in
-	 * the interrupt exception case we jump to do_IRQ() and defer the
-	 * INTEVT read until there. As a bonus, we can also clean up the SR.RB
-	 * checks that do_IRQ() was doing..
-	 */
-	stc	r2_bank, r8
-	cmp/pz	r8
-	bf	interrupt_exception
-	shlr2	r8
-	shlr	r8
-	mov.l	4f, r9
-	add	r8, r9
-	mov.l	@r9, r9
-	jmp	@r9
-	 nop
 	rts
-	 nop
+	 mov.l	r0, @-r15
 
+!
+! 0x600: Interrupt / NMI vector
+!
+	.balign 	512,0,512
+ENTRY(handle_interrupt)
+#if defined(CONFIG_KGDB)
+	mov.l	2f, k2
+	! Debounce (filter nested NMI)
+	mov.l	@k2, k0
+	mov.l	9f, k1
+	cmp/eq	k1, k0
+	bf	11f
+	mov.l	10f, k1
+	tas.b	@k1
+	bt	11f
+	rte
+	 nop
 	.align	2
-1:	.long	0x00001000	! DSP=1
-2:	.long	0x000080f0	! FD=1, IMASK=15
-3:	.long	0xcfffffff	! RB=0, BL=0
-4:	.long	exception_handling_table
+9:	.long	NMI_VEC
+10:	.long	in_nmi
+11:
+#endif /* defined(CONFIG_KGDB) */
+	sts	pr, k3		! save original pr value in k3
+	mova	exception_data, k0
 
-interrupt_exception:
-	mov.l	1f, r9
+	! Setup stack and save DSP context (k0 contains original r15 on return)
+	bsr	prepare_stack
+	 PREF(k0)
+
+	! Save registers / Switch to bank 0
+	mov.l	1f, k4		! SR bits to clear in k4
+	bsr	save_regs	! needs original pr value in k3
+	 mov	#-1, k2		! default vector kept in k2
+
+	! Setup return address and jump to do_IRQ
+	mov.l	4f, r9		! fetch return address
+	lds	r9, pr		! put return address in pr
 	mov.l	2f, r4
-	mov.l	@r4, r4
+	mov.l	3f, r9
+	mov.l	@r4, r4		! pass INTEVT vector as arg0
 	jmp	@r9
-	 mov	r15, r5
-	rts
-	 nop
-
-	.align 2
-1:	.long	do_IRQ
-2:	.long	INTEVT
+	 mov	r15, r5		! pass saved registers as arg1
 
-	.align	2
 ENTRY(exception_none)
 	rts
 	 nop
+
+	.align	L1_CACHE_SHIFT
+exception_data:
+0:	.long	0x000080f0	! FD=1, IMASK=15
+1:	.long	0xcfffffff	! RB=0, BL=0
+2:	.long	INTEVT
+3:	.long	do_IRQ
+4:	.long	ret_from_irq
+5:	.long	EXPEVT
+6:	.long	exception_handling_table
+7:	.long	ret_from_exception
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/Makefile linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,8 @@
 
 obj-y	:= ex.o probe.o entry.o setup-sh3.o
 
+obj-$(CONFIG_HIBERNATION)		+= swsusp.o
+
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7705)	+= setup-sh7705.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7706)	+= setup-sh770x.o
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7705.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * SH7705 Setup
  *
- *  Copyright (C) 2006, 2007  Paul Mundt
+ *  Copyright (C) 2006 - 2009  Paul Mundt
  *  Copyright (C) 2007  Nobuhiro Iwamatsu
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -21,51 +21,36 @@ enum {
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
 	PINT07, PINT815,
-	DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
-	SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
-	ADC_ADI,
-	USB_USI0, USB_USI1,
+
+	DMAC, SCIF0, SCIF2, ADC_ADI, USB,
+
 	TPU0, TPU1, TPU2, TPU3,
-	TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT,
-	REF_RCMI,
+	TMU0, TMU1, TMU2,
 
-	/* interrupt groups */
-	RTC, TMU2, DMAC, USB, SCIF2, SCIF0,
+	RTC, WDT, REF_RCMI,
 };
 
 static struct intc_vect vectors[] __initdata = {
 	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
-	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
-	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
-	INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
-	INTC_VECT(SCIF0_TXI, 0x8e0),
-	INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
-	INTC_VECT(SCIF2_TXI, 0x960),
+	INTC_VECT(DMAC, 0x800), INTC_VECT(DMAC, 0x820),
+	INTC_VECT(DMAC, 0x840), INTC_VECT(DMAC, 0x860),
+	INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+	INTC_VECT(SCIF0, 0x8e0),
+	INTC_VECT(SCIF2, 0x900), INTC_VECT(SCIF2, 0x920),
+	INTC_VECT(SCIF2, 0x960),
 	INTC_VECT(ADC_ADI, 0x980),
-	INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
+	INTC_VECT(USB, 0xa20), INTC_VECT(USB, 0xa40),
 	INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
 	INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0),
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
-	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
+	INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
 	INTC_VECT(WDT, 0x560),
 	INTC_VECT(REF_RCMI, 0x580),
 };
 
-static struct intc_group groups[] __initdata = {
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
-	INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
-	INTC_GROUP(USB, USB_USI0, USB_USI1),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
-	INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
-};
-
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
 	{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } },
@@ -78,7 +63,7 @@ static struct intc_prio_reg prio_registe
 
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
 static struct plat_sci_port sci_platform_data[] = {
@@ -86,12 +71,12 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xa4410000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 56, 57, 59 },
+		.irqs		= { 56, 56, 56 },
 	}, {
 		.mapbase	= 0xa4400000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 52, 53, 55 },
+		.irqs		= { 52, 52, 52 },
 	}, {
 		.flags = 0,
 	}
@@ -115,14 +100,6 @@ static struct resource rtc_resources[] =
 		.start  = 20,
 		.flags	= IORESOURCE_IRQ,
 	},
-	[2] =	{
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] =	{
-		.start	= 22,
-		.flags  = IORESOURCE_IRQ,
-	},
 };
 
 static struct sh_rtc_platform_info rtc_info = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh770x.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  * SH3 Setup code for SH7706, SH7707, SH7708, SH7709
  *
  *  Copyright (C) 2007  Magnus Damm
+ *  Copyright (C) 2009  Paul Mundt
  *
  * Based on setup-sh7709.c
  *
@@ -24,46 +25,37 @@ enum {
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
 	PINT07, PINT815,
-	DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
-	SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI,
-	ADC_ADI,
+	DMAC, SCIF0, SCIF2, SCI, ADC_ADI,
 	LCDC, PCC0, PCC1,
-	TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT,
-	REF_RCMI, REF_ROVI,
-
-	/* interrupt groups */
-	RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0,
+	TMU0, TMU1, TMU2,
+	RTC, WDT, REF,
 };
 
 static struct intc_vect vectors[] __initdata = {
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
-	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
-	INTC_VECT(SCI_ERI, 0x4e0), INTC_VECT(SCI_RXI, 0x500),
-	INTC_VECT(SCI_TXI, 0x520), INTC_VECT(SCI_TEI, 0x540),
+	INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
+	INTC_VECT(SCI, 0x4e0), INTC_VECT(SCI, 0x500),
+	INTC_VECT(SCI, 0x520), INTC_VECT(SCI, 0x540),
 	INTC_VECT(WDT, 0x560),
-	INTC_VECT(REF_RCMI, 0x580),
-	INTC_VECT(REF_ROVI, 0x5a0),
+	INTC_VECT(REF, 0x580),
+	INTC_VECT(REF, 0x5a0),
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
 	/* IRQ0->5 are handled in setup-sh3.c */
-	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
-	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
+	INTC_VECT(DMAC, 0x800), INTC_VECT(DMAC, 0x820),
+	INTC_VECT(DMAC, 0x840), INTC_VECT(DMAC, 0x860),
 	INTC_VECT(ADC_ADI, 0x980),
-	INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
-	INTC_VECT(SCIF2_BRI, 0x940), INTC_VECT(SCIF2_TXI, 0x960),
+	INTC_VECT(SCIF2, 0x900), INTC_VECT(SCIF2, 0x920),
+	INTC_VECT(SCIF2, 0x940), INTC_VECT(SCIF2, 0x960),
 #endif
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
     defined(CONFIG_CPU_SUBTYPE_SH7709)
 	INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
-	INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
-	INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
+	INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+	INTC_VECT(SCIF0, 0x8c0), INTC_VECT(SCIF0, 0x8e0),
 #endif
 #if defined(CONFIG_CPU_SUBTYPE_SH7707)
 	INTC_VECT(LCDC, 0x9a0),
@@ -71,16 +63,6 @@ static struct intc_vect vectors[] __init
 #endif
 };
 
-static struct intc_group groups[] __initdata = {
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
-	INTC_GROUP(REF, REF_RCMI, REF_ROVI),
-	INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
-	INTC_GROUP(SCI, SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
-	INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
-};
-
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
 	{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } },
@@ -101,7 +83,7 @@ static struct intc_prio_reg prio_registe
 #endif
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
 static struct resource rtc_resources[] = {
@@ -111,14 +93,6 @@ static struct resource rtc_resources[] =
 		.flags  = IORESOURCE_IO,
 	},
 	[1] =	{
-		.start  = 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] =	{
-		.start	= 22,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] =	{
 		.start	= 20,
 		.flags  = IORESOURCE_IRQ,
 	},
@@ -136,7 +110,7 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xfffffe80,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCI,
-		.irqs		= { 23, 24, 25, 0 },
+		.irqs		= { 23, 23, 23, 0 },
 	},
 #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7707) || \
@@ -145,7 +119,7 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xa4000150,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 56, 57, 59, 58 },
+		.irqs		= { 56, 56, 56, 56 },
 	},
 #endif
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
@@ -154,7 +128,7 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xa4000140,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_IRDA,
-		.irqs		= { 52, 53, 55, 54 },
+		.irqs		= { 52, 52, 52, 52 },
 	},
 #endif
 	{
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7710.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * SH3 Setup code for SH7710, SH7712
  *
- *  Copyright (C) 2006, 2007  Paul Mundt
+ *  Copyright (C) 2006 - 2009  Paul Mundt
  *  Copyright (C) 2007  Nobuhiro Iwamatsu
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -20,59 +20,40 @@ enum {
 
 	/* interrupt sources */
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
-	DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
-	DMAC_DEI4, DMAC_DEI5,
-	IPSEC,
+	DMAC1, SCIF0, SCIF1, DMAC2, IPSEC,
 	EDMAC0, EDMAC1, EDMAC2,
-	SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI,
-	SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI,
-	TMU0, TMU1, TMU2,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT,
-	REF,
+	SIOF0, SIOF1,
 
-	/* interrupt groups */
-	RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1,
+	TMU0, TMU1, TMU2,
+	RTC, WDT, REF,
 };
 
 static struct intc_vect vectors[] __initdata = {
 	/* IRQ0->5 are handled in setup-sh3.c */
-	INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
-	INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
-	INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
-	INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
-	INTC_VECT(SCIF1_ERI, 0x900), INTC_VECT(SCIF1_RXI, 0x920),
-	INTC_VECT(SCIF1_BRI, 0x940), INTC_VECT(SCIF1_TXI, 0x960),
-	INTC_VECT(DMAC_DEI4, 0xb80), INTC_VECT(DMAC_DEI5, 0xba0),
+	INTC_VECT(DMAC1, 0x800), INTC_VECT(DMAC1, 0x820),
+	INTC_VECT(DMAC1, 0x840), INTC_VECT(DMAC1, 0x860),
+	INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+	INTC_VECT(SCIF0, 0x8c0), INTC_VECT(SCIF0, 0x8e0),
+	INTC_VECT(SCIF1, 0x900), INTC_VECT(SCIF1, 0x920),
+	INTC_VECT(SCIF1, 0x940), INTC_VECT(SCIF1, 0x960),
+	INTC_VECT(DMAC2, 0xb80), INTC_VECT(DMAC2, 0xba0),
 #ifdef CONFIG_CPU_SUBTYPE_SH7710
 	INTC_VECT(IPSEC, 0xbe0),
 #endif
 	INTC_VECT(EDMAC0, 0xc00), INTC_VECT(EDMAC1, 0xc20),
 	INTC_VECT(EDMAC2, 0xc40),
-	INTC_VECT(SIOF0_ERI, 0xe00), INTC_VECT(SIOF0_TXI, 0xe20),
-	INTC_VECT(SIOF0_RXI, 0xe40), INTC_VECT(SIOF0_CCI, 0xe60),
-	INTC_VECT(SIOF1_ERI, 0xe80), INTC_VECT(SIOF1_TXI, 0xea0),
-	INTC_VECT(SIOF1_RXI, 0xec0), INTC_VECT(SIOF1_CCI, 0xee0),
+	INTC_VECT(SIOF0, 0xe00), INTC_VECT(SIOF0, 0xe20),
+	INTC_VECT(SIOF0, 0xe40), INTC_VECT(SIOF0, 0xe60),
+	INTC_VECT(SIOF1, 0xe80), INTC_VECT(SIOF1, 0xea0),
+	INTC_VECT(SIOF1, 0xec0), INTC_VECT(SIOF1, 0xee0),
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
 	INTC_VECT(TMU2, 0x440),
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
 	INTC_VECT(WDT, 0x560),
 	INTC_VECT(REF, 0x580),
 };
 
-static struct intc_group groups[] __initdata = {
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(DMAC2, DMAC_DEI4, DMAC_DEI5),
-	INTC_GROUP(SIOF0, SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI),
-	INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI),
-};
-
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
 	{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
@@ -85,7 +66,7 @@ static struct intc_prio_reg prio_registe
 	{ 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
 static struct resource rtc_resources[] = {
@@ -98,14 +79,6 @@ static struct resource rtc_resources[] =
 		.start  = 20,
 		.flags	= IORESOURCE_IRQ,
 	},
-	[2] =	{
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] =	{
-		.start	= 22,
-		.flags  = IORESOURCE_IRQ,
-	},
 };
 
 static struct sh_rtc_platform_info rtc_info = {
@@ -127,12 +100,12 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xa4400000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 52, 53, 55, 54 },
+		.irqs		= { 52, 52, 52, 52 },
 	}, {
 		.mapbase	= 0xa4410000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs           = { 56, 57, 59, 58 },
+		.irqs           = { 56, 56, 56, 56 },
 	}, {
 
 		.flags = 0,
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/setup-sh7720.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  * SH7720 Setup
  *
  *  Copyright (C) 2007  Markus Brunner, Mark Jonas
+ *  Copyright (C) 2009  Paul Mundt
  *
  *  Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c:
  *
@@ -26,17 +27,7 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 22,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
+		/* Shared Period/Carry/Alarm IRQ */
 		.start	= 20,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -150,62 +141,49 @@ enum {
 	UNUSED = 0,
 
 	/* interrupt sources */
-	TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
+	TMU0, TMU1, TMU2, RTC,
+	WDT, REF_RCMI, SIM,
 	IRQ0, IRQ1, IRQ2, IRQ3,
 	USBF_SPD, TMU_SUNI, IRQ5, IRQ4,
-	DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL,
-	ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT,
+	DMAC1, LCDC, SSL,
+	ADC, DMAC2, USBFI, CMT,
 	SCIF0, SCIF1,
-	PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC,
-	SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC,
+	PINT07, PINT815, TPU, IIC,
+	SIOF0, SIOF1, MMC, PCC,
 	USBHI, AFEIF,
 	H_UDI,
-	/* interrupt groups */
-	TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC,
 };
 
 static struct intc_vect vectors[] __initdata = {
 	/* IRQ0->5 are handled in setup-sh3.c */
 	INTC_VECT(TMU0, 0x400),       INTC_VECT(TMU1, 0x420),
-	INTC_VECT(TMU2, 0x440),       INTC_VECT(RTC_ATI, 0x480),
-	INTC_VECT(RTC_PRI, 0x4a0),    INTC_VECT(RTC_CUI, 0x4c0),
-	INTC_VECT(SIM_ERI, 0x4e0),    INTC_VECT(SIM_RXI, 0x500),
-	INTC_VECT(SIM_TXI, 0x520),    INTC_VECT(SIM_TEND, 0x540),
+	INTC_VECT(TMU2, 0x440),       INTC_VECT(RTC, 0x480),
+	INTC_VECT(RTC, 0x4a0),	      INTC_VECT(RTC, 0x4c0),
+	INTC_VECT(SIM, 0x4e0),	      INTC_VECT(SIM, 0x500),
+	INTC_VECT(SIM, 0x520),	      INTC_VECT(SIM, 0x540),
 	INTC_VECT(WDT, 0x560),        INTC_VECT(REF_RCMI, 0x580),
 	/* H_UDI cannot be masked */  INTC_VECT(TMU_SUNI, 0x6c0),
-	INTC_VECT(USBF_SPD, 0x6e0),   INTC_VECT(DMAC1_DEI0, 0x800),
-	INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840),
-	INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900),
+	INTC_VECT(USBF_SPD, 0x6e0),   INTC_VECT(DMAC1, 0x800),
+	INTC_VECT(DMAC1, 0x820),      INTC_VECT(DMAC1, 0x840),
+	INTC_VECT(DMAC1, 0x860),      INTC_VECT(LCDC, 0x900),
 #if defined(CONFIG_CPU_SUBTYPE_SH7720)
 	INTC_VECT(SSL, 0x980),
 #endif
-	INTC_VECT(USBFI0, 0xa20),     INTC_VECT(USBFI1, 0xa40),
+	INTC_VECT(USBFI, 0xa20),      INTC_VECT(USBFI, 0xa40),
 	INTC_VECT(USBHI, 0xa60),
-	INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0),
+	INTC_VECT(DMAC2, 0xb80),      INTC_VECT(DMAC2, 0xba0),
 	INTC_VECT(ADC, 0xbe0),        INTC_VECT(SCIF0, 0xc00),
 	INTC_VECT(SCIF1, 0xc20),      INTC_VECT(PINT07, 0xc80),
 	INTC_VECT(PINT815, 0xca0),    INTC_VECT(SIOF0, 0xd00),
-	INTC_VECT(SIOF1, 0xd20),      INTC_VECT(TPU0, 0xd80),
-	INTC_VECT(TPU1, 0xda0),       INTC_VECT(TPU2, 0xdc0),
-	INTC_VECT(TPU3, 0xde0),       INTC_VECT(IIC, 0xe00),
-	INTC_VECT(MMCI0, 0xe80),      INTC_VECT(MMCI1, 0xea0),
-	INTC_VECT(MMCI2, 0xec0),      INTC_VECT(MMCI3, 0xee0),
+	INTC_VECT(SIOF1, 0xd20),      INTC_VECT(TPU, 0xd80),
+	INTC_VECT(TPU, 0xda0),        INTC_VECT(TPU, 0xdc0),
+	INTC_VECT(TPU, 0xde0),        INTC_VECT(IIC, 0xe00),
+	INTC_VECT(MMC, 0xe80),        INTC_VECT(MMC, 0xea0),
+	INTC_VECT(MMC, 0xec0),        INTC_VECT(MMC, 0xee0),
 	INTC_VECT(CMT, 0xf00),        INTC_VECT(PCC, 0xf60),
 	INTC_VECT(AFEIF, 0xfe0),
 };
 
-static struct intc_group groups[] __initdata = {
-	INTC_GROUP(TMU, TMU0, TMU1, TMU2),
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
-	INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3),
-	INTC_GROUP(USBFI, USBFI0, USBFI1),
-	INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5),
-	INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3),
-	INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3),
-};
-
 static struct intc_prio_reg prio_registers[] __initdata = {
 	{ 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
 	{ 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
@@ -219,7 +197,7 @@ static struct intc_prio_reg prio_registe
 	{ 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } },
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, NULL,
 		NULL, prio_registers, NULL);
 
 void __init plat_irq_setup(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/swsusp.S linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/swsusp.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh3/swsusp.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh3/swsusp.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,147 @@
+/*
+ * arch/sh/kernel/cpu/sh3/swsusp.S
+ *
+ * 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/page.h>
+
+#define k0	r0
+#define k1	r1
+#define k2	r2
+#define k3	r3
+#define k4	r4
+
+! swsusp_arch_resume()
+! - copy restore_pblist pages
+! - restore registers from swsusp_arch_regs_cpu0
+
+ENTRY(swsusp_arch_resume)
+	mov.l	1f, r15
+	mov.l	2f, r4
+	mov.l	@r4, r4
+
+swsusp_copy_loop:
+	mov	r4, r0
+	cmp/eq	#0, r0
+	bt	swsusp_restore_regs
+
+	mov.l	@(PBE_ADDRESS, r4), r2
+	mov.l	@(PBE_ORIG_ADDRESS, r4), r5
+
+	mov	#(PAGE_SIZE >> 10), r3
+	shll8	r3
+	shlr2	r3 /* PAGE_SIZE / 16 */
+swsusp_copy_page:
+	dt	r3
+	mov.l	@r2+,r1   /*  16n+0 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1	  /*  16n+4 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1   /*  16n+8 */
+	mov.l	r1,@r5
+	add	#4,r5
+	mov.l	@r2+,r1   /*  16n+12 */
+	mov.l	r1,@r5
+	bf/s	swsusp_copy_page
+	 add	#4,r5
+
+	bra	swsusp_copy_loop
+	 mov.l	@(PBE_NEXT, r4), r4
+
+swsusp_restore_regs:
+	! BL=0: R7->R0 is bank0
+	mov.l	3f, r8
+	mov.l	4f, r5
+	jsr	@r5
+	 nop
+
+	! BL=1: R7->R0 is bank1
+	lds	k2, pr
+	ldc	k3, ssr
+
+	mov.l	@r15+, r0
+	mov.l	@r15+, r1
+	mov.l	@r15+, r2
+	mov.l	@r15+, r3
+	mov.l	@r15+, r4
+	mov.l	@r15+, r5
+	mov.l	@r15+, r6
+	mov.l	@r15+, r7
+
+	rte
+	 nop
+	! BL=0: R7->R0 is bank0
+
+	.align	2
+1:	.long	swsusp_arch_regs_cpu0
+2:	.long	restore_pblist
+3:	.long	0x20000000 ! RB=1
+4:	.long	restore_regs
+
+! swsusp_arch_suspend()
+! - prepare pc for resume, return from function without swsusp_save on resume
+! - save registers in swsusp_arch_regs_cpu0
+! - call swsusp_save write suspend image
+
+ENTRY(swsusp_arch_suspend)
+	sts	pr, r0		! save pr in r0
+	mov	r15, r2		! save sp in r2
+	mov	r8, r5		! save r8 in r5
+	stc	sr, r1
+	ldc	r1, ssr		! save sr in ssr
+	mov.l	1f, r1
+	ldc	r1, spc		! setup pc value for resuming
+	mov.l	5f, r15		! use swsusp_arch_regs_cpu0 as stack
+	mov.l	6f, r3
+	add	r3, r15		! save from top of structure
+
+	! BL=0: R7->R0 is bank0
+	mov.l	2f, r3		! get new SR value for bank1
+	mov	#0, r4
+	mov.l	7f, r1
+	jsr	@r1		! switch to bank1 and save bank1 r7->r0
+	 not	r4, r4
+
+	! BL=1: R7->R0 is bank1
+	stc	r2_bank, k0	! fetch old sp from r2_bank0
+	mov.l	3f, k4		! SR bits to clear in k4
+	mov.l	8f, k1
+	jsr	@k1		! switch to bank0 and save all regs
+	 stc	r0_bank, k3	! fetch old pr from r0_bank0
+
+	! BL=0: R7->R0 is bank0
+	mov	r2, r15		! restore old sp
+	mov	r5, r8		! restore old r8
+	stc	ssr, r1
+	ldc	r1, sr		! restore old sr
+	lds	r0, pr		! restore old pr
+	mov.l	4f, r0
+	jmp	@r0
+	 nop
+
+swsusp_call_save:
+	mov	r2, r15		! restore old sp
+	mov	r5, r8		! restore old r8
+	lds	r0, pr		! restore old pr
+	rts
+	 mov	#0, r0
+
+	.align	2
+1:	.long	swsusp_call_save
+2:	.long	0x20000000 ! RB=1
+3:	.long	0xdfffffff ! RB=0
+4:	.long	swsusp_save
+5:	.long	swsusp_arch_regs_cpu0
+6:	.long	SWSUSP_ARCH_REGS_SIZE
+7:	.long	save_low_regs
+8:	.long	save_regs
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/Makefile linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
 obj-y	:= probe.o common.o
 common-y	+= $(addprefix ../sh3/, entry.o ex.o)
 
+obj-$(CONFIG_HIBERNATION)		+= $(addprefix ../sh3/, swsusp.o)
 obj-$(CONFIG_SH_FPU)			+= fpu.o softfloat.o
 obj-$(CONFIG_SH_STORE_QUEUES)		+= sq.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/probe.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/probe.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/probe.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,6 +129,13 @@ int __init detect_cpu_and_cache_system(v
 		boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
 					  CPU_HAS_LLSC;
 		break;
+	case 0x4004:
+		boot_cpu_data.type = CPU_SH7786;
+		boot_cpu_data.icache.ways = 4;
+		boot_cpu_data.dcache.ways = 4;
+		boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
+			CPU_HAS_LLSC | CPU_HAS_PTEAEX;
+		break;
 	case 0x3008:
 		boot_cpu_data.icache.ways = 4;
 		boot_cpu_data.dcache.ways = 4;
@@ -192,11 +199,6 @@ int __init detect_cpu_and_cache_system(v
 		break;
 	}
 
-#ifdef CONFIG_SH_DIRECT_MAPPED
-	boot_cpu_data.icache.ways = 1;
-	boot_cpu_data.dcache.ways = 1;
-#endif
-
 #ifdef CONFIG_CPU_HAS_PTEA
 	boot_cpu_data.flags |= CPU_HAS_PTEA;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4/setup-sh7750.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,17 +21,7 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 22,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
+		/* Shared Period/Carry/Alarm IRQ */
 		.start	= 20,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -50,13 +40,13 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xffe00000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCI,
-		.irqs		= { 23, 24, 25, 0 },
+		.irqs		= { 23, 23, 23, 0 },
 	}, {
 #endif
 		.mapbase	= 0xffe80000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
+		.irqs		= { 40, 40, 40, 40 },
 	}, {
 		.flags = 0,
 	}
@@ -87,43 +77,27 @@ enum {
 
 	/* interrupt sources */
 	IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
-	HUDI, GPIOI,
-	DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
-	DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
-	DMAC_DMAE,
+	HUDI, GPIOI, DMAC,
 	PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
 	PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
-	TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
-	SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
-	WDT,
-	REF_RCMI, REF_ROVI,
+	TMU3, TMU4, TMU0, TMU1, TMU2, RTC, SCI1, SCIF, WDT, REF,
 
 	/* interrupt groups */
-	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+	PCIC1,
 };
 
 static struct intc_vect vectors[] __initdata = {
 	INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
 	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
-	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
-	INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
-	INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
-	INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
-	INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
+	INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
+	INTC_VECT(SCI1, 0x4e0), INTC_VECT(SCI1, 0x500),
+	INTC_VECT(SCI1, 0x520), INTC_VECT(SCI1, 0x540),
+	INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720),
+	INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760),
 	INTC_VECT(WDT, 0x560),
-	INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
-};
-
-static struct intc_group groups[] __initdata = {
-	INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
-	INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
-	INTC_GROUP(REF, REF_RCMI, REF_ROVI),
+	INTC_VECT(REF, 0x580), INTC_VECT(REF, 0x5a0),
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -136,7 +110,7 @@ static struct intc_prio_reg prio_registe
 						 PCIC1, PCIC0_PCISERR } },
 };
 
-static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, NULL,
 			 NULL, prio_registers, NULL);
 
 /* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
@@ -145,39 +119,28 @@ static DECLARE_INTC_DESC(intc_desc, "sh7
 	defined(CONFIG_CPU_SUBTYPE_SH7751) || \
 	defined(CONFIG_CPU_SUBTYPE_SH7091)
 static struct intc_vect vectors_dma4[] __initdata = {
-	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
-	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
-	INTC_VECT(DMAC_DMAE, 0x6c0),
-};
-
-static struct intc_group groups_dma4[] __initdata = {
-	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
-		   DMAC_DMTE3, DMAC_DMAE),
+	INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+	INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+	INTC_VECT(DMAC, 0x6c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
-			 vectors_dma4, groups_dma4,
+			 vectors_dma4, NULL,
 			 NULL, prio_registers, NULL);
 #endif
 
 /* SH7750R and SH7751R both have 8-channel DMA controllers */
 #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
 static struct intc_vect vectors_dma8[] __initdata = {
-	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
-	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
-	INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
-	INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
-	INTC_VECT(DMAC_DMAE, 0x6c0),
-};
-
-static struct intc_group groups_dma8[] __initdata = {
-	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
-		   DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
-		   DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
+	INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+	INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+	INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
+	INTC_VECT(DMAC, 0x7c0), INTC_VECT(DMAC, 0x7e0),
+	INTC_VECT(DMAC, 0x6c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
-			 vectors_dma8, groups_dma8,
+			 vectors_dma8, NULL,
 			 NULL, prio_registers, NULL);
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/clock-sh7786.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+ *
+ * SH7786 support for the clock framework
+ *
+ * Copyright (C) 2008, 2009  Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7785
+ *  Copyright (C) 2007  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/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int ifc_divisors[] = { 1, 2, 4, 1 };
+static int sfc_divisors[] = { 1, 1, 4, 1 };
+static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 1,
+			     24, 32, 1, 1, 1, 1, 1, 1 };
+static int mfc_divisors[] = { 1, 1, 4, 1 };
+static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1,
+			      24, 32, 1, 48, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
+}
+
+static struct clk_ops sh7786_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQMR1) & 0x000f);
+	clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7786_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7786_clk_ops[] = {
+	&sh7786_master_clk_ops,
+	&sh7786_module_clk_ops,
+	&sh7786_bus_clk_ops,
+	&sh7786_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7786_clk_ops))
+		*ops = sh7786_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
+	clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_shyway_clk_ops = {
+	.recalc		= shyway_clk_recalc,
+};
+
+static struct clk sh7786_shyway_clk = {
+	.name		= "shyway_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh7786_shyway_clk_ops,
+};
+
+static void ddr_clk_recalc(struct clk *clk)
+{
+	int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
+	clk->rate = clk->parent->rate / mfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_ddr_clk_ops = {
+	.recalc		= ddr_clk_recalc,
+};
+
+static struct clk sh7786_ddr_clk = {
+	.name		= "ddr_clk",
+	.flags		= CLK_ALWAYS_ENABLED,
+	.ops		= &sh7786_ddr_clk_ops,
+};
+
+/*
+ * Additional SH7786-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7786_onchip_clocks[] = {
+	&sh7786_shyway_clk,
+	&sh7786_ddr_clk,
+};
+
+static int __init sh7786_clk_init(void)
+{
+	struct clk *clk = clk_get(NULL, "master_clk");
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
+		struct clk *clkp = sh7786_onchip_clocks[i];
+
+		clkp->parent = clk;
+		clk_register(clkp);
+		clk_enable(clkp);
+	}
+
+	/*
+	 * Now that we have the rest of the clocks registered, we need to
+	 * force the parent clock to propagate so that these clocks will
+	 * automatically figure out their rate. We cheat by handing the
+	 * parent clock its current rate and forcing child propagation.
+	 */
+	clk_set_rate(clk, clk_get_rate(clk));
+
+	clk_put(clk);
+
+	return 0;
+}
+arch_initcall(sh7786_clk_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/Makefile linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7763)	+= setu
 obj-$(CONFIG_CPU_SUBTYPE_SH7770)	+= setup-sh7770.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= setup-sh7780.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7785)	+= setup-sh7785.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786)	+= setup-sh7786.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7343)	+= setup-sh7343.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7722)	+= setup-sh7722.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7723)	+= setup-sh7723.o
@@ -21,6 +22,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7763)	:= cl
 clock-$(CONFIG_CPU_SUBTYPE_SH7770)	:= clock-sh7770.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7780)	:= clock-sh7780.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7785)	:= clock-sh7785.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7786)	:= clock-sh7786.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7343)	:= clock-sh7722.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7722)	:= clock-sh7722.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7723)	:= clock-sh7722.o
@@ -31,6 +33,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SHX3)	:= cloc
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7722)	:= pinmux-sh7722.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7723)	:= pinmux-sh7723.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
 
 obj-y			+= $(clock-y)
 obj-$(CONFIG_SMP)	+= $(smp-y)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,843 @@
+/*
+ * SH7786 Pinmux
+ *
+ * Copyright (C) 2008, 2009  Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ *  Based on SH7785 pinmux
+ *
+ *  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/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7786.h>
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+	PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+	PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+	PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+	PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+	PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+	PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+	PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+	PE7_DATA, PE6_DATA,
+	PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+	PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+	PG7_DATA, PG6_DATA, PG5_DATA,
+	PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+	PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
+	PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+	PJ3_DATA, PJ2_DATA, PJ1_DATA,
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+	PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+	PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+	PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+	PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+	PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+	PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+	PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+	PE7_IN, PE6_IN,
+	PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+	PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+	PG7_IN, PG6_IN, PG5_IN,
+	PH7_IN, PH6_IN, PH5_IN, PH4_IN,
+	PH3_IN, PH2_IN, PH1_IN, PH0_IN,
+	PJ7_IN, PJ6_IN, PJ5_IN, PJ4_IN,
+	PJ3_IN, PJ2_IN, PJ1_IN,
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PA7_IN_PU, PA6_IN_PU, PA5_IN_PU, PA4_IN_PU,
+	PA3_IN_PU, PA2_IN_PU, PA1_IN_PU, PA0_IN_PU,
+	PB7_IN_PU, PB6_IN_PU, PB5_IN_PU, PB4_IN_PU,
+	PB3_IN_PU, PB2_IN_PU, PB1_IN_PU, PB0_IN_PU,
+	PC7_IN_PU, PC6_IN_PU, PC5_IN_PU, PC4_IN_PU,
+	PC3_IN_PU, PC2_IN_PU, PC1_IN_PU, PC0_IN_PU,
+	PD7_IN_PU, PD6_IN_PU, PD5_IN_PU, PD4_IN_PU,
+	PD3_IN_PU, PD2_IN_PU, PD1_IN_PU, PD0_IN_PU,
+	PE7_IN_PU, PE6_IN_PU,
+	PF7_IN_PU, PF6_IN_PU, PF5_IN_PU, PF4_IN_PU,
+	PF3_IN_PU, PF2_IN_PU, PF1_IN_PU, PF0_IN_PU,
+	PG7_IN_PU, PG6_IN_PU, PG5_IN_PU,
+	PH7_IN_PU, PH6_IN_PU, PH5_IN_PU, PH4_IN_PU,
+	PH3_IN_PU, PH2_IN_PU, PH1_IN_PU, PH0_IN_PU,
+	PJ7_IN_PU, PJ6_IN_PU, PJ5_IN_PU, PJ4_IN_PU,
+	PJ3_IN_PU, PJ2_IN_PU, PJ1_IN_PU,
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
+	PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
+	PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
+	PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
+	PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+	PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+	PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+	PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+	PE7_OUT, PE6_OUT,
+	PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+	PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+	PG7_OUT, PG6_OUT, PG5_OUT,
+	PH7_OUT, PH6_OUT, PH5_OUT, PH4_OUT,
+	PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
+	PJ7_OUT, PJ6_OUT, PJ5_OUT, PJ4_OUT,
+	PJ3_OUT, PJ2_OUT, PJ1_OUT,
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PA7_FN, PA6_FN, PA5_FN, PA4_FN,
+	PA3_FN, PA2_FN, PA1_FN, PA0_FN,
+	PB7_FN, PB6_FN, PB5_FN, PB4_FN,
+	PB3_FN, PB2_FN, PB1_FN, PB0_FN,
+	PC7_FN, PC6_FN, PC5_FN, PC4_FN,
+	PC3_FN, PC2_FN, PC1_FN, PC0_FN,
+	PD7_FN, PD6_FN, PD5_FN, PD4_FN,
+	PD3_FN, PD2_FN, PD1_FN, PD0_FN,
+	PE7_FN, PE6_FN,
+	PF7_FN, PF6_FN, PF5_FN, PF4_FN,
+	PF3_FN, PF2_FN, PF1_FN, PF0_FN,
+	PG7_FN, PG6_FN, PG5_FN,
+	PH7_FN, PH6_FN, PH5_FN, PH4_FN,
+	PH3_FN, PH2_FN, PH1_FN, PH0_FN,
+	PJ7_FN, PJ6_FN, PJ5_FN, PJ4_FN,
+	PJ3_FN, PJ2_FN, PJ1_FN,
+	P1MSEL14_0, P1MSEL14_1,
+	P1MSEL13_0, P1MSEL13_1,
+	P1MSEL12_0, P1MSEL12_1,
+	P1MSEL11_0, P1MSEL11_1,
+	P1MSEL10_0, P1MSEL10_1,
+	P1MSEL9_0, P1MSEL9_1,
+	P1MSEL8_0, P1MSEL8_1,
+	P1MSEL7_0, P1MSEL7_1,
+	P1MSEL6_0, P1MSEL6_1,
+	P1MSEL5_0, P1MSEL5_1,
+	P1MSEL4_0, P1MSEL4_1,
+	P1MSEL3_0, P1MSEL3_1,
+	P1MSEL2_0, P1MSEL2_1,
+	P1MSEL1_0, P1MSEL1_1,
+	P1MSEL0_0, P1MSEL0_1,
+
+	P2MSEL15_0, P2MSEL15_1,
+	P2MSEL14_0, P2MSEL14_1,
+	P2MSEL13_0, P2MSEL13_1,
+	P2MSEL12_0, P2MSEL12_1,
+	P2MSEL11_0, P2MSEL11_1,
+	P2MSEL10_0, P2MSEL10_1,
+	P2MSEL9_0, P2MSEL9_1,
+	P2MSEL8_0, P2MSEL8_1,
+	P2MSEL7_0, P2MSEL7_1,
+	P2MSEL6_0, P2MSEL6_1,
+	P2MSEL5_0, P2MSEL5_1,
+	P2MSEL4_0, P2MSEL4_1,
+	P2MSEL3_0, P2MSEL3_1,
+	P2MSEL2_0, P2MSEL2_1,
+	P2MSEL1_0, P2MSEL1_1,
+	P2MSEL0_0, P2MSEL0_1,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+	DCLKIN_MARK, DCLKOUT_MARK, ODDF_MARK,
+	VSYNC_MARK, HSYNC_MARK, CDE_MARK, DISP_MARK,
+	DR0_MARK, DR1_MARK, DR2_MARK, DR3_MARK, DR4_MARK, DR5_MARK,
+	DG0_MARK, DG1_MARK, DG2_MARK, DG3_MARK, DG4_MARK, DG5_MARK,
+	DB0_MARK, DB1_MARK, DB2_MARK, DB3_MARK, DB4_MARK, DB5_MARK,
+	ETH_MAGIC_MARK, ETH_LINK_MARK, ETH_TX_ER_MARK, ETH_TX_EN_MARK,
+	ETH_MDIO_MARK, ETH_RX_CLK_MARK, ETH_MDC_MARK, ETH_COL_MARK,
+	ETH_TX_CLK_MARK, ETH_CRS_MARK, ETH_RX_DV_MARK, ETH_RX_ER_MARK,
+	ETH_TXD3_MARK, ETH_TXD2_MARK, ETH_TXD1_MARK, ETH_TXD0_MARK,
+	ETH_RXD3_MARK, ETH_RXD2_MARK, ETH_RXD1_MARK, ETH_RXD0_MARK,
+	HSPI_CLK_MARK, HSPI_CS_MARK, HSPI_RX_MARK, HSPI_TX_MARK,
+	SCIF0_CTS_MARK, SCIF0_RTS_MARK,
+	SCIF0_SCK_MARK, SCIF0_RXD_MARK, SCIF0_TXD_MARK,
+	SCIF1_SCK_MARK, SCIF1_RXD_MARK, SCIF1_TXD_MARK,
+	SCIF3_SCK_MARK, SCIF3_RXD_MARK, SCIF3_TXD_MARK,
+	SCIF4_SCK_MARK, SCIF4_RXD_MARK, SCIF4_TXD_MARK,
+	SCIF5_SCK_MARK, SCIF5_RXD_MARK, SCIF5_TXD_MARK,
+	BREQ_MARK, IOIS16_MARK, CE2B_MARK, CE2A_MARK, BACK_MARK,
+	FALE_MARK, FRB_MARK, FSTATUS_MARK,
+	FSE_MARK, FCLE_MARK,
+	DACK0_MARK, DACK1_MARK, DACK2_MARK, DACK3_MARK,
+	DREQ0_MARK, DREQ1_MARK, DREQ2_MARK, DREQ3_MARK,
+	DRAK0_MARK, DRAK1_MARK, DRAK2_MARK, DRAK3_MARK,
+	USB_OVC1_MARK, USB_OVC0_MARK,
+	USB_PENC1_MARK, USB_PENC0_MARK,
+	HAC_RES_MARK,
+	HAC1_SDOUT_MARK, HAC1_SDIN_MARK, HAC1_SYNC_MARK, HAC1_BITCLK_MARK,
+	HAC0_SDOUT_MARK, HAC0_SDIN_MARK, HAC0_SYNC_MARK, HAC0_BITCLK_MARK,
+	SSI0_SDATA_MARK, SSI0_SCK_MARK, SSI0_WS_MARK, SSI0_CLK_MARK,
+	SSI1_SDATA_MARK, SSI1_SCK_MARK, SSI1_WS_MARK, SSI1_CLK_MARK,
+	SSI2_SDATA_MARK, SSI2_SCK_MARK, SSI2_WS_MARK,
+	SSI3_SDATA_MARK, SSI3_SCK_MARK, SSI3_WS_MARK,
+	SDIF1CMD_MARK, SDIF1CD_MARK, SDIF1WP_MARK, SDIF1CLK_MARK,
+	SDIF1D3_MARK, SDIF1D2_MARK, SDIF1D1_MARK, SDIF1D0_MARK,
+	SDIF0CMD_MARK, SDIF0CD_MARK, SDIF0WP_MARK, SDIF0CLK_MARK,
+	SDIF0D3_MARK, SDIF0D2_MARK, SDIF0D1_MARK, SDIF0D0_MARK,
+	TCLK_MARK,
+	IRL7_MARK, IRL6_MARK, IRL5_MARK, IRL4_MARK,
+	PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+
+	/* PA GPIO */
+	PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU),
+	PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT, PA6_IN_PU),
+	PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT, PA5_IN_PU),
+	PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT, PA4_IN_PU),
+	PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT, PA3_IN_PU),
+	PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT, PA2_IN_PU),
+	PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT, PA1_IN_PU),
+	PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT, PA0_IN_PU),
+
+	/* PB GPIO */
+	PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT, PB7_IN_PU),
+	PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT, PB6_IN_PU),
+	PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT, PB5_IN_PU),
+	PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT, PB4_IN_PU),
+	PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT, PB3_IN_PU),
+	PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT, PB2_IN_PU),
+	PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT, PB1_IN_PU),
+	PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT, PB0_IN_PU),
+
+	/* PC GPIO */
+	PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT, PC7_IN_PU),
+	PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT, PC6_IN_PU),
+	PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT, PC5_IN_PU),
+	PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT, PC4_IN_PU),
+	PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT, PC3_IN_PU),
+	PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT, PC2_IN_PU),
+	PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT, PC1_IN_PU),
+	PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT, PC0_IN_PU),
+
+	/* PD GPIO */
+	PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT, PD7_IN_PU),
+	PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT, PD6_IN_PU),
+	PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT, PD5_IN_PU),
+	PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT, PD4_IN_PU),
+	PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT, PD3_IN_PU),
+	PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT, PD2_IN_PU),
+	PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT, PD1_IN_PU),
+	PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT, PD0_IN_PU),
+
+	/* PE GPIO */
+	PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT, PE7_IN_PU),
+	PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT, PE6_IN_PU),
+
+	/* PF GPIO */
+	PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT, PF7_IN_PU),
+	PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT, PF6_IN_PU),
+	PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT, PF5_IN_PU),
+	PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT, PF4_IN_PU),
+	PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT, PF3_IN_PU),
+	PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT, PF2_IN_PU),
+	PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT, PF1_IN_PU),
+	PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT, PF0_IN_PU),
+
+	/* PG GPIO */
+	PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT, PG7_IN_PU),
+	PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT, PG6_IN_PU),
+	PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT, PG5_IN_PU),
+
+	/* PH GPIO */
+	PINMUX_DATA(PH7_DATA, PH7_IN, PH7_OUT, PH7_IN_PU),
+	PINMUX_DATA(PH6_DATA, PH6_IN, PH6_OUT, PH6_IN_PU),
+	PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT, PH5_IN_PU),
+	PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT, PH4_IN_PU),
+	PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT, PH3_IN_PU),
+	PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT, PH2_IN_PU),
+	PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT, PH1_IN_PU),
+	PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT, PH0_IN_PU),
+
+	/* PJ GPIO */
+	PINMUX_DATA(PJ7_DATA, PJ7_IN, PJ7_OUT, PJ7_IN_PU),
+	PINMUX_DATA(PJ6_DATA, PJ6_IN, PJ6_OUT, PJ6_IN_PU),
+	PINMUX_DATA(PJ5_DATA, PJ5_IN, PJ5_OUT, PJ5_IN_PU),
+	PINMUX_DATA(PJ4_DATA, PJ4_IN, PJ4_OUT, PJ4_IN_PU),
+	PINMUX_DATA(PJ3_DATA, PJ3_IN, PJ3_OUT, PJ3_IN_PU),
+	PINMUX_DATA(PJ2_DATA, PJ2_IN, PJ2_OUT, PJ2_IN_PU),
+	PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT, PJ1_IN_PU),
+
+	/* PA FN */
+	PINMUX_DATA(CDE_MARK,		P1MSEL2_0, PA7_FN),
+	PINMUX_DATA(DISP_MARK,		P1MSEL2_0, PA6_FN),
+	PINMUX_DATA(DR5_MARK,		P1MSEL2_0, PA5_FN),
+	PINMUX_DATA(DR4_MARK,		P1MSEL2_0, PA4_FN),
+	PINMUX_DATA(DR3_MARK,		P1MSEL2_0, PA3_FN),
+	PINMUX_DATA(DR2_MARK,		P1MSEL2_0, PA2_FN),
+	PINMUX_DATA(DR1_MARK,		P1MSEL2_0, PA1_FN),
+	PINMUX_DATA(DR0_MARK,		P1MSEL2_0, PA0_FN),
+	PINMUX_DATA(ETH_MAGIC_MARK,	P1MSEL2_1, PA7_FN),
+	PINMUX_DATA(ETH_LINK_MARK,	P1MSEL2_1, PA6_FN),
+	PINMUX_DATA(ETH_TX_ER_MARK,	P1MSEL2_1, PA5_FN),
+	PINMUX_DATA(ETH_TX_EN_MARK,	P1MSEL2_1, PA4_FN),
+	PINMUX_DATA(ETH_TXD3_MARK,	P1MSEL2_1, PA3_FN),
+	PINMUX_DATA(ETH_TXD2_MARK,	P1MSEL2_1, PA2_FN),
+	PINMUX_DATA(ETH_TXD1_MARK,	P1MSEL2_1, PA1_FN),
+	PINMUX_DATA(ETH_TXD0_MARK,	P1MSEL2_1, PA0_FN),
+
+	/* PB FN */
+	PINMUX_DATA(VSYNC_MARK,		P1MSEL3_0, PB7_FN),
+	PINMUX_DATA(ODDF_MARK,		P1MSEL3_0, PB6_FN),
+	PINMUX_DATA(DG5_MARK,		P1MSEL2_0, PB5_FN),
+	PINMUX_DATA(DG4_MARK,		P1MSEL2_0, PB4_FN),
+	PINMUX_DATA(DG3_MARK,		P1MSEL2_0, PB3_FN),
+	PINMUX_DATA(DG2_MARK,		P1MSEL2_0, PB2_FN),
+	PINMUX_DATA(DG1_MARK,		P1MSEL2_0, PB1_FN),
+	PINMUX_DATA(DG0_MARK,		P1MSEL2_0, PB0_FN),
+	PINMUX_DATA(HSPI_CLK_MARK,	P1MSEL3_1, PB7_FN),
+	PINMUX_DATA(HSPI_CS_MARK,	P1MSEL3_1, PB6_FN),
+	PINMUX_DATA(ETH_MDIO_MARK,	P1MSEL2_1, PB5_FN),
+	PINMUX_DATA(ETH_RX_CLK_MARK,	P1MSEL2_1, PB4_FN),
+	PINMUX_DATA(ETH_MDC_MARK,	P1MSEL2_1, PB3_FN),
+	PINMUX_DATA(ETH_COL_MARK,	P1MSEL2_1, PB2_FN),
+	PINMUX_DATA(ETH_TX_CLK_MARK,	P1MSEL2_1, PB1_FN),
+	PINMUX_DATA(ETH_CRS_MARK,	P1MSEL2_1, PB0_FN),
+
+	/* PC FN */
+	PINMUX_DATA(DCLKIN_MARK,	P1MSEL3_0, PC7_FN),
+	PINMUX_DATA(HSYNC_MARK,		P1MSEL3_0, PC6_FN),
+	PINMUX_DATA(DB5_MARK,		P1MSEL2_0, PC5_FN),
+	PINMUX_DATA(DB4_MARK,		P1MSEL2_0, PC4_FN),
+	PINMUX_DATA(DB3_MARK,		P1MSEL2_0, PC3_FN),
+	PINMUX_DATA(DB2_MARK,		P1MSEL2_0, PC2_FN),
+	PINMUX_DATA(DB1_MARK,		P1MSEL2_0, PC1_FN),
+	PINMUX_DATA(DB0_MARK,		P1MSEL2_0, PC0_FN),
+
+	PINMUX_DATA(HSPI_RX_MARK,	P1MSEL3_1, PC7_FN),
+	PINMUX_DATA(HSPI_TX_MARK,	P1MSEL3_1, PC6_FN),
+	PINMUX_DATA(ETH_RXD3_MARK,	P1MSEL2_1, PC5_FN),
+	PINMUX_DATA(ETH_RXD2_MARK,	P1MSEL2_1, PC4_FN),
+	PINMUX_DATA(ETH_RXD1_MARK,	P1MSEL2_1, PC3_FN),
+	PINMUX_DATA(ETH_RXD0_MARK,	P1MSEL2_1, PC2_FN),
+	PINMUX_DATA(ETH_RX_DV_MARK,	P1MSEL2_1, PC1_FN),
+	PINMUX_DATA(ETH_RX_ER_MARK,	P1MSEL2_1, PC0_FN),
+
+	/* PD FN */
+	PINMUX_DATA(DCLKOUT_MARK,	PD7_FN),
+	PINMUX_DATA(SCIF1_SCK_MARK,	PD6_FN),
+	PINMUX_DATA(SCIF1_RXD_MARK,	PD5_FN),
+	PINMUX_DATA(SCIF1_TXD_MARK,	PD4_FN),
+	PINMUX_DATA(DACK1_MARK,		P1MSEL13_1, P1MSEL12_0, PD3_FN),
+	PINMUX_DATA(BACK_MARK,		P1MSEL13_0, P1MSEL12_1, PD3_FN),
+	PINMUX_DATA(FALE_MARK,		P1MSEL13_0, P1MSEL12_0, PD3_FN),
+	PINMUX_DATA(DACK0_MARK,		P1MSEL14_1, PD2_FN),
+	PINMUX_DATA(FCLE_MARK,		P1MSEL14_0, PD2_FN),
+	PINMUX_DATA(DREQ1_MARK,		P1MSEL10_0, P1MSEL9_1, PD1_FN),
+	PINMUX_DATA(BREQ_MARK,		P1MSEL10_1, P1MSEL9_0, PD1_FN),
+	PINMUX_DATA(USB_OVC1_MARK,	P1MSEL10_0, P1MSEL9_0, PD1_FN),
+	PINMUX_DATA(DREQ0_MARK,		P1MSEL11_1, PD0_FN),
+	PINMUX_DATA(USB_OVC0_MARK,	P1MSEL11_0, PD0_FN),
+
+	/* PE FN */
+	PINMUX_DATA(USB_PENC1_MARK,	PE7_FN),
+	PINMUX_DATA(USB_PENC0_MARK,	PE6_FN),
+
+	/* PF FN */
+	PINMUX_DATA(HAC1_SDOUT_MARK,	P2MSEL15_0, P2MSEL14_0, PF7_FN),
+	PINMUX_DATA(HAC1_SDIN_MARK,	P2MSEL15_0, P2MSEL14_0, PF6_FN),
+	PINMUX_DATA(HAC1_SYNC_MARK,	P2MSEL15_0, P2MSEL14_0, PF5_FN),
+	PINMUX_DATA(HAC1_BITCLK_MARK,	P2MSEL15_0, P2MSEL14_0, PF4_FN),
+	PINMUX_DATA(HAC0_SDOUT_MARK,	P2MSEL13_0, P2MSEL12_0, PF3_FN),
+	PINMUX_DATA(HAC0_SDIN_MARK,	P2MSEL13_0, P2MSEL12_0, PF2_FN),
+	PINMUX_DATA(HAC0_SYNC_MARK,	P2MSEL13_0, P2MSEL12_0, PF1_FN),
+	PINMUX_DATA(HAC0_BITCLK_MARK,	P2MSEL13_0, P2MSEL12_0, PF0_FN),
+	PINMUX_DATA(SSI1_SDATA_MARK,	P2MSEL15_0, P2MSEL14_1, PF7_FN),
+	PINMUX_DATA(SSI1_SCK_MARK,	P2MSEL15_0, P2MSEL14_1, PF6_FN),
+	PINMUX_DATA(SSI1_WS_MARK,	P2MSEL15_0, P2MSEL14_1, PF5_FN),
+	PINMUX_DATA(SSI1_CLK_MARK,	P2MSEL15_0, P2MSEL14_1, PF4_FN),
+	PINMUX_DATA(SSI0_SDATA_MARK,	P2MSEL13_0, P2MSEL12_1, PF3_FN),
+	PINMUX_DATA(SSI0_SCK_MARK,	P2MSEL13_0, P2MSEL12_1, PF2_FN),
+	PINMUX_DATA(SSI0_WS_MARK,	P2MSEL13_0, P2MSEL12_1, PF1_FN),
+	PINMUX_DATA(SSI0_CLK_MARK,	P2MSEL13_0, P2MSEL12_1, PF0_FN),
+	PINMUX_DATA(SDIF1CMD_MARK,	P2MSEL15_1, P2MSEL14_0, PF7_FN),
+	PINMUX_DATA(SDIF1CD_MARK,	P2MSEL15_1, P2MSEL14_0, PF6_FN),
+	PINMUX_DATA(SDIF1WP_MARK,	P2MSEL15_1, P2MSEL14_0, PF5_FN),
+	PINMUX_DATA(SDIF1CLK_MARK,	P2MSEL15_1, P2MSEL14_0, PF4_FN),
+	PINMUX_DATA(SDIF1D3_MARK,	P2MSEL13_1, P2MSEL12_0, PF3_FN),
+	PINMUX_DATA(SDIF1D2_MARK,	P2MSEL13_1, P2MSEL12_0, PF2_FN),
+	PINMUX_DATA(SDIF1D1_MARK,	P2MSEL13_1, P2MSEL12_0, PF1_FN),
+	PINMUX_DATA(SDIF1D0_MARK,	P2MSEL13_1, P2MSEL12_0, PF0_FN),
+
+	/* PG FN */
+	PINMUX_DATA(SCIF3_SCK_MARK,	P1MSEL8_0, PG7_FN),
+	PINMUX_DATA(SSI2_SDATA_MARK,	P1MSEL8_1, PG7_FN),
+	PINMUX_DATA(SCIF3_RXD_MARK,	P1MSEL7_0, P1MSEL6_0, PG6_FN),
+	PINMUX_DATA(SSI2_SCK_MARK,	P1MSEL7_1, P1MSEL6_0, PG6_FN),
+	PINMUX_DATA(TCLK_MARK,		P1MSEL7_0, P1MSEL6_1, PG6_FN),
+	PINMUX_DATA(SCIF3_TXD_MARK,	P1MSEL5_0, P1MSEL4_0, PG5_FN),
+	PINMUX_DATA(SSI2_WS_MARK,	P1MSEL5_1, P1MSEL4_0, PG5_FN),
+	PINMUX_DATA(HAC_RES_MARK,	P1MSEL5_0, P1MSEL4_1, PG5_FN),
+
+	/* PH FN */
+	PINMUX_DATA(DACK3_MARK,		P2MSEL4_0, PH7_FN),
+	PINMUX_DATA(SDIF0CMD_MARK,	P2MSEL4_1, PH7_FN),
+	PINMUX_DATA(DACK2_MARK,		P2MSEL4_0, PH6_FN),
+	PINMUX_DATA(SDIF0CD_MARK,	P2MSEL4_1, PH6_FN),
+	PINMUX_DATA(DREQ3_MARK,		P2MSEL4_0, PH5_FN),
+	PINMUX_DATA(SDIF0WP_MARK,	P2MSEL4_1, PH5_FN),
+	PINMUX_DATA(DREQ2_MARK,		P2MSEL3_0, P2MSEL2_1, PH4_FN),
+	PINMUX_DATA(SDIF0CLK_MARK,	P2MSEL3_1, P2MSEL2_0, PH4_FN),
+	PINMUX_DATA(SCIF0_CTS_MARK,	P2MSEL3_0, P2MSEL2_0, PH4_FN),
+	PINMUX_DATA(SDIF0D3_MARK,	P2MSEL1_1, P2MSEL0_0, PH3_FN),
+	PINMUX_DATA(SCIF0_RTS_MARK,	P2MSEL1_0, P2MSEL0_0, PH3_FN),
+	PINMUX_DATA(IRL7_MARK,		P2MSEL1_0, P2MSEL0_1, PH3_FN),
+	PINMUX_DATA(SDIF0D2_MARK,	P2MSEL1_1, P2MSEL0_0, PH2_FN),
+	PINMUX_DATA(SCIF0_SCK_MARK,	P2MSEL1_0, P2MSEL0_0, PH2_FN),
+	PINMUX_DATA(IRL6_MARK,		P2MSEL1_0, P2MSEL0_1, PH2_FN),
+	PINMUX_DATA(SDIF0D1_MARK,	P2MSEL1_1, P2MSEL0_0, PH1_FN),
+	PINMUX_DATA(SCIF0_RXD_MARK,	P2MSEL1_0, P2MSEL0_0, PH1_FN),
+	PINMUX_DATA(IRL5_MARK,		P2MSEL1_0, P2MSEL0_1, PH1_FN),
+	PINMUX_DATA(SDIF0D0_MARK,	P2MSEL1_1, P2MSEL0_0, PH0_FN),
+	PINMUX_DATA(SCIF0_TXD_MARK,	P2MSEL1_0, P2MSEL0_0, PH0_FN),
+	PINMUX_DATA(IRL4_MARK,		P2MSEL1_0, P2MSEL0_1, PH0_FN),
+
+	/* PJ FN */
+	PINMUX_DATA(SCIF5_SCK_MARK,	P2MSEL11_1, PJ7_FN),
+	PINMUX_DATA(FRB_MARK,		P2MSEL11_0, PJ7_FN),
+	PINMUX_DATA(SCIF5_RXD_MARK,	P2MSEL10_0, PJ6_FN),
+	PINMUX_DATA(IOIS16_MARK,	P2MSEL10_1, PJ6_FN),
+	PINMUX_DATA(SCIF5_TXD_MARK,	P2MSEL10_0, PJ5_FN),
+	PINMUX_DATA(CE2B_MARK,		P2MSEL10_1, PJ5_FN),
+	PINMUX_DATA(DRAK3_MARK,		P2MSEL7_0, PJ4_FN),
+	PINMUX_DATA(CE2A_MARK,		P2MSEL7_1, PJ4_FN),
+	PINMUX_DATA(SCIF4_SCK_MARK,	P2MSEL9_0, P2MSEL8_0, PJ3_FN),
+	PINMUX_DATA(DRAK2_MARK,		P2MSEL9_0, P2MSEL8_1, PJ3_FN),
+	PINMUX_DATA(SSI3_WS_MARK,	P2MSEL9_1, P2MSEL8_0, PJ3_FN),
+	PINMUX_DATA(SCIF4_RXD_MARK,	P2MSEL6_1, P2MSEL5_0, PJ2_FN),
+	PINMUX_DATA(DRAK1_MARK,		P2MSEL6_0, P2MSEL5_1, PJ2_FN),
+	PINMUX_DATA(FSTATUS_MARK,	P2MSEL6_0, P2MSEL5_0, PJ2_FN),
+	PINMUX_DATA(SSI3_SDATA_MARK,	P2MSEL6_1, P2MSEL5_1, PJ2_FN),
+	PINMUX_DATA(SCIF4_TXD_MARK,	P2MSEL6_1, P2MSEL5_0, PJ1_FN),
+	PINMUX_DATA(DRAK0_MARK,		P2MSEL6_0, P2MSEL5_1, PJ1_FN),
+	PINMUX_DATA(FSE_MARK,		P2MSEL6_0, P2MSEL5_0, PJ1_FN),
+	PINMUX_DATA(SSI3_SCK_MARK,	P2MSEL6_1, P2MSEL5_1, PJ1_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	/* PA */
+	PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+	PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+	PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+	PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+	PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+	PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+	PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+	PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+	/* PB */
+	PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+	PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+	PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+	PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+	PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+	PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+	PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+	PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+	/* PC */
+	PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+	PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+	PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+	PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+	PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+	PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+	PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+	PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+	/* PD */
+	PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+	PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+	PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+	PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+	PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+	PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+	PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+	PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+	/* PE */
+	PINMUX_GPIO(GPIO_PE5, PE7_DATA),
+	PINMUX_GPIO(GPIO_PE4, PE6_DATA),
+
+	/* PF */
+	PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+	PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+	PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+	PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+	PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+	PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+	PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+	PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+	/* PG */
+	PINMUX_GPIO(GPIO_PG7, PG7_DATA),
+	PINMUX_GPIO(GPIO_PG6, PG6_DATA),
+	PINMUX_GPIO(GPIO_PG5, PG5_DATA),
+
+	/* PH */
+	PINMUX_GPIO(GPIO_PH7, PH7_DATA),
+	PINMUX_GPIO(GPIO_PH6, PH6_DATA),
+	PINMUX_GPIO(GPIO_PH5, PH5_DATA),
+	PINMUX_GPIO(GPIO_PH4, PH4_DATA),
+	PINMUX_GPIO(GPIO_PH3, PH3_DATA),
+	PINMUX_GPIO(GPIO_PH2, PH2_DATA),
+	PINMUX_GPIO(GPIO_PH1, PH1_DATA),
+	PINMUX_GPIO(GPIO_PH0, PH0_DATA),
+
+	/* PJ */
+	PINMUX_GPIO(GPIO_PJ7, PJ7_DATA),
+	PINMUX_GPIO(GPIO_PJ6, PJ6_DATA),
+	PINMUX_GPIO(GPIO_PJ5, PJ5_DATA),
+	PINMUX_GPIO(GPIO_PJ4, PJ4_DATA),
+	PINMUX_GPIO(GPIO_PJ3, PJ3_DATA),
+	PINMUX_GPIO(GPIO_PJ2, PJ2_DATA),
+	PINMUX_GPIO(GPIO_PJ1, PJ1_DATA),
+
+	/* FN */
+	PINMUX_GPIO(GPIO_FN_CDE,		CDE_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_MAGIC,		ETH_MAGIC_MARK),
+	PINMUX_GPIO(GPIO_FN_DISP,		DISP_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_LINK,		ETH_LINK_MARK),
+	PINMUX_GPIO(GPIO_FN_DR5,		DR5_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TX_ER,		ETH_TX_ER_MARK),
+	PINMUX_GPIO(GPIO_FN_DR4,		DR4_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TX_EN,		ETH_TX_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_DR3,		DR3_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TXD3,		ETH_TXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_DR2,		DR2_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TXD2,		ETH_TXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_DR1,		DR1_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TXD1,		ETH_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_DR0,		DR0_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TXD0,		ETH_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_VSYNC,		VSYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_HSPI_CLK,		HSPI_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_ODDF,		ODDF_MARK),
+	PINMUX_GPIO(GPIO_FN_HSPI_CS,		HSPI_CS_MARK),
+	PINMUX_GPIO(GPIO_FN_DG5,		DG5_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_MDIO,		ETH_MDIO_MARK),
+	PINMUX_GPIO(GPIO_FN_DG4,		DG4_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RX_CLK,		ETH_RX_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_DG3,		DG3_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_MDC,		ETH_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_DG2,		DG2_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_COL,		ETH_COL_MARK),
+	PINMUX_GPIO(GPIO_FN_DG1,		DG1_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_TX_CLK,		ETH_TX_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_DG0,		DG0_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_CRS,		ETH_CRS_MARK),
+	PINMUX_GPIO(GPIO_FN_DCLKIN,		DCLKIN_MARK),
+	PINMUX_GPIO(GPIO_FN_HSPI_RX,		HSPI_RX_MARK),
+	PINMUX_GPIO(GPIO_FN_HSYNC,		HSYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_HSPI_TX,		HSPI_TX_MARK),
+	PINMUX_GPIO(GPIO_FN_DB5,		DB5_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RXD3,		ETH_RXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_DB4,		DB4_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RXD2,		ETH_RXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_DB3,		DB3_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RXD1,		ETH_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_DB2,		DB2_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RXD0,		ETH_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_DB1,		DB1_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RX_DV,		ETH_RX_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_DB0,		DB0_MARK),
+	PINMUX_GPIO(GPIO_FN_ETH_RX_ER,		ETH_RX_ER_MARK),
+	PINMUX_GPIO(GPIO_FN_DCLKOUT,		DCLKOUT_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF1_SCK,		SCIF1_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF1_RXD,		SCIF1_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF1_TXD,		SCIF1_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK1,		DACK1_MARK),
+	PINMUX_GPIO(GPIO_FN_BACK,		BACK_MARK),
+	PINMUX_GPIO(GPIO_FN_FALE,		FALE_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK0,		DACK0_MARK),
+	PINMUX_GPIO(GPIO_FN_FCLE,		FCLE_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ1,		DREQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_BREQ,		BREQ_MARK),
+	PINMUX_GPIO(GPIO_FN_USB_OVC1,		USB_OVC1_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ0,		DREQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_USB_OVC0,		USB_OVC0_MARK),
+	PINMUX_GPIO(GPIO_FN_USB_PENC1,		USB_PENC1_MARK),
+	PINMUX_GPIO(GPIO_FN_USB_PENC0,		USB_PENC0_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC1_SDOUT,		HAC1_SDOUT_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI1_SDATA,		SSI1_SDATA_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1CMD,		SDIF1CMD_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC1_SDIN,		HAC1_SDIN_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI1_SCK,		SSI1_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1CD,		SDIF1CD_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC1_SYNC,		HAC1_SYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI1_WS,		SSI1_WS_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1WP,		SDIF1WP_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC1_BITCLK,	HAC1_BITCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI1_CLK,		SSI1_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1CLK,		SDIF1CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC0_SDOUT,		HAC0_SDOUT_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI0_SDATA,		SSI0_SDATA_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1D3,		SDIF1D3_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC0_SDIN,		HAC0_SDIN_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI0_SCK,		SSI0_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1D2,		SDIF1D2_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC0_SYNC,		HAC0_SYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI0_WS,		SSI0_WS_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1D1,		SDIF1D1_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC0_BITCLK,	HAC0_BITCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI0_CLK,		SSI0_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF1D0,		SDIF1D0_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF3_SCK,		SCIF3_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI2_SDATA,		SSI2_SDATA_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF3_RXD,		SCIF3_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_TCLK,		TCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI2_SCK,		SSI2_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF3_TXD,		SCIF3_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_HAC_RES,		HAC_RES_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI2_WS,		SSI2_WS_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK3,		DACK3_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0CMD,		SDIF0CMD_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK2,		DACK2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0CD,		SDIF0CD_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ3,		DREQ3_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0WP,		SDIF0WP_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF0_CTS,		SCIF0_CTS_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ2,		DREQ2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0CLK,		SDIF0CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF0_RTS,		SCIF0_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL7,		IRL7_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0D3,		SDIF0D3_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF0_SCK,		SCIF0_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL6,		IRL6_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0D2,		SDIF0D2_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF0_RXD,		SCIF0_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL5,		IRL5_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0D1,		SDIF0D1_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF0_TXD,		SCIF0_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_IRL4,		IRL4_MARK),
+	PINMUX_GPIO(GPIO_FN_SDIF0D0,		SDIF0D0_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF5_SCK,		SCIF5_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_FRB,		FRB_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF5_RXD,		SCIF5_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_IOIS16,		IOIS16_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF5_TXD,		SCIF5_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_CE2B,		CE2B_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK3,		DRAK3_MARK),
+	PINMUX_GPIO(GPIO_FN_CE2A,		CE2A_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF4_SCK,		SCIF4_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK2,		DRAK2_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI3_WS,		SSI3_WS_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF4_RXD,		SCIF4_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK1,		DRAK1_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI3_SDATA,		SSI3_SDATA_MARK),
+	PINMUX_GPIO(GPIO_FN_FSTATUS,		FSTATUS_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF4_TXD,		SCIF4_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_DRAK0,		DRAK0_MARK),
+	PINMUX_GPIO(GPIO_FN_SSI3_SCK,		SSI3_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_FSE,		FSE_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("PACR", 0xffcc0000, 16, 2) {
+		PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU,
+		PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU,
+		PA5_FN, PA5_OUT, PA5_IN, PA5_IN_PU,
+		PA4_FN, PA4_OUT, PA4_IN, PA4_IN_PU,
+		PA3_FN, PA3_OUT, PA3_IN, PA3_IN_PU,
+		PA2_FN, PA2_OUT, PA2_IN, PA2_IN_PU,
+		PA1_FN, PA1_OUT, PA1_IN, PA1_IN_PU,
+		PA0_FN, PA0_OUT, PA0_IN, PA0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PBCR", 0xffcc0002, 16, 2) {
+		PB7_FN, PB7_OUT, PB7_IN, PB7_IN_PU,
+		PB6_FN, PB6_OUT, PB6_IN, PB6_IN_PU,
+		PB5_FN, PB5_OUT, PB5_IN, PB5_IN_PU,
+		PB4_FN, PB4_OUT, PB4_IN, PB4_IN_PU,
+		PB3_FN, PB3_OUT, PB3_IN, PB3_IN_PU,
+		PB2_FN, PB2_OUT, PB2_IN, PB2_IN_PU,
+		PB1_FN, PB1_OUT, PB1_IN, PB1_IN_PU,
+		PB0_FN, PB0_OUT, PB0_IN, PB0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PCCR", 0xffcc0004, 16, 2) {
+		PC7_FN, PC7_OUT, PC7_IN, PC7_IN_PU,
+		PC6_FN, PC6_OUT, PC6_IN, PC6_IN_PU,
+		PC5_FN, PC5_OUT, PC5_IN, PC5_IN_PU,
+		PC4_FN, PC4_OUT, PC4_IN, PC4_IN_PU,
+		PC3_FN, PC3_OUT, PC3_IN, PC3_IN_PU,
+		PC2_FN, PC2_OUT, PC2_IN, PC2_IN_PU,
+		PC1_FN, PC1_OUT, PC1_IN, PC1_IN_PU,
+		PC0_FN, PC0_OUT, PC0_IN, PC0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PDCR", 0xffcc0006, 16, 2) {
+		PD7_FN, PD7_OUT, PD7_IN, PD7_IN_PU,
+		PD6_FN, PD6_OUT, PD6_IN, PD6_IN_PU,
+		PD5_FN, PD5_OUT, PD5_IN, PD5_IN_PU,
+		PD4_FN, PD4_OUT, PD4_IN, PD4_IN_PU,
+		PD3_FN, PD3_OUT, PD3_IN, PD3_IN_PU,
+		PD2_FN, PD2_OUT, PD2_IN, PD2_IN_PU,
+		PD1_FN, PD1_OUT, PD1_IN, PD1_IN_PU,
+		PD0_FN, PD0_OUT, PD0_IN, PD0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PECR", 0xffcc0008, 16, 2) {
+		PE7_FN, PE7_OUT, PE7_IN, PE7_IN_PU,
+		PE6_FN, PE6_OUT, PE6_IN, PE6_IN_PU,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG("PFCR", 0xffcc000a, 16, 2) {
+		PF7_FN, PF7_OUT, PF7_IN, PF7_IN_PU,
+		PF6_FN, PF6_OUT, PF6_IN, PF6_IN_PU,
+		PF5_FN, PF5_OUT, PF5_IN, PF5_IN_PU,
+		PF4_FN, PF4_OUT, PF4_IN, PF4_IN_PU,
+		PF3_FN, PF3_OUT, PF3_IN, PF3_IN_PU,
+		PF2_FN, PF2_OUT, PF2_IN, PF2_IN_PU,
+		PF1_FN, PF1_OUT, PF1_IN, PF1_IN_PU,
+		PF0_FN, PF0_OUT, PF0_IN, PF0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PGCR", 0xffcc000c, 16, 2) {
+		PG7_FN, PG7_OUT, PG7_IN, PG7_IN_PU,
+		PG6_FN, PG6_OUT, PG6_IN, PG6_IN_PU,
+		PG5_FN, PG5_OUT, PG5_IN, PG5_IN_PU,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG("PHCR", 0xffcc000e, 16, 2) {
+		PH7_FN, PH7_OUT, PH7_IN, PH7_IN_PU,
+		PH6_FN, PH6_OUT, PH6_IN, PH6_IN_PU,
+		PH5_FN, PH5_OUT, PH5_IN, PH5_IN_PU,
+		PH4_FN, PH4_OUT, PH4_IN, PH4_IN_PU,
+		PH3_FN, PH3_OUT, PH3_IN, PH3_IN_PU,
+		PH2_FN, PH2_OUT, PH2_IN, PH2_IN_PU,
+		PH1_FN, PH1_OUT, PH1_IN, PH1_IN_PU,
+		PH0_FN, PH0_OUT, PH0_IN, PH0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PJCR", 0xffcc0010, 16, 2) {
+		PJ7_FN, PJ7_OUT, PJ7_IN, PJ7_IN_PU,
+		PJ6_FN, PJ6_OUT, PJ6_IN, PJ6_IN_PU,
+		PJ5_FN, PJ5_OUT, PJ5_IN, PJ5_IN_PU,
+		PJ4_FN, PJ4_OUT, PJ4_IN, PJ4_IN_PU,
+		PJ3_FN, PJ3_OUT, PJ3_IN, PJ3_IN_PU,
+		PJ2_FN, PJ2_OUT, PJ2_IN, PJ2_IN_PU,
+		PJ1_FN, PJ1_OUT, PJ1_IN, PJ1_IN_PU,
+		0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG("P1MSELR", 0xffcc0080, 16, 1) {
+		0, 0,
+		P1MSEL14_0, P1MSEL14_1,
+		P1MSEL13_0, P1MSEL13_1,
+		P1MSEL12_0, P1MSEL12_1,
+		P1MSEL11_0, P1MSEL11_1,
+		P1MSEL10_0, P1MSEL10_1,
+		P1MSEL9_0,  P1MSEL9_1,
+		P1MSEL8_0,  P1MSEL8_1,
+		P1MSEL7_0,  P1MSEL7_1,
+		P1MSEL6_0,  P1MSEL6_1,
+		P1MSEL5_0,  P1MSEL5_1,
+		P1MSEL4_0,  P1MSEL4_1,
+		P1MSEL3_0,  P1MSEL3_1,
+		P1MSEL2_0,  P1MSEL2_1,
+		P1MSEL1_0,  P1MSEL1_1,
+		P1MSEL0_0,  P1MSEL0_1 }
+	},
+	{ PINMUX_CFG_REG("P2MSELR", 0xffcc0082, 16, 1) {
+		P2MSEL15_0, P2MSEL15_1,
+		P2MSEL14_0, P2MSEL14_1,
+		P2MSEL13_0, P2MSEL13_1,
+		P2MSEL12_0, P2MSEL12_1,
+		P2MSEL11_0, P2MSEL11_1,
+		P2MSEL10_0, P2MSEL10_1,
+		P2MSEL9_0,  P2MSEL9_1,
+		P2MSEL8_0,  P2MSEL8_1,
+		P2MSEL7_0,  P2MSEL7_1,
+		P2MSEL6_0,  P2MSEL6_1,
+		P2MSEL5_0,  P2MSEL5_1,
+		P2MSEL4_0,  P2MSEL4_1,
+		P2MSEL3_0,  P2MSEL3_1,
+		P2MSEL2_0,  P2MSEL2_1,
+		P2MSEL1_0,  P2MSEL1_1,
+		P2MSEL0_0,  P2MSEL0_1 }
+	},
+	{}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PADR", 0xffcc0020, 8) {
+		PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+		PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA }
+	},
+	{ PINMUX_DATA_REG("PBDR", 0xffcc0022, 8) {
+		PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+		PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA }
+	},
+	{ PINMUX_DATA_REG("PCDR", 0xffcc0024, 8) {
+		PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+		PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA }
+	},
+	{ PINMUX_DATA_REG("PDDR", 0xffcc0026, 8) {
+		PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+		PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA }
+	},
+	{ PINMUX_DATA_REG("PEDR", 0xffcc0028, 8) {
+		PE7_DATA, PE6_DATA,
+		0, 0, 0, 0, 0, 0 }
+	},
+	{ PINMUX_DATA_REG("PFDR", 0xffcc002a, 8) {
+		PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+		PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA }
+	},
+	{ PINMUX_DATA_REG("PGDR", 0xffcc002c, 8) {
+		PG7_DATA, PG6_DATA, PG5_DATA, 0,
+		0, 0, 0, 0 }
+	},
+	{ PINMUX_DATA_REG("PHDR", 0xffcc002e, 8) {
+		PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+		PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA }
+	},
+	{ PINMUX_DATA_REG("PJDR", 0xffcc0030, 8) {
+		PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+		PJ3_DATA, PJ2_DATA, PJ1_DATA, 0 }
+	},
+	{ },
+};
+
+static struct pinmux_info sh7786_pinmux_info = {
+	.name = "sh7786_pfc",
+	.reserved_id = PINMUX_RESERVED,
+	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.first_gpio = GPIO_PA7,
+	.last_gpio = GPIO_FN_FSE,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+	return register_pinmux(&sh7786_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7343.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/serial.h>
 #include <linux/serial_sci.h>
 #include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
 #include <asm/clock.h>
 
 static struct resource iic0_resources[] = {
@@ -140,6 +141,38 @@ static struct platform_device jpu_device
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_cmt_config cmt_platform_data = {
+	.name = "CMT",
+	.channel_offset = 0x60,
+	.timer_bit = 5,
+	.clk = "cmt0",
+	.clockevent_rating = 125,
+	.clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+	[0] = {
+		.name	= "CMT",
+		.start	= 0x044a0060,
+		.end	= 0x044a006b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 104,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt_device = {
+	.name		= "sh_cmt",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &cmt_platform_data,
+	},
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
+};
+
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xffe00000,
@@ -175,6 +208,7 @@ static struct platform_device sci_device
 };
 
 static struct platform_device *sh7343_devices[] __initdata = {
+	&cmt_device,
 	&iic0_device,
 	&iic1_device,
 	&sci_device,
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7366.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/serial.h>
 #include <linux/serial_sci.h>
 #include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
 #include <asm/clock.h>
 
 static struct resource iic_resources[] = {
@@ -147,6 +148,38 @@ static struct platform_device veu1_devic
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_cmt_config cmt_platform_data = {
+	.name = "CMT",
+	.channel_offset = 0x60,
+	.timer_bit = 5,
+	.clk = "cmt0",
+	.clockevent_rating = 125,
+	.clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+	[0] = {
+		.name	= "CMT",
+		.start	= 0x044a0060,
+		.end	= 0x044a006b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 104,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt_device = {
+	.name		= "sh_cmt",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &cmt_platform_data,
+	},
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
+};
+
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xffe00000,
@@ -167,6 +200,7 @@ static struct platform_device sci_device
 };
 
 static struct platform_device *sh7366_devices[] __initdata = {
+	&cmt_device,
 	&iic_device,
 	&sci_device,
 	&usb_host_device,
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7722.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/serial_sci.h>
 #include <linux/mm.h>
 #include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
 
@@ -176,6 +177,38 @@ static struct platform_device jpu_device
 	.num_resources	= ARRAY_SIZE(jpu_resources),
 };
 
+static struct sh_cmt_config cmt_platform_data = {
+	.name = "CMT",
+	.channel_offset = 0x60,
+	.timer_bit = 5,
+	.clk = "cmt0",
+	.clockevent_rating = 125,
+	.clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+	[0] = {
+		.name	= "CMT",
+		.start	= 0x044a0060,
+		.end	= 0x044a006b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 104,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt_device = {
+	.name		= "sh_cmt",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &cmt_platform_data,
+	},
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
+};
+
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase	= 0xffe00000,
@@ -209,6 +242,7 @@ static struct platform_device sci_device
 };
 
 static struct platform_device *sh7722_devices[] __initdata = {
+	&cmt_device,
 	&rtc_device,
 	&usbf_device,
 	&iic_device,
@@ -222,7 +256,6 @@ static int __init sh7722_devices_setup(v
 {
 	clk_always_enable("uram0"); /* URAM */
 	clk_always_enable("xymem0"); /* XYMEM */
-	clk_always_enable("rtc0"); /* RTC */
 	clk_always_enable("veu0"); /* VEU */
 	clk_always_enable("vpu0"); /* VPU */
 	clk_always_enable("jpu0"); /* JPU */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7723.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/serial_sci.h>
 #include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
 
@@ -100,6 +101,38 @@ static struct platform_device veu1_devic
 	.num_resources	= ARRAY_SIZE(veu1_resources),
 };
 
+static struct sh_cmt_config cmt_platform_data = {
+	.name = "CMT",
+	.channel_offset = 0x60,
+	.timer_bit = 5,
+	.clk = "cmt0",
+	.clockevent_rating = 125,
+	.clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+	[0] = {
+		.name	= "CMT",
+		.start	= 0x044a0060,
+		.end	= 0x044a006b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 104,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device cmt_device = {
+	.name		= "sh_cmt",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &cmt_platform_data,
+	},
+	.resource	= cmt_resources,
+	.num_resources	= ARRAY_SIZE(cmt_resources),
+};
+
 static struct plat_sci_port sci_platform_data[] = {
 	{
 		.mapbase        = 0xffe00000,
@@ -221,6 +254,7 @@ static struct platform_device iic_device
 };
 
 static struct platform_device *sh7723_devices[] __initdata = {
+	&cmt_device,
 	&sci_device,
 	&rtc_device,
 	&iic_device,
@@ -233,7 +267,6 @@ static struct platform_device *sh7723_de
 static int __init sh7723_devices_setup(void)
 {
 	clk_always_enable("meram0"); /* MERAM */
-	clk_always_enable("rtc0"); /* RTC */
 	clk_always_enable("veu1"); /* VEU2H1 */
 	clk_always_enable("veu0"); /* VEU2H0 */
 	clk_always_enable("vpu0"); /* VPU */
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7763.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2006  Paul Mundt
  *  Copyright (C) 2007  Yoshihiro Shimoda
- *  Copyright (C) 2008  Nobuhiro Iwamatsu
+ *  Copyright (C) 2008, 2009  Nobuhiro Iwamatsu
  *
  * 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
@@ -22,18 +22,8 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 22,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
-		.start	= 20,
+		/* Shared Period/Carry/Alarm IRQ */
+		.start  = 20,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -50,17 +40,17 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xffe00000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
+		.irqs		= { 40, 40, 40, 40 },
 	}, {
 		.mapbase	= 0xffe08000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 76, 77, 79, 78 },
+		.irqs		= { 76, 76, 76, 76 },
 	}, {
 		.mapbase	= 0xffe10000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 104, 105, 107, 106 },
+		.irqs		= { 104, 104, 104, 104 },
 	}, {
 		.flags = 0,
 	}
@@ -148,93 +138,65 @@ enum {
 	IRL_HHLL, IRL_HHLH, IRL_HHHL,
 
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
-	HUDI, LCDC,
-	DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	DMAC0_DMINT4, DMAC0_DMINT5,
-	IIC0, IIC1,
-	CMT,
-	GEINT0, GEINT1, GEINT2,
-	HAC,
-	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
-	PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
-	STIF0, STIF1,
-	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
-	SIOF0, SIOF1, SIOF2,
-	USBH, USBFI0, USBFI1,
-	TPU, PCC,
-	MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
-	SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
+	RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+	HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC,
+	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+	STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2,
+	USBH, USBF, TPU, PCC, MMCIF, SIM,
 	TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
-	SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
-	GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3,
+	SCIF2, GPIO,
 
 	/* interrupt groups */
 
-	TMU012, TMU345, RTC, DMAC, SCIF0, GETHER, PCIC5,
-	SCIF1, USBF, MMCIF, SIM, SCIF2, GPIO,
+	TMU012, TMU345,
 };
 
 static struct intc_vect vectors[] __initdata = {
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
 	INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
 	INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
 	INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
 	INTC_VECT(LCDC, 0x620),
-	INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
-	INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
-	INTC_VECT(DMAC0_DMAE, 0x6c0),
-	INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
-	INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
-	INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
+	INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+	INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+	INTC_VECT(DMAC, 0x6c0),
+	INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+	INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+	INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
 	INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
-	INTC_VECT(CMT, 0x900), INTC_VECT(GEINT0, 0x920),
-	INTC_VECT(GEINT1, 0x940), INTC_VECT(GEINT2, 0x960),
+	INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920),
+	INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960),
 	INTC_VECT(HAC, 0x980),
 	INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
 	INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
-	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
-	INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
-	INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
+	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+	INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+	INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
 	INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
-	INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
-	INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
+	INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
+	INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
 	INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
-	INTC_VECT(USBH, 0xc60), INTC_VECT(USBFI0, 0xc80),
-	INTC_VECT(USBFI1, 0xca0),
+	INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80),
+	INTC_VECT(USBF, 0xca0),
 	INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
-	INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
-	INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
-	INTC_VECT(SIM_ERI, 0xd80), INTC_VECT(SIM_RXI, 0xda0),
-	INTC_VECT(SIM_TXI, 0xdc0), INTC_VECT(SIM_TEND, 0xde0),
+	INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+	INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
+	INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
+	INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
 	INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
 	INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
 	INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
 	INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
-	INTC_VECT(SCIF2_ERI, 0xf00), INTC_VECT(SCIF2_RXI, 0xf20),
-	INTC_VECT(SCIF2_BRI, 0xf40), INTC_VECT(SCIF2_TXI, 0xf60),
-	INTC_VECT(GPIO_CH0, 0xf80), INTC_VECT(GPIO_CH1, 0xfa0),
-	INTC_VECT(GPIO_CH2, 0xfc0), INTC_VECT(GPIO_CH3, 0xfe0),
+	INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20),
+	INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60),
+	INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+	INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
 };
 
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
 	INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
-	INTC_GROUP(DMAC, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
-		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
-	INTC_GROUP(GETHER, GEINT0, GEINT1, GEINT2),
-	INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
-	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(USBF, USBFI0, USBFI1),
-	INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
-	INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
-	INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
-	INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7780.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,17 +20,7 @@ static struct resource rtc_resources[] =
 		.flags	= IORESOURCE_IO,
 	},
 	[1] = {
-		/* Period IRQ */
-		.start	= 21,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* Carry IRQ */
-		.start	= 22,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		/* Alarm IRQ */
+		/* Shared Period/Carry/Alarm IRQ */
 		.start	= 20,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -48,12 +38,12 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xffe00000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
+		.irqs		= { 40, 40, 40, 40 },
 	}, {
 		.mapbase	= 0xffe10000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 76, 77, 79, 78 },
+		.irqs		= { 76, 76, 76, 76 },
 	}, {
 		.flags = 0,
 	}
@@ -90,82 +80,55 @@ enum {
 	IRL_HHLL, IRL_HHLH, IRL_HHHL,
 
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
-	RTC_ATI, RTC_PRI, RTC_CUI,
-	WDT,
-	TMU0, TMU1, TMU2, TMU2_TICPI,
-	HUDI,
-	DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7,
-	CMT, HAC,
-	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
-	PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
-	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
-	SIOF, HSPI,
-	MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
-	DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11,
-	TMU3, TMU4, TMU5,
-	SSI,
-	FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
-	GPIOI0, GPIOI1, GPIOI2, GPIOI3,
+	RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+	HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,
+	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+	SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL,	GPIO,
 
 	/* interrupt groups */
 
-	RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1,
-	PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO,
+	TMU012,	TMU345,
 };
 
 static struct intc_vect vectors[] __initdata = {
-	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
-	INTC_VECT(RTC_CUI, 0x4c0),
+	INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+	INTC_VECT(RTC, 0x4c0),
 	INTC_VECT(WDT, 0x560),
 	INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
 	INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
 	INTC_VECT(HUDI, 0x600),
-	INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
-	INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
-	INTC_VECT(DMAC0_DMAE, 0x6c0),
-	INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
-	INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
-	INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
-	INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0),
+	INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
+	INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
+	INTC_VECT(DMAC0, 0x6c0),
+	INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+	INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+	INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
+	INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),
 	INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
 	INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
 	INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
-	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
-	INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
-	INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
-	INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
-	INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
+	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+	INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+	INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
+	INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
+	INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
 	INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
-	INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
-	INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
-	INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0),
-	INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0),
+	INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+	INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
+	INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),
+	INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),
 	INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
 	INTC_VECT(TMU5, 0xe40),
 	INTC_VECT(SSI, 0xe80),
-	INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
-	INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
-	INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
-	INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
+	INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
+	INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
+	INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+	INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
 };
 
 static struct intc_group groups[] __initdata = {
-	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
 	INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
-	INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
-		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
-	INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
-		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
-	INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
-	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
 	INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
-	INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
-		   FLCTL_FLTRQ0, FLCTL_FLTRQ1),
-	INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7785.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,18 +20,13 @@ static struct plat_sci_port sci_platform
 		.mapbase	= 0xffea0000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 40, 41, 43, 42 },
+		.irqs		= { 40, 40, 40, 40 },
 	}, {
 		.mapbase	= 0xffeb0000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
-		.irqs		= { 44, 45, 47, 46 },
-	},
-
-	/*
-	 * The rest of these all have multiplexed IRQs
-	 */
-	{
+		.irqs		= { 44, 44, 44, 44 },
+	}, {
 		.mapbase	= 0xffec0000,
 		.flags		= UPF_BOOT_AUTOCONF,
 		.type		= PORT_SCIF,
@@ -91,33 +86,19 @@ enum {
 	IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
 
 	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
-	WDT,
-	TMU0, TMU1, TMU2, TMU2_TICPI,
-	HUDI,
-	DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
-	DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
-	SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
-	SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
-	DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
-	DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
-	HSPI,
+	WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+	HUDI, DMAC0, SCIF0, SCIF1, DMAC1, HSPI,
 	SCIF2, SCIF3, SCIF4, SCIF5,
-	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
-	PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
-	SIOF,
-	MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
-	DU,
-	GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI,
+	PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+	SIOF, MMCIF, DU, GDTA,
 	TMU3, TMU4, TMU5,
 	SSI0, SSI1,
 	HAC0, HAC1,
-	FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
-	GPIOI0, GPIOI1, GPIOI2, GPIOI3,
+	FLCTL, GPIO,
 
 	/* interrupt groups */
 
-	TMU012, DMAC0, SCIF0, SCIF1, DMAC1,
-	PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO
+	TMU012,	TMU345
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -125,57 +106,45 @@ static struct intc_vect vectors[] __init
 	INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
 	INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
 	INTC_VECT(HUDI, 0x600),
-	INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640),
-	INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680),
-	INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0),
-	INTC_VECT(DMAC0_DMAE, 0x6e0),
-	INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
-	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(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0),
-	INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0),
-	INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920),
-	INTC_VECT(DMAC1_DMAE, 0x940),
+	INTC_VECT(DMAC0, 0x620), INTC_VECT(DMAC0, 0x640),
+	INTC_VECT(DMAC0, 0x660), INTC_VECT(DMAC0, 0x680),
+	INTC_VECT(DMAC0, 0x6a0), INTC_VECT(DMAC0, 0x6c0),
+	INTC_VECT(DMAC0, 0x6e0),
+	INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+	INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+	INTC_VECT(SCIF1, 0x780), INTC_VECT(SCIF1, 0x7a0),
+	INTC_VECT(SCIF1, 0x7c0), INTC_VECT(SCIF1, 0x7e0),
+	INTC_VECT(DMAC1, 0x880), INTC_VECT(DMAC1, 0x8a0),
+	INTC_VECT(DMAC1, 0x8c0), INTC_VECT(DMAC1, 0x8e0),
+	INTC_VECT(DMAC1, 0x900), INTC_VECT(DMAC1, 0x920),
+	INTC_VECT(DMAC1, 0x940),
 	INTC_VECT(HSPI, 0x960),
 	INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0),
 	INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0),
 	INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
 	INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
-	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
-	INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
-	INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
+	INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+	INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+	INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
 	INTC_VECT(SIOF, 0xc00),
-	INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
-	INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
+	INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+	INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
 	INTC_VECT(DU, 0xd80),
-	INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0),
-	INTC_VECT(GDTA_GAERI, 0xde0),
+	INTC_VECT(GDTA, 0xda0), INTC_VECT(GDTA, 0xdc0),
+	INTC_VECT(GDTA, 0xde0),
 	INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
 	INTC_VECT(TMU5, 0xe40),
 	INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
 	INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0),
-	INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
-	INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
-	INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
-	INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
+	INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
+	INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
+	INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+	INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
 };
 
 static struct intc_group groups[] __initdata = {
 	INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
-	INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
-		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
-	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
-	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
-	INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
-		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE),
-	INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
-	INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
-	INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI),
 	INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
-	INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
-		   FLCTL_FLTRQ0, FLCTL_FLTRQ1),
-	INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh4a/setup-sh7786.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,490 @@
+/*
+ * SH7786 Setup
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7785 Setup
+ *
+ *  Copyright (C) 2007  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/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.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 },
+	},
+	/*
+	 * 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 = {
+	.name		= "sh-sci",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= sci_platform_data,
+	},
+};
+
+static struct resource usb_ohci_resources[] = {
+	[0] = {
+		.start	= 0xffe70400,
+		.end	= 0xffe704ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 77,
+		.end	= 77,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 usb_ohci_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device usb_ohci_device = {
+	.name		= "sh_ohci",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &usb_ohci_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(usb_ohci_resources),
+	.resource	= usb_ohci_resources,
+};
+
+static struct platform_device *sh7786_devices[] __initdata = {
+	&sci_device,
+	&usb_ohci_device,
+};
+
+
+/*
+ * Please call this function if your platform board
+ * use external clock for USB
+ * */
+#define USBCTL0		0xffe70858
+#define CLOCK_MODE_MASK 0xffffff7f
+#define EXT_CLOCK_MODE  0x00000080
+void __init sh7786_usb_use_exclock(void)
+{
+	u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
+	__raw_writel(val | EXT_CLOCK_MODE, USBCTL0);
+}
+
+#define USBINITREG1	0xffe70094
+#define USBINITREG2	0xffe7009c
+#define USBINITVAL1	0x00ff0040
+#define USBINITVAL2	0x00000001
+
+#define USBPCTL1	0xffe70804
+#define USBST		0xffe70808
+#define PHY_ENB		0x00000001
+#define PLL_ENB		0x00000002
+#define PHY_RST		0x00000004
+#define ACT_PLL_STATUS	0xc0000000
+static void __init sh7786_usb_setup(void)
+{
+	int i = 1000000;
+
+	/*
+	 * USB initial settings
+	 *
+	 * The following settings are necessary
+	 * for using the USB modules.
+	 *
+	 * see "USB Inital Settings" for detail
+	 */
+	__raw_writel(USBINITVAL1, USBINITREG1);
+	__raw_writel(USBINITVAL2, USBINITREG2);
+
+	/*
+	 * Set the PHY and PLL enable bit
+	 */
+	__raw_writel(PHY_ENB | PLL_ENB, USBPCTL1);
+	while (i--) {
+		if (ACT_PLL_STATUS == (__raw_readl(USBST) & ACT_PLL_STATUS)) {
+			/* Set the PHY RST bit */
+			__raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1);
+			printk(KERN_INFO "sh7786 usb setup done\n");
+			break;
+		}
+		cpu_relax();
+	}
+}
+
+static int __init sh7786_devices_setup(void)
+{
+	sh7786_usb_setup();
+	return platform_add_devices(sh7786_devices,
+				    ARRAY_SIZE(sh7786_devices));
+}
+device_initcall(sh7786_devices_setup);
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+
+	IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
+
+	IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
+
+	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+	WDT,
+	TMU0_0, TMU0_1, TMU0_2, TMU0_3,
+	TMU1_0, TMU1_1, TMU1_2,
+	DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
+	HUDI1, HUDI0,
+	DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
+	HPB_0, HPB_1, HPB_2,
+	SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
+	SCIF1,
+	TMU2, TMU3,
+	SCIF2, SCIF3, SCIF4, SCIF5,
+	Eth_0, Eth_1,
+	PCIeC0_0, PCIeC0_1, PCIeC0_2,
+	PCIeC1_0, PCIeC1_1, PCIeC1_2,
+	USB,
+	I2C0, I2C1,
+	DU,
+	SSI0, SSI1, SSI2, SSI3,
+	PCIeC2_0, PCIeC2_1, PCIeC2_2,
+	HAC0, HAC1,
+	FLCTL,
+	HSPI,
+	GPIO0, GPIO1,
+	Thermal,
+	INTC0, INTC1, INTC2, INTC3, INTC4, INTC5, INTC6, INTC7,
+
+	/* interrupt groups */
+};
+
+static struct intc_vect vectors[] __initdata = {
+	INTC_VECT(WDT, 0x3e0),
+	INTC_VECT(TMU0_0, 0x400), INTC_VECT(TMU0_1, 0x420),
+	INTC_VECT(TMU0_2, 0x440), INTC_VECT(TMU0_3, 0x460),
+	INTC_VECT(TMU1_0, 0x480), INTC_VECT(TMU1_1, 0x4a0),
+	INTC_VECT(TMU1_2, 0x4c0),
+	INTC_VECT(DMAC0_0, 0x500), INTC_VECT(DMAC0_1, 0x520),
+	INTC_VECT(DMAC0_2, 0x540), INTC_VECT(DMAC0_3, 0x560),
+	INTC_VECT(DMAC0_4, 0x580), INTC_VECT(DMAC0_5, 0x5a0),
+	INTC_VECT(DMAC0_6, 0x5c0),
+	INTC_VECT(HUDI1, 0x5e0), INTC_VECT(HUDI0, 0x600),
+	INTC_VECT(DMAC1_0, 0x620), INTC_VECT(DMAC1_1, 0x640),
+	INTC_VECT(DMAC1_2, 0x660), INTC_VECT(DMAC1_3, 0x680),
+	INTC_VECT(HPB_0, 0x6a0), INTC_VECT(HPB_1, 0x6c0),
+	INTC_VECT(HPB_2, 0x6e0),
+	INTC_VECT(SCIF0_0, 0x700), INTC_VECT(SCIF0_1, 0x720),
+	INTC_VECT(SCIF0_2, 0x740), INTC_VECT(SCIF0_3, 0x760),
+	INTC_VECT(SCIF1, 0x780),
+	INTC_VECT(TMU2, 0x7a0), INTC_VECT(TMU3, 0x7c0),
+	INTC_VECT(SCIF2, 0x840), INTC_VECT(SCIF3, 0x860),
+	INTC_VECT(SCIF4, 0x880), INTC_VECT(SCIF5, 0x8a0),
+	INTC_VECT(Eth_0, 0x8c0), INTC_VECT(Eth_1, 0x8e0),
+	INTC_VECT(PCIeC0_0, 0xae0), INTC_VECT(PCIeC0_1, 0xb00),
+	INTC_VECT(PCIeC0_2, 0xb20),
+	INTC_VECT(PCIeC1_0, 0xb40), INTC_VECT(PCIeC1_1, 0xb60),
+	INTC_VECT(PCIeC1_2, 0xb80),
+	INTC_VECT(USB, 0xba0),
+	INTC_VECT(I2C0, 0xcc0), INTC_VECT(I2C1, 0xce0),
+	INTC_VECT(DU, 0xd00),
+	INTC_VECT(SSI0, 0xd20), INTC_VECT(SSI1, 0xd40),
+	INTC_VECT(SSI2, 0xd60), INTC_VECT(SSI3, 0xd80),
+	INTC_VECT(PCIeC2_0, 0xda0), INTC_VECT(PCIeC2_1, 0xdc0),
+	INTC_VECT(PCIeC2_2, 0xde0),
+	INTC_VECT(HAC0, 0xe00), INTC_VECT(HAC1, 0xe20),
+	INTC_VECT(FLCTL, 0xe40),
+	INTC_VECT(HSPI, 0xe80),
+	INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0),
+	INTC_VECT(Thermal, 0xee0),
+};
+
+/* FIXME: Main CPU support only now */
+#if 1 /* Main CPU */
+#define CnINTMSK0	0xfe410030
+#define CnINTMSK1	0xfe410040
+#define CnINTMSKCLR0	0xfe410050
+#define CnINTMSKCLR1	0xfe410060
+#define CnINT2MSKR0	0xfe410a20
+#define CnINT2MSKR1	0xfe410a24
+#define CnINT2MSKR2	0xfe410a28
+#define CnINT2MSKR3	0xfe410a2c
+#define CnINT2MSKCR0	0xfe410a30
+#define CnINT2MSKCR1	0xfe410a34
+#define CnINT2MSKCR2	0xfe410a38
+#define CnINT2MSKCR3	0xfe410a3c
+#else /* Sub CPU */
+#define CnINTMSK0	0xfe410034
+#define CnINTMSK1	0xfe410044
+#define CnINTMSKCLR0	0xfe410054
+#define CnINTMSKCLR1	0xfe410064
+#define CnINT2MSKR0	0xfe410b20
+#define CnINT2MSKR1	0xfe410b24
+#define CnINT2MSKR2	0xfe410b28
+#define CnINT2MSKR3	0xfe410b2c
+#define CnINT2MSKCR0	0xfe410b30
+#define CnINT2MSKCR1	0xfe410b34
+#define CnINT2MSKCR2	0xfe410b38
+#define CnINT2MSKCR3	0xfe410b3c
+#endif
+
+#define INTMSK2		0xfe410068
+#define INTMSKCLR2	0xfe41006c
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+	{ CnINTMSK0, CnINTMSKCLR0, 32,
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+	{ INTMSK2, INTMSKCLR2, 32,
+	  { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	    IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	    IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	    IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
+	    IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	    IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	    IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	    IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
+	{ CnINT2MSKR0, CnINT2MSKCR0 , 32,
+	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT } },
+	{ CnINT2MSKR1, CnINT2MSKCR1, 32,
+	  { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0,
+	    DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
+	    HUDI1, HUDI0,
+	    DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
+	    HPB_0, HPB_1, HPB_2,
+	    SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
+	    SCIF1,
+	    TMU2, TMU3, 0, } },
+	{ CnINT2MSKR2, CnINT2MSKCR2, 32,
+	  { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5,
+	    Eth_0, Eth_1,
+	    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	    PCIeC0_0, PCIeC0_1, PCIeC0_2,
+	    PCIeC1_0, PCIeC1_1, PCIeC1_2,
+	    USB, 0, 0 } },
+	{ CnINT2MSKR3, CnINT2MSKCR3, 32,
+	  { 0, 0, 0, 0, 0, 0,
+	    I2C0, I2C1,
+	    DU, SSI0, SSI1, SSI2, SSI3,
+	    PCIeC2_0, PCIeC2_1, PCIeC2_2,
+	    HAC0, HAC1,
+	    FLCTL, 0,
+	    HSPI, GPIO0, GPIO1, Thermal,
+	    0, 0, 0, 0, 0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+	{ 0xfe410010, 0, 32, 4, /* INTPRI */   { IRQ0, IRQ1, IRQ2, IRQ3,
+						 IRQ4, IRQ5, IRQ6, IRQ7 } },
+	{ 0xfe410800, 0, 32, 8, /* INT2PRI0 */ { 0, 0, 0, WDT } },
+	{ 0xfe410804, 0, 32, 8, /* INT2PRI1 */ { TMU0_0, TMU0_1,
+						 TMU0_2, TMU0_3 } },
+	{ 0xfe410808, 0, 32, 8, /* INT2PRI2 */ { TMU1_0, TMU1_1,
+						 TMU1_2, 0 } },
+	{ 0xfe41080c, 0, 32, 8, /* INT2PRI3 */ { DMAC0_0, DMAC0_1,
+						 DMAC0_2, DMAC0_3 } },
+	{ 0xfe410810, 0, 32, 8, /* INT2PRI4 */ { DMAC0_4, DMAC0_5,
+						 DMAC0_6, HUDI1 } },
+	{ 0xfe410814, 0, 32, 8, /* INT2PRI5 */ { HUDI0, DMAC1_0,
+						 DMAC1_1, DMAC1_2 } },
+	{ 0xfe410818, 0, 32, 8, /* INT2PRI6 */ { DMAC1_3, HPB_0,
+						 HPB_1, HPB_2 } },
+	{ 0xfe41081c, 0, 32, 8, /* INT2PRI7 */ { SCIF0_0, SCIF0_1,
+						 SCIF0_2, SCIF0_3 } },
+	{ 0xfe410820, 0, 32, 8, /* INT2PRI8 */ { SCIF1, TMU2, TMU3, 0 } },
+	{ 0xfe410824, 0, 32, 8, /* INT2PRI9 */ { 0, 0, SCIF2, SCIF3 } },
+	{ 0xfe410828, 0, 32, 8, /* INT2PRI10 */ { SCIF4, SCIF5,
+						  Eth_0, Eth_1 } },
+	{ 0xfe41082c, 0, 32, 8, /* INT2PRI11 */ { 0, 0, 0, 0 } },
+	{ 0xfe410830, 0, 32, 8, /* INT2PRI12 */ { 0, 0, 0, 0 } },
+	{ 0xfe410834, 0, 32, 8, /* INT2PRI13 */ { 0, 0, 0, 0 } },
+	{ 0xfe410838, 0, 32, 8, /* INT2PRI14 */ { 0, 0, 0, PCIeC0_0 } },
+	{ 0xfe41083c, 0, 32, 8, /* INT2PRI15 */ { PCIeC0_1, PCIeC0_2,
+						  PCIeC1_0, PCIeC1_1 } },
+	{ 0xfe410840, 0, 32, 8, /* INT2PRI16 */ { PCIeC1_2, USB, 0, 0 } },
+	{ 0xfe410844, 0, 32, 8, /* INT2PRI17 */ { 0, 0, 0, 0 } },
+	{ 0xfe410848, 0, 32, 8, /* INT2PRI18 */ { 0, 0, I2C0, I2C1 } },
+	{ 0xfe41084c, 0, 32, 8, /* INT2PRI19 */ { DU, SSI0, SSI1, SSI2 } },
+	{ 0xfe410850, 0, 32, 8, /* INT2PRI20 */ { SSI3, PCIeC2_0,
+						  PCIeC2_1, PCIeC2_2 } },
+	{ 0xfe410854, 0, 32, 8, /* INT2PRI21 */ { HAC0, HAC1, FLCTL, 0 } },
+	{ 0xfe410858, 0, 32, 8, /* INT2PRI22 */ { HSPI, GPIO0,
+						  GPIO1, Thermal } },
+	{ 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } },
+	{ 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,
+			 mask_registers, prio_registers, NULL);
+
+/* Support for external interrupt pins in IRQ mode */
+
+static struct intc_vect vectors_irq0123[] __initdata = {
+	INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
+	INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
+};
+
+static struct intc_vect vectors_irq4567[] __initdata = {
+	INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340),
+	INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+	{ 0xfe41001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
+					    IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+	{ 0xfe410024, 0, 32, /* INTREQ */
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7786-irq0123",
+			     vectors_irq0123, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7786-irq4567",
+			     vectors_irq4567, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+/* External interrupt pins in IRL mode */
+
+static struct intc_vect vectors_irl0123[] __initdata = {
+	INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
+	INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
+	INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
+	INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
+	INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
+	INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
+	INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
+	INTC_VECT(IRL0_HHHL, 0x3c0),
+};
+
+static struct intc_vect vectors_irl4567[] __initdata = {
+	INTC_VECT(IRL4_LLLL, 0x900), INTC_VECT(IRL4_LLLH, 0x920),
+	INTC_VECT(IRL4_LLHL, 0x940), INTC_VECT(IRL4_LLHH, 0x960),
+	INTC_VECT(IRL4_LHLL, 0x980), INTC_VECT(IRL4_LHLH, 0x9a0),
+	INTC_VECT(IRL4_LHHL, 0x9c0), INTC_VECT(IRL4_LHHH, 0x9e0),
+	INTC_VECT(IRL4_HLLL, 0xa00), INTC_VECT(IRL4_HLLH, 0xa20),
+	INTC_VECT(IRL4_HLHL, 0xa40), INTC_VECT(IRL4_HLHH, 0xa60),
+	INTC_VECT(IRL4_HHLL, 0xa80), INTC_VECT(IRL4_HHLH, 0xaa0),
+	INTC_VECT(IRL4_HHHL, 0xac0),
+};
+
+static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7786-irl0123", vectors_irl0123,
+			 NULL, mask_registers, NULL, NULL);
+
+static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
+			 NULL, mask_registers, NULL, NULL);
+
+#define INTC_ICR0	0xfe410000
+#define INTC_INTMSK0	CnINTMSK0
+#define INTC_INTMSK1	CnINTMSK1
+#define INTC_INTMSK2	INTMSK2
+#define INTC_INTMSKCLR1	CnINTMSKCLR1
+#define INTC_INTMSKCLR2	INTMSKCLR2
+
+void __init plat_irq_setup(void)
+{
+	/* disable IRQ3-0 + IRQ7-4 */
+	ctrl_outl(0xff000000, INTC_INTMSK0);
+
+	/* disable IRL3-0 + IRL7-4 */
+	ctrl_outl(0xc0000000, INTC_INTMSK1);
+	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+
+	/* select IRL mode for IRL3-0 + IRL7-4 */
+	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+
+	register_intc_controller(&intc_desc);
+}
+
+void __init plat_irq_setup_pins(int mode)
+{
+	switch (mode) {
+	case IRQ_MODE_IRQ7654:
+		/* select IRQ mode for IRL7-4 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq4567);
+		break;
+	case IRQ_MODE_IRQ3210:
+		/* select IRQ mode for IRL3-0 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq0123);
+		break;
+	case IRQ_MODE_IRL7654:
+		/* enable IRL7-4 but don't provide any masking */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL3210:
+		/* enable IRL0-3 but don't provide any masking */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL7654_MASK:
+		/* enable IRL7-4 and mask using cpu intc controller */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl4567);
+		break;
+	case IRQ_MODE_IRL3210_MASK:
+		/* enable IRL0-3 and mask using cpu intc controller */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl0123);
+		break;
+	default:
+		BUG();
+	}
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh5/entry.S linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh5/entry.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/sh5/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
  * for more details.
  */
 #include <linux/errno.h>
+#include <linux/init.h>
 #include <linux/sys.h>
 #include <cpu/registers.h>
 #include <asm/processor.h>
@@ -2058,10 +2059,10 @@ asm_uaccess_end:
 
 
 /*
- * --- .text.init Section
+ * --- .init.text Section
  */
 
-	.section	.text.init, "ax"
+	__INIT
 
 /*
  * void trap_init (void)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/Makefile linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux/SuperH SH-Mobile backends.
+#
+
+# Power Management & Sleep mode
+obj-$(CONFIG_PM)	+= pm.o sleep.o
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/pm.c linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/pm.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
+ *
+ * Power management support code for SuperH Mobile
+ *
+ *  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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <asm/suspend.h>
+#include <asm/uaccess.h>
+
+/*
+ * Sleep modes available on SuperH Mobile:
+ *
+ * Sleep mode is just plain "sleep" instruction
+ * Sleep Self-Refresh mode is above plus RAM put in Self-Refresh
+ * Standby Self-Refresh mode is above plus stopped clocks
+ */
+#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)
+
+/*
+ * 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
+ *
+ * All modes should be tied in with cpuidle. But before that can
+ * happen we need to keep track of enabled hardware blocks so we
+ * can avoid entering sleep modes that stop clocks to hardware
+ * blocks that are in use even though the cpu core is idle.
+ */
+
+extern const unsigned char sh_mobile_standby[];
+extern const unsigned int sh_mobile_standby_size;
+
+static void sh_mobile_call_standby(unsigned long mode)
+{
+	extern void *vbr_base;
+	void *onchip_mem = (void *)0xe5200000; /* ILRAM */
+	void (*standby_onchip_mem)(unsigned long) = onchip_mem;
+
+	/* Note: Wake up from sleep may generate exceptions!
+	 * Setup VBR to point to on-chip ram if self-refresh is
+	 * going to be used.
+	 */
+	if (mode & SUSP_SH_SF)
+		asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
+
+	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
+	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
+	wmb();
+	ctrl_barrier();
+
+	/* Let assembly snippet in on-chip memory handle the rest */
+	standby_onchip_mem(mode);
+
+	/* Put VBR back in System RAM again */
+	if (mode & SUSP_SH_SF)
+		asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+}
+
+static int sh_pm_enter(suspend_state_t state)
+{
+	local_irq_disable();
+	set_bl_bit();
+	sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);
+	local_irq_disable();
+	clear_bl_bit();
+	return 0;
+}
+
+static struct platform_suspend_ops sh_pm_ops = {
+	.enter          = sh_pm_enter,
+	.valid          = suspend_valid_only_mem,
+};
+
+static int __init sh_pm_init(void)
+{
+	suspend_set_ops(&sh_pm_ops);
+	return 0;
+}
+
+late_initcall(sh_pm_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/cpu/shmobile/sleep.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
+ *
+ * Sleep mode and Standby modes support for SuperH Mobile
+ *
+ *  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>
+
+/* manage self-refresh and enter standby mode.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+
+	.balign 	4096,0,4096
+ENTRY(sh_mobile_standby)
+	mov	r4, r0
+
+	tst	#SUSP_SH_SF, r0
+	bt	skip_set_sf
+
+	/* SDRAM: 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
+
+skip_set_sf:
+	tst	#SUSP_SH_SLEEP, r0
+	bt	test_standby
+
+	/* set mode to "sleep mode" */
+	bra	do_sleep
+	 mov	#0x00, r1
+
+test_standby:
+	tst	#SUSP_SH_STANDBY, r0
+	bt	test_rstandby
+
+	/* set mode to "software standby mode" */
+	bra	do_sleep
+	 mov	#0x80, r1
+
+test_rstandby:
+	tst	#SUSP_SH_RSTANDBY, r0
+	bt	test_ustandby
+
+	/* set mode to "r-standby mode" */
+	bra	do_sleep
+	 mov	#0x20, r1
+
+test_ustandby:
+	tst	#SUSP_SH_USTANDBY, r0
+	bt	done_sleep
+
+	/* set mode to "u-standby mode" */
+	mov	#0x10, r1
+
+	/* fall-through */
+
+do_sleep:
+	/* setup and enter selected standby mode */
+	mov.l	5f, r4
+	mov.l	r1, @r4
+	sleep
+
+done_sleep:
+	/* reset standby mode to sleep mode */
+	mov.l	5f, r4
+	mov	#0x00, r1
+	mov.l	r1, @r4
+
+	tst	#SUSP_SH_SF, r0
+	bt	skip_restore_sf
+
+	/* SDRAM: set auto-refresh mode */
+	mov.l	1f, r4
+	mov.l	@r4, r2
+	mov.l   4f, r3
+	and	r3, r2
+	mov.l	r2, @r4
+	mov.l	6f, r4
+	mov.l	7f, r1
+	mov.l	8f, r2
+	mov.l	@r4, r3
+	mov	#-1, r4
+	add	r4, r3
+	or	r2, r3
+	mov.l	r3, @r1
+skip_restore_sf:
+	rts
+	 nop
+
+	.balign 4
+1:	.long	0xfe400008 /* SDCR0 */
+2:	.long	0x00000400
+3:	.long	0xffff7fff
+4:	.long	0xfffffbff
+5:	.long	0xa4150020 /* STBCR */
+6:	.long   0xfe40001c /* RTCOR */
+7:	.long   0xfe400018 /* RTCNT */
+8:	.long   0xa55a0000
+
+/* interrupt vector @ 0x600 */
+	.balign 	0x400,0,0x400
+	.long	0xdeadbeef
+	.balign 	0x200,0,0x200
+	/* sh7722 will end up here in sleep mode */
+	rte
+	 nop
+sh_mobile_standby_end:
+
+ENTRY(sh_mobile_standby_size)
+	.long sh_mobile_standby_end - sh_mobile_standby
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/gpio.c linux-libre-2.6.30-gnu1/arch/sh/kernel/gpio.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,36 +19,75 @@
 #include <linux/bitops.h>
 #include <linux/gpio.h>
 
-static struct pinmux_info *registered_gpio;
+static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+{
+	if (enum_id < r->begin)
+		return 0;
 
-static struct pinmux_info *gpio_controller(unsigned gpio)
+	if (enum_id > r->end)
+		return 0;
+
+	return 1;
+}
+
+static unsigned long gpio_read_raw_reg(unsigned long reg,
+				       unsigned long reg_width)
 {
-	if (!registered_gpio)
-		return NULL;
+	switch (reg_width) {
+	case 8:
+		return ctrl_inb(reg);
+	case 16:
+		return ctrl_inw(reg);
+	case 32:
+		return ctrl_inl(reg);
+	}
 
-	if (gpio < registered_gpio->first_gpio)
-		return NULL;
+	BUG();
+	return 0;
+}
 
-	if (gpio > registered_gpio->last_gpio)
-		return NULL;
+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;
+	}
 
-	return registered_gpio;
+	BUG();
 }
 
-static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+static void gpio_write_bit(struct pinmux_data_reg *dr,
+			   unsigned long in_pos, unsigned long value)
 {
-	if (enum_id < r->begin)
-		return 0;
+	unsigned long pos;
 
-	if (enum_id > r->end)
-		return 0;
+	pos = dr->reg_width - (in_pos + 1);
 
-	return 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 read_write_reg(unsigned long reg, unsigned long reg_width,
-			  unsigned long field_width, unsigned long in_pos,
-			  unsigned long value, int do_write)
+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;
 
@@ -57,52 +96,53 @@ static int read_write_reg(unsigned long
 	pos = reg_width - ((in_pos + 1) * field_width);
 
 #ifdef DEBUG
-	pr_info("%s, addr = %lx, value = %ld, pos = %ld, "
+	pr_info("read_reg: addr = %lx, pos = %ld, "
 		"r_width = %ld, f_width = %ld\n",
-		do_write ? "write" : "read", reg, value, pos,
-		reg_width, field_width);
+		reg, pos, reg_width, field_width);
 #endif
 
-	switch (reg_width) {
-	case 8:
-		data = ctrl_inb(reg);
-		break;
-	case 16:
-		data = ctrl_inw(reg);
-		break;
-	case 32:
-		data = ctrl_inl(reg);
-		break;
-	}
+	data = gpio_read_raw_reg(reg, reg_width);
+	return (data >> pos) & mask;
+}
 
-	if (!do_write)
-		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;
 
-	data &= ~(mask << pos);
-	data |= value << 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(data, reg);
+		ctrl_outb((ctrl_inb(reg) & mask) | value, reg);
 		break;
 	case 16:
-		ctrl_outw(data, reg);
+		ctrl_outw((ctrl_inw(reg) & mask) | value, reg);
 		break;
 	case 32:
-		ctrl_outl(data, reg);
+		ctrl_outl((ctrl_inl(reg) & mask) | value, reg);
 		break;
 	}
-	return 0;
 }
 
-static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
-			struct pinmux_data_reg **drp, int *bitp)
+static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
 {
-	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
+	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
 	struct pinmux_data_reg *data_reg;
 	int k, n;
 
-	if (!enum_in_range(enum_id, &gpioc->data))
+	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
 		return -1;
 
 	k = 0;
@@ -113,19 +153,58 @@ static int get_data_reg(struct pinmux_in
 			break;
 
 		for (n = 0; n < data_reg->reg_width; n++) {
-			if (data_reg->enum_ids[n] == enum_id) {
-				*drp = data_reg;
-				*bitp = 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)
@@ -187,9 +266,9 @@ static int get_gpio_enum_id(struct pinmu
 	return -1;
 }
 
-static int write_config_reg(struct pinmux_info *gpioc,
-			    struct pinmux_cfg_reg *crp,
-			    int index)
+static void write_config_reg(struct pinmux_info *gpioc,
+			     struct pinmux_cfg_reg *crp,
+			     int index)
 {
 	unsigned long ncomb, pos, value;
 
@@ -197,8 +276,7 @@ static int write_config_reg(struct pinmu
 	pos = index / ncomb;
 	value = index % ncomb;
 
-	return read_write_reg(crp->reg, crp->reg_width,
-			      crp->field_width, pos, value, 1);
+	gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
 }
 
 static int check_config_reg(struct pinmux_info *gpioc,
@@ -211,8 +289,8 @@ static int check_config_reg(struct pinmu
 	pos = index / ncomb;
 	value = index % ncomb;
 
-	if (read_write_reg(crp->reg, crp->reg_width,
-			   crp->field_width, pos, 0, 0) == value)
+	if (gpio_read_reg(crp->reg, crp->reg_width,
+			  crp->field_width, pos) == value)
 		return 0;
 
 	return -1;
@@ -220,8 +298,8 @@ static int check_config_reg(struct pinmu
 
 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
 
-int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
-		       int pinmux_type, int cfg_mode)
+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;
@@ -287,8 +365,7 @@ int pinmux_config_gpio(struct pinmux_inf
 			break;
 
 		case GPIO_CFG_REQ:
-			if (write_config_reg(gpioc, cr, index) != 0)
-				goto out_err;
+			write_config_reg(gpioc, cr, index);
 			*cntp = *cntp + 1;
 			break;
 
@@ -305,9 +382,14 @@ int pinmux_config_gpio(struct pinmux_inf
 
 static DEFINE_SPINLOCK(gpio_lock);
 
-int __gpio_request(unsigned gpio)
+static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
+	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;
@@ -319,29 +401,30 @@ int __gpio_request(unsigned gpio)
 
 	spin_lock_irqsave(&gpio_lock, flags);
 
-	if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
+	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, gpio, &dummy, &i) != 0)
+	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, gpio,
+		if (pinmux_config_gpio(gpioc, offset,
 				       pinmux_type,
 				       GPIO_CFG_DRYRUN) != 0)
 			goto err_unlock;
 
-		if (pinmux_config_gpio(gpioc, gpio,
+		if (pinmux_config_gpio(gpioc, offset,
 				       pinmux_type,
 				       GPIO_CFG_REQ) != 0)
 			BUG();
 	}
 
-	gpioc->gpios[gpio].flags = pinmux_type;
+	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+	gpioc->gpios[offset].flags |= pinmux_type;
 
 	ret = 0;
  err_unlock:
@@ -349,11 +432,10 @@ int __gpio_request(unsigned gpio)
  err_out:
 	return ret;
 }
-EXPORT_SYMBOL(__gpio_request);
 
-void gpio_free(unsigned gpio)
+static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
 	unsigned long flags;
 	int pinmux_type;
 
@@ -362,20 +444,23 @@ void gpio_free(unsigned gpio)
 
 	spin_lock_irqsave(&gpio_lock, flags);
 
-	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
-	pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
-	gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE;
+	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);
 }
-EXPORT_SYMBOL(gpio_free);
 
 static int pinmux_direction(struct pinmux_info *gpioc,
 			    unsigned gpio, int new_pinmux_type)
 {
-	int ret, pinmux_type;
+	int pinmux_type;
+	int ret = -EINVAL;
+
+	if (!gpioc)
+		goto err_out;
 
-	ret = -EINVAL;
 	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
 
 	switch (pinmux_type) {
@@ -401,102 +486,99 @@ static int pinmux_direction(struct pinmu
 			       GPIO_CFG_REQ) != 0)
 		BUG();
 
-	gpioc->gpios[gpio].flags = new_pinmux_type;
+	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
+	gpioc->gpios[gpio].flags |= new_pinmux_type;
 
 	ret = 0;
  err_out:
 	return ret;
 }
 
-int gpio_direction_input(unsigned gpio)
+static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
 	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
+	int ret;
 
 	spin_lock_irqsave(&gpio_lock, flags);
-	ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
+	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
 	spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
+
 	return ret;
 }
-EXPORT_SYMBOL(gpio_direction_input);
 
-static int __gpio_get_set_value(struct pinmux_info *gpioc,
-				unsigned gpio, int value,
-				int do_write)
+static void sh_gpio_set_value(struct pinmux_info *gpioc,
+			     unsigned gpio, int value)
 {
 	struct pinmux_data_reg *dr = NULL;
 	int bit = 0;
 
-	if (get_data_reg(gpioc, gpio, &dr, &bit) != 0)
+	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
 		BUG();
 	else
-		value = read_write_reg(dr->reg, dr->reg_width,
-				       1, bit, !!value, do_write);
-
-	return value;
+		gpio_write_bit(dr, bit, value);
 }
 
-int gpio_direction_output(unsigned gpio, int value)
+static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				    int value)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
+	struct pinmux_info *gpioc = chip_to_pinmux(chip);
 	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (!gpioc)
-		goto err_out;
+	int ret;
 
+	sh_gpio_set_value(gpioc, offset, value);
 	spin_lock_irqsave(&gpio_lock, flags);
-	__gpio_get_set_value(gpioc, gpio, value, 1);
-	ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
+	ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
 	spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
+
 	return ret;
 }
-EXPORT_SYMBOL(gpio_direction_output);
 
-int gpio_get_value(unsigned gpio)
+static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
-	unsigned long flags;
-	int value = 0;
+	struct pinmux_data_reg *dr = NULL;
+	int bit = 0;
 
-	if (!gpioc)
+	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
 		BUG();
-	else {
-		spin_lock_irqsave(&gpio_lock, flags);
-		value = __gpio_get_set_value(gpioc, gpio, 0, 0);
-		spin_unlock_irqrestore(&gpio_lock, flags);
+		return 0;
 	}
 
-	return value;
+	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
 }
-EXPORT_SYMBOL(gpio_get_value);
 
-void gpio_set_value(unsigned gpio, int value)
+static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct pinmux_info *gpioc = gpio_controller(gpio);
-	unsigned long flags;
+	return sh_gpio_get_value(chip_to_pinmux(chip), offset);
+}
 
-	if (!gpioc)
-		BUG();
-	else {
-		spin_lock_irqsave(&gpio_lock, flags);
-		__gpio_get_set_value(gpioc, gpio, value, 1);
-		spin_unlock_irqrestore(&gpio_lock, flags);
-	}
+static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
 }
-EXPORT_SYMBOL(gpio_set_value);
 
 int register_pinmux(struct pinmux_info *pip)
 {
-	registered_gpio = pip;
-	pr_info("pinmux: %s handling gpio %d -> %d\n",
+	struct gpio_chip *chip = &pip->chip;
+
+	pr_info("sh pinmux: %s handling gpio %d -> %d\n",
 		pip->name, pip->first_gpio, pip->last_gpio);
 
-	return 0;
+	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.29-gnu1/arch/sh/kernel/head_32.S linux-libre-2.6.30-gnu1/arch/sh/kernel/head_32.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/head_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/head_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,7 @@
  *
  * Head.S contains the SH exception handlers and startup code.
  */
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 
@@ -40,7 +41,7 @@ ENTRY(empty_zero_page)
 1:
 	.skip	PAGE_SIZE - empty_zero_page - 1b
 
-	.section	.text.head, "ax"
+	__HEAD
 
 /*
  * Condition at the entry of _stext:
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/head_64.S linux-libre-2.6.30-gnu1/arch/sh/kernel/head_64.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/head_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/head_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+
+#include <linux/init.h>
+
 #include <asm/page.h>
 #include <asm/cache.h>
 #include <asm/tlb.h>
@@ -110,7 +113,7 @@ empty_bad_pte_table:
 fpu_in_use:	.quad	0
 
 
-	.section	.text.head, "ax"
+	__HEAD
 	.balign L1_CACHE_BYTES
 /*
  * Condition at the entry of __stext:
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/idle.c linux-libre-2.6.30-gnu1/arch/sh/kernel/idle.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/idle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/idle.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@ static int __init hlt_setup(char *__unus
 }
 __setup("hlt", hlt_setup);
 
-static void default_idle(void)
+void default_idle(void)
 {
 	if (!hlt_counter) {
 		clear_thread_flag(TIF_POLLING_NRFLAG);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/io_trapped.c linux-libre-2.6.30-gnu1/arch/sh/kernel/io_trapped.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/io_trapped.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/io_trapped.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/bitops.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/mmu_context.h>
 #include <asm/uaccess.h>
@@ -32,6 +33,15 @@ EXPORT_SYMBOL_GPL(trapped_mem);
 #endif
 static DEFINE_SPINLOCK(trapped_lock);
 
+static int trapped_io_disable __read_mostly;
+
+static int __init trapped_io_setup(char *__unused)
+{
+	trapped_io_disable = 1;
+	return 1;
+}
+__setup("noiotrap", trapped_io_setup);
+
 int register_trapped_io(struct trapped_io *tiop)
 {
 	struct resource *res;
@@ -39,6 +49,9 @@ int register_trapped_io(struct trapped_i
 	struct page *pages[TRAPPED_PAGES_MAX];
 	int k, n;
 
+	if (unlikely(trapped_io_disable))
+		return 0;
+
 	/* structure must be page aligned */
 	if ((unsigned long)tiop & (PAGE_SIZE - 1))
 		goto bad;
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/irq.c linux-libre-2.6.30-gnu1/arch/sh/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p,
 			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 		seq_printf(p, " %14s", irq_desc[i].chip->name);
 		seq_printf(p, "-%-8s", irq_desc[i].name);
 		seq_printf(p, "  %s", action->name);
@@ -106,7 +106,7 @@ asmlinkage int do_IRQ(unsigned int irq,
 	}
 #endif
 
-	irq = irq_demux(evt2irq(irq));
+	irq = irq_demux(intc_evt2irq(irq));
 
 #ifdef CONFIG_IRQSTACKS
 	curctx = (union irq_ctx *)current_thread_info();
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/machine_kexec.c linux-libre-2.6.30-gnu1/arch/sh/kernel/machine_kexec.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/machine_kexec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/machine_kexec.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,21 +14,22 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/numa.h>
+#include <linux/ftrace.h>
+#include <linux/suspend.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
-typedef NORET_TYPE void (*relocate_new_kernel_t)(
-				unsigned long indirection_page,
-				unsigned long reboot_code_buffer,
-				unsigned long start_address,
-				unsigned long vbr_reg) ATTRIB_NORET;
+typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
+				      unsigned long reboot_code_buffer,
+				      unsigned long start_address);
 
 extern const unsigned char relocate_new_kernel[];
 extern const unsigned int relocate_new_kernel_size;
 extern void *gdb_vbr_vector;
+extern void *vbr_base;
 
 void machine_shutdown(void)
 {
@@ -45,6 +46,12 @@ 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;
 }
 
@@ -73,17 +80,33 @@ static void kexec_info(struct kimage *im
  */
 void machine_kexec(struct kimage *image)
 {
-
 	unsigned long page_list;
 	unsigned long reboot_code_buffer;
-	unsigned long vbr_reg;
 	relocate_new_kernel_t rnk;
+	unsigned long entry;
+	unsigned long *ptr;
+	int save_ftrace_enabled;
 
-#if defined(CONFIG_SH_STANDARD_BIOS)
-	vbr_reg = ((unsigned long )gdb_vbr_vector) - 0x100;
-#else
-	vbr_reg = 0x80000000;  // dummy
+	/*
+	 * Nicked from the mips version of machine_kexec():
+	 * The generic kexec code builds a page list with physical
+	 * addresses. Use phys_to_virt() to convert them to virtual.
+	 */
+	for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
+	     ptr = (entry & IND_INDIRECTION) ?
+	       phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
+		if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
+		    *ptr & IND_DESTINATION)
+			*ptr = (unsigned long) phys_to_virt(*ptr);
+	}
+
+#ifdef CONFIG_KEXEC_JUMP
+	if (image->preserve_context)
+		save_processor_state();
 #endif
+
+	save_ftrace_enabled = __ftrace_enabled_save();
+
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
@@ -97,12 +120,37 @@ void machine_kexec(struct kimage *image)
 	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
 						relocate_new_kernel_size);
 
-        kexec_info(image);
+	kexec_info(image);
 	flush_cache_all();
 
+#if defined(CONFIG_SH_STANDARD_BIOS)
+	asm volatile("ldc %0, vbr" :
+		     : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
+		     : "memory");
+#endif
+
 	/* now call it */
 	rnk = (relocate_new_kernel_t) reboot_code_buffer;
-	(*rnk)(page_list, reboot_code_buffer, P2SEGADDR(image->start), vbr_reg);
+	(*rnk)(page_list, reboot_code_buffer,
+	       (unsigned long)phys_to_virt(image->start));
+
+#ifdef CONFIG_KEXEC_JUMP
+	asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+
+	if (image->preserve_context)
+		restore_processor_state();
+
+	/* Convert page list back to physical addresses, what a mess. */
+	for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
+	     ptr = (*ptr & IND_INDIRECTION) ?
+	       phys_to_virt(*ptr & PAGE_MASK) : ptr + 1) {
+		if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
+		    *ptr & IND_DESTINATION)
+			*ptr = virt_to_phys(*ptr);
+	}
+#endif
+
+	__ftrace_enabled_restore(save_ftrace_enabled);
 }
 
 void arch_crash_save_vmcoreinfo(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/Makefile_32 linux-libre-2.6.30-gnu1/arch/sh/kernel/Makefile_32
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/Makefile_32	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/Makefile_32	2009-06-09 23:05:27.000000000 -0400
@@ -30,5 +30,6 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
+obj-$(CONFIG_HIBERNATION)	+= swsusp.o
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/process_32.c linux-libre-2.6.30-gnu1/arch/sh/kernel/process_32.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/process_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/process_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -170,20 +170,32 @@ int dump_fpu(struct pt_regs *regs, elf_f
 
 asmlinkage void ret_from_fork(void);
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU)
+#if defined(CONFIG_SH_FPU) || 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:
+		 * __save_dsp(p);
+		 * p->thread.dsp_status.status |= SR_DSP
+		 */
+		p->thread.dsp_status = tsk->thread.dsp_status;
+	}
+#endif
+
 	childregs = task_pt_regs(p);
 	*childregs = *regs;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/process_64.c linux-libre-2.6.30-gnu1/arch/sh/kernel/process_64.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/process_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/process_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -425,7 +425,7 @@ int dump_fpu(struct pt_regs *regs, elf_f
 
 asmlinkage void ret_from_fork(void);
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/ptrace_32.c linux-libre-2.6.30-gnu1/arch/sh/kernel/ptrace_32.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/ptrace_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/ptrace_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,7 +200,8 @@ static int dspregs_get(struct task_struc
 		       unsigned int pos, unsigned int count,
 		       void *kbuf, void __user *ubuf)
 {
-	const struct pt_dspregs *regs = task_pt_dspregs(target);
+	const struct pt_dspregs *regs =
+		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
 	int ret;
 
 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs,
@@ -217,7 +218,8 @@ static int dspregs_set(struct task_struc
 		       unsigned int pos, unsigned int count,
 		       const void *kbuf, const void __user *ubuf)
 {
-	struct pt_dspregs *regs = task_pt_dspregs(target);
+	struct pt_dspregs *regs =
+		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
 	int ret;
 
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/relocate_kernel.S linux-libre-2.6.30-gnu1/arch/sh/kernel/relocate_kernel.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/relocate_kernel.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/relocate_kernel.S	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,8 @@
  *
  * LANDISK/sh4 is supported. Maybe, SH archtecture works well.
  *
+ * 2009-03-18 Magnus Damm - Added Kexec Jump support
+ *
  * This source code is licensed under the GNU General Public License,
  * Version 2.  See the file COPYING for more details.
  */
@@ -16,23 +18,141 @@ relocate_new_kernel:
 	/* r4 = indirection_page   */
 	/* r5 = reboot_code_buffer */
 	/* r6 = start_address      */
-	/* r7 = vbr_reg            */
 
-	mov.l	10f,r8	  /* PAGE_SIZE */
-	mov.l	11f,r9    /* P2SEG */
+	mov.l	10f, r0		/* PAGE_SIZE */
+	add	r5, r0		/* setup new stack at end of control page */
 
-	/*  stack setting */
-	add	r8,r5
-	mov	r5,r15
+	/* save r15->r8 to new stack */
+	mov.l	r15, @-r0
+	mov	r0, r15
+	mov.l	r14, @-r15
+	mov.l	r13, @-r15
+	mov.l	r12, @-r15
+	mov.l	r11, @-r15
+	mov.l	r10, @-r15
+	mov.l	r9, @-r15
+	mov.l	r8, @-r15
+
+	/* save other random registers */
+	sts.l	macl, @-r15
+	sts.l	mach, @-r15
+	stc.l	gbr, @-r15
+	stc.l	ssr, @-r15
+	stc.l	sr, @-r15
+	sts.l	pr, @-r15
+	stc.l	spc, @-r15
+
+	/* switch to bank1 and save r7->r0 */
+	mov.l	12f, r9
+	stc	sr, r8
+	or	r9, r8
+	ldc	r8, sr
+	mov.l	r7, @-r15
+	mov.l	r6, @-r15
+	mov.l	r5, @-r15
+	mov.l	r4, @-r15
+	mov.l	r3, @-r15
+	mov.l	r2, @-r15
+	mov.l	r1, @-r15
+	mov.l	r0, @-r15
+
+	/* switch to bank0 and save r7->r0 */
+	mov.l	12f, r9
+	not	r9, r9
+	stc	sr, r8
+	and	r9, r8
+	ldc	r8, sr
+	mov.l	r7, @-r15
+	mov.l	r6, @-r15
+	mov.l	r5, @-r15
+	mov.l	r4, @-r15
+	mov.l	r3, @-r15
+	mov.l	r2, @-r15
+	mov.l	r1, @-r15
+	mov.l	r0, @-r15
+
+	mov.l	r4, @-r15	/* save indirection page again */
+
+	bsr	swap_pages	/* swap pages before jumping to new kernel */
+	 nop
+
+	mova	11f, r0
+	mov.l	r15, @r0	/* save pointer to stack */
 
+	jsr	@r6		/* hand over control to new kernel */
+	 nop
+
+	mov.l	11f, r15	/* get pointer to stack */
+	mov.l	@r15+, r4	/* restore r4 to get indirection page */
+
+	bsr	swap_pages	/* swap pages back to previous state */
+	 nop
+
+	/* make sure bank0 is active and restore r0->r7 */
+	mov.l	12f, r9
+	not	r9, r9
+	stc	sr, r8
+	and	r9, r8
+	ldc	r8, sr
+	mov.l	@r15+, r0
+	mov.l	@r15+, r1
+	mov.l	@r15+, r2
+	mov.l	@r15+, r3
+	mov.l	@r15+, r4
+	mov.l	@r15+, r5
+	mov.l	@r15+, r6
+	mov.l	@r15+, r7
+
+	/* switch to bank1 and restore r0->r7 */
+	mov.l	12f, r9
+	stc	sr, r8
+	or	r9, r8
+	ldc	r8, sr
+	mov.l	@r15+, r0
+	mov.l	@r15+, r1
+	mov.l	@r15+, r2
+	mov.l	@r15+, r3
+	mov.l	@r15+, r4
+	mov.l	@r15+, r5
+	mov.l	@r15+, r6
+	mov.l	@r15+, r7
+
+	/* switch back to bank0 */
+	mov.l	12f, r9
+	not	r9, r9
+	stc	sr, r8
+	and	r9, r8
+	ldc	r8, sr
+
+	/* restore other random registers */
+	ldc.l	@r15+, spc
+	lds.l	@r15+, pr
+	ldc.l	@r15+, sr
+	ldc.l	@r15+, ssr
+	ldc.l	@r15+, gbr
+	lds.l	@r15+, mach
+	lds.l	@r15+, macl
+
+	/* restore r8->r15 */
+	mov.l	@r15+, r8
+	mov.l	@r15+, r9
+	mov.l	@r15+, r10
+	mov.l	@r15+, r11
+	mov.l	@r15+, r12
+	mov.l	@r15+, r13
+	mov.l	@r15+, r14
+	mov.l	@r15+, r15
+	rts
+	 nop
+
+swap_pages:
 	bra	1f
-	mov	r4,r0	  /* cmd = indirection_page */
+	 mov	r4,r0	  /* cmd = indirection_page */
 0:
 	mov.l	@r4+,r0	  /* cmd = *ind++ */
 
-1:	/* addr = (cmd | P2SEG) & 0xfffffff0 */
+1:	/* addr = cmd & 0xfffffff0 */
 	mov	r0,r2
-	or	r9,r2
 	mov	#-16,r1
 	and	r1,r2
 
@@ -40,57 +160,70 @@ relocate_new_kernel:
 	tst	#1,r0
 	bt	2f
 	bra	0b
-	mov	r2,r5
+	 mov	r2,r5
 
 2:	/* else if(cmd & IND_INDIRECTION) ind = addr  */
 	tst	#2,r0
 	bt	3f
 	bra	0b
-	mov	r2,r4
+	 mov	r2,r4
 
-3:	/* else if(cmd & IND_DONE) goto 6  */
+3:	/* else if(cmd & IND_DONE) return */
 	tst	#4,r0
 	bt	4f
-	bra	6f
-	nop
+	rts
+	 nop
 
 4:	/* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
 	tst	#8,r0
 	bt	0b
 
-	mov	r8,r3
+	mov.l	10f,r3	  /* PAGE_SIZE */
 	shlr2	r3
 	shlr2	r3
 5:
 	dt	r3
-	mov.l	@r2+,r1   /*  16n+0 */
-	mov.l	r1,@r5
-	add	#4,r5
-	mov.l	@r2+,r1	  /*  16n+4 */
-	mov.l	r1,@r5
-	add	#4,r5
-	mov.l	@r2+,r1   /*  16n+8 */
-	mov.l	r1,@r5
-	add	#4,r5
-	mov.l	@r2+,r1   /*  16n+12 */
-	mov.l	r1,@r5
-	add	#4,r5
+
+	/* regular kexec just overwrites the destination page
+	 * with the contents of the source page.
+	 * for the kexec jump case we need to swap the contents
+	 * of the pages.
+	 * to keep it simple swap the contents for both cases.
+	 */
+	mov.l	@(0, r2), r8
+	mov.l	@(0, r5), r1
+	mov.l	r8, @(0, r5)
+	mov.l	r1, @(0, r2)
+
+	mov.l	@(4, r2), r8
+	mov.l	@(4, r5), r1
+	mov.l	r8, @(4, r5)
+	mov.l	r1, @(4, r2)
+
+	mov.l	@(8, r2), r8
+	mov.l	@(8, r5), r1
+	mov.l	r8, @(8, r5)
+	mov.l	r1, @(8, r2)
+
+	mov.l	@(12, r2), r8
+	mov.l	@(12, r5), r1
+	mov.l	r8, @(12, r5)
+	mov.l	r1, @(12, r2)
+
+	add	#16,r5
+	add	#16,r2
 	bf	5b
 
 	bra	0b
-	nop
-6:
-#ifdef CONFIG_SH_STANDARD_BIOS
-	ldc   r7, vbr
-#endif
-	jmp @r6
-	nop
+	 nop
 
 	.align 2
 10:
 	.long	PAGE_SIZE
 11:
-	.long	P2SEG
+	.long	0
+12:
+	.long	0x20000000 ! RB=1
 
 relocate_new_kernel_end:
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/setup.c linux-libre-2.6.30-gnu1/arch/sh/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,12 +103,11 @@ static int __init early_parse_mem(char *
 	size = memparse(p, &p);
 
 	if (size > __MEMORY_SIZE) {
-		static char msg[] __initdata = KERN_ERR
+		printk(KERN_ERR
 			"Using mem= to increase the size of kernel memory "
 			"is not allowed.\n"
 			"  Recompile the kernel with the correct value for "
-			"CONFIG_MEMORY_SIZE.\n";
-		printk(msg);
+			"CONFIG_MEMORY_SIZE.\n");
 		return 0;
 	}
 
@@ -432,6 +431,7 @@ static const char *cpu_name[] = {
 	[CPU_SH7763]	= "SH7763",	[CPU_SH7770]	= "SH7770",
 	[CPU_SH7780]	= "SH7780",	[CPU_SH7781]	= "SH7781",
 	[CPU_SH7343]	= "SH7343",	[CPU_SH7785]	= "SH7785",
+	[CPU_SH7786]	= "SH7786",
 	[CPU_SH7722]	= "SH7722",	[CPU_SHX3]	= "SH-X3",
 	[CPU_SH5_101]	= "SH5-101",	[CPU_SH5_103]	= "SH5-103",
 	[CPU_MXG]	= "MX-G",	[CPU_SH7723]	= "SH7723",
@@ -448,7 +448,7 @@ EXPORT_SYMBOL(get_cpu_subtype);
 /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
 static const char *cpu_flags[] = {
 	"none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
-	"ptea", "llsc", "l2", "op32", NULL
+	"ptea", "llsc", "l2", "op32", "pteaex", NULL
 };
 
 static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/swsusp.c linux-libre-2.6.30-gnu1/arch/sh/kernel/swsusp.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/swsusp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/swsusp.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * swsusp.c - SuperH hibernation support
+ *
+ * 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/mm.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <asm/suspend.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/fpu.h>
+
+struct swsusp_arch_regs swsusp_arch_regs_cpu0;
+
+int pfn_is_nosave(unsigned long pfn)
+{
+	unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+	unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+
+	return (pfn >= begin_pfn) && (pfn < end_pfn);
+}
+
+void save_processor_state(void)
+{
+	init_fpu(current);
+}
+
+void restore_processor_state(void)
+{
+	local_flush_tlb_all();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/syscalls_32.S linux-libre-2.6.30-gnu1/arch/sh/kernel/syscalls_32.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/syscalls_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/syscalls_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -349,3 +349,5 @@ ENTRY(sys_call_table)
 	.long sys_dup3			/* 330 */
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_writev
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/syscalls_64.S linux-libre-2.6.30-gnu1/arch/sh/kernel/syscalls_64.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/syscalls_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/syscalls_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -387,3 +387,5 @@ sys_call_table:
 	.long sys_dup3
 	.long sys_pipe2
 	.long sys_inotify_init1		/* 360 */
+	.long sys_preadv
+	.long sys_pwritev
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/sys_sh.c linux-libre-2.6.30-gnu1/arch/sh/kernel/sys_sh.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/sys_sh.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/sys_sh.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,6 +63,15 @@ asmlinkage long sys_mmap2(unsigned long
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
 {
+	/*
+	 * The shift for mmap2 is constant, regardless of PAGE_SIZE
+	 * setting.
+	 */
+	if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
+		return -EINVAL;
+
+	pgoff >>= PAGE_SHIFT - 12;
+
 	return do_mmap2(addr, len, prot, flags, fd, pgoff);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/time_32.c linux-libre-2.6.30-gnu1/arch/sh/kernel/time_32.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/time_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/time_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,14 +41,6 @@ static int null_rtc_set_time(const time_
 	return 0;
 }
 
-/*
- * Null high precision timer functions for systems lacking one.
- */
-static cycle_t null_hpt_read(void)
-{
-	return 0;
-}
-
 void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
 
@@ -112,7 +104,6 @@ int do_settimeofday(struct timespec *tv)
 EXPORT_SYMBOL(do_settimeofday);
 #endif /* !CONFIG_GENERIC_TIME */
 
-#ifndef CONFIG_GENERIC_CLOCKEVENTS
 /* last time the RTC clock got updated */
 static long last_rtc_update;
 
@@ -156,7 +147,6 @@ void handle_timer_tick(void)
 	update_process_times(user_mode(get_irq_regs()));
 #endif
 }
-#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 #ifdef CONFIG_PM
 int timer_suspend(struct sys_device *dev, pm_message_t state)
@@ -189,7 +179,12 @@ static struct sysdev_class timer_sysclas
 
 static int __init timer_init_sysfs(void)
 {
-	int ret = sysdev_class_register(&timer_sysclass);
+	int ret;
+
+	if (!sys_timer)
+		return 0;
+
+	ret = sysdev_class_register(&timer_sysclass);
 	if (ret != 0)
 		return ret;
 
@@ -200,42 +195,21 @@ device_initcall(timer_init_sysfs);
 
 void (*board_time_init)(void);
 
-/*
- * Shamelessly based on the MIPS and Sparc64 work.
- */
-static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
-unsigned long sh_hpt_frequency = 0;
-
-#define NSEC_PER_CYC_SHIFT	10
-
-static struct clocksource clocksource_sh = {
+struct clocksource clocksource_sh = {
 	.name		= "SuperH",
-	.rating		= 200,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.read		= null_hpt_read,
-	.shift		= 16,
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static void __init init_sh_clocksource(void)
-{
-	if (!sh_hpt_frequency || clocksource_sh.read == null_hpt_read)
-		return;
-
-	clocksource_sh.mult = clocksource_hz2mult(sh_hpt_frequency,
-						  clocksource_sh.shift);
-
-	timer_ticks_per_nsec_quotient =
-		clocksource_hz2mult(sh_hpt_frequency, NSEC_PER_CYC_SHIFT);
-
-	clocksource_register(&clocksource_sh);
-}
-
 #ifdef CONFIG_GENERIC_TIME
 unsigned long long sched_clock(void)
 {
-	unsigned long long ticks = clocksource_sh.read();
-	return (ticks * timer_ticks_per_nsec_quotient) >> NSEC_PER_CYC_SHIFT;
+	unsigned long long cycles;
+
+	/* jiffies based sched_clock if no clocksource is installed */
+	if (!clocksource_sh.rating)
+		return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
+
+	cycles = clocksource_sh.read(&clocksource_sh);
+	return cyc2ns(&clocksource_sh, cycles);
 }
 #endif
 
@@ -259,17 +233,8 @@ void __init time_init(void)
 	 * initialized for us.
 	 */
 	sys_timer = get_sys_timer();
-	printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
-
-
-	if (sys_timer->ops->read)
-		clocksource_sh.read = sys_timer->ops->read;
-
-	init_sh_clocksource();
-
-	if (sh_hpt_frequency)
-		printk("Using %lu.%03lu MHz high precision timer.\n",
-		       ((sh_hpt_frequency + 500) / 1000) / 1000,
-		       ((sh_hpt_frequency + 500) / 1000) % 1000);
+	if (unlikely(!sys_timer))
+		panic("System timer missing.\n");
 
+	printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/time_64.c linux-libre-2.6.30-gnu1/arch/sh/kernel/time_64.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/time_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/time_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -284,7 +284,6 @@ static irqreturn_t timer_interrupt(int i
 static struct irqaction irq0  = {
 	.handler = timer_interrupt,
 	.flags = IRQF_DISABLED,
-	.mask = CPU_MASK_NONE,
 	.name = "timer",
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-cmt.c linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-cmt.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-cmt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-cmt.c	2009-06-09 23:05:27.000000000 -0400
@@ -109,7 +109,6 @@ static struct irqaction cmt_irq = {
 	.name		= "timer",
 	.handler	= cmt_timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.mask		= CPU_MASK_NONE,
 };
 
 static void cmt_clk_init(struct clk *clk)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-mtu2.c linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-mtu2.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-mtu2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-mtu2.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,8 @@
 #define MTU2_TSR_1	0xfffe4385
 #define MTU2_TCNT_1	0xfffe4386	/* 16-bit counter */
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7201)
+#if defined(CONFIG_CPU_SUBTYPE_SH7201) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7203)
 #define MTU2_TGRA_1	0xfffe4388
 #else
 #define MTU2_TGRA_1	0xfffe438a
@@ -114,7 +115,6 @@ static struct irqaction mtu2_irq = {
 	.name		= "timer",
 	.handler	= mtu2_timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.mask		= CPU_MASK_NONE,
 };
 
 static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-tmu.c linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-tmu.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/timers/timer-tmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/timers/timer-tmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,7 +81,7 @@ static int tmu_timer_stop(void)
  */
 static int tmus_are_scaled;
 
-static cycle_t tmu_timer_read(void)
+static cycle_t tmu_timer_read(struct clocksource *cs)
 {
 	return ((cycle_t)(~_tmu_read(TMU1)))<<tmus_are_scaled;
 }
@@ -146,7 +146,14 @@ static irqreturn_t tmu_timer_interrupt(i
 	_tmu_clear_status(TMU0);
 	_tmu_set_irq(TMU0,tmu0_clockevent.mode != CLOCK_EVT_MODE_ONESHOT);
 
-	evt->event_handler(evt);
+	switch (tmu0_clockevent.mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_PERIODIC:
+		evt->event_handler(evt);
+		break;
+	default:
+		break;
+	}
 
 	return IRQ_HANDLED;
 }
@@ -155,7 +162,6 @@ static struct irqaction tmu0_irq = {
 	.name		= "periodic/oneshot timer",
 	.handler	= tmu_timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.mask		= CPU_MASK_NONE,
 };
 
 static void __init tmu_clk_init(struct clk *clk)
@@ -237,6 +243,7 @@ static int tmu_timer_init(void)
     !defined(CONFIG_CPU_SUBTYPE_SH7721) && \
     !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
     !defined(CONFIG_CPU_SUBTYPE_SH7785) && \
+    !defined(CONFIG_CPU_SUBTYPE_SH7786) && \
     !defined(CONFIG_CPU_SUBTYPE_SHX3)
 	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
 #endif
@@ -254,7 +261,14 @@ static int tmu_timer_init(void)
 
 	_tmu_start(TMU1);
 
-	sh_hpt_frequency = clk_get_rate(&tmu1_clk);
+	clocksource_sh.rating = 200;
+	clocksource_sh.mask = CLOCKSOURCE_MASK(32);
+	clocksource_sh.read = tmu_timer_read;
+	clocksource_sh.shift = 10;
+	clocksource_sh.mult = clocksource_hz2mult(clk_get_rate(&tmu1_clk),
+						  clocksource_sh.shift);
+	clocksource_sh.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+	clocksource_register(&clocksource_sh);
 
 	tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC,
 				      tmu0_clockevent.shift);
@@ -264,6 +278,7 @@ static int tmu_timer_init(void)
 			clockevent_delta2ns(1, &tmu0_clockevent);
 
 	tmu0_clockevent.cpumask = cpumask_of(0);
+	tmu0_clockevent.rating = 100;
 
 	clockevents_register_device(&tmu0_clockevent);
 
@@ -274,7 +289,6 @@ static struct sys_timer_ops tmu_timer_op
 	.init		= tmu_timer_init,
 	.start		= tmu_timer_start,
 	.stop		= tmu_timer_stop,
-	.read		= tmu_timer_read,
 };
 
 struct sys_timer tmu_timer = {
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/traps_32.c linux-libre-2.6.30-gnu1/arch/sh/kernel/traps_32.c
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/traps_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/traps_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -664,6 +664,8 @@ asmlinkage void do_reserved_inst(unsigne
 	if (is_dsp_inst(regs)) {
 		/* Enable DSP mode, and restart instruction. */
 		regs->sr |= SR_DSP;
+		/* Save DSP mode */
+		tsk->thread.dsp_status.status |= SR_DSP;
 		return;
 	}
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/vmlinux_32.lds.S linux-libre-2.6.30-gnu1/arch/sh/kernel/vmlinux_32.lds.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/vmlinux_32.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/vmlinux_32.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,10 @@ OUTPUT_ARCH(sh)
 ENTRY(_start)
 SECTIONS
 {
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB_FIXED
+	. = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
+	    CONFIG_ZERO_PAGE_OFFSET;
+#elif defined(CONFIG_32BIT)
 	. = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
 #else
 	. = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
@@ -28,7 +31,7 @@ SECTIONS
 	} = 0
 
 	.text : {
-		*(.text.head)
+		HEAD_TEXT
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/kernel/vmlinux_64.lds.S linux-libre-2.6.30-gnu1/arch/sh/kernel/vmlinux_64.lds.S
--- linux-libre-2.6.29-gnu1/arch/sh/kernel/vmlinux_64.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/kernel/vmlinux_64.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ SECTIONS
 	} = 0
 
 	.text : C_PHYS(.text) {
-		*(.text.head)
+		HEAD_TEXT
 		TEXT_TEXT
 		*(.text64)
 		*(.text..SHmedia32)
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/Makefile linux-libre-2.6.30-gnu1/arch/sh/Makefile
--- linux-libre-2.6.29-gnu1/arch/sh/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -80,6 +80,7 @@ OBJCOPYFLAGS	:= -O binary -R .note -R .n
 defaultimage-$(CONFIG_SUPERH32)			:= zImage
 defaultimage-$(CONFIG_SH_SH7785LCR)		:= uImage
 defaultimage-$(CONFIG_SH_RSK)			:= uImage
+defaultimage-$(CONFIG_SH_URQUELL)		:= uImage
 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE)	:= vmlinux
 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE)	:= vmlinux
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/asids-debugfs.c linux-libre-2.6.30-gnu1/arch/sh/mm/asids-debugfs.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/asids-debugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/asids-debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,10 +37,8 @@ static int asids_seq_show(struct seq_fil
 			continue;
 
 		if (p->mm)
-			seq_printf(file, "%5d : %02lx\n", pid,
+			seq_printf(file, "%5d : %04lx\n", pid,
 				   cpu_asid(smp_processor_id(), p->mm));
-		else
-			seq_printf(file, "%5d : (none)\n", pid);
 	}
 
 	read_unlock(&tasklist_lock);
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/consistent.c linux-libre-2.6.30-gnu1/arch/sh/mm/consistent.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/consistent.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/consistent.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,11 +10,22 @@
  * for more details.
  */
 #include <linux/mm.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
+#include <linux/io.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
-#include <asm/io.h>
+
+#define PREALLOC_DMA_DEBUG_ENTRIES	4096
+
+static int __init dma_init(void)
+{
+	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+	return 0;
+}
+fs_initcall(dma_init);
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t gfp)
@@ -45,6 +56,9 @@ void *dma_alloc_coherent(struct device *
 	split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
 
 	*dma_handle = virt_to_phys(ret);
+
+	debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache);
+
 	return ret_nocache;
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
@@ -56,12 +70,15 @@ void dma_free_coherent(struct device *de
 	unsigned long pfn = dma_handle >> PAGE_SHIFT;
 	int k;
 
-	if (!dma_release_from_coherent(dev, order, vaddr)) {
-		WARN_ON(irqs_disabled());	/* for portability */
-		for (k = 0; k < (1 << order); k++)
-			__free_pages(pfn_to_page(pfn + k), 0);
-		iounmap(vaddr);
-	}
+	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);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/ioremap_32.c linux-libre-2.6.30-gnu1/arch/sh/mm/ioremap_32.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/ioremap_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/ioremap_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -59,11 +59,13 @@ void __iomem *__ioremap(unsigned long ph
 	if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr))
 		return (void __iomem *)phys_addr;
 
+#if !defined(CONFIG_PMB_FIXED)
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
 	if (phys_addr < virt_to_phys(high_memory))
 		return NULL;
+#endif
 
 	/*
 	 * Mappings have to be page-aligned
@@ -81,7 +83,7 @@ void __iomem *__ioremap(unsigned long ph
 	area->phys_addr = phys_addr;
 	orig_addr = addr = (unsigned long)area->addr;
 
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB
 	/*
 	 * First try to remap through the PMB once a valid VMA has been
 	 * established. Smaller allocations (or the rest of the size
@@ -119,10 +121,10 @@ void __iounmap(void __iomem *addr)
 	unsigned long seg = PXSEG(vaddr);
 	struct vm_struct *p;
 
-	if (seg < P3SEG || seg >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
+	if (seg < P3SEG || vaddr >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
 		return;
 
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB
 	/*
 	 * Purge any PMB entries that may have been established for this
 	 * mapping, then proceed with conventional VMA teardown.
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/Kconfig linux-libre-2.6.30-gnu1/arch/sh/mm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sh/mm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@ config 32BIT
 	bool
 	default y if CPU_SH5
 
-config PMB
+config PMB_ENABLE
 	bool "Support 32-bit physical addressing through PMB"
 	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
 	select 32BIT
@@ -67,6 +67,33 @@ config PMB
 	  32-bits through the SH-4A PMB. If this is not set, legacy
 	  29-bit physical addressing will be used.
 
+choice
+	prompt "PMB handling type"
+	depends on PMB_ENABLE
+	default PMB_FIXED
+
+config PMB
+	bool "PMB"
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+	select 32BIT
+	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
+	  29-bit physical addressing will be used.
+
+config PMB_FIXED
+	bool "fixed PMB"
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || \
+					   CPU_SUBTYPE_SH7785)
+	select 32BIT
+	help
+	  If this option is enabled, fixed PMB mappings are inherited
+	  from the boot loader, and the kernel does not attempt dynamic
+	  management. This is the closest to legacy 29-bit physical mode,
+	  and allows systems to support up to 512MiB of system memory.
+
+endchoice
+
 config X2TLB
 	bool "Enable extended TLB mode"
 	depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL
@@ -224,18 +251,6 @@ config SH7705_CACHE_32KB
 	depends on CPU_SUBTYPE_SH7705
 	default y
 
-config SH_DIRECT_MAPPED
-	bool "Use direct-mapped caching"
-	default n
-	help
-	  Selecting this option will configure the caches to be direct-mapped,
-	  even if the cache supports a 2 or 4-way mode. This is useful primarily
-	  for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R,
-	  SH4-202, SH4-501, etc.)
-
-	  Turn this option off for platforms that do not have a direct-mapped
-	  cache, and you have no need to run the caches in such a configuration.
-
 choice
 	prompt "Cache mode"
 	default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/Makefile_32 linux-libre-2.6.30-gnu1/arch/sh/mm/Makefile_32
--- linux-libre-2.6.29-gnu1/arch/sh/mm/Makefile_32	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/Makefile_32	2009-06-09 23:05:27.000000000 -0400
@@ -25,8 +25,10 @@ obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
 endif
 
 ifdef CONFIG_MMU
-obj-$(CONFIG_CPU_SH3)	+= tlb-sh3.o
-obj-$(CONFIG_CPU_SH4)	+= tlb-sh4.o
+tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
+tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
+obj-y				+= $(tlb-y)
 ifndef CONFIG_CACHE_OFF
 obj-$(CONFIG_CPU_SH4)		+= pg-sh4.o
 obj-$(CONFIG_SH7705_CACHE_32KB)	+= pg-sh7705.o
@@ -35,6 +37,7 @@ endif
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PMB)		+= pmb.o
+obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
 obj-$(CONFIG_NUMA)		+= numa.o
 
 EXTRA_CFLAGS += -Werror
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/pmb.c linux-libre-2.6.30-gnu1/arch/sh/mm/pmb.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/pmb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/pmb.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,8 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
@@ -402,3 +404,39 @@ static int __init pmb_debugfs_init(void)
 	return 0;
 }
 postcore_initcall(pmb_debugfs_init);
+
+#ifdef CONFIG_PM
+static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
+{
+	static pm_message_t prev_state;
+
+	/* 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);
+	}
+	prev_state = state;
+	return 0;
+}
+
+static int pmb_sysdev_resume(struct sys_device *dev)
+{
+	return pmb_sysdev_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_driver pmb_sysdev_driver = {
+	.suspend = pmb_sysdev_suspend,
+	.resume = pmb_sysdev_resume,
+};
+
+static int __init pmb_sysdev_init(void)
+{
+	return sysdev_driver_register(&cpu_sysdev_class, &pmb_sysdev_driver);
+}
+
+subsys_initcall(pmb_sysdev_init);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/mm/pmb-fixed.c linux-libre-2.6.30-gnu1/arch/sh/mm/pmb-fixed.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/pmb-fixed.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/pmb-fixed.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * 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.29-gnu1/arch/sh/mm/tlb-pteaex.c linux-libre-2.6.30-gnu1/arch/sh/mm/tlb-pteaex.c
--- linux-libre-2.6.29-gnu1/arch/sh/mm/tlb-pteaex.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/sh/mm/tlb-pteaex.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * arch/sh/mm/tlb-pteaex.c
+ *
+ * TLB operations for SH-X3 CPUs featuring PTE ASID Extensions.
+ *
+ * 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/mm.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	unsigned long pteval;
+	unsigned long vpn;
+
+	/* Ptrace may call this routine. */
+	if (vma && current->active_mm != vma->vm_mm)
+		return;
+
+#ifndef CONFIG_CACHE_OFF
+	{
+		unsigned long pfn = pte_pfn(pte);
+
+		if (pfn_valid(pfn)) {
+			struct page *page = pfn_to_page(pfn);
+
+			if (!test_bit(PG_mapped, &page->flags)) {
+				unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+				__flush_wback_region((void *)P1SEGADDR(phys),
+						     PAGE_SIZE);
+				__set_bit(PG_mapped, &page->flags);
+			}
+		}
+	}
+#endif
+
+	local_irq_save(flags);
+
+	/* Set PTEH register */
+	vpn = address & MMU_VPN_MASK;
+	__raw_writel(vpn, MMU_PTEH);
+
+	/* Set PTEAEX */
+	__raw_writel(get_asid(), MMU_PTEAEX);
+
+	pteval = pte.pte_low;
+
+	/* Set PTEA register */
+#ifdef CONFIG_X2TLB
+	/*
+	 * For the extended mode TLB this is trivial, only the ESZ and
+	 * EPR bits need to be written out to PTEA, with the remainder of
+	 * the protection bits (with the exception of the compat-mode SZ
+	 * and PR bits, which are cleared) being written out in PTEL.
+	 */
+	__raw_writel(pte.pte_high, MMU_PTEA);
+#endif
+
+	/* Set PTEL register */
+	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+#ifdef CONFIG_CACHE_WRITETHROUGH
+	pteval |= _PAGE_WT;
+#endif
+	/* conveniently, we want all the software flags to be 0 anyway */
+	__raw_writel(pteval, MMU_PTEL);
+
+	/* Load the TLB */
+	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+	local_irq_restore(flags);
+}
+
+/*
+ * While SH-X2 extended TLB mode splits out the memory-mapped I/UTLB
+ * data arrays, SH-X3 cores with PTEAEX split out the memory-mapped
+ * address arrays. In compat mode the second array is inaccessible, while
+ * in extended mode, the legacy 8-bit ASID field in address array 1 has
+ * undefined behaviour.
+ */
+void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
+						 unsigned long page)
+{
+	jump_to_uncached();
+	__raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
+	__raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
+	back_to_cached();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/oprofile/common.c linux-libre-2.6.30-gnu1/arch/sh/oprofile/common.c
--- linux-libre-2.6.29-gnu1/arch/sh/oprofile/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/oprofile/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,6 +107,7 @@ int __init oprofile_arch_init(struct opr
 	case CPU_SH7780:
 	case CPU_SH7781:
 	case CPU_SH7785:
+	case CPU_SH7786:
 	case CPU_SH7723:
 	case CPU_SHX3:
 		lmodel = &op_model_sh4a_ops;
diff -druNp linux-libre-2.6.29-gnu1/arch/sh/tools/mach-types linux-libre-2.6.30-gnu1/arch/sh/tools/mach-types
--- linux-libre-2.6.29-gnu1/arch/sh/tools/mach-types	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sh/tools/mach-types	2009-06-09 23:05:27.000000000 -0400
@@ -52,3 +52,6 @@ RSK7203			SH_RSK7203
 AP325RXA		SH_AP325RXA
 SH7763RDP		SH_SH7763RDP
 SH7785LCR		SH_SH7785LCR
+URQUELL			SH_URQUELL
+ESPT			SH_ESPT
+POLARIS			SH_POLARIS
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/configs/sparc32_defconfig linux-libre-2.6.30-gnu1/arch/sparc/configs/sparc32_defconfig
--- linux-libre-2.6.29-gnu1/arch/sparc/configs/sparc32_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/configs/sparc32_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Thu Jan  8 16:45:44 2009
+# Linux kernel version: 2.6.30-rc2
+# Fri Apr 17 04:04:46 2009
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -30,17 +30,27 @@ 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_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=14
-# CONFIG_CGROUPS is not set
 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
@@ -49,24 +59,28 @@ CONFIG_NAMESPACES=y
 # 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 is not set
 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_STRIP_ASM_SYMS is not set
 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
@@ -75,12 +89,15 @@ CONFIG_SHMEM=y
 CONFIG_AIO=y
 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_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -93,7 +110,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -109,11 +125,6 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-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_FREEZER is not set
 
 #
@@ -144,6 +155,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_SUN_PM=y
 # CONFIG_SPARC_LED is not set
 CONFIG_SERIAL_CONSOLE=y
@@ -159,6 +172,7 @@ CONFIG_PCI_SYSCALL=y
 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
 CONFIG_SUN_OPENPROMFS=m
 CONFIG_SPARC32_PCI=y
@@ -175,8 +189,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -251,6 +263,7 @@ CONFIG_IPV6_TUNNEL=m
 # 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
 
@@ -263,7 +276,6 @@ CONFIG_NET_PKTGEN=m
 # 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
@@ -313,12 +325,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # 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_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -375,8 +391,10 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 # CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -398,6 +416,7 @@ CONFIG_SCSI_QLOGICPTI=m
 CONFIG_SCSI_SUNESP=y
 # CONFIG_SCSI_SRP 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
@@ -413,6 +432,7 @@ CONFIG_SCSI_SUNESP=y
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -430,6 +450,8 @@ CONFIG_SUNQE=m
 # 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_ZMII is not set
@@ -448,6 +470,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_E1000 is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -462,6 +485,7 @@ CONFIG_NETDEV_1000=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=y
 # CONFIG_CHELSIO_T1 is not set
@@ -471,6 +495,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
@@ -480,6 +505,7 @@ 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
 
 #
@@ -487,7 +513,6 @@ CONFIG_CHELSIO_T3_DEPENDS=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
@@ -537,7 +562,6 @@ CONFIG_MOUSE_PS2=m
 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_TOUCHKIT is not set
@@ -597,6 +621,7 @@ 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_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -688,7 +713,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_COMPAT=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -700,7 +724,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,6 +774,7 @@ CONFIG_RTC_DRV_M48T59=y
 # on-CPU RTC drivers
 #
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -777,6 +802,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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
@@ -786,6 +812,11 @@ CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=m
@@ -820,14 +851,20 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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=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_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -838,7 +875,6 @@ CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -911,6 +947,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 is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -939,15 +978,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-
-#
-# Tracers
-#
-# 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_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_KGDB=y
@@ -979,10 +1010,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=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1052,6 +1085,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1059,6 +1093,7 @@ CONFIG_CRYPTO_DEFLATE=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1074,7 +1109,10 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=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.29-gnu1/arch/sparc/configs/sparc64_defconfig linux-libre-2.6.30-gnu1/arch/sparc/configs/sparc64_defconfig
--- linux-libre-2.6.29-gnu1/arch/sparc/configs/sparc64_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/configs/sparc64_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  2 18:14:26 2009
+# Linux kernel version: 2.6.30-rc2
+# Fri Apr 17 02:03:07 2009
 #
+CONFIG_64BIT=y
 CONFIG_SPARC=y
+# CONFIG_SPARC32 is not set
 CONFIG_SPARC64=y
 CONFIG_ARCH_DEFCONFIG="arch/sparc/configs/sparc64_defconfig"
 CONFIG_BITS=64
-CONFIG_64BIT=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -22,6 +23,7 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -36,17 +38,27 @@ 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_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=18
-# CONFIG_CGROUPS is not set
 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=y
@@ -55,24 +67,28 @@ CONFIG_NAMESPACES=y
 # 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_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_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
@@ -82,6 +98,7 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -91,15 +108,16 @@ CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
 CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=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 is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -107,10 +125,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
@@ -127,11 +143,6 @@ CONFIG_DEFAULT_AS=y
 # 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_FREEZER is not set
 
 #
@@ -185,11 +196,12 @@ CONFIG_SPARSEMEM_VMEMMAP=y
 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_NR_QUICK=1
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
 # CONFIG_PREEMPT_NONE is not set
@@ -210,6 +222,8 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_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_SUN_OPENPROMFS=m
 CONFIG_SPARC64_PCI=y
@@ -229,8 +243,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -292,25 +304,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-CONFIG_IP_DCCP=m
-CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
-
-#
-# DCCP CCIDs Configuration (EXPERIMENTAL)
-#
-CONFIG_IP_DCCP_CCID2=m
-# CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
-# CONFIG_IP_DCCP_CCID3_DEBUG is not set
-CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
-
-#
-# DCCP Kernel Hacking
-#
-# CONFIG_IP_DCCP_DEBUG is not set
-# CONFIG_NET_DCCPPROBE 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
@@ -326,6 +320,7 @@ CONFIG_VLAN_8021Q=m
 # 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
 
@@ -334,18 +329,19 @@ CONFIG_VLAN_8021Q=m
 #
 CONFIG_NET_PKTGEN=m
 CONFIG_NET_TCPPROBE=m
+# 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=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
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -389,19 +385,27 @@ CONFIG_SUNVDC=m
 # 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_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO 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_93CX6 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_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
@@ -439,6 +443,7 @@ CONFIG_BLK_DEV_ALI15X3=y
 # 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
@@ -506,8 +511,10 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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_LIBFC is not set
+# CONFIG_LIBFCOE is not set
 # CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -528,6 +535,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_SUNESP is not set
 # CONFIG_SCSI_SRP 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
@@ -536,7 +544,7 @@ CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID456=m
-# CONFIG_MD_RAID5_RESHAPE is not set
+CONFIG_MD_RAID6_PQ=m
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
@@ -561,6 +569,7 @@ CONFIG_DM_ZERO=m
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O 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
@@ -589,14 +598,16 @@ CONFIG_PHYLIB=m
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
+CONFIG_SUNLANCE=m
+CONFIG_HAPPYMEAL=m
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-CONFIG_CASSINI=m
+CONFIG_SUNGEM=m
+# CONFIG_CASSINI is not set
 CONFIG_SUNVNET=m
 # 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_ZMII is not set
@@ -631,9 +642,10 @@ CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
-# CONFIG_E1000E is not set
+CONFIG_E1000E=m
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -648,6 +660,7 @@ CONFIG_BNX2=m
 # 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
@@ -657,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=m
@@ -666,6 +680,7 @@ CONFIG_NIU=m
 # 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
 
 #
@@ -673,7 +688,10 @@ CONFIG_NIU=m
 #
 # 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
@@ -738,7 +756,6 @@ 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_TOUCHKIT is not set
@@ -805,6 +822,7 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_HW_RANDOM_N2RNG=m
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -867,12 +885,9 @@ CONFIG_I2C_ALGOBIT=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
@@ -897,12 +912,14 @@ 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_I5K_AMB 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
@@ -917,10 +934,14 @@ 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_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_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -957,10 +978,12 @@ CONFIG_SSB_POSSIBLE=y
 # 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -1053,6 +1076,7 @@ CONFIG_FB_ATY_GX=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
 
 #
@@ -1141,6 +1165,8 @@ CONFIG_SND_ALI5451=m
 # 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
@@ -1197,28 +1223,31 @@ CONFIG_USB_HIDDEV=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_DRAGONRISE_FF is not set
 CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=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_NTRIG=y
 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_TOPSEED=y
 # CONFIG_THRUSTMASTER_FF is not set
 # CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
@@ -1247,6 +1276,7 @@ CONFIG_USB_DEVICEFS=y
 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=y
@@ -1268,18 +1298,17 @@ CONFIG_USB_UHCI_HCD=m
 # 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_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
@@ -1315,7 +1344,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
@@ -1327,6 +1355,11 @@ CONFIG_USB_STORAGE=m
 # 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
@@ -1390,6 +1423,7 @@ CONFIG_RTC_DRV_BQ4802=y
 CONFIG_RTC_DRV_SUN4V=y
 CONFIG_RTC_DRV_STARFIRE=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1412,6 +1446,7 @@ 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
@@ -1426,6 +1461,7 @@ 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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1435,6 +1471,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
@@ -1460,10 +1501,7 @@ CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=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_ECRYPT_FS is not set
@@ -1473,6 +1511,7 @@ CONFIG_HUGETLB_PAGE=y
 # 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
@@ -1481,6 +1520,7 @@ CONFIG_HUGETLB_PAGE=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
@@ -1555,6 +1595,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 is not set
 CONFIG_SCHEDSTATS=y
 # CONFIG_TIMER_STATS is not set
@@ -1590,10 +1633,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_RING_BUFFER=y
 CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -1602,18 +1647,21 @@ CONFIG_TRACING=y
 # 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=y
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG 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_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 
 #
 # Security options
@@ -1642,10 +1690,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=m
 CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 CONFIG_CRYPTO_TEST=m
@@ -1715,6 +1765,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1723,11 +1774,13 @@ CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
 # CONFIG_CRC_T10DIF is not set
@@ -1737,8 +1790,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=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_HAVE_LMB=y
+CONFIG_NLATTR=y
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/atomic_32.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/atomic_32.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/atomic_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/atomic_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,8 @@
 
 #ifdef __KERNEL__
 
+#include <asm/system.h>
+
 #define ATOMIC_INIT(i)  { (i) }
 
 extern int __atomic_add_return(int, atomic_t *);
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/elf_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/elf_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/elf_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/elf_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -208,8 +208,9 @@ do {	unsigned long new_flags = current_t
 	else						\
 		clear_thread_flag(TIF_ABI_PENDING);	\
 	/* flush_thread will update pgd cache */	\
-	if (current->personality != PER_LINUX32)	\
-		set_personality(PER_LINUX);		\
+	if (personality(current->personality) != PER_LINUX32)	\
+		set_personality(PER_LINUX |		\
+			(current->personality & (~PER_MASK)));	\
 } while (0)
 
 #endif /* !(__ASM_SPARC64_ELF_H) */
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/mmu_context_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/mmu_context_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/mmu_context_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/mmu_context_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -121,8 +121,8 @@ static inline void switch_mm(struct mm_s
 	 * local TLB.
 	 */
 	cpu = smp_processor_id();
-	if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
-		cpu_set(cpu, mm->cpu_vm_mask);
+	if (!ctx_valid || !cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+		cpumask_set_cpu(cpu, mm_cpumask(mm));
 		__flush_tlb_mm(CTX_HWBITS(mm->context),
 			       SECONDARY_CONTEXT);
 	}
@@ -141,8 +141,8 @@ static inline void activate_mm(struct mm
 	if (!CTX_VALID(mm->context))
 		get_new_mmu_context(mm);
 	cpu = smp_processor_id();
-	if (!cpu_isset(cpu, mm->cpu_vm_mask))
-		cpu_set(cpu, mm->cpu_vm_mask);
+	if (!cpumask_test_cpu(cpu, mm_cpumask(mm)))
+		cpumask_set_cpu(cpu, mm_cpumask(mm));
 
 	load_secondary_context(mm);
 	__flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/mmzone.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/mmzone.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/mmzone.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/mmzone.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,8 @@
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
 
+#include <linux/cpumask.h>
+
 extern struct pglist_data *node_data[];
 
 #define NODE_DATA(nid)		(node_data[nid])
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/parport.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/parport.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/parport.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/parport.h	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,7 @@ static int __devinit ecpp_probe(struct o
 	if (!strcmp(parent->name, "dma")) {
 		p = parport_pc_probe_port(base, base + 0x400,
 					  op->irqs[0], PARPORT_DMA_NOFIFO,
-					  op->dev.parent->parent);
+					  op->dev.parent->parent, 0);
 		if (!p)
 			return -ENOMEM;
 		dev_set_drvdata(&op->dev, p);
@@ -168,7 +168,8 @@ static int __devinit ecpp_probe(struct o
 	p = parport_pc_probe_port(base, base + 0x400,
 				  op->irqs[0],
 				  slot,
-				  op->dev.parent);
+				  op->dev.parent,
+				  0);
 	err = -ENOMEM;
 	if (!p)
 		goto out_disable_irq;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/smp_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/smp_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/smp_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/smp_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,8 @@ extern cpumask_t cpu_core_map[NR_CPUS];
 extern int sparc64_multi_core;
 
 extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
 
 /*
  *	General functions that each host system must provide.
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,9 @@
 
 #define SO_MARK			0x0022
 
+#define SO_TIMESTAMPING		0x0023
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 /* 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.29-gnu1/arch/sparc/include/asm/spinlock_32.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/spinlock_32.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/spinlock_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/spinlock_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -177,6 +177,8 @@ static inline int __read_trylock(raw_rwl
 #define __raw_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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/spinlock_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/spinlock_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/spinlock_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/spinlock_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -211,9 +211,11 @@ static int inline __write_trylock(raw_rw
 }
 
 #define __raw_read_lock(p)	__read_lock(p)
+#define __raw_read_lock_flags(p, f) __read_lock(p)
 #define __raw_read_trylock(p)	__read_trylock(p)
 #define __raw_read_unlock(p)	__read_unlock(p)
 #define __raw_write_lock(p)	__write_lock(p)
+#define __raw_write_lock_flags(p, f) __write_lock(p)
 #define __raw_write_unlock(p)	__write_unlock(p)
 #define __raw_write_trylock(p)	__write_trylock(p)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/system_32.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/system_32.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/system_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/system_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -126,7 +126,7 @@ extern void flushw_all(void);
 #define switch_to(prev, next, last) do {						\
 	SWITCH_ENTER(prev);								\
 	SWITCH_DO_LAZY_FPU(next);							\
-	cpu_set(smp_processor_id(), next->active_mm->cpu_vm_mask);			\
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(next->active_mm));		\
 	__asm__ __volatile__(								\
 	"sethi	%%hi(here - 0x8), %%o7\n\t"						\
 	"mov	%%g6, %%g3\n\t"								\
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/tlb_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/tlb_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/tlb_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/tlb_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -57,6 +57,8 @@ static inline struct mmu_gather *tlb_gat
 
 static inline void tlb_flush_mmu(struct mmu_gather *mp)
 {
+	if (!mp->fullmm)
+		flush_tlb_pending();
 	if (mp->need_flush) {
 		free_pages_and_swap_cache(mp->pages, mp->pages_nr);
 		mp->pages_nr = 0;
@@ -78,8 +80,6 @@ static inline void tlb_finish_mmu(struct
 
 	if (mp->fullmm)
 		mp->fullmm = 0;
-	else
-		flush_tlb_pending();
 
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/topology_64.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/topology_64.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/topology_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/topology_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,11 +28,6 @@ static inline cpumask_t node_to_cpumask(
 #define node_to_cpumask_ptr_next(v, node)	\
 			   v = &(numa_cpumask_lookup_table[node])
 
-static inline int node_to_first_cpu(int node)
-{
-	return cpumask_first(cpumask_of_node(node));
-}
-
 struct pci_bus;
 #ifdef CONFIG_PCI
 extern int pcibus_to_node(struct pci_bus *pbus);
@@ -43,13 +38,9 @@ static inline int pcibus_to_node(struct
 }
 #endif
 
-#define pcibus_to_cpumask(bus)	\
-	(pcibus_to_node(bus) == -1 ? \
-	 CPU_MASK_ALL : \
-	 node_to_cpumask(pcibus_to_node(bus)))
 #define cpumask_of_pcibus(bus)	\
 	(pcibus_to_node(bus) == -1 ? \
-	 CPU_MASK_ALL_PTR : \
+	 cpu_all_mask : \
 	 cpumask_of_node(pcibus_to_node(bus)))
 
 #define SD_NODE_INIT (struct sched_domain) {		\
@@ -89,7 +80,6 @@ static inline int pcibus_to_node(struct
 #define smt_capable()				(sparc64_multi_core)
 #endif /* CONFIG_SMP */
 
-#define cpu_coregroup_map(cpu)			(cpu_core_map[cpu])
 #define cpu_coregroup_mask(cpu)			(&cpu_core_map[cpu])
 
 #endif /* _ASM_SPARC64_TOPOLOGY_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/include/asm/unistd.h linux-libre-2.6.30-gnu1/arch/sparc/include/asm/unistd.h
--- linux-libre-2.6.29-gnu1/arch/sparc/include/asm/unistd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/include/asm/unistd.h	2009-06-09 23:05:27.000000000 -0400
@@ -392,8 +392,10 @@
 #define __NR_pipe2		321
 #define __NR_inotify_init1	322
 #define __NR_accept4		323
+#define __NR_preadv		324
+#define __NR_pwritev		325
 
-#define NR_SYSCALLS		324
+#define NR_SYSCALLS		326
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/Kconfig linux-libre-2.6.30-gnu1/arch/sparc/Kconfig
--- linux-libre-2.6.29-gnu1/arch/sparc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -124,6 +124,9 @@ config ARCH_NO_VIRT_TO_BUS
 config OF
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y if SPARC64
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/Kconfig.debug linux-libre-2.6.30-gnu1/arch/sparc/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/sparc/Kconfig.debug	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -22,14 +22,6 @@ config DEBUG_DCFLUSH
 config STACK_DEBUG
 	bool "Stack Overflow Detection Support"
 
-config DEBUG_PAGEALLOC
-	bool "Debug page memory allocations"
-	depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION
-	help
-	  Unmap pages from the kernel linear mapping after free_pages().
-	  This results in a large slowdown, but helps to find certain types
-	  of memory corruptions.
-
 config MCOUNT
 	bool
 	depends on SPARC64
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/ds.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/ds.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/ds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/ds.c	2009-06-09 23:05:27.000000000 -0400
@@ -653,7 +653,7 @@ static void __cpuinit dr_cpu_data(struct
 		if (cpu_list[i] == CPU_SENTINEL)
 			continue;
 
-		if (cpu_list[i] < NR_CPUS)
+		if (cpu_list[i] < nr_cpu_ids)
 			cpu_set(cpu_list[i], mask);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/head_32.S linux-libre-2.6.30-gnu1/arch/sparc/kernel/head_32.S
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/head_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/head_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -72,7 +72,7 @@ sun4e_notsup:
 	.align 4
 
 	/* The Sparc trap table, bootloader gives us control at _start. */
-	.section .text.head,"ax"
+	__HEAD
 	.globl	start, _stext, _start, __stext
 	.globl  trapbase
 _start:   /* danger danger */
@@ -735,7 +735,7 @@ go_to_highmem:
 		 nop
 
 /* The code above should be at beginning and we have to take care about
- * short jumps, as branching to .text.init section from .text is usually
+ * short jumps, as branching to .init.text section from .text is usually
  * impossible */
 		__INIT
 /* Acquire boot time privileged register values, this will help debugging.
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/head_64.S linux-libre-2.6.30-gnu1/arch/sparc/kernel/head_64.S
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/head_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/head_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -467,7 +467,7 @@ jump_to_sun4u_init:
 	jmpl    %g2 + %g0, %g0
 	 nop
 
-	.section	.text.init.refok
+	__REF
 sun4u_init:
 	BRANCH_IF_SUN4V(g1, sun4v_init)
 
@@ -686,7 +686,7 @@ tlb_fixup_done:
 	 * point.
 	 *
 	 * There used to be enormous complexity wrt. transferring
-	 * over from the firwmare's trap table to the Linux kernel's.
+	 * over from the firmware's trap table to the Linux kernel's.
 	 * For example, there was a chicken & egg problem wrt. building
 	 * the OBP page tables, yet needing to be on the Linux kernel
 	 * trap table (to translate PAGE_OFFSET addresses) in order to
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/irq_32.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_32.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/irq_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -439,7 +439,6 @@ static int request_fast_irq(unsigned int
 	flush_cache_all();
 
 	action->flags = irqflags;
-	cpus_clear(action->mask);
 	action->name = devname;
 	action->dev_id = NULL;
 	action->next = NULL;
@@ -574,7 +573,6 @@ int request_irq(unsigned int irq,
 
 	action->handler = handler;
 	action->flags = irqflags;
-	cpus_clear(action->mask);
 	action->name = devname;
 	action->next = NULL;
 	action->dev_id = dev_id;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/irq_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/irq_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %9s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
@@ -252,9 +252,10 @@ struct irq_handler_data {
 #ifdef CONFIG_SMP
 static int irq_choose_cpu(unsigned int virt_irq)
 {
-	cpumask_t mask = irq_desc[virt_irq].affinity;
+	cpumask_t mask;
 	int cpuid;
 
+	cpumask_copy(&mask, irq_desc[virt_irq].affinity);
 	if (cpus_equal(mask, CPU_MASK_ALL)) {
 		static int irq_rover;
 		static DEFINE_SPINLOCK(irq_rover_lock);
@@ -265,12 +266,12 @@ static int irq_choose_cpu(unsigned int v
 		spin_lock_irqsave(&irq_rover_lock, flags);
 
 		while (!cpu_online(irq_rover)) {
-			if (++irq_rover >= NR_CPUS)
+			if (++irq_rover >= nr_cpu_ids)
 				irq_rover = 0;
 		}
 		cpuid = irq_rover;
 		do {
-			if (++irq_rover >= NR_CPUS)
+			if (++irq_rover >= nr_cpu_ids)
 				irq_rover = 0;
 		} while (!cpu_online(irq_rover));
 
@@ -805,7 +806,7 @@ void fixup_irqs(void)
 		    !(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);
+					irq_desc[irq].affinity);
 		}
 		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/ldc.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/ldc.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/ldc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/ldc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1183,8 +1183,7 @@ out_free_txq:
 	free_queue(lp->tx_num_entries, lp->tx_base);
 
 out_free_mssbuf:
-	if (mssbuf)
-		kfree(mssbuf);
+	kfree(mssbuf);
 
 out_free_iommu:
 	ldc_iommu_release(lp);
@@ -1217,8 +1216,7 @@ void ldc_free(struct ldc_channel *lp)
 
 	hlist_del(&lp->list);
 
-	if (lp->mssbuf)
-		kfree(lp->mssbuf);
+	kfree(lp->mssbuf);
 
 	ldc_iommu_release(lp);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/led.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/led.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/led.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/led.c	2009-06-09 23:05:27.000000000 -0400
@@ -126,7 +126,6 @@ static int __init led_init(void)
 	led = proc_create("led", 0, NULL, &led_proc_fops);
 	if (!led)
 		return -ENOMEM;
-	led->owner = THIS_MODULE;
 
 	printk(KERN_INFO
 	       "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/mdesc.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/mdesc.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/mdesc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/mdesc.c	2009-06-09 23:05:27.000000000 -0400
@@ -567,7 +567,7 @@ static void __init report_platform_prope
 			max_cpu = NR_CPUS;
 		}
 		for (i = 0; i < max_cpu; i++)
-			cpu_set(i, cpu_possible_map);
+			set_cpu_possible(i, true);
 	}
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/nmi.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/nmi.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/nmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/nmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/kprobes.h>
 #include <linux/kernel_stat.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/kdebug.h>
 #include <linux/delay.h>
@@ -206,13 +207,33 @@ void nmi_adjust_hz(unsigned int new_hz)
 }
 EXPORT_SYMBOL_GPL(nmi_adjust_hz);
 
+static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p)
+{
+	on_each_cpu(stop_watchdog, NULL, 1);
+	return 0;
+}
+
+static struct notifier_block nmi_reboot_notifier = {
+	.notifier_call = nmi_shutdown,
+};
+
 int __init nmi_init(void)
 {
+	int err;
+
 	nmi_usable = 1;
 
 	on_each_cpu(start_watchdog, NULL, 1);
 
-	return check_nmi_watchdog();
+	err = check_nmi_watchdog();
+	if (!err) {
+		err = register_reboot_notifier(&nmi_reboot_notifier);
+		if (err) {
+			nmi_usable = 0;
+			on_each_cpu(stop_watchdog, NULL, 1);
+		}
+	}
+	return err;
 }
 
 static int __init setup_nmi_watchdog(char *str)
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/of_device_32.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/of_device_32.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/of_device_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/of_device_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -246,8 +246,25 @@ static unsigned long of_bus_pci_get_flag
 
 static int of_bus_sbus_match(struct device_node *np)
 {
-	return !strcmp(np->name, "sbus") ||
-		!strcmp(np->name, "sbi");
+	struct device_node *dp = np;
+
+	while (dp) {
+		if (!strcmp(dp->name, "sbus") ||
+		    !strcmp(dp->name, "sbi"))
+			return 1;
+
+		/* Have a look at use_1to1_mapping().  We're trying
+		 * to match SBUS if that's the top-level bus and we
+		 * don't have some intervening real bus that provides
+		 * ranges based translations.
+		 */
+		if (of_find_property(dp, "ranges", NULL) != NULL)
+			break;
+
+		dp = dp->parent;
+	}
+
+	return 0;
 }
 
 static void of_bus_sbus_count_cells(struct device_node *child,
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/of_device_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/of_device_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/of_device_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/of_device_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,8 +99,7 @@ static inline u64 of_read_addr(const u32
 	return r;
 }
 
-static void __init get_cells(struct device_node *dp,
-			     int *addrc, int *sizec)
+static void get_cells(struct device_node *dp, int *addrc, int *sizec)
 {
 	if (addrc)
 		*addrc = of_n_addr_cells(dp);
@@ -301,8 +300,25 @@ static unsigned long of_bus_pci_get_flag
 
 static int of_bus_sbus_match(struct device_node *np)
 {
-	return !strcmp(np->name, "sbus") ||
-		!strcmp(np->name, "sbi");
+	struct device_node *dp = np;
+
+	while (dp) {
+		if (!strcmp(dp->name, "sbus") ||
+		    !strcmp(dp->name, "sbi"))
+			return 1;
+
+		/* Have a look at use_1to1_mapping().  We're trying
+		 * to match SBUS if that's the top-level bus and we
+		 * don't have some intervening real bus that provides
+		 * ranges based translations.
+		 */
+		if (of_find_property(dp, "ranges", NULL) != NULL)
+			break;
+
+		dp = dp->parent;
+	}
+
+	return 0;
 }
 
 static void of_bus_sbus_count_cells(struct device_node *child,
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_fire.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_fire.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_fire.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_fire.c	2009-06-09 23:05:27.000000000 -0400
@@ -409,8 +409,8 @@ static void pci_fire_hw_init(struct pci_
 	upa_writeq(~(u64)0, pbm->pbm_regs + FIRE_PEC_IENAB);
 }
 
-static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm,
-				    struct of_device *op, u32 portid)
+static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
+				       struct of_device *op, u32 portid)
 {
 	const struct linux_prom64_registers *regs;
 	struct device_node *dp = op->node;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_psycho.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_psycho.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_psycho.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_psycho.c	2009-06-09 23:05:27.000000000 -0400
@@ -365,8 +365,8 @@ static void pbm_config_busmastering(stru
 	pci_config_write8(addr, 64);
 }
 
-static void __init psycho_scan_bus(struct pci_pbm_info *pbm,
-				   struct device *parent)
+static void __devinit psycho_scan_bus(struct pci_pbm_info *pbm,
+				      struct device *parent)
 {
 	pbm_config_busmastering(pbm);
 	pbm->is_66mhz_capable = 0;
@@ -482,8 +482,8 @@ static void psycho_pbm_strbuf_init(struc
 #define PSYCHO_MEMSPACE_B	0x180000000UL
 #define PSYCHO_MEMSPACE_SIZE	0x07fffffffUL
 
-static void __init psycho_pbm_init(struct pci_pbm_info *pbm,
-				   struct of_device *op, int is_pbm_a)
+static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm,
+				      struct of_device *op, int is_pbm_a)
 {
 	psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO);
 	psycho_pbm_strbuf_init(pbm, is_pbm_a);
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_sabre.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_sabre.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_sabre.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_sabre.c	2009-06-09 23:05:27.000000000 -0400
@@ -402,8 +402,8 @@ static void apb_init(struct pci_bus *sab
 	}
 }
 
-static void __init sabre_scan_bus(struct pci_pbm_info *pbm,
-				  struct device *parent)
+static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm,
+				     struct device *parent)
 {
 	static int once;
 
@@ -442,8 +442,8 @@ static void __init sabre_scan_bus(struct
 	sabre_register_error_handlers(pbm);
 }
 
-static void __init sabre_pbm_init(struct pci_pbm_info *pbm,
-				  struct of_device *op)
+static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
+				     struct of_device *op)
 {
 	psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE);
 	pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_sun4v.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_sun4v.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/pci_sun4v.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/pci_sun4v.c	2009-06-09 23:05:27.000000000 -0400
@@ -545,8 +545,8 @@ static const struct dma_ops sun4v_dma_op
 	.sync_sg_for_cpu		= dma_4v_sync_sg_for_cpu,
 };
 
-static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
-				      struct device *parent)
+static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
+					 struct device *parent)
 {
 	struct property *prop;
 	struct device_node *dp;
@@ -559,8 +559,8 @@ static void __init pci_sun4v_scan_bus(st
 	/* XXX register error interrupt handlers XXX */
 }
 
-static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm,
-						   struct iommu *iommu)
+static unsigned long __devinit probe_existing_entries(struct pci_pbm_info *pbm,
+						      struct iommu *iommu)
 {
 	struct iommu_arena *arena = &iommu->arena;
 	unsigned long i, cnt = 0;
@@ -587,7 +587,7 @@ static unsigned long __init probe_existi
 	return cnt;
 }
 
-static int __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
+static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
 {
 	static const u32 vdma_default[] = { 0x80000000, 0x80000000 };
 	struct iommu *iommu = pbm->iommu;
@@ -889,8 +889,8 @@ static void pci_sun4v_msi_init(struct pc
 }
 #endif /* !(CONFIG_PCI_MSI) */
 
-static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
-				     struct of_device *op, u32 devhandle)
+static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
+					struct of_device *op, u32 devhandle)
 {
 	struct device_node *dp = op->node;
 	int err;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/power.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/power.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/power.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/power.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@ static irqreturn_t power_handler(int irq
 	return IRQ_HANDLED;
 }
 
-static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
+static int __devinit has_button_interrupt(unsigned int irq, struct device_node *dp)
 {
 	if (irq == 0xffffffff)
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/process_32.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/process_32.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/process_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/process_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -455,7 +455,7 @@ asmlinkage int sparc_do_fork(unsigned lo
  */
 extern void ret_from_fork(void);
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/process_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/process_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/process_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/process_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -561,7 +561,7 @@ asmlinkage long sparc_do_fork(unsigned l
  * Parent -->  %o0 == childs  pid, %o1 == 0
  * Child  -->  %o0 == parents pid, %o1 == 1
  */
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/prom_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/prom_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/prom_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/prom_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -518,8 +518,8 @@ void __init of_fill_in_cpu_data(void)
 		}
 
 #ifdef CONFIG_SMP
-		cpu_set(cpuid, cpu_present_map);
-		cpu_set(cpuid, cpu_possible_map);
+		set_cpu_present(cpuid, true);
+		set_cpu_possible(cpuid, true);
 #endif
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/smp_32.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/smp_32.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/smp_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/smp_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,13 +70,12 @@ void __init smp_cpus_done(unsigned int m
 	extern void smp4m_smp_done(void);
 	extern void smp4d_smp_done(void);
 	unsigned long bogosum = 0;
-	int cpu, num;
+	int cpu, num = 0;
 
-	for (cpu = 0, num = 0; cpu < NR_CPUS; cpu++)
-		if (cpu_online(cpu)) {
-			num++;
-			bogosum += cpu_data(cpu).udelay_val;
-		}
+	for_each_online_cpu(cpu) {
+		num++;
+		bogosum += cpu_data(cpu).udelay_val;
+	}
 
 	printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 		num, bogosum/(500000/HZ),
@@ -144,7 +143,7 @@ void smp_flush_tlb_all(void)
 void smp_flush_cache_mm(struct mm_struct *mm)
 {
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask))
 			xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
@@ -155,12 +154,13 @@ void smp_flush_cache_mm(struct mm_struct
 void smp_flush_tlb_mm(struct mm_struct *mm)
 {
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask)) {
 			xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
 			if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
-				mm->cpu_vm_mask = cpumask_of_cpu(smp_processor_id());
+				cpumask_copy(mm_cpumask(mm),
+					     cpumask_of(smp_processor_id()));
 		}
 		local_flush_tlb_mm(mm);
 	}
@@ -172,7 +172,7 @@ void smp_flush_cache_range(struct vm_are
 	struct mm_struct *mm = vma->vm_mm;
 
 	if (mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask))
 			xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end);
@@ -186,7 +186,7 @@ void smp_flush_tlb_range(struct vm_area_
 	struct mm_struct *mm = vma->vm_mm;
 
 	if (mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask))
 			xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end);
@@ -199,7 +199,7 @@ void smp_flush_cache_page(struct vm_area
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask))
 			xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
@@ -212,7 +212,7 @@ void smp_flush_tlb_page(struct vm_area_s
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = mm->cpu_vm_mask;
+		cpumask_t cpu_mask = *mm_cpumask(mm);
 		cpu_clear(smp_processor_id(), cpu_mask);
 		if (!cpus_empty(cpu_mask))
 			xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
@@ -241,7 +241,7 @@ void smp_flush_page_to_ram(unsigned long
 
 void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
 {
-	cpumask_t cpu_mask = mm->cpu_vm_mask;
+	cpumask_t cpu_mask = *mm_cpumask(mm);
 	cpu_clear(smp_processor_id(), cpu_mask);
 	if (!cpus_empty(cpu_mask))
 		xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
@@ -332,8 +332,8 @@ void __init smp_setup_cpu_possible_map(v
 	instance = 0;
 	while (!cpu_find_by_instance(instance, NULL, &mid)) {
 		if (mid < NR_CPUS) {
-			cpu_set(mid, cpu_possible_map);
-			cpu_set(mid, cpu_present_map);
+			set_cpu_possible(mid, true);
+			set_cpu_present(mid, true);
 		}
 		instance++;
 	}
@@ -351,8 +351,8 @@ void __init smp_prepare_boot_cpu(void)
 		printk("boot cpu id != 0, this could work but is untested\n");
 
 	current_thread_info()->cpu = cpuid;
-	cpu_set(cpuid, cpu_online_map);
-	cpu_set(cpuid, cpu_possible_map);
+	set_cpu_online(cpuid, true);
+	set_cpu_possible(cpuid, true);
 }
 
 int __cpuinit __cpu_up(unsigned int cpu)
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/smp_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/smp_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/smp_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/smp_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -118,9 +118,9 @@ void __cpuinit smp_callin(void)
 	while (!cpu_isset(cpuid, smp_commenced_mask))
 		rmb();
 
-	ipi_call_lock();
+	ipi_call_lock_irq();
 	cpu_set(cpuid, cpu_online_map);
-	ipi_call_unlock();
+	ipi_call_unlock_irq();
 
 	/* idle thread is expected to have preempt disabled */
 	preempt_disable();
@@ -808,9 +808,9 @@ static void smp_start_sync_tick_client(i
 
 extern unsigned long xcall_call_function;
 
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
-	xcall_deliver((u64) &xcall_call_function, 0, 0, &mask);
+	xcall_deliver((u64) &xcall_call_function, 0, 0, mask);
 }
 
 extern unsigned long xcall_call_function_single;
@@ -850,7 +850,7 @@ static void tsb_sync(void *info)
 
 void smp_tsb_sync(struct mm_struct *mm)
 {
-	smp_call_function_mask(mm->cpu_vm_mask, tsb_sync, mm, 1);
+	smp_call_function_many(mm_cpumask(mm), tsb_sync, mm, 1);
 }
 
 extern unsigned long xcall_flush_tlb_mm;
@@ -1031,7 +1031,7 @@ void smp_fetch_global_regs(void)
  *    If the address space is non-shared (ie. mm->count == 1) we avoid
  *    cross calls when we want to flush the currently running process's
  *    tlb state.  This is done by clearing all cpu bits except the current
- *    processor's in current->active_mm->cpu_vm_mask and performing the
+ *    processor's in current->mm->cpu_vm_mask and performing the
  *    flush locally only.  This will force any subsequent cpus which run
  *    this task to flush the context from the local tlb if the process
  *    migrates to another cpu (again).
@@ -1055,13 +1055,13 @@ void smp_flush_tlb_mm(struct mm_struct *
 	int cpu = get_cpu();
 
 	if (atomic_read(&mm->mm_users) == 1) {
-		mm->cpu_vm_mask = cpumask_of_cpu(cpu);
+		cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
 		goto local_flush_and_out;
 	}
 
 	smp_cross_call_masked(&xcall_flush_tlb_mm,
 			      ctx, 0, 0,
-			      &mm->cpu_vm_mask);
+			      mm_cpumask(mm));
 
 local_flush_and_out:
 	__flush_tlb_mm(ctx, SECONDARY_CONTEXT);
@@ -1074,12 +1074,12 @@ void smp_flush_tlb_pending(struct mm_str
 	u32 ctx = CTX_HWBITS(mm->context);
 	int cpu = get_cpu();
 
-	if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1)
-		mm->cpu_vm_mask = cpumask_of_cpu(cpu);
+	if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
+		cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
 	else
 		smp_cross_call_masked(&xcall_flush_tlb_pending,
 				      ctx, nr, (unsigned long) vaddrs,
-				      &mm->cpu_vm_mask);
+				      mm_cpumask(mm));
 
 	__flush_tlb_pending(ctx, nr, vaddrs);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4d_irq.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4d_irq.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4d_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4d_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -326,7 +326,6 @@ int sun4d_request_irq(unsigned int irq,
 
 	action->handler = handler;
 	action->flags = irqflags;
-	cpus_clear(action->mask);
 	action->name = devname;
 	action->next = NULL;
 	action->dev_id = dev_id;
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4d_smp.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4d_smp.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4d_smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4d_smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,7 +150,7 @@ void __cpuinit smp4d_callin(void)
 	spin_lock_irqsave(&sun4d_imsk_lock, flags);
 	cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
 	spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
-	cpu_set(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, true);
 
 }
 
@@ -228,11 +228,10 @@ void __init smp4d_smp_done(void)
 	/* 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;
-		}
+	for_each_online_cpu(i) {
+		*prev = i;
+		prev = &cpu_data(i).next;
+	}
 	*prev = first;
 	local_flush_cache_all();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4m_smp.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4m_smp.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/sun4m_smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/sun4m_smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,7 @@ void __cpuinit smp4m_callin(void)
 
 	local_irq_enable();
 
-	cpu_set(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, true);
 }
 
 /*
@@ -186,11 +186,9 @@ void __init smp4m_smp_done(void)
 	/* 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;
-		}
+	for_each_online_cpu(i) {
+		*prev = i;
+		prev = &cpu_data(i).next;
 	}
 	*prev = first;
 	local_flush_cache_all();
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/sys_sparc32.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/sys_sparc32.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/sys_sparc32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/sys_sparc32.c	2009-06-09 23:05:27.000000000 -0400
@@ -206,21 +206,12 @@ asmlinkage long compat_sys_fstatat64(uns
 		struct compat_stat64 __user * statbuf, int flag)
 {
 	struct kstat stat;
-	int error = -EINVAL;
-
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-		goto out;
-
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
-	else
-		error = vfs_stat_fd(dfd, filename, &stat);
-
-	if (!error)
-		error = cp_compat_stat64(&stat, statbuf);
+	int error;
 
-out:
-	return error;
+	error = vfs_fstatat(dfd, filename, &stat, flag);
+	if (error)
+		return error;
+	return cp_compat_stat64(&stat, statbuf);
 }
 
 asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/systbls_32.S linux-libre-2.6.30-gnu1/arch/sparc/kernel/systbls_32.S
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/systbls_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/systbls_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -81,4 +81,4 @@ sys_call_table:
 /*305*/	.long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
 /*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
+/*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/systbls_64.S linux-libre-2.6.30-gnu1/arch/sparc/kernel/systbls_64.S
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/systbls_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/systbls_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,7 @@ sys_call_table32:
 /*150*/	.word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
 	.word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
 /*160*/	.word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall
-	.word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr
+	.word sys_quotactl, sys_set_tid_address, compat_sys_mount, compat_sys_ustat, sys32_setxattr
 /*170*/	.word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
 	.word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/	.word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
@@ -82,7 +82,7 @@ sys_call_table32:
 	.word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
 /*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
+/*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv, compat_sys_pwritev
 
 #endif /* CONFIG_COMPAT */
 
@@ -156,4 +156,4 @@ sys_call_table:
 	.word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
 /*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
+/*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/time_64.c linux-libre-2.6.30-gnu1/arch/sparc/kernel/time_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/time_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/time_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -729,7 +729,7 @@ void timer_interrupt(int irq, struct pt_
 
 	irq_enter();
 
-	kstat_this_cpu.irqs[0]++;
+	kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
 
 	if (unlikely(!evt->event_handler)) {
 		printk(KERN_WARNING
@@ -814,6 +814,11 @@ void udelay(unsigned long usecs)
 }
 EXPORT_SYMBOL(udelay);
 
+static cycle_t clocksource_tick_read(struct clocksource *cs)
+{
+	return tick_ops->get_tick();
+}
+
 void __init time_init(void)
 {
 	unsigned long freq = sparc64_init_timers();
@@ -827,7 +832,7 @@ void __init time_init(void)
 	clocksource_tick.mult =
 		clocksource_hz2mult(freq,
 				    clocksource_tick.shift);
-	clocksource_tick.read = tick_ops->get_tick;
+	clocksource_tick.read = clocksource_tick_read;
 
 	printk("clocksource: mult[%x] shift[%d]\n",
 	       clocksource_tick.mult, clocksource_tick.shift);
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/sparc/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/sparc/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@ SECTIONS
 	.text TEXTSTART :
 	{
 		_text = .;
-		*(.text.head)
+		HEAD_TEXT
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/lib/csum_copy_from_user.S linux-libre-2.6.30-gnu1/arch/sparc/lib/csum_copy_from_user.S
--- linux-libre-2.6.29-gnu1/arch/sparc/lib/csum_copy_from_user.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/lib/csum_copy_from_user.S	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
 
 #define EX_LD(x)		\
 98:	x;			\
-	.section .fixup;	\
+	.section .fixup, "ax";	\
 	.align 4;		\
 99:	retl;			\
 	 mov	-1, %o0;	\
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/lib/csum_copy_to_user.S linux-libre-2.6.30-gnu1/arch/sparc/lib/csum_copy_to_user.S
--- linux-libre-2.6.29-gnu1/arch/sparc/lib/csum_copy_to_user.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/lib/csum_copy_to_user.S	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
 
 #define EX_ST(x)		\
 98:	x;			\
-	.section .fixup;	\
+	.section .fixup,"ax";	\
 	.align 4;		\
 99:	retl;			\
 	 mov	-1, %o0;	\
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/mm/highmem.c linux-libre-2.6.30-gnu1/arch/sparc/mm/highmem.c
--- linux-libre-2.6.29-gnu1/arch/sparc/mm/highmem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/mm/highmem.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,7 @@ void *kmap_atomic(struct page *page, enu
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/mm/init_64.c linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.c
--- linux-libre-2.6.29-gnu1/arch/sparc/mm/init_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,8 +70,8 @@ extern struct tsb swapper_4m_tsb[KERNEL_
 
 #define MAX_BANKS	32
 
-static struct linux_prom64_registers pavail[MAX_BANKS] __initdata;
-static int pavail_ents __initdata;
+static struct linux_prom64_registers pavail[MAX_BANKS] __devinitdata;
+static int pavail_ents __devinitdata;
 
 static int cmp_p64(const void *a, const void *b)
 {
@@ -968,7 +968,7 @@ int of_node_to_nid(struct device_node *d
 	return nid;
 }
 
-static void add_node_ranges(void)
+static void __init add_node_ranges(void)
 {
 	int i;
 
@@ -1092,7 +1092,7 @@ static void __init numa_parse_mdesc_grou
 		if (strcmp(name, "cpu"))
 			continue;
 		id = mdesc_get_property(md, target, "id", NULL);
-		if (*id < NR_CPUS)
+		if (*id < nr_cpu_ids)
 			cpu_set(*id, *mask);
 	}
 }
@@ -1841,7 +1841,7 @@ void __init paging_init(void)
 	printk("Booting Linux...\n");
 }
 
-int __init page_in_phys_avail(unsigned long paddr)
+int __devinit page_in_phys_avail(unsigned long paddr)
 {
 	int i;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/sparc/mm/srmmu.c linux-libre-2.6.30-gnu1/arch/sparc/mm/srmmu.c
--- linux-libre-2.6.29-gnu1/arch/sparc/mm/srmmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/sparc/mm/srmmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -1425,7 +1425,7 @@ static void __init init_vac_layout(void)
 				min_line_size = vac_line_size;
 			//FIXME: cpus not contiguous!!
 			cpu++;
-			if (cpu >= NR_CPUS || !cpu_online(cpu))
+			if (cpu >= nr_cpu_ids || !cpu_online(cpu))
 				break;
 #else
 			break;
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/net_kern.c linux-libre-2.6.30-gnu1/arch/um/drivers/net_kern.c
--- linux-libre-2.6.29-gnu1/arch/um/drivers/net_kern.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/net_kern.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ static int uml_net_rx(struct net_device
 		drop_skb->dev = dev;
 		/* Read a packet into drop_skb and don't do anything with it. */
 		(*lp->read)(lp->fd, drop_skb, lp);
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return 0;
 	}
 
@@ -99,8 +99,8 @@ static int uml_net_rx(struct net_device
 		skb_trim(skb, pkt_len);
 		skb->protocol = (*lp->protocol)(skb);
 
-		lp->stats.rx_bytes += skb->len;
-		lp->stats.rx_packets++;
+		dev->stats.rx_bytes += skb->len;
+		dev->stats.rx_packets++;
 		netif_rx(skb);
 		return pkt_len;
 	}
@@ -224,8 +224,8 @@ static int uml_net_start_xmit(struct sk_
 	len = (*lp->write)(lp->fd, skb, lp);
 
 	if (len == skb->len) {
-		lp->stats.tx_packets++;
-		lp->stats.tx_bytes += skb->len;
+		dev->stats.tx_packets++;
+		dev->stats.tx_bytes += skb->len;
 		dev->trans_start = jiffies;
 		netif_start_queue(dev);
 
@@ -234,7 +234,7 @@ static int uml_net_start_xmit(struct sk_
 	}
 	else if (len == 0) {
 		netif_start_queue(dev);
-		lp->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 	}
 	else {
 		netif_start_queue(dev);
@@ -248,12 +248,6 @@ static int uml_net_start_xmit(struct sk_
 	return 0;
 }
 
-static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
-{
-	struct uml_net_private *lp = netdev_priv(dev);
-	return &lp->stats;
-}
-
 static void uml_net_set_multicast_list(struct net_device *dev)
 {
 	return;
@@ -377,6 +371,18 @@ static void net_device_release(struct de
 	free_netdev(netdev);
 }
 
+static const struct net_device_ops uml_netdev_ops = {
+	.ndo_open 		= uml_net_open,
+	.ndo_stop 		= uml_net_close,
+	.ndo_start_xmit 	= uml_net_start_xmit,
+	.ndo_set_multicast_list = uml_net_set_multicast_list,
+	.ndo_tx_timeout 	= uml_net_tx_timeout,
+	.ndo_set_mac_address	= uml_net_set_mac,
+	.ndo_change_mtu 	= uml_net_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*
  * Ensures that platform_driver_register is called only once by
  * eth_configure.  Will be set in an initcall.
@@ -473,14 +479,7 @@ static void eth_configure(int n, void *i
 
 	set_ether_mac(dev, device->mac);
 	dev->mtu = transport->user->mtu;
-	dev->open = uml_net_open;
-	dev->hard_start_xmit = uml_net_start_xmit;
-	dev->stop = uml_net_close;
-	dev->get_stats = uml_net_get_stats;
-	dev->set_multicast_list = uml_net_set_multicast_list;
-	dev->tx_timeout = uml_net_tx_timeout;
-	dev->set_mac_address = uml_net_set_mac;
-	dev->change_mtu = uml_net_change_mtu;
+	dev->netdev_ops = &uml_netdev_ops;
 	dev->ethtool_ops = &uml_net_ethtool_ops;
 	dev->watchdog_timeo = (HZ >> 1);
 	dev->irq = UM_ETH_IRQ;
@@ -758,7 +757,7 @@ static int uml_inetaddr_event(struct not
 	void (*proc)(unsigned char *, unsigned char *, void *);
 	unsigned char addr_buf[4], netmask_buf[4];
 
-	if (dev->open != uml_net_open)
+	if (dev->netdev_ops->ndo_open != uml_net_open)
 		return NOTIFY_DONE;
 
 	lp = netdev_priv(dev);
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/pcap_user.h linux-libre-2.6.30-gnu1/arch/um/drivers/pcap_user.h
--- linux-libre-2.6.29-gnu1/arch/um/drivers/pcap_user.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/pcap_user.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,13 +19,3 @@ extern const struct net_user_info pcap_u
 
 extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/port.h linux-libre-2.6.30-gnu1/arch/um/drivers/port.h
--- linux-libre-2.6.29-gnu1/arch/um/drivers/port.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/port.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,13 +18,3 @@ extern void port_remove_dev(void *d);
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/ssl.h linux-libre-2.6.30-gnu1/arch/um/drivers/ssl.h
--- linux-libre-2.6.29-gnu1/arch/um/drivers/ssl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/ssl.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,13 +11,3 @@ extern void ssl_receive_char(int line, c
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/stdio_console.h linux-libre-2.6.30-gnu1/arch/um/drivers/stdio_console.h
--- linux-libre-2.6.29-gnu1/arch/um/drivers/stdio_console.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/stdio_console.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,13 +9,3 @@
 extern void save_console_flags(void);
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/ubd_kern.c linux-libre-2.6.30-gnu1/arch/um/drivers/ubd_kern.c
--- linux-libre-2.6.29-gnu1/arch/um/drivers/ubd_kern.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/ubd_kern.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,12 +17,12 @@
  * James McMechan
  */
 
-#define MAJOR_NR UBD_MAJOR
 #define UBD_SHIFT 4
 
 #include "linux/kernel.h"
 #include "linux/module.h"
 #include "linux/blkdev.h"
+#include "linux/ata.h"
 #include "linux/hdreg.h"
 #include "linux/init.h"
 #include "linux/cdrom.h"
@@ -115,7 +115,7 @@ static struct block_device_operations ub
 };
 
 /* Protected by ubd_lock */
-static int fake_major = MAJOR_NR;
+static int fake_major = UBD_MAJOR;
 static struct gendisk *ubd_gendisk[MAX_DEV];
 static struct gendisk *fake_gendisk[MAX_DEV];
 
@@ -299,7 +299,7 @@ static int ubd_setup_common(char *str, i
 		}
 
 		mutex_lock(&ubd_lock);
-		if(fake_major != MAJOR_NR){
+		if (fake_major != UBD_MAJOR) {
 			*error_out = "Can't assign a fake major twice";
 			goto out1;
 		}
@@ -818,13 +818,13 @@ static int ubd_disk_register(int major,
 	disk->first_minor = unit << UBD_SHIFT;
 	disk->fops = &ubd_blops;
 	set_capacity(disk, size / 512);
-	if(major == MAJOR_NR)
+	if (major == UBD_MAJOR)
 		sprintf(disk->disk_name, "ubd%c", 'a' + unit);
 	else
 		sprintf(disk->disk_name, "ubd_fake%d", unit);
 
 	/* sysfs register (not for ide fake devices) */
-	if (major == MAJOR_NR) {
+	if (major == UBD_MAJOR) {
 		ubd_devs[unit].pdev.id   = unit;
 		ubd_devs[unit].pdev.name = DRIVER_NAME;
 		ubd_devs[unit].pdev.dev.release = ubd_device_release;
@@ -871,13 +871,13 @@ static int ubd_add(int n, char **error_o
 	ubd_dev->queue->queuedata = ubd_dev;
 
 	blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
-	err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
+	err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
 	if(err){
 		*error_out = "Failed to register device";
 		goto out_cleanup;
 	}
 
-	if(fake_major != MAJOR_NR)
+	if (fake_major != UBD_MAJOR)
 		ubd_disk_register(fake_major, ubd_dev->size, n,
 				  &fake_gendisk[n]);
 
@@ -1059,10 +1059,10 @@ static int __init ubd_init(void)
 	char *error;
 	int i, err;
 
-	if (register_blkdev(MAJOR_NR, "ubd"))
+	if (register_blkdev(UBD_MAJOR, "ubd"))
 		return -1;
 
-	if (fake_major != MAJOR_NR) {
+	if (fake_major != UBD_MAJOR) {
 		char name[sizeof("ubd_nnn\0")];
 
 		snprintf(name, sizeof(name), "ubd_%d", fake_major);
@@ -1309,16 +1309,15 @@ static int ubd_ioctl(struct block_device
 		     unsigned int cmd, unsigned long arg)
 {
 	struct ubd *ubd_dev = bdev->bd_disk->private_data;
-	struct hd_driveid ubd_id = {
-		.cyls		= 0,
-		.heads		= 128,
-		.sectors	= 32,
-	};
+	u16 ubd_id[ATA_ID_WORDS];
 
 	switch (cmd) {
 		struct cdrom_volctrl volume;
 	case HDIO_GET_IDENTITY:
-		ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
+		memset(&ubd_id, 0, ATA_ID_WORDS * 2);
+		ubd_id[ATA_ID_CYLS]	= ubd_dev->size / (128 * 32 * 512);
+		ubd_id[ATA_ID_HEADS]	= 128;
+		ubd_id[ATA_ID_SECTORS]	= 32;
 		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
 				 sizeof(ubd_id)))
 			return -EFAULT;
diff -druNp linux-libre-2.6.29-gnu1/arch/um/drivers/xterm.h linux-libre-2.6.30-gnu1/arch/um/drivers/xterm.h
--- linux-libre-2.6.29-gnu1/arch/um/drivers/xterm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/drivers/xterm.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,13 +10,3 @@ extern int xterm_fd(int socket, int *pid
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/um/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/irq_vectors.h linux-libre-2.6.30-gnu1/arch/um/include/asm/irq_vectors.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/irq_vectors.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/irq_vectors.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/um/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,13 +10,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/pda.h linux-libre-2.6.30-gnu1/arch/um/include/asm/pda.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/pda.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/pda.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,13 +19,3 @@ extern struct foo me;
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/pgalloc.h linux-libre-2.6.30-gnu1/arch/um/include/asm/pgalloc.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/pgalloc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/pgalloc.h	2009-06-09 23:05:27.000000000 -0400
@@ -60,13 +60,3 @@ static inline void pmd_free(struct mm_st
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/asm/pgtable-3level.h linux-libre-2.6.30-gnu1/arch/um/include/asm/pgtable-3level.h
--- linux-libre-2.6.29-gnu1/arch/um/include/asm/pgtable-3level.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/asm/pgtable-3level.h	2009-06-09 23:05:27.000000000 -0400
@@ -134,13 +134,3 @@ static inline pmd_t pfn_pmd(pfn_t page_n
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/frame_kern.h linux-libre-2.6.30-gnu1/arch/um/include/shared/frame_kern.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/frame_kern.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/frame_kern.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,13 +20,3 @@ extern int setup_signal_stack_si(unsigne
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/initrd.h linux-libre-2.6.30-gnu1/arch/um/include/shared/initrd.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/initrd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/initrd.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,13 +10,3 @@ extern int load_initrd(char *filename, v
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/irq_kern.h linux-libre-2.6.30-gnu1/arch/um/include/shared/irq_kern.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/irq_kern.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/irq_kern.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,13 +16,3 @@ extern int um_request_irq(unsigned int i
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/mem_kern.h linux-libre-2.6.30-gnu1/arch/um/include/shared/mem_kern.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/mem_kern.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/mem_kern.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,13 +18,3 @@ extern void register_remapper(struct rem
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/net_kern.h linux-libre-2.6.30-gnu1/arch/um/include/shared/net_kern.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/net_kern.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/net_kern.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,7 @@ struct uml_net_private {
 	spinlock_t lock;
 	struct net_device *dev;
 	struct timer_list tl;
-	struct net_device_stats stats;
+
 	struct work_struct work;
 	int fd;
 	unsigned char mac[ETH_ALEN];
diff -druNp linux-libre-2.6.29-gnu1/arch/um/include/shared/ubd_user.h linux-libre-2.6.30-gnu1/arch/um/include/shared/ubd_user.h
--- linux-libre-2.6.29-gnu1/arch/um/include/shared/ubd_user.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/include/shared/ubd_user.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,13 +14,3 @@ extern int kernel_fd;
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/Kconfig.rest linux-libre-2.6.30-gnu1/arch/um/Kconfig.rest
--- linux-libre-2.6.29-gnu1/arch/um/Kconfig.rest	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/Kconfig.rest	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,7 @@ source "drivers/leds/Kconfig"
 
 #This is just to shut up some Kconfig warnings, so no prompt.
 config INPUT
-	bool
+	tristate
 	default n
 
 source "arch/um/Kconfig.debug"
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/config.c.in linux-libre-2.6.30-gnu1/arch/um/kernel/config.c.in
--- linux-libre-2.6.29-gnu1/arch/um/kernel/config.c.in	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/config.c.in	2009-06-09 23:05:27.000000000 -0400
@@ -7,11 +7,15 @@
 #include <stdlib.h>
 #include "init.h"
 
-static __initdata char *config = "CONFIG";
+static __initdata const char *config[] = {
+"CONFIG"
+};
 
 static int __init print_config(char *line, int *add)
 {
-	printf("%s", config);
+	int i;
+	for (i = 0; i < sizeof(config)/sizeof(config[0]); i++)
+		printf("%s", config[i]);
 	exit(0);
 }
 
@@ -20,13 +24,3 @@ __uml_setup("--showconfig", print_config
 "    Prints the config file that this UML binary was generated from.\n\n"
 );
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/irq.c linux-libre-2.6.30-gnu1/arch/um/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/um/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/Makefile linux-libre-2.6.30-gnu1/arch/um/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/um/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ $(obj)/config.tmp: $(objtree)/.config FO
 	$(call if_changed,quote1)
 
 quiet_cmd_quote1 = QUOTE   $@
-      cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' \
+      cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n",/' \
 		   $< > $@
 
 $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
@@ -36,9 +36,9 @@ $(obj)/config.c: $(src)/config.c.in $(ob
 
 quiet_cmd_quote2 = QUOTE   $@
       cmd_quote2 = sed -e '/CONFIG/{'          \
-		  -e 's/"CONFIG"\;/""/'        \
+		  -e 's/"CONFIG"//'            \
 		  -e 'r $(obj)/config.tmp'     \
 		  -e 'a \'                     \
-		  -e '""\;'                    \
+		  -e '""'                      \
 		  -e '}'                       \
 		  $< > $@
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/process.c linux-libre-2.6.30-gnu1/arch/um/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/um/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -179,7 +179,7 @@ void fork_handler(void)
 	userspace(&current->thread.regs.regs);
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
 		unsigned long stack_top, struct task_struct * p,
 		struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/syscall.c linux-libre-2.6.30-gnu1/arch/um/kernel/syscall.c
--- linux-libre-2.6.29-gnu1/arch/um/kernel/syscall.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/syscall.c	2009-06-09 23:05:27.000000000 -0400
@@ -127,7 +127,8 @@ int kernel_execve(const char *filename,
 
 	fs = get_fs();
 	set_fs(KERNEL_DS);
-	ret = um_execve(filename, argv, envp);
+	ret = um_execve((char *)filename, (char __user *__user *)argv,
+			(char __user *__user *) envp);
 	set_fs(fs);
 
 	return ret;
diff -druNp linux-libre-2.6.29-gnu1/arch/um/kernel/time.c linux-libre-2.6.30-gnu1/arch/um/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/um/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,7 @@ static irqreturn_t um_timer(int irq, voi
 	return IRQ_HANDLED;
 }
 
-static cycle_t itimer_read(void)
+static cycle_t itimer_read(struct clocksource *cs)
 {
 	return os_nsecs() / 1000;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/um/os-Linux/start_up.c linux-libre-2.6.30-gnu1/arch/um/os-Linux/start_up.c
--- linux-libre-2.6.29-gnu1/arch/um/os-Linux/start_up.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/os-Linux/start_up.c	2009-06-09 23:05:27.000000000 -0400
@@ -244,7 +244,7 @@ static void __init check_sysemu(void)
 
 	if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
 		   (void *) PTRACE_O_TRACESYSGOOD) < 0))
-		fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
+		fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed");
 
 	while (1) {
 		count++;
@@ -252,12 +252,12 @@ static void __init check_sysemu(void)
 			goto fail;
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 		if (n < 0)
-			fatal_perror("check_ptrace : wait failed");
+			fatal_perror("check_sysemu: wait failed");
 
 		if (WIFSTOPPED(status) &&
 		    (WSTOPSIG(status) == (SIGTRAP|0x80))) {
 			if (!count) {
-				non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
+				non_fatal("check_sysemu: SYSEMU_SINGLESTEP "
 					  "doesn't singlestep");
 				goto fail;
 			}
@@ -271,7 +271,7 @@ static void __init check_sysemu(void)
 		else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
 			count++;
 		else {
-			non_fatal("check_ptrace : expected SIGTRAP or "
+			non_fatal("check_sysemu: expected SIGTRAP or "
 				  "(SIGTRAP | 0x80), got status = %d\n",
 				  status);
 			goto fail;
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-i386/asm/archparam.h linux-libre-2.6.30-gnu1/arch/um/sys-i386/asm/archparam.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-i386/asm/archparam.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-i386/asm/archparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-i386/shared/sysdep/checksum.h linux-libre-2.6.30-gnu1/arch/um/sys-i386/shared/sysdep/checksum.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-i386/shared/sysdep/checksum.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-i386/shared/sysdep/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -199,13 +199,3 @@ static __inline__ __wsum csum_and_copy_t
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-i386/sys_call_table.S linux-libre-2.6.30-gnu1/arch/um/sys-i386/sys_call_table.S
--- linux-libre-2.6.29-gnu1/arch/um/sys-i386/sys_call_table.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-i386/sys_call_table.S	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,17 @@
 
 #define old_mmap old_mmap_i386
 
+#define ptregs_fork sys_fork
+#define ptregs_execve sys_execve
+#define ptregs_iopl sys_iopl
+#define ptregs_vm86old sys_vm86old
+#define ptregs_sigreturn sys_sigreturn
+#define ptregs_clone sys_clone
+#define ptregs_vm86 sys_vm86
+#define ptregs_rt_sigreturn sys_rt_sigreturn
+#define ptregs_sigaltstack sys_sigaltstack
+#define ptregs_vfork sys_vfork
+
 .section .rodata,"a"
 
 #include "../../x86/kernel/syscall_table_32.S"
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/ptrace.h linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,13 +14,3 @@ struct sys_pt_regs {
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/sigcontext.h linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/sigcontext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/syscalls.h linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/syscalls.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ia64/sysdep/syscalls.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ia64/sysdep/syscalls.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/miscthings.c linux-libre-2.6.30-gnu1/arch/um/sys-ppc/miscthings.c
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/miscthings.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/miscthings.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,14 +40,3 @@ void shove_aux_table(unsigned long sp)
 }
 /* END stuff taken from arch/ppc/kernel/process.c */
 
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/ptrace.c linux-libre-2.6.30-gnu1/arch/um/sys-ppc/ptrace.c
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/ptrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/ptrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,13 +56,3 @@ int peek_user(struct task_struct *child,
 	return put_user(tmp, (unsigned long *) data);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/ptrace_user.c linux-libre-2.6.30-gnu1/arch/um/sys-ppc/ptrace_user.c
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/ptrace_user.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/ptrace_user.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,13 +27,3 @@ int ptrace_setregs(long pid, unsigned lo
     }
     return 0;
 }
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/ptrace.h linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -91,13 +91,3 @@ extern void shove_aux_table(unsigned lon
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/sigcontext.h linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/sigcontext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,13 +50,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/syscalls.h linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/syscalls.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/shared/sysdep/syscalls.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/shared/sysdep/syscalls.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,13 +41,3 @@ int old_mmap(unsigned long addr, unsigne
 
 #define LAST_ARCH_SYSCALL __NR_fadvise64
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-ppc/sigcontext.c linux-libre-2.6.30-gnu1/arch/um/sys-ppc/sigcontext.c
--- linux-libre-2.6.29-gnu1/arch/um/sys-ppc/sigcontext.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-ppc/sigcontext.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,13 +2,3 @@
 #include "asm/sigcontext.h"
 #include "sysdep/ptrace.h"
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/asm/archparam.h linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/asm/archparam.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/asm/archparam.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/asm/archparam.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/asm/module.h linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/asm/module.h
--- linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/asm/module.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/asm/module.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,13 +18,3 @@ struct mod_arch_specific
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/mem.c linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/mem.c
--- linux-libre-2.6.29-gnu1/arch/um/sys-x86_64/mem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/um/sys-x86_64/mem.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,12 +14,3 @@ unsigned long vm_data_default_flags = __
 unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
 unsigned long vm_force_exec32 = PROT_EXEC;
 
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/a20.c linux-libre-2.6.30-gnu1/arch/x86/boot/a20.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/a20.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/a20.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  *
  *   Copyright (C) 1991, 1992 Linus Torvalds
  *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
+ *   Copyright 2009 Intel Corporation
  *
  *   This file is part of the Linux kernel, and is made available under
  *   the terms of the GNU General Public License version 2.
@@ -15,16 +16,23 @@
 #include "boot.h"
 
 #define MAX_8042_LOOPS	100000
+#define MAX_8042_FF	32
 
 static int empty_8042(void)
 {
 	u8 status;
 	int loops = MAX_8042_LOOPS;
+	int ffs   = MAX_8042_FF;
 
 	while (loops--) {
 		io_delay();
 
 		status = inb(0x64);
+		if (status == 0xff) {
+			/* FF is a plausible, but very unlikely status */
+			if (!--ffs)
+				return -1; /* Assume no KBC present */
+		}
 		if (status & 1) {
 			/* Read and discard input data */
 			io_delay();
@@ -118,44 +126,37 @@ static void enable_a20_fast(void)
 
 int enable_a20(void)
 {
-#if defined(CONFIG_X86_ELAN)
-	/* Elan croaks if we try to touch the KBC */
-	enable_a20_fast();
-	while (!a20_test_long())
-		;
-	return 0;
-#elif defined(CONFIG_X86_VOYAGER)
-	/* On Voyager, a20_test() is unsafe? */
-	enable_a20_kbc();
-	return 0;
-#else
        int loops = A20_ENABLE_LOOPS;
-	while (loops--) {
-		/* First, check to see if A20 is already enabled
-		   (legacy free, etc.) */
-		if (a20_test_short())
-			return 0;
-
-		/* Next, try the BIOS (INT 0x15, AX=0x2401) */
-		enable_a20_bios();
-		if (a20_test_short())
-			return 0;
-
-		/* Try enabling A20 through the keyboard controller */
-		empty_8042();
-		if (a20_test_short())
-			return 0; /* BIOS worked, but with delayed reaction */
-
-		enable_a20_kbc();
-		if (a20_test_long())
-			return 0;
+       int kbc_err;
 
-		/* Finally, try enabling the "fast A20 gate" */
-		enable_a20_fast();
-		if (a20_test_long())
-			return 0;
-	}
+       while (loops--) {
+	       /* First, check to see if A20 is already enabled
+		  (legacy free, etc.) */
+	       if (a20_test_short())
+		       return 0;
+	       
+	       /* Next, try the BIOS (INT 0x15, AX=0x2401) */
+	       enable_a20_bios();
+	       if (a20_test_short())
+		       return 0;
+	       
+	       /* Try enabling A20 through the keyboard controller */
+	       kbc_err = empty_8042();
 
-	return -1;
-#endif
+	       if (a20_test_short())
+		       return 0; /* BIOS worked, but with delayed reaction */
+	
+	       if (!kbc_err) {
+		       enable_a20_kbc();
+		       if (a20_test_long())
+			       return 0;
+	       }
+	       
+	       /* Finally, try enabling the "fast A20 gate" */
+	       enable_a20_fast();
+	       if (a20_test_long())
+		       return 0;
+       }
+       
+       return -1;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/boot.h linux-libre-2.6.30-gnu1/arch/x86/boot/boot.h
--- linux-libre-2.6.29-gnu1/arch/x86/boot/boot.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/boot.h	2009-06-09 23:05:27.000000000 -0400
@@ -302,9 +302,6 @@ void probe_cards(int unsafe);
 /* video-vesa.c */
 void vesa_store_edid(void);
 
-/* voyager.c */
-int query_voyager(void);
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* BOOT_BOOT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/head_32.S linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/head_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/head_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/head_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -25,14 +25,12 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/boot.h>
 #include <asm/asm-offsets.h>
 
 .section ".text.head","ax",@progbits
-	.globl startup_32
-
-startup_32:
+ENTRY(startup_32)
 	cld
 	/* test KEEP_SEGMENTS flag to see if the bootloader is asking
 	 * us to not reload segments */
@@ -113,6 +111,8 @@ startup_32:
  */
 	leal relocated(%ebx), %eax
 	jmp *%eax
+ENDPROC(startup_32)
+
 .section ".text"
 relocated:
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/head_64.S linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/head_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/head_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/head_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -26,8 +26,8 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <asm/pgtable_types.h>
+#include <asm/page_types.h>
 #include <asm/boot.h>
 #include <asm/msr.h>
 #include <asm/processor-flags.h>
@@ -35,9 +35,7 @@
 
 .section ".text.head"
 	.code32
-	.globl startup_32
-
-startup_32:
+ENTRY(startup_32)
 	cld
 	/* test KEEP_SEGMENTS flag to see if the bootloader is asking
 	 * us to not reload segments */
@@ -176,6 +174,7 @@ startup_32:
 
 	/* Jump from 32bit compatibility mode into 64bit mode. */
 	lret
+ENDPROC(startup_32)
 
 no_longmode:
 	/* This isn't an x86-64 CPU so hang */
@@ -295,7 +294,6 @@ relocated:
 	call	decompress_kernel
 	popq	%rsi
 
-
 /*
  * Jump to the decompressed kernel.
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/Makefile linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,10 +4,11 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma 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_64) := -mcmodel=small
 KBUILD_CFLAGS += $(cflags-y)
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
@@ -47,18 +48,35 @@ ifeq ($(CONFIG_X86_32),y)
 ifdef CONFIG_RELOCATABLE
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
 	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE
+	$(call if_changed,lzma)
 else
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzma)
 endif
 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
 
 else
+
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzma)
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
 endif
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+suffix_$(CONFIG_KERNEL_GZIP)  = gz
+suffix_$(CONFIG_KERNEL_BZIP2) = bz2
+suffix_$(CONFIG_KERNEL_LZMA)  = lzma
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
 	$(call if_changed,ld)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/misc.c linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/misc.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/misc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/misc.c	2009-06-09 23:05:27.000000000 -0400
@@ -116,71 +116,13 @@
 /*
  * gzip declarations
  */
-
-#define OF(args)	args
 #define STATIC		static
 
 #undef memset
 #undef memcpy
 #define memzero(s, n)	memset((s), 0, (n))
 
-typedef unsigned char	uch;
-typedef unsigned short	ush;
-typedef unsigned long	ulg;
-
-/*
- * Window size must be at least 32k, and a power of two.
- * We don't actually have a window just a huge output buffer,
- * so we report a 2G window size, as that should always be
- * larger than our output buffer:
- */
-#define WSIZE		0x80000000
-
-/* Input buffer: */
-static unsigned char	*inbuf;
-
-/* Sliding window buffer (and final output buffer): */
-static unsigned char	*window;
-
-/* Valid bytes in inbuf: */
-static unsigned		insize;
 
-/* Index of next byte to be processed in inbuf: */
-static unsigned		inptr;
-
-/* Bytes in output buffer: */
-static unsigned		outcnt;
-
-/* gzip flag byte */
-#define ASCII_FLAG	0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION	0x02 /* bit 1 set: continuation of multi-part gz file */
-#define EXTRA_FIELD	0x04 /* bit 2 set: extra field present */
-#define ORIG_NAM	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) do { if (!(cond)) error(msg); } while (0)
-#  define Trace(x)	do { fprintf x; } while (0)
-#  define Tracev(x)	do { if (verbose) fprintf x ; } while (0)
-#  define Tracevv(x)	do { if (verbose > 1) fprintf x ; } while (0)
-#  define Tracec(c, x)	do { if (verbose && (c)) fprintf x ; } while (0)
-#  define Tracecv(c, x)	do { if (verbose > 1 && (c)) fprintf x ; } while (0)
-#else
-#  define Assert(cond, msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c, x)
-#  define Tracecv(c, x)
-#endif
-
-static int  fill_inbuf(void);
-static void flush_window(void);
 static void error(char *m);
 
 /*
@@ -189,13 +131,8 @@ static void error(char *m);
 static struct boot_params *real_mode;		/* Pointer to real-mode data */
 static int quiet;
 
-extern unsigned char input_data[];
-extern int input_len;
-
-static long bytes_out;
-
 static void *memset(void *s, int c, unsigned n);
-static void *memcpy(void *dest, const void *src, unsigned n);
+void *memcpy(void *dest, const void *src, unsigned n);
 
 static void __putstr(int, const char *);
 #define putstr(__x)  __putstr(0, __x)
@@ -213,7 +150,17 @@ static char *vidmem;
 static int vidport;
 static int lines, cols;
 
-#include "../../../../lib/inflate.c"
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
 
 static void scroll(void)
 {
@@ -282,7 +229,7 @@ static void *memset(void *s, int c, unsi
 	return s;
 }
 
-static void *memcpy(void *dest, const void *src, unsigned n)
+void *memcpy(void *dest, const void *src, unsigned n)
 {
 	int i;
 	const char *s = src;
@@ -293,38 +240,6 @@ static void *memcpy(void *dest, const vo
 	return dest;
 }
 
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-	error("ran out of input data");
-	return 0;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-	/* With my window equal to my output buffer
-	 * I only need to compute the crc here.
-	 */
-	unsigned long c = crc;         /* temporary variable */
-	unsigned n;
-	unsigned char *in, ch;
-
-	in = window;
-	for (n = 0; n < outcnt; n++) {
-		ch = *in++;
-		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-	}
-	crc = c;
-	bytes_out += (unsigned long)outcnt;
-	outcnt = 0;
-}
 
 static void error(char *x)
 {
@@ -407,12 +322,8 @@ asmlinkage void decompress_kernel(void *
 	lines = real_mode->screen_info.orig_video_lines;
 	cols = real_mode->screen_info.orig_video_cols;
 
-	window = output;		/* Output buffer (Normally at 1M) */
 	free_mem_ptr     = heap;	/* Heap */
 	free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
-	inbuf  = input_data;		/* Input buffer */
-	insize = input_len;
-	inptr  = 0;
 
 #ifdef CONFIG_X86_64
 	if ((unsigned long)output & (__KERNEL_ALIGN - 1))
@@ -430,10 +341,9 @@ asmlinkage void decompress_kernel(void *
 #endif
 #endif
 
-	makecrc();
 	if (!quiet)
 		putstr("\nDecompressing Linux... ");
-	gunzip();
+	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
 	parse_elf(output);
 	if (!quiet)
 		putstr("done.\nBooting the kernel.\n");
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/relocs.c linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/relocs.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/compressed/relocs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/compressed/relocs.c	2009-06-09 23:05:27.000000000 -0400
@@ -504,8 +504,11 @@ static void walk_relocs(void (*visit)(El
 			if (sym->st_shndx == SHN_ABS) {
 				continue;
 			}
-			if (r_type == R_386_PC32) {
-				/* PC relative relocations don't need to be adjusted */
+			if (r_type == R_386_NONE || r_type == 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) {
 				/* Visit relocations that need to be adjusted */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/copy.S linux-libre-2.6.30-gnu1/arch/x86/boot/copy.S
--- linux-libre-2.6.29-gnu1/arch/x86/boot/copy.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/copy.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,8 @@
  *
  * ----------------------------------------------------------------------- */
 
+#include <linux/linkage.h>
+
 /*
  * Memory copy routines
  */
@@ -15,9 +17,7 @@
 	.code16gcc
 	.text
 
-	.globl	memcpy
-	.type	memcpy, @function
-memcpy:
+GLOBAL(memcpy)
 	pushw	%si
 	pushw	%di
 	movw	%ax, %di
@@ -31,11 +31,9 @@ memcpy:
 	popw	%di
 	popw	%si
 	ret
-	.size	memcpy, .-memcpy
+ENDPROC(memcpy)
 
-	.globl	memset
-	.type	memset, @function
-memset:
+GLOBAL(memset)
 	pushw	%di
 	movw	%ax, %di
 	movzbl	%dl, %eax
@@ -48,52 +46,42 @@ memset:
 	rep; stosb
 	popw	%di
 	ret
-	.size	memset, .-memset
+ENDPROC(memset)
 
-	.globl	copy_from_fs
-	.type	copy_from_fs, @function
-copy_from_fs:
+GLOBAL(copy_from_fs)
 	pushw	%ds
 	pushw	%fs
 	popw	%ds
 	call	memcpy
 	popw	%ds
 	ret
-	.size	copy_from_fs, .-copy_from_fs
+ENDPROC(copy_from_fs)
 
-	.globl	copy_to_fs
-	.type	copy_to_fs, @function
-copy_to_fs:
+GLOBAL(copy_to_fs)
 	pushw	%es
 	pushw	%fs
 	popw	%es
 	call	memcpy
 	popw	%es
 	ret
-	.size	copy_to_fs, .-copy_to_fs
+ENDPROC(copy_to_fs)
 
 #if 0 /* Not currently used, but can be enabled as needed */
-
-	.globl	copy_from_gs
-	.type	copy_from_gs, @function
-copy_from_gs:
+GLOBAL(copy_from_gs)
 	pushw	%ds
 	pushw	%gs
 	popw	%ds
 	call	memcpy
 	popw	%ds
 	ret
-	.size	copy_from_gs, .-copy_from_gs
-	.globl	copy_to_gs
+ENDPROC(copy_from_gs)
 
-	.type	copy_to_gs, @function
-copy_to_gs:
+GLOBAL(copy_to_gs)
 	pushw	%es
 	pushw	%gs
 	popw	%es
 	call	memcpy
 	popw	%es
 	ret
-	.size	copy_to_gs, .-copy_to_gs
-
+ENDPROC(copy_to_gs)
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/header.S linux-libre-2.6.30-gnu1/arch/x86/boot/header.S
--- linux-libre-2.6.29-gnu1/arch/x86/boot/header.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/header.S	2009-06-09 23:05:27.000000000 -0400
@@ -19,17 +19,13 @@
 #include <linux/utsrelease.h>
 #include <asm/boot.h>
 #include <asm/e820.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/setup.h>
 #include "boot.h"
 #include "offsets.h"
 
-SETUPSECTS	= 4			/* default nr of setup-sectors */
 BOOTSEG		= 0x07C0		/* original address of boot-sector */
-SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
-SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
-					/* to be loaded */
-ROOT_DEV	= 0			/* ROOT_DEV is now written by "build" */
+SYSSEG		= 0x1000		/* historical load address >> 4 */
 
 #ifndef SVGA_MODE
 #define SVGA_MODE ASK_VGA
@@ -97,12 +93,12 @@ bugger_off_msg:
 	.section ".header", "a"
 	.globl	hdr
 hdr:
-setup_sects:	.byte SETUPSECTS
+setup_sects:	.byte 0			/* Filled in by build.c */
 root_flags:	.word ROOT_RDONLY
-syssize:	.long SYSSIZE
-ram_size:	.word RAMDISK
+syssize:	.long 0			/* Filled in by build.c */
+ram_size:	.word 0			/* Obsolete */
 vid_mode:	.word SVGA_MODE
-root_dev:	.word ROOT_DEV
+root_dev:	.word 0			/* Filled in by build.c */
 boot_flag:	.word 0xAA55
 
 	# offset 512, entry point
@@ -123,14 +119,15 @@ _start:
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
-start_sys_seg:	.word	SYSSEG
+start_sys_seg:	.word	SYSSEG		# obsolete and meaningless, but just
+					# in case something decided to "use" it
 		.word	kernel_version-512 # pointing to kernel version string
 					# above section of header is compatible
 					# with loadlin-1.5 (header v1.5). Don't
 					# change it.
 
-type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
-					#      Bootlin, SYSLX, bootsect...)
+type_of_loader:	.byte	0		# 0 means ancient bootloader, newer
+					# bootloaders know to change this.
 					# See Documentation/i386/boot.txt for
 					# assigned ids
 
@@ -142,11 +139,7 @@ CAN_USE_HEAP	= 0x80			# If set, the load
 					# space behind setup.S can be used for
 					# heap purposes.
 					# Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-		.byte	0
-#else
 		.byte	LOADED_HIGH
-#endif
 
 setup_move_size: .word  0x8000		# size to move, when setup is not
 					# loaded at 0x90000. We will move setup
@@ -157,11 +150,7 @@ setup_move_size: .word  0x8000		# size t
 
 code32_start:				# here loaders can put a different
 					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
 		.long	0x100000	# 0x100000 = default for big kernel
-#endif
 
 ramdisk_image:	.long	0		# address of loaded ramdisk image
 					# Here the loader puts the 32-bit
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/main.c linux-libre-2.6.30-gnu1/arch/x86/boot/main.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -149,11 +149,6 @@ void main(void)
 	/* Query MCA information */
 	query_mca();
 
-	/* Voyager */
-#ifdef CONFIG_X86_VOYAGER
-	query_voyager();
-#endif
-
 	/* Query Intel SpeedStep (IST) information */
 	query_ist();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/Makefile linux-libre-2.6.30-gnu1/arch/x86/boot/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/boot/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,33 +6,30 @@
 # for more details.
 #
 # Copyright (C) 1994 by Linus Torvalds
+# Changed by many, many contributors over the years.
 #
 
 # ROOT_DEV specifies the default root-device when making the image.
 # This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
 # the default of FLOPPY is used by 'build'.
 
-ROOT_DEV := CURRENT
+ROOT_DEV	:= CURRENT
 
 # If you want to preset the SVGA mode, uncomment the next line and
 # set SVGA_MODE to whatever number you want.
 # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
 # The number is the same as you would ordinarily press at bootup.
 
-SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-
-# If you want the RAM disk device, define this to be the size in blocks.
-
-#RAMDISK := -DRAMDISK=512
+SVGA_MODE	:= -DSVGA_MODE=NORMAL_VGA
 
-targets		:= vmlinux.bin setup.bin setup.elf zImage bzImage
+targets		:= vmlinux.bin setup.bin setup.elf bzImage
+targets		+= fdimage fdimage144 fdimage288 image.iso mtools.conf
 subdir-		:= compressed
 
 setup-y		+= a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
 setup-y		+= header.o main.o mca.o memory.o pm.o pmjump.o
 setup-y		+= printf.o string.o tty.o video.o video-mode.o version.o
 setup-$(CONFIG_X86_APM_BOOT) += apm.o
-setup-$(CONFIG_X86_VOYAGER) += voyager.o
 
 # The link order of the video-*.o modules can matter.  In particular,
 # video-vga.o *must* be listed first, followed by video-vesa.o.
@@ -60,6 +57,7 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
 # How to compile the 16-bit code.  Note we always compile for -march=i386,
 # that way we can complain to the user if the CPU is insufficient.
 KBUILD_CFLAGS	:= $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+		   -DDISABLE_BRANCH_PROFILING \
 		   -Wall -Wstrict-prototypes \
 		   -march=i386 -mregparm=3 \
 		   -include $(srctree)/$(src)/code16gcc.h \
@@ -69,20 +67,16 @@ KBUILD_CFLAGS	:= $(LINUXINCLUDE) -g -Os
 			$(call cc-option, -fno-unit-at-a-time)) \
 		   $(call cc-option, -fno-stack-protector) \
 		   $(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS +=   $(call cc-option,-m32)
+KBUILD_CFLAGS	+= $(call cc-option, -m32)
 KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
 
-$(obj)/zImage:  asflags-y := $(SVGA_MODE) $(RAMDISK)
-$(obj)/bzImage: ccflags-y := -D__BIG_KERNEL__
-$(obj)/bzImage: asflags-y := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
-$(obj)/bzImage: BUILDFLAGS   := -b
+$(obj)/bzImage: asflags-y  := $(SVGA_MODE)
 
 quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
-	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
+cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \
+	$(ROOT_DEV) > $@
 
-$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
-			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
 
@@ -117,9 +111,11 @@ $(obj)/setup.bin: $(obj)/setup.elf FORCE
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
+# Set this if you want to pass append arguments to the
+# bzdisk/fdimage/isoimage kernel
 FDARGS =
-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
+# Set this if you want an initrd included with the
+# bzdisk/fdimage/isoimage kernel
 FDINITRD =
 
 image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
@@ -128,7 +124,7 @@ $(obj)/mtools.conf: $(src)/mtools.conf.i
 	sed -e 's|@OBJ@|$(obj)|g' < $< > $@
 
 # This requires write access to /dev/fd0
-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
+bzdisk: $(obj)/bzImage $(obj)/mtools.conf
 	MTOOLSRC=$(obj)/mtools.conf mformat a:			; sync
 	syslinux /dev/fd0					; sync
 	echo '$(image_cmdline)' | \
@@ -136,10 +132,10 @@ zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
 	if [ -f '$(FDINITRD)' ] ; then \
 		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
 	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux	; sync
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage a:linux	; sync
 
 # These require being root or having syslinux 2.02 or higher installed
-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
+fdimage fdimage144: $(obj)/bzImage $(obj)/mtools.conf
 	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
 	MTOOLSRC=$(obj)/mtools.conf mformat v:			; sync
 	syslinux $(obj)/fdimage					; sync
@@ -148,9 +144,9 @@ fdimage fdimage144: $(BOOTIMAGE) $(obj)/
 	if [ -f '$(FDINITRD)' ] ; then \
 		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
 	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux	; sync
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage v:linux	; sync
 
-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
+fdimage288: $(obj)/bzImage $(obj)/mtools.conf
 	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
 	MTOOLSRC=$(obj)/mtools.conf mformat w:			; sync
 	syslinux $(obj)/fdimage					; sync
@@ -159,9 +155,9 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.c
 	if [ -f '$(FDINITRD)' ] ; then \
 		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
 	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux	; sync
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage w:linux	; sync
 
-isoimage: $(BOOTIMAGE)
+isoimage: $(obj)/bzImage
 	-rm -rf $(obj)/isoimage
 	mkdir $(obj)/isoimage
 	for i in lib lib64 share end ; do \
@@ -171,7 +167,7 @@ isoimage: $(BOOTIMAGE)
 		fi ; \
 		if [ $$i = end ] ; then exit 1 ; fi ; \
 	done
-	cp $(BOOTIMAGE) $(obj)/isoimage/linux
+	cp $(obj)/bzImage $(obj)/isoimage/linux
 	echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
 	if [ -f '$(FDINITRD)' ] ; then \
 		cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
@@ -182,12 +178,13 @@ isoimage: $(BOOTIMAGE)
 	isohybrid $(obj)/image.iso 2>/dev/null || true
 	rm -rf $(obj)/isoimage
 
-zlilo: $(BOOTIMAGE)
+bzlilo: $(obj)/bzImage
 	if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
 	if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
-	cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
+	cat $(obj)/bzImage > $(INSTALL_PATH)/vmlinuz
 	cp System.map $(INSTALL_PATH)/
 	if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
 install:
-	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/bzImage \
+		System.map "$(INSTALL_PATH)"
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/memory.c linux-libre-2.6.30-gnu1/arch/x86/boot/memory.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/memory.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/memory.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
  *
  *   Copyright (C) 1991, 1992 Linus Torvalds
  *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author H. Peter Anvin
  *
  *   This file is part of the Linux kernel, and is made available under
  *   the terms of the GNU General Public License version 2.
@@ -20,20 +21,37 @@ static int detect_memory_e820(void)
 {
 	int count = 0;
 	u32 next = 0;
-	u32 size, id;
+	u32 size, id, edi;
 	u8 err;
 	struct e820entry *desc = boot_params.e820_map;
+	static struct e820entry buf; /* static so it is zeroed */
+
+	/*
+	 * Note: at least one BIOS is known which assumes that the
+	 * buffer pointed to by one e820 call is the same one as
+	 * the previous call, and only changes modified fields.  Therefore,
+	 * we use a temporary buffer and copy the results entry by entry.
+	 *
+	 * This routine deliberately does not try to account for
+	 * ACPI 3+ extended attributes.  This is because there are
+	 * BIOSes in the field which report zero for the valid bit for
+	 * all ranges, and we don't currently make any use of the
+	 * other attribute bits.  Revisit this if we see the extended
+	 * attribute bits deployed in a meaningful way in the future.
+	 */
 
 	do {
-		size = sizeof(struct e820entry);
+		size = sizeof buf;
 
-		/* Important: %edx is clobbered by some BIOSes,
-		   so it must be either used for the error output
-		   or explicitly marked clobbered. */
-		asm("int $0x15; setc %0"
+		/* Important: %edx and %esi are clobbered by some BIOSes,
+		   so they must be either used for the error output
+		   or explicitly marked clobbered.  Given that, assume there
+		   is something out there clobbering %ebp and %edi, too. */
+		asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
 		    : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
-		      "=m" (*desc)
-		    : "D" (desc), "d" (SMAP), "a" (0xe820));
+		      "=D" (edi), "+m" (buf)
+		    : "D" (&buf), "d" (SMAP), "a" (0xe820)
+		    : "esi");
 
 		/* BIOSes which terminate the chain with CF = 1 as opposed
 		   to %ebx = 0 don't always report the SMAP signature on
@@ -51,8 +69,8 @@ static int detect_memory_e820(void)
 			break;
 		}
 
+		*desc++ = buf;
 		count++;
-		desc++;
 	} while (next && count < ARRAY_SIZE(boot_params.e820_map));
 
 	return boot_params.e820_entries = count;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/pm.c linux-libre-2.6.30-gnu1/arch/x86/boot/pm.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,47 +33,6 @@ static void realmode_switch_hook(void)
 }
 
 /*
- * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
- * A bzImage kernel is loaded and runs at 0x100000.
- */
-static void move_kernel_around(void)
-{
-	/* Note: rely on the compile-time option here rather than
-	   the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
-	   sets the loadflags to zero. */
-#ifndef __BIG_KERNEL__
-	u16 dst_seg, src_seg;
-	u32 syssize;
-
-	dst_seg =  0x1000 >> 4;
-	src_seg = 0x10000 >> 4;
-	syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraphs */
-
-	while (syssize) {
-		int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
-		int dwords = paras << 2;
-
-		asm volatile("pushw %%es ; "
-			     "pushw %%ds ; "
-			     "movw %1,%%es ; "
-			     "movw %2,%%ds ; "
-			     "xorw %%di,%%di ; "
-			     "xorw %%si,%%si ; "
-			     "rep;movsl ; "
-			     "popw %%ds ; "
-			     "popw %%es"
-			     : "+c" (dwords)
-			     : "r" (dst_seg), "r" (src_seg)
-			     : "esi", "edi");
-
-		syssize -= paras;
-		dst_seg += paras;
-		src_seg += paras;
-	}
-#endif
-}
-
-/*
  * Disable all interrupts at the legacy PIC.
  */
 static void mask_all_interrupts(void)
@@ -147,9 +106,6 @@ void go_to_protected_mode(void)
 	/* Hook before leaving real mode, also disables interrupts */
 	realmode_switch_hook();
 
-	/* Move the kernel/setup to their final resting places */
-	move_kernel_around();
-
 	/* Enable the A20 gate */
 	if (enable_a20()) {
 		puts("A20 gate not responding, unable to boot...\n");
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/pmjump.S linux-libre-2.6.30-gnu1/arch/x86/boot/pmjump.S
--- linux-libre-2.6.29-gnu1/arch/x86/boot/pmjump.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/pmjump.S	2009-06-09 23:05:27.000000000 -0400
@@ -15,18 +15,15 @@
 #include <asm/boot.h>
 #include <asm/processor-flags.h>
 #include <asm/segment.h>
+#include <linux/linkage.h>
 
 	.text
-
-	.globl	protected_mode_jump
-	.type	protected_mode_jump, @function
-
 	.code16
 
 /*
  * void protected_mode_jump(u32 entrypoint, u32 bootparams);
  */
-protected_mode_jump:
+GLOBAL(protected_mode_jump)
 	movl	%edx, %esi		# Pointer to boot_params table
 
 	xorl	%ebx, %ebx
@@ -47,12 +44,11 @@ protected_mode_jump:
 	.byte	0x66, 0xea		# ljmpl opcode
 2:	.long	in_pm32			# offset
 	.word	__BOOT_CS		# segment
-
-	.size	protected_mode_jump, .-protected_mode_jump
+ENDPROC(protected_mode_jump)
 
 	.code32
-	.type	in_pm32, @function
-in_pm32:
+	.section ".text32","ax"
+GLOBAL(in_pm32)
 	# Set up data segments for flat 32-bit mode
 	movl	%ecx, %ds
 	movl	%ecx, %es
@@ -78,5 +74,4 @@ in_pm32:
 	lldt	%cx
 
 	jmpl	*%eax			# Jump to the 32-bit entrypoint
-
-	.size	in_pm32, .-in_pm32
+ENDPROC(in_pm32)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/setup.ld linux-libre-2.6.30-gnu1/arch/x86/boot/setup.ld
--- linux-libre-2.6.29-gnu1/arch/x86/boot/setup.ld	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/setup.ld	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,8 @@ SECTIONS
 	.header		: { *(.header) }
 	.inittext	: { *(.inittext) }
 	.initdata	: { *(.initdata) }
-	.text		: { *(.text*) }
+	.text		: { *(.text) }
+	.text32		: { *(.text32) }
 
 	. = ALIGN(16);
 	.rodata		: { *(.rodata*) }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/tools/build.c linux-libre-2.6.30-gnu1/arch/x86/boot/tools/build.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/tools/build.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/tools/build.c	2009-06-09 23:05:27.000000000 -0400
@@ -130,7 +130,7 @@ static void die(const char * str, ...)
 
 static void usage(void)
 {
-	die("Usage: build [-b] setup system [rootdev] [> image]");
+	die("Usage: build setup system [rootdev] [> image]");
 }
 
 int main(int argc, char ** argv)
@@ -145,11 +145,6 @@ int main(int argc, char ** argv)
 	void *kernel;
 	u32 crc = 0xffffffffUL;
 
-	if (argc > 2 && !strcmp(argv[1], "-b"))
-	  {
-	    is_big_kernel = 1;
-	    argc--, argv++;
-	  }
 	if ((argc < 3) || (argc > 4))
 		usage();
 	if (argc > 3) {
@@ -216,8 +211,6 @@ int main(int argc, char ** argv)
 		die("Unable to mmap '%s': %m", argv[2]);
 	/* Number of 16-byte paragraphs, including space for a 4-byte CRC */
 	sys_size = (sz + 15 + 4) / 16;
-	if (!is_big_kernel && sys_size > DEF_SYSSIZE)
-		die("System is too big. Try using bzImage or modules.");
 
 	/* Patch the setup code with the appropriate size parameters */
 	buf[0x1f1] = setup_sectors-1;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/video-vga.c linux-libre-2.6.30-gnu1/arch/x86/boot/video-vga.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/video-vga.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/video-vga.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,10 +129,10 @@ u16 vga_crtc(void)
 	return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
 }
 
-static void vga_set_480_scanlines(int end)
+static void vga_set_480_scanlines(void)
 {
-	u16 crtc;
-	u8  csel;
+	u16 crtc;		/* CRTC base address */
+	u8  csel;		/* CRTC miscellaneous output register */
 
 	crtc = vga_crtc();
 
@@ -140,30 +140,47 @@ static void vga_set_480_scanlines(int en
 	out_idx(0x0b, crtc, 0x06); /* Vertical total */
 	out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
 	out_idx(0xea, crtc, 0x10); /* Vertical sync start */
-	out_idx(end, crtc, 0x12); /* Vertical display end */
+	out_idx(0xdf, crtc, 0x12); /* Vertical display end */
 	out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
 	out_idx(0x04, crtc, 0x16); /* Vertical blank end */
 	csel = inb(0x3cc);
 	csel &= 0x0d;
 	csel |= 0xe2;
-	outb(csel, 0x3cc);
+	outb(csel, 0x3c2);
+}
+
+static void vga_set_vertical_end(int lines)
+{
+	u16 crtc;		/* CRTC base address */
+	u8  ovfw;		/* CRTC overflow register */
+	int end = lines-1;
+
+	crtc = vga_crtc();
+
+	ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
+
+	out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
+	out_idx(end,  crtc, 0x12); /* Vertical display end */
 }
 
 static void vga_set_80x30(void)
 {
-	vga_set_480_scanlines(0xdf);
+	vga_set_480_scanlines();
+	vga_set_vertical_end(30*16);
 }
 
 static void vga_set_80x34(void)
 {
+	vga_set_480_scanlines();
 	vga_set_14font();
-	vga_set_480_scanlines(0xdb);
+	vga_set_vertical_end(34*14);
 }
 
 static void vga_set_80x60(void)
 {
+	vga_set_480_scanlines();
 	vga_set_8font();
-	vga_set_480_scanlines(0xdf);
+	vga_set_vertical_end(60*8);
 }
 
 static int vga_set_mode(struct mode_info *mode)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/boot/voyager.c linux-libre-2.6.30-gnu1/arch/x86/boot/voyager.c
--- linux-libre-2.6.29-gnu1/arch/x86/boot/voyager.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/boot/voyager.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
- *
- *   Copyright (C) 1991, 1992 Linus Torvalds
- *   Copyright 2007 rPath, Inc. - All Rights Reserved
- *
- *   This file is part of the Linux kernel, and is made available under
- *   the terms of the GNU General Public License version 2.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * Get the Voyager config information
- */
-
-#include "boot.h"
-
-int query_voyager(void)
-{
-	u8 err;
-	u16 es, di;
-	/* Abuse the apm_bios_info area for this */
-	u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
-
-	data_ptr[0] = 0xff;	/* Flag on config not found(?) */
-
-	asm("pushw %%es ; "
-	    "int $0x15 ; "
-	    "setc %0 ; "
-	    "movw %%es, %1 ; "
-	    "popw %%es"
-	    : "=q" (err), "=r" (es), "=D" (di)
-	    : "a" (0xffc0));
-
-	if (err)
-		return -1;	/* Not Voyager */
-
-	set_fs(es);
-	copy_from_fs(data_ptr, di, 7);	/* Table is 7 bytes apparently */
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/configs/i386_defconfig linux-libre-2.6.30-gnu1/arch/x86/configs/i386_defconfig
--- linux-libre-2.6.29-gnu1/arch/x86/configs/i386_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/configs/i386_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc5
-# Wed Sep  3 17:23:09 2008
+# Linux kernel version: 2.6.29-rc4
+# Tue Feb 24 15:50:58 2009
 #
 # CONFIG_64BIT is not set
 CONFIG_X86_32=y
 # CONFIG_X86_64 is not set
 CONFIG_X86=y
 CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
-# CONFIG_GENERIC_LOCKBREAK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_CLOCKSOURCE_WATCHDOG=y
@@ -24,16 +23,14 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_HWEIGHT=y
-# CONFIG_GENERIC_GPIO is not set
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 # CONFIG_GENERIC_TIME_VSYSCALL is not set
 CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 # CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
@@ -42,12 +39,12 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_ZONE_DMA32 is not set
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 # CONFIG_AUDIT_ARCH is not set
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
 CONFIG_X86_SMP=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_X86_32_SMP=y
 CONFIG_X86_HT=y
 CONFIG_X86_BIOS_REBOOT=y
@@ -76,30 +73,44 @@ CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_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=18
-CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
-CONFIG_CGROUP_NS=y
-# CONFIG_CGROUP_DEVICE is not set
-CONFIG_CPUSETS=y
 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 # CONFIG_USER_SCHED is not set
 CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 # CONFIG_CGROUP_MEM_RES_CTLR is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
-CONFIG_PROC_PID_CPUSET=y
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+CONFIG_NET_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -124,12 +135,15 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
 CONFIG_MARKERS=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
@@ -139,15 +153,10 @@ CONFIG_KRETPROBES=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=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
@@ -155,12 +164,10 @@ 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_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 CONFIG_BLK_DEV_IO_TRACE=y
-# CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -176,7 +183,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
 
 #
 # Processor type and features
@@ -186,15 +193,14 @@ CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_SMP=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
-CONFIG_X86_PC=y
 # CONFIG_X86_ELAN is not set
-# CONFIG_X86_VOYAGER is not set
 # CONFIG_X86_GENERICARCH is not set
 # CONFIG_X86_VSMP is not set
 # CONFIG_X86_RDC321X is not set
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 # CONFIG_PARAVIRT_GUEST is not set
 # CONFIG_MEMTEST is not set
 # CONFIG_M386 is not set
@@ -238,10 +244,19 @@ CONFIG_X86_TSC=y
 CONFIG_X86_CMOV=y
 CONFIG_X86_MINIMUM_CPU_FAMILY=4
 CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_CYRIX_32=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR_32=y
+CONFIG_CPU_SUP_TRANSMETA_32=y
+CONFIG_CPU_SUP_UMC_32=y
+CONFIG_X86_DS=y
+CONFIG_X86_PTRACE_BTS=y
 CONFIG_HPET_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
 CONFIG_DMI=y
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_IOMMU_API is not set
 CONFIG_NR_CPUS=64
 CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
@@ -250,12 +265,17 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
-# CONFIG_X86_MCE is not set
+CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_NONFATAL=y
+CONFIG_X86_MCE_P4THERMAL=y
 CONFIG_VM86=y
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
 CONFIG_X86_REBOOTFIXUPS=y
 CONFIG_MICROCODE=y
+CONFIG_MICROCODE_INTEL=y
+CONFIG_MICROCODE_AMD=y
 CONFIG_MICROCODE_OLD_INTERFACE=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
@@ -264,6 +284,7 @@ CONFIG_HIGHMEM4G=y
 # CONFIG_HIGHMEM64G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_HIGHMEM=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
@@ -274,14 +295,17 @@ CONFIG_FLATMEM_MANUAL=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPARSEMEM_STATIC=y
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+# 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_HIGHPTE=y
+CONFIG_X86_CHECK_BIOS_CORRUPTION=y
+CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
+CONFIG_X86_RESERVE_LOW_64K=y
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
 # CONFIG_MTRR_SANITIZER is not set
@@ -302,10 +326,11 @@ CONFIG_PHYSICAL_START=0x1000000
 CONFIG_PHYSICAL_ALIGN=0x200000
 CONFIG_HOTPLUG_CPU=y
 # CONFIG_COMPAT_VDSO is not set
+# CONFIG_CMDLINE_BOOL is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 
 #
-# Power management options
+# Power management and ACPI options
 #
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
@@ -331,19 +356,13 @@ CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_DOCK=y
-# CONFIG_ACPI_BAY is not set
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=y
-# CONFIG_ACPI_WMI is not set
-# CONFIG_ACPI_ASUS is not set
-# CONFIG_ACPI_TOSHIBA is not set
 # CONFIG_ACPI_CUSTOM_DSDT is not set
 CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
 # CONFIG_ACPI_PCI_SLOT is not set
-CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_X86_PM_TIMER=y
 CONFIG_ACPI_CONTAINER=y
@@ -388,7 +407,6 @@ CONFIG_X86_ACPI_CPUFREQ=y
 #
 # shared options
 #
-# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
 # CONFIG_X86_SPEEDSTEP_LIB is not set
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
@@ -415,6 +433,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
 CONFIG_HT_IRQ=y
 CONFIG_ISA_DMA_API=y
 # CONFIG_ISA is not set
@@ -452,13 +471,17 @@ CONFIG_HOTPLUG_PCI=y
 # Executable file formats / Emulations
 #
 CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=y
+CONFIG_HAVE_ATOMIC_IOMAP=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -519,7 +542,6 @@ CONFIG_DEFAULT_CUBIC=y
 # CONFIG_DEFAULT_RENO is not set
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -557,19 +579,21 @@ CONFIG_NF_CONNTRACK_IRC=y
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CT_NETLINK=y
 CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFLOG=y
 CONFIG_NETFILTER_XT_TARGET_SECMARK=y
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=y
 CONFIG_NF_CONNTRACK_IPV4=y
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=y
@@ -595,8 +619,8 @@ CONFIG_IP_NF_MANGLE=y
 CONFIG_NF_CONNTRACK_IPV6=y
 CONFIG_IP6_NF_IPTABLES=y
 CONFIG_IP6_NF_MATCH_IPV6HEADER=y
-CONFIG_IP6_NF_FILTER=y
 CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 # CONFIG_IP_DCCP is not set
@@ -604,6 +628,7 @@ CONFIG_IP6_NF_MANGLE=y
 # 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_LLC=y
@@ -623,6 +648,7 @@ CONFIG_NET_SCHED=y
 # 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
@@ -630,6 +656,7 @@ CONFIG_NET_SCHED=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
 # CONFIG_NET_SCH_INGRESS is not set
 
 #
@@ -644,6 +671,7 @@ CONFIG_NET_CLS=y
 # CONFIG_NET_CLS_RSVP is not set
 # CONFIG_NET_CLS_RSVP6 is not set
 # CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_CLS_CGROUP is not set
 CONFIG_NET_EMATCH=y
 CONFIG_NET_EMATCH_STACK=32
 # CONFIG_NET_EMATCH_CMP is not set
@@ -659,7 +687,9 @@ CONFIG_NET_CLS_ACT=y
 # 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
@@ -676,29 +706,33 @@ CONFIG_HAMRADIO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
-
-#
-# Wireless
-#
+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 is not set
 CONFIG_MAC80211=y
 
 #
 # Rate control algorithm selection
 #
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-CONFIG_MAC80211_RC_DEFAULT="pid"
+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_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
-# CONFIG_IEEE80211 is not set
-# CONFIG_RFKILL is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+# CONFIG_RFKILL_INPUT is not set
+CONFIG_RFKILL_LEDS=y
 # CONFIG_NET_9P is not set
 
 #
@@ -722,7 +756,7 @@ CONFIG_PROC_EVENTS=y
 # CONFIG_MTD is not set
 # CONFIG_PARPORT is not set
 CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
+CONFIG_PNP_DEBUG_MESSAGES=y
 
 #
 # Protocols
@@ -750,20 +784,19 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 # CONFIG_IBM_ASM 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_ACER_WMI is not set
-# CONFIG_ASUS_LAPTOP is not set
-# CONFIG_FUJITSU_LAPTOP is not set
-# CONFIG_TC1100_WMI is not set
-# CONFIG_MSI_LAPTOP is not set
-# CONFIG_COMPAL_LAPTOP is not set
-# CONFIG_SONY_LAPTOP is not set
-# CONFIG_THINKPAD_ACPI is not set
-# CONFIG_INTEL_MENLOW is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -802,7 +835,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
-CONFIG_SCSI_ISCSI_ATTRS=y
+# 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
@@ -875,6 +908,7 @@ CONFIG_PATA_OLDPIIX=y
 CONFIG_PATA_SCH=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
@@ -930,6 +964,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
@@ -953,6 +990,9 @@ CONFIG_NET_TULIP=y
 # 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
@@ -960,7 +1000,6 @@ CONFIG_NET_PCI=y
 # CONFIG_B44 is not set
 CONFIG_FORCEDETH=y
 # CONFIG_FORCEDETH_NAPI is not set
-# CONFIG_EEPRO100 is not set
 CONFIG_E100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -974,15 +1013,16 @@ CONFIG_8139TOO=y
 # 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_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=y
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 CONFIG_E1000E=y
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
@@ -1000,18 +1040,23 @@ CONFIG_BNX2=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E 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_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_TR=y
 # CONFIG_IBMOL is not set
@@ -1025,9 +1070,8 @@ CONFIG_TR=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 # CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 # CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AIRO is not set
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
@@ -1044,6 +1088,8 @@ CONFIG_WLAN_80211=y
 CONFIG_ATH5K=y
 # CONFIG_ATH5K_DEBUG is not set
 # CONFIG_ATH9K is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 # CONFIG_IWLCORE is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_IWLAGN is not set
@@ -1055,6 +1101,10 @@ CONFIG_ATH5K=y
 # CONFIG_RT2X00 is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -1062,6 +1112,7 @@ CONFIG_ATH5K=y
 # 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_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -1123,6 +1174,7 @@ 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_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -1160,15 +1212,16 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # 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_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_PCSPKR is not set
 # CONFIG_INPUT_APANEL is not set
@@ -1179,6 +1232,7 @@ 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 is not set
 
 #
@@ -1245,6 +1299,7 @@ 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 is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
@@ -1279,6 +1334,7 @@ CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
 
 #
 # I2C Hardware Bus support
@@ -1331,8 +1387,6 @@ CONFIG_I2C_I801=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
@@ -1351,8 +1405,78 @@ CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 # CONFIG_PDA_POWER is not set
 # CONFIG_BATTERY_DS2760 is not set
-# CONFIG_HWMON is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ABITUGURU3 is not set
+# CONFIG_SENSORS_AD7414 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_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_K8TEMP is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_FSCHMD is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_HDAPS is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_SENSORS_APPLESMC is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -1372,6 +1496,7 @@ CONFIG_WATCHDOG=y
 # CONFIG_I6300ESB_WDT is not set
 # CONFIG_ITCO_WDT is not set
 # CONFIG_IT8712F_WDT is not set
+# CONFIG_IT87_WDT is not set
 # CONFIG_HP_WATCHDOG is not set
 # CONFIG_SC1200_WDT is not set
 # CONFIG_PC87413_WDT is not set
@@ -1379,9 +1504,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_SBC8360_WDT is not set
 # CONFIG_SBC7240_WDT is not set
 # CONFIG_CPU5_WDT is not set
+# CONFIG_SMSC_SCH311X_WDT is not set
 # CONFIG_SMSC37B787_WDT is not set
 # CONFIG_W83627HF_WDT is not set
 # CONFIG_W83697HF_WDT is not set
+# CONFIG_W83697UG_WDT is not set
 # CONFIG_W83877F_WDT is not set
 # CONFIG_W83977F_WDT is not set
 # CONFIG_MACHZ_WDT is not set
@@ -1397,11 +1524,11 @@ CONFIG_WATCHDOG=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
 
 #
@@ -1410,7 +1537,13 @@ CONFIG_SSB_POSSIBLE=y
 # 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_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
@@ -1450,6 +1583,7 @@ CONFIG_DRM=y
 # CONFIG_DRM_I810 is not set
 # CONFIG_DRM_I830 is not set
 CONFIG_DRM_I915=y
+# CONFIG_DRM_I915_KMS is not set
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
 # CONFIG_DRM_VIA is not set
@@ -1459,6 +1593,7 @@ CONFIG_DRM_I915=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
@@ -1487,7 +1622,6 @@ CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_UVESA is not set
 # CONFIG_FB_VESA is not set
 CONFIG_FB_EFI=y
-# CONFIG_FB_IMAC is not set
 # CONFIG_FB_N411 is not set
 # CONFIG_FB_HGA is not set
 # CONFIG_FB_S1D13XXX is not set
@@ -1503,6 +1637,7 @@ CONFIG_FB_EFI=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -1515,12 +1650,15 @@ CONFIG_FB_EFI=y
 # CONFIG_FB_CARMINE is not set
 # CONFIG_FB_GEODE is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX 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_PROGEAR is not set
 # CONFIG_BACKLIGHT_MBP_NVIDIA is not set
+# CONFIG_BACKLIGHT_SAHARA is not set
 
 #
 # Display device support
@@ -1540,10 +1678,12 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 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_JACK=y
 CONFIG_SND_SEQUENCER=y
 CONFIG_SND_SEQ_DUMMY=y
 CONFIG_SND_OSSEMUL=y
@@ -1551,6 +1691,8 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
 CONFIG_SND_DYNAMIC_MINORS=y
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
@@ -1605,11 +1747,16 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_FM801 is not set
 CONFIG_SND_HDA_INTEL=y
 CONFIG_SND_HDA_HWDEP=y
+# CONFIG_SND_HDA_RECONFIG is not set
+# CONFIG_SND_HDA_INPUT_BEEP is not set
 CONFIG_SND_HDA_CODEC_REALTEK=y
 CONFIG_SND_HDA_CODEC_ANALOG=y
 CONFIG_SND_HDA_CODEC_SIGMATEL=y
 CONFIG_SND_HDA_CODEC_VIA=y
 CONFIG_SND_HDA_CODEC_ATIHDMI=y
+CONFIG_SND_HDA_CODEC_NVHDMI=y
+CONFIG_SND_HDA_CODEC_INTELHDMI=y
+CONFIG_SND_HDA_ELD=y
 CONFIG_SND_HDA_CODEC_CONEXANT=y
 CONFIG_SND_HDA_CODEC_CMEDIA=y
 CONFIG_SND_HDA_CODEC_SI3054=y
@@ -1643,6 +1790,7 @@ CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_US122L is not set
 CONFIG_SND_PCMCIA=y
 # CONFIG_SND_VXPOCKET is not set
 # CONFIG_SND_PDAUDIOCF is not set
@@ -1657,15 +1805,37 @@ CONFIG_HIDRAW=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT_POWERBOOK=y
-CONFIG_HID_FF=y
 CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=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=y
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
 CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
 CONFIG_THRUSTMASTER_FF=y
 CONFIG_ZEROPLUS_FF=y
-CONFIG_USB_HIDDEV=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1683,6 +1853,8 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_SUSPEND=y
 # 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
@@ -1691,6 +1863,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_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
@@ -1700,6 +1873,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # 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
@@ -1707,20 +1882,20 @@ CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 # 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 also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# 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_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
@@ -1728,7 +1903,6 @@ 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_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 CONFIG_USB_LIBUSUAL=y
 
@@ -1749,6 +1923,7 @@ CONFIG_USB_LIBUSUAL=y
 # 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
@@ -1766,7 +1941,13 @@ CONFIG_USB_LIBUSUAL=y
 # 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_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -1775,6 +1956,7 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_ALIX2 is not set
 # CONFIG_LEDS_PCA9532 is not set
 # CONFIG_LEDS_CLEVO_MAIL is not set
 # CONFIG_LEDS_PCA955X is not set
@@ -1785,6 +1967,7 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_TIMER is not set
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
@@ -1824,6 +2007,7 @@ 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
 
 #
 # SPI RTC drivers
@@ -1833,12 +2017,15 @@ CONFIG_RTC_INTF_DEV=y
 # Platform RTC drivers
 #
 CONFIG_RTC_DRV_CMOS=y
+# 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
 
 #
@@ -1851,6 +2038,22 @@ CONFIG_DMADEVICES=y
 #
 # CONFIG_INTEL_IOATDMA is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+# CONFIG_ACER_WMI is not set
+# CONFIG_ASUS_LAPTOP is not set
+# CONFIG_FUJITSU_LAPTOP is not set
+# CONFIG_TC1100_WMI is not set
+# CONFIG_MSI_LAPTOP is not set
+# CONFIG_PANASONIC_LAPTOP is not set
+# CONFIG_COMPAL_LAPTOP is not set
+# CONFIG_SONY_LAPTOP is not set
+# CONFIG_THINKPAD_ACPI is not set
+# CONFIG_INTEL_MENLOW is not set
+CONFIG_EEEPC_LAPTOP=y
+# CONFIG_ACPI_WMI is not set
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_TOSHIBA is not set
 
 #
 # Firmware Drivers
@@ -1861,8 +2064,7 @@ CONFIG_EFI_VARS=y
 # CONFIG_DELL_RBU is not set
 # CONFIG_DCDBAS is not set
 CONFIG_DMIID=y
-CONFIG_ISCSI_IBFT_FIND=y
-CONFIG_ISCSI_IBFT=y
+# CONFIG_ISCSI_IBFT_FIND is not set
 
 #
 # File systems
@@ -1872,21 +2074,24 @@ CONFIG_EXT3_FS=y
 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 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=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS 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=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=y
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=y
 CONFIG_QUOTACTL=y
@@ -1920,16 +2125,14 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_VMCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=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_ECRYPT_FS is not set
@@ -1939,6 +2142,7 @@ CONFIG_HUGETLB_PAGE=y
 # 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
@@ -1960,6 +2164,7 @@ CONFIG_NFS_ACL_SUPPORT=y
 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
@@ -2036,7 +2241,7 @@ CONFIG_NLS_UTF8=y
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
-CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
@@ -2066,33 +2271,54 @@ CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL 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_ARCH_WANT_FRAME_POINTERS=y
 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_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_HW_BRANCH_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SYSPROF_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_POWER_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_HW_BRANCH_TRACER is not set
 CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_STRICT_DEVMEM is not set
 CONFIG_X86_VERBOSE_BOOTUP=y
 CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_DBGP=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -2123,8 +2349,10 @@ CONFIG_OPTIMIZE_INLINING=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
+# CONFIG_SECURITY_PATH is not set
 CONFIG_SECURITY_FILE_CAPABILITIES=y
 # CONFIG_SECURITY_ROOTPLUG is not set
 CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
@@ -2135,7 +2363,6 @@ CONFIG_SECURITY_SELINUX_DISABLE=y
 CONFIG_SECURITY_SELINUX_DEVELOP=y
 CONFIG_SECURITY_SELINUX_AVC_STATS=y
 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
-# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
 # CONFIG_SECURITY_SMACK is not set
 CONFIG_CRYPTO=y
@@ -2143,11 +2370,18 @@ 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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -2182,6 +2416,7 @@ CONFIG_CRYPTO_HMAC=y
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -2222,6 +2457,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE 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_PADLOCK is not set
 # CONFIG_CRYPTO_DEV_GEODE is not set
@@ -2239,6 +2479,7 @@ CONFIG_VIRTUALIZATION=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_FIRST_BIT=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/configs/x86_64_defconfig linux-libre-2.6.30-gnu1/arch/x86/configs/x86_64_defconfig
--- linux-libre-2.6.29-gnu1/arch/x86/configs/x86_64_defconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/configs/x86_64_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc5
-# Wed Sep  3 17:13:39 2008
+# Linux kernel version: 2.6.29-rc4
+# Tue Feb 24 15:44:16 2009
 #
 CONFIG_64BIT=y
 # CONFIG_X86_32 is not set
 CONFIG_X86_64=y
 CONFIG_X86=y
 CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
-# CONFIG_GENERIC_LOCKBREAK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_CLOCKSOURCE_WATCHDOG=y
@@ -23,17 +22,16 @@ CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_GENERIC_HWEIGHT=y
-# CONFIG_GENERIC_GPIO is not set
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=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_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
@@ -42,12 +40,12 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ZONE_DMA32=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_AUDIT_ARCH=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
 CONFIG_X86_SMP=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_X86_64_SMP=y
 CONFIG_X86_HT=y
 CONFIG_X86_BIOS_REBOOT=y
@@ -76,30 +74,44 @@ CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_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 is not set
 CONFIG_LOG_BUF_SHIFT=18
-CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
-CONFIG_CGROUP_NS=y
-# CONFIG_CGROUP_DEVICE is not set
-CONFIG_CPUSETS=y
 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 # CONFIG_USER_SCHED is not set
 CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_FREEZER=y
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 # CONFIG_CGROUP_MEM_RES_CTLR is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
-CONFIG_PROC_PID_CPUSET=y
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+CONFIG_NET_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -124,12 +136,15 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
 CONFIG_MARKERS=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
@@ -139,15 +154,10 @@ CONFIG_KRETPROBES=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=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=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -155,7 +165,6 @@ 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_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_BLK_DEV_IO_TRACE=y
@@ -175,7 +184,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
 
 #
 # Processor type and features
@@ -185,13 +194,14 @@ CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_SMP=y
+CONFIG_SPARSE_IRQ=y
+# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
-CONFIG_X86_PC=y
 # CONFIG_X86_ELAN is not set
-# CONFIG_X86_VOYAGER is not set
 # CONFIG_X86_GENERICARCH is not set
 # CONFIG_X86_VSMP is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 # CONFIG_PARAVIRT_GUEST is not set
 # CONFIG_MEMTEST is not set
 # CONFIG_M386 is not set
@@ -230,6 +240,11 @@ CONFIG_X86_CMPXCHG64=y
 CONFIG_X86_CMOV=y
 CONFIG_X86_MINIMUM_CPU_FAMILY=64
 CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR_64=y
+CONFIG_X86_DS=y
+CONFIG_X86_PTRACE_BTS=y
 CONFIG_HPET_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
 CONFIG_DMI=y
@@ -237,8 +252,11 @@ CONFIG_GART_IOMMU=y
 CONFIG_CALGARY_IOMMU=y
 CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
 CONFIG_AMD_IOMMU=y
+CONFIG_AMD_IOMMU_STATS=y
 CONFIG_SWIOTLB=y
 CONFIG_IOMMU_HELPER=y
+CONFIG_IOMMU_API=y
+# CONFIG_MAXSMP is not set
 CONFIG_NR_CPUS=64
 CONFIG_SCHED_SMT=y
 CONFIG_SCHED_MC=y
@@ -247,12 +265,19 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_X86_IO_APIC=y
-# CONFIG_X86_MCE is not set
+CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
+CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
+CONFIG_X86_MCE_AMD=y
 # CONFIG_I8K is not set
 CONFIG_MICROCODE=y
+CONFIG_MICROCODE_INTEL=y
+CONFIG_MICROCODE_AMD=y
 CONFIG_MICROCODE_OLD_INTERFACE=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_DIRECT_GBPAGES=y
 CONFIG_NUMA=y
 CONFIG_K8_NUMA=y
 CONFIG_X86_64_ACPI_NUMA=y
@@ -269,7 +294,6 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_MEMORY_PRESENT=y
-# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPARSEMEM_VMEMMAP=y
@@ -280,10 +304,14 @@ CONFIG_SPARSEMEM_VMEMMAP=y
 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=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_X86_CHECK_BIOS_CORRUPTION=y
+CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
+CONFIG_X86_RESERVE_LOW_64K=y
 CONFIG_MTRR=y
 # CONFIG_MTRR_SANITIZER is not set
 CONFIG_X86_PAT=y
@@ -302,11 +330,12 @@ CONFIG_PHYSICAL_START=0x1000000
 CONFIG_PHYSICAL_ALIGN=0x200000
 CONFIG_HOTPLUG_CPU=y
 # CONFIG_COMPAT_VDSO is not set
+# CONFIG_CMDLINE_BOOL is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 
 #
-# Power management options
+# Power management and ACPI options
 #
 CONFIG_ARCH_HIBERNATION_HEADER=y
 CONFIG_PM=y
@@ -333,20 +362,14 @@ CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_DOCK=y
-# CONFIG_ACPI_BAY is not set
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=y
 CONFIG_ACPI_NUMA=y
-# CONFIG_ACPI_WMI is not set
-# CONFIG_ACPI_ASUS is not set
-# CONFIG_ACPI_TOSHIBA is not set
 # CONFIG_ACPI_CUSTOM_DSDT is not set
 CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
 # CONFIG_ACPI_PCI_SLOT is not set
-CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_X86_PM_TIMER=y
 CONFIG_ACPI_CONTAINER=y
@@ -381,13 +404,17 @@ CONFIG_X86_ACPI_CPUFREQ=y
 #
 # shared options
 #
-# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
 # CONFIG_X86_SPEEDSTEP_LIB is not set
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
 
 #
+# Memory power savings
+#
+# CONFIG_I7300_IDLE is not set
+
+#
 # Bus options (PCI etc.)
 #
 CONFIG_PCI=y
@@ -395,8 +422,10 @@ CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_DMAR=y
+# CONFIG_DMAR_DEFAULT_ON is not set
 CONFIG_DMAR_GFX_WA=y
 CONFIG_DMAR_FLOPPY_WA=y
+# CONFIG_INTR_REMAP is not set
 CONFIG_PCIEPORTBUS=y
 # CONFIG_HOTPLUG_PCI_PCIE is not set
 CONFIG_PCIEAER=y
@@ -405,6 +434,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
 CONFIG_HT_IRQ=y
 CONFIG_ISA_DMA_API=y
 CONFIG_K8_NB=y
@@ -438,6 +468,8 @@ CONFIG_HOTPLUG_PCI=y
 #
 CONFIG_BINFMT_ELF=y
 CONFIG_COMPAT_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+# CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_IA32_EMULATION=y
 # CONFIG_IA32_AOUT is not set
@@ -449,6 +481,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -509,7 +542,6 @@ CONFIG_DEFAULT_CUBIC=y
 # CONFIG_DEFAULT_RENO is not set
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -547,19 +579,21 @@ CONFIG_NF_CONNTRACK_IRC=y
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CT_NETLINK=y
 CONFIG_NETFILTER_XTABLES=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFLOG=y
 CONFIG_NETFILTER_XT_TARGET_SECMARK=y
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=y
 CONFIG_NF_CONNTRACK_IPV4=y
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=y
@@ -585,8 +619,8 @@ CONFIG_IP_NF_MANGLE=y
 CONFIG_NF_CONNTRACK_IPV6=y
 CONFIG_IP6_NF_IPTABLES=y
 CONFIG_IP6_NF_MATCH_IPV6HEADER=y
-CONFIG_IP6_NF_FILTER=y
 CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
 CONFIG_IP6_NF_TARGET_REJECT=y
 CONFIG_IP6_NF_MANGLE=y
 # CONFIG_IP_DCCP is not set
@@ -594,6 +628,7 @@ CONFIG_IP6_NF_MANGLE=y
 # 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_LLC=y
@@ -613,6 +648,7 @@ CONFIG_NET_SCHED=y
 # 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
@@ -620,6 +656,7 @@ CONFIG_NET_SCHED=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
 # CONFIG_NET_SCH_INGRESS is not set
 
 #
@@ -634,6 +671,7 @@ CONFIG_NET_CLS=y
 # CONFIG_NET_CLS_RSVP is not set
 # CONFIG_NET_CLS_RSVP6 is not set
 # CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_CLS_CGROUP is not set
 CONFIG_NET_EMATCH=y
 CONFIG_NET_EMATCH_STACK=32
 # CONFIG_NET_EMATCH_CMP is not set
@@ -649,7 +687,9 @@ CONFIG_NET_CLS_ACT=y
 # 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
@@ -666,29 +706,33 @@ CONFIG_HAMRADIO=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
-
-#
-# Wireless
-#
+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 is not set
 CONFIG_MAC80211=y
 
 #
 # Rate control algorithm selection
 #
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-CONFIG_MAC80211_RC_DEFAULT="pid"
+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_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
-# CONFIG_IEEE80211 is not set
-# CONFIG_RFKILL is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+# CONFIG_RFKILL_INPUT is not set
+CONFIG_RFKILL_LEDS=y
 # CONFIG_NET_9P is not set
 
 #
@@ -712,7 +756,7 @@ CONFIG_PROC_EVENTS=y
 # CONFIG_MTD is not set
 # CONFIG_PARPORT is not set
 CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
+CONFIG_PNP_DEBUG_MESSAGES=y
 
 #
 # Protocols
@@ -740,21 +784,21 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 # CONFIG_IBM_ASM 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_ACER_WMI is not set
-# CONFIG_ASUS_LAPTOP is not set
-# CONFIG_FUJITSU_LAPTOP is not set
-# CONFIG_MSI_LAPTOP is not set
-# CONFIG_COMPAL_LAPTOP is not set
-# CONFIG_SONY_LAPTOP is not set
-# CONFIG_THINKPAD_ACPI is not set
-# CONFIG_INTEL_MENLOW is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_SGI_XP is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_SGI_GRU is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -793,7 +837,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
-CONFIG_SCSI_ISCSI_ATTRS=y
+# 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
@@ -864,6 +908,7 @@ CONFIG_PATA_OLDPIIX=y
 CONFIG_PATA_SCH=y
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
@@ -919,6 +964,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
@@ -942,6 +990,9 @@ CONFIG_NET_TULIP=y
 # 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
@@ -949,7 +1000,6 @@ CONFIG_NET_PCI=y
 # CONFIG_B44 is not set
 CONFIG_FORCEDETH=y
 # CONFIG_FORCEDETH_NAPI is not set
-# CONFIG_EEPRO100 is not set
 CONFIG_E100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -963,15 +1013,16 @@ CONFIG_8139TOO_PIO=y
 # 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_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=y
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_E1000E is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
@@ -989,18 +1040,23 @@ CONFIG_TIGON3=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E 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_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_TR=y
 # CONFIG_IBMOL is not set
@@ -1013,9 +1069,8 @@ CONFIG_TR=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 # CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 # CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AIRO is not set
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
@@ -1032,6 +1087,8 @@ CONFIG_WLAN_80211=y
 CONFIG_ATH5K=y
 # CONFIG_ATH5K_DEBUG is not set
 # CONFIG_ATH9K is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
 # CONFIG_IWLCORE is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_IWLAGN is not set
@@ -1043,6 +1100,10 @@ CONFIG_ATH5K=y
 # CONFIG_RT2X00 is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -1050,6 +1111,7 @@ CONFIG_ATH5K=y
 # 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_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -1059,6 +1121,7 @@ CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
 # CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_IBMTR is not set
 # CONFIG_WAN is not set
 CONFIG_FDDI=y
 # CONFIG_DEFXX is not set
@@ -1110,6 +1173,7 @@ 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_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -1147,15 +1211,16 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # 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_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_PCSPKR is not set
 # CONFIG_INPUT_APANEL is not set
@@ -1165,6 +1230,7 @@ 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 is not set
 
 #
@@ -1231,6 +1297,7 @@ 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 is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
@@ -1260,6 +1327,7 @@ CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_CHARDEV is not set
 CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
 
 #
 # I2C Hardware Bus support
@@ -1311,8 +1379,6 @@ CONFIG_I2C_I801=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
@@ -1331,8 +1397,78 @@ CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 # CONFIG_PDA_POWER is not set
 # CONFIG_BATTERY_DS2760 is not set
-# CONFIG_HWMON is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ABITUGURU3 is not set
+# CONFIG_SENSORS_AD7414 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_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_K8TEMP is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_FSCHMD is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 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_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 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_HDAPS is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_SENSORS_APPLESMC is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -1352,15 +1488,18 @@ CONFIG_WATCHDOG=y
 # CONFIG_I6300ESB_WDT is not set
 # CONFIG_ITCO_WDT is not set
 # CONFIG_IT8712F_WDT is not set
+# CONFIG_IT87_WDT is not set
 # CONFIG_HP_WATCHDOG is not set
 # CONFIG_SC1200_WDT is not set
 # CONFIG_PC87413_WDT is not set
 # CONFIG_60XX_WDT is not set
 # CONFIG_SBC8360_WDT is not set
 # CONFIG_CPU5_WDT is not set
+# CONFIG_SMSC_SCH311X_WDT is not set
 # CONFIG_SMSC37B787_WDT is not set
 # CONFIG_W83627HF_WDT is not set
 # CONFIG_W83697HF_WDT is not set
+# CONFIG_W83697UG_WDT is not set
 # CONFIG_W83877F_WDT is not set
 # CONFIG_W83977F_WDT is not set
 # CONFIG_MACHZ_WDT is not set
@@ -1376,11 +1515,11 @@ CONFIG_WATCHDOG=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
 
 #
@@ -1389,7 +1528,13 @@ CONFIG_SSB_POSSIBLE=y
 # 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_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
@@ -1423,6 +1568,7 @@ CONFIG_DRM=y
 # CONFIG_DRM_I810 is not set
 # CONFIG_DRM_I830 is not set
 CONFIG_DRM_I915=y
+CONFIG_DRM_I915_KMS=y
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
 # CONFIG_DRM_VIA is not set
@@ -1432,6 +1578,7 @@ CONFIG_DRM_I915=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
@@ -1460,7 +1607,6 @@ CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_UVESA is not set
 # CONFIG_FB_VESA is not set
 CONFIG_FB_EFI=y
-# CONFIG_FB_IMAC is not set
 # CONFIG_FB_N411 is not set
 # CONFIG_FB_HGA is not set
 # CONFIG_FB_S1D13XXX is not set
@@ -1475,6 +1621,7 @@ CONFIG_FB_EFI=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -1486,12 +1633,15 @@ CONFIG_FB_EFI=y
 # CONFIG_FB_CARMINE is not set
 # CONFIG_FB_GEODE is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX 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_PROGEAR is not set
 # CONFIG_BACKLIGHT_MBP_NVIDIA is not set
+# CONFIG_BACKLIGHT_SAHARA is not set
 
 #
 # Display device support
@@ -1511,10 +1661,12 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 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_JACK=y
 CONFIG_SND_SEQUENCER=y
 CONFIG_SND_SEQ_DUMMY=y
 CONFIG_SND_OSSEMUL=y
@@ -1522,6 +1674,8 @@ CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
 CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
 CONFIG_SND_DYNAMIC_MINORS=y
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
@@ -1575,11 +1729,16 @@ CONFIG_SND_PCI=y
 # CONFIG_SND_FM801 is not set
 CONFIG_SND_HDA_INTEL=y
 CONFIG_SND_HDA_HWDEP=y
+# CONFIG_SND_HDA_RECONFIG is not set
+# CONFIG_SND_HDA_INPUT_BEEP is not set
 CONFIG_SND_HDA_CODEC_REALTEK=y
 CONFIG_SND_HDA_CODEC_ANALOG=y
 CONFIG_SND_HDA_CODEC_SIGMATEL=y
 CONFIG_SND_HDA_CODEC_VIA=y
 CONFIG_SND_HDA_CODEC_ATIHDMI=y
+CONFIG_SND_HDA_CODEC_NVHDMI=y
+CONFIG_SND_HDA_CODEC_INTELHDMI=y
+CONFIG_SND_HDA_ELD=y
 CONFIG_SND_HDA_CODEC_CONEXANT=y
 CONFIG_SND_HDA_CODEC_CMEDIA=y
 CONFIG_SND_HDA_CODEC_SI3054=y
@@ -1612,6 +1771,7 @@ CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_US122L is not set
 CONFIG_SND_PCMCIA=y
 # CONFIG_SND_VXPOCKET is not set
 # CONFIG_SND_PDAUDIOCF is not set
@@ -1626,15 +1786,37 @@ CONFIG_HIDRAW=y
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT_POWERBOOK=y
-CONFIG_HID_FF=y
 CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=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=y
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
 CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
 CONFIG_THRUSTMASTER_FF=y
 CONFIG_ZEROPLUS_FF=y
-CONFIG_USB_HIDDEV=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1652,6 +1834,8 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_SUSPEND=y
 # 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
@@ -1660,6 +1844,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_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
@@ -1669,6 +1854,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # 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
@@ -1676,20 +1863,20 @@ CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 # 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 also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# 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_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
@@ -1697,7 +1884,6 @@ 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_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 CONFIG_USB_LIBUSUAL=y
 
@@ -1718,6 +1904,7 @@ CONFIG_USB_LIBUSUAL=y
 # 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
@@ -1735,7 +1922,13 @@ CONFIG_USB_LIBUSUAL=y
 # 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_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -1744,6 +1937,7 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_ALIX2 is not set
 # CONFIG_LEDS_PCA9532 is not set
 # CONFIG_LEDS_CLEVO_MAIL is not set
 # CONFIG_LEDS_PCA955X is not set
@@ -1754,6 +1948,7 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_TIMER is not set
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
@@ -1793,6 +1988,7 @@ 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
 
 #
 # SPI RTC drivers
@@ -1802,12 +1998,15 @@ CONFIG_RTC_INTF_DEV=y
 # Platform RTC drivers
 #
 CONFIG_RTC_DRV_CMOS=y
+# 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
 
 #
@@ -1820,6 +2019,21 @@ CONFIG_DMADEVICES=y
 #
 # CONFIG_INTEL_IOATDMA is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+# CONFIG_ACER_WMI is not set
+# CONFIG_ASUS_LAPTOP is not set
+# CONFIG_FUJITSU_LAPTOP is not set
+# CONFIG_MSI_LAPTOP is not set
+# CONFIG_PANASONIC_LAPTOP is not set
+# CONFIG_COMPAL_LAPTOP is not set
+# CONFIG_SONY_LAPTOP is not set
+# CONFIG_THINKPAD_ACPI is not set
+# CONFIG_INTEL_MENLOW is not set
+CONFIG_EEEPC_LAPTOP=y
+# CONFIG_ACPI_WMI is not set
+# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_TOSHIBA is not set
 
 #
 # Firmware Drivers
@@ -1830,8 +2044,7 @@ CONFIG_EFI_VARS=y
 # CONFIG_DELL_RBU is not set
 # CONFIG_DCDBAS is not set
 CONFIG_DMIID=y
-CONFIG_ISCSI_IBFT_FIND=y
-CONFIG_ISCSI_IBFT=y
+# CONFIG_ISCSI_IBFT_FIND is not set
 
 #
 # File systems
@@ -1841,22 +2054,25 @@ CONFIG_EXT3_FS=y
 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 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=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_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=y
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=y
 CONFIG_QUOTACTL=y
@@ -1890,16 +2106,14 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_VMCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=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_ECRYPT_FS is not set
@@ -1909,6 +2123,7 @@ CONFIG_HUGETLB_PAGE=y
 # 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
@@ -1930,6 +2145,7 @@ CONFIG_NFS_ACL_SUPPORT=y
 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
@@ -2006,7 +2222,7 @@ CONFIG_NLS_UTF8=y
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
-CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
@@ -2035,40 +2251,60 @@ CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL 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_ARCH_WANT_FRAME_POINTERS=y
 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_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_HW_BRANCH_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SYSPROF_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_POWER_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_HW_BRANCH_TRACER is not set
 CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 # CONFIG_STRICT_DEVMEM is not set
 CONFIG_X86_VERBOSE_BOOTUP=y
 CONFIG_EARLY_PRINTK=y
+CONFIG_EARLY_PRINTK_DBGP=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_DEBUG_PER_CPU_MAPS is not set
 # CONFIG_X86_PTDUMP is not set
 CONFIG_DEBUG_RODATA=y
-# CONFIG_DIRECT_GBPAGES is not set
 # CONFIG_DEBUG_RODATA_TEST is not set
 CONFIG_DEBUG_NX_TEST=m
 # CONFIG_IOMMU_DEBUG is not set
@@ -2092,8 +2328,10 @@ CONFIG_OPTIMIZE_INLINING=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
+# CONFIG_SECURITY_PATH is not set
 CONFIG_SECURITY_FILE_CAPABILITIES=y
 # CONFIG_SECURITY_ROOTPLUG is not set
 CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
@@ -2104,7 +2342,6 @@ CONFIG_SECURITY_SELINUX_DISABLE=y
 CONFIG_SECURITY_SELINUX_DEVELOP=y
 CONFIG_SECURITY_SELINUX_AVC_STATS=y
 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
-# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
 # CONFIG_SECURITY_SMACK is not set
 CONFIG_CRYPTO=y
@@ -2112,11 +2349,18 @@ 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_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -2151,6 +2395,7 @@ CONFIG_CRYPTO_HMAC=y
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -2191,6 +2436,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE 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_HAVE_KVM=y
@@ -2205,6 +2455,7 @@ CONFIG_VIRTUALIZATION=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_FIRST_BIT=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/aes_glue.c linux-libre-2.6.30-gnu1/arch/x86/crypto/aes_glue.c
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/aes_glue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/aes_glue.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,17 +5,29 @@
 
 #include <crypto/aes.h>
 
-asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
-asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
+asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
+
+void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+{
+	aes_enc_blk(ctx, dst, src);
+}
+EXPORT_SYMBOL_GPL(crypto_aes_encrypt_x86);
+
+void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+{
+	aes_dec_blk(ctx, dst, src);
+}
+EXPORT_SYMBOL_GPL(crypto_aes_decrypt_x86);
 
 static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
-	aes_enc_blk(tfm, dst, src);
+	aes_enc_blk(crypto_tfm_ctx(tfm), dst, src);
 }
 
 static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
-	aes_dec_blk(tfm, dst, src);
+	aes_dec_blk(crypto_tfm_ctx(tfm), dst, src);
 }
 
 static struct crypto_alg aes_alg = {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/aes-i586-asm_32.S linux-libre-2.6.30-gnu1/arch/x86/crypto/aes-i586-asm_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/aes-i586-asm_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/aes-i586-asm_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -41,14 +41,14 @@
 #define tlen 1024   // length of each of 4 'xor' arrays (256 32-bit words)
 
 /* offsets to parameters with one register pushed onto stack */
-#define tfm 8
+#define ctx 8
 #define out_blk 12
 #define in_blk 16
 
-/* offsets in crypto_tfm structure */
-#define klen (crypto_tfm_ctx_offset + 0)
-#define ekey (crypto_tfm_ctx_offset + 4)
-#define dkey (crypto_tfm_ctx_offset + 244)
+/* offsets in crypto_aes_ctx structure */
+#define klen (480)
+#define ekey (0)
+#define dkey (240)
 
 // register mapping for encrypt and decrypt subroutines
 
@@ -217,7 +217,7 @@
 	do_col (table, r5,r0,r1,r4, r2,r3);		/* idx=r5 */
 
 // AES (Rijndael) Encryption Subroutine
-/* void aes_enc_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */
+/* void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out_blk, const u8 *in_blk) */
 
 .global  aes_enc_blk
 
@@ -228,7 +228,7 @@
 
 aes_enc_blk:
 	push    %ebp
-	mov     tfm(%esp),%ebp
+	mov     ctx(%esp),%ebp
 
 // CAUTION: the order and the values used in these assigns 
 // rely on the register mappings
@@ -292,7 +292,7 @@ aes_enc_blk:
 	ret
 
 // AES (Rijndael) Decryption Subroutine
-/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */
+/* void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out_blk, const u8 *in_blk) */
 
 .global  aes_dec_blk
 
@@ -303,7 +303,7 @@ aes_enc_blk:
 
 aes_dec_blk:
 	push    %ebp
-	mov     tfm(%esp),%ebp
+	mov     ctx(%esp),%ebp
 
 // CAUTION: the order and the values used in these assigns 
 // rely on the register mappings
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/aesni-intel_asm.S linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_asm.S
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/aesni-intel_asm.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_asm.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,896 @@
+/*
+ * Implement AES algorithm in Intel AES-NI instructions.
+ *
+ * The white paper of AES-NI instructions can be downloaded from:
+ *   http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
+ *
+ * Copyright (C) 2008, Intel Corp.
+ *    Author: Huang Ying <ying.huang@intel.com>
+ *            Vinodh Gopal <vinodh.gopal@intel.com>
+ *            Kahraman Akdemir
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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>
+
+.text
+
+#define STATE1	%xmm0
+#define STATE2	%xmm4
+#define STATE3	%xmm5
+#define STATE4	%xmm6
+#define STATE	STATE1
+#define IN1	%xmm1
+#define IN2	%xmm7
+#define IN3	%xmm8
+#define IN4	%xmm9
+#define IN	IN1
+#define KEY	%xmm2
+#define IV	%xmm3
+
+#define KEYP	%rdi
+#define OUTP	%rsi
+#define INP	%rdx
+#define LEN	%rcx
+#define IVP	%r8
+#define KLEN	%r9d
+#define T1	%r10
+#define TKEYP	T1
+#define T2	%r11
+
+_key_expansion_128:
+_key_expansion_256a:
+	pshufd $0b11111111, %xmm1, %xmm1
+	shufps $0b00010000, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	shufps $0b10001100, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	pxor %xmm1, %xmm0
+	movaps %xmm0, (%rcx)
+	add $0x10, %rcx
+	ret
+
+_key_expansion_192a:
+	pshufd $0b01010101, %xmm1, %xmm1
+	shufps $0b00010000, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	shufps $0b10001100, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	pxor %xmm1, %xmm0
+
+	movaps %xmm2, %xmm5
+	movaps %xmm2, %xmm6
+	pslldq $4, %xmm5
+	pshufd $0b11111111, %xmm0, %xmm3
+	pxor %xmm3, %xmm2
+	pxor %xmm5, %xmm2
+
+	movaps %xmm0, %xmm1
+	shufps $0b01000100, %xmm0, %xmm6
+	movaps %xmm6, (%rcx)
+	shufps $0b01001110, %xmm2, %xmm1
+	movaps %xmm1, 16(%rcx)
+	add $0x20, %rcx
+	ret
+
+_key_expansion_192b:
+	pshufd $0b01010101, %xmm1, %xmm1
+	shufps $0b00010000, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	shufps $0b10001100, %xmm0, %xmm4
+	pxor %xmm4, %xmm0
+	pxor %xmm1, %xmm0
+
+	movaps %xmm2, %xmm5
+	pslldq $4, %xmm5
+	pshufd $0b11111111, %xmm0, %xmm3
+	pxor %xmm3, %xmm2
+	pxor %xmm5, %xmm2
+
+	movaps %xmm0, (%rcx)
+	add $0x10, %rcx
+	ret
+
+_key_expansion_256b:
+	pshufd $0b10101010, %xmm1, %xmm1
+	shufps $0b00010000, %xmm2, %xmm4
+	pxor %xmm4, %xmm2
+	shufps $0b10001100, %xmm2, %xmm4
+	pxor %xmm4, %xmm2
+	pxor %xmm1, %xmm2
+	movaps %xmm2, (%rcx)
+	add $0x10, %rcx
+	ret
+
+/*
+ * int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ *                   unsigned int key_len)
+ */
+ENTRY(aesni_set_key)
+	movups (%rsi), %xmm0		# user key (first 16 bytes)
+	movaps %xmm0, (%rdi)
+	lea 0x10(%rdi), %rcx		# key addr
+	movl %edx, 480(%rdi)
+	pxor %xmm4, %xmm4		# xmm4 is assumed 0 in _key_expansion_x
+	cmp $24, %dl
+	jb .Lenc_key128
+	je .Lenc_key192
+	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
+	call _key_expansion_256a
+	# aeskeygenassist $0x1, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	call _key_expansion_256b
+	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	call _key_expansion_256a
+	# aeskeygenassist $0x2, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	call _key_expansion_256b
+	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	call _key_expansion_256a
+	# aeskeygenassist $0x4, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	call _key_expansion_256b
+	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	call _key_expansion_256a
+	# aeskeygenassist $0x8, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	call _key_expansion_256b
+	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	call _key_expansion_256a
+	# aeskeygenassist $0x10, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	call _key_expansion_256b
+	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	call _key_expansion_256a
+	# aeskeygenassist $0x20, %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	call _key_expansion_256b
+	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	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
+	call _key_expansion_192a
+	# aeskeygenassist $0x2, %xmm2, %xmm1	# round 2
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+	call _key_expansion_192b
+	# aeskeygenassist $0x4, %xmm2, %xmm1	# round 3
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+	call _key_expansion_192a
+	# aeskeygenassist $0x8, %xmm2, %xmm1	# round 4
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+	call _key_expansion_192b
+	# aeskeygenassist $0x10, %xmm2, %xmm1	# round 5
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+	call _key_expansion_192a
+	# aeskeygenassist $0x20, %xmm2, %xmm1	# round 6
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+	call _key_expansion_192b
+	# aeskeygenassist $0x40, %xmm2, %xmm1	# round 7
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+	call _key_expansion_192a
+	# aeskeygenassist $0x80, %xmm2, %xmm1	# round 8
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x80
+	call _key_expansion_192b
+	jmp .Ldec_key
+.Lenc_key128:
+	# aeskeygenassist $0x1, %xmm0, %xmm1	# round 1
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+	call _key_expansion_128
+	# aeskeygenassist $0x2, %xmm0, %xmm1	# round 2
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+	call _key_expansion_128
+	# aeskeygenassist $0x4, %xmm0, %xmm1	# round 3
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+	call _key_expansion_128
+	# aeskeygenassist $0x8, %xmm0, %xmm1	# round 4
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+	call _key_expansion_128
+	# aeskeygenassist $0x10, %xmm0, %xmm1	# round 5
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+	call _key_expansion_128
+	# aeskeygenassist $0x20, %xmm0, %xmm1	# round 6
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+	call _key_expansion_128
+	# aeskeygenassist $0x40, %xmm0, %xmm1	# round 7
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x40
+	call _key_expansion_128
+	# aeskeygenassist $0x80, %xmm0, %xmm1	# round 8
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x80
+	call _key_expansion_128
+	# aeskeygenassist $0x1b, %xmm0, %xmm1	# round 9
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x1b
+	call _key_expansion_128
+	# aeskeygenassist $0x36, %xmm0, %xmm1	# round 10
+	.byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x36
+	call _key_expansion_128
+.Ldec_key:
+	sub $0x10, %rcx
+	movaps (%rdi), %xmm0
+	movaps (%rcx), %xmm1
+	movaps %xmm0, 240(%rcx)
+	movaps %xmm1, 240(%rdi)
+	add $0x10, %rdi
+	lea 240-16(%rcx), %rsi
+.align 4
+.Ldec_key_loop:
+	movaps (%rdi), %xmm0
+	# aesimc %xmm0, %xmm1
+	.byte 0x66, 0x0f, 0x38, 0xdb, 0xc8
+	movaps %xmm1, (%rsi)
+	add $0x10, %rdi
+	sub $0x10, %rsi
+	cmp %rcx, %rdi
+	jb .Ldec_key_loop
+	xor %rax, %rax
+	ret
+
+/*
+ * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+ENTRY(aesni_enc)
+	movl 480(KEYP), KLEN		# key length
+	movups (INP), STATE		# input
+	call _aesni_enc1
+	movups STATE, (OUTP)		# output
+	ret
+
+/*
+ * _aesni_enc1:		internal ABI
+ * input:
+ *	KEYP:		key struct pointer
+ *	KLEN:		round count
+ *	STATE:		initial state (input)
+ * output:
+ *	STATE:		finial state (output)
+ * changed:
+ *	KEY
+ *	TKEYP (T1)
+ */
+_aesni_enc1:
+	movaps (KEYP), KEY		# key
+	mov KEYP, TKEYP
+	pxor KEY, STATE		# round 0
+	add $0x30, TKEYP
+	cmp $24, KLEN
+	jb .Lenc128
+	lea 0x20(TKEYP), TKEYP
+	je .Lenc192
+	add $0x20, TKEYP
+	movaps -0x60(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps -0x50(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+.align 4
+.Lenc192:
+	movaps -0x40(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps -0x30(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+.align 4
+.Lenc128:
+	movaps -0x20(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps -0x10(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps (TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x10(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x20(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x30(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x40(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x50(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x60(TKEYP), KEY
+	# aesenc KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+	movaps 0x70(TKEYP), KEY
+	# aesenclast KEY, STATE	# last round
+	.byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
+	ret
+
+/*
+ * _aesni_enc4:	internal ABI
+ * input:
+ *	KEYP:		key struct pointer
+ *	KLEN:		round count
+ *	STATE1:		initial state (input)
+ *	STATE2
+ *	STATE3
+ *	STATE4
+ * output:
+ *	STATE1:		finial state (output)
+ *	STATE2
+ *	STATE3
+ *	STATE4
+ * changed:
+ *	KEY
+ *	TKEYP (T1)
+ */
+_aesni_enc4:
+	movaps (KEYP), KEY		# key
+	mov KEYP, TKEYP
+	pxor KEY, STATE1		# round 0
+	pxor KEY, STATE2
+	pxor KEY, STATE3
+	pxor KEY, STATE4
+	add $0x30, TKEYP
+	cmp $24, KLEN
+	jb .L4enc128
+	lea 0x20(TKEYP), TKEYP
+	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
+	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
+#.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
+	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
+#.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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	ret
+
+/*
+ * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+ENTRY(aesni_dec)
+	mov 480(KEYP), KLEN		# key length
+	add $240, KEYP
+	movups (INP), STATE		# input
+	call _aesni_dec1
+	movups STATE, (OUTP)		#output
+	ret
+
+/*
+ * _aesni_dec1:		internal ABI
+ * input:
+ *	KEYP:		key struct pointer
+ *	KLEN:		key length
+ *	STATE:		initial state (input)
+ * output:
+ *	STATE:		finial state (output)
+ * changed:
+ *	KEY
+ *	TKEYP (T1)
+ */
+_aesni_dec1:
+	movaps (KEYP), KEY		# key
+	mov KEYP, TKEYP
+	pxor KEY, STATE		# round 0
+	add $0x30, TKEYP
+	cmp $24, KLEN
+	jb .Ldec128
+	lea 0x20(TKEYP), TKEYP
+	je .Ldec192
+	add $0x20, TKEYP
+	movaps -0x60(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps -0x50(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+.align 4
+.Ldec192:
+	movaps -0x40(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps -0x30(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+.align 4
+.Ldec128:
+	movaps -0x20(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps -0x10(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps (TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x10(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x20(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x30(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x40(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x50(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x60(TKEYP), KEY
+	# aesdec KEY, STATE
+	.byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+	movaps 0x70(TKEYP), KEY
+	# aesdeclast KEY, STATE		# last round
+	.byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
+	ret
+
+/*
+ * _aesni_dec4:	internal ABI
+ * input:
+ *	KEYP:		key struct pointer
+ *	KLEN:		key length
+ *	STATE1:		initial state (input)
+ *	STATE2
+ *	STATE3
+ *	STATE4
+ * output:
+ *	STATE1:		finial state (output)
+ *	STATE2
+ *	STATE3
+ *	STATE4
+ * changed:
+ *	KEY
+ *	TKEYP (T1)
+ */
+_aesni_dec4:
+	movaps (KEYP), KEY		# key
+	mov KEYP, TKEYP
+	pxor KEY, STATE1		# round 0
+	pxor KEY, STATE2
+	pxor KEY, STATE3
+	pxor KEY, STATE4
+	add $0x30, TKEYP
+	cmp $24, KLEN
+	jb .L4dec128
+	lea 0x20(TKEYP), TKEYP
+	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
+	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
+.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
+	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
+.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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	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
+	ret
+
+/*
+ * void aesni_ecb_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ *		      size_t len)
+ */
+ENTRY(aesni_ecb_enc)
+	test LEN, LEN		# check length
+	jz .Lecb_enc_ret
+	mov 480(KEYP), KLEN
+	cmp $16, LEN
+	jb .Lecb_enc_ret
+	cmp $64, LEN
+	jb .Lecb_enc_loop1
+.align 4
+.Lecb_enc_loop4:
+	movups (INP), STATE1
+	movups 0x10(INP), STATE2
+	movups 0x20(INP), STATE3
+	movups 0x30(INP), STATE4
+	call _aesni_enc4
+	movups STATE1, (OUTP)
+	movups STATE2, 0x10(OUTP)
+	movups STATE3, 0x20(OUTP)
+	movups STATE4, 0x30(OUTP)
+	sub $64, LEN
+	add $64, INP
+	add $64, OUTP
+	cmp $64, LEN
+	jge .Lecb_enc_loop4
+	cmp $16, LEN
+	jb .Lecb_enc_ret
+.align 4
+.Lecb_enc_loop1:
+	movups (INP), STATE1
+	call _aesni_enc1
+	movups STATE1, (OUTP)
+	sub $16, LEN
+	add $16, INP
+	add $16, OUTP
+	cmp $16, LEN
+	jge .Lecb_enc_loop1
+.Lecb_enc_ret:
+	ret
+
+/*
+ * void aesni_ecb_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ *		      size_t len);
+ */
+ENTRY(aesni_ecb_dec)
+	test LEN, LEN
+	jz .Lecb_dec_ret
+	mov 480(KEYP), KLEN
+	add $240, KEYP
+	cmp $16, LEN
+	jb .Lecb_dec_ret
+	cmp $64, LEN
+	jb .Lecb_dec_loop1
+.align 4
+.Lecb_dec_loop4:
+	movups (INP), STATE1
+	movups 0x10(INP), STATE2
+	movups 0x20(INP), STATE3
+	movups 0x30(INP), STATE4
+	call _aesni_dec4
+	movups STATE1, (OUTP)
+	movups STATE2, 0x10(OUTP)
+	movups STATE3, 0x20(OUTP)
+	movups STATE4, 0x30(OUTP)
+	sub $64, LEN
+	add $64, INP
+	add $64, OUTP
+	cmp $64, LEN
+	jge .Lecb_dec_loop4
+	cmp $16, LEN
+	jb .Lecb_dec_ret
+.align 4
+.Lecb_dec_loop1:
+	movups (INP), STATE1
+	call _aesni_dec1
+	movups STATE1, (OUTP)
+	sub $16, LEN
+	add $16, INP
+	add $16, OUTP
+	cmp $16, LEN
+	jge .Lecb_dec_loop1
+.Lecb_dec_ret:
+	ret
+
+/*
+ * void aesni_cbc_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ *		      size_t len, u8 *iv)
+ */
+ENTRY(aesni_cbc_enc)
+	cmp $16, LEN
+	jb .Lcbc_enc_ret
+	mov 480(KEYP), KLEN
+	movups (IVP), STATE	# load iv as initial state
+.align 4
+.Lcbc_enc_loop:
+	movups (INP), IN	# load input
+	pxor IN, STATE
+	call _aesni_enc1
+	movups STATE, (OUTP)	# store output
+	sub $16, LEN
+	add $16, INP
+	add $16, OUTP
+	cmp $16, LEN
+	jge .Lcbc_enc_loop
+	movups STATE, (IVP)
+.Lcbc_enc_ret:
+	ret
+
+/*
+ * void aesni_cbc_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ *		      size_t len, u8 *iv)
+ */
+ENTRY(aesni_cbc_dec)
+	cmp $16, LEN
+	jb .Lcbc_dec_ret
+	mov 480(KEYP), KLEN
+	add $240, KEYP
+	movups (IVP), IV
+	cmp $64, LEN
+	jb .Lcbc_dec_loop1
+.align 4
+.Lcbc_dec_loop4:
+	movups (INP), IN1
+	movaps IN1, STATE1
+	movups 0x10(INP), IN2
+	movaps IN2, STATE2
+	movups 0x20(INP), IN3
+	movaps IN3, STATE3
+	movups 0x30(INP), IN4
+	movaps IN4, STATE4
+	call _aesni_dec4
+	pxor IV, STATE1
+	pxor IN1, STATE2
+	pxor IN2, STATE3
+	pxor IN3, STATE4
+	movaps IN4, IV
+	movups STATE1, (OUTP)
+	movups STATE2, 0x10(OUTP)
+	movups STATE3, 0x20(OUTP)
+	movups STATE4, 0x30(OUTP)
+	sub $64, LEN
+	add $64, INP
+	add $64, OUTP
+	cmp $64, LEN
+	jge .Lcbc_dec_loop4
+	cmp $16, LEN
+	jb .Lcbc_dec_ret
+.align 4
+.Lcbc_dec_loop1:
+	movups (INP), IN
+	movaps IN, STATE
+	call _aesni_dec1
+	pxor IV, STATE
+	movups STATE, (OUTP)
+	movaps IN, IV
+	sub $16, LEN
+	add $16, INP
+	add $16, OUTP
+	cmp $16, LEN
+	jge .Lcbc_dec_loop1
+	movups IV, (IVP)
+.Lcbc_dec_ret:
+	ret
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/aesni-intel_glue.c linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_glue.c
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/aesni-intel_glue.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_glue.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,461 @@
+/*
+ * Support for Intel AES-NI instructions. This file contains glue
+ * code, the real AES implementation is in intel-aes_asm.S.
+ *
+ * Copyright (C) 2008, 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/hardirq.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/cryptd.h>
+#include <asm/i387.h>
+#include <asm/aes.h>
+
+struct async_aes_ctx {
+	struct cryptd_ablkcipher *cryptd_tfm;
+};
+
+#define AESNI_ALIGN	16
+#define AES_BLOCK_MASK	(~(AES_BLOCK_SIZE-1))
+
+asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+			     unsigned int key_len);
+asmlinkage void aesni_enc(struct crypto_aes_ctx *ctx, u8 *out,
+			  const u8 *in);
+asmlinkage void aesni_dec(struct crypto_aes_ctx *ctx, u8 *out,
+			  const u8 *in);
+asmlinkage void aesni_ecb_enc(struct crypto_aes_ctx *ctx, u8 *out,
+			      const u8 *in, unsigned int len);
+asmlinkage void aesni_ecb_dec(struct crypto_aes_ctx *ctx, u8 *out,
+			      const u8 *in, unsigned int len);
+asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
+			      const u8 *in, unsigned int len, u8 *iv);
+asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
+			      const u8 *in, unsigned int len, u8 *iv);
+
+static inline int kernel_fpu_using(void)
+{
+	if (in_interrupt() && !(read_cr0() & X86_CR0_TS))
+		return 1;
+	return 0;
+}
+
+static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
+{
+	unsigned long addr = (unsigned long)raw_ctx;
+	unsigned long align = AESNI_ALIGN;
+
+	if (align <= crypto_tfm_ctx_alignment())
+		align = 1;
+	return (struct crypto_aes_ctx *)ALIGN(addr, align);
+}
+
+static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
+			      const u8 *in_key, unsigned int key_len)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(raw_ctx);
+	u32 *flags = &tfm->crt_flags;
+	int err;
+
+	if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 &&
+	    key_len != AES_KEYSIZE_256) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	if (kernel_fpu_using())
+		err = crypto_aes_expand_key(ctx, in_key, key_len);
+	else {
+		kernel_fpu_begin();
+		err = aesni_set_key(ctx, in_key, key_len);
+		kernel_fpu_end();
+	}
+
+	return err;
+}
+
+static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+		       unsigned int key_len)
+{
+	return aes_set_key_common(tfm, crypto_tfm_ctx(tfm), in_key, key_len);
+}
+
+static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+	if (kernel_fpu_using())
+		crypto_aes_encrypt_x86(ctx, dst, src);
+	else {
+		kernel_fpu_begin();
+		aesni_enc(ctx, dst, src);
+		kernel_fpu_end();
+	}
+}
+
+static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+	if (kernel_fpu_using())
+		crypto_aes_decrypt_x86(ctx, dst, src);
+	else {
+		kernel_fpu_begin();
+		aesni_dec(ctx, dst, src);
+		kernel_fpu_end();
+	}
+}
+
+static struct crypto_alg aesni_alg = {
+	.cra_name		= "aes",
+	.cra_driver_name	= "aes-aesni",
+	.cra_priority		= 300,
+	.cra_flags		= CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+	.cra_alignmask		= 0,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(aesni_alg.cra_list),
+	.cra_u	= {
+		.cipher	= {
+			.cia_min_keysize	= AES_MIN_KEY_SIZE,
+			.cia_max_keysize	= AES_MAX_KEY_SIZE,
+			.cia_setkey		= aes_set_key,
+			.cia_encrypt		= aes_encrypt,
+			.cia_decrypt		= aes_decrypt
+		}
+	}
+};
+
+static int ecb_encrypt(struct blkcipher_desc *desc,
+		       struct scatterlist *dst, struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt(desc, &walk);
+
+	kernel_fpu_begin();
+	while ((nbytes = walk.nbytes)) {
+		aesni_ecb_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+			      nbytes & AES_BLOCK_MASK);
+		nbytes &= AES_BLOCK_SIZE - 1;
+		err = blkcipher_walk_done(desc, &walk, nbytes);
+	}
+	kernel_fpu_end();
+
+	return err;
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc,
+		       struct scatterlist *dst, struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt(desc, &walk);
+
+	kernel_fpu_begin();
+	while ((nbytes = walk.nbytes)) {
+		aesni_ecb_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+			      nbytes & AES_BLOCK_MASK);
+		nbytes &= AES_BLOCK_SIZE - 1;
+		err = blkcipher_walk_done(desc, &walk, nbytes);
+	}
+	kernel_fpu_end();
+
+	return err;
+}
+
+static struct crypto_alg blk_ecb_alg = {
+	.cra_name		= "__ecb-aes-aesni",
+	.cra_driver_name	= "__driver-ecb-aes-aesni",
+	.cra_priority		= 0,
+	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_blkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(blk_ecb_alg.cra_list),
+	.cra_u = {
+		.blkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.setkey		= aes_set_key,
+			.encrypt	= ecb_encrypt,
+			.decrypt	= ecb_decrypt,
+		},
+	},
+};
+
+static int cbc_encrypt(struct blkcipher_desc *desc,
+		       struct scatterlist *dst, struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt(desc, &walk);
+
+	kernel_fpu_begin();
+	while ((nbytes = walk.nbytes)) {
+		aesni_cbc_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+			      nbytes & AES_BLOCK_MASK, walk.iv);
+		nbytes &= AES_BLOCK_SIZE - 1;
+		err = blkcipher_walk_done(desc, &walk, nbytes);
+	}
+	kernel_fpu_end();
+
+	return err;
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc,
+		       struct scatterlist *dst, struct scatterlist *src,
+		       unsigned int nbytes)
+{
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+	struct blkcipher_walk walk;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt(desc, &walk);
+
+	kernel_fpu_begin();
+	while ((nbytes = walk.nbytes)) {
+		aesni_cbc_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+			      nbytes & AES_BLOCK_MASK, walk.iv);
+		nbytes &= AES_BLOCK_SIZE - 1;
+		err = blkcipher_walk_done(desc, &walk, nbytes);
+	}
+	kernel_fpu_end();
+
+	return err;
+}
+
+static struct crypto_alg blk_cbc_alg = {
+	.cra_name		= "__cbc-aes-aesni",
+	.cra_driver_name	= "__driver-cbc-aes-aesni",
+	.cra_priority		= 0,
+	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_blkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(blk_cbc_alg.cra_list),
+	.cra_u = {
+		.blkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.setkey		= aes_set_key,
+			.encrypt	= cbc_encrypt,
+			.decrypt	= cbc_decrypt,
+		},
+	},
+};
+
+static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
+			unsigned int key_len)
+{
+	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+	return crypto_ablkcipher_setkey(&ctx->cryptd_tfm->base, key, key_len);
+}
+
+static int ablk_encrypt(struct ablkcipher_request *req)
+{
+	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+	if (kernel_fpu_using()) {
+		struct ablkcipher_request *cryptd_req =
+			ablkcipher_request_ctx(req);
+		memcpy(cryptd_req, req, sizeof(*req));
+		ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+		return crypto_ablkcipher_encrypt(cryptd_req);
+	} else {
+		struct blkcipher_desc desc;
+		desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+		desc.info = req->info;
+		desc.flags = 0;
+		return crypto_blkcipher_crt(desc.tfm)->encrypt(
+			&desc, req->dst, req->src, req->nbytes);
+	}
+}
+
+static int ablk_decrypt(struct ablkcipher_request *req)
+{
+	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+	if (kernel_fpu_using()) {
+		struct ablkcipher_request *cryptd_req =
+			ablkcipher_request_ctx(req);
+		memcpy(cryptd_req, req, sizeof(*req));
+		ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+		return crypto_ablkcipher_decrypt(cryptd_req);
+	} else {
+		struct blkcipher_desc desc;
+		desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+		desc.info = req->info;
+		desc.flags = 0;
+		return crypto_blkcipher_crt(desc.tfm)->decrypt(
+			&desc, req->dst, req->src, req->nbytes);
+	}
+}
+
+static void ablk_exit(struct crypto_tfm *tfm)
+{
+	struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	cryptd_free_ablkcipher(ctx->cryptd_tfm);
+}
+
+static void ablk_init_common(struct crypto_tfm *tfm,
+			     struct cryptd_ablkcipher *cryptd_tfm)
+{
+	struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->cryptd_tfm = cryptd_tfm;
+	tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) +
+		crypto_ablkcipher_reqsize(&cryptd_tfm->base);
+}
+
+static int ablk_ecb_init(struct crypto_tfm *tfm)
+{
+	struct cryptd_ablkcipher *cryptd_tfm;
+
+	cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ecb-aes-aesni", 0, 0);
+	if (IS_ERR(cryptd_tfm))
+		return PTR_ERR(cryptd_tfm);
+	ablk_init_common(tfm, cryptd_tfm);
+	return 0;
+}
+
+static struct crypto_alg ablk_ecb_alg = {
+	.cra_name		= "ecb(aes)",
+	.cra_driver_name	= "ecb-aes-aesni",
+	.cra_priority		= 400,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct async_aes_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(ablk_ecb_alg.cra_list),
+	.cra_init		= ablk_ecb_init,
+	.cra_exit		= ablk_exit,
+	.cra_u = {
+		.ablkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.setkey		= ablk_set_key,
+			.encrypt	= ablk_encrypt,
+			.decrypt	= ablk_decrypt,
+		},
+	},
+};
+
+static int ablk_cbc_init(struct crypto_tfm *tfm)
+{
+	struct cryptd_ablkcipher *cryptd_tfm;
+
+	cryptd_tfm = cryptd_alloc_ablkcipher("__driver-cbc-aes-aesni", 0, 0);
+	if (IS_ERR(cryptd_tfm))
+		return PTR_ERR(cryptd_tfm);
+	ablk_init_common(tfm, cryptd_tfm);
+	return 0;
+}
+
+static struct crypto_alg ablk_cbc_alg = {
+	.cra_name		= "cbc(aes)",
+	.cra_driver_name	= "cbc-aes-aesni",
+	.cra_priority		= 400,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct async_aes_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(ablk_cbc_alg.cra_list),
+	.cra_init		= ablk_cbc_init,
+	.cra_exit		= ablk_exit,
+	.cra_u = {
+		.ablkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.ivsize		= AES_BLOCK_SIZE,
+			.setkey		= ablk_set_key,
+			.encrypt	= ablk_encrypt,
+			.decrypt	= ablk_decrypt,
+		},
+	},
+};
+
+static int __init aesni_init(void)
+{
+	int err;
+
+	if (!cpu_has_aes) {
+		printk(KERN_ERR "Intel AES-NI instructions are not detected.\n");
+		return -ENODEV;
+	}
+	if ((err = crypto_register_alg(&aesni_alg)))
+		goto aes_err;
+	if ((err = crypto_register_alg(&blk_ecb_alg)))
+		goto blk_ecb_err;
+	if ((err = crypto_register_alg(&blk_cbc_alg)))
+		goto blk_cbc_err;
+	if ((err = crypto_register_alg(&ablk_ecb_alg)))
+		goto ablk_ecb_err;
+	if ((err = crypto_register_alg(&ablk_cbc_alg)))
+		goto ablk_cbc_err;
+
+	return err;
+
+ablk_cbc_err:
+	crypto_unregister_alg(&ablk_ecb_alg);
+ablk_ecb_err:
+	crypto_unregister_alg(&blk_cbc_alg);
+blk_cbc_err:
+	crypto_unregister_alg(&blk_ecb_alg);
+blk_ecb_err:
+	crypto_unregister_alg(&aesni_alg);
+aes_err:
+	return err;
+}
+
+static void __exit aesni_exit(void)
+{
+	crypto_unregister_alg(&ablk_cbc_alg);
+	crypto_unregister_alg(&ablk_ecb_alg);
+	crypto_unregister_alg(&blk_cbc_alg);
+	crypto_unregister_alg(&blk_ecb_alg);
+	crypto_unregister_alg(&aesni_alg);
+}
+
+module_init(aesni_init);
+module_exit(aesni_exit);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("aes");
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/aes-x86_64-asm_64.S linux-libre-2.6.30-gnu1/arch/x86/crypto/aes-x86_64-asm_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/aes-x86_64-asm_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/aes-x86_64-asm_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -17,8 +17,6 @@
 
 #include <asm/asm-offsets.h>
 
-#define BASE crypto_tfm_ctx_offset
-
 #define R1	%rax
 #define R1E	%eax
 #define R1X	%ax
@@ -56,13 +54,13 @@
 	.align	8;			\
 FUNC:	movq	r1,r2;			\
 	movq	r3,r4;			\
-	leaq	BASE+KEY+48+4(r8),r9;	\
+	leaq	KEY+48(r8),r9;		\
 	movq	r10,r11;		\
 	movl	(r7),r5 ## E;		\
 	movl	4(r7),r1 ## E;		\
 	movl	8(r7),r6 ## E;		\
 	movl	12(r7),r7 ## E;		\
-	movl	BASE+0(r8),r10 ## E;	\
+	movl	480(r8),r10 ## E;	\
 	xorl	-48(r9),r5 ## E;	\
 	xorl	-44(r9),r1 ## E;	\
 	xorl	-40(r9),r6 ## E;	\
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/crypto/Makefile linux-libre-2.6.30-gnu1/arch/x86/crypto/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/crypto/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/crypto/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@ obj-$(CONFIG_CRYPTO_SALSA20_586) += sals
 obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
 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_CRC32C_INTEL) += crc32c-intel.o
 
@@ -19,3 +20,5 @@ salsa20-i586-y := salsa20-i586-asm_32.o
 aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
 twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
 salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
+
+aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/ia32/ia32entry.S linux-libre-2.6.30-gnu1/arch/x86/ia32/ia32entry.S
--- linux-libre-2.6.29-gnu1/arch/x86/ia32/ia32entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/ia32/ia32entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -112,8 +112,8 @@ ENTRY(ia32_sysenter_target)
 	CFI_DEF_CFA	rsp,0
 	CFI_REGISTER	rsp,rbp
 	SWAPGS_UNSAFE_STACK
-	movq	%gs:pda_kernelstack, %rsp
-	addq	$(PDA_STACKOFFSET),%rsp	
+	movq	PER_CPU_VAR(kernel_stack), %rsp
+	addq	$(KERNEL_STACK_OFFSET),%rsp
 	/*
 	 * No need to follow this irqs on/off section: the syscall
 	 * disabled irqs, here we enable it straight after entry:
@@ -273,13 +273,13 @@ ENDPROC(ia32_sysenter_target)
 ENTRY(ia32_cstar_target)
 	CFI_STARTPROC32	simple
 	CFI_SIGNAL_FRAME
-	CFI_DEF_CFA	rsp,PDA_STACKOFFSET
+	CFI_DEF_CFA	rsp,KERNEL_STACK_OFFSET
 	CFI_REGISTER	rip,rcx
 	/*CFI_REGISTER	rflags,r11*/
 	SWAPGS_UNSAFE_STACK
 	movl	%esp,%r8d
 	CFI_REGISTER	rsp,r8
-	movq	%gs:pda_kernelstack,%rsp
+	movq	PER_CPU_VAR(kernel_stack),%rsp
 	/*
 	 * No need to follow this irqs on/off section: the syscall
 	 * disabled irqs and here we enable it straight after entry:
@@ -557,7 +557,7 @@ ia32_sys_call_table:
 	.quad sys32_olduname
 	.quad sys_umask		/* 60 */
 	.quad sys_chroot
-	.quad sys32_ustat
+	.quad compat_sys_ustat
 	.quad sys_dup2
 	.quad sys_getppid
 	.quad sys_getpgrp		/* 65 */
@@ -828,4 +828,6 @@ ia32_sys_call_table:
 	.quad sys_dup3			/* 330 */
 	.quad sys_pipe2
 	.quad sys_inotify_init1
+	.quad compat_sys_preadv
+	.quad compat_sys_pwritev
 ia32_syscall_end:
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/ia32/ia32_signal.c linux-libre-2.6.30-gnu1/arch/x86/ia32/ia32_signal.c
--- linux-libre-2.6.29-gnu1/arch/x86/ia32/ia32_signal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/ia32/ia32_signal.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,8 +33,6 @@
 #include <asm/sigframe.h>
 #include <asm/sys_ia32.h>
 
-#define DEBUG_SIG 0
-
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 #define FIX_EFLAGS	(X86_EFLAGS_AC | X86_EFLAGS_OF | \
@@ -46,78 +44,83 @@ void signal_fault(struct pt_regs *regs,
 
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
-	int err;
+	int err = 0;
 
 	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
-	/* If you change siginfo_t structure, please make sure that
-	   this code is fixed accordingly.
-	   It should never copy any pad contained in the structure
-	   to avoid security leaks, but must copy the generic
-	   3 ints plus the relevant union member.  */
-	err = __put_user(from->si_signo, &to->si_signo);
-	err |= __put_user(from->si_errno, &to->si_errno);
-	err |= __put_user((short)from->si_code, &to->si_code);
+	put_user_try {
+		/* If you change siginfo_t structure, please make sure that
+		   this code is fixed accordingly.
+		   It should never copy any pad contained in the structure
+		   to avoid security leaks, but must copy the generic
+		   3 ints plus the relevant union member.  */
+		put_user_ex(from->si_signo, &to->si_signo);
+		put_user_ex(from->si_errno, &to->si_errno);
+		put_user_ex((short)from->si_code, &to->si_code);
 
-	if (from->si_code < 0) {
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
-	} else {
-		/*
-		 * First 32bits of unions are always present:
-		 * si_pid === si_band === si_tid === si_addr(LS half)
-		 */
-		err |= __put_user(from->_sifields._pad[0],
-				  &to->_sifields._pad[0]);
-		switch (from->si_code >> 16) {
-		case __SI_FAULT >> 16:
-			break;
-		case __SI_CHLD >> 16:
-			err |= __put_user(from->si_utime, &to->si_utime);
-			err |= __put_user(from->si_stime, &to->si_stime);
-			err |= __put_user(from->si_status, &to->si_status);
-			/* FALL THROUGH */
-		default:
-		case __SI_KILL >> 16:
-			err |= __put_user(from->si_uid, &to->si_uid);
-			break;
-		case __SI_POLL >> 16:
-			err |= __put_user(from->si_fd, &to->si_fd);
-			break;
-		case __SI_TIMER >> 16:
-			err |= __put_user(from->si_overrun, &to->si_overrun);
-			err |= __put_user(ptr_to_compat(from->si_ptr),
-					  &to->si_ptr);
-			break;
-			 /* This is not generated by the kernel as of now.  */
-		case __SI_RT >> 16:
-		case __SI_MESGQ >> 16:
-			err |= __put_user(from->si_uid, &to->si_uid);
-			err |= __put_user(from->si_int, &to->si_int);
-			break;
+		if (from->si_code < 0) {
+			put_user_ex(from->si_pid, &to->si_pid);
+			put_user_ex(from->si_uid, &to->si_uid);
+			put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
+		} else {
+			/*
+			 * First 32bits of unions are always present:
+			 * si_pid === si_band === si_tid === si_addr(LS half)
+			 */
+			put_user_ex(from->_sifields._pad[0],
+					  &to->_sifields._pad[0]);
+			switch (from->si_code >> 16) {
+			case __SI_FAULT >> 16:
+				break;
+			case __SI_CHLD >> 16:
+				put_user_ex(from->si_utime, &to->si_utime);
+				put_user_ex(from->si_stime, &to->si_stime);
+				put_user_ex(from->si_status, &to->si_status);
+				/* FALL THROUGH */
+			default:
+			case __SI_KILL >> 16:
+				put_user_ex(from->si_uid, &to->si_uid);
+				break;
+			case __SI_POLL >> 16:
+				put_user_ex(from->si_fd, &to->si_fd);
+				break;
+			case __SI_TIMER >> 16:
+				put_user_ex(from->si_overrun, &to->si_overrun);
+				put_user_ex(ptr_to_compat(from->si_ptr),
+					    &to->si_ptr);
+				break;
+				 /* This is not generated by the kernel as of now.  */
+			case __SI_RT >> 16:
+			case __SI_MESGQ >> 16:
+				put_user_ex(from->si_uid, &to->si_uid);
+				put_user_ex(from->si_int, &to->si_int);
+				break;
+			}
 		}
-	}
+	} put_user_catch(err);
+
 	return err;
 }
 
 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 {
-	int err;
+	int err = 0;
 	u32 ptr32;
 
 	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
 		return -EFAULT;
 
-	err = __get_user(to->si_signo, &from->si_signo);
-	err |= __get_user(to->si_errno, &from->si_errno);
-	err |= __get_user(to->si_code, &from->si_code);
+	get_user_try {
+		get_user_ex(to->si_signo, &from->si_signo);
+		get_user_ex(to->si_errno, &from->si_errno);
+		get_user_ex(to->si_code, &from->si_code);
 
-	err |= __get_user(to->si_pid, &from->si_pid);
-	err |= __get_user(to->si_uid, &from->si_uid);
-	err |= __get_user(ptr32, &from->si_ptr);
-	to->si_ptr = compat_ptr(ptr32);
+		get_user_ex(to->si_pid, &from->si_pid);
+		get_user_ex(to->si_uid, &from->si_uid);
+		get_user_ex(ptr32, &from->si_ptr);
+		to->si_ptr = compat_ptr(ptr32);
+	} get_user_catch(err);
 
 	return err;
 }
@@ -142,17 +145,23 @@ asmlinkage long sys32_sigaltstack(const
 				  struct pt_regs *regs)
 {
 	stack_t uss, uoss;
-	int ret;
+	int ret, err = 0;
 	mm_segment_t seg;
 
 	if (uss_ptr) {
 		u32 ptr;
 
 		memset(&uss, 0, sizeof(stack_t));
-		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
-			    __get_user(ptr, &uss_ptr->ss_sp) ||
-			    __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
-			    __get_user(uss.ss_size, &uss_ptr->ss_size))
+		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
+			return -EFAULT;
+
+		get_user_try {
+			get_user_ex(ptr, &uss_ptr->ss_sp);
+			get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
+			get_user_ex(uss.ss_size, &uss_ptr->ss_size);
+		} get_user_catch(err);
+
+		if (err)
 			return -EFAULT;
 		uss.ss_sp = compat_ptr(ptr);
 	}
@@ -161,10 +170,16 @@ asmlinkage long sys32_sigaltstack(const
 	ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
 	set_fs(seg);
 	if (ret >= 0 && uoss_ptr)  {
-		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
-		    __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
-		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
-		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
+			return -EFAULT;
+
+		put_user_try {
+			put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
+			put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
+			put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
+		} put_user_catch(err);
+
+		if (err)
 			ret = -EFAULT;
 	}
 	return ret;
@@ -173,75 +188,78 @@ asmlinkage long sys32_sigaltstack(const
 /*
  * Do a signal return; undo the signal stack.
  */
+#define loadsegment_gs(v)	load_gs_index(v)
+#define loadsegment_fs(v)	loadsegment(fs, v)
+#define loadsegment_ds(v)	loadsegment(ds, v)
+#define loadsegment_es(v)	loadsegment(es, v)
+
+#define get_user_seg(seg)	({ unsigned int v; savesegment(seg, v); v; })
+#define set_user_seg(seg, v)	loadsegment_##seg(v)
+
 #define COPY(x)			{		\
-	err |= __get_user(regs->x, &sc->x);	\
+	get_user_ex(regs->x, &sc->x);		\
 }
 
-#define COPY_SEG_CPL3(seg)	{			\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		regs->seg = tmp | 3;			\
-}
+#define GET_SEG(seg)		({			\
+	unsigned short tmp;				\
+	get_user_ex(tmp, &sc->seg);			\
+	tmp;						\
+})
+
+#define COPY_SEG_CPL3(seg)	do {			\
+	regs->seg = GET_SEG(seg) | 3;			\
+} while (0)
 
 #define RELOAD_SEG(seg)		{		\
-	unsigned int cur, pre;			\
-	err |= __get_user(pre, &sc->seg);	\
-	savesegment(seg, cur);			\
+	unsigned int pre = GET_SEG(seg);	\
+	unsigned int cur = get_user_seg(seg);	\
 	pre |= 3;				\
 	if (pre != cur)				\
-		loadsegment(seg, pre);		\
+		set_user_seg(seg, pre);		\
 }
 
 static int ia32_restore_sigcontext(struct pt_regs *regs,
 				   struct sigcontext_ia32 __user *sc,
 				   unsigned int *pax)
 {
-	unsigned int tmpflags, gs, oldgs, err = 0;
+	unsigned int tmpflags, err = 0;
 	void __user *buf;
 	u32 tmp;
 
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-#if DEBUG_SIG
-	printk(KERN_DEBUG "SIG restore_sigcontext: "
-	       "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
-	       sc, sc->err, sc->ip, sc->cs, sc->flags);
-#endif
-
-	/*
-	 * Reload fs and gs if they have changed in the signal
-	 * handler.  This does not handle long fs/gs base changes in
-	 * the handler, but does not clobber them at least in the
-	 * normal case.
-	 */
-	err |= __get_user(gs, &sc->gs);
-	gs |= 3;
-	savesegment(gs, oldgs);
-	if (gs != oldgs)
-		load_gs_index(gs);
+	get_user_try {
+		/*
+		 * Reload fs and gs if they have changed in the signal
+		 * handler.  This does not handle long fs/gs base changes in
+		 * the handler, but does not clobber them at least in the
+		 * normal case.
+		 */
+		RELOAD_SEG(gs);
+		RELOAD_SEG(fs);
+		RELOAD_SEG(ds);
+		RELOAD_SEG(es);
 
-	RELOAD_SEG(fs);
-	RELOAD_SEG(ds);
-	RELOAD_SEG(es);
+		COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
+		COPY(dx); COPY(cx); COPY(ip);
+		/* Don't touch extended registers */
 
-	COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
-	COPY(dx); COPY(cx); COPY(ip);
-	/* Don't touch extended registers */
+		COPY_SEG_CPL3(cs);
+		COPY_SEG_CPL3(ss);
 
-	COPY_SEG_CPL3(cs);
-	COPY_SEG_CPL3(ss);
+		get_user_ex(tmpflags, &sc->flags);
+		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
+		/* disable syscall checks */
+		regs->orig_ax = -1;
 
-	err |= __get_user(tmpflags, &sc->flags);
-	regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
-	/* disable syscall checks */
-	regs->orig_ax = -1;
+		get_user_ex(tmp, &sc->fpstate);
+		buf = compat_ptr(tmp);
+		err |= restore_i387_xstate_ia32(buf);
 
-	err |= __get_user(tmp, &sc->fpstate);
-	buf = compat_ptr(tmp);
-	err |= restore_i387_xstate_ia32(buf);
+		get_user_ex(*pax, &sc->ax);
+	} get_user_catch(err);
 
-	err |= __get_user(*pax, &sc->ax);
 	return err;
 }
 
@@ -317,38 +335,36 @@ static int ia32_setup_sigcontext(struct
 				 void __user *fpstate,
 				 struct pt_regs *regs, unsigned int mask)
 {
-	int tmp, err = 0;
+	int err = 0;
 
-	savesegment(gs, tmp);
-	err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
-	savesegment(fs, tmp);
-	err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
-	savesegment(ds, tmp);
-	err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
-	savesegment(es, tmp);
-	err |= __put_user(tmp, (unsigned int __user *)&sc->es);
+	put_user_try {
+		put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
+		put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
+		put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
+		put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
 
-	err |= __put_user(regs->di, &sc->di);
-	err |= __put_user(regs->si, &sc->si);
-	err |= __put_user(regs->bp, &sc->bp);
-	err |= __put_user(regs->sp, &sc->sp);
-	err |= __put_user(regs->bx, &sc->bx);
-	err |= __put_user(regs->dx, &sc->dx);
-	err |= __put_user(regs->cx, &sc->cx);
-	err |= __put_user(regs->ax, &sc->ax);
-	err |= __put_user(current->thread.trap_no, &sc->trapno);
-	err |= __put_user(current->thread.error_code, &sc->err);
-	err |= __put_user(regs->ip, &sc->ip);
-	err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
-	err |= __put_user(regs->flags, &sc->flags);
-	err |= __put_user(regs->sp, &sc->sp_at_signal);
-	err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
+		put_user_ex(regs->di, &sc->di);
+		put_user_ex(regs->si, &sc->si);
+		put_user_ex(regs->bp, &sc->bp);
+		put_user_ex(regs->sp, &sc->sp);
+		put_user_ex(regs->bx, &sc->bx);
+		put_user_ex(regs->dx, &sc->dx);
+		put_user_ex(regs->cx, &sc->cx);
+		put_user_ex(regs->ax, &sc->ax);
+		put_user_ex(current->thread.trap_no, &sc->trapno);
+		put_user_ex(current->thread.error_code, &sc->err);
+		put_user_ex(regs->ip, &sc->ip);
+		put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
+		put_user_ex(regs->flags, &sc->flags);
+		put_user_ex(regs->sp, &sc->sp_at_signal);
+		put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
 
-	err |= __put_user(ptr_to_compat(fpstate), &sc->fpstate);
+		put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
 
-	/* non-iBCS2 extensions.. */
-	err |= __put_user(mask, &sc->oldmask);
-	err |= __put_user(current->thread.cr2, &sc->cr2);
+		/* non-iBCS2 extensions.. */
+		put_user_ex(mask, &sc->oldmask);
+		put_user_ex(current->thread.cr2, &sc->cr2);
+	} put_user_catch(err);
 
 	return err;
 }
@@ -437,13 +453,17 @@ int ia32_setup_frame(int sig, struct k_s
 		else
 			restorer = &frame->retcode;
 	}
-	err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
 
-	/*
-	 * These are actually not used anymore, but left because some
-	 * gdb versions depend on them as a marker.
-	 */
-	err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
+	put_user_try {
+		put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
+
+		/*
+		 * These are actually not used anymore, but left because some
+		 * gdb versions depend on them as a marker.
+		 */
+		put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
+	} put_user_catch(err);
+
 	if (err)
 		return -EFAULT;
 
@@ -462,11 +482,6 @@ int ia32_setup_frame(int sig, struct k_s
 	regs->cs = __USER32_CS;
 	regs->ss = __USER32_DS;
 
-#if DEBUG_SIG
-	printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
-	       current->comm, current->pid, frame, regs->ip, frame->pretcode);
-#endif
-
 	return 0;
 }
 
@@ -496,41 +511,40 @@ int ia32_setup_rt_frame(int sig, struct
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		return -EFAULT;
 
-	err |= __put_user(sig, &frame->sig);
-	err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
-	err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
-	err |= copy_siginfo_to_user32(&frame->info, info);
-	if (err)
-		return -EFAULT;
+	put_user_try {
+		put_user_ex(sig, &frame->sig);
+		put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
+		put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
+		err |= copy_siginfo_to_user32(&frame->info, info);
 
-	/* Create the ucontext.  */
-	if (cpu_has_xsave)
-		err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
-	else
-		err |= __put_user(0, &frame->uc.uc_flags);
-	err |= __put_user(0, &frame->uc.uc_link);
-	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->sp),
-			  &frame->uc.uc_stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
-				     regs, set->sig[0]);
-	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
-	if (err)
-		return -EFAULT;
+		/* Create the ucontext.  */
+		if (cpu_has_xsave)
+			put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
+		else
+			put_user_ex(0, &frame->uc.uc_flags);
+		put_user_ex(0, &frame->uc.uc_link);
+		put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+		put_user_ex(sas_ss_flags(regs->sp),
+			    &frame->uc.uc_stack.ss_flags);
+		put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+		err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
+					     regs, set->sig[0]);
+		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-	if (ka->sa.sa_flags & SA_RESTORER)
-		restorer = ka->sa.sa_restorer;
-	else
-		restorer = VDSO32_SYMBOL(current->mm->context.vdso,
-					 rt_sigreturn);
-	err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
+		if (ka->sa.sa_flags & SA_RESTORER)
+			restorer = ka->sa.sa_restorer;
+		else
+			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+						 rt_sigreturn);
+		put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
+
+		/*
+		 * Not actually used anymore, but left because some gdb
+		 * versions need it.
+		 */
+		put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
+	} put_user_catch(err);
 
-	/*
-	 * Not actually used anymore, but left because some gdb
-	 * versions need it.
-	 */
-	err |= __put_user(*((u64 *)&code), (u64 *)frame->retcode);
 	if (err)
 		return -EFAULT;
 
@@ -549,10 +563,5 @@ int ia32_setup_rt_frame(int sig, struct
 	regs->cs = __USER32_CS;
 	regs->ss = __USER32_DS;
 
-#if DEBUG_SIG
-	printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
-	       current->comm, current->pid, frame, regs->ip, frame->pretcode);
-#endif
-
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/ia32/sys_ia32.c linux-libre-2.6.30-gnu1/arch/x86/ia32/sys_ia32.c
--- linux-libre-2.6.29-gnu1/arch/x86/ia32/sys_ia32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/ia32/sys_ia32.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,21 +129,12 @@ asmlinkage long sys32_fstatat(unsigned i
 			      struct stat64 __user *statbuf, int flag)
 {
 	struct kstat stat;
-	int error = -EINVAL;
-
-	if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
-		goto out;
-
-	if (flag & AT_SYMLINK_NOFOLLOW)
-		error = vfs_lstat_fd(dfd, filename, &stat);
-	else
-		error = vfs_stat_fd(dfd, filename, &stat);
-
-	if (!error)
-		error = cp_stat64(statbuf, &stat);
+	int error;
 
-out:
-	return error;
+	error = vfs_fstatat(dfd, filename, &stat, flag);
+	if (error)
+		return error;
+	return cp_stat64(statbuf, &stat);
 }
 
 /*
@@ -638,28 +629,6 @@ long sys32_uname(struct old_utsname __us
 	return err ? -EFAULT : 0;
 }
 
-long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
-{
-	struct ustat u;
-	mm_segment_t seg;
-	int ret;
-
-	seg = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_ustat(dev, (struct ustat __user *)&u);
-	set_fs(seg);
-	if (ret < 0)
-		return ret;
-
-	if (!access_ok(VERIFY_WRITE, u32p, sizeof(struct ustat32)) ||
-	    __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||
-	    __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||
-	    __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||
-	    __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))
-		ret = -EFAULT;
-	return ret;
-}
-
 asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
 			     compat_uptr_t __user *envp, struct pt_regs *regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/acpi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/acpi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/acpi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/acpi.h	2009-06-09 23:05:27.000000000 -0400
@@ -102,9 +102,6 @@ static inline void disable_acpi(void)
 	acpi_noirq = 1;
 }
 
-/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
-#define FIX_ACPI_PAGES 4
-
 extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
 
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/aes.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/aes.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/aes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/aes.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+#ifndef ASM_X86_AES_H
+#define ASM_X86_AES_H
+
+#include <linux/crypto.h>
+#include <crypto/aes.h>
+
+void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst,
+			    const u8 *src);
+void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst,
+			    const u8 *src);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/a.out-core.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/a.out-core.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/a.out-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/a.out-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -55,7 +55,7 @@ static inline void aout_dump_thread(stru
 	dump->regs.ds = (u16)regs->ds;
 	dump->regs.es = (u16)regs->es;
 	dump->regs.fs = (u16)regs->fs;
-	savesegment(gs, dump->regs.gs);
+	dump->regs.gs = get_user_gs(regs);
 	dump->regs.orig_ax = regs->orig_ax;
 	dump->regs.ip = regs->ip;
 	dump->regs.cs = (u16)regs->cs;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/apicdef.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,7 @@
 #define		APIC_ESR_SENDILL	0x00020
 #define		APIC_ESR_RECVILL	0x00040
 #define		APIC_ESR_ILLREGA	0x00080
+#define 	APIC_LVTCMCI	0x2f0
 #define	APIC_ICR	0x300
 #define		APIC_DEST_SELF		0x40000
 #define		APIC_DEST_ALLINC	0x80000
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/apic.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,15 +1,18 @@
 #ifndef _ASM_X86_APIC_H
 #define _ASM_X86_APIC_H
 
-#include <linux/pm.h>
+#include <linux/cpumask.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 
 #include <asm/alternative.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
+#include <asm/cpufeature.h>
 #include <asm/processor.h>
+#include <asm/apicdef.h>
+#include <asm/atomic.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
 #include <asm/system.h>
-#include <asm/cpufeature.h>
 #include <asm/msr.h>
 
 #define ARCH_APICTIMER_STOPS_ON_C3	1
@@ -33,7 +36,13 @@
 	} while (0)
 
 
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
 extern void generic_apic_probe(void);
+#else
+static inline void generic_apic_probe(void)
+{
+}
+#endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
@@ -41,6 +50,21 @@ extern unsigned int apic_verbosity;
 extern int local_apic_timer_c2_ok;
 
 extern int disable_apic;
+
+#ifdef CONFIG_SMP
+extern void __inquire_remote_apic(int apicid);
+#else /* CONFIG_SMP */
+static inline void __inquire_remote_apic(int apicid)
+{
+}
+#endif /* CONFIG_SMP */
+
+static inline void default_inquire_remote_apic(int apicid)
+{
+	if (apic_verbosity >= APIC_DEBUG)
+		__inquire_remote_apic(apicid);
+}
+
 /*
  * Basic functions accessing APICs.
  */
@@ -51,7 +75,14 @@ extern int disable_apic;
 #define setup_secondary_clock setup_secondary_APIC_clock
 #endif
 
+#ifdef CONFIG_X86_64
 extern int is_vsmp_box(void);
+#else
+static inline int is_vsmp_box(void)
+{
+	return 0;
+}
+#endif
 extern void xapic_wait_icr_idle(void);
 extern u32 safe_xapic_wait_icr_idle(void);
 extern void xapic_icr_write(u32, u32);
@@ -71,6 +102,25 @@ static inline u32 native_apic_mem_read(u
 	return *((volatile u32 *)(APIC_BASE + reg));
 }
 
+extern void native_apic_wait_icr_idle(void);
+extern u32 native_safe_apic_wait_icr_idle(void);
+extern void native_apic_icr_write(u32 low, u32 id);
+extern u64 native_apic_icr_read(void);
+
+#define EIM_8BIT_APIC_ID	0
+#define EIM_32BIT_APIC_ID	1
+
+#ifdef CONFIG_X86_X2APIC
+/*
+ * Make previous memory operations globally visible before
+ * sending the IPI through x2apic wrmsr. We need a serializing instruction or
+ * mfence for this.
+ */
+static inline void x2apic_wrmsr_fence(void)
+{
+	asm volatile("mfence" : : : "memory");
+}
+
 static inline void native_apic_msr_write(u32 reg, u32 v)
 {
 	if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
@@ -91,8 +141,32 @@ static inline u32 native_apic_msr_read(u
 	return low;
 }
 
-#ifndef CONFIG_X86_32
-extern int x2apic;
+static inline void native_x2apic_wait_icr_idle(void)
+{
+	/* no need to wait for icr idle in x2apic */
+	return;
+}
+
+static inline u32 native_safe_x2apic_wait_icr_idle(void)
+{
+	/* no need to wait for icr idle in x2apic */
+	return 0;
+}
+
+static inline void native_x2apic_icr_write(u32 low, u32 id)
+{
+	wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
+}
+
+static inline u64 native_x2apic_icr_read(void)
+{
+	unsigned long val;
+
+	rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
+	return val;
+}
+
+extern int x2apic, x2apic_phys;
 extern void check_x2apic(void);
 extern void enable_x2apic(void);
 extern void enable_IR_x2apic(void);
@@ -110,30 +184,27 @@ static inline int x2apic_enabled(void)
 	return 0;
 }
 #else
-#define x2apic_enabled()	0
-#endif
-
-struct apic_ops {
-	u32 (*read)(u32 reg);
-	void (*write)(u32 reg, u32 v);
-	u64 (*icr_read)(void);
-	void (*icr_write)(u32 low, u32 high);
-	void (*wait_icr_idle)(void);
-	u32 (*safe_wait_icr_idle)(void);
-};
+static inline void check_x2apic(void)
+{
+}
+static inline void enable_x2apic(void)
+{
+}
+static inline void enable_IR_x2apic(void)
+{
+}
+static inline int x2apic_enabled(void)
+{
+	return 0;
+}
 
-extern struct apic_ops *apic_ops;
+#define	x2apic	0
 
-#define apic_read (apic_ops->read)
-#define apic_write (apic_ops->write)
-#define apic_icr_read (apic_ops->icr_read)
-#define apic_icr_write (apic_ops->icr_write)
-#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
-#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle)
+#endif
 
 extern int get_physical_broadcast(void);
 
-#ifdef CONFIG_X86_64
+#ifdef CONFIG_X86_X2APIC
 static inline void ack_x2APIC_irq(void)
 {
 	/* Docs say use 0 for future compatibility */
@@ -141,18 +212,6 @@ static inline void ack_x2APIC_irq(void)
 }
 #endif
 
-
-static inline void ack_APIC_irq(void)
-{
-	/*
-	 * ack_APIC_irq() actually gets compiled as a single instruction
-	 * ... yummie.
-	 */
-
-	/* Docs say use 0 for future compatibility */
-	apic_write(APIC_EOI, 0);
-}
-
 extern int lapic_get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void connect_bsp_APIC(void);
@@ -196,4 +255,329 @@ static inline void disable_local_APIC(vo
 
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
+#ifdef CONFIG_X86_64
+#define	SET_APIC_ID(x)		(apic->set_apic_id(x))
+#else
+
+#endif
+
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic APIC sub-arch data struct.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ */
+struct apic {
+	char *name;
+
+	int (*probe)(void);
+	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
+	int (*apic_id_registered)(void);
+
+	u32 irq_delivery_mode;
+	u32 irq_dest_mode;
+
+	const struct cpumask *(*target_cpus)(void);
+
+	int disable_esr;
+
+	int dest_logical;
+	unsigned long (*check_apicid_used)(physid_mask_t bitmap, 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 (*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 (*setup_portio_remap)(void);
+	int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
+	void (*enable_apic_mode)(void);
+	int (*phys_pkg_id)(int cpuid_apic, int index_msb);
+
+	/*
+	 * When one of the next two hooks returns 1 the apic
+	 * is switched to this. Essentially they are additional
+	 * probe functions:
+	 */
+	int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid);
+
+	unsigned int (*get_apic_id)(unsigned long x);
+	unsigned long (*set_apic_id)(unsigned int id);
+	unsigned long apic_id_mask;
+
+	unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
+	unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
+					       const struct cpumask *andmask);
+
+	/* ipi */
+	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
+	void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
+					 int vector);
+	void (*send_IPI_allbutself)(int vector);
+	void (*send_IPI_all)(int vector);
+	void (*send_IPI_self)(int vector);
+
+	/* wakeup_secondary_cpu */
+	int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
+
+	int trampoline_phys_low;
+	int trampoline_phys_high;
+
+	void (*wait_for_init_deassert)(atomic_t *deassert);
+	void (*smp_callin_clear_local_apic)(void);
+	void (*inquire_remote_apic)(int apicid);
+
+	/* apic ops */
+	u32 (*read)(u32 reg);
+	void (*write)(u32 reg, u32 v);
+	u64 (*icr_read)(void);
+	void (*icr_write)(u32 low, u32 high);
+	void (*wait_icr_idle)(void);
+	u32 (*safe_wait_icr_idle)(void);
+};
+
+/*
+ * Pointer to the local APIC driver in use on this system (there's
+ * always just one such driver in use - the kernel decides via an
+ * early probing process which one it picks - and then sticks to it):
+ */
+extern struct apic *apic;
+
+/*
+ * APIC functionality to boot other CPUs - only used on SMP:
+ */
+#ifdef CONFIG_SMP
+extern atomic_t init_deasserted;
+extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
+#endif
+
+static inline u32 apic_read(u32 reg)
+{
+	return apic->read(reg);
+}
+
+static inline void apic_write(u32 reg, u32 val)
+{
+	apic->write(reg, val);
+}
+
+static inline u64 apic_icr_read(void)
+{
+	return apic->icr_read();
+}
+
+static inline void apic_icr_write(u32 low, u32 high)
+{
+	apic->icr_write(low, high);
+}
+
+static inline void apic_wait_icr_idle(void)
+{
+	apic->wait_icr_idle();
+}
+
+static inline u32 safe_apic_wait_icr_idle(void)
+{
+	return apic->safe_wait_icr_idle();
+}
+
+
+static inline void ack_APIC_irq(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	/*
+	 * ack_APIC_irq() actually gets compiled as a single instruction
+	 * ... yummie.
+	 */
+
+	/* Docs say use 0 for future compatibility */
+	apic_write(APIC_EOI, 0);
+#endif
+}
+
+static inline unsigned default_get_apic_id(unsigned long x)
+{
+	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+
+	if (APIC_XAPIC(ver))
+		return (x >> 24) & 0xFF;
+	else
+		return (x >> 24) & 0x0F;
+}
+
+/*
+ * Warm reset vector default position:
+ */
+#define DEFAULT_TRAMPOLINE_PHYS_LOW		0x467
+#define DEFAULT_TRAMPOLINE_PHYS_HIGH		0x469
+
+#ifdef CONFIG_X86_64
+extern struct apic apic_flat;
+extern struct apic apic_physflat;
+extern struct apic apic_x2apic_cluster;
+extern struct apic apic_x2apic_phys;
+extern int default_acpi_madt_oem_check(char *, char *);
+
+extern void apic_send_IPI_self(int vector);
+
+extern struct apic apic_x2apic_uv_x;
+DECLARE_PER_CPU(int, x2apic_extra_bits);
+
+extern int default_cpu_present_to_apicid(int mps_cpu);
+extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
+#endif
+
+static inline void default_wait_for_init_deassert(atomic_t *deassert)
+{
+	while (!atomic_read(deassert))
+		cpu_relax();
+	return;
+}
+
+extern void generic_bigsmp_probe(void);
+
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+#include <asm/smp.h>
+
+#define APIC_DFR_VALUE	(APIC_DFR_FLAT)
+
+static inline const struct cpumask *default_target_cpus(void)
+{
+#ifdef CONFIG_SMP
+	return cpu_online_mask;
+#else
+	return cpumask_of(0);
+#endif
+}
+
+DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
+
+
+static inline unsigned int read_apic_id(void)
+{
+	unsigned int reg;
+
+	reg = apic_read(APIC_ID);
+
+	return apic->get_apic_id(reg);
+}
+
+extern void default_setup_apic_routing(void);
+
+#ifdef CONFIG_X86_32
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+extern void default_init_apic_ldr(void);
+
+static inline int default_apic_id_registered(void)
+{
+	return physid_isset(read_apic_id(), phys_cpu_present_map);
+}
+
+static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
+extern int default_apicid_to_node(int logical_apicid);
+
+#endif
+
+static inline unsigned int
+default_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
+}
+
+static inline unsigned int
+default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			       const struct cpumask *andmask)
+{
+	unsigned long mask1 = cpumask_bits(cpumask)[0];
+	unsigned long mask2 = cpumask_bits(andmask)[0];
+	unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
+
+	return (unsigned int)(mask1 & mask2 & mask3);
+}
+
+static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+	return physid_isset(apicid, bitmap);
+}
+
+static inline unsigned long default_check_apicid_present(int bit)
+{
+	return physid_isset(bit, phys_cpu_present_map);
+}
+
+static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+	return phys_map;
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int default_cpu_to_logical_apicid(int cpu)
+{
+	return 1 << cpu;
+}
+
+static inline int __default_cpu_present_to_apicid(int mps_cpu)
+{
+	if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
+		return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
+	else
+		return BAD_APICID;
+}
+
+static inline int
+__default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
+}
+
+#ifdef CONFIG_X86_32
+static inline int default_cpu_present_to_apicid(int mps_cpu)
+{
+	return __default_cpu_present_to_apicid(mps_cpu);
+}
+
+static inline int
+default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+}
+#else
+extern int default_cpu_present_to_apicid(int mps_cpu);
+extern int default_check_phys_apicid_present(int boot_cpu_physical_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
+extern u8 cpu_2_logical_apicid[NR_CPUS];
+#endif
+
 #endif /* _ASM_X86_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/apicnum.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/apicnum.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/apicnum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/apicnum.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#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.29-gnu1/arch/x86/include/asm/apm.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/apm.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/apm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/apm.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ *  Machine specific APM BIOS functions for generic.
+ *  Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp>
+ */
+
+#ifndef _ASM_X86_MACH_DEFAULT_APM_H
+#define _ASM_X86_MACH_DEFAULT_APM_H
+
+#ifdef APM_ZERO_SEGS
+#	define APM_DO_ZERO_SEGS \
+		"pushl %%ds\n\t" \
+		"pushl %%es\n\t" \
+		"xorl %%edx, %%edx\n\t" \
+		"mov %%dx, %%ds\n\t" \
+		"mov %%dx, %%es\n\t" \
+		"mov %%dx, %%fs\n\t" \
+		"mov %%dx, %%gs\n\t"
+#	define APM_DO_POP_SEGS \
+		"popl %%es\n\t" \
+		"popl %%ds\n\t"
+#else
+#	define APM_DO_ZERO_SEGS
+#	define APM_DO_POP_SEGS
+#endif
+
+static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
+					u32 *eax, u32 *ebx, u32 *ecx,
+					u32 *edx, u32 *esi)
+{
+	/*
+	 * N.B. We do NOT need a cld after the BIOS call
+	 * because we always save and restore the flags.
+	 */
+	__asm__ __volatile__(APM_DO_ZERO_SEGS
+		"pushl %%edi\n\t"
+		"pushl %%ebp\n\t"
+		"lcall *%%cs:apm_bios_entry\n\t"
+		"setc %%al\n\t"
+		"popl %%ebp\n\t"
+		"popl %%edi\n\t"
+		APM_DO_POP_SEGS
+		: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
+		  "=S" (*esi)
+		: "a" (func), "b" (ebx_in), "c" (ecx_in)
+		: "memory", "cc");
+}
+
+static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
+						u32 ecx_in, u32 *eax)
+{
+	int	cx, dx, si;
+	u8	error;
+
+	/*
+	 * N.B. We do NOT need a cld after the BIOS call
+	 * because we always save and restore the flags.
+	 */
+	__asm__ __volatile__(APM_DO_ZERO_SEGS
+		"pushl %%edi\n\t"
+		"pushl %%ebp\n\t"
+		"lcall *%%cs:apm_bios_entry\n\t"
+		"setc %%bl\n\t"
+		"popl %%ebp\n\t"
+		"popl %%edi\n\t"
+		APM_DO_POP_SEGS
+		: "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
+		  "=S" (si)
+		: "a" (func), "b" (ebx_in), "c" (ecx_in)
+		: "memory", "cc");
+	return error;
+}
+
+#endif /* _ASM_X86_MACH_DEFAULT_APM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/arch_hooks.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/arch_hooks.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/arch_hooks.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/arch_hooks.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-#ifndef _ASM_X86_ARCH_HOOKS_H
-#define _ASM_X86_ARCH_HOOKS_H
-
-#include <linux/interrupt.h>
-
-/*
- *	linux/include/asm/arch_hooks.h
- *
- *	define the architecture specific hooks
- */
-
-/* these aren't arch hooks, they are generic routines
- * that can be used by the hooks */
-extern void init_ISA_irqs(void);
-extern irqreturn_t timer_interrupt(int irq, void *dev_id);
-
-/* these are the defined hooks */
-extern void intr_init_hook(void);
-extern void pre_intr_init_hook(void);
-extern void pre_setup_arch_hook(void);
-extern void trap_init_hook(void);
-extern void pre_time_init_hook(void);
-extern void time_init_hook(void);
-extern void mca_nmi_hook(void);
-
-#endif /* _ASM_X86_ARCH_HOOKS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef __ASM_MACH_APICDEF_H
-#define __ASM_MACH_APICDEF_H
-
-#define		APIC_ID_MASK		(0xFF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
-	return (((x)>>24)&0xFF);
-}
-
-#define		GET_APIC_ID(x)	get_apic_id(x)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,155 +0,0 @@
-#ifndef __ASM_MACH_APIC_H
-#define __ASM_MACH_APIC_H
-
-#define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu))
-#define esr_disable (1)
-
-static inline int apic_id_registered(void)
-{
-	return (1);
-}
-
-static inline const cpumask_t *target_cpus(void)
-{
-#ifdef CONFIG_SMP
-	return &cpu_online_map;
-#else
-	return &cpumask_of_cpu(0);
-#endif
-}
-
-#undef APIC_DEST_LOGICAL
-#define APIC_DEST_LOGICAL	0
-#define APIC_DFR_VALUE		(APIC_DFR_FLAT)
-#define INT_DELIVERY_MODE	(dest_Fixed)
-#define INT_DEST_MODE		(0)    /* phys delivery to target proc */
-#define NO_BALANCE_IRQ		(0)
-
-static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-	return (0);
-}
-
-static inline unsigned long check_apicid_present(int bit)
-{
-	return (1);
-}
-
-static inline unsigned long calculate_ldr(int cpu)
-{
-	unsigned long val, id;
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	id = xapic_phys_to_log_apicid(cpu);
-	val |= SET_APIC_LOGICAL_ID(id);
-	return val;
-}
-
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static inline void init_apic_ldr(void)
-{
-	unsigned long val;
-	int cpu = smp_processor_id();
-
-	apic_write(APIC_DFR, APIC_DFR_VALUE);
-	val = calculate_ldr(cpu);
-	apic_write(APIC_LDR, val);
-}
-
-static inline void setup_apic_routing(void)
-{
-	printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
-		"Physflat", nr_ioapics);
-}
-
-static inline int multi_timer_check(int apic, int irq)
-{
-	return (0);
-}
-
-static inline int apicid_to_node(int logical_apicid)
-{
-	return apicid_2_node[hard_smp_processor_id()];
-}
-
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-	if (mps_cpu < nr_cpu_ids)
-		return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
-
-	return BAD_APICID;
-}
-
-static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
-{
-	return physid_mask_of_physid(phys_apicid);
-}
-
-extern u8 cpu_2_logical_apicid[];
-/* Mapping from cpu number to logical apicid */
-static inline int cpu_to_logical_apicid(int cpu)
-{
-	if (cpu >= nr_cpu_ids)
-		return BAD_APICID;
-	return cpu_physical_id(cpu);
-}
-
-static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
-{
-	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0xFFL);
-}
-
-static inline void setup_portio_remap(void)
-{
-}
-
-static inline void enable_apic_mode(void)
-{
-}
-
-static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-	return (1);
-}
-
-/* As we are using single CPU as destination, pick only one CPU here */
-static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-	int cpu;
-	int apicid;	
-
-	cpu = first_cpu(*cpumask);
-	apicid = cpu_to_logical_apicid(cpu);
-	return apicid;
-}
-
-static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						  const struct cpumask *andmask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	for_each_cpu_and(cpu, cpumask, andmask)
-		if (cpumask_test_cpu(cpu, cpu_online_mask))
-			break;
-	if (cpu < nr_cpu_ids)
-		return cpu_to_logical_apicid(cpu);
-
-	return BAD_APICID;
-}
-
-static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
-	return cpuid_apic >> index_msb;
-}
-
-#endif /* __ASM_MACH_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/bigsmp/ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/bigsmp/ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-#ifndef __ASM_MACH_IPI_H
-#define __ASM_MACH_IPI_H
-
-void send_IPI_mask_sequence(const struct cpumask *mask, int vector);
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector);
-
-static inline void send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	send_IPI_mask_sequence(mask, vector);
-}
-
-static inline void send_IPI_allbutself(int vector)
-{
-	send_IPI_mask_allbutself(cpu_online_mask, vector);
-}
-
-static inline void send_IPI_all(int vector)
-{
-	send_IPI_mask(cpu_online_mask, vector);
-}
-
-#endif /* __ASM_MACH_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/boot.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/boot.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/boot.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/boot.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,26 +1,36 @@
 #ifndef _ASM_X86_BOOT_H
 #define _ASM_X86_BOOT_H
 
-/* Don't touch these, unless you really know what you're doing. */
-#define DEF_SYSSEG	0x1000
-#define DEF_SYSSIZE	0x7F00
-
 /* Internal svga startup constants */
 #define NORMAL_VGA	0xffff		/* 80x25 mode */
 #define EXTENDED_VGA	0xfffe		/* 80x50 mode */
 #define ASK_VGA		0xfffd		/* ask for it at bootup */
 
+#ifdef __KERNEL__
+
 /* Physical address where kernel should be loaded. */
 #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
 				+ (CONFIG_PHYSICAL_ALIGN - 1)) \
 				& ~(CONFIG_PHYSICAL_ALIGN - 1))
 
+#ifdef CONFIG_KERNEL_BZIP2
+#define BOOT_HEAP_SIZE             0x400000
+#else /* !CONFIG_KERNEL_BZIP2 */
+
 #ifdef CONFIG_X86_64
 #define BOOT_HEAP_SIZE	0x7000
-#define BOOT_STACK_SIZE	0x4000
 #else
 #define BOOT_HEAP_SIZE	0x4000
+#endif
+
+#endif /* !CONFIG_KERNEL_BZIP2 */
+
+#ifdef CONFIG_X86_64
+#define BOOT_STACK_SIZE	0x4000
+#else
 #define BOOT_STACK_SIZE	0x1000
 #endif
 
+#endif /* __KERNEL__ */
+
 #endif /* _ASM_X86_BOOT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/cacheflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,24 +5,43 @@
 #include <linux/mm.h>
 
 /* Caches aren't brain-dead on the intel. */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#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 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, end)		do { } while (0)
-#define flush_icache_page(vma, pg)		do { } while (0)
-#define flush_icache_user_range(vma, pg, adr, len)	do { } while (0)
-#define flush_cache_vmap(start, end)		do { } while (0)
-#define flush_cache_vunmap(start, end)		do { } while (0)
+static inline void flush_cache_all(void) { }
+static inline void flush_cache_mm(struct mm_struct *mm) { }
+static inline void flush_cache_dup_mm(struct mm_struct *mm) { }
+static inline void flush_cache_range(struct vm_area_struct *vma,
+				     unsigned long start, unsigned long end) { }
+static inline void flush_cache_page(struct vm_area_struct *vma,
+				    unsigned long vmaddr, unsigned long pfn) { }
+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) { }
+static inline void flush_icache_range(unsigned long start,
+				      unsigned long end) { }
+static inline void flush_icache_page(struct vm_area_struct *vma,
+				     struct page *page) { }
+static inline void flush_icache_user_range(struct vm_area_struct *vma,
+					   struct page *page,
+					   unsigned long addr,
+					   unsigned long len) { }
+static inline void flush_cache_vmap(unsigned long start, unsigned long end) { }
+static inline void flush_cache_vunmap(unsigned long start,
+				      unsigned long end) { }
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
-	memcpy((dst), (src), (len))
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
-	memcpy((dst), (src), (len))
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+				     struct page *page, unsigned long vaddr,
+				     void *dst, const void *src,
+				     unsigned long len)
+{
+	memcpy(dst, src, len);
+}
+
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+				       struct page *page, unsigned long vaddr,
+				       void *dst, const void *src,
+				       unsigned long len)
+{
+	memcpy(dst, src, len);
+}
 
 #define PG_non_WB				PG_arch_1
 PAGEFLAG(NonWB, non_WB)
@@ -71,6 +90,9 @@ int set_memory_4k(unsigned long addr, in
 int set_memory_array_uc(unsigned long *addr, int addrinarray);
 int set_memory_array_wb(unsigned long *addr, int addrinarray);
 
+int set_pages_array_uc(struct page **pages, int addrinarray);
+int set_pages_array_wb(struct page **pages, int addrinarray);
+
 /*
  * For legacy compatibility with the old APIs, a few functions
  * are provided that work on a "struct page".
@@ -104,6 +126,11 @@ void clflush_cache_range(void *addr, uns
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 extern const int rodata_test_data;
+void set_kernel_text_rw(void);
+void set_kernel_text_ro(void);
+#else
+static inline void set_kernel_text_rw(void) { }
+static inline void set_kernel_text_ro(void) { }
 #endif
 
 #ifdef CONFIG_DEBUG_RODATA_TEST
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/calling.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/calling.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/calling.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/calling.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,55 @@
 /*
- * Some macros to handle stack frames in assembly.
+
+ x86 function call convention, 64-bit:
+ -------------------------------------
+  arguments           |  callee-saved      | extra caller-saved | return
+ [callee-clobbered]   |                    | [callee-clobbered] |
+ ---------------------------------------------------------------------------
+ rdi rsi rdx rcx r8-9 | rbx rbp [*] r12-15 | r10-11             | rax, rdx [**]
+
+ ( rsp is obviously invariant across normal function calls. (gcc can 'merge'
+   functions when it sees tail-call optimization possibilities) rflags is
+   clobbered. Leftover arguments are passed over the stack frame.)
+
+ [*]  In the frame-pointers case rbp is fixed to the stack frame.
+
+ [**] for struct return values wider than 64 bits the return convention is a
+      bit more complex: up to 128 bits width we return small structures
+      straight in rax, rdx. For structures larger than that (3 words or
+      larger) the caller puts a pointer to an on-stack return struct
+      [allocated in the caller's stack frame] into the first argument - i.e.
+      into rdi. All other arguments shift up by one in this case.
+      Fortunately this case is rare in the kernel.
+
+For 32-bit we have the following conventions - kernel is built with
+-mregparm=3 and -freg-struct-return:
+
+ x86 function calling convention, 32-bit:
+ ----------------------------------------
+  arguments         | callee-saved        | extra caller-saved | return
+ [callee-clobbered] |                     | [callee-clobbered] |
+ -------------------------------------------------------------------------
+ eax edx ecx        | ebx edi esi ebp [*] | <none>             | eax, edx [**]
+
+ ( here too esp is obviously invariant across normal function calls. eflags
+   is clobbered. Leftover arguments are passed over the stack frame. )
+
+ [*]  In the frame-pointers case ebp is fixed to the stack frame.
+
+ [**] We build with -freg-struct-return, which on 32-bit means similar
+      semantics as on 64-bit: edx can be used for a second return value
+      (i.e. covering integer and structure sizes up to 64 bits) - after that
+      it gets more complex and more expensive: 3-word or larger struct returns
+      get done in the caller's frame and the pointer to the return struct goes
+      into regparm0, i.e. eax - the other arguments shift up and the
+      function's register parameters degenerate to regparm=2 in essence.
+
+*/
+
+
+/*
+ * 64-bit system call stack frame layout defines and helpers,
+ * for assembly code:
  */
 
 #define R15		  0
@@ -9,7 +59,7 @@
 #define RBP		 32
 #define RBX		 40
 
-/* arguments: interrupts/non tracing syscalls only save upto here*/
+/* arguments: interrupts/non tracing syscalls only save up to here: */
 #define R11		 48
 #define R10		 56
 #define R9		 64
@@ -22,7 +72,7 @@
 #define ORIG_RAX	120       /* + error_code */
 /* end of arguments */
 
-/* cpu exception frame or undefined in case of fast syscall. */
+/* cpu exception frame or undefined in case of fast syscall: */
 #define RIP		128
 #define CS		136
 #define EFLAGS		144
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpu_debug.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpu_debug.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpu_debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpu_debug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,226 @@
+#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)
+
+/*
+ * DisplayFamily_DisplayModel	Processor Families/Processor Number Series
+ * --------------------------	------------------------------------------
+ * 05_01, 05_02, 05_04		Pentium, Pentium with MMX
+ *
+ * 06_01			Pentium Pro
+ * 06_03, 06_05			Pentium II Xeon, Pentium II
+ * 06_07, 06_08, 06_0A, 06_0B	Pentium III Xeon, Pentum III
+ *
+ * 06_09, 060D			Pentium M
+ *
+ * 06_0E			Core Duo, Core Solo
+ *
+ * 06_0F			Xeon 3000, 3200, 5100, 5300, 7300 series,
+ *				Core 2 Quad, Core 2 Extreme, Core 2 Duo,
+ *				Pentium dual-core
+ * 06_17			Xeon 5200, 5400 series, Core 2 Quad Q9650
+ *
+ * 06_1C			Atom
+ *
+ * 0F_00, 0F_01, 0F_02		Xeon, Xeon MP, Pentium 4
+ * 0F_03, 0F_04			Xeon, Xeon MP, Pentium 4, Pentium D
+ *
+ * 0F_06			Xeon 7100, 5000 Series, Xeon MP,
+ *				Pentium 4, Pentium D
+ */
+
+/* Register processors bits */
+enum cpu_processor_bit {
+	CPU_NONE,
+/* Intel */
+	CPU_INTEL_PENTIUM_BIT,
+	CPU_INTEL_P6_BIT,
+	CPU_INTEL_PENTIUM_M_BIT,
+	CPU_INTEL_CORE_BIT,
+	CPU_INTEL_CORE2_BIT,
+	CPU_INTEL_ATOM_BIT,
+	CPU_INTEL_XEON_P4_BIT,
+	CPU_INTEL_XEON_MP_BIT,
+/* AMD */
+	CPU_AMD_K6_BIT,
+	CPU_AMD_K7_BIT,
+	CPU_AMD_K8_BIT,
+	CPU_AMD_0F_BIT,
+	CPU_AMD_10_BIT,
+	CPU_AMD_11_BIT,
+};
+
+#define	CPU_INTEL_PENTIUM	(1 << CPU_INTEL_PENTIUM_BIT)
+#define	CPU_INTEL_P6		(1 << CPU_INTEL_P6_BIT)
+#define	CPU_INTEL_PENTIUM_M	(1 << CPU_INTEL_PENTIUM_M_BIT)
+#define	CPU_INTEL_CORE		(1 << CPU_INTEL_CORE_BIT)
+#define	CPU_INTEL_CORE2		(1 << CPU_INTEL_CORE2_BIT)
+#define	CPU_INTEL_ATOM		(1 << CPU_INTEL_ATOM_BIT)
+#define	CPU_INTEL_XEON_P4	(1 << CPU_INTEL_XEON_P4_BIT)
+#define	CPU_INTEL_XEON_MP	(1 << CPU_INTEL_XEON_MP_BIT)
+
+#define	CPU_INTEL_PX		(CPU_INTEL_P6 | CPU_INTEL_PENTIUM_M)
+#define	CPU_INTEL_COREX		(CPU_INTEL_CORE | CPU_INTEL_CORE2)
+#define	CPU_INTEL_XEON		(CPU_INTEL_XEON_P4 | CPU_INTEL_XEON_MP)
+#define	CPU_CO_AT		(CPU_INTEL_CORE | CPU_INTEL_ATOM)
+#define	CPU_C2_AT		(CPU_INTEL_CORE2 | CPU_INTEL_ATOM)
+#define	CPU_CX_AT		(CPU_INTEL_COREX | CPU_INTEL_ATOM)
+#define	CPU_CX_XE		(CPU_INTEL_COREX | CPU_INTEL_XEON)
+#define	CPU_P6_XE		(CPU_INTEL_P6 | CPU_INTEL_XEON)
+#define	CPU_PM_CO_AT		(CPU_INTEL_PENTIUM_M | CPU_CO_AT)
+#define	CPU_C2_AT_XE		(CPU_C2_AT | CPU_INTEL_XEON)
+#define	CPU_CX_AT_XE		(CPU_CX_AT | CPU_INTEL_XEON)
+#define	CPU_P6_CX_AT		(CPU_INTEL_P6 | CPU_CX_AT)
+#define	CPU_P6_CX_XE		(CPU_P6_XE | CPU_INTEL_COREX)
+#define	CPU_P6_CX_AT_XE		(CPU_INTEL_P6 | CPU_CX_AT_XE)
+#define	CPU_PM_CX_AT_XE		(CPU_INTEL_PENTIUM_M | CPU_CX_AT_XE)
+#define	CPU_PM_CX_AT		(CPU_INTEL_PENTIUM_M | CPU_CX_AT)
+#define	CPU_PM_CX_XE		(CPU_INTEL_PENTIUM_M | CPU_CX_XE)
+#define	CPU_PX_CX_AT		(CPU_INTEL_PX | CPU_CX_AT)
+#define	CPU_PX_CX_AT_XE		(CPU_INTEL_PX | CPU_CX_AT_XE)
+
+/* Select all supported Intel CPUs */
+#define	CPU_INTEL_ALL		(CPU_INTEL_PENTIUM | CPU_PX_CX_AT_XE)
+
+#define	CPU_AMD_K6		(1 << CPU_AMD_K6_BIT)
+#define	CPU_AMD_K7		(1 << CPU_AMD_K7_BIT)
+#define	CPU_AMD_K8		(1 << CPU_AMD_K8_BIT)
+#define	CPU_AMD_0F		(1 << CPU_AMD_0F_BIT)
+#define	CPU_AMD_10		(1 << CPU_AMD_10_BIT)
+#define	CPU_AMD_11		(1 << CPU_AMD_11_BIT)
+
+#define	CPU_K10_PLUS		(CPU_AMD_10 | CPU_AMD_11)
+#define	CPU_K0F_PLUS		(CPU_AMD_0F | CPU_K10_PLUS)
+#define	CPU_K8_PLUS		(CPU_AMD_K8 | CPU_K0F_PLUS)
+#define	CPU_K7_PLUS		(CPU_AMD_K7 | CPU_K8_PLUS)
+
+/* Select all supported AMD CPUs */
+#define	CPU_AMD_ALL		(CPU_AMD_K6 | CPU_K7_PLUS)
+
+/* Select all supported CPUs */
+#define	CPU_ALL			(CPU_INTEL_ALL | CPU_AMD_ALL)
+
+#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	*/
+	unsigned		model;		/* Supported models	*/
+};
+
+#endif /* _ASM_X86_CPU_DEBUG_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpufeature.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpufeature.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpufeature.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpufeature.h	2009-06-09 23:05:27.000000000 -0400
@@ -154,6 +154,7 @@
  * CPUID levels like 0x6, 0xA etc
  */
 #define X86_FEATURE_IDA		(7*32+ 0) /* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT	(7*32+ 1) /* Always Running APIC Timer */
 
 /* Virtualization flags: Linux defined */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
@@ -213,6 +214,7 @@ extern const char * const x86_power_flag
 #define cpu_has_xmm		boot_cpu_has(X86_FEATURE_XMM)
 #define cpu_has_xmm2		boot_cpu_has(X86_FEATURE_XMM2)
 #define cpu_has_xmm3		boot_cpu_has(X86_FEATURE_XMM3)
+#define cpu_has_aes		boot_cpu_has(X86_FEATURE_AES)
 #define cpu_has_ht		boot_cpu_has(X86_FEATURE_HT)
 #define cpu_has_mp		boot_cpu_has(X86_FEATURE_MP)
 #define cpu_has_nx		boot_cpu_has(X86_FEATURE_NX)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,20 @@
 #include <linux/nodemask.h>
 #include <linux/percpu.h>
 
+#ifdef CONFIG_SMP
+
+extern void prefill_possible_map(void);
+
+#else /* CONFIG_SMP */
+
+static inline void prefill_possible_map(void) {}
+
+#define cpu_physical_id(cpu)			boot_cpu_physical_apicid
+#define safe_smp_processor_id()			0
+#define stack_smp_processor_id()		0
+
+#endif /* CONFIG_SMP */
+
 struct x86_cpu {
 	struct cpu cpu;
 };
@@ -17,4 +31,7 @@ extern void arch_unregister_cpu(int);
 #endif
 
 DECLARE_PER_CPU(int, cpu_state);
+
+extern unsigned int boot_cpu_id;
+
 #endif /* _ASM_X86_CPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpumask.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpumask.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/cpumask.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpumask.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+#ifndef _ASM_X86_CPUMASK_H
+#define _ASM_X86_CPUMASK_H
+#ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
+
+extern cpumask_var_t cpu_callin_mask;
+extern cpumask_var_t cpu_callout_mask;
+extern cpumask_var_t cpu_initialized_mask;
+extern cpumask_var_t cpu_sibling_setup_mask;
+
+extern void setup_cpu_local_masks(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_CPUMASK_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/current.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/current.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/current.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/current.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,39 +1,21 @@
 #ifndef _ASM_X86_CURRENT_H
 #define _ASM_X86_CURRENT_H
 
-#ifdef CONFIG_X86_32
 #include <linux/compiler.h>
 #include <asm/percpu.h>
 
+#ifndef __ASSEMBLY__
 struct task_struct;
 
 DECLARE_PER_CPU(struct task_struct *, current_task);
-static __always_inline struct task_struct *get_current(void)
-{
-	return x86_read_percpu(current_task);
-}
-
-#else /* X86_32 */
-
-#ifndef __ASSEMBLY__
-#include <asm/pda.h>
-
-struct task_struct;
 
 static __always_inline struct task_struct *get_current(void)
 {
-	return read_pda(pcurrent);
+	return percpu_read(current_task);
 }
 
-#else /* __ASSEMBLY__ */
-
-#include <asm/asm-offsets.h>
-#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg
+#define current get_current()
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* X86_32 */
-
-#define current get_current()
-
 #endif /* _ASM_X86_CURRENT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/desc.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/desc.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/desc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/desc.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,7 @@ extern gate_desc idt_table[];
 struct gdt_page {
 	struct desc_struct gdt[GDT_ENTRIES];
 } __attribute__((aligned(PAGE_SIZE)));
-DECLARE_PER_CPU(struct gdt_page, gdt_page);
+DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
 {
@@ -91,7 +91,6 @@ static inline int desc_empty(const void
 #define store_gdt(dtr) native_store_gdt(dtr)
 #define store_idt(dtr) native_store_idt(dtr)
 #define store_tr(tr) (tr = native_store_tr())
-#define store_ldt(ldt) asm("sldt %0":"=m" (ldt))
 
 #define load_TLS(t, cpu) native_load_tls(t, cpu)
 #define set_ldt native_set_ldt
@@ -112,6 +111,8 @@ static inline void paravirt_free_ldt(str
 }
 #endif	/* CONFIG_PARAVIRT */
 
+#define store_ldt(ldt) asm("sldt %0" : "=m"(ldt))
+
 static inline void native_write_idt_entry(gate_desc *idt, int entry,
 					  const gate_desc *gate)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/device.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/device.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/device.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@ struct dev_archdata {
 	void	*acpi_handle;
 #endif
 #ifdef CONFIG_X86_64
-struct dma_mapping_ops *dma_ops;
+struct dma_map_ops *dma_ops;
 #endif
 #ifdef CONFIG_DMAR
 	void *iommu; /* hook for IOMMU specific extension */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/dma-mapping.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/dma-mapping.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/dma-mapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/dma-mapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,8 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 #include <asm-generic/dma-coherent.h>
@@ -16,47 +18,9 @@ extern int iommu_merge;
 extern struct device x86_dma_fallback_dev;
 extern int panic_on_overflow;
 
-struct dma_mapping_ops {
-	int             (*mapping_error)(struct device *dev,
-					 dma_addr_t dma_addr);
-	void*           (*alloc_coherent)(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t gfp);
-	void            (*free_coherent)(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle);
-	dma_addr_t      (*map_single)(struct device *hwdev, phys_addr_t ptr,
-				size_t size, int direction);
-	void            (*unmap_single)(struct device *dev, dma_addr_t addr,
-				size_t size, int direction);
-	void            (*sync_single_for_cpu)(struct device *hwdev,
-				dma_addr_t dma_handle, size_t size,
-				int direction);
-	void            (*sync_single_for_device)(struct device *hwdev,
-				dma_addr_t dma_handle, size_t size,
-				int direction);
-	void            (*sync_single_range_for_cpu)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size, int direction);
-	void            (*sync_single_range_for_device)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size, int direction);
-	void            (*sync_sg_for_cpu)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				int direction);
-	void            (*sync_sg_for_device)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				int direction);
-	int             (*map_sg)(struct device *hwdev, struct scatterlist *sg,
-				int nents, int direction);
-	void            (*unmap_sg)(struct device *hwdev,
-				struct scatterlist *sg, int nents,
-				int direction);
-	int             (*dma_supported)(struct device *hwdev, u64 mask);
-	int		is_phys;
-};
-
-extern struct dma_mapping_ops *dma_ops;
+extern struct dma_map_ops *dma_ops;
 
-static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
 #ifdef CONFIG_X86_32
 	return dma_ops;
@@ -71,7 +35,7 @@ static inline struct dma_mapping_ops *ge
 /* Make sure we keep the same behaviour */
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
 	if (ops->mapping_error)
 		return ops->mapping_error(dev, dma_addr);
 
@@ -90,137 +54,167 @@ extern void *dma_generic_alloc_coherent(
 
 static inline dma_addr_t
 dma_map_single(struct device *hwdev, void *ptr, size_t size,
-	       int direction)
+	       enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
+	dma_addr_t addr;
 
-	BUG_ON(!valid_dma_direction(direction));
-	return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
+	BUG_ON(!valid_dma_direction(dir));
+	addr = ops->map_page(hwdev, virt_to_page(ptr),
+			     (unsigned long)ptr & ~PAGE_MASK, size,
+			     dir, NULL);
+	debug_dma_map_page(hwdev, 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,
-		 int direction)
+		 enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	BUG_ON(!valid_dma_direction(direction));
-	if (ops->unmap_single)
-		ops->unmap_single(dev, addr, size, direction);
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops->unmap_page)
+		ops->unmap_page(dev, addr, size, dir, NULL);
+	debug_dma_unmap_page(dev, addr, size, dir, true);
 }
 
 static inline int
 dma_map_sg(struct device *hwdev, struct scatterlist *sg,
-	   int nents, int direction)
+	   int nents, enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
+	int ents;
 
-	BUG_ON(!valid_dma_direction(direction));
-	return ops->map_sg(hwdev, sg, nents, direction);
+	BUG_ON(!valid_dma_direction(dir));
+	ents = ops->map_sg(hwdev, sg, nents, dir, NULL);
+	debug_dma_map_sg(hwdev, sg, nents, ents, dir);
+
+	return ents;
 }
 
 static inline void
 dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-	     int direction)
+	     enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
+	debug_dma_unmap_sg(hwdev, sg, nents, dir);
 	if (ops->unmap_sg)
-		ops->unmap_sg(hwdev, sg, nents, direction);
+		ops->unmap_sg(hwdev, sg, nents, dir, NULL);
 }
 
 static inline void
 dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
-			size_t size, int direction)
+			size_t size, enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_single_for_cpu)
-		ops->sync_single_for_cpu(hwdev, dma_handle, size, direction);
+		ops->sync_single_for_cpu(hwdev, dma_handle, size, dir);
+	debug_dma_sync_single_for_cpu(hwdev, dma_handle, size, dir);
 	flush_write_buffers();
 }
 
 static inline void
 dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
-			   size_t size, int direction)
+			   size_t size, enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_single_for_device)
-		ops->sync_single_for_device(hwdev, dma_handle, size, direction);
+		ops->sync_single_for_device(hwdev, dma_handle, size, dir);
+	debug_dma_sync_single_for_device(hwdev, dma_handle, size, dir);
 	flush_write_buffers();
 }
 
 static inline void
 dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
-			      unsigned long offset, size_t size, int direction)
+			      unsigned long offset, size_t size,
+			      enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_single_range_for_cpu)
 		ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
-					       size, direction);
+					       size, dir);
+	debug_dma_sync_single_range_for_cpu(hwdev, dma_handle,
+					    offset, size, dir);
 	flush_write_buffers();
 }
 
 static inline void
 dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
 				 unsigned long offset, size_t size,
-				 int direction)
+				 enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_single_range_for_device)
 		ops->sync_single_range_for_device(hwdev, dma_handle,
-						  offset, size, direction);
+						  offset, size, dir);
+	debug_dma_sync_single_range_for_device(hwdev, dma_handle,
+					       offset, size, dir);
 	flush_write_buffers();
 }
 
 static inline void
 dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
-		    int nelems, int direction)
+		    int nelems, enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_sg_for_cpu)
-		ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
+		ops->sync_sg_for_cpu(hwdev, sg, nelems, dir);
+	debug_dma_sync_sg_for_cpu(hwdev, sg, nelems, dir);
 	flush_write_buffers();
 }
 
 static inline void
 dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
-		       int nelems, int direction)
+		       int nelems, enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+	struct dma_map_ops *ops = get_dma_ops(hwdev);
 
-	BUG_ON(!valid_dma_direction(direction));
+	BUG_ON(!valid_dma_direction(dir));
 	if (ops->sync_sg_for_device)
-		ops->sync_sg_for_device(hwdev, sg, nelems, direction);
+		ops->sync_sg_for_device(hwdev, sg, nelems, dir);
+	debug_dma_sync_sg_for_device(hwdev, sg, nelems, dir);
 
 	flush_write_buffers();
 }
 
 static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 				      size_t offset, size_t size,
-				      int direction)
+				      enum dma_data_direction dir)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	dma_addr_t addr;
 
-	BUG_ON(!valid_dma_direction(direction));
-	return ops->map_single(dev, page_to_phys(page) + offset,
-			       size, direction);
+	BUG_ON(!valid_dma_direction(dir));
+	addr = ops->map_page(dev, page, offset, size, dir, NULL);
+	debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+
+	return addr;
 }
 
 static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
-				  size_t size, int direction)
+				  size_t size, enum dma_data_direction dir)
 {
-	dma_unmap_single(dev, addr, size, direction);
+	struct dma_map_ops *ops = get_dma_ops(dev);
+
+	BUG_ON(!valid_dma_direction(dir));
+	if (ops->unmap_page)
+		ops->unmap_page(dev, addr, size, dir, NULL);
+	debug_dma_unmap_page(dev, addr, size, dir, false);
 }
 
 static inline void
@@ -244,7 +238,7 @@ static inline unsigned long dma_alloc_co
 
 	dma_mask = dev->coherent_dma_mask;
 	if (!dma_mask)
-		dma_mask = (gfp & GFP_DMA) ? DMA_24BIT_MASK : DMA_32BIT_MASK;
+		dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
 
 	return dma_mask;
 }
@@ -253,10 +247,10 @@ static inline gfp_t dma_alloc_coherent_g
 {
 	unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp);
 
-	if (dma_mask <= DMA_24BIT_MASK)
+	if (dma_mask <= DMA_BIT_MASK(24))
 		gfp |= GFP_DMA;
 #ifdef CONFIG_X86_64
-	if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA))
+	if (dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
 		gfp |= GFP_DMA32;
 #endif
        return gfp;
@@ -266,7 +260,7 @@ static inline void *
 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 		gfp_t gfp)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *memory;
 
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
@@ -285,20 +279,24 @@ dma_alloc_coherent(struct device *dev, s
 	if (!ops->alloc_coherent)
 		return NULL;
 
-	return ops->alloc_coherent(dev, size, dma_handle,
-				   dma_alloc_coherent_gfp_flags(dev, gfp));
+	memory = ops->alloc_coherent(dev, size, dma_handle,
+				     dma_alloc_coherent_gfp_flags(dev, gfp));
+	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+
+	return memory;
 }
 
 static inline void dma_free_coherent(struct device *dev, size_t size,
 				     void *vaddr, dma_addr_t bus)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	WARN_ON(irqs_disabled());       /* for portability */
 
 	if (dma_release_from_coherent(dev, get_order(size), vaddr))
 		return;
 
+	debug_dma_free_coherent(dev, size, vaddr, bus);
 	if (ops->free_coherent)
 		ops->free_coherent(dev, size, vaddr, bus);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/dmi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/dmi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/dmi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/dmi.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,22 +1,15 @@
 #ifndef _ASM_X86_DMI_H
 #define _ASM_X86_DMI_H
 
-#include <asm/io.h>
-
-#define DMI_MAX_DATA 2048
+#include <linux/compiler.h>
+#include <linux/init.h>
 
-extern int dmi_alloc_index;
-extern char dmi_alloc_data[DMI_MAX_DATA];
+#include <asm/io.h>
+#include <asm/setup.h>
 
-/* This is so early that there is no good way to allocate dynamic memory.
-   Allocate data in an BSS array. */
-static inline void *dmi_alloc(unsigned len)
+static __always_inline __init void *dmi_alloc(unsigned len)
 {
-	int idx = dmi_alloc_index;
-	if ((dmi_alloc_index + len) > DMI_MAX_DATA)
-		return NULL;
-	dmi_alloc_index += len;
-	return dmi_alloc_data + idx;
+	return extend_brk(len, sizeof(int));
 }
 
 /* Use early IO mappings for DMI because it's initialized early */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/do_timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/do_timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/do_timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/do_timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,16 @@
+/* defines for inline arch setup functions */
+#include <linux/clockchips.h>
+
+#include <asm/i8259.h>
+#include <asm/i8253.h>
+
+/**
+ * do_timer_interrupt_hook - hook into timer tick
+ *
+ * Call the pit clock event handler. see asm/i8253.h
+ **/
+
+static inline void do_timer_interrupt_hook(void)
+{
+	global_clock_event->event_handler(global_clock_event);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/e820.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/e820.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/e820.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/e820.h	2009-06-09 23:05:27.000000000 -0400
@@ -72,7 +72,7 @@ extern int e820_all_mapped(u64 start, u6
 extern void e820_add_region(u64 start, u64 size, int type);
 extern void e820_print_map(char *who);
 extern int
-sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, int *pnr_map);
+sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
 extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
 			       unsigned new_type);
 extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/elf.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/elf.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/elf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/elf.h	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,7 @@ extern unsigned int vdso_enabled;
  * now struct_user_regs, they are different)
  */
 
-#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
+#define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs)	\
 do {						\
 	pr_reg[0] = regs->bx;			\
 	pr_reg[1] = regs->cx;			\
@@ -124,7 +124,6 @@ do {						\
 	pr_reg[7] = regs->ds & 0xffff;		\
 	pr_reg[8] = regs->es & 0xffff;		\
 	pr_reg[9] = regs->fs & 0xffff;		\
-	savesegment(gs, pr_reg[10]);		\
 	pr_reg[11] = regs->orig_ax;		\
 	pr_reg[12] = regs->ip;			\
 	pr_reg[13] = regs->cs & 0xffff;		\
@@ -133,6 +132,18 @@ do {						\
 	pr_reg[16] = regs->ss & 0xffff;		\
 } while (0);
 
+#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
+do {						\
+	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
+	pr_reg[10] = get_user_gs(regs);		\
+} while (0);
+
+#define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs)	\
+do {						\
+	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
+	savesegment(gs, pr_reg[10]);		\
+} while (0);
+
 #define ELF_PLATFORM	(utsname()->machine)
 #define set_personality_64bit()	do { } while (0)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/entry_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/entry_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/entry_arch.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/entry_arch.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * This file is designed to contain the BUILD_INTERRUPT specifications for
+ * all of the extra named interrupt vectors used by the architecture.
+ * Usually this is the Inter Process Interrupts (IPIs)
+ */
+
+/*
+ * The following vectors are part of the Linux architecture, there
+ * is no hardware IRQ pin equivalent for them, they are triggered
+ * through the ICC by us (IPIs)
+ */
+#ifdef CONFIG_SMP
+BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
+BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
+BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
+BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
+
+BUILD_INTERRUPT3(invalidate_interrupt0,INVALIDATE_TLB_VECTOR_START+0,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt1,INVALIDATE_TLB_VECTOR_START+1,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt2,INVALIDATE_TLB_VECTOR_START+2,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt3,INVALIDATE_TLB_VECTOR_START+3,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt4,INVALIDATE_TLB_VECTOR_START+4,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt5,INVALIDATE_TLB_VECTOR_START+5,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt6,INVALIDATE_TLB_VECTOR_START+6,
+		 smp_invalidate_interrupt)
+BUILD_INTERRUPT3(invalidate_interrupt7,INVALIDATE_TLB_VECTOR_START+7,
+		 smp_invalidate_interrupt)
+#endif
+
+BUILD_INTERRUPT(generic_interrupt, GENERIC_INTERRUPT_VECTOR)
+
+/*
+ * every pentium local APIC has two 'local interrupts', with a
+ * soft-definable vector attached to both interrupts, one of
+ * which is a timer interrupt, the other one is error counter
+ * overflow. Linux uses the local APIC timer interrupt to get
+ * a much simpler SMP time architecture:
+ */
+#ifdef CONFIG_X86_LOCAL_APIC
+
+BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
+BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
+BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
+
+#ifdef CONFIG_PERF_COUNTERS
+BUILD_INTERRUPT(perf_counter_interrupt, LOCAL_PERF_VECTOR)
+#endif
+
+#ifdef CONFIG_X86_MCE_P4THERMAL
+BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef __ASM_ES7000_APICDEF_H
-#define __ASM_ES7000_APICDEF_H
-
-#define		APIC_ID_MASK		(0xFF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
-	return (((x)>>24)&0xFF);
-}
-
-#define		GET_APIC_ID(x)	get_apic_id(x)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,242 +0,0 @@
-#ifndef __ASM_ES7000_APIC_H
-#define __ASM_ES7000_APIC_H
-
-#include <linux/gfp.h>
-
-#define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu)
-#define esr_disable (1)
-
-static inline int apic_id_registered(void)
-{
-	        return (1);
-}
-
-static inline const cpumask_t *target_cpus_cluster(void)
-{
-	return &CPU_MASK_ALL;
-}
-
-static inline const cpumask_t *target_cpus(void)
-{
-	return &cpumask_of_cpu(smp_processor_id());
-}
-
-#define APIC_DFR_VALUE_CLUSTER		(APIC_DFR_CLUSTER)
-#define INT_DELIVERY_MODE_CLUSTER	(dest_LowestPrio)
-#define INT_DEST_MODE_CLUSTER		(1) /* logical delivery broadcast to all procs */
-#define NO_BALANCE_IRQ_CLUSTER		(1)
-
-#define APIC_DFR_VALUE		(APIC_DFR_FLAT)
-#define INT_DELIVERY_MODE	(dest_Fixed)
-#define INT_DEST_MODE		(0)    /* phys delivery to target procs */
-#define NO_BALANCE_IRQ		(0)
-#undef  APIC_DEST_LOGICAL
-#define APIC_DEST_LOGICAL	0x0
-
-static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-	return 0;
-}
-static inline unsigned long check_apicid_present(int bit)
-{
-	return physid_isset(bit, phys_cpu_present_map);
-}
-
-#define apicid_cluster(apicid) (apicid & 0xF0)
-
-static inline unsigned long calculate_ldr(int cpu)
-{
-	unsigned long id;
-	id = xapic_phys_to_log_apicid(cpu);
-	return (SET_APIC_LOGICAL_ID(id));
-}
-
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LdR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static inline void init_apic_ldr_cluster(void)
-{
-	unsigned long val;
-	int cpu = smp_processor_id();
-
-	apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER);
-	val = calculate_ldr(cpu);
-	apic_write(APIC_LDR, val);
-}
-
-static inline void init_apic_ldr(void)
-{
-	unsigned long val;
-	int cpu = smp_processor_id();
-
-	apic_write(APIC_DFR, APIC_DFR_VALUE);
-	val = calculate_ldr(cpu);
-	apic_write(APIC_LDR, val);
-}
-
-extern int apic_version [MAX_APICS];
-static inline void setup_apic_routing(void)
-{
-	int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
-	printk("Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
-		(apic_version[apic] == 0x14) ?
-			"Physical Cluster" : "Logical Cluster",
-			nr_ioapics, cpus_addr(*target_cpus())[0]);
-}
-
-static inline int multi_timer_check(int apic, int irq)
-{
-	return 0;
-}
-
-static inline int apicid_to_node(int logical_apicid)
-{
-	return 0;
-}
-
-
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-	if (!mps_cpu)
-		return boot_cpu_physical_apicid;
-	else if (mps_cpu < nr_cpu_ids)
-		return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
-	else
-		return BAD_APICID;
-}
-
-static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
-{
-	static int id = 0;
-	physid_mask_t mask;
-	mask = physid_mask_of_physid(id);
-	++id;
-	return mask;
-}
-
-extern u8 cpu_2_logical_apicid[];
-/* Mapping from cpu number to logical apicid */
-static inline int cpu_to_logical_apicid(int cpu)
-{
-#ifdef CONFIG_SMP
-	if (cpu >= nr_cpu_ids)
-		return BAD_APICID;
-	return (int)cpu_2_logical_apicid[cpu];
-#else
-	return logical_smp_processor_id();
-#endif
-}
-
-static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
-{
-	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0xff);
-}
-
-
-static inline void setup_portio_remap(void)
-{
-}
-
-extern unsigned int boot_cpu_physical_apicid;
-static inline int check_phys_apicid_present(int cpu_physical_apicid)
-{
-	boot_cpu_physical_apicid = read_apic_id();
-	return (1);
-}
-
-static inline unsigned int
-cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
-{
-	int num_bits_set;
-	int cpus_found = 0;
-	int cpu;
-	int apicid;
-
-	num_bits_set = cpumask_weight(cpumask);
-	/* Return id to all */
-	if (num_bits_set == nr_cpu_ids)
-		return 0xFF;
-	/*
-	 * The cpus in the mask must all be on the apic cluster.  If are not
-	 * on the same apicid cluster return default value of TARGET_CPUS.
-	 */
-	cpu = cpumask_first(cpumask);
-	apicid = cpu_to_logical_apicid(cpu);
-	while (cpus_found < num_bits_set) {
-		if (cpumask_test_cpu(cpu, cpumask)) {
-			int new_apicid = cpu_to_logical_apicid(cpu);
-			if (apicid_cluster(apicid) !=
-					apicid_cluster(new_apicid)){
-				printk ("%s: Not a valid mask!\n", __func__);
-				return 0xFF;
-			}
-			apicid = new_apicid;
-			cpus_found++;
-		}
-		cpu++;
-	}
-	return apicid;
-}
-
-static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-	int num_bits_set;
-	int cpus_found = 0;
-	int cpu;
-	int apicid;
-
-	num_bits_set = cpus_weight(*cpumask);
-	/* Return id to all */
-	if (num_bits_set == nr_cpu_ids)
-		return cpu_to_logical_apicid(0);
-	/*
-	 * The cpus in the mask must all be on the apic cluster.  If are not
-	 * on the same apicid cluster return default value of TARGET_CPUS.
-	 */
-	cpu = first_cpu(*cpumask);
-	apicid = cpu_to_logical_apicid(cpu);
-	while (cpus_found < num_bits_set) {
-		if (cpu_isset(cpu, *cpumask)) {
-			int new_apicid = cpu_to_logical_apicid(cpu);
-			if (apicid_cluster(apicid) !=
-					apicid_cluster(new_apicid)){
-				printk ("%s: Not a valid mask!\n", __func__);
-				return cpu_to_logical_apicid(0);
-			}
-			apicid = new_apicid;
-			cpus_found++;
-		}
-		cpu++;
-	}
-	return apicid;
-}
-
-
-static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask,
-						  const struct cpumask *andmask)
-{
-	int apicid = cpu_to_logical_apicid(0);
-	cpumask_var_t cpumask;
-
-	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
-		return apicid;
-
-	cpumask_and(cpumask, inmask, andmask);
-	cpumask_and(cpumask, cpumask, cpu_online_mask);
-	apicid = cpu_mask_to_apicid(cpumask);
-
-	free_cpumask_var(cpumask);
-	return apicid;
-}
-
-static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
-	return cpuid_apic >> index_msb;
-}
-
-#endif /* __ASM_ES7000_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-#ifndef __ASM_ES7000_IPI_H
-#define __ASM_ES7000_IPI_H
-
-void send_IPI_mask_sequence(const struct cpumask *mask, int vector);
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector);
-
-static inline void send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	send_IPI_mask_sequence(mask, vector);
-}
-
-static inline void send_IPI_allbutself(int vector)
-{
-	send_IPI_mask_allbutself(cpu_online_mask, vector);
-}
-
-static inline void send_IPI_all(int vector)
-{
-	send_IPI_mask(cpu_online_mask, vector);
-}
-
-#endif /* __ASM_ES7000_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/mpparse.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/mpparse.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/mpparse.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/mpparse.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-#ifndef __ASM_ES7000_MPPARSE_H
-#define __ASM_ES7000_MPPARSE_H
-
-#include <linux/acpi.h>
-
-extern int parse_unisys_oem (char *oemptr);
-extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
-extern void setup_unisys(void);
-
-#ifndef CONFIG_X86_GENERICARCH
-extern int acpi_madt_oem_check(char *oem_id, char *oem_table_id);
-extern int mps_oem_check(struct mpc_table *mpc, char *oem, char *productid);
-#endif
-
-#ifdef CONFIG_ACPI
-
-static inline int es7000_check_dsdt(void)
-{
-	struct acpi_table_header header;
-
-	if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
-	    !strncmp(header.oem_id, "UNISYS", 6))
-		return 1;
-	return 0;
-}
-#endif
-
-#endif /* __ASM_MACH_MPPARSE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/wakecpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/wakecpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/es7000/wakecpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/es7000/wakecpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-#ifndef __ASM_ES7000_WAKECPU_H
-#define __ASM_ES7000_WAKECPU_H
-
-#define TRAMPOLINE_PHYS_LOW	0x467
-#define TRAMPOLINE_PHYS_HIGH	0x469
-
-static inline void wait_for_init_deassert(atomic_t *deassert)
-{
-#ifndef CONFIG_ES7000_CLUSTERED_APIC
-	while (!atomic_read(deassert))
-		cpu_relax();
-#endif
-	return;
-}
-
-/* Nothing to do for most platforms, since cleared by the INIT cycle */
-static inline void smp_callin_clear_local_apic(void)
-{
-}
-
-static inline void store_NMI_vector(unsigned short *high, unsigned short *low)
-{
-}
-
-static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
-{
-}
-
-extern void __inquire_remote_apic(int apicid);
-
-static inline void inquire_remote_apic(int apicid)
-{
-	if (apic_verbosity >= APIC_DEBUG)
-		__inquire_remote_apic(apicid);
-}
-
-#endif /* __ASM_MACH_WAKECPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,119 +0,0 @@
-/*
- * fixmap.h: compile-time virtual memory allocation
- *
- * 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) 1998 Ingo Molnar
- *
- * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
- */
-
-#ifndef _ASM_X86_FIXMAP_32_H
-#define _ASM_X86_FIXMAP_32_H
-
-
-/* used by vmalloc.c, vsyscall.lds.S.
- *
- * Leave one empty page between vmalloc'ed areas and
- * the start of the fixmap.
- */
-extern unsigned long __FIXADDR_TOP;
-#define FIXADDR_USER_START     __fix_to_virt(FIX_VDSO)
-#define FIXADDR_USER_END       __fix_to_virt(FIX_VDSO - 1)
-
-#ifndef __ASSEMBLY__
-#include <linux/kernel.h>
-#include <asm/acpi.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-#include <asm/kmap_types.h>
-
-/*
- * Here we define all the compile-time 'special' virtual
- * addresses. The point is to have a constant address at
- * compile time, but to set the physical address only
- * in the boot process. We allocate these special addresses
- * from the end of virtual memory (0xfffff000) backwards.
- * Also this lets us do fail-safe vmalloc(), we
- * can guarantee that these special addresses and
- * vmalloc()-ed addresses never overlap.
- *
- * these 'compile-time allocated' memory buffers are
- * fixed-size 4k pages. (or larger if used with an increment
- * highger than 1) use fixmap_set(idx,phys) to associate
- * physical memory with fixmap indices.
- *
- * TLB entries of such buffers will not be flushed across
- * task switches.
- */
-enum fixed_addresses {
-	FIX_HOLE,
-	FIX_VDSO,
-	FIX_DBGP_BASE,
-	FIX_EARLYCON_MEM_BASE,
-#ifdef CONFIG_X86_LOCAL_APIC
-	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
-#endif
-#ifdef CONFIG_X86_IO_APIC
-	FIX_IO_APIC_BASE_0,
-	FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
-#endif
-#ifdef CONFIG_X86_VISWS_APIC
-	FIX_CO_CPU,	/* Cobalt timer */
-	FIX_CO_APIC,	/* Cobalt APIC Redirection Table */
-	FIX_LI_PCIA,	/* Lithium PCI Bridge A */
-	FIX_LI_PCIB,	/* Lithium PCI Bridge B */
-#endif
-#ifdef CONFIG_X86_F00F_BUG
-	FIX_F00F_IDT,	/* Virtual mapping for IDT */
-#endif
-#ifdef CONFIG_X86_CYCLONE_TIMER
-	FIX_CYCLONE_TIMER, /*cyclone timer register*/
-#endif
-	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
-#ifdef CONFIG_PCI_MMCONFIG
-	FIX_PCIE_MCFG,
-#endif
-#ifdef CONFIG_PARAVIRT
-	FIX_PARAVIRT_BOOTMAP,
-#endif
-	__end_of_permanent_fixed_addresses,
-	/*
-	 * 256 temporary boot-time mappings, used by early_ioremap(),
-	 * before ioremap() is functional.
-	 *
-	 * We round it up to the next 256 pages boundary so that we
-	 * can have a single pgd entry and a single pte table:
-	 */
-#define NR_FIX_BTMAPS		64
-#define FIX_BTMAPS_SLOTS	4
-	FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
-			(__end_of_permanent_fixed_addresses & 255),
-	FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
-	FIX_WP_TEST,
-#ifdef CONFIG_ACPI
-	FIX_ACPI_BEGIN,
-	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-#endif
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-	FIX_OHCI1394_BASE,
-#endif
-	__end_of_fixed_addresses
-};
-
-extern void reserve_top_address(unsigned long reserve);
-
-
-#define FIXADDR_TOP	((unsigned long)__FIXADDR_TOP)
-
-#define __FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
-#define __FIXADDR_BOOT_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START		(FIXADDR_TOP - __FIXADDR_SIZE)
-#define FIXADDR_BOOT_START	(FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
-
-#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_X86_FIXMAP_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-/*
- * fixmap.h: compile-time virtual memory allocation
- *
- * 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) 1998 Ingo Molnar
- */
-
-#ifndef _ASM_X86_FIXMAP_64_H
-#define _ASM_X86_FIXMAP_64_H
-
-#include <linux/kernel.h>
-#include <asm/acpi.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/vsyscall.h>
-
-/*
- * Here we define all the compile-time 'special' virtual
- * addresses. The point is to have a constant address at
- * compile time, but to set the physical address only
- * in the boot process.
- *
- * These 'compile-time allocated' memory buffers are
- * fixed-size 4k pages (or larger if used with an increment
- * higher than 1). Use set_fixmap(idx,phys) to associate
- * physical memory with fixmap indices.
- *
- * TLB entries of such buffers will not be flushed across
- * task switches.
- */
-
-enum fixed_addresses {
-	VSYSCALL_LAST_PAGE,
-	VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
-			    + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
-	VSYSCALL_HPET,
-	FIX_DBGP_BASE,
-	FIX_EARLYCON_MEM_BASE,
-	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
-	FIX_IO_APIC_BASE_0,
-	FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
-#ifdef CONFIG_PARAVIRT
-	FIX_PARAVIRT_BOOTMAP,
-#endif
-	__end_of_permanent_fixed_addresses,
-#ifdef CONFIG_ACPI
-	FIX_ACPI_BEGIN,
-	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-#endif
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-	FIX_OHCI1394_BASE,
-#endif
-	/*
-	 * 256 temporary boot-time mappings, used by early_ioremap(),
-	 * before ioremap() is functional.
-	 *
-	 * We round it up to the next 256 pages boundary so that we
-	 * can have a single pgd entry and a single pte table:
-	 */
-#define NR_FIX_BTMAPS		64
-#define FIX_BTMAPS_SLOTS	4
-	FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
-			(__end_of_permanent_fixed_addresses & 255),
-	FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
-	__end_of_fixed_addresses
-};
-
-#define FIXADDR_TOP	(VSYSCALL_END-PAGE_SIZE)
-#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
-#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
-
-/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
-#define FIXADDR_USER_START	((unsigned long)VSYSCALL32_VSYSCALL)
-#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
-
-#endif /* _ASM_X86_FIXMAP_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/fixmap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,12 +1,148 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * 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) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ * x86_32 and x86_64 integration by Gustavo F. Padovan, February 2009
+ */
+
 #ifndef _ASM_X86_FIXMAP_H
 #define _ASM_X86_FIXMAP_H
 
+#ifndef __ASSEMBLY__
+#include <linux/kernel.h>
+#include <asm/acpi.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
 #ifdef CONFIG_X86_32
-# include "fixmap_32.h"
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
 #else
-# include "fixmap_64.h"
+#include <asm/vsyscall.h>
 #endif
 
+/*
+ * We can't declare FIXADDR_TOP as variable for x86_64 because vsyscall
+ * uses fixmaps that relies on FIXADDR_TOP for proper address calculation.
+ * Because of this, FIXADDR_TOP x86 integration was left as later work.
+ */
+#ifdef CONFIG_X86_32
+/* used by vmalloc.c, vsyscall.lds.S.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap.
+ */
+extern unsigned long __FIXADDR_TOP;
+#define FIXADDR_TOP	((unsigned long)__FIXADDR_TOP)
+
+#define FIXADDR_USER_START     __fix_to_virt(FIX_VDSO)
+#define FIXADDR_USER_END       __fix_to_virt(FIX_VDSO - 1)
+#else
+#define FIXADDR_TOP	(VSYSCALL_END-PAGE_SIZE)
+
+/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
+#define FIXADDR_USER_START	((unsigned long)VSYSCALL32_VSYSCALL)
+#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
+#endif
+
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process.
+ * for x86_32: We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * These 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages (or larger if used with an increment
+ * higher than 1). Use set_fixmap(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+enum fixed_addresses {
+#ifdef CONFIG_X86_32
+	FIX_HOLE,
+	FIX_VDSO,
+#else
+	VSYSCALL_LAST_PAGE,
+	VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE
+			    + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
+	VSYSCALL_HPET,
+#endif
+	FIX_DBGP_BASE,
+	FIX_EARLYCON_MEM_BASE,
+#ifdef CONFIG_X86_LOCAL_APIC
+	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
+#endif
+#ifdef CONFIG_X86_IO_APIC
+	FIX_IO_APIC_BASE_0,
+	FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
+#endif
+#ifdef CONFIG_X86_VISWS_APIC
+	FIX_CO_CPU,	/* Cobalt timer */
+	FIX_CO_APIC,	/* Cobalt APIC Redirection Table */
+	FIX_LI_PCIA,	/* Lithium PCI Bridge A */
+	FIX_LI_PCIB,	/* Lithium PCI Bridge B */
+#endif
+#ifdef CONFIG_X86_F00F_BUG
+	FIX_F00F_IDT,	/* Virtual mapping for IDT */
+#endif
+#ifdef CONFIG_X86_CYCLONE_TIMER
+	FIX_CYCLONE_TIMER, /*cyclone timer register*/
+#endif
+#ifdef CONFIG_X86_32
+	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
+	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#ifdef CONFIG_PCI_MMCONFIG
+	FIX_PCIE_MCFG,
+#endif
+#endif
+#ifdef CONFIG_PARAVIRT
+	FIX_PARAVIRT_BOOTMAP,
+#endif
+	FIX_TEXT_POKE0,	/* reserve 2 pages for text_poke() */
+	FIX_TEXT_POKE1,
+	__end_of_permanent_fixed_addresses,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+	FIX_OHCI1394_BASE,
+#endif
+	/*
+	 * 256 temporary boot-time mappings, used by early_ioremap(),
+	 * before ioremap() is functional.
+	 *
+	 * We round it up to the next 256 pages boundary so that we
+	 * can have a single pgd entry and a single pte table:
+	 */
+#define NR_FIX_BTMAPS		64
+#define FIX_BTMAPS_SLOTS	4
+	FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
+			(__end_of_permanent_fixed_addresses & 255),
+	FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
+#ifdef CONFIG_X86_32
+	FIX_WP_TEST,
+#endif
+	__end_of_fixed_addresses
+};
+
+
+extern void reserve_top_address(unsigned long reserve);
+
+#define FIXADDR_SIZE	(__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_BOOT_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START		(FIXADDR_TOP - FIXADDR_SIZE)
+#define FIXADDR_BOOT_START	(FIXADDR_TOP - FIXADDR_BOOT_SIZE)
+
 extern int fixmaps_set;
 
 extern pte_t *kmap_pte;
@@ -15,11 +151,11 @@ extern pte_t *pkmap_page_table;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
 void native_set_fixmap(enum fixed_addresses idx,
-		       unsigned long phys, pgprot_t flags);
+		       phys_addr_t phys, pgprot_t flags);
 
 #ifndef CONFIG_PARAVIRT
 static inline void __set_fixmap(enum fixed_addresses idx,
-				unsigned long phys, pgprot_t flags)
+				phys_addr_t phys, pgprot_t flags)
 {
 	native_set_fixmap(idx, phys, flags);
 }
@@ -69,4 +205,5 @@ static inline unsigned long virt_to_fix(
 	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
 	return __virt_to_fix(vaddr);
 }
+#endif /* !__ASSEMBLY__ */
 #endif /* _ASM_X86_FIXMAP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/ftrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,6 +28,13 @@
 
 #endif
 
+/* FIXME: I don't want to stay hardcoded */
+#ifdef CONFIG_X86_64
+# define FTRACE_SYSCALL_MAX     296
+#else
+# define FTRACE_SYSCALL_MAX     333
+#endif
+
 #ifdef CONFIG_FUNCTION_TRACER
 #define MCOUNT_ADDR		((long)(mcount))
 #define MCOUNT_INSN_SIZE	5 /* sizeof mcount call */
@@ -55,29 +62,4 @@ struct dyn_arch_ftrace {
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_FUNCTION_TRACER */
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-
-#ifndef __ASSEMBLY__
-
-/*
- * Stack of return addresses for functions
- * of a thread.
- * Used in struct thread_info
- */
-struct ftrace_ret_stack {
-	unsigned long ret;
-	unsigned long func;
-	unsigned long long calltime;
-};
-
-/*
- * Primary handler of a function return.
- * It relays on ftrace_return_to_handler.
- * Defined in entry_32/64.S
- */
-extern void return_to_handler(void);
-
-#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-
 #endif /* _ASM_X86_FTRACE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,148 +0,0 @@
-#ifndef _ASM_X86_GENAPIC_32_H
-#define _ASM_X86_GENAPIC_32_H
-
-#include <asm/mpspec.h>
-#include <asm/atomic.h>
-
-/*
- * Generic APIC driver interface.
- *
- * An straight forward mapping of the APIC related parts of the
- * x86 subarchitecture interface to a dynamic object.
- *
- * This is used by the "generic" x86 subarchitecture.
- *
- * Copyright 2003 Andi Kleen, SuSE Labs.
- */
-
-struct mpc_bus;
-struct mpc_table;
-struct mpc_cpu;
-
-struct genapic {
-	char *name;
-	int (*probe)(void);
-
-	int (*apic_id_registered)(void);
-	const struct cpumask *(*target_cpus)(void);
-	int int_delivery_mode;
-	int int_dest_mode;
-	int ESR_DISABLE;
-	int apic_destination_logical;
-	unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
-	unsigned long (*check_apicid_present)(int apicid);
-	int no_balance_irq;
-	int no_ioapic_check;
-	void (*init_apic_ldr)(void);
-	physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
-
-	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 (*setup_portio_remap)(void);
-	int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
-	void (*enable_apic_mode)(void);
-	u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
-
-	/* mpparse */
-	/* When one of the next two hooks returns 1 the genapic
-	   is switched to this. Essentially they are additional probe
-	   functions. */
-	int (*mps_oem_check)(struct mpc_table *mpc, char *oem,
-			     char *productid);
-	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
-
-	unsigned (*get_apic_id)(unsigned long x);
-	unsigned long apic_id_mask;
-	unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
-	unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
-					       const struct cpumask *andmask);
-	void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
-
-#ifdef CONFIG_SMP
-	/* ipi */
-	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
-	void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
-					 int vector);
-	void (*send_IPI_allbutself)(int vector);
-	void (*send_IPI_all)(int vector);
-#endif
-	int (*wakeup_cpu)(int apicid, unsigned long start_eip);
-	int trampoline_phys_low;
-	int trampoline_phys_high;
-	void (*wait_for_init_deassert)(atomic_t *deassert);
-	void (*smp_callin_clear_local_apic)(void);
-	void (*store_NMI_vector)(unsigned short *high, unsigned short *low);
-	void (*restore_NMI_vector)(unsigned short *high, unsigned short *low);
-	void (*inquire_remote_apic)(int apicid);
-};
-
-#define APICFUNC(x) .x = x,
-
-/* More functions could be probably marked IPIFUNC and save some space
-   in UP GENERICARCH kernels, but I don't have the nerve right now
-   to untangle this mess. -AK  */
-#ifdef CONFIG_SMP
-#define IPIFUNC(x) APICFUNC(x)
-#else
-#define IPIFUNC(x)
-#endif
-
-#define APIC_INIT(aname, aprobe)			\
-{							\
-	.name = aname,					\
-	.probe = aprobe,				\
-	.int_delivery_mode = INT_DELIVERY_MODE,		\
-	.int_dest_mode = INT_DEST_MODE,			\
-	.no_balance_irq = NO_BALANCE_IRQ,		\
-	.ESR_DISABLE = esr_disable,			\
-	.apic_destination_logical = APIC_DEST_LOGICAL,	\
-	APICFUNC(apic_id_registered)			\
-	APICFUNC(target_cpus)				\
-	APICFUNC(check_apicid_used)			\
-	APICFUNC(check_apicid_present)			\
-	APICFUNC(init_apic_ldr)				\
-	APICFUNC(ioapic_phys_id_map)			\
-	APICFUNC(setup_apic_routing)			\
-	APICFUNC(multi_timer_check)			\
-	APICFUNC(apicid_to_node)			\
-	APICFUNC(cpu_to_logical_apicid)			\
-	APICFUNC(cpu_present_to_apicid)			\
-	APICFUNC(apicid_to_cpu_present)			\
-	APICFUNC(setup_portio_remap)			\
-	APICFUNC(check_phys_apicid_present)		\
-	APICFUNC(mps_oem_check)				\
-	APICFUNC(get_apic_id)				\
-	.apic_id_mask = APIC_ID_MASK,			\
-	APICFUNC(cpu_mask_to_apicid)			\
-	APICFUNC(cpu_mask_to_apicid_and)		\
-	APICFUNC(vector_allocation_domain)		\
-	APICFUNC(acpi_madt_oem_check)			\
-	IPIFUNC(send_IPI_mask)				\
-	IPIFUNC(send_IPI_allbutself)			\
-	IPIFUNC(send_IPI_all)				\
-	APICFUNC(enable_apic_mode)			\
-	APICFUNC(phys_pkg_id)				\
-	.trampoline_phys_low = TRAMPOLINE_PHYS_LOW,		\
-	.trampoline_phys_high = TRAMPOLINE_PHYS_HIGH,		\
-	APICFUNC(wait_for_init_deassert)		\
-	APICFUNC(smp_callin_clear_local_apic)		\
-	APICFUNC(store_NMI_vector)			\
-	APICFUNC(restore_NMI_vector)			\
-	APICFUNC(inquire_remote_apic)			\
-}
-
-extern struct genapic *genapic;
-extern void es7000_update_genapic_to_cluster(void);
-
-enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
-#define get_uv_system_type()		UV_NONE
-#define is_uv_system()			0
-#define uv_wakeup_secondary(a, b)	1
-#define uv_system_init()		do {} while (0)
-
-
-#endif /* _ASM_X86_GENAPIC_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,66 +0,0 @@
-#ifndef _ASM_X86_GENAPIC_64_H
-#define _ASM_X86_GENAPIC_64_H
-
-#include <linux/cpumask.h>
-
-/*
- * Copyright 2004 James Cleverdon, IBM.
- * Subject to the GNU Public License, v.2
- *
- * Generic APIC sub-arch data struct.
- *
- * Hacked for x86-64 by James Cleverdon from i386 architecture code by
- * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
- * James Cleverdon.
- */
-
-struct genapic {
-	char *name;
-	int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
-	u32 int_delivery_mode;
-	u32 int_dest_mode;
-	int (*apic_id_registered)(void);
-	const struct cpumask *(*target_cpus)(void);
-	void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
-	void (*init_apic_ldr)(void);
-	/* ipi */
-	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
-	void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
-					 int vector);
-	void (*send_IPI_allbutself)(int vector);
-	void (*send_IPI_all)(int vector);
-	void (*send_IPI_self)(int vector);
-	/* */
-	unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
-	unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
-					       const struct cpumask *andmask);
-	unsigned int (*phys_pkg_id)(int index_msb);
-	unsigned int (*get_apic_id)(unsigned long x);
-	unsigned long (*set_apic_id)(unsigned int id);
-	unsigned long apic_id_mask;
-	/* wakeup_secondary_cpu */
-	int (*wakeup_cpu)(int apicid, unsigned long start_eip);
-};
-
-extern struct genapic *genapic;
-
-extern struct genapic apic_flat;
-extern struct genapic apic_physflat;
-extern struct genapic apic_x2apic_cluster;
-extern struct genapic apic_x2apic_phys;
-extern int acpi_madt_oem_check(char *, char *);
-
-extern void apic_send_IPI_self(int vector);
-enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
-extern enum uv_system_type get_uv_system_type(void);
-extern int is_uv_system(void);
-
-extern struct genapic apic_x2apic_uv_x;
-DECLARE_PER_CPU(int, x2apic_extra_bits);
-extern void uv_cpu_init(void);
-extern void uv_system_init(void);
-extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
-
-extern void setup_apic_routing(void);
-
-#endif /* _ASM_X86_GENAPIC_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/genapic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/genapic.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1 @@
-#ifdef CONFIG_X86_32
-# include "genapic_32.h"
-#else
-# include "genapic_64.h"
-#endif
+#include <asm/apic.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-#ifndef _ASM_X86_HARDIRQ_32_H
-#define _ASM_X86_HARDIRQ_32_H
-
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-typedef struct {
-	unsigned int __softirq_pending;
-	unsigned long idle_timestamp;
-	unsigned int __nmi_count;	/* arch dependent */
-	unsigned int apic_timer_irqs;	/* arch dependent */
-	unsigned int irq0_irqs;
-	unsigned int irq_resched_count;
-	unsigned int irq_call_count;
-	unsigned int irq_tlb_count;
-	unsigned int irq_thermal_count;
-	unsigned int irq_spurious_count;
-} ____cacheline_aligned irq_cpustat_t;
-
-DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
-
-#define __ARCH_IRQ_STAT
-#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
-
-#define inc_irq_stat(member)	(__get_cpu_var(irq_stat).member++)
-
-void ack_bad_irq(unsigned int irq);
-#include <linux/irq_cpustat.h>
-
-#endif /* _ASM_X86_HARDIRQ_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-#ifndef _ASM_X86_HARDIRQ_64_H
-#define _ASM_X86_HARDIRQ_64_H
-
-#include <linux/threads.h>
-#include <linux/irq.h>
-#include <asm/pda.h>
-#include <asm/apic.h>
-
-/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
-#define MAX_HARDIRQS_PER_CPU NR_VECTORS
-
-#define __ARCH_IRQ_STAT 1
-
-#define inc_irq_stat(member)	add_pda(member, 1)
-
-#define local_softirq_pending() read_pda(__softirq_pending)
-
-#define __ARCH_SET_SOFTIRQ_PENDING 1
-
-#define set_softirq_pending(x) write_pda(__softirq_pending, (x))
-#define or_softirq_pending(x)  or_pda(__softirq_pending, (x))
-
-extern void ack_bad_irq(unsigned int irq);
-
-#endif /* _ASM_X86_HARDIRQ_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/hardirq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/hardirq.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,53 @@
-#ifdef CONFIG_X86_32
-# include "hardirq_32.h"
-#else
-# include "hardirq_64.h"
+#ifndef _ASM_X86_HARDIRQ_H
+#define _ASM_X86_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __nmi_count;	/* arch dependent */
+	unsigned int irq0_irqs;
+#ifdef CONFIG_X86_LOCAL_APIC
+	unsigned int apic_timer_irqs;	/* arch dependent */
+	unsigned int irq_spurious_count;
+#endif
+	unsigned int generic_irqs;	/* arch dependent */
+#ifdef CONFIG_SMP
+	unsigned int irq_resched_count;
+	unsigned int irq_call_count;
+	unsigned int irq_tlb_count;
+#endif
+#ifdef CONFIG_X86_MCE
+	unsigned int irq_thermal_count;
+# ifdef CONFIG_X86_64
+	unsigned int irq_threshold_count;
+# endif
 #endif
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+
+/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
+#define MAX_HARDIRQS_PER_CPU NR_VECTORS
+
+#define __ARCH_IRQ_STAT
+
+#define inc_irq_stat(member)	percpu_add(irq_stat.member, 1)
+
+#define local_softirq_pending()	percpu_read(irq_stat.__softirq_pending)
+
+#define __ARCH_SET_SOFTIRQ_PENDING
+
+#define set_softirq_pending(x)	percpu_write(irq_stat.__softirq_pending, (x))
+#define or_softirq_pending(x)	percpu_or(irq_stat.__softirq_pending, (x))
+
+extern void ack_bad_irq(unsigned int irq);
 
 extern u64 arch_irq_stat_cpu(unsigned int cpu);
 #define arch_irq_stat_cpu	arch_irq_stat_cpu
 
 extern u64 arch_irq_stat(void);
 #define arch_irq_stat		arch_irq_stat
+
+#endif /* _ASM_X86_HARDIRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/highmem.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/highmem.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/highmem.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/highmem.h	2009-06-09 23:05:27.000000000 -0400
@@ -63,6 +63,7 @@ void *kmap_atomic_prot(struct page *page
 void *kmap_atomic(struct page *page, enum km_type type);
 void kunmap_atomic(void *kvaddr, enum km_type type);
 void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
 struct page *kmap_atomic_to_page(void *ptr);
 
 #ifndef CONFIG_PARAVIRT
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/hw_irq.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/hw_irq.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/hw_irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/hw_irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,10 +25,9 @@
 #include <asm/irq.h>
 #include <asm/sections.h>
 
-#define platform_legacy_irq(irq)	((irq) < 16)
-
 /* Interrupt handlers registered during init_IRQ */
 extern void apic_timer_interrupt(void);
+extern void generic_interrupt(void);
 extern void error_interrupt(void);
 extern void spurious_interrupt(void);
 extern void thermal_interrupt(void);
@@ -58,7 +57,7 @@ extern void make_8259A_irq(unsigned int
 extern void init_8259A(int aeoi);
 
 /* IOAPIC */
-#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
+#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
 extern unsigned long io_apic_irqs;
 
 extern void init_VISWS_APIC_irqs(void);
@@ -67,15 +66,7 @@ extern void disable_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void setup_ioapic_dest(void);
 
-#ifdef CONFIG_X86_64
 extern void enable_IO_APIC(void);
-#endif
-
-/* IPI functions */
-#ifdef CONFIG_X86_32
-extern void send_IPI_self(int vector);
-#endif
-extern void send_IPI(int dest, int vector);
 
 /* Statistics */
 extern atomic_t irq_err_count;
@@ -84,21 +75,11 @@ extern atomic_t irq_mis_count;
 /* EISA */
 extern void eisa_set_level_irq(unsigned int irq);
 
-/* Voyager functions */
-extern asmlinkage void vic_cpi_interrupt(void);
-extern asmlinkage void vic_sys_interrupt(void);
-extern asmlinkage void vic_cmn_interrupt(void);
-extern asmlinkage void qic_timer_interrupt(void);
-extern asmlinkage void qic_invalidate_interrupt(void);
-extern asmlinkage void qic_reschedule_interrupt(void);
-extern asmlinkage void qic_enable_irq_interrupt(void);
-extern asmlinkage void qic_call_function_interrupt(void);
-
 /* SMP */
 extern void smp_apic_timer_interrupt(struct pt_regs *);
 extern void smp_spurious_interrupt(struct pt_regs *);
 extern void smp_error_interrupt(struct pt_regs *);
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
 extern void smp_reschedule_interrupt(struct pt_regs *);
 extern void smp_call_function_interrupt(struct pt_regs *);
 extern void smp_call_function_single_interrupt(struct pt_regs *);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/i8259.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/i8259.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/i8259.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/i8259.h	2009-06-09 23:05:27.000000000 -0400
@@ -60,4 +60,8 @@ extern struct irq_chip i8259A_chip;
 extern void mask_8259A(void);
 extern void unmask_8259A(void);
 
+#ifdef CONFIG_X86_32
+extern void init_ISA_irqs(void);
+#endif
+
 #endif /* _ASM_X86_I8259_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/ia32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/ia32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/ia32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/ia32.h	2009-06-09 23:05:27.000000000 -0400
@@ -129,13 +129,6 @@ typedef struct compat_siginfo {
 	} _sifields;
 } compat_siginfo_t;
 
-struct ustat32 {
-	__u32			f_tfree;
-	compat_ino_t		f_tinode;
-	char			f_fname[6];
-	char			f_fpack[6];
-};
-
 #define IA32_STACK_TOP IA32_PAGE_OFFSET
 
 #ifdef __KERNEL__
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/init.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/init.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/init.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/init.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+#ifndef _ASM_X86_INIT_32_H
+#define _ASM_X86_INIT_32_H
+
+#ifdef CONFIG_X86_32
+extern void __init early_ioremap_page_table_range_init(void);
+#endif
+
+extern unsigned long __init
+kernel_physical_mapping_init(unsigned long start,
+			     unsigned long end,
+			     unsigned long page_size_mask);
+
+
+extern unsigned long __initdata e820_table_start;
+extern unsigned long __meminitdata e820_table_end;
+extern unsigned long __meminitdata e820_table_top;
+
+#endif /* _ASM_X86_INIT_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,8 +37,6 @@
   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   */
 
-#define IO_SPACE_LIMIT 0xffff
-
 #define XQUAD_PORTIO_BASE 0xfe400000
 #define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
 
@@ -53,92 +51,6 @@
  */
 #define xlate_dev_kmem_ptr(p)	p
 
-/**
- *	virt_to_phys	-	map virtual addresses to physical
- *	@address: address to remap
- *
- *	The returned physical address is the physical (CPU) mapping for
- *	the memory address given. It is only valid to use this function on
- *	addresses directly mapped or allocated via kmalloc.
- *
- *	This function does not give bus mappings for DMA transfers. In
- *	almost all conceivable cases a device driver should not be using
- *	this function
- */
-
-static inline unsigned long virt_to_phys(volatile void *address)
-{
-	return __pa(address);
-}
-
-/**
- *	phys_to_virt	-	map physical address to virtual
- *	@address: address to remap
- *
- *	The returned virtual address is a current CPU mapping for
- *	the memory address given. It is only valid to use this function on
- *	addresses that have a kernel mapping
- *
- *	This function does not handle bus mappings for DMA transfers. In
- *	almost all conceivable cases a device driver should not be using
- *	this function
- */
-
-static inline void *phys_to_virt(unsigned long address)
-{
-	return __va(address);
-}
-
-/*
- * Change "struct page" to physical address.
- */
-#define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-
-/**
- * ioremap     -   map bus memory into CPU space
- * @offset:    bus address of the memory
- * @size:      size of the resource to map
- *
- * ioremap performs a platform specific sequence of operations to
- * make bus memory CPU accessible via the readb/readw/readl/writeb/
- * writew/writel functions and the other mmio helpers. The returned
- * address is not guaranteed to be usable directly as a virtual
- * address.
- *
- * If the area you are trying to map is a PCI BAR you should have a
- * look at pci_iomap().
- */
-extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
-extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
-extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
-				unsigned long prot_val);
-
-/*
- * The default ioremap() behavior is non-cached:
- */
-static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
-{
-	return ioremap_nocache(offset, size);
-}
-
-extern void iounmap(volatile void __iomem *addr);
-
-/*
- * ISA I/O bus memory addresses are 1:1 with the physical address.
- */
-#define isa_virt_to_bus virt_to_phys
-#define isa_page_to_bus page_to_phys
-#define isa_bus_to_virt phys_to_virt
-
-/*
- * However PCI ones are not necessarily 1:1 and therefore these interfaces
- * are forbidden in portable PCI drivers.
- *
- * Allow them on x86 for legacy drivers, though.
- */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
 static inline void
 memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -136,73 +136,12 @@ __OUTS(b)
 __OUTS(w)
 __OUTS(l)
 
-#define IO_SPACE_LIMIT 0xffff
-
 #if defined(__KERNEL__) && defined(__x86_64__)
 
 #include <linux/vmalloc.h>
 
-#ifndef __i386__
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are pretty trivial
- */
-static inline unsigned long virt_to_phys(volatile void *address)
-{
-	return __pa(address);
-}
-
-static inline void *phys_to_virt(unsigned long address)
-{
-	return __va(address);
-}
-#endif
-
-/*
- * Change "struct page" to physical address.
- */
-#define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-
 #include <asm-generic/iomap.h>
 
-/*
- * This one maps high address device memory and turns off caching for that area.
- * it's useful if some control registers are in such an area and write combining
- * or read caching is not desirable:
- */
-extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
-extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
-extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
-				unsigned long prot_val);
-
-/*
- * The default ioremap() behavior is non-cached:
- */
-static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
-{
-	return ioremap_nocache(offset, size);
-}
-
-extern void iounmap(volatile void __iomem *addr);
-
-extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
-
-/*
- * ISA I/O bus memory addresses are 1:1 with the physical address.
- */
-#define isa_virt_to_bus virt_to_phys
-#define isa_page_to_bus page_to_phys
-#define isa_bus_to_virt phys_to_virt
-
-/*
- * However PCI ones are not necessarily 1:1 and therefore these interfaces
- * are forbidden in portable PCI drivers.
- *
- * Allow them on x86 for legacy drivers, though.
- */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
 void __memcpy_fromio(void *, unsigned long, unsigned);
 void __memcpy_toio(unsigned long, const void *, unsigned);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/io_apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_apic.h	2009-06-09 23:05:27.000000000 -0400
@@ -114,38 +114,16 @@ struct IR_IO_APIC_route_entry {
 extern int nr_ioapics;
 extern int nr_ioapic_registers[MAX_IO_APICS];
 
-/*
- * MP-BIOS irq configuration table structures:
- */
-
 #define MP_MAX_IOAPIC_PIN 127
 
-struct mp_config_ioapic {
-	unsigned long mp_apicaddr;
-	unsigned int mp_apicid;
-	unsigned char mp_type;
-	unsigned char mp_apicver;
-	unsigned char mp_flags;
-};
-
-struct mp_config_intsrc {
-	unsigned int mp_dstapic;
-	unsigned char mp_type;
-	unsigned char mp_irqtype;
-	unsigned short mp_irqflag;
-	unsigned char mp_srcbus;
-	unsigned char mp_srcbusirq;
-	unsigned char mp_dstirq;
-};
-
 /* I/O APIC entries */
-extern struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
+extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
 
 /* # of MP IRQ source entries */
 extern int mp_irq_entries;
 
 /* MP IRQ source entries */
-extern struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
@@ -165,15 +143,6 @@ extern int noioapicreroute;
 /* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
 extern int timer_through_8259;
 
-static inline void disable_ioapic_setup(void)
-{
-#ifdef CONFIG_PCI
-	noioapicquirk = 1;
-	noioapicreroute = -1;
-#endif
-	skip_ioapic_setup = 1;
-}
-
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
  * assignment of PCI IRQ's.
@@ -193,13 +162,23 @@ extern int (*ioapic_renumber_irq)(int io
 extern void ioapic_init_mappings(void);
 
 #ifdef CONFIG_X86_64
-extern int save_mask_IO_APIC_setup(void);
-extern void restore_IO_APIC_setup(void);
-extern void reinit_intr_remapped_IO_APIC(int);
+extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
+extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
+extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
+	struct IO_APIC_route_entry **ioapic_entries);
 #endif
 
 extern void probe_nr_irqs_gsi(void);
 
+extern int setup_ioapic_entry(int apic, int irq,
+			      struct IO_APIC_route_entry *entry,
+			      unsigned int destination, int trigger,
+			      int polarity, int vector, int pin);
+extern void ioapic_write_entry(int apic, int pin,
+			       struct IO_APIC_route_entry e);
 #else  /* !CONFIG_X86_IO_APIC */
 #define io_apic_assign_pci_irqs 0
 static const int timer_through_8259 = 0;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/io.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
 
 #include <linux/compiler.h>
 #include <asm-generic/int-ll64.h>
+#include <asm/page.h>
 
 #define build_mmio_read(name, size, type, reg, barrier) \
 static inline type name(const volatile void __iomem *addr) \
@@ -80,6 +81,98 @@ static inline void writeq(__u64 val, vol
 #define readq			readq
 #define writeq			writeq
 
+/**
+ *	virt_to_phys	-	map virtual addresses to physical
+ *	@address: address to remap
+ *
+ *	The returned physical address is the physical (CPU) mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses directly mapped or allocated via kmalloc.
+ *
+ *	This function does not give bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+
+static inline phys_addr_t virt_to_phys(volatile void *address)
+{
+	return __pa(address);
+}
+
+/**
+ *	phys_to_virt	-	map physical address to virtual
+ *	@address: address to remap
+ *
+ *	The returned virtual address is a current CPU mapping for
+ *	the memory address given. It is only valid to use this function on
+ *	addresses that have a kernel mapping
+ *
+ *	This function does not handle bus mappings for DMA transfers. In
+ *	almost all conceivable cases a device driver should not be using
+ *	this function
+ */
+
+static inline void *phys_to_virt(phys_addr_t address)
+{
+	return __va(address);
+}
+
+/*
+ * Change "struct page" to physical address.
+ */
+#define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+
+/*
+ * ISA I/O bus memory addresses are 1:1 with the physical address.
+ * However, we truncate the address to unsigned int to avoid undesirable
+ * promitions in legacy drivers.
+ */
+static inline unsigned int isa_virt_to_bus(volatile void *address)
+{
+	return (unsigned int)virt_to_phys(address);
+}
+#define isa_page_to_bus(page)	((unsigned int)page_to_phys(page))
+#define isa_bus_to_virt		phys_to_virt
+
+/*
+ * However PCI ones are not necessarily 1:1 and therefore these interfaces
+ * are forbidden in portable PCI drivers.
+ *
+ * Allow them on x86 for legacy drivers, though.
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+/**
+ * ioremap     -   map bus memory into CPU space
+ * @offset:    bus address of the memory
+ * @size:      size of the resource to map
+ *
+ * ioremap performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * If the area you are trying to map is a PCI BAR you should have a
+ * look at pci_iomap().
+ */
+extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
+extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
+extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
+				unsigned long prot_val);
+
+/*
+ * The default ioremap() behavior is non-cached:
+ */
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return ioremap_nocache(offset, size);
+}
+
+extern void iounmap(volatile void __iomem *addr);
+
+
 #ifdef CONFIG_X86_32
 # include "io_32.h"
 #else
@@ -91,7 +184,7 @@ extern void unxlate_dev_mem_ptr(unsigned
 
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				unsigned long prot_val);
-extern void __iomem *ioremap_wc(unsigned long offset, unsigned long size);
+extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
 
 /*
  * early_ioremap() and early_iounmap() are for temporary early boot-time
@@ -100,10 +193,12 @@ extern void __iomem *ioremap_wc(unsigned
  */
 extern void early_ioremap_init(void);
 extern void early_ioremap_reset(void);
-extern void __iomem *early_ioremap(unsigned long offset, unsigned long size);
-extern void __iomem *early_memremap(unsigned long offset, unsigned long size);
+extern void __iomem *early_ioremap(resource_size_t phys_addr,
+				   unsigned long size);
+extern void __iomem *early_memremap(resource_size_t phys_addr,
+				    unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
-extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
 
+#define IO_SPACE_LIMIT 0xffff
 
 #endif /* _ASM_X86_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/iommu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/iommu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/iommu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/iommu.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 
 extern void pci_iommu_shutdown(void);
 extern void no_iommu_init(void);
-extern struct dma_mapping_ops nommu_dma_ops;
+extern struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/ipi.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_IPI_H
 #define _ASM_X86_IPI_H
 
+#ifdef CONFIG_X86_LOCAL_APIC
+
 /*
  * Copyright 2004 James Cleverdon, IBM.
  * Subject to the GNU Public License, v.2
@@ -55,8 +57,8 @@ static inline void __xapic_wait_icr_idle
 		cpu_relax();
 }
 
-static inline void __send_IPI_shortcut(unsigned int shortcut, int vector,
-				       unsigned int dest)
+static inline void
+__default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
 {
 	/*
 	 * Subtle. In the case of the 'never do double writes' workaround
@@ -87,8 +89,8 @@ static inline void __send_IPI_shortcut(u
  * This is used to send an IPI with no shorthand notation (the destination is
  * specified in bits 56 to 63 of the ICR).
  */
-static inline void __send_IPI_dest_field(unsigned int mask, int vector,
-					 unsigned int dest)
+static inline void
+ __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
 {
 	unsigned long cfg;
 
@@ -117,41 +119,44 @@ static inline void __send_IPI_dest_field
 	native_apic_mem_write(APIC_ICR, cfg);
 }
 
-static inline void send_IPI_mask_sequence(const struct cpumask *mask,
-					  int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
+extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
+						 int vector);
+extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
+							 int vector);
+extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
+							 int vector);
+extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
+							 int vector);
 
-	/*
-	 * Hack. The clustered APIC addressing mode doesn't allow us to send
-	 * to an arbitrary mask, so I do a unicast to each CPU instead.
-	 * - mbligh
-	 */
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		__send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
-				      vector, APIC_DEST_PHYSICAL);
-	}
-	local_irq_restore(flags);
+/* Avoid include hell */
+#define NMI_VECTOR 0x02
+
+extern int no_broadcast;
+
+static inline void __default_local_send_IPI_allbutself(int vector)
+{
+	if (no_broadcast || vector == NMI_VECTOR)
+		apic->send_IPI_mask_allbutself(cpu_online_mask, vector);
+	else
+		__default_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, apic->dest_logical);
 }
 
-static inline void send_IPI_mask_allbutself(const struct cpumask *mask,
-					    int vector)
+static inline void __default_local_send_IPI_all(int vector)
 {
-	unsigned long flags;
-	unsigned int query_cpu;
-	unsigned int this_cpu = smp_processor_id();
+	if (no_broadcast || vector == NMI_VECTOR)
+		apic->send_IPI_mask(cpu_online_mask, vector);
+	else
+		__default_send_IPI_shortcut(APIC_DEST_ALLINC, vector, apic->dest_logical);
+}
 
-	/* See Hack comment above */
+#ifdef CONFIG_X86_32
+extern void default_send_IPI_mask_logical(const struct cpumask *mask,
+						 int vector);
+extern void default_send_IPI_allbutself(int vector);
+extern void default_send_IPI_all(int vector);
+extern void default_send_IPI_self(int vector);
+#endif
 
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask)
-		if (query_cpu != this_cpu)
-			__send_IPI_dest_field(
-				per_cpu(x86_cpu_to_apicid, query_cpu),
-				vector, APIC_DEST_PHYSICAL);
-	local_irq_restore(flags);
-}
+#endif
 
 #endif /* _ASM_X86_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,9 +36,12 @@ static inline int irq_canonicalize(int i
 extern void fixup_irqs(void);
 #endif
 
-extern unsigned int do_IRQ(struct pt_regs *regs);
+extern void (*generic_interrupt_extension)(void);
 extern void init_IRQ(void);
 extern void native_init_IRQ(void);
+extern bool handle_irq(unsigned irq, struct pt_regs *regs);
+
+extern unsigned int do_IRQ(struct pt_regs *regs);
 
 /* Interrupt vector management */
 extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/*
- * Per-cpu current frame pointer - the location of the last exception frame on
- * the stack, stored in the per-cpu area.
- *
- * Jeremy Fitzhardinge <jeremy@goop.org>
- */
-#ifndef _ASM_X86_IRQ_REGS_32_H
-#define _ASM_X86_IRQ_REGS_32_H
-
-#include <asm/percpu.h>
-
-#define ARCH_HAS_OWN_IRQ_REGS
-
-DECLARE_PER_CPU(struct pt_regs *, irq_regs);
-
-static inline struct pt_regs *get_irq_regs(void)
-{
-	return x86_read_percpu(irq_regs);
-}
-
-static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
-{
-	struct pt_regs *old_regs;
-
-	old_regs = get_irq_regs();
-	x86_write_percpu(irq_regs, new_regs);
-
-	return old_regs;
-}
-
-#endif /* _ASM_X86_IRQ_REGS_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include <asm-generic/irq_regs.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,31 @@
-#ifdef CONFIG_X86_32
-# include "irq_regs_32.h"
-#else
-# include "irq_regs_64.h"
-#endif
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack, stored in the per-cpu area.
+ *
+ * Jeremy Fitzhardinge <jeremy@goop.org>
+ */
+#ifndef _ASM_X86_IRQ_REGS_H
+#define _ASM_X86_IRQ_REGS_H
+
+#include <asm/percpu.h>
+
+#define ARCH_HAS_OWN_IRQ_REGS
+
+DECLARE_PER_CPU(struct pt_regs *, irq_regs);
+
+static inline struct pt_regs *get_irq_regs(void)
+{
+	return percpu_read(irq_regs);
+}
+
+static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
+{
+	struct pt_regs *old_regs;
+
+	old_regs = get_irq_regs();
+	percpu_write(irq_regs, new_regs);
+
+	return old_regs;
+}
+
+#endif /* _ASM_X86_IRQ_REGS_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_remapping.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_remapping.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_remapping.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_remapping.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,8 +1,6 @@
 #ifndef _ASM_X86_IRQ_REMAPPING_H
 #define _ASM_X86_IRQ_REMAPPING_H
 
-extern int x2apic;
-
 #define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
 
 #endif	/* _ASM_X86_IRQ_REMAPPING_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_vectors.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_vectors.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/irq_vectors.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/irq_vectors.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,47 +1,69 @@
 #ifndef _ASM_X86_IRQ_VECTORS_H
 #define _ASM_X86_IRQ_VECTORS_H
 
-#include <linux/threads.h>
+/*
+ * Linux IRQ vector layout.
+ *
+ * There are 256 IDT entries (per CPU - each entry is 8 bytes) which can
+ * be defined by Linux. They are used as a jump table by the CPU when a
+ * given vector is triggered - by a CPU-external, CPU-internal or
+ * software-triggered event.
+ *
+ * Linux sets the kernel code address each entry jumps to early during
+ * bootup, and never changes them. This is the general layout of the
+ * IDT entries:
+ *
+ *  Vectors   0 ...  31 : system traps and exceptions - hardcoded events
+ *  Vectors  32 ... 127 : device interrupts
+ *  Vector  128         : legacy int80 syscall interface
+ *  Vectors 129 ... 237 : device interrupts
+ *  Vectors 238 ... 255 : special interrupts
+ *
+ * 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table.
+ *
+ * This file enumerates the exact layout of them:
+ */
 
-#define NMI_VECTOR		0x02
+#define NMI_VECTOR			0x02
 
 /*
  * IDT vectors usable for external interrupt sources start
  * at 0x20:
  */
-#define FIRST_EXTERNAL_VECTOR	0x20
+#define FIRST_EXTERNAL_VECTOR		0x20
 
 #ifdef CONFIG_X86_32
-# define SYSCALL_VECTOR		0x80
+# define SYSCALL_VECTOR			0x80
 #else
-# define IA32_SYSCALL_VECTOR	0x80
+# define IA32_SYSCALL_VECTOR		0x80
 #endif
 
 /*
  * Reserve the lowest usable priority level 0x20 - 0x2f for triggering
  * cleanup after irq migration.
  */
-#define IRQ_MOVE_CLEANUP_VECTOR	FIRST_EXTERNAL_VECTOR
+#define IRQ_MOVE_CLEANUP_VECTOR		FIRST_EXTERNAL_VECTOR
 
 /*
  * Vectors 0x30-0x3f are used for ISA interrupts.
  */
-#define IRQ0_VECTOR		(FIRST_EXTERNAL_VECTOR + 0x10)
-#define IRQ1_VECTOR		(IRQ0_VECTOR + 1)
-#define IRQ2_VECTOR		(IRQ0_VECTOR + 2)
-#define IRQ3_VECTOR		(IRQ0_VECTOR + 3)
-#define IRQ4_VECTOR		(IRQ0_VECTOR + 4)
-#define IRQ5_VECTOR		(IRQ0_VECTOR + 5)
-#define IRQ6_VECTOR		(IRQ0_VECTOR + 6)
-#define IRQ7_VECTOR		(IRQ0_VECTOR + 7)
-#define IRQ8_VECTOR		(IRQ0_VECTOR + 8)
-#define IRQ9_VECTOR		(IRQ0_VECTOR + 9)
-#define IRQ10_VECTOR		(IRQ0_VECTOR + 10)
-#define IRQ11_VECTOR		(IRQ0_VECTOR + 11)
-#define IRQ12_VECTOR		(IRQ0_VECTOR + 12)
-#define IRQ13_VECTOR		(IRQ0_VECTOR + 13)
-#define IRQ14_VECTOR		(IRQ0_VECTOR + 14)
-#define IRQ15_VECTOR		(IRQ0_VECTOR + 15)
+#define IRQ0_VECTOR			(FIRST_EXTERNAL_VECTOR + 0x10)
+
+#define IRQ1_VECTOR			(IRQ0_VECTOR +  1)
+#define IRQ2_VECTOR			(IRQ0_VECTOR +  2)
+#define IRQ3_VECTOR			(IRQ0_VECTOR +  3)
+#define IRQ4_VECTOR			(IRQ0_VECTOR +  4)
+#define IRQ5_VECTOR			(IRQ0_VECTOR +  5)
+#define IRQ6_VECTOR			(IRQ0_VECTOR +  6)
+#define IRQ7_VECTOR			(IRQ0_VECTOR +  7)
+#define IRQ8_VECTOR			(IRQ0_VECTOR +  8)
+#define IRQ9_VECTOR			(IRQ0_VECTOR +  9)
+#define IRQ10_VECTOR			(IRQ0_VECTOR + 10)
+#define IRQ11_VECTOR			(IRQ0_VECTOR + 11)
+#define IRQ12_VECTOR			(IRQ0_VECTOR + 12)
+#define IRQ13_VECTOR			(IRQ0_VECTOR + 13)
+#define IRQ14_VECTOR			(IRQ0_VECTOR + 14)
+#define IRQ15_VECTOR			(IRQ0_VECTOR + 15)
 
 /*
  * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
@@ -49,119 +71,103 @@
  *  some of the following vectors are 'rare', they are merged
  *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
  *  TLB, reschedule and local APIC vectors are performance-critical.
- *
- *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
  */
-#ifdef CONFIG_X86_32
-
-# define SPURIOUS_APIC_VECTOR		0xff
-# define ERROR_APIC_VECTOR		0xfe
-# define INVALIDATE_TLB_VECTOR		0xfd
-# define RESCHEDULE_VECTOR		0xfc
-# define CALL_FUNCTION_VECTOR		0xfb
-# define CALL_FUNCTION_SINGLE_VECTOR	0xfa
-# define THERMAL_APIC_VECTOR		0xf0
-
-#else
 
 #define SPURIOUS_APIC_VECTOR		0xff
+/*
+ * Sanity check
+ */
+#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
+# error SPURIOUS_APIC_VECTOR definition error
+#endif
+
 #define ERROR_APIC_VECTOR		0xfe
 #define RESCHEDULE_VECTOR		0xfd
 #define CALL_FUNCTION_VECTOR		0xfc
 #define CALL_FUNCTION_SINGLE_VECTOR	0xfb
 #define THERMAL_APIC_VECTOR		0xfa
-#define THRESHOLD_APIC_VECTOR		0xf9
-#define UV_BAU_MESSAGE			0xf8
-#define INVALIDATE_TLB_VECTOR_END	0xf7
-#define INVALIDATE_TLB_VECTOR_START	0xf0	/* f0-f7 used for TLB flush */
-
-#define NUM_INVALIDATE_TLB_VECTORS	8
 
+#ifdef CONFIG_X86_32
+/* 0xf8 - 0xf9 : free */
+#else
+# define THRESHOLD_APIC_VECTOR		0xf9
+# define UV_BAU_MESSAGE			0xf8
 #endif
 
+/* f0-f7 used for spreading out TLB flushes: */
+#define INVALIDATE_TLB_VECTOR_END	0xf7
+#define INVALIDATE_TLB_VECTOR_START	0xf0
+#define NUM_INVALIDATE_TLB_VECTORS	   8
+
 /*
  * Local APIC timer IRQ vector is on a different priority level,
  * to work around the 'lost local interrupt if more than 2 IRQ
  * sources per level' errata.
  */
-#define LOCAL_TIMER_VECTOR	0xef
+#define LOCAL_TIMER_VECTOR		0xef
+
+/*
+ * Performance monitoring interrupt vector:
+ */
+#define LOCAL_PERF_VECTOR		0xee
+
+/*
+ * Generic system vector for platform specific use
+ */
+#define GENERIC_INTERRUPT_VECTOR	0xed
 
 /*
  * First APIC vector available to drivers: (vectors 0x30-0xee) we
  * start at 0x31(0x41) to spread out vectors evenly between priority
  * levels. (0x80 is the syscall vector)
  */
-#define FIRST_DEVICE_VECTOR	(IRQ15_VECTOR + 2)
-
-#define NR_VECTORS		256
-
-#define FPU_IRQ			13
+#define FIRST_DEVICE_VECTOR		(IRQ15_VECTOR + 2)
 
-#define	FIRST_VM86_IRQ		3
-#define LAST_VM86_IRQ		15
-#define invalid_vm86_irq(irq)	((irq) < 3 || (irq) > 15)
+#define NR_VECTORS			 256
 
-#define NR_IRQS_LEGACY		16
+#define FPU_IRQ				  13
 
-#if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER)
+#define	FIRST_VM86_IRQ			   3
+#define LAST_VM86_IRQ			  15
 
-#ifndef CONFIG_SPARSE_IRQ
-# if NR_CPUS < MAX_IO_APICS
-#  define NR_IRQS (NR_VECTORS + (32 * NR_CPUS))
-# else
-#  define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
-# endif
-#else
-# if (8 * NR_CPUS) > (32 * MAX_IO_APICS)
-#  define NR_IRQS (NR_VECTORS + (8 * NR_CPUS))
-# else
-#  define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
-# endif
+#ifndef __ASSEMBLY__
+static inline int invalid_vm86_irq(int irq)
+{
+	return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ;
+}
 #endif
 
-#elif defined(CONFIG_X86_VOYAGER)
-
-# define NR_IRQS		224
+/*
+ * Size the maximum number of interrupts.
+ *
+ * If the irq_desc[] array has a sparse layout, we can size things
+ * generously - it scales up linearly with the maximum number of CPUs,
+ * and the maximum number of IO-APICs, whichever is higher.
+ *
+ * In other cases we size more conservatively, to not create too large
+ * static arrays.
+ */
 
-#else /* IO_APIC || VOYAGER */
+#define NR_IRQS_LEGACY			  16
 
-# define NR_IRQS		16
+#define CPU_VECTOR_LIMIT		(  8 * NR_CPUS      )
+#define IO_APIC_VECTOR_LIMIT		( 32 * MAX_IO_APICS )
 
+#ifdef CONFIG_X86_IO_APIC
+# ifdef CONFIG_SPARSE_IRQ
+#  define NR_IRQS					\
+	(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ?	\
+		(NR_VECTORS + CPU_VECTOR_LIMIT)  :	\
+		(NR_VECTORS + IO_APIC_VECTOR_LIMIT))
+# else
+#  if NR_CPUS < MAX_IO_APICS
+#   define NR_IRQS 			(NR_VECTORS + 4*CPU_VECTOR_LIMIT)
+#  else
+#   define NR_IRQS			(NR_VECTORS + IO_APIC_VECTOR_LIMIT)
+#  endif
+# endif
+#else /* !CONFIG_X86_IO_APIC: */
+# define NR_IRQS			NR_IRQS_LEGACY
 #endif
 
-/* Voyager specific defines */
-/* These define the CPIs we use in linux */
-#define VIC_CPI_LEVEL0			0
-#define VIC_CPI_LEVEL1			1
-/* now the fake CPIs */
-#define VIC_TIMER_CPI			2
-#define VIC_INVALIDATE_CPI		3
-#define VIC_RESCHEDULE_CPI		4
-#define VIC_ENABLE_IRQ_CPI		5
-#define VIC_CALL_FUNCTION_CPI		6
-#define VIC_CALL_FUNCTION_SINGLE_CPI	7
-
-/* Now the QIC CPIs:  Since we don't need the two initial levels,
- * these are 2 less than the VIC CPIs */
-#define QIC_CPI_OFFSET			1
-#define QIC_TIMER_CPI			(VIC_TIMER_CPI - QIC_CPI_OFFSET)
-#define QIC_INVALIDATE_CPI		(VIC_INVALIDATE_CPI - QIC_CPI_OFFSET)
-#define QIC_RESCHEDULE_CPI		(VIC_RESCHEDULE_CPI - QIC_CPI_OFFSET)
-#define QIC_ENABLE_IRQ_CPI		(VIC_ENABLE_IRQ_CPI - QIC_CPI_OFFSET)
-#define QIC_CALL_FUNCTION_CPI		(VIC_CALL_FUNCTION_CPI - QIC_CPI_OFFSET)
-#define QIC_CALL_FUNCTION_SINGLE_CPI	(VIC_CALL_FUNCTION_SINGLE_CPI - QIC_CPI_OFFSET)
-
-#define VIC_START_FAKE_CPI		VIC_TIMER_CPI
-#define VIC_END_FAKE_CPI		VIC_CALL_FUNCTION_SINGLE_CPI
-
-/* this is the SYS_INT CPI. */
-#define VIC_SYS_INT			8
-#define VIC_CMN_INT			15
-
-/* This is the boot CPI for alternate processors.  It gets overwritten
- * by the above once the system has activated all available processors */
-#define VIC_CPU_BOOT_CPI		VIC_CPI_LEVEL0
-#define VIC_CPU_BOOT_ERRATA_CPI		(VIC_CPI_LEVEL0 + 8)
-
-
 #endif /* _ASM_X86_IRQ_VECTORS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/kexec.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/kexec.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/kexec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/kexec.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,27 +10,12 @@
 #else
 # define PA_CONTROL_PAGE	0
 # define VA_CONTROL_PAGE	1
-# define PA_PGD			2
-# define VA_PGD			3
-# define PA_PUD_0		4
-# define VA_PUD_0		5
-# define PA_PMD_0		6
-# define VA_PMD_0		7
-# define PA_PTE_0		8
-# define VA_PTE_0		9
-# define PA_PUD_1		10
-# define VA_PUD_1		11
-# define PA_PMD_1		12
-# define VA_PMD_1		13
-# define PA_PTE_1		14
-# define VA_PTE_1		15
-# define PA_TABLE_PAGE		16
-# define PAGES_NR		17
+# define PA_TABLE_PAGE		2
+# define PA_SWAP_PAGE		3
+# define PAGES_NR		4
 #endif
 
-#ifdef CONFIG_X86_32
 # define KEXEC_CONTROL_CODE_MAX_SIZE	2048
-#endif
 
 #ifndef __ASSEMBLY__
 
@@ -151,15 +136,16 @@ relocate_kernel(unsigned long indirectio
 		unsigned int has_pae,
 		unsigned int preserve_context);
 #else
-NORET_TYPE void
+unsigned long
 relocate_kernel(unsigned long indirection_page,
 		unsigned long page_list,
-		unsigned long start_address) ATTRIB_NORET;
+		unsigned long start_address,
+		unsigned int preserve_context);
 #endif
 
-#ifdef CONFIG_X86_32
 #define ARCH_HAS_KIMAGE_ARCH
 
+#ifdef CONFIG_X86_32
 struct kimage_arch {
 	pgd_t *pgd;
 #ifdef CONFIG_X86_PAE
@@ -169,6 +155,12 @@ struct kimage_arch {
 	pte_t *pte0;
 	pte_t *pte1;
 };
+#else
+struct kimage_arch {
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+};
 #endif
 
 #endif /* __ASSEMBLY__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/kvm.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/kvm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #define __KVM_HAVE_DEVICE_ASSIGNMENT
 #define __KVM_HAVE_MSI
 #define __KVM_HAVE_USER_NMI
+#define __KVM_HAVE_GUEST_DEBUG
 
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
@@ -212,7 +213,30 @@ struct kvm_pit_channel_state {
 	__s64 count_load_time;
 };
 
+struct kvm_debug_exit_arch {
+	__u32 exception;
+	__u32 pad;
+	__u64 pc;
+	__u64 dr6;
+	__u64 dr7;
+};
+
+#define KVM_GUESTDBG_USE_SW_BP		0x00010000
+#define KVM_GUESTDBG_USE_HW_BP		0x00020000
+#define KVM_GUESTDBG_INJECT_DB		0x00040000
+#define KVM_GUESTDBG_INJECT_BP		0x00080000
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+	__u64 debugreg[8];
+};
+
 struct kvm_pit_state {
 	struct kvm_pit_channel_state channels[3];
 };
+
+struct kvm_reinject_control {
+	__u8 pit_reinject;
+	__u8 reserved[31];
+};
 #endif /* _ASM_X86_KVM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/kvm_host.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_host.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/kvm_host.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <asm/pvclock-abi.h>
 #include <asm/desc.h>
 #include <asm/mtrr.h>
+#include <asm/msr-index.h>
 
 #define KVM_MAX_VCPUS 16
 #define KVM_MEMORY_SLOTS 32
@@ -134,11 +135,18 @@ enum {
 
 #define KVM_NR_MEM_OBJS 40
 
-struct kvm_guest_debug {
-	int enabled;
-	unsigned long bp[4];
-	int singlestep;
-};
+#define KVM_NR_DB_REGS	4
+
+#define DR6_BD		(1 << 13)
+#define DR6_BS		(1 << 14)
+#define DR6_FIXED_1	0xffff0ff0
+#define DR6_VOLATILE	0x0000e00f
+
+#define DR7_BP_EN_MASK	0x000000ff
+#define DR7_GE		(1 << 9)
+#define DR7_GD		(1 << 13)
+#define DR7_FIXED_1	0x00000400
+#define DR7_VOLATILE	0xffff23ff
 
 /*
  * We don't want allocation failures within the mmu code, so we preallocate
@@ -162,7 +170,8 @@ struct kvm_pte_chain {
  *   bits 0:3 - total guest paging levels (2-4, or zero for real mode)
  *   bits 4:7 - page table level for this shadow (1-4)
  *   bits 8:9 - page table quadrant for 2-level guests
- *   bit   16 - "metaphysical" - gfn is not a real page (huge page/real mode)
+ *   bit   16 - direct mapping of virtual to physical mapping at gfn
+ *              used for real mode and two-dimensional paging
  *   bits 17:19 - common access permissions for all ptes in this shadow page
  */
 union kvm_mmu_page_role {
@@ -172,9 +181,10 @@ union kvm_mmu_page_role {
 		unsigned level:4;
 		unsigned quadrant:2;
 		unsigned pad_for_nice_hex_output:6;
-		unsigned metaphysical:1;
+		unsigned direct:1;
 		unsigned access:3;
 		unsigned invalid:1;
+		unsigned cr4_pge:1;
 	};
 };
 
@@ -218,6 +228,18 @@ struct kvm_pv_mmu_op_buffer {
 	char buf[512] __aligned(sizeof(long));
 };
 
+struct kvm_pio_request {
+	unsigned long count;
+	int cur_count;
+	gva_t guest_gva;
+	int in;
+	int port;
+	int size;
+	int string;
+	int down;
+	int rep;
+};
+
 /*
  * x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level
  * 32-bit).  The kvm_mmu structure abstracts the details of the current mmu
@@ -236,6 +258,7 @@ struct kvm_mmu {
 	hpa_t root_hpa;
 	int root_level;
 	int shadow_root_level;
+	union kvm_mmu_page_role base_role;
 
 	u64 *pae_root;
 };
@@ -258,6 +281,7 @@ struct kvm_vcpu_arch {
 	unsigned long cr3;
 	unsigned long cr4;
 	unsigned long cr8;
+	u32 hflags;
 	u64 pdptrs[4]; /* pae */
 	u64 shadow_efer;
 	u64 apic_base;
@@ -338,6 +362,15 @@ struct kvm_vcpu_arch {
 
 	struct mtrr_state_type mtrr_state;
 	u32 pat;
+
+	int switch_db_regs;
+	unsigned long host_db[KVM_NR_DB_REGS];
+	unsigned long host_dr6;
+	unsigned long host_dr7;
+	unsigned long db[KVM_NR_DB_REGS];
+	unsigned long dr6;
+	unsigned long dr7;
+	unsigned long eff_db[KVM_NR_DB_REGS];
 };
 
 struct kvm_mem_alias {
@@ -378,6 +411,7 @@ struct kvm_arch{
 
 	unsigned long irq_sources_bitmap;
 	unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
+	u64 vm_init_tsc;
 };
 
 struct kvm_vm_stat {
@@ -446,8 +480,7 @@ struct kvm_x86_ops {
 	void (*vcpu_put)(struct kvm_vcpu *vcpu);
 
 	int (*set_guest_debug)(struct kvm_vcpu *vcpu,
-			       struct kvm_debug_guest *dbg);
-	void (*guest_debug_pre)(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);
@@ -583,16 +616,12 @@ void kvm_queue_exception_e(struct kvm_vc
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
 			   u32 error_code);
 
-void kvm_pic_set_irq(void *opaque, int irq, int level);
+int kvm_pic_set_irq(void *opaque, int irq, int level);
 
 void kvm_inject_nmi(struct kvm_vcpu *vcpu);
 
 void fx_init(struct kvm_vcpu *vcpu);
 
-int emulator_read_std(unsigned long addr,
-		      void *val,
-		      unsigned int bytes,
-		      struct kvm_vcpu *vcpu);
 int emulator_write_emulated(unsigned long addr,
 			    const void *val,
 			    unsigned int bytes,
@@ -737,6 +766,10 @@ enum {
 	TASK_SWITCH_GATE = 3,
 };
 
+#define HF_GIF_MASK		(1 << 0)
+#define HF_HIF_MASK		(1 << 1)
+#define HF_VINTR_MASK		(1 << 2)
+
 /*
  * Hardware virtualization extension instructions may fault if a
  * reboot turns off virtualization while processes are running.
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/lguest_hcall.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/lguest_hcall.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/lguest_hcall.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/lguest_hcall.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
 #define LHCALL_FLUSH_ASYNC	0
 #define LHCALL_LGUEST_INIT	1
 #define LHCALL_SHUTDOWN		2
-#define LHCALL_LOAD_GDT		3
 #define LHCALL_NEW_PGTABLE	4
 #define LHCALL_FLUSH_TLB	5
 #define LHCALL_LOAD_IDT_ENTRY	6
@@ -17,6 +16,7 @@
 #define LHCALL_SET_PMD		15
 #define LHCALL_LOAD_TLS		16
 #define LHCALL_NOTIFY		17
+#define LHCALL_LOAD_GDT_ENTRY	18
 
 #define LGUEST_TRAP_ENTRY 0x1F
 
@@ -26,36 +26,20 @@
 
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
+#include <asm/kvm_para.h>
 
 /*G:031 But first, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
- * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts).  Fifteen hypercalls are
+ * We use the KVM hypercall mechanism. Eighteen hypercalls are
  * available: the hypercall number is put in the %eax register, and the
- * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
+ * arguments (when required) are placed in %ebx, %ecx and %edx.  If a return
  * value makes sense, it's returned in %eax.
  *
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally". */
-static inline unsigned long
-hcall(unsigned long call,
-      unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-	/* "int" is the Intel instruction to trigger a trap. */
-	asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
-		     /* The call in %eax (aka "a") might be overwritten */
-		     : "=a"(call)
-		       /* The arguments are in %eax, %edx, %ebx & %ecx */
-		     : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
-		       /* "memory" means this might write somewhere in memory.
-			* This isn't true for all calls, but it's safe to tell
-			* gcc that it might happen so it doesn't get clever. */
-		     : "memory");
-	return call;
-}
 /*:*/
 
 /* Can't use our min() macro here: needs to be a constant */
@@ -64,7 +48,7 @@ hcall(unsigned long call,
 #define LHCALL_RING_SIZE 64
 struct hcall_args {
 	/* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */
-	unsigned long arg0, arg2, arg3, arg1;
+	unsigned long arg0, arg1, arg2, arg3;
 };
 
 #endif /* !__ASSEMBLY__ */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/linkage.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/linkage.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/linkage.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/linkage.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,11 @@
 #ifndef _ASM_X86_LINKAGE_H
 #define _ASM_X86_LINKAGE_H
 
+#include <linux/stringify.h>
+
 #undef notrace
 #define notrace __attribute__((no_instrument_function))
 
-#ifdef CONFIG_X86_64
-#define __ALIGN .p2align 4,,15
-#define __ALIGN_STR ".p2align 4,,15"
-#endif
-
 #ifdef CONFIG_X86_32
 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
 /*
@@ -50,72 +47,20 @@
 	__asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \
 			      "g" (arg4), "g" (arg5), "g" (arg6))
 
-#endif
-
-#ifdef CONFIG_X86_ALIGNMENT_16
-#define __ALIGN .align 16,0x90
-#define __ALIGN_STR ".align 16,0x90"
-#endif
-
-/*
- * to check ENTRY_X86/END_X86 and
- * KPROBE_ENTRY_X86/KPROBE_END_X86
- * unbalanced-missed-mixed appearance
- */
-#define __set_entry_x86		.set ENTRY_X86_IN, 0
-#define __unset_entry_x86	.set ENTRY_X86_IN, 1
-#define __set_kprobe_x86	.set KPROBE_X86_IN, 0
-#define __unset_kprobe_x86	.set KPROBE_X86_IN, 1
-
-#define __macro_err_x86 .error "ENTRY_X86/KPROBE_X86 unbalanced,missed,mixed"
-
-#define __check_entry_x86	\
-	.ifdef ENTRY_X86_IN;	\
-	.ifeq ENTRY_X86_IN;	\
-	__macro_err_x86;	\
-	.abort;			\
-	.endif;			\
-	.endif
-
-#define __check_kprobe_x86	\
-	.ifdef KPROBE_X86_IN;	\
-	.ifeq KPROBE_X86_IN;	\
-	__macro_err_x86;	\
-	.abort;			\
-	.endif;			\
-	.endif
-
-#define __check_entry_kprobe_x86	\
-	__check_entry_x86;		\
-	__check_kprobe_x86
+#endif /* CONFIG_X86_32 */
 
-#define ENTRY_KPROBE_FINAL_X86 __check_entry_kprobe_x86
+#ifdef __ASSEMBLY__
 
-#define ENTRY_X86(name)			\
-	__check_entry_kprobe_x86;	\
-	__set_entry_x86;		\
-	.globl name;			\
-	__ALIGN;			\
+#define GLOBAL(name)	\
+	.globl name;	\
 	name:
 
-#define END_X86(name)			\
-	__unset_entry_x86;		\
-	__check_entry_kprobe_x86;	\
-	.size name, .-name
-
-#define KPROBE_ENTRY_X86(name)		\
-	__check_entry_kprobe_x86;	\
-	__set_kprobe_x86;		\
-	.pushsection .kprobes.text, "ax"; \
-	.globl name;			\
-	__ALIGN;			\
-	name:
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_ALIGNMENT_16)
+#define __ALIGN		.p2align 4, 0x90
+#define __ALIGN_STR	__stringify(__ALIGN)
+#endif
 
-#define KPROBE_END_X86(name)		\
-	__unset_kprobe_x86;		\
-	__check_entry_kprobe_x86;	\
-	.size name, .-name;		\
-	.popsection
+#endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_LINKAGE_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/apm.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/apm.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/apm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/apm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*
- *  Machine specific APM BIOS functions for generic.
- *  Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-
-#ifndef _ASM_X86_MACH_DEFAULT_APM_H
-#define _ASM_X86_MACH_DEFAULT_APM_H
-
-#ifdef APM_ZERO_SEGS
-#	define APM_DO_ZERO_SEGS \
-		"pushl %%ds\n\t" \
-		"pushl %%es\n\t" \
-		"xorl %%edx, %%edx\n\t" \
-		"mov %%dx, %%ds\n\t" \
-		"mov %%dx, %%es\n\t" \
-		"mov %%dx, %%fs\n\t" \
-		"mov %%dx, %%gs\n\t"
-#	define APM_DO_POP_SEGS \
-		"popl %%es\n\t" \
-		"popl %%ds\n\t"
-#else
-#	define APM_DO_ZERO_SEGS
-#	define APM_DO_POP_SEGS
-#endif
-
-static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
-					u32 *eax, u32 *ebx, u32 *ecx,
-					u32 *edx, u32 *esi)
-{
-	/*
-	 * N.B. We do NOT need a cld after the BIOS call
-	 * because we always save and restore the flags.
-	 */
-	__asm__ __volatile__(APM_DO_ZERO_SEGS
-		"pushl %%edi\n\t"
-		"pushl %%ebp\n\t"
-		"lcall *%%cs:apm_bios_entry\n\t"
-		"setc %%al\n\t"
-		"popl %%ebp\n\t"
-		"popl %%edi\n\t"
-		APM_DO_POP_SEGS
-		: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
-		  "=S" (*esi)
-		: "a" (func), "b" (ebx_in), "c" (ecx_in)
-		: "memory", "cc");
-}
-
-static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
-						u32 ecx_in, u32 *eax)
-{
-	int	cx, dx, si;
-	u8	error;
-
-	/*
-	 * N.B. We do NOT need a cld after the BIOS call
-	 * because we always save and restore the flags.
-	 */
-	__asm__ __volatile__(APM_DO_ZERO_SEGS
-		"pushl %%edi\n\t"
-		"pushl %%ebp\n\t"
-		"lcall *%%cs:apm_bios_entry\n\t"
-		"setc %%bl\n\t"
-		"popl %%ebp\n\t"
-		"popl %%edi\n\t"
-		APM_DO_POP_SEGS
-		: "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
-		  "=S" (si)
-		: "a" (func), "b" (ebx_in), "c" (ecx_in)
-		: "memory", "cc");
-	return error;
-}
-
-#endif /* _ASM_X86_MACH_DEFAULT_APM_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/do_timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/do_timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/do_timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/do_timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/* defines for inline arch setup functions */
-#include <linux/clockchips.h>
-
-#include <asm/i8259.h>
-#include <asm/i8253.h>
-
-/**
- * do_timer_interrupt_hook - hook into timer tick
- *
- * Call the pit clock event handler. see asm/i8253.h
- **/
-
-static inline void do_timer_interrupt_hook(void)
-{
-	global_clock_event->event_handler(global_clock_event);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/entry_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/entry_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/entry_arch.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/entry_arch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/*
- * This file is designed to contain the BUILD_INTERRUPT specifications for
- * all of the extra named interrupt vectors used by the architecture.
- * Usually this is the Inter Process Interrupts (IPIs)
- */
-
-/*
- * The following vectors are part of the Linux architecture, there
- * is no hardware IRQ pin equivalent for them, they are triggered
- * through the ICC by us (IPIs)
- */
-#ifdef CONFIG_X86_SMP
-BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
-BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
-BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
-BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
-BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
-#endif
-
-/*
- * every pentium local APIC has two 'local interrupts', with a
- * soft-definable vector attached to both interrupts, one of
- * which is a timer interrupt, the other one is error counter
- * overflow. Linux uses the local APIC timer interrupt to get
- * a much simpler SMP time architecture:
- */
-#ifdef CONFIG_X86_LOCAL_APIC
-BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
-BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
-BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
-
-#ifdef CONFIG_X86_MCE_P4THERMAL
-BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
-#endif
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H
-#define _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H
-
-#include <asm/apic.h>
-
-#ifdef CONFIG_X86_64
-#define	APIC_ID_MASK		(genapic->apic_id_mask)
-#define GET_APIC_ID(x)		(genapic->get_apic_id(x))
-#define	SET_APIC_ID(x)		(genapic->set_apic_id(x))
-#else
-#define		APIC_ID_MASK		(0xF<<24)
-static inline unsigned get_apic_id(unsigned long x) 
-{
-	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
-	if (APIC_XAPIC(ver))
-		return (((x)>>24)&0xFF);
-	else
-		return (((x)>>24)&0xF);
-} 
-
-#define		GET_APIC_ID(x)	get_apic_id(x)
-#endif
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_APICDEF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,168 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_APIC_H
-#define _ASM_X86_MACH_DEFAULT_MACH_APIC_H
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-#include <mach_apicdef.h>
-#include <asm/smp.h>
-
-#define APIC_DFR_VALUE	(APIC_DFR_FLAT)
-
-static inline const struct cpumask *target_cpus(void)
-{ 
-#ifdef CONFIG_SMP
-	return cpu_online_mask;
-#else
-	return cpumask_of(0);
-#endif
-} 
-
-#define NO_BALANCE_IRQ (0)
-#define esr_disable (0)
-
-#ifdef CONFIG_X86_64
-#include <asm/genapic.h>
-#define INT_DELIVERY_MODE (genapic->int_delivery_mode)
-#define INT_DEST_MODE (genapic->int_dest_mode)
-#define TARGET_CPUS	  (genapic->target_cpus())
-#define apic_id_registered (genapic->apic_id_registered)
-#define init_apic_ldr (genapic->init_apic_ldr)
-#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
-#define cpu_mask_to_apicid_and (genapic->cpu_mask_to_apicid_and)
-#define phys_pkg_id	(genapic->phys_pkg_id)
-#define vector_allocation_domain    (genapic->vector_allocation_domain)
-#define read_apic_id()  (GET_APIC_ID(apic_read(APIC_ID)))
-#define send_IPI_self (genapic->send_IPI_self)
-#define wakeup_secondary_cpu (genapic->wakeup_cpu)
-extern void setup_apic_routing(void);
-#else
-#define INT_DELIVERY_MODE dest_LowestPrio
-#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
-#define TARGET_CPUS (target_cpus())
-#define wakeup_secondary_cpu wakeup_secondary_cpu_via_init
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static inline void init_apic_ldr(void)
-{
-	unsigned long val;
-
-	apic_write(APIC_DFR, APIC_DFR_VALUE);
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
-	apic_write(APIC_LDR, val);
-}
-
-static inline int apic_id_registered(void)
-{
-	return physid_isset(read_apic_id(), phys_cpu_present_map);
-}
-
-static inline unsigned int cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	return cpumask_bits(cpumask)[0];
-}
-
-static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						  const struct cpumask *andmask)
-{
-	unsigned long mask1 = cpumask_bits(cpumask)[0];
-	unsigned long mask2 = cpumask_bits(andmask)[0];
-	unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
-
-	return (unsigned int)(mask1 & mask2 & mask3);
-}
-
-static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
-	return cpuid_apic >> index_msb;
-}
-
-static inline void setup_apic_routing(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
-					"Flat", nr_ioapics);
-#endif
-}
-
-static inline int apicid_to_node(int logical_apicid)
-{
-#ifdef CONFIG_SMP
-	return apicid_2_node[hard_smp_processor_id()];
-#else
-	return 0;
-#endif
-}
-
-static inline void vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-        /* Careful. Some cpus do not strictly honor the set of cpus
-         * specified in the interrupt destination when using lowest
-         * priority interrupt delivery mode.
-         *
-         * In particular there was a hyperthreading cpu observed to
-         * deliver interrupts to the wrong hyperthread when only one
-         * hyperthread was specified in the interrupt desitination.
-         */
-	*retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
-}
-#endif
-
-static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-	return physid_isset(apicid, bitmap);
-}
-
-static inline unsigned long check_apicid_present(int bit)
-{
-	return physid_isset(bit, phys_cpu_present_map);
-}
-
-static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
-{
-	return phys_map;
-}
-
-static inline int multi_timer_check(int apic, int irq)
-{
-	return 0;
-}
-
-/* Mapping from cpu number to logical apicid */
-static inline int cpu_to_logical_apicid(int cpu)
-{
-	return 1 << cpu;
-}
-
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-	if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
-		return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
-	else
-		return BAD_APICID;
-}
-
-static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
-{
-	return physid_mask_of_physid(phys_apicid);
-}
-
-static inline void setup_portio_remap(void)
-{
-}
-
-static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-	return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
-}
-
-static inline void enable_apic_mode(void)
-{
-}
-#endif /* CONFIG_X86_LOCAL_APIC */
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_IPI_H
-#define _ASM_X86_MACH_DEFAULT_MACH_IPI_H
-
-/* Avoid include hell */
-#define NMI_VECTOR 0x02
-
-void send_IPI_mask_bitmask(const struct cpumask *mask, int vector);
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector);
-void __send_IPI_shortcut(unsigned int shortcut, int vector);
-
-extern int no_broadcast;
-
-#ifdef CONFIG_X86_64
-#include <asm/genapic.h>
-#define send_IPI_mask (genapic->send_IPI_mask)
-#define send_IPI_mask_allbutself (genapic->send_IPI_mask_allbutself)
-#else
-static inline void send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	send_IPI_mask_bitmask(mask, vector);
-}
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector);
-#endif
-
-static inline void __local_send_IPI_allbutself(int vector)
-{
-	if (no_broadcast || vector == NMI_VECTOR)
-		send_IPI_mask_allbutself(cpu_online_mask, vector);
-	else
-		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
-}
-
-static inline void __local_send_IPI_all(int vector)
-{
-	if (no_broadcast || vector == NMI_VECTOR)
-		send_IPI_mask(cpu_online_mask, vector);
-	else
-		__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
-}
-
-#ifdef CONFIG_X86_64
-#define send_IPI_allbutself (genapic->send_IPI_allbutself)
-#define send_IPI_all (genapic->send_IPI_all)
-#else
-static inline void send_IPI_allbutself(int vector)
-{
-	/*
-	 * if there are no other CPUs in the system then we get an APIC send 
-	 * error if we try to broadcast, thus avoid sending IPIs in this case.
-	 */
-	if (!(num_online_cpus() > 1))
-		return;
-
-	__local_send_IPI_allbutself(vector);
-	return;
-}
-
-static inline void send_IPI_all(int vector)
-{
-	__local_send_IPI_all(vector);
-}
-#endif
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_mpparse.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_mpparse.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_mpparse.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_mpparse.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H
-#define _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H
-
-static inline int
-mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-	return 0;
-}
-
-/* Hook from generic ACPI tables.c */
-static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	return 0;
-}
-
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_MPPARSE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_mpspec.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_mpspec.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_mpspec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_mpspec.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H
-#define _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H
-
-#define MAX_IRQ_SOURCES 256
-
-#if CONFIG_BASE_SMALL == 0
-#define MAX_MP_BUSSES 256
-#else
-#define MAX_MP_BUSSES 32
-#endif
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_MPSPEC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/*
- *  Machine specific calibrate_tsc() for generic.
- *  Split out from timer_tsc.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-/* ------ Calibrate the TSC ------- 
- * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
- * Too much 64-bit arithmetic here to do this cleanly in C, and for
- * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
- * output busy loop as low as possible. We avoid reading the CTC registers
- * directly because of the awkward 8-bit access mechanism of the 82C54
- * device.
- */
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
-#define _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
-
-#define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
-#define CALIBRATE_LATCH	\
-	((CLOCK_TICK_RATE * CALIBRATE_TIME_MSEC + 1000/2)/1000)
-
-static inline void mach_prepare_counter(void)
-{
-       /* Set the Gate high, disable speaker */
-	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-
-	/*
-	 * Now let's take care of CTC channel 2
-	 *
-	 * Set the Gate high, program CTC channel 2 for mode 0,
-	 * (interrupt on terminal count mode), binary count,
-	 * load 5 * LATCH count, (LSB and MSB) to begin countdown.
-	 *
-	 * Some devices need a delay here.
-	 */
-	outb(0xb0, 0x43);			/* binary, mode 0, LSB/MSB, Ch 2 */
-	outb_p(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
-	outb_p(CALIBRATE_LATCH >> 8, 0x42);       /* MSB of count */
-}
-
-static inline void mach_countup(unsigned long *count_p)
-{
-	unsigned long count = 0;
-	do {
-		count++;
-	} while ((inb_p(0x61) & 0x20) == 0);
-	*count_p = count;
-}
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_TIMER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_traps.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_traps.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_traps.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_traps.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- *  Machine specific NMI handling for generic.
- *  Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp>
- */
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
-#define _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
-
-#include <asm/mc146818rtc.h>
-
-static inline unsigned char get_nmi_reason(void)
-{
-	return inb(0x61);
-}
-
-static inline void reassert_nmi(void)
-{
-	int old_reg = -1;
-
-	if (do_i_have_lock_cmos())
-		old_reg = current_lock_cmos_reg();
-	else
-		lock_cmos(0); /* register doesn't matter here */
-	outb(0x8f, 0x70);
-	inb(0x71);		/* dummy */
-	outb(0x0f, 0x70);
-	inb(0x71);		/* dummy */
-	if (old_reg >= 0)
-		outb(old_reg, 0x70);
-	else
-		unlock_cmos();
-}
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_wakecpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_wakecpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/mach_wakecpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/mach_wakecpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-#ifndef _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H
-#define _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H
-
-#define TRAMPOLINE_PHYS_LOW (0x467)
-#define TRAMPOLINE_PHYS_HIGH (0x469)
-
-static inline void wait_for_init_deassert(atomic_t *deassert)
-{
-	while (!atomic_read(deassert))
-		cpu_relax();
-	return;
-}
-
-/* Nothing to do for most platforms, since cleared by the INIT cycle */
-static inline void smp_callin_clear_local_apic(void)
-{
-}
-
-static inline void store_NMI_vector(unsigned short *high, unsigned short *low)
-{
-}
-
-static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
-{
-}
-
-#ifdef CONFIG_SMP
-extern void __inquire_remote_apic(int apicid);
-#else /* CONFIG_SMP */
-static inline void __inquire_remote_apic(int apicid)
-{
-}
-#endif /* CONFIG_SMP */
-
-static inline void inquire_remote_apic(int apicid)
-{
-	if (apic_verbosity >= APIC_DEBUG)
-		__inquire_remote_apic(apicid);
-}
-
-#endif /* _ASM_X86_MACH_DEFAULT_MACH_WAKECPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/pci-functions.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/pci-functions.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/pci-functions.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/pci-functions.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/*
- *	PCI BIOS function numbering for conventional PCI BIOS 
- *	systems
- */
-
-#define PCIBIOS_PCI_FUNCTION_ID 	0xb1XX
-#define PCIBIOS_PCI_BIOS_PRESENT 	0xb101
-#define PCIBIOS_FIND_PCI_DEVICE		0xb102
-#define PCIBIOS_FIND_PCI_CLASS_CODE	0xb103
-#define PCIBIOS_GENERATE_SPECIAL_CYCLE	0xb106
-#define PCIBIOS_READ_CONFIG_BYTE	0xb108
-#define PCIBIOS_READ_CONFIG_WORD	0xb109
-#define PCIBIOS_READ_CONFIG_DWORD	0xb10a
-#define PCIBIOS_WRITE_CONFIG_BYTE	0xb10b
-#define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
-#define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
-#define PCIBIOS_GET_ROUTING_OPTIONS	0xb10e
-#define PCIBIOS_SET_PCI_HW_INT		0xb10f
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/setup_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/setup_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/setup_arch.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/setup_arch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-/* Hook to call BIOS initialisation function */
-
-/* no action for generic */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/smpboot_hooks.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/smpboot_hooks.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-default/smpboot_hooks.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-default/smpboot_hooks.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
- * which needs to alter them. */
-
-static inline void smpboot_clear_io_apic_irqs(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	io_apic_irqs = 0;
-#endif
-}
-
-static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
-{
-	CMOS_WRITE(0xa, 0xf);
-	local_flush_tlb();
-	pr_debug("1.\n");
-	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
-								 start_eip >> 4;
-	pr_debug("2.\n");
-	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
-							 start_eip & 0xf;
-	pr_debug("3.\n");
-}
-
-static inline void smpboot_restore_warm_reset_vector(void)
-{
-	/*
-	 * Install writable page 0 entry to set BIOS data area.
-	 */
-	local_flush_tlb();
-
-	/*
-	 * Paranoid:  Set warm reset code and vector here back
-	 * to default values.
-	 */
-	CMOS_WRITE(0, 0xf);
-
-	*((volatile long *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0;
-}
-
-static inline void __init smpboot_setup_io_apic(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	/*
-	 * Here we can be sure that there is an IO-APIC in the system. Let's
-	 * go and set it up:
-	 */
-	if (!skip_ioapic_setup && nr_ioapics)
-		setup_IO_APIC();
-	else {
-		nr_ioapics = 0;
-		localise_nmi_watchdog();
-	}
-#endif
-}
-
-static inline void smpboot_clear_io_apic(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-	nr_ioapics = 0;
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/gpio.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/gpio.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,15 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_GPIO_H
-#define _ASM_X86_MACH_GENERIC_GPIO_H
-
-int gpio_request(unsigned gpio, const char *label);
-void gpio_free(unsigned gpio);
-int gpio_direction_input(unsigned gpio);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
-void gpio_set_value(unsigned gpio, int value);
-int gpio_to_irq(unsigned gpio);
-int irq_to_gpio(unsigned irq);
-
-#include <asm-generic/gpio.h>           /* cansleep wrappers */
-
-#endif /* _ASM_X86_MACH_GENERIC_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_APICDEF_H
-#define _ASM_X86_MACH_GENERIC_MACH_APICDEF_H
-
-#ifndef APIC_DEFINITION
-#include <asm/genapic.h>
-
-#define GET_APIC_ID (genapic->get_apic_id)
-#define APIC_ID_MASK (genapic->apic_id_mask)
-#endif
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_APICDEF_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_APIC_H
-#define _ASM_X86_MACH_GENERIC_MACH_APIC_H
-
-#include <asm/genapic.h>
-
-#define esr_disable (genapic->ESR_DISABLE)
-#define NO_BALANCE_IRQ (genapic->no_balance_irq)
-#define INT_DELIVERY_MODE (genapic->int_delivery_mode)
-#define INT_DEST_MODE (genapic->int_dest_mode)
-#undef APIC_DEST_LOGICAL
-#define APIC_DEST_LOGICAL (genapic->apic_destination_logical)
-#define TARGET_CPUS	  (genapic->target_cpus())
-#define apic_id_registered (genapic->apic_id_registered)
-#define init_apic_ldr (genapic->init_apic_ldr)
-#define ioapic_phys_id_map (genapic->ioapic_phys_id_map)
-#define setup_apic_routing (genapic->setup_apic_routing)
-#define multi_timer_check (genapic->multi_timer_check)
-#define apicid_to_node (genapic->apicid_to_node)
-#define cpu_to_logical_apicid (genapic->cpu_to_logical_apicid) 
-#define cpu_present_to_apicid (genapic->cpu_present_to_apicid)
-#define apicid_to_cpu_present (genapic->apicid_to_cpu_present)
-#define setup_portio_remap (genapic->setup_portio_remap)
-#define check_apicid_present (genapic->check_apicid_present)
-#define check_phys_apicid_present (genapic->check_phys_apicid_present)
-#define check_apicid_used (genapic->check_apicid_used)
-#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
-#define cpu_mask_to_apicid_and (genapic->cpu_mask_to_apicid_and)
-#define vector_allocation_domain (genapic->vector_allocation_domain)
-#define enable_apic_mode (genapic->enable_apic_mode)
-#define phys_pkg_id (genapic->phys_pkg_id)
-#define wakeup_secondary_cpu (genapic->wakeup_cpu)
-
-extern void generic_bigsmp_probe(void);
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_IPI_H
-#define _ASM_X86_MACH_GENERIC_MACH_IPI_H
-
-#include <asm/genapic.h>
-
-#define send_IPI_mask (genapic->send_IPI_mask)
-#define send_IPI_allbutself (genapic->send_IPI_allbutself)
-#define send_IPI_all (genapic->send_IPI_all)
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_mpparse.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_mpparse.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_mpparse.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_mpparse.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H
-#define _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H
-
-
-extern int mps_oem_check(struct mpc_table *, char *, char *);
-
-extern int acpi_madt_oem_check(char *, char *);
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_MPPARSE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_mpspec.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_mpspec.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_mpspec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_mpspec.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H
-#define _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H
-
-#define MAX_IRQ_SOURCES 256
-
-/* Summit or generic (i.e. installer) kernels need lots of bus entries. */
-/* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
-#define MAX_MP_BUSSES 260
-
-extern void numaq_mps_oem_check(struct mpc_table *, char *, char *);
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_MPSPEC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_wakecpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_wakecpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-generic/mach_wakecpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-generic/mach_wakecpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_MACH_GENERIC_MACH_WAKECPU_H
-#define _ASM_X86_MACH_GENERIC_MACH_WAKECPU_H
-
-#define TRAMPOLINE_PHYS_LOW (genapic->trampoline_phys_low)
-#define TRAMPOLINE_PHYS_HIGH (genapic->trampoline_phys_high)
-#define wait_for_init_deassert (genapic->wait_for_init_deassert)
-#define smp_callin_clear_local_apic (genapic->smp_callin_clear_local_apic)
-#define store_NMI_vector (genapic->store_NMI_vector)
-#define restore_NMI_vector (genapic->restore_NMI_vector)
-#define inquire_remote_apic (genapic->inquire_remote_apic)
-
-#endif /* _ASM_X86_MACH_GENERIC_MACH_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-rdc321x/gpio.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-rdc321x/gpio.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-rdc321x/gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-rdc321x/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-#ifndef _ASM_X86_MACH_RDC321X_GPIO_H
-#define _ASM_X86_MACH_RDC321X_GPIO_H
-
-#include <linux/kernel.h>
-
-extern int rdc_gpio_get_value(unsigned gpio);
-extern void rdc_gpio_set_value(unsigned gpio, int value);
-extern int rdc_gpio_direction_input(unsigned gpio);
-extern int rdc_gpio_direction_output(unsigned gpio, int value);
-extern int rdc_gpio_request(unsigned gpio, const char *label);
-extern void rdc_gpio_free(unsigned gpio);
-extern void __init rdc321x_gpio_setup(void);
-
-/* Wrappers for the arch-neutral GPIO API */
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
-	return rdc_gpio_request(gpio, label);
-}
-
-static inline void gpio_free(unsigned gpio)
-{
-	might_sleep();
-	rdc_gpio_free(gpio);
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
-	return rdc_gpio_direction_input(gpio);
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
-	return rdc_gpio_direction_output(gpio, value);
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
-	return rdc_gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
-	rdc_gpio_set_value(gpio, value);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return gpio;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-	return irq;
-}
-
-/* For cansleep */
-#include <asm-generic/gpio.h>
-
-#endif /* _ASM_X86_MACH_RDC321X_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#define PFX	"rdc321x: "
-
-/* General purpose configuration and data registers */
-#define RDC3210_CFGREG_ADDR     0x0CF8
-#define RDC3210_CFGREG_DATA     0x0CFC
-
-#define RDC321X_GPIO_CTRL_REG1	0x48
-#define RDC321X_GPIO_CTRL_REG2	0x84
-#define RDC321X_GPIO_DATA_REG1	0x4c
-#define RDC321X_GPIO_DATA_REG2	0x88
-
-#define RDC321X_MAX_GPIO	58
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach_timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach_timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach_timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach_timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ *  Machine specific calibrate_tsc() for generic.
+ *  Split out from timer_tsc.c by Osamu Tomita <tomita@cinet.co.jp>
+ */
+/* ------ Calibrate the TSC ------- 
+ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+ * Too much 64-bit arithmetic here to do this cleanly in C, and for
+ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
+ * output busy loop as low as possible. We avoid reading the CTC registers
+ * directly because of the awkward 8-bit access mechanism of the 82C54
+ * device.
+ */
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
+#define _ASM_X86_MACH_DEFAULT_MACH_TIMER_H
+
+#define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
+#define CALIBRATE_LATCH	\
+	((CLOCK_TICK_RATE * CALIBRATE_TIME_MSEC + 1000/2)/1000)
+
+static inline void mach_prepare_counter(void)
+{
+       /* Set the Gate high, disable speaker */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/*
+	 * Now let's take care of CTC channel 2
+	 *
+	 * Set the Gate high, program CTC channel 2 for mode 0,
+	 * (interrupt on terminal count mode), binary count,
+	 * load 5 * LATCH count, (LSB and MSB) to begin countdown.
+	 *
+	 * Some devices need a delay here.
+	 */
+	outb(0xb0, 0x43);			/* binary, mode 0, LSB/MSB, Ch 2 */
+	outb_p(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
+	outb_p(CALIBRATE_LATCH >> 8, 0x42);       /* MSB of count */
+}
+
+static inline void mach_countup(unsigned long *count_p)
+{
+	unsigned long count = 0;
+	do {
+		count++;
+	} while ((inb_p(0x61) & 0x20) == 0);
+	*count_p = count;
+}
+
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_TIMER_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach_traps.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach_traps.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach_traps.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach_traps.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ *  Machine specific NMI handling for generic.
+ *  Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp>
+ */
+#ifndef _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
+#define _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H
+
+#include <asm/mc146818rtc.h>
+
+static inline unsigned char get_nmi_reason(void)
+{
+	return inb(0x61);
+}
+
+static inline void reassert_nmi(void)
+{
+	int old_reg = -1;
+
+	if (do_i_have_lock_cmos())
+		old_reg = current_lock_cmos_reg();
+	else
+		lock_cmos(0); /* register doesn't matter here */
+	outb(0x8f, 0x70);
+	inb(0x71);		/* dummy */
+	outb(0x0f, 0x70);
+	inb(0x71);		/* dummy */
+	if (old_reg >= 0)
+		outb(old_reg, 0x70);
+	else
+		unlock_cmos();
+}
+
+#endif /* _ASM_X86_MACH_DEFAULT_MACH_TRAPS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/do_timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/do_timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/do_timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/do_timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* defines for inline arch setup functions */
-#include <linux/clockchips.h>
-
-#include <asm/voyager.h>
-#include <asm/i8253.h>
-
-/**
- * do_timer_interrupt_hook - hook into timer tick
- *
- * Call the pit clock event handler. see asm/i8253.h
- **/
-static inline void do_timer_interrupt_hook(void)
-{
-	global_clock_event->event_handler(global_clock_event);
-	voyager_timer_interrupt();
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/entry_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/entry_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/entry_arch.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/entry_arch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* Copyright (C) 2002
- *
- * Author: James.Bottomley@HansenPartnership.com
- *
- * linux/arch/i386/voyager/entry_arch.h
- *
- * This file builds the VIC and QIC CPI gates
- */
-
-/* initialise the voyager interrupt gates 
- *
- * This uses the macros in irq.h to set up assembly jump gates.  The
- * calls are then redirected to the same routine with smp_ prefixed */
-BUILD_INTERRUPT(vic_sys_interrupt, VIC_SYS_INT)
-BUILD_INTERRUPT(vic_cmn_interrupt, VIC_CMN_INT)
-BUILD_INTERRUPT(vic_cpi_interrupt, VIC_CPI_LEVEL0);
-
-/* do all the QIC interrupts */
-BUILD_INTERRUPT(qic_timer_interrupt, QIC_TIMER_CPI);
-BUILD_INTERRUPT(qic_invalidate_interrupt, QIC_INVALIDATE_CPI);
-BUILD_INTERRUPT(qic_reschedule_interrupt, QIC_RESCHEDULE_CPI);
-BUILD_INTERRUPT(qic_enable_irq_interrupt, QIC_ENABLE_IRQ_CPI);
-BUILD_INTERRUPT(qic_call_function_interrupt, QIC_CALL_FUNCTION_CPI);
-BUILD_INTERRUPT(qic_call_function_single_interrupt, QIC_CALL_FUNCTION_SINGLE_CPI);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/setup_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/setup_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mach-voyager/setup_arch.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mach-voyager/setup_arch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#include <asm/voyager.h>
-#include <asm/setup.h>
-#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *) \
-			(&boot_params.apm_bios_info))
-
-/* Hook to call BIOS initialisation function */
-
-/* for voyager, pass the voyager BIOS/SUS info area to the detection
- * routines */
-
-#define ARCH_SETUP	voyager_detect(VOYAGER_BIOS_INFO);
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mce.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mce.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mce.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mce.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
  */
 
 #define MCG_CTL_P	 (1UL<<8)   /* MCG_CAP register available */
+#define MCG_EXT_P	 (1ULL<<9)   /* Extended registers available */
+#define MCG_CMCI_P	 (1ULL<<10)  /* CMCI supported */
 
 #define MCG_STATUS_RIPV  (1UL<<0)   /* restart ip valid */
 #define MCG_STATUS_EIPV  (1UL<<1)   /* ip points to correct instruction */
@@ -90,14 +92,29 @@ extern int mce_disabled;
 
 #include <asm/atomic.h>
 
+void mce_setup(struct mce *m);
 void mce_log(struct mce *m);
 DECLARE_PER_CPU(struct sys_device, device_mce);
 extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
+/*
+ * To support more than 128 would need to escape the predefined
+ * Linux defined extended banks first.
+ */
+#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1)
+
 #ifdef CONFIG_X86_MCE_INTEL
 void mce_intel_feature_init(struct cpuinfo_x86 *c);
+void cmci_clear(void);
+void cmci_reenable(void);
+void cmci_rediscover(int dying);
+void cmci_recheck(void);
 #else
 static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { }
+static inline void cmci_clear(void) {}
+static inline void cmci_reenable(void) {}
+static inline void cmci_rediscover(int dying) {}
+static inline void cmci_recheck(void) {}
 #endif
 
 #ifdef CONFIG_X86_MCE_AMD
@@ -106,11 +123,24 @@ void mce_amd_feature_init(struct cpuinfo
 static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { }
 #endif
 
-void mce_log_therm_throt_event(unsigned int cpu, __u64 status);
+extern int mce_available(struct cpuinfo_x86 *c);
+
+void mce_log_therm_throt_event(__u64 status);
 
 extern atomic_t mce_entry;
 
 extern void do_machine_check(struct pt_regs *, long);
+
+typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
+DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
+
+enum mcp_flags {
+	MCP_TIMESTAMP = (1 << 0),	/* log time stamp */
+	MCP_UC = (1 << 1),		/* log uncorrected errors */
+	MCP_DONTLOG = (1 << 2),		/* only clear, don't log */
+};
+extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
+
 extern int mce_notify_user(void);
 
 #endif /* !CONFIG_X86_32 */
@@ -120,8 +150,8 @@ extern void mcheck_init(struct cpuinfo_x
 #else
 #define mcheck_init(c) do { } while (0)
 #endif
-extern void stop_mce(void);
-extern void restart_mce(void);
+
+extern void (*mce_threshold_vector)(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-#ifndef _ASM_X86_MMU_CONTEXT_32_H
-#define _ASM_X86_MMU_CONTEXT_32_H
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-#ifdef CONFIG_SMP
-	if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK)
-		x86_write_percpu(cpu_tlbstate.state, TLBSTATE_LAZY);
-#endif
-}
-
-static inline void switch_mm(struct mm_struct *prev,
-			     struct mm_struct *next,
-			     struct task_struct *tsk)
-{
-	int cpu = smp_processor_id();
-
-	if (likely(prev != next)) {
-		/* stop flush ipis for the previous mm */
-		cpu_clear(cpu, prev->cpu_vm_mask);
-#ifdef CONFIG_SMP
-		x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK);
-		x86_write_percpu(cpu_tlbstate.active_mm, next);
-#endif
-		cpu_set(cpu, next->cpu_vm_mask);
-
-		/* Re-load page tables */
-		load_cr3(next->pgd);
-
-		/*
-		 * load the LDT, if the LDT is different:
-		 */
-		if (unlikely(prev->context.ldt != next->context.ldt))
-			load_LDT_nolock(&next->context);
-	}
-#ifdef CONFIG_SMP
-	else {
-		x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK);
-		BUG_ON(x86_read_percpu(cpu_tlbstate.active_mm) != next);
-
-		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
-			/* We were in lazy tlb mode and leave_mm disabled
-			 * tlb flush IPI delivery. We must reload %cr3.
-			 */
-			load_cr3(next->pgd);
-			load_LDT_nolock(&next->context);
-		}
-	}
-#endif
-}
-
-#define deactivate_mm(tsk, mm)			\
-	asm("movl %0,%%gs": :"r" (0));
-
-#endif /* _ASM_X86_MMU_CONTEXT_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context_64.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-#ifndef _ASM_X86_MMU_CONTEXT_64_H
-#define _ASM_X86_MMU_CONTEXT_64_H
-
-#include <asm/pda.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-#ifdef CONFIG_SMP
-	if (read_pda(mmu_state) == TLBSTATE_OK)
-		write_pda(mmu_state, TLBSTATE_LAZY);
-#endif
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
-			     struct task_struct *tsk)
-{
-	unsigned cpu = smp_processor_id();
-	if (likely(prev != next)) {
-		/* stop flush ipis for the previous mm */
-		cpu_clear(cpu, prev->cpu_vm_mask);
-#ifdef CONFIG_SMP
-		write_pda(mmu_state, TLBSTATE_OK);
-		write_pda(active_mm, next);
-#endif
-		cpu_set(cpu, next->cpu_vm_mask);
-		load_cr3(next->pgd);
-
-		if (unlikely(next->context.ldt != prev->context.ldt))
-			load_LDT_nolock(&next->context);
-	}
-#ifdef CONFIG_SMP
-	else {
-		write_pda(mmu_state, TLBSTATE_OK);
-		if (read_pda(active_mm) != next)
-			BUG();
-		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
-			/* We were in lazy tlb mode and leave_mm disabled
-			 * tlb flush IPI delivery. We must reload CR3
-			 * to make sure to use no freed page tables.
-			 */
-			load_cr3(next->pgd);
-			load_LDT_nolock(&next->context);
-		}
-	}
-#endif
-}
-
-#define deactivate_mm(tsk, mm)			\
-do {						\
-	load_gs_index(0);			\
-	asm volatile("movl %0,%%fs"::"r"(0));	\
-} while (0)
-
-#endif /* _ASM_X86_MMU_CONTEXT_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,11 +21,54 @@ static inline void paravirt_activate_mm(
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 void destroy_context(struct mm_struct *mm);
 
-#ifdef CONFIG_X86_32
-# include "mmu_context_32.h"
-#else
-# include "mmu_context_64.h"
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+#ifdef CONFIG_SMP
+	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+		percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
+#endif
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			     struct task_struct *tsk)
+{
+	unsigned cpu = smp_processor_id();
+
+	if (likely(prev != next)) {
+		/* stop flush ipis for the previous mm */
+		cpu_clear(cpu, prev->cpu_vm_mask);
+#ifdef CONFIG_SMP
+		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+		percpu_write(cpu_tlbstate.active_mm, next);
 #endif
+		cpu_set(cpu, next->cpu_vm_mask);
+
+		/* Re-load page tables */
+		load_cr3(next->pgd);
+
+		/*
+		 * load the LDT, if the LDT is different:
+		 */
+		if (unlikely(prev->context.ldt != next->context.ldt))
+			load_LDT_nolock(&next->context);
+	}
+#ifdef CONFIG_SMP
+	else {
+		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+		BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
+
+		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
+			/* We were in lazy tlb mode and leave_mm disabled
+			 * tlb flush IPI delivery. We must reload CR3
+			 * to make sure to use no freed page tables.
+			 */
+			load_cr3(next->pgd);
+			load_LDT_nolock(&next->context);
+		}
+	}
+#endif
+}
 
 #define activate_mm(prev, next)			\
 do {						\
@@ -33,5 +76,17 @@ do {						\
 	switch_mm((prev), (next), NULL);	\
 } while (0);
 
+#ifdef CONFIG_X86_32
+#define deactivate_mm(tsk, mm)			\
+do {						\
+	lazy_load_gs(0);			\
+} while (0)
+#else
+#define deactivate_mm(tsk, mm)			\
+do {						\
+	load_gs_index(0);			\
+	loadsegment(fs, 0);			\
+} while (0)
+#endif
 
 #endif /* _ASM_X86_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmzone_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmzone_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mmzone_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mmzone_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -91,46 +91,9 @@ static inline int pfn_valid(int pfn)
 #endif /* CONFIG_DISCONTIGMEM */
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-
-/*
- * Following are macros that are specific to this numa platform.
- */
-#define reserve_bootmem(addr, size, flags) \
-	reserve_bootmem_node(NODE_DATA(0), (addr), (size), (flags))
-#define alloc_bootmem(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_nopanic(x) \
-	__alloc_bootmem_node_nopanic(NODE_DATA(0), (x), SMP_CACHE_BYTES, \
-				__pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_low(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0)
-#define alloc_bootmem_pages(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_pages_nopanic(x) \
-	__alloc_bootmem_node_nopanic(NODE_DATA(0), (x), PAGE_SIZE, \
-				__pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_low_pages(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
-#define alloc_bootmem_node(pgdat, x)					\
-({									\
-	struct pglist_data  __maybe_unused			\
-				*__alloc_bootmem_node__pgdat = (pgdat);	\
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES,	\
-						__pa(MAX_DMA_ADDRESS));	\
-})
-#define alloc_bootmem_pages_node(pgdat, x)				\
-({									\
-	struct pglist_data  __maybe_unused			\
-				*__alloc_bootmem_node__pgdat = (pgdat);	\
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE,		\
-						__pa(MAX_DMA_ADDRESS));	\
-})
-#define alloc_bootmem_low_pages_node(pgdat, x)				\
-({									\
-	struct pglist_data  __maybe_unused			\
-				*__alloc_bootmem_node__pgdat = (pgdat);	\
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0);		\
-})
+/* always use node 0 for bootmem on this numa platform */
+#define bootmem_arch_preferred_node(__bdata, size, align, goal, limit)	\
+	(NODE_DATA(0)->bdata)
 #endif /* CONFIG_NEED_MULTIPLE_NODES */
 
 #endif /* _ASM_X86_MMZONE_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mpspec_def.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mpspec_def.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mpspec_def.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mpspec_def.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,17 +24,18 @@
 # endif
 #endif
 
-struct intel_mp_floating {
-	char mpf_signature[4];		/* "_MP_"			*/
-	unsigned int mpf_physptr;	/* Configuration table address	*/
-	unsigned char mpf_length;	/* Our length (paragraphs)	*/
-	unsigned char mpf_specification;/* Specification version	*/
-	unsigned char mpf_checksum;	/* Checksum (makes sum 0)	*/
-	unsigned char mpf_feature1;	/* Standard or configuration ?	*/
-	unsigned char mpf_feature2;	/* Bit7 set for IMCR|PIC	*/
-	unsigned char mpf_feature3;	/* Unused (0)			*/
-	unsigned char mpf_feature4;	/* Unused (0)			*/
-	unsigned char mpf_feature5;	/* Unused (0)			*/
+/* Intel MP Floating Pointer Structure */
+struct mpf_intel {
+	char signature[4];		/* "_MP_"			*/
+	unsigned int physptr;		/* Configuration table address	*/
+	unsigned char length;		/* Our length (paragraphs)	*/
+	unsigned char specification;	/* Specification version	*/
+	unsigned char checksum;		/* Checksum (makes sum 0)	*/
+	unsigned char feature1;		/* Standard or configuration ?	*/
+	unsigned char feature2;		/* Bit7 set for IMCR|PIC	*/
+	unsigned char feature3;		/* Unused (0)			*/
+	unsigned char feature4;		/* Unused (0)			*/
+	unsigned char feature5;		/* Unused (0)			*/
 };
 
 #define MPC_SIGNATURE "PCMP"
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/mpspec.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/mpspec.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/mpspec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/mpspec.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,18 @@ extern int apic_version[MAX_APICS];
 extern int pic_mode;
 
 #ifdef CONFIG_X86_32
-#include <mach_mpspec.h>
+
+/*
+ * Summit or generic (i.e. installer) kernels need lots of bus entries.
+ * Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets.
+ */
+#if CONFIG_BASE_SMALL == 0
+# define MAX_MP_BUSSES		260
+#else
+# define MAX_MP_BUSSES		32
+#endif
+
+#define MAX_IRQ_SOURCES		256
 
 extern unsigned int def_to_bigsmp;
 extern u8 apicid_2_node[];
@@ -20,15 +31,15 @@ extern int mp_bus_id_to_local[MAX_MP_BUS
 extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 #endif
 
-#define MAX_APICID 256
+#define MAX_APICID		256
 
-#else
+#else /* CONFIG_X86_64: */
 
-#define MAX_MP_BUSSES 256
+#define MAX_MP_BUSSES		256
 /* Each PCI slot may be a combo card with its own bus.  4 IRQ pins per slot. */
-#define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4)
+#define MAX_IRQ_SOURCES		(MAX_MP_BUSSES * 4)
 
-#endif
+#endif /* CONFIG_X86_64 */
 
 extern void early_find_smp_config(void);
 extern void early_get_smp_config(void);
@@ -45,11 +56,13 @@ extern int smp_found_config;
 extern int mpc_default_type;
 extern unsigned long mp_lapic_addr;
 
-extern void find_smp_config(void);
 extern void get_smp_config(void);
+
 #ifdef CONFIG_X86_MPPARSE
+extern void find_smp_config(void);
 extern void early_reserve_e820_mpc_new(void);
 #else
+static inline void find_smp_config(void) { }
 static inline void early_reserve_e820_mpc_new(void) { }
 #endif
 
@@ -64,6 +77,8 @@ extern int acpi_probe_gsi(void);
 #ifdef CONFIG_X86_IO_APIC
 extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
 				u32 gsi, int triggering, int polarity);
+extern int mp_find_ioapic(int gsi);
+extern int mp_find_ioapic_pin(int ioapic, int gsi);
 #else
 static inline int
 mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
@@ -148,4 +163,8 @@ static inline void physid_set_mask_of_ph
 
 extern physid_mask_t phys_cpu_present_map;
 
+extern int generic_mps_oem_check(struct mpc_table *, char *, char *);
+
+extern int default_acpi_madt_oem_check(char *, char *);
+
 #endif /* _ASM_X86_MPSPEC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/msidef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/msidef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/msidef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/msidef.h	2009-06-09 23:05:27.000000000 -0400
@@ -47,6 +47,7 @@
 #define	 MSI_ADDR_DEST_ID_MASK		0x00ffff0
 #define  MSI_ADDR_DEST_ID(dest)		(((dest) << MSI_ADDR_DEST_ID_SHIFT) & \
 					 MSI_ADDR_DEST_ID_MASK)
+#define MSI_ADDR_EXT_DEST_ID(dest)	((dest) & 0xffffff00)
 
 #define MSI_ADDR_IR_EXT_INT		(1 << 4)
 #define MSI_ADDR_IR_SHV			(1 << 3)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/msr-index.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/msr-index.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/msr-index.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/msr-index.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,11 +18,15 @@
 #define _EFER_LME		8  /* Long mode enable */
 #define _EFER_LMA		10 /* Long mode active (read-only) */
 #define _EFER_NX		11 /* No execute enable */
+#define _EFER_SVME		12 /* Enable virtualization */
+#define _EFER_FFXSR		14 /* Enable Fast FXSAVE/FXRSTOR */
 
 #define EFER_SCE		(1<<_EFER_SCE)
 #define EFER_LME		(1<<_EFER_LME)
 #define EFER_LMA		(1<<_EFER_LMA)
 #define EFER_NX			(1<<_EFER_NX)
+#define EFER_SVME		(1<<_EFER_SVME)
+#define EFER_FFXSR		(1<<_EFER_FFXSR)
 
 /* Intel MSRs. Some also available on other CPUs */
 #define MSR_IA32_PERFCTR0		0x000000c1
@@ -77,6 +81,11 @@
 #define MSR_IA32_MC0_ADDR		0x00000402
 #define MSR_IA32_MC0_MISC		0x00000403
 
+/* These are consecutive and not in the normal 4er MCE bank block */
+#define MSR_IA32_MC0_CTL2		0x00000280
+#define CMCI_EN			(1ULL << 30)
+#define CMCI_THRESHOLD_MASK		0xffffULL
+
 #define MSR_P6_PERFCTR0			0x000000c1
 #define MSR_P6_PERFCTR1			0x000000c2
 #define MSR_P6_EVNTSEL0			0x00000186
@@ -360,4 +369,9 @@
 #define MSR_IA32_VMX_PROCBASED_CTLS2    0x0000048b
 #define MSR_IA32_VMX_EPT_VPID_CAP       0x0000048c
 
+/* AMD-V MSRs */
+
+#define MSR_VM_CR                       0xc0010114
+#define MSR_VM_HSAVE_PA                 0xc0010117
+
 #endif /* _ASM_X86_MSR_INDEX_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numa_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numa_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numa_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numa_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,8 +4,12 @@
 extern int pxm_to_nid(int pxm);
 extern void numa_remove_cpu(int cpu);
 
-#ifdef CONFIG_NUMA
+#ifdef CONFIG_HIGHMEM
 extern void set_highmem_pages_init(void);
+#else
+static inline void set_highmem_pages_init(void)
+{
+}
 #endif
 
 #endif /* _ASM_X86_NUMA_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef __ASM_NUMAQ_APICDEF_H
-#define __ASM_NUMAQ_APICDEF_H
-
-
-#define APIC_ID_MASK (0xF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
-	        return (((x)>>24)&0x0F);
-}
-
-#define         GET_APIC_ID(x)  get_apic_id(x)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,142 +0,0 @@
-#ifndef __ASM_NUMAQ_APIC_H
-#define __ASM_NUMAQ_APIC_H
-
-#include <asm/io.h>
-#include <linux/mmzone.h>
-#include <linux/nodemask.h>
-
-#define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
-
-static inline const cpumask_t *target_cpus(void)
-{
-	return &CPU_MASK_ALL;
-}
-
-#define NO_BALANCE_IRQ (1)
-#define esr_disable (1)
-
-#define INT_DELIVERY_MODE dest_LowestPrio
-#define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
- 
-static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-	return physid_isset(apicid, bitmap);
-}
-static inline unsigned long check_apicid_present(int bit)
-{
-	return physid_isset(bit, phys_cpu_present_map);
-}
-#define apicid_cluster(apicid) (apicid & 0xF0)
-
-static inline int apic_id_registered(void)
-{
-	return 1;
-}
-
-static inline void init_apic_ldr(void)
-{
-	/* Already done in NUMA-Q firmware */
-}
-
-static inline void setup_apic_routing(void)
-{
-	printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
-		"NUMA-Q", nr_ioapics);
-}
-
-/*
- * Skip adding the timer int on secondary nodes, which causes
- * a small but painful rift in the time-space continuum.
- */
-static inline int multi_timer_check(int apic, int irq)
-{
-	return apic != 0 && irq == 0;
-}
-
-static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
-{
-	/* We don't have a good way to do this yet - hack */
-	return physids_promote(0xFUL);
-}
-
-/* Mapping from cpu number to logical apicid */
-extern u8 cpu_2_logical_apicid[];
-static inline int cpu_to_logical_apicid(int cpu)
-{
-	if (cpu >= nr_cpu_ids)
-		return BAD_APICID;
-	return (int)cpu_2_logical_apicid[cpu];
-}
-
-/*
- * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
- * cpu to APIC ID relation to properly interact with the intelligent
- * mode of the cluster controller.
- */
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-	if (mps_cpu < 60)
-		return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
-	else
-		return BAD_APICID;
-}
-
-static inline int apicid_to_node(int logical_apicid) 
-{
-	return logical_apicid >> 4;
-}
-
-static inline physid_mask_t apicid_to_cpu_present(int logical_apicid)
-{
-	int node = apicid_to_node(logical_apicid);
-	int cpu = __ffs(logical_apicid & 0xf);
-
-	return physid_mask_of_physid(cpu + 4*node);
-}
-
-extern void *xquad_portio;
-
-static inline void setup_portio_remap(void)
-{
-	int num_quads = num_online_nodes();
-
-	if (num_quads <= 1)
-       		return;
-
-	printk("Remapping cross-quad port I/O for %d quads\n", num_quads);
-	xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
-	printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
-		(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
-}
-
-static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-	return (1);
-}
-
-static inline void enable_apic_mode(void)
-{
-}
-
-/*
- * We use physical apicids here, not logical, so just return the default
- * physical broadcast to stop people from breaking us
- */
-static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-	return (int) 0xF;
-}
-
-static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						  const struct cpumask *andmask)
-{
-	return (int) 0xF;
-}
-
-/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
-static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
-	return cpuid_apic >> index_msb;
-}
-
-#endif /* __ASM_NUMAQ_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-#ifndef __ASM_NUMAQ_IPI_H
-#define __ASM_NUMAQ_IPI_H
-
-void send_IPI_mask_sequence(const struct cpumask *mask, int vector);
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector);
-
-static inline void send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	send_IPI_mask_sequence(mask, vector);
-}
-
-static inline void send_IPI_allbutself(int vector)
-{
-	send_IPI_mask_allbutself(cpu_online_mask, vector);
-}
-
-static inline void send_IPI_all(int vector)
-{
-	send_IPI_mask(cpu_online_mask, vector);
-}
-
-#endif /* __ASM_NUMAQ_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/mpparse.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/mpparse.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/mpparse.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/mpparse.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef __ASM_NUMAQ_MPPARSE_H
-#define __ASM_NUMAQ_MPPARSE_H
-
-extern void numaq_mps_oem_check(struct mpc_table *, char *, char *);
-
-#endif /* __ASM_NUMAQ_MPPARSE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/wakecpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/wakecpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq/wakecpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq/wakecpu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-#ifndef __ASM_NUMAQ_WAKECPU_H
-#define __ASM_NUMAQ_WAKECPU_H
-
-/* This file copes with machines that wakeup secondary CPUs by NMIs */
-
-#define TRAMPOLINE_PHYS_LOW (0x8)
-#define TRAMPOLINE_PHYS_HIGH (0xa)
-
-/* We don't do anything here because we use NMI's to boot instead */
-static inline void wait_for_init_deassert(atomic_t *deassert)
-{
-}
-
-/*
- * Because we use NMIs rather than the INIT-STARTUP sequence to
- * bootstrap the CPUs, the APIC may be in a weird state. Kick it.
- */
-static inline void smp_callin_clear_local_apic(void)
-{
-	clear_local_APIC();
-}
-
-static inline void store_NMI_vector(unsigned short *high, unsigned short *low)
-{
-	printk("Storing NMI vector\n");
-	*high =
-	  *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH));
-	*low =
-	  *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW));
-}
-
-static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
-{
-	printk("Restoring NMI vector\n");
-	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
-								 *high;
-	*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
-								 *low;
-}
-
-static inline void inquire_remote_apic(int apicid)
-{
-}
-
-#endif /* __ASM_NUMAQ_WAKECPU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/numaq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/numaq.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,8 @@
 extern int found_numaq;
 extern int get_memcfg_numaq(void);
 
+extern void *xquad_portio;
+
 /*
  * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,82 +1,14 @@
 #ifndef _ASM_X86_PAGE_32_H
 #define _ASM_X86_PAGE_32_H
 
-/*
- * This handles the memory map.
- *
- * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
- * a virtual address space of one gigabyte, which limits the
- * amount of physical memory you can use to about 950MB.
- *
- * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
- * and CONFIG_HIGHMEM64G options in the kernel configuration.
- */
-#define __PAGE_OFFSET		_AC(CONFIG_PAGE_OFFSET, UL)
-
-#ifdef CONFIG_4KSTACKS
-#define THREAD_ORDER	0
-#else
-#define THREAD_ORDER	1
-#endif
-#define THREAD_SIZE 	(PAGE_SIZE << THREAD_ORDER)
-
-#define STACKFAULT_STACK 0
-#define DOUBLEFAULT_STACK 1
-#define NMI_STACK 0
-#define DEBUG_STACK 0
-#define MCE_STACK 0
-#define N_EXCEPTION_STACKS 1
-
-#ifdef CONFIG_X86_PAE
-/* 44=32+12, the limit we can fit into an unsigned long pfn */
-#define __PHYSICAL_MASK_SHIFT	44
-#define __VIRTUAL_MASK_SHIFT	32
-#define PAGETABLE_LEVELS	3
-
-#ifndef __ASSEMBLY__
-typedef u64	pteval_t;
-typedef u64	pmdval_t;
-typedef u64	pudval_t;
-typedef u64	pgdval_t;
-typedef u64	pgprotval_t;
-
-typedef union {
-	struct {
-		unsigned long pte_low, pte_high;
-	};
-	pteval_t pte;
-} pte_t;
-#endif	/* __ASSEMBLY__
- */
-#else  /* !CONFIG_X86_PAE */
-#define __PHYSICAL_MASK_SHIFT	32
-#define __VIRTUAL_MASK_SHIFT	32
-#define PAGETABLE_LEVELS	2
-
-#ifndef __ASSEMBLY__
-typedef unsigned long	pteval_t;
-typedef unsigned long	pmdval_t;
-typedef unsigned long	pudval_t;
-typedef unsigned long	pgdval_t;
-typedef unsigned long	pgprotval_t;
-
-typedef union {
-	pteval_t pte;
-	pteval_t pte_low;
-} pte_t;
-
-#endif	/* __ASSEMBLY__ */
-#endif	/* CONFIG_X86_PAE */
+#include <asm/page_32_types.h>
 
 #ifndef __ASSEMBLY__
-typedef struct page *pgtable_t;
-#endif
 
 #ifdef CONFIG_HUGETLB_PAGE
 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 #endif
 
-#ifndef __ASSEMBLY__
 #define __phys_addr_nodebug(x)	((x) - PAGE_OFFSET)
 #ifdef CONFIG_DEBUG_VIRTUAL
 extern unsigned long __phys_addr(unsigned long);
@@ -89,23 +21,6 @@ extern unsigned long __phys_addr(unsigne
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
 #endif /* CONFIG_FLATMEM */
 
-extern int nx_enabled;
-
-/*
- * This much address space is reserved for vmalloc() and iomap()
- * as well as fixmap mappings.
- */
-extern unsigned int __VMALLOC_RESERVE;
-extern int sysctl_legacy_va_layout;
-
-extern void find_low_pfn_range(void);
-extern unsigned long init_memory_mapping(unsigned long start,
-					 unsigned long end);
-extern void initmem_init(unsigned long, unsigned long);
-extern void free_initmem(void);
-extern void setup_bootmem_allocator(void);
-
-
 #ifdef CONFIG_X86_USE_3DNOW
 #include <asm/mmx.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_32_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_32_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_32_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_32_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+#ifndef _ASM_X86_PAGE_32_DEFS_H
+#define _ASM_X86_PAGE_32_DEFS_H
+
+#include <linux/const.h>
+
+/*
+ * This handles the memory map.
+ *
+ * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
+ * a virtual address space of one gigabyte, which limits the
+ * amount of physical memory you can use to about 950MB.
+ *
+ * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+ * and CONFIG_HIGHMEM64G options in the kernel configuration.
+ */
+#define __PAGE_OFFSET		_AC(CONFIG_PAGE_OFFSET, UL)
+
+#ifdef CONFIG_4KSTACKS
+#define THREAD_ORDER	0
+#else
+#define THREAD_ORDER	1
+#endif
+#define THREAD_SIZE 	(PAGE_SIZE << THREAD_ORDER)
+
+#define STACKFAULT_STACK 0
+#define DOUBLEFAULT_STACK 1
+#define NMI_STACK 0
+#define DEBUG_STACK 0
+#define MCE_STACK 0
+#define N_EXCEPTION_STACKS 1
+
+#ifdef CONFIG_X86_PAE
+/* 44=32+12, the limit we can fit into an unsigned long pfn */
+#define __PHYSICAL_MASK_SHIFT	44
+#define __VIRTUAL_MASK_SHIFT	32
+
+#else  /* !CONFIG_X86_PAE */
+#define __PHYSICAL_MASK_SHIFT	32
+#define __VIRTUAL_MASK_SHIFT	32
+#endif	/* CONFIG_X86_PAE */
+
+/*
+ * Kernel image size is limited to 512 MB (see in arch/x86/kernel/head_32.S)
+ */
+#define KERNEL_IMAGE_SIZE	(512 * 1024 * 1024)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This much address space is reserved for vmalloc() and iomap()
+ * as well as fixmap mappings.
+ */
+extern unsigned int __VMALLOC_RESERVE;
+extern int sysctl_legacy_va_layout;
+
+extern void find_low_pfn_range(void);
+extern unsigned long init_memory_mapping(unsigned long start,
+					 unsigned long end);
+extern void initmem_init(unsigned long, unsigned long);
+extern void free_initmem(void);
+extern void setup_bootmem_allocator(void);
+
+#endif	/* !__ASSEMBLY__ */
+
+#endif /* _ASM_X86_PAGE_32_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,105 +1,6 @@
 #ifndef _ASM_X86_PAGE_64_H
 #define _ASM_X86_PAGE_64_H
 
-#define PAGETABLE_LEVELS	4
-
-#define THREAD_ORDER	1
-#define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
-#define CURRENT_MASK (~(THREAD_SIZE - 1))
-
-#define EXCEPTION_STACK_ORDER 0
-#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
-
-#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
-#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
-
-#define IRQSTACK_ORDER 2
-#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER)
-
-#define STACKFAULT_STACK 1
-#define DOUBLEFAULT_STACK 2
-#define NMI_STACK 3
-#define DEBUG_STACK 4
-#define MCE_STACK 5
-#define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
-
-#define PUD_PAGE_SIZE		(_AC(1, UL) << PUD_SHIFT)
-#define PUD_PAGE_MASK		(~(PUD_PAGE_SIZE-1))
-
-/*
- * Set __PAGE_OFFSET to the most negative possible address +
- * PGDIR_SIZE*16 (pgd slot 272).  The gap is to allow a space for a
- * hypervisor to fit.  Choosing 16 slots here is arbitrary, but it's
- * what Xen requires.
- */
-#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
-
-#define __PHYSICAL_START	CONFIG_PHYSICAL_START
-#define __KERNEL_ALIGN		0x200000
-
-/*
- * Make sure kernel is aligned to 2MB address. Catching it at compile
- * time is better. Change your config file and compile the kernel
- * for a 2MB aligned address (CONFIG_PHYSICAL_START)
- */
-#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
-#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
-#endif
-
-#define __START_KERNEL		(__START_KERNEL_map + __PHYSICAL_START)
-#define __START_KERNEL_map	_AC(0xffffffff80000000, UL)
-
-/* See Documentation/x86_64/mm.txt for a description of the memory map. */
-#define __PHYSICAL_MASK_SHIFT	46
-#define __VIRTUAL_MASK_SHIFT	48
-
-/*
- * Kernel image size is limited to 512 MB (see level2_kernel_pgt in
- * arch/x86/kernel/head_64.S), and it is mapped here:
- */
-#define KERNEL_IMAGE_SIZE	(512 * 1024 * 1024)
-#define KERNEL_IMAGE_START	_AC(0xffffffff80000000, UL)
-
-#ifndef __ASSEMBLY__
-void clear_page(void *page);
-void copy_page(void *to, void *from);
-
-/* duplicated to the one in bootmem.h */
-extern unsigned long max_pfn;
-extern unsigned long phys_base;
-
-extern unsigned long __phys_addr(unsigned long);
-#define __phys_reloc_hide(x)	(x)
-
-/*
- * These are used to make use of C type-checking..
- */
-typedef unsigned long	pteval_t;
-typedef unsigned long	pmdval_t;
-typedef unsigned long	pudval_t;
-typedef unsigned long	pgdval_t;
-typedef unsigned long	pgprotval_t;
-
-typedef struct page *pgtable_t;
-
-typedef struct { pteval_t pte; } pte_t;
-
-#define vmemmap ((struct page *)VMEMMAP_START)
-
-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 free_initmem(void);
-
-extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
-extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
-
-#endif	/* !__ASSEMBLY__ */
-
-#ifdef CONFIG_FLATMEM
-#define pfn_valid(pfn)          ((pfn) < max_pfn)
-#endif
-
+#include <asm/page_64_types.h>
 
 #endif /* _ASM_X86_PAGE_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_64_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_64_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_64_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_64_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,89 @@
+#ifndef _ASM_X86_PAGE_64_DEFS_H
+#define _ASM_X86_PAGE_64_DEFS_H
+
+#define THREAD_ORDER	1
+#define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
+#define CURRENT_MASK (~(THREAD_SIZE - 1))
+
+#define EXCEPTION_STACK_ORDER 0
+#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
+
+#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
+#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
+
+#define IRQ_STACK_ORDER 2
+#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
+
+#define STACKFAULT_STACK 1
+#define DOUBLEFAULT_STACK 2
+#define NMI_STACK 3
+#define DEBUG_STACK 4
+#define MCE_STACK 5
+#define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
+
+#define PUD_PAGE_SIZE		(_AC(1, UL) << PUD_SHIFT)
+#define PUD_PAGE_MASK		(~(PUD_PAGE_SIZE-1))
+
+/*
+ * Set __PAGE_OFFSET to the most negative possible address +
+ * PGDIR_SIZE*16 (pgd slot 272).  The gap is to allow a space for a
+ * hypervisor to fit.  Choosing 16 slots here is arbitrary, but it's
+ * what Xen requires.
+ */
+#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)
+
+#define __PHYSICAL_START	CONFIG_PHYSICAL_START
+#define __KERNEL_ALIGN		0x200000
+
+/*
+ * Make sure kernel is aligned to 2MB address. Catching it at compile
+ * time is better. Change your config file and compile the kernel
+ * for a 2MB aligned address (CONFIG_PHYSICAL_START)
+ */
+#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
+#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
+#endif
+
+#define __START_KERNEL		(__START_KERNEL_map + __PHYSICAL_START)
+#define __START_KERNEL_map	_AC(0xffffffff80000000, UL)
+
+/* See Documentation/x86_64/mm.txt for a description of the memory map. */
+#define __PHYSICAL_MASK_SHIFT	46
+#define __VIRTUAL_MASK_SHIFT	48
+
+/*
+ * Kernel image size is limited to 512 MB (see level2_kernel_pgt in
+ * arch/x86/kernel/head_64.S), and it is mapped here:
+ */
+#define KERNEL_IMAGE_SIZE	(512 * 1024 * 1024)
+#define KERNEL_IMAGE_START	_AC(0xffffffff80000000, UL)
+
+#ifndef __ASSEMBLY__
+void clear_page(void *page);
+void copy_page(void *to, void *from);
+
+/* duplicated to the one in bootmem.h */
+extern unsigned long max_pfn;
+extern unsigned long phys_base;
+
+extern unsigned long __phys_addr(unsigned long);
+#define __phys_reloc_hide(x)	(x)
+
+#define vmemmap ((struct page *)VMEMMAP_START)
+
+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 free_initmem(void);
+
+extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
+extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
+
+#endif	/* !__ASSEMBLY__ */
+
+#ifdef CONFIG_FLATMEM
+#define pfn_valid(pfn)          ((pfn) < max_pfn)
+#endif
+
+#endif /* _ASM_X86_PAGE_64_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,42 +1,11 @@
 #ifndef _ASM_X86_PAGE_H
 #define _ASM_X86_PAGE_H
 
-#include <linux/const.h>
-
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT	12
-#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK	(~(PAGE_SIZE-1))
+#include <linux/types.h>
 
 #ifdef __KERNEL__
 
-#define __PHYSICAL_MASK		((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
-#define __VIRTUAL_MASK		((1UL << __VIRTUAL_MASK_SHIFT) - 1)
-
-/* Cast PAGE_MASK to a signed type so that it is sign-extended if
-   virtual addresses are 32-bits but physical addresses are larger
-   (ie, 32-bit PAE). */
-#define PHYSICAL_PAGE_MASK	(((signed long)PAGE_MASK) & __PHYSICAL_MASK)
-
-/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
-#define PTE_PFN_MASK		((pteval_t)PHYSICAL_PAGE_MASK)
-
-/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
-#define PTE_FLAGS_MASK		(~PTE_PFN_MASK)
-
-#define PMD_PAGE_SIZE		(_AC(1, UL) << PMD_SHIFT)
-#define PMD_PAGE_MASK		(~(PMD_PAGE_SIZE-1))
-
-#define HPAGE_SHIFT		PMD_SHIFT
-#define HPAGE_SIZE		(_AC(1,UL) << HPAGE_SHIFT)
-#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
-#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
-
-#define HUGE_MAX_HSTATE 2
-
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-#endif
+#include <asm/page_types.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/page_64.h>
@@ -44,38 +13,18 @@
 #include <asm/page_32.h>
 #endif	/* CONFIG_X86_64 */
 
-#define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
-
-#define VM_DATA_DEFAULT_FLAGS \
-	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
-	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-
 #ifndef __ASSEMBLY__
 
-typedef struct { pgdval_t pgd; } pgd_t;
-typedef struct { pgprotval_t pgprot; } pgprot_t;
-
-extern int page_is_ram(unsigned long pagenr);
-extern int devmem_is_allowed(unsigned long pagenr);
-extern void map_devmem(unsigned long pfn, unsigned long size,
-		       pgprot_t vma_prot);
-extern void unmap_devmem(unsigned long pfn, unsigned long size,
-			 pgprot_t vma_prot);
-
-extern unsigned long max_low_pfn_mapped;
-extern unsigned long max_pfn_mapped;
-
 struct page;
 
 static inline void clear_user_page(void *page, unsigned long vaddr,
-				struct page *pg)
+				   struct page *pg)
 {
 	clear_page(page);
 }
 
 static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
-				struct page *topage)
+				  struct page *topage)
 {
 	copy_page(to, from);
 }
@@ -84,99 +33,6 @@ static inline void copy_user_page(void *
 	alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
 #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 
-static inline pgd_t native_make_pgd(pgdval_t val)
-{
-	return (pgd_t) { val };
-}
-
-static inline pgdval_t native_pgd_val(pgd_t pgd)
-{
-	return pgd.pgd;
-}
-
-#if PAGETABLE_LEVELS >= 3
-#if PAGETABLE_LEVELS == 4
-typedef struct { pudval_t pud; } pud_t;
-
-static inline pud_t native_make_pud(pmdval_t val)
-{
-	return (pud_t) { val };
-}
-
-static inline pudval_t native_pud_val(pud_t pud)
-{
-	return pud.pud;
-}
-#else	/* PAGETABLE_LEVELS == 3 */
-#include <asm-generic/pgtable-nopud.h>
-
-static inline pudval_t native_pud_val(pud_t pud)
-{
-	return native_pgd_val(pud.pgd);
-}
-#endif	/* PAGETABLE_LEVELS == 4 */
-
-typedef struct { pmdval_t pmd; } pmd_t;
-
-static inline pmd_t native_make_pmd(pmdval_t val)
-{
-	return (pmd_t) { val };
-}
-
-static inline pmdval_t native_pmd_val(pmd_t pmd)
-{
-	return pmd.pmd;
-}
-#else  /* PAGETABLE_LEVELS == 2 */
-#include <asm-generic/pgtable-nopmd.h>
-
-static inline pmdval_t native_pmd_val(pmd_t pmd)
-{
-	return native_pgd_val(pmd.pud.pgd);
-}
-#endif	/* PAGETABLE_LEVELS >= 3 */
-
-static inline pte_t native_make_pte(pteval_t val)
-{
-	return (pte_t) { .pte = val };
-}
-
-static inline pteval_t native_pte_val(pte_t pte)
-{
-	return pte.pte;
-}
-
-static inline pteval_t native_pte_flags(pte_t pte)
-{
-	return native_pte_val(pte) & PTE_FLAGS_MASK;
-}
-
-#define pgprot_val(x)	((x).pgprot)
-#define __pgprot(x)	((pgprot_t) { (x) } )
-
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#else  /* !CONFIG_PARAVIRT */
-
-#define pgd_val(x)	native_pgd_val(x)
-#define __pgd(x)	native_make_pgd(x)
-
-#ifndef __PAGETABLE_PUD_FOLDED
-#define pud_val(x)	native_pud_val(x)
-#define __pud(x)	native_make_pud(x)
-#endif
-
-#ifndef __PAGETABLE_PMD_FOLDED
-#define pmd_val(x)	native_pmd_val(x)
-#define __pmd(x)	native_make_pmd(x)
-#endif
-
-#define pte_val(x)	native_pte_val(x)
-#define pte_flags(x)	native_pte_flags(x)
-#define __pte(x)	native_make_pte(x)
-
-#endif	/* CONFIG_PARAVIRT */
-
 #define __pa(x)		__phys_addr((unsigned long)(x))
 #define __pa_nodebug(x)	__phys_addr_nodebug((unsigned long)(x))
 /* __pa_symbol should be used for C visible symbols.
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/page_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/page_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,51 @@
+#ifndef _ASM_X86_PAGE_DEFS_H
+#define _ASM_X86_PAGE_DEFS_H
+
+#include <linux/const.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#define __PHYSICAL_MASK		((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
+#define __VIRTUAL_MASK		((1UL << __VIRTUAL_MASK_SHIFT) - 1)
+
+/* Cast PAGE_MASK to a signed type so that it is sign-extended if
+   virtual addresses are 32-bits but physical addresses are larger
+   (ie, 32-bit PAE). */
+#define PHYSICAL_PAGE_MASK	(((signed long)PAGE_MASK) & __PHYSICAL_MASK)
+
+#define PMD_PAGE_SIZE		(_AC(1, UL) << PMD_SHIFT)
+#define PMD_PAGE_MASK		(~(PMD_PAGE_SIZE-1))
+
+#define HPAGE_SHIFT		PMD_SHIFT
+#define HPAGE_SIZE		(_AC(1,UL) << HPAGE_SHIFT)
+#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+
+#define HUGE_MAX_HSTATE 2
+
+#define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
+
+#define VM_DATA_DEFAULT_FLAGS \
+	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#ifdef CONFIG_X86_64
+#include <asm/page_64_types.h>
+#else
+#include <asm/page_32_types.h>
+#endif	/* CONFIG_X86_64 */
+
+#ifndef __ASSEMBLY__
+
+extern int page_is_ram(unsigned long pagenr);
+extern int devmem_is_allowed(unsigned long pagenr);
+
+extern unsigned long max_low_pfn_mapped;
+extern unsigned long max_pfn_mapped;
+
+#endif	/* !__ASSEMBLY__ */
+
+#endif	/* _ASM_X86_PAGE_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/paravirt.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/paravirt.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/paravirt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/paravirt.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * para-virtualization: those hooks are defined here. */
 
 #ifdef CONFIG_PARAVIRT
-#include <asm/page.h>
+#include <asm/pgtable_types.h>
 #include <asm/asm.h>
 
 /* Bitmask of what can be clobbered: usually at least eax. */
@@ -12,21 +12,38 @@
 #define CLBR_EAX  (1 << 0)
 #define CLBR_ECX  (1 << 1)
 #define CLBR_EDX  (1 << 2)
+#define CLBR_EDI  (1 << 3)
 
-#ifdef CONFIG_X86_64
-#define CLBR_RSI  (1 << 3)
-#define CLBR_RDI  (1 << 4)
+#ifdef CONFIG_X86_32
+/* CLBR_ANY should match all regs platform has. For i386, that's just it */
+#define CLBR_ANY  ((1 << 4) - 1)
+
+#define CLBR_ARG_REGS	(CLBR_EAX | CLBR_EDX | CLBR_ECX)
+#define CLBR_RET_REG	(CLBR_EAX | CLBR_EDX)
+#define CLBR_SCRATCH	(0)
+#else
+#define CLBR_RAX  CLBR_EAX
+#define CLBR_RCX  CLBR_ECX
+#define CLBR_RDX  CLBR_EDX
+#define CLBR_RDI  CLBR_EDI
+#define CLBR_RSI  (1 << 4)
 #define CLBR_R8   (1 << 5)
 #define CLBR_R9   (1 << 6)
 #define CLBR_R10  (1 << 7)
 #define CLBR_R11  (1 << 8)
+
 #define CLBR_ANY  ((1 << 9) - 1)
+
+#define CLBR_ARG_REGS	(CLBR_RDI | CLBR_RSI | CLBR_RDX | \
+			 CLBR_RCX | CLBR_R8 | CLBR_R9)
+#define CLBR_RET_REG	(CLBR_RAX)
+#define CLBR_SCRATCH	(CLBR_R10 | CLBR_R11)
+
 #include <asm/desc_defs.h>
-#else
-/* CLBR_ANY should match all regs platform has. For i386, that's just it */
-#define CLBR_ANY  ((1 << 3) - 1)
 #endif /* X86_64 */
 
+#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
+
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/cpumask.h>
@@ -40,6 +57,14 @@ struct tss_struct;
 struct mm_struct;
 struct desc_struct;
 
+/*
+ * Wrapper type for pointers to code which uses the non-standard
+ * calling convention.  See PV_CALL_SAVE_REGS_THUNK below.
+ */
+struct paravirt_callee_save {
+	void *func;
+};
+
 /* general info */
 struct pv_info {
 	unsigned int kernel_rpl;
@@ -189,11 +214,15 @@ struct pv_irq_ops {
 	 * expected to use X86_EFLAGS_IF; all other bits
 	 * returned from save_fl are undefined, and may be ignored by
 	 * restore_fl.
+	 *
+	 * NOTE: These functions callers expect the callee to preserve
+	 * more registers than the standard C calling convention.
 	 */
-	unsigned long (*save_fl)(void);
-	void (*restore_fl)(unsigned long);
-	void (*irq_disable)(void);
-	void (*irq_enable)(void);
+	struct paravirt_callee_save save_fl;
+	struct paravirt_callee_save restore_fl;
+	struct paravirt_callee_save irq_disable;
+	struct paravirt_callee_save irq_enable;
+
 	void (*safe_halt)(void);
 	void (*halt)(void);
 
@@ -244,7 +273,8 @@ struct pv_mmu_ops {
 	void (*flush_tlb_user)(void);
 	void (*flush_tlb_kernel)(void);
 	void (*flush_tlb_single)(unsigned long addr);
-	void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm,
+	void (*flush_tlb_others)(const struct cpumask *cpus,
+				 struct mm_struct *mm,
 				 unsigned long va);
 
 	/* Hooks for allocating and freeing a pagetable top-level */
@@ -278,18 +308,15 @@ struct pv_mmu_ops {
 	void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
 					pte_t *ptep, pte_t pte);
 
-	pteval_t (*pte_val)(pte_t);
-	pteval_t (*pte_flags)(pte_t);
-	pte_t (*make_pte)(pteval_t pte);
+	struct paravirt_callee_save pte_val;
+	struct paravirt_callee_save make_pte;
 
-	pgdval_t (*pgd_val)(pgd_t);
-	pgd_t (*make_pgd)(pgdval_t pgd);
+	struct paravirt_callee_save pgd_val;
+	struct paravirt_callee_save make_pgd;
 
 #if PAGETABLE_LEVELS >= 3
 #ifdef CONFIG_X86_PAE
 	void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
-	void (*set_pte_present)(struct mm_struct *mm, unsigned long addr,
-				pte_t *ptep, pte_t pte);
 	void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
 			  pte_t *ptep);
 	void (*pmd_clear)(pmd_t *pmdp);
@@ -298,12 +325,12 @@ struct pv_mmu_ops {
 
 	void (*set_pud)(pud_t *pudp, pud_t pudval);
 
-	pmdval_t (*pmd_val)(pmd_t);
-	pmd_t (*make_pmd)(pmdval_t pmd);
+	struct paravirt_callee_save pmd_val;
+	struct paravirt_callee_save make_pmd;
 
 #if PAGETABLE_LEVELS == 4
-	pudval_t (*pud_val)(pud_t);
-	pud_t (*make_pud)(pudval_t pud);
+	struct paravirt_callee_save pud_val;
+	struct paravirt_callee_save make_pud;
 
 	void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
 #endif	/* PAGETABLE_LEVELS == 4 */
@@ -320,7 +347,7 @@ struct pv_mmu_ops {
 	/* Sometimes the physical address is a pfn, and sometimes its
 	   an mfn.  We can tell which is which from the index. */
 	void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
-			   unsigned long phys, pgprot_t flags);
+			   phys_addr_t phys, pgprot_t flags);
 };
 
 struct raw_spinlock;
@@ -360,7 +387,7 @@ extern struct pv_lock_ops pv_lock_ops;
 
 #define paravirt_type(op)				\
 	[paravirt_typenum] "i" (PARAVIRT_PATCH(op)),	\
-	[paravirt_opptr] "m" (op)
+	[paravirt_opptr] "i" (&(op))
 #define paravirt_clobber(clobber)		\
 	[paravirt_clobber] "i" (clobber)
 
@@ -388,6 +415,8 @@ extern struct pv_lock_ops pv_lock_ops;
 	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
 
 unsigned paravirt_patch_nop(void);
+unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
+unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
 unsigned paravirt_patch_ignore(unsigned len);
 unsigned paravirt_patch_call(void *insnbuf,
 			     const void *target, u16 tgt_clobbers,
@@ -412,7 +441,7 @@ int paravirt_disable_iospace(void);
  * offset into the paravirt_patch_template structure, and can therefore be
  * freely converted back into a structure offset.
  */
-#define PARAVIRT_CALL	"call *%[paravirt_opptr];"
+#define PARAVIRT_CALL	"call *%c[paravirt_opptr];"
 
 /*
  * These macros are intended to wrap calls through one of the paravirt
@@ -479,25 +508,45 @@ int paravirt_disable_iospace(void);
  * makes sure the incoming and outgoing types are always correct.
  */
 #ifdef CONFIG_X86_32
-#define PVOP_VCALL_ARGS			unsigned long __eax, __edx, __ecx
+#define PVOP_VCALL_ARGS				\
+	unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
 #define PVOP_CALL_ARGS			PVOP_VCALL_ARGS
+
+#define PVOP_CALL_ARG1(x)		"a" ((unsigned long)(x))
+#define PVOP_CALL_ARG2(x)		"d" ((unsigned long)(x))
+#define PVOP_CALL_ARG3(x)		"c" ((unsigned long)(x))
+
 #define PVOP_VCALL_CLOBBERS		"=a" (__eax), "=d" (__edx),	\
 					"=c" (__ecx)
 #define PVOP_CALL_CLOBBERS		PVOP_VCALL_CLOBBERS
+
+#define PVOP_VCALLEE_CLOBBERS		"=a" (__eax), "=d" (__edx)
+#define PVOP_CALLEE_CLOBBERS		PVOP_VCALLEE_CLOBBERS
+
 #define EXTRA_CLOBBERS
 #define VEXTRA_CLOBBERS
-#else
-#define PVOP_VCALL_ARGS		unsigned long __edi, __esi, __edx, __ecx
+#else  /* CONFIG_X86_64 */
+#define PVOP_VCALL_ARGS					\
+	unsigned long __edi = __edi, __esi = __esi,	\
+		__edx = __edx, __ecx = __ecx
 #define PVOP_CALL_ARGS		PVOP_VCALL_ARGS, __eax
+
+#define PVOP_CALL_ARG1(x)		"D" ((unsigned long)(x))
+#define PVOP_CALL_ARG2(x)		"S" ((unsigned long)(x))
+#define PVOP_CALL_ARG3(x)		"d" ((unsigned long)(x))
+#define PVOP_CALL_ARG4(x)		"c" ((unsigned long)(x))
+
 #define PVOP_VCALL_CLOBBERS	"=D" (__edi),				\
 				"=S" (__esi), "=d" (__edx),		\
 				"=c" (__ecx)
-
 #define PVOP_CALL_CLOBBERS	PVOP_VCALL_CLOBBERS, "=a" (__eax)
 
+#define PVOP_VCALLEE_CLOBBERS	"=a" (__eax)
+#define PVOP_CALLEE_CLOBBERS	PVOP_VCALLEE_CLOBBERS
+
 #define EXTRA_CLOBBERS	 , "r8", "r9", "r10", "r11"
 #define VEXTRA_CLOBBERS	 , "rax", "r8", "r9", "r10", "r11"
-#endif
+#endif	/* CONFIG_X86_32 */
 
 #ifdef CONFIG_PARAVIRT_DEBUG
 #define PVOP_TEST_NULL(op)	BUG_ON(op == NULL)
@@ -505,10 +554,11 @@ int paravirt_disable_iospace(void);
 #define PVOP_TEST_NULL(op)	((void)op)
 #endif
 
-#define __PVOP_CALL(rettype, op, pre, post, ...)			\
+#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr,		\
+		      pre, post, ...)					\
 	({								\
 		rettype __ret;						\
-		PVOP_CALL_ARGS;					\
+		PVOP_CALL_ARGS;						\
 		PVOP_TEST_NULL(op);					\
 		/* This is 32-bit specific, but is okay in 64-bit */	\
 		/* since this condition will never hold */		\
@@ -516,70 +566,113 @@ int paravirt_disable_iospace(void);
 			asm volatile(pre				\
 				     paravirt_alt(PARAVIRT_CALL)	\
 				     post				\
-				     : PVOP_CALL_CLOBBERS		\
+				     : call_clbr			\
 				     : paravirt_type(op),		\
-				       paravirt_clobber(CLBR_ANY),	\
+				       paravirt_clobber(clbr),		\
 				       ##__VA_ARGS__			\
-				     : "memory", "cc" EXTRA_CLOBBERS);	\
+				     : "memory", "cc" extra_clbr);	\
 			__ret = (rettype)((((u64)__edx) << 32) | __eax); \
 		} else {						\
 			asm volatile(pre				\
 				     paravirt_alt(PARAVIRT_CALL)	\
 				     post				\
-				     : PVOP_CALL_CLOBBERS		\
+				     : call_clbr			\
 				     : paravirt_type(op),		\
-				       paravirt_clobber(CLBR_ANY),	\
+				       paravirt_clobber(clbr),		\
 				       ##__VA_ARGS__			\
-				     : "memory", "cc" EXTRA_CLOBBERS);	\
+				     : "memory", "cc" extra_clbr);	\
 			__ret = (rettype)__eax;				\
 		}							\
 		__ret;							\
 	})
-#define __PVOP_VCALL(op, pre, post, ...)				\
+
+#define __PVOP_CALL(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS,	\
+		      EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
+
+#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
+		      PVOP_CALLEE_CLOBBERS, ,				\
+		      pre, post, ##__VA_ARGS__)
+
+
+#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...)	\
 	({								\
 		PVOP_VCALL_ARGS;					\
 		PVOP_TEST_NULL(op);					\
 		asm volatile(pre					\
 			     paravirt_alt(PARAVIRT_CALL)		\
 			     post					\
-			     : PVOP_VCALL_CLOBBERS			\
+			     : call_clbr				\
 			     : paravirt_type(op),			\
-			       paravirt_clobber(CLBR_ANY),		\
+			       paravirt_clobber(clbr),			\
 			       ##__VA_ARGS__				\
-			     : "memory", "cc" VEXTRA_CLOBBERS);		\
+			     : "memory", "cc" extra_clbr);		\
 	})
 
+#define __PVOP_VCALL(op, pre, post, ...)				\
+	____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS,		\
+		       VEXTRA_CLOBBERS,					\
+		       pre, post, ##__VA_ARGS__)
+
+#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
+		      PVOP_VCALLEE_CLOBBERS, ,				\
+		      pre, post, ##__VA_ARGS__)
+
+
+
 #define PVOP_CALL0(rettype, op)						\
 	__PVOP_CALL(rettype, op, "", "")
 #define PVOP_VCALL0(op)							\
 	__PVOP_VCALL(op, "", "")
 
+#define PVOP_CALLEE0(rettype, op)					\
+	__PVOP_CALLEESAVE(rettype, op, "", "")
+#define PVOP_VCALLEE0(op)						\
+	__PVOP_VCALLEESAVE(op, "", "")
+
+
 #define PVOP_CALL1(rettype, op, arg1)					\
-	__PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)))
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
 #define PVOP_VCALL1(op, arg1)						\
-	__PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)))
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
+
+#define PVOP_CALLEE1(rettype, op, arg1)					\
+	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
+#define PVOP_VCALLEE1(op, arg1)						\
+	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
+
 
 #define PVOP_CALL2(rettype, op, arg1, arg2)				\
-	__PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)), 	\
-	"1" ((unsigned long)(arg2)))
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
+		    PVOP_CALL_ARG2(arg2))
 #define PVOP_VCALL2(op, arg1, arg2)					\
-	__PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)), 		\
-	"1" ((unsigned long)(arg2)))
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
+		     PVOP_CALL_ARG2(arg2))
+
+#define PVOP_CALLEE2(rettype, op, arg1, arg2)				\
+	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1),	\
+			  PVOP_CALL_ARG2(arg2))
+#define PVOP_VCALLEE2(op, arg1, arg2)					\
+	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1),		\
+			   PVOP_CALL_ARG2(arg2))
+
 
 #define PVOP_CALL3(rettype, op, arg1, arg2, arg3)			\
-	__PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)),	\
-	"1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)))
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
+		    PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
 #define PVOP_VCALL3(op, arg1, arg2, arg3)				\
-	__PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)),		\
-	"1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)))
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
+		     PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
 
 /* This is the only difference in x86_64. We can make it much simpler */
 #ifdef CONFIG_X86_32
 #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
 	__PVOP_CALL(rettype, op,					\
 		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
-		    "0" ((u32)(arg1)), "1" ((u32)(arg2)),		\
-		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
+		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
+		    PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
 #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
 	__PVOP_VCALL(op,						\
 		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
@@ -587,13 +680,13 @@ int paravirt_disable_iospace(void);
 		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
 #else
 #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
-	__PVOP_CALL(rettype, op, "", "", "0" ((unsigned long)(arg1)),	\
-	"1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)),		\
-	"3"((unsigned long)(arg4)))
+	__PVOP_CALL(rettype, op, "", "",				\
+		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
+		    PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
 #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
-	__PVOP_VCALL(op, "", "", "0" ((unsigned long)(arg1)),		\
-	"1"((unsigned long)(arg2)), "2"((unsigned long)(arg3)),		\
-	"3"((unsigned long)(arg4)))
+	__PVOP_VCALL(op, "", "",					\
+		     PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),	\
+		     PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
 #endif
 
 static inline int paravirt_enabled(void)
@@ -984,10 +1077,11 @@ static inline void __flush_tlb_single(un
 	PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);
 }
 
-static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+static inline void flush_tlb_others(const struct cpumask *cpumask,
+				    struct mm_struct *mm,
 				    unsigned long va)
 {
-	PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va);
+	PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va);
 }
 
 static inline int paravirt_pgd_alloc(struct mm_struct *mm)
@@ -1059,13 +1153,13 @@ static inline pte_t __pte(pteval_t val)
 	pteval_t ret;
 
 	if (sizeof(pteval_t) > sizeof(long))
-		ret = PVOP_CALL2(pteval_t,
-				 pv_mmu_ops.make_pte,
-				 val, (u64)val >> 32);
+		ret = PVOP_CALLEE2(pteval_t,
+				   pv_mmu_ops.make_pte,
+				   val, (u64)val >> 32);
 	else
-		ret = PVOP_CALL1(pteval_t,
-				 pv_mmu_ops.make_pte,
-				 val);
+		ret = PVOP_CALLEE1(pteval_t,
+				   pv_mmu_ops.make_pte,
+				   val);
 
 	return (pte_t) { .pte = ret };
 }
@@ -1075,29 +1169,12 @@ static inline pteval_t pte_val(pte_t pte
 	pteval_t ret;
 
 	if (sizeof(pteval_t) > sizeof(long))
-		ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_val,
-				 pte.pte, (u64)pte.pte >> 32);
-	else
-		ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_val,
-				 pte.pte);
-
-	return ret;
-}
-
-static inline pteval_t pte_flags(pte_t pte)
-{
-	pteval_t ret;
-
-	if (sizeof(pteval_t) > sizeof(long))
-		ret = PVOP_CALL2(pteval_t, pv_mmu_ops.pte_flags,
-				 pte.pte, (u64)pte.pte >> 32);
+		ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_val,
+				   pte.pte, (u64)pte.pte >> 32);
 	else
-		ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_flags,
-				 pte.pte);
+		ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_val,
+				   pte.pte);
 
-#ifdef CONFIG_PARAVIRT_DEBUG
-	BUG_ON(ret & PTE_PFN_MASK);
-#endif
 	return ret;
 }
 
@@ -1106,11 +1183,11 @@ static inline pgd_t __pgd(pgdval_t val)
 	pgdval_t ret;
 
 	if (sizeof(pgdval_t) > sizeof(long))
-		ret = PVOP_CALL2(pgdval_t, pv_mmu_ops.make_pgd,
-				 val, (u64)val >> 32);
+		ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.make_pgd,
+				   val, (u64)val >> 32);
 	else
-		ret = PVOP_CALL1(pgdval_t, pv_mmu_ops.make_pgd,
-				 val);
+		ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.make_pgd,
+				   val);
 
 	return (pgd_t) { ret };
 }
@@ -1120,11 +1197,11 @@ static inline pgdval_t pgd_val(pgd_t pgd
 	pgdval_t ret;
 
 	if (sizeof(pgdval_t) > sizeof(long))
-		ret =  PVOP_CALL2(pgdval_t, pv_mmu_ops.pgd_val,
-				  pgd.pgd, (u64)pgd.pgd >> 32);
+		ret =  PVOP_CALLEE2(pgdval_t, pv_mmu_ops.pgd_val,
+				    pgd.pgd, (u64)pgd.pgd >> 32);
 	else
-		ret =  PVOP_CALL1(pgdval_t, pv_mmu_ops.pgd_val,
-				  pgd.pgd);
+		ret =  PVOP_CALLEE1(pgdval_t, pv_mmu_ops.pgd_val,
+				    pgd.pgd);
 
 	return ret;
 }
@@ -1188,11 +1265,11 @@ static inline pmd_t __pmd(pmdval_t val)
 	pmdval_t ret;
 
 	if (sizeof(pmdval_t) > sizeof(long))
-		ret = PVOP_CALL2(pmdval_t, pv_mmu_ops.make_pmd,
-				 val, (u64)val >> 32);
+		ret = PVOP_CALLEE2(pmdval_t, pv_mmu_ops.make_pmd,
+				   val, (u64)val >> 32);
 	else
-		ret = PVOP_CALL1(pmdval_t, pv_mmu_ops.make_pmd,
-				 val);
+		ret = PVOP_CALLEE1(pmdval_t, pv_mmu_ops.make_pmd,
+				   val);
 
 	return (pmd_t) { ret };
 }
@@ -1202,11 +1279,11 @@ static inline pmdval_t pmd_val(pmd_t pmd
 	pmdval_t ret;
 
 	if (sizeof(pmdval_t) > sizeof(long))
-		ret =  PVOP_CALL2(pmdval_t, pv_mmu_ops.pmd_val,
-				  pmd.pmd, (u64)pmd.pmd >> 32);
+		ret =  PVOP_CALLEE2(pmdval_t, pv_mmu_ops.pmd_val,
+				    pmd.pmd, (u64)pmd.pmd >> 32);
 	else
-		ret =  PVOP_CALL1(pmdval_t, pv_mmu_ops.pmd_val,
-				  pmd.pmd);
+		ret =  PVOP_CALLEE1(pmdval_t, pv_mmu_ops.pmd_val,
+				    pmd.pmd);
 
 	return ret;
 }
@@ -1228,11 +1305,11 @@ static inline pud_t __pud(pudval_t val)
 	pudval_t ret;
 
 	if (sizeof(pudval_t) > sizeof(long))
-		ret = PVOP_CALL2(pudval_t, pv_mmu_ops.make_pud,
-				 val, (u64)val >> 32);
+		ret = PVOP_CALLEE2(pudval_t, pv_mmu_ops.make_pud,
+				   val, (u64)val >> 32);
 	else
-		ret = PVOP_CALL1(pudval_t, pv_mmu_ops.make_pud,
-				 val);
+		ret = PVOP_CALLEE1(pudval_t, pv_mmu_ops.make_pud,
+				   val);
 
 	return (pud_t) { ret };
 }
@@ -1242,11 +1319,11 @@ static inline pudval_t pud_val(pud_t pud
 	pudval_t ret;
 
 	if (sizeof(pudval_t) > sizeof(long))
-		ret =  PVOP_CALL2(pudval_t, pv_mmu_ops.pud_val,
-				  pud.pud, (u64)pud.pud >> 32);
+		ret =  PVOP_CALLEE2(pudval_t, pv_mmu_ops.pud_val,
+				    pud.pud, (u64)pud.pud >> 32);
 	else
-		ret =  PVOP_CALL1(pudval_t, pv_mmu_ops.pud_val,
-				  pud.pud);
+		ret =  PVOP_CALLEE1(pudval_t, pv_mmu_ops.pud_val,
+				    pud.pud);
 
 	return ret;
 }
@@ -1286,13 +1363,6 @@ static inline void set_pte_atomic(pte_t
 		    pte.pte, pte.pte >> 32);
 }
 
-static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
-				   pte_t *ptep, pte_t pte)
-{
-	/* 5 arg words */
-	pv_mmu_ops.set_pte_present(mm, addr, ptep, pte);
-}
-
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 			     pte_t *ptep)
 {
@@ -1309,12 +1379,6 @@ static inline void set_pte_atomic(pte_t
 	set_pte(ptep, pte);
 }
 
-static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
-				   pte_t *ptep, pte_t pte)
-{
-	set_pte(ptep, pte);
-}
-
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 			     pte_t *ptep)
 {
@@ -1368,17 +1432,18 @@ static inline void arch_leave_lazy_mmu_m
 void arch_flush_lazy_mmu_mode(void);
 
 static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
-				unsigned long phys, pgprot_t flags)
+				phys_addr_t phys, pgprot_t flags)
 {
 	pv_mmu_ops.set_fixmap(idx, phys, flags);
 }
 
 void _paravirt_nop(void);
-#define paravirt_nop	((void *)_paravirt_nop)
+u32 _paravirt_ident_32(u32);
+u64 _paravirt_ident_64(u64);
 
-void paravirt_use_bytelocks(void);
+#define paravirt_nop	((void *)_paravirt_nop)
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
 
 static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
 {
@@ -1426,12 +1491,37 @@ extern struct paravirt_patch_site __para
 	__parainstructions_end[];
 
 #ifdef CONFIG_X86_32
-#define PV_SAVE_REGS "pushl %%ecx; pushl %%edx;"
-#define PV_RESTORE_REGS "popl %%edx; popl %%ecx"
+#define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
+#define PV_RESTORE_REGS "popl %edx; popl %ecx;"
+
+/* save and restore all caller-save registers, except return value */
+#define PV_SAVE_ALL_CALLER_REGS		"pushl %ecx;"
+#define PV_RESTORE_ALL_CALLER_REGS	"popl  %ecx;"
+
 #define PV_FLAGS_ARG "0"
 #define PV_EXTRA_CLOBBERS
 #define PV_VEXTRA_CLOBBERS
 #else
+/* save and restore all caller-save registers, except return value */
+#define PV_SAVE_ALL_CALLER_REGS						\
+	"push %rcx;"							\
+	"push %rdx;"							\
+	"push %rsi;"							\
+	"push %rdi;"							\
+	"push %r8;"							\
+	"push %r9;"							\
+	"push %r10;"							\
+	"push %r11;"
+#define PV_RESTORE_ALL_CALLER_REGS					\
+	"pop %r11;"							\
+	"pop %r10;"							\
+	"pop %r9;"							\
+	"pop %r8;"							\
+	"pop %rdi;"							\
+	"pop %rsi;"							\
+	"pop %rdx;"							\
+	"pop %rcx;"
+
 /* We save some registers, but all of them, that's too much. We clobber all
  * caller saved registers but the argument parameter */
 #define PV_SAVE_REGS "pushq %%rdi;"
@@ -1441,52 +1531,76 @@ extern struct paravirt_patch_site __para
 #define PV_FLAGS_ARG "D"
 #endif
 
+/*
+ * Generate a thunk around a function which saves all caller-save
+ * registers except for the return value.  This allows C functions to
+ * be called from assembler code where fewer than normal registers are
+ * available.  It may also help code generation around calls from C
+ * code if the common case doesn't use many registers.
+ *
+ * When a callee is wrapped in a thunk, the caller can assume that all
+ * arg regs and all scratch registers are preserved across the
+ * call. The return value in rax/eax will not be saved, even for void
+ * functions.
+ */
+#define PV_CALLEE_SAVE_REGS_THUNK(func)					\
+	extern typeof(func) __raw_callee_save_##func;			\
+	static void *__##func##__ __used = func;			\
+									\
+	asm(".pushsection .text;"					\
+	    "__raw_callee_save_" #func ": "				\
+	    PV_SAVE_ALL_CALLER_REGS					\
+	    "call " #func ";"						\
+	    PV_RESTORE_ALL_CALLER_REGS					\
+	    "ret;"							\
+	    ".popsection")
+
+/* Get a reference to a callee-save function */
+#define PV_CALLEE_SAVE(func)						\
+	((struct paravirt_callee_save) { __raw_callee_save_##func })
+
+/* Promise that "func" already uses the right calling convention */
+#define __PV_IS_CALLEE_SAVE(func)			\
+	((struct paravirt_callee_save) { func })
+
 static inline unsigned long __raw_local_save_flags(void)
 {
 	unsigned long f;
 
-	asm volatile(paravirt_alt(PV_SAVE_REGS
-				  PARAVIRT_CALL
-				  PV_RESTORE_REGS)
+	asm volatile(paravirt_alt(PARAVIRT_CALL)
 		     : "=a"(f)
 		     : paravirt_type(pv_irq_ops.save_fl),
 		       paravirt_clobber(CLBR_EAX)
-		     : "memory", "cc" PV_VEXTRA_CLOBBERS);
+		     : "memory", "cc");
 	return f;
 }
 
 static inline void raw_local_irq_restore(unsigned long f)
 {
-	asm volatile(paravirt_alt(PV_SAVE_REGS
-				  PARAVIRT_CALL
-				  PV_RESTORE_REGS)
+	asm volatile(paravirt_alt(PARAVIRT_CALL)
 		     : "=a"(f)
 		     : PV_FLAGS_ARG(f),
 		       paravirt_type(pv_irq_ops.restore_fl),
 		       paravirt_clobber(CLBR_EAX)
-		     : "memory", "cc" PV_EXTRA_CLOBBERS);
+		     : "memory", "cc");
 }
 
 static inline void raw_local_irq_disable(void)
 {
-	asm volatile(paravirt_alt(PV_SAVE_REGS
-				  PARAVIRT_CALL
-				  PV_RESTORE_REGS)
+	asm volatile(paravirt_alt(PARAVIRT_CALL)
 		     :
 		     : paravirt_type(pv_irq_ops.irq_disable),
 		       paravirt_clobber(CLBR_EAX)
-		     : "memory", "eax", "cc" PV_EXTRA_CLOBBERS);
+		     : "memory", "eax", "cc");
 }
 
 static inline void raw_local_irq_enable(void)
 {
-	asm volatile(paravirt_alt(PV_SAVE_REGS
-				  PARAVIRT_CALL
-				  PV_RESTORE_REGS)
+	asm volatile(paravirt_alt(PARAVIRT_CALL)
 		     :
 		     : paravirt_type(pv_irq_ops.irq_enable),
 		       paravirt_clobber(CLBR_EAX)
-		     : "memory", "eax", "cc" PV_EXTRA_CLOBBERS);
+		     : "memory", "eax", "cc");
 }
 
 static inline unsigned long __raw_local_irq_save(void)
@@ -1529,33 +1643,49 @@ static inline unsigned long __raw_local_
 	.popsection
 
 
+#define COND_PUSH(set, mask, reg)			\
+	.if ((~(set)) & mask); push %reg; .endif
+#define COND_POP(set, mask, reg)			\
+	.if ((~(set)) & mask); pop %reg; .endif
+
 #ifdef CONFIG_X86_64
-#define PV_SAVE_REGS				\
-	push %rax;				\
-	push %rcx;				\
-	push %rdx;				\
-	push %rsi;				\
-	push %rdi;				\
-	push %r8;				\
-	push %r9;				\
-	push %r10;				\
-	push %r11
-#define PV_RESTORE_REGS				\
-	pop %r11;				\
-	pop %r10;				\
-	pop %r9;				\
-	pop %r8;				\
-	pop %rdi;				\
-	pop %rsi;				\
-	pop %rdx;				\
-	pop %rcx;				\
-	pop %rax
+
+#define PV_SAVE_REGS(set)			\
+	COND_PUSH(set, CLBR_RAX, rax);		\
+	COND_PUSH(set, CLBR_RCX, rcx);		\
+	COND_PUSH(set, CLBR_RDX, rdx);		\
+	COND_PUSH(set, CLBR_RSI, rsi);		\
+	COND_PUSH(set, CLBR_RDI, rdi);		\
+	COND_PUSH(set, CLBR_R8, r8);		\
+	COND_PUSH(set, CLBR_R9, r9);		\
+	COND_PUSH(set, CLBR_R10, r10);		\
+	COND_PUSH(set, CLBR_R11, r11)
+#define PV_RESTORE_REGS(set)			\
+	COND_POP(set, CLBR_R11, r11);		\
+	COND_POP(set, CLBR_R10, r10);		\
+	COND_POP(set, CLBR_R9, r9);		\
+	COND_POP(set, CLBR_R8, r8);		\
+	COND_POP(set, CLBR_RDI, rdi);		\
+	COND_POP(set, CLBR_RSI, rsi);		\
+	COND_POP(set, CLBR_RDX, rdx);		\
+	COND_POP(set, CLBR_RCX, rcx);		\
+	COND_POP(set, CLBR_RAX, rax)
+
 #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 8)
 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8)
 #define PARA_INDIRECT(addr)	*addr(%rip)
 #else
-#define PV_SAVE_REGS   pushl %eax; pushl %edi; pushl %ecx; pushl %edx
-#define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
+#define PV_SAVE_REGS(set)			\
+	COND_PUSH(set, CLBR_EAX, eax);		\
+	COND_PUSH(set, CLBR_EDI, edi);		\
+	COND_PUSH(set, CLBR_ECX, ecx);		\
+	COND_PUSH(set, CLBR_EDX, edx)
+#define PV_RESTORE_REGS(set)			\
+	COND_POP(set, CLBR_EDX, edx);		\
+	COND_POP(set, CLBR_ECX, ecx);		\
+	COND_POP(set, CLBR_EDI, edi);		\
+	COND_POP(set, CLBR_EAX, eax)
+
 #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 4)
 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
 #define PARA_INDIRECT(addr)	*%cs:addr
@@ -1567,15 +1697,15 @@ static inline unsigned long __raw_local_
 
 #define DISABLE_INTERRUPTS(clobbers)					\
 	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
-		  PV_SAVE_REGS;						\
+		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\
 		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable);	\
-		  PV_RESTORE_REGS;)			\
+		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #define ENABLE_INTERRUPTS(clobbers)					\
 	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers,	\
-		  PV_SAVE_REGS;						\
+		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\
 		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable);	\
-		  PV_RESTORE_REGS;)
+		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #define USERGS_SYSRET32							\
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32),	\
@@ -1605,11 +1735,15 @@ static inline unsigned long __raw_local_
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\
 		  swapgs)
 
+/*
+ * Note: swapgs is very special, and in practise is either going to be
+ * implemented with a single "swapgs" instruction or something very
+ * special.  Either way, we don't need to save any registers for
+ * it.
+ */
 #define SWAPGS								\
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\
-		  PV_SAVE_REGS;						\
-		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs);		\
-		  PV_RESTORE_REGS					\
+		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs)		\
 		 )
 
 #define GET_CR2_INTO_RCX				\
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pat.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pat.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pat.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pat.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,13 +2,12 @@
 #define _ASM_X86_PAT_H
 
 #include <linux/types.h>
+#include <asm/pgtable_types.h>
 
 #ifdef CONFIG_X86_PAT
 extern int pat_enabled;
-extern void validate_pat_support(struct cpuinfo_x86 *c);
 #else
 static const int pat_enabled;
-static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
 #endif
 
 extern void pat_init(void);
@@ -17,6 +16,7 @@ extern int reserve_memtype(u64 start, u6
 		unsigned long req_type, unsigned long *ret_type);
 extern int free_memtype(u64 start, u64 end);
 
-extern void pat_disable(char *reason);
+extern int kernel_map_sync_memtype(u64 base, unsigned long size,
+		unsigned long flag);
 
 #endif /* _ASM_X86_PAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci_32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-#ifndef _ASM_X86_PCI_32_H
-#define _ASM_X86_PCI_32_H
-
-
-#ifdef __KERNEL__
-
-
-/* Dynamic DMA mapping stuff.
- * i386 has everything mapped statically.
- */
-
-struct pci_dev;
-
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME[0];
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)	unsigned LEN_NAME[0];
-#define pci_unmap_addr(PTR, ADDR_NAME)	sizeof((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
-	do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
-#define pci_unmap_len(PTR, LEN_NAME)		sizeof((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
-	do { break; } while (pci_unmap_len(PTR, LEN_NAME))
-
-
-#endif /* __KERNEL__ */
-
-
-#endif /* _ASM_X86_PCI_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,28 +24,6 @@ extern int (*pci_config_write)(int seg,
 
 extern void dma32_reserve_bootmem(void);
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions
- *
- * On AMD64 it mostly equals, but we set it to zero if a hardware
- * IOMMU (gart) of sotware IOMMU (swiotlb) is available.
- */
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
-#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))
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_X86_PCI_64_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci-functions.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci-functions.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci-functions.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci-functions.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ *	PCI BIOS function numbering for conventional PCI BIOS 
+ *	systems
+ */
+
+#define PCIBIOS_PCI_FUNCTION_ID 	0xb1XX
+#define PCIBIOS_PCI_BIOS_PRESENT 	0xb101
+#define PCIBIOS_FIND_PCI_DEVICE		0xb102
+#define PCIBIOS_FIND_PCI_CLASS_CODE	0xb103
+#define PCIBIOS_GENERATE_SPECIAL_CYCLE	0xb106
+#define PCIBIOS_READ_CONFIG_BYTE	0xb108
+#define PCIBIOS_READ_CONFIG_WORD	0xb109
+#define PCIBIOS_READ_CONFIG_DWORD	0xb10a
+#define PCIBIOS_WRITE_CONFIG_BYTE	0xb10b
+#define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
+#define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
+#define PCIBIOS_GET_ROUTING_OPTIONS	0xb10e
+#define PCIBIOS_SET_PCI_HW_INT		0xb10f
+
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -86,12 +86,43 @@ static inline void early_quirks(void) {
 
 extern void pci_iommu_alloc(void);
 
-#endif  /* __KERNEL__ */
+/* MSI arch hook */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG)
+
+#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_X86_32
-# include "pci_32.h"
 #else
-# include "pci_64.h"
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)       dma_addr_t ADDR_NAME[0];
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
+#define pci_unmap_addr(PTR, ADDR_NAME)  sizeof((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+	        do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
+#define pci_unmap_len(PTR, LEN_NAME)            sizeof((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+	        do { break; } while (pci_unmap_len(PTR, LEN_NAME))
+
+#endif
+
+#endif  /* __KERNEL__ */
+
+#ifdef CONFIG_X86_64
+#include "pci_64.h"
 #endif
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
@@ -109,11 +140,6 @@ static inline int __pcibus_to_node(const
 	return sd->node;
 }
 
-static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
-{
-	return node_to_cpumask(__pcibus_to_node(bus));
-}
-
 static inline const struct cpumask *
 cpumask_of_pcibus(const struct pci_bus *bus)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pda.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pda.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pda.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pda.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,137 +0,0 @@
-#ifndef _ASM_X86_PDA_H
-#define _ASM_X86_PDA_H
-
-#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <linux/types.h>
-#include <linux/cache.h>
-#include <asm/page.h>
-
-/* Per processor datastructure. %gs points to it while the kernel runs */
-struct x8664_pda {
-	struct task_struct *pcurrent;	/* 0  Current process */
-	unsigned long data_offset;	/* 8 Per cpu data offset from linker
-					   address */
-	unsigned long kernelstack;	/* 16 top of kernel stack for current */
-	unsigned long oldrsp;		/* 24 user rsp for system call */
-	int irqcount;			/* 32 Irq nesting counter. Starts -1 */
-	unsigned int cpunumber;		/* 36 Logical CPU number */
-#ifdef CONFIG_CC_STACKPROTECTOR
-	unsigned long stack_canary;	/* 40 stack canary value */
-					/* gcc-ABI: this canary MUST be at
-					   offset 40!!! */
-#endif
-	char *irqstackptr;
-	short nodenumber;		/* number of current node (32k max) */
-	short in_bootmem;		/* pda lives in bootmem */
-	unsigned int __softirq_pending;
-	unsigned int __nmi_count;	/* number of NMI on this CPUs */
-	short mmu_state;
-	short isidle;
-	struct mm_struct *active_mm;
-	unsigned apic_timer_irqs;
-	unsigned irq0_irqs;
-	unsigned irq_resched_count;
-	unsigned irq_call_count;
-	unsigned irq_tlb_count;
-	unsigned irq_thermal_count;
-	unsigned irq_threshold_count;
-	unsigned irq_spurious_count;
-} ____cacheline_aligned_in_smp;
-
-extern struct x8664_pda **_cpu_pda;
-extern void pda_init(int);
-
-#define cpu_pda(i) (_cpu_pda[i])
-
-/*
- * There is no fast way to get the base address of the PDA, all the accesses
- * have to mention %fs/%gs.  So it needs to be done this Torvaldian way.
- */
-extern void __bad_pda_field(void) __attribute__((noreturn));
-
-/*
- * proxy_pda doesn't actually exist, but tell gcc it is accessed for
- * all PDA accesses so it gets read/write dependencies right.
- */
-extern struct x8664_pda _proxy_pda;
-
-#define pda_offset(field) offsetof(struct x8664_pda, field)
-
-#define pda_to_op(op, field, val)					\
-do {									\
-	typedef typeof(_proxy_pda.field) T__;				\
-	if (0) { T__ tmp__; tmp__ = (val); }	/* type checking */	\
-	switch (sizeof(_proxy_pda.field)) {				\
-	case 2:								\
-		asm(op "w %1,%%gs:%c2" :				\
-		    "+m" (_proxy_pda.field) :				\
-		    "ri" ((T__)val),					\
-		    "i"(pda_offset(field)));				\
-		break;							\
-	case 4:								\
-		asm(op "l %1,%%gs:%c2" :				\
-		    "+m" (_proxy_pda.field) :				\
-		    "ri" ((T__)val),					\
-		    "i" (pda_offset(field)));				\
-		break;							\
-	case 8:								\
-		asm(op "q %1,%%gs:%c2":					\
-		    "+m" (_proxy_pda.field) :				\
-		    "ri" ((T__)val),					\
-		    "i"(pda_offset(field)));				\
-		break;							\
-	default:							\
-		__bad_pda_field();					\
-	}								\
-} while (0)
-
-#define pda_from_op(op, field)			\
-({						\
-	typeof(_proxy_pda.field) ret__;		\
-	switch (sizeof(_proxy_pda.field)) {	\
-	case 2:					\
-		asm(op "w %%gs:%c1,%0" :	\
-		    "=r" (ret__) :		\
-		    "i" (pda_offset(field)),	\
-		    "m" (_proxy_pda.field));	\
-		break;				\
-	case 4:					\
-		asm(op "l %%gs:%c1,%0":		\
-		    "=r" (ret__):		\
-		    "i" (pda_offset(field)),	\
-		    "m" (_proxy_pda.field));	\
-		break;				\
-	case 8:					\
-		asm(op "q %%gs:%c1,%0":		\
-		    "=r" (ret__) :		\
-		    "i" (pda_offset(field)),	\
-		    "m" (_proxy_pda.field));	\
-		break;				\
-	default:				\
-		__bad_pda_field();		\
-	}					\
-	ret__;					\
-})
-
-#define read_pda(field)		pda_from_op("mov", field)
-#define write_pda(field, val)	pda_to_op("mov", field, val)
-#define add_pda(field, val)	pda_to_op("add", field, val)
-#define sub_pda(field, val)	pda_to_op("sub", field, val)
-#define or_pda(field, val)	pda_to_op("or", field, val)
-
-/* This is not atomic against other CPUs -- CPU preemption needs to be off */
-#define test_and_clear_bit_pda(bit, field)				\
-({									\
-	int old__;							\
-	asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0"			\
-		     : "=r" (old__), "+m" (_proxy_pda.field)		\
-		     : "dIr" (bit), "i" (pda_offset(field)) : "memory");\
-	old__;								\
-})
-
-#endif
-
-#define PDA_STACKOFFSET (5*8)
-
-#endif /* _ASM_X86_PDA_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/percpu.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/percpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/percpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,53 +2,12 @@
 #define _ASM_X86_PERCPU_H
 
 #ifdef CONFIG_X86_64
-#include <linux/compiler.h>
-
-/* Same as asm-generic/percpu.h, except that we store the per cpu offset
-   in the PDA. Longer term the PDA and every per cpu variable
-   should be just put into a single section and referenced directly
-   from %gs */
-
-#ifdef CONFIG_SMP
-#include <asm/pda.h>
-
-#define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset)
-#define __my_cpu_offset read_pda(data_offset)
-
-#define per_cpu_offset(x) (__per_cpu_offset(x))
-
+#define __percpu_seg		gs
+#define __percpu_mov_op		movq
+#else
+#define __percpu_seg		fs
+#define __percpu_mov_op		movl
 #endif
-#include <asm-generic/percpu.h>
-
-DECLARE_PER_CPU(struct x8664_pda, pda);
-
-/*
- * These are supposed to be implemented as a single instruction which
- * operates on the per-cpu data base segment.  x86-64 doesn't have
- * that yet, so this is a fairly inefficient workaround for the
- * meantime.  The single instruction is atomic with respect to
- * preemption and interrupts, so we need to explicitly disable
- * interrupts here to achieve the same effect.  However, because it
- * can be used from within interrupt-disable/enable, we can't actually
- * disable interrupts; disabling preemption is enough.
- */
-#define x86_read_percpu(var)						\
-	({								\
-		typeof(per_cpu_var(var)) __tmp;				\
-		preempt_disable();					\
-		__tmp = __get_cpu_var(var);				\
-		preempt_enable();					\
-		__tmp;							\
-	})
-
-#define x86_write_percpu(var, val)					\
-	do {								\
-		preempt_disable();					\
-		__get_cpu_var(var) = (val);				\
-		preempt_enable();					\
-	} while(0)
-
-#else /* CONFIG_X86_64 */
 
 #ifdef __ASSEMBLY__
 
@@ -65,47 +24,48 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
  *    PER_CPU(cpu_gdt_descr, %ebx)
  */
 #ifdef CONFIG_SMP
-#define PER_CPU(var, reg)				\
-	movl %fs:per_cpu__##this_cpu_off, reg;		\
+#define PER_CPU(var, reg)						\
+	__percpu_mov_op %__percpu_seg:per_cpu__this_cpu_off, reg;	\
 	lea per_cpu__##var(reg), reg
-#define PER_CPU_VAR(var)	%fs:per_cpu__##var
+#define PER_CPU_VAR(var)	%__percpu_seg:per_cpu__##var
 #else /* ! SMP */
-#define PER_CPU(var, reg)			\
-	movl $per_cpu__##var, reg
+#define PER_CPU(var, reg)						\
+	__percpu_mov_op $per_cpu__##var, reg
 #define PER_CPU_VAR(var)	per_cpu__##var
 #endif	/* SMP */
 
+#ifdef CONFIG_X86_64_SMP
+#define INIT_PER_CPU_VAR(var)  init_per_cpu__##var
+#else
+#define INIT_PER_CPU_VAR(var)  per_cpu__##var
+#endif
+
 #else /* ...!ASSEMBLY */
 
+#include <linux/stringify.h>
+
+#ifdef CONFIG_SMP
+#define __percpu_arg(x)		"%%"__stringify(__percpu_seg)":%P" #x
+#define __my_cpu_offset		percpu_read(this_cpu_off)
+#else
+#define __percpu_arg(x)		"%" #x
+#endif
+
 /*
- * PER_CPU finds an address of a per-cpu variable.
- *
- * Args:
- *    var - variable name
- *    cpu - 32bit register containing the current CPU number
- *
- * The resulting address is stored in the "cpu" argument.
+ * Initialized pointers to per-cpu variables needed for the boot
+ * processor need to use these macros to get the proper address
+ * offset from __per_cpu_load on SMP.
  *
- * Example:
- *    PER_CPU(cpu_gdt_descr, %ebx)
+ * There also must be an entry in vmlinux_64.lds.S
  */
-#ifdef CONFIG_SMP
-
-#define __my_cpu_offset x86_read_percpu(this_cpu_off)
-
-/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
-#define __percpu_seg "%%fs:"
-
-#else  /* !SMP */
-
-#define __percpu_seg ""
-
-#endif	/* SMP */
-
-#include <asm-generic/percpu.h>
+#define DECLARE_INIT_PER_CPU(var) \
+       extern typeof(per_cpu_var(var)) init_per_cpu_var(var)
 
-/* We can use this directly for local CPU (faster). */
-DECLARE_PER_CPU(unsigned long, this_cpu_off);
+#ifdef CONFIG_X86_64_SMP
+#define init_per_cpu_var(var)  init_per_cpu__##var
+#else
+#define init_per_cpu_var(var)  per_cpu_var(var)
+#endif
 
 /* For arch-specific code, we can use direct single-insn ops (they
  * don't give an lvalue though). */
@@ -120,19 +80,24 @@ do {							\
 	}						\
 	switch (sizeof(var)) {				\
 	case 1:						\
-		asm(op "b %1,"__percpu_seg"%0"		\
+		asm(op "b %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "ri" ((T__)val));			\
+		    : "qi" ((T__)(val)));		\
 		break;					\
 	case 2:						\
-		asm(op "w %1,"__percpu_seg"%0"		\
+		asm(op "w %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "ri" ((T__)val));			\
+		    : "ri" ((T__)(val)));		\
 		break;					\
 	case 4:						\
-		asm(op "l %1,"__percpu_seg"%0"		\
+		asm(op "l %1,"__percpu_arg(0)		\
 		    : "+m" (var)			\
-		    : "ri" ((T__)val));			\
+		    : "ri" ((T__)(val)));		\
+		break;					\
+	case 8:						\
+		asm(op "q %1,"__percpu_arg(0)		\
+		    : "+m" (var)			\
+		    : "re" ((T__)(val)));		\
 		break;					\
 	default: __bad_percpu_size();			\
 	}						\
@@ -143,17 +108,22 @@ do {							\
 	typeof(var) ret__;				\
 	switch (sizeof(var)) {				\
 	case 1:						\
-		asm(op "b "__percpu_seg"%1,%0"		\
-		    : "=r" (ret__)			\
+		asm(op "b "__percpu_arg(1)",%0"		\
+		    : "=q" (ret__)			\
 		    : "m" (var));			\
 		break;					\
 	case 2:						\
-		asm(op "w "__percpu_seg"%1,%0"		\
+		asm(op "w "__percpu_arg(1)",%0"		\
 		    : "=r" (ret__)			\
 		    : "m" (var));			\
 		break;					\
 	case 4:						\
-		asm(op "l "__percpu_seg"%1,%0"		\
+		asm(op "l "__percpu_arg(1)",%0"		\
+		    : "=r" (ret__)			\
+		    : "m" (var));			\
+		break;					\
+	case 8:						\
+		asm(op "q "__percpu_arg(1)",%0"		\
 		    : "=r" (ret__)			\
 		    : "m" (var));			\
 		break;					\
@@ -162,13 +132,30 @@ do {							\
 	ret__;						\
 })
 
-#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var)
-#define x86_write_percpu(var, val) percpu_to_op("mov", per_cpu__##var, val)
-#define x86_add_percpu(var, val) percpu_to_op("add", per_cpu__##var, val)
-#define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val)
-#define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val)
+#define percpu_read(var)	percpu_from_op("mov", per_cpu__##var)
+#define percpu_write(var, val)	percpu_to_op("mov", per_cpu__##var, val)
+#define percpu_add(var, val)	percpu_to_op("add", per_cpu__##var, val)
+#define percpu_sub(var, val)	percpu_to_op("sub", per_cpu__##var, val)
+#define percpu_and(var, val)	percpu_to_op("and", per_cpu__##var, val)
+#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)
+
+/* This is not atomic against other CPUs -- CPU preemption needs to be off */
+#define x86_test_and_clear_bit_percpu(bit, var)				\
+({									\
+	int old__;							\
+	asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0"		\
+		     : "=r" (old__), "+m" (per_cpu__##var)		\
+		     : "dIr" (bit));					\
+	old__;								\
+})
+
+#include <asm-generic/percpu.h>
+
+/* We can use this directly for local CPU (faster). */
+DECLARE_PER_CPU(unsigned long, this_cpu_off);
+
 #endif /* !__ASSEMBLY__ */
-#endif /* !CONFIG_X86_64 */
 
 #ifdef CONFIG_SMP
 
@@ -195,9 +182,9 @@ do {							\
 #define	early_per_cpu_ptr(_name) (_name##_early_ptr)
 #define	early_per_cpu_map(_name, _idx) (_name##_early_map[_idx])
 #define	early_per_cpu(_name, _cpu) 				\
-	(early_per_cpu_ptr(_name) ?				\
-		early_per_cpu_ptr(_name)[_cpu] :		\
-		per_cpu(_name, _cpu))
+	*(early_per_cpu_ptr(_name) ?				\
+		&early_per_cpu_ptr(_name)[_cpu] :		\
+		&per_cpu(_name, _cpu))
 
 #else	/* !CONFIG_SMP */
 #define	DEFINE_EARLY_PER_CPU(_type, _name, _initvalue)		\
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level-defs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level-defs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level-defs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level-defs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H
-#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H
-
-#define SHARED_KERNEL_PMD	0
-
-/*
- * traditional i386 two-level paging structure:
- */
-
-#define PGDIR_SHIFT	22
-#define PTRS_PER_PGD	1024
-
-/*
- * the i386 is two-level, so we don't really have any
- * PMD directory physically.
- */
-
-#define PTRS_PER_PTE	1024
-
-#endif /* _ASM_X86_PGTABLE_2LEVEL_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,13 +26,6 @@ static inline void native_set_pte_atomic
 	native_set_pte(ptep, pte);
 }
 
-static inline void native_set_pte_present(struct mm_struct *mm,
-					  unsigned long addr,
-					  pte_t *ptep, pte_t pte)
-{
-	native_set_pte(ptep, pte);
-}
-
 static inline void native_pmd_clear(pmd_t *pmdp)
 {
 	native_set_pmd(pmdp, __pmd(0));
@@ -53,8 +46,6 @@ static inline pte_t native_ptep_get_and_
 #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
 #endif
 
-#define pte_none(x)		(!(x).pte_low)
-
 /*
  * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken,
  * split up the 29 bits of offset into this range:
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-2level_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-2level_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,37 @@
+#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H
+#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+typedef unsigned long	pteval_t;
+typedef unsigned long	pmdval_t;
+typedef unsigned long	pudval_t;
+typedef unsigned long	pgdval_t;
+typedef unsigned long	pgprotval_t;
+
+typedef union {
+	pteval_t pte;
+	pteval_t pte_low;
+} pte_t;
+#endif	/* !__ASSEMBLY__ */
+
+#define SHARED_KERNEL_PMD	0
+#define PAGETABLE_LEVELS	2
+
+/*
+ * traditional i386 two-level paging structure:
+ */
+
+#define PGDIR_SHIFT	22
+#define PTRS_PER_PGD	1024
+
+
+/*
+ * the i386 is two-level, so we don't really have any
+ * PMD directory physically.
+ */
+
+#define PTRS_PER_PTE	1024
+
+#endif /* _ASM_X86_PGTABLE_2LEVEL_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef _ASM_X86_PGTABLE_32_H
 #define _ASM_X86_PGTABLE_32_H
 
+#include <asm/pgtable_32_types.h>
 
 /*
  * The Linux memory management assumes a three-level page table setup. On
@@ -33,47 +34,6 @@ void paging_init(void);
 
 extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
 
-/*
- * The Linux x86 paging architecture is 'compile-time dual-mode', it
- * implements both the traditional 2-level x86 page tables and the
- * newer 3-level PAE-mode page tables.
- */
-#ifdef CONFIG_X86_PAE
-# include <asm/pgtable-3level-defs.h>
-# define PMD_SIZE	(1UL << PMD_SHIFT)
-# define PMD_MASK	(~(PMD_SIZE - 1))
-#else
-# include <asm/pgtable-2level-defs.h>
-#endif
-
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
-
-/* Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts.  That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_OFFSET	(8 * 1024 * 1024)
-#define VMALLOC_START	((unsigned long)high_memory + VMALLOC_OFFSET)
-#ifdef CONFIG_X86_PAE
-#define LAST_PKMAP 512
-#else
-#define LAST_PKMAP 1024
-#endif
-
-#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1))	\
-		    & PMD_MASK)
-
-#ifdef CONFIG_HIGHMEM
-# define VMALLOC_END	(PKMAP_BASE - 2 * PAGE_SIZE)
-#else
-# define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
-#endif
-
-#define MAXMEM	(VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
 
 /*
  * Define this if things work differently on an i386 and an i486:
@@ -82,58 +42,12 @@ extern void set_pmd_pfn(unsigned long, u
  */
 #undef TEST_ACCESS_OK
 
-/* The boot page tables (all created as a single array) */
-extern unsigned long pg0[];
-
-#define pte_present(x)	((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
-
-/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
-#define pmd_none(x)	(!(unsigned long)pmd_val((x)))
-#define pmd_present(x)	(pmd_val((x)) & _PAGE_PRESENT)
-#define pmd_bad(x) ((pmd_val(x) & (PTE_FLAGS_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
-
-#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-
 #ifdef CONFIG_X86_PAE
 # include <asm/pgtable-3level.h>
 #else
 # include <asm/pgtable-2level.h>
 #endif
 
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
-
-
-static inline int pud_large(pud_t pud) { return 0; }
-
-/*
- * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
- *
- * this macro returns the index of the entry in the pmd page which would
- * control the given virtual address
- */
-#define pmd_index(address)				\
-	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
-
-/*
- * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
- *
- * this macro returns the index of the entry in the pte page which would
- * control the given virtual address
- */
-#define pte_index(address)					\
-	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-#define pte_offset_kernel(dir, address)				\
-	((pte_t *)pmd_page_vaddr(*(dir)) +  pte_index((address)))
-
-#define pmd_page(pmd) (pfn_to_page(pmd_val((pmd)) >> PAGE_SHIFT))
-
-#define pmd_page_vaddr(pmd)					\
-	((unsigned long)__va(pmd_val((pmd)) & PTE_PFN_MASK))
-
 #if defined(CONFIG_HIGHPTE)
 #define pte_offset_map(dir, address)					\
 	((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), KM_PTE0) +		\
@@ -176,7 +90,4 @@ do {						\
 #define kern_addr_valid(kaddr)	(0)
 #endif
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #endif /* _ASM_X86_PGTABLE_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_32_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_32_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_32_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_32_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,51 @@
+#ifndef _ASM_X86_PGTABLE_32_DEFS_H
+#define _ASM_X86_PGTABLE_32_DEFS_H
+
+/*
+ * The Linux x86 paging architecture is 'compile-time dual-mode', it
+ * implements both the traditional 2-level x86 page tables and the
+ * newer 3-level PAE-mode page tables.
+ */
+#ifdef CONFIG_X86_PAE
+# include <asm/pgtable-3level_types.h>
+# define PMD_SIZE	(1UL << PMD_SHIFT)
+# define PMD_MASK	(~(PMD_SIZE - 1))
+#else
+# include <asm/pgtable-2level_types.h>
+#endif
+
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	(8 * 1024 * 1024)
+
+#ifndef __ASSEMBLER__
+extern bool __vmalloc_start_set; /* set once high_memory is set */
+#endif
+
+#define VMALLOC_START	((unsigned long)high_memory + VMALLOC_OFFSET)
+#ifdef CONFIG_X86_PAE
+#define LAST_PKMAP 512
+#else
+#define LAST_PKMAP 1024
+#endif
+
+#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1))	\
+		    & PMD_MASK)
+
+#ifdef CONFIG_HIGHMEM
+# define VMALLOC_END	(PKMAP_BASE - 2 * PAGE_SIZE)
+#else
+# define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
+#endif
+
+#define MAXMEM	(VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
+
+#endif /* _ASM_X86_PGTABLE_32_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level-defs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level-defs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level-defs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level-defs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H
-#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H
-
-#ifdef CONFIG_PARAVIRT
-#define SHARED_KERNEL_PMD	(pv_info.shared_kernel_pmd)
-#else
-#define SHARED_KERNEL_PMD	1
-#endif
-
-/*
- * PGDIR_SHIFT determines what a top-level page table entry can map
- */
-#define PGDIR_SHIFT	30
-#define PTRS_PER_PGD	4
-
-/*
- * PMD_SHIFT determines the size of the area a middle-level
- * page table can map
- */
-#define PMD_SHIFT	21
-#define PTRS_PER_PMD	512
-
-/*
- * entries per page directory level
- */
-#define PTRS_PER_PTE	512
-
-#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,21 +18,6 @@
 	printk("%s:%d: bad pgd %p(%016Lx).\n",				\
 	       __FILE__, __LINE__, &(e), pgd_val(e))
 
-static inline int pud_none(pud_t pud)
-{
-	return pud_val(pud) == 0;
-}
-
-static inline int pud_bad(pud_t pud)
-{
-	return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
-}
-
-static inline int pud_present(pud_t pud)
-{
-	return pud_val(pud) & _PAGE_PRESENT;
-}
-
 /* Rules for using set_pte: the pte being assigned *must* be
  * either not present or in a state where the hardware will
  * not attempt to update the pte.  In places where this is
@@ -46,23 +31,6 @@ static inline void native_set_pte(pte_t
 	ptep->pte_low = pte.pte_low;
 }
 
-/*
- * Since this is only called on user PTEs, and the page fault handler
- * must handle the already racy situation of simultaneous page faults,
- * we are justified in merely clearing the PTE present bit, followed
- * by a set.  The ordering here is important.
- */
-static inline void native_set_pte_present(struct mm_struct *mm,
-					  unsigned long addr,
-					  pte_t *ptep, pte_t pte)
-{
-	ptep->pte_low = 0;
-	smp_wmb();
-	ptep->pte_high = pte.pte_high;
-	smp_wmb();
-	ptep->pte_low = pte.pte_low;
-}
-
 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
 {
 	set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
@@ -120,15 +88,6 @@ static inline void pud_clear(pud_t *pudp
 		write_cr3(pgd);
 }
 
-#define pud_page(pud) pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
-
-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PTE_PFN_MASK))
-
-
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(pud, address) ((pmd_t *)pud_page_vaddr(*(pud)) +	\
-				  pmd_index(address))
-
 #ifdef CONFIG_SMP
 static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
 {
@@ -145,17 +104,6 @@ static inline pte_t native_ptep_get_and_
 #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp)
 #endif
 
-#define __HAVE_ARCH_PTE_SAME
-static inline int pte_same(pte_t a, pte_t b)
-{
-	return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
-}
-
-static inline int pte_none(pte_t pte)
-{
-	return !pte.pte_low && !pte.pte_high;
-}
-
 /*
  * Bits 0, 6 and 7 are taken in the low part of the pte,
  * put the 32 bits of offset into the high part.
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable-3level_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable-3level_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H
+#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+typedef u64	pteval_t;
+typedef u64	pmdval_t;
+typedef u64	pudval_t;
+typedef u64	pgdval_t;
+typedef u64	pgprotval_t;
+
+typedef union {
+	struct {
+		unsigned long pte_low, pte_high;
+	};
+	pteval_t pte;
+} pte_t;
+#endif	/* !__ASSEMBLY__ */
+
+#ifdef CONFIG_PARAVIRT
+#define SHARED_KERNEL_PMD	(pv_info.shared_kernel_pmd)
+#else
+#define SHARED_KERNEL_PMD	1
+#endif
+
+#define PAGETABLE_LEVELS	3
+
+/*
+ * PGDIR_SHIFT determines what a top-level page table entry can map
+ */
+#define PGDIR_SHIFT	30
+#define PTRS_PER_PGD	4
+
+/*
+ * PMD_SHIFT determines the size of the area a middle-level
+ * page table can map
+ */
+#define PMD_SHIFT	21
+#define PTRS_PER_PMD	512
+
+/*
+ * entries per page directory level
+ */
+#define PTRS_PER_PTE	512
+
+
+#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,8 @@
 #define _ASM_X86_PGTABLE_64_H
 
 #include <linux/const.h>
+#include <asm/pgtable_64_types.h>
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -11,7 +13,6 @@
 #include <asm/processor.h>
 #include <linux/bitops.h>
 #include <linux/threads.h>
-#include <asm/pda.h>
 
 extern pud_t level3_kernel_pgt[512];
 extern pud_t level3_ident_pgt[512];
@@ -26,32 +27,6 @@ extern void paging_init(void);
 
 #endif /* !__ASSEMBLY__ */
 
-#define SHARED_KERNEL_PMD	0
-
-/*
- * PGDIR_SHIFT determines what a top-level page table entry can map
- */
-#define PGDIR_SHIFT	39
-#define PTRS_PER_PGD	512
-
-/*
- * 3rd level page
- */
-#define PUD_SHIFT	30
-#define PTRS_PER_PUD	512
-
-/*
- * PMD_SHIFT determines the size of the area a middle-level
- * page table can map
- */
-#define PMD_SHIFT	21
-#define PTRS_PER_PMD	512
-
-/*
- * entries per page directory level
- */
-#define PTRS_PER_PTE	512
-
 #ifndef __ASSEMBLY__
 
 #define pte_ERROR(e)					\
@@ -67,9 +42,6 @@ extern void paging_init(void);
 	printk("%s:%d: bad pgd %p(%016lx).\n",		\
 	       __FILE__, __LINE__, &(e), pgd_val(e))
 
-#define pgd_none(x)	(!pgd_val(x))
-#define pud_none(x)	(!pud_val(x))
-
 struct mm_struct;
 
 void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
@@ -134,48 +106,6 @@ static inline void native_pgd_clear(pgd_
 	native_set_pgd(pgd, native_make_pgd(0));
 }
 
-#define pte_same(a, b)		((a).pte == (b).pte)
-
-#endif /* !__ASSEMBLY__ */
-
-#define PMD_SIZE	(_AC(1, UL) << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE - 1))
-#define PUD_SIZE	(_AC(1, UL) << PUD_SHIFT)
-#define PUD_MASK	(~(PUD_SIZE - 1))
-#define PGDIR_SIZE	(_AC(1, UL) << PGDIR_SHIFT)
-#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
-
-
-#define MAXMEM		 _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
-#define VMALLOC_START    _AC(0xffffc20000000000, UL)
-#define VMALLOC_END      _AC(0xffffe1ffffffffff, UL)
-#define VMEMMAP_START	 _AC(0xffffe20000000000, UL)
-#define MODULES_VADDR    _AC(0xffffffffa0000000, UL)
-#define MODULES_END      _AC(0xffffffffff000000, UL)
-#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
-
-#ifndef __ASSEMBLY__
-
-static inline int pgd_bad(pgd_t pgd)
-{
-	return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
-}
-
-static inline int pud_bad(pud_t pud)
-{
-	return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
-}
-
-static inline int pmd_bad(pmd_t pmd)
-{
-	return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
-}
-
-#define pte_none(x)	(!pte_val((x)))
-#define pte_present(x)	(pte_val((x)) & (_PAGE_PRESENT | _PAGE_PROTNONE))
-
-#define pages_to_mb(x)	((x) >> (20 - PAGE_SHIFT))   /* FIXME: is this right? */
-
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
@@ -184,41 +114,12 @@ static inline int pmd_bad(pmd_t pmd)
 /*
  * Level 4 access.
  */
-#define pgd_page_vaddr(pgd)						\
-	((unsigned long)__va((unsigned long)pgd_val((pgd)) & PTE_PFN_MASK))
-#define pgd_page(pgd)		(pfn_to_page(pgd_val((pgd)) >> PAGE_SHIFT))
-#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
 static inline int pgd_large(pgd_t pgd) { return 0; }
 #define mk_kernel_pgd(address) __pgd((address) | _KERNPG_TABLE)
 
 /* PUD - Level3 access */
-/* to find an entry in a page-table-directory. */
-#define pud_page_vaddr(pud)						\
-	((unsigned long)__va(pud_val((pud)) & PHYSICAL_PAGE_MASK))
-#define pud_page(pud)	(pfn_to_page(pud_val((pud)) >> PAGE_SHIFT))
-#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
-#define pud_offset(pgd, address)					\
-	((pud_t *)pgd_page_vaddr(*(pgd)) + pud_index((address)))
-#define pud_present(pud) (pud_val((pud)) & _PAGE_PRESENT)
-
-static inline int pud_large(pud_t pte)
-{
-	return (pud_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
-		(_PAGE_PSE | _PAGE_PRESENT);
-}
 
 /* PMD  - Level 2 access */
-#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val((pmd)) & PTE_PFN_MASK))
-#define pmd_page(pmd)		(pfn_to_page(pmd_val((pmd)) >> PAGE_SHIFT))
-
-#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
-#define pmd_offset(dir, address) ((pmd_t *)pud_page_vaddr(*(dir)) + \
-				  pmd_index(address))
-#define pmd_none(x)	(!pmd_val((x)))
-#define pmd_present(x)	(pmd_val((x)) & _PAGE_PRESENT)
-#define pfn_pmd(nr, prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val((prot))))
-#define pmd_pfn(x)  ((pmd_val((x)) & __PHYSICAL_MASK) >> PAGE_SHIFT)
-
 #define pte_to_pgoff(pte) ((pte_val((pte)) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
 #define pgoff_to_pte(off) ((pte_t) { .pte = ((off) << PAGE_SHIFT) |	\
 					    _PAGE_FILE })
@@ -226,13 +127,6 @@ static inline int pud_large(pud_t pte)
 
 /* PTE - Level 1 access. */
 
-/* page, protection -> pte */
-#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn((page)), (pgprot))
-
-#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-#define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_vaddr(*(dir)) + \
-					 pte_index((address)))
-
 /* x86-64 always has all page tables mapped. */
 #define pte_offset_map(dir, address) pte_offset_kernel((dir), (address))
 #define pte_offset_map_nested(dir, address) pte_offset_kernel((dir), (address))
@@ -266,9 +160,6 @@ extern int direct_gbpages;
 extern int kern_addr_valid(unsigned long addr);
 extern void cleanup_highmap(void);
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_64_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_64_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_64_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_64_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,63 @@
+#ifndef _ASM_X86_PGTABLE_64_DEFS_H
+#define _ASM_X86_PGTABLE_64_DEFS_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef unsigned long	pteval_t;
+typedef unsigned long	pmdval_t;
+typedef unsigned long	pudval_t;
+typedef unsigned long	pgdval_t;
+typedef unsigned long	pgprotval_t;
+
+typedef struct { pteval_t pte; } pte_t;
+
+#endif	/* !__ASSEMBLY__ */
+
+#define SHARED_KERNEL_PMD	0
+#define PAGETABLE_LEVELS	4
+
+/*
+ * PGDIR_SHIFT determines what a top-level page table entry can map
+ */
+#define PGDIR_SHIFT	39
+#define PTRS_PER_PGD	512
+
+/*
+ * 3rd level page
+ */
+#define PUD_SHIFT	30
+#define PTRS_PER_PUD	512
+
+/*
+ * PMD_SHIFT determines the size of the area a middle-level
+ * page table can map
+ */
+#define PMD_SHIFT	21
+#define PTRS_PER_PMD	512
+
+/*
+ * entries per page directory level
+ */
+#define PTRS_PER_PTE	512
+
+#define PMD_SIZE	(_AC(1, UL) << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE - 1))
+#define PUD_SIZE	(_AC(1, UL) << PUD_SHIFT)
+#define PUD_MASK	(~(PUD_SIZE - 1))
+#define PGDIR_SIZE	(_AC(1, UL) << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
+
+
+#define MAXMEM		 _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
+#define VMALLOC_START    _AC(0xffffc20000000000, UL)
+#define VMALLOC_END      _AC(0xffffe1ffffffffff, UL)
+#define VMEMMAP_START	 _AC(0xffffe20000000000, UL)
+#define MODULES_VADDR    _AC(0xffffffffa0000000, UL)
+#define MODULES_END      _AC(0xffffffffff000000, UL)
+#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
+
+#endif /* _ASM_X86_PGTABLE_64_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,164 +1,9 @@
 #ifndef _ASM_X86_PGTABLE_H
 #define _ASM_X86_PGTABLE_H
 
-#define FIRST_USER_ADDRESS	0
-
-#define _PAGE_BIT_PRESENT	0	/* is present */
-#define _PAGE_BIT_RW		1	/* writeable */
-#define _PAGE_BIT_USER		2	/* userspace addressable */
-#define _PAGE_BIT_PWT		3	/* page write through */
-#define _PAGE_BIT_PCD		4	/* page cache disabled */
-#define _PAGE_BIT_ACCESSED	5	/* was accessed (raised by CPU) */
-#define _PAGE_BIT_DIRTY		6	/* was written to (raised by CPU) */
-#define _PAGE_BIT_PSE		7	/* 4 MB (or 2MB) page */
-#define _PAGE_BIT_PAT		7	/* on 4KB pages */
-#define _PAGE_BIT_GLOBAL	8	/* Global TLB entry PPro+ */
-#define _PAGE_BIT_UNUSED1	9	/* available for programmer */
-#define _PAGE_BIT_IOMAP		10	/* flag used to indicate IO mapping */
-#define _PAGE_BIT_UNUSED3	11
-#define _PAGE_BIT_PAT_LARGE	12	/* On 2MB or 1GB pages */
-#define _PAGE_BIT_SPECIAL	_PAGE_BIT_UNUSED1
-#define _PAGE_BIT_CPA_TEST	_PAGE_BIT_UNUSED1
-#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
-
-/* If _PAGE_BIT_PRESENT is clear, we use these: */
-/* - if the user mapped it with PROT_NONE; pte_present gives true */
-#define _PAGE_BIT_PROTNONE	_PAGE_BIT_GLOBAL
-/* - set: nonlinear file mapping, saved PTE; unset:swap */
-#define _PAGE_BIT_FILE		_PAGE_BIT_DIRTY
-
-#define _PAGE_PRESENT	(_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
-#define _PAGE_RW	(_AT(pteval_t, 1) << _PAGE_BIT_RW)
-#define _PAGE_USER	(_AT(pteval_t, 1) << _PAGE_BIT_USER)
-#define _PAGE_PWT	(_AT(pteval_t, 1) << _PAGE_BIT_PWT)
-#define _PAGE_PCD	(_AT(pteval_t, 1) << _PAGE_BIT_PCD)
-#define _PAGE_ACCESSED	(_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
-#define _PAGE_DIRTY	(_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
-#define _PAGE_PSE	(_AT(pteval_t, 1) << _PAGE_BIT_PSE)
-#define _PAGE_GLOBAL	(_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
-#define _PAGE_UNUSED1	(_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
-#define _PAGE_IOMAP	(_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
-#define _PAGE_UNUSED3	(_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
-#define _PAGE_PAT	(_AT(pteval_t, 1) << _PAGE_BIT_PAT)
-#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
-#define _PAGE_SPECIAL	(_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
-#define _PAGE_CPA_TEST	(_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
-#define __HAVE_ARCH_PTE_SPECIAL
-
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
-#define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
-#else
-#define _PAGE_NX	(_AT(pteval_t, 0))
-#endif
-
-#define _PAGE_FILE	(_AT(pteval_t, 1) << _PAGE_BIT_FILE)
-#define _PAGE_PROTNONE	(_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
-
-#define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |	\
-			 _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |	\
-			 _PAGE_DIRTY)
-
-/* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |		\
-			 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY)
-
-#define _PAGE_CACHE_MASK	(_PAGE_PCD | _PAGE_PWT)
-#define _PAGE_CACHE_WB		(0)
-#define _PAGE_CACHE_WC		(_PAGE_PWT)
-#define _PAGE_CACHE_UC_MINUS	(_PAGE_PCD)
-#define _PAGE_CACHE_UC		(_PAGE_PCD | _PAGE_PWT)
-
-#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
-				 _PAGE_ACCESSED | _PAGE_NX)
-
-#define PAGE_SHARED_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_RW |	\
-					 _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY_NOEXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
-					 _PAGE_ACCESSED | _PAGE_NX)
-#define PAGE_COPY_EXEC		__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
-					 _PAGE_ACCESSED)
-#define PAGE_COPY		PAGE_COPY_NOEXEC
-#define PAGE_READONLY		__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
-					 _PAGE_ACCESSED | _PAGE_NX)
-#define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
-					 _PAGE_ACCESSED)
-
-#define __PAGE_KERNEL_EXEC						\
-	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
-#define __PAGE_KERNEL		(__PAGE_KERNEL_EXEC | _PAGE_NX)
-
-#define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)
-#define __PAGE_KERNEL_RX		(__PAGE_KERNEL_EXEC & ~_PAGE_RW)
-#define __PAGE_KERNEL_EXEC_NOCACHE	(__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
-#define __PAGE_KERNEL_WC		(__PAGE_KERNEL | _PAGE_CACHE_WC)
-#define __PAGE_KERNEL_NOCACHE		(__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
-#define __PAGE_KERNEL_UC_MINUS		(__PAGE_KERNEL | _PAGE_PCD)
-#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)
-#define __PAGE_KERNEL_VSYSCALL_NOCACHE	(__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
-#define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)
-#define __PAGE_KERNEL_LARGE_NOCACHE	(__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
-#define __PAGE_KERNEL_LARGE_EXEC	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
-
-#define __PAGE_KERNEL_IO		(__PAGE_KERNEL | _PAGE_IOMAP)
-#define __PAGE_KERNEL_IO_NOCACHE	(__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP)
-#define __PAGE_KERNEL_IO_UC_MINUS	(__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP)
-#define __PAGE_KERNEL_IO_WC		(__PAGE_KERNEL_WC | _PAGE_IOMAP)
-
-#define PAGE_KERNEL			__pgprot(__PAGE_KERNEL)
-#define PAGE_KERNEL_RO			__pgprot(__PAGE_KERNEL_RO)
-#define PAGE_KERNEL_EXEC		__pgprot(__PAGE_KERNEL_EXEC)
-#define PAGE_KERNEL_RX			__pgprot(__PAGE_KERNEL_RX)
-#define PAGE_KERNEL_WC			__pgprot(__PAGE_KERNEL_WC)
-#define PAGE_KERNEL_NOCACHE		__pgprot(__PAGE_KERNEL_NOCACHE)
-#define PAGE_KERNEL_UC_MINUS		__pgprot(__PAGE_KERNEL_UC_MINUS)
-#define PAGE_KERNEL_EXEC_NOCACHE	__pgprot(__PAGE_KERNEL_EXEC_NOCACHE)
-#define PAGE_KERNEL_LARGE		__pgprot(__PAGE_KERNEL_LARGE)
-#define PAGE_KERNEL_LARGE_NOCACHE	__pgprot(__PAGE_KERNEL_LARGE_NOCACHE)
-#define PAGE_KERNEL_LARGE_EXEC		__pgprot(__PAGE_KERNEL_LARGE_EXEC)
-#define PAGE_KERNEL_VSYSCALL		__pgprot(__PAGE_KERNEL_VSYSCALL)
-#define PAGE_KERNEL_VSYSCALL_NOCACHE	__pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)
-
-#define PAGE_KERNEL_IO			__pgprot(__PAGE_KERNEL_IO)
-#define PAGE_KERNEL_IO_NOCACHE		__pgprot(__PAGE_KERNEL_IO_NOCACHE)
-#define PAGE_KERNEL_IO_UC_MINUS		__pgprot(__PAGE_KERNEL_IO_UC_MINUS)
-#define PAGE_KERNEL_IO_WC		__pgprot(__PAGE_KERNEL_IO_WC)
-
-/*         xwr */
-#define __P000	PAGE_NONE
-#define __P001	PAGE_READONLY
-#define __P010	PAGE_COPY
-#define __P011	PAGE_COPY
-#define __P100	PAGE_READONLY_EXEC
-#define __P101	PAGE_READONLY_EXEC
-#define __P110	PAGE_COPY_EXEC
-#define __P111	PAGE_COPY_EXEC
-
-#define __S000	PAGE_NONE
-#define __S001	PAGE_READONLY
-#define __S010	PAGE_SHARED
-#define __S011	PAGE_SHARED
-#define __S100	PAGE_READONLY_EXEC
-#define __S101	PAGE_READONLY_EXEC
-#define __S110	PAGE_SHARED_EXEC
-#define __S111	PAGE_SHARED_EXEC
+#include <asm/page.h>
 
-/*
- * early identity mapping  pte attrib macros.
- */
-#ifdef CONFIG_X86_64
-#define __PAGE_KERNEL_IDENT_LARGE_EXEC	__PAGE_KERNEL_LARGE_EXEC
-#else
-/*
- * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
- * bits are combined, this will alow user to access the high address mapped
- * VDSO in the presence of CONFIG_COMPAT_VDSO
- */
-#define PTE_IDENT_ATTR	 0x003		/* PRESENT+RW */
-#define PDE_IDENT_ATTR	 0x067		/* PRESENT+RW+USER+DIRTY+ACCESSED */
-#define PGD_IDENT_ATTR	 0x001		/* PRESENT (no other attributes) */
-#endif
+#include <asm/pgtable_types.h>
 
 /*
  * Macro to mark a page protection value as UC-
@@ -170,9 +15,6 @@
 
 #ifndef __ASSEMBLY__
 
-#define pgprot_writecombine	pgprot_writecombine
-extern pgprot_t pgprot_writecombine(pgprot_t prot);
-
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
@@ -183,6 +25,64 @@ extern unsigned long empty_zero_page[PAG
 extern spinlock_t pgd_lock;
 extern struct list_head pgd_list;
 
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else  /* !CONFIG_PARAVIRT */
+#define set_pte(ptep, pte)		native_set_pte(ptep, pte)
+#define set_pte_at(mm, addr, ptep, pte)	native_set_pte_at(mm, addr, ptep, pte)
+
+#define set_pte_atomic(ptep, pte)					\
+	native_set_pte_atomic(ptep, pte)
+
+#define set_pmd(pmdp, pmd)		native_set_pmd(pmdp, pmd)
+
+#ifndef __PAGETABLE_PUD_FOLDED
+#define set_pgd(pgdp, pgd)		native_set_pgd(pgdp, pgd)
+#define pgd_clear(pgd)			native_pgd_clear(pgd)
+#endif
+
+#ifndef set_pud
+# define set_pud(pudp, pud)		native_set_pud(pudp, pud)
+#endif
+
+#ifndef __PAGETABLE_PMD_FOLDED
+#define pud_clear(pud)			native_pud_clear(pud)
+#endif
+
+#define pte_clear(mm, addr, ptep)	native_pte_clear(mm, addr, ptep)
+#define pmd_clear(pmd)			native_pmd_clear(pmd)
+
+#define pte_update(mm, addr, ptep)              do { } while (0)
+#define pte_update_defer(mm, addr, ptep)        do { } while (0)
+
+static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
+{
+	native_pagetable_setup_start(base);
+}
+
+static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
+{
+	native_pagetable_setup_done(base);
+}
+
+#define pgd_val(x)	native_pgd_val(x)
+#define __pgd(x)	native_make_pgd(x)
+
+#ifndef __PAGETABLE_PUD_FOLDED
+#define pud_val(x)	native_pud_val(x)
+#define __pud(x)	native_make_pud(x)
+#endif
+
+#ifndef __PAGETABLE_PMD_FOLDED
+#define pmd_val(x)	native_pmd_val(x)
+#define __pmd(x)	native_make_pmd(x)
+#endif
+
+#define pte_val(x)	native_pte_val(x)
+#define __pte(x)	native_make_pte(x)
+
+#endif	/* CONFIG_PARAVIRT */
+
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -236,72 +136,84 @@ static inline unsigned long pte_pfn(pte_
 
 static inline int pmd_large(pmd_t pte)
 {
-	return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
+	return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
 		(_PAGE_PSE | _PAGE_PRESENT);
 }
 
+static inline pte_t pte_set_flags(pte_t pte, pteval_t set)
+{
+	pteval_t v = native_pte_val(pte);
+
+	return native_make_pte(v | set);
+}
+
+static inline pte_t pte_clear_flags(pte_t pte, pteval_t clear)
+{
+	pteval_t v = native_pte_val(pte);
+
+	return native_make_pte(v & ~clear);
+}
+
 static inline pte_t pte_mkclean(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_DIRTY);
+	return pte_clear_flags(pte, _PAGE_DIRTY);
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
+	return pte_clear_flags(pte, _PAGE_ACCESSED);
 }
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_RW);
+	return pte_clear_flags(pte, _PAGE_RW);
 }
 
 static inline pte_t pte_mkexec(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_NX);
+	return pte_clear_flags(pte, _PAGE_NX);
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_DIRTY);
+	return pte_set_flags(pte, _PAGE_DIRTY);
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_ACCESSED);
+	return pte_set_flags(pte, _PAGE_ACCESSED);
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_RW);
+	return pte_set_flags(pte, _PAGE_RW);
 }
 
 static inline pte_t pte_mkhuge(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_PSE);
+	return pte_set_flags(pte, _PAGE_PSE);
 }
 
 static inline pte_t pte_clrhuge(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_PSE);
+	return pte_clear_flags(pte, _PAGE_PSE);
 }
 
 static inline pte_t pte_mkglobal(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_GLOBAL);
+	return pte_set_flags(pte, _PAGE_GLOBAL);
 }
 
 static inline pte_t pte_clrglobal(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~_PAGE_GLOBAL);
+	return pte_clear_flags(pte, _PAGE_GLOBAL);
 }
 
 static inline pte_t pte_mkspecial(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_SPECIAL);
+	return pte_set_flags(pte, _PAGE_SPECIAL);
 }
 
-extern pteval_t __supported_pte_mask;
-
 /*
  * Mask out unsupported bits in a present pgprot.  Non-present pgprots
  * can use those bits for other purposes, so leave them be.
@@ -374,82 +286,197 @@ static inline int is_new_memtype_allowed
 	return 1;
 }
 
-#ifndef __ASSEMBLY__
-/* Indicate that x86 has its own track and untrack pfn vma functions */
-#define __HAVE_PFNMAP_TRACKING
-
-#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
-
-/* Install a pte for a particular vaddr in kernel space. */
-void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+pmd_t *populate_extra_pmd(unsigned long vaddr);
+pte_t *populate_extra_pte(unsigned long vaddr);
+#endif	/* __ASSEMBLY__ */
 
 #ifdef CONFIG_X86_32
-extern void native_pagetable_setup_start(pgd_t *base);
-extern void native_pagetable_setup_done(pgd_t *base);
+# include "pgtable_32.h"
 #else
-static inline void native_pagetable_setup_start(pgd_t *base) {}
-static inline void native_pagetable_setup_done(pgd_t *base) {}
+# include "pgtable_64.h"
 #endif
 
-struct seq_file;
-extern void arch_report_meminfo(struct seq_file *m);
+#ifndef __ASSEMBLY__
+#include <linux/mm_types.h>
 
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#else  /* !CONFIG_PARAVIRT */
-#define set_pte(ptep, pte)		native_set_pte(ptep, pte)
-#define set_pte_at(mm, addr, ptep, pte)	native_set_pte_at(mm, addr, ptep, pte)
+static inline int pte_none(pte_t pte)
+{
+	return !pte.pte;
+}
 
-#define set_pte_present(mm, addr, ptep, pte)				\
-	native_set_pte_present(mm, addr, ptep, pte)
-#define set_pte_atomic(ptep, pte)					\
-	native_set_pte_atomic(ptep, pte)
+#define __HAVE_ARCH_PTE_SAME
+static inline int pte_same(pte_t a, pte_t b)
+{
+	return a.pte == b.pte;
+}
 
-#define set_pmd(pmdp, pmd)		native_set_pmd(pmdp, pmd)
+static inline int pte_present(pte_t a)
+{
+	return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE);
+}
 
-#ifndef __PAGETABLE_PUD_FOLDED
-#define set_pgd(pgdp, pgd)		native_set_pgd(pgdp, pgd)
-#define pgd_clear(pgd)			native_pgd_clear(pgd)
-#endif
+static inline int pmd_present(pmd_t pmd)
+{
+	return pmd_flags(pmd) & _PAGE_PRESENT;
+}
 
-#ifndef set_pud
-# define set_pud(pudp, pud)		native_set_pud(pudp, pud)
-#endif
+static inline int pmd_none(pmd_t pmd)
+{
+	/* Only check low word on 32-bit platforms, since it might be
+	   out of sync with upper half. */
+	return (unsigned long)native_pmd_val(pmd) == 0;
+}
 
-#ifndef __PAGETABLE_PMD_FOLDED
-#define pud_clear(pud)			native_pud_clear(pud)
-#endif
+static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+{
+	return (unsigned long)__va(pmd_val(pmd) & PTE_PFN_MASK);
+}
 
-#define pte_clear(mm, addr, ptep)	native_pte_clear(mm, addr, ptep)
-#define pmd_clear(pmd)			native_pmd_clear(pmd)
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pmd_page(pmd)	pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
 
-#define pte_update(mm, addr, ptep)              do { } while (0)
-#define pte_update_defer(mm, addr, ptep)        do { } while (0)
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
+static inline unsigned pmd_index(unsigned long address)
+{
+	return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+}
 
-static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * (Currently stuck as a macro because of indirect forward reference
+ * to linux/mm.h:page_to_nid())
+ */
+#define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this function returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+static inline unsigned pte_index(unsigned long address)
 {
-	native_pagetable_setup_start(base);
+	return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
 }
 
-static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
+static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
 {
-	native_pagetable_setup_done(base);
+	return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
 }
-#endif	/* CONFIG_PARAVIRT */
 
-#endif	/* __ASSEMBLY__ */
+static inline int pmd_bad(pmd_t pmd)
+{
+	return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
+}
 
-#ifdef CONFIG_X86_32
-# include "pgtable_32.h"
+static inline unsigned long pages_to_mb(unsigned long npg)
+{
+	return npg >> (20 - PAGE_SHIFT);
+}
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
+	remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#if PAGETABLE_LEVELS > 2
+static inline int pud_none(pud_t pud)
+{
+	return native_pud_val(pud) == 0;
+}
+
+static inline int pud_present(pud_t pud)
+{
+	return pud_flags(pud) & _PAGE_PRESENT;
+}
+
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+	return (unsigned long)__va((unsigned long)pud_val(pud) & PTE_PFN_MASK);
+}
+
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pud_page(pud)		pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
+
+/* Find an entry in the second-level page table.. */
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+	return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
+}
+
+static inline int pud_large(pud_t pud)
+{
+	return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
+		(_PAGE_PSE | _PAGE_PRESENT);
+}
+
+static inline int pud_bad(pud_t pud)
+{
+	return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
+}
 #else
-# include "pgtable_64.h"
-#endif
+static inline int pud_large(pud_t pud)
+{
+	return 0;
+}
+#endif	/* PAGETABLE_LEVELS > 2 */
+
+#if PAGETABLE_LEVELS > 3
+static inline int pgd_present(pgd_t pgd)
+{
+	return pgd_flags(pgd) & _PAGE_PRESENT;
+}
+
+static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+{
+	return (unsigned long)__va((unsigned long)pgd_val(pgd) & PTE_PFN_MASK);
+}
+
+/*
+ * Currently stuck as a macro due to indirect forward reference to
+ * linux/mmzone.h's __section_mem_map_addr() definition:
+ */
+#define pgd_page(pgd)		pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
+
+/* to find an entry in a page-table-directory. */
+static inline unsigned pud_index(unsigned long address)
+{
+	return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
+}
+
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+{
+	return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address);
+}
+
+static inline int pgd_bad(pgd_t pgd)
+{
+	return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
+}
+
+static inline int pgd_none(pgd_t pgd)
+{
+	return !native_pgd_val(pgd);
+}
+#endif	/* PAGETABLE_LEVELS > 3 */
+
+#endif	/* __ASSEMBLY__ */
 
 /*
  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
@@ -476,28 +503,6 @@ static inline void __init paravirt_paget
 
 #ifndef __ASSEMBLY__
 
-enum {
-	PG_LEVEL_NONE,
-	PG_LEVEL_4K,
-	PG_LEVEL_2M,
-	PG_LEVEL_1G,
-	PG_LEVEL_NUM
-};
-
-#ifdef CONFIG_PROC_FS
-extern void update_page_count(int level, unsigned long pages);
-#else
-static inline void update_page_count(int level, unsigned long pages) { }
-#endif
-
-/*
- * Helper function that returns the kernel pagetable entry controlling
- * the virtual address 'address'. NULL means no pagetable entry present.
- * NOTE: the return type is pte_t but if the pmd is PSE then we return it
- * as a pte too.
- */
-extern pte_t *lookup_address(unsigned long address, unsigned int *level);
-
 /* local pte updates need not use xchg for locking */
 static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_types.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_types.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/pgtable_types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/pgtable_types.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,329 @@
+#ifndef _ASM_X86_PGTABLE_DEFS_H
+#define _ASM_X86_PGTABLE_DEFS_H
+
+#include <linux/const.h>
+#include <asm/page_types.h>
+
+#define FIRST_USER_ADDRESS	0
+
+#define _PAGE_BIT_PRESENT	0	/* is present */
+#define _PAGE_BIT_RW		1	/* writeable */
+#define _PAGE_BIT_USER		2	/* userspace addressable */
+#define _PAGE_BIT_PWT		3	/* page write through */
+#define _PAGE_BIT_PCD		4	/* page cache disabled */
+#define _PAGE_BIT_ACCESSED	5	/* was accessed (raised by CPU) */
+#define _PAGE_BIT_DIRTY		6	/* was written to (raised by CPU) */
+#define _PAGE_BIT_PSE		7	/* 4 MB (or 2MB) page */
+#define _PAGE_BIT_PAT		7	/* on 4KB pages */
+#define _PAGE_BIT_GLOBAL	8	/* Global TLB entry PPro+ */
+#define _PAGE_BIT_UNUSED1	9	/* available for programmer */
+#define _PAGE_BIT_IOMAP		10	/* flag used to indicate IO mapping */
+#define _PAGE_BIT_UNUSED3	11
+#define _PAGE_BIT_PAT_LARGE	12	/* On 2MB or 1GB pages */
+#define _PAGE_BIT_SPECIAL	_PAGE_BIT_UNUSED1
+#define _PAGE_BIT_CPA_TEST	_PAGE_BIT_UNUSED1
+#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
+
+/* If _PAGE_BIT_PRESENT is clear, we use these: */
+/* - if the user mapped it with PROT_NONE; pte_present gives true */
+#define _PAGE_BIT_PROTNONE	_PAGE_BIT_GLOBAL
+/* - set: nonlinear file mapping, saved PTE; unset:swap */
+#define _PAGE_BIT_FILE		_PAGE_BIT_DIRTY
+
+#define _PAGE_PRESENT	(_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
+#define _PAGE_RW	(_AT(pteval_t, 1) << _PAGE_BIT_RW)
+#define _PAGE_USER	(_AT(pteval_t, 1) << _PAGE_BIT_USER)
+#define _PAGE_PWT	(_AT(pteval_t, 1) << _PAGE_BIT_PWT)
+#define _PAGE_PCD	(_AT(pteval_t, 1) << _PAGE_BIT_PCD)
+#define _PAGE_ACCESSED	(_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
+#define _PAGE_DIRTY	(_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
+#define _PAGE_PSE	(_AT(pteval_t, 1) << _PAGE_BIT_PSE)
+#define _PAGE_GLOBAL	(_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
+#define _PAGE_UNUSED1	(_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
+#define _PAGE_IOMAP	(_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
+#define _PAGE_UNUSED3	(_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
+#define _PAGE_PAT	(_AT(pteval_t, 1) << _PAGE_BIT_PAT)
+#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
+#define _PAGE_SPECIAL	(_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
+#define _PAGE_CPA_TEST	(_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
+#define __HAVE_ARCH_PTE_SPECIAL
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+#define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
+#else
+#define _PAGE_NX	(_AT(pteval_t, 0))
+#endif
+
+#define _PAGE_FILE	(_AT(pteval_t, 1) << _PAGE_BIT_FILE)
+#define _PAGE_PROTNONE	(_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
+
+#define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |	\
+			 _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED |	\
+			 _PAGE_DIRTY)
+
+/* Set of bits not changed in pte_modify */
+#define _PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |		\
+			 _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define _PAGE_CACHE_MASK	(_PAGE_PCD | _PAGE_PWT)
+#define _PAGE_CACHE_WB		(0)
+#define _PAGE_CACHE_WC		(_PAGE_PWT)
+#define _PAGE_CACHE_UC_MINUS	(_PAGE_PCD)
+#define _PAGE_CACHE_UC		(_PAGE_PCD | _PAGE_PWT)
+
+#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
+				 _PAGE_ACCESSED | _PAGE_NX)
+
+#define PAGE_SHARED_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_RW |	\
+					 _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_COPY_NOEXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+					 _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_COPY_EXEC		__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+					 _PAGE_ACCESSED)
+#define PAGE_COPY		PAGE_COPY_NOEXEC
+#define PAGE_READONLY		__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+					 _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+					 _PAGE_ACCESSED)
+
+#define __PAGE_KERNEL_EXEC						\
+	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
+#define __PAGE_KERNEL		(__PAGE_KERNEL_EXEC | _PAGE_NX)
+
+#define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)
+#define __PAGE_KERNEL_RX		(__PAGE_KERNEL_EXEC & ~_PAGE_RW)
+#define __PAGE_KERNEL_EXEC_NOCACHE	(__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
+#define __PAGE_KERNEL_WC		(__PAGE_KERNEL | _PAGE_CACHE_WC)
+#define __PAGE_KERNEL_NOCACHE		(__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
+#define __PAGE_KERNEL_UC_MINUS		(__PAGE_KERNEL | _PAGE_PCD)
+#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)
+#define __PAGE_KERNEL_VSYSCALL_NOCACHE	(__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
+#define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)
+#define __PAGE_KERNEL_LARGE_NOCACHE	(__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
+#define __PAGE_KERNEL_LARGE_EXEC	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
+
+#define __PAGE_KERNEL_IO		(__PAGE_KERNEL | _PAGE_IOMAP)
+#define __PAGE_KERNEL_IO_NOCACHE	(__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP)
+#define __PAGE_KERNEL_IO_UC_MINUS	(__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP)
+#define __PAGE_KERNEL_IO_WC		(__PAGE_KERNEL_WC | _PAGE_IOMAP)
+
+#define PAGE_KERNEL			__pgprot(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO			__pgprot(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_EXEC		__pgprot(__PAGE_KERNEL_EXEC)
+#define PAGE_KERNEL_RX			__pgprot(__PAGE_KERNEL_RX)
+#define PAGE_KERNEL_WC			__pgprot(__PAGE_KERNEL_WC)
+#define PAGE_KERNEL_NOCACHE		__pgprot(__PAGE_KERNEL_NOCACHE)
+#define PAGE_KERNEL_UC_MINUS		__pgprot(__PAGE_KERNEL_UC_MINUS)
+#define PAGE_KERNEL_EXEC_NOCACHE	__pgprot(__PAGE_KERNEL_EXEC_NOCACHE)
+#define PAGE_KERNEL_LARGE		__pgprot(__PAGE_KERNEL_LARGE)
+#define PAGE_KERNEL_LARGE_NOCACHE	__pgprot(__PAGE_KERNEL_LARGE_NOCACHE)
+#define PAGE_KERNEL_LARGE_EXEC		__pgprot(__PAGE_KERNEL_LARGE_EXEC)
+#define PAGE_KERNEL_VSYSCALL		__pgprot(__PAGE_KERNEL_VSYSCALL)
+#define PAGE_KERNEL_VSYSCALL_NOCACHE	__pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)
+
+#define PAGE_KERNEL_IO			__pgprot(__PAGE_KERNEL_IO)
+#define PAGE_KERNEL_IO_NOCACHE		__pgprot(__PAGE_KERNEL_IO_NOCACHE)
+#define PAGE_KERNEL_IO_UC_MINUS		__pgprot(__PAGE_KERNEL_IO_UC_MINUS)
+#define PAGE_KERNEL_IO_WC		__pgprot(__PAGE_KERNEL_IO_WC)
+
+/*         xwr */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY_EXEC
+#define __P101	PAGE_READONLY_EXEC
+#define __P110	PAGE_COPY_EXEC
+#define __P111	PAGE_COPY_EXEC
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY_EXEC
+#define __S101	PAGE_READONLY_EXEC
+#define __S110	PAGE_SHARED_EXEC
+#define __S111	PAGE_SHARED_EXEC
+
+/*
+ * early identity mapping  pte attrib macros.
+ */
+#ifdef CONFIG_X86_64
+#define __PAGE_KERNEL_IDENT_LARGE_EXEC	__PAGE_KERNEL_LARGE_EXEC
+#else
+/*
+ * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
+ * bits are combined, this will alow user to access the high address mapped
+ * VDSO in the presence of CONFIG_COMPAT_VDSO
+ */
+#define PTE_IDENT_ATTR	 0x003		/* PRESENT+RW */
+#define PDE_IDENT_ATTR	 0x067		/* PRESENT+RW+USER+DIRTY+ACCESSED */
+#define PGD_IDENT_ATTR	 0x001		/* PRESENT (no other attributes) */
+#endif
+
+#ifdef CONFIG_X86_32
+# include "pgtable_32_types.h"
+#else
+# include "pgtable_64_types.h"
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
+#define PTE_PFN_MASK		((pteval_t)PHYSICAL_PAGE_MASK)
+
+/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
+#define PTE_FLAGS_MASK		(~PTE_PFN_MASK)
+
+typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
+
+typedef struct { pgdval_t pgd; } pgd_t;
+
+static inline pgd_t native_make_pgd(pgdval_t val)
+{
+	return (pgd_t) { val };
+}
+
+static inline pgdval_t native_pgd_val(pgd_t pgd)
+{
+	return pgd.pgd;
+}
+
+static inline pgdval_t pgd_flags(pgd_t pgd)
+{
+	return native_pgd_val(pgd) & PTE_FLAGS_MASK;
+}
+
+#if PAGETABLE_LEVELS > 3
+typedef struct { pudval_t pud; } pud_t;
+
+static inline pud_t native_make_pud(pmdval_t val)
+{
+	return (pud_t) { val };
+}
+
+static inline pudval_t native_pud_val(pud_t pud)
+{
+	return pud.pud;
+}
+#else
+#include <asm-generic/pgtable-nopud.h>
+
+static inline pudval_t native_pud_val(pud_t pud)
+{
+	return native_pgd_val(pud.pgd);
+}
+#endif
+
+#if PAGETABLE_LEVELS > 2
+typedef struct { pmdval_t pmd; } pmd_t;
+
+static inline pmd_t native_make_pmd(pmdval_t val)
+{
+	return (pmd_t) { val };
+}
+
+static inline pmdval_t native_pmd_val(pmd_t pmd)
+{
+	return pmd.pmd;
+}
+#else
+#include <asm-generic/pgtable-nopmd.h>
+
+static inline pmdval_t native_pmd_val(pmd_t pmd)
+{
+	return native_pgd_val(pmd.pud.pgd);
+}
+#endif
+
+static inline pudval_t pud_flags(pud_t pud)
+{
+	return native_pud_val(pud) & PTE_FLAGS_MASK;
+}
+
+static inline pmdval_t pmd_flags(pmd_t pmd)
+{
+	return native_pmd_val(pmd) & PTE_FLAGS_MASK;
+}
+
+static inline pte_t native_make_pte(pteval_t val)
+{
+	return (pte_t) { .pte = val };
+}
+
+static inline pteval_t native_pte_val(pte_t pte)
+{
+	return pte.pte;
+}
+
+static inline pteval_t pte_flags(pte_t pte)
+{
+	return native_pte_val(pte) & PTE_FLAGS_MASK;
+}
+
+#define pgprot_val(x)	((x).pgprot)
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+
+typedef struct page *pgtable_t;
+
+extern pteval_t __supported_pte_mask;
+extern int nx_enabled;
+extern void set_nx(void);
+
+#define pgprot_writecombine	pgprot_writecombine
+extern pgprot_t pgprot_writecombine(pgprot_t prot);
+
+/* Indicate that x86 has its own track and untrack pfn vma functions */
+#define __HAVE_PFNMAP_TRACKING
+
+#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);
+
+/* Install a pte for a particular vaddr in kernel space. */
+void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+
+#ifdef CONFIG_X86_32
+extern void native_pagetable_setup_start(pgd_t *base);
+extern void native_pagetable_setup_done(pgd_t *base);
+#else
+static inline void native_pagetable_setup_start(pgd_t *base) {}
+static inline void native_pagetable_setup_done(pgd_t *base) {}
+#endif
+
+struct seq_file;
+extern void arch_report_meminfo(struct seq_file *m);
+
+enum {
+	PG_LEVEL_NONE,
+	PG_LEVEL_4K,
+	PG_LEVEL_2M,
+	PG_LEVEL_1G,
+	PG_LEVEL_NUM
+};
+
+#ifdef CONFIG_PROC_FS
+extern void update_page_count(int level, unsigned long pages);
+#else
+static inline void update_page_count(int level, unsigned long pages) { }
+#endif
+
+/*
+ * Helper function that returns the kernel pagetable entry controlling
+ * the virtual address 'address'. NULL means no pagetable entry present.
+ * NOTE: the return type is pte_t but if the pmd is PSE then we return it
+ * as a pte too.
+ */
+extern pte_t *lookup_address(unsigned long address, unsigned int *level);
+
+#endif	/* !__ASSEMBLY__ */
+
+#endif /* _ASM_X86_PGTABLE_DEFS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/prctl.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/prctl.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/prctl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/prctl.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,8 +6,4 @@
 #define ARCH_GET_FS 0x1003
 #define ARCH_GET_GS 0x1004
 
-#ifdef CONFIG_X86_64
-extern long sys_arch_prctl(int, unsigned long);
-#endif /* CONFIG_X86_64 */
-
 #endif /* _ASM_X86_PRCTL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/processor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@ struct mm_struct;
 #include <asm/cpufeature.h>
 #include <asm/system.h>
 #include <asm/page.h>
+#include <asm/pgtable_types.h>
 #include <asm/percpu.h>
 #include <asm/msr.h>
 #include <asm/desc_defs.h>
@@ -73,10 +74,10 @@ struct cpuinfo_x86 {
 	char			pad0;
 #else
 	/* Number of 4K pages in DTLB/ITLB combined(in pages): */
-	int			 x86_tlbsize;
+	int			x86_tlbsize;
+#endif
 	__u8			x86_virt_bits;
 	__u8			x86_phys_bits;
-#endif
 	/* CPUID returned core id bits: */
 	__u8			x86_coreid_bits;
 	/* Max extended CPUID function supported: */
@@ -93,7 +94,7 @@ struct cpuinfo_x86 {
 	unsigned long		loops_per_jiffy;
 #ifdef CONFIG_SMP
 	/* cpus sharing the last level cache: */
-	cpumask_t		llc_shared_map;
+	cpumask_var_t		llc_shared_map;
 #endif
 	/* cpuid returned max cores value: */
 	u16			 x86_max_cores;
@@ -137,7 +138,7 @@ extern struct tss_struct	doublefault_tss
 extern __u32			cleared_cpu_caps[NCAPINTS];
 
 #ifdef CONFIG_SMP
-DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 #define cpu_data(cpu)		per_cpu(cpu_info, cpu)
 #define current_cpu_data	__get_cpu_var(cpu_info)
 #else
@@ -247,7 +248,6 @@ struct x86_hw_tss {
 #define IO_BITMAP_LONGS			(IO_BITMAP_BYTES/sizeof(long))
 #define IO_BITMAP_OFFSET		offsetof(struct tss_struct, io_bitmap)
 #define INVALID_IO_BITMAP_OFFSET	0x8000
-#define INVALID_IO_BITMAP_OFFSET_LAZY	0x9000
 
 struct tss_struct {
 	/*
@@ -262,11 +262,6 @@ struct tss_struct {
 	 * be within the limit.
 	 */
 	unsigned long		io_bitmap[IO_BITMAP_LONGS + 1];
-	/*
-	 * Cache the current maximum and the last task that used the bitmap:
-	 */
-	unsigned long		io_bitmap_max;
-	struct thread_struct	*io_bitmap_owner;
 
 	/*
 	 * .. and then another 0x100 bytes for the emergency kernel stack:
@@ -275,7 +270,7 @@ struct tss_struct {
 
 } ____cacheline_aligned;
 
-DECLARE_PER_CPU(struct tss_struct, init_tss);
+DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
 
 /*
  * Save the original ist values for checking stack pointers during debugging
@@ -357,6 +352,11 @@ struct i387_soft_struct {
 	u32			entry_eip;
 };
 
+struct ymmh_struct {
+	/* 16 * 16 bytes for each YMMH-reg = 256 bytes */
+	u32 ymmh_space[64];
+};
+
 struct xsave_hdr_struct {
 	u64 xstate_bv;
 	u64 reserved1[2];
@@ -366,6 +366,7 @@ struct xsave_hdr_struct {
 struct xsave_struct {
 	struct i387_fxsave_struct i387;
 	struct xsave_hdr_struct xsave_hdr;
+	struct ymmh_struct ymmh;
 	/* new processor state extensions will go here */
 } __attribute__ ((packed, aligned (64)));
 
@@ -378,9 +379,33 @@ union thread_xstate {
 
 #ifdef CONFIG_X86_64
 DECLARE_PER_CPU(struct orig_ist, orig_ist);
+
+union irq_stack_union {
+	char irq_stack[IRQ_STACK_SIZE];
+	/*
+	 * GCC hardcodes the stack canary as %gs:40.  Since the
+	 * irq_stack is the object at %gs:0, we reserve the bottom
+	 * 48 bytes of the irq stack for the canary.
+	 */
+	struct {
+		char gs_base[40];
+		unsigned long stack_canary;
+	};
+};
+
+DECLARE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union);
+DECLARE_INIT_PER_CPU(irq_stack_union);
+
+DECLARE_PER_CPU(char *, irq_stack_ptr);
+DECLARE_PER_CPU(unsigned int, irq_count);
+extern unsigned long kernel_eflags;
+extern asmlinkage void ignore_sysret(void);
+#else	/* X86_64 */
+#ifdef CONFIG_CC_STACKPROTECTOR
+DECLARE_PER_CPU(unsigned long, stack_canary);
 #endif
+#endif	/* X86_64 */
 
-extern void print_cpu_info(struct cpuinfo_x86 *);
 extern unsigned int xstate_size;
 extern void free_thread_xstate(struct task_struct *);
 extern struct kmem_cache *task_xstate_cachep;
@@ -717,6 +742,7 @@ static inline void __sti_mwait(unsigned
 extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void init_c1e_mask(void);
 
 extern unsigned long		boot_option_idle_override;
 extern unsigned long		idle_halt;
@@ -752,9 +778,9 @@ extern int sysenter_setup(void);
 extern struct desc_ptr		early_gdt_descr;
 
 extern void cpu_set_gdt(int);
-extern void switch_to_new_gdt(void);
+extern void switch_to_new_gdt(int);
+extern void load_percpu_segment(int);
 extern void cpu_init(void);
-extern void init_gdt(int cpu);
 
 static inline unsigned long get_debugctlmsr(void)
 {
@@ -839,6 +865,7 @@ static inline void spin_lock_prefetch(co
  * User space process size: 3GB (default).
  */
 #define TASK_SIZE		PAGE_OFFSET
+#define TASK_SIZE_MAX		TASK_SIZE
 #define STACK_TOP		TASK_SIZE
 #define STACK_TOP_MAX		STACK_TOP
 
@@ -898,7 +925,7 @@ extern unsigned long thread_saved_pc(str
 /*
  * User space process size. 47bits minus one guard page.
  */
-#define TASK_SIZE64	((1UL << 47) - PAGE_SIZE)
+#define TASK_SIZE_MAX	((1UL << 47) - PAGE_SIZE)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
@@ -907,12 +934,12 @@ extern unsigned long thread_saved_pc(str
 					0xc0000000 : 0xFFFFe000)
 
 #define TASK_SIZE		(test_thread_flag(TIF_IA32) ? \
-					IA32_PAGE_OFFSET : TASK_SIZE64)
+					IA32_PAGE_OFFSET : TASK_SIZE_MAX)
 #define TASK_SIZE_OF(child)	((test_tsk_thread_flag(child, TIF_IA32)) ? \
-					IA32_PAGE_OFFSET : TASK_SIZE64)
+					IA32_PAGE_OFFSET : TASK_SIZE_MAX)
 
 #define STACK_TOP		TASK_SIZE
-#define STACK_TOP_MAX		TASK_SIZE64
+#define STACK_TOP_MAX		TASK_SIZE_MAX
 
 #define INIT_THREAD  { \
 	.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/proto.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/proto.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/proto.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/proto.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,11 +18,7 @@ extern void syscall32_cpu_init(void);
 
 extern void check_efer(void);
 
-#ifdef CONFIG_X86_BIOS_REBOOT
 extern int reboot_force;
-#else
-static const int reboot_force = 0;
-#endif
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/ptrace-abi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/ptrace-abi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/ptrace-abi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/ptrace-abi.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,8 +80,6 @@
 
 #define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
 
-#ifdef CONFIG_X86_PTRACE_BTS
-
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 
@@ -140,6 +138,5 @@ struct ptrace_bts_config {
    BTS records are read from oldest to newest.
    Returns number of BTS records drained.
 */
-#endif /* CONFIG_X86_PTRACE_BTS */
 
 #endif /* _ASM_X86_PTRACE_ABI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/ptrace.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/ptrace.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/ptrace.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/ptrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ struct pt_regs {
 	int  xds;
 	int  xes;
 	int  xfs;
-	/* int  gs; */
+	int  xgs;
 	long orig_eax;
 	long eip;
 	int  xcs;
@@ -50,7 +50,7 @@ struct pt_regs {
 	unsigned long ds;
 	unsigned long es;
 	unsigned long fs;
-	/* int  gs; */
+	unsigned long gs;
 	unsigned long orig_ax;
 	unsigned long ip;
 	unsigned long cs;
@@ -187,14 +187,15 @@ static inline int v8086_mode(struct pt_r
 
 /*
  * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
- * when it traps.  So regs will be the current sp.
+ * when it traps.  The previous stack will be directly underneath the saved
+ * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
  *
  * This is valid only for kernel mode traps.
  */
-static inline unsigned long kernel_trap_sp(struct pt_regs *regs)
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 {
 #ifdef CONFIG_X86_32
-	return (unsigned long)regs;
+	return (unsigned long)(&regs->sp);
 #else
 	return regs->sp;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/rdc321x_defs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/rdc321x_defs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/rdc321x_defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/rdc321x_defs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#define PFX	"rdc321x: "
+
+/* General purpose configuration and data registers */
+#define RDC3210_CFGREG_ADDR     0x0CF8
+#define RDC3210_CFGREG_DATA     0x0CFC
+
+#define RDC321X_GPIO_CTRL_REG1	0x48
+#define RDC321X_GPIO_CTRL_REG2	0x84
+#define RDC321X_GPIO_DATA_REG1	0x4c
+#define RDC321X_GPIO_DATA_REG2	0x88
+
+#define RDC321X_MAX_GPIO	58
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/required-features.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/required-features.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/required-features.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/required-features.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@
 #ifdef CONFIG_X86_64
 #define NEED_PSE	0
 #define NEED_MSR	(1<<(X86_FEATURE_MSR & 31))
-#define NEED_PGE	(1<<(X86_FEATURE_PGE & 31))
+#define NEED_PGE	0
 #define NEED_FXSR	(1<<(X86_FEATURE_FXSR & 31))
 #define NEED_XMM	(1<<(X86_FEATURE_XMM & 31))
 #define NEED_XMM2	(1<<(X86_FEATURE_XMM2 & 31))
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/sections.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/sections.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/sections.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/sections.h	2009-06-09 23:05:27.000000000 -0400
@@ -1 +1,8 @@
+#ifndef _ASM_X86_SECTIONS_H
+#define _ASM_X86_SECTIONS_H
+
 #include <asm-generic/sections.h>
+
+extern char __brk_base[], __brk_limit[];
+
+#endif	/* _ASM_X86_SECTIONS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/segment.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/segment.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/segment.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/segment.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,7 @@
  *
  *  26 - ESPFIX small SS
  *  27 - per-cpu			[ offset to per-cpu data area ]
- *  28 - unused
+ *  28 - stack_canary-20		[ for stack protector ]
  *  29 - unused
  *  30 - unused
  *  31 - TSS for double fault handler
@@ -95,6 +95,13 @@
 #define __KERNEL_PERCPU 0
 #endif
 
+#define GDT_ENTRY_STACK_CANARY		(GDT_ENTRY_KERNEL_BASE + 16)
+#ifdef CONFIG_CC_STACKPROTECTOR
+#define __KERNEL_STACK_CANARY		(GDT_ENTRY_STACK_CANARY * 8)
+#else
+#define __KERNEL_STACK_CANARY		0
+#endif
+
 #define GDT_ENTRY_DOUBLEFAULT_TSS	31
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/setup_arch.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/setup_arch.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/setup_arch.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/setup_arch.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+/* Hook to call BIOS initialisation function */
+
+/* no action for generic */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/setup.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/setup.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/setup.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/setup.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,33 +1,19 @@
 #ifndef _ASM_X86_SETUP_H
 #define _ASM_X86_SETUP_H
 
+#ifdef __KERNEL__
+
 #define COMMAND_LINE_SIZE 2048
 
 #ifndef __ASSEMBLY__
 
-/* Interrupt control for vSMPowered x86_64 systems */
-void vsmp_init(void);
-
-
-void setup_bios_corruption_check(void);
-
-
-#ifdef CONFIG_X86_VISWS
-extern void visws_early_detect(void);
-extern int is_visws_box(void);
-#else
-static inline void visws_early_detect(void) { }
-static inline int is_visws_box(void) { return 0; }
-#endif
-
-extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
-extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
 /*
  * Any setup quirks to be performed?
  */
 struct mpc_cpu;
 struct mpc_bus;
 struct mpc_oemtable;
+
 struct x86_quirks {
 	int (*arch_pre_time_init)(void);
 	int (*arch_time_init)(void);
@@ -43,20 +29,19 @@ struct x86_quirks {
 	void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
 	void (*mpc_oem_pci_bus)(struct mpc_bus *m);
 	void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
-                                    unsigned short oemsize);
+				unsigned short oemsize);
 	int (*setup_ioapic_ids)(void);
-	int (*update_genapic)(void);
 };
 
-extern struct x86_quirks *x86_quirks;
-extern unsigned long saved_video_mode;
+extern void x86_quirk_pre_intr_init(void);
+extern void x86_quirk_intr_init(void);
 
-#ifndef CONFIG_PARAVIRT
-#define paravirt_post_allocator_init()	do {} while (0)
-#endif
-#endif /* __ASSEMBLY__ */
+extern void x86_quirk_trap_init(void);
 
-#ifdef __KERNEL__
+extern void x86_quirk_pre_time_init(void);
+extern void x86_quirk_time_init(void);
+
+#endif /* __ASSEMBLY__ */
 
 #ifdef __i386__
 
@@ -78,6 +63,30 @@ extern unsigned long saved_video_mode;
 #ifndef __ASSEMBLY__
 #include <asm/bootparam.h>
 
+/* Interrupt control for vSMPowered x86_64 systems */
+#ifdef CONFIG_X86_64
+void vsmp_init(void);
+#else
+static inline void vsmp_init(void) { }
+#endif
+
+void setup_bios_corruption_check(void);
+
+#ifdef CONFIG_X86_VISWS
+extern void visws_early_detect(void);
+extern int is_visws_box(void);
+#else
+static inline void visws_early_detect(void) { }
+static inline int is_visws_box(void) { return 0; }
+#endif
+
+extern struct x86_quirks *x86_quirks;
+extern unsigned long saved_video_mode;
+
+#ifndef CONFIG_PARAVIRT
+#define paravirt_post_allocator_init()	do {} while (0)
+#endif
+
 #ifndef _SETUP
 
 /*
@@ -91,21 +100,51 @@ extern struct boot_params boot_params;
  */
 #define LOWMEMSIZE()	(0x9f000)
 
+/* exceedingly early brk-like allocator */
+extern unsigned long _brk_end;
+void *extend_brk(size_t size, size_t align);
+
+/*
+ * Reserve space in the brk section.  The name must be unique within
+ * the file, and somewhat descriptive.  The size is in bytes.  Must be
+ * used at file scope.
+ *
+ * (This uses a temp function to wrap the asm so we can pass it the
+ * size parameter; otherwise we wouldn't be able to.  We can't use a
+ * "section" attribute on a normal variable because it always ends up
+ * being @progbits, which ends up allocating space in the vmlinux
+ * executable.)
+ */
+#define RESERVE_BRK(name,sz)						\
+	static void __section(.discard) __used				\
+	__brk_reservation_fn_##name##__(void) {				\
+		asm volatile (						\
+			".pushsection .brk_reservation,\"aw\",@nobits;" \
+			".brk." #name ":"				\
+			" 1:.skip %c0;"					\
+			" .size .brk." #name ", . - 1b;"		\
+			" .popsection"					\
+			: : "i" (sz));					\
+	}
+
 #ifdef __i386__
 
 void __init i386_start_kernel(void);
 extern void probe_roms(void);
 
-extern unsigned long init_pg_tables_start;
-extern unsigned long init_pg_tables_end;
-
 #else
-void __init x86_64_init_pda(void);
 void __init x86_64_start_kernel(char *real_mode);
 void __init x86_64_start_reservations(char *real_mode_data);
 
 #endif /* __i386__ */
 #endif /* _SETUP */
+#else
+#define RESERVE_BRK(name,sz)				\
+	.pushsection .brk_reservation,"aw",@nobits;	\
+.brk.name:						\
+1:	.skip sz;					\
+	.size .brk.name,.-1b;				\
+	.popsection
 #endif /* __ASSEMBLY__ */
 #endif  /*  __KERNEL__  */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/sigcontext.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/sigcontext.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/sigcontext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/sigcontext.h	2009-06-09 23:05:27.000000000 -0400
@@ -269,6 +269,11 @@ struct _xsave_hdr {
 	__u64 reserved2[5];
 };
 
+struct _ymmh_state {
+	/* 16 * 16 bytes for each YMMH-reg */
+	__u32 ymmh_space[64];
+};
+
 /*
  * Extended state pointed by the fpstate pointer in the sigcontext.
  * In addition to the fpstate, information encoded in the xstate_hdr
@@ -278,6 +283,7 @@ struct _xsave_hdr {
 struct _xstate {
 	struct _fpstate fpstate;
 	struct _xsave_hdr xstate_hdr;
+	struct _ymmh_state ymmh;
 	/* new processor state extensions go here */
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/smpboot_hooks.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/smpboot_hooks.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/smpboot_hooks.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/smpboot_hooks.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,61 @@
+/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
+ * which needs to alter them. */
+
+static inline void smpboot_clear_io_apic_irqs(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	io_apic_irqs = 0;
+#endif
+}
+
+static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
+{
+	CMOS_WRITE(0xa, 0xf);
+	local_flush_tlb();
+	pr_debug("1.\n");
+	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) =
+								 start_eip >> 4;
+	pr_debug("2.\n");
+	*((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_low)) =
+							 start_eip & 0xf;
+	pr_debug("3.\n");
+}
+
+static inline void smpboot_restore_warm_reset_vector(void)
+{
+	/*
+	 * Install writable page 0 entry to set BIOS data area.
+	 */
+	local_flush_tlb();
+
+	/*
+	 * Paranoid:  Set warm reset code and vector here back
+	 * to default values.
+	 */
+	CMOS_WRITE(0, 0xf);
+
+	*((volatile long *)phys_to_virt(apic->trampoline_phys_low)) = 0;
+}
+
+static inline void __init smpboot_setup_io_apic(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	/*
+	 * Here we can be sure that there is an IO-APIC in the system. Let's
+	 * go and set it up:
+	 */
+	if (!skip_ioapic_setup && nr_ioapics)
+		setup_IO_APIC();
+	else {
+		nr_ioapics = 0;
+		localise_nmi_watchdog();
+	}
+#endif
+}
+
+static inline void smpboot_clear_io_apic(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	nr_ioapics = 0;
+#endif
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/smp.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/smp.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/smp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/smp.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,53 +15,25 @@
 #  include <asm/io_apic.h>
 # endif
 #endif
-#include <asm/pda.h>
 #include <asm/thread_info.h>
-
-#ifdef CONFIG_X86_64
-
-extern cpumask_var_t cpu_callin_mask;
-extern cpumask_var_t cpu_callout_mask;
-extern cpumask_var_t cpu_initialized_mask;
-extern cpumask_var_t cpu_sibling_setup_mask;
-
-#else /* CONFIG_X86_32 */
-
-extern cpumask_t cpu_callin_map;
-extern cpumask_t cpu_callout_map;
-extern cpumask_t cpu_initialized;
-extern cpumask_t cpu_sibling_setup_map;
-
-#define cpu_callin_mask		((struct cpumask *)&cpu_callin_map)
-#define cpu_callout_mask	((struct cpumask *)&cpu_callout_map)
-#define cpu_initialized_mask	((struct cpumask *)&cpu_initialized)
-#define cpu_sibling_setup_mask	((struct cpumask *)&cpu_sibling_setup_map)
-
-#endif /* CONFIG_X86_32 */
-
-extern void (*mtrr_hook)(void);
-extern void zap_low_mappings(void);
-
-extern int __cpuinit get_local_pda(int cpu);
+#include <asm/cpumask.h>
 
 extern int smp_num_siblings;
 extern unsigned int num_processors;
 
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
 DECLARE_PER_CPU(u16, cpu_llc_id);
-#ifdef CONFIG_X86_32
 DECLARE_PER_CPU(int, cpu_number);
-#endif
 
 static inline struct cpumask *cpu_sibling_mask(int cpu)
 {
-	return &per_cpu(cpu_sibling_map, cpu);
+	return per_cpu(cpu_sibling_map, cpu);
 }
 
 static inline struct cpumask *cpu_core_mask(int cpu)
 {
-	return &per_cpu(cpu_core_map, cpu);
+	return per_cpu(cpu_core_map, cpu);
 }
 
 DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
@@ -149,9 +121,10 @@ static inline void arch_send_call_functi
 	smp_ops.send_call_func_single_ipi(cpu);
 }
 
-static inline void arch_send_call_function_ipi(cpumask_t mask)
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
+static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
-	smp_ops.send_call_func_ipi(&mask);
+	smp_ops.send_call_func_ipi(mask);
 }
 
 void cpu_disable_common(void);
@@ -167,8 +140,6 @@ void play_dead_common(void);
 void native_send_call_func_ipi(const struct cpumask *mask);
 void native_send_call_func_single_ipi(int cpu);
 
-extern void prefill_possible_map(void);
-
 void smp_store_cpu_info(int id);
 #define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
 
@@ -177,10 +148,6 @@ static inline int num_booting_cpus(void)
 {
 	return cpumask_weight(cpu_callout_mask);
 }
-#else
-static inline void prefill_possible_map(void)
-{
-}
 #endif /* CONFIG_SMP */
 
 extern unsigned disabled_cpus __cpuinitdata;
@@ -191,11 +158,11 @@ extern unsigned disabled_cpus __cpuinitd
  * from the initial startup. We map APIC_BASE very early in page_setup(),
  * so this is correct in the x86 case.
  */
-#define raw_smp_processor_id() (x86_read_percpu(cpu_number))
+#define raw_smp_processor_id() (percpu_read(cpu_number))
 extern int safe_smp_processor_id(void);
 
 #elif defined(CONFIG_X86_64_SMP)
-#define raw_smp_processor_id()	read_pda(cpunumber)
+#define raw_smp_processor_id() (percpu_read(cpu_number))
 
 #define stack_smp_processor_id()					\
 ({								\
@@ -205,10 +172,6 @@ extern int safe_smp_processor_id(void);
 })
 #define safe_smp_processor_id()		smp_processor_id()
 
-#else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */
-#define cpu_physical_id(cpu)		boot_cpu_physical_apicid
-#define safe_smp_processor_id()		0
-#define stack_smp_processor_id() 	0
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -220,28 +183,9 @@ static inline int logical_smp_processor_
 	return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR));
 }
 
-#include <mach_apicdef.h>
-static inline unsigned int read_apic_id(void)
-{
-	unsigned int reg;
-
-	reg = *(u32 *)(APIC_BASE + APIC_ID);
-
-	return GET_APIC_ID(reg);
-}
 #endif
 
-
-# if defined(APIC_DEFINITION) || defined(CONFIG_X86_64)
 extern int hard_smp_processor_id(void);
-# else
-#include <mach_apicdef.h>
-static inline int hard_smp_processor_id(void)
-{
-	/* we don't want to mark this access volatile - bad code generation */
-	return read_apic_id();
-}
-# endif /* APIC_DEFINITION */
 
 #else /* CONFIG_X86_LOCAL_APIC */
 
@@ -251,11 +195,5 @@ static inline int hard_smp_processor_id(
 
 #endif /* CONFIG_X86_LOCAL_APIC */
 
-#ifdef CONFIG_X86_HAS_BOOT_CPU_ID
-extern unsigned char boot_cpu_id;
-#else
-#define boot_cpu_id	0
-#endif
-
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_SMP_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,4 +54,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif /* _ASM_X86_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/spinlock.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/spinlock.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/spinlock.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/spinlock.h	2009-06-09 23:05:27.000000000 -0400
@@ -172,70 +172,8 @@ static inline int __ticket_spin_is_conte
 	return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
 }
 
-#ifdef CONFIG_PARAVIRT
-/*
- * Define virtualization-friendly old-style lock byte lock, for use in
- * pv_lock_ops if desired.
- *
- * This differs from the pre-2.6.24 spinlock by always using xchgb
- * rather than decb to take the lock; this allows it to use a
- * zero-initialized lock structure.  It also maintains a 1-byte
- * contention counter, so that we can implement
- * __byte_spin_is_contended.
- */
-struct __byte_spinlock {
-	s8 lock;
-	s8 spinners;
-};
-
-static inline int __byte_spin_is_locked(raw_spinlock_t *lock)
-{
-	struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
-	return bl->lock != 0;
-}
-
-static inline int __byte_spin_is_contended(raw_spinlock_t *lock)
-{
-	struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
-	return bl->spinners != 0;
-}
-
-static inline void __byte_spin_lock(raw_spinlock_t *lock)
-{
-	struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
-	s8 val = 1;
-
-	asm("1: xchgb %1, %0\n"
-	    "   test %1,%1\n"
-	    "   jz 3f\n"
-	    "   " LOCK_PREFIX "incb %2\n"
-	    "2: rep;nop\n"
-	    "   cmpb $1, %0\n"
-	    "   je 2b\n"
-	    "   " LOCK_PREFIX "decb %2\n"
-	    "   jmp 1b\n"
-	    "3:"
-	    : "+m" (bl->lock), "+q" (val), "+m" (bl->spinners): : "memory");
-}
-
-static inline int __byte_spin_trylock(raw_spinlock_t *lock)
-{
-	struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
-	u8 old = 1;
-
-	asm("xchgb %1,%0"
-	    : "+m" (bl->lock), "+q" (old) : : "memory");
-
-	return old == 0;
-}
+#ifndef CONFIG_PARAVIRT_SPINLOCKS
 
-static inline void __byte_spin_unlock(raw_spinlock_t *lock)
-{
-	struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
-	smp_wmb();
-	bl->lock = 0;
-}
-#else  /* !CONFIG_PARAVIRT */
 static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
 {
 	return __ticket_spin_is_locked(lock);
@@ -268,7 +206,7 @@ static __always_inline void __raw_spin_l
 	__raw_spin_lock(lock);
 }
 
-#endif	/* CONFIG_PARAVIRT */
+#endif	/* CONFIG_PARAVIRT_SPINLOCKS */
 
 static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
 {
@@ -330,8 +268,7 @@ static inline int __raw_read_trylock(raw
 {
 	atomic_t *count = (atomic_t *)lock;
 
-	atomic_dec(count);
-	if (atomic_read(count) >= 0)
+	if (atomic_dec_return(count) >= 0)
 		return 1;
 	atomic_inc(count);
 	return 0;
@@ -358,6 +295,9 @@ static inline void __raw_write_unlock(ra
 		     : "+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 _raw_spin_relax(lock)	cpu_relax()
 #define _raw_read_relax(lock)	cpu_relax()
 #define _raw_write_relax(lock)	cpu_relax()
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/stackprotector.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/stackprotector.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/stackprotector.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/stackprotector.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * GCC stack protector support.
+ *
+ * Stack protector works by putting predefined pattern at the start of
+ * the stack frame and verifying that it hasn't been overwritten when
+ * returning from the function.  The pattern is called stack canary
+ * and unfortunately gcc requires it to be at a fixed offset from %gs.
+ * On x86_64, the offset is 40 bytes and on x86_32 20 bytes.  x86_64
+ * and x86_32 use segment registers differently and thus handles this
+ * requirement differently.
+ *
+ * On x86_64, %gs is shared by percpu area and stack canary.  All
+ * percpu symbols are zero based and %gs points to the base of percpu
+ * area.  The first occupant of the percpu area is always
+ * irq_stack_union which contains stack_canary at offset 40.  Userland
+ * %gs is always saved and restored on kernel entry and exit using
+ * swapgs, so stack protector doesn't add any complexity there.
+ *
+ * On x86_32, it's slightly more complicated.  As in x86_64, %gs is
+ * used for userland TLS.  Unfortunately, some processors are much
+ * slower at loading segment registers with different value when
+ * entering and leaving the kernel, so the kernel uses %fs for percpu
+ * area and manages %gs lazily so that %gs is switched only when
+ * necessary, usually during task switch.
+ *
+ * As gcc requires the stack canary at %gs:20, %gs can't be managed
+ * lazily if stack protector is enabled, so the kernel saves and
+ * restores userland %gs on kernel entry and exit.  This behavior is
+ * controlled by CONFIG_X86_32_LAZY_GS and accessors are defined in
+ * system.h to hide the details.
+ */
+
+#ifndef _ASM_STACKPROTECTOR_H
+#define _ASM_STACKPROTECTOR_H 1
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+
+#include <asm/tsc.h>
+#include <asm/processor.h>
+#include <asm/percpu.h>
+#include <asm/system.h>
+#include <asm/desc.h>
+#include <linux/random.h>
+
+/*
+ * 24 byte read-only segment initializer for stack canary.  Linker
+ * can't handle the address bit shifting.  Address will be set in
+ * head_32 for boot CPU and setup_per_cpu_areas() for others.
+ */
+#define GDT_STACK_CANARY_INIT						\
+	[GDT_ENTRY_STACK_CANARY] = { { { 0x00000018, 0x00409000 } } },
+
+/*
+ * Initialize the stackprotector canary value.
+ *
+ * NOTE: this must only be called from functions that never return,
+ * and it must always be inlined.
+ */
+static __always_inline void boot_init_stack_canary(void)
+{
+	u64 canary;
+	u64 tsc;
+
+#ifdef CONFIG_X86_64
+	BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40);
+#endif
+	/*
+	 * We both use the random pool and the current TSC as a source
+	 * of randomness. The TSC only matters for very early init,
+	 * there it already has some randomness on most systems. Later
+	 * on during the bootup the random pool has true entropy too.
+	 */
+	get_random_bytes(&canary, sizeof(canary));
+	tsc = __native_read_tsc();
+	canary += tsc + (tsc << 32UL);
+
+	current->stack_canary = canary;
+#ifdef CONFIG_X86_64
+	percpu_write(irq_stack_union.stack_canary, canary);
+#else
+	percpu_write(stack_canary, canary);
+#endif
+}
+
+static inline void setup_stack_canary_segment(int cpu)
+{
+#ifdef CONFIG_X86_32
+	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20;
+	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
+	struct desc_struct desc;
+
+	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
+	desc.base0 = canary & 0xffff;
+	desc.base1 = (canary >> 16) & 0xff;
+	desc.base2 = (canary >> 24) & 0xff;
+	write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
+#endif
+}
+
+static inline void load_stack_canary_segment(void)
+{
+#ifdef CONFIG_X86_32
+	asm("mov %0, %%gs" : : "r" (__KERNEL_STACK_CANARY) : "memory");
+#endif
+}
+
+#else	/* CC_STACKPROTECTOR */
+
+#define GDT_STACK_CANARY_INIT
+
+/* dummy boot_init_stack_canary() is defined in linux/stackprotector.h */
+
+static inline void setup_stack_canary_segment(int cpu)
+{ }
+
+static inline void load_stack_canary_segment(void)
+{
+#ifdef CONFIG_X86_32
+	asm volatile ("mov %0, %%gs" : : "r" (0));
+#endif
+}
+
+#endif	/* CC_STACKPROTECTOR */
+#endif	/* _ASM_STACKPROTECTOR_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/apicdef.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/apicdef.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/apicdef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/apicdef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef __ASM_SUMMIT_APICDEF_H
-#define __ASM_SUMMIT_APICDEF_H
-
-#define		APIC_ID_MASK		(0xFF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
-	return (x>>24)&0xFF;
-}
-
-#define		GET_APIC_ID(x)	get_apic_id(x)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/apic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/apic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/apic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/apic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-#ifndef __ASM_SUMMIT_APIC_H
-#define __ASM_SUMMIT_APIC_H
-
-#include <asm/smp.h>
-#include <linux/gfp.h>
-
-#define esr_disable (1)
-#define NO_BALANCE_IRQ (0)
-
-/* In clustered mode, the high nibble of APIC ID is a cluster number.
- * The low nibble is a 4-bit bitmap. */
-#define XAPIC_DEST_CPUS_SHIFT	4
-#define XAPIC_DEST_CPUS_MASK	((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
-#define XAPIC_DEST_CLUSTER_MASK	(XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
-
-#define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
-
-static inline const cpumask_t *target_cpus(void)
-{
-	/* CPU_MASK_ALL (0xff) has undefined behaviour with
-	 * dest_LowestPrio mode logical clustered apic interrupt routing
-	 * Just start on cpu 0.  IRQ balancing will spread load
-	 */
-	return &cpumask_of_cpu(0);
-}
-
-#define INT_DELIVERY_MODE (dest_LowestPrio)
-#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
-
-static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-	return 0;
-}
-
-/* we don't use the phys_cpu_present_map to indicate apicid presence */
-static inline unsigned long check_apicid_present(int bit)
-{
-	return 1;
-}
-
-#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
-
-extern u8 cpu_2_logical_apicid[];
-
-static inline void init_apic_ldr(void)
-{
-	unsigned long val, id;
-	int count = 0;
-	u8 my_id = (u8)hard_smp_processor_id();
-	u8 my_cluster = (u8)apicid_cluster(my_id);
-#ifdef CONFIG_SMP
-	u8 lid;
-	int i;
-
-	/* Create logical APIC IDs by counting CPUs already in cluster. */
-	for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
-		lid = cpu_2_logical_apicid[i];
-		if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
-			++count;
-	}
-#endif
-	/* We only have a 4 wide bitmap in cluster mode.  If a deranged
-	 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
-	BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
-	id = my_cluster | (1UL << count);
-	apic_write(APIC_DFR, APIC_DFR_VALUE);
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	val |= SET_APIC_LOGICAL_ID(id);
-	apic_write(APIC_LDR, val);
-}
-
-static inline int multi_timer_check(int apic, int irq)
-{
-	return 0;
-}
-
-static inline int apic_id_registered(void)
-{
-	return 1;
-}
-
-static inline void setup_apic_routing(void)
-{
-	printk("Enabling APIC mode:  Summit.  Using %d I/O APICs\n",
-						nr_ioapics);
-}
-
-static inline int apicid_to_node(int logical_apicid)
-{
-#ifdef CONFIG_SMP
-	return apicid_2_node[hard_smp_processor_id()];
-#else
-	return 0;
-#endif
-}
-
-/* Mapping from cpu number to logical apicid */
-static inline int cpu_to_logical_apicid(int cpu)
-{
-#ifdef CONFIG_SMP
-	if (cpu >= nr_cpu_ids)
-		return BAD_APICID;
-	return (int)cpu_2_logical_apicid[cpu];
-#else
-	return logical_smp_processor_id();
-#endif
-}
-
-static inline int cpu_present_to_apicid(int mps_cpu)
-{
-	if (mps_cpu < nr_cpu_ids)
-		return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
-	else
-		return BAD_APICID;
-}
-
-static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map)
-{
-	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0x0F);
-}
-
-static inline physid_mask_t apicid_to_cpu_present(int apicid)
-{
-	return physid_mask_of_physid(0);
-}
-
-static inline void setup_portio_remap(void)
-{
-}
-
-static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-	return 1;
-}
-
-static inline void enable_apic_mode(void)
-{
-}
-
-static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-	int num_bits_set;
-	int cpus_found = 0;
-	int cpu;
-	int apicid;
-
-	num_bits_set = cpus_weight(*cpumask);
-	/* Return id to all */
-	if (num_bits_set >= nr_cpu_ids)
-		return (int) 0xFF;
-	/*
-	 * The cpus in the mask must all be on the apic cluster.  If are not
-	 * on the same apicid cluster return default value of TARGET_CPUS.
-	 */
-	cpu = first_cpu(*cpumask);
-	apicid = cpu_to_logical_apicid(cpu);
-	while (cpus_found < num_bits_set) {
-		if (cpu_isset(cpu, *cpumask)) {
-			int new_apicid = cpu_to_logical_apicid(cpu);
-			if (apicid_cluster(apicid) !=
-					apicid_cluster(new_apicid)){
-				printk ("%s: Not a valid mask!\n", __func__);
-				return 0xFF;
-			}
-			apicid = apicid | new_apicid;
-			cpus_found++;
-		}
-		cpu++;
-	}
-	return apicid;
-}
-
-static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask,
-						  const struct cpumask *andmask)
-{
-	int apicid = cpu_to_logical_apicid(0);
-	cpumask_var_t cpumask;
-
-	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
-		return apicid;
-
-	cpumask_and(cpumask, inmask, andmask);
-	cpumask_and(cpumask, cpumask, cpu_online_mask);
-	apicid = cpu_mask_to_apicid(cpumask);
-
-	free_cpumask_var(cpumask);
-	return apicid;
-}
-
-/* cpuid returns the value latched in the HW at reset, not the APIC ID
- * register's value.  For any box whose BIOS changes APIC IDs, like
- * clustered APIC systems, we must use hard_smp_processor_id.
- *
- * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
- */
-static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
-	return hard_smp_processor_id() >> index_msb;
-}
-
-#endif /* __ASM_SUMMIT_APIC_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/ipi.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/ipi.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/ipi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/ipi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-#ifndef __ASM_SUMMIT_IPI_H
-#define __ASM_SUMMIT_IPI_H
-
-void send_IPI_mask_sequence(const cpumask_t *mask, int vector);
-void send_IPI_mask_allbutself(const cpumask_t *mask, int vector);
-
-static inline void send_IPI_mask(const cpumask_t *mask, int vector)
-{
-	send_IPI_mask_sequence(mask, vector);
-}
-
-static inline void send_IPI_allbutself(int vector)
-{
-	cpumask_t mask = cpu_online_map;
-	cpu_clear(smp_processor_id(), mask);
-
-	if (!cpus_empty(mask))
-		send_IPI_mask(&mask, vector);
-}
-
-static inline void send_IPI_all(int vector)
-{
-	send_IPI_mask(&cpu_online_map, vector);
-}
-
-#endif /* __ASM_SUMMIT_IPI_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/mpparse.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/mpparse.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/summit/mpparse.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/summit/mpparse.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,109 +0,0 @@
-#ifndef __ASM_SUMMIT_MPPARSE_H
-#define __ASM_SUMMIT_MPPARSE_H
-
-#include <asm/tsc.h>
-
-extern int use_cyclone;
-
-#ifdef CONFIG_X86_SUMMIT_NUMA
-extern void setup_summit(void);
-#else
-#define setup_summit()	{}
-#endif
-
-static inline int mps_oem_check(struct mpc_table *mpc, char *oem,
-		char *productid)
-{
-	if (!strncmp(oem, "IBM ENSW", 8) &&
-			(!strncmp(productid, "VIGIL SMP", 9)
-			 || !strncmp(productid, "EXA", 3)
-			 || !strncmp(productid, "RUTHLESS SMP", 12))){
-		mark_tsc_unstable("Summit based system");
-		use_cyclone = 1; /*enable cyclone-timer*/
-		setup_summit();
-		return 1;
-	}
-	return 0;
-}
-
-/* Hook from generic ACPI tables.c */
-static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	if (!strncmp(oem_id, "IBM", 3) &&
-	    (!strncmp(oem_table_id, "SERVIGIL", 8)
-	     || !strncmp(oem_table_id, "EXA", 3))){
-		mark_tsc_unstable("Summit based system");
-		use_cyclone = 1; /*enable cyclone-timer*/
-		setup_summit();
-		return 1;
-	}
-	return 0;
-}
-
-struct rio_table_hdr {
-	unsigned char version;      /* Version number of this data structure           */
-	                            /* Version 3 adds chassis_num & WP_index           */
-	unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil)   */
-	unsigned char num_rio_dev;  /* # of RIO I/O devices (Cyclones and Winnipegs)   */
-} __attribute__((packed));
-
-struct scal_detail {
-	unsigned char node_id;      /* Scalability Node ID                             */
-	unsigned long CBAR;         /* Address of 1MB register space                   */
-	unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
-	unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-	unsigned char port1node;    /* Node ID port connected to: 0xFF = None          */
-	unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-	unsigned char port2node;    /* Node ID port connected to: 0xFF = None          */
-	unsigned char port2port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-	unsigned char chassis_num;  /* 1 based Chassis number (1 = boot node)          */
-} __attribute__((packed));
-
-struct rio_detail {
-	unsigned char node_id;      /* RIO Node ID                                     */
-	unsigned long BBAR;         /* Address of 1MB register space                   */
-	unsigned char type;         /* Type of device                                  */
-	unsigned char owner_id;     /* For WPEG: Node ID of Cyclone that owns this WPEG*/
-	                            /* For CYC:  Node ID of Twister that owns this CYC */
-	unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
-	unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-	unsigned char port1node;    /* Node ID port connected to: 0xFF=None            */
-	unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-	unsigned char first_slot;   /* For WPEG: Lowest slot number below this WPEG    */
-	                            /* For CYC:  0                                     */
-	unsigned char status;       /* For WPEG: Bit 0 = 1 : the XAPIC is used         */
-	                            /*                 = 0 : the XAPIC is not used, ie:*/
-	                            /*                     ints fwded to another XAPIC */
-	                            /*           Bits1:7 Reserved                      */
-	                            /* For CYC:  Bits0:7 Reserved                      */
-	unsigned char WP_index;     /* For WPEG: WPEG instance index - lower ones have */
-	                            /*           lower slot numbers/PCI bus numbers    */
-	                            /* For CYC:  No meaning                            */
-	unsigned char chassis_num;  /* 1 based Chassis number                          */
-	                            /* For LookOut WPEGs this field indicates the      */
-	                            /* Expansion Chassis #, enumerated from Boot       */
-	                            /* Node WPEG external port, then Boot Node CYC     */
-	                            /* external port, then Next Vigil chassis WPEG     */
-	                            /* external port, etc.                             */
-	                            /* Shared Lookouts have only 1 chassis number (the */
-	                            /* first one assigned)                             */
-} __attribute__((packed));
-
-
-typedef enum {
-	CompatTwister = 0,  /* Compatibility Twister               */
-	AltTwister    = 1,  /* Alternate Twister of internal 8-way */
-	CompatCyclone = 2,  /* Compatibility Cyclone               */
-	AltCyclone    = 3,  /* Alternate Cyclone of internal 8-way */
-	CompatWPEG    = 4,  /* Compatibility WPEG                  */
-	AltWPEG       = 5,  /* Second Planar WPEG                  */
-	LookOutAWPEG  = 6,  /* LookOut WPEG                        */
-	LookOutBWPEG  = 7,  /* LookOut WPEG                        */
-} node_type;
-
-static inline int is_WPEG(struct rio_detail *rio){
-	return (rio->type == CompatWPEG || rio->type == AltWPEG ||
-		rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
-}
-
-#endif /* __ASM_SUMMIT_MPPARSE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/suspend_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/suspend_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/suspend_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/suspend_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,28 +24,4 @@ struct saved_context {
 	unsigned long return_address;
 } __attribute__((packed));
 
-#ifdef CONFIG_ACPI
-extern unsigned long saved_eip;
-extern unsigned long saved_esp;
-extern unsigned long saved_ebp;
-extern unsigned long saved_ebx;
-extern unsigned long saved_esi;
-extern unsigned long saved_edi;
-
-static inline void acpi_save_register_state(unsigned long return_point)
-{
-	saved_eip = return_point;
-	asm volatile("movl %%esp,%0" : "=m" (saved_esp));
-	asm volatile("movl %%ebp,%0" : "=m" (saved_ebp));
-	asm volatile("movl %%ebx,%0" : "=m" (saved_ebx));
-	asm volatile("movl %%edi,%0" : "=m" (saved_edi));
-	asm volatile("movl %%esi,%0" : "=m" (saved_esi));
-}
-
-#define acpi_restore_register_state()  do {} while (0)
-
-/* routines for saving/restoring kernel state */
-extern int acpi_save_state_mem(void);
-#endif
-
 #endif /* _ASM_X86_SUSPEND_32_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/svm.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/svm.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/svm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/svm.h	2009-06-09 23:05:27.000000000 -0400
@@ -174,10 +174,6 @@ struct __attribute__ ((__packed__)) vmcb
 #define SVM_CPUID_FEATURE_SHIFT 2
 #define SVM_CPUID_FUNC 0x8000000a
 
-#define MSR_EFER_SVME_MASK (1ULL << 12)
-#define MSR_VM_CR       0xc0010114
-#define MSR_VM_HSAVE_PA 0xc0010117ULL
-
 #define SVM_VM_CR_SVM_DISABLE 4
 
 #define SVM_SELECTOR_S_SHIFT 4
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/syscalls.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/syscalls.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/syscalls.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/syscalls.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,21 +29,21 @@ asmlinkage int sys_get_thread_area(struc
 /* X86_32 only */
 #ifdef CONFIG_X86_32
 /* kernel/process_32.c */
-asmlinkage int sys_fork(struct pt_regs);
-asmlinkage int sys_clone(struct pt_regs);
-asmlinkage int sys_vfork(struct pt_regs);
-asmlinkage int sys_execve(struct pt_regs);
+int sys_fork(struct pt_regs *);
+int sys_clone(struct pt_regs *);
+int sys_vfork(struct pt_regs *);
+int sys_execve(struct pt_regs *);
 
 /* kernel/signal_32.c */
 asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
 asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
 			     struct old_sigaction __user *);
-asmlinkage int sys_sigaltstack(unsigned long);
-asmlinkage unsigned long sys_sigreturn(unsigned long);
-asmlinkage int sys_rt_sigreturn(unsigned long);
+int sys_sigaltstack(struct pt_regs *);
+unsigned long sys_sigreturn(struct pt_regs *);
+long sys_rt_sigreturn(struct pt_regs *);
 
 /* kernel/ioport.c */
-asmlinkage long sys_iopl(unsigned long);
+long sys_iopl(struct pt_regs *);
 
 /* kernel/sys_i386_32.c */
 asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
@@ -59,8 +59,8 @@ struct oldold_utsname;
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
 
 /* kernel/vm86_32.c */
-asmlinkage int sys_vm86old(struct pt_regs);
-asmlinkage int sys_vm86(struct pt_regs);
+int sys_vm86old(struct pt_regs *);
+int sys_vm86(struct pt_regs *);
 
 #else /* CONFIG_X86_32 */
 
@@ -74,6 +74,7 @@ asmlinkage long sys_vfork(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/ioport.c */
 asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
@@ -81,7 +82,7 @@ asmlinkage long sys_iopl(unsigned int, s
 /* kernel/signal_64.c */
 asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
 				struct pt_regs *);
-asmlinkage long sys_rt_sigreturn(struct pt_regs *);
+long sys_rt_sigreturn(struct pt_regs *);
 
 /* kernel/sys_x86_64.c */
 asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/sys_ia32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/sys_ia32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/sys_ia32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/sys_ia32.h	2009-06-09 23:05:27.000000000 -0400
@@ -70,8 +70,6 @@ struct old_utsname;
 asmlinkage long sys32_olduname(struct oldold_utsname __user *);
 long sys32_uname(struct old_utsname __user *);
 
-long sys32_ustat(unsigned, struct ustat32 __user *);
-
 asmlinkage long sys32_execve(char __user *, compat_uptr_t __user *,
 			     compat_uptr_t __user *, struct pt_regs *);
 asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/system.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/system.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/system.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,9 +20,26 @@
 struct task_struct; /* one of the stranger aspects of C forward declarations */
 struct task_struct *__switch_to(struct task_struct *prev,
 				struct task_struct *next);
+struct tss_struct;
+void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
+		      struct tss_struct *tss);
 
 #ifdef CONFIG_X86_32
 
+#ifdef CONFIG_CC_STACKPROTECTOR
+#define __switch_canary							\
+	"movl %P[task_canary](%[next]), %%ebx\n\t"			\
+	"movl %%ebx, "__percpu_arg([stack_canary])"\n\t"
+#define __switch_canary_oparam						\
+	, [stack_canary] "=m" (per_cpu_var(stack_canary))
+#define __switch_canary_iparam						\
+	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
+#else	/* CC_STACKPROTECTOR */
+#define __switch_canary
+#define __switch_canary_oparam
+#define __switch_canary_iparam
+#endif	/* CC_STACKPROTECTOR */
+
 /*
  * Saving eflags is important. It switches not only IOPL between tasks,
  * it also protects other tasks from NT leaking through sysenter etc.
@@ -44,6 +61,7 @@ do {									\
 		     "movl %[next_sp],%%esp\n\t"	/* restore ESP   */ \
 		     "movl $1f,%[prev_ip]\n\t"	/* save    EIP   */	\
 		     "pushl %[next_ip]\n\t"	/* restore EIP   */	\
+		     __switch_canary					\
 		     "jmp __switch_to\n"	/* regparm call  */	\
 		     "1:\t"						\
 		     "popl %%ebp\n\t"		/* restore EBP   */	\
@@ -58,6 +76,8 @@ do {									\
 		       "=b" (ebx), "=c" (ecx), "=d" (edx),		\
 		       "=S" (esi), "=D" (edi)				\
 		       							\
+		       __switch_canary_oparam				\
+									\
 		       /* input parameters: */				\
 		     : [next_sp]  "m" (next->thread.sp),		\
 		       [next_ip]  "m" (next->thread.ip),		\
@@ -66,6 +86,8 @@ do {									\
 		       [prev]     "a" (prev),				\
 		       [next]     "d" (next)				\
 									\
+		       __switch_canary_iparam				\
+									\
 		     : /* reloaded segment registers */			\
 			"memory");					\
 } while (0)
@@ -86,27 +108,44 @@ do {									\
 	, "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
 	  "r12", "r13", "r14", "r15"
 
+#ifdef CONFIG_CC_STACKPROTECTOR
+#define __switch_canary							  \
+	"movq %P[task_canary](%%rsi),%%r8\n\t"				  \
+	"movq %%r8,"__percpu_arg([gs_canary])"\n\t"
+#define __switch_canary_oparam						  \
+	, [gs_canary] "=m" (per_cpu_var(irq_stack_union.stack_canary))
+#define __switch_canary_iparam						  \
+	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
+#else	/* CC_STACKPROTECTOR */
+#define __switch_canary
+#define __switch_canary_oparam
+#define __switch_canary_iparam
+#endif	/* CC_STACKPROTECTOR */
+
 /* Save restore flags to clear handle leaking NT */
 #define switch_to(prev, next, last) \
-	asm volatile(SAVE_CONTEXT						    \
+	asm volatile(SAVE_CONTEXT					  \
 	     "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 %%gs:%P[pda_pcurrent],%%rsi\n\t"			  \
+	     "movq "__percpu_arg([current_task])",%%rsi\n\t"		  \
+	     __switch_canary						  \
 	     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
-	     LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"	  \
 	     "movq %%rax,%%rdi\n\t" 					  \
-	     "jc   ret_from_fork\n\t"					  \
+	     "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"	  \
+	     "jnz   ret_from_fork\n\t"					  \
 	     RESTORE_CONTEXT						  \
 	     : "=a" (last)					  	  \
+	       __switch_canary_oparam					  \
 	     : [next] "S" (next), [prev] "D" (prev),			  \
 	       [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \
 	       [ti_flags] "i" (offsetof(struct thread_info, flags)),	  \
-	       [tif_fork] "i" (TIF_FORK),			  	  \
+	       [_tif_fork] "i" (_TIF_FORK),			  	  \
 	       [thread_info] "i" (offsetof(struct task_struct, stack)),   \
-	       [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))  \
+	       [current_task] "m" (per_cpu_var(current_task))		  \
+	       __switch_canary_iparam					  \
 	     : "memory", "cc" __EXTRA_CLOBBER)
 #endif
 
@@ -165,6 +204,25 @@ extern void native_load_gs_index(unsigne
 #define savesegment(seg, value)				\
 	asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
 
+/*
+ * x86_32 user gs accessors.
+ */
+#ifdef CONFIG_X86_32
+#ifdef CONFIG_X86_32_LAZY_GS
+#define get_user_gs(regs)	(u16)({unsigned long v; savesegment(gs, v); v;})
+#define set_user_gs(regs, v)	loadsegment(gs, (unsigned long)(v))
+#define task_user_gs(tsk)	((tsk)->thread.gs)
+#define lazy_save_gs(v)		savesegment(gs, (v))
+#define lazy_load_gs(v)		loadsegment(gs, (v))
+#else	/* X86_32_LAZY_GS */
+#define get_user_gs(regs)	(u16)((regs)->gs)
+#define set_user_gs(regs, v)	do { (regs)->gs = (v); } while (0)
+#define task_user_gs(tsk)	(task_pt_regs(tsk)->gs)
+#define lazy_save_gs(v)		do { } while (0)
+#define lazy_load_gs(v)		do { } while (0)
+#endif	/* X86_32_LAZY_GS */
+#endif	/* X86_32 */
+
 static inline unsigned long get_limit(unsigned long segment)
 {
 	unsigned long __limit;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/thread_info.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/thread_info.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/thread_info.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/thread_info.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,7 @@ struct thread_info {
 						*/
 	__u8			supervisor_stack[0];
 #endif
+	int			uaccess_err;
 };
 
 #define INIT_THREAD_INFO(tsk)			\
@@ -93,6 +94,7 @@ struct thread_info {
 #define TIF_FORCED_TF		24	/* true if TF in eflags artificially */
 #define TIF_DEBUGCTLMSR		25	/* uses thread_struct.debugctlmsr */
 #define TIF_DS_AREA_MSR		26      /* uses thread_struct.ds_area_msr */
+#define TIF_SYSCALL_FTRACE	27	/* for ftrace syscall instrumentation */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
@@ -114,15 +116,17 @@ struct thread_info {
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
 #define _TIF_DEBUGCTLMSR	(1 << TIF_DEBUGCTLMSR)
 #define _TIF_DS_AREA_MSR	(1 << TIF_DS_AREA_MSR)
+#define _TIF_SYSCALL_FTRACE	(1 << TIF_SYSCALL_FTRACE)
 
 /* work to do in syscall_trace_enter() */
 #define _TIF_WORK_SYSCALL_ENTRY	\
-	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | \
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE |	\
 	 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
 
 /* work to do in syscall_trace_leave() */
 #define _TIF_WORK_SYSCALL_EXIT	\
-	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP |	\
+	 _TIF_SYSCALL_FTRACE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK							\
@@ -131,7 +135,7 @@ struct thread_info {
 	   _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
 
 /* work to do on any return to user space */
-#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
+#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE)
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK						\
@@ -194,25 +198,21 @@ static inline struct thread_info *curren
 
 #else /* X86_32 */
 
-#include <asm/pda.h>
+#include <asm/percpu.h>
+#define KERNEL_STACK_OFFSET (5*8)
 
 /*
  * macros/functions for gaining access to the thread information structure
  * preempt_count needs to be 1 initially, until the scheduler is functional.
  */
 #ifndef __ASSEMBLY__
-static inline struct thread_info *current_thread_info(void)
-{
-	struct thread_info *ti;
-	ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE);
-	return ti;
-}
+DECLARE_PER_CPU(unsigned long, kernel_stack);
 
-/* do not use in interrupt context */
-static inline struct thread_info *stack_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
-	asm("andq %%rsp,%0; " : "=r" (ti) : "0" (~(THREAD_SIZE - 1)));
+	ti = (void *)(percpu_read(kernel_stack) +
+		      KERNEL_STACK_OFFSET - THREAD_SIZE);
 	return ti;
 }
 
@@ -220,8 +220,8 @@ static inline struct thread_info *stack_
 
 /* how to get the thread information struct from ASM */
 #define GET_THREAD_INFO(reg) \
-	movq %gs:pda_kernelstack,reg ; \
-	subq $(THREAD_SIZE-PDA_STACKOFFSET),reg
+	movq PER_CPU_VAR(kernel_stack),reg ; \
+	subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg
 
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/timer.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/timer.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/timer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/timer.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/percpu.h>
+#include <linux/interrupt.h>
 
 #define TICK_SIZE (tick_nsec / 1000)
 
@@ -11,8 +12,9 @@ unsigned long native_calibrate_tsc(void)
 
 #ifdef CONFIG_X86_32
 extern int timer_ack;
-extern int recalibrate_cpu_khz(void);
+extern irqreturn_t timer_interrupt(int irq, void *dev_id);
 #endif /* CONFIG_X86_32 */
+extern int recalibrate_cpu_khz(void);
 
 extern int no_timer_check;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/tlbflush.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/tlbflush.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/tlbflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,7 @@ static inline void flush_tlb_range(struc
 		__flush_tlb();
 }
 
-static inline void native_flush_tlb_others(const cpumask_t *cpumask,
+static inline void native_flush_tlb_others(const struct cpumask *cpumask,
 					   struct mm_struct *mm,
 					   unsigned long va)
 {
@@ -142,31 +142,28 @@ static inline void flush_tlb_range(struc
 	flush_tlb_mm(vma->vm_mm);
 }
 
-void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm,
-			     unsigned long va);
+void native_flush_tlb_others(const struct cpumask *cpumask,
+			     struct mm_struct *mm, unsigned long va);
 
 #define TLBSTATE_OK	1
 #define TLBSTATE_LAZY	2
 
-#ifdef CONFIG_X86_32
 struct tlb_state {
 	struct mm_struct *active_mm;
 	int state;
-	char __cacheline_padding[L1_CACHE_BYTES-8];
 };
-DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
+DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
 
-void reset_lazy_tlbstate(void);
-#else
 static inline void reset_lazy_tlbstate(void)
 {
+	percpu_write(cpu_tlbstate.state, 0);
+	percpu_write(cpu_tlbstate.active_mm, &init_mm);
 }
-#endif
 
 #endif	/* SMP */
 
 #ifndef CONFIG_PARAVIRT
-#define flush_tlb_others(mask, mm, va)	native_flush_tlb_others(&mask, mm, va)
+#define flush_tlb_others(mask, mm, va)	native_flush_tlb_others(mask, mm, va)
 #endif
 
 static inline void flush_tlb_kernel_range(unsigned long start,
@@ -175,4 +172,6 @@ static inline void flush_tlb_kernel_rang
 	flush_tlb_all();
 }
 
+extern void zap_low_mappings(void);
+
 #endif /* _ASM_X86_TLBFLUSH_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/topology.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/topology.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,9 +44,6 @@
 
 #ifdef CONFIG_X86_32
 
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t node_to_cpumask_map[];
-
 /* Mappings between logical cpu number and node number */
 extern int cpu_to_node_map[];
 
@@ -57,39 +54,18 @@ static inline int cpu_to_node(int cpu)
 }
 #define early_cpu_to_node(cpu)	cpu_to_node(cpu)
 
-/* Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used.  The
- * cpumask_of_node function should be used whenever possible.
- */
-static inline cpumask_t node_to_cpumask(int node)
-{
-	return node_to_cpumask_map[node];
-}
-
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline const struct cpumask *cpumask_of_node(int node)
-{
-	return &node_to_cpumask_map[node];
-}
-
 #else /* CONFIG_X86_64 */
 
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t *node_to_cpumask_map;
-
 /* Mappings between logical cpu number and node number */
 DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
 
 /* Returns the number of the current Node. */
-#define numa_node_id()		read_pda(nodenumber)
+DECLARE_PER_CPU(int, node_number);
+#define numa_node_id()		percpu_read(node_number)
 
 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
 extern int cpu_to_node(int cpu);
 extern int early_cpu_to_node(int cpu);
-extern const cpumask_t *cpumask_of_node(int node);
-extern cpumask_t node_to_cpumask(int node);
 
 #else	/* !CONFIG_DEBUG_PER_CPU_MAPS */
 
@@ -102,37 +78,27 @@ static inline int cpu_to_node(int cpu)
 /* Same function but used if called before per_cpu areas are setup */
 static inline int early_cpu_to_node(int cpu)
 {
-	if (early_per_cpu_ptr(x86_cpu_to_node_map))
-		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
-
-	return per_cpu(x86_cpu_to_node_map, cpu);
+	return early_per_cpu(x86_cpu_to_node_map, cpu);
 }
 
-/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
-static inline const cpumask_t *cpumask_of_node(int node)
-{
-	return &node_to_cpumask_map[node];
-}
+#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
 
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline cpumask_t node_to_cpumask(int node)
+#endif /* CONFIG_X86_64 */
+
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+extern const struct cpumask *cpumask_of_node(int node);
+#else
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
 {
 	return node_to_cpumask_map[node];
 }
+#endif
 
-#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
-
-/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node)		\
-		const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node)	\
-			   v = cpumask_of_node(node)
-
-#endif /* CONFIG_X86_64 */
+extern void setup_node_to_cpumask_map(void);
 
 /*
  * Returns the number of the node containing Node 'node'. This
@@ -141,7 +107,6 @@ static inline cpumask_t node_to_cpumask(
 #define parent_node(node) (node)
 
 #define pcibus_to_node(bus) __pcibus_to_node(bus)
-#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus)
 
 #ifdef CONFIG_X86_32
 extern unsigned long node_start_pfn[];
@@ -192,54 +157,39 @@ extern int __node_distance(int, int);
 
 #else /* !CONFIG_NUMA */
 
-#define numa_node_id()		0
-#define	cpu_to_node(cpu)	0
-#define	early_cpu_to_node(cpu)	0
+static inline int numa_node_id(void)
+{
+	return 0;
+}
 
-static inline const cpumask_t *cpumask_of_node(int node)
+static inline int cpu_to_node(int cpu)
 {
-	return &cpu_online_map;
+	return 0;
 }
-static inline cpumask_t node_to_cpumask(int node)
+
+static inline int early_cpu_to_node(int cpu)
 {
-	return cpu_online_map;
+	return 0;
 }
-static inline int node_to_first_cpu(int node)
+
+static inline const struct cpumask *cpumask_of_node(int node)
 {
-	return first_cpu(cpu_online_map);
+	return cpu_online_mask;
 }
 
-/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node)		\
-		const cpumask_t *v = cpumask_of_node(node)
+static inline void setup_node_to_cpumask_map(void) { }
 
-#define node_to_cpumask_ptr_next(v, node)	\
-			   v = cpumask_of_node(node)
 #endif
 
 #include <asm-generic/topology.h>
 
-#ifdef CONFIG_NUMA
-/* Returns the number of the first CPU on Node 'node'. */
-static inline int node_to_first_cpu(int node)
-{
-	return cpumask_first(cpumask_of_node(node));
-}
-#endif
-
-extern cpumask_t cpu_coregroup_map(int cpu);
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
 
 #ifdef ENABLE_TOPO_DEFINES
 #define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
-#define topology_core_siblings(cpu)		(per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu)		(per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu)		(&per_cpu(cpu_core_map, cpu))
-#define topology_thread_cpumask(cpu)		(&per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
+#define topology_thread_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
 
 /* indicates that pointers to the topology cpumask_t maps are valid */
 #define arch_provides_topology_pointers		yes
@@ -250,10 +200,10 @@ static inline void arch_fix_phys_package
 }
 
 struct pci_bus;
-void set_pci_bus_resources_arch_default(struct pci_bus *b);
+void x86_pci_root_bus_res_quirks(struct pci_bus *b);
 
 #ifdef CONFIG_SMP
-#define mc_capable()	(cpus_weight(per_cpu(cpu_core_map, 0)) != nr_cpu_ids)
+#define mc_capable()	(cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)
 #define smt_capable()			(smp_num_siblings > 1)
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/trampoline.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/trampoline.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/trampoline.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/trampoline.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@ extern unsigned char *trampoline_base;
 
 extern unsigned long init_rsp;
 extern unsigned long initial_code;
+extern unsigned long initial_gs;
 
 #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
 #define TRAMPOLINE_BASE 0x6000
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/traps.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/traps.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/traps.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/traps.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@ dotraplinkage void do_int3(struct pt_reg
 dotraplinkage void do_overflow(struct pt_regs *, long);
 dotraplinkage void do_bounds(struct pt_regs *, long);
 dotraplinkage void do_invalid_op(struct pt_regs *, long);
-dotraplinkage void do_device_not_available(struct pt_regs);
+dotraplinkage void do_device_not_available(struct pt_regs *, long);
 dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long);
 dotraplinkage void do_invalid_TSS(struct pt_regs *, long);
 dotraplinkage void do_segment_not_present(struct pt_regs *, long);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uaccess_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uaccess_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -188,16 +188,16 @@ __copy_to_user_inatomic(void __user *dst
 extern long __copy_user_nocache(void *dst, const void __user *src,
 				unsigned size, int zerorest);
 
-static inline int __copy_from_user_nocache(void *dst, const void __user *src,
-					   unsigned size)
+static inline int
+__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
 {
 	might_sleep();
 	return __copy_user_nocache(dst, src, size, 1);
 }
 
-static inline int __copy_from_user_inatomic_nocache(void *dst,
-						    const void __user *src,
-						    unsigned size)
+static inline int
+__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
+				  unsigned size)
 {
 	return __copy_user_nocache(dst, src, size, 0);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uaccess.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uaccess.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
@@ -121,7 +121,7 @@ extern int __get_user_bad(void);
 
 #define __get_user_x(size, ret, x, ptr)		      \
 	asm volatile("call __get_user_" #size	      \
-		     : "=a" (ret),"=d" (x)	      \
+		     : "=a" (ret), "=d" (x)	      \
 		     : "0" (ptr))		      \
 
 /* Careful: we have to cast the result to the type of the pointer
@@ -181,12 +181,12 @@ extern int __get_user_bad(void);
 
 #define __put_user_x(size, x, ptr, __ret_pu)			\
 	asm volatile("call __put_user_" #size : "=a" (__ret_pu)	\
-		     :"0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
+		     : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
 
 
 
 #ifdef CONFIG_X86_32
-#define __put_user_u64(x, addr, err)					\
+#define __put_user_asm_u64(x, addr, err, errret)			\
 	asm volatile("1:	movl %%eax,0(%2)\n"			\
 		     "2:	movl %%edx,4(%2)\n"			\
 		     "3:\n"						\
@@ -197,14 +197,24 @@ extern int __get_user_bad(void);
 		     _ASM_EXTABLE(1b, 4b)				\
 		     _ASM_EXTABLE(2b, 4b)				\
 		     : "=r" (err)					\
-		     : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
+		     : "A" (x), "r" (addr), "i" (errret), "0" (err))
+
+#define __put_user_asm_ex_u64(x, addr)					\
+	asm volatile("1:	movl %%eax,0(%1)\n"			\
+		     "2:	movl %%edx,4(%1)\n"			\
+		     "3:\n"						\
+		     _ASM_EXTABLE(1b, 2b - 1b)				\
+		     _ASM_EXTABLE(2b, 3b - 2b)				\
+		     : : "A" (x), "r" (addr))
 
 #define __put_user_x8(x, ptr, __ret_pu)				\
 	asm volatile("call __put_user_8" : "=a" (__ret_pu)	\
 		     : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
 #else
-#define __put_user_u64(x, ptr, retval) \
-	__put_user_asm(x, ptr, retval, "q", "", "Zr", -EFAULT)
+#define __put_user_asm_u64(x, ptr, retval, errret) \
+	__put_user_asm(x, ptr, retval, "q", "", "Zr", errret)
+#define __put_user_asm_ex_u64(x, addr)	\
+	__put_user_asm_ex(x, addr, "q", "", "Zr")
 #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu)
 #endif
 
@@ -276,10 +286,32 @@ do {									\
 		__put_user_asm(x, ptr, retval, "w", "w", "ir", errret);	\
 		break;							\
 	case 4:								\
-		__put_user_asm(x, ptr, retval, "l", "k",  "ir", errret);\
+		__put_user_asm(x, ptr, retval, "l", "k", "ir", errret);	\
 		break;							\
 	case 8:								\
-		__put_user_u64((__typeof__(*ptr))(x), ptr, retval);	\
+		__put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval,	\
+				   errret);				\
+		break;							\
+	default:							\
+		__put_user_bad();					\
+	}								\
+} while (0)
+
+#define __put_user_size_ex(x, ptr, size)				\
+do {									\
+	__chk_user_ptr(ptr);						\
+	switch (size) {							\
+	case 1:								\
+		__put_user_asm_ex(x, ptr, "b", "b", "iq");		\
+		break;							\
+	case 2:								\
+		__put_user_asm_ex(x, ptr, "w", "w", "ir");		\
+		break;							\
+	case 4:								\
+		__put_user_asm_ex(x, ptr, "l", "k", "ir");		\
+		break;							\
+	case 8:								\
+		__put_user_asm_ex_u64((__typeof__(*ptr))(x), ptr);	\
 		break;							\
 	default:							\
 		__put_user_bad();					\
@@ -311,9 +343,12 @@ do {									\
 
 #ifdef CONFIG_X86_32
 #define __get_user_asm_u64(x, ptr, retval, errret)	(x) = __get_user_bad()
+#define __get_user_asm_ex_u64(x, ptr)			(x) = __get_user_bad()
 #else
 #define __get_user_asm_u64(x, ptr, retval, errret) \
 	 __get_user_asm(x, ptr, retval, "q", "", "=r", errret)
+#define __get_user_asm_ex_u64(x, ptr) \
+	 __get_user_asm_ex(x, ptr, "q", "", "=r")
 #endif
 
 #define __get_user_size(x, ptr, size, retval, errret)			\
@@ -350,6 +385,33 @@ do {									\
 		     : "=r" (err), ltype(x)				\
 		     : "m" (__m(addr)), "i" (errret), "0" (err))
 
+#define __get_user_size_ex(x, ptr, size)				\
+do {									\
+	__chk_user_ptr(ptr);						\
+	switch (size) {							\
+	case 1:								\
+		__get_user_asm_ex(x, ptr, "b", "b", "=q");		\
+		break;							\
+	case 2:								\
+		__get_user_asm_ex(x, ptr, "w", "w", "=r");		\
+		break;							\
+	case 4:								\
+		__get_user_asm_ex(x, ptr, "l", "k", "=r");		\
+		break;							\
+	case 8:								\
+		__get_user_asm_ex_u64(x, ptr);				\
+		break;							\
+	default:							\
+		(x) = __get_user_bad();					\
+	}								\
+} while (0)
+
+#define __get_user_asm_ex(x, addr, itype, rtype, ltype)			\
+	asm volatile("1:	mov"itype" %1,%"rtype"0\n"		\
+		     "2:\n"						\
+		     _ASM_EXTABLE(1b, 2b - 1b)				\
+		     : ltype(x) : "m" (__m(addr)))
+
 #define __put_user_nocheck(x, ptr, size)			\
 ({								\
 	int __pu_err;						\
@@ -385,6 +447,26 @@ struct __large_struct { unsigned long bu
 		     _ASM_EXTABLE(1b, 3b)				\
 		     : "=r"(err)					\
 		     : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
+
+#define __put_user_asm_ex(x, addr, itype, rtype, ltype)			\
+	asm volatile("1:	mov"itype" %"rtype"0,%1\n"		\
+		     "2:\n"						\
+		     _ASM_EXTABLE(1b, 2b - 1b)				\
+		     : : ltype(x), "m" (__m(addr)))
+
+/*
+ * uaccess_try and catch
+ */
+#define uaccess_try	do {						\
+	int prev_err = current_thread_info()->uaccess_err;		\
+	current_thread_info()->uaccess_err = 0;				\
+	barrier();
+
+#define uaccess_catch(err)						\
+	(err) |= current_thread_info()->uaccess_err;			\
+	current_thread_info()->uaccess_err = prev_err;			\
+} while (0)
+
 /**
  * __get_user: - Get a simple variable from user space, with less checking.
  * @x:   Variable to store result.
@@ -408,6 +490,7 @@ struct __large_struct { unsigned long bu
 
 #define __get_user(x, ptr)						\
 	__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
 /**
  * __put_user: - Write a simple value into user space, with less checking.
  * @x:   Value to copy to user space.
@@ -435,6 +518,45 @@ struct __large_struct { unsigned long bu
 #define __put_user_unaligned __put_user
 
 /*
+ * {get|put}_user_try and catch
+ *
+ * get_user_try {
+ *	get_user_ex(...);
+ * } get_user_catch(err)
+ */
+#define get_user_try		uaccess_try
+#define get_user_catch(err)	uaccess_catch(err)
+
+#define get_user_ex(x, ptr)	do {					\
+	unsigned long __gue_val;					\
+	__get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr))));	\
+	(x) = (__force __typeof__(*(ptr)))__gue_val;			\
+} while (0)
+
+#ifdef CONFIG_X86_WP_WORKS_OK
+
+#define put_user_try		uaccess_try
+#define put_user_catch(err)	uaccess_catch(err)
+
+#define put_user_ex(x, ptr)						\
+	__put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+
+#else /* !CONFIG_X86_WP_WORKS_OK */
+
+#define put_user_try		do {		\
+	int __uaccess_err = 0;
+
+#define put_user_catch(err)			\
+	(err) |= __uaccess_err;			\
+} while (0)
+
+#define put_user_ex(x, ptr)	do {		\
+	__uaccess_err |= __put_user(x, ptr);	\
+} while (0)
+
+#endif /* CONFIG_X86_WP_WORKS_OK */
+
+/*
  * movsl can be slow when source and dest are not both 8-byte aligned
  */
 #ifdef CONFIG_X86_INTEL_USERCOPY
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/unistd_32.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/unistd_32.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/unistd_32.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/unistd_32.h	2009-06-09 23:05:27.000000000 -0400
@@ -338,6 +338,8 @@
 #define __NR_dup3		330
 #define __NR_pipe2		331
 #define __NR_inotify_init1	332
+#define __NR_preadv		333
+#define __NR_pwritev		334
 
 #ifdef __KERNEL__
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/unistd_64.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/unistd_64.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/unistd_64.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/unistd_64.h	2009-06-09 23:05:27.000000000 -0400
@@ -653,6 +653,10 @@ __SYSCALL(__NR_dup3, sys_dup3)
 __SYSCALL(__NR_pipe2, sys_pipe2)
 #define __NR_inotify_init1			294
 __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
+#define __NR_preadv				295
+__SYSCALL(__NR_preadv, sys_preadv)
+#define __NR_pwritev				296
+__SYSCALL(__NR_pwritev, sys_pwritev)
 
 
 #ifndef __NO_STUBS
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_bau.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_bau.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_bau.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_bau.h	2009-06-09 23:05:27.000000000 -0400
@@ -325,7 +325,6 @@ static inline void bau_cpubits_clear(str
 #define cpubit_isset(cpu, bau_local_cpumask) \
 	test_bit((cpu), (bau_local_cpumask).bits)
 
-extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long);
 extern void uv_bau_message_intr1(void);
 extern void uv_bau_timeout_intr1(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,33 @@
+#ifndef _ASM_X86_UV_UV_H
+#define _ASM_X86_UV_UV_H
+
+enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
+
+struct cpumask;
+struct mm_struct;
+
+#ifdef CONFIG_X86_UV
+
+extern enum uv_system_type get_uv_system_type(void);
+extern int is_uv_system(void);
+extern void uv_cpu_init(void);
+extern void uv_system_init(void);
+extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
+						 struct mm_struct *mm,
+						 unsigned long va,
+						 unsigned int cpu);
+
+#else	/* X86_UV */
+
+static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; }
+static inline int is_uv_system(void)	{ return 0; }
+static inline void uv_cpu_init(void)	{ }
+static inline void uv_system_init(void)	{ }
+static inline const struct cpumask *
+uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm,
+		    unsigned long va, unsigned int cpu)
+{ return cpumask; }
+
+#endif	/* X86_UV */
+
+#endif	/* _ASM_X86_UV_UV_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_hub.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_hub.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_hub.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_hub.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,11 +11,13 @@
 #ifndef _ASM_X86_UV_UV_HUB_H
 #define _ASM_X86_UV_UV_HUB_H
 
+#ifdef CONFIG_X86_64
 #include <linux/numa.h>
 #include <linux/percpu.h>
 #include <linux/timer.h>
 #include <asm/types.h>
 #include <asm/percpu.h>
+#include <asm/uv/uv_mmrs.h>
 
 
 /*
@@ -199,6 +201,10 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __
 #define SCIR_CPU_ACTIVITY	0x02	/* not idle */
 #define SCIR_CPU_HB_INTERVAL	(HZ)	/* once per second */
 
+/* Loop through all installed blades */
+#define for_each_possible_blade(bid)		\
+	for ((bid) = 0; (bid) < uv_num_possible_blades(); (bid)++)
+
 /*
  * Macros for converting between kernel virtual addresses, socket local physical
  * addresses, and UV global physical addresses.
@@ -393,6 +399,7 @@ static inline void uv_set_scir_bits(unsi
 		uv_write_local_mmr8(uv_hub_info->scir.offset, value);
 	}
 }
+
 static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
 {
 	if (uv_cpu_hub_info(cpu)->scir.state != value) {
@@ -401,4 +408,15 @@ static inline void uv_set_cpu_scir_bits(
 	}
 }
 
+static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
+{
+	unsigned long val;
+
+	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+			((apicid & 0x3f) << UVH_IPI_INT_APIC_ID_SHFT) |
+			(vector << UVH_IPI_INT_VECTOR_SHFT);
+	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+}
+
+#endif /* CONFIG_X86_64 */
 #endif /* _ASM_X86_UV_UV_HUB_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_mmrs.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_mmrs.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/uv/uv_mmrs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_mmrs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,3 +1,4 @@
+
 /*
  * 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
@@ -16,6 +17,11 @@
 /* ========================================================================= */
 /*                           UVH_BAU_DATA_CONFIG                             */
 /* ========================================================================= */
+#define UVH_LB_BAU_MISC_CONTROL 0x320170UL
+#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
+/* 1011 timebase 7 (168millisec) * 3 ticks -> 500ms */
 #define UVH_BAU_DATA_CONFIG 0x61680UL
 #define UVH_BAU_DATA_CONFIG_32 0x0438
 
@@ -243,6 +249,158 @@ union uvh_event_occurred0_u {
 #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
 
 /* ========================================================================= */
+/*                         UVH_GR0_TLB_INT0_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
+
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int0_config_u {
+    unsigned long	v;
+    struct uvh_gr0_tlb_int0_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR0_TLB_INT1_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL
+
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int1_config_u {
+    unsigned long	v;
+    struct uvh_gr0_tlb_int1_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR1_TLB_INT0_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL
+
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int0_config_u {
+    unsigned long	v;
+    struct uvh_gr1_tlb_int0_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                         UVH_GR1_TLB_INT1_CONFIG                           */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL
+
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int1_config_u {
+    unsigned long	v;
+    struct uvh_gr1_tlb_int1_config_s {
+	unsigned long	vector_  :  8;  /* RW */
+	unsigned long	dm       :  3;  /* RW */
+	unsigned long	destmode :  1;  /* RW */
+	unsigned long	status   :  1;  /* RO */
+	unsigned long	p        :  1;  /* RO */
+	unsigned long	rsvd_14  :  1;  /*    */
+	unsigned long	t        :  1;  /* RO */
+	unsigned long	m        :  1;  /* RW */
+	unsigned long	rsvd_17_31: 15;  /*    */
+	unsigned long	apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
 /*                               UVH_INT_CMPB                                */
 /* ========================================================================= */
 #define UVH_INT_CMPB 0x22080UL
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/vic.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/vic.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/vic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/vic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/* Copyright (C) 1999,2001
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * Standard include definitions for the NCR Voyager Interrupt Controller */
-
-/* The eight CPI vectors.  To activate a CPI, you write a bit mask
- * corresponding to the processor set to be interrupted into the
- * relevant register.  That set of CPUs will then be interrupted with
- * the CPI */
-static const int VIC_CPI_Registers[] =
-	{0xFC00, 0xFC01, 0xFC08, 0xFC09,
-	 0xFC10, 0xFC11, 0xFC18, 0xFC19 };
-
-#define VIC_PROC_WHO_AM_I		0xfc29
-#	define	QUAD_IDENTIFIER		0xC0
-#	define  EIGHT_SLOT_IDENTIFIER	0xE0
-#define QIC_EXTENDED_PROCESSOR_SELECT	0xFC72
-#define VIC_CPI_BASE_REGISTER		0xFC41
-#define VIC_PROCESSOR_ID		0xFC21
-#	define VIC_CPU_MASQUERADE_ENABLE 0x8
-
-#define VIC_CLAIM_REGISTER_0		0xFC38
-#define VIC_CLAIM_REGISTER_1		0xFC39
-#define VIC_REDIRECT_REGISTER_0		0xFC60
-#define VIC_REDIRECT_REGISTER_1		0xFC61
-#define VIC_PRIORITY_REGISTER		0xFC20
-
-#define VIC_PRIMARY_MC_BASE		0xFC48
-#define VIC_SECONDARY_MC_BASE		0xFC49
-
-#define QIC_PROCESSOR_ID		0xFC71
-#	define	QIC_CPUID_ENABLE	0x08
-
-#define QIC_VIC_CPI_BASE_REGISTER	0xFC79
-#define QIC_CPI_BASE_REGISTER		0xFC7A
-
-#define QIC_MASK_REGISTER0		0xFC80
-/* NOTE: these are masked high, enabled low */
-#	define QIC_PERF_TIMER		0x01
-#	define QIC_LPE			0x02
-#	define QIC_SYS_INT		0x04
-#	define QIC_CMN_INT		0x08
-/* at the moment, just enable CMN_INT, disable SYS_INT */
-#	define QIC_DEFAULT_MASK0	(~(QIC_CMN_INT /* | VIC_SYS_INT */))
-#define QIC_MASK_REGISTER1		0xFC81
-#	define QIC_BOOT_CPI_MASK	0xFE
-/* Enable CPI's 1-6 inclusive */
-#	define QIC_CPI_ENABLE		0x81
-
-#define QIC_INTERRUPT_CLEAR0		0xFC8A
-#define QIC_INTERRUPT_CLEAR1		0xFC8B
-
-/* this is where we place the CPI vectors */
-#define VIC_DEFAULT_CPI_BASE		0xC0
-/* this is where we place the QIC CPI vectors */
-#define QIC_DEFAULT_CPI_BASE		0xD0
-
-#define VIC_BOOT_INTERRUPT_MASK		0xfe
-
-extern void smp_vic_timer_interrupt(void);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/virtext.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/virtext.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/virtext.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/virtext.h	2009-06-09 23:05:27.000000000 -0400
@@ -118,7 +118,7 @@ static inline void cpu_svm_disable(void)
 
 	wrmsrl(MSR_VM_HSAVE_PA, 0);
 	rdmsrl(MSR_EFER, efer);
-	wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK);
+	wrmsrl(MSR_EFER, efer & ~EFER_SVME);
 }
 
 /** Makes sure SVM is disabled, if it is supported on the CPU
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/vmx.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/vmx.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/vmx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/vmx.h	2009-06-09 23:05:27.000000000 -0400
@@ -270,8 +270,9 @@ enum vmcs_field {
 
 #define INTR_TYPE_EXT_INTR              (0 << 8) /* external interrupt */
 #define INTR_TYPE_NMI_INTR		(2 << 8) /* NMI */
-#define INTR_TYPE_EXCEPTION             (3 << 8) /* processor exception */
+#define INTR_TYPE_HARD_EXCEPTION	(3 << 8) /* processor exception */
 #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
+#define INTR_TYPE_SOFT_EXCEPTION	(6 << 8) /* software exception */
 
 /* GUEST_INTERRUPTIBILITY_INFO flags. */
 #define GUEST_INTR_STATE_STI		0x00000001
@@ -311,7 +312,7 @@ enum vmcs_field {
 #define DEBUG_REG_ACCESS_TYPE           0x10    /* 4, direction of access */
 #define TYPE_MOV_TO_DR                  (0 << 4)
 #define TYPE_MOV_FROM_DR                (1 << 4)
-#define DEBUG_REG_ACCESS_REG            0xf00   /* 11:8, general purpose reg. */
+#define DEBUG_REG_ACCESS_REG(eq)        (((eq) >> 8) & 0xf) /* 11:8, general purpose reg. */
 
 
 /* segment AR */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/voyager.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/voyager.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/voyager.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/voyager.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,529 +0,0 @@
-/* Copyright (C) 1999,2001
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * Standard include definitions for the NCR Voyager system */
-
-#undef	VOYAGER_DEBUG
-#undef	VOYAGER_CAT_DEBUG
-
-#ifdef VOYAGER_DEBUG
-#define VDEBUG(x)	printk x
-#else
-#define VDEBUG(x)
-#endif
-
-/* There are three levels of voyager machine: 3,4 and 5. The rule is
- * if it's less than 3435 it's a Level 3 except for a 3360 which is
- * a level 4.  A 3435 or above is a Level 5 */
-#define VOYAGER_LEVEL5_AND_ABOVE	0x3435
-#define VOYAGER_LEVEL4			0x3360
-
-/* The L4 DINO ASIC */
-#define VOYAGER_DINO			0x43
-
-/* voyager ports in standard I/O space */
-#define VOYAGER_MC_SETUP	0x96
-
-
-#define	VOYAGER_CAT_CONFIG_PORT			0x97
-#	define VOYAGER_CAT_DESELECT		0xff
-#define VOYAGER_SSPB_RELOCATION_PORT		0x98
-
-/* Valid CAT controller commands */
-/* start instruction register cycle */
-#define VOYAGER_CAT_IRCYC			0x01
-/* start data register cycle */
-#define VOYAGER_CAT_DRCYC			0x02
-/* move to execute state */
-#define VOYAGER_CAT_RUN				0x0F
-/* end operation */
-#define VOYAGER_CAT_END				0x80
-/* hold in idle state */
-#define VOYAGER_CAT_HOLD			0x90
-/* single step an "intest" vector */
-#define VOYAGER_CAT_STEP			0xE0
-/* return cat controller to CLEMSON mode */
-#define VOYAGER_CAT_CLEMSON			0xFF
-
-/* the default cat command header */
-#define VOYAGER_CAT_HEADER			0x7F
-
-/* the range of possible CAT module ids in the system */
-#define VOYAGER_MIN_MODULE			0x10
-#define VOYAGER_MAX_MODULE			0x1f
-
-/* The voyager registers per asic */
-#define VOYAGER_ASIC_ID_REG			0x00
-#define VOYAGER_ASIC_TYPE_REG			0x01
-/* the sub address registers can be made auto incrementing on reads */
-#define VOYAGER_AUTO_INC_REG			0x02
-#	define VOYAGER_AUTO_INC			0x04
-#	define VOYAGER_NO_AUTO_INC		0xfb
-#define VOYAGER_SUBADDRDATA			0x03
-#define VOYAGER_SCANPATH			0x05
-#	define VOYAGER_CONNECT_ASIC		0x01
-#	define VOYAGER_DISCONNECT_ASIC		0xfe
-#define VOYAGER_SUBADDRLO			0x06
-#define VOYAGER_SUBADDRHI			0x07
-#define VOYAGER_SUBMODSELECT			0x08
-#define VOYAGER_SUBMODPRESENT			0x09
-
-#define VOYAGER_SUBADDR_LO			0xff
-#define VOYAGER_SUBADDR_HI			0xffff
-
-/* the maximum size of a scan path -- used to form instructions */
-#define VOYAGER_MAX_SCAN_PATH			0x100
-/* the biggest possible register size (in bytes) */
-#define VOYAGER_MAX_REG_SIZE			4
-
-/* Total number of possible modules (including submodules) */
-#define VOYAGER_MAX_MODULES			16
-/* Largest number of asics per module */
-#define VOYAGER_MAX_ASICS_PER_MODULE		7
-
-/* the CAT asic of each module is always the first one */
-#define VOYAGER_CAT_ID				0
-#define VOYAGER_PSI				0x1a
-
-/* voyager instruction operations and registers */
-#define VOYAGER_READ_CONFIG			0x1
-#define VOYAGER_WRITE_CONFIG			0x2
-#define VOYAGER_BYPASS				0xff
-
-typedef struct voyager_asic {
-	__u8	asic_addr;	/* ASIC address; Level 4 */
-	__u8	asic_type;      /* ASIC type */
-	__u8	asic_id;	/* ASIC id */
-	__u8	jtag_id[4];	/* JTAG id */
-	__u8	asic_location;	/* Location within scan path; start w/ 0 */
-	__u8	bit_location;	/* Location within bit stream; start w/ 0 */
-	__u8	ireg_length;	/* Instruction register length */
-	__u16	subaddr;	/* Amount of sub address space */
-	struct voyager_asic *next;	/* Next asic in linked list */
-} voyager_asic_t;
-
-typedef struct voyager_module {
-	__u8	module_addr;		/* Module address */
-	__u8	scan_path_connected;	/* Scan path connected */
-	__u16   ee_size;		/* Size of the EEPROM */
-	__u16   num_asics;		/* Number of Asics */
-	__u16   inst_bits;		/* Instruction bits in the scan path */
-	__u16   largest_reg;		/* Largest register in the scan path */
-	__u16   smallest_reg;		/* Smallest register in the scan path */
-	voyager_asic_t   *asic;		/* First ASIC in scan path (CAT_I) */
-	struct   voyager_module *submodule;	/* Submodule pointer */
-	struct   voyager_module *next;		/* Next module in linked list */
-} voyager_module_t;
-
-typedef struct voyager_eeprom_hdr {
-	 __u8  module_id[4];
-	 __u8  version_id;
-	 __u8  config_id;
-	 __u16 boundry_id;	/* boundary scan id */
-	 __u16 ee_size;		/* size of EEPROM */
-	 __u8  assembly[11];	/* assembly # */
-	 __u8  assembly_rev;	/* assembly rev */
-	 __u8  tracer[4];	/* tracer number */
-	 __u16 assembly_cksum;	/* asm checksum */
-	 __u16 power_consump;	/* pwr requirements */
-	 __u16 num_asics;	/* number of asics */
-	 __u16 bist_time;	/* min. bist time */
-	 __u16 err_log_offset;	/* error log offset */
-	 __u16 scan_path_offset;/* scan path offset */
-	 __u16 cct_offset;
-	 __u16 log_length;	/* length of err log */
-	 __u16 xsum_end;	/* offset to end of
-				   checksum */
-	 __u8  reserved[4];
-	 __u8  sflag;		/* starting sentinal */
-	 __u8  part_number[13];	/* prom part number */
-	 __u8  version[10];	/* version number */
-	 __u8  signature[8];
-	 __u16 eeprom_chksum;
-	 __u32  data_stamp_offset;
-	 __u8  eflag ;		 /* ending sentinal */
-} __attribute__((packed)) voyager_eprom_hdr_t;
-
-
-
-#define VOYAGER_EPROM_SIZE_OFFSET				\
-	((__u16)(&(((voyager_eprom_hdr_t *)0)->ee_size)))
-#define VOYAGER_XSUM_END_OFFSET		0x2a
-
-/* the following three definitions are for internal table layouts
- * in the module EPROMs.  We really only care about the IDs and
- * offsets */
-typedef struct voyager_sp_table {
-	__u8 asic_id;
-	__u8 bypass_flag;
-	__u16 asic_data_offset;
-	__u16 config_data_offset;
-} __attribute__((packed)) voyager_sp_table_t;
-
-typedef struct voyager_jtag_table {
-	__u8 icode[4];
-	__u8 runbist[4];
-	__u8 intest[4];
-	__u8 samp_preld[4];
-	__u8 ireg_len;
-} __attribute__((packed)) voyager_jtt_t;
-
-typedef struct voyager_asic_data_table {
-	__u8 jtag_id[4];
-	__u16 length_bsr;
-	__u16 length_bist_reg;
-	__u32 bist_clk;
-	__u16 subaddr_bits;
-	__u16 seed_bits;
-	__u16 sig_bits;
-	__u16 jtag_offset;
-} __attribute__((packed)) voyager_at_t;
-
-/* Voyager Interrupt Controller (VIC) registers */
-
-/* Base to add to Cross Processor Interrupts (CPIs) when triggering
- * the CPU IRQ line */
-/* register defines for the WCBICs (one per processor) */
-#define VOYAGER_WCBIC0	0x41		/* bus A node P1 processor 0 */
-#define VOYAGER_WCBIC1	0x49		/* bus A node P1 processor 1 */
-#define VOYAGER_WCBIC2	0x51		/* bus A node P2 processor 0 */
-#define VOYAGER_WCBIC3	0x59		/* bus A node P2 processor 1 */
-#define VOYAGER_WCBIC4	0x61		/* bus B node P1 processor 0 */
-#define VOYAGER_WCBIC5	0x69		/* bus B node P1 processor 1 */
-#define VOYAGER_WCBIC6	0x71		/* bus B node P2 processor 0 */
-#define VOYAGER_WCBIC7	0x79		/* bus B node P2 processor 1 */
-
-
-/* top of memory registers */
-#define VOYAGER_WCBIC_TOM_L	0x4
-#define VOYAGER_WCBIC_TOM_H	0x5
-
-/* register defines for Voyager Memory Contol (VMC)
- * these are present on L4 machines only */
-#define	VOYAGER_VMC1		0x81
-#define VOYAGER_VMC2		0x91
-#define VOYAGER_VMC3		0xa1
-#define VOYAGER_VMC4		0xb1
-
-/* VMC Ports */
-#define VOYAGER_VMC_MEMORY_SETUP	0x9
-#	define VMC_Interleaving		0x01
-#	define VMC_4Way			0x02
-#	define VMC_EvenCacheLines	0x04
-#	define VMC_HighLine		0x08
-#	define VMC_Start0_Enable	0x20
-#	define VMC_Start1_Enable	0x40
-#	define VMC_Vremap		0x80
-#define VOYAGER_VMC_BANK_DENSITY	0xa
-#	define	VMC_BANK_EMPTY		0
-#	define	VMC_BANK_4MB		1
-#	define	VMC_BANK_16MB		2
-#	define	VMC_BANK_64MB		3
-#	define	VMC_BANK0_MASK		0x03
-#	define	VMC_BANK1_MASK		0x0C
-#	define	VMC_BANK2_MASK		0x30
-#	define	VMC_BANK3_MASK		0xC0
-
-/* Magellan Memory Controller (MMC) defines - present on L5 */
-#define VOYAGER_MMC_ASIC_ID		1
-/* the two memory modules corresponding to memory cards in the system */
-#define VOYAGER_MMC_MEMORY0_MODULE	0x14
-#define VOYAGER_MMC_MEMORY1_MODULE	0x15
-/* the Magellan Memory Address (MMA) defines */
-#define VOYAGER_MMA_ASIC_ID		2
-
-/* Submodule number for the Quad Baseboard */
-#define VOYAGER_QUAD_BASEBOARD		1
-
-/* ASIC defines for the Quad Baseboard */
-#define VOYAGER_QUAD_QDATA0		1
-#define VOYAGER_QUAD_QDATA1		2
-#define VOYAGER_QUAD_QABC		3
-
-/* Useful areas in extended CMOS */
-#define VOYAGER_PROCESSOR_PRESENT_MASK	0x88a
-#define VOYAGER_MEMORY_CLICKMAP		0xa23
-#define VOYAGER_DUMP_LOCATION		0xb1a
-
-/* SUS In Control bit - used to tell SUS that we don't need to be
- * babysat anymore */
-#define VOYAGER_SUS_IN_CONTROL_PORT	0x3ff
-#	define VOYAGER_IN_CONTROL_FLAG	0x80
-
-/* Voyager PSI defines */
-#define VOYAGER_PSI_STATUS_REG		0x08
-#	define PSI_DC_FAIL		0x01
-#	define PSI_MON			0x02
-#	define PSI_FAULT		0x04
-#	define PSI_ALARM		0x08
-#	define PSI_CURRENT		0x10
-#	define PSI_DVM			0x20
-#	define PSI_PSCFAULT		0x40
-#	define PSI_STAT_CHG		0x80
-
-#define VOYAGER_PSI_SUPPLY_REG		0x8000
-	/* read */
-#	define PSI_FAIL_DC		0x01
-#	define PSI_FAIL_AC		0x02
-#	define PSI_MON_INT		0x04
-#	define PSI_SWITCH_OFF		0x08
-#	define PSI_HX_OFF		0x10
-#	define PSI_SECURITY		0x20
-#	define PSI_CMOS_BATT_LOW	0x40
-#	define PSI_CMOS_BATT_FAIL	0x80
-	/* write */
-#	define PSI_CLR_SWITCH_OFF	0x13
-#	define PSI_CLR_HX_OFF		0x14
-#	define PSI_CLR_CMOS_BATT_FAIL	0x17
-
-#define VOYAGER_PSI_MASK		0x8001
-#	define PSI_MASK_MASK		0x10
-
-#define VOYAGER_PSI_AC_FAIL_REG		0x8004
-#define	AC_FAIL_STAT_CHANGE		0x80
-
-#define VOYAGER_PSI_GENERAL_REG		0x8007
-	/* read */
-#	define PSI_SWITCH_ON		0x01
-#	define PSI_SWITCH_ENABLED	0x02
-#	define PSI_ALARM_ENABLED	0x08
-#	define PSI_SECURE_ENABLED	0x10
-#	define PSI_COLD_RESET		0x20
-#	define PSI_COLD_START		0x80
-	/* write */
-#	define PSI_POWER_DOWN		0x10
-#	define PSI_SWITCH_DISABLE	0x01
-#	define PSI_SWITCH_ENABLE	0x11
-#	define PSI_CLEAR		0x12
-#	define PSI_ALARM_DISABLE	0x03
-#	define PSI_ALARM_ENABLE		0x13
-#	define PSI_CLEAR_COLD_RESET	0x05
-#	define PSI_SET_COLD_RESET	0x15
-#	define PSI_CLEAR_COLD_START	0x07
-#	define PSI_SET_COLD_START	0x17
-
-
-
-struct voyager_bios_info {
-	__u8	len;
-	__u8	major;
-	__u8	minor;
-	__u8	debug;
-	__u8	num_classes;
-	__u8	class_1;
-	__u8	class_2;
-};
-
-/* The following structures and definitions are for the Kernel/SUS
- * interface these are needed to find out how SUS initialised any Quad
- * boards in the system */
-
-#define	NUMBER_OF_MC_BUSSES	2
-#define SLOTS_PER_MC_BUS	8
-#define MAX_CPUS                16      /* 16 way CPU system */
-#define MAX_PROCESSOR_BOARDS	4	/* 4 processor slot system */
-#define MAX_CACHE_LEVELS	4	/* # of cache levels supported */
-#define MAX_SHARED_CPUS		4	/* # of CPUs that can share a LARC */
-#define NUMBER_OF_POS_REGS	8
-
-typedef struct {
-	__u8	MC_Slot;
-	__u8	POS_Values[NUMBER_OF_POS_REGS];
-} __attribute__((packed)) MC_SlotInformation_t;
-
-struct QuadDescription {
-	__u8  Type;	/* for type 0 (DYADIC or MONADIC) all fields
-			 * will be zero except for slot */
-	__u8 StructureVersion;
-	__u32 CPI_BaseAddress;
-	__u32  LARC_BankSize;
-	__u32 LocalMemoryStateBits;
-	__u8  Slot; /* Processor slots 1 - 4 */
-} __attribute__((packed));
-
-struct ProcBoardInfo {
-	__u8 Type;
-	__u8 StructureVersion;
-	__u8 NumberOfBoards;
-	struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS];
-} __attribute__((packed));
-
-struct CacheDescription {
-	__u8 Level;
-	__u32 TotalSize;
-	__u16 LineSize;
-	__u8  Associativity;
-	__u8  CacheType;
-	__u8  WriteType;
-	__u8  Number_CPUs_SharedBy;
-	__u8  Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS];
-
-} __attribute__((packed));
-
-struct CPU_Description {
-	__u8 CPU_HardwareId;
-	char *FRU_String;
-	__u8 NumberOfCacheLevels;
-	struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS];
-} __attribute__((packed));
-
-struct CPU_Info {
-	__u8 Type;
-	__u8 StructureVersion;
-	__u8 NumberOf_CPUs;
-	struct CPU_Description CPU_Data[MAX_CPUS];
-} __attribute__((packed));
-
-
-/*
- * This structure will be used by SUS and the OS.
- * The assumption about this structure is that no blank space is
- * packed in it by our friend the compiler.
- */
-typedef struct {
-	__u8	Mailbox_SUS;		/* Written to by SUS to give
-					   commands/response to the OS */
-	__u8	Mailbox_OS;		/* Written to by the OS to give
-					   commands/response to SUS */
-	__u8	SUS_MailboxVersion;	/* Tells the OS which iteration of the
-					   interface SUS supports */
-	__u8	OS_MailboxVersion;	/* Tells SUS which iteration of the
-					   interface the OS supports */
-	__u32	OS_Flags;		/* Flags set by the OS as info for
-					   SUS */
-	__u32	SUS_Flags;		/* Flags set by SUS as info
-					   for the OS */
-	__u32	WatchDogPeriod;		/* Watchdog period (in seconds) which
-					   the DP uses to see if the OS
-					   is dead */
-	__u32	WatchDogCount;		/* Updated by the OS on every tic. */
-	__u32	MemoryFor_SUS_ErrorLog;	/* Flat 32 bit address which tells SUS
-					   where to stuff the SUS error log
-					   on a dump */
-	MC_SlotInformation_t MC_SlotInfo[NUMBER_OF_MC_BUSSES*SLOTS_PER_MC_BUS];
-					/* Storage for MCA POS data */
-	/* All new SECOND_PASS_INTERFACE fields added from this point */
-	struct ProcBoardInfo    *BoardData;
-	struct CPU_Info         *CPU_Data;
-	/* All new fields must be added from this point */
-} Voyager_KernelSUS_Mbox_t;
-
-/* structure for finding the right memory address to send a QIC CPI to */
-struct voyager_qic_cpi {
-	/* Each cache line (32 bytes) can trigger a cpi.  The cpi
-	 * read/write may occur anywhere in the cache line---pick the
-	 * middle to be safe */
-	struct  {
-		__u32 pad1[3];
-		__u32 cpi;
-		__u32 pad2[4];
-	} qic_cpi[8];
-};
-
-struct voyager_status {
-	__u32	power_fail:1;
-	__u32	switch_off:1;
-	__u32	request_from_kernel:1;
-};
-
-struct voyager_psi_regs {
-	__u8 cat_id;
-	__u8 cat_dev;
-	__u8 cat_control;
-	__u8 subaddr;
-	__u8 dummy4;
-	__u8 checkbit;
-	__u8 subaddr_low;
-	__u8 subaddr_high;
-	__u8 intstatus;
-	__u8 stat1;
-	__u8 stat3;
-	__u8 fault;
-	__u8 tms;
-	__u8 gen;
-	__u8 sysconf;
-	__u8 dummy15;
-};
-
-struct voyager_psi_subregs {
-	__u8 supply;
-	__u8 mask;
-	__u8 present;
-	__u8 DCfail;
-	__u8 ACfail;
-	__u8 fail;
-	__u8 UPSfail;
-	__u8 genstatus;
-};
-
-struct voyager_psi {
-	struct voyager_psi_regs regs;
-	struct voyager_psi_subregs subregs;
-};
-
-struct voyager_SUS {
-#define	VOYAGER_DUMP_BUTTON_NMI		0x1
-#define VOYAGER_SUS_VALID		0x2
-#define VOYAGER_SYSINT_COMPLETE		0x3
-	__u8	SUS_mbox;
-#define VOYAGER_NO_COMMAND		0x0
-#define VOYAGER_IGNORE_DUMP		0x1
-#define VOYAGER_DO_DUMP			0x2
-#define VOYAGER_SYSINT_HANDSHAKE	0x3
-#define VOYAGER_DO_MEM_DUMP		0x4
-#define VOYAGER_SYSINT_WAS_RECOVERED	0x5
-	__u8	kernel_mbox;
-#define	VOYAGER_MAILBOX_VERSION		0x10
-	__u8	SUS_version;
-	__u8	kernel_version;
-#define VOYAGER_OS_HAS_SYSINT		0x1
-#define VOYAGER_OS_IN_PROGRESS		0x2
-#define VOYAGER_UPDATING_WDPERIOD	0x4
-	__u32	kernel_flags;
-#define VOYAGER_SUS_BOOTING		0x1
-#define VOYAGER_SUS_IN_PROGRESS		0x2
-	__u32	SUS_flags;
-	__u32	watchdog_period;
-	__u32	watchdog_count;
-	__u32	SUS_errorlog;
-	/* lots of system configuration stuff under here */
-};
-
-/* Variables exported by voyager_smp */
-extern __u32 voyager_extended_vic_processors;
-extern __u32 voyager_allowed_boot_processors;
-extern __u32 voyager_quad_processors;
-extern struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS];
-extern struct voyager_SUS *voyager_SUS;
-
-/* variables exported always */
-extern struct task_struct *voyager_thread;
-extern int voyager_level;
-extern struct voyager_status voyager_status;
-
-/* functions exported by the voyager and voyager_smp modules */
-extern int voyager_cat_readb(__u8 module, __u8 asic, int reg);
-extern void voyager_cat_init(void);
-extern void voyager_detect(struct voyager_bios_info *);
-extern void voyager_trap_init(void);
-extern void voyager_setup_irqs(void);
-extern int voyager_memory_detect(int region, __u32 *addr, __u32 *length);
-extern void voyager_smp_intr_init(void);
-extern __u8 voyager_extended_cmos_read(__u16 cmos_address);
-extern void voyager_smp_dump(void);
-extern void voyager_timer_interrupt(void);
-extern void smp_local_timer_interrupt(void);
-extern void voyager_power_off(void);
-extern void smp_voyager_power_off(void *dummy);
-extern void voyager_restart(void);
-extern void voyager_cat_power_off(void);
-extern void voyager_cat_do_common_interrupt(void);
-extern void voyager_handle_nmi(void);
-extern void voyager_smp_intr_init(void);
-/* Commands for the following are */
-#define	VOYAGER_PSI_READ	0
-#define VOYAGER_PSI_WRITE	1
-#define VOYAGER_PSI_SUBREAD	2
-#define VOYAGER_PSI_SUBWRITE	3
-extern void voyager_cat_psi(__u8, __u16, __u8 *);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/events.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/events.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/events.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/events.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,10 +15,4 @@ static inline int xen_irqs_disabled(stru
 	return raw_irqs_disabled_flags(regs->flags);
 }
 
-static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
-{
-	regs->orig_ax = ~irq;
-	do_IRQ(regs);
-}
-
 #endif /* _ASM_X86_XEN_EVENTS_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/hypercall.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/hypercall.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/hypercall.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/hypercall.h	2009-06-09 23:05:27.000000000 -0400
@@ -296,6 +296,8 @@ HYPERVISOR_get_debugreg(int reg)
 static inline int
 HYPERVISOR_update_descriptor(u64 ma, u64 desc)
 {
+	if (sizeof(u64) == sizeof(long))
+		return _hypercall2(int, update_descriptor, ma, desc);
 	return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/hypervisor.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/hypervisor.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/hypervisor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/hypervisor.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,22 +38,30 @@ extern struct shared_info *HYPERVISOR_sh
 extern struct start_info *xen_start_info;
 
 enum xen_domain_type {
-	XEN_NATIVE,
-	XEN_PV_DOMAIN,
-	XEN_HVM_DOMAIN,
+	XEN_NATIVE,		/* running on bare hardware    */
+	XEN_PV_DOMAIN,		/* running in a PV domain      */
+	XEN_HVM_DOMAIN,		/* running in a Xen hvm domain */
 };
 
-extern enum xen_domain_type xen_domain_type;
-
 #ifdef CONFIG_XEN
-#define xen_domain()		(xen_domain_type != XEN_NATIVE)
+extern enum xen_domain_type xen_domain_type;
 #else
-#define xen_domain()		(0)
+#define xen_domain_type		XEN_NATIVE
 #endif
 
-#define xen_pv_domain()		(xen_domain() && xen_domain_type == XEN_PV_DOMAIN)
-#define xen_hvm_domain()	(xen_domain() && xen_domain_type == XEN_HVM_DOMAIN)
+#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)
 
-#define xen_initial_domain()	(xen_pv_domain() && xen_start_info->flags & SIF_INITDOMAIN)
+#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.29-gnu1/arch/x86/include/asm/xen/page.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/page.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/xen/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/xen/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -124,7 +124,8 @@ static inline unsigned long mfn_to_local
 
 /* VIRT <-> MACHINE conversion */
 #define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
-#define virt_to_mfn(v)		(pfn_to_mfn(PFN_DOWN(__pa(v))))
+#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
+#define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
 #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
 static inline unsigned long pte_mfn(pte_t pte)
@@ -164,6 +165,7 @@ static inline pte_t __pte_ma(pteval_t x)
 
 
 xmaddr_t arbitrary_virt_to_machine(void *address);
+unsigned long arbitrary_virt_to_mfn(void *vaddr);
 void make_lowmem_page_readonly(void *vaddr);
 void make_lowmem_page_readwrite(void *vaddr);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/include/asm/xsave.h linux-libre-2.6.30-gnu1/arch/x86/include/asm/xsave.h
--- linux-libre-2.6.29-gnu1/arch/x86/include/asm/xsave.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/include/asm/xsave.h	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@
 
 #define XSTATE_FP	0x1
 #define XSTATE_SSE	0x2
+#define XSTATE_YMM	0x4
 
 #define XSTATE_FPSSE	(XSTATE_FP | XSTATE_SSE)
 
@@ -15,7 +16,7 @@
 /*
  * These are the features that the OS can handle currently.
  */
-#define XCNTXT_MASK	(XSTATE_FP | XSTATE_SSE)
+#define XCNTXT_MASK	(XSTATE_FP | XSTATE_SSE | XSTATE_YMM)
 
 #ifdef CONFIG_X86_64
 #define REX_PREFIX	"0x48, "
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/Kconfig linux-libre-2.6.30-gnu1/arch/x86/Kconfig
--- linux-libre-2.6.29-gnu1/arch/x86/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@ mainmenu "Linux Kernel Configuration for
 config 64BIT
 	bool "64-bit kernel" if ARCH = "x86"
 	default ARCH = "x86_64"
-	help
+	---help---
 	  Say yes to build a 64-bit kernel - formerly known as x86_64
 	  Say no to build a 32-bit kernel - formerly known as i386
 
@@ -34,12 +34,18 @@ config X86
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
-	select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
-	select HAVE_ARCH_KGDB if !X86_VOYAGER
+	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
+	select HAVE_FTRACE_SYSCALLS
+	select HAVE_KVM
+	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_GENERIC_DMA_COHERENT if X86_32
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
 	select USER_STACKTRACE_SUPPORT
+	select HAVE_DMA_API_DEBUG
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZMA
 
 config ARCH_DEFCONFIG
 	string
@@ -133,18 +139,19 @@ config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
 config HAVE_SETUP_PER_CPU_AREA
-	def_bool X86_64_SMP || (X86_SMP && !X86_VOYAGER)
+	def_bool y
+
+config HAVE_DYNAMIC_PER_CPU_AREA
+	def_bool y
 
 config HAVE_CPUMASK_OF_CPU_MAP
 	def_bool X86_64_SMP
 
 config ARCH_HIBERNATION_POSSIBLE
 	def_bool y
-	depends on !SMP || !X86_VOYAGER
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on !X86_VOYAGER
 
 config ZONE_DMA32
 	bool
@@ -160,11 +167,17 @@ config AUDIT_ARCH
 config ARCH_SUPPORTS_OPTIMIZED_INLINING
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
 	bool
 	default y
 
+config GENERIC_HARDIRQS_NO__DO_IRQ
+       def_bool y
+
 config GENERIC_IRQ_PROBE
 	bool
 	default y
@@ -174,11 +187,6 @@ config GENERIC_PENDING_IRQ
 	depends on GENERIC_HARDIRQS && SMP
 	default y
 
-config X86_SMP
-	bool
-	depends on SMP && ((X86_32 && !X86_VOYAGER) || X86_64)
-	default y
-
 config USE_GENERIC_SMP_HELPERS
 	def_bool y
 	depends on SMP
@@ -194,19 +202,17 @@ config X86_64_SMP
 config X86_HT
 	bool
 	depends on SMP
-	depends on (X86_32 && !X86_VOYAGER) || X86_64
-	default y
-
-config X86_BIOS_REBOOT
-	bool
-	depends on !X86_VOYAGER
 	default y
 
 config X86_TRAMPOLINE
 	bool
-	depends on X86_SMP || (X86_VOYAGER && SMP) || (64BIT && ACPI_SLEEP)
+	depends on SMP || (64BIT && ACPI_SLEEP)
 	default y
 
+config X86_32_LAZY_GS
+	def_bool y
+	depends on X86_32 && !CC_STACKPROTECTOR
+
 config KTIME_SCALAR
 	def_bool X86_32
 source "init/Kconfig"
@@ -244,14 +250,21 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
-config X86_HAS_BOOT_CPU_ID
-	def_bool y
-	depends on X86_VOYAGER
+config X86_X2APIC
+	bool "Support x2apic"
+	depends on X86_LOCAL_APIC && X86_64 && INTR_REMAP
+	---help---
+	  This enables x2apic support on CPUs that have this feature.
+
+	  This allows 32-bit apic IDs (so it can support very large systems),
+	  and accesses the local apic via MSRs not via mmio.
+
+	  If you don't know what to do here, say N.
 
 config SPARSE_IRQ
 	bool "Support sparse irq numbering"
 	depends on PCI_MSI || HT_IRQ
-	help
+	---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.
@@ -264,115 +277,143 @@ config SPARSE_IRQ
 config NUMA_MIGRATE_IRQ_DESC
 	bool "Move irq desc when changing irq smp_affinity"
 	depends on SPARSE_IRQ && NUMA
+	depends on BROKEN
 	default n
-	help
+	---help---
 	  This enables moving irq_desc to cpu/node that irq will use handled.
 
 	  If you don't know what to do here, say N.
 
-config X86_FIND_SMP_CONFIG
-	def_bool y
-	depends on X86_MPPARSE || X86_VOYAGER
-
 config X86_MPPARSE
 	bool "Enable MPS table" if ACPI
 	default y
 	depends on X86_LOCAL_APIC
-	help
+	---help---
 	  For old smp systems that do not have proper acpi support. Newer systems
 	  (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
 
-choice
-	prompt "Subarchitecture Type"
-	default X86_PC
+config X86_BIGSMP
+	bool "Support for big SMP systems with more than 8 CPUs"
+	depends on X86_32 && SMP
+	---help---
+	  This option is needed for the systems that have more than 8 CPUs
 
-config X86_PC
-	bool "PC-compatible"
-	help
-	  Choose this option if your computer is a standard PC or compatible.
+if X86_32
+config X86_EXTENDED_PLATFORM
+	bool "Support for extended (non-PC) x86 platforms"
+	default y
+	---help---
+	  If you disable this option then the kernel will only support
+	  standard PC platforms. (which covers the vast majority of
+	  systems out there.)
+
+	  If you enable this option then you'll be able to select support
+	  for the following (non-PC) 32 bit x86 platforms:
+		AMD Elan
+		NUMAQ (IBM/Sequent)
+		RDC R-321x SoC
+		SGI 320/540 (Visual Workstation)
+		Summit/EXA (IBM x440)
+		Unisys ES7000 IA32 series
+
+	  If you have one of these systems, or if you want to build a
+	  generic distribution kernel, say Y here - otherwise say N.
+endif
+
+if X86_64
+config X86_EXTENDED_PLATFORM
+	bool "Support for extended (non-PC) x86 platforms"
+	default y
+	---help---
+	  If you disable this option then the kernel will only support
+	  standard PC platforms. (which covers the vast majority of
+	  systems out there.)
+
+	  If you enable this option then you'll be able to select support
+	  for the following (non-PC) 64 bit x86 platforms:
+		ScaleMP vSMP
+		SGI Ultraviolet
+
+	  If you have one of these systems, or if you want to build a
+	  generic distribution kernel, say Y here - otherwise say N.
+endif
+# This is an alphabetically sorted list of 64 bit extended platforms
+# Please maintain the alphabetic order if and when there are additions
+
+config X86_VSMP
+	bool "ScaleMP vSMP"
+	select PARAVIRT
+	depends on X86_64 && PCI
+	depends on X86_EXTENDED_PLATFORM
+	---help---
+	  Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
+	  supposed to run on these EM64T-based machines.  Only choose this option
+	  if you have one of these machines.
+
+config X86_UV
+	bool "SGI Ultraviolet"
+	depends on X86_64
+	depends on X86_EXTENDED_PLATFORM
+	depends on NUMA
+	select X86_X2APIC
+	---help---
+	  This option is needed in order to support SGI Ultraviolet systems.
+	  If you don't have one of these, you should say N here.
+
+# Following is an alphabetically sorted list of 32 bit extended platforms
+# Please maintain the alphabetic order if and when there are additions
 
 config X86_ELAN
 	bool "AMD Elan"
 	depends on X86_32
-	help
+	depends on X86_EXTENDED_PLATFORM
+	---help---
 	  Select this for an AMD Elan processor.
 
 	  Do not use this option for K6/Athlon/Opteron processors!
 
 	  If unsure, choose "PC-compatible" instead.
 
-config X86_VOYAGER
-	bool "Voyager (NCR)"
-	depends on X86_32 && (SMP || BROKEN) && !PCI
-	help
-	  Voyager is an MCA-based 32-way capable SMP architecture proprietary
-	  to NCR Corp.  Machine classes 345x/35xx/4100/51xx are Voyager-based.
-
-	  *** WARNING ***
-
-	  If you do not specifically know you have a Voyager based machine,
-	  say N here, otherwise the kernel you build will not be bootable.
-
-config X86_GENERICARCH
-       bool "Generic architecture"
+config X86_RDC321X
+	bool "RDC R-321x SoC"
 	depends on X86_32
-       help
-          This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
+	depends on X86_EXTENDED_PLATFORM
+	select M486
+	select X86_REBOOTFIXUPS
+	---help---
+	  This option is needed for RDC R-321x system-on-chip, also known
+	  as R-8610-(G).
+	  If you don't have one of these chips, you should say N here.
+
+config X86_32_NON_STANDARD
+	bool "Support non-standard 32-bit SMP architectures"
+	depends on X86_32 && SMP
+	depends on X86_EXTENDED_PLATFORM
+	---help---
+	  This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
 	  subarchitectures.  It is intended for a generic binary kernel.
 	  if you select them all, kernel will probe it one by one. and will
 	  fallback to default.
 
-if X86_GENERICARCH
+# Alphabetically sorted list of Non standard 32 bit platforms
 
 config X86_NUMAQ
 	bool "NUMAQ (IBM/Sequent)"
-	depends on SMP && X86_32 && PCI && X86_MPPARSE
+	depends on X86_32_NON_STANDARD
 	select NUMA
-	help
+	select X86_MPPARSE
+	---help---
 	  This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
 	  NUMA multiquad box. This changes the way that processors are
 	  bootstrapped, and uses Clustered Logical APIC addressing mode instead
 	  of Flat Logical.  You will need a new lynxer.elf file to flash your
 	  firmware with - send email to <Martin.Bligh@us.ibm.com>.
 
-config X86_SUMMIT
-	bool "Summit/EXA (IBM x440)"
-	depends on X86_32 && SMP
-	help
-	  This option is needed for IBM systems that use the Summit/EXA chipset.
-	  In particular, it is needed for the x440.
-
-config X86_ES7000
-	bool "Support for Unisys ES7000 IA32 series"
-	depends on X86_32 && SMP
-	help
-	  Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
-	  supposed to run on an IA32-based Unisys ES7000 system.
-
-config X86_BIGSMP
-	bool "Support for big SMP systems with more than 8 CPUs"
-	depends on X86_32 && SMP
-	help
-	  This option is needed for the systems that have more than 8 CPUs
-	  and if the system is not of any sub-arch type above.
-
-endif
-
-config X86_VSMP
-	bool "Support for ScaleMP vSMP"
-	select PARAVIRT
-	depends on X86_64 && PCI
-	help
-	  Support for ScaleMP vSMP systems.  Say 'Y' here if this kernel is
-	  supposed to run on these EM64T-based machines.  Only choose this option
-	  if you have one of these machines.
-
-endchoice
-
 config X86_VISWS
 	bool "SGI 320/540 (Visual Workstation)"
-	depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE && PCI_GODIRECT
-	help
+	depends on X86_32 && PCI && X86_MPPARSE && PCI_GODIRECT
+	depends on X86_32_NON_STANDARD
+	---help---
 	  The SGI Visual Workstation series is an IA32-based workstation
 	  based on SGI systems chips with some legacy PC hardware attached.
 
@@ -381,21 +422,25 @@ config X86_VISWS
 	  A kernel compiled for the Visual Workstation will run on general
 	  PCs as well. See <file:Documentation/sgi-visws.txt> for details.
 
-config X86_RDC321X
-	bool "RDC R-321x SoC"
-	depends on X86_32
-	select M486
-	select X86_REBOOTFIXUPS
-	help
-	  This option is needed for RDC R-321x system-on-chip, also known
-	  as R-8610-(G).
-	  If you don't have one of these chips, you should say N here.
+config X86_SUMMIT
+	bool "Summit/EXA (IBM x440)"
+	depends on X86_32_NON_STANDARD
+	---help---
+	  This option is needed for IBM systems that use the Summit/EXA chipset.
+	  In particular, it is needed for the x440.
+
+config X86_ES7000
+	bool "Unisys ES7000 IA32 series"
+	depends on X86_32_NON_STANDARD && X86_BIGSMP
+	---help---
+	  Support for Unisys ES7000 systems.  Say 'Y' here if this kernel is
+	  supposed to run on an IA32-based Unisys ES7000 system.
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
 	prompt "Single-depth WCHAN output"
 	depends on X86
-	help
+	---help---
 	  Calculate simpler /proc/<PID>/wchan values. If this option
 	  is disabled then wchan values will recurse back to the
 	  caller function. This provides more accurate wchan values,
@@ -405,7 +450,7 @@ config SCHED_OMIT_FRAME_POINTER
 
 menuconfig PARAVIRT_GUEST
 	bool "Paravirtualized guest support"
-	help
+	---help---
 	  Say Y here to get to see options related to running Linux under
 	  various hypervisors.  This option alone does not add any kernel code.
 
@@ -419,8 +464,7 @@ config VMI
 	bool "VMI Guest support"
 	select PARAVIRT
 	depends on X86_32
-	depends on !X86_VOYAGER
-	help
+	---help---
 	  VMI provides a paravirtualized interface to the VMware ESX server
 	  (it could be used by other hypervisors in theory too, but is not
 	  at the moment), by linking the kernel to a GPL-ed ROM module
@@ -430,8 +474,7 @@ config KVM_CLOCK
 	bool "KVM paravirtualized clock"
 	select PARAVIRT
 	select PARAVIRT_CLOCK
-	depends on !X86_VOYAGER
-	help
+	---help---
 	  Turning on this option will allow you to run a paravirtualized clock
 	  when running over the KVM hypervisor. Instead of relying on a PIT
 	  (or probably other) emulation by the underlying device model, the host
@@ -441,22 +484,33 @@ config KVM_CLOCK
 config KVM_GUEST
 	bool "KVM Guest support"
 	select PARAVIRT
-	depends on !X86_VOYAGER
-	help
-	 This option enables various optimizations for running under the KVM
-	 hypervisor.
+	---help---
+	  This option enables various optimizations for running under the KVM
+	  hypervisor.
 
 source "arch/x86/lguest/Kconfig"
 
 config PARAVIRT
 	bool "Enable paravirtualization code"
-	depends on !X86_VOYAGER
-	help
+	---help---
 	  This changes the kernel so it can modify itself when it is run
 	  under a hypervisor, potentially improving performance significantly
 	  over full virtualization.  However, when run without a hypervisor
 	  the kernel is theoretically slower and slightly larger.
 
+config PARAVIRT_SPINLOCKS
+	bool "Paravirtualization layer for spinlocks"
+	depends on PARAVIRT && SMP && EXPERIMENTAL
+	---help---
+	  Paravirtualized spinlocks allow a pvops backend to replace the
+	  spinlock implementation with something virtualization-friendly
+	  (for example, block the virtual CPU rather than spinning).
+
+	  Unfortunately the downside is an up to 5% performance hit on
+	  native kernels, with various workloads.
+
+	  If you are unsure how to answer this question, answer N.
+
 config PARAVIRT_CLOCK
 	bool
 	default n
@@ -464,51 +518,51 @@ config PARAVIRT_CLOCK
 endif
 
 config PARAVIRT_DEBUG
-       bool "paravirt-ops debugging"
-       depends on PARAVIRT && DEBUG_KERNEL
-       help
-         Enable to debug paravirt_ops internals.  Specifically, BUG if
-	 a paravirt_op is missing when it is called.
+	bool "paravirt-ops debugging"
+	depends on PARAVIRT && DEBUG_KERNEL
+	---help---
+	  Enable to debug paravirt_ops internals.  Specifically, BUG if
+	  a paravirt_op is missing when it is called.
 
 config MEMTEST
 	bool "Memtest"
-	help
+	---help---
 	  This option adds a kernel parameter 'memtest', which allows memtest
 	  to be set.
-		memtest=0, mean disabled; -- default
-		memtest=1, mean do 1 test pattern;
-		...
-		memtest=4, mean do 4 test patterns.
+	        memtest=0, mean disabled; -- default
+	        memtest=1, mean do 1 test pattern;
+	        ...
+	        memtest=4, mean do 4 test patterns.
 	  If you are unsure how to answer this question, answer N.
 
 config X86_SUMMIT_NUMA
 	def_bool y
-	depends on X86_32 && NUMA && X86_GENERICARCH
+	depends on X86_32 && NUMA && X86_32_NON_STANDARD
 
 config X86_CYCLONE_TIMER
 	def_bool y
-	depends on X86_GENERICARCH
+	depends on X86_32_NON_STANDARD
 
 source "arch/x86/Kconfig.cpu"
 
 config HPET_TIMER
 	def_bool X86_64
 	prompt "HPET Timer Support" if X86_32
-	help
-         Use the IA-PC HPET (High Precision Event Timer) to manage
-         time in preference to the PIT and RTC, if a HPET is
-         present.
-         HPET is the next generation timer replacing legacy 8254s.
-         The HPET provides a stable time base on SMP
-         systems, unlike the TSC, but it is more expensive to access,
-         as it is off-chip.  You can find the HPET spec at
-         <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
+	---help---
+	  Use the IA-PC HPET (High Precision Event Timer) to manage
+	  time in preference to the PIT and RTC, if a HPET is
+	  present.
+	  HPET is the next generation timer replacing legacy 8254s.
+	  The HPET provides a stable time base on SMP
+	  systems, unlike the TSC, but it is more expensive to access,
+	  as it is off-chip.  You can find the HPET spec at
+	  <http://www.intel.com/hardwaredesign/hpetspec_1.pdf>.
 
-         You can safely choose Y here.  However, HPET will only be
-         activated if the platform and the BIOS support this feature.
-         Otherwise the 8254 will be used for timing services.
+	  You can safely choose Y here.  However, HPET will only be
+	  activated if the platform and the BIOS support this feature.
+	  Otherwise the 8254 will be used for timing services.
 
-         Choose N to continue using the legacy 8254 timer.
+	  Choose N to continue using the legacy 8254 timer.
 
 config HPET_EMULATE_RTC
 	def_bool y
@@ -519,7 +573,7 @@ config HPET_EMULATE_RTC
 config DMI
 	default y
 	bool "Enable DMI scanning" if EMBEDDED
-	help
+	---help---
 	  Enabled scanning of DMI to identify machine quirks. Say Y
 	  here unless you have verified that your setup is not
 	  affected by entries in the DMI blacklist. Required by PNP
@@ -531,7 +585,7 @@ config GART_IOMMU
 	select SWIOTLB
 	select AGP
 	depends on X86_64 && PCI
-	help
+	---help---
 	  Support for full DMA access of devices with 32bit memory access only
 	  on systems with more than 3GB. This is usually needed for USB,
 	  sound, many IDE/SATA chipsets and some other devices.
@@ -546,7 +600,7 @@ config CALGARY_IOMMU
 	bool "IBM Calgary IOMMU support"
 	select SWIOTLB
 	depends on X86_64 && PCI && EXPERIMENTAL
-	help
+	---help---
 	  Support for hardware IOMMUs in IBM's xSeries x366 and x460
 	  systems. Needed to run systems with more than 3GB of memory
 	  properly with 32-bit PCI devices that do not support DAC
@@ -564,7 +618,7 @@ config CALGARY_IOMMU_ENABLED_BY_DEFAULT
 	def_bool y
 	prompt "Should Calgary be enabled by default?"
 	depends on CALGARY_IOMMU
-	help
+	---help---
 	  Should Calgary be enabled by default? if you choose 'y', Calgary
 	  will be used (if it exists). If you choose 'n', Calgary will not be
 	  used even if it exists. If you choose 'n' and would like to use
@@ -576,7 +630,7 @@ config AMD_IOMMU
 	select SWIOTLB
 	select PCI_MSI
 	depends on X86_64 && PCI && ACPI
-	help
+	---help---
 	  With this option you can enable support for AMD IOMMU hardware in
 	  your system. An IOMMU is a hardware component which provides
 	  remapping of DMA memory accesses from devices. With an AMD IOMMU you
@@ -591,7 +645,7 @@ config AMD_IOMMU_STATS
 	bool "Export AMD IOMMU statistics to debugfs"
 	depends on AMD_IOMMU
 	select DEBUG_FS
-	help
+	---help---
 	  This option enables code in the AMD IOMMU driver to collect various
 	  statistics about whats happening in the driver and exports that
 	  information to userspace via debugfs.
@@ -600,7 +654,7 @@ config AMD_IOMMU_STATS
 # need this always selected by IOMMU for the VIA workaround
 config SWIOTLB
 	def_bool y if X86_64
-	help
+	---help---
 	  Support for software bounce buffers used on x86-64 systems
 	  which don't have a hardware IOMMU (e.g. the current generation
 	  of Intel's x86-64 CPUs). Using this PCI devices which can only
@@ -618,18 +672,19 @@ config MAXSMP
 	depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
 	select CPUMASK_OFFSTACK
 	default n
-	help
+	---help---
 	  Configure maximum number of CPUS and NUMA Nodes for this architecture.
 	  If unsure, say N.
 
 config NR_CPUS
 	int "Maximum number of CPUs" if SMP && !MAXSMP
+	range 2 8 if SMP && X86_32 && !X86_BIGSMP
 	range 2 512 if SMP && !MAXSMP
 	default "1" if !SMP
 	default "4096" if MAXSMP
 	default "32" if SMP && (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000)
 	default "8" if SMP
-	help
+	---help---
 	  This allows you to specify the maximum number of CPUs which this
 	  kernel will support.  The maximum supported value is 512 and the
 	  minimum value which makes sense is 2.
@@ -640,7 +695,7 @@ config NR_CPUS
 config SCHED_SMT
 	bool "SMT (Hyperthreading) scheduler support"
 	depends on X86_HT
-	help
+	---help---
 	  SMT scheduler support improves the CPU scheduler's decision making
 	  when dealing with Intel Pentium 4 chips with HyperThreading at a
 	  cost of slightly increased overhead in some places. If unsure say
@@ -650,7 +705,7 @@ config SCHED_MC
 	def_bool y
 	prompt "Multi-core scheduler support"
 	depends on X86_HT
-	help
+	---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.
@@ -659,8 +714,8 @@ source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
 	bool "Local APIC support on uniprocessors"
-	depends on X86_32 && !SMP && !(X86_VOYAGER || X86_GENERICARCH)
-	help
+	depends on X86_32 && !SMP && !X86_32_NON_STANDARD
+	---help---
 	  A local APIC (Advanced Programmable Interrupt Controller) is an
 	  integrated interrupt controller in the CPU. If you have a single-CPU
 	  system which has a processor with a local APIC, you can say Y here to
@@ -673,7 +728,7 @@ config X86_UP_APIC
 config X86_UP_IOAPIC
 	bool "IO-APIC support on uniprocessors"
 	depends on X86_UP_APIC
-	help
+	---help---
 	  An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
 	  SMP-capable replacement for PC-style interrupt controllers. Most
 	  SMP systems and many recent uniprocessor systems have one.
@@ -684,11 +739,11 @@ config X86_UP_IOAPIC
 
 config X86_LOCAL_APIC
 	def_bool y
-	depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
+	depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
 
 config X86_IO_APIC
 	def_bool y
-	depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
+	depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
 
 config X86_VISWS_APIC
 	def_bool y
@@ -698,7 +753,7 @@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
 	bool "Reroute for broken boot IRQs"
 	default n
 	depends on X86_IO_APIC
-	help
+	---help---
 	  This option enables a workaround that fixes a source of
 	  spurious interrupts. This is recommended when threaded
 	  interrupt handling is used on systems where the generation of
@@ -720,7 +775,6 @@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
 
 config X86_MCE
 	bool "Machine Check Exception"
-	depends on !X86_VOYAGER
 	---help---
 	  Machine Check Exception support allows the processor to notify the
 	  kernel if it detects a problem (e.g. overheating, component failure).
@@ -739,7 +793,7 @@ config X86_MCE_INTEL
 	def_bool y
 	prompt "Intel MCE features"
 	depends on X86_64 && X86_MCE && X86_LOCAL_APIC
-	help
+	---help---
 	   Additional support for intel specific MCE features such as
 	   the thermal monitor.
 
@@ -747,14 +801,19 @@ config X86_MCE_AMD
 	def_bool y
 	prompt "AMD MCE features"
 	depends on X86_64 && X86_MCE && X86_LOCAL_APIC
-	help
+	---help---
 	   Additional support for AMD specific MCE features such as
 	   the DRAM Error Threshold.
 
+config X86_MCE_THRESHOLD
+	depends on X86_MCE_AMD || X86_MCE_INTEL
+	bool
+	default y
+
 config X86_MCE_NONFATAL
 	tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
 	depends on X86_32 && X86_MCE
-	help
+	---help---
 	  Enabling this feature starts a timer that triggers every 5 seconds which
 	  will look at the machine check registers to see if anything happened.
 	  Non-fatal problems automatically get corrected (but still logged).
@@ -767,7 +826,7 @@ config X86_MCE_NONFATAL
 config X86_MCE_P4THERMAL
 	bool "check for P4 thermal throttling interrupt."
 	depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP)
-	help
+	---help---
 	  Enabling this feature will cause a message to be printed when the P4
 	  enters thermal throttling.
 
@@ -775,11 +834,11 @@ config VM86
 	bool "Enable VM86 support" if EMBEDDED
 	default y
 	depends on X86_32
-	help
-          This option is required by programs like DOSEMU to run 16-bit legacy
+	---help---
+	  This option is required by programs like DOSEMU to run 16-bit legacy
 	  code on X86 processors. It also may be needed by software like
-          XFree86 to initialize some video cards via BIOS. Disabling this
-          option saves about 6k.
+	  XFree86 to initialize some video cards via BIOS. Disabling this
+	  option saves about 6k.
 
 config TOSHIBA
 	tristate "Toshiba Laptop support"
@@ -853,33 +912,33 @@ config MICROCODE
 	  module will be called microcode.
 
 config MICROCODE_INTEL
-       bool "Intel microcode patch loading support"
-       depends on MICROCODE
-       default MICROCODE
-       select FW_LOADER
-       --help---
-         This options enables microcode patch loading support for Intel
-         processors.
+	bool "Intel microcode patch loading support"
+	depends on MICROCODE
+	default MICROCODE
+	select FW_LOADER
+	---help---
+	  This options enables microcode patch loading support for Intel
+	  processors.
 
-         For latest news and information on obtaining all the required
-         Intel ingredients for this driver, check:
-         <http://www.urbanmyth.org/microcode/>.
+	  For latest news and information on obtaining all the required
+	  Intel ingredients for this driver, check:
+	  <http://www.urbanmyth.org/microcode/>.
 
 config MICROCODE_AMD
-       bool "AMD microcode patch loading support"
-       depends on MICROCODE
-       select FW_LOADER
-       --help---
-         If you select this option, microcode patch loading support for AMD
-	 processors will be enabled.
+	bool "AMD microcode patch loading support"
+	depends on MICROCODE
+	select FW_LOADER
+	---help---
+	  If you select this option, microcode patch loading support for AMD
+	  processors will be enabled.
 
-   config MICROCODE_OLD_INTERFACE
+config MICROCODE_OLD_INTERFACE
 	def_bool y
 	depends on MICROCODE
 
 config X86_MSR
 	tristate "/dev/cpu/*/msr - Model-specific register support"
-	help
+	---help---
 	  This device gives privileged processes access to the x86
 	  Model-Specific Registers (MSRs).  It is a character device with
 	  major 202 and minors 0 to 31 for /dev/cpu/0/msr to /dev/cpu/31/msr.
@@ -888,12 +947,18 @@ config X86_MSR
 
 config X86_CPUID
 	tristate "/dev/cpu/*/cpuid - CPU information support"
-	help
+	---help---
 	  This device gives processes access to the x86 CPUID instruction to
 	  be executed on a specific processor.  It is a character device
 	  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
@@ -940,7 +1005,7 @@ config NOHIGHMEM
 config HIGHMEM4G
 	bool "4GB"
 	depends on !X86_NUMAQ
-	help
+	---help---
 	  Select this if you have a 32-bit processor and between 1 and 4
 	  gigabytes of physical RAM.
 
@@ -948,7 +1013,7 @@ config HIGHMEM64G
 	bool "64GB"
 	depends on !M386 && !M486
 	select X86_PAE
-	help
+	---help---
 	  Select this if you have a 32-bit processor and more than 4
 	  gigabytes of physical RAM.
 
@@ -959,7 +1024,7 @@ choice
 	prompt "Memory split" if EMBEDDED
 	default VMSPLIT_3G
 	depends on X86_32
-	help
+	---help---
 	  Select the desired split between kernel and user memory.
 
 	  If the address range available to the kernel is less than the
@@ -1005,20 +1070,20 @@ config HIGHMEM
 config X86_PAE
 	bool "PAE (Physical Address Extension) Support"
 	depends on X86_32 && !HIGHMEM4G
-	help
+	---help---
 	  PAE is required for NX support, and furthermore enables
 	  larger swapspace support for non-overcommit purposes. It
 	  has the cost of more pagetable lookup overhead, and also
 	  consumes more pagetable space per process.
 
 config ARCH_PHYS_ADDR_T_64BIT
-       def_bool X86_64 || X86_PAE
+	def_bool X86_64 || X86_PAE
 
 config DIRECT_GBPAGES
 	bool "Enable 1GB pages for kernel pagetables" if EMBEDDED
 	default y
 	depends on X86_64
-	help
+	---help---
 	  Allow the kernel linear mapping to use 1GB pages on CPUs that
 	  support it. This can improve the kernel's performance a tiny bit by
 	  reducing TLB pressure. If in doubt, say "Y".
@@ -1028,9 +1093,8 @@ config NUMA
 	bool "Numa Memory Allocation and Scheduler Support"
 	depends on SMP
 	depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && EXPERIMENTAL)
-	default n if X86_PC
 	default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP)
-	help
+	---help---
 	  Enable NUMA (Non Uniform Memory Access) support.
 
 	  The kernel will try to allocate memory used by a CPU on the
@@ -1053,19 +1117,19 @@ config K8_NUMA
 	def_bool y
 	prompt "Old style AMD Opteron NUMA detection"
 	depends on X86_64 && NUMA && PCI
-	help
-	 Enable K8 NUMA node topology detection.  You should say Y here if
-	 you have a multi processor AMD K8 system. This uses an old
-	 method to read the NUMA configuration directly from the builtin
-	 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
-	 instead, which also takes priority if both are compiled in.
+	---help---
+	  Enable K8 NUMA node topology detection.  You should say Y here if
+	  you have a multi processor AMD K8 system. This uses an old
+	  method to read the NUMA configuration directly from the builtin
+	  Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
+	  instead, which also takes priority if both are compiled in.
 
 config X86_64_ACPI_NUMA
 	def_bool y
 	prompt "ACPI NUMA detection"
 	depends on X86_64 && NUMA && ACPI && PCI
 	select ACPI_NUMA
-	help
+	---help---
 	  Enable ACPI SRAT based node topology detection.
 
 # Some NUMA nodes have memory ranges that span
@@ -1080,24 +1144,24 @@ config NODES_SPAN_OTHER_NODES
 config NUMA_EMU
 	bool "NUMA emulation"
 	depends on X86_64 && NUMA
-	help
+	---help---
 	  Enable NUMA emulation. A flat machine will be split
 	  into virtual nodes when booted with "numa=fake=N", where N is the
 	  number of nodes. This is only useful for debugging.
 
 config NODES_SHIFT
 	int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
-	range 1 9   if X86_64
+	range 1 9
 	default "9" if MAXSMP
 	default "6" if X86_64
 	default "4" if X86_NUMAQ
 	default "3"
 	depends on NEED_MULTIPLE_NODES
-	help
+	---help---
 	  Specify the maximum number of NUMA Nodes available on the target
-	  system.  Increases memory reserved to accomodate various tables.
+	  system.  Increases memory reserved to accommodate various tables.
 
-config HAVE_ARCH_BOOTMEM_NODE
+config HAVE_ARCH_BOOTMEM
 	def_bool y
 	depends on X86_32 && NUMA
 
@@ -1131,7 +1195,7 @@ config ARCH_SPARSEMEM_DEFAULT
 
 config ARCH_SPARSEMEM_ENABLE
 	def_bool y
-	depends on X86_64 || NUMA || (EXPERIMENTAL && X86_PC) || X86_GENERICARCH
+	depends on X86_64 || NUMA || (EXPERIMENTAL && X86_32) || X86_32_NON_STANDARD
 	select SPARSEMEM_STATIC if X86_32
 	select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 
@@ -1148,61 +1212,61 @@ source "mm/Kconfig"
 config HIGHPTE
 	bool "Allocate 3rd-level pagetables from highmem"
 	depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
-	help
+	---help---
 	  The VM uses one page table entry for each page of physical memory.
 	  For systems with a lot of RAM, this can be wasteful of precious
 	  low memory.  Setting this option will put user-space page table
 	  entries in high memory.
 
 config X86_CHECK_BIOS_CORRUPTION
-        bool "Check for low memory corruption"
-	help
-	 Periodically check for memory corruption in low memory, which
-	 is suspected to be caused by BIOS.  Even when enabled in the
-	 configuration, it is disabled at runtime.  Enable it by
-	 setting "memory_corruption_check=1" on the kernel command
-	 line.  By default it scans the low 64k of memory every 60
-	 seconds; see the memory_corruption_check_size and
-	 memory_corruption_check_period parameters in
-	 Documentation/kernel-parameters.txt to adjust this.
+	bool "Check for low memory corruption"
+	---help---
+	  Periodically check for memory corruption in low memory, which
+	  is suspected to be caused by BIOS.  Even when enabled in the
+	  configuration, it is disabled at runtime.  Enable it by
+	  setting "memory_corruption_check=1" on the kernel command
+	  line.  By default it scans the low 64k of memory every 60
+	  seconds; see the memory_corruption_check_size and
+	  memory_corruption_check_period parameters in
+	  Documentation/kernel-parameters.txt to adjust this.
 
-	 When enabled with the default parameters, this option has
-	 almost no overhead, as it reserves a relatively small amount
-	 of memory and scans it infrequently.  It both detects corruption
-	 and prevents it from affecting the running system.
+	  When enabled with the default parameters, this option has
+	  almost no overhead, as it reserves a relatively small amount
+	  of memory and scans it infrequently.  It both detects corruption
+	  and prevents it from affecting the running system.
 
-	 It is, however, intended as a diagnostic tool; if repeatable
-	 BIOS-originated corruption always affects the same memory,
-	 you can use memmap= to prevent the kernel from using that
-	 memory.
+	  It is, however, intended as a diagnostic tool; if repeatable
+	  BIOS-originated corruption always affects the same memory,
+	  you can use memmap= to prevent the kernel from using that
+	  memory.
 
 config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
-        bool "Set the default setting of memory_corruption_check"
+	bool "Set the default setting of memory_corruption_check"
 	depends on X86_CHECK_BIOS_CORRUPTION
 	default y
-	help
-	 Set whether the default state of memory_corruption_check is
-	 on or off.
+	---help---
+	  Set whether the default state of memory_corruption_check is
+	  on or off.
 
 config X86_RESERVE_LOW_64K
-        bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
+	bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
 	default y
-	help
-	 Reserve the first 64K of physical RAM on BIOSes that are known
-	 to potentially corrupt that memory range. A numbers of BIOSes are
-	 known to utilize this area during suspend/resume, so it must not
-	 be used by the kernel.
+	---help---
+	  Reserve the first 64K of physical RAM on BIOSes that are known
+	  to potentially corrupt that memory range. A numbers of BIOSes are
+	  known to utilize this area during suspend/resume, so it must not
+	  be used by the kernel.
 
-	 Set this to N if you are absolutely sure that you trust the BIOS
-	 to get all its memory reservations and usages right.
+	  Set this to N if you are absolutely sure that you trust the BIOS
+	  to get all its memory reservations and usages right.
 
-	 If you have doubts about the BIOS (e.g. suspend/resume does not
-	 work or there's kernel crashes after certain hardware hotplug
-	 events) and it's not AMI or Phoenix, then you might want to enable
-	 X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
-	 corruption patterns.
+	  If you have doubts about the BIOS (e.g. suspend/resume does not
+	  work or there's kernel crashes after certain hardware hotplug
+	  events) and it's not AMI or Phoenix, then you might want to enable
+	  X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
+	  corruption patterns.
 
-	 Say Y if unsure.
+	  Say Y if unsure.
 
 config MATH_EMULATION
 	bool
@@ -1268,12 +1332,12 @@ config MTRR_SANITIZER
 	def_bool y
 	prompt "MTRR cleanup support"
 	depends on MTRR
-	help
+	---help---
 	  Convert MTRR layout from continuous to discrete, so X drivers can
 	  add writeback entries.
 
 	  Can be disabled with disable_mtrr_cleanup on the kernel command line.
-	  The largest mtrr entry size for a continous block can be set with
+	  The largest mtrr entry size for a continuous block can be set with
 	  mtrr_chunk_size.
 
 	  If unsure, say Y.
@@ -1283,7 +1347,7 @@ config MTRR_SANITIZER_ENABLE_DEFAULT
 	range 0 1
 	default "0"
 	depends on MTRR_SANITIZER
-	help
+	---help---
 	  Enable mtrr cleanup default value
 
 config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
@@ -1291,7 +1355,7 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAU
 	range 0 7
 	default "1"
 	depends on MTRR_SANITIZER
-	help
+	---help---
 	  mtrr cleanup spare entries default, it can be changed via
 	  mtrr_spare_reg_nr=N on the kernel command line.
 
@@ -1299,7 +1363,7 @@ config X86_PAT
 	bool
 	prompt "x86 PAT support"
 	depends on MTRR
-	help
+	---help---
 	  Use PAT attributes to setup page level cache control.
 
 	  PATs are the modern equivalents of MTRRs and are much more
@@ -1314,20 +1378,20 @@ config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
 	---help---
-	This enables the kernel to use EFI runtime services that are
-	available (such as the EFI variable services).
+	  This enables the kernel to use EFI runtime services that are
+	  available (such as the EFI variable services).
 
-	This option is only useful on systems that have EFI firmware.
-  	In addition, you should use the latest ELILO loader available
-  	at <http://elilo.sourceforge.net> in order to take advantage
-  	of EFI runtime services. However, even with this option, the
-  	resultant kernel should continue to boot on existing non-EFI
-  	platforms.
+	  This option is only useful on systems that have EFI firmware.
+	  In addition, you should use the latest ELILO loader available
+	  at <http://elilo.sourceforge.net> in order to take advantage
+	  of EFI runtime services. However, even with this option, the
+	  resultant kernel should continue to boot on existing non-EFI
+	  platforms.
 
 config SECCOMP
 	def_bool y
 	prompt "Enable seccomp to safely compute untrusted bytecode"
-	help
+	---help---
 	  This kernel feature is useful for number crunching applications
 	  that may need to compute untrusted bytecode during their
 	  execution. By using pipes or other transports made available to
@@ -1340,13 +1404,16 @@ config SECCOMP
 
 	  If unsure, say Y. Only embedded should say N here.
 
+config CC_STACKPROTECTOR_ALL
+	bool
+
 config CC_STACKPROTECTOR
 	bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
-	depends on X86_64 && EXPERIMENTAL && BROKEN
-	help
-         This option turns on the -fstack-protector GCC feature. This
-	  feature puts, at the beginning of critical functions, a canary
-	  value on the stack just before the return address, and validates
+	select CC_STACKPROTECTOR_ALL
+	---help---
+	  This option turns on the -fstack-protector GCC feature. This
+	  feature puts, at the beginning of functions, a canary value on
+	  the stack just before the return address, and validates
 	  the value just before actually returning.  Stack based buffer
 	  overflows (that need to overwrite this return address) now also
 	  overwrite the canary, which gets detected and the attack is then
@@ -1354,22 +1421,14 @@ config CC_STACKPROTECTOR
 
 	  This feature requires gcc version 4.2 or above, or a distribution
 	  gcc with the feature backported. Older versions are automatically
-	  detected and for those versions, this configuration option is ignored.
-
-config CC_STACKPROTECTOR_ALL
-	bool "Use stack-protector for all functions"
-	depends on CC_STACKPROTECTOR
-	help
-	  Normally, GCC only inserts the canary value protection for
-	  functions that use large-ish on-stack buffers. By enabling
-	  this option, GCC will be asked to do this for ALL functions.
+	  detected and for those versions, this configuration option is
+	  ignored. (and a warning is printed during bootup)
 
 source kernel/Kconfig.hz
 
 config KEXEC
 	bool "kexec system call"
-	depends on X86_BIOS_REBOOT
-	help
+	---help---
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
 	  but it is independent of the system firmware.   And like a reboot
@@ -1386,7 +1445,7 @@ config KEXEC
 config CRASH_DUMP
 	bool "kernel crash dumps"
 	depends on X86_64 || (X86_32 && HIGHMEM)
-	help
+	---help---
 	  Generate crash dump after being started by kexec.
 	  This should be normally only set in special crash dump kernels
 	  which are loaded in the main kernel with kexec-tools into
@@ -1400,8 +1459,8 @@ config CRASH_DUMP
 config KEXEC_JUMP
 	bool "kexec jump (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
-	depends on KEXEC && HIBERNATION && X86_32
-	help
+	depends on KEXEC && HIBERNATION
+	---help---
 	  Jump between original kernel and kexeced kernel and invoke
 	  code in physical address mode via KEXEC
 
@@ -1410,7 +1469,7 @@ config PHYSICAL_START
 	default "0x1000000" if X86_NUMAQ
 	default "0x200000" if X86_64
 	default "0x100000"
-	help
+	---help---
 	  This gives the physical address where the kernel is loaded.
 
 	  If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
@@ -1451,7 +1510,7 @@ config PHYSICAL_START
 config RELOCATABLE
 	bool "Build a relocatable kernel (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
-	help
+	---help---
 	  This builds a kernel image that retains relocation information
 	  so it can be loaded someplace besides the default 1MB.
 	  The relocations tend to make the kernel binary about 10% larger,
@@ -1471,7 +1530,7 @@ config PHYSICAL_ALIGN
 	default "0x100000" if X86_32
 	default "0x200000" if X86_64
 	range 0x2000 0x400000
-	help
+	---help---
 	  This value puts the alignment restrictions on physical address
 	  where kernel is loaded and run from. Kernel is compiled for an
 	  address which meets above alignment restriction.
@@ -1492,7 +1551,7 @@ config PHYSICAL_ALIGN
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG && !X86_VOYAGER
+	depends on SMP && HOTPLUG
 	---help---
 	  Say Y here to allow turning CPUs off and on. CPUs can be
 	  controlled through /sys/devices/system/cpu.
@@ -1504,7 +1563,7 @@ config COMPAT_VDSO
 	def_bool y
 	prompt "Compat VDSO support"
 	depends on X86_32 || IA32_EMULATION
-	help
+	---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
@@ -1516,7 +1575,7 @@ config COMPAT_VDSO
 config CMDLINE_BOOL
 	bool "Built-in kernel command line"
 	default n
-	help
+	---help---
 	  Allow for specifying boot arguments to the kernel at
 	  build time.  On some systems (e.g. embedded ones), it is
 	  necessary or convenient to provide some or all of the
@@ -1534,7 +1593,7 @@ config CMDLINE
 	string "Built-in kernel command string"
 	depends on CMDLINE_BOOL
 	default ""
-	help
+	---help---
 	  Enter arguments here that should be compiled into the kernel
 	  image and used at boot time.  If the boot loader provides a
 	  command line at boot time, it is appended to this string to
@@ -1551,7 +1610,7 @@ config CMDLINE_OVERRIDE
 	bool "Built-in command line overrides boot loader arguments"
 	default n
 	depends on CMDLINE_BOOL
-	help
+	---help---
 	  Set this option to 'Y' to have the kernel ignore the boot loader
 	  command line, and use ONLY the built-in command line.
 
@@ -1573,7 +1632,6 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
 	depends on NUMA
 
 menu "Power management and ACPI options"
-	depends on !X86_VOYAGER
 
 config ARCH_HIBERNATION_HEADER
 	def_bool y
@@ -1651,7 +1709,7 @@ if APM
 
 config APM_IGNORE_USER_SUSPEND
 	bool "Ignore USER SUSPEND"
-	help
+	---help---
 	  This option will ignore USER SUSPEND requests. On machines with a
 	  compliant APM BIOS, you want to say N. However, on the NEC Versa M
 	  series notebooks, it is necessary to say Y because of a BIOS bug.
@@ -1675,7 +1733,7 @@ config APM_DO_ENABLE
 
 config APM_CPU_IDLE
 	bool "Make CPU Idle calls when idle"
-	help
+	---help---
 	  Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
 	  On some machines, this can activate improved power savings, such as
 	  a slowed CPU clock rate, when the machine is idle. These idle calls
@@ -1686,7 +1744,7 @@ config APM_CPU_IDLE
 
 config APM_DISPLAY_BLANK
 	bool "Enable console blanking using APM"
-	help
+	---help---
 	  Enable console blanking using the APM. Some laptops can use this to
 	  turn off the LCD backlight when the screen blanker of the Linux
 	  virtual console blanks the screen. Note that this is only used by
@@ -1699,7 +1757,7 @@ config APM_DISPLAY_BLANK
 
 config APM_ALLOW_INTS
 	bool "Allow interrupts during APM BIOS calls"
-	help
+	---help---
 	  Normally we disable external interrupts while we are making calls to
 	  the APM BIOS as a measure to lessen the effects of a badly behaving
 	  BIOS implementation.  The BIOS should reenable interrupts if it
@@ -1724,7 +1782,7 @@ config PCI
 	bool "PCI support"
 	default y
 	select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
-	help
+	---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. Other bus systems are ISA, EISA, MicroChannel (MCA) or
@@ -1794,7 +1852,7 @@ config PCI_MMCONFIG
 
 config DMAR
 	bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
-	depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
+	depends on PCI_MSI && ACPI && EXPERIMENTAL
 	help
 	  DMA remapping (DMAR) devices support enables independent address
 	  translations for Direct Memory Access (DMA) from devices.
@@ -1817,29 +1875,29 @@ config DMAR_GFX_WA
 	def_bool y
 	prompt "Support for Graphics workaround"
 	depends on DMAR
-	help
-	 Current Graphics drivers tend to use physical address
-	 for DMA and avoid using DMA APIs. Setting this config
-	 option permits the IOMMU driver to set a unity map for
-	 all the OS-visible memory. Hence the driver can continue
-	 to use physical addresses for DMA.
+	---help---
+	  Current Graphics drivers tend to use physical address
+	  for DMA and avoid using DMA APIs. Setting this config
+	  option permits the IOMMU driver to set a unity map for
+	  all the OS-visible memory. Hence the driver can continue
+	  to use physical addresses for DMA.
 
 config DMAR_FLOPPY_WA
 	def_bool y
 	depends on DMAR
-	help
-	 Floppy disk drivers are know to bypass DMA API calls
-	 thereby failing to work when IOMMU is enabled. This
-	 workaround will setup a 1:1 mapping for the first
-	 16M to make floppy (an ISA device) work.
+	---help---
+	  Floppy disk drivers are know to bypass DMA API calls
+	  thereby failing to work when IOMMU is enabled. This
+	  workaround will setup a 1:1 mapping for the first
+	  16M to make floppy (an ISA device) work.
 
 config INTR_REMAP
 	bool "Support for Interrupt Remapping (EXPERIMENTAL)"
 	depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
-	help
-	 Supports Interrupt remapping for IO-APIC and MSI devices.
-	 To use x2apic mode in the CPU's which support x2APIC enhancements or
-	 to support platforms with CPU's having > 8 bit APIC ID, say Y.
+	---help---
+	  Supports Interrupt remapping for IO-APIC and MSI devices.
+	  To use x2apic mode in the CPU's which support x2APIC enhancements or
+	  to support platforms with CPU's having > 8 bit APIC ID, say Y.
 
 source "drivers/pci/pcie/Kconfig"
 
@@ -1853,8 +1911,7 @@ if X86_32
 
 config ISA
 	bool "ISA support"
-	depends on !X86_VOYAGER
-	help
+	---help---
 	  Find out whether you have ISA slots on your motherboard.  ISA is the
 	  name of a bus system, i.e. the way the CPU talks to the other stuff
 	  inside your box.  Other bus systems are PCI, EISA, MicroChannel
@@ -1880,9 +1937,8 @@ config EISA
 source "drivers/eisa/Kconfig"
 
 config MCA
-	bool "MCA support" if !X86_VOYAGER
-	default y if X86_VOYAGER
-	help
+	bool "MCA support"
+	---help---
 	  MicroChannel Architecture is found in some IBM PS/2 machines and
 	  laptops.  It is a bus system similar to PCI or ISA. See
 	  <file:Documentation/mca.txt> (and especially the web page given
@@ -1892,8 +1948,7 @@ source "drivers/mca/Kconfig"
 
 config SCx200
 	tristate "NatSemi SCx200 support"
-	depends on !X86_VOYAGER
-	help
+	---help---
 	  This provides basic support for National Semiconductor's
 	  (now AMD's) Geode processors.  The driver probes for the
 	  PCI-IDs of several on-chip devices, so its a good dependency
@@ -1905,7 +1960,7 @@ config SCx200HR_TIMER
 	tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
 	depends on SCx200 && GENERIC_TIME
 	default y
-	help
+	---help---
 	  This driver provides a clocksource built upon the on-chip
 	  27MHz high-resolution timer.  Its also a workaround for
 	  NSC Geode SC-1100's buggy TSC, which loses time when the
@@ -1916,7 +1971,7 @@ 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
+	---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
@@ -1925,7 +1980,7 @@ config GEODE_MFGPT_TIMER
 config OLPC
 	bool "One Laptop Per Child support"
 	default n
-	help
+	---help---
 	  Add support for detecting the unique features of the OLPC
 	  XO hardware.
 
@@ -1950,16 +2005,16 @@ config IA32_EMULATION
 	bool "IA32 Emulation"
 	depends on X86_64
 	select COMPAT_BINFMT_ELF
-	help
+	---help---
 	  Include code to run 32-bit programs under a 64-bit kernel. You should
 	  likely turn this on, unless you're 100% sure that you don't have any
 	  32-bit programs left.
 
 config IA32_AOUT
-       tristate "IA32 a.out support"
-       depends on IA32_EMULATION
-       help
-         Support old a.out binaries in the 32bit emulation.
+	tristate "IA32 a.out support"
+	depends on IA32_EMULATION
+	---help---
+	  Support old a.out binaries in the 32bit emulation.
 
 config COMPAT
 	def_bool y
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/Kconfig.cpu linux-libre-2.6.30-gnu1/arch/x86/Kconfig.cpu
--- linux-libre-2.6.29-gnu1/arch/x86/Kconfig.cpu	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/Kconfig.cpu	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ config M386
 config M486
 	bool "486"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a 486 series processor, either Intel or one of the
 	  compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
 	  DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
@@ -59,7 +59,7 @@ config M486
 config M586
 	bool "586/K5/5x86/6x86/6x86MX"
 	depends on X86_32
-	help
+	---help---
 	  Select this for an 586 or 686 series processor such as the AMD K5,
 	  the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
 	  assume the RDTSC (Read Time Stamp Counter) instruction.
@@ -67,21 +67,21 @@ config M586
 config M586TSC
 	bool "Pentium-Classic"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Pentium Classic processor with the RDTSC (Read
 	  Time Stamp Counter) instruction for benchmarking.
 
 config M586MMX
 	bool "Pentium-MMX"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Pentium with the MMX graphics/multimedia
 	  extended instructions.
 
 config M686
 	bool "Pentium-Pro"
 	depends on X86_32
-	help
+	---help---
 	  Select this for Intel Pentium Pro chips.  This enables the use of
 	  Pentium Pro extended instructions, and disables the init-time guard
 	  against the f00f bug found in earlier Pentiums.
@@ -89,7 +89,7 @@ config M686
 config MPENTIUMII
 	bool "Pentium-II/Celeron(pre-Coppermine)"
 	depends on X86_32
-	help
+	---help---
 	  Select this for Intel chips based on the Pentium-II and
 	  pre-Coppermine Celeron core.  This option enables an unaligned
 	  copy optimization, compiles the kernel with optimization flags
@@ -99,7 +99,7 @@ config MPENTIUMII
 config MPENTIUMIII
 	bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
 	depends on X86_32
-	help
+	---help---
 	  Select this for Intel chips based on the Pentium-III and
 	  Celeron-Coppermine core.  This option enables use of some
 	  extended prefetch instructions in addition to the Pentium II
@@ -108,14 +108,14 @@ config MPENTIUMIII
 config MPENTIUMM
 	bool "Pentium M"
 	depends on X86_32
-	help
+	---help---
 	  Select this for Intel Pentium M (not Pentium-4 M)
 	  notebook chips.
 
 config MPENTIUM4
 	bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon"
 	depends on X86_32
-	help
+	---help---
 	  Select this for Intel Pentium 4 chips.  This includes the
 	  Pentium 4, Pentium D, P4-based Celeron and Xeon, and
 	  Pentium-4 M (not Pentium M) chips.  This option enables compile
@@ -151,7 +151,7 @@ config MPENTIUM4
 config MK6
 	bool "K6/K6-II/K6-III"
 	depends on X86_32
-	help
+	---help---
 	  Select this for an AMD K6-family processor.  Enables use of
 	  some extended instructions, and passes appropriate optimization
 	  flags to GCC.
@@ -159,14 +159,14 @@ config MK6
 config MK7
 	bool "Athlon/Duron/K7"
 	depends on X86_32
-	help
+	---help---
 	  Select this for an AMD Athlon K7-family processor.  Enables use of
 	  some extended instructions, and passes appropriate optimization
 	  flags to GCC.
 
 config MK8
 	bool "Opteron/Athlon64/Hammer/K8"
-	help
+	---help---
 	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.
 	  Enables use of some extended instructions, and passes appropriate
 	  optimization flags to GCC.
@@ -174,7 +174,7 @@ config MK8
 config MCRUSOE
 	bool "Crusoe"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Transmeta Crusoe processor.  Treats the processor
 	  like a 586 with TSC, and sets some GCC optimization flags (like a
 	  Pentium Pro with no alignment requirements).
@@ -182,13 +182,13 @@ config MCRUSOE
 config MEFFICEON
 	bool "Efficeon"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Transmeta Efficeon processor.
 
 config MWINCHIPC6
 	bool "Winchip-C6"
 	depends on X86_32
-	help
+	---help---
 	  Select this for an IDT Winchip C6 chip.  Linux and GCC
 	  treat this chip as a 586TSC with some extended instructions
 	  and alignment requirements.
@@ -196,7 +196,7 @@ config MWINCHIPC6
 config MWINCHIP3D
 	bool "Winchip-2/Winchip-2A/Winchip-3"
 	depends on X86_32
-	help
+	---help---
 	  Select this for an IDT Winchip-2, 2A or 3.  Linux and GCC
 	  treat this chip as a 586TSC with some extended instructions
 	  and alignment requirements.  Also enable out of order memory
@@ -206,19 +206,19 @@ config MWINCHIP3D
 config MGEODEGX1
 	bool "GeodeGX1"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
 
 config MGEODE_LX
 	bool "Geode GX/LX"
 	depends on X86_32
-	help
+	---help---
 	  Select this for AMD Geode GX and LX processors.
 
 config MCYRIXIII
 	bool "CyrixIII/VIA-C3"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
 	  treat this chip as a generic 586. Whilst the CPU is 686 class,
 	  it lacks the cmov extension which gcc assumes is present when
@@ -230,7 +230,7 @@ config MCYRIXIII
 config MVIAC3_2
 	bool "VIA C3-2 (Nehemiah)"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a VIA C3 "Nehemiah". Selecting this enables usage
 	  of SSE and tells gcc to treat the CPU as a 686.
 	  Note, this kernel will not boot on older (pre model 9) C3s.
@@ -238,14 +238,14 @@ config MVIAC3_2
 config MVIAC7
 	bool "VIA C7"
 	depends on X86_32
-	help
+	---help---
 	  Select this for a VIA C7.  Selecting this uses the correct cache
 	  shift and tells gcc to treat the CPU as a 686.
 
 config MPSC
 	bool "Intel P4 / older Netburst based Xeon"
 	depends on X86_64
-	help
+	---help---
 	  Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
 	  Xeon CPUs with Intel 64bit which is compatible with x86-64.
 	  Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
@@ -255,7 +255,7 @@ config MPSC
 
 config MCORE2
 	bool "Core 2/newer Xeon"
-	help
+	---help---
 
 	  Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
 	  53xx) CPUs. You can distinguish newer from older Xeons by the CPU
@@ -265,7 +265,7 @@ config MCORE2
 config GENERIC_CPU
 	bool "Generic-x86-64"
 	depends on X86_64
-	help
+	---help---
 	  Generic x86-64 CPU.
 	  Run equally well on all x86-64 CPUs.
 
@@ -274,7 +274,7 @@ endchoice
 config X86_GENERIC
 	bool "Generic x86 support"
 	depends on X86_32
-	help
+	---help---
 	  Instead of just including optimizations for the selected
 	  x86 variant (e.g. PII, Crusoe or Athlon), include some more
 	  generic optimizations as well. This will make the kernel
@@ -294,25 +294,23 @@ config X86_CPU
 # Define implied options from the CPU selection here
 config X86_L1_CACHE_BYTES
 	int
-	default "128" if GENERIC_CPU || MPSC
-	default "64" if MK8 || MCORE2
-	depends on X86_64
+	default "128" if MPSC
+	default "64" if GENERIC_CPU || MK8 || MCORE2 || X86_32
 
 config X86_INTERNODE_CACHE_BYTES
 	int
 	default "4096" if X86_VSMP
 	default X86_L1_CACHE_BYTES if !X86_VSMP
-	depends on X86_64
 
 config X86_CMPXCHG
 	def_bool X86_64 || (X86_32 && !M386)
 
 config X86_L1_CACHE_SHIFT
 	int
-	default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC
+	default "7" if MPENTIUM4 || MPSC
 	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 || MVIAC7
+	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 || X86_GENERIC || GENERIC_CPU
 
 config X86_XADD
 	def_bool y
@@ -321,7 +319,7 @@ config X86_XADD
 config X86_PPRO_FENCE
 	bool "PentiumPro memory ordering errata workaround"
 	depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
-	help
+	---help---
 	  Old PentiumPro multiprocessor systems had errata that could cause
 	  memory operations to violate the x86 ordering standard in rare cases.
 	  Enabling this option will attempt to work around some (but not all)
@@ -414,14 +412,14 @@ config X86_DEBUGCTLMSR
 
 menuconfig PROCESSOR_SELECT
 	bool "Supported processor vendors" if EMBEDDED
-	help
+	---help---
 	  This lets you choose what x86 vendor support code your kernel
 	  will include.
 
 config CPU_SUP_INTEL
 	default y
 	bool "Support Intel processors" if PROCESSOR_SELECT
-	help
+	---help---
 	  This enables detection, tunings and quirks for Intel processors
 
 	  You need this enabled if you want your kernel to run on an
@@ -435,7 +433,7 @@ config CPU_SUP_CYRIX_32
 	default y
 	bool "Support Cyrix processors" if PROCESSOR_SELECT
 	depends on !64BIT
-	help
+	---help---
 	  This enables detection, tunings and quirks for Cyrix processors
 
 	  You need this enabled if you want your kernel to run on a
@@ -448,7 +446,7 @@ config CPU_SUP_CYRIX_32
 config CPU_SUP_AMD
 	default y
 	bool "Support AMD processors" if PROCESSOR_SELECT
-	help
+	---help---
 	  This enables detection, tunings and quirks for AMD processors
 
 	  You need this enabled if you want your kernel to run on an
@@ -458,25 +456,10 @@ config CPU_SUP_AMD
 
 	  If unsure, say N.
 
-config CPU_SUP_CENTAUR_32
-	default y
-	bool "Support Centaur processors" if PROCESSOR_SELECT
-	depends on !64BIT
-	help
-	  This enables detection, tunings and quirks for Centaur processors
-
-	  You need this enabled if you want your kernel to run on a
-	  Centaur CPU. Disabling this option on other types of CPUs
-	  makes the kernel a tiny bit smaller. Disabling it on a Centaur
-	  CPU might render the kernel unbootable.
-
-	  If unsure, say N.
-
-config CPU_SUP_CENTAUR_64
+config CPU_SUP_CENTAUR
 	default y
 	bool "Support Centaur processors" if PROCESSOR_SELECT
-	depends on 64BIT
-	help
+	---help---
 	  This enables detection, tunings and quirks for Centaur processors
 
 	  You need this enabled if you want your kernel to run on a
@@ -490,7 +473,7 @@ config CPU_SUP_TRANSMETA_32
 	default y
 	bool "Support Transmeta processors" if PROCESSOR_SELECT
 	depends on !64BIT
-	help
+	---help---
 	  This enables detection, tunings and quirks for Transmeta processors
 
 	  You need this enabled if you want your kernel to run on a
@@ -504,7 +487,7 @@ config CPU_SUP_UMC_32
 	default y
 	bool "Support UMC processors" if PROCESSOR_SELECT
 	depends on !64BIT
-	help
+	---help---
 	  This enables detection, tunings and quirks for UMC processors
 
 	  You need this enabled if you want your kernel to run on a
@@ -523,7 +506,8 @@ config X86_PTRACE_BTS
 	bool "Branch Trace Store"
 	default y
 	depends on X86_DEBUGCTLMSR
-	help
+	depends on BROKEN
+	---help---
 	  This adds a ptrace interface to the hardware's branch trace store.
 
 	  Debuggers may use it to collect an execution trace of the debugged
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/Kconfig.debug linux-libre-2.6.30-gnu1/arch/x86/Kconfig.debug
--- linux-libre-2.6.29-gnu1/arch/x86/Kconfig.debug	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@ source "lib/Kconfig.debug"
 
 config STRICT_DEVMEM
 	bool "Filter access to /dev/mem"
-	help
+	---help---
 	  If this option is disabled, you allow userspace (root) access to all
 	  of memory, including kernel and userspace memory. Accidental
 	  access to this is obviously disastrous, but specific access can
@@ -25,7 +25,7 @@ config STRICT_DEVMEM
 config X86_VERBOSE_BOOTUP
 	bool "Enable verbose x86 bootup info messages"
 	default y
-	help
+	---help---
 	  Enables the informational output from the decompression stage
 	  (e.g. bzImage) of the boot. If you disable this you will still
 	  see errors. Disable this if you want silent bootup.
@@ -33,7 +33,7 @@ config X86_VERBOSE_BOOTUP
 config EARLY_PRINTK
 	bool "Early printk" if EMBEDDED
 	default y
-	help
+	---help---
 	  Write kernel log output directly into the VGA buffer or to a serial
 	  port.
 
@@ -47,7 +47,7 @@ config EARLY_PRINTK_DBGP
 	bool "Early printk via EHCI debug port"
 	default n
 	depends on EARLY_PRINTK && PCI
-	help
+	---help---
 	  Write kernel log output directly into the EHCI debug port.
 
 	  This is useful for kernel debugging when your machine crashes very
@@ -59,33 +59,25 @@ config EARLY_PRINTK_DBGP
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
-	help
+	---help---
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
 	depends on DEBUG_KERNEL
-	help
+	---help---
 	  Enables the display of the minimum amount of free stack which each
 	  task has ever had available in the sysrq-T and sysrq-P debug output.
 
 	  This option will slow down process creation somewhat.
 
-config DEBUG_PAGEALLOC
-	bool "Debug page memory allocations"
-	depends on DEBUG_KERNEL
-	help
-	  Unmap pages from the kernel linear mapping after free_pages().
-	  This results in a large slowdown, but helps to find certain types
-	  of memory corruptions.
-
 config DEBUG_PER_CPU_MAPS
 	bool "Debug access to per_cpu maps"
 	depends on DEBUG_KERNEL
-	depends on X86_SMP
+	depends on SMP
 	default n
-	help
+	---help---
 	  Say Y to verify that the per_cpu map being accessed has
 	  been setup.  Adds a fair amount of code to kernel memory
 	  and decreases performance.
@@ -96,7 +88,7 @@ config X86_PTDUMP
 	bool "Export kernel pagetable layout to userspace via debugfs"
 	depends on DEBUG_KERNEL
 	select DEBUG_FS
-	help
+	---help---
 	  Say Y here if you want to show the kernel pagetable layout in a
 	  debugfs file. This information is only useful for kernel developers
 	  who are working in architecture specific areas of the kernel.
@@ -108,7 +100,7 @@ config DEBUG_RODATA
 	bool "Write protect kernel read-only data structures"
 	default y
 	depends on DEBUG_KERNEL
-	help
+	---help---
 	  Mark the kernel read-only data as write-protected in the pagetables,
 	  in order to catch accidental (and incorrect) writes to such const
 	  data. This is recommended so that we can catch kernel bugs sooner.
@@ -117,7 +109,8 @@ config DEBUG_RODATA
 config DEBUG_RODATA_TEST
 	bool "Testcase for the DEBUG_RODATA feature"
 	depends on DEBUG_RODATA
-	help
+	default y
+	---help---
 	  This option enables a testcase for the DEBUG_RODATA
 	  feature as well as for the change_page_attr() infrastructure.
 	  If in doubt, say "N"
@@ -125,7 +118,7 @@ config DEBUG_RODATA_TEST
 config DEBUG_NX_TEST
 	tristate "Testcase for the NX non-executable stack feature"
 	depends on DEBUG_KERNEL && m
-	help
+	---help---
 	  This option enables a testcase for the CPU NX capability
 	  and the software setup of this feature.
 	  If in doubt, say "N"
@@ -133,7 +126,7 @@ config DEBUG_NX_TEST
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on X86_32
-	help
+	---help---
 	  If you say Y here the kernel will use a 4Kb stacksize for the
 	  kernel stack attached to each process/thread. This facilitates
 	  running more threads on a system and also reduces the pressure
@@ -144,7 +137,7 @@ config DOUBLEFAULT
 	default y
 	bool "Enable doublefault exception handler" if EMBEDDED
 	depends on X86_32
-	help
+	---help---
 	  This option allows trapping of rare doublefault exceptions that
 	  would otherwise cause a system to silently reboot. Disabling this
 	  option saves about 4k and might cause you much additional grey
@@ -154,7 +147,7 @@ config IOMMU_DEBUG
 	bool "Enable IOMMU debugging"
 	depends on GART_IOMMU && DEBUG_KERNEL
 	depends on X86_64
-	help
+	---help---
 	  Force the IOMMU to on even when you have less than 4GB of
 	  memory and add debugging code. On overflow always panic. And
 	  allow to enable IOMMU leak tracing. Can be disabled at boot
@@ -170,7 +163,7 @@ config IOMMU_LEAK
 	bool "IOMMU leak tracing"
 	depends on DEBUG_KERNEL
 	depends on IOMMU_DEBUG
-	help
+	---help---
 	  Add a simple leak tracer to the IOMMU code. This is useful when you
 	  are debugging a buggy device driver that leaks IOMMU mappings.
 
@@ -203,25 +196,25 @@ choice
 
 config IO_DELAY_0X80
 	bool "port 0x80 based port-IO delay [recommended]"
-	help
+	---help---
 	  This is the traditional Linux IO delay used for in/out_p.
 	  It is the most tested hence safest selection here.
 
 config IO_DELAY_0XED
 	bool "port 0xed based port-IO delay"
-	help
+	---help---
 	  Use port 0xed as the IO delay. This frees up port 0x80 which is
 	  often used as a hardware-debug port.
 
 config IO_DELAY_UDELAY
 	bool "udelay based port-IO delay"
-	help
+	---help---
 	  Use udelay(2) as the IO delay method. This provides the delay
 	  while not having any side-effect on the IO port space.
 
 config IO_DELAY_NONE
 	bool "no port-IO delay"
-	help
+	---help---
 	  No port-IO delay. Will break on old boxes that require port-IO
 	  delay for certain operations. Should work on most new machines.
 
@@ -255,18 +248,18 @@ config DEBUG_BOOT_PARAMS
 	bool "Debug boot parameters"
 	depends on DEBUG_KERNEL
 	depends on DEBUG_FS
-	help
+	---help---
 	  This option will cause struct boot_params to be exported via debugfs.
 
 config CPA_DEBUG
 	bool "CPA self-test code"
 	depends on DEBUG_KERNEL
-	help
+	---help---
 	  Do change_page_attr() self-tests every 30 seconds.
 
 config OPTIMIZE_INLINING
 	bool "Allow gcc to uninline functions marked 'inline'"
-	help
+	---help---
 	  This option determines if the kernel forces gcc to inline the functions
 	  developers have marked 'inline'. Doing so takes away freedom from gcc to
 	  do what it thinks is best, which is desirable for the gcc 3.x series of
@@ -279,4 +272,3 @@ config OPTIMIZE_INLINING
 	  If unsure, say N.
 
 endmenu
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/boot.c linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/boot.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/boot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/boot.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,15 +37,10 @@
 #include <asm/pgtable.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
-#include <asm/genapic.h>
 #include <asm/io.h>
 #include <asm/mpspec.h>
 #include <asm/smp.h>
 
-#ifdef CONFIG_X86_LOCAL_APIC
-# include <mach_apic.h>
-#endif
-
 static int __initdata acpi_force = 0;
 u32 acpi_rsdt_forced;
 #ifdef	CONFIG_ACPI
@@ -56,16 +51,7 @@ int acpi_disabled = 1;
 EXPORT_SYMBOL(acpi_disabled);
 
 #ifdef	CONFIG_X86_64
-
-#include <asm/proto.h>
-
-#else				/* X86 */
-
-#ifdef	CONFIG_X86_LOCAL_APIC
-#include <mach_apic.h>
-#include <mach_mpparse.h>
-#endif				/* CONFIG_X86_LOCAL_APIC */
-
+# include <asm/proto.h>
 #endif				/* X86 */
 
 #define BAD_MADT_ENTRY(entry, end) (					    \
@@ -121,35 +107,18 @@ enum acpi_irq_model_id acpi_irq_model =
  */
 char *__init __acpi_map_table(unsigned long phys, unsigned long size)
 {
-	unsigned long base, offset, mapped_size;
-	int idx;
 
 	if (!phys || !size)
 		return NULL;
 
-	if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
-		return __va(phys);
-
-	offset = phys & (PAGE_SIZE - 1);
-	mapped_size = PAGE_SIZE - offset;
-	clear_fixmap(FIX_ACPI_END);
-	set_fixmap(FIX_ACPI_END, phys);
-	base = fix_to_virt(FIX_ACPI_END);
-
-	/*
-	 * Most cases can be covered by the below.
-	 */
-	idx = FIX_ACPI_END;
-	while (mapped_size < size) {
-		if (--idx < FIX_ACPI_BEGIN)
-			return NULL;	/* cannot handle this */
-		phys += PAGE_SIZE;
-		clear_fixmap(idx);
-		set_fixmap(idx, phys);
-		mapped_size += PAGE_SIZE;
-	}
+	return early_ioremap(phys, size);
+}
+void __init __acpi_unmap_table(char *map, unsigned long size)
+{
+	if (!map || !size)
+		return;
 
-	return ((unsigned char *)base + offset);
+	early_iounmap(map, size);
 }
 
 #ifdef CONFIG_PCI_MMCONFIG
@@ -239,7 +208,8 @@ static int __init acpi_parse_madt(struct
 		       madt->address);
 	}
 
-	acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
+	default_acpi_madt_oem_check(madt->header.oem_id,
+				    madt->header.oem_table_id);
 
 	return 0;
 }
@@ -260,6 +230,35 @@ static void __cpuinit acpi_register_lapi
 }
 
 static int __init
+acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
+{
+	struct acpi_madt_local_x2apic *processor = NULL;
+
+	processor = (struct acpi_madt_local_x2apic *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+#ifdef CONFIG_X86_X2APIC
+	/*
+	 * We need to register disabled CPU as well to permit
+	 * counting disabled CPUs. This allows us to size
+	 * cpus_possible_map more accurately, to permit
+	 * to not preallocating memory for all NR_CPUS
+	 * when we use CPU hotplug.
+	 */
+	acpi_register_lapic(processor->local_apic_id,	/* APIC ID */
+			    processor->lapic_flags & ACPI_MADT_ENABLED);
+#else
+	printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
+#endif
+
+	return 0;
+}
+
+static int __init
 acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
 {
 	struct acpi_madt_local_apic *processor = NULL;
@@ -319,6 +318,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_su
 }
 
 static int __init
+acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
+		      const unsigned long end)
+{
+	struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
+
+	x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
+
+	if (BAD_MADT_ENTRY(x2apic_nmi, end))
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (x2apic_nmi->lint != 1)
+		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+	return 0;
+}
+
+static int __init
 acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
 {
 	struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
@@ -823,6 +841,7 @@ static int __init early_acpi_parse_madt_
 static int __init acpi_parse_madt_lapic_entries(void)
 {
 	int count;
+	int x2count = 0;
 
 	if (!cpu_has_apic)
 		return -ENODEV;
@@ -846,22 +865,28 @@ static int __init acpi_parse_madt_lapic_
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
 				      acpi_parse_sapic, MAX_APICS);
 
-	if (!count)
+	if (!count) {
+		x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
+						acpi_parse_x2apic, MAX_APICS);
 		count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
 					      acpi_parse_lapic, MAX_APICS);
-	if (!count) {
+	}
+	if (!count && !x2count) {
 		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return -ENODEV;
-	} else if (count < 0) {
+	} else if (count < 0 || x2count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return count;
 	}
 
+	x2count =
+	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
+				  acpi_parse_x2apic_nmi, 0);
 	count =
 	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
-	if (count < 0) {
+	if (count < 0 || x2count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return count;
@@ -884,7 +909,7 @@ static struct {
 	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 } mp_ioapic_routing[MAX_IO_APICS];
 
-static int mp_find_ioapic(int gsi)
+int mp_find_ioapic(int gsi)
 {
 	int i = 0;
 
@@ -899,6 +924,16 @@ static int mp_find_ioapic(int gsi)
 	return -1;
 }
 
+int mp_find_ioapic_pin(int ioapic, int gsi)
+{
+	if (WARN_ON(ioapic == -1))
+		return -1;
+	if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end))
+		return -1;
+
+	return gsi - mp_ioapic_routing[ioapic].gsi_base;
+}
+
 static u8 __init uniq_ioapic_id(u8 id)
 {
 #ifdef CONFIG_X86_32
@@ -912,8 +947,8 @@ static u8 __init uniq_ioapic_id(u8 id)
 	DECLARE_BITMAP(used, 256);
 	bitmap_zero(used, 256);
 	for (i = 0; i < nr_ioapics; i++) {
-		struct mp_config_ioapic *ia = &mp_ioapics[i];
-		__set_bit(ia->mp_apicid, used);
+		struct mpc_ioapic *ia = &mp_ioapics[i];
+		__set_bit(ia->apicid, used);
 	}
 	if (!test_bit(id, used))
 		return id;
@@ -945,29 +980,29 @@ void __init mp_register_ioapic(int id, u
 
 	idx = nr_ioapics;
 
-	mp_ioapics[idx].mp_type = MP_IOAPIC;
-	mp_ioapics[idx].mp_flags = MPC_APIC_USABLE;
-	mp_ioapics[idx].mp_apicaddr = address;
+	mp_ioapics[idx].type = MP_IOAPIC;
+	mp_ioapics[idx].flags = MPC_APIC_USABLE;
+	mp_ioapics[idx].apicaddr = address;
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-	mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id);
+	mp_ioapics[idx].apicid = uniq_ioapic_id(id);
 #ifdef CONFIG_X86_32
-	mp_ioapics[idx].mp_apicver = io_apic_get_version(idx);
+	mp_ioapics[idx].apicver = io_apic_get_version(idx);
 #else
-	mp_ioapics[idx].mp_apicver = 0;
+	mp_ioapics[idx].apicver = 0;
 #endif
 	/*
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
-	mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid;
+	mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
 	mp_ioapic_routing[idx].gsi_base = gsi_base;
 	mp_ioapic_routing[idx].gsi_end = gsi_base +
 	    io_apic_get_redir_entries(idx);
 
-	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
-	       "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid,
-	       mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr,
+	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
+	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
+	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
 	       mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
 
 	nr_ioapics++;
@@ -996,19 +1031,19 @@ int __init acpi_probe_gsi(void)
 	return max_gsi + 1;
 }
 
-static void assign_to_mp_irq(struct mp_config_intsrc *m,
-				    struct mp_config_intsrc *mp_irq)
+static void assign_to_mp_irq(struct mpc_intsrc *m,
+				    struct mpc_intsrc *mp_irq)
 {
-	memcpy(mp_irq, m, sizeof(struct mp_config_intsrc));
+	memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
 }
 
-static int mp_irq_cmp(struct mp_config_intsrc *mp_irq,
-				struct mp_config_intsrc *m)
+static int mp_irq_cmp(struct mpc_intsrc *mp_irq,
+				struct mpc_intsrc *m)
 {
-	return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc));
+	return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
 }
 
-static void save_mp_irq(struct mp_config_intsrc *m)
+static void save_mp_irq(struct mpc_intsrc *m)
 {
 	int i;
 
@@ -1026,7 +1061,7 @@ void __init mp_override_legacy_irq(u8 bu
 {
 	int ioapic;
 	int pin;
-	struct mp_config_intsrc mp_irq;
+	struct mpc_intsrc mp_irq;
 
 	/*
 	 * Convert 'gsi' to 'ioapic.pin'.
@@ -1034,7 +1069,7 @@ void __init mp_override_legacy_irq(u8 bu
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic < 0)
 		return;
-	pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
+	pin = mp_find_ioapic_pin(ioapic, gsi);
 
 	/*
 	 * TBD: This check is for faulty timer entries, where the override
@@ -1044,13 +1079,13 @@ void __init mp_override_legacy_irq(u8 bu
 	if ((bus_irq == 0) && (trigger == 3))
 		trigger = 1;
 
-	mp_irq.mp_type = MP_INTSRC;
-	mp_irq.mp_irqtype = mp_INT;
-	mp_irq.mp_irqflag = (trigger << 2) | polarity;
-	mp_irq.mp_srcbus = MP_ISA_BUS;
-	mp_irq.mp_srcbusirq = bus_irq;	/* IRQ */
-	mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */
-	mp_irq.mp_dstirq = pin;	/* INTIN# */
+	mp_irq.type = MP_INTSRC;
+	mp_irq.irqtype = mp_INT;
+	mp_irq.irqflag = (trigger << 2) | polarity;
+	mp_irq.srcbus = MP_ISA_BUS;
+	mp_irq.srcbusirq = bus_irq;	/* IRQ */
+	mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
+	mp_irq.dstirq = pin;	/* INTIN# */
 
 	save_mp_irq(&mp_irq);
 }
@@ -1060,7 +1095,7 @@ void __init mp_config_acpi_legacy_irqs(v
 	int i;
 	int ioapic;
 	unsigned int dstapic;
-	struct mp_config_intsrc mp_irq;
+	struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
 	/*
@@ -1085,7 +1120,7 @@ void __init mp_config_acpi_legacy_irqs(v
 	ioapic = mp_find_ioapic(0);
 	if (ioapic < 0)
 		return;
-	dstapic = mp_ioapics[ioapic].mp_apicid;
+	dstapic = mp_ioapics[ioapic].apicid;
 
 	/*
 	 * Use the default configuration for the IRQs 0-15.  Unless
@@ -1095,16 +1130,14 @@ void __init mp_config_acpi_legacy_irqs(v
 		int idx;
 
 		for (idx = 0; idx < mp_irq_entries; idx++) {
-			struct mp_config_intsrc *irq = mp_irqs + idx;
+			struct mpc_intsrc *irq = mp_irqs + idx;
 
 			/* Do we already have a mapping for this ISA IRQ? */
-			if (irq->mp_srcbus == MP_ISA_BUS
-			    && irq->mp_srcbusirq == i)
+			if (irq->srcbus == MP_ISA_BUS && irq->srcbusirq == i)
 				break;
 
 			/* Do we already have a mapping for this IOAPIC pin */
-			if (irq->mp_dstapic == dstapic &&
-			    irq->mp_dstirq == i)
+			if (irq->dstapic == dstapic && irq->dstirq == i)
 				break;
 		}
 
@@ -1113,13 +1146,13 @@ void __init mp_config_acpi_legacy_irqs(v
 			continue;	/* IRQ already used */
 		}
 
-		mp_irq.mp_type = MP_INTSRC;
-		mp_irq.mp_irqflag = 0;	/* Conforming */
-		mp_irq.mp_srcbus = MP_ISA_BUS;
-		mp_irq.mp_dstapic = dstapic;
-		mp_irq.mp_irqtype = mp_INT;
-		mp_irq.mp_srcbusirq = i; /* Identity mapped */
-		mp_irq.mp_dstirq = i;
+		mp_irq.type = MP_INTSRC;
+		mp_irq.irqflag = 0;	/* Conforming */
+		mp_irq.srcbus = MP_ISA_BUS;
+		mp_irq.dstapic = dstapic;
+		mp_irq.irqtype = mp_INT;
+		mp_irq.srcbusirq = i; /* Identity mapped */
+		mp_irq.dstirq = i;
 
 		save_mp_irq(&mp_irq);
 	}
@@ -1156,7 +1189,7 @@ int mp_register_gsi(u32 gsi, int trigger
 		return gsi;
 	}
 
-	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
+	ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
 #ifdef CONFIG_X86_32
 	if (ioapic_renumber_irq)
@@ -1230,22 +1263,22 @@ int mp_config_acpi_gsi(unsigned char num
 			u32 gsi, int triggering, int polarity)
 {
 #ifdef CONFIG_X86_MPPARSE
-	struct mp_config_intsrc mp_irq;
+	struct mpc_intsrc mp_irq;
 	int ioapic;
 
 	if (!acpi_ioapic)
 		return 0;
 
 	/* print the entry should happen on mptable identically */
-	mp_irq.mp_type = MP_INTSRC;
-	mp_irq.mp_irqtype = mp_INT;
-	mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
+	mp_irq.type = MP_INTSRC;
+	mp_irq.irqtype = mp_INT;
+	mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
 				(polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
-	mp_irq.mp_srcbus = number;
-	mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
+	mp_irq.srcbus = number;
+	mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
 	ioapic = mp_find_ioapic(gsi);
-	mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id;
-	mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
+	mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
+	mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
 
 	save_mp_irq(&mp_irq);
 #endif
@@ -1372,7 +1405,7 @@ static void __init acpi_process_madt(voi
 		if (!error) {
 			acpi_lapic = 1;
 
-#ifdef CONFIG_X86_GENERICARCH
+#ifdef CONFIG_X86_BIGSMP
 			generic_bigsmp_probe();
 #endif
 			/*
@@ -1384,9 +1417,8 @@ static void __init acpi_process_madt(voi
 				acpi_ioapic = 1;
 
 				smp_found_config = 1;
-#ifdef CONFIG_X86_32
-				setup_apic_routing();
-#endif
+				if (apic->setup_apic_routing)
+					apic->setup_apic_routing();
 			}
 		}
 		if (error == -EINVAL) {
@@ -1493,7 +1525,7 @@ static int __init dmi_ignore_irq0_timer_
 
 /*
  * If your system is blacklisted here, but you find that acpi=force
- * works for you, please contact acpi-devel@sourceforge.net
+ * works for you, please contact linux-acpi@vger.kernel.org
  */
 static struct dmi_system_id __initdata acpi_dmi_table[] = {
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/realmode/wakeup.S linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/realmode/wakeup.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/realmode/wakeup.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/realmode/wakeup.S	2009-06-09 23:05:27.000000000 -0400
@@ -3,8 +3,8 @@
  */
 #include <asm/segment.h>
 #include <asm/msr-index.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/page_types.h>
+#include <asm/pgtable_types.h>
 #include <asm/processor-flags.h>
 
 	.code16
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/sleep.c linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/sleep.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/sleep.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/sleep.c	2009-06-09 23:05:27.000000000 -0400
@@ -101,6 +101,7 @@ int acpi_save_state_mem(void)
 	stack_start.sp = temp_stack + sizeof(temp_stack);
 	early_gdt_descr.address =
 			(unsigned long)get_cpu_gdt_table(smp_processor_id());
+	initial_gs = per_cpu_offset(smp_processor_id());
 #endif
 	initial_code = (unsigned long)wakeup_long64;
 	saved_magic = 0x123456789abcdef0;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/wakeup_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/wakeup_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/wakeup_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/wakeup_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 	.section .text.page_aligned
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 
 # Copyright 2003, 2008 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/wakeup_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/wakeup_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/acpi/wakeup_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/acpi/wakeup_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,8 +1,8 @@
 .text
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <asm/pgtable_types.h>
+#include <asm/page_types.h>
 #include <asm/msr.h>
 #include <asm/asm-offsets.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/alternative.c linux-libre-2.6.30-gnu1/arch/x86/kernel/alternative.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/alternative.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/alternative.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/kprobes.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/memory.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -12,7 +13,9 @@
 #include <asm/nmi.h>
 #include <asm/vsyscall.h>
 #include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 #include <asm/io.h>
+#include <asm/fixmap.h>
 
 #define MAX_PATCH_LEN (255-1)
 
@@ -226,6 +229,7 @@ static void alternatives_smp_lock(u8 **s
 {
 	u8 **ptr;
 
+	mutex_lock(&text_mutex);
 	for (ptr = start; ptr < end; ptr++) {
 		if (*ptr < text)
 			continue;
@@ -234,6 +238,7 @@ static void alternatives_smp_lock(u8 **s
 		/* turn DS segment override prefix into lock prefix */
 		text_poke(*ptr, ((unsigned char []){0xf0}), 1);
 	};
+	mutex_unlock(&text_mutex);
 }
 
 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
@@ -243,6 +248,7 @@ static void alternatives_smp_unlock(u8 *
 	if (noreplace_smp)
 		return;
 
+	mutex_lock(&text_mutex);
 	for (ptr = start; ptr < end; ptr++) {
 		if (*ptr < text)
 			continue;
@@ -251,6 +257,7 @@ static void alternatives_smp_unlock(u8 *
 		/* turn lock prefix into DS segment override prefix */
 		text_poke(*ptr, ((unsigned char []){0x3E}), 1);
 	};
+	mutex_unlock(&text_mutex);
 }
 
 struct smp_alt_module {
@@ -414,9 +421,17 @@ void __init alternative_instructions(voi
 	   that might execute the to be patched code.
 	   Other CPUs are not running. */
 	stop_nmi();
-#ifdef CONFIG_X86_MCE
-	stop_mce();
-#endif
+
+	/*
+	 * Don't stop machine check exceptions while patching.
+	 * MCEs only happen when something got corrupted and in this
+	 * case we must do something about the corruption.
+	 * Ignoring it is worse than a unlikely patching race.
+	 * Also machine checks tend to be broadcast and if one CPU
+	 * goes into machine check the others follow quickly, so we don't
+	 * expect a machine check to cause undue problems during to code
+	 * patching.
+	 */
 
 	apply_alternatives(__alt_instructions, __alt_instructions_end);
 
@@ -456,9 +471,6 @@ void __init alternative_instructions(voi
 				(unsigned long)__smp_locks_end);
 
 	restart_nmi();
-#ifdef CONFIG_X86_MCE
-	restart_mce();
-#endif
 }
 
 /**
@@ -495,12 +507,13 @@ void *text_poke_early(void *addr, const
  * It means the size must be writable atomically and the address must be aligned
  * in a way that permits an atomic write. It also makes sure we fit on a single
  * page.
+ *
+ * Note: Must be called under text_mutex.
  */
 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
 {
 	unsigned long flags;
 	char *vaddr;
-	int nr_pages = 2;
 	struct page *pages[2];
 	int i;
 
@@ -513,18 +526,21 @@ void *__kprobes text_poke(void *addr, co
 		pages[1] = virt_to_page(addr + PAGE_SIZE);
 	}
 	BUG_ON(!pages[0]);
-	if (!pages[1])
-		nr_pages = 1;
-	vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
-	BUG_ON(!vaddr);
 	local_irq_save(flags);
+	set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
+	if (pages[1])
+		set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
+	vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
 	memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
-	local_irq_restore(flags);
-	vunmap(vaddr);
+	clear_fixmap(FIX_TEXT_POKE0);
+	if (pages[1])
+		clear_fixmap(FIX_TEXT_POKE1);
+	local_flush_tlb();
 	sync_core();
 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
 	   that causes hangs on some VIA CPUs. */
 	for (i = 0; i < len; i++)
 		BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
+	local_irq_restore(flags);
 	return addr;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/amd_iommu.c linux-libre-2.6.30-gnu1/arch/x86/kernel/amd_iommu.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/amd_iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/amd_iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,10 +22,9 @@
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
 #include <linux/iommu-helper.h>
-#ifdef CONFIG_IOMMU_API
 #include <linux/iommu.h>
-#endif
 #include <asm/proto.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
@@ -1297,8 +1296,10 @@ static void __unmap_single(struct amd_io
 /*
  * The exported map_single function for dma_ops.
  */
-static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
-			     size_t size, int dir)
+static dma_addr_t map_page(struct device *dev, struct page *page,
+			   unsigned long offset, size_t size,
+			   enum dma_data_direction dir,
+			   struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct amd_iommu *iommu;
@@ -1306,6 +1307,7 @@ static dma_addr_t map_single(struct devi
 	u16 devid;
 	dma_addr_t addr;
 	u64 dma_mask;
+	phys_addr_t paddr = page_to_phys(page) + offset;
 
 	INC_STATS_COUNTER(cnt_map_single);
 
@@ -1340,8 +1342,8 @@ out:
 /*
  * The exported unmap_single function for dma_ops.
  */
-static void unmap_single(struct device *dev, dma_addr_t dma_addr,
-			 size_t size, int dir)
+static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+		       enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct amd_iommu *iommu;
@@ -1390,7 +1392,8 @@ static int map_sg_no_iommu(struct device
  * lists).
  */
 static int map_sg(struct device *dev, struct scatterlist *sglist,
-		  int nelems, int dir)
+		  int nelems, enum dma_data_direction dir,
+		  struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct amd_iommu *iommu;
@@ -1457,7 +1460,8 @@ unmap:
  * lists).
  */
 static void unmap_sg(struct device *dev, struct scatterlist *sglist,
-		     int nelems, int dir)
+		     int nelems, enum dma_data_direction dir,
+		     struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct amd_iommu *iommu;
@@ -1644,11 +1648,11 @@ static void prealloc_protection_domains(
 	}
 }
 
-static struct dma_mapping_ops amd_iommu_dma_ops = {
+static struct dma_map_ops amd_iommu_dma_ops = {
 	.alloc_coherent = alloc_coherent,
 	.free_coherent = free_coherent,
-	.map_single = map_single,
-	.unmap_single = unmap_single,
+	.map_page = map_page,
+	.unmap_page = unmap_page,
 	.map_sg = map_sg,
 	.unmap_sg = unmap_sg,
 	.dma_supported = amd_iommu_dma_supported,
@@ -1924,6 +1928,12 @@ static phys_addr_t amd_iommu_iova_to_phy
 	return paddr;
 }
 
+static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
+				    unsigned long cap)
+{
+	return 0;
+}
+
 static struct iommu_ops amd_iommu_ops = {
 	.domain_init = amd_iommu_domain_init,
 	.domain_destroy = amd_iommu_domain_destroy,
@@ -1932,5 +1942,6 @@ static struct iommu_ops amd_iommu_ops =
 	.map = amd_iommu_map_range,
 	.unmap = amd_iommu_unmap_range,
 	.iova_to_phys = amd_iommu_iova_to_phys,
+	.domain_has_cap = amd_iommu_domain_has_cap,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/amd_iommu_init.c linux-libre-2.6.30-gnu1/arch/x86/kernel/amd_iommu_init.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/amd_iommu_init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/amd_iommu_init.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,10 +49,10 @@
 #define IVHD_DEV_EXT_SELECT             0x46
 #define IVHD_DEV_EXT_SELECT_RANGE       0x47
 
-#define IVHD_FLAG_HT_TUN_EN             0x00
-#define IVHD_FLAG_PASSPW_EN             0x01
-#define IVHD_FLAG_RESPASSPW_EN          0x02
-#define IVHD_FLAG_ISOC_EN               0x03
+#define IVHD_FLAG_HT_TUN_EN_MASK        0x01
+#define IVHD_FLAG_PASSPW_EN_MASK        0x02
+#define IVHD_FLAG_RESPASSPW_EN_MASK     0x04
+#define IVHD_FLAG_ISOC_EN_MASK          0x08
 
 #define IVMD_FLAG_EXCL_RANGE            0x08
 #define IVMD_FLAG_UNITY_MAP             0x01
@@ -569,19 +569,19 @@ static void __init init_iommu_from_acpi(
 	 * First set the recommended feature enable bits from ACPI
 	 * into the IOMMU control registers
 	 */
-	h->flags & IVHD_FLAG_HT_TUN_EN ?
+	h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
 		iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
 		iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
 
-	h->flags & IVHD_FLAG_PASSPW_EN ?
+	h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
 		iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
 		iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
 
-	h->flags & IVHD_FLAG_RESPASSPW_EN ?
+	h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
 		iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
 		iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
 
-	h->flags & IVHD_FLAG_ISOC_EN ?
+	h->flags & IVHD_FLAG_ISOC_EN_MASK ?
 		iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
 		iommu_feature_disable(iommu, CONTROL_ISOC_EN);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/apic.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/apic.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/apic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/apic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2275 @@
+/*
+ *	Local APIC handling, local APIC timers
+ *
+ *	(c) 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
+ *
+ *	Fixes
+ *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs;
+ *					thanks to Eric Gilmore
+ *					and Rolf G. Tews
+ *					for testing these extensively.
+ *	Maciej W. Rozycki	:	Various updates and fixes.
+ *	Mikael Pettersson	:	Power Management for UP-APIC.
+ *	Pavel Machek and
+ *	Mikael Pettersson	:	PM converted to driver model.
+ */
+
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/acpi_pmtmr.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/bootmem.h>
+#include <linux/ftrace.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/timex.h>
+#include <linux/dmar.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/dmi.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm/pgalloc.h>
+#include <asm/atomic.h>
+#include <asm/mpspec.h>
+#include <asm/i8253.h>
+#include <asm/i8259.h>
+#include <asm/proto.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
+#include <asm/hpet.h>
+#include <asm/idle.h>
+#include <asm/mtrr.h>
+#include <asm/smp.h>
+#include <asm/mce.h>
+
+unsigned int num_processors;
+
+unsigned disabled_cpus __cpuinitdata;
+
+/* Processor that is doing the boot up */
+unsigned int boot_cpu_physical_apicid = -1U;
+
+/*
+ * The highest APIC ID seen during enumeration.
+ *
+ * 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;
+
+/*
+ * Bitmask of physically existing CPUs:
+ */
+physid_mask_t phys_cpu_present_map;
+
+/*
+ * Map cpu index to physical APIC ID
+ */
+DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
+DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
+EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
+
+#ifdef CONFIG_X86_32
+/*
+ * Knob to control our willingness to enable the local APIC.
+ *
+ * +1=force-enable
+ */
+static int force_enable_local_apic;
+/*
+ * APIC command line parameters
+ */
+static int __init parse_lapic(char *arg)
+{
+	force_enable_local_apic = 1;
+	return 0;
+}
+early_param("lapic", parse_lapic);
+/* Local APIC was disabled by the BIOS and enabled by the kernel */
+static int enabled_via_apicbase;
+
+#endif
+
+#ifdef CONFIG_X86_64
+static int apic_calibrate_pmtmr __initdata;
+static __init int setup_apicpmtimer(char *s)
+{
+	apic_calibrate_pmtmr = 1;
+	notsc_setup(NULL);
+	return 0;
+}
+__setup("apicpmtimer", setup_apicpmtimer);
+#endif
+
+#ifdef CONFIG_X86_X2APIC
+int x2apic;
+/* x2apic enabled before OS handover */
+static int x2apic_preenabled;
+static int disable_x2apic;
+static __init int setup_nox2apic(char *str)
+{
+	disable_x2apic = 1;
+	setup_clear_cpu_cap(X86_FEATURE_X2APIC);
+	return 0;
+}
+early_param("nox2apic", setup_nox2apic);
+#endif
+
+unsigned long mp_lapic_addr;
+int disable_apic;
+/* Disable local APIC timer from the kernel commandline or via dmi quirk */
+static int disable_apic_timer __cpuinitdata;
+/* Local APIC timer works in C2 */
+int local_apic_timer_c2_ok;
+EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
+
+int first_system_vector = 0xfe;
+
+/*
+ * Debug level, exported for io_apic.c
+ */
+unsigned int apic_verbosity;
+
+int pic_mode;
+
+/* Have we found an MP table */
+int smp_found_config;
+
+static struct resource lapic_resource = {
+	.name = "Local APIC",
+	.flags = IORESOURCE_MEM | IORESOURCE_BUSY,
+};
+
+static unsigned int calibration_result;
+
+static int lapic_next_event(unsigned long delta,
+			    struct clock_event_device *evt);
+static void lapic_timer_setup(enum clock_event_mode mode,
+			      struct clock_event_device *evt);
+static void lapic_timer_broadcast(const struct cpumask *mask);
+static void apic_pm_activate(void);
+
+/*
+ * The local apic timer can be used for any function which is CPU local.
+ */
+static struct clock_event_device lapic_clockevent = {
+	.name		= "lapic",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
+			| CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
+	.shift		= 32,
+	.set_mode	= lapic_timer_setup,
+	.set_next_event	= lapic_next_event,
+	.broadcast	= lapic_timer_broadcast,
+	.rating		= 100,
+	.irq		= -1,
+};
+static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
+
+static unsigned long apic_phys;
+
+/*
+ * Get the LAPIC version
+ */
+static inline int lapic_get_version(void)
+{
+	return GET_APIC_VERSION(apic_read(APIC_LVR));
+}
+
+/*
+ * Check, if the APIC is integrated or a separate chip
+ */
+static inline int lapic_is_integrated(void)
+{
+#ifdef CONFIG_X86_64
+	return 1;
+#else
+	return APIC_INTEGRATED(lapic_get_version());
+#endif
+}
+
+/*
+ * Check, whether this is a modern or a first generation APIC
+ */
+static int modern_apic(void)
+{
+	/* AMD systems use old APIC versions, so check the CPU */
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+	    boot_cpu_data.x86 >= 0xf)
+		return 1;
+	return lapic_get_version() >= 0x14;
+}
+
+void native_apic_wait_icr_idle(void)
+{
+	while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
+		cpu_relax();
+}
+
+u32 native_safe_apic_wait_icr_idle(void)
+{
+	u32 send_status;
+	int timeout;
+
+	timeout = 0;
+	do {
+		send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+		if (!send_status)
+			break;
+		udelay(100);
+	} while (timeout++ < 1000);
+
+	return send_status;
+}
+
+void native_apic_icr_write(u32 low, u32 id)
+{
+	apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
+	apic_write(APIC_ICR, low);
+}
+
+u64 native_apic_icr_read(void)
+{
+	u32 icr1, icr2;
+
+	icr2 = apic_read(APIC_ICR2);
+	icr1 = apic_read(APIC_ICR);
+
+	return icr1 | ((u64)icr2 << 32);
+}
+
+/**
+ * enable_NMI_through_LVT0 - enable NMI through local vector table 0
+ */
+void __cpuinit enable_NMI_through_LVT0(void)
+{
+	unsigned int v;
+
+	/* unmask and set to NMI */
+	v = APIC_DM_NMI;
+
+	/* Level triggered for 82489DX (32bit mode) */
+	if (!lapic_is_integrated())
+		v |= APIC_LVT_LEVEL_TRIGGER;
+
+	apic_write(APIC_LVT0, v);
+}
+
+#ifdef CONFIG_X86_32
+/**
+ * get_physical_broadcast - Get number of physical broadcast IDs
+ */
+int get_physical_broadcast(void)
+{
+	return modern_apic() ? 0xff : 0xf;
+}
+#endif
+
+/**
+ * lapic_get_maxlvt - get the maximum number of local vector table entries
+ */
+int lapic_get_maxlvt(void)
+{
+	unsigned int v;
+
+	v = apic_read(APIC_LVR);
+	/*
+	 * - we always have APIC integrated on 64bit mode
+	 * - 82489DXs do not report # of LVT entries
+	 */
+	return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2;
+}
+
+/*
+ * Local APIC timer
+ */
+
+/* Clock divisor */
+#define APIC_DIVISOR 16
+
+/*
+ * This function sets up the local APIC timer, with a timeout of
+ * 'clocks' APIC bus clock. During calibration we actually call
+ * this function twice on the boot CPU, once with a bogus timeout
+ * value, second time for real. The other (noncalibrating) CPUs
+ * call this function only once, with the real, calibrated value.
+ *
+ * We do reads before writes even if unnecessary, to get around the
+ * P5 APIC double write bug.
+ */
+static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
+{
+	unsigned int lvtt_value, tmp_value;
+
+	lvtt_value = LOCAL_TIMER_VECTOR;
+	if (!oneshot)
+		lvtt_value |= APIC_LVT_TIMER_PERIODIC;
+	if (!lapic_is_integrated())
+		lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
+
+	if (!irqen)
+		lvtt_value |= APIC_LVT_MASKED;
+
+	apic_write(APIC_LVTT, lvtt_value);
+
+	/*
+	 * Divide PICLK by 16
+	 */
+	tmp_value = apic_read(APIC_TDCR);
+	apic_write(APIC_TDCR,
+		(tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
+		APIC_TDR_DIV_16);
+
+	if (!oneshot)
+		apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
+}
+
+/*
+ * Setup extended LVT, AMD specific (K8, family 10h)
+ *
+ * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
+ * MCE interrupts are supported. Thus MCE offset must be set to 0.
+ *
+ * If mask=1, the LVT entry does not generate interrupts while mask=0
+ * enables the vector. See also the BKDGs.
+ */
+
+#define APIC_EILVT_LVTOFF_MCE 0
+#define APIC_EILVT_LVTOFF_IBS 1
+
+static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
+{
+	unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
+	unsigned int  v   = (mask << 16) | (msg_type << 8) | vector;
+
+	apic_write(reg, v);
+}
+
+u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
+{
+	setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
+	return APIC_EILVT_LVTOFF_MCE;
+}
+
+u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
+{
+	setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
+	return APIC_EILVT_LVTOFF_IBS;
+}
+EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
+
+/*
+ * Program the next event, relative to now
+ */
+static int lapic_next_event(unsigned long delta,
+			    struct clock_event_device *evt)
+{
+	apic_write(APIC_TMICT, delta);
+	return 0;
+}
+
+/*
+ * Setup the lapic timer in periodic or oneshot mode
+ */
+static void lapic_timer_setup(enum clock_event_mode mode,
+			      struct clock_event_device *evt)
+{
+	unsigned long flags;
+	unsigned int v;
+
+	/* Lapic used as dummy for broadcast ? */
+	if (evt->features & CLOCK_EVT_FEAT_DUMMY)
+		return;
+
+	local_irq_save(flags);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+	case CLOCK_EVT_MODE_ONESHOT:
+		__setup_APIC_LVTT(calibration_result,
+				  mode != CLOCK_EVT_MODE_PERIODIC, 1);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		v = apic_read(APIC_LVTT);
+		v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
+		apic_write(APIC_LVTT, v);
+		apic_write(APIC_TMICT, 0xffffffff);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do here */
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+/*
+ * Local APIC timer broadcast function
+ */
+static void lapic_timer_broadcast(const struct cpumask *mask)
+{
+#ifdef CONFIG_SMP
+	apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
+#endif
+}
+
+/*
+ * Setup the local APIC timer for this CPU. Copy the initilized values
+ * of the boot CPU and register the clock event in the framework.
+ */
+static void __cpuinit setup_APIC_timer(void)
+{
+	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
+
+	if (cpu_has(&current_cpu_data, X86_FEATURE_ARAT)) {
+		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
+		/* Make LAPIC timer preferrable over percpu HPET */
+		lapic_clockevent.rating = 150;
+	}
+
+	memcpy(levt, &lapic_clockevent, sizeof(*levt));
+	levt->cpumask = cpumask_of(smp_processor_id());
+
+	clockevents_register_device(levt);
+}
+
+/*
+ * In this functions we calibrate APIC bus clocks to the external timer.
+ *
+ * We want to do the calibration only once since we want to have local timer
+ * irqs syncron. CPUs connected by the same APIC bus have the very same bus
+ * frequency.
+ *
+ * This was previously done by reading the PIT/HPET and waiting for a wrap
+ * around to find out, that a tick has elapsed. I have a box, where the PIT
+ * readout is broken, so it never gets out of the wait loop again. This was
+ * also reported by others.
+ *
+ * Monitoring the jiffies value is inaccurate and the clockevents
+ * infrastructure allows us to do a simple substitution of the interrupt
+ * handler.
+ *
+ * The calibration routine also uses the pm_timer when possible, as the PIT
+ * happens to run way too slow (factor 2.3 on my VAIO CoreDuo, which goes
+ * back to normal later in the boot process).
+ */
+
+#define LAPIC_CAL_LOOPS		(HZ/10)
+
+static __initdata int lapic_cal_loops = -1;
+static __initdata long lapic_cal_t1, lapic_cal_t2;
+static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;
+static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2;
+static __initdata unsigned long lapic_cal_j1, lapic_cal_j2;
+
+/*
+ * Temporary interrupt handler.
+ */
+static void __init lapic_cal_handler(struct clock_event_device *dev)
+{
+	unsigned long long tsc = 0;
+	long tapic = apic_read(APIC_TMCCT);
+	unsigned long pm = acpi_pm_read_early();
+
+	if (cpu_has_tsc)
+		rdtscll(tsc);
+
+	switch (lapic_cal_loops++) {
+	case 0:
+		lapic_cal_t1 = tapic;
+		lapic_cal_tsc1 = tsc;
+		lapic_cal_pm1 = pm;
+		lapic_cal_j1 = jiffies;
+		break;
+
+	case LAPIC_CAL_LOOPS:
+		lapic_cal_t2 = tapic;
+		lapic_cal_tsc2 = tsc;
+		if (pm < lapic_cal_pm1)
+			pm += ACPI_PM_OVRRUN;
+		lapic_cal_pm2 = pm;
+		lapic_cal_j2 = jiffies;
+		break;
+	}
+}
+
+static int __init
+calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
+{
+	const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
+	const long pm_thresh = pm_100ms / 100;
+	unsigned long mult;
+	u64 res;
+
+#ifndef CONFIG_X86_PM_TIMER
+	return -1;
+#endif
+
+	apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm);
+
+	/* Check, if the PM timer is available */
+	if (!deltapm)
+		return -1;
+
+	mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
+
+	if (deltapm > (pm_100ms - pm_thresh) &&
+	    deltapm < (pm_100ms + pm_thresh)) {
+		apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n");
+		return 0;
+	}
+
+	res = (((u64)deltapm) *  mult) >> 22;
+	do_div(res, 1000000);
+	pr_warning("APIC calibration not consistent "
+		   "with PM-Timer: %ldms instead of 100ms\n",(long)res);
+
+	/* Correct the lapic counter value */
+	res = (((u64)(*delta)) * pm_100ms);
+	do_div(res, deltapm);
+	pr_info("APIC delta adjusted to PM-Timer: "
+		"%lu (%ld)\n", (unsigned long)res, *delta);
+	*delta = (long)res;
+
+	/* Correct the tsc counter value */
+	if (cpu_has_tsc) {
+		res = (((u64)(*deltatsc)) * pm_100ms);
+		do_div(res, deltapm);
+		apic_printk(APIC_VERBOSE, "TSC delta adjusted to "
+					  "PM-Timer: %lu (%ld) \n",
+					(unsigned long)res, *deltatsc);
+		*deltatsc = (long)res;
+	}
+
+	return 0;
+}
+
+static int __init calibrate_APIC_clock(void)
+{
+	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
+	void (*real_handler)(struct clock_event_device *dev);
+	unsigned long deltaj;
+	long delta, deltatsc;
+	int pm_referenced = 0;
+
+	local_irq_disable();
+
+	/* Replace the global interrupt handler */
+	real_handler = global_clock_event->event_handler;
+	global_clock_event->event_handler = lapic_cal_handler;
+
+	/*
+	 * Setup the APIC counter to maximum. There is no way the lapic
+	 * can underflow in the 100ms detection time frame
+	 */
+	__setup_APIC_LVTT(0xffffffff, 0, 0);
+
+	/* Let the interrupts run */
+	local_irq_enable();
+
+	while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
+		cpu_relax();
+
+	local_irq_disable();
+
+	/* Restore the real event handler */
+	global_clock_event->event_handler = real_handler;
+
+	/* Build delta t1-t2 as apic timer counts down */
+	delta = lapic_cal_t1 - lapic_cal_t2;
+	apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
+
+	deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
+
+	/* we trust the PM based calibration if possible */
+	pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
+					&delta, &deltatsc);
+
+	/* Calculate the scaled math multiplication factor */
+	lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
+				       lapic_clockevent.shift);
+	lapic_clockevent.max_delta_ns =
+		clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
+	lapic_clockevent.min_delta_ns =
+		clockevent_delta2ns(0xF, &lapic_clockevent);
+
+	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, "..... calibration result: %u\n",
+		    calibration_result);
+
+	if (cpu_has_tsc) {
+		apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
+			    "%ld.%04ld MHz.\n",
+			    (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ),
+			    (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ));
+	}
+
+	apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
+		    "%u.%04u MHz.\n",
+		    calibration_result / (1000000 / HZ),
+		    calibration_result % (1000000 / HZ));
+
+	/*
+	 * Do a sanity check on the APIC calibration result
+	 */
+	if (calibration_result < (1000000 / HZ)) {
+		local_irq_enable();
+		pr_warning("APIC frequency too slow, disabling apic timer\n");
+		return -1;
+	}
+
+	levt->features &= ~CLOCK_EVT_FEAT_DUMMY;
+
+	/*
+	 * PM timer calibration failed or not turned on
+	 * so lets try APIC timer based calibration
+	 */
+	if (!pm_referenced) {
+		apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
+
+		/*
+		 * Setup the apic timer manually
+		 */
+		levt->event_handler = lapic_cal_handler;
+		lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
+		lapic_cal_loops = -1;
+
+		/* Let the interrupts run */
+		local_irq_enable();
+
+		while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
+			cpu_relax();
+
+		/* Stop the lapic timer */
+		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
+
+		/* Jiffies delta */
+		deltaj = lapic_cal_j2 - lapic_cal_j1;
+		apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
+
+		/* Check, if the jiffies result is consistent */
+		if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2)
+			apic_printk(APIC_VERBOSE, "... jiffies result ok\n");
+		else
+			levt->features |= CLOCK_EVT_FEAT_DUMMY;
+	} else
+		local_irq_enable();
+
+	if (levt->features & CLOCK_EVT_FEAT_DUMMY) {
+		pr_warning("APIC timer disabled due to verification failure\n");
+			return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Setup the boot APIC
+ *
+ * Calibrate and verify the result.
+ */
+void __init setup_boot_APIC_clock(void)
+{
+	/*
+	 * The local apic timer can be disabled via the kernel
+	 * commandline or from the CPU detection code. Register the lapic
+	 * timer as a dummy clock event source on SMP systems, so the
+	 * broadcast mechanism is used. On UP systems simply ignore it.
+	 */
+	if (disable_apic_timer) {
+		pr_info("Disabling APIC timer\n");
+		/* No broadcast on UP ! */
+		if (num_possible_cpus() > 1) {
+			lapic_clockevent.mult = 1;
+			setup_APIC_timer();
+		}
+		return;
+	}
+
+	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
+		    "calibrating APIC timer ...\n");
+
+	if (calibrate_APIC_clock()) {
+		/* No broadcast on UP ! */
+		if (num_possible_cpus() > 1)
+			setup_APIC_timer();
+		return;
+	}
+
+	/*
+	 * If nmi_watchdog is set to IO_APIC, we need the
+	 * PIT/HPET going.  Otherwise register lapic as a dummy
+	 * device.
+	 */
+	if (nmi_watchdog != NMI_IO_APIC)
+		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
+	else
+		pr_warning("APIC timer registered as dummy,"
+			" due to nmi_watchdog=%d!\n", nmi_watchdog);
+
+	/* Setup the lapic or request the broadcast */
+	setup_APIC_timer();
+}
+
+void __cpuinit setup_secondary_APIC_clock(void)
+{
+	setup_APIC_timer();
+}
+
+/*
+ * The guts of the apic timer interrupt
+ */
+static void local_apic_timer_interrupt(void)
+{
+	int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
+
+	/*
+	 * Normally we should not be here till LAPIC has been initialized but
+	 * in some cases like kdump, its possible that there is a pending LAPIC
+	 * timer interrupt from previous kernel's context and is delivered in
+	 * new kernel the moment interrupts are enabled.
+	 *
+	 * Interrupts are enabled early and LAPIC is setup much later, hence
+	 * its possible that when we get here evt->event_handler is NULL.
+	 * Check for event_handler being NULL and discard the interrupt as
+	 * spurious.
+	 */
+	if (!evt->event_handler) {
+		pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu);
+		/* Switch it off */
+		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
+		return;
+	}
+
+	/*
+	 * the NMI deadlock-detector uses this.
+	 */
+	inc_irq_stat(apic_timer_irqs);
+
+	evt->event_handler(evt);
+}
+
+/*
+ * Local APIC timer interrupt. This is the most natural way for doing
+ * local interrupts, but local timer interrupts can be emulated by
+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
+ *
+ * [ if a single-CPU system runs an SMP kernel then we call the local
+ *   interrupt as well. Thus we cannot inline the local irq ... ]
+ */
+void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	/*
+	 * NOTE! We'd better ACK the irq immediately,
+	 * because timer handling can be slow.
+	 */
+	ack_APIC_irq();
+	/*
+	 * update_process_times() expects us to have done irq_enter().
+	 * Besides, if we don't timer interrupts ignore the global
+	 * interrupt lock, which is the WrongThing (tm) to do.
+	 */
+	exit_idle();
+	irq_enter();
+	local_apic_timer_interrupt();
+	irq_exit();
+
+	set_irq_regs(old_regs);
+}
+
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return -EINVAL;
+}
+
+/*
+ * Local APIC start and shutdown
+ */
+
+/**
+ * clear_local_APIC - shutdown the local APIC
+ *
+ * This is called, when a CPU is disabled and before rebooting, so the state of
+ * the local APIC has no dangling leftovers. Also used to cleanout any BIOS
+ * leftovers during boot.
+ */
+void clear_local_APIC(void)
+{
+	int maxlvt;
+	u32 v;
+
+	/* APIC hasn't been mapped yet */
+	if (!x2apic && !apic_phys)
+		return;
+
+	maxlvt = lapic_get_maxlvt();
+	/*
+	 * Masking an LVT entry can trigger a local APIC error
+	 * if the vector is zero. Mask LVTERR first to prevent this.
+	 */
+	if (maxlvt >= 3) {
+		v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
+		apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
+	}
+	/*
+	 * Careful: we have to set masks only first to deassert
+	 * any level-triggered sources.
+	 */
+	v = apic_read(APIC_LVTT);
+	apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
+	v = apic_read(APIC_LVT0);
+	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
+	v = apic_read(APIC_LVT1);
+	apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
+	if (maxlvt >= 4) {
+		v = apic_read(APIC_LVTPC);
+		apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
+	}
+
+	/* lets not touch this if we didn't frob it */
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
+	if (maxlvt >= 5) {
+		v = apic_read(APIC_LVTTHMR);
+		apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
+	}
+#endif
+#ifdef CONFIG_X86_MCE_INTEL
+	if (maxlvt >= 6) {
+		v = apic_read(APIC_LVTCMCI);
+		if (!(v & APIC_LVT_MASKED))
+			apic_write(APIC_LVTCMCI, v | APIC_LVT_MASKED);
+	}
+#endif
+
+	/*
+	 * Clean APIC state for other OSs:
+	 */
+	apic_write(APIC_LVTT, APIC_LVT_MASKED);
+	apic_write(APIC_LVT0, APIC_LVT_MASKED);
+	apic_write(APIC_LVT1, APIC_LVT_MASKED);
+	if (maxlvt >= 3)
+		apic_write(APIC_LVTERR, APIC_LVT_MASKED);
+	if (maxlvt >= 4)
+		apic_write(APIC_LVTPC, APIC_LVT_MASKED);
+
+	/* Integrated APIC (!82489DX) ? */
+	if (lapic_is_integrated()) {
+		if (maxlvt > 3)
+			/* Clear ESR due to Pentium errata 3AP and 11AP */
+			apic_write(APIC_ESR, 0);
+		apic_read(APIC_ESR);
+	}
+}
+
+/**
+ * disable_local_APIC - clear and disable the local APIC
+ */
+void disable_local_APIC(void)
+{
+	unsigned int value;
+
+	/* APIC hasn't been mapped yet */
+	if (!apic_phys)
+		return;
+
+	clear_local_APIC();
+
+	/*
+	 * Disable APIC (implies clearing of registers
+	 * for 82489DX!).
+	 */
+	value = apic_read(APIC_SPIV);
+	value &= ~APIC_SPIV_APIC_ENABLED;
+	apic_write(APIC_SPIV, value);
+
+#ifdef CONFIG_X86_32
+	/*
+	 * When LAPIC was disabled by the BIOS and enabled by the kernel,
+	 * restore the disabled state.
+	 */
+	if (enabled_via_apicbase) {
+		unsigned int l, h;
+
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		l &= ~MSR_IA32_APICBASE_ENABLE;
+		wrmsr(MSR_IA32_APICBASE, l, h);
+	}
+#endif
+}
+
+/*
+ * If Linux enabled the LAPIC against the BIOS default disable it down before
+ * re-entering the BIOS on shutdown.  Otherwise the BIOS may get confused and
+ * not power-off.  Additionally clear all LVT entries before disable_local_APIC
+ * for the case where Linux didn't enable the LAPIC.
+ */
+void lapic_shutdown(void)
+{
+	unsigned long flags;
+
+	if (!cpu_has_apic)
+		return;
+
+	local_irq_save(flags);
+
+#ifdef CONFIG_X86_32
+	if (!enabled_via_apicbase)
+		clear_local_APIC();
+	else
+#endif
+		disable_local_APIC();
+
+
+	local_irq_restore(flags);
+}
+
+/*
+ * This is to verify that we're looking at a real local APIC.
+ * Check these against your board if the CPUs aren't getting
+ * started for no apparent reason.
+ */
+int __init verify_local_APIC(void)
+{
+	unsigned int reg0, reg1;
+
+	/*
+	 * The version register is read-only in a real APIC.
+	 */
+	reg0 = apic_read(APIC_LVR);
+	apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
+	apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
+	reg1 = apic_read(APIC_LVR);
+	apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
+
+	/*
+	 * The two version reads above should print the same
+	 * numbers.  If the second one is different, then we
+	 * poke at a non-APIC.
+	 */
+	if (reg1 != reg0)
+		return 0;
+
+	/*
+	 * Check if the version looks reasonably.
+	 */
+	reg1 = GET_APIC_VERSION(reg0);
+	if (reg1 == 0x00 || reg1 == 0xff)
+		return 0;
+	reg1 = lapic_get_maxlvt();
+	if (reg1 < 0x02 || reg1 == 0xff)
+		return 0;
+
+	/*
+	 * The ID register is read/write in a real APIC.
+	 */
+	reg0 = apic_read(APIC_ID);
+	apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
+	apic_write(APIC_ID, reg0 ^ apic->apic_id_mask);
+	reg1 = apic_read(APIC_ID);
+	apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
+	apic_write(APIC_ID, reg0);
+	if (reg1 != (reg0 ^ apic->apic_id_mask))
+		return 0;
+
+	/*
+	 * The next two are just to see if we have sane values.
+	 * They're only really relevant if we're in Virtual Wire
+	 * compatibility mode, but most boxes are anymore.
+	 */
+	reg0 = apic_read(APIC_LVT0);
+	apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
+	reg1 = apic_read(APIC_LVT1);
+	apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
+
+	return 1;
+}
+
+/**
+ * sync_Arb_IDs - synchronize APIC bus arbitration IDs
+ */
+void __init sync_Arb_IDs(void)
+{
+	/*
+	 * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not
+	 * needed on AMD.
+	 */
+	if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+		return;
+
+	/*
+	 * Wait for idle.
+	 */
+	apic_wait_icr_idle();
+
+	apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
+	apic_write(APIC_ICR, APIC_DEST_ALLINC |
+			APIC_INT_LEVELTRIG | APIC_DM_INIT);
+}
+
+/*
+ * An initial setup of the virtual wire mode.
+ */
+void __init init_bsp_APIC(void)
+{
+	unsigned int value;
+
+	/*
+	 * Don't do the setup now if we have a SMP BIOS as the
+	 * through-I/O-APIC virtual wire mode might be active.
+	 */
+	if (smp_found_config || !cpu_has_apic)
+		return;
+
+	/*
+	 * Do not trust the local APIC being empty at bootup.
+	 */
+	clear_local_APIC();
+
+	/*
+	 * Enable APIC.
+	 */
+	value = apic_read(APIC_SPIV);
+	value &= ~APIC_VECTOR_MASK;
+	value |= APIC_SPIV_APIC_ENABLED;
+
+#ifdef CONFIG_X86_32
+	/* This bit is reserved on P4/Xeon and should be cleared */
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
+	    (boot_cpu_data.x86 == 15))
+		value &= ~APIC_SPIV_FOCUS_DISABLED;
+	else
+#endif
+		value |= APIC_SPIV_FOCUS_DISABLED;
+	value |= SPURIOUS_APIC_VECTOR;
+	apic_write(APIC_SPIV, value);
+
+	/*
+	 * Set up the virtual wire mode.
+	 */
+	apic_write(APIC_LVT0, APIC_DM_EXTINT);
+	value = APIC_DM_NMI;
+	if (!lapic_is_integrated())		/* 82489DX */
+		value |= APIC_LVT_LEVEL_TRIGGER;
+	apic_write(APIC_LVT1, value);
+}
+
+static void __cpuinit lapic_setup_esr(void)
+{
+	unsigned int oldvalue, value, maxlvt;
+
+	if (!lapic_is_integrated()) {
+		pr_info("No ESR for 82489DX.\n");
+		return;
+	}
+
+	if (apic->disable_esr) {
+		/*
+		 * Something untraceable is creating bad interrupts on
+		 * secondary quads ... for the moment, just leave the
+		 * ESR disabled - we can't do anything useful with the
+		 * errors anyway - mbligh
+		 */
+		pr_info("Leaving ESR disabled.\n");
+		return;
+	}
+
+	maxlvt = lapic_get_maxlvt();
+	if (maxlvt > 3)		/* Due to the Pentium erratum 3AP. */
+		apic_write(APIC_ESR, 0);
+	oldvalue = apic_read(APIC_ESR);
+
+	/* enables sending errors */
+	value = ERROR_APIC_VECTOR;
+	apic_write(APIC_LVTERR, value);
+
+	/*
+	 * spec says clear errors after enabling vector.
+	 */
+	if (maxlvt > 3)
+		apic_write(APIC_ESR, 0);
+	value = apic_read(APIC_ESR);
+	if (value != oldvalue)
+		apic_printk(APIC_VERBOSE, "ESR value before enabling "
+			"vector: 0x%08x  after: 0x%08x\n",
+			oldvalue, value);
+}
+
+
+/**
+ * setup_local_APIC - setup the local APIC
+ */
+void __cpuinit setup_local_APIC(void)
+{
+	unsigned int value;
+	int i, j;
+
+	if (disable_apic) {
+		arch_disable_smp_support();
+		return;
+	}
+
+#ifdef CONFIG_X86_32
+	/* Pound the ESR really hard over the head with a big hammer - mbligh */
+	if (lapic_is_integrated() && apic->disable_esr) {
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+	}
+#endif
+
+	preempt_disable();
+
+	/*
+	 * Double-check whether this APIC is really registered.
+	 * This is meaningless in clustered apic mode, so we skip it.
+	 */
+	if (!apic->apic_id_registered())
+		BUG();
+
+	/*
+	 * Intel recommends to set DFR, LDR and TPR before enabling
+	 * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+	 * document number 292116).  So here it goes...
+	 */
+	apic->init_apic_ldr();
+
+	/*
+	 * Set Task Priority to 'accept all'. We never change this
+	 * later on.
+	 */
+	value = apic_read(APIC_TASKPRI);
+	value &= ~APIC_TPRI_MASK;
+	apic_write(APIC_TASKPRI, value);
+
+	/*
+	 * After a crash, we no longer service the interrupts and a pending
+	 * interrupt from previous kernel might still have ISR bit set.
+	 *
+	 * Most probably by now CPU has serviced that pending interrupt and
+	 * it might not have done the ack_APIC_irq() because it thought,
+	 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
+	 * does not clear the ISR bit and cpu thinks it has already serivced
+	 * the interrupt. Hence a vector might get locked. It was noticed
+	 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
+	 */
+	for (i = APIC_ISR_NR - 1; i >= 0; i--) {
+		value = apic_read(APIC_ISR + i*0x10);
+		for (j = 31; j >= 0; j--) {
+			if (value & (1<<j))
+				ack_APIC_irq();
+		}
+	}
+
+	/*
+	 * Now that we are all set up, enable the APIC
+	 */
+	value = apic_read(APIC_SPIV);
+	value &= ~APIC_VECTOR_MASK;
+	/*
+	 * Enable APIC
+	 */
+	value |= APIC_SPIV_APIC_ENABLED;
+
+#ifdef CONFIG_X86_32
+	/*
+	 * Some unknown Intel IO/APIC (or APIC) errata is biting us with
+	 * certain networking cards. If high frequency interrupts are
+	 * happening on a particular IOAPIC pin, plus the IOAPIC routing
+	 * entry is masked/unmasked at a high rate as well then sooner or
+	 * later IOAPIC line gets 'stuck', no more interrupts are received
+	 * from the device. If focus CPU is disabled then the hang goes
+	 * away, oh well :-(
+	 *
+	 * [ This bug can be reproduced easily with a level-triggered
+	 *   PCI Ne2000 networking cards and PII/PIII processors, dual
+	 *   BX chipset. ]
+	 */
+	/*
+	 * Actually disabling the focus CPU check just makes the hang less
+	 * frequent as it makes the interrupt distributon model be more
+	 * like LRU than MRU (the short-term load is more even across CPUs).
+	 * See also the comment in end_level_ioapic_irq().  --macro
+	 */
+
+	/*
+	 * - enable focus processor (bit==0)
+	 * - 64bit mode always use processor focus
+	 *   so no need to set it
+	 */
+	value &= ~APIC_SPIV_FOCUS_DISABLED;
+#endif
+
+	/*
+	 * Set spurious IRQ vector
+	 */
+	value |= SPURIOUS_APIC_VECTOR;
+	apic_write(APIC_SPIV, value);
+
+	/*
+	 * Set up LVT0, LVT1:
+	 *
+	 * set up through-local-APIC on the BP's LINT0. This is not
+	 * strictly necessary in pure symmetric-IO mode, but sometimes
+	 * we delegate interrupts to the 8259A.
+	 */
+	/*
+	 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
+	 */
+	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
+	if (!smp_processor_id() && (pic_mode || !value)) {
+		value = APIC_DM_EXTINT;
+		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
+				smp_processor_id());
+	} else {
+		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
+		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
+				smp_processor_id());
+	}
+	apic_write(APIC_LVT0, value);
+
+	/*
+	 * only the BP should see the LINT1 NMI signal, obviously.
+	 */
+	if (!smp_processor_id())
+		value = APIC_DM_NMI;
+	else
+		value = APIC_DM_NMI | APIC_LVT_MASKED;
+	if (!lapic_is_integrated())		/* 82489DX */
+		value |= APIC_LVT_LEVEL_TRIGGER;
+	apic_write(APIC_LVT1, value);
+
+	preempt_enable();
+
+#ifdef CONFIG_X86_MCE_INTEL
+	/* Recheck CMCI information after local APIC is up on CPU #0 */
+	if (smp_processor_id() == 0)
+		cmci_recheck();
+#endif
+}
+
+void __cpuinit end_local_APIC_setup(void)
+{
+	lapic_setup_esr();
+
+#ifdef CONFIG_X86_32
+	{
+		unsigned int value;
+		/* Disable the local apic timer */
+		value = apic_read(APIC_LVTT);
+		value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
+		apic_write(APIC_LVTT, value);
+	}
+#endif
+
+	setup_apic_nmi_watchdog(NULL);
+	apic_pm_activate();
+}
+
+#ifdef CONFIG_X86_X2APIC
+void check_x2apic(void)
+{
+	if (x2apic_enabled()) {
+		pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
+		x2apic_preenabled = x2apic = 1;
+	}
+}
+
+void enable_x2apic(void)
+{
+	int msr, msr2;
+
+	if (!x2apic)
+		return;
+
+	rdmsr(MSR_IA32_APICBASE, msr, msr2);
+	if (!(msr & X2APIC_ENABLE)) {
+		pr_info("Enabling x2apic\n");
+		wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
+	}
+}
+
+void __init enable_IR_x2apic(void)
+{
+#ifdef CONFIG_INTR_REMAP
+	int ret;
+	unsigned long flags;
+	struct IO_APIC_route_entry **ioapic_entries = NULL;
+
+	if (!cpu_has_x2apic)
+		return;
+
+	if (!x2apic_preenabled && disable_x2apic) {
+		pr_info("Skipped enabling x2apic and Interrupt-remapping "
+			"because of nox2apic\n");
+		return;
+	}
+
+	if (x2apic_preenabled && disable_x2apic)
+		panic("Bios already enabled x2apic, can't enforce nox2apic");
+
+	if (!x2apic_preenabled && skip_ioapic_setup) {
+		pr_info("Skipped enabling x2apic and Interrupt-remapping "
+			"because of skipping io-apic setup\n");
+		return;
+	}
+
+	ret = dmar_table_init();
+	if (ret) {
+		pr_info("dmar_table_init() failed with %d:\n", ret);
+
+		if (x2apic_preenabled)
+			panic("x2apic enabled by bios. But IR enabling failed");
+		else
+			pr_info("Not enabling x2apic,Intr-remapping\n");
+		return;
+	}
+
+	ioapic_entries = alloc_ioapic_entries();
+	if (!ioapic_entries) {
+		pr_info("Allocate ioapic_entries failed: %d\n", ret);
+		goto end;
+	}
+
+	ret = save_IO_APIC_setup(ioapic_entries);
+	if (ret) {
+		pr_info("Saving IO-APIC state failed: %d\n", ret);
+		goto end;
+	}
+
+	local_irq_save(flags);
+	mask_IO_APIC_setup(ioapic_entries);
+	mask_8259A();
+
+	ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
+
+	if (ret && x2apic_preenabled) {
+		local_irq_restore(flags);
+		panic("x2apic enabled by bios. But IR enabling failed");
+	}
+
+	if (ret)
+		goto end_restore;
+
+	if (!x2apic) {
+		x2apic = 1;
+		enable_x2apic();
+	}
+
+end_restore:
+	if (ret)
+		/*
+		 * IR enabling failed
+		 */
+		restore_IO_APIC_setup(ioapic_entries);
+	else
+		reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
+
+	unmask_8259A();
+	local_irq_restore(flags);
+
+end:
+	if (!ret) {
+		if (!x2apic_preenabled)
+			pr_info("Enabled x2apic and interrupt-remapping\n");
+		else
+			pr_info("Enabled Interrupt-remapping\n");
+	} else
+		pr_err("Failed to enable Interrupt-remapping and x2apic\n");
+	if (ioapic_entries)
+		free_ioapic_entries(ioapic_entries);
+#else
+	if (!cpu_has_x2apic)
+		return;
+
+	if (x2apic_preenabled)
+		panic("x2apic enabled prior OS handover,"
+		      " enable CONFIG_INTR_REMAP");
+
+	pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
+		" and x2apic\n");
+#endif
+
+	return;
+}
+#endif /* CONFIG_X86_X2APIC */
+
+#ifdef CONFIG_X86_64
+/*
+ * Detect and enable local APICs on non-SMP boards.
+ * Original code written by Keir Fraser.
+ * On AMD64 we trust the BIOS - if it says no APIC it is likely
+ * not correctly set up (usually the APIC timer won't work etc.)
+ */
+static int __init detect_init_APIC(void)
+{
+	if (!cpu_has_apic) {
+		pr_info("No local APIC present\n");
+		return -1;
+	}
+
+	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+	boot_cpu_physical_apicid = 0;
+	return 0;
+}
+#else
+/*
+ * Detect and initialize APIC
+ */
+static int __init detect_init_APIC(void)
+{
+	u32 h, l, features;
+
+	/* Disabled by kernel option? */
+	if (disable_apic)
+		return -1;
+
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_AMD:
+		if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
+		    (boot_cpu_data.x86 >= 15))
+			break;
+		goto no_apic;
+	case X86_VENDOR_INTEL:
+		if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
+		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
+			break;
+		goto no_apic;
+	default:
+		goto no_apic;
+	}
+
+	if (!cpu_has_apic) {
+		/*
+		 * Over-ride BIOS and try to enable the local APIC only if
+		 * "lapic" specified.
+		 */
+		if (!force_enable_local_apic) {
+			pr_info("Local APIC disabled by BIOS -- "
+				"you can enable it with \"lapic\"\n");
+			return -1;
+		}
+		/*
+		 * Some BIOSes disable the local APIC in the APIC_BASE
+		 * MSR. This can only be done in software for Intel P6 or later
+		 * and AMD K7 (Model > 1) or later.
+		 */
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		if (!(l & MSR_IA32_APICBASE_ENABLE)) {
+			pr_info("Local APIC disabled by BIOS -- reenabling.\n");
+			l &= ~MSR_IA32_APICBASE_BASE;
+			l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+			wrmsr(MSR_IA32_APICBASE, l, h);
+			enabled_via_apicbase = 1;
+		}
+	}
+	/*
+	 * The APIC feature bit should now be enabled
+	 * in `cpuid'
+	 */
+	features = cpuid_edx(1);
+	if (!(features & (1 << X86_FEATURE_APIC))) {
+		pr_warning("Could not enable APIC!\n");
+		return -1;
+	}
+	set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
+	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+	/* The BIOS may have set up the APIC at some other address */
+	rdmsr(MSR_IA32_APICBASE, l, h);
+	if (l & MSR_IA32_APICBASE_ENABLE)
+		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
+
+	pr_info("Found and enabled local APIC!\n");
+
+	apic_pm_activate();
+
+	return 0;
+
+no_apic:
+	pr_info("No local APIC present or hardware disabled\n");
+	return -1;
+}
+#endif
+
+#ifdef CONFIG_X86_64
+void __init early_init_lapic_mapping(void)
+{
+	unsigned long phys_addr;
+
+	/*
+	 * If no local APIC can be found then go out
+	 * : it means there is no mpatable and MADT
+	 */
+	if (!smp_found_config)
+		return;
+
+	phys_addr = mp_lapic_addr;
+
+	set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
+	apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
+		    APIC_BASE, phys_addr);
+
+	/*
+	 * Fetch the APIC ID of the BSP in case we have a
+	 * default configuration (or the MP table is broken).
+	 */
+	boot_cpu_physical_apicid = read_apic_id();
+}
+#endif
+
+/**
+ * init_apic_mappings - initialize APIC mappings
+ */
+void __init init_apic_mappings(void)
+{
+	if (x2apic) {
+		boot_cpu_physical_apicid = read_apic_id();
+		return;
+	}
+
+	/*
+	 * If no local APIC can be found then set up a fake all
+	 * zeroes page to simulate the local APIC and another
+	 * one for the IO-APIC.
+	 */
+	if (!smp_found_config && detect_init_APIC()) {
+		apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+		apic_phys = __pa(apic_phys);
+	} else
+		apic_phys = mp_lapic_addr;
+
+	set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
+	apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
+				APIC_BASE, apic_phys);
+
+	/*
+	 * Fetch the APIC ID of the BSP in case we have a
+	 * default configuration (or the MP table is broken).
+	 */
+	if (boot_cpu_physical_apicid == -1U)
+		boot_cpu_physical_apicid = read_apic_id();
+}
+
+/*
+ * This initializes the IO-APIC and APIC hardware if this is
+ * a UP kernel.
+ */
+int apic_version[MAX_APICS];
+
+int __init APIC_init_uniprocessor(void)
+{
+	if (disable_apic) {
+		pr_info("Apic disabled\n");
+		return -1;
+	}
+#ifdef CONFIG_X86_64
+	if (!cpu_has_apic) {
+		disable_apic = 1;
+		pr_info("Apic disabled by BIOS\n");
+		return -1;
+	}
+#else
+	if (!smp_found_config && !cpu_has_apic)
+		return -1;
+
+	/*
+	 * Complain if the BIOS pretends there is one.
+	 */
+	if (!cpu_has_apic &&
+	    APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
+		pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
+			boot_cpu_physical_apicid);
+		clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
+		return -1;
+	}
+#endif
+
+	enable_IR_x2apic();
+#ifdef CONFIG_X86_64
+	default_setup_apic_routing();
+#endif
+
+	verify_local_APIC();
+	connect_bsp_APIC();
+
+#ifdef CONFIG_X86_64
+	apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
+#else
+	/*
+	 * Hack: In case of kdump, after a crash, kernel might be booting
+	 * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
+	 * might be zero if read from MP tables. Get it from LAPIC.
+	 */
+# ifdef CONFIG_CRASH_DUMP
+	boot_cpu_physical_apicid = read_apic_id();
+# endif
+#endif
+	physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
+	setup_local_APIC();
+
+#ifdef CONFIG_X86_IO_APIC
+	/*
+	 * Now enable IO-APICs, actually call clear_IO_APIC
+	 * We need clear_IO_APIC before enabling error vector
+	 */
+	if (!skip_ioapic_setup && nr_ioapics)
+		enable_IO_APIC();
+#endif
+
+	end_local_APIC_setup();
+
+#ifdef CONFIG_X86_IO_APIC
+	if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+		setup_IO_APIC();
+	else {
+		nr_ioapics = 0;
+		localise_nmi_watchdog();
+	}
+#else
+	localise_nmi_watchdog();
+#endif
+
+	setup_boot_clock();
+#ifdef CONFIG_X86_64
+	check_nmi_watchdog();
+#endif
+
+	return 0;
+}
+
+/*
+ * Local APIC interrupts
+ */
+
+/*
+ * This interrupt should _never_ happen with our APIC/SMP architecture
+ */
+void smp_spurious_interrupt(struct pt_regs *regs)
+{
+	u32 v;
+
+	exit_idle();
+	irq_enter();
+	/*
+	 * Check if this really is a spurious interrupt and ACK it
+	 * if it is a vectored one.  Just in case...
+	 * Spurious interrupts should not be ACKed.
+	 */
+	v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
+	if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
+		ack_APIC_irq();
+
+	inc_irq_stat(irq_spurious_count);
+
+	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
+	pr_info("spurious APIC interrupt on CPU#%d, "
+		"should never happen.\n", smp_processor_id());
+	irq_exit();
+}
+
+/*
+ * This interrupt should never happen with our APIC/SMP architecture
+ */
+void smp_error_interrupt(struct pt_regs *regs)
+{
+	u32 v, v1;
+
+	exit_idle();
+	irq_enter();
+	/* First tickle the hardware, only then report what went on. -- REW */
+	v = apic_read(APIC_ESR);
+	apic_write(APIC_ESR, 0);
+	v1 = apic_read(APIC_ESR);
+	ack_APIC_irq();
+	atomic_inc(&irq_err_count);
+
+	/*
+	 * Here is what the APIC error bits mean:
+	 * 0: Send CS error
+	 * 1: Receive CS error
+	 * 2: Send accept error
+	 * 3: Receive accept error
+	 * 4: Reserved
+	 * 5: Send illegal vector
+	 * 6: Received illegal vector
+	 * 7: Illegal register address
+	 */
+	pr_debug("APIC error on CPU%d: %02x(%02x)\n",
+		smp_processor_id(), v , v1);
+	irq_exit();
+}
+
+/**
+ * connect_bsp_APIC - attach the APIC to the interrupt system
+ */
+void __init connect_bsp_APIC(void)
+{
+#ifdef CONFIG_X86_32
+	if (pic_mode) {
+		/*
+		 * Do not trust the local APIC being empty at bootup.
+		 */
+		clear_local_APIC();
+		/*
+		 * PIC mode, enable APIC mode in the IMCR, i.e.  connect BSP's
+		 * local APIC to INT and NMI lines.
+		 */
+		apic_printk(APIC_VERBOSE, "leaving PIC mode, "
+				"enabling APIC mode.\n");
+		outb(0x70, 0x22);
+		outb(0x01, 0x23);
+	}
+#endif
+	if (apic->enable_apic_mode)
+		apic->enable_apic_mode();
+}
+
+/**
+ * disconnect_bsp_APIC - detach the APIC from the interrupt system
+ * @virt_wire_setup:	indicates, whether virtual wire mode is selected
+ *
+ * Virtual wire mode is necessary to deliver legacy interrupts even when the
+ * APIC is disabled.
+ */
+void disconnect_bsp_APIC(int virt_wire_setup)
+{
+	unsigned int value;
+
+#ifdef CONFIG_X86_32
+	if (pic_mode) {
+		/*
+		 * Put the board back into PIC mode (has an effect only on
+		 * certain older boards).  Note that APIC interrupts, including
+		 * IPIs, won't work beyond this point!  The only exception are
+		 * INIT IPIs.
+		 */
+		apic_printk(APIC_VERBOSE, "disabling APIC mode, "
+				"entering PIC mode.\n");
+		outb(0x70, 0x22);
+		outb(0x00, 0x23);
+		return;
+	}
+#endif
+
+	/* Go back to Virtual Wire compatibility mode */
+
+	/* For the spurious interrupt use vector F, and enable it */
+	value = apic_read(APIC_SPIV);
+	value &= ~APIC_VECTOR_MASK;
+	value |= APIC_SPIV_APIC_ENABLED;
+	value |= 0xf;
+	apic_write(APIC_SPIV, value);
+
+	if (!virt_wire_setup) {
+		/*
+		 * For LVT0 make it edge triggered, active high,
+		 * external and enabled
+		 */
+		value = apic_read(APIC_LVT0);
+		value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
+		apic_write(APIC_LVT0, value);
+	} else {
+		/* Disable LVT0 */
+		apic_write(APIC_LVT0, APIC_LVT_MASKED);
+	}
+
+	/*
+	 * For LVT1 make it edge triggered, active high,
+	 * nmi and enabled
+	 */
+	value = apic_read(APIC_LVT1);
+	value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+	value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+	value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+	apic_write(APIC_LVT1, value);
+}
+
+void __cpuinit generic_processor_info(int apicid, int version)
+{
+	int cpu;
+
+	/*
+	 * Validate version
+	 */
+	if (version == 0x0) {
+		pr_warning("BIOS bug, APIC version is 0 for CPU#%d! "
+			   "fixing up to 0x10. (tell your hw vendor)\n",
+				version);
+		version = 0x10;
+	}
+	apic_version[apicid] = version;
+
+	if (num_processors >= nr_cpu_ids) {
+		int max = nr_cpu_ids;
+		int thiscpu = max + disabled_cpus;
+
+		pr_warning(
+			"ACPI: NR_CPUS/possible_cpus limit of %i reached."
+			"  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
+
+		disabled_cpus++;
+		return;
+	}
+
+	num_processors++;
+	cpu = cpumask_next_zero(-1, cpu_present_mask);
+
+	if (version != apic_version[boot_cpu_physical_apicid])
+		WARN_ONCE(1,
+			"ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n",
+			apic_version[boot_cpu_physical_apicid], cpu, version);
+
+	physid_set(apicid, phys_cpu_present_map);
+	if (apicid == boot_cpu_physical_apicid) {
+		/*
+		 * x86_bios_cpu_apicid is required to have processors listed
+		 * in same order as logical cpu numbers. Hence the first
+		 * entry is BSP, and so on.
+		 */
+		cpu = 0;
+	}
+	if (apicid > max_physical_apicid)
+		max_physical_apicid = apicid;
+
+#ifdef CONFIG_X86_32
+	/*
+	 * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
+	 * but we need to work other dependencies like SMP_SUSPEND etc
+	 * before this can be done without some confusion.
+	 * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
+	 *       - Ashok Raj <ashok.raj@intel.com>
+	 */
+	if (max_physical_apicid >= 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;
+		}
+	}
+#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;
+#endif
+
+	set_cpu_possible(cpu, true);
+	set_cpu_present(cpu, true);
+}
+
+int hard_smp_processor_id(void)
+{
+	return read_apic_id();
+}
+
+void default_init_apic_ldr(void)
+{
+	unsigned long val;
+
+	apic_write(APIC_DFR, APIC_DFR_VALUE);
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
+	apic_write(APIC_LDR, val);
+}
+
+#ifdef CONFIG_X86_32
+int default_apicid_to_node(int logical_apicid)
+{
+#ifdef CONFIG_SMP
+	return apicid_2_node[hard_smp_processor_id()];
+#else
+	return 0;
+#endif
+}
+#endif
+
+/*
+ * Power management
+ */
+#ifdef CONFIG_PM
+
+static struct {
+	/*
+	 * 'active' is true if the local APIC was enabled by us and
+	 * not the BIOS; this signifies that we are also responsible
+	 * for disabling it before entering apm/acpi suspend
+	 */
+	int active;
+	/* r/w apic fields */
+	unsigned int apic_id;
+	unsigned int apic_taskpri;
+	unsigned int apic_ldr;
+	unsigned int apic_dfr;
+	unsigned int apic_spiv;
+	unsigned int apic_lvtt;
+	unsigned int apic_lvtpc;
+	unsigned int apic_lvt0;
+	unsigned int apic_lvt1;
+	unsigned int apic_lvterr;
+	unsigned int apic_tmict;
+	unsigned int apic_tdcr;
+	unsigned int apic_thmr;
+} apic_pm_state;
+
+static int lapic_suspend(struct sys_device *dev, pm_message_t state)
+{
+	unsigned long flags;
+	int maxlvt;
+
+	if (!apic_pm_state.active)
+		return 0;
+
+	maxlvt = lapic_get_maxlvt();
+
+	apic_pm_state.apic_id = apic_read(APIC_ID);
+	apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
+	apic_pm_state.apic_ldr = apic_read(APIC_LDR);
+	apic_pm_state.apic_dfr = apic_read(APIC_DFR);
+	apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
+	apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
+	if (maxlvt >= 4)
+		apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
+	apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
+	apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
+	apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
+	apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
+	apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
+	if (maxlvt >= 5)
+		apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
+#endif
+
+	local_irq_save(flags);
+	disable_local_APIC();
+#ifdef CONFIG_INTR_REMAP
+	if (intr_remapping_enabled)
+		disable_intr_remapping();
+#endif
+	local_irq_restore(flags);
+	return 0;
+}
+
+static int lapic_resume(struct sys_device *dev)
+{
+	unsigned int l, h;
+	unsigned long flags;
+	int maxlvt;
+
+#ifdef CONFIG_INTR_REMAP
+	int ret;
+	struct IO_APIC_route_entry **ioapic_entries = NULL;
+
+	if (!apic_pm_state.active)
+		return 0;
+
+	local_irq_save(flags);
+	if (x2apic) {
+		ioapic_entries = alloc_ioapic_entries();
+		if (!ioapic_entries) {
+			WARN(1, "Alloc ioapic_entries in lapic resume failed.");
+			return -ENOMEM;
+		}
+
+		ret = save_IO_APIC_setup(ioapic_entries);
+		if (ret) {
+			WARN(1, "Saving IO-APIC state failed: %d\n", ret);
+			free_ioapic_entries(ioapic_entries);
+			return ret;
+		}
+
+		mask_IO_APIC_setup(ioapic_entries);
+		mask_8259A();
+		enable_x2apic();
+	}
+#else
+	if (!apic_pm_state.active)
+		return 0;
+
+	local_irq_save(flags);
+	if (x2apic)
+		enable_x2apic();
+#endif
+
+	else {
+		/*
+		 * Make sure the APICBASE points to the right address
+		 *
+		 * FIXME! This will be wrong if we ever support suspend on
+		 * SMP! We'll need to do this as part of the CPU restore!
+		 */
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		l &= ~MSR_IA32_APICBASE_BASE;
+		l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
+		wrmsr(MSR_IA32_APICBASE, l, h);
+	}
+
+	maxlvt = lapic_get_maxlvt();
+	apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
+	apic_write(APIC_ID, apic_pm_state.apic_id);
+	apic_write(APIC_DFR, apic_pm_state.apic_dfr);
+	apic_write(APIC_LDR, apic_pm_state.apic_ldr);
+	apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri);
+	apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
+	apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
+	apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
+	if (maxlvt >= 5)
+		apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
+#endif
+	if (maxlvt >= 4)
+		apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
+	apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
+	apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
+	apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
+	apic_write(APIC_ESR, 0);
+	apic_read(APIC_ESR);
+	apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
+	apic_write(APIC_ESR, 0);
+	apic_read(APIC_ESR);
+
+#ifdef CONFIG_INTR_REMAP
+	if (intr_remapping_enabled)
+		reenable_intr_remapping(EIM_32BIT_APIC_ID);
+
+	if (x2apic) {
+		unmask_8259A();
+		restore_IO_APIC_setup(ioapic_entries);
+		free_ioapic_entries(ioapic_entries);
+	}
+#endif
+
+	local_irq_restore(flags);
+
+
+	return 0;
+}
+
+/*
+ * This device has no shutdown method - fully functioning local APICs
+ * are needed on every CPU up until machine_halt/restart/poweroff.
+ */
+
+static struct sysdev_class lapic_sysclass = {
+	.name		= "lapic",
+	.resume		= lapic_resume,
+	.suspend	= lapic_suspend,
+};
+
+static struct sys_device device_lapic = {
+	.id	= 0,
+	.cls	= &lapic_sysclass,
+};
+
+static void __cpuinit apic_pm_activate(void)
+{
+	apic_pm_state.active = 1;
+}
+
+static int __init init_lapic_sysfs(void)
+{
+	int error;
+
+	if (!cpu_has_apic)
+		return 0;
+	/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
+
+	error = sysdev_class_register(&lapic_sysclass);
+	if (!error)
+		error = sysdev_register(&device_lapic);
+	return error;
+}
+
+/* local apic needs to resume before other devices access its registers. */
+core_initcall(init_lapic_sysfs);
+
+#else	/* CONFIG_PM */
+
+static void apic_pm_activate(void) { }
+
+#endif	/* CONFIG_PM */
+
+#ifdef CONFIG_X86_64
+/*
+ * apic_is_clustered_box() -- Check if we can expect good TSC
+ *
+ * Thus far, the major user of this is IBM's Summit2 series:
+ *
+ * Clustered boxes may have unsynced TSC problems if they are
+ * multi-chassis. Use available data to take a good guess.
+ * If in doubt, go HPET.
+ */
+__cpuinit int apic_is_clustered_box(void)
+{
+	int i, clusters, zeros;
+	unsigned id;
+	u16 *bios_cpu_apicid;
+	DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
+
+	/*
+	 * there is not this kind of box with AMD CPU yet.
+	 * Some AMD box with quadcore cpu and 8 sockets apicid
+	 * will be [4, 0x23] or [8, 0x27] could be thought to
+	 * vsmp box still need checking...
+	 */
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
+		return 0;
+
+	bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
+	bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
+
+	for (i = 0; i < nr_cpu_ids; i++) {
+		/* are we being called early in kernel startup? */
+		if (bios_cpu_apicid) {
+			id = bios_cpu_apicid[i];
+		} else if (i < nr_cpu_ids) {
+			if (cpu_present(i))
+				id = per_cpu(x86_bios_cpu_apicid, i);
+			else
+				continue;
+		} else
+			break;
+
+		if (id != BAD_APICID)
+			__set_bit(APIC_CLUSTERID(id), clustermap);
+	}
+
+	/* Problem:  Partially populated chassis may not have CPUs in some of
+	 * the APIC clusters they have been allocated.  Only present CPUs have
+	 * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
+	 * Since clusters are allocated sequentially, count zeros only if
+	 * they are bounded by ones.
+	 */
+	clusters = 0;
+	zeros = 0;
+	for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
+		if (test_bit(i, clustermap)) {
+			clusters += 1 + zeros;
+			zeros = 0;
+		} else
+			++zeros;
+	}
+
+	/* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
+	 * not guaranteed to be synced between boards
+	 */
+	if (is_vsmp_box() && clusters > 1)
+		return 1;
+
+	/*
+	 * If clusters > 2, then should be multi-chassis.
+	 * May have to revisit this when multi-core + hyperthreaded CPUs come
+	 * out, but AFAIK this will work even for them.
+	 */
+	return (clusters > 2);
+}
+#endif
+
+/*
+ * APIC command line parameters
+ */
+static int __init setup_disableapic(char *arg)
+{
+	disable_apic = 1;
+	setup_clear_cpu_cap(X86_FEATURE_APIC);
+	return 0;
+}
+early_param("disableapic", setup_disableapic);
+
+/* same as disableapic, for compatibility */
+static int __init setup_nolapic(char *arg)
+{
+	return setup_disableapic(arg);
+}
+early_param("nolapic", setup_nolapic);
+
+static int __init parse_lapic_timer_c2_ok(char *arg)
+{
+	local_apic_timer_c2_ok = 1;
+	return 0;
+}
+early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
+
+static int __init parse_disable_apic_timer(char *arg)
+{
+	disable_apic_timer = 1;
+	return 0;
+}
+early_param("noapictimer", parse_disable_apic_timer);
+
+static int __init parse_nolapic_timer(char *arg)
+{
+	disable_apic_timer = 1;
+	return 0;
+}
+early_param("nolapic_timer", parse_nolapic_timer);
+
+static int __init apic_set_verbosity(char *arg)
+{
+	if (!arg)  {
+#ifdef CONFIG_X86_64
+		skip_ioapic_setup = 0;
+		return 0;
+#endif
+		return -EINVAL;
+	}
+
+	if (strcmp("debug", arg) == 0)
+		apic_verbosity = APIC_DEBUG;
+	else if (strcmp("verbose", arg) == 0)
+		apic_verbosity = APIC_VERBOSE;
+	else {
+		pr_warning("APIC Verbosity level %s not recognised"
+			" use apic=verbose or apic=debug\n", arg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+early_param("apic", apic_set_verbosity);
+
+static int __init lapic_insert_resource(void)
+{
+	if (!apic_phys)
+		return -1;
+
+	/* Put local APIC into the resource map. */
+	lapic_resource.start = apic_phys;
+	lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
+	insert_resource(&iomem_resource, &lapic_resource);
+
+	return 0;
+}
+
+/*
+ * need call insert after e820_reserve_resources()
+ * that is using request_resource
+ */
+late_initcall(lapic_insert_resource);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/apic_flat_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/apic_flat_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/apic_flat_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/apic_flat_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,373 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Flat APIC subarch code.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ */
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/hardirq.h>
+#include <asm/smp.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
+
+static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	return 1;
+}
+
+static const struct cpumask *flat_target_cpus(void)
+{
+	return cpu_online_mask;
+}
+
+static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	/* Careful. Some cpus do not strictly honor the set of cpus
+	 * specified in the interrupt destination when using lowest
+	 * priority interrupt delivery mode.
+	 *
+	 * In particular there was a hyperthreading cpu observed to
+	 * deliver interrupts to the wrong hyperthread when only one
+	 * hyperthread was specified in the interrupt desitination.
+	 */
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static void flat_init_apic_ldr(void)
+{
+	unsigned long val;
+	unsigned long num, id;
+
+	num = smp_processor_id();
+	id = 1UL << num;
+	apic_write(APIC_DFR, APIC_DFR_FLAT);
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	val |= SET_APIC_LOGICAL_ID(id);
+	apic_write(APIC_LDR, val);
+}
+
+static inline void _flat_send_IPI_mask(unsigned long mask, int vector)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__default_send_IPI_dest_field(mask, vector, apic->dest_logical);
+	local_irq_restore(flags);
+}
+
+static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
+{
+	unsigned long mask = cpumask_bits(cpumask)[0];
+
+	_flat_send_IPI_mask(mask, vector);
+}
+
+static void
+ flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)
+{
+	unsigned long mask = cpumask_bits(cpumask)[0];
+	int cpu = smp_processor_id();
+
+	if (cpu < BITS_PER_LONG)
+		clear_bit(cpu, &mask);
+
+	_flat_send_IPI_mask(mask, vector);
+}
+
+static void flat_send_IPI_allbutself(int vector)
+{
+	int cpu = smp_processor_id();
+#ifdef	CONFIG_HOTPLUG_CPU
+	int hotplug = 1;
+#else
+	int hotplug = 0;
+#endif
+	if (hotplug || vector == NMI_VECTOR) {
+		if (!cpumask_equal(cpu_online_mask, cpumask_of(cpu))) {
+			unsigned long mask = cpumask_bits(cpu_online_mask)[0];
+
+			if (cpu < BITS_PER_LONG)
+				clear_bit(cpu, &mask);
+
+			_flat_send_IPI_mask(mask, vector);
+		}
+	} else if (num_online_cpus() > 1) {
+		__default_send_IPI_shortcut(APIC_DEST_ALLBUT,
+					    vector, apic->dest_logical);
+	}
+}
+
+static void flat_send_IPI_all(int vector)
+{
+	if (vector == NMI_VECTOR) {
+		flat_send_IPI_mask(cpu_online_mask, vector);
+	} else {
+		__default_send_IPI_shortcut(APIC_DEST_ALLINC,
+					    vector, apic->dest_logical);
+	}
+}
+
+static unsigned int flat_get_apic_id(unsigned long x)
+{
+	unsigned int id;
+
+	id = (((x)>>24) & 0xFFu);
+
+	return id;
+}
+
+static unsigned long set_apic_id(unsigned int id)
+{
+	unsigned long x;
+
+	x = ((id & 0xFFu)<<24);
+	return x;
+}
+
+static unsigned int read_xapic_id(void)
+{
+	unsigned int id;
+
+	id = flat_get_apic_id(apic_read(APIC_ID));
+	return id;
+}
+
+static int flat_apic_id_registered(void)
+{
+	return physid_isset(read_xapic_id(), phys_cpu_present_map);
+}
+
+static int flat_phys_pkg_id(int initial_apic_id, int index_msb)
+{
+	return hard_smp_processor_id() >> index_msb;
+}
+
+struct apic apic_flat =  {
+	.name				= "flat",
+	.probe				= NULL,
+	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
+	.apic_id_registered		= flat_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	.irq_dest_mode			= 1, /* logical */
+
+	.target_cpus			= flat_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= NULL,
+	.check_apicid_present		= NULL,
+
+	.vector_allocation_domain	= flat_vector_allocation_domain,
+	.init_apic_ldr			= flat_init_apic_ldr,
+
+	.ioapic_phys_id_map		= NULL,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= NULL,
+	.cpu_to_logical_apicid		= NULL,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= NULL,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= flat_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= flat_get_apic_id,
+	.set_apic_id			= set_apic_id,
+	.apic_id_mask			= 0xFFu << 24,
+
+	.cpu_mask_to_apicid		= default_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= flat_send_IPI_mask,
+	.send_IPI_mask_allbutself	= flat_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= flat_send_IPI_allbutself,
+	.send_IPI_all			= flat_send_IPI_all,
+	.send_IPI_self			= apic_send_IPI_self,
+
+	.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		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
+
+/*
+ * Physflat mode is used when there are more than 8 CPUs on a AMD system.
+ * We cannot use logical delivery in this case because the mask
+ * overflows, so use physical mode.
+ */
+static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+#ifdef CONFIG_ACPI
+	/*
+	 * Quirk: some x86_64 machines can only use physical APIC mode
+	 * regardless of how many processors are present (x86_64 ES7000
+	 * is an example).
+	 */
+	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
+		printk(KERN_DEBUG "system APIC only can use physical flat");
+		return 1;
+	}
+#endif
+
+	return 0;
+}
+
+static const struct cpumask *physflat_target_cpus(void)
+{
+	return cpu_online_mask;
+}
+
+static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector)
+{
+	default_send_IPI_mask_sequence_phys(cpumask, vector);
+}
+
+static void physflat_send_IPI_mask_allbutself(const struct cpumask *cpumask,
+					      int vector)
+{
+	default_send_IPI_mask_allbutself_phys(cpumask, vector);
+}
+
+static void physflat_send_IPI_allbutself(int vector)
+{
+	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
+}
+
+static void physflat_send_IPI_all(int vector)
+{
+	physflat_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	cpu = cpumask_first(cpumask);
+	if ((unsigned)cpu < nr_cpu_ids)
+		return per_cpu(x86_cpu_to_apicid, cpu);
+	else
+		return BAD_APICID;
+}
+
+static unsigned int
+physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+				const struct cpumask *andmask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	for_each_cpu_and(cpu, cpumask, andmask) {
+		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;
+}
+
+struct apic apic_physflat =  {
+
+	.name				= "physical flat",
+	.probe				= NULL,
+	.acpi_madt_oem_check		= physflat_acpi_madt_oem_check,
+	.apic_id_registered		= flat_apic_id_registered,
+
+	.irq_delivery_mode		= dest_Fixed,
+	.irq_dest_mode			= 0, /* physical */
+
+	.target_cpus			= physflat_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= 0,
+	.check_apicid_used		= NULL,
+	.check_apicid_present		= NULL,
+
+	.vector_allocation_domain	= physflat_vector_allocation_domain,
+	/* not needed, but shouldn't hurt: */
+	.init_apic_ldr			= flat_init_apic_ldr,
+
+	.ioapic_phys_id_map		= NULL,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= NULL,
+	.cpu_to_logical_apicid		= NULL,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= NULL,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= flat_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= flat_get_apic_id,
+	.set_apic_id			= set_apic_id,
+	.apic_id_mask			= 0xFFu << 24,
+
+	.cpu_mask_to_apicid		= physflat_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= physflat_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= physflat_send_IPI_mask,
+	.send_IPI_mask_allbutself	= physflat_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= physflat_send_IPI_allbutself,
+	.send_IPI_all			= physflat_send_IPI_all,
+	.send_IPI_self			= apic_send_IPI_self,
+
+	.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		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/bigsmp_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/bigsmp_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/bigsmp_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/bigsmp_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,267 @@
+/*
+ * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
+ *
+ * Drives the local APIC in "clustered mode".
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+#include <linux/smp.h>
+
+#include <asm/apicdef.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+static unsigned bigsmp_get_apic_id(unsigned long x)
+{
+	return (x >> 24) & 0xFF;
+}
+
+static int bigsmp_apic_id_registered(void)
+{
+	return 1;
+}
+
+static const struct cpumask *bigsmp_target_cpus(void)
+{
+#ifdef CONFIG_SMP
+	return cpu_online_mask;
+#else
+	return cpumask_of(0);
+#endif
+}
+
+static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+	return 0;
+}
+
+static unsigned long bigsmp_check_apicid_present(int bit)
+{
+	return 1;
+}
+
+static inline unsigned long calculate_ldr(int cpu)
+{
+	unsigned long val, id;
+
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	id = per_cpu(x86_bios_cpu_apicid, cpu);
+	val |= SET_APIC_LOGICAL_ID(id);
+
+	return val;
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static void bigsmp_init_apic_ldr(void)
+{
+	unsigned long val;
+	int cpu = smp_processor_id();
+
+	apic_write(APIC_DFR, APIC_DFR_FLAT);
+	val = calculate_ldr(cpu);
+	apic_write(APIC_LDR, val);
+}
+
+static void bigsmp_setup_apic_routing(void)
+{
+	printk(KERN_INFO
+		"Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
+		nr_ioapics);
+}
+
+static int bigsmp_apicid_to_node(int logical_apicid)
+{
+	return apicid_2_node[hard_smp_processor_id()];
+}
+
+static int bigsmp_cpu_present_to_apicid(int mps_cpu)
+{
+	if (mps_cpu < nr_cpu_ids)
+		return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
+
+	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)
+{
+	if (cpu >= nr_cpu_ids)
+		return BAD_APICID;
+	return cpu_physical_id(cpu);
+}
+
+static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+	/* For clustered we don't have a good way to do this yet - hack */
+	return physids_promote(0xFFL);
+}
+
+static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return 1;
+}
+
+/* As we are using single CPU as destination, pick only one CPU here */
+static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask));
+}
+
+static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			      const struct cpumask *andmask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	for_each_cpu_and(cpu, cpumask, andmask) {
+		if (cpumask_test_cpu(cpu, cpu_online_mask))
+			break;
+	}
+	if (cpu < nr_cpu_ids)
+		return bigsmp_cpu_to_logical_apicid(cpu);
+
+	return BAD_APICID;
+}
+
+static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
+static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	default_send_IPI_mask_sequence_phys(mask, vector);
+}
+
+static void bigsmp_send_IPI_allbutself(int vector)
+{
+	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
+}
+
+static void bigsmp_send_IPI_all(int vector)
+{
+	bigsmp_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int dmi_bigsmp; /* can be set by dmi scanners */
+
+static int hp_ht_bigsmp(const struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
+	dmi_bigsmp = 1;
+
+	return 0;
+}
+
+
+static const struct dmi_system_id bigsmp_dmi_table[] = {
+	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
+		}
+	},
+
+	{ hp_ht_bigsmp, "HP ProLiant DL740",
+		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
+		}
+	},
+	{ } /* NULL entry stops DMI scanning */
+};
+
+static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static int probe_bigsmp(void)
+{
+	if (def_to_bigsmp)
+		dmi_bigsmp = 1;
+	else
+		dmi_check_system(bigsmp_dmi_table);
+
+	return dmi_bigsmp;
+}
+
+struct apic apic_bigsmp = {
+
+	.name				= "bigsmp",
+	.probe				= probe_bigsmp,
+	.acpi_madt_oem_check		= NULL,
+	.apic_id_registered		= bigsmp_apic_id_registered,
+
+	.irq_delivery_mode		= dest_Fixed,
+	/* phys delivery to target CPU: */
+	.irq_dest_mode			= 0,
+
+	.target_cpus			= bigsmp_target_cpus,
+	.disable_esr			= 1,
+	.dest_logical			= 0,
+	.check_apicid_used		= bigsmp_check_apicid_used,
+	.check_apicid_present		= bigsmp_check_apicid_present,
+
+	.vector_allocation_domain	= bigsmp_vector_allocation_domain,
+	.init_apic_ldr			= bigsmp_init_apic_ldr,
+
+	.ioapic_phys_id_map		= bigsmp_ioapic_phys_id_map,
+	.setup_apic_routing		= bigsmp_setup_apic_routing,
+	.multi_timer_check		= NULL,
+	.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,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= bigsmp_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= bigsmp_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= bigsmp_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0xFF << 24,
+
+	.cpu_mask_to_apicid		= bigsmp_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= bigsmp_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= bigsmp_send_IPI_mask,
+	.send_IPI_mask_allbutself	= NULL,
+	.send_IPI_allbutself		= bigsmp_send_IPI_allbutself,
+	.send_IPI_all			= bigsmp_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW,
+	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+	.wait_for_init_deassert		= default_wait_for_init_deassert,
+
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/es7000_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/es7000_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/es7000_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/es7000_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,781 @@
+/*
+ * Written by: Garry Forsgren, Unisys Corporation
+ *             Natalie Protasevich, Unisys Corporation
+ *
+ * This file contains the code to configure and interface
+ * with Unisys ES7000 series hardware system manager.
+ *
+ * Copyright (c) 2003 Unisys Corporation.
+ * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
+ *
+ *   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 would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Unisys Corporation, Township Line & Union Meeting
+ * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
+ *
+ * http://www.unisys.com
+ */
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/apicdef.h>
+#include <asm/atomic.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+/*
+ * ES7000 chipsets
+ */
+
+#define NON_UNISYS			0
+#define ES7000_CLASSIC			1
+#define ES7000_ZORRO			2
+
+#define	MIP_REG				1
+#define	MIP_PSAI_REG			4
+
+#define	MIP_BUSY			1
+#define	MIP_SPIN			0xf0000
+#define	MIP_VALID			0x0100000000000000ULL
+#define	MIP_SW_APIC			0x1020b
+
+#define	MIP_PORT(val)			((val >> 32) & 0xffff)
+
+#define	MIP_RD_LO(val)			(val & 0xffffffff)
+
+struct mip_reg {
+	unsigned long long		off_0x00;
+	unsigned long long		off_0x08;
+	unsigned long long		off_0x10;
+	unsigned long long		off_0x18;
+	unsigned long long		off_0x20;
+	unsigned long long		off_0x28;
+	unsigned long long		off_0x30;
+	unsigned long long		off_0x38;
+};
+
+struct mip_reg_info {
+	unsigned long long		mip_info;
+	unsigned long long		delivery_info;
+	unsigned long long		host_reg;
+	unsigned long long		mip_reg;
+};
+
+struct psai {
+	unsigned long long		entry_type;
+	unsigned long long		addr;
+	unsigned long long		bep_addr;
+};
+
+#ifdef CONFIG_ACPI
+
+struct es7000_oem_table {
+	struct acpi_table_header	Header;
+	u32				OEMTableAddr;
+	u32				OEMTableSize;
+};
+
+static unsigned long			oem_addrX;
+static unsigned long			oem_size;
+
+#endif
+
+/*
+ * ES7000 Globals
+ */
+
+static volatile unsigned long		*psai;
+static struct mip_reg			*mip_reg;
+static struct mip_reg			*host_reg;
+static int 				mip_port;
+static unsigned long			mip_addr;
+static unsigned long			host_addr;
+
+int					es7000_plat;
+
+/*
+ * GSI override for ES7000 platforms.
+ */
+
+static unsigned int			base;
+
+static int
+es7000_rename_gsi(int ioapic, int gsi)
+{
+	if (es7000_plat == ES7000_ZORRO)
+		return gsi;
+
+	if (!base) {
+		int i;
+		for (i = 0; i < nr_ioapics; i++)
+			base += nr_ioapic_registers[i];
+	}
+
+	if (!ioapic && (gsi < 16))
+		gsi += base;
+
+	return gsi;
+}
+
+static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
+{
+	unsigned long vect = 0, psaival = 0;
+
+	if (psai == NULL)
+		return -1;
+
+	vect = ((unsigned long)__pa(eip)/0x1000) << 16;
+	psaival = (0x1000000 | vect | cpu);
+
+	while (*psai & 0x1000000)
+		;
+
+	*psai = psaival;
+
+	return 0;
+}
+
+static int es7000_apic_is_cluster(void)
+{
+	/* MPENTIUMIII */
+	if (boot_cpu_data.x86 == 6 &&
+	    (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11))
+		return 1;
+
+	return 0;
+}
+
+static void setup_unisys(void)
+{
+	/*
+	 * Determine the generation of the ES7000 currently running.
+	 *
+	 * es7000_plat = 1 if the machine is a 5xx ES7000 box
+	 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
+	 *
+	 */
+	if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
+		es7000_plat = ES7000_ZORRO;
+	else
+		es7000_plat = ES7000_CLASSIC;
+	ioapic_renumber_irq = es7000_rename_gsi;
+}
+
+/*
+ * Parse the OEM Table:
+ */
+static int parse_unisys_oem(char *oemptr)
+{
+	int			i;
+	int 			success = 0;
+	unsigned char		type, size;
+	unsigned long		val;
+	char			*tp = NULL;
+	struct psai		*psaip = NULL;
+	struct mip_reg_info 	*mi;
+	struct mip_reg		*host, *mip;
+
+	tp = oemptr;
+
+	tp += 8;
+
+	for (i = 0; i <= 6; i++) {
+		type = *tp++;
+		size = *tp++;
+		tp -= 2;
+		switch (type) {
+		case MIP_REG:
+			mi = (struct mip_reg_info *)tp;
+			val = MIP_RD_LO(mi->host_reg);
+			host_addr = val;
+			host = (struct mip_reg *)val;
+			host_reg = __va(host);
+			val = MIP_RD_LO(mi->mip_reg);
+			mip_port = MIP_PORT(mi->mip_info);
+			mip_addr = val;
+			mip = (struct mip_reg *)val;
+			mip_reg = __va(mip);
+			pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
+				 (unsigned long)host_reg);
+			pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
+				 (unsigned long)mip_reg);
+			success++;
+			break;
+		case MIP_PSAI_REG:
+			psaip = (struct psai *)tp;
+			if (tp != NULL) {
+				if (psaip->addr)
+					psai = __va(psaip->addr);
+				else
+					psai = NULL;
+				success++;
+			}
+			break;
+		default:
+			break;
+		}
+		tp += size;
+	}
+
+	if (success < 2)
+		es7000_plat = NON_UNISYS;
+	else
+		setup_unisys();
+
+	return es7000_plat;
+}
+
+#ifdef CONFIG_ACPI
+static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
+{
+	struct acpi_table_header *header = NULL;
+	struct es7000_oem_table *table;
+	acpi_size tbl_size;
+	acpi_status ret;
+	int i = 0;
+
+	for (;;) {
+		ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
+		if (!ACPI_SUCCESS(ret))
+			return -1;
+
+		if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
+			break;
+
+		early_acpi_os_unmap_memory(header, tbl_size);
+	}
+
+	table = (void *)header;
+
+	oem_addrX	= table->OEMTableAddr;
+	oem_size	= table->OEMTableSize;
+
+	early_acpi_os_unmap_memory(header, tbl_size);
+
+	*oem_addr	= (unsigned long)__acpi_map_table(oem_addrX, oem_size);
+
+	return 0;
+}
+
+static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
+{
+	if (!oem_addr)
+		return;
+
+	__acpi_unmap_table((char *)oem_addr, oem_size);
+}
+
+static int es7000_check_dsdt(void)
+{
+	struct acpi_table_header header;
+
+	if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
+	    !strncmp(header.oem_id, "UNISYS", 6))
+		return 1;
+	return 0;
+}
+
+static int es7000_acpi_ret;
+
+/* Hook from generic ACPI tables.c */
+static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	unsigned long oem_addr = 0;
+	int check_dsdt;
+	int ret = 0;
+
+	/* check dsdt at first to avoid clear fix_map for oem_addr */
+	check_dsdt = es7000_check_dsdt();
+
+	if (!find_unisys_acpi_oem_table(&oem_addr)) {
+		if (check_dsdt) {
+			ret = parse_unisys_oem((char *)oem_addr);
+		} else {
+			setup_unisys();
+			ret = 1;
+		}
+		/*
+		 * we need to unmap it
+		 */
+		unmap_unisys_acpi_oem_table(oem_addr);
+	}
+
+	es7000_acpi_ret = ret;
+
+	return ret && !es7000_apic_is_cluster();
+}
+
+static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
+{
+	int ret = es7000_acpi_ret;
+
+	return ret && es7000_apic_is_cluster();
+}
+
+#else /* !CONFIG_ACPI: */
+static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	return 0;
+}
+
+static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
+{
+	return 0;
+}
+#endif /* !CONFIG_ACPI */
+
+static void es7000_spin(int n)
+{
+	int i = 0;
+
+	while (i++ < n)
+		rep_nop();
+}
+
+static int es7000_mip_write(struct mip_reg *mip_reg)
+{
+	int status = 0;
+	int spin;
+
+	spin = MIP_SPIN;
+	while ((host_reg->off_0x38 & MIP_VALID) != 0) {
+		if (--spin <= 0) {
+			WARN(1,	"Timeout waiting for Host Valid Flag\n");
+			return -1;
+		}
+		es7000_spin(MIP_SPIN);
+	}
+
+	memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
+	outb(1, mip_port);
+
+	spin = MIP_SPIN;
+
+	while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
+		if (--spin <= 0) {
+			WARN(1,	"Timeout waiting for MIP Valid Flag\n");
+			return -1;
+		}
+		es7000_spin(MIP_SPIN);
+	}
+
+	status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
+	mip_reg->off_0x38 &= ~MIP_VALID;
+
+	return status;
+}
+
+static void es7000_enable_apic_mode(void)
+{
+	struct mip_reg es7000_mip_reg;
+	int mip_status;
+
+	if (!es7000_plat)
+		return;
+
+	printk(KERN_INFO "ES7000: 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;
+
+	while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
+		WARN(1, "Command failed, status = %x\n", mip_status);
+}
+
+static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	/* Careful. Some cpus do not strictly honor the set of cpus
+	 * specified in the interrupt destination when using lowest
+	 * priority interrupt delivery mode.
+	 *
+	 * In particular there was a hyperthreading cpu observed to
+	 * deliver interrupts to the wrong hyperthread when only one
+	 * hyperthread was specified in the interrupt desitination.
+	 */
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
+
+
+static void es7000_wait_for_init_deassert(atomic_t *deassert)
+{
+	while (!atomic_read(deassert))
+		cpu_relax();
+}
+
+static unsigned int es7000_get_apic_id(unsigned long x)
+{
+	return (x >> 24) & 0xFF;
+}
+
+static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	default_send_IPI_mask_sequence_phys(mask, vector);
+}
+
+static void es7000_send_IPI_allbutself(int vector)
+{
+	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
+}
+
+static void es7000_send_IPI_all(int vector)
+{
+	es7000_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int es7000_apic_id_registered(void)
+{
+	return 1;
+}
+
+static const struct cpumask *target_cpus_cluster(void)
+{
+	return cpu_all_mask;
+}
+
+static const struct cpumask *es7000_target_cpus(void)
+{
+	return cpumask_of(smp_processor_id());
+}
+
+static unsigned long
+es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+	return 0;
+}
+static unsigned long es7000_check_apicid_present(int bit)
+{
+	return physid_isset(bit, phys_cpu_present_map);
+}
+
+static unsigned long calculate_ldr(int cpu)
+{
+	unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
+
+	return SET_APIC_LOGICAL_ID(id);
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LdR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static void es7000_init_apic_ldr_cluster(void)
+{
+	unsigned long val;
+	int cpu = smp_processor_id();
+
+	apic_write(APIC_DFR, APIC_DFR_CLUSTER);
+	val = calculate_ldr(cpu);
+	apic_write(APIC_LDR, val);
+}
+
+static void es7000_init_apic_ldr(void)
+{
+	unsigned long val;
+	int cpu = smp_processor_id();
+
+	apic_write(APIC_DFR, APIC_DFR_FLAT);
+	val = calculate_ldr(cpu);
+	apic_write(APIC_LDR, val);
+}
+
+static void es7000_setup_apic_routing(void)
+{
+	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",
+		(apic_version[apic] == 0x14) ?
+			"Physical Cluster" : "Logical Cluster",
+		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
+}
+
+static int es7000_apicid_to_node(int logical_apicid)
+{
+	return 0;
+}
+
+
+static int es7000_cpu_present_to_apicid(int mps_cpu)
+{
+	if (!mps_cpu)
+		return boot_cpu_physical_apicid;
+	else if (mps_cpu < nr_cpu_ids)
+		return per_cpu(x86_bios_cpu_apicid, mps_cpu);
+	else
+		return BAD_APICID;
+}
+
+static int cpu_id;
+
+static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
+{
+	physid_mask_t mask;
+
+	mask = physid_mask_of_physid(cpu_id);
+	++cpu_id;
+
+	return mask;
+}
+
+/* Mapping from cpu number to logical apicid */
+static int es7000_cpu_to_logical_apicid(int cpu)
+{
+#ifdef CONFIG_SMP
+	if (cpu >= nr_cpu_ids)
+		return BAD_APICID;
+	return cpu_2_logical_apicid[cpu];
+#else
+	return logical_smp_processor_id();
+#endif
+}
+
+static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+	/* For clustered we don't have a good way to do this yet - hack */
+	return physids_promote(0xff);
+}
+
+static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
+{
+	boot_cpu_physical_apicid = read_apic_id();
+	return 1;
+}
+
+static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	unsigned int round = 0;
+	int cpu, uninitialized_var(apicid);
+
+	/*
+	 * The cpus in the mask must all be on the apic cluster.
+	 */
+	for_each_cpu(cpu, cpumask) {
+		int new_apicid = es7000_cpu_to_logical_apicid(cpu);
+
+		if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+			WARN(1, "Not a valid mask!");
+
+			return BAD_APICID;
+		}
+		apicid = new_apicid;
+		round++;
+	}
+	return apicid;
+}
+
+static unsigned int
+es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
+			      const struct cpumask *andmask)
+{
+	int apicid = es7000_cpu_to_logical_apicid(0);
+	cpumask_var_t cpumask;
+
+	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
+		return apicid;
+
+	cpumask_and(cpumask, inmask, andmask);
+	cpumask_and(cpumask, cpumask, cpu_online_mask);
+	apicid = es7000_cpu_mask_to_apicid(cpumask);
+
+	free_cpumask_var(cpumask);
+
+	return apicid;
+}
+
+static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
+static int probe_es7000(void)
+{
+	/* probed later in mptable/ACPI hooks */
+	return 0;
+}
+
+static int es7000_mps_ret;
+static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
+		char *productid)
+{
+	int ret = 0;
+
+	if (mpc->oemptr) {
+		struct mpc_oemtable *oem_table =
+			(struct mpc_oemtable *)mpc->oemptr;
+
+		if (!strncmp(oem, "UNISYS", 6))
+			ret = parse_unisys_oem((char *)oem_table);
+	}
+
+	es7000_mps_ret = ret;
+
+	return ret && !es7000_apic_is_cluster();
+}
+
+static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
+		char *productid)
+{
+	int ret = es7000_mps_ret;
+
+	return ret && es7000_apic_is_cluster();
+}
+
+struct apic apic_es7000_cluster = {
+
+	.name				= "es7000",
+	.probe				= probe_es7000,
+	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check_cluster,
+	.apic_id_registered		= es7000_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	/* logical delivery broadcast to all procs: */
+	.irq_dest_mode			= 1,
+
+	.target_cpus			= target_cpus_cluster,
+	.disable_esr			= 1,
+	.dest_logical			= 0,
+	.check_apicid_used		= es7000_check_apicid_used,
+	.check_apicid_present		= es7000_check_apicid_present,
+
+	.vector_allocation_domain	= es7000_vector_allocation_domain,
+	.init_apic_ldr			= es7000_init_apic_ldr_cluster,
+
+	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
+	.setup_apic_routing		= es7000_setup_apic_routing,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= es7000_apicid_to_node,
+	.cpu_to_logical_apicid		= es7000_cpu_to_logical_apicid,
+	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
+	.enable_apic_mode		= es7000_enable_apic_mode,
+	.phys_pkg_id			= es7000_phys_pkg_id,
+	.mps_oem_check			= es7000_mps_oem_check_cluster,
+
+	.get_apic_id			= es7000_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0xFF << 24,
+
+	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= es7000_send_IPI_mask,
+	.send_IPI_mask_allbutself	= NULL,
+	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
+	.send_IPI_all			= es7000_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.wakeup_secondary_cpu		= wakeup_secondary_cpu_via_mip,
+
+	.trampoline_phys_low		= 0x467,
+	.trampoline_phys_high		= 0x469,
+
+	.wait_for_init_deassert		= NULL,
+
+	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
+
+struct apic __refdata apic_es7000 = {
+
+	.name				= "es7000",
+	.probe				= probe_es7000,
+	.acpi_madt_oem_check		= es7000_acpi_madt_oem_check,
+	.apic_id_registered		= es7000_apic_id_registered,
+
+	.irq_delivery_mode		= dest_Fixed,
+	/* phys delivery to target CPUs: */
+	.irq_dest_mode			= 0,
+
+	.target_cpus			= es7000_target_cpus,
+	.disable_esr			= 1,
+	.dest_logical			= 0,
+	.check_apicid_used		= es7000_check_apicid_used,
+	.check_apicid_present		= es7000_check_apicid_present,
+
+	.vector_allocation_domain	= es7000_vector_allocation_domain,
+	.init_apic_ldr			= es7000_init_apic_ldr,
+
+	.ioapic_phys_id_map		= es7000_ioapic_phys_id_map,
+	.setup_apic_routing		= es7000_setup_apic_routing,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= es7000_apicid_to_node,
+	.cpu_to_logical_apicid		= es7000_cpu_to_logical_apicid,
+	.cpu_present_to_apicid		= es7000_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= es7000_apicid_to_cpu_present,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= es7000_check_phys_apicid_present,
+	.enable_apic_mode		= es7000_enable_apic_mode,
+	.phys_pkg_id			= es7000_phys_pkg_id,
+	.mps_oem_check			= es7000_mps_oem_check,
+
+	.get_apic_id			= es7000_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0xFF << 24,
+
+	.cpu_mask_to_apicid		= es7000_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= es7000_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= es7000_send_IPI_mask,
+	.send_IPI_mask_allbutself	= NULL,
+	.send_IPI_allbutself		= es7000_send_IPI_allbutself,
+	.send_IPI_all			= es7000_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.trampoline_phys_low		= 0x467,
+	.trampoline_phys_high		= 0x469,
+
+	.wait_for_init_deassert		= es7000_wait_for_init_deassert,
+
+	/* Nothing to do for most platforms, since cleared by the INIT cycle: */
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/io_apic.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/io_apic.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/io_apic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/io_apic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4209 @@
+/*
+ *	Intel IO-APIC support for multi-Pentium hosts.
+ *
+ *	Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo
+ *
+ *	Many thanks to Stig Venaas for trying out countless experimental
+ *	patches and reporting/debugging problems patiently!
+ *
+ *	(c) 1999, Multiple IO-APIC support, developed by
+ *	Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
+ *      Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
+ *	further tested and cleaned up by Zach Brown <zab@redhat.com>
+ *	and Ingo Molnar <mingo@redhat.com>
+ *
+ *	Fixes
+ *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs;
+ *					thanks to Eric Gilmore
+ *					and Rolf G. Tews
+ *					for testing these extensively
+ *	Paul Diefenbaugh	:	Added full ACPI support
+ */
+
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/mc146818rtc.h>
+#include <linux/compiler.h>
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/msi.h>
+#include <linux/htirq.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h>	/* time_after() */
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
+#include <linux/bootmem.h>
+#include <linux/dmar.h>
+#include <linux/hpet.h>
+
+#include <asm/idle.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/cpu.h>
+#include <asm/desc.h>
+#include <asm/proto.h>
+#include <asm/acpi.h>
+#include <asm/dma.h>
+#include <asm/timer.h>
+#include <asm/i8259.h>
+#include <asm/nmi.h>
+#include <asm/msidef.h>
+#include <asm/hypertransport.h>
+#include <asm/setup.h>
+#include <asm/irq_remapping.h>
+#include <asm/hpet.h>
+#include <asm/uv/uv_hub.h>
+#include <asm/uv/uv_irq.h>
+
+#include <asm/apic.h>
+
+#define __apicdebuginit(type) static type __init
+
+/*
+ *      Is the SiS APIC rmw bug present ?
+ *      -1 = don't know, 0 = no, 1 = yes
+ */
+int sis_apic_bug = -1;
+
+static DEFINE_SPINLOCK(ioapic_lock);
+static DEFINE_SPINLOCK(vector_lock);
+
+/*
+ * # of IRQ routing registers
+ */
+int nr_ioapic_registers[MAX_IO_APICS];
+
+/* I/O APIC entries */
+struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
+int nr_ioapics;
+
+/* MP IRQ source entries */
+struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
+
+/* # of MP IRQ source entries */
+int mp_irq_entries;
+
+#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
+int mp_bus_id_to_type[MAX_MP_BUSSES];
+#endif
+
+DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
+
+int skip_ioapic_setup;
+
+void arch_disable_smp_support(void)
+{
+#ifdef CONFIG_PCI
+	noioapicquirk = 1;
+	noioapicreroute = -1;
+#endif
+	skip_ioapic_setup = 1;
+}
+
+static int __init parse_noapic(char *str)
+{
+	/* disable IO-APIC */
+	arch_disable_smp_support();
+	return 0;
+}
+early_param("noapic", parse_noapic);
+
+struct irq_pin_list;
+
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * the indexing order of this array favors 1:1 mappings
+ * between pins and IRQs.
+ */
+
+struct irq_pin_list {
+	int apic, pin;
+	struct irq_pin_list *next;
+};
+
+static struct irq_pin_list *get_one_free_irq_2_pin(int cpu)
+{
+	struct irq_pin_list *pin;
+	int node;
+
+	node = cpu_to_node(cpu);
+
+	pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
+
+	return pin;
+}
+
+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;
+#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
+	u8 move_desc_pending : 1;
+#endif
+};
+
+/* 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[] = {
+#else
+static struct irq_cfg irq_cfgx[NR_IRQS] = {
+#endif
+	[0]  = { .vector = IRQ0_VECTOR,  },
+	[1]  = { .vector = IRQ1_VECTOR,  },
+	[2]  = { .vector = IRQ2_VECTOR,  },
+	[3]  = { .vector = IRQ3_VECTOR,  },
+	[4]  = { .vector = IRQ4_VECTOR,  },
+	[5]  = { .vector = IRQ5_VECTOR,  },
+	[6]  = { .vector = IRQ6_VECTOR,  },
+	[7]  = { .vector = IRQ7_VECTOR,  },
+	[8]  = { .vector = IRQ8_VECTOR,  },
+	[9]  = { .vector = IRQ9_VECTOR,  },
+	[10] = { .vector = IRQ10_VECTOR, },
+	[11] = { .vector = IRQ11_VECTOR, },
+	[12] = { .vector = IRQ12_VECTOR, },
+	[13] = { .vector = IRQ13_VECTOR, },
+	[14] = { .vector = IRQ14_VECTOR, },
+	[15] = { .vector = IRQ15_VECTOR, },
+};
+
+int __init arch_early_irq_init(void)
+{
+	struct irq_cfg *cfg;
+	struct irq_desc *desc;
+	int count;
+	int i;
+
+	cfg = irq_cfgx;
+	count = ARRAY_SIZE(irq_cfgx);
+
+	for (i = 0; i < count; i++) {
+		desc = irq_to_desc(i);
+		desc->chip_data = &cfg[i];
+		alloc_bootmem_cpumask_var(&cfg[i].domain);
+		alloc_bootmem_cpumask_var(&cfg[i].old_domain);
+		if (i < NR_IRQS_LEGACY)
+			cpumask_setall(cfg[i].domain);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_SPARSE_IRQ
+static struct irq_cfg *irq_cfg(unsigned int irq)
+{
+	struct irq_cfg *cfg = NULL;
+	struct irq_desc *desc;
+
+	desc = irq_to_desc(irq);
+	if (desc)
+		cfg = desc->chip_data;
+
+	return cfg;
+}
+
+static struct irq_cfg *get_one_free_irq_cfg(int cpu)
+{
+	struct irq_cfg *cfg;
+	int node;
+
+	node = cpu_to_node(cpu);
+
+	cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
+	if (cfg) {
+		if (!alloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) {
+			kfree(cfg);
+			cfg = NULL;
+		} else if (!alloc_cpumask_var_node(&cfg->old_domain,
+							  GFP_ATOMIC, node)) {
+			free_cpumask_var(cfg->domain);
+			kfree(cfg);
+			cfg = NULL;
+		} else {
+			cpumask_clear(cfg->domain);
+			cpumask_clear(cfg->old_domain);
+		}
+	}
+
+	return cfg;
+}
+
+int arch_init_chip_data(struct irq_desc *desc, int cpu)
+{
+	struct irq_cfg *cfg;
+
+	cfg = desc->chip_data;
+	if (!cfg) {
+		desc->chip_data = get_one_free_irq_cfg(cpu);
+		if (!desc->chip_data) {
+			printk(KERN_ERR "can not alloc irq_cfg\n");
+			BUG_ON(1);
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
+
+static void
+init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
+{
+	struct irq_pin_list *old_entry, *head, *tail, *entry;
+
+	cfg->irq_2_pin = NULL;
+	old_entry = old_cfg->irq_2_pin;
+	if (!old_entry)
+		return;
+
+	entry = get_one_free_irq_2_pin(cpu);
+	if (!entry)
+		return;
+
+	entry->apic	= old_entry->apic;
+	entry->pin	= old_entry->pin;
+	head		= entry;
+	tail		= entry;
+	old_entry	= old_entry->next;
+	while (old_entry) {
+		entry = get_one_free_irq_2_pin(cpu);
+		if (!entry) {
+			entry = head;
+			while (entry) {
+				head = entry->next;
+				kfree(entry);
+				entry = head;
+			}
+			/* still use the old one */
+			return;
+		}
+		entry->apic	= old_entry->apic;
+		entry->pin	= old_entry->pin;
+		tail->next	= entry;
+		tail		= entry;
+		old_entry	= old_entry->next;
+	}
+
+	tail->next = NULL;
+	cfg->irq_2_pin = head;
+}
+
+static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
+{
+	struct irq_pin_list *entry, *next;
+
+	if (old_cfg->irq_2_pin == cfg->irq_2_pin)
+		return;
+
+	entry = old_cfg->irq_2_pin;
+
+	while (entry) {
+		next = entry->next;
+		kfree(entry);
+		entry = next;
+	}
+	old_cfg->irq_2_pin = NULL;
+}
+
+void arch_init_copy_chip_data(struct irq_desc *old_desc,
+				 struct irq_desc *desc, int cpu)
+{
+	struct irq_cfg *cfg;
+	struct irq_cfg *old_cfg;
+
+	cfg = get_one_free_irq_cfg(cpu);
+
+	if (!cfg)
+		return;
+
+	desc->chip_data = cfg;
+
+	old_cfg = old_desc->chip_data;
+
+	memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
+
+	init_copy_irq_2_pin(old_cfg, cfg, cpu);
+}
+
+static void free_irq_cfg(struct irq_cfg *old_cfg)
+{
+	kfree(old_cfg);
+}
+
+void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
+{
+	struct irq_cfg *old_cfg, *cfg;
+
+	old_cfg = old_desc->chip_data;
+	cfg = desc->chip_data;
+
+	if (old_cfg == cfg)
+		return;
+
+	if (old_cfg) {
+		free_irq_2_pin(old_cfg, cfg);
+		free_irq_cfg(old_cfg);
+		old_desc->chip_data = NULL;
+	}
+}
+
+static void
+set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+	struct irq_cfg *cfg = desc->chip_data;
+
+	if (!cfg->move_in_progress) {
+		/* it means that domain is not changed */
+		if (!cpumask_intersects(desc->affinity, mask))
+			cfg->move_desc_pending = 1;
+	}
+}
+#endif
+
+#else
+static struct irq_cfg *irq_cfg(unsigned int irq)
+{
+	return irq < nr_irqs ? irq_cfgx + irq : NULL;
+}
+
+#endif
+
+#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC
+static inline void
+set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+}
+#endif
+
+struct io_apic {
+	unsigned int index;
+	unsigned int unused[3];
+	unsigned int data;
+	unsigned int unused2[11];
+	unsigned int eoi;
+};
+
+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+{
+	return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
+		+ (mp_ioapics[idx].apicaddr & ~PAGE_MASK);
+}
+
+static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(vector, &io_apic->eoi);
+}
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	return readl(&io_apic->data);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+	writel(reg, &io_apic->index);
+	writel(value, &io_apic->data);
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
+{
+	struct io_apic __iomem *io_apic = io_apic_base(apic);
+
+	if (sis_apic_bug)
+		writel(reg, &io_apic->index);
+	writel(value, &io_apic->data);
+}
+
+static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
+{
+	struct irq_pin_list *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	entry = cfg->irq_2_pin;
+	for (;;) {
+		unsigned int reg;
+		int pin;
+
+		if (!entry)
+			break;
+		pin = entry->pin;
+		reg = io_apic_read(entry->apic, 0x10 + pin*2);
+		/* Is the remote IRR bit set? */
+		if (reg & IO_APIC_REDIR_REMOTE_IRR) {
+			spin_unlock_irqrestore(&ioapic_lock, flags);
+			return true;
+		}
+		if (!entry->next)
+			break;
+		entry = entry->next;
+	}
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return false;
+}
+
+union entry_union {
+	struct { u32 w1, w2; };
+	struct IO_APIC_route_entry entry;
+};
+
+static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
+{
+	union entry_union eu;
+	unsigned long flags;
+	spin_lock_irqsave(&ioapic_lock, flags);
+	eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
+	eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+	return eu.entry;
+}
+
+/*
+ * When we write a new IO APIC routing entry, we need to write the high
+ * word first! If the mask bit in the low word is clear, we will enable
+ * the interrupt, and we need to make sure the entry is fully populated
+ * before that happens.
+ */
+static void
+__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
+{
+	union entry_union eu;
+	eu.entry = e;
+	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+}
+
+void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__ioapic_write_entry(apic, pin, e);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+/*
+ * When we mask an IO APIC routing entry, we need to write the low
+ * word first, in order to set the mask bit before we change the
+ * high bits!
+ */
+static void ioapic_mask_entry(int apic, int pin)
+{
+	unsigned long flags;
+	union entry_union eu = { .entry.mask = 1 };
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static 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);
+	}
+	cfg->move_in_progress = 0;
+}
+
+static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
+{
+	int apic, pin;
+	struct irq_pin_list *entry;
+	u8 vector = cfg->vector;
+
+	entry = cfg->irq_2_pin;
+	for (;;) {
+		unsigned int reg;
+
+		if (!entry)
+			break;
+
+		apic = entry->apic;
+		pin = entry->pin;
+		/*
+		 * With interrupt-remapping, destination information comes
+		 * from interrupt-remapping table entry.
+		 */
+		if (!irq_remapped(irq))
+			io_apic_write(apic, 0x11 + pin*2, dest);
+		reg = io_apic_read(apic, 0x10 + pin*2);
+		reg &= ~IO_APIC_REDIR_VECTOR_MASK;
+		reg |= vector;
+		io_apic_modify(apic, 0x10 + pin*2, reg);
+		if (!entry->next)
+			break;
+		entry = entry->next;
+	}
+}
+
+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
+ * leaves desc->affinity untouched.
+ */
+static unsigned int
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+{
+	struct irq_cfg *cfg;
+	unsigned int irq;
+
+	if (!cpumask_intersects(mask, cpu_online_mask))
+		return BAD_APICID;
+
+	irq = desc->irq;
+	cfg = desc->chip_data;
+	if (assign_irq_vector(irq, cfg, mask))
+		return BAD_APICID;
+
+	/* check that before desc->addinity get updated */
+	set_extra_move_desc(desc, mask);
+
+	cpumask_copy(desc->affinity, mask);
+
+	return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+}
+
+static void
+set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+	struct irq_cfg *cfg;
+	unsigned long flags;
+	unsigned int dest;
+	unsigned int irq;
+
+	irq = desc->irq;
+	cfg = desc->chip_data;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	dest = set_desc_affinity(desc, mask);
+	if (dest != BAD_APICID) {
+		/* Only the high 8 bits are valid. */
+		dest = SET_APIC_LOGICAL_ID(dest);
+		__target_IO_APIC_irq(irq, dest, cfg);
+	}
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+static void
+set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc;
+
+	desc = irq_to_desc(irq);
+
+	set_ioapic_affinity_irq_desc(desc, mask);
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
+ * shared ISA-space IRQs, so we have to support them. We are super
+ * fast in the common case, and fast for shared ISA-space IRQs.
+ */
+static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
+{
+	struct irq_pin_list *entry;
+
+	entry = cfg->irq_2_pin;
+	if (!entry) {
+		entry = get_one_free_irq_2_pin(cpu);
+		if (!entry) {
+			printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
+					apic, pin);
+			return;
+		}
+		cfg->irq_2_pin = entry;
+		entry->apic = apic;
+		entry->pin = pin;
+		return;
+	}
+
+	while (entry->next) {
+		/* not again, please */
+		if (entry->apic == apic && entry->pin == pin)
+			return;
+
+		entry = entry->next;
+	}
+
+	entry->next = get_one_free_irq_2_pin(cpu);
+	entry = entry->next;
+	entry->apic = apic;
+	entry->pin = pin;
+}
+
+/*
+ * Reroute an IRQ to a different pin.
+ */
+static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
+				      int oldapic, int oldpin,
+				      int newapic, int newpin)
+{
+	struct irq_pin_list *entry = cfg->irq_2_pin;
+	int replaced = 0;
+
+	while (entry) {
+		if (entry->apic == oldapic && entry->pin == oldpin) {
+			entry->apic = newapic;
+			entry->pin = newpin;
+			replaced = 1;
+			/* every one is different, right? */
+			break;
+		}
+		entry = entry->next;
+	}
+
+	/* why? call replace before add? */
+	if (!replaced)
+		add_pin_to_irq_cpu(cfg, cpu, newapic, newpin);
+}
+
+static inline 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 (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) {
+		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);
+	}
+}
+
+static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
+{
+	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
+}
+
+#ifdef CONFIG_X86_64
+static void io_apic_sync(struct irq_pin_list *entry)
+{
+	/*
+	 * Synchronize the IO-APIC and the CPU by doing
+	 * a dummy read from the IO-APIC
+	 */
+	struct io_apic __iomem *io_apic;
+	io_apic = io_apic_base(entry->apic);
+	readl(&io_apic->data);
+}
+
+static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
+{
+	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
+}
+#else /* CONFIG_X86_32 */
+static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
+{
+	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL);
+}
+
+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);
+}
+#endif /* CONFIG_X86_32 */
+
+static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
+{
+	struct irq_cfg *cfg = desc->chip_data;
+	unsigned long flags;
+
+	BUG_ON(!cfg);
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__mask_IO_APIC_irq(cfg);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
+{
+	struct irq_cfg *cfg = desc->chip_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	__unmask_IO_APIC_irq(cfg);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+static void mask_IO_APIC_irq(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	mask_IO_APIC_irq_desc(desc);
+}
+static void unmask_IO_APIC_irq(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	unmask_IO_APIC_irq_desc(desc);
+}
+
+static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
+{
+	struct IO_APIC_route_entry entry;
+
+	/* Check delivery_mode to be sure we're not clearing an SMI pin */
+	entry = ioapic_read_entry(apic, pin);
+	if (entry.delivery_mode == dest_SMI)
+		return;
+	/*
+	 * Disable it in the IO-APIC irq-routing table:
+	 */
+	ioapic_mask_entry(apic, pin);
+}
+
+static void clear_IO_APIC (void)
+{
+	int apic, pin;
+
+	for (apic = 0; apic < nr_ioapics; apic++)
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+			clear_IO_APIC_pin(apic, pin);
+}
+
+#ifdef CONFIG_X86_32
+/*
+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
+ * specific CPU-side IRQs.
+ */
+
+#define MAX_PIRQS 8
+static int pirq_entries[MAX_PIRQS] = {
+	[0 ... MAX_PIRQS - 1] = -1
+};
+
+static int __init ioapic_pirq_setup(char *str)
+{
+	int i, max;
+	int ints[MAX_PIRQS+1];
+
+	get_options(str, ARRAY_SIZE(ints), ints);
+
+	apic_printk(APIC_VERBOSE, KERN_INFO
+			"PIRQ redirection, working around broken MP-BIOS.\n");
+	max = MAX_PIRQS;
+	if (ints[0] < MAX_PIRQS)
+		max = ints[0];
+
+	for (i = 0; i < max; i++) {
+		apic_printk(APIC_VERBOSE, KERN_DEBUG
+				"... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
+		/*
+		 * PIRQs are mapped upside down, usually.
+		 */
+		pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
+	}
+	return 1;
+}
+
+__setup("pirq=", ioapic_pirq_setup);
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_INTR_REMAP
+struct IO_APIC_route_entry **alloc_ioapic_entries(void)
+{
+	int apic;
+	struct IO_APIC_route_entry **ioapic_entries;
+
+	ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
+				GFP_ATOMIC);
+	if (!ioapic_entries)
+		return 0;
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		ioapic_entries[apic] =
+			kzalloc(sizeof(struct IO_APIC_route_entry) *
+				nr_ioapic_registers[apic], GFP_ATOMIC);
+		if (!ioapic_entries[apic])
+			goto nomem;
+	}
+
+	return ioapic_entries;
+
+nomem:
+	while (--apic >= 0)
+		kfree(ioapic_entries[apic]);
+	kfree(ioapic_entries);
+
+	return 0;
+}
+
+/*
+ * Saves all the IO-APIC RTE's
+ */
+int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+	int apic, pin;
+
+	if (!ioapic_entries)
+		return -ENOMEM;
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		if (!ioapic_entries[apic])
+			return -ENOMEM;
+
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+			ioapic_entries[apic][pin] =
+				ioapic_read_entry(apic, pin);
+	}
+
+	return 0;
+}
+
+/*
+ * Mask all IO APIC entries.
+ */
+void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+	int apic, pin;
+
+	if (!ioapic_entries)
+		return;
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		if (!ioapic_entries[apic])
+			break;
+
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+			struct IO_APIC_route_entry entry;
+
+			entry = ioapic_entries[apic][pin];
+			if (!entry.mask) {
+				entry.mask = 1;
+				ioapic_write_entry(apic, pin, entry);
+			}
+		}
+	}
+}
+
+/*
+ * Restore IO APIC entries which was saved in ioapic_entries.
+ */
+int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+	int apic, pin;
+
+	if (!ioapic_entries)
+		return -ENOMEM;
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		if (!ioapic_entries[apic])
+			return -ENOMEM;
+
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+			ioapic_write_entry(apic, pin,
+					ioapic_entries[apic][pin]);
+	}
+	return 0;
+}
+
+void reinit_intr_remapped_IO_APIC(int intr_remapping,
+	struct IO_APIC_route_entry **ioapic_entries)
+
+{
+	/*
+	 * for now plain restore of previous settings.
+	 * TBD: In the case of OS enabling interrupt-remapping,
+	 * IO-APIC RTE's need to be setup to point to interrupt-remapping
+	 * table entries. for now, do a plain restore, and wait for
+	 * the setup_IO_APIC_irqs() to do proper initialization.
+	 */
+	restore_IO_APIC_setup(ioapic_entries);
+}
+
+void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
+{
+	int apic;
+
+	for (apic = 0; apic < nr_ioapics; apic++)
+		kfree(ioapic_entries[apic]);
+
+	kfree(ioapic_entries);
+}
+#endif
+
+/*
+ * Find the IRQ entry number of a certain pin.
+ */
+static int find_irq_entry(int apic, int pin, int type)
+{
+	int i;
+
+	for (i = 0; i < mp_irq_entries; i++)
+		if (mp_irqs[i].irqtype == type &&
+		    (mp_irqs[i].dstapic == mp_ioapics[apic].apicid ||
+		     mp_irqs[i].dstapic == MP_APIC_ALL) &&
+		    mp_irqs[i].dstirq == pin)
+			return i;
+
+	return -1;
+}
+
+/*
+ * Find the pin to which IRQ[irq] (ISA) is connected
+ */
+static int __init find_isa_irq_pin(int irq, int type)
+{
+	int i;
+
+	for (i = 0; i < mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].srcbus;
+
+		if (test_bit(lbus, mp_bus_not_pci) &&
+		    (mp_irqs[i].irqtype == type) &&
+		    (mp_irqs[i].srcbusirq == irq))
+
+			return mp_irqs[i].dstirq;
+	}
+	return -1;
+}
+
+static int __init find_isa_irq_apic(int irq, int type)
+{
+	int i;
+
+	for (i = 0; i < mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].srcbus;
+
+		if (test_bit(lbus, mp_bus_not_pci) &&
+		    (mp_irqs[i].irqtype == type) &&
+		    (mp_irqs[i].srcbusirq == irq))
+			break;
+	}
+	if (i < mp_irq_entries) {
+		int apic;
+		for(apic = 0; apic < nr_ioapics; apic++) {
+			if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic)
+				return apic;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Find a specific PCI IRQ entry.
+ * Not an __init, possibly needed by modules
+ */
+static int pin_2_irq(int idx, int apic, int pin);
+
+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
+{
+	int apic, i, best_guess = -1;
+
+	apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
+		bus, slot, pin);
+	if (test_bit(bus, mp_bus_not_pci)) {
+		apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
+		return -1;
+	}
+	for (i = 0; i < mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].srcbus;
+
+		for (apic = 0; apic < nr_ioapics; apic++)
+			if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
+			    mp_irqs[i].dstapic == MP_APIC_ALL)
+				break;
+
+		if (!test_bit(lbus, mp_bus_not_pci) &&
+		    !mp_irqs[i].irqtype &&
+		    (bus == lbus) &&
+		    (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
+			int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
+
+			if (!(apic || IO_APIC_IRQ(irq)))
+				continue;
+
+			if (pin == (mp_irqs[i].srcbusirq & 3))
+				return irq;
+			/*
+			 * Use the first all-but-pin matching entry as a
+			 * best-guess fuzzy result for broken mptables.
+			 */
+			if (best_guess < 0)
+				best_guess = irq;
+		}
+	}
+	return best_guess;
+}
+
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+/*
+ * EISA Edge/Level control register, ELCR
+ */
+static int EISA_ELCR(unsigned int irq)
+{
+	if (irq < NR_IRQS_LEGACY) {
+		unsigned int port = 0x4d0 + (irq >> 3);
+		return (inb(port) >> (irq & 7)) & 1;
+	}
+	apic_printk(APIC_VERBOSE, KERN_INFO
+			"Broken MPtable reports ISA irq %d\n", irq);
+	return 0;
+}
+
+#endif
+
+/* ISA interrupts are always polarity zero edge triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_ISA_trigger(idx)	(0)
+#define default_ISA_polarity(idx)	(0)
+
+/* EISA interrupts are always polarity zero and can be edge or level
+ * trigger depending on the ELCR value.  If an interrupt is listed as
+ * EISA conforming in the MP table, that means its trigger type must
+ * be read in from the ELCR */
+
+#define default_EISA_trigger(idx)	(EISA_ELCR(mp_irqs[idx].srcbusirq))
+#define default_EISA_polarity(idx)	default_ISA_polarity(idx)
+
+/* PCI interrupts are always polarity one level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_PCI_trigger(idx)	(1)
+#define default_PCI_polarity(idx)	(1)
+
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx)	(1)
+#define default_MCA_polarity(idx)	default_ISA_polarity(idx)
+
+static int MPBIOS_polarity(int idx)
+{
+	int bus = mp_irqs[idx].srcbus;
+	int polarity;
+
+	/*
+	 * Determine IRQ line polarity (high active or low active):
+	 */
+	switch (mp_irqs[idx].irqflag & 3)
+	{
+		case 0: /* conforms, ie. bus-type dependent polarity */
+			if (test_bit(bus, mp_bus_not_pci))
+				polarity = default_ISA_polarity(idx);
+			else
+				polarity = default_PCI_polarity(idx);
+			break;
+		case 1: /* high active */
+		{
+			polarity = 0;
+			break;
+		}
+		case 2: /* reserved */
+		{
+			printk(KERN_WARNING "broken BIOS!!\n");
+			polarity = 1;
+			break;
+		}
+		case 3: /* low active */
+		{
+			polarity = 1;
+			break;
+		}
+		default: /* invalid */
+		{
+			printk(KERN_WARNING "broken BIOS!!\n");
+			polarity = 1;
+			break;
+		}
+	}
+	return polarity;
+}
+
+static int MPBIOS_trigger(int idx)
+{
+	int bus = mp_irqs[idx].srcbus;
+	int trigger;
+
+	/*
+	 * Determine IRQ trigger mode (edge or level sensitive):
+	 */
+	switch ((mp_irqs[idx].irqflag>>2) & 3)
+	{
+		case 0: /* conforms, ie. bus-type dependent */
+			if (test_bit(bus, mp_bus_not_pci))
+				trigger = default_ISA_trigger(idx);
+			else
+				trigger = default_PCI_trigger(idx);
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+			switch (mp_bus_id_to_type[bus]) {
+				case MP_BUS_ISA: /* ISA pin */
+				{
+					/* set before the switch */
+					break;
+				}
+				case MP_BUS_EISA: /* EISA pin */
+				{
+					trigger = default_EISA_trigger(idx);
+					break;
+				}
+				case MP_BUS_PCI: /* PCI pin */
+				{
+					/* set before the switch */
+					break;
+				}
+				case MP_BUS_MCA: /* MCA pin */
+				{
+					trigger = default_MCA_trigger(idx);
+					break;
+				}
+				default:
+				{
+					printk(KERN_WARNING "broken BIOS!!\n");
+					trigger = 1;
+					break;
+				}
+			}
+#endif
+			break;
+		case 1: /* edge */
+		{
+			trigger = 0;
+			break;
+		}
+		case 2: /* reserved */
+		{
+			printk(KERN_WARNING "broken BIOS!!\n");
+			trigger = 1;
+			break;
+		}
+		case 3: /* level */
+		{
+			trigger = 1;
+			break;
+		}
+		default: /* invalid */
+		{
+			printk(KERN_WARNING "broken BIOS!!\n");
+			trigger = 0;
+			break;
+		}
+	}
+	return trigger;
+}
+
+static inline int irq_polarity(int idx)
+{
+	return MPBIOS_polarity(idx);
+}
+
+static inline int irq_trigger(int idx)
+{
+	return MPBIOS_trigger(idx);
+}
+
+int (*ioapic_renumber_irq)(int ioapic, int irq);
+static int pin_2_irq(int idx, int apic, int pin)
+{
+	int irq, i;
+	int bus = mp_irqs[idx].srcbus;
+
+	/*
+	 * Debugging check, we are in big trouble if this message pops up!
+	 */
+	if (mp_irqs[idx].dstirq != pin)
+		printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
+
+	if (test_bit(bus, mp_bus_not_pci)) {
+		irq = mp_irqs[idx].srcbusirq;
+	} else {
+		/*
+		 * PCI IRQs are mapped in order
+		 */
+		i = irq = 0;
+		while (i < apic)
+			irq += nr_ioapic_registers[i++];
+		irq += pin;
+		/*
+                 * For MPS mode, so far only needed by ES7000 platform
+                 */
+		if (ioapic_renumber_irq)
+			irq = ioapic_renumber_irq(apic, irq);
+	}
+
+#ifdef CONFIG_X86_32
+	/*
+	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
+	 */
+	if ((pin >= 16) && (pin <= 23)) {
+		if (pirq_entries[pin-16] != -1) {
+			if (!pirq_entries[pin-16]) {
+				apic_printk(APIC_VERBOSE, KERN_DEBUG
+						"disabling PIRQ%d\n", pin-16);
+			} else {
+				irq = pirq_entries[pin-16];
+				apic_printk(APIC_VERBOSE, KERN_DEBUG
+						"using PIRQ%d -> IRQ %d\n",
+						pin-16, irq);
+			}
+		}
+	}
+#endif
+
+	return irq;
+}
+
+void lock_vector_lock(void)
+{
+	/* Used to the online set of cpus does not change
+	 * during assign_irq_vector.
+	 */
+	spin_lock(&vector_lock);
+}
+
+void unlock_vector_lock(void)
+{
+	spin_unlock(&vector_lock);
+}
+
+static int
+__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+{
+	/*
+	 * NOTE! The local APIC isn't very good at handling
+	 * multiple interrupts at the same interrupt level.
+	 * As the interrupt level is determined by taking the
+	 * vector number and shifting that right by 4, we
+	 * want to spread these out a bit so that they don't
+	 * all fall in the same interrupt level.
+	 *
+	 * Also, we've got to be careful not to trash gate
+	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
+	 */
+	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
+	unsigned int old_vector;
+	int cpu, err;
+	cpumask_var_t tmp_mask;
+
+	if ((cfg->move_in_progress) || cfg->move_cleanup_count)
+		return -EBUSY;
+
+	if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC))
+		return -ENOMEM;
+
+	old_vector = cfg->vector;
+	if (old_vector) {
+		cpumask_and(tmp_mask, mask, cpu_online_mask);
+		cpumask_and(tmp_mask, cfg->domain, tmp_mask);
+		if (!cpumask_empty(tmp_mask)) {
+			free_cpumask_var(tmp_mask);
+			return 0;
+		}
+	}
+
+	/* Only try and allocate irqs on cpus that are present */
+	err = -ENOSPC;
+	for_each_cpu_and(cpu, mask, cpu_online_mask) {
+		int new_cpu;
+		int vector, offset;
+
+		apic->vector_allocation_domain(cpu, tmp_mask);
+
+		vector = current_vector;
+		offset = current_offset;
+next:
+		vector += 8;
+		if (vector >= first_system_vector) {
+			/* If out of vectors on large boxen, must share them. */
+			offset = (offset + 1) % 8;
+			vector = FIRST_DEVICE_VECTOR + offset;
+		}
+		if (unlikely(current_vector == vector))
+			continue;
+
+		if (test_bit(vector, used_vectors))
+			goto next;
+
+		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
+			if (per_cpu(vector_irq, new_cpu)[vector] != -1)
+				goto next;
+		/* Found one! */
+		current_vector = vector;
+		current_offset = offset;
+		if (old_vector) {
+			cfg->move_in_progress = 1;
+			cpumask_copy(cfg->old_domain, cfg->domain);
+		}
+		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
+			per_cpu(vector_irq, new_cpu)[vector] = irq;
+		cfg->vector = vector;
+		cpumask_copy(cfg->domain, tmp_mask);
+		err = 0;
+		break;
+	}
+	free_cpumask_var(tmp_mask);
+	return err;
+}
+
+static int
+assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
+{
+	int err;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	err = __assign_irq_vector(irq, cfg, mask);
+	spin_unlock_irqrestore(&vector_lock, flags);
+	return err;
+}
+
+static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
+{
+	int cpu, vector;
+
+	BUG_ON(!cfg->vector);
+
+	vector = cfg->vector;
+	for_each_cpu_and(cpu, cfg->domain, cpu_online_mask)
+		per_cpu(vector_irq, cpu)[vector] = -1;
+
+	cfg->vector = 0;
+	cpumask_clear(cfg->domain);
+
+	if (likely(!cfg->move_in_progress))
+		return;
+	for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
+		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
+								vector++) {
+			if (per_cpu(vector_irq, cpu)[vector] != irq)
+				continue;
+			per_cpu(vector_irq, cpu)[vector] = -1;
+			break;
+		}
+	}
+	cfg->move_in_progress = 0;
+}
+
+void __setup_vector_irq(int cpu)
+{
+	/* Initialize vector_irq on a new cpu */
+	/* This function must be called with vector_lock held */
+	int irq, vector;
+	struct irq_cfg *cfg;
+	struct irq_desc *desc;
+
+	/* Mark the inuse vectors */
+	for_each_irq_desc(irq, desc) {
+		cfg = desc->chip_data;
+		if (!cpumask_test_cpu(cpu, cfg->domain))
+			continue;
+		vector = cfg->vector;
+		per_cpu(vector_irq, cpu)[vector] = irq;
+	}
+	/* Mark the free vectors */
+	for (vector = 0; vector < NR_VECTORS; ++vector) {
+		irq = per_cpu(vector_irq, cpu)[vector];
+		if (irq < 0)
+			continue;
+
+		cfg = irq_cfg(irq);
+		if (!cpumask_test_cpu(cpu, cfg->domain))
+			per_cpu(vector_irq, cpu)[vector] = -1;
+	}
+}
+
+static struct irq_chip ioapic_chip;
+static struct irq_chip ir_ioapic_chip;
+
+#define IOAPIC_AUTO     -1
+#define IOAPIC_EDGE     0
+#define IOAPIC_LEVEL    1
+
+#ifdef CONFIG_X86_32
+static inline int IO_APIC_irq_trigger(int irq)
+{
+	int apic, idx, pin;
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+			idx = find_irq_entry(apic, pin, mp_INT);
+			if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
+				return irq_trigger(idx);
+		}
+	}
+	/*
+         * nonexistent IRQs are edge default
+         */
+	return 0;
+}
+#else
+static inline int IO_APIC_irq_trigger(int irq)
+{
+	return 1;
+}
+#endif
+
+static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger)
+{
+
+	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+	    trigger == IOAPIC_LEVEL)
+		desc->status |= IRQ_LEVEL;
+	else
+		desc->status &= ~IRQ_LEVEL;
+
+	if (irq_remapped(irq)) {
+		desc->status |= IRQ_MOVE_PCNTXT;
+		if (trigger)
+			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
+						      handle_fasteoi_irq,
+						     "fasteoi");
+		else
+			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
+						      handle_edge_irq, "edge");
+		return;
+	}
+
+	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+	    trigger == IOAPIC_LEVEL)
+		set_irq_chip_and_handler_name(irq, &ioapic_chip,
+					      handle_fasteoi_irq,
+					      "fasteoi");
+	else
+		set_irq_chip_and_handler_name(irq, &ioapic_chip,
+					      handle_edge_irq, "edge");
+}
+
+int setup_ioapic_entry(int apic_id, int irq,
+		       struct IO_APIC_route_entry *entry,
+		       unsigned int destination, int trigger,
+		       int polarity, int vector, int pin)
+{
+	/*
+	 * add it to the IO-APIC irq-routing table:
+	 */
+	memset(entry,0,sizeof(*entry));
+
+	if (intr_remapping_enabled) {
+		struct intel_iommu *iommu = map_ioapic_to_ir(apic_id);
+		struct irte irte;
+		struct IR_IO_APIC_route_entry *ir_entry =
+			(struct IR_IO_APIC_route_entry *) entry;
+		int index;
+
+		if (!iommu)
+			panic("No mapping iommu for ioapic %d\n", apic_id);
+
+		index = alloc_irte(iommu, irq, 1);
+		if (index < 0)
+			panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
+
+		memset(&irte, 0, sizeof(irte));
+
+		irte.present = 1;
+		irte.dst_mode = apic->irq_dest_mode;
+		/*
+		 * Trigger mode in the IRTE will always be edge, and the
+		 * actual level or edge trigger will be setup in the IO-APIC
+		 * RTE. This will help simplify level triggered irq migration.
+		 * For more details, see the comments above explainig IO-APIC
+		 * irq migration in the presence of interrupt-remapping.
+		 */
+		irte.trigger_mode = 0;
+		irte.dlvry_mode = apic->irq_delivery_mode;
+		irte.vector = vector;
+		irte.dest_id = IRTE_DEST(destination);
+
+		modify_irte(irq, &irte);
+
+		ir_entry->index2 = (index >> 15) & 0x1;
+		ir_entry->zero = 0;
+		ir_entry->format = 1;
+		ir_entry->index = (index & 0x7fff);
+		/*
+		 * IO-APIC RTE will be configured with virtual vector.
+		 * irq handler will do the explicit EOI to the io-apic.
+		 */
+		ir_entry->vector = pin;
+	} else {
+		entry->delivery_mode = apic->irq_delivery_mode;
+		entry->dest_mode = apic->irq_dest_mode;
+		entry->dest = destination;
+		entry->vector = vector;
+	}
+
+	entry->mask = 0;				/* enable IRQ */
+	entry->trigger = trigger;
+	entry->polarity = polarity;
+
+	/* Mask level triggered irqs.
+	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
+	 */
+	if (trigger)
+		entry->mask = 1;
+	return 0;
+}
+
+static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
+			      int trigger, int polarity)
+{
+	struct irq_cfg *cfg;
+	struct IO_APIC_route_entry entry;
+	unsigned int dest;
+
+	if (!IO_APIC_IRQ(irq))
+		return;
+
+	cfg = desc->chip_data;
+
+	if (assign_irq_vector(irq, cfg, apic->target_cpus()))
+		return;
+
+	dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
+
+	apic_printk(APIC_VERBOSE,KERN_DEBUG
+		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
+		    "IRQ %d Mode:%i Active:%i)\n",
+		    apic_id, mp_ioapics[apic_id].apicid, pin, cfg->vector,
+		    irq, trigger, polarity);
+
+
+	if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry,
+			       dest, trigger, polarity, cfg->vector, pin)) {
+		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
+		       mp_ioapics[apic_id].apicid, pin);
+		__clear_irq_vector(irq, cfg);
+		return;
+	}
+
+	ioapic_register_intr(irq, desc, trigger);
+	if (irq < NR_IRQS_LEGACY)
+		disable_8259A_irq(irq);
+
+	ioapic_write_entry(apic_id, pin, entry);
+}
+
+static void __init setup_IO_APIC_irqs(void)
+{
+	int apic_id, pin, idx, irq;
+	int notcon = 0;
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
+	int cpu = boot_cpu_id;
+
+	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
+
+	for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
+		for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+
+			idx = find_irq_entry(apic_id, pin, mp_INT);
+			if (idx == -1) {
+				if (!notcon) {
+					notcon = 1;
+					apic_printk(APIC_VERBOSE,
+						KERN_DEBUG " %d-%d",
+						mp_ioapics[apic_id].apicid, pin);
+				} else
+					apic_printk(APIC_VERBOSE, " %d-%d",
+						mp_ioapics[apic_id].apicid, pin);
+				continue;
+			}
+			if (notcon) {
+				apic_printk(APIC_VERBOSE,
+					" (apicid-pin) not connected\n");
+				notcon = 0;
+			}
+
+			irq = pin_2_irq(idx, apic_id, pin);
+
+			/*
+			 * Skip the timer IRQ if there's a quirk handler
+			 * installed and if it returns 1:
+			 */
+			if (apic->multi_timer_check &&
+					apic->multi_timer_check(apic_id, irq))
+				continue;
+
+			desc = irq_to_desc_alloc_cpu(irq, cpu);
+			if (!desc) {
+				printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+				continue;
+			}
+			cfg = desc->chip_data;
+			add_pin_to_irq_cpu(cfg, cpu, apic_id, pin);
+
+			setup_IO_APIC_irq(apic_id, pin, irq, desc,
+					irq_trigger(idx), irq_polarity(idx));
+		}
+	}
+
+	if (notcon)
+		apic_printk(APIC_VERBOSE,
+			" (apicid-pin) not connected\n");
+}
+
+/*
+ * Set up the timer pin, possibly with the 8259A-master behind.
+ */
+static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
+					int vector)
+{
+	struct IO_APIC_route_entry entry;
+
+	if (intr_remapping_enabled)
+		return;
+
+	memset(&entry, 0, sizeof(entry));
+
+	/*
+	 * We use logical delivery to get the timer IRQ
+	 * to the first CPU.
+	 */
+	entry.dest_mode = apic->irq_dest_mode;
+	entry.mask = 0;			/* don't mask IRQ for edge */
+	entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus());
+	entry.delivery_mode = apic->irq_delivery_mode;
+	entry.polarity = 0;
+	entry.trigger = 0;
+	entry.vector = vector;
+
+	/*
+	 * The timer IRQ doesn't have to know that behind the
+	 * scene we may have a 8259A-master in AEOI mode ...
+	 */
+	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
+
+	/*
+	 * Add it to the IO-APIC irq-routing table:
+	 */
+	ioapic_write_entry(apic_id, pin, entry);
+}
+
+
+__apicdebuginit(void) print_IO_APIC(void)
+{
+	int apic, i;
+	union IO_APIC_reg_00 reg_00;
+	union IO_APIC_reg_01 reg_01;
+	union IO_APIC_reg_02 reg_02;
+	union IO_APIC_reg_03 reg_03;
+	unsigned long flags;
+	struct irq_cfg *cfg;
+	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",
+		       mp_ioapics[i].apicid, nr_ioapic_registers[i]);
+
+	/*
+	 * We are a bit conservative about what we expect.  We have to
+	 * know about every hardware change ASAP.
+	 */
+	printk(KERN_INFO "testing the IO APIC.......................\n");
+
+	for (apic = 0; apic < nr_ioapics; apic++) {
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_00.raw = io_apic_read(apic, 0);
+	reg_01.raw = io_apic_read(apic, 1);
+	if (reg_01.bits.version >= 0x10)
+		reg_02.raw = io_apic_read(apic, 2);
+	if (reg_01.bits.version >= 0x20)
+		reg_03.raw = io_apic_read(apic, 3);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	printk("\n");
+	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid);
+	printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
+	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
+	printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
+	printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
+
+	printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
+	printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
+
+	printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
+	printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
+
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+	 * but the value of reg_02 is read as the previous read register
+	 * value, so ignore it if reg_02 == reg_01.
+	 */
+	if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
+		printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
+		printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
+	}
+
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+	 * or reg_03, but the value of reg_0[23] is read as the previous read
+	 * register value, so ignore it if reg_03 == reg_0[12].
+	 */
+	if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
+	    reg_03.raw != reg_01.raw) {
+		printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
+		printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.bits.boot_DT);
+	}
+
+	printk(KERN_DEBUG ".... IRQ redirection table:\n");
+
+	printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
+			  " Stat Dmod Deli Vect:   \n");
+
+	for (i = 0; i <= reg_01.bits.entries; i++) {
+		struct IO_APIC_route_entry entry;
+
+		entry = ioapic_read_entry(apic, i);
+
+		printk(KERN_DEBUG " %02x %03X ",
+			i,
+			entry.dest
+		);
+
+		printk("%1d    %1d    %1d   %1d   %1d    %1d    %1d    %02X\n",
+			entry.mask,
+			entry.trigger,
+			entry.irr,
+			entry.polarity,
+			entry.delivery_status,
+			entry.dest_mode,
+			entry.delivery_mode,
+			entry.vector
+		);
+	}
+	}
+	printk(KERN_DEBUG "IRQ to pin mappings:\n");
+	for_each_irq_desc(irq, desc) {
+		struct irq_pin_list *entry;
+
+		cfg = desc->chip_data;
+		entry = cfg->irq_2_pin;
+		if (!entry)
+			continue;
+		printk(KERN_DEBUG "IRQ%d ", irq);
+		for (;;) {
+			printk("-> %d:%d", entry->apic, entry->pin);
+			if (!entry->next)
+				break;
+			entry = entry->next;
+		}
+		printk("\n");
+	}
+
+	printk(KERN_INFO ".................................... done.\n");
+
+	return;
+}
+
+__apicdebuginit(void) print_APIC_bitfield(int base)
+{
+	unsigned int v;
+	int i, j;
+
+	if (apic_verbosity == APIC_QUIET)
+		return;
+
+	printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
+	for (i = 0; i < 8; i++) {
+		v = apic_read(base + i*0x10);
+		for (j = 0; j < 32; j++) {
+			if (v & (1<<j))
+				printk("1");
+			else
+				printk("0");
+		}
+		printk("\n");
+	}
+}
+
+__apicdebuginit(void) print_local_APIC(void *dummy)
+{
+	unsigned int v, ver, maxlvt;
+	u64 icr;
+
+	if (apic_verbosity == APIC_QUIET)
+		return;
+
+	printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
+		smp_processor_id(), hard_smp_processor_id());
+	v = apic_read(APIC_ID);
+	printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, read_apic_id());
+	v = apic_read(APIC_LVR);
+	printk(KERN_INFO "... APIC VERSION: %08x\n", v);
+	ver = GET_APIC_VERSION(v);
+	maxlvt = lapic_get_maxlvt();
+
+	v = apic_read(APIC_TASKPRI);
+	printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
+
+	if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
+		if (!APIC_XAPIC(ver)) {
+			v = apic_read(APIC_ARBPRI);
+			printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
+			       v & APIC_ARBPRI_MASK);
+		}
+		v = apic_read(APIC_PROCPRI);
+		printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
+	}
+
+	/*
+	 * Remote read supported only in the 82489DX and local APIC for
+	 * Pentium processors.
+	 */
+	if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
+		v = apic_read(APIC_RRR);
+		printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
+	}
+
+	v = apic_read(APIC_LDR);
+	printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
+	if (!x2apic_enabled()) {
+		v = apic_read(APIC_DFR);
+		printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+	}
+	v = apic_read(APIC_SPIV);
+	printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
+
+	printk(KERN_DEBUG "... APIC ISR field:\n");
+	print_APIC_bitfield(APIC_ISR);
+	printk(KERN_DEBUG "... APIC TMR field:\n");
+	print_APIC_bitfield(APIC_TMR);
+	printk(KERN_DEBUG "... APIC IRR field:\n");
+	print_APIC_bitfield(APIC_IRR);
+
+	if (APIC_INTEGRATED(ver)) {             /* !82489DX */
+		if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
+			apic_write(APIC_ESR, 0);
+
+		v = apic_read(APIC_ESR);
+		printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
+	}
+
+	icr = apic_icr_read();
+	printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr);
+	printk(KERN_DEBUG "... APIC ICR2: %08x\n", (u32)(icr >> 32));
+
+	v = apic_read(APIC_LVTT);
+	printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
+
+	if (maxlvt > 3) {                       /* PC is LVT#4. */
+		v = apic_read(APIC_LVTPC);
+		printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
+	}
+	v = apic_read(APIC_LVT0);
+	printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
+	v = apic_read(APIC_LVT1);
+	printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
+
+	if (maxlvt > 2) {			/* ERR is LVT#3. */
+		v = apic_read(APIC_LVTERR);
+		printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
+	}
+
+	v = apic_read(APIC_TMICT);
+	printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
+	v = apic_read(APIC_TMCCT);
+	printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
+	v = apic_read(APIC_TDCR);
+	printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
+	printk("\n");
+}
+
+__apicdebuginit(void) print_all_local_APICs(void)
+{
+	int cpu;
+
+	preempt_disable();
+	for_each_online_cpu(cpu)
+		smp_call_function_single(cpu, print_local_APIC, NULL, 1);
+	preempt_enable();
+}
+
+__apicdebuginit(void) print_PIC(void)
+{
+	unsigned int v;
+	unsigned long flags;
+
+	if (apic_verbosity == APIC_QUIET)
+		return;
+
+	printk(KERN_DEBUG "\nprinting PIC contents\n");
+
+	spin_lock_irqsave(&i8259A_lock, flags);
+
+	v = inb(0xa1) << 8 | inb(0x21);
+	printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
+
+	v = inb(0xa0) << 8 | inb(0x20);
+	printk(KERN_DEBUG "... PIC  IRR: %04x\n", v);
+
+	outb(0x0b,0xa0);
+	outb(0x0b,0x20);
+	v = inb(0xa0) << 8 | inb(0x20);
+	outb(0x0a,0xa0);
+	outb(0x0a,0x20);
+
+	spin_unlock_irqrestore(&i8259A_lock, flags);
+
+	printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
+
+	v = inb(0x4d1) << 8 | inb(0x4d0);
+	printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
+}
+
+__apicdebuginit(int) print_all_ICs(void)
+{
+	print_PIC();
+	print_all_local_APICs();
+	print_IO_APIC();
+
+	return 0;
+}
+
+fs_initcall(print_all_ICs);
+
+
+/* Where if anywhere is the i8259 connect in external int mode */
+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+
+void __init enable_IO_APIC(void)
+{
+	union IO_APIC_reg_01 reg_01;
+	int i8259_apic, i8259_pin;
+	int apic;
+	unsigned long flags;
+
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	for (apic = 0; apic < nr_ioapics; apic++) {
+		spin_lock_irqsave(&ioapic_lock, flags);
+		reg_01.raw = io_apic_read(apic, 1);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+	}
+	for(apic = 0; apic < nr_ioapics; apic++) {
+		int pin;
+		/* See if any of the pins is in ExtINT mode */
+		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+			struct IO_APIC_route_entry entry;
+			entry = ioapic_read_entry(apic, pin);
+
+			/* If the interrupt line is enabled and in ExtInt mode
+			 * I have found the pin where the i8259 is connected.
+			 */
+			if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
+				ioapic_i8259.apic = apic;
+				ioapic_i8259.pin  = pin;
+				goto found_i8259;
+			}
+		}
+	}
+ found_i8259:
+	/* Look to see what if the MP table has reported the ExtINT */
+	/* If we could not find the appropriate pin by looking at the ioapic
+	 * the i8259 probably is not connected the ioapic but give the
+	 * mptable a chance anyway.
+	 */
+	i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
+	i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
+	/* Trust the MP table if nothing is setup in the hardware */
+	if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
+		printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
+		ioapic_i8259.pin  = i8259_pin;
+		ioapic_i8259.apic = i8259_apic;
+	}
+	/* Complain if the MP table and the hardware disagree */
+	if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
+		(i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
+	{
+		printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
+	}
+
+	/*
+	 * Do not trust the IO-APIC being empty at bootup
+	 */
+	clear_IO_APIC();
+}
+
+/*
+ * Not an __init, needed by the reboot code
+ */
+void disable_IO_APIC(void)
+{
+	/*
+	 * Clear the IO-APIC before rebooting:
+	 */
+	clear_IO_APIC();
+
+	/*
+	 * If the i8259 is routed through an IOAPIC
+	 * Put that IOAPIC in virtual wire mode
+	 * so legacy interrupts can be delivered.
+	 *
+	 * With interrupt-remapping, for now we will use virtual wire A mode,
+	 * as virtual wire B is little complex (need to configure both
+	 * IOAPIC RTE aswell as interrupt-remapping table entry).
+	 * As this gets called during crash dump, keep this simple for now.
+	 */
+	if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) {
+		struct IO_APIC_route_entry entry;
+
+		memset(&entry, 0, sizeof(entry));
+		entry.mask            = 0; /* Enabled */
+		entry.trigger         = 0; /* Edge */
+		entry.irr             = 0;
+		entry.polarity        = 0; /* High */
+		entry.delivery_status = 0;
+		entry.dest_mode       = 0; /* Physical */
+		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
+		entry.vector          = 0;
+		entry.dest            = read_apic_id();
+
+		/*
+		 * Add it to the IO-APIC irq-routing table:
+		 */
+		ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
+	}
+
+	/*
+	 * Use virtual wire A mode when interrupt remapping is enabled.
+	 */
+	disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1);
+}
+
+#ifdef CONFIG_X86_32
+/*
+ * function to set the IO-APIC physical IDs based on the
+ * values stored in the MPC table.
+ *
+ * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
+ */
+
+static void __init setup_ioapic_ids_from_mpc(void)
+{
+	union IO_APIC_reg_00 reg_00;
+	physid_mask_t phys_id_present_map;
+	int apic_id;
+	int i;
+	unsigned char old_id;
+	unsigned long flags;
+
+	if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
+		return;
+
+	/*
+	 * Don't check I/O APIC IDs for xAPIC systems.  They have
+	 * no meaning without the serial APIC bus.
+	 */
+	if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+		|| APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
+		return;
+	/*
+	 * 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);
+
+	/*
+	 * Set the IOAPIC ID to the value stored in the MPC table.
+	 */
+	for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
+
+		/* Read the register 0 value */
+		spin_lock_irqsave(&ioapic_lock, flags);
+		reg_00.raw = io_apic_read(apic_id, 0);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+
+		old_id = mp_ioapics[apic_id].apicid;
+
+		if (mp_ioapics[apic_id].apicid >= get_physical_broadcast()) {
+			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
+				apic_id, mp_ioapics[apic_id].apicid);
+			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+				reg_00.bits.ID);
+			mp_ioapics[apic_id].apicid = reg_00.bits.ID;
+		}
+
+		/*
+		 * Sanity check, is the ID really free? 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(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);
+			for (i = 0; i < get_physical_broadcast(); i++)
+				if (!physid_isset(i, phys_id_present_map))
+					break;
+			if (i >= get_physical_broadcast())
+				panic("Max APIC ID exceeded!\n");
+			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+				i);
+			physid_set(i, phys_id_present_map);
+			mp_ioapics[apic_id].apicid = i;
+		} else {
+			physid_mask_t tmp;
+			tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid);
+			apic_printk(APIC_VERBOSE, "Setting %d in the "
+					"phys_id_present_map\n",
+					mp_ioapics[apic_id].apicid);
+			physids_or(phys_id_present_map, phys_id_present_map, tmp);
+		}
+
+
+		/*
+		 * We need to adjust the IRQ routing table
+		 * if the ID changed.
+		 */
+		if (old_id != mp_ioapics[apic_id].apicid)
+			for (i = 0; i < mp_irq_entries; i++)
+				if (mp_irqs[i].dstapic == old_id)
+					mp_irqs[i].dstapic
+						= mp_ioapics[apic_id].apicid;
+
+		/*
+		 * Read the right value from the MPC table and
+		 * write it into the ID register.
+		 */
+		apic_printk(APIC_VERBOSE, KERN_INFO
+			"...changing IO-APIC physical APIC ID to %d ...",
+			mp_ioapics[apic_id].apicid);
+
+		reg_00.bits.ID = mp_ioapics[apic_id].apicid;
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(apic_id, 0, reg_00.raw);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+
+		/*
+		 * Sanity check
+		 */
+		spin_lock_irqsave(&ioapic_lock, flags);
+		reg_00.raw = io_apic_read(apic_id, 0);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+		if (reg_00.bits.ID != mp_ioapics[apic_id].apicid)
+			printk("could not set ID!\n");
+		else
+			apic_printk(APIC_VERBOSE, " ok.\n");
+	}
+}
+#endif
+
+int no_timer_check __initdata;
+
+static int __init notimercheck(char *s)
+{
+	no_timer_check = 1;
+	return 1;
+}
+__setup("no_timer_check", notimercheck);
+
+/*
+ * There is a nasty bug in some older SMP boards, their mptable lies
+ * about the timer IRQ. We do the following to work around the situation:
+ *
+ *	- timer IRQ defaults to IO-APIC IRQ
+ *	- if this function detects that timer IRQs are defunct, then we fall
+ *	  back to ISA timer IRQs
+ */
+static int __init timer_irq_works(void)
+{
+	unsigned long t1 = jiffies;
+	unsigned long flags;
+
+	if (no_timer_check)
+		return 1;
+
+	local_save_flags(flags);
+	local_irq_enable();
+	/* Let ten ticks pass... */
+	mdelay((10 * 1000) / HZ);
+	local_irq_restore(flags);
+
+	/*
+	 * Expect a few ticks at least, to be sure some possible
+	 * glue logic does not lock up after one or two first
+	 * ticks in a non-ExtINT mode.  Also the local APIC
+	 * might have cached one ExtINT interrupt.  Finally, at
+	 * least one tick may be lost due to delays.
+	 */
+
+	/* jiffies wrap? */
+	if (time_after(jiffies, t1 + 4))
+		return 1;
+	return 0;
+}
+
+/*
+ * In the SMP+IOAPIC case it might happen that there are an unspecified
+ * number of pending IRQ events unhandled. These cases are very rare,
+ * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
+ * better to do it this way as thus we do not have to be aware of
+ * 'pending' interrupts in the IRQ path, except at this point.
+ */
+/*
+ * Edge triggered needs to resend any interrupt
+ * that was delayed but this is now handled in the device
+ * independent code.
+ */
+
+/*
+ * Starting up a edge-triggered IO-APIC interrupt is
+ * nasty - we need to make sure that we get the edge.
+ * If it is already asserted for some reason, we need
+ * return 1 to indicate that is was pending.
+ *
+ * This is not complete - we should be able to fake
+ * an edge even if it isn't on the 8259A...
+ */
+
+static unsigned int startup_ioapic_irq(unsigned int irq)
+{
+	int was_pending = 0;
+	unsigned long flags;
+	struct irq_cfg *cfg;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	if (irq < NR_IRQS_LEGACY) {
+		disable_8259A_irq(irq);
+		if (i8259A_irq_pending(irq))
+			was_pending = 1;
+	}
+	cfg = irq_cfg(irq);
+	__unmask_IO_APIC_irq(cfg);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return was_pending;
+}
+
+#ifdef CONFIG_X86_64
+static int ioapic_retrigger_irq(unsigned int irq)
+{
+
+	struct irq_cfg *cfg = irq_cfg(irq);
+	unsigned long flags;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector);
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	return 1;
+}
+#else
+static int ioapic_retrigger_irq(unsigned int irq)
+{
+	apic->send_IPI_self(irq_cfg(irq)->vector);
+
+	return 1;
+}
+#endif
+
+/*
+ * Level and edge triggered IO-APIC interrupts need different handling,
+ * so we use two separate IRQ descriptors. Edge triggered IRQs can be
+ * handled with the level-triggered descriptor, but that one has slightly
+ * more overhead. Level-triggered interrupts cannot be handled with the
+ * edge-triggered handler, without risking IRQ storms and other ugly
+ * races.
+ */
+
+#ifdef CONFIG_SMP
+
+#ifdef CONFIG_INTR_REMAP
+
+/*
+ * Migrate the IO-APIC irq in the presence of intr-remapping.
+ *
+ * For both level and edge triggered, irq migration is a simple atomic
+ * update(of vector and cpu destination) of IRTE and flush the hardware cache.
+ *
+ * For level triggered, we eliminate the io-apic RTE modification (with the
+ * updated vector information), by using a virtual vector (io-apic pin number).
+ * Real vector that is used for interrupting cpu will be coming from
+ * the interrupt-remapping table entry.
+ */
+static void
+migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+{
+	struct irq_cfg *cfg;
+	struct irte irte;
+	unsigned int dest;
+	unsigned int irq;
+
+	if (!cpumask_intersects(mask, cpu_online_mask))
+		return;
+
+	irq = desc->irq;
+	if (get_irte(irq, &irte))
+		return;
+
+	cfg = desc->chip_data;
+	if (assign_irq_vector(irq, cfg, mask))
+		return;
+
+	set_extra_move_desc(desc, mask);
+
+	dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
+
+	irte.vector = cfg->vector;
+	irte.dest_id = IRTE_DEST(dest);
+
+	/*
+	 * Modified the IRTE and flushes the Interrupt entry cache.
+	 */
+	modify_irte(irq, &irte);
+
+	if (cfg->move_in_progress)
+		send_cleanup_vector(cfg);
+
+	cpumask_copy(desc->affinity, mask);
+}
+
+/*
+ * Migrates the IRQ destination in the process context.
+ */
+static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+					    const struct cpumask *mask)
+{
+	migrate_ioapic_irq_desc(desc, mask);
+}
+static void set_ir_ioapic_affinity_irq(unsigned int irq,
+				       const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	set_ir_ioapic_affinity_irq_desc(desc, mask);
+}
+#else
+static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+						   const struct cpumask *mask)
+{
+}
+#endif
+
+asmlinkage void smp_irq_move_cleanup_interrupt(void)
+{
+	unsigned vector, me;
+
+	ack_APIC_irq();
+	exit_idle();
+	irq_enter();
+
+	me = smp_processor_id();
+	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
+		unsigned int irq;
+		unsigned int irr;
+		struct irq_desc *desc;
+		struct irq_cfg *cfg;
+		irq = __get_cpu_var(vector_irq)[vector];
+
+		if (irq == -1)
+			continue;
+
+		desc = irq_to_desc(irq);
+		if (!desc)
+			continue;
+
+		cfg = irq_cfg(irq);
+		spin_lock(&desc->lock);
+		if (!cfg->move_cleanup_count)
+			goto unlock;
+
+		if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
+			goto unlock;
+
+		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
+		/*
+		 * Check if the vector that needs to be cleanedup is
+		 * registered at the cpu's IRR. If so, then this is not
+		 * the best time to clean it up. Lets clean it up in the
+		 * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR
+		 * to myself.
+		 */
+		if (irr  & (1 << (vector % 32))) {
+			apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
+			goto unlock;
+		}
+		__get_cpu_var(vector_irq)[vector] = -1;
+		cfg->move_cleanup_count--;
+unlock:
+		spin_unlock(&desc->lock);
+	}
+
+	irq_exit();
+}
+
+static void irq_complete_move(struct irq_desc **descp)
+{
+	struct irq_desc *desc = *descp;
+	struct irq_cfg *cfg = desc->chip_data;
+	unsigned vector, me;
+
+	if (likely(!cfg->move_in_progress)) {
+#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
+		if (likely(!cfg->move_desc_pending))
+			return;
+
+		/* domain has not changed, but affinity did */
+		me = smp_processor_id();
+		if (cpumask_test_cpu(me, desc->affinity)) {
+			*descp = desc = move_irq_desc(desc, me);
+			/* get the new one */
+			cfg = desc->chip_data;
+			cfg->move_desc_pending = 0;
+		}
+#endif
+		return;
+	}
+
+	vector = ~get_irq_regs()->orig_ax;
+	me = smp_processor_id();
+
+	if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
+#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
+		*descp = desc = move_irq_desc(desc, me);
+		/* get the new one */
+		cfg = desc->chip_data;
+#endif
+		send_cleanup_vector(cfg);
+	}
+}
+#else
+static inline void irq_complete_move(struct irq_desc **descp) {}
+#endif
+
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+	int apic, pin;
+	struct irq_pin_list *entry;
+
+	entry = cfg->irq_2_pin;
+	for (;;) {
+
+		if (!entry)
+			break;
+
+		apic = entry->apic;
+		pin = entry->pin;
+		io_apic_eoi(apic, pin);
+		entry = entry->next;
+	}
+}
+
+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);
+}
+
+#ifdef CONFIG_X86_X2APIC
+static void ack_x2apic_level(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	ack_x2APIC_irq();
+	eoi_ioapic_irq(desc);
+}
+
+static void ack_x2apic_edge(unsigned int irq)
+{
+	ack_x2APIC_irq();
+}
+#endif
+
+static void ack_apic_edge(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	irq_complete_move(&desc);
+	move_native_irq(irq);
+	ack_APIC_irq();
+}
+
+atomic_t irq_mis_count;
+
+static void ack_apic_level(unsigned int irq)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+
+#ifdef CONFIG_X86_32
+	unsigned long v;
+	int i;
+#endif
+	struct irq_cfg *cfg;
+	int do_unmask_irq = 0;
+
+	irq_complete_move(&desc);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+	/* If we are moving the irq we need to mask it */
+	if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
+		do_unmask_irq = 1;
+		mask_IO_APIC_irq_desc(desc);
+	}
+#endif
+
+#ifdef CONFIG_X86_32
+	/*
+	* It appears there is an erratum which affects at least version 0x11
+	* of I/O APIC (that's the 82093AA and cores integrated into various
+	* chipsets).  Under certain conditions a level-triggered interrupt is
+	* erroneously delivered as edge-triggered one but the respective IRR
+	* bit gets set nevertheless.  As a result the I/O unit expects an EOI
+	* message but it will never arrive and further interrupts are blocked
+	* from the source.  The exact reason is so far unknown, but the
+	* phenomenon was observed when two consecutive interrupt requests
+	* from a given source get delivered to the same CPU and the source is
+	* temporarily disabled in between.
+	*
+	* A workaround is to simulate an EOI message manually.  We achieve it
+	* by setting the trigger mode to edge and then to level when the edge
+	* trigger mode gets detected in the TMR of a local APIC for a
+	* 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
+	*/
+	cfg = desc->chip_data;
+	i = cfg->vector;
+
+	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+#endif
+
+	/*
+	 * We must acknowledge the irq before we move it or the acknowledge will
+	 * not propagate properly.
+	 */
+	ack_APIC_irq();
+
+	if (irq_remapped(irq))
+		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.
+		 *
+		 * On rare occasions the broadcast level triggered ack gets
+		 * delayed going to ioapics, and if we reprogram the
+		 * vector while Remote IRR is still set the irq will never
+		 * fire again.
+		 *
+		 * To prevent this scenario we read the Remote IRR bit
+		 * of the ioapic.  This has two effects.
+		 * - On any sane system the read of the ioapic will
+		 *   flush writes (and acks) going to the ioapic from
+		 *   this cpu.
+		 * - We get to see if the ACK has actually been delivered.
+		 *
+		 * Based on failed experiments of reprogramming the
+		 * ioapic entry from outside of irq context starting
+		 * with masking the ioapic entry and then polling until
+		 * Remote IRR was clear before reprogramming the
+		 * ioapic I don't trust the Remote IRR bit to be
+		 * completey accurate.
+		 *
+		 * However there appears to be no other way to plug
+		 * this race, so if the Remote IRR bit is not
+		 * accurate and is causing problems then it is a hardware bug
+		 * and you can go talk to the chipset vendor about it.
+		 */
+		cfg = desc->chip_data;
+		if (!io_apic_level_ack_pending(cfg))
+			move_masked_irq(irq);
+		unmask_IO_APIC_irq_desc(desc);
+	}
+
+#ifdef CONFIG_X86_32
+	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);
+	}
+#endif
+}
+
+#ifdef CONFIG_INTR_REMAP
+static void ir_ack_apic_edge(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+       if (x2apic_enabled())
+               return ack_x2apic_edge(irq);
+#endif
+       return ack_apic_edge(irq);
+}
+
+static void ir_ack_apic_level(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+       if (x2apic_enabled())
+               return ack_x2apic_level(irq);
+#endif
+       return ack_apic_level(irq);
+}
+#endif /* CONFIG_INTR_REMAP */
+
+static struct irq_chip ioapic_chip __read_mostly = {
+	.name		= "IO-APIC",
+	.startup	= startup_ioapic_irq,
+	.mask		= mask_IO_APIC_irq,
+	.unmask		= unmask_IO_APIC_irq,
+	.ack		= ack_apic_edge,
+	.eoi		= ack_apic_level,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_ioapic_affinity_irq,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+static struct irq_chip ir_ioapic_chip __read_mostly = {
+	.name		= "IR-IO-APIC",
+	.startup	= startup_ioapic_irq,
+	.mask		= mask_IO_APIC_irq,
+	.unmask		= unmask_IO_APIC_irq,
+#ifdef CONFIG_INTR_REMAP
+	.ack		= ir_ack_apic_edge,
+	.eoi		= ir_ack_apic_level,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_ir_ioapic_affinity_irq,
+#endif
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+static inline void init_IO_APIC_traps(void)
+{
+	int irq;
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
+
+	/*
+	 * NOTE! The local APIC isn't very good at handling
+	 * multiple interrupts at the same interrupt level.
+	 * As the interrupt level is determined by taking the
+	 * vector number and shifting that right by 4, we
+	 * want to spread these out a bit so that they don't
+	 * all fall in the same interrupt level.
+	 *
+	 * Also, we've got to be careful not to trash gate
+	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
+	 */
+	for_each_irq_desc(irq, desc) {
+		cfg = desc->chip_data;
+		if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
+			/*
+			 * Hmm.. We don't have an entry for this,
+			 * so default to an old-fashioned 8259
+			 * interrupt if we can..
+			 */
+			if (irq < NR_IRQS_LEGACY)
+				make_8259A_irq(irq);
+			else
+				/* Strange. Oh, well.. */
+				desc->chip = &no_irq_chip;
+		}
+	}
+}
+
+/*
+ * The local APIC irq-chip implementation:
+ */
+
+static void mask_lapic_irq(unsigned int irq)
+{
+	unsigned long v;
+
+	v = apic_read(APIC_LVT0);
+	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
+}
+
+static void unmask_lapic_irq(unsigned int irq)
+{
+	unsigned long v;
+
+	v = apic_read(APIC_LVT0);
+	apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
+}
+
+static void ack_lapic_irq(unsigned int irq)
+{
+	ack_APIC_irq();
+}
+
+static struct irq_chip lapic_chip __read_mostly = {
+	.name		= "local-APIC",
+	.mask		= mask_lapic_irq,
+	.unmask		= unmask_lapic_irq,
+	.ack		= ack_lapic_irq,
+};
+
+static void lapic_register_intr(int irq, struct irq_desc *desc)
+{
+	desc->status &= ~IRQ_LEVEL;
+	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
+				      "edge");
+}
+
+static void __init setup_nmi(void)
+{
+	/*
+	 * Dirty trick to enable the NMI watchdog ...
+	 * We put the 8259A master into AEOI mode and
+	 * unmask on all local APICs LVT0 as NMI.
+	 *
+	 * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
+	 * is from Maciej W. Rozycki - so we do not have to EOI from
+	 * the NMI handler or the timer interrupt.
+	 */
+	apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
+
+	enable_NMI_through_LVT0();
+
+	apic_printk(APIC_VERBOSE, " done.\n");
+}
+
+/*
+ * This looks a bit hackish but it's about the only one way of sending
+ * a few INTA cycles to 8259As and any associated glue logic.  ICR does
+ * not support the ExtINT mode, unfortunately.  We need to send these
+ * cycles as some i82489DX-based boards have glue logic that keeps the
+ * 8259A interrupt line asserted until INTA.  --macro
+ */
+static inline void __init unlock_ExtINT_logic(void)
+{
+	int apic, pin, i;
+	struct IO_APIC_route_entry entry0, entry1;
+	unsigned char save_control, save_freq_select;
+
+	pin  = find_isa_irq_pin(8, mp_INT);
+	if (pin == -1) {
+		WARN_ON_ONCE(1);
+		return;
+	}
+	apic = find_isa_irq_apic(8, mp_INT);
+	if (apic == -1) {
+		WARN_ON_ONCE(1);
+		return;
+	}
+
+	entry0 = ioapic_read_entry(apic, pin);
+	clear_IO_APIC_pin(apic, pin);
+
+	memset(&entry1, 0, sizeof(entry1));
+
+	entry1.dest_mode = 0;			/* physical delivery */
+	entry1.mask = 0;			/* unmask IRQ now */
+	entry1.dest = hard_smp_processor_id();
+	entry1.delivery_mode = dest_ExtINT;
+	entry1.polarity = entry0.polarity;
+	entry1.trigger = 0;
+	entry1.vector = 0;
+
+	ioapic_write_entry(apic, pin, entry1);
+
+	save_control = CMOS_READ(RTC_CONTROL);
+	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+	CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
+		   RTC_FREQ_SELECT);
+	CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
+
+	i = 100;
+	while (i-- > 0) {
+		mdelay(10);
+		if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
+			i -= 10;
+	}
+
+	CMOS_WRITE(save_control, RTC_CONTROL);
+	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+	clear_IO_APIC_pin(apic, pin);
+
+	ioapic_write_entry(apic, pin, entry0);
+}
+
+static int disable_timer_pin_1 __initdata;
+/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
+static int __init disable_timer_pin_setup(char *arg)
+{
+	disable_timer_pin_1 = 1;
+	return 0;
+}
+early_param("disable_timer_pin_1", disable_timer_pin_setup);
+
+int timer_through_8259 __initdata;
+
+/*
+ * This code may look a bit paranoid, but it's supposed to cooperate with
+ * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
+ * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
+ * fanatically on his truly buggy board.
+ *
+ * FIXME: really need to revamp this for all platforms.
+ */
+static inline void __init check_timer(void)
+{
+	struct irq_desc *desc = irq_to_desc(0);
+	struct irq_cfg *cfg = desc->chip_data;
+	int cpu = boot_cpu_id;
+	int apic1, pin1, apic2, pin2;
+	unsigned long flags;
+	int no_pin1 = 0;
+
+	local_irq_save(flags);
+
+	/*
+	 * get/set the timer IRQ vector:
+	 */
+	disable_8259A_irq(0);
+	assign_irq_vector(0, cfg, apic->target_cpus());
+
+	/*
+	 * As IRQ0 is to be enabled in the 8259A, the virtual
+	 * wire has to be disabled in the local APIC.  Also
+	 * timer interrupts need to be acknowledged manually in
+	 * the 8259A for the i82489DX when using the NMI
+	 * watchdog as that APIC treats NMIs as level-triggered.
+	 * The AEOI mode will finish them in the 8259A
+	 * automatically.
+	 */
+	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
+	init_8259A(1);
+#ifdef CONFIG_X86_32
+	{
+		unsigned int ver;
+
+		ver = apic_read(APIC_LVR);
+		ver = GET_APIC_VERSION(ver);
+		timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
+	}
+#endif
+
+	pin1  = find_isa_irq_pin(0, mp_INT);
+	apic1 = find_isa_irq_apic(0, mp_INT);
+	pin2  = ioapic_i8259.pin;
+	apic2 = ioapic_i8259.apic;
+
+	apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
+		    "apic1=%d pin1=%d apic2=%d pin2=%d\n",
+		    cfg->vector, apic1, pin1, apic2, pin2);
+
+	/*
+	 * Some BIOS writers are clueless and report the ExtINTA
+	 * I/O APIC input from the cascaded 8259A as the timer
+	 * interrupt input.  So just in case, if only one pin
+	 * was found above, try it both directly and through the
+	 * 8259A.
+	 */
+	if (pin1 == -1) {
+		if (intr_remapping_enabled)
+			panic("BIOS bug: timer not connected to IO-APIC");
+		pin1 = pin2;
+		apic1 = apic2;
+		no_pin1 = 1;
+	} else if (pin2 == -1) {
+		pin2 = pin1;
+		apic2 = apic1;
+	}
+
+	if (pin1 != -1) {
+		/*
+		 * Ok, does IRQ0 through the IOAPIC work?
+		 */
+		if (no_pin1) {
+			add_pin_to_irq_cpu(cfg, cpu, apic1, pin1);
+			setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
+		} else {
+			/* for edge trigger, setup_IO_APIC_irq already
+			 * leave it unmasked.
+			 * so only need to unmask if it is level-trigger
+			 * do we really have level trigger timer?
+			 */
+			int idx;
+			idx = find_irq_entry(apic1, pin1, mp_INT);
+			if (idx != -1 && irq_trigger(idx))
+				unmask_IO_APIC_irq_desc(desc);
+		}
+		if (timer_irq_works()) {
+			if (nmi_watchdog == NMI_IO_APIC) {
+				setup_nmi();
+				enable_8259A_irq(0);
+			}
+			if (disable_timer_pin_1 > 0)
+				clear_IO_APIC_pin(0, pin1);
+			goto out;
+		}
+		if (intr_remapping_enabled)
+			panic("timer doesn't work through Interrupt-remapped IO-APIC");
+		local_irq_disable();
+		clear_IO_APIC_pin(apic1, pin1);
+		if (!no_pin1)
+			apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
+				    "8254 timer not connected to IO-APIC\n");
+
+		apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
+			    "(IRQ0) through the 8259A ...\n");
+		apic_printk(APIC_QUIET, KERN_INFO
+			    "..... (found apic %d pin %d) ...\n", apic2, pin2);
+		/*
+		 * legacy devices should be connected to IO APIC #0
+		 */
+		replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2);
+		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
+		enable_8259A_irq(0);
+		if (timer_irq_works()) {
+			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
+			timer_through_8259 = 1;
+			if (nmi_watchdog == NMI_IO_APIC) {
+				disable_8259A_irq(0);
+				setup_nmi();
+				enable_8259A_irq(0);
+			}
+			goto out;
+		}
+		/*
+		 * Cleanup, just in case ...
+		 */
+		local_irq_disable();
+		disable_8259A_irq(0);
+		clear_IO_APIC_pin(apic2, pin2);
+		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
+	}
+
+	if (nmi_watchdog == NMI_IO_APIC) {
+		apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
+			    "through the IO-APIC - disabling NMI Watchdog!\n");
+		nmi_watchdog = NMI_NONE;
+	}
+#ifdef CONFIG_X86_32
+	timer_ack = 0;
+#endif
+
+	apic_printk(APIC_QUIET, KERN_INFO
+		    "...trying to set up timer as Virtual Wire IRQ...\n");
+
+	lapic_register_intr(0, desc);
+	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
+	enable_8259A_irq(0);
+
+	if (timer_irq_works()) {
+		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
+		goto out;
+	}
+	local_irq_disable();
+	disable_8259A_irq(0);
+	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
+	apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
+
+	apic_printk(APIC_QUIET, KERN_INFO
+		    "...trying to set up timer as ExtINT IRQ...\n");
+
+	init_8259A(0);
+	make_8259A_irq(0);
+	apic_write(APIC_LVT0, APIC_DM_EXTINT);
+
+	unlock_ExtINT_logic();
+
+	if (timer_irq_works()) {
+		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
+		goto out;
+	}
+	local_irq_disable();
+	apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
+	panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
+		"report.  Then try booting with the 'noapic' option.\n");
+out:
+	local_irq_restore(flags);
+}
+
+/*
+ * Traditionally ISA IRQ2 is the cascade IRQ, and is not available
+ * to devices.  However there may be an I/O APIC pin available for
+ * this interrupt regardless.  The pin may be left unconnected, but
+ * typically it will be reused as an ExtINT cascade interrupt for
+ * the master 8259A.  In the MPS case such a pin will normally be
+ * reported as an ExtINT interrupt in the MP table.  With ACPI
+ * there is no provision for ExtINT interrupts, and in the absence
+ * of an override it would be treated as an ordinary ISA I/O APIC
+ * interrupt, that is edge-triggered and unmasked by default.  We
+ * used to do this, but it caused problems on some systems because
+ * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
+ * the same ExtINT cascade interrupt to drive the local APIC of the
+ * bootstrap processor.  Therefore we refrain from routing IRQ2 to
+ * the I/O APIC in all cases now.  No actual device should request
+ * it anyway.  --macro
+ */
+#define PIC_IRQS	(1 << PIC_CASCADE_IR)
+
+void __init setup_IO_APIC(void)
+{
+
+	/*
+	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
+	 */
+
+	io_apic_irqs = ~PIC_IRQS;
+
+	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
+	/*
+         * Set up IO-APIC IRQ routing.
+         */
+#ifdef CONFIG_X86_32
+	if (!acpi_ioapic)
+		setup_ioapic_ids_from_mpc();
+#endif
+	sync_Arb_IDs();
+	setup_IO_APIC_irqs();
+	init_IO_APIC_traps();
+	check_timer();
+}
+
+/*
+ *      Called after all the initialization is done. If we didnt find any
+ *      APIC bugs then we can allow the modify fast path
+ */
+
+static int __init io_apic_bug_finalize(void)
+{
+	if (sis_apic_bug == -1)
+		sis_apic_bug = 0;
+	return 0;
+}
+
+late_initcall(io_apic_bug_finalize);
+
+struct sysfs_ioapic_data {
+	struct sys_device dev;
+	struct IO_APIC_route_entry entry[0];
+};
+static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
+
+static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct IO_APIC_route_entry *entry;
+	struct sysfs_ioapic_data *data;
+	int i;
+
+	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	entry = data->entry;
+	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ )
+		*entry = ioapic_read_entry(dev->id, i);
+
+	return 0;
+}
+
+static int ioapic_resume(struct sys_device *dev)
+{
+	struct IO_APIC_route_entry *entry;
+	struct sysfs_ioapic_data *data;
+	unsigned long flags;
+	union IO_APIC_reg_00 reg_00;
+	int i;
+
+	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	entry = data->entry;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_00.raw = io_apic_read(dev->id, 0);
+	if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) {
+		reg_00.bits.ID = mp_ioapics[dev->id].apicid;
+		io_apic_write(dev->id, 0, reg_00.raw);
+	}
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+	for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
+		ioapic_write_entry(dev->id, i, entry[i]);
+
+	return 0;
+}
+
+static struct sysdev_class ioapic_sysdev_class = {
+	.name = "ioapic",
+	.suspend = ioapic_suspend,
+	.resume = ioapic_resume,
+};
+
+static int __init ioapic_init_sysfs(void)
+{
+	struct sys_device * dev;
+	int i, size, error;
+
+	error = sysdev_class_register(&ioapic_sysdev_class);
+	if (error)
+		return error;
+
+	for (i = 0; i < nr_ioapics; i++ ) {
+		size = sizeof(struct sys_device) + nr_ioapic_registers[i]
+			* sizeof(struct IO_APIC_route_entry);
+		mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
+		if (!mp_ioapic_data[i]) {
+			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
+			continue;
+		}
+		dev = &mp_ioapic_data[i]->dev;
+		dev->id = i;
+		dev->cls = &ioapic_sysdev_class;
+		error = sysdev_register(dev);
+		if (error) {
+			kfree(mp_ioapic_data[i]);
+			mp_ioapic_data[i] = NULL;
+			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+device_initcall(ioapic_init_sysfs);
+
+static int nr_irqs_gsi = NR_IRQS_LEGACY;
+/*
+ * Dynamic irq allocate and deallocation
+ */
+unsigned int create_irq_nr(unsigned int irq_want)
+{
+	/* Allocate an unused irq */
+	unsigned int irq;
+	unsigned int new;
+	unsigned long flags;
+	struct irq_cfg *cfg_new = NULL;
+	int cpu = boot_cpu_id;
+	struct irq_desc *desc_new = NULL;
+
+	irq = 0;
+	if (irq_want < nr_irqs_gsi)
+		irq_want = nr_irqs_gsi;
+
+	spin_lock_irqsave(&vector_lock, flags);
+	for (new = irq_want; new < nr_irqs; new++) {
+		desc_new = irq_to_desc_alloc_cpu(new, cpu);
+		if (!desc_new) {
+			printk(KERN_INFO "can not get irq_desc for %d\n", new);
+			continue;
+		}
+		cfg_new = desc_new->chip_data;
+
+		if (cfg_new->vector != 0)
+			continue;
+		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
+			irq = new;
+		break;
+	}
+	spin_unlock_irqrestore(&vector_lock, flags);
+
+	if (irq > 0) {
+		dynamic_irq_init(irq);
+		/* restore it, in case dynamic_irq_init clear it */
+		if (desc_new)
+			desc_new->chip_data = cfg_new;
+	}
+	return irq;
+}
+
+int create_irq(void)
+{
+	unsigned int irq_want;
+	int irq;
+
+	irq_want = nr_irqs_gsi;
+	irq = create_irq_nr(irq_want);
+
+	if (irq == 0)
+		irq = -1;
+
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+	struct irq_cfg *cfg;
+	struct irq_desc *desc;
+
+	/* store it, in case dynamic_irq_cleanup clear it */
+	desc = irq_to_desc(irq);
+	cfg = desc->chip_data;
+	dynamic_irq_cleanup(irq);
+	/* connect back irq_cfg */
+	if (desc)
+		desc->chip_data = cfg;
+
+	free_irte(irq);
+	spin_lock_irqsave(&vector_lock, flags);
+	__clear_irq_vector(irq, cfg);
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+/*
+ * MSI message composition
+ */
+#ifdef CONFIG_PCI_MSI
+static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
+{
+	struct irq_cfg *cfg;
+	int err;
+	unsigned dest;
+
+	if (disable_apic)
+		return -ENXIO;
+
+	cfg = irq_cfg(irq);
+	err = assign_irq_vector(irq, cfg, apic->target_cpus());
+	if (err)
+		return err;
+
+	dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
+
+	if (irq_remapped(irq)) {
+		struct irte irte;
+		int ir_index;
+		u16 sub_handle;
+
+		ir_index = map_irq_to_irte_handle(irq, &sub_handle);
+		BUG_ON(ir_index == -1);
+
+		memset (&irte, 0, sizeof(irte));
+
+		irte.present = 1;
+		irte.dst_mode = apic->irq_dest_mode;
+		irte.trigger_mode = 0; /* edge */
+		irte.dlvry_mode = apic->irq_delivery_mode;
+		irte.vector = cfg->vector;
+		irte.dest_id = IRTE_DEST(dest);
+
+		modify_irte(irq, &irte);
+
+		msg->address_hi = MSI_ADDR_BASE_HI;
+		msg->data = sub_handle;
+		msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
+				  MSI_ADDR_IR_SHV |
+				  MSI_ADDR_IR_INDEX1(ir_index) |
+				  MSI_ADDR_IR_INDEX2(ir_index);
+	} else {
+		if (x2apic_enabled())
+			msg->address_hi = MSI_ADDR_BASE_HI |
+					  MSI_ADDR_EXT_DEST_ID(dest);
+		else
+			msg->address_hi = MSI_ADDR_BASE_HI;
+
+		msg->address_lo =
+			MSI_ADDR_BASE_LO |
+			((apic->irq_dest_mode == 0) ?
+				MSI_ADDR_DEST_MODE_PHYSICAL:
+				MSI_ADDR_DEST_MODE_LOGICAL) |
+			((apic->irq_delivery_mode != dest_LowestPrio) ?
+				MSI_ADDR_REDIRECTION_CPU:
+				MSI_ADDR_REDIRECTION_LOWPRI) |
+			MSI_ADDR_DEST_ID(dest);
+
+		msg->data =
+			MSI_DATA_TRIGGER_EDGE |
+			MSI_DATA_LEVEL_ASSERT |
+			((apic->irq_delivery_mode != dest_LowestPrio) ?
+				MSI_DATA_DELIVERY_FIXED:
+				MSI_DATA_DELIVERY_LOWPRI) |
+			MSI_DATA_VECTOR(cfg->vector);
+	}
+	return err;
+}
+
+#ifdef CONFIG_SMP
+static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg;
+	struct msi_msg msg;
+	unsigned int dest;
+
+	dest = set_desc_affinity(desc, mask);
+	if (dest == BAD_APICID)
+		return;
+
+	cfg = desc->chip_data;
+
+	read_msi_msg_desc(desc, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(cfg->vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	write_msi_msg_desc(desc, &msg);
+}
+#ifdef CONFIG_INTR_REMAP
+/*
+ * Migrate the MSI irq to another cpumask. This migration is
+ * done in the process context using interrupt-remapping hardware.
+ */
+static void
+ir_set_msi_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;
+	struct irte irte;
+
+	if (get_irte(irq, &irte))
+		return;
+
+	dest = set_desc_affinity(desc, mask);
+	if (dest == BAD_APICID)
+		return;
+
+	irte.vector = cfg->vector;
+	irte.dest_id = IRTE_DEST(dest);
+
+	/*
+	 * atomically update the IRTE with the new destination and vector.
+	 */
+	modify_irte(irq, &irte);
+
+	/*
+	 * After this point, all the interrupts will start arriving
+	 * at the new destination. So, time to cleanup the previous
+	 * vector allocation.
+	 */
+	if (cfg->move_in_progress)
+		send_cleanup_vector(cfg);
+}
+
+#endif
+#endif /* CONFIG_SMP */
+
+/*
+ * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
+ * which implement the MSI or MSI-X Capability Structure.
+ */
+static struct irq_chip msi_chip = {
+	.name		= "PCI-MSI",
+	.unmask		= unmask_msi_irq,
+	.mask		= mask_msi_irq,
+	.ack		= ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_msi_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+static struct irq_chip msi_ir_chip = {
+	.name		= "IR-PCI-MSI",
+	.unmask		= unmask_msi_irq,
+	.mask		= mask_msi_irq,
+#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,
+};
+
+/*
+ * Map the PCI dev to the corresponding remapping hardware unit
+ * and allocate 'nvec' consecutive interrupt-remapping table entries
+ * in it.
+ */
+static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
+{
+	struct intel_iommu *iommu;
+	int index;
+
+	iommu = map_dev_to_ir(dev);
+	if (!iommu) {
+		printk(KERN_ERR
+		       "Unable to map PCI %s to iommu\n", pci_name(dev));
+		return -ENOENT;
+	}
+
+	index = alloc_irte(iommu, irq, nvec);
+	if (index < 0) {
+		printk(KERN_ERR
+		       "Unable to allocate %d IRTE for PCI %s\n", nvec,
+		       pci_name(dev));
+		return -ENOSPC;
+	}
+	return index;
+}
+
+static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
+{
+	int ret;
+	struct msi_msg msg;
+
+	ret = msi_compose_msg(dev, irq, &msg);
+	if (ret < 0)
+		return ret;
+
+	set_irq_msi(irq, msidesc);
+	write_msi_msg(irq, &msg);
+
+	if (irq_remapped(irq)) {
+		struct irq_desc *desc = irq_to_desc(irq);
+		/*
+		 * irq migration in process context
+		 */
+		desc->status |= IRQ_MOVE_PCNTXT;
+		set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
+	} else
+		set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
+
+	dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq);
+
+	return 0;
+}
+
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+	unsigned int irq;
+	int ret, sub_handle;
+	struct msi_desc *msidesc;
+	unsigned int irq_want;
+	struct intel_iommu *iommu = NULL;
+	int index = 0;
+
+	/* x86 doesn't support multiple MSI yet */
+	if (type == PCI_CAP_ID_MSI && nvec > 1)
+		return 1;
+
+	irq_want = nr_irqs_gsi;
+	sub_handle = 0;
+	list_for_each_entry(msidesc, &dev->msi_list, list) {
+		irq = create_irq_nr(irq_want);
+		if (irq == 0)
+			return -1;
+		irq_want = irq + 1;
+		if (!intr_remapping_enabled)
+			goto no_ir;
+
+		if (!sub_handle) {
+			/*
+			 * allocate the consecutive block of IRTE's
+			 * for 'nvec'
+			 */
+			index = msi_alloc_irte(dev, irq, nvec);
+			if (index < 0) {
+				ret = index;
+				goto error;
+			}
+		} else {
+			iommu = map_dev_to_ir(dev);
+			if (!iommu) {
+				ret = -ENOENT;
+				goto error;
+			}
+			/*
+			 * setup the mapping between the irq and the IRTE
+			 * base index, the sub_handle pointing to the
+			 * appropriate interrupt remap table entry.
+			 */
+			set_irte_irq(irq, iommu, index, sub_handle);
+		}
+no_ir:
+		ret = setup_msi_irq(dev, msidesc, irq);
+		if (ret < 0)
+			goto error;
+		sub_handle++;
+	}
+	return 0;
+
+error:
+	destroy_irq(irq);
+	return ret;
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	destroy_irq(irq);
+}
+
+#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
+#ifdef CONFIG_SMP
+static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg;
+	struct msi_msg msg;
+	unsigned int dest;
+
+	dest = set_desc_affinity(desc, mask);
+	if (dest == BAD_APICID)
+		return;
+
+	cfg = desc->chip_data;
+
+	dmar_msi_read(irq, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(cfg->vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	dmar_msi_write(irq, &msg);
+}
+
+#endif /* CONFIG_SMP */
+
+struct irq_chip dmar_msi_type = {
+	.name = "DMAR_MSI",
+	.unmask = dmar_msi_unmask,
+	.mask = dmar_msi_mask,
+	.ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity = dmar_msi_set_affinity,
+#endif
+	.retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_dmar_msi(unsigned int irq)
+{
+	int ret;
+	struct msi_msg msg;
+
+	ret = msi_compose_msg(NULL, irq, &msg);
+	if (ret < 0)
+		return ret;
+	dmar_msi_write(irq, &msg);
+	set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
+		"edge");
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_HPET_TIMER
+
+#ifdef CONFIG_SMP
+static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg;
+	struct msi_msg msg;
+	unsigned int dest;
+
+	dest = set_desc_affinity(desc, mask);
+	if (dest == BAD_APICID)
+		return;
+
+	cfg = desc->chip_data;
+
+	hpet_msi_read(irq, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(cfg->vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	hpet_msi_write(irq, &msg);
+}
+
+#endif /* CONFIG_SMP */
+
+static struct irq_chip hpet_msi_type = {
+	.name = "HPET_MSI",
+	.unmask = hpet_msi_unmask,
+	.mask = hpet_msi_mask,
+	.ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity = hpet_msi_set_affinity,
+#endif
+	.retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_hpet_msi(unsigned int irq)
+{
+	int ret;
+	struct msi_msg msg;
+	struct irq_desc *desc = irq_to_desc(irq);
+
+	ret = msi_compose_msg(NULL, irq, &msg);
+	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");
+
+	return 0;
+}
+#endif
+
+#endif /* CONFIG_PCI_MSI */
+/*
+ * Hypertransport interrupt support
+ */
+#ifdef CONFIG_HT_IRQ
+
+#ifdef CONFIG_SMP
+
+static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
+{
+	struct ht_irq_msg msg;
+	fetch_ht_irq_msg(irq, &msg);
+
+	msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
+	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
+
+	msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
+	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
+
+	write_ht_irq_msg(irq, &msg);
+}
+
+static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
+{
+	struct irq_desc *desc = irq_to_desc(irq);
+	struct irq_cfg *cfg;
+	unsigned int dest;
+
+	dest = set_desc_affinity(desc, mask);
+	if (dest == BAD_APICID)
+		return;
+
+	cfg = desc->chip_data;
+
+	target_ht_irq(irq, dest, cfg->vector);
+}
+
+#endif
+
+static struct irq_chip ht_irq_chip = {
+	.name		= "PCI-HT",
+	.mask		= mask_ht_irq,
+	.unmask		= unmask_ht_irq,
+	.ack		= ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity	= set_ht_irq_affinity,
+#endif
+	.retrigger	= ioapic_retrigger_irq,
+};
+
+int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
+{
+	struct irq_cfg *cfg;
+	int err;
+
+	if (disable_apic)
+		return -ENXIO;
+
+	cfg = irq_cfg(irq);
+	err = assign_irq_vector(irq, cfg, apic->target_cpus());
+	if (!err) {
+		struct ht_irq_msg msg;
+		unsigned dest;
+
+		dest = apic->cpu_mask_to_apicid_and(cfg->domain,
+						    apic->target_cpus());
+
+		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
+
+		msg.address_lo =
+			HT_IRQ_LOW_BASE |
+			HT_IRQ_LOW_DEST_ID(dest) |
+			HT_IRQ_LOW_VECTOR(cfg->vector) |
+			((apic->irq_dest_mode == 0) ?
+				HT_IRQ_LOW_DM_PHYSICAL :
+				HT_IRQ_LOW_DM_LOGICAL) |
+			HT_IRQ_LOW_RQEOI_EDGE |
+			((apic->irq_delivery_mode != dest_LowestPrio) ?
+				HT_IRQ_LOW_MT_FIXED :
+				HT_IRQ_LOW_MT_ARBITRATED) |
+			HT_IRQ_LOW_IRQ_MASKED;
+
+		write_ht_irq_msg(irq, &msg);
+
+		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
+					      handle_edge_irq, "edge");
+
+		dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);
+	}
+	return err;
+}
+#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;
+
+	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;
+	BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+	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);
+
+	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;
+
+	mmr_value = 0;
+	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+	BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+	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;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_01.raw = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.bits.entries;
+}
+
+void __init probe_nr_irqs_gsi(void)
+{
+	int nr = 0;
+
+	nr = acpi_probe_gsi();
+	if (nr > nr_irqs_gsi) {
+		nr_irqs_gsi = nr;
+	} else {
+		/* for acpi=off or acpi is not compiled in */
+		int idx;
+
+		nr = 0;
+		for (idx = 0; idx < nr_ioapics; idx++)
+			nr += io_apic_get_redir_entries(idx) + 1;
+
+		if (nr > nr_irqs_gsi)
+			nr_irqs_gsi = nr;
+	}
+
+	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
+}
+
+#ifdef CONFIG_SPARSE_IRQ
+int __init arch_probe_nr_irqs(void)
+{
+	int nr;
+
+	if (nr_irqs > (NR_VECTORS * nr_cpu_ids))
+		nr_irqs = NR_VECTORS * nr_cpu_ids;
+
+	nr = nr_irqs_gsi + 8 * nr_cpu_ids;
+#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ)
+	/*
+	 * for MSI and HT dyn irq
+	 */
+	nr += nr_irqs_gsi * 16;
+#endif
+	if (nr < nr_irqs)
+		nr_irqs = nr;
+
+	return 0;
+}
+#endif
+
+/* --------------------------------------------------------------------------
+                          ACPI-based IOAPIC Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI
+
+#ifdef CONFIG_X86_32
+int __init io_apic_get_unique_id(int ioapic, int apic_id)
+{
+	union IO_APIC_reg_00 reg_00;
+	static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
+	physid_mask_t tmp;
+	unsigned long flags;
+	int i = 0;
+
+	/*
+	 * The P4 platform supports up to 256 APIC IDs on two separate APIC
+	 * buses (one for LAPICs, one for IOAPICs), where predecessors only
+	 * supports up to 16 on one shared APIC bus.
+	 *
+	 * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
+	 *      advantage of new APIC bus architecture.
+	 */
+
+	if (physids_empty(apic_id_map))
+		apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map);
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_00.raw = io_apic_read(ioapic, 0);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	if (apic_id >= get_physical_broadcast()) {
+		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
+			"%d\n", ioapic, apic_id, reg_00.bits.ID);
+		apic_id = reg_00.bits.ID;
+	}
+
+	/*
+	 * 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)) {
+
+		for (i = 0; i < get_physical_broadcast(); i++) {
+			if (!apic->check_apicid_used(apic_id_map, i))
+				break;
+		}
+
+		if (i == get_physical_broadcast())
+			panic("Max apic_id exceeded!\n");
+
+		printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
+			"trying %d\n", ioapic, apic_id, i);
+
+		apic_id = i;
+	}
+
+	tmp = apic->apicid_to_cpu_present(apic_id);
+	physids_or(apic_id_map, apic_id_map, tmp);
+
+	if (reg_00.bits.ID != apic_id) {
+		reg_00.bits.ID = apic_id;
+
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(ioapic, 0, reg_00.raw);
+		reg_00.raw = io_apic_read(ioapic, 0);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+
+		/* Sanity check */
+		if (reg_00.bits.ID != apic_id) {
+			printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
+			return -1;
+		}
+	}
+
+	apic_printk(APIC_VERBOSE, KERN_INFO
+			"IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+
+	return apic_id;
+}
+
+int __init io_apic_get_version(int ioapic)
+{
+	union IO_APIC_reg_01	reg_01;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_01.raw = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.bits.version;
+}
+#endif
+
+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
+{
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
+	int cpu = boot_cpu_id;
+
+	if (!IO_APIC_IRQ(irq)) {
+		apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
+			ioapic);
+		return -EINVAL;
+	}
+
+	desc = irq_to_desc_alloc_cpu(irq, cpu);
+	if (!desc) {
+		printk(KERN_INFO "can not get irq_desc %d\n", irq);
+		return 0;
+	}
+
+	/*
+	 * IRQs < 16 are already in the irq_2_pin[] map
+	 */
+	if (irq >= NR_IRQS_LEGACY) {
+		cfg = desc->chip_data;
+		add_pin_to_irq_cpu(cfg, cpu, ioapic, pin);
+	}
+
+	setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
+
+	return 0;
+}
+
+
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+{
+	int i;
+
+	if (skip_ioapic_setup)
+		return -1;
+
+	for (i = 0; i < mp_irq_entries; i++)
+		if (mp_irqs[i].irqtype == mp_INT &&
+		    mp_irqs[i].srcbusirq == bus_irq)
+			break;
+	if (i >= mp_irq_entries)
+		return -1;
+
+	*trigger = irq_trigger(i);
+	*polarity = irq_polarity(i);
+	return 0;
+}
+
+#endif /* CONFIG_ACPI */
+
+/*
+ * This function currently is only a helper for the i386 smp boot process where
+ * we need to reprogram the ioredtbls to cater for the cpus which have come online
+ * so mask in all cases should simply be apic->target_cpus()
+ */
+#ifdef CONFIG_SMP
+void __init setup_ioapic_dest(void)
+{
+	int pin, ioapic, irq, irq_entry;
+	struct irq_desc *desc;
+	struct irq_cfg *cfg;
+	const struct cpumask *mask;
+
+	if (skip_ioapic_setup == 1)
+		return;
+
+	for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
+		for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+			irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+			if (irq_entry == -1)
+				continue;
+			irq = pin_2_irq(irq_entry, ioapic, pin);
+
+			/* setup_IO_APIC_irqs could fail to get vector for some device
+			 * when you have too many devices, because at that time only boot
+			 * cpu is online.
+			 */
+			desc = irq_to_desc(irq);
+			cfg = desc->chip_data;
+			if (!cfg->vector) {
+				setup_IO_APIC_irq(ioapic, pin, irq, desc,
+						  irq_trigger(irq_entry),
+						  irq_polarity(irq_entry));
+				continue;
+
+			}
+
+			/*
+			 * Honour affinities which have been set in early boot
+			 */
+			if (desc->status &
+			    (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+				mask = desc->affinity;
+			else
+				mask = apic->target_cpus();
+
+			if (intr_remapping_enabled)
+				set_ir_ioapic_affinity_irq_desc(desc, mask);
+			else
+				set_ioapic_affinity_irq_desc(desc, mask);
+		}
+
+	}
+}
+#endif
+
+#define IOAPIC_RESOURCE_NAME_SIZE 11
+
+static struct resource *ioapic_resources;
+
+static struct resource * __init ioapic_setup_resources(void)
+{
+	unsigned long n;
+	struct resource *res;
+	char *mem;
+	int i;
+
+	if (nr_ioapics <= 0)
+		return NULL;
+
+	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
+	n *= nr_ioapics;
+
+	mem = alloc_bootmem(n);
+	res = (void *)mem;
+
+	if (mem != NULL) {
+		mem += sizeof(struct resource) * nr_ioapics;
+
+		for (i = 0; i < nr_ioapics; i++) {
+			res[i].name = mem;
+			res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+			sprintf(mem,  "IOAPIC %u", i);
+			mem += IOAPIC_RESOURCE_NAME_SIZE;
+		}
+	}
+
+	ioapic_resources = res;
+
+	return res;
+}
+
+void __init ioapic_init_mappings(void)
+{
+	unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
+	struct resource *ioapic_res;
+	int i;
+
+	ioapic_res = ioapic_setup_resources();
+	for (i = 0; i < nr_ioapics; i++) {
+		if (smp_found_config) {
+			ioapic_phys = mp_ioapics[i].apicaddr;
+#ifdef CONFIG_X86_32
+			if (!ioapic_phys) {
+				printk(KERN_ERR
+				       "WARNING: bogus zero IO-APIC "
+				       "address found in MPTABLE, "
+				       "disabling IO/APIC support!\n");
+				smp_found_config = 0;
+				skip_ioapic_setup = 1;
+				goto fake_ioapic_page;
+			}
+#endif
+		} else {
+#ifdef CONFIG_X86_32
+fake_ioapic_page:
+#endif
+			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);
+		idx++;
+
+		if (ioapic_res != NULL) {
+			ioapic_res->start = ioapic_phys;
+			ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
+			ioapic_res++;
+		}
+	}
+}
+
+static int __init ioapic_insert_resources(void)
+{
+	int i;
+	struct resource *r = ioapic_resources;
+
+	if (!r) {
+		if (nr_ioapics > 0) {
+			printk(KERN_ERR
+				"IO APIC resources couldn't be allocated.\n");
+			return -1;
+		}
+		return 0;
+	}
+
+	for (i = 0; i < nr_ioapics; i++) {
+		insert_resource(&iomem_resource, r);
+		r++;
+	}
+
+	return 0;
+}
+
+/* Insert the IO APIC resources after PCI initialization has occured to handle
+ * IO APICS that are mapped in on a BAR in PCI space. */
+late_initcall(ioapic_insert_resources);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/ipi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/ipi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/ipi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/ipi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,164 @@
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+#include <linux/cache.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+
+#include <asm/smp.h>
+#include <asm/mtrr.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/apic.h>
+#include <asm/proto.h>
+#include <asm/ipi.h>
+
+void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector)
+{
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	/*
+	 * Hack. The clustered APIC addressing mode doesn't allow us to send
+	 * to an arbitrary mask, so I do a unicast to each CPU instead.
+	 * - mbligh
+	 */
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		__default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid,
+				query_cpu), vector, APIC_DEST_PHYSICAL);
+	}
+	local_irq_restore(flags);
+}
+
+void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
+						 int vector)
+{
+	unsigned int this_cpu = smp_processor_id();
+	unsigned int query_cpu;
+	unsigned long flags;
+
+	/* See Hack comment above */
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		if (query_cpu == this_cpu)
+			continue;
+		__default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid,
+				 query_cpu), vector, APIC_DEST_PHYSICAL);
+	}
+	local_irq_restore(flags);
+}
+
+void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
+						 int vector)
+{
+	unsigned long flags;
+	unsigned int query_cpu;
+
+	/*
+	 * Hack. The clustered APIC addressing mode doesn't allow us to send
+	 * to an arbitrary mask, so I do a unicasts to each CPU instead. This
+	 * should be modified to do 1 message per cluster ID - mbligh
+	 */
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask)
+		__default_send_IPI_dest_field(
+			apic->cpu_to_logical_apicid(query_cpu), vector,
+			apic->dest_logical);
+	local_irq_restore(flags);
+}
+
+void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
+						 int vector)
+{
+	unsigned long flags;
+	unsigned int query_cpu;
+	unsigned int this_cpu = smp_processor_id();
+
+	/* See Hack comment above */
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		if (query_cpu == this_cpu)
+			continue;
+		__default_send_IPI_dest_field(
+			apic->cpu_to_logical_apicid(query_cpu), vector,
+			apic->dest_logical);
+		}
+	local_irq_restore(flags);
+}
+
+#ifdef CONFIG_X86_32
+
+/*
+ * This is only used on smaller machines.
+ */
+void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector)
+{
+	unsigned long mask = cpumask_bits(cpumask)[0];
+	unsigned long flags;
+
+	local_irq_save(flags);
+	WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]);
+	__default_send_IPI_dest_field(mask, vector, apic->dest_logical);
+	local_irq_restore(flags);
+}
+
+void default_send_IPI_allbutself(int vector)
+{
+	/*
+	 * if there are no other CPUs in the system then we get an APIC send
+	 * error if we try to broadcast, thus avoid sending IPIs in this case.
+	 */
+	if (!(num_online_cpus() > 1))
+		return;
+
+	__default_local_send_IPI_allbutself(vector);
+}
+
+void default_send_IPI_all(int vector)
+{
+	__default_local_send_IPI_all(vector);
+}
+
+void default_send_IPI_self(int vector)
+{
+	__default_send_IPI_shortcut(APIC_DEST_SELF, vector, apic->dest_logical);
+}
+
+/* must come after the send_IPI functions above for inlining */
+static int convert_apicid_to_cpu(int apic_id)
+{
+	int i;
+
+	for_each_possible_cpu(i) {
+		if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
+			return i;
+	}
+	return -1;
+}
+
+int safe_smp_processor_id(void)
+{
+	int apicid, cpuid;
+
+	if (!boot_cpu_has(X86_FEATURE_APIC))
+		return 0;
+
+	apicid = hard_smp_processor_id();
+	if (apicid == BAD_APICID)
+		return 0;
+
+	cpuid = convert_apicid_to_cpu(apicid);
+
+	return cpuid >= 0 ? cpuid : 0;
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,19 @@
+#
+# 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_IO_APIC)	+= io_apic.o
+obj-$(CONFIG_SMP)		+= ipi.o
+
+ifeq ($(CONFIG_X86_64),y)
+obj-y				+= apic_flat_64.o
+obj-$(CONFIG_X86_X2APIC)	+= x2apic_cluster.o
+obj-$(CONFIG_X86_X2APIC)	+= x2apic_phys.o
+obj-$(CONFIG_X86_UV)		+= x2apic_uv_x.o
+endif
+
+obj-$(CONFIG_X86_BIGSMP)	+= bigsmp_32.o
+obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
+obj-$(CONFIG_X86_ES7000)	+= es7000_32.o
+obj-$(CONFIG_X86_SUMMIT)	+= summit_32.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/nmi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/nmi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/nmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/nmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,566 @@
+/*
+ *  NMI watchdog support on APIC systems
+ *
+ *  Started by Ingo Molnar <mingo@redhat.com>
+ *
+ *  Fixes:
+ *  Mikael Pettersson	: AMD K7 support for local APIC NMI watchdog.
+ *  Mikael Pettersson	: Power Management for local APIC NMI watchdog.
+ *  Mikael Pettersson	: Pentium 4 support for local APIC NMI watchdog.
+ *  Pavel Machek and
+ *  Mikael Pettersson	: PM converted to driver model. Disable/enable API.
+ */
+
+#include <asm/apic.h>
+
+#include <linux/nmi.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/sysctl.h>
+#include <linux/percpu.h>
+#include <linux/kprobes.h>
+#include <linux/cpumask.h>
+#include <linux/kernel_stat.h>
+#include <linux/kdebug.h>
+#include <linux/smp.h>
+
+#include <asm/i8259.h>
+#include <asm/io_apic.h>
+#include <asm/proto.h>
+#include <asm/timer.h>
+
+#include <asm/mce.h>
+
+#include <asm/mach_traps.h>
+
+int unknown_nmi_panic;
+int nmi_watchdog_enabled;
+
+static cpumask_var_t backtrace_mask;
+
+/* nmi_active:
+ * >0: the lapic NMI watchdog is active, but can be disabled
+ * <0: the lapic NMI watchdog has not been set up, and cannot
+ *     be enabled
+ *  0: the lapic NMI watchdog is disabled, but can be enabled
+ */
+atomic_t nmi_active = ATOMIC_INIT(0);		/* oprofile uses this */
+EXPORT_SYMBOL(nmi_active);
+
+unsigned int nmi_watchdog = NMI_NONE;
+EXPORT_SYMBOL(nmi_watchdog);
+
+static int panic_on_timeout;
+
+static unsigned int nmi_hz = HZ;
+static DEFINE_PER_CPU(short, wd_enabled);
+static int endflag __initdata;
+
+static inline unsigned int get_nmi_count(int cpu)
+{
+	return per_cpu(irq_stat, cpu).__nmi_count;
+}
+
+static inline int mce_in_progress(void)
+{
+#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
+	return atomic_read(&mce_entry) > 0;
+#endif
+	return 0;
+}
+
+/*
+ * Take the local apic timer and PIT/HPET into account. We don't
+ * know which one is active, when we have highres/dyntick on
+ */
+static inline unsigned int get_timer_irqs(int cpu)
+{
+	return per_cpu(irq_stat, cpu).apic_timer_irqs +
+		per_cpu(irq_stat, cpu).irq0_irqs;
+}
+
+#ifdef CONFIG_SMP
+/*
+ * The performance counters used by NMI_LOCAL_APIC don't trigger when
+ * the CPU is idle. To make sure the NMI watchdog really ticks on all
+ * CPUs during the test make them busy.
+ */
+static __init void nmi_cpu_busy(void *data)
+{
+	local_irq_enable_in_hardirq();
+	/*
+	 * Intentionally don't use cpu_relax here. This is
+	 * to make sure that the performance counter really ticks,
+	 * even if there is a simulator or similar that catches the
+	 * pause instruction. On a real HT machine this is fine because
+	 * all other CPUs are busy with "useless" delay loops and don't
+	 * care if they get somewhat less cycles.
+	 */
+	while (endflag == 0)
+		mb();
+}
+#endif
+
+static void report_broken_nmi(int cpu, int *prev_nmi_count)
+{
+	printk(KERN_CONT "\n");
+
+	printk(KERN_WARNING
+		"WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
+			cpu, prev_nmi_count[cpu], get_nmi_count(cpu));
+
+	printk(KERN_WARNING
+		"Please report this to bugzilla.kernel.org,\n");
+	printk(KERN_WARNING
+		"and attach the output of the 'dmesg' command.\n");
+
+	per_cpu(wd_enabled, cpu) = 0;
+	atomic_dec(&nmi_active);
+}
+
+static void __acpi_nmi_disable(void *__unused)
+{
+	apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
+}
+
+int __init check_nmi_watchdog(void)
+{
+	unsigned int *prev_nmi_count;
+	int cpu;
+
+	if (!nmi_watchdog_active() || !atomic_read(&nmi_active))
+		return 0;
+
+	prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL);
+	if (!prev_nmi_count)
+		goto error;
+
+	alloc_cpumask_var(&backtrace_mask, GFP_KERNEL|__GFP_ZERO);
+	printk(KERN_INFO "Testing NMI watchdog ... ");
+
+#ifdef CONFIG_SMP
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		smp_call_function(nmi_cpu_busy, (void *)&endflag, 0);
+#endif
+
+	for_each_possible_cpu(cpu)
+		prev_nmi_count[cpu] = get_nmi_count(cpu);
+	local_irq_enable();
+	mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
+
+	for_each_online_cpu(cpu) {
+		if (!per_cpu(wd_enabled, cpu))
+			continue;
+		if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
+			report_broken_nmi(cpu, prev_nmi_count);
+	}
+	endflag = 1;
+	if (!atomic_read(&nmi_active)) {
+		kfree(prev_nmi_count);
+		atomic_set(&nmi_active, -1);
+		goto error;
+	}
+	printk("OK.\n");
+
+	/*
+	 * now that we know it works we can reduce NMI frequency to
+	 * something more reasonable; makes a difference in some configs
+	 */
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		nmi_hz = lapic_adjust_nmi_hz(1);
+
+	kfree(prev_nmi_count);
+	return 0;
+error:
+	if (nmi_watchdog == NMI_IO_APIC) {
+		if (!timer_through_8259)
+			disable_8259A_irq(0);
+		on_each_cpu(__acpi_nmi_disable, NULL, 1);
+	}
+
+#ifdef CONFIG_X86_32
+	timer_ack = 0;
+#endif
+	return -1;
+}
+
+static int __init setup_nmi_watchdog(char *str)
+{
+	unsigned int nmi;
+
+	if (!strncmp(str, "panic", 5)) {
+		panic_on_timeout = 1;
+		str = strchr(str, ',');
+		if (!str)
+			return 1;
+		++str;
+	}
+
+	if (!strncmp(str, "lapic", 5))
+		nmi_watchdog = NMI_LOCAL_APIC;
+	else if (!strncmp(str, "ioapic", 6))
+		nmi_watchdog = NMI_IO_APIC;
+	else {
+		get_option(&str, &nmi);
+		if (nmi >= NMI_INVALID)
+			return 0;
+		nmi_watchdog = nmi;
+	}
+
+	return 1;
+}
+__setup("nmi_watchdog=", setup_nmi_watchdog);
+
+/*
+ * Suspend/resume support
+ */
+#ifdef CONFIG_PM
+
+static int nmi_pm_active; /* nmi_active before suspend */
+
+static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
+{
+	/* only CPU0 goes here, other CPUs should be offline */
+	nmi_pm_active = atomic_read(&nmi_active);
+	stop_apic_nmi_watchdog(NULL);
+	BUG_ON(atomic_read(&nmi_active) != 0);
+	return 0;
+}
+
+static int lapic_nmi_resume(struct sys_device *dev)
+{
+	/* only CPU0 goes here, other CPUs should be offline */
+	if (nmi_pm_active > 0) {
+		setup_apic_nmi_watchdog(NULL);
+		touch_nmi_watchdog();
+	}
+	return 0;
+}
+
+static struct sysdev_class nmi_sysclass = {
+	.name		= "lapic_nmi",
+	.resume		= lapic_nmi_resume,
+	.suspend	= lapic_nmi_suspend,
+};
+
+static struct sys_device device_lapic_nmi = {
+	.id	= 0,
+	.cls	= &nmi_sysclass,
+};
+
+static int __init init_lapic_nmi_sysfs(void)
+{
+	int error;
+
+	/*
+	 * should really be a BUG_ON but b/c this is an
+	 * init call, it just doesn't work.  -dcz
+	 */
+	if (nmi_watchdog != NMI_LOCAL_APIC)
+		return 0;
+
+	if (atomic_read(&nmi_active) < 0)
+		return 0;
+
+	error = sysdev_class_register(&nmi_sysclass);
+	if (!error)
+		error = sysdev_register(&device_lapic_nmi);
+	return error;
+}
+
+/* must come after the local APIC's device_initcall() */
+late_initcall(init_lapic_nmi_sysfs);
+
+#endif	/* CONFIG_PM */
+
+static void __acpi_nmi_enable(void *__unused)
+{
+	apic_write(APIC_LVT0, APIC_DM_NMI);
+}
+
+/*
+ * Enable timer based NMIs on all CPUs:
+ */
+void acpi_nmi_enable(void)
+{
+	if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
+		on_each_cpu(__acpi_nmi_enable, NULL, 1);
+}
+
+/*
+ * Disable timer based NMIs on all CPUs:
+ */
+void acpi_nmi_disable(void)
+{
+	if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
+		on_each_cpu(__acpi_nmi_disable, NULL, 1);
+}
+
+/*
+ * This function is called as soon the LAPIC NMI watchdog driver has everything
+ * in place and it's ready to check if the NMIs belong to the NMI watchdog
+ */
+void cpu_nmi_set_wd_enabled(void)
+{
+	__get_cpu_var(wd_enabled) = 1;
+}
+
+void setup_apic_nmi_watchdog(void *unused)
+{
+	if (__get_cpu_var(wd_enabled))
+		return;
+
+	/* cheap hack to support suspend/resume */
+	/* if cpu0 is not active neither should the other cpus */
+	if (smp_processor_id() != 0 && atomic_read(&nmi_active) <= 0)
+		return;
+
+	switch (nmi_watchdog) {
+	case NMI_LOCAL_APIC:
+		if (lapic_watchdog_init(nmi_hz) < 0) {
+			__get_cpu_var(wd_enabled) = 0;
+			return;
+		}
+		/* FALL THROUGH */
+	case NMI_IO_APIC:
+		__get_cpu_var(wd_enabled) = 1;
+		atomic_inc(&nmi_active);
+	}
+}
+
+void stop_apic_nmi_watchdog(void *unused)
+{
+	/* only support LOCAL and IO APICs for now */
+	if (!nmi_watchdog_active())
+		return;
+	if (__get_cpu_var(wd_enabled) == 0)
+		return;
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		lapic_watchdog_stop();
+	else
+		__acpi_nmi_disable(NULL);
+	__get_cpu_var(wd_enabled) = 0;
+	atomic_dec(&nmi_active);
+}
+
+/*
+ * the best way to detect whether a CPU has a 'hard lockup' problem
+ * is to check it's local APIC timer IRQ counts. If they are not
+ * changing then that CPU has some problem.
+ *
+ * as these watchdog NMI IRQs are generated on every CPU, we only
+ * have to check the current processor.
+ *
+ * since NMIs don't listen to _any_ locks, we have to be extremely
+ * careful not to rely on unsafe variables. The printk might lock
+ * up though, so we have to break up any console locks first ...
+ * [when there will be more tty-related locks, break them up here too!]
+ */
+
+static DEFINE_PER_CPU(unsigned, last_irq_sum);
+static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(int, nmi_touch);
+
+void touch_nmi_watchdog(void)
+{
+	if (nmi_watchdog_active()) {
+		unsigned cpu;
+
+		/*
+		 * Tell other CPUs to reset their alert counters. We cannot
+		 * do it ourselves because the alert count increase is not
+		 * atomic.
+		 */
+		for_each_present_cpu(cpu) {
+			if (per_cpu(nmi_touch, cpu) != 1)
+				per_cpu(nmi_touch, cpu) = 1;
+		}
+	}
+
+	/*
+	 * Tickle the softlockup detector too:
+	 */
+	touch_softlockup_watchdog();
+}
+EXPORT_SYMBOL(touch_nmi_watchdog);
+
+notrace __kprobes int
+nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
+{
+	/*
+	 * Since current_thread_info()-> is always on the stack, and we
+	 * always switch the stack NMI-atomically, it's safe to use
+	 * smp_processor_id().
+	 */
+	unsigned int sum;
+	int touched = 0;
+	int cpu = smp_processor_id();
+	int rc = 0;
+
+	/* check for other users first */
+	if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
+			== NOTIFY_STOP) {
+		rc = 1;
+		touched = 1;
+	}
+
+	sum = get_timer_irqs(cpu);
+
+	if (__get_cpu_var(nmi_touch)) {
+		__get_cpu_var(nmi_touch) = 0;
+		touched = 1;
+	}
+
+	/* We can be called before check_nmi_watchdog, hence NULL check. */
+	if (backtrace_mask != NULL && cpumask_test_cpu(cpu, backtrace_mask)) {
+		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */
+
+		spin_lock(&lock);
+		printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
+		dump_stack();
+		spin_unlock(&lock);
+		cpumask_clear_cpu(cpu, backtrace_mask);
+	}
+
+	/* Could check oops_in_progress here too, but it's safer not to */
+	if (mce_in_progress())
+		touched = 1;
+
+	/* if the none of the timers isn't firing, this cpu isn't doing much */
+	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
+		/*
+		 * 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)
+			/*
+			 * die_nmi will return ONLY if NOTIFY_STOP happens..
+			 */
+			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);
+	}
+
+	/* see if the nmi watchdog went off */
+	if (!__get_cpu_var(wd_enabled))
+		return rc;
+	switch (nmi_watchdog) {
+	case NMI_LOCAL_APIC:
+		rc |= lapic_wd_event(nmi_hz);
+		break;
+	case NMI_IO_APIC:
+		/*
+		 * don't know how to accurately check for this.
+		 * just assume it was a watchdog timer interrupt
+		 * This matches the old behaviour.
+		 */
+		rc = 1;
+		break;
+	}
+	return rc;
+}
+
+#ifdef CONFIG_SYSCTL
+
+static void enable_ioapic_nmi_watchdog_single(void *unused)
+{
+	__get_cpu_var(wd_enabled) = 1;
+	atomic_inc(&nmi_active);
+	__acpi_nmi_enable(NULL);
+}
+
+static void enable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 1);
+	touch_nmi_watchdog();
+}
+
+static void disable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(stop_apic_nmi_watchdog, NULL, 1);
+}
+
+static int __init setup_unknown_nmi_panic(char *str)
+{
+	unknown_nmi_panic = 1;
+	return 1;
+}
+__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
+
+static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
+{
+	unsigned char reason = get_nmi_reason();
+	char buf[64];
+
+	sprintf(buf, "NMI received for unknown reason %02x\n", reason);
+	die_nmi(buf, regs, 1); /* Always panic here */
+	return 0;
+}
+
+/*
+ * proc handler for /proc/sys/kernel/nmi
+ */
+int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
+			void __user *buffer, size_t *length, loff_t *ppos)
+{
+	int old_state;
+
+	nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0;
+	old_state = nmi_watchdog_enabled;
+	proc_dointvec(table, write, file, buffer, length, ppos);
+	if (!!old_state == !!nmi_watchdog_enabled)
+		return 0;
+
+	if (atomic_read(&nmi_active) < 0 || !nmi_watchdog_active()) {
+		printk(KERN_WARNING
+			"NMI watchdog is permanently disabled\n");
+		return -EIO;
+	}
+
+	if (nmi_watchdog == NMI_LOCAL_APIC) {
+		if (nmi_watchdog_enabled)
+			enable_lapic_nmi_watchdog();
+		else
+			disable_lapic_nmi_watchdog();
+	} else if (nmi_watchdog == NMI_IO_APIC) {
+		if (nmi_watchdog_enabled)
+			enable_ioapic_nmi_watchdog();
+		else
+			disable_ioapic_nmi_watchdog();
+	} else {
+		printk(KERN_WARNING
+			"NMI watchdog doesn't know what hardware to touch\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+#endif /* CONFIG_SYSCTL */
+
+int do_nmi_callback(struct pt_regs *regs, int cpu)
+{
+#ifdef CONFIG_SYSCTL
+	if (unknown_nmi_panic)
+		return unknown_nmi_panic_callback(regs, cpu);
+#endif
+	return 0;
+}
+
+void __trigger_all_cpu_backtrace(void)
+{
+	int i;
+
+	cpumask_copy(backtrace_mask, cpu_online_mask);
+	/* 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))
+			break;
+		mdelay(1);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/numaq_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/numaq_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/numaq_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/numaq_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,558 @@
+/*
+ * Written by: Patricia Gaughen, IBM Corporation
+ *
+ * Copyright (C) 2002, IBM Corp.
+ * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gone@us.ibm.com>
+ */
+#include <linux/nodemask.h>
+#include <linux/topology.h>
+#include <linux/bootmem.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/numa.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/numaq.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/e820.h>
+#include <asm/ipi.h>
+
+#define	MB_TO_PAGES(addr)		((addr) << (20 - PAGE_SHIFT))
+
+int found_numaq;
+
+/*
+ * Have to match translation table entries to main table entries by counter
+ * hence the mpc_record variable .... can't see a less disgusting way of
+ * doing this ....
+ */
+struct mpc_trans {
+	unsigned char			mpc_type;
+	unsigned char			trans_len;
+	unsigned char			trans_type;
+	unsigned char			trans_quad;
+	unsigned char			trans_global;
+	unsigned char			trans_local;
+	unsigned short			trans_reserved;
+};
+
+/* x86_quirks member */
+static int				mpc_record;
+
+static struct mpc_trans			*translation_table[MAX_MPC_ENTRY];
+
+int					mp_bus_id_to_node[MAX_MP_BUSSES];
+int					mp_bus_id_to_local[MAX_MP_BUSSES];
+int					quad_local_to_mp_bus_id[NR_CPUS/4][4];
+
+
+static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
+{
+	struct eachquadmem *eq = scd->eq + node;
+
+	node_set_online(node);
+
+	/* Convert to pages */
+	node_start_pfn[node] =
+		 MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size);
+
+	node_end_pfn[node] =
+		 MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
+
+	e820_register_active_regions(node, node_start_pfn[node],
+						node_end_pfn[node]);
+
+	memory_present(node, node_start_pfn[node], node_end_pfn[node]);
+
+	node_remap_size[node] = node_memmap_size_bytes(node,
+					node_start_pfn[node],
+					node_end_pfn[node]);
+}
+
+/*
+ * Function: smp_dump_qct()
+ *
+ * Description: gets memory layout from the quad config table.  This
+ * function also updates node_online_map with the nodes (quads) present.
+ */
+static void __init smp_dump_qct(void)
+{
+	struct sys_cfg_data *scd;
+	int node;
+
+	scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
+
+	nodes_clear(node_online_map);
+	for_each_node(node) {
+		if (scd->quads_present31_0 & (1 << node))
+			numaq_register_node(node, scd);
+	}
+}
+
+void __cpuinit numaq_tsc_disable(void)
+{
+	if (!found_numaq)
+		return;
+
+	if (num_online_nodes() > 1) {
+		printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
+		setup_clear_cpu_cap(X86_FEATURE_TSC);
+	}
+}
+
+static int __init numaq_pre_time_init(void)
+{
+	numaq_tsc_disable();
+	return 0;
+}
+
+static inline int generate_logical_apicid(int quad, int phys_apicid)
+{
+	return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
+}
+
+/* x86_quirks member */
+static int mpc_apic_id(struct mpc_cpu *m)
+{
+	int quad = translation_table[mpc_record]->trans_quad;
+	int logical_apicid = generate_logical_apicid(quad, m->apicid);
+
+	printk(KERN_DEBUG
+		"Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
+		 m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
+		(m->cpufeature & CPU_MODEL_MASK) >> 4,
+		 m->apicver, quad, logical_apicid);
+
+	return logical_apicid;
+}
+
+/* x86_quirks member */
+static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
+{
+	int quad = translation_table[mpc_record]->trans_quad;
+	int local = translation_table[mpc_record]->trans_local;
+
+	mp_bus_id_to_node[m->busid] = quad;
+	mp_bus_id_to_local[m->busid] = local;
+
+	printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
+}
+
+/* x86_quirks member */
+static void mpc_oem_pci_bus(struct mpc_bus *m)
+{
+	int quad = translation_table[mpc_record]->trans_quad;
+	int local = translation_table[mpc_record]->trans_local;
+
+	quad_local_to_mp_bus_id[quad][local] = m->busid;
+}
+
+static void __init MP_translation_info(struct mpc_trans *m)
+{
+	printk(KERN_INFO
+	    "Translation: record %d, type %d, quad %d, global %d, local %d\n",
+	       mpc_record, m->trans_type, m->trans_quad, m->trans_global,
+	       m->trans_local);
+
+	if (mpc_record >= MAX_MPC_ENTRY)
+		printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
+	else
+		translation_table[mpc_record] = m; /* stash this for later */
+
+	if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
+		node_set_online(m->trans_quad);
+}
+
+static int __init mpf_checksum(unsigned char *mp, int len)
+{
+	int sum = 0;
+
+	while (len--)
+		sum += *mp++;
+
+	return sum & 0xFF;
+}
+
+/*
+ * Read/parse the MPC oem tables
+ */
+static void __init
+ smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
+{
+	int count = sizeof(*oemtable);	/* the header size */
+	unsigned char *oemptr = ((unsigned char *)oemtable) + count;
+
+	mpc_record = 0;
+	printk(KERN_INFO
+		"Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
+
+	if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
+		printk(KERN_WARNING
+		       "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
+		       oemtable->signature[0], oemtable->signature[1],
+		       oemtable->signature[2], oemtable->signature[3]);
+		return;
+	}
+
+	if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
+		printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
+		return;
+	}
+
+	while (count < oemtable->length) {
+		switch (*oemptr) {
+		case MP_TRANSLATION:
+			{
+				struct mpc_trans *m = (void *)oemptr;
+
+				MP_translation_info(m);
+				oemptr += sizeof(*m);
+				count += sizeof(*m);
+				++mpc_record;
+				break;
+			}
+		default:
+			printk(KERN_WARNING
+			       "Unrecognised OEM table entry type! - %d\n",
+			       (int)*oemptr);
+			return;
+		}
+	}
+}
+
+static int __init numaq_setup_ioapic_ids(void)
+{
+	/* so can skip it */
+	return 1;
+}
+
+static struct x86_quirks numaq_x86_quirks __initdata = {
+	.arch_pre_time_init		= numaq_pre_time_init,
+	.arch_time_init			= NULL,
+	.arch_pre_intr_init		= NULL,
+	.arch_memory_setup		= NULL,
+	.arch_intr_init			= NULL,
+	.arch_trap_init			= NULL,
+	.mach_get_smp_config		= NULL,
+	.mach_find_smp_config		= NULL,
+	.mpc_record			= &mpc_record,
+	.mpc_apic_id			= mpc_apic_id,
+	.mpc_oem_bus_info		= mpc_oem_bus_info,
+	.mpc_oem_pci_bus		= mpc_oem_pci_bus,
+	.smp_read_mpc_oem		= smp_read_mpc_oem,
+	.setup_ioapic_ids		= numaq_setup_ioapic_ids,
+};
+
+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)
+		early_get_smp_config();
+
+	if (found_numaq)
+		x86_quirks = &numaq_x86_quirks;
+}
+
+int __init get_memcfg_numaq(void)
+{
+	early_check_numaq();
+	if (!found_numaq)
+		return 0;
+	smp_dump_qct();
+
+	return 1;
+}
+
+#define NUMAQ_APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
+
+static inline unsigned int numaq_get_apic_id(unsigned long x)
+{
+	return (x >> 24) & 0x0F;
+}
+
+static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	default_send_IPI_mask_sequence_logical(mask, vector);
+}
+
+static inline void numaq_send_IPI_allbutself(int vector)
+{
+	default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
+}
+
+static inline void numaq_send_IPI_all(int vector)
+{
+	numaq_send_IPI_mask(cpu_online_mask, vector);
+}
+
+#define NUMAQ_TRAMPOLINE_PHYS_LOW	(0x8)
+#define NUMAQ_TRAMPOLINE_PHYS_HIGH	(0xa)
+
+/*
+ * Because we use NMIs rather than the INIT-STARTUP sequence to
+ * bootstrap the CPUs, the APIC may be in a weird state. Kick it:
+ */
+static inline void numaq_smp_callin_clear_local_apic(void)
+{
+	clear_local_APIC();
+}
+
+static inline const struct cpumask *numaq_target_cpus(void)
+{
+	return cpu_all_mask;
+}
+
+static inline unsigned long
+numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+	return physid_isset(apicid, bitmap);
+}
+
+static inline unsigned long numaq_check_apicid_present(int bit)
+{
+	return physid_isset(bit, phys_cpu_present_map);
+}
+
+static inline int numaq_apic_id_registered(void)
+{
+	return 1;
+}
+
+static inline void numaq_init_apic_ldr(void)
+{
+	/* Already done in NUMA-Q firmware */
+}
+
+static inline void numaq_setup_apic_routing(void)
+{
+	printk(KERN_INFO
+		"Enabling APIC mode:  NUMA-Q.  Using %d I/O APICs\n",
+		nr_ioapics);
+}
+
+/*
+ * Skip adding the timer int on secondary nodes, which causes
+ * a small but painful rift in the time-space continuum.
+ */
+static inline int numaq_multi_timer_check(int apic, int irq)
+{
+	return apic != 0 && irq == 0;
+}
+
+static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+	/* We don't have a good way to do this yet - hack */
+	return physids_promote(0xFUL);
+}
+
+static inline int numaq_cpu_to_logical_apicid(int cpu)
+{
+	if (cpu >= nr_cpu_ids)
+		return BAD_APICID;
+	return cpu_2_logical_apicid[cpu];
+}
+
+/*
+ * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
+ * cpu to APIC ID relation to properly interact with the intelligent
+ * mode of the cluster controller.
+ */
+static inline int numaq_cpu_present_to_apicid(int mps_cpu)
+{
+	if (mps_cpu < 60)
+		return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
+	else
+		return BAD_APICID;
+}
+
+static inline int numaq_apicid_to_node(int logical_apicid)
+{
+	return logical_apicid >> 4;
+}
+
+static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
+{
+	int node = numaq_apicid_to_node(logical_apicid);
+	int cpu = __ffs(logical_apicid & 0xf);
+
+	return physid_mask_of_physid(cpu + 4*node);
+}
+
+/* Where the IO area was mapped on multiquad, always 0 otherwise */
+void *xquad_portio;
+
+static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return 1;
+}
+
+/*
+ * We use physical apicids here, not logical, so just return the default
+ * physical broadcast to stop people from breaking us
+ */
+static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	return 0x0F;
+}
+
+static inline unsigned int
+numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			     const struct cpumask *andmask)
+{
+	return 0x0F;
+}
+
+/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
+static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
+static int
+numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+	if (strncmp(oem, "IBM NUMA", 8))
+		printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
+	else
+		found_numaq = 1;
+
+	return found_numaq;
+}
+
+static int probe_numaq(void)
+{
+	/* already know from get_memcfg_numaq() */
+	return found_numaq;
+}
+
+static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	/* Careful. Some cpus do not strictly honor the set of cpus
+	 * specified in the interrupt destination when using lowest
+	 * priority interrupt delivery mode.
+	 *
+	 * In particular there was a hyperthreading cpu observed to
+	 * deliver interrupts to the wrong hyperthread when only one
+	 * hyperthread was specified in the interrupt desitination.
+	 */
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
+
+static void numaq_setup_portio_remap(void)
+{
+	int num_quads = num_online_nodes();
+
+	if (num_quads <= 1)
+		return;
+
+	printk(KERN_INFO
+		"Remapping cross-quad port I/O for %d quads\n", num_quads);
+
+	xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
+
+	printk(KERN_INFO
+		"xquad_portio vaddr 0x%08lx, len %08lx\n",
+		(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
+}
+
+struct apic apic_numaq = {
+
+	.name				= "NUMAQ",
+	.probe				= probe_numaq,
+	.acpi_madt_oem_check		= NULL,
+	.apic_id_registered		= numaq_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	/* physical delivery on LOCAL quad: */
+	.irq_dest_mode			= 0,
+
+	.target_cpus			= numaq_target_cpus,
+	.disable_esr			= 1,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= numaq_check_apicid_used,
+	.check_apicid_present		= numaq_check_apicid_present,
+
+	.vector_allocation_domain	= numaq_vector_allocation_domain,
+	.init_apic_ldr			= numaq_init_apic_ldr,
+
+	.ioapic_phys_id_map		= numaq_ioapic_phys_id_map,
+	.setup_apic_routing		= numaq_setup_apic_routing,
+	.multi_timer_check		= numaq_multi_timer_check,
+	.apicid_to_node			= numaq_apicid_to_node,
+	.cpu_to_logical_apicid		= numaq_cpu_to_logical_apicid,
+	.cpu_present_to_apicid		= numaq_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= numaq_apicid_to_cpu_present,
+	.setup_portio_remap		= numaq_setup_portio_remap,
+	.check_phys_apicid_present	= numaq_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= numaq_phys_pkg_id,
+	.mps_oem_check			= numaq_mps_oem_check,
+
+	.get_apic_id			= numaq_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0x0F << 24,
+
+	.cpu_mask_to_apicid		= numaq_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= numaq_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= numaq_send_IPI_mask,
+	.send_IPI_mask_allbutself	= NULL,
+	.send_IPI_allbutself		= numaq_send_IPI_allbutself,
+	.send_IPI_all			= numaq_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.wakeup_secondary_cpu		= wakeup_secondary_cpu_via_nmi,
+	.trampoline_phys_low		= NUMAQ_TRAMPOLINE_PHYS_LOW,
+	.trampoline_phys_high		= NUMAQ_TRAMPOLINE_PHYS_HIGH,
+
+	/* We don't do anything here because we use NMI's to boot instead */
+	.wait_for_init_deassert		= NULL,
+
+	.smp_callin_clear_local_apic	= numaq_smp_callin_clear_local_apic,
+	.inquire_remote_apic		= NULL,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/probe_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/probe_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/probe_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/probe_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,285 @@
+/*
+ * Default generic APIC driver. This handles up to 8 CPUs.
+ *
+ * Copyright 2003 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic x86 APIC driver probe layer.
+ */
+#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/threads.h>
+#include <linux/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/ipi.h>
+
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/acpi.h>
+#include <asm/e820.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI	(1)
+#else
+#define DEFAULT_SEND_IPI	(0)
+#endif
+
+int no_broadcast = DEFAULT_SEND_IPI;
+
+static __init int no_ipi_broadcast(char *str)
+{
+	get_option(&str, &no_broadcast);
+	pr_info("Using %s mode\n",
+		no_broadcast ? "No IPI Broadcast" : "IPI Broadcast");
+	return 1;
+}
+__setup("no_ipi_broadcast=", no_ipi_broadcast);
+
+static int __init print_ipi_mode(void)
+{
+	pr_info("Using IPI %s mode\n",
+		no_broadcast ? "No-Shortcut" : "Shortcut");
+	return 0;
+}
+late_initcall(print_ipi_mode);
+
+void default_setup_apic_routing(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+	printk(KERN_INFO
+		"Enabling APIC mode:  Flat.  Using %d I/O APICs\n",
+		nr_ioapics);
+#endif
+}
+
+static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	/*
+	 * Careful. Some cpus do not strictly honor the set of cpus
+	 * specified in the interrupt destination when using lowest
+	 * priority interrupt delivery mode.
+	 *
+	 * In particular there was a hyperthreading cpu observed to
+	 * deliver interrupts to the wrong hyperthread when only one
+	 * hyperthread was specified in the interrupt desitination.
+	 */
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
+
+/* should be called last. */
+static int probe_default(void)
+{
+	return 1;
+}
+
+struct apic apic_default = {
+
+	.name				= "default",
+	.probe				= probe_default,
+	.acpi_madt_oem_check		= NULL,
+	.apic_id_registered		= default_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	/* logical delivery broadcast to all CPUs: */
+	.irq_dest_mode			= 1,
+
+	.target_cpus			= default_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= default_check_apicid_used,
+	.check_apicid_present		= default_check_apicid_present,
+
+	.vector_allocation_domain	= default_vector_allocation_domain,
+	.init_apic_ldr			= default_init_apic_ldr,
+
+	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
+	.setup_apic_routing		= default_setup_apic_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,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= default_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= default_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			= default_send_IPI_mask_logical,
+	.send_IPI_mask_allbutself	= default_send_IPI_mask_allbutself_logical,
+	.send_IPI_allbutself		= default_send_IPI_allbutself,
+	.send_IPI_all			= default_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW,
+	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+	.wait_for_init_deassert		= default_wait_for_init_deassert,
+
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
+
+extern struct apic apic_numaq;
+extern struct apic apic_summit;
+extern struct apic apic_bigsmp;
+extern struct apic apic_es7000;
+extern struct apic apic_es7000_cluster;
+extern struct apic apic_default;
+
+struct apic *apic = &apic_default;
+EXPORT_SYMBOL_GPL(apic);
+
+static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_X86_NUMAQ
+	&apic_numaq,
+#endif
+#ifdef CONFIG_X86_SUMMIT
+	&apic_summit,
+#endif
+#ifdef CONFIG_X86_BIGSMP
+	&apic_bigsmp,
+#endif
+#ifdef CONFIG_X86_ES7000
+	&apic_es7000,
+	&apic_es7000_cluster,
+#endif
+	&apic_default,	/* must be last */
+	NULL,
+};
+
+static int cmdline_apic __initdata;
+static int __init parse_apic(char *arg)
+{
+	int i;
+
+	if (!arg)
+		return -EINVAL;
+
+	for (i = 0; apic_probe[i]; i++) {
+		if (!strcmp(apic_probe[i]->name, arg)) {
+			apic = apic_probe[i];
+			cmdline_apic = 1;
+			return 0;
+		}
+	}
+
+	/* Parsed again by __setup for debug/verbose */
+	return 0;
+}
+early_param("apic", parse_apic);
+
+void __init generic_bigsmp_probe(void)
+{
+#ifdef CONFIG_X86_BIGSMP
+	/*
+	 * This routine is used to switch to bigsmp mode when
+	 * - There is no apic= option specified by the user
+	 * - generic_apic_probe() has chosen apic_default as the sub_arch
+	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+	 */
+
+	if (!cmdline_apic && apic == &apic_default) {
+		if (apic_bigsmp.probe()) {
+			apic = &apic_bigsmp;
+			printk(KERN_INFO "Overriding APIC driver with %s\n",
+			       apic->name);
+		}
+	}
+#endif
+}
+
+void __init generic_apic_probe(void)
+{
+	if (!cmdline_apic) {
+		int i;
+		for (i = 0; apic_probe[i]; i++) {
+			if (apic_probe[i]->probe()) {
+				apic = apic_probe[i];
+				break;
+			}
+		}
+		/* Not visible without early console */
+		if (!apic_probe[i])
+			panic("Didn't find an APIC driver");
+	}
+	printk(KERN_INFO "Using APIC driver %s\n", apic->name);
+}
+
+/* These functions can switch the APIC even after the initial ->probe() */
+
+int __init
+generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+	int i;
+
+	for (i = 0; apic_probe[i]; ++i) {
+		if (!apic_probe[i]->mps_oem_check)
+			continue;
+		if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
+			continue;
+
+		if (!cmdline_apic) {
+			apic = apic_probe[i];
+			printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+			       apic->name);
+		}
+		return 1;
+	}
+	return 0;
+}
+
+int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	int i;
+
+	for (i = 0; apic_probe[i]; ++i) {
+		if (!apic_probe[i]->acpi_madt_oem_check)
+			continue;
+		if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
+			continue;
+
+		if (!cmdline_apic) {
+			apic = apic_probe[i];
+			printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+			       apic->name);
+		}
+		return 1;
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/probe_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/probe_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/probe_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/probe_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic APIC sub-arch probe layer.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/hardirq.h>
+#include <linux/dmar.h>
+
+#include <asm/smp.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+#include <asm/setup.h>
+
+extern struct apic apic_flat;
+extern struct apic apic_physflat;
+extern struct apic apic_x2xpic_uv_x;
+extern struct apic apic_x2apic_phys;
+extern struct apic apic_x2apic_cluster;
+
+struct apic __read_mostly *apic = &apic_flat;
+EXPORT_SYMBOL_GPL(apic);
+
+static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_X86_UV
+	&apic_x2apic_uv_x,
+#endif
+#ifdef CONFIG_X86_X2APIC
+	&apic_x2apic_phys,
+	&apic_x2apic_cluster,
+#endif
+	&apic_physflat,
+	NULL,
+};
+
+/*
+ * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
+ */
+void __init default_setup_apic_routing(void)
+{
+#ifdef CONFIG_X86_X2APIC
+	if (x2apic && (apic != &apic_x2apic_phys &&
+#ifdef CONFIG_X86_UV
+		       apic != &apic_x2apic_uv_x &&
+#endif
+		       apic != &apic_x2apic_cluster)) {
+		if (x2apic_phys)
+			apic = &apic_x2apic_phys;
+		else
+			apic = &apic_x2apic_cluster;
+		printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
+	}
+#endif
+
+	if (apic == &apic_flat) {
+		if (max_physical_apicid >= 8)
+			apic = &apic_physflat;
+		printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
+	}
+
+	/*
+	 * Now that apic routing model is selected, configure the
+	 * fault handling for intr remapping.
+	 */
+	if (intr_remapping_enabled)
+		enable_drhd_fault_handling();
+}
+
+/* Same for both flat and physical. */
+
+void apic_send_IPI_self(int vector)
+{
+	__default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
+}
+
+int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	int i;
+
+	for (i = 0; apic_probe[i]; ++i) {
+		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
+			apic = apic_probe[i];
+			printk(KERN_INFO "Setting APIC routing to %s.\n",
+				apic->name);
+			return 1;
+		}
+	}
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/summit_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/summit_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/summit_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/summit_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,576 @@
+/*
+ * IBM Summit-Specific Code
+ *
+ * Written By: Matthew Dobson, IBM Corporation
+ *
+ * Copyright (c) 2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <colpatch@us.ibm.com>
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/bios_ebda.h>
+
+/*
+ * APIC driver for the IBM "Summit" chipset.
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <asm/smp.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <asm/ipi.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/smp.h>
+
+static unsigned summit_get_apic_id(unsigned long x)
+{
+	return (x >> 24) & 0xFF;
+}
+
+static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	default_send_IPI_mask_sequence_logical(mask, vector);
+}
+
+static void summit_send_IPI_allbutself(int vector)
+{
+	default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
+}
+
+static void summit_send_IPI_all(int vector)
+{
+	summit_send_IPI_mask(cpu_online_mask, vector);
+}
+
+#include <asm/tsc.h>
+
+extern int use_cyclone;
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+static void setup_summit(void);
+#else
+static inline void setup_summit(void) {}
+#endif
+
+static int summit_mps_oem_check(struct mpc_table *mpc, char *oem,
+		char *productid)
+{
+	if (!strncmp(oem, "IBM ENSW", 8) &&
+			(!strncmp(productid, "VIGIL SMP", 9)
+			 || !strncmp(productid, "EXA", 3)
+			 || !strncmp(productid, "RUTHLESS SMP", 12))){
+		mark_tsc_unstable("Summit based system");
+		use_cyclone = 1; /*enable cyclone-timer*/
+		setup_summit();
+		return 1;
+	}
+	return 0;
+}
+
+/* Hook from generic ACPI tables.c */
+static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (!strncmp(oem_id, "IBM", 3) &&
+	    (!strncmp(oem_table_id, "SERVIGIL", 8)
+	     || !strncmp(oem_table_id, "EXA", 3))){
+		mark_tsc_unstable("Summit based system");
+		use_cyclone = 1; /*enable cyclone-timer*/
+		setup_summit();
+		return 1;
+	}
+	return 0;
+}
+
+struct rio_table_hdr {
+	unsigned char version;      /* Version number of this data structure           */
+	                            /* Version 3 adds chassis_num & WP_index           */
+	unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil)   */
+	unsigned char num_rio_dev;  /* # of RIO I/O devices (Cyclones and Winnipegs)   */
+} __attribute__((packed));
+
+struct scal_detail {
+	unsigned char node_id;      /* Scalability Node ID                             */
+	unsigned long CBAR;         /* Address of 1MB register space                   */
+	unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
+	unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+	unsigned char port1node;    /* Node ID port connected to: 0xFF = None          */
+	unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+	unsigned char port2node;    /* Node ID port connected to: 0xFF = None          */
+	unsigned char port2port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+	unsigned char chassis_num;  /* 1 based Chassis number (1 = boot node)          */
+} __attribute__((packed));
+
+struct rio_detail {
+	unsigned char node_id;      /* RIO Node ID                                     */
+	unsigned long BBAR;         /* Address of 1MB register space                   */
+	unsigned char type;         /* Type of device                                  */
+	unsigned char owner_id;     /* For WPEG: Node ID of Cyclone that owns this WPEG*/
+	                            /* For CYC:  Node ID of Twister that owns this CYC */
+	unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
+	unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+	unsigned char port1node;    /* Node ID port connected to: 0xFF=None            */
+	unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+	unsigned char first_slot;   /* For WPEG: Lowest slot number below this WPEG    */
+	                            /* For CYC:  0                                     */
+	unsigned char status;       /* For WPEG: Bit 0 = 1 : the XAPIC is used         */
+	                            /*                 = 0 : the XAPIC is not used, ie:*/
+	                            /*                     ints fwded to another XAPIC */
+	                            /*           Bits1:7 Reserved                      */
+	                            /* For CYC:  Bits0:7 Reserved                      */
+	unsigned char WP_index;     /* For WPEG: WPEG instance index - lower ones have */
+	                            /*           lower slot numbers/PCI bus numbers    */
+	                            /* For CYC:  No meaning                            */
+	unsigned char chassis_num;  /* 1 based Chassis number                          */
+	                            /* For LookOut WPEGs this field indicates the      */
+	                            /* Expansion Chassis #, enumerated from Boot       */
+	                            /* Node WPEG external port, then Boot Node CYC     */
+	                            /* external port, then Next Vigil chassis WPEG     */
+	                            /* external port, etc.                             */
+	                            /* Shared Lookouts have only 1 chassis number (the */
+	                            /* first one assigned)                             */
+} __attribute__((packed));
+
+
+typedef enum {
+	CompatTwister = 0,  /* Compatibility Twister               */
+	AltTwister    = 1,  /* Alternate Twister of internal 8-way */
+	CompatCyclone = 2,  /* Compatibility Cyclone               */
+	AltCyclone    = 3,  /* Alternate Cyclone of internal 8-way */
+	CompatWPEG    = 4,  /* Compatibility WPEG                  */
+	AltWPEG       = 5,  /* Second Planar WPEG                  */
+	LookOutAWPEG  = 6,  /* LookOut WPEG                        */
+	LookOutBWPEG  = 7,  /* LookOut WPEG                        */
+} node_type;
+
+static inline int is_WPEG(struct rio_detail *rio){
+	return (rio->type == CompatWPEG || rio->type == AltWPEG ||
+		rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
+}
+
+
+/* In clustered mode, the high nibble of APIC ID is a cluster number.
+ * The low nibble is a 4-bit bitmap. */
+#define XAPIC_DEST_CPUS_SHIFT	4
+#define XAPIC_DEST_CPUS_MASK	((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
+#define XAPIC_DEST_CLUSTER_MASK	(XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
+
+#define SUMMIT_APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
+
+static const struct cpumask *summit_target_cpus(void)
+{
+	/* CPU_MASK_ALL (0xff) has undefined behaviour with
+	 * dest_LowestPrio mode logical clustered apic interrupt routing
+	 * Just start on cpu 0.  IRQ balancing will spread load
+	 */
+	return cpumask_of(0);
+}
+
+static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+	return 0;
+}
+
+/* we don't use the phys_cpu_present_map to indicate apicid presence */
+static unsigned long summit_check_apicid_present(int bit)
+{
+	return 1;
+}
+
+static void summit_init_apic_ldr(void)
+{
+	unsigned long val, id;
+	int count = 0;
+	u8 my_id = (u8)hard_smp_processor_id();
+	u8 my_cluster = APIC_CLUSTER(my_id);
+#ifdef CONFIG_SMP
+	u8 lid;
+	int i;
+
+	/* Create logical APIC IDs by counting CPUs already in cluster. */
+	for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
+		lid = cpu_2_logical_apicid[i];
+		if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
+			++count;
+	}
+#endif
+	/* We only have a 4 wide bitmap in cluster mode.  If a deranged
+	 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
+	BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
+	id = my_cluster | (1UL << count);
+	apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	val |= SET_APIC_LOGICAL_ID(id);
+	apic_write(APIC_LDR, val);
+}
+
+static int summit_apic_id_registered(void)
+{
+	return 1;
+}
+
+static void summit_setup_apic_routing(void)
+{
+	printk("Enabling APIC mode:  Summit.  Using %d I/O APICs\n",
+						nr_ioapics);
+}
+
+static int summit_apicid_to_node(int logical_apicid)
+{
+#ifdef CONFIG_SMP
+	return apicid_2_node[hard_smp_processor_id()];
+#else
+	return 0;
+#endif
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int summit_cpu_to_logical_apicid(int cpu)
+{
+#ifdef CONFIG_SMP
+	if (cpu >= nr_cpu_ids)
+		return BAD_APICID;
+	return cpu_2_logical_apicid[cpu];
+#else
+	return logical_smp_processor_id();
+#endif
+}
+
+static int summit_cpu_present_to_apicid(int mps_cpu)
+{
+	if (mps_cpu < nr_cpu_ids)
+		return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
+	else
+		return BAD_APICID;
+}
+
+static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
+{
+	/* For clustered we don't have a good way to do this yet - hack */
+	return physids_promote(0x0F);
+}
+
+static physid_mask_t summit_apicid_to_cpu_present(int apicid)
+{
+	return physid_mask_of_physid(0);
+}
+
+static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return 1;
+}
+
+static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	unsigned int round = 0;
+	int cpu, apicid = 0;
+
+	/*
+	 * The cpus in the mask must all be on the apic cluster.
+	 */
+	for_each_cpu(cpu, cpumask) {
+		int new_apicid = summit_cpu_to_logical_apicid(cpu);
+
+		if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+			printk("%s: Not a valid mask!\n", __func__);
+			return BAD_APICID;
+		}
+		apicid |= new_apicid;
+		round++;
+	}
+	return apicid;
+}
+
+static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
+			      const struct cpumask *andmask)
+{
+	int apicid = summit_cpu_to_logical_apicid(0);
+	cpumask_var_t cpumask;
+
+	if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
+		return apicid;
+
+	cpumask_and(cpumask, inmask, andmask);
+	cpumask_and(cpumask, cpumask, cpu_online_mask);
+	apicid = summit_cpu_mask_to_apicid(cpumask);
+
+	free_cpumask_var(cpumask);
+
+	return apicid;
+}
+
+/*
+ * cpuid returns the value latched in the HW at reset, not the APIC ID
+ * register's value.  For any box whose BIOS changes APIC IDs, like
+ * clustered APIC systems, we must use hard_smp_processor_id.
+ *
+ * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
+ */
+static int summit_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+	return hard_smp_processor_id() >> index_msb;
+}
+
+static int probe_summit(void)
+{
+	/* probed later in mptable/ACPI hooks */
+	return 0;
+}
+
+static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	/* Careful. Some cpus do not strictly honor the set of cpus
+	 * specified in the interrupt destination when using lowest
+	 * priority interrupt delivery mode.
+	 *
+	 * In particular there was a hyperthreading cpu observed to
+	 * deliver interrupts to the wrong hyperthread when only one
+	 * hyperthread was specified in the interrupt desitination.
+	 */
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
+}
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+static struct rio_table_hdr *rio_table_hdr;
+static struct scal_detail   *scal_devs[MAX_NUMNODES];
+static struct rio_detail    *rio_devs[MAX_NUMNODES*4];
+
+#ifndef CONFIG_X86_NUMAQ
+static int mp_bus_id_to_node[MAX_MP_BUSSES];
+#endif
+
+static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
+{
+	int twister = 0, node = 0;
+	int i, bus, num_buses;
+
+	for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
+		if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
+			twister = rio_devs[i]->owner_id;
+			break;
+		}
+	}
+	if (i == rio_table_hdr->num_rio_dev) {
+		printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__);
+		return last_bus;
+	}
+
+	for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
+		if (scal_devs[i]->node_id == twister) {
+			node = scal_devs[i]->node_id;
+			break;
+		}
+	}
+	if (i == rio_table_hdr->num_scal_dev) {
+		printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__);
+		return last_bus;
+	}
+
+	switch (rio_devs[wpeg_num]->type) {
+	case CompatWPEG:
+		/*
+		 * The Compatibility Winnipeg controls the 2 legacy buses,
+		 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
+		 * a PCI-PCI bridge card is used in either slot: total 5 buses.
+		 */
+		num_buses = 5;
+		break;
+	case AltWPEG:
+		/*
+		 * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
+		 * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
+		 * the "extra" buses for each of those slots: total 7 buses.
+		 */
+		num_buses = 7;
+		break;
+	case LookOutAWPEG:
+	case LookOutBWPEG:
+		/*
+		 * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
+		 * & the "extra" buses for each of those slots: total 9 buses.
+		 */
+		num_buses = 9;
+		break;
+	default:
+		printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__);
+		return last_bus;
+	}
+
+	for (bus = last_bus; bus < last_bus + num_buses; bus++)
+		mp_bus_id_to_node[bus] = node;
+	return bus;
+}
+
+static int build_detail_arrays(void)
+{
+	unsigned long ptr;
+	int i, scal_detail_size, rio_detail_size;
+
+	if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
+		printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
+		return 0;
+	}
+
+	switch (rio_table_hdr->version) {
+	default:
+		printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version);
+		return 0;
+	case 2:
+		scal_detail_size = 11;
+		rio_detail_size = 13;
+		break;
+	case 3:
+		scal_detail_size = 12;
+		rio_detail_size = 15;
+		break;
+	}
+
+	ptr = (unsigned long)rio_table_hdr + 3;
+	for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
+		scal_devs[i] = (struct scal_detail *)ptr;
+
+	for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
+		rio_devs[i] = (struct rio_detail *)ptr;
+
+	return 1;
+}
+
+void setup_summit(void)
+{
+	unsigned long		ptr;
+	unsigned short		offset;
+	int			i, next_wpeg, next_bus = 0;
+
+	/* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
+	ptr = get_bios_ebda();
+	ptr = (unsigned long)phys_to_virt(ptr);
+
+	rio_table_hdr = NULL;
+	offset = 0x180;
+	while (offset) {
+		/* The block id is stored in the 2nd word */
+		if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
+			/* set the pointer past the offset & block id */
+			rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
+			break;
+		}
+		/* The next offset is stored in the 1st word.  0 means no more */
+		offset = *((unsigned short *)(ptr + offset));
+	}
+	if (!rio_table_hdr) {
+		printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__);
+		return;
+	}
+
+	if (!build_detail_arrays())
+		return;
+
+	/* The first Winnipeg we're looking for has an index of 0 */
+	next_wpeg = 0;
+	do {
+		for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
+			if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
+				/* It's the Winnipeg we're looking for! */
+				next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
+				next_wpeg++;
+				break;
+			}
+		}
+		/*
+		 * If we go through all Rio devices and don't find one with
+		 * the next index, it means we've found all the Winnipegs,
+		 * and thus all the PCI buses.
+		 */
+		if (i == rio_table_hdr->num_rio_dev)
+			next_wpeg = 0;
+	} while (next_wpeg != 0);
+}
+#endif
+
+struct apic apic_summit = {
+
+	.name				= "summit",
+	.probe				= probe_summit,
+	.acpi_madt_oem_check		= summit_acpi_madt_oem_check,
+	.apic_id_registered		= summit_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	/* logical delivery broadcast to all CPUs: */
+	.irq_dest_mode			= 1,
+
+	.target_cpus			= summit_target_cpus,
+	.disable_esr			= 1,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= summit_check_apicid_used,
+	.check_apicid_present		= summit_check_apicid_present,
+
+	.vector_allocation_domain	= summit_vector_allocation_domain,
+	.init_apic_ldr			= summit_init_apic_ldr,
+
+	.ioapic_phys_id_map		= summit_ioapic_phys_id_map,
+	.setup_apic_routing		= summit_setup_apic_routing,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= summit_apicid_to_node,
+	.cpu_to_logical_apicid		= summit_cpu_to_logical_apicid,
+	.cpu_present_to_apicid		= summit_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= summit_apicid_to_cpu_present,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= summit_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= summit_phys_pkg_id,
+	.mps_oem_check			= summit_mps_oem_check,
+
+	.get_apic_id			= summit_get_apic_id,
+	.set_apic_id			= NULL,
+	.apic_id_mask			= 0xFF << 24,
+
+	.cpu_mask_to_apicid		= summit_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= summit_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= summit_send_IPI_mask,
+	.send_IPI_mask_allbutself	= NULL,
+	.send_IPI_allbutself		= summit_send_IPI_allbutself,
+	.send_IPI_all			= summit_send_IPI_all,
+	.send_IPI_self			= default_send_IPI_self,
+
+	.trampoline_phys_low		= DEFAULT_TRAMPOLINE_PHYS_LOW,
+	.trampoline_phys_high		= DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+	.wait_for_init_deassert		= default_wait_for_init_deassert,
+
+	.smp_callin_clear_local_apic	= NULL,
+	.inquire_remote_apic		= default_inquire_remote_apic,
+
+	.read				= native_apic_mem_read,
+	.write				= native_apic_mem_write,
+	.icr_read			= native_apic_icr_read,
+	.icr_write			= native_apic_icr_write,
+	.wait_icr_idle			= native_apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_cluster.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_cluster.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_cluster.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_cluster.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,245 @@
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/dmar.h>
+
+#include <asm/smp.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
+
+static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	return x2apic_enabled();
+}
+
+/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
+
+static const struct cpumask *x2apic_target_cpus(void)
+{
+	return cpumask_of(0);
+}
+
+/*
+ * for now each logical cpu is in its own vector allocation domain.
+ */
+static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static void
+ __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
+{
+	unsigned long cfg;
+
+	cfg = __prepare_ICR(0, vector, dest);
+
+	/*
+	 * send the IPI.
+	 */
+	native_x2apic_icr_write(cfg, apicid);
+}
+
+/*
+ * for now, we send the IPI's one by one in the cpumask.
+ * TBD: Based on the cpu mask, we can send the IPI's to the cluster group
+ * at once. We have 16 cpu's in a cluster. This will minimize IPI register
+ * writes.
+ */
+static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		__x2apic_send_IPI_dest(
+			per_cpu(x86_cpu_to_logical_apicid, query_cpu),
+			vector, apic->dest_logical);
+	}
+	local_irq_restore(flags);
+}
+
+static void
+ x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
+{
+	unsigned long this_cpu = smp_processor_id();
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		if (query_cpu == this_cpu)
+			continue;
+		__x2apic_send_IPI_dest(
+				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
+				vector, apic->dest_logical);
+	}
+	local_irq_restore(flags);
+}
+
+static void x2apic_send_IPI_allbutself(int vector)
+{
+	unsigned long this_cpu = smp_processor_id();
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_online_cpu(query_cpu) {
+		if (query_cpu == this_cpu)
+			continue;
+		__x2apic_send_IPI_dest(
+				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
+				vector, apic->dest_logical);
+	}
+	local_irq_restore(flags);
+}
+
+static void x2apic_send_IPI_all(int vector)
+{
+	x2apic_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int x2apic_apic_id_registered(void)
+{
+	return 1;
+}
+
+static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	/*
+	 * We're using fixed IRQ delivery, can only return one logical APIC ID.
+	 * May as well be the first.
+	 */
+	int cpu = cpumask_first(cpumask);
+
+	if ((unsigned)cpu < nr_cpu_ids)
+		return per_cpu(x86_cpu_to_logical_apicid, cpu);
+	else
+		return BAD_APICID;
+}
+
+static unsigned int
+x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			      const struct cpumask *andmask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one logical APIC ID.
+	 * May as well be the first.
+	 */
+	for_each_cpu_and(cpu, cpumask, andmask) {
+		if (cpumask_test_cpu(cpu, cpu_online_mask))
+			break;
+	}
+
+	if (cpu < nr_cpu_ids)
+		return per_cpu(x86_cpu_to_logical_apicid, cpu);
+
+	return BAD_APICID;
+}
+
+static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
+{
+	unsigned int id;
+
+	id = x;
+	return id;
+}
+
+static unsigned long set_apic_id(unsigned int id)
+{
+	unsigned long x;
+
+	x = id;
+	return x;
+}
+
+static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb)
+{
+	return current_cpu_data.initial_apicid >> index_msb;
+}
+
+static void x2apic_send_IPI_self(int vector)
+{
+	apic_write(APIC_SELF_IPI, vector);
+}
+
+static void init_x2apic_ldr(void)
+{
+	int cpu = smp_processor_id();
+
+	per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR);
+}
+
+struct apic apic_x2apic_cluster = {
+
+	.name				= "cluster x2apic",
+	.probe				= NULL,
+	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check,
+	.apic_id_registered		= x2apic_apic_id_registered,
+
+	.irq_delivery_mode		= dest_LowestPrio,
+	.irq_dest_mode			= 1, /* logical */
+
+	.target_cpus			= x2apic_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= NULL,
+	.check_apicid_present		= NULL,
+
+	.vector_allocation_domain	= x2apic_vector_allocation_domain,
+	.init_apic_ldr			= init_x2apic_ldr,
+
+	.ioapic_phys_id_map		= NULL,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= NULL,
+	.cpu_to_logical_apicid		= NULL,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= NULL,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= x2apic_cluster_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= x2apic_cluster_phys_get_apic_id,
+	.set_apic_id			= set_apic_id,
+	.apic_id_mask			= 0xFFFFFFFFu,
+
+	.cpu_mask_to_apicid		= x2apic_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= x2apic_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= x2apic_send_IPI_mask,
+	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= x2apic_send_IPI_allbutself,
+	.send_IPI_all			= x2apic_send_IPI_all,
+	.send_IPI_self			= x2apic_send_IPI_self,
+
+	.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				= native_apic_msr_read,
+	.write				= native_apic_msr_write,
+	.icr_read			= native_x2apic_icr_read,
+	.icr_write			= native_x2apic_icr_write,
+	.wait_icr_idle			= native_x2apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_phys.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_phys.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_phys.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_phys.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,234 @@
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/dmar.h>
+
+#include <asm/smp.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+int x2apic_phys;
+
+static int set_x2apic_phys_mode(char *arg)
+{
+	x2apic_phys = 1;
+	return 0;
+}
+early_param("x2apic_phys", set_x2apic_phys_mode);
+
+static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (x2apic_phys)
+		return x2apic_enabled();
+	else
+		return 0;
+}
+
+/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
+
+static const struct cpumask *x2apic_target_cpus(void)
+{
+	return cpumask_of(0);
+}
+
+static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
+				   unsigned int dest)
+{
+	unsigned long cfg;
+
+	cfg = __prepare_ICR(0, vector, dest);
+
+	/*
+	 * send the IPI.
+	 */
+	native_x2apic_icr_write(cfg, apicid);
+}
+
+static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
+				       vector, APIC_DEST_PHYSICAL);
+	}
+	local_irq_restore(flags);
+}
+
+static void
+ x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
+{
+	unsigned long this_cpu = smp_processor_id();
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_cpu(query_cpu, mask) {
+		if (query_cpu != this_cpu)
+			__x2apic_send_IPI_dest(
+				per_cpu(x86_cpu_to_apicid, query_cpu),
+				vector, APIC_DEST_PHYSICAL);
+	}
+	local_irq_restore(flags);
+}
+
+static void x2apic_send_IPI_allbutself(int vector)
+{
+	unsigned long this_cpu = smp_processor_id();
+	unsigned long query_cpu;
+	unsigned long flags;
+
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+	for_each_online_cpu(query_cpu) {
+		if (query_cpu == this_cpu)
+			continue;
+		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
+				       vector, APIC_DEST_PHYSICAL);
+	}
+	local_irq_restore(flags);
+}
+
+static void x2apic_send_IPI_all(int vector)
+{
+	x2apic_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int x2apic_apic_id_registered(void)
+{
+	return 1;
+}
+
+static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	int cpu = cpumask_first(cpumask);
+
+	if ((unsigned)cpu < nr_cpu_ids)
+		return per_cpu(x86_cpu_to_apicid, cpu);
+	else
+		return BAD_APICID;
+}
+
+static unsigned int
+x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			      const struct cpumask *andmask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	for_each_cpu_and(cpu, cpumask, andmask) {
+		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;
+}
+
+static unsigned int x2apic_phys_get_apic_id(unsigned long x)
+{
+	return x;
+}
+
+static unsigned long set_apic_id(unsigned int id)
+{
+	return id;
+}
+
+static int x2apic_phys_pkg_id(int initial_apicid, int index_msb)
+{
+	return current_cpu_data.initial_apicid >> index_msb;
+}
+
+static void x2apic_send_IPI_self(int vector)
+{
+	apic_write(APIC_SELF_IPI, vector);
+}
+
+static void init_x2apic_ldr(void)
+{
+}
+
+struct apic apic_x2apic_phys = {
+
+	.name				= "physical x2apic",
+	.probe				= NULL,
+	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check,
+	.apic_id_registered		= x2apic_apic_id_registered,
+
+	.irq_delivery_mode		= dest_Fixed,
+	.irq_dest_mode			= 0, /* physical */
+
+	.target_cpus			= x2apic_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= 0,
+	.check_apicid_used		= NULL,
+	.check_apicid_present		= NULL,
+
+	.vector_allocation_domain	= x2apic_vector_allocation_domain,
+	.init_apic_ldr			= init_x2apic_ldr,
+
+	.ioapic_phys_id_map		= NULL,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= NULL,
+	.cpu_to_logical_apicid		= NULL,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= NULL,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= x2apic_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= x2apic_phys_get_apic_id,
+	.set_apic_id			= set_apic_id,
+	.apic_id_mask			= 0xFFFFFFFFu,
+
+	.cpu_mask_to_apicid		= x2apic_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= x2apic_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= x2apic_send_IPI_mask,
+	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= x2apic_send_IPI_allbutself,
+	.send_IPI_all			= x2apic_send_IPI_all,
+	.send_IPI_self			= x2apic_send_IPI_self,
+
+	.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				= native_apic_msr_read,
+	.write				= native_apic_msr_write,
+	.icr_read			= native_x2apic_icr_read,
+	.icr_write			= native_x2apic_icr_write,
+	.wait_icr_idle			= native_x2apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
+};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,669 @@
+/*
+ * 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.
+ *
+ * SGI UV APIC functions (note: not an Intel compatible APIC)
+ *
+ * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ */
+#include <linux/cpumask.h>
+#include <linux/hardirq.h>
+#include <linux/proc_fs.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/uv/uv_mmrs.h>
+#include <asm/uv/uv_hub.h>
+#include <asm/current.h>
+#include <asm/pgtable.h>
+#include <asm/uv/bios.h>
+#include <asm/uv/uv.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+#include <asm/smp.h>
+
+DEFINE_PER_CPU(int, x2apic_extra_bits);
+
+static enum uv_system_type uv_system_type;
+
+static int early_get_nodeid(void)
+{
+	union uvh_node_id_u node_id;
+	unsigned long *mmr;
+
+	mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_NODE_ID, sizeof(*mmr));
+	node_id.v = *mmr;
+	early_iounmap(mmr, sizeof(*mmr));
+	return node_id.s.node_id;
+}
+
+static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (!strcmp(oem_id, "SGI")) {
+		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);
+			uv_system_type = UV_NON_UNIQUE_APIC;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+enum uv_system_type get_uv_system_type(void)
+{
+	return uv_system_type;
+}
+
+int is_uv_system(void)
+{
+	return uv_system_type != UV_NONE;
+}
+EXPORT_SYMBOL_GPL(is_uv_system);
+
+DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
+
+struct uv_blade_info *uv_blade_info;
+EXPORT_SYMBOL_GPL(uv_blade_info);
+
+short *uv_node_to_blade;
+EXPORT_SYMBOL_GPL(uv_node_to_blade);
+
+short *uv_cpu_to_blade;
+EXPORT_SYMBOL_GPL(uv_cpu_to_blade);
+
+short uv_possible_blades;
+EXPORT_SYMBOL_GPL(uv_possible_blades);
+
+unsigned long sn_rtc_cycles_per_second;
+EXPORT_SYMBOL(sn_rtc_cycles_per_second);
+
+/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
+
+static const struct cpumask *uv_target_cpus(void)
+{
+	return cpumask_of(0);
+}
+
+static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+{
+#ifdef CONFIG_SMP
+	unsigned long val;
+	int pnode;
+
+	pnode = uv_apicid_to_pnode(phys_apicid);
+	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
+	    ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
+	    APIC_DM_INIT;
+	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+	mdelay(10);
+
+	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
+	    ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
+	    APIC_DM_STARTUP;
+	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+
+	atomic_set(&init_deasserted, 1);
+#endif
+	return 0;
+}
+
+static void uv_send_IPI_one(int cpu, int vector)
+{
+	unsigned long apicid;
+	int pnode;
+
+	apicid = per_cpu(x86_cpu_to_apicid, cpu);
+	pnode = uv_apicid_to_pnode(apicid);
+	uv_hub_send_ipi(pnode, apicid, vector);
+}
+
+static void uv_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	unsigned int cpu;
+
+	for_each_cpu(cpu, mask)
+		uv_send_IPI_one(cpu, vector);
+}
+
+static void uv_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
+{
+	unsigned int this_cpu = smp_processor_id();
+	unsigned int cpu;
+
+	for_each_cpu(cpu, mask) {
+		if (cpu != this_cpu)
+			uv_send_IPI_one(cpu, vector);
+	}
+}
+
+static void uv_send_IPI_allbutself(int vector)
+{
+	unsigned int this_cpu = smp_processor_id();
+	unsigned int cpu;
+
+	for_each_online_cpu(cpu) {
+		if (cpu != this_cpu)
+			uv_send_IPI_one(cpu, vector);
+	}
+}
+
+static void uv_send_IPI_all(int vector)
+{
+	uv_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int uv_apic_id_registered(void)
+{
+	return 1;
+}
+
+static void uv_init_apic_ldr(void)
+{
+}
+
+static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask)
+{
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	int cpu = cpumask_first(cpumask);
+
+	if ((unsigned)cpu < nr_cpu_ids)
+		return per_cpu(x86_cpu_to_apicid, cpu);
+	else
+		return BAD_APICID;
+}
+
+static unsigned int
+uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+			  const struct cpumask *andmask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	for_each_cpu_and(cpu, cpumask, andmask) {
+		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;
+}
+
+static unsigned int x2apic_get_apic_id(unsigned long x)
+{
+	unsigned int id;
+
+	WARN_ON(preemptible() && num_online_cpus() > 1);
+	id = x | __get_cpu_var(x2apic_extra_bits);
+
+	return id;
+}
+
+static unsigned long set_apic_id(unsigned int id)
+{
+	unsigned long x;
+
+	/* maskout x2apic_extra_bits ? */
+	x = id;
+	return x;
+}
+
+static unsigned int uv_read_apic_id(void)
+{
+
+	return x2apic_get_apic_id(apic_read(APIC_ID));
+}
+
+static int uv_phys_pkg_id(int initial_apicid, int index_msb)
+{
+	return uv_read_apic_id() >> index_msb;
+}
+
+static void uv_send_IPI_self(int vector)
+{
+	apic_write(APIC_SELF_IPI, vector);
+}
+
+struct apic apic_x2apic_uv_x = {
+
+	.name				= "UV large system",
+	.probe				= NULL,
+	.acpi_madt_oem_check		= uv_acpi_madt_oem_check,
+	.apic_id_registered		= uv_apic_id_registered,
+
+	.irq_delivery_mode		= dest_Fixed,
+	.irq_dest_mode			= 1, /* logical */
+
+	.target_cpus			= uv_target_cpus,
+	.disable_esr			= 0,
+	.dest_logical			= APIC_DEST_LOGICAL,
+	.check_apicid_used		= NULL,
+	.check_apicid_present		= NULL,
+
+	.vector_allocation_domain	= uv_vector_allocation_domain,
+	.init_apic_ldr			= uv_init_apic_ldr,
+
+	.ioapic_phys_id_map		= NULL,
+	.setup_apic_routing		= NULL,
+	.multi_timer_check		= NULL,
+	.apicid_to_node			= NULL,
+	.cpu_to_logical_apicid		= NULL,
+	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
+	.apicid_to_cpu_present		= NULL,
+	.setup_portio_remap		= NULL,
+	.check_phys_apicid_present	= default_check_phys_apicid_present,
+	.enable_apic_mode		= NULL,
+	.phys_pkg_id			= uv_phys_pkg_id,
+	.mps_oem_check			= NULL,
+
+	.get_apic_id			= x2apic_get_apic_id,
+	.set_apic_id			= set_apic_id,
+	.apic_id_mask			= 0xFFFFFFFFu,
+
+	.cpu_mask_to_apicid		= uv_cpu_mask_to_apicid,
+	.cpu_mask_to_apicid_and		= uv_cpu_mask_to_apicid_and,
+
+	.send_IPI_mask			= uv_send_IPI_mask,
+	.send_IPI_mask_allbutself	= uv_send_IPI_mask_allbutself,
+	.send_IPI_allbutself		= uv_send_IPI_allbutself,
+	.send_IPI_all			= uv_send_IPI_all,
+	.send_IPI_self			= uv_send_IPI_self,
+
+	.wakeup_secondary_cpu		= uv_wakeup_secondary,
+	.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				= native_apic_msr_read,
+	.write				= native_apic_msr_write,
+	.icr_read			= native_x2apic_icr_read,
+	.icr_write			= native_x2apic_icr_write,
+	.wait_icr_idle			= native_x2apic_wait_icr_idle,
+	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
+};
+
+static __cpuinit void set_x2apic_extra_bits(int pnode)
+{
+	__get_cpu_var(x2apic_extra_bits) = (pnode << 6);
+}
+
+/*
+ * Called on boot cpu.
+ */
+static __init int boot_pnode_to_blade(int pnode)
+{
+	int blade;
+
+	for (blade = 0; blade < uv_num_possible_blades(); blade++)
+		if (pnode == uv_blade_info[blade].pnode)
+			return blade;
+	BUG();
+}
+
+struct redir_addr {
+	unsigned long redirect;
+	unsigned long alias;
+};
+
+#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
+
+static __initdata struct redir_addr redir_addrs[] = {
+	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG},
+	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG},
+	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG},
+};
+
+static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
+{
+	union uvh_si_alias0_overlay_config_u alias;
+	union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
+		alias.v = uv_read_local_mmr(redir_addrs[i].alias);
+		if (alias.s.base == 0) {
+			*size = (1UL << alias.s.m_alias);
+			redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
+			*base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
+			return;
+		}
+	}
+	BUG();
+}
+
+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);
+}
+
+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)
+{
+	unsigned long bytes, paddr;
+
+	paddr = base << shift;
+	bytes = (1UL << shift) * (max_pnode + 1);
+	printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
+						paddr + bytes);
+	if (map_type == map_uc)
+		init_extra_mapping_uc(paddr, bytes);
+	else
+		init_extra_mapping_wb(paddr, bytes);
+
+}
+static __init void map_gru_high(int max_pnode)
+{
+	union uvh_rh_gam_gru_overlay_config_mmr_u gru;
+	int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
+
+	gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
+	if (gru.s.enable)
+		map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
+}
+
+static __init void map_config_high(int max_pnode)
+{
+	union uvh_rh_gam_cfg_overlay_config_mmr_u cfg;
+	int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT;
+
+	cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR);
+	if (cfg.s.enable)
+		map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc);
+}
+
+static __init void map_mmr_high(int max_pnode)
+{
+	union uvh_rh_gam_mmr_overlay_config_mmr_u mmr;
+	int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT;
+
+	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);
+}
+
+static __init void map_mmioh_high(int max_pnode)
+{
+	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
+	int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
+
+	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);
+}
+
+static __init void uv_rtc_init(void)
+{
+	long status;
+	u64 ticks_per_sec;
+
+	status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
+					&ticks_per_sec);
+	if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
+		printk(KERN_WARNING
+			"unable to determine platform RTC clock frequency, "
+			"guessing.\n");
+		/* BIOS gives wrong value for clock freq. so guess */
+		sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
+	} else
+		sn_rtc_cycles_per_second = ticks_per_sec;
+}
+
+/*
+ * percpu heartbeat timer
+ */
+static void uv_heartbeat(unsigned long ignored)
+{
+	struct timer_list *timer = &uv_hub_info->scir.timer;
+	unsigned char bits = uv_hub_info->scir.state;
+
+	/* flip heartbeat bit */
+	bits ^= SCIR_CPU_HEARTBEAT;
+
+	/* is this cpu idle? */
+	if (idle_cpu(raw_smp_processor_id()))
+		bits &= ~SCIR_CPU_ACTIVITY;
+	else
+		bits |= SCIR_CPU_ACTIVITY;
+
+	/* update system controller interface reg */
+	uv_set_scir_bits(bits);
+
+	/* enable next timer period */
+	mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL);
+}
+
+static void __cpuinit uv_heartbeat_enable(int cpu)
+{
+	if (!uv_cpu_hub_info(cpu)->scir.enabled) {
+		struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer;
+
+		uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY);
+		setup_timer(timer, uv_heartbeat, cpu);
+		timer->expires = jiffies + SCIR_CPU_HB_INTERVAL;
+		add_timer_on(timer, cpu);
+		uv_cpu_hub_info(cpu)->scir.enabled = 1;
+	}
+
+	/* check boot cpu */
+	if (!uv_cpu_hub_info(0)->scir.enabled)
+		uv_heartbeat_enable(0);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __cpuinit uv_heartbeat_disable(int cpu)
+{
+	if (uv_cpu_hub_info(cpu)->scir.enabled) {
+		uv_cpu_hub_info(cpu)->scir.enabled = 0;
+		del_timer(&uv_cpu_hub_info(cpu)->scir.timer);
+	}
+	uv_set_cpu_scir_bits(cpu, 0xff);
+}
+
+/*
+ * cpu hotplug notifier
+ */
+static __cpuinit int uv_scir_cpu_notify(struct notifier_block *self,
+				       unsigned long action, void *hcpu)
+{
+	long cpu = (long)hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+		uv_heartbeat_enable(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		uv_heartbeat_disable(cpu);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static __init void uv_scir_register_cpu_notifier(void)
+{
+	hotcpu_notifier(uv_scir_cpu_notify, 0);
+}
+
+#else /* !CONFIG_HOTPLUG_CPU */
+
+static __init void uv_scir_register_cpu_notifier(void)
+{
+}
+
+static __init int uv_init_heartbeat(void)
+{
+	int cpu;
+
+	if (is_uv_system())
+		for_each_online_cpu(cpu)
+			uv_heartbeat_enable(cpu);
+	return 0;
+}
+
+late_initcall(uv_init_heartbeat);
+
+#endif /* !CONFIG_HOTPLUG_CPU */
+
+/*
+ * Called on each cpu to initialize the per_cpu UV data area.
+ * FIXME: hotplug not supported yet
+ */
+void __cpuinit uv_cpu_init(void)
+{
+	/* CPU 0 initilization will be done via uv_system_init. */
+	if (!uv_blade_info)
+		return;
+
+	uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
+
+	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
+		set_x2apic_extra_bits(uv_hub_info->pnode);
+}
+
+
+void __init uv_system_init(void)
+{
+	union uvh_si_addr_map_config_u m_n_config;
+	union uvh_node_id_u node_id;
+	unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
+	int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
+	int max_pnode = 0;
+	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;
+	mmr_base =
+	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
+	    ~UV_MMR_ENABLE;
+	printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
+
+	for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
+		uv_possible_blades +=
+		  hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8));
+	printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades());
+
+	bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
+	uv_blade_info = kmalloc(bytes, GFP_KERNEL);
+
+	get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
+
+	bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
+	uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
+	memset(uv_node_to_blade, 255, bytes);
+
+	bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus();
+	uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL);
+	memset(uv_cpu_to_blade, 255, bytes);
+
+	blade = 0;
+	for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
+		present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
+		for (j = 0; j < 64; j++) {
+			if (!test_bit(j, &present))
+				continue;
+			uv_blade_info[blade].pnode = (i * 64 + j);
+			uv_blade_info[blade].nr_possible_cpus = 0;
+			uv_blade_info[blade].nr_online_cpus = 0;
+			blade++;
+		}
+	}
+
+	pnode_mask = (1 << n_val) - 1;
+	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
+	gnode_upper = (((unsigned long)node_id.s.node_id) &
+		       ~((1 << n_val) - 1)) << m_val;
+
+	uv_bios_init();
+	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
+			    &sn_coherency_id, &sn_region_size);
+	uv_rtc_init();
+
+	for_each_present_cpu(cpu) {
+		nid = cpu_to_node(cpu);
+		pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
+		blade = boot_pnode_to_blade(pnode);
+		lcpu = uv_blade_info[blade].nr_possible_cpus;
+		uv_blade_info[blade].nr_possible_cpus++;
+
+		uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
+		uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
+		uv_cpu_hub_info(cpu)->m_val = m_val;
+		uv_cpu_hub_info(cpu)->n_val = m_val;
+		uv_cpu_hub_info(cpu)->numa_blade_id = blade;
+		uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
+		uv_cpu_hub_info(cpu)->pnode = pnode;
+		uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
+		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
+		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_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);
+	}
+
+	/* Add blade/pnode info for nodes without cpus */
+	for_each_online_node(nid) {
+		if (uv_node_to_blade[nid] >= 0)
+			continue;
+		paddr = node_start_pfn(nid) << PAGE_SHIFT;
+		paddr = uv_soc_phys_ram_to_gpa(paddr);
+		pnode = (paddr >> m_val) & pnode_mask;
+		blade = boot_pnode_to_blade(pnode);
+		uv_node_to_blade[nid] = blade;
+	}
+
+	map_gru_high(max_pnode);
+	map_mmr_high(max_pnode);
+	map_config_high(max_pnode);
+	map_mmioh_high(max_pnode);
+
+	uv_cpu_init();
+	uv_scir_register_cpu_notifier();
+	proc_mkdir("sgi_uv", NULL);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apic.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apic.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2223 +0,0 @@
-/*
- *	Local APIC handling, local APIC timers
- *
- *	(c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
- *
- *	Fixes
- *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs;
- *					thanks to Eric Gilmore
- *					and Rolf G. Tews
- *					for testing these extensively.
- *	Maciej W. Rozycki	:	Various updates and fixes.
- *	Mikael Pettersson	:	Power Management for UP-APIC.
- *	Pavel Machek and
- *	Mikael Pettersson	:	PM converted to driver model.
- */
-
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/kernel_stat.h>
-#include <linux/sysdev.h>
-#include <linux/ioport.h>
-#include <linux/cpu.h>
-#include <linux/clockchips.h>
-#include <linux/acpi_pmtmr.h>
-#include <linux/module.h>
-#include <linux/dmi.h>
-#include <linux/dmar.h>
-#include <linux/ftrace.h>
-#include <linux/smp.h>
-#include <linux/nmi.h>
-#include <linux/timex.h>
-
-#include <asm/atomic.h>
-#include <asm/mtrr.h>
-#include <asm/mpspec.h>
-#include <asm/desc.h>
-#include <asm/arch_hooks.h>
-#include <asm/hpet.h>
-#include <asm/pgalloc.h>
-#include <asm/i8253.h>
-#include <asm/idle.h>
-#include <asm/proto.h>
-#include <asm/apic.h>
-#include <asm/i8259.h>
-#include <asm/smp.h>
-
-#include <mach_apic.h>
-#include <mach_apicdef.h>
-#include <mach_ipi.h>
-
-/*
- * Sanity check
- */
-#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
-# error SPURIOUS_APIC_VECTOR definition error
-#endif
-
-#ifdef CONFIG_X86_32
-/*
- * Knob to control our willingness to enable the local APIC.
- *
- * +1=force-enable
- */
-static int force_enable_local_apic;
-/*
- * APIC command line parameters
- */
-static int __init parse_lapic(char *arg)
-{
-	force_enable_local_apic = 1;
-	return 0;
-}
-early_param("lapic", parse_lapic);
-/* Local APIC was disabled by the BIOS and enabled by the kernel */
-static int enabled_via_apicbase;
-
-#endif
-
-#ifdef CONFIG_X86_64
-static int apic_calibrate_pmtmr __initdata;
-static __init int setup_apicpmtimer(char *s)
-{
-	apic_calibrate_pmtmr = 1;
-	notsc_setup(NULL);
-	return 0;
-}
-__setup("apicpmtimer", setup_apicpmtimer);
-#endif
-
-#ifdef CONFIG_X86_64
-#define HAVE_X2APIC
-#endif
-
-#ifdef HAVE_X2APIC
-int x2apic;
-/* x2apic enabled before OS handover */
-static int x2apic_preenabled;
-static int disable_x2apic;
-static __init int setup_nox2apic(char *str)
-{
-	disable_x2apic = 1;
-	setup_clear_cpu_cap(X86_FEATURE_X2APIC);
-	return 0;
-}
-early_param("nox2apic", setup_nox2apic);
-#endif
-
-unsigned long mp_lapic_addr;
-int disable_apic;
-/* Disable local APIC timer from the kernel commandline or via dmi quirk */
-static int disable_apic_timer __cpuinitdata;
-/* Local APIC timer works in C2 */
-int local_apic_timer_c2_ok;
-EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
-
-int first_system_vector = 0xfe;
-
-/*
- * Debug level, exported for io_apic.c
- */
-unsigned int apic_verbosity;
-
-int pic_mode;
-
-/* Have we found an MP table */
-int smp_found_config;
-
-static struct resource lapic_resource = {
-	.name = "Local APIC",
-	.flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
-static unsigned int calibration_result;
-
-static int lapic_next_event(unsigned long delta,
-			    struct clock_event_device *evt);
-static void lapic_timer_setup(enum clock_event_mode mode,
-			      struct clock_event_device *evt);
-static void lapic_timer_broadcast(const struct cpumask *mask);
-static void apic_pm_activate(void);
-
-/*
- * The local apic timer can be used for any function which is CPU local.
- */
-static struct clock_event_device lapic_clockevent = {
-	.name		= "lapic",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
-			| CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
-	.shift		= 32,
-	.set_mode	= lapic_timer_setup,
-	.set_next_event	= lapic_next_event,
-	.broadcast	= lapic_timer_broadcast,
-	.rating		= 100,
-	.irq		= -1,
-};
-static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
-
-static unsigned long apic_phys;
-
-/*
- * Get the LAPIC version
- */
-static inline int lapic_get_version(void)
-{
-	return GET_APIC_VERSION(apic_read(APIC_LVR));
-}
-
-/*
- * Check, if the APIC is integrated or a separate chip
- */
-static inline int lapic_is_integrated(void)
-{
-#ifdef CONFIG_X86_64
-	return 1;
-#else
-	return APIC_INTEGRATED(lapic_get_version());
-#endif
-}
-
-/*
- * Check, whether this is a modern or a first generation APIC
- */
-static int modern_apic(void)
-{
-	/* AMD systems use old APIC versions, so check the CPU */
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-	    boot_cpu_data.x86 >= 0xf)
-		return 1;
-	return lapic_get_version() >= 0x14;
-}
-
-/*
- * Paravirt kernels also might be using these below ops. So we still
- * use generic apic_read()/apic_write(), which might be pointing to different
- * ops in PARAVIRT case.
- */
-void xapic_wait_icr_idle(void)
-{
-	while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
-		cpu_relax();
-}
-
-u32 safe_xapic_wait_icr_idle(void)
-{
-	u32 send_status;
-	int timeout;
-
-	timeout = 0;
-	do {
-		send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
-		if (!send_status)
-			break;
-		udelay(100);
-	} while (timeout++ < 1000);
-
-	return send_status;
-}
-
-void xapic_icr_write(u32 low, u32 id)
-{
-	apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
-	apic_write(APIC_ICR, low);
-}
-
-static u64 xapic_icr_read(void)
-{
-	u32 icr1, icr2;
-
-	icr2 = apic_read(APIC_ICR2);
-	icr1 = apic_read(APIC_ICR);
-
-	return icr1 | ((u64)icr2 << 32);
-}
-
-static struct apic_ops xapic_ops = {
-	.read = native_apic_mem_read,
-	.write = native_apic_mem_write,
-	.icr_read = xapic_icr_read,
-	.icr_write = xapic_icr_write,
-	.wait_icr_idle = xapic_wait_icr_idle,
-	.safe_wait_icr_idle = safe_xapic_wait_icr_idle,
-};
-
-struct apic_ops __read_mostly *apic_ops = &xapic_ops;
-EXPORT_SYMBOL_GPL(apic_ops);
-
-#ifdef HAVE_X2APIC
-static void x2apic_wait_icr_idle(void)
-{
-	/* no need to wait for icr idle in x2apic */
-	return;
-}
-
-static u32 safe_x2apic_wait_icr_idle(void)
-{
-	/* no need to wait for icr idle in x2apic */
-	return 0;
-}
-
-void x2apic_icr_write(u32 low, u32 id)
-{
-	wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
-}
-
-static u64 x2apic_icr_read(void)
-{
-	unsigned long val;
-
-	rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
-	return val;
-}
-
-static struct apic_ops x2apic_ops = {
-	.read = native_apic_msr_read,
-	.write = native_apic_msr_write,
-	.icr_read = x2apic_icr_read,
-	.icr_write = x2apic_icr_write,
-	.wait_icr_idle = x2apic_wait_icr_idle,
-	.safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
-};
-#endif
-
-/**
- * enable_NMI_through_LVT0 - enable NMI through local vector table 0
- */
-void __cpuinit enable_NMI_through_LVT0(void)
-{
-	unsigned int v;
-
-	/* unmask and set to NMI */
-	v = APIC_DM_NMI;
-
-	/* Level triggered for 82489DX (32bit mode) */
-	if (!lapic_is_integrated())
-		v |= APIC_LVT_LEVEL_TRIGGER;
-
-	apic_write(APIC_LVT0, v);
-}
-
-#ifdef CONFIG_X86_32
-/**
- * get_physical_broadcast - Get number of physical broadcast IDs
- */
-int get_physical_broadcast(void)
-{
-	return modern_apic() ? 0xff : 0xf;
-}
-#endif
-
-/**
- * lapic_get_maxlvt - get the maximum number of local vector table entries
- */
-int lapic_get_maxlvt(void)
-{
-	unsigned int v;
-
-	v = apic_read(APIC_LVR);
-	/*
-	 * - we always have APIC integrated on 64bit mode
-	 * - 82489DXs do not report # of LVT entries
-	 */
-	return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2;
-}
-
-/*
- * Local APIC timer
- */
-
-/* Clock divisor */
-#define APIC_DIVISOR 16
-
-/*
- * This function sets up the local APIC timer, with a timeout of
- * 'clocks' APIC bus clock. During calibration we actually call
- * this function twice on the boot CPU, once with a bogus timeout
- * value, second time for real. The other (noncalibrating) CPUs
- * call this function only once, with the real, calibrated value.
- *
- * We do reads before writes even if unnecessary, to get around the
- * P5 APIC double write bug.
- */
-static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
-{
-	unsigned int lvtt_value, tmp_value;
-
-	lvtt_value = LOCAL_TIMER_VECTOR;
-	if (!oneshot)
-		lvtt_value |= APIC_LVT_TIMER_PERIODIC;
-	if (!lapic_is_integrated())
-		lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
-
-	if (!irqen)
-		lvtt_value |= APIC_LVT_MASKED;
-
-	apic_write(APIC_LVTT, lvtt_value);
-
-	/*
-	 * Divide PICLK by 16
-	 */
-	tmp_value = apic_read(APIC_TDCR);
-	apic_write(APIC_TDCR,
-		(tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
-		APIC_TDR_DIV_16);
-
-	if (!oneshot)
-		apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
-}
-
-/*
- * Setup extended LVT, AMD specific (K8, family 10h)
- *
- * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
- * MCE interrupts are supported. Thus MCE offset must be set to 0.
- *
- * If mask=1, the LVT entry does not generate interrupts while mask=0
- * enables the vector. See also the BKDGs.
- */
-
-#define APIC_EILVT_LVTOFF_MCE 0
-#define APIC_EILVT_LVTOFF_IBS 1
-
-static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
-{
-	unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
-	unsigned int  v   = (mask << 16) | (msg_type << 8) | vector;
-
-	apic_write(reg, v);
-}
-
-u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
-{
-	setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
-	return APIC_EILVT_LVTOFF_MCE;
-}
-
-u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
-{
-	setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
-	return APIC_EILVT_LVTOFF_IBS;
-}
-EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
-
-/*
- * Program the next event, relative to now
- */
-static int lapic_next_event(unsigned long delta,
-			    struct clock_event_device *evt)
-{
-	apic_write(APIC_TMICT, delta);
-	return 0;
-}
-
-/*
- * Setup the lapic timer in periodic or oneshot mode
- */
-static void lapic_timer_setup(enum clock_event_mode mode,
-			      struct clock_event_device *evt)
-{
-	unsigned long flags;
-	unsigned int v;
-
-	/* Lapic used as dummy for broadcast ? */
-	if (evt->features & CLOCK_EVT_FEAT_DUMMY)
-		return;
-
-	local_irq_save(flags);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-	case CLOCK_EVT_MODE_ONESHOT:
-		__setup_APIC_LVTT(calibration_result,
-				  mode != CLOCK_EVT_MODE_PERIODIC, 1);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		v = apic_read(APIC_LVTT);
-		v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-		apic_write(APIC_LVTT, v);
-		apic_write(APIC_TMICT, 0xffffffff);
-		break;
-	case CLOCK_EVT_MODE_RESUME:
-		/* Nothing to do here */
-		break;
-	}
-
-	local_irq_restore(flags);
-}
-
-/*
- * Local APIC timer broadcast function
- */
-static void lapic_timer_broadcast(const struct cpumask *mask)
-{
-#ifdef CONFIG_SMP
-	send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
-#endif
-}
-
-/*
- * Setup the local APIC timer for this CPU. Copy the initilized values
- * of the boot CPU and register the clock event in the framework.
- */
-static void __cpuinit setup_APIC_timer(void)
-{
-	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
-
-	memcpy(levt, &lapic_clockevent, sizeof(*levt));
-	levt->cpumask = cpumask_of(smp_processor_id());
-
-	clockevents_register_device(levt);
-}
-
-/*
- * In this functions we calibrate APIC bus clocks to the external timer.
- *
- * We want to do the calibration only once since we want to have local timer
- * irqs syncron. CPUs connected by the same APIC bus have the very same bus
- * frequency.
- *
- * This was previously done by reading the PIT/HPET and waiting for a wrap
- * around to find out, that a tick has elapsed. I have a box, where the PIT
- * readout is broken, so it never gets out of the wait loop again. This was
- * also reported by others.
- *
- * Monitoring the jiffies value is inaccurate and the clockevents
- * infrastructure allows us to do a simple substitution of the interrupt
- * handler.
- *
- * The calibration routine also uses the pm_timer when possible, as the PIT
- * happens to run way too slow (factor 2.3 on my VAIO CoreDuo, which goes
- * back to normal later in the boot process).
- */
-
-#define LAPIC_CAL_LOOPS		(HZ/10)
-
-static __initdata int lapic_cal_loops = -1;
-static __initdata long lapic_cal_t1, lapic_cal_t2;
-static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;
-static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2;
-static __initdata unsigned long lapic_cal_j1, lapic_cal_j2;
-
-/*
- * Temporary interrupt handler.
- */
-static void __init lapic_cal_handler(struct clock_event_device *dev)
-{
-	unsigned long long tsc = 0;
-	long tapic = apic_read(APIC_TMCCT);
-	unsigned long pm = acpi_pm_read_early();
-
-	if (cpu_has_tsc)
-		rdtscll(tsc);
-
-	switch (lapic_cal_loops++) {
-	case 0:
-		lapic_cal_t1 = tapic;
-		lapic_cal_tsc1 = tsc;
-		lapic_cal_pm1 = pm;
-		lapic_cal_j1 = jiffies;
-		break;
-
-	case LAPIC_CAL_LOOPS:
-		lapic_cal_t2 = tapic;
-		lapic_cal_tsc2 = tsc;
-		if (pm < lapic_cal_pm1)
-			pm += ACPI_PM_OVRRUN;
-		lapic_cal_pm2 = pm;
-		lapic_cal_j2 = jiffies;
-		break;
-	}
-}
-
-static int __init calibrate_by_pmtimer(long deltapm, long *delta)
-{
-	const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
-	const long pm_thresh = pm_100ms / 100;
-	unsigned long mult;
-	u64 res;
-
-#ifndef CONFIG_X86_PM_TIMER
-	return -1;
-#endif
-
-	apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
-
-	/* Check, if the PM timer is available */
-	if (!deltapm)
-		return -1;
-
-	mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
-
-	if (deltapm > (pm_100ms - pm_thresh) &&
-	    deltapm < (pm_100ms + pm_thresh)) {
-		apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
-	} else {
-		res = (((u64)deltapm) *  mult) >> 22;
-		do_div(res, 1000000);
-		pr_warning("APIC calibration not consistent "
-			"with PM Timer: %ldms instead of 100ms\n",
-			(long)res);
-		/* Correct the lapic counter value */
-		res = (((u64)(*delta)) * pm_100ms);
-		do_div(res, deltapm);
-		pr_info("APIC delta adjusted to PM-Timer: "
-			"%lu (%ld)\n", (unsigned long)res, *delta);
-		*delta = (long)res;
-	}
-
-	return 0;
-}
-
-static int __init calibrate_APIC_clock(void)
-{
-	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
-	void (*real_handler)(struct clock_event_device *dev);
-	unsigned long deltaj;
-	long delta;
-	int pm_referenced = 0;
-
-	local_irq_disable();
-
-	/* Replace the global interrupt handler */
-	real_handler = global_clock_event->event_handler;
-	global_clock_event->event_handler = lapic_cal_handler;
-
-	/*
-	 * Setup the APIC counter to maximum. There is no way the lapic
-	 * can underflow in the 100ms detection time frame
-	 */
-	__setup_APIC_LVTT(0xffffffff, 0, 0);
-
-	/* Let the interrupts run */
-	local_irq_enable();
-
-	while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
-		cpu_relax();
-
-	local_irq_disable();
-
-	/* Restore the real event handler */
-	global_clock_event->event_handler = real_handler;
-
-	/* Build delta t1-t2 as apic timer counts down */
-	delta = lapic_cal_t1 - lapic_cal_t2;
-	apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
-
-	/* we trust the PM based calibration if possible */
-	pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
-					&delta);
-
-	/* Calculate the scaled math multiplication factor */
-	lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
-				       lapic_clockevent.shift);
-	lapic_clockevent.max_delta_ns =
-		clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
-	lapic_clockevent.min_delta_ns =
-		clockevent_delta2ns(0xF, &lapic_clockevent);
-
-	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, "..... calibration result: %u\n",
-		    calibration_result);
-
-	if (cpu_has_tsc) {
-		delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
-		apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
-			    "%ld.%04ld MHz.\n",
-			    (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ),
-			    (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ));
-	}
-
-	apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
-		    "%u.%04u MHz.\n",
-		    calibration_result / (1000000 / HZ),
-		    calibration_result % (1000000 / HZ));
-
-	/*
-	 * Do a sanity check on the APIC calibration result
-	 */
-	if (calibration_result < (1000000 / HZ)) {
-		local_irq_enable();
-		pr_warning("APIC frequency too slow, disabling apic timer\n");
-		return -1;
-	}
-
-	levt->features &= ~CLOCK_EVT_FEAT_DUMMY;
-
-	/*
-	 * PM timer calibration failed or not turned on
-	 * so lets try APIC timer based calibration
-	 */
-	if (!pm_referenced) {
-		apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
-
-		/*
-		 * Setup the apic timer manually
-		 */
-		levt->event_handler = lapic_cal_handler;
-		lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
-		lapic_cal_loops = -1;
-
-		/* Let the interrupts run */
-		local_irq_enable();
-
-		while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
-			cpu_relax();
-
-		/* Stop the lapic timer */
-		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
-
-		/* Jiffies delta */
-		deltaj = lapic_cal_j2 - lapic_cal_j1;
-		apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
-
-		/* Check, if the jiffies result is consistent */
-		if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2)
-			apic_printk(APIC_VERBOSE, "... jiffies result ok\n");
-		else
-			levt->features |= CLOCK_EVT_FEAT_DUMMY;
-	} else
-		local_irq_enable();
-
-	if (levt->features & CLOCK_EVT_FEAT_DUMMY) {
-		pr_warning("APIC timer disabled due to verification failure\n");
-			return -1;
-	}
-
-	return 0;
-}
-
-/*
- * Setup the boot APIC
- *
- * Calibrate and verify the result.
- */
-void __init setup_boot_APIC_clock(void)
-{
-	/*
-	 * The local apic timer can be disabled via the kernel
-	 * commandline or from the CPU detection code. Register the lapic
-	 * timer as a dummy clock event source on SMP systems, so the
-	 * broadcast mechanism is used. On UP systems simply ignore it.
-	 */
-	if (disable_apic_timer) {
-		pr_info("Disabling APIC timer\n");
-		/* No broadcast on UP ! */
-		if (num_possible_cpus() > 1) {
-			lapic_clockevent.mult = 1;
-			setup_APIC_timer();
-		}
-		return;
-	}
-
-	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
-		    "calibrating APIC timer ...\n");
-
-	if (calibrate_APIC_clock()) {
-		/* No broadcast on UP ! */
-		if (num_possible_cpus() > 1)
-			setup_APIC_timer();
-		return;
-	}
-
-	/*
-	 * If nmi_watchdog is set to IO_APIC, we need the
-	 * PIT/HPET going.  Otherwise register lapic as a dummy
-	 * device.
-	 */
-	if (nmi_watchdog != NMI_IO_APIC)
-		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
-	else
-		pr_warning("APIC timer registered as dummy,"
-			" due to nmi_watchdog=%d!\n", nmi_watchdog);
-
-	/* Setup the lapic or request the broadcast */
-	setup_APIC_timer();
-}
-
-void __cpuinit setup_secondary_APIC_clock(void)
-{
-	setup_APIC_timer();
-}
-
-/*
- * The guts of the apic timer interrupt
- */
-static void local_apic_timer_interrupt(void)
-{
-	int cpu = smp_processor_id();
-	struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
-
-	/*
-	 * Normally we should not be here till LAPIC has been initialized but
-	 * in some cases like kdump, its possible that there is a pending LAPIC
-	 * timer interrupt from previous kernel's context and is delivered in
-	 * new kernel the moment interrupts are enabled.
-	 *
-	 * Interrupts are enabled early and LAPIC is setup much later, hence
-	 * its possible that when we get here evt->event_handler is NULL.
-	 * Check for event_handler being NULL and discard the interrupt as
-	 * spurious.
-	 */
-	if (!evt->event_handler) {
-		pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu);
-		/* Switch it off */
-		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
-		return;
-	}
-
-	/*
-	 * the NMI deadlock-detector uses this.
-	 */
-	inc_irq_stat(apic_timer_irqs);
-
-	evt->event_handler(evt);
-}
-
-/*
- * Local APIC timer interrupt. This is the most natural way for doing
- * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesn't support APIC timers]
- *
- * [ if a single-CPU system runs an SMP kernel then we call the local
- *   interrupt as well. Thus we cannot inline the local irq ... ]
- */
-void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-
-	/*
-	 * NOTE! We'd better ACK the irq immediately,
-	 * because timer handling can be slow.
-	 */
-	ack_APIC_irq();
-	/*
-	 * update_process_times() expects us to have done irq_enter().
-	 * Besides, if we don't timer interrupts ignore the global
-	 * interrupt lock, which is the WrongThing (tm) to do.
-	 */
-	exit_idle();
-	irq_enter();
-	local_apic_timer_interrupt();
-	irq_exit();
-
-	set_irq_regs(old_regs);
-}
-
-int setup_profiling_timer(unsigned int multiplier)
-{
-	return -EINVAL;
-}
-
-/*
- * Local APIC start and shutdown
- */
-
-/**
- * clear_local_APIC - shutdown the local APIC
- *
- * This is called, when a CPU is disabled and before rebooting, so the state of
- * the local APIC has no dangling leftovers. Also used to cleanout any BIOS
- * leftovers during boot.
- */
-void clear_local_APIC(void)
-{
-	int maxlvt;
-	u32 v;
-
-	/* APIC hasn't been mapped yet */
-	if (!apic_phys)
-		return;
-
-	maxlvt = lapic_get_maxlvt();
-	/*
-	 * Masking an LVT entry can trigger a local APIC error
-	 * if the vector is zero. Mask LVTERR first to prevent this.
-	 */
-	if (maxlvt >= 3) {
-		v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
-		apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
-	}
-	/*
-	 * Careful: we have to set masks only first to deassert
-	 * any level-triggered sources.
-	 */
-	v = apic_read(APIC_LVTT);
-	apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
-	v = apic_read(APIC_LVT0);
-	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-	v = apic_read(APIC_LVT1);
-	apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
-	if (maxlvt >= 4) {
-		v = apic_read(APIC_LVTPC);
-		apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
-	}
-
-	/* lets not touch this if we didn't frob it */
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
-	if (maxlvt >= 5) {
-		v = apic_read(APIC_LVTTHMR);
-		apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
-	}
-#endif
-	/*
-	 * Clean APIC state for other OSs:
-	 */
-	apic_write(APIC_LVTT, APIC_LVT_MASKED);
-	apic_write(APIC_LVT0, APIC_LVT_MASKED);
-	apic_write(APIC_LVT1, APIC_LVT_MASKED);
-	if (maxlvt >= 3)
-		apic_write(APIC_LVTERR, APIC_LVT_MASKED);
-	if (maxlvt >= 4)
-		apic_write(APIC_LVTPC, APIC_LVT_MASKED);
-
-	/* Integrated APIC (!82489DX) ? */
-	if (lapic_is_integrated()) {
-		if (maxlvt > 3)
-			/* Clear ESR due to Pentium errata 3AP and 11AP */
-			apic_write(APIC_ESR, 0);
-		apic_read(APIC_ESR);
-	}
-}
-
-/**
- * disable_local_APIC - clear and disable the local APIC
- */
-void disable_local_APIC(void)
-{
-	unsigned int value;
-
-	/* APIC hasn't been mapped yet */
-	if (!apic_phys)
-		return;
-
-	clear_local_APIC();
-
-	/*
-	 * Disable APIC (implies clearing of registers
-	 * for 82489DX!).
-	 */
-	value = apic_read(APIC_SPIV);
-	value &= ~APIC_SPIV_APIC_ENABLED;
-	apic_write(APIC_SPIV, value);
-
-#ifdef CONFIG_X86_32
-	/*
-	 * When LAPIC was disabled by the BIOS and enabled by the kernel,
-	 * restore the disabled state.
-	 */
-	if (enabled_via_apicbase) {
-		unsigned int l, h;
-
-		rdmsr(MSR_IA32_APICBASE, l, h);
-		l &= ~MSR_IA32_APICBASE_ENABLE;
-		wrmsr(MSR_IA32_APICBASE, l, h);
-	}
-#endif
-}
-
-/*
- * If Linux enabled the LAPIC against the BIOS default disable it down before
- * re-entering the BIOS on shutdown.  Otherwise the BIOS may get confused and
- * not power-off.  Additionally clear all LVT entries before disable_local_APIC
- * for the case where Linux didn't enable the LAPIC.
- */
-void lapic_shutdown(void)
-{
-	unsigned long flags;
-
-	if (!cpu_has_apic)
-		return;
-
-	local_irq_save(flags);
-
-#ifdef CONFIG_X86_32
-	if (!enabled_via_apicbase)
-		clear_local_APIC();
-	else
-#endif
-		disable_local_APIC();
-
-
-	local_irq_restore(flags);
-}
-
-/*
- * This is to verify that we're looking at a real local APIC.
- * Check these against your board if the CPUs aren't getting
- * started for no apparent reason.
- */
-int __init verify_local_APIC(void)
-{
-	unsigned int reg0, reg1;
-
-	/*
-	 * The version register is read-only in a real APIC.
-	 */
-	reg0 = apic_read(APIC_LVR);
-	apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
-	apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
-	reg1 = apic_read(APIC_LVR);
-	apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
-
-	/*
-	 * The two version reads above should print the same
-	 * numbers.  If the second one is different, then we
-	 * poke at a non-APIC.
-	 */
-	if (reg1 != reg0)
-		return 0;
-
-	/*
-	 * Check if the version looks reasonably.
-	 */
-	reg1 = GET_APIC_VERSION(reg0);
-	if (reg1 == 0x00 || reg1 == 0xff)
-		return 0;
-	reg1 = lapic_get_maxlvt();
-	if (reg1 < 0x02 || reg1 == 0xff)
-		return 0;
-
-	/*
-	 * The ID register is read/write in a real APIC.
-	 */
-	reg0 = apic_read(APIC_ID);
-	apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
-	apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
-	reg1 = apic_read(APIC_ID);
-	apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
-	apic_write(APIC_ID, reg0);
-	if (reg1 != (reg0 ^ APIC_ID_MASK))
-		return 0;
-
-	/*
-	 * The next two are just to see if we have sane values.
-	 * They're only really relevant if we're in Virtual Wire
-	 * compatibility mode, but most boxes are anymore.
-	 */
-	reg0 = apic_read(APIC_LVT0);
-	apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
-	reg1 = apic_read(APIC_LVT1);
-	apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
-
-	return 1;
-}
-
-/**
- * sync_Arb_IDs - synchronize APIC bus arbitration IDs
- */
-void __init sync_Arb_IDs(void)
-{
-	/*
-	 * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not
-	 * needed on AMD.
-	 */
-	if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-		return;
-
-	/*
-	 * Wait for idle.
-	 */
-	apic_wait_icr_idle();
-
-	apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
-	apic_write(APIC_ICR, APIC_DEST_ALLINC |
-			APIC_INT_LEVELTRIG | APIC_DM_INIT);
-}
-
-/*
- * An initial setup of the virtual wire mode.
- */
-void __init init_bsp_APIC(void)
-{
-	unsigned int value;
-
-	/*
-	 * Don't do the setup now if we have a SMP BIOS as the
-	 * through-I/O-APIC virtual wire mode might be active.
-	 */
-	if (smp_found_config || !cpu_has_apic)
-		return;
-
-	/*
-	 * Do not trust the local APIC being empty at bootup.
-	 */
-	clear_local_APIC();
-
-	/*
-	 * Enable APIC.
-	 */
-	value = apic_read(APIC_SPIV);
-	value &= ~APIC_VECTOR_MASK;
-	value |= APIC_SPIV_APIC_ENABLED;
-
-#ifdef CONFIG_X86_32
-	/* This bit is reserved on P4/Xeon and should be cleared */
-	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-	    (boot_cpu_data.x86 == 15))
-		value &= ~APIC_SPIV_FOCUS_DISABLED;
-	else
-#endif
-		value |= APIC_SPIV_FOCUS_DISABLED;
-	value |= SPURIOUS_APIC_VECTOR;
-	apic_write(APIC_SPIV, value);
-
-	/*
-	 * Set up the virtual wire mode.
-	 */
-	apic_write(APIC_LVT0, APIC_DM_EXTINT);
-	value = APIC_DM_NMI;
-	if (!lapic_is_integrated())		/* 82489DX */
-		value |= APIC_LVT_LEVEL_TRIGGER;
-	apic_write(APIC_LVT1, value);
-}
-
-static void __cpuinit lapic_setup_esr(void)
-{
-	unsigned int oldvalue, value, maxlvt;
-
-	if (!lapic_is_integrated()) {
-		pr_info("No ESR for 82489DX.\n");
-		return;
-	}
-
-	if (esr_disable) {
-		/*
-		 * Something untraceable is creating bad interrupts on
-		 * secondary quads ... for the moment, just leave the
-		 * ESR disabled - we can't do anything useful with the
-		 * errors anyway - mbligh
-		 */
-		pr_info("Leaving ESR disabled.\n");
-		return;
-	}
-
-	maxlvt = lapic_get_maxlvt();
-	if (maxlvt > 3)		/* Due to the Pentium erratum 3AP. */
-		apic_write(APIC_ESR, 0);
-	oldvalue = apic_read(APIC_ESR);
-
-	/* enables sending errors */
-	value = ERROR_APIC_VECTOR;
-	apic_write(APIC_LVTERR, value);
-
-	/*
-	 * spec says clear errors after enabling vector.
-	 */
-	if (maxlvt > 3)
-		apic_write(APIC_ESR, 0);
-	value = apic_read(APIC_ESR);
-	if (value != oldvalue)
-		apic_printk(APIC_VERBOSE, "ESR value before enabling "
-			"vector: 0x%08x  after: 0x%08x\n",
-			oldvalue, value);
-}
-
-
-/**
- * setup_local_APIC - setup the local APIC
- */
-void __cpuinit setup_local_APIC(void)
-{
-	unsigned int value;
-	int i, j;
-
-#ifdef CONFIG_X86_32
-	/* Pound the ESR really hard over the head with a big hammer - mbligh */
-	if (lapic_is_integrated() && esr_disable) {
-		apic_write(APIC_ESR, 0);
-		apic_write(APIC_ESR, 0);
-		apic_write(APIC_ESR, 0);
-		apic_write(APIC_ESR, 0);
-	}
-#endif
-
-	preempt_disable();
-
-	/*
-	 * Double-check whether this APIC is really registered.
-	 * This is meaningless in clustered apic mode, so we skip it.
-	 */
-	if (!apic_id_registered())
-		BUG();
-
-	/*
-	 * Intel recommends to set DFR, LDR and TPR before enabling
-	 * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
-	 * document number 292116).  So here it goes...
-	 */
-	init_apic_ldr();
-
-	/*
-	 * Set Task Priority to 'accept all'. We never change this
-	 * later on.
-	 */
-	value = apic_read(APIC_TASKPRI);
-	value &= ~APIC_TPRI_MASK;
-	apic_write(APIC_TASKPRI, value);
-
-	/*
-	 * After a crash, we no longer service the interrupts and a pending
-	 * interrupt from previous kernel might still have ISR bit set.
-	 *
-	 * Most probably by now CPU has serviced that pending interrupt and
-	 * it might not have done the ack_APIC_irq() because it thought,
-	 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
-	 * does not clear the ISR bit and cpu thinks it has already serivced
-	 * the interrupt. Hence a vector might get locked. It was noticed
-	 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
-	 */
-	for (i = APIC_ISR_NR - 1; i >= 0; i--) {
-		value = apic_read(APIC_ISR + i*0x10);
-		for (j = 31; j >= 0; j--) {
-			if (value & (1<<j))
-				ack_APIC_irq();
-		}
-	}
-
-	/*
-	 * Now that we are all set up, enable the APIC
-	 */
-	value = apic_read(APIC_SPIV);
-	value &= ~APIC_VECTOR_MASK;
-	/*
-	 * Enable APIC
-	 */
-	value |= APIC_SPIV_APIC_ENABLED;
-
-#ifdef CONFIG_X86_32
-	/*
-	 * Some unknown Intel IO/APIC (or APIC) errata is biting us with
-	 * certain networking cards. If high frequency interrupts are
-	 * happening on a particular IOAPIC pin, plus the IOAPIC routing
-	 * entry is masked/unmasked at a high rate as well then sooner or
-	 * later IOAPIC line gets 'stuck', no more interrupts are received
-	 * from the device. If focus CPU is disabled then the hang goes
-	 * away, oh well :-(
-	 *
-	 * [ This bug can be reproduced easily with a level-triggered
-	 *   PCI Ne2000 networking cards and PII/PIII processors, dual
-	 *   BX chipset. ]
-	 */
-	/*
-	 * Actually disabling the focus CPU check just makes the hang less
-	 * frequent as it makes the interrupt distributon model be more
-	 * like LRU than MRU (the short-term load is more even across CPUs).
-	 * See also the comment in end_level_ioapic_irq().  --macro
-	 */
-
-	/*
-	 * - enable focus processor (bit==0)
-	 * - 64bit mode always use processor focus
-	 *   so no need to set it
-	 */
-	value &= ~APIC_SPIV_FOCUS_DISABLED;
-#endif
-
-	/*
-	 * Set spurious IRQ vector
-	 */
-	value |= SPURIOUS_APIC_VECTOR;
-	apic_write(APIC_SPIV, value);
-
-	/*
-	 * Set up LVT0, LVT1:
-	 *
-	 * set up through-local-APIC on the BP's LINT0. This is not
-	 * strictly necessary in pure symmetric-IO mode, but sometimes
-	 * we delegate interrupts to the 8259A.
-	 */
-	/*
-	 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
-	 */
-	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
-	if (!smp_processor_id() && (pic_mode || !value)) {
-		value = APIC_DM_EXTINT;
-		apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
-				smp_processor_id());
-	} else {
-		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
-		apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
-				smp_processor_id());
-	}
-	apic_write(APIC_LVT0, value);
-
-	/*
-	 * only the BP should see the LINT1 NMI signal, obviously.
-	 */
-	if (!smp_processor_id())
-		value = APIC_DM_NMI;
-	else
-		value = APIC_DM_NMI | APIC_LVT_MASKED;
-	if (!lapic_is_integrated())		/* 82489DX */
-		value |= APIC_LVT_LEVEL_TRIGGER;
-	apic_write(APIC_LVT1, value);
-
-	preempt_enable();
-}
-
-void __cpuinit end_local_APIC_setup(void)
-{
-	lapic_setup_esr();
-
-#ifdef CONFIG_X86_32
-	{
-		unsigned int value;
-		/* Disable the local apic timer */
-		value = apic_read(APIC_LVTT);
-		value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-		apic_write(APIC_LVTT, value);
-	}
-#endif
-
-	setup_apic_nmi_watchdog(NULL);
-	apic_pm_activate();
-}
-
-#ifdef HAVE_X2APIC
-void check_x2apic(void)
-{
-	int msr, msr2;
-
-	rdmsr(MSR_IA32_APICBASE, msr, msr2);
-
-	if (msr & X2APIC_ENABLE) {
-		pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
-		x2apic_preenabled = x2apic = 1;
-		apic_ops = &x2apic_ops;
-	}
-}
-
-void enable_x2apic(void)
-{
-	int msr, msr2;
-
-	rdmsr(MSR_IA32_APICBASE, msr, msr2);
-	if (!(msr & X2APIC_ENABLE)) {
-		pr_info("Enabling x2apic\n");
-		wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
-	}
-}
-
-void __init enable_IR_x2apic(void)
-{
-#ifdef CONFIG_INTR_REMAP
-	int ret;
-	unsigned long flags;
-
-	if (!cpu_has_x2apic)
-		return;
-
-	if (!x2apic_preenabled && disable_x2apic) {
-		pr_info("Skipped enabling x2apic and Interrupt-remapping "
-			"because of nox2apic\n");
-		return;
-	}
-
-	if (x2apic_preenabled && disable_x2apic)
-		panic("Bios already enabled x2apic, can't enforce nox2apic");
-
-	if (!x2apic_preenabled && skip_ioapic_setup) {
-		pr_info("Skipped enabling x2apic and Interrupt-remapping "
-			"because of skipping io-apic setup\n");
-		return;
-	}
-
-	ret = dmar_table_init();
-	if (ret) {
-		pr_info("dmar_table_init() failed with %d:\n", ret);
-
-		if (x2apic_preenabled)
-			panic("x2apic enabled by bios. But IR enabling failed");
-		else
-			pr_info("Not enabling x2apic,Intr-remapping\n");
-		return;
-	}
-
-	local_irq_save(flags);
-	mask_8259A();
-
-	ret = save_mask_IO_APIC_setup();
-	if (ret) {
-		pr_info("Saving IO-APIC state failed: %d\n", ret);
-		goto end;
-	}
-
-	ret = enable_intr_remapping(1);
-
-	if (ret && x2apic_preenabled) {
-		local_irq_restore(flags);
-		panic("x2apic enabled by bios. But IR enabling failed");
-	}
-
-	if (ret)
-		goto end_restore;
-
-	if (!x2apic) {
-		x2apic = 1;
-		apic_ops = &x2apic_ops;
-		enable_x2apic();
-	}
-
-end_restore:
-	if (ret)
-		/*
-		 * IR enabling failed
-		 */
-		restore_IO_APIC_setup();
-	else
-		reinit_intr_remapped_IO_APIC(x2apic_preenabled);
-
-end:
-	unmask_8259A();
-	local_irq_restore(flags);
-
-	if (!ret) {
-		if (!x2apic_preenabled)
-			pr_info("Enabled x2apic and interrupt-remapping\n");
-		else
-			pr_info("Enabled Interrupt-remapping\n");
-	} else
-		pr_err("Failed to enable Interrupt-remapping and x2apic\n");
-#else
-	if (!cpu_has_x2apic)
-		return;
-
-	if (x2apic_preenabled)
-		panic("x2apic enabled prior OS handover,"
-		      " enable CONFIG_INTR_REMAP");
-
-	pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
-		" and x2apic\n");
-#endif
-
-	return;
-}
-#endif /* HAVE_X2APIC */
-
-#ifdef CONFIG_X86_64
-/*
- * Detect and enable local APICs on non-SMP boards.
- * Original code written by Keir Fraser.
- * On AMD64 we trust the BIOS - if it says no APIC it is likely
- * not correctly set up (usually the APIC timer won't work etc.)
- */
-static int __init detect_init_APIC(void)
-{
-	if (!cpu_has_apic) {
-		pr_info("No local APIC present\n");
-		return -1;
-	}
-
-	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-	boot_cpu_physical_apicid = 0;
-	return 0;
-}
-#else
-/*
- * Detect and initialize APIC
- */
-static int __init detect_init_APIC(void)
-{
-	u32 h, l, features;
-
-	/* Disabled by kernel option? */
-	if (disable_apic)
-		return -1;
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
-		    (boot_cpu_data.x86 >= 15))
-			break;
-		goto no_apic;
-	case X86_VENDOR_INTEL:
-		if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
-		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
-			break;
-		goto no_apic;
-	default:
-		goto no_apic;
-	}
-
-	if (!cpu_has_apic) {
-		/*
-		 * Over-ride BIOS and try to enable the local APIC only if
-		 * "lapic" specified.
-		 */
-		if (!force_enable_local_apic) {
-			pr_info("Local APIC disabled by BIOS -- "
-				"you can enable it with \"lapic\"\n");
-			return -1;
-		}
-		/*
-		 * Some BIOSes disable the local APIC in the APIC_BASE
-		 * MSR. This can only be done in software for Intel P6 or later
-		 * and AMD K7 (Model > 1) or later.
-		 */
-		rdmsr(MSR_IA32_APICBASE, l, h);
-		if (!(l & MSR_IA32_APICBASE_ENABLE)) {
-			pr_info("Local APIC disabled by BIOS -- reenabling.\n");
-			l &= ~MSR_IA32_APICBASE_BASE;
-			l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
-			wrmsr(MSR_IA32_APICBASE, l, h);
-			enabled_via_apicbase = 1;
-		}
-	}
-	/*
-	 * The APIC feature bit should now be enabled
-	 * in `cpuid'
-	 */
-	features = cpuid_edx(1);
-	if (!(features & (1 << X86_FEATURE_APIC))) {
-		pr_warning("Could not enable APIC!\n");
-		return -1;
-	}
-	set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
-	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
-	/* The BIOS may have set up the APIC at some other address */
-	rdmsr(MSR_IA32_APICBASE, l, h);
-	if (l & MSR_IA32_APICBASE_ENABLE)
-		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
-
-	pr_info("Found and enabled local APIC!\n");
-
-	apic_pm_activate();
-
-	return 0;
-
-no_apic:
-	pr_info("No local APIC present or hardware disabled\n");
-	return -1;
-}
-#endif
-
-#ifdef CONFIG_X86_64
-void __init early_init_lapic_mapping(void)
-{
-	unsigned long phys_addr;
-
-	/*
-	 * If no local APIC can be found then go out
-	 * : it means there is no mpatable and MADT
-	 */
-	if (!smp_found_config)
-		return;
-
-	phys_addr = mp_lapic_addr;
-
-	set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
-	apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
-		    APIC_BASE, phys_addr);
-
-	/*
-	 * Fetch the APIC ID of the BSP in case we have a
-	 * default configuration (or the MP table is broken).
-	 */
-	boot_cpu_physical_apicid = read_apic_id();
-}
-#endif
-
-/**
- * init_apic_mappings - initialize APIC mappings
- */
-void __init init_apic_mappings(void)
-{
-#ifdef HAVE_X2APIC
-	if (x2apic) {
-		boot_cpu_physical_apicid = read_apic_id();
-		return;
-	}
-#endif
-
-	/*
-	 * If no local APIC can be found then set up a fake all
-	 * zeroes page to simulate the local APIC and another
-	 * one for the IO-APIC.
-	 */
-	if (!smp_found_config && detect_init_APIC()) {
-		apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
-		apic_phys = __pa(apic_phys);
-	} else
-		apic_phys = mp_lapic_addr;
-
-	set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
-	apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
-				APIC_BASE, apic_phys);
-
-	/*
-	 * Fetch the APIC ID of the BSP in case we have a
-	 * default configuration (or the MP table is broken).
-	 */
-	if (boot_cpu_physical_apicid == -1U)
-		boot_cpu_physical_apicid = read_apic_id();
-}
-
-/*
- * This initializes the IO-APIC and APIC hardware if this is
- * a UP kernel.
- */
-int apic_version[MAX_APICS];
-
-int __init APIC_init_uniprocessor(void)
-{
-#ifdef CONFIG_X86_64
-	if (disable_apic) {
-		pr_info("Apic disabled\n");
-		return -1;
-	}
-	if (!cpu_has_apic) {
-		disable_apic = 1;
-		pr_info("Apic disabled by BIOS\n");
-		return -1;
-	}
-#else
-	if (!smp_found_config && !cpu_has_apic)
-		return -1;
-
-	/*
-	 * Complain if the BIOS pretends there is one.
-	 */
-	if (!cpu_has_apic &&
-	    APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
-		pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
-			boot_cpu_physical_apicid);
-		clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
-		return -1;
-	}
-#endif
-
-#ifdef HAVE_X2APIC
-	enable_IR_x2apic();
-#endif
-#ifdef CONFIG_X86_64
-	setup_apic_routing();
-#endif
-
-	verify_local_APIC();
-	connect_bsp_APIC();
-
-#ifdef CONFIG_X86_64
-	apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
-#else
-	/*
-	 * Hack: In case of kdump, after a crash, kernel might be booting
-	 * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
-	 * might be zero if read from MP tables. Get it from LAPIC.
-	 */
-# ifdef CONFIG_CRASH_DUMP
-	boot_cpu_physical_apicid = read_apic_id();
-# endif
-#endif
-	physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
-	setup_local_APIC();
-
-#ifdef CONFIG_X86_64
-	/*
-	 * Now enable IO-APICs, actually call clear_IO_APIC
-	 * We need clear_IO_APIC before enabling vector on BP
-	 */
-	if (!skip_ioapic_setup && nr_ioapics)
-		enable_IO_APIC();
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
-	if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
-#endif
-		localise_nmi_watchdog();
-	end_local_APIC_setup();
-
-#ifdef CONFIG_X86_IO_APIC
-	if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
-		setup_IO_APIC();
-# ifdef CONFIG_X86_64
-	else
-		nr_ioapics = 0;
-# endif
-#endif
-
-#ifdef CONFIG_X86_64
-	setup_boot_APIC_clock();
-	check_nmi_watchdog();
-#else
-	setup_boot_clock();
-#endif
-
-	return 0;
-}
-
-/*
- * Local APIC interrupts
- */
-
-/*
- * This interrupt should _never_ happen with our APIC/SMP architecture
- */
-void smp_spurious_interrupt(struct pt_regs *regs)
-{
-	u32 v;
-
-	exit_idle();
-	irq_enter();
-	/*
-	 * Check if this really is a spurious interrupt and ACK it
-	 * if it is a vectored one.  Just in case...
-	 * Spurious interrupts should not be ACKed.
-	 */
-	v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
-	if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
-		ack_APIC_irq();
-
-	inc_irq_stat(irq_spurious_count);
-
-	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
-	pr_info("spurious APIC interrupt on CPU#%d, "
-		"should never happen.\n", smp_processor_id());
-	irq_exit();
-}
-
-/*
- * This interrupt should never happen with our APIC/SMP architecture
- */
-void smp_error_interrupt(struct pt_regs *regs)
-{
-	u32 v, v1;
-
-	exit_idle();
-	irq_enter();
-	/* First tickle the hardware, only then report what went on. -- REW */
-	v = apic_read(APIC_ESR);
-	apic_write(APIC_ESR, 0);
-	v1 = apic_read(APIC_ESR);
-	ack_APIC_irq();
-	atomic_inc(&irq_err_count);
-
-	/*
-	 * Here is what the APIC error bits mean:
-	 * 0: Send CS error
-	 * 1: Receive CS error
-	 * 2: Send accept error
-	 * 3: Receive accept error
-	 * 4: Reserved
-	 * 5: Send illegal vector
-	 * 6: Received illegal vector
-	 * 7: Illegal register address
-	 */
-	pr_debug("APIC error on CPU%d: %02x(%02x)\n",
-		smp_processor_id(), v , v1);
-	irq_exit();
-}
-
-/**
- * connect_bsp_APIC - attach the APIC to the interrupt system
- */
-void __init connect_bsp_APIC(void)
-{
-#ifdef CONFIG_X86_32
-	if (pic_mode) {
-		/*
-		 * Do not trust the local APIC being empty at bootup.
-		 */
-		clear_local_APIC();
-		/*
-		 * PIC mode, enable APIC mode in the IMCR, i.e.  connect BSP's
-		 * local APIC to INT and NMI lines.
-		 */
-		apic_printk(APIC_VERBOSE, "leaving PIC mode, "
-				"enabling APIC mode.\n");
-		outb(0x70, 0x22);
-		outb(0x01, 0x23);
-	}
-#endif
-	enable_apic_mode();
-}
-
-/**
- * disconnect_bsp_APIC - detach the APIC from the interrupt system
- * @virt_wire_setup:	indicates, whether virtual wire mode is selected
- *
- * Virtual wire mode is necessary to deliver legacy interrupts even when the
- * APIC is disabled.
- */
-void disconnect_bsp_APIC(int virt_wire_setup)
-{
-	unsigned int value;
-
-#ifdef CONFIG_X86_32
-	if (pic_mode) {
-		/*
-		 * Put the board back into PIC mode (has an effect only on
-		 * certain older boards).  Note that APIC interrupts, including
-		 * IPIs, won't work beyond this point!  The only exception are
-		 * INIT IPIs.
-		 */
-		apic_printk(APIC_VERBOSE, "disabling APIC mode, "
-				"entering PIC mode.\n");
-		outb(0x70, 0x22);
-		outb(0x00, 0x23);
-		return;
-	}
-#endif
-
-	/* Go back to Virtual Wire compatibility mode */
-
-	/* For the spurious interrupt use vector F, and enable it */
-	value = apic_read(APIC_SPIV);
-	value &= ~APIC_VECTOR_MASK;
-	value |= APIC_SPIV_APIC_ENABLED;
-	value |= 0xf;
-	apic_write(APIC_SPIV, value);
-
-	if (!virt_wire_setup) {
-		/*
-		 * For LVT0 make it edge triggered, active high,
-		 * external and enabled
-		 */
-		value = apic_read(APIC_LVT0);
-		value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
-			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
-			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
-		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
-		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
-		apic_write(APIC_LVT0, value);
-	} else {
-		/* Disable LVT0 */
-		apic_write(APIC_LVT0, APIC_LVT_MASKED);
-	}
-
-	/*
-	 * For LVT1 make it edge triggered, active high,
-	 * nmi and enabled
-	 */
-	value = apic_read(APIC_LVT1);
-	value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
-			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
-			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
-	value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
-	value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
-	apic_write(APIC_LVT1, value);
-}
-
-void __cpuinit generic_processor_info(int apicid, int version)
-{
-	int cpu;
-
-	/*
-	 * Validate version
-	 */
-	if (version == 0x0) {
-		pr_warning("BIOS bug, APIC version is 0 for CPU#%d! "
-			   "fixing up to 0x10. (tell your hw vendor)\n",
-				version);
-		version = 0x10;
-	}
-	apic_version[apicid] = version;
-
-	if (num_processors >= nr_cpu_ids) {
-		int max = nr_cpu_ids;
-		int thiscpu = max + disabled_cpus;
-
-		pr_warning(
-			"ACPI: NR_CPUS/possible_cpus limit of %i reached."
-			"  Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
-
-		disabled_cpus++;
-		return;
-	}
-
-	num_processors++;
-	cpu = cpumask_next_zero(-1, cpu_present_mask);
-
-	if (version != apic_version[boot_cpu_physical_apicid])
-		WARN_ONCE(1,
-			"ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n",
-			apic_version[boot_cpu_physical_apicid], cpu, version);
-
-	physid_set(apicid, phys_cpu_present_map);
-	if (apicid == boot_cpu_physical_apicid) {
-		/*
-		 * x86_bios_cpu_apicid is required to have processors listed
-		 * in same order as logical cpu numbers. Hence the first
-		 * entry is BSP, and so on.
-		 */
-		cpu = 0;
-	}
-	if (apicid > max_physical_apicid)
-		max_physical_apicid = apicid;
-
-#ifdef CONFIG_X86_32
-	/*
-	 * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
-	 * but we need to work other dependencies like SMP_SUSPEND etc
-	 * before this can be done without some confusion.
-	 * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
-	 *       - Ashok Raj <ashok.raj@intel.com>
-	 */
-	if (max_physical_apicid >= 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;
-		}
-	}
-#endif
-
-#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64)
-	/* are we being called early in kernel startup? */
-	if (early_per_cpu_ptr(x86_cpu_to_apicid)) {
-		u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
-		u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-
-		cpu_to_apicid[cpu] = apicid;
-		bios_cpu_apicid[cpu] = apicid;
-	} else {
-		per_cpu(x86_cpu_to_apicid, cpu) = apicid;
-		per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
-	}
-#endif
-
-	set_cpu_possible(cpu, true);
-	set_cpu_present(cpu, true);
-}
-
-#ifdef CONFIG_X86_64
-int hard_smp_processor_id(void)
-{
-	return read_apic_id();
-}
-#endif
-
-/*
- * Power management
- */
-#ifdef CONFIG_PM
-
-static struct {
-	/*
-	 * 'active' is true if the local APIC was enabled by us and
-	 * not the BIOS; this signifies that we are also responsible
-	 * for disabling it before entering apm/acpi suspend
-	 */
-	int active;
-	/* r/w apic fields */
-	unsigned int apic_id;
-	unsigned int apic_taskpri;
-	unsigned int apic_ldr;
-	unsigned int apic_dfr;
-	unsigned int apic_spiv;
-	unsigned int apic_lvtt;
-	unsigned int apic_lvtpc;
-	unsigned int apic_lvt0;
-	unsigned int apic_lvt1;
-	unsigned int apic_lvterr;
-	unsigned int apic_tmict;
-	unsigned int apic_tdcr;
-	unsigned int apic_thmr;
-} apic_pm_state;
-
-static int lapic_suspend(struct sys_device *dev, pm_message_t state)
-{
-	unsigned long flags;
-	int maxlvt;
-
-	if (!apic_pm_state.active)
-		return 0;
-
-	maxlvt = lapic_get_maxlvt();
-
-	apic_pm_state.apic_id = apic_read(APIC_ID);
-	apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
-	apic_pm_state.apic_ldr = apic_read(APIC_LDR);
-	apic_pm_state.apic_dfr = apic_read(APIC_DFR);
-	apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
-	apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
-	if (maxlvt >= 4)
-		apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
-	apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
-	apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
-	apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
-	apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
-	apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
-	if (maxlvt >= 5)
-		apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
-#endif
-
-	local_irq_save(flags);
-	disable_local_APIC();
-	local_irq_restore(flags);
-	return 0;
-}
-
-static int lapic_resume(struct sys_device *dev)
-{
-	unsigned int l, h;
-	unsigned long flags;
-	int maxlvt;
-
-	if (!apic_pm_state.active)
-		return 0;
-
-	maxlvt = lapic_get_maxlvt();
-
-	local_irq_save(flags);
-
-#ifdef HAVE_X2APIC
-	if (x2apic)
-		enable_x2apic();
-	else
-#endif
-	{
-		/*
-		 * Make sure the APICBASE points to the right address
-		 *
-		 * FIXME! This will be wrong if we ever support suspend on
-		 * SMP! We'll need to do this as part of the CPU restore!
-		 */
-		rdmsr(MSR_IA32_APICBASE, l, h);
-		l &= ~MSR_IA32_APICBASE_BASE;
-		l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
-		wrmsr(MSR_IA32_APICBASE, l, h);
-	}
-
-	apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
-	apic_write(APIC_ID, apic_pm_state.apic_id);
-	apic_write(APIC_DFR, apic_pm_state.apic_dfr);
-	apic_write(APIC_LDR, apic_pm_state.apic_ldr);
-	apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri);
-	apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
-	apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
-	apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
-	if (maxlvt >= 5)
-		apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
-#endif
-	if (maxlvt >= 4)
-		apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
-	apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
-	apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
-	apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
-	apic_write(APIC_ESR, 0);
-	apic_read(APIC_ESR);
-	apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
-	apic_write(APIC_ESR, 0);
-	apic_read(APIC_ESR);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-/*
- * This device has no shutdown method - fully functioning local APICs
- * are needed on every CPU up until machine_halt/restart/poweroff.
- */
-
-static struct sysdev_class lapic_sysclass = {
-	.name		= "lapic",
-	.resume		= lapic_resume,
-	.suspend	= lapic_suspend,
-};
-
-static struct sys_device device_lapic = {
-	.id	= 0,
-	.cls	= &lapic_sysclass,
-};
-
-static void __cpuinit apic_pm_activate(void)
-{
-	apic_pm_state.active = 1;
-}
-
-static int __init init_lapic_sysfs(void)
-{
-	int error;
-
-	if (!cpu_has_apic)
-		return 0;
-	/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
-
-	error = sysdev_class_register(&lapic_sysclass);
-	if (!error)
-		error = sysdev_register(&device_lapic);
-	return error;
-}
-device_initcall(init_lapic_sysfs);
-
-#else	/* CONFIG_PM */
-
-static void apic_pm_activate(void) { }
-
-#endif	/* CONFIG_PM */
-
-#ifdef CONFIG_X86_64
-/*
- * apic_is_clustered_box() -- Check if we can expect good TSC
- *
- * Thus far, the major user of this is IBM's Summit2 series:
- *
- * Clustered boxes may have unsynced TSC problems if they are
- * multi-chassis. Use available data to take a good guess.
- * If in doubt, go HPET.
- */
-__cpuinit int apic_is_clustered_box(void)
-{
-	int i, clusters, zeros;
-	unsigned id;
-	u16 *bios_cpu_apicid;
-	DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
-
-	/*
-	 * there is not this kind of box with AMD CPU yet.
-	 * Some AMD box with quadcore cpu and 8 sockets apicid
-	 * will be [4, 0x23] or [8, 0x27] could be thought to
-	 * vsmp box still need checking...
-	 */
-	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
-		return 0;
-
-	bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-	bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
-
-	for (i = 0; i < nr_cpu_ids; i++) {
-		/* are we being called early in kernel startup? */
-		if (bios_cpu_apicid) {
-			id = bios_cpu_apicid[i];
-		} else if (i < nr_cpu_ids) {
-			if (cpu_present(i))
-				id = per_cpu(x86_bios_cpu_apicid, i);
-			else
-				continue;
-		} else
-			break;
-
-		if (id != BAD_APICID)
-			__set_bit(APIC_CLUSTERID(id), clustermap);
-	}
-
-	/* Problem:  Partially populated chassis may not have CPUs in some of
-	 * the APIC clusters they have been allocated.  Only present CPUs have
-	 * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
-	 * Since clusters are allocated sequentially, count zeros only if
-	 * they are bounded by ones.
-	 */
-	clusters = 0;
-	zeros = 0;
-	for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
-		if (test_bit(i, clustermap)) {
-			clusters += 1 + zeros;
-			zeros = 0;
-		} else
-			++zeros;
-	}
-
-	/* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
-	 * not guaranteed to be synced between boards
-	 */
-	if (is_vsmp_box() && clusters > 1)
-		return 1;
-
-	/*
-	 * If clusters > 2, then should be multi-chassis.
-	 * May have to revisit this when multi-core + hyperthreaded CPUs come
-	 * out, but AFAIK this will work even for them.
-	 */
-	return (clusters > 2);
-}
-#endif
-
-/*
- * APIC command line parameters
- */
-static int __init setup_disableapic(char *arg)
-{
-	disable_apic = 1;
-	setup_clear_cpu_cap(X86_FEATURE_APIC);
-	return 0;
-}
-early_param("disableapic", setup_disableapic);
-
-/* same as disableapic, for compatibility */
-static int __init setup_nolapic(char *arg)
-{
-	return setup_disableapic(arg);
-}
-early_param("nolapic", setup_nolapic);
-
-static int __init parse_lapic_timer_c2_ok(char *arg)
-{
-	local_apic_timer_c2_ok = 1;
-	return 0;
-}
-early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
-
-static int __init parse_disable_apic_timer(char *arg)
-{
-	disable_apic_timer = 1;
-	return 0;
-}
-early_param("noapictimer", parse_disable_apic_timer);
-
-static int __init parse_nolapic_timer(char *arg)
-{
-	disable_apic_timer = 1;
-	return 0;
-}
-early_param("nolapic_timer", parse_nolapic_timer);
-
-static int __init apic_set_verbosity(char *arg)
-{
-	if (!arg)  {
-#ifdef CONFIG_X86_64
-		skip_ioapic_setup = 0;
-		return 0;
-#endif
-		return -EINVAL;
-	}
-
-	if (strcmp("debug", arg) == 0)
-		apic_verbosity = APIC_DEBUG;
-	else if (strcmp("verbose", arg) == 0)
-		apic_verbosity = APIC_VERBOSE;
-	else {
-		pr_warning("APIC Verbosity level %s not recognised"
-			" use apic=verbose or apic=debug\n", arg);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-early_param("apic", apic_set_verbosity);
-
-static int __init lapic_insert_resource(void)
-{
-	if (!apic_phys)
-		return -1;
-
-	/* Put local APIC into the resource map. */
-	lapic_resource.start = apic_phys;
-	lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
-	insert_resource(&iomem_resource, &lapic_resource);
-
-	return 0;
-}
-
-/*
- * need call insert after e820_reserve_resources()
- * that is using request_resource
- */
-late_initcall(lapic_insert_resource);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/apm_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/apm_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/apm_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/apm_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -301,7 +301,7 @@ extern int (*console_blank_hook)(int);
  */
 #define APM_ZERO_SEGS
 
-#include "apm.h"
+#include <asm/apm.h>
 
 /*
  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
@@ -466,7 +466,7 @@ static const lookup_t error_table[] = {
  *	@err: APM BIOS return code
  *
  *	Write a meaningful log entry to the kernel log in the event of
- *	an APM error.
+ *	an APM error.  Note that this also handles (negative) kernel errors.
  */
 
 static void apm_error(char *str, int err)
@@ -478,43 +478,14 @@ static void apm_error(char *str, int err
 			break;
 	if (i < ERROR_COUNT)
 		printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
+	else if (err < 0)
+		printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err);
 	else
 		printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
 		       str, err);
 }
 
 /*
- * Lock APM functionality to physical CPU 0
- */
-
-#ifdef CONFIG_SMP
-
-static cpumask_t apm_save_cpus(void)
-{
-	cpumask_t x = current->cpus_allowed;
-	/* Some bioses don't like being called from CPU != 0 */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
-	BUG_ON(smp_processor_id() != 0);
-	return x;
-}
-
-static inline void apm_restore_cpus(cpumask_t mask)
-{
-	set_cpus_allowed(current, mask);
-}
-
-#else
-
-/*
- *	No CPU lockdown needed on a uniprocessor
- */
-
-#define apm_save_cpus()		(current->cpus_allowed)
-#define apm_restore_cpus(x)	(void)(x)
-
-#endif
-
-/*
  * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
  * apm_info.allow_ints, we are being really paranoid here!  Not only
  * are interrupts disabled, but all the segment registers (except SS)
@@ -568,16 +539,23 @@ static inline void apm_irq_restore(unsig
 #	define APM_DO_RESTORE_SEGS
 #endif
 
+struct apm_bios_call {
+	u32 func;
+	/* In and out */
+	u32 ebx;
+	u32 ecx;
+	/* Out only */
+	u32 eax;
+	u32 edx;
+	u32 esi;
+
+	/* Error: -ENOMEM, or bits 8-15 of eax */
+	int err;
+};
+
 /**
- *	apm_bios_call	-	Make an APM BIOS 32bit call
- *	@func: APM function to execute
- *	@ebx_in: EBX register for call entry
- *	@ecx_in: ECX register for call entry
- *	@eax: EAX register return
- *	@ebx: EBX register return
- *	@ecx: ECX register return
- *	@edx: EDX register return
- *	@esi: ESI register return
+ *	__apm_bios_call - Make an APM BIOS 32bit call
+ *	@_call: pointer to struct apm_bios_call.
  *
  *	Make an APM call using the 32bit protected mode interface. The
  *	caller is responsible for knowing if APM BIOS is configured and
@@ -586,80 +564,142 @@ static inline void apm_irq_restore(unsig
  *	flag is loaded into AL.  If there is an error, then the error
  *	code is returned in AH (bits 8-15 of eax) and this function
  *	returns non-zero.
+ *
+ *	Note: this makes the call on the current CPU.
  */
-
-static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
-	u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
+static long __apm_bios_call(void *_call)
 {
 	APM_DECL_SEGS
 	unsigned long		flags;
-	cpumask_t		cpus;
 	int			cpu;
 	struct desc_struct	save_desc_40;
 	struct desc_struct	*gdt;
-
-	cpus = apm_save_cpus();
+	struct apm_bios_call	*call = _call;
 
 	cpu = get_cpu();
+	BUG_ON(cpu != 0);
 	gdt = get_cpu_gdt_table(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
 	apm_irq_save(flags);
 	APM_DO_SAVE_SEGS;
-	apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+	apm_bios_call_asm(call->func, call->ebx, call->ecx,
+			  &call->eax, &call->ebx, &call->ecx, &call->edx,
+			  &call->esi);
 	APM_DO_RESTORE_SEGS;
 	apm_irq_restore(flags);
 	gdt[0x40 / 8] = save_desc_40;
 	put_cpu();
-	apm_restore_cpus(cpus);
 
-	return *eax & 0xff;
+	return call->eax & 0xff;
+}
+
+/* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
+static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
+{
+	int ret;
+
+	/* Don't bother with work_on_cpu in the common case, so we don't
+	 * have to worry about OOM or overhead. */
+	if (get_cpu() == 0) {
+		ret = fn(call);
+		put_cpu();
+	} else {
+		put_cpu();
+		ret = work_on_cpu(0, fn, call);
+	}
+
+	/* work_on_cpu can fail with -ENOMEM */
+	if (ret < 0)
+		call->err = ret;
+	else
+		call->err = (call->eax >> 8) & 0xff;
+
+	return ret;
 }
 
 /**
- *	apm_bios_call_simple	-	make a simple APM BIOS 32bit call
- *	@func: APM function to invoke
- *	@ebx_in: EBX register value for BIOS call
- *	@ecx_in: ECX register value for BIOS call
- *	@eax: EAX register on return from the BIOS call
+ *	apm_bios_call	-	Make an APM BIOS 32bit call (on CPU 0)
+ *	@call: the apm_bios_call registers.
+ *
+ *	If there is an error, it is returned in @call.err.
+ */
+static int apm_bios_call(struct apm_bios_call *call)
+{
+	return on_cpu0(__apm_bios_call, call);
+}
+
+/**
+ *	__apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
+ *	@_call: pointer to struct apm_bios_call.
  *
  *	Make a BIOS call that returns one value only, or just status.
  *	If there is an error, then the error code is returned in AH
- *	(bits 8-15 of eax) and this function returns non-zero. This is
- *	used for simpler BIOS operations. This call may hold interrupts
- *	off for a long time on some laptops.
+ *	(bits 8-15 of eax) and this function returns non-zero (it can
+ *	also return -ENOMEM). This is used for simpler BIOS operations.
+ *	This call may hold interrupts off for a long time on some laptops.
+ *
+ *	Note: this makes the call on the current CPU.
  */
-
-static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
+static long __apm_bios_call_simple(void *_call)
 {
 	u8			error;
 	APM_DECL_SEGS
 	unsigned long		flags;
-	cpumask_t		cpus;
 	int			cpu;
 	struct desc_struct	save_desc_40;
 	struct desc_struct	*gdt;
-
-	cpus = apm_save_cpus();
+	struct apm_bios_call	*call = _call;
 
 	cpu = get_cpu();
+	BUG_ON(cpu != 0);
 	gdt = get_cpu_gdt_table(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
 	apm_irq_save(flags);
 	APM_DO_SAVE_SEGS;
-	error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
+	error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
+					 &call->eax);
 	APM_DO_RESTORE_SEGS;
 	apm_irq_restore(flags);
 	gdt[0x40 / 8] = save_desc_40;
 	put_cpu();
-	apm_restore_cpus(cpus);
 	return error;
 }
 
 /**
+ *	apm_bios_call_simple	-	make a simple APM BIOS 32bit call
+ *	@func: APM function to invoke
+ *	@ebx_in: EBX register value for BIOS call
+ *	@ecx_in: ECX register value for BIOS call
+ *	@eax: EAX register on return from the BIOS call
+ *	@err: bits
+ *
+ *	Make a BIOS call that returns one value only, or just status.
+ *	If there is an error, then the error code is returned in @err
+ *	and this function returns non-zero. This is used for simpler
+ *	BIOS operations.  This call may hold interrupts off for a long
+ *	time on some laptops.
+ */
+static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
+				int *err)
+{
+	struct apm_bios_call call;
+	int ret;
+
+	call.func = func;
+	call.ebx = ebx_in;
+	call.ecx = ecx_in;
+
+	ret = on_cpu0(__apm_bios_call_simple, &call);
+	*eax = call.eax;
+	*err = call.err;
+	return ret;
+}
+
+/**
  *	apm_driver_version	-	APM driver version
  *	@val:	loaded with the APM version on return
  *
@@ -678,9 +718,10 @@ static u8 apm_bios_call_simple(u32 func,
 static int apm_driver_version(u_short *val)
 {
 	u32 eax;
+	int err;
 
-	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
+		return err;
 	*val = eax;
 	return APM_SUCCESS;
 }
@@ -701,22 +742,21 @@ static int apm_driver_version(u_short *v
  *	that APM 1.2 is in use. If no messges are pending the value 0x80
  *	is returned (No power management events pending).
  */
-
 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
 {
-	u32 eax;
-	u32 ebx;
-	u32 ecx;
-	u32 dummy;
+	struct apm_bios_call call;
 
-	if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
-			  &dummy, &dummy))
-		return (eax >> 8) & 0xff;
-	*event = ebx;
+	call.func = APM_FUNC_GET_EVENT;
+	call.ebx = call.ecx = 0;
+
+	if (apm_bios_call(&call))
+		return call.err;
+
+	*event = call.ebx;
 	if (apm_info.connection_version < 0x0102)
 		*info = ~0; /* indicate info not valid */
 	else
-		*info = ecx;
+		*info = call.ecx;
 	return APM_SUCCESS;
 }
 
@@ -737,9 +777,10 @@ static int apm_get_event(apm_event_t *ev
 static int set_power_state(u_short what, u_short state)
 {
 	u32 eax;
+	int err;
 
-	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
+		return err;
 	return APM_SUCCESS;
 }
 
@@ -770,6 +811,7 @@ static int apm_do_idle(void)
 	u8 ret = 0;
 	int idled = 0;
 	int polling;
+	int err;
 
 	polling = !!(current_thread_info()->status & TS_POLLING);
 	if (polling) {
@@ -782,7 +824,7 @@ static int apm_do_idle(void)
 	}
 	if (!need_resched()) {
 		idled = 1;
-		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
+		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
 	}
 	if (polling)
 		current_thread_info()->status |= TS_POLLING;
@@ -797,8 +839,7 @@ static int apm_do_idle(void)
 		 * Only report the failure the first 5 times.
 		 */
 		if (++t < 5) {
-			printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
-			       (eax >> 8) & 0xff);
+			printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
 			t = jiffies;
 		}
 		return -1;
@@ -816,9 +857,10 @@ static int apm_do_idle(void)
 static void apm_do_busy(void)
 {
 	u32 dummy;
+	int err;
 
 	if (clock_slowed || ALWAYS_CALL_BUSY) {
-		(void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+		(void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
 		clock_slowed = 0;
 	}
 }
@@ -937,7 +979,7 @@ static void apm_power_off(void)
 
 	/* Some bioses don't like being called from CPU != 0 */
 	if (apm_info.realmode_power_off) {
-		(void)apm_save_cpus();
+		set_cpus_allowed_ptr(current, cpumask_of(0));
 		machine_real_restart(po_bios_call, sizeof(po_bios_call));
 	} else {
 		(void)set_system_power_state(APM_STATE_OFF);
@@ -956,12 +998,13 @@ static void apm_power_off(void)
 static int apm_enable_power_management(int enable)
 {
 	u32 eax;
+	int err;
 
 	if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
 		return APM_NOT_ENGAGED;
 	if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
-				 enable, &eax))
-		return (eax >> 8) & 0xff;
+				 enable, &eax, &err))
+		return err;
 	if (enable)
 		apm_info.bios.flags &= ~APM_BIOS_DISABLED;
 	else
@@ -986,24 +1029,23 @@ static int apm_enable_power_management(i
 
 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
 {
-	u32 eax;
-	u32 ebx;
-	u32 ecx;
-	u32 edx;
-	u32 dummy;
+	struct apm_bios_call call;
+
+	call.func = APM_FUNC_GET_STATUS;
+	call.ebx = APM_DEVICE_ALL;
+	call.ecx = 0;
 
 	if (apm_info.get_power_status_broken)
 		return APM_32_UNSUPPORTED;
-	if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
-			  &eax, &ebx, &ecx, &edx, &dummy))
-		return (eax >> 8) & 0xff;
-	*status = ebx;
-	*bat = ecx;
+	if (apm_bios_call(&call))
+		return call.err;
+	*status = call.ebx;
+	*bat = call.ecx;
 	if (apm_info.get_power_status_swabinminutes) {
-		*life = swab16((u16)edx);
+		*life = swab16((u16)call.edx);
 		*life |= 0x8000;
 	} else
-		*life = edx;
+		*life = call.edx;
 	return APM_SUCCESS;
 }
 
@@ -1048,12 +1090,14 @@ static int apm_get_battery_status(u_shor
 static int apm_engage_power_management(u_short device, int enable)
 {
 	u32 eax;
+	int err;
 
 	if ((enable == 0) && (device == APM_DEVICE_ALL)
 	    && (apm_info.bios.flags & APM_BIOS_DISABLED))
 		return APM_DISABLED;
-	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable,
+				 &eax, &err))
+		return err;
 	if (device == APM_DEVICE_ALL) {
 		if (enable)
 			apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
@@ -1190,8 +1234,10 @@ static int suspend(int vetoable)
 	struct apm_user	*as;
 
 	device_suspend(PMSG_SUSPEND);
-	local_irq_disable();
+
 	device_power_down(PMSG_SUSPEND);
+
+	local_irq_disable();
 	sysdev_suspend(PMSG_SUSPEND);
 
 	local_irq_enable();
@@ -1209,9 +1255,12 @@ static int suspend(int vetoable)
 	if (err != APM_SUCCESS)
 		apm_error("suspend", err);
 	err = (err == APM_SUCCESS) ? 0 : -EIO;
+
 	sysdev_resume();
-	device_power_up(PMSG_RESUME);
 	local_irq_enable();
+
+	device_power_up(PMSG_RESUME);
+
 	device_resume(PMSG_RESUME);
 	queue_event(APM_NORMAL_RESUME, NULL);
 	spin_lock(&user_list_lock);
@@ -1228,8 +1277,9 @@ static void standby(void)
 {
 	int err;
 
-	local_irq_disable();
 	device_power_down(PMSG_SUSPEND);
+
+	local_irq_disable();
 	sysdev_suspend(PMSG_SUSPEND);
 	local_irq_enable();
 
@@ -1239,8 +1289,9 @@ static void standby(void)
 
 	local_irq_disable();
 	sysdev_resume();
-	device_power_up(PMSG_RESUME);
 	local_irq_enable();
+
+	device_power_up(PMSG_RESUME);
 }
 
 static apm_event_t get_event(void)
@@ -1682,16 +1733,14 @@ static int apm(void *unused)
 	char 		*power_stat;
 	char 		*bat_stat;
 
-#ifdef CONFIG_SMP
 	/* 2002/08/01 - WT
 	 * This is to avoid random crashes at boot time during initialization
 	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
 	 * Some bioses don't like being called from CPU != 0.
 	 * Method suggested by Ingo Molnar.
 	 */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
+	set_cpus_allowed_ptr(current, cpumask_of(0));
 	BUG_ON(smp_processor_id() != 0);
-#endif
 
 	if (apm_info.connection_version == 0) {
 		apm_info.connection_version = apm_info.bios.version;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/asm-offsets_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/asm-offsets_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/asm-offsets_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/asm-offsets_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/thread_info.h>
 #include <asm/bootparam.h>
 #include <asm/elf.h>
+#include <asm/suspend.h>
 
 #include <xen/interface/xen.h>
 
@@ -75,6 +76,7 @@ void foo(void)
 	OFFSET(PT_DS,  pt_regs, ds);
 	OFFSET(PT_ES,  pt_regs, es);
 	OFFSET(PT_FS,  pt_regs, fs);
+	OFFSET(PT_GS,  pt_regs, gs);
 	OFFSET(PT_ORIG_EAX, pt_regs, orig_ax);
 	OFFSET(PT_EIP, pt_regs, ip);
 	OFFSET(PT_CS,  pt_regs, cs);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/asm-offsets_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/asm-offsets_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/asm-offsets_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/asm-offsets_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,12 +11,12 @@
 #include <linux/hardirq.h>
 #include <linux/suspend.h>
 #include <linux/kbuild.h>
-#include <asm/pda.h>
 #include <asm/processor.h>
 #include <asm/segment.h>
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
 #include <asm/bootparam.h>
+#include <asm/suspend.h>
 
 #include <xen/interface/xen.h>
 
@@ -48,16 +48,6 @@ int main(void)
 #endif
 	BLANK();
 #undef ENTRY
-#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
-	ENTRY(kernelstack); 
-	ENTRY(oldrsp); 
-	ENTRY(pcurrent); 
-	ENTRY(irqcount);
-	ENTRY(cpunumber);
-	ENTRY(irqstackptr);
-	ENTRY(data_offset);
-	BLANK();
-#undef ENTRY
 #ifdef CONFIG_PARAVIRT
 	BLANK();
 	OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/bios_uv.c linux-libre-2.6.30-gnu1/arch/x86/kernel/bios_uv.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/bios_uv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/bios_uv.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,8 @@ void uv_bios_init(void)
 	memcpy(&uv_systab, tab, sizeof(struct uv_systab));
 	iounmap(tab);
 
-	printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision);
+	printk(KERN_INFO "EFI UV System Table Revision %d\n",
+					uv_systab.revision);
 }
 #else	/* !CONFIG_EFI */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/check.c linux-libre-2.6.30-gnu1/arch/x86/kernel/check.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/check.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/check.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,15 +83,15 @@ void __init setup_bios_corruption_check(
 		u64 size;
 		addr = find_e820_area_size(addr, &size, PAGE_SIZE);
 
-		if (addr == 0)
+		if (!(addr + 1))
+			break;
+
+		if (addr >= corruption_check_size)
 			break;
 
 		if ((addr + size) > corruption_check_size)
 			size = corruption_check_size - addr;
 
-		if (size == 0)
-			break;
-
 		e820_update_range(addr, size, E820_RAM, E820_RESERVED);
 		scan_areas[num_scan_areas].addr = addr;
 		scan_areas[num_scan_areas].size = size;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/addon_cpuid_features.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
 #include <asm/pat.h>
 #include <asm/processor.h>
 
-#include <mach_apic.h>
+#include <asm/apic.h>
 
 struct cpuid_bit {
 	u16 feature;
@@ -29,8 +29,9 @@ void __cpuinit init_scattered_cpuid_feat
 	u32 regs[4];
 	const struct cpuid_bit *cb;
 
-	static const struct cpuid_bit cpuid_bits[] = {
+	static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
 		{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+		{ X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
 		{ 0, 0, 0, 0 }
 	};
 
@@ -69,7 +70,7 @@ void __cpuinit init_scattered_cpuid_feat
  */
 void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
 	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;
@@ -116,22 +117,14 @@ void __cpuinit detect_extended_topology(
 
 	core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
 
-#ifdef CONFIG_X86_32
-	c->cpu_core_id = phys_pkg_id(c->initial_apicid, ht_mask_width)
+	c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width)
 						 & core_select_mask;
-	c->phys_proc_id = phys_pkg_id(c->initial_apicid, core_plus_mask_width);
-	/*
-	 * Reinit the apicid, now that we have extended initial_apicid.
-	 */
-	c->apicid = phys_pkg_id(c->initial_apicid, 0);
-#else
-	c->cpu_core_id = phys_pkg_id(ht_mask_width) & core_select_mask;
-	c->phys_proc_id = phys_pkg_id(core_plus_mask_width);
+	c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width);
 	/*
 	 * Reinit the apicid, now that we have extended initial_apicid.
 	 */
-	c->apicid = phys_pkg_id(0);
-#endif
+	c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
+
 	c->x86_max_cores = (core_level_siblings / smp_num_siblings);
 
 
@@ -143,37 +136,3 @@ void __cpuinit detect_extended_topology(
 	return;
 #endif
 }
-
-#ifdef CONFIG_X86_PAT
-void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
-{
-	if (!cpu_has_pat)
-		pat_disable("PAT not supported by CPU.");
-
-	switch (c->x86_vendor) {
-	case X86_VENDOR_INTEL:
-		/*
-		 * There is a known erratum on Pentium III and Core Solo
-		 * and Core Duo CPUs.
-		 * " Page with PAT set to WC while associated MTRR is UC
-		 *   may consolidate to UC "
-		 * Because of this erratum, it is better to stick with
-		 * setting WC in MTRR rather than using PAT on these CPUs.
-		 *
-		 * Enable PAT WC only on P4, Core 2 or later CPUs.
-		 */
-		if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15))
-			return;
-
-		pat_disable("PAT WC disabled due to known CPU erratum.");
-		return;
-
-	case X86_VENDOR_AMD:
-	case X86_VENDOR_CENTAUR:
-	case X86_VENDOR_TRANSMETA:
-		return;
-	}
-
-	pat_disable("PAT disabled. Not yet verified on this CPU type.");
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/amd.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/amd.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/amd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/amd.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/apic.h>
+#include <asm/cpu.h>
 
 #ifdef CONFIG_X86_64
 # include <asm/numa_64.h>
@@ -12,8 +13,6 @@
 # include <asm/cacheflush.h>
 #endif
 
-#include <mach_apic.h>
-
 #include "cpu.h"
 
 #ifdef CONFIG_X86_32
@@ -143,6 +142,55 @@ static void __cpuinit init_amd_k6(struct
 	}
 }
 
+static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+	/* calling is from identify_secondary_cpu() ? */
+	if (c->cpu_index == boot_cpu_id)
+		return;
+
+	/*
+	 * Certain Athlons might work (for various values of 'work') in SMP
+	 * but they are not certified as MP capable.
+	 */
+	/* Athlon 660/661 is valid. */
+	if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
+	    (c->x86_mask == 1)))
+		goto valid_k7;
+
+	/* Duron 670 is valid */
+	if ((c->x86_model == 7) && (c->x86_mask == 0))
+		goto valid_k7;
+
+	/*
+	 * Athlon 662, Duron 671, and Athlon >model 7 have capability
+	 * bit. It's worth noting that the A5 stepping (662) of some
+	 * Athlon XP's have the MP bit set.
+	 * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
+	 * more.
+	 */
+	if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
+	    ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
+	     (c->x86_model > 7))
+		if (cpu_has_mp)
+			goto valid_k7;
+
+	/* If we get here, not a certified SMP capable AMD system. */
+
+	/*
+	 * Don't taint if we are running SMP kernel on a single non-MP
+	 * approved Athlon
+	 */
+	WARN_ONCE(1, "WARNING: This combination of AMD"
+		"processors is not suitable for SMP.\n");
+	if (!test_taint(TAINT_UNSAFE_SMP))
+		add_taint(TAINT_UNSAFE_SMP);
+
+valid_k7:
+	;
+#endif
+}
+
 static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
@@ -177,6 +225,8 @@ static void __cpuinit init_amd_k7(struct
 	}
 
 	set_cpu_cap(c, X86_FEATURE_K7);
+
+	amd_k7_smp_check(c);
 }
 #endif
 
@@ -452,7 +502,7 @@ static unsigned int __cpuinit amd_size_c
 }
 #endif
 
-static struct cpu_dev amd_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
 	.c_vendor	= "AMD",
 	.c_ident	= { "AuthenticAMD" },
 #ifdef CONFIG_X86_32
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/centaur_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/centaur_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/centaur_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/centaur_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/cpufeature.h>
-#include <asm/processor.h>
-
-#include "cpu.h"
-
-static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
-{
-	if (c->x86 == 0x6 && c->x86_model >= 0xf)
-		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-
-	set_cpu_cap(c, X86_FEATURE_SYSENTER32);
-}
-
-static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
-{
-	early_init_centaur(c);
-
-	if (c->x86 == 0x6 && c->x86_model >= 0xf) {
-		c->x86_cache_alignment = c->x86_clflush_size * 2;
-		set_cpu_cap(c, X86_FEATURE_REP_GOOD);
-	}
-	set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
-}
-
-static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
-	.c_vendor	= "Centaur",
-	.c_ident	= { "CentaurHauls" },
-	.c_early_init	= early_init_centaur,
-	.c_init		= init_centaur,
-	.c_x86_vendor	= X86_VENDOR_CENTAUR,
-};
-
-cpu_dev_register(centaur_cpu_dev);
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/centaur.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/centaur.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/centaur.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/centaur.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,11 @@
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/bitops.h>
 
 #include <asm/processor.h>
-#include <asm/msr.h>
 #include <asm/e820.h>
 #include <asm/mtrr.h>
+#include <asm/msr.h>
 
 #include "cpu.h"
 
@@ -276,7 +276,7 @@ static void __cpuinit init_c3(struct cpu
 		 */
 		c->x86_capability[5] = cpuid_edx(0xC0000001);
 	}
-
+#ifdef CONFIG_X86_32
 	/* Cyrix III family needs CX8 & PGE explicitly enabled. */
 	if (c->x86_model >= 6 && c->x86_model <= 9) {
 		rdmsr(MSR_VIA_FCR, lo, hi);
@@ -288,6 +288,11 @@ static void __cpuinit init_c3(struct cpu
 	/* Before Nehemiah, the C3's had 3dNOW! */
 	if (c->x86_model >= 6 && c->x86_model < 9)
 		set_cpu_cap(c, X86_FEATURE_3DNOW);
+#endif
+	if (c->x86 == 0x6 && c->x86_model >= 0xf) {
+		c->x86_cache_alignment = c->x86_clflush_size * 2;
+		set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+	}
 
 	display_cacheinfo(c);
 }
@@ -316,16 +321,25 @@ enum {
 static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
 {
 	switch (c->x86) {
+#ifdef CONFIG_X86_32
 	case 5:
 		/* Emulate MTRRs using Centaur's MCR. */
 		set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
 		break;
+#endif
+	case 6:
+		if (c->x86_model >= 0xf)
+			set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+		break;
 	}
+#ifdef CONFIG_X86_64
+	set_cpu_cap(c, X86_FEATURE_SYSENTER32);
+#endif
 }
 
 static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
 {
-
+#ifdef CONFIG_X86_32
 	char *name;
 	u32  fcr_set = 0;
 	u32  fcr_clr = 0;
@@ -337,8 +351,10 @@ static void __cpuinit init_centaur(struc
 	 * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
 	 */
 	clear_cpu_cap(c, 0*32+31);
-
+#endif
+	early_init_centaur(c);
 	switch (c->x86) {
+#ifdef CONFIG_X86_32
 	case 5:
 		switch (c->x86_model) {
 		case 4:
@@ -442,16 +458,20 @@ static void __cpuinit init_centaur(struc
 		}
 		sprintf(c->x86_model_id, "WinChip %s", name);
 		break;
-
+#endif
 	case 6:
 		init_c3(c);
 		break;
 	}
+#ifdef CONFIG_X86_64
+	set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+#endif
 }
 
 static unsigned int __cpuinit
 centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
+#ifdef CONFIG_X86_32
 	/* VIA C3 CPUs (670-68F) need further shifting. */
 	if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
 		size >>= 8;
@@ -464,11 +484,11 @@ centaur_size_cache(struct cpuinfo_x86 *c
 	if ((c->x86 == 6) && (c->x86_model == 9) &&
 				(c->x86_mask == 1) && (size == 65))
 		size -= 1;
-
+#endif
 	return size;
 }
 
-static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst centaur_cpu_dev = {
 	.c_vendor	= "Centaur",
 	.c_ident	= { "CentaurHauls" },
 	.c_early_init	= early_init_centaur,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/common.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/common.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,120 +1,126 @@
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
 #include <linux/bootmem.h>
+#include <linux/linkage.h>
 #include <linux/bitops.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/kgdb.h>
-#include <linux/topology.h>
+#include <linux/percpu.h>
+#include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kgdb.h>
 #include <linux/smp.h>
-#include <linux/percpu.h>
-#include <asm/i387.h>
-#include <asm/msr.h>
-#include <asm/io.h>
-#include <asm/linkage.h>
+#include <linux/io.h>
+
+#include <asm/stackprotector.h>
 #include <asm/mmu_context.h>
+#include <asm/hypervisor.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/topology.h>
+#include <asm/cpumask.h>
+#include <asm/pgtable.h>
+#include <asm/atomic.h>
+#include <asm/proto.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
 #include <asm/mtrr.h>
+#include <asm/numa.h>
+#include <asm/asm.h>
+#include <asm/cpu.h>
 #include <asm/mce.h>
+#include <asm/msr.h>
 #include <asm/pat.h>
-#include <asm/asm.h>
-#include <asm/numa.h>
 #include <asm/smp.h>
+
 #ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/mpspec.h>
-#include <asm/apic.h>
-#include <mach_apic.h>
-#include <asm/genapic.h>
+#include <asm/uv/uv.h>
 #endif
 
-#include <asm/pda.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/desc.h>
-#include <asm/atomic.h>
-#include <asm/proto.h>
-#include <asm/sections.h>
-#include <asm/setup.h>
-#include <asm/hypervisor.h>
-
 #include "cpu.h"
 
-#ifdef CONFIG_X86_64
-
 /* all of these masks are initialized in setup_cpu_local_masks() */
-cpumask_var_t cpu_callin_mask;
-cpumask_var_t cpu_callout_mask;
 cpumask_var_t cpu_initialized_mask;
+cpumask_var_t cpu_callout_mask;
+cpumask_var_t cpu_callin_mask;
 
 /* representing cpus for which sibling maps can be computed */
 cpumask_var_t cpu_sibling_setup_mask;
 
-#else /* CONFIG_X86_32 */
-
-cpumask_t cpu_callin_map;
-cpumask_t cpu_callout_map;
-cpumask_t cpu_initialized;
-cpumask_t cpu_sibling_setup_map;
-
-#endif /* CONFIG_X86_32 */
-
+/* correctly size the local cpu masks */
+void __init setup_cpu_local_masks(void)
+{
+	alloc_bootmem_cpumask_var(&cpu_initialized_mask);
+	alloc_bootmem_cpumask_var(&cpu_callin_mask);
+	alloc_bootmem_cpumask_var(&cpu_callout_mask);
+	alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
+}
 
-static struct cpu_dev *this_cpu __cpuinitdata;
+static const struct cpu_dev *this_cpu __cpuinitdata;
 
+DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 #ifdef CONFIG_X86_64
-/* We need valid kernel segments for data and code in long mode too
- * IRET will check the segment types  kkeil 2000/10/28
- * Also sysret mandates a special GDT layout
- */
-/* The TLS descriptors are currently at a different place compared to i386.
-   Hopefully nobody expects them at a fixed place (Wine?) */
-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
-	[GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
-	[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
-	[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
-	[GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
-	[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
-	[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
-} };
+	/*
+	 * We need valid kernel segments for data and code in long mode too
+	 * IRET will check the segment types  kkeil 2000/10/28
+	 * Also sysret mandates a special GDT layout
+	 *
+	 * TLS descriptors are currently at a different place compared to i386.
+	 * Hopefully nobody expects them at a fixed place (Wine?)
+	 */
+	[GDT_ENTRY_KERNEL32_CS]		= { { { 0x0000ffff, 0x00cf9b00 } } },
+	[GDT_ENTRY_KERNEL_CS]		= { { { 0x0000ffff, 0x00af9b00 } } },
+	[GDT_ENTRY_KERNEL_DS]		= { { { 0x0000ffff, 0x00cf9300 } } },
+	[GDT_ENTRY_DEFAULT_USER32_CS]	= { { { 0x0000ffff, 0x00cffb00 } } },
+	[GDT_ENTRY_DEFAULT_USER_DS]	= { { { 0x0000ffff, 0x00cff300 } } },
+	[GDT_ENTRY_DEFAULT_USER_CS]	= { { { 0x0000ffff, 0x00affb00 } } },
 #else
-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
-	[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
-	[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
-	[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
-	[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
+	[GDT_ENTRY_KERNEL_CS]		= { { { 0x0000ffff, 0x00cf9a00 } } },
+	[GDT_ENTRY_KERNEL_DS]		= { { { 0x0000ffff, 0x00cf9200 } } },
+	[GDT_ENTRY_DEFAULT_USER_CS]	= { { { 0x0000ffff, 0x00cffa00 } } },
+	[GDT_ENTRY_DEFAULT_USER_DS]	= { { { 0x0000ffff, 0x00cff200 } } },
 	/*
 	 * Segments used for calling PnP BIOS have byte granularity.
 	 * They code segments and data segments have fixed 64k limits,
 	 * the transfer segment sizes are set at run time.
 	 */
 	/* 32-bit code */
-	[GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
+	[GDT_ENTRY_PNPBIOS_CS32]	= { { { 0x0000ffff, 0x00409a00 } } },
 	/* 16-bit code */
-	[GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
+	[GDT_ENTRY_PNPBIOS_CS16]	= { { { 0x0000ffff, 0x00009a00 } } },
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_DS]		= { { { 0x0000ffff, 0x00009200 } } },
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_TS1]		= { { { 0x00000000, 0x00009200 } } },
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_TS2]		= { { { 0x00000000, 0x00009200 } } },
 	/*
 	 * The APM segments have byte granularity and their bases
 	 * are set at run time.  All have 64k limits.
 	 */
 	/* 32-bit code */
-	[GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
+	[GDT_ENTRY_APMBIOS_BASE]	= { { { 0x0000ffff, 0x00409a00 } } },
 	/* 16-bit code */
-	[GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
+	[GDT_ENTRY_APMBIOS_BASE+1]	= { { { 0x0000ffff, 0x00009a00 } } },
 	/* data */
-	[GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
+	[GDT_ENTRY_APMBIOS_BASE+2]	= { { { 0x0000ffff, 0x00409200 } } },
 
-	[GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
-	[GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
-} };
+	[GDT_ENTRY_ESPFIX_SS]		= { { { 0x00000000, 0x00c09200 } } },
+	[GDT_ENTRY_PERCPU]		= { { { 0x0000ffff, 0x00cf9200 } } },
+	GDT_STACK_CANARY_INIT
 #endif
+} };
 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
+static int __init x86_xsave_setup(char *s)
+{
+	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+	return 1;
+}
+__setup("noxsave", x86_xsave_setup);
+
 #ifdef CONFIG_X86_32
 static int cachesize_override __cpuinitdata = -1;
 static int disable_x86_serial_nr __cpuinitdata = 1;
@@ -153,16 +159,17 @@ static inline int flag_is_changeable_p(u
 	 * the CPUID. Add "volatile" to not allow gcc to
 	 * optimize the subsequent calls to this function.
 	 */
-	asm volatile ("pushfl\n\t"
-		      "pushfl\n\t"
-		      "popl %0\n\t"
-		      "movl %0,%1\n\t"
-		      "xorl %2,%0\n\t"
-		      "pushl %0\n\t"
-		      "popfl\n\t"
-		      "pushfl\n\t"
-		      "popl %0\n\t"
-		      "popfl\n\t"
+	asm volatile ("pushfl		\n\t"
+		      "pushfl		\n\t"
+		      "popl %0		\n\t"
+		      "movl %0, %1	\n\t"
+		      "xorl %2, %0	\n\t"
+		      "pushl %0		\n\t"
+		      "popfl		\n\t"
+		      "pushfl		\n\t"
+		      "popl %0		\n\t"
+		      "popfl		\n\t"
+
 		      : "=&r" (f1), "=&r" (f2)
 		      : "ir" (flag));
 
@@ -177,18 +184,22 @@ static int __cpuinit have_cpuid_p(void)
 
 static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
 {
-	if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr) {
-		/* Disable processor serial number */
-		unsigned long lo, hi;
-		rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
-		lo |= 0x200000;
-		wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
-		printk(KERN_NOTICE "CPU serial number disabled.\n");
-		clear_cpu_cap(c, X86_FEATURE_PN);
+	unsigned long lo, hi;
 
-		/* Disabling the serial number may affect the cpuid level */
-		c->cpuid_level = cpuid_eax(0);
-	}
+	if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr)
+		return;
+
+	/* Disable processor serial number: */
+
+	rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
+	lo |= 0x200000;
+	wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
+
+	printk(KERN_NOTICE "CPU serial number disabled.\n");
+	clear_cpu_cap(c, X86_FEATURE_PN);
+
+	/* Disabling the serial number may affect the cpuid level */
+	c->cpuid_level = cpuid_eax(0);
 }
 
 static int __init x86_serial_nr_setup(char *s)
@@ -213,16 +224,64 @@ static inline void squash_the_stupid_ser
 #endif
 
 /*
+ * Some CPU features depend on higher CPUID levels, which may not always
+ * be available due to CPUID level capping or broken virtualization
+ * software.  Add those features to this table to auto-disable them.
+ */
+struct cpuid_dependent_feature {
+	u32 feature;
+	u32 level;
+};
+
+static const struct cpuid_dependent_feature __cpuinitconst
+cpuid_dependent_features[] = {
+	{ X86_FEATURE_MWAIT,		0x00000005 },
+	{ X86_FEATURE_DCA,		0x00000009 },
+	{ X86_FEATURE_XSAVE,		0x0000000d },
+	{ 0, 0 }
+};
+
+static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
+{
+	const struct cpuid_dependent_feature *df;
+
+	for (df = cpuid_dependent_features; df->feature; df++) {
+
+		if (!cpu_has(c, df->feature))
+			continue;
+		/*
+		 * Note: cpuid_level is set to -1 if unavailable, but
+		 * extended_extended_level is set to 0 if unavailable
+		 * and the legitimate extended levels are all negative
+		 * when signed; hence the weird messing around with
+		 * signs here...
+		 */
+		if (!((s32)df->level < 0 ?
+		     (u32)df->level > (u32)c->extended_cpuid_level :
+		     (s32)df->level > (s32)c->cpuid_level))
+			continue;
+
+		clear_cpu_cap(c, df->feature);
+		if (!warn)
+			continue;
+
+		printk(KERN_WARNING
+		       "CPU: CPU feature %s disabled, no CPUID level 0x%x\n",
+				x86_cap_flags[df->feature], df->level);
+	}
+}
+
+/*
  * Naming convention should be: <Name> [(<Codename>)]
  * This table only is used unless init_<vendor>() below doesn't set it;
- * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used
- *
+ * in particular, if CPUID levels 0x80000002..4 are supported, this
+ * isn't used
  */
 
 /* Look up CPU names by table lookup. */
-static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c)
+static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c)
 {
-	struct cpu_model_info *info;
+	const struct cpu_model_info *info;
 
 	if (c->x86_model >= 16)
 		return NULL;	/* Range check */
@@ -242,21 +301,34 @@ static char __cpuinit *table_lookup_mode
 
 __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
 
-/* Current gdt points %fs at the "master" per-cpu area: after this,
- * it's on the real one. */
-void switch_to_new_gdt(void)
+void load_percpu_segment(int cpu)
+{
+#ifdef CONFIG_X86_32
+	loadsegment(fs, __KERNEL_PERCPU);
+#else
+	loadsegment(gs, 0);
+	wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
+#endif
+	load_stack_canary_segment();
+}
+
+/*
+ * Current gdt points %fs at the "master" per-cpu area: after this,
+ * it's on the real one.
+ */
+void switch_to_new_gdt(int cpu)
 {
 	struct desc_ptr gdt_descr;
 
-	gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
+	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
 	gdt_descr.size = GDT_SIZE - 1;
 	load_gdt(&gdt_descr);
-#ifdef CONFIG_X86_32
-	asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
-#endif
+	/* Reload the per-cpu base */
+
+	load_percpu_segment(cpu);
 }
 
-static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
+static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {};
 
 static void __cpuinit default_init(struct cpuinfo_x86 *c)
 {
@@ -275,7 +347,7 @@ static void __cpuinit default_init(struc
 #endif
 }
 
-static struct cpu_dev __cpuinitdata default_cpu = {
+static const struct cpu_dev __cpuinitconst default_cpu = {
 	.c_init	= default_init,
 	.c_vendor = "Unknown",
 	.c_x86_vendor = X86_VENDOR_UNKNOWN,
@@ -289,22 +361,24 @@ static void __cpuinit get_model_name(str
 	if (c->extended_cpuid_level < 0x80000004)
 		return;
 
-	v = (unsigned int *) c->x86_model_id;
+	v = (unsigned int *)c->x86_model_id;
 	cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
 	cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
 	cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
 	c->x86_model_id[48] = 0;
 
-	/* Intel chips right-justify this string for some dumb reason;
-	   undo that brain damage */
+	/*
+	 * Intel chips right-justify this string for some dumb reason;
+	 * undo that brain damage:
+	 */
 	p = q = &c->x86_model_id[0];
 	while (*p == ' ')
-	     p++;
+		p++;
 	if (p != q) {
-	     while (*p)
-		  *q++ = *p++;
-	     while (q <= &c->x86_model_id[48])
-		  *q++ = '\0';	/* Zero-pad the rest */
+		while (*p)
+			*q++ = *p++;
+		while (q <= &c->x86_model_id[48])
+			*q++ = '\0';	/* Zero-pad the rest */
 	}
 }
 
@@ -373,36 +447,30 @@ void __cpuinit detect_ht(struct cpuinfo_
 
 	if (smp_num_siblings == 1) {
 		printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
-	} else if (smp_num_siblings > 1) {
+		goto out;
+	}
 
-		if (smp_num_siblings > nr_cpu_ids) {
-			printk(KERN_WARNING "CPU: Unsupported number of siblings %d",
-					smp_num_siblings);
-			smp_num_siblings = 1;
-			return;
-		}
+	if (smp_num_siblings <= 1)
+		goto out;
 
-		index_msb = get_count_order(smp_num_siblings);
-#ifdef CONFIG_X86_64
-		c->phys_proc_id = phys_pkg_id(index_msb);
-#else
-		c->phys_proc_id = phys_pkg_id(c->initial_apicid, index_msb);
-#endif
+	if (smp_num_siblings > nr_cpu_ids) {
+		pr_warning("CPU: Unsupported number of siblings %d",
+			   smp_num_siblings);
+		smp_num_siblings = 1;
+		return;
+	}
 
-		smp_num_siblings = smp_num_siblings / c->x86_max_cores;
+	index_msb = get_count_order(smp_num_siblings);
+	c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
 
-		index_msb = get_count_order(smp_num_siblings);
+	smp_num_siblings = smp_num_siblings / c->x86_max_cores;
 
-		core_bits = get_count_order(c->x86_max_cores);
+	index_msb = get_count_order(smp_num_siblings);
 
-#ifdef CONFIG_X86_64
-		c->cpu_core_id = phys_pkg_id(index_msb) &
-					       ((1 << core_bits) - 1);
-#else
-		c->cpu_core_id = phys_pkg_id(c->initial_apicid, index_msb) &
-					       ((1 << core_bits) - 1);
-#endif
-	}
+	core_bits = get_count_order(c->x86_max_cores);
+
+	c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) &
+				       ((1 << core_bits) - 1);
 
 out:
 	if ((c->x86_max_cores * smp_num_siblings) > 1) {
@@ -417,8 +485,8 @@ out:
 static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
 {
 	char *v = c->x86_vendor_id;
-	int i;
 	static int printed;
+	int i;
 
 	for (i = 0; i < X86_VENDOR_NUM; i++) {
 		if (!cpu_devs[i])
@@ -427,6 +495,7 @@ static void __cpuinit get_cpu_vendor(str
 		if (!strcmp(v, cpu_devs[i]->c_ident[0]) ||
 		    (cpu_devs[i]->c_ident[1] &&
 		     !strcmp(v, cpu_devs[i]->c_ident[1]))) {
+
 			this_cpu = cpu_devs[i];
 			c->x86_vendor = this_cpu->c_x86_vendor;
 			return;
@@ -435,7 +504,9 @@ static void __cpuinit get_cpu_vendor(str
 
 	if (!printed) {
 		printed++;
-		printk(KERN_ERR "CPU: vendor_id '%s' unknown, using generic init.\n", v);
+		printk(KERN_ERR
+		    "CPU: vendor_id '%s' unknown, using generic init.\n", v);
+
 		printk(KERN_ERR "CPU: Your system may be unstable.\n");
 	}
 
@@ -455,14 +526,17 @@ void __cpuinit cpu_detect(struct cpuinfo
 	/* Intel-defined flags: level 0x00000001 */
 	if (c->cpuid_level >= 0x00000001) {
 		u32 junk, tfms, cap0, misc;
+
 		cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
 		c->x86 = (tfms >> 8) & 0xf;
 		c->x86_model = (tfms >> 4) & 0xf;
 		c->x86_mask = tfms & 0xf;
+
 		if (c->x86 == 0xf)
 			c->x86 += (tfms >> 20) & 0xff;
 		if (c->x86 >= 0x6)
 			c->x86_model += ((tfms >> 16) & 0xf) << 4;
+
 		if (cap0 & (1<<19)) {
 			c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
 			c->x86_cache_alignment = c->x86_clflush_size;
@@ -478,6 +552,7 @@ static void __cpuinit get_cpu_cap(struct
 	/* Intel-defined flags: level 0x00000001 */
 	if (c->cpuid_level >= 0x00000001) {
 		u32 capability, excap;
+
 		cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
 		c->x86_capability[0] = capability;
 		c->x86_capability[4] = excap;
@@ -486,6 +561,7 @@ static void __cpuinit get_cpu_cap(struct
 	/* AMD-defined flags: level 0x80000001 */
 	xlvl = cpuid_eax(0x80000000);
 	c->extended_cpuid_level = xlvl;
+
 	if ((xlvl & 0xffff0000) == 0x80000000) {
 		if (xlvl >= 0x80000001) {
 			c->x86_capability[1] = cpuid_edx(0x80000001);
@@ -493,13 +569,15 @@ static void __cpuinit get_cpu_cap(struct
 		}
 	}
 
-#ifdef CONFIG_X86_64
 	if (c->extended_cpuid_level >= 0x80000008) {
 		u32 eax = cpuid_eax(0x80000008);
 
 		c->x86_virt_bits = (eax >> 8) & 0xff;
 		c->x86_phys_bits = eax & 0xff;
 	}
+#ifdef CONFIG_X86_32
+	else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
+		c->x86_phys_bits = 36;
 #endif
 
 	if (c->extended_cpuid_level >= 0x80000007)
@@ -546,8 +624,12 @@ static void __init early_identify_cpu(st
 {
 #ifdef CONFIG_X86_64
 	c->x86_clflush_size = 64;
+	c->x86_phys_bits = 36;
+	c->x86_virt_bits = 48;
 #else
 	c->x86_clflush_size = 32;
+	c->x86_phys_bits = 32;
+	c->x86_virt_bits = 32;
 #endif
 	c->x86_cache_alignment = c->x86_clflush_size;
 
@@ -570,21 +652,20 @@ static void __init early_identify_cpu(st
 	if (this_cpu->c_early_init)
 		this_cpu->c_early_init(c);
 
-	validate_pat_support(c);
-
 #ifdef CONFIG_SMP
 	c->cpu_index = boot_cpu_id;
 #endif
+	filter_cpuid_features(c, false);
 }
 
 void __init early_cpu_init(void)
 {
-	struct cpu_dev **cdev;
+	const struct cpu_dev *const *cdev;
 	int count = 0;
 
-	printk("KERNEL supported cpus:\n");
+	printk(KERN_INFO "KERNEL supported cpus:\n");
 	for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
-		struct cpu_dev *cpudev = *cdev;
+		const struct cpu_dev *cpudev = *cdev;
 		unsigned int j;
 
 		if (count >= X86_VENDOR_NUM)
@@ -595,7 +676,7 @@ void __init early_cpu_init(void)
 		for (j = 0; j < 2; j++) {
 			if (!cpudev->c_ident[j])
 				continue;
-			printk("  %s %s\n", cpudev->c_vendor,
+			printk(KERN_INFO "  %s %s\n", cpudev->c_vendor,
 				cpudev->c_ident[j]);
 		}
 	}
@@ -637,7 +718,7 @@ static void __cpuinit generic_identify(s
 		c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
 #ifdef CONFIG_X86_32
 # ifdef CONFIG_X86_HT
-		c->apicid = phys_pkg_id(c->initial_apicid, 0);
+		c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
 # else
 		c->apicid = c->initial_apicid;
 # endif
@@ -671,9 +752,13 @@ static void __cpuinit identify_cpu(struc
 	c->x86_coreid_bits = 0;
 #ifdef CONFIG_X86_64
 	c->x86_clflush_size = 64;
+	c->x86_phys_bits = 36;
+	c->x86_virt_bits = 48;
 #else
 	c->cpuid_level = -1;	/* CPUID not detected */
 	c->x86_clflush_size = 32;
+	c->x86_phys_bits = 32;
+	c->x86_virt_bits = 32;
 #endif
 	c->x86_cache_alignment = c->x86_clflush_size;
 	memset(&c->x86_capability, 0, sizeof c->x86_capability);
@@ -684,7 +769,7 @@ static void __cpuinit identify_cpu(struc
 		this_cpu->c_identify(c);
 
 #ifdef CONFIG_X86_64
-	c->apicid = phys_pkg_id(0);
+	c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
 #endif
 
 	/*
@@ -704,13 +789,16 @@ static void __cpuinit identify_cpu(struc
 	squash_the_stupid_serial_number(c);
 
 	/*
-	 * The vendor-specific functions might have changed features.  Now
-	 * we do "generic changes."
+	 * The vendor-specific functions might have changed features.
+	 * Now we do "generic changes."
 	 */
 
+	/* Filter out anything that depends on CPUID levels we don't have */
+	filter_cpuid_features(c, true);
+
 	/* If the model name is still unset, do table lookup. */
 	if (!c->x86_model_id[0]) {
-		char *p;
+		const char *p;
 		p = table_lookup_model(c);
 		if (p)
 			strcpy(c->x86_model_id, p);
@@ -766,6 +854,7 @@ static void vgetcpu_set_mode(void)
 void __init identify_boot_cpu(void)
 {
 	identify_cpu(&boot_cpu_data);
+	init_c1e_mask();
 #ifdef CONFIG_X86_32
 	sysenter_setup();
 	enable_sep_cpu();
@@ -785,11 +874,11 @@ void __cpuinit identify_secondary_cpu(st
 }
 
 struct msr_range {
-	unsigned min;
-	unsigned max;
+	unsigned	min;
+	unsigned	max;
 };
 
-static struct msr_range msr_range_array[] __cpuinitdata = {
+static const struct msr_range msr_range_array[] __cpuinitconst = {
 	{ 0x00000000, 0x00000418},
 	{ 0xc0000000, 0xc000040b},
 	{ 0xc0010000, 0xc0010142},
@@ -798,14 +887,15 @@ static struct msr_range msr_range_array[
 
 static void __cpuinit print_cpu_msr(void)
 {
+	unsigned index_min, index_max;
 	unsigned index;
 	u64 val;
 	int i;
-	unsigned index_min, index_max;
 
 	for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
 		index_min = msr_range_array[i].min;
 		index_max = msr_range_array[i].max;
+
 		for (index = index_min; index < index_max; index++) {
 			if (rdmsrl_amd_safe(index, &val))
 				continue;
@@ -815,6 +905,7 @@ static void __cpuinit print_cpu_msr(void
 }
 
 static int show_msr __cpuinitdata;
+
 static __init int setup_show_msr(char *arg)
 {
 	int num;
@@ -836,12 +927,14 @@ __setup("noclflush", setup_noclflush);
 
 void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
-	char *vendor = NULL;
+	const char *vendor = NULL;
 
-	if (c->x86_vendor < X86_VENDOR_NUM)
+	if (c->x86_vendor < X86_VENDOR_NUM) {
 		vendor = this_cpu->c_vendor;
-	else if (c->cpuid_level >= 0)
-		vendor = c->x86_vendor_id;
+	} else {
+		if (c->cpuid_level >= 0)
+			vendor = c->x86_vendor_id;
+	}
 
 	if (vendor && !strstr(c->x86_model_id, vendor))
 		printk(KERN_CONT "%s ", vendor);
@@ -868,65 +961,45 @@ void __cpuinit print_cpu_info(struct cpu
 static __init int setup_disablecpuid(char *arg)
 {
 	int bit;
+
 	if (get_option(&arg, &bit) && bit < NCAPINTS*32)
 		setup_clear_cpu_cap(bit);
 	else
 		return 0;
+
 	return 1;
 }
 __setup("clearcpuid=", setup_disablecpuid);
 
 #ifdef CONFIG_X86_64
-struct x8664_pda **_cpu_pda __read_mostly;
-EXPORT_SYMBOL(_cpu_pda);
-
 struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
 
-static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
-
-void __cpuinit pda_init(int cpu)
-{
-	struct x8664_pda *pda = cpu_pda(cpu);
-
-	/* Setup up data that may be needed in __get_free_pages early */
-	loadsegment(fs, 0);
-	loadsegment(gs, 0);
-	/* Memory clobbers used to order PDA accessed */
-	mb();
-	wrmsrl(MSR_GS_BASE, pda);
-	mb();
+DEFINE_PER_CPU_FIRST(union irq_stack_union,
+		     irq_stack_union) __aligned(PAGE_SIZE);
 
-	pda->cpunumber = cpu;
-	pda->irqcount = -1;
-	pda->kernelstack = (unsigned long)stack_thread_info() -
-				 PDA_STACKOFFSET + THREAD_SIZE;
-	pda->active_mm = &init_mm;
-	pda->mmu_state = 0;
+DEFINE_PER_CPU(char *, irq_stack_ptr) =
+	init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
 
-	if (cpu == 0) {
-		/* others are initialized in smpboot.c */
-		pda->pcurrent = &init_task;
-		pda->irqstackptr = boot_cpu_stack;
-		pda->irqstackptr += IRQSTACKSIZE - 64;
-	} else {
-		if (!pda->irqstackptr) {
-			pda->irqstackptr = (char *)
-				__get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
-			if (!pda->irqstackptr)
-				panic("cannot allocate irqstack for cpu %d",
-				      cpu);
-			pda->irqstackptr += IRQSTACKSIZE - 64;
-		}
+DEFINE_PER_CPU(unsigned long, kernel_stack) =
+	(unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
+EXPORT_PER_CPU_SYMBOL(kernel_stack);
 
-		if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE)
-			pda->nodenumber = cpu_to_node(cpu);
-	}
-}
+DEFINE_PER_CPU(unsigned int, irq_count) = -1;
 
-static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ +
-				  DEBUG_STKSZ] __page_aligned_bss;
+/*
+ * Special IST stacks which the CPU switches to when it calls
+ * an IST-marked descriptor entry. Up to 7 stacks (hardware
+ * limit), all of them are 4K, except the debug stack which
+ * is 8K.
+ */
+static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
+	  [0 ... N_EXCEPTION_STACKS - 1]	= EXCEPTION_STKSZ,
+	  [DEBUG_STACK - 1]			= DEBUG_STKSZ
+};
 
-extern asmlinkage void ignore_sysret(void);
+static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
+	[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
+	__aligned(PAGE_SIZE);
 
 /* May not be marked __init: used by software suspend */
 void syscall_init(void)
@@ -957,16 +1030,38 @@ unsigned long kernel_eflags;
  */
 DEFINE_PER_CPU(struct orig_ist, orig_ist);
 
-#else
+#else	/* CONFIG_X86_64 */
 
-/* Make sure %fs is initialized properly in idle threads */
+#ifdef CONFIG_CC_STACKPROTECTOR
+DEFINE_PER_CPU(unsigned long, stack_canary);
+#endif
+
+/* Make sure %fs and %gs are initialized properly in idle threads */
 struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
 {
 	memset(regs, 0, sizeof(struct pt_regs));
 	regs->fs = __KERNEL_PERCPU;
+	regs->gs = __KERNEL_STACK_CANARY;
+
 	return regs;
 }
-#endif
+#endif	/* CONFIG_X86_64 */
+
+/*
+ * Clear all 6 debug registers:
+ */
+static void clear_all_debug_regs(void)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		/* Ignore db4, db5 */
+		if ((i == 4) || (i == 5))
+			continue;
+
+		set_debugreg(0, i);
+	}
+}
 
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
@@ -976,21 +1071,25 @@ struct pt_regs * __cpuinit idle_regs(str
  * A lot of state is already set up in PDA init for 64 bit
  */
 #ifdef CONFIG_X86_64
+
 void __cpuinit cpu_init(void)
 {
-	int cpu = stack_smp_processor_id();
-	struct tss_struct *t = &per_cpu(init_tss, cpu);
-	struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
-	unsigned long v;
-	char *estacks = NULL;
+	struct orig_ist *orig_ist;
 	struct task_struct *me;
+	struct tss_struct *t;
+	unsigned long v;
+	int cpu;
 	int i;
 
-	/* CPU 0 is initialised in head64.c */
-	if (cpu != 0)
-		pda_init(cpu);
-	else
-		estacks = boot_exception_stacks;
+	cpu = stack_smp_processor_id();
+	t = &per_cpu(init_tss, cpu);
+	orig_ist = &per_cpu(orig_ist, cpu);
+
+#ifdef CONFIG_NUMA
+	if (cpu != 0 && percpu_read(node_number) == 0 &&
+	    cpu_to_node(cpu) != NUMA_NO_NODE)
+		percpu_write(node_number, cpu_to_node(cpu));
+#endif
 
 	me = current;
 
@@ -1006,7 +1105,9 @@ void __cpuinit cpu_init(void)
 	 * and set up the GDT descriptor:
 	 */
 
-	switch_to_new_gdt();
+	switch_to_new_gdt(cpu);
+	loadsegment(fs, 0);
+
 	load_idt((const struct desc_ptr *)&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
@@ -1017,31 +1118,24 @@ void __cpuinit cpu_init(void)
 	barrier();
 
 	check_efer();
-	if (cpu != 0 && x2apic)
+	if (cpu != 0)
 		enable_x2apic();
 
 	/*
 	 * set up and load the per-CPU TSS
 	 */
 	if (!orig_ist->ist[0]) {
-		static const unsigned int order[N_EXCEPTION_STACKS] = {
-		  [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
-		  [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
-		};
+		char *estacks = per_cpu(exception_stacks, cpu);
+
 		for (v = 0; v < N_EXCEPTION_STACKS; v++) {
-			if (cpu) {
-				estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
-				if (!estacks)
-					panic("Cannot allocate exception "
-					      "stack %ld %d\n", v, cpu);
-			}
-			estacks += PAGE_SIZE << order[v];
+			estacks += exception_stack_sizes[v];
 			orig_ist->ist[v] = t->x86_tss.ist[v] =
 					(unsigned long)estacks;
 		}
 	}
 
 	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+
 	/*
 	 * <= is required because the CPU will access up to
 	 * 8 bits beyond the end of the IO permission bitmap.
@@ -1051,8 +1145,7 @@ void __cpuinit cpu_init(void)
 
 	atomic_inc(&init_mm.mm_count);
 	me->active_mm = &init_mm;
-	if (me->mm)
-		BUG();
+	BUG_ON(me->mm);
 	enter_lazy_tlb(&init_mm, me);
 
 	load_sp0(t, &current->thread);
@@ -1069,22 +1162,9 @@ void __cpuinit cpu_init(void)
 	 */
 	if (kgdb_connected && arch_kgdb_ops.correct_hw_break)
 		arch_kgdb_ops.correct_hw_break();
-	else {
-#endif
-	/*
-	 * Clear all 6 debug registers:
-	 */
-
-	set_debugreg(0UL, 0);
-	set_debugreg(0UL, 1);
-	set_debugreg(0UL, 2);
-	set_debugreg(0UL, 3);
-	set_debugreg(0UL, 6);
-	set_debugreg(0UL, 7);
-#ifdef CONFIG_KGDB
-	/* If the kgdb is connected no debug regs should be altered. */
-	}
+	else
 #endif
+		clear_all_debug_regs();
 
 	fpu_init();
 
@@ -1105,7 +1185,8 @@ void __cpuinit cpu_init(void)
 
 	if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
 		printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
-		for (;;) local_irq_enable();
+		for (;;)
+			local_irq_enable();
 	}
 
 	printk(KERN_INFO "Initializing CPU#%d\n", cpu);
@@ -1114,15 +1195,14 @@ void __cpuinit cpu_init(void)
 		clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
 	load_idt(&idt_descr);
-	switch_to_new_gdt();
+	switch_to_new_gdt(cpu);
 
 	/*
 	 * Set up and load the per-CPU TSS and LDT
 	 */
 	atomic_inc(&init_mm.mm_count);
 	curr->active_mm = &init_mm;
-	if (curr->mm)
-		BUG();
+	BUG_ON(curr->mm);
 	enter_lazy_tlb(&init_mm, curr);
 
 	load_sp0(t, thread);
@@ -1130,21 +1210,14 @@ void __cpuinit cpu_init(void)
 	load_TR_desc();
 	load_LDT(&init_mm.context);
 
+	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+
 #ifdef CONFIG_DOUBLEFAULT
 	/* Set up doublefault TSS pointer in the GDT */
 	__set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
 #endif
 
-	/* Clear %gs. */
-	asm volatile ("mov %0, %%gs" : : "r" (0));
-
-	/* Clear all 6 debug registers: */
-	set_debugreg(0, 0);
-	set_debugreg(0, 1);
-	set_debugreg(0, 2);
-	set_debugreg(0, 3);
-	set_debugreg(0, 6);
-	set_debugreg(0, 7);
+	clear_all_debug_regs();
 
 	/*
 	 * Force FPU initialization:
@@ -1164,6 +1237,4 @@ void __cpuinit cpu_init(void)
 
 	xsave_init();
 }
-
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpu_debug.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpu_debug.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpu_debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpu_debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,901 @@
+/*
+ * 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_arr[CPU_REG_ALL_BIT]);
+static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
+static DEFINE_PER_CPU(unsigned, cpu_modelflag);
+static DEFINE_PER_CPU(int, cpu_priv_count);
+static DEFINE_PER_CPU(unsigned, cpu_model);
+
+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	},
+};
+
+/* Intel Registers Range */
+static struct cpu_debug_range cpu_intel_range[] = {
+	{ 0x00000000, 0x00000001, CPU_MC,	CPU_INTEL_ALL		},
+	{ 0x00000006, 0x00000007, CPU_MONITOR,	CPU_CX_AT_XE		},
+	{ 0x00000010, 0x00000010, CPU_TIME,	CPU_INTEL_ALL		},
+	{ 0x00000011, 0x00000013, CPU_PMC,	CPU_INTEL_PENTIUM	},
+	{ 0x00000017, 0x00000017, CPU_PLATFORM,	CPU_PX_CX_AT_XE		},
+	{ 0x0000001B, 0x0000001B, CPU_APIC,	CPU_P6_CX_AT_XE		},
+
+	{ 0x0000002A, 0x0000002A, CPU_POWERON,	CPU_PX_CX_AT_XE		},
+	{ 0x0000002B, 0x0000002B, CPU_POWERON,	CPU_INTEL_XEON		},
+	{ 0x0000002C, 0x0000002C, CPU_FREQ,	CPU_INTEL_XEON		},
+	{ 0x0000003A, 0x0000003A, CPU_CONTROL,	CPU_CX_AT_XE		},
+
+	{ 0x00000040, 0x00000043, CPU_LBRANCH,	CPU_PM_CX_AT_XE		},
+	{ 0x00000044, 0x00000047, CPU_LBRANCH,	CPU_PM_CO_AT		},
+	{ 0x00000060, 0x00000063, CPU_LBRANCH,	CPU_C2_AT		},
+	{ 0x00000064, 0x00000067, CPU_LBRANCH,	CPU_INTEL_ATOM		},
+
+	{ 0x00000079, 0x00000079, CPU_BIOS,	CPU_P6_CX_AT_XE		},
+	{ 0x00000088, 0x0000008A, CPU_CACHE,	CPU_INTEL_P6		},
+	{ 0x0000008B, 0x0000008B, CPU_BIOS,	CPU_P6_CX_AT_XE		},
+	{ 0x0000009B, 0x0000009B, CPU_MONITOR,	CPU_INTEL_XEON		},
+
+	{ 0x000000C1, 0x000000C2, CPU_PMC,	CPU_P6_CX_AT		},
+	{ 0x000000CD, 0x000000CD, CPU_FREQ,	CPU_CX_AT		},
+	{ 0x000000E7, 0x000000E8, CPU_PERF,	CPU_CX_AT		},
+	{ 0x000000FE, 0x000000FE, CPU_MTRR,	CPU_P6_CX_XE		},
+
+	{ 0x00000116, 0x00000116, CPU_CACHE,	CPU_INTEL_P6		},
+	{ 0x00000118, 0x00000118, CPU_CACHE,	CPU_INTEL_P6		},
+	{ 0x00000119, 0x00000119, CPU_CACHE,	CPU_INTEL_PX		},
+	{ 0x0000011A, 0x0000011B, CPU_CACHE,	CPU_INTEL_P6		},
+	{ 0x0000011E, 0x0000011E, CPU_CACHE,	CPU_PX_CX_AT		},
+
+	{ 0x00000174, 0x00000176, CPU_SYSENTER,	CPU_P6_CX_AT_XE		},
+	{ 0x00000179, 0x0000017A, CPU_MC,	CPU_PX_CX_AT_XE		},
+	{ 0x0000017B, 0x0000017B, CPU_MC,	CPU_P6_XE		},
+	{ 0x00000186, 0x00000187, CPU_PMC,	CPU_P6_CX_AT		},
+	{ 0x00000198, 0x00000199, CPU_PERF,	CPU_PM_CX_AT_XE		},
+	{ 0x0000019A, 0x0000019A, CPU_TIME,	CPU_PM_CX_AT_XE		},
+	{ 0x0000019B, 0x0000019D, CPU_THERM,	CPU_PM_CX_AT_XE		},
+	{ 0x000001A0, 0x000001A0, CPU_MISC,	CPU_PM_CX_AT_XE		},
+
+	{ 0x000001C9, 0x000001C9, CPU_LBRANCH,	CPU_PM_CX_AT		},
+	{ 0x000001D7, 0x000001D8, CPU_LBRANCH,	CPU_INTEL_XEON		},
+	{ 0x000001D9, 0x000001D9, CPU_DEBUG,	CPU_CX_AT_XE		},
+	{ 0x000001DA, 0x000001DA, CPU_LBRANCH,	CPU_INTEL_XEON		},
+	{ 0x000001DB, 0x000001DB, CPU_LBRANCH,	CPU_P6_XE		},
+	{ 0x000001DC, 0x000001DC, CPU_LBRANCH,	CPU_INTEL_P6		},
+	{ 0x000001DD, 0x000001DE, CPU_LBRANCH,	CPU_PX_CX_AT_XE		},
+	{ 0x000001E0, 0x000001E0, CPU_LBRANCH,	CPU_INTEL_P6		},
+
+	{ 0x00000200, 0x0000020F, CPU_MTRR,	CPU_P6_CX_XE		},
+	{ 0x00000250, 0x00000250, CPU_MTRR,	CPU_P6_CX_XE		},
+	{ 0x00000258, 0x00000259, CPU_MTRR,	CPU_P6_CX_XE		},
+	{ 0x00000268, 0x0000026F, CPU_MTRR,	CPU_P6_CX_XE		},
+	{ 0x00000277, 0x00000277, CPU_PAT,	CPU_C2_AT_XE		},
+	{ 0x000002FF, 0x000002FF, CPU_MTRR,	CPU_P6_CX_XE		},
+
+	{ 0x00000300, 0x00000308, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x00000309, 0x0000030B, CPU_PMC,	CPU_C2_AT_XE		},
+	{ 0x0000030C, 0x00000311, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x00000345, 0x00000345, CPU_PMC,	CPU_C2_AT		},
+	{ 0x00000360, 0x00000371, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x0000038D, 0x00000390, CPU_PMC,	CPU_C2_AT		},
+	{ 0x000003A0, 0x000003BE, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x000003C0, 0x000003CD, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x000003E0, 0x000003E1, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x000003F0, 0x000003F0, CPU_PMC,	CPU_INTEL_XEON		},
+	{ 0x000003F1, 0x000003F1, CPU_PMC,	CPU_C2_AT_XE		},
+	{ 0x000003F2, 0x000003F2, CPU_PMC,	CPU_INTEL_XEON		},
+
+	{ 0x00000400, 0x00000402, CPU_MC,	CPU_PM_CX_AT_XE		},
+	{ 0x00000403, 0x00000403, CPU_MC,	CPU_INTEL_XEON		},
+	{ 0x00000404, 0x00000406, CPU_MC,	CPU_PM_CX_AT_XE		},
+	{ 0x00000407, 0x00000407, CPU_MC,	CPU_INTEL_XEON		},
+	{ 0x00000408, 0x0000040A, CPU_MC,	CPU_PM_CX_AT_XE		},
+	{ 0x0000040B, 0x0000040B, CPU_MC,	CPU_INTEL_XEON		},
+	{ 0x0000040C, 0x0000040E, CPU_MC,	CPU_PM_CX_XE		},
+	{ 0x0000040F, 0x0000040F, CPU_MC,	CPU_INTEL_XEON		},
+	{ 0x00000410, 0x00000412, CPU_MC,	CPU_PM_CX_AT_XE		},
+	{ 0x00000413, 0x00000417, CPU_MC,	CPU_CX_AT_XE		},
+	{ 0x00000480, 0x0000048B, CPU_VMX,	CPU_CX_AT_XE		},
+
+	{ 0x00000600, 0x00000600, CPU_DEBUG,	CPU_PM_CX_AT_XE		},
+	{ 0x00000680, 0x0000068F, CPU_LBRANCH,	CPU_INTEL_XEON		},
+	{ 0x000006C0, 0x000006CF, CPU_LBRANCH,	CPU_INTEL_XEON		},
+
+	{ 0x000107CC, 0x000107D3, CPU_PMC,	CPU_INTEL_XEON_MP	},
+
+	{ 0xC0000080, 0xC0000080, CPU_FEATURES,	CPU_INTEL_XEON		},
+	{ 0xC0000081, 0xC0000082, CPU_CALL,	CPU_INTEL_XEON		},
+	{ 0xC0000084, 0xC0000084, CPU_CALL,	CPU_INTEL_XEON		},
+	{ 0xC0000100, 0xC0000102, CPU_BASE,	CPU_INTEL_XEON		},
+};
+
+/* AMD Registers Range */
+static struct cpu_debug_range cpu_amd_range[] = {
+	{ 0x00000000, 0x00000001, CPU_MC,	CPU_K10_PLUS,		},
+	{ 0x00000010, 0x00000010, CPU_TIME,	CPU_K8_PLUS,		},
+	{ 0x0000001B, 0x0000001B, CPU_APIC,	CPU_K8_PLUS,		},
+	{ 0x0000002A, 0x0000002A, CPU_POWERON,	CPU_K7_PLUS		},
+	{ 0x0000008B, 0x0000008B, CPU_VER,	CPU_K8_PLUS		},
+	{ 0x000000FE, 0x000000FE, CPU_MTRR,	CPU_K8_PLUS,		},
+
+	{ 0x00000174, 0x00000176, CPU_SYSENTER,	CPU_K8_PLUS,		},
+	{ 0x00000179, 0x0000017B, CPU_MC,	CPU_K8_PLUS,		},
+	{ 0x000001D9, 0x000001D9, CPU_DEBUG,	CPU_K8_PLUS,		},
+	{ 0x000001DB, 0x000001DE, CPU_LBRANCH,	CPU_K8_PLUS,		},
+
+	{ 0x00000200, 0x0000020F, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0x00000250, 0x00000250, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0x00000258, 0x00000259, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0x00000268, 0x0000026F, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0x00000277, 0x00000277, CPU_PAT,	CPU_K8_PLUS,		},
+	{ 0x000002FF, 0x000002FF, CPU_MTRR,	CPU_K8_PLUS,		},
+
+	{ 0x00000400, 0x00000413, CPU_MC,	CPU_K8_PLUS,		},
+
+	{ 0xC0000080, 0xC0000080, CPU_FEATURES,	CPU_AMD_ALL,		},
+	{ 0xC0000081, 0xC0000084, CPU_CALL,	CPU_K8_PLUS,		},
+	{ 0xC0000100, 0xC0000102, CPU_BASE,	CPU_K8_PLUS,		},
+	{ 0xC0000103, 0xC0000103, CPU_TIME,	CPU_K10_PLUS,		},
+
+	{ 0xC0010000, 0xC0010007, CPU_PMC,	CPU_K8_PLUS,		},
+	{ 0xC0010010, 0xC0010010, CPU_CONF,	CPU_K7_PLUS,		},
+	{ 0xC0010015, 0xC0010015, CPU_CONF,	CPU_K7_PLUS,		},
+	{ 0xC0010016, 0xC001001A, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0xC001001D, 0xC001001D, CPU_MTRR,	CPU_K8_PLUS,		},
+	{ 0xC001001F, 0xC001001F, CPU_CONF,	CPU_K8_PLUS,		},
+	{ 0xC0010030, 0xC0010035, CPU_BIOS,	CPU_K8_PLUS,		},
+	{ 0xC0010044, 0xC0010048, CPU_MC,	CPU_K8_PLUS,		},
+	{ 0xC0010050, 0xC0010056, CPU_SMM,	CPU_K0F_PLUS,		},
+	{ 0xC0010058, 0xC0010058, CPU_CONF,	CPU_K10_PLUS,		},
+	{ 0xC0010060, 0xC0010060, CPU_CACHE,	CPU_AMD_11,		},
+	{ 0xC0010061, 0xC0010068, CPU_SMM,	CPU_K10_PLUS,		},
+	{ 0xC0010069, 0xC001006B, CPU_SMM,	CPU_AMD_11,		},
+	{ 0xC0010070, 0xC0010071, CPU_SMM,	CPU_K10_PLUS,		},
+	{ 0xC0010111, 0xC0010113, CPU_SMM,	CPU_K8_PLUS,		},
+	{ 0xC0010114, 0xC0010118, CPU_SVM,	CPU_K10_PLUS,		},
+	{ 0xC0010140, 0xC0010141, CPU_OSVM,	CPU_K10_PLUS,		},
+	{ 0xC0011022, 0xC0011023, CPU_CONF,	CPU_K10_PLUS,		},
+};
+
+
+/* Intel */
+static int get_intel_modelflag(unsigned model)
+{
+	int flag;
+
+	switch (model) {
+	case 0x0501:
+	case 0x0502:
+	case 0x0504:
+		flag = CPU_INTEL_PENTIUM;
+		break;
+	case 0x0601:
+	case 0x0603:
+	case 0x0605:
+	case 0x0607:
+	case 0x0608:
+	case 0x060A:
+	case 0x060B:
+		flag = CPU_INTEL_P6;
+		break;
+	case 0x0609:
+	case 0x060D:
+		flag = CPU_INTEL_PENTIUM_M;
+		break;
+	case 0x060E:
+		flag = CPU_INTEL_CORE;
+		break;
+	case 0x060F:
+	case 0x0617:
+		flag = CPU_INTEL_CORE2;
+		break;
+	case 0x061C:
+		flag = CPU_INTEL_ATOM;
+		break;
+	case 0x0F00:
+	case 0x0F01:
+	case 0x0F02:
+	case 0x0F03:
+	case 0x0F04:
+		flag = CPU_INTEL_XEON_P4;
+		break;
+	case 0x0F06:
+		flag = CPU_INTEL_XEON_MP;
+		break;
+	default:
+		flag = CPU_NONE;
+		break;
+	}
+
+	return flag;
+}
+
+/* AMD */
+static int get_amd_modelflag(unsigned model)
+{
+	int flag;
+
+	switch (model >> 8) {
+	case 0x6:
+		flag = CPU_AMD_K6;
+		break;
+	case 0x7:
+		flag = CPU_AMD_K7;
+		break;
+	case 0x8:
+		flag = CPU_AMD_K8;
+		break;
+	case 0xf:
+		flag = CPU_AMD_0F;
+		break;
+	case 0x10:
+		flag = CPU_AMD_10;
+		break;
+	case 0x11:
+		flag = CPU_AMD_11;
+		break;
+	default:
+		flag = CPU_NONE;
+		break;
+	}
+
+	return flag;
+}
+
+static int get_cpu_modelflag(unsigned cpu)
+{
+	int flag;
+
+	flag = per_cpu(cpu_model, cpu);
+
+	switch (flag >> 16) {
+	case X86_VENDOR_INTEL:
+		flag = get_intel_modelflag(flag);
+		break;
+	case X86_VENDOR_AMD:
+		flag = get_amd_modelflag(flag & 0xffff);
+		break;
+	default:
+		flag = CPU_NONE;
+		break;
+	}
+
+	return flag;
+}
+
+static int get_cpu_range_count(unsigned cpu)
+{
+	int index;
+
+	switch (per_cpu(cpu_model, cpu) >> 16) {
+	case X86_VENDOR_INTEL:
+		index = ARRAY_SIZE(cpu_intel_range);
+		break;
+	case X86_VENDOR_AMD:
+		index = ARRAY_SIZE(cpu_amd_range);
+		break;
+	default:
+		index = 0;
+		break;
+	}
+
+	return index;
+}
+
+static int is_typeflag_valid(unsigned cpu, unsigned flag)
+{
+	unsigned vendor, modelflag;
+	int i, index;
+
+	/* Standard Registers should be always valid */
+	if (flag >= CPU_TSS)
+		return 1;
+
+	modelflag = per_cpu(cpu_modelflag, cpu);
+	vendor = per_cpu(cpu_model, cpu) >> 16;
+	index = get_cpu_range_count(cpu);
+
+	for (i = 0; i < index; i++) {
+		switch (vendor) {
+		case X86_VENDOR_INTEL:
+			if ((cpu_intel_range[i].model & modelflag) &&
+			    (cpu_intel_range[i].flag & flag))
+				return 1;
+			break;
+		case X86_VENDOR_AMD:
+			if ((cpu_amd_range[i].model & modelflag) &&
+			    (cpu_amd_range[i].flag & flag))
+				return 1;
+			break;
+		}
+	}
+
+	/* Invalid */
+	return 0;
+}
+
+static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
+			      int index, unsigned flag)
+{
+	unsigned modelflag;
+
+	modelflag = per_cpu(cpu_modelflag, cpu);
+	*max = 0;
+	switch (per_cpu(cpu_model, cpu) >> 16) {
+	case X86_VENDOR_INTEL:
+		if ((cpu_intel_range[index].model & modelflag) &&
+		    (cpu_intel_range[index].flag & flag)) {
+			*min = cpu_intel_range[index].min;
+			*max = cpu_intel_range[index].max;
+		}
+		break;
+	case X86_VENDOR_AMD:
+		if ((cpu_amd_range[index].model & modelflag) &&
+		    (cpu_amd_range[index].flag & flag)) {
+			*min = cpu_amd_range[index].min;
+			*max = cpu_amd_range[index].max;
+		}
+		break;
+	}
+
+	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, range;
+
+	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;
+		}
+	}
+
+	range = get_cpu_range_count(cpu);
+
+	for (i = 0; i < 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));
+#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, range, err = 0;
+	char reg_dir[12];
+	u32 low, high;
+
+	range = get_cpu_range_count(cpu);
+
+	for (i = 0; i < 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;
+		per_cpu(cpu_model, cpu) = ((cpui->x86_vendor << 16) |
+					   (cpui->x86 << 8) |
+					   (cpui->x86_model));
+		per_cpu(cpu_modelflag, cpu) = get_cpu_modelflag(cpu);
+
+		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.29-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
+ * acpi-cpufreq.c - ACPI Processor P-States Driver
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -33,19 +33,21 @@
 #include <linux/cpufreq.h>
 #include <linux/compiler.h>
 #include <linux/dmi.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
 
 #include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+
 #include <acpi/processor.h>
 
-#include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"acpi-cpufreq", msg)
 
 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
@@ -63,13 +65,20 @@ enum {
 struct acpi_cpufreq_data {
 	struct acpi_processor_performance *acpi_data;
 	struct cpufreq_frequency_table *freq_table;
-	unsigned int max_freq;
 	unsigned int resume;
 	unsigned int cpu_feature;
 };
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
 
+struct acpi_msr_data {
+	u64 saved_aperf, saved_mperf;
+};
+
+static DEFINE_PER_CPU(struct acpi_msr_data, msr_data);
+
+DEFINE_TRACE(power_mark);
+
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
 
@@ -95,7 +104,7 @@ static unsigned extract_io(u32 value, st
 
 	perf = data->acpi_data;
 
-	for (i=0; i<perf->state_count; i++) {
+	for (i = 0; i < perf->state_count; i++) {
 		if (value == perf->states[i].status)
 			return data->freq_table[i].frequency;
 	}
@@ -110,7 +119,7 @@ static unsigned extract_msr(u32 msr, str
 	msr &= INTEL_MSR_RANGE;
 	perf = data->acpi_data;
 
-	for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
 		if (msr == perf->states[data->freq_table[i].index].status)
 			return data->freq_table[i].frequency;
 	}
@@ -138,19 +147,18 @@ struct io_addr {
 	u8 bit_width;
 };
 
-typedef union {
-	struct msr_addr msr;
-	struct io_addr io;
-} drv_addr_union;
-
 struct drv_cmd {
 	unsigned int type;
 	const struct cpumask *mask;
-	drv_addr_union addr;
+	union {
+		struct msr_addr msr;
+		struct io_addr io;
+	} addr;
 	u32 val;
 };
 
-static long do_drv_read(void *_cmd)
+/* Called via smp_call_function_single(), on the target CPU */
+static void do_drv_read(void *_cmd)
 {
 	struct drv_cmd *cmd = _cmd;
 	u32 h;
@@ -167,10 +175,10 @@ static long do_drv_read(void *_cmd)
 	default:
 		break;
 	}
-	return 0;
 }
 
-static long do_drv_write(void *_cmd)
+/* Called via smp_call_function_many(), on the target CPUs */
+static void do_drv_write(void *_cmd)
 {
 	struct drv_cmd *cmd = _cmd;
 	u32 lo, hi;
@@ -189,23 +197,24 @@ static long do_drv_write(void *_cmd)
 	default:
 		break;
 	}
-	return 0;
 }
 
 static void drv_read(struct drv_cmd *cmd)
 {
 	cmd->val = 0;
 
-	work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd);
+	smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1);
 }
 
 static void drv_write(struct drv_cmd *cmd)
 {
-	unsigned int i;
+	int this_cpu;
 
-	for_each_cpu(i, cmd->mask) {
-		work_on_cpu(i, do_drv_write, cmd);
-	}
+	this_cpu = get_cpu();
+	if (cpumask_test_cpu(this_cpu, cmd->mask))
+		do_drv_write(cmd);
+	smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
+	put_cpu();
 }
 
 static u32 get_cur_val(const struct cpumask *mask)
@@ -239,28 +248,23 @@ static u32 get_cur_val(const struct cpum
 	return cmd.val;
 }
 
-struct perf_cur {
+struct perf_pair {
 	union {
 		struct {
 			u32 lo;
 			u32 hi;
 		} split;
 		u64 whole;
-	} aperf_cur, mperf_cur;
+	} aperf, mperf;
 };
 
-
-static long read_measured_perf_ctrs(void *_cur)
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
 {
-	struct perf_cur *cur = _cur;
-
-	rdmsr(MSR_IA32_APERF, cur->aperf_cur.split.lo, cur->aperf_cur.split.hi);
-	rdmsr(MSR_IA32_MPERF, cur->mperf_cur.split.lo, cur->mperf_cur.split.hi);
-
-	wrmsr(MSR_IA32_APERF, 0, 0);
-	wrmsr(MSR_IA32_MPERF, 0, 0);
+	struct perf_pair *cur = _cur;
 
-	return 0;
+	rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
+	rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
 }
 
 /*
@@ -279,58 +283,63 @@ static long read_measured_perf_ctrs(void
 static unsigned int get_measured_perf(struct cpufreq_policy *policy,
 				      unsigned int cpu)
 {
-	struct perf_cur cur;
+	struct perf_pair readin, cur;
 	unsigned int perf_percent;
 	unsigned int retval;
 
-	if (!work_on_cpu(cpu, read_measured_perf_ctrs, &cur))
+	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1))
 		return 0;
 
+	cur.aperf.whole = readin.aperf.whole -
+				per_cpu(msr_data, cpu).saved_aperf;
+	cur.mperf.whole = readin.mperf.whole -
+				per_cpu(msr_data, cpu).saved_mperf;
+	per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole;
+	per_cpu(msr_data, cpu).saved_mperf = readin.mperf.whole;
+
 #ifdef __i386__
 	/*
 	 * We dont want to do 64 bit divide with 32 bit kernel
 	 * Get an approximate value. Return failure in case we cannot get
 	 * an approximate value.
 	 */
-	if (unlikely(cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) {
+	if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
 		int shift_count;
 		u32 h;
 
-		h = max_t(u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi);
+		h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi);
 		shift_count = fls(h);
 
-		cur.aperf_cur.whole >>= shift_count;
-		cur.mperf_cur.whole >>= shift_count;
+		cur.aperf.whole >>= shift_count;
+		cur.mperf.whole >>= shift_count;
 	}
 
-	if (((unsigned long)(-1) / 100) < cur.aperf_cur.split.lo) {
+	if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
 		int shift_count = 7;
-		cur.aperf_cur.split.lo >>= shift_count;
-		cur.mperf_cur.split.lo >>= shift_count;
+		cur.aperf.split.lo >>= shift_count;
+		cur.mperf.split.lo >>= shift_count;
 	}
 
-	if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo)
-		perf_percent = (cur.aperf_cur.split.lo * 100) /
-				cur.mperf_cur.split.lo;
+	if (cur.aperf.split.lo && cur.mperf.split.lo)
+		perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
 	else
 		perf_percent = 0;
 
 #else
-	if (unlikely(((unsigned long)(-1) / 100) < cur.aperf_cur.whole)) {
+	if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
 		int shift_count = 7;
-		cur.aperf_cur.whole >>= shift_count;
-		cur.mperf_cur.whole >>= shift_count;
+		cur.aperf.whole >>= shift_count;
+		cur.mperf.whole >>= shift_count;
 	}
 
-	if (cur.aperf_cur.whole && cur.mperf_cur.whole)
-		perf_percent = (cur.aperf_cur.whole * 100) /
-				cur.mperf_cur.whole;
+	if (cur.aperf.whole && cur.mperf.whole)
+		perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
 	else
 		perf_percent = 0;
 
 #endif
 
-	retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100;
+	retval = (policy->cpuinfo.max_freq * perf_percent) / 100;
 
 	return retval;
 }
@@ -369,7 +378,7 @@ static unsigned int check_freqs(const st
 	unsigned int cur_freq;
 	unsigned int i;
 
-	for (i=0; i<100; i++) {
+	for (i = 0; i < 100; i++) {
 		cur_freq = extract_freq(get_cur_val(mask), data);
 		if (cur_freq == freq)
 			return 1;
@@ -494,7 +503,7 @@ acpi_cpufreq_guess_freq(struct acpi_cpuf
 		unsigned long freq;
 		unsigned long freqn = perf->states[0].core_frequency * 1000;
 
-		for (i=0; i<(perf->state_count-1); i++) {
+		for (i = 0; i < (perf->state_count-1); i++) {
 			freq = freqn;
 			freqn = perf->states[i+1].core_frequency * 1000;
 			if ((2 * cpu_khz) > (freqn + freq)) {
@@ -541,7 +550,7 @@ static int __init acpi_cpufreq_early_ini
 		return -ENOMEM;
 	}
 	for_each_possible_cpu(i) {
-		if (!alloc_cpumask_var_node(
+		if (!zalloc_cpumask_var_node(
 			&per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map,
 			GFP_KERNEL, cpu_to_node(i))) {
 
@@ -601,7 +610,7 @@ static int acpi_cpufreq_cpu_init(struct
 	if (!data)
 		return -ENOMEM;
 
-	data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
+	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
 	per_cpu(drv_data, cpu) = data;
 
 	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
@@ -673,17 +682,24 @@ static int acpi_cpufreq_cpu_init(struct
 
 	/* detect transition latency */
 	policy->cpuinfo.transition_latency = 0;
-	for (i=0; i<perf->state_count; i++) {
+	for (i = 0; i < perf->state_count; i++) {
 		if ((perf->states[i].transition_latency * 1000) >
 		    policy->cpuinfo.transition_latency)
 			policy->cpuinfo.transition_latency =
 			    perf->states[i].transition_latency * 1000;
 	}
 
-	data->max_freq = perf->states[0].core_frequency * 1000;
+	/* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
+	if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
+	    policy->cpuinfo.transition_latency > 20 * 1000) {
+		policy->cpuinfo.transition_latency = 20 * 1000;
+		printk_once(KERN_INFO
+			    "P-state transition latency capped at 20 uS\n");
+	}
+
 	/* table init */
-	for (i=0; i<perf->state_count; i++) {
-		if (i>0 && perf->states[i].core_frequency >=
+	for (i = 0; i < perf->state_count; i++) {
+		if (i > 0 && perf->states[i].core_frequency >=
 		    data->freq_table[valid_states-1].frequency / 1000)
 			continue;
 
@@ -699,6 +715,9 @@ static int acpi_cpufreq_cpu_init(struct
 	if (result)
 		goto err_freqfree;
 
+	if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
+		printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n");
+
 	switch (perf->control_register.space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 		/* Current speed is unknown and not detectable by IO port */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@
  * nforce2_chipset:
  * FSB is changed using the chipset
  */
-static struct pci_dev *nforce2_chipset_dev;
+static struct pci_dev *nforce2_dev;
 
 /* fid:
  * multiplier * 10
@@ -56,7 +56,9 @@ MODULE_PARM_DESC(fid, "CPU multiplier to
 MODULE_PARM_DESC(min_fsb,
 		"Minimum FSB to use, if not defined: current FSB - 50");
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
+#define PFX "cpufreq-nforce2: "
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"cpufreq-nforce2", msg)
 
 /**
  * nforce2_calc_fsb - calculate FSB
@@ -118,11 +120,11 @@ static void nforce2_write_pll(int pll)
 	int temp;
 
 	/* Set the pll addr. to 0x00 */
-	pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0);
+	pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);
 
 	/* Now write the value in all 64 registers */
 	for (temp = 0; temp <= 0x3f; temp++)
-		pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll);
+		pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
 
 	return;
 }
@@ -139,8 +141,8 @@ static unsigned int nforce2_fsb_read(int
 	u32 fsb, temp = 0;
 
 	/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
-	nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
-						0x01EF, PCI_ANY_ID, PCI_ANY_ID, NULL);
+	nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF,
+				PCI_ANY_ID, PCI_ANY_ID, NULL);
 	if (!nforce2_sub5)
 		return 0;
 
@@ -148,13 +150,13 @@ static unsigned int nforce2_fsb_read(int
 	fsb /= 1000000;
 
 	/* Check if PLL register is already set */
-	pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
 
 	if (bootfsb || !temp)
 		return fsb;
 
 	/* Use PLL register FSB value */
-	pci_read_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, &temp);
+	pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp);
 	fsb = nforce2_calc_fsb(temp);
 
 	return fsb;
@@ -174,18 +176,18 @@ static int nforce2_set_fsb(unsigned int
 	int pll = 0;
 
 	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
-		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
+		printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb);
 		return -EINVAL;
 	}
 
 	tfsb = nforce2_fsb_read(0);
 	if (!tfsb) {
-		printk(KERN_ERR "cpufreq: Error while reading the FSB\n");
+		printk(KERN_ERR PFX "Error while reading the FSB\n");
 		return -EINVAL;
 	}
 
 	/* First write? Then set actual value */
-	pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
 	if (!temp) {
 		pll = nforce2_calc_pll(tfsb);
 
@@ -197,7 +199,7 @@ static int nforce2_set_fsb(unsigned int
 
 	/* Enable write access */
 	temp = 0x01;
-	pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp);
+	pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp);
 
 	diff = tfsb - fsb;
 
@@ -222,7 +224,7 @@ static int nforce2_set_fsb(unsigned int
 	}
 
 	temp = 0x40;
-	pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp);
+	pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp);
 
 	return 0;
 }
@@ -244,7 +246,8 @@ static unsigned int nforce2_get(unsigned
  * nforce2_target - set a new CPUFreq policy
  * @policy: new policy
  * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
  *
  * Sets a new CPUFreq policy.
  */
@@ -276,7 +279,7 @@ static int nforce2_target(struct cpufreq
 	/* local_irq_save(flags); */
 
 	if (nforce2_set_fsb(target_fsb) < 0)
-		printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
+		printk(KERN_ERR PFX "Changing FSB to %d failed\n",
 			target_fsb);
 	else
 		dprintk("Changed FSB successfully to %d\n",
@@ -327,8 +330,8 @@ static int nforce2_cpu_init(struct cpufr
 	/* FIX: Get FID from CPU */
 	if (!fid) {
 		if (!cpu_khz) {
-			printk(KERN_WARNING
-			       "cpufreq: cpu_khz not set, can't calculate multiplier!\n");
+			printk(KERN_WARNING PFX
+			"cpu_khz not set, can't calculate multiplier!\n");
 			return -ENODEV;
 		}
 
@@ -343,7 +346,7 @@ static int nforce2_cpu_init(struct cpufr
 		}
 	}
 
-	printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb,
+	printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb,
 	       fid / 10, fid % 10);
 
 	/* Set maximum FSB to FSB at boot time */
@@ -392,17 +395,18 @@ static struct cpufreq_driver nforce2_dri
  */
 static unsigned int nforce2_detect_chipset(void)
 {
-	nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
+	nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
 					PCI_DEVICE_ID_NVIDIA_NFORCE2,
 					PCI_ANY_ID, PCI_ANY_ID, NULL);
 
-	if (nforce2_chipset_dev == NULL)
+	if (nforce2_dev == NULL)
 		return -ENODEV;
 
-	printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
-	       nforce2_chipset_dev->revision);
-	printk(KERN_INFO
-	       "cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
+	printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n",
+	       nforce2_dev->revision);
+	printk(KERN_INFO PFX
+	       "FSB changing is maybe unstable and can lead to "
+	       "crashes and data loss.\n");
 
 	return 0;
 }
@@ -420,7 +424,7 @@ static int __init nforce2_init(void)
 
 	/* detect chipset */
 	if (nforce2_detect_chipset()) {
-		printk(KERN_ERR "cpufreq: No nForce2 chipset.\n");
+		printk(KERN_INFO PFX "No nForce2 chipset.\n");
 		return -ENODEV;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/elanfreq.c	2009-06-09 23:05:27.000000000 -0400
@@ -184,7 +184,8 @@ static int elanfreq_target(struct cpufre
 {
 	unsigned int newstate = 0;
 
-	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	elanfreq_set_cpu_state(newstate);
@@ -301,7 +302,8 @@ static void __exit elanfreq_exit(void)
 module_param(max_freq, int, 0444);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
+MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, "
+		"Sven Geggus <sven@geggus.net>");
 MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
 
 module_init(elanfreq_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/e_powersaver.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/e_powersaver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/e_powersaver.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,12 +12,12 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
 
 #include <asm/msr.h>
 #include <asm/tsc.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/delay.h>
 
 #define EPS_BRAND_C7M	0
 #define EPS_BRAND_C7	1
@@ -184,7 +184,7 @@ static int eps_cpu_init(struct cpufreq_p
 		break;
 	}
 
-	switch(brand) {
+	switch (brand) {
 	case EPS_BRAND_C7M:
 		printk(KERN_CONT "C7-M\n");
 		break;
@@ -204,12 +204,12 @@ static int eps_cpu_init(struct cpufreq_p
 	}
 	/* Enable Enhanced PowerSaver */
 	rdmsrl(MSR_IA32_MISC_ENABLE, val);
-	if (!(val & 1 << 16)) {
-		val |= 1 << 16;
+	if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+		val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
 		wrmsrl(MSR_IA32_MISC_ENABLE, val);
 		/* Can be locked at 0 */
 		rdmsrl(MSR_IA32_MISC_ENABLE, val);
-		if (!(val & 1 << 16)) {
+		if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
 			printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
 			return -ENODEV;
 		}
@@ -218,17 +218,20 @@ static int eps_cpu_init(struct cpufreq_p
 	/* Print voltage and multiplier */
 	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
 	current_voltage = lo & 0xff;
-	printk(KERN_INFO "eps: Current voltage = %dmV\n", current_voltage * 16 + 700);
+	printk(KERN_INFO "eps: Current voltage = %dmV\n",
+			current_voltage * 16 + 700);
 	current_multiplier = (lo >> 8) & 0xff;
 	printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
 
 	/* Print limits */
 	max_voltage = hi & 0xff;
-	printk(KERN_INFO "eps: Highest voltage = %dmV\n", max_voltage * 16 + 700);
+	printk(KERN_INFO "eps: Highest voltage = %dmV\n",
+			max_voltage * 16 + 700);
 	max_multiplier = (hi >> 8) & 0xff;
 	printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
 	min_voltage = (hi >> 16) & 0xff;
-	printk(KERN_INFO "eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700);
+	printk(KERN_INFO "eps: Lowest voltage = %dmV\n",
+			min_voltage * 16 + 700);
 	min_multiplier = (hi >> 24) & 0xff;
 	printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
 
@@ -318,7 +321,7 @@ static int eps_cpu_exit(struct cpufreq_p
 	return 0;
 }
 
-static struct freq_attr* eps_attr[] = {
+static struct freq_attr *eps_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -356,7 +359,7 @@ static void __exit eps_exit(void)
 	cpufreq_unregister_driver(&eps_driver);
 }
 
-MODULE_AUTHOR("Rafa³ Bilski <rafalbilski@interia.pl>");
+MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
 MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,8 +79,9 @@
 #include <linux/smp.h>
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
+#include <linux/errno.h>
+
 #include <asm/processor-cyrix.h>
-#include <asm/errno.h>
 
 /* PCI config registers, all at F0 */
 #define PCI_PMER1	0x80	/* power management enable register 1 */
@@ -122,8 +123,8 @@ static struct gxfreq_params *gx_params;
 static int stock_freq;
 
 /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
-static int pci_busclk = 0;
-module_param (pci_busclk, int, 0444);
+static int pci_busclk;
+module_param(pci_busclk, int, 0444);
 
 /* maximum duration for which the cpu may be suspended
  * (32us * MAX_DURATION). If no parameter is given, this defaults
@@ -132,7 +133,7 @@ module_param (pci_busclk, int, 0444);
  * is suspended -- processing power is just 0.39% of what it used to be,
  * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
 static int max_duration = 255;
-module_param (max_duration, int, 0444);
+module_param(max_duration, int, 0444);
 
 /* For the default policy, we want at least some processing power
  * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
@@ -140,7 +141,8 @@ module_param (max_duration, int, 0444);
 #define POLICY_MIN_DIV 20
 
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"gx-suspmod", msg)
 
 /**
  * we can detect a core multipiler from dir0_lsb
@@ -166,12 +168,20 @@ static int gx_freq_mult[16] = {
  *	Low Level chipset interface				*
  ****************************************************************/
 static struct pci_device_id gx_chipset_tbl[] __initdata = {
-	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510,
+		PCI_ANY_ID, PCI_ANY_ID },
 	{ 0, },
 };
 
+static void gx_write_byte(int reg, int value)
+{
+	pci_write_config_byte(gx_params->cs55x0, reg, value);
+}
+
 /**
  * gx_detect_chipset:
  *
@@ -200,7 +210,8 @@ static __init struct pci_dev *gx_detect_
 /**
  * gx_get_cpuspeed:
  *
- * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs.
+ * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi
+ * Geode CPU runs.
  */
 static unsigned int gx_get_cpuspeed(unsigned int cpu)
 {
@@ -217,17 +228,18 @@ static unsigned int gx_get_cpuspeed(unsi
  *
  **/
 
-static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration)
+static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration,
+		u8 *off_duration)
 {
 	unsigned int i;
 	u8 tmp_on, tmp_off;
 	int old_tmp_freq = stock_freq;
 	int tmp_freq;
 
-	*off_duration=1;
-	*on_duration=0;
+	*off_duration = 1;
+	*on_duration = 0;
 
-	for (i=max_duration; i>0; i--) {
+	for (i = max_duration; i > 0; i--) {
 		tmp_off = ((khz * i) / stock_freq) & 0xff;
 		tmp_on = i - tmp_off;
 		tmp_freq = (stock_freq * tmp_off) / i;
@@ -259,26 +271,34 @@ static void gx_set_cpuspeed(unsigned int
 	freqs.cpu = 0;
 	freqs.old = gx_get_cpuspeed(0);
 
-	new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration);
+	new_khz = gx_validate_speed(khz, &gx_params->on_duration,
+			&gx_params->off_duration);
 
 	freqs.new = new_khz;
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 	local_irq_save(flags);
 
-	if (new_khz != stock_freq) {  /* if new khz == 100% of CPU speed, it is special case */
+
+
+	if (new_khz != stock_freq) {
+		/* if new khz == 100% of CPU speed, it is special case */
 		switch (gx_params->cs55x0->device) {
 		case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
 			pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
 			/* FIXME: need to test other values -- Zwane,Miura */
-			pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */
-			pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
-			pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
+			/* typical 2 to 4ms */
+			gx_write_byte(PCI_IRQTC, 4);
+			/* typical 50 to 100ms */
+			gx_write_byte(PCI_VIDTC, 100);
+			gx_write_byte(PCI_PMER1, pmer1);
 
-			if (gx_params->cs55x0->revision < 0x10) {   /* CS5530(rev 1.2, 1.3) */
-				suscfg = gx_params->pci_suscfg | SUSMOD;
-			} else {                           /* CS5530A,B.. */
-				suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
+			if (gx_params->cs55x0->revision < 0x10) {
+				/* CS5530(rev 1.2, 1.3) */
+				suscfg = gx_params->pci_suscfg|SUSMOD;
+			} else {
+				/* CS5530A,B.. */
+				suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE;
 			}
 			break;
 		case PCI_DEVICE_ID_CYRIX_5520:
@@ -294,13 +314,13 @@ static void gx_set_cpuspeed(unsigned int
 		suscfg = gx_params->pci_suscfg & ~(SUSMOD);
 		gx_params->off_duration = 0;
 		gx_params->on_duration = 0;
-		dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n");
+		dprintk("suspend modulation disabled: cpu runs 100%% speed.\n");
 	}
 
-	pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration);
-	pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration);
+	gx_write_byte(PCI_MODOFF, gx_params->off_duration);
+	gx_write_byte(PCI_MODON, gx_params->on_duration);
 
-	pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg);
+	gx_write_byte(PCI_SUSCFG, suscfg);
 	pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg);
 
 	local_irq_restore(flags);
@@ -334,7 +354,8 @@ static int cpufreq_gx_verify(struct cpuf
 		return -EINVAL;
 
 	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+			stock_freq);
 
 	/* it needs to be assured that at least one supported frequency is
 	 * within policy->min and policy->max. If it is not, policy->max
@@ -354,7 +375,8 @@ static int cpufreq_gx_verify(struct cpuf
 	policy->max = tmp_freq;
 	if (policy->max < policy->min)
 		policy->max = policy->min;
-	cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+			stock_freq);
 
 	return 0;
 }
@@ -398,18 +420,18 @@ static int cpufreq_gx_cpu_init(struct cp
 		return -ENODEV;
 
 	/* determine maximum frequency */
-	if (pci_busclk) {
+	if (pci_busclk)
 		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-	} else if (cpu_khz) {
+	else if (cpu_khz)
 		maxfreq = cpu_khz;
-	} else {
+	else
 		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-	}
+
 	stock_freq = maxfreq;
 	curfreq = gx_get_cpuspeed(0);
 
 	dprintk("cpu max frequency is %d.\n", maxfreq);
-	dprintk("cpu current frequency is %dkHz.\n",curfreq);
+	dprintk("cpu current frequency is %dkHz.\n", curfreq);
 
 	/* setup basic struct for cpufreq API */
 	policy->cpu = 0;
@@ -447,7 +469,8 @@ static int __init cpufreq_gx_init(void)
 	struct pci_dev *gx_pci;
 
 	/* Test if we have the right hardware */
-	if ((gx_pci = gx_detect_chipset()) == NULL)
+	gx_pci = gx_detect_chipset();
+	if (gx_pci == NULL)
 		return -ENODEV;
 
 	/* check whether module parameters are sane */
@@ -468,9 +491,11 @@ static int __init cpufreq_gx_init(void)
 	pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1));
 	pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
 	pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
-	pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration));
+	pci_read_config_byte(params->cs55x0, PCI_MODOFF,
+			&(params->off_duration));
 
-	if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) {
+	ret = cpufreq_register_driver(&gx_suspmod_driver);
+	if (ret) {
 		kfree(params);
 		return ret;                   /* register error! */
 	}
@@ -485,9 +510,9 @@ static void __exit cpufreq_gx_exit(void)
 	kfree(gx_params);
 }
 
-MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
-MODULE_DESCRIPTION ("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>");
+MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
+MODULE_LICENSE("GPL");
 
 module_init(cpufreq_gx_init);
 module_exit(cpufreq_gx_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -87,30 +87,15 @@ config X86_POWERNOW_K7_ACPI
 config X86_POWERNOW_K8
 	tristate "AMD Opteron/Athlon64 PowerNow!"
 	select CPU_FREQ_TABLE
+	depends on ACPI && ACPI_PROCESSOR
 	help
-	  This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
+	  This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called powernow-k8.
 
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
-	  If in doubt, say N.
-
-config X86_POWERNOW_K8_ACPI
-	bool
-	prompt "ACPI Support" if X86_32
-	depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR
-	depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
-	default y
-	help
-	  This provides access to the K8s Processor Performance States via ACPI.
-	  This driver is probably required for CPUFreq to work with multi-socket and
-	  SMP systems.  It is not required on at least some single-socket yet
-	  multi-core systems, even if SMP is enabled.
-
-	  It is safe to say Y here.
-
 config X86_GX_SUSPMOD
 	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
 	depends on X86_32 && PCI
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,12 +30,11 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/acpi.h>
 
 #include <asm/msr.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/acpi.h>
-#include <linux/acpi.h>
 #include <acpi/processor.h>
 
 #include "longhaul.h"
@@ -58,7 +57,7 @@
 #define USE_NORTHBRIDGE		(1 << 2)
 
 static int cpu_model;
-static unsigned int numscales=16;
+static unsigned int numscales = 16;
 static unsigned int fsb;
 
 static const struct mV_pos *vrm_mV_table;
@@ -67,8 +66,8 @@ static const unsigned char *mV_vrm_table
 static unsigned int highest_speed, lowest_speed; /* kHz */
 static unsigned int minmult, maxmult;
 static int can_scale_voltage;
-static struct acpi_processor *pr = NULL;
-static struct acpi_processor_cx *cx = NULL;
+static struct acpi_processor *pr;
+static struct acpi_processor_cx *cx;
 static u32 acpi_regs_addr;
 static u8 longhaul_flags;
 static unsigned int longhaul_index;
@@ -78,12 +77,13 @@ static int scale_voltage;
 static int disable_acpi_c3;
 static int revid_errata;
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"longhaul", msg)
 
 
 /* Clock ratios multiplied by 10 */
-static int clock_ratio[32];
-static int eblcr_table[32];
+static int mults[32];
+static int eblcr[32];
 static int longhaul_version;
 static struct cpufreq_frequency_table *longhaul_table;
 
@@ -93,7 +93,7 @@ static char speedbuffer[8];
 static char *print_speed(int speed)
 {
 	if (speed < 1000) {
-		snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed);
+		snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
 		return speedbuffer;
 	}
 
@@ -122,27 +122,28 @@ static unsigned int calc_speed(int mult)
 
 static int longhaul_get_cpu_mult(void)
 {
-	unsigned long invalue=0,lo, hi;
+	unsigned long invalue = 0, lo, hi;
 
-	rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
-	invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
-	if (longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) {
+	rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
+	invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
+	if (longhaul_version == TYPE_LONGHAUL_V2 ||
+	    longhaul_version == TYPE_POWERSAVER) {
 		if (lo & (1<<27))
-			invalue+=16;
+			invalue += 16;
 	}
-	return eblcr_table[invalue];
+	return eblcr[invalue];
 }
 
 /* For processor with BCR2 MSR */
 
-static void do_longhaul1(unsigned int clock_ratio_index)
+static void do_longhaul1(unsigned int mults_index)
 {
 	union msr_bcr2 bcr2;
 
 	rdmsrl(MSR_VIA_BCR2, bcr2.val);
 	/* Enable software clock multiplier */
 	bcr2.bits.ESOFTBF = 1;
-	bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff;
+	bcr2.bits.CLOCKMUL = mults_index & 0xff;
 
 	/* Sync to timer tick */
 	safe_halt();
@@ -161,7 +162,7 @@ static void do_longhaul1(unsigned int cl
 
 /* For processor with Longhaul MSR */
 
-static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
+static void do_powersaver(int cx_address, unsigned int mults_index,
 			  unsigned int dir)
 {
 	union msr_longhaul longhaul;
@@ -173,11 +174,11 @@ static void do_powersaver(int cx_address
 		longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
 	else
 		longhaul.bits.RevisionKey = 0;
-	longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
-	longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
+	longhaul.bits.SoftBusRatio = mults_index & 0xf;
+	longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
 	/* Setup new voltage */
 	if (can_scale_voltage)
-		longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f;
+		longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
 	/* Sync to timer tick */
 	safe_halt();
 	/* Raise voltage if necessary */
@@ -240,14 +241,14 @@ static void do_powersaver(int cx_address
 
 /**
  * longhaul_set_cpu_frequency()
- * @clock_ratio_index : bitpattern of the new multiplier.
+ * @mults_index : bitpattern of the new multiplier.
  *
  * Sets a new clock ratio.
  */
 
 static void longhaul_setstate(unsigned int table_index)
 {
-	unsigned int clock_ratio_index;
+	unsigned int mults_index;
 	int speed, mult;
 	struct cpufreq_freqs freqs;
 	unsigned long flags;
@@ -256,9 +257,9 @@ static void longhaul_setstate(unsigned i
 	u32 bm_timeout = 1000;
 	unsigned int dir = 0;
 
-	clock_ratio_index = longhaul_table[table_index].index;
+	mults_index = longhaul_table[table_index].index;
 	/* Safety precautions */
-	mult = clock_ratio[clock_ratio_index & 0x1f];
+	mult = mults[mults_index & 0x1f];
 	if (mult == -1)
 		return;
 	speed = calc_speed(mult);
@@ -274,7 +275,7 @@ static void longhaul_setstate(unsigned i
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
-	dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
+	dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
 			fsb, mult/10, mult%10, print_speed(speed/1000));
 retry_loop:
 	preempt_disable();
@@ -282,8 +283,8 @@ retry_loop:
 
 	pic2_mask = inb(0xA1);
 	pic1_mask = inb(0x21);	/* works on C3. save mask. */
-	outb(0xFF,0xA1);	/* Overkill */
-	outb(0xFE,0x21);	/* TMR0 only */
+	outb(0xFF, 0xA1);	/* Overkill */
+	outb(0xFE, 0x21);	/* TMR0 only */
 
 	/* Wait while PCI bus is busy. */
 	if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
@@ -303,7 +304,7 @@ retry_loop:
 		outb(3, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Disable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 	}
 	switch (longhaul_version) {
 
@@ -312,7 +313,7 @@ retry_loop:
 	 * Software controlled multipliers only.
 	 */
 	case TYPE_LONGHAUL_V1:
-		do_longhaul1(clock_ratio_index);
+		do_longhaul1(mults_index);
 		break;
 
 	/*
@@ -326,10 +327,10 @@ retry_loop:
 	case TYPE_POWERSAVER:
 		if (longhaul_flags & USE_ACPI_C3) {
 			/* Don't allow wakeup */
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-			do_powersaver(cx->address, clock_ratio_index, dir);
+			acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+			do_powersaver(cx->address, mults_index, dir);
 		} else {
-			do_powersaver(0, clock_ratio_index, dir);
+			do_powersaver(0, mults_index, dir);
 		}
 		break;
 	}
@@ -339,10 +340,10 @@ retry_loop:
 		outb(0, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Enable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 	}
-	outb(pic2_mask,0xA1);	/* restore mask */
-	outb(pic1_mask,0x21);
+	outb(pic2_mask, 0xA1);	/* restore mask */
+	outb(pic1_mask, 0x21);
 
 	local_irq_restore(flags);
 	preempt_enable();
@@ -392,7 +393,8 @@ retry_loop:
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
 	if (!bm_timeout)
-		printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n");
+		printk(KERN_INFO PFX "Warning: Timeout while waiting for "
+				"idle PCI bus.\n");
 }
 
 /*
@@ -458,31 +460,32 @@ static int __init longhaul_get_ranges(vo
 		break;
 	}
 
-	dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
+	dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n",
 		 minmult/10, minmult%10, maxmult/10, maxmult%10);
 
 	highest_speed = calc_speed(maxmult);
 	lowest_speed = calc_speed(minmult);
-	dprintk ("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
+	dprintk("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
 		 print_speed(lowest_speed/1000),
 		 print_speed(highest_speed/1000));
 
 	if (lowest_speed == highest_speed) {
-		printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n");
+		printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
 		return -EINVAL;
 	}
 	if (lowest_speed > highest_speed) {
-		printk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
+		printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
 			lowest_speed, highest_speed);
 		return -EINVAL;
 	}
 
-	longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
-	if(!longhaul_table)
+	longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
+			GFP_KERNEL);
+	if (!longhaul_table)
 		return -ENOMEM;
 
 	for (j = 0; j < numscales; j++) {
-		ratio = clock_ratio[j];
+		ratio = mults[j];
 		if (ratio == -1)
 			continue;
 		if (ratio > maxmult || ratio < minmult)
@@ -507,13 +510,10 @@ static int __init longhaul_get_ranges(vo
 			}
 		}
 		if (min_i != j) {
-			unsigned int temp;
-			temp = longhaul_table[j].frequency;
-			longhaul_table[j].frequency = longhaul_table[min_i].frequency;
-			longhaul_table[min_i].frequency = temp;
-			temp = longhaul_table[j].index;
-			longhaul_table[j].index = longhaul_table[min_i].index;
-			longhaul_table[min_i].index = temp;
+			swap(longhaul_table[j].frequency,
+			     longhaul_table[min_i].frequency);
+			swap(longhaul_table[j].index,
+			     longhaul_table[min_i].index);
 		}
 	}
 
@@ -521,7 +521,7 @@ static int __init longhaul_get_ranges(vo
 
 	/* Find index we are running on */
 	for (j = 0; j < k; j++) {
-		if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) {
+		if (mults[longhaul_table[j].index & 0x1f] == mult) {
 			longhaul_index = j;
 			break;
 		}
@@ -559,20 +559,22 @@ static void __init longhaul_setup_voltag
 	maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
 
 	if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
-		printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
+		printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
 					"Voltage scaling disabled.\n",
-					minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
+					minvid.mV/1000, minvid.mV%1000,
+					maxvid.mV/1000, maxvid.mV%1000);
 		return;
 	}
 
 	if (minvid.mV == maxvid.mV) {
-		printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
-				"both %d.%03d. Voltage scaling disabled\n",
+		printk(KERN_INFO PFX "Claims to support voltage scaling but "
+				"min & max are both %d.%03d. "
+				"Voltage scaling disabled\n",
 				maxvid.mV/1000, maxvid.mV%1000);
 		return;
 	}
 
-	/* How many voltage steps */
+	/* How many voltage steps*/
 	numvscales = maxvid.pos - minvid.pos + 1;
 	printk(KERN_INFO PFX
 		"Max VID=%d.%03d  "
@@ -586,7 +588,7 @@ static void __init longhaul_setup_voltag
 	j = longhaul.bits.MinMHzBR;
 	if (longhaul.bits.MinMHzBR4)
 		j += 16;
-	min_vid_speed = eblcr_table[j];
+	min_vid_speed = eblcr[j];
 	if (min_vid_speed == -1)
 		return;
 	switch (longhaul.bits.MinMHzFSB) {
@@ -617,7 +619,8 @@ static void __init longhaul_setup_voltag
 			pos = minvid.pos;
 		longhaul_table[j].index |= mV_vrm_table[pos] << 8;
 		vid = vrm_mV_table[mV_vrm_table[pos]];
-		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV);
+		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
+				speed, j, vid.mV);
 		j++;
 	}
 
@@ -640,7 +643,8 @@ static int longhaul_target(struct cpufre
 	unsigned int dir = 0;
 	u8 vid, current_vid;
 
-	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
+	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
+				relation, &table_index))
 		return -EINVAL;
 
 	/* Don't set same frequency again */
@@ -656,7 +660,8 @@ static int longhaul_target(struct cpufre
 		 * this in hardware, C3 is old and we need to do this
 		 * in software. */
 		i = longhaul_index;
-		current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f;
+		current_vid = (longhaul_table[longhaul_index].index >> 8);
+		current_vid &= 0x1f;
 		if (table_index > longhaul_index)
 			dir = 1;
 		while (i != table_index) {
@@ -691,9 +696,9 @@ static acpi_status longhaul_walk_callbac
 {
 	struct acpi_device *d;
 
-	if ( acpi_bus_get_device(obj_handle, &d) ) {
+	if (acpi_bus_get_device(obj_handle, &d))
 		return 0;
-	}
+
 	*return_value = acpi_driver_data(d);
 	return 1;
 }
@@ -750,7 +755,7 @@ static int longhaul_setup_southbridge(vo
 	/* Find VT8235 southbridge */
 	dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
 	if (dev == NULL)
-	/* Find VT8237 southbridge */
+		/* Find VT8237 southbridge */
 		dev = pci_get_device(PCI_VENDOR_ID_VIA,
 				     PCI_DEVICE_ID_VIA_8237, NULL);
 	if (dev != NULL) {
@@ -769,7 +774,8 @@ static int longhaul_setup_southbridge(vo
 		if (pci_cmd & 1 << 7) {
 			pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
 			acpi_regs_addr &= 0xff00;
-			printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr);
+			printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
+					acpi_regs_addr);
 		}
 
 		pci_dev_put(dev);
@@ -781,7 +787,7 @@ static int longhaul_setup_southbridge(vo
 static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
-	char *cpuname=NULL;
+	char *cpuname = NULL;
 	int ret;
 	u32 lo, hi;
 
@@ -791,8 +797,8 @@ static int __init longhaul_cpu_init(stru
 		cpu_model = CPU_SAMUEL;
 		cpuname = "C3 'Samuel' [C5A]";
 		longhaul_version = TYPE_LONGHAUL_V1;
-		memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
-		memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr));
+		memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+		memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
 		break;
 
 	case 7:
@@ -803,10 +809,8 @@ static int __init longhaul_cpu_init(stru
 			cpuname = "C3 'Samuel 2' [C5B]";
 			/* Note, this is not a typo, early Samuel2's had
 			 * Samuel1 ratios. */
-			memcpy(clock_ratio, samuel1_clock_ratio,
-				sizeof(samuel1_clock_ratio));
-			memcpy(eblcr_table, samuel2_eblcr,
-				sizeof(samuel2_eblcr));
+			memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+			memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
 			break;
 		case 1 ... 15:
 			longhaul_version = TYPE_LONGHAUL_V1;
@@ -817,10 +821,8 @@ static int __init longhaul_cpu_init(stru
 				cpu_model = CPU_EZRA;
 				cpuname = "C3 'Ezra' [C5C]";
 			}
-			memcpy(clock_ratio, ezra_clock_ratio,
-				sizeof(ezra_clock_ratio));
-			memcpy(eblcr_table, ezra_eblcr,
-				sizeof(ezra_eblcr));
+			memcpy(mults, ezra_mults, sizeof(ezra_mults));
+			memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
 			break;
 		}
 		break;
@@ -829,18 +831,16 @@ static int __init longhaul_cpu_init(stru
 		cpu_model = CPU_EZRA_T;
 		cpuname = "C3 'Ezra-T' [C5M]";
 		longhaul_version = TYPE_POWERSAVER;
-		numscales=32;
-		memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio));
-		memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr));
+		numscales = 32;
+		memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
+		memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
 		break;
 
 	case 9:
 		longhaul_version = TYPE_POWERSAVER;
 		numscales = 32;
-		memcpy(clock_ratio,
-		       nehemiah_clock_ratio,
-		       sizeof(nehemiah_clock_ratio));
-		memcpy(eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
+		memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
+		memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
 		switch (c->x86_mask) {
 		case 0 ... 1:
 			cpu_model = CPU_NEHEMIAH;
@@ -869,14 +869,14 @@ static int __init longhaul_cpu_init(stru
 			longhaul_version = TYPE_LONGHAUL_V1;
 	}
 
-	printk (KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
+	printk(KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
 	switch (longhaul_version) {
 	case TYPE_LONGHAUL_V1:
 	case TYPE_LONGHAUL_V2:
-		printk ("Longhaul v%d supported.\n", longhaul_version);
+		printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
 		break;
 	case TYPE_POWERSAVER:
-		printk ("Powersaver supported.\n");
+		printk(KERN_CONT "Powersaver supported.\n");
 		break;
 	};
 
@@ -940,7 +940,7 @@ static int __devexit longhaul_cpu_exit(s
 	return 0;
 }
 
-static struct freq_attr* longhaul_attr[] = {
+static struct freq_attr *longhaul_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -966,13 +966,15 @@ static int __init longhaul_init(void)
 
 #ifdef CONFIG_SMP
 	if (num_online_cpus() > 1) {
-		printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n");
+		printk(KERN_ERR PFX "More than 1 CPU detected, "
+				"longhaul disabled.\n");
 		return -ENODEV;
 	}
 #endif
 #ifdef CONFIG_X86_IO_APIC
 	if (cpu_has_apic) {
-		printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n");
+		printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
+				"broken in this configuration.\n");
 		return -ENODEV;
 	}
 #endif
@@ -993,8 +995,8 @@ static void __exit longhaul_exit(void)
 {
 	int i;
 
-	for (i=0; i < numscales; i++) {
-		if (clock_ratio[i] == maxmult) {
+	for (i = 0; i < numscales; i++) {
+		if (mults[i] == maxmult) {
 			longhaul_setstate(i);
 			break;
 		}
@@ -1007,11 +1009,11 @@ static void __exit longhaul_exit(void)
 /* Even if BIOS is exporting ACPI C3 state, and it is used
  * with success when CPU is idle, this state doesn't
  * trigger frequency transition in some cases. */
-module_param (disable_acpi_c3, int, 0644);
+module_param(disable_acpi_c3, int, 0644);
 MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
 /* Change CPU voltage with frequency. Very usefull to save
  * power, but most VIA C3 processors aren't supporting it. */
-module_param (scale_voltage, int, 0644);
+module_param(scale_voltage, int, 0644);
 MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
 /* Force revision key to 0 for processors which doesn't
  * support voltage scaling, but are introducing itself as
@@ -1019,9 +1021,9 @@ MODULE_PARM_DESC(scale_voltage, "Scale v
 module_param(revid_errata, int, 0644);
 MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
 
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
+MODULE_LICENSE("GPL");
 
 late_initcall(longhaul_init);
 module_exit(longhaul_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.h linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.h
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longhaul.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,14 +49,14 @@ union msr_longhaul {
 
 /*
  * Clock ratio tables. Div/Mod by 10 to get ratio.
- * The eblcr ones specify the ratio read from the CPU.
- * The clock_ratio ones specify what to write to the CPU.
+ * The eblcr values specify the ratio read from the CPU.
+ * The mults values specify what to write to the CPU.
  */
 
 /*
  * VIA C3 Samuel 1  & Samuel 2 (stepping 0)
  */
-static const int __initdata samuel1_clock_ratio[16] = {
+static const int __initdata samuel1_mults[16] = {
 	-1, /* 0000 -> RESERVED */
 	30, /* 0001 ->  3.0x */
 	40, /* 0010 ->  4.0x */
@@ -119,7 +119,7 @@ static const int __initdata samuel2_eblc
 /*
  * VIA C3 Ezra
  */
-static const int __initdata ezra_clock_ratio[16] = {
+static const int __initdata ezra_mults[16] = {
 	100, /* 0000 -> 10.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -160,7 +160,7 @@ static const int __initdata ezra_eblcr[1
 /*
  * VIA C3 (Ezra-T) [C5M].
  */
-static const int __initdata ezrat_clock_ratio[32] = {
+static const int __initdata ezrat_mults[32] = {
 	100, /* 0000 -> 10.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -235,7 +235,7 @@ static const int __initdata ezrat_eblcr[
 /*
  * VIA C3 Nehemiah */
 
-static const int __initdata  nehemiah_clock_ratio[32] = {
+static const int __initdata  nehemiah_mults[32] = {
 	100, /* 0000 -> 10.0x */
 	-1, /* 0001 -> 16.0x */
 	40,  /* 0010 ->  4.0x */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/longrun.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,12 +11,13 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
+#include <linux/timex.h>
 
 #include <asm/msr.h>
 #include <asm/processor.h>
-#include <asm/timex.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longrun", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"longrun", msg)
 
 static struct cpufreq_driver	longrun_driver;
 
@@ -51,7 +52,7 @@ static void __init longrun_get_policy(st
 	msr_lo &= 0x0000007F;
 	msr_hi &= 0x0000007F;
 
-	if ( longrun_high_freq <= longrun_low_freq ) {
+	if (longrun_high_freq <= longrun_low_freq) {
 		/* Assume degenerate Longrun table */
 		policy->min = policy->max = longrun_high_freq;
 	} else {
@@ -79,7 +80,7 @@ static int longrun_set_policy(struct cpu
 	if (!policy)
 		return -EINVAL;
 
-	if ( longrun_high_freq <= longrun_low_freq ) {
+	if (longrun_high_freq <= longrun_low_freq) {
 		/* Assume degenerate Longrun table */
 		pctg_lo = pctg_hi = 100;
 	} else {
@@ -152,7 +153,7 @@ static unsigned int longrun_get(unsigned
 	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
 	dprintk("cpuid eax is %u\n", eax);
 
-	return (eax * 1000);
+	return eax * 1000;
 }
 
 /**
@@ -196,7 +197,8 @@ static unsigned int __init longrun_deter
 		rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
 		*high_freq = msr_lo * 1000; /* to kHz */
 
-		dprintk("longrun table interface told %u - %u kHz\n", *low_freq, *high_freq);
+		dprintk("longrun table interface told %u - %u kHz\n",
+				*low_freq, *high_freq);
 
 		if (*low_freq > *high_freq)
 			*low_freq = *high_freq;
@@ -219,7 +221,7 @@ static unsigned int __init longrun_deter
 	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
 	/* try decreasing in 10% steps, some processors react only
 	 * on some barrier values */
-	for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -=10) {
+	for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) {
 		/* set to 0 to try_hi perf_pctg */
 		msr_lo &= 0xFFFFFF80;
 		msr_hi &= 0xFFFFFF80;
@@ -236,7 +238,7 @@ static unsigned int __init longrun_deter
 
 	/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
 	 * eqals
-	 * low_freq * ( 1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
+	 * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
 	 *
 	 * high_freq * perf_pctg is stored tempoarily into "ebx".
 	 */
@@ -317,9 +319,10 @@ static void __exit longrun_exit(void)
 }
 
 
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("LongRun driver for Transmeta Crusoe and Efficeon processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and "
+		"Efficeon processors.");
+MODULE_LICENSE("GPL");
 
 module_init(longrun_init);
 module_exit(longrun_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,11 @@
+# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
+# K8 systems. ACPI is preferred to all other hardware-specific drivers.
+# speedstep-* is preferred over p4-clockmod.
+
+obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)		+= acpi-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)		+= powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)		+= powernow-k7.o
-obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o
 obj-$(CONFIG_X86_LONGHAUL)		+= longhaul.o
 obj-$(CONFIG_X86_E_POWERSAVER)		+= e_powersaver.o
 obj-$(CONFIG_ELAN_CPUFREQ)		+= elanfreq.o
@@ -10,7 +15,6 @@ obj-$(CONFIG_X86_GX_SUSPMOD)		+= gx-susp
 obj-$(CONFIG_X86_SPEEDSTEP_ICH)		+= speedstep-ich.o
 obj-$(CONFIG_X86_SPEEDSTEP_LIB)		+= speedstep-lib.o
 obj-$(CONFIG_X86_SPEEDSTEP_SMI)		+= speedstep-smi.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ)		+= acpi-cpufreq.o
 obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)	+= speedstep-centrino.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)		+= p4-clockmod.o
 obj-$(CONFIG_X86_CPUFREQ_NFORCE2)	+= cpufreq-nforce2.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,15 +27,17 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/cpumask.h>
+#include <linux/timex.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
-#include <asm/timex.h>
+#include <asm/timer.h>
 
 #include "speedstep-lib.h"
 
 #define PFX	"p4-clockmod: "
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "p4-clockmod", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"p4-clockmod", msg)
 
 /*
  * Duty Cycle (3bits), note DC_DISABLE is not specified in
@@ -58,7 +60,8 @@ static int cpufreq_p4_setdc(unsigned int
 {
 	u32 l, h;
 
-	if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV))
+	if (!cpu_online(cpu) ||
+	    (newstate > DC_DISABLE) || (newstate == DC_RESV))
 		return -EINVAL;
 
 	rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h);
@@ -66,7 +69,8 @@ static int cpufreq_p4_setdc(unsigned int
 	if (l & 0x01)
 		dprintk("CPU#%d currently thermal throttled\n", cpu);
 
-	if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT))
+	if (has_N44_O17_errata[cpu] &&
+	    (newstate == DC_25PT || newstate == DC_DFLT))
 		newstate = DC_38PT;
 
 	rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
@@ -112,7 +116,8 @@ static int cpufreq_p4_target(struct cpuf
 	struct cpufreq_freqs freqs;
 	int i;
 
-	if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	freqs.old = cpufreq_p4_get(policy->cpu);
@@ -127,7 +132,8 @@ static int cpufreq_p4_target(struct cpuf
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 	}
 
-	/* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
+	/* run on each logical CPU,
+	 * see section 13.15.3 of IA32 Intel Architecture Software
 	 * Developer's Manual, Volume 3
 	 */
 	for_each_cpu(i, policy->cpus)
@@ -153,28 +159,31 @@ static unsigned int cpufreq_p4_get_frequ
 {
 	if (c->x86 == 0x06) {
 		if (cpu_has(c, X86_FEATURE_EST))
-			printk(KERN_WARNING PFX "Warning: EST-capable CPU detected. "
-			       "The acpi-cpufreq module offers voltage scaling"
-			       " in addition of frequency scaling. You should use "
-			       "that instead of p4-clockmod, if possible.\n");
+			printk(KERN_WARNING PFX "Warning: EST-capable CPU "
+			       "detected. The acpi-cpufreq module offers "
+			       "voltage scaling in addition of frequency "
+			       "scaling. You should use that instead of "
+			       "p4-clockmod, if possible.\n");
 		switch (c->x86_model) {
 		case 0x0E: /* Core */
 		case 0x0F: /* Core Duo */
 		case 0x16: /* Celeron Core */
+		case 0x1C: /* Atom */
 			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-			return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PCORE);
+			return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
 		case 0x0D: /* Pentium M (Dothan) */
 			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
 			/* fall through */
 		case 0x09: /* Pentium M (Banias) */
-			return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+			return speedstep_get_frequency(SPEEDSTEP_CPU_PM);
 		}
 	}
 
 	if (c->x86 != 0xF) {
 		if (!cpu_has(c, X86_FEATURE_EST))
-			printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. "
-				"Please send an e-mail to <cpufreq@vger.kernel.org>\n");
+			printk(KERN_WARNING PFX "Unknown CPU. "
+				"Please send an e-mail to "
+				"<cpufreq@vger.kernel.org>\n");
 		return 0;
 	}
 
@@ -182,16 +191,16 @@ static unsigned int cpufreq_p4_get_frequ
 	 * throttling is active or not. */
 	p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
 
-	if (speedstep_detect_processor() == SPEEDSTEP_PROCESSOR_P4M) {
+	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) {
 		printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. "
 		       "The speedstep-ich or acpi cpufreq modules offer "
 		       "voltage scaling in addition of frequency scaling. "
 		       "You should use either one instead of p4-clockmod, "
 		       "if possible.\n");
-		return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4M);
+		return speedstep_get_frequency(SPEEDSTEP_CPU_P4M);
 	}
 
-	return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D);
+	return speedstep_get_frequency(SPEEDSTEP_CPU_P4D);
 }
 
 
@@ -203,7 +212,7 @@ static int cpufreq_p4_cpu_init(struct cp
 	unsigned int i;
 
 #ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
 #endif
 
 	/* Errata workaround */
@@ -217,14 +226,20 @@ static int cpufreq_p4_cpu_init(struct cp
 		dprintk("has errata -- disabling low frequencies\n");
 	}
 
+	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D &&
+	    c->x86_model < 2) {
+		/* switch to maximum frequency and measure result */
+		cpufreq_p4_setdc(policy->cpu, DC_DISABLE);
+		recalibrate_cpu_khz();
+	}
 	/* get max frequency */
 	stock_freq = cpufreq_p4_get_frequency(c);
 	if (!stock_freq)
 		return -EINVAL;
 
 	/* table init */
-	for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if ((i<2) && (has_N44_O17_errata[policy->cpu]))
+	for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if ((i < 2) && (has_N44_O17_errata[policy->cpu]))
 			p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
 		else
 			p4clockmod_table[i].frequency = (stock_freq * i)/8;
@@ -232,7 +247,10 @@ static int cpufreq_p4_cpu_init(struct cp
 	cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
 
 	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = 1000000; /* assumed */
+
+	/* the transition latency is set to be 1 higher than the maximum
+	 * transition latency of the ondemand governor */
+	policy->cpuinfo.transition_latency = 10000001;
 	policy->cur = stock_freq;
 
 	return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
@@ -258,12 +276,12 @@ static unsigned int cpufreq_p4_get(unsig
 		l = DC_DISABLE;
 
 	if (l != DC_DISABLE)
-		return (stock_freq * l / 8);
+		return stock_freq * l / 8;
 
 	return stock_freq;
 }
 
-static struct freq_attr* p4clockmod_attr[] = {
+static struct freq_attr *p4clockmod_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -298,9 +316,10 @@ static int __init cpufreq_p4_init(void)
 
 	ret = cpufreq_register_driver(&p4clockmod_driver);
 	if (!ret)
-		printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n");
+		printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock "
+				"Modulation available\n");
 
-	return (ret);
+	return ret;
 }
 
 
@@ -310,9 +329,9 @@ static void __exit cpufreq_p4_exit(void)
 }
 
 
-MODULE_AUTHOR ("Zwane Mwaikambo <zwane@commfireservices.com>");
-MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
+MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
+MODULE_LICENSE("GPL");
 
 late_initcall(cpufreq_p4_init);
 module_exit(cpufreq_p4_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,7 @@
 /*
  *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne PÃ¤nkÃ¤lÃ¤, Dominik Brodowski.
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne PÃ¤nkÃ¤lÃ¤,
+ *                 Dominik Brodowski.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
  *
@@ -13,14 +14,15 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
-
-#include <asm/msr.h>
 #include <linux/timex.h>
 #include <linux/io.h>
 
+#include <asm/msr.h>
+
 #define POWERNOW_IOPORT 0xfff0          /* it doesn't matter where, as long
 					   as it is unused */
 
+#define PFX "powernow-k6: "
 static unsigned int                     busfreq;   /* FSB, in 10 kHz */
 static unsigned int                     max_multiplier;
 
@@ -47,8 +49,8 @@ static struct cpufreq_frequency_table cl
  */
 static int powernow_k6_get_cpu_multiplier(void)
 {
-	u64             invalue = 0;
-	u32             msrval;
+	u64 invalue = 0;
+	u32 msrval;
 
 	msrval = POWERNOW_IOPORT + 0x1;
 	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
@@ -68,12 +70,12 @@ static int powernow_k6_get_cpu_multiplie
  */
 static void powernow_k6_set_state(unsigned int best_i)
 {
-	unsigned long           outvalue = 0, invalue = 0;
-	unsigned long           msrval;
-	struct cpufreq_freqs    freqs;
+	unsigned long outvalue = 0, invalue = 0;
+	unsigned long msrval;
+	struct cpufreq_freqs freqs;
 
 	if (clock_ratio[best_i].index > max_multiplier) {
-		printk(KERN_ERR "cpufreq: invalid target frequency\n");
+		printk(KERN_ERR PFX "invalid target frequency\n");
 		return;
 	}
 
@@ -119,7 +121,8 @@ static int powernow_k6_verify(struct cpu
  * powernow_k6_setpolicy - sets a new CPUFreq policy
  * @policy: new policy
  * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
  *
  * sets a new CPUFreq policy
  */
@@ -127,9 +130,10 @@ static int powernow_k6_target(struct cpu
 			       unsigned int target_freq,
 			       unsigned int relation)
 {
-	unsigned int    newstate = 0;
+	unsigned int newstate = 0;
 
-	if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	powernow_k6_set_state(newstate);
@@ -140,7 +144,7 @@ static int powernow_k6_target(struct cpu
 
 static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
 {
-	unsigned int i;
+	unsigned int i, f;
 	int result;
 
 	if (policy->cpu != 0)
@@ -152,10 +156,11 @@ static int powernow_k6_cpu_init(struct c
 
 	/* table init */
 	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (clock_ratio[i].index > max_multiplier)
+		f = clock_ratio[i].index;
+		if (f > max_multiplier)
 			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
 		else
-			clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
+			clock_ratio[i].frequency = busfreq * f;
 	}
 
 	/* cpuinfo and default policy values */
@@ -185,7 +190,9 @@ static int powernow_k6_cpu_exit(struct c
 
 static unsigned int powernow_k6_get(unsigned int cpu)
 {
-	return busfreq * powernow_k6_get_cpu_multiplier();
+	unsigned int ret;
+	ret = (busfreq * powernow_k6_get_cpu_multiplier());
+	return ret;
 }
 
 static struct freq_attr *powernow_k6_attr[] = {
@@ -221,7 +228,7 @@ static int __init powernow_k6_init(void)
 		return -ENODEV;
 
 	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
-		printk("cpufreq: PowerNow IOPORT region already used.\n");
+		printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n");
 		return -EIO;
 	}
 
@@ -246,7 +253,8 @@ static void __exit powernow_k6_exit(void
 }
 
 
-MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, "
+		"Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,10 +6,12 @@
  *  Licensed under the terms of the GNU GPL License version 2.
  *  Based upon datasheets & sample CPUs kindly provided by AMD.
  *
- * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
- * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
- * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
- * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+ * Errata 5:
+ *  CPU may fail to execute a FID/VID change in presence of interrupt.
+ *  - We cli/sti on stepping A0 CPUs around the FID/VID transition.
+ * Errata 15:
+ *  CPU with half frequency multipliers may hang upon wakeup from disconnect.
+ *  - We disable half multipliers if ACPI is used on A0 stepping CPUs.
  */
 
 #include <linux/kernel.h>
@@ -20,11 +22,11 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/dmi.h>
+#include <linux/timex.h>
+#include <linux/io.h>
 
+#include <asm/timer.h>		/* Needed for recalibrate_cpu_khz() */
 #include <asm/msr.h>
-#include <asm/timer.h>
-#include <asm/timex.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
@@ -58,9 +60,9 @@ struct pst_s {
 union powernow_acpi_control_t {
 	struct {
 		unsigned long fid:5,
-		vid:5,
-		sgtc:20,
-		res1:2;
+			vid:5,
+			sgtc:20,
+			res1:2;
 	} bits;
 	unsigned long val;
 };
@@ -94,14 +96,15 @@ static struct cpufreq_frequency_table *p
 
 static unsigned int can_scale_bus;
 static unsigned int can_scale_vid;
-static unsigned int minimum_speed=-1;
+static unsigned int minimum_speed = -1;
 static unsigned int maximum_speed;
 static unsigned int number_scales;
 static unsigned int fsb;
 static unsigned int latency;
 static char have_a0;
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"powernow-k7", msg)
 
 static int check_fsb(unsigned int fsbspeed)
 {
@@ -109,7 +112,7 @@ static int check_fsb(unsigned int fsbspe
 	unsigned int f = fsb / 1000;
 
 	delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
-	return (delta < 5);
+	return delta < 5;
 }
 
 static int check_powernow(void)
@@ -117,24 +120,26 @@ static int check_powernow(void)
 	struct cpuinfo_x86 *c = &cpu_data(0);
 	unsigned int maxei, eax, ebx, ecx, edx;
 
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
+	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
 #ifdef MODULE
-		printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n");
+		printk(KERN_INFO PFX "This module only works with "
+				"AMD K7 CPUs\n");
 #endif
 		return 0;
 	}
 
 	/* Get maximum capabilities */
-	maxei = cpuid_eax (0x80000000);
+	maxei = cpuid_eax(0x80000000);
 	if (maxei < 0x80000007) {	/* Any powernow info ? */
 #ifdef MODULE
-		printk (KERN_INFO PFX "No powernow capabilities detected\n");
+		printk(KERN_INFO PFX "No powernow capabilities detected\n");
 #endif
 		return 0;
 	}
 
 	if ((c->x86_model == 6) && (c->x86_mask == 0)) {
-		printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n");
+		printk(KERN_INFO PFX "K7 660[A0] core detected, "
+				"enabling errata workarounds\n");
 		have_a0 = 1;
 	}
 
@@ -144,37 +149,44 @@ static int check_powernow(void)
 	if (!(edx & (1 << 1 | 1 << 2)))
 		return 0;
 
-	printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
+	printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
 
 	if (edx & 1 << 1) {
-		printk ("frequency");
-		can_scale_bus=1;
+		printk("frequency");
+		can_scale_bus = 1;
 	}
 
 	if ((edx & (1 << 1 | 1 << 2)) == 0x6)
-		printk (" and ");
+		printk(" and ");
 
 	if (edx & 1 << 2) {
-		printk ("voltage");
-		can_scale_vid=1;
+		printk("voltage");
+		can_scale_vid = 1;
 	}
 
-	printk (".\n");
+	printk(".\n");
 	return 1;
 }
 
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+static void invalidate_entry(unsigned int entry)
+{
+	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
+#endif
 
-static int get_ranges (unsigned char *pst)
+static int get_ranges(unsigned char *pst)
 {
 	unsigned int j;
 	unsigned int speed;
 	u8 fid, vid;
 
-	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+				(number_scales + 1)), GFP_KERNEL);
 	if (!powernow_table)
 		return -ENOMEM;
 
-	for (j=0 ; j < number_scales; j++) {
+	for (j = 0 ; j < number_scales; j++) {
 		fid = *pst++;
 
 		powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
@@ -182,10 +194,10 @@ static int get_ranges (unsigned char *ps
 
 		speed = powernow_table[j].frequency;
 
-		if ((fid_codes[fid] % 10)==5) {
+		if ((fid_codes[fid] % 10) == 5) {
 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 			if (have_a0 == 1)
-				powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID;
+				invalidate_entry(j);
 #endif
 		}
 
@@ -197,7 +209,7 @@ static int get_ranges (unsigned char *ps
 		vid = *pst++;
 		powernow_table[j].index |= (vid << 8); /* upper 8 bits */
 
-		dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
+		dprintk("   FID: 0x%x (%d.%dx [%dMHz])  "
 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
 			 fid_codes[fid] % 10, speed/1000, vid,
 			 mobile_vid_table[vid]/1000,
@@ -214,13 +226,13 @@ static void change_FID(int fid)
 {
 	union msr_fidvidctl fidvidctl;
 
-	rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 	if (fidvidctl.bits.FID != fid) {
 		fidvidctl.bits.SGTC = latency;
 		fidvidctl.bits.FID = fid;
 		fidvidctl.bits.VIDC = 0;
 		fidvidctl.bits.FIDC = 1;
-		wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 	}
 }
 
@@ -229,18 +241,18 @@ static void change_VID(int vid)
 {
 	union msr_fidvidctl fidvidctl;
 
-	rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 	if (fidvidctl.bits.VID != vid) {
 		fidvidctl.bits.SGTC = latency;
 		fidvidctl.bits.VID = vid;
 		fidvidctl.bits.FIDC = 0;
 		fidvidctl.bits.VIDC = 1;
-		wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 	}
 }
 
 
-static void change_speed (unsigned int index)
+static void change_speed(unsigned int index)
 {
 	u8 fid, vid;
 	struct cpufreq_freqs freqs;
@@ -257,7 +269,7 @@ static void change_speed (unsigned int i
 
 	freqs.cpu = 0;
 
-	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 	cfid = fidvidstatus.bits.CFID;
 	freqs.old = fsb * fid_codes[cfid] / 10;
 
@@ -310,7 +322,7 @@ static int powernow_acpi_init(void)
 		goto err0;
 	}
 
-	if (!alloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
+	if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
 								GFP_KERNEL)) {
 		retval = -ENOMEM;
 		goto err05;
@@ -321,12 +333,14 @@ static int powernow_acpi_init(void)
 		goto err1;
 	}
 
-	if (acpi_processor_perf->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
+	if (acpi_processor_perf->control_register.space_id !=
+			ACPI_ADR_SPACE_FIXED_HARDWARE) {
 		retval = -ENODEV;
 		goto err2;
 	}
 
-	if (acpi_processor_perf->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
+	if (acpi_processor_perf->status_register.space_id !=
+			ACPI_ADR_SPACE_FIXED_HARDWARE) {
 		retval = -ENODEV;
 		goto err2;
 	}
@@ -338,7 +352,8 @@ static int powernow_acpi_init(void)
 		goto err2;
 	}
 
-	powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL);
+	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+				(number_scales + 1)), GFP_KERNEL);
 	if (!powernow_table) {
 		retval = -ENOMEM;
 		goto err2;
@@ -352,7 +367,7 @@ static int powernow_acpi_init(void)
 		unsigned int speed, speed_mhz;
 
 		pc.val = (unsigned long) state->control;
-		dprintk ("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
+		dprintk("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
 			 i,
 			 (u32) state->core_frequency,
 			 (u32) state->power,
@@ -381,12 +396,12 @@ static int powernow_acpi_init(void)
 		if (speed % 1000 > 0)
 			speed_mhz++;
 
-		if ((fid_codes[fid] % 10)==5) {
+		if ((fid_codes[fid] % 10) == 5) {
 			if (have_a0 == 1)
-				powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+				invalidate_entry(i);
 		}
 
-		dprintk ("   FID: 0x%x (%d.%dx [%dMHz])  "
+		dprintk("   FID: 0x%x (%d.%dx [%dMHz])  "
 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
 			 fid_codes[fid] % 10, speed_mhz, vid,
 			 mobile_vid_table[vid]/1000,
@@ -422,7 +437,8 @@ err1:
 err05:
 	kfree(acpi_processor_perf);
 err0:
-	printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n");
+	printk(KERN_WARNING PFX "ACPI perflib can not be used on "
+			"this platform\n");
 	acpi_processor_perf = NULL;
 	return retval;
 }
@@ -435,7 +451,14 @@ static int powernow_acpi_init(void)
 }
 #endif
 
-static int powernow_decode_bios (int maxfid, int startvid)
+static void print_pst_entry(struct pst_s *pst, unsigned int j)
+{
+	dprintk("PST:%d (@%p)\n", j, pst);
+	dprintk(" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
+		pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
+}
+
+static int powernow_decode_bios(int maxfid, int startvid)
 {
 	struct psb_s *psb;
 	struct pst_s *pst;
@@ -446,61 +469,67 @@ static int powernow_decode_bios (int max
 
 	etuple = cpuid_eax(0x80000001);
 
-	for (i=0xC0000; i < 0xffff0 ; i+=16) {
+	for (i = 0xC0000; i < 0xffff0 ; i += 16) {
 
 		p = phys_to_virt(i);
 
-		if (memcmp(p, "AMDK7PNOW!",  10) == 0){
-			dprintk ("Found PSB header at %p\n", p);
+		if (memcmp(p, "AMDK7PNOW!",  10) == 0) {
+			dprintk("Found PSB header at %p\n", p);
 			psb = (struct psb_s *) p;
-			dprintk ("Table version: 0x%x\n", psb->tableversion);
+			dprintk("Table version: 0x%x\n", psb->tableversion);
 			if (psb->tableversion != 0x12) {
-				printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n");
+				printk(KERN_INFO PFX "Sorry, only v1.2 tables"
+						" supported right now\n");
 				return -ENODEV;
 			}
 
-			dprintk ("Flags: 0x%x\n", psb->flags);
-			if ((psb->flags & 1)==0) {
-				dprintk ("Mobile voltage regulator\n");
-			} else {
-				dprintk ("Desktop voltage regulator\n");
-			}
+			dprintk("Flags: 0x%x\n", psb->flags);
+			if ((psb->flags & 1) == 0)
+				dprintk("Mobile voltage regulator\n");
+			else
+				dprintk("Desktop voltage regulator\n");
 
 			latency = psb->settlingtime;
 			if (latency < 100) {
-				printk(KERN_INFO PFX "BIOS set settling time to %d microseconds. "
-						"Should be at least 100. Correcting.\n", latency);
+				printk(KERN_INFO PFX "BIOS set settling time "
+						"to %d microseconds. "
+						"Should be at least 100. "
+						"Correcting.\n", latency);
 				latency = 100;
 			}
-			dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime);
-			dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
+			dprintk("Settling Time: %d microseconds.\n",
+					psb->settlingtime);
+			dprintk("Has %d PST tables. (Only dumping ones "
+					"relevant to this CPU).\n",
+					psb->numpst);
 
-			p += sizeof (struct psb_s);
+			p += sizeof(struct psb_s);
 
 			pst = (struct pst_s *) p;
 
-			for (j=0; j<psb->numpst; j++) {
+			for (j = 0; j < psb->numpst; j++) {
 				pst = (struct pst_s *) p;
 				number_scales = pst->numpstates;
 
-				if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) &&
-				    (maxfid==pst->maxfid) && (startvid==pst->startvid))
-				{
-					dprintk ("PST:%d (@%p)\n", j, pst);
-					dprintk (" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
-						 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
-
-					ret = get_ranges ((char *) pst + sizeof (struct pst_s));
+				if ((etuple == pst->cpuid) &&
+				    check_fsb(pst->fsbspeed) &&
+				    (maxfid == pst->maxfid) &&
+				    (startvid == pst->startvid)) {
+					print_pst_entry(pst, j);
+					p = (char *)pst + sizeof(struct pst_s);
+					ret = get_ranges(p);
 					return ret;
 				} else {
 					unsigned int k;
-					p = (char *) pst + sizeof (struct pst_s);
-					for (k=0; k<number_scales; k++)
-						p+=2;
+					p = (char *)pst + sizeof(struct pst_s);
+					for (k = 0; k < number_scales; k++)
+						p += 2;
 				}
 			}
-			printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple);
-			printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n");
+			printk(KERN_INFO PFX "No PST tables match this cpuid "
+					"(0x%x)\n", etuple);
+			printk(KERN_INFO PFX "This is indicative of a broken "
+					"BIOS.\n");
 
 			return -EINVAL;
 		}
@@ -511,13 +540,14 @@ static int powernow_decode_bios (int max
 }
 
 
-static int powernow_target (struct cpufreq_policy *policy,
+static int powernow_target(struct cpufreq_policy *policy,
 			    unsigned int target_freq,
 			    unsigned int relation)
 {
 	unsigned int newstate;
 
-	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
+				relation, &newstate))
 		return -EINVAL;
 
 	change_speed(newstate);
@@ -526,7 +556,7 @@ static int powernow_target (struct cpufr
 }
 
 
-static int powernow_verify (struct cpufreq_policy *policy)
+static int powernow_verify(struct cpufreq_policy *policy)
 {
 	return cpufreq_frequency_table_verify(policy, powernow_table);
 }
@@ -566,18 +596,23 @@ static unsigned int powernow_get(unsigne
 
 	if (cpu)
 		return 0;
-	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 	cfid = fidvidstatus.bits.CFID;
 
-	return (fsb * fid_codes[cfid] / 10);
+	return fsb * fid_codes[cfid] / 10;
 }
 
 
 static int __init acer_cpufreq_pst(const struct dmi_system_id *d)
 {
-	printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
-	printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
-	printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
+	printk(KERN_WARNING PFX
+		"%s laptop with broken PST tables in BIOS detected.\n",
+		d->ident);
+	printk(KERN_WARNING PFX
+		"You need to downgrade to 3A21 (09/09/2002), or try a newer "
+		"BIOS than 3A71 (01/20/2003)\n");
+	printk(KERN_WARNING PFX
+		"cpufreq scaling has been disabled as a result of this.\n");
 	return 0;
 }
 
@@ -598,7 +633,7 @@ static struct dmi_system_id __initdata p
 	{ }
 };
 
-static int __init powernow_cpu_init (struct cpufreq_policy *policy)
+static int __init powernow_cpu_init(struct cpufreq_policy *policy)
 {
 	union msr_fidvidstatus fidvidstatus;
 	int result;
@@ -606,7 +641,7 @@ static int __init powernow_cpu_init (str
 	if (policy->cpu != 0)
 		return -ENODEV;
 
-	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
 	recalibrate_cpu_khz();
 
@@ -618,19 +653,21 @@ static int __init powernow_cpu_init (str
 	dprintk("FSB: %3dMHz\n", fsb/1000);
 
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
-		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
+		printk(KERN_INFO PFX "PSB/PST known to be broken.  "
+				"Trying ACPI instead\n");
 		result = powernow_acpi_init();
 	} else {
-		result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
+		result = powernow_decode_bios(fidvidstatus.bits.MFID,
+				fidvidstatus.bits.SVID);
 		if (result) {
-			printk (KERN_INFO PFX "Trying ACPI perflib\n");
+			printk(KERN_INFO PFX "Trying ACPI perflib\n");
 			maximum_speed = 0;
 			minimum_speed = -1;
 			latency = 0;
 			result = powernow_acpi_init();
 			if (result) {
-				printk (KERN_INFO PFX "ACPI and legacy methods failed\n");
-				printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n");
+				printk(KERN_INFO PFX
+					"ACPI and legacy methods failed\n");
 			}
 		} else {
 			/* SGTC use the bus clock as timer */
@@ -642,10 +679,11 @@ static int __init powernow_cpu_init (str
 	if (result)
 		return result;
 
-	printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
+	printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
 				minimum_speed/1000, maximum_speed/1000);
 
-	policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency);
+	policy->cpuinfo.transition_latency =
+		cpufreq_scale(2000000UL, fsb, latency);
 
 	policy->cur = powernow_get(0);
 
@@ -654,7 +692,8 @@ static int __init powernow_cpu_init (str
 	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
 }
 
-static int powernow_cpu_exit (struct cpufreq_policy *policy) {
+static int powernow_cpu_exit(struct cpufreq_policy *policy)
+{
 	cpufreq_frequency_table_put_attr(policy->cpu);
 
 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
@@ -669,7 +708,7 @@ static int powernow_cpu_exit (struct cpu
 	return 0;
 }
 
-static struct freq_attr* powernow_table_attr[] = {
+static struct freq_attr *powernow_table_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -685,15 +724,15 @@ static struct cpufreq_driver powernow_dr
 	.attr	= powernow_table_attr,
 };
 
-static int __init powernow_init (void)
+static int __init powernow_init(void)
 {
-	if (check_powernow()==0)
+	if (check_powernow() == 0)
 		return -ENODEV;
 	return cpufreq_register_driver(&powernow_driver);
 }
 
 
-static void __exit powernow_exit (void)
+static void __exit powernow_exit(void)
 {
 	cpufreq_unregister_driver(&powernow_driver);
 }
@@ -701,9 +740,9 @@ static void __exit powernow_exit (void)
 module_param(acpi_force,  int, 0444);
 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
+MODULE_LICENSE("GPL");
 
 late_initcall(powernow_init);
 module_exit(powernow_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,16 +33,14 @@
 #include <linux/string.h>
 #include <linux/cpumask.h>
 #include <linux/sched.h>	/* for current / set_cpus_allowed() */
+#include <linux/io.h>
+#include <linux/delay.h>
 
 #include <asm/msr.h>
-#include <asm/io.h>
-#include <asm/delay.h>
 
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 #include <linux/acpi.h>
 #include <linux/mutex.h>
 #include <acpi/processor.h>
-#endif
 
 #define PFX "powernow-k8: "
 #define VERSION "version 2.20.00"
@@ -56,7 +54,10 @@ static DEFINE_PER_CPU(struct powernow_k8
 static int cpu_family = CPU_OPTERON;
 
 #ifndef CONFIG_SMP
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+	return cpumask_of(0);
+}
 #endif
 
 /* Return a frequency in MHz, given an input fid */
@@ -71,7 +72,8 @@ static u32 find_khz_freq_from_fid(u32 fi
 	return 1000 * find_freq_from_fid(fid);
 }
 
-static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate)
+static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
+		u32 pstate)
 {
 	return data[pstate].frequency;
 }
@@ -186,7 +188,9 @@ static int write_new_fid(struct powernow
 		return 1;
 	}
 
-	lo = fid | (data->currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+	lo = fid;
+	lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
+	lo |= MSR_C_LO_INIT_FID_VID;
 
 	dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
 		fid, lo, data->plllock * PLL_LOCK_CONVERSION);
@@ -194,7 +198,9 @@ static int write_new_fid(struct powernow
 	do {
 		wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
 		if (i++ > 100) {
-			printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n");
+			printk(KERN_ERR PFX
+				"Hardware error - pending bit very stuck - "
+				"no further pstate changes possible\n");
 			return 1;
 		}
 	} while (query_current_values_with_pending_wait(data));
@@ -202,14 +208,16 @@ static int write_new_fid(struct powernow
 	count_off_irt(data);
 
 	if (savevid != data->currvid) {
-		printk(KERN_ERR PFX "vid change on fid trans, old 0x%x, new 0x%x\n",
-		       savevid, data->currvid);
+		printk(KERN_ERR PFX
+			"vid change on fid trans, old 0x%x, new 0x%x\n",
+			savevid, data->currvid);
 		return 1;
 	}
 
 	if (fid != data->currfid) {
-		printk(KERN_ERR PFX "fid trans failed, fid 0x%x, curr 0x%x\n", fid,
-		        data->currfid);
+		printk(KERN_ERR PFX
+			"fid trans failed, fid 0x%x, curr 0x%x\n", fid,
+			data->currfid);
 		return 1;
 	}
 
@@ -228,7 +236,9 @@ static int write_new_vid(struct powernow
 		return 1;
 	}
 
-	lo = data->currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+	lo = data->currfid;
+	lo |= (vid << MSR_C_LO_VID_SHIFT);
+	lo |= MSR_C_LO_INIT_FID_VID;
 
 	dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
 		vid, lo, STOP_GRANT_5NS);
@@ -236,20 +246,24 @@ static int write_new_vid(struct powernow
 	do {
 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
 		if (i++ > 100) {
-			printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+			printk(KERN_ERR PFX "internal error - pending bit "
+					"very stuck - no further pstate "
+					"changes possible\n");
 			return 1;
 		}
 	} while (query_current_values_with_pending_wait(data));
 
 	if (savefid != data->currfid) {
-		printk(KERN_ERR PFX "fid changed on vid trans, old 0x%x new 0x%x\n",
+		printk(KERN_ERR PFX "fid changed on vid trans, old "
+			"0x%x new 0x%x\n",
 		       savefid, data->currfid);
 		return 1;
 	}
 
 	if (vid != data->currvid) {
-		printk(KERN_ERR PFX "vid trans failed, vid 0x%x, curr 0x%x\n", vid,
-				data->currvid);
+		printk(KERN_ERR PFX "vid trans failed, vid 0x%x, "
+				"curr 0x%x\n",
+				vid, data->currvid);
 		return 1;
 	}
 
@@ -261,7 +275,8 @@ static int write_new_vid(struct powernow
  * Decreasing vid codes represent increasing voltages:
  * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
  */
-static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step)
+static int decrease_vid_code_by_step(struct powernow_k8_data *data,
+		u32 reqvid, u32 step)
 {
 	if ((data->currvid - reqvid) > step)
 		reqvid = data->currvid - step;
@@ -283,7 +298,8 @@ static int transition_pstate(struct powe
 }
 
 /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
-static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid)
+static int transition_fid_vid(struct powernow_k8_data *data,
+		u32 reqfid, u32 reqvid)
 {
 	if (core_voltage_pre_transition(data, reqvid))
 		return 1;
@@ -298,7 +314,8 @@ static int transition_fid_vid(struct pow
 		return 1;
 
 	if ((reqfid != data->currfid) || (reqvid != data->currvid)) {
-		printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, curr 0x%x 0x%x\n",
+		printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, "
+				"curr 0x%x 0x%x\n",
 				smp_processor_id(),
 				reqfid, reqvid, data->currfid, data->currvid);
 		return 1;
@@ -311,13 +328,15 @@ static int transition_fid_vid(struct pow
 }
 
 /* Phase 1 - core voltage transition ... setup voltage */
-static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid)
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+		u32 reqvid)
 {
 	u32 rvosteps = data->rvo;
 	u32 savefid = data->currfid;
 	u32 maxvid, lo;
 
-	dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
+	dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
+		"reqvid 0x%x, rvo 0x%x\n",
 		smp_processor_id(),
 		data->currfid, data->currvid, reqvid, data->rvo);
 
@@ -340,7 +359,7 @@ static int core_voltage_pre_transition(s
 		} else {
 			dprintk("ph1: changing vid for rvo, req 0x%x\n",
 				data->currvid - 1);
-			if (decrease_vid_code_by_step(data, data->currvid - 1, 1))
+			if (decrease_vid_code_by_step(data, data->currvid-1, 1))
 				return 1;
 			rvosteps--;
 		}
@@ -350,7 +369,8 @@ static int core_voltage_pre_transition(s
 		return 1;
 
 	if (savefid != data->currfid) {
-		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", data->currfid);
+		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n",
+				data->currfid);
 		return 1;
 	}
 
@@ -363,20 +383,24 @@ static int core_voltage_pre_transition(s
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff;
+	u32 fid_interval, savevid = data->currvid;
 
-	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
-		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
-			reqfid, data->currfid);
+	if ((reqfid < HI_FID_TABLE_BOTTOM) &&
+	    (data->currfid < HI_FID_TABLE_BOTTOM)) {
+		printk(KERN_ERR PFX "ph2: illegal lo-lo transition "
+				"0x%x 0x%x\n", reqfid, data->currfid);
 		return 1;
 	}
 
 	if (data->currfid == reqfid) {
-		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", data->currfid);
+		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
+				data->currfid);
 		return 0;
 	}
 
-	dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
+	dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, "
+		"reqfid 0x%x\n",
 		smp_processor_id(),
 		data->currfid, data->currvid, reqfid);
 
@@ -390,14 +414,14 @@ static int core_frequency_transition(str
 
 		if (reqfid > data->currfid) {
 			if (data->currfid > LO_FID_TABLE_TOP) {
-				if (write_new_fid(data, data->currfid + fid_interval)) {
+				if (write_new_fid(data,
+						data->currfid + fid_interval))
 					return 1;
-				}
 			} else {
 				if (write_new_fid
-				    (data, 2 + convert_fid_to_vco_fid(data->currfid))) {
+				    (data,
+				     2 + convert_fid_to_vco_fid(data->currfid)))
 					return 1;
-				}
 			}
 		} else {
 			if (write_new_fid(data, data->currfid - fid_interval))
@@ -417,7 +441,8 @@ static int core_frequency_transition(str
 
 	if (data->currfid != reqfid) {
 		printk(KERN_ERR PFX
-			"ph2: mismatch, failed fid transition, curr 0x%x, req 0x%x\n",
+			"ph2: mismatch, failed fid transition, "
+			"curr 0x%x, req 0x%x\n",
 			data->currfid, reqfid);
 		return 1;
 	}
@@ -435,7 +460,8 @@ static int core_frequency_transition(str
 }
 
 /* Phase 3 - core voltage transition flow ... jump to the final vid. */
-static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid)
+static int core_voltage_post_transition(struct powernow_k8_data *data,
+		u32 reqvid)
 {
 	u32 savefid = data->currfid;
 	u32 savereqvid = reqvid;
@@ -457,7 +483,8 @@ static int core_voltage_post_transition(
 
 		if (data->currvid != reqvid) {
 			printk(KERN_ERR PFX
-			       "ph3: failed vid transition\n, req 0x%x, curr 0x%x",
+			       "ph3: failed vid transition\n, "
+			       "req 0x%x, curr 0x%x",
 			       reqvid, data->currvid);
 			return 1;
 		}
@@ -508,7 +535,8 @@ static int check_supported_cpu(unsigned
 	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
 		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
-			printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
+			printk(KERN_INFO PFX
+				"Processor cpuid %x not supported\n", eax);
 			goto out;
 		}
 
@@ -520,8 +548,10 @@ static int check_supported_cpu(unsigned
 		}
 
 		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
-		if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) {
-			printk(KERN_INFO PFX "Power state transitions not supported\n");
+		if ((edx & P_STATE_TRANSITION_CAPABLE)
+			!= P_STATE_TRANSITION_CAPABLE) {
+			printk(KERN_INFO PFX
+				"Power state transitions not supported\n");
 			goto out;
 		}
 	} else { /* must be a HW Pstate capable processor */
@@ -539,7 +569,8 @@ out:
 	return rc;
 }
 
-static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
+static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
+		u8 maxvid)
 {
 	unsigned int j;
 	u8 lastfid = 0xff;
@@ -550,12 +581,14 @@ static int check_pst_table(struct powern
 			       j, pst[j].vid);
 			return -EINVAL;
 		}
-		if (pst[j].vid < data->rvo) {	/* vid + rvo >= 0 */
+		if (pst[j].vid < data->rvo) {
+			/* vid + rvo >= 0 */
 			printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
 			       " %d\n", j);
 			return -ENODEV;
 		}
-		if (pst[j].vid < maxvid + data->rvo) {	/* vid + rvo >= maxvid */
+		if (pst[j].vid < maxvid + data->rvo) {
+			/* vid + rvo >= maxvid */
 			printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
 			       " %d\n", j);
 			return -ENODEV;
@@ -579,23 +612,31 @@ static int check_pst_table(struct powern
 		return -EINVAL;
 	}
 	if (lastfid > LO_FID_TABLE_TOP)
-		printk(KERN_INFO FW_BUG PFX  "first fid not from lo freq table\n");
+		printk(KERN_INFO FW_BUG PFX
+			"first fid not from lo freq table\n");
 
 	return 0;
 }
 
+static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
+{
+	data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
+
 static void print_basics(struct powernow_k8_data *data)
 {
 	int j;
 	for (j = 0; j < data->numps; j++) {
-		if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
+		if (data->powernow_table[j].frequency !=
+				CPUFREQ_ENTRY_INVALID) {
 			if (cpu_family == CPU_HW_PSTATE) {
-				printk(KERN_INFO PFX "   %d : pstate %d (%d MHz)\n",
-					j,
+				printk(KERN_INFO PFX
+					"   %d : pstate %d (%d MHz)\n", j,
 					data->powernow_table[j].index,
 					data->powernow_table[j].frequency/1000);
 			} else {
-				printk(KERN_INFO PFX "   %d : fid 0x%x (%d MHz), vid 0x%x\n",
+				printk(KERN_INFO PFX
+					"   %d : fid 0x%x (%d MHz), vid 0x%x\n",
 					j,
 					data->powernow_table[j].index & 0xff,
 					data->powernow_table[j].frequency/1000,
@@ -604,20 +645,39 @@ static void print_basics(struct powernow
 		}
 	}
 	if (data->batps)
-		printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps);
+		printk(KERN_INFO PFX "Only %d pstates on battery\n",
+				data->batps);
 }
 
-static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
+static u32 freq_from_fid_did(u32 fid, u32 did)
+{
+	u32 mhz = 0;
+
+	if (boot_cpu_data.x86 == 0x10)
+		mhz = (100 * (fid + 0x10)) >> did;
+	else if (boot_cpu_data.x86 == 0x11)
+		mhz = (100 * (fid + 8)) >> did;
+	else
+		BUG();
+
+	return mhz * 1000;
+}
+
+static int fill_powernow_table(struct powernow_k8_data *data,
+		struct pst_s *pst, u8 maxvid)
 {
 	struct cpufreq_frequency_table *powernow_table;
 	unsigned int j;
 
-	if (data->batps) {    /* use ACPI support to get full speed on mains power */
-		printk(KERN_WARNING PFX "Only %d pstates usable (use ACPI driver for full range\n", data->batps);
+	if (data->batps) {
+		/* use ACPI support to get full speed on mains power */
+		printk(KERN_WARNING PFX
+			"Only %d pstates usable (use ACPI driver for full "
+			"range\n", data->batps);
 		data->numps = data->batps;
 	}
 
-	for ( j=1; j<data->numps; j++ ) {
+	for (j = 1; j < data->numps; j++) {
 		if (pst[j-1].fid >= pst[j].fid) {
 			printk(KERN_ERR PFX "PST out of sequence\n");
 			return -EINVAL;
@@ -640,9 +700,11 @@ static int fill_powernow_table(struct po
 	}
 
 	for (j = 0; j < data->numps; j++) {
+		int freq;
 		powernow_table[j].index = pst[j].fid; /* lower 8 bits */
 		powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
-		powernow_table[j].frequency = find_khz_freq_from_fid(pst[j].fid);
+		freq = find_khz_freq_from_fid(pst[j].fid);
+		powernow_table[j].frequency = freq;
 	}
 	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
 	powernow_table[data->numps].index = 0;
@@ -654,11 +716,12 @@ static int fill_powernow_table(struct po
 
 	dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
 	data->powernow_table = powernow_table;
-	if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
 		print_basics(data);
 
 	for (j = 0; j < data->numps; j++)
-		if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
+		if ((pst[j].fid == data->currfid) &&
+		    (pst[j].vid == data->currvid))
 			return 0;
 
 	dprintk("currfid/vid do not match PST, ignoring\n");
@@ -698,7 +761,8 @@ static int find_psb_table(struct powerno
 		}
 
 		data->vstable = psb->vstable;
-		dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
+		dprintk("voltage stabilization time: %d(*20us)\n",
+				data->vstable);
 
 		dprintk("flags2: 0x%x\n", psb->flags2);
 		data->rvo = psb->flags2 & 3;
@@ -713,11 +777,12 @@ static int find_psb_table(struct powerno
 
 		dprintk("numpst: 0x%x\n", psb->num_tables);
 		cpst = psb->num_tables;
-		if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
+		if ((psb->cpuid == 0x00000fc0) ||
+		    (psb->cpuid == 0x00000fe0)) {
 			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-			if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) {
+			if ((thiscpuid == 0x00000fc0) ||
+			    (thiscpuid == 0x00000fe0))
 				cpst = 1;
-			}
 		}
 		if (cpst != 1) {
 			printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
@@ -732,7 +797,8 @@ static int find_psb_table(struct powerno
 
 		data->numps = psb->numps;
 		dprintk("numpstates: 0x%x\n", data->numps);
-		return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
+		return fill_powernow_table(data,
+				(struct pst_s *)(psb+1), maxvid);
 	}
 	/*
 	 * If you see this message, complain to BIOS manufacturer. If
@@ -745,28 +811,31 @@ static int find_psb_table(struct powerno
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * www.amd.com
 	 */
-	printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+	printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
 	return -ENODEV;
 }
 
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
+static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
+		unsigned int index)
 {
+	acpi_integer control;
+
 	if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
 		return;
 
-	data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
-	data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
-	data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
-	data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
-	data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
-	data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
-}
+	control = data->acpi_data.states[index].control; data->irt = (control
+			>> IRT_SHIFT) & IRT_MASK; data->rvo = (control >>
+				RVO_SHIFT) & RVO_MASK; data->exttype = (control
+					>> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+	data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1
+		<< ((control >> MVS_SHIFT) & MVS_MASK); data->vstable =
+		(control >> VST_SHIFT) & VST_MASK; }
 
 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 {
 	struct cpufreq_frequency_table *powernow_table;
 	int ret_val = -ENODEV;
+	acpi_integer control, status;
 
 	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
 		dprintk("register performance failed: bad ACPI data\n");
@@ -779,11 +848,13 @@ static int powernow_k8_cpu_init_acpi(str
 		goto err_out;
 	}
 
-	if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
-		(data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+	control = data->acpi_data.control_register.space_id;
+	status = data->acpi_data.status_register.space_id;
+
+	if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
 		dprintk("Invalid control/status registers (%x - %x)\n",
-			data->acpi_data.control_register.space_id,
-			data->acpi_data.status_register.space_id);
+			control, status);
 		goto err_out;
 	}
 
@@ -802,20 +873,21 @@ static int powernow_k8_cpu_init_acpi(str
 	if (ret_val)
 		goto err_out_mem;
 
-	powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
+	powernow_table[data->acpi_data.state_count].frequency =
+		CPUFREQ_TABLE_END;
 	powernow_table[data->acpi_data.state_count].index = 0;
 	data->powernow_table = powernow_table;
 
 	/* fill in data */
 	data->numps = data->acpi_data.state_count;
-	if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
 		print_basics(data);
 	powernow_k8_acpi_pst_values(data, 0);
 
 	/* notify BIOS that we exist */
 	acpi_processor_notify_smm(THIS_MODULE);
 
-	if (!alloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
+	if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
 		printk(KERN_ERR PFX
 				"unable to alloc powernow_k8_data cpumask\n");
 		ret_val = -ENOMEM;
@@ -830,13 +902,15 @@ err_out_mem:
 err_out:
 	acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
 
-	/* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
+	/* data->acpi_data.state_count informs us at ->exit()
+	 * whether ACPI was used */
 	data->acpi_data.state_count = 0;
 
 	return ret_val;
 }
 
-static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
+static int fill_powernow_table_pstate(struct powernow_k8_data *data,
+		struct cpufreq_frequency_table *powernow_table)
 {
 	int i;
 	u32 hi = 0, lo = 0;
@@ -848,84 +922,106 @@ static int fill_powernow_table_pstate(st
 
 		index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
 		if (index > data->max_hw_pstate) {
-			printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
-			printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
-			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+			printk(KERN_ERR PFX "invalid pstate %d - "
+					"bad value %d.\n", i, index);
+			printk(KERN_ERR PFX "Please report to BIOS "
+					"manufacturer\n");
+			invalidate_entry(data, i);
 			continue;
 		}
 		rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
 		if (!(hi & HW_PSTATE_VALID_MASK)) {
 			dprintk("invalid pstate %d, ignoring\n", index);
-			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+			invalidate_entry(data, i);
 			continue;
 		}
 
 		powernow_table[i].index = index;
 
-		powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000;
+		/* Frequency may be rounded for these */
+		if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+			powernow_table[i].frequency =
+				freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
+		} else
+			powernow_table[i].frequency =
+				data->acpi_data.states[i].core_frequency * 1000;
 	}
 	return 0;
 }
 
-static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
+static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+		struct cpufreq_frequency_table *powernow_table)
 {
 	int i;
 	int cntlofreq = 0;
+
 	for (i = 0; i < data->acpi_data.state_count; i++) {
 		u32 fid;
 		u32 vid;
+		u32 freq, index;
+		acpi_integer status, control;
 
 		if (data->exttype) {
-			fid = data->acpi_data.states[i].status & EXT_FID_MASK;
-			vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK;
+			status =  data->acpi_data.states[i].status;
+			fid = status & EXT_FID_MASK;
+			vid = (status >> VID_SHIFT) & EXT_VID_MASK;
 		} else {
-			fid = data->acpi_data.states[i].control & FID_MASK;
-			vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
+			control =  data->acpi_data.states[i].control;
+			fid = control & FID_MASK;
+			vid = (control >> VID_SHIFT) & VID_MASK;
 		}
 
 		dprintk("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
 
-		powernow_table[i].index = fid; /* lower 8 bits */
-		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
-		powernow_table[i].frequency = find_khz_freq_from_fid(fid);
+		index = fid | (vid<<8);
+		powernow_table[i].index = index;
+
+		freq = find_khz_freq_from_fid(fid);
+		powernow_table[i].frequency = freq;
 
 		/* verify frequency is OK */
-		if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) ||
-			(powernow_table[i].frequency < (MIN_FREQ * 1000))) {
-			dprintk("invalid freq %u kHz, ignoring\n", powernow_table[i].frequency);
-			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
+			dprintk("invalid freq %u kHz, ignoring\n", freq);
+			invalidate_entry(data, i);
 			continue;
 		}
 
-		/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
+		/* verify voltage is OK -
+		 * BIOSs are using "off" to indicate invalid */
 		if (vid == VID_OFF) {
 			dprintk("invalid vid %u, ignoring\n", vid);
-			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+			invalidate_entry(data, i);
 			continue;
 		}
 
 		/* verify only 1 entry from the lo frequency table */
 		if (fid < HI_FID_TABLE_BOTTOM) {
 			if (cntlofreq) {
-				/* if both entries are the same, ignore this one ... */
-				if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
-				    (powernow_table[i].index != powernow_table[cntlofreq].index)) {
-					printk(KERN_ERR PFX "Too many lo freq table entries\n");
+				/* if both entries are the same,
+				 * ignore this one ... */
+				if ((freq != powernow_table[cntlofreq].frequency) ||
+				    (index != powernow_table[cntlofreq].index)) {
+					printk(KERN_ERR PFX
+						"Too many lo freq table "
+						"entries\n");
 					return 1;
 				}
 
-				dprintk("double low frequency table entry, ignoring it.\n");
-				powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+				dprintk("double low frequency table entry, "
+						"ignoring it.\n");
+				invalidate_entry(data, i);
 				continue;
 			} else
 				cntlofreq = i;
 		}
 
-		if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
-			printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
-				powernow_table[i].frequency,
-				(unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
-			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+		if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
+			printk(KERN_INFO PFX "invalid freq entries "
+				"%u kHz vs. %u kHz\n", freq,
+				(unsigned int)
+				(data->acpi_data.states[i].core_frequency
+				 * 1000));
+			invalidate_entry(data, i);
 			continue;
 		}
 	}
@@ -935,7 +1031,8 @@ static int fill_powernow_table_fidvid(st
 static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
 {
 	if (data->acpi_data.state_count)
-		acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
+		acpi_processor_unregister_performance(&data->acpi_data,
+				data->cpu);
 	free_cpumask_var(data->acpi_data.shared_cpu_map);
 }
 
@@ -953,15 +1050,9 @@ static int get_transition_latency(struct
 	return 1000 * max_latency;
 }
 
-#else
-static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
-static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
-static int get_transition_latency(struct powernow_k8_data *data) { return 0; }
-#endif /* CONFIG_X86_POWERNOW_K8_ACPI */
-
 /* Take a frequency, and issue the fid/vid transition command */
-static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index)
+static int transition_frequency_fidvid(struct powernow_k8_data *data,
+		unsigned int index)
 {
 	u32 fid = 0;
 	u32 vid = 0;
@@ -989,7 +1080,8 @@ static int transition_frequency_fidvid(s
 		return 0;
 	}
 
-	if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
+	if ((fid < HI_FID_TABLE_BOTTOM) &&
+	    (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX
 		       "ignoring illegal change in lo freq table-%x to 0x%x\n",
 		       data->currfid, fid);
@@ -1017,7 +1109,8 @@ static int transition_frequency_fidvid(s
 }
 
 /* Take a frequency, and issue the hardware pstate transition command */
-static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index)
+static int transition_frequency_pstate(struct powernow_k8_data *data,
+		unsigned int index)
 {
 	u32 pstate = 0;
 	int res, i;
@@ -1029,7 +1122,8 @@ static int transition_frequency_pstate(s
 	pstate = index & HW_PSTATE_MASK;
 	if (pstate > data->max_hw_pstate)
 		return 0;
-	freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+	freqs.old = find_khz_freq_from_pstate(data->powernow_table,
+			data->currpstate);
 	freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
 
 	for_each_cpu_mask_nr(i, *(data->available_cores)) {
@@ -1048,7 +1142,8 @@ static int transition_frequency_pstate(s
 }
 
 /* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation)
+static int powernowk8_target(struct cpufreq_policy *pol,
+		unsigned targfreq, unsigned relation)
 {
 	cpumask_t oldmask;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
@@ -1087,14 +1182,18 @@ static int powernowk8_target(struct cpuf
 		dprintk("targ: curr fid 0x%x, vid 0x%x\n",
 		data->currfid, data->currvid);
 
-		if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
+		if ((checkvid != data->currvid) ||
+		    (checkfid != data->currfid)) {
 			printk(KERN_INFO PFX
-				"error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
-				checkfid, data->currfid, checkvid, data->currvid);
+				"error - out of sync, fix 0x%x 0x%x, "
+				"vid 0x%x 0x%x\n",
+				checkfid, data->currfid,
+				checkvid, data->currvid);
 		}
 	}
 
-	if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
+	if (cpufreq_frequency_table_target(pol, data->powernow_table,
+				targfreq, relation, &newstate))
 		goto err_out;
 
 	mutex_lock(&fidvid_mutex);
@@ -1114,7 +1213,8 @@ static int powernowk8_target(struct cpuf
 	mutex_unlock(&fidvid_mutex);
 
 	if (cpu_family == CPU_HW_PSTATE)
-		pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate);
+		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+				newstate);
 	else
 		pol->cur = find_khz_freq_from_fid(data->currfid);
 	ret = 0;
@@ -1135,6 +1235,10 @@ static int powernowk8_verify(struct cpuf
 	return cpufreq_frequency_table_verify(pol, data->powernow_table);
 }
 
+static const char ACPI_PSS_BIOS_BUG_MSG[] =
+	KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
+	KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n";
+
 /* per CPU init entry point to the driver */
 static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 {
@@ -1163,33 +1267,19 @@ static int __cpuinit powernowk8_cpu_init
 		 * an UP version, and is deprecated by AMD.
 		 */
 		if (num_online_cpus() != 1) {
-#ifndef CONFIG_ACPI_PROCESSOR
-			printk(KERN_ERR PFX "ACPI Processor support is required "
-			       "for SMP systems but is absent. Please load the "
-			       "ACPI Processor module before starting this "
-			       "driver.\n");
-#else
-			printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide"
-			       " ACPI _PSS objects in a way that Linux "
-			       "understands. Please report this to the Linux "
-			       "ACPI maintainers and complain to your BIOS "
-			       "vendor.\n");
-#endif
-			kfree(data);
-			return -ENODEV;
+			printk_once(ACPI_PSS_BIOS_BUG_MSG);
+			goto err_out;
 		}
 		if (pol->cpu != 0) {
 			printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
 			       "CPU other than CPU0. Complain to your BIOS "
 			       "vendor.\n");
-			kfree(data);
-			return -ENODEV;
+			goto err_out;
 		}
 		rc = find_psb_table(data);
-		if (rc) {
-			kfree(data);
-			return -ENODEV;
-		}
+		if (rc)
+			goto err_out;
+
 		/* Take a crude guess here.
 		 * That guess was in microseconds, so multiply with 1000 */
 		pol->cpuinfo.transition_latency = (
@@ -1204,16 +1294,16 @@ static int __cpuinit powernowk8_cpu_init
 
 	if (smp_processor_id() != pol->cpu) {
 		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
-		goto err_out;
+		goto err_out_unmask;
 	}
 
 	if (pending_bit_stuck()) {
 		printk(KERN_ERR PFX "failing init, change pending bit set\n");
-		goto err_out;
+		goto err_out_unmask;
 	}
 
 	if (query_current_values_with_pending_wait(data))
-		goto err_out;
+		goto err_out_unmask;
 
 	if (cpu_family == CPU_OPTERON)
 		fidvid_msr_init();
@@ -1224,11 +1314,12 @@ static int __cpuinit powernowk8_cpu_init
 	if (cpu_family == CPU_HW_PSTATE)
 		cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
 	else
-		cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
+		cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
 	data->available_cores = pol->cpus;
 
 	if (cpu_family == CPU_HW_PSTATE)
-		pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+				data->currpstate);
 	else
 		pol->cur = find_khz_freq_from_fid(data->currfid);
 	dprintk("policy current frequency %d kHz\n", pol->cur);
@@ -1245,7 +1336,8 @@ static int __cpuinit powernowk8_cpu_init
 	cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
 
 	if (cpu_family == CPU_HW_PSTATE)
-		dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate);
+		dprintk("cpu_init done, current pstate 0x%x\n",
+				data->currpstate);
 	else
 		dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
 			data->currfid, data->currvid);
@@ -1254,15 +1346,16 @@ static int __cpuinit powernowk8_cpu_init
 
 	return 0;
 
-err_out:
+err_out_unmask:
 	set_cpus_allowed_ptr(current, &oldmask);
 	powernow_k8_cpu_exit_acpi(data);
 
+err_out:
 	kfree(data);
 	return -ENODEV;
 }
 
-static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
 {
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 
@@ -1279,14 +1372,14 @@ static int __devexit powernowk8_cpu_exit
 	return 0;
 }
 
-static unsigned int powernowk8_get (unsigned int cpu)
+static unsigned int powernowk8_get(unsigned int cpu)
 {
 	struct powernow_k8_data *data;
 	cpumask_t oldmask = current->cpus_allowed;
 	unsigned int khz = 0;
 	unsigned int first;
 
-	first = first_cpu(per_cpu(cpu_core_map, cpu));
+	first = cpumask_first(cpu_core_mask(cpu));
 	data = per_cpu(powernow_data, first);
 
 	if (!data)
@@ -1315,7 +1408,7 @@ out:
 	return khz;
 }
 
-static struct freq_attr* powernow_k8_attr[] = {
+static struct freq_attr *powernow_k8_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -1360,7 +1453,8 @@ static void __exit powernowk8_exit(void)
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and "
+		"Mark Langsdorf <mark.langsdorf@amd.com>");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.h linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,11 +45,10 @@ struct powernow_k8_data {
 	 * frequency is in kHz */
 	struct cpufreq_frequency_table  *powernow_table;
 
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 	/* the acpi table needs to be kept. it's only available if ACPI was
 	 * used to determine valid frequency/vid/fid states */
 	struct acpi_processor_performance acpi_data;
-#endif
+
 	/* we need to keep track of associated cores, but let cpufreq
 	 * handle hotplug events - so just point at cpufreq pol->cpus
 	 * structure */
@@ -222,10 +221,8 @@ static int core_frequency_transition(str
 
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
 
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
 static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
-#endif
 
 #ifdef CONFIG_SMP
 static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/sc520_freq.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/sc520_freq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/sc520_freq.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,17 +19,19 @@
 
 #include <linux/delay.h>
 #include <linux/cpufreq.h>
+#include <linux/timex.h>
+#include <linux/io.h>
 
 #include <asm/msr.h>
-#include <asm/timex.h>
-#include <asm/io.h>
 
 #define MMCR_BASE	0xfffef000	/* The default base address */
 #define OFFS_CPUCTL	0x2   /* CPU Control Register */
 
 static __u8 __iomem *cpuctl;
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"sc520_freq", msg)
+#define PFX "sc520_freq: "
 
 static struct cpufreq_frequency_table sc520_freq_table[] = {
 	{0x01,	100000},
@@ -43,7 +45,8 @@ static unsigned int sc520_freq_get_cpu_f
 
 	switch (clockspeed_reg & 0x03) {
 	default:
-		printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
+		printk(KERN_ERR PFX "error: cpuctl register has unexpected "
+				"value %02x\n", clockspeed_reg);
 	case 0x01:
 		return 100000;
 	case 0x02:
@@ -51,7 +54,7 @@ static unsigned int sc520_freq_get_cpu_f
 	}
 }
 
-static void sc520_freq_set_cpu_state (unsigned int state)
+static void sc520_freq_set_cpu_state(unsigned int state)
 {
 
 	struct cpufreq_freqs	freqs;
@@ -76,18 +79,19 @@ static void sc520_freq_set_cpu_state (un
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 };
 
-static int sc520_freq_verify (struct cpufreq_policy *policy)
+static int sc520_freq_verify(struct cpufreq_policy *policy)
 {
 	return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
 }
 
-static int sc520_freq_target (struct cpufreq_policy *policy,
+static int sc520_freq_target(struct cpufreq_policy *policy,
 			    unsigned int target_freq,
 			    unsigned int relation)
 {
 	unsigned int newstate = 0;
 
-	if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, sc520_freq_table,
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	sc520_freq_set_cpu_state(newstate);
@@ -116,7 +120,7 @@ static int sc520_freq_cpu_init(struct cp
 
 	result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
 	if (result)
-		return (result);
+		return result;
 
 	cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
 
@@ -131,7 +135,7 @@ static int sc520_freq_cpu_exit(struct cp
 }
 
 
-static struct freq_attr* sc520_freq_attr[] = {
+static struct freq_attr *sc520_freq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -155,13 +159,13 @@ static int __init sc520_freq_init(void)
 	int err;
 
 	/* Test if we have the right hardware */
-	if(c->x86_vendor != X86_VENDOR_AMD ||
-				c->x86 != 4 || c->x86_model != 9) {
+	if (c->x86_vendor != X86_VENDOR_AMD ||
+	    c->x86 != 4 || c->x86_model != 9) {
 		dprintk("no Elan SC520 processor found!\n");
 		return -ENODEV;
 	}
 	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
-	if(!cpuctl) {
+	if (!cpuctl) {
 		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
 		return -ENOMEM;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	2009-06-09 23:05:27.000000000 -0400
@@ -390,14 +390,14 @@ static int centrino_cpu_init(struct cpuf
 	   enable it if not. */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
 
-	if (!(l & (1<<16))) {
-		l |= (1<<16);
+	if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+		l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
 		dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
 		wrmsr(MSR_IA32_MISC_ENABLE, l, h);
 
 		/* check to see if it stuck */
 		rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-		if (!(l & (1<<16))) {
+		if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
 			printk(KERN_INFO PFX
 				"couldn't enable Enhanced SpeedStep\n");
 			return -ENODEV;
@@ -471,7 +471,7 @@ static int centrino_target (struct cpufr
 
 	if (unlikely(!alloc_cpumask_var(&saved_mask, GFP_KERNEL)))
 		return -ENOMEM;
-	if (unlikely(!alloc_cpumask_var(&covered_cpus, GFP_KERNEL))) {
+	if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) {
 		free_cpumask_var(saved_mask);
 		return -ENOMEM;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset
 
 /* speedstep_processor
  */
-static unsigned int speedstep_processor = 0;
+static unsigned int speedstep_processor;
 
 static u32 pmbase;
 
@@ -54,7 +54,8 @@ static struct cpufreq_frequency_table sp
 };
 
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-ich", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"speedstep-ich", msg)
 
 
 /**
@@ -62,7 +63,7 @@ static struct cpufreq_frequency_table sp
  *
  * Returns: -ENODEV if no register could be found
  */
-static int speedstep_find_register (void)
+static int speedstep_find_register(void)
 {
 	if (!speedstep_chipset_dev)
 		return -ENODEV;
@@ -90,7 +91,7 @@ static int speedstep_find_register (void
  *
  *   Tries to change the SpeedStep state.
  */
-static void speedstep_set_state (unsigned int state)
+static void speedstep_set_state(unsigned int state)
 {
 	u8 pm2_blk;
 	u8 value;
@@ -133,11 +134,11 @@ static void speedstep_set_state (unsigne
 
 	dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
 
-	if (state == (value & 0x1)) {
-		dprintk("change to %u MHz succeeded\n", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
-	} else {
-		printk (KERN_ERR "cpufreq: change failed - I/O error\n");
-	}
+	if (state == (value & 0x1))
+		dprintk("change to %u MHz succeeded\n",
+			speedstep_get_frequency(speedstep_processor) / 1000);
+	else
+		printk(KERN_ERR "cpufreq: change failed - I/O error\n");
 
 	return;
 }
@@ -149,7 +150,7 @@ static void speedstep_set_state (unsigne
  *   Tries to activate the SpeedStep status and control registers.
  * Returns -EINVAL on an unsupported chipset, and zero on success.
  */
-static int speedstep_activate (void)
+static int speedstep_activate(void)
 {
 	u16 value = 0;
 
@@ -175,20 +176,18 @@ static int speedstep_activate (void)
  * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
  * chipset, or zero on failure.
  */
-static unsigned int speedstep_detect_chipset (void)
+static unsigned int speedstep_detect_chipset(void)
 {
 	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801DB_12,
-			      PCI_ANY_ID,
-			      PCI_ANY_ID,
+			      PCI_ANY_ID, PCI_ANY_ID,
 			      NULL);
 	if (speedstep_chipset_dev)
 		return 4; /* 4-M */
 
 	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801CA_12,
-			      PCI_ANY_ID,
-			      PCI_ANY_ID,
+			      PCI_ANY_ID, PCI_ANY_ID,
 			      NULL);
 	if (speedstep_chipset_dev)
 		return 3; /* 3-M */
@@ -196,8 +195,7 @@ static unsigned int speedstep_detect_chi
 
 	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801BA_10,
-			      PCI_ANY_ID,
-			      PCI_ANY_ID,
+			      PCI_ANY_ID, PCI_ANY_ID,
 			      NULL);
 	if (speedstep_chipset_dev) {
 		/* speedstep.c causes lockups on Dell Inspirons 8000 and
@@ -208,8 +206,7 @@ static unsigned int speedstep_detect_chi
 
 		hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82815_MC,
-			      PCI_ANY_ID,
-			      PCI_ANY_ID,
+			      PCI_ANY_ID, PCI_ANY_ID,
 			      NULL);
 
 		if (!hostbridge)
@@ -236,7 +233,7 @@ static unsigned int _speedstep_get(const
 
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed_ptr(current, cpus);
-	speed = speedstep_get_processor_frequency(speedstep_processor);
+	speed = speedstep_get_frequency(speedstep_processor);
 	set_cpus_allowed_ptr(current, &cpus_allowed);
 	dprintk("detected %u kHz as current frequency\n", speed);
 	return speed;
@@ -251,11 +248,12 @@ static unsigned int speedstep_get(unsign
  * speedstep_target - set a new CPUFreq policy
  * @policy: new policy
  * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
  *
  * Sets a new CPUFreq policy.
  */
-static int speedstep_target (struct cpufreq_policy *policy,
+static int speedstep_target(struct cpufreq_policy *policy,
 			     unsigned int target_freq,
 			     unsigned int relation)
 {
@@ -264,7 +262,8 @@ static int speedstep_target (struct cpuf
 	cpumask_t cpus_allowed;
 	int i;
 
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	freqs.old = _speedstep_get(policy->cpus);
@@ -308,7 +307,7 @@ static int speedstep_target (struct cpuf
  * Limit must be within speedstep_low_freq and speedstep_high_freq, with
  * at least one border included.
  */
-static int speedstep_verify (struct cpufreq_policy *policy)
+static int speedstep_verify(struct cpufreq_policy *policy)
 {
 	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
 }
@@ -322,7 +321,7 @@ static int speedstep_cpu_init(struct cpu
 
 	/* only run on CPU to be set, or on its sibling */
 #ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
 #endif
 
 	cpus_allowed = current->cpus_allowed;
@@ -344,7 +343,8 @@ static int speedstep_cpu_init(struct cpu
 		return -EIO;
 
 	dprintk("currently at %s speed setting - %i MHz\n",
-		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+		? "low" : "high",
 		(speed / 1000));
 
 	/* cpuinfo and default policy values */
@@ -352,9 +352,9 @@ static int speedstep_cpu_init(struct cpu
 
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
 	if (result)
-		return (result);
+		return result;
 
-        cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
+	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
 
 	return 0;
 }
@@ -366,7 +366,7 @@ static int speedstep_cpu_exit(struct cpu
 	return 0;
 }
 
-static struct freq_attr* speedstep_attr[] = {
+static struct freq_attr *speedstep_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -396,13 +396,15 @@ static int __init speedstep_init(void)
 	/* detect processor */
 	speedstep_processor = speedstep_detect_processor();
 	if (!speedstep_processor) {
-		dprintk("Intel(R) SpeedStep(TM) capable processor not found\n");
+		dprintk("Intel(R) SpeedStep(TM) capable processor "
+				"not found\n");
 		return -ENODEV;
 	}
 
 	/* detect chipset */
 	if (!speedstep_detect_chipset()) {
-		dprintk("Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n");
+		dprintk("Intel(R) SpeedStep(TM) for this chipset not "
+				"(yet) available.\n");
 		return -ENODEV;
 	}
 
@@ -431,9 +433,11 @@ static void __exit speedstep_exit(void)
 }
 
 
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>, "
+		"Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets "
+		"with ICH-M southbridges.");
+MODULE_LICENSE("GPL");
 
 module_init(speedstep_init);
 module_exit(speedstep_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,12 +16,16 @@
 #include <linux/slab.h>
 
 #include <asm/msr.h>
+#include <asm/tsc.h>
 #include "speedstep-lib.h"
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-lib", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"speedstep-lib", msg)
+
+#define PFX "speedstep-lib: "
 
 #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
-static int relaxed_check = 0;
+static int relaxed_check;
 #else
 #define relaxed_check 0
 #endif
@@ -30,14 +34,14 @@ static int relaxed_check = 0;
  *                   GET PROCESSOR CORE SPEED IN KHZ                 *
  *********************************************************************/
 
-static unsigned int pentium3_get_frequency (unsigned int processor)
+static unsigned int pentium3_get_frequency(unsigned int processor)
 {
-        /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
+	/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
 	struct {
 		unsigned int ratio;	/* Frequency Multiplier (x10) */
 		u8 bitmap;		/* power on configuration bits
 					[27, 25:22] (in MSR 0x2a) */
-	} msr_decode_mult [] = {
+	} msr_decode_mult[] = {
 		{ 30, 0x01 },
 		{ 35, 0x05 },
 		{ 40, 0x02 },
@@ -52,7 +56,7 @@ static unsigned int pentium3_get_frequen
 		{ 85, 0x26 },
 		{ 90, 0x20 },
 		{ 100, 0x2b },
-		{ 0, 0xff }     /* error or unknown value */
+		{ 0, 0xff }	/* error or unknown value */
 	};
 
 	/* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
@@ -60,7 +64,7 @@ static unsigned int pentium3_get_frequen
 		unsigned int value;	/* Front Side Bus speed in MHz */
 		u8 bitmap;		/* power on configuration bits [18: 19]
 					(in MSR 0x2a) */
-	} msr_decode_fsb [] = {
+	} msr_decode_fsb[] = {
 		{  66, 0x0 },
 		{ 100, 0x2 },
 		{ 133, 0x1 },
@@ -85,7 +89,7 @@ static unsigned int pentium3_get_frequen
 	}
 
 	/* decode the multiplier */
-	if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) {
+	if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
 		dprintk("workaround for early PIIIs\n");
 		msr_lo &= 0x03c00000;
 	} else
@@ -97,9 +101,10 @@ static unsigned int pentium3_get_frequen
 		j++;
 	}
 
-	dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
+	dprintk("speed is %u\n",
+		(msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
 
-	return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);
+	return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
 }
 
 
@@ -112,20 +117,23 @@ static unsigned int pentiumM_get_frequen
 
 	/* see table B-2 of 24547212.pdf */
 	if (msr_lo & 0x00040000) {
-		printk(KERN_DEBUG "speedstep-lib: PM - invalid FSB: 0x%x 0x%x\n", msr_lo, msr_tmp);
+		printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
+				msr_lo, msr_tmp);
 		return 0;
 	}
 
 	msr_tmp = (msr_lo >> 22) & 0x1f;
-	dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000));
+	dprintk("bits 22-26 are 0x%x, speed is %u\n",
+			msr_tmp, (msr_tmp * 100 * 1000));
 
-	return (msr_tmp * 100 * 1000);
+	return msr_tmp * 100 * 1000;
 }
 
 static unsigned int pentium_core_get_frequency(void)
 {
 	u32 fsb = 0;
 	u32 msr_lo, msr_tmp;
+	int ret;
 
 	rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
 	/* see table B-2 of 25366920.pdf */
@@ -153,12 +161,15 @@ static unsigned int pentium_core_get_fre
 	}
 
 	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
-	dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+	dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
+			msr_lo, msr_tmp);
 
 	msr_tmp = (msr_lo >> 22) & 0x1f;
-	dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb));
+	dprintk("bits 22-26 are 0x%x, speed is %u\n",
+			msr_tmp, (msr_tmp * fsb));
 
-	return (msr_tmp * fsb);
+	ret = (msr_tmp * fsb);
+	return ret;
 }
 
 
@@ -167,6 +178,16 @@ static unsigned int pentium4_get_frequen
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 	u32 msr_lo, msr_hi, mult;
 	unsigned int fsb = 0;
+	unsigned int ret;
+	u8 fsb_code;
+
+	/* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
+	 * to System Bus Frequency Ratio Field in the Processor Frequency
+	 * Configuration Register of the MSR. Therefore the current
+	 * frequency cannot be calculated and has to be measured.
+	 */
+	if (c->x86_model < 2)
+		return cpu_khz;
 
 	rdmsr(0x2c, msr_lo, msr_hi);
 
@@ -177,62 +198,61 @@ static unsigned int pentium4_get_frequen
 	 * revision #12 in Table B-1: MSRs in the Pentium 4 and
 	 * Intel Xeon Processors, on page B-4 and B-5.
 	 */
-	if (c->x86_model < 2)
+	fsb_code = (msr_lo >> 16) & 0x7;
+	switch (fsb_code) {
+	case 0:
 		fsb = 100 * 1000;
-	else {
-		u8 fsb_code = (msr_lo >> 16) & 0x7;
-		switch (fsb_code) {
-		case 0:
-			fsb = 100 * 1000;
-			break;
-		case 1:
-			fsb = 13333 * 10;
-			break;
-		case 2:
-			fsb = 200 * 1000;
-			break;
-		}
+		break;
+	case 1:
+		fsb = 13333 * 10;
+		break;
+	case 2:
+		fsb = 200 * 1000;
+		break;
 	}
 
 	if (!fsb)
-		printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");
+		printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
+				"Please send an e-mail to <linux@brodo.de>\n");
 
 	/* Multiplier. */
 	mult = msr_lo >> 24;
 
-	dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult));
+	dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
+			fsb, mult, (fsb * mult));
 
-	return (fsb * mult);
+	ret = (fsb * mult);
+	return ret;
 }
 
 
-unsigned int speedstep_get_processor_frequency(unsigned int processor)
+unsigned int speedstep_get_frequency(unsigned int processor)
 {
 	switch (processor) {
-	case SPEEDSTEP_PROCESSOR_PCORE:
+	case SPEEDSTEP_CPU_PCORE:
 		return pentium_core_get_frequency();
-	case SPEEDSTEP_PROCESSOR_PM:
+	case SPEEDSTEP_CPU_PM:
 		return pentiumM_get_frequency();
-	case SPEEDSTEP_PROCESSOR_P4D:
-	case SPEEDSTEP_PROCESSOR_P4M:
+	case SPEEDSTEP_CPU_P4D:
+	case SPEEDSTEP_CPU_P4M:
 		return pentium4_get_frequency();
-	case SPEEDSTEP_PROCESSOR_PIII_T:
-	case SPEEDSTEP_PROCESSOR_PIII_C:
-	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
+	case SPEEDSTEP_CPU_PIII_T:
+	case SPEEDSTEP_CPU_PIII_C:
+	case SPEEDSTEP_CPU_PIII_C_EARLY:
 		return pentium3_get_frequency(processor);
 	default:
 		return 0;
 	};
 	return 0;
 }
-EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
+EXPORT_SYMBOL_GPL(speedstep_get_frequency);
 
 
 /*********************************************************************
  *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
  *********************************************************************/
 
-unsigned int speedstep_detect_processor (void)
+unsigned int speedstep_detect_processor(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
 	u32 ebx, msr_lo, msr_hi;
@@ -261,7 +281,7 @@ unsigned int speedstep_detect_processor
 			 * sample has ebx = 0x0f, production has 0x0e.
 			 */
 			if ((ebx == 0x0e) || (ebx == 0x0f))
-				return SPEEDSTEP_PROCESSOR_P4M;
+				return SPEEDSTEP_CPU_P4M;
 			break;
 		case 7:
 			/*
@@ -272,7 +292,7 @@ unsigned int speedstep_detect_processor
 			 * samples are only of B-stepping...
 			 */
 			if (ebx == 0x0e)
-				return SPEEDSTEP_PROCESSOR_P4M;
+				return SPEEDSTEP_CPU_P4M;
 			break;
 		case 9:
 			/*
@@ -288,10 +308,13 @@ unsigned int speedstep_detect_processor
 			 * M-P4-Ms may have either ebx=0xe or 0xf [see above]
 			 * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
 			 * also, M-P4M HTs have ebx=0x8, too
-			 * For now, they are distinguished by the model_id string
+			 * For now, they are distinguished by the model_id
+			 * string
 			 */
-			if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL))
-				return SPEEDSTEP_PROCESSOR_P4M;
+			if ((ebx == 0x0e) ||
+				(strstr(c->x86_model_id,
+				    "Mobile Intel(R) Pentium(R) 4") != NULL))
+				return SPEEDSTEP_CPU_P4M;
 			break;
 		default:
 			break;
@@ -301,7 +324,8 @@ unsigned int speedstep_detect_processor
 
 	switch (c->x86_model) {
 	case 0x0B: /* Intel PIII [Tualatin] */
-		/* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */
+		/* cpuid_ebx(1) is 0x04 for desktop PIII,
+		 * 0x06 for mobile PIII-M */
 		ebx = cpuid_ebx(0x00000001);
 		dprintk("ebx is %x\n", ebx);
 
@@ -313,14 +337,15 @@ unsigned int speedstep_detect_processor
 		/* So far all PIII-M processors support SpeedStep. See
 		 * Intel's 24540640.pdf of June 2003
 		 */
-		return SPEEDSTEP_PROCESSOR_PIII_T;
+		return SPEEDSTEP_CPU_PIII_T;
 
 	case 0x08: /* Intel PIII [Coppermine] */
 
 		/* all mobile PIII Coppermines have FSB 100 MHz
 		 * ==> sort out a few desktop PIIIs. */
 		rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
-		dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);
+		dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
+				msr_lo, msr_hi);
 		msr_lo &= 0x00c0000;
 		if (msr_lo != 0x0080000)
 			return 0;
@@ -332,13 +357,15 @@ unsigned int speedstep_detect_processor
 		 * bit 56 or 57 is set
 		 */
 		rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
-		dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
-		if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
+		dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
+				msr_lo, msr_hi);
+		if ((msr_hi & (1<<18)) &&
+		    (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
 			if (c->x86_mask == 0x01) {
 				dprintk("early PIII version\n");
-				return SPEEDSTEP_PROCESSOR_PIII_C_EARLY;
+				return SPEEDSTEP_CPU_PIII_C_EARLY;
 			} else
-				return SPEEDSTEP_PROCESSOR_PIII_C;
+				return SPEEDSTEP_CPU_PIII_C;
 		}
 
 	default:
@@ -369,7 +396,7 @@ unsigned int speedstep_get_freqs(unsigne
 	dprintk("trying to determine both speeds\n");
 
 	/* get current speed */
-	prev_speed = speedstep_get_processor_frequency(processor);
+	prev_speed = speedstep_get_frequency(processor);
 	if (!prev_speed)
 		return -EIO;
 
@@ -379,7 +406,7 @@ unsigned int speedstep_get_freqs(unsigne
 
 	/* switch to low state */
 	set_state(SPEEDSTEP_LOW);
-	*low_speed = speedstep_get_processor_frequency(processor);
+	*low_speed = speedstep_get_frequency(processor);
 	if (!*low_speed) {
 		ret = -EIO;
 		goto out;
@@ -398,7 +425,7 @@ unsigned int speedstep_get_freqs(unsigne
 	if (transition_latency)
 		do_gettimeofday(&tv2);
 
-	*high_speed = speedstep_get_processor_frequency(processor);
+	*high_speed = speedstep_get_frequency(processor);
 	if (!*high_speed) {
 		ret = -EIO;
 		goto out;
@@ -426,9 +453,12 @@ unsigned int speedstep_get_freqs(unsigne
 		/* check if the latency measurement is too high or too low
 		 * and set it to a safe value (500uSec) in that case
 		 */
-		if (*transition_latency > 10000000 || *transition_latency < 50000) {
-			printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
-					"range (%u nSec), falling back to a safe one of %u nSec.\n",
+		if (*transition_latency > 10000000 ||
+		    *transition_latency < 50000) {
+			printk(KERN_WARNING PFX "frequency transition "
+					"measured seems out of range (%u "
+					"nSec), falling back to a safe one of"
+					"%u nSec.\n",
 					*transition_latency, 500000);
 			*transition_latency = 500000;
 		}
@@ -436,15 +466,16 @@ unsigned int speedstep_get_freqs(unsigne
 
 out:
 	local_irq_restore(flags);
-	return (ret);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(speedstep_get_freqs);
 
 #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
 module_param(relaxed_check, int, 0444);
-MODULE_PARM_DESC(relaxed_check, "Don't do all checks for speedstep capability.");
+MODULE_PARM_DESC(relaxed_check,
+		"Don't do all checks for speedstep capability.");
 #endif
 
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	2009-06-09 23:05:27.000000000 -0400
@@ -12,17 +12,17 @@
 
 /* processors */
 
-#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY	0x00000001  /* Coppermine core */
-#define SPEEDSTEP_PROCESSOR_PIII_C		0x00000002  /* Coppermine core */
-#define SPEEDSTEP_PROCESSOR_PIII_T		0x00000003  /* Tualatin core */
-#define SPEEDSTEP_PROCESSOR_P4M			0x00000004  /* P4-M  */
+#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  */
 
 /* 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_processor_frequency() call. */
-#define SPEEDSTEP_PROCESSOR_PM			0xFFFFFF03  /* Pentium M  */
-#define SPEEDSTEP_PROCESSOR_P4D			0xFFFFFF04  /* desktop P4  */
-#define SPEEDSTEP_PROCESSOR_PCORE		0xFFFFFF05  /* Core */
+ * 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 states -- only two of them */
 
@@ -34,7 +34,7 @@
 extern unsigned int speedstep_detect_processor (void);
 
 /* detect the current speed (in khz) of the processor */
-extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
+extern unsigned int speedstep_get_frequency(unsigned int processor);
 
 
 /* detect the low and high speeds of the processor. The callback
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,8 +19,8 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <asm/ist.h>
-#include <asm/io.h>
 
 #include "speedstep-lib.h"
 
@@ -30,12 +30,12 @@
  * If user gives it, these are used.
  *
  */
-static int smi_port = 0;
-static int smi_cmd = 0;
-static unsigned int smi_sig = 0;
+static int smi_port;
+static int smi_cmd;
+static unsigned int smi_sig;
 
 /* info about the processor */
-static unsigned int speedstep_processor = 0;
+static unsigned int speedstep_processor;
 
 /*
  * There are only two frequency states for each processor. Values
@@ -56,12 +56,13 @@ static struct cpufreq_frequency_table sp
  * of DMA activity going on? */
 #define SMI_TRIES 5
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-smi", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+		"speedstep-smi", msg)
 
 /**
  * speedstep_smi_ownership
  */
-static int speedstep_smi_ownership (void)
+static int speedstep_smi_ownership(void)
 {
 	u32 command, result, magic, dummy;
 	u32 function = GET_SPEEDSTEP_OWNER;
@@ -70,16 +71,18 @@ static int speedstep_smi_ownership (void
 	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
 	magic = virt_to_phys(magic_data);
 
-	dprintk("trying to obtain ownership with command %x at port %x\n", command, smi_port);
+	dprintk("trying to obtain ownership with command %x at port %x\n",
+			command, smi_port);
 
 	__asm__ __volatile__(
 		"push %%ebp\n"
 		"out %%al, (%%dx)\n"
 		"pop %%ebp\n"
-		: "=D" (result), "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
-			"=S" (dummy)
+		: "=D" (result),
+		  "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+		  "=S" (dummy)
 		: "a" (command), "b" (function), "c" (0), "d" (smi_port),
-			"D" (0), "S" (magic)
+		  "D" (0), "S" (magic)
 		: "memory"
 	);
 
@@ -97,10 +100,10 @@ static int speedstep_smi_ownership (void
  * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
  * shows that the latter occurs if !(ist_info.event & 0xFFFF).
  */
-static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
+static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high)
 {
 	u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
-	u32 state=0;
+	u32 state = 0;
 	u32 function = GET_SPEEDSTEP_FREQS;
 
 	if (!(ist_info.event & 0xFFFF)) {
@@ -110,17 +113,25 @@ static int speedstep_smi_get_freqs (unsi
 
 	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
 
-	dprintk("trying to determine frequencies with command %x at port %x\n", command, smi_port);
+	dprintk("trying to determine frequencies with command %x at port %x\n",
+			command, smi_port);
 
 	__asm__ __volatile__(
 		"push %%ebp\n"
 		"out %%al, (%%dx)\n"
 		"pop %%ebp"
-		: "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi), "=S" (dummy)
-		: "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
+		: "=a" (result),
+		  "=b" (high_mhz),
+		  "=c" (low_mhz),
+		  "=d" (state), "=D" (edi), "=S" (dummy)
+		: "a" (command),
+		  "b" (function),
+		  "c" (state),
+		  "d" (smi_port), "S" (0), "D" (0)
 	);
 
-	dprintk("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz);
+	dprintk("result %x, low_freq %u, high_freq %u\n",
+			result, low_mhz, high_mhz);
 
 	/* abort if results are obviously incorrect... */
 	if ((high_mhz + low_mhz) < 600)
@@ -137,26 +148,30 @@ static int speedstep_smi_get_freqs (unsi
  * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
  *
  */
-static int speedstep_get_state (void)
+static int speedstep_get_state(void)
 {
-	u32 function=GET_SPEEDSTEP_STATE;
+	u32 function = GET_SPEEDSTEP_STATE;
 	u32 result, state, edi, command, dummy;
 
 	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
 
-	dprintk("trying to determine current setting with command %x at port %x\n", command, smi_port);
+	dprintk("trying to determine current setting with command %x "
+		"at port %x\n", command, smi_port);
 
 	__asm__ __volatile__(
 		"push %%ebp\n"
 		"out %%al, (%%dx)\n"
 		"pop %%ebp\n"
-		: "=a" (result), "=b" (state), "=D" (edi), "=c" (dummy), "=d" (dummy), "=S" (dummy)
-		: "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0), "D" (0)
+		: "=a" (result),
+		  "=b" (state), "=D" (edi),
+		  "=c" (dummy), "=d" (dummy), "=S" (dummy)
+		: "a" (command), "b" (function), "c" (0),
+		  "d" (smi_port), "S" (0), "D" (0)
 	);
 
 	dprintk("state is %x, result is %x\n", state, result);
 
-	return (state & 1);
+	return state & 1;
 }
 
 
@@ -165,11 +180,11 @@ static int speedstep_get_state (void)
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
  *
  */
-static void speedstep_set_state (unsigned int state)
+static void speedstep_set_state(unsigned int state)
 {
 	unsigned int result = 0, command, new_state, dummy;
 	unsigned long flags;
-	unsigned int function=SET_SPEEDSTEP_STATE;
+	unsigned int function = SET_SPEEDSTEP_STATE;
 	unsigned int retry = 0;
 
 	if (state > 0x1)
@@ -180,11 +195,14 @@ static void speedstep_set_state (unsigne
 
 	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
 
-	dprintk("trying to set frequency to state %u with command %x at port %x\n", state, command, smi_port);
+	dprintk("trying to set frequency to state %u "
+		"with command %x at port %x\n",
+		state, command, smi_port);
 
 	do {
 		if (retry) {
-			dprintk("retry %u, previous result %u, waiting...\n", retry, result);
+			dprintk("retry %u, previous result %u, waiting...\n",
+					retry, result);
 			mdelay(retry * 50);
 		}
 		retry++;
@@ -192,20 +210,26 @@ static void speedstep_set_state (unsigne
 			"push %%ebp\n"
 			"out %%al, (%%dx)\n"
 			"pop %%ebp"
-			: "=b" (new_state), "=D" (result), "=c" (dummy), "=a" (dummy),
-				"=d" (dummy), "=S" (dummy)
-			: "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
+			: "=b" (new_state), "=D" (result),
+			  "=c" (dummy), "=a" (dummy),
+			  "=d" (dummy), "=S" (dummy)
+			: "a" (command), "b" (function), "c" (state),
+			  "d" (smi_port), "S" (0), "D" (0)
 			);
 	} while ((new_state != state) && (retry <= SMI_TRIES));
 
 	/* enable IRQs */
 	local_irq_restore(flags);
 
-	if (new_state == state) {
-		dprintk("change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result);
-	} else {
-		printk(KERN_ERR "cpufreq: change to state %u failed with new_state %u and result %u\n", state, new_state, result);
-	}
+	if (new_state == state)
+		dprintk("change to %u MHz succeeded after %u tries "
+			"with result %u\n",
+			(speedstep_freqs[new_state].frequency / 1000),
+			retry, result);
+	else
+		printk(KERN_ERR "cpufreq: change to state %u "
+			"failed with new_state %u and result %u\n",
+			state, new_state, result);
 
 	return;
 }
@@ -219,13 +243,14 @@ static void speedstep_set_state (unsigne
  *
  * Sets a new CPUFreq policy/freq.
  */
-static int speedstep_target (struct cpufreq_policy *policy,
+static int speedstep_target(struct cpufreq_policy *policy,
 			unsigned int target_freq, unsigned int relation)
 {
 	unsigned int newstate = 0;
 	struct cpufreq_freqs freqs;
 
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
+	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+				target_freq, relation, &newstate))
 		return -EINVAL;
 
 	freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
@@ -250,7 +275,7 @@ static int speedstep_target (struct cpuf
  * Limit must be within speedstep_low_freq and speedstep_high_freq, with
  * at least one border included.
  */
-static int speedstep_verify (struct cpufreq_policy *policy)
+static int speedstep_verify(struct cpufreq_policy *policy)
 {
 	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
 }
@@ -259,7 +284,8 @@ static int speedstep_verify (struct cpuf
 static int speedstep_cpu_init(struct cpufreq_policy *policy)
 {
 	int result;
-	unsigned int speed,state;
+	unsigned int speed, state;
+	unsigned int *low, *high;
 
 	/* capability check */
 	if (policy->cpu != 0)
@@ -272,19 +298,23 @@ static int speedstep_cpu_init(struct cpu
 	}
 
 	/* detect low and high frequency */
-	result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency,
-				&speedstep_freqs[SPEEDSTEP_HIGH].frequency);
+	low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
+	high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
+
+	result = speedstep_smi_get_freqs(low, high);
 	if (result) {
-		/* fall back to speedstep_lib.c dection mechanism: try both states out */
-		dprintk("could not detect low and high frequencies by SMI call.\n");
+		/* fall back to speedstep_lib.c dection mechanism:
+		 * try both states out */
+		dprintk("could not detect low and high frequencies "
+				"by SMI call.\n");
 		result = speedstep_get_freqs(speedstep_processor,
-				&speedstep_freqs[SPEEDSTEP_LOW].frequency,
-				&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				low, high,
 				NULL,
 				&speedstep_set_state);
 
 		if (result) {
-			dprintk("could not detect two different speeds -- aborting.\n");
+			dprintk("could not detect two different speeds"
+					" -- aborting.\n");
 			return result;
 		} else
 			dprintk("workaround worked.\n");
@@ -295,7 +325,8 @@ static int speedstep_cpu_init(struct cpu
 	speed = speedstep_freqs[state].frequency;
 
 	dprintk("currently at %s speed setting - %i MHz\n",
-		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+		? "low" : "high",
 		(speed / 1000));
 
 	/* cpuinfo and default policy values */
@@ -304,7 +335,7 @@ static int speedstep_cpu_init(struct cpu
 
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
 	if (result)
-		return (result);
+		return result;
 
 	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
 
@@ -321,7 +352,7 @@ static unsigned int speedstep_get(unsign
 {
 	if (cpu)
 		return -ENODEV;
-	return speedstep_get_processor_frequency(speedstep_processor);
+	return speedstep_get_frequency(speedstep_processor);
 }
 
 
@@ -335,7 +366,7 @@ static int speedstep_resume(struct cpufr
 	return result;
 }
 
-static struct freq_attr* speedstep_attr[] = {
+static struct freq_attr *speedstep_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
 };
@@ -364,21 +395,23 @@ static int __init speedstep_init(void)
 	speedstep_processor = speedstep_detect_processor();
 
 	switch (speedstep_processor) {
-	case SPEEDSTEP_PROCESSOR_PIII_T:
-	case SPEEDSTEP_PROCESSOR_PIII_C:
-	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
+	case SPEEDSTEP_CPU_PIII_T:
+	case SPEEDSTEP_CPU_PIII_C:
+	case SPEEDSTEP_CPU_PIII_C_EARLY:
 		break;
 	default:
 		speedstep_processor = 0;
 	}
 
 	if (!speedstep_processor) {
-		dprintk ("No supported Intel CPU detected.\n");
+		dprintk("No supported Intel CPU detected.\n");
 		return -ENODEV;
 	}
 
-	dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n",
-		ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level);
+	dprintk("signature:0x%.8lx, command:0x%.8lx, "
+		"event:0x%.8lx, perf_level:0x%.8lx.\n",
+		ist_info.signature, ist_info.command,
+		ist_info.event, ist_info.perf_level);
 
 	/* Error if no IST-SMI BIOS or no PARM
 		 sig= 'ISGE' aka 'Intel Speedstep Gate E' */
@@ -416,17 +449,20 @@ static void __exit speedstep_exit(void)
 	cpufreq_unregister_driver(&speedstep_driver);
 }
 
-module_param(smi_port,  int, 0444);
-module_param(smi_cmd,   int, 0444);
-module_param(smi_sig,  uint, 0444);
+module_param(smi_port, int, 0444);
+module_param(smi_cmd,  int, 0444);
+module_param(smi_sig, uint, 0444);
 
-MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value -- Intel's default setting is 0xb2");
-MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value -- Intel's default setting is 0x82");
-MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the SMI interface.");
+MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value "
+		"-- Intel's default setting is 0xb2");
+MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value "
+		"-- Intel's default setting is 0x82");
+MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the "
+		"SMI interface.");
 
-MODULE_AUTHOR ("Hiroshi Miura");
-MODULE_DESCRIPTION ("Speedstep driver for IST applet SMI interface.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Hiroshi Miura");
+MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
+MODULE_LICENSE("GPL");
 
 module_init(speedstep_init);
 module_exit(speedstep_exit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpu.h linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpu.h
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cpu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpu.h	2009-06-09 23:05:27.000000000 -0400
@@ -3,33 +3,34 @@
 #define ARCH_X86_CPU_H
 
 struct cpu_model_info {
-	int vendor;
-	int family;
-	char *model_names[16];
+	int		vendor;
+	int		family;
+	const char	*model_names[16];
 };
 
 /* attempt to consolidate cpu attributes */
 struct cpu_dev {
-	char	* c_vendor;
+	const char	*c_vendor;
 
 	/* some have two possibilities for cpuid string */
-	char	* c_ident[2];	
+	const char	*c_ident[2];
 
 	struct		cpu_model_info c_models[4];
 
-	void            (*c_early_init)(struct cpuinfo_x86 *c);
-	void		(*c_init)(struct cpuinfo_x86 * c);
-	void		(*c_identify)(struct cpuinfo_x86 * c);
-	unsigned int	(*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size);
-	int	c_x86_vendor;
+	void            (*c_early_init)(struct cpuinfo_x86 *);
+	void		(*c_init)(struct cpuinfo_x86 *);
+	void		(*c_identify)(struct cpuinfo_x86 *);
+	unsigned int	(*c_size_cache)(struct cpuinfo_x86 *, unsigned int);
+	int		c_x86_vendor;
 };
 
 #define cpu_dev_register(cpu_devX) \
-	static struct cpu_dev *__cpu_dev_##cpu_devX __used \
+	static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \
 	__attribute__((__section__(".x86_cpu_dev.init"))) = \
 	&cpu_devX;
 
-extern struct cpu_dev *__x86_cpu_dev_start[], *__x86_cpu_dev_end[];
+extern const struct cpu_dev *const __x86_cpu_dev_start[],
+			    *const __x86_cpu_dev_end[];
 
 extern void display_cacheinfo(struct cpuinfo_x86 *c);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cyrix.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cyrix.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/cyrix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cyrix.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,23 +61,23 @@ static void __cpuinit do_cyrix_devid(uns
  */
 static unsigned char Cx86_dir0_msb __cpuinitdata = 0;
 
-static char Cx86_model[][9] __cpuinitdata = {
+static const char __cpuinitconst Cx86_model[][9] = {
 	"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
 	"M II ", "Unknown"
 };
-static char Cx486_name[][5] __cpuinitdata = {
+static const char __cpuinitconst Cx486_name[][5] = {
 	"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
 	"SRx2", "DRx2"
 };
-static char Cx486S_name[][4] __cpuinitdata = {
+static const char __cpuinitconst Cx486S_name[][4] = {
 	"S", "S2", "Se", "S2e"
 };
-static char Cx486D_name[][4] __cpuinitdata = {
+static const char __cpuinitconst Cx486D_name[][4] = {
 	"DX", "DX2", "?", "?", "?", "DX4"
 };
 static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock";
-static char cyrix_model_mult1[] __cpuinitdata = "12??43";
-static char cyrix_model_mult2[] __cpuinitdata = "12233445";
+static const char __cpuinitconst cyrix_model_mult1[] = "12??43";
+static const char __cpuinitconst cyrix_model_mult2[] = "12233445";
 
 /*
  * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old
@@ -435,7 +435,7 @@ static void __cpuinit cyrix_identify(str
 	}
 }
 
-static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst cyrix_cpu_dev = {
 	.c_vendor	= "Cyrix",
 	.c_ident	= { "CyrixInstead" },
 	.c_early_init	= early_init_cyrix,
@@ -446,7 +446,7 @@ static struct cpu_dev cyrix_cpu_dev __cp
 
 cpu_dev_register(cyrix_cpu_dev);
 
-static struct cpu_dev nsc_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst nsc_cpu_dev = {
 	.c_vendor	= "NSC",
 	.c_ident	= { "Geode by NSC" },
 	.c_init		= init_nsc,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/intel.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/intel.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/intel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/intel.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/smp.h>
+#include <linux/sched.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
 
@@ -13,6 +14,7 @@
 #include <asm/uaccess.h>
 #include <asm/ds.h>
 #include <asm/bugs.h>
+#include <asm/cpu.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/topology.h>
@@ -24,7 +26,6 @@
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/mpspec.h>
 #include <asm/apic.h>
-#include <mach_apic.h>
 #endif
 
 static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
@@ -54,15 +55,37 @@ static void __cpuinit early_init_intel(s
 		c->x86_cache_alignment = 128;
 #endif
 
+	/* CPUID workaround for 0F33/0F34 CPU */
+	if (c->x86 == 0xF && c->x86_model == 0x3
+	    && (c->x86_mask == 0x3 || c->x86_mask == 0x4))
+		c->x86_phys_bits = 36;
+
 	/*
 	 * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
-	 * with P/T states and does not stop in deep C-states
+	 * with P/T states and does not stop in deep C-states.
+	 *
+	 * It is also reliable across cores and sockets. (but not across
+	 * cabinets - we turn it off in that case explicitly.)
 	 */
 	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;
 	}
 
+	/*
+	 * There is a known erratum on Pentium III and Core Solo
+	 * and Core Duo CPUs.
+	 * " Page with PAT set to WC while associated MTRR is UC
+	 *   may consolidate to UC "
+	 * Because of this erratum, it is better to stick with
+	 * setting WC in MTRR rather than using PAT on these CPUs.
+	 *
+	 * Enable PAT WC only on P4, Core 2 or later CPUs.
+	 */
+	if (c->x86 == 6 && c->x86_model < 15)
+		clear_cpu_cap(c, X86_FEATURE_PAT);
 }
 
 #ifdef CONFIG_X86_32
@@ -99,6 +122,28 @@ static void __cpuinit trap_init_f00f_bug
 }
 #endif
 
+static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+	/* calling is from identify_secondary_cpu() ? */
+	if (c->cpu_index == boot_cpu_id)
+		return;
+
+	/*
+	 * Mask B, Pentium, but not Pentium MMX
+	 */
+	if (c->x86 == 5 &&
+	    c->x86_mask >= 1 && c->x86_mask <= 4 &&
+	    c->x86_model <= 3) {
+		/*
+		 * Remember we have B step Pentia with bugs
+		 */
+		WARN_ONCE(1, "WARNING: SMP operation may be unreliable"
+				    "with B stepping processors.\n");
+	}
+#endif
+}
+
 static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
 {
 	unsigned long lo, hi;
@@ -135,10 +180,10 @@ static void __cpuinit intel_workarounds(
 	 */
 	if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
 		rdmsr(MSR_IA32_MISC_ENABLE, lo, hi);
-		if ((lo & (1<<9)) == 0) {
+		if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) {
 			printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
 			printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
-			lo |= (1<<9);	/* Disable hw prefetching */
+			lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE;
 			wrmsr (MSR_IA32_MISC_ENABLE, lo, hi);
 		}
 	}
@@ -175,6 +220,8 @@ static void __cpuinit intel_workarounds(
 #ifdef CONFIG_X86_NUMAQ
 	numaq_tsc_disable();
 #endif
+
+	intel_smp_check(c);
 }
 #else
 static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
@@ -374,7 +421,7 @@ static unsigned int __cpuinit intel_size
 }
 #endif
 
-static struct cpu_dev intel_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst intel_cpu_dev = {
 	.c_vendor	= "Intel",
 	.c_ident	= { "GenuineIntel" },
 #ifdef CONFIG_X86_32
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/intel_cacheinfo.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ struct _cache_table
 };
 
 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __cpuinitdata =
+static const struct _cache_table __cpuinitconst cache_table[] =
 {
 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x08, LVL_1_INST, 16 },	/* 4-way set assoc, 32 byte line size */
@@ -147,10 +147,19 @@ struct _cpuid4_info {
 	union _cpuid4_leaf_ecx ecx;
 	unsigned long size;
 	unsigned long can_disable;
-	cpumask_t shared_cpu_map;	/* future?: only cpus/node is needed */
+	DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 };
 
-#ifdef CONFIG_PCI
+/* subset of above _cpuid4_info w/o shared_cpu_map */
+struct _cpuid4_info_regs {
+	union _cpuid4_leaf_eax eax;
+	union _cpuid4_leaf_ebx ebx;
+	union _cpuid4_leaf_ecx ecx;
+	unsigned long size;
+	unsigned long can_disable;
+};
+
+#if defined(CONFIG_PCI) && defined(CONFIG_SYSFS)
 static struct pci_device_id k8_nb_id[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
@@ -197,15 +206,15 @@ union l3_cache {
 	unsigned val;
 };
 
-static unsigned short assocs[] __cpuinitdata = {
+static const unsigned short __cpuinitconst assocs[] = {
 	[1] = 1, [2] = 2, [4] = 4, [6] = 8,
 	[8] = 16, [0xa] = 32, [0xb] = 48,
 	[0xc] = 64,
 	[0xf] = 0xffff // ??
 };
 
-static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
-static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
+static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
+static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
 
 static void __cpuinit
 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
@@ -278,7 +287,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_
 }
 
 static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
+amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
 	if (index < 3)
 		return;
@@ -286,7 +295,8 @@ amd_check_l3_disable(int index, struct _
 }
 
 static int
-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+__cpuinit cpuid4_cache_lookup_regs(int index,
+				   struct _cpuid4_info_regs *this_leaf)
 {
 	union _cpuid4_leaf_eax 	eax;
 	union _cpuid4_leaf_ebx 	ebx;
@@ -353,11 +363,10 @@ unsigned int __cpuinit init_intel_cachei
 		 * parameters cpuid leaf to find the cache details
 		 */
 		for (i = 0; i < num_cache_leaves; i++) {
-			struct _cpuid4_info this_leaf;
-
+			struct _cpuid4_info_regs this_leaf;
 			int retval;
 
-			retval = cpuid4_cache_lookup(i, &this_leaf);
+			retval = cpuid4_cache_lookup_regs(i, &this_leaf);
 			if (retval >= 0) {
 				switch(this_leaf.eax.split.level) {
 				    case 1:
@@ -490,6 +499,8 @@ unsigned int __cpuinit init_intel_cachei
 	return l2;
 }
 
+#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]))
@@ -506,17 +517,20 @@ static void __cpuinit cache_shared_cpu_m
 	num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
 
 	if (num_threads_sharing == 1)
-		cpu_set(cpu, this_leaf->shared_cpu_map);
+		cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
 	else {
 		index_msb = get_count_order(num_threads_sharing);
 
 		for_each_online_cpu(i) {
 			if (cpu_data(i).apicid >> index_msb ==
 			    c->apicid >> index_msb) {
-				cpu_set(i, this_leaf->shared_cpu_map);
+				cpumask_set_cpu(i,
+					to_cpumask(this_leaf->shared_cpu_map));
 				if (i != cpu && per_cpu(cpuid4_info, i))  {
-					sibling_leaf = CPUID4_INFO_IDX(i, index);
-					cpu_set(cpu, sibling_leaf->shared_cpu_map);
+					sibling_leaf =
+						CPUID4_INFO_IDX(i, index);
+					cpumask_set_cpu(cpu, to_cpumask(
+						sibling_leaf->shared_cpu_map));
 				}
 			}
 		}
@@ -528,9 +542,10 @@ static void __cpuinit cache_remove_share
 	int sibling;
 
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
-	for_each_cpu_mask_nr(sibling, this_leaf->shared_cpu_map) {
+	for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
 		sibling_leaf = CPUID4_INFO_IDX(sibling, index);
-		cpu_clear(cpu, sibling_leaf->shared_cpu_map);
+		cpumask_clear_cpu(cpu,
+				  to_cpumask(sibling_leaf->shared_cpu_map));
 	}
 }
 #else
@@ -549,6 +564,15 @@ static void __cpuinit free_cache_attribu
 	per_cpu(cpuid4_info, cpu) = NULL;
 }
 
+static int
+__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+	struct _cpuid4_info_regs *leaf_regs =
+		(struct _cpuid4_info_regs *)this_leaf;
+
+	return cpuid4_cache_lookup_regs(index, leaf_regs);
+}
+
 static void __cpuinit get_cpu_leaves(void *_retval)
 {
 	int j, *retval = _retval, cpu = smp_processor_id();
@@ -590,8 +614,6 @@ static int __cpuinit detect_cache_attrib
 	return retval;
 }
 
-#ifdef CONFIG_SYSFS
-
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 
@@ -635,8 +657,9 @@ static ssize_t show_shared_cpu_map_func(
 	int n = 0;
 
 	if (len > 1) {
-		cpumask_t *mask = &this_leaf->shared_cpu_map;
+		const struct cpumask *mask;
 
+		mask = to_cpumask(this_leaf->shared_cpu_map);
 		n = type?
 			cpulist_scnprintf(buf, len-2, mask) :
 			cpumask_scnprintf(buf, len-2, mask);
@@ -699,7 +722,8 @@ static struct pci_dev *get_k8_northbridg
 
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
 {
-	int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
+	const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
+	int node = cpu_to_node(cpumask_first(mask));
 	struct pci_dev *dev = NULL;
 	ssize_t ret = 0;
 	int i;
@@ -733,7 +757,8 @@ static ssize_t
 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
 		    size_t count)
 {
-	int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
+	const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
+	int node = cpu_to_node(cpumask_first(mask));
 	struct pci_dev *dev = NULL;
 	unsigned int ret, index, val;
 
@@ -878,7 +903,7 @@ err_out:
 	return -ENOMEM;
 }
 
-static cpumask_t cache_dev_map = CPU_MASK_NONE;
+static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
 
 /* Add/Remove cache interface for CPU device */
 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
@@ -918,7 +943,7 @@ static int __cpuinit cache_add_dev(struc
 		}
 		kobject_uevent(&(this_object->kobj), KOBJ_ADD);
 	}
-	cpu_set(cpu, cache_dev_map);
+	cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
 
 	kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
 	return 0;
@@ -931,9 +956,9 @@ static void __cpuinit cache_remove_dev(s
 
 	if (per_cpu(cpuid4_info, cpu) == NULL)
 		return;
-	if (!cpu_isset(cpu, cache_dev_map))
+	if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
 		return;
-	cpu_clear(cpu, cache_dev_map);
+	cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
 
 	for (i = 0; i < num_cache_leaves; i++)
 		kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,11 +14,12 @@ obj-y			+= vmware.o hypervisor.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
-obj-$(CONFIG_CPU_SUP_CENTAUR_32)	+= centaur.o
-obj-$(CONFIG_CPU_SUP_CENTAUR_64)	+= centaur_64.o
+obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,3 +4,4 @@ obj-$(CONFIG_X86_32)		+= k7.o p4.o p5.o
 obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel_64.o
 obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd_64.o
 obj-$(CONFIG_X86_MCE_NONFATAL)	+= non-fatal.o
+obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,20 +60,6 @@ void mcheck_init(struct cpuinfo_x86 *c)
 	}
 }
 
-static unsigned long old_cr4 __initdata;
-
-void __init stop_mce(void)
-{
-	old_cr4 = read_cr4();
-	clear_in_cr4(X86_CR4_MCE);
-}
-
-void __init restart_mce(void)
-{
-	if (old_cr4 & X86_CR4_MCE)
-		set_in_cr4(X86_CR4_MCE);
-}
-
 static int __init mcheck_disable(char *str)
 {
 	mce_disabled = 1;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,8 @@
  * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs.
  * Rest from unknown author(s).
  * 2004 Andi Kleen. Rewrote most of it.
+ * Copyright 2008 Intel Corporation
+ * Author: Andi Kleen
  */
 
 #include <linux/init.h>
@@ -24,6 +26,9 @@
 #include <linux/ctype.h>
 #include <linux/kmod.h>
 #include <linux/kdebug.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include <linux/ratelimit.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/mce.h>
@@ -32,7 +37,6 @@
 #include <asm/idle.h>
 
 #define MISC_MCELOG_MINOR 227
-#define NR_SYSFS_BANKS 6
 
 atomic_t mce_entry;
 
@@ -47,7 +51,7 @@ static int mce_dont_init;
  */
 static int tolerant = 1;
 static int banks;
-static unsigned long bank[NR_SYSFS_BANKS] = { [0 ... NR_SYSFS_BANKS-1] = ~0UL };
+static u64 *bank;
 static unsigned long notify_user;
 static int rip_msr;
 static int mce_bootlog = -1;
@@ -58,6 +62,19 @@ static char *trigger_argv[2] = { trigger
 
 static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
 
+/* MCA banks polled by the period polling timer for corrected events */
+DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
+	[0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
+};
+
+/* Do initial initialization of a struct mce */
+void mce_setup(struct mce *m)
+{
+	memset(m, 0, sizeof(struct mce));
+	m->cpu = smp_processor_id();
+	rdtscll(m->tsc);
+}
+
 /*
  * Lockless MCE logging infrastructure.
  * This avoids deadlocks on printk locks without having to break locks. Also
@@ -119,11 +136,11 @@ static void print_mce(struct mce *m)
 			print_symbol("{%s}", m->ip);
 		printk("\n");
 	}
-	printk(KERN_EMERG "TSC %Lx ", m->tsc);
+	printk(KERN_EMERG "TSC %llx ", m->tsc);
 	if (m->addr)
-		printk("ADDR %Lx ", m->addr);
+		printk("ADDR %llx ", m->addr);
 	if (m->misc)
-		printk("MISC %Lx ", m->misc);
+		printk("MISC %llx ", m->misc);
 	printk("\n");
 	printk(KERN_EMERG "This is not a software problem!\n");
 	printk(KERN_EMERG "Run through mcelog --ascii to decode "
@@ -149,8 +166,10 @@ static void mce_panic(char *msg, struct
 	panic(msg);
 }
 
-static int mce_available(struct cpuinfo_x86 *c)
+int mce_available(struct cpuinfo_x86 *c)
 {
+	if (mce_dont_init)
+		return 0;
 	return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
 }
 
@@ -172,7 +191,78 @@ static inline void mce_get_rip(struct mc
 }
 
 /*
- * The actual machine check handler
+ * Poll for corrected events or events that happened before reset.
+ * Those are just logged through /dev/mcelog.
+ *
+ * This is executed in standard interrupt context.
+ */
+void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
+{
+	struct mce m;
+	int i;
+
+	mce_setup(&m);
+
+	rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
+	for (i = 0; i < banks; i++) {
+		if (!bank[i] || !test_bit(i, *b))
+			continue;
+
+		m.misc = 0;
+		m.addr = 0;
+		m.bank = i;
+		m.tsc = 0;
+
+		barrier();
+		rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status);
+		if (!(m.status & MCI_STATUS_VAL))
+			continue;
+
+		/*
+		 * Uncorrected events are handled by the exception handler
+		 * when it is enabled. But when the exception is disabled log
+		 * everything.
+		 *
+		 * TBD do the same check for MCI_STATUS_EN here?
+		 */
+		if ((m.status & MCI_STATUS_UC) && !(flags & MCP_UC))
+			continue;
+
+		if (m.status & MCI_STATUS_MISCV)
+			rdmsrl(MSR_IA32_MC0_MISC + i*4, m.misc);
+		if (m.status & MCI_STATUS_ADDRV)
+			rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
+
+		if (!(flags & MCP_TIMESTAMP))
+			m.tsc = 0;
+		/*
+		 * Don't get the IP here because it's unlikely to
+		 * have anything to do with the actual error location.
+		 */
+		if (!(flags & MCP_DONTLOG)) {
+			mce_log(&m);
+			add_taint(TAINT_MACHINE_CHECK);
+		}
+
+		/*
+		 * Clear state for this bank.
+		 */
+		wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+	}
+
+	/*
+	 * Don't clear MCG_STATUS here because it's only defined for
+	 * exceptions.
+	 */
+}
+
+/*
+ * The actual machine check handler. This only handles real
+ * exceptions when something got corrupted coming in through int 18.
+ *
+ * This is executed in NMI context not subject to normal locking rules. This
+ * implies that most kernel services cannot be safely used. Don't even
+ * think about putting a printk in there!
  */
 void do_machine_check(struct pt_regs * regs, long error_code)
 {
@@ -190,17 +280,18 @@ void do_machine_check(struct pt_regs * r
 	 * error.
 	 */
 	int kill_it = 0;
+	DECLARE_BITMAP(toclear, MAX_NR_BANKS);
 
 	atomic_inc(&mce_entry);
 
-	if ((regs
-	     && notify_die(DIE_NMI, "machine check", regs, error_code,
+	if (notify_die(DIE_NMI, "machine check", regs, error_code,
 			   18, SIGKILL) == NOTIFY_STOP)
-	    || !banks)
+		goto out2;
+	if (!banks)
 		goto out2;
 
-	memset(&m, 0, sizeof(struct mce));
-	m.cpu = smp_processor_id();
+	mce_setup(&m);
+
 	rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
 	/* if the restart IP is not valid, we're done for */
 	if (!(m.mcgstatus & MCG_STATUS_RIPV))
@@ -210,18 +301,32 @@ void do_machine_check(struct pt_regs * r
 	barrier();
 
 	for (i = 0; i < banks; i++) {
-		if (i < NR_SYSFS_BANKS && !bank[i])
+		__clear_bit(i, toclear);
+		if (!bank[i])
 			continue;
 
 		m.misc = 0;
 		m.addr = 0;
 		m.bank = i;
-		m.tsc = 0;
 
 		rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status);
 		if ((m.status & MCI_STATUS_VAL) == 0)
 			continue;
 
+		/*
+		 * Non uncorrected errors are handled by machine_check_poll
+		 * Leave them alone.
+		 */
+		if ((m.status & MCI_STATUS_UC) == 0)
+			continue;
+
+		/*
+		 * Set taint even when machine check was not enabled.
+		 */
+		add_taint(TAINT_MACHINE_CHECK);
+
+		__set_bit(i, toclear);
+
 		if (m.status & MCI_STATUS_EN) {
 			/* if PCC was set, there's no way out */
 			no_way_out |= !!(m.status & MCI_STATUS_PCC);
@@ -235,6 +340,12 @@ void do_machine_check(struct pt_regs * r
 					no_way_out = 1;
 				kill_it = 1;
 			}
+		} else {
+			/*
+			 * Machine check event was not enabled. Clear, but
+			 * ignore.
+			 */
+			continue;
 		}
 
 		if (m.status & MCI_STATUS_MISCV)
@@ -243,10 +354,7 @@ void do_machine_check(struct pt_regs * r
 			rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
 
 		mce_get_rip(&m, regs);
-		if (error_code >= 0)
-			rdtscll(m.tsc);
-		if (error_code != -2)
-			mce_log(&m);
+		mce_log(&m);
 
 		/* Did this bank cause the exception? */
 		/* Assume that the bank with uncorrectable errors did it,
@@ -255,14 +363,8 @@ void do_machine_check(struct pt_regs * r
 			panicm = m;
 			panicm_found = 1;
 		}
-
-		add_taint(TAINT_MACHINE_CHECK);
 	}
 
-	/* Never do anything final in the polling timer */
-	if (!regs)
-		goto out;
-
 	/* If we didn't find an uncorrectable error, pick
 	   the last one (shouldn't happen, just being safe). */
 	if (!panicm_found)
@@ -309,10 +411,11 @@ void do_machine_check(struct pt_regs * r
 	/* notify userspace ASAP */
 	set_thread_flag(TIF_MCE_NOTIFY);
 
- out:
 	/* the last thing we do is clear state */
-	for (i = 0; i < banks; i++)
-		wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+	for (i = 0; i < banks; i++) {
+		if (test_bit(i, toclear))
+			wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+	}
 	wrmsrl(MSR_IA32_MCG_STATUS, 0);
  out2:
 	atomic_dec(&mce_entry);
@@ -332,15 +435,13 @@ void do_machine_check(struct pt_regs * r
  * and historically has been the register value of the
  * MSR_IA32_THERMAL_STATUS (Intel) msr.
  */
-void mce_log_therm_throt_event(unsigned int cpu, __u64 status)
+void mce_log_therm_throt_event(__u64 status)
 {
 	struct mce m;
 
-	memset(&m, 0, sizeof(m));
-	m.cpu = cpu;
+	mce_setup(&m);
 	m.bank = MCE_THERMAL_BANK;
 	m.status = status;
-	rdtscll(m.tsc);
 	mce_log(&m);
 }
 #endif /* CONFIG_X86_MCE_INTEL */
@@ -352,56 +453,67 @@ void mce_log_therm_throt_event(unsigned
  */
 
 static int check_interval = 5 * 60; /* 5 minutes */
-static int next_interval; /* in jiffies */
-static void mcheck_timer(struct work_struct *work);
-static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer);
+static DEFINE_PER_CPU(int, next_interval); /* in jiffies */
+static void mcheck_timer(unsigned long);
+static DEFINE_PER_CPU(struct timer_list, mce_timer);
 
-static void mcheck_check_cpu(void *info)
+static void mcheck_timer(unsigned long data)
 {
-	if (mce_available(&current_cpu_data))
-		do_machine_check(NULL, 0);
-}
+	struct timer_list *t = &per_cpu(mce_timer, data);
+	int *n;
 
-static void mcheck_timer(struct work_struct *work)
-{
-	on_each_cpu(mcheck_check_cpu, NULL, 1);
+	WARN_ON(smp_processor_id() != data);
+
+	if (mce_available(&current_cpu_data))
+		machine_check_poll(MCP_TIMESTAMP,
+				&__get_cpu_var(mce_poll_banks));
 
 	/*
 	 * Alert userspace if needed.  If we logged an MCE, reduce the
 	 * polling interval, otherwise increase the polling interval.
 	 */
+	n = &__get_cpu_var(next_interval);
 	if (mce_notify_user()) {
-		next_interval = max(next_interval/2, HZ/100);
+		*n = max(*n/2, HZ/100);
 	} else {
-		next_interval = min(next_interval * 2,
-				(int)round_jiffies_relative(check_interval*HZ));
+		*n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ));
 	}
 
-	schedule_delayed_work(&mcheck_work, next_interval);
+	t->expires = jiffies + *n;
+	add_timer(t);
 }
 
+static void mce_do_trigger(struct work_struct *work)
+{
+	call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT);
+}
+
+static DECLARE_WORK(mce_trigger_work, mce_do_trigger);
+
 /*
- * This is only called from process context.  This is where we do
- * anything we need to alert userspace about new MCEs.  This is called
- * directly from the poller and also from entry.S and idle, thanks to
- * TIF_MCE_NOTIFY.
+ * Notify the user(s) about new machine check events.
+ * Can be called from interrupt context, but not from machine check/NMI
+ * context.
  */
 int mce_notify_user(void)
 {
+	/* Not more than two messages every minute */
+	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
+
 	clear_thread_flag(TIF_MCE_NOTIFY);
 	if (test_and_clear_bit(0, &notify_user)) {
-		static unsigned long last_print;
-		unsigned long now = jiffies;
-
 		wake_up_interruptible(&mce_wait);
-		if (trigger[0])
-			call_usermodehelper(trigger, trigger_argv, NULL,
-						UMH_NO_WAIT);
 
-		if (time_after_eq(now, last_print + (check_interval*HZ))) {
-			last_print = now;
+		/*
+		 * There is no risk of missing notifications because
+		 * work_pending is always cleared before the function is
+		 * executed.
+		 */
+		if (trigger[0] && !work_pending(&mce_trigger_work))
+			schedule_work(&mce_trigger_work);
+
+		if (__ratelimit(&ratelimit))
 			printk(KERN_INFO "Machine check events logged\n");
-		}
 
 		return 1;
 	}
@@ -425,63 +537,78 @@ static struct notifier_block mce_idle_no
 
 static __init int periodic_mcheck_init(void)
 {
-	next_interval = check_interval * HZ;
-	if (next_interval)
-		schedule_delayed_work(&mcheck_work,
-				      round_jiffies_relative(next_interval));
-	idle_notifier_register(&mce_idle_notifier);
-	return 0;
+       idle_notifier_register(&mce_idle_notifier);
+       return 0;
 }
 __initcall(periodic_mcheck_init);
 
-
 /*
  * Initialize Machine Checks for a CPU.
  */
-static void mce_init(void *dummy)
+static int mce_cap_init(void)
 {
 	u64 cap;
-	int i;
+	unsigned b;
 
 	rdmsrl(MSR_IA32_MCG_CAP, cap);
-	banks = cap & 0xff;
-	if (banks > MCE_EXTENDED_BANK) {
-		banks = MCE_EXTENDED_BANK;
-		printk(KERN_INFO "MCE: warning: using only %d banks\n",
-		       MCE_EXTENDED_BANK);
+	b = cap & 0xff;
+	if (b > MAX_NR_BANKS) {
+		printk(KERN_WARNING
+		       "MCE: Using only %u machine check banks out of %u\n",
+			MAX_NR_BANKS, b);
+		b = MAX_NR_BANKS;
+	}
+
+	/* Don't support asymmetric configurations today */
+	WARN_ON(banks != 0 && b != banks);
+	banks = b;
+	if (!bank) {
+		bank = kmalloc(banks * sizeof(u64), GFP_KERNEL);
+		if (!bank)
+			return -ENOMEM;
+		memset(bank, 0xff, banks * sizeof(u64));
 	}
+
 	/* Use accurate RIP reporting if available. */
 	if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9)
 		rip_msr = MSR_IA32_MCG_EIP;
 
-	/* Log the machine checks left over from the previous reset.
-	   This also clears all registers */
-	do_machine_check(NULL, mce_bootlog ? -1 : -2);
+	return 0;
+}
+
+static void mce_init(void *dummy)
+{
+	u64 cap;
+	int i;
+	mce_banks_t all_banks;
+
+	/*
+	 * Log the machine checks left over from the previous reset.
+	 */
+	bitmap_fill(all_banks, MAX_NR_BANKS);
+	machine_check_poll(MCP_UC|(!mce_bootlog ? MCP_DONTLOG : 0), &all_banks);
 
 	set_in_cr4(X86_CR4_MCE);
 
+	rdmsrl(MSR_IA32_MCG_CAP, cap);
 	if (cap & MCG_CTL_P)
 		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
 
 	for (i = 0; i < banks; i++) {
-		if (i < NR_SYSFS_BANKS)
-			wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
-		else
-			wrmsrl(MSR_IA32_MC0_CTL+4*i, ~0UL);
-
+		wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
 		wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
 	}
 }
 
 /* Add per CPU specific workarounds here */
-static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
+static void mce_cpu_quirks(struct cpuinfo_x86 *c)
 {
 	/* This should be disabled by the BIOS, but isn't always */
 	if (c->x86_vendor == X86_VENDOR_AMD) {
-		if(c->x86 == 15)
+		if (c->x86 == 15 && banks > 4)
 			/* disable GART TBL walk error reporting, which trips off
 			   incorrectly with the IOMMU & 3ware & Cerberus. */
-			clear_bit(10, &bank[4]);
+			clear_bit(10, (unsigned long *)&bank[4]);
 		if(c->x86 <= 17 && mce_bootlog < 0)
 			/* Lots of broken BIOS around that don't clear them
 			   by default and leave crap in there. Don't log. */
@@ -504,20 +631,37 @@ static void mce_cpu_features(struct cpui
 	}
 }
 
+static void mce_init_timer(void)
+{
+	struct timer_list *t = &__get_cpu_var(mce_timer);
+	int *n = &__get_cpu_var(next_interval);
+
+	*n = check_interval * HZ;
+	if (!*n)
+		return;
+	setup_timer(t, mcheck_timer, smp_processor_id());
+	t->expires = round_jiffies(jiffies + *n);
+	add_timer(t);
+}
+
 /*
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off.
  */
 void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
-	mce_cpu_quirks(c);
+	if (!mce_available(c))
+		return;
 
-	if (mce_dont_init ||
-	    !mce_available(c))
+	if (mce_cap_init() < 0) {
+		mce_dont_init = 1;
 		return;
+	}
+	mce_cpu_quirks(c);
 
 	mce_init(NULL);
 	mce_cpu_features(c);
+	mce_init_timer();
 }
 
 /*
@@ -573,7 +717,7 @@ static ssize_t mce_read(struct file *fil
 {
 	unsigned long *cpu_tsc;
 	static DEFINE_MUTEX(mce_read_mutex);
-	unsigned next;
+	unsigned prev, next;
 	char __user *buf = ubuf;
 	int i, err;
 
@@ -592,25 +736,32 @@ static ssize_t mce_read(struct file *fil
 	}
 
 	err = 0;
-	for (i = 0; i < next; i++) {
-		unsigned long start = jiffies;
+	prev = 0;
+	do {
+		for (i = prev; i < next; i++) {
+			unsigned long start = jiffies;
 
-		while (!mcelog.entry[i].finished) {
-			if (time_after_eq(jiffies, start + 2)) {
-				memset(mcelog.entry + i,0, sizeof(struct mce));
-				goto timeout;
+			while (!mcelog.entry[i].finished) {
+				if (time_after_eq(jiffies, start + 2)) {
+					memset(mcelog.entry + i, 0,
+					       sizeof(struct mce));
+					goto timeout;
+				}
+				cpu_relax();
 			}
-			cpu_relax();
+			smp_rmb();
+			err |= copy_to_user(buf, mcelog.entry + i,
+					    sizeof(struct mce));
+			buf += sizeof(struct mce);
+timeout:
+			;
 		}
-		smp_rmb();
-		err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce));
-		buf += sizeof(struct mce);
- timeout:
-		;
-	}
 
-	memset(mcelog.entry, 0, next * sizeof(struct mce));
-	mcelog.next = 0;
+		memset(mcelog.entry + prev, 0,
+		       (next - prev) * sizeof(struct mce));
+		prev = next;
+		next = cmpxchg(&mcelog.next, prev, 0);
+	} while (next != prev);
 
 	synchronize_sched();
 
@@ -680,20 +831,6 @@ static struct miscdevice mce_log_device
 	&mce_chrdev_ops,
 };
 
-static unsigned long old_cr4 __initdata;
-
-void __init stop_mce(void)
-{
-	old_cr4 = read_cr4();
-	clear_in_cr4(X86_CR4_MCE);
-}
-
-void __init restart_mce(void)
-{
-	if (old_cr4 & X86_CR4_MCE)
-		set_in_cr4(X86_CR4_MCE);
-}
-
 /*
  * Old style boot options parsing. Only for compatibility.
  */
@@ -703,8 +840,7 @@ static int __init mcheck_disable(char *s
 	return 1;
 }
 
-/* mce=off disables machine check. Note you can re-enable it later
-   using sysfs.
+/* mce=off disables machine check.
    mce=TOLERANCELEVEL (number, see above)
    mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
    mce=nobootlog Don't log MCEs from before booting. */
@@ -728,6 +864,29 @@ __setup("mce=", mcheck_enable);
  * Sysfs support
  */
 
+/*
+ * Disable machine checks on suspend and shutdown. We can't really handle
+ * them later.
+ */
+static int mce_disable(void)
+{
+	int i;
+
+	for (i = 0; i < banks; i++)
+		wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+	return 0;
+}
+
+static int mce_suspend(struct sys_device *dev, pm_message_t state)
+{
+	return mce_disable();
+}
+
+static int mce_shutdown(struct sys_device *dev)
+{
+	return mce_disable();
+}
+
 /* On resume clear all MCE state. Don't want to see leftovers from the BIOS.
    Only one CPU is active at this time, the others get readded later using
    CPU hotplug. */
@@ -738,20 +897,23 @@ static int mce_resume(struct sys_device
 	return 0;
 }
 
+static void mce_cpu_restart(void *data)
+{
+	del_timer_sync(&__get_cpu_var(mce_timer));
+	if (mce_available(&current_cpu_data))
+		mce_init(NULL);
+	mce_init_timer();
+}
+
 /* Reinit MCEs after user configuration changes */
 static void mce_restart(void)
 {
-	if (next_interval)
-		cancel_delayed_work(&mcheck_work);
-	/* Timer race is harmless here */
-	on_each_cpu(mce_init, NULL, 1);
-	next_interval = check_interval * HZ;
-	if (next_interval)
-		schedule_delayed_work(&mcheck_work,
-				      round_jiffies_relative(next_interval));
+	on_each_cpu(mce_cpu_restart, NULL, 1);
 }
 
 static struct sysdev_class mce_sysclass = {
+	.suspend = mce_suspend,
+	.shutdown = mce_shutdown,
 	.resume = mce_resume,
 	.name = "machinecheck",
 };
@@ -778,16 +940,26 @@ void (*threshold_cpu_callback)(unsigned
 	}								\
 	static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name);
 
-/*
- * TBD should generate these dynamically based on number of available banks.
- * Have only 6 contol banks in /sysfs until then.
- */
-ACCESSOR(bank0ctl,bank[0],mce_restart())
-ACCESSOR(bank1ctl,bank[1],mce_restart())
-ACCESSOR(bank2ctl,bank[2],mce_restart())
-ACCESSOR(bank3ctl,bank[3],mce_restart())
-ACCESSOR(bank4ctl,bank[4],mce_restart())
-ACCESSOR(bank5ctl,bank[5],mce_restart())
+static struct sysdev_attribute *bank_attrs;
+
+static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr,
+			 char *buf)
+{
+	u64 b = bank[attr - bank_attrs];
+	return sprintf(buf, "%llx\n", b);
+}
+
+static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
+			const char *buf, size_t siz)
+{
+	char *end;
+	u64 new = simple_strtoull(buf, &end, 0);
+	if (end == buf)
+		return -EINVAL;
+	bank[attr - bank_attrs] = new;
+	mce_restart();
+	return end-buf;
+}
 
 static ssize_t show_trigger(struct sys_device *s, struct sysdev_attribute *attr,
 				char *buf)
@@ -814,13 +986,11 @@ static SYSDEV_ATTR(trigger, 0644, show_t
 static SYSDEV_INT_ATTR(tolerant, 0644, tolerant);
 ACCESSOR(check_interval,check_interval,mce_restart())
 static struct sysdev_attribute *mce_attributes[] = {
-	&attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl,
-	&attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl,
 	&attr_tolerant.attr, &attr_check_interval, &attr_trigger,
 	NULL
 };
 
-static cpumask_t mce_device_initialized = CPU_MASK_NONE;
+static cpumask_var_t mce_device_initialized;
 
 /* Per cpu sysdev init.  All of the cpus still share the same ctl bank */
 static __cpuinit int mce_create_device(unsigned int cpu)
@@ -845,11 +1015,22 @@ static __cpuinit int mce_create_device(u
 		if (err)
 			goto error;
 	}
-	cpu_set(cpu, mce_device_initialized);
+	for (i = 0; i < banks; i++) {
+		err = sysdev_create_file(&per_cpu(device_mce, cpu),
+					&bank_attrs[i]);
+		if (err)
+			goto error2;
+	}
+	cpumask_set_cpu(cpu, mce_device_initialized);
 
 	return 0;
+error2:
+	while (--i >= 0) {
+		sysdev_remove_file(&per_cpu(device_mce, cpu),
+					&bank_attrs[i]);
+	}
 error:
-	while (i--) {
+	while (--i >= 0) {
 		sysdev_remove_file(&per_cpu(device_mce,cpu),
 				   mce_attributes[i]);
 	}
@@ -862,14 +1043,44 @@ static __cpuinit void mce_remove_device(
 {
 	int i;
 
-	if (!cpu_isset(cpu, mce_device_initialized))
+	if (!cpumask_test_cpu(cpu, mce_device_initialized))
 		return;
 
 	for (i = 0; mce_attributes[i]; i++)
 		sysdev_remove_file(&per_cpu(device_mce,cpu),
 			mce_attributes[i]);
+	for (i = 0; i < banks; i++)
+		sysdev_remove_file(&per_cpu(device_mce, cpu),
+			&bank_attrs[i]);
 	sysdev_unregister(&per_cpu(device_mce,cpu));
-	cpu_clear(cpu, mce_device_initialized);
+	cpumask_clear_cpu(cpu, mce_device_initialized);
+}
+
+/* Make sure there are no machine checks on offlined CPUs. */
+static void mce_disable_cpu(void *h)
+{
+	int i;
+	unsigned long action = *(unsigned long *)h;
+
+	if (!mce_available(&current_cpu_data))
+		return;
+	if (!(action & CPU_TASKS_FROZEN))
+		cmci_clear();
+	for (i = 0; i < banks; i++)
+		wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+}
+
+static void mce_reenable_cpu(void *h)
+{
+	int i;
+	unsigned long action = *(unsigned long *)h;
+
+	if (!mce_available(&current_cpu_data))
+		return;
+	if (!(action & CPU_TASKS_FROZEN))
+		cmci_reenable();
+	for (i = 0; i < banks; i++)
+		wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]);
 }
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -877,6 +1088,7 @@ static int __cpuinit mce_cpu_callback(st
 				      unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
+	struct timer_list *t = &per_cpu(mce_timer, cpu);
 
 	switch (action) {
 	case CPU_ONLINE:
@@ -891,6 +1103,22 @@ static int __cpuinit mce_cpu_callback(st
 			threshold_cpu_callback(action, cpu);
 		mce_remove_device(cpu);
 		break;
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+		del_timer_sync(t);
+		smp_call_function_single(cpu, mce_disable_cpu, &action, 1);
+		break;
+	case CPU_DOWN_FAILED:
+	case CPU_DOWN_FAILED_FROZEN:
+		t->expires = round_jiffies(jiffies +
+						__get_cpu_var(next_interval));
+		add_timer_on(t, cpu);
+		smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
+		break;
+	case CPU_POST_DEAD:
+		/* intentionally ignoring frozen here */
+		cmci_rediscover(cpu);
+		break;
 	}
 	return NOTIFY_OK;
 }
@@ -899,6 +1127,34 @@ static struct notifier_block mce_cpu_not
 	.notifier_call = mce_cpu_callback,
 };
 
+static __init int mce_init_banks(void)
+{
+	int i;
+
+	bank_attrs = kzalloc(sizeof(struct sysdev_attribute) * banks,
+				GFP_KERNEL);
+	if (!bank_attrs)
+		return -ENOMEM;
+
+	for (i = 0; i < banks; i++) {
+		struct sysdev_attribute *a = &bank_attrs[i];
+		a->attr.name = kasprintf(GFP_KERNEL, "bank%d", i);
+		if (!a->attr.name)
+			goto nomem;
+		a->attr.mode = 0644;
+		a->show = show_bank;
+		a->store = set_bank;
+	}
+	return 0;
+
+nomem:
+	while (--i >= 0)
+		kfree(bank_attrs[i].attr.name);
+	kfree(bank_attrs);
+	bank_attrs = NULL;
+	return -ENOMEM;
+}
+
 static __init int mce_init_device(void)
 {
 	int err;
@@ -906,6 +1162,13 @@ static __init int mce_init_device(void)
 
 	if (!mce_available(&boot_cpu_data))
 		return -EIO;
+
+	zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
+
+	err = mce_init_banks();
+	if (err)
+		return err;
+
 	err = sysdev_class_register(&mce_sysclass);
 	if (err)
 		return err;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,7 +67,7 @@ static struct threshold_block threshold_
 struct threshold_bank {
 	struct kobject *kobj;
 	struct threshold_block *blocks;
-	cpumask_t cpus;
+	cpumask_var_t cpus;
 };
 static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
 
@@ -79,6 +79,8 @@ static unsigned char shared_bank[NR_BANK
 
 static DEFINE_PER_CPU(unsigned char, bank_map);	/* see which banks are on */
 
+static void amd_threshold_interrupt(void);
+
 /*
  * CPU Initialization
  */
@@ -90,7 +92,8 @@ struct thresh_restart {
 };
 
 /* must be called with correct cpu affinity */
-static long threshold_restart_bank(void *_tr)
+/* Called via smp_call_function_single() */
+static void threshold_restart_bank(void *_tr)
 {
 	struct thresh_restart *tr = _tr;
 	u32 mci_misc_hi, mci_misc_lo;
@@ -117,7 +120,6 @@ static long threshold_restart_bank(void
 
 	mci_misc_hi |= MASK_COUNT_EN_HI;
 	wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi);
-	return 0;
 }
 
 /* cpu init entry point, called from mce.c with preempt off */
@@ -174,6 +176,8 @@ void mce_amd_feature_init(struct cpuinfo
 			tr.reset = 0;
 			tr.old_limit = 0;
 			threshold_restart_bank(&tr);
+
+			mce_threshold_vector = amd_threshold_interrupt;
 		}
 	}
 }
@@ -187,19 +191,13 @@ void mce_amd_feature_init(struct cpuinfo
  * the interrupt goes off when error_count reaches threshold_limit.
  * the handler will simply log mcelog w/ software defined bank number.
  */
-asmlinkage void mce_threshold_interrupt(void)
+static void amd_threshold_interrupt(void)
 {
 	unsigned int bank, block;
 	struct mce m;
 	u32 low = 0, high = 0, address = 0;
 
-	ack_APIC_irq();
-	exit_idle();
-	irq_enter();
-
-	memset(&m, 0, sizeof(m));
-	rdtscll(m.tsc);
-	m.cpu = smp_processor_id();
+	mce_setup(&m);
 
 	/* assume first bank caused it */
 	for (bank = 0; bank < NR_BANKS; ++bank) {
@@ -233,7 +231,8 @@ asmlinkage void mce_threshold_interrupt(
 
 			/* Log the machine check that caused the threshold
 			   event. */
-			do_machine_check(NULL, 0);
+			machine_check_poll(MCP_TIMESTAMP,
+					&__get_cpu_var(mce_poll_banks));
 
 			if (high & MASK_OVERFLOW_HI) {
 				rdmsrl(address, m.misc);
@@ -243,13 +242,10 @@ asmlinkage void mce_threshold_interrupt(
 				       + bank * NR_BLOCKS
 				       + block;
 				mce_log(&m);
-				goto out;
+				return;
 			}
 		}
 	}
-out:
-	inc_irq_stat(irq_threshold_count);
-	irq_exit();
 }
 
 /*
@@ -283,7 +279,7 @@ static ssize_t store_interrupt_enable(st
 	tr.b = b;
 	tr.reset = 0;
 	tr.old_limit = 0;
-	work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+	smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
 
 	return end - buf;
 }
@@ -305,23 +301,32 @@ static ssize_t store_threshold_limit(str
 	tr.b = b;
 	tr.reset = 0;
 
-	work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+	smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
 
 	return end - buf;
 }
 
-static long local_error_count(void *_b)
+struct threshold_block_cross_cpu {
+	struct threshold_block *tb;
+	long retval;
+};
+
+static void local_error_count_handler(void *_tbcc)
 {
-	struct threshold_block *b = _b;
+	struct threshold_block_cross_cpu *tbcc = _tbcc;
+	struct threshold_block *b = tbcc->tb;
 	u32 low, high;
 
 	rdmsr(b->address, low, high);
-	return (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
+	tbcc->retval = (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
 }
 
 static ssize_t show_error_count(struct threshold_block *b, char *buf)
 {
-	return sprintf(buf, "%lx\n", work_on_cpu(b->cpu, local_error_count, b));
+	struct threshold_block_cross_cpu tbcc = { .tb = b, };
+
+	smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1);
+	return sprintf(buf, "%lx\n", tbcc.retval);
 }
 
 static ssize_t store_error_count(struct threshold_block *b,
@@ -329,7 +334,7 @@ static ssize_t store_error_count(struct
 {
 	struct thresh_restart tr = { .b = b, .reset = 1, .old_limit = 0 };
 
-	work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+	smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
 	return 1;
 }
 
@@ -398,7 +403,7 @@ static __cpuinit int allocate_threshold_
 	if ((bank >= NR_BANKS) || (block >= NR_BLOCKS))
 		return 0;
 
-	if (rdmsr_safe(address, &low, &high))
+	if (rdmsr_safe_on_cpu(cpu, address, &low, &high))
 		return 0;
 
 	if (!(high & MASK_VALID_HI)) {
@@ -462,12 +467,11 @@ out_free:
 	return err;
 }
 
-static __cpuinit long local_allocate_threshold_blocks(void *_bank)
+static __cpuinit long
+local_allocate_threshold_blocks(int cpu, unsigned int bank)
 {
-	unsigned int *bank = _bank;
-
-	return allocate_threshold_blocks(smp_processor_id(), *bank, 0,
-					 MSR_IA32_MC0_MISC + *bank * 4);
+	return allocate_threshold_blocks(cpu, bank, 0,
+					 MSR_IA32_MC0_MISC + bank * 4);
 }
 
 /* symlinks sibling shared banks to first core.  first core owns dir/files. */
@@ -481,7 +485,7 @@ static __cpuinit int threshold_create_ba
 
 #ifdef CONFIG_SMP
 	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
-		i = first_cpu(per_cpu(cpu_core_map, cpu));
+		i = cpumask_first(cpu_core_mask(cpu));
 
 		/* first core not up yet */
 		if (cpu_data(i).cpu_core_id)
@@ -501,7 +505,7 @@ static __cpuinit int threshold_create_ba
 		if (err)
 			goto out;
 
-		b->cpus = per_cpu(cpu_core_map, cpu);
+		cpumask_copy(b->cpus, cpu_core_mask(cpu));
 		per_cpu(threshold_banks, cpu)[bank] = b;
 		goto out;
 	}
@@ -512,24 +516,29 @@ static __cpuinit int threshold_create_ba
 		err = -ENOMEM;
 		goto out;
 	}
+	if (!alloc_cpumask_var(&b->cpus, GFP_KERNEL)) {
+		kfree(b);
+		err = -ENOMEM;
+		goto out;
+	}
 
 	b->kobj = kobject_create_and_add(name, &per_cpu(device_mce, cpu).kobj);
 	if (!b->kobj)
 		goto out_free;
 
 #ifndef CONFIG_SMP
-	b->cpus = CPU_MASK_ALL;
+	cpumask_setall(b->cpus);
 #else
-	b->cpus = per_cpu(cpu_core_map, cpu);
+	cpumask_copy(b->cpus, cpu_core_mask(cpu));
 #endif
 
 	per_cpu(threshold_banks, cpu)[bank] = b;
 
-	err = work_on_cpu(cpu, local_allocate_threshold_blocks, &bank);
+	err = local_allocate_threshold_blocks(cpu, bank);
 	if (err)
 		goto out_free;
 
-	for_each_cpu_mask_nr(i, b->cpus) {
+	for_each_cpu(i, b->cpus) {
 		if (i == cpu)
 			continue;
 
@@ -545,6 +554,7 @@ static __cpuinit int threshold_create_ba
 
 out_free:
 	per_cpu(threshold_banks, cpu)[bank] = NULL;
+	free_cpumask_var(b->cpus);
 	kfree(b);
 out:
 	return err;
@@ -619,7 +629,7 @@ static void threshold_remove_bank(unsign
 #endif
 
 	/* remove all sibling symlinks before unregistering */
-	for_each_cpu_mask_nr(i, b->cpus) {
+	for_each_cpu(i, b->cpus) {
 		if (i == cpu)
 			continue;
 
@@ -632,6 +642,7 @@ static void threshold_remove_bank(unsign
 free_out:
 	kobject_del(b->kobj);
 	kobject_put(b->kobj);
+	free_cpumask_var(b->cpus);
 	kfree(b);
 	per_cpu(threshold_banks, cpu)[bank] = NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_intel_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,17 +1,21 @@
 /*
  * Intel specific MCE features.
  * Copyright 2004 Zwane Mwaikambo <zwane@linuxpower.ca>
+ * Copyright (C) 2008, 2009 Intel Corporation
+ * Author: Andi Kleen
  */
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <asm/processor.h>
+#include <asm/apic.h>
 #include <asm/msr.h>
 #include <asm/mce.h>
 #include <asm/hw_irq.h>
 #include <asm/idle.h>
 #include <asm/therm_throt.h>
+#include <asm/apic.h>
 
 asmlinkage void smp_thermal_interrupt(void)
 {
@@ -24,7 +28,7 @@ asmlinkage void smp_thermal_interrupt(vo
 
 	rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
 	if (therm_throt_process(msr_val & 1))
-		mce_log_therm_throt_event(smp_processor_id(), msr_val);
+		mce_log_therm_throt_event(msr_val);
 
 	inc_irq_stat(irq_thermal_count);
 	irq_exit();
@@ -48,13 +52,13 @@ static void intel_init_thermal(struct cp
 	 */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
 	h = apic_read(APIC_LVTTHMR);
-	if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
+	if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
 		printk(KERN_DEBUG
 		       "CPU%d: Thermal monitoring handled by SMI\n", cpu);
 		return;
 	}
 
-	if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
+	if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
 		tm2 = 1;
 
 	if (h & APIC_VECTOR_MASK) {
@@ -72,7 +76,7 @@ static void intel_init_thermal(struct cp
 	wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
 
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-	wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
+	wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
 
 	l = apic_read(APIC_LVTTHMR);
 	apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
@@ -84,7 +88,211 @@ static void intel_init_thermal(struct cp
 	return;
 }
 
+/*
+ * Support for Intel Correct Machine Check Interrupts. This allows
+ * the CPU to raise an interrupt when a corrected machine check happened.
+ * Normally we pick those up using a regular polling timer.
+ * Also supports reliable discovery of shared banks.
+ */
+
+static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
+
+/*
+ * cmci_discover_lock protects against parallel discovery attempts
+ * which could race against each other.
+ */
+static DEFINE_SPINLOCK(cmci_discover_lock);
+
+#define CMCI_THRESHOLD 1
+
+static int cmci_supported(int *banks)
+{
+	u64 cap;
+
+	/*
+	 * Vendor check is not strictly needed, but the initial
+	 * initialization is vendor keyed and this
+	 * makes sure none of the backdoors are entered otherwise.
+	 */
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return 0;
+	if (!cpu_has_apic || lapic_get_maxlvt() < 6)
+		return 0;
+	rdmsrl(MSR_IA32_MCG_CAP, cap);
+	*banks = min_t(unsigned, MAX_NR_BANKS, cap & 0xff);
+	return !!(cap & MCG_CMCI_P);
+}
+
+/*
+ * The interrupt handler. This is called on every event.
+ * Just call the poller directly to log any events.
+ * This could in theory increase the threshold under high load,
+ * but doesn't for now.
+ */
+static void intel_threshold_interrupt(void)
+{
+	machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned));
+	mce_notify_user();
+}
+
+static void print_update(char *type, int *hdr, int num)
+{
+	if (*hdr == 0)
+		printk(KERN_INFO "CPU %d MCA banks", smp_processor_id());
+	*hdr = 1;
+	printk(KERN_CONT " %s:%d", type, num);
+}
+
+/*
+ * Enable CMCI (Corrected Machine Check Interrupt) for available MCE banks
+ * on this CPU. Use the algorithm recommended in the SDM to discover shared
+ * banks.
+ */
+static void cmci_discover(int banks, int boot)
+{
+	unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned);
+	unsigned long flags;
+	int hdr = 0;
+	int i;
+
+	spin_lock_irqsave(&cmci_discover_lock, flags);
+	for (i = 0; i < banks; i++) {
+		u64 val;
+
+		if (test_bit(i, owned))
+			continue;
+
+		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+
+		/* Already owned by someone else? */
+		if (val & CMCI_EN) {
+			if (test_and_clear_bit(i, owned) || boot)
+				print_update("SHD", &hdr, i);
+			__clear_bit(i, __get_cpu_var(mce_poll_banks));
+			continue;
+		}
+
+		val |= CMCI_EN | CMCI_THRESHOLD;
+		wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+
+		/* Did the enable bit stick? -- the bank supports CMCI */
+		if (val & CMCI_EN) {
+			if (!test_and_set_bit(i, owned) || boot)
+				print_update("CMCI", &hdr, i);
+			__clear_bit(i, __get_cpu_var(mce_poll_banks));
+		} else {
+			WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
+		}
+	}
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
+	if (hdr)
+		printk(KERN_CONT "\n");
+}
+
+/*
+ * Just in case we missed an event during initialization check
+ * all the CMCI owned banks.
+ */
+void cmci_recheck(void)
+{
+	unsigned long flags;
+	int banks;
+
+	if (!mce_available(&current_cpu_data) || !cmci_supported(&banks))
+		return;
+	local_irq_save(flags);
+	machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned));
+	local_irq_restore(flags);
+}
+
+/*
+ * Disable CMCI on this CPU for all banks it owns when it goes down.
+ * This allows other CPUs to claim the banks on rediscovery.
+ */
+void cmci_clear(void)
+{
+	unsigned long flags;
+	int i;
+	int banks;
+	u64 val;
+
+	if (!cmci_supported(&banks))
+		return;
+	spin_lock_irqsave(&cmci_discover_lock, flags);
+	for (i = 0; i < banks; i++) {
+		if (!test_bit(i, __get_cpu_var(mce_banks_owned)))
+			continue;
+		/* Disable CMCI */
+		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK);
+		wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		__clear_bit(i, __get_cpu_var(mce_banks_owned));
+	}
+	spin_unlock_irqrestore(&cmci_discover_lock, flags);
+}
+
+/*
+ * After a CPU went down cycle through all the others and rediscover
+ * Must run in process context.
+ */
+void cmci_rediscover(int dying)
+{
+	int banks;
+	int cpu;
+	cpumask_var_t old;
+
+	if (!cmci_supported(&banks))
+		return;
+	if (!alloc_cpumask_var(&old, GFP_KERNEL))
+		return;
+	cpumask_copy(old, &current->cpus_allowed);
+
+	for_each_online_cpu (cpu) {
+		if (cpu == dying)
+			continue;
+		if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
+			continue;
+		/* Recheck banks in case CPUs don't all have the same */
+		if (cmci_supported(&banks))
+			cmci_discover(banks, 0);
+	}
+
+	set_cpus_allowed_ptr(current, old);
+	free_cpumask_var(old);
+}
+
+/*
+ * Reenable CMCI on this CPU in case a CPU down failed.
+ */
+void cmci_reenable(void)
+{
+	int banks;
+	if (cmci_supported(&banks))
+		cmci_discover(banks, 0);
+}
+
+static void intel_init_cmci(void)
+{
+	int banks;
+
+	if (!cmci_supported(&banks))
+		return;
+
+	mce_threshold_vector = intel_threshold_interrupt;
+	cmci_discover(banks, 1);
+	/*
+	 * For CPU #0 this runs with still disabled APIC, but that's
+	 * ok because only the vector is set up. We still do another
+	 * check for the banks later for CPU #0 just to make sure
+	 * to not miss any events.
+	 */
+	apic_write(APIC_LVTCMCI, THRESHOLD_APIC_VECTOR|APIC_DM_FIXED);
+	cmci_recheck();
+}
+
 void mce_intel_feature_init(struct cpuinfo_x86 *c)
 {
 	intel_init_thermal(c);
+	intel_init_cmci();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/p4.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/p4.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/p4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/p4.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,7 +85,7 @@ static void intel_init_thermal(struct cp
 	 */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
 	h = apic_read(APIC_LVTTHMR);
-	if ((l & (1<<3)) && (h & APIC_DM_SMI)) {
+	if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
 		printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n",
 				cpu);
 		return; /* -EBUSY */
@@ -111,7 +111,7 @@ static void intel_init_thermal(struct cp
 	vendor_thermal_interrupt = intel_thermal_interrupt;
 
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-	wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
+	wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
 
 	l = apic_read(APIC_LVTTHMR);
 	apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/threshold.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/threshold.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mcheck/threshold.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/threshold.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Common corrected MCE threshold handler code:
+ */
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_vectors.h>
+#include <asm/apic.h>
+#include <asm/idle.h>
+#include <asm/mce.h>
+
+static void default_threshold_interrupt(void)
+{
+	printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n",
+			 THRESHOLD_APIC_VECTOR);
+}
+
+void (*mce_threshold_vector)(void) = default_threshold_interrupt;
+
+asmlinkage void mce_threshold_interrupt(void)
+{
+	exit_idle();
+	irq_enter();
+	inc_irq_stat(irq_threshold_count);
+	mce_threshold_vector();
+	irq_exit();
+	/* Ack only at the end to avoid potential reentry */
+	ack_APIC_irq();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1101 @@
+/*  MTRR (Memory Type Range Register) cleanup
+
+    Copyright (C) 2009 Yinghai Lu
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; 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/pci.h>
+#include <linux/smp.h>
+#include <linux/cpu.h>
+#include <linux/mutex.h>
+#include <linux/sort.h>
+
+#include <asm/e820.h>
+#include <asm/mtrr.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/kvm_para.h>
+#include "mtrr.h"
+
+/* should be related to MTRR_VAR_RANGES nums */
+#define RANGE_NUM 256
+
+struct res_range {
+	unsigned long start;
+	unsigned long end;
+};
+
+static int __init
+add_range(struct res_range *range, int nr_range, unsigned long start,
+			      unsigned long end)
+{
+	/* out of slots */
+	if (nr_range >= RANGE_NUM)
+		return nr_range;
+
+	range[nr_range].start = start;
+	range[nr_range].end = end;
+
+	nr_range++;
+
+	return nr_range;
+}
+
+static int __init
+add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
+			      unsigned long end)
+{
+	int i;
+
+	/* try to merge it with old one */
+	for (i = 0; i < nr_range; i++) {
+		unsigned long final_start, final_end;
+		unsigned long common_start, common_end;
+
+		if (!range[i].end)
+			continue;
+
+		common_start = max(range[i].start, start);
+		common_end = min(range[i].end, end);
+		if (common_start > common_end + 1)
+			continue;
+
+		final_start = min(range[i].start, start);
+		final_end = max(range[i].end, end);
+
+		range[i].start = final_start;
+		range[i].end =  final_end;
+		return nr_range;
+	}
+
+	/* need to add that */
+	return add_range(range, nr_range, start, end);
+}
+
+static void __init
+subtract_range(struct res_range *range, unsigned long start, unsigned long end)
+{
+	int i, j;
+
+	for (j = 0; j < RANGE_NUM; j++) {
+		if (!range[j].end)
+			continue;
+
+		if (start <= range[j].start && end >= range[j].end) {
+			range[j].start = 0;
+			range[j].end = 0;
+			continue;
+		}
+
+		if (start <= range[j].start && end < range[j].end &&
+		    range[j].start < end + 1) {
+			range[j].start = end + 1;
+			continue;
+		}
+
+
+		if (start > range[j].start && end >= range[j].end &&
+		    range[j].end > start - 1) {
+			range[j].end = start - 1;
+			continue;
+		}
+
+		if (start > range[j].start && end < range[j].end) {
+			/* find the new spare */
+			for (i = 0; i < RANGE_NUM; i++) {
+				if (range[i].end == 0)
+					break;
+			}
+			if (i < RANGE_NUM) {
+				range[i].end = range[j].end;
+				range[i].start = end + 1;
+			} else {
+				printk(KERN_ERR "run of slot in ranges\n");
+			}
+			range[j].end = start - 1;
+			continue;
+		}
+	}
+}
+
+static int __init cmp_range(const void *x1, const void *x2)
+{
+	const struct res_range *r1 = x1;
+	const struct res_range *r2 = x2;
+	long start1, start2;
+
+	start1 = r1->start;
+	start2 = r2->start;
+
+	return start1 - start2;
+}
+
+struct var_mtrr_range_state {
+	unsigned long base_pfn;
+	unsigned long size_pfn;
+	mtrr_type type;
+};
+
+static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
+static int __initdata debug_print;
+
+static int __init
+x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
+		       unsigned long extra_remove_base,
+		       unsigned long extra_remove_size)
+{
+	unsigned long base, size;
+	mtrr_type type;
+	int i;
+
+	for (i = 0; i < num_var_ranges; i++) {
+		type = range_state[i].type;
+		if (type != MTRR_TYPE_WRBACK)
+			continue;
+		base = range_state[i].base_pfn;
+		size = range_state[i].size_pfn;
+		nr_range = add_range_with_merge(range, nr_range, base,
+						base + size - 1);
+	}
+	if (debug_print) {
+		printk(KERN_DEBUG "After WB checking\n");
+		for (i = 0; i < nr_range; i++)
+			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+				 range[i].start, range[i].end + 1);
+	}
+
+	/* take out UC ranges */
+	for (i = 0; i < num_var_ranges; i++) {
+		type = range_state[i].type;
+		if (type != MTRR_TYPE_UNCACHABLE &&
+		    type != MTRR_TYPE_WRPROT)
+			continue;
+		size = range_state[i].size_pfn;
+		if (!size)
+			continue;
+		base = range_state[i].base_pfn;
+		if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
+		    (mtrr_state.enabled & 1)) {
+			/* Var MTRR contains UC entry below 1M? Skip it: */
+			printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d "
+				"contains strange UC entry under 1M, check "
+				"with your system vendor!\n", i);
+			if (base + size <= (1<<(20-PAGE_SHIFT)))
+				continue;
+			size -= (1<<(20-PAGE_SHIFT)) - base;
+			base = 1<<(20-PAGE_SHIFT);
+		}
+		subtract_range(range, base, base + size - 1);
+	}
+	if (extra_remove_size)
+		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++)
+			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);
+	if  (debug_print) {
+		printk(KERN_DEBUG "After sorting\n");
+		for (i = 0; i < nr_range; i++)
+			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+				 range[i].start, range[i].end + 1);
+	}
+
+	/* clear those is not used */
+	for (i = nr_range; i < RANGE_NUM; i++)
+		memset(&range[i], 0, sizeof(range[i]));
+
+	return nr_range;
+}
+
+static struct res_range __initdata range[RANGE_NUM];
+static int __initdata nr_range;
+
+#ifdef CONFIG_MTRR_SANITIZER
+
+static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
+{
+	unsigned long sum;
+	int i;
+
+	sum = 0;
+	for (i = 0; i < nr_range; i++)
+		sum += range[i].end + 1 - range[i].start;
+
+	return sum;
+}
+
+static int enable_mtrr_cleanup __initdata =
+	CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT;
+
+static int __init disable_mtrr_cleanup_setup(char *str)
+{
+	enable_mtrr_cleanup = 0;
+	return 0;
+}
+early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup);
+
+static int __init enable_mtrr_cleanup_setup(char *str)
+{
+	enable_mtrr_cleanup = 1;
+	return 0;
+}
+early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
+
+static int __init mtrr_cleanup_debug_setup(char *str)
+{
+	debug_print = 1;
+	return 0;
+}
+early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
+
+struct var_mtrr_state {
+	unsigned long	range_startk;
+	unsigned long	range_sizek;
+	unsigned long	chunk_sizek;
+	unsigned long	gran_sizek;
+	unsigned int	reg;
+};
+
+static void __init
+set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+		unsigned char type, unsigned int address_bits)
+{
+	u32 base_lo, base_hi, mask_lo, mask_hi;
+	u64 base, mask;
+
+	if (!sizek) {
+		fill_mtrr_var_range(reg, 0, 0, 0, 0);
+		return;
+	}
+
+	mask = (1ULL << address_bits) - 1;
+	mask &= ~((((u64)sizek) << 10) - 1);
+
+	base  = ((u64)basek) << 10;
+
+	base |= type;
+	mask |= 0x800;
+
+	base_lo = base & ((1ULL<<32) - 1);
+	base_hi = base >> 32;
+
+	mask_lo = mask & ((1ULL<<32) - 1);
+	mask_hi = mask >> 32;
+
+	fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
+}
+
+static void __init
+save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+		unsigned char type)
+{
+	range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
+	range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
+	range_state[reg].type = type;
+}
+
+static void __init
+set_var_mtrr_all(unsigned int address_bits)
+{
+	unsigned long basek, sizek;
+	unsigned char type;
+	unsigned int reg;
+
+	for (reg = 0; reg < num_var_ranges; reg++) {
+		basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10);
+		sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10);
+		type = range_state[reg].type;
+
+		set_var_mtrr(reg, basek, sizek, type, address_bits);
+	}
+}
+
+static unsigned long to_size_factor(unsigned long sizek, char *factorp)
+{
+	char factor;
+	unsigned long base = sizek;
+
+	if (base & ((1<<10) - 1)) {
+		/* not MB alignment */
+		factor = 'K';
+	} else if (base & ((1<<20) - 1)) {
+		factor = 'M';
+		base >>= 10;
+	} else {
+		factor = 'G';
+		base >>= 20;
+	}
+
+	*factorp = factor;
+
+	return base;
+}
+
+static unsigned int __init
+range_to_mtrr(unsigned int reg, unsigned long range_startk,
+	      unsigned long range_sizek, unsigned char type)
+{
+	if (!range_sizek || (reg >= num_var_ranges))
+		return reg;
+
+	while (range_sizek) {
+		unsigned long max_align, align;
+		unsigned long sizek;
+
+		/* Compute the maximum size I can make a range */
+		if (range_startk)
+			max_align = ffs(range_startk) - 1;
+		else
+			max_align = 32;
+		align = fls(range_sizek) - 1;
+		if (align > max_align)
+			align = max_align;
+
+		sizek = 1 << align;
+		if (debug_print) {
+			char start_factor = 'K', size_factor = 'K';
+			unsigned long start_base, size_base;
+
+			start_base = to_size_factor(range_startk,
+							 &start_factor),
+			size_base = to_size_factor(sizek, &size_factor),
+
+			printk(KERN_DEBUG "Setting variable MTRR %d, "
+				"base: %ld%cB, range: %ld%cB, type %s\n",
+				reg, start_base, start_factor,
+				size_base, size_factor,
+				(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
+				   ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other")
+				);
+		}
+		save_var_mtrr(reg++, range_startk, sizek, type);
+		range_startk += sizek;
+		range_sizek -= sizek;
+		if (reg >= num_var_ranges)
+			break;
+	}
+	return reg;
+}
+
+static unsigned __init
+range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
+			unsigned long sizek)
+{
+	unsigned long hole_basek, hole_sizek;
+	unsigned long second_basek, second_sizek;
+	unsigned long range0_basek, range0_sizek;
+	unsigned long range_basek, range_sizek;
+	unsigned long chunk_sizek;
+	unsigned long gran_sizek;
+
+	hole_basek = 0;
+	hole_sizek = 0;
+	second_basek = 0;
+	second_sizek = 0;
+	chunk_sizek = state->chunk_sizek;
+	gran_sizek = state->gran_sizek;
+
+	/* align with gran size, prevent small block used up MTRRs */
+	range_basek = ALIGN(state->range_startk, gran_sizek);
+	if ((range_basek > basek) && basek)
+		return second_sizek;
+	state->range_sizek -= (range_basek - state->range_startk);
+	range_sizek = ALIGN(state->range_sizek, gran_sizek);
+
+	while (range_sizek > state->range_sizek) {
+		range_sizek -= gran_sizek;
+		if (!range_sizek)
+			return 0;
+	}
+	state->range_sizek = range_sizek;
+
+	/* try to append some small hole */
+	range0_basek = state->range_startk;
+	range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
+
+	/* no increase */
+	if (range0_sizek == state->range_sizek) {
+		if (debug_print)
+			printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
+				range0_basek<<10,
+				(range0_basek + state->range_sizek)<<10);
+		state->reg = range_to_mtrr(state->reg, range0_basek,
+				state->range_sizek, MTRR_TYPE_WRBACK);
+		return 0;
+	}
+
+	/* only cut back, when it is not the last */
+	if (sizek) {
+		while (range0_basek + range0_sizek > (basek + sizek)) {
+			if (range0_sizek >= chunk_sizek)
+				range0_sizek -= chunk_sizek;
+			else
+				range0_sizek = 0;
+
+			if (!range0_sizek)
+				break;
+		}
+	}
+
+second_try:
+	range_basek = range0_basek + range0_sizek;
+
+	/* one hole in the middle */
+	if (range_basek > basek && range_basek <= (basek + sizek))
+		second_sizek = range_basek - basek;
+
+	if (range0_sizek > state->range_sizek) {
+
+		/* one hole in middle or at end */
+		hole_sizek = range0_sizek - state->range_sizek - second_sizek;
+
+		/* hole size should be less than half of range0 size */
+		if (hole_sizek >= (range0_sizek >> 1) &&
+		    range0_sizek >= chunk_sizek) {
+			range0_sizek -= chunk_sizek;
+			second_sizek = 0;
+			hole_sizek = 0;
+
+			goto second_try;
+		}
+	}
+
+	if (range0_sizek) {
+		if (debug_print)
+			printk(KERN_DEBUG "range0: %016lx - %016lx\n",
+				range0_basek<<10,
+				(range0_basek + range0_sizek)<<10);
+		state->reg = range_to_mtrr(state->reg, range0_basek,
+				range0_sizek, MTRR_TYPE_WRBACK);
+	}
+
+	if (range0_sizek < state->range_sizek) {
+		/* need to handle left over */
+		range_sizek = state->range_sizek - range0_sizek;
+
+		if (debug_print)
+			printk(KERN_DEBUG "range: %016lx - %016lx\n",
+				 range_basek<<10,
+				 (range_basek + range_sizek)<<10);
+		state->reg = range_to_mtrr(state->reg, range_basek,
+				 range_sizek, MTRR_TYPE_WRBACK);
+	}
+
+	if (hole_sizek) {
+		hole_basek = range_basek - hole_sizek - second_sizek;
+		if (debug_print)
+			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
+				 hole_basek<<10,
+				 (hole_basek + hole_sizek)<<10);
+		state->reg = range_to_mtrr(state->reg, hole_basek,
+				 hole_sizek, MTRR_TYPE_UNCACHABLE);
+	}
+
+	return second_sizek;
+}
+
+static void __init
+set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
+		   unsigned long size_pfn)
+{
+	unsigned long basek, sizek;
+	unsigned long second_sizek = 0;
+
+	if (state->reg >= num_var_ranges)
+		return;
+
+	basek = base_pfn << (PAGE_SHIFT - 10);
+	sizek = size_pfn << (PAGE_SHIFT - 10);
+
+	/* See if I can merge with the last range */
+	if ((basek <= 1024) ||
+	    (state->range_startk + state->range_sizek == basek)) {
+		unsigned long endk = basek + sizek;
+		state->range_sizek = endk - state->range_startk;
+		return;
+	}
+	/* Write the range mtrrs */
+	if (state->range_sizek != 0)
+		second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
+
+	/* Allocate an msr */
+	state->range_startk = basek + second_sizek;
+	state->range_sizek  = sizek - second_sizek;
+}
+
+/* mininum size of mtrr block that can take hole */
+static u64 mtrr_chunk_size __initdata = (256ULL<<20);
+
+static int __init parse_mtrr_chunk_size_opt(char *p)
+{
+	if (!p)
+		return -EINVAL;
+	mtrr_chunk_size = memparse(p, &p);
+	return 0;
+}
+early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
+
+/* granity of mtrr of block */
+static u64 mtrr_gran_size __initdata;
+
+static int __init parse_mtrr_gran_size_opt(char *p)
+{
+	if (!p)
+		return -EINVAL;
+	mtrr_gran_size = memparse(p, &p);
+	return 0;
+}
+early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
+
+static int nr_mtrr_spare_reg __initdata =
+				 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
+
+static int __init parse_mtrr_spare_reg(char *arg)
+{
+	if (arg)
+		nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
+	return 0;
+}
+
+early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
+
+static int __init
+x86_setup_var_mtrrs(struct res_range *range, int nr_range,
+		    u64 chunk_size, u64 gran_size)
+{
+	struct var_mtrr_state var_state;
+	int i;
+	int num_reg;
+
+	var_state.range_startk	= 0;
+	var_state.range_sizek	= 0;
+	var_state.reg		= 0;
+	var_state.chunk_sizek	= chunk_size >> 10;
+	var_state.gran_sizek	= gran_size >> 10;
+
+	memset(range_state, 0, sizeof(range_state));
+
+	/* Write the range etc */
+	for (i = 0; i < nr_range; i++)
+		set_var_mtrr_range(&var_state, range[i].start,
+				   range[i].end - range[i].start + 1);
+
+	/* Write the last range */
+	if (var_state.range_sizek != 0)
+		range_to_mtrr_with_hole(&var_state, 0, 0);
+
+	num_reg = var_state.reg;
+	/* Clear out the extra MTRR's */
+	while (var_state.reg < num_var_ranges) {
+		save_var_mtrr(var_state.reg, 0, 0, 0);
+		var_state.reg++;
+	}
+
+	return num_reg;
+}
+
+struct mtrr_cleanup_result {
+	unsigned long gran_sizek;
+	unsigned long chunk_sizek;
+	unsigned long lose_cover_sizek;
+	unsigned int num_reg;
+	int bad;
+};
+
+/*
+ * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
+ * chunk size: gran_size, ..., 2G
+ * so we need (1+16)*8
+ */
+#define NUM_RESULT	136
+#define PSHIFT		(PAGE_SHIFT - 10)
+
+static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
+static unsigned long __initdata min_loss_pfn[RANGE_NUM];
+
+static void __init print_out_mtrr_range_state(void)
+{
+	int i;
+	char start_factor = 'K', size_factor = 'K';
+	unsigned long start_base, size_base;
+	mtrr_type type;
+
+	for (i = 0; i < num_var_ranges; i++) {
+
+		size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
+		if (!size_base)
+			continue;
+
+		size_base = to_size_factor(size_base, &size_factor),
+		start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
+		start_base = to_size_factor(start_base, &start_factor),
+		type = range_state[i].type;
+
+		printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
+			i, start_base, start_factor,
+			size_base, size_factor,
+			(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
+			    ((type == MTRR_TYPE_WRPROT) ? "WP" :
+			     ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
+			);
+	}
+}
+
+static int __init mtrr_need_cleanup(void)
+{
+	int i;
+	mtrr_type type;
+	unsigned long size;
+	/* extra one for all 0 */
+	int num[MTRR_NUM_TYPES + 1];
+
+	/* check entries number */
+	memset(num, 0, sizeof(num));
+	for (i = 0; i < num_var_ranges; i++) {
+		type = range_state[i].type;
+		size = range_state[i].size_pfn;
+		if (type >= MTRR_NUM_TYPES)
+			continue;
+		if (!size)
+			type = MTRR_NUM_TYPES;
+		if (type == MTRR_TYPE_WRPROT)
+			type = MTRR_TYPE_UNCACHABLE;
+		num[type]++;
+	}
+
+	/* check if we got UC entries */
+	if (!num[MTRR_TYPE_UNCACHABLE])
+		return 0;
+
+	/* check if we only had WB and UC */
+	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
+		num_var_ranges - num[MTRR_NUM_TYPES])
+		return 0;
+
+	return 1;
+}
+
+static unsigned long __initdata range_sums;
+static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
+					 unsigned long extra_remove_base,
+					 unsigned long extra_remove_size,
+					 int i)
+{
+	int num_reg;
+	static struct res_range range_new[RANGE_NUM];
+	static int nr_range_new;
+	unsigned long range_sums_new;
+
+	/* convert ranges to var ranges state */
+	num_reg = x86_setup_var_mtrrs(range, nr_range,
+						chunk_size, gran_size);
+
+	/* we got new setting in range_state, check it */
+	memset(range_new, 0, sizeof(range_new));
+	nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
+				extra_remove_base, extra_remove_size);
+	range_sums_new = sum_ranges(range_new, nr_range_new);
+
+	result[i].chunk_sizek = chunk_size >> 10;
+	result[i].gran_sizek = gran_size >> 10;
+	result[i].num_reg = num_reg;
+	if (range_sums < range_sums_new) {
+		result[i].lose_cover_sizek =
+			(range_sums_new - range_sums) << PSHIFT;
+		result[i].bad = 1;
+	} else
+		result[i].lose_cover_sizek =
+			(range_sums - range_sums_new) << PSHIFT;
+
+	/* double check it */
+	if (!result[i].bad && !result[i].lose_cover_sizek) {
+		if (nr_range_new != nr_range ||
+			memcmp(range, range_new, sizeof(range)))
+				result[i].bad = 1;
+	}
+
+	if (!result[i].bad && (range_sums - range_sums_new <
+				min_loss_pfn[num_reg])) {
+		min_loss_pfn[num_reg] =
+			range_sums - range_sums_new;
+	}
+}
+
+static void __init mtrr_print_out_one_result(int i)
+{
+	char gran_factor, chunk_factor, lose_factor;
+	unsigned long gran_base, chunk_base, lose_base;
+
+	gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
+	chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
+	lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+	printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
+			result[i].bad ? "*BAD*" : " ",
+			gran_base, gran_factor, chunk_base, chunk_factor);
+	printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
+			result[i].num_reg, result[i].bad ? "-" : "",
+			lose_base, lose_factor);
+}
+
+static int __init mtrr_search_optimal_index(void)
+{
+	int i;
+	int num_reg_good;
+	int index_good;
+
+	if (nr_mtrr_spare_reg >= num_var_ranges)
+		nr_mtrr_spare_reg = num_var_ranges - 1;
+	num_reg_good = -1;
+	for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
+		if (!min_loss_pfn[i])
+			num_reg_good = i;
+	}
+
+	index_good = -1;
+	if (num_reg_good != -1) {
+		for (i = 0; i < NUM_RESULT; i++) {
+			if (!result[i].bad &&
+			    result[i].num_reg == num_reg_good &&
+			    !result[i].lose_cover_sizek) {
+				index_good = i;
+				break;
+			}
+		}
+	}
+
+	return index_good;
+}
+
+
+int __init mtrr_cleanup(unsigned address_bits)
+{
+	unsigned long extra_remove_base, extra_remove_size;
+	unsigned long base, size, def, dummy;
+	mtrr_type type;
+	u64 chunk_size, gran_size;
+	int index_good;
+	int i;
+
+	if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
+		return 0;
+	rdmsr(MTRRdefType_MSR, def, dummy);
+	def &= 0xff;
+	if (def != MTRR_TYPE_UNCACHABLE)
+		return 0;
+
+	/* get it and store it aside */
+	memset(range_state, 0, sizeof(range_state));
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i, &base, &size, &type);
+		range_state[i].base_pfn = base;
+		range_state[i].size_pfn = size;
+		range_state[i].type = type;
+	}
+
+	/* check if we need handle it and can handle it */
+	if (!mtrr_need_cleanup())
+		return 0;
+
+	/* print original var MTRRs at first, for debugging: */
+	printk(KERN_DEBUG "original variable MTRRs\n");
+	print_out_mtrr_range_state();
+
+	memset(range, 0, sizeof(range));
+	extra_remove_size = 0;
+	extra_remove_base = 1 << (32 - PAGE_SHIFT);
+	if (mtrr_tom2)
+		extra_remove_size =
+			(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
+	nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
+					  extra_remove_size);
+	/*
+	 * [0, 1M) should always be coverred by var mtrr with WB
+	 * and fixed mtrrs should take effective before var mtrr for it
+	 */
+	nr_range = add_range_with_merge(range, nr_range, 0,
+					(1ULL<<(20 - PAGE_SHIFT)) - 1);
+	/* sort the ranges */
+	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+
+	range_sums = sum_ranges(range, nr_range);
+	printk(KERN_INFO "total RAM coverred: %ldM\n",
+	       range_sums >> (20 - PAGE_SHIFT));
+
+	if (mtrr_chunk_size && mtrr_gran_size) {
+		i = 0;
+		mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
+				      extra_remove_base, extra_remove_size, i);
+
+		mtrr_print_out_one_result(i);
+
+		if (!result[i].bad) {
+			set_var_mtrr_all(address_bits);
+			printk(KERN_DEBUG "New variable MTRRs\n");
+			print_out_mtrr_range_state();
+			return 1;
+		}
+		printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
+		       "will find optimal one\n");
+	}
+
+	i = 0;
+	memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
+	memset(result, 0, sizeof(result));
+	for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
+
+		for (chunk_size = gran_size; chunk_size < (1ULL<<32);
+		     chunk_size <<= 1) {
+
+			if (i >= NUM_RESULT)
+				continue;
+
+			mtrr_calc_range_state(chunk_size, gran_size,
+				      extra_remove_base, extra_remove_size, i);
+			if (debug_print) {
+				mtrr_print_out_one_result(i);
+				printk(KERN_INFO "\n");
+			}
+
+			i++;
+		}
+	}
+
+	/* try to find the optimal index */
+	index_good = mtrr_search_optimal_index();
+
+	if (index_good != -1) {
+		printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
+		i = index_good;
+		mtrr_print_out_one_result(i);
+
+		/* convert ranges to var ranges state */
+		chunk_size = result[i].chunk_sizek;
+		chunk_size <<= 10;
+		gran_size = result[i].gran_sizek;
+		gran_size <<= 10;
+		x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
+		set_var_mtrr_all(address_bits);
+		printk(KERN_DEBUG "New variable MTRRs\n");
+		print_out_mtrr_range_state();
+		return 1;
+	} else {
+		/* print out all */
+		for (i = 0; i < NUM_RESULT; i++)
+			mtrr_print_out_one_result(i);
+	}
+
+	printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
+	printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
+
+	return 0;
+}
+#else
+int __init mtrr_cleanup(unsigned address_bits)
+{
+	return 0;
+}
+#endif
+
+static int disable_mtrr_trim;
+
+static int __init disable_mtrr_trim_setup(char *str)
+{
+	disable_mtrr_trim = 1;
+	return 0;
+}
+early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
+
+/*
+ * Newer AMD K8s and later CPUs have a special magic MSR way to force WB
+ * for memory >4GB. Check for that here.
+ * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
+ * apply to are wrong, but so far we don't know of any such case in the wild.
+ */
+#define Tom2Enabled (1U << 21)
+#define Tom2ForceMemTypeWB (1U << 22)
+
+int __init amd_special_default_mtrr(void)
+{
+	u32 l, h;
+
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+		return 0;
+	if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
+		return 0;
+	/* In case some hypervisor doesn't pass SYSCFG through */
+	if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
+		return 0;
+	/*
+	 * Memory between 4GB and top of mem is forced WB by this magic bit.
+	 * Reserved before K8RevF, but should be zero there.
+	 */
+	if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
+		 (Tom2Enabled | Tom2ForceMemTypeWB))
+		return 1;
+	return 0;
+}
+
+static u64 __init real_trim_memory(unsigned long start_pfn,
+				   unsigned long limit_pfn)
+{
+	u64 trim_start, trim_size;
+	trim_start = start_pfn;
+	trim_start <<= PAGE_SHIFT;
+	trim_size = limit_pfn;
+	trim_size <<= PAGE_SHIFT;
+	trim_size -= trim_start;
+
+	return e820_update_range(trim_start, trim_size, E820_RAM,
+				E820_RESERVED);
+}
+/**
+ * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
+ * @end_pfn: ending page frame number
+ *
+ * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
+ * memory configurations.  This routine checks that the highest MTRR matches
+ * the end of memory, to make sure the MTRRs having a write back type cover
+ * all of the memory the kernel is intending to use. If not, it'll trim any
+ * memory off the end by adjusting end_pfn, removing it from the kernel's
+ * allocation pools, warning the user with an obnoxious message.
+ */
+int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
+{
+	unsigned long i, base, size, highest_pfn = 0, def, dummy;
+	mtrr_type type;
+	u64 total_trim_size;
+
+	/* extra one for all 0 */
+	int num[MTRR_NUM_TYPES + 1];
+	/*
+	 * Make sure we only trim uncachable memory on machines that
+	 * support the Intel MTRR architecture:
+	 */
+	if (!is_cpu(INTEL) || disable_mtrr_trim)
+		return 0;
+	rdmsr(MTRRdefType_MSR, def, dummy);
+	def &= 0xff;
+	if (def != MTRR_TYPE_UNCACHABLE)
+		return 0;
+
+	/* get it and store it aside */
+	memset(range_state, 0, sizeof(range_state));
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i, &base, &size, &type);
+		range_state[i].base_pfn = base;
+		range_state[i].size_pfn = size;
+		range_state[i].type = type;
+	}
+
+	/* Find highest cached pfn */
+	for (i = 0; i < num_var_ranges; i++) {
+		type = range_state[i].type;
+		if (type != MTRR_TYPE_WRBACK)
+			continue;
+		base = range_state[i].base_pfn;
+		size = range_state[i].size_pfn;
+		if (highest_pfn < base + size)
+			highest_pfn = base + size;
+	}
+
+	/* kvm/qemu doesn't have mtrr set right, don't trim them all */
+	if (!highest_pfn) {
+		printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
+		return 0;
+	}
+
+	/* check entries number */
+	memset(num, 0, sizeof(num));
+	for (i = 0; i < num_var_ranges; i++) {
+		type = range_state[i].type;
+		if (type >= MTRR_NUM_TYPES)
+			continue;
+		size = range_state[i].size_pfn;
+		if (!size)
+			type = MTRR_NUM_TYPES;
+		num[type]++;
+	}
+
+	/* no entry for WB? */
+	if (!num[MTRR_TYPE_WRBACK])
+		return 0;
+
+	/* check if we only had WB and UC */
+	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
+		num_var_ranges - num[MTRR_NUM_TYPES])
+		return 0;
+
+	memset(range, 0, sizeof(range));
+	nr_range = 0;
+	if (mtrr_tom2) {
+		range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT));
+		range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1;
+		if (highest_pfn < range[nr_range].end + 1)
+			highest_pfn = range[nr_range].end + 1;
+		nr_range++;
+	}
+	nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
+
+	total_trim_size = 0;
+	/* check the head */
+	if (range[0].start)
+		total_trim_size += real_trim_memory(0, range[0].start);
+	/* check the holes */
+	for (i = 0; i < nr_range - 1; i++) {
+		if (range[i].end + 1 < range[i+1].start)
+			total_trim_size += real_trim_memory(range[i].end + 1,
+							    range[i+1].start);
+	}
+	/* check the top */
+	i = nr_range - 1;
+	if (range[i].end + 1 < end_pfn)
+		total_trim_size += real_trim_memory(range[i].end + 1,
+							 end_pfn);
+
+	if (total_trim_size) {
+		printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
+			" all of memory, losing %lluMB of RAM.\n",
+			total_trim_size >> 20);
+
+		if (!changed_by_mtrr_cleanup)
+			WARN_ON(1);
+
+		printk(KERN_INFO "update e820 for mtrr\n");
+		update_e820();
+
+		return 1;
+	}
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/generic.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/generic.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,13 +33,31 @@ u64 mtrr_tom2;
 struct mtrr_state_type mtrr_state = {};
 EXPORT_SYMBOL_GPL(mtrr_state);
 
-static int __initdata mtrr_show;
-static int __init mtrr_debug(char *opt)
+/**
+ * BIOS is expected to clear MtrrFixDramModEn bit, see for example
+ * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
+ * Opteron Processors" (26094 Rev. 3.30 February 2006), section
+ * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set
+ * to 1 during BIOS initalization of the fixed MTRRs, then cleared to
+ * 0 for operation."
+ */
+static inline void k8_check_syscfg_dram_mod_en(void)
 {
-	mtrr_show = 1;
-	return 0;
+	u32 lo, hi;
+
+	if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
+	      (boot_cpu_data.x86 >= 0x0f)))
+		return;
+
+	rdmsr(MSR_K8_SYSCFG, lo, hi);
+	if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
+		printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
+		       " not cleared by BIOS, clearing this bit\n",
+		       smp_processor_id());
+		lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
+		mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi);
+	}
 }
-early_param("mtrr.show", mtrr_debug);
 
 /*
  * Returns the effective MTRR type for the region
@@ -174,6 +192,8 @@ get_fixed_ranges(mtrr_type * frs)
 	unsigned int *p = (unsigned int *) frs;
 	int i;
 
+	k8_check_syscfg_dram_mod_en();
+
 	rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
 
 	for (i = 0; i < 2; i++)
@@ -188,18 +208,98 @@ void mtrr_save_fixed_ranges(void *info)
 		get_fixed_ranges(mtrr_state.fixed_ranges);
 }
 
-static void print_fixed(unsigned base, unsigned step, const mtrr_type*types)
+static unsigned __initdata last_fixed_start;
+static unsigned __initdata last_fixed_end;
+static mtrr_type __initdata last_fixed_type;
+
+static void __init print_fixed_last(void)
+{
+	if (!last_fixed_end)
+		return;
+
+	printk(KERN_DEBUG "  %05X-%05X %s\n", last_fixed_start,
+		last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
+
+	last_fixed_end = 0;
+}
+
+static void __init update_fixed_last(unsigned base, unsigned end,
+				       mtrr_type type)
+{
+	last_fixed_start = base;
+	last_fixed_end = end;
+	last_fixed_type = type;
+}
+
+static void __init print_fixed(unsigned base, unsigned step,
+			       const mtrr_type *types)
 {
 	unsigned i;
 
-	for (i = 0; i < 8; ++i, ++types, base += step)
-		printk(KERN_INFO "MTRR %05X-%05X %s\n",
-			base, base + step - 1, mtrr_attrib_to_str(*types));
+	for (i = 0; i < 8; ++i, ++types, base += step) {
+		if (last_fixed_end == 0) {
+			update_fixed_last(base, base + step, *types);
+			continue;
+		}
+		if (last_fixed_end == base && last_fixed_type == *types) {
+			last_fixed_end = base + step;
+			continue;
+		}
+		/* new segments: gap or different type */
+		print_fixed_last();
+		update_fixed_last(base, base + step, *types);
+	}
 }
 
 static void prepare_set(void);
 static void post_set(void);
 
+static void __init print_mtrr_state(void)
+{
+	unsigned int i;
+	int high_width;
+
+	printk(KERN_DEBUG "MTRR default type: %s\n",
+			 mtrr_attrib_to_str(mtrr_state.def_type));
+	if (mtrr_state.have_fixed) {
+		printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n",
+		       mtrr_state.enabled & 1 ? "en" : "dis");
+		print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
+		for (i = 0; i < 2; ++i)
+			print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8);
+		for (i = 0; i < 8; ++i)
+			print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8);
+
+		/* tail */
+		print_fixed_last();
+	}
+	printk(KERN_DEBUG "MTRR variable ranges %sabled:\n",
+	       mtrr_state.enabled & 2 ? "en" : "dis");
+	if (size_or_mask & 0xffffffffUL)
+		high_width = ffs(size_or_mask & 0xffffffffUL) - 1;
+	else
+		high_width = ffs(size_or_mask>>32) + 32 - 1;
+	high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4;
+	for (i = 0; i < num_var_ranges; ++i) {
+		if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
+			printk(KERN_DEBUG "  %u base %0*X%05X000 mask %0*X%05X000 %s\n",
+			       i,
+			       high_width,
+			       mtrr_state.var_ranges[i].base_hi,
+			       mtrr_state.var_ranges[i].base_lo >> 12,
+			       high_width,
+			       mtrr_state.var_ranges[i].mask_hi,
+			       mtrr_state.var_ranges[i].mask_lo >> 12,
+			       mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
+		else
+			printk(KERN_DEBUG "  %u disabled\n", i);
+	}
+	if (mtrr_tom2) {
+		printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n",
+				  mtrr_tom2, mtrr_tom2>>20);
+	}
+}
+
 /*  Grab all of the MTRR state for this CPU into *state  */
 void __init get_mtrr_state(void)
 {
@@ -231,41 +331,9 @@ void __init get_mtrr_state(void)
 		mtrr_tom2 |= low;
 		mtrr_tom2 &= 0xffffff800000ULL;
 	}
-	if (mtrr_show) {
-		int high_width;
 
-		printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type));
-		if (mtrr_state.have_fixed) {
-			printk(KERN_INFO "MTRR fixed ranges %sabled:\n",
-			       mtrr_state.enabled & 1 ? "en" : "dis");
-			print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
-			for (i = 0; i < 2; ++i)
-				print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8);
-			for (i = 0; i < 8; ++i)
-				print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8);
-		}
-		printk(KERN_INFO "MTRR variable ranges %sabled:\n",
-		       mtrr_state.enabled & 2 ? "en" : "dis");
-		high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4;
-		for (i = 0; i < num_var_ranges; ++i) {
-			if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
-				printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n",
-				       i,
-				       high_width,
-				       mtrr_state.var_ranges[i].base_hi,
-				       mtrr_state.var_ranges[i].base_lo >> 12,
-				       high_width,
-				       mtrr_state.var_ranges[i].mask_hi,
-				       mtrr_state.var_ranges[i].mask_lo >> 12,
-				       mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
-			else
-				printk(KERN_INFO "MTRR %u disabled\n", i);
-		}
-		if (mtrr_tom2) {
-			printk(KERN_INFO "TOM2: %016llx aka %lldM\n",
-					  mtrr_tom2, mtrr_tom2>>20);
-		}
-	}
+	print_mtrr_state();
+
 	mtrr_state_set = 1;
 
 	/* PAT setup for BP. We need to go through sync steps here */
@@ -308,27 +376,10 @@ void mtrr_wrmsr(unsigned msr, unsigned a
 }
 
 /**
- * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs
- * see AMD publication no. 24593, chapter 3.2.1 for more information
- */
-static inline void k8_enable_fixed_iorrs(void)
-{
-	unsigned lo, hi;
-
-	rdmsr(MSR_K8_SYSCFG, lo, hi);
-	mtrr_wrmsr(MSR_K8_SYSCFG, lo
-				| K8_MTRRFIXRANGE_DRAM_ENABLE
-				| K8_MTRRFIXRANGE_DRAM_MODIFY, hi);
-}
-
-/**
  * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have
  * @msr: MSR address of the MTTR which should be checked and updated
  * @changed: pointer which indicates whether the MTRR needed to be changed
  * @msrwords: pointer to the MSR values which the MSR should have
- *
- * If K8 extentions are wanted, update the K8 SYSCFG MSR also.
- * See AMD publication no. 24593, chapter 7.8.1, page 233 for more information.
  */
 static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
 {
@@ -337,10 +388,6 @@ static void set_fixed_range(int msr, boo
 	rdmsr(msr, lo, hi);
 
 	if (lo != msrwords[0] || hi != msrwords[1]) {
-		if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-		    (boot_cpu_data.x86 >= 0x0f && boot_cpu_data.x86 <= 0x11) &&
-		    ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK))
-			k8_enable_fixed_iorrs();
 		mtrr_wrmsr(msr, msrwords[0], msrwords[1]);
 		*changed = true;
 	}
@@ -376,22 +423,31 @@ static void generic_get_mtrr(unsigned in
 {
 	unsigned int mask_lo, mask_hi, base_lo, base_hi;
 	unsigned int tmp, hi;
+	int cpu;
+
+	/*
+	 * get_mtrr doesn't need to update mtrr_state, also it could be called
+	 * from any cpu, so try to print it out directly.
+	 */
+	cpu = get_cpu();
 
 	rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
+
 	if ((mask_lo & 0x800) == 0) {
 		/*  Invalid (i.e. free) range  */
 		*base = 0;
 		*size = 0;
 		*type = 0;
-		return;
+		goto out_put_cpu;
 	}
 
 	rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
 
-	/* Work out the shifted address mask. */
+	/* Work out the shifted address mask: */
 	tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
 	mask_lo = size_or_mask | tmp;
-	/* Expand tmp with high bits to all 1s*/
+
+	/* Expand tmp with high bits to all 1s: */
 	hi = fls(tmp);
 	if (hi > 0) {
 		tmp |= ~((1<<(hi - 1)) - 1);
@@ -402,11 +458,16 @@ static void generic_get_mtrr(unsigned in
 		}
 	}
 
-	/* This works correctly if size is a power of two, i.e. a
-	   contiguous range. */
+	/*
+	 * This works correctly if size is a power of two, i.e. a
+	 * contiguous range:
+	 */
 	*size = -mask_lo;
 	*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
 	*type = base_lo & 0xff;
+
+out_put_cpu:
+	put_cpu();
 }
 
 /**
@@ -419,6 +480,8 @@ static int set_fixed_ranges(mtrr_type *
 	bool changed = false;
 	int block=-1, range;
 
+	k8_check_syscfg_dram_mod_en();
+
 	while (fixed_range_blocks[++block].ranges)
 	    for (range=0; range < fixed_range_blocks[block].ranges; range++)
 		set_fixed_range(fixed_range_blocks[block].base_msr + range,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/if.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/if.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/if.c	2009-06-09 23:05:27.000000000 -0400
@@ -377,10 +377,6 @@ static const struct file_operations mtrr
 	.release = mtrr_close,
 };
 
-
-static struct proc_dir_entry *proc_root_mtrr;
-
-
 static int mtrr_seq_show(struct seq_file *seq, void *offset)
 {
 	char factor;
@@ -423,11 +419,7 @@ static int __init mtrr_if_init(void)
 	    (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
 		return -ENODEV;
 
-	proc_root_mtrr =
-		proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
-
-	if (proc_root_mtrr)
-		proc_root_mtrr->owner = THIS_MODULE;
+	proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/main.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/main.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -574,7 +574,7 @@ struct mtrr_value {
 	unsigned long	lsize;
 };
 
-static struct mtrr_value mtrr_state[MTRR_MAX_VAR_RANGES];
+static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
 
 static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
 {
@@ -582,9 +582,9 @@ static int mtrr_save(struct sys_device *
 
 	for (i = 0; i < num_var_ranges; i++) {
 		mtrr_if->get(i,
-			     &mtrr_state[i].lbase,
-			     &mtrr_state[i].lsize,
-			     &mtrr_state[i].ltype);
+			     &mtrr_value[i].lbase,
+			     &mtrr_value[i].lsize,
+			     &mtrr_value[i].ltype);
 	}
 	return 0;
 }
@@ -594,11 +594,11 @@ static int mtrr_restore(struct sys_devic
 	int i;
 
 	for (i = 0; i < num_var_ranges; i++) {
-		if (mtrr_state[i].lsize) 
+		if (mtrr_value[i].lsize)
 			set_mtrr(i,
-				 mtrr_state[i].lbase,
-				 mtrr_state[i].lsize,
-				 mtrr_state[i].ltype);
+				 mtrr_value[i].lbase,
+				 mtrr_value[i].lsize,
+				 mtrr_value[i].ltype);
 	}
 	return 0;
 }
@@ -610,1058 +610,7 @@ static struct sysdev_driver mtrr_sysdev_
 	.resume		= mtrr_restore,
 };
 
-/* should be related to MTRR_VAR_RANGES nums */
-#define RANGE_NUM 256
-
-struct res_range {
-	unsigned long start;
-	unsigned long end;
-};
-
-static int __init
-add_range(struct res_range *range, int nr_range, unsigned long start,
-			      unsigned long end)
-{
-	/* out of slots */
-	if (nr_range >= RANGE_NUM)
-		return nr_range;
-
-	range[nr_range].start = start;
-	range[nr_range].end = end;
-
-	nr_range++;
-
-	return nr_range;
-}
-
-static int __init
-add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
-			      unsigned long end)
-{
-	int i;
-
-	/* try to merge it with old one */
-	for (i = 0; i < nr_range; i++) {
-		unsigned long final_start, final_end;
-		unsigned long common_start, common_end;
-
-		if (!range[i].end)
-			continue;
-
-		common_start = max(range[i].start, start);
-		common_end = min(range[i].end, end);
-		if (common_start > common_end + 1)
-			continue;
-
-		final_start = min(range[i].start, start);
-		final_end = max(range[i].end, end);
-
-		range[i].start = final_start;
-		range[i].end =  final_end;
-		return nr_range;
-	}
-
-	/* need to add that */
-	return add_range(range, nr_range, start, end);
-}
-
-static void __init
-subtract_range(struct res_range *range, unsigned long start, unsigned long end)
-{
-	int i, j;
-
-	for (j = 0; j < RANGE_NUM; j++) {
-		if (!range[j].end)
-			continue;
-
-		if (start <= range[j].start && end >= range[j].end) {
-			range[j].start = 0;
-			range[j].end = 0;
-			continue;
-		}
-
-		if (start <= range[j].start && end < range[j].end &&
-		    range[j].start < end + 1) {
-			range[j].start = end + 1;
-			continue;
-		}
-
-
-		if (start > range[j].start && end >= range[j].end &&
-		    range[j].end > start - 1) {
-			range[j].end = start - 1;
-			continue;
-		}
-
-		if (start > range[j].start && end < range[j].end) {
-			/* find the new spare */
-			for (i = 0; i < RANGE_NUM; i++) {
-				if (range[i].end == 0)
-					break;
-			}
-			if (i < RANGE_NUM) {
-				range[i].end = range[j].end;
-				range[i].start = end + 1;
-			} else {
-				printk(KERN_ERR "run of slot in ranges\n");
-			}
-			range[j].end = start - 1;
-			continue;
-		}
-	}
-}
-
-static int __init cmp_range(const void *x1, const void *x2)
-{
-	const struct res_range *r1 = x1;
-	const struct res_range *r2 = x2;
-	long start1, start2;
-
-	start1 = r1->start;
-	start2 = r2->start;
-
-	return start1 - start2;
-}
-
-struct var_mtrr_range_state {
-	unsigned long base_pfn;
-	unsigned long size_pfn;
-	mtrr_type type;
-};
-
-static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
-static int __initdata debug_print;
-
-static int __init
-x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
-		       unsigned long extra_remove_base,
-		       unsigned long extra_remove_size)
-{
-	unsigned long i, base, size;
-	mtrr_type type;
-
-	for (i = 0; i < num_var_ranges; i++) {
-		type = range_state[i].type;
-		if (type != MTRR_TYPE_WRBACK)
-			continue;
-		base = range_state[i].base_pfn;
-		size = range_state[i].size_pfn;
-		nr_range = add_range_with_merge(range, nr_range, base,
-						base + size - 1);
-	}
-	if (debug_print) {
-		printk(KERN_DEBUG "After WB checking\n");
-		for (i = 0; i < nr_range; i++)
-			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
-				 range[i].start, range[i].end + 1);
-	}
-
-	/* take out UC ranges */
-	for (i = 0; i < num_var_ranges; i++) {
-		type = range_state[i].type;
-		if (type != MTRR_TYPE_UNCACHABLE &&
-		    type != MTRR_TYPE_WRPROT)
-			continue;
-		size = range_state[i].size_pfn;
-		if (!size)
-			continue;
-		base = range_state[i].base_pfn;
-		subtract_range(range, base, base + size - 1);
-	}
-	if (extra_remove_size)
-		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++)
-			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);
-	if  (debug_print) {
-		printk(KERN_DEBUG "After sorting\n");
-		for (i = 0; i < nr_range; i++)
-			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
-				 range[i].start, range[i].end + 1);
-	}
-
-	/* clear those is not used */
-	for (i = nr_range; i < RANGE_NUM; i++)
-		memset(&range[i], 0, sizeof(range[i]));
-
-	return nr_range;
-}
-
-static struct res_range __initdata range[RANGE_NUM];
-static int __initdata nr_range;
-
-#ifdef CONFIG_MTRR_SANITIZER
-
-static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
-{
-	unsigned long sum;
-	int i;
-
-	sum = 0;
-	for (i = 0; i < nr_range; i++)
-		sum += range[i].end + 1 - range[i].start;
-
-	return sum;
-}
-
-static int enable_mtrr_cleanup __initdata =
-	CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT;
-
-static int __init disable_mtrr_cleanup_setup(char *str)
-{
-	enable_mtrr_cleanup = 0;
-	return 0;
-}
-early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup);
-
-static int __init enable_mtrr_cleanup_setup(char *str)
-{
-	enable_mtrr_cleanup = 1;
-	return 0;
-}
-early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
-
-static int __init mtrr_cleanup_debug_setup(char *str)
-{
-	debug_print = 1;
-	return 0;
-}
-early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
-
-struct var_mtrr_state {
-	unsigned long	range_startk;
-	unsigned long	range_sizek;
-	unsigned long	chunk_sizek;
-	unsigned long	gran_sizek;
-	unsigned int	reg;
-};
-
-static void __init
-set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
-		unsigned char type, unsigned int address_bits)
-{
-	u32 base_lo, base_hi, mask_lo, mask_hi;
-	u64 base, mask;
-
-	if (!sizek) {
-		fill_mtrr_var_range(reg, 0, 0, 0, 0);
-		return;
-	}
-
-	mask = (1ULL << address_bits) - 1;
-	mask &= ~((((u64)sizek) << 10) - 1);
-
-	base  = ((u64)basek) << 10;
-
-	base |= type;
-	mask |= 0x800;
-
-	base_lo = base & ((1ULL<<32) - 1);
-	base_hi = base >> 32;
-
-	mask_lo = mask & ((1ULL<<32) - 1);
-	mask_hi = mask >> 32;
-
-	fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
-}
-
-static void __init
-save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
-		unsigned char type)
-{
-	range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
-	range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
-	range_state[reg].type = type;
-}
-
-static void __init
-set_var_mtrr_all(unsigned int address_bits)
-{
-	unsigned long basek, sizek;
-	unsigned char type;
-	unsigned int reg;
-
-	for (reg = 0; reg < num_var_ranges; reg++) {
-		basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10);
-		sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10);
-		type = range_state[reg].type;
-
-		set_var_mtrr(reg, basek, sizek, type, address_bits);
-	}
-}
-
-static unsigned long to_size_factor(unsigned long sizek, char *factorp)
-{
-	char factor;
-	unsigned long base = sizek;
-
-	if (base & ((1<<10) - 1)) {
-		/* not MB alignment */
-		factor = 'K';
-	} else if (base & ((1<<20) - 1)){
-		factor = 'M';
-		base >>= 10;
-	} else {
-		factor = 'G';
-		base >>= 20;
-	}
-
-	*factorp = factor;
-
-	return base;
-}
-
-static unsigned int __init
-range_to_mtrr(unsigned int reg, unsigned long range_startk,
-	      unsigned long range_sizek, unsigned char type)
-{
-	if (!range_sizek || (reg >= num_var_ranges))
-		return reg;
-
-	while (range_sizek) {
-		unsigned long max_align, align;
-		unsigned long sizek;
-
-		/* Compute the maximum size I can make a range */
-		if (range_startk)
-			max_align = ffs(range_startk) - 1;
-		else
-			max_align = 32;
-		align = fls(range_sizek) - 1;
-		if (align > max_align)
-			align = max_align;
-
-		sizek = 1 << align;
-		if (debug_print) {
-			char start_factor = 'K', size_factor = 'K';
-			unsigned long start_base, size_base;
-
-			start_base = to_size_factor(range_startk, &start_factor),
-			size_base = to_size_factor(sizek, &size_factor),
-
-			printk(KERN_DEBUG "Setting variable MTRR %d, "
-				"base: %ld%cB, range: %ld%cB, type %s\n",
-				reg, start_base, start_factor,
-				size_base, size_factor,
-				(type == MTRR_TYPE_UNCACHABLE)?"UC":
-				    ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
-				);
-		}
-		save_var_mtrr(reg++, range_startk, sizek, type);
-		range_startk += sizek;
-		range_sizek -= sizek;
-		if (reg >= num_var_ranges)
-			break;
-	}
-	return reg;
-}
-
-static unsigned __init
-range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
-			unsigned long sizek)
-{
-	unsigned long hole_basek, hole_sizek;
-	unsigned long second_basek, second_sizek;
-	unsigned long range0_basek, range0_sizek;
-	unsigned long range_basek, range_sizek;
-	unsigned long chunk_sizek;
-	unsigned long gran_sizek;
-
-	hole_basek = 0;
-	hole_sizek = 0;
-	second_basek = 0;
-	second_sizek = 0;
-	chunk_sizek = state->chunk_sizek;
-	gran_sizek = state->gran_sizek;
-
-	/* align with gran size, prevent small block used up MTRRs */
-	range_basek = ALIGN(state->range_startk, gran_sizek);
-	if ((range_basek > basek) && basek)
-		return second_sizek;
-	state->range_sizek -= (range_basek - state->range_startk);
-	range_sizek = ALIGN(state->range_sizek, gran_sizek);
-
-	while (range_sizek > state->range_sizek) {
-		range_sizek -= gran_sizek;
-		if (!range_sizek)
-			return 0;
-	}
-	state->range_sizek = range_sizek;
-
-	/* try to append some small hole */
-	range0_basek = state->range_startk;
-	range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
-
-	/* no increase */
-	if (range0_sizek == state->range_sizek) {
-		if (debug_print)
-			printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
-				range0_basek<<10,
-				(range0_basek + state->range_sizek)<<10);
-		state->reg = range_to_mtrr(state->reg, range0_basek,
-				state->range_sizek, MTRR_TYPE_WRBACK);
-		return 0;
-	}
-
-	/* only cut back, when it is not the last */
-	if (sizek) {
-		while (range0_basek + range0_sizek > (basek + sizek)) {
-			if (range0_sizek >= chunk_sizek)
-				range0_sizek -= chunk_sizek;
-			else
-				range0_sizek = 0;
-
-			if (!range0_sizek)
-				break;
-		}
-	}
-
-second_try:
-	range_basek = range0_basek + range0_sizek;
-
-	/* one hole in the middle */
-	if (range_basek > basek && range_basek <= (basek + sizek))
-		second_sizek = range_basek - basek;
-
-	if (range0_sizek > state->range_sizek) {
-
-		/* one hole in middle or at end */
-		hole_sizek = range0_sizek - state->range_sizek - second_sizek;
-
-		/* hole size should be less than half of range0 size */
-		if (hole_sizek >= (range0_sizek >> 1) &&
-		    range0_sizek >= chunk_sizek) {
-			range0_sizek -= chunk_sizek;
-			second_sizek = 0;
-			hole_sizek = 0;
-
-			goto second_try;
-		}
-	}
-
-	if (range0_sizek) {
-		if (debug_print)
-			printk(KERN_DEBUG "range0: %016lx - %016lx\n",
-				range0_basek<<10,
-				(range0_basek + range0_sizek)<<10);
-		state->reg = range_to_mtrr(state->reg, range0_basek,
-				range0_sizek, MTRR_TYPE_WRBACK);
-	}
-
-	if (range0_sizek < state->range_sizek) {
-		/* need to handle left over */
-		range_sizek = state->range_sizek - range0_sizek;
-
-		if (debug_print)
-			printk(KERN_DEBUG "range: %016lx - %016lx\n",
-				 range_basek<<10,
-				 (range_basek + range_sizek)<<10);
-		state->reg = range_to_mtrr(state->reg, range_basek,
-				 range_sizek, MTRR_TYPE_WRBACK);
-	}
-
-	if (hole_sizek) {
-		hole_basek = range_basek - hole_sizek - second_sizek;
-		if (debug_print)
-			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
-				 hole_basek<<10,
-				 (hole_basek + hole_sizek)<<10);
-		state->reg = range_to_mtrr(state->reg, hole_basek,
-				 hole_sizek, MTRR_TYPE_UNCACHABLE);
-	}
-
-	return second_sizek;
-}
-
-static void __init
-set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
-		   unsigned long size_pfn)
-{
-	unsigned long basek, sizek;
-	unsigned long second_sizek = 0;
-
-	if (state->reg >= num_var_ranges)
-		return;
-
-	basek = base_pfn << (PAGE_SHIFT - 10);
-	sizek = size_pfn << (PAGE_SHIFT - 10);
-
-	/* See if I can merge with the last range */
-	if ((basek <= 1024) ||
-	    (state->range_startk + state->range_sizek == basek)) {
-		unsigned long endk = basek + sizek;
-		state->range_sizek = endk - state->range_startk;
-		return;
-	}
-	/* Write the range mtrrs */
-	if (state->range_sizek != 0)
-		second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
-
-	/* Allocate an msr */
-	state->range_startk = basek + second_sizek;
-	state->range_sizek  = sizek - second_sizek;
-}
-
-/* mininum size of mtrr block that can take hole */
-static u64 mtrr_chunk_size __initdata = (256ULL<<20);
-
-static int __init parse_mtrr_chunk_size_opt(char *p)
-{
-	if (!p)
-		return -EINVAL;
-	mtrr_chunk_size = memparse(p, &p);
-	return 0;
-}
-early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
-
-/* granity of mtrr of block */
-static u64 mtrr_gran_size __initdata;
-
-static int __init parse_mtrr_gran_size_opt(char *p)
-{
-	if (!p)
-		return -EINVAL;
-	mtrr_gran_size = memparse(p, &p);
-	return 0;
-}
-early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
-
-static int nr_mtrr_spare_reg __initdata =
-				 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
-
-static int __init parse_mtrr_spare_reg(char *arg)
-{
-	if (arg)
-		nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
-	return 0;
-}
-
-early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
-
-static int __init
-x86_setup_var_mtrrs(struct res_range *range, int nr_range,
-		    u64 chunk_size, u64 gran_size)
-{
-	struct var_mtrr_state var_state;
-	int i;
-	int num_reg;
-
-	var_state.range_startk	= 0;
-	var_state.range_sizek	= 0;
-	var_state.reg		= 0;
-	var_state.chunk_sizek	= chunk_size >> 10;
-	var_state.gran_sizek	= gran_size >> 10;
-
-	memset(range_state, 0, sizeof(range_state));
-
-	/* Write the range etc */
-	for (i = 0; i < nr_range; i++)
-		set_var_mtrr_range(&var_state, range[i].start,
-				   range[i].end - range[i].start + 1);
-
-	/* Write the last range */
-	if (var_state.range_sizek != 0)
-		range_to_mtrr_with_hole(&var_state, 0, 0);
-
-	num_reg = var_state.reg;
-	/* Clear out the extra MTRR's */
-	while (var_state.reg < num_var_ranges) {
-		save_var_mtrr(var_state.reg, 0, 0, 0);
-		var_state.reg++;
-	}
-
-	return num_reg;
-}
-
-struct mtrr_cleanup_result {
-	unsigned long gran_sizek;
-	unsigned long chunk_sizek;
-	unsigned long lose_cover_sizek;
-	unsigned int num_reg;
-	int bad;
-};
-
-/*
- * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
- * chunk size: gran_size, ..., 2G
- * so we need (1+16)*8
- */
-#define NUM_RESULT	136
-#define PSHIFT		(PAGE_SHIFT - 10)
-
-static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
-static unsigned long __initdata min_loss_pfn[RANGE_NUM];
-
-static void __init print_out_mtrr_range_state(void)
-{
-	int i;
-	char start_factor = 'K', size_factor = 'K';
-	unsigned long start_base, size_base;
-	mtrr_type type;
-
-	for (i = 0; i < num_var_ranges; i++) {
-
-		size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
-		if (!size_base)
-			continue;
-
-		size_base = to_size_factor(size_base, &size_factor),
-		start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
-		start_base = to_size_factor(start_base, &start_factor),
-		type = range_state[i].type;
-
-		printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
-			i, start_base, start_factor,
-			size_base, size_factor,
-			(type == MTRR_TYPE_UNCACHABLE) ? "UC" :
-			    ((type == MTRR_TYPE_WRPROT) ? "WP" :
-			     ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
-			);
-	}
-}
-
-static int __init mtrr_need_cleanup(void)
-{
-	int i;
-	mtrr_type type;
-	unsigned long size;
-	/* extra one for all 0 */
-	int num[MTRR_NUM_TYPES + 1];
-
-	/* check entries number */
-	memset(num, 0, sizeof(num));
-	for (i = 0; i < num_var_ranges; i++) {
-		type = range_state[i].type;
-		size = range_state[i].size_pfn;
-		if (type >= MTRR_NUM_TYPES)
-			continue;
-		if (!size)
-			type = MTRR_NUM_TYPES;
-		if (type == MTRR_TYPE_WRPROT)
-			type = MTRR_TYPE_UNCACHABLE;
-		num[type]++;
-	}
-
-	/* check if we got UC entries */
-	if (!num[MTRR_TYPE_UNCACHABLE])
-		return 0;
-
-	/* check if we only had WB and UC */
-	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
-		num_var_ranges - num[MTRR_NUM_TYPES])
-		return 0;
-
-	return 1;
-}
-
-static unsigned long __initdata range_sums;
-static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
-					 unsigned long extra_remove_base,
-					 unsigned long extra_remove_size,
-					 int i)
-{
-	int num_reg;
-	static struct res_range range_new[RANGE_NUM];
-	static int nr_range_new;
-	unsigned long range_sums_new;
-
-	/* convert ranges to var ranges state */
-	num_reg = x86_setup_var_mtrrs(range, nr_range,
-						chunk_size, gran_size);
-
-	/* we got new setting in range_state, check it */
-	memset(range_new, 0, sizeof(range_new));
-	nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
-				extra_remove_base, extra_remove_size);
-	range_sums_new = sum_ranges(range_new, nr_range_new);
-
-	result[i].chunk_sizek = chunk_size >> 10;
-	result[i].gran_sizek = gran_size >> 10;
-	result[i].num_reg = num_reg;
-	if (range_sums < range_sums_new) {
-		result[i].lose_cover_sizek =
-			(range_sums_new - range_sums) << PSHIFT;
-		result[i].bad = 1;
-	} else
-		result[i].lose_cover_sizek =
-			(range_sums - range_sums_new) << PSHIFT;
-
-	/* double check it */
-	if (!result[i].bad && !result[i].lose_cover_sizek) {
-		if (nr_range_new != nr_range ||
-			memcmp(range, range_new, sizeof(range)))
-				result[i].bad = 1;
-	}
-
-	if (!result[i].bad && (range_sums - range_sums_new <
-				min_loss_pfn[num_reg])) {
-		min_loss_pfn[num_reg] =
-			range_sums - range_sums_new;
-	}
-}
-
-static void __init mtrr_print_out_one_result(int i)
-{
-	char gran_factor, chunk_factor, lose_factor;
-	unsigned long gran_base, chunk_base, lose_base;
-
-	gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
-	chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
-	lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
-	printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
-			result[i].bad ? "*BAD*" : " ",
-			gran_base, gran_factor, chunk_base, chunk_factor);
-	printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
-			result[i].num_reg, result[i].bad ? "-" : "",
-			lose_base, lose_factor);
-}
-
-static int __init mtrr_search_optimal_index(void)
-{
-	int i;
-	int num_reg_good;
-	int index_good;
-
-	if (nr_mtrr_spare_reg >= num_var_ranges)
-		nr_mtrr_spare_reg = num_var_ranges - 1;
-	num_reg_good = -1;
-	for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
-		if (!min_loss_pfn[i])
-			num_reg_good = i;
-	}
-
-	index_good = -1;
-	if (num_reg_good != -1) {
-		for (i = 0; i < NUM_RESULT; i++) {
-			if (!result[i].bad &&
-			    result[i].num_reg == num_reg_good &&
-			    !result[i].lose_cover_sizek) {
-				index_good = i;
-				break;
-			}
-		}
-	}
-
-	return index_good;
-}
-
-
-static int __init mtrr_cleanup(unsigned address_bits)
-{
-	unsigned long extra_remove_base, extra_remove_size;
-	unsigned long base, size, def, dummy;
-	mtrr_type type;
-	u64 chunk_size, gran_size;
-	int index_good;
-	int i;
-
-	if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
-		return 0;
-	rdmsr(MTRRdefType_MSR, def, dummy);
-	def &= 0xff;
-	if (def != MTRR_TYPE_UNCACHABLE)
-		return 0;
-
-	/* get it and store it aside */
-	memset(range_state, 0, sizeof(range_state));
-	for (i = 0; i < num_var_ranges; i++) {
-		mtrr_if->get(i, &base, &size, &type);
-		range_state[i].base_pfn = base;
-		range_state[i].size_pfn = size;
-		range_state[i].type = type;
-	}
-
-	/* check if we need handle it and can handle it */
-	if (!mtrr_need_cleanup())
-		return 0;
-
-	/* print original var MTRRs at first, for debugging: */
-	printk(KERN_DEBUG "original variable MTRRs\n");
-	print_out_mtrr_range_state();
-
-	memset(range, 0, sizeof(range));
-	extra_remove_size = 0;
-	extra_remove_base = 1 << (32 - PAGE_SHIFT);
-	if (mtrr_tom2)
-		extra_remove_size =
-			(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
-	nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
-					  extra_remove_size);
-	/*
-	 * [0, 1M) should always be coverred by var mtrr with WB
-	 * and fixed mtrrs should take effective before var mtrr for it
-	 */
-	nr_range = add_range_with_merge(range, nr_range, 0,
-					(1ULL<<(20 - PAGE_SHIFT)) - 1);
-	/* sort the ranges */
-	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
-
-	range_sums = sum_ranges(range, nr_range);
-	printk(KERN_INFO "total RAM coverred: %ldM\n",
-	       range_sums >> (20 - PAGE_SHIFT));
-
-	if (mtrr_chunk_size && mtrr_gran_size) {
-		i = 0;
-		mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
-				      extra_remove_base, extra_remove_size, i);
-
-		mtrr_print_out_one_result(i);
-
-		if (!result[i].bad) {
-			set_var_mtrr_all(address_bits);
-			return 1;
-		}
-		printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
-		       "will find optimal one\n");
-	}
-
-	i = 0;
-	memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
-	memset(result, 0, sizeof(result));
-	for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
-
-		for (chunk_size = gran_size; chunk_size < (1ULL<<32);
-		     chunk_size <<= 1) {
-
-			if (i >= NUM_RESULT)
-				continue;
-
-			mtrr_calc_range_state(chunk_size, gran_size,
-				      extra_remove_base, extra_remove_size, i);
-			if (debug_print) {
-				mtrr_print_out_one_result(i);
-				printk(KERN_INFO "\n");
-			}
-
-			i++;
-		}
-	}
-
-	/* try to find the optimal index */
-	index_good = mtrr_search_optimal_index();
-
-	if (index_good != -1) {
-		printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
-		i = index_good;
-		mtrr_print_out_one_result(i);
-
-		/* convert ranges to var ranges state */
-		chunk_size = result[i].chunk_sizek;
-		chunk_size <<= 10;
-		gran_size = result[i].gran_sizek;
-		gran_size <<= 10;
-		x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
-		set_var_mtrr_all(address_bits);
-		printk(KERN_DEBUG "New variable MTRRs\n");
-		print_out_mtrr_range_state();
-		return 1;
-	} else {
-		/* print out all */
-		for (i = 0; i < NUM_RESULT; i++)
-			mtrr_print_out_one_result(i);
-	}
-
-	printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
-	printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
-
-	return 0;
-}
-#else
-static int __init mtrr_cleanup(unsigned address_bits)
-{
-	return 0;
-}
-#endif
-
-static int __initdata changed_by_mtrr_cleanup;
-
-static int disable_mtrr_trim;
-
-static int __init disable_mtrr_trim_setup(char *str)
-{
-	disable_mtrr_trim = 1;
-	return 0;
-}
-early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
-
-/*
- * Newer AMD K8s and later CPUs have a special magic MSR way to force WB
- * for memory >4GB. Check for that here.
- * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
- * apply to are wrong, but so far we don't know of any such case in the wild.
- */
-#define Tom2Enabled (1U << 21)
-#define Tom2ForceMemTypeWB (1U << 22)
-
-int __init amd_special_default_mtrr(void)
-{
-	u32 l, h;
-
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
-		return 0;
-	if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
-		return 0;
-	/* In case some hypervisor doesn't pass SYSCFG through */
-	if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
-		return 0;
-	/*
-	 * Memory between 4GB and top of mem is forced WB by this magic bit.
-	 * Reserved before K8RevF, but should be zero there.
-	 */
-	if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
-		 (Tom2Enabled | Tom2ForceMemTypeWB))
-		return 1;
-	return 0;
-}
-
-static u64 __init real_trim_memory(unsigned long start_pfn,
-				   unsigned long limit_pfn)
-{
-	u64 trim_start, trim_size;
-	trim_start = start_pfn;
-	trim_start <<= PAGE_SHIFT;
-	trim_size = limit_pfn;
-	trim_size <<= PAGE_SHIFT;
-	trim_size -= trim_start;
-
-	return e820_update_range(trim_start, trim_size, E820_RAM,
-				E820_RESERVED);
-}
-/**
- * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
- * @end_pfn: ending page frame number
- *
- * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
- * memory configurations.  This routine checks that the highest MTRR matches
- * the end of memory, to make sure the MTRRs having a write back type cover
- * all of the memory the kernel is intending to use. If not, it'll trim any
- * memory off the end by adjusting end_pfn, removing it from the kernel's
- * allocation pools, warning the user with an obnoxious message.
- */
-int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
-{
-	unsigned long i, base, size, highest_pfn = 0, def, dummy;
-	mtrr_type type;
-	u64 total_trim_size;
-
-	/* extra one for all 0 */
-	int num[MTRR_NUM_TYPES + 1];
-	/*
-	 * Make sure we only trim uncachable memory on machines that
-	 * support the Intel MTRR architecture:
-	 */
-	if (!is_cpu(INTEL) || disable_mtrr_trim)
-		return 0;
-	rdmsr(MTRRdefType_MSR, def, dummy);
-	def &= 0xff;
-	if (def != MTRR_TYPE_UNCACHABLE)
-		return 0;
-
-	/* get it and store it aside */
-	memset(range_state, 0, sizeof(range_state));
-	for (i = 0; i < num_var_ranges; i++) {
-		mtrr_if->get(i, &base, &size, &type);
-		range_state[i].base_pfn = base;
-		range_state[i].size_pfn = size;
-		range_state[i].type = type;
-	}
-
-	/* Find highest cached pfn */
-	for (i = 0; i < num_var_ranges; i++) {
-		type = range_state[i].type;
-		if (type != MTRR_TYPE_WRBACK)
-			continue;
-		base = range_state[i].base_pfn;
-		size = range_state[i].size_pfn;
-		if (highest_pfn < base + size)
-			highest_pfn = base + size;
-	}
-
-	/* kvm/qemu doesn't have mtrr set right, don't trim them all */
-	if (!highest_pfn) {
-		printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
-		return 0;
-	}
-
-	/* check entries number */
-	memset(num, 0, sizeof(num));
-	for (i = 0; i < num_var_ranges; i++) {
-		type = range_state[i].type;
-		if (type >= MTRR_NUM_TYPES)
-			continue;
-		size = range_state[i].size_pfn;
-		if (!size)
-			type = MTRR_NUM_TYPES;
-		num[type]++;
-	}
-
-	/* no entry for WB? */
-	if (!num[MTRR_TYPE_WRBACK])
-		return 0;
-
-	/* check if we only had WB and UC */
-	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
-		num_var_ranges - num[MTRR_NUM_TYPES])
-		return 0;
-
-	memset(range, 0, sizeof(range));
-	nr_range = 0;
-	if (mtrr_tom2) {
-		range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT));
-		range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1;
-		if (highest_pfn < range[nr_range].end + 1)
-			highest_pfn = range[nr_range].end + 1;
-		nr_range++;
-	}
-	nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
-
-	total_trim_size = 0;
-	/* check the head */
-	if (range[0].start)
-		total_trim_size += real_trim_memory(0, range[0].start);
-	/* check the holes */
-	for (i = 0; i < nr_range - 1; i++) {
-		if (range[i].end + 1 < range[i+1].start)
-			total_trim_size += real_trim_memory(range[i].end + 1,
-							    range[i+1].start);
-	}
-	/* check the top */
-	i = nr_range - 1;
-	if (range[i].end + 1 < end_pfn)
-		total_trim_size += real_trim_memory(range[i].end + 1,
-							 end_pfn);
-
-	if (total_trim_size) {
-		printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
-			" all of memory, losing %lluMB of RAM.\n",
-			total_trim_size >> 20);
-
-		if (!changed_by_mtrr_cleanup)
-			WARN_ON(1);
-
-		printk(KERN_INFO "update e820 for mtrr\n");
-		update_e820();
-
-		return 1;
-	}
-
-	return 0;
-}
+int __initdata changed_by_mtrr_cleanup;
 
 /**
  * mtrr_bp_init - initialize mtrrs on the boot CPU
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,3 +1,3 @@
-obj-y		:= main.o if.o generic.o state.o
+obj-y		:= main.o if.o generic.o state.o cleanup.o
 obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mtrr/mtrr.h	2009-06-09 23:05:27.000000000 -0400
@@ -79,6 +79,7 @@ extern struct mtrr_ops * mtrr_if;
 
 extern unsigned int num_var_ranges;
 extern u64 mtrr_tom2;
+extern struct mtrr_state_type mtrr_state;
 
 void mtrr_state_warn(void);
 const char *mtrr_attrib_to_str(int x);
@@ -88,3 +89,6 @@ void mtrr_wrmsr(unsigned, unsigned, unsi
 int amd_init_mtrr(void);
 int cyrix_init_mtrr(void);
 int centaur_init_mtrr(void);
+
+extern int changed_by_mtrr_cleanup;
+extern int mtrr_cleanup(unsigned address_bits);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/perfctr-watchdog.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/nmi.h>
 #include <linux/kprobes.h>
 
-#include <asm/apic.h>
+#include <asm/genapic.h>
 #include <asm/intel_arch_perfmon.h>
 
 struct nmi_watchdog_ctlblk {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/proc.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/proc.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,15 +7,14 @@
 /*
  *	Get CPU information for use by the procfs.
  */
-#ifdef CONFIG_X86_32
 static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
 			      unsigned int cpu)
 {
-#ifdef CONFIG_X86_HT
+#ifdef CONFIG_SMP
 	if (c->x86_max_cores * smp_num_siblings > 1) {
 		seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
 		seq_printf(m, "siblings\t: %d\n",
-			   cpus_weight(per_cpu(cpu_core_map, cpu)));
+			   cpumask_weight(cpu_core_mask(cpu)));
 		seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
 		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 		seq_printf(m, "apicid\t\t: %d\n", c->apicid);
@@ -24,6 +23,7 @@ static void show_cpuinfo_core(struct seq
 #endif
 }
 
+#ifdef CONFIG_X86_32
 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 {
 	/*
@@ -50,22 +50,6 @@ static void show_cpuinfo_misc(struct seq
 		   c->wp_works_ok ? "yes" : "no");
 }
 #else
-static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
-			      unsigned int cpu)
-{
-#ifdef CONFIG_SMP
-	if (c->x86_max_cores * smp_num_siblings > 1) {
-		seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
-		seq_printf(m, "siblings\t: %d\n",
-			   cpus_weight(per_cpu(cpu_core_map, cpu)));
-		seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
-		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
-		seq_printf(m, "apicid\t\t: %d\n", c->apicid);
-		seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid);
-	}
-#endif
-}
-
 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 {
 	seq_printf(m,
@@ -159,9 +143,9 @@ static int show_cpuinfo(struct seq_file
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
 	if (*pos == 0)	/* just in case, cpu 0 is not the first */
-		*pos = first_cpu(cpu_online_map);
+		*pos = cpumask_first(cpu_online_mask);
 	else
-		*pos = next_cpu_nr(*pos - 1, cpu_online_map);
+		*pos = cpumask_next(*pos - 1, cpu_online_mask);
 	if ((*pos) < nr_cpu_ids)
 		return &cpu_data(*pos);
 	return NULL;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/transmeta.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/transmeta.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/transmeta.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/transmeta.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,7 +98,7 @@ static void __cpuinit init_transmeta(str
 #endif
 }
 
-static struct cpu_dev transmeta_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst transmeta_cpu_dev = {
 	.c_vendor	= "Transmeta",
 	.c_ident	= { "GenuineTMx86", "TransmetaCPU" },
 	.c_early_init	= early_init_transmeta,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/umc.c linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/umc.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/cpu/umc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/umc.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * so no special init takes place.
  */
 
-static struct cpu_dev umc_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst umc_cpu_dev = {
 	.c_vendor	= "UMC",
 	.c_ident	= { "UMC UMC UMC" },
 	.c_models = {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/crash.c linux-libre-2.6.30-gnu1/arch/x86/kernel/crash.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/crash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/crash.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,12 +24,10 @@
 #include <asm/apic.h>
 #include <asm/hpet.h>
 #include <linux/kdebug.h>
-#include <asm/smp.h>
+#include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
 
-#include <mach_ipi.h>
-
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/dumpstack_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/dumpstack_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/dumpstack_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/dumpstack_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -106,7 +106,8 @@ void dump_trace(struct task_struct *task
 		const struct stacktrace_ops *ops, void *data)
 {
 	const unsigned cpu = get_cpu();
-	unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
+	unsigned long *irq_stack_end =
+		(unsigned long *)per_cpu(irq_stack_ptr, cpu);
 	unsigned used = 0;
 	struct thread_info *tinfo;
 	int graph = 0;
@@ -160,23 +161,23 @@ void dump_trace(struct task_struct *task
 			stack = (unsigned long *) estack_end[-2];
 			continue;
 		}
-		if (irqstack_end) {
-			unsigned long *irqstack;
-			irqstack = irqstack_end -
-				(IRQSTACKSIZE - 64) / sizeof(*irqstack);
+		if (irq_stack_end) {
+			unsigned long *irq_stack;
+			irq_stack = irq_stack_end -
+				(IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);
 
-			if (stack >= irqstack && stack < irqstack_end) {
+			if (stack >= irq_stack && stack < irq_stack_end) {
 				if (ops->stack(data, "IRQ") < 0)
 					break;
 				bp = print_context_stack(tinfo, stack, bp,
-					ops, data, irqstack_end, &graph);
+					ops, data, irq_stack_end, &graph);
 				/*
 				 * We link to the next stack (which would be
 				 * the process stack normally) the last
 				 * pointer (index -1 to end) in the IRQ stack:
 				 */
-				stack = (unsigned long *) (irqstack_end[-1]);
-				irqstack_end = NULL;
+				stack = (unsigned long *) (irq_stack_end[-1]);
+				irq_stack_end = NULL;
 				ops->stack(data, "EOI");
 				continue;
 			}
@@ -199,10 +200,10 @@ show_stack_log_lvl(struct task_struct *t
 	unsigned long *stack;
 	int i;
 	const int cpu = smp_processor_id();
-	unsigned long *irqstack_end =
-		(unsigned long *) (cpu_pda(cpu)->irqstackptr);
-	unsigned long *irqstack =
-		(unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
+	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);
 
 	/*
 	 * debugging aid: "show_stack(NULL, NULL);" prints the
@@ -218,9 +219,9 @@ show_stack_log_lvl(struct task_struct *t
 
 	stack = sp;
 	for (i = 0; i < kstack_depth_to_print; i++) {
-		if (stack >= irqstack && stack <= irqstack_end) {
-			if (stack == irqstack_end) {
-				stack = (unsigned long *) (irqstack_end[-1]);
+		if (stack >= irq_stack && stack <= irq_stack_end) {
+			if (stack == irq_stack_end) {
+				stack = (unsigned long *) (irq_stack_end[-1]);
 				printk(" <EOI> ");
 			}
 		} else {
@@ -241,7 +242,7 @@ void show_registers(struct pt_regs *regs
 	int i;
 	unsigned long sp;
 	const int cpu = smp_processor_id();
-	struct task_struct *cur = cpu_pda(cpu)->pcurrent;
+	struct task_struct *cur = current;
 
 	sp = regs->sp;
 	printk("CPU %d ", cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/dumpstack.c linux-libre-2.6.30-gnu1/arch/x86/kernel/dumpstack.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/dumpstack.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/dumpstack.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,10 +10,12 @@
 #include <linux/kdebug.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
+#include <linux/ftrace.h>
 #include <linux/kexec.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
 #include <linux/sysfs.h>
+#include <linux/ftrace.h>
 
 #include <asm/stacktrace.h>
 
@@ -99,7 +101,7 @@ print_context_stack(struct thread_info *
 				frame = frame->next_frame;
 				bp = (unsigned long) frame;
 			} else {
-				ops->address(data, addr, bp == 0);
+				ops->address(data, addr, 0);
 			}
 			print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
 		}
@@ -195,6 +197,11 @@ unsigned __kprobes long oops_begin(void)
 	int cpu;
 	unsigned long flags;
 
+	/* notify the hw-branch tracer so it may disable tracing and
+	   add the last trace to the trace buffer -
+	   the earlier this happens, the more useful the trace. */
+	trace_hw_branch_oops();
+
 	oops_enter();
 
 	/* racy, but better than risking deadlock. */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/e820.c linux-libre-2.6.30-gnu1/arch/x86/kernel/e820.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/e820.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/e820.c	2009-06-09 23:05:27.000000000 -0400
@@ -110,19 +110,50 @@ int __init e820_all_mapped(u64 start, u6
 /*
  * Add a memory region to the kernel e820 map.
  */
-void __init e820_add_region(u64 start, u64 size, int type)
+static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
+					 int type)
 {
-	int x = e820.nr_map;
+	int x = e820x->nr_map;
 
-	if (x == ARRAY_SIZE(e820.map)) {
+	if (x == ARRAY_SIZE(e820x->map)) {
 		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
 		return;
 	}
 
-	e820.map[x].addr = start;
-	e820.map[x].size = size;
-	e820.map[x].type = type;
-	e820.nr_map++;
+	e820x->map[x].addr = start;
+	e820x->map[x].size = size;
+	e820x->map[x].type = type;
+	e820x->nr_map++;
+}
+
+void __init e820_add_region(u64 start, u64 size, int type)
+{
+	__e820_add_region(&e820, start, size, type);
+}
+
+static void __init e820_print_type(u32 type)
+{
+	switch (type) {
+	case E820_RAM:
+	case E820_RESERVED_KERN:
+		printk(KERN_CONT "(usable)");
+		break;
+	case E820_RESERVED:
+		printk(KERN_CONT "(reserved)");
+		break;
+	case E820_ACPI:
+		printk(KERN_CONT "(ACPI data)");
+		break;
+	case E820_NVS:
+		printk(KERN_CONT "(ACPI NVS)");
+		break;
+	case E820_UNUSABLE:
+		printk(KERN_CONT "(unusable)");
+		break;
+	default:
+		printk(KERN_CONT "type %u", type);
+		break;
+	}
 }
 
 void __init e820_print_map(char *who)
@@ -134,27 +165,8 @@ void __init e820_print_map(char *who)
 		       (unsigned long long) e820.map[i].addr,
 		       (unsigned long long)
 		       (e820.map[i].addr + e820.map[i].size));
-		switch (e820.map[i].type) {
-		case E820_RAM:
-		case E820_RESERVED_KERN:
-			printk(KERN_CONT "(usable)\n");
-			break;
-		case E820_RESERVED:
-			printk(KERN_CONT "(reserved)\n");
-			break;
-		case E820_ACPI:
-			printk(KERN_CONT "(ACPI data)\n");
-			break;
-		case E820_NVS:
-			printk(KERN_CONT "(ACPI NVS)\n");
-			break;
-		case E820_UNUSABLE:
-			printk("(unusable)\n");
-			break;
-		default:
-			printk(KERN_CONT "type %u\n", e820.map[i].type);
-			break;
-		}
+		e820_print_type(e820.map[i].type);
+		printk(KERN_CONT "\n");
 	}
 }
 
@@ -221,7 +233,7 @@ void __init e820_print_map(char *who)
  */
 
 int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
-				int *pnr_map)
+			     u32 *pnr_map)
 {
 	struct change_member {
 		struct e820entry *pbios; /* pointer to original bios entry */
@@ -417,11 +429,12 @@ static int __init append_e820_map(struct
 	return __append_e820_map(biosmap, nr_map);
 }
 
-static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
+static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
 					u64 size, unsigned old_type,
 					unsigned new_type)
 {
-	int i;
+	u64 end;
+	unsigned int i;
 	u64 real_updated_size = 0;
 
 	BUG_ON(old_type == new_type);
@@ -429,27 +442,55 @@ static u64 __init e820_update_range_map(
 	if (size > (ULLONG_MAX - start))
 		size = ULLONG_MAX - start;
 
-	for (i = 0; i < e820.nr_map; i++) {
+	end = start + size;
+	printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ",
+		       (unsigned long long) start,
+		       (unsigned long long) end);
+	e820_print_type(old_type);
+	printk(KERN_CONT " ==> ");
+	e820_print_type(new_type);
+	printk(KERN_CONT "\n");
+
+	for (i = 0; i < e820x->nr_map; i++) {
 		struct e820entry *ei = &e820x->map[i];
 		u64 final_start, final_end;
+		u64 ei_end;
+
 		if (ei->type != old_type)
 			continue;
-		/* totally covered? */
-		if (ei->addr >= start &&
-		    (ei->addr + ei->size) <= (start + size)) {
+
+		ei_end = ei->addr + ei->size;
+		/* totally covered by new range? */
+		if (ei->addr >= start && ei_end <= end) {
 			ei->type = new_type;
 			real_updated_size += ei->size;
 			continue;
 		}
+
+		/* new range is totally covered? */
+		if (ei->addr < start && ei_end > end) {
+			__e820_add_region(e820x, start, size, new_type);
+			__e820_add_region(e820x, end, ei_end - end, ei->type);
+			ei->size = start - ei->addr;
+			real_updated_size += size;
+			continue;
+		}
+
 		/* partially covered */
 		final_start = max(start, ei->addr);
-		final_end = min(start + size, ei->addr + ei->size);
+		final_end = min(end, ei_end);
 		if (final_start >= final_end)
 			continue;
-		e820_add_region(final_start, final_end - final_start,
-					 new_type);
+
+		__e820_add_region(e820x, final_start, final_end - final_start,
+				  new_type);
+
 		real_updated_size += final_end - final_start;
 
+		/*
+		 * left range could be head or tail, so need to update
+		 * size at first.
+		 */
 		ei->size -= final_end - final_start;
 		if (ei->addr < final_start)
 			continue;
@@ -461,13 +502,13 @@ static u64 __init e820_update_range_map(
 u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
 			     unsigned new_type)
 {
-	return e820_update_range_map(&e820, start, size, old_type, new_type);
+	return __e820_update_range(&e820, start, size, old_type, new_type);
 }
 
 static u64 __init e820_update_range_saved(u64 start, u64 size,
 					  unsigned old_type, unsigned new_type)
 {
-	return e820_update_range_map(&e820_saved, start, size, old_type,
+	return __e820_update_range(&e820_saved, start, size, old_type,
 				     new_type);
 }
 
@@ -511,7 +552,7 @@ u64 __init e820_remove_range(u64 start,
 
 void __init update_e820(void)
 {
-	int nr_map;
+	u32 nr_map;
 
 	nr_map = e820.nr_map;
 	if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
@@ -522,7 +563,7 @@ void __init update_e820(void)
 }
 static void __init update_e820_saved(void)
 {
-	int nr_map;
+	u32 nr_map;
 
 	nr_map = e820_saved.nr_map;
 	if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
@@ -858,6 +899,9 @@ void __init reserve_early_overlap_ok(u64
  */
 void __init reserve_early(u64 start, u64 end, char *name)
 {
+	if (start >= end)
+		return;
+
 	drop_overlaps_that_are_ok(start, end);
 	__reserve_early(start, end, name, 0);
 }
@@ -1017,8 +1061,8 @@ u64 __init find_e820_area_size(u64 start
 			continue;
 		return addr;
 	}
-	return -1UL;
 
+	return -1ULL;
 }
 
 /*
@@ -1030,14 +1074,24 @@ u64 __init early_reserve_e820(u64 startt
 	u64 addr;
 	u64 start;
 
-	start = startt;
-	while (size < sizet)
+	for (start = startt; ; start += size) {
 		start = find_e820_area_size(start, &size, align);
+		if (!(start + 1))
+			return 0;
+		if (size >= sizet)
+			break;
+	}
 
-	if (size < sizet)
+#ifdef CONFIG_X86_32
+	if (start >= MAXMEM)
 		return 0;
+	if (start + size > MAXMEM)
+		size = MAXMEM - start;
+#endif
 
 	addr = round_down(start + size - sizet, align);
+	if (addr < start)
+		return 0;
 	e820_update_range(addr, sizet, E820_RAM, E820_RESERVED);
 	e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
 	printk(KERN_INFO "update e820 for early_reserve_e820\n");
@@ -1250,7 +1304,7 @@ early_param("memmap", parse_memmap_opt);
 void __init finish_e820_parsing(void)
 {
 	if (userdef) {
-		int nr = e820.nr_map;
+		u32 nr = e820.nr_map;
 
 		if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
 			early_panic("Invalid user supplied memory map");
@@ -1333,7 +1387,7 @@ void __init e820_reserve_resources_late(
 char *__init default_machine_specific_memory_setup(void)
 {
 	char *who = "BIOS-e820";
-	int new_nr;
+	u32 new_nr;
 	/*
 	 * Try to copy the BIOS-supplied E820-map.
 	 *
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/early_printk.c linux-libre-2.6.30-gnu1/arch/x86/kernel/early_printk.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/early_printk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/early_printk.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,8 +13,8 @@
 #include <asm/setup.h>
 #include <xen/hvc-console.h>
 #include <asm/pci-direct.h>
-#include <asm/pgtable.h>
 #include <asm/fixmap.h>
+#include <asm/pgtable.h>
 #include <linux/usb/ehci_def.h>
 
 /* Simple VGA output */
@@ -250,7 +250,7 @@ static int dbgp_wait_until_complete(void
 	return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);
 }
 
-static void dbgp_mdelay(int ms)
+static void __init dbgp_mdelay(int ms)
 {
 	int i;
 
@@ -311,7 +311,7 @@ static void dbgp_set_data(const void *bu
 	writel(hi, &ehci_debug->data47);
 }
 
-static void dbgp_get_data(void *buf, int size)
+static void __init dbgp_get_data(void *buf, int size)
 {
 	unsigned char *bytes = buf;
 	u32 lo, hi;
@@ -355,7 +355,7 @@ static int dbgp_bulk_write(unsigned devn
 	return ret;
 }
 
-static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
+static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
 				 int size)
 {
 	u32 pids, addr, ctrl;
@@ -386,8 +386,8 @@ static int dbgp_bulk_read(unsigned devnu
 	return ret;
 }
 
-static int dbgp_control_msg(unsigned devnum, int requesttype, int request,
-	int value, int index, void *data, int size)
+static int __init dbgp_control_msg(unsigned devnum, int requesttype,
+	int request, int value, int index, void *data, int size)
 {
 	u32 pids, addr, ctrl;
 	struct usb_ctrlrequest req;
@@ -489,7 +489,7 @@ static u32 __init find_dbgp(int ehci_num
 	return 0;
 }
 
-static int ehci_reset_port(int port)
+static int __init ehci_reset_port(int port)
 {
 	u32 portsc;
 	u32 delay_time, delay;
@@ -532,7 +532,7 @@ static int ehci_reset_port(int port)
 	return -EBUSY;
 }
 
-static int ehci_wait_for_port(int port)
+static int __init ehci_wait_for_port(int port)
 {
 	u32 status;
 	int ret, reps;
@@ -557,13 +557,13 @@ static inline void dbgp_printk(const cha
 
 typedef void (*set_debug_port_t)(int port);
 
-static void default_set_debug_port(int port)
+static void __init default_set_debug_port(int port)
 {
 }
 
-static set_debug_port_t set_debug_port = default_set_debug_port;
+static set_debug_port_t __initdata set_debug_port = default_set_debug_port;
 
-static void nvidia_set_debug_port(int port)
+static void __init nvidia_set_debug_port(int port)
 {
 	u32 dword;
 	dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@
 #include <asm/proto.h>
 #include <asm/efi.h>
 #include <asm/cacheflush.h>
+#include <asm/fixmap.h>
 
 static pgd_t save_pgd __initdata;
 static unsigned long efi_flags __initdata;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/efi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/efi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/efi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/efi.c	2009-06-09 23:05:27.000000000 -0400
@@ -366,10 +366,12 @@ void __init efi_init(void)
 					SMBIOS_TABLE_GUID)) {
 			efi.smbios = config_tables[i].table;
 			printk(" SMBIOS=0x%lx ", config_tables[i].table);
+#ifdef CONFIG_X86_UV
 		} else if (!efi_guidcmp(config_tables[i].guid,
 					UV_SYSTEM_TABLE_GUID)) {
 			efi.uv_systab = config_tables[i].table;
 			printk(" UVsystab=0x%lx ", config_tables[i].table);
+#endif
 		} else if (!efi_guidcmp(config_tables[i].guid,
 					HCDP_TABLE_GUID)) {
 			efi.hcdp = config_tables[i].table;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_stub_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_stub_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_stub_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_stub_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  */
 
 #include <linux/linkage.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 
 /*
  * efi_call_phys(void *, ...) is a function with variable parameters.
@@ -113,6 +113,7 @@ ENTRY(efi_call_phys)
 	movl	(%edx), %ecx
 	pushl	%ecx
 	ret
+ENDPROC(efi_call_phys)
 .previous
 
 .data
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_stub_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_stub_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/efi_stub_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/efi_stub_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,7 @@ ENTRY(efi_call0)
 	addq $32, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call0)
 
 ENTRY(efi_call1)
 	SAVE_XMM
@@ -50,6 +51,7 @@ ENTRY(efi_call1)
 	addq $32, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call1)
 
 ENTRY(efi_call2)
 	SAVE_XMM
@@ -59,6 +61,7 @@ ENTRY(efi_call2)
 	addq $32, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call2)
 
 ENTRY(efi_call3)
 	SAVE_XMM
@@ -69,6 +72,7 @@ ENTRY(efi_call3)
 	addq $32, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call3)
 
 ENTRY(efi_call4)
 	SAVE_XMM
@@ -80,6 +84,7 @@ ENTRY(efi_call4)
 	addq $32, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call4)
 
 ENTRY(efi_call5)
 	SAVE_XMM
@@ -92,6 +97,7 @@ ENTRY(efi_call5)
 	addq $48, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call5)
 
 ENTRY(efi_call6)
 	SAVE_XMM
@@ -107,3 +113,4 @@ ENTRY(efi_call6)
 	addq $48, %rsp
 	RESTORE_XMM
 	ret
+ENDPROC(efi_call6)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/entry_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/entry_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/entry_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/entry_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -30,12 +30,13 @@
  *	1C(%esp) - %ds
  *	20(%esp) - %es
  *	24(%esp) - %fs
- *	28(%esp) - orig_eax
- *	2C(%esp) - %eip
- *	30(%esp) - %cs
- *	34(%esp) - %eflags
- *	38(%esp) - %oldesp
- *	3C(%esp) - %oldss
+ *	28(%esp) - %gs		saved iff !CONFIG_X86_32_LAZY_GS
+ *	2C(%esp) - orig_eax
+ *	30(%esp) - %eip
+ *	34(%esp) - %cs
+ *	38(%esp) - %eflags
+ *	3C(%esp) - %oldesp
+ *	40(%esp) - %oldss
  *
  * "current" is in register %ebx during any slow entries.
  */
@@ -46,7 +47,7 @@
 #include <asm/errno.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/desc.h>
 #include <asm/percpu.h>
 #include <asm/dwarf2.h>
@@ -101,121 +102,221 @@
 #define resume_userspace_sig	resume_userspace
 #endif
 
-#define SAVE_ALL \
-	cld; \
-	pushl %fs; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	/*CFI_REL_OFFSET fs, 0;*/\
-	pushl %es; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	/*CFI_REL_OFFSET es, 0;*/\
-	pushl %ds; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	/*CFI_REL_OFFSET ds, 0;*/\
-	pushl %eax; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET eax, 0;\
-	pushl %ebp; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET ebp, 0;\
-	pushl %edi; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET edi, 0;\
-	pushl %esi; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET esi, 0;\
-	pushl %edx; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET edx, 0;\
-	pushl %ecx; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET ecx, 0;\
-	pushl %ebx; \
-	CFI_ADJUST_CFA_OFFSET 4;\
-	CFI_REL_OFFSET ebx, 0;\
-	movl $(__USER_DS), %edx; \
-	movl %edx, %ds; \
-	movl %edx, %es; \
-	movl $(__KERNEL_PERCPU), %edx; \
+/*
+ * User gs save/restore
+ *
+ * %gs is used for userland TLS and kernel only uses it for stack
+ * canary which is required to be at %gs:20 by gcc.  Read the comment
+ * at the top of stackprotector.h for more info.
+ *
+ * Local labels 98 and 99 are used.
+ */
+#ifdef CONFIG_X86_32_LAZY_GS
+
+ /* unfortunately push/pop can't be no-op */
+.macro PUSH_GS
+	pushl $0
+	CFI_ADJUST_CFA_OFFSET 4
+.endm
+.macro POP_GS pop=0
+	addl $(4 + \pop), %esp
+	CFI_ADJUST_CFA_OFFSET -(4 + \pop)
+.endm
+.macro POP_GS_EX
+.endm
+
+ /* all the rest are no-op */
+.macro PTGS_TO_GS
+.endm
+.macro PTGS_TO_GS_EX
+.endm
+.macro GS_TO_REG reg
+.endm
+.macro REG_TO_PTGS reg
+.endm
+.macro SET_KERNEL_GS reg
+.endm
+
+#else	/* CONFIG_X86_32_LAZY_GS */
+
+.macro PUSH_GS
+	pushl %gs
+	CFI_ADJUST_CFA_OFFSET 4
+	/*CFI_REL_OFFSET gs, 0*/
+.endm
+
+.macro POP_GS pop=0
+98:	popl %gs
+	CFI_ADJUST_CFA_OFFSET -4
+	/*CFI_RESTORE gs*/
+  .if \pop <> 0
+	add $\pop, %esp
+	CFI_ADJUST_CFA_OFFSET -\pop
+  .endif
+.endm
+.macro POP_GS_EX
+.pushsection .fixup, "ax"
+99:	movl $0, (%esp)
+	jmp 98b
+.section __ex_table, "a"
+	.align 4
+	.long 98b, 99b
+.popsection
+.endm
+
+.macro PTGS_TO_GS
+98:	mov PT_GS(%esp), %gs
+.endm
+.macro PTGS_TO_GS_EX
+.pushsection .fixup, "ax"
+99:	movl $0, PT_GS(%esp)
+	jmp 98b
+.section __ex_table, "a"
+	.align 4
+	.long 98b, 99b
+.popsection
+.endm
+
+.macro GS_TO_REG reg
+	movl %gs, \reg
+	/*CFI_REGISTER gs, \reg*/
+.endm
+.macro REG_TO_PTGS reg
+	movl \reg, PT_GS(%esp)
+	/*CFI_REL_OFFSET gs, PT_GS*/
+.endm
+.macro SET_KERNEL_GS reg
+	movl $(__KERNEL_STACK_CANARY), \reg
+	movl \reg, %gs
+.endm
+
+#endif	/* CONFIG_X86_32_LAZY_GS */
+
+.macro SAVE_ALL
+	cld
+	PUSH_GS
+	pushl %fs
+	CFI_ADJUST_CFA_OFFSET 4
+	/*CFI_REL_OFFSET fs, 0;*/
+	pushl %es
+	CFI_ADJUST_CFA_OFFSET 4
+	/*CFI_REL_OFFSET es, 0;*/
+	pushl %ds
+	CFI_ADJUST_CFA_OFFSET 4
+	/*CFI_REL_OFFSET ds, 0;*/
+	pushl %eax
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET eax, 0
+	pushl %ebp
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET ebp, 0
+	pushl %edi
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET edi, 0
+	pushl %esi
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET esi, 0
+	pushl %edx
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET edx, 0
+	pushl %ecx
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET ecx, 0
+	pushl %ebx
+	CFI_ADJUST_CFA_OFFSET 4
+	CFI_REL_OFFSET ebx, 0
+	movl $(__USER_DS), %edx
+	movl %edx, %ds
+	movl %edx, %es
+	movl $(__KERNEL_PERCPU), %edx
 	movl %edx, %fs
+	SET_KERNEL_GS %edx
+.endm
 
-#define RESTORE_INT_REGS \
-	popl %ebx;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE ebx;\
-	popl %ecx;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE ecx;\
-	popl %edx;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE edx;\
-	popl %esi;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE esi;\
-	popl %edi;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE edi;\
-	popl %ebp;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	CFI_RESTORE ebp;\
-	popl %eax;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
+.macro RESTORE_INT_REGS
+	popl %ebx
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE ebx
+	popl %ecx
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE ecx
+	popl %edx
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE edx
+	popl %esi
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE esi
+	popl %edi
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE edi
+	popl %ebp
+	CFI_ADJUST_CFA_OFFSET -4
+	CFI_RESTORE ebp
+	popl %eax
+	CFI_ADJUST_CFA_OFFSET -4
 	CFI_RESTORE eax
+.endm
 
-#define RESTORE_REGS	\
-	RESTORE_INT_REGS; \
-1:	popl %ds;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	/*CFI_RESTORE ds;*/\
-2:	popl %es;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	/*CFI_RESTORE es;*/\
-3:	popl %fs;	\
-	CFI_ADJUST_CFA_OFFSET -4;\
-	/*CFI_RESTORE fs;*/\
-.pushsection .fixup,"ax";	\
-4:	movl $0,(%esp);	\
-	jmp 1b;		\
-5:	movl $0,(%esp);	\
-	jmp 2b;		\
-6:	movl $0,(%esp);	\
-	jmp 3b;		\
-.section __ex_table,"a";\
-	.align 4;	\
-	.long 1b,4b;	\
-	.long 2b,5b;	\
-	.long 3b,6b;	\
+.macro RESTORE_REGS pop=0
+	RESTORE_INT_REGS
+1:	popl %ds
+	CFI_ADJUST_CFA_OFFSET -4
+	/*CFI_RESTORE ds;*/
+2:	popl %es
+	CFI_ADJUST_CFA_OFFSET -4
+	/*CFI_RESTORE es;*/
+3:	popl %fs
+	CFI_ADJUST_CFA_OFFSET -4
+	/*CFI_RESTORE fs;*/
+	POP_GS \pop
+.pushsection .fixup, "ax"
+4:	movl $0, (%esp)
+	jmp 1b
+5:	movl $0, (%esp)
+	jmp 2b
+6:	movl $0, (%esp)
+	jmp 3b
+.section __ex_table, "a"
+	.align 4
+	.long 1b, 4b
+	.long 2b, 5b
+	.long 3b, 6b
 .popsection
+	POP_GS_EX
+.endm
 
-#define RING0_INT_FRAME \
-	CFI_STARTPROC simple;\
-	CFI_SIGNAL_FRAME;\
-	CFI_DEF_CFA esp, 3*4;\
-	/*CFI_OFFSET cs, -2*4;*/\
+.macro RING0_INT_FRAME
+	CFI_STARTPROC simple
+	CFI_SIGNAL_FRAME
+	CFI_DEF_CFA esp, 3*4
+	/*CFI_OFFSET cs, -2*4;*/
 	CFI_OFFSET eip, -3*4
+.endm
 
-#define RING0_EC_FRAME \
-	CFI_STARTPROC simple;\
-	CFI_SIGNAL_FRAME;\
-	CFI_DEF_CFA esp, 4*4;\
-	/*CFI_OFFSET cs, -2*4;*/\
+.macro RING0_EC_FRAME
+	CFI_STARTPROC simple
+	CFI_SIGNAL_FRAME
+	CFI_DEF_CFA esp, 4*4
+	/*CFI_OFFSET cs, -2*4;*/
 	CFI_OFFSET eip, -3*4
+.endm
 
-#define RING0_PTREGS_FRAME \
-	CFI_STARTPROC simple;\
-	CFI_SIGNAL_FRAME;\
-	CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\
-	/*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\
-	CFI_OFFSET eip, PT_EIP-PT_OLDESP;\
-	/*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\
-	/*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\
-	CFI_OFFSET eax, PT_EAX-PT_OLDESP;\
-	CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\
-	CFI_OFFSET edi, PT_EDI-PT_OLDESP;\
-	CFI_OFFSET esi, PT_ESI-PT_OLDESP;\
-	CFI_OFFSET edx, PT_EDX-PT_OLDESP;\
-	CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\
+.macro RING0_PTREGS_FRAME
+	CFI_STARTPROC simple
+	CFI_SIGNAL_FRAME
+	CFI_DEF_CFA esp, PT_OLDESP-PT_EBX
+	/*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/
+	CFI_OFFSET eip, PT_EIP-PT_OLDESP
+	/*CFI_OFFSET es, PT_ES-PT_OLDESP;*/
+	/*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/
+	CFI_OFFSET eax, PT_EAX-PT_OLDESP
+	CFI_OFFSET ebp, PT_EBP-PT_OLDESP
+	CFI_OFFSET edi, PT_EDI-PT_OLDESP
+	CFI_OFFSET esi, PT_ESI-PT_OLDESP
+	CFI_OFFSET edx, PT_EDX-PT_OLDESP
+	CFI_OFFSET ecx, PT_ECX-PT_OLDESP
 	CFI_OFFSET ebx, PT_EBX-PT_OLDESP
+.endm
 
 ENTRY(ret_from_fork)
 	CFI_STARTPROC
@@ -341,8 +442,7 @@ sysenter_past_esp:
 
 	GET_THREAD_INFO(%ebp)
 
-	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
 	jnz sysenter_audit
 sysenter_do_call:
 	cmpl $(nr_syscalls), %eax
@@ -353,7 +453,7 @@ sysenter_do_call:
 	DISABLE_INTERRUPTS(CLBR_ANY)
 	TRACE_IRQS_OFF
 	movl TI_flags(%ebp), %ecx
-	testw $_TIF_ALLWORK_MASK, %cx
+	testl $_TIF_ALLWORK_MASK, %ecx
 	jne sysexit_audit
 sysenter_exit:
 /* if something modifies registers it must also disable sysexit */
@@ -362,11 +462,12 @@ sysenter_exit:
 	xorl %ebp,%ebp
 	TRACE_IRQS_ON
 1:	mov  PT_FS(%esp), %fs
+	PTGS_TO_GS
 	ENABLE_INTERRUPTS_SYSEXIT
 
 #ifdef CONFIG_AUDITSYSCALL
 sysenter_audit:
-	testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+	testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	addl $4,%esp
 	CFI_ADJUST_CFA_OFFSET -4
@@ -383,7 +484,7 @@ sysenter_audit:
 	jmp sysenter_do_call
 
 sysexit_audit:
-	testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
+	testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx
 	jne syscall_exit_work
 	TRACE_IRQS_ON
 	ENABLE_INTERRUPTS(CLBR_ANY)
@@ -396,7 +497,7 @@ sysexit_audit:
 	DISABLE_INTERRUPTS(CLBR_ANY)
 	TRACE_IRQS_OFF
 	movl TI_flags(%ebp), %ecx
-	testw $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %cx
+	testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %ecx
 	jne syscall_exit_work
 	movl PT_EAX(%esp),%eax	/* reload syscall return value */
 	jmp sysenter_exit
@@ -410,6 +511,7 @@ sysexit_audit:
 	.align 4
 	.long 1b,2b
 .popsection
+	PTGS_TO_GS_EX
 ENDPROC(ia32_sysenter_target)
 
 	# system call handler stub
@@ -420,8 +522,7 @@ ENTRY(system_call)
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
 					# system call tracing in operation / emulation
-	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
@@ -435,7 +536,7 @@ syscall_exit:
 					# between sampling and the iret
 	TRACE_IRQS_OFF
 	movl TI_flags(%ebp), %ecx
-	testw $_TIF_ALLWORK_MASK, %cx	# current->work
+	testl $_TIF_ALLWORK_MASK, %ecx	# current->work
 	jne syscall_exit_work
 
 restore_all:
@@ -452,8 +553,7 @@ restore_all:
 restore_nocheck:
 	TRACE_IRQS_IRET
 restore_nocheck_notrace:
-	RESTORE_REGS
-	addl $4, %esp			# skip orig_eax/error_code
+	RESTORE_REGS 4			# skip orig_eax/error_code
 	CFI_ADJUST_CFA_OFFSET -4
 irq_return:
 	INTERRUPT_RETURN
@@ -571,7 +671,7 @@ END(syscall_trace_entry)
 	# perform syscall exit tracing
 	ALIGN
 syscall_exit_work:
-	testb $_TIF_WORK_SYSCALL_EXIT, %cl
+	testl $_TIF_WORK_SYSCALL_EXIT, %ecx
 	jz work_pending
 	TRACE_IRQS_ON
 	ENABLE_INTERRUPTS(CLBR_ANY)	# could let syscall_trace_leave() call
@@ -595,28 +695,50 @@ syscall_badsys:
 END(syscall_badsys)
 	CFI_ENDPROC
 
-#define FIXUP_ESPFIX_STACK \
-	/* since we are on a wrong stack, we cant make it a C code :( */ \
-	PER_CPU(gdt_page, %ebx); \
-	GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
-	addl %esp, %eax; \
-	pushl $__KERNEL_DS; \
-	CFI_ADJUST_CFA_OFFSET 4; \
-	pushl %eax; \
-	CFI_ADJUST_CFA_OFFSET 4; \
-	lss (%esp), %esp; \
-	CFI_ADJUST_CFA_OFFSET -8;
-#define UNWIND_ESPFIX_STACK \
-	movl %ss, %eax; \
-	/* see if on espfix stack */ \
-	cmpw $__ESPFIX_SS, %ax; \
-	jne 27f; \
-	movl $__KERNEL_DS, %eax; \
-	movl %eax, %ds; \
-	movl %eax, %es; \
-	/* switch to normal stack */ \
-	FIXUP_ESPFIX_STACK; \
-27:;
+/*
+ * System calls that need a pt_regs pointer.
+ */
+#define PTREGSCALL(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)
+
+.macro FIXUP_ESPFIX_STACK
+	/* since we are on a wrong stack, we cant make it a C code :( */
+	PER_CPU(gdt_page, %ebx)
+	GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
+	addl %esp, %eax
+	pushl $__KERNEL_DS
+	CFI_ADJUST_CFA_OFFSET 4
+	pushl %eax
+	CFI_ADJUST_CFA_OFFSET 4
+	lss (%esp), %esp
+	CFI_ADJUST_CFA_OFFSET -8
+.endm
+.macro UNWIND_ESPFIX_STACK
+	movl %ss, %eax
+	/* see if on espfix stack */
+	cmpw $__ESPFIX_SS, %ax
+	jne 27f
+	movl $__KERNEL_DS, %eax
+	movl %eax, %ds
+	movl %eax, %es
+	/* switch to normal stack */
+	FIXUP_ESPFIX_STACK
+27:
+.endm
 
 /*
  * Build the entry stubs and pointer table with some assembler magic.
@@ -672,7 +794,7 @@ common_interrupt:
 ENDPROC(common_interrupt)
 	CFI_ENDPROC
 
-#define BUILD_INTERRUPT(name, nr)	\
+#define BUILD_INTERRUPT3(name, nr, fn)	\
 ENTRY(name)				\
 	RING0_INT_FRAME;		\
 	pushl $~(nr);			\
@@ -680,13 +802,15 @@ ENTRY(name)				\
 	SAVE_ALL;			\
 	TRACE_IRQS_OFF			\
 	movl %esp,%eax;			\
-	call smp_##name;		\
+	call fn;			\
 	jmp ret_from_intr;		\
 	CFI_ENDPROC;			\
 ENDPROC(name)
 
+#define BUILD_INTERRUPT(name, nr)	BUILD_INTERRUPT3(name, nr, smp_##name)
+
 /* The include is where all of the SMP etc. interrupts come from */
-#include "entry_arch.h"
+#include <asm/entry_arch.h>
 
 ENTRY(coprocessor_error)
 	RING0_INT_FRAME
@@ -1068,7 +1192,10 @@ ENTRY(page_fault)
 	CFI_ADJUST_CFA_OFFSET 4
 	ALIGN
 error_code:
-	/* the function address is in %fs's slot on the stack */
+	/* the function address is in %gs's slot on the stack */
+	pushl %fs
+	CFI_ADJUST_CFA_OFFSET 4
+	/*CFI_REL_OFFSET fs, 0*/
 	pushl %es
 	CFI_ADJUST_CFA_OFFSET 4
 	/*CFI_REL_OFFSET es, 0*/
@@ -1097,20 +1224,15 @@ error_code:
 	CFI_ADJUST_CFA_OFFSET 4
 	CFI_REL_OFFSET ebx, 0
 	cld
-	pushl %fs
-	CFI_ADJUST_CFA_OFFSET 4
-	/*CFI_REL_OFFSET fs, 0*/
 	movl $(__KERNEL_PERCPU), %ecx
 	movl %ecx, %fs
 	UNWIND_ESPFIX_STACK
-	popl %ecx
-	CFI_ADJUST_CFA_OFFSET -4
-	/*CFI_REGISTER es, ecx*/
-	movl PT_FS(%esp), %edi		# get the function address
+	GS_TO_REG %ecx
+	movl PT_GS(%esp), %edi		# get the function address
 	movl PT_ORIG_EAX(%esp), %edx	# get the error code
 	movl $-1, PT_ORIG_EAX(%esp)	# no syscall to restart
-	mov  %ecx, PT_FS(%esp)
-	/*CFI_REL_OFFSET fs, ES*/
+	REG_TO_PTGS %ecx
+	SET_KERNEL_GS %ecx
 	movl $(__USER_DS), %ecx
 	movl %ecx, %ds
 	movl %ecx, %es
@@ -1134,26 +1256,27 @@ END(page_fault)
  * by hand onto the new stack - while updating the return eip past
  * the instruction that would have done it for sysenter.
  */
-#define FIX_STACK(offset, ok, label)		\
-	cmpw $__KERNEL_CS,4(%esp);		\
-	jne ok;					\
-label:						\
-	movl TSS_sysenter_sp0+offset(%esp),%esp;	\
-	CFI_DEF_CFA esp, 0;			\
-	CFI_UNDEFINED eip;			\
-	pushfl;					\
-	CFI_ADJUST_CFA_OFFSET 4;		\
-	pushl $__KERNEL_CS;			\
-	CFI_ADJUST_CFA_OFFSET 4;		\
-	pushl $sysenter_past_esp;		\
-	CFI_ADJUST_CFA_OFFSET 4;		\
+.macro FIX_STACK offset ok label
+	cmpw $__KERNEL_CS, 4(%esp)
+	jne \ok
+\label:
+	movl TSS_sysenter_sp0 + \offset(%esp), %esp
+	CFI_DEF_CFA esp, 0
+	CFI_UNDEFINED eip
+	pushfl
+	CFI_ADJUST_CFA_OFFSET 4
+	pushl $__KERNEL_CS
+	CFI_ADJUST_CFA_OFFSET 4
+	pushl $sysenter_past_esp
+	CFI_ADJUST_CFA_OFFSET 4
 	CFI_REL_OFFSET eip, 0
+.endm
 
 ENTRY(debug)
 	RING0_INT_FRAME
 	cmpl $ia32_sysenter_target,(%esp)
 	jne debug_stack_correct
-	FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
+	FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
 debug_stack_correct:
 	pushl $-1			# mark this as an int
 	CFI_ADJUST_CFA_OFFSET 4
@@ -1211,7 +1334,7 @@ nmi_stack_correct:
 
 nmi_stack_fixup:
 	RING0_INT_FRAME
-	FIX_STACK(12,nmi_stack_correct, 1)
+	FIX_STACK 12, nmi_stack_correct, 1
 	jmp nmi_stack_correct
 
 nmi_debug_stack_check:
@@ -1222,7 +1345,7 @@ nmi_debug_stack_check:
 	jb nmi_stack_correct
 	cmpl $debug_esp_fix_insn,(%esp)
 	ja nmi_stack_correct
-	FIX_STACK(24,nmi_stack_correct, 1)
+	FIX_STACK 24, nmi_stack_correct, 1
 	jmp nmi_stack_correct
 
 nmi_espfix_stack:
@@ -1234,7 +1357,7 @@ nmi_espfix_stack:
 	CFI_ADJUST_CFA_OFFSET 4
 	pushl %esp
 	CFI_ADJUST_CFA_OFFSET 4
-	addw $4, (%esp)
+	addl $4, (%esp)
 	/* copy the iret frame of 12 bytes */
 	.rept 3
 	pushl 16(%esp)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/entry_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/entry_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/entry_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/entry_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -48,10 +48,11 @@
 #include <asm/unistd.h>
 #include <asm/thread_info.h>
 #include <asm/hw_irq.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/irqflags.h>
 #include <asm/paravirt.h>
 #include <asm/ftrace.h>
+#include <asm/percpu.h>
 
 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
 #include <linux/elf-em.h>
@@ -76,20 +77,17 @@ ENTRY(ftrace_caller)
 	movq 8(%rbp), %rsi
 	subq $MCOUNT_INSN_SIZE, %rdi
 
-.globl ftrace_call
-ftrace_call:
+GLOBAL(ftrace_call)
 	call ftrace_stub
 
 	MCOUNT_RESTORE_FRAME
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-.globl ftrace_graph_call
-ftrace_graph_call:
+GLOBAL(ftrace_graph_call)
 	jmp ftrace_stub
 #endif
 
-.globl ftrace_stub
-ftrace_stub:
+GLOBAL(ftrace_stub)
 	retq
 END(ftrace_caller)
 
@@ -109,8 +107,7 @@ ENTRY(mcount)
 	jnz ftrace_graph_caller
 #endif
 
-.globl ftrace_stub
-ftrace_stub:
+GLOBAL(ftrace_stub)
 	retq
 
 trace:
@@ -147,9 +144,7 @@ ENTRY(ftrace_graph_caller)
 	retq
 END(ftrace_graph_caller)
 
-
-.globl return_to_handler
-return_to_handler:
+GLOBAL(return_to_handler)
 	subq  $80, %rsp
 
 	movq %rax, (%rsp)
@@ -187,6 +182,7 @@ return_to_handler:
 ENTRY(native_usergs_sysret64)
 	swapgs
 	sysretq
+ENDPROC(native_usergs_sysret64)
 #endif /* CONFIG_PARAVIRT */
 
 
@@ -209,7 +205,7 @@ ENTRY(native_usergs_sysret64)
 
 	/* %rsp:at FRAMEEND */
 	.macro FIXUP_TOP_OF_STACK tmp offset=0
-	movq %gs:pda_oldrsp,\tmp
+	movq PER_CPU_VAR(old_rsp),\tmp
 	movq \tmp,RSP+\offset(%rsp)
 	movq $__USER_DS,SS+\offset(%rsp)
 	movq $__USER_CS,CS+\offset(%rsp)
@@ -220,7 +216,7 @@ ENTRY(native_usergs_sysret64)
 
 	.macro RESTORE_TOP_OF_STACK tmp offset=0
 	movq RSP+\offset(%rsp),\tmp
-	movq \tmp,%gs:pda_oldrsp
+	movq \tmp,PER_CPU_VAR(old_rsp)
 	movq EFLAGS+\offset(%rsp),\tmp
 	movq \tmp,R11+\offset(%rsp)
 	.endm
@@ -336,15 +332,15 @@ ENTRY(save_args)
 	je 1f
 	SWAPGS
 	/*
-	 * irqcount is used to check if a CPU is already on an interrupt stack
+	 * irq_count is used to check if a CPU is already on an interrupt stack
 	 * or not. While this is essentially redundant with preempt_count it is
 	 * a little cheaper to use a separate counter in the PDA (short of
 	 * moving irq_enter into assembly, which would be too much work)
 	 */
-1:	incl %gs:pda_irqcount
+1:	incl PER_CPU_VAR(irq_count)
 	jne 2f
 	popq_cfi %rax			/* move return address... */
-	mov %gs:pda_irqstackptr,%rsp
+	mov PER_CPU_VAR(irq_stack_ptr),%rsp
 	EMPTY_FRAME 0
 	pushq_cfi %rbp			/* backlink for unwinder */
 	pushq_cfi %rax			/* ... to the new stack */
@@ -372,6 +368,7 @@ ENTRY(save_rest)
 END(save_rest)
 
 /* save complete stack frame */
+	.pushsection .kprobes.text, "ax"
 ENTRY(save_paranoid)
 	XCPT_FRAME 1 RDI+8
 	cld
@@ -400,6 +397,7 @@ ENTRY(save_paranoid)
 1:	ret
 	CFI_ENDPROC
 END(save_paranoid)
+	.popsection
 
 /*
  * A newly forked process directly context switches into this address.
@@ -409,6 +407,8 @@ END(save_paranoid)
 ENTRY(ret_from_fork)
 	DEFAULT_FRAME
 
+	LOCK ; btr $TIF_FORK,TI_flags(%r8)
+
 	push kernel_eflags(%rip)
 	CFI_ADJUST_CFA_OFFSET 8
 	popf					# reset kernel eflags
@@ -418,7 +418,6 @@ ENTRY(ret_from_fork)
 
 	GET_THREAD_INFO(%rcx)
 
-	CFI_REMEMBER_STATE
 	RESTORE_REST
 
 	testl $3, CS-ARGOFFSET(%rsp)		# from kernel_thread?
@@ -430,7 +429,6 @@ ENTRY(ret_from_fork)
 	RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
 	jmp ret_from_sys_call			# go to the SYSRET fastpath
 
-	CFI_RESTORE_STATE
 	CFI_ENDPROC
 END(ret_from_fork)
 
@@ -468,7 +466,7 @@ END(ret_from_fork)
 ENTRY(system_call)
 	CFI_STARTPROC	simple
 	CFI_SIGNAL_FRAME
-	CFI_DEF_CFA	rsp,PDA_STACKOFFSET
+	CFI_DEF_CFA	rsp,KERNEL_STACK_OFFSET
 	CFI_REGISTER	rip,rcx
 	/*CFI_REGISTER	rflags,r11*/
 	SWAPGS_UNSAFE_STACK
@@ -479,8 +477,8 @@ ENTRY(system_call)
 	 */
 ENTRY(system_call_after_swapgs)
 
-	movq	%rsp,%gs:pda_oldrsp
-	movq	%gs:pda_kernelstack,%rsp
+	movq	%rsp,PER_CPU_VAR(old_rsp)
+	movq	PER_CPU_VAR(kernel_stack),%rsp
 	/*
 	 * No need to follow this irqs off/on section - it's straight
 	 * and short:
@@ -523,7 +521,7 @@ sysret_check:
 	CFI_REGISTER	rip,rcx
 	RESTORE_ARGS 0,-ARG_SKIP,1
 	/*CFI_REGISTER	rflags,r11*/
-	movq	%gs:pda_oldrsp, %rsp
+	movq	PER_CPU_VAR(old_rsp), %rsp
 	USERGS_SYSRET64
 
 	CFI_RESTORE_STATE
@@ -630,16 +628,14 @@ tracesys:
  * Syscall return path ending with IRET.
  * Has correct top of stack, but partial stack frame.
  */
-	.globl int_ret_from_sys_call
-	.globl int_with_check
-int_ret_from_sys_call:
+GLOBAL(int_ret_from_sys_call)
 	DISABLE_INTERRUPTS(CLBR_NONE)
 	TRACE_IRQS_OFF
 	testl $3,CS-ARGOFFSET(%rsp)
 	je retint_restore_args
 	movl $_TIF_ALLWORK_MASK,%edi
 	/* edi:	mask to check */
-int_with_check:
+GLOBAL(int_with_check)
 	LOCKDEP_SYS_EXIT_IRQ
 	GET_THREAD_INFO(%rcx)
 	movl TI_flags(%rcx),%edx
@@ -833,11 +829,11 @@ common_interrupt:
 	XCPT_FRAME
 	addq $-0x80,(%rsp)		/* Adjust vector to [-256,-1] range */
 	interrupt do_IRQ
-	/* 0(%rsp): oldrsp-ARGOFFSET */
+	/* 0(%rsp): old_rsp-ARGOFFSET */
 ret_from_intr:
 	DISABLE_INTERRUPTS(CLBR_NONE)
 	TRACE_IRQS_OFF
-	decl %gs:pda_irqcount
+	decl PER_CPU_VAR(irq_count)
 	leaveq
 	CFI_DEF_CFA_REGISTER	rsp
 	CFI_ADJUST_CFA_OFFSET	-8
@@ -982,10 +978,14 @@ apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \
 	irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt
 #endif
 
+#ifdef CONFIG_X86_UV
 apicinterrupt UV_BAU_MESSAGE \
 	uv_bau_message_intr1 uv_bau_message_interrupt
+#endif
 apicinterrupt LOCAL_TIMER_VECTOR \
 	apic_timer_interrupt smp_apic_timer_interrupt
+apicinterrupt GENERIC_INTERRUPT_VECTOR \
+	generic_interrupt smp_generic_interrupt
 
 #ifdef CONFIG_SMP
 apicinterrupt INVALIDATE_TLB_VECTOR_START+0 \
@@ -1073,10 +1073,10 @@ ENTRY(\sym)
 	TRACE_IRQS_OFF
 	movq %rsp,%rdi		/* pt_regs pointer */
 	xorl %esi,%esi		/* no error code */
-	movq %gs:pda_data_offset, %rbp
-	subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+	PER_CPU(init_tss, %rbp)
+	subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
 	call \do_sym
-	addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+	addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
 	jmp paranoid_exit	/* %ebx: no swapgs flag */
 	CFI_ENDPROC
 END(\sym)
@@ -1138,7 +1138,7 @@ ENTRY(native_load_gs_index)
 	CFI_STARTPROC
 	pushf
 	CFI_ADJUST_CFA_OFFSET 8
-	DISABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI))
+	DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)
 	SWAPGS
 gs_change:
 	movl %edi,%gs
@@ -1260,14 +1260,14 @@ ENTRY(call_softirq)
 	CFI_REL_OFFSET rbp,0
 	mov  %rsp,%rbp
 	CFI_DEF_CFA_REGISTER rbp
-	incl %gs:pda_irqcount
-	cmove %gs:pda_irqstackptr,%rsp
+	incl PER_CPU_VAR(irq_count)
+	cmove PER_CPU_VAR(irq_stack_ptr),%rsp
 	push  %rbp			# backlink for old unwinder
 	call __do_softirq
 	leaveq
 	CFI_DEF_CFA_REGISTER	rsp
 	CFI_ADJUST_CFA_OFFSET   -8
-	decl %gs:pda_irqcount
+	decl PER_CPU_VAR(irq_count)
 	ret
 	CFI_ENDPROC
 END(call_softirq)
@@ -1297,15 +1297,15 @@ ENTRY(xen_do_hypervisor_callback)   # do
 	movq %rdi, %rsp            # we don't return, adjust the stack frame
 	CFI_ENDPROC
 	DEFAULT_FRAME
-11:	incl %gs:pda_irqcount
+11:	incl PER_CPU_VAR(irq_count)
 	movq %rsp,%rbp
 	CFI_DEF_CFA_REGISTER rbp
-	cmovzq %gs:pda_irqstackptr,%rsp
+	cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp
 	pushq %rbp			# backlink for old unwinder
 	call xen_evtchn_do_upcall
 	popq %rsp
 	CFI_DEF_CFA_REGISTER rsp
-	decl %gs:pda_irqcount
+	decl PER_CPU_VAR(irq_count)
 	jmp  error_exit
 	CFI_ENDPROC
 END(do_hypervisor_callback)
@@ -1410,7 +1410,10 @@ ENTRY(paranoid_exit)
 paranoid_swapgs:
 	TRACE_IRQS_IRETQ 0
 	SWAPGS_UNSAFE_STACK
+	RESTORE_ALL 8
+	jmp irq_return
 paranoid_restore:
+	TRACE_IRQS_IRETQ 0
 	RESTORE_ALL 8
 	jmp irq_return
 paranoid_userspace:
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/es7000_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/es7000_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/es7000_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/es7000_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,378 +0,0 @@
-/*
- * Written by: Garry Forsgren, Unisys Corporation
- *             Natalie Protasevich, Unisys Corporation
- * This file contains the code to configure and interface
- * with Unisys ES7000 series hardware system manager.
- *
- * Copyright (c) 2003 Unisys 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 would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Unisys Corporation, Township Line & Union Meeting
- * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
- *
- * http://www.unisys.com
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <asm/nmi.h>
-#include <asm/smp.h>
-#include <asm/atomic.h>
-#include <asm/apicdef.h>
-#include <mach_mpparse.h>
-#include <asm/genapic.h>
-#include <asm/setup.h>
-
-/*
- * ES7000 chipsets
- */
-
-#define NON_UNISYS		0
-#define ES7000_CLASSIC		1
-#define ES7000_ZORRO		2
-
-
-#define	MIP_REG			1
-#define	MIP_PSAI_REG		4
-
-#define	MIP_BUSY		1
-#define	MIP_SPIN		0xf0000
-#define	MIP_VALID		0x0100000000000000ULL
-#define	MIP_PORT(VALUE)	((VALUE >> 32) & 0xffff)
-
-#define	MIP_RD_LO(VALUE)	(VALUE & 0xffffffff)
-
-struct mip_reg_info {
-	unsigned long long mip_info;
-	unsigned long long delivery_info;
-	unsigned long long host_reg;
-	unsigned long long mip_reg;
-};
-
-struct part_info {
-	unsigned char type;
-	unsigned char length;
-	unsigned char part_id;
-	unsigned char apic_mode;
-	unsigned long snum;
-	char ptype[16];
-	char sname[64];
-	char pname[64];
-};
-
-struct psai {
-	unsigned long long entry_type;
-	unsigned long long addr;
-	unsigned long long bep_addr;
-};
-
-struct es7000_mem_info {
-	unsigned char type;
-	unsigned char length;
-	unsigned char resv[6];
-	unsigned long long  start;
-	unsigned long long  size;
-};
-
-struct es7000_oem_table {
-	unsigned long long hdr;
-	struct mip_reg_info mip;
-	struct part_info pif;
-	struct es7000_mem_info shm;
-	struct psai psai;
-};
-
-#ifdef CONFIG_ACPI
-
-struct oem_table {
-	struct acpi_table_header Header;
-	u32 OEMTableAddr;
-	u32 OEMTableSize;
-};
-
-extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
-#endif
-
-struct mip_reg {
-	unsigned long long off_0;
-	unsigned long long off_8;
-	unsigned long long off_10;
-	unsigned long long off_18;
-	unsigned long long off_20;
-	unsigned long long off_28;
-	unsigned long long off_30;
-	unsigned long long off_38;
-};
-
-#define	MIP_SW_APIC		0x1020b
-#define	MIP_FUNC(VALUE)		(VALUE & 0xff)
-
-/*
- * ES7000 Globals
- */
-
-static volatile unsigned long	*psai = NULL;
-static struct mip_reg		*mip_reg;
-static struct mip_reg		*host_reg;
-static int 			mip_port;
-static unsigned long		mip_addr, host_addr;
-
-int es7000_plat;
-
-/*
- * GSI override for ES7000 platforms.
- */
-
-static unsigned int base;
-
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-	if (es7000_plat == ES7000_ZORRO)
-		return gsi;
-
-	if (!base) {
-		int i;
-		for (i = 0; i < nr_ioapics; i++)
-			base += nr_ioapic_registers[i];
-	}
-
-	if (!ioapic && (gsi < 16))
-		gsi += base;
-	return gsi;
-}
-
-static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
-{
-	unsigned long vect = 0, psaival = 0;
-
-	if (psai == NULL)
-		return -1;
-
-	vect = ((unsigned long)__pa(eip)/0x1000) << 16;
-	psaival = (0x1000000 | vect | cpu);
-
-	while (*psai & 0x1000000)
-		;
-
-	*psai = psaival;
-
-	return 0;
-}
-
-static void noop_wait_for_deassert(atomic_t *deassert_not_used)
-{
-}
-
-static int __init es7000_update_genapic(void)
-{
-	genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-
-	/* MPENTIUMIII */
-	if (boot_cpu_data.x86 == 6 &&
-	    (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
-		es7000_update_genapic_to_cluster();
-		genapic->wait_for_init_deassert = noop_wait_for_deassert;
-		genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-	}
-
-	return 0;
-}
-
-void __init
-setup_unisys(void)
-{
-	/*
-	 * Determine the generation of the ES7000 currently running.
-	 *
-	 * es7000_plat = 1 if the machine is a 5xx ES7000 box
-	 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
-	 *
-	 */
-	if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
-		es7000_plat = ES7000_ZORRO;
-	else
-		es7000_plat = ES7000_CLASSIC;
-	ioapic_renumber_irq = es7000_rename_gsi;
-
-	x86_quirks->update_genapic = es7000_update_genapic;
-}
-
-/*
- * Parse the OEM Table
- */
-
-int __init
-parse_unisys_oem (char *oemptr)
-{
-	int                     i;
-	int 			success = 0;
-	unsigned char           type, size;
-	unsigned long           val;
-	char                    *tp = NULL;
-	struct psai             *psaip = NULL;
-	struct mip_reg_info 	*mi;
-	struct mip_reg		*host, *mip;
-
-	tp = oemptr;
-
-	tp += 8;
-
-	for (i=0; i <= 6; i++) {
-		type = *tp++;
-		size = *tp++;
-		tp -= 2;
-		switch (type) {
-		case MIP_REG:
-			mi = (struct mip_reg_info *)tp;
-			val = MIP_RD_LO(mi->host_reg);
-			host_addr = val;
-			host = (struct mip_reg *)val;
-			host_reg = __va(host);
-			val = MIP_RD_LO(mi->mip_reg);
-			mip_port = MIP_PORT(mi->mip_info);
-			mip_addr = val;
-			mip = (struct mip_reg *)val;
-			mip_reg = __va(mip);
-			pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
-				 (unsigned long)host_reg);
-			pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
-				 (unsigned long)mip_reg);
-			success++;
-			break;
-		case MIP_PSAI_REG:
-			psaip = (struct psai *)tp;
-			if (tp != NULL) {
-				if (psaip->addr)
-					psai = __va(psaip->addr);
-				else
-					psai = NULL;
-				success++;
-			}
-			break;
-		default:
-			break;
-		}
-		tp += size;
-	}
-
-	if (success < 2) {
-		es7000_plat = NON_UNISYS;
-	} else
-		setup_unisys();
-	return es7000_plat;
-}
-
-#ifdef CONFIG_ACPI
-static unsigned long oem_addrX;
-static unsigned long oem_size;
-int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
-{
-	struct acpi_table_header *header = NULL;
-	int i = 0;
-
-	while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) {
-		if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) {
-			struct oem_table *t = (struct oem_table *)header;
-
-			oem_addrX = t->OEMTableAddr;
-			oem_size = t->OEMTableSize;
-
-			*oem_addr = (unsigned long)__acpi_map_table(oem_addrX,
-								    oem_size);
-			return 0;
-		}
-	}
-	return -1;
-}
-
-void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
-{
-}
-#endif
-
-static void
-es7000_spin(int n)
-{
-	int i = 0;
-
-	while (i++ < n)
-		rep_nop();
-}
-
-static int __init
-es7000_mip_write(struct mip_reg *mip_reg)
-{
-	int			status = 0;
-	int			spin;
-
-	spin = MIP_SPIN;
-	while (((unsigned long long)host_reg->off_38 &
-		(unsigned long long)MIP_VALID) != 0) {
-			if (--spin <= 0) {
-				printk("es7000_mip_write: Timeout waiting for Host Valid Flag");
-				return -1;
-			}
-		es7000_spin(MIP_SPIN);
-	}
-
-	memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
-	outb(1, mip_port);
-
-	spin = MIP_SPIN;
-
-	while (((unsigned long long)mip_reg->off_38 &
-		(unsigned long long)MIP_VALID) == 0) {
-		if (--spin <= 0) {
-			printk("es7000_mip_write: Timeout waiting for MIP Valid Flag");
-			return -1;
-		}
-		es7000_spin(MIP_SPIN);
-	}
-
-	status = ((unsigned long long)mip_reg->off_0 &
-		(unsigned long long)0xffff0000000000ULL) >> 48;
-	mip_reg->off_38 = ((unsigned long long)mip_reg->off_38 &
-		(unsigned long long)~MIP_VALID);
-	return status;
-}
-
-void __init
-es7000_sw_apic(void)
-{
-	if (es7000_plat) {
-		int mip_status;
-		struct mip_reg es7000_mip_reg;
-
-		printk("ES7000: Enabling APIC mode.\n");
-        	memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
-        	es7000_mip_reg.off_0 = MIP_SW_APIC;
-        	es7000_mip_reg.off_38 = (MIP_VALID);
-        	while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
-              		printk("es7000_sw_apic: command failed, status = %x\n",
-				mip_status);
-		return;
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/ftrace.c linux-libre-2.6.30-gnu1/arch/x86/kernel/ftrace.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/ftrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/ftrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,14 +18,28 @@
 #include <linux/init.h>
 #include <linux/list.h>
 
+#include <trace/syscall.h>
+
+#include <asm/cacheflush.h>
 #include <asm/ftrace.h>
-#include <linux/ftrace.h>
 #include <asm/nops.h>
 #include <asm/nmi.h>
 
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
+int ftrace_arch_code_modify_prepare(void)
+{
+	set_kernel_text_rw();
+	return 0;
+}
+
+int ftrace_arch_code_modify_post_process(void)
+{
+	set_kernel_text_ro();
+	return 0;
+}
+
 union ftrace_code_union {
 	char code[MCOUNT_INSN_SIZE];
 	struct {
@@ -66,11 +80,11 @@ static unsigned char *ftrace_call_replac
  *
  * 1) Put the instruction pointer into the IP buffer
  *    and the new code into the "code" buffer.
- * 2) Set a flag that says we are modifying code
- * 3) Wait for any running NMIs to finish.
- * 4) Write the code
- * 5) clear the flag.
- * 6) Wait for any running NMIs to finish.
+ * 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
@@ -82,9 +96,9 @@ static unsigned char *ftrace_call_replac
  * are the same as what exists.
  */
 
-static atomic_t in_nmi = ATOMIC_INIT(0);
+#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 int mod_code_write;		/* set when NMI should do the 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 */
 
@@ -101,6 +115,20 @@ int ftrace_arch_read_dyn_info(char *buf,
 	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)
 {
 	/*
@@ -111,37 +139,52 @@ static void ftrace_mod_code(void)
 	 */
 	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)
 {
-	atomic_inc(&in_nmi);
-	/* Must have in_nmi seen before reading write flag */
-	smp_mb();
-	if (mod_code_write) {
+	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 in_nmi */
-	smp_wmb();
-	atomic_dec(&in_nmi);
+	/* 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)
 {
-	int waited = 0;
+	if (!atomic_read(&nmi_running))
+		return;
 
-	while (atomic_read(&in_nmi)) {
-		waited = 1;
+	do {
 		cpu_relax();
-	}
+	} while (atomic_read(&nmi_running));
 
-	if (waited)
-		nmi_wait_count++;
+	nmi_wait_count++;
 }
 
 static int
@@ -151,14 +194,9 @@ do_ftrace_mod_code(unsigned long ip, voi
 	mod_code_newcode = new_code;
 
 	/* The buffers need to be visible before we let NMIs write them */
-	smp_wmb();
-
-	mod_code_write = 1;
-
-	/* Make sure write bit is visible before we wait on NMIs */
 	smp_mb();
 
-	wait_for_nmi();
+	wait_for_nmi_and_set_mod_flag();
 
 	/* Make sure all running NMIs have finished before we write the code */
 	smp_mb();
@@ -166,13 +204,9 @@ do_ftrace_mod_code(unsigned long ip, voi
 	ftrace_mod_code();
 
 	/* Make sure the write happens before clearing the bit */
-	smp_wmb();
-
-	mod_code_write = 0;
-
-	/* make sure NMIs see the cleared bit */
 	smp_mb();
 
+	clear_mod_flag();
 	wait_for_nmi();
 
 	return mod_code_status;
@@ -368,100 +402,8 @@ int ftrace_disable_ftrace_graph_caller(v
 	return ftrace_mod_jmp(ip, old_offset, new_offset);
 }
 
-#else /* CONFIG_DYNAMIC_FTRACE */
-
-/*
- * These functions are picked from those used on
- * this page for dynamic ftrace. They have been
- * simplified to ignore all traces in NMI context.
- */
-static atomic_t in_nmi;
-
-void ftrace_nmi_enter(void)
-{
-	atomic_inc(&in_nmi);
-}
-
-void ftrace_nmi_exit(void)
-{
-	atomic_dec(&in_nmi);
-}
-
 #endif /* !CONFIG_DYNAMIC_FTRACE */
 
-/* Add a function return address to the trace stack on thread info.*/
-static int push_return_trace(unsigned long ret, unsigned long long time,
-				unsigned long func, int *depth)
-{
-	int index;
-
-	if (!current->ret_stack)
-		return -EBUSY;
-
-	/* The return trace stack is full */
-	if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
-		atomic_inc(&current->trace_overrun);
-		return -EBUSY;
-	}
-
-	index = ++current->curr_ret_stack;
-	barrier();
-	current->ret_stack[index].ret = ret;
-	current->ret_stack[index].func = func;
-	current->ret_stack[index].calltime = time;
-	*depth = index;
-
-	return 0;
-}
-
-/* Retrieve a function return address to the trace stack on thread info.*/
-static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
-{
-	int index;
-
-	index = current->curr_ret_stack;
-
-	if (unlikely(index < 0)) {
-		ftrace_graph_stop();
-		WARN_ON(1);
-		/* Might as well panic, otherwise we have no where to go */
-		*ret = (unsigned long)panic;
-		return;
-	}
-
-	*ret = current->ret_stack[index].ret;
-	trace->func = current->ret_stack[index].func;
-	trace->calltime = current->ret_stack[index].calltime;
-	trace->overrun = atomic_read(&current->trace_overrun);
-	trace->depth = index;
-	barrier();
-	current->curr_ret_stack--;
-
-}
-
-/*
- * Send the trace to the ring-buffer.
- * @return the original return address.
- */
-unsigned long ftrace_return_to_handler(void)
-{
-	struct ftrace_graph_ret trace;
-	unsigned long ret;
-
-	pop_return_trace(&trace, &ret);
-	trace.rettime = cpu_clock(raw_smp_processor_id());
-	ftrace_graph_return(&trace);
-
-	if (unlikely(!ret)) {
-		ftrace_graph_stop();
-		WARN_ON(1);
-		/* Might as well panic. What else to do? */
-		ret = (unsigned long)panic;
-	}
-
-	return ret;
-}
-
 /*
  * Hook the return address and push it in the stack of return addrs
  * in current thread info.
@@ -469,14 +411,13 @@ unsigned long ftrace_return_to_handler(v
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 {
 	unsigned long old;
-	unsigned long long calltime;
 	int faulted;
 	struct ftrace_graph_ent trace;
 	unsigned long return_hooker = (unsigned long)
 				&return_to_handler;
 
 	/* Nmi's are currently unsupported */
-	if (unlikely(atomic_read(&in_nmi)))
+	if (unlikely(in_nmi()))
 		return;
 
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
@@ -501,7 +442,7 @@ void prepare_ftrace_return(unsigned long
 		_ASM_EXTABLE(1b, 4b)
 		_ASM_EXTABLE(2b, 4b)
 
-		: [old] "=r" (old), [faulted] "=r" (faulted)
+		: [old] "=&r" (old), [faulted] "=r" (faulted)
 		: [parent] "r" (parent), [return_hooker] "r" (return_hooker)
 		: "memory"
 	);
@@ -512,17 +453,7 @@ void prepare_ftrace_return(unsigned long
 		return;
 	}
 
-	if (unlikely(!__kernel_text_address(old))) {
-		ftrace_graph_stop();
-		*parent = old;
-		WARN_ON(1);
-		return;
-	}
-
-	calltime = cpu_clock(raw_smp_processor_id());
-
-	if (push_return_trace(old, calltime,
-				self_addr, &trace.depth) == -EBUSY) {
+	if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
 		*parent = old;
 		return;
 	}
@@ -536,3 +467,66 @@ 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];
+}
+
+void arch_init_ftrace_syscalls(void)
+{
+	int i;
+	struct syscall_metadata *meta;
+	unsigned long **psys_syscall_table = &sys_call_table;
+	static atomic_t refs;
+
+	if (atomic_inc_return(&refs) != 1)
+		goto end;
+
+	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+					FTRACE_SYSCALL_MAX, GFP_KERNEL);
+	if (!syscalls_metadata) {
+		WARN_ON(1);
+		return;
+	}
+
+	for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
+		meta = find_syscall_meta(psys_syscall_table[i]);
+		syscalls_metadata[i] = meta;
+	}
+	return;
+
+	/* Paranoid: avoid overflow */
+end:
+	atomic_dec(&refs);
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/genapic_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/genapic_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/genapic_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/genapic_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-/*
- * Copyright 2004 James Cleverdon, IBM.
- * Subject to the GNU Public License, v.2
- *
- * Generic APIC sub-arch probe layer.
- *
- * Hacked for x86-64 by James Cleverdon from i386 architecture code by
- * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
- * James Cleverdon.
- */
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/hardirq.h>
-#include <linux/dmar.h>
-
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/genapic.h>
-#include <asm/setup.h>
-
-extern struct genapic apic_flat;
-extern struct genapic apic_physflat;
-extern struct genapic apic_x2xpic_uv_x;
-extern struct genapic apic_x2apic_phys;
-extern struct genapic apic_x2apic_cluster;
-
-struct genapic __read_mostly *genapic = &apic_flat;
-
-static struct genapic *apic_probe[] __initdata = {
-	&apic_x2apic_uv_x,
-	&apic_x2apic_phys,
-	&apic_x2apic_cluster,
-	&apic_physflat,
-	NULL,
-};
-
-/*
- * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
- */
-void __init setup_apic_routing(void)
-{
-	if (genapic == &apic_x2apic_phys || genapic == &apic_x2apic_cluster) {
-		if (!intr_remapping_enabled)
-			genapic = &apic_flat;
-	}
-
-	if (genapic == &apic_flat) {
-		if (max_physical_apicid >= 8)
-			genapic = &apic_physflat;
-		printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
-	}
-
-	if (x86_quirks->update_genapic)
-		x86_quirks->update_genapic();
-}
-
-/* Same for both flat and physical. */
-
-void apic_send_IPI_self(int vector)
-{
-	__send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
-}
-
-int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	int i;
-
-	for (i = 0; apic_probe[i]; ++i) {
-		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
-			genapic = apic_probe[i];
-			printk(KERN_INFO "Setting APIC routing to %s.\n",
-				genapic->name);
-			return 1;
-		}
-	}
-	return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/genapic_flat_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/genapic_flat_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/genapic_flat_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/genapic_flat_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,307 +0,0 @@
-/*
- * Copyright 2004 James Cleverdon, IBM.
- * Subject to the GNU Public License, v.2
- *
- * Flat APIC subarch code.
- *
- * Hacked for x86-64 by James Cleverdon from i386 architecture code by
- * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
- * James Cleverdon.
- */
-#include <linux/errno.h>
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/hardirq.h>
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/genapic.h>
-#include <mach_apicdef.h>
-
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
-
-static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	return 1;
-}
-
-static const struct cpumask *flat_target_cpus(void)
-{
-	return cpu_online_mask;
-}
-
-static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	/* Careful. Some cpus do not strictly honor the set of cpus
-	 * specified in the interrupt destination when using lowest
-	 * priority interrupt delivery mode.
-	 *
-	 * In particular there was a hyperthreading cpu observed to
-	 * deliver interrupts to the wrong hyperthread when only one
-	 * hyperthread was specified in the interrupt desitination.
-	 */
-	cpumask_clear(retmask);
-	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
-}
-
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static void flat_init_apic_ldr(void)
-{
-	unsigned long val;
-	unsigned long num, id;
-
-	num = smp_processor_id();
-	id = 1UL << num;
-	apic_write(APIC_DFR, APIC_DFR_FLAT);
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	val |= SET_APIC_LOGICAL_ID(id);
-	apic_write(APIC_LDR, val);
-}
-
-static inline void _flat_send_IPI_mask(unsigned long mask, int vector)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
-	local_irq_restore(flags);
-}
-
-static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
-{
-	unsigned long mask = cpumask_bits(cpumask)[0];
-
-	_flat_send_IPI_mask(mask, vector);
-}
-
-static void flat_send_IPI_mask_allbutself(const struct cpumask *cpumask,
-					  int vector)
-{
-	unsigned long mask = cpumask_bits(cpumask)[0];
-	int cpu = smp_processor_id();
-
-	if (cpu < BITS_PER_LONG)
-		clear_bit(cpu, &mask);
-	_flat_send_IPI_mask(mask, vector);
-}
-
-static void flat_send_IPI_allbutself(int vector)
-{
-	int cpu = smp_processor_id();
-#ifdef	CONFIG_HOTPLUG_CPU
-	int hotplug = 1;
-#else
-	int hotplug = 0;
-#endif
-	if (hotplug || vector == NMI_VECTOR) {
-		if (!cpumask_equal(cpu_online_mask, cpumask_of(cpu))) {
-			unsigned long mask = cpumask_bits(cpu_online_mask)[0];
-
-			if (cpu < BITS_PER_LONG)
-				clear_bit(cpu, &mask);
-
-			_flat_send_IPI_mask(mask, vector);
-		}
-	} else if (num_online_cpus() > 1) {
-		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL);
-	}
-}
-
-static void flat_send_IPI_all(int vector)
-{
-	if (vector == NMI_VECTOR)
-		flat_send_IPI_mask(cpu_online_mask, vector);
-	else
-		__send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
-}
-
-static unsigned int get_apic_id(unsigned long x)
-{
-	unsigned int id;
-
-	id = (((x)>>24) & 0xFFu);
-	return id;
-}
-
-static unsigned long set_apic_id(unsigned int id)
-{
-	unsigned long x;
-
-	x = ((id & 0xFFu)<<24);
-	return x;
-}
-
-static unsigned int read_xapic_id(void)
-{
-	unsigned int id;
-
-	id = get_apic_id(apic_read(APIC_ID));
-	return id;
-}
-
-static int flat_apic_id_registered(void)
-{
-	return physid_isset(read_xapic_id(), phys_cpu_present_map);
-}
-
-static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
-}
-
-static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						const struct cpumask *andmask)
-{
-	unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
-	unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS;
-
-	return mask1 & mask2;
-}
-
-static unsigned int phys_pkg_id(int index_msb)
-{
-	return hard_smp_processor_id() >> index_msb;
-}
-
-struct genapic apic_flat =  {
-	.name = "flat",
-	.acpi_madt_oem_check = flat_acpi_madt_oem_check,
-	.int_delivery_mode = dest_LowestPrio,
-	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
-	.target_cpus = flat_target_cpus,
-	.vector_allocation_domain = flat_vector_allocation_domain,
-	.apic_id_registered = flat_apic_id_registered,
-	.init_apic_ldr = flat_init_apic_ldr,
-	.send_IPI_all = flat_send_IPI_all,
-	.send_IPI_allbutself = flat_send_IPI_allbutself,
-	.send_IPI_mask = flat_send_IPI_mask,
-	.send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself,
-	.send_IPI_self = apic_send_IPI_self,
-	.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
-	.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
-	.phys_pkg_id = phys_pkg_id,
-	.get_apic_id = get_apic_id,
-	.set_apic_id = set_apic_id,
-	.apic_id_mask = (0xFFu<<24),
-};
-
-/*
- * Physflat mode is used when there are more than 8 CPUs on a AMD system.
- * We cannot use logical delivery in this case because the mask
- * overflows, so use physical mode.
- */
-static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-#ifdef CONFIG_ACPI
-	/*
-	 * Quirk: some x86_64 machines can only use physical APIC mode
-	 * regardless of how many processors are present (x86_64 ES7000
-	 * is an example).
-	 */
-	if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
-		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
-		printk(KERN_DEBUG "system APIC only can use physical flat");
-		return 1;
-	}
-#endif
-
-	return 0;
-}
-
-static const struct cpumask *physflat_target_cpus(void)
-{
-	return cpu_online_mask;
-}
-
-static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
-}
-
-static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector)
-{
-	send_IPI_mask_sequence(cpumask, vector);
-}
-
-static void physflat_send_IPI_mask_allbutself(const struct cpumask *cpumask,
-					      int vector)
-{
-	send_IPI_mask_allbutself(cpumask, vector);
-}
-
-static void physflat_send_IPI_allbutself(int vector)
-{
-	send_IPI_mask_allbutself(cpu_online_mask, vector);
-}
-
-static void physflat_send_IPI_all(int vector)
-{
-	physflat_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	cpu = cpumask_first(cpumask);
-	if ((unsigned)cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-	else
-		return BAD_APICID;
-}
-
-static unsigned int
-physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-				const struct cpumask *andmask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	for_each_cpu_and(cpu, cpumask, andmask)
-		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;
-}
-
-struct genapic apic_physflat =  {
-	.name = "physical flat",
-	.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
-	.int_delivery_mode = dest_Fixed,
-	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
-	.target_cpus = physflat_target_cpus,
-	.vector_allocation_domain = physflat_vector_allocation_domain,
-	.apic_id_registered = flat_apic_id_registered,
-	.init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
-	.send_IPI_all = physflat_send_IPI_all,
-	.send_IPI_allbutself = physflat_send_IPI_allbutself,
-	.send_IPI_mask = physflat_send_IPI_mask,
-	.send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself,
-	.send_IPI_self = apic_send_IPI_self,
-	.cpu_mask_to_apicid = physflat_cpu_mask_to_apicid,
-	.cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and,
-	.phys_pkg_id = phys_pkg_id,
-	.get_apic_id = get_apic_id,
-	.set_apic_id = set_apic_id,
-	.apic_id_mask = (0xFFu<<24),
-};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_cluster.c linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_cluster.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_cluster.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_cluster.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,198 +0,0 @@
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/dmar.h>
-
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/genapic.h>
-
-DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
-
-static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	if (cpu_has_x2apic)
-		return 1;
-
-	return 0;
-}
-
-/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
-
-static const struct cpumask *x2apic_target_cpus(void)
-{
-	return cpumask_of(0);
-}
-
-/*
- * for now each logical cpu is in its own vector allocation domain.
- */
-static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
-}
-
-static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
-				   unsigned int dest)
-{
-	unsigned long cfg;
-
-	cfg = __prepare_ICR(0, vector, dest);
-
-	/*
-	 * send the IPI.
-	 */
-	x2apic_icr_write(cfg, apicid);
-}
-
-/*
- * for now, we send the IPI's one by one in the cpumask.
- * TBD: Based on the cpu mask, we can send the IPI's to the cluster group
- * at once. We have 16 cpu's in a cluster. This will minimize IPI register
- * writes.
- */
-static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask)
-		__x2apic_send_IPI_dest(
-			per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-			vector, APIC_DEST_LOGICAL);
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_mask_allbutself(const struct cpumask *mask,
-					    int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-	unsigned long this_cpu = smp_processor_id();
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask)
-		if (query_cpu != this_cpu)
-			__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-				vector, APIC_DEST_LOGICAL);
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_allbutself(int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-	unsigned long this_cpu = smp_processor_id();
-
-	local_irq_save(flags);
-	for_each_online_cpu(query_cpu)
-		if (query_cpu != this_cpu)
-			__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-				vector, APIC_DEST_LOGICAL);
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_all(int vector)
-{
-	x2apic_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int x2apic_apic_id_registered(void)
-{
-	return 1;
-}
-
-static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one logical APIC ID.
-	 * May as well be the first.
-	 */
-	cpu = cpumask_first(cpumask);
-	if ((unsigned)cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_logical_apicid, cpu);
-	else
-		return BAD_APICID;
-}
-
-static unsigned int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						  const struct cpumask *andmask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one logical APIC ID.
-	 * May as well be the first.
-	 */
-	for_each_cpu_and(cpu, cpumask, andmask)
-		if (cpumask_test_cpu(cpu, cpu_online_mask))
-			break;
-	if (cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_logical_apicid, cpu);
-	return BAD_APICID;
-}
-
-static unsigned int get_apic_id(unsigned long x)
-{
-	unsigned int id;
-
-	id = x;
-	return id;
-}
-
-static unsigned long set_apic_id(unsigned int id)
-{
-	unsigned long x;
-
-	x = id;
-	return x;
-}
-
-static unsigned int phys_pkg_id(int index_msb)
-{
-	return current_cpu_data.initial_apicid >> index_msb;
-}
-
-static void x2apic_send_IPI_self(int vector)
-{
-	apic_write(APIC_SELF_IPI, vector);
-}
-
-static void init_x2apic_ldr(void)
-{
-	int cpu = smp_processor_id();
-
-	per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR);
-	return;
-}
-
-struct genapic apic_x2apic_cluster = {
-	.name = "cluster x2apic",
-	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
-	.int_delivery_mode = dest_LowestPrio,
-	.int_dest_mode = (APIC_DEST_LOGICAL != 0),
-	.target_cpus = x2apic_target_cpus,
-	.vector_allocation_domain = x2apic_vector_allocation_domain,
-	.apic_id_registered = x2apic_apic_id_registered,
-	.init_apic_ldr = init_x2apic_ldr,
-	.send_IPI_all = x2apic_send_IPI_all,
-	.send_IPI_allbutself = x2apic_send_IPI_allbutself,
-	.send_IPI_mask = x2apic_send_IPI_mask,
-	.send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself,
-	.send_IPI_self = x2apic_send_IPI_self,
-	.cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid,
-	.cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and,
-	.phys_pkg_id = phys_pkg_id,
-	.get_apic_id = get_apic_id,
-	.set_apic_id = set_apic_id,
-	.apic_id_mask = (0xFFFFFFFFu),
-};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_phys.c linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_phys.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_phys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_phys.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,194 +0,0 @@
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/dmar.h>
-
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/genapic.h>
-
-static int x2apic_phys;
-
-static int set_x2apic_phys_mode(char *arg)
-{
-	x2apic_phys = 1;
-	return 0;
-}
-early_param("x2apic_phys", set_x2apic_phys_mode);
-
-static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	if (cpu_has_x2apic && x2apic_phys)
-		return 1;
-
-	return 0;
-}
-
-/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
-
-static const struct cpumask *x2apic_target_cpus(void)
-{
-	return cpumask_of(0);
-}
-
-static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
-}
-
-static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
-				   unsigned int dest)
-{
-	unsigned long cfg;
-
-	cfg = __prepare_ICR(0, vector, dest);
-
-	/*
-	 * send the IPI.
-	 */
-	x2apic_icr_write(cfg, apicid);
-}
-
-static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
-				       vector, APIC_DEST_PHYSICAL);
-	}
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_mask_allbutself(const struct cpumask *mask,
-					    int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-	unsigned long this_cpu = smp_processor_id();
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		if (query_cpu != this_cpu)
-			__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_apicid, query_cpu),
-				vector, APIC_DEST_PHYSICAL);
-	}
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_allbutself(int vector)
-{
-	unsigned long flags;
-	unsigned long query_cpu;
-	unsigned long this_cpu = smp_processor_id();
-
-	local_irq_save(flags);
-	for_each_online_cpu(query_cpu)
-		if (query_cpu != this_cpu)
-			__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_apicid, query_cpu),
-				vector, APIC_DEST_PHYSICAL);
-	local_irq_restore(flags);
-}
-
-static void x2apic_send_IPI_all(int vector)
-{
-	x2apic_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int x2apic_apic_id_registered(void)
-{
-	return 1;
-}
-
-static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	cpu = cpumask_first(cpumask);
-	if ((unsigned)cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-	else
-		return BAD_APICID;
-}
-
-static unsigned int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-						  const struct cpumask *andmask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	for_each_cpu_and(cpu, cpumask, andmask)
-		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;
-}
-
-static unsigned int get_apic_id(unsigned long x)
-{
-	unsigned int id;
-
-	id = x;
-	return id;
-}
-
-static unsigned long set_apic_id(unsigned int id)
-{
-	unsigned long x;
-
-	x = id;
-	return x;
-}
-
-static unsigned int phys_pkg_id(int index_msb)
-{
-	return current_cpu_data.initial_apicid >> index_msb;
-}
-
-static void x2apic_send_IPI_self(int vector)
-{
-	apic_write(APIC_SELF_IPI, vector);
-}
-
-static void init_x2apic_ldr(void)
-{
-	return;
-}
-
-struct genapic apic_x2apic_phys = {
-	.name = "physical x2apic",
-	.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
-	.int_delivery_mode = dest_Fixed,
-	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
-	.target_cpus = x2apic_target_cpus,
-	.vector_allocation_domain = x2apic_vector_allocation_domain,
-	.apic_id_registered = x2apic_apic_id_registered,
-	.init_apic_ldr = init_x2apic_ldr,
-	.send_IPI_all = x2apic_send_IPI_all,
-	.send_IPI_allbutself = x2apic_send_IPI_allbutself,
-	.send_IPI_mask = x2apic_send_IPI_mask,
-	.send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself,
-	.send_IPI_self = x2apic_send_IPI_self,
-	.cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid,
-	.cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and,
-	.phys_pkg_id = phys_pkg_id,
-	.get_apic_id = get_apic_id,
-	.set_apic_id = set_apic_id,
-	.apic_id_mask = (0xFFFFFFFFu),
-};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_uv_x.c linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_uv_x.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/genx2apic_uv_x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/genx2apic_uv_x.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,600 +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.
- *
- * SGI UV APIC functions (note: not an Intel compatible APIC)
- *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/threads.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/hardirq.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h>
-#include <asm/current.h>
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/genapic.h>
-#include <asm/pgtable.h>
-#include <asm/uv/uv_mmrs.h>
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/bios.h>
-
-DEFINE_PER_CPU(int, x2apic_extra_bits);
-
-static enum uv_system_type uv_system_type;
-
-static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	if (!strcmp(oem_id, "SGI")) {
-		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")) {
-			uv_system_type = UV_NON_UNIQUE_APIC;
-			return 1;
-		}
-	}
-	return 0;
-}
-
-enum uv_system_type get_uv_system_type(void)
-{
-	return uv_system_type;
-}
-
-int is_uv_system(void)
-{
-	return uv_system_type != UV_NONE;
-}
-EXPORT_SYMBOL_GPL(is_uv_system);
-
-DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
-EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
-
-struct uv_blade_info *uv_blade_info;
-EXPORT_SYMBOL_GPL(uv_blade_info);
-
-short *uv_node_to_blade;
-EXPORT_SYMBOL_GPL(uv_node_to_blade);
-
-short *uv_cpu_to_blade;
-EXPORT_SYMBOL_GPL(uv_cpu_to_blade);
-
-short uv_possible_blades;
-EXPORT_SYMBOL_GPL(uv_possible_blades);
-
-unsigned long sn_rtc_cycles_per_second;
-EXPORT_SYMBOL(sn_rtc_cycles_per_second);
-
-/* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
-
-static const struct cpumask *uv_target_cpus(void)
-{
-	return cpumask_of(0);
-}
-
-static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
-}
-
-int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip)
-{
-	unsigned long val;
-	int pnode;
-
-	pnode = uv_apicid_to_pnode(phys_apicid);
-	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
-	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-	    (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
-	    APIC_DM_INIT;
-	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
-	mdelay(10);
-
-	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
-	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
-	    (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
-	    APIC_DM_STARTUP;
-	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
-	return 0;
-}
-
-static void uv_send_IPI_one(int cpu, int vector)
-{
-	unsigned long val, apicid, lapicid;
-	int pnode;
-
-	apicid = per_cpu(x86_cpu_to_apicid, cpu);
-	lapicid = apicid & 0x3f;		/* ZZZ macro needed */
-	pnode = uv_apicid_to_pnode(apicid);
-	val =
-	    (1UL << UVH_IPI_INT_SEND_SHFT) | (lapicid <<
-					      UVH_IPI_INT_APIC_ID_SHFT) |
-	    (vector << UVH_IPI_INT_VECTOR_SHFT);
-	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
-}
-
-static void uv_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	unsigned int cpu;
-
-	for_each_cpu(cpu, mask)
-		uv_send_IPI_one(cpu, vector);
-}
-
-static void uv_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
-{
-	unsigned int cpu;
-	unsigned int this_cpu = smp_processor_id();
-
-	for_each_cpu(cpu, mask)
-		if (cpu != this_cpu)
-			uv_send_IPI_one(cpu, vector);
-}
-
-static void uv_send_IPI_allbutself(int vector)
-{
-	unsigned int cpu;
-	unsigned int this_cpu = smp_processor_id();
-
-	for_each_online_cpu(cpu)
-		if (cpu != this_cpu)
-			uv_send_IPI_one(cpu, vector);
-}
-
-static void uv_send_IPI_all(int vector)
-{
-	uv_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int uv_apic_id_registered(void)
-{
-	return 1;
-}
-
-static void uv_init_apic_ldr(void)
-{
-}
-
-static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	cpu = cpumask_first(cpumask);
-	if ((unsigned)cpu < nr_cpu_ids)
-		return per_cpu(x86_cpu_to_apicid, cpu);
-	else
-		return BAD_APICID;
-}
-
-static unsigned int uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-					      const struct cpumask *andmask)
-{
-	int cpu;
-
-	/*
-	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
-	 * May as well be the first.
-	 */
-	for_each_cpu_and(cpu, cpumask, andmask)
-		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;
-}
-
-static unsigned int get_apic_id(unsigned long x)
-{
-	unsigned int id;
-
-	WARN_ON(preemptible() && num_online_cpus() > 1);
-	id = x | __get_cpu_var(x2apic_extra_bits);
-
-	return id;
-}
-
-static unsigned long set_apic_id(unsigned int id)
-{
-	unsigned long x;
-
-	/* maskout x2apic_extra_bits ? */
-	x = id;
-	return x;
-}
-
-static unsigned int uv_read_apic_id(void)
-{
-
-	return get_apic_id(apic_read(APIC_ID));
-}
-
-static unsigned int phys_pkg_id(int index_msb)
-{
-	return uv_read_apic_id() >> index_msb;
-}
-
-static void uv_send_IPI_self(int vector)
-{
-	apic_write(APIC_SELF_IPI, vector);
-}
-
-struct genapic apic_x2apic_uv_x = {
-	.name = "UV large system",
-	.acpi_madt_oem_check = uv_acpi_madt_oem_check,
-	.int_delivery_mode = dest_Fixed,
-	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
-	.target_cpus = uv_target_cpus,
-	.vector_allocation_domain = uv_vector_allocation_domain,
-	.apic_id_registered = uv_apic_id_registered,
-	.init_apic_ldr = uv_init_apic_ldr,
-	.send_IPI_all = uv_send_IPI_all,
-	.send_IPI_allbutself = uv_send_IPI_allbutself,
-	.send_IPI_mask = uv_send_IPI_mask,
-	.send_IPI_mask_allbutself = uv_send_IPI_mask_allbutself,
-	.send_IPI_self = uv_send_IPI_self,
-	.cpu_mask_to_apicid = uv_cpu_mask_to_apicid,
-	.cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and,
-	.phys_pkg_id = phys_pkg_id,
-	.get_apic_id = get_apic_id,
-	.set_apic_id = set_apic_id,
-	.apic_id_mask = (0xFFFFFFFFu),
-};
-
-static __cpuinit void set_x2apic_extra_bits(int pnode)
-{
-	__get_cpu_var(x2apic_extra_bits) = (pnode << 6);
-}
-
-/*
- * Called on boot cpu.
- */
-static __init int boot_pnode_to_blade(int pnode)
-{
-	int blade;
-
-	for (blade = 0; blade < uv_num_possible_blades(); blade++)
-		if (pnode == uv_blade_info[blade].pnode)
-			return blade;
-	BUG();
-}
-
-struct redir_addr {
-	unsigned long redirect;
-	unsigned long alias;
-};
-
-#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
-
-static __initdata struct redir_addr redir_addrs[] = {
-	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG},
-	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG},
-	{UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG},
-};
-
-static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
-{
-	union uvh_si_alias0_overlay_config_u alias;
-	union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
-		alias.v = uv_read_local_mmr(redir_addrs[i].alias);
-		if (alias.s.base == 0) {
-			*size = (1UL << alias.s.m_alias);
-			redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
-			*base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
-			return;
-		}
-	}
-	BUG();
-}
-
-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);
-}
-
-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)
-{
-	unsigned long bytes, paddr;
-
-	paddr = base << shift;
-	bytes = (1UL << shift) * (max_pnode + 1);
-	printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
-	       					paddr + bytes);
-	if (map_type == map_uc)
-		init_extra_mapping_uc(paddr, bytes);
-	else
-		init_extra_mapping_wb(paddr, bytes);
-
-}
-static __init void map_gru_high(int max_pnode)
-{
-	union uvh_rh_gam_gru_overlay_config_mmr_u gru;
-	int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
-
-	gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
-	if (gru.s.enable)
-		map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
-}
-
-static __init void map_config_high(int max_pnode)
-{
-	union uvh_rh_gam_cfg_overlay_config_mmr_u cfg;
-	int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT;
-
-	cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR);
-	if (cfg.s.enable)
-		map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc);
-}
-
-static __init void map_mmr_high(int max_pnode)
-{
-	union uvh_rh_gam_mmr_overlay_config_mmr_u mmr;
-	int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT;
-
-	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);
-}
-
-static __init void map_mmioh_high(int max_pnode)
-{
-	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
-	int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
-
-	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);
-}
-
-static __init void uv_rtc_init(void)
-{
-	long status;
-	u64 ticks_per_sec;
-
-	status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
-					&ticks_per_sec);
-	if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
-		printk(KERN_WARNING
-			"unable to determine platform RTC clock frequency, "
-			"guessing.\n");
-		/* BIOS gives wrong value for clock freq. so guess */
-		sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
-	} else
-		sn_rtc_cycles_per_second = ticks_per_sec;
-}
-
-/*
- * percpu heartbeat timer
- */
-static void uv_heartbeat(unsigned long ignored)
-{
-	struct timer_list *timer = &uv_hub_info->scir.timer;
-	unsigned char bits = uv_hub_info->scir.state;
-
-	/* flip heartbeat bit */
-	bits ^= SCIR_CPU_HEARTBEAT;
-
-	/* is this cpu idle? */
-	if (idle_cpu(raw_smp_processor_id()))
-		bits &= ~SCIR_CPU_ACTIVITY;
-	else
-		bits |= SCIR_CPU_ACTIVITY;
-
-	/* update system controller interface reg */
-	uv_set_scir_bits(bits);
-
-	/* enable next timer period */
-	mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL);
-}
-
-static void __cpuinit uv_heartbeat_enable(int cpu)
-{
-	if (!uv_cpu_hub_info(cpu)->scir.enabled) {
-		struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer;
-
-		uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY);
-		setup_timer(timer, uv_heartbeat, cpu);
-		timer->expires = jiffies + SCIR_CPU_HB_INTERVAL;
-		add_timer_on(timer, cpu);
-		uv_cpu_hub_info(cpu)->scir.enabled = 1;
-	}
-
-	/* check boot cpu */
-	if (!uv_cpu_hub_info(0)->scir.enabled)
-		uv_heartbeat_enable(0);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __cpuinit uv_heartbeat_disable(int cpu)
-{
-	if (uv_cpu_hub_info(cpu)->scir.enabled) {
-		uv_cpu_hub_info(cpu)->scir.enabled = 0;
-		del_timer(&uv_cpu_hub_info(cpu)->scir.timer);
-	}
-	uv_set_cpu_scir_bits(cpu, 0xff);
-}
-
-/*
- * cpu hotplug notifier
- */
-static __cpuinit int uv_scir_cpu_notify(struct notifier_block *self,
-				       unsigned long action, void *hcpu)
-{
-	long cpu = (long)hcpu;
-
-	switch (action) {
-	case CPU_ONLINE:
-		uv_heartbeat_enable(cpu);
-		break;
-	case CPU_DOWN_PREPARE:
-		uv_heartbeat_disable(cpu);
-		break;
-	default:
-		break;
-	}
-	return NOTIFY_OK;
-}
-
-static __init void uv_scir_register_cpu_notifier(void)
-{
-	hotcpu_notifier(uv_scir_cpu_notify, 0);
-}
-
-#else /* !CONFIG_HOTPLUG_CPU */
-
-static __init void uv_scir_register_cpu_notifier(void)
-{
-}
-
-static __init int uv_init_heartbeat(void)
-{
-	int cpu;
-
-	if (is_uv_system())
-		for_each_online_cpu(cpu)
-			uv_heartbeat_enable(cpu);
-	return 0;
-}
-
-late_initcall(uv_init_heartbeat);
-
-#endif /* !CONFIG_HOTPLUG_CPU */
-
-/*
- * Called on each cpu to initialize the per_cpu UV data area.
- * 	ZZZ hotplug not supported yet
- */
-void __cpuinit uv_cpu_init(void)
-{
-	/* CPU 0 initilization will be done via uv_system_init. */
-	if (!uv_blade_info)
-		return;
-
-	uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
-
-	if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
-		set_x2apic_extra_bits(uv_hub_info->pnode);
-}
-
-
-void __init uv_system_init(void)
-{
-	union uvh_si_addr_map_config_u m_n_config;
-	union uvh_node_id_u node_id;
-	unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
-	int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
-	int max_pnode = 0;
-	unsigned long mmr_base, present;
-
-	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;
-	mmr_base =
-	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
-	    ~UV_MMR_ENABLE;
-	printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
-
-	for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
-		uv_possible_blades +=
-		  hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8));
-	printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades());
-
-	bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
-	uv_blade_info = kmalloc(bytes, GFP_KERNEL);
-
-	get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
-
-	bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
-	uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
-	memset(uv_node_to_blade, 255, bytes);
-
-	bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus();
-	uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL);
-	memset(uv_cpu_to_blade, 255, bytes);
-
-	blade = 0;
-	for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
-		present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
-		for (j = 0; j < 64; j++) {
-			if (!test_bit(j, &present))
-				continue;
-			uv_blade_info[blade].pnode = (i * 64 + j);
-			uv_blade_info[blade].nr_possible_cpus = 0;
-			uv_blade_info[blade].nr_online_cpus = 0;
-			blade++;
-		}
-	}
-
-	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
-	gnode_upper = (((unsigned long)node_id.s.node_id) &
-		       ~((1 << n_val) - 1)) << m_val;
-
-	uv_bios_init();
-	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
-			    &sn_coherency_id, &sn_region_size);
-	uv_rtc_init();
-
-	for_each_present_cpu(cpu) {
-		nid = cpu_to_node(cpu);
-		pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
-		blade = boot_pnode_to_blade(pnode);
-		lcpu = uv_blade_info[blade].nr_possible_cpus;
-		uv_blade_info[blade].nr_possible_cpus++;
-
-		uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
-		uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
-		uv_cpu_hub_info(cpu)->m_val = m_val;
-		uv_cpu_hub_info(cpu)->n_val = m_val;
-		uv_cpu_hub_info(cpu)->numa_blade_id = blade;
-		uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
-		uv_cpu_hub_info(cpu)->pnode = pnode;
-		uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) - 1;
-		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
-		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
-		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_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);
-	}
-
-	map_gru_high(max_pnode);
-	map_mmr_high(max_pnode);
-	map_config_high(max_pnode);
-	map_mmioh_high(max_pnode);
-
-	uv_cpu_init();
-	uv_scir_register_cpu_notifier();
-	proc_mkdir("sgi_uv", NULL);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/head32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/head32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/head32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/head32.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@ void __init i386_start_kernel(void)
 {
 	reserve_trampoline_memory();
 
-	reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
+	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Reserve INITRD */
@@ -29,9 +29,6 @@ void __init i386_start_kernel(void)
 		reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
 	}
 #endif
-	reserve_early(init_pg_tables_start, init_pg_tables_end,
-			"INIT_PG_TABLE");
-
 	reserve_ebda_region();
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/head_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/head_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/head_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/head_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -11,14 +11,15 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/page_types.h>
+#include <asm/pgtable_types.h>
 #include <asm/desc.h>
 #include <asm/cache.h>
 #include <asm/thread_info.h>
 #include <asm/asm-offsets.h>
 #include <asm/setup.h>
 #include <asm/processor-flags.h>
+#include <asm/percpu.h>
 
 /* Physical address */
 #define pa(X) ((X) - __PAGE_OFFSET)
@@ -37,42 +38,40 @@
 #define X86_VENDOR_ID	new_cpu_data+CPUINFO_x86_vendor_id
 
 /*
- * This is how much memory *in addition to the memory covered up to
- * and including _end* we need mapped initially.
+ * This is how much memory in addition to the memory covered up to
+ * and including _end we need mapped initially.
  * We need:
- *  - one bit for each possible page, but only in low memory, which means
- *     2^32/4096/8 = 128K worst case (4G/4G split.)
- *  - enough space to map all low memory, which means
- *     (2^32/4096) / 1024 pages (worst case, non PAE)
- *     (2^32/4096) / 512 + 4 pages (worst case for PAE)
- *  - a few pages for allocator use before the kernel pagetable has
- *     been set up
+ *     (KERNEL_IMAGE_SIZE/4096) / 1024 pages (worst case, non PAE)
+ *     (KERNEL_IMAGE_SIZE/4096) / 512 + 4 pages (worst case for PAE)
  *
  * Modulo rounding, each megabyte assigned here requires a kilobyte of
  * memory, which is currently unreclaimed.
  *
  * This should be a multiple of a page.
+ *
+ * KERNEL_IMAGE_SIZE should be greater than pa(_end)
+ * and small than max_low_pfn, otherwise will waste some page table entries
  */
-LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
-
-/*
- * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate
- * pagetables from above the 16MB DMA limit, so we'll have to set
- * up pagetables 16MB more (worst-case):
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-LOW_PAGES = LOW_PAGES + 0x1000000
-#endif
 
 #if PTRS_PER_PMD > 1
-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
+#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
 #else
-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
 #endif
-BOOTBITMAP_SIZE = LOW_PAGES / 8
-ALLOCATOR_SLOP = 4
 
-INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
+/* Enough space to fit pagetables for the low memory linear map */
+MAPPING_BEYOND_END = \
+	PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+
+/*
+ * Worst-case size of the kernel mapping we need to make:
+ * the worst-case size of the kernel itself, plus the extra we need
+ * to map for the linear map.
+ */
+KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
+
+INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
+RESERVE_BRK(pagetables, INIT_MAP_SIZE)
 
 /*
  * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
@@ -165,10 +164,10 @@ num_subarch_entries = (. - subarch_entri
 
 /*
  * Initialize page tables.  This creates a PDE and a set of page
- * tables, which are located immediately beyond _end.  The variable
- * init_pg_tables_end is set up to point to the first "safe" location.
+ * tables, which are located immediately beyond __brk_base.  The variable
+ * _brk_end is set up to point to the first "safe" location.
  * Mappings are created both at virtual address 0 (identity mapping)
- * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END.
+ * and PAGE_OFFSET for up to _end.
  *
  * Note that the stack is not yet set up!
  */
@@ -189,8 +188,7 @@ default_entry:
 
 	xorl %ebx,%ebx				/* %ebx is kept at zero */
 
-	movl $pa(pg0), %edi
-	movl %edi, pa(init_pg_tables_start)
+	movl $pa(__brk_base), %edi
 	movl $pa(swapper_pg_pmd), %edx
 	movl $PTE_IDENT_ATTR, %eax
 10:
@@ -208,14 +206,14 @@ default_entry:
 	loop 11b
 
 	/*
-	 * End condition: we must map up to and including INIT_MAP_BEYOND_END
-	 * bytes beyond the end of our own page tables.
+	 * End condition: we must map up to the end + MAPPING_BEYOND_END.
 	 */
-	leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
+	movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
 	cmpl %ebp,%eax
 	jb 10b
 1:
-	movl %edi,pa(init_pg_tables_end)
+	addl $__PAGE_OFFSET, %edi
+	movl %edi, pa(_brk_end)
 	shrl $12, %eax
 	movl %eax, pa(max_pfn_mapped)
 
@@ -226,8 +224,7 @@ default_entry:
 
 page_pde_offset = (__PAGE_OFFSET >> 20);
 
-	movl $pa(pg0), %edi
-	movl %edi, pa(init_pg_tables_start)
+	movl $pa(__brk_base), %edi
 	movl $pa(swapper_pg_dir), %edx
 	movl $PTE_IDENT_ATTR, %eax
 10:
@@ -241,14 +238,13 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
 	addl $0x1000,%eax
 	loop 11b
 	/*
-	 * End condition: we must map up to and including INIT_MAP_BEYOND_END
-	 * bytes beyond the end of our own page tables; the +0x007 is
-	 * the attribute bits
+	 * End condition: we must map up to the end + MAPPING_BEYOND_END.
 	 */
-	leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
+	movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
 	cmpl %ebp,%eax
 	jb 10b
-	movl %edi,pa(init_pg_tables_end)
+	addl $__PAGE_OFFSET, %edi
+	movl %edi, pa(_brk_end)
 	shrl $12, %eax
 	movl %eax, pa(max_pfn_mapped)
 
@@ -429,14 +425,34 @@ is386:	movl $2,%ecx		# set MP
 	ljmp $(__KERNEL_CS),$1f
 1:	movl $(__KERNEL_DS),%eax	# reload all the segment registers
 	movl %eax,%ss			# after changing gdt.
-	movl %eax,%fs			# gets reset once there's real percpu
 
 	movl $(__USER_DS),%eax		# DS/ES contains default USER segment
 	movl %eax,%ds
 	movl %eax,%es
 
-	xorl %eax,%eax			# Clear GS and LDT
+	movl $(__KERNEL_PERCPU), %eax
+	movl %eax,%fs			# set this cpu's percpu
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+	/*
+	 * The linker can't handle this by relocation.  Manually set
+	 * base address in stack canary segment descriptor.
+	 */
+	cmpb $0,ready
+	jne 1f
+	movl $per_cpu__gdt_page,%eax
+	movl $per_cpu__stack_canary,%ecx
+	subl $20, %ecx
+	movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
+	shrl $16, %ecx
+	movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
+	movb %ch, 8 * GDT_ENTRY_STACK_CANARY + 7(%eax)
+1:
+#endif
+	movl $(__KERNEL_STACK_CANARY),%eax
 	movl %eax,%gs
+
+	xorl %eax,%eax			# Clear LDT
 	lldt %ax
 
 	cld			# gcc2 wants the direction flag cleared at all times
@@ -446,8 +462,6 @@ is386:	movl $2,%ecx		# set MP
 	movb $1, ready
 	cmpb $0,%cl		# the first CPU calls start_kernel
 	je   1f
-	movl $(__KERNEL_PERCPU), %eax
-	movl %eax,%fs		# set this cpu's percpu
 	movl (stack_start), %esp
 1:
 #endif /* CONFIG_SMP */
@@ -548,12 +562,8 @@ early_fault:
 	pushl %eax
 	pushl %edx		/* trapno */
 	pushl $fault_msg
-#ifdef CONFIG_EARLY_PRINTK
-	call early_printk
-#else
 	call printk
 #endif
-#endif
 	call dump_stack
 hlt_loop:
 	hlt
@@ -580,11 +590,10 @@ ignore_int:
 	pushl 32(%esp)
 	pushl 40(%esp)
 	pushl $int_msg
-#ifdef CONFIG_EARLY_PRINTK
-	call early_printk
-#else
 	call printk
-#endif
+
+	call dump_stack
+
 	addl $(5*4),%esp
 	popl %ds
 	popl %es
@@ -622,6 +631,7 @@ swapper_pg_fixmap:
 	.fill 1024,4,0
 ENTRY(empty_zero_page)
 	.fill 4096,1,0
+
 /*
  * This starts the data section.
  */
@@ -660,7 +670,7 @@ early_recursion_flag:
 	.long 0
 
 int_msg:
-	.asciz "Unknown interrupt or fault at EIP %p %p %p\n"
+	.asciz "Unknown interrupt or fault at: %p %p %p\n"
 
 fault_msg:
 /* fault info: */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/head64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/head64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/head64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/head64.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,27 +26,6 @@
 #include <asm/bios_ebda.h>
 #include <asm/trampoline.h>
 
-/* boot cpu pda */
-static struct x8664_pda _boot_cpu_pda;
-
-#ifdef CONFIG_SMP
-/*
- * We install an empty cpu_pda pointer table to indicate to early users
- * (numa_set_node) that the cpu_pda pointer table for cpus other than
- * the boot cpu is not yet setup.
- */
-static struct x8664_pda *__cpu_pda[NR_CPUS] __initdata;
-#else
-static struct x8664_pda *__cpu_pda[NR_CPUS] __read_mostly;
-#endif
-
-void __init x86_64_init_pda(void)
-{
-	_cpu_pda = __cpu_pda;
-	cpu_pda(0) = &_boot_cpu_pda;
-	pda_init(0);
-}
-
 static void __init zap_identity_mappings(void)
 {
 	pgd_t *pgd = pgd_offset_k(0UL);
@@ -112,8 +91,6 @@ void __init x86_64_start_kernel(char * r
 	if (console_loglevel == 10)
 		early_printk("Kernel alive\n");
 
-	x86_64_init_pda();
-
 	x86_64_start_reservations(real_mode_data);
 }
 
@@ -123,7 +100,7 @@ void __init x86_64_start_reservations(ch
 
 	reserve_trampoline_memory();
 
-	reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
+	reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Reserve INITRD */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/head_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/head_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/head_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/head_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/msr.h>
 #include <asm/cache.h>
 #include <asm/processor-flags.h>
+#include <asm/percpu.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -226,12 +227,15 @@ ENTRY(secondary_startup_64)
 	movl %eax,%fs
 	movl %eax,%gs
 
-	/* 
-	 * Setup up a dummy PDA. this is just for some early bootup code
-	 * that does in_interrupt() 
-	 */ 
+	/* Set up %gs.
+	 *
+	 * The base of %gs always points to the bottom of the irqstack
+	 * union.  If the stack protector canary is enabled, it is
+	 * located at %gs:40.  Note that, on SMP, the boot cpu uses
+	 * init data section till per cpu areas are set up.
+	 */
 	movl	$MSR_GS_BASE,%ecx
-	movq	$empty_zero_page,%rax
+	movq	initial_gs(%rip),%rax
 	movq    %rax,%rdx
 	shrq	$32,%rdx
 	wrmsr	
@@ -257,6 +261,8 @@ ENTRY(secondary_startup_64)
 	.align	8
 	ENTRY(initial_code)
 	.quad	x86_64_start_kernel
+	ENTRY(initial_gs)
+	.quad	INIT_PER_CPU_VAR(irq_stack_union)
 	__FINITDATA
 
 	ENTRY(stack_start)
@@ -323,8 +329,6 @@ early_idt_ripmsg:
 #endif /* CONFIG_EARLY_PRINTK */
 	.previous
 
-.balign PAGE_SIZE
-
 #define NEXT_PAGE(name) \
 	.balign	PAGE_SIZE; \
 ENTRY(name)
@@ -401,7 +405,8 @@ NEXT_PAGE(level2_spare_pgt)
 	.globl early_gdt_descr
 early_gdt_descr:
 	.word	GDT_ENTRIES*8-1
-	.quad   per_cpu__gdt_page
+early_gdt_descr_base:
+	.quad	INIT_PER_CPU_VAR(gdt_page)
 
 ENTRY(phys_base)
 	/* This must match the first entry in level2_kernel_pgt */
@@ -412,7 +417,7 @@ ENTRY(phys_base)
 	.section .bss, "aw", @nobits
 	.align L1_CACHE_BYTES
 ENTRY(idt_table)
-	.skip 256 * 16
+	.skip IDT_ENTRIES * 16
 
 	.section .bss.page_aligned, "aw", @nobits
 	.align PAGE_SIZE
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/hpet.c linux-libre-2.6.30-gnu1/arch/x86/kernel/hpet.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/hpet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/hpet.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,6 +80,7 @@ static inline void hpet_clear_mapping(vo
  */
 static int boot_hpet_disable;
 int hpet_force_user;
+static int hpet_verbose;
 
 static int __init hpet_setup(char *str)
 {
@@ -88,6 +89,8 @@ static int __init hpet_setup(char *str)
 			boot_hpet_disable = 1;
 		if (!strncmp("force", str, 5))
 			hpet_force_user = 1;
+		if (!strncmp("verbose", str, 7))
+			hpet_verbose = 1;
 	}
 	return 1;
 }
@@ -119,6 +122,43 @@ int is_hpet_enabled(void)
 }
 EXPORT_SYMBOL_GPL(is_hpet_enabled);
 
+static void _hpet_print_config(const char *function, int line)
+{
+	u32 i, timers, l, h;
+	printk(KERN_INFO "hpet: %s(%d):\n", function, line);
+	l = hpet_readl(HPET_ID);
+	h = hpet_readl(HPET_PERIOD);
+	timers = ((l & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
+	printk(KERN_INFO "hpet: ID: 0x%x, PERIOD: 0x%x\n", l, h);
+	l = hpet_readl(HPET_CFG);
+	h = hpet_readl(HPET_STATUS);
+	printk(KERN_INFO "hpet: CFG: 0x%x, STATUS: 0x%x\n", l, h);
+	l = hpet_readl(HPET_COUNTER);
+	h = hpet_readl(HPET_COUNTER+4);
+	printk(KERN_INFO "hpet: COUNTER_l: 0x%x, COUNTER_h: 0x%x\n", l, h);
+
+	for (i = 0; i < timers; i++) {
+		l = hpet_readl(HPET_Tn_CFG(i));
+		h = hpet_readl(HPET_Tn_CFG(i)+4);
+		printk(KERN_INFO "hpet: T%d: CFG_l: 0x%x, CFG_h: 0x%x\n",
+		       i, l, h);
+		l = hpet_readl(HPET_Tn_CMP(i));
+		h = hpet_readl(HPET_Tn_CMP(i)+4);
+		printk(KERN_INFO "hpet: T%d: CMP_l: 0x%x, CMP_h: 0x%x\n",
+		       i, l, h);
+		l = hpet_readl(HPET_Tn_ROUTE(i));
+		h = hpet_readl(HPET_Tn_ROUTE(i)+4);
+		printk(KERN_INFO "hpet: T%d ROUTE_l: 0x%x, ROUTE_h: 0x%x\n",
+		       i, l, h);
+	}
+}
+
+#define hpet_print_config()					\
+do {								\
+	if (hpet_verbose)					\
+		_hpet_print_config(__FUNCTION__, __LINE__);	\
+} while (0)
+
 /*
  * When the hpet driver (/dev/hpet) is enabled, we need to reserve
  * timer 0 and timer 1 in case of RTC emulation.
@@ -191,27 +231,42 @@ static struct clock_event_device hpet_cl
 	.rating		= 50,
 };
 
-static void hpet_start_counter(void)
+static void hpet_stop_counter(void)
 {
 	unsigned long cfg = hpet_readl(HPET_CFG);
-
 	cfg &= ~HPET_CFG_ENABLE;
 	hpet_writel(cfg, HPET_CFG);
+}
+
+static void hpet_reset_counter(void)
+{
 	hpet_writel(0, HPET_COUNTER);
 	hpet_writel(0, HPET_COUNTER + 4);
+}
+
+static void hpet_start_counter(void)
+{
+	unsigned long cfg = hpet_readl(HPET_CFG);
 	cfg |= HPET_CFG_ENABLE;
 	hpet_writel(cfg, HPET_CFG);
 }
 
+static void hpet_restart_counter(void)
+{
+	hpet_stop_counter();
+	hpet_reset_counter();
+	hpet_start_counter();
+}
+
 static void hpet_resume_device(void)
 {
 	force_hpet_resume();
 }
 
-static void hpet_restart_counter(void)
+static void hpet_resume_counter(void)
 {
 	hpet_resume_device();
-	hpet_start_counter();
+	hpet_restart_counter();
 }
 
 static void hpet_enable_legacy_int(void)
@@ -264,6 +319,7 @@ static void hpet_set_mode(enum clock_eve
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
+		hpet_stop_counter();
 		delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
 		delta >>= evt->shift;
 		now = hpet_readl(HPET_COUNTER);
@@ -274,14 +330,18 @@ static void hpet_set_mode(enum clock_eve
 		cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
 		       HPET_TN_SETVAL | HPET_TN_32BIT;
 		hpet_writel(cfg, HPET_Tn_CFG(timer));
-		/*
-		 * The first write after writing TN_SETVAL to the
-		 * config register sets the counter value, the second
-		 * write sets the period.
-		 */
 		hpet_writel(cmp, HPET_Tn_CMP(timer));
 		udelay(1);
+		/*
+		 * HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL
+		 * cleared) to T0_CMP to set the period. The HPET_TN_SETVAL
+		 * bit is automatically cleared after the first write.
+		 * (See AMD-8111 HyperTransport I/O Hub Data Sheet,
+		 * Publication # 24674)
+		 */
 		hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
+		hpet_start_counter();
+		hpet_print_config();
 		break;
 
 	case CLOCK_EVT_MODE_ONESHOT:
@@ -308,6 +368,7 @@ static void hpet_set_mode(enum clock_eve
 			irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
 			enable_irq(hdev->irq);
 		}
+		hpet_print_config();
 		break;
 	}
 }
@@ -526,6 +587,7 @@ static void hpet_msi_capability_lookup(u
 
 	num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
 	num_timers++; /* Value read out starts from 0 */
+	hpet_print_config();
 
 	hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL);
 	if (!hpet_devs)
@@ -676,7 +738,7 @@ static int hpet_cpuhp_notify(struct noti
 /*
  * Clock source related code
  */
-static cycle_t read_hpet(void)
+static cycle_t read_hpet(struct clocksource *cs)
 {
 	return (cycle_t)hpet_readl(HPET_COUNTER);
 }
@@ -695,7 +757,7 @@ static struct clocksource clocksource_hp
 	.mask		= HPET_MASK,
 	.shift		= HPET_SHIFT,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-	.resume		= hpet_restart_counter,
+	.resume		= hpet_resume_counter,
 #ifdef CONFIG_X86_64
 	.vread		= vread_hpet,
 #endif
@@ -707,10 +769,10 @@ static int hpet_clocksource_register(voi
 	cycle_t t1;
 
 	/* Start the counter */
-	hpet_start_counter();
+	hpet_restart_counter();
 
 	/* Verify whether hpet counter works */
-	t1 = read_hpet();
+	t1 = hpet_readl(HPET_COUNTER);
 	rdtscll(start);
 
 	/*
@@ -724,7 +786,7 @@ static int hpet_clocksource_register(voi
 		rdtscll(now);
 	} while ((now - start) < 200000UL);
 
-	if (t1 == read_hpet()) {
+	if (t1 == hpet_readl(HPET_COUNTER)) {
 		printk(KERN_WARNING
 		       "HPET counter not counting. HPET disabled\n");
 		return -ENODEV;
@@ -793,6 +855,7 @@ int __init hpet_enable(void)
 	 * information and the number of channels
 	 */
 	id = hpet_readl(HPET_ID);
+	hpet_print_config();
 
 #ifdef CONFIG_HPET_EMULATE_RTC
 	/*
@@ -845,6 +908,7 @@ static __init int hpet_late_init(void)
 		return -ENODEV;
 
 	hpet_reserve_platform_timers(hpet_readl(HPET_ID));
+	hpet_print_config();
 
 	for_each_online_cpu(cpu) {
 		hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/i8253.c linux-libre-2.6.30-gnu1/arch/x86/kernel/i8253.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/i8253.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/i8253.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,17 +3,17 @@
  *
  */
 #include <linux/clockchips.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
 
-#include <asm/smp.h>
-#include <asm/delay.h>
 #include <asm/i8253.h>
-#include <asm/io.h>
 #include <asm/hpet.h>
+#include <asm/smp.h>
 
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
@@ -40,7 +40,7 @@ static void init_pit_timer(enum clock_ev
 {
 	spin_lock(&i8253_lock);
 
-	switch(mode) {
+	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* binary, mode 2, LSB/MSB, ch 0 */
 		outb_pit(0x34, PIT_MODE);
@@ -95,7 +95,7 @@ static int pit_next_event(unsigned long
  * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
  * !using_apic_timer decisions in do_timer_interrupt_hook()
  */
-static struct clock_event_device pit_clockevent = {
+static struct clock_event_device pit_ce = {
 	.name		= "pit",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.set_mode	= init_pit_timer,
@@ -114,15 +114,13 @@ void __init setup_pit_timer(void)
 	 * Start pit with the boot cpu mask and make it global after the
 	 * IO_APIC has been initialized.
 	 */
-	pit_clockevent.cpumask = cpumask_of(smp_processor_id());
-	pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
-				     pit_clockevent.shift);
-	pit_clockevent.max_delta_ns =
-		clockevent_delta2ns(0x7FFF, &pit_clockevent);
-	pit_clockevent.min_delta_ns =
-		clockevent_delta2ns(0xF, &pit_clockevent);
-	clockevents_register_device(&pit_clockevent);
-	global_clock_event = &pit_clockevent;
+	pit_ce.cpumask = cpumask_of(smp_processor_id());
+	pit_ce.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
+	pit_ce.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_ce);
+	pit_ce.min_delta_ns = clockevent_delta2ns(0xF, &pit_ce);
+
+	clockevents_register_device(&pit_ce);
+	global_clock_event = &pit_ce;
 }
 
 #ifndef CONFIG_X86_64
@@ -131,13 +129,13 @@ void __init setup_pit_timer(void)
  * to just read by itself. So use jiffies to emulate a free
  * running counter:
  */
-static cycle_t pit_read(void)
+static cycle_t pit_read(struct clocksource *cs)
 {
+	static int old_count;
+	static u32 old_jifs;
 	unsigned long flags;
 	int count;
 	u32 jifs;
-	static int old_count;
-	static u32 old_jifs;
 
 	spin_lock_irqsave(&i8253_lock, flags);
 	/*
@@ -179,9 +177,9 @@ static cycle_t pit_read(void)
 	 * Previous attempts to handle these cases intelligently were
 	 * buggy, so we just do the simple thing now.
 	 */
-	if (count > old_count && jifs == old_jifs) {
+	if (count > old_count && jifs == old_jifs)
 		count = old_count;
-	}
+
 	old_count = count;
 	old_jifs = jifs;
 
@@ -192,13 +190,13 @@ static cycle_t pit_read(void)
 	return (cycle_t)(jifs * LATCH) + count;
 }
 
-static struct clocksource clocksource_pit = {
-	.name	= "pit",
-	.rating = 110,
-	.read	= pit_read,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.mult	= 0,
-	.shift	= 20,
+static struct clocksource pit_cs = {
+	.name		= "pit",
+	.rating		= 110,
+	.read		= pit_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.mult		= 0,
+	.shift		= 20,
 };
 
 static void pit_disable_clocksource(void)
@@ -206,9 +204,9 @@ static void pit_disable_clocksource(void
 	/*
 	 * Use mult to check whether it is registered or not
 	 */
-	if (clocksource_pit.mult) {
-		clocksource_unregister(&clocksource_pit);
-		clocksource_pit.mult = 0;
+	if (pit_cs.mult) {
+		clocksource_unregister(&pit_cs);
+		pit_cs.mult = 0;
 	}
 }
 
@@ -222,13 +220,13 @@ static int __init init_pit_clocksource(v
 	  * - when local APIC timer is active (PIT is switched off)
 	  */
 	if (num_possible_cpus() > 1 || is_hpet_enabled() ||
-	    pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC)
+	    pit_ce.mode != CLOCK_EVT_MODE_PERIODIC)
 		return 0;
 
-	clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
-						   clocksource_pit.shift);
-	return clocksource_register(&clocksource_pit);
+	pit_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, pit_cs.shift);
+
+	return clocksource_register(&pit_cs);
 }
 arch_initcall(init_pit_clocksource);
 
-#endif
+#endif /* !CONFIG_X86_64 */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/i8259.c linux-libre-2.6.30-gnu1/arch/x86/kernel/i8259.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/i8259.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/i8259.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,6 @@
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 #include <asm/apic.h>
-#include <asm/arch_hooks.h>
 #include <asm/i8259.h>
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/io_apic.c linux-libre-2.6.30-gnu1/arch/x86/kernel/io_apic.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/io_apic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/io_apic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4169 +0,0 @@
-/*
- *	Intel IO-APIC support for multi-Pentium hosts.
- *
- *	Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
- *
- *	Many thanks to Stig Venaas for trying out countless experimental
- *	patches and reporting/debugging problems patiently!
- *
- *	(c) 1999, Multiple IO-APIC support, developed by
- *	Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
- *      Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
- *	further tested and cleaned up by Zach Brown <zab@redhat.com>
- *	and Ingo Molnar <mingo@redhat.com>
- *
- *	Fixes
- *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs;
- *					thanks to Eric Gilmore
- *					and Rolf G. Tews
- *					for testing these extensively
- *	Paul Diefenbaugh	:	Added full ACPI support
- */
-
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/mc146818rtc.h>
-#include <linux/compiler.h>
-#include <linux/acpi.h>
-#include <linux/module.h>
-#include <linux/sysdev.h>
-#include <linux/msi.h>
-#include <linux/htirq.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-#include <linux/jiffies.h>	/* time_after() */
-#ifdef CONFIG_ACPI
-#include <acpi/acpi_bus.h>
-#endif
-#include <linux/bootmem.h>
-#include <linux/dmar.h>
-#include <linux/hpet.h>
-
-#include <asm/idle.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/desc.h>
-#include <asm/proto.h>
-#include <asm/acpi.h>
-#include <asm/dma.h>
-#include <asm/timer.h>
-#include <asm/i8259.h>
-#include <asm/nmi.h>
-#include <asm/msidef.h>
-#include <asm/hypertransport.h>
-#include <asm/setup.h>
-#include <asm/irq_remapping.h>
-#include <asm/hpet.h>
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/uv_irq.h>
-
-#include <mach_ipi.h>
-#include <mach_apic.h>
-#include <mach_apicdef.h>
-
-#define __apicdebuginit(type) static type __init
-
-/*
- *      Is the SiS APIC rmw bug present ?
- *      -1 = don't know, 0 = no, 1 = yes
- */
-int sis_apic_bug = -1;
-
-static DEFINE_SPINLOCK(ioapic_lock);
-static DEFINE_SPINLOCK(vector_lock);
-
-/*
- * # of IRQ routing registers
- */
-int nr_ioapic_registers[MAX_IO_APICS];
-
-/* I/O APIC entries */
-struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
-int nr_ioapics;
-
-/* MP IRQ source entries */
-struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-
-/* # of MP IRQ source entries */
-int mp_irq_entries;
-
-#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
-int mp_bus_id_to_type[MAX_MP_BUSSES];
-#endif
-
-DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
-
-int skip_ioapic_setup;
-
-static int __init parse_noapic(char *str)
-{
-	/* disable IO-APIC */
-	disable_ioapic_setup();
-	return 0;
-}
-early_param("noapic", parse_noapic);
-
-struct irq_pin_list;
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
-struct irq_pin_list {
-	int apic, pin;
-	struct irq_pin_list *next;
-};
-
-static struct irq_pin_list *get_one_free_irq_2_pin(int cpu)
-{
-	struct irq_pin_list *pin;
-	int node;
-
-	node = cpu_to_node(cpu);
-
-	pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node);
-
-	return pin;
-}
-
-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;
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-	u8 move_desc_pending : 1;
-#endif
-};
-
-/* 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[] = {
-#else
-static struct irq_cfg irq_cfgx[NR_IRQS] = {
-#endif
-	[0]  = { .vector = IRQ0_VECTOR,  },
-	[1]  = { .vector = IRQ1_VECTOR,  },
-	[2]  = { .vector = IRQ2_VECTOR,  },
-	[3]  = { .vector = IRQ3_VECTOR,  },
-	[4]  = { .vector = IRQ4_VECTOR,  },
-	[5]  = { .vector = IRQ5_VECTOR,  },
-	[6]  = { .vector = IRQ6_VECTOR,  },
-	[7]  = { .vector = IRQ7_VECTOR,  },
-	[8]  = { .vector = IRQ8_VECTOR,  },
-	[9]  = { .vector = IRQ9_VECTOR,  },
-	[10] = { .vector = IRQ10_VECTOR, },
-	[11] = { .vector = IRQ11_VECTOR, },
-	[12] = { .vector = IRQ12_VECTOR, },
-	[13] = { .vector = IRQ13_VECTOR, },
-	[14] = { .vector = IRQ14_VECTOR, },
-	[15] = { .vector = IRQ15_VECTOR, },
-};
-
-int __init arch_early_irq_init(void)
-{
-	struct irq_cfg *cfg;
-	struct irq_desc *desc;
-	int count;
-	int i;
-
-	cfg = irq_cfgx;
-	count = ARRAY_SIZE(irq_cfgx);
-
-	for (i = 0; i < count; i++) {
-		desc = irq_to_desc(i);
-		desc->chip_data = &cfg[i];
-		alloc_bootmem_cpumask_var(&cfg[i].domain);
-		alloc_bootmem_cpumask_var(&cfg[i].old_domain);
-		if (i < NR_IRQS_LEGACY)
-			cpumask_setall(cfg[i].domain);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_SPARSE_IRQ
-static struct irq_cfg *irq_cfg(unsigned int irq)
-{
-	struct irq_cfg *cfg = NULL;
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-	if (desc)
-		cfg = desc->chip_data;
-
-	return cfg;
-}
-
-static struct irq_cfg *get_one_free_irq_cfg(int cpu)
-{
-	struct irq_cfg *cfg;
-	int node;
-
-	node = cpu_to_node(cpu);
-
-	cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node);
-	if (cfg) {
-		if (!alloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) {
-			kfree(cfg);
-			cfg = NULL;
-		} else if (!alloc_cpumask_var_node(&cfg->old_domain,
-							  GFP_ATOMIC, node)) {
-			free_cpumask_var(cfg->domain);
-			kfree(cfg);
-			cfg = NULL;
-		} else {
-			cpumask_clear(cfg->domain);
-			cpumask_clear(cfg->old_domain);
-		}
-	}
-
-	return cfg;
-}
-
-int arch_init_chip_data(struct irq_desc *desc, int cpu)
-{
-	struct irq_cfg *cfg;
-
-	cfg = desc->chip_data;
-	if (!cfg) {
-		desc->chip_data = get_one_free_irq_cfg(cpu);
-		if (!desc->chip_data) {
-			printk(KERN_ERR "can not alloc irq_cfg\n");
-			BUG_ON(1);
-		}
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-
-static void
-init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu)
-{
-	struct irq_pin_list *old_entry, *head, *tail, *entry;
-
-	cfg->irq_2_pin = NULL;
-	old_entry = old_cfg->irq_2_pin;
-	if (!old_entry)
-		return;
-
-	entry = get_one_free_irq_2_pin(cpu);
-	if (!entry)
-		return;
-
-	entry->apic	= old_entry->apic;
-	entry->pin	= old_entry->pin;
-	head		= entry;
-	tail		= entry;
-	old_entry	= old_entry->next;
-	while (old_entry) {
-		entry = get_one_free_irq_2_pin(cpu);
-		if (!entry) {
-			entry = head;
-			while (entry) {
-				head = entry->next;
-				kfree(entry);
-				entry = head;
-			}
-			/* still use the old one */
-			return;
-		}
-		entry->apic	= old_entry->apic;
-		entry->pin	= old_entry->pin;
-		tail->next	= entry;
-		tail		= entry;
-		old_entry	= old_entry->next;
-	}
-
-	tail->next = NULL;
-	cfg->irq_2_pin = head;
-}
-
-static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg)
-{
-	struct irq_pin_list *entry, *next;
-
-	if (old_cfg->irq_2_pin == cfg->irq_2_pin)
-		return;
-
-	entry = old_cfg->irq_2_pin;
-
-	while (entry) {
-		next = entry->next;
-		kfree(entry);
-		entry = next;
-	}
-	old_cfg->irq_2_pin = NULL;
-}
-
-void arch_init_copy_chip_data(struct irq_desc *old_desc,
-				 struct irq_desc *desc, int cpu)
-{
-	struct irq_cfg *cfg;
-	struct irq_cfg *old_cfg;
-
-	cfg = get_one_free_irq_cfg(cpu);
-
-	if (!cfg)
-		return;
-
-	desc->chip_data = cfg;
-
-	old_cfg = old_desc->chip_data;
-
-	memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
-
-	init_copy_irq_2_pin(old_cfg, cfg, cpu);
-}
-
-static void free_irq_cfg(struct irq_cfg *old_cfg)
-{
-	kfree(old_cfg);
-}
-
-void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
-{
-	struct irq_cfg *old_cfg, *cfg;
-
-	old_cfg = old_desc->chip_data;
-	cfg = desc->chip_data;
-
-	if (old_cfg == cfg)
-		return;
-
-	if (old_cfg) {
-		free_irq_2_pin(old_cfg, cfg);
-		free_irq_cfg(old_cfg);
-		old_desc->chip_data = NULL;
-	}
-}
-
-static void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-	struct irq_cfg *cfg = desc->chip_data;
-
-	if (!cfg->move_in_progress) {
-		/* it means that domain is not changed */
-		if (!cpumask_intersects(&desc->affinity, mask))
-			cfg->move_desc_pending = 1;
-	}
-}
-#endif
-
-#else
-static struct irq_cfg *irq_cfg(unsigned int irq)
-{
-	return irq < nr_irqs ? irq_cfgx + irq : NULL;
-}
-
-#endif
-
-#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC
-static inline void
-set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-}
-#endif
-
-struct io_apic {
-	unsigned int index;
-	unsigned int unused[3];
-	unsigned int data;
-};
-
-static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
-{
-	return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
-		+ (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
-}
-
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-	struct io_apic __iomem *io_apic = io_apic_base(apic);
-	writel(reg, &io_apic->index);
-	return readl(&io_apic->data);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	struct io_apic __iomem *io_apic = io_apic_base(apic);
-	writel(reg, &io_apic->index);
-	writel(value, &io_apic->data);
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index register
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
-	struct io_apic __iomem *io_apic = io_apic_base(apic);
-
-	if (sis_apic_bug)
-		writel(reg, &io_apic->index);
-	writel(value, &io_apic->data);
-}
-
-static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
-{
-	struct irq_pin_list *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	entry = cfg->irq_2_pin;
-	for (;;) {
-		unsigned int reg;
-		int pin;
-
-		if (!entry)
-			break;
-		pin = entry->pin;
-		reg = io_apic_read(entry->apic, 0x10 + pin*2);
-		/* Is the remote IRR bit set? */
-		if (reg & IO_APIC_REDIR_REMOTE_IRR) {
-			spin_unlock_irqrestore(&ioapic_lock, flags);
-			return true;
-		}
-		if (!entry->next)
-			break;
-		entry = entry->next;
-	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	return false;
-}
-
-union entry_union {
-	struct { u32 w1, w2; };
-	struct IO_APIC_route_entry entry;
-};
-
-static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
-{
-	union entry_union eu;
-	unsigned long flags;
-	spin_lock_irqsave(&ioapic_lock, flags);
-	eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
-	eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-	return eu.entry;
-}
-
-/*
- * When we write a new IO APIC routing entry, we need to write the high
- * word first! If the mask bit in the low word is clear, we will enable
- * the interrupt, and we need to make sure the entry is fully populated
- * before that happens.
- */
-static void
-__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
-	union entry_union eu;
-	eu.entry = e;
-	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
-	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
-}
-
-static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&ioapic_lock, flags);
-	__ioapic_write_entry(apic, pin, e);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-/*
- * When we mask an IO APIC routing entry, we need to write the low
- * word first, in order to set the mask bit before we change the
- * high bits!
- */
-static void ioapic_mask_entry(int apic, int pin)
-{
-	unsigned long flags;
-	union entry_union eu = { .entry.mask = 1 };
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
-	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-#ifdef CONFIG_SMP
-static 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)
-			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);
-		send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
-		free_cpumask_var(cleanup_mask);
-	}
-	cfg->move_in_progress = 0;
-}
-
-static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
-{
-	int apic, pin;
-	struct irq_pin_list *entry;
-	u8 vector = cfg->vector;
-
-	entry = cfg->irq_2_pin;
-	for (;;) {
-		unsigned int reg;
-
-		if (!entry)
-			break;
-
-		apic = entry->apic;
-		pin = entry->pin;
-#ifdef CONFIG_INTR_REMAP
-		/*
-		 * With interrupt-remapping, destination information comes
-		 * from interrupt-remapping table entry.
-		 */
-		if (!irq_remapped(irq))
-			io_apic_write(apic, 0x11 + pin*2, dest);
-#else
-		io_apic_write(apic, 0x11 + pin*2, dest);
-#endif
-		reg = io_apic_read(apic, 0x10 + pin*2);
-		reg &= ~IO_APIC_REDIR_VECTOR_MASK;
-		reg |= vector;
-		io_apic_modify(apic, 0x10 + pin*2, reg);
-		if (!entry->next)
-			break;
-		entry = entry->next;
-	}
-}
-
-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 leaves desc->affinity untouched.
- */
-static unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
-{
-	struct irq_cfg *cfg;
-	unsigned int irq;
-
-	if (!cpumask_intersects(mask, cpu_online_mask))
-		return BAD_APICID;
-
-	irq = desc->irq;
-	cfg = desc->chip_data;
-	if (assign_irq_vector(irq, cfg, mask))
-		return BAD_APICID;
-
-	cpumask_and(&desc->affinity, cfg->domain, mask);
-	set_extra_move_desc(desc, mask);
-	return cpu_mask_to_apicid_and(&desc->affinity, cpu_online_mask);
-}
-
-static void
-set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-	struct irq_cfg *cfg;
-	unsigned long flags;
-	unsigned int dest;
-	unsigned int irq;
-
-	irq = desc->irq;
-	cfg = desc->chip_data;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	dest = set_desc_affinity(desc, mask);
-	if (dest != BAD_APICID) {
-		/* Only the high 8 bits are valid. */
-		dest = SET_APIC_LOGICAL_ID(dest);
-		__target_IO_APIC_irq(irq, dest, cfg);
-	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void
-set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc;
-
-	desc = irq_to_desc(irq);
-
-	set_ioapic_affinity_irq_desc(desc, mask);
-}
-#endif /* CONFIG_SMP */
-
-/*
- * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
- * shared ISA-space IRQs, so we have to support them. We are super
- * fast in the common case, and fast for shared ISA-space IRQs.
- */
-static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin)
-{
-	struct irq_pin_list *entry;
-
-	entry = cfg->irq_2_pin;
-	if (!entry) {
-		entry = get_one_free_irq_2_pin(cpu);
-		if (!entry) {
-			printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
-					apic, pin);
-			return;
-		}
-		cfg->irq_2_pin = entry;
-		entry->apic = apic;
-		entry->pin = pin;
-		return;
-	}
-
-	while (entry->next) {
-		/* not again, please */
-		if (entry->apic == apic && entry->pin == pin)
-			return;
-
-		entry = entry->next;
-	}
-
-	entry->next = get_one_free_irq_2_pin(cpu);
-	entry = entry->next;
-	entry->apic = apic;
-	entry->pin = pin;
-}
-
-/*
- * Reroute an IRQ to a different pin.
- */
-static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu,
-				      int oldapic, int oldpin,
-				      int newapic, int newpin)
-{
-	struct irq_pin_list *entry = cfg->irq_2_pin;
-	int replaced = 0;
-
-	while (entry) {
-		if (entry->apic == oldapic && entry->pin == oldpin) {
-			entry->apic = newapic;
-			entry->pin = newpin;
-			replaced = 1;
-			/* every one is different, right? */
-			break;
-		}
-		entry = entry->next;
-	}
-
-	/* why? call replace before add? */
-	if (!replaced)
-		add_pin_to_irq_cpu(cfg, cpu, newapic, newpin);
-}
-
-static inline 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 (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) {
-		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);
-	}
-}
-
-static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
-}
-
-#ifdef CONFIG_X86_64
-static void io_apic_sync(struct irq_pin_list *entry)
-{
-	/*
-	 * Synchronize the IO-APIC and the CPU by doing
-	 * a dummy read from the IO-APIC
-	 */
-	struct io_apic __iomem *io_apic;
-	io_apic = io_apic_base(entry->apic);
-	readl(&io_apic->data);
-}
-
-static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
-}
-#else /* CONFIG_X86_32 */
-static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL);
-}
-
-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);
-}
-#endif /* CONFIG_X86_32 */
-
-static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
-{
-	struct irq_cfg *cfg = desc->chip_data;
-	unsigned long flags;
-
-	BUG_ON(!cfg);
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	__mask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void unmask_IO_APIC_irq_desc(struct irq_desc *desc)
-{
-	struct irq_cfg *cfg = desc->chip_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	__unmask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void mask_IO_APIC_irq(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	mask_IO_APIC_irq_desc(desc);
-}
-static void unmask_IO_APIC_irq(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	unmask_IO_APIC_irq_desc(desc);
-}
-
-static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
-{
-	struct IO_APIC_route_entry entry;
-
-	/* Check delivery_mode to be sure we're not clearing an SMI pin */
-	entry = ioapic_read_entry(apic, pin);
-	if (entry.delivery_mode == dest_SMI)
-		return;
-	/*
-	 * Disable it in the IO-APIC irq-routing table:
-	 */
-	ioapic_mask_entry(apic, pin);
-}
-
-static void clear_IO_APIC (void)
-{
-	int apic, pin;
-
-	for (apic = 0; apic < nr_ioapics; apic++)
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-			clear_IO_APIC_pin(apic, pin);
-}
-
-#if !defined(CONFIG_SMP) && defined(CONFIG_X86_32)
-void send_IPI_self(int vector)
-{
-	unsigned int cfg;
-
-	/*
-	 * Wait for idle.
-	 */
-	apic_wait_icr_idle();
-	cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
-	/*
-	 * Send the IPI. The write to APIC_ICR fires this off.
-	 */
-	apic_write(APIC_ICR, cfg);
-}
-#endif /* !CONFIG_SMP && CONFIG_X86_32*/
-
-#ifdef CONFIG_X86_32
-/*
- * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
- * specific CPU-side IRQs.
- */
-
-#define MAX_PIRQS 8
-static int pirq_entries [MAX_PIRQS];
-static int pirqs_enabled;
-
-static int __init ioapic_pirq_setup(char *str)
-{
-	int i, max;
-	int ints[MAX_PIRQS+1];
-
-	get_options(str, ARRAY_SIZE(ints), ints);
-
-	for (i = 0; i < MAX_PIRQS; i++)
-		pirq_entries[i] = -1;
-
-	pirqs_enabled = 1;
-	apic_printk(APIC_VERBOSE, KERN_INFO
-			"PIRQ redirection, working around broken MP-BIOS.\n");
-	max = MAX_PIRQS;
-	if (ints[0] < MAX_PIRQS)
-		max = ints[0];
-
-	for (i = 0; i < max; i++) {
-		apic_printk(APIC_VERBOSE, KERN_DEBUG
-				"... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
-		/*
-		 * PIRQs are mapped upside down, usually.
-		 */
-		pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
-	}
-	return 1;
-}
-
-__setup("pirq=", ioapic_pirq_setup);
-#endif /* CONFIG_X86_32 */
-
-#ifdef CONFIG_INTR_REMAP
-/* I/O APIC RTE contents at the OS boot up */
-static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
-
-/*
- * Saves and masks all the unmasked IO-APIC RTE's
- */
-int save_mask_IO_APIC_setup(void)
-{
-	union IO_APIC_reg_01 reg_01;
-	unsigned long flags;
-	int apic, pin;
-
-	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(apic, 1);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-	}
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		early_ioapic_entries[apic] =
-			kzalloc(sizeof(struct IO_APIC_route_entry) *
-				nr_ioapic_registers[apic], GFP_KERNEL);
-		if (!early_ioapic_entries[apic])
-			goto nomem;
-	}
-
-	for (apic = 0; apic < nr_ioapics; apic++)
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-			struct IO_APIC_route_entry entry;
-
-			entry = early_ioapic_entries[apic][pin] =
-				ioapic_read_entry(apic, pin);
-			if (!entry.mask) {
-				entry.mask = 1;
-				ioapic_write_entry(apic, pin, entry);
-			}
-		}
-
-	return 0;
-
-nomem:
-	while (apic >= 0)
-		kfree(early_ioapic_entries[apic--]);
-	memset(early_ioapic_entries, 0,
-		ARRAY_SIZE(early_ioapic_entries));
-
-	return -ENOMEM;
-}
-
-void restore_IO_APIC_setup(void)
-{
-	int apic, pin;
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		if (!early_ioapic_entries[apic])
-			break;
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-			ioapic_write_entry(apic, pin,
-					   early_ioapic_entries[apic][pin]);
-		kfree(early_ioapic_entries[apic]);
-		early_ioapic_entries[apic] = NULL;
-	}
-}
-
-void reinit_intr_remapped_IO_APIC(int intr_remapping)
-{
-	/*
-	 * for now plain restore of previous settings.
-	 * TBD: In the case of OS enabling interrupt-remapping,
-	 * IO-APIC RTE's need to be setup to point to interrupt-remapping
-	 * table entries. for now, do a plain restore, and wait for
-	 * the setup_IO_APIC_irqs() to do proper initialization.
-	 */
-	restore_IO_APIC_setup();
-}
-#endif
-
-/*
- * Find the IRQ entry number of a certain pin.
- */
-static int find_irq_entry(int apic, int pin, int type)
-{
-	int i;
-
-	for (i = 0; i < mp_irq_entries; i++)
-		if (mp_irqs[i].mp_irqtype == type &&
-		    (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
-		     mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
-		    mp_irqs[i].mp_dstirq == pin)
-			return i;
-
-	return -1;
-}
-
-/*
- * Find the pin to which IRQ[irq] (ISA) is connected
- */
-static int __init find_isa_irq_pin(int irq, int type)
-{
-	int i;
-
-	for (i = 0; i < mp_irq_entries; i++) {
-		int lbus = mp_irqs[i].mp_srcbus;
-
-		if (test_bit(lbus, mp_bus_not_pci) &&
-		    (mp_irqs[i].mp_irqtype == type) &&
-		    (mp_irqs[i].mp_srcbusirq == irq))
-
-			return mp_irqs[i].mp_dstirq;
-	}
-	return -1;
-}
-
-static int __init find_isa_irq_apic(int irq, int type)
-{
-	int i;
-
-	for (i = 0; i < mp_irq_entries; i++) {
-		int lbus = mp_irqs[i].mp_srcbus;
-
-		if (test_bit(lbus, mp_bus_not_pci) &&
-		    (mp_irqs[i].mp_irqtype == type) &&
-		    (mp_irqs[i].mp_srcbusirq == irq))
-			break;
-	}
-	if (i < mp_irq_entries) {
-		int apic;
-		for(apic = 0; apic < nr_ioapics; apic++) {
-			if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
-				return apic;
-		}
-	}
-
-	return -1;
-}
-
-/*
- * Find a specific PCI IRQ entry.
- * Not an __init, possibly needed by modules
- */
-static int pin_2_irq(int idx, int apic, int pin);
-
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-{
-	int apic, i, best_guess = -1;
-
-	apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
-		bus, slot, pin);
-	if (test_bit(bus, mp_bus_not_pci)) {
-		apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
-		return -1;
-	}
-	for (i = 0; i < mp_irq_entries; i++) {
-		int lbus = mp_irqs[i].mp_srcbus;
-
-		for (apic = 0; apic < nr_ioapics; apic++)
-			if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
-			    mp_irqs[i].mp_dstapic == MP_APIC_ALL)
-				break;
-
-		if (!test_bit(lbus, mp_bus_not_pci) &&
-		    !mp_irqs[i].mp_irqtype &&
-		    (bus == lbus) &&
-		    (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
-			int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq);
-
-			if (!(apic || IO_APIC_IRQ(irq)))
-				continue;
-
-			if (pin == (mp_irqs[i].mp_srcbusirq & 3))
-				return irq;
-			/*
-			 * Use the first all-but-pin matching entry as a
-			 * best-guess fuzzy result for broken mptables.
-			 */
-			if (best_guess < 0)
-				best_guess = irq;
-		}
-	}
-	return best_guess;
-}
-
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
-/*
- * EISA Edge/Level control register, ELCR
- */
-static int EISA_ELCR(unsigned int irq)
-{
-	if (irq < NR_IRQS_LEGACY) {
-		unsigned int port = 0x4d0 + (irq >> 3);
-		return (inb(port) >> (irq & 7)) & 1;
-	}
-	apic_printk(APIC_VERBOSE, KERN_INFO
-			"Broken MPtable reports ISA irq %d\n", irq);
-	return 0;
-}
-
-#endif
-
-/* ISA interrupts are always polarity zero edge triggered,
- * when listed as conforming in the MP table. */
-
-#define default_ISA_trigger(idx)	(0)
-#define default_ISA_polarity(idx)	(0)
-
-/* EISA interrupts are always polarity zero and can be edge or level
- * trigger depending on the ELCR value.  If an interrupt is listed as
- * EISA conforming in the MP table, that means its trigger type must
- * be read in from the ELCR */
-
-#define default_EISA_trigger(idx)	(EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
-#define default_EISA_polarity(idx)	default_ISA_polarity(idx)
-
-/* PCI interrupts are always polarity one level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_PCI_trigger(idx)	(1)
-#define default_PCI_polarity(idx)	(1)
-
-/* MCA interrupts are always polarity zero level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_MCA_trigger(idx)	(1)
-#define default_MCA_polarity(idx)	default_ISA_polarity(idx)
-
-static int MPBIOS_polarity(int idx)
-{
-	int bus = mp_irqs[idx].mp_srcbus;
-	int polarity;
-
-	/*
-	 * Determine IRQ line polarity (high active or low active):
-	 */
-	switch (mp_irqs[idx].mp_irqflag & 3)
-	{
-		case 0: /* conforms, ie. bus-type dependent polarity */
-			if (test_bit(bus, mp_bus_not_pci))
-				polarity = default_ISA_polarity(idx);
-			else
-				polarity = default_PCI_polarity(idx);
-			break;
-		case 1: /* high active */
-		{
-			polarity = 0;
-			break;
-		}
-		case 2: /* reserved */
-		{
-			printk(KERN_WARNING "broken BIOS!!\n");
-			polarity = 1;
-			break;
-		}
-		case 3: /* low active */
-		{
-			polarity = 1;
-			break;
-		}
-		default: /* invalid */
-		{
-			printk(KERN_WARNING "broken BIOS!!\n");
-			polarity = 1;
-			break;
-		}
-	}
-	return polarity;
-}
-
-static int MPBIOS_trigger(int idx)
-{
-	int bus = mp_irqs[idx].mp_srcbus;
-	int trigger;
-
-	/*
-	 * Determine IRQ trigger mode (edge or level sensitive):
-	 */
-	switch ((mp_irqs[idx].mp_irqflag>>2) & 3)
-	{
-		case 0: /* conforms, ie. bus-type dependent */
-			if (test_bit(bus, mp_bus_not_pci))
-				trigger = default_ISA_trigger(idx);
-			else
-				trigger = default_PCI_trigger(idx);
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
-			switch (mp_bus_id_to_type[bus]) {
-				case MP_BUS_ISA: /* ISA pin */
-				{
-					/* set before the switch */
-					break;
-				}
-				case MP_BUS_EISA: /* EISA pin */
-				{
-					trigger = default_EISA_trigger(idx);
-					break;
-				}
-				case MP_BUS_PCI: /* PCI pin */
-				{
-					/* set before the switch */
-					break;
-				}
-				case MP_BUS_MCA: /* MCA pin */
-				{
-					trigger = default_MCA_trigger(idx);
-					break;
-				}
-				default:
-				{
-					printk(KERN_WARNING "broken BIOS!!\n");
-					trigger = 1;
-					break;
-				}
-			}
-#endif
-			break;
-		case 1: /* edge */
-		{
-			trigger = 0;
-			break;
-		}
-		case 2: /* reserved */
-		{
-			printk(KERN_WARNING "broken BIOS!!\n");
-			trigger = 1;
-			break;
-		}
-		case 3: /* level */
-		{
-			trigger = 1;
-			break;
-		}
-		default: /* invalid */
-		{
-			printk(KERN_WARNING "broken BIOS!!\n");
-			trigger = 0;
-			break;
-		}
-	}
-	return trigger;
-}
-
-static inline int irq_polarity(int idx)
-{
-	return MPBIOS_polarity(idx);
-}
-
-static inline int irq_trigger(int idx)
-{
-	return MPBIOS_trigger(idx);
-}
-
-int (*ioapic_renumber_irq)(int ioapic, int irq);
-static int pin_2_irq(int idx, int apic, int pin)
-{
-	int irq, i;
-	int bus = mp_irqs[idx].mp_srcbus;
-
-	/*
-	 * Debugging check, we are in big trouble if this message pops up!
-	 */
-	if (mp_irqs[idx].mp_dstirq != pin)
-		printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
-
-	if (test_bit(bus, mp_bus_not_pci)) {
-		irq = mp_irqs[idx].mp_srcbusirq;
-	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
-		/*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-		if (ioapic_renumber_irq)
-			irq = ioapic_renumber_irq(apic, irq);
-	}
-
-#ifdef CONFIG_X86_32
-	/*
-	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
-	 */
-	if ((pin >= 16) && (pin <= 23)) {
-		if (pirq_entries[pin-16] != -1) {
-			if (!pirq_entries[pin-16]) {
-				apic_printk(APIC_VERBOSE, KERN_DEBUG
-						"disabling PIRQ%d\n", pin-16);
-			} else {
-				irq = pirq_entries[pin-16];
-				apic_printk(APIC_VERBOSE, KERN_DEBUG
-						"using PIRQ%d -> IRQ %d\n",
-						pin-16, irq);
-			}
-		}
-	}
-#endif
-
-	return irq;
-}
-
-void lock_vector_lock(void)
-{
-	/* Used to the online set of cpus does not change
-	 * during assign_irq_vector.
-	 */
-	spin_lock(&vector_lock);
-}
-
-void unlock_vector_lock(void)
-{
-	spin_unlock(&vector_lock);
-}
-
-static int
-__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
-{
-	/*
-	 * NOTE! The local APIC isn't very good at handling
-	 * multiple interrupts at the same interrupt level.
-	 * As the interrupt level is determined by taking the
-	 * vector number and shifting that right by 4, we
-	 * want to spread these out a bit so that they don't
-	 * all fall in the same interrupt level.
-	 *
-	 * Also, we've got to be careful not to trash gate
-	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
-	 */
-	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
-	unsigned int old_vector;
-	int cpu, err;
-	cpumask_var_t tmp_mask;
-
-	if ((cfg->move_in_progress) || cfg->move_cleanup_count)
-		return -EBUSY;
-
-	if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC))
-		return -ENOMEM;
-
-	old_vector = cfg->vector;
-	if (old_vector) {
-		cpumask_and(tmp_mask, mask, cpu_online_mask);
-		cpumask_and(tmp_mask, cfg->domain, tmp_mask);
-		if (!cpumask_empty(tmp_mask)) {
-			free_cpumask_var(tmp_mask);
-			return 0;
-		}
-	}
-
-	/* Only try and allocate irqs on cpus that are present */
-	err = -ENOSPC;
-	for_each_cpu_and(cpu, mask, cpu_online_mask) {
-		int new_cpu;
-		int vector, offset;
-
-		vector_allocation_domain(cpu, tmp_mask);
-
-		vector = current_vector;
-		offset = current_offset;
-next:
-		vector += 8;
-		if (vector >= first_system_vector) {
-			/* If out of vectors on large boxen, must share them. */
-			offset = (offset + 1) % 8;
-			vector = FIRST_DEVICE_VECTOR + offset;
-		}
-		if (unlikely(current_vector == vector))
-			continue;
-
-		if (test_bit(vector, used_vectors))
-			goto next;
-
-		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
-			if (per_cpu(vector_irq, new_cpu)[vector] != -1)
-				goto next;
-		/* Found one! */
-		current_vector = vector;
-		current_offset = offset;
-		if (old_vector) {
-			cfg->move_in_progress = 1;
-			cpumask_copy(cfg->old_domain, cfg->domain);
-		}
-		for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
-			per_cpu(vector_irq, new_cpu)[vector] = irq;
-		cfg->vector = vector;
-		cpumask_copy(cfg->domain, tmp_mask);
-		err = 0;
-		break;
-	}
-	free_cpumask_var(tmp_mask);
-	return err;
-}
-
-static int
-assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)
-{
-	int err;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	err = __assign_irq_vector(irq, cfg, mask);
-	spin_unlock_irqrestore(&vector_lock, flags);
-	return err;
-}
-
-static void __clear_irq_vector(int irq, struct irq_cfg *cfg)
-{
-	int cpu, vector;
-
-	BUG_ON(!cfg->vector);
-
-	vector = cfg->vector;
-	for_each_cpu_and(cpu, cfg->domain, cpu_online_mask)
-		per_cpu(vector_irq, cpu)[vector] = -1;
-
-	cfg->vector = 0;
-	cpumask_clear(cfg->domain);
-
-	if (likely(!cfg->move_in_progress))
-		return;
-	for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) {
-		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
-								vector++) {
-			if (per_cpu(vector_irq, cpu)[vector] != irq)
-				continue;
-			per_cpu(vector_irq, cpu)[vector] = -1;
-			break;
-		}
-	}
-	cfg->move_in_progress = 0;
-}
-
-void __setup_vector_irq(int cpu)
-{
-	/* Initialize vector_irq on a new cpu */
-	/* This function must be called with vector_lock held */
-	int irq, vector;
-	struct irq_cfg *cfg;
-	struct irq_desc *desc;
-
-	/* Mark the inuse vectors */
-	for_each_irq_desc(irq, desc) {
-		cfg = desc->chip_data;
-		if (!cpumask_test_cpu(cpu, cfg->domain))
-			continue;
-		vector = cfg->vector;
-		per_cpu(vector_irq, cpu)[vector] = irq;
-	}
-	/* Mark the free vectors */
-	for (vector = 0; vector < NR_VECTORS; ++vector) {
-		irq = per_cpu(vector_irq, cpu)[vector];
-		if (irq < 0)
-			continue;
-
-		cfg = irq_cfg(irq);
-		if (!cpumask_test_cpu(cpu, cfg->domain))
-			per_cpu(vector_irq, cpu)[vector] = -1;
-	}
-}
-
-static struct irq_chip ioapic_chip;
-#ifdef CONFIG_INTR_REMAP
-static struct irq_chip ir_ioapic_chip;
-#endif
-
-#define IOAPIC_AUTO     -1
-#define IOAPIC_EDGE     0
-#define IOAPIC_LEVEL    1
-
-#ifdef CONFIG_X86_32
-static inline int IO_APIC_irq_trigger(int irq)
-{
-	int apic, idx, pin;
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-			idx = find_irq_entry(apic, pin, mp_INT);
-			if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
-				return irq_trigger(idx);
-		}
-	}
-	/*
-         * nonexistent IRQs are edge default
-         */
-	return 0;
-}
-#else
-static inline int IO_APIC_irq_trigger(int irq)
-{
-	return 1;
-}
-#endif
-
-static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger)
-{
-
-	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-	    trigger == IOAPIC_LEVEL)
-		desc->status |= IRQ_LEVEL;
-	else
-		desc->status &= ~IRQ_LEVEL;
-
-#ifdef CONFIG_INTR_REMAP
-	if (irq_remapped(irq)) {
-		desc->status |= IRQ_MOVE_PCNTXT;
-		if (trigger)
-			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
-						      handle_fasteoi_irq,
-						     "fasteoi");
-		else
-			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
-						      handle_edge_irq, "edge");
-		return;
-	}
-#endif
-	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-	    trigger == IOAPIC_LEVEL)
-		set_irq_chip_and_handler_name(irq, &ioapic_chip,
-					      handle_fasteoi_irq,
-					      "fasteoi");
-	else
-		set_irq_chip_and_handler_name(irq, &ioapic_chip,
-					      handle_edge_irq, "edge");
-}
-
-static int setup_ioapic_entry(int apic, int irq,
-			      struct IO_APIC_route_entry *entry,
-			      unsigned int destination, int trigger,
-			      int polarity, int vector)
-{
-	/*
-	 * add it to the IO-APIC irq-routing table:
-	 */
-	memset(entry,0,sizeof(*entry));
-
-#ifdef CONFIG_INTR_REMAP
-	if (intr_remapping_enabled) {
-		struct intel_iommu *iommu = map_ioapic_to_ir(apic);
-		struct irte irte;
-		struct IR_IO_APIC_route_entry *ir_entry =
-			(struct IR_IO_APIC_route_entry *) entry;
-		int index;
-
-		if (!iommu)
-			panic("No mapping iommu for ioapic %d\n", apic);
-
-		index = alloc_irte(iommu, irq, 1);
-		if (index < 0)
-			panic("Failed to allocate IRTE for ioapic %d\n", apic);
-
-		memset(&irte, 0, sizeof(irte));
-
-		irte.present = 1;
-		irte.dst_mode = INT_DEST_MODE;
-		irte.trigger_mode = trigger;
-		irte.dlvry_mode = INT_DELIVERY_MODE;
-		irte.vector = vector;
-		irte.dest_id = IRTE_DEST(destination);
-
-		modify_irte(irq, &irte);
-
-		ir_entry->index2 = (index >> 15) & 0x1;
-		ir_entry->zero = 0;
-		ir_entry->format = 1;
-		ir_entry->index = (index & 0x7fff);
-	} else
-#endif
-	{
-		entry->delivery_mode = INT_DELIVERY_MODE;
-		entry->dest_mode = INT_DEST_MODE;
-		entry->dest = destination;
-	}
-
-	entry->mask = 0;				/* enable IRQ */
-	entry->trigger = trigger;
-	entry->polarity = polarity;
-	entry->vector = vector;
-
-	/* Mask level triggered irqs.
-	 * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
-	 */
-	if (trigger)
-		entry->mask = 1;
-	return 0;
-}
-
-static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, struct irq_desc *desc,
-			      int trigger, int polarity)
-{
-	struct irq_cfg *cfg;
-	struct IO_APIC_route_entry entry;
-	unsigned int dest;
-
-	if (!IO_APIC_IRQ(irq))
-		return;
-
-	cfg = desc->chip_data;
-
-	if (assign_irq_vector(irq, cfg, TARGET_CPUS))
-		return;
-
-	dest = cpu_mask_to_apicid_and(cfg->domain, TARGET_CPUS);
-
-	apic_printk(APIC_VERBOSE,KERN_DEBUG
-		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
-		    "IRQ %d Mode:%i Active:%i)\n",
-		    apic, mp_ioapics[apic].mp_apicid, pin, cfg->vector,
-		    irq, trigger, polarity);
-
-
-	if (setup_ioapic_entry(mp_ioapics[apic].mp_apicid, irq, &entry,
-			       dest, trigger, polarity, cfg->vector)) {
-		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
-		       mp_ioapics[apic].mp_apicid, pin);
-		__clear_irq_vector(irq, cfg);
-		return;
-	}
-
-	ioapic_register_intr(irq, desc, trigger);
-	if (irq < NR_IRQS_LEGACY)
-		disable_8259A_irq(irq);
-
-	ioapic_write_entry(apic, pin, entry);
-}
-
-static void __init setup_IO_APIC_irqs(void)
-{
-	int apic, pin, idx, irq;
-	int notcon = 0;
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
-	int cpu = boot_cpu_id;
-
-	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-
-			idx = find_irq_entry(apic, pin, mp_INT);
-			if (idx == -1) {
-				if (!notcon) {
-					notcon = 1;
-					apic_printk(APIC_VERBOSE,
-						KERN_DEBUG " %d-%d",
-						mp_ioapics[apic].mp_apicid,
-						pin);
-				} else
-					apic_printk(APIC_VERBOSE, " %d-%d",
-						mp_ioapics[apic].mp_apicid,
-						pin);
-				continue;
-			}
-			if (notcon) {
-				apic_printk(APIC_VERBOSE,
-					" (apicid-pin) not connected\n");
-				notcon = 0;
-			}
-
-			irq = pin_2_irq(idx, apic, pin);
-#ifdef CONFIG_X86_32
-			if (multi_timer_check(apic, irq))
-				continue;
-#endif
-			desc = irq_to_desc_alloc_cpu(irq, cpu);
-			if (!desc) {
-				printk(KERN_INFO "can not get irq_desc for %d\n", irq);
-				continue;
-			}
-			cfg = desc->chip_data;
-			add_pin_to_irq_cpu(cfg, cpu, apic, pin);
-
-			setup_IO_APIC_irq(apic, pin, irq, desc,
-					irq_trigger(idx), irq_polarity(idx));
-		}
-	}
-
-	if (notcon)
-		apic_printk(APIC_VERBOSE,
-			" (apicid-pin) not connected\n");
-}
-
-/*
- * Set up the timer pin, possibly with the 8259A-master behind.
- */
-static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin,
-					int vector)
-{
-	struct IO_APIC_route_entry entry;
-
-#ifdef CONFIG_INTR_REMAP
-	if (intr_remapping_enabled)
-		return;
-#endif
-
-	memset(&entry, 0, sizeof(entry));
-
-	/*
-	 * We use logical delivery to get the timer IRQ
-	 * to the first CPU.
-	 */
-	entry.dest_mode = INT_DEST_MODE;
-	entry.mask = 1;					/* mask IRQ now */
-	entry.dest = cpu_mask_to_apicid(TARGET_CPUS);
-	entry.delivery_mode = INT_DELIVERY_MODE;
-	entry.polarity = 0;
-	entry.trigger = 0;
-	entry.vector = vector;
-
-	/*
-	 * The timer IRQ doesn't have to know that behind the
-	 * scene we may have a 8259A-master in AEOI mode ...
-	 */
-	set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
-
-	/*
-	 * Add it to the IO-APIC irq-routing table:
-	 */
-	ioapic_write_entry(apic, pin, entry);
-}
-
-
-__apicdebuginit(void) print_IO_APIC(void)
-{
-	int apic, i;
-	union IO_APIC_reg_00 reg_00;
-	union IO_APIC_reg_01 reg_01;
-	union IO_APIC_reg_02 reg_02;
-	union IO_APIC_reg_03 reg_03;
-	unsigned long flags;
-	struct irq_cfg *cfg;
-	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",
-		       mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
-
-	/*
-	 * We are a bit conservative about what we expect.  We have to
-	 * know about every hardware change ASAP.
-	 */
-	printk(KERN_INFO "testing the IO APIC.......................\n");
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_00.raw = io_apic_read(apic, 0);
-	reg_01.raw = io_apic_read(apic, 1);
-	if (reg_01.bits.version >= 0x10)
-		reg_02.raw = io_apic_read(apic, 2);
-	if (reg_01.bits.version >= 0x20)
-		reg_03.raw = io_apic_read(apic, 3);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	printk("\n");
-	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
-	printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
-	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
-	printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
-	printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
-
-	printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
-	printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
-
-	printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
-	printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
-
-	/*
-	 * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
-	 * but the value of reg_02 is read as the previous read register
-	 * value, so ignore it if reg_02 == reg_01.
-	 */
-	if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
-		printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
-		printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
-	}
-
-	/*
-	 * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
-	 * or reg_03, but the value of reg_0[23] is read as the previous read
-	 * register value, so ignore it if reg_03 == reg_0[12].
-	 */
-	if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
-	    reg_03.raw != reg_01.raw) {
-		printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
-		printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.bits.boot_DT);
-	}
-
-	printk(KERN_DEBUG ".... IRQ redirection table:\n");
-
-	printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
-			  " Stat Dmod Deli Vect:   \n");
-
-	for (i = 0; i <= reg_01.bits.entries; i++) {
-		struct IO_APIC_route_entry entry;
-
-		entry = ioapic_read_entry(apic, i);
-
-		printk(KERN_DEBUG " %02x %03X ",
-			i,
-			entry.dest
-		);
-
-		printk("%1d    %1d    %1d   %1d   %1d    %1d    %1d    %02X\n",
-			entry.mask,
-			entry.trigger,
-			entry.irr,
-			entry.polarity,
-			entry.delivery_status,
-			entry.dest_mode,
-			entry.delivery_mode,
-			entry.vector
-		);
-	}
-	}
-	printk(KERN_DEBUG "IRQ to pin mappings:\n");
-	for_each_irq_desc(irq, desc) {
-		struct irq_pin_list *entry;
-
-		cfg = desc->chip_data;
-		entry = cfg->irq_2_pin;
-		if (!entry)
-			continue;
-		printk(KERN_DEBUG "IRQ%d ", irq);
-		for (;;) {
-			printk("-> %d:%d", entry->apic, entry->pin);
-			if (!entry->next)
-				break;
-			entry = entry->next;
-		}
-		printk("\n");
-	}
-
-	printk(KERN_INFO ".................................... done.\n");
-
-	return;
-}
-
-__apicdebuginit(void) print_APIC_bitfield(int base)
-{
-	unsigned int v;
-	int i, j;
-
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
-	printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
-	for (i = 0; i < 8; i++) {
-		v = apic_read(base + i*0x10);
-		for (j = 0; j < 32; j++) {
-			if (v & (1<<j))
-				printk("1");
-			else
-				printk("0");
-		}
-		printk("\n");
-	}
-}
-
-__apicdebuginit(void) print_local_APIC(void *dummy)
-{
-	unsigned int v, ver, maxlvt;
-	u64 icr;
-
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
-	printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
-		smp_processor_id(), hard_smp_processor_id());
-	v = apic_read(APIC_ID);
-	printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, read_apic_id());
-	v = apic_read(APIC_LVR);
-	printk(KERN_INFO "... APIC VERSION: %08x\n", v);
-	ver = GET_APIC_VERSION(v);
-	maxlvt = lapic_get_maxlvt();
-
-	v = apic_read(APIC_TASKPRI);
-	printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
-
-	if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
-		if (!APIC_XAPIC(ver)) {
-			v = apic_read(APIC_ARBPRI);
-			printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-			       v & APIC_ARBPRI_MASK);
-		}
-		v = apic_read(APIC_PROCPRI);
-		printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
-	}
-
-	/*
-	 * Remote read supported only in the 82489DX and local APIC for
-	 * Pentium processors.
-	 */
-	if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
-		v = apic_read(APIC_RRR);
-		printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
-	}
-
-	v = apic_read(APIC_LDR);
-	printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-	if (!x2apic_enabled()) {
-		v = apic_read(APIC_DFR);
-		printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
-	}
-	v = apic_read(APIC_SPIV);
-	printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
-
-	printk(KERN_DEBUG "... APIC ISR field:\n");
-	print_APIC_bitfield(APIC_ISR);
-	printk(KERN_DEBUG "... APIC TMR field:\n");
-	print_APIC_bitfield(APIC_TMR);
-	printk(KERN_DEBUG "... APIC IRR field:\n");
-	print_APIC_bitfield(APIC_IRR);
-
-	if (APIC_INTEGRATED(ver)) {             /* !82489DX */
-		if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
-			apic_write(APIC_ESR, 0);
-
-		v = apic_read(APIC_ESR);
-		printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
-	}
-
-	icr = apic_icr_read();
-	printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr);
-	printk(KERN_DEBUG "... APIC ICR2: %08x\n", (u32)(icr >> 32));
-
-	v = apic_read(APIC_LVTT);
-	printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
-
-	if (maxlvt > 3) {                       /* PC is LVT#4. */
-		v = apic_read(APIC_LVTPC);
-		printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
-	}
-	v = apic_read(APIC_LVT0);
-	printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
-	v = apic_read(APIC_LVT1);
-	printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
-
-	if (maxlvt > 2) {			/* ERR is LVT#3. */
-		v = apic_read(APIC_LVTERR);
-		printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
-	}
-
-	v = apic_read(APIC_TMICT);
-	printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
-	v = apic_read(APIC_TMCCT);
-	printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
-	v = apic_read(APIC_TDCR);
-	printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
-	printk("\n");
-}
-
-__apicdebuginit(void) print_all_local_APICs(void)
-{
-	int cpu;
-
-	preempt_disable();
-	for_each_online_cpu(cpu)
-		smp_call_function_single(cpu, print_local_APIC, NULL, 1);
-	preempt_enable();
-}
-
-__apicdebuginit(void) print_PIC(void)
-{
-	unsigned int v;
-	unsigned long flags;
-
-	if (apic_verbosity == APIC_QUIET)
-		return;
-
-	printk(KERN_DEBUG "\nprinting PIC contents\n");
-
-	spin_lock_irqsave(&i8259A_lock, flags);
-
-	v = inb(0xa1) << 8 | inb(0x21);
-	printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
-
-	v = inb(0xa0) << 8 | inb(0x20);
-	printk(KERN_DEBUG "... PIC  IRR: %04x\n", v);
-
-	outb(0x0b,0xa0);
-	outb(0x0b,0x20);
-	v = inb(0xa0) << 8 | inb(0x20);
-	outb(0x0a,0xa0);
-	outb(0x0a,0x20);
-
-	spin_unlock_irqrestore(&i8259A_lock, flags);
-
-	printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
-
-	v = inb(0x4d1) << 8 | inb(0x4d0);
-	printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
-}
-
-__apicdebuginit(int) print_all_ICs(void)
-{
-	print_PIC();
-	print_all_local_APICs();
-	print_IO_APIC();
-
-	return 0;
-}
-
-fs_initcall(print_all_ICs);
-
-
-/* Where if anywhere is the i8259 connect in external int mode */
-static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
-
-void __init enable_IO_APIC(void)
-{
-	union IO_APIC_reg_01 reg_01;
-	int i8259_apic, i8259_pin;
-	int apic;
-	unsigned long flags;
-
-#ifdef CONFIG_X86_32
-	int i;
-	if (!pirqs_enabled)
-		for (i = 0; i < MAX_PIRQS; i++)
-			pirq_entries[i] = -1;
-#endif
-
-	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(apic, 1);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-	}
-	for(apic = 0; apic < nr_ioapics; apic++) {
-		int pin;
-		/* See if any of the pins is in ExtINT mode */
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-			struct IO_APIC_route_entry entry;
-			entry = ioapic_read_entry(apic, pin);
-
-			/* If the interrupt line is enabled and in ExtInt mode
-			 * I have found the pin where the i8259 is connected.
-			 */
-			if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
-				ioapic_i8259.apic = apic;
-				ioapic_i8259.pin  = pin;
-				goto found_i8259;
-			}
-		}
-	}
- found_i8259:
-	/* Look to see what if the MP table has reported the ExtINT */
-	/* If we could not find the appropriate pin by looking at the ioapic
-	 * the i8259 probably is not connected the ioapic but give the
-	 * mptable a chance anyway.
-	 */
-	i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
-	i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
-	/* Trust the MP table if nothing is setup in the hardware */
-	if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
-		printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
-		ioapic_i8259.pin  = i8259_pin;
-		ioapic_i8259.apic = i8259_apic;
-	}
-	/* Complain if the MP table and the hardware disagree */
-	if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
-		(i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
-	{
-		printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
-	}
-
-	/*
-	 * Do not trust the IO-APIC being empty at bootup
-	 */
-	clear_IO_APIC();
-}
-
-/*
- * Not an __init, needed by the reboot code
- */
-void disable_IO_APIC(void)
-{
-	/*
-	 * Clear the IO-APIC before rebooting:
-	 */
-	clear_IO_APIC();
-
-	/*
-	 * If the i8259 is routed through an IOAPIC
-	 * Put that IOAPIC in virtual wire mode
-	 * so legacy interrupts can be delivered.
-	 */
-	if (ioapic_i8259.pin != -1) {
-		struct IO_APIC_route_entry entry;
-
-		memset(&entry, 0, sizeof(entry));
-		entry.mask            = 0; /* Enabled */
-		entry.trigger         = 0; /* Edge */
-		entry.irr             = 0;
-		entry.polarity        = 0; /* High */
-		entry.delivery_status = 0;
-		entry.dest_mode       = 0; /* Physical */
-		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
-		entry.vector          = 0;
-		entry.dest            = read_apic_id();
-
-		/*
-		 * Add it to the IO-APIC irq-routing table:
-		 */
-		ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
-	}
-
-	disconnect_bsp_APIC(ioapic_i8259.pin != -1);
-}
-
-#ifdef CONFIG_X86_32
-/*
- * function to set the IO-APIC physical IDs based on the
- * values stored in the MPC table.
- *
- * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
- */
-
-static void __init setup_ioapic_ids_from_mpc(void)
-{
-	union IO_APIC_reg_00 reg_00;
-	physid_mask_t phys_id_present_map;
-	int apic;
-	int i;
-	unsigned char old_id;
-	unsigned long flags;
-
-	if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
-		return;
-
-	/*
-	 * Don't check I/O APIC IDs for xAPIC systems.  They have
-	 * no meaning without the serial APIC bus.
-	 */
-	if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
-		|| APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
-		return;
-	/*
-	 * This is broken; anything with a real cpu count has to
-	 * circumvent this idiocy regardless.
-	 */
-	phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
-
-	/*
-	 * Set the IOAPIC ID to the value stored in the MPC table.
-	 */
-	for (apic = 0; apic < nr_ioapics; apic++) {
-
-		/* Read the register 0 value */
-		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_00.raw = io_apic_read(apic, 0);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-
-		old_id = mp_ioapics[apic].mp_apicid;
-
-		if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
-			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-				apic, mp_ioapics[apic].mp_apicid);
-			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-				reg_00.bits.ID);
-			mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
-		}
-
-		/*
-		 * Sanity check, is the ID really free? 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 (check_apicid_used(phys_id_present_map,
-					mp_ioapics[apic].mp_apicid)) {
-			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
-				apic, mp_ioapics[apic].mp_apicid);
-			for (i = 0; i < get_physical_broadcast(); i++)
-				if (!physid_isset(i, phys_id_present_map))
-					break;
-			if (i >= get_physical_broadcast())
-				panic("Max APIC ID exceeded!\n");
-			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-				i);
-			physid_set(i, phys_id_present_map);
-			mp_ioapics[apic].mp_apicid = i;
-		} else {
-			physid_mask_t tmp;
-			tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
-			apic_printk(APIC_VERBOSE, "Setting %d in the "
-					"phys_id_present_map\n",
-					mp_ioapics[apic].mp_apicid);
-			physids_or(phys_id_present_map, phys_id_present_map, tmp);
-		}
-
-
-		/*
-		 * We need to adjust the IRQ routing table
-		 * if the ID changed.
-		 */
-		if (old_id != mp_ioapics[apic].mp_apicid)
-			for (i = 0; i < mp_irq_entries; i++)
-				if (mp_irqs[i].mp_dstapic == old_id)
-					mp_irqs[i].mp_dstapic
-						= mp_ioapics[apic].mp_apicid;
-
-		/*
-		 * Read the right value from the MPC table and
-		 * write it into the ID register.
-		 */
-		apic_printk(APIC_VERBOSE, KERN_INFO
-			"...changing IO-APIC physical APIC ID to %d ...",
-			mp_ioapics[apic].mp_apicid);
-
-		reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
-		spin_lock_irqsave(&ioapic_lock, flags);
-		io_apic_write(apic, 0, reg_00.raw);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-
-		/*
-		 * Sanity check
-		 */
-		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_00.raw = io_apic_read(apic, 0);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-		if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
-			printk("could not set ID!\n");
-		else
-			apic_printk(APIC_VERBOSE, " ok.\n");
-	}
-}
-#endif
-
-int no_timer_check __initdata;
-
-static int __init notimercheck(char *s)
-{
-	no_timer_check = 1;
-	return 1;
-}
-__setup("no_timer_check", notimercheck);
-
-/*
- * There is a nasty bug in some older SMP boards, their mptable lies
- * about the timer IRQ. We do the following to work around the situation:
- *
- *	- timer IRQ defaults to IO-APIC IRQ
- *	- if this function detects that timer IRQs are defunct, then we fall
- *	  back to ISA timer IRQs
- */
-static int __init timer_irq_works(void)
-{
-	unsigned long t1 = jiffies;
-	unsigned long flags;
-
-	if (no_timer_check)
-		return 1;
-
-	local_save_flags(flags);
-	local_irq_enable();
-	/* Let ten ticks pass... */
-	mdelay((10 * 1000) / HZ);
-	local_irq_restore(flags);
-
-	/*
-	 * Expect a few ticks at least, to be sure some possible
-	 * glue logic does not lock up after one or two first
-	 * ticks in a non-ExtINT mode.  Also the local APIC
-	 * might have cached one ExtINT interrupt.  Finally, at
-	 * least one tick may be lost due to delays.
-	 */
-
-	/* jiffies wrap? */
-	if (time_after(jiffies, t1 + 4))
-		return 1;
-	return 0;
-}
-
-/*
- * In the SMP+IOAPIC case it might happen that there are an unspecified
- * number of pending IRQ events unhandled. These cases are very rare,
- * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
- * better to do it this way as thus we do not have to be aware of
- * 'pending' interrupts in the IRQ path, except at this point.
- */
-/*
- * Edge triggered needs to resend any interrupt
- * that was delayed but this is now handled in the device
- * independent code.
- */
-
-/*
- * Starting up a edge-triggered IO-APIC interrupt is
- * nasty - we need to make sure that we get the edge.
- * If it is already asserted for some reason, we need
- * return 1 to indicate that is was pending.
- *
- * This is not complete - we should be able to fake
- * an edge even if it isn't on the 8259A...
- */
-
-static unsigned int startup_ioapic_irq(unsigned int irq)
-{
-	int was_pending = 0;
-	unsigned long flags;
-	struct irq_cfg *cfg;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	if (irq < NR_IRQS_LEGACY) {
-		disable_8259A_irq(irq);
-		if (i8259A_irq_pending(irq))
-			was_pending = 1;
-	}
-	cfg = irq_cfg(irq);
-	__unmask_IO_APIC_irq(cfg);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	return was_pending;
-}
-
-#ifdef CONFIG_X86_64
-static int ioapic_retrigger_irq(unsigned int irq)
-{
-
-	struct irq_cfg *cfg = irq_cfg(irq);
-	unsigned long flags;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector);
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	return 1;
-}
-#else
-static int ioapic_retrigger_irq(unsigned int irq)
-{
-	send_IPI_self(irq_cfg(irq)->vector);
-
-	return 1;
-}
-#endif
-
-/*
- * Level and edge triggered IO-APIC interrupts need different handling,
- * so we use two separate IRQ descriptors. Edge triggered IRQs can be
- * handled with the level-triggered descriptor, but that one has slightly
- * more overhead. Level-triggered interrupts cannot be handled with the
- * edge-triggered handler, without risking IRQ storms and other ugly
- * races.
- */
-
-#ifdef CONFIG_SMP
-
-#ifdef CONFIG_INTR_REMAP
-static void ir_irq_migration(struct work_struct *work);
-
-static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration);
-
-/*
- * Migrate the IO-APIC irq in the presence of intr-remapping.
- *
- * For edge triggered, irq migration is a simple atomic update(of vector
- * and cpu destination) of IRTE and flush the hardware cache.
- *
- * For level triggered, we need to modify the io-apic RTE aswell with the update
- * vector information, along with modifying IRTE with vector and destination.
- * So irq migration for level triggered is little  bit more complex compared to
- * edge triggered migration. But the good news is, we use the same algorithm
- * for level triggered migration as we have today, only difference being,
- * we now initiate the irq migration from process context instead of the
- * interrupt context.
- *
- * In future, when we do a directed EOI (combined with cpu EOI broadcast
- * suppression) to the IO-APIC, level triggered irq migration will also be
- * as simple as edge triggered migration and we can do the irq migration
- * with a simple atomic update to IO-APIC RTE.
- */
-static void
-migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
-{
-	struct irq_cfg *cfg;
-	struct irte irte;
-	int modify_ioapic_rte;
-	unsigned int dest;
-	unsigned long flags;
-	unsigned int irq;
-
-	if (!cpumask_intersects(mask, cpu_online_mask))
-		return;
-
-	irq = desc->irq;
-	if (get_irte(irq, &irte))
-		return;
-
-	cfg = desc->chip_data;
-	if (assign_irq_vector(irq, cfg, mask))
-		return;
-
-	set_extra_move_desc(desc, mask);
-
-	dest = cpu_mask_to_apicid_and(cfg->domain, mask);
-
-	modify_ioapic_rte = desc->status & IRQ_LEVEL;
-	if (modify_ioapic_rte) {
-		spin_lock_irqsave(&ioapic_lock, flags);
-		__target_IO_APIC_irq(irq, dest, cfg);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-	}
-
-	irte.vector = cfg->vector;
-	irte.dest_id = IRTE_DEST(dest);
-
-	/*
-	 * Modified the IRTE and flushes the Interrupt entry cache.
-	 */
-	modify_irte(irq, &irte);
-
-	if (cfg->move_in_progress)
-		send_cleanup_vector(cfg);
-
-	cpumask_copy(&desc->affinity, mask);
-}
-
-static int migrate_irq_remapped_level_desc(struct irq_desc *desc)
-{
-	int ret = -1;
-	struct irq_cfg *cfg = desc->chip_data;
-
-	mask_IO_APIC_irq_desc(desc);
-
-	if (io_apic_level_ack_pending(cfg)) {
-		/*
-		 * Interrupt in progress. Migrating irq now will change the
-		 * vector information in the IO-APIC RTE and that will confuse
-		 * the EOI broadcast performed by cpu.
-		 * So, delay the irq migration to the next instance.
-		 */
-		schedule_delayed_work(&ir_migration_work, 1);
-		goto unmask;
-	}
-
-	/* everthing is clear. we have right of way */
-	migrate_ioapic_irq_desc(desc, &desc->pending_mask);
-
-	ret = 0;
-	desc->status &= ~IRQ_MOVE_PENDING;
-	cpumask_clear(&desc->pending_mask);
-
-unmask:
-	unmask_IO_APIC_irq_desc(desc);
-
-	return ret;
-}
-
-static void ir_irq_migration(struct work_struct *work)
-{
-	unsigned int irq;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(irq, desc) {
-		if (desc->status & IRQ_MOVE_PENDING) {
-			unsigned long flags;
-
-			spin_lock_irqsave(&desc->lock, flags);
-			if (!desc->chip->set_affinity ||
-			    !(desc->status & IRQ_MOVE_PENDING)) {
-				desc->status &= ~IRQ_MOVE_PENDING;
-				spin_unlock_irqrestore(&desc->lock, flags);
-				continue;
-			}
-
-			desc->chip->set_affinity(irq, &desc->pending_mask);
-			spin_unlock_irqrestore(&desc->lock, flags);
-		}
-	}
-}
-
-/*
- * Migrates the IRQ destination in the process context.
- */
-static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
-					    const struct cpumask *mask)
-{
-	if (desc->status & IRQ_LEVEL) {
-		desc->status |= IRQ_MOVE_PENDING;
-		cpumask_copy(&desc->pending_mask, mask);
-		migrate_irq_remapped_level_desc(desc);
-		return;
-	}
-
-	migrate_ioapic_irq_desc(desc, mask);
-}
-static void set_ir_ioapic_affinity_irq(unsigned int irq,
-				       const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	set_ir_ioapic_affinity_irq_desc(desc, mask);
-}
-#endif
-
-asmlinkage void smp_irq_move_cleanup_interrupt(void)
-{
-	unsigned vector, me;
-
-	ack_APIC_irq();
-	exit_idle();
-	irq_enter();
-
-	me = smp_processor_id();
-	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
-		unsigned int irq;
-		struct irq_desc *desc;
-		struct irq_cfg *cfg;
-		irq = __get_cpu_var(vector_irq)[vector];
-
-		if (irq == -1)
-			continue;
-
-		desc = irq_to_desc(irq);
-		if (!desc)
-			continue;
-
-		cfg = irq_cfg(irq);
-		spin_lock(&desc->lock);
-		if (!cfg->move_cleanup_count)
-			goto unlock;
-
-		if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
-			goto unlock;
-
-		__get_cpu_var(vector_irq)[vector] = -1;
-		cfg->move_cleanup_count--;
-unlock:
-		spin_unlock(&desc->lock);
-	}
-
-	irq_exit();
-}
-
-static void irq_complete_move(struct irq_desc **descp)
-{
-	struct irq_desc *desc = *descp;
-	struct irq_cfg *cfg = desc->chip_data;
-	unsigned vector, me;
-
-	if (likely(!cfg->move_in_progress)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-		if (likely(!cfg->move_desc_pending))
-			return;
-
-		/* domain has not changed, but affinity did */
-		me = smp_processor_id();
-		if (cpu_isset(me, desc->affinity)) {
-			*descp = desc = move_irq_desc(desc, me);
-			/* get the new one */
-			cfg = desc->chip_data;
-			cfg->move_desc_pending = 0;
-		}
-#endif
-		return;
-	}
-
-	vector = ~get_irq_regs()->orig_ax;
-	me = smp_processor_id();
-
-	if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
-#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
-		*descp = desc = move_irq_desc(desc, me);
-		/* get the new one */
-		cfg = desc->chip_data;
-#endif
-		send_cleanup_vector(cfg);
-	}
-}
-#else
-static inline void irq_complete_move(struct irq_desc **descp) {}
-#endif
-
-#ifdef CONFIG_INTR_REMAP
-static void ack_x2apic_level(unsigned int irq)
-{
-	ack_x2APIC_irq();
-}
-
-static void ack_x2apic_edge(unsigned int irq)
-{
-	ack_x2APIC_irq();
-}
-
-#endif
-
-static void ack_apic_edge(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	irq_complete_move(&desc);
-	move_native_irq(irq);
-	ack_APIC_irq();
-}
-
-atomic_t irq_mis_count;
-
-static void ack_apic_level(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-#ifdef CONFIG_X86_32
-	unsigned long v;
-	int i;
-#endif
-	struct irq_cfg *cfg;
-	int do_unmask_irq = 0;
-
-	irq_complete_move(&desc);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
-	/* If we are moving the irq we need to mask it */
-	if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
-		do_unmask_irq = 1;
-		mask_IO_APIC_irq_desc(desc);
-	}
-#endif
-
-#ifdef CONFIG_X86_32
-	/*
-	* It appears there is an erratum which affects at least version 0x11
-	* of I/O APIC (that's the 82093AA and cores integrated into various
-	* chipsets).  Under certain conditions a level-triggered interrupt is
-	* erroneously delivered as edge-triggered one but the respective IRR
-	* bit gets set nevertheless.  As a result the I/O unit expects an EOI
-	* message but it will never arrive and further interrupts are blocked
-	* from the source.  The exact reason is so far unknown, but the
-	* phenomenon was observed when two consecutive interrupt requests
-	* from a given source get delivered to the same CPU and the source is
-	* temporarily disabled in between.
-	*
-	* A workaround is to simulate an EOI message manually.  We achieve it
-	* by setting the trigger mode to edge and then to level when the edge
-	* trigger mode gets detected in the TMR of a local APIC for a
-	* 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
-	*/
-	cfg = desc->chip_data;
-	i = cfg->vector;
-
-	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-#endif
-
-	/*
-	 * We must acknowledge the irq before we move it or the acknowledge will
-	 * not propagate properly.
-	 */
-	ack_APIC_irq();
-
-	/* Now we can move and renable the irq */
-	if (unlikely(do_unmask_irq)) {
-		/* Only migrate the irq if the ack has been received.
-		 *
-		 * On rare occasions the broadcast level triggered ack gets
-		 * delayed going to ioapics, and if we reprogram the
-		 * vector while Remote IRR is still set the irq will never
-		 * fire again.
-		 *
-		 * To prevent this scenario we read the Remote IRR bit
-		 * of the ioapic.  This has two effects.
-		 * - On any sane system the read of the ioapic will
-		 *   flush writes (and acks) going to the ioapic from
-		 *   this cpu.
-		 * - We get to see if the ACK has actually been delivered.
-		 *
-		 * Based on failed experiments of reprogramming the
-		 * ioapic entry from outside of irq context starting
-		 * with masking the ioapic entry and then polling until
-		 * Remote IRR was clear before reprogramming the
-		 * ioapic I don't trust the Remote IRR bit to be
-		 * completey accurate.
-		 *
-		 * However there appears to be no other way to plug
-		 * this race, so if the Remote IRR bit is not
-		 * accurate and is causing problems then it is a hardware bug
-		 * and you can go talk to the chipset vendor about it.
-		 */
-		cfg = desc->chip_data;
-		if (!io_apic_level_ack_pending(cfg))
-			move_masked_irq(irq);
-		unmask_IO_APIC_irq_desc(desc);
-	}
-
-#ifdef CONFIG_X86_32
-	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);
-	}
-#endif
-}
-
-static struct irq_chip ioapic_chip __read_mostly = {
-	.name		= "IO-APIC",
-	.startup	= startup_ioapic_irq,
-	.mask		= mask_IO_APIC_irq,
-	.unmask		= unmask_IO_APIC_irq,
-	.ack		= ack_apic_edge,
-	.eoi		= ack_apic_level,
-#ifdef CONFIG_SMP
-	.set_affinity	= set_ioapic_affinity_irq,
-#endif
-	.retrigger	= ioapic_retrigger_irq,
-};
-
-#ifdef CONFIG_INTR_REMAP
-static struct irq_chip ir_ioapic_chip __read_mostly = {
-	.name		= "IR-IO-APIC",
-	.startup	= startup_ioapic_irq,
-	.mask		= mask_IO_APIC_irq,
-	.unmask		= unmask_IO_APIC_irq,
-	.ack		= ack_x2apic_edge,
-	.eoi		= ack_x2apic_level,
-#ifdef CONFIG_SMP
-	.set_affinity	= set_ir_ioapic_affinity_irq,
-#endif
-	.retrigger	= ioapic_retrigger_irq,
-};
-#endif
-
-static inline void init_IO_APIC_traps(void)
-{
-	int irq;
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
-
-	/*
-	 * NOTE! The local APIC isn't very good at handling
-	 * multiple interrupts at the same interrupt level.
-	 * As the interrupt level is determined by taking the
-	 * vector number and shifting that right by 4, we
-	 * want to spread these out a bit so that they don't
-	 * all fall in the same interrupt level.
-	 *
-	 * Also, we've got to be careful not to trash gate
-	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
-	 */
-	for_each_irq_desc(irq, desc) {
-		cfg = desc->chip_data;
-		if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) {
-			/*
-			 * Hmm.. We don't have an entry for this,
-			 * so default to an old-fashioned 8259
-			 * interrupt if we can..
-			 */
-			if (irq < NR_IRQS_LEGACY)
-				make_8259A_irq(irq);
-			else
-				/* Strange. Oh, well.. */
-				desc->chip = &no_irq_chip;
-		}
-	}
-}
-
-/*
- * The local APIC irq-chip implementation:
- */
-
-static void mask_lapic_irq(unsigned int irq)
-{
-	unsigned long v;
-
-	v = apic_read(APIC_LVT0);
-	apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-}
-
-static void unmask_lapic_irq(unsigned int irq)
-{
-	unsigned long v;
-
-	v = apic_read(APIC_LVT0);
-	apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
-}
-
-static void ack_lapic_irq(unsigned int irq)
-{
-	ack_APIC_irq();
-}
-
-static struct irq_chip lapic_chip __read_mostly = {
-	.name		= "local-APIC",
-	.mask		= mask_lapic_irq,
-	.unmask		= unmask_lapic_irq,
-	.ack		= ack_lapic_irq,
-};
-
-static void lapic_register_intr(int irq, struct irq_desc *desc)
-{
-	desc->status &= ~IRQ_LEVEL;
-	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
-				      "edge");
-}
-
-static void __init setup_nmi(void)
-{
-	/*
-	 * Dirty trick to enable the NMI watchdog ...
-	 * We put the 8259A master into AEOI mode and
-	 * unmask on all local APICs LVT0 as NMI.
-	 *
-	 * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
-	 * is from Maciej W. Rozycki - so we do not have to EOI from
-	 * the NMI handler or the timer interrupt.
-	 */
-	apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-
-	enable_NMI_through_LVT0();
-
-	apic_printk(APIC_VERBOSE, " done.\n");
-}
-
-/*
- * This looks a bit hackish but it's about the only one way of sending
- * a few INTA cycles to 8259As and any associated glue logic.  ICR does
- * not support the ExtINT mode, unfortunately.  We need to send these
- * cycles as some i82489DX-based boards have glue logic that keeps the
- * 8259A interrupt line asserted until INTA.  --macro
- */
-static inline void __init unlock_ExtINT_logic(void)
-{
-	int apic, pin, i;
-	struct IO_APIC_route_entry entry0, entry1;
-	unsigned char save_control, save_freq_select;
-
-	pin  = find_isa_irq_pin(8, mp_INT);
-	if (pin == -1) {
-		WARN_ON_ONCE(1);
-		return;
-	}
-	apic = find_isa_irq_apic(8, mp_INT);
-	if (apic == -1) {
-		WARN_ON_ONCE(1);
-		return;
-	}
-
-	entry0 = ioapic_read_entry(apic, pin);
-	clear_IO_APIC_pin(apic, pin);
-
-	memset(&entry1, 0, sizeof(entry1));
-
-	entry1.dest_mode = 0;			/* physical delivery */
-	entry1.mask = 0;			/* unmask IRQ now */
-	entry1.dest = hard_smp_processor_id();
-	entry1.delivery_mode = dest_ExtINT;
-	entry1.polarity = entry0.polarity;
-	entry1.trigger = 0;
-	entry1.vector = 0;
-
-	ioapic_write_entry(apic, pin, entry1);
-
-	save_control = CMOS_READ(RTC_CONTROL);
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
-	CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
-		   RTC_FREQ_SELECT);
-	CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
-
-	i = 100;
-	while (i-- > 0) {
-		mdelay(10);
-		if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
-			i -= 10;
-	}
-
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-	clear_IO_APIC_pin(apic, pin);
-
-	ioapic_write_entry(apic, pin, entry0);
-}
-
-static int disable_timer_pin_1 __initdata;
-/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
-static int __init disable_timer_pin_setup(char *arg)
-{
-	disable_timer_pin_1 = 1;
-	return 0;
-}
-early_param("disable_timer_pin_1", disable_timer_pin_setup);
-
-int timer_through_8259 __initdata;
-
-/*
- * This code may look a bit paranoid, but it's supposed to cooperate with
- * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
- * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
- * fanatically on his truly buggy board.
- *
- * FIXME: really need to revamp this for all platforms.
- */
-static inline void __init check_timer(void)
-{
-	struct irq_desc *desc = irq_to_desc(0);
-	struct irq_cfg *cfg = desc->chip_data;
-	int cpu = boot_cpu_id;
-	int apic1, pin1, apic2, pin2;
-	unsigned long flags;
-	unsigned int ver;
-	int no_pin1 = 0;
-
-	local_irq_save(flags);
-
-	ver = apic_read(APIC_LVR);
-	ver = GET_APIC_VERSION(ver);
-
-	/*
-	 * get/set the timer IRQ vector:
-	 */
-	disable_8259A_irq(0);
-	assign_irq_vector(0, cfg, TARGET_CPUS);
-
-	/*
-	 * As IRQ0 is to be enabled in the 8259A, the virtual
-	 * wire has to be disabled in the local APIC.  Also
-	 * timer interrupts need to be acknowledged manually in
-	 * the 8259A for the i82489DX when using the NMI
-	 * watchdog as that APIC treats NMIs as level-triggered.
-	 * The AEOI mode will finish them in the 8259A
-	 * automatically.
-	 */
-	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-	init_8259A(1);
-#ifdef CONFIG_X86_32
-	timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
-#endif
-
-	pin1  = find_isa_irq_pin(0, mp_INT);
-	apic1 = find_isa_irq_apic(0, mp_INT);
-	pin2  = ioapic_i8259.pin;
-	apic2 = ioapic_i8259.apic;
-
-	apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
-		    "apic1=%d pin1=%d apic2=%d pin2=%d\n",
-		    cfg->vector, apic1, pin1, apic2, pin2);
-
-	/*
-	 * Some BIOS writers are clueless and report the ExtINTA
-	 * I/O APIC input from the cascaded 8259A as the timer
-	 * interrupt input.  So just in case, if only one pin
-	 * was found above, try it both directly and through the
-	 * 8259A.
-	 */
-	if (pin1 == -1) {
-#ifdef CONFIG_INTR_REMAP
-		if (intr_remapping_enabled)
-			panic("BIOS bug: timer not connected to IO-APIC");
-#endif
-		pin1 = pin2;
-		apic1 = apic2;
-		no_pin1 = 1;
-	} else if (pin2 == -1) {
-		pin2 = pin1;
-		apic2 = apic1;
-	}
-
-	if (pin1 != -1) {
-		/*
-		 * Ok, does IRQ0 through the IOAPIC work?
-		 */
-		if (no_pin1) {
-			add_pin_to_irq_cpu(cfg, cpu, apic1, pin1);
-			setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
-		}
-		unmask_IO_APIC_irq_desc(desc);
-		if (timer_irq_works()) {
-			if (nmi_watchdog == NMI_IO_APIC) {
-				setup_nmi();
-				enable_8259A_irq(0);
-			}
-			if (disable_timer_pin_1 > 0)
-				clear_IO_APIC_pin(0, pin1);
-			goto out;
-		}
-#ifdef CONFIG_INTR_REMAP
-		if (intr_remapping_enabled)
-			panic("timer doesn't work through Interrupt-remapped IO-APIC");
-#endif
-		clear_IO_APIC_pin(apic1, pin1);
-		if (!no_pin1)
-			apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
-				    "8254 timer not connected to IO-APIC\n");
-
-		apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
-			    "(IRQ0) through the 8259A ...\n");
-		apic_printk(APIC_QUIET, KERN_INFO
-			    "..... (found apic %d pin %d) ...\n", apic2, pin2);
-		/*
-		 * legacy devices should be connected to IO APIC #0
-		 */
-		replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2);
-		setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
-		unmask_IO_APIC_irq_desc(desc);
-		enable_8259A_irq(0);
-		if (timer_irq_works()) {
-			apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
-			timer_through_8259 = 1;
-			if (nmi_watchdog == NMI_IO_APIC) {
-				disable_8259A_irq(0);
-				setup_nmi();
-				enable_8259A_irq(0);
-			}
-			goto out;
-		}
-		/*
-		 * Cleanup, just in case ...
-		 */
-		disable_8259A_irq(0);
-		clear_IO_APIC_pin(apic2, pin2);
-		apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
-	}
-
-	if (nmi_watchdog == NMI_IO_APIC) {
-		apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
-			    "through the IO-APIC - disabling NMI Watchdog!\n");
-		nmi_watchdog = NMI_NONE;
-	}
-#ifdef CONFIG_X86_32
-	timer_ack = 0;
-#endif
-
-	apic_printk(APIC_QUIET, KERN_INFO
-		    "...trying to set up timer as Virtual Wire IRQ...\n");
-
-	lapic_register_intr(0, desc);
-	apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);	/* Fixed mode */
-	enable_8259A_irq(0);
-
-	if (timer_irq_works()) {
-		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
-		goto out;
-	}
-	disable_8259A_irq(0);
-	apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
-	apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
-
-	apic_printk(APIC_QUIET, KERN_INFO
-		    "...trying to set up timer as ExtINT IRQ...\n");
-
-	init_8259A(0);
-	make_8259A_irq(0);
-	apic_write(APIC_LVT0, APIC_DM_EXTINT);
-
-	unlock_ExtINT_logic();
-
-	if (timer_irq_works()) {
-		apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
-		goto out;
-	}
-	apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
-	panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
-		"report.  Then try booting with the 'noapic' option.\n");
-out:
-	local_irq_restore(flags);
-}
-
-/*
- * Traditionally ISA IRQ2 is the cascade IRQ, and is not available
- * to devices.  However there may be an I/O APIC pin available for
- * this interrupt regardless.  The pin may be left unconnected, but
- * typically it will be reused as an ExtINT cascade interrupt for
- * the master 8259A.  In the MPS case such a pin will normally be
- * reported as an ExtINT interrupt in the MP table.  With ACPI
- * there is no provision for ExtINT interrupts, and in the absence
- * of an override it would be treated as an ordinary ISA I/O APIC
- * interrupt, that is edge-triggered and unmasked by default.  We
- * used to do this, but it caused problems on some systems because
- * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
- * the same ExtINT cascade interrupt to drive the local APIC of the
- * bootstrap processor.  Therefore we refrain from routing IRQ2 to
- * the I/O APIC in all cases now.  No actual device should request
- * it anyway.  --macro
- */
-#define PIC_IRQS	(1 << PIC_CASCADE_IR)
-
-void __init setup_IO_APIC(void)
-{
-
-#ifdef CONFIG_X86_32
-	enable_IO_APIC();
-#else
-	/*
-	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
-	 */
-#endif
-
-	io_apic_irqs = ~PIC_IRQS;
-
-	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
-	/*
-         * Set up IO-APIC IRQ routing.
-         */
-#ifdef CONFIG_X86_32
-	if (!acpi_ioapic)
-		setup_ioapic_ids_from_mpc();
-#endif
-	sync_Arb_IDs();
-	setup_IO_APIC_irqs();
-	init_IO_APIC_traps();
-	check_timer();
-}
-
-/*
- *      Called after all the initialization is done. If we didnt find any
- *      APIC bugs then we can allow the modify fast path
- */
-
-static int __init io_apic_bug_finalize(void)
-{
-	if (sis_apic_bug == -1)
-		sis_apic_bug = 0;
-	return 0;
-}
-
-late_initcall(io_apic_bug_finalize);
-
-struct sysfs_ioapic_data {
-	struct sys_device dev;
-	struct IO_APIC_route_entry entry[0];
-};
-static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
-
-static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
-{
-	struct IO_APIC_route_entry *entry;
-	struct sysfs_ioapic_data *data;
-	int i;
-
-	data = container_of(dev, struct sysfs_ioapic_data, dev);
-	entry = data->entry;
-	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ )
-		*entry = ioapic_read_entry(dev->id, i);
-
-	return 0;
-}
-
-static int ioapic_resume(struct sys_device *dev)
-{
-	struct IO_APIC_route_entry *entry;
-	struct sysfs_ioapic_data *data;
-	unsigned long flags;
-	union IO_APIC_reg_00 reg_00;
-	int i;
-
-	data = container_of(dev, struct sysfs_ioapic_data, dev);
-	entry = data->entry;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_00.raw = io_apic_read(dev->id, 0);
-	if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
-		reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
-		io_apic_write(dev->id, 0, reg_00.raw);
-	}
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-	for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
-		ioapic_write_entry(dev->id, i, entry[i]);
-
-	return 0;
-}
-
-static struct sysdev_class ioapic_sysdev_class = {
-	.name = "ioapic",
-	.suspend = ioapic_suspend,
-	.resume = ioapic_resume,
-};
-
-static int __init ioapic_init_sysfs(void)
-{
-	struct sys_device * dev;
-	int i, size, error;
-
-	error = sysdev_class_register(&ioapic_sysdev_class);
-	if (error)
-		return error;
-
-	for (i = 0; i < nr_ioapics; i++ ) {
-		size = sizeof(struct sys_device) + nr_ioapic_registers[i]
-			* sizeof(struct IO_APIC_route_entry);
-		mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
-		if (!mp_ioapic_data[i]) {
-			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-			continue;
-		}
-		dev = &mp_ioapic_data[i]->dev;
-		dev->id = i;
-		dev->cls = &ioapic_sysdev_class;
-		error = sysdev_register(dev);
-		if (error) {
-			kfree(mp_ioapic_data[i]);
-			mp_ioapic_data[i] = NULL;
-			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-			continue;
-		}
-	}
-
-	return 0;
-}
-
-device_initcall(ioapic_init_sysfs);
-
-/*
- * Dynamic irq allocate and deallocation
- */
-unsigned int create_irq_nr(unsigned int irq_want)
-{
-	/* Allocate an unused irq */
-	unsigned int irq;
-	unsigned int new;
-	unsigned long flags;
-	struct irq_cfg *cfg_new = NULL;
-	int cpu = boot_cpu_id;
-	struct irq_desc *desc_new = NULL;
-
-	irq = 0;
-	spin_lock_irqsave(&vector_lock, flags);
-	for (new = irq_want; new < NR_IRQS; new++) {
-		if (platform_legacy_irq(new))
-			continue;
-
-		desc_new = irq_to_desc_alloc_cpu(new, cpu);
-		if (!desc_new) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", new);
-			continue;
-		}
-		cfg_new = desc_new->chip_data;
-
-		if (cfg_new->vector != 0)
-			continue;
-		if (__assign_irq_vector(new, cfg_new, TARGET_CPUS) == 0)
-			irq = new;
-		break;
-	}
-	spin_unlock_irqrestore(&vector_lock, flags);
-
-	if (irq > 0) {
-		dynamic_irq_init(irq);
-		/* restore it, in case dynamic_irq_init clear it */
-		if (desc_new)
-			desc_new->chip_data = cfg_new;
-	}
-	return irq;
-}
-
-static int nr_irqs_gsi = NR_IRQS_LEGACY;
-int create_irq(void)
-{
-	unsigned int irq_want;
-	int irq;
-
-	irq_want = nr_irqs_gsi;
-	irq = create_irq_nr(irq_want);
-
-	if (irq == 0)
-		irq = -1;
-
-	return irq;
-}
-
-void destroy_irq(unsigned int irq)
-{
-	unsigned long flags;
-	struct irq_cfg *cfg;
-	struct irq_desc *desc;
-
-	/* store it, in case dynamic_irq_cleanup clear it */
-	desc = irq_to_desc(irq);
-	cfg = desc->chip_data;
-	dynamic_irq_cleanup(irq);
-	/* connect back irq_cfg */
-	if (desc)
-		desc->chip_data = cfg;
-
-#ifdef CONFIG_INTR_REMAP
-	free_irte(irq);
-#endif
-	spin_lock_irqsave(&vector_lock, flags);
-	__clear_irq_vector(irq, cfg);
-	spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-/*
- * MSI message composition
- */
-#ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
-{
-	struct irq_cfg *cfg;
-	int err;
-	unsigned dest;
-
-	cfg = irq_cfg(irq);
-	err = assign_irq_vector(irq, cfg, TARGET_CPUS);
-	if (err)
-		return err;
-
-	dest = cpu_mask_to_apicid_and(cfg->domain, TARGET_CPUS);
-
-#ifdef CONFIG_INTR_REMAP
-	if (irq_remapped(irq)) {
-		struct irte irte;
-		int ir_index;
-		u16 sub_handle;
-
-		ir_index = map_irq_to_irte_handle(irq, &sub_handle);
-		BUG_ON(ir_index == -1);
-
-		memset (&irte, 0, sizeof(irte));
-
-		irte.present = 1;
-		irte.dst_mode = INT_DEST_MODE;
-		irte.trigger_mode = 0; /* edge */
-		irte.dlvry_mode = INT_DELIVERY_MODE;
-		irte.vector = cfg->vector;
-		irte.dest_id = IRTE_DEST(dest);
-
-		modify_irte(irq, &irte);
-
-		msg->address_hi = MSI_ADDR_BASE_HI;
-		msg->data = sub_handle;
-		msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT |
-				  MSI_ADDR_IR_SHV |
-				  MSI_ADDR_IR_INDEX1(ir_index) |
-				  MSI_ADDR_IR_INDEX2(ir_index);
-	} else
-#endif
-	{
-		msg->address_hi = MSI_ADDR_BASE_HI;
-		msg->address_lo =
-			MSI_ADDR_BASE_LO |
-			((INT_DEST_MODE == 0) ?
-				MSI_ADDR_DEST_MODE_PHYSICAL:
-				MSI_ADDR_DEST_MODE_LOGICAL) |
-			((INT_DELIVERY_MODE != dest_LowestPrio) ?
-				MSI_ADDR_REDIRECTION_CPU:
-				MSI_ADDR_REDIRECTION_LOWPRI) |
-			MSI_ADDR_DEST_ID(dest);
-
-		msg->data =
-			MSI_DATA_TRIGGER_EDGE |
-			MSI_DATA_LEVEL_ASSERT |
-			((INT_DELIVERY_MODE != dest_LowestPrio) ?
-				MSI_DATA_DELIVERY_FIXED:
-				MSI_DATA_DELIVERY_LOWPRI) |
-			MSI_DATA_VECTOR(cfg->vector);
-	}
-	return err;
-}
-
-#ifdef CONFIG_SMP
-static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
-	struct msi_msg msg;
-	unsigned int dest;
-
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
-		return;
-
-	cfg = desc->chip_data;
-
-	read_msi_msg_desc(desc, &msg);
-
-	msg.data &= ~MSI_DATA_VECTOR_MASK;
-	msg.data |= MSI_DATA_VECTOR(cfg->vector);
-	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
-
-	write_msi_msg_desc(desc, &msg);
-}
-#ifdef CONFIG_INTR_REMAP
-/*
- * Migrate the MSI irq to another cpumask. This migration is
- * done in the process context using interrupt-remapping hardware.
- */
-static void
-ir_set_msi_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;
-	struct irte irte;
-
-	if (get_irte(irq, &irte))
-		return;
-
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
-		return;
-
-	irte.vector = cfg->vector;
-	irte.dest_id = IRTE_DEST(dest);
-
-	/*
-	 * atomically update the IRTE with the new destination and vector.
-	 */
-	modify_irte(irq, &irte);
-
-	/*
-	 * After this point, all the interrupts will start arriving
-	 * at the new destination. So, time to cleanup the previous
-	 * vector allocation.
-	 */
-	if (cfg->move_in_progress)
-		send_cleanup_vector(cfg);
-}
-
-#endif
-#endif /* CONFIG_SMP */
-
-/*
- * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI or MSI-X Capability Structure.
- */
-static struct irq_chip msi_chip = {
-	.name		= "PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
-	.ack		= ack_apic_edge,
-#ifdef CONFIG_SMP
-	.set_affinity	= set_msi_irq_affinity,
-#endif
-	.retrigger	= ioapic_retrigger_irq,
-};
-
-#ifdef CONFIG_INTR_REMAP
-static struct irq_chip msi_ir_chip = {
-	.name		= "IR-PCI-MSI",
-	.unmask		= unmask_msi_irq,
-	.mask		= mask_msi_irq,
-	.ack		= ack_x2apic_edge,
-#ifdef CONFIG_SMP
-	.set_affinity	= ir_set_msi_irq_affinity,
-#endif
-	.retrigger	= ioapic_retrigger_irq,
-};
-
-/*
- * Map the PCI dev to the corresponding remapping hardware unit
- * and allocate 'nvec' consecutive interrupt-remapping table entries
- * in it.
- */
-static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
-{
-	struct intel_iommu *iommu;
-	int index;
-
-	iommu = map_dev_to_ir(dev);
-	if (!iommu) {
-		printk(KERN_ERR
-		       "Unable to map PCI %s to iommu\n", pci_name(dev));
-		return -ENOENT;
-	}
-
-	index = alloc_irte(iommu, irq, nvec);
-	if (index < 0) {
-		printk(KERN_ERR
-		       "Unable to allocate %d IRTE for PCI %s\n", nvec,
-		       pci_name(dev));
-		return -ENOSPC;
-	}
-	return index;
-}
-#endif
-
-static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
-{
-	int ret;
-	struct msi_msg msg;
-
-	ret = msi_compose_msg(dev, irq, &msg);
-	if (ret < 0)
-		return ret;
-
-	set_irq_msi(irq, msidesc);
-	write_msi_msg(irq, &msg);
-
-#ifdef CONFIG_INTR_REMAP
-	if (irq_remapped(irq)) {
-		struct irq_desc *desc = irq_to_desc(irq);
-		/*
-		 * irq migration in process context
-		 */
-		desc->status |= IRQ_MOVE_PCNTXT;
-		set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
-	} else
-#endif
-		set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
-
-	dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq);
-
-	return 0;
-}
-
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc)
-{
-	unsigned int irq;
-	int ret;
-	unsigned int irq_want;
-
-	irq_want = nr_irqs_gsi;
-	irq = create_irq_nr(irq_want);
-	if (irq == 0)
-		return -1;
-
-#ifdef CONFIG_INTR_REMAP
-	if (!intr_remapping_enabled)
-		goto no_ir;
-
-	ret = msi_alloc_irte(dev, irq, 1);
-	if (ret < 0)
-		goto error;
-no_ir:
-#endif
-	ret = setup_msi_irq(dev, msidesc, irq);
-	if (ret < 0) {
-		destroy_irq(irq);
-		return ret;
-	}
-	return 0;
-
-#ifdef CONFIG_INTR_REMAP
-error:
-	destroy_irq(irq);
-	return ret;
-#endif
-}
-
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
-	unsigned int irq;
-	int ret, sub_handle;
-	struct msi_desc *msidesc;
-	unsigned int irq_want;
-
-#ifdef CONFIG_INTR_REMAP
-	struct intel_iommu *iommu = 0;
-	int index = 0;
-#endif
-
-	irq_want = nr_irqs_gsi;
-	sub_handle = 0;
-	list_for_each_entry(msidesc, &dev->msi_list, list) {
-		irq = create_irq_nr(irq_want);
-		irq_want++;
-		if (irq == 0)
-			return -1;
-#ifdef CONFIG_INTR_REMAP
-		if (!intr_remapping_enabled)
-			goto no_ir;
-
-		if (!sub_handle) {
-			/*
-			 * allocate the consecutive block of IRTE's
-			 * for 'nvec'
-			 */
-			index = msi_alloc_irte(dev, irq, nvec);
-			if (index < 0) {
-				ret = index;
-				goto error;
-			}
-		} else {
-			iommu = map_dev_to_ir(dev);
-			if (!iommu) {
-				ret = -ENOENT;
-				goto error;
-			}
-			/*
-			 * setup the mapping between the irq and the IRTE
-			 * base index, the sub_handle pointing to the
-			 * appropriate interrupt remap table entry.
-			 */
-			set_irte_irq(irq, iommu, index, sub_handle);
-		}
-no_ir:
-#endif
-		ret = setup_msi_irq(dev, msidesc, irq);
-		if (ret < 0)
-			goto error;
-		sub_handle++;
-	}
-	return 0;
-
-error:
-	destroy_irq(irq);
-	return ret;
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-	destroy_irq(irq);
-}
-
-#ifdef CONFIG_DMAR
-#ifdef CONFIG_SMP
-static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
-	struct msi_msg msg;
-	unsigned int dest;
-
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
-		return;
-
-	cfg = desc->chip_data;
-
-	dmar_msi_read(irq, &msg);
-
-	msg.data &= ~MSI_DATA_VECTOR_MASK;
-	msg.data |= MSI_DATA_VECTOR(cfg->vector);
-	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
-
-	dmar_msi_write(irq, &msg);
-}
-
-#endif /* CONFIG_SMP */
-
-struct irq_chip dmar_msi_type = {
-	.name = "DMAR_MSI",
-	.unmask = dmar_msi_unmask,
-	.mask = dmar_msi_mask,
-	.ack = ack_apic_edge,
-#ifdef CONFIG_SMP
-	.set_affinity = dmar_msi_set_affinity,
-#endif
-	.retrigger = ioapic_retrigger_irq,
-};
-
-int arch_setup_dmar_msi(unsigned int irq)
-{
-	int ret;
-	struct msi_msg msg;
-
-	ret = msi_compose_msg(NULL, irq, &msg);
-	if (ret < 0)
-		return ret;
-	dmar_msi_write(irq, &msg);
-	set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
-		"edge");
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_HPET_TIMER
-
-#ifdef CONFIG_SMP
-static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
-	struct msi_msg msg;
-	unsigned int dest;
-
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
-		return;
-
-	cfg = desc->chip_data;
-
-	hpet_msi_read(irq, &msg);
-
-	msg.data &= ~MSI_DATA_VECTOR_MASK;
-	msg.data |= MSI_DATA_VECTOR(cfg->vector);
-	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
-	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
-
-	hpet_msi_write(irq, &msg);
-}
-
-#endif /* CONFIG_SMP */
-
-struct irq_chip hpet_msi_type = {
-	.name = "HPET_MSI",
-	.unmask = hpet_msi_unmask,
-	.mask = hpet_msi_mask,
-	.ack = ack_apic_edge,
-#ifdef CONFIG_SMP
-	.set_affinity = hpet_msi_set_affinity,
-#endif
-	.retrigger = ioapic_retrigger_irq,
-};
-
-int arch_setup_hpet_msi(unsigned int irq)
-{
-	int ret;
-	struct msi_msg msg;
-
-	ret = msi_compose_msg(NULL, irq, &msg);
-	if (ret < 0)
-		return ret;
-
-	hpet_msi_write(irq, &msg);
-	set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
-		"edge");
-
-	return 0;
-}
-#endif
-
-#endif /* CONFIG_PCI_MSI */
-/*
- * Hypertransport interrupt support
- */
-#ifdef CONFIG_HT_IRQ
-
-#ifdef CONFIG_SMP
-
-static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
-{
-	struct ht_irq_msg msg;
-	fetch_ht_irq_msg(irq, &msg);
-
-	msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK);
-	msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
-
-	msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest);
-	msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
-
-	write_ht_irq_msg(irq, &msg);
-}
-
-static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-	struct irq_cfg *cfg;
-	unsigned int dest;
-
-	dest = set_desc_affinity(desc, mask);
-	if (dest == BAD_APICID)
-		return;
-
-	cfg = desc->chip_data;
-
-	target_ht_irq(irq, dest, cfg->vector);
-}
-
-#endif
-
-static struct irq_chip ht_irq_chip = {
-	.name		= "PCI-HT",
-	.mask		= mask_ht_irq,
-	.unmask		= unmask_ht_irq,
-	.ack		= ack_apic_edge,
-#ifdef CONFIG_SMP
-	.set_affinity	= set_ht_irq_affinity,
-#endif
-	.retrigger	= ioapic_retrigger_irq,
-};
-
-int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
-{
-	struct irq_cfg *cfg;
-	int err;
-
-	cfg = irq_cfg(irq);
-	err = assign_irq_vector(irq, cfg, TARGET_CPUS);
-	if (!err) {
-		struct ht_irq_msg msg;
-		unsigned dest;
-
-		dest = cpu_mask_to_apicid_and(cfg->domain, TARGET_CPUS);
-
-		msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
-
-		msg.address_lo =
-			HT_IRQ_LOW_BASE |
-			HT_IRQ_LOW_DEST_ID(dest) |
-			HT_IRQ_LOW_VECTOR(cfg->vector) |
-			((INT_DEST_MODE == 0) ?
-				HT_IRQ_LOW_DM_PHYSICAL :
-				HT_IRQ_LOW_DM_LOGICAL) |
-			HT_IRQ_LOW_RQEOI_EDGE |
-			((INT_DELIVERY_MODE != dest_LowestPrio) ?
-				HT_IRQ_LOW_MT_FIXED :
-				HT_IRQ_LOW_MT_ARBITRATED) |
-			HT_IRQ_LOW_IRQ_MASKED;
-
-		write_ht_irq_msg(irq, &msg);
-
-		set_irq_chip_and_handler_name(irq, &ht_irq_chip,
-					      handle_edge_irq, "edge");
-
-		dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);
-	}
-	return err;
-}
-#endif /* CONFIG_HT_IRQ */
-
-#ifdef CONFIG_X86_64
-/*
- * 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;
-
-	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;
-	BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-	entry->vector = cfg->vector;
-	entry->delivery_mode = INT_DELIVERY_MODE;
-	entry->dest_mode = INT_DEST_MODE;
-	entry->polarity = 0;
-	entry->trigger = 0;
-	entry->mask = 0;
-	entry->dest = cpu_mask_to_apicid(eligible_cpu);
-
-	mmr_pnode = uv_blade_to_pnode(mmr_blade);
-	uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
-
-	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;
-
-	mmr_value = 0;
-	entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
-	BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
-
-	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;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_01.raw = io_apic_read(ioapic, 1);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	return reg_01.bits.entries;
-}
-
-void __init probe_nr_irqs_gsi(void)
-{
-	int nr = 0;
-
-	nr = acpi_probe_gsi();
-	if (nr > nr_irqs_gsi) {
-		nr_irqs_gsi = nr;
-	} else {
-		/* for acpi=off or acpi is not compiled in */
-		int idx;
-
-		nr = 0;
-		for (idx = 0; idx < nr_ioapics; idx++)
-			nr += io_apic_get_redir_entries(idx) + 1;
-
-		if (nr > nr_irqs_gsi)
-			nr_irqs_gsi = nr;
-	}
-
-	printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
-}
-
-/* --------------------------------------------------------------------------
-                          ACPI-based IOAPIC Configuration
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI
-
-#ifdef CONFIG_X86_32
-int __init io_apic_get_unique_id(int ioapic, int apic_id)
-{
-	union IO_APIC_reg_00 reg_00;
-	static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
-	physid_mask_t tmp;
-	unsigned long flags;
-	int i = 0;
-
-	/*
-	 * The P4 platform supports up to 256 APIC IDs on two separate APIC
-	 * buses (one for LAPICs, one for IOAPICs), where predecessors only
-	 * supports up to 16 on one shared APIC bus.
-	 *
-	 * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
-	 *      advantage of new APIC bus architecture.
-	 */
-
-	if (physids_empty(apic_id_map))
-		apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_00.raw = io_apic_read(ioapic, 0);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	if (apic_id >= get_physical_broadcast()) {
-		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
-			"%d\n", ioapic, apic_id, reg_00.bits.ID);
-		apic_id = reg_00.bits.ID;
-	}
-
-	/*
-	 * 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 (check_apicid_used(apic_id_map, apic_id)) {
-
-		for (i = 0; i < get_physical_broadcast(); i++) {
-			if (!check_apicid_used(apic_id_map, i))
-				break;
-		}
-
-		if (i == get_physical_broadcast())
-			panic("Max apic_id exceeded!\n");
-
-		printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
-			"trying %d\n", ioapic, apic_id, i);
-
-		apic_id = i;
-	}
-
-	tmp = apicid_to_cpu_present(apic_id);
-	physids_or(apic_id_map, apic_id_map, tmp);
-
-	if (reg_00.bits.ID != apic_id) {
-		reg_00.bits.ID = apic_id;
-
-		spin_lock_irqsave(&ioapic_lock, flags);
-		io_apic_write(ioapic, 0, reg_00.raw);
-		reg_00.raw = io_apic_read(ioapic, 0);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-
-		/* Sanity check */
-		if (reg_00.bits.ID != apic_id) {
-			printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
-			return -1;
-		}
-	}
-
-	apic_printk(APIC_VERBOSE, KERN_INFO
-			"IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
-
-	return apic_id;
-}
-
-int __init io_apic_get_version(int ioapic)
-{
-	union IO_APIC_reg_01	reg_01;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_01.raw = io_apic_read(ioapic, 1);
-	spin_unlock_irqrestore(&ioapic_lock, flags);
-
-	return reg_01.bits.version;
-}
-#endif
-
-int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
-{
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
-	int cpu = boot_cpu_id;
-
-	if (!IO_APIC_IRQ(irq)) {
-		apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-			ioapic);
-		return -EINVAL;
-	}
-
-	desc = irq_to_desc_alloc_cpu(irq, cpu);
-	if (!desc) {
-		printk(KERN_INFO "can not get irq_desc %d\n", irq);
-		return 0;
-	}
-
-	/*
-	 * IRQs < 16 are already in the irq_2_pin[] map
-	 */
-	if (irq >= NR_IRQS_LEGACY) {
-		cfg = desc->chip_data;
-		add_pin_to_irq_cpu(cfg, cpu, ioapic, pin);
-	}
-
-	setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity);
-
-	return 0;
-}
-
-
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
-{
-	int i;
-
-	if (skip_ioapic_setup)
-		return -1;
-
-	for (i = 0; i < mp_irq_entries; i++)
-		if (mp_irqs[i].mp_irqtype == mp_INT &&
-		    mp_irqs[i].mp_srcbusirq == bus_irq)
-			break;
-	if (i >= mp_irq_entries)
-		return -1;
-
-	*trigger = irq_trigger(i);
-	*polarity = irq_polarity(i);
-	return 0;
-}
-
-#endif /* CONFIG_ACPI */
-
-/*
- * This function currently is only a helper for the i386 smp boot process where
- * we need to reprogram the ioredtbls to cater for the cpus which have come online
- * so mask in all cases should simply be TARGET_CPUS
- */
-#ifdef CONFIG_SMP
-void __init setup_ioapic_dest(void)
-{
-	int pin, ioapic, irq, irq_entry;
-	struct irq_desc *desc;
-	struct irq_cfg *cfg;
-	const struct cpumask *mask;
-
-	if (skip_ioapic_setup == 1)
-		return;
-
-	for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-		for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-			irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-			if (irq_entry == -1)
-				continue;
-			irq = pin_2_irq(irq_entry, ioapic, pin);
-
-			/* setup_IO_APIC_irqs could fail to get vector for some device
-			 * when you have too many devices, because at that time only boot
-			 * cpu is online.
-			 */
-			desc = irq_to_desc(irq);
-			cfg = desc->chip_data;
-			if (!cfg->vector) {
-				setup_IO_APIC_irq(ioapic, pin, irq, desc,
-						  irq_trigger(irq_entry),
-						  irq_polarity(irq_entry));
-				continue;
-
-			}
-
-			/*
-			 * Honour affinities which have been set in early boot
-			 */
-			if (desc->status &
-			    (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
-				mask = &desc->affinity;
-			else
-				mask = TARGET_CPUS;
-
-#ifdef CONFIG_INTR_REMAP
-			if (intr_remapping_enabled)
-				set_ir_ioapic_affinity_irq_desc(desc, mask);
-			else
-#endif
-				set_ioapic_affinity_irq_desc(desc, mask);
-		}
-
-	}
-}
-#endif
-
-#define IOAPIC_RESOURCE_NAME_SIZE 11
-
-static struct resource *ioapic_resources;
-
-static struct resource * __init ioapic_setup_resources(void)
-{
-	unsigned long n;
-	struct resource *res;
-	char *mem;
-	int i;
-
-	if (nr_ioapics <= 0)
-		return NULL;
-
-	n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
-	n *= nr_ioapics;
-
-	mem = alloc_bootmem(n);
-	res = (void *)mem;
-
-	if (mem != NULL) {
-		mem += sizeof(struct resource) * nr_ioapics;
-
-		for (i = 0; i < nr_ioapics; i++) {
-			res[i].name = mem;
-			res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-			sprintf(mem,  "IOAPIC %u", i);
-			mem += IOAPIC_RESOURCE_NAME_SIZE;
-		}
-	}
-
-	ioapic_resources = res;
-
-	return res;
-}
-
-void __init ioapic_init_mappings(void)
-{
-	unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
-	struct resource *ioapic_res;
-	int i;
-
-	ioapic_res = ioapic_setup_resources();
-	for (i = 0; i < nr_ioapics; i++) {
-		if (smp_found_config) {
-			ioapic_phys = mp_ioapics[i].mp_apicaddr;
-#ifdef CONFIG_X86_32
-			if (!ioapic_phys) {
-				printk(KERN_ERR
-				       "WARNING: bogus zero IO-APIC "
-				       "address found in MPTABLE, "
-				       "disabling IO/APIC support!\n");
-				smp_found_config = 0;
-				skip_ioapic_setup = 1;
-				goto fake_ioapic_page;
-			}
-#endif
-		} else {
-#ifdef CONFIG_X86_32
-fake_ioapic_page:
-#endif
-			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);
-		idx++;
-
-		if (ioapic_res != NULL) {
-			ioapic_res->start = ioapic_phys;
-			ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
-			ioapic_res++;
-		}
-	}
-}
-
-static int __init ioapic_insert_resources(void)
-{
-	int i;
-	struct resource *r = ioapic_resources;
-
-	if (!r) {
-		printk(KERN_ERR
-		       "IO APIC resources could be not be allocated.\n");
-		return -1;
-	}
-
-	for (i = 0; i < nr_ioapics; i++) {
-		insert_resource(&iomem_resource, r);
-		r++;
-	}
-
-	return 0;
-}
-
-/* Insert the IO APIC resources after PCI initialization has occured to handle
- * IO APICS that are mapped in on a BAR in PCI space. */
-late_initcall(ioapic_insert_resources);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/io_delay.c linux-libre-2.6.30-gnu1/arch/x86/kernel/io_delay.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/io_delay.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/io_delay.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,10 +7,10 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
 
@@ -47,8 +47,7 @@ EXPORT_SYMBOL(native_io_delay);
 static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id)
 {
 	if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) {
-		printk(KERN_NOTICE "%s: using 0xed I/O delay port\n",
-			id->ident);
+		pr_notice("%s: using 0xed I/O delay port\n", id->ident);
 		io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
 	}
 
@@ -64,40 +63,40 @@ static struct dmi_system_id __initdata i
 		.callback	= dmi_io_delay_0xed_port,
 		.ident		= "Compaq Presario V6000",
 		.matches	= {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
-			DMI_MATCH(DMI_BOARD_NAME, "30B7")
+			DMI_MATCH(DMI_BOARD_VENDOR,	"Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME,	"30B7")
 		}
 	},
 	{
 		.callback	= dmi_io_delay_0xed_port,
 		.ident		= "HP Pavilion dv9000z",
 		.matches	= {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
-			DMI_MATCH(DMI_BOARD_NAME, "30B9")
+			DMI_MATCH(DMI_BOARD_VENDOR,	"Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME,	"30B9")
 		}
 	},
 	{
 		.callback	= dmi_io_delay_0xed_port,
 		.ident		= "HP Pavilion dv6000",
 		.matches	= {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
-			DMI_MATCH(DMI_BOARD_NAME, "30B8")
+			DMI_MATCH(DMI_BOARD_VENDOR,	"Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME,	"30B8")
 		}
 	},
 	{
 		.callback	= dmi_io_delay_0xed_port,
 		.ident		= "HP Pavilion tx1000",
 		.matches	= {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
-			DMI_MATCH(DMI_BOARD_NAME, "30BF")
+			DMI_MATCH(DMI_BOARD_VENDOR,	"Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME,	"30BF")
 		}
 	},
 	{
 		.callback	= dmi_io_delay_0xed_port,
 		.ident		= "Presario F700",
 		.matches	= {
-			DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
-			DMI_MATCH(DMI_BOARD_NAME, "30D3")
+			DMI_MATCH(DMI_BOARD_VENDOR,	"Quanta"),
+			DMI_MATCH(DMI_BOARD_NAME,	"30D3")
 		}
 	},
 	{ }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/ioport.c linux-libre-2.6.30-gnu1/arch/x86/kernel/ioport.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/ioport.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/ioport.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,19 +85,8 @@ asmlinkage long sys_ioperm(unsigned long
 
 	t->io_bitmap_max = bytes;
 
-#ifdef CONFIG_X86_32
-	/*
-	 * Sets the lazy trigger so that the next I/O operation will
-	 * reload the correct bitmap.
-	 * Reset the owner so that a process switch will not set
-	 * tss->io_bitmap_base to IO_BITMAP_OFFSET.
-	 */
-	tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
-	tss->io_bitmap_owner = NULL;
-#else
 	/* Update the TSS: */
 	memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
-#endif
 
 	put_cpu();
 
@@ -131,9 +120,8 @@ static int do_iopl(unsigned int level, s
 }
 
 #ifdef CONFIG_X86_32
-asmlinkage long sys_iopl(unsigned long regsp)
+long sys_iopl(struct pt_regs *regs)
 {
-	struct pt_regs *regs = (struct pt_regs *)&regsp;
 	unsigned int level = regs->bx;
 	struct thread_struct *t = &current->thread;
 	int rc;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/ipi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/ipi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/ipi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/ipi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,190 +0,0 @@
-#include <linux/cpumask.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/kernel_stat.h>
-#include <linux/mc146818rtc.h>
-#include <linux/cache.h>
-#include <linux/cpu.h>
-#include <linux/module.h>
-
-#include <asm/smp.h>
-#include <asm/mtrr.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-#include <asm/apic.h>
-#include <asm/proto.h>
-
-#ifdef CONFIG_X86_32
-#include <mach_apic.h>
-#include <mach_ipi.h>
-
-/*
- * the following functions deal with sending IPIs between CPUs.
- *
- * We use 'broadcast', CPU->CPU IPIs and self-IPIs too.
- */
-
-static inline int __prepare_ICR(unsigned int shortcut, int vector)
-{
-	unsigned int icr = shortcut | APIC_DEST_LOGICAL;
-
-	switch (vector) {
-	default:
-		icr |= APIC_DM_FIXED | vector;
-		break;
-	case NMI_VECTOR:
-		icr |= APIC_DM_NMI;
-		break;
-	}
-	return icr;
-}
-
-static inline int __prepare_ICR2(unsigned int mask)
-{
-	return SET_APIC_DEST_FIELD(mask);
-}
-
-void __send_IPI_shortcut(unsigned int shortcut, int vector)
-{
-	/*
-	 * Subtle. In the case of the 'never do double writes' workaround
-	 * we have to lock out interrupts to be safe.  As we don't care
-	 * of the value read we use an atomic rmw access to avoid costly
-	 * cli/sti.  Otherwise we use an even cheaper single atomic write
-	 * to the APIC.
-	 */
-	unsigned int cfg;
-
-	/*
-	 * Wait for idle.
-	 */
-	apic_wait_icr_idle();
-
-	/*
-	 * No need to touch the target chip field
-	 */
-	cfg = __prepare_ICR(shortcut, vector);
-
-	/*
-	 * Send the IPI. The write to APIC_ICR fires this off.
-	 */
-	apic_write(APIC_ICR, cfg);
-}
-
-void send_IPI_self(int vector)
-{
-	__send_IPI_shortcut(APIC_DEST_SELF, vector);
-}
-
-/*
- * This is used to send an IPI with no shorthand notation (the destination is
- * specified in bits 56 to 63 of the ICR).
- */
-static inline void __send_IPI_dest_field(unsigned long mask, int vector)
-{
-	unsigned long cfg;
-
-	/*
-	 * Wait for idle.
-	 */
-	if (unlikely(vector == NMI_VECTOR))
-		safe_apic_wait_icr_idle();
-	else
-		apic_wait_icr_idle();
-
-	/*
-	 * prepare target chip field
-	 */
-	cfg = __prepare_ICR2(mask);
-	apic_write(APIC_ICR2, cfg);
-
-	/*
-	 * program the ICR
-	 */
-	cfg = __prepare_ICR(0, vector);
-
-	/*
-	 * Send the IPI. The write to APIC_ICR fires this off.
-	 */
-	apic_write(APIC_ICR, cfg);
-}
-
-/*
- * This is only used on smaller machines.
- */
-void send_IPI_mask_bitmask(const struct cpumask *cpumask, int vector)
-{
-	unsigned long mask = cpumask_bits(cpumask)[0];
-	unsigned long flags;
-
-	local_irq_save(flags);
-	WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]);
-	__send_IPI_dest_field(mask, vector);
-	local_irq_restore(flags);
-}
-
-void send_IPI_mask_sequence(const struct cpumask *mask, int vector)
-{
-	unsigned long flags;
-	unsigned int query_cpu;
-
-	/*
-	 * Hack. The clustered APIC addressing mode doesn't allow us to send
-	 * to an arbitrary mask, so I do a unicasts to each CPU instead. This
-	 * should be modified to do 1 message per cluster ID - mbligh
-	 */
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask)
-		__send_IPI_dest_field(cpu_to_logical_apicid(query_cpu), vector);
-	local_irq_restore(flags);
-}
-
-void send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
-{
-	unsigned long flags;
-	unsigned int query_cpu;
-	unsigned int this_cpu = smp_processor_id();
-
-	/* See Hack comment above */
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask)
-		if (query_cpu != this_cpu)
-			__send_IPI_dest_field(cpu_to_logical_apicid(query_cpu),
-					      vector);
-	local_irq_restore(flags);
-}
-
-/* must come after the send_IPI functions above for inlining */
-static int convert_apicid_to_cpu(int apic_id)
-{
-	int i;
-
-	for_each_possible_cpu(i) {
-		if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
-			return i;
-	}
-	return -1;
-}
-
-int safe_smp_processor_id(void)
-{
-	int apicid, cpuid;
-
-	if (!boot_cpu_has(X86_FEATURE_APIC))
-		return 0;
-
-	apicid = hard_smp_processor_id();
-	if (apicid == BAD_APICID)
-		return 0;
-
-	cpuid = convert_apicid_to_cpu(apicid);
-
-	return cpuid >= 0 ? cpuid : 0;
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/irq_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/irq_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/irq_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/irq_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
+#include <linux/percpu.h>
 
 #include <asm/apic.h>
 
@@ -55,13 +56,13 @@ static inline void print_stack_overflow(
 union irq_ctx {
 	struct thread_info      tinfo;
 	u32                     stack[THREAD_SIZE/sizeof(u32)];
-};
+} __attribute__((aligned(PAGE_SIZE)));
 
-static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
-static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
+static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx);
+static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx);
 
-static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
-static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
+static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, hardirq_stack);
+static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, softirq_stack);
 
 static void call_on_stack(void *func, void *stack)
 {
@@ -81,7 +82,7 @@ execute_on_irq_stack(int overflow, struc
 	u32 *isp, arg1, arg2;
 
 	curctx = (union irq_ctx *) current_thread_info();
-	irqctx = hardirq_ctx[smp_processor_id()];
+	irqctx = __get_cpu_var(hardirq_ctx);
 
 	/*
 	 * this is where we switch to the IRQ stack. However, if we are
@@ -125,34 +126,34 @@ void __cpuinit irq_ctx_init(int cpu)
 {
 	union irq_ctx *irqctx;
 
-	if (hardirq_ctx[cpu])
+	if (per_cpu(hardirq_ctx, cpu))
 		return;
 
-	irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE];
+	irqctx = &per_cpu(hardirq_stack, cpu);
 	irqctx->tinfo.task		= NULL;
 	irqctx->tinfo.exec_domain	= NULL;
 	irqctx->tinfo.cpu		= cpu;
 	irqctx->tinfo.preempt_count	= HARDIRQ_OFFSET;
 	irqctx->tinfo.addr_limit	= MAKE_MM_SEG(0);
 
-	hardirq_ctx[cpu] = irqctx;
+	per_cpu(hardirq_ctx, cpu) = irqctx;
 
-	irqctx = (union irq_ctx *) &softirq_stack[cpu*THREAD_SIZE];
+	irqctx = &per_cpu(softirq_stack, cpu);
 	irqctx->tinfo.task		= NULL;
 	irqctx->tinfo.exec_domain	= NULL;
 	irqctx->tinfo.cpu		= cpu;
 	irqctx->tinfo.preempt_count	= 0;
 	irqctx->tinfo.addr_limit	= MAKE_MM_SEG(0);
 
-	softirq_ctx[cpu] = irqctx;
+	per_cpu(softirq_ctx, cpu) = irqctx;
 
 	printk(KERN_DEBUG "CPU %u irqstacks, hard=%p soft=%p\n",
-	       cpu, hardirq_ctx[cpu], softirq_ctx[cpu]);
+	       cpu, per_cpu(hardirq_ctx, cpu),  per_cpu(softirq_ctx, cpu));
 }
 
 void irq_ctx_exit(int cpu)
 {
-	hardirq_ctx[cpu] = NULL;
+	per_cpu(hardirq_ctx, cpu) = NULL;
 }
 
 asmlinkage void do_softirq(void)
@@ -169,7 +170,7 @@ asmlinkage void do_softirq(void)
 
 	if (local_softirq_pending()) {
 		curctx = current_thread_info();
-		irqctx = softirq_ctx[smp_processor_id()];
+		irqctx = __get_cpu_var(softirq_ctx);
 		irqctx->tinfo.task = curctx->task;
 		irqctx->tinfo.previous_esp = current_stack_pointer;
 
@@ -191,33 +192,16 @@ static inline int
 execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { return 0; }
 #endif
 
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-unsigned int do_IRQ(struct pt_regs *regs)
+bool handle_irq(unsigned irq, struct pt_regs *regs)
 {
-	struct pt_regs *old_regs;
-	/* high bit used in ret_from_ code */
-	int overflow;
-	unsigned vector = ~regs->orig_ax;
 	struct irq_desc *desc;
-	unsigned irq;
-
-
-	old_regs = set_irq_regs(regs);
-	irq_enter();
-	irq = __get_cpu_var(vector_irq)[vector];
+	int overflow;
 
 	overflow = check_stack_overflow();
 
 	desc = irq_to_desc(irq);
-	if (unlikely(!desc)) {
-		printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
-					__func__, irq, vector, smp_processor_id());
-		BUG();
-	}
+	if (unlikely(!desc))
+		return false;
 
 	if (!execute_on_irq_stack(overflow, desc, irq)) {
 		if (unlikely(overflow))
@@ -225,13 +209,10 @@ unsigned int do_IRQ(struct pt_regs *regs
 		desc->handle_irq(irq, desc);
 	}
 
-	irq_exit();
-	set_irq_regs(old_regs);
-	return 1;
+	return true;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-#include <mach_apic.h>
 
 /* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
 void fixup_irqs(void)
@@ -248,7 +229,7 @@ void fixup_irqs(void)
 		if (irq == 2)
 			continue;
 
-		affinity = &desc->affinity;
+		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;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/irq_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/irq_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/irq_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/irq_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,13 @@
 #include <linux/smp.h>
 #include <asm/io_apic.h>
 #include <asm/idle.h>
+#include <asm/apic.h>
+
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
+DEFINE_PER_CPU(struct pt_regs *, irq_regs);
+EXPORT_PER_CPU_SYMBOL(irq_regs);
 
 /*
  * Probabilistic stack overflow check:
@@ -41,42 +48,18 @@ static inline void stack_overflow_check(
 #endif
 }
 
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
+bool handle_irq(unsigned irq, struct pt_regs *regs)
 {
-	struct pt_regs *old_regs = set_irq_regs(regs);
 	struct irq_desc *desc;
 
-	/* high bit used in ret_from_ code  */
-	unsigned vector = ~regs->orig_ax;
-	unsigned irq;
-
-	exit_idle();
-	irq_enter();
-	irq = __get_cpu_var(vector_irq)[vector];
-
 	stack_overflow_check(regs);
 
 	desc = irq_to_desc(irq);
-	if (likely(desc))
-		generic_handle_irq_desc(irq, desc);
-	else {
-		if (!disable_apic)
-			ack_APIC_irq();
-
-		if (printk_ratelimit())
-			printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
-				__func__, smp_processor_id(), vector);
-	}
-
-	irq_exit();
+	if (unlikely(!desc))
+		return false;
 
-	set_irq_regs(old_regs);
-	return 1;
+	generic_handle_irq_desc(irq, desc);
+	return true;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -100,7 +83,7 @@ void fixup_irqs(void)
 		/* interrupt's are disabled at this point */
 		spin_lock(&desc->lock);
 
-		affinity = &desc->affinity;
+		affinity = desc->affinity;
 		if (!irq_has_action(irq) ||
 		    cpumask_equal(affinity, cpu_online_mask)) {
 			spin_unlock(&desc->lock);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/irq.c linux-libre-2.6.30-gnu1/arch/x86/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,13 +6,18 @@
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
 #include <linux/smp.h>
+#include <linux/ftrace.h>
 
 #include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/irq.h>
+#include <asm/idle.h>
 
 atomic_t irq_err_count;
 
+/* Function pointer for generic interrupt vector handling */
+void (*generic_interrupt_extension)(void) = NULL;
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
@@ -36,63 +41,64 @@ void ack_bad_irq(unsigned int irq)
 #endif
 }
 
-#ifdef CONFIG_X86_32
-# define irq_stats(x)		(&per_cpu(irq_stat, x))
-#else
-# define irq_stats(x)		cpu_pda(x)
-#endif
+#define irq_stats(x)		(&per_cpu(irq_stat, x))
 /*
  * /proc/interrupts printing:
  */
-static int show_other_interrupts(struct seq_file *p)
+static int show_other_interrupts(struct seq_file *p, int prec)
 {
 	int j;
 
-	seq_printf(p, "NMI: ");
+	seq_printf(p, "%*s: ", prec, "NMI");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
 	seq_printf(p, "  Non-maskable interrupts\n");
 #ifdef CONFIG_X86_LOCAL_APIC
-	seq_printf(p, "LOC: ");
+	seq_printf(p, "%*s: ", prec, "LOC");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
 	seq_printf(p, "  Local timer interrupts\n");
+
+	seq_printf(p, "%*s: ", prec, "SPU");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
+	seq_printf(p, "  Spurious interrupts\n");
 #endif
+	if (generic_interrupt_extension) {
+		seq_printf(p, "%*s: ", prec, "PLT");
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", irq_stats(j)->generic_irqs);
+		seq_printf(p, "  Platform interrupts\n");
+	}
 #ifdef CONFIG_SMP
-	seq_printf(p, "RES: ");
+	seq_printf(p, "%*s: ", prec, "RES");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
 	seq_printf(p, "  Rescheduling interrupts\n");
-	seq_printf(p, "CAL: ");
+	seq_printf(p, "%*s: ", prec, "CAL");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
 	seq_printf(p, "  Function call interrupts\n");
-	seq_printf(p, "TLB: ");
+	seq_printf(p, "%*s: ", prec, "TLB");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
 	seq_printf(p, "  TLB shootdowns\n");
 #endif
 #ifdef CONFIG_X86_MCE
-	seq_printf(p, "TRM: ");
+	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_64
-	seq_printf(p, "THR: ");
+	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_LOCAL_APIC
-	seq_printf(p, "SPU: ");
-	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
-	seq_printf(p, "  Spurious interrupts\n");
-#endif
-	seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
 #if defined(CONFIG_X86_IO_APIC)
-	seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+	seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
 #endif
 	return 0;
 }
@@ -100,19 +106,22 @@ static int show_other_interrupts(struct
 int show_interrupts(struct seq_file *p, void *v)
 {
 	unsigned long flags, any_count = 0;
-	int i = *(loff_t *) v, j;
+	int i = *(loff_t *) v, j, prec;
 	struct irqaction *action;
 	struct irq_desc *desc;
 
 	if (i > nr_irqs)
 		return 0;
 
+	for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
+		j *= 10;
+
 	if (i == nr_irqs)
-		return show_other_interrupts(p);
+		return show_other_interrupts(p, prec);
 
 	/* print header */
 	if (i == 0) {
-		seq_printf(p, "           ");
+		seq_printf(p, "%*s", prec + 8, "");
 		for_each_online_cpu(j)
 			seq_printf(p, "CPU%-8d", j);
 		seq_putc(p, '\n');
@@ -123,23 +132,15 @@ int show_interrupts(struct seq_file *p,
 		return 0;
 
 	spin_lock_irqsave(&desc->lock, flags);
-#ifndef CONFIG_SMP
-	any_count = kstat_irqs(i);
-#else
 	for_each_online_cpu(j)
 		any_count |= kstat_irqs_cpu(i, j);
-#endif
 	action = desc->action;
 	if (!action && !any_count)
 		goto out;
 
-	seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
-	seq_printf(p, "%10u ", kstat_irqs(i));
-#else
+	seq_printf(p, "%*d: ", prec, i);
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#endif
 	seq_printf(p, " %8s", desc->chip->name);
 	seq_printf(p, "-%-8s", desc->name);
 
@@ -164,7 +165,10 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	sum += irq_stats(cpu)->apic_timer_irqs;
+	sum += irq_stats(cpu)->irq_spurious_count;
 #endif
+	if (generic_interrupt_extension)
+		sum += irq_stats(cpu)->generic_irqs;
 #ifdef CONFIG_SMP
 	sum += irq_stats(cpu)->irq_resched_count;
 	sum += irq_stats(cpu)->irq_call_count;
@@ -176,9 +180,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 	sum += irq_stats(cpu)->irq_threshold_count;
 #endif
 #endif
-#ifdef CONFIG_X86_LOCAL_APIC
-	sum += irq_stats(cpu)->irq_spurious_count;
-#endif
 	return sum;
 }
 
@@ -192,4 +193,63 @@ u64 arch_irq_stat(void)
 	return sum;
 }
 
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	/* high bit used in ret_from_ code  */
+	unsigned vector = ~regs->orig_ax;
+	unsigned irq;
+
+	exit_idle();
+	irq_enter();
+
+	irq = __get_cpu_var(vector_irq)[vector];
+
+	if (!handle_irq(irq, regs)) {
+#ifdef CONFIG_X86_64
+		if (!disable_apic)
+			ack_APIC_irq();
+#endif
+
+		if (printk_ratelimit())
+			printk(KERN_EMERG "%s: %d.%d No irq handler for vector (irq %d)\n",
+			       __func__, smp_processor_id(), vector, irq);
+	}
+
+	irq_exit();
+
+	set_irq_regs(old_regs);
+	return 1;
+}
+
+/*
+ * Handler for GENERIC_INTERRUPT_VECTOR.
+ */
+void smp_generic_interrupt(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	ack_APIC_irq();
+
+	exit_idle();
+
+	irq_enter();
+
+	inc_irq_stat(generic_irqs);
+
+	if (generic_interrupt_extension)
+		generic_interrupt_extension();
+
+	irq_exit();
+
+	set_irq_regs(old_regs);
+}
+
 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/irqinit_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/irqinit_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/irqinit_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/irqinit_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 #include <asm/apic.h>
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
 #include <asm/i8259.h>
 #include <asm/traps.h>
 
@@ -50,7 +50,6 @@ static irqreturn_t math_error_irq(int cp
  */
 static struct irqaction fpu_irq = {
 	.handler = math_error_irq,
-	.mask = CPU_MASK_NONE,
 	.name = "fpu",
 };
 
@@ -78,6 +77,14 @@ void __init init_ISA_irqs(void)
 	}
 }
 
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = {
+	.handler = no_action,
+	.name = "cascade",
+};
+
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
 	[0 ... IRQ0_VECTOR - 1] = -1,
 	[IRQ0_VECTOR] = 0,
@@ -118,8 +125,8 @@ void __init native_init_IRQ(void)
 {
 	int i;
 
-	/* all the set up before the call gates are initialised */
-	pre_intr_init_hook();
+	/* Execute any quirks before the call gates are initialised: */
+	x86_quirk_pre_intr_init();
 
 	/*
 	 * Cover the whole vector space, no vector can escape
@@ -140,8 +147,15 @@ void __init native_init_IRQ(void)
 	 */
 	alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
 
-	/* IPI for invalidation */
-	alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
+	/* IPIs for invalidation */
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6);
+	alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7);
 
 	/* IPI for generic function call */
 	alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
@@ -159,6 +173,9 @@ void __init native_init_IRQ(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 vectors for APIC spurious and error interrupts */
 	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
 	alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
@@ -169,10 +186,14 @@ void __init native_init_IRQ(void)
 	alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 #endif
 
-	/* setup after call gates are initialised (usually add in
-	 * the architecture specific gates)
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
+
+	/*
+	 * Call quirks after call gates are initialised (usually add in
+	 * the architecture specific gates):
 	 */
-	intr_init_hook();
+	x86_quirk_intr_init();
 
 	/*
 	 * External FPU? Set up irq13 if so, for
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/irqinit_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/irqinit_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/irqinit_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/irqinit_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,6 @@
 
 static struct irqaction irq2 = {
 	.handler = no_action,
-	.mask = CPU_MASK_NONE,
 	.name = "cascade",
 };
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
@@ -147,6 +146,9 @@ 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 vectors for APIC spurious and error interrupts */
 	alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
 	alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/kdebugfs.c linux-libre-2.6.30-gnu1/arch/x86/kernel/kdebugfs.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/kdebugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/kdebugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,11 +8,11 @@
  */
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
-#include <linux/stat.h>
+#include <linux/module.h>
 #include <linux/init.h>
+#include <linux/stat.h>
 #include <linux/io.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 
 #include <asm/setup.h>
 
@@ -26,9 +26,8 @@ struct setup_data_node {
 	u32 len;
 };
 
-static ssize_t
-setup_data_read(struct file *file, char __user *user_buf, size_t count,
-		loff_t *ppos)
+static ssize_t setup_data_read(struct file *file, char __user *user_buf,
+			       size_t count, loff_t *ppos)
 {
 	struct setup_data_node *node = file->private_data;
 	unsigned long remain;
@@ -39,20 +38,21 @@ setup_data_read(struct file *file, char
 
 	if (pos < 0)
 		return -EINVAL;
+
 	if (pos >= node->len)
 		return 0;
 
 	if (count > node->len - pos)
 		count = node->len - pos;
+
 	pa = node->paddr + sizeof(struct setup_data) + pos;
 	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
 	if (PageHighMem(pg)) {
 		p = ioremap_cache(pa, count);
 		if (!p)
 			return -ENXIO;
-	} else {
+	} else
 		p = __va(pa);
-	}
 
 	remain = copy_to_user(user_buf, p, count);
 
@@ -70,12 +70,13 @@ setup_data_read(struct file *file, char
 static int setup_data_open(struct inode *inode, struct file *file)
 {
 	file->private_data = inode->i_private;
+
 	return 0;
 }
 
 static const struct file_operations fops_setup_data = {
-	.read =		setup_data_read,
-	.open =		setup_data_open,
+	.read		= setup_data_read,
+	.open		= setup_data_open,
 };
 
 static int __init
@@ -84,57 +85,50 @@ create_setup_data_node(struct dentry *pa
 {
 	struct dentry *d, *type, *data;
 	char buf[16];
-	int error;
 
 	sprintf(buf, "%d", no);
 	d = debugfs_create_dir(buf, parent);
-	if (!d) {
-		error = -ENOMEM;
-		goto err_return;
-	}
+	if (!d)
+		return -ENOMEM;
+
 	type = debugfs_create_x32("type", S_IRUGO, d, &node->type);
-	if (!type) {
-		error = -ENOMEM;
+	if (!type)
 		goto err_dir;
-	}
+
 	data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
-	if (!data) {
-		error = -ENOMEM;
+	if (!data)
 		goto err_type;
-	}
+
 	return 0;
 
 err_type:
 	debugfs_remove(type);
 err_dir:
 	debugfs_remove(d);
-err_return:
-	return error;
+	return -ENOMEM;
 }
 
 static int __init create_setup_data_nodes(struct dentry *parent)
 {
 	struct setup_data_node *node;
 	struct setup_data *data;
-	int error, no = 0;
+	int error = -ENOMEM;
 	struct dentry *d;
 	struct page *pg;
 	u64 pa_data;
+	int no = 0;
 
 	d = debugfs_create_dir("setup_data", parent);
-	if (!d) {
-		error = -ENOMEM;
-		goto err_return;
-	}
+	if (!d)
+		return -ENOMEM;
 
 	pa_data = boot_params.hdr.setup_data;
 
 	while (pa_data) {
 		node = kmalloc(sizeof(*node), GFP_KERNEL);
-		if (!node) {
-			error = -ENOMEM;
+		if (!node)
 			goto err_dir;
-		}
+
 		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
 		if (PageHighMem(pg)) {
 			data = ioremap_cache(pa_data, sizeof(*data));
@@ -143,9 +137,8 @@ static int __init create_setup_data_node
 				error = -ENXIO;
 				goto err_dir;
 			}
-		} else {
+		} else
 			data = __va(pa_data);
-		}
 
 		node->paddr = pa_data;
 		node->type = data->type;
@@ -159,11 +152,11 @@ static int __init create_setup_data_node
 			goto err_dir;
 		no++;
 	}
+
 	return 0;
 
 err_dir:
 	debugfs_remove(d);
-err_return:
 	return error;
 }
 
@@ -175,28 +168,26 @@ static struct debugfs_blob_wrapper boot_
 static int __init boot_params_kdebugfs_init(void)
 {
 	struct dentry *dbp, *version, *data;
-	int error;
+	int error = -ENOMEM;
 
 	dbp = debugfs_create_dir("boot_params", NULL);
-	if (!dbp) {
-		error = -ENOMEM;
-		goto err_return;
-	}
+	if (!dbp)
+		return -ENOMEM;
+
 	version = debugfs_create_x16("version", S_IRUGO, dbp,
 				     &boot_params.hdr.version);
-	if (!version) {
-		error = -ENOMEM;
+	if (!version)
 		goto err_dir;
-	}
+
 	data = debugfs_create_blob("data", S_IRUGO, dbp,
 				   &boot_params_blob);
-	if (!data) {
-		error = -ENOMEM;
+	if (!data)
 		goto err_version;
-	}
+
 	error = create_setup_data_nodes(dbp);
 	if (error)
 		goto err_data;
+
 	return 0;
 
 err_data:
@@ -205,10 +196,9 @@ err_version:
 	debugfs_remove(version);
 err_dir:
 	debugfs_remove(dbp);
-err_return:
 	return error;
 }
-#endif
+#endif /* CONFIG_DEBUG_BOOT_PARAMS */
 
 static int __init arch_kdebugfs_init(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/kgdb.c linux-libre-2.6.30-gnu1/arch/x86/kernel/kgdb.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/kgdb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/kgdb.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@
 #include <asm/apicdef.h>
 #include <asm/system.h>
 
-#include <mach_ipi.h>
+#include <asm/apic.h>
 
 /*
  * Put the error code here just in case the user cares:
@@ -88,6 +88,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[GDB_SS]	= __KERNEL_DS;
 	gdb_regs[GDB_FS]	= 0xFFFF;
 	gdb_regs[GDB_GS]	= 0xFFFF;
+	gdb_regs[GDB_SP]	= (int)&regs->sp;
 #else
 	gdb_regs[GDB_R8]	= regs->r8;
 	gdb_regs[GDB_R9]	= regs->r9;
@@ -100,8 +101,8 @@ 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;
-#endif
 	gdb_regs[GDB_SP]	= regs->sp;
+#endif
 }
 
 /**
@@ -347,7 +348,7 @@ void kgdb_post_primary_code(struct pt_re
  */
 void kgdb_roundup_cpus(unsigned long flags)
 {
-	send_IPI_allbutself(APIC_DM_NMI);
+	apic->send_IPI_allbutself(APIC_DM_NMI);
 }
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/kprobes.c linux-libre-2.6.30-gnu1/arch/x86/kernel/kprobes.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/kprobes.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/kprobes.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ static int __kprobes can_boost(kprobe_op
 	kprobe_opcode_t opcode;
 	kprobe_opcode_t *orig_opcodes = opcodes;
 
-	if (search_exception_tables(opcodes))
+	if (search_exception_tables((unsigned long)opcodes))
 		return 0;	/* Page fault may occur on this address. */
 
 retry:
@@ -638,13 +638,13 @@ static void __used __kprobes kretprobe_t
 #else
 			"	pushf\n"
 			/*
-			 * Skip cs, ip, orig_ax.
+			 * Skip cs, ip, orig_ax and gs.
 			 * trampoline_handler() will plug in these values
 			 */
-			"	subl $12, %esp\n"
+			"	subl $16, %esp\n"
 			"	pushl %fs\n"
-			"	pushl %ds\n"
 			"	pushl %es\n"
+			"	pushl %ds\n"
 			"	pushl %eax\n"
 			"	pushl %ebp\n"
 			"	pushl %edi\n"
@@ -655,10 +655,10 @@ static void __used __kprobes kretprobe_t
 			"	movl %esp, %eax\n"
 			"	call trampoline_handler\n"
 			/* Move flags to cs */
-			"	movl 52(%esp), %edx\n"
-			"	movl %edx, 48(%esp)\n"
+			"	movl 56(%esp), %edx\n"
+			"	movl %edx, 52(%esp)\n"
 			/* Replace saved flags with true return address. */
-			"	movl %eax, 52(%esp)\n"
+			"	movl %eax, 56(%esp)\n"
 			"	popl %ebx\n"
 			"	popl %ecx\n"
 			"	popl %edx\n"
@@ -666,8 +666,8 @@ static void __used __kprobes kretprobe_t
 			"	popl %edi\n"
 			"	popl %ebp\n"
 			"	popl %eax\n"
-			/* Skip ip, orig_ax, es, ds, fs */
-			"	addl $20, %esp\n"
+			/* Skip ds, es, fs, gs, orig_ax and ip */
+			"	addl $24, %esp\n"
 			"	popf\n"
 #endif
 			"	ret\n");
@@ -691,6 +691,7 @@ static __used __kprobes void *trampoline
 	regs->cs = __KERNEL_CS;
 #else
 	regs->cs = __KERNEL_CS | get_kernel_rpl();
+	regs->gs = 0;
 #endif
 	regs->ip = trampoline_address;
 	regs->orig_ax = ~0UL;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/kvm.c linux-libre-2.6.30-gnu1/arch/x86/kernel/kvm.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/kvm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/kvm.c	2009-06-09 23:05:27.000000000 -0400
@@ -138,12 +138,6 @@ static void kvm_set_pte_atomic(pte_t *pt
 	kvm_mmu_write(ptep, pte_val(pte));
 }
 
-static void kvm_set_pte_present(struct mm_struct *mm, unsigned long addr,
-				pte_t *ptep, pte_t pte)
-{
-	kvm_mmu_write(ptep, pte_val(pte));
-}
-
 static void kvm_pte_clear(struct mm_struct *mm,
 			  unsigned long addr, pte_t *ptep)
 {
@@ -220,7 +214,6 @@ static void paravirt_ops_setup(void)
 #if PAGETABLE_LEVELS >= 3
 #ifdef CONFIG_X86_PAE
 		pv_mmu_ops.set_pte_atomic = kvm_set_pte_atomic;
-		pv_mmu_ops.set_pte_present = kvm_set_pte_present;
 		pv_mmu_ops.pte_clear = kvm_pte_clear;
 		pv_mmu_ops.pmd_clear = kvm_pmd_clear;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/kvmclock.c linux-libre-2.6.30-gnu1/arch/x86/kernel/kvmclock.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/kvmclock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/kvmclock.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/clocksource.h>
 #include <linux/kvm_para.h>
 #include <asm/pvclock.h>
-#include <asm/arch_hooks.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
 #include <linux/percpu.h>
@@ -78,6 +77,11 @@ static cycle_t kvm_clock_read(void)
 	return ret;
 }
 
+static cycle_t kvm_clock_get_cycles(struct clocksource *cs)
+{
+	return kvm_clock_read();
+}
+
 /*
  * If we don't do that, there is the possibility that the guest
  * will calibrate under heavy load - thus, getting a lower lpj -
@@ -108,7 +112,7 @@ static void kvm_get_preset_lpj(void)
 
 static struct clocksource kvm_clock = {
 	.name = "kvm-clock",
-	.read = kvm_clock_read,
+	.read = kvm_clock_get_cycles,
 	.rating = 400,
 	.mask = CLOCKSOURCE_MASK(64),
 	.mult = 1 << KVM_SCALE,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/machine_kexec_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/machine_kexec_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/machine_kexec_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/machine_kexec_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,12 +14,12 @@
 #include <linux/ftrace.h>
 #include <linux/suspend.h>
 #include <linux/gfp.h>
+#include <linux/io.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
-#include <asm/io.h>
 #include <asm/apic.h>
 #include <asm/cpufeature.h>
 #include <asm/desc.h>
@@ -63,7 +63,7 @@ static void load_segments(void)
 		"\tmovl %%eax,%%fs\n"
 		"\tmovl %%eax,%%gs\n"
 		"\tmovl %%eax,%%ss\n"
-		::: "eax", "memory");
+		: : : "eax", "memory");
 #undef STR
 #undef __STR
 }
@@ -121,7 +121,7 @@ static void machine_kexec_page_table_set
 static void machine_kexec_prepare_page_tables(struct kimage *image)
 {
 	void *control_page;
-	pmd_t *pmd = 0;
+	pmd_t *pmd = NULL;
 
 	control_page = page_address(image->control_code_page);
 #ifdef CONFIG_X86_PAE
@@ -194,7 +194,7 @@ void machine_kexec(struct kimage *image)
 				       unsigned int preserve_context);
 
 #ifdef CONFIG_KEXEC_JUMP
-	if (kexec_image->preserve_context)
+	if (image->preserve_context)
 		save_processor_state();
 #endif
 
@@ -205,7 +205,8 @@ void machine_kexec(struct kimage *image)
 
 	if (image->preserve_context) {
 #ifdef CONFIG_X86_IO_APIC
-		/* We need to put APICs in legacy mode so that we can
+		/*
+		 * We need to put APICs in legacy mode so that we can
 		 * get timer interrupts in second kernel. kexec/kdump
 		 * paths already have calls to disable_IO_APIC() in
 		 * one form or other. kexec jump path also need
@@ -227,7 +228,8 @@ void machine_kexec(struct kimage *image)
 		page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
 						<< PAGE_SHIFT);
 
-	/* The segment registers are funny things, they have both a
+	/*
+	 * The segment registers are funny things, they have both a
 	 * visible and an invisible part.  Whenever the visible part is
 	 * set to a specific selector, the invisible part is loaded
 	 * with from a table in memory.  At no other time is the
@@ -237,11 +239,12 @@ void machine_kexec(struct kimage *image)
 	 * segments, before I zap the gdt with an invalid value.
 	 */
 	load_segments();
-	/* The gdt & idt are now invalid.
+	/*
+	 * The gdt & idt are now invalid.
 	 * If you want to load them you must set up your own idt & gdt.
 	 */
-	set_gdt(phys_to_virt(0),0);
-	set_idt(phys_to_virt(0),0);
+	set_gdt(phys_to_virt(0), 0);
+	set_idt(phys_to_virt(0), 0);
 
 	/* now call it */
 	image->start = relocate_kernel_ptr((unsigned long)image->head,
@@ -250,7 +253,7 @@ void machine_kexec(struct kimage *image)
 					   image->preserve_context);
 
 #ifdef CONFIG_KEXEC_JUMP
-	if (kexec_image->preserve_context)
+	if (image->preserve_context)
 		restore_processor_state();
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/machine_kexec_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/machine_kexec_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/machine_kexec_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/machine_kexec_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,20 +12,47 @@
 #include <linux/reboot.h>
 #include <linux/numa.h>
 #include <linux/ftrace.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
-#include <asm/io.h>
 
-#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-static u64 kexec_pgd[512] PAGE_ALIGNED;
-static u64 kexec_pud0[512] PAGE_ALIGNED;
-static u64 kexec_pmd0[512] PAGE_ALIGNED;
-static u64 kexec_pte0[512] PAGE_ALIGNED;
-static u64 kexec_pud1[512] PAGE_ALIGNED;
-static u64 kexec_pmd1[512] PAGE_ALIGNED;
-static u64 kexec_pte1[512] PAGE_ALIGNED;
+static int init_one_level2_page(struct kimage *image, pgd_t *pgd,
+				unsigned long addr)
+{
+	pud_t *pud;
+	pmd_t *pmd;
+	struct page *page;
+	int result = -ENOMEM;
+
+	addr &= PMD_MASK;
+	pgd += pgd_index(addr);
+	if (!pgd_present(*pgd)) {
+		page = kimage_alloc_control_pages(image, 0);
+		if (!page)
+			goto out;
+		pud = (pud_t *)page_address(page);
+		memset(pud, 0, PAGE_SIZE);
+		set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE));
+	}
+	pud = pud_offset(pgd, addr);
+	if (!pud_present(*pud)) {
+		page = kimage_alloc_control_pages(image, 0);
+		if (!page)
+			goto out;
+		pmd = (pmd_t *)page_address(page);
+		memset(pmd, 0, PAGE_SIZE);
+		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+	}
+	pmd = pmd_offset(pud, addr);
+	if (!pmd_present(*pmd))
+		set_pmd(pmd, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
+	result = 0;
+out:
+	return result;
+}
 
 static void init_level2_page(pmd_t *level2p, unsigned long addr)
 {
@@ -92,9 +119,8 @@ static int init_level4_page(struct kimag
 		}
 		level3p = (pud_t *)page_address(page);
 		result = init_level3_page(image, level3p, addr, last_addr);
-		if (result) {
+		if (result)
 			goto out;
-		}
 		set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE));
 		addr += PGDIR_SIZE;
 	}
@@ -107,12 +133,72 @@ out:
 	return result;
 }
 
+static void free_transition_pgtable(struct kimage *image)
+{
+	free_page((unsigned long)image->arch.pud);
+	free_page((unsigned long)image->arch.pmd);
+	free_page((unsigned long)image->arch.pte);
+}
+
+static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
+{
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	unsigned long vaddr, paddr;
+	int result = -ENOMEM;
+
+	vaddr = (unsigned long)relocate_kernel;
+	paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE);
+	pgd += pgd_index(vaddr);
+	if (!pgd_present(*pgd)) {
+		pud = (pud_t *)get_zeroed_page(GFP_KERNEL);
+		if (!pud)
+			goto err;
+		image->arch.pud = pud;
+		set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE));
+	}
+	pud = pud_offset(pgd, vaddr);
+	if (!pud_present(*pud)) {
+		pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL);
+		if (!pmd)
+			goto err;
+		image->arch.pmd = pmd;
+		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
+	}
+	pmd = pmd_offset(pud, vaddr);
+	if (!pmd_present(*pmd)) {
+		pte = (pte_t *)get_zeroed_page(GFP_KERNEL);
+		if (!pte)
+			goto err;
+		image->arch.pte = pte;
+		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
+	}
+	pte = pte_offset_kernel(pmd, vaddr);
+	set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
+	return 0;
+err:
+	free_transition_pgtable(image);
+	return result;
+}
+
 
 static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
 {
 	pgd_t *level4p;
+	int result;
 	level4p = (pgd_t *)__va(start_pgtable);
-	return init_level4_page(image, level4p, 0, max_pfn << PAGE_SHIFT);
+	result = init_level4_page(image, level4p, 0, max_pfn << PAGE_SHIFT);
+	if (result)
+		return result;
+	/*
+	 * image->start may be outside 0 ~ max_pfn, for example when
+	 * jump back to original kernel from kexeced kernel
+	 */
+	result = init_one_level2_page(image, level4p, image->start);
+	if (result)
+		return result;
+	return init_transition_pgtable(image, level4p);
 }
 
 static void set_idt(void *newidt, u16 limit)
@@ -174,7 +260,7 @@ int machine_kexec_prepare(struct kimage
 
 void machine_kexec_cleanup(struct kimage *image)
 {
-	return;
+	free_transition_pgtable(image);
 }
 
 /*
@@ -185,36 +271,45 @@ void machine_kexec(struct kimage *image)
 {
 	unsigned long page_list[PAGES_NR];
 	void *control_page;
+	int save_ftrace_enabled;
 
-	tracer_disable();
+#ifdef CONFIG_KEXEC_JUMP
+	if (image->preserve_context)
+		save_processor_state();
+#endif
+
+	save_ftrace_enabled = __ftrace_enabled_save();
 
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
+	if (image->preserve_context) {
+#ifdef CONFIG_X86_IO_APIC
+		/*
+		 * We need to put APICs in legacy mode so that we can
+		 * get timer interrupts in second kernel. kexec/kdump
+		 * paths already have calls to disable_IO_APIC() in
+		 * one form or other. kexec jump path also need
+		 * one.
+		 */
+		disable_IO_APIC();
+#endif
+	}
+
 	control_page = page_address(image->control_code_page) + PAGE_SIZE;
-	memcpy(control_page, relocate_kernel, PAGE_SIZE);
+	memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
 
 	page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
-	page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-	page_list[PA_PGD] = virt_to_phys(&kexec_pgd);
-	page_list[VA_PGD] = (unsigned long)kexec_pgd;
-	page_list[PA_PUD_0] = virt_to_phys(&kexec_pud0);
-	page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
-	page_list[PA_PMD_0] = virt_to_phys(&kexec_pmd0);
-	page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-	page_list[PA_PTE_0] = virt_to_phys(&kexec_pte0);
-	page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-	page_list[PA_PUD_1] = virt_to_phys(&kexec_pud1);
-	page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
-	page_list[PA_PMD_1] = virt_to_phys(&kexec_pmd1);
-	page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-	page_list[PA_PTE_1] = virt_to_phys(&kexec_pte1);
-	page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
-
+	page_list[VA_CONTROL_PAGE] = (unsigned long)control_page;
 	page_list[PA_TABLE_PAGE] =
 	  (unsigned long)__pa(page_address(image->control_code_page));
 
-	/* The segment registers are funny things, they have both a
+	if (image->type == KEXEC_TYPE_DEFAULT)
+		page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
+						<< PAGE_SHIFT);
+
+	/*
+	 * The segment registers are funny things, they have both a
 	 * visible and an invisible part.  Whenever the visible part is
 	 * set to a specific selector, the invisible part is loaded
 	 * with from a table in memory.  At no other time is the
@@ -224,15 +319,25 @@ void machine_kexec(struct kimage *image)
 	 * segments, before I zap the gdt with an invalid value.
 	 */
 	load_segments();
-	/* The gdt & idt are now invalid.
+	/*
+	 * The gdt & idt are now invalid.
 	 * If you want to load them you must set up your own idt & gdt.
 	 */
-	set_gdt(phys_to_virt(0),0);
-	set_idt(phys_to_virt(0),0);
+	set_gdt(phys_to_virt(0), 0);
+	set_idt(phys_to_virt(0), 0);
 
 	/* now call it */
-	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-			image->start);
+	image->start = relocate_kernel((unsigned long)image->head,
+				       (unsigned long)page_list,
+				       image->start,
+				       image->preserve_context);
+
+#ifdef CONFIG_KEXEC_JUMP
+	if (image->preserve_context)
+		restore_processor_state();
+#endif
+
+	__ftrace_enabled_restore(save_ftrace_enabled);
 }
 
 void arch_crash_save_vmcoreinfo(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/Makefile linux-libre-2.6.30-gnu1/arch/x86/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -23,11 +23,12 @@ nostackp := $(call cc-option, -fno-stack
 CFLAGS_vsyscall_64.o	:= $(PROFILING) -g0 $(nostackp)
 CFLAGS_hpet.o		:= $(nostackp)
 CFLAGS_tsc.o		:= $(nostackp)
+CFLAGS_paravirt.o	:= $(nostackp)
 
 obj-y			:= process_$(BITS).o signal.o entry_$(BITS).o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time_$(BITS).o ioport.o ldt.o dumpstack.o
-obj-y			+= setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
+obj-y			+= setup.o i8259.o irqinit_$(BITS).o
 obj-$(CONFIG_X86_VISWS)	+= visws_quirks.o
 obj-$(CONFIG_X86_32)	+= probe_roms_32.o
 obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
@@ -49,31 +50,27 @@ obj-y				+= step.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-y				+= cpu/
 obj-y				+= acpi/
-obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
+obj-y				+= reboot.o
 obj-$(CONFIG_MCA)		+= mca_32.o
 obj-$(CONFIG_X86_MSR)		+= msr.o
 obj-$(CONFIG_X86_CPUID)		+= cpuid.o
 obj-$(CONFIG_PCI)		+= early-quirks.o
 apm-y				:= apm_32.o
 obj-$(CONFIG_APM)		+= apm.o
-obj-$(CONFIG_X86_SMP)		+= smp.o
-obj-$(CONFIG_X86_SMP)		+= smpboot.o tsc_sync.o ipi.o tlb_$(BITS).o
-obj-$(CONFIG_X86_32_SMP)	+= smpcommon.o
-obj-$(CONFIG_X86_64_SMP)	+= tsc_sync.o smpcommon.o
+obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_SMP)		+= smpboot.o tsc_sync.o
+obj-$(CONFIG_SMP)		+= setup_percpu.o
+obj-$(CONFIG_X86_64_SMP)	+= tsc_sync.o
 obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline_$(BITS).o
 obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
-obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
-obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
+obj-y				+= apic/
 obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups_32.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
-obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
-obj-$(CONFIG_X86_ES7000)	+= es7000_32.o
-obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit_32.o
-obj-y				+= vsmp_64.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_MODULES)		+= module_$(BITS).o
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
@@ -92,7 +89,8 @@ obj-$(CONFIG_DEBUG_NX_TEST)	+= test_nx.o
 obj-$(CONFIG_VMI)		+= vmi_32.o vmiclock_32.o
 obj-$(CONFIG_KVM_GUEST)		+= kvm.o
 obj-$(CONFIG_KVM_CLOCK)		+= kvmclock.o
-obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirt_patch_$(BITS).o paravirt-spinlocks.o
+obj-$(CONFIG_PARAVIRT)		+= paravirt.o paravirt_patch_$(BITS).o
+obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
 obj-$(CONFIG_PARAVIRT_CLOCK)	+= pvclock.o
 
 obj-$(CONFIG_PCSPKR_PLATFORM)	+= pcspeaker.o
@@ -109,21 +107,19 @@ obj-$(CONFIG_MICROCODE)			+= microcode.o
 
 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
 
-obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb_64.o # NB rename without _64
+obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
 
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
-        obj-y				+= genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
-	obj-y				+= bios_uv.o uv_irq.o uv_sysfs.o
-        obj-y				+= genx2apic_cluster.o
-        obj-y				+= genx2apic_phys.o
-        obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
-        obj-$(CONFIG_AUDIT)		+= audit_64.o
+	obj-$(CONFIG_X86_UV)		+= tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o uv_time.o
+	obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer_64.o
+	obj-$(CONFIG_AUDIT)		+= audit_64.o
 
-        obj-$(CONFIG_GART_IOMMU)	+= pci-gart_64.o aperture_64.o
-        obj-$(CONFIG_CALGARY_IOMMU)	+= pci-calgary_64.o tce_64.o
-        obj-$(CONFIG_AMD_IOMMU)		+= amd_iommu_init.o amd_iommu.o
+	obj-$(CONFIG_GART_IOMMU)	+= pci-gart_64.o aperture_64.o
+	obj-$(CONFIG_CALGARY_IOMMU)	+= pci-calgary_64.o tce_64.o
+	obj-$(CONFIG_AMD_IOMMU)		+= amd_iommu_init.o amd_iommu.o
 
-        obj-$(CONFIG_PCI_MMCONFIG)	+= mmconf-fam10h_64.o
+	obj-$(CONFIG_PCI_MMCONFIG)	+= mmconf-fam10h_64.o
+	obj-y				+= vsmp_64.o
 endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/mca_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/mca_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/mca_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/mca_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,6 @@
 #include <linux/ioport.h>
 #include <asm/uaccess.h>
 #include <linux/init.h>
-#include <asm/arch_hooks.h>
 
 static unsigned char which_scsi;
 
@@ -474,6 +473,4 @@ void __kprobes mca_handle_nmi(void)
 	 * adapter was responsible for the error.
 	 */
 	bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback);
-
-	mca_nmi_hook();
-} /* mca_handle_nmi */
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/mfgpt_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/mfgpt_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/mfgpt_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/mfgpt_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -348,7 +348,6 @@ static irqreturn_t mfgpt_tick(int irq, v
 static struct irqaction mfgptirq  = {
 	.handler = mfgpt_tick,
 	.flags = IRQF_DISABLED | IRQF_NOBALANCING,
-	.mask = CPU_MASK_NONE,
 	.name = "mfgpt-timer"
 };
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_amd.c linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_amd.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_amd.c	2013-05-03 17:59:33.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_amd.c	2013-05-03 16:43:21.000000000 -0400
@@ -12,31 +12,30 @@
  *
  *  Licensed under the terms of the GNU General Public
  *  License version 2. See file COPYING for details.
-*/
-
+ */
+#include <linux/platform_device.h>
 #include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/miscdevice.h>
+#include <linux/firmware.h>
 #include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/cpumask.h>
+#include <linux/pci_ids.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
 #include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("AMD Microcode Update Driver");
 MODULE_AUTHOR("Peter Oruba");
@@ -72,8 +71,8 @@ struct microcode_header_amd {
 } __attribute__((packed));
 
 struct microcode_amd {
-	struct microcode_header_amd hdr;
-	unsigned int mpb[0];
+	struct microcode_header_amd	hdr;
+	unsigned int			mpb[0];
 };
 
 #define UCODE_MAX_SIZE			2048
@@ -184,8 +183,8 @@ static int get_ucode_data(void *to, cons
 	return 0;
 }
 
-static void *get_next_ucode(const u8 *buf, unsigned int size,
-			    unsigned int *mc_size)
+static void *
+get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
 {
 	unsigned int total_size;
 	u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
@@ -223,7 +222,6 @@ static void *get_next_ucode(const u8 *bu
 	return mc;
 }
 
-
 static int install_equiv_cpu_table(const u8 *buf)
 {
 	u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
@@ -372,4 +370,3 @@ struct microcode_ops * __init init_amd_m
 {
 	return &microcode_amd_ops;
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_core.c linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_core.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,41 +70,41 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
+#include <linux/platform_device.h>
 #include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
 #include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
 #include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
 MODULE_LICENSE("GPL");
 
-#define MICROCODE_VERSION 	"2.00"
+#define MICROCODE_VERSION	"2.00"
 
-static struct microcode_ops *microcode_ops;
+static struct microcode_ops	*microcode_ops;
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
 static DEFINE_MUTEX(microcode_mutex);
 
-struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
+struct ucode_cpu_info		ucode_cpu_info[NR_CPUS];
 EXPORT_SYMBOL_GPL(ucode_cpu_info);
 
 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
@@ -198,18 +198,33 @@ static void microcode_dev_exit(void)
 
 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
 #else
-#define microcode_dev_init() 0
-#define microcode_dev_exit() do { } while (0)
+#define microcode_dev_init()	0
+#define microcode_dev_exit()	do { } while (0)
 #endif
 
 /* fake device for request_firmware */
-static struct platform_device *microcode_pdev;
+static struct platform_device	*microcode_pdev;
+
+static long reload_for_cpu(void *unused)
+{
+	struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
+	int err = 0;
+
+	mutex_lock(&microcode_mutex);
+	if (uci->valid) {
+		err = microcode_ops->request_microcode_fw(smp_processor_id(),
+							  &microcode_pdev->dev);
+		if (!err)
+			microcode_ops->apply_microcode(smp_processor_id());
+	}
+	mutex_unlock(&microcode_mutex);
+	return err;
+}
 
 static ssize_t reload_store(struct sys_device *dev,
 			    struct sysdev_attribute *attr,
 			    const char *buf, size_t sz)
 {
-	struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 	char *end;
 	unsigned long val = simple_strtoul(buf, &end, 0);
 	int err = 0;
@@ -218,21 +233,9 @@ static ssize_t reload_store(struct sys_d
 	if (end == buf)
 		return -EINVAL;
 	if (val == 1) {
-		cpumask_t old = current->cpus_allowed;
-
 		get_online_cpus();
-		if (cpu_online(cpu)) {
-			set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-			mutex_lock(&microcode_mutex);
-			if (uci->valid) {
-				err = microcode_ops->request_microcode_fw(cpu,
-						&microcode_pdev->dev);
-				if (!err)
-					microcode_ops->apply_microcode(cpu);
-			}
-			mutex_unlock(&microcode_mutex);
-			set_cpus_allowed_ptr(current, &old);
-		}
+		if (cpu_online(cpu))
+			err = work_on_cpu(cpu, reload_for_cpu, NULL);
 		put_online_cpus();
 	}
 	if (err)
@@ -268,8 +271,8 @@ static struct attribute *mc_default_attr
 };
 
 static struct attribute_group mc_attr_group = {
-	.attrs = mc_default_attrs,
-	.name = "microcode",
+	.attrs		= mc_default_attrs,
+	.name		= "microcode",
 };
 
 static void __microcode_fini_cpu(int cpu)
@@ -328,9 +331,9 @@ static int microcode_resume_cpu(int cpu)
 	return 0;
 }
 
-static void microcode_update_cpu(int cpu)
+static long microcode_update_cpu(void *unused)
 {
-	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
 	int err = 0;
 
 	/*
@@ -338,30 +341,27 @@ static void microcode_update_cpu(int cpu
 	 * otherwise just request a firmware:
 	 */
 	if (uci->valid) {
-		err = microcode_resume_cpu(cpu);
-	} else {	
-		collect_cpu_info(cpu);
+		err = microcode_resume_cpu(smp_processor_id());
+	} else {
+		collect_cpu_info(smp_processor_id());
 		if (uci->valid && system_state == SYSTEM_RUNNING)
-			err = microcode_ops->request_microcode_fw(cpu,
+			err = microcode_ops->request_microcode_fw(
+					smp_processor_id(),
 					&microcode_pdev->dev);
 	}
 	if (!err)
-		microcode_ops->apply_microcode(cpu);
+		microcode_ops->apply_microcode(smp_processor_id());
+	return err;
 }
 
-static void microcode_init_cpu(int cpu)
+static int microcode_init_cpu(int cpu)
 {
-	cpumask_t old = current->cpus_allowed;
-
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-	/* We should bind the task to the CPU */
-	BUG_ON(raw_smp_processor_id() != cpu);
-
+	int err;
 	mutex_lock(&microcode_mutex);
-	microcode_update_cpu(cpu);
+	err = work_on_cpu(cpu, microcode_update_cpu, NULL);
 	mutex_unlock(&microcode_mutex);
 
-	set_cpus_allowed_ptr(current, &old);
+	return err;
 }
 
 static int mc_sysdev_add(struct sys_device *sys_dev)
@@ -379,8 +379,9 @@ static int mc_sysdev_add(struct sys_devi
 	if (err)
 		return err;
 
-	microcode_init_cpu(cpu);
-	return 0;
+	err = microcode_init_cpu(cpu);
+
+	return err;
 }
 
 static int mc_sysdev_remove(struct sys_device *sys_dev)
@@ -404,14 +405,14 @@ static int mc_sysdev_resume(struct sys_d
 		return 0;
 
 	/* only CPU 0 will apply ucode here */
-	microcode_update_cpu(0);
+	microcode_update_cpu(NULL);
 	return 0;
 }
 
 static struct sysdev_driver mc_sysdev_driver = {
-	.add = mc_sysdev_add,
-	.remove = mc_sysdev_remove,
-	.resume = mc_sysdev_resume,
+	.add		= mc_sysdev_add,
+	.remove		= mc_sysdev_remove,
+	.resume		= mc_sysdev_resume,
 };
 
 static __cpuinit int
@@ -424,7 +425,9 @@ mc_cpu_callback(struct notifier_block *n
 	switch (action) {
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
-		microcode_init_cpu(cpu);
+		if (microcode_init_cpu(cpu))
+			printk(KERN_ERR "microcode: failed to init CPU%d\n",
+			       cpu);
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
 		pr_debug("microcode: CPU%d added\n", cpu);
@@ -448,7 +451,7 @@ mc_cpu_callback(struct notifier_block *n
 }
 
 static struct notifier_block __refdata mc_cpu_notifier = {
-	.notifier_call = mc_cpu_callback,
+	.notifier_call	= mc_cpu_callback,
 };
 
 static int __init microcode_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_intel.c linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_intel.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 17:59:43.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/microcode_intel.c	2013-05-03 16:43:25.000000000 -0400
@@ -70,28 +70,28 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
+#include <linux/platform_device.h>
 #include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
 #include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
 #include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -129,12 +129,13 @@ struct extended_sigtable {
 	struct extended_signature sigs[0];
 };
 
-#define DEFAULT_UCODE_DATASIZE 	(2000)
+#define DEFAULT_UCODE_DATASIZE	(2000)
 #define MC_HEADER_SIZE		(sizeof(struct microcode_header_intel))
 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
 #define EXT_HEADER_SIZE		(sizeof(struct extended_sigtable))
 #define EXT_SIGNATURE_SIZE	(sizeof(struct extended_signature))
 #define DWSIZE			(sizeof(u32))
+
 #define get_totalsize(mc) \
 	(((struct microcode_intel *)mc)->hdr.totalsize ? \
 	 ((struct microcode_intel *)mc)->hdr.totalsize : \
@@ -196,31 +197,32 @@ static inline int update_match_cpu(struc
 	return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1;
 }
 
-static inline int 
-update_match_revision(struct microcode_header_intel *mc_header,	int rev)
+static inline int
+update_match_revision(struct microcode_header_intel *mc_header, int rev)
 {
 	return (mc_header->rev <= rev) ? 0 : 1;
 }
 
 static int microcode_sanity_check(void *mc)
 {
+	unsigned long total_size, data_size, ext_table_size;
 	struct microcode_header_intel *mc_header = mc;
 	struct extended_sigtable *ext_header = NULL;
-	struct extended_signature *ext_sig;
-	unsigned long total_size, data_size, ext_table_size;
 	int sum, orig_sum, ext_sigcount = 0, i;
+	struct extended_signature *ext_sig;
 
 	total_size = get_totalsize(mc_header);
 	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");
+				"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");
+				"Unknown microcode update format\n");
 		return -EINVAL;
 	}
 	ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
@@ -318,11 +320,15 @@ get_matching_microcode(struct cpu_signat
 
 static void apply_microcode(int cpu)
 {
+	struct microcode_intel *mc_intel;
+	struct ucode_cpu_info *uci;
 	unsigned long flags;
 	unsigned int val[2];
-	int cpu_num = raw_smp_processor_id();
-	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-	struct microcode_intel *mc_intel = uci->mc;
+	int cpu_num;
+
+	cpu_num = raw_smp_processor_id();
+	uci = ucode_cpu_info + cpu;
+	mc_intel = uci->mc;
 
 	/* We should bind the task to the CPU */
 	BUG_ON(cpu_num != cpu);
@@ -348,15 +354,17 @@ static void apply_microcode(int cpu)
 	spin_unlock_irqrestore(&microcode_update_lock, flags);
 	if (val[1] != mc_intel->hdr.rev) {
 		printk(KERN_ERR "microcode: CPU%d update from revision "
-			"0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]);
+				"0x%x to 0x%x failed\n",
+			cpu_num, uci->cpu_sig.rev, val[1]);
 		return;
 	}
 	printk(KERN_INFO "microcode: CPU%d updated from revision "
-	       "0x%x to 0x%x, date = %04x-%02x-%02x \n",
+			 "0x%x to 0x%x, date = %04x-%02x-%02x \n",
 		cpu_num, uci->cpu_sig.rev, val[1],
 		mc_intel->hdr.date & 0xffff,
 		mc_intel->hdr.date >> 24,
 		(mc_intel->hdr.date >> 16) & 0xff);
+
 	uci->cpu_sig.rev = val[1];
 }
 
@@ -404,18 +412,23 @@ static int generic_load_microcode(int cp
 		leftover  -= mc_size;
 	}
 
-	if (new_mc) {
-		if (!leftover) {
-			if (uci->mc)
-				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);
-		} else
-			vfree(new_mc);
+	if (!new_mc)
+		goto out;
+
+	if (leftover) {
+		vfree(new_mc);
+		goto out;
 	}
 
+	if (uci->mc)
+		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);
+
+ out:
 	return (int)leftover;
 }
 
@@ -442,8 +455,8 @@ static int request_microcode_fw(int cpu,
 		return ret;
 	}
 
-	ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size,
-			&get_ucode_fw);
+	ret = generic_load_microcode(cpu, (void *)firmware->data,
+				     firmware->size, &get_ucode_fw);
 
 	release_firmware(firmware);
 
@@ -460,7 +473,7 @@ static int request_microcode_user(int cp
 	/* We should bind the task to the CPU */
 	BUG_ON(cpu != raw_smp_processor_id());
 
-	return generic_load_microcode(cpu, (void*)buf, size, &get_ucode_user);
+	return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
 }
 
 static void microcode_fini_cpu(int cpu)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/mmconf-fam10h_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/mmconf-fam10h_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/mmconf-fam10h_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/mmconf-fam10h_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -226,7 +226,7 @@ static int __devinit set_check_enable_am
         return 0;
 }
 
-static struct dmi_system_id __devinitdata mmconf_dmi_table[] = {
+static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = {
         {
                 .callback = set_check_enable_amd_mmconf,
                 .ident = "Sun Microsystems Machine",
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/module_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/module_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/module_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/module_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ void module_free(struct module *mod, voi
 {
 	vfree(module_region);
 	/* FIXME: If module_region == mod->init_region, trim exception
-           table entries. */
+	   table entries. */
 }
 
 /* We don't need anything special. */
@@ -113,13 +113,13 @@ int module_finalize(const Elf_Ehdr *hdr,
 		*para = NULL;
 	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
 
-	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { 
+	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
 		if (!strcmp(".text", secstrings + s->sh_name))
 			text = s;
 		if (!strcmp(".altinstructions", secstrings + s->sh_name))
 			alt = s;
 		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks= s;
+			locks = s;
 		if (!strcmp(".parainstructions", secstrings + s->sh_name))
 			para = s;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/module_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/module_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/module_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/module_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,14 +30,14 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-#define DEBUGP(fmt...) 
+#define DEBUGP(fmt...)
 
 #ifndef CONFIG_UML
 void module_free(struct module *mod, void *module_region)
 {
 	vfree(module_region);
 	/* FIXME: If module_region == mod->init_region, trim exception
-           table entries. */
+	   table entries. */
 }
 
 void *module_alloc(unsigned long size)
@@ -77,7 +77,7 @@ int apply_relocate_add(Elf64_Shdr *sechd
 	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
 	Elf64_Sym *sym;
 	void *loc;
-	u64 val; 
+	u64 val;
 
 	DEBUGP("Applying relocate section %u to %u\n", relsec,
 	       sechdrs[relsec].sh_info);
@@ -91,11 +91,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
 		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
 			+ ELF64_R_SYM(rel[i].r_info);
 
-	        DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
-		       (int)ELF64_R_TYPE(rel[i].r_info), 
-		       sym->st_value, rel[i].r_addend, (u64)loc);
+		DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
+			(int)ELF64_R_TYPE(rel[i].r_info),
+			sym->st_value, rel[i].r_addend, (u64)loc);
 
-		val = sym->st_value + rel[i].r_addend; 
+		val = sym->st_value + rel[i].r_addend;
 
 		switch (ELF64_R_TYPE(rel[i].r_info)) {
 		case R_X86_64_NONE:
@@ -113,16 +113,16 @@ int apply_relocate_add(Elf64_Shdr *sechd
 			if ((s64)val != *(s32 *)loc)
 				goto overflow;
 			break;
-		case R_X86_64_PC32: 
+		case R_X86_64_PC32:
 			val -= (u64)loc;
 			*(u32 *)loc = val;
 #if 0
 			if ((s64)val != *(s32 *)loc)
-				goto overflow; 
+				goto overflow;
 #endif
 			break;
 		default:
-			printk(KERN_ERR "module %s: Unknown rela relocation: %Lu\n",
+			printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
 			       me->name, ELF64_R_TYPE(rel[i].r_info));
 			return -ENOEXEC;
 		}
@@ -130,7 +130,7 @@ int apply_relocate_add(Elf64_Shdr *sechd
 	return 0;
 
 overflow:
-	printk(KERN_ERR "overflow in relocation type %d val %Lx\n", 
+	printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
 	       (int)ELF64_R_TYPE(rel[i].r_info), val);
 	printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
 	       me->name);
@@ -143,13 +143,13 @@ int apply_relocate(Elf_Shdr *sechdrs,
 		   unsigned int relsec,
 		   struct module *me)
 {
-	printk("non add relocation not supported\n");
+	printk(KERN_ERR "non add relocation not supported\n");
 	return -ENOSYS;
-} 
+}
 
 int module_finalize(const Elf_Ehdr *hdr,
-                    const Elf_Shdr *sechdrs,
-                    struct module *me)
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
 {
 	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
 		*para = NULL;
@@ -161,7 +161,7 @@ int module_finalize(const Elf_Ehdr *hdr,
 		if (!strcmp(".altinstructions", secstrings + s->sh_name))
 			alt = s;
 		if (!strcmp(".smp_locks", secstrings + s->sh_name))
-			locks= s;
+			locks = s;
 		if (!strcmp(".parainstructions", secstrings + s->sh_name))
 			para = s;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/mpparse.c linux-libre-2.6.30-gnu1/arch/x86/kernel/mpparse.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/mpparse.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/mpparse.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  *	compliant MP-table parsing routines.
  *
  *	(c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk>
- *	(c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
+ *	(c) 1998, 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
  *      (c) 2008 Alexey Starikovskiy <astarikovskiy@suse.de>
  */
 
@@ -29,12 +29,7 @@
 #include <asm/setup.h>
 #include <asm/smp.h>
 
-#include <mach_apic.h>
-#ifdef CONFIG_X86_32
-#include <mach_apicdef.h>
-#include <mach_mpparse.h>
-#endif
-
+#include <asm/apic.h>
 /*
  * Checksum an MP configuration block.
  */
@@ -114,9 +109,6 @@ static void __init MP_bus_info(struct mp
 	} else
 		printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
 
 static int bad_ioapic(unsigned long address)
 {
@@ -144,11 +136,11 @@ static void __init MP_ioapic_info(struct
 	if (bad_ioapic(m->apicaddr))
 		return;
 
-	mp_ioapics[nr_ioapics].mp_apicaddr = m->apicaddr;
-	mp_ioapics[nr_ioapics].mp_apicid = m->apicid;
-	mp_ioapics[nr_ioapics].mp_type = m->type;
-	mp_ioapics[nr_ioapics].mp_apicver = m->apicver;
-	mp_ioapics[nr_ioapics].mp_flags = m->flags;
+	mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
+	mp_ioapics[nr_ioapics].apicid = m->apicid;
+	mp_ioapics[nr_ioapics].type = m->type;
+	mp_ioapics[nr_ioapics].apicver = m->apicver;
+	mp_ioapics[nr_ioapics].flags = m->flags;
 	nr_ioapics++;
 }
 
@@ -160,55 +152,55 @@ static void print_MP_intsrc_info(struct
 		m->srcbusirq, m->dstapic, m->dstirq);
 }
 
-static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq)
+static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
 {
 	apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
 		" IRQ %02x, APIC ID %x, APIC INT %02x\n",
-		mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3,
-		(mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus,
-		mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq);
+		mp_irq->irqtype, mp_irq->irqflag & 3,
+		(mp_irq->irqflag >> 2) & 3, mp_irq->srcbus,
+		mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
 }
 
 static void __init assign_to_mp_irq(struct mpc_intsrc *m,
-				    struct mp_config_intsrc *mp_irq)
+				    struct mpc_intsrc *mp_irq)
 {
-	mp_irq->mp_dstapic = m->dstapic;
-	mp_irq->mp_type = m->type;
-	mp_irq->mp_irqtype = m->irqtype;
-	mp_irq->mp_irqflag = m->irqflag;
-	mp_irq->mp_srcbus = m->srcbus;
-	mp_irq->mp_srcbusirq = m->srcbusirq;
-	mp_irq->mp_dstirq = m->dstirq;
+	mp_irq->dstapic = m->dstapic;
+	mp_irq->type = m->type;
+	mp_irq->irqtype = m->irqtype;
+	mp_irq->irqflag = m->irqflag;
+	mp_irq->srcbus = m->srcbus;
+	mp_irq->srcbusirq = m->srcbusirq;
+	mp_irq->dstirq = m->dstirq;
 }
 
-static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq,
+static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq,
 					struct mpc_intsrc *m)
 {
-	m->dstapic = mp_irq->mp_dstapic;
-	m->type = mp_irq->mp_type;
-	m->irqtype = mp_irq->mp_irqtype;
-	m->irqflag = mp_irq->mp_irqflag;
-	m->srcbus = mp_irq->mp_srcbus;
-	m->srcbusirq = mp_irq->mp_srcbusirq;
-	m->dstirq = mp_irq->mp_dstirq;
+	m->dstapic = mp_irq->dstapic;
+	m->type = mp_irq->type;
+	m->irqtype = mp_irq->irqtype;
+	m->irqflag = mp_irq->irqflag;
+	m->srcbus = mp_irq->srcbus;
+	m->srcbusirq = mp_irq->srcbusirq;
+	m->dstirq = mp_irq->dstirq;
 }
 
-static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
+static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq,
 					struct mpc_intsrc *m)
 {
-	if (mp_irq->mp_dstapic != m->dstapic)
+	if (mp_irq->dstapic != m->dstapic)
 		return 1;
-	if (mp_irq->mp_type != m->type)
+	if (mp_irq->type != m->type)
 		return 2;
-	if (mp_irq->mp_irqtype != m->irqtype)
+	if (mp_irq->irqtype != m->irqtype)
 		return 3;
-	if (mp_irq->mp_irqflag != m->irqflag)
+	if (mp_irq->irqflag != m->irqflag)
 		return 4;
-	if (mp_irq->mp_srcbus != m->srcbus)
+	if (mp_irq->srcbus != m->srcbus)
 		return 5;
-	if (mp_irq->mp_srcbusirq != m->srcbusirq)
+	if (mp_irq->srcbusirq != m->srcbusirq)
 		return 6;
-	if (mp_irq->mp_dstirq != m->dstirq)
+	if (mp_irq->dstirq != m->dstirq)
 		return 7;
 
 	return 0;
@@ -229,8 +221,12 @@ static void __init MP_intsrc_info(struct
 	if (++mp_irq_entries == MAX_IRQ_SOURCES)
 		panic("Max # of irq sources exceeded!!\n");
 }
+#else /* CONFIG_X86_IO_APIC */
+static inline void __init MP_bus_info(struct mpc_bus *m) {}
+static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
+static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
+#endif /* CONFIG_X86_IO_APIC */
 
-#endif
 
 static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
 {
@@ -280,6 +276,20 @@ static int __init smp_check_mpc(struct m
 	return 1;
 }
 
+static void skip_entry(unsigned char **ptr, int *count, int size)
+{
+	*ptr += size;
+	*count += size;
+}
+
+static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
+{
+	printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"
+		"type %x\n", *mpt);
+	print_hex_dump(KERN_ERR, "  ", DUMP_PREFIX_ADDRESS, 16,
+			1, mpc, mpc->length, 1);
+}
+
 static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
 {
 	char str[16];
@@ -292,16 +302,7 @@ static int __init smp_read_mpc(struct mp
 		return 0;
 
 #ifdef CONFIG_X86_32
-	/*
-	 * need to make sure summit and es7000's mps_oem_check is safe to be
-	 * called early via genericarch 's mps_oem_check
-	 */
-	if (early) {
-#ifdef CONFIG_X86_NUMAQ
-		numaq_mps_oem_check(mpc, oem, str);
-#endif
-	} else
-		mps_oem_check(mpc, oem, str);
+	generic_mps_oem_check(mpc, oem, str);
 #endif
 	/* save the local APIC address, it might be non-default */
 	if (!acpi_lapic)
@@ -324,61 +325,30 @@ static int __init smp_read_mpc(struct mp
 	while (count < mpc->length) {
 		switch (*mpt) {
 		case MP_PROCESSOR:
-			{
-				struct mpc_cpu *m = (struct mpc_cpu *)mpt;
-				/* ACPI may have already provided this data */
-				if (!acpi_lapic)
-					MP_processor_info(m);
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			/* ACPI may have already provided this data */
+			if (!acpi_lapic)
+				MP_processor_info((struct mpc_cpu *)mpt);
+			skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
+			break;
 		case MP_BUS:
-			{
-				struct mpc_bus *m = (struct mpc_bus *)mpt;
-#ifdef CONFIG_X86_IO_APIC
-				MP_bus_info(m);
-#endif
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			MP_bus_info((struct mpc_bus *)mpt);
+			skip_entry(&mpt, &count, sizeof(struct mpc_bus));
+			break;
 		case MP_IOAPIC:
-			{
-#ifdef CONFIG_X86_IO_APIC
-				struct mpc_ioapic *m = (struct mpc_ioapic *)mpt;
-				MP_ioapic_info(m);
-#endif
-				mpt += sizeof(struct mpc_ioapic);
-				count += sizeof(struct mpc_ioapic);
-				break;
-			}
+			MP_ioapic_info((struct mpc_ioapic *)mpt);
+			skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
+			break;
 		case MP_INTSRC:
-			{
-#ifdef CONFIG_X86_IO_APIC
-				struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
-
-				MP_intsrc_info(m);
-#endif
-				mpt += sizeof(struct mpc_intsrc);
-				count += sizeof(struct mpc_intsrc);
-				break;
-			}
+			MP_intsrc_info((struct mpc_intsrc *)mpt);
+			skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
+			break;
 		case MP_LINTSRC:
-			{
-				struct mpc_lintsrc *m =
-				    (struct mpc_lintsrc *)mpt;
-				MP_lintsrc_info(m);
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			MP_lintsrc_info((struct mpc_lintsrc *)mpt);
+			skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
+			break;
 		default:
 			/* wrong mptable */
-			printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
-			printk(KERN_ERR "type %x\n", *mpt);
-			print_hex_dump(KERN_ERR, "  ", DUMP_PREFIX_ADDRESS, 16,
-					1, mpc, mpc->length, 1);
+			smp_dump_mptable(mpc, mpt);
 			count = mpc->length;
 			break;
 		}
@@ -386,13 +356,13 @@ static int __init smp_read_mpc(struct mp
 			(*x86_quirks->mpc_record)++;
 	}
 
-#ifdef CONFIG_X86_GENERICARCH
-       generic_bigsmp_probe();
+#ifdef CONFIG_X86_BIGSMP
+	generic_bigsmp_probe();
 #endif
 
-#ifdef CONFIG_X86_32
-	setup_apic_routing();
-#endif
+	if (apic->setup_apic_routing)
+		apic->setup_apic_routing();
+
 	if (!num_processors)
 		printk(KERN_ERR "MPTABLE: no processors registered!\n");
 	return num_processors;
@@ -417,7 +387,7 @@ static void __init construct_default_ioi
 	intsrc.type = MP_INTSRC;
 	intsrc.irqflag = 0;	/* conforming */
 	intsrc.srcbus = 0;
-	intsrc.dstapic = mp_ioapics[0].mp_apicid;
+	intsrc.dstapic = mp_ioapics[0].apicid;
 
 	intsrc.irqtype = mp_INT;
 
@@ -570,14 +540,76 @@ static inline void __init construct_defa
 	}
 }
 
-static struct intel_mp_floating *mpf_found;
+static struct mpf_intel *mpf_found;
+
+static unsigned long __init get_mpc_size(unsigned long physptr)
+{
+	struct mpc_table *mpc;
+	unsigned long size;
+
+	mpc = early_ioremap(physptr, PAGE_SIZE);
+	size = mpc->length;
+	early_iounmap(mpc, PAGE_SIZE);
+	apic_printk(APIC_VERBOSE, "  mpc: %lx-%lx\n", physptr, physptr + size);
+
+	return size;
+}
+
+static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
+{
+	struct mpc_table *mpc;
+	unsigned long size;
+
+	size = get_mpc_size(mpf->physptr);
+	mpc = early_ioremap(mpf->physptr, size);
+	/*
+	 * Read the physical hardware table.  Anything here will
+	 * override the defaults.
+	 */
+	if (!smp_read_mpc(mpc, early)) {
+#ifdef CONFIG_X86_LOCAL_APIC
+		smp_found_config = 0;
+#endif
+		printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"
+			"... disabling SMP support. (tell your hw vendor)\n");
+		early_iounmap(mpc, size);
+		return -1;
+	}
+	early_iounmap(mpc, size);
+
+	if (early)
+		return -1;
+
+#ifdef CONFIG_X86_IO_APIC
+	/*
+	 * If there are no explicit MP IRQ entries, then we are
+	 * broken.  We set up most of the low 16 IO-APIC pins to
+	 * ISA defaults and hope it will work.
+	 */
+	if (!mp_irq_entries) {
+		struct mpc_bus bus;
+
+		printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
+		       "using default mptable. (tell your hw vendor)\n");
+
+		bus.type = MP_BUS;
+		bus.busid = 0;
+		memcpy(bus.bustype, "ISA   ", 6);
+		MP_bus_info(&bus);
+
+		construct_default_ioirq_mptable(0);
+	}
+#endif
+
+	return 0;
+}
 
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
 static void __init __get_smp_config(unsigned int early)
 {
-	struct intel_mp_floating *mpf = mpf_found;
+	struct mpf_intel *mpf = mpf_found;
 
 	if (!mpf)
 		return;
@@ -598,9 +630,9 @@ static void __init __get_smp_config(unsi
 	}
 
 	printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
-	       mpf->mpf_specification);
+	       mpf->specification);
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
-	if (mpf->mpf_feature2 & (1 << 7)) {
+	if (mpf->feature2 & (1 << 7)) {
 		printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
 		pic_mode = 1;
 	} else {
@@ -611,7 +643,7 @@ static void __init __get_smp_config(unsi
 	/*
 	 * Now see if we need to read further.
 	 */
-	if (mpf->mpf_feature1 != 0) {
+	if (mpf->feature1 != 0) {
 		if (early) {
 			/*
 			 * local APIC has default address
@@ -621,49 +653,12 @@ static void __init __get_smp_config(unsi
 		}
 
 		printk(KERN_INFO "Default MP configuration #%d\n",
-		       mpf->mpf_feature1);
-		construct_default_ISA_mptable(mpf->mpf_feature1);
-
-	} else if (mpf->mpf_physptr) {
-
-		/*
-		 * Read the physical hardware table.  Anything here will
-		 * override the defaults.
-		 */
-		if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) {
-#ifdef CONFIG_X86_LOCAL_APIC
-			smp_found_config = 0;
-#endif
-			printk(KERN_ERR
-			       "BIOS bug, MP table errors detected!...\n");
-			printk(KERN_ERR "... disabling SMP support. "
-			       "(tell your hw vendor)\n");
-			return;
-		}
+		       mpf->feature1);
+		construct_default_ISA_mptable(mpf->feature1);
 
-		if (early)
+	} else if (mpf->physptr) {
+		if (check_physptr(mpf, early))
 			return;
-#ifdef CONFIG_X86_IO_APIC
-		/*
-		 * If there are no explicit MP IRQ entries, then we are
-		 * broken.  We set up most of the low 16 IO-APIC pins to
-		 * ISA defaults and hope it will work.
-		 */
-		if (!mp_irq_entries) {
-			struct mpc_bus bus;
-
-			printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
-			       "using default mptable. "
-			       "(tell your hw vendor)\n");
-
-			bus.type = MP_BUS;
-			bus.busid = 0;
-			memcpy(bus.bustype, "ISA   ", 6);
-			MP_bus_info(&bus);
-
-			construct_default_ioirq_mptable(0);
-		}
-#endif
 	} else
 		BUG();
 
@@ -684,54 +679,62 @@ void __init get_smp_config(void)
 	__get_smp_config(0);
 }
 
+static void __init smp_reserve_bootmem(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
+}
+
 static int __init smp_scan_config(unsigned long base, unsigned long length,
 				  unsigned reserve)
 {
 	unsigned int *bp = phys_to_virt(base);
-	struct intel_mp_floating *mpf;
+	struct mpf_intel *mpf;
 
 	apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n",
 			bp, length);
 	BUILD_BUG_ON(sizeof(*mpf) != 16);
 
 	while (length > 0) {
-		mpf = (struct intel_mp_floating *)bp;
+		mpf = (struct mpf_intel *)bp;
 		if ((*bp == SMP_MAGIC_IDENT) &&
-		    (mpf->mpf_length == 1) &&
+		    (mpf->length == 1) &&
 		    !mpf_checksum((unsigned char *)bp, 16) &&
-		    ((mpf->mpf_specification == 1)
-		     || (mpf->mpf_specification == 4))) {
+		    ((mpf->specification == 1)
+		     || (mpf->specification == 4))) {
 #ifdef CONFIG_X86_LOCAL_APIC
 			smp_found_config = 1;
 #endif
 			mpf_found = mpf;
 
-			printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
-			       mpf, virt_to_phys(mpf));
+			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), PAGE_SIZE,
-					BOOTMEM_DEFAULT);
-			if (mpf->mpf_physptr) {
-				unsigned long size = PAGE_SIZE;
-#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 mpg->mpf_physptr yields BUG()
-				 * in reserve_bootmem.
-				 */
-				unsigned long end = max_low_pfn * PAGE_SIZE;
-				if (mpf->mpf_physptr + size > end)
-					size = end - mpf->mpf_physptr;
-#endif
-				reserve_bootmem_generic(mpf->mpf_physptr, size,
+			reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
 						BOOTMEM_DEFAULT);
-			}
+			if (mpf->physptr)
+				smp_reserve_bootmem(mpf);
 
 			return 1;
 		}
@@ -809,15 +812,15 @@ static int  __init get_MP_intsrc_index(s
 	/* not legacy */
 
 	for (i = 0; i < mp_irq_entries; i++) {
-		if (mp_irqs[i].mp_irqtype != mp_INT)
+		if (mp_irqs[i].irqtype != mp_INT)
 			continue;
 
-		if (mp_irqs[i].mp_irqflag != 0x0f)
+		if (mp_irqs[i].irqflag != 0x0f)
 			continue;
 
-		if (mp_irqs[i].mp_srcbus != m->srcbus)
+		if (mp_irqs[i].srcbus != m->srcbus)
 			continue;
-		if (mp_irqs[i].mp_srcbusirq != m->srcbusirq)
+		if (mp_irqs[i].srcbusirq != m->srcbusirq)
 			continue;
 		if (irq_used[i]) {
 			/* already claimed */
@@ -834,7 +837,58 @@ static int  __init get_MP_intsrc_index(s
 #define SPARE_SLOT_NUM 20
 
 static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
-#endif
+
+static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
+{
+	int i;
+
+	apic_printk(APIC_VERBOSE, "OLD ");
+	print_MP_intsrc_info(m);
+
+	i = get_MP_intsrc_index(m);
+	if (i > 0) {
+		assign_to_mpc_intsrc(&mp_irqs[i], m);
+		apic_printk(APIC_VERBOSE, "NEW ");
+		print_mp_irq_info(&mp_irqs[i]);
+		return;
+	}
+	if (!i) {
+		/* legacy, do nothing */
+		return;
+	}
+	if (*nr_m_spare < SPARE_SLOT_NUM) {
+		/*
+		 * not found (-1), or duplicated (-2) are invalid entries,
+		 * we need to use the slot later
+		 */
+		m_spare[*nr_m_spare] = m;
+		*nr_m_spare += 1;
+	}
+}
+#else /* CONFIG_X86_IO_APIC */
+static
+inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
+#endif /* CONFIG_X86_IO_APIC */
+
+static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
+		      int count)
+{
+	if (!mpc_new_phys) {
+		pr_info("No spare slots, try to append...take your risk, "
+			"new mpc_length %x\n", count);
+	} else {
+		if (count <= mpc_new_length)
+			pr_info("No spare slots, try to append..., "
+				"new mpc_length %x\n", count);
+		else {
+			pr_err("mpc_new_length %lx is too small\n",
+				mpc_new_length);
+			return -1;
+		}
+	}
+
+	return 0;
+}
 
 static int  __init replace_intsrc_all(struct mpc_table *mpc,
 					unsigned long mpc_new_phys,
@@ -842,77 +896,33 @@ static int  __init replace_intsrc_all(st
 {
 #ifdef CONFIG_X86_IO_APIC
 	int i;
-	int nr_m_spare = 0;
 #endif
-
 	int count = sizeof(*mpc);
+	int nr_m_spare = 0;
 	unsigned char *mpt = ((unsigned char *)mpc) + count;
 
 	printk(KERN_INFO "mpc_length %x\n", mpc->length);
 	while (count < mpc->length) {
 		switch (*mpt) {
 		case MP_PROCESSOR:
-			{
-				struct mpc_cpu *m = (struct mpc_cpu *)mpt;
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
+			break;
 		case MP_BUS:
-			{
-				struct mpc_bus *m = (struct mpc_bus *)mpt;
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			skip_entry(&mpt, &count, sizeof(struct mpc_bus));
+			break;
 		case MP_IOAPIC:
-			{
-				mpt += sizeof(struct mpc_ioapic);
-				count += sizeof(struct mpc_ioapic);
-				break;
-			}
+			skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
+			break;
 		case MP_INTSRC:
-			{
-#ifdef CONFIG_X86_IO_APIC
-				struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
-
-				printk(KERN_INFO "OLD ");
-				print_MP_intsrc_info(m);
-				i = get_MP_intsrc_index(m);
-				if (i > 0) {
-					assign_to_mpc_intsrc(&mp_irqs[i], m);
-					printk(KERN_INFO "NEW ");
-					print_mp_irq_info(&mp_irqs[i]);
-				} else if (!i) {
-					/* legacy, do nothing */
-				} else if (nr_m_spare < SPARE_SLOT_NUM) {
-					/*
-					 * not found (-1), or duplicated (-2)
-					 * are invalid entries,
-					 * we need to use the slot  later
-					 */
-					m_spare[nr_m_spare] = m;
-					nr_m_spare++;
-				}
-#endif
-				mpt += sizeof(struct mpc_intsrc);
-				count += sizeof(struct mpc_intsrc);
-				break;
-			}
+			check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare);
+			skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
+			break;
 		case MP_LINTSRC:
-			{
-				struct mpc_lintsrc *m =
-				    (struct mpc_lintsrc *)mpt;
-				mpt += sizeof(*m);
-				count += sizeof(*m);
-				break;
-			}
+			skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
+			break;
 		default:
 			/* wrong mptable */
-			printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
-			printk(KERN_ERR "type %x\n", *mpt);
-			print_hex_dump(KERN_ERR, "  ", DUMP_PREFIX_ADDRESS, 16,
-					1, mpc, mpc->length, 1);
+			smp_dump_mptable(mpc, mpt);
 			goto out;
 		}
 	}
@@ -922,30 +932,22 @@ static int  __init replace_intsrc_all(st
 		if (irq_used[i])
 			continue;
 
-		if (mp_irqs[i].mp_irqtype != mp_INT)
+		if (mp_irqs[i].irqtype != mp_INT)
 			continue;
 
-		if (mp_irqs[i].mp_irqflag != 0x0f)
+		if (mp_irqs[i].irqflag != 0x0f)
 			continue;
 
 		if (nr_m_spare > 0) {
-			printk(KERN_INFO "*NEW* found ");
+			apic_printk(APIC_VERBOSE, "*NEW* found\n");
 			nr_m_spare--;
 			assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]);
 			m_spare[nr_m_spare] = NULL;
 		} else {
 			struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
 			count += sizeof(struct mpc_intsrc);
-			if (!mpc_new_phys) {
-				printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count);
-			} else {
-				if (count <= mpc_new_length)
-					printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count);
-				else {
-					printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length);
-					goto out;
-				}
-			}
+			if (!check_slot(mpc_new_phys, mpc_new_length, count))
+				goto out;
 			assign_to_mpc_intsrc(&mp_irqs[i], m);
 			mpc->length = count;
 			mpt += sizeof(struct mpc_intsrc);
@@ -1001,7 +1003,7 @@ static int __init update_mp_table(void)
 {
 	char str[16];
 	char oem[10];
-	struct intel_mp_floating *mpf;
+	struct mpf_intel *mpf;
 	struct mpc_table *mpc, *mpc_new;
 
 	if (!enable_update_mptable)
@@ -1014,19 +1016,19 @@ static int __init update_mp_table(void)
 	/*
 	 * Now see if we need to go further.
 	 */
-	if (mpf->mpf_feature1 != 0)
+	if (mpf->feature1 != 0)
 		return 0;
 
-	if (!mpf->mpf_physptr)
+	if (!mpf->physptr)
 		return 0;
 
-	mpc = phys_to_virt(mpf->mpf_physptr);
+	mpc = phys_to_virt(mpf->physptr);
 
 	if (!smp_check_mpc(mpc, oem, str))
 		return 0;
 
-	printk(KERN_INFO "mpf: %lx\n", virt_to_phys(mpf));
-	printk(KERN_INFO "mpf_physptr: %x\n", mpf->mpf_physptr);
+	printk(KERN_INFO "mpf: %llx\n", (u64)virt_to_phys(mpf));
+	printk(KERN_INFO "physptr: %x\n", mpf->physptr);
 
 	if (mpc_new_phys && mpc->length > mpc_new_length) {
 		mpc_new_phys = 0;
@@ -1047,23 +1049,23 @@ static int __init update_mp_table(void)
 		}
 		printk(KERN_INFO "use in-positon replacing\n");
 	} else {
-		mpf->mpf_physptr = mpc_new_phys;
+		mpf->physptr = mpc_new_phys;
 		mpc_new = phys_to_virt(mpc_new_phys);
 		memcpy(mpc_new, mpc, mpc->length);
 		mpc = mpc_new;
 		/* check if we can modify that */
-		if (mpc_new_phys - mpf->mpf_physptr) {
-			struct intel_mp_floating *mpf_new;
+		if (mpc_new_phys - mpf->physptr) {
+			struct mpf_intel *mpf_new;
 			/* steal 16 bytes from [0, 1k) */
 			printk(KERN_INFO "mpf new: %x\n", 0x400 - 16);
 			mpf_new = phys_to_virt(0x400 - 16);
 			memcpy(mpf_new, mpf, 16);
 			mpf = mpf_new;
-			mpf->mpf_physptr = mpc_new_phys;
+			mpf->physptr = mpc_new_phys;
 		}
-		mpf->mpf_checksum = 0;
-		mpf->mpf_checksum -= mpf_checksum((unsigned char *)mpf, 16);
-		printk(KERN_INFO "mpf_physptr new: %x\n", mpf->mpf_physptr);
+		mpf->checksum = 0;
+		mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
+		printk(KERN_INFO "physptr new: %x\n", mpf->physptr);
 	}
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/msr.c linux-libre-2.6.30-gnu1/arch/x86/kernel/msr.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/msr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/msr.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,10 +35,10 @@
 #include <linux/device.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
+#include <linux/uaccess.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
-#include <asm/uaccess.h>
 #include <asm/system.h>
 
 static struct class *msr_class;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/nmi.c linux-libre-2.6.30-gnu1/arch/x86/kernel/nmi.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/nmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/nmi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,572 +0,0 @@
-/*
- *  NMI watchdog support on APIC systems
- *
- *  Started by Ingo Molnar <mingo@redhat.com>
- *
- *  Fixes:
- *  Mikael Pettersson	: AMD K7 support for local APIC NMI watchdog.
- *  Mikael Pettersson	: Power Management for local APIC NMI watchdog.
- *  Mikael Pettersson	: Pentium 4 support for local APIC NMI watchdog.
- *  Pavel Machek and
- *  Mikael Pettersson	: PM converted to driver model. Disable/enable API.
- */
-
-#include <asm/apic.h>
-
-#include <linux/nmi.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/sysdev.h>
-#include <linux/sysctl.h>
-#include <linux/percpu.h>
-#include <linux/kprobes.h>
-#include <linux/cpumask.h>
-#include <linux/kernel_stat.h>
-#include <linux/kdebug.h>
-#include <linux/smp.h>
-
-#include <asm/i8259.h>
-#include <asm/io_apic.h>
-#include <asm/proto.h>
-#include <asm/timer.h>
-
-#include <asm/mce.h>
-
-#include <mach_traps.h>
-
-int unknown_nmi_panic;
-int nmi_watchdog_enabled;
-
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
-
-/* nmi_active:
- * >0: the lapic NMI watchdog is active, but can be disabled
- * <0: the lapic NMI watchdog has not been set up, and cannot
- *     be enabled
- *  0: the lapic NMI watchdog is disabled, but can be enabled
- */
-atomic_t nmi_active = ATOMIC_INIT(0);		/* oprofile uses this */
-EXPORT_SYMBOL(nmi_active);
-
-unsigned int nmi_watchdog = NMI_NONE;
-EXPORT_SYMBOL(nmi_watchdog);
-
-static int panic_on_timeout;
-
-static unsigned int nmi_hz = HZ;
-static DEFINE_PER_CPU(short, wd_enabled);
-static int endflag __initdata;
-
-static inline unsigned int get_nmi_count(int cpu)
-{
-#ifdef CONFIG_X86_64
-	return cpu_pda(cpu)->__nmi_count;
-#else
-	return nmi_count(cpu);
-#endif
-}
-
-static inline int mce_in_progress(void)
-{
-#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
-	return atomic_read(&mce_entry) > 0;
-#endif
-	return 0;
-}
-
-/*
- * Take the local apic timer and PIT/HPET into account. We don't
- * know which one is active, when we have highres/dyntick on
- */
-static inline unsigned int get_timer_irqs(int cpu)
-{
-#ifdef CONFIG_X86_64
-	return read_pda(apic_timer_irqs) + read_pda(irq0_irqs);
-#else
-	return per_cpu(irq_stat, cpu).apic_timer_irqs +
-		per_cpu(irq_stat, cpu).irq0_irqs;
-#endif
-}
-
-#ifdef CONFIG_SMP
-/*
- * The performance counters used by NMI_LOCAL_APIC don't trigger when
- * the CPU is idle. To make sure the NMI watchdog really ticks on all
- * CPUs during the test make them busy.
- */
-static __init void nmi_cpu_busy(void *data)
-{
-	local_irq_enable_in_hardirq();
-	/*
-	 * Intentionally don't use cpu_relax here. This is
-	 * to make sure that the performance counter really ticks,
-	 * even if there is a simulator or similar that catches the
-	 * pause instruction. On a real HT machine this is fine because
-	 * all other CPUs are busy with "useless" delay loops and don't
-	 * care if they get somewhat less cycles.
-	 */
-	while (endflag == 0)
-		mb();
-}
-#endif
-
-static void report_broken_nmi(int cpu, int *prev_nmi_count)
-{
-	printk(KERN_CONT "\n");
-
-	printk(KERN_WARNING
-		"WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
-			cpu, prev_nmi_count[cpu], get_nmi_count(cpu));
-
-	printk(KERN_WARNING
-		"Please report this to bugzilla.kernel.org,\n");
-	printk(KERN_WARNING
-		"and attach the output of the 'dmesg' command.\n");
-
-	per_cpu(wd_enabled, cpu) = 0;
-	atomic_dec(&nmi_active);
-}
-
-static void __acpi_nmi_disable(void *__unused)
-{
-	apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
-}
-
-int __init check_nmi_watchdog(void)
-{
-	unsigned int *prev_nmi_count;
-	int cpu;
-
-	if (!nmi_watchdog_active() || !atomic_read(&nmi_active))
-		return 0;
-
-	prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL);
-	if (!prev_nmi_count)
-		goto error;
-
-	printk(KERN_INFO "Testing NMI watchdog ... ");
-
-#ifdef CONFIG_SMP
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		smp_call_function(nmi_cpu_busy, (void *)&endflag, 0);
-#endif
-
-	for_each_possible_cpu(cpu)
-		prev_nmi_count[cpu] = get_nmi_count(cpu);
-	local_irq_enable();
-	mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
-
-	for_each_online_cpu(cpu) {
-		if (!per_cpu(wd_enabled, cpu))
-			continue;
-		if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
-			report_broken_nmi(cpu, prev_nmi_count);
-	}
-	endflag = 1;
-	if (!atomic_read(&nmi_active)) {
-		kfree(prev_nmi_count);
-		atomic_set(&nmi_active, -1);
-		goto error;
-	}
-	printk("OK.\n");
-
-	/*
-	 * now that we know it works we can reduce NMI frequency to
-	 * something more reasonable; makes a difference in some configs
-	 */
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		nmi_hz = lapic_adjust_nmi_hz(1);
-
-	kfree(prev_nmi_count);
-	return 0;
-error:
-	if (nmi_watchdog == NMI_IO_APIC) {
-		if (!timer_through_8259)
-			disable_8259A_irq(0);
-		on_each_cpu(__acpi_nmi_disable, NULL, 1);
-	}
-
-#ifdef CONFIG_X86_32
-	timer_ack = 0;
-#endif
-	return -1;
-}
-
-static int __init setup_nmi_watchdog(char *str)
-{
-	unsigned int nmi;
-
-	if (!strncmp(str, "panic", 5)) {
-		panic_on_timeout = 1;
-		str = strchr(str, ',');
-		if (!str)
-			return 1;
-		++str;
-	}
-
-	if (!strncmp(str, "lapic", 5))
-		nmi_watchdog = NMI_LOCAL_APIC;
-	else if (!strncmp(str, "ioapic", 6))
-		nmi_watchdog = NMI_IO_APIC;
-	else {
-		get_option(&str, &nmi);
-		if (nmi >= NMI_INVALID)
-			return 0;
-		nmi_watchdog = nmi;
-	}
-
-	return 1;
-}
-__setup("nmi_watchdog=", setup_nmi_watchdog);
-
-/*
- * Suspend/resume support
- */
-#ifdef CONFIG_PM
-
-static int nmi_pm_active; /* nmi_active before suspend */
-
-static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
-{
-	/* only CPU0 goes here, other CPUs should be offline */
-	nmi_pm_active = atomic_read(&nmi_active);
-	stop_apic_nmi_watchdog(NULL);
-	BUG_ON(atomic_read(&nmi_active) != 0);
-	return 0;
-}
-
-static int lapic_nmi_resume(struct sys_device *dev)
-{
-	/* only CPU0 goes here, other CPUs should be offline */
-	if (nmi_pm_active > 0) {
-		setup_apic_nmi_watchdog(NULL);
-		touch_nmi_watchdog();
-	}
-	return 0;
-}
-
-static struct sysdev_class nmi_sysclass = {
-	.name		= "lapic_nmi",
-	.resume		= lapic_nmi_resume,
-	.suspend	= lapic_nmi_suspend,
-};
-
-static struct sys_device device_lapic_nmi = {
-	.id	= 0,
-	.cls	= &nmi_sysclass,
-};
-
-static int __init init_lapic_nmi_sysfs(void)
-{
-	int error;
-
-	/*
-	 * should really be a BUG_ON but b/c this is an
-	 * init call, it just doesn't work.  -dcz
-	 */
-	if (nmi_watchdog != NMI_LOCAL_APIC)
-		return 0;
-
-	if (atomic_read(&nmi_active) < 0)
-		return 0;
-
-	error = sysdev_class_register(&nmi_sysclass);
-	if (!error)
-		error = sysdev_register(&device_lapic_nmi);
-	return error;
-}
-
-/* must come after the local APIC's device_initcall() */
-late_initcall(init_lapic_nmi_sysfs);
-
-#endif	/* CONFIG_PM */
-
-static void __acpi_nmi_enable(void *__unused)
-{
-	apic_write(APIC_LVT0, APIC_DM_NMI);
-}
-
-/*
- * Enable timer based NMIs on all CPUs:
- */
-void acpi_nmi_enable(void)
-{
-	if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
-		on_each_cpu(__acpi_nmi_enable, NULL, 1);
-}
-
-/*
- * Disable timer based NMIs on all CPUs:
- */
-void acpi_nmi_disable(void)
-{
-	if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC)
-		on_each_cpu(__acpi_nmi_disable, NULL, 1);
-}
-
-/*
- * This function is called as soon the LAPIC NMI watchdog driver has everything
- * in place and it's ready to check if the NMIs belong to the NMI watchdog
- */
-void cpu_nmi_set_wd_enabled(void)
-{
-	__get_cpu_var(wd_enabled) = 1;
-}
-
-void setup_apic_nmi_watchdog(void *unused)
-{
-	if (__get_cpu_var(wd_enabled))
-		return;
-
-	/* cheap hack to support suspend/resume */
-	/* if cpu0 is not active neither should the other cpus */
-	if (smp_processor_id() != 0 && atomic_read(&nmi_active) <= 0)
-		return;
-
-	switch (nmi_watchdog) {
-	case NMI_LOCAL_APIC:
-		if (lapic_watchdog_init(nmi_hz) < 0) {
-			__get_cpu_var(wd_enabled) = 0;
-			return;
-		}
-		/* FALL THROUGH */
-	case NMI_IO_APIC:
-		__get_cpu_var(wd_enabled) = 1;
-		atomic_inc(&nmi_active);
-	}
-}
-
-void stop_apic_nmi_watchdog(void *unused)
-{
-	/* only support LOCAL and IO APICs for now */
-	if (!nmi_watchdog_active())
-		return;
-	if (__get_cpu_var(wd_enabled) == 0)
-		return;
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		lapic_watchdog_stop();
-	else
-		__acpi_nmi_disable(NULL);
-	__get_cpu_var(wd_enabled) = 0;
-	atomic_dec(&nmi_active);
-}
-
-/*
- * the best way to detect whether a CPU has a 'hard lockup' problem
- * is to check it's local APIC timer IRQ counts. If they are not
- * changing then that CPU has some problem.
- *
- * as these watchdog NMI IRQs are generated on every CPU, we only
- * have to check the current processor.
- *
- * since NMIs don't listen to _any_ locks, we have to be extremely
- * careful not to rely on unsafe variables. The printk might lock
- * up though, so we have to break up any console locks first ...
- * [when there will be more tty-related locks, break them up here too!]
- */
-
-static DEFINE_PER_CPU(unsigned, last_irq_sum);
-static DEFINE_PER_CPU(local_t, alert_counter);
-static DEFINE_PER_CPU(int, nmi_touch);
-
-void touch_nmi_watchdog(void)
-{
-	if (nmi_watchdog_active()) {
-		unsigned cpu;
-
-		/*
-		 * Tell other CPUs to reset their alert counters. We cannot
-		 * do it ourselves because the alert count increase is not
-		 * atomic.
-		 */
-		for_each_present_cpu(cpu) {
-			if (per_cpu(nmi_touch, cpu) != 1)
-				per_cpu(nmi_touch, cpu) = 1;
-		}
-	}
-
-	/*
-	 * Tickle the softlockup detector too:
-	 */
-	touch_softlockup_watchdog();
-}
-EXPORT_SYMBOL(touch_nmi_watchdog);
-
-notrace __kprobes int
-nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
-{
-	/*
-	 * Since current_thread_info()-> is always on the stack, and we
-	 * always switch the stack NMI-atomically, it's safe to use
-	 * smp_processor_id().
-	 */
-	unsigned int sum;
-	int touched = 0;
-	int cpu = smp_processor_id();
-	int rc = 0;
-
-	/* check for other users first */
-	if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
-			== NOTIFY_STOP) {
-		rc = 1;
-		touched = 1;
-	}
-
-	sum = get_timer_irqs(cpu);
-
-	if (__get_cpu_var(nmi_touch)) {
-		__get_cpu_var(nmi_touch) = 0;
-		touched = 1;
-	}
-
-	if (cpu_isset(cpu, backtrace_mask)) {
-		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */
-
-		spin_lock(&lock);
-		printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
-		dump_stack();
-		spin_unlock(&lock);
-		cpu_clear(cpu, backtrace_mask);
-	}
-
-	/* Could check oops_in_progress here too, but it's safer not to */
-	if (mce_in_progress())
-		touched = 1;
-
-	/* if the none of the timers isn't firing, this cpu isn't doing much */
-	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
-		/*
-		 * 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)
-			/*
-			 * die_nmi will return ONLY if NOTIFY_STOP happens..
-			 */
-			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);
-	}
-
-	/* see if the nmi watchdog went off */
-	if (!__get_cpu_var(wd_enabled))
-		return rc;
-	switch (nmi_watchdog) {
-	case NMI_LOCAL_APIC:
-		rc |= lapic_wd_event(nmi_hz);
-		break;
-	case NMI_IO_APIC:
-		/*
-		 * don't know how to accurately check for this.
-		 * just assume it was a watchdog timer interrupt
-		 * This matches the old behaviour.
-		 */
-		rc = 1;
-		break;
-	}
-	return rc;
-}
-
-#ifdef CONFIG_SYSCTL
-
-static void enable_ioapic_nmi_watchdog_single(void *unused)
-{
-	__get_cpu_var(wd_enabled) = 1;
-	atomic_inc(&nmi_active);
-	__acpi_nmi_enable(NULL);
-}
-
-static void enable_ioapic_nmi_watchdog(void)
-{
-	on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 1);
-	touch_nmi_watchdog();
-}
-
-static void disable_ioapic_nmi_watchdog(void)
-{
-	on_each_cpu(stop_apic_nmi_watchdog, NULL, 1);
-}
-
-static int __init setup_unknown_nmi_panic(char *str)
-{
-	unknown_nmi_panic = 1;
-	return 1;
-}
-__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
-
-static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
-{
-	unsigned char reason = get_nmi_reason();
-	char buf[64];
-
-	sprintf(buf, "NMI received for unknown reason %02x\n", reason);
-	die_nmi(buf, regs, 1); /* Always panic here */
-	return 0;
-}
-
-/*
- * proc handler for /proc/sys/kernel/nmi
- */
-int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
-			void __user *buffer, size_t *length, loff_t *ppos)
-{
-	int old_state;
-
-	nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0;
-	old_state = nmi_watchdog_enabled;
-	proc_dointvec(table, write, file, buffer, length, ppos);
-	if (!!old_state == !!nmi_watchdog_enabled)
-		return 0;
-
-	if (atomic_read(&nmi_active) < 0 || !nmi_watchdog_active()) {
-		printk(KERN_WARNING
-			"NMI watchdog is permanently disabled\n");
-		return -EIO;
-	}
-
-	if (nmi_watchdog == NMI_LOCAL_APIC) {
-		if (nmi_watchdog_enabled)
-			enable_lapic_nmi_watchdog();
-		else
-			disable_lapic_nmi_watchdog();
-	} else if (nmi_watchdog == NMI_IO_APIC) {
-		if (nmi_watchdog_enabled)
-			enable_ioapic_nmi_watchdog();
-		else
-			disable_ioapic_nmi_watchdog();
-	} else {
-		printk(KERN_WARNING
-			"NMI watchdog doesn't know what hardware to touch\n");
-		return -EIO;
-	}
-	return 0;
-}
-
-#endif /* CONFIG_SYSCTL */
-
-int do_nmi_callback(struct pt_regs *regs, int cpu)
-{
-#ifdef CONFIG_SYSCTL
-	if (unknown_nmi_panic)
-		return unknown_nmi_panic_callback(regs, cpu);
-#endif
-	return 0;
-}
-
-void __trigger_all_cpu_backtrace(void)
-{
-	int i;
-
-	backtrace_mask = cpu_online_map;
-	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
-	for (i = 0; i < 10 * 1000; i++) {
-		if (cpus_empty(backtrace_mask))
-			break;
-		mdelay(1);
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/numaq_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/numaq_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/numaq_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/numaq_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,293 +0,0 @@
-/*
- * Written by: Patricia Gaughen, IBM Corporation
- *
- * Copyright (C) 2002, IBM Corp.
- *
- * All rights reserved.          
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gone@us.ibm.com>
- */
-
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/mmzone.h>
-#include <linux/module.h>
-#include <linux/nodemask.h>
-#include <asm/numaq.h>
-#include <asm/topology.h>
-#include <asm/processor.h>
-#include <asm/genapic.h>
-#include <asm/e820.h>
-#include <asm/setup.h>
-
-#define	MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
-
-/*
- * Function: smp_dump_qct()
- *
- * Description: gets memory layout from the quad config table.  This
- * function also updates node_online_map with the nodes (quads) present.
- */
-static void __init smp_dump_qct(void)
-{
-	int node;
-	struct eachquadmem *eq;
-	struct sys_cfg_data *scd =
-		(struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR);
-
-	nodes_clear(node_online_map);
-	for_each_node(node) {
-		if (scd->quads_present31_0 & (1 << node)) {
-			node_set_online(node);
-			eq = &scd->eq[node];
-			/* Convert to pages */
-			node_start_pfn[node] = MB_TO_PAGES(
-				eq->hi_shrd_mem_start - eq->priv_mem_size);
-			node_end_pfn[node] = MB_TO_PAGES(
-				eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
-
-			e820_register_active_regions(node, node_start_pfn[node],
-							node_end_pfn[node]);
-			memory_present(node,
-				node_start_pfn[node], node_end_pfn[node]);
-			node_remap_size[node] = node_memmap_size_bytes(node,
-							node_start_pfn[node],
-							node_end_pfn[node]);
-		}
-	}
-}
-
-
-void __cpuinit numaq_tsc_disable(void)
-{
-	if (!found_numaq)
-		return;
-
-	if (num_online_nodes() > 1) {
-		printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
-		setup_clear_cpu_cap(X86_FEATURE_TSC);
-	}
-}
-
-static int __init numaq_pre_time_init(void)
-{
-	numaq_tsc_disable();
-	return 0;
-}
-
-int found_numaq;
-/*
- * Have to match translation table entries to main table entries by counter
- * hence the mpc_record variable .... can't see a less disgusting way of
- * doing this ....
- */
-struct mpc_config_translation {
-	unsigned char mpc_type;
-	unsigned char trans_len;
-	unsigned char trans_type;
-	unsigned char trans_quad;
-	unsigned char trans_global;
-	unsigned char trans_local;
-	unsigned short trans_reserved;
-};
-
-/* x86_quirks member */
-static int mpc_record;
-static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
-    __cpuinitdata;
-
-static inline int generate_logical_apicid(int quad, int phys_apicid)
-{
-	return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
-}
-
-/* x86_quirks member */
-static int mpc_apic_id(struct mpc_cpu *m)
-{
-	int quad = translation_table[mpc_record]->trans_quad;
-	int logical_apicid = generate_logical_apicid(quad, m->apicid);
-
-	printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
-	       m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
-	       (m->cpufeature & CPU_MODEL_MASK) >> 4,
-	       m->apicver, quad, logical_apicid);
-	return logical_apicid;
-}
-
-int mp_bus_id_to_node[MAX_MP_BUSSES];
-
-int mp_bus_id_to_local[MAX_MP_BUSSES];
-
-/* x86_quirks member */
-static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
-{
-	int quad = translation_table[mpc_record]->trans_quad;
-	int local = translation_table[mpc_record]->trans_local;
-
-	mp_bus_id_to_node[m->busid] = quad;
-	mp_bus_id_to_local[m->busid] = local;
-	printk(KERN_INFO "Bus #%d is %s (node %d)\n",
-	       m->busid, name, quad);
-}
-
-int quad_local_to_mp_bus_id [NR_CPUS/4][4];
-
-/* x86_quirks member */
-static void mpc_oem_pci_bus(struct mpc_bus *m)
-{
-	int quad = translation_table[mpc_record]->trans_quad;
-	int local = translation_table[mpc_record]->trans_local;
-
-	quad_local_to_mp_bus_id[quad][local] = m->busid;
-}
-
-static void __init MP_translation_info(struct mpc_config_translation *m)
-{
-	printk(KERN_INFO
-	       "Translation: record %d, type %d, quad %d, global %d, local %d\n",
-	       mpc_record, m->trans_type, m->trans_quad, m->trans_global,
-	       m->trans_local);
-
-	if (mpc_record >= MAX_MPC_ENTRY)
-		printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
-	else
-		translation_table[mpc_record] = m;	/* stash this for later */
-	if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
-		node_set_online(m->trans_quad);
-}
-
-static int __init mpf_checksum(unsigned char *mp, int len)
-{
-	int sum = 0;
-
-	while (len--)
-		sum += *mp++;
-
-	return sum & 0xFF;
-}
-
-/*
- * Read/parse the MPC oem tables
- */
-
-static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable,
-				    unsigned short oemsize)
-{
-	int count = sizeof(*oemtable);	/* the header size */
-	unsigned char *oemptr = ((unsigned char *)oemtable) + count;
-
-	mpc_record = 0;
-	printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n",
-	       oemtable);
-	if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
-		printk(KERN_WARNING
-		       "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
-		       oemtable->signature[0], oemtable->signature[1],
-		       oemtable->signature[2], oemtable->signature[3]);
-		return;
-	}
-	if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
-		printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
-		return;
-	}
-	while (count < oemtable->length) {
-		switch (*oemptr) {
-		case MP_TRANSLATION:
-			{
-				struct mpc_config_translation *m =
-				    (struct mpc_config_translation *)oemptr;
-				MP_translation_info(m);
-				oemptr += sizeof(*m);
-				count += sizeof(*m);
-				++mpc_record;
-				break;
-			}
-		default:
-			{
-				printk(KERN_WARNING
-				       "Unrecognised OEM table entry type! - %d\n",
-				       (int)*oemptr);
-				return;
-			}
-		}
-	}
-}
-
-static int __init numaq_setup_ioapic_ids(void)
-{
-	/* so can skip it */
-	return 1;
-}
-
-static int __init numaq_update_genapic(void)
-{
-	genapic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
-
-	return 0;
-}
-
-static struct x86_quirks numaq_x86_quirks __initdata = {
-	.arch_pre_time_init	= numaq_pre_time_init,
-	.arch_time_init		= NULL,
-	.arch_pre_intr_init	= NULL,
-	.arch_memory_setup	= NULL,
-	.arch_intr_init		= NULL,
-	.arch_trap_init		= NULL,
-	.mach_get_smp_config	= NULL,
-	.mach_find_smp_config	= NULL,
-	.mpc_record		= &mpc_record,
-	.mpc_apic_id		= mpc_apic_id,
-	.mpc_oem_bus_info	= mpc_oem_bus_info,
-	.mpc_oem_pci_bus	= mpc_oem_pci_bus,
-	.smp_read_mpc_oem	= smp_read_mpc_oem,
-	.setup_ioapic_ids	= numaq_setup_ioapic_ids,
-	.update_genapic		= numaq_update_genapic,
-};
-
-void numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-	if (strncmp(oem, "IBM NUMA", 8))
-		printk("Warning!  Not a NUMA-Q system!\n");
-	else
-		found_numaq = 1;
-}
-
-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)
-		early_get_smp_config();
-
-	if (found_numaq)
-		x86_quirks = &numaq_x86_quirks;
-}
-
-int __init get_memcfg_numaq(void)
-{
-	early_check_numaq();
-	if (!found_numaq)
-		return 0;
-	smp_dump_qct();
-	return 1;
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt.c linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <asm/paravirt.h>
 #include <asm/desc.h>
 #include <asm/setup.h>
-#include <asm/arch_hooks.h>
 #include <asm/pgtable.h>
 #include <asm/time.h>
 #include <asm/pgalloc.h>
@@ -44,6 +43,17 @@ void _paravirt_nop(void)
 {
 }
 
+/* identity function, which can be inlined */
+u32 _paravirt_ident_32(u32 x)
+{
+	return x;
+}
+
+u64 _paravirt_ident_64(u64 x)
+{
+	return x;
+}
+
 static void __init default_banner(void)
 {
 	printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
@@ -124,7 +134,9 @@ static void *get_call_destination(u8 typ
 		.pv_irq_ops = pv_irq_ops,
 		.pv_apic_ops = pv_apic_ops,
 		.pv_mmu_ops = pv_mmu_ops,
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
 		.pv_lock_ops = pv_lock_ops,
+#endif
 	};
 	return *((void **)&tmpl + type);
 }
@@ -138,9 +150,16 @@ unsigned paravirt_patch_default(u8 type,
 	if (opfunc == NULL)
 		/* If there's no function, patch it with a ud2a (BUG) */
 		ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
-	else if (opfunc == paravirt_nop)
+	else if (opfunc == _paravirt_nop)
 		/* If the operation is a nop, then nop the callsite */
 		ret = paravirt_patch_nop();
+
+	/* identity functions just return their single argument */
+	else if (opfunc == _paravirt_ident_32)
+		ret = paravirt_patch_ident_32(insnbuf, len);
+	else if (opfunc == _paravirt_ident_64)
+		ret = paravirt_patch_ident_64(insnbuf, len);
+
 	else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
 		 type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) ||
 		 type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) ||
@@ -318,10 +337,10 @@ struct pv_time_ops pv_time_ops = {
 
 struct pv_irq_ops pv_irq_ops = {
 	.init_IRQ = native_init_IRQ,
-	.save_fl = native_save_fl,
-	.restore_fl = native_restore_fl,
-	.irq_disable = native_irq_disable,
-	.irq_enable = native_irq_enable,
+	.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
+	.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
+	.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
+	.irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable),
 	.safe_halt = native_safe_halt,
 	.halt = native_halt,
 #ifdef CONFIG_X86_64
@@ -399,6 +418,14 @@ struct pv_apic_ops pv_apic_ops = {
 #endif
 };
 
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
+/* 32-bit pagetable entries */
+#define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_32)
+#else
+/* 64-bit pagetable entries */
+#define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_64)
+#endif
+
 struct pv_mmu_ops pv_mmu_ops = {
 #ifndef CONFIG_X86_64
 	.pagetable_setup_start = native_pagetable_setup_start,
@@ -445,27 +472,27 @@ struct pv_mmu_ops pv_mmu_ops = {
 #if PAGETABLE_LEVELS >= 3
 #ifdef CONFIG_X86_PAE
 	.set_pte_atomic = native_set_pte_atomic,
-	.set_pte_present = native_set_pte_present,
 	.pte_clear = native_pte_clear,
 	.pmd_clear = native_pmd_clear,
 #endif
 	.set_pud = native_set_pud,
-	.pmd_val = native_pmd_val,
-	.make_pmd = native_make_pmd,
+
+	.pmd_val = PTE_IDENT,
+	.make_pmd = PTE_IDENT,
 
 #if PAGETABLE_LEVELS == 4
-	.pud_val = native_pud_val,
-	.make_pud = native_make_pud,
+	.pud_val = PTE_IDENT,
+	.make_pud = PTE_IDENT,
+
 	.set_pgd = native_set_pgd,
 #endif
 #endif /* PAGETABLE_LEVELS >= 3 */
 
-	.pte_val = native_pte_val,
-	.pte_flags = native_pte_flags,
-	.pgd_val = native_pgd_val,
+	.pte_val = PTE_IDENT,
+	.pgd_val = PTE_IDENT,
 
-	.make_pte = native_make_pte,
-	.make_pgd = native_make_pgd,
+	.make_pte = PTE_IDENT,
+	.make_pgd = PTE_IDENT,
 
 	.dup_mmap = paravirt_nop,
 	.exit_mmap = paravirt_nop,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt_patch_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt_patch_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt_patch_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt_patch_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,18 @@ DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %c
 DEF_NATIVE(pv_cpu_ops, clts, "clts");
 DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
 
+unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len)
+{
+	/* arg in %eax, return in %eax */
+	return 0;
+}
+
+unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
+{
+	/* arg in %edx:%eax, return in %edx:%eax */
+	return 0;
+}
+
 unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
 		      unsigned long addr, unsigned len)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt_patch_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt_patch_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt_patch_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt_patch_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,21 @@ DEF_NATIVE(pv_cpu_ops, usergs_sysret64,
 DEF_NATIVE(pv_cpu_ops, usergs_sysret32, "swapgs; sysretl");
 DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs");
 
+DEF_NATIVE(, mov32, "mov %edi, %eax");
+DEF_NATIVE(, mov64, "mov %rdi, %rax");
+
+unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len)
+{
+	return paravirt_patch_insns(insnbuf, len,
+				    start__mov32, end__mov32);
+}
+
+unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
+{
+	return paravirt_patch_insns(insnbuf, len,
+				    start__mov64, end__mov64);
+}
+
 unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
 		      unsigned long addr, unsigned len)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt-spinlocks.c linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt-spinlocks.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/paravirt-spinlocks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/paravirt-spinlocks.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,13 +26,3 @@ struct pv_lock_ops pv_lock_ops = {
 };
 EXPORT_SYMBOL(pv_lock_ops);
 
-void __init paravirt_use_bytelocks(void)
-{
-#ifdef CONFIG_SMP
-	pv_lock_ops.spin_is_locked = __byte_spin_is_locked;
-	pv_lock_ops.spin_is_contended = __byte_spin_is_contended;
-	pv_lock_ops.spin_lock = __byte_spin_lock;
-	pv_lock_ops.spin_trylock = __byte_spin_trylock;
-	pv_lock_ops.spin_unlock = __byte_spin_unlock;
-#endif
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-calgary_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-calgary_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-calgary_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-calgary_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -380,8 +380,9 @@ static inline struct iommu_table *find_i
 	return tbl;
 }
 
-static void calgary_unmap_sg(struct device *dev,
-	struct scatterlist *sglist, int nelems, int direction)
+static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist,
+			     int nelems,enum dma_data_direction dir,
+			     struct dma_attrs *attrs)
 {
 	struct iommu_table *tbl = find_iommu_table(dev);
 	struct scatterlist *s;
@@ -404,7 +405,8 @@ static void calgary_unmap_sg(struct devi
 }
 
 static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
-	int nelems, int direction)
+			  int nelems, enum dma_data_direction dir,
+			  struct dma_attrs *attrs)
 {
 	struct iommu_table *tbl = find_iommu_table(dev);
 	struct scatterlist *s;
@@ -429,15 +431,14 @@ static int calgary_map_sg(struct device
 		s->dma_address = (entry << PAGE_SHIFT) | s->offset;
 
 		/* insert into HW table */
-		tce_build(tbl, entry, npages, vaddr & PAGE_MASK,
-			  direction);
+		tce_build(tbl, entry, npages, vaddr & PAGE_MASK, dir);
 
 		s->dma_length = s->length;
 	}
 
 	return nelems;
 error:
-	calgary_unmap_sg(dev, sg, nelems, direction);
+	calgary_unmap_sg(dev, sg, nelems, dir, NULL);
 	for_each_sg(sg, s, nelems, i) {
 		sg->dma_address = bad_dma_address;
 		sg->dma_length = 0;
@@ -445,10 +446,12 @@ error:
 	return 0;
 }
 
-static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
-	size_t size, int direction)
+static dma_addr_t calgary_map_page(struct device *dev, struct page *page,
+				   unsigned long offset, size_t size,
+				   enum dma_data_direction dir,
+				   struct dma_attrs *attrs)
 {
-	void *vaddr = phys_to_virt(paddr);
+	void *vaddr = page_address(page) + offset;
 	unsigned long uaddr;
 	unsigned int npages;
 	struct iommu_table *tbl = find_iommu_table(dev);
@@ -456,17 +459,18 @@ static dma_addr_t calgary_map_single(str
 	uaddr = (unsigned long)vaddr;
 	npages = iommu_num_pages(uaddr, size, PAGE_SIZE);
 
-	return iommu_alloc(dev, tbl, vaddr, npages, direction);
+	return iommu_alloc(dev, tbl, vaddr, npages, dir);
 }
 
-static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
-	size_t size, int direction)
+static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr,
+			       size_t size, enum dma_data_direction dir,
+			       struct dma_attrs *attrs)
 {
 	struct iommu_table *tbl = find_iommu_table(dev);
 	unsigned int npages;
 
-	npages = iommu_num_pages(dma_handle, size, PAGE_SIZE);
-	iommu_free(tbl, dma_handle, npages);
+	npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
+	iommu_free(tbl, dma_addr, npages);
 }
 
 static void* calgary_alloc_coherent(struct device *dev, size_t size,
@@ -515,13 +519,13 @@ static void calgary_free_coherent(struct
 	free_pages((unsigned long)vaddr, get_order(size));
 }
 
-static struct dma_mapping_ops calgary_dma_ops = {
+static struct dma_map_ops calgary_dma_ops = {
 	.alloc_coherent = calgary_alloc_coherent,
 	.free_coherent = calgary_free_coherent,
-	.map_single = calgary_map_single,
-	.unmap_single = calgary_unmap_single,
 	.map_sg = calgary_map_sg,
 	.unmap_sg = calgary_unmap_sg,
+	.map_page = calgary_map_page,
+	.unmap_page = calgary_unmap_page,
 };
 
 static inline void __iomem * busno_to_bbar(unsigned char num)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-dma.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-dma.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,5 @@
 #include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
 #include <linux/dmar.h>
 #include <linux/bootmem.h>
 #include <linux/pci.h>
@@ -12,7 +13,7 @@
 
 static int forbid_dac __read_mostly;
 
-struct dma_mapping_ops *dma_ops;
+struct dma_map_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
 static int iommu_sac_force __read_mostly;
@@ -39,11 +40,14 @@ EXPORT_SYMBOL(bad_dma_address);
    to older i386. */
 struct device x86_dma_fallback_dev = {
 	.init_name = "fallback device",
-	.coherent_dma_mask = DMA_32BIT_MASK,
+	.coherent_dma_mask = DMA_BIT_MASK(32),
 	.dma_mask = &x86_dma_fallback_dev.coherent_dma_mask,
 };
 EXPORT_SYMBOL(x86_dma_fallback_dev);
 
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES       32768
+
 int dma_set_mask(struct device *dev, u64 mask)
 {
 	if (!dev->dma_mask || !dma_supported(dev, mask))
@@ -144,7 +148,7 @@ again:
 	if (!is_buffer_dma_capable(dma_mask, addr, size)) {
 		__free_pages(page, get_order(size));
 
-		if (dma_mask < DMA_32BIT_MASK && !(flag & GFP_DMA)) {
+		if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
 			flag = (flag & ~GFP_DMA32) | GFP_DMA;
 			goto again;
 		}
@@ -224,7 +228,7 @@ early_param("iommu", iommu_setup);
 
 int dma_supported(struct device *dev, u64 mask)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+	struct dma_map_ops *ops = get_dma_ops(dev);
 
 #ifdef CONFIG_PCI
 	if (mask > 0xffffffff && forbid_dac > 0) {
@@ -239,7 +243,7 @@ int dma_supported(struct device *dev, u6
 	/* Copied from i386. Doesn't make much sense, because it will
 	   only work for pci_alloc_coherent.
 	   The caller just has to use GFP_DMA in this case. */
-	if (mask < DMA_24BIT_MASK)
+	if (mask < DMA_BIT_MASK(24))
 		return 0;
 
 	/* Tell the device to use SAC when IOMMU force is on.  This
@@ -254,7 +258,7 @@ int dma_supported(struct device *dev, u6
 	   SAC for these.  Assume all masks <= 40 bits are of this
 	   type. Normally this doesn't make any difference, but gives
 	   more gentle handling of IOMMU overflow. */
-	if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
+	if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) {
 		dev_info(dev, "Force SAC with mask %Lx\n", mask);
 		return 0;
 	}
@@ -265,6 +269,12 @@ EXPORT_SYMBOL(dma_supported);
 
 static int __init pci_iommu_init(void)
 {
+	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+#ifdef CONFIG_PCI
+	dma_debug_add_bus(&pci_bus_type);
+#endif
+
 	calgary_iommu_init();
 
 	intel_iommu_init();
@@ -290,8 +300,7 @@ fs_initcall(pci_iommu_init);
 static __devinit void via_no_dac(struct pci_dev *dev)
 {
 	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
-		printk(KERN_INFO
-			"PCI: VIA PCI bridge detected. Disabling DAC.\n");
+		dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");
 		forbid_dac = 1;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-gart_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-gart_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-gart_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-gart_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -255,10 +255,13 @@ static dma_addr_t dma_map_area(struct de
 }
 
 /* Map a single area into the IOMMU */
-static dma_addr_t
-gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
+static dma_addr_t gart_map_page(struct device *dev, struct page *page,
+				unsigned long offset, size_t size,
+				enum dma_data_direction dir,
+				struct dma_attrs *attrs)
 {
 	unsigned long bus;
+	phys_addr_t paddr = page_to_phys(page) + offset;
 
 	if (!dev)
 		dev = &x86_dma_fallback_dev;
@@ -275,8 +278,9 @@ gart_map_single(struct device *dev, phys
 /*
  * Free a DMA mapping.
  */
-static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
-			      size_t size, int direction)
+static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr,
+			    size_t size, enum dma_data_direction dir,
+			    struct dma_attrs *attrs)
 {
 	unsigned long iommu_page;
 	int npages;
@@ -298,8 +302,8 @@ static void gart_unmap_single(struct dev
 /*
  * Wrapper for pci_unmap_single working with scatterlists.
  */
-static void
-gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+			  enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	struct scatterlist *s;
 	int i;
@@ -307,7 +311,7 @@ gart_unmap_sg(struct device *dev, struct
 	for_each_sg(sg, s, nents, i) {
 		if (!s->dma_length || !s->length)
 			break;
-		gart_unmap_single(dev, s->dma_address, s->dma_length, dir);
+		gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL);
 	}
 }
 
@@ -329,7 +333,7 @@ static int dma_map_sg_nonforce(struct de
 			addr = dma_map_area(dev, addr, s->length, dir, 0);
 			if (addr == bad_dma_address) {
 				if (i > 0)
-					gart_unmap_sg(dev, sg, i, dir);
+					gart_unmap_sg(dev, sg, i, dir, NULL);
 				nents = 0;
 				sg[0].dma_length = 0;
 				break;
@@ -400,8 +404,8 @@ dma_map_cont(struct device *dev, struct
  * DMA map all entries in a scatterlist.
  * Merge chunks that have page aligned sizes into a continuous mapping.
  */
-static int
-gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		       enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	struct scatterlist *s, *ps, *start_sg, *sgmap;
 	int need = 0, nextneed, i, out, start;
@@ -468,7 +472,7 @@ gart_map_sg(struct device *dev, struct s
 
 error:
 	flush_gart();
-	gart_unmap_sg(dev, sg, out, dir);
+	gart_unmap_sg(dev, sg, out, dir, NULL);
 
 	/* When it was forced or merged try again in a dumb way */
 	if (force_iommu || iommu_merge) {
@@ -521,7 +525,7 @@ static void
 gart_free_coherent(struct device *dev, size_t size, void *vaddr,
 		   dma_addr_t dma_addr)
 {
-	gart_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL);
+	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
 	free_pages((unsigned long)vaddr, get_order(size));
 }
 
@@ -707,11 +711,11 @@ static __init int init_k8_gatt(struct ag
 	return -1;
 }
 
-static struct dma_mapping_ops gart_dma_ops = {
-	.map_single			= gart_map_single,
-	.unmap_single			= gart_unmap_single,
+static struct dma_map_ops gart_dma_ops = {
 	.map_sg				= gart_map_sg,
 	.unmap_sg			= gart_unmap_sg,
+	.map_page			= gart_map_page,
+	.unmap_page			= gart_unmap_page,
 	.alloc_coherent			= gart_alloc_coherent,
 	.free_coherent			= gart_free_coherent,
 };
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-nommu.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-nommu.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-nommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-nommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,21 +1,21 @@
 /* Fallback functions when the main IOMMU code is not compiled in. This
    code is roughly equivalent to i386. */
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/string.h>
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
 
-#include <asm/iommu.h>
 #include <asm/processor.h>
+#include <asm/iommu.h>
 #include <asm/dma.h>
 
 static int
 check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
 {
 	if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) {
-		if (*hwdev->dma_mask >= DMA_32BIT_MASK)
+		if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
 			printk(KERN_ERR
 			    "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
 				name, (long long)bus, size,
@@ -25,19 +25,19 @@ check_addr(char *name, struct device *hw
 	return 1;
 }
 
-static dma_addr_t
-nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size,
-	       int direction)
+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 bus = paddr;
+	dma_addr_t bus = page_to_phys(page) + offset;
 	WARN_ON(size == 0);
-	if (!check_addr("map_single", hwdev, bus, size))
-				return bad_dma_address;
+	if (!check_addr("map_single", dev, bus, size))
+		return bad_dma_address;
 	flush_write_buffers();
 	return bus;
 }
 
-
 /* Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scatter-gather version of the
  * above pci_map_single interface.  Here the scatter gather list
@@ -54,7 +54,8 @@ nommu_map_single(struct device *hwdev, p
  * the same here.
  */
 static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
-	       int nents, int direction)
+			int nents, enum dma_data_direction dir,
+			struct dma_attrs *attrs)
 {
 	struct scatterlist *s;
 	int i;
@@ -78,12 +79,12 @@ static void nommu_free_coherent(struct d
 	free_pages((unsigned long)vaddr, get_order(size));
 }
 
-struct dma_mapping_ops nommu_dma_ops = {
-	.alloc_coherent = dma_generic_alloc_coherent,
-	.free_coherent = nommu_free_coherent,
-	.map_single = nommu_map_single,
-	.map_sg = nommu_map_sg,
-	.is_phys = 1,
+struct dma_map_ops nommu_dma_ops = {
+	.alloc_coherent	= dma_generic_alloc_coherent,
+	.free_coherent	= nommu_free_coherent,
+	.map_sg		= nommu_map_sg,
+	.map_page	= nommu_map_page,
+	.is_phys	= 1,
 };
 
 void __init no_iommu_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-swiotlb_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-swiotlb_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-swiotlb_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-swiotlb_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,91 +0,0 @@
-/* Glue code to lib/swiotlb.c */
-
-#include <linux/pci.h>
-#include <linux/cache.h>
-#include <linux/module.h>
-#include <linux/swiotlb.h>
-#include <linux/bootmem.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/iommu.h>
-#include <asm/swiotlb.h>
-#include <asm/dma.h>
-
-int swiotlb __read_mostly;
-
-void * __init swiotlb_alloc_boot(size_t size, unsigned long nslabs)
-{
-	return alloc_bootmem_low_pages(size);
-}
-
-void *swiotlb_alloc(unsigned order, unsigned long nslabs)
-{
-	return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order);
-}
-
-dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
-{
-	return paddr;
-}
-
-phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr)
-{
-	return baddr;
-}
-
-int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size)
-{
-	return 0;
-}
-
-static dma_addr_t
-swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size,
-			int direction)
-{
-	return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction);
-}
-
-static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-					dma_addr_t *dma_handle, gfp_t flags)
-{
-	void *vaddr;
-
-	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags);
-	if (vaddr)
-		return vaddr;
-
-	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
-}
-
-struct dma_mapping_ops swiotlb_dma_ops = {
-	.mapping_error = swiotlb_dma_mapping_error,
-	.alloc_coherent = x86_swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
-	.map_single = swiotlb_map_single_phys,
-	.unmap_single = swiotlb_unmap_single,
-	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
-	.sync_single_for_device = swiotlb_sync_single_for_device,
-	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
-	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
-	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-	.sync_sg_for_device = swiotlb_sync_sg_for_device,
-	.map_sg = swiotlb_map_sg,
-	.unmap_sg = swiotlb_unmap_sg,
-	.dma_supported = NULL,
-};
-
-void __init pci_swiotlb_init(void)
-{
-	/* don't initialize swiotlb if iommu=off (no_iommu=1) */
-#ifdef CONFIG_X86_64
-	if (!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN)
-	       swiotlb = 1;
-#endif
-	if (swiotlb_force)
-		swiotlb = 1;
-	if (swiotlb) {
-		printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
-		swiotlb_init();
-		dma_ops = &swiotlb_dma_ops;
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-swiotlb.c linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-swiotlb.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/pci-swiotlb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-swiotlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,84 @@
+/* Glue code to lib/swiotlb.c */
+
+#include <linux/pci.h>
+#include <linux/cache.h>
+#include <linux/module.h>
+#include <linux/swiotlb.h>
+#include <linux/bootmem.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/iommu.h>
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+
+int swiotlb __read_mostly;
+
+void * __init swiotlb_alloc_boot(size_t size, unsigned long nslabs)
+{
+	return alloc_bootmem_low_pages(size);
+}
+
+void *swiotlb_alloc(unsigned order, unsigned long nslabs)
+{
+	return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order);
+}
+
+dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
+{
+	return paddr;
+}
+
+phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr)
+{
+	return baddr;
+}
+
+int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size)
+{
+	return 0;
+}
+
+static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+					dma_addr_t *dma_handle, gfp_t flags)
+{
+	void *vaddr;
+
+	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags);
+	if (vaddr)
+		return vaddr;
+
+	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
+}
+
+static struct dma_map_ops swiotlb_dma_ops = {
+	.mapping_error = swiotlb_dma_mapping_error,
+	.alloc_coherent = x86_swiotlb_alloc_coherent,
+	.free_coherent = swiotlb_free_coherent,
+	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+	.sync_single_for_device = swiotlb_sync_single_for_device,
+	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+	.sync_sg_for_device = swiotlb_sync_sg_for_device,
+	.map_sg = swiotlb_map_sg_attrs,
+	.unmap_sg = swiotlb_unmap_sg_attrs,
+	.map_page = swiotlb_map_page,
+	.unmap_page = swiotlb_unmap_page,
+	.dma_supported = NULL,
+};
+
+void __init pci_swiotlb_init(void)
+{
+	/* don't initialize swiotlb if iommu=off (no_iommu=1) */
+#ifdef CONFIG_X86_64
+	if (!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN)
+	       swiotlb = 1;
+#endif
+	if (swiotlb_force)
+		swiotlb = 1;
+	if (swiotlb) {
+		printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
+		swiotlb_init();
+		dma_ops = &swiotlb_dma_ops;
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/probe_roms_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/probe_roms_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/probe_roms_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/probe_roms_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/io.h>
-#include <setup_arch.h>
+#include <asm/setup_arch.h>
 
 static struct resource system_rom_resource = {
 	.name	= "System ROM",
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/process_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/process_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/process_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/process_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <stdarg.h>
 
+#include <linux/stackprotector.h>
 #include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -66,9 +67,6 @@ asmlinkage void ret_from_fork(void) __as
 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
 EXPORT_PER_CPU_SYMBOL(current_task);
 
-DEFINE_PER_CPU(int, cpu_number);
-EXPORT_PER_CPU_SYMBOL(cpu_number);
-
 /*
  * Return saved PC of a blocked thread.
  */
@@ -94,6 +92,15 @@ void cpu_idle(void)
 {
 	int cpu = smp_processor_id();
 
+	/*
+	 * If we're the non-boot CPU, nothing set the stack canary up
+	 * for us.  CPU0 already has it initialized but no harm in
+	 * doing it again.  This is a good place for updating it, as
+	 * we wont ever return from this function (so the invalid
+	 * canaries already on the stack wont ever trigger).
+	 */
+	boot_init_stack_canary();
+
 	current_thread_info()->status |= TS_POLLING;
 
 	/* endless idle loop with no priority at all */
@@ -108,7 +115,6 @@ void cpu_idle(void)
 				play_dead();
 
 			local_irq_disable();
-			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
 			/* Don't trace irqs off for idle */
 			stop_critical_timings();
 			pm_idle();
@@ -132,7 +138,7 @@ void __show_regs(struct pt_regs *regs, i
 	if (user_mode_vm(regs)) {
 		sp = regs->sp;
 		ss = regs->ss & 0xffff;
-		savesegment(gs, gs);
+		gs = get_user_gs(regs);
 	} else {
 		sp = (unsigned long) (&regs->sp);
 		savesegment(ss, ss);
@@ -213,6 +219,7 @@ int kernel_thread(int (*fn)(void *), voi
 	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();
@@ -223,55 +230,6 @@ int kernel_thread(int (*fn)(void *), voi
 }
 EXPORT_SYMBOL(kernel_thread);
 
-/*
- * Free current thread data structures etc..
- */
-void exit_thread(void)
-{
-	/* The process may have allocated an io port bitmap... nuke it. */
-	if (unlikely(test_thread_flag(TIF_IO_BITMAP))) {
-		struct task_struct *tsk = current;
-		struct thread_struct *t = &tsk->thread;
-		int cpu = get_cpu();
-		struct tss_struct *tss = &per_cpu(init_tss, cpu);
-
-		kfree(t->io_bitmap_ptr);
-		t->io_bitmap_ptr = NULL;
-		clear_thread_flag(TIF_IO_BITMAP);
-		/*
-		 * Careful, clear this in the TSS too:
-		 */
-		memset(tss->io_bitmap, 0xff, tss->io_bitmap_max);
-		t->io_bitmap_max = 0;
-		tss->io_bitmap_owner = NULL;
-		tss->io_bitmap_max = 0;
-		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
-		put_cpu();
-	}
-
-	ds_exit_thread(current);
-}
-
-void flush_thread(void)
-{
-	struct task_struct *tsk = current;
-
-	tsk->thread.debugreg0 = 0;
-	tsk->thread.debugreg1 = 0;
-	tsk->thread.debugreg2 = 0;
-	tsk->thread.debugreg3 = 0;
-	tsk->thread.debugreg6 = 0;
-	tsk->thread.debugreg7 = 0;
-	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
-	clear_tsk_thread_flag(tsk, TIF_DEBUG);
-	/*
-	 * Forget coprocessor state..
-	 */
-	tsk->fpu_counter = 0;
-	clear_fpu(tsk);
-	clear_used_math();
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 	BUG_ON(dead_task->mm);
@@ -287,7 +245,7 @@ void prepare_to_copy(struct task_struct
 	unlazy_fpu(tsk);
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
 	unsigned long unused,
 	struct task_struct *p, struct pt_regs *regs)
 {
@@ -305,7 +263,7 @@ int copy_thread(int nr, unsigned long cl
 
 	p->thread.ip = (unsigned long) ret_from_fork;
 
-	savesegment(gs, p->thread.gs);
+	task_user_gs(p) = get_user_gs(regs);
 
 	tsk = current;
 	if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
@@ -343,7 +301,7 @@ int copy_thread(int nr, unsigned long cl
 void
 start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
 {
-	__asm__("movl %0, %%gs" : : "r"(0));
+	set_user_gs(regs, 0);
 	regs->fs		= 0;
 	set_fs(USER_DS);
 	regs->ds		= __USER_DS;
@@ -359,127 +317,6 @@ start_thread(struct pt_regs *regs, unsig
 }
 EXPORT_SYMBOL_GPL(start_thread);
 
-static void hard_disable_TSC(void)
-{
-	write_cr4(read_cr4() | X86_CR4_TSD);
-}
-
-void disable_TSC(void)
-{
-	preempt_disable();
-	if (!test_and_set_thread_flag(TIF_NOTSC))
-		/*
-		 * Must flip the CPU state synchronously with
-		 * TIF_NOTSC in the current running context.
-		 */
-		hard_disable_TSC();
-	preempt_enable();
-}
-
-static void hard_enable_TSC(void)
-{
-	write_cr4(read_cr4() & ~X86_CR4_TSD);
-}
-
-static void enable_TSC(void)
-{
-	preempt_disable();
-	if (test_and_clear_thread_flag(TIF_NOTSC))
-		/*
-		 * Must flip the CPU state synchronously with
-		 * TIF_NOTSC in the current running context.
-		 */
-		hard_enable_TSC();
-	preempt_enable();
-}
-
-int get_tsc_mode(unsigned long adr)
-{
-	unsigned int val;
-
-	if (test_thread_flag(TIF_NOTSC))
-		val = PR_TSC_SIGSEGV;
-	else
-		val = PR_TSC_ENABLE;
-
-	return put_user(val, (unsigned int __user *)adr);
-}
-
-int set_tsc_mode(unsigned int val)
-{
-	if (val == PR_TSC_SIGSEGV)
-		disable_TSC();
-	else if (val == PR_TSC_ENABLE)
-		enable_TSC();
-	else
-		return -EINVAL;
-
-	return 0;
-}
-
-static noinline void
-__switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
-		 struct tss_struct *tss)
-{
-	struct thread_struct *prev, *next;
-
-	prev = &prev_p->thread;
-	next = &next_p->thread;
-
-	if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
-	    test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
-		ds_switch_to(prev_p, next_p);
-	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 */
-		if (test_tsk_thread_flag(next_p, TIF_NOTSC))
-			hard_disable_TSC();
-		else
-			hard_enable_TSC();
-	}
-
-	if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
-		/*
-		 * Disable the bitmap via an invalid offset. We still cache
-		 * the previous bitmap owner and the IO bitmap contents:
-		 */
-		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
-		return;
-	}
-
-	if (likely(next == tss->io_bitmap_owner)) {
-		/*
-		 * Previous owner of the bitmap (hence the bitmap content)
-		 * matches the next task, we dont have to do anything but
-		 * to set a valid offset in the TSS:
-		 */
-		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
-		return;
-	}
-	/*
-	 * Lazy TSS's I/O bitmap copy. We set an invalid offset here
-	 * and we let the task to get a GPF in case an I/O instruction
-	 * is performed.  The handler of the GPF will verify that the
-	 * faulting task has a valid I/O bitmap and, it true, does the
-	 * real copy and restart the instruction.  This will save us
-	 * redundant copies when the currently switched task does not
-	 * perform any I/O during its timeslice.
-	 */
-	tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
-}
 
 /*
  *	switch_to(x,yn) should switch tasks from x to y.
@@ -540,7 +377,7 @@ __switch_to(struct task_struct *prev_p,
 	 * used %fs or %gs (it does not today), or if the kernel is
 	 * running inside of a hypervisor layer.
 	 */
-	savesegment(gs, prev->gs);
+	lazy_save_gs(prev->gs);
 
 	/*
 	 * Load the per-thread Thread-Local Storage descriptor.
@@ -586,64 +423,44 @@ __switch_to(struct task_struct *prev_p,
 	 * Restore %gs if needed (which is common)
 	 */
 	if (prev->gs | next->gs)
-		loadsegment(gs, next->gs);
+		lazy_load_gs(next->gs);
 
-	x86_write_percpu(current_task, next_p);
+	percpu_write(current_task, next_p);
 
 	return prev_p;
 }
 
-asmlinkage int sys_fork(struct pt_regs regs)
-{
-	return do_fork(SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
-}
-
-asmlinkage int sys_clone(struct pt_regs regs)
+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;
+	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);
-}
-
-/*
- * This is trivial, and on the face of it looks like it
- * could equally well be done in user mode.
- *
- * Not so, for quite unobvious reasons - register pressure.
- * In user mode vfork() cannot have a stack frame, and if
- * done by calling the "clone()" system call directly, you
- * do not have enough call-clobbered registers to hold all
- * the information you need.
- */
-asmlinkage int sys_vfork(struct pt_regs regs)
-{
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 0, NULL, NULL);
+		newsp = regs->sp;
+	return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
 }
 
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(struct pt_regs regs)
+int sys_execve(struct pt_regs *regs)
 {
 	int error;
 	char *filename;
 
-	filename = getname((char __user *) regs.bx);
+	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);
+			(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);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/process_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/process_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/process_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/process_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <stdarg.h>
 
+#include <linux/stackprotector.h>
 #include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -47,7 +48,6 @@
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/mmu_context.h>
-#include <asm/pda.h>
 #include <asm/prctl.h>
 #include <asm/desc.h>
 #include <asm/proto.h>
@@ -58,6 +58,12 @@
 
 asmlinkage extern void ret_from_fork(void);
 
+DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
+EXPORT_PER_CPU_SYMBOL(current_task);
+
+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);
@@ -76,13 +82,13 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregist
 
 void enter_idle(void)
 {
-	write_pda(isidle, 1);
+	percpu_write(is_idle, 1);
 	atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 }
 
 static void __exit_idle(void)
 {
-	if (test_and_clear_bit_pda(0, isidle) == 0)
+	if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
 		return;
 	atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 }
@@ -112,6 +118,16 @@ static inline void play_dead(void)
 void cpu_idle(void)
 {
 	current_thread_info()->status |= TS_POLLING;
+
+	/*
+	 * If we're the non-boot CPU, nothing set the stack canary up
+	 * for us.  CPU0 already has it initialized but no harm in
+	 * doing it again.  This is a good place for updating it, as
+	 * we wont ever return from this function (so the invalid
+	 * canaries already on the stack wont ever trigger).
+	 */
+	boot_init_stack_canary();
+
 	/* endless idle loop with no priority at all */
 	while (1) {
 		tick_nohz_stop_sched_tick(1);
@@ -221,61 +237,6 @@ void show_regs(struct pt_regs *regs)
 	show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
 }
 
-/*
- * Free current thread data structures etc..
- */
-void exit_thread(void)
-{
-	struct task_struct *me = current;
-	struct thread_struct *t = &me->thread;
-
-	if (me->thread.io_bitmap_ptr) {
-		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
-
-		kfree(t->io_bitmap_ptr);
-		t->io_bitmap_ptr = NULL;
-		clear_thread_flag(TIF_IO_BITMAP);
-		/*
-		 * Careful, clear this in the TSS too:
-		 */
-		memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
-		t->io_bitmap_max = 0;
-		put_cpu();
-	}
-
-	ds_exit_thread(current);
-}
-
-void flush_thread(void)
-{
-	struct task_struct *tsk = current;
-
-	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;
-		}
-	}
-	clear_tsk_thread_flag(tsk, TIF_DEBUG);
-
-	tsk->thread.debugreg0 = 0;
-	tsk->thread.debugreg1 = 0;
-	tsk->thread.debugreg2 = 0;
-	tsk->thread.debugreg3 = 0;
-	tsk->thread.debugreg6 = 0;
-	tsk->thread.debugreg7 = 0;
-	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
-	/*
-	 * Forget coprocessor state..
-	 */
-	tsk->fpu_counter = 0;
-	clear_fpu(tsk);
-	clear_used_math();
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 	if (dead_task->mm) {
@@ -317,7 +278,7 @@ void prepare_to_copy(struct task_struct
 	unlazy_fpu(tsk);
 }
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
 		unsigned long unused,
 	struct task_struct *p, struct pt_regs *regs)
 {
@@ -397,7 +358,7 @@ start_thread(struct pt_regs *regs, unsig
 	load_gs_index(0);
 	regs->ip		= new_ip;
 	regs->sp		= new_sp;
-	write_pda(oldrsp, new_sp);
+	percpu_write(old_rsp, new_sp);
 	regs->cs		= __USER_CS;
 	regs->ss		= __USER_DS;
 	regs->flags		= 0x200;
@@ -409,118 +370,6 @@ start_thread(struct pt_regs *regs, unsig
 }
 EXPORT_SYMBOL_GPL(start_thread);
 
-static void hard_disable_TSC(void)
-{
-	write_cr4(read_cr4() | X86_CR4_TSD);
-}
-
-void disable_TSC(void)
-{
-	preempt_disable();
-	if (!test_and_set_thread_flag(TIF_NOTSC))
-		/*
-		 * Must flip the CPU state synchronously with
-		 * TIF_NOTSC in the current running context.
-		 */
-		hard_disable_TSC();
-	preempt_enable();
-}
-
-static void hard_enable_TSC(void)
-{
-	write_cr4(read_cr4() & ~X86_CR4_TSD);
-}
-
-static void enable_TSC(void)
-{
-	preempt_disable();
-	if (test_and_clear_thread_flag(TIF_NOTSC))
-		/*
-		 * Must flip the CPU state synchronously with
-		 * TIF_NOTSC in the current running context.
-		 */
-		hard_enable_TSC();
-	preempt_enable();
-}
-
-int get_tsc_mode(unsigned long adr)
-{
-	unsigned int val;
-
-	if (test_thread_flag(TIF_NOTSC))
-		val = PR_TSC_SIGSEGV;
-	else
-		val = PR_TSC_ENABLE;
-
-	return put_user(val, (unsigned int __user *)adr);
-}
-
-int set_tsc_mode(unsigned int val)
-{
-	if (val == PR_TSC_SIGSEGV)
-		disable_TSC();
-	else if (val == PR_TSC_ENABLE)
-		enable_TSC();
-	else
-		return -EINVAL;
-
-	return 0;
-}
-
-/*
- * This special macro can be used to load a debugging register
- */
-#define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r)
-
-static inline void __switch_to_xtra(struct task_struct *prev_p,
-				    struct task_struct *next_p,
-				    struct tss_struct *tss)
-{
-	struct thread_struct *prev, *next;
-
-	prev = &prev_p->thread,
-	next = &next_p->thread;
-
-	if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
-	    test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
-		ds_switch_to(prev_p, next_p);
-	else if (next->debugctlmsr != prev->debugctlmsr)
-		update_debugctlmsr(next->debugctlmsr);
-
-	if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
-		loaddebug(next, 0);
-		loaddebug(next, 1);
-		loaddebug(next, 2);
-		loaddebug(next, 3);
-		/* no 4 and 5 */
-		loaddebug(next, 6);
-		loaddebug(next, 7);
-	}
-
-	if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
-	    test_tsk_thread_flag(next_p, TIF_NOTSC)) {
-		/* prev and next are different */
-		if (test_tsk_thread_flag(next_p, TIF_NOTSC))
-			hard_disable_TSC();
-		else
-			hard_enable_TSC();
-	}
-
-	if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
-		/*
-		 * Copy the relevant range of the IO bitmap.
-		 * Normally this is 128 bytes or less:
-		 */
-		memcpy(tss->io_bitmap, next->io_bitmap_ptr,
-		       max(prev->io_bitmap_max, next->io_bitmap_max));
-	} else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
-		/*
-		 * Clear any possible leftover bits:
-		 */
-		memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
-	}
-}
-
 /*
  *	switch_to(x,y) should switch tasks from x to y.
  *
@@ -618,21 +467,13 @@ __switch_to(struct task_struct *prev_p,
 	/*
 	 * Switch the PDA and FPU contexts.
 	 */
-	prev->usersp = read_pda(oldrsp);
-	write_pda(oldrsp, next->usersp);
-	write_pda(pcurrent, next_p);
+	prev->usersp = percpu_read(old_rsp);
+	percpu_write(old_rsp, next->usersp);
+	percpu_write(current_task, next_p);
 
-	write_pda(kernelstack,
+	percpu_write(kernel_stack,
 		  (unsigned long)task_stack_page(next_p) +
-		  THREAD_SIZE - PDA_STACKOFFSET);
-#ifdef CONFIG_CC_STACKPROTECTOR
-	write_pda(stack_canary, next_p->stack_canary);
-	/*
-	 * Build time only check to make sure the stack_canary is at
-	 * offset 40 in the pda; this is a gcc ABI requirement
-	 */
-	BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
-#endif
+		  THREAD_SIZE - KERNEL_STACK_OFFSET);
 
 	/*
 	 * Now maybe reload the debug registers and handle I/O bitmaps
@@ -686,11 +527,6 @@ void set_personality_64bit(void)
 	current->personality &= ~READ_IMPLIES_EXEC;
 }
 
-asmlinkage long sys_fork(struct pt_regs *regs)
-{
-	return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
-}
-
 asmlinkage long
 sys_clone(unsigned long clone_flags, unsigned long newsp,
 	  void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
@@ -700,22 +536,6 @@ sys_clone(unsigned long clone_flags, uns
 	return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
 }
 
-/*
- * This is trivial, and on the face of it looks like it
- * could equally well be done in user mode.
- *
- * Not so, for quite unobvious reasons - register pressure.
- * In user mode vfork() cannot have a stack frame, and if
- * done by calling the "clone()" system call directly, you
- * do not have enough call-clobbered registers to hold all
- * the information you need.
- */
-asmlinkage long sys_vfork(struct pt_regs *regs)
-{
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
-		    NULL, NULL);
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long stack;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/process.c linux-libre-2.6.30-gnu1/arch/x86/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,16 +1,19 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <asm/idle.h>
 #include <linux/smp.h>
+#include <linux/prctl.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/clockchips.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
 #include <asm/system.h>
 #include <asm/apic.h>
+#include <asm/idle.h>
+#include <asm/uaccess.h>
+#include <asm/i387.h>
 
 unsigned long idle_halt;
 EXPORT_SYMBOL(idle_halt);
@@ -19,6 +22,9 @@ EXPORT_SYMBOL(idle_nomwait);
 
 struct kmem_cache *task_xstate_cachep;
 
+DEFINE_TRACE(power_start);
+DEFINE_TRACE(power_end);
+
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
 	*dst = *src;
@@ -56,6 +62,193 @@ void arch_task_cache_init(void)
 }
 
 /*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+	struct task_struct *me = current;
+	struct thread_struct *t = &me->thread;
+	unsigned long *bp = t->io_bitmap_ptr;
+
+	if (bp) {
+		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
+
+		t->io_bitmap_ptr = NULL;
+		clear_thread_flag(TIF_IO_BITMAP);
+		/*
+		 * Careful, clear this in the TSS too:
+		 */
+		memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
+		t->io_bitmap_max = 0;
+		put_cpu();
+		kfree(bp);
+	}
+
+	ds_exit_thread(current);
+}
+
+void flush_thread(void)
+{
+	struct task_struct *tsk = current;
+
+#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
+
+	clear_tsk_thread_flag(tsk, TIF_DEBUG);
+
+	tsk->thread.debugreg0 = 0;
+	tsk->thread.debugreg1 = 0;
+	tsk->thread.debugreg2 = 0;
+	tsk->thread.debugreg3 = 0;
+	tsk->thread.debugreg6 = 0;
+	tsk->thread.debugreg7 = 0;
+	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
+	/*
+	 * Forget coprocessor state..
+	 */
+	tsk->fpu_counter = 0;
+	clear_fpu(tsk);
+	clear_used_math();
+}
+
+static void hard_disable_TSC(void)
+{
+	write_cr4(read_cr4() | X86_CR4_TSD);
+}
+
+void disable_TSC(void)
+{
+	preempt_disable();
+	if (!test_and_set_thread_flag(TIF_NOTSC))
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOTSC in the current running context.
+		 */
+		hard_disable_TSC();
+	preempt_enable();
+}
+
+static void hard_enable_TSC(void)
+{
+	write_cr4(read_cr4() & ~X86_CR4_TSD);
+}
+
+static void enable_TSC(void)
+{
+	preempt_disable();
+	if (test_and_clear_thread_flag(TIF_NOTSC))
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOTSC in the current running context.
+		 */
+		hard_enable_TSC();
+	preempt_enable();
+}
+
+int get_tsc_mode(unsigned long adr)
+{
+	unsigned int val;
+
+	if (test_thread_flag(TIF_NOTSC))
+		val = PR_TSC_SIGSEGV;
+	else
+		val = PR_TSC_ENABLE;
+
+	return put_user(val, (unsigned int __user *)adr);
+}
+
+int set_tsc_mode(unsigned int val)
+{
+	if (val == PR_TSC_SIGSEGV)
+		disable_TSC();
+	else if (val == PR_TSC_ENABLE)
+		enable_TSC();
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
+		      struct tss_struct *tss)
+{
+	struct thread_struct *prev, *next;
+
+	prev = &prev_p->thread;
+	next = &next_p->thread;
+
+	if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
+	    test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
+		ds_switch_to(prev_p, next_p);
+	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 */
+		if (test_tsk_thread_flag(next_p, TIF_NOTSC))
+			hard_disable_TSC();
+		else
+			hard_enable_TSC();
+	}
+
+	if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
+		/*
+		 * Copy the relevant range of the IO bitmap.
+		 * Normally this is 128 bytes or less:
+		 */
+		memcpy(tss->io_bitmap, next->io_bitmap_ptr,
+		       max(prev->io_bitmap_max, next->io_bitmap_max));
+	} else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
+		/*
+		 * Clear any possible leftover bits:
+		 */
+		memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
+	}
+}
+
+int sys_fork(struct pt_regs *regs)
+{
+	return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+}
+
+/*
+ * This is trivial, and on the face of it looks like it
+ * could equally well be done in user mode.
+ *
+ * Not so, for quite unobvious reasons - register pressure.
+ * In user mode vfork() cannot have a stack frame, and if
+ * done by calling the "clone()" system call directly, you
+ * do not have enough call-clobbered registers to hold all
+ * the information you need.
+ */
+int sys_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
+		       NULL, NULL);
+}
+
+
+/*
  * Idle related variables and functions
  */
 unsigned long boot_option_idle_override = 0;
@@ -135,7 +328,7 @@ void stop_this_cpu(void *dummy)
 	/*
 	 * Remove this CPU:
 	 */
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 	disable_local_APIC();
 
 	for (;;) {
@@ -285,12 +478,13 @@ static int __cpuinit check_c1e_idle(cons
 	return 1;
 }
 
-static cpumask_t c1e_mask = CPU_MASK_NONE;
+static cpumask_var_t c1e_mask;
 static int c1e_detected;
 
 void c1e_remove_cpu(int cpu)
 {
-	cpu_clear(cpu, c1e_mask);
+	if (c1e_mask != NULL)
+		cpumask_clear_cpu(cpu, c1e_mask);
 }
 
 /*
@@ -319,8 +513,8 @@ static void c1e_idle(void)
 	if (c1e_detected) {
 		int cpu = smp_processor_id();
 
-		if (!cpu_isset(cpu, c1e_mask)) {
-			cpu_set(cpu, c1e_mask);
+		if (!cpumask_test_cpu(cpu, c1e_mask)) {
+			cpumask_set_cpu(cpu, c1e_mask);
 			/*
 			 * Force broadcast so ACPI can not interfere. Needs
 			 * to run with interrupts enabled as it uses
@@ -350,7 +544,7 @@ static void c1e_idle(void)
 
 void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
 	if (pm_idle == poll_idle && smp_num_siblings > 1) {
 		printk(KERN_WARNING "WARNING: polling idle and HT enabled,"
 			" performance may degrade.\n");
@@ -372,6 +566,15 @@ void __cpuinit select_idle_routine(const
 		pm_idle = default_idle;
 }
 
+void __init init_c1e_mask(void)
+{
+	/* If we're using c1e_idle, we need to allocate c1e_mask. */
+	if (pm_idle == c1e_idle) {
+		alloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+		cpumask_clear(c1e_mask);
+	}
+}
+
 static int __init idle_setup(char *str)
 {
 	if (!str)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/ptrace.c linux-libre-2.6.30-gnu1/arch/x86/kernel/ptrace.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/ptrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/ptrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,8 @@
 #include <asm/proto.h>
 #include <asm/ds.h>
 
+#include <trace/syscall.h>
+
 #include "tls.h"
 
 enum x86_regset {
@@ -75,10 +77,7 @@ static inline bool invalid_selector(u16
 static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
 {
 	BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
-	regno >>= 2;
-	if (regno > FS)
-		--regno;
-	return &regs->bx + regno;
+	return &regs->bx + (regno >> 2);
 }
 
 static u16 get_segment_reg(struct task_struct *task, unsigned long offset)
@@ -90,9 +89,10 @@ static u16 get_segment_reg(struct task_s
 	if (offset != offsetof(struct user_regs_struct, gs))
 		retval = *pt_regs_access(task_pt_regs(task), offset);
 	else {
-		retval = task->thread.gs;
 		if (task == current)
-			savesegment(gs, retval);
+			retval = get_user_gs(task_pt_regs(task));
+		else
+			retval = task_user_gs(task);
 	}
 	return retval;
 }
@@ -126,13 +126,10 @@ static int set_segment_reg(struct task_s
 		break;
 
 	case offsetof(struct user_regs_struct, gs):
-		task->thread.gs = value;
 		if (task == current)
-			/*
-			 * The user-mode %gs is not affected by
-			 * kernel entry, so we must update the CPU.
-			 */
-			loadsegment(gs, value);
+			set_user_gs(task_pt_regs(task), value);
+		else
+			task_user_gs(task) = value;
 	}
 
 	return 0;
@@ -273,7 +270,7 @@ static unsigned long debugreg_addr_limit
 	if (test_tsk_thread_flag(task, TIF_IA32))
 		return IA32_PAGE_OFFSET - 3;
 #endif
-	return TASK_SIZE64 - 7;
+	return TASK_SIZE_MAX - 7;
 }
 
 #endif	/* CONFIG_X86_32 */
@@ -690,9 +687,8 @@ static int ptrace_bts_config(struct task
 		if (!cfg.signal)
 			return -EINVAL;
 
-		return -EOPNOTSUPP;
-
 		child->thread.bts_ovfl_signal = cfg.signal;
+		return -EOPNOTSUPP;
 	}
 
 	if ((cfg.flags & PTRACE_BTS_O_ALLOC) &&
@@ -1421,6 +1417,9 @@ asmregparm long syscall_trace_enter(stru
 	    tracehook_report_syscall_entry(regs))
 		ret = -1L;
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_enter(regs);
+
 	if (unlikely(current->audit_context)) {
 		if (IS_IA32)
 			audit_syscall_entry(AUDIT_ARCH_I386,
@@ -1444,6 +1443,9 @@ asmregparm void syscall_trace_leave(stru
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_exit(regs);
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, 0);
 
@@ -1461,6 +1463,6 @@ asmregparm void syscall_trace_leave(stru
 	 * system call instruction.
 	 */
 	if (test_thread_flag(TIF_SINGLESTEP) &&
-	    tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
+	    tracehook_consider_fatal_signal(current, SIGTRAP))
 		send_sigtrap(current, regs, 0, TRAP_BRKPT);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/quirks.c linux-libre-2.6.30-gnu1/arch/x86/kernel/quirks.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/quirks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/quirks.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,8 +74,7 @@ static void ich_force_hpet_resume(void)
 	if (!force_hpet_address)
 		return;
 
-	if (rcba_base == NULL)
-		BUG();
+	BUG_ON(rcba_base == NULL);
 
 	/* read the Function Disable register, dword mode only */
 	val = readl(rcba_base + 0x3404);
@@ -172,7 +171,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
 			 ich_force_enable_hpet);
-
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x3a16,	/* ICH10 */
+			 ich_force_enable_hpet);
 
 static struct pci_dev *cached_dev;
 
@@ -261,8 +261,6 @@ static void old_ich_force_enable_hpet_us
 {
 	if (hpet_force_user)
 		old_ich_force_enable_hpet(dev);
-	else
-		hpet_print_force_info();
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/reboot.c linux-libre-2.6.30-gnu1/arch/x86/kernel/reboot.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/reboot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/reboot.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/reboot.h>
 #include <asm/pci_x86.h>
 #include <asm/virtext.h>
+#include <asm/cpu.h>
 
 #ifdef CONFIG_X86_32
 # include <linux/dmi.h>
@@ -23,8 +24,6 @@
 # include <asm/iommu.h>
 #endif
 
-#include <mach_ipi.h>
-
 /*
  * Power off function, if any
  */
@@ -225,6 +224,22 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
 		},
 	},
+	{	/* Handle problems with rebooting on Dell DXP061 */
+		.callback = set_bios_reboot,
+		.ident = "Dell DXP061",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
+		},
+	},
+	{	/* Handle problems with rebooting on Sony VGN-Z540N */
+		.callback = set_bios_reboot,
+		.ident = "Sony VGN-Z540N",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
+		},
+	},
 	{ }
 };
 
@@ -658,7 +673,7 @@ static int crash_nmi_callback(struct not
 
 static void smp_send_nmi_allbutself(void)
 {
-	send_IPI_allbutself(NMI_VECTOR);
+	apic->send_IPI_allbutself(NMI_VECTOR);
 }
 
 static struct notifier_block crash_nmi_nb = {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/relocate_kernel_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/relocate_kernel_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/relocate_kernel_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/relocate_kernel_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
  */
 
 #include <linux/linkage.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/kexec.h>
 #include <asm/processor-flags.h>
 
@@ -17,7 +17,8 @@
 
 #define PTR(x) (x << 2)
 
-/* control_page + KEXEC_CONTROL_CODE_MAX_SIZE
+/*
+ * control_page + KEXEC_CONTROL_CODE_MAX_SIZE
  * ~ control_page + PAGE_SIZE are used as data storage and stack for
  * jumping back
  */
@@ -76,8 +77,10 @@ relocate_kernel:
 	movl	%eax, CP_PA_SWAP_PAGE(%edi)
 	movl	%ebx, CP_PA_BACKUP_PAGES_MAP(%edi)
 
-	/* get physical address of control page now */
-	/* this is impossible after page table switch */
+	/*
+	 * get physical address of control page now
+	 * this is impossible after page table switch
+	 */
 	movl	PTR(PA_CONTROL_PAGE)(%ebp), %edi
 
 	/* switch to new set of page tables */
@@ -97,7 +100,8 @@ identity_mapped:
 	/* store the start address on the stack */
 	pushl   %edx
 
-	/* Set cr0 to a known state:
+	/*
+	 * Set cr0 to a known state:
 	 *  - Paging disabled
 	 *  - Alignment check disabled
 	 *  - Write protect disabled
@@ -113,7 +117,8 @@ identity_mapped:
 	/* clear cr4 if applicable */
 	testl	%ecx, %ecx
 	jz	1f
-	/* Set cr4 to a known state:
+	/*
+	 * Set cr4 to a known state:
 	 * Setting everything to zero seems safe.
 	 */
 	xorl	%eax, %eax
@@ -132,15 +137,18 @@ identity_mapped:
 	call	swap_pages
 	addl	$8, %esp
 
-	/* To be certain of avoiding problems with self-modifying code
+	/*
+	 * To be certain of avoiding problems with self-modifying code
 	 * I need to execute a serializing instruction here.
 	 * So I flush the TLB, it's handy, and not processor dependent.
 	 */
 	xorl	%eax, %eax
 	movl	%eax, %cr3
 
-	/* set all of the registers to known values */
-	/* leave %esp alone */
+	/*
+	 * set all of the registers to known values
+	 * leave %esp alone
+	 */
 
 	testl	%esi, %esi
 	jnz 1f
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/relocate_kernel_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/relocate_kernel_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/relocate_kernel_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/relocate_kernel_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -7,10 +7,10 @@
  */
 
 #include <linux/linkage.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/kexec.h>
 #include <asm/processor-flags.h>
-#include <asm/pgtable.h>
+#include <asm/pgtable_types.h>
 
 /*
  * Must be relocatable PIC code callable as a C function
@@ -19,145 +19,76 @@
 #define PTR(x) (x << 3)
 #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
 
+/*
+ * control_page + KEXEC_CONTROL_CODE_MAX_SIZE
+ * ~ control_page + PAGE_SIZE are used as data storage and stack for
+ * jumping back
+ */
+#define DATA(offset)		(KEXEC_CONTROL_CODE_MAX_SIZE+(offset))
+
+/* Minimal CPU state */
+#define RSP			DATA(0x0)
+#define CR0			DATA(0x8)
+#define CR3			DATA(0x10)
+#define CR4			DATA(0x18)
+
+/* other data */
+#define CP_PA_TABLE_PAGE	DATA(0x20)
+#define CP_PA_SWAP_PAGE		DATA(0x28)
+#define CP_PA_BACKUP_PAGES_MAP	DATA(0x30)
+
 	.text
 	.align PAGE_SIZE
 	.code64
 	.globl relocate_kernel
 relocate_kernel:
-	/* %rdi indirection_page
+	/*
+	 * %rdi indirection_page
 	 * %rsi page_list
 	 * %rdx start address
+	 * %rcx preserve_context
 	 */
 
-	/* map the control page at its virtual address */
-
-	movq	$0x0000ff8000000000, %r10        /* mask */
-	mov	$(39 - 3), %cl                   /* bits to shift */
-	movq	PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PGD)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PUD_0)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PUD_0)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PMD_0)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PMD_0)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PTE_0)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PTE_0)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	/* identity map the control page at its physical address */
-
-	movq	$0x0000ff8000000000, %r10        /* mask */
-	mov	$(39 - 3), %cl                   /* bits to shift */
-	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PGD)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PUD_1)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PUD_1)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PMD_1)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PMD_1)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_PTE_1)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
-
-	shrq	$9, %r10
-	sub	$9, %cl
-
-	movq	%r11, %r9
-	andq	%r10, %r9
-	shrq	%cl, %r9
-
-	movq	PTR(VA_PTE_1)(%rsi), %r8
-	addq	%r8, %r9
-	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
-	orq	$PAGE_ATTR, %r8
-	movq	%r8, (%r9)
+	/* Save the CPU context, used for jumping back */
+	pushq %rbx
+	pushq %rbp
+	pushq %r12
+	pushq %r13
+	pushq %r14
+	pushq %r15
+	pushf
 
-relocate_new_kernel:
-	/* %rdi indirection_page
-	 * %rsi page_list
-	 * %rdx start address
-	 */
+	movq	PTR(VA_CONTROL_PAGE)(%rsi), %r11
+	movq	%rsp, RSP(%r11)
+	movq	%cr0, %rax
+	movq	%rax, CR0(%r11)
+	movq	%cr3, %rax
+	movq	%rax, CR3(%r11)
+	movq	%cr4, %rax
+	movq	%rax, CR4(%r11)
 
 	/* zero out flags, and disable interrupts */
 	pushq $0
 	popfq
 
-	/* get physical address of control page now */
-	/* this is impossible after page table switch */
+	/*
+	 * get physical address of control page now
+	 * this is impossible after page table switch
+	 */
 	movq	PTR(PA_CONTROL_PAGE)(%rsi), %r8
 
 	/* get physical address of page table now too */
-	movq	PTR(PA_TABLE_PAGE)(%rsi), %rcx
+	movq	PTR(PA_TABLE_PAGE)(%rsi), %r9
 
-	/* switch to new set of page tables */
-	movq	PTR(PA_PGD)(%rsi), %r9
+	/* get physical address of swap page now */
+	movq	PTR(PA_SWAP_PAGE)(%rsi), %r10
+
+	/* save some information for jumping back */
+	movq	%r9, CP_PA_TABLE_PAGE(%r11)
+	movq	%r10, CP_PA_SWAP_PAGE(%r11)
+	movq	%rdi, CP_PA_BACKUP_PAGES_MAP(%r11)
+
+	/* Switch to the identity mapped page tables */
 	movq	%r9, %cr3
 
 	/* setup a new stack at the end of the physical control page */
@@ -172,7 +103,8 @@ identity_mapped:
 	/* store the start address on the stack */
 	pushq   %rdx
 
-	/* Set cr0 to a known state:
+	/*
+	 * Set cr0 to a known state:
 	 *  - Paging enabled
 	 *  - Alignment check disabled
 	 *  - Write protect disabled
@@ -185,7 +117,8 @@ identity_mapped:
 	orl	$(X86_CR0_PG | X86_CR0_PE), %eax
 	movq	%rax, %cr0
 
-	/* Set cr4 to a known state:
+	/*
+	 * Set cr4 to a known state:
 	 *  - physical address extension enabled
 	 */
 	movq	$X86_CR4_PAE, %rax
@@ -194,12 +127,88 @@ identity_mapped:
 	jmp 1f
 1:
 
-	/* Switch to the identity mapped page tables,
-	 * and flush the TLB.
-	*/
-	movq	%rcx, %cr3
+	/* Flush the TLB (needed?) */
+	movq	%r9, %cr3
+
+	movq	%rcx, %r11
+	call	swap_pages
+
+	/*
+	 * To be certain of avoiding problems with self-modifying code
+	 * I need to execute a serializing instruction here.
+	 * So I flush the TLB by reloading %cr3 here, it's handy,
+	 * and not processor dependent.
+	 */
+	movq	%cr3, %rax
+	movq	%rax, %cr3
+
+	/*
+	 * set all of the registers to known values
+	 * leave %rsp alone
+	 */
+
+	testq	%r11, %r11
+	jnz 1f
+	xorq	%rax, %rax
+	xorq	%rbx, %rbx
+	xorq    %rcx, %rcx
+	xorq    %rdx, %rdx
+	xorq    %rsi, %rsi
+	xorq    %rdi, %rdi
+	xorq    %rbp, %rbp
+	xorq	%r8,  %r8
+	xorq	%r9,  %r9
+	xorq	%r10, %r9
+	xorq	%r11, %r11
+	xorq	%r12, %r12
+	xorq	%r13, %r13
+	xorq	%r14, %r14
+	xorq	%r15, %r15
+
+	ret
+
+1:
+	popq	%rdx
+	leaq	PAGE_SIZE(%r10), %rsp
+	call	*%rdx
+
+	/* get the re-entry point of the peer system */
+	movq	0(%rsp), %rbp
+	call	1f
+1:
+	popq	%r8
+	subq	$(1b - relocate_kernel), %r8
+	movq	CP_PA_SWAP_PAGE(%r8), %r10
+	movq	CP_PA_BACKUP_PAGES_MAP(%r8), %rdi
+	movq	CP_PA_TABLE_PAGE(%r8), %rax
+	movq	%rax, %cr3
+	lea	PAGE_SIZE(%r8), %rsp
+	call	swap_pages
+	movq	$virtual_mapped, %rax
+	pushq	%rax
+	ret
+
+virtual_mapped:
+	movq	RSP(%r8), %rsp
+	movq	CR4(%r8), %rax
+	movq	%rax, %cr4
+	movq	CR3(%r8), %rax
+	movq	CR0(%r8), %r8
+	movq	%rax, %cr3
+	movq	%r8, %cr0
+	movq	%rbp, %rax
+
+	popf
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+	ret
 
 	/* Do the copies */
+swap_pages:
 	movq	%rdi, %rcx 	/* Put the page_list in %rcx */
 	xorq	%rdi, %rdi
 	xorq	%rsi, %rsi
@@ -231,36 +240,27 @@ identity_mapped:
 	movq	%rcx,   %rsi  /* For ever source page do a copy */
 	andq	$0xfffffffffffff000, %rsi
 
+	movq	%rdi, %rdx
+	movq	%rsi, %rax
+
+	movq	%r10, %rdi
 	movq	$512,   %rcx
 	rep ; movsq
-	jmp	0b
-3:
 
-	/* To be certain of avoiding problems with self-modifying code
-	 * I need to execute a serializing instruction here.
-	 * So I flush the TLB by reloading %cr3 here, it's handy,
-	 * and not processor dependent.
-	 */
-	movq	%cr3, %rax
-	movq	%rax, %cr3
-
-	/* set all of the registers to known values */
-	/* leave %rsp alone */
+	movq	%rax, %rdi
+	movq	%rdx, %rsi
+	movq	$512,   %rcx
+	rep ; movsq
 
-	xorq	%rax, %rax
-	xorq	%rbx, %rbx
-	xorq    %rcx, %rcx
-	xorq    %rdx, %rdx
-	xorq    %rsi, %rsi
-	xorq    %rdi, %rdi
-	xorq    %rbp, %rbp
-	xorq	%r8,  %r8
-	xorq	%r9,  %r9
-	xorq	%r10, %r9
-	xorq	%r11, %r11
-	xorq	%r12, %r12
-	xorq	%r13, %r13
-	xorq	%r14, %r14
-	xorq	%r15, %r15
+	movq	%rdx, %rdi
+	movq	%r10, %rsi
+	movq	$512,   %rcx
+	rep ; movsq
 
+	lea	PAGE_SIZE(%rax), %rsi
+	jmp	0b
+3:
 	ret
+
+	.globl kexec_control_code_size
+.set kexec_control_code_size, . - relocate_kernel
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/rtc.c linux-libre-2.6.30-gnu1/arch/x86/kernel/rtc.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/rtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/rtc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,14 @@
 /*
  * RTC related functions
  */
+#include <linux/platform_device.h>
+#include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/bcd.h>
-#include <linux/mc146818rtc.h>
-#include <linux/platform_device.h>
 #include <linux/pnp.h>
 
-#include <asm/time.h>
 #include <asm/vsyscall.h>
+#include <asm/time.h>
 
 #ifdef CONFIG_X86_32
 /*
@@ -16,9 +16,9 @@
  * register we are working with.  It is required for NMI access to the
  * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
  */
-volatile unsigned long cmos_lock = 0;
+volatile unsigned long cmos_lock;
 EXPORT_SYMBOL(cmos_lock);
-#endif
+#endif /* CONFIG_X86_32 */
 
 /* For two digit years assume time is always after that */
 #define CMOS_YEARS_OFFS 2000
@@ -38,9 +38,9 @@ EXPORT_SYMBOL(rtc_lock);
  */
 int mach_set_rtc_mmss(unsigned long nowtime)
 {
-	int retval = 0;
 	int real_seconds, real_minutes, cmos_minutes;
 	unsigned char save_control, save_freq_select;
+	int retval = 0;
 
 	 /* tell the clock it's being set */
 	save_control = CMOS_READ(RTC_CONTROL);
@@ -72,8 +72,8 @@ int mach_set_rtc_mmss(unsigned long nowt
 			real_seconds = bin2bcd(real_seconds);
 			real_minutes = bin2bcd(real_minutes);
 		}
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
+		CMOS_WRITE(real_seconds, RTC_SECONDS);
+		CMOS_WRITE(real_minutes, RTC_MINUTES);
 	} else {
 		printk(KERN_WARNING
 		       "set_rtc_mmss: can't update from %d to %d\n",
@@ -151,6 +151,7 @@ unsigned char rtc_cmos_read(unsigned cha
 	outb(addr, RTC_PORT(0));
 	val = inb(RTC_PORT(1));
 	lock_cmos_suffix(addr);
+
 	return val;
 }
 EXPORT_SYMBOL(rtc_cmos_read);
@@ -166,8 +167,8 @@ EXPORT_SYMBOL(rtc_cmos_write);
 
 static int set_rtc_mmss(unsigned long nowtime)
 {
-	int retval;
 	unsigned long flags;
+	int retval;
 
 	spin_lock_irqsave(&rtc_lock, flags);
 	retval = set_wallclock(nowtime);
@@ -242,6 +243,7 @@ static __init int add_rtc_cmos(void)
 	platform_device_register(&rtc_device);
 	dev_info(&rtc_device.dev,
 		 "registered platform RTC device (no PNP device found)\n");
+
 	return 0;
 }
 device_initcall(add_rtc_cmos);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/setup.c linux-libre-2.6.30-gnu1/arch/x86/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,14 +74,15 @@
 #include <asm/e820.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
-#include <asm/arch_hooks.h>
 #include <asm/efi.h>
+#include <asm/timer.h>
+#include <asm/i8259.h>
 #include <asm/sections.h>
 #include <asm/dmi.h>
 #include <asm/io_apic.h>
 #include <asm/ist.h>
 #include <asm/vmi.h>
-#include <setup_arch.h>
+#include <asm/setup_arch.h>
 #include <asm/bios_ebda.h>
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
@@ -89,7 +90,7 @@
 
 #include <asm/system.h>
 #include <asm/vsyscall.h>
-#include <asm/smp.h>
+#include <asm/cpu.h>
 #include <asm/desc.h>
 #include <asm/dma.h>
 #include <asm/iommu.h>
@@ -97,7 +98,6 @@
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
 
-#include <mach_apic.h>
 #include <asm/paravirt.h>
 #include <asm/hypervisor.h>
 
@@ -112,6 +112,25 @@
 #define ARCH_SETUP
 #endif
 
+RESERVE_BRK(dmi_alloc, 65536);
+
+unsigned int boot_cpu_id __read_mostly;
+
+static __initdata unsigned long _brk_start = (unsigned long)__brk_base;
+unsigned long _brk_end = (unsigned long)__brk_base;
+
+#ifdef CONFIG_X86_64
+int default_cpu_present_to_apicid(int mps_cpu)
+{
+	return __default_cpu_present_to_apicid(mps_cpu);
+}
+
+int default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+}
+#endif
+
 #ifndef CONFIG_DEBUG_BOOT_PARAMS
 struct boot_params __initdata boot_params;
 #else
@@ -144,12 +163,6 @@ static struct resource bss_resource = {
 
 
 #ifdef CONFIG_X86_32
-/* This value is set up by the early boot code to point to the value
-   immediately after the boot time page tables.  It contains a *physical*
-   address, and must not be in the .bss segment! */
-unsigned long init_pg_tables_start __initdata = ~0UL;
-unsigned long init_pg_tables_end __initdata = ~0UL;
-
 static struct resource video_ram_resource = {
 	.name	= "Video RAM area",
 	.start	= 0xa0000,
@@ -188,7 +201,9 @@ struct ist_info ist_info;
 #endif
 
 #else
-struct cpuinfo_x86 boot_cpu_data __read_mostly;
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {
+	.x86_phys_bits = MAX_PHYSMEM_BITS,
+};
 EXPORT_SYMBOL(boot_cpu_data);
 #endif
 
@@ -203,12 +218,6 @@ unsigned long mmu_cr4_features = X86_CR4
 int bootloader_type;
 
 /*
- * Early DMI memory
- */
-int dmi_alloc_index;
-char dmi_alloc_data[DMI_MAX_DATA];
-
-/*
  * Setup options
  */
 struct screen_info screen_info;
@@ -253,6 +262,35 @@ static inline void copy_edd(void)
 }
 #endif
 
+void * __init extend_brk(size_t size, size_t align)
+{
+	size_t mask = align - 1;
+	void *ret;
+
+	BUG_ON(_brk_start == 0);
+	BUG_ON(align & mask);
+
+	_brk_end = (_brk_end + mask) & ~mask;
+	BUG_ON((char *)(_brk_end + size) > __brk_limit);
+
+	ret = (void *)_brk_end;
+	_brk_end += size;
+
+	memset(ret, 0, size);
+
+	return ret;
+}
+
+static void __init reserve_brk(void)
+{
+	if (_brk_end > _brk_start)
+		reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
+
+	/* Mark brk area as locked down and no longer taking any
+	   new allocations */
+	_brk_start = 0;
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 
 #ifdef CONFIG_X86_32
@@ -586,20 +624,7 @@ static int __init setup_elfcorehdr(char
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static int __init default_update_genapic(void)
-{
-#ifdef CONFIG_X86_SMP
-# if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
-	genapic->wakeup_cpu = wakeup_secondary_cpu_via_init;
-# endif
-#endif
-
-	return 0;
-}
-
-static struct x86_quirks default_x86_quirks __initdata = {
-	.update_genapic         = default_update_genapic,
-};
+static struct x86_quirks default_x86_quirks __initdata;
 
 struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
 
@@ -656,7 +681,6 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
-	pre_setup_arch_hook();
 #else
 	printk(KERN_INFO "Command line: %s\n", boot_command_line);
 #endif
@@ -715,11 +739,7 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code = (unsigned long) _etext;
 	init_mm.end_data = (unsigned long) _edata;
-#ifdef CONFIG_X86_32
-	init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
-#else
-	init_mm.brk = (unsigned long) &_end;
-#endif
+	init_mm.brk = _brk_end;
 
 	code_resource.start = virt_to_phys(_text);
 	code_resource.end = virt_to_phys(_etext)-1;
@@ -824,8 +844,7 @@ void __init setup_arch(char **cmdline_p)
 #else
 	num_physpages = max_pfn;
 
- 	if (cpu_has_x2apic)
- 		check_x2apic();
+	check_x2apic();
 
 	/* How many end-of-memory variables you have, grandma! */
 	/* need this before calling reserve_initrd */
@@ -841,6 +860,8 @@ void __init setup_arch(char **cmdline_p)
 	setup_bios_corruption_check();
 #endif
 
+	reserve_brk();
+
 	/* max_pfn_mapped is updated here */
 	max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
 	max_pfn_mapped = max_low_pfn_mapped;
@@ -865,9 +886,7 @@ void __init setup_arch(char **cmdline_p)
 
 	reserve_initrd();
 
-#ifdef CONFIG_X86_64
 	vsmp_init();
-#endif
 
 	io_delay_init();
 
@@ -893,12 +912,11 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	acpi_reserve_bootmem();
 #endif
-#ifdef CONFIG_X86_FIND_SMP_CONFIG
 	/*
 	 * Find and reserve possible boot-time SMP configuration:
 	 */
 	find_smp_config();
-#endif
+
 	reserve_crashkernel();
 
 #ifdef CONFIG_X86_64
@@ -925,9 +943,7 @@ void __init setup_arch(char **cmdline_p)
 	map_vsyscall();
 #endif
 
-#ifdef CONFIG_X86_GENERICARCH
 	generic_apic_probe();
-#endif
 
 	early_quirks();
 
@@ -978,4 +994,94 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
+#ifdef CONFIG_X86_32
+
+/**
+ * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
+ *
+ * Description:
+ *	Perform any necessary interrupt initialisation prior to setting up
+ *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
+ *	interrupts should be initialised here if the machine emulates a PC
+ *	in any way.
+ **/
+void __init x86_quirk_pre_intr_init(void)
+{
+	if (x86_quirks->arch_pre_intr_init) {
+		if (x86_quirks->arch_pre_intr_init())
+			return;
+	}
+	init_ISA_irqs();
+}
+
+/**
+ * x86_quirk_intr_init - post gate setup interrupt initialisation
+ *
+ * Description:
+ *	Fill in any interrupts that may have been left out by the general
+ *	init_IRQ() routine.  interrupts having to do with the machine rather
+ *	than the devices on the I/O bus (like APIC interrupts in intel MP
+ *	systems) are started here.
+ **/
+void __init x86_quirk_intr_init(void)
+{
+	if (x86_quirks->arch_intr_init) {
+		if (x86_quirks->arch_intr_init())
+			return;
+	}
+}
+
+/**
+ * x86_quirk_trap_init - initialise system specific traps
+ *
+ * Description:
+ *	Called as the final act of trap_init().  Used in VISWS to initialise
+ *	the various board specific APIC traps.
+ **/
+void __init x86_quirk_trap_init(void)
+{
+	if (x86_quirks->arch_trap_init) {
+		if (x86_quirks->arch_trap_init())
+			return;
+	}
+}
+
+static struct irqaction irq0  = {
+	.handler = timer_interrupt,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+	.name = "timer"
+};
 
+/**
+ * x86_quirk_pre_time_init - do any specific initialisations before.
+ *
+ **/
+void __init x86_quirk_pre_time_init(void)
+{
+	if (x86_quirks->arch_pre_time_init)
+		x86_quirks->arch_pre_time_init();
+}
+
+/**
+ * x86_quirk_time_init - do any specific initialisations for the system timer.
+ *
+ * Description:
+ *	Must plug the system timer interrupt source at HZ into the IRQ listed
+ *	in irq_vectors.h:TIMER_IRQ
+ **/
+void __init x86_quirk_time_init(void)
+{
+	if (x86_quirks->arch_time_init) {
+		/*
+		 * A nonzero return code does not mean failure, it means
+		 * that the architecture quirk does not want any
+		 * generic (timer) setup to be performed after this:
+		 */
+		if (x86_quirks->arch_time_init())
+			return;
+	}
+
+	irq0.mask = cpumask_of_cpu(0);
+	setup_irq(0, &irq0);
+}
+#endif /* CONFIG_X86_32 */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/setup_percpu.c linux-libre-2.6.30-gnu1/arch/x86/kernel/setup_percpu.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/setup_percpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/setup_percpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,402 +7,427 @@
 #include <linux/crash_dump.h>
 #include <linux/smp.h>
 #include <linux/topology.h>
+#include <linux/pfn.h>
 #include <asm/sections.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
 #include <asm/highmem.h>
+#include <asm/proto.h>
+#include <asm/cpumask.h>
+#include <asm/cpu.h>
+#include <asm/stackprotector.h>
 
-#ifdef CONFIG_X86_LOCAL_APIC
-unsigned int num_processors;
-unsigned disabled_cpus __cpuinitdata;
-/* Processor that is doing the boot up */
-unsigned int boot_cpu_physical_apicid = -1U;
-EXPORT_SYMBOL(boot_cpu_physical_apicid);
-unsigned int max_physical_apicid;
-
-/* Bitmask of physically existing CPUs */
-physid_mask_t phys_cpu_present_map;
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
 #endif
 
-/* map cpu index to physical APIC ID */
-DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
-DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
-EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
-EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
-
-#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
-#define	X86_64_NUMA	1
+DEFINE_PER_CPU(int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
 
-/* map cpu index to node index */
-DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
-EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
+#ifdef CONFIG_X86_64
+#define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
+#else
+#define BOOT_PERCPU_OFFSET 0
+#endif
 
-/* which logical CPUs are on which nodes */
-cpumask_t *node_to_cpumask_map;
-EXPORT_SYMBOL(node_to_cpumask_map);
+DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
+EXPORT_PER_CPU_SYMBOL(this_cpu_off);
 
-/* setup node_to_cpumask_map */
-static void __init setup_node_to_cpumask_map(void);
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
+	[0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
+};
+EXPORT_SYMBOL(__per_cpu_offset);
 
+/*
+ * On x86_64 symbols referenced from code should be reachable using
+ * 32bit relocations.  Reserve space for static percpu variables in
+ * modules so that they are always served from the first chunk which
+ * is located at the percpu segment base.  On x86_32, anything can
+ * address anywhere.  No need to reserve space in the first chunk.
+ */
+#ifdef CONFIG_X86_64
+#define PERCPU_FIRST_CHUNK_RESERVE	PERCPU_MODULE_RESERVE
 #else
-static inline void setup_node_to_cpumask_map(void) { }
+#define PERCPU_FIRST_CHUNK_RESERVE	0
 #endif
 
-#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP)
-/*
- * Copy data used in early init routines from the initial arrays to the
- * per cpu data areas.  These arrays then become expendable and the
- * *_early_ptr's are zeroed indicating that the static arrays are gone.
+/**
+ * pcpu_need_numa - determine percpu allocation needs to consider NUMA
+ *
+ * If NUMA is not configured or there is only one NUMA node available,
+ * there is no reason to consider NUMA.  This function determines
+ * whether percpu allocation should consider NUMA or not.
+ *
+ * RETURNS:
+ * true if NUMA should be considered; otherwise, false.
  */
-static void __init setup_per_cpu_maps(void)
+static bool __init pcpu_need_numa(void)
 {
-	int cpu;
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+	pg_data_t *last = NULL;
+	unsigned int cpu;
 
 	for_each_possible_cpu(cpu) {
-		per_cpu(x86_cpu_to_apicid, cpu) =
-				early_per_cpu_map(x86_cpu_to_apicid, cpu);
-		per_cpu(x86_bios_cpu_apicid, cpu) =
-				early_per_cpu_map(x86_bios_cpu_apicid, cpu);
-#ifdef X86_64_NUMA
-		per_cpu(x86_cpu_to_node_map, cpu) =
-				early_per_cpu_map(x86_cpu_to_node_map, cpu);
-#endif
-	}
+		int node = early_cpu_to_node(cpu);
 
-	/* indicate the early static arrays will soon be gone */
-	early_per_cpu_ptr(x86_cpu_to_apicid) = NULL;
-	early_per_cpu_ptr(x86_bios_cpu_apicid) = NULL;
-#ifdef X86_64_NUMA
-	early_per_cpu_ptr(x86_cpu_to_node_map) = NULL;
+		if (node_online(node) && NODE_DATA(node) &&
+		    last && last != NODE_DATA(node))
+			return true;
+
+		last = NODE_DATA(node);
+	}
 #endif
+	return false;
 }
 
-#ifdef CONFIG_X86_32
-/*
- * Great future not-so-futuristic plan: make i386 and x86_64 do it
- * the same way
+/**
+ * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu
+ * @cpu: cpu to allocate for
+ * @size: size allocation in bytes
+ * @align: alignment
+ *
+ * Allocate @size bytes aligned at @align for cpu @cpu.  This wrapper
+ * does the right thing for NUMA regardless of the current
+ * configuration.
+ *
+ * RETURNS:
+ * Pointer to the allocated area on success, NULL on failure.
  */
-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(__per_cpu_offset);
-static inline void setup_cpu_pda_map(void) { }
-
-#elif !defined(CONFIG_SMP)
-static inline void setup_cpu_pda_map(void) { }
+static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
+					unsigned long align)
+{
+	const unsigned long goal = __pa(MAX_DMA_ADDRESS);
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+	int node = early_cpu_to_node(cpu);
+	void *ptr;
 
-#else /* CONFIG_SMP && CONFIG_X86_64 */
+	if (!node_online(node) || !NODE_DATA(node)) {
+		ptr = __alloc_bootmem_nopanic(size, align, goal);
+		pr_info("cpu %d has no node %d or node-local memory\n",
+			cpu, node);
+		pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n",
+			 cpu, size, __pa(ptr));
+	} 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));
+	}
+	return ptr;
+#else
+	return __alloc_bootmem_nopanic(size, align, goal);
+#endif
+}
 
 /*
- * Allocate cpu_pda pointer table and array via alloc_bootmem.
+ * Remap allocator
+ *
+ * This allocator uses PMD page as unit.  A PMD page is allocated for
+ * each cpu and each is remapped into vmalloc area using PMD mapping.
+ * As PMD page is quite large, only part of it is used for the first
+ * chunk.  Unused part is returned to the bootmem allocator.
+ *
+ * So, the PMD pages are mapped twice - once to the physical mapping
+ * and to the vmalloc area for the first percpu chunk.  The double
+ * mapping does add one more PMD TLB entry pressure but still is much
+ * better than only using 4k mappings while still being NUMA friendly.
  */
-static void __init setup_cpu_pda_map(void)
-{
-	char *pda;
-	struct x8664_pda **new_cpu_pda;
-	unsigned long size;
-	int cpu;
-
-	size = roundup(sizeof(struct x8664_pda), cache_line_size());
-
-	/* allocate cpu_pda array and pointer table */
-	{
-		unsigned long tsize = nr_cpu_ids * sizeof(void *);
-		unsigned long asize = size * (nr_cpu_ids - 1);
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+static size_t pcpur_size __initdata;
+static void **pcpur_ptrs __initdata;
 
-		tsize = roundup(tsize, cache_line_size());
-		new_cpu_pda = alloc_bootmem(tsize + asize);
-		pda = (char *)new_cpu_pda + tsize;
-	}
+static struct page * __init pcpur_get_page(unsigned int cpu, int pageno)
+{
+	size_t off = (size_t)pageno << PAGE_SHIFT;
 
-	/* initialize pointer table to static pda's */
-	for_each_possible_cpu(cpu) {
-		if (cpu == 0) {
-			/* leave boot cpu pda in place */
-			new_cpu_pda[0] = cpu_pda(0);
-			continue;
-		}
-		new_cpu_pda[cpu] = (struct x8664_pda *)pda;
-		new_cpu_pda[cpu]->in_bootmem = 1;
-		pda += size;
-	}
+	if (off >= pcpur_size)
+		return NULL;
 
-	/* point to new pointer table */
-	_cpu_pda = new_cpu_pda;
+	return virt_to_page(pcpur_ptrs[cpu] + off);
 }
 
-#endif /* CONFIG_SMP && CONFIG_X86_64 */
-
-#ifdef CONFIG_X86_64
-
-/* correctly size the local cpu masks */
-static void __init setup_cpu_local_masks(void)
+static ssize_t __init setup_pcpu_remap(size_t static_size)
 {
-	alloc_bootmem_cpumask_var(&cpu_initialized_mask);
-	alloc_bootmem_cpumask_var(&cpu_callin_mask);
-	alloc_bootmem_cpumask_var(&cpu_callout_mask);
-	alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
-}
-
-#else /* CONFIG_X86_32 */
+	static struct vm_struct vm;
+	size_t ptrs_size, dyn_size;
+	unsigned int cpu;
+	ssize_t ret;
 
-static inline void setup_cpu_local_masks(void)
-{
-}
+	/*
+	 * If large page isn't supported, there's no benefit in doing
+	 * this.  Also, on non-NUMA, embedding is better.
+	 *
+	 * NOTE: disabled for now.
+	 */
+	if (true || !cpu_has_pse || !pcpu_need_numa())
+		return -EINVAL;
 
-#endif /* CONFIG_X86_32 */
+	/*
+	 * Currently supports only single page.  Supporting multiple
+	 * pages won't be too difficult if it ever becomes necessary.
+	 */
+	pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
+			       PERCPU_DYNAMIC_RESERVE);
+	if (pcpur_size > PMD_SIZE) {
+		pr_warning("PERCPU: static data is larger than large page, "
+			   "can't use large page\n");
+		return -EINVAL;
+	}
+	dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;
 
-/*
- * Great future plan:
- * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
- * Always point %gs to its beginning
- */
-void __init setup_per_cpu_areas(void)
-{
-	ssize_t size, old_size;
-	char *ptr;
-	int cpu;
-	unsigned long align = 1;
+	/* allocate pointer array and alloc large pages */
+	ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0]));
+	pcpur_ptrs = alloc_bootmem(ptrs_size);
 
-	/* Setup cpu_pda map */
-	setup_cpu_pda_map();
+	for_each_possible_cpu(cpu) {
+		pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE);
+		if (!pcpur_ptrs[cpu])
+			goto enomem;
 
-	/* Copy section for each CPU (we discard the original) */
-	old_size = PERCPU_ENOUGH_ROOM;
-	align = max_t(unsigned long, PAGE_SIZE, align);
-	size = roundup(old_size, align);
+		/*
+		 * Only use pcpur_size bytes and give back the rest.
+		 *
+		 * Ingo: The 2MB up-rounding bootmem is needed to make
+		 * sure the partial 2MB page is still fully RAM - it's
+		 * not well-specified to have a PAT-incompatible area
+		 * (unmapped RAM, device memory, etc.) in that hole.
+		 */
+		free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size),
+			     PMD_SIZE - pcpur_size);
 
-	pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n",
-		NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids);
+		memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size);
+	}
 
-	pr_info("PERCPU: Allocating %zd bytes of per cpu data\n", size);
+	/* allocate address and map */
+	vm.flags = VM_ALLOC;
+	vm.size = num_possible_cpus() * PMD_SIZE;
+	vm_area_register_early(&vm, PMD_SIZE);
 
 	for_each_possible_cpu(cpu) {
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-		ptr = __alloc_bootmem(size, align,
-				 __pa(MAX_DMA_ADDRESS));
-#else
-		int node = early_cpu_to_node(cpu);
-		if (!node_online(node) || !NODE_DATA(node)) {
-			ptr = __alloc_bootmem(size, align,
-					 __pa(MAX_DMA_ADDRESS));
-			pr_info("cpu %d has no node %d or node-local memory\n",
-				cpu, node);
-			pr_debug("per cpu data for cpu%d at %016lx\n",
-				 cpu, __pa(ptr));
-		} else {
-			ptr = __alloc_bootmem_node(NODE_DATA(node), size, align,
-							__pa(MAX_DMA_ADDRESS));
-			pr_debug("per cpu data for cpu%d on node%d at %016lx\n",
-				cpu, node, __pa(ptr));
-		}
-#endif
-		per_cpu_offset(cpu) = ptr - __per_cpu_start;
-		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+		pmd_t *pmd;
+
+		pmd = populate_extra_pmd((unsigned long)vm.addr
+					 + cpu * PMD_SIZE);
+		set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])),
+				     PAGE_KERNEL_LARGE));
 	}
 
-	/* Setup percpu data maps */
-	setup_per_cpu_maps();
+	/* we're ready, commit */
+	pr_info("PERCPU: Remapped at %p with large pages, static data "
+		"%zu bytes\n", vm.addr, static_size);
 
-	/* Setup node to cpumask map */
-	setup_node_to_cpumask_map();
+	ret = pcpu_setup_first_chunk(pcpur_get_page, static_size,
+				     PERCPU_FIRST_CHUNK_RESERVE, dyn_size,
+				     PMD_SIZE, vm.addr, NULL);
+	goto out_free_ar;
 
-	/* Setup cpu initialized, callin, callout masks */
-	setup_cpu_local_masks();
+enomem:
+	for_each_possible_cpu(cpu)
+		if (pcpur_ptrs[cpu])
+			free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE);
+	ret = -ENOMEM;
+out_free_ar:
+	free_bootmem(__pa(pcpur_ptrs), ptrs_size);
+	return ret;
+}
+#else
+static ssize_t __init setup_pcpu_remap(size_t static_size)
+{
+	return -EINVAL;
 }
-
 #endif
 
-#ifdef X86_64_NUMA
-
 /*
- * Allocate node_to_cpumask_map based on number of available nodes
- * Requires node_possible_map to be valid.
+ * Embedding allocator
  *
- * Note: node_to_cpumask() is not valid until after this is done.
+ * The first chunk is sized to just contain the static area plus
+ * module and dynamic reserves and embedded into linear physical
+ * mapping so that it can use PMD mapping without additional TLB
+ * pressure.
  */
-static void __init setup_node_to_cpumask_map(void)
+static ssize_t __init setup_pcpu_embed(size_t static_size)
 {
-	unsigned int node, num = 0;
-	cpumask_t *map;
-
-	/* setup nr_node_ids if not done yet */
-	if (nr_node_ids == MAX_NUMNODES) {
-		for_each_node_mask(node, node_possible_map)
-			num = node;
-		nr_node_ids = num + 1;
-	}
-
-	/* allocate the map */
-	map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
+	size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
 
-	pr_debug("Node to cpumask map at %p for %d nodes\n",
-		 map, nr_node_ids);
+	/*
+	 * If large page isn't supported, there's no benefit in doing
+	 * this.  Also, embedding allocation doesn't play well with
+	 * NUMA.
+	 */
+	if (!cpu_has_pse || pcpu_need_numa())
+		return -EINVAL;
 
-	/* node_to_cpumask() will now work */
-	node_to_cpumask_map = map;
+	return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE,
+				      reserve - PERCPU_FIRST_CHUNK_RESERVE, -1);
 }
 
-void __cpuinit numa_set_node(int cpu, int node)
-{
-	int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
-
-	if (cpu_pda(cpu) && node != NUMA_NO_NODE)
-		cpu_pda(cpu)->nodenumber = node;
-
-	if (cpu_to_node_map)
-		cpu_to_node_map[cpu] = node;
-
-	else if (per_cpu_offset(cpu))
-		per_cpu(x86_cpu_to_node_map, cpu) = node;
-
-	else
-		pr_debug("Setting node for non-present cpu %d\n", cpu);
-}
+/*
+ * 4k page allocator
+ *
+ * This is the basic allocator.  Static percpu area is allocated
+ * page-by-page and most of initialization is done by the generic
+ * setup function.
+ */
+static struct page **pcpu4k_pages __initdata;
+static int pcpu4k_nr_static_pages __initdata;
 
-void __cpuinit numa_clear_node(int cpu)
+static struct page * __init pcpu4k_get_page(unsigned int cpu, int pageno)
 {
-	numa_set_node(cpu, NUMA_NO_NODE);
+	if (pageno < pcpu4k_nr_static_pages)
+		return pcpu4k_pages[cpu * pcpu4k_nr_static_pages + pageno];
+	return NULL;
 }
 
-#ifndef CONFIG_DEBUG_PER_CPU_MAPS
-
-void __cpuinit numa_add_cpu(int cpu)
+static void __init pcpu4k_populate_pte(unsigned long addr)
 {
-	cpu_set(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+	populate_extra_pte(addr);
 }
 
-void __cpuinit numa_remove_cpu(int cpu)
+static ssize_t __init setup_pcpu_4k(size_t static_size)
 {
-	cpu_clear(cpu, node_to_cpumask_map[cpu_to_node(cpu)]);
-}
+	size_t pages_size;
+	unsigned int cpu;
+	int i, j;
+	ssize_t ret;
 
-#else /* CONFIG_DEBUG_PER_CPU_MAPS */
+	pcpu4k_nr_static_pages = PFN_UP(static_size);
 
-/*
- * --------- debug versions of the numa functions ---------
- */
-static void __cpuinit numa_set_cpumask(int cpu, int enable)
-{
-	int node = cpu_to_node(cpu);
-	cpumask_t *mask;
-	char buf[64];
+	/* unaligned allocations can't be freed, round up to page size */
+	pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * num_possible_cpus()
+			       * sizeof(pcpu4k_pages[0]));
+	pcpu4k_pages = alloc_bootmem(pages_size);
 
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_ERR "node_to_cpumask_map NULL\n");
-		dump_stack();
-		return;
-	}
+	/* allocate and copy */
+	j = 0;
+	for_each_possible_cpu(cpu)
+		for (i = 0; i < pcpu4k_nr_static_pages; i++) {
+			void *ptr;
 
-	mask = &node_to_cpumask_map[node];
-	if (enable)
-		cpu_set(cpu, *mask);
-	else
-		cpu_clear(cpu, *mask);
+			ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE);
+			if (!ptr)
+				goto enomem;
 
-	cpulist_scnprintf(buf, sizeof(buf), mask);
-	printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
-		enable ? "numa_add_cpu" : "numa_remove_cpu", cpu, node, buf);
-}
+			memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE);
+			pcpu4k_pages[j++] = virt_to_page(ptr);
+		}
 
-void __cpuinit numa_add_cpu(int cpu)
-{
-	numa_set_cpumask(cpu, 1);
-}
+	/* we're ready, commit */
+	pr_info("PERCPU: Allocated %d 4k pages, static data %zu bytes\n",
+		pcpu4k_nr_static_pages, static_size);
 
-void __cpuinit numa_remove_cpu(int cpu)
-{
-	numa_set_cpumask(cpu, 0);
+	ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size,
+				     PERCPU_FIRST_CHUNK_RESERVE, -1,
+				     -1, NULL, pcpu4k_populate_pte);
+	goto out_free_ar;
+
+enomem:
+	while (--j >= 0)
+		free_bootmem(__pa(page_address(pcpu4k_pages[j])), PAGE_SIZE);
+	ret = -ENOMEM;
+out_free_ar:
+	free_bootmem(__pa(pcpu4k_pages), pages_size);
+	return ret;
 }
 
-int cpu_to_node(int cpu)
+static inline void setup_percpu_segment(int cpu)
 {
-	if (early_per_cpu_ptr(x86_cpu_to_node_map)) {
-		printk(KERN_WARNING
-			"cpu_to_node(%d): usage too early!\n", cpu);
-		dump_stack();
-		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
-	}
-	return per_cpu(x86_cpu_to_node_map, cpu);
+#ifdef CONFIG_X86_32
+	struct desc_struct gdt;
+
+	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
+			0x2 | DESCTYPE_S, 0x8);
+	gdt.s = 1;
+	write_gdt_entry(get_cpu_gdt_table(cpu),
+			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
+#endif
 }
-EXPORT_SYMBOL(cpu_to_node);
 
 /*
- * Same function as cpu_to_node() but used if called before the
- * per_cpu areas are setup.
+ * Great future plan:
+ * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
+ * Always point %gs to its beginning
  */
-int early_cpu_to_node(int cpu)
+void __init setup_per_cpu_areas(void)
 {
-	if (early_per_cpu_ptr(x86_cpu_to_node_map))
-		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
-
-	if (!per_cpu_offset(cpu)) {
-		printk(KERN_WARNING
-			"early_cpu_to_node(%d): no per_cpu area!\n", cpu);
-		dump_stack();
-		return NUMA_NO_NODE;
-	}
-	return per_cpu(x86_cpu_to_node_map, cpu);
-}
+	size_t static_size = __per_cpu_end - __per_cpu_start;
+	unsigned int cpu;
+	unsigned long delta;
+	size_t pcpu_unit_size;
+	ssize_t ret;
 
+	pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n",
+		NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids);
 
-/* empty cpumask */
-static const cpumask_t cpu_mask_none;
+	/*
+	 * Allocate percpu area.  If PSE is supported, try to make use
+	 * of large page mappings.  Please read comments on top of
+	 * each allocator for details.
+	 */
+	ret = setup_pcpu_remap(static_size);
+	if (ret < 0)
+		ret = setup_pcpu_embed(static_size);
+	if (ret < 0)
+		ret = setup_pcpu_4k(static_size);
+	if (ret < 0)
+		panic("cannot allocate static percpu area (%zu bytes, err=%zd)",
+		      static_size, ret);
 
-/*
- * Returns a pointer to the bitmask of CPUs on Node 'node'.
- */
-const cpumask_t *cpumask_of_node(int node)
-{
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_WARNING
-			"cpumask_of_node(%d): no node_to_cpumask_map!\n",
-			node);
-		dump_stack();
-		return (const cpumask_t *)&cpu_online_map;
-	}
-	if (node >= nr_node_ids) {
-		printk(KERN_WARNING
-			"cpumask_of_node(%d): node > nr_node_ids(%d)\n",
-			node, nr_node_ids);
-		dump_stack();
-		return &cpu_mask_none;
-	}
-	return &node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(cpumask_of_node);
+	pcpu_unit_size = ret;
 
-/*
- * Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used.  The
- * node_to_cpumask_ptr function should be used whenever possible.
- */
-cpumask_t node_to_cpumask(int node)
-{
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_WARNING
-			"node_to_cpumask(%d): no node_to_cpumask_map!\n", node);
-		dump_stack();
-		return cpu_online_map;
-	}
-	if (node >= nr_node_ids) {
-		printk(KERN_WARNING
-			"node_to_cpumask(%d): node > nr_node_ids(%d)\n",
-			node, nr_node_ids);
-		dump_stack();
-		return cpu_mask_none;
+	/* alrighty, percpu areas up and running */
+	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+	for_each_possible_cpu(cpu) {
+		per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
+		per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
+		per_cpu(cpu_number, cpu) = cpu;
+		setup_percpu_segment(cpu);
+		setup_stack_canary_segment(cpu);
+		/*
+		 * Copy data used in early init routines from the
+		 * initial arrays to the per cpu data areas.  These
+		 * arrays then become expendable and the *_early_ptr's
+		 * are zeroed indicating that the static arrays are
+		 * gone.
+		 */
+#ifdef CONFIG_X86_LOCAL_APIC
+		per_cpu(x86_cpu_to_apicid, cpu) =
+			early_per_cpu_map(x86_cpu_to_apicid, cpu);
+		per_cpu(x86_bios_cpu_apicid, cpu) =
+			early_per_cpu_map(x86_bios_cpu_apicid, cpu);
+#endif
+#ifdef CONFIG_X86_64
+		per_cpu(irq_stack_ptr, cpu) =
+			per_cpu(irq_stack_union.irq_stack, cpu) +
+			IRQ_STACK_SIZE - 64;
+#ifdef CONFIG_NUMA
+		per_cpu(x86_cpu_to_node_map, cpu) =
+			early_per_cpu_map(x86_cpu_to_node_map, cpu);
+#endif
+#endif
+		/*
+		 * Up to this point, the boot CPU has been using .data.init
+		 * area.  Reload any changed state for the boot CPU.
+		 */
+		if (cpu == boot_cpu_id)
+			switch_to_new_gdt(cpu);
 	}
-	return node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(node_to_cpumask);
-
-/*
- * --------- end of debug versions of the numa functions ---------
- */
 
-#endif /* CONFIG_DEBUG_PER_CPU_MAPS */
+	/* indicate the early static arrays will soon be gone */
+#ifdef CONFIG_X86_LOCAL_APIC
+	early_per_cpu_ptr(x86_cpu_to_apicid) = NULL;
+	early_per_cpu_ptr(x86_bios_cpu_apicid) = NULL;
+#endif
+#if defined(CONFIG_X86_64) && defined(CONFIG_NUMA)
+	early_per_cpu_ptr(x86_cpu_to_node_map) = NULL;
+#endif
 
-#endif /* X86_64_NUMA */
+	/* Setup node to cpumask map */
+	setup_node_to_cpumask_map();
 
+	/* Setup cpu initialized, callin, callout masks */
+	setup_cpu_local_masks();
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/signal.c linux-libre-2.6.30-gnu1/arch/x86/kernel/signal.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/signal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/signal.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,27 +50,23 @@
 # define FIX_EFLAGS	__FIX_EFLAGS
 #endif
 
-#define COPY(x)			{		\
-	err |= __get_user(regs->x, &sc->x);	\
-}
+#define COPY(x)			do {			\
+	get_user_ex(regs->x, &sc->x);			\
+} while (0)
 
-#define COPY_SEG(seg)		{			\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		regs->seg = tmp;			\
-}
+#define GET_SEG(seg)		({			\
+	unsigned short tmp;				\
+	get_user_ex(tmp, &sc->seg);			\
+	tmp;						\
+})
 
-#define COPY_SEG_CPL3(seg)	{			\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		regs->seg = tmp | 3;			\
-}
+#define COPY_SEG(seg)		do {			\
+	regs->seg = GET_SEG(seg);			\
+} while (0)
 
-#define GET_SEG(seg)		{			\
-		unsigned short tmp;			\
-		err |= __get_user(tmp, &sc->seg);	\
-		loadsegment(seg, tmp);			\
-}
+#define COPY_SEG_CPL3(seg)	do {			\
+	regs->seg = GET_SEG(seg) | 3;			\
+} while (0)
 
 static int
 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
@@ -83,45 +79,49 @@ restore_sigcontext(struct pt_regs *regs,
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
+	get_user_try {
+
 #ifdef CONFIG_X86_32
-	GET_SEG(gs);
-	COPY_SEG(fs);
-	COPY_SEG(es);
-	COPY_SEG(ds);
+		set_user_gs(regs, GET_SEG(gs));
+		COPY_SEG(fs);
+		COPY_SEG(es);
+		COPY_SEG(ds);
 #endif /* CONFIG_X86_32 */
 
-	COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
-	COPY(dx); COPY(cx); COPY(ip);
+		COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
+		COPY(dx); COPY(cx); COPY(ip);
 
 #ifdef CONFIG_X86_64
-	COPY(r8);
-	COPY(r9);
-	COPY(r10);
-	COPY(r11);
-	COPY(r12);
-	COPY(r13);
-	COPY(r14);
-	COPY(r15);
+		COPY(r8);
+		COPY(r9);
+		COPY(r10);
+		COPY(r11);
+		COPY(r12);
+		COPY(r13);
+		COPY(r14);
+		COPY(r15);
 #endif /* CONFIG_X86_64 */
 
 #ifdef CONFIG_X86_32
-	COPY_SEG_CPL3(cs);
-	COPY_SEG_CPL3(ss);
+		COPY_SEG_CPL3(cs);
+		COPY_SEG_CPL3(ss);
 #else /* !CONFIG_X86_32 */
-	/* Kernel saves and restores only the CS segment register on signals,
-	 * which is the bare minimum needed to allow mixed 32/64-bit code.
-	 * App's signal handler can save/restore other segments if needed. */
-	COPY_SEG_CPL3(cs);
+		/* Kernel saves and restores only the CS segment register on signals,
+		 * which is the bare minimum needed to allow mixed 32/64-bit code.
+		 * App's signal handler can save/restore other segments if needed. */
+		COPY_SEG_CPL3(cs);
 #endif /* CONFIG_X86_32 */
 
-	err |= __get_user(tmpflags, &sc->flags);
-	regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
-	regs->orig_ax = -1;		/* disable syscall checks */
+		get_user_ex(tmpflags, &sc->flags);
+		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
+		regs->orig_ax = -1;		/* disable syscall checks */
 
-	err |= __get_user(buf, &sc->fpstate);
-	err |= restore_i387_xstate(buf);
+		get_user_ex(buf, &sc->fpstate);
+		err |= restore_i387_xstate(buf);
+
+		get_user_ex(*pax, &sc->ax);
+	} get_user_catch(err);
 
-	err |= __get_user(*pax, &sc->ax);
 	return err;
 }
 
@@ -131,57 +131,55 @@ setup_sigcontext(struct sigcontext __use
 {
 	int err = 0;
 
-#ifdef CONFIG_X86_32
-	{
-		unsigned int tmp;
+	put_user_try {
 
-		savesegment(gs, tmp);
-		err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
-	}
-	err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
-	err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
-	err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
+#ifdef CONFIG_X86_32
+		put_user_ex(get_user_gs(regs), (unsigned int __user *)&sc->gs);
+		put_user_ex(regs->fs, (unsigned int __user *)&sc->fs);
+		put_user_ex(regs->es, (unsigned int __user *)&sc->es);
+		put_user_ex(regs->ds, (unsigned int __user *)&sc->ds);
 #endif /* CONFIG_X86_32 */
 
-	err |= __put_user(regs->di, &sc->di);
-	err |= __put_user(regs->si, &sc->si);
-	err |= __put_user(regs->bp, &sc->bp);
-	err |= __put_user(regs->sp, &sc->sp);
-	err |= __put_user(regs->bx, &sc->bx);
-	err |= __put_user(regs->dx, &sc->dx);
-	err |= __put_user(regs->cx, &sc->cx);
-	err |= __put_user(regs->ax, &sc->ax);
+		put_user_ex(regs->di, &sc->di);
+		put_user_ex(regs->si, &sc->si);
+		put_user_ex(regs->bp, &sc->bp);
+		put_user_ex(regs->sp, &sc->sp);
+		put_user_ex(regs->bx, &sc->bx);
+		put_user_ex(regs->dx, &sc->dx);
+		put_user_ex(regs->cx, &sc->cx);
+		put_user_ex(regs->ax, &sc->ax);
 #ifdef CONFIG_X86_64
-	err |= __put_user(regs->r8, &sc->r8);
-	err |= __put_user(regs->r9, &sc->r9);
-	err |= __put_user(regs->r10, &sc->r10);
-	err |= __put_user(regs->r11, &sc->r11);
-	err |= __put_user(regs->r12, &sc->r12);
-	err |= __put_user(regs->r13, &sc->r13);
-	err |= __put_user(regs->r14, &sc->r14);
-	err |= __put_user(regs->r15, &sc->r15);
+		put_user_ex(regs->r8, &sc->r8);
+		put_user_ex(regs->r9, &sc->r9);
+		put_user_ex(regs->r10, &sc->r10);
+		put_user_ex(regs->r11, &sc->r11);
+		put_user_ex(regs->r12, &sc->r12);
+		put_user_ex(regs->r13, &sc->r13);
+		put_user_ex(regs->r14, &sc->r14);
+		put_user_ex(regs->r15, &sc->r15);
 #endif /* CONFIG_X86_64 */
 
-	err |= __put_user(current->thread.trap_no, &sc->trapno);
-	err |= __put_user(current->thread.error_code, &sc->err);
-	err |= __put_user(regs->ip, &sc->ip);
+		put_user_ex(current->thread.trap_no, &sc->trapno);
+		put_user_ex(current->thread.error_code, &sc->err);
+		put_user_ex(regs->ip, &sc->ip);
 #ifdef CONFIG_X86_32
-	err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
-	err |= __put_user(regs->flags, &sc->flags);
-	err |= __put_user(regs->sp, &sc->sp_at_signal);
-	err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
+		put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
+		put_user_ex(regs->flags, &sc->flags);
+		put_user_ex(regs->sp, &sc->sp_at_signal);
+		put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
 #else /* !CONFIG_X86_32 */
-	err |= __put_user(regs->flags, &sc->flags);
-	err |= __put_user(regs->cs, &sc->cs);
-	err |= __put_user(0, &sc->gs);
-	err |= __put_user(0, &sc->fs);
+		put_user_ex(regs->flags, &sc->flags);
+		put_user_ex(regs->cs, &sc->cs);
+		put_user_ex(0, &sc->gs);
+		put_user_ex(0, &sc->fs);
 #endif /* CONFIG_X86_32 */
 
-	err |= __put_user(fpstate, &sc->fpstate);
+		put_user_ex(fpstate, &sc->fpstate);
 
-	/* non-iBCS2 extensions.. */
-	err |= __put_user(mask, &sc->oldmask);
-	err |= __put_user(current->thread.cr2, &sc->cr2);
+		/* non-iBCS2 extensions.. */
+		put_user_ex(mask, &sc->oldmask);
+		put_user_ex(current->thread.cr2, &sc->cr2);
+	} put_user_catch(err);
 
 	return err;
 }
@@ -189,6 +187,77 @@ setup_sigcontext(struct sigcontext __use
 /*
  * Set up a signal frame.
  */
+
+/*
+ * Determine which stack to use..
+ */
+static unsigned long align_sigframe(unsigned long sp)
+{
+#ifdef CONFIG_X86_32
+	/*
+	 * Align the stack pointer according to the i386 ABI,
+	 * i.e. so that on function entry ((sp + 4) & 15) == 0.
+	 */
+	sp = ((sp + 4) & -16ul) - 4;
+#else /* !CONFIG_X86_32 */
+	sp = round_down(sp, 16) - 8;
+#endif
+	return sp;
+}
+
+static inline void __user *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
+	     void __user **fpstate)
+{
+	/* Default to using normal stack */
+	unsigned long sp = regs->sp;
+	int onsigstack = on_sig_stack(sp);
+
+#ifdef CONFIG_X86_64
+	/* redzone */
+	sp -= 128;
+#endif /* CONFIG_X86_64 */
+
+	if (!onsigstack) {
+		/* This is the X/Open sanctioned signal stack switching.  */
+		if (ka->sa.sa_flags & SA_ONSTACK) {
+			if (current->sas_ss_size)
+				sp = current->sas_ss_sp + current->sas_ss_size;
+		} else {
+#ifdef CONFIG_X86_32
+			/* This is the legacy signal stack switching. */
+			if ((regs->ss & 0xffff) != __USER_DS &&
+				!(ka->sa.sa_flags & SA_RESTORER) &&
+					ka->sa.sa_restorer)
+				sp = (unsigned long) ka->sa.sa_restorer;
+#endif /* CONFIG_X86_32 */
+		}
+	}
+
+	if (used_math()) {
+		sp -= sig_xstate_size;
+#ifdef CONFIG_X86_64
+		sp = round_down(sp, 64);
+#endif /* CONFIG_X86_64 */
+		*fpstate = (void __user *)sp;
+	}
+
+	sp = align_sigframe(sp - frame_size);
+
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (onsigstack && !likely(on_sig_stack(sp)))
+		return (void __user *)-1L;
+
+	/* save i387 state */
+	if (used_math() && save_i387_xstate(*fpstate) < 0)
+		return (void __user *)-1L;
+
+	return (void __user *)sp;
+}
+
 #ifdef CONFIG_X86_32
 static const struct {
 	u16 poplmovl;
@@ -212,54 +281,6 @@ static const struct {
 	0
 };
 
-/*
- * Determine which stack to use..
- */
-static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
-	     void **fpstate)
-{
-	unsigned long sp;
-
-	/* Default to using normal stack */
-	sp = regs->sp;
-
-	/*
-	 * If we are on the alternate signal stack and would overflow it, don't.
-	 * Return an always-bogus address instead so we will die with SIGSEGV.
-	 */
-	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
-		return (void __user *) -1L;
-
-	/* This is the X/Open sanctioned signal stack switching.  */
-	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (sas_ss_flags(sp) == 0)
-			sp = current->sas_ss_sp + current->sas_ss_size;
-	} else {
-		/* This is the legacy signal stack switching. */
-		if ((regs->ss & 0xffff) != __USER_DS &&
-			!(ka->sa.sa_flags & SA_RESTORER) &&
-				ka->sa.sa_restorer)
-			sp = (unsigned long) ka->sa.sa_restorer;
-	}
-
-	if (used_math()) {
-		sp = sp - sig_xstate_size;
-		*fpstate = (struct _fpstate *) sp;
-		if (save_i387_xstate(*fpstate) < 0)
-			return (void __user *)-1L;
-	}
-
-	sp -= frame_size;
-	/*
-	 * Align the stack pointer according to the i386 ABI,
-	 * i.e. so that on function entry ((sp + 4) & 15) == 0.
-	 */
-	sp = ((sp + 4) & -16ul) - 4;
-
-	return (void __user *) sp;
-}
-
 static int
 __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 	      struct pt_regs *regs)
@@ -336,43 +357,41 @@ static int __setup_rt_frame(int sig, str
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		return -EFAULT;
 
-	err |= __put_user(sig, &frame->sig);
-	err |= __put_user(&frame->info, &frame->pinfo);
-	err |= __put_user(&frame->uc, &frame->puc);
-	err |= copy_siginfo_to_user(&frame->info, info);
-	if (err)
-		return -EFAULT;
+	put_user_try {
+		put_user_ex(sig, &frame->sig);
+		put_user_ex(&frame->info, &frame->pinfo);
+		put_user_ex(&frame->uc, &frame->puc);
+		err |= copy_siginfo_to_user(&frame->info, info);
 
-	/* Create the ucontext.  */
-	if (cpu_has_xsave)
-		err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
-	else
-		err |= __put_user(0, &frame->uc.uc_flags);
-	err |= __put_user(0, &frame->uc.uc_link);
-	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->sp),
-			  &frame->uc.uc_stack.ss_flags);
-	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
-				regs, set->sig[0]);
-	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
-	if (err)
-		return -EFAULT;
+		/* Create the ucontext.  */
+		if (cpu_has_xsave)
+			put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
+		else
+			put_user_ex(0, &frame->uc.uc_flags);
+		put_user_ex(0, &frame->uc.uc_link);
+		put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+		put_user_ex(sas_ss_flags(regs->sp),
+			    &frame->uc.uc_stack.ss_flags);
+		put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+		err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
+					regs, set->sig[0]);
+		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-	/* Set up to return from userspace.  */
-	restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
-	if (ka->sa.sa_flags & SA_RESTORER)
-		restorer = ka->sa.sa_restorer;
-	err |= __put_user(restorer, &frame->pretcode);
+		/* Set up to return from userspace.  */
+		restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
+		if (ka->sa.sa_flags & SA_RESTORER)
+			restorer = ka->sa.sa_restorer;
+		put_user_ex(restorer, &frame->pretcode);
 
-	/*
-	 * This is movl $__NR_rt_sigreturn, %ax ; int $0x80
-	 *
-	 * WE DO NOT USE IT ANY MORE! It's only left here for historical
-	 * reasons and because gdb uses it as a signature to notice
-	 * signal handler stack frames.
-	 */
-	err |= __put_user(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
+		/*
+		 * This is movl $__NR_rt_sigreturn, %ax ; int $0x80
+		 *
+		 * WE DO NOT USE IT ANY MORE! It's only left here for historical
+		 * reasons and because gdb uses it as a signature to notice
+		 * signal handler stack frames.
+		 */
+		put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
+	} put_user_catch(err);
 
 	if (err)
 		return -EFAULT;
@@ -392,24 +411,6 @@ static int __setup_rt_frame(int sig, str
 	return 0;
 }
 #else /* !CONFIG_X86_32 */
-/*
- * Determine which stack to use..
- */
-static void __user *
-get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size)
-{
-	/* Default to using normal stack - redzone*/
-	sp -= 128;
-
-	/* This is the X/Open sanctioned signal stack switching.  */
-	if (ka->sa.sa_flags & SA_ONSTACK) {
-		if (sas_ss_flags(sp) == 0)
-			sp = current->sas_ss_sp + current->sas_ss_size;
-	}
-
-	return (void __user *)round_down(sp - size, 64);
-}
-
 static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			    sigset_t *set, struct pt_regs *regs)
 {
@@ -418,15 +419,7 @@ static int __setup_rt_frame(int sig, str
 	int err = 0;
 	struct task_struct *me = current;
 
-	if (used_math()) {
-		fp = get_stack(ka, regs->sp, sig_xstate_size);
-		frame = (void __user *)round_down(
-			(unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
-
-		if (save_i387_xstate(fp) < 0)
-			return -EFAULT;
-	} else
-		frame = get_stack(ka, regs->sp, sizeof(struct rt_sigframe)) - 8;
+	frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp);
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		return -EFAULT;
@@ -436,28 +429,30 @@ static int __setup_rt_frame(int sig, str
 			return -EFAULT;
 	}
 
-	/* Create the ucontext.  */
-	if (cpu_has_xsave)
-		err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags);
-	else
-		err |= __put_user(0, &frame->uc.uc_flags);
-	err |= __put_user(0, &frame->uc.uc_link);
-	err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(regs->sp),
-			  &frame->uc.uc_stack.ss_flags);
-	err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
-	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+	put_user_try {
+		/* Create the ucontext.  */
+		if (cpu_has_xsave)
+			put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
+		else
+			put_user_ex(0, &frame->uc.uc_flags);
+		put_user_ex(0, &frame->uc.uc_link);
+		put_user_ex(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+		put_user_ex(sas_ss_flags(regs->sp),
+			    &frame->uc.uc_stack.ss_flags);
+		put_user_ex(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+		err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
+		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
-	/* x86-64 should always use SA_RESTORER. */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
-	} else {
-		/* could use a vstub here */
-		return -EFAULT;
-	}
+		/* Set up to return from userspace.  If provided, use a stub
+		   already in userspace.  */
+		/* x86-64 should always use SA_RESTORER. */
+		if (ka->sa.sa_flags & SA_RESTORER) {
+			put_user_ex(ka->sa.sa_restorer, &frame->pretcode);
+		} else {
+			/* could use a vstub here */
+			err |= -EFAULT;
+		}
+	} put_user_catch(err);
 
 	if (err)
 		return -EFAULT;
@@ -509,31 +504,41 @@ sys_sigaction(int sig, const struct old_
 	      struct old_sigaction __user *oact)
 {
 	struct k_sigaction new_ka, old_ka;
-	int ret;
+	int ret = 0;
 
 	if (act) {
 		old_sigset_t mask;
 
-		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 			return -EFAULT;
 
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
+		get_user_try {
+			get_user_ex(new_ka.sa.sa_handler, &act->sa_handler);
+			get_user_ex(new_ka.sa.sa_flags, &act->sa_flags);
+			get_user_ex(mask, &act->sa_mask);
+			get_user_ex(new_ka.sa.sa_restorer, &act->sa_restorer);
+		} get_user_catch(ret);
+
+		if (ret)
+			return -EFAULT;
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 			return -EFAULT;
 
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+		put_user_try {
+			put_user_ex(old_ka.sa.sa_handler, &oact->sa_handler);
+			put_user_ex(old_ka.sa.sa_flags, &oact->sa_flags);
+			put_user_ex(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+			put_user_ex(old_ka.sa.sa_restorer, &oact->sa_restorer);
+		} put_user_catch(ret);
+
+		if (ret)
+			return -EFAULT;
 	}
 
 	return ret;
@@ -541,14 +546,9 @@ sys_sigaction(int sig, const struct old_
 #endif /* CONFIG_X86_32 */
 
 #ifdef CONFIG_X86_32
-asmlinkage int sys_sigaltstack(unsigned long bx)
+int sys_sigaltstack(struct pt_regs *regs)
 {
-	/*
-	 * This is needed to make gcc realize it doesn't own the
-	 * "struct pt_regs"
-	 */
-	struct pt_regs *regs = (struct pt_regs *)&bx;
-	const stack_t __user *uss = (const stack_t __user *)bx;
+	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);
@@ -566,14 +566,12 @@ sys_sigaltstack(const stack_t __user *us
  * Do a signal return; undo the signal stack.
  */
 #ifdef CONFIG_X86_32
-asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
+unsigned long sys_sigreturn(struct pt_regs *regs)
 {
 	struct sigframe __user *frame;
-	struct pt_regs *regs;
 	unsigned long ax;
 	sigset_t set;
 
-	regs = (struct pt_regs *) &__unused;
 	frame = (struct sigframe __user *)(regs->sp - 8);
 
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -600,7 +598,7 @@ badframe:
 }
 #endif /* CONFIG_X86_32 */
 
-static long do_rt_sigreturn(struct pt_regs *regs)
+long sys_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
 	unsigned long ax;
@@ -631,25 +629,6 @@ badframe:
 	return 0;
 }
 
-#ifdef CONFIG_X86_32
-/*
- * Note: do not pass in pt_regs directly as with tail-call optimization
- * GCC will incorrectly stomp on the caller's frame and corrupt user-space
- * register state:
- */
-asmlinkage int sys_rt_sigreturn(unsigned long __unused)
-{
-	struct pt_regs *regs = (struct pt_regs *)&__unused;
-
-	return do_rt_sigreturn(regs);
-}
-#else /* !CONFIG_X86_32 */
-asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
-{
-	return do_rt_sigreturn(regs);
-}
-#endif /* CONFIG_X86_32 */
-
 /*
  * OK, we're invoking a handler:
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/smpboot.c linux-libre-2.6.30-gnu1/arch/x86/kernel/smpboot.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/smpboot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/smpboot.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *	x86 SMP booting functions
  *
  *	(c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk>
- *	(c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
+ *	(c) 1998, 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
  *	Copyright 2001 Andi Kleen, SuSE Labs.
  *
  *	Much of the core SMP work is based on previous work by Thomas Radke, to
@@ -53,7 +53,6 @@
 #include <asm/nmi.h>
 #include <asm/irq.h>
 #include <asm/idle.h>
-#include <asm/smp.h>
 #include <asm/trampoline.h>
 #include <asm/cpu.h>
 #include <asm/numa.h>
@@ -61,13 +60,12 @@
 #include <asm/tlbflush.h>
 #include <asm/mtrr.h>
 #include <asm/vmi.h>
-#include <asm/genapic.h>
+#include <asm/apic.h>
 #include <asm/setup.h>
+#include <asm/uv/uv.h>
 #include <linux/mc146818rtc.h>
 
-#include <mach_apic.h>
-#include <mach_wakecpu.h>
-#include <smpboot_hooks.h>
+#include <asm/smpboot_hooks.h>
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
@@ -103,29 +101,20 @@ EXPORT_SYMBOL(smp_num_siblings);
 DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID;
 
 /* representing HT siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
 EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
 
 /* representing HT and core siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
 EXPORT_PER_CPU_SYMBOL(cpu_core_map);
 
 /* Per CPU bogomips and other parameters */
 DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
-static atomic_t init_deasserted;
-
-
-/* Set if we find a B stepping CPU */
-static int __cpuinitdata smp_b_stepping;
+atomic_t init_deasserted;
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
-
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly =
-				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
-EXPORT_SYMBOL(node_to_cpumask_map);
 /* which node each logical CPU is on */
 int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
 EXPORT_SYMBOL(cpu_to_node_map);
@@ -134,7 +123,7 @@ EXPORT_SYMBOL(cpu_to_node_map);
 static void map_cpu_to_node(int cpu, int node)
 {
 	printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
-	cpumask_set_cpu(cpu, &node_to_cpumask_map[node]);
+	cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
 	cpu_to_node_map[cpu] = node;
 }
 
@@ -145,7 +134,7 @@ static void unmap_cpu_to_node(int cpu)
 
 	printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
 	for (node = 0; node < MAX_NUMNODES; node++)
-		cpumask_clear_cpu(cpu, &node_to_cpumask_map[node]);
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
 	cpu_to_node_map[cpu] = 0;
 }
 #else /* !(CONFIG_NUMA && CONFIG_X86_32) */
@@ -163,7 +152,7 @@ static void map_cpu_to_logical_apicid(vo
 {
 	int cpu = smp_processor_id();
 	int apicid = logical_smp_processor_id();
-	int node = apicid_to_node(apicid);
+	int node = apic->apicid_to_node(apicid);
 
 	if (!node_online(node))
 		node = first_online_node;
@@ -196,7 +185,8 @@ static void __cpuinit smp_callin(void)
 	 * our local APIC.  We have to wait for the IPI or we'll
 	 * lock up on an APIC access.
 	 */
-	wait_for_init_deassert(&init_deasserted);
+	if (apic->wait_for_init_deassert)
+		apic->wait_for_init_deassert(&init_deasserted);
 
 	/*
 	 * (This works even if the APIC is not enabled.)
@@ -243,7 +233,8 @@ static void __cpuinit smp_callin(void)
 	 */
 
 	pr_debug("CALLIN, before setup_local_APIC().\n");
-	smp_callin_clear_local_apic();
+	if (apic->smp_callin_clear_local_apic)
+		apic->smp_callin_clear_local_apic();
 	setup_local_APIC();
 	end_local_APIC_setup();
 	map_cpu_to_logical_apicid();
@@ -271,8 +262,6 @@ static void __cpuinit smp_callin(void)
 	cpumask_set_cpu(cpuid, cpu_callin_mask);
 }
 
-static int __cpuinitdata unsafe_smp;
-
 /*
  * Activate a secondary processor.
  */
@@ -307,7 +296,7 @@ notrace static void __cpuinit start_seco
 	__flush_tlb_all();
 #endif
 
-	/* This must be done before setting cpu_online_map */
+	/* This must be done before setting cpu_online_mask */
 	set_cpu_sibling_map(raw_smp_processor_id());
 	wmb();
 
@@ -340,75 +329,22 @@ notrace static void __cpuinit start_seco
 	cpu_idle();
 }
 
-static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* In this case, llc_shared_map is a pointer to a cpumask. */
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+				    const struct cpuinfo_x86 *src)
 {
-	/*
-	 * Mask B, Pentium, but not Pentium MMX
-	 */
-	if (c->x86_vendor == X86_VENDOR_INTEL &&
-	    c->x86 == 5 &&
-	    c->x86_mask >= 1 && c->x86_mask <= 4 &&
-	    c->x86_model <= 3)
-		/*
-		 * Remember we have B step Pentia with bugs
-		 */
-		smp_b_stepping = 1;
-
-	/*
-	 * Certain Athlons might work (for various values of 'work') in SMP
-	 * but they are not certified as MP capable.
-	 */
-	if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
-
-		if (num_possible_cpus() == 1)
-			goto valid_k7;
-
-		/* Athlon 660/661 is valid. */
-		if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
-		    (c->x86_mask == 1)))
-			goto valid_k7;
-
-		/* Duron 670 is valid */
-		if ((c->x86_model == 7) && (c->x86_mask == 0))
-			goto valid_k7;
-
-		/*
-		 * Athlon 662, Duron 671, and Athlon >model 7 have capability
-		 * bit. It's worth noting that the A5 stepping (662) of some
-		 * Athlon XP's have the MP bit set.
-		 * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
-		 * more.
-		 */
-		if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
-		    ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
-		     (c->x86_model > 7))
-			if (cpu_has_mp)
-				goto valid_k7;
-
-		/* If we get here, not a certified SMP capable AMD system. */
-		unsafe_smp = 1;
-	}
-
-valid_k7:
-	;
+	struct cpumask *llc = dst->llc_shared_map;
+	*dst = *src;
+	dst->llc_shared_map = llc;
 }
-
-static void __cpuinit smp_checks(void)
+#else
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+				    const struct cpuinfo_x86 *src)
 {
-	if (smp_b_stepping)
-		printk(KERN_WARNING "WARNING: SMP operation may be unreliable"
-				    "with B stepping processors.\n");
-
-	/*
-	 * Don't taint if we are running SMP kernel on a single non-MP
-	 * approved Athlon
-	 */
-	if (unsafe_smp && num_online_cpus() > 1) {
-		printk(KERN_INFO "WARNING: This combination of AMD"
-			"processors is not suitable for SMP.\n");
-		add_taint(TAINT_UNSAFE_SMP);
-	}
+	*dst = *src;
 }
+#endif /* CONFIG_CPUMASK_OFFSTACK */
 
 /*
  * The bootstrap kernel entry code has set these up. Save them for
@@ -419,11 +355,10 @@ void __cpuinit smp_store_cpu_info(int id
 {
 	struct cpuinfo_x86 *c = &cpu_data(id);
 
-	*c = boot_cpu_data;
+	copy_cpuinfo_x86(c, &boot_cpu_data);
 	c->cpu_index = id;
 	if (id != 0)
 		identify_secondary_cpu(c);
-	smp_apply_quirks(c);
 }
 
 
@@ -444,15 +379,15 @@ void __cpuinit set_cpu_sibling_map(int c
 				cpumask_set_cpu(cpu, cpu_sibling_mask(i));
 				cpumask_set_cpu(i, cpu_core_mask(cpu));
 				cpumask_set_cpu(cpu, cpu_core_mask(i));
-				cpumask_set_cpu(i, &c->llc_shared_map);
-				cpumask_set_cpu(cpu, &o->llc_shared_map);
+				cpumask_set_cpu(i, c->llc_shared_map);
+				cpumask_set_cpu(cpu, o->llc_shared_map);
 			}
 		}
 	} else {
 		cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
 	}
 
-	cpumask_set_cpu(cpu, &c->llc_shared_map);
+	cpumask_set_cpu(cpu, c->llc_shared_map);
 
 	if (current_cpu_data.x86_max_cores == 1) {
 		cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu));
@@ -463,8 +398,8 @@ void __cpuinit set_cpu_sibling_map(int c
 	for_each_cpu(i, cpu_sibling_setup_mask) {
 		if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
 		    per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
-			cpumask_set_cpu(i, &c->llc_shared_map);
-			cpumask_set_cpu(cpu, &cpu_data(i).llc_shared_map);
+			cpumask_set_cpu(i, c->llc_shared_map);
+			cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map);
 		}
 		if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
 			cpumask_set_cpu(i, cpu_core_mask(cpu));
@@ -502,12 +437,7 @@ const struct cpumask *cpu_coregroup_mask
 	if (sched_mc_power_savings || sched_smt_power_savings)
 		return cpu_core_mask(cpu);
 	else
-		return &c->llc_shared_map;
-}
-
-cpumask_t cpu_coregroup_map(int cpu)
-{
-	return *cpu_coregroup_mask(cpu);
+		return c->llc_shared_map;
 }
 
 static void impress_friends(void)
@@ -583,7 +513,7 @@ wakeup_secondary_cpu_via_nmi(int logical
 	/* Target chip */
 	/* Boot on the stack */
 	/* Kick the second */
-	apic_icr_write(APIC_DM_NMI | APIC_DEST_LOGICAL, logical_apicid);
+	apic_icr_write(APIC_DM_NMI | apic->dest_logical, logical_apicid);
 
 	pr_debug("Waiting for send to finish...\n");
 	send_status = safe_apic_wait_icr_idle();
@@ -614,12 +544,6 @@ wakeup_secondary_cpu_via_init(int phys_a
 	unsigned long send_status, accept_status = 0;
 	int maxlvt, num_starts, j;
 
-	if (get_uv_system_type() == UV_NON_UNIQUE_APIC) {
-		send_status = uv_wakeup_secondary(phys_apicid, start_eip);
-		atomic_set(&init_deasserted, 1);
-		return send_status;
-	}
-
 	maxlvt = lapic_get_maxlvt();
 
 	/*
@@ -745,78 +669,23 @@ static void __cpuinit do_fork_idle(struc
 	complete(&c_idle->done);
 }
 
-#ifdef CONFIG_X86_64
-
-/* __ref because it's safe to call free_bootmem when after_bootmem == 0. */
-static void __ref free_bootmem_pda(struct x8664_pda *oldpda)
-{
-	if (!after_bootmem)
-		free_bootmem((unsigned long)oldpda, sizeof(*oldpda));
-}
-
-/*
- * Allocate node local memory for the AP pda.
- *
- * Must be called after the _cpu_pda pointer table is initialized.
- */
-int __cpuinit get_local_pda(int cpu)
-{
-	struct x8664_pda *oldpda, *newpda;
-	unsigned long size = sizeof(struct x8664_pda);
-	int node = cpu_to_node(cpu);
-
-	if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem)
-		return 0;
-
-	oldpda = cpu_pda(cpu);
-	newpda = kmalloc_node(size, GFP_ATOMIC, node);
-	if (!newpda) {
-		printk(KERN_ERR "Could not allocate node local PDA "
-			"for CPU %d on node %d\n", cpu, node);
-
-		if (oldpda)
-			return 0;	/* have a usable pda */
-		else
-			return -1;
-	}
-
-	if (oldpda) {
-		memcpy(newpda, oldpda, size);
-		free_bootmem_pda(oldpda);
-	}
-
-	newpda->in_bootmem = 0;
-	cpu_pda(cpu) = newpda;
-	return 0;
-}
-#endif /* CONFIG_X86_64 */
-
-static int __cpuinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
- * Returns zero if CPU booted OK, else error code from wakeup_secondary_cpu.
+ * Returns zero if CPU booted OK, else error code from
+ * ->wakeup_secondary_cpu.
  */
+static int __cpuinit do_boot_cpu(int apicid, int cpu)
 {
 	unsigned long boot_error = 0;
-	int timeout;
 	unsigned long start_ip;
-	unsigned short nmi_high = 0, nmi_low = 0;
+	int timeout;
 	struct create_idle c_idle = {
-		.cpu = cpu,
-		.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+		.cpu	= cpu,
+		.done	= COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
 	};
-	INIT_WORK(&c_idle.work, do_fork_idle);
 
-#ifdef CONFIG_X86_64
-	/* Allocate node local memory for AP pdas */
-	if (cpu > 0) {
-		boot_error = get_local_pda(cpu);
-		if (boot_error)
-			goto restore_state;
-			/* if can't get pda memory, can't start cpu */
-	}
-#endif
+	INIT_WORK(&c_idle.work, do_fork_idle);
 
 	alternatives_smp_switch(1);
 
@@ -847,14 +716,16 @@ static int __cpuinit do_boot_cpu(int api
 
 	set_idle_for_cpu(cpu, c_idle.idle);
 do_rest:
-#ifdef CONFIG_X86_32
 	per_cpu(current_task, cpu) = c_idle.idle;
-	init_gdt(cpu);
+#ifdef CONFIG_X86_32
 	/* Stack for startup_32 can be just as for start_secondary onwards */
 	irq_ctx_init(cpu);
 #else
-	cpu_pda(cpu)->pcurrent = c_idle.idle;
 	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
+	initial_gs = per_cpu_offset(cpu);
+	per_cpu(kernel_stack, cpu) =
+		(unsigned long)task_stack_page(c_idle.idle) -
+		KERNEL_STACK_OFFSET + THREAD_SIZE;
 #endif
 	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
 	initial_code = (unsigned long)start_secondary;
@@ -878,8 +749,6 @@ do_rest:
 
 		pr_debug("Setting warm reset code and vector.\n");
 
-		store_NMI_vector(&nmi_high, &nmi_low);
-
 		smpboot_setup_warm_reset_vector(start_ip);
 		/*
 		 * Be paranoid about clearing APIC errors.
@@ -891,9 +760,13 @@ do_rest:
 	}
 
 	/*
-	 * Starting actual IPI sequence...
+	 * Kick the secondary CPU. Use the method in the APIC driver
+	 * if it's defined - or use an INIT boot APIC message otherwise:
 	 */
-	boot_error = wakeup_secondary_cpu(apicid, start_ip);
+	if (apic->wakeup_secondary_cpu)
+		boot_error = apic->wakeup_secondary_cpu(apicid, start_ip);
+	else
+		boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip);
 
 	if (!boot_error) {
 		/*
@@ -927,13 +800,11 @@ do_rest:
 			else
 				/* trampoline code not run */
 				printk(KERN_ERR "Not responding.\n");
-			if (get_uv_system_type() != UV_NON_UNIQUE_APIC)
-				inquire_remote_apic(apicid);
+			if (apic->inquire_remote_apic)
+				apic->inquire_remote_apic(apicid);
 		}
 	}
-#ifdef CONFIG_X86_64
-restore_state:
-#endif
+
 	if (boot_error) {
 		/* Try to put things back the way they were before ... */
 		numa_remove_cpu(cpu); /* was set by numa_add_cpu */
@@ -961,7 +832,7 @@ restore_state:
 
 int __cpuinit native_cpu_up(unsigned int cpu)
 {
-	int apicid = cpu_present_to_apicid(cpu);
+	int apicid = apic->cpu_present_to_apicid(cpu);
 	unsigned long flags;
 	int err;
 
@@ -1033,9 +904,8 @@ int __cpuinit native_cpu_up(unsigned int
  */
 static __init void disable_smp(void)
 {
-	/* use the read/write pointers to the present and possible maps */
-	cpumask_copy(&cpu_present_map, cpumask_of(0));
-	cpumask_copy(&cpu_possible_map, cpumask_of(0));
+	init_cpu_present(cpumask_of(0));
+	init_cpu_possible(cpumask_of(0));
 	smpboot_clear_io_apic_irqs();
 
 	if (smp_found_config)
@@ -1054,14 +924,14 @@ static int __init smp_sanity_check(unsig
 {
 	preempt_disable();
 
-#if defined(CONFIG_X86_PC) && defined(CONFIG_X86_32)
+#if !defined(CONFIG_X86_BIGSMP) && defined(CONFIG_X86_32)
 	if (def_to_bigsmp && nr_cpu_ids > 8) {
 		unsigned int cpu;
 		unsigned nr;
 
 		printk(KERN_WARNING
 		       "More than 8 CPUs detected - skipping them.\n"
-		       "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n");
+		       "Use CONFIG_X86_BIGSMP.\n");
 
 		nr = 0;
 		for_each_present_cpu(cpu) {
@@ -1107,7 +977,7 @@ static int __init smp_sanity_check(unsig
 	 * Should not be necessary because the MP table should list the boot
 	 * CPU too, but we do it for the sake of robustness anyway.
 	 */
-	if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
+	if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) {
 		printk(KERN_NOTICE
 			"weird, boot CPU (#%d) not listed by the BIOS.\n",
 			boot_cpu_physical_apicid);
@@ -1125,6 +995,7 @@ static int __init smp_sanity_check(unsig
 		printk(KERN_ERR "... forcing use of dummy APIC emulation."
 				"(tell your hw vendor)\n");
 		smpboot_clear_io_apic();
+		arch_disable_smp_support();
 		return -1;
 	}
 
@@ -1166,6 +1037,8 @@ static void __init smp_cpu_index_default
  */
 void __init native_smp_prepare_cpus(unsigned int max_cpus)
 {
+	unsigned int i;
+
 	preempt_disable();
 	smp_cpu_index_default();
 	current_cpu_data = boot_cpu_data;
@@ -1179,11 +1052,19 @@ void __init native_smp_prepare_cpus(unsi
 	boot_cpu_logical_apicid = logical_smp_processor_id();
 #endif
 	current_thread_info()->cpu = 0;  /* needed? */
+	for_each_possible_cpu(i) {
+		alloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
+		alloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+		alloc_cpumask_var(&cpu_data(i).llc_shared_map, GFP_KERNEL);
+		cpumask_clear(per_cpu(cpu_core_map, i));
+		cpumask_clear(per_cpu(cpu_sibling_map, i));
+		cpumask_clear(cpu_data(i).llc_shared_map);
+	}
 	set_cpu_sibling_map(0);
 
-#ifdef CONFIG_X86_64
 	enable_IR_x2apic();
-	setup_apic_routing();
+#ifdef CONFIG_X86_64
+	default_setup_apic_routing();
 #endif
 
 	if (smp_sanity_check(max_cpus) < 0) {
@@ -1207,18 +1088,18 @@ void __init native_smp_prepare_cpus(unsi
 	 */
 	setup_local_APIC();
 
-#ifdef CONFIG_X86_64
 	/*
 	 * Enable IO APIC before setting up error vector
 	 */
 	if (!skip_ioapic_setup && nr_ioapics)
 		enable_IO_APIC();
-#endif
+
 	end_local_APIC_setup();
 
 	map_cpu_to_logical_apicid();
 
-	setup_portio_remap();
+	if (apic->setup_portio_remap)
+		apic->setup_portio_remap();
 
 	smpboot_setup_io_apic();
 	/*
@@ -1240,10 +1121,7 @@ out:
 void __init native_smp_prepare_boot_cpu(void)
 {
 	int me = smp_processor_id();
-#ifdef CONFIG_X86_32
-	init_gdt(me);
-#endif
-	switch_to_new_gdt();
+	switch_to_new_gdt(me);
 	/* already set me in cpu_online_mask in boot_cpu_init() */
 	cpumask_set_cpu(me, cpu_callout_mask);
 	per_cpu(cpu_state, me) = CPU_ONLINE;
@@ -1254,7 +1132,6 @@ void __init native_smp_cpus_done(unsigne
 	pr_debug("Boot done.\n");
 
 	impress_friends();
-	smp_checks();
 #ifdef CONFIG_X86_IO_APIC
 	setup_ioapic_dest();
 #endif
@@ -1271,11 +1148,11 @@ early_param("possible_cpus", _setup_poss
 
 
 /*
- * cpu_possible_map should be static, it cannot change as cpu's
+ * cpu_possible_mask should be static, it cannot change as cpu's
  * are onlined, or offlined. The reason is per-cpu data-structures
  * are allocated by some modules at init time, and dont expect to
  * do this dynamically on cpu arrival/departure.
- * cpu_present_map on the other hand can change dynamically.
+ * cpu_present_mask on the other hand can change dynamically.
  * In case when cpu_hotplug is not compiled, then we resort to current
  * behaviour, which is cpu_possible == cpu_present.
  * - Ashok Raj
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/smp.c linux-libre-2.6.30-gnu1/arch/x86/kernel/smp.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *	Intel SMP support routines.
  *
  *	(c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk>
- *	(c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
+ *	(c) 1998-99, 2000, 2009 Ingo Molnar <mingo@redhat.com>
  *      (c) 2002,2003 Andi Kleen, SuSE Labs.
  *
  *	i386 and x86_64 integration by Glauber Costa <gcosta@redhat.com>
@@ -26,8 +26,7 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
-#include <mach_ipi.h>
-#include <mach_apic.h>
+#include <asm/apic.h>
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
  *
@@ -118,12 +117,12 @@ static void native_smp_send_reschedule(i
 		WARN_ON(1);
 		return;
 	}
-	send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
+	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
 }
 
 void native_send_call_func_single_ipi(int cpu)
 {
-	send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
+	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
 }
 
 void native_send_call_func_ipi(const struct cpumask *mask)
@@ -131,7 +130,7 @@ void native_send_call_func_ipi(const str
 	cpumask_var_t allbutself;
 
 	if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
-		send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
+		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 		return;
 	}
 
@@ -140,9 +139,9 @@ void native_send_call_func_ipi(const str
 
 	if (cpumask_equal(mask, allbutself) &&
 	    cpumask_equal(cpu_online_mask, cpu_callout_mask))
-		send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+		apic->send_IPI_allbutself(CALL_FUNCTION_VECTOR);
 	else
-		send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
+		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 
 	free_cpumask_var(allbutself);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/smpcommon.c linux-libre-2.6.30-gnu1/arch/x86/kernel/smpcommon.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/smpcommon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/smpcommon.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*
- * SMP stuff which is common to all sub-architectures.
- */
-#include <linux/module.h>
-#include <asm/smp.h>
-
-#ifdef CONFIG_X86_32
-DEFINE_PER_CPU(unsigned long, this_cpu_off);
-EXPORT_PER_CPU_SYMBOL(this_cpu_off);
-
-/*
- * Initialize the CPU's GDT.  This is either the boot CPU doing itself
- * (still using the master per-cpu area), or a CPU doing it for a
- * secondary which will soon come up.
- */
-__cpuinit void init_gdt(int cpu)
-{
-	struct desc_struct gdt;
-
-	pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
-			0x2 | DESCTYPE_S, 0x8);
-	gdt.s = 1;
-
-	write_gdt_entry(get_cpu_gdt_table(cpu),
-			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
-
-	per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
-	per_cpu(cpu_number, cpu) = cpu;
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/stacktrace.c linux-libre-2.6.30-gnu1/arch/x86/kernel/stacktrace.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/stacktrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/stacktrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Stack trace management functions
  *
- *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *  Copyright (C) 2006-2009 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  */
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/summit_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/summit_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/summit_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/summit_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,188 +0,0 @@
-/*
- * IBM Summit-Specific Code
- *
- * Written By: Matthew Dobson, IBM Corporation
- *
- * Copyright (c) 2003 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <colpatch@us.ibm.com>
- *
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/bios_ebda.h>
-#include <asm/summit/mpparse.h>
-
-static struct rio_table_hdr *rio_table_hdr __initdata;
-static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
-static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;
-
-#ifndef CONFIG_X86_NUMAQ
-static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata;
-#endif
-
-static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
-{
-	int twister = 0, node = 0;
-	int i, bus, num_buses;
-
-	for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
-		if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
-			twister = rio_devs[i]->owner_id;
-			break;
-		}
-	}
-	if (i == rio_table_hdr->num_rio_dev) {
-		printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__);
-		return last_bus;
-	}
-
-	for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
-		if (scal_devs[i]->node_id == twister) {
-			node = scal_devs[i]->node_id;
-			break;
-		}
-	}
-	if (i == rio_table_hdr->num_scal_dev) {
-		printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__);
-		return last_bus;
-	}
-
-	switch (rio_devs[wpeg_num]->type) {
-	case CompatWPEG:
-		/*
-		 * The Compatibility Winnipeg controls the 2 legacy buses,
-		 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
-		 * a PCI-PCI bridge card is used in either slot: total 5 buses.
-		 */
-		num_buses = 5;
-		break;
-	case AltWPEG:
-		/*
-		 * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
-		 * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
-		 * the "extra" buses for each of those slots: total 7 buses.
-		 */
-		num_buses = 7;
-		break;
-	case LookOutAWPEG:
-	case LookOutBWPEG:
-		/*
-		 * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
-		 * & the "extra" buses for each of those slots: total 9 buses.
-		 */
-		num_buses = 9;
-		break;
-	default:
-		printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__);
-		return last_bus;
-	}
-
-	for (bus = last_bus; bus < last_bus + num_buses; bus++)
-		mp_bus_id_to_node[bus] = node;
-	return bus;
-}
-
-static int __init build_detail_arrays(void)
-{
-	unsigned long ptr;
-	int i, scal_detail_size, rio_detail_size;
-
-	if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
-		printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
-		return 0;
-	}
-
-	switch (rio_table_hdr->version) {
-	default:
-		printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version);
-		return 0;
-	case 2:
-		scal_detail_size = 11;
-		rio_detail_size = 13;
-		break;
-	case 3:
-		scal_detail_size = 12;
-		rio_detail_size = 15;
-		break;
-	}
-
-	ptr = (unsigned long)rio_table_hdr + 3;
-	for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
-		scal_devs[i] = (struct scal_detail *)ptr;
-
-	for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
-		rio_devs[i] = (struct rio_detail *)ptr;
-
-	return 1;
-}
-
-void __init setup_summit(void)
-{
-	unsigned long		ptr;
-	unsigned short		offset;
-	int			i, next_wpeg, next_bus = 0;
-
-	/* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
-	ptr = get_bios_ebda();
-	ptr = (unsigned long)phys_to_virt(ptr);
-
-	rio_table_hdr = NULL;
-	offset = 0x180;
-	while (offset) {
-		/* The block id is stored in the 2nd word */
-		if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
-			/* set the pointer past the offset & block id */
-			rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
-			break;
-		}
-		/* The next offset is stored in the 1st word.  0 means no more */
-		offset = *((unsigned short *)(ptr + offset));
-	}
-	if (!rio_table_hdr) {
-		printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__);
-		return;
-	}
-
-	if (!build_detail_arrays())
-		return;
-
-	/* The first Winnipeg we're looking for has an index of 0 */
-	next_wpeg = 0;
-	do {
-		for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
-			if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
-				/* It's the Winnipeg we're looking for! */
-				next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
-				next_wpeg++;
-				break;
-			}
-		}
-		/*
-		 * If we go through all Rio devices and don't find one with
-		 * the next index, it means we've found all the Winnipegs,
-		 * and thus all the PCI buses.
-		 */
-		if (i == rio_table_hdr->num_rio_dev)
-			next_wpeg = 0;
-	} while (next_wpeg != 0);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/syscall_table_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/syscall_table_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/syscall_table_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/syscall_table_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
-	.long sys_fork
+	.long ptregs_fork
 	.long sys_read
 	.long sys_write
 	.long sys_open		/* 5 */
@@ -10,7 +10,7 @@ ENTRY(sys_call_table)
 	.long sys_creat
 	.long sys_link
 	.long sys_unlink	/* 10 */
-	.long sys_execve
+	.long ptregs_execve
 	.long sys_chdir
 	.long sys_time
 	.long sys_mknod
@@ -109,17 +109,17 @@ ENTRY(sys_call_table)
 	.long sys_newlstat
 	.long sys_newfstat
 	.long sys_uname
-	.long sys_iopl		/* 110 */
+	.long ptregs_iopl	/* 110 */
 	.long sys_vhangup
 	.long sys_ni_syscall	/* old "idle" system call */
-	.long sys_vm86old
+	.long ptregs_vm86old
 	.long sys_wait4
 	.long sys_swapoff	/* 115 */
 	.long sys_sysinfo
 	.long sys_ipc
 	.long sys_fsync
-	.long sys_sigreturn
-	.long sys_clone		/* 120 */
+	.long ptregs_sigreturn
+	.long ptregs_clone	/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
 	.long sys_modify_ldt
@@ -165,14 +165,14 @@ ENTRY(sys_call_table)
 	.long sys_mremap
 	.long sys_setresuid16
 	.long sys_getresuid16	/* 165 */
-	.long sys_vm86
+	.long ptregs_vm86
 	.long sys_ni_syscall	/* Old sys_query_module */
 	.long sys_poll
 	.long sys_nfsservctl
 	.long sys_setresgid16	/* 170 */
 	.long sys_getresgid16
 	.long sys_prctl
-	.long sys_rt_sigreturn
+	.long ptregs_rt_sigreturn
 	.long sys_rt_sigaction
 	.long sys_rt_sigprocmask	/* 175 */
 	.long sys_rt_sigpending
@@ -185,11 +185,11 @@ ENTRY(sys_call_table)
 	.long sys_getcwd
 	.long sys_capget
 	.long sys_capset	/* 185 */
-	.long sys_sigaltstack
+	.long ptregs_sigaltstack
 	.long sys_sendfile
 	.long sys_ni_syscall	/* reserved for streams1 */
 	.long sys_ni_syscall	/* reserved for streams2 */
-	.long sys_vfork		/* 190 */
+	.long ptregs_vfork	/* 190 */
 	.long sys_getrlimit
 	.long sys_mmap2
 	.long sys_truncate64
@@ -332,3 +332,5 @@ ENTRY(sys_call_table)
 	.long sys_dup3			/* 330 */
 	.long sys_pipe2
 	.long sys_inotify_init1
+	.long sys_preadv
+	.long sys_pwritev
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/time_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/time_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/time_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/time_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,12 +33,12 @@
 #include <linux/time.h>
 #include <linux/mca.h>
 
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
 #include <asm/hpet.h>
 #include <asm/time.h>
 #include <asm/timer.h>
 
-#include "do_timer.h"
+#include <asm/do_timer.h>
 
 int timer_ack;
 
@@ -118,7 +118,7 @@ void __init hpet_time_init(void)
 {
 	if (!hpet_enable())
 		setup_pit_timer();
-	time_init_hook();
+	x86_quirk_time_init();
 }
 
 /*
@@ -131,7 +131,7 @@ void __init hpet_time_init(void)
  */
 void __init time_init(void)
 {
-	pre_time_init_hook();
+	x86_quirk_pre_time_init();
 	tsc_init();
 	late_time_init = choose_time_init();
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/time_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/time_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/time_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/time_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -116,7 +116,6 @@ unsigned long __init calibrate_cpu(void)
 static struct irqaction irq0 = {
 	.handler	= timer_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER,
-	.mask		= CPU_MASK_NONE,
 	.name		= "timer"
 };
 
@@ -125,7 +124,6 @@ void __init hpet_time_init(void)
 	if (!hpet_enable())
 		setup_pit_timer();
 
-	irq0.mask = cpumask_of_cpu(0);
 	setup_irq(0, &irq0);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,256 +0,0 @@
-#include <linux/spinlock.h>
-#include <linux/cpu.h>
-#include <linux/interrupt.h>
-
-#include <asm/tlbflush.h>
-
-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
-			____cacheline_aligned = { &init_mm, 0, };
-
-/* must come after the send_IPI functions above for inlining */
-#include <mach_ipi.h>
-
-/*
- *	Smarter SMP flushing macros.
- *		c/o Linus Torvalds.
- *
- *	These mean you can really definitely utterly forget about
- *	writing to user space from interrupts. (Its not allowed anyway).
- *
- *	Optimizations Manfred Spraul <manfred@colorfullife.com>
- */
-
-static cpumask_t flush_cpumask;
-static struct mm_struct *flush_mm;
-static unsigned long flush_va;
-static DEFINE_SPINLOCK(tlbstate_lock);
-
-/*
- * We cannot call mmdrop() because we are in interrupt context,
- * instead update mm->cpu_vm_mask.
- *
- * We need to reload %cr3 since the page tables may be going
- * away from under us..
- */
-void leave_mm(int cpu)
-{
-	BUG_ON(x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK);
-	cpu_clear(cpu, x86_read_percpu(cpu_tlbstate.active_mm)->cpu_vm_mask);
-	load_cr3(swapper_pg_dir);
-}
-EXPORT_SYMBOL_GPL(leave_mm);
-
-/*
- *
- * The flush IPI assumes that a thread switch happens in this order:
- * [cpu0: the cpu that switches]
- * 1) switch_mm() either 1a) or 1b)
- * 1a) thread switch to a different mm
- * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
- * 	Stop ipi delivery for the old mm. This is not synchronized with
- * 	the other cpus, but smp_invalidate_interrupt ignore flush ipis
- * 	for the wrong mm, and in the worst case we perform a superfluous
- * 	tlb flush.
- * 1a2) set cpu_tlbstate to TLBSTATE_OK
- * 	Now the smp_invalidate_interrupt won't call leave_mm if cpu0
- *	was in lazy tlb mode.
- * 1a3) update cpu_tlbstate[].active_mm
- * 	Now cpu0 accepts tlb flushes for the new mm.
- * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
- * 	Now the other cpus will send tlb flush ipis.
- * 1a4) change cr3.
- * 1b) thread switch without mm change
- *	cpu_tlbstate[].active_mm is correct, cpu0 already handles
- *	flush ipis.
- * 1b1) set cpu_tlbstate to TLBSTATE_OK
- * 1b2) test_and_set the cpu bit in cpu_vm_mask.
- * 	Atomically set the bit [other cpus will start sending flush ipis],
- * 	and test the bit.
- * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
- * 2) switch %%esp, ie current
- *
- * The interrupt must handle 2 special cases:
- * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm.
- * - the cpu performs speculative tlb reads, i.e. even if the cpu only
- *   runs in kernel space, the cpu could load tlb entries for user space
- *   pages.
- *
- * The good news is that cpu_tlbstate is local to each cpu, no
- * write/read ordering problems.
- */
-
-/*
- * TLB flush IPI:
- *
- * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
- * 2) Leave the mm if we are in the lazy tlb mode.
- */
-
-void smp_invalidate_interrupt(struct pt_regs *regs)
-{
-	unsigned long cpu;
-
-	cpu = get_cpu();
-
-	if (!cpu_isset(cpu, flush_cpumask))
-		goto out;
-		/*
-		 * This was a BUG() but until someone can quote me the
-		 * line from the intel manual that guarantees an IPI to
-		 * multiple CPUs is retried _only_ on the erroring CPUs
-		 * its staying as a return
-		 *
-		 * BUG();
-		 */
-
-	if (flush_mm == x86_read_percpu(cpu_tlbstate.active_mm)) {
-		if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) {
-			if (flush_va == TLB_FLUSH_ALL)
-				local_flush_tlb();
-			else
-				__flush_tlb_one(flush_va);
-		} else
-			leave_mm(cpu);
-	}
-	ack_APIC_irq();
-	smp_mb__before_clear_bit();
-	cpu_clear(cpu, flush_cpumask);
-	smp_mb__after_clear_bit();
-out:
-	put_cpu_no_resched();
-	inc_irq_stat(irq_tlb_count);
-}
-
-void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
-			     unsigned long va)
-{
-	cpumask_t cpumask = *cpumaskp;
-
-	/*
-	 * A couple of (to be removed) sanity checks:
-	 *
-	 * - current CPU must not be in mask
-	 * - mask must exist :)
-	 */
-	BUG_ON(cpus_empty(cpumask));
-	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
-	BUG_ON(!mm);
-
-#ifdef CONFIG_HOTPLUG_CPU
-	/* If a CPU which we ran on has gone down, OK. */
-	cpus_and(cpumask, cpumask, cpu_online_map);
-	if (unlikely(cpus_empty(cpumask)))
-		return;
-#endif
-
-	/*
-	 * i'm not happy about this global shared spinlock in the
-	 * MM hot path, but we'll see how contended it is.
-	 * AK: x86-64 has a faster method that could be ported.
-	 */
-	spin_lock(&tlbstate_lock);
-
-	flush_mm = mm;
-	flush_va = va;
-	cpus_or(flush_cpumask, cpumask, flush_cpumask);
-
-	/*
-	 * Make the above memory operations globally visible before
-	 * sending the IPI.
-	 */
-	smp_mb();
-	/*
-	 * We have to send the IPI only to
-	 * CPUs affected.
-	 */
-	send_IPI_mask(&cpumask, INVALIDATE_TLB_VECTOR);
-
-	while (!cpus_empty(flush_cpumask))
-		/* nothing. lockup detection does not belong here */
-		cpu_relax();
-
-	flush_mm = NULL;
-	flush_va = 0;
-	spin_unlock(&tlbstate_lock);
-}
-
-void flush_tlb_current_task(void)
-{
-	struct mm_struct *mm = current->mm;
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	local_flush_tlb();
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-	preempt_enable();
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	if (current->active_mm == mm) {
-		if (current->mm)
-			local_flush_tlb();
-		else
-			leave_mm(smp_processor_id());
-	}
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-
-	preempt_enable();
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	if (current->active_mm == mm) {
-		if (current->mm)
-			__flush_tlb_one(va);
-		 else
-			leave_mm(smp_processor_id());
-	}
-
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, va);
-
-	preempt_enable();
-}
-EXPORT_SYMBOL(flush_tlb_page);
-
-static void do_flush_tlb_all(void *info)
-{
-	unsigned long cpu = smp_processor_id();
-
-	__flush_tlb_all();
-	if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_LAZY)
-		leave_mm(cpu);
-}
-
-void flush_tlb_all(void)
-{
-	on_each_cpu(do_flush_tlb_all, NULL, 1);
-}
-
-void reset_lazy_tlbstate(void)
-{
-	int cpu = raw_smp_processor_id();
-
-	per_cpu(cpu_tlbstate, cpu).state = 0;
-	per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
-}
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,284 +0,0 @@
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mc146818rtc.h>
-#include <linux/interrupt.h>
-
-#include <asm/mtrr.h>
-#include <asm/pgalloc.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-#include <asm/proto.h>
-#include <asm/apicdef.h>
-#include <asm/idle.h>
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/uv_bau.h>
-
-#include <mach_ipi.h>
-/*
- *	Smarter SMP flushing macros.
- *		c/o Linus Torvalds.
- *
- *	These mean you can really definitely utterly forget about
- *	writing to user space from interrupts. (Its not allowed anyway).
- *
- *	Optimizations Manfred Spraul <manfred@colorfullife.com>
- *
- *	More scalable flush, from Andi Kleen
- *
- *	To avoid global state use 8 different call vectors.
- *	Each CPU uses a specific vector to trigger flushes on other
- *	CPUs. Depending on the received vector the target CPUs look into
- *	the right per cpu variable for the flush data.
- *
- *	With more than 8 CPUs they are hashed to the 8 available
- *	vectors. The limited global vector space forces us to this right now.
- *	In future when interrupts are split into per CPU domains this could be
- *	fixed, at the cost of triggering multiple IPIs in some cases.
- */
-
-union smp_flush_state {
-	struct {
-		cpumask_t flush_cpumask;
-		struct mm_struct *flush_mm;
-		unsigned long flush_va;
-		spinlock_t tlbstate_lock;
-	};
-	char pad[SMP_CACHE_BYTES];
-} ____cacheline_aligned;
-
-/* State is put into the per CPU data section, but padded
-   to a full cache line because other CPUs can access it and we don't
-   want false sharing in the per cpu data segment. */
-static DEFINE_PER_CPU(union smp_flush_state, flush_state);
-
-/*
- * We cannot call mmdrop() because we are in interrupt context,
- * instead update mm->cpu_vm_mask.
- */
-void leave_mm(int cpu)
-{
-	if (read_pda(mmu_state) == TLBSTATE_OK)
-		BUG();
-	cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
-	load_cr3(swapper_pg_dir);
-}
-EXPORT_SYMBOL_GPL(leave_mm);
-
-/*
- *
- * The flush IPI assumes that a thread switch happens in this order:
- * [cpu0: the cpu that switches]
- * 1) switch_mm() either 1a) or 1b)
- * 1a) thread switch to a different mm
- * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
- *	Stop ipi delivery for the old mm. This is not synchronized with
- *	the other cpus, but smp_invalidate_interrupt ignore flush ipis
- *	for the wrong mm, and in the worst case we perform a superfluous
- *	tlb flush.
- * 1a2) set cpu mmu_state to TLBSTATE_OK
- *	Now the smp_invalidate_interrupt won't call leave_mm if cpu0
- *	was in lazy tlb mode.
- * 1a3) update cpu active_mm
- *	Now cpu0 accepts tlb flushes for the new mm.
- * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
- *	Now the other cpus will send tlb flush ipis.
- * 1a4) change cr3.
- * 1b) thread switch without mm change
- *	cpu active_mm is correct, cpu0 already handles
- *	flush ipis.
- * 1b1) set cpu mmu_state to TLBSTATE_OK
- * 1b2) test_and_set the cpu bit in cpu_vm_mask.
- *	Atomically set the bit [other cpus will start sending flush ipis],
- *	and test the bit.
- * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
- * 2) switch %%esp, ie current
- *
- * The interrupt must handle 2 special cases:
- * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm.
- * - the cpu performs speculative tlb reads, i.e. even if the cpu only
- *   runs in kernel space, the cpu could load tlb entries for user space
- *   pages.
- *
- * The good news is that cpu mmu_state is local to each cpu, no
- * write/read ordering problems.
- */
-
-/*
- * TLB flush IPI:
- *
- * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
- * 2) Leave the mm if we are in the lazy tlb mode.
- *
- * Interrupts are disabled.
- */
-
-asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
-{
-	int cpu;
-	int sender;
-	union smp_flush_state *f;
-
-	cpu = smp_processor_id();
-	/*
-	 * orig_rax contains the negated interrupt vector.
-	 * Use that to determine where the sender put the data.
-	 */
-	sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
-	f = &per_cpu(flush_state, sender);
-
-	if (!cpu_isset(cpu, f->flush_cpumask))
-		goto out;
-		/*
-		 * This was a BUG() but until someone can quote me the
-		 * line from the intel manual that guarantees an IPI to
-		 * multiple CPUs is retried _only_ on the erroring CPUs
-		 * its staying as a return
-		 *
-		 * BUG();
-		 */
-
-	if (f->flush_mm == read_pda(active_mm)) {
-		if (read_pda(mmu_state) == TLBSTATE_OK) {
-			if (f->flush_va == TLB_FLUSH_ALL)
-				local_flush_tlb();
-			else
-				__flush_tlb_one(f->flush_va);
-		} else
-			leave_mm(cpu);
-	}
-out:
-	ack_APIC_irq();
-	cpu_clear(cpu, f->flush_cpumask);
-	inc_irq_stat(irq_tlb_count);
-}
-
-void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
-			     unsigned long va)
-{
-	int sender;
-	union smp_flush_state *f;
-	cpumask_t cpumask = *cpumaskp;
-
-	if (is_uv_system() && uv_flush_tlb_others(&cpumask, mm, va))
-		return;
-
-	/* Caller has disabled preemption */
-	sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
-	f = &per_cpu(flush_state, sender);
-
-	/*
-	 * Could avoid this lock when
-	 * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
-	 * probably not worth checking this for a cache-hot lock.
-	 */
-	spin_lock(&f->tlbstate_lock);
-
-	f->flush_mm = mm;
-	f->flush_va = va;
-	cpus_or(f->flush_cpumask, cpumask, f->flush_cpumask);
-
-	/*
-	 * Make the above memory operations globally visible before
-	 * sending the IPI.
-	 */
-	smp_mb();
-	/*
-	 * We have to send the IPI only to
-	 * CPUs affected.
-	 */
-	send_IPI_mask(&cpumask, INVALIDATE_TLB_VECTOR_START + sender);
-
-	while (!cpus_empty(f->flush_cpumask))
-		cpu_relax();
-
-	f->flush_mm = NULL;
-	f->flush_va = 0;
-	spin_unlock(&f->tlbstate_lock);
-}
-
-static int __cpuinit init_smp_flush(void)
-{
-	int i;
-
-	for_each_possible_cpu(i)
-		spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
-
-	return 0;
-}
-core_initcall(init_smp_flush);
-
-void flush_tlb_current_task(void)
-{
-	struct mm_struct *mm = current->mm;
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	local_flush_tlb();
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-	preempt_enable();
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	if (current->active_mm == mm) {
-		if (current->mm)
-			local_flush_tlb();
-		else
-			leave_mm(smp_processor_id());
-	}
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-
-	preempt_enable();
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	cpumask_t cpu_mask;
-
-	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
-
-	if (current->active_mm == mm) {
-		if (current->mm)
-			__flush_tlb_one(va);
-		else
-			leave_mm(smp_processor_id());
-	}
-
-	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, va);
-
-	preempt_enable();
-}
-
-static void do_flush_tlb_all(void *info)
-{
-	unsigned long cpu = smp_processor_id();
-
-	__flush_tlb_all();
-	if (read_pda(mmu_state) == TLBSTATE_LAZY)
-		leave_mm(cpu);
-}
-
-void flush_tlb_all(void)
-{
-	on_each_cpu(do_flush_tlb_all, NULL, 1);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_uv.c linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_uv.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/tlb_uv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_uv.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,21 +11,22 @@
 #include <linux/kernel.h>
 
 #include <asm/mmu_context.h>
+#include <asm/uv/uv.h>
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/uv_bau.h>
-#include <asm/genapic.h>
+#include <asm/apic.h>
 #include <asm/idle.h>
 #include <asm/tsc.h>
 #include <asm/irq_vectors.h>
 
-#include <mach_apic.h>
-
 static struct bau_control	**uv_bau_table_bases __read_mostly;
 static int			uv_bau_retry_limit __read_mostly;
 
 /* position of pnode (which is nasid>>1): */
 static int			uv_nshift __read_mostly;
+/* base pnode in this partition */
+static int			uv_partition_base_pnode __read_mostly;
 
 static unsigned long		uv_mmask __read_mostly;
 
@@ -33,6 +34,34 @@ static DEFINE_PER_CPU(struct ptc_stats,
 static DEFINE_PER_CPU(struct bau_control, bau_control);
 
 /*
+ * Determine the first node on a blade.
+ */
+static int __init blade_to_first_node(int blade)
+{
+	int node, b;
+
+	for_each_online_node(node) {
+		b = uv_node_to_blade_id(node);
+		if (blade == b)
+			return node;
+	}
+	return -1; /* shouldn't happen */
+}
+
+/*
+ * Determine the apicid of the first cpu on a blade.
+ */
+static int __init blade_to_first_apicid(int blade)
+{
+	int cpu;
+
+	for_each_present_cpu(cpu)
+		if (blade == uv_cpu_to_blade_id(cpu))
+			return per_cpu(x86_cpu_to_apicid, cpu);
+	return -1;
+}
+
+/*
  * Free a software acknowledge hardware resource by clearing its Pending
  * bit. This will return a reply to the sender.
  * If the message has timed out, a reply has already been sent by the
@@ -68,7 +97,7 @@ static void uv_bau_process_message(struc
 	msp = __get_cpu_var(bau_control).msg_statuses + msg_slot;
 	cpu = uv_blade_processor_id();
 	msg->number_of_cpus =
-	    uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id()));
+		uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id()));
 	this_cpu_mask = 1UL << cpu;
 	if (msp->seen_by.bits & this_cpu_mask)
 		return;
@@ -210,19 +239,20 @@ static int uv_wait_completion(struct bau
  *
  * Send a broadcast and wait for a broadcast message to complete.
  *
- * The cpumaskp mask contains the cpus the broadcast was sent to.
+ * The flush_mask contains the cpus the broadcast was sent to.
  *
- * Returns 1 if all remote flushing was done. The mask is zeroed.
- * Returns 0 if some remote flushing remains to be done. The mask is left
- * unchanged.
+ * Returns NULL if all remote flushing was done. The mask is zeroed.
+ * Returns @flush_mask if some remote flushing remains to be done. The
+ * mask will have some bits still set.
  */
-int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc,
-			   cpumask_t *cpumaskp)
+const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode,
+					     struct bau_desc *bau_desc,
+					     struct cpumask *flush_mask)
 {
 	int completion_status = 0;
 	int right_shift;
 	int tries = 0;
-	int blade;
+	int pnode;
 	int bit;
 	unsigned long mmr_offset;
 	unsigned long index;
@@ -257,73 +287,83 @@ int uv_flush_send_and_wait(int cpu, int
 		 * the cpu's, all of which are still in the mask.
 		 */
 		__get_cpu_var(ptcstats).ptc_i++;
-		return 0;
+		return flush_mask;
 	}
 
 	/*
 	 * Success, so clear the remote cpu's from the mask so we don't
 	 * use the IPI method of shootdown on them.
 	 */
-	for_each_cpu_mask(bit, *cpumaskp) {
-		blade = uv_cpu_to_blade_id(bit);
-		if (blade == this_blade)
+	for_each_cpu(bit, flush_mask) {
+		pnode = uv_cpu_to_pnode(bit);
+		if (pnode == this_pnode)
 			continue;
-		cpu_clear(bit, *cpumaskp);
+		cpumask_clear_cpu(bit, flush_mask);
 	}
-	if (!cpus_empty(*cpumaskp))
-		return 0;
-	return 1;
+	if (!cpumask_empty(flush_mask))
+		return flush_mask;
+	return NULL;
 }
 
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
 /**
  * uv_flush_tlb_others - globally purge translation cache of a virtual
  * address or all TLB's
- * @cpumaskp: mask of all cpu's in which the address is to be removed
+ * @cpumask: mask of all cpu's in which the address is to be removed
  * @mm: mm_struct containing virtual address range
  * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu)
+ * @cpu: the current cpu
  *
  * This is the entry point for initiating any UV global TLB shootdown.
  *
  * Purges the translation caches of all specified processors of the given
  * virtual address, or purges all TLB's on specified processors.
  *
- * The caller has derived the cpumaskp from the mm_struct and has subtracted
- * the local cpu from the mask.  This function is called only if there
- * are bits set in the mask. (e.g. flush_tlb_page())
+ * The caller has derived the cpumask from the mm_struct.  This function
+ * is called only if there are bits set in the mask. (e.g. flush_tlb_page())
  *
- * The cpumaskp is converted into a nodemask of the nodes containing
+ * The cpumask is converted into a nodemask of the nodes containing
  * the cpus.
  *
- * Returns 1 if all remote flushing was done.
- * Returns 0 if some remote flushing remains to be done.
+ * Note that this function should be called with preemption disabled.
+ *
+ * Returns NULL if all remote flushing was done.
+ * Returns pointer to cpumask if some remote flushing remains to be
+ * done.  The returned pointer is valid till preemption is re-enabled.
  */
-int uv_flush_tlb_others(cpumask_t *cpumaskp, struct mm_struct *mm,
-			unsigned long va)
+const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
+					  struct mm_struct *mm,
+					  unsigned long va, unsigned int cpu)
 {
+	struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
 	int i;
 	int bit;
-	int blade;
-	int cpu;
-	int this_blade;
+	int pnode;
+	int uv_cpu;
+	int this_pnode;
 	int locals = 0;
 	struct bau_desc *bau_desc;
 
-	cpu = uv_blade_processor_id();
-	this_blade = uv_numa_blade_id();
+	cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu));
+
+	uv_cpu = uv_blade_processor_id();
+	this_pnode = uv_hub_info->pnode;
 	bau_desc = __get_cpu_var(bau_control).descriptor_base;
-	bau_desc += UV_ITEMS_PER_DESCRIPTOR * cpu;
+	bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu;
 
 	bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
 
 	i = 0;
-	for_each_cpu_mask(bit, *cpumaskp) {
-		blade = uv_cpu_to_blade_id(bit);
-		BUG_ON(blade > (UV_DISTRIBUTION_SIZE - 1));
-		if (blade == this_blade) {
+	for_each_cpu(bit, flush_mask) {
+		pnode = uv_cpu_to_pnode(bit);
+		BUG_ON(pnode > (UV_DISTRIBUTION_SIZE - 1));
+		if (pnode == this_pnode) {
 			locals++;
 			continue;
 		}
-		bau_node_set(blade, &bau_desc->distribution);
+		bau_node_set(pnode - uv_partition_base_pnode,
+				&bau_desc->distribution);
 		i++;
 	}
 	if (i == 0) {
@@ -331,17 +371,17 @@ int uv_flush_tlb_others(cpumask_t *cpuma
 		 * no off_node flushing; return status for local node
 		 */
 		if (locals)
-			return 0;
+			return flush_mask;
 		else
-			return 1;
+			return NULL;
 	}
 	__get_cpu_var(ptcstats).requestor++;
 	__get_cpu_var(ptcstats).ntargeted += i;
 
 	bau_desc->payload.address = va;
-	bau_desc->payload.sending_cpu = smp_processor_id();
+	bau_desc->payload.sending_cpu = cpu;
 
-	return uv_flush_send_and_wait(cpu, this_blade, bau_desc, cpumaskp);
+	return uv_flush_send_and_wait(uv_cpu, this_pnode, bau_desc, flush_mask);
 }
 
 /*
@@ -409,24 +449,58 @@ void uv_bau_message_interrupt(struct pt_
 	set_irq_regs(old_regs);
 }
 
+/*
+ * uv_enable_timeouts
+ *
+ * Each target blade (i.e. blades that have cpu's) needs to have
+ * shootdown message timeouts enabled.  The timeout does not cause
+ * an interrupt, but causes an error message to be returned to
+ * the sender.
+ */
 static void uv_enable_timeouts(void)
 {
-	int i;
 	int blade;
-	int last_blade;
+	int nblades;
 	int pnode;
-	int cur_cpu = 0;
-	unsigned long apicid;
+	unsigned long mmr_image;
 
-	last_blade = -1;
-	for_each_online_node(i) {
-		blade = uv_node_to_blade_id(i);
-		if (blade == last_blade)
+	nblades = uv_num_possible_blades();
+
+	for (blade = 0; blade < nblades; blade++) {
+		if (!uv_blade_nr_possible_cpus(blade))
 			continue;
-		last_blade = blade;
-		apicid = per_cpu(x86_cpu_to_apicid, cur_cpu);
+
 		pnode = uv_blade_to_pnode(blade);
-		cur_cpu += uv_blade_nr_possible_cpus(i);
+		mmr_image =
+		    uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL);
+		/*
+		 * Set the timeout period and then lock it in, in three
+		 * steps; captures and locks in the period.
+		 *
+		 * To program the period, the SOFT_ACK_MODE must be off.
+		 */
+		mmr_image &= ~((unsigned long)1 <<
+			       UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
+		uv_write_global_mmr64
+		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+		/*
+		 * Set the 4-bit period.
+		 */
+		mmr_image &= ~((unsigned long)0xf <<
+			UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
+		mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD <<
+			     UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
+		uv_write_global_mmr64
+		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+		/*
+		 * Subsequent reversals of the timebase bit (3) cause an
+		 * immediate timeout of one or all INTD resources as
+		 * indicated in bits 2:0 (7 causes all of them to timeout).
+		 */
+		mmr_image |= ((unsigned long)1 <<
+			      UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
+		uv_write_global_mmr64
+		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
 	}
 }
 
@@ -473,8 +547,7 @@ static int uv_ptc_seq_show(struct seq_fi
 			   stat->requestee, stat->onetlb, stat->alltlb,
 			   stat->s_retry, stat->d_retry, stat->ptc_i);
 		seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n",
-			   uv_read_global_mmr64(uv_blade_to_pnode
-					(uv_cpu_to_blade_id(cpu)),
+			   uv_read_global_mmr64(uv_cpu_to_pnode(cpu),
 					UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE),
 			   stat->sflush, stat->dflush,
 			   stat->retriesok, stat->nomsg,
@@ -608,16 +681,18 @@ static struct bau_control * __init uv_ta
  * finish the initialization of the per-blade control structures
  */
 static void __init
-uv_table_bases_finish(int blade, int node, int cur_cpu,
+uv_table_bases_finish(int blade,
 		      struct bau_control *bau_tablesp,
 		      struct bau_desc *adp)
 {
 	struct bau_control *bcp;
-	int i;
+	int cpu;
 
-	for (i = cur_cpu; i < cur_cpu + uv_blade_nr_possible_cpus(blade); i++) {
-		bcp = (struct bau_control *)&per_cpu(bau_control, i);
+	for_each_present_cpu(cpu) {
+		if (blade != uv_cpu_to_blade_id(cpu))
+			continue;
 
+		bcp = (struct bau_control *)&per_cpu(bau_control, cpu);
 		bcp->bau_msg_head	= bau_tablesp->va_queue_first;
 		bcp->va_queue_first	= bau_tablesp->va_queue_first;
 		bcp->va_queue_last	= bau_tablesp->va_queue_last;
@@ -640,11 +715,10 @@ uv_activation_descriptor_init(int node,
 	struct bau_desc *adp;
 	struct bau_desc *ad2;
 
-	adp = (struct bau_desc *)
-	    kmalloc_node(16384, GFP_KERNEL, node);
+	adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node);
 	BUG_ON(!adp);
 
-	pa = __pa((unsigned long)adp);
+	pa = uv_gpa(adp); /* need the real nasid*/
 	n = pa >> uv_nshift;
 	m = pa & uv_mmask;
 
@@ -658,8 +732,12 @@ uv_activation_descriptor_init(int node,
 	for (i = 0, ad2 = adp; i < UV_ACTIVATION_DESCRIPTOR_SIZE; i++, ad2++) {
 		memset(ad2, 0, sizeof(struct bau_desc));
 		ad2->header.sw_ack_flag = 1;
-		ad2->header.base_dest_nodeid =
-		    uv_blade_to_pnode(uv_cpu_to_blade_id(0));
+		/*
+		 * base_dest_nodeid is the first node in the partition, so
+		 * the bit map will indicate partition-relative node numbers.
+		 * note that base_dest_nodeid is actually a nasid.
+		 */
+		ad2->header.base_dest_nodeid = uv_partition_base_pnode << 1;
 		ad2->header.command = UV_NET_ENDPOINT_INTD;
 		ad2->header.int_both = 1;
 		/*
@@ -677,6 +755,8 @@ static struct bau_payload_queue_entry *
 uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
 {
 	struct bau_payload_queue_entry *pqp;
+	unsigned long pa;
+	int pn;
 	char *cp;
 
 	pqp = (struct bau_payload_queue_entry *) kmalloc_node(
@@ -687,10 +767,14 @@ uv_payload_queue_init(int node, int pnod
 	cp = (char *)pqp + 31;
 	pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5);
 	bau_tablesp->va_queue_first = pqp;
+	/*
+	 * need the pnode of where the memory was really allocated
+	 */
+	pa = uv_gpa(pqp);
+	pn = pa >> uv_nshift;
 	uv_write_global_mmr64(pnode,
 			      UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
-			      ((unsigned long)pnode <<
-			       UV_PAYLOADQ_PNODE_SHIFT) |
+			      ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
 			      uv_physnodeaddr(pqp));
 	uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL,
 			      uv_physnodeaddr(pqp));
@@ -706,8 +790,9 @@ uv_payload_queue_init(int node, int pnod
 /*
  * Initialization of each UV blade's structures
  */
-static int __init uv_init_blade(int blade, int node, int cur_cpu)
+static int __init uv_init_blade(int blade)
 {
+	int node;
 	int pnode;
 	unsigned long pa;
 	unsigned long apicid;
@@ -715,16 +800,17 @@ static int __init uv_init_blade(int blad
 	struct bau_payload_queue_entry *pqp;
 	struct bau_control *bau_tablesp;
 
+	node = blade_to_first_node(blade);
 	bau_tablesp = uv_table_bases_init(blade, node);
 	pnode = uv_blade_to_pnode(blade);
 	adp = uv_activation_descriptor_init(node, pnode);
 	pqp = uv_payload_queue_init(node, pnode, bau_tablesp);
-	uv_table_bases_finish(blade, node, cur_cpu, bau_tablesp, adp);
+	uv_table_bases_finish(blade, bau_tablesp, adp);
 	/*
 	 * the below initialization can't be in firmware because the
 	 * messaging IRQ will be determined by the OS
 	 */
-	apicid = per_cpu(x86_cpu_to_apicid, cur_cpu);
+	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,
@@ -739,39 +825,34 @@ static int __init uv_init_blade(int blad
 static int __init uv_bau_init(void)
 {
 	int blade;
-	int node;
 	int nblades;
-	int last_blade;
-	int cur_cpu = 0;
+	int cur_cpu;
 
 	if (!is_uv_system())
 		return 0;
 
+	for_each_possible_cpu(cur_cpu)
+		zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
+				       GFP_KERNEL, cpu_to_node(cur_cpu));
+
 	uv_bau_retry_limit = 1;
 	uv_nshift = uv_hub_info->n_val;
 	uv_mmask = (1UL << uv_hub_info->n_val) - 1;
-	nblades = 0;
-	last_blade = -1;
-	for_each_online_node(node) {
-		blade = uv_node_to_blade_id(node);
-		if (blade == last_blade)
-			continue;
-		last_blade = blade;
-		nblades++;
-	}
+	nblades = uv_num_possible_blades();
+
 	uv_bau_table_bases = (struct bau_control **)
 	    kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL);
 	BUG_ON(!uv_bau_table_bases);
 
-	last_blade = -1;
-	for_each_online_node(node) {
-		blade = uv_node_to_blade_id(node);
-		if (blade == last_blade)
-			continue;
-		last_blade = blade;
-		uv_init_blade(blade, node, cur_cpu);
-		cur_cpu += uv_blade_nr_possible_cpus(blade);
-	}
+	uv_partition_base_pnode = 0x7fffffff;
+	for (blade = 0; blade < nblades; blade++)
+		if (uv_blade_nr_possible_cpus(blade) &&
+			(uv_blade_to_pnode(blade) < uv_partition_base_pnode))
+			uv_partition_base_pnode = uv_blade_to_pnode(blade);
+	for (blade = 0; blade < nblades; blade++)
+		if (uv_blade_nr_possible_cpus(blade))
+			uv_init_blade(blade);
+
 	alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
 	uv_enable_timeouts();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/topology.c linux-libre-2.6.30-gnu1/arch/x86/kernel/topology.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/topology.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/topology.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,10 +25,10 @@
  *
  * Send feedback to <colpatch@us.ibm.com>
  */
-#include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/nodemask.h>
 #include <linux/mmzone.h>
+#include <linux/init.h>
+#include <linux/smp.h>
 #include <asm/cpu.h>
 
 static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
@@ -47,6 +47,7 @@ int __ref arch_register_cpu(int num)
 	 */
 	if (num)
 		per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
+
 	return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
 }
 EXPORT_SYMBOL(arch_register_cpu);
@@ -56,12 +57,13 @@ void arch_unregister_cpu(int num)
 	unregister_cpu(&per_cpu(cpu_devices, num).cpu);
 }
 EXPORT_SYMBOL(arch_unregister_cpu);
-#else
+#else /* CONFIG_HOTPLUG_CPU */
+
 static int __init arch_register_cpu(int num)
 {
 	return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
 }
-#endif /*CONFIG_HOTPLUG_CPU*/
+#endif /* CONFIG_HOTPLUG_CPU */
 
 static int __init topology_init(void)
 {
@@ -70,11 +72,11 @@ static int __init topology_init(void)
 #ifdef CONFIG_NUMA
 	for_each_online_node(i)
 		register_one_node(i);
-#endif /* CONFIG_NUMA */
+#endif
 
 	for_each_present_cpu(i)
 		arch_register_cpu(i);
+
 	return 0;
 }
-
 subsys_initcall(topology_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/trampoline_32.S linux-libre-2.6.30-gnu1/arch/x86/kernel/trampoline_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/trampoline_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/trampoline_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 
 /* We can free up trampoline after bootup if cpu hotplug is not supported. */
 #ifndef CONFIG_HOTPLUG_CPU
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/trampoline_64.S linux-libre-2.6.30-gnu1/arch/x86/kernel/trampoline_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/trampoline_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/trampoline_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -25,10 +25,11 @@
  */
 
 #include <linux/linkage.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <asm/pgtable_types.h>
+#include <asm/page_types.h>
 #include <asm/msr.h>
 #include <asm/segment.h>
+#include <asm/processor-flags.h>
 
 .section .rodata, "a", @progbits
 
@@ -37,7 +38,7 @@
 ENTRY(trampoline_data)
 r_base = .
 	cli			# We should be safe anyway
-	wbinvd	
+	wbinvd
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 	mov	%ax, %es
@@ -73,9 +74,8 @@ r_base = .
 	lidtl	tidt - r_base	# load idt with 0, 0
 	lgdtl	tgdt - r_base	# load gdt with whatever is appropriate
 
-	xor	%ax, %ax
-	inc	%ax		# protected mode (PE) bit
-	lmsw	%ax		# into protected mode
+	mov	$X86_CR0_PE, %ax	# protected mode (PE) bit
+	lmsw	%ax			# into protected mode
 
 	# flush prefetch and jump to startup_32
 	ljmpl	*(startup_32_vector - r_base)
@@ -86,9 +86,8 @@ startup_32:
 	movl	$__KERNEL_DS, %eax	# Initialize the %ds segment register
 	movl	%eax, %ds
 
-	xorl	%eax, %eax
-	btsl	$5, %eax		# Enable PAE mode
-	movl	%eax, %cr4
+	movl	$X86_CR4_PAE, %eax
+	movl	%eax, %cr4		# Enable PAE mode
 
 					# Setup trampoline 4 level pagetables
 	leal	(trampoline_level4_pgt - r_base)(%esi), %eax
@@ -99,9 +98,9 @@ startup_32:
 	xorl	%edx, %edx
 	wrmsr
 
-	xorl	%eax, %eax
-	btsl	$31, %eax		# Enable paging and in turn activate Long Mode
-	btsl	$0, %eax		# Enable protected mode
+	# Enable paging and in turn activate Long Mode
+	# Enable protected mode
+	movl	$(X86_CR0_PG | X86_CR0_PE), %eax
 	movl	%eax, %cr0
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/traps.c linux-libre-2.6.30-gnu1/arch/x86/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -54,15 +54,14 @@
 #include <asm/desc.h>
 #include <asm/i387.h>
 
-#include <mach_traps.h>
+#include <asm/mach_traps.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
-#include <asm/pda.h>
 #else
 #include <asm/processor-flags.h>
-#include <asm/arch_hooks.h>
+#include <asm/setup.h>
 #include <asm/traps.h>
 
 #include "cpu/mcheck/mce.h"
@@ -119,47 +118,6 @@ die_if_kernel(const char *str, struct pt
 	if (!user_mode_vm(regs))
 		die(str, regs, err);
 }
-
-/*
- * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
- * invalid offset set (the LAZY one) and the faulting thread has
- * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS,
- * we set the offset field correctly and return 1.
- */
-static int lazy_iobitmap_copy(void)
-{
-	struct thread_struct *thread;
-	struct tss_struct *tss;
-	int cpu;
-
-	cpu = get_cpu();
-	tss = &per_cpu(init_tss, cpu);
-	thread = &current->thread;
-
-	if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
-	    thread->io_bitmap_ptr) {
-		memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
-		       thread->io_bitmap_max);
-		/*
-		 * If the previously set map was extending to higher ports
-		 * than the current one, pad extra space with 0xff (no access).
-		 */
-		if (thread->io_bitmap_max < tss->io_bitmap_max) {
-			memset((char *) tss->io_bitmap +
-				thread->io_bitmap_max, 0xff,
-				tss->io_bitmap_max - thread->io_bitmap_max);
-		}
-		tss->io_bitmap_max = thread->io_bitmap_max;
-		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
-		tss->io_bitmap_owner = thread;
-		put_cpu();
-
-		return 1;
-	}
-	put_cpu();
-
-	return 0;
-}
 #endif
 
 static void __kprobes
@@ -310,11 +268,6 @@ do_general_protection(struct pt_regs *re
 	conditional_sti(regs);
 
 #ifdef CONFIG_X86_32
-	if (lazy_iobitmap_copy()) {
-		/* restart the faulting instruction */
-		return;
-	}
-
 	if (regs->flags & X86_VM_MASK)
 		goto gp_in_vm86;
 #endif
@@ -914,19 +867,20 @@ void math_emulate(struct math_emu_info *
 }
 #endif /* CONFIG_MATH_EMULATION */
 
-dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs)
+dotraplinkage void __kprobes
+do_device_not_available(struct pt_regs *regs, long error_code)
 {
 #ifdef CONFIG_X86_32
 	if (read_cr0() & X86_CR0_EM) {
 		struct math_emu_info info = { };
 
-		conditional_sti(&regs);
+		conditional_sti(regs);
 
-		info.regs = &regs;
+		info.regs = regs;
 		math_emulate(&info);
 	} else {
 		math_state_restore(); /* interrupts still off */
-		conditional_sti(&regs);
+		conditional_sti(regs);
 	}
 #else
 	math_state_restore();
@@ -942,7 +896,7 @@ dotraplinkage void do_iret_error(struct
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_BADSTK;
-	info.si_addr = 0;
+	info.si_addr = NULL;
 	if (notify_die(DIE_TRAP, "iret exception",
 			regs, error_code, 32, SIGILL) == NOTIFY_STOP)
 		return;
@@ -1026,6 +980,6 @@ void __init trap_init(void)
 	cpu_init();
 
 #ifdef CONFIG_X86_32
-	trap_init_hook();
+	x86_quirk_trap_init();
 #endif
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/tsc.c linux-libre-2.6.30-gnu1/arch/x86/kernel/tsc.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/tsc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/tsc.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,20 +17,21 @@
 #include <asm/delay.h>
 #include <asm/hypervisor.h>
 
-unsigned int cpu_khz;           /* TSC clocks / usec, not used here */
+unsigned int __read_mostly cpu_khz;	/* TSC clocks / usec, not used here */
 EXPORT_SYMBOL(cpu_khz);
-unsigned int tsc_khz;
+
+unsigned int __read_mostly tsc_khz;
 EXPORT_SYMBOL(tsc_khz);
 
 /*
  * TSC can be unstable due to cpufreq or due to unsynced TSCs
  */
-static int tsc_unstable;
+static int __read_mostly tsc_unstable;
 
 /* native_sched_clock() is called before tsc_init(), so
    we must start with the TSC soft disabled to prevent
    erroneous rdtsc usage on !cpu_has_tsc processors */
-static int tsc_disabled = -1;
+static int __read_mostly tsc_disabled = -1;
 
 static int tsc_clocksource_reliable;
 /*
@@ -543,8 +544,6 @@ unsigned long native_calibrate_tsc(void)
 	return tsc_pit_min;
 }
 
-#ifdef CONFIG_X86_32
-/* Only called from the Powernow K7 cpu freq driver */
 int recalibrate_cpu_khz(void)
 {
 #ifndef CONFIG_SMP
@@ -566,7 +565,6 @@ int recalibrate_cpu_khz(void)
 
 EXPORT_SYMBOL(recalibrate_cpu_khz);
 
-#endif /* CONFIG_X86_32 */
 
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
@@ -701,7 +699,7 @@ static struct clocksource clocksource_ts
  * code, which is necessary to support wrapping clocksources like pm
  * timer.
  */
-static cycle_t read_tsc(void)
+static cycle_t read_tsc(struct clocksource *cs)
 {
 	cycle_t ret = (cycle_t)get_cycles();
 
@@ -793,7 +791,7 @@ __cpuinit int unsynchronized_tsc(void)
 	if (!cpu_has_tsc || tsc_unstable)
 		return 1;
 
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
 	if (apic_is_clustered_box())
 		return 1;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/uv_sysfs.c linux-libre-2.6.30-gnu1/arch/x86/kernel/uv_sysfs.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/uv_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/uv_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <linux/sysdev.h>
 #include <asm/uv/bios.h>
+#include <asm/uv/uv.h>
 
 struct kobject *sgi_uv_kobj;
 
@@ -47,6 +48,9 @@ static int __init sgi_uv_sysfs_init(void
 {
 	unsigned long ret;
 
+	if (!is_uv_system())
+		return -ENODEV;
+
 	if (!sgi_uv_kobj)
 		sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
 	if (!sgi_uv_kobj) {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/uv_time.c linux-libre-2.6.30-gnu1/arch/x86/kernel/uv_time.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/uv_time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/uv_time.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,393 @@
+/*
+ * SGI RTC clock/timer routines.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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) 2009 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) Dimitri Sivanich
+ */
+#include <linux/clockchips.h>
+
+#include <asm/uv/uv_mmrs.h>
+#include <asm/uv/uv_hub.h>
+#include <asm/uv/bios.h>
+#include <asm/uv/uv.h>
+#include <asm/apic.h>
+#include <asm/cpu.h>
+
+#define RTC_NAME		"sgi_rtc"
+
+static cycle_t uv_read_rtc(struct clocksource *cs);
+static int uv_rtc_next_event(unsigned long, struct clock_event_device *);
+static void uv_rtc_timer_setup(enum clock_event_mode,
+				struct clock_event_device *);
+
+static struct clocksource clocksource_uv = {
+	.name		= RTC_NAME,
+	.rating		= 400,
+	.read		= uv_read_rtc,
+	.mask		= (cycle_t)UVH_RTC_REAL_TIME_CLOCK_MASK,
+	.shift		= 10,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct clock_event_device clock_event_device_uv = {
+	.name		= RTC_NAME,
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 20,
+	.rating		= 400,
+	.irq		= -1,
+	.set_next_event	= uv_rtc_next_event,
+	.set_mode	= uv_rtc_timer_setup,
+	.event_handler	= NULL,
+};
+
+static DEFINE_PER_CPU(struct clock_event_device, cpu_ced);
+
+/* There is one of these allocated per node */
+struct uv_rtc_timer_head {
+	spinlock_t	lock;
+	/* next cpu waiting for timer, local node relative: */
+	int		next_cpu;
+	/* number of cpus on this node: */
+	int		ncpus;
+	struct {
+		int	lcpu;		/* systemwide logical cpu number */
+		u64	expires;	/* next timer expiration for this cpu */
+	} cpu[1];
+};
+
+/*
+ * Access to uv_rtc_timer_head via blade id.
+ */
+static struct uv_rtc_timer_head		**blade_info __read_mostly;
+
+static int				uv_rtc_enable;
+
+/*
+ * Hardware interface routines
+ */
+
+/* Send IPIs to another node */
+static void uv_rtc_send_IPI(int cpu)
+{
+	unsigned long apicid, val;
+	int pnode;
+
+	apicid = cpu_physical_id(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);
+
+	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+}
+
+/* Check for an RTC interrupt pending */
+static int uv_intr_pending(int pnode)
+{
+	return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) &
+		UVH_EVENT_OCCURRED0_RTC1_MASK;
+}
+
+/* Setup interrupt and return non-zero if early expiration occurred. */
+static int uv_setup_intr(int cpu, u64 expires)
+{
+	u64 val;
+	int pnode = uv_cpu_to_pnode(cpu);
+
+	uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
+		UVH_RTC1_INT_CONFIG_M_MASK);
+	uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L);
+
+	uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
+		UVH_EVENT_OCCURRED0_RTC1_MASK);
+
+	val = (GENERIC_INTERRUPT_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
+		((u64)cpu_physical_id(cpu) << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
+
+	/* Set configuration */
+	uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val);
+	/* Initialize comparator value */
+	uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires);
+
+	return (expires < uv_read_rtc(NULL) && !uv_intr_pending(pnode));
+}
+
+/*
+ * Per-cpu timer tracking routines
+ */
+
+static __init void uv_rtc_deallocate_timers(void)
+{
+	int bid;
+
+	for_each_possible_blade(bid) {
+		kfree(blade_info[bid]);
+	}
+	kfree(blade_info);
+}
+
+/* Allocate per-node list of cpu timer expiration times. */
+static __init int uv_rtc_allocate_timers(void)
+{
+	int cpu;
+
+	blade_info = kmalloc(uv_possible_blades * sizeof(void *), GFP_KERNEL);
+	if (!blade_info)
+		return -ENOMEM;
+	memset(blade_info, 0, uv_possible_blades * sizeof(void *));
+
+	for_each_present_cpu(cpu) {
+		int nid = cpu_to_node(cpu);
+		int bid = uv_cpu_to_blade_id(cpu);
+		int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id;
+		struct uv_rtc_timer_head *head = blade_info[bid];
+
+		if (!head) {
+			head = kmalloc_node(sizeof(struct uv_rtc_timer_head) +
+				(uv_blade_nr_possible_cpus(bid) *
+					2 * sizeof(u64)),
+				GFP_KERNEL, nid);
+			if (!head) {
+				uv_rtc_deallocate_timers();
+				return -ENOMEM;
+			}
+			spin_lock_init(&head->lock);
+			head->ncpus = uv_blade_nr_possible_cpus(bid);
+			head->next_cpu = -1;
+			blade_info[bid] = head;
+		}
+
+		head->cpu[bcpu].lcpu = cpu;
+		head->cpu[bcpu].expires = ULLONG_MAX;
+	}
+
+	return 0;
+}
+
+/* Find and set the next expiring timer.  */
+static void uv_rtc_find_next_timer(struct uv_rtc_timer_head *head, int pnode)
+{
+	u64 lowest = ULLONG_MAX;
+	int c, bcpu = -1;
+
+	head->next_cpu = -1;
+	for (c = 0; c < head->ncpus; c++) {
+		u64 exp = head->cpu[c].expires;
+		if (exp < lowest) {
+			bcpu = c;
+			lowest = exp;
+		}
+	}
+	if (bcpu >= 0) {
+		head->next_cpu = bcpu;
+		c = head->cpu[bcpu].lcpu;
+		if (uv_setup_intr(c, lowest))
+			/* If we didn't set it up in time, trigger */
+			uv_rtc_send_IPI(c);
+	} else {
+		uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
+			UVH_RTC1_INT_CONFIG_M_MASK);
+	}
+}
+
+/*
+ * Set expiration time for current cpu.
+ *
+ * Returns 1 if we missed the expiration time.
+ */
+static int uv_rtc_set_timer(int cpu, u64 expires)
+{
+	int pnode = uv_cpu_to_pnode(cpu);
+	int bid = uv_cpu_to_blade_id(cpu);
+	struct uv_rtc_timer_head *head = blade_info[bid];
+	int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id;
+	u64 *t = &head->cpu[bcpu].expires;
+	unsigned long flags;
+	int next_cpu;
+
+	spin_lock_irqsave(&head->lock, flags);
+
+	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) {
+		head->next_cpu = bcpu;
+		if (uv_setup_intr(cpu, expires)) {
+			*t = ULLONG_MAX;
+			uv_rtc_find_next_timer(head, pnode);
+			spin_unlock_irqrestore(&head->lock, flags);
+			return 1;
+		}
+	}
+
+	spin_unlock_irqrestore(&head->lock, flags);
+	return 0;
+}
+
+/*
+ * Unset expiration time for current cpu.
+ *
+ * Returns 1 if this timer was pending.
+ */
+static int uv_rtc_unset_timer(int cpu)
+{
+	int pnode = uv_cpu_to_pnode(cpu);
+	int bid = uv_cpu_to_blade_id(cpu);
+	struct uv_rtc_timer_head *head = blade_info[bid];
+	int bcpu = uv_cpu_hub_info(cpu)->blade_processor_id;
+	u64 *t = &head->cpu[bcpu].expires;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&head->lock, flags);
+
+	if (head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t)
+		rc = 1;
+
+	*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);
+
+	return rc;
+}
+
+
+/*
+ * Kernel interface routines.
+ */
+
+/*
+ * Read the RTC.
+ */
+static cycle_t uv_read_rtc(struct clocksource *cs)
+{
+	return (cycle_t)uv_read_local_mmr(UVH_RTC);
+}
+
+/*
+ * Program the next event, relative to now
+ */
+static int uv_rtc_next_event(unsigned long delta,
+			     struct clock_event_device *ced)
+{
+	int ced_cpu = cpumask_first(ced->cpumask);
+
+	return uv_rtc_set_timer(ced_cpu, delta + uv_read_rtc(NULL));
+}
+
+/*
+ * Setup the RTC timer in oneshot mode
+ */
+static void uv_rtc_timer_setup(enum clock_event_mode mode,
+			       struct clock_event_device *evt)
+{
+	int ced_cpu = cpumask_first(evt->cpumask);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do here yet */
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		uv_rtc_unset_timer(ced_cpu);
+		break;
+	}
+}
+
+static void uv_rtc_interrupt(void)
+{
+	struct clock_event_device *ced = &__get_cpu_var(cpu_ced);
+	int cpu = smp_processor_id();
+
+	if (!ced || !ced->event_handler)
+		return;
+
+	if (uv_rtc_unset_timer(cpu) != 1)
+		return;
+
+	ced->event_handler(ced);
+}
+
+static int __init uv_enable_rtc(char *str)
+{
+	uv_rtc_enable = 1;
+
+	return 1;
+}
+__setup("uvrtc", uv_enable_rtc);
+
+static __init void uv_rtc_register_clockevents(struct work_struct *dummy)
+{
+	struct clock_event_device *ced = &__get_cpu_var(cpu_ced);
+
+	*ced = clock_event_device_uv;
+	ced->cpumask = cpumask_of(smp_processor_id());
+	clockevents_register_device(ced);
+}
+
+static __init int uv_rtc_setup_clock(void)
+{
+	int rc;
+
+	if (!uv_rtc_enable || !is_uv_system() || generic_interrupt_extension)
+		return -ENODEV;
+
+	generic_interrupt_extension = uv_rtc_interrupt;
+
+	clocksource_uv.mult = clocksource_hz2mult(sn_rtc_cycles_per_second,
+				clocksource_uv.shift);
+
+	rc = clocksource_register(&clocksource_uv);
+	if (rc) {
+		generic_interrupt_extension = NULL;
+		return rc;
+	}
+
+	/* Setup and register clockevents */
+	rc = uv_rtc_allocate_timers();
+	if (rc) {
+		clocksource_unregister(&clocksource_uv);
+		generic_interrupt_extension = NULL;
+		return rc;
+	}
+
+	clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second,
+				NSEC_PER_SEC, clock_event_device_uv.shift);
+
+	clock_event_device_uv.min_delta_ns = NSEC_PER_SEC /
+						sn_rtc_cycles_per_second;
+
+	clock_event_device_uv.max_delta_ns = clocksource_uv.mask *
+				(NSEC_PER_SEC / sn_rtc_cycles_per_second);
+
+	rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
+	if (rc) {
+		clocksource_unregister(&clocksource_uv);
+		generic_interrupt_extension = NULL;
+		uv_rtc_deallocate_timers();
+	}
+
+	return rc;
+}
+arch_initcall(uv_rtc_setup_clock);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/visws_quirks.c linux-libre-2.6.30-gnu1/arch/x86/kernel/visws_quirks.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/visws_quirks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/visws_quirks.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,18 +24,14 @@
 
 #include <asm/visws/cobalt.h>
 #include <asm/visws/piix4.h>
-#include <asm/arch_hooks.h>
 #include <asm/io_apic.h>
 #include <asm/fixmap.h>
 #include <asm/reboot.h>
 #include <asm/setup.h>
+#include <asm/apic.h>
 #include <asm/e820.h>
 #include <asm/io.h>
 
-#include <mach_ipi.h>
-
-#include "mach_apic.h"
-
 #include <linux/kernel_stat.h>
 
 #include <asm/i8259.h>
@@ -49,8 +45,6 @@
 
 extern int no_broadcast;
 
-#include <asm/apic.h>
-
 char visws_board_type	= -1;
 char visws_board_rev	= -1;
 
@@ -200,7 +194,7 @@ static void __init MP_processor_info(str
 		return;
 	}
 
-	apic_cpus = apicid_to_cpu_present(m->apicid);
+	apic_cpus = apic->apicid_to_cpu_present(m->apicid);
 	physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
 	/*
 	 * Validate version
@@ -584,7 +578,7 @@ static struct irq_chip piix4_virtual_irq
 static irqreturn_t piix4_master_intr(int irq, void *dev_id)
 {
 	int realirq;
-	irq_desc_t *desc;
+	struct irq_desc *desc;
 	unsigned long flags;
 
 	spin_lock_irqsave(&i8259A_lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vm86_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/vm86_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vm86_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vm86_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,7 +158,7 @@ struct pt_regs *save_v86_state(struct ke
 	ret = KVM86->regs32;
 
 	ret->fs = current->thread.saved_fs;
-	loadsegment(gs, current->thread.saved_gs);
+	set_user_gs(ret, current->thread.saved_gs);
 
 	return ret;
 }
@@ -197,9 +197,9 @@ 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);
 
-asmlinkage int sys_vm86old(struct pt_regs regs)
+int sys_vm86old(struct pt_regs *regs)
 {
-	struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.bx;
+	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
@@ -218,7 +218,7 @@ asmlinkage int sys_vm86old(struct pt_reg
 	if (tmp)
 		goto out;
 	memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus);
-	info.regs32 = &regs;
+	info.regs32 = regs;
 	tsk->thread.vm86_info = v86;
 	do_sys_vm86(&info, tsk);
 	ret = 0;	/* we never return here */
@@ -227,7 +227,7 @@ out:
 }
 
 
-asmlinkage int sys_vm86(struct pt_regs regs)
+int sys_vm86(struct pt_regs *regs)
 {
 	struct kernel_vm86_struct info; /* declare this _on top_,
 					 * this avoids wasting of stack space.
@@ -239,12 +239,12 @@ asmlinkage int sys_vm86(struct pt_regs r
 	struct vm86plus_struct __user *v86;
 
 	tsk = current;
-	switch (regs.bx) {
+	switch (regs->bx) {
 	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(regs->bx, (int)regs->cx);
 		goto out;
 	case VM86_PLUS_INSTALL_CHECK:
 		/*
@@ -261,14 +261,14 @@ asmlinkage int sys_vm86(struct pt_regs r
 	ret = -EPERM;
 	if (tsk->thread.saved_sp0)
 		goto out;
-	v86 = (struct vm86plus_struct __user *)regs.cx;
+	v86 = (struct vm86plus_struct __user *)regs->cx;
 	tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
 				       offsetof(struct kernel_vm86_struct, regs32) -
 				       sizeof(info.regs));
 	ret = -EFAULT;
 	if (tmp)
 		goto out;
-	info.regs32 = &regs;
+	info.regs32 = regs;
 	info.vm86plus.is_vm86pus = 1;
 	tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
 	do_sys_vm86(&info, tsk);
@@ -323,7 +323,7 @@ static void do_sys_vm86(struct kernel_vm
 	info->regs32->ax = 0;
 	tsk->thread.saved_sp0 = tsk->thread.sp0;
 	tsk->thread.saved_fs = info->regs32->fs;
-	savesegment(gs, tsk->thread.saved_gs);
+	tsk->thread.saved_gs = get_user_gs(info->regs32);
 
 	tss = &per_cpu(init_tss, get_cpu());
 	tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vmi_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/vmi_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vmi_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vmi_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -395,11 +395,6 @@ static void vmi_set_pte_atomic(pte_t *pt
 	vmi_ops.update_pte(ptep, VMI_PAGE_PT);
 }
 
-static void vmi_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
-{
-	vmi_ops.set_pte(pte, ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 1));
-}
-
 static void vmi_set_pud(pud_t *pudp, pud_t pudval)
 {
 	/* Um, eww */
@@ -680,10 +675,11 @@ static inline int __init activate_vmi(vo
 	para_fill(pv_mmu_ops.write_cr2, SetCR2);
 	para_fill(pv_mmu_ops.write_cr3, SetCR3);
 	para_fill(pv_cpu_ops.write_cr4, SetCR4);
-	para_fill(pv_irq_ops.save_fl, GetInterruptMask);
-	para_fill(pv_irq_ops.restore_fl, SetInterruptMask);
-	para_fill(pv_irq_ops.irq_disable, DisableInterrupts);
-	para_fill(pv_irq_ops.irq_enable, EnableInterrupts);
+
+	para_fill(pv_irq_ops.save_fl.func, GetInterruptMask);
+	para_fill(pv_irq_ops.restore_fl.func, SetInterruptMask);
+	para_fill(pv_irq_ops.irq_disable.func, DisableInterrupts);
+	para_fill(pv_irq_ops.irq_enable.func, EnableInterrupts);
 
 	para_fill(pv_cpu_ops.wbinvd, WBINVD);
 	para_fill(pv_cpu_ops.read_tsc, RDTSC);
@@ -749,7 +745,6 @@ static inline int __init activate_vmi(vo
 		pv_mmu_ops.set_pmd = vmi_set_pmd;
 #ifdef CONFIG_X86_PAE
 		pv_mmu_ops.set_pte_atomic = vmi_set_pte_atomic;
-		pv_mmu_ops.set_pte_present = vmi_set_pte_present;
 		pv_mmu_ops.set_pud = vmi_set_pud;
 		pv_mmu_ops.pte_clear = vmi_pte_clear;
 		pv_mmu_ops.pmd_clear = vmi_pmd_clear;
@@ -797,8 +792,8 @@ static inline int __init activate_vmi(vo
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
-       para_fill(apic_ops->read, APICRead);
-       para_fill(apic_ops->write, APICWrite);
+       para_fill(apic->read, APICRead);
+       para_fill(apic->write, APICWrite);
 #endif
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vmiclock_32.c linux-libre-2.6.30-gnu1/arch/x86/kernel/vmiclock_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vmiclock_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vmiclock_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 
 #include <asm/vmi.h>
 #include <asm/vmi_time.h>
-#include <asm/arch_hooks.h>
 #include <asm/apicdef.h>
 #include <asm/apic.h>
 #include <asm/timer.h>
@@ -203,7 +202,6 @@ static struct irqaction vmi_clock_action
 	.name 		= "vmi-timer",
 	.handler 	= vmi_timer_interrupt,
 	.flags 		= IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
-	.mask 		= CPU_MASK_ALL,
 };
 
 static void __devinit vmi_time_init_clockevent(void)
@@ -256,7 +254,7 @@ void __devinit vmi_time_bsp_init(void)
 	 */
 	clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
 	local_irq_disable();
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_SMP
 	/*
 	 * XXX handle_percpu_irq only defined for SMP; we need to switch over
 	 * to using it, since this is a local interrupt, which each CPU must
@@ -285,11 +283,10 @@ void __devinit vmi_time_ap_init(void)
 /** vmi clocksource */
 static struct clocksource clocksource_vmi;
 
-static cycle_t read_real_cycles(void)
+static cycle_t read_real_cycles(struct clocksource *cs)
 {
 	cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
-	return ret >= clocksource_vmi.cycle_last ?
-		ret : clocksource_vmi.cycle_last;
+	return max(ret, clocksource_vmi.cycle_last);
 }
 
 static struct clocksource clocksource_vmi = {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vmlinux_32.lds.S linux-libre-2.6.30-gnu1/arch/x86/kernel/vmlinux_32.lds.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vmlinux_32.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vmlinux_32.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/cache.h>
 #include <asm/boot.h>
 
@@ -178,14 +178,7 @@ SECTIONS
 	__initramfs_end = .;
   }
 #endif
-  . = ALIGN(PAGE_SIZE);
-  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
-	__per_cpu_start = .;
-	*(.data.percpu.page_aligned)
-	*(.data.percpu)
-	*(.data.percpu.shared_aligned)
-	__per_cpu_end = .;
-  }
+  PERCPU(PAGE_SIZE)
   . = ALIGN(PAGE_SIZE);
   /* freed after init ends here */
 
@@ -196,15 +189,24 @@ SECTIONS
 	*(.bss)
 	. = ALIGN(4);
 	__bss_stop = .;
-  	_end = . ;
-	/* This is where the kernel creates the early boot page tables */
+  }
+
+  .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
 	. = ALIGN(PAGE_SIZE);
-	pg0 = . ;
+	__brk_base = . ;
+ 	. += 64 * 1024 ;	/* 64k alignment slop space */
+	*(.brk_reservation)	/* areas brk users have reserved */
+	__brk_limit = . ;
+  }
+
+  .end : AT(ADDR(.end) - LOAD_OFFSET) {
+	_end = . ;
   }
 
   /* Sections to be discarded */
   /DISCARD/ : {
 	*(.exitcall.exit)
+	*(.discard)
 	}
 
   STABS_DEBUG
@@ -212,6 +214,12 @@ SECTIONS
   DWARF_DEBUG
 }
 
+/*
+ * Build-time check on the image size:
+ */
+ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
+	"kernel image bigger than KERNEL_IMAGE_SIZE")
+
 #ifdef CONFIG_KEXEC
 /* Link time checks */
 #include <asm/kexec.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vmlinux_64.lds.S linux-libre-2.6.30-gnu1/arch/x86/kernel/vmlinux_64.lds.S
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vmlinux_64.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vmlinux_64.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,8 @@
 #define LOAD_OFFSET __START_KERNEL_map
 
 #include <asm-generic/vmlinux.lds.h>
-#include <asm/page.h>
+#include <asm/asm-offsets.h>
+#include <asm/page_types.h>
 
 #undef i386	/* in case the preprocessor is a 32bit one */
 
@@ -13,20 +14,23 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86
 OUTPUT_ARCH(i386:x86-64)
 ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
-_proxy_pda = 1;
 PHDRS {
 	text PT_LOAD FLAGS(5);	/* R_E */
 	data PT_LOAD FLAGS(7);	/* RWE */
 	user PT_LOAD FLAGS(7);	/* RWE */
 	data.init PT_LOAD FLAGS(7);	/* RWE */
+#ifdef CONFIG_SMP
+	percpu PT_LOAD FLAGS(7);	/* RWE */
+#endif
+	data.init2 PT_LOAD FLAGS(7);	/* RWE */
 	note PT_NOTE FLAGS(0);	/* ___ */
 }
 SECTIONS
 {
   . = __START_KERNEL;
   phys_startup_64 = startup_64 - LOAD_OFFSET;
-  _text = .;			/* Text and read-only data */
   .text :  AT(ADDR(.text) - LOAD_OFFSET) {
+	_text = .;			/* Text and read-only data */
 	/* First the code that has to be first for bootstrapping */
 	*(.text.head)
 	_stext = .;
@@ -57,13 +61,13 @@ SECTIONS
   .data : AT(ADDR(.data) - LOAD_OFFSET) {
 	DATA_DATA
 	CONSTRUCTORS
+	_edata = .;			/* End of data section */
 	} :data
 
-  _edata = .;			/* End of data section */
 
-  . = ALIGN(PAGE_SIZE);
-  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+	. = ALIGN(PAGE_SIZE);
+	. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
 	*(.data.cacheline_aligned)
   }
   . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
@@ -121,29 +125,29 @@ SECTIONS
 #undef VVIRT_OFFSET
 #undef VVIRT
 
-  . = ALIGN(THREAD_SIZE);	/* init_task */
   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+	. = ALIGN(THREAD_SIZE);	/* init_task */
 	*(.data.init_task)
   }:data.init
 
-  . = ALIGN(PAGE_SIZE);
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+	. = ALIGN(PAGE_SIZE);
 	*(.data.page_aligned)
   }
 
-  /* might get freed after init */
-  . = ALIGN(PAGE_SIZE);
-  __smp_alt_begin = .;
-  __smp_locks = .;
   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+	/* might get freed after init */
+	. = ALIGN(PAGE_SIZE);
+	__smp_alt_begin = .;
+	__smp_locks = .;
 	*(.smp_locks)
+	__smp_locks_end = .;
+	. = ALIGN(PAGE_SIZE);
+	__smp_alt_end = .;
   }
-  __smp_locks_end = .;
-  . = ALIGN(PAGE_SIZE);
-  __smp_alt_end = .;
 
   . = ALIGN(PAGE_SIZE);		/* Init code and data */
-  __init_begin = .;
+  __init_begin = .;	/* paired with __init_end */
   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
 	_sinittext = .;
 	INIT_TEXT
@@ -155,40 +159,42 @@ SECTIONS
 	__initdata_end = .;
    }
 
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+	. = ALIGN(16);
+	__setup_start = .;
+	*(.init.setup)
+	__setup_end = .;
+  }
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+	__initcall_start = .;
 	INITCALLS
+	__initcall_end = .;
   }
-  __initcall_end = .;
-  __con_initcall_start = .;
   .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+	__con_initcall_start = .;
 	*(.con_initcall.init)
+	__con_initcall_end = .;
   }
-  __con_initcall_end = .;
-  __x86_cpu_dev_start = .;
   .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
+	__x86_cpu_dev_start = .;
 	*(.x86_cpu_dev.init)
+	__x86_cpu_dev_end = .;
   }
-  __x86_cpu_dev_end = .;
   SECURITY_INIT
 
   . = ALIGN(8);
   .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
-  __parainstructions = .;
+	__parainstructions = .;
        *(.parainstructions)
-  __parainstructions_end = .;
+	__parainstructions_end = .;
   }
 
-  . = ALIGN(8);
-  __alt_instructions = .;
   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+	. = ALIGN(8);
+	__alt_instructions = .;
 	*(.altinstructions)
+	__alt_instructions_end = .;
   }
-  __alt_instructions_end = .;
   .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
 	*(.altinstr_replacement)
   }
@@ -203,28 +209,53 @@ SECTIONS
 
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(PAGE_SIZE);
-  __initramfs_start = .;
-  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
-  __initramfs_end = .;
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+	__initramfs_start = .;
+	*(.init.ramfs)
+	__initramfs_end = .;
+  }
 #endif
 
+#ifdef CONFIG_SMP
+  /*
+   * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
+   * output PHDR, so the next output section - __data_nosave - should
+   * start another section data.init2.  Also, pda should be at the head of
+   * percpu area.  Preallocate it and define the percpu offset symbol
+   * so that it can be accessed as a percpu variable.
+   */
+  . = ALIGN(PAGE_SIZE);
+  PERCPU_VADDR(0, :percpu)
+#else
   PERCPU(PAGE_SIZE)
+#endif
 
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
-  . = ALIGN(PAGE_SIZE);
-  __nosave_begin = .;
-  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
-  . = ALIGN(PAGE_SIZE);
-  __nosave_end = .;
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+	. = ALIGN(PAGE_SIZE);
+	__nosave_begin = .;
+	*(.data.nosave)
+	. = ALIGN(PAGE_SIZE);
+	__nosave_end = .;
+  } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
 
-  __bss_start = .;		/* BSS */
   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+	. = ALIGN(PAGE_SIZE);
+	__bss_start = .;		/* BSS */
 	*(.bss.page_aligned)
 	*(.bss)
-	}
-  __bss_stop = .;
+	__bss_stop = .;
+  }
+
+  .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
+	. = ALIGN(PAGE_SIZE);
+	__brk_base = . ;
+ 	. += 64 * 1024 ;	/* 64k alignment slop space */
+	*(.brk_reservation)	/* areas brk users have reserved */
+	__brk_limit = . ;
+  }
 
   _end = . ;
 
@@ -232,6 +263,7 @@ SECTIONS
   /DISCARD/ : {
 	*(.exitcall.exit)
 	*(.eh_frame)
+	*(.discard)
 	}
 
   STABS_DEBUG
@@ -239,8 +271,28 @@ SECTIONS
   DWARF_DEBUG
 }
 
+ /*
+  * Per-cpu symbols which need to be offset from __per_cpu_load
+  * for the boot processor.
+  */
+#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
+INIT_PER_CPU(gdt_page);
+INIT_PER_CPU(irq_stack_union);
+
 /*
  * Build-time check on the image size:
  */
 ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
 	"kernel image bigger than KERNEL_IMAGE_SIZE")
+
+#ifdef CONFIG_SMP
+ASSERT((per_cpu__irq_stack_union == 0),
+        "irq_stack_union is not at start of per-cpu area");
+#endif
+
+#ifdef CONFIG_KEXEC
+#include <asm/kexec.h>
+
+ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,
+       "kexec control code size is too big")
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/vsmp_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/vsmp_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/vsmp_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/vsmp_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,7 @@ static unsigned long vsmp_save_fl(void)
 		flags &= ~X86_EFLAGS_IF;
 	return flags;
 }
+PV_CALLEE_SAVE_REGS_THUNK(vsmp_save_fl);
 
 static void vsmp_restore_fl(unsigned long flags)
 {
@@ -46,6 +47,7 @@ static void vsmp_restore_fl(unsigned lon
 		flags |= X86_EFLAGS_AC;
 	native_restore_fl(flags);
 }
+PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl);
 
 static void vsmp_irq_disable(void)
 {
@@ -53,6 +55,7 @@ static void vsmp_irq_disable(void)
 
 	native_restore_fl((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
 }
+PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable);
 
 static void vsmp_irq_enable(void)
 {
@@ -60,6 +63,7 @@ static void vsmp_irq_enable(void)
 
 	native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
 }
+PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_enable);
 
 static unsigned __init_or_module vsmp_patch(u8 type, u16 clobbers, void *ibuf,
 				  unsigned long addr, unsigned len)
@@ -90,10 +94,10 @@ static void __init set_vsmp_pv_ops(void)
 	       cap, ctl);
 	if (cap & ctl & (1 << 4)) {
 		/* Setup irq ops and turn on vSMP  IRQ fastpath handling */
-		pv_irq_ops.irq_disable = vsmp_irq_disable;
-		pv_irq_ops.irq_enable  = vsmp_irq_enable;
-		pv_irq_ops.save_fl  = vsmp_save_fl;
-		pv_irq_ops.restore_fl  = vsmp_restore_fl;
+		pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable);
+		pv_irq_ops.irq_enable  = PV_CALLEE_SAVE(vsmp_irq_enable);
+		pv_irq_ops.save_fl  = PV_CALLEE_SAVE(vsmp_save_fl);
+		pv_irq_ops.restore_fl  = PV_CALLEE_SAVE(vsmp_restore_fl);
 		pv_init_ops.patch = vsmp_patch;
 
 		ctl &= ~(1 << 4);
@@ -135,6 +139,7 @@ int is_vsmp_box(void)
 		return 0;
 	}
 }
+
 #else
 static void __init detect_vsmp_box(void)
 {
@@ -144,7 +149,6 @@ int is_vsmp_box(void)
 	return 0;
 }
 #endif
-
 void __init vsmp_init(void)
 {
 	detect_vsmp_box();
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/x8664_ksyms_64.c linux-libre-2.6.30-gnu1/arch/x86/kernel/x8664_ksyms_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/x8664_ksyms_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,5 +58,3 @@ EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(init_level4_pgt);
 EXPORT_SYMBOL(load_gs_index);
-
-EXPORT_SYMBOL(_proxy_pda);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kernel/xsave.c linux-libre-2.6.30-gnu1/arch/x86/kernel/xsave.c
--- linux-libre-2.6.29-gnu1/arch/x86/kernel/xsave.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kernel/xsave.c	2009-06-09 23:05:27.000000000 -0400
@@ -89,7 +89,7 @@ int save_i387_xstate(void __user *buf)
 
 	if (!used_math())
 		return 0;
-	clear_used_math(); /* trigger finit */
+
 	if (task_thread_info(tsk)->status & TS_USEDFPU) {
 		/*
 	 	 * Start with clearing the user buffer. This will present a
@@ -114,6 +114,8 @@ int save_i387_xstate(void __user *buf)
 			return -1;
 	}
 
+	clear_used_math(); /* trigger finit */
+
 	if (task_thread_info(tsk)->status & TS_XSAVE) {
 		struct _fpstate __user *fx = buf;
 		struct _xstate __user *x = buf;
@@ -324,7 +326,7 @@ void __ref xsave_cntxt_init(void)
 	}
 
 	/*
-	 * for now OS knows only about FP/SSE
+	 * Support only the state known to OS.
 	 */
 	pcntxt_mask = pcntxt_mask & XCNTXT_MASK;
 	xsave_init();
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/i8254.c linux-libre-2.6.30-gnu1/arch/x86/kvm/i8254.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/i8254.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/i8254.c	2009-06-09 23:05:27.000000000 -0400
@@ -201,6 +201,9 @@ static int __pit_timer_fn(struct kvm_kpi
 	if (!atomic_inc_and_test(&pt->pending))
 		set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
 
+	if (!pt->reinject)
+		atomic_set(&pt->pending, 1);
+
 	if (vcpu0 && waitqueue_active(&vcpu0->wq))
 		wake_up_interruptible(&vcpu0->wq);
 
@@ -536,6 +539,16 @@ void kvm_pit_reset(struct kvm_pit *pit)
 	pit->pit_state.irq_ack = 1;
 }
 
+static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
+{
+	struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier);
+
+	if (!mask) {
+		atomic_set(&pit->pit_state.pit_timer.pending, 0);
+		pit->pit_state.irq_ack = 1;
+	}
+}
+
 struct kvm_pit *kvm_create_pit(struct kvm *kvm)
 {
 	struct kvm_pit *pit;
@@ -545,9 +558,7 @@ struct kvm_pit *kvm_create_pit(struct kv
 	if (!pit)
 		return NULL;
 
-	mutex_lock(&kvm->lock);
 	pit->irq_source_id = kvm_request_irq_source_id(kvm);
-	mutex_unlock(&kvm->lock);
 	if (pit->irq_source_id < 0) {
 		kfree(pit);
 		return NULL;
@@ -580,10 +591,14 @@ struct kvm_pit *kvm_create_pit(struct kv
 	pit_state->irq_ack_notifier.gsi = 0;
 	pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
 	kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
+	pit_state->pit_timer.reinject = true;
 	mutex_unlock(&pit->pit_state.lock);
 
 	kvm_pit_reset(pit);
 
+	pit->mask_notifier.func = pit_mask_notifer;
+	kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+
 	return pit;
 }
 
@@ -592,6 +607,8 @@ void kvm_free_pit(struct kvm *kvm)
 	struct hrtimer *timer;
 
 	if (kvm->arch.vpit) {
+		kvm_unregister_irq_mask_notifier(kvm, 0,
+					       &kvm->arch.vpit->mask_notifier);
 		mutex_lock(&kvm->arch.vpit->pit_state.lock);
 		timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
 		hrtimer_cancel(timer);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/i8254.h linux-libre-2.6.30-gnu1/arch/x86/kvm/i8254.h
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/i8254.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/i8254.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@ struct kvm_kpit_timer {
 	s64 period; /* unit: ns */
 	s64 scheduled;
 	atomic_t pending;
+	bool reinject;
 };
 
 struct kvm_kpit_channel_state {
@@ -45,6 +46,7 @@ struct kvm_pit {
 	struct kvm *kvm;
 	struct kvm_kpit_state pit_state;
 	int irq_source_id;
+	struct kvm_irq_mask_notifier mask_notifier;
 };
 
 #define KVM_PIT_BASE_ADDRESS	    0x40
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/i8259.c linux-libre-2.6.30-gnu1/arch/x86/kvm/i8259.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/i8259.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/i8259.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,11 +32,13 @@
 #include <linux/kvm_host.h>
 
 static void pic_lock(struct kvm_pic *s)
+	__acquires(&s->lock)
 {
 	spin_lock(&s->lock);
 }
 
 static void pic_unlock(struct kvm_pic *s)
+	__releases(&s->lock)
 {
 	struct kvm *kvm = s->kvm;
 	unsigned acks = s->pending_acks;
@@ -49,7 +51,8 @@ static void pic_unlock(struct kvm_pic *s
 	spin_unlock(&s->lock);
 
 	while (acks) {
-		kvm_notify_acked_irq(kvm, __ffs(acks));
+		kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)),
+				     __ffs(acks));
 		acks &= acks - 1;
 	}
 
@@ -76,12 +79,13 @@ void kvm_pic_clear_isr_ack(struct kvm *k
 /*
  * set irq level. If an edge is detected, then the IRR is set to 1
  */
-static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
+static inline int pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
 {
-	int mask;
+	int mask, ret = 1;
 	mask = 1 << irq;
 	if (s->elcr & mask)	/* level triggered */
 		if (level) {
+			ret = !(s->irr & mask);
 			s->irr |= mask;
 			s->last_irr |= mask;
 		} else {
@@ -90,11 +94,15 @@ static inline void pic_set_irq1(struct k
 		}
 	else	/* edge triggered */
 		if (level) {
-			if ((s->last_irr & mask) == 0)
+			if ((s->last_irr & mask) == 0) {
+				ret = !(s->irr & mask);
 				s->irr |= mask;
+			}
 			s->last_irr |= mask;
 		} else
 			s->last_irr &= ~mask;
+
+	return (s->imr & mask) ? -1 : ret;
 }
 
 /*
@@ -171,16 +179,19 @@ void kvm_pic_update_irq(struct kvm_pic *
 	pic_unlock(s);
 }
 
-void kvm_pic_set_irq(void *opaque, int irq, int level)
+int kvm_pic_set_irq(void *opaque, int irq, int level)
 {
 	struct kvm_pic *s = opaque;
+	int ret = -1;
 
 	pic_lock(s);
 	if (irq >= 0 && irq < PIC_NUM_PINS) {
-		pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
+		ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 		pic_update_irq(s);
 	}
 	pic_unlock(s);
+
+	return ret;
 }
 
 /*
@@ -232,7 +243,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
 	}
 	pic_update_irq(s);
 	pic_unlock(s);
-	kvm_notify_acked_irq(kvm, irq);
+	kvm_notify_acked_irq(kvm, SELECT_PIC(irq), irq);
 
 	return intno;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/irq.h linux-libre-2.6.30-gnu1/arch/x86/kvm/irq.h
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,8 @@
 #include "lapic.h"
 
 #define PIC_NUM_PINS 16
+#define SELECT_PIC(irq) \
+	((irq) < 8 ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE)
 
 struct kvm;
 struct kvm_vcpu;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/Kconfig linux-libre-2.6.30-gnu1/arch/x86/kvm/Kconfig
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,10 @@
 config HAVE_KVM
        bool
 
+config HAVE_KVM_IRQCHIP
+       bool
+       default y
+
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
 	depends on HAVE_KVM || X86
@@ -55,7 +59,8 @@ config KVM_AMD
 
 config KVM_TRACE
 	bool "KVM trace support"
-	depends on KVM && MARKERS && SYSFS
+	depends on KVM && SYSFS
+	select MARKERS
 	select RELAY
 	select DEBUG_FS
 	default n
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/kvm_svm.h linux-libre-2.6.30-gnu1/arch/x86/kvm/kvm_svm.h
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/kvm_svm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/kvm_svm.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,6 @@ static const u32 host_save_user_msrs[] =
 };
 
 #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
-#define NUM_DB_REGS 4
 
 struct kvm_vcpu;
 
@@ -29,18 +28,23 @@ struct vcpu_svm {
 	struct svm_cpu_data *svm_data;
 	uint64_t asid_generation;
 
-	unsigned long db_regs[NUM_DB_REGS];
-
 	u64 next_rip;
 
 	u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
 	u64 host_gs_base;
 	unsigned long host_cr2;
-	unsigned long host_db_regs[NUM_DB_REGS];
-	unsigned long host_dr6;
-	unsigned long host_dr7;
 
 	u32 *msrpm;
+	struct vmcb *hsave;
+	u64 hsave_msr;
+
+	u64 nested_vmcb;
+
+	/* These are the merged vectors */
+	u32 *nested_msrpm;
+
+	/* gpa pointers to the real vectors */
+	u64 nested_vmcb_msrpm;
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/mmu.c linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/mmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -145,11 +145,20 @@ struct kvm_rmap_desc {
 	struct kvm_rmap_desc *more;
 };
 
-struct kvm_shadow_walk {
-	int (*entry)(struct kvm_shadow_walk *walk, struct kvm_vcpu *vcpu,
-		     u64 addr, u64 *spte, int level);
+struct kvm_shadow_walk_iterator {
+	u64 addr;
+	hpa_t shadow_addr;
+	int level;
+	u64 *sptep;
+	unsigned index;
 };
 
+#define for_each_shadow_entry(_vcpu, _addr, _walker)    \
+	for (shadow_walk_init(&(_walker), _vcpu, _addr);	\
+	     shadow_walk_okay(&(_walker));			\
+	     shadow_walk_next(&(_walker)))
+
+
 struct kvm_unsync_walk {
 	int (*entry) (struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk);
 };
@@ -343,7 +352,6 @@ static void *mmu_memory_cache_alloc(stru
 
 	BUG_ON(!mc->nobjs);
 	p = mc->objects[--mc->nobjs];
-	memset(p, 0, size);
 	return p;
 }
 
@@ -794,10 +802,8 @@ static struct kvm_mmu_page *kvm_mmu_allo
 	set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
 	list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
 	INIT_LIST_HEAD(&sp->oos_link);
-	ASSERT(is_empty_shadow_page(sp->spt));
 	bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS);
 	sp->multimapped = 0;
-	sp->global = 1;
 	sp->parent_pte = parent_pte;
 	--vcpu->kvm->arch.n_free_mmu_pages;
 	return sp;
@@ -983,8 +989,8 @@ struct kvm_mmu_pages {
 	     idx < 512;					\
 	     idx = find_next_bit(bitmap, 512, idx+1))
 
-int mmu_pages_add(struct kvm_mmu_pages *pvec, struct kvm_mmu_page *sp,
-		   int idx)
+static int mmu_pages_add(struct kvm_mmu_pages *pvec, struct kvm_mmu_page *sp,
+			 int idx)
 {
 	int i;
 
@@ -1059,7 +1065,7 @@ static struct kvm_mmu_page *kvm_mmu_look
 	index = kvm_page_table_hashfn(gfn);
 	bucket = &kvm->arch.mmu_page_hash[index];
 	hlist_for_each_entry(sp, node, bucket, hash_link)
-		if (sp->gfn == gfn && !sp->role.metaphysical
+		if (sp->gfn == gfn && !sp->role.direct
 		    && !sp->role.invalid) {
 			pgprintk("%s: found role %x\n",
 				 __func__, sp->role.word);
@@ -1115,8 +1121,9 @@ struct mmu_page_path {
 			i < pvec.nr && ({ sp = pvec.page[i].sp; 1;});	\
 			i = mmu_pages_next(&pvec, &parents, i))
 
-int mmu_pages_next(struct kvm_mmu_pages *pvec, struct mmu_page_path *parents,
-		   int i)
+static int mmu_pages_next(struct kvm_mmu_pages *pvec,
+			  struct mmu_page_path *parents,
+			  int i)
 {
 	int n;
 
@@ -1135,7 +1142,7 @@ int mmu_pages_next(struct kvm_mmu_pages
 	return n;
 }
 
-void mmu_pages_clear_parents(struct mmu_page_path *parents)
+static void mmu_pages_clear_parents(struct mmu_page_path *parents)
 {
 	struct kvm_mmu_page *sp;
 	unsigned int level = 0;
@@ -1193,7 +1200,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
 					     gfn_t gfn,
 					     gva_t gaddr,
 					     unsigned level,
-					     int metaphysical,
+					     int direct,
 					     unsigned access,
 					     u64 *parent_pte)
 {
@@ -1204,10 +1211,9 @@ static struct kvm_mmu_page *kvm_mmu_get_
 	struct kvm_mmu_page *sp;
 	struct hlist_node *node, *tmp;
 
-	role.word = 0;
-	role.glevels = vcpu->arch.mmu.root_level;
+	role = vcpu->arch.mmu.base_role;
 	role.level = level;
-	role.metaphysical = metaphysical;
+	role.direct = direct;
 	role.access = access;
 	if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
 		quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
@@ -1242,8 +1248,9 @@ static struct kvm_mmu_page *kvm_mmu_get_
 	pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word);
 	sp->gfn = gfn;
 	sp->role = role;
+	sp->global = 0;
 	hlist_add_head(&sp->hash_link, bucket);
-	if (!metaphysical) {
+	if (!direct) {
 		if (rmap_write_protect(vcpu->kvm, gfn))
 			kvm_flush_remote_tlbs(vcpu->kvm);
 		account_shadowed(vcpu->kvm, gfn);
@@ -1255,35 +1262,35 @@ static struct kvm_mmu_page *kvm_mmu_get_
 	return sp;
 }
 
-static int walk_shadow(struct kvm_shadow_walk *walker,
-		       struct kvm_vcpu *vcpu, u64 addr)
+static void shadow_walk_init(struct kvm_shadow_walk_iterator *iterator,
+			     struct kvm_vcpu *vcpu, u64 addr)
 {
-	hpa_t shadow_addr;
-	int level;
-	int r;
-	u64 *sptep;
-	unsigned index;
-
-	shadow_addr = vcpu->arch.mmu.root_hpa;
-	level = vcpu->arch.mmu.shadow_root_level;
-	if (level == PT32E_ROOT_LEVEL) {
-		shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
-		shadow_addr &= PT64_BASE_ADDR_MASK;
-		if (!shadow_addr)
-			return 1;
-		--level;
+	iterator->addr = addr;
+	iterator->shadow_addr = vcpu->arch.mmu.root_hpa;
+	iterator->level = vcpu->arch.mmu.shadow_root_level;
+	if (iterator->level == PT32E_ROOT_LEVEL) {
+		iterator->shadow_addr
+			= vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
+		iterator->shadow_addr &= PT64_BASE_ADDR_MASK;
+		--iterator->level;
+		if (!iterator->shadow_addr)
+			iterator->level = 0;
 	}
+}
 
-	while (level >= PT_PAGE_TABLE_LEVEL) {
-		index = SHADOW_PT_INDEX(addr, level);
-		sptep = ((u64 *)__va(shadow_addr)) + index;
-		r = walker->entry(walker, vcpu, addr, sptep, level);
-		if (r)
-			return r;
-		shadow_addr = *sptep & PT64_BASE_ADDR_MASK;
-		--level;
-	}
-	return 0;
+static bool shadow_walk_okay(struct kvm_shadow_walk_iterator *iterator)
+{
+	if (iterator->level < PT_PAGE_TABLE_LEVEL)
+		return false;
+	iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level);
+	iterator->sptep	= ((u64 *)__va(iterator->shadow_addr)) + iterator->index;
+	return true;
+}
+
+static void shadow_walk_next(struct kvm_shadow_walk_iterator *iterator)
+{
+	iterator->shadow_addr = *iterator->sptep & PT64_BASE_ADDR_MASK;
+	--iterator->level;
 }
 
 static void kvm_mmu_page_unlink_children(struct kvm *kvm,
@@ -1388,7 +1395,7 @@ static int kvm_mmu_zap_page(struct kvm *
 	kvm_mmu_page_unlink_children(kvm, sp);
 	kvm_mmu_unlink_parents(kvm, sp);
 	kvm_flush_remote_tlbs(kvm);
-	if (!sp->role.invalid && !sp->role.metaphysical)
+	if (!sp->role.invalid && !sp->role.direct)
 		unaccount_shadowed(kvm, sp->gfn);
 	if (sp->unsync)
 		kvm_unlink_unsync_page(kvm, sp);
@@ -1451,7 +1458,7 @@ static int kvm_mmu_unprotect_page(struct
 	index = kvm_page_table_hashfn(gfn);
 	bucket = &kvm->arch.mmu_page_hash[index];
 	hlist_for_each_entry_safe(sp, node, n, bucket, hash_link)
-		if (sp->gfn == gfn && !sp->role.metaphysical) {
+		if (sp->gfn == gfn && !sp->role.direct) {
 			pgprintk("%s: gfn %lx role %x\n", __func__, gfn,
 				 sp->role.word);
 			r = 1;
@@ -1463,11 +1470,20 @@ static int kvm_mmu_unprotect_page(struct
 
 static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
 {
+	unsigned index;
+	struct hlist_head *bucket;
 	struct kvm_mmu_page *sp;
+	struct hlist_node *node, *nn;
 
-	while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) {
-		pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word);
-		kvm_mmu_zap_page(kvm, sp);
+	index = kvm_page_table_hashfn(gfn);
+	bucket = &kvm->arch.mmu_page_hash[index];
+	hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) {
+		if (sp->gfn == gfn && !sp->role.direct
+		    && !sp->role.invalid) {
+			pgprintk("%s: zap %lx %x\n",
+				 __func__, gfn, sp->role.word);
+			kvm_mmu_zap_page(kvm, sp);
+		}
 	}
 }
 
@@ -1622,7 +1638,7 @@ static int kvm_unsync_page(struct kvm_vc
 	bucket = &vcpu->kvm->arch.mmu_page_hash[index];
 	/* don't unsync if pagetable is shadowed with multiple roles */
 	hlist_for_each_entry_safe(s, node, n, bucket, hash_link) {
-		if (s->gfn != sp->gfn || s->role.metaphysical)
+		if (s->gfn != sp->gfn || s->role.direct)
 			continue;
 		if (s->role.word != sp->role.word)
 			return 1;
@@ -1669,8 +1685,6 @@ static int set_spte(struct kvm_vcpu *vcp
 	u64 mt_mask = shadow_mt_mask;
 	struct kvm_mmu_page *sp = page_header(__pa(shadow_pte));
 
-	if (!(vcpu->arch.cr4 & X86_CR4_PGE))
-		global = 0;
 	if (!global && sp->global) {
 		sp->global = 0;
 		if (sp->unsync) {
@@ -1777,12 +1791,8 @@ static void mmu_set_spte(struct kvm_vcpu
 			pgprintk("hfn old %lx new %lx\n",
 				 spte_to_pfn(*shadow_pte), pfn);
 			rmap_remove(vcpu->kvm, shadow_pte);
-		} else {
-			if (largepage)
-				was_rmapped = is_large_pte(*shadow_pte);
-			else
-				was_rmapped = 1;
-		}
+		} else
+			was_rmapped = 1;
 	}
 	if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
 		      dirty, largepage, global, gfn, pfn, speculative, true)) {
@@ -1820,67 +1830,42 @@ static void nonpaging_new_cr3(struct kvm
 {
 }
 
-struct direct_shadow_walk {
-	struct kvm_shadow_walk walker;
-	pfn_t pfn;
-	int write;
-	int largepage;
-	int pt_write;
-};
-
-static int direct_map_entry(struct kvm_shadow_walk *_walk,
-			    struct kvm_vcpu *vcpu,
-			    u64 addr, u64 *sptep, int level)
+static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
+			int largepage, gfn_t gfn, pfn_t pfn)
 {
-	struct direct_shadow_walk *walk =
-		container_of(_walk, struct direct_shadow_walk, walker);
+	struct kvm_shadow_walk_iterator iterator;
 	struct kvm_mmu_page *sp;
+	int pt_write = 0;
 	gfn_t pseudo_gfn;
-	gfn_t gfn = addr >> PAGE_SHIFT;
-
-	if (level == PT_PAGE_TABLE_LEVEL
-	    || (walk->largepage && level == PT_DIRECTORY_LEVEL)) {
-		mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
-			     0, walk->write, 1, &walk->pt_write,
-			     walk->largepage, 0, gfn, walk->pfn, false);
-		++vcpu->stat.pf_fixed;
-		return 1;
-	}
 
-	if (*sptep == shadow_trap_nonpresent_pte) {
-		pseudo_gfn = (addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
-		sp = kvm_mmu_get_page(vcpu, pseudo_gfn, (gva_t)addr, level - 1,
-				      1, ACC_ALL, sptep);
-		if (!sp) {
-			pgprintk("nonpaging_map: ENOMEM\n");
-			kvm_release_pfn_clean(walk->pfn);
-			return -ENOMEM;
+	for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
+		if (iterator.level == PT_PAGE_TABLE_LEVEL
+		    || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
+			mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
+				     0, write, 1, &pt_write,
+				     largepage, 0, gfn, pfn, false);
+			++vcpu->stat.pf_fixed;
+			break;
 		}
 
-		set_shadow_pte(sptep,
-			       __pa(sp->spt)
-			       | PT_PRESENT_MASK | PT_WRITABLE_MASK
-			       | shadow_user_mask | shadow_x_mask);
-	}
-	return 0;
-}
-
-static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
-			int largepage, gfn_t gfn, pfn_t pfn)
-{
-	int r;
-	struct direct_shadow_walk walker = {
-		.walker = { .entry = direct_map_entry, },
-		.pfn = pfn,
-		.largepage = largepage,
-		.write = write,
-		.pt_write = 0,
-	};
+		if (*iterator.sptep == shadow_trap_nonpresent_pte) {
+			pseudo_gfn = (iterator.addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
+			sp = kvm_mmu_get_page(vcpu, pseudo_gfn, iterator.addr,
+					      iterator.level - 1,
+					      1, ACC_ALL, iterator.sptep);
+			if (!sp) {
+				pgprintk("nonpaging_map: ENOMEM\n");
+				kvm_release_pfn_clean(pfn);
+				return -ENOMEM;
+			}
 
-	r = walk_shadow(&walker.walker, vcpu, gfn << PAGE_SHIFT);
-	if (r < 0)
-		return r;
-	return walker.pt_write;
+			set_shadow_pte(iterator.sptep,
+				       __pa(sp->spt)
+				       | PT_PRESENT_MASK | PT_WRITABLE_MASK
+				       | shadow_user_mask | shadow_x_mask);
+		}
+	}
+	return pt_write;
 }
 
 static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
@@ -1962,7 +1947,7 @@ static void mmu_alloc_roots(struct kvm_v
 	int i;
 	gfn_t root_gfn;
 	struct kvm_mmu_page *sp;
-	int metaphysical = 0;
+	int direct = 0;
 
 	root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
 
@@ -1971,18 +1956,18 @@ static void mmu_alloc_roots(struct kvm_v
 
 		ASSERT(!VALID_PAGE(root));
 		if (tdp_enabled)
-			metaphysical = 1;
+			direct = 1;
 		sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
-				      PT64_ROOT_LEVEL, metaphysical,
+				      PT64_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
 		root = __pa(sp->spt);
 		++sp->root_count;
 		vcpu->arch.mmu.root_hpa = root;
 		return;
 	}
-	metaphysical = !is_paging(vcpu);
+	direct = !is_paging(vcpu);
 	if (tdp_enabled)
-		metaphysical = 1;
+		direct = 1;
 	for (i = 0; i < 4; ++i) {
 		hpa_t root = vcpu->arch.mmu.pae_root[i];
 
@@ -1996,7 +1981,7 @@ static void mmu_alloc_roots(struct kvm_v
 		} else if (vcpu->arch.mmu.root_level == 0)
 			root_gfn = 0;
 		sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
-				      PT32_ROOT_LEVEL, metaphysical,
+				      PT32_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
 		root = __pa(sp->spt);
 		++sp->root_count;
@@ -2251,17 +2236,23 @@ static int init_kvm_tdp_mmu(struct kvm_v
 
 static int init_kvm_softmmu(struct kvm_vcpu *vcpu)
 {
+	int r;
+
 	ASSERT(vcpu);
 	ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
 
 	if (!is_paging(vcpu))
-		return nonpaging_init_context(vcpu);
+		r = nonpaging_init_context(vcpu);
 	else if (is_long_mode(vcpu))
-		return paging64_init_context(vcpu);
+		r = paging64_init_context(vcpu);
 	else if (is_pae(vcpu))
-		return paging32E_init_context(vcpu);
+		r = paging32E_init_context(vcpu);
 	else
-		return paging32_init_context(vcpu);
+		r = paging32_init_context(vcpu);
+
+	vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level;
+
+	return r;
 }
 
 static int init_kvm_mmu(struct kvm_vcpu *vcpu)
@@ -2492,7 +2483,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *
 	index = kvm_page_table_hashfn(gfn);
 	bucket = &vcpu->kvm->arch.mmu_page_hash[index];
 	hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) {
-		if (sp->gfn != gfn || sp->role.metaphysical || sp->role.invalid)
+		if (sp->gfn != gfn || sp->role.direct || sp->role.invalid)
 			continue;
 		pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8;
 		misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
@@ -2906,8 +2897,7 @@ static int kvm_pv_mmu_write(struct kvm_v
 
 static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu)
 {
-	kvm_x86_ops->tlb_flush(vcpu);
-	set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
+	kvm_set_cr3(vcpu, vcpu->arch.cr3);
 	return 1;
 }
 
@@ -3130,7 +3120,7 @@ static void audit_write_protection(struc
 	gfn_t gfn;
 
 	list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
-		if (sp->role.metaphysical)
+		if (sp->role.direct)
 			continue;
 
 		gfn = unalias_gfn(vcpu->kvm, sp->gfn);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/mmu.h linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,7 +54,7 @@ static inline int kvm_mmu_reload(struct
 static inline int is_long_mode(struct kvm_vcpu *vcpu)
 {
 #ifdef CONFIG_X86_64
-	return vcpu->arch.shadow_efer & EFER_LME;
+	return vcpu->arch.shadow_efer & EFER_LMA;
 #else
 	return 0;
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/paging_tmpl.h linux-libre-2.6.30-gnu1/arch/x86/kvm/paging_tmpl.h
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/paging_tmpl.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/paging_tmpl.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,6 @@
 #if PTTYPE == 64
 	#define pt_element_t u64
 	#define guest_walker guest_walker64
-	#define shadow_walker shadow_walker64
 	#define FNAME(name) paging##64_##name
 	#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
 	#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
@@ -42,7 +41,6 @@
 #elif PTTYPE == 32
 	#define pt_element_t u32
 	#define guest_walker guest_walker32
-	#define shadow_walker shadow_walker32
 	#define FNAME(name) paging##32_##name
 	#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
 	#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
@@ -73,18 +71,6 @@ struct guest_walker {
 	u32 error_code;
 };
 
-struct shadow_walker {
-	struct kvm_shadow_walk walker;
-	struct guest_walker *guest_walker;
-	int user_fault;
-	int write_fault;
-	int largepage;
-	int *ptwrite;
-	pfn_t pfn;
-	u64 *sptep;
-	gpa_t pte_gpa;
-};
-
 static gfn_t gpte_to_gfn(pt_element_t gpte)
 {
 	return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -283,91 +269,79 @@ static void FNAME(update_pte)(struct kvm
 /*
  * Fetch a shadow pte for a specific level in the paging hierarchy.
  */
-static int FNAME(shadow_walk_entry)(struct kvm_shadow_walk *_sw,
-				    struct kvm_vcpu *vcpu, u64 addr,
-				    u64 *sptep, int level)
+static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
+			 struct guest_walker *gw,
+			 int user_fault, int write_fault, int largepage,
+			 int *ptwrite, pfn_t pfn)
 {
-	struct shadow_walker *sw =
-		container_of(_sw, struct shadow_walker, walker);
-	struct guest_walker *gw = sw->guest_walker;
 	unsigned access = gw->pt_access;
 	struct kvm_mmu_page *shadow_page;
-	u64 spte;
-	int metaphysical;
+	u64 spte, *sptep;
+	int direct;
 	gfn_t table_gfn;
 	int r;
+	int level;
 	pt_element_t curr_pte;
+	struct kvm_shadow_walk_iterator iterator;
 
-	if (level == PT_PAGE_TABLE_LEVEL
-	    || (sw->largepage && level == PT_DIRECTORY_LEVEL)) {
-		mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
-			     sw->user_fault, sw->write_fault,
-			     gw->ptes[gw->level-1] & PT_DIRTY_MASK,
-			     sw->ptwrite, sw->largepage,
-			     gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
-			     gw->gfn, sw->pfn, false);
-		sw->sptep = sptep;
-		return 1;
-	}
-
-	if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
-		return 0;
-
-	if (is_large_pte(*sptep)) {
-		set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
-		kvm_flush_remote_tlbs(vcpu->kvm);
-		rmap_remove(vcpu->kvm, sptep);
-	}
+	if (!is_present_pte(gw->ptes[gw->level - 1]))
+		return NULL;
 
-	if (level == PT_DIRECTORY_LEVEL && gw->level == PT_DIRECTORY_LEVEL) {
-		metaphysical = 1;
-		if (!is_dirty_pte(gw->ptes[level - 1]))
-			access &= ~ACC_WRITE_MASK;
-		table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
-	} else {
-		metaphysical = 0;
-		table_gfn = gw->table_gfn[level - 2];
-	}
-	shadow_page = kvm_mmu_get_page(vcpu, table_gfn, (gva_t)addr, level-1,
-				       metaphysical, access, sptep);
-	if (!metaphysical) {
-		r = kvm_read_guest_atomic(vcpu->kvm, gw->pte_gpa[level - 2],
-					  &curr_pte, sizeof(curr_pte));
-		if (r || curr_pte != gw->ptes[level - 2]) {
-			kvm_mmu_put_page(shadow_page, sptep);
-			kvm_release_pfn_clean(sw->pfn);
-			sw->sptep = NULL;
-			return 1;
+	for_each_shadow_entry(vcpu, addr, iterator) {
+		level = iterator.level;
+		sptep = iterator.sptep;
+		if (level == PT_PAGE_TABLE_LEVEL
+		    || (largepage && level == PT_DIRECTORY_LEVEL)) {
+			mmu_set_spte(vcpu, sptep, access,
+				     gw->pte_access & access,
+				     user_fault, write_fault,
+				     gw->ptes[gw->level-1] & PT_DIRTY_MASK,
+				     ptwrite, largepage,
+				     gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
+				     gw->gfn, pfn, false);
+			break;
 		}
-	}
 
-	spte = __pa(shadow_page->spt) | PT_PRESENT_MASK | PT_ACCESSED_MASK
-		| PT_WRITABLE_MASK | PT_USER_MASK;
-	*sptep = spte;
-	return 0;
-}
+		if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
+			continue;
 
-static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
-			 struct guest_walker *guest_walker,
-			 int user_fault, int write_fault, int largepage,
-			 int *ptwrite, pfn_t pfn)
-{
-	struct shadow_walker walker = {
-		.walker = { .entry = FNAME(shadow_walk_entry), },
-		.guest_walker = guest_walker,
-		.user_fault = user_fault,
-		.write_fault = write_fault,
-		.largepage = largepage,
-		.ptwrite = ptwrite,
-		.pfn = pfn,
-	};
+		if (is_large_pte(*sptep)) {
+			rmap_remove(vcpu->kvm, sptep);
+			set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+			kvm_flush_remote_tlbs(vcpu->kvm);
+		}
 
-	if (!is_present_pte(guest_walker->ptes[guest_walker->level - 1]))
-		return NULL;
+		if (level == PT_DIRECTORY_LEVEL
+		    && gw->level == PT_DIRECTORY_LEVEL) {
+			direct = 1;
+			if (!is_dirty_pte(gw->ptes[level - 1]))
+				access &= ~ACC_WRITE_MASK;
+			table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
+		} else {
+			direct = 0;
+			table_gfn = gw->table_gfn[level - 2];
+		}
+		shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
+					       direct, access, sptep);
+		if (!direct) {
+			r = kvm_read_guest_atomic(vcpu->kvm,
+						  gw->pte_gpa[level - 2],
+						  &curr_pte, sizeof(curr_pte));
+			if (r || curr_pte != gw->ptes[level - 2]) {
+				kvm_mmu_put_page(shadow_page, sptep);
+				kvm_release_pfn_clean(pfn);
+				sptep = NULL;
+				break;
+			}
+		}
 
-	walk_shadow(&walker.walker, vcpu, addr);
+		spte = __pa(shadow_page->spt)
+			| PT_PRESENT_MASK | PT_ACCESSED_MASK
+			| PT_WRITABLE_MASK | PT_USER_MASK;
+		*sptep = spte;
+	}
 
-	return walker.sptep;
+	return sptep;
 }
 
 /*
@@ -465,54 +439,56 @@ out_unlock:
 	return 0;
 }
 
-static int FNAME(shadow_invlpg_entry)(struct kvm_shadow_walk *_sw,
-				      struct kvm_vcpu *vcpu, u64 addr,
-				      u64 *sptep, int level)
+static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 {
-	struct shadow_walker *sw =
-		container_of(_sw, struct shadow_walker, walker);
+	struct kvm_shadow_walk_iterator iterator;
+	pt_element_t gpte;
+	gpa_t pte_gpa = -1;
+	int level;
+	u64 *sptep;
+	int need_flush = 0;
 
-	/* FIXME: properly handle invlpg on large guest pages */
-	if (level == PT_PAGE_TABLE_LEVEL ||
-	    ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) {
-		struct kvm_mmu_page *sp = page_header(__pa(sptep));
+	spin_lock(&vcpu->kvm->mmu_lock);
 
-		sw->pte_gpa = (sp->gfn << PAGE_SHIFT);
-		sw->pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
+	for_each_shadow_entry(vcpu, gva, iterator) {
+		level = iterator.level;
+		sptep = iterator.sptep;
 
-		if (is_shadow_present_pte(*sptep)) {
-			rmap_remove(vcpu->kvm, sptep);
-			if (is_large_pte(*sptep))
-				--vcpu->kvm->stat.lpages;
+		/* FIXME: properly handle invlpg on large guest pages */
+		if (level == PT_PAGE_TABLE_LEVEL ||
+		    ((level == PT_DIRECTORY_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);
+				if (is_large_pte(*sptep))
+					--vcpu->kvm->stat.lpages;
+				need_flush = 1;
+			}
+			set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+			break;
 		}
-		set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
-		return 1;
-	}
-	if (!is_shadow_present_pte(*sptep))
-		return 1;
-	return 0;
-}
 
-static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
-{
-	pt_element_t gpte;
-	struct shadow_walker walker = {
-		.walker = { .entry = FNAME(shadow_invlpg_entry), },
-		.pte_gpa = -1,
-	};
+		if (!is_shadow_present_pte(*sptep))
+			break;
+	}
 
-	spin_lock(&vcpu->kvm->mmu_lock);
-	walk_shadow(&walker.walker, vcpu, gva);
+	if (need_flush)
+		kvm_flush_remote_tlbs(vcpu->kvm);
 	spin_unlock(&vcpu->kvm->mmu_lock);
-	if (walker.pte_gpa == -1)
+
+	if (pte_gpa == -1)
 		return;
-	if (kvm_read_guest_atomic(vcpu->kvm, walker.pte_gpa, &gpte,
+	if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
 				  sizeof(pt_element_t)))
 		return;
 	if (is_present_pte(gpte) && (gpte & PT_ACCESSED_MASK)) {
 		if (mmu_topup_memory_caches(vcpu))
 			return;
-		kvm_mmu_pte_write(vcpu, walker.pte_gpa, (const u8 *)&gpte,
+		kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
 				  sizeof(pt_element_t), 0);
 	}
 }
@@ -540,7 +516,7 @@ static void FNAME(prefetch_page)(struct
 	pt_element_t pt[256 / sizeof(pt_element_t)];
 	gpa_t pte_gpa;
 
-	if (sp->role.metaphysical
+	if (sp->role.direct
 	    || (PTTYPE == 32 && sp->role.level > PT_PAGE_TABLE_LEVEL)) {
 		nonpaging_prefetch_page(vcpu, sp);
 		return;
@@ -619,7 +595,6 @@ static int FNAME(sync_page)(struct kvm_v
 
 #undef pt_element_t
 #undef guest_walker
-#undef shadow_walker
 #undef FNAME
 #undef PT_BASE_ADDR_MASK
 #undef PT_INDEX
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/svm.c linux-libre-2.6.30-gnu1/arch/x86/kvm/svm.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/svm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/svm.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,9 +38,6 @@ MODULE_LICENSE("GPL");
 #define IOPM_ALLOC_ORDER 2
 #define MSRPM_ALLOC_ORDER 1
 
-#define DR7_GD_MASK (1 << 13)
-#define DR6_BD_MASK (1 << 13)
-
 #define SEG_TYPE_LDT 2
 #define SEG_TYPE_BUSY_TSS16 3
 
@@ -50,6 +47,15 @@ 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
+
 /* enable NPT for AMD64 and X86 with PAE */
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 static bool npt_enabled = true;
@@ -60,14 +66,29 @@ static int npt = 1;
 
 module_param(npt, int, S_IRUGO);
 
+static int nested = 0;
+module_param(nested, int, S_IRUGO);
+
 static void kvm_reput_irq(struct vcpu_svm *svm);
 static void svm_flush_tlb(struct kvm_vcpu *vcpu);
 
+static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override);
+static int nested_svm_vmexit(struct vcpu_svm *svm);
+static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
+			     void *arg2, void *opaque);
+static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
+				      bool has_error_code, u32 error_code);
+
 static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
 	return container_of(vcpu, struct vcpu_svm, vcpu);
 }
 
+static inline bool is_nested(struct vcpu_svm *svm)
+{
+	return svm->nested_vmcb;
+}
+
 static unsigned long iopm_base;
 
 struct kvm_ldttss_desc {
@@ -157,32 +178,6 @@ static inline void kvm_write_cr2(unsigne
 	asm volatile ("mov %0, %%cr2" :: "r" (val));
 }
 
-static inline unsigned long read_dr6(void)
-{
-	unsigned long dr6;
-
-	asm volatile ("mov %%dr6, %0" : "=r" (dr6));
-	return dr6;
-}
-
-static inline void write_dr6(unsigned long val)
-{
-	asm volatile ("mov %0, %%dr6" :: "r" (val));
-}
-
-static inline unsigned long read_dr7(void)
-{
-	unsigned long dr7;
-
-	asm volatile ("mov %%dr7, %0" : "=r" (dr7));
-	return dr7;
-}
-
-static inline void write_dr7(unsigned long val)
-{
-	asm volatile ("mov %0, %%dr7" :: "r" (val));
-}
-
 static inline void force_new_asid(struct kvm_vcpu *vcpu)
 {
 	to_svm(vcpu)->asid_generation--;
@@ -198,7 +193,7 @@ static void svm_set_efer(struct kvm_vcpu
 	if (!npt_enabled && !(efer & EFER_LMA))
 		efer &= ~EFER_LME;
 
-	to_svm(vcpu)->vmcb->save.efer = efer | MSR_EFER_SVME_MASK;
+	to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
 	vcpu->arch.shadow_efer = efer;
 }
 
@@ -207,6 +202,11 @@ static void svm_queue_exception(struct k
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	/* If we are within a nested VM we'd better #VMEXIT and let the
+	   guest handle the exception */
+	if (nested_svm_check_exception(svm, nr, has_error_code, error_code))
+		return;
+
 	svm->vmcb->control.event_inj = nr
 		| SVM_EVTINJ_VALID
 		| (has_error_code ? SVM_EVTINJ_VALID_ERR : 0)
@@ -242,7 +242,7 @@ static void skip_emulated_instruction(st
 	kvm_rip_write(vcpu, svm->next_rip);
 	svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
 
-	vcpu->arch.interrupt_window_open = 1;
+	vcpu->arch.interrupt_window_open = (svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
 
 static int has_svm(void)
@@ -250,7 +250,7 @@ static int has_svm(void)
 	const char *msg;
 
 	if (!cpu_has_svm(&msg)) {
-		printk(KERN_INFO "has_svn: %s\n", msg);
+		printk(KERN_INFO "has_svm: %s\n", msg);
 		return 0;
 	}
 
@@ -292,7 +292,7 @@ static void svm_hardware_enable(void *ga
 	svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	rdmsrl(MSR_EFER, efer);
-	wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK);
+	wrmsrl(MSR_EFER, efer | EFER_SVME);
 
 	wrmsrl(MSR_VM_HSAVE_PA,
 	       page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
@@ -411,12 +411,19 @@ static __init int svm_hardware_setup(voi
 
 	iopm_va = page_address(iopm_pages);
 	memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER));
-	clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */
 	iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT;
 
 	if (boot_cpu_has(X86_FEATURE_NX))
 		kvm_enable_efer_bits(EFER_NX);
 
+	if (boot_cpu_has(X86_FEATURE_FXSR_OPT))
+		kvm_enable_efer_bits(EFER_FFXSR);
+
+	if (nested) {
+		printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
+		kvm_enable_efer_bits(EFER_SVME);
+	}
+
 	for_each_online_cpu(cpu) {
 		r = svm_cpu_init(cpu);
 		if (r)
@@ -559,7 +566,7 @@ static void init_vmcb(struct vcpu_svm *s
 	init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
 	init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
 
-	save->efer = MSR_EFER_SVME_MASK;
+	save->efer = EFER_SVME;
 	save->dr6 = 0xffff0ff0;
 	save->dr7 = 0x400;
 	save->rflags = 2;
@@ -591,6 +598,9 @@ static void init_vmcb(struct vcpu_svm *s
 		save->cr4 = 0;
 	}
 	force_new_asid(&svm->vcpu);
+
+	svm->nested_vmcb = 0;
+	svm->vcpu.arch.hflags = HF_GIF_MASK;
 }
 
 static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -615,6 +625,8 @@ static struct kvm_vcpu *svm_create_vcpu(
 	struct vcpu_svm *svm;
 	struct page *page;
 	struct page *msrpm_pages;
+	struct page *hsave_page;
+	struct page *nested_msrpm_pages;
 	int err;
 
 	svm = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
@@ -637,14 +649,25 @@ static struct kvm_vcpu *svm_create_vcpu(
 	msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
 	if (!msrpm_pages)
 		goto uninit;
+
+	nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
+	if (!nested_msrpm_pages)
+		goto uninit;
+
 	svm->msrpm = page_address(msrpm_pages);
 	svm_vcpu_init_msrpm(svm->msrpm);
 
+	hsave_page = alloc_page(GFP_KERNEL);
+	if (!hsave_page)
+		goto uninit;
+	svm->hsave = page_address(hsave_page);
+
+	svm->nested_msrpm = page_address(nested_msrpm_pages);
+
 	svm->vmcb = page_address(page);
 	clear_page(svm->vmcb);
 	svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
 	svm->asid_generation = 0;
-	memset(svm->db_regs, 0, sizeof(svm->db_regs));
 	init_vmcb(svm);
 
 	fx_init(&svm->vcpu);
@@ -669,6 +692,8 @@ static void svm_free_vcpu(struct kvm_vcp
 
 	__free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
 	__free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
+	__free_page(virt_to_page(svm->hsave));
+	__free_pages(virt_to_page(svm->nested_msrpm), MSRPM_ALLOC_ORDER);
 	kvm_vcpu_uninit(vcpu);
 	kmem_cache_free(kvm_vcpu_cache, svm);
 }
@@ -718,6 +743,16 @@ static void svm_set_rflags(struct kvm_vc
 	to_svm(vcpu)->vmcb->save.rflags = rflags;
 }
 
+static void svm_set_vintr(struct vcpu_svm *svm)
+{
+	svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR;
+}
+
+static void svm_clear_vintr(struct vcpu_svm *svm)
+{
+	svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
+}
+
 static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg)
 {
 	struct vmcb_save_area *save = &to_svm(vcpu)->vmcb->save;
@@ -760,22 +795,42 @@ static void svm_get_segment(struct kvm_v
 	var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
 	var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
 
-	/*
-	 * SVM always stores 0 for the 'G' bit in the CS selector in
-	 * the VMCB on a VMEXIT. This hurts cross-vendor migration:
-	 * Intel's VMENTRY has a check on the 'G' bit.
+	/* AMD's VMCB does not have an explicit unusable field, so emulate it
+	 * for cross vendor migration purposes by "not present"
 	 */
-	if (seg == VCPU_SREG_CS)
-		var->g = s->limit > 0xfffff;
+	var->unusable = !var->present || (var->type == 0);
 
-	/*
-	 * Work around a bug where the busy flag in the tr selector
-	 * isn't exposed
-	 */
-	if (seg == VCPU_SREG_TR)
+	switch (seg) {
+	case VCPU_SREG_CS:
+		/*
+		 * SVM always stores 0 for the 'G' bit in the CS selector in
+		 * the VMCB on a VMEXIT. This hurts cross-vendor migration:
+		 * Intel's VMENTRY has a check on the 'G' bit.
+		 */
+		var->g = s->limit > 0xfffff;
+		break;
+	case VCPU_SREG_TR:
+		/*
+		 * Work around a bug where the busy flag in the tr selector
+		 * isn't exposed
+		 */
 		var->type |= 0x2;
-
-	var->unusable = !var->present;
+		break;
+	case VCPU_SREG_DS:
+	case VCPU_SREG_ES:
+	case VCPU_SREG_FS:
+	case VCPU_SREG_GS:
+		/*
+		 * The accessed bit must always be set in the segment
+		 * descriptor cache, although it can be cleared in the
+		 * descriptor, the cached bit always remains at 1. Since
+		 * Intel has a check on this, set it here to support
+		 * cross-vendor migration.
+		 */
+		if (!var->unusable)
+			var->type |= 0x1;
+		break;
+	}
 }
 
 static int svm_get_cpl(struct kvm_vcpu *vcpu)
@@ -905,9 +960,37 @@ static void svm_set_segment(struct kvm_v
 
 }
 
-static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
+static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
 {
-	return -EOPNOTSUPP;
+	int old_debug = vcpu->guest_debug;
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	vcpu->guest_debug = dbg->control;
+
+	svm->vmcb->control.intercept_exceptions &=
+		~((1 << DB_VECTOR) | (1 << BP_VECTOR));
+	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
+		if (vcpu->guest_debug &
+		    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+			svm->vmcb->control.intercept_exceptions |=
+				1 << DB_VECTOR;
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+			svm->vmcb->control.intercept_exceptions |=
+				1 << BP_VECTOR;
+	} else
+		vcpu->guest_debug = 0;
+
+	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;
 }
 
 static int svm_get_irq(struct kvm_vcpu *vcpu)
@@ -949,7 +1032,29 @@ static void new_asid(struct vcpu_svm *sv
 
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
 {
-	unsigned long val = to_svm(vcpu)->db_regs[dr];
+	struct vcpu_svm *svm = to_svm(vcpu);
+	unsigned long val;
+
+	switch (dr) {
+	case 0 ... 3:
+		val = vcpu->arch.db[dr];
+		break;
+	case 6:
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+			val = vcpu->arch.dr6;
+		else
+			val = svm->vmcb->save.dr6;
+		break;
+	case 7:
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+			val = vcpu->arch.dr7;
+		else
+			val = svm->vmcb->save.dr7;
+		break;
+	default:
+		val = 0;
+	}
+
 	KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
 	return val;
 }
@@ -959,33 +1064,40 @@ static void svm_set_dr(struct kvm_vcpu *
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	*exception = 0;
+	KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler);
 
-	if (svm->vmcb->save.dr7 & DR7_GD_MASK) {
-		svm->vmcb->save.dr7 &= ~DR7_GD_MASK;
-		svm->vmcb->save.dr6 |= DR6_BD_MASK;
-		*exception = DB_VECTOR;
-		return;
-	}
+	*exception = 0;
 
 	switch (dr) {
 	case 0 ... 3:
-		svm->db_regs[dr] = value;
+		vcpu->arch.db[dr] = value;
+		if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+			vcpu->arch.eff_db[dr] = value;
 		return;
 	case 4 ... 5:
-		if (vcpu->arch.cr4 & X86_CR4_DE) {
+		if (vcpu->arch.cr4 & X86_CR4_DE)
 			*exception = UD_VECTOR;
+		return;
+	case 6:
+		if (value & 0xffffffff00000000ULL) {
+			*exception = GP_VECTOR;
 			return;
 		}
-	case 7: {
-		if (value & ~((1ULL << 32) - 1)) {
+		vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1;
+		return;
+	case 7:
+		if (value & 0xffffffff00000000ULL) {
 			*exception = GP_VECTOR;
 			return;
 		}
-		svm->vmcb->save.dr7 = value;
+		vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1;
+		if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
+			svm->vmcb->save.dr7 = vcpu->arch.dr7;
+			vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK);
+		}
 		return;
-	}
 	default:
+		/* FIXME: Possible case? */
 		printk(KERN_DEBUG "%s: unexpected dr %u\n",
 		       __func__, dr);
 		*exception = UD_VECTOR;
@@ -1031,6 +1143,27 @@ 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)
+{
+	if (!(svm->vcpu.guest_debug &
+	      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
+		kvm_queue_exception(&svm->vcpu, DB_VECTOR);
+		return 1;
+	}
+	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 = DB_VECTOR;
+	return 0;
+}
+
+static int bp_interception(struct vcpu_svm *svm, struct kvm_run *kvm_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)
 {
 	int er;
@@ -1080,7 +1213,7 @@ static int shutdown_interception(struct
 static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
 	u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */
-	int size, down, in, string, rep;
+	int size, in, string;
 	unsigned port;
 
 	++svm->vcpu.stat.io_exits;
@@ -1099,8 +1232,6 @@ static int io_interception(struct vcpu_s
 	in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
 	port = io_info >> 16;
 	size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
-	rep = (io_info & SVM_IOIO_REP_MASK) != 0;
-	down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
 
 	skip_emulated_instruction(&svm->vcpu);
 	return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
@@ -1139,6 +1270,567 @@ static int vmmcall_interception(struct v
 	return 1;
 }
 
+static int nested_svm_check_permissions(struct vcpu_svm *svm)
+{
+	if (!(svm->vcpu.arch.shadow_efer & EFER_SVME)
+	    || !is_paging(&svm->vcpu)) {
+		kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+		return 1;
+	}
+
+	if (svm->vmcb->save.cpl) {
+		kvm_inject_gp(&svm->vcpu, 0);
+		return 1;
+	}
+
+       return 0;
+}
+
+static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
+				      bool has_error_code, u32 error_code)
+{
+	if (is_nested(svm)) {
+		svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
+		svm->vmcb->control.exit_code_hi = 0;
+		svm->vmcb->control.exit_info_1 = error_code;
+		svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
+		if (nested_svm_exit_handled(svm, false)) {
+			nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
+
+			nested_svm_vmexit(svm);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static inline int nested_svm_intr(struct vcpu_svm *svm)
+{
+	if (is_nested(svm)) {
+		if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
+			return 0;
+
+		if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
+			return 0;
+
+		svm->vmcb->control.exit_code = SVM_EXIT_INTR;
+
+		if (nested_svm_exit_handled(svm, false)) {
+			nsvm_printk("VMexit -> INTR\n");
+			nested_svm_vmexit(svm);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
+{
+	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)) {
+		printk(KERN_INFO "%s: could not find page at 0x%llx\n",
+		       __func__, gpa);
+		kvm_release_page_clean(page);
+		kvm_inject_gp(&svm->vcpu, 0);
+		return NULL;
+	}
+	return page;
+}
+
+static int nested_svm_do(struct vcpu_svm *svm,
+			 u64 arg1_gpa, u64 arg2_gpa, void *opaque,
+			 int (*handler)(struct vcpu_svm *svm,
+					void *arg1,
+					void *arg2,
+					void *opaque))
+{
+	struct page *arg1_page;
+	struct page *arg2_page = NULL;
+	void *arg1;
+	void *arg2 = NULL;
+	int retval;
+
+	arg1_page = nested_svm_get_page(svm, arg1_gpa);
+	if(arg1_page == NULL)
+		return 1;
+
+	if (arg2_gpa) {
+		arg2_page = nested_svm_get_page(svm, arg2_gpa);
+		if(arg2_page == NULL) {
+			kvm_release_page_clean(arg1_page);
+			return 1;
+		}
+	}
+
+	arg1 = kmap_atomic(arg1_page, KM_USER0);
+	if (arg2_gpa)
+		arg2 = kmap_atomic(arg2_page, KM_USER1);
+
+	retval = handler(svm, arg1, arg2, opaque);
+
+	kunmap_atomic(arg1, KM_USER0);
+	if (arg2_gpa)
+		kunmap_atomic(arg2, KM_USER1);
+
+	kvm_release_page_dirty(arg1_page);
+	if (arg2_gpa)
+		kvm_release_page_dirty(arg2_page);
+
+	return retval;
+}
+
+static int nested_svm_exit_handled_real(struct vcpu_svm *svm,
+					void *arg1,
+					void *arg2,
+					void *opaque)
+{
+	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+	bool kvm_overrides = *(bool *)opaque;
+	u32 exit_code = svm->vmcb->control.exit_code;
+
+	if (kvm_overrides) {
+		switch (exit_code) {
+		case SVM_EXIT_INTR:
+		case SVM_EXIT_NMI:
+			return 0;
+		/* For now we are always handling NPFs when using them */
+		case SVM_EXIT_NPF:
+			if (npt_enabled)
+				return 0;
+			break;
+		/* When we're shadowing, trap PFs */
+		case SVM_EXIT_EXCP_BASE + PF_VECTOR:
+			if (!npt_enabled)
+				return 0;
+			break;
+		default:
+			break;
+		}
+	}
+
+	switch (exit_code) {
+	case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
+		u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
+		if (nested_vmcb->control.intercept_cr_read & cr_bits)
+			return 1;
+		break;
+	}
+	case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
+		u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
+		if (nested_vmcb->control.intercept_cr_write & cr_bits)
+			return 1;
+		break;
+	}
+	case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
+		u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
+		if (nested_vmcb->control.intercept_dr_read & dr_bits)
+			return 1;
+		break;
+	}
+	case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
+		u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
+		if (nested_vmcb->control.intercept_dr_write & dr_bits)
+			return 1;
+		break;
+	}
+	case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: {
+		u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
+		if (nested_vmcb->control.intercept_exceptions & excp_bits)
+			return 1;
+		break;
+	}
+	default: {
+		u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
+		nsvm_printk("exit code: 0x%x\n", exit_code);
+		if (nested_vmcb->control.intercept & exit_bits)
+			return 1;
+	}
+	}
+
+	return 0;
+}
+
+static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
+				       void *arg1, void *arg2,
+				       void *opaque)
+{
+	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+	u8 *msrpm = (u8 *)arg2;
+        u32 t0, t1;
+	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
+	u32 param = svm->vmcb->control.exit_info_1 & 1;
+
+	if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
+		return 0;
+
+	switch(msr) {
+	case 0 ... 0x1fff:
+		t0 = (msr * 2) % 8;
+		t1 = msr / 8;
+		break;
+	case 0xc0000000 ... 0xc0001fff:
+		t0 = (8192 + msr - 0xc0000000) * 2;
+		t1 = (t0 / 8);
+		t0 %= 8;
+		break;
+	case 0xc0010000 ... 0xc0011fff:
+		t0 = (16384 + msr - 0xc0010000) * 2;
+		t1 = (t0 / 8);
+		t0 %= 8;
+		break;
+	default:
+		return 1;
+		break;
+	}
+	if (msrpm[t1] & ((1 << param) << t0))
+		return 1;
+
+	return 0;
+}
+
+static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
+{
+	bool k = kvm_override;
+
+	switch (svm->vmcb->control.exit_code) {
+	case SVM_EXIT_MSR:
+		return nested_svm_do(svm, svm->nested_vmcb,
+				     svm->nested_vmcb_msrpm, NULL,
+				     nested_svm_exit_handled_msr);
+	default: break;
+	}
+
+	return nested_svm_do(svm, svm->nested_vmcb, 0, &k,
+			     nested_svm_exit_handled_real);
+}
+
+static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
+				  void *arg2, void *opaque)
+{
+	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+	struct vmcb *hsave = svm->hsave;
+	u64 nested_save[] = { nested_vmcb->save.cr0,
+			      nested_vmcb->save.cr3,
+			      nested_vmcb->save.cr4,
+			      nested_vmcb->save.efer,
+			      nested_vmcb->control.intercept_cr_read,
+			      nested_vmcb->control.intercept_cr_write,
+			      nested_vmcb->control.intercept_dr_read,
+			      nested_vmcb->control.intercept_dr_write,
+			      nested_vmcb->control.intercept_exceptions,
+			      nested_vmcb->control.intercept,
+			      nested_vmcb->control.msrpm_base_pa,
+			      nested_vmcb->control.iopm_base_pa,
+			      nested_vmcb->control.tsc_offset };
+
+	/* Give the current vmcb to the guest */
+	memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb));
+	nested_vmcb->save.cr0 = nested_save[0];
+	if (!npt_enabled)
+		nested_vmcb->save.cr3 = nested_save[1];
+	nested_vmcb->save.cr4 = nested_save[2];
+	nested_vmcb->save.efer = nested_save[3];
+	nested_vmcb->control.intercept_cr_read = nested_save[4];
+	nested_vmcb->control.intercept_cr_write = nested_save[5];
+	nested_vmcb->control.intercept_dr_read = nested_save[6];
+	nested_vmcb->control.intercept_dr_write = nested_save[7];
+	nested_vmcb->control.intercept_exceptions = nested_save[8];
+	nested_vmcb->control.intercept = nested_save[9];
+	nested_vmcb->control.msrpm_base_pa = nested_save[10];
+	nested_vmcb->control.iopm_base_pa = nested_save[11];
+	nested_vmcb->control.tsc_offset = nested_save[12];
+
+	/* We always set V_INTR_MASKING and remember the old value in hflags */
+	if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
+		nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
+
+	if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) &&
+	    (nested_vmcb->control.int_vector)) {
+		nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n",
+				nested_vmcb->control.int_vector);
+	}
+
+	/* Restore the original control entries */
+	svm->vmcb->control = hsave->control;
+
+	/* Kill any pending exceptions */
+	if (svm->vcpu.arch.exception.pending == true)
+		nsvm_printk("WARNING: Pending Exception\n");
+	svm->vcpu.arch.exception.pending = false;
+
+	/* Restore selected save entries */
+	svm->vmcb->save.es = hsave->save.es;
+	svm->vmcb->save.cs = hsave->save.cs;
+	svm->vmcb->save.ss = hsave->save.ss;
+	svm->vmcb->save.ds = hsave->save.ds;
+	svm->vmcb->save.gdtr = hsave->save.gdtr;
+	svm->vmcb->save.idtr = hsave->save.idtr;
+	svm->vmcb->save.rflags = hsave->save.rflags;
+	svm_set_efer(&svm->vcpu, hsave->save.efer);
+	svm_set_cr0(&svm->vcpu, hsave->save.cr0 | X86_CR0_PE);
+	svm_set_cr4(&svm->vcpu, hsave->save.cr4);
+	if (npt_enabled) {
+		svm->vmcb->save.cr3 = hsave->save.cr3;
+		svm->vcpu.arch.cr3 = hsave->save.cr3;
+	} else {
+		kvm_set_cr3(&svm->vcpu, hsave->save.cr3);
+	}
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, hsave->save.rax);
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, hsave->save.rsp);
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, hsave->save.rip);
+	svm->vmcb->save.dr7 = 0;
+	svm->vmcb->save.cpl = 0;
+	svm->vmcb->control.exit_int_info = 0;
+
+	svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+	/* Exit nested SVM mode */
+	svm->nested_vmcb = 0;
+
+	return 0;
+}
+
+static int nested_svm_vmexit(struct vcpu_svm *svm)
+{
+	nsvm_printk("VMexit\n");
+	if (nested_svm_do(svm, svm->nested_vmcb, 0,
+			  NULL, nested_svm_vmexit_real))
+		return 1;
+
+	kvm_mmu_reset_context(&svm->vcpu);
+	kvm_mmu_load(&svm->vcpu);
+
+	return 0;
+}
+
+static int nested_svm_vmrun_msrpm(struct vcpu_svm *svm, void *arg1,
+				  void *arg2, void *opaque)
+{
+	int i;
+	u32 *nested_msrpm = (u32*)arg1;
+	for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
+		svm->nested_msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
+	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested_msrpm);
+
+	return 0;
+}
+
+static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
+			    void *arg2, void *opaque)
+{
+	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+	struct vmcb *hsave = svm->hsave;
+
+	/* nested_vmcb is our indicator if nested SVM is activated */
+	svm->nested_vmcb = svm->vmcb->save.rax;
+
+	/* Clear internal status */
+	svm->vcpu.arch.exception.pending = false;
+
+	/* Save the old vmcb, so we don't need to pick what we save, but
+	   can restore everything when a VMEXIT occurs */
+	memcpy(hsave, svm->vmcb, sizeof(struct vmcb));
+	/* We need to remember the original CR3 in the SPT case */
+	if (!npt_enabled)
+		hsave->save.cr3 = svm->vcpu.arch.cr3;
+	hsave->save.cr4 = svm->vcpu.arch.cr4;
+	hsave->save.rip = svm->next_rip;
+
+	if (svm->vmcb->save.rflags & X86_EFLAGS_IF)
+		svm->vcpu.arch.hflags |= HF_HIF_MASK;
+	else
+		svm->vcpu.arch.hflags &= ~HF_HIF_MASK;
+
+	/* Load the nested guest state */
+	svm->vmcb->save.es = nested_vmcb->save.es;
+	svm->vmcb->save.cs = nested_vmcb->save.cs;
+	svm->vmcb->save.ss = nested_vmcb->save.ss;
+	svm->vmcb->save.ds = nested_vmcb->save.ds;
+	svm->vmcb->save.gdtr = nested_vmcb->save.gdtr;
+	svm->vmcb->save.idtr = nested_vmcb->save.idtr;
+	svm->vmcb->save.rflags = nested_vmcb->save.rflags;
+	svm_set_efer(&svm->vcpu, nested_vmcb->save.efer);
+	svm_set_cr0(&svm->vcpu, nested_vmcb->save.cr0);
+	svm_set_cr4(&svm->vcpu, nested_vmcb->save.cr4);
+	if (npt_enabled) {
+		svm->vmcb->save.cr3 = nested_vmcb->save.cr3;
+		svm->vcpu.arch.cr3 = nested_vmcb->save.cr3;
+	} else {
+		kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
+		kvm_mmu_reset_context(&svm->vcpu);
+	}
+	svm->vmcb->save.cr2 = nested_vmcb->save.cr2;
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
+	kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip);
+	/* In case we don't even reach vcpu_run, the fields are not updated */
+	svm->vmcb->save.rax = nested_vmcb->save.rax;
+	svm->vmcb->save.rsp = nested_vmcb->save.rsp;
+	svm->vmcb->save.rip = nested_vmcb->save.rip;
+	svm->vmcb->save.dr7 = nested_vmcb->save.dr7;
+	svm->vmcb->save.dr6 = nested_vmcb->save.dr6;
+	svm->vmcb->save.cpl = nested_vmcb->save.cpl;
+
+	/* We don't want a nested guest to be more powerful than the guest,
+	   so all intercepts are ORed */
+	svm->vmcb->control.intercept_cr_read |=
+		nested_vmcb->control.intercept_cr_read;
+	svm->vmcb->control.intercept_cr_write |=
+		nested_vmcb->control.intercept_cr_write;
+	svm->vmcb->control.intercept_dr_read |=
+		nested_vmcb->control.intercept_dr_read;
+	svm->vmcb->control.intercept_dr_write |=
+		nested_vmcb->control.intercept_dr_write;
+	svm->vmcb->control.intercept_exceptions |=
+		nested_vmcb->control.intercept_exceptions;
+
+	svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
+
+	svm->nested_vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
+
+	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;
+
+	svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+	return 0;
+}
+
+static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
+{
+	to_vmcb->save.fs = from_vmcb->save.fs;
+	to_vmcb->save.gs = from_vmcb->save.gs;
+	to_vmcb->save.tr = from_vmcb->save.tr;
+	to_vmcb->save.ldtr = from_vmcb->save.ldtr;
+	to_vmcb->save.kernel_gs_base = from_vmcb->save.kernel_gs_base;
+	to_vmcb->save.star = from_vmcb->save.star;
+	to_vmcb->save.lstar = from_vmcb->save.lstar;
+	to_vmcb->save.cstar = from_vmcb->save.cstar;
+	to_vmcb->save.sfmask = from_vmcb->save.sfmask;
+	to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs;
+	to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp;
+	to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip;
+
+	return 1;
+}
+
+static int nested_svm_vmload(struct vcpu_svm *svm, void *nested_vmcb,
+			     void *arg2, void *opaque)
+{
+	return nested_svm_vmloadsave((struct vmcb *)nested_vmcb, svm->vmcb);
+}
+
+static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
+			     void *arg2, void *opaque)
+{
+	return nested_svm_vmloadsave(svm->vmcb, (struct vmcb *)nested_vmcb);
+}
+
+static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	if (nested_svm_check_permissions(svm))
+		return 1;
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
+	nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmload);
+
+	return 1;
+}
+
+static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	if (nested_svm_check_permissions(svm))
+		return 1;
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
+	nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmsave);
+
+	return 1;
+}
+
+static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	nsvm_printk("VMrun\n");
+	if (nested_svm_check_permissions(svm))
+		return 1;
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
+	if (nested_svm_do(svm, svm->vmcb->save.rax, 0,
+			  NULL, nested_svm_vmrun))
+		return 1;
+
+	if (nested_svm_do(svm, svm->nested_vmcb_msrpm, 0,
+		      NULL, nested_svm_vmrun_msrpm))
+		return 1;
+
+	return 1;
+}
+
+static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	if (nested_svm_check_permissions(svm))
+		return 1;
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
+	svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+	return 1;
+}
+
+static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	if (nested_svm_check_permissions(svm))
+		return 1;
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
+	svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+
+	/* After a CLGI no interrupts should come */
+	svm_clear_vintr(svm);
+	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+
+	return 1;
+}
+
 static int invalid_op_interception(struct vcpu_svm *svm,
 				   struct kvm_run *kvm_run)
 {
@@ -1250,6 +1942,15 @@ static int svm_get_msr(struct kvm_vcpu *
 	case MSR_IA32_LASTINTTOIP:
 		*data = svm->vmcb->save.last_excp_to;
 		break;
+	case MSR_VM_HSAVE_PA:
+		*data = svm->hsave_msr;
+		break;
+	case MSR_VM_CR:
+		*data = 0;
+		break;
+	case MSR_IA32_UCODE_REV:
+		*data = 0x01000065;
+		break;
 	default:
 		return kvm_get_msr_common(vcpu, ecx, data);
 	}
@@ -1344,6 +2045,9 @@ static int svm_set_msr(struct kvm_vcpu *
 		pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data);
 
 		break;
+	case MSR_VM_HSAVE_PA:
+		svm->hsave_msr = data;
+		break;
 	default:
 		return kvm_set_msr_common(vcpu, ecx, data);
 	}
@@ -1380,7 +2084,7 @@ static int interrupt_window_interception
 {
 	KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler);
 
-	svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
+	svm_clear_vintr(svm);
 	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
 	/*
 	 * If the user space waits to inject interrupts, exit as soon as
@@ -1417,6 +2121,8 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_WRITE_DR3]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR5]			= emulate_on_interception,
 	[SVM_EXIT_WRITE_DR7]			= emulate_on_interception,
+	[SVM_EXIT_EXCP_BASE + DB_VECTOR]	= db_interception,
+	[SVM_EXIT_EXCP_BASE + BP_VECTOR]	= bp_interception,
 	[SVM_EXIT_EXCP_BASE + UD_VECTOR]	= ud_interception,
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
 	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
@@ -1436,12 +2142,12 @@ static int (*svm_exit_handlers[])(struct
 	[SVM_EXIT_MSR]				= msr_interception,
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
 	[SVM_EXIT_SHUTDOWN]			= shutdown_interception,
-	[SVM_EXIT_VMRUN]			= invalid_op_interception,
+	[SVM_EXIT_VMRUN]			= vmrun_interception,
 	[SVM_EXIT_VMMCALL]			= vmmcall_interception,
-	[SVM_EXIT_VMLOAD]			= invalid_op_interception,
-	[SVM_EXIT_VMSAVE]			= invalid_op_interception,
-	[SVM_EXIT_STGI]				= invalid_op_interception,
-	[SVM_EXIT_CLGI]				= invalid_op_interception,
+	[SVM_EXIT_VMLOAD]			= vmload_interception,
+	[SVM_EXIT_VMSAVE]			= vmsave_interception,
+	[SVM_EXIT_STGI]				= stgi_interception,
+	[SVM_EXIT_CLGI]				= clgi_interception,
 	[SVM_EXIT_SKINIT]			= invalid_op_interception,
 	[SVM_EXIT_WBINVD]                       = emulate_on_interception,
 	[SVM_EXIT_MONITOR]			= invalid_op_interception,
@@ -1457,6 +2163,17 @@ static int handle_exit(struct kvm_run *k
 	KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip,
 		    (u32)((u64)svm->vmcb->save.rip >> 32), entryexit);
 
+	if (is_nested(svm)) {
+		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);
+		if (nested_svm_exit_handled(svm, true)) {
+			nested_svm_vmexit(svm);
+			nsvm_printk("-> #VMEXIT\n");
+			return 1;
+		}
+	}
+
 	if (npt_enabled) {
 		int mmu_reload = 0;
 		if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
@@ -1544,6 +2261,8 @@ static void svm_set_irq(struct kvm_vcpu
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	nested_svm_intr(svm);
+
 	svm_inject_irq(svm, irq);
 }
 
@@ -1589,11 +2308,17 @@ static void svm_intr_assist(struct kvm_v
 	if (!kvm_cpu_has_interrupt(vcpu))
 		goto out;
 
+	if (nested_svm_intr(svm))
+		goto out;
+
+	if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
+		goto out;
+
 	if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
 	    (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
 	    (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
 		/* unable to deliver irq, set pending irq */
-		vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
+		svm_set_vintr(svm);
 		svm_inject_irq(svm, 0x0);
 		goto out;
 	}
@@ -1615,7 +2340,8 @@ static void kvm_reput_irq(struct vcpu_sv
 	}
 
 	svm->vcpu.arch.interrupt_window_open =
-		!(control->int_state & SVM_INTERRUPT_SHADOW_MASK);
+		!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+		 (svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
 
 static void svm_do_inject_vector(struct vcpu_svm *svm)
@@ -1637,9 +2363,13 @@ static void do_interrupt_requests(struct
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct vmcb_control_area *control = &svm->vmcb->control;
 
+	if (nested_svm_intr(svm))
+		return;
+
 	svm->vcpu.arch.interrupt_window_open =
 		(!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-		 (svm->vmcb->save.rflags & X86_EFLAGS_IF));
+		 (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
+		 (svm->vcpu.arch.hflags & HF_GIF_MASK));
 
 	if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
 		/*
@@ -1652,9 +2382,9 @@ static void do_interrupt_requests(struct
 	 */
 	if (!svm->vcpu.arch.interrupt_window_open &&
 	    (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window))
-		control->intercept |= 1ULL << INTERCEPT_VINTR;
-	 else
-		control->intercept &= ~(1ULL << INTERCEPT_VINTR);
+		svm_set_vintr(svm);
+	else
+		svm_clear_vintr(svm);
 }
 
 static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -1662,22 +2392,6 @@ static int svm_set_tss_addr(struct kvm *
 	return 0;
 }
 
-static void save_db_regs(unsigned long *db_regs)
-{
-	asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
-	asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
-	asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
-	asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
-}
-
-static void load_db_regs(unsigned long *db_regs)
-{
-	asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
-	asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
-	asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
-	asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
-}
-
 static void svm_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	force_new_asid(vcpu);
@@ -1736,19 +2450,12 @@ static void svm_vcpu_run(struct kvm_vcpu
 	gs_selector = kvm_read_gs();
 	ldt_selector = kvm_read_ldt();
 	svm->host_cr2 = kvm_read_cr2();
-	svm->host_dr6 = read_dr6();
-	svm->host_dr7 = read_dr7();
-	svm->vmcb->save.cr2 = vcpu->arch.cr2;
+	if (!is_nested(svm))
+		svm->vmcb->save.cr2 = vcpu->arch.cr2;
 	/* required for live migration with NPT */
 	if (npt_enabled)
 		svm->vmcb->save.cr3 = vcpu->arch.cr3;
 
-	if (svm->vmcb->save.dr7 & 0xff) {
-		write_dr7(0);
-		save_db_regs(svm->host_db_regs);
-		load_db_regs(svm->db_regs);
-	}
-
 	clgi();
 
 	local_irq_enable();
@@ -1824,16 +2531,11 @@ static void svm_vcpu_run(struct kvm_vcpu
 #endif
 		);
 
-	if ((svm->vmcb->save.dr7 & 0xff))
-		load_db_regs(svm->host_db_regs);
-
 	vcpu->arch.cr2 = svm->vmcb->save.cr2;
 	vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
 	vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
 	vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
-	write_dr6(svm->host_dr6);
-	write_dr7(svm->host_dr7);
 	kvm_write_cr2(svm->host_cr2);
 
 	kvm_load_fs(fs_selector);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/vmx.c linux-libre-2.6.30-gnu1/arch/x86/kvm/vmx.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/vmx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/vmx.c	2009-06-09 23:05:27.000000000 -0400
@@ -91,6 +91,7 @@ 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;
@@ -189,21 +190,21 @@ static inline int is_page_fault(u32 intr
 {
 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
 			     INTR_INFO_VALID_MASK)) ==
-		(INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
+		(INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
 }
 
 static inline int is_no_device(u32 intr_info)
 {
 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
 			     INTR_INFO_VALID_MASK)) ==
-		(INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
+		(INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
 }
 
 static inline int is_invalid_opcode(u32 intr_info)
 {
 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
 			     INTR_INFO_VALID_MASK)) ==
-		(INTR_TYPE_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
+		(INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
 }
 
 static inline int is_external_interrupt(u32 intr_info)
@@ -480,8 +481,13 @@ static void update_exception_bitmap(stru
 	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR);
 	if (!vcpu->fpu_active)
 		eb |= 1u << NM_VECTOR;
-	if (vcpu->guest_debug.enabled)
-		eb |= 1u << DB_VECTOR;
+	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
+		if (vcpu->guest_debug &
+		    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+			eb |= 1u << DB_VECTOR;
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+			eb |= 1u << BP_VECTOR;
+	}
 	if (vcpu->arch.rmode.active)
 		eb = ~0;
 	if (vm_need_ept())
@@ -747,29 +753,33 @@ static void vmx_queue_exception(struct k
 				bool has_error_code, u32 error_code)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	u32 intr_info = nr | INTR_INFO_VALID_MASK;
 
-	if (has_error_code)
+	if (has_error_code) {
 		vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+		intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+	}
 
 	if (vcpu->arch.rmode.active) {
 		vmx->rmode.irq.pending = true;
 		vmx->rmode.irq.vector = nr;
 		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-		if (nr == BP_VECTOR)
+		if (nr == BP_VECTOR || nr == OF_VECTOR)
 			vmx->rmode.irq.rip++;
-		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-			     nr | INTR_TYPE_SOFT_INTR
-			     | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
-			     | INTR_INFO_VALID_MASK);
+		intr_info |= INTR_TYPE_SOFT_INTR;
+		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
 		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
 		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
 		return;
 	}
 
-	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-		     nr | INTR_TYPE_EXCEPTION
-		     | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
-		     | INTR_INFO_VALID_MASK);
+	if (nr == BP_VECTOR || nr == OF_VECTOR) {
+		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
+		intr_info |= INTR_TYPE_SOFT_EXCEPTION;
+	} else
+		intr_info |= INTR_TYPE_HARD_EXCEPTION;
+
+	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
 }
 
 static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
@@ -856,11 +866,8 @@ static u64 guest_read_tsc(void)
  * writes 'guest_tsc' into guest's timestamp counter "register"
  * guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc
  */
-static void guest_write_tsc(u64 guest_tsc)
+static void guest_write_tsc(u64 guest_tsc, u64 host_tsc)
 {
-	u64 host_tsc;
-
-	rdtscll(host_tsc);
 	vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
 }
 
@@ -925,14 +932,15 @@ static int vmx_set_msr(struct kvm_vcpu *
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	struct kvm_msr_entry *msr;
+	u64 host_tsc;
 	int ret = 0;
 
 	switch (msr_index) {
-#ifdef CONFIG_X86_64
 	case MSR_EFER:
 		vmx_load_host_state(vmx);
 		ret = kvm_set_msr_common(vcpu, msr_index, data);
 		break;
+#ifdef CONFIG_X86_64
 	case MSR_FS_BASE:
 		vmcs_writel(GUEST_FS_BASE, data);
 		break;
@@ -950,7 +958,8 @@ static int vmx_set_msr(struct kvm_vcpu *
 		vmcs_writel(GUEST_SYSENTER_ESP, data);
 		break;
 	case MSR_IA32_TIME_STAMP_COUNTER:
-		guest_write_tsc(data);
+		rdtscll(host_tsc);
+		guest_write_tsc(data, host_tsc);
 		break;
 	case MSR_P6_PERFCTR0:
 	case MSR_P6_PERFCTR1:
@@ -999,40 +1008,28 @@ static void vmx_cache_reg(struct kvm_vcp
 	}
 }
 
-static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
+static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
 {
-	unsigned long dr7 = 0x400;
-	int old_singlestep;
-
-	old_singlestep = vcpu->guest_debug.singlestep;
-
-	vcpu->guest_debug.enabled = dbg->enabled;
-	if (vcpu->guest_debug.enabled) {
-		int i;
-
-		dr7 |= 0x200;  /* exact */
-		for (i = 0; i < 4; ++i) {
-			if (!dbg->breakpoints[i].enabled)
-				continue;
-			vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
-			dr7 |= 2 << (i*2);    /* global enable */
-			dr7 |= 0 << (i*4+16); /* execution breakpoint */
-		}
+	int old_debug = vcpu->guest_debug;
+	unsigned long flags;
 
-		vcpu->guest_debug.singlestep = dbg->singlestep;
-	} else
-		vcpu->guest_debug.singlestep = 0;
+	vcpu->guest_debug = dbg->control;
+	if (!(vcpu->guest_debug & KVM_GUESTDBG_ENABLE))
+		vcpu->guest_debug = 0;
 
-	if (old_singlestep && !vcpu->guest_debug.singlestep) {
-		unsigned long flags;
+	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);
+	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);
-	}
+	vmcs_writel(GUEST_RFLAGS, flags);
 
 	update_exception_bitmap(vcpu);
-	vmcs_writel(GUEST_DR7, dr7);
 
 	return 0;
 }
@@ -1433,6 +1430,29 @@ continue_rmode:
 	init_rmode(vcpu->kvm);
 }
 
+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);
+
+	vcpu->arch.shadow_efer = efer;
+	if (!msr)
+		return;
+	if (efer & EFER_LMA) {
+		vmcs_write32(VM_ENTRY_CONTROLS,
+			     vmcs_read32(VM_ENTRY_CONTROLS) |
+			     VM_ENTRY_IA32E_MODE);
+		msr->data = efer;
+	} else {
+		vmcs_write32(VM_ENTRY_CONTROLS,
+			     vmcs_read32(VM_ENTRY_CONTROLS) &
+			     ~VM_ENTRY_IA32E_MODE);
+
+		msr->data = efer & ~EFER_LME;
+	}
+	setup_msrs(vmx);
+}
+
 #ifdef CONFIG_X86_64
 
 static void enter_lmode(struct kvm_vcpu *vcpu)
@@ -1447,13 +1467,8 @@ static void enter_lmode(struct kvm_vcpu
 			     (guest_tr_ar & ~AR_TYPE_MASK)
 			     | AR_TYPE_BUSY_64_TSS);
 	}
-
 	vcpu->arch.shadow_efer |= EFER_LMA;
-
-	find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME;
-	vmcs_write32(VM_ENTRY_CONTROLS,
-		     vmcs_read32(VM_ENTRY_CONTROLS)
-		     | VM_ENTRY_IA32E_MODE);
+	vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
 }
 
 static void exit_lmode(struct kvm_vcpu *vcpu)
@@ -1612,30 +1627,6 @@ static void vmx_set_cr4(struct kvm_vcpu
 	vmcs_writel(GUEST_CR4, hw_cr4);
 }
 
-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);
-
-	vcpu->arch.shadow_efer = efer;
-	if (!msr)
-		return;
-	if (efer & EFER_LMA) {
-		vmcs_write32(VM_ENTRY_CONTROLS,
-				     vmcs_read32(VM_ENTRY_CONTROLS) |
-				     VM_ENTRY_IA32E_MODE);
-		msr->data = efer;
-
-	} else {
-		vmcs_write32(VM_ENTRY_CONTROLS,
-				     vmcs_read32(VM_ENTRY_CONTROLS) &
-				     ~VM_ENTRY_IA32E_MODE);
-
-		msr->data = efer & ~EFER_LME;
-	}
-	setup_msrs(vmx);
-}
-
 static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
 {
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -1653,7 +1644,7 @@ static void vmx_get_segment(struct kvm_v
 	var->limit = vmcs_read32(sf->limit);
 	var->selector = vmcs_read16(sf->selector);
 	ar = vmcs_read32(sf->ar_bytes);
-	if (ar & AR_UNUSABLE_MASK)
+	if ((ar & AR_UNUSABLE_MASK) && !emulate_invalid_guest_state)
 		ar = 0;
 	var->type = ar & 15;
 	var->s = (ar >> 4) & 1;
@@ -1788,14 +1779,16 @@ static bool code_segment_valid(struct kv
 	vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
 	cs_rpl = cs.selector & SELECTOR_RPL_MASK;
 
+	if (cs.unusable)
+		return false;
 	if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK))
 		return false;
 	if (!cs.s)
 		return false;
-	if (!(~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK))) {
+	if (cs.type & AR_TYPE_WRITEABLE_MASK) {
 		if (cs.dpl > cs_rpl)
 			return false;
-	} else if (cs.type & AR_TYPE_CODE_MASK) {
+	} else {
 		if (cs.dpl != cs_rpl)
 			return false;
 	}
@@ -1814,7 +1807,9 @@ static bool stack_segment_valid(struct k
 	vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
 	ss_rpl = ss.selector & SELECTOR_RPL_MASK;
 
-	if ((ss.type != 3) || (ss.type != 7))
+	if (ss.unusable)
+		return true;
+	if (ss.type != 3 && ss.type != 7)
 		return false;
 	if (!ss.s)
 		return false;
@@ -1834,6 +1829,8 @@ static bool data_segment_valid(struct kv
 	vmx_get_segment(vcpu, &var, seg);
 	rpl = var.selector & SELECTOR_RPL_MASK;
 
+	if (var.unusable)
+		return true;
 	if (!var.s)
 		return false;
 	if (!var.present)
@@ -1855,9 +1852,11 @@ static bool tr_valid(struct kvm_vcpu *vc
 
 	vmx_get_segment(vcpu, &tr, VCPU_SREG_TR);
 
+	if (tr.unusable)
+		return false;
 	if (tr.selector & SELECTOR_TI_MASK)	/* TI = 1 */
 		return false;
-	if ((tr.type != 3) || (tr.type != 11)) /* TODO: Check if guest is in IA32e mode */
+	if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */
 		return false;
 	if (!tr.present)
 		return false;
@@ -1871,6 +1870,8 @@ static bool ldtr_valid(struct kvm_vcpu *
 
 	vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR);
 
+	if (ldtr.unusable)
+		return true;
 	if (ldtr.selector & SELECTOR_TI_MASK)	/* TI = 1 */
 		return false;
 	if (ldtr.type != 2)
@@ -2112,7 +2113,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
 {
 	u32 host_sysenter_cs, msr_low, msr_high;
 	u32 junk;
-	u64 host_pat;
+	u64 host_pat, tsc_this, tsc_base;
 	unsigned long a;
 	struct descriptor_table dt;
 	int i;
@@ -2240,6 +2241,12 @@ static int vmx_vcpu_setup(struct vcpu_vm
 	vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
 	vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
 
+	tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
+	rdtscll(tsc_this);
+	if (tsc_this < vmx->vcpu.kvm->arch.vm_init_tsc)
+		tsc_base = tsc_this;
+
+	guest_write_tsc(0, tsc_base);
 
 	return 0;
 }
@@ -2319,7 +2326,6 @@ static int vmx_vcpu_reset(struct kvm_vcp
 		kvm_rip_write(vcpu, 0);
 	kvm_register_write(vcpu, VCPU_REGS_RSP, 0);
 
-	/* todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 */
 	vmcs_writel(GUEST_DR7, 0x400);
 
 	vmcs_writel(GUEST_GDTR_BASE, 0);
@@ -2332,8 +2338,6 @@ static int vmx_vcpu_reset(struct kvm_vcp
 	vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
 	vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
 
-	guest_write_tsc(0);
-
 	/* Special registers */
 	vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
 
@@ -2486,6 +2490,11 @@ static void do_interrupt_requests(struct
 {
 	vmx_update_window_states(vcpu);
 
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+				GUEST_INTR_STATE_STI |
+				GUEST_INTR_STATE_MOV_SS);
+
 	if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
 		if (vcpu->arch.interrupt.pending) {
 			enable_nmi_window(vcpu);
@@ -2536,24 +2545,6 @@ static int vmx_set_tss_addr(struct kvm *
 	return 0;
 }
 
-static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu)
-{
-	struct kvm_guest_debug *dbg = &vcpu->guest_debug;
-
-	set_debugreg(dbg->bp[0], 0);
-	set_debugreg(dbg->bp[1], 1);
-	set_debugreg(dbg->bp[2], 2);
-	set_debugreg(dbg->bp[3], 3);
-
-	if (dbg->singlestep) {
-		unsigned long flags;
-
-		flags = vmcs_readl(GUEST_RFLAGS);
-		flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
-		vmcs_writel(GUEST_RFLAGS, flags);
-	}
-}
-
 static int handle_rmode_exception(struct kvm_vcpu *vcpu,
 				  int vec, u32 err_code)
 {
@@ -2570,9 +2561,17 @@ static int handle_rmode_exception(struct
 	 *        the required debugging infrastructure rework.
 	 */
 	switch (vec) {
-	case DE_VECTOR:
 	case DB_VECTOR:
+		if (vcpu->guest_debug &
+		    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+			return 0;
+		kvm_queue_exception(vcpu, vec);
+		return 1;
 	case BP_VECTOR:
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+			return 0;
+		/* fall through */
+	case DE_VECTOR:
 	case OF_VECTOR:
 	case BR_VECTOR:
 	case UD_VECTOR:
@@ -2589,8 +2588,8 @@ static int handle_rmode_exception(struct
 static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	u32 intr_info, error_code;
-	unsigned long cr2, rip;
+	u32 intr_info, ex_no, error_code;
+	unsigned long cr2, rip, dr6;
 	u32 vect_info;
 	enum emulation_result er;
 
@@ -2649,14 +2648,30 @@ static int handle_exception(struct kvm_v
 		return 1;
 	}
 
-	if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) ==
-	    (INTR_TYPE_EXCEPTION | 1)) {
+	ex_no = intr_info & INTR_INFO_VECTOR_MASK;
+	switch (ex_no) {
+	case DB_VECTOR:
+		dr6 = vmcs_readl(EXIT_QUALIFICATION);
+		if (!(vcpu->guest_debug &
+		      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
+			vcpu->arch.dr6 = dr6 | DR6_FIXED_1;
+			kvm_queue_exception(vcpu, DB_VECTOR);
+			return 1;
+		}
+		kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
+		kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
+		/* fall through */
+	case BP_VECTOR:
 		kvm_run->exit_reason = KVM_EXIT_DEBUG;
-		return 0;
+		kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
+		kvm_run->debug.arch.exception = ex_no;
+		break;
+	default:
+		kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
+		kvm_run->ex.exception = ex_no;
+		kvm_run->ex.error_code = error_code;
+		break;
 	}
-	kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
-	kvm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK;
-	kvm_run->ex.error_code = error_code;
 	return 0;
 }
 
@@ -2677,7 +2692,7 @@ static int handle_triple_fault(struct kv
 static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	unsigned long exit_qualification;
-	int size, down, in, string, rep;
+	int size, in, string;
 	unsigned port;
 
 	++vcpu->stat.io_exits;
@@ -2693,8 +2708,6 @@ static int handle_io(struct kvm_vcpu *vc
 
 	size = (exit_qualification & 7) + 1;
 	in = (exit_qualification & 8) != 0;
-	down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
-	rep = (exit_qualification & 32) != 0;
 	port = exit_qualification >> 16;
 
 	skip_emulated_instruction(vcpu);
@@ -2795,21 +2808,44 @@ static int handle_dr(struct kvm_vcpu *vc
 	unsigned long val;
 	int dr, reg;
 
-	/*
-	 * FIXME: this code assumes the host is debugging the guest.
-	 *        need to deal with guest debugging itself too.
-	 */
+	dr = vmcs_readl(GUEST_DR7);
+	if (dr & DR7_GD) {
+		/*
+		 * As the vm-exit takes precedence over the debug trap, we
+		 * need to emulate the latter, either for the host or the
+		 * 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 =
+				vmcs_readl(GUEST_CS_BASE) +
+				vmcs_readl(GUEST_RIP);
+			kvm_run->debug.arch.exception = DB_VECTOR;
+			kvm_run->exit_reason = KVM_EXIT_DEBUG;
+			return 0;
+		} else {
+			vcpu->arch.dr7 &= ~DR7_GD;
+			vcpu->arch.dr6 |= DR6_BD;
+			vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
+			kvm_queue_exception(vcpu, DB_VECTOR);
+			return 1;
+		}
+	}
+
 	exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
-	dr = exit_qualification & 7;
-	reg = (exit_qualification >> 8) & 15;
-	if (exit_qualification & 16) {
-		/* mov from dr */
+	dr = exit_qualification & DEBUG_REG_ACCESS_NUM;
+	reg = DEBUG_REG_ACCESS_REG(exit_qualification);
+	if (exit_qualification & TYPE_MOV_FROM_DR) {
 		switch (dr) {
+		case 0 ... 3:
+			val = vcpu->arch.db[dr];
+			break;
 		case 6:
-			val = 0xffff0ff0;
+			val = vcpu->arch.dr6;
 			break;
 		case 7:
-			val = 0x400;
+			val = vcpu->arch.dr7;
 			break;
 		default:
 			val = 0;
@@ -2817,7 +2853,38 @@ static int handle_dr(struct kvm_vcpu *vc
 		kvm_register_write(vcpu, reg, val);
 		KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
 	} else {
-		/* mov to dr */
+		val = vcpu->arch.regs[reg];
+		switch (dr) {
+		case 0 ... 3:
+			vcpu->arch.db[dr] = val;
+			if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+				vcpu->arch.eff_db[dr] = val;
+			break;
+		case 4 ... 5:
+			if (vcpu->arch.cr4 & X86_CR4_DE)
+				kvm_queue_exception(vcpu, UD_VECTOR);
+			break;
+		case 6:
+			if (val & 0xffffffff00000000ULL) {
+				kvm_queue_exception(vcpu, GP_VECTOR);
+				break;
+			}
+			vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
+			break;
+		case 7:
+			if (val & 0xffffffff00000000ULL) {
+				kvm_queue_exception(vcpu, GP_VECTOR);
+				break;
+			}
+			vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
+			if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
+				vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
+				vcpu->arch.switch_db_regs =
+					(val & DR7_BP_EN_MASK);
+			}
+			break;
+		}
+		KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)val, handler);
 	}
 	skip_emulated_instruction(vcpu);
 	return 1;
@@ -2968,17 +3035,25 @@ static int handle_task_switch(struct kvm
 	}
 	tss_selector = exit_qualification;
 
-	return kvm_task_switch(vcpu, tss_selector, reason);
+	if (!kvm_task_switch(vcpu, tss_selector, reason))
+		return 0;
+
+	/* clear all local breakpoint enable flags */
+	vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~55);
+
+	/*
+	 * TODO: What about debug traps on tss switch?
+	 *       Are we supposed to inject them and update dr6?
+	 */
+
+	return 1;
 }
 
 static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	u64 exit_qualification;
-	enum emulation_result er;
 	gpa_t gpa;
-	unsigned long hva;
 	int gla_validity;
-	int r;
 
 	exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
 
@@ -3001,32 +3076,7 @@ static int handle_ept_violation(struct k
 	}
 
 	gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
-	hva = gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT);
-	if (!kvm_is_error_hva(hva)) {
-		r = kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
-		if (r < 0) {
-			printk(KERN_ERR "EPT: Not enough memory!\n");
-			return -ENOMEM;
-		}
-		return 1;
-	} else {
-		/* must be MMIO */
-		er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
-
-		if (er == EMULATE_FAIL) {
-			printk(KERN_ERR
-			 "EPT: Fail to handle EPT violation vmexit!er is %d\n",
-			 er);
-			printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
-			 (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
-			 (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS));
-			printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
-				(long unsigned int)exit_qualification);
-			return -ENOTSUPP;
-		} else if (er == EMULATE_DO_MMIO)
-			return 0;
-	}
-	return 1;
+	return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
 }
 
 static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -3046,7 +3096,7 @@ static void handle_invalid_guest_state(s
 				struct kvm_run *kvm_run)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	int err;
+	enum emulation_result err = EMULATE_DONE;
 
 	preempt_enable();
 	local_irq_enable();
@@ -3071,10 +3121,7 @@ static void handle_invalid_guest_state(s
 	local_irq_disable();
 	preempt_disable();
 
-	/* Guest state should be valid now except if we need to
-	 * emulate an MMIO */
-	if (guest_state_valid(vcpu))
-		vmx->emulation_required = 0;
+	vmx->invalid_state_emulation_result = err;
 }
 
 /*
@@ -3123,8 +3170,11 @@ static int kvm_handle_exit(struct kvm_ru
 
 	/* If we need to emulate an MMIO from handle_invalid_guest_state
 	 * we just return 0 */
-	if (vmx->emulation_required && emulate_invalid_guest_state)
-		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;
+	}
 
 	/* Access CR3 don't cause VMExit in paging mode, so we need
 	 * to sync with guest real CR3. */
@@ -3238,7 +3288,8 @@ static void vmx_complete_interrupts(stru
 			vmx->vcpu.arch.nmi_injected = false;
 	}
 	kvm_clear_exception_queue(&vmx->vcpu);
-	if (idtv_info_valid && type == INTR_TYPE_EXCEPTION) {
+	if (idtv_info_valid && (type == INTR_TYPE_HARD_EXCEPTION ||
+				type == INTR_TYPE_SOFT_EXCEPTION)) {
 		if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
 			error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
 			kvm_queue_exception_e(&vmx->vcpu, vector, error);
@@ -3259,6 +3310,11 @@ static void vmx_intr_assist(struct kvm_v
 
 	vmx_update_window_states(vcpu);
 
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+				GUEST_INTR_STATE_STI |
+				GUEST_INTR_STATE_MOV_SS);
+
 	if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
 		if (vcpu->arch.interrupt.pending) {
 			enable_nmi_window(vcpu);
@@ -3347,6 +3403,8 @@ static void vmx_vcpu_run(struct kvm_vcpu
 	 */
 	vmcs_writel(HOST_CR0, read_cr0());
 
+	set_debugreg(vcpu->arch.dr6, 6);
+
 	asm(
 		/* Store host registers */
 		"push %%"R"dx; push %%"R"bp;"
@@ -3441,6 +3499,8 @@ static void vmx_vcpu_run(struct kvm_vcpu
 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
 	vcpu->arch.regs_dirty = 0;
 
+	get_debugreg(vcpu->arch.dr6, 6);
+
 	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
 	if (vmx->rmode.irq.pending)
 		fixup_rmode_irq(vmx);
@@ -3595,7 +3655,6 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.vcpu_put = vmx_vcpu_put,
 
 	.set_guest_debug = set_guest_debug,
-	.guest_debug_pre = kvm_guest_debug_pre,
 	.get_msr = vmx_get_msr,
 	.set_msr = vmx_set_msr,
 	.get_segment_base = vmx_get_segment_base,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/x86.c linux-libre-2.6.30-gnu1/arch/x86/kvm/x86.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/x86.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/x86.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/highmem.h>
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
+#include <linux/cpufreq.h>
 
 #include <asm/uaccess.h>
 #include <asm/msr.h>
@@ -69,6 +70,8 @@ static u64 __read_mostly efer_reserved_b
 
 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
 				    struct kvm_cpuid_entry2 __user *entries);
+struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
+					      u32 function, u32 index);
 
 struct kvm_x86_ops *kvm_x86_ops;
 EXPORT_SYMBOL_GPL(kvm_x86_ops);
@@ -173,6 +176,7 @@ void kvm_inject_page_fault(struct kvm_vc
 			   u32 error_code)
 {
 	++vcpu->stat.pf_guest;
+
 	if (vcpu->arch.exception.pending) {
 		if (vcpu->arch.exception.nr == PF_VECTOR) {
 			printk(KERN_DEBUG "kvm: inject_page_fault:"
@@ -334,6 +338,9 @@ EXPORT_SYMBOL_GPL(kvm_lmsw);
 
 void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
+	unsigned long old_cr4 = vcpu->arch.cr4;
+	unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
+
 	if (cr4 & CR4_RESERVED_BITS) {
 		printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
 		kvm_inject_gp(vcpu, 0);
@@ -347,7 +354,8 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu,
 			kvm_inject_gp(vcpu, 0);
 			return;
 		}
-	} else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE)
+	} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
+		   && ((cr4 ^ old_cr4) & pdptr_bits)
 		   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
 		printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
 		kvm_inject_gp(vcpu, 0);
@@ -361,6 +369,7 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu,
 	}
 	kvm_x86_ops->set_cr4(vcpu, cr4);
 	vcpu->arch.cr4 = cr4;
+	vcpu->arch.mmu.base_role.cr4_pge = (cr4 & X86_CR4_PGE) && !tdp_enabled;
 	kvm_mmu_sync_global(vcpu);
 	kvm_mmu_reset_context(vcpu);
 }
@@ -442,6 +451,11 @@ unsigned long kvm_get_cr8(struct kvm_vcp
 }
 EXPORT_SYMBOL_GPL(kvm_get_cr8);
 
+static inline u32 bit(int bitno)
+{
+	return 1 << (bitno & 31);
+}
+
 /*
  * List of msr numbers which we expose to userspace through KVM_GET_MSRS
  * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
@@ -456,7 +470,7 @@ static u32 msrs_to_save[] = {
 	MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
 	MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
-	MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT
+	MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
 };
 
 static unsigned num_msrs_to_save;
@@ -481,6 +495,28 @@ static void set_efer(struct kvm_vcpu *vc
 		return;
 	}
 
+	if (efer & EFER_FFXSR) {
+		struct kvm_cpuid_entry2 *feat;
+
+		feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+		if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
+			printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
+			kvm_inject_gp(vcpu, 0);
+			return;
+		}
+	}
+
+	if (efer & EFER_SVME) {
+		struct kvm_cpuid_entry2 *feat;
+
+		feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+		if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
+			printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
+			kvm_inject_gp(vcpu, 0);
+			return;
+		}
+	}
+
 	kvm_x86_ops->set_efer(vcpu, efer);
 
 	efer &= ~EFER_LMA;
@@ -586,6 +622,8 @@ static void kvm_set_time_scale(uint32_t
 		 hv_clock->tsc_to_system_mul);
 }
 
+static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz);
+
 static void kvm_write_guest_time(struct kvm_vcpu *v)
 {
 	struct timespec ts;
@@ -596,9 +634,9 @@ static void kvm_write_guest_time(struct
 	if ((!vcpu->time_page))
 		return;
 
-	if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) {
-		kvm_set_time_scale(tsc_khz, &vcpu->hv_clock);
-		vcpu->hv_clock_tsc_khz = tsc_khz;
+	if (unlikely(vcpu->hv_clock_tsc_khz != __get_cpu_var(cpu_tsc_khz))) {
+		kvm_set_time_scale(__get_cpu_var(cpu_tsc_khz), &vcpu->hv_clock);
+		vcpu->hv_clock_tsc_khz = __get_cpu_var(cpu_tsc_khz);
 	}
 
 	/* Keep irq disabled to prevent changes to the clock */
@@ -629,6 +667,16 @@ static void kvm_write_guest_time(struct
 	mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
 }
 
+static int kvm_request_guest_time_update(struct kvm_vcpu *v)
+{
+	struct kvm_vcpu_arch *vcpu = &v->arch;
+
+	if (!vcpu->time_page)
+		return 0;
+	set_bit(KVM_REQ_KVMCLOCK_UPDATE, &v->requests);
+	return 1;
+}
+
 static bool msr_mtrr_valid(unsigned msr)
 {
 	switch (msr) {
@@ -722,6 +770,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
 		break;
 	case MSR_IA32_UCODE_REV:
 	case MSR_IA32_UCODE_WRITE:
+	case MSR_VM_HSAVE_PA:
 		break;
 	case 0x200 ... 0x2ff:
 		return set_msr_mtrr(vcpu, msr, data);
@@ -758,7 +807,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
 			vcpu->arch.time_page = NULL;
 		}
 
-		kvm_write_guest_time(vcpu);
+		kvm_request_guest_time_update(vcpu);
 		break;
 	}
 	default:
@@ -843,6 +892,7 @@ int kvm_get_msr_common(struct kvm_vcpu *
 	case MSR_IA32_LASTBRANCHTOIP:
 	case MSR_IA32_LASTINTFROMIP:
 	case MSR_IA32_LASTINTTOIP:
+	case MSR_VM_HSAVE_PA:
 		data = 0;
 		break;
 	case MSR_MTRRcap:
@@ -967,10 +1017,13 @@ int kvm_dev_ioctl_check_extension(long e
 	case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
 	case KVM_CAP_SET_TSS_ADDR:
 	case KVM_CAP_EXT_CPUID:
+	case KVM_CAP_CLOCKSOURCE:
 	case KVM_CAP_PIT:
 	case KVM_CAP_NOP_IO_DELAY:
 	case KVM_CAP_MP_STATE:
 	case KVM_CAP_SYNC_MMU:
+	case KVM_CAP_REINJECT_CONTROL:
+	case KVM_CAP_IRQ_INJECT_STATUS:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -991,9 +1044,6 @@ int kvm_dev_ioctl_check_extension(long e
 	case KVM_CAP_IOMMU:
 		r = iommu_found();
 		break;
-	case KVM_CAP_CLOCKSOURCE:
-		r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC);
-		break;
 	default:
 		r = 0;
 		break;
@@ -1044,7 +1094,7 @@ long kvm_arch_dev_ioctl(struct file *fil
 		if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
 			goto out;
 		r = kvm_dev_ioctl_get_supported_cpuid(&cpuid,
-			cpuid_arg->entries);
+						      cpuid_arg->entries);
 		if (r)
 			goto out;
 
@@ -1064,7 +1114,7 @@ out:
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	kvm_x86_ops->vcpu_load(vcpu, cpu);
-	kvm_write_guest_time(vcpu);
+	kvm_request_guest_time_update(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -1075,9 +1125,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
 
 static int is_efer_nx(void)
 {
-	u64 efer;
+	unsigned long long efer = 0;
 
-	rdmsrl(MSR_EFER, efer);
+	rdmsrl_safe(MSR_EFER, &efer);
 	return efer & EFER_NX;
 }
 
@@ -1142,8 +1192,8 @@ out:
 }
 
 static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
-				    struct kvm_cpuid2 *cpuid,
-				    struct kvm_cpuid_entry2 __user *entries)
+				     struct kvm_cpuid2 *cpuid,
+				     struct kvm_cpuid_entry2 __user *entries)
 {
 	int r;
 
@@ -1162,8 +1212,8 @@ out:
 }
 
 static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
-				    struct kvm_cpuid2 *cpuid,
-				    struct kvm_cpuid_entry2 __user *entries)
+				     struct kvm_cpuid2 *cpuid,
+				     struct kvm_cpuid_entry2 __user *entries)
 {
 	int r;
 
@@ -1172,7 +1222,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(str
 		goto out;
 	r = -EFAULT;
 	if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
-			   vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
+			 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out;
 	return 0;
 
@@ -1181,18 +1231,13 @@ out:
 	return r;
 }
 
-static inline u32 bit(int bitno)
-{
-	return 1 << (bitno & 31);
-}
-
 static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
-			  u32 index)
+			   u32 index)
 {
 	entry->function = function;
 	entry->index = index;
 	cpuid_count(entry->function, entry->index,
-		&entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
+		    &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
 	entry->flags = 0;
 }
 
@@ -1218,19 +1263,21 @@ static void do_cpuid_ent(struct kvm_cpui
 		bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
 		bit(X86_FEATURE_MMX) | bit(X86_FEATURE_FXSR) |
 		bit(X86_FEATURE_SYSCALL) |
-		(bit(X86_FEATURE_NX) && is_efer_nx()) |
+		(is_efer_nx() ? bit(X86_FEATURE_NX) : 0) |
 #ifdef CONFIG_X86_64
 		bit(X86_FEATURE_LM) |
 #endif
+		bit(X86_FEATURE_FXSR_OPT) |
 		bit(X86_FEATURE_MMXEXT) |
 		bit(X86_FEATURE_3DNOWEXT) |
 		bit(X86_FEATURE_3DNOW);
 	const u32 kvm_supported_word3_x86_features =
 		bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16);
 	const u32 kvm_supported_word6_x86_features =
-		bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY);
+		bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY) |
+		bit(X86_FEATURE_SVM);
 
-	/* all func 2 cpuid_count() should be called on the same cpu */
+	/* all calls to cpuid_count() should be made on the same cpu */
 	get_cpu();
 	do_cpuid_1_ent(entry, function, index);
 	++*nent;
@@ -1304,7 +1351,7 @@ static void do_cpuid_ent(struct kvm_cpui
 }
 
 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
-				    struct kvm_cpuid_entry2 __user *entries)
+				     struct kvm_cpuid_entry2 __user *entries)
 {
 	struct kvm_cpuid_entry2 *cpuid_entries;
 	int limit, nent = 0, r = -E2BIG;
@@ -1321,7 +1368,7 @@ static int kvm_dev_ioctl_get_supported_c
 	limit = cpuid_entries[0].eax;
 	for (func = 1; func <= limit && nent < cpuid->nent; ++func)
 		do_cpuid_ent(&cpuid_entries[nent], func, 0,
-				&nent, cpuid->nent);
+			     &nent, cpuid->nent);
 	r = -E2BIG;
 	if (nent >= cpuid->nent)
 		goto out_free;
@@ -1330,10 +1377,10 @@ static int kvm_dev_ioctl_get_supported_c
 	limit = cpuid_entries[nent - 1].eax;
 	for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
 		do_cpuid_ent(&cpuid_entries[nent], func, 0,
-			       &nent, cpuid->nent);
+			     &nent, cpuid->nent);
 	r = -EFAULT;
 	if (copy_to_user(entries, cpuid_entries,
-			nent * sizeof(struct kvm_cpuid_entry2)))
+			 nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out_free;
 	cpuid->nent = nent;
 	r = 0;
@@ -1477,7 +1524,7 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
 			goto out;
 		r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid,
-				cpuid_arg->entries);
+					      cpuid_arg->entries);
 		if (r)
 			goto out;
 		break;
@@ -1490,7 +1537,7 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
 			goto out;
 		r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
-				cpuid_arg->entries);
+					      cpuid_arg->entries);
 		if (r)
 			goto out;
 		r = -EFAULT;
@@ -1710,6 +1757,15 @@ static int kvm_vm_ioctl_set_pit(struct k
 	return r;
 }
 
+static int kvm_vm_ioctl_reinject(struct kvm *kvm,
+				 struct kvm_reinject_control *control)
+{
+	if (!kvm->arch.vpit)
+		return -ENXIO;
+	kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
+	return 0;
+}
+
 /*
  * Get (and clear) the dirty memory log for a memory slot.
  */
@@ -1807,13 +1863,26 @@ long kvm_arch_vm_ioctl(struct file *filp
 			}
 		} else
 			goto out;
+		r = kvm_setup_default_irq_routing(kvm);
+		if (r) {
+			kfree(kvm->arch.vpic);
+			kfree(kvm->arch.vioapic);
+			goto out;
+		}
 		break;
 	case KVM_CREATE_PIT:
+		mutex_lock(&kvm->lock);
+		r = -EEXIST;
+		if (kvm->arch.vpit)
+			goto create_pit_unlock;
 		r = -ENOMEM;
 		kvm->arch.vpit = kvm_create_pit(kvm);
 		if (kvm->arch.vpit)
 			r = 0;
+	create_pit_unlock:
+		mutex_unlock(&kvm->lock);
 		break;
+	case KVM_IRQ_LINE_STATUS:
 	case KVM_IRQ_LINE: {
 		struct kvm_irq_level irq_event;
 
@@ -1821,10 +1890,17 @@ long kvm_arch_vm_ioctl(struct file *filp
 		if (copy_from_user(&irq_event, argp, sizeof irq_event))
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
+			__s32 status;
 			mutex_lock(&kvm->lock);
-			kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
-				    irq_event.irq, irq_event.level);
+			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+					irq_event.irq, irq_event.level);
 			mutex_unlock(&kvm->lock);
+			if (ioctl == KVM_IRQ_LINE_STATUS) {
+				irq_event.status = status;
+				if (copy_to_user(argp, &irq_event,
+							sizeof irq_event))
+					goto out;
+			}
 			r = 0;
 		}
 		break;
@@ -1907,6 +1983,17 @@ long kvm_arch_vm_ioctl(struct file *filp
 		r = 0;
 		break;
 	}
+	case KVM_REINJECT_CONTROL: {
+		struct kvm_reinject_control control;
+		r =  -EFAULT;
+		if (copy_from_user(&control, argp, sizeof(control)))
+			goto out;
+		r = kvm_vm_ioctl_reinject(kvm, &control);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		;
 	}
@@ -1960,10 +2047,8 @@ static struct kvm_io_device *vcpu_find_m
 	return dev;
 }
 
-int emulator_read_std(unsigned long addr,
-			     void *val,
-			     unsigned int bytes,
-			     struct kvm_vcpu *vcpu)
+static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
+			       struct kvm_vcpu *vcpu)
 {
 	void *data = val;
 	int r = X86EMUL_CONTINUE;
@@ -1971,27 +2056,57 @@ int emulator_read_std(unsigned long addr
 	while (bytes) {
 		gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
 		unsigned offset = addr & (PAGE_SIZE-1);
-		unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
+		unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
 		int ret;
 
 		if (gpa == UNMAPPED_GVA) {
 			r = X86EMUL_PROPAGATE_FAULT;
 			goto out;
 		}
-		ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
+		ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
 		if (ret < 0) {
 			r = X86EMUL_UNHANDLEABLE;
 			goto out;
 		}
 
-		bytes -= tocopy;
-		data += tocopy;
-		addr += tocopy;
+		bytes -= toread;
+		data += toread;
+		addr += toread;
 	}
 out:
 	return r;
 }
-EXPORT_SYMBOL_GPL(emulator_read_std);
+
+static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
+				struct kvm_vcpu *vcpu)
+{
+	void *data = val;
+	int r = X86EMUL_CONTINUE;
+
+	while (bytes) {
+		gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+		unsigned offset = addr & (PAGE_SIZE-1);
+		unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
+		int ret;
+
+		if (gpa == UNMAPPED_GVA) {
+			r = X86EMUL_PROPAGATE_FAULT;
+			goto out;
+		}
+		ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
+		if (ret < 0) {
+			r = X86EMUL_UNHANDLEABLE;
+			goto out;
+		}
+
+		bytes -= towrite;
+		data += towrite;
+		addr += towrite;
+	}
+out:
+	return r;
+}
+
 
 static int emulator_read_emulated(unsigned long addr,
 				  void *val,
@@ -2013,8 +2128,8 @@ static int emulator_read_emulated(unsign
 	if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
 		goto mmio;
 
-	if (emulator_read_std(addr, val, bytes, vcpu)
-			== X86EMUL_CONTINUE)
+	if (kvm_read_guest_virt(addr, val, bytes, vcpu)
+				== X86EMUL_CONTINUE)
 		return X86EMUL_CONTINUE;
 	if (gpa == UNMAPPED_GVA)
 		return X86EMUL_PROPAGATE_FAULT;
@@ -2217,7 +2332,7 @@ void kvm_report_emulation_failure(struct
 
 	rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
 
-	emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
+	kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
 
 	printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
 	       context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
@@ -2225,7 +2340,7 @@ void kvm_report_emulation_failure(struct
 EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
 
 static struct x86_emulate_ops emulate_ops = {
-	.read_std            = emulator_read_std,
+	.read_std            = kvm_read_guest_virt,
 	.read_emulated       = emulator_read_emulated,
 	.write_emulated      = emulator_write_emulated,
 	.cmpxchg_emulated    = emulator_cmpxchg_emulated,
@@ -2327,40 +2442,19 @@ int emulate_instruction(struct kvm_vcpu
 }
 EXPORT_SYMBOL_GPL(emulate_instruction);
 
-static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(vcpu->arch.pio.guest_pages); ++i)
-		if (vcpu->arch.pio.guest_pages[i]) {
-			kvm_release_page_dirty(vcpu->arch.pio.guest_pages[i]);
-			vcpu->arch.pio.guest_pages[i] = NULL;
-		}
-}
-
 static int pio_copy_data(struct kvm_vcpu *vcpu)
 {
 	void *p = vcpu->arch.pio_data;
-	void *q;
+	gva_t q = vcpu->arch.pio.guest_gva;
 	unsigned bytes;
-	int nr_pages = vcpu->arch.pio.guest_pages[1] ? 2 : 1;
+	int ret;
 
-	q = vmap(vcpu->arch.pio.guest_pages, nr_pages, VM_READ|VM_WRITE,
-		 PAGE_KERNEL);
-	if (!q) {
-		free_pio_guest_pages(vcpu);
-		return -ENOMEM;
-	}
-	q += vcpu->arch.pio.guest_page_offset;
 	bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
 	if (vcpu->arch.pio.in)
-		memcpy(q, p, bytes);
+		ret = kvm_write_guest_virt(q, p, bytes, vcpu);
 	else
-		memcpy(p, q, bytes);
-	q -= vcpu->arch.pio.guest_page_offset;
-	vunmap(q);
-	free_pio_guest_pages(vcpu);
-	return 0;
+		ret = kvm_read_guest_virt(q, p, bytes, vcpu);
+	return ret;
 }
 
 int complete_pio(struct kvm_vcpu *vcpu)
@@ -2471,7 +2565,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcp
 	vcpu->arch.pio.in = in;
 	vcpu->arch.pio.string = 0;
 	vcpu->arch.pio.down = 0;
-	vcpu->arch.pio.guest_page_offset = 0;
 	vcpu->arch.pio.rep = 0;
 
 	if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2499,9 +2592,7 @@ int kvm_emulate_pio_string(struct kvm_vc
 		  gva_t address, int rep, unsigned port)
 {
 	unsigned now, in_page;
-	int i, ret = 0;
-	int nr_pages = 1;
-	struct page *page;
+	int ret = 0;
 	struct kvm_io_device *pio_dev;
 
 	vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2513,7 +2604,6 @@ int kvm_emulate_pio_string(struct kvm_vc
 	vcpu->arch.pio.in = in;
 	vcpu->arch.pio.string = 1;
 	vcpu->arch.pio.down = down;
-	vcpu->arch.pio.guest_page_offset = offset_in_page(address);
 	vcpu->arch.pio.rep = rep;
 
 	if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2533,15 +2623,8 @@ int kvm_emulate_pio_string(struct kvm_vc
 	else
 		in_page = offset_in_page(address) + size;
 	now = min(count, (unsigned long)in_page / size);
-	if (!now) {
-		/*
-		 * String I/O straddles page boundary.  Pin two guest pages
-		 * so that we satisfy atomicity constraints.  Do just one
-		 * transaction to avoid complexity.
-		 */
-		nr_pages = 2;
+	if (!now)
 		now = 1;
-	}
 	if (down) {
 		/*
 		 * String I/O in reverse.  Yuck.  Kill the guest, fix later.
@@ -2556,15 +2639,7 @@ int kvm_emulate_pio_string(struct kvm_vc
 	if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count)
 		kvm_x86_ops->skip_emulated_instruction(vcpu);
 
-	for (i = 0; i < nr_pages; ++i) {
-		page = gva_to_page(vcpu, address + i * PAGE_SIZE);
-		vcpu->arch.pio.guest_pages[i] = page;
-		if (!page) {
-			kvm_inject_gp(vcpu, 0);
-			free_pio_guest_pages(vcpu);
-			return 1;
-		}
-	}
+	vcpu->arch.pio.guest_gva = address;
 
 	pio_dev = vcpu_find_pio_dev(vcpu, port,
 				    vcpu->arch.pio.cur_count,
@@ -2572,7 +2647,11 @@ int kvm_emulate_pio_string(struct kvm_vc
 	if (!vcpu->arch.pio.in) {
 		/* string PIO write */
 		ret = pio_copy_data(vcpu);
-		if (ret >= 0 && pio_dev) {
+		if (ret == X86EMUL_PROPAGATE_FAULT) {
+			kvm_inject_gp(vcpu, 0);
+			return 1;
+		}
+		if (ret == 0 && pio_dev) {
 			pio_string_write(pio_dev, vcpu);
 			complete_pio(vcpu);
 			if (vcpu->arch.pio.count == 0)
@@ -2587,9 +2666,72 @@ int kvm_emulate_pio_string(struct kvm_vc
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
 
+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)
+{
+	struct cpufreq_freqs *freq = data;
+	struct kvm *kvm;
+	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);
+
+	spin_lock(&kvm_lock);
+	list_for_each_entry(kvm, &vm_list, vm_list) {
+		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+			vcpu = kvm->vcpus[i];
+			if (!vcpu)
+				continue;
+			if (vcpu->cpu != freq->cpu)
+				continue;
+			if (!kvm_request_guest_time_update(vcpu))
+				continue;
+			if (vcpu->cpu != smp_processor_id())
+				send_ipi++;
+		}
+	}
+	spin_unlock(&kvm_lock);
+
+	if (freq->old < freq->new && send_ipi) {
+		/*
+		 * We upscale the frequency.  Must make the guest
+		 * doesn't see old kvmclock values while running with
+		 * the new frequency, otherwise we risk the guest sees
+		 * time go backwards.
+		 *
+		 * In case we update the frequency for another cpu
+		 * (which might be in guest context) send an interrupt
+		 * to kick the cpu out of guest context.  Next time
+		 * guest context is entered kvmclock will be updated,
+		 * so the guest will not see stale values.
+		 */
+		smp_call_function_single(freq->cpu, bounce_off, NULL, 1);
+	}
+	return 0;
+}
+
+static struct notifier_block kvmclock_cpufreq_notifier_block = {
+        .notifier_call  = kvmclock_cpufreq_notifier
+};
+
 int kvm_arch_init(void *opaque)
 {
-	int r;
+	int r, cpu;
 	struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
 
 	if (kvm_x86_ops) {
@@ -2620,6 +2762,15 @@ int kvm_arch_init(void *opaque)
 	kvm_mmu_set_base_ptes(PT_PRESENT_MASK);
 	kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
 			PT_DIRTY_MASK, PT64_NX_MASK, 0, 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);
+	}
+
 	return 0;
 
 out:
@@ -2628,6 +2779,9 @@ out:
 
 void kvm_arch_exit(void)
 {
+	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+		cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
+					    CPUFREQ_TRANSITION_NOTIFIER);
 	kvm_x86_ops = NULL;
 	kvm_mmu_module_exit();
 }
@@ -2827,25 +2981,20 @@ static int is_matching_cpuid_entry(struc
 	if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index)
 		return 0;
 	if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
-		!(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
+	    !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
 		return 0;
 	return 1;
 }
 
-void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
+struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
+					      u32 function, u32 index)
 {
 	int i;
-	u32 function, index;
-	struct kvm_cpuid_entry2 *e, *best;
+	struct kvm_cpuid_entry2 *best = NULL;
 
-	function = kvm_register_read(vcpu, VCPU_REGS_RAX);
-	index = kvm_register_read(vcpu, VCPU_REGS_RCX);
-	kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
-	kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
-	kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
-	kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
-	best = NULL;
 	for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
+		struct kvm_cpuid_entry2 *e;
+
 		e = &vcpu->arch.cpuid_entries[i];
 		if (is_matching_cpuid_entry(e, function, index)) {
 			if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
@@ -2860,6 +3009,21 @@ void kvm_emulate_cpuid(struct kvm_vcpu *
 			if (!best || e->function > best->function)
 				best = e;
 	}
+	return best;
+}
+
+void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
+{
+	u32 function, index;
+	struct kvm_cpuid_entry2 *best;
+
+	function = kvm_register_read(vcpu, VCPU_REGS_RAX);
+	index = kvm_register_read(vcpu, VCPU_REGS_RCX);
+	kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
+	kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
+	kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
+	kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
+	best = kvm_find_cpuid_entry(vcpu, function, index);
 	if (best) {
 		kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
 		kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);
@@ -2945,6 +3109,8 @@ static int vcpu_enter_guest(struct kvm_v
 	if (vcpu->requests) {
 		if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
 			__kvm_migrate_timers(vcpu);
+		if (test_and_clear_bit(KVM_REQ_KVMCLOCK_UPDATE, &vcpu->requests))
+			kvm_write_guest_time(vcpu);
 		if (test_and_clear_bit(KVM_REQ_MMU_SYNC, &vcpu->requests))
 			kvm_mmu_sync_roots(vcpu);
 		if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
@@ -2979,9 +3145,6 @@ static int vcpu_enter_guest(struct kvm_v
 		goto out;
 	}
 
-	if (vcpu->guest_debug.enabled)
-		kvm_x86_ops->guest_debug_pre(vcpu);
-
 	vcpu->guest_mode = 1;
 	/*
 	 * Make sure that guest_mode assignment won't happen after
@@ -3002,10 +3165,34 @@ static int vcpu_enter_guest(struct kvm_v
 
 	kvm_guest_enter();
 
+	get_debugreg(vcpu->arch.host_dr6, 6);
+	get_debugreg(vcpu->arch.host_dr7, 7);
+	if (unlikely(vcpu->arch.switch_db_regs)) {
+		get_debugreg(vcpu->arch.host_db[0], 0);
+		get_debugreg(vcpu->arch.host_db[1], 1);
+		get_debugreg(vcpu->arch.host_db[2], 2);
+		get_debugreg(vcpu->arch.host_db[3], 3);
+
+		set_debugreg(0, 7);
+		set_debugreg(vcpu->arch.eff_db[0], 0);
+		set_debugreg(vcpu->arch.eff_db[1], 1);
+		set_debugreg(vcpu->arch.eff_db[2], 2);
+		set_debugreg(vcpu->arch.eff_db[3], 3);
+	}
 
 	KVMTRACE_0D(VMENTRY, vcpu, entryexit);
 	kvm_x86_ops->run(vcpu, kvm_run);
 
+	if (unlikely(vcpu->arch.switch_db_regs)) {
+		set_debugreg(0, 7);
+		set_debugreg(vcpu->arch.host_db[0], 0);
+		set_debugreg(vcpu->arch.host_db[1], 1);
+		set_debugreg(vcpu->arch.host_db[2], 2);
+		set_debugreg(vcpu->arch.host_db[3], 3);
+	}
+	set_debugreg(vcpu->arch.host_dr6, 6);
+	set_debugreg(vcpu->arch.host_dr7, 7);
+
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
@@ -3192,7 +3379,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	/*
 	 * Don't leak debug flags in case they were set for guest debugging
 	 */
-	if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep)
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
 		regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
 
 	vcpu_put(vcpu);
@@ -3811,15 +3998,32 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 	return 0;
 }
 
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
-				    struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					struct kvm_guest_debug *dbg)
 {
-	int r;
+	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)) {
+		for (i = 0; i < KVM_NR_DB_REGS; ++i)
+			vcpu->arch.eff_db[i] = dbg->arch.debugreg[i];
+		vcpu->arch.switch_db_regs =
+			(dbg->arch.debugreg[7] & DR7_BP_EN_MASK);
+	} else {
+		for (i = 0; i < KVM_NR_DB_REGS; i++)
+			vcpu->arch.eff_db[i] = vcpu->arch.db[i];
+		vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK);
+	}
+
 	r = kvm_x86_ops->set_guest_debug(vcpu, dbg);
 
+	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);
+
 	vcpu_put(vcpu);
 
 	return r;
@@ -3962,6 +4166,11 @@ EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
+	if (vcpu->arch.time_page) {
+		kvm_release_page_dirty(vcpu->arch.time_page);
+		vcpu->arch.time_page = NULL;
+	}
+
 	kvm_x86_ops->vcpu_free(vcpu);
 }
 
@@ -4007,6 +4216,11 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu
 	vcpu->arch.nmi_pending = false;
 	vcpu->arch.nmi_injected = false;
 
+	vcpu->arch.switch_db_regs = 0;
+	memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
+	vcpu->arch.dr6 = DR6_FIXED_1;
+	vcpu->arch.dr7 = DR7_FIXED_1;
+
 	return kvm_x86_ops->vcpu_reset(vcpu);
 }
 
@@ -4100,6 +4314,8 @@ struct  kvm *kvm_arch_create_vm(void)
 	/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
 	set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
 
+	rdtscll(kvm->arch.vm_init_tsc);
+
 	return kvm;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/kvm/x86_emulate.c linux-libre-2.6.30-gnu1/arch/x86/kvm/x86_emulate.c
--- linux-libre-2.6.29-gnu1/arch/x86/kvm/x86_emulate.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/kvm/x86_emulate.c	2009-06-09 23:05:27.000000000 -0400
@@ -178,7 +178,7 @@ static u32 opcode_table[256] = {
 	0, ImplicitOps | Stack, 0, 0,
 	ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
 	/* 0xC8 - 0xCF */
-	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, ImplicitOps | Stack, 0, 0, 0, 0,
 	/* 0xD0 - 0xD7 */
 	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
 	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
@@ -1136,18 +1136,19 @@ static inline void emulate_push(struct x
 }
 
 static int emulate_pop(struct x86_emulate_ctxt *ctxt,
-		       struct x86_emulate_ops *ops)
+		       struct x86_emulate_ops *ops,
+		       void *dest, int len)
 {
 	struct decode_cache *c = &ctxt->decode;
 	int rc;
 
 	rc = ops->read_emulated(register_address(c, ss_base(ctxt),
 						 c->regs[VCPU_REGS_RSP]),
-				&c->src.val, c->src.bytes, ctxt->vcpu);
+				dest, len, ctxt->vcpu);
 	if (rc != 0)
 		return rc;
 
-	register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.bytes);
+	register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
 	return rc;
 }
 
@@ -1157,11 +1158,9 @@ static inline int emulate_grp1a(struct x
 	struct decode_cache *c = &ctxt->decode;
 	int rc;
 
-	c->src.bytes = c->dst.bytes;
-	rc = emulate_pop(ctxt, ops);
+	rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
 	if (rc != 0)
 		return rc;
-	c->dst.val = c->src.val;
 	return 0;
 }
 
@@ -1279,6 +1278,25 @@ static inline int emulate_grp9(struct x8
 	return 0;
 }
 
+static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
+			   struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+	unsigned long cs;
+
+	rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
+	if (rc)
+		return rc;
+	if (c->op_bytes == 4)
+		c->eip = (u32)c->eip;
+	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+	if (rc)
+		return rc;
+	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
+	return rc;
+}
+
 static inline int writeback(struct x86_emulate_ctxt *ctxt,
 			    struct x86_emulate_ops *ops)
 {
@@ -1467,11 +1485,9 @@ special_insn:
 		break;
 	case 0x58 ... 0x5f: /* pop reg */
 	pop_instruction:
-		c->src.bytes = c->op_bytes;
-		rc = emulate_pop(ctxt, ops);
+		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
 		if (rc != 0)
 			goto done;
-		c->dst.val = c->src.val;
 		break;
 	case 0x63:		/* movsxd */
 		if (ctxt->mode != X86EMUL_MODE_PROT64)
@@ -1738,6 +1754,11 @@ special_insn:
 	mov:
 		c->dst.val = c->src.val;
 		break;
+	case 0xcb:		/* ret far */
+		rc = emulate_ret_far(ctxt, ops);
+		if (rc)
+			goto done;
+		break;
 	case 0xd0 ... 0xd1:	/* Grp2 */
 		c->src.val = 1;
 		emulate_grp2(ctxt);
@@ -1908,11 +1929,16 @@ twobyte_insn:
 			c->dst.type = OP_NONE;
 			break;
 		case 3: /* lidt/vmmcall */
-			if (c->modrm_mod == 3 && c->modrm_rm == 1) {
-				rc = kvm_fix_hypercall(ctxt->vcpu);
-				if (rc)
-					goto done;
-				kvm_emulate_hypercall(ctxt->vcpu);
+			if (c->modrm_mod == 3) {
+				switch (c->modrm_rm) {
+				case 1:
+					rc = kvm_fix_hypercall(ctxt->vcpu);
+					if (rc)
+						goto done;
+					break;
+				default:
+					goto cannot_emulate;
+				}
 			} else {
 				rc = read_descriptor(ctxt, ops, c->src.ptr,
 						     &size, &address,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lguest/boot.c linux-libre-2.6.30-gnu1/arch/x86/lguest/boot.c
--- linux-libre-2.6.29-gnu1/arch/x86/lguest/boot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lguest/boot.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,6 +67,7 @@
 #include <asm/mce.h>
 #include <asm/io.h>
 #include <asm/i387.h>
+#include <asm/stackprotector.h>
 #include <asm/reboot.h>		/* for struct machine_ops */
 
 /*G:010 Welcome to the Guest!
@@ -107,7 +108,7 @@ static void async_hcall(unsigned long ca
 	local_irq_save(flags);
 	if (lguest_data.hcall_status[next_call] != 0xFF) {
 		/* Table full, so do normal hcall which will flush table. */
-		hcall(call, arg1, arg2, arg3);
+		kvm_hypercall3(call, arg1, arg2, arg3);
 	} else {
 		lguest_data.hcalls[next_call].arg0 = call;
 		lguest_data.hcalls[next_call].arg1 = arg1;
@@ -134,13 +135,32 @@ static void async_hcall(unsigned long ca
  *
  * So, when we're in lazy mode, we call async_hcall() to store the call for
  * future processing: */
-static void lazy_hcall(unsigned long call,
+static void lazy_hcall1(unsigned long call,
+		       unsigned long arg1)
+{
+	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+		kvm_hypercall1(call, arg1);
+	else
+		async_hcall(call, arg1, 0, 0);
+}
+
+static void lazy_hcall2(unsigned long call,
+		       unsigned long arg1,
+		       unsigned long arg2)
+{
+	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+		kvm_hypercall2(call, arg1, arg2);
+	else
+		async_hcall(call, arg1, arg2, 0);
+}
+
+static void lazy_hcall3(unsigned long call,
 		       unsigned long arg1,
 		       unsigned long arg2,
 		       unsigned long arg3)
 {
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-		hcall(call, arg1, arg2, arg3);
+		kvm_hypercall3(call, arg1, arg2, arg3);
 	else
 		async_hcall(call, arg1, arg2, arg3);
 }
@@ -150,7 +170,7 @@ static void lazy_hcall(unsigned long cal
 static void lguest_leave_lazy_mode(void)
 {
 	paravirt_leave_lazy(paravirt_get_lazy_mode());
-	hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
+	kvm_hypercall0(LHCALL_FLUSH_ASYNC);
 }
 
 /*G:033
@@ -173,24 +193,29 @@ static unsigned long save_fl(void)
 {
 	return lguest_data.irq_enabled;
 }
+PV_CALLEE_SAVE_REGS_THUNK(save_fl);
 
 /* restore_flags() just sets the flags back to the value given. */
 static void restore_fl(unsigned long flags)
 {
 	lguest_data.irq_enabled = flags;
 }
+PV_CALLEE_SAVE_REGS_THUNK(restore_fl);
 
 /* Interrupts go off... */
 static void irq_disable(void)
 {
 	lguest_data.irq_enabled = 0;
 }
+PV_CALLEE_SAVE_REGS_THUNK(irq_disable);
 
 /* Interrupts go on... */
 static void irq_enable(void)
 {
 	lguest_data.irq_enabled = X86_EFLAGS_IF;
 }
+PV_CALLEE_SAVE_REGS_THUNK(irq_enable);
+
 /*:*/
 /*M:003 Note that we don't check for outstanding interrupts when we re-enable
  * them (or when we unmask an interrupt).  This seems to work for the moment,
@@ -224,7 +249,7 @@ static void lguest_write_idt_entry(gate_
 	/* Keep the local copy up to date. */
 	native_write_idt_entry(dt, entrynum, g);
 	/* Tell Host about this new entry. */
-	hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+	kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
 }
 
 /* Changing to a different IDT is very rare: we keep the IDT up-to-date every
@@ -236,7 +261,7 @@ static void lguest_load_idt(const struct
 	struct desc_struct *idt = (void *)desc->address;
 
 	for (i = 0; i < (desc->size+1)/8; i++)
-		hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+		kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
 }
 
 /*
@@ -249,15 +274,15 @@ static void lguest_load_idt(const struct
  * controls the entire thing and the Guest asks it to make changes using the
  * LOAD_GDT hypercall.
  *
- * This is the opposite of the IDT code where we have a LOAD_IDT_ENTRY
- * hypercall and use that repeatedly to load a new IDT.  I don't think it
- * really matters, but wouldn't it be nice if they were the same?  Wouldn't
- * it be even better if you were the one to send the patch to fix it?
+ * This is the exactly like the IDT code.
  */
 static void lguest_load_gdt(const struct desc_ptr *desc)
 {
-	BUG_ON((desc->size+1)/8 != GDT_ENTRIES);
-	hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0);
+	unsigned int i;
+	struct desc_struct *gdt = (void *)desc->address;
+
+	for (i = 0; i < (desc->size+1)/8; i++)
+		kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b);
 }
 
 /* For a single GDT entry which changes, we do the lazy thing: alter our GDT,
@@ -267,7 +292,9 @@ static void lguest_write_gdt_entry(struc
 				   const void *desc, int type)
 {
 	native_write_gdt_entry(dt, entrynum, desc, type);
-	hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0);
+	/* Tell Host about this new entry. */
+	kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
+		       dt[entrynum].a, dt[entrynum].b);
 }
 
 /* OK, I lied.  There are three "thread local storage" GDT entries which change
@@ -278,8 +305,8 @@ static void lguest_load_tls(struct threa
 	/* There's one problem which normal hardware doesn't have: the Host
 	 * can't handle us removing entries we're currently using.  So we clear
 	 * the GS register here: if it's needed it'll be reloaded anyway. */
-	loadsegment(gs, 0);
-	lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
+	lazy_load_gs(0);
+	lazy_hcall2(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu);
 }
 
 /*G:038 That's enough excitement for now, back to ploughing through each of
@@ -377,7 +404,7 @@ static void lguest_cpuid(unsigned int *a
 static unsigned long current_cr0;
 static void lguest_write_cr0(unsigned long val)
 {
-	lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0);
+	lazy_hcall1(LHCALL_TS, val & X86_CR0_TS);
 	current_cr0 = val;
 }
 
@@ -391,7 +418,7 @@ static unsigned long lguest_read_cr0(voi
  * the vowels have been optimized out. */
 static void lguest_clts(void)
 {
-	lazy_hcall(LHCALL_TS, 0, 0, 0);
+	lazy_hcall1(LHCALL_TS, 0);
 	current_cr0 &= ~X86_CR0_TS;
 }
 
@@ -413,7 +440,7 @@ static bool cr3_changed = false;
 static void lguest_write_cr3(unsigned long cr3)
 {
 	lguest_data.pgdir = cr3;
-	lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0);
+	lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
 	cr3_changed = true;
 }
 
@@ -485,11 +512,17 @@ static void lguest_write_cr4(unsigned lo
  * into a process' address space.  We set the entry then tell the Host the
  * toplevel and address this corresponds to.  The Guest uses one pagetable per
  * process, so we need to tell the Host which one we're changing (mm->pgd). */
+static void lguest_pte_update(struct mm_struct *mm, unsigned long addr,
+			       pte_t *ptep)
+{
+	lazy_hcall3(LHCALL_SET_PTE, __pa(mm->pgd), addr, ptep->pte_low);
+}
+
 static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep, pte_t pteval)
 {
 	*ptep = pteval;
-	lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, pteval.pte_low);
+	lguest_pte_update(mm, addr, ptep);
 }
 
 /* The Guest calls this to set a top-level entry.  Again, we set the entry then
@@ -498,8 +531,8 @@ static void lguest_set_pte_at(struct mm_
 static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
 {
 	*pmdp = pmdval;
-	lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK,
-		   (__pa(pmdp)&(PAGE_SIZE-1))/4, 0);
+	lazy_hcall2(LHCALL_SET_PMD, __pa(pmdp) & PAGE_MASK,
+		   (__pa(pmdp) & (PAGE_SIZE - 1)) / 4);
 }
 
 /* There are a couple of legacy places where the kernel sets a PTE, but we
@@ -515,7 +548,7 @@ static void lguest_set_pte(pte_t *ptep,
 {
 	*ptep = pteval;
 	if (cr3_changed)
-		lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
+		lazy_hcall1(LHCALL_FLUSH_TLB, 1);
 }
 
 /* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on
@@ -531,7 +564,7 @@ static void lguest_set_pte(pte_t *ptep,
 static void lguest_flush_tlb_single(unsigned long addr)
 {
 	/* Simply set it to zero: if it was not, it will fault back in. */
-	lazy_hcall(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
+	lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
 }
 
 /* This is what happens after the Guest has removed a large number of entries.
@@ -539,7 +572,7 @@ static void lguest_flush_tlb_single(unsi
  * have changed, ie. virtual addresses below PAGE_OFFSET. */
 static void lguest_flush_tlb_user(void)
 {
-	lazy_hcall(LHCALL_FLUSH_TLB, 0, 0, 0);
+	lazy_hcall1(LHCALL_FLUSH_TLB, 0);
 }
 
 /* This is called when the kernel page tables have changed.  That's not very
@@ -547,7 +580,7 @@ static void lguest_flush_tlb_user(void)
  * slow), so it's worth separating this from the user flushing above. */
 static void lguest_flush_tlb_kernel(void)
 {
-	lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
+	lazy_hcall1(LHCALL_FLUSH_TLB, 1);
 }
 
 /*
@@ -631,7 +664,7 @@ static unsigned long lguest_tsc_khz(void
 
 /* If we can't use the TSC, the kernel falls back to our lower-priority
  * "lguest_clock", where we read the time value given to us by the Host. */
-static cycle_t lguest_clock_read(void)
+static cycle_t lguest_clock_read(struct clocksource *cs)
 {
 	unsigned long sec, nsec;
 
@@ -684,7 +717,7 @@ static int lguest_clockevent_set_next_ev
 	}
 
 	/* Please wake us this far in the future. */
-	hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0);
+	kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
 	return 0;
 }
 
@@ -695,7 +728,7 @@ static void lguest_clockevent_set_mode(e
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		/* A 0 argument shuts the clock down. */
-		hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0);
+		kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* This is what we expect. */
@@ -770,8 +803,8 @@ static void lguest_time_init(void)
 static void lguest_load_sp0(struct tss_struct *tss,
 			    struct thread_struct *thread)
 {
-	lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0,
-		   THREAD_SIZE/PAGE_SIZE);
+	lazy_hcall3(LHCALL_SET_STACK, __KERNEL_DS | 0x1, thread->sp0,
+		   THREAD_SIZE / PAGE_SIZE);
 }
 
 /* Let's just say, I wouldn't do debugging under a Guest. */
@@ -830,20 +863,21 @@ static u32 lguest_apic_safe_wait_icr_idl
 	return 0;
 }
 
-static struct apic_ops lguest_basic_apic_ops = {
-	.read = lguest_apic_read,
-	.write = lguest_apic_write,
-	.icr_read = lguest_apic_icr_read,
-	.icr_write = lguest_apic_icr_write,
-	.wait_icr_idle = lguest_apic_wait_icr_idle,
-	.safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle,
+static void set_lguest_basic_apic_ops(void)
+{
+	apic->read = lguest_apic_read;
+	apic->write = lguest_apic_write;
+	apic->icr_read = lguest_apic_icr_read;
+	apic->icr_write = lguest_apic_icr_write;
+	apic->wait_icr_idle = lguest_apic_wait_icr_idle;
+	apic->safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle;
 };
 #endif
 
 /* STOP!  Until an interrupt comes in. */
 static void lguest_safe_halt(void)
 {
-	hcall(LHCALL_HALT, 0, 0, 0);
+	kvm_hypercall0(LHCALL_HALT);
 }
 
 /* The SHUTDOWN hypercall takes a string to describe what's happening, and
@@ -853,7 +887,8 @@ static void lguest_safe_halt(void)
  * rather than virtual addresses, so we use __pa() here. */
 static void lguest_power_off(void)
 {
-	hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0);
+	kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
+					LGUEST_SHUTDOWN_POWEROFF);
 }
 
 /*
@@ -863,7 +898,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-	hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0);
+	kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
 	/* The hcall won't return, but to keep gcc happy, we're "done". */
 	return NOTIFY_DONE;
 }
@@ -904,7 +939,7 @@ static __init int early_put_chars(u32 vt
 		len = sizeof(scratch) - 1;
 	scratch[len] = '\0';
 	memcpy(scratch, buf, len);
-	hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0);
+	kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
 
 	/* This routine returns the number of bytes actually written. */
 	return len;
@@ -914,7 +949,7 @@ static __init int early_put_chars(u32 vt
  * Launcher to reboot us. */
 static void lguest_restart(char *reason)
 {
-	hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
+	kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
 }
 
 /*G:050
@@ -991,10 +1026,10 @@ __init void lguest_init(void)
 
 	/* interrupt-related operations */
 	pv_irq_ops.init_IRQ = lguest_init_IRQ;
-	pv_irq_ops.save_fl = save_fl;
-	pv_irq_ops.restore_fl = restore_fl;
-	pv_irq_ops.irq_disable = irq_disable;
-	pv_irq_ops.irq_enable = irq_enable;
+	pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
+	pv_irq_ops.restore_fl = PV_CALLEE_SAVE(restore_fl);
+	pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
+	pv_irq_ops.irq_enable = PV_CALLEE_SAVE(irq_enable);
 	pv_irq_ops.safe_halt = lguest_safe_halt;
 
 	/* init-time operations */
@@ -1034,10 +1069,12 @@ __init void lguest_init(void)
 	pv_mmu_ops.read_cr3 = lguest_read_cr3;
 	pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
 	pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
+	pv_mmu_ops.pte_update = lguest_pte_update;
+	pv_mmu_ops.pte_update_defer = lguest_pte_update;
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	/* apic read/write intercepts */
-	apic_ops = &lguest_basic_apic_ops;
+	set_lguest_basic_apic_ops();
 #endif
 
 	/* time operations */
@@ -1052,21 +1089,21 @@ __init void lguest_init(void)
 	 * lguest_init() where the rest of the fairly chaotic boot setup
 	 * occurs. */
 
-	/* The native boot code sets up initial page tables immediately after
-	 * the kernel itself, and sets init_pg_tables_end so they're not
-	 * clobbered.  The Launcher places our initial pagetables somewhere at
-	 * the top of our physical memory, so we don't need extra space: set
-	 * init_pg_tables_end to the end of the kernel. */
-	init_pg_tables_start = __pa(pg0);
-	init_pg_tables_end = __pa(pg0);
+	/* The stack protector is a weird thing where gcc places a canary
+	 * value on the stack and then checks it on return.  This file is
+	 * compiled with -fno-stack-protector it, so we got this far without
+	 * problems.  The value of the canary is kept at offset 20 from the
+	 * %gs register, so we need to set that up before calling C functions
+	 * in other files. */
+	setup_stack_canary_segment(0);
+	/* We could just call load_stack_canary_segment(), but we might as
+	 * call switch_to_new_gdt() which loads the whole table and sets up
+	 * the per-cpu segment descriptor register %fs as well. */
+	switch_to_new_gdt(0);
 
 	/* As described in head_32.S, we map the first 128M of memory. */
 	max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
 
-	/* Load the %fs segment register (the per-cpu segment register) with
-	 * the normal data segment to get through booting. */
-	asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
-
 	/* The Host<->Guest Switcher lives at the top of our address space, and
 	 * the Host told us how big it is when we made LGUEST_INIT hypercall:
 	 * it put the answer in lguest_data.reserve_mem  */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lguest/i386_head.S linux-libre-2.6.30-gnu1/arch/x86/lguest/i386_head.S
--- linux-libre-2.6.29-gnu1/arch/x86/lguest/i386_head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lguest/i386_head.S	2009-06-09 23:05:27.000000000 -0400
@@ -27,8 +27,8 @@ ENTRY(lguest_entry)
 	/* We make the "initialization" hypercall now to tell the Host about
 	 * us, and also find out where it put our page tables. */
 	movl $LHCALL_LGUEST_INIT, %eax
-	movl $lguest_data - __PAGE_OFFSET, %edx
-	int $LGUEST_TRAP_ENTRY
+	movl $lguest_data - __PAGE_OFFSET, %ebx
+	.byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
 
 	/* Set up the initial stack so we can run C code. */
 	movl $(init_thread_union+THREAD_SIZE),%esp
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lguest/Kconfig linux-libre-2.6.30-gnu1/arch/x86/lguest/Kconfig
--- linux-libre-2.6.29-gnu1/arch/x86/lguest/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lguest/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,6 @@ config LGUEST_GUEST
 	select PARAVIRT
 	depends on X86_32
 	depends on !X86_PAE
-	depends on !X86_VOYAGER
 	select VIRTIO
 	select VIRTIO_RING
 	select VIRTIO_CONSOLE
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lguest/Makefile linux-libre-2.6.30-gnu1/arch/x86/lguest/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/lguest/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lguest/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1 +1,2 @@
 obj-y		:= i386_head.o boot.o
+CFLAGS_boot.o	:= $(call cc-option, -fno-stack-protector)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lib/getuser.S linux-libre-2.6.30-gnu1/arch/x86/lib/getuser.S
--- linux-libre-2.6.29-gnu1/arch/x86/lib/getuser.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lib/getuser.S	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@
 
 #include <linux/linkage.h>
 #include <asm/dwarf2.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/errno.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/lib/memcpy_64.S linux-libre-2.6.30-gnu1/arch/x86/lib/memcpy_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/lib/memcpy_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/lib/memcpy_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,30 +1,38 @@
 /* Copyright 2002 Andi Kleen */
 
 #include <linux/linkage.h>
-#include <asm/dwarf2.h>
+
 #include <asm/cpufeature.h>
+#include <asm/dwarf2.h>
 
 /*
  * memcpy - Copy a memory block.
  *
- * Input:	
- * rdi destination
- * rsi source
- * rdx count
- * 
+ * Input:
+ *  rdi destination
+ *  rsi source
+ *  rdx count
+ *
  * Output:
  * rax original destination
- */	
+ */
 
+/*
+ * memcpy_c() - fast string ops (REP MOVSQ) based variant.
+ *
+ * Calls to this get patched into the kernel image via the
+ * alternative instructions framework:
+ */
 	ALIGN
 memcpy_c:
 	CFI_STARTPROC
-	movq %rdi,%rax
-	movl %edx,%ecx
-	shrl $3,%ecx
-	andl $7,%edx
+	movq %rdi, %rax
+
+	movl %edx, %ecx
+	shrl $3, %ecx
+	andl $7, %edx
 	rep movsq
-	movl %edx,%ecx
+	movl %edx, %ecx
 	rep movsb
 	ret
 	CFI_ENDPROC
@@ -33,99 +41,110 @@ ENDPROC(memcpy_c)
 ENTRY(__memcpy)
 ENTRY(memcpy)
 	CFI_STARTPROC
-	pushq %rbx
-	CFI_ADJUST_CFA_OFFSET 8
-	CFI_REL_OFFSET rbx, 0
-	movq %rdi,%rax
 
-	movl %edx,%ecx
-	shrl $6,%ecx
+	/*
+	 * Put the number of full 64-byte blocks into %ecx.
+	 * Tail portion is handled at the end:
+	 */
+	movq %rdi, %rax
+	movl %edx, %ecx
+	shrl   $6, %ecx
 	jz .Lhandle_tail
 
 	.p2align 4
 .Lloop_64:
+	/*
+	 * We decrement the loop index here - and the zero-flag is
+	 * checked at the end of the loop (instructions inbetween do
+	 * not change the zero flag):
+	 */
 	decl %ecx
 
-	movq (%rsi),%r11
-	movq 8(%rsi),%r8
-
-	movq %r11,(%rdi)
-	movq %r8,1*8(%rdi)
-
-	movq 2*8(%rsi),%r9
-	movq 3*8(%rsi),%r10
-
-	movq %r9,2*8(%rdi)
-	movq %r10,3*8(%rdi)
+	/*
+	 * Move in blocks of 4x16 bytes:
+	 */
+	movq 0*8(%rsi),		%r11
+	movq 1*8(%rsi),		%r8
+	movq %r11,		0*8(%rdi)
+	movq %r8,		1*8(%rdi)
 
-	movq 4*8(%rsi),%r11
-	movq 5*8(%rsi),%r8
+	movq 2*8(%rsi),		%r9
+	movq 3*8(%rsi),		%r10
+	movq %r9,		2*8(%rdi)
+	movq %r10,		3*8(%rdi)
 
-	movq %r11,4*8(%rdi)
-	movq %r8,5*8(%rdi)
+	movq 4*8(%rsi),		%r11
+	movq 5*8(%rsi),		%r8
+	movq %r11,		4*8(%rdi)
+	movq %r8,		5*8(%rdi)
 
-	movq 6*8(%rsi),%r9
-	movq 7*8(%rsi),%r10
+	movq 6*8(%rsi),		%r9
+	movq 7*8(%rsi),		%r10
+	movq %r9,		6*8(%rdi)
+	movq %r10,		7*8(%rdi)
 
-	movq %r9,6*8(%rdi)
-	movq %r10,7*8(%rdi)
+	leaq 64(%rsi), %rsi
+	leaq 64(%rdi), %rdi
 
-	leaq 64(%rsi),%rsi
-	leaq 64(%rdi),%rdi
 	jnz  .Lloop_64
 
 .Lhandle_tail:
-	movl %edx,%ecx
-	andl $63,%ecx
-	shrl $3,%ecx
+	movl %edx, %ecx
+	andl  $63, %ecx
+	shrl   $3, %ecx
 	jz   .Lhandle_7
+
 	.p2align 4
 .Lloop_8:
 	decl %ecx
-	movq (%rsi),%r8
-	movq %r8,(%rdi)
-	leaq 8(%rdi),%rdi
-	leaq 8(%rsi),%rsi
+	movq (%rsi),		%r8
+	movq %r8,		(%rdi)
+	leaq 8(%rdi),		%rdi
+	leaq 8(%rsi),		%rsi
 	jnz  .Lloop_8
 
 .Lhandle_7:
-	movl %edx,%ecx
-	andl $7,%ecx
-	jz .Lende
+	movl %edx, %ecx
+	andl $7, %ecx
+	jz .Lend
+
 	.p2align 4
 .Lloop_1:
-	movb (%rsi),%r8b
-	movb %r8b,(%rdi)
+	movb (%rsi), %r8b
+	movb %r8b, (%rdi)
 	incq %rdi
 	incq %rsi
 	decl %ecx
 	jnz .Lloop_1
 
-.Lende:
-	popq %rbx
-	CFI_ADJUST_CFA_OFFSET -8
-	CFI_RESTORE rbx
+.Lend:
 	ret
-.Lfinal:
 	CFI_ENDPROC
 ENDPROC(memcpy)
 ENDPROC(__memcpy)
 
-	/* Some CPUs run faster using the string copy instructions.
-	   It is also a lot simpler. Use this when possible */
+	/*
+	 * Some CPUs run faster using the string copy instructions.
+	 * It is also a lot simpler. Use this when possible:
+	 */
 
-	.section .altinstr_replacement,"ax"
+	.section .altinstr_replacement, "ax"
 1:	.byte 0xeb				/* jmp <disp8> */
 	.byte (memcpy_c - memcpy) - (2f - 1b)	/* offset */
 2:
 	.previous
-	.section .altinstructions,"a"
+
+	.section .altinstructions, "a"
 	.align 8
 	.quad memcpy
 	.quad 1b
 	.byte X86_FEATURE_REP_GOOD
-	/* Replace only beginning, memcpy is used to apply alternatives, so it
-	 * is silly to overwrite itself with nops - reboot is only outcome... */
+
+	/*
+	 * Replace only beginning, memcpy is used to apply alternatives,
+	 * so it is silly to overwrite itself with nops - reboot is the
+	 * only outcome...
+	 */
 	.byte 2b - 1b
 	.byte 2b - 1b
 	.previous
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-default/Makefile linux-libre-2.6.30-gnu1/arch/x86/mach-default/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/mach-default/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-default/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-obj-y				:= setup.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-default/setup.c linux-libre-2.6.30-gnu1/arch/x86/mach-default/setup.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-default/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-default/setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,174 +0,0 @@
-/*
- *	Machine specific setup for generic
- */
-
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/acpi.h>
-#include <asm/arch_hooks.h>
-#include <asm/e820.h>
-#include <asm/setup.h>
-
-#include <mach_ipi.h>
-
-#ifdef CONFIG_HOTPLUG_CPU
-#define DEFAULT_SEND_IPI	(1)
-#else
-#define DEFAULT_SEND_IPI	(0)
-#endif
-
-int no_broadcast = DEFAULT_SEND_IPI;
-
-/**
- * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
- *
- * Description:
- *	Perform any necessary interrupt initialisation prior to setting up
- *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
- *	interrupts should be initialised here if the machine emulates a PC
- *	in any way.
- **/
-void __init pre_intr_init_hook(void)
-{
-	if (x86_quirks->arch_pre_intr_init) {
-		if (x86_quirks->arch_pre_intr_init())
-			return;
-	}
-	init_ISA_irqs();
-}
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = {
-	.handler = no_action,
-	.mask = CPU_MASK_NONE,
-	.name = "cascade",
-};
-
-/**
- * intr_init_hook - post gate setup interrupt initialisation
- *
- * Description:
- *	Fill in any interrupts that may have been left out by the general
- *	init_IRQ() routine.  interrupts having to do with the machine rather
- *	than the devices on the I/O bus (like APIC interrupts in intel MP
- *	systems) are started here.
- **/
-void __init intr_init_hook(void)
-{
-	if (x86_quirks->arch_intr_init) {
-		if (x86_quirks->arch_intr_init())
-			return;
-	}
-	if (!acpi_ioapic)
-		setup_irq(2, &irq2);
-
-}
-
-/**
- * pre_setup_arch_hook - hook called prior to any setup_arch() execution
- *
- * Description:
- *	generally used to activate any machine specific identification
- *	routines that may be needed before setup_arch() runs.  On Voyager
- *	this is used to get the board revision and type.
- **/
-void __init pre_setup_arch_hook(void)
-{
-}
-
-/**
- * trap_init_hook - initialise system specific traps
- *
- * Description:
- *	Called as the final act of trap_init().  Used in VISWS to initialise
- *	the various board specific APIC traps.
- **/
-void __init trap_init_hook(void)
-{
-	if (x86_quirks->arch_trap_init) {
-		if (x86_quirks->arch_trap_init())
-			return;
-	}
-}
-
-static struct irqaction irq0  = {
-	.handler = timer_interrupt,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
-	.mask = CPU_MASK_NONE,
-	.name = "timer"
-};
-
-/**
- * pre_time_init_hook - do any specific initialisations before.
- *
- **/
-void __init pre_time_init_hook(void)
-{
-	if (x86_quirks->arch_pre_time_init)
-		x86_quirks->arch_pre_time_init();
-}
-
-/**
- * time_init_hook - do any specific initialisations for the system timer.
- *
- * Description:
- *	Must plug the system timer interrupt source at HZ into the IRQ listed
- *	in irq_vectors.h:TIMER_IRQ
- **/
-void __init time_init_hook(void)
-{
-	if (x86_quirks->arch_time_init) {
-		/*
-		 * A nonzero return code does not mean failure, it means
-		 * that the architecture quirk does not want any
-		 * generic (timer) setup to be performed after this:
-		 */
-		if (x86_quirks->arch_time_init())
-			return;
-	}
-
-	irq0.mask = cpumask_of_cpu(0);
-	setup_irq(0, &irq0);
-}
-
-#ifdef CONFIG_MCA
-/**
- * mca_nmi_hook - hook into MCA specific NMI chain
- *
- * Description:
- *	The MCA (Microchannel Architecture) has an NMI chain for NMI sources
- *	along the MCA bus.  Use this to hook into that chain if you will need
- *	it.
- **/
-void mca_nmi_hook(void)
-{
-	/*
-	 * If I recall correctly, there's a whole bunch of other things that
-	 * we can do to check for NMI problems, but that's all I know about
-	 * at the moment.
-	 */
-	pr_warning("NMI generated from unknown source!\n");
-}
-#endif
-
-static __init int no_ipi_broadcast(char *str)
-{
-	get_option(&str, &no_broadcast);
-	pr_info("Using %s mode\n",
-		no_broadcast ? "No IPI Broadcast" : "IPI Broadcast");
-	return 1;
-}
-__setup("no_ipi_broadcast=", no_ipi_broadcast);
-
-static int __init print_ipi_mode(void)
-{
-	pr_info("Using IPI %s mode\n",
-		no_broadcast ? "No-Shortcut" : "Shortcut");
-	return 0;
-}
-
-late_initcall(print_ipi_mode);
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/bigsmp.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/bigsmp.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/bigsmp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/bigsmp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/*
- * APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs.
- * Drives the local APIC in "clustered mode".
- */
-#define APIC_DEFINITION 1
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/genapic.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/dmi.h>
-#include <asm/bigsmp/apicdef.h>
-#include <linux/smp.h>
-#include <asm/bigsmp/apic.h>
-#include <asm/bigsmp/ipi.h>
-#include <asm/mach-default/mach_mpparse.h>
-#include <asm/mach-default/mach_wakecpu.h>
-
-static int dmi_bigsmp; /* can be set by dmi scanners */
-
-static int hp_ht_bigsmp(const struct dmi_system_id *d)
-{
-	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
-	dmi_bigsmp = 1;
-	return 0;
-}
-
-
-static const struct dmi_system_id bigsmp_dmi_table[] = {
-	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
-	{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-	DMI_MATCH(DMI_BIOS_VERSION, "P44-"),}
-	},
-
-	{ hp_ht_bigsmp, "HP ProLiant DL740",
-	{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-	DMI_MATCH(DMI_BIOS_VERSION, "P47-"),}
-	},
-	 { }
-};
-
-static void vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-	cpus_clear(*retmask);
-	cpu_set(cpu, *retmask);
-}
-
-static int probe_bigsmp(void)
-{
-	if (def_to_bigsmp)
-		dmi_bigsmp = 1;
-	else
-		dmi_check_system(bigsmp_dmi_table);
-	return dmi_bigsmp;
-}
-
-struct genapic apic_bigsmp = APIC_INIT("bigsmp", probe_bigsmp);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/default.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/default.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/default.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/default.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/*
- * Default generic APIC driver. This handles up to 8 CPUs.
- */
-#define APIC_DEFINITION 1
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/mach-default/mach_apicdef.h>
-#include <asm/genapic.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <asm/mach-default/mach_apic.h>
-#include <asm/mach-default/mach_ipi.h>
-#include <asm/mach-default/mach_mpparse.h>
-#include <asm/mach-default/mach_wakecpu.h>
-
-/* should be called last. */
-static int probe_default(void)
-{
-	return 1;
-}
-
-struct genapic apic_default = APIC_INIT("default", probe_default);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/es7000.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/es7000.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/es7000.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/es7000.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,103 +0,0 @@
-/*
- * APIC driver for the Unisys ES7000 chipset.
- */
-#define APIC_DEFINITION 1
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/genapic.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <asm/es7000/apicdef.h>
-#include <linux/smp.h>
-#include <asm/es7000/apic.h>
-#include <asm/es7000/ipi.h>
-#include <asm/es7000/mpparse.h>
-#include <asm/mach-default/mach_wakecpu.h>
-
-void __init es7000_update_genapic_to_cluster(void)
-{
-	genapic->target_cpus = target_cpus_cluster;
-	genapic->int_delivery_mode = INT_DELIVERY_MODE_CLUSTER;
-	genapic->int_dest_mode = INT_DEST_MODE_CLUSTER;
-	genapic->no_balance_irq = NO_BALANCE_IRQ_CLUSTER;
-
-	genapic->init_apic_ldr = init_apic_ldr_cluster;
-
-	genapic->cpu_mask_to_apicid = cpu_mask_to_apicid_cluster;
-}
-
-static int probe_es7000(void)
-{
-	/* probed later in mptable/ACPI hooks */
-	return 0;
-}
-
-extern void es7000_sw_apic(void);
-static void __init enable_apic_mode(void)
-{
-	es7000_sw_apic();
-	return;
-}
-
-static __init int
-mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-	if (mpc->oemptr) {
-		struct mpc_oemtable *oem_table =
-			(struct mpc_oemtable *)mpc->oemptr;
-		if (!strncmp(oem, "UNISYS", 6))
-			return parse_unisys_oem((char *)oem_table);
-	}
-	return 0;
-}
-
-#ifdef CONFIG_ACPI
-/* Hook from generic ACPI tables.c */
-static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	unsigned long oem_addr = 0;
-	int check_dsdt;
-	int ret = 0;
-
-	/* check dsdt at first to avoid clear fix_map for oem_addr */
-	check_dsdt = es7000_check_dsdt();
-
-	if (!find_unisys_acpi_oem_table(&oem_addr)) {
-		if (check_dsdt)
-			ret = parse_unisys_oem((char *)oem_addr);
-		else {
-			setup_unisys();
-			ret = 1;
-		}
-		/*
-		 * we need to unmap it
-		 */
-		unmap_unisys_acpi_oem_table(oem_addr);
-	}
-	return ret;
-}
-#else
-static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	return 0;
-}
-#endif
-
-static void vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-	/* Careful. Some cpus do not strictly honor the set of cpus
-	 * specified in the interrupt destination when using lowest
-	 * priority interrupt delivery mode.
-	 *
-	 * In particular there was a hyperthreading cpu observed to
-	 * deliver interrupts to the wrong hyperthread when only one
-	 * hyperthread was specified in the interrupt desitination.
-	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-struct genapic __initdata_refok apic_es7000 = APIC_INIT("es7000", probe_es7000);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/Makefile linux-libre-2.6.30-gnu1/arch/x86/mach-generic/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#
-# Makefile for the generic architecture
-#
-
-EXTRA_CFLAGS			:= -Iarch/x86/kernel
-
-obj-y				:= probe.o default.o
-obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
-obj-$(CONFIG_X86_SUMMIT)	+= summit.o
-obj-$(CONFIG_X86_BIGSMP)	+= bigsmp.o
-obj-$(CONFIG_X86_ES7000)	+= es7000.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/numaq.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/numaq.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/numaq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/numaq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/*
- * APIC driver for the IBM NUMAQ chipset.
- */
-#define APIC_DEFINITION 1
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/genapic.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <asm/numaq/apicdef.h>
-#include <linux/smp.h>
-#include <asm/numaq/apic.h>
-#include <asm/numaq/ipi.h>
-#include <asm/numaq/mpparse.h>
-#include <asm/numaq/wakecpu.h>
-#include <asm/numaq.h>
-
-static int mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-	numaq_mps_oem_check(mpc, oem, productid);
-	return found_numaq;
-}
-
-static int probe_numaq(void)
-{
-	/* already know from get_memcfg_numaq() */
-	return found_numaq;
-}
-
-/* Hook from generic ACPI tables.c */
-static int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	return 0;
-}
-
-static void vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-	/* Careful. Some cpus do not strictly honor the set of cpus
-	 * specified in the interrupt destination when using lowest
-	 * priority interrupt delivery mode.
-	 *
-	 * In particular there was a hyperthreading cpu observed to
-	 * deliver interrupts to the wrong hyperthread when only one
-	 * hyperthread was specified in the interrupt desitination.
-	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-struct genapic apic_numaq = APIC_INIT("NUMAQ", probe_numaq);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/probe.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/probe.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/probe.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,152 +0,0 @@
-/*
- * Copyright 2003 Andi Kleen, SuSE Labs.
- * Subject to the GNU Public License, v.2
- *
- * Generic x86 APIC driver probe layer.
- */
-#include <linux/threads.h>
-#include <linux/cpumask.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/genapic.h>
-#include <asm/setup.h>
-
-extern struct genapic apic_numaq;
-extern struct genapic apic_summit;
-extern struct genapic apic_bigsmp;
-extern struct genapic apic_es7000;
-extern struct genapic apic_default;
-
-struct genapic *genapic = &apic_default;
-
-static struct genapic *apic_probe[] __initdata = {
-#ifdef CONFIG_X86_NUMAQ
-	&apic_numaq,
-#endif
-#ifdef CONFIG_X86_SUMMIT
-	&apic_summit,
-#endif
-#ifdef CONFIG_X86_BIGSMP
-	&apic_bigsmp,
-#endif
-#ifdef CONFIG_X86_ES7000
-	&apic_es7000,
-#endif
-	&apic_default,	/* must be last */
-	NULL,
-};
-
-static int cmdline_apic __initdata;
-static int __init parse_apic(char *arg)
-{
-	int i;
-
-	if (!arg)
-		return -EINVAL;
-
-	for (i = 0; apic_probe[i]; i++) {
-		if (!strcmp(apic_probe[i]->name, arg)) {
-			genapic = apic_probe[i];
-			cmdline_apic = 1;
-			return 0;
-		}
-	}
-
-	if (x86_quirks->update_genapic)
-		x86_quirks->update_genapic();
-
-	/* Parsed again by __setup for debug/verbose */
-	return 0;
-}
-early_param("apic", parse_apic);
-
-void __init generic_bigsmp_probe(void)
-{
-#ifdef CONFIG_X86_BIGSMP
-	/*
-	 * This routine is used to switch to bigsmp mode when
-	 * - There is no apic= option specified by the user
-	 * - generic_apic_probe() has chosen apic_default as the sub_arch
-	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
-	 */
-
-	if (!cmdline_apic && genapic == &apic_default) {
-		if (apic_bigsmp.probe()) {
-			genapic = &apic_bigsmp;
-			if (x86_quirks->update_genapic)
-				x86_quirks->update_genapic();
-			printk(KERN_INFO "Overriding APIC driver with %s\n",
-			       genapic->name);
-		}
-	}
-#endif
-}
-
-void __init generic_apic_probe(void)
-{
-	if (!cmdline_apic) {
-		int i;
-		for (i = 0; apic_probe[i]; i++) {
-			if (apic_probe[i]->probe()) {
-				genapic = apic_probe[i];
-				break;
-			}
-		}
-		/* Not visible without early console */
-		if (!apic_probe[i])
-			panic("Didn't find an APIC driver");
-
-		if (x86_quirks->update_genapic)
-			x86_quirks->update_genapic();
-	}
-	printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
-}
-
-/* These functions can switch the APIC even after the initial ->probe() */
-
-int __init mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-	int i;
-	for (i = 0; apic_probe[i]; ++i) {
-		if (apic_probe[i]->mps_oem_check(mpc, oem, productid)) {
-			if (!cmdline_apic) {
-				genapic = apic_probe[i];
-				if (x86_quirks->update_genapic)
-					x86_quirks->update_genapic();
-				printk(KERN_INFO "Switched to APIC driver `%s'.\n",
-				       genapic->name);
-			}
-			return 1;
-		}
-	}
-	return 0;
-}
-
-int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	int i;
-	for (i = 0; apic_probe[i]; ++i) {
-		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
-			if (!cmdline_apic) {
-				genapic = apic_probe[i];
-				if (x86_quirks->update_genapic)
-					x86_quirks->update_genapic();
-				printk(KERN_INFO "Switched to APIC driver `%s'.\n",
-				       genapic->name);
-			}
-			return 1;
-		}
-	}
-	return 0;
-}
-
-int hard_smp_processor_id(void)
-{
-	return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-generic/summit.c linux-libre-2.6.30-gnu1/arch/x86/mach-generic/summit.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-generic/summit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-generic/summit.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * APIC driver for the IBM "Summit" chipset.
- */
-#define APIC_DEFINITION 1
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/genapic.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <asm/summit/apicdef.h>
-#include <linux/smp.h>
-#include <asm/summit/apic.h>
-#include <asm/summit/ipi.h>
-#include <asm/summit/mpparse.h>
-#include <asm/mach-default/mach_wakecpu.h>
-
-static int probe_summit(void)
-{
-	/* probed later in mptable/ACPI hooks */
-	return 0;
-}
-
-static void vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-	/* Careful. Some cpus do not strictly honor the set of cpus
-	 * specified in the interrupt destination when using lowest
-	 * priority interrupt delivery mode.
-	 *
-	 * In particular there was a hyperthreading cpu observed to
-	 * deliver interrupts to the wrong hyperthread when only one
-	 * hyperthread was specified in the interrupt desitination.
-	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-struct genapic apic_summit = APIC_INIT("summit", probe_summit);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/gpio.c linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/gpio.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,194 +0,0 @@
-/*
- *  GPIO support for RDC SoC R3210/R8610
- *
- *  Copyright (C) 2007, Florian Fainelli <florian@openwrt.org>
- *  Copyright (C) 2008, Volker Weiss <dev@tintuc.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/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/module.h>
-
-#include <asm/gpio.h>
-#include <asm/mach-rdc321x/rdc321x_defs.h>
-
-
-/* spin lock to protect our private copy of GPIO data register plus
-   the access to PCI conf registers. */
-static DEFINE_SPINLOCK(gpio_lock);
-
-/* copy of GPIO data registers */
-static u32 gpio_data_reg1;
-static u32 gpio_data_reg2;
-
-static u32 gpio_request_data[2];
-
-
-static inline void rdc321x_conf_write(unsigned addr, u32 value)
-{
-	outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
-	outl(value, RDC3210_CFGREG_DATA);
-}
-
-static inline void rdc321x_conf_or(unsigned addr, u32 value)
-{
-	outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
-	value |= inl(RDC3210_CFGREG_DATA);
-	outl(value, RDC3210_CFGREG_DATA);
-}
-
-static inline u32 rdc321x_conf_read(unsigned addr)
-{
-	outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
-
-	return inl(RDC3210_CFGREG_DATA);
-}
-
-/* configure pin as GPIO */
-static void rdc321x_configure_gpio(unsigned gpio)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	rdc321x_conf_or(gpio < 32
-		? RDC321X_GPIO_CTRL_REG1 : RDC321X_GPIO_CTRL_REG2,
-		1 << (gpio & 0x1f));
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-
-/* initially setup the 2 copies of the gpio data registers.
-   This function must be called by the platform setup code. */
-void __init rdc321x_gpio_setup()
-{
-	/* this might not be, what others (BIOS, bootloader, etc.)
-	   wrote to these registers before, but it's a good guess. Still
-	   better than just using 0xffffffff. */
-
-	gpio_data_reg1 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG1);
-	gpio_data_reg2 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG2);
-}
-
-/* determine, if gpio number is valid */
-static inline int rdc321x_is_gpio(unsigned gpio)
-{
-	return gpio <= RDC321X_MAX_GPIO;
-}
-
-/* request GPIO */
-int rdc_gpio_request(unsigned gpio, const char *label)
-{
-	unsigned long flags;
-
-	if (!rdc321x_is_gpio(gpio))
-		return -EINVAL;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	if (gpio_request_data[(gpio & 0x20) ? 1 : 0] & (1 << (gpio & 0x1f)))
-		goto inuse;
-	gpio_request_data[(gpio & 0x20) ? 1 : 0] |= (1 << (gpio & 0x1f));
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return 0;
-inuse:
-	spin_unlock_irqrestore(&gpio_lock, flags);
-	return -EINVAL;
-}
-EXPORT_SYMBOL(rdc_gpio_request);
-
-/* release previously-claimed GPIO */
-void rdc_gpio_free(unsigned gpio)
-{
-	unsigned long flags;
-
-	if (!rdc321x_is_gpio(gpio))
-		return;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	gpio_request_data[(gpio & 0x20) ? 1 : 0] &= ~(1 << (gpio & 0x1f));
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-EXPORT_SYMBOL(rdc_gpio_free);
-
-/* read GPIO pin */
-int rdc_gpio_get_value(unsigned gpio)
-{
-	u32 reg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-	reg = rdc321x_conf_read(gpio < 32
-		? RDC321X_GPIO_DATA_REG1 : RDC321X_GPIO_DATA_REG2);
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return (1 << (gpio & 0x1f)) & reg ? 1 : 0;
-}
-EXPORT_SYMBOL(rdc_gpio_get_value);
-
-/* set GPIO pin to value */
-void rdc_gpio_set_value(unsigned gpio, int value)
-{
-	unsigned long flags;
-	u32 reg;
-
-	reg = 1 << (gpio & 0x1f);
-	if (gpio < 32) {
-		spin_lock_irqsave(&gpio_lock, flags);
-		if (value)
-			gpio_data_reg1 |= reg;
-		else
-			gpio_data_reg1 &= ~reg;
-		rdc321x_conf_write(RDC321X_GPIO_DATA_REG1, gpio_data_reg1);
-		spin_unlock_irqrestore(&gpio_lock, flags);
-	} else {
-		spin_lock_irqsave(&gpio_lock, flags);
-		if (value)
-			gpio_data_reg2 |= reg;
-		else
-			gpio_data_reg2 &= ~reg;
-		rdc321x_conf_write(RDC321X_GPIO_DATA_REG2, gpio_data_reg2);
-		spin_unlock_irqrestore(&gpio_lock, flags);
-	}
-}
-EXPORT_SYMBOL(rdc_gpio_set_value);
-
-/* configure GPIO pin as input */
-int rdc_gpio_direction_input(unsigned gpio)
-{
-	if (!rdc321x_is_gpio(gpio))
-		return -EINVAL;
-
-	rdc321x_configure_gpio(gpio);
-
-	return 0;
-}
-EXPORT_SYMBOL(rdc_gpio_direction_input);
-
-/* configure GPIO pin as output and set value */
-int rdc_gpio_direction_output(unsigned gpio, int value)
-{
-	if (!rdc321x_is_gpio(gpio))
-		return -EINVAL;
-
-	gpio_set_value(gpio, value);
-	rdc321x_configure_gpio(gpio);
-
-	return 0;
-}
-EXPORT_SYMBOL(rdc_gpio_direction_output);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/Makefile linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#
-# Makefile for the RDC321x specific parts of the kernel
-#
-obj-$(CONFIG_X86_RDC321X)        := gpio.o platform.o
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/platform.c linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/platform.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-rdc321x/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-rdc321x/platform.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-/*
- *  Generic RDC321x platform devices
- *
- *  Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the
- *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA  02110-1301, USA.
- *
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-
-#include <asm/gpio.h>
-
-/* LEDS */
-static struct gpio_led default_leds[] = {
-	{ .name = "rdc:dmz", .gpio = 1, },
-};
-
-static struct gpio_led_platform_data rdc321x_led_data = {
-	.num_leds = ARRAY_SIZE(default_leds),
-	.leds = default_leds,
-};
-
-static struct platform_device rdc321x_leds = {
-	.name = "leds-gpio",
-	.id = -1,
-	.dev = {
-		.platform_data = &rdc321x_led_data,
-	}
-};
-
-/* Watchdog */
-static struct platform_device rdc321x_wdt = {
-	.name = "rdc321x-wdt",
-	.id = -1,
-	.num_resources = 0,
-};
-
-static struct platform_device *rdc321x_devs[] = {
-	&rdc321x_leds,
-	&rdc321x_wdt
-};
-
-static int __init rdc_board_setup(void)
-{
-	rdc321x_gpio_setup();
-
-	return platform_add_devices(rdc321x_devs, ARRAY_SIZE(rdc321x_devs));
-}
-
-arch_initcall(rdc_board_setup);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/Makefile linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-EXTRA_CFLAGS	:= -Iarch/x86/kernel
-obj-y			:= setup.o voyager_basic.o voyager_thread.o
-
-obj-$(CONFIG_SMP)	+= voyager_smp.o voyager_cat.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/setup.c linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/setup.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,118 +0,0 @@
-/*
- *	Machine specific setup for generic
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/arch_hooks.h>
-#include <asm/voyager.h>
-#include <asm/e820.h>
-#include <asm/io.h>
-#include <asm/setup.h>
-
-void __init pre_intr_init_hook(void)
-{
-	init_ISA_irqs();
-}
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = {
-	.handler = no_action,
-	.mask = CPU_MASK_NONE,
-	.name = "cascade",
-};
-
-void __init intr_init_hook(void)
-{
-#ifdef CONFIG_SMP
-	voyager_smp_intr_init();
-#endif
-
-	setup_irq(2, &irq2);
-}
-
-static void voyager_disable_tsc(void)
-{
-	/* Voyagers run their CPUs from independent clocks, so disable
-	 * the TSC code because we can't sync them */
-	setup_clear_cpu_cap(X86_FEATURE_TSC);
-}
-
-void __init pre_setup_arch_hook(void)
-{
-	voyager_disable_tsc();
-}
-
-void __init pre_time_init_hook(void)
-{
-	voyager_disable_tsc();
-}
-
-void __init trap_init_hook(void)
-{
-}
-
-static struct irqaction irq0 = {
-	.handler = timer_interrupt,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
-	.mask = CPU_MASK_NONE,
-	.name = "timer"
-};
-
-void __init time_init_hook(void)
-{
-	irq0.mask = cpumask_of_cpu(safe_smp_processor_id());
-	setup_irq(0, &irq0);
-}
-
-/* Hook for machine specific memory setup. */
-
-char *__init machine_specific_memory_setup(void)
-{
-	char *who;
-	int new_nr;
-
-	who = "NOT VOYAGER";
-
-	if (voyager_level == 5) {
-		__u32 addr, length;
-		int i;
-
-		who = "Voyager-SUS";
-
-		e820.nr_map = 0;
-		for (i = 0; voyager_memory_detect(i, &addr, &length); i++) {
-			e820_add_region(addr, length, E820_RAM);
-		}
-		return who;
-	} else if (voyager_level == 4) {
-		__u32 tom;
-		__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
-		/* select the DINO config space */
-		outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT);
-		/* Read DINO top of memory register */
-		tom = ((inb(catbase + 0x4) & 0xf0) << 16)
-		    + ((inb(catbase + 0x5) & 0x7f) << 24);
-
-		if (inb(catbase) != VOYAGER_DINO) {
-			printk(KERN_ERR
-			       "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
-			tom = (boot_params.screen_info.ext_mem_k) << 10;
-		}
-		who = "Voyager-TOM";
-		e820_add_region(0, 0x9f000, E820_RAM);
-		/* map from 1M to top of memory */
-		e820_add_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024,
-				  E820_RAM);
-		/* FIXME: Should check the ASICs to see if I need to
-		 * take out the 8M window.  Just do it at the moment
-		 * */
-		e820_add_region(8 * 1024 * 1024, 8 * 1024 * 1024,
-				  E820_RESERVED);
-		return who;
-	}
-
-	return default_machine_specific_memory_setup();
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_basic.c linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_basic.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_basic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_basic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,317 +0,0 @@
-/* Copyright (C) 1999,2001 
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * This file contains all the voyager specific routines for getting
- * initialisation of the architecture to function.  For additional
- * features see:
- *
- *	voyager_cat.c - Voyager CAT bus interface
- *	voyager_smp.c - Voyager SMP hal (emulates linux smp.c)
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/sysrq.h>
-#include <linux/smp.h>
-#include <linux/nodemask.h>
-#include <asm/io.h>
-#include <asm/voyager.h>
-#include <asm/vic.h>
-#include <linux/pm.h>
-#include <asm/tlbflush.h>
-#include <asm/arch_hooks.h>
-#include <asm/i8253.h>
-
-/*
- * Power off function, if any
- */
-void (*pm_power_off) (void);
-EXPORT_SYMBOL(pm_power_off);
-
-int voyager_level = 0;
-
-struct voyager_SUS *voyager_SUS = NULL;
-
-#ifdef CONFIG_SMP
-static void voyager_dump(int dummy1, struct tty_struct *dummy3)
-{
-	/* get here via a sysrq */
-	voyager_smp_dump();
-}
-
-static struct sysrq_key_op sysrq_voyager_dump_op = {
-	.handler = voyager_dump,
-	.help_msg = "Voyager",
-	.action_msg = "Dump Voyager Status",
-};
-#endif
-
-void voyager_detect(struct voyager_bios_info *bios)
-{
-	if (bios->len != 0xff) {
-		int class = (bios->class_1 << 8)
-		    | (bios->class_2 & 0xff);
-
-		printk("Voyager System detected.\n"
-		       "        Class %x, Revision %d.%d\n",
-		       class, bios->major, bios->minor);
-		if (class == VOYAGER_LEVEL4)
-			voyager_level = 4;
-		else if (class < VOYAGER_LEVEL5_AND_ABOVE)
-			voyager_level = 3;
-		else
-			voyager_level = 5;
-		printk("        Architecture Level %d\n", voyager_level);
-		if (voyager_level < 4)
-			printk
-			    ("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
-		/* install the power off handler */
-		pm_power_off = voyager_power_off;
-#ifdef CONFIG_SMP
-		register_sysrq_key('v', &sysrq_voyager_dump_op);
-#endif
-	} else {
-		printk("\n\n**WARNING**: No Voyager Subsystem Found\n");
-	}
-}
-
-void voyager_system_interrupt(int cpl, void *dev_id)
-{
-	printk("Voyager: detected system interrupt\n");
-}
-
-/* Routine to read information from the extended CMOS area */
-__u8 voyager_extended_cmos_read(__u16 addr)
-{
-	outb(addr & 0xff, 0x74);
-	outb((addr >> 8) & 0xff, 0x75);
-	return inb(0x76);
-}
-
-/* internal definitions for the SUS Click Map of memory */
-
-#define CLICK_ENTRIES	16
-#define CLICK_SIZE	4096	/* click to byte conversion for Length */
-
-typedef struct ClickMap {
-	struct Entry {
-		__u32 Address;
-		__u32 Length;
-	} Entry[CLICK_ENTRIES];
-} ClickMap_t;
-
-/* This routine is pretty much an awful hack to read the bios clickmap by
- * mapping it into page 0.  There are usually three regions in the map:
- * 	Base Memory
- * 	Extended Memory
- *	zero length marker for end of map
- *
- * Returns are 0 for failure and 1 for success on extracting region.
- */
-int __init voyager_memory_detect(int region, __u32 * start, __u32 * length)
-{
-	int i;
-	int retval = 0;
-	__u8 cmos[4];
-	ClickMap_t *map;
-	unsigned long map_addr;
-	unsigned long old;
-
-	if (region >= CLICK_ENTRIES) {
-		printk("Voyager: Illegal ClickMap region %d\n", region);
-		return 0;
-	}
-
-	for (i = 0; i < sizeof(cmos); i++)
-		cmos[i] =
-		    voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
-
-	map_addr = *(unsigned long *)cmos;
-
-	/* steal page 0 for this */
-	old = pg0[0];
-	pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
-	local_flush_tlb();
-	/* now clear everything out but page 0 */
-	map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
-
-	/* zero length is the end of the clickmap */
-	if (map->Entry[region].Length != 0) {
-		*length = map->Entry[region].Length * CLICK_SIZE;
-		*start = map->Entry[region].Address;
-		retval = 1;
-	}
-
-	/* replace the mapping */
-	pg0[0] = old;
-	local_flush_tlb();
-	return retval;
-}
-
-/* voyager specific handling code for timer interrupts.  Used to hand
- * off the timer tick to the SMP code, since the VIC doesn't have an
- * internal timer (The QIC does, but that's another story). */
-void voyager_timer_interrupt(void)
-{
-	if ((jiffies & 0x3ff) == 0) {
-
-		/* There seems to be something flaky in either
-		 * hardware or software that is resetting the timer 0
-		 * count to something much higher than it should be
-		 * This seems to occur in the boot sequence, just
-		 * before root is mounted.  Therefore, every 10
-		 * seconds or so, we sanity check the timer zero count
-		 * and kick it back to where it should be.
-		 *
-		 * FIXME: This is the most awful hack yet seen.  I
-		 * should work out exactly what is interfering with
-		 * the timer count settings early in the boot sequence
-		 * and swiftly introduce it to something sharp and
-		 * pointy.  */
-		__u16 val;
-
-		spin_lock(&i8253_lock);
-
-		outb_p(0x00, 0x43);
-		val = inb_p(0x40);
-		val |= inb(0x40) << 8;
-		spin_unlock(&i8253_lock);
-
-		if (val > LATCH) {
-			printk
-			    ("\nVOYAGER: countdown timer value too high (%d), resetting\n\n",
-			     val);
-			spin_lock(&i8253_lock);
-			outb(0x34, 0x43);
-			outb_p(LATCH & 0xff, 0x40);	/* LSB */
-			outb(LATCH >> 8, 0x40);	/* MSB */
-			spin_unlock(&i8253_lock);
-		}
-	}
-#ifdef CONFIG_SMP
-	smp_vic_timer_interrupt();
-#endif
-}
-
-void voyager_power_off(void)
-{
-	printk("VOYAGER Power Off\n");
-
-	if (voyager_level == 5) {
-		voyager_cat_power_off();
-	} else if (voyager_level == 4) {
-		/* This doesn't apparently work on most L4 machines,
-		 * but the specs say to do this to get automatic power
-		 * off.  Unfortunately, if it doesn't power off the
-		 * machine, it ends up doing a cold restart, which
-		 * isn't really intended, so comment out the code */
-#if 0
-		int port;
-
-		/* enable the voyager Configuration Space */
-		outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, VOYAGER_MC_SETUP);
-		/* the port for the power off flag is an offset from the
-		   floating base */
-		port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
-		/* set the power off flag */
-		outb(inb(port) | 0x1, port);
-#endif
-	}
-	/* and wait for it to happen */
-	local_irq_disable();
-	for (;;)
-		halt();
-}
-
-/* copied from process.c */
-static inline void kb_wait(void)
-{
-	int i;
-
-	for (i = 0; i < 0x10000; i++)
-		if ((inb_p(0x64) & 0x02) == 0)
-			break;
-}
-
-void machine_shutdown(void)
-{
-	/* Architecture specific shutdown needed before a kexec */
-}
-
-void machine_restart(char *cmd)
-{
-	printk("Voyager Warm Restart\n");
-	kb_wait();
-
-	if (voyager_level == 5) {
-		/* write magic values to the RTC to inform system that
-		 * shutdown is beginning */
-		outb(0x8f, 0x70);
-		outb(0x5, 0x71);
-
-		udelay(50);
-		outb(0xfe, 0x64);	/* pull reset low */
-	} else if (voyager_level == 4) {
-		__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8;
-		__u8 basebd = inb(VOYAGER_MC_SETUP);
-
-		outb(basebd | 0x08, VOYAGER_MC_SETUP);
-		outb(0x02, catbase + 0x21);
-	}
-	local_irq_disable();
-	for (;;)
-		halt();
-}
-
-void machine_emergency_restart(void)
-{
-	/*for now, just hook this to a warm restart */
-	machine_restart(NULL);
-}
-
-void mca_nmi_hook(void)
-{
-	__u8 dumpval __maybe_unused = inb(0xf823);
-	__u8 swnmi __maybe_unused = inb(0xf813);
-
-	/* FIXME: assume dump switch pressed */
-	/* check to see if the dump switch was pressed */
-	VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi));
-	/* clear swnmi */
-	outb(0xff, 0xf813);
-	/* tell SUS to ignore dump */
-	if (voyager_level == 5 && voyager_SUS != NULL) {
-		if (voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
-			voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
-			voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
-			udelay(1000);
-			voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP;
-			voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
-		}
-	}
-	printk(KERN_ERR
-	       "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n",
-	       smp_processor_id());
-	show_stack(NULL, NULL);
-	show_state();
-}
-
-void machine_halt(void)
-{
-	/* treat a halt like a power off */
-	machine_power_off();
-}
-
-void machine_power_off(void)
-{
-	if (pm_power_off)
-		pm_power_off();
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_cat.c linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_cat.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_cat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_cat.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1197 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* Copyright (C) 1999,2001
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * This file contains all the logic for manipulating the CAT bus
- * in a level 5 machine.
- *
- * The CAT bus is a serial configuration and test bus.  Its primary
- * uses are to probe the initial configuration of the system and to
- * diagnose error conditions when a system interrupt occurs.  The low
- * level interface is fairly primitive, so most of this file consists
- * of bit shift manipulations to send and receive packets on the
- * serial bus */
-
-#include <linux/types.h>
-#include <linux/completion.h>
-#include <linux/sched.h>
-#include <asm/voyager.h>
-#include <asm/vic.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#ifdef VOYAGER_CAT_DEBUG
-#define CDEBUG(x)	printk x
-#else
-#define CDEBUG(x)
-#endif
-
-/* the CAT command port */
-#define CAT_CMD		(sspb + 0xe)
-/* the CAT data port */
-#define CAT_DATA	(sspb + 0xd)
-
-/* the internal cat functions */
-static void cat_pack(__u8 * msg, __u16 start_bit, __u8 * data, __u16 num_bits);
-static void cat_unpack(__u8 * msg, __u16 start_bit, __u8 * data,
-		       __u16 num_bits);
-static void cat_build_header(__u8 * header, const __u16 len,
-			     const __u16 smallest_reg_bits,
-			     const __u16 longest_reg_bits);
-static int cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp,
-			__u8 reg, __u8 op);
-static int cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp,
-		       __u8 reg, __u8 * value);
-static int cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes,
-			__u8 pad_bits);
-static int cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
-		     __u8 value);
-static int cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
-		    __u8 * value);
-static int cat_subread(voyager_module_t * modp, voyager_asic_t * asicp,
-		       __u16 offset, __u16 len, void *buf);
-static int cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
-			__u8 reg, __u8 value);
-static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp);
-static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp);
-
-static inline const char *cat_module_name(int module_id)
-{
-	switch (module_id) {
-	case 0x10:
-		return "Processor Slot 0";
-	case 0x11:
-		return "Processor Slot 1";
-	case 0x12:
-		return "Processor Slot 2";
-	case 0x13:
-		return "Processor Slot 4";
-	case 0x14:
-		return "Memory Slot 0";
-	case 0x15:
-		return "Memory Slot 1";
-	case 0x18:
-		return "Primary Microchannel";
-	case 0x19:
-		return "Secondary Microchannel";
-	case 0x1a:
-		return "Power Supply Interface";
-	case 0x1c:
-		return "Processor Slot 5";
-	case 0x1d:
-		return "Processor Slot 6";
-	case 0x1e:
-		return "Processor Slot 7";
-	case 0x1f:
-		return "Processor Slot 8";
-	default:
-		return "Unknown Module";
-	}
-}
-
-static int sspb = 0;		/* stores the super port location */
-int voyager_8slot = 0;		/* set to true if a 51xx monster */
-
-voyager_module_t *voyager_cat_list;
-
-/* the I/O port assignments for the VIC and QIC */
-static struct resource vic_res = {
-	.name = "Voyager Interrupt Controller",
-	.start = 0xFC00,
-	.end = 0xFC6F
-};
-static struct resource qic_res = {
-	.name = "Quad Interrupt Controller",
-	.start = 0xFC70,
-	.end = 0xFCFF
-};
-
-/* This function is used to pack a data bit stream inside a message.
- * It writes num_bits of the data buffer in msg starting at start_bit.
- * Note: This function assumes that any unused bit in the data stream
- * is set to zero so that the ors will work correctly */
-static void
-cat_pack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
-{
-	/* compute initial shift needed */
-	const __u16 offset = start_bit % BITS_PER_BYTE;
-	__u16 len = num_bits / BITS_PER_BYTE;
-	__u16 byte = start_bit / BITS_PER_BYTE;
-	__u16 residue = (num_bits % BITS_PER_BYTE) + offset;
-	int i;
-
-	/* adjust if we have more than a byte of residue */
-	if (residue >= BITS_PER_BYTE) {
-		residue -= BITS_PER_BYTE;
-		len++;
-	}
-
-	/* clear out the bits.  We assume here that if len==0 then
-	 * residue >= offset.  This is always true for the catbus
-	 * operations */
-	msg[byte] &= 0xff << (BITS_PER_BYTE - offset);
-	msg[byte++] |= data[0] >> offset;
-	if (len == 0)
-		return;
-	for (i = 1; i < len; i++)
-		msg[byte++] = (data[i - 1] << (BITS_PER_BYTE - offset))
-		    | (data[i] >> offset);
-	if (residue != 0) {
-		__u8 mask = 0xff >> residue;
-		__u8 last_byte = data[i - 1] << (BITS_PER_BYTE - offset)
-		    | (data[i] >> offset);
-
-		last_byte &= ~mask;
-		msg[byte] &= mask;
-		msg[byte] |= last_byte;
-	}
-	return;
-}
-
-/* unpack the data again (same arguments as cat_pack()). data buffer
- * must be zero populated.
- *
- * Function: given a message string move to start_bit and copy num_bits into
- * data (starting at bit 0 in data).
- */
-static void
-cat_unpack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits)
-{
-	/* compute initial shift needed */
-	const __u16 offset = start_bit % BITS_PER_BYTE;
-	__u16 len = num_bits / BITS_PER_BYTE;
-	const __u8 last_bits = num_bits % BITS_PER_BYTE;
-	__u16 byte = start_bit / BITS_PER_BYTE;
-	int i;
-
-	if (last_bits != 0)
-		len++;
-
-	/* special case: want < 8 bits from msg and we can get it from
-	 * a single byte of the msg */
-	if (len == 0 && BITS_PER_BYTE - offset >= num_bits) {
-		data[0] = msg[byte] << offset;
-		data[0] &= 0xff >> (BITS_PER_BYTE - num_bits);
-		return;
-	}
-	for (i = 0; i < len; i++) {
-		/* this annoying if has to be done just in case a read of
-		 * msg one beyond the array causes a panic */
-		if (offset != 0) {
-			data[i] = msg[byte++] << offset;
-			data[i] |= msg[byte] >> (BITS_PER_BYTE - offset);
-		} else {
-			data[i] = msg[byte++];
-		}
-	}
-	/* do we need to truncate the final byte */
-	if (last_bits != 0) {
-		data[i - 1] &= 0xff << (BITS_PER_BYTE - last_bits);
-	}
-	return;
-}
-
-static void
-cat_build_header(__u8 * header, const __u16 len, const __u16 smallest_reg_bits,
-		 const __u16 longest_reg_bits)
-{
-	int i;
-	__u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE;
-	__u8 *last_byte = &header[len - 1];
-
-	if (start_bit == 0)
-		start_bit = 1;	/* must have at least one bit in the hdr */
-
-	for (i = 0; i < len; i++)
-		header[i] = 0;
-
-	for (i = start_bit; i > 0; i--)
-		*last_byte = ((*last_byte) << 1) + 1;
-
-}
-
-static int
-cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 op)
-{
-	__u8 parity, inst, inst_buf[4] = { 0 };
-	__u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE];
-	__u16 ibytes, hbytes, padbits;
-	int i;
-
-	/* 
-	 * Parity is the parity of the register number + 1 (READ_REGISTER
-	 * and WRITE_REGISTER always add '1' to the number of bits == 1)
-	 */
-	parity = (__u8) (1 + (reg & 0x01) +
-			 ((__u8) (reg & 0x02) >> 1) +
-			 ((__u8) (reg & 0x04) >> 2) +
-			 ((__u8) (reg & 0x08) >> 3)) % 2;
-
-	inst = ((parity << 7) | (reg << 2) | op);
-
-	outb(VOYAGER_CAT_IRCYC, CAT_CMD);
-	if (!modp->scan_path_connected) {
-		if (asicp->asic_id != VOYAGER_CAT_ID) {
-			printk
-			    ("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n");
-			return 1;
-		}
-		outb(VOYAGER_CAT_HEADER, CAT_DATA);
-		outb(inst, CAT_DATA);
-		if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
-			CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n"));
-			return 1;
-		}
-		return 0;
-	}
-	ibytes = modp->inst_bits / BITS_PER_BYTE;
-	if ((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) {
-		padbits = BITS_PER_BYTE - padbits;
-		ibytes++;
-	}
-	hbytes = modp->largest_reg / BITS_PER_BYTE;
-	if (modp->largest_reg % BITS_PER_BYTE)
-		hbytes++;
-	CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes));
-	/* initialise the instruction sequence to 0xff */
-	for (i = 0; i < ibytes + hbytes; i++)
-		iseq[i] = 0xff;
-	cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg);
-	cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE);
-	inst_buf[0] = inst;
-	inst_buf[1] = 0xFF >> (modp->largest_reg % BITS_PER_BYTE);
-	cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length);
-#ifdef VOYAGER_CAT_DEBUG
-	printk("ins = 0x%x, iseq: ", inst);
-	for (i = 0; i < ibytes + hbytes; i++)
-		printk("0x%x ", iseq[i]);
-	printk("\n");
-#endif
-	if (cat_shiftout(iseq, ibytes, hbytes, padbits)) {
-		CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n"));
-		return 1;
-	}
-	CDEBUG(("CAT SHIFTOUT DONE\n"));
-	return 0;
-}
-
-static int
-cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
-	    __u8 * value)
-{
-	if (!modp->scan_path_connected) {
-		if (asicp->asic_id != VOYAGER_CAT_ID) {
-			CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n"));
-			return 1;
-		}
-		if (reg > VOYAGER_SUBADDRHI)
-			outb(VOYAGER_CAT_RUN, CAT_CMD);
-		outb(VOYAGER_CAT_DRCYC, CAT_CMD);
-		outb(VOYAGER_CAT_HEADER, CAT_DATA);
-		*value = inb(CAT_DATA);
-		outb(0xAA, CAT_DATA);
-		if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
-			CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n"));
-			return 1;
-		}
-		return 0;
-	} else {
-		__u16 sbits = modp->num_asics - 1 + asicp->ireg_length;
-		__u16 sbytes = sbits / BITS_PER_BYTE;
-		__u16 tbytes;
-		__u8 string[VOYAGER_MAX_SCAN_PATH],
-		    trailer[VOYAGER_MAX_REG_SIZE];
-		__u8 padbits;
-		int i;
-
-		outb(VOYAGER_CAT_DRCYC, CAT_CMD);
-
-		if ((padbits = sbits % BITS_PER_BYTE) != 0) {
-			padbits = BITS_PER_BYTE - padbits;
-			sbytes++;
-		}
-		tbytes = asicp->ireg_length / BITS_PER_BYTE;
-		if (asicp->ireg_length % BITS_PER_BYTE)
-			tbytes++;
-		CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n",
-			tbytes, sbytes, padbits));
-		cat_build_header(trailer, tbytes, 1, asicp->ireg_length);
-
-		for (i = tbytes - 1; i >= 0; i--) {
-			outb(trailer[i], CAT_DATA);
-			string[sbytes + i] = inb(CAT_DATA);
-		}
-
-		for (i = sbytes - 1; i >= 0; i--) {
-			outb(0xaa, CAT_DATA);
-			string[i] = inb(CAT_DATA);
-		}
-		*value = 0;
-		cat_unpack(string,
-			   padbits + (tbytes * BITS_PER_BYTE) +
-			   asicp->asic_location, value, asicp->ireg_length);
-#ifdef VOYAGER_CAT_DEBUG
-		printk("value=0x%x, string: ", *value);
-		for (i = 0; i < tbytes + sbytes; i++)
-			printk("0x%x ", string[i]);
-		printk("\n");
-#endif
-
-		/* sanity check the rest of the return */
-		for (i = 0; i < tbytes; i++) {
-			__u8 input = 0;
-
-			cat_unpack(string, padbits + (i * BITS_PER_BYTE),
-				   &input, BITS_PER_BYTE);
-			if (trailer[i] != input) {
-				CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i]));
-				return 1;
-			}
-		}
-		CDEBUG(("cat_getdata DONE\n"));
-		return 0;
-	}
-}
-
-static int
-cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits)
-{
-	int i;
-
-	for (i = data_bytes + header_bytes - 1; i >= header_bytes; i--)
-		outb(data[i], CAT_DATA);
-
-	for (i = header_bytes - 1; i >= 0; i--) {
-		__u8 header = 0;
-		__u8 input;
-
-		outb(data[i], CAT_DATA);
-		input = inb(CAT_DATA);
-		CDEBUG(("cat_shiftout: returned 0x%x\n", input));
-		cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits,
-			   &header, BITS_PER_BYTE);
-		if (input != header) {
-			CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header));
-			return 1;
-		}
-	}
-	return 0;
-}
-
-static int
-cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
-	     __u8 reg, __u8 value)
-{
-	outb(VOYAGER_CAT_DRCYC, CAT_CMD);
-	if (!modp->scan_path_connected) {
-		if (asicp->asic_id != VOYAGER_CAT_ID) {
-			CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n"));
-			return 1;
-		}
-		outb(VOYAGER_CAT_HEADER, CAT_DATA);
-		outb(value, CAT_DATA);
-		if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) {
-			CDEBUG(("cat_senddata: failed to get correct header response to sent data\n"));
-			return 1;
-		}
-		if (reg > VOYAGER_SUBADDRHI) {
-			outb(VOYAGER_CAT_RUN, CAT_CMD);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			outb(VOYAGER_CAT_RUN, CAT_CMD);
-		}
-
-		return 0;
-	} else {
-		__u16 hbytes = asicp->ireg_length / BITS_PER_BYTE;
-		__u16 dbytes =
-		    (modp->num_asics - 1 + asicp->ireg_length) / BITS_PER_BYTE;
-		__u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH],
-		    hseq[VOYAGER_MAX_REG_SIZE];
-		int i;
-
-		if ((padbits = (modp->num_asics - 1
-				+ asicp->ireg_length) % BITS_PER_BYTE) != 0) {
-			padbits = BITS_PER_BYTE - padbits;
-			dbytes++;
-		}
-		if (asicp->ireg_length % BITS_PER_BYTE)
-			hbytes++;
-
-		cat_build_header(hseq, hbytes, 1, asicp->ireg_length);
-
-		for (i = 0; i < dbytes + hbytes; i++)
-			dseq[i] = 0xff;
-		CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n",
-			dbytes, hbytes, padbits));
-		cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length,
-			 hseq, hbytes * BITS_PER_BYTE);
-		cat_pack(dseq, asicp->asic_location, &value,
-			 asicp->ireg_length);
-#ifdef VOYAGER_CAT_DEBUG
-		printk("dseq ");
-		for (i = 0; i < hbytes + dbytes; i++) {
-			printk("0x%x ", dseq[i]);
-		}
-		printk("\n");
-#endif
-		return cat_shiftout(dseq, dbytes, hbytes, padbits);
-	}
-}
-
-static int
-cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 value)
-{
-	if (cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG))
-		return 1;
-	return cat_senddata(modp, asicp, reg, value);
-}
-
-static int
-cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
-	 __u8 * value)
-{
-	if (cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG))
-		return 1;
-	return cat_getdata(modp, asicp, reg, value);
-}
-
-static int
-cat_subaddrsetup(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
-		 __u16 len)
-{
-	__u8 val;
-
-	if (len > 1) {
-		/* set auto increment */
-		__u8 newval;
-
-		if (cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) {
-			CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n"));
-			return 1;
-		}
-		CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n",
-			val));
-		newval = val | VOYAGER_AUTO_INC;
-		if (newval != val) {
-			if (cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) {
-				CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n"));
-				return 1;
-			}
-		}
-	}
-	if (cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8) (offset & 0xff))) {
-		CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n"));
-		return 1;
-	}
-	if (asicp->subaddr > VOYAGER_SUBADDR_LO) {
-		if (cat_write
-		    (modp, asicp, VOYAGER_SUBADDRHI, (__u8) (offset >> 8))) {
-			CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n"));
-			return 1;
-		}
-		cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val);
-		CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset,
-			val));
-	}
-	cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val);
-	CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val));
-	return 0;
-}
-
-static int
-cat_subwrite(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
-	     __u16 len, void *buf)
-{
-	int i, retval;
-
-	/* FIXME: need special actions for VOYAGER_CAT_ID here */
-	if (asicp->asic_id == VOYAGER_CAT_ID) {
-		CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n"));
-		/* FIXME -- This is supposed to be handled better
-		 * There is a problem writing to the cat asic in the
-		 * PSI.  The 30us delay seems to work, though */
-		udelay(30);
-	}
-
-	if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
-		printk("cat_subwrite: cat_subaddrsetup FAILED\n");
-		return retval;
-	}
-
-	if (cat_sendinst
-	    (modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) {
-		printk("cat_subwrite: cat_sendinst FAILED\n");
-		return 1;
-	}
-	for (i = 0; i < len; i++) {
-		if (cat_senddata(modp, asicp, 0xFF, ((__u8 *) buf)[i])) {
-			printk
-			    ("cat_subwrite: cat_sendata element at %d FAILED\n",
-			     i);
-			return 1;
-		}
-	}
-	return 0;
-}
-static int
-cat_subread(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset,
-	    __u16 len, void *buf)
-{
-	int i, retval;
-
-	if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) {
-		CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n"));
-		return retval;
-	}
-
-	if (cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) {
-		CDEBUG(("cat_subread: cat_sendinst failed\n"));
-		return 1;
-	}
-	for (i = 0; i < len; i++) {
-		if (cat_getdata(modp, asicp, 0xFF, &((__u8 *) buf)[i])) {
-			CDEBUG(("cat_subread: cat_getdata element %d failed\n",
-				i));
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/* buffer for storing EPROM data read in during initialisation */
-static __initdata __u8 eprom_buf[0xFFFF];
-static voyager_module_t *voyager_initial_module;
-
-/* Initialise the cat bus components.  We assume this is called by the
- * boot cpu *after* all memory initialisation has been done (so we can
- * use kmalloc) but before smp initialisation, so we can probe the SMP
- * configuration and pick up necessary information.  */
-void __init voyager_cat_init(void)
-{
-	voyager_module_t **modpp = &voyager_initial_module;
-	voyager_asic_t **asicpp;
-	voyager_asic_t *qabc_asic = NULL;
-	int i, j;
-	unsigned long qic_addr = 0;
-	__u8 qabc_data[0x20];
-	__u8 num_submodules, val;
-	voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *) & eprom_buf[0];
-
-	__u8 cmos[4];
-	unsigned long addr;
-
-	/* initiallise the SUS mailbox */
-	for (i = 0; i < sizeof(cmos); i++)
-		cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i);
-	addr = *(unsigned long *)cmos;
-	if ((addr & 0xff000000) != 0xff000000) {
-		printk(KERN_ERR
-		       "Voyager failed to get SUS mailbox (addr = 0x%lx\n",
-		       addr);
-	} else {
-		static struct resource res;
-
-		res.name = "voyager SUS";
-		res.start = addr;
-		res.end = addr + 0x3ff;
-
-		request_resource(&iomem_resource, &res);
-		voyager_SUS = (struct voyager_SUS *)
-		    ioremap(addr, 0x400);
-		printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n",
-		       voyager_SUS->SUS_version);
-		voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION;
-		voyager_SUS->kernel_flags = VOYAGER_OS_HAS_SYSINT;
-	}
-
-	/* clear the processor counts */
-	voyager_extended_vic_processors = 0;
-	voyager_quad_processors = 0;
-
-	printk("VOYAGER: beginning CAT bus probe\n");
-	/* set up the SuperSet Port Block which tells us where the
-	 * CAT communication port is */
-	sspb = inb(VOYAGER_SSPB_RELOCATION_PORT) * 0x100;
-	VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb));
-
-	/* now find out if were 8 slot or normal */
-	if ((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER)
-	    == EIGHT_SLOT_IDENTIFIER) {
-		voyager_8slot = 1;
-		printk(KERN_NOTICE
-		       "Voyager: Eight slot 51xx configuration detected\n");
-	}
-
-	for (i = VOYAGER_MIN_MODULE; i <= VOYAGER_MAX_MODULE; i++) {
-		__u8 input;
-		int asic;
-		__u16 eprom_size;
-		__u16 sp_offset;
-
-		outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
-		outb(i, VOYAGER_CAT_CONFIG_PORT);
-
-		/* check the presence of the module */
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		outb(VOYAGER_CAT_IRCYC, CAT_CMD);
-		outb(VOYAGER_CAT_HEADER, CAT_DATA);
-		/* stream series of alternating 1's and 0's to stimulate
-		 * response */
-		outb(0xAA, CAT_DATA);
-		input = inb(CAT_DATA);
-		outb(VOYAGER_CAT_END, CAT_CMD);
-		if (input != VOYAGER_CAT_HEADER) {
-			continue;
-		}
-		CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i,
-			cat_module_name(i)));
-		*modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL);	/*&voyager_module_storage[cat_count++]; */
-		if (*modpp == NULL) {
-			printk("**WARNING** kmalloc failure in cat_init\n");
-			continue;
-		}
-		memset(*modpp, 0, sizeof(voyager_module_t));
-		/* need temporary asic for cat_subread.  It will be
-		 * filled in correctly later */
-		(*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL);	/*&voyager_asic_storage[asic_count]; */
-		if ((*modpp)->asic == NULL) {
-			printk("**WARNING** kmalloc failure in cat_init\n");
-			continue;
-		}
-		memset((*modpp)->asic, 0, sizeof(voyager_asic_t));
-		(*modpp)->asic->asic_id = VOYAGER_CAT_ID;
-		(*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI;
-		(*modpp)->module_addr = i;
-		(*modpp)->scan_path_connected = 0;
-		if (i == VOYAGER_PSI) {
-			/* Exception leg for modules with no EEPROM */
-			printk("Module \"%s\"\n", cat_module_name(i));
-			continue;
-		}
-
-		CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		cat_disconnect(*modpp, (*modpp)->asic);
-		if (cat_subread(*modpp, (*modpp)->asic,
-				VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
-				&eprom_size)) {
-			printk
-			    ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
-			     i);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		if (eprom_size > sizeof(eprom_buf)) {
-			printk
-			    ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x.  Need %d\n",
-			     i, eprom_size);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		outb(VOYAGER_CAT_END, CAT_CMD);
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
-			eprom_size));
-		if (cat_subread
-		    (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		outb(VOYAGER_CAT_END, CAT_CMD);
-		printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n",
-		       cat_module_name(i), eprom_hdr->version_id,
-		       *((__u32 *) eprom_hdr->tracer), eprom_hdr->num_asics);
-		(*modpp)->ee_size = eprom_hdr->ee_size;
-		(*modpp)->num_asics = eprom_hdr->num_asics;
-		asicpp = &((*modpp)->asic);
-		sp_offset = eprom_hdr->scan_path_offset;
-		/* All we really care about are the Quad cards.  We
-		 * identify them because they are in a processor slot
-		 * and have only four asics */
-		if ((i < 0x10 || (i >= 0x14 && i < 0x1c) || i > 0x1f)) {
-			modpp = &((*modpp)->next);
-			continue;
-		}
-		/* Now we know it's in a processor slot, does it have
-		 * a quad baseboard submodule */
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODPRESENT,
-			 &num_submodules);
-		/* lowest two bits, active low */
-		num_submodules = ~(0xfc | num_submodules);
-		CDEBUG(("VOYAGER CAT: %d submodules present\n",
-			num_submodules));
-		if (num_submodules == 0) {
-			/* fill in the dyadic extended processors */
-			__u8 cpu = i & 0x07;
-
-			printk("Module \"%s\": Dyadic Processor Card\n",
-			       cat_module_name(i));
-			voyager_extended_vic_processors |= (1 << cpu);
-			cpu += 4;
-			voyager_extended_vic_processors |= (1 << cpu);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-
-		/* now we want to read the asics on the first submodule,
-		 * which should be the quad base board */
-
-		cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, &val);
-		CDEBUG(("cat_init: SUBMODSELECT value = 0x%x\n", val));
-		val = (val & 0x7c) | VOYAGER_QUAD_BASEBOARD;
-		cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val);
-
-		outb(VOYAGER_CAT_END, CAT_CMD);
-
-		CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET));
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		cat_disconnect(*modpp, (*modpp)->asic);
-		if (cat_subread(*modpp, (*modpp)->asic,
-				VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size),
-				&eprom_size)) {
-			printk
-			    ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n",
-			     i);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		if (eprom_size > sizeof(eprom_buf)) {
-			printk
-			    ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x.  Need %d\n",
-			     i, eprom_size);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		outb(VOYAGER_CAT_END, CAT_CMD);
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i,
-			eprom_size));
-		if (cat_subread
-		    (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) {
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			continue;
-		}
-		outb(VOYAGER_CAT_END, CAT_CMD);
-		/* Now do everything for the QBB submodule 1 */
-		(*modpp)->ee_size = eprom_hdr->ee_size;
-		(*modpp)->num_asics = eprom_hdr->num_asics;
-		asicpp = &((*modpp)->asic);
-		sp_offset = eprom_hdr->scan_path_offset;
-		/* get rid of the dummy CAT asic and read the real one */
-		kfree((*modpp)->asic);
-		for (asic = 0; asic < (*modpp)->num_asics; asic++) {
-			int j;
-			voyager_asic_t *asicp = *asicpp = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL);	/*&voyager_asic_storage[asic_count++]; */
-			voyager_sp_table_t *sp_table;
-			voyager_at_t *asic_table;
-			voyager_jtt_t *jtag_table;
-
-			if (asicp == NULL) {
-				printk
-				    ("**WARNING** kmalloc failure in cat_init\n");
-				continue;
-			}
-			asicpp = &(asicp->next);
-			asicp->asic_location = asic;
-			sp_table =
-			    (voyager_sp_table_t *) (eprom_buf + sp_offset);
-			asicp->asic_id = sp_table->asic_id;
-			asic_table =
-			    (voyager_at_t *) (eprom_buf +
-					      sp_table->asic_data_offset);
-			for (j = 0; j < 4; j++)
-				asicp->jtag_id[j] = asic_table->jtag_id[j];
-			jtag_table =
-			    (voyager_jtt_t *) (eprom_buf +
-					       asic_table->jtag_offset);
-			asicp->ireg_length = jtag_table->ireg_len;
-			asicp->bit_location = (*modpp)->inst_bits;
-			(*modpp)->inst_bits += asicp->ireg_length;
-			if (asicp->ireg_length > (*modpp)->largest_reg)
-				(*modpp)->largest_reg = asicp->ireg_length;
-			if (asicp->ireg_length < (*modpp)->smallest_reg ||
-			    (*modpp)->smallest_reg == 0)
-				(*modpp)->smallest_reg = asicp->ireg_length;
-			CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n",
-				asicp->asic_id, asicp->ireg_length,
-				asicp->bit_location));
-			if (asicp->asic_id == VOYAGER_QUAD_QABC) {
-				CDEBUG(("VOYAGER CAT: QABC ASIC found\n"));
-				qabc_asic = asicp;
-			}
-			sp_offset += sizeof(voyager_sp_table_t);
-		}
-		CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n", (*modpp)->inst_bits, (*modpp)->largest_reg, (*modpp)->smallest_reg));
-		/* OK, now we have the QUAD ASICs set up, use them.
-		 * we need to:
-		 *
-		 * 1. Find the Memory area for the Quad CPIs.
-		 * 2. Find the Extended VIC processor
-		 * 3. Configure a second extended VIC processor (This
-		 *    cannot be done for the 51xx.
-		 * */
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		cat_connect(*modpp, (*modpp)->asic);
-		CDEBUG(("CAT CONNECTED!!\n"));
-		cat_subread(*modpp, qabc_asic, 0, sizeof(qabc_data), qabc_data);
-		qic_addr = qabc_data[5] << 8;
-		qic_addr = (qic_addr | qabc_data[6]) << 8;
-		qic_addr = (qic_addr | qabc_data[7]) << 8;
-		printk
-		    ("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n",
-		     cat_module_name(i), qic_addr, qabc_data[8]);
-#if 0				/* plumbing fails---FIXME */
-		if ((qabc_data[8] & 0xf0) == 0) {
-			/* FIXME: 32 way 8 CPU slot monster cannot be
-			 * plumbed this way---need to check for it */
-
-			printk("Plumbing second Extended Quad Processor\n");
-			/* second VIC line hardwired to Quad CPU 1 */
-			qabc_data[8] |= 0x20;
-			cat_subwrite(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
-#ifdef VOYAGER_CAT_DEBUG
-			/* verify plumbing */
-			cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]);
-			if ((qabc_data[8] & 0xf0) == 0) {
-				CDEBUG(("PLUMBING FAILED: 0x%x\n",
-					qabc_data[8]));
-			}
-#endif
-		}
-#endif
-
-		{
-			struct resource *res =
-			    kzalloc(sizeof(struct resource), GFP_KERNEL);
-			res->name = kmalloc(128, GFP_KERNEL);
-			sprintf((char *)res->name, "Voyager %s Quad CPI",
-				cat_module_name(i));
-			res->start = qic_addr;
-			res->end = qic_addr + 0x3ff;
-			request_resource(&iomem_resource, res);
-		}
-
-		qic_addr = (unsigned long)ioremap_cache(qic_addr, 0x400);
-
-		for (j = 0; j < 4; j++) {
-			__u8 cpu;
-
-			if (voyager_8slot) {
-				/* 8 slot has a different mapping,
-				 * each slot has only one vic line, so
-				 * 1 cpu in each slot must be < 8 */
-				cpu = (i & 0x07) + j * 8;
-			} else {
-				cpu = (i & 0x03) + j * 4;
-			}
-			if ((qabc_data[8] & (1 << j))) {
-				voyager_extended_vic_processors |= (1 << cpu);
-			}
-			if (qabc_data[8] & (1 << (j + 4))) {
-				/* Second SET register plumbed: Quad
-				 * card has two VIC connected CPUs.
-				 * Secondary cannot be booted as a VIC
-				 * CPU */
-				voyager_extended_vic_processors |= (1 << cpu);
-				voyager_allowed_boot_processors &=
-				    (~(1 << cpu));
-			}
-
-			voyager_quad_processors |= (1 << cpu);
-			voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *)
-			    (qic_addr + (j << 8));
-			CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu,
-				(unsigned long)voyager_quad_cpi_addr[cpu]));
-		}
-		outb(VOYAGER_CAT_END, CAT_CMD);
-
-		*asicpp = NULL;
-		modpp = &((*modpp)->next);
-	}
-	*modpp = NULL;
-	printk
-	    ("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n",
-	     voyager_extended_vic_processors, voyager_quad_processors,
-	     voyager_allowed_boot_processors);
-	request_resource(&ioport_resource, &vic_res);
-	if (voyager_quad_processors)
-		request_resource(&ioport_resource, &qic_res);
-	/* set up the front power switch */
-}
-
-int voyager_cat_readb(__u8 module, __u8 asic, int reg)
-{
-	return 0;
-}
-
-static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp)
-{
-	__u8 val;
-	int err = 0;
-
-	if (!modp->scan_path_connected)
-		return 0;
-	if (asicp->asic_id != VOYAGER_CAT_ID) {
-		CDEBUG(("cat_disconnect: ASIC is not CAT\n"));
-		return 1;
-	}
-	err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
-	if (err) {
-		CDEBUG(("cat_disconnect: failed to read SCANPATH\n"));
-		return err;
-	}
-	val &= VOYAGER_DISCONNECT_ASIC;
-	err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
-	if (err) {
-		CDEBUG(("cat_disconnect: failed to write SCANPATH\n"));
-		return err;
-	}
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	modp->scan_path_connected = 0;
-
-	return 0;
-}
-
-static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp)
-{
-	__u8 val;
-	int err = 0;
-
-	if (modp->scan_path_connected)
-		return 0;
-	if (asicp->asic_id != VOYAGER_CAT_ID) {
-		CDEBUG(("cat_connect: ASIC is not CAT\n"));
-		return 1;
-	}
-
-	err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val);
-	if (err) {
-		CDEBUG(("cat_connect: failed to read SCANPATH\n"));
-		return err;
-	}
-	val |= VOYAGER_CONNECT_ASIC;
-	err = cat_write(modp, asicp, VOYAGER_SCANPATH, val);
-	if (err) {
-		CDEBUG(("cat_connect: failed to write SCANPATH\n"));
-		return err;
-	}
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	modp->scan_path_connected = 1;
-
-	return 0;
-}
-
-void voyager_cat_power_off(void)
-{
-	/* Power the machine off by writing to the PSI over the CAT
-	 * bus */
-	__u8 data;
-	voyager_module_t psi = { 0 };
-	voyager_asic_t psi_asic = { 0 };
-
-	psi.asic = &psi_asic;
-	psi.asic->asic_id = VOYAGER_CAT_ID;
-	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
-	psi.module_addr = VOYAGER_PSI;
-	psi.scan_path_connected = 0;
-
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	/* Connect the PSI to the CAT Bus */
-	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	cat_disconnect(&psi, &psi_asic);
-	/* Read the status */
-	cat_subread(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	CDEBUG(("PSI STATUS 0x%x\n", data));
-	/* These two writes are power off prep and perform */
-	data = PSI_CLEAR;
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	data = PSI_POWER_DOWN;
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data);
-	outb(VOYAGER_CAT_END, CAT_CMD);
-}
-
-struct voyager_status voyager_status = { 0 };
-
-void voyager_cat_psi(__u8 cmd, __u16 reg, __u8 * data)
-{
-	voyager_module_t psi = { 0 };
-	voyager_asic_t psi_asic = { 0 };
-
-	psi.asic = &psi_asic;
-	psi.asic->asic_id = VOYAGER_CAT_ID;
-	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
-	psi.module_addr = VOYAGER_PSI;
-	psi.scan_path_connected = 0;
-
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	/* Connect the PSI to the CAT Bus */
-	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	cat_disconnect(&psi, &psi_asic);
-	switch (cmd) {
-	case VOYAGER_PSI_READ:
-		cat_read(&psi, &psi_asic, reg, data);
-		break;
-	case VOYAGER_PSI_WRITE:
-		cat_write(&psi, &psi_asic, reg, *data);
-		break;
-	case VOYAGER_PSI_SUBREAD:
-		cat_subread(&psi, &psi_asic, reg, 1, data);
-		break;
-	case VOYAGER_PSI_SUBWRITE:
-		cat_subwrite(&psi, &psi_asic, reg, 1, data);
-		break;
-	default:
-		printk(KERN_ERR "Voyager PSI, unrecognised command %d\n", cmd);
-		break;
-	}
-	outb(VOYAGER_CAT_END, CAT_CMD);
-}
-
-void voyager_cat_do_common_interrupt(void)
-{
-	/* This is caused either by a memory parity error or something
-	 * in the PSI */
-	__u8 data;
-	voyager_module_t psi = { 0 };
-	voyager_asic_t psi_asic = { 0 };
-	struct voyager_psi psi_reg;
-	int i;
-      re_read:
-	psi.asic = &psi_asic;
-	psi.asic->asic_id = VOYAGER_CAT_ID;
-	psi.asic->subaddr = VOYAGER_SUBADDR_HI;
-	psi.module_addr = VOYAGER_PSI;
-	psi.scan_path_connected = 0;
-
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	/* Connect the PSI to the CAT Bus */
-	outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT);
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	cat_disconnect(&psi, &psi_asic);
-	/* Read the status.  NOTE: Need to read *all* the PSI regs here
-	 * otherwise the cmn int will be reasserted */
-	for (i = 0; i < sizeof(psi_reg.regs); i++) {
-		cat_read(&psi, &psi_asic, i, &((__u8 *) & psi_reg.regs)[i]);
-	}
-	outb(VOYAGER_CAT_END, CAT_CMD);
-	if ((psi_reg.regs.checkbit & 0x02) == 0) {
-		psi_reg.regs.checkbit |= 0x02;
-		cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit);
-		printk("VOYAGER RE-READ PSI\n");
-		goto re_read;
-	}
-	outb(VOYAGER_CAT_RUN, CAT_CMD);
-	for (i = 0; i < sizeof(psi_reg.subregs); i++) {
-		/* This looks strange, but the PSI doesn't do auto increment
-		 * correctly */
-		cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i,
-			    1, &((__u8 *) & psi_reg.subregs)[i]);
-	}
-	outb(VOYAGER_CAT_END, CAT_CMD);
-#ifdef VOYAGER_CAT_DEBUG
-	printk("VOYAGER PSI: ");
-	for (i = 0; i < sizeof(psi_reg.regs); i++)
-		printk("%02x ", ((__u8 *) & psi_reg.regs)[i]);
-	printk("\n           ");
-	for (i = 0; i < sizeof(psi_reg.subregs); i++)
-		printk("%02x ", ((__u8 *) & psi_reg.subregs)[i]);
-	printk("\n");
-#endif
-	if (psi_reg.regs.intstatus & PSI_MON) {
-		/* switch off or power fail */
-
-		if (psi_reg.subregs.supply & PSI_SWITCH_OFF) {
-			if (voyager_status.switch_off) {
-				printk(KERN_ERR
-				       "Voyager front panel switch turned off again---Immediate power off!\n");
-				voyager_cat_power_off();
-				/* not reached */
-			} else {
-				printk(KERN_ERR
-				       "Voyager front panel switch turned off\n");
-				voyager_status.switch_off = 1;
-				voyager_status.request_from_kernel = 1;
-				wake_up_process(voyager_thread);
-			}
-			/* Tell the hardware we're taking care of the
-			 * shutdown, otherwise it will power the box off
-			 * within 3 seconds of the switch being pressed and,
-			 * which is much more important to us, continue to 
-			 * assert the common interrupt */
-			data = PSI_CLR_SWITCH_OFF;
-			outb(VOYAGER_CAT_RUN, CAT_CMD);
-			cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG,
-				     1, &data);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-		} else {
-
-			VDEBUG(("Voyager ac fail reg 0x%x\n",
-				psi_reg.subregs.ACfail));
-			if ((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) {
-				/* No further update */
-				return;
-			}
-#if 0
-			/* Don't bother trying to find out who failed.
-			 * FIXME: This probably makes the code incorrect on
-			 * anything other than a 345x */
-			for (i = 0; i < 5; i++) {
-				if (psi_reg.subregs.ACfail & (1 << i)) {
-					break;
-				}
-			}
-			printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i);
-#endif
-			/* DON'T do this: it shuts down the AC PSI 
-			   outb(VOYAGER_CAT_RUN, CAT_CMD);
-			   data = PSI_MASK_MASK | i;
-			   cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK,
-			   1, &data);
-			   outb(VOYAGER_CAT_END, CAT_CMD);
-			 */
-			printk(KERN_ERR "Voyager AC power failure\n");
-			outb(VOYAGER_CAT_RUN, CAT_CMD);
-			data = PSI_COLD_START;
-			cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG,
-				     1, &data);
-			outb(VOYAGER_CAT_END, CAT_CMD);
-			voyager_status.power_fail = 1;
-			voyager_status.request_from_kernel = 1;
-			wake_up_process(voyager_thread);
-		}
-
-	} else if (psi_reg.regs.intstatus & PSI_FAULT) {
-		/* Major fault! */
-		printk(KERN_ERR
-		       "Voyager PSI Detected major fault, immediate power off!\n");
-		voyager_cat_power_off();
-		/* not reached */
-	} else if (psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM
-					     | PSI_CURRENT | PSI_DVM
-					     | PSI_PSCFAULT | PSI_STAT_CHG)) {
-		/* other psi fault */
-
-		printk(KERN_WARNING "Voyager PSI status 0x%x\n", data);
-		/* clear the PSI fault */
-		outb(VOYAGER_CAT_RUN, CAT_CMD);
-		cat_write(&psi, &psi_asic, VOYAGER_PSI_STATUS_REG, 0);
-		outb(VOYAGER_CAT_END, CAT_CMD);
-	}
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_smp.c linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_smp.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_smp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1807 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* Copyright (C) 1999,2001
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * This file provides all the same external entries as smp.c but uses
- * the voyager hal to provide the functionality
- */
-#include <linux/cpu.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/mc146818rtc.h>
-#include <linux/cache.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/bootmem.h>
-#include <linux/completion.h>
-#include <asm/desc.h>
-#include <asm/voyager.h>
-#include <asm/vic.h>
-#include <asm/mtrr.h>
-#include <asm/pgalloc.h>
-#include <asm/tlbflush.h>
-#include <asm/arch_hooks.h>
-#include <asm/trampoline.h>
-
-/* TLB state -- visible externally, indexed physically */
-DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 };
-
-/* CPU IRQ affinity -- set to all ones initially */
-static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned =
-	{[0 ... NR_CPUS-1]  = ~0UL };
-
-/* per CPU data structure (for /proc/cpuinfo et al), visible externally
- * indexed physically */
-DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
-EXPORT_PER_CPU_SYMBOL(cpu_info);
-
-/* physical ID of the CPU used to boot the system */
-unsigned char boot_cpu_id;
-
-/* The memory line addresses for the Quad CPIs */
-struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS] __cacheline_aligned;
-
-/* The masks for the Extended VIC processors, filled in by cat_init */
-__u32 voyager_extended_vic_processors = 0;
-
-/* Masks for the extended Quad processors which cannot be VIC booted */
-__u32 voyager_allowed_boot_processors = 0;
-
-/* The mask for the Quad Processors (both extended and non-extended) */
-__u32 voyager_quad_processors = 0;
-
-/* Total count of live CPUs, used in process.c to display
- * the CPU information and in irq.c for the per CPU irq
- * activity count.  Finally exported by i386_ksyms.c */
-static int voyager_extended_cpus = 1;
-
-/* Used for the invalidate map that's also checked in the spinlock */
-static volatile unsigned long smp_invalidate_needed;
-
-/* Bitmask of CPUs present in the system - exported by i386_syms.c, used
- * by scheduler but indexed physically */
-static cpumask_t voyager_phys_cpu_present_map = CPU_MASK_NONE;
-
-/* The internal functions */
-static void send_CPI(__u32 cpuset, __u8 cpi);
-static void ack_CPI(__u8 cpi);
-static int ack_QIC_CPI(__u8 cpi);
-static void ack_special_QIC_CPI(__u8 cpi);
-static void ack_VIC_CPI(__u8 cpi);
-static void send_CPI_allbutself(__u8 cpi);
-static void mask_vic_irq(unsigned int irq);
-static void unmask_vic_irq(unsigned int irq);
-static unsigned int startup_vic_irq(unsigned int irq);
-static void enable_local_vic_irq(unsigned int irq);
-static void disable_local_vic_irq(unsigned int irq);
-static void before_handle_vic_irq(unsigned int irq);
-static void after_handle_vic_irq(unsigned int irq);
-static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask);
-static void ack_vic_irq(unsigned int irq);
-static void vic_enable_cpi(void);
-static void do_boot_cpu(__u8 cpuid);
-static void do_quad_bootstrap(void);
-static void initialize_secondary(void);
-
-int hard_smp_processor_id(void);
-int safe_smp_processor_id(void);
-
-/* Inline functions */
-static inline void send_one_QIC_CPI(__u8 cpu, __u8 cpi)
-{
-	voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi =
-	    (smp_processor_id() << 16) + cpi;
-}
-
-static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi)
-{
-	int cpu;
-
-	for_each_online_cpu(cpu) {
-		if (cpuset & (1 << cpu)) {
-#ifdef VOYAGER_DEBUG
-			if (!cpu_online(cpu))
-				VDEBUG(("CPU%d sending cpi %d to CPU%d not in "
-					"cpu_online_map\n",
-					hard_smp_processor_id(), cpi, cpu));
-#endif
-			send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
-		}
-	}
-}
-
-static inline void wrapper_smp_local_timer_interrupt(void)
-{
-	irq_enter();
-	smp_local_timer_interrupt();
-	irq_exit();
-}
-
-static inline void send_one_CPI(__u8 cpu, __u8 cpi)
-{
-	if (voyager_quad_processors & (1 << cpu))
-		send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
-	else
-		send_CPI(1 << cpu, cpi);
-}
-
-static inline void send_CPI_allbutself(__u8 cpi)
-{
-	__u8 cpu = smp_processor_id();
-	__u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu);
-	send_CPI(mask, cpi);
-}
-
-static inline int is_cpu_quad(void)
-{
-	__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
-	return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER);
-}
-
-static inline int is_cpu_extended(void)
-{
-	__u8 cpu = hard_smp_processor_id();
-
-	return (voyager_extended_vic_processors & (1 << cpu));
-}
-
-static inline int is_cpu_vic_boot(void)
-{
-	__u8 cpu = hard_smp_processor_id();
-
-	return (voyager_extended_vic_processors
-		& voyager_allowed_boot_processors & (1 << cpu));
-}
-
-static inline void ack_CPI(__u8 cpi)
-{
-	switch (cpi) {
-	case VIC_CPU_BOOT_CPI:
-		if (is_cpu_quad() && !is_cpu_vic_boot())
-			ack_QIC_CPI(cpi);
-		else
-			ack_VIC_CPI(cpi);
-		break;
-	case VIC_SYS_INT:
-	case VIC_CMN_INT:
-		/* These are slightly strange.  Even on the Quad card,
-		 * They are vectored as VIC CPIs */
-		if (is_cpu_quad())
-			ack_special_QIC_CPI(cpi);
-		else
-			ack_VIC_CPI(cpi);
-		break;
-	default:
-		printk("VOYAGER ERROR: CPI%d is in common CPI code\n", cpi);
-		break;
-	}
-}
-
-/* local variables */
-
-/* The VIC IRQ descriptors -- these look almost identical to the
- * 8259 IRQs except that masks and things must be kept per processor
- */
-static struct irq_chip vic_chip = {
-	.name = "VIC",
-	.startup = startup_vic_irq,
-	.mask = mask_vic_irq,
-	.unmask = unmask_vic_irq,
-	.set_affinity = set_vic_irq_affinity,
-};
-
-/* used to count up as CPUs are brought on line (starts at 0) */
-static int cpucount = 0;
-
-/* The per cpu profile stuff - used in smp_local_timer_interrupt */
-static DEFINE_PER_CPU(int, prof_multiplier) = 1;
-static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
-static DEFINE_PER_CPU(int, prof_counter) = 1;
-
-/* the map used to check if a CPU has booted */
-static __u32 cpu_booted_map;
-
-/* the synchronize flag used to hold all secondary CPUs spinning in
- * a tight loop until the boot sequence is ready for them */
-static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
-
-/* This is for the new dynamic CPU boot code */
-
-/* The per processor IRQ masks (these are usually kept in sync) */
-static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
-
-/* the list of IRQs to be enabled by the VIC_ENABLE_IRQ_CPI */
-static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
-
-/* Lock for enable/disable of VIC interrupts */
-static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
-
-/* The boot processor is correctly set up in PC mode when it
- * comes up, but the secondaries need their master/slave 8259
- * pairs initializing correctly */
-
-/* Interrupt counters (per cpu) and total - used to try to
- * even up the interrupt handling routines */
-static long vic_intr_total = 0;
-static long vic_intr_count[NR_CPUS] __cacheline_aligned = { 0 };
-static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 };
-
-/* Since we can only use CPI0, we fake all the other CPIs */
-static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned;
-
-/* debugging routine to read the isr of the cpu's pic */
-static inline __u16 vic_read_isr(void)
-{
-	__u16 isr;
-
-	outb(0x0b, 0xa0);
-	isr = inb(0xa0) << 8;
-	outb(0x0b, 0x20);
-	isr |= inb(0x20);
-
-	return isr;
-}
-
-static __init void qic_setup(void)
-{
-	if (!is_cpu_quad()) {
-		/* not a quad, no setup */
-		return;
-	}
-	outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
-	outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
-
-	if (is_cpu_extended()) {
-		/* the QIC duplicate of the VIC base register */
-		outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER);
-		outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER);
-
-		/* FIXME: should set up the QIC timer and memory parity
-		 * error vectors here */
-	}
-}
-
-static __init void vic_setup_pic(void)
-{
-	outb(1, VIC_REDIRECT_REGISTER_1);
-	/* clear the claim registers for dynamic routing */
-	outb(0, VIC_CLAIM_REGISTER_0);
-	outb(0, VIC_CLAIM_REGISTER_1);
-
-	outb(0, VIC_PRIORITY_REGISTER);
-	/* Set the Primary and Secondary Microchannel vector
-	 * bases to be the same as the ordinary interrupts
-	 *
-	 * FIXME: This would be more efficient using separate
-	 * vectors. */
-	outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
-	outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);
-	/* Now initiallise the master PIC belonging to this CPU by
-	 * sending the four ICWs */
-
-	/* ICW1: level triggered, ICW4 needed */
-	outb(0x19, 0x20);
-
-	/* ICW2: vector base */
-	outb(FIRST_EXTERNAL_VECTOR, 0x21);
-
-	/* ICW3: slave at line 2 */
-	outb(0x04, 0x21);
-
-	/* ICW4: 8086 mode */
-	outb(0x01, 0x21);
-
-	/* now the same for the slave PIC */
-
-	/* ICW1: level trigger, ICW4 needed */
-	outb(0x19, 0xA0);
-
-	/* ICW2: slave vector base */
-	outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1);
-
-	/* ICW3: slave ID */
-	outb(0x02, 0xA1);
-
-	/* ICW4: 8086 mode */
-	outb(0x01, 0xA1);
-}
-
-static void do_quad_bootstrap(void)
-{
-	if (is_cpu_quad() && is_cpu_vic_boot()) {
-		int i;
-		unsigned long flags;
-		__u8 cpuid = hard_smp_processor_id();
-
-		local_irq_save(flags);
-
-		for (i = 0; i < 4; i++) {
-			/* FIXME: this would be >>3 &0x7 on the 32 way */
-			if (((cpuid >> 2) & 0x03) == i)
-				/* don't lower our own mask! */
-				continue;
-
-			/* masquerade as local Quad CPU */
-			outb(QIC_CPUID_ENABLE | i, QIC_PROCESSOR_ID);
-			/* enable the startup CPI */
-			outb(QIC_BOOT_CPI_MASK, QIC_MASK_REGISTER1);
-			/* restore cpu id */
-			outb(0, QIC_PROCESSOR_ID);
-		}
-		local_irq_restore(flags);
-	}
-}
-
-void prefill_possible_map(void)
-{
-	/* This is empty on voyager because we need a much
-	 * earlier detection which is done in find_smp_config */
-}
-
-/* Set up all the basic stuff: read the SMP config and make all the
- * SMP information reflect only the boot cpu.  All others will be
- * brought on-line later. */
-void __init find_smp_config(void)
-{
-	int i;
-
-	boot_cpu_id = hard_smp_processor_id();
-
-	printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id);
-
-	/* initialize the CPU structures (moved from smp_boot_cpus) */
-	for (i = 0; i < nr_cpu_ids; i++)
-		cpu_irq_affinity[i] = ~0;
-	cpu_online_map = cpumask_of_cpu(boot_cpu_id);
-
-	/* The boot CPU must be extended */
-	voyager_extended_vic_processors = 1 << boot_cpu_id;
-	/* initially, all of the first 8 CPUs can boot */
-	voyager_allowed_boot_processors = 0xff;
-	/* set up everything for just this CPU, we can alter
-	 * this as we start the other CPUs later */
-	/* now get the CPU disposition from the extended CMOS */
-	cpus_addr(voyager_phys_cpu_present_map)[0] =
-	    voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
-	cpus_addr(voyager_phys_cpu_present_map)[0] |=
-	    voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
-	cpus_addr(voyager_phys_cpu_present_map)[0] |=
-	    voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
-				       2) << 16;
-	cpus_addr(voyager_phys_cpu_present_map)[0] |=
-	    voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
-				       3) << 24;
-	init_cpu_possible(&voyager_phys_cpu_present_map);
-	printk("VOYAGER SMP: voyager_phys_cpu_present_map = 0x%lx\n",
-	       cpus_addr(voyager_phys_cpu_present_map)[0]);
-	/* Here we set up the VIC to enable SMP */
-	/* enable the CPIs by writing the base vector to their register */
-	outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
-	outb(1, VIC_REDIRECT_REGISTER_1);
-	/* set the claim registers for static routing --- Boot CPU gets
-	 * all interrupts untill all other CPUs started */
-	outb(0xff, VIC_CLAIM_REGISTER_0);
-	outb(0xff, VIC_CLAIM_REGISTER_1);
-	/* Set the Primary and Secondary Microchannel vector
-	 * bases to be the same as the ordinary interrupts
-	 *
-	 * FIXME: This would be more efficient using separate
-	 * vectors. */
-	outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
-	outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);
-
-	/* Finally tell the firmware that we're driving */
-	outb(inb(VOYAGER_SUS_IN_CONTROL_PORT) | VOYAGER_IN_CONTROL_FLAG,
-	     VOYAGER_SUS_IN_CONTROL_PORT);
-
-	current_thread_info()->cpu = boot_cpu_id;
-	x86_write_percpu(cpu_number, boot_cpu_id);
-}
-
-/*
- *	The bootstrap kernel entry code has set these up. Save them
- *	for a given CPU, id is physical */
-void __init smp_store_cpu_info(int id)
-{
-	struct cpuinfo_x86 *c = &cpu_data(id);
-
-	*c = boot_cpu_data;
-	c->cpu_index = id;
-
-	identify_secondary_cpu(c);
-}
-
-/* Routine initially called when a non-boot CPU is brought online */
-static void __init start_secondary(void *unused)
-{
-	__u8 cpuid = hard_smp_processor_id();
-
-	cpu_init();
-
-	/* OK, we're in the routine */
-	ack_CPI(VIC_CPU_BOOT_CPI);
-
-	/* setup the 8259 master slave pair belonging to this CPU ---
-	 * we won't actually receive any until the boot CPU
-	 * relinquishes it's static routing mask */
-	vic_setup_pic();
-
-	qic_setup();
-
-	if (is_cpu_quad() && !is_cpu_vic_boot()) {
-		/* clear the boot CPI */
-		__u8 dummy;
-
-		dummy =
-		    voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
-		printk("read dummy %d\n", dummy);
-	}
-
-	/* lower the mask to receive CPIs */
-	vic_enable_cpi();
-
-	VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid));
-
-	notify_cpu_starting(cpuid);
-
-	/* enable interrupts */
-	local_irq_enable();
-
-	/* get our bogomips */
-	calibrate_delay();
-
-	/* save our processor parameters */
-	smp_store_cpu_info(cpuid);
-
-	/* if we're a quad, we may need to bootstrap other CPUs */
-	do_quad_bootstrap();
-
-	/* FIXME: this is rather a poor hack to prevent the CPU
-	 * activating softirqs while it's supposed to be waiting for
-	 * permission to proceed.  Without this, the new per CPU stuff
-	 * in the softirqs will fail */
-	local_irq_disable();
-	cpu_set(cpuid, cpu_callin_map);
-
-	/* signal that we're done */
-	cpu_booted_map = 1;
-
-	while (!cpu_isset(cpuid, smp_commenced_mask))
-		rep_nop();
-	local_irq_enable();
-
-	local_flush_tlb();
-
-	cpu_set(cpuid, cpu_online_map);
-	wmb();
-	cpu_idle();
-}
-
-/* Routine to kick start the given CPU and wait for it to report ready
- * (or timeout in startup).  When this routine returns, the requested
- * CPU is either fully running and configured or known to be dead.
- *
- * We call this routine sequentially 1 CPU at a time, so no need for
- * locking */
-
-static void __init do_boot_cpu(__u8 cpu)
-{
-	struct task_struct *idle;
-	int timeout;
-	unsigned long flags;
-	int quad_boot = (1 << cpu) & voyager_quad_processors
-	    & ~(voyager_extended_vic_processors
-		& voyager_allowed_boot_processors);
-
-	/* This is the format of the CPI IDT gate (in real mode) which
-	 * we're hijacking to boot the CPU */
-	union IDTFormat {
-		struct seg {
-			__u16 Offset;
-			__u16 Segment;
-		} idt;
-		__u32 val;
-	} hijack_source;
-
-	__u32 *hijack_vector;
-	__u32 start_phys_address = setup_trampoline();
-
-	/* There's a clever trick to this: The linux trampoline is
-	 * compiled to begin at absolute location zero, so make the
-	 * address zero but have the data segment selector compensate
-	 * for the actual address */
-	hijack_source.idt.Offset = start_phys_address & 0x000F;
-	hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF;
-
-	cpucount++;
-	alternatives_smp_switch(1);
-
-	idle = fork_idle(cpu);
-	if (IS_ERR(idle))
-		panic("failed fork for CPU%d", cpu);
-	idle->thread.ip = (unsigned long)start_secondary;
-	/* init_tasks (in sched.c) is indexed logically */
-	stack_start.sp = (void *)idle->thread.sp;
-
-	init_gdt(cpu);
-	per_cpu(current_task, cpu) = idle;
-	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
-	irq_ctx_init(cpu);
-
-	/* Note: Don't modify initial ss override */
-	VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
-		(unsigned long)hijack_source.val, hijack_source.idt.Segment,
-		hijack_source.idt.Offset, stack_start.sp));
-
-	/* init lowmem identity mapping */
-	clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-			min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
-	flush_tlb_all();
-
-	if (quad_boot) {
-		printk("CPU %d: non extended Quad boot\n", cpu);
-		hijack_vector =
-		    (__u32 *)
-		    phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE) * 4);
-		*hijack_vector = hijack_source.val;
-	} else {
-		printk("CPU%d: extended VIC boot\n", cpu);
-		hijack_vector =
-		    (__u32 *)
-		    phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE) * 4);
-		*hijack_vector = hijack_source.val;
-		/* VIC errata, may also receive interrupt at this address */
-		hijack_vector =
-		    (__u32 *)
-		    phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI +
-				  VIC_DEFAULT_CPI_BASE) * 4);
-		*hijack_vector = hijack_source.val;
-	}
-	/* All non-boot CPUs start with interrupts fully masked.  Need
-	 * to lower the mask of the CPI we're about to send.  We do
-	 * this in the VIC by masquerading as the processor we're
-	 * about to boot and lowering its interrupt mask */
-	local_irq_save(flags);
-	if (quad_boot) {
-		send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI);
-	} else {
-		outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
-		/* here we're altering registers belonging to `cpu' */
-
-		outb(VIC_BOOT_INTERRUPT_MASK, 0x21);
-		/* now go back to our original identity */
-		outb(boot_cpu_id, VIC_PROCESSOR_ID);
-
-		/* and boot the CPU */
-
-		send_CPI((1 << cpu), VIC_CPU_BOOT_CPI);
-	}
-	cpu_booted_map = 0;
-	local_irq_restore(flags);
-
-	/* now wait for it to become ready (or timeout) */
-	for (timeout = 0; timeout < 50000; timeout++) {
-		if (cpu_booted_map)
-			break;
-		udelay(100);
-	}
-	/* reset the page table */
-	zap_low_mappings();
-
-	if (cpu_booted_map) {
-		VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
-			cpu, smp_processor_id()));
-
-		printk("CPU%d: ", cpu);
-		print_cpu_info(&cpu_data(cpu));
-		wmb();
-		cpu_set(cpu, cpu_callout_map);
-		cpu_set(cpu, cpu_present_map);
-	} else {
-		printk("CPU%d FAILED TO BOOT: ", cpu);
-		if (*
-		    ((volatile unsigned char *)phys_to_virt(start_phys_address))
-		    == 0xA5)
-			printk("Stuck.\n");
-		else
-			printk("Not responding.\n");
-
-		cpucount--;
-	}
-}
-
-void __init smp_boot_cpus(void)
-{
-	int i;
-
-	/* CAT BUS initialisation must be done after the memory */
-	/* FIXME: The L4 has a catbus too, it just needs to be
-	 * accessed in a totally different way */
-	if (voyager_level == 5) {
-		voyager_cat_init();
-
-		/* now that the cat has probed the Voyager System Bus, sanity
-		 * check the cpu map */
-		if (((voyager_quad_processors | voyager_extended_vic_processors)
-		     & cpus_addr(voyager_phys_cpu_present_map)[0]) !=
-		    cpus_addr(voyager_phys_cpu_present_map)[0]) {
-			/* should panic */
-			printk("\n\n***WARNING*** "
-			       "Sanity check of CPU present map FAILED\n");
-		}
-	} else if (voyager_level == 4)
-		voyager_extended_vic_processors =
-		    cpus_addr(voyager_phys_cpu_present_map)[0];
-
-	/* this sets up the idle task to run on the current cpu */
-	voyager_extended_cpus = 1;
-	/* Remove the global_irq_holder setting, it triggers a BUG() on
-	 * schedule at the moment */
-	//global_irq_holder = boot_cpu_id;
-
-	/* FIXME: Need to do something about this but currently only works
-	 * on CPUs with a tsc which none of mine have.
-	 smp_tune_scheduling();
-	 */
-	smp_store_cpu_info(boot_cpu_id);
-	/* setup the jump vector */
-	initial_code = (unsigned long)initialize_secondary;
-	printk("CPU%d: ", boot_cpu_id);
-	print_cpu_info(&cpu_data(boot_cpu_id));
-
-	if (is_cpu_quad()) {
-		/* booting on a Quad CPU */
-		printk("VOYAGER SMP: Boot CPU is Quad\n");
-		qic_setup();
-		do_quad_bootstrap();
-	}
-
-	/* enable our own CPIs */
-	vic_enable_cpi();
-
-	cpu_set(boot_cpu_id, cpu_online_map);
-	cpu_set(boot_cpu_id, cpu_callout_map);
-
-	/* loop over all the extended VIC CPUs and boot them.  The
-	 * Quad CPUs must be bootstrapped by their extended VIC cpu */
-	for (i = 0; i < nr_cpu_ids; i++) {
-		if (i == boot_cpu_id || !cpu_isset(i, voyager_phys_cpu_present_map))
-			continue;
-		do_boot_cpu(i);
-		/* This udelay seems to be needed for the Quad boots
-		 * don't remove unless you know what you're doing */
-		udelay(1000);
-	}
-	/* we could compute the total bogomips here, but why bother?,
-	 * Code added from smpboot.c */
-	{
-		unsigned long bogosum = 0;
-
-		for_each_online_cpu(i)
-			bogosum += cpu_data(i).loops_per_jiffy;
-		printk(KERN_INFO "Total of %d processors activated "
-		       "(%lu.%02lu BogoMIPS).\n",
-		       cpucount + 1, bogosum / (500000 / HZ),
-		       (bogosum / (5000 / HZ)) % 100);
-	}
-	voyager_extended_cpus = hweight32(voyager_extended_vic_processors);
-	printk("VOYAGER: Extended (interrupt handling CPUs): "
-	       "%d, non-extended: %d\n", voyager_extended_cpus,
-	       num_booting_cpus() - voyager_extended_cpus);
-	/* that's it, switch to symmetric mode */
-	outb(0, VIC_PRIORITY_REGISTER);
-	outb(0, VIC_CLAIM_REGISTER_0);
-	outb(0, VIC_CLAIM_REGISTER_1);
-
-	VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus()));
-}
-
-/* Reload the secondary CPUs task structure (this function does not
- * return ) */
-static void __init initialize_secondary(void)
-{
-#if 0
-	// AC kernels only
-	set_current(hard_get_current());
-#endif
-
-	/*
-	 * We don't actually need to load the full TSS,
-	 * basically just the stack pointer and the eip.
-	 */
-
-	asm volatile ("movl %0,%%esp\n\t"
-		      "jmp *%1"::"r" (current->thread.sp),
-		      "r"(current->thread.ip));
-}
-
-/* handle a Voyager SYS_INT -- If we don't, the base board will
- * panic the system.
- *
- * System interrupts occur because some problem was detected on the
- * various busses.  To find out what you have to probe all the
- * hardware via the CAT bus.  FIXME: At the moment we do nothing. */
-void smp_vic_sys_interrupt(struct pt_regs *regs)
-{
-	ack_CPI(VIC_SYS_INT);
-	printk("Voyager SYSTEM INTERRUPT\n");
-}
-
-/* Handle a voyager CMN_INT; These interrupts occur either because of
- * a system status change or because a single bit memory error
- * occurred.  FIXME: At the moment, ignore all this. */
-void smp_vic_cmn_interrupt(struct pt_regs *regs)
-{
-	static __u8 in_cmn_int = 0;
-	static DEFINE_SPINLOCK(cmn_int_lock);
-
-	/* common ints are broadcast, so make sure we only do this once */
-	_raw_spin_lock(&cmn_int_lock);
-	if (in_cmn_int)
-		goto unlock_end;
-
-	in_cmn_int++;
-	_raw_spin_unlock(&cmn_int_lock);
-
-	VDEBUG(("Voyager COMMON INTERRUPT\n"));
-
-	if (voyager_level == 5)
-		voyager_cat_do_common_interrupt();
-
-	_raw_spin_lock(&cmn_int_lock);
-	in_cmn_int = 0;
-      unlock_end:
-	_raw_spin_unlock(&cmn_int_lock);
-	ack_CPI(VIC_CMN_INT);
-}
-
-/*
- * Reschedule call back. Nothing to do, all the work is done
- * automatically when we return from the interrupt.  */
-static void smp_reschedule_interrupt(void)
-{
-	/* do nothing */
-}
-
-static struct mm_struct *flush_mm;
-static unsigned long flush_va;
-static DEFINE_SPINLOCK(tlbstate_lock);
-
-/*
- * We cannot call mmdrop() because we are in interrupt context,
- * instead update mm->cpu_vm_mask.
- *
- * We need to reload %cr3 since the page tables may be going
- * away from under us..
- */
-static inline void voyager_leave_mm(unsigned long cpu)
-{
-	if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
-		BUG();
-	cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
-	load_cr3(swapper_pg_dir);
-}
-
-/*
- * Invalidate call-back
- */
-static void smp_invalidate_interrupt(void)
-{
-	__u8 cpu = smp_processor_id();
-
-	if (!test_bit(cpu, &smp_invalidate_needed))
-		return;
-	/* This will flood messages.  Don't uncomment unless you see
-	 * Problems with cross cpu invalidation
-	 VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
-	 smp_processor_id()));
-	 */
-
-	if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
-		if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
-			if (flush_va == TLB_FLUSH_ALL)
-				local_flush_tlb();
-			else
-				__flush_tlb_one(flush_va);
-		} else
-			voyager_leave_mm(cpu);
-	}
-	smp_mb__before_clear_bit();
-	clear_bit(cpu, &smp_invalidate_needed);
-	smp_mb__after_clear_bit();
-}
-
-/* All the new flush operations for 2.4 */
-
-/* This routine is called with a physical cpu mask */
-static void
-voyager_flush_tlb_others(unsigned long cpumask, struct mm_struct *mm,
-			 unsigned long va)
-{
-	int stuck = 50000;
-
-	if (!cpumask)
-		BUG();
-	if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask)
-		BUG();
-	if (cpumask & (1 << smp_processor_id()))
-		BUG();
-	if (!mm)
-		BUG();
-
-	spin_lock(&tlbstate_lock);
-
-	flush_mm = mm;
-	flush_va = va;
-	atomic_set_mask(cpumask, &smp_invalidate_needed);
-	/*
-	 * We have to send the CPI only to
-	 * CPUs affected.
-	 */
-	send_CPI(cpumask, VIC_INVALIDATE_CPI);
-
-	while (smp_invalidate_needed) {
-		mb();
-		if (--stuck == 0) {
-			printk("***WARNING*** Stuck doing invalidate CPI "
-			       "(CPU%d)\n", smp_processor_id());
-			break;
-		}
-	}
-
-	/* Uncomment only to debug invalidation problems
-	   VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
-	 */
-
-	flush_mm = NULL;
-	flush_va = 0;
-	spin_unlock(&tlbstate_lock);
-}
-
-void flush_tlb_current_task(void)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long cpu_mask;
-
-	preempt_disable();
-
-	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
-	local_flush_tlb();
-	if (cpu_mask)
-		voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-
-	preempt_enable();
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-	unsigned long cpu_mask;
-
-	preempt_disable();
-
-	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
-
-	if (current->active_mm == mm) {
-		if (current->mm)
-			local_flush_tlb();
-		else
-			voyager_leave_mm(smp_processor_id());
-	}
-	if (cpu_mask)
-		voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-
-	preempt_enable();
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long cpu_mask;
-
-	preempt_disable();
-
-	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
-	if (current->active_mm == mm) {
-		if (current->mm)
-			__flush_tlb_one(va);
-		else
-			voyager_leave_mm(smp_processor_id());
-	}
-
-	if (cpu_mask)
-		voyager_flush_tlb_others(cpu_mask, mm, va);
-
-	preempt_enable();
-}
-
-EXPORT_SYMBOL(flush_tlb_page);
-
-/* enable the requested IRQs */
-static void smp_enable_irq_interrupt(void)
-{
-	__u8 irq;
-	__u8 cpu = get_cpu();
-
-	VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu,
-		vic_irq_enable_mask[cpu]));
-
-	spin_lock(&vic_irq_lock);
-	for (irq = 0; irq < 16; irq++) {
-		if (vic_irq_enable_mask[cpu] & (1 << irq))
-			enable_local_vic_irq(irq);
-	}
-	vic_irq_enable_mask[cpu] = 0;
-	spin_unlock(&vic_irq_lock);
-
-	put_cpu_no_resched();
-}
-
-/*
- *	CPU halt call-back
- */
-static void smp_stop_cpu_function(void *dummy)
-{
-	VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
-	cpu_clear(smp_processor_id(), cpu_online_map);
-	local_irq_disable();
-	for (;;)
-		halt();
-}
-
-/* execute a thread on a new CPU.  The function to be called must be
- * previously set up.  This is used to schedule a function for
- * execution on all CPUs - set up the function then broadcast a
- * function_interrupt CPI to come here on each CPU */
-static void smp_call_function_interrupt(void)
-{
-	irq_enter();
-	generic_smp_call_function_interrupt();
-	__get_cpu_var(irq_stat).irq_call_count++;
-	irq_exit();
-}
-
-static void smp_call_function_single_interrupt(void)
-{
-	irq_enter();
-	generic_smp_call_function_single_interrupt();
-	__get_cpu_var(irq_stat).irq_call_count++;
-	irq_exit();
-}
-
-/* Sorry about the name.  In an APIC based system, the APICs
- * themselves are programmed to send a timer interrupt.  This is used
- * by linux to reschedule the processor.  Voyager doesn't have this,
- * so we use the system clock to interrupt one processor, which in
- * turn, broadcasts a timer CPI to all the others --- we receive that
- * CPI here.  We don't use this actually for counting so losing
- * ticks doesn't matter
- *
- * FIXME: For those CPUs which actually have a local APIC, we could
- * try to use it to trigger this interrupt instead of having to
- * broadcast the timer tick.  Unfortunately, all my pentium DYADs have
- * no local APIC, so I can't do this
- *
- * This function is currently a placeholder and is unused in the code */
-void smp_apic_timer_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	wrapper_smp_local_timer_interrupt();
-	set_irq_regs(old_regs);
-}
-
-/* All of the QUAD interrupt GATES */
-void smp_qic_timer_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	ack_QIC_CPI(QIC_TIMER_CPI);
-	wrapper_smp_local_timer_interrupt();
-	set_irq_regs(old_regs);
-}
-
-void smp_qic_invalidate_interrupt(struct pt_regs *regs)
-{
-	ack_QIC_CPI(QIC_INVALIDATE_CPI);
-	smp_invalidate_interrupt();
-}
-
-void smp_qic_reschedule_interrupt(struct pt_regs *regs)
-{
-	ack_QIC_CPI(QIC_RESCHEDULE_CPI);
-	smp_reschedule_interrupt();
-}
-
-void smp_qic_enable_irq_interrupt(struct pt_regs *regs)
-{
-	ack_QIC_CPI(QIC_ENABLE_IRQ_CPI);
-	smp_enable_irq_interrupt();
-}
-
-void smp_qic_call_function_interrupt(struct pt_regs *regs)
-{
-	ack_QIC_CPI(QIC_CALL_FUNCTION_CPI);
-	smp_call_function_interrupt();
-}
-
-void smp_qic_call_function_single_interrupt(struct pt_regs *regs)
-{
-	ack_QIC_CPI(QIC_CALL_FUNCTION_SINGLE_CPI);
-	smp_call_function_single_interrupt();
-}
-
-void smp_vic_cpi_interrupt(struct pt_regs *regs)
-{
-	struct pt_regs *old_regs = set_irq_regs(regs);
-	__u8 cpu = smp_processor_id();
-
-	if (is_cpu_quad())
-		ack_QIC_CPI(VIC_CPI_LEVEL0);
-	else
-		ack_VIC_CPI(VIC_CPI_LEVEL0);
-
-	if (test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
-		wrapper_smp_local_timer_interrupt();
-	if (test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
-		smp_invalidate_interrupt();
-	if (test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
-		smp_reschedule_interrupt();
-	if (test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
-		smp_enable_irq_interrupt();
-	if (test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
-		smp_call_function_interrupt();
-	if (test_and_clear_bit(VIC_CALL_FUNCTION_SINGLE_CPI, &vic_cpi_mailbox[cpu]))
-		smp_call_function_single_interrupt();
-	set_irq_regs(old_regs);
-}
-
-static void do_flush_tlb_all(void *info)
-{
-	unsigned long cpu = smp_processor_id();
-
-	__flush_tlb_all();
-	if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
-		voyager_leave_mm(cpu);
-}
-
-/* flush the TLB of every active CPU in the system */
-void flush_tlb_all(void)
-{
-	on_each_cpu(do_flush_tlb_all, 0, 1);
-}
-
-/* send a reschedule CPI to one CPU by physical CPU number*/
-static void voyager_smp_send_reschedule(int cpu)
-{
-	send_one_CPI(cpu, VIC_RESCHEDULE_CPI);
-}
-
-int hard_smp_processor_id(void)
-{
-	__u8 i;
-	__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
-	if ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
-		return cpumask & 0x1F;
-
-	for (i = 0; i < 8; i++) {
-		if (cpumask & (1 << i))
-			return i;
-	}
-	printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask);
-	return 0;
-}
-
-int safe_smp_processor_id(void)
-{
-	return hard_smp_processor_id();
-}
-
-/* broadcast a halt to all other CPUs */
-static void voyager_smp_send_stop(void)
-{
-	smp_call_function(smp_stop_cpu_function, NULL, 1);
-}
-
-/* this function is triggered in time.c when a clock tick fires
- * we need to re-broadcast the tick to all CPUs */
-void smp_vic_timer_interrupt(void)
-{
-	send_CPI_allbutself(VIC_TIMER_CPI);
-	smp_local_timer_interrupt();
-}
-
-/* local (per CPU) timer interrupt.  It does both profiling and
- * process statistics/rescheduling.
- *
- * We do profiling in every local tick, statistics/rescheduling
- * happen only every 'profiling multiplier' ticks. The default
- * multiplier is 1 and it can be changed by writing the new multiplier
- * value into /proc/profile.
- */
-void smp_local_timer_interrupt(void)
-{
-	int cpu = smp_processor_id();
-	long weight;
-
-	profile_tick(CPU_PROFILING);
-	if (--per_cpu(prof_counter, cpu) <= 0) {
-		/*
-		 * The multiplier may have changed since the last time we got
-		 * to this point as a result of the user writing to
-		 * /proc/profile. In this case we need to adjust the APIC
-		 * timer accordingly.
-		 *
-		 * Interrupts are already masked off at this point.
-		 */
-		per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu);
-		if (per_cpu(prof_counter, cpu) !=
-		    per_cpu(prof_old_multiplier, cpu)) {
-			/* FIXME: need to update the vic timer tick here */
-			per_cpu(prof_old_multiplier, cpu) =
-			    per_cpu(prof_counter, cpu);
-		}
-
-		update_process_times(user_mode_vm(get_irq_regs()));
-	}
-
-	if (((1 << cpu) & voyager_extended_vic_processors) == 0)
-		/* only extended VIC processors participate in
-		 * interrupt distribution */
-		return;
-
-	/*
-	 * We take the 'long' return path, and there every subsystem
-	 * grabs the appropriate locks (kernel lock/ irq lock).
-	 *
-	 * we might want to decouple profiling from the 'long path',
-	 * and do the profiling totally in assembly.
-	 *
-	 * Currently this isn't too much of an issue (performance wise),
-	 * we can take more than 100K local irqs per second on a 100 MHz P5.
-	 */
-
-	if ((++vic_tick[cpu] & 0x7) != 0)
-		return;
-	/* get here every 16 ticks (about every 1/6 of a second) */
-
-	/* Change our priority to give someone else a chance at getting
-	 * the IRQ. The algorithm goes like this:
-	 *
-	 * In the VIC, the dynamically routed interrupt is always
-	 * handled by the lowest priority eligible (i.e. receiving
-	 * interrupts) CPU.  If >1 eligible CPUs are equal lowest, the
-	 * lowest processor number gets it.
-	 *
-	 * The priority of a CPU is controlled by a special per-CPU
-	 * VIC priority register which is 3 bits wide 0 being lowest
-	 * and 7 highest priority..
-	 *
-	 * Therefore we subtract the average number of interrupts from
-	 * the number we've fielded.  If this number is negative, we
-	 * lower the activity count and if it is positive, we raise
-	 * it.
-	 *
-	 * I'm afraid this still leads to odd looking interrupt counts:
-	 * the totals are all roughly equal, but the individual ones
-	 * look rather skewed.
-	 *
-	 * FIXME: This algorithm is total crap when mixed with SMP
-	 * affinity code since we now try to even up the interrupt
-	 * counts when an affinity binding is keeping them on a
-	 * particular CPU*/
-	weight = (vic_intr_count[cpu] * voyager_extended_cpus
-		  - vic_intr_total) >> 4;
-	weight += 4;
-	if (weight > 7)
-		weight = 7;
-	if (weight < 0)
-		weight = 0;
-
-	outb((__u8) weight, VIC_PRIORITY_REGISTER);
-
-#ifdef VOYAGER_DEBUG
-	if ((vic_tick[cpu] & 0xFFF) == 0) {
-		/* print this message roughly every 25 secs */
-		printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n",
-		       cpu, vic_tick[cpu], weight);
-	}
-#endif
-}
-
-/* setup the profiling timer */
-int setup_profiling_timer(unsigned int multiplier)
-{
-	int i;
-
-	if ((!multiplier))
-		return -EINVAL;
-
-	/*
-	 * Set the new multiplier for each CPU. CPUs don't start using the
-	 * new values until the next timer interrupt in which they do process
-	 * accounting.
-	 */
-	for (i = 0; i < nr_cpu_ids; ++i)
-		per_cpu(prof_multiplier, i) = multiplier;
-
-	return 0;
-}
-
-/* This is a bit of a mess, but forced on us by the genirq changes
- * there's no genirq handler that really does what voyager wants
- * so hack it up with the simple IRQ handler */
-static void handle_vic_irq(unsigned int irq, struct irq_desc *desc)
-{
-	before_handle_vic_irq(irq);
-	handle_simple_irq(irq, desc);
-	after_handle_vic_irq(irq);
-}
-
-/*  The CPIs are handled in the per cpu 8259s, so they must be
- *  enabled to be received: FIX: enabling the CPIs in the early
- *  boot sequence interferes with bug checking; enable them later
- *  on in smp_init */
-#define VIC_SET_GATE(cpi, vector) \
-	set_intr_gate((cpi) + VIC_DEFAULT_CPI_BASE, (vector))
-#define QIC_SET_GATE(cpi, vector) \
-	set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector))
-
-void __init voyager_smp_intr_init(void)
-{
-	int i;
-
-	/* initialize the per cpu irq mask to all disabled */
-	for (i = 0; i < nr_cpu_ids; i++)
-		vic_irq_mask[i] = 0xFFFF;
-
-	VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt);
-
-	VIC_SET_GATE(VIC_SYS_INT, vic_sys_interrupt);
-	VIC_SET_GATE(VIC_CMN_INT, vic_cmn_interrupt);
-
-	QIC_SET_GATE(QIC_TIMER_CPI, qic_timer_interrupt);
-	QIC_SET_GATE(QIC_INVALIDATE_CPI, qic_invalidate_interrupt);
-	QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt);
-	QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt);
-	QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt);
-
-	/* now put the VIC descriptor into the first 48 IRQs
-	 *
-	 * This is for later: first 16 correspond to PC IRQs; next 16
-	 * are Primary MC IRQs and final 16 are Secondary MC IRQs */
-	for (i = 0; i < 48; i++)
-		set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
-}
-
-/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
- * processor to receive CPI */
-static void send_CPI(__u32 cpuset, __u8 cpi)
-{
-	int cpu;
-	__u32 quad_cpuset = (cpuset & voyager_quad_processors);
-
-	if (cpi < VIC_START_FAKE_CPI) {
-		/* fake CPI are only used for booting, so send to the
-		 * extended quads as well---Quads must be VIC booted */
-		outb((__u8) (cpuset), VIC_CPI_Registers[cpi]);
-		return;
-	}
-	if (quad_cpuset)
-		send_QIC_CPI(quad_cpuset, cpi);
-	cpuset &= ~quad_cpuset;
-	cpuset &= 0xff;		/* only first 8 CPUs vaild for VIC CPI */
-	if (cpuset == 0)
-		return;
-	for_each_online_cpu(cpu) {
-		if (cpuset & (1 << cpu))
-			set_bit(cpi, &vic_cpi_mailbox[cpu]);
-	}
-	if (cpuset)
-		outb((__u8) cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
-}
-
-/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
- * set the cache line to shared by reading it.
- *
- * DON'T make this inline otherwise the cache line read will be
- * optimised away
- * */
-static int ack_QIC_CPI(__u8 cpi)
-{
-	__u8 cpu = hard_smp_processor_id();
-
-	cpi &= 7;
-
-	outb(1 << cpi, QIC_INTERRUPT_CLEAR1);
-	return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi;
-}
-
-static void ack_special_QIC_CPI(__u8 cpi)
-{
-	switch (cpi) {
-	case VIC_CMN_INT:
-		outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0);
-		break;
-	case VIC_SYS_INT:
-		outb(QIC_SYS_INT, QIC_INTERRUPT_CLEAR0);
-		break;
-	}
-	/* also clear at the VIC, just in case (nop for non-extended proc) */
-	ack_VIC_CPI(cpi);
-}
-
-/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */
-static void ack_VIC_CPI(__u8 cpi)
-{
-#ifdef VOYAGER_DEBUG
-	unsigned long flags;
-	__u16 isr;
-	__u8 cpu = smp_processor_id();
-
-	local_irq_save(flags);
-	isr = vic_read_isr();
-	if ((isr & (1 << (cpi & 7))) == 0) {
-		printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi);
-	}
-#endif
-	/* send specific EOI; the two system interrupts have
-	 * bit 4 set for a separate vector but behave as the
-	 * corresponding 3 bit intr */
-	outb_p(0x60 | (cpi & 7), 0x20);
-
-#ifdef VOYAGER_DEBUG
-	if ((vic_read_isr() & (1 << (cpi & 7))) != 0) {
-		printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi);
-	}
-	local_irq_restore(flags);
-#endif
-}
-
-/* cribbed with thanks from irq.c */
-#define __byte(x,y)	(((unsigned char *)&(y))[x])
-#define cached_21(cpu)	(__byte(0,vic_irq_mask[cpu]))
-#define cached_A1(cpu)	(__byte(1,vic_irq_mask[cpu]))
-
-static unsigned int startup_vic_irq(unsigned int irq)
-{
-	unmask_vic_irq(irq);
-
-	return 0;
-}
-
-/* The enable and disable routines.  This is where we run into
- * conflicting architectural philosophy.  Fundamentally, the voyager
- * architecture does not expect to have to disable interrupts globally
- * (the IRQ controllers belong to each CPU).  The processor masquerade
- * which is used to start the system shouldn't be used in a running OS
- * since it will cause great confusion if two separate CPUs drive to
- * the same IRQ controller (I know, I've tried it).
- *
- * The solution is a variant on the NCR lazy SPL design:
- *
- * 1) To disable an interrupt, do nothing (other than set the
- *    IRQ_DISABLED flag).  This dares the interrupt actually to arrive.
- *
- * 2) If the interrupt dares to come in, raise the local mask against
- *    it (this will result in all the CPU masks being raised
- *    eventually).
- *
- * 3) To enable the interrupt, lower the mask on the local CPU and
- *    broadcast an Interrupt enable CPI which causes all other CPUs to
- *    adjust their masks accordingly.  */
-
-static void unmask_vic_irq(unsigned int irq)
-{
-	/* linux doesn't to processor-irq affinity, so enable on
-	 * all CPUs we know about */
-	int cpu = smp_processor_id(), real_cpu;
-	__u16 mask = (1 << irq);
-	__u32 processorList = 0;
-	unsigned long flags;
-
-	VDEBUG(("VOYAGER: unmask_vic_irq(%d) CPU%d affinity 0x%lx\n",
-		irq, cpu, cpu_irq_affinity[cpu]));
-	spin_lock_irqsave(&vic_irq_lock, flags);
-	for_each_online_cpu(real_cpu) {
-		if (!(voyager_extended_vic_processors & (1 << real_cpu)))
-			continue;
-		if (!(cpu_irq_affinity[real_cpu] & mask)) {
-			/* irq has no affinity for this CPU, ignore */
-			continue;
-		}
-		if (real_cpu == cpu) {
-			enable_local_vic_irq(irq);
-		} else if (vic_irq_mask[real_cpu] & mask) {
-			vic_irq_enable_mask[real_cpu] |= mask;
-			processorList |= (1 << real_cpu);
-		}
-	}
-	spin_unlock_irqrestore(&vic_irq_lock, flags);
-	if (processorList)
-		send_CPI(processorList, VIC_ENABLE_IRQ_CPI);
-}
-
-static void mask_vic_irq(unsigned int irq)
-{
-	/* lazy disable, do nothing */
-}
-
-static void enable_local_vic_irq(unsigned int irq)
-{
-	__u8 cpu = smp_processor_id();
-	__u16 mask = ~(1 << irq);
-	__u16 old_mask = vic_irq_mask[cpu];
-
-	vic_irq_mask[cpu] &= mask;
-	if (vic_irq_mask[cpu] == old_mask)
-		return;
-
-	VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n",
-		irq, cpu));
-
-	if (irq & 8) {
-		outb_p(cached_A1(cpu), 0xA1);
-		(void)inb_p(0xA1);
-	} else {
-		outb_p(cached_21(cpu), 0x21);
-		(void)inb_p(0x21);
-	}
-}
-
-static void disable_local_vic_irq(unsigned int irq)
-{
-	__u8 cpu = smp_processor_id();
-	__u16 mask = (1 << irq);
-	__u16 old_mask = vic_irq_mask[cpu];
-
-	if (irq == 7)
-		return;
-
-	vic_irq_mask[cpu] |= mask;
-	if (old_mask == vic_irq_mask[cpu])
-		return;
-
-	VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n",
-		irq, cpu));
-
-	if (irq & 8) {
-		outb_p(cached_A1(cpu), 0xA1);
-		(void)inb_p(0xA1);
-	} else {
-		outb_p(cached_21(cpu), 0x21);
-		(void)inb_p(0x21);
-	}
-}
-
-/* The VIC is level triggered, so the ack can only be issued after the
- * interrupt completes.  However, we do Voyager lazy interrupt
- * handling here: It is an extremely expensive operation to mask an
- * interrupt in the vic, so we merely set a flag (IRQ_DISABLED).  If
- * this interrupt actually comes in, then we mask and ack here to push
- * the interrupt off to another CPU */
-static void before_handle_vic_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_to_desc(irq);
-	__u8 cpu = smp_processor_id();
-
-	_raw_spin_lock(&vic_irq_lock);
-	vic_intr_total++;
-	vic_intr_count[cpu]++;
-
-	if (!(cpu_irq_affinity[cpu] & (1 << irq))) {
-		/* The irq is not in our affinity mask, push it off
-		 * onto another CPU */
-		VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d "
-			"on cpu %d\n", irq, cpu));
-		disable_local_vic_irq(irq);
-		/* set IRQ_INPROGRESS to prevent the handler in irq.c from
-		 * actually calling the interrupt routine */
-		desc->status |= IRQ_REPLAY | IRQ_INPROGRESS;
-	} else if (desc->status & IRQ_DISABLED) {
-		/* Damn, the interrupt actually arrived, do the lazy
-		 * disable thing. The interrupt routine in irq.c will
-		 * not handle a IRQ_DISABLED interrupt, so nothing more
-		 * need be done here */
-		VDEBUG(("VOYAGER DEBUG: lazy disable of irq %d on CPU %d\n",
-			irq, cpu));
-		disable_local_vic_irq(irq);
-		desc->status |= IRQ_REPLAY;
-	} else {
-		desc->status &= ~IRQ_REPLAY;
-	}
-
-	_raw_spin_unlock(&vic_irq_lock);
-}
-
-/* Finish the VIC interrupt: basically mask */
-static void after_handle_vic_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_to_desc(irq);
-
-	_raw_spin_lock(&vic_irq_lock);
-	{
-		unsigned int status = desc->status & ~IRQ_INPROGRESS;
-#ifdef VOYAGER_DEBUG
-		__u16 isr;
-#endif
-
-		desc->status = status;
-		if ((status & IRQ_DISABLED))
-			disable_local_vic_irq(irq);
-#ifdef VOYAGER_DEBUG
-		/* DEBUG: before we ack, check what's in progress */
-		isr = vic_read_isr();
-		if ((isr & (1 << irq) && !(status & IRQ_REPLAY)) == 0) {
-			int i;
-			__u8 cpu = smp_processor_id();
-			__u8 real_cpu;
-			int mask;	/* Um... initialize me??? --RR */
-
-			printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
-			       cpu, irq);
-			for_each_possible_cpu(real_cpu, mask) {
-
-				outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
-				     VIC_PROCESSOR_ID);
-				isr = vic_read_isr();
-				if (isr & (1 << irq)) {
-					printk
-					    ("VOYAGER SMP: CPU%d ack irq %d\n",
-					     real_cpu, irq);
-					ack_vic_irq(irq);
-				}
-				outb(cpu, VIC_PROCESSOR_ID);
-			}
-		}
-#endif /* VOYAGER_DEBUG */
-		/* as soon as we ack, the interrupt is eligible for
-		 * receipt by another CPU so everything must be in
-		 * order here  */
-		ack_vic_irq(irq);
-		if (status & IRQ_REPLAY) {
-			/* replay is set if we disable the interrupt
-			 * in the before_handle_vic_irq() routine, so
-			 * clear the in progress bit here to allow the
-			 * next CPU to handle this correctly */
-			desc->status &= ~(IRQ_REPLAY | IRQ_INPROGRESS);
-		}
-#ifdef VOYAGER_DEBUG
-		isr = vic_read_isr();
-		if ((isr & (1 << irq)) != 0)
-			printk("VOYAGER SMP: after_handle_vic_irq() after "
-			       "ack irq=%d, isr=0x%x\n", irq, isr);
-#endif /* VOYAGER_DEBUG */
-	}
-	_raw_spin_unlock(&vic_irq_lock);
-
-	/* All code after this point is out of the main path - the IRQ
-	 * may be intercepted by another CPU if reasserted */
-}
-
-/* Linux processor - interrupt affinity manipulations.
- *
- * For each processor, we maintain a 32 bit irq affinity mask.
- * Initially it is set to all 1's so every processor accepts every
- * interrupt.  In this call, we change the processor's affinity mask:
- *
- * Change from enable to disable:
- *
- * If the interrupt ever comes in to the processor, we will disable it
- * and ack it to push it off to another CPU, so just accept the mask here.
- *
- * Change from disable to enable:
- *
- * change the mask and then do an interrupt enable CPI to re-enable on
- * the selected processors */
-
-void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask)
-{
-	/* Only extended processors handle interrupts */
-	unsigned long real_mask;
-	unsigned long irq_mask = 1 << irq;
-	int cpu;
-
-	real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors;
-
-	if (cpus_addr(*mask)[0] == 0)
-		/* can't have no CPUs to accept the interrupt -- extremely
-		 * bad things will happen */
-		return;
-
-	if (irq == 0)
-		/* can't change the affinity of the timer IRQ.  This
-		 * is due to the constraint in the voyager
-		 * architecture that the CPI also comes in on and IRQ
-		 * line and we have chosen IRQ0 for this.  If you
-		 * raise the mask on this interrupt, the processor
-		 * will no-longer be able to accept VIC CPIs */
-		return;
-
-	if (irq >= 32)
-		/* You can only have 32 interrupts in a voyager system
-		 * (and 32 only if you have a secondary microchannel
-		 * bus) */
-		return;
-
-	for_each_online_cpu(cpu) {
-		unsigned long cpu_mask = 1 << cpu;
-
-		if (cpu_mask & real_mask) {
-			/* enable the interrupt for this cpu */
-			cpu_irq_affinity[cpu] |= irq_mask;
-		} else {
-			/* disable the interrupt for this cpu */
-			cpu_irq_affinity[cpu] &= ~irq_mask;
-		}
-	}
-	/* this is magic, we now have the correct affinity maps, so
-	 * enable the interrupt.  This will send an enable CPI to
-	 * those CPUs who need to enable it in their local masks,
-	 * causing them to correct for the new affinity . If the
-	 * interrupt is currently globally disabled, it will simply be
-	 * disabled again as it comes in (voyager lazy disable).  If
-	 * the affinity map is tightened to disable the interrupt on a
-	 * cpu, it will be pushed off when it comes in */
-	unmask_vic_irq(irq);
-}
-
-static void ack_vic_irq(unsigned int irq)
-{
-	if (irq & 8) {
-		outb(0x62, 0x20);	/* Specific EOI to cascade */
-		outb(0x60 | (irq & 7), 0xA0);
-	} else {
-		outb(0x60 | (irq & 7), 0x20);
-	}
-}
-
-/* enable the CPIs.  In the VIC, the CPIs are delivered by the 8259
- * but are not vectored by it.  This means that the 8259 mask must be
- * lowered to receive them */
-static __init void vic_enable_cpi(void)
-{
-	__u8 cpu = smp_processor_id();
-
-	/* just take a copy of the current mask (nop for boot cpu) */
-	vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id];
-
-	enable_local_vic_irq(VIC_CPI_LEVEL0);
-	enable_local_vic_irq(VIC_CPI_LEVEL1);
-	/* for sys int and cmn int */
-	enable_local_vic_irq(7);
-
-	if (is_cpu_quad()) {
-		outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
-		outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
-		VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n",
-			cpu, QIC_CPI_ENABLE));
-	}
-
-	VDEBUG(("VOYAGER SMP: ENABLE CPI: CPU%d: MASK 0x%x\n",
-		cpu, vic_irq_mask[cpu]));
-}
-
-void voyager_smp_dump()
-{
-	int old_cpu = smp_processor_id(), cpu;
-
-	/* dump the interrupt masks of each processor */
-	for_each_online_cpu(cpu) {
-		__u16 imr, isr, irr;
-		unsigned long flags;
-
-		local_irq_save(flags);
-		outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
-		imr = (inb(0xa1) << 8) | inb(0x21);
-		outb(0x0a, 0xa0);
-		irr = inb(0xa0) << 8;
-		outb(0x0a, 0x20);
-		irr |= inb(0x20);
-		outb(0x0b, 0xa0);
-		isr = inb(0xa0) << 8;
-		outb(0x0b, 0x20);
-		isr |= inb(0x20);
-		outb(old_cpu, VIC_PROCESSOR_ID);
-		local_irq_restore(flags);
-		printk("\tCPU%d: mask=0x%x, IMR=0x%x, IRR=0x%x, ISR=0x%x\n",
-		       cpu, vic_irq_mask[cpu], imr, irr, isr);
-#if 0
-		/* These lines are put in to try to unstick an un ack'd irq */
-		if (isr != 0) {
-			int irq;
-			for (irq = 0; irq < 16; irq++) {
-				if (isr & (1 << irq)) {
-					printk("\tCPU%d: ack irq %d\n",
-					       cpu, irq);
-					local_irq_save(flags);
-					outb(VIC_CPU_MASQUERADE_ENABLE | cpu,
-					     VIC_PROCESSOR_ID);
-					ack_vic_irq(irq);
-					outb(old_cpu, VIC_PROCESSOR_ID);
-					local_irq_restore(flags);
-				}
-			}
-		}
-#endif
-	}
-}
-
-void smp_voyager_power_off(void *dummy)
-{
-	if (smp_processor_id() == boot_cpu_id)
-		voyager_power_off();
-	else
-		smp_stop_cpu_function(NULL);
-}
-
-static void __init voyager_smp_prepare_cpus(unsigned int max_cpus)
-{
-	/* FIXME: ignore max_cpus for now */
-	smp_boot_cpus();
-}
-
-static void __cpuinit voyager_smp_prepare_boot_cpu(void)
-{
-	init_gdt(smp_processor_id());
-	switch_to_new_gdt();
-
-	cpu_online_map = cpumask_of_cpu(smp_processor_id());
-	cpu_callout_map = cpumask_of_cpu(smp_processor_id());
-	cpu_callin_map = CPU_MASK_NONE;
-	cpu_present_map = cpumask_of_cpu(smp_processor_id());
-
-}
-
-static int __cpuinit voyager_cpu_up(unsigned int cpu)
-{
-	/* This only works at boot for x86.  See "rewrite" above. */
-	if (cpu_isset(cpu, smp_commenced_mask))
-		return -ENOSYS;
-
-	/* In case one didn't come up */
-	if (!cpu_isset(cpu, cpu_callin_map))
-		return -EIO;
-	/* Unleash the CPU! */
-	cpu_set(cpu, smp_commenced_mask);
-	while (!cpu_online(cpu))
-		mb();
-	return 0;
-}
-
-static void __init voyager_smp_cpus_done(unsigned int max_cpus)
-{
-	zap_low_mappings();
-}
-
-void __init smp_setup_processor_id(void)
-{
-	current_thread_info()->cpu = hard_smp_processor_id();
-	x86_write_percpu(cpu_number, hard_smp_processor_id());
-}
-
-static void voyager_send_call_func(const struct cpumask *callmask)
-{
-	__u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id());
-	send_CPI(mask, VIC_CALL_FUNCTION_CPI);
-}
-
-static void voyager_send_call_func_single(int cpu)
-{
-	send_CPI(1 << cpu, VIC_CALL_FUNCTION_SINGLE_CPI);
-}
-
-struct smp_ops smp_ops = {
-	.smp_prepare_boot_cpu = voyager_smp_prepare_boot_cpu,
-	.smp_prepare_cpus = voyager_smp_prepare_cpus,
-	.cpu_up = voyager_cpu_up,
-	.smp_cpus_done = voyager_smp_cpus_done,
-
-	.smp_send_stop = voyager_smp_send_stop,
-	.smp_send_reschedule = voyager_smp_send_reschedule,
-
-	.send_call_func_ipi = voyager_send_call_func,
-	.send_call_func_single_ipi = voyager_send_call_func_single,
-};
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_thread.c linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_thread.c
--- linux-libre-2.6.29-gnu1/arch/x86/mach-voyager/voyager_thread.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mach-voyager/voyager_thread.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* Copyright (C) 2001
- *
- * Author: J.E.J.Bottomley@HansenPartnership.com
- *
- * This module provides the machine status monitor thread for the
- * voyager architecture.  This allows us to monitor the machine
- * environment (temp, voltage, fan function) and the front panel and
- * internal UPS.  If a fault is detected, this thread takes corrective
- * action (usually just informing init)
- * */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/mc146818rtc.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/kmod.h>
-#include <linux/completion.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <asm/desc.h>
-#include <asm/voyager.h>
-#include <asm/vic.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
-
-struct task_struct *voyager_thread;
-static __u8 set_timeout;
-
-static int execute(const char *string)
-{
-	int ret;
-
-	char *envp[] = {
-		"HOME=/",
-		"TERM=linux",
-		"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
-		NULL,
-	};
-	char *argv[] = {
-		"/bin/bash",
-		"-c",
-		(char *)string,
-		NULL,
-	};
-
-	if ((ret =
-	     call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
-		printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string,
-		       ret);
-	}
-	return ret;
-}
-
-static void check_from_kernel(void)
-{
-	if (voyager_status.switch_off) {
-
-		/* FIXME: This should be configurable via proc */
-		execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
-	} else if (voyager_status.power_fail) {
-		VDEBUG(("Voyager daemon detected AC power failure\n"));
-
-		/* FIXME: This should be configureable via proc */
-		execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1");
-		set_timeout = 1;
-	}
-}
-
-static void check_continuing_condition(void)
-{
-	if (voyager_status.power_fail) {
-		__u8 data;
-		voyager_cat_psi(VOYAGER_PSI_SUBREAD,
-				VOYAGER_PSI_AC_FAIL_REG, &data);
-		if ((data & 0x1f) == 0) {
-			/* all power restored */
-			printk(KERN_NOTICE
-			       "VOYAGER AC power restored, cancelling shutdown\n");
-			/* FIXME: should be user configureable */
-			execute
-			    ("umask 600; echo O > /etc/powerstatus; kill -PWR 1");
-			set_timeout = 0;
-		}
-	}
-}
-
-static int thread(void *unused)
-{
-	printk(KERN_NOTICE "Voyager starting monitor thread\n");
-
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT);
-
-		VDEBUG(("Voyager Daemon awoken\n"));
-		if (voyager_status.request_from_kernel == 0) {
-			/* probably awoken from timeout */
-			check_continuing_condition();
-		} else {
-			check_from_kernel();
-			voyager_status.request_from_kernel = 0;
-		}
-	}
-}
-
-static int __init voyager_thread_start(void)
-{
-	voyager_thread = kthread_run(thread, NULL, "kvoyagerd");
-	if (IS_ERR(voyager_thread)) {
-		printk(KERN_ERR
-		       "Voyager: Failed to create system monitor thread.\n");
-		return PTR_ERR(voyager_thread);
-	}
-	return 0;
-}
-
-static void __exit voyager_thread_stop(void)
-{
-	kthread_stop(voyager_thread);
-}
-
-module_init(voyager_thread_start);
-module_exit(voyager_thread_stop);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/Makefile linux-libre-2.6.30-gnu1/arch/x86/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -70,14 +70,17 @@ else
         # this works around some issues with generating unwind tables in older gccs
         # newer gccs do it by default
         KBUILD_CFLAGS += -maccumulate-outgoing-args
+endif
 
-        stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh
-        stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \
-                "$(CC)" -fstack-protector )
-        stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \
-                "$(CC)" -fstack-protector-all )
-
-        KBUILD_CFLAGS += $(stackp-y)
+ifdef CONFIG_CC_STACKPROTECTOR
+	cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
+        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC)),y)
+                stackp-y := -fstack-protector
+                stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
+                KBUILD_CFLAGS += $(stackp-y)
+        else
+                $(warning stack protector enabled but no compiler support)
+        endif
 endif
 
 # Stackpointer is addressed different for 32 bit and 64 bit x86
@@ -102,29 +105,6 @@ KBUILD_CFLAGS += -fno-asynchronous-unwin
 # prevent gcc from generating any FP code by mistake
 KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
 
-###
-# Sub architecture support
-# fcore-y is linked before mcore-y files.
-
-# Default subarch .c files
-mcore-y  := arch/x86/mach-default/
-
-# Voyager subarch support
-mflags-$(CONFIG_X86_VOYAGER)	:= -Iarch/x86/include/asm/mach-voyager
-mcore-$(CONFIG_X86_VOYAGER)	:= arch/x86/mach-voyager/
-
-# generic subarchitecture
-mflags-$(CONFIG_X86_GENERICARCH):= -Iarch/x86/include/asm/mach-generic
-fcore-$(CONFIG_X86_GENERICARCH)	+= arch/x86/mach-generic/
-mcore-$(CONFIG_X86_GENERICARCH)	:= arch/x86/mach-default/
-
-# default subarch .h files
-mflags-y += -Iarch/x86/include/asm/mach-default
-
-# 64 bit does not support subarch support - clear sub arch variables
-fcore-$(CONFIG_X86_64)  :=
-mcore-$(CONFIG_X86_64)  :=
-
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 
@@ -150,9 +130,6 @@ core-$(CONFIG_LGUEST_GUEST) += arch/x86/
 core-y += arch/x86/kernel/
 core-y += arch/x86/mm/
 
-# Remaining sub architecture files
-core-y += $(mcore-y)
-
 core-y += arch/x86/crypto/
 core-y += arch/x86/vdso/
 core-$(CONFIG_IA32_EMULATION) += arch/x86/ia32/
@@ -176,34 +153,27 @@ endif
 
 boot := arch/x86/boot
 
-PHONY += zImage bzImage compressed zlilo bzlilo \
-         zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
+BOOT_TARGETS = bzlilo bzdisk fdimage fdimage144 fdimage288 isoimage
+
+PHONY += bzImage $(BOOT_TARGETS)
 
 # Default kernel to build
 all: bzImage
 
 # KBUILD_IMAGE specify target image being built
-                    KBUILD_IMAGE := $(boot)/bzImage
-zImage zlilo zdisk: KBUILD_IMAGE := $(boot)/zImage
+KBUILD_IMAGE := $(boot)/bzImage
 
-zImage bzImage: vmlinux
+bzImage: vmlinux
 	$(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/$@
 
-compressed: zImage
-
-zlilo bzlilo: vmlinux
-	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
-
-zdisk bzdisk: vmlinux
-	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
-
-fdimage fdimage144 fdimage288 isoimage: vmlinux
-	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
+$(BOOT_TARGETS): vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $@
 
+PHONY += install
 install:
-	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+	$(Q)$(MAKE) $(build)=$(boot) $@
 
 PHONY += vdso_install
 vdso_install:
@@ -228,7 +198,3 @@ define archhelp
   echo  '                  FDARGS="..."  arguments for the booted kernel'
   echo  '                  FDINITRD=file initrd for the booted kernel'
 endef
-
-CLEAN_FILES += arch/x86/boot/fdimage \
-	       arch/x86/boot/image.iso \
-	       arch/x86/boot/mtools.conf
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/math-emu/get_address.c linux-libre-2.6.30-gnu1/arch/x86/math-emu/get_address.c
--- linux-libre-2.6.29-gnu1/arch/x86/math-emu/get_address.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/math-emu/get_address.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,11 +150,9 @@ static long pm_address(u_char FPU_modrm,
 #endif /* PARANOID */
 
 	switch (segment) {
-		/* gs isn't used by the kernel, so it still has its
-		   user-space value. */
 	case PREFIX_GS_ - 1:
-		/* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
-		savesegment(gs, addr->selector);
+		/* user gs handling can be lazy, use special accessors */
+		addr->selector = get_user_gs(FPU_info->regs);
 		break;
 	default:
 		addr->selector = PM_REG_(segment);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/extable.c linux-libre-2.6.30-gnu1/arch/x86/mm/extable.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/extable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/extable.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,12 @@ int fixup_exception(struct pt_regs *regs
 
 	fixup = search_exception_tables(regs->ip);
 	if (fixup) {
+		/* If fixup is less than 16, it means uaccess error */
+		if (fixup->fixup < 16) {
+			current_thread_info()->uaccess_err = -EFAULT;
+			regs->ip += fixup->fixup;
+			return 1;
+		}
 		regs->ip = fixup->fixup;
 		return 1;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/fault.c linux-libre-2.6.30-gnu1/arch/x86/mm/fault.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/fault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/fault.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,73 +1,79 @@
 /*
  *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
+ *  Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
+ *  Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar
  */
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mmiotrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>		/* For unblank_screen() */
+#include <linux/mmiotrace.h>
+#include <linux/bootmem.h>
 #include <linux/compiler.h>
 #include <linux/highmem.h>
-#include <linux/bootmem.h>		/* for max_low_pfn */
-#include <linux/vmalloc.h>
-#include <linux/module.h>
 #include <linux/kprobes.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/vt_kern.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/module.h>
 #include <linux/kdebug.h>
+#include <linux/errno.h>
+#include <linux/magic.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/tty.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm-generic/sections.h>
 
-#include <asm/system.h>
-#include <asm/desc.h>
-#include <asm/segment.h>
-#include <asm/pgalloc.h>
-#include <asm/smp.h>
 #include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+#include <asm/segment.h>
+#include <asm/system.h>
 #include <asm/proto.h>
-#include <asm-generic/sections.h>
 #include <asm/traps.h>
+#include <asm/desc.h>
 
 /*
- * Page fault error code bits
- *	bit 0 == 0 means no page found, 1 means protection fault
- *	bit 1 == 0 means read, 1 means write
- *	bit 2 == 0 means kernel, 1 means user-mode
- *	bit 3 == 1 means use of reserved bit detected
- *	bit 4 == 1 means fault was an instruction fetch
+ * Page fault error code bits:
+ *
+ *   bit 0 ==	 0: no page found	1: protection fault
+ *   bit 1 ==	 0: read access		1: write access
+ *   bit 2 ==	 0: kernel-mode access	1: user-mode access
+ *   bit 3 ==				1: use of reserved bit detected
+ *   bit 4 ==				1: fault was an instruction fetch
  */
-#define PF_PROT		(1<<0)
-#define PF_WRITE	(1<<1)
-#define PF_USER		(1<<2)
-#define PF_RSVD		(1<<3)
-#define PF_INSTR	(1<<4)
+enum x86_pf_error_code {
 
+	PF_PROT		=		1 << 0,
+	PF_WRITE	=		1 << 1,
+	PF_USER		=		1 << 2,
+	PF_RSVD		=		1 << 3,
+	PF_INSTR	=		1 << 4,
+};
+
+/*
+ * 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)
 {
-#ifdef CONFIG_MMIOTRACE
 	if (unlikely(is_kmmio_active()))
 		if (kmmio_handler(regs, addr) == 1)
 			return -1;
-#endif
 	return 0;
 }
 
 static inline int notify_page_fault(struct pt_regs *regs)
 {
-#ifdef CONFIG_KPROBES
 	int ret = 0;
 
 	/* kprobe_running() needs smp_processor_id() */
-	if (!user_mode_vm(regs)) {
+	if (kprobes_built_in() && !user_mode_vm(regs)) {
 		preempt_disable();
 		if (kprobe_running() && kprobe_fault_handler(regs, 14))
 			ret = 1;
@@ -75,29 +81,76 @@ static inline int notify_page_fault(stru
 	}
 
 	return ret;
-#else
-	return 0;
-#endif
 }
 
 /*
- * X86_32
- * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
- * Check that here and ignore it.
+ * Prefetch quirks:
  *
- * X86_64
- * Sometimes the CPU reports invalid exceptions on prefetch.
- * Check that here and ignore it.
+ * 32-bit mode:
  *
- * Opcode checker based on code by Richard Brunner
+ *   Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
+ *   Check that here and ignore it.
+ *
+ * 64-bit mode:
+ *
+ *   Sometimes the CPU reports invalid exceptions on prefetch.
+ *   Check that here and ignore it.
+ *
+ * Opcode checker based on code by Richard Brunner.
  */
-static int is_prefetch(struct pt_regs *regs, unsigned long addr,
-		       unsigned long error_code)
+static inline int
+check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr,
+		      unsigned char opcode, int *prefetch)
 {
+	unsigned char instr_hi = opcode & 0xf0;
+	unsigned char instr_lo = opcode & 0x0f;
+
+	switch (instr_hi) {
+	case 0x20:
+	case 0x30:
+		/*
+		 * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
+		 * In X86_64 long mode, the CPU will signal invalid
+		 * opcode if some of these prefixes are present so
+		 * X86_64 will never get here anyway
+		 */
+		return ((instr_lo & 7) == 0x6);
+#ifdef CONFIG_X86_64
+	case 0x40:
+		/*
+		 * In AMD64 long mode 0x40..0x4F are valid REX prefixes
+		 * Need to figure out under what instruction mode the
+		 * instruction was issued. Could check the LDT for lm,
+		 * but for now it's good enough to assume that long
+		 * mode only uses well known segments or kernel.
+		 */
+		return (!user_mode(regs)) || (regs->cs == __USER_CS);
+#endif
+	case 0x60:
+		/* 0x64 thru 0x67 are valid prefixes in all modes. */
+		return (instr_lo & 0xC) == 0x4;
+	case 0xF0:
+		/* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
+		return !instr_lo || (instr_lo>>1) == 1;
+	case 0x00:
+		/* Prefetch instruction is 0x0F0D or 0x0F18 */
+		if (probe_kernel_address(instr, opcode))
+			return 0;
+
+		*prefetch = (instr_lo == 0xF) &&
+			(opcode == 0x0D || opcode == 0x18);
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+static int
+is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
+{
+	unsigned char *max_instr;
 	unsigned char *instr;
-	int scan_more = 1;
 	int prefetch = 0;
-	unsigned char *max_instr;
 
 	/*
 	 * If it was a exec (instruction fetch) fault on NX page, then
@@ -106,106 +159,170 @@ static int is_prefetch(struct pt_regs *r
 	if (error_code & PF_INSTR)
 		return 0;
 
-	instr = (unsigned char *)convert_ip_to_linear(current, regs);
+	instr = (void *)convert_ip_to_linear(current, regs);
 	max_instr = instr + 15;
 
 	if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
 		return 0;
 
-	while (scan_more && instr < max_instr) {
+	while (instr < max_instr) {
 		unsigned char opcode;
-		unsigned char instr_hi;
-		unsigned char instr_lo;
 
 		if (probe_kernel_address(instr, opcode))
 			break;
 
-		instr_hi = opcode & 0xf0;
-		instr_lo = opcode & 0x0f;
 		instr++;
 
-		switch (instr_hi) {
-		case 0x20:
-		case 0x30:
-			/*
-			 * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
-			 * In X86_64 long mode, the CPU will signal invalid
-			 * opcode if some of these prefixes are present so
-			 * X86_64 will never get here anyway
-			 */
-			scan_more = ((instr_lo & 7) == 0x6);
-			break;
-#ifdef CONFIG_X86_64
-		case 0x40:
-			/*
-			 * In AMD64 long mode 0x40..0x4F are valid REX prefixes
-			 * Need to figure out under what instruction mode the
-			 * instruction was issued. Could check the LDT for lm,
-			 * but for now it's good enough to assume that long
-			 * mode only uses well known segments or kernel.
-			 */
-			scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
-			break;
-#endif
-		case 0x60:
-			/* 0x64 thru 0x67 are valid prefixes in all modes. */
-			scan_more = (instr_lo & 0xC) == 0x4;
-			break;
-		case 0xF0:
-			/* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
-			scan_more = !instr_lo || (instr_lo>>1) == 1;
-			break;
-		case 0x00:
-			/* Prefetch instruction is 0x0F0D or 0x0F18 */
-			scan_more = 0;
-
-			if (probe_kernel_address(instr, opcode))
-				break;
-			prefetch = (instr_lo == 0xF) &&
-				(opcode == 0x0D || opcode == 0x18);
-			break;
-		default:
-			scan_more = 0;
+		if (!check_prefetch_opcode(regs, instr, opcode, &prefetch))
 			break;
-		}
 	}
 	return prefetch;
 }
 
-static void force_sig_info_fault(int si_signo, int si_code,
-	unsigned long address, struct task_struct *tsk)
+static void
+force_sig_info_fault(int si_signo, int si_code, unsigned long address,
+		     struct task_struct *tsk)
 {
 	siginfo_t info;
 
-	info.si_signo = si_signo;
-	info.si_errno = 0;
-	info.si_code = si_code;
-	info.si_addr = (void __user *)address;
+	info.si_signo	= si_signo;
+	info.si_errno	= 0;
+	info.si_code	= si_code;
+	info.si_addr	= (void __user *)address;
+
 	force_sig_info(si_signo, &info, tsk);
 }
 
-#ifdef CONFIG_X86_64
-static int bad_address(void *p)
+DEFINE_SPINLOCK(pgd_lock);
+LIST_HEAD(pgd_list);
+
+#ifdef CONFIG_X86_32
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
 {
-	unsigned long dummy;
-	return probe_kernel_address((unsigned long *)p, dummy);
+	unsigned index = pgd_index(address);
+	pgd_t *pgd_k;
+	pud_t *pud, *pud_k;
+	pmd_t *pmd, *pmd_k;
+
+	pgd += index;
+	pgd_k = init_mm.pgd + index;
+
+	if (!pgd_present(*pgd_k))
+		return NULL;
+
+	/*
+	 * set_pgd(pgd, *pgd_k); here would be useless on PAE
+	 * and redundant with the set_pmd() on non-PAE. As would
+	 * set_pud.
+	 */
+	pud = pud_offset(pgd, address);
+	pud_k = pud_offset(pgd_k, address);
+	if (!pud_present(*pud_k))
+		return NULL;
+
+	pmd = pmd_offset(pud, address);
+	pmd_k = pmd_offset(pud_k, address);
+	if (!pmd_present(*pmd_k))
+		return NULL;
+
+	if (!pmd_present(*pmd)) {
+		set_pmd(pmd, *pmd_k);
+		arch_flush_lazy_mmu_mode();
+	} else {
+		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+	}
+
+	return pmd_k;
+}
+
+void vmalloc_sync_all(void)
+{
+	unsigned long address;
+
+	if (SHARED_KERNEL_PMD)
+		return;
+
+	for (address = VMALLOC_START & PMD_MASK;
+	     address >= TASK_SIZE && address < FIXADDR_TOP;
+	     address += PMD_SIZE) {
+
+		unsigned long flags;
+		struct page *page;
+
+		spin_lock_irqsave(&pgd_lock, flags);
+		list_for_each_entry(page, &pgd_list, lru) {
+			if (!vmalloc_sync_one(page_address(page), address))
+				break;
+		}
+		spin_unlock_irqrestore(&pgd_lock, flags);
+	}
+}
+
+/*
+ * 32-bit:
+ *
+ *   Handle a fault on the vmalloc or module mapping area
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+	unsigned long pgd_paddr;
+	pmd_t *pmd_k;
+	pte_t *pte_k;
+
+	/* Make sure we are in vmalloc area: */
+	if (!(address >= VMALLOC_START && address < VMALLOC_END))
+		return -1;
+
+	/*
+	 * Synchronize this task's top level page-table
+	 * with the 'reference' page table.
+	 *
+	 * Do _not_ use "current" here. We might be inside
+	 * an interrupt in the middle of a task switch..
+	 */
+	pgd_paddr = read_cr3();
+	pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
+	if (!pmd_k)
+		return -1;
+
+	pte_k = pte_offset_kernel(pmd_k, address);
+	if (!pte_present(*pte_k))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Did it hit the DOS screen memory VA from vm86 mode?
+ */
+static inline void
+check_v8086_mode(struct pt_regs *regs, unsigned long address,
+		 struct task_struct *tsk)
+{
+	unsigned long bit;
+
+	if (!v8086_mode(regs))
+		return;
+
+	bit = (address - 0xA0000) >> PAGE_SHIFT;
+	if (bit < 32)
+		tsk->thread.screen_bitmap |= 1 << bit;
 }
-#endif
 
 static void dump_pagetable(unsigned long address)
 {
-#ifdef CONFIG_X86_32
 	__typeof__(pte_val(__pte(0))) page;
 
 	page = read_cr3();
 	page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
+
 #ifdef CONFIG_X86_PAE
 	printk("*pdpt = %016Lx ", page);
 	if ((page >> PAGE_SHIFT) < max_low_pfn
 	    && page & _PAGE_PRESENT) {
 		page &= PAGE_MASK;
 		page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
-		                                         & (PTRS_PER_PMD - 1)];
+							& (PTRS_PER_PMD - 1)];
 		printk(KERN_CONT "*pde = %016Lx ", page);
 		page &= ~_PAGE_NX;
 	}
@@ -217,19 +334,145 @@ static void dump_pagetable(unsigned long
 	 * We must not directly access the pte in the highpte
 	 * case if the page table is located in highmem.
 	 * And let's rather not kmap-atomic the pte, just in case
-	 * it's allocated already.
+	 * it's allocated already:
 	 */
 	if ((page >> PAGE_SHIFT) < max_low_pfn
 	    && (page & _PAGE_PRESENT)
 	    && !(page & _PAGE_PSE)) {
+
 		page &= PAGE_MASK;
 		page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
-		                                         & (PTRS_PER_PTE - 1)];
+							& (PTRS_PER_PTE - 1)];
 		printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
 	}
 
 	printk("\n");
-#else /* CONFIG_X86_64 */
+}
+
+#else /* CONFIG_X86_64: */
+
+void vmalloc_sync_all(void)
+{
+	unsigned long address;
+
+	for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;
+	     address += PGDIR_SIZE) {
+
+		const pgd_t *pgd_ref = pgd_offset_k(address);
+		unsigned long flags;
+		struct page *page;
+
+		if (pgd_none(*pgd_ref))
+			continue;
+
+		spin_lock_irqsave(&pgd_lock, flags);
+		list_for_each_entry(page, &pgd_list, lru) {
+			pgd_t *pgd;
+			pgd = (pgd_t *)page_address(page) + pgd_index(address);
+			if (pgd_none(*pgd))
+				set_pgd(pgd, *pgd_ref);
+			else
+				BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+		}
+		spin_unlock_irqrestore(&pgd_lock, flags);
+	}
+}
+
+/*
+ * 64-bit:
+ *
+ *   Handle a fault on the vmalloc area
+ *
+ * This assumes no large pages in there.
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+	pgd_t *pgd, *pgd_ref;
+	pud_t *pud, *pud_ref;
+	pmd_t *pmd, *pmd_ref;
+	pte_t *pte, *pte_ref;
+
+	/* Make sure we are in vmalloc area: */
+	if (!(address >= VMALLOC_START && address < VMALLOC_END))
+		return -1;
+
+	/*
+	 * Copy kernel mappings over when needed. This can also
+	 * happen within a race in page table update. In the later
+	 * case just flush:
+	 */
+	pgd = pgd_offset(current->active_mm, address);
+	pgd_ref = pgd_offset_k(address);
+	if (pgd_none(*pgd_ref))
+		return -1;
+
+	if (pgd_none(*pgd))
+		set_pgd(pgd, *pgd_ref);
+	else
+		BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+
+	/*
+	 * Below here mismatches are bugs because these lower tables
+	 * are shared:
+	 */
+
+	pud = pud_offset(pgd, address);
+	pud_ref = pud_offset(pgd_ref, address);
+	if (pud_none(*pud_ref))
+		return -1;
+
+	if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
+		BUG();
+
+	pmd = pmd_offset(pud, address);
+	pmd_ref = pmd_offset(pud_ref, address);
+	if (pmd_none(*pmd_ref))
+		return -1;
+
+	if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+		BUG();
+
+	pte_ref = pte_offset_kernel(pmd_ref, address);
+	if (!pte_present(*pte_ref))
+		return -1;
+
+	pte = pte_offset_kernel(pmd, address);
+
+	/*
+	 * Don't use pte_page here, because the mappings can point
+	 * outside mem_map, and the NUMA hash lookup cannot handle
+	 * that:
+	 */
+	if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
+		BUG();
+
+	return 0;
+}
+
+static const char errata93_warning[] =
+KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
+KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
+KERN_ERR "******* Please consider a BIOS update.\n"
+KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
+
+/*
+ * No vm86 mode in 64-bit mode:
+ */
+static inline void
+check_v8086_mode(struct pt_regs *regs, unsigned long address,
+		 struct task_struct *tsk)
+{
+}
+
+static int bad_address(void *p)
+{
+	unsigned long dummy;
+
+	return probe_kernel_address((unsigned long *)p, dummy);
+}
+
+static void dump_pagetable(unsigned long address)
+{
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
@@ -238,102 +481,77 @@ static void dump_pagetable(unsigned long
 	pgd = (pgd_t *)read_cr3();
 
 	pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
+
 	pgd += pgd_index(address);
-	if (bad_address(pgd)) goto bad;
+	if (bad_address(pgd))
+		goto bad;
+
 	printk("PGD %lx ", pgd_val(*pgd));
-	if (!pgd_present(*pgd)) goto ret;
+
+	if (!pgd_present(*pgd))
+		goto out;
 
 	pud = pud_offset(pgd, address);
-	if (bad_address(pud)) goto bad;
+	if (bad_address(pud))
+		goto bad;
+
 	printk("PUD %lx ", pud_val(*pud));
 	if (!pud_present(*pud) || pud_large(*pud))
-		goto ret;
+		goto out;
 
 	pmd = pmd_offset(pud, address);
-	if (bad_address(pmd)) goto bad;
+	if (bad_address(pmd))
+		goto bad;
+
 	printk("PMD %lx ", pmd_val(*pmd));
-	if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
+	if (!pmd_present(*pmd) || pmd_large(*pmd))
+		goto out;
 
 	pte = pte_offset_kernel(pmd, address);
-	if (bad_address(pte)) goto bad;
+	if (bad_address(pte))
+		goto bad;
+
 	printk("PTE %lx", pte_val(*pte));
-ret:
+out:
 	printk("\n");
 	return;
 bad:
 	printk("BAD\n");
-#endif
 }
 
-#ifdef CONFIG_X86_32
-static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
-{
-	unsigned index = pgd_index(address);
-	pgd_t *pgd_k;
-	pud_t *pud, *pud_k;
-	pmd_t *pmd, *pmd_k;
-
-	pgd += index;
-	pgd_k = init_mm.pgd + index;
-
-	if (!pgd_present(*pgd_k))
-		return NULL;
-
-	/*
-	 * set_pgd(pgd, *pgd_k); here would be useless on PAE
-	 * and redundant with the set_pmd() on non-PAE. As would
-	 * set_pud.
-	 */
-
-	pud = pud_offset(pgd, address);
-	pud_k = pud_offset(pgd_k, address);
-	if (!pud_present(*pud_k))
-		return NULL;
-
-	pmd = pmd_offset(pud, address);
-	pmd_k = pmd_offset(pud_k, address);
-	if (!pmd_present(*pmd_k))
-		return NULL;
-	if (!pmd_present(*pmd)) {
-		set_pmd(pmd, *pmd_k);
-		arch_flush_lazy_mmu_mode();
-	} else
-		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
-	return pmd_k;
-}
-#endif
-
-#ifdef CONFIG_X86_64
-static const char errata93_warning[] =
-KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
-KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
-KERN_ERR "******* Please consider a BIOS update.\n"
-KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
-#endif
+#endif /* CONFIG_X86_64 */
 
-/* Workaround for K8 erratum #93 & buggy BIOS.
-   BIOS SMM functions are required to use a specific workaround
-   to avoid corruption of the 64bit RIP register on C stepping K8.
-   A lot of BIOS that didn't get tested properly miss this.
-   The OS sees this as a page fault with the upper 32bits of RIP cleared.
-   Try to work around it here.
-   Note we only handle faults in kernel here.
-   Does nothing for X86_32
+/*
+ * Workaround for K8 erratum #93 & buggy BIOS.
+ *
+ * BIOS SMM functions are required to use a specific workaround
+ * to avoid corruption of the 64bit RIP register on C stepping K8.
+ *
+ * A lot of BIOS that didn't get tested properly miss this.
+ *
+ * The OS sees this as a page fault with the upper 32bits of RIP cleared.
+ * Try to work around it here.
+ *
+ * Note we only handle faults in kernel here.
+ * Does nothing on 32-bit.
  */
 static int is_errata93(struct pt_regs *regs, unsigned long address)
 {
 #ifdef CONFIG_X86_64
-	static int warned;
+	static int once;
+
 	if (address != regs->ip)
 		return 0;
+
 	if ((address >> 32) != 0)
 		return 0;
+
 	address |= 0xffffffffUL << 32;
 	if ((address >= (u64)_stext && address <= (u64)_etext) ||
 	    (address >= MODULES_VADDR && address <= MODULES_END)) {
-		if (!warned) {
+		if (!once) {
 			printk(errata93_warning);
-			warned = 1;
+			once = 1;
 		}
 		regs->ip = address;
 		return 1;
@@ -343,16 +561,17 @@ static int is_errata93(struct pt_regs *r
 }
 
 /*
- * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal
- * addresses >4GB.  We catch this in the page fault handler because these
- * addresses are not reachable. Just detect this case and return.  Any code
+ * Work around K8 erratum #100 K8 in compat mode occasionally jumps
+ * to illegal addresses >4GB.
+ *
+ * We catch this in the page fault handler because these addresses
+ * are not reachable. Just detect this case and return.  Any code
  * segment in LDT is compatibility mode.
  */
 static int is_errata100(struct pt_regs *regs, unsigned long address)
 {
 #ifdef CONFIG_X86_64
-	if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
-	    (address >> 32))
+	if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
 		return 1;
 #endif
 	return 0;
@@ -362,8 +581,9 @@ static int is_f00f_bug(struct pt_regs *r
 {
 #ifdef CONFIG_X86_F00F_BUG
 	unsigned long nr;
+
 	/*
-	 * Pentium F0 0F C7 C8 bug workaround.
+	 * Pentium F0 0F C7 C8 bug workaround:
 	 */
 	if (boot_cpu_data.f00f_bug) {
 		nr = (address - idt_descr.address) >> 3;
@@ -377,62 +597,277 @@ static int is_f00f_bug(struct pt_regs *r
 	return 0;
 }
 
-static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
-			    unsigned long address)
+static const char nx_warning[] = KERN_CRIT
+"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
+
+static void
+show_fault_oops(struct pt_regs *regs, unsigned long error_code,
+		unsigned long address)
 {
-#ifdef CONFIG_X86_32
 	if (!oops_may_print())
 		return;
-#endif
 
-#ifdef CONFIG_X86_PAE
 	if (error_code & PF_INSTR) {
 		unsigned int level;
+
 		pte_t *pte = lookup_address(address, &level);
 
 		if (pte && pte_present(*pte) && !pte_exec(*pte))
-			printk(KERN_CRIT "kernel tried to execute "
-				"NX-protected page - exploit attempt? "
-				"(uid: %d)\n", current_uid());
+			printk(nx_warning, current_uid());
 	}
-#endif
 
 	printk(KERN_ALERT "BUG: unable to handle kernel ");
 	if (address < PAGE_SIZE)
 		printk(KERN_CONT "NULL pointer dereference");
 	else
 		printk(KERN_CONT "paging request");
+
 	printk(KERN_CONT " at %p\n", (void *) address);
 	printk(KERN_ALERT "IP:");
 	printk_address(regs->ip, 1);
+
 	dump_pagetable(address);
 }
 
-#ifdef CONFIG_X86_64
-static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
-				 unsigned long error_code)
+static noinline void
+pgtable_bad(struct pt_regs *regs, unsigned long error_code,
+	    unsigned long address)
 {
-	unsigned long flags = oops_begin();
-	int sig = SIGKILL;
 	struct task_struct *tsk;
+	unsigned long flags;
+	int sig;
+
+	flags = oops_begin();
+	tsk = current;
+	sig = SIGKILL;
 
 	printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
-	       current->comm, address);
+	       tsk->comm, address);
 	dump_pagetable(address);
-	tsk = current;
-	tsk->thread.cr2 = address;
-	tsk->thread.trap_no = 14;
-	tsk->thread.error_code = error_code;
+
+	tsk->thread.cr2		= address;
+	tsk->thread.trap_no	= 14;
+	tsk->thread.error_code	= error_code;
+
 	if (__die("Bad pagetable", regs, error_code))
 		sig = 0;
+
 	oops_end(flags, regs, sig);
 }
-#endif
+
+static noinline void
+no_context(struct pt_regs *regs, unsigned long error_code,
+	   unsigned long address)
+{
+	struct task_struct *tsk = current;
+	unsigned long *stackend;
+	unsigned long flags;
+	int sig;
+
+	/* Are we prepared to handle this kernel fault? */
+	if (fixup_exception(regs))
+		return;
+
+	/*
+	 * 32-bit:
+	 *
+	 *   Valid to do another page fault here, because if this fault
+	 *   had been triggered by is_prefetch fixup_exception would have
+	 *   handled it.
+	 *
+	 * 64-bit:
+	 *
+	 *   Hall of shame of CPU/BIOS bugs.
+	 */
+	if (is_prefetch(regs, error_code, address))
+		return;
+
+	if (is_errata93(regs, address))
+		return;
+
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice:
+	 */
+	flags = oops_begin();
+
+	show_fault_oops(regs, error_code, address);
+
+	stackend = end_of_stack(tsk);
+	if (*stackend != STACK_END_MAGIC)
+		printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+
+	tsk->thread.cr2		= address;
+	tsk->thread.trap_no	= 14;
+	tsk->thread.error_code	= error_code;
+
+	sig = SIGKILL;
+	if (__die("Oops", regs, error_code))
+		sig = 0;
+
+	/* Executive summary in case the body of the oops scrolled away */
+	printk(KERN_EMERG "CR2: %016lx\n", address);
+
+	oops_end(flags, regs, sig);
+}
+
+/*
+ * Print out info about fatal segfaults, if the show_unhandled_signals
+ * sysctl is set:
+ */
+static inline void
+show_signal_msg(struct pt_regs *regs, unsigned long error_code,
+		unsigned long address, struct task_struct *tsk)
+{
+	if (!unhandled_signal(tsk, SIGSEGV))
+		return;
+
+	if (!printk_ratelimit())
+		return;
+
+	printk(KERN_CONT "%s%s[%d]: segfault at %lx ip %p sp %p error %lx",
+		task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+		tsk->comm, task_pid_nr(tsk), address,
+		(void *)regs->ip, (void *)regs->sp, error_code);
+
+	print_vma_addr(KERN_CONT " in ", regs->ip);
+
+	printk(KERN_CONT "\n");
+}
+
+static void
+__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
+		       unsigned long address, int si_code)
+{
+	struct task_struct *tsk = current;
+
+	/* User mode accesses just cause a SIGSEGV */
+	if (error_code & PF_USER) {
+		/*
+		 * It's possible to have interrupts off here:
+		 */
+		local_irq_enable();
+
+		/*
+		 * Valid to do another page fault here because this one came
+		 * from user space:
+		 */
+		if (is_prefetch(regs, error_code, address))
+			return;
+
+		if (is_errata100(regs, address))
+			return;
+
+		if (unlikely(show_unhandled_signals))
+			show_signal_msg(regs, error_code, address, tsk);
+
+		/* Kernel addresses are always protection faults: */
+		tsk->thread.cr2		= address;
+		tsk->thread.error_code	= error_code | (address >= TASK_SIZE);
+		tsk->thread.trap_no	= 14;
+
+		force_sig_info_fault(SIGSEGV, si_code, address, tsk);
+
+		return;
+	}
+
+	if (is_f00f_bug(regs, address))
+		return;
+
+	no_context(regs, error_code, address);
+}
+
+static noinline void
+bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
+		     unsigned long address)
+{
+	__bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR);
+}
+
+static void
+__bad_area(struct pt_regs *regs, unsigned long error_code,
+	   unsigned long address, int si_code)
+{
+	struct mm_struct *mm = current->mm;
+
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
+	up_read(&mm->mmap_sem);
+
+	__bad_area_nosemaphore(regs, error_code, address, si_code);
+}
+
+static noinline void
+bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+{
+	__bad_area(regs, error_code, address, SEGV_MAPERR);
+}
+
+static noinline void
+bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
+		      unsigned long address)
+{
+	__bad_area(regs, error_code, address, SEGV_ACCERR);
+}
+
+/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */
+static void
+out_of_memory(struct pt_regs *regs, unsigned long error_code,
+	      unsigned long address)
+{
+	/*
+	 * We ran out of memory, call the OOM killer, and return the userspace
+	 * (which will retry the fault, or kill us if we got oom-killed):
+	 */
+	up_read(&current->mm->mmap_sem);
+
+	pagefault_out_of_memory();
+}
+
+static void
+do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+{
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+
+	up_read(&mm->mmap_sem);
+
+	/* Kernel mode? Handle exceptions or die: */
+	if (!(error_code & PF_USER))
+		no_context(regs, error_code, address);
+
+	/* User-space => ok to do another page fault: */
+	if (is_prefetch(regs, error_code, address))
+		return;
+
+	tsk->thread.cr2		= address;
+	tsk->thread.error_code	= error_code;
+	tsk->thread.trap_no	= 14;
+
+	force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
+}
+
+static noinline void
+mm_fault_error(struct pt_regs *regs, unsigned long error_code,
+	       unsigned long address, unsigned int fault)
+{
+	if (fault & VM_FAULT_OOM) {
+		out_of_memory(regs, error_code, address);
+	} else {
+		if (fault & VM_FAULT_SIGBUS)
+			do_sigbus(regs, error_code, address);
+		else
+			BUG();
+	}
+}
 
 static int spurious_fault_check(unsigned long error_code, pte_t *pte)
 {
 	if ((error_code & PF_WRITE) && !pte_write(*pte))
 		return 0;
+
 	if ((error_code & PF_INSTR) && !pte_exec(*pte))
 		return 0;
 
@@ -440,21 +875,25 @@ static int spurious_fault_check(unsigned
 }
 
 /*
- * Handle a spurious fault caused by a stale TLB entry.  This allows
- * us to lazily refresh the TLB when increasing the permissions of a
- * kernel page (RO -> RW or NX -> X).  Doing it eagerly is very
- * expensive since that implies doing a full cross-processor TLB
- * flush, even if no stale TLB entries exist on other processors.
+ * Handle a spurious fault caused by a stale TLB entry.
+ *
+ * This allows us to lazily refresh the TLB when increasing the
+ * permissions of a kernel page (RO -> RW or NX -> X).  Doing it
+ * eagerly is very expensive since that implies doing a full
+ * cross-processor TLB flush, even if no stale TLB entries exist
+ * on other processors.
+ *
  * There are no security implications to leaving a stale TLB when
  * increasing the permissions on a page.
  */
-static int spurious_fault(unsigned long address,
-			  unsigned long error_code)
+static noinline int
+spurious_fault(unsigned long error_code, unsigned long address)
 {
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
+	int ret;
 
 	/* Reserved-bit violation or user access to kernel space? */
 	if (error_code & (PF_USER | PF_RSVD))
@@ -482,127 +921,71 @@ static int spurious_fault(unsigned long
 	if (!pte_present(*pte))
 		return 0;
 
-	return spurious_fault_check(error_code, pte);
-}
-
-/*
- * X86_32
- * Handle a fault on the vmalloc or module mapping area
- *
- * X86_64
- * Handle a fault on the vmalloc area
- *
- * This assumes no large pages in there.
- */
-static int vmalloc_fault(unsigned long address)
-{
-#ifdef CONFIG_X86_32
-	unsigned long pgd_paddr;
-	pmd_t *pmd_k;
-	pte_t *pte_k;
-
-	/* Make sure we are in vmalloc area */
-	if (!(address >= VMALLOC_START && address < VMALLOC_END))
-		return -1;
+	ret = spurious_fault_check(error_code, pte);
+	if (!ret)
+		return 0;
 
 	/*
-	 * Synchronize this task's top level page-table
-	 * with the 'reference' page table.
-	 *
-	 * Do _not_ use "current" here. We might be inside
-	 * an interrupt in the middle of a task switch..
+	 * Make sure we have permissions in PMD.
+	 * If not, then there's a bug in the page tables:
 	 */
-	pgd_paddr = read_cr3();
-	pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
-	if (!pmd_k)
-		return -1;
-	pte_k = pte_offset_kernel(pmd_k, address);
-	if (!pte_present(*pte_k))
-		return -1;
-	return 0;
-#else
-	pgd_t *pgd, *pgd_ref;
-	pud_t *pud, *pud_ref;
-	pmd_t *pmd, *pmd_ref;
-	pte_t *pte, *pte_ref;
+	ret = spurious_fault_check(error_code, (pte_t *) pmd);
+	WARN_ONCE(!ret, "PMD has incorrect permission bits\n");
 
-	/* Make sure we are in vmalloc area */
-	if (!(address >= VMALLOC_START && address < VMALLOC_END))
-		return -1;
+	return ret;
+}
 
-	/* Copy kernel mappings over when needed. This can also
-	   happen within a race in page table update. In the later
-	   case just flush. */
+int show_unhandled_signals = 1;
 
-	pgd = pgd_offset(current->active_mm, address);
-	pgd_ref = pgd_offset_k(address);
-	if (pgd_none(*pgd_ref))
-		return -1;
-	if (pgd_none(*pgd))
-		set_pgd(pgd, *pgd_ref);
-	else
-		BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+static inline int
+access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
+{
+	if (write) {
+		/* write, present and write, not present: */
+		if (unlikely(!(vma->vm_flags & VM_WRITE)))
+			return 1;
+		return 0;
+	}
 
-	/* Below here mismatches are bugs because these lower tables
-	   are shared */
+	/* read, present: */
+	if (unlikely(error_code & PF_PROT))
+		return 1;
+
+	/* read, not present: */
+	if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))))
+		return 1;
 
-	pud = pud_offset(pgd, address);
-	pud_ref = pud_offset(pgd_ref, address);
-	if (pud_none(*pud_ref))
-		return -1;
-	if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
-		BUG();
-	pmd = pmd_offset(pud, address);
-	pmd_ref = pmd_offset(pud_ref, address);
-	if (pmd_none(*pmd_ref))
-		return -1;
-	if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
-		BUG();
-	pte_ref = pte_offset_kernel(pmd_ref, address);
-	if (!pte_present(*pte_ref))
-		return -1;
-	pte = pte_offset_kernel(pmd, address);
-	/* Don't use pte_page here, because the mappings can point
-	   outside mem_map, and the NUMA hash lookup cannot handle
-	   that. */
-	if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
-		BUG();
 	return 0;
-#endif
 }
 
-int show_unhandled_signals = 1;
+static int fault_in_kernel_space(unsigned long address)
+{
+	return address >= TASK_SIZE_MAX;
+}
 
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-#ifdef CONFIG_X86_64
-asmlinkage
-#endif
-void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
+dotraplinkage void __kprobes
+do_page_fault(struct pt_regs *regs, unsigned long error_code)
 {
-	struct task_struct *tsk;
-	struct mm_struct *mm;
 	struct vm_area_struct *vma;
+	struct task_struct *tsk;
 	unsigned long address;
-	int write, si_code;
+	struct mm_struct *mm;
+	int write;
 	int fault;
-#ifdef CONFIG_X86_64
-	unsigned long flags;
-	int sig;
-#endif
 
 	tsk = current;
 	mm = tsk->mm;
+
 	prefetchw(&mm->mmap_sem);
 
-	/* get the address */
+	/* Get the faulting address: */
 	address = read_cr2();
 
-	si_code = SEGV_MAPERR;
-
 	if (unlikely(kmmio_fault(regs, address)))
 		return;
 
@@ -619,319 +1002,147 @@ void __kprobes do_page_fault(struct pt_r
 	 * (error_code & 4) == 0, and that the fault was not a
 	 * protection error (error_code & 9) == 0.
 	 */
-#ifdef CONFIG_X86_32
-	if (unlikely(address >= TASK_SIZE)) {
-#else
-	if (unlikely(address >= TASK_SIZE64)) {
-#endif
+	if (unlikely(fault_in_kernel_space(address))) {
 		if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
 		    vmalloc_fault(address) >= 0)
 			return;
 
-		/* Can handle a stale RO->RW TLB */
-		if (spurious_fault(address, error_code))
+		/* Can handle a stale RO->RW TLB: */
+		if (spurious_fault(error_code, address))
 			return;
 
-		/* kprobes don't want to hook the spurious faults. */
+		/* kprobes don't want to hook the spurious faults: */
 		if (notify_page_fault(regs))
 			return;
 		/*
 		 * Don't take the mm semaphore here. If we fixup a prefetch
-		 * fault we could otherwise deadlock.
+		 * fault we could otherwise deadlock:
 		 */
-		goto bad_area_nosemaphore;
-	}
+		bad_area_nosemaphore(regs, error_code, address);
 
-	/* kprobes don't want to hook the spurious faults. */
-	if (notify_page_fault(regs))
 		return;
+	}
 
+	/* kprobes don't want to hook the spurious faults: */
+	if (unlikely(notify_page_fault(regs)))
+		return;
 	/*
 	 * It's safe to allow irq's after cr2 has been saved and the
 	 * vmalloc fault has been handled.
 	 *
 	 * User-mode registers count as a user access even for any
-	 * potential system fault or CPU buglet.
+	 * potential system fault or CPU buglet:
 	 */
 	if (user_mode_vm(regs)) {
 		local_irq_enable();
 		error_code |= PF_USER;
-	} else if (regs->flags & X86_EFLAGS_IF)
-		local_irq_enable();
+	} else {
+		if (regs->flags & X86_EFLAGS_IF)
+			local_irq_enable();
+	}
 
-#ifdef CONFIG_X86_64
 	if (unlikely(error_code & PF_RSVD))
-		pgtable_bad(address, regs, error_code);
-#endif
+		pgtable_bad(regs, error_code, address);
 
 	/*
-	 * If we're in an interrupt, have no user context or are running in an
-	 * atomic region then we must not take the fault.
+	 * If we're in an interrupt, have no user context or are running
+	 * in an atomic region then we must not take the fault:
 	 */
-	if (unlikely(in_atomic() || !mm))
-		goto bad_area_nosemaphore;
+	if (unlikely(in_atomic() || !mm)) {
+		bad_area_nosemaphore(regs, error_code, address);
+		return;
+	}
 
 	/*
 	 * When running in the kernel we expect faults to occur only to
-	 * addresses in user space.  All other faults represent errors in the
-	 * kernel and should generate an OOPS.  Unfortunately, in the case of an
-	 * erroneous fault occurring in a code path which already holds mmap_sem
-	 * we will deadlock attempting to validate the fault against the
-	 * address space.  Luckily the kernel only validly references user
-	 * space from well defined areas of code, which are listed in the
-	 * exceptions table.
+	 * addresses in user space.  All other faults represent errors in
+	 * the kernel and should generate an OOPS.  Unfortunately, in the
+	 * case of an erroneous fault occurring in a code path which already
+	 * holds mmap_sem we will deadlock attempting to validate the fault
+	 * against the address space.  Luckily the kernel only validly
+	 * references user space from well defined areas of code, which are
+	 * listed in the exceptions table.
 	 *
 	 * As the vast majority of faults will be valid we will only perform
-	 * the source reference check when there is a possibility of a deadlock.
-	 * Attempt to lock the address space, if we cannot we then validate the
-	 * source.  If this is invalid we can skip the address space check,
-	 * thus avoiding the deadlock.
+	 * the source reference check when there is a possibility of a
+	 * deadlock. Attempt to lock the address space, if we cannot we then
+	 * validate the source. If this is invalid we can skip the address
+	 * space check, thus avoiding the deadlock:
 	 */
-	if (!down_read_trylock(&mm->mmap_sem)) {
+	if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
 		if ((error_code & PF_USER) == 0 &&
-		    !search_exception_tables(regs->ip))
-			goto bad_area_nosemaphore;
+		    !search_exception_tables(regs->ip)) {
+			bad_area_nosemaphore(regs, error_code, address);
+			return;
+		}
 		down_read(&mm->mmap_sem);
+	} else {
+		/*
+		 * The above down_read_trylock() might have succeeded in
+		 * which case we'll have missed the might_sleep() from
+		 * down_read():
+		 */
+		might_sleep();
 	}
 
 	vma = find_vma(mm, address);
-	if (!vma)
-		goto bad_area;
-	if (vma->vm_start <= address)
+	if (unlikely(!vma)) {
+		bad_area(regs, error_code, address);
+		return;
+	}
+	if (likely(vma->vm_start <= address))
 		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN))
-		goto bad_area;
+	if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
+		bad_area(regs, error_code, address);
+		return;
+	}
 	if (error_code & PF_USER) {
 		/*
 		 * Accessing the stack below %sp is always a bug.
 		 * The large cushion allows instructions like enter
-		 * and pusha to work.  ("enter $65535,$31" pushes
+		 * and pusha to work. ("enter $65535, $31" pushes
 		 * 32 pointers and then decrements %sp by 65535.)
 		 */
-		if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
-			goto bad_area;
+		if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
+			bad_area(regs, error_code, address);
+			return;
+		}
 	}
-	if (expand_stack(vma, address))
-		goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
+	if (unlikely(expand_stack(vma, address))) {
+		bad_area(regs, error_code, address);
+		return;
+	}
+
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
 good_area:
-	si_code = SEGV_ACCERR;
-	write = 0;
-	switch (error_code & (PF_PROT|PF_WRITE)) {
-	default:	/* 3: write, present */
-		/* fall through */
-	case PF_WRITE:		/* write, not present */
-		if (!(vma->vm_flags & VM_WRITE))
-			goto bad_area;
-		write++;
-		break;
-	case PF_PROT:		/* read, present */
-		goto bad_area;
-	case 0:			/* read, not present */
-		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
-			goto bad_area;
+	write = error_code & PF_WRITE;
+
+	if (unlikely(access_error(error_code, write, vma))) {
+		bad_area_access_error(regs, error_code, address);
+		return;
 	}
 
 	/*
 	 * If for any reason at all we couldn't handle the fault,
 	 * make sure we exit gracefully rather than endlessly redo
-	 * the fault.
+	 * the fault:
 	 */
 	fault = handle_mm_fault(mm, vma, address, write);
+
 	if (unlikely(fault & VM_FAULT_ERROR)) {
-		if (fault & VM_FAULT_OOM)
-			goto out_of_memory;
-		else if (fault & VM_FAULT_SIGBUS)
-			goto do_sigbus;
-		BUG();
+		mm_fault_error(regs, error_code, address, fault);
+		return;
 	}
+
 	if (fault & VM_FAULT_MAJOR)
 		tsk->maj_flt++;
 	else
 		tsk->min_flt++;
 
-#ifdef CONFIG_X86_32
-	/*
-	 * Did it hit the DOS screen memory VA from vm86 mode?
-	 */
-	if (v8086_mode(regs)) {
-		unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
-		if (bit < 32)
-			tsk->thread.screen_bitmap |= 1 << bit;
-	}
-#endif
-	up_read(&mm->mmap_sem);
-	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:
-	up_read(&mm->mmap_sem);
-
-bad_area_nosemaphore:
-	/* User mode accesses just cause a SIGSEGV */
-	if (error_code & PF_USER) {
-		/*
-		 * It's possible to have interrupts off here.
-		 */
-		local_irq_enable();
-
-		/*
-		 * Valid to do another page fault here because this one came
-		 * from user space.
-		 */
-		if (is_prefetch(regs, address, error_code))
-			return;
-
-		if (is_errata100(regs, address))
-			return;
-
-		if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
-		    printk_ratelimit()) {
-			printk(
-			"%s%s[%d]: segfault at %lx ip %p sp %p error %lx",
-			task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-			tsk->comm, task_pid_nr(tsk), address,
-			(void *) regs->ip, (void *) regs->sp, error_code);
-			print_vma_addr(" in ", regs->ip);
-			printk("\n");
-		}
-
-		tsk->thread.cr2 = address;
-		/* Kernel addresses are always protection faults */
-		tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-		tsk->thread.trap_no = 14;
-		force_sig_info_fault(SIGSEGV, si_code, address, tsk);
-		return;
-	}
-
-	if (is_f00f_bug(regs, address))
-		return;
-
-no_context:
-	/* Are we prepared to handle this kernel fault?  */
-	if (fixup_exception(regs))
-		return;
-
-	/*
-	 * X86_32
-	 * Valid to do another page fault here, because if this fault
-	 * had been triggered by is_prefetch fixup_exception would have
-	 * handled it.
-	 *
-	 * X86_64
-	 * Hall of shame of CPU/BIOS bugs.
-	 */
-	if (is_prefetch(regs, address, error_code))
-		return;
-
-	if (is_errata93(regs, address))
-		return;
-
-/*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
-#ifdef CONFIG_X86_32
-	bust_spinlocks(1);
-#else
-	flags = oops_begin();
-#endif
-
-	show_fault_oops(regs, error_code, address);
-
-	tsk->thread.cr2 = address;
-	tsk->thread.trap_no = 14;
-	tsk->thread.error_code = error_code;
-
-#ifdef CONFIG_X86_32
-	die("Oops", regs, error_code);
-	bust_spinlocks(0);
-	do_exit(SIGKILL);
-#else
-	sig = SIGKILL;
-	if (__die("Oops", regs, error_code))
-		sig = 0;
-	/* Executive summary in case the body of the oops scrolled away */
-	printk(KERN_EMERG "CR2: %016lx\n", address);
-	oops_end(flags, regs, sig);
-#endif
-
-out_of_memory:
-	/*
-	 * We ran out of memory, call the OOM killer, and return the userspace
-	 * (which will retry the fault, or kill us if we got oom-killed).
-	 */
-	up_read(&mm->mmap_sem);
-	pagefault_out_of_memory();
-	return;
+	check_v8086_mode(regs, address, tsk);
 
-do_sigbus:
 	up_read(&mm->mmap_sem);
-
-	/* Kernel mode? Handle exceptions or die */
-	if (!(error_code & PF_USER))
-		goto no_context;
-#ifdef CONFIG_X86_32
-	/* User space => ok to do another page fault */
-	if (is_prefetch(regs, address, error_code))
-		return;
-#endif
-	tsk->thread.cr2 = address;
-	tsk->thread.error_code = error_code;
-	tsk->thread.trap_no = 14;
-	force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
-}
-
-DEFINE_SPINLOCK(pgd_lock);
-LIST_HEAD(pgd_list);
-
-void vmalloc_sync_all(void)
-{
-	unsigned long address;
-
-#ifdef CONFIG_X86_32
-	if (SHARED_KERNEL_PMD)
-		return;
-
-	for (address = VMALLOC_START & PMD_MASK;
-	     address >= TASK_SIZE && address < FIXADDR_TOP;
-	     address += PMD_SIZE) {
-		unsigned long flags;
-		struct page *page;
-
-		spin_lock_irqsave(&pgd_lock, flags);
-		list_for_each_entry(page, &pgd_list, lru) {
-			if (!vmalloc_sync_one(page_address(page),
-					      address))
-				break;
-		}
-		spin_unlock_irqrestore(&pgd_lock, flags);
-	}
-#else /* CONFIG_X86_64 */
-	for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;
-	     address += PGDIR_SIZE) {
-		const pgd_t *pgd_ref = pgd_offset_k(address);
-		unsigned long flags;
-		struct page *page;
-
-		if (pgd_none(*pgd_ref))
-			continue;
-		spin_lock_irqsave(&pgd_lock, flags);
-		list_for_each_entry(page, &pgd_list, lru) {
-			pgd_t *pgd;
-			pgd = (pgd_t *)page_address(page) + pgd_index(address);
-			if (pgd_none(*pgd))
-				set_pgd(pgd, *pgd_ref);
-			else
-				BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
-		}
-		spin_unlock_irqrestore(&pgd_lock, flags);
-	}
-#endif
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/gup.c linux-libre-2.6.30-gnu1/arch/x86/mm/gup.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/gup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/gup.c	2009-06-09 23:05:27.000000000 -0400
@@ -219,6 +219,22 @@ static int gup_pud_range(pgd_t pgd, unsi
 	return 1;
 }
 
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start:	starting user address
+ * @nr_pages:	number of pages from start to pin
+ * @write:	whether pages will be written to
+ * @pages:	array that receives pointers to the pages pinned.
+ * 		Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
 int get_user_pages_fast(unsigned long start, int nr_pages, int write,
 			struct page **pages)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/highmem_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/highmem_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/highmem_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/highmem_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
+#include <linux/swap.h> /* for totalram_pages */
 
 void *kmap(struct page *page)
 {
@@ -18,49 +19,6 @@ void kunmap(struct page *page)
 	kunmap_high(page);
 }
 
-static void debug_kmap_atomic_prot(enum km_type type)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
-	static unsigned warn_count = 10;
-
-	if (unlikely(warn_count == 0))
-		return;
-
-	if (unlikely(in_interrupt())) {
-		if (in_irq()) {
-			if (type != KM_IRQ0 && type != KM_IRQ1 &&
-			    type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
-			    type != KM_BOUNCE_READ) {
-				WARN_ON(1);
-				warn_count--;
-			}
-		} else if (!irqs_disabled()) {	/* softirq */
-			if (type != KM_IRQ0 && type != KM_IRQ1 &&
-			    type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
-			    type != KM_SKB_SUNRPC_DATA &&
-			    type != KM_SKB_DATA_SOFTIRQ &&
-			    type != KM_BOUNCE_READ) {
-				WARN_ON(1);
-				warn_count--;
-			}
-		}
-	}
-
-	if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
-			type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
-		if (!irqs_disabled()) {
-			WARN_ON(1);
-			warn_count--;
-		}
-	} else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
-		if (irq_count() == 0 && !irqs_disabled()) {
-			WARN_ON(1);
-			warn_count--;
-		}
-	}
-#endif
-}
-
 /*
  * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
  * no global lock is needed and because the kmap code must perform a global TLB
@@ -80,7 +38,7 @@ void *kmap_atomic_prot(struct page *page
 	if (!PageHighMem(page))
 		return page_address(page);
 
-	debug_kmap_atomic_prot(type);
+	debug_kmap_atomic(type);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
@@ -120,22 +78,13 @@ void kunmap_atomic(void *kvaddr, enum km
 	pagefault_enable();
 }
 
-/* This is the same as kmap_atomic() but can map memory that doesn't
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
  * have a struct page associated with it.
  */
 void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
 {
-	enum fixed_addresses idx;
-	unsigned long vaddr;
-
-	pagefault_disable();
-
-	idx = type + KM_TYPE_NR*smp_processor_id();
-	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
-	arch_flush_lazy_mmu_mode();
-
-	return (void*) vaddr;
+	return kmap_atomic_prot_pfn(pfn, type, kmap_prot);
 }
 EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */
 
@@ -156,3 +105,27 @@ EXPORT_SYMBOL(kmap);
 EXPORT_SYMBOL(kunmap);
 EXPORT_SYMBOL(kmap_atomic);
 EXPORT_SYMBOL(kunmap_atomic);
+
+void __init set_highmem_pages_init(void)
+{
+	struct zone *zone;
+	int nid;
+
+	for_each_zone(zone) {
+		unsigned long zone_start_pfn, zone_end_pfn;
+
+		if (!is_highmem(zone))
+			continue;
+
+		zone_start_pfn = zone->zone_start_pfn;
+		zone_end_pfn = zone_start_pfn + zone->spanned_pages;
+
+		nid = zone_to_nid(zone);
+		printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n",
+				zone->name, nid, zone_start_pfn, zone_end_pfn);
+
+		add_highpages_with_active_regions(nid, zone_start_pfn,
+				 zone_end_pfn);
+	}
+	totalram_pages += totalhigh_pages;
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/hugetlbpage.c linux-libre-2.6.30-gnu1/arch/x86/mm/hugetlbpage.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/hugetlbpage.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/hugetlbpage.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,12 +26,16 @@ static unsigned long page_table_shareabl
 	unsigned long sbase = saddr & PUD_MASK;
 	unsigned long s_end = sbase + PUD_SIZE;
 
+	/* Allow segments to share if only one is marked locked */
+	unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED;
+	unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED;
+
 	/*
 	 * match the virtual addresses, permission and the alignment of the
 	 * page table page.
 	 */
 	if (pmd_index(addr) != pmd_index(saddr) ||
-	    vma->vm_flags != svma->vm_flags ||
+	    vm_flags != svm_flags ||
 	    sbase < svma->vm_start || svma->vm_end < s_end)
 		return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/init_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/init_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/init_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/init_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,9 +49,7 @@
 #include <asm/paravirt.h>
 #include <asm/setup.h>
 #include <asm/cacheflush.h>
-#include <asm/smp.h>
-
-unsigned int __VMALLOC_RESERVE = 128 << 20;
+#include <asm/init.h>
 
 unsigned long max_low_pfn_mapped;
 unsigned long max_pfn_mapped;
@@ -61,19 +59,14 @@ unsigned long highstart_pfn, highend_pfn
 
 static noinline int do_test_wp_bit(void);
 
-
-static unsigned long __initdata table_start;
-static unsigned long __meminitdata table_end;
-static unsigned long __meminitdata table_top;
-
-static int __initdata after_init_bootmem;
+bool __read_mostly __vmalloc_start_set = false;
 
 static __init void *alloc_low_page(void)
 {
-	unsigned long pfn = table_end++;
+	unsigned long pfn = e820_table_end++;
 	void *adr;
 
-	if (pfn >= table_top)
+	if (pfn >= e820_table_top)
 		panic("alloc_low_page: ran out of memory");
 
 	adr = __va(pfn * PAGE_SIZE);
@@ -93,7 +86,7 @@ static pmd_t * __init one_md_table_init(
 
 #ifdef CONFIG_X86_PAE
 	if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
-		if (after_init_bootmem)
+		if (after_bootmem)
 			pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
 		else
 			pmd_table = (pmd_t *)alloc_low_page();
@@ -120,7 +113,7 @@ static pte_t * __init one_page_table_ini
 	if (!(pmd_val(*pmd) & _PAGE_PRESENT)) {
 		pte_t *page_table = NULL;
 
-		if (after_init_bootmem) {
+		if (after_bootmem) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
 			page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
 #endif
@@ -138,6 +131,23 @@ static pte_t * __init one_page_table_ini
 	return pte_offset_kernel(pmd, 0);
 }
 
+pmd_t * __init populate_extra_pmd(unsigned long vaddr)
+{
+	int pgd_idx = pgd_index(vaddr);
+	int pmd_idx = pmd_index(vaddr);
+
+	return one_md_table_init(swapper_pg_dir + pgd_idx) + pmd_idx;
+}
+
+pte_t * __init populate_extra_pte(unsigned long vaddr)
+{
+	int pte_idx = pte_index(vaddr);
+	pmd_t *pmd;
+
+	pmd = populate_extra_pmd(vaddr);
+	return one_page_table_init(pmd) + pte_idx;
+}
+
 static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd,
 					   unsigned long vaddr, pte_t *lastpte)
 {
@@ -154,12 +164,12 @@ static pte_t *__init page_table_kmap_che
 	if (pmd_idx_kmap_begin != pmd_idx_kmap_end
 	    && (vaddr >> PMD_SHIFT) >= pmd_idx_kmap_begin
 	    && (vaddr >> PMD_SHIFT) <= pmd_idx_kmap_end
-	    && ((__pa(pte) >> PAGE_SHIFT) < table_start
-		|| (__pa(pte) >> PAGE_SHIFT) >= table_end)) {
+	    && ((__pa(pte) >> PAGE_SHIFT) < e820_table_start
+		|| (__pa(pte) >> PAGE_SHIFT) >= e820_table_end)) {
 		pte_t *newpte;
 		int i;
 
-		BUG_ON(after_init_bootmem);
+		BUG_ON(after_bootmem);
 		newpte = alloc_low_page();
 		for (i = 0; i < PTRS_PER_PTE; i++)
 			set_pte(newpte + i, pte[i]);
@@ -228,11 +238,14 @@ static inline int is_kernel_text(unsigne
  * of max_low_pfn pages, by creating page tables starting from address
  * PAGE_OFFSET:
  */
-static void __init kernel_physical_mapping_init(pgd_t *pgd_base,
-						unsigned long start_pfn,
-						unsigned long end_pfn,
-						int use_pse)
+unsigned long __init
+kernel_physical_mapping_init(unsigned long start,
+			     unsigned long end,
+			     unsigned long page_size_mask)
 {
+	int use_pse = page_size_mask == (1<<PG_LEVEL_2M);
+	unsigned long start_pfn, end_pfn;
+	pgd_t *pgd_base = swapper_pg_dir;
 	int pgd_idx, pmd_idx, pte_ofs;
 	unsigned long pfn;
 	pgd_t *pgd;
@@ -241,6 +254,9 @@ static void __init kernel_physical_mappi
 	unsigned pages_2m, pages_4k;
 	int mapping_iter;
 
+	start_pfn = start >> PAGE_SHIFT;
+	end_pfn = end >> PAGE_SHIFT;
+
 	/*
 	 * First iteration will setup identity mapping using large/small pages
 	 * based on use_pse, with other attributes same as set by
@@ -355,26 +371,6 @@ repeat:
 		mapping_iter = 2;
 		goto repeat;
 	}
-}
-
-/*
- * devmem_is_allowed() checks to see if /dev/mem access to a certain address
- * is valid. The argument is a physical page number.
- *
- *
- * On x86, access has to be given to the first megabyte of ram because that area
- * contains bios code and data regions used by X and dosemu and similar apps.
- * Access has to be given to non-kernel-ram areas as well, these contain the PCI
- * mmio resources as well as potential bios/acpi data regions.
- */
-int devmem_is_allowed(unsigned long pagenr)
-{
-	if (pagenr <= 256)
-		return 1;
-	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
-		return 0;
-	if (!page_is_ram(pagenr))
-		return 1;
 	return 0;
 }
 
@@ -470,22 +466,10 @@ void __init add_highpages_with_active_re
 	work_with_active_regions(nid, add_highpages_work_fn, &data);
 }
 
-#ifndef CONFIG_NUMA
-static void __init set_highmem_pages_init(void)
-{
-	add_highpages_with_active_regions(0, highstart_pfn, highend_pfn);
-
-	totalram_pages += totalhigh_pages;
-}
-#endif /* !CONFIG_NUMA */
-
 #else
 static inline void permanent_kmaps_init(pgd_t *pgd_base)
 {
 }
-static inline void set_highmem_pages_init(void)
-{
-}
 #endif /* CONFIG_HIGHMEM */
 
 void __init native_pagetable_setup_start(pgd_t *base)
@@ -543,8 +527,9 @@ void __init native_pagetable_setup_done(
  * be partially populated, and so it avoids stomping on any existing
  * mappings.
  */
-static void __init early_ioremap_page_table_range_init(pgd_t *pgd_base)
+void __init early_ioremap_page_table_range_init(void)
 {
+	pgd_t *pgd_base = swapper_pg_dir;
 	unsigned long vaddr, end;
 
 	/*
@@ -639,7 +624,7 @@ static int __init noexec_setup(char *str
 }
 early_param("noexec", noexec_setup);
 
-static void __init set_nx(void)
+void __init set_nx(void)
 {
 	unsigned int v[4], l, h;
 
@@ -675,75 +660,97 @@ static int __init parse_highmem(char *ar
 }
 early_param("highmem", parse_highmem);
 
+#define MSG_HIGHMEM_TOO_BIG \
+	"highmem size (%luMB) is bigger than pages available (%luMB)!\n"
+
+#define MSG_LOWMEM_TOO_SMALL \
+	"highmem size (%luMB) results in <64MB lowmem, ignoring it!\n"
 /*
- * Determine low and high memory ranges:
+ * All of RAM fits into lowmem - but if user wants highmem
+ * artificially via the highmem=x boot parameter then create
+ * it:
  */
-void __init find_low_pfn_range(void)
+void __init lowmem_pfn_init(void)
 {
-	/* it could update max_pfn */
-
 	/* max_low_pfn is 0, we already have early_res support */
-
 	max_low_pfn = max_pfn;
-	if (max_low_pfn > MAXMEM_PFN) {
-		if (highmem_pages == -1)
-			highmem_pages = max_pfn - MAXMEM_PFN;
-		if (highmem_pages + MAXMEM_PFN < max_pfn)
-			max_pfn = MAXMEM_PFN + highmem_pages;
-		if (highmem_pages + MAXMEM_PFN > max_pfn) {
-			printk(KERN_WARNING "only %luMB highmem pages "
-				"available, ignoring highmem size of %uMB.\n",
-				pages_to_mb(max_pfn - MAXMEM_PFN),
+
+	if (highmem_pages == -1)
+		highmem_pages = 0;
+#ifdef CONFIG_HIGHMEM
+	if (highmem_pages >= max_pfn) {
+		printk(KERN_ERR MSG_HIGHMEM_TOO_BIG,
+			pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
+		highmem_pages = 0;
+	}
+	if (highmem_pages) {
+		if (max_low_pfn - highmem_pages < 64*1024*1024/PAGE_SIZE) {
+			printk(KERN_ERR MSG_LOWMEM_TOO_SMALL,
 				pages_to_mb(highmem_pages));
 			highmem_pages = 0;
 		}
-		max_low_pfn = MAXMEM_PFN;
+		max_low_pfn -= highmem_pages;
+	}
+#else
+	if (highmem_pages)
+		printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
+#endif
+}
+
+#define MSG_HIGHMEM_TOO_SMALL \
+	"only %luMB highmem pages available, ignoring highmem size of %luMB!\n"
+
+#define MSG_HIGHMEM_TRIMMED \
+	"Warning: only 4GB will be used. Use a HIGHMEM64G enabled kernel!\n"
+/*
+ * We have more RAM than fits into lowmem - we try to put it into
+ * highmem, also taking the highmem=x boot parameter into account:
+ */
+void __init highmem_pfn_init(void)
+{
+	max_low_pfn = MAXMEM_PFN;
+
+	if (highmem_pages == -1)
+		highmem_pages = max_pfn - MAXMEM_PFN;
+
+	if (highmem_pages + MAXMEM_PFN < max_pfn)
+		max_pfn = MAXMEM_PFN + highmem_pages;
+
+	if (highmem_pages + MAXMEM_PFN > max_pfn) {
+		printk(KERN_WARNING MSG_HIGHMEM_TOO_SMALL,
+			pages_to_mb(max_pfn - MAXMEM_PFN),
+			pages_to_mb(highmem_pages));
+		highmem_pages = 0;
+	}
 #ifndef CONFIG_HIGHMEM
-		/* Maximum memory usable is what is directly addressable */
-		printk(KERN_WARNING "Warning only %ldMB will be used.\n",
-					MAXMEM>>20);
-		if (max_pfn > MAX_NONPAE_PFN)
-			printk(KERN_WARNING
-				 "Use a HIGHMEM64G enabled kernel.\n");
-		else
-			printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
-		max_pfn = MAXMEM_PFN;
+	/* Maximum memory usable is what is directly addressable */
+	printk(KERN_WARNING "Warning only %ldMB will be used.\n", MAXMEM>>20);
+	if (max_pfn > MAX_NONPAE_PFN)
+		printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n");
+	else
+		printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
+	max_pfn = MAXMEM_PFN;
 #else /* !CONFIG_HIGHMEM */
 #ifndef CONFIG_HIGHMEM64G
-		if (max_pfn > MAX_NONPAE_PFN) {
-			max_pfn = MAX_NONPAE_PFN;
-			printk(KERN_WARNING "Warning only 4GB will be used."
-				"Use a HIGHMEM64G enabled kernel.\n");
-		}
+	if (max_pfn > MAX_NONPAE_PFN) {
+		max_pfn = MAX_NONPAE_PFN;
+		printk(KERN_WARNING MSG_HIGHMEM_TRIMMED);
+	}
 #endif /* !CONFIG_HIGHMEM64G */
 #endif /* !CONFIG_HIGHMEM */
-	} else {
-		if (highmem_pages == -1)
-			highmem_pages = 0;
-#ifdef CONFIG_HIGHMEM
-		if (highmem_pages >= max_pfn) {
-			printk(KERN_ERR "highmem size specified (%uMB) is "
-				"bigger than pages available (%luMB)!.\n",
-				pages_to_mb(highmem_pages),
-				pages_to_mb(max_pfn));
-			highmem_pages = 0;
-		}
-		if (highmem_pages) {
-			if (max_low_pfn - highmem_pages <
-			    64*1024*1024/PAGE_SIZE){
-				printk(KERN_ERR "highmem size %uMB results in "
-				"smaller than 64MB lowmem, ignoring it.\n"
-					, pages_to_mb(highmem_pages));
-				highmem_pages = 0;
-			}
-			max_low_pfn -= highmem_pages;
-		}
-#else
-		if (highmem_pages)
-			printk(KERN_ERR "ignoring highmem size on non-highmem"
-					" kernel!\n");
-#endif
-	}
+}
+
+/*
+ * Determine low and high memory ranges:
+ */
+void __init find_low_pfn_range(void)
+{
+	/* it could update max_pfn */
+
+	if (max_pfn <= MAXMEM_PFN)
+		lowmem_pfn_init();
+	else
+		highmem_pfn_init();
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
@@ -769,6 +776,8 @@ void __init initmem_init(unsigned long s
 #ifdef CONFIG_FLATMEM
 	max_mapnr = num_physpages;
 #endif
+	__vmalloc_start_set = true;
+
 	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
 			pages_to_mb(max_low_pfn));
 
@@ -790,176 +799,66 @@ static void __init zone_sizes_init(void)
 	free_area_init_nodes(max_zone_pfns);
 }
 
+static unsigned long __init setup_node_bootmem(int nodeid,
+				 unsigned long start_pfn,
+				 unsigned long end_pfn,
+				 unsigned long bootmap)
+{
+	unsigned long bootmap_size;
+
+	/* don't touch min_low_pfn */
+	bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
+					 bootmap >> PAGE_SHIFT,
+					 start_pfn, end_pfn);
+	printk(KERN_INFO "  node %d low ram: %08lx - %08lx\n",
+		nodeid, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+	printk(KERN_INFO "  node %d bootmap %08lx - %08lx\n",
+		 nodeid, bootmap, bootmap + bootmap_size);
+	free_bootmem_with_active_regions(nodeid, end_pfn);
+	early_res_to_bootmem(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+
+	return bootmap + bootmap_size;
+}
+
 void __init setup_bootmem_allocator(void)
 {
-	int i;
+	int nodeid;
 	unsigned long bootmap_size, bootmap;
 	/*
 	 * Initialize the boot-time allocator (with low memory only):
 	 */
 	bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
-	bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT,
-				 max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
+	bootmap = find_e820_area(0, max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
 				 PAGE_SIZE);
 	if (bootmap == -1L)
 		panic("Cannot find bootmem map of size %ld\n", bootmap_size);
 	reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
 
-	/* don't touch min_low_pfn */
-	bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap >> PAGE_SHIFT,
-					 min_low_pfn, max_low_pfn);
 	printk(KERN_INFO "  mapped low ram: 0 - %08lx\n",
 		 max_pfn_mapped<<PAGE_SHIFT);
-	printk(KERN_INFO "  low ram: %08lx - %08lx\n",
-		 min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT);
-	printk(KERN_INFO "  bootmap %08lx - %08lx\n",
-		 bootmap, bootmap + bootmap_size);
-	for_each_online_node(i)
-		free_bootmem_with_active_regions(i, max_low_pfn);
-	early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
-
-	after_init_bootmem = 1;
-}
-
-static void __init find_early_table_space(unsigned long end, int use_pse)
-{
-	unsigned long puds, pmds, ptes, tables, start;
-
-	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-	tables = PAGE_ALIGN(puds * sizeof(pud_t));
-
-	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
-	tables += PAGE_ALIGN(pmds * sizeof(pmd_t));
-
-	if (use_pse) {
-		unsigned long extra;
-
-		extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
-		extra += PMD_SIZE;
-		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	} else
-		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-	tables += PAGE_ALIGN(ptes * sizeof(pte_t));
-
-	/* for fixmap */
-	tables += PAGE_ALIGN(__end_of_fixed_addresses * sizeof(pte_t));
-
-	/*
-	 * RED-PEN putting page tables only on node 0 could
-	 * cause a hotspot and fill up ZONE_DMA. The page tables
-	 * need roughly 0.5KB per GB.
-	 */
-	start = 0x7000;
-	table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
-					tables, PAGE_SIZE);
-	if (table_start == -1UL)
-		panic("Cannot find space for the kernel page tables");
-
-	table_start >>= PAGE_SHIFT;
-	table_end = table_start;
-	table_top = table_start + (tables>>PAGE_SHIFT);
+	printk(KERN_INFO "  low ram: 0 - %08lx\n", max_low_pfn<<PAGE_SHIFT);
 
-	printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
-		end, table_start << PAGE_SHIFT,
-		(table_start << PAGE_SHIFT) + tables);
-}
+	for_each_online_node(nodeid) {
+		 unsigned long start_pfn, end_pfn;
 
-unsigned long __init_refok init_memory_mapping(unsigned long start,
-						unsigned long end)
-{
-	pgd_t *pgd_base = swapper_pg_dir;
-	unsigned long start_pfn, end_pfn;
-	unsigned long big_page_start;
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	/*
-	 * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages.
-	 * This will simplify cpa(), which otherwise needs to support splitting
-	 * large pages into small in interrupt context, etc.
-	 */
-	int use_pse = 0;
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+		start_pfn = node_start_pfn[nodeid];
+		end_pfn = node_end_pfn[nodeid];
+		if (start_pfn > max_low_pfn)
+			continue;
+		if (end_pfn > max_low_pfn)
+			end_pfn = max_low_pfn;
 #else
-	int use_pse = cpu_has_pse;
-#endif
-
-	/*
-	 * Find space for the kernel direct mapping tables.
-	 */
-	if (!after_init_bootmem)
-		find_early_table_space(end, use_pse);
-
-#ifdef CONFIG_X86_PAE
-	set_nx();
-	if (nx_enabled)
-		printk(KERN_INFO "NX (Execute Disable) protection: active\n");
+		start_pfn = 0;
+		end_pfn = max_low_pfn;
 #endif
-
-	/* Enable PSE if available */
-	if (cpu_has_pse)
-		set_in_cr4(X86_CR4_PSE);
-
-	/* Enable PGE if available */
-	if (cpu_has_pge) {
-		set_in_cr4(X86_CR4_PGE);
-		__supported_pte_mask |= _PAGE_GLOBAL;
-	}
-
-	/*
-	 * Don't use a large page for the first 2/4MB of memory
-	 * because there are often fixed size MTRRs in there
-	 * and overlapping MTRRs into large pages can cause
-	 * slowdowns.
-	 */
-	big_page_start = PMD_SIZE;
-
-	if (start < big_page_start) {
-		start_pfn = start >> PAGE_SHIFT;
-		end_pfn = min(big_page_start>>PAGE_SHIFT, end>>PAGE_SHIFT);
-	} else {
-		/* head is not big page alignment ? */
-		start_pfn = start >> PAGE_SHIFT;
-		end_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT)
-				 << (PMD_SHIFT - PAGE_SHIFT);
-	}
-	if (start_pfn < end_pfn)
-		kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn, 0);
-
-	/* big page range */
-	start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT)
-			 << (PMD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < (big_page_start >> PAGE_SHIFT))
-		start_pfn =  big_page_start >> PAGE_SHIFT;
-	end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < end_pfn)
-		kernel_physical_mapping_init(pgd_base, start_pfn, end_pfn,
-					     use_pse);
-
-	/* tail is not big page alignment ? */
-	start_pfn = end_pfn;
-	if (start_pfn > (big_page_start>>PAGE_SHIFT)) {
-		end_pfn = end >> PAGE_SHIFT;
-		if (start_pfn < end_pfn)
-			kernel_physical_mapping_init(pgd_base, start_pfn,
-							 end_pfn, 0);
+		bootmap = setup_node_bootmem(nodeid, start_pfn, end_pfn,
+						 bootmap);
 	}
 
-	early_ioremap_page_table_range_init(pgd_base);
-
-	load_cr3(swapper_pg_dir);
-
-	__flush_tlb_all();
-
-	if (!after_init_bootmem)
-		reserve_early(table_start << PAGE_SHIFT,
-				 table_end << PAGE_SHIFT, "PGTABLE");
-
-	if (!after_init_bootmem)
-		early_memtest(start, end);
-
-	return end >> PAGE_SHIFT;
+	after_bootmem = 1;
 }
 
-
 /*
  * paging_init() sets up the page tables - note that the first 8MB are
  * already mapped by head.S.
@@ -1155,17 +1054,47 @@ 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;
+
+void set_kernel_text_rw(void)
+{
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long size = PFN_ALIGN(_etext) - start;
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read write\n",
+		 start, start+size);
+
+	set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
+void set_kernel_text_ro(void)
+{
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long size = PFN_ALIGN(_etext) - start;
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read only\n",
+		 start, start+size);
+
+	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
 void mark_rodata_ro(void)
 {
 	unsigned long start = PFN_ALIGN(_text);
 	unsigned long size = PFN_ALIGN(_etext) - start;
 
-#ifndef CONFIG_DYNAMIC_FTRACE
-	/* Dynamic tracing modifies the kernel text section */
 	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
 	printk(KERN_INFO "Write protecting the kernel text: %luk\n",
 		size >> 10);
 
+	kernel_set_to_readonly = 1;
+
 #ifdef CONFIG_CPA_DEBUG
 	printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
 		start, start+size);
@@ -1174,7 +1103,6 @@ void mark_rodata_ro(void)
 	printk(KERN_INFO "Testing CPA: write protecting again\n");
 	set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
 #endif
-#endif /* CONFIG_DYNAMIC_FTRACE */
 
 	start += size;
 	size = (unsigned long)__end_rodata - start;
@@ -1193,52 +1121,6 @@ void mark_rodata_ro(void)
 }
 #endif
 
-void free_init_pages(char *what, unsigned long begin, unsigned long end)
-{
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	/*
-	 * If debugging page accesses then do not free this memory but
-	 * mark them not present - any buggy init-section access will
-	 * create a kernel page fault:
-	 */
-	printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-		begin, PAGE_ALIGN(end));
-	set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-#else
-	unsigned long addr;
-
-	/*
-	 * We just marked the kernel text read only above, now that
-	 * we are going to free part of that, we need to make that
-	 * writeable first.
-	 */
-	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
-
-	for (addr = begin; addr < end; addr += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-		init_page_count(virt_to_page(addr));
-		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
-		free_page(addr);
-		totalram_pages++;
-	}
-	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
-#endif
-}
-
-void free_initmem(void)
-{
-	free_init_pages("unused kernel memory",
-			(unsigned long)(&__init_begin),
-			(unsigned long)(&__init_end));
-}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
-{
-	free_init_pages("initrd memory", start, end);
-}
-#endif
-
 int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
 				   int flags)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/init_64.c linux-libre-2.6.30-gnu1/arch/x86/mm/init_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/init_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/init_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,7 @@
 #include <asm/kdebug.h>
 #include <asm/numa.h>
 #include <asm/cacheflush.h>
+#include <asm/init.h>
 
 /*
  * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -61,12 +62,6 @@ static unsigned long dma_reserve __initd
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-int direct_gbpages
-#ifdef CONFIG_DIRECT_GBPAGES
-				= 1
-#endif
-;
-
 static int __init parse_direct_gbpages_off(char *arg)
 {
 	direct_gbpages = 0;
@@ -87,12 +82,10 @@ early_param("gbpages", parse_direct_gbpa
  * around without checking the pgd every time.
  */
 
-int after_bootmem;
-
 pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
 EXPORT_SYMBOL_GPL(__supported_pte_mask);
 
-static int do_not_nx __cpuinitdata;
+static int disable_nx __cpuinitdata;
 
 /*
  * noexec=on|off
@@ -107,9 +100,9 @@ static int __init nonx_setup(char *str)
 		return -EINVAL;
 	if (!strncmp(str, "on", 2)) {
 		__supported_pte_mask |= _PAGE_NX;
-		do_not_nx = 0;
+		disable_nx = 0;
 	} else if (!strncmp(str, "off", 3)) {
-		do_not_nx = 1;
+		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
 	}
 	return 0;
@@ -121,7 +114,7 @@ void __cpuinit check_efer(void)
 	unsigned long efer;
 
 	rdmsrl(MSR_EFER, efer);
-	if (!(efer & EFER_NX) || do_not_nx)
+	if (!(efer & EFER_NX) || disable_nx)
 		__supported_pte_mask &= ~_PAGE_NX;
 }
 
@@ -168,34 +161,51 @@ static __ref void *spp_getpage(void)
 	return ptr;
 }
 
-void
-set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte)
+static pud_t *fill_pud(pgd_t *pgd, unsigned long vaddr)
 {
-	pud_t *pud;
-	pmd_t *pmd;
-	pte_t *pte;
+	if (pgd_none(*pgd)) {
+		pud_t *pud = (pud_t *)spp_getpage();
+		pgd_populate(&init_mm, pgd, pud);
+		if (pud != pud_offset(pgd, 0))
+			printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n",
+			       pud, pud_offset(pgd, 0));
+	}
+	return pud_offset(pgd, vaddr);
+}
 
-	pud = pud_page + pud_index(vaddr);
+static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr)
+{
 	if (pud_none(*pud)) {
-		pmd = (pmd_t *) spp_getpage();
+		pmd_t *pmd = (pmd_t *) spp_getpage();
 		pud_populate(&init_mm, pud, pmd);
-		if (pmd != pmd_offset(pud, 0)) {
+		if (pmd != pmd_offset(pud, 0))
 			printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
-				pmd, pmd_offset(pud, 0));
-			return;
-		}
+			       pmd, pmd_offset(pud, 0));
 	}
-	pmd = pmd_offset(pud, vaddr);
+	return pmd_offset(pud, vaddr);
+}
+
+static pte_t *fill_pte(pmd_t *pmd, unsigned long vaddr)
+{
 	if (pmd_none(*pmd)) {
-		pte = (pte_t *) spp_getpage();
+		pte_t *pte = (pte_t *) spp_getpage();
 		pmd_populate_kernel(&init_mm, pmd, pte);
-		if (pte != pte_offset_kernel(pmd, 0)) {
+		if (pte != pte_offset_kernel(pmd, 0))
 			printk(KERN_ERR "PAGETABLE BUG #02!\n");
-			return;
-		}
 	}
+	return pte_offset_kernel(pmd, vaddr);
+}
+
+void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte)
+{
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	pud = pud_page + pud_index(vaddr);
+	pmd = fill_pmd(pud, vaddr);
+	pte = fill_pte(pmd, vaddr);
 
-	pte = pte_offset_kernel(pmd, vaddr);
 	set_pte(pte, new_pte);
 
 	/*
@@ -205,8 +215,7 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
 	__flush_tlb_one(vaddr);
 }
 
-void
-set_pte_vaddr(unsigned long vaddr, pte_t pteval)
+void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
 {
 	pgd_t *pgd;
 	pud_t *pud_page;
@@ -223,6 +232,24 @@ set_pte_vaddr(unsigned long vaddr, pte_t
 	set_pte_vaddr_pud(pud_page, vaddr, pteval);
 }
 
+pmd_t * __init populate_extra_pmd(unsigned long vaddr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+
+	pgd = pgd_offset_k(vaddr);
+	pud = fill_pud(pgd, vaddr);
+	return fill_pmd(pud, vaddr);
+}
+
+pte_t * __init populate_extra_pte(unsigned long vaddr)
+{
+	pmd_t *pmd;
+
+	pmd = populate_extra_pmd(vaddr);
+	return fill_pte(pmd, vaddr);
+}
+
 /*
  * Create large page table mappings for a range of physical addresses.
  */
@@ -291,13 +318,9 @@ void __init cleanup_highmap(void)
 	}
 }
 
-static unsigned long __initdata table_start;
-static unsigned long __meminitdata table_end;
-static unsigned long __meminitdata table_top;
-
 static __ref void *alloc_low_page(unsigned long *phys)
 {
-	unsigned long pfn = table_end++;
+	unsigned long pfn = e820_table_end++;
 	void *adr;
 
 	if (after_bootmem) {
@@ -307,7 +330,7 @@ static __ref void *alloc_low_page(unsign
 		return adr;
 	}
 
-	if (pfn >= table_top)
+	if (pfn >= e820_table_top)
 		panic("alloc_low_page: ran out of memory");
 
 	adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
@@ -547,58 +570,10 @@ phys_pud_update(pgd_t *pgd, unsigned lon
 	return phys_pud_init(pud, addr, end, page_size_mask);
 }
 
-static void __init find_early_table_space(unsigned long end, int use_pse,
-					  int use_gbpages)
-{
-	unsigned long puds, pmds, ptes, tables, start;
-
-	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-	tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
-	if (use_gbpages) {
-		unsigned long extra;
-		extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
-		pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
-	} else
-		pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
-	tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
-
-	if (use_pse) {
-		unsigned long extra;
-		extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
-		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	} else
-		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
-
-	/*
-	 * RED-PEN putting page tables only on node 0 could
-	 * cause a hotspot and fill up ZONE_DMA. The page tables
-	 * need roughly 0.5KB per GB.
-	 */
-	start = 0x8000;
-	table_start = find_e820_area(start, end, tables, PAGE_SIZE);
-	if (table_start == -1UL)
-		panic("Cannot find space for the kernel page tables");
-
-	table_start >>= PAGE_SHIFT;
-	table_end = table_start;
-	table_top = table_start + (tables >> PAGE_SHIFT);
-
-	printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
-		end, table_start << PAGE_SHIFT, table_top << PAGE_SHIFT);
-}
-
-static void __init init_gbpages(void)
-{
-	if (direct_gbpages && cpu_has_gbpages)
-		printk(KERN_INFO "Using GB pages for direct mapping\n");
-	else
-		direct_gbpages = 0;
-}
-
-static unsigned long __meminit kernel_physical_mapping_init(unsigned long start,
-						unsigned long end,
-						unsigned long page_size_mask)
+unsigned long __init
+kernel_physical_mapping_init(unsigned long start,
+			     unsigned long end,
+			     unsigned long page_size_mask)
 {
 
 	unsigned long next, last_map_addr = end;
@@ -635,176 +610,6 @@ static unsigned long __meminit kernel_ph
 	return last_map_addr;
 }
 
-struct map_range {
-	unsigned long start;
-	unsigned long end;
-	unsigned page_size_mask;
-};
-
-#define NR_RANGE_MR 5
-
-static int save_mr(struct map_range *mr, int nr_range,
-		   unsigned long start_pfn, unsigned long end_pfn,
-		   unsigned long page_size_mask)
-{
-
-	if (start_pfn < end_pfn) {
-		if (nr_range >= NR_RANGE_MR)
-			panic("run out of range for init_memory_mapping\n");
-		mr[nr_range].start = start_pfn<<PAGE_SHIFT;
-		mr[nr_range].end   = end_pfn<<PAGE_SHIFT;
-		mr[nr_range].page_size_mask = page_size_mask;
-		nr_range++;
-	}
-
-	return nr_range;
-}
-
-/*
- * Setup the direct mapping of the physical memory at PAGE_OFFSET.
- * This runs before bootmem is initialized and gets pages directly from
- * the physical memory. To access them they are temporarily mapped.
- */
-unsigned long __init_refok init_memory_mapping(unsigned long start,
-					       unsigned long end)
-{
-	unsigned long last_map_addr = 0;
-	unsigned long page_size_mask = 0;
-	unsigned long start_pfn, end_pfn;
-	unsigned long pos;
-
-	struct map_range mr[NR_RANGE_MR];
-	int nr_range, i;
-	int use_pse, use_gbpages;
-
-	printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end);
-
-	/*
-	 * Find space for the kernel direct mapping tables.
-	 *
-	 * Later we should allocate these tables in the local node of the
-	 * memory mapped. Unfortunately this is done currently before the
-	 * nodes are discovered.
-	 */
-	if (!after_bootmem)
-		init_gbpages();
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	/*
-	 * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages.
-	 * This will simplify cpa(), which otherwise needs to support splitting
-	 * large pages into small in interrupt context, etc.
-	 */
-	use_pse = use_gbpages = 0;
-#else
-	use_pse = cpu_has_pse;
-	use_gbpages = direct_gbpages;
-#endif
-
-	if (use_gbpages)
-		page_size_mask |= 1 << PG_LEVEL_1G;
-	if (use_pse)
-		page_size_mask |= 1 << PG_LEVEL_2M;
-
-	memset(mr, 0, sizeof(mr));
-	nr_range = 0;
-
-	/* head if not big page alignment ?*/
-	start_pfn = start >> PAGE_SHIFT;
-	pos = start_pfn << PAGE_SHIFT;
-	end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT)
-			<< (PMD_SHIFT - PAGE_SHIFT);
-	if (end_pfn > (end >> PAGE_SHIFT))
-		end_pfn = end >> PAGE_SHIFT;
-	if (start_pfn < end_pfn) {
-		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
-		pos = end_pfn << PAGE_SHIFT;
-	}
-
-	/* big page (2M) range*/
-	start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
-			 << (PMD_SHIFT - PAGE_SHIFT);
-	end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
-			 << (PUD_SHIFT - PAGE_SHIFT);
-	if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)))
-		end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT));
-	if (start_pfn < end_pfn) {
-		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
-				page_size_mask & (1<<PG_LEVEL_2M));
-		pos = end_pfn << PAGE_SHIFT;
-	}
-
-	/* big page (1G) range */
-	start_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
-			 << (PUD_SHIFT - PAGE_SHIFT);
-	end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < end_pfn) {
-		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
-				page_size_mask &
-				 ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G)));
-		pos = end_pfn << PAGE_SHIFT;
-	}
-
-	/* tail is not big page (1G) alignment */
-	start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
-			 << (PMD_SHIFT - PAGE_SHIFT);
-	end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
-	if (start_pfn < end_pfn) {
-		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
-				page_size_mask & (1<<PG_LEVEL_2M));
-		pos = end_pfn << PAGE_SHIFT;
-	}
-
-	/* tail is not big page (2M) alignment */
-	start_pfn = pos>>PAGE_SHIFT;
-	end_pfn = end>>PAGE_SHIFT;
-	nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
-
-	/* try to merge same page size and continuous */
-	for (i = 0; nr_range > 1 && i < nr_range - 1; i++) {
-		unsigned long old_start;
-		if (mr[i].end != mr[i+1].start ||
-		    mr[i].page_size_mask != mr[i+1].page_size_mask)
-			continue;
-		/* move it */
-		old_start = mr[i].start;
-		memmove(&mr[i], &mr[i+1],
-			 (nr_range - 1 - i) * sizeof (struct map_range));
-		mr[i--].start = old_start;
-		nr_range--;
-	}
-
-	for (i = 0; i < nr_range; i++)
-		printk(KERN_DEBUG " %010lx - %010lx page %s\n",
-				mr[i].start, mr[i].end,
-			(mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
-			 (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
-
-	if (!after_bootmem)
-		find_early_table_space(end, use_pse, use_gbpages);
-
-	for (i = 0; i < nr_range; i++)
-		last_map_addr = kernel_physical_mapping_init(
-					mr[i].start, mr[i].end,
-					mr[i].page_size_mask);
-
-	if (!after_bootmem)
-		mmu_cr4_features = read_cr4();
-	__flush_tlb_all();
-
-	if (!after_bootmem && table_end > table_start)
-		reserve_early(table_start << PAGE_SHIFT,
-				 table_end << PAGE_SHIFT, "PGTABLE");
-
-	printk(KERN_INFO "last_map_addr: %lx end: %lx\n",
-			 last_map_addr, end);
-
-	if (!after_bootmem)
-		early_memtest(start, end);
-
-	return last_map_addr >> PAGE_SHIFT;
-}
-
 #ifndef CONFIG_NUMA
 void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -876,28 +681,6 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
 
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
-/*
- * devmem_is_allowed() checks to see if /dev/mem access to a certain address
- * is valid. The argument is a physical page number.
- *
- *
- * On x86, access has to be given to the first megabyte of ram because that area
- * contains bios code and data regions used by X and dosemu and similar apps.
- * Access has to be given to non-kernel-ram areas as well, these contain the PCI
- * mmio resources as well as potential bios/acpi data regions.
- */
-int devmem_is_allowed(unsigned long pagenr)
-{
-	if (pagenr <= 256)
-		return 1;
-	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
-		return 0;
-	if (!page_is_ram(pagenr))
-		return 1;
-	return 0;
-}
-
-
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
 			 kcore_modules, kcore_vsyscall;
 
@@ -947,46 +730,39 @@ void __init mem_init(void)
 		initsize >> 10);
 }
 
-void free_init_pages(char *what, unsigned long begin, unsigned long end)
+#ifdef CONFIG_DEBUG_RODATA
+const int rodata_test_data = 0xC3;
+EXPORT_SYMBOL_GPL(rodata_test_data);
+
+static int kernel_set_to_readonly;
+
+void set_kernel_text_rw(void)
 {
-	unsigned long addr = begin;
+	unsigned long start = PFN_ALIGN(_stext);
+	unsigned long end = PFN_ALIGN(__start_rodata);
 
-	if (addr >= end)
+	if (!kernel_set_to_readonly)
 		return;
 
-	/*
-	 * If debugging page accesses then do not free this memory but
-	 * mark them not present - any buggy init-section access will
-	 * create a kernel page fault:
-	 */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
-		begin, PAGE_ALIGN(end));
-	set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
-#else
-	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
+	pr_debug("Set kernel text: %lx - %lx for read write\n",
+		 start, end);
 
-	for (; addr < end; addr += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-		init_page_count(virt_to_page(addr));
-		memset((void *)(addr & ~(PAGE_SIZE-1)),
-			POISON_FREE_INITMEM, PAGE_SIZE);
-		free_page(addr);
-		totalram_pages++;
-	}
-#endif
+	set_memory_rw(start, (end - start) >> PAGE_SHIFT);
 }
 
-void free_initmem(void)
+void set_kernel_text_ro(void)
 {
-	free_init_pages("unused kernel memory",
-			(unsigned long)(&__init_begin),
-			(unsigned long)(&__init_end));
-}
+	unsigned long start = PFN_ALIGN(_stext);
+	unsigned long end = PFN_ALIGN(__start_rodata);
 
-#ifdef CONFIG_DEBUG_RODATA
-const int rodata_test_data = 0xC3;
-EXPORT_SYMBOL_GPL(rodata_test_data);
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read only\n",
+		 start, end);
+
+	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+}
 
 void mark_rodata_ro(void)
 {
@@ -994,15 +770,12 @@ void mark_rodata_ro(void)
 	unsigned long rodata_start =
 		((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
 
-#ifdef CONFIG_DYNAMIC_FTRACE
-	/* Dynamic tracing modifies the kernel text section */
-	start = rodata_start;
-#endif
-
 	printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
 	       (end - start) >> 10);
 	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 
+	kernel_set_to_readonly = 1;
+
 	/*
 	 * The rodata section (but not the kernel text!) should also be
 	 * not-executable.
@@ -1022,13 +795,6 @@ void mark_rodata_ro(void)
 
 #endif
 
-#ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
-{
-	free_init_pages("initrd memory", start, end);
-}
-#endif
-
 int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
 				   int flags)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/init.c linux-libre-2.6.30-gnu1/arch/x86/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,409 @@
+#include <linux/ioport.h>
+#include <linux/swap.h>
+
+#include <asm/cacheflush.h>
+#include <asm/e820.h>
+#include <asm/init.h>
+#include <asm/page.h>
+#include <asm/page_types.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+
+unsigned long __initdata e820_table_start;
+unsigned long __meminitdata e820_table_end;
+unsigned long __meminitdata e820_table_top;
+
+int after_bootmem;
+
+int direct_gbpages
+#ifdef CONFIG_DIRECT_GBPAGES
+				= 1
+#endif
+;
+
+static void __init find_early_table_space(unsigned long end, int use_pse,
+					  int use_gbpages)
+{
+	unsigned long puds, pmds, ptes, tables, start;
+
+	puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
+	tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
+
+	if (use_gbpages) {
+		unsigned long extra;
+
+		extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
+		pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT;
+	} else
+		pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
+
+	tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
+
+	if (use_pse) {
+		unsigned long extra;
+
+		extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
+#ifdef CONFIG_X86_32
+		extra += PMD_SIZE;
+#endif
+		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	} else
+		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
+
+#ifdef CONFIG_X86_32
+	/* for fixmap */
+	tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
+#endif
+
+	/*
+	 * RED-PEN putting page tables only on node 0 could
+	 * cause a hotspot and fill up ZONE_DMA. The page tables
+	 * need roughly 0.5KB per GB.
+	 */
+#ifdef CONFIG_X86_32
+	start = 0x7000;
+	e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT,
+					tables, PAGE_SIZE);
+#else /* CONFIG_X86_64 */
+	start = 0x8000;
+	e820_table_start = find_e820_area(start, end, tables, PAGE_SIZE);
+#endif
+	if (e820_table_start == -1UL)
+		panic("Cannot find space for the kernel page tables");
+
+	e820_table_start >>= PAGE_SHIFT;
+	e820_table_end = e820_table_start;
+	e820_table_top = e820_table_start + (tables >> PAGE_SHIFT);
+
+	printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
+		end, e820_table_start << PAGE_SHIFT, e820_table_top << PAGE_SHIFT);
+}
+
+struct map_range {
+	unsigned long start;
+	unsigned long end;
+	unsigned page_size_mask;
+};
+
+#ifdef CONFIG_X86_32
+#define NR_RANGE_MR 3
+#else /* CONFIG_X86_64 */
+#define NR_RANGE_MR 5
+#endif
+
+static int __meminit save_mr(struct map_range *mr, int nr_range,
+			     unsigned long start_pfn, unsigned long end_pfn,
+			     unsigned long page_size_mask)
+{
+	if (start_pfn < end_pfn) {
+		if (nr_range >= NR_RANGE_MR)
+			panic("run out of range for init_memory_mapping\n");
+		mr[nr_range].start = start_pfn<<PAGE_SHIFT;
+		mr[nr_range].end   = end_pfn<<PAGE_SHIFT;
+		mr[nr_range].page_size_mask = page_size_mask;
+		nr_range++;
+	}
+
+	return nr_range;
+}
+
+#ifdef CONFIG_X86_64
+static void __init init_gbpages(void)
+{
+	if (direct_gbpages && cpu_has_gbpages)
+		printk(KERN_INFO "Using GB pages for direct mapping\n");
+	else
+		direct_gbpages = 0;
+}
+#else
+static inline void init_gbpages(void)
+{
+}
+#endif
+
+/*
+ * Setup the direct mapping of the physical memory at PAGE_OFFSET.
+ * This runs before bootmem is initialized and gets pages directly from
+ * the physical memory. To access them they are temporarily mapped.
+ */
+unsigned long __init_refok init_memory_mapping(unsigned long start,
+					       unsigned long end)
+{
+	unsigned long page_size_mask = 0;
+	unsigned long start_pfn, end_pfn;
+	unsigned long ret = 0;
+	unsigned long pos;
+
+	struct map_range mr[NR_RANGE_MR];
+	int nr_range, i;
+	int use_pse, use_gbpages;
+
+	printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end);
+
+	if (!after_bootmem)
+		init_gbpages();
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	/*
+	 * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages.
+	 * This will simplify cpa(), which otherwise needs to support splitting
+	 * large pages into small in interrupt context, etc.
+	 */
+	use_pse = use_gbpages = 0;
+#else
+	use_pse = cpu_has_pse;
+	use_gbpages = direct_gbpages;
+#endif
+
+#ifdef CONFIG_X86_32
+#ifdef CONFIG_X86_PAE
+	set_nx();
+	if (nx_enabled)
+		printk(KERN_INFO "NX (Execute Disable) protection: active\n");
+#endif
+
+	/* Enable PSE if available */
+	if (cpu_has_pse)
+		set_in_cr4(X86_CR4_PSE);
+
+	/* Enable PGE if available */
+	if (cpu_has_pge) {
+		set_in_cr4(X86_CR4_PGE);
+		__supported_pte_mask |= _PAGE_GLOBAL;
+	}
+#endif
+
+	if (use_gbpages)
+		page_size_mask |= 1 << PG_LEVEL_1G;
+	if (use_pse)
+		page_size_mask |= 1 << PG_LEVEL_2M;
+
+	memset(mr, 0, sizeof(mr));
+	nr_range = 0;
+
+	/* head if not big page alignment ? */
+	start_pfn = start >> PAGE_SHIFT;
+	pos = start_pfn << PAGE_SHIFT;
+#ifdef CONFIG_X86_32
+	/*
+	 * Don't use a large page for the first 2/4MB of memory
+	 * because there are often fixed size MTRRs in there
+	 * and overlapping MTRRs into large pages can cause
+	 * slowdowns.
+	 */
+	if (pos == 0)
+		end_pfn = 1<<(PMD_SHIFT - PAGE_SHIFT);
+	else
+		end_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
+				 << (PMD_SHIFT - PAGE_SHIFT);
+#else /* CONFIG_X86_64 */
+	end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT)
+			<< (PMD_SHIFT - PAGE_SHIFT);
+#endif
+	if (end_pfn > (end >> PAGE_SHIFT))
+		end_pfn = end >> PAGE_SHIFT;
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
+		pos = end_pfn << PAGE_SHIFT;
+	}
+
+	/* big page (2M) range */
+	start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
+			 << (PMD_SHIFT - PAGE_SHIFT);
+#ifdef CONFIG_X86_32
+	end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
+#else /* CONFIG_X86_64 */
+	end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
+			 << (PUD_SHIFT - PAGE_SHIFT);
+	if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)))
+		end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT));
+#endif
+
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+				page_size_mask & (1<<PG_LEVEL_2M));
+		pos = end_pfn << PAGE_SHIFT;
+	}
+
+#ifdef CONFIG_X86_64
+	/* big page (1G) range */
+	start_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
+			 << (PUD_SHIFT - PAGE_SHIFT);
+	end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT);
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+				page_size_mask &
+				 ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G)));
+		pos = end_pfn << PAGE_SHIFT;
+	}
+
+	/* tail is not big page (1G) alignment */
+	start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
+			 << (PMD_SHIFT - PAGE_SHIFT);
+	end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
+	if (start_pfn < end_pfn) {
+		nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
+				page_size_mask & (1<<PG_LEVEL_2M));
+		pos = end_pfn << PAGE_SHIFT;
+	}
+#endif
+
+	/* tail is not big page (2M) alignment */
+	start_pfn = pos>>PAGE_SHIFT;
+	end_pfn = end>>PAGE_SHIFT;
+	nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
+
+	/* try to merge same page size and continuous */
+	for (i = 0; nr_range > 1 && i < nr_range - 1; i++) {
+		unsigned long old_start;
+		if (mr[i].end != mr[i+1].start ||
+		    mr[i].page_size_mask != mr[i+1].page_size_mask)
+			continue;
+		/* move it */
+		old_start = mr[i].start;
+		memmove(&mr[i], &mr[i+1],
+			(nr_range - 1 - i) * sizeof(struct map_range));
+		mr[i--].start = old_start;
+		nr_range--;
+	}
+
+	for (i = 0; i < nr_range; i++)
+		printk(KERN_DEBUG " %010lx - %010lx page %s\n",
+				mr[i].start, mr[i].end,
+			(mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
+			 (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
+
+	/*
+	 * Find space for the kernel direct mapping tables.
+	 *
+	 * Later we should allocate these tables in the local node of the
+	 * memory mapped. Unfortunately this is done currently before the
+	 * nodes are discovered.
+	 */
+	if (!after_bootmem)
+		find_early_table_space(end, use_pse, use_gbpages);
+
+#ifdef CONFIG_X86_32
+	for (i = 0; i < nr_range; i++)
+		kernel_physical_mapping_init(mr[i].start, mr[i].end,
+					     mr[i].page_size_mask);
+	ret = end;
+#else /* CONFIG_X86_64 */
+	for (i = 0; i < nr_range; i++)
+		ret = kernel_physical_mapping_init(mr[i].start, mr[i].end,
+						   mr[i].page_size_mask);
+#endif
+
+#ifdef CONFIG_X86_32
+	early_ioremap_page_table_range_init();
+
+	load_cr3(swapper_pg_dir);
+#endif
+
+#ifdef CONFIG_X86_64
+	if (!after_bootmem && !start) {
+		pud_t *pud;
+		pmd_t *pmd;
+
+		mmu_cr4_features = read_cr4();
+
+		/*
+		 * _brk_end cannot change anymore, but it and _end may be
+		 * located on different 2M pages. cleanup_highmap(), however,
+		 * can only consider _end when it runs, so destroy any
+		 * mappings beyond _brk_end here.
+		 */
+		pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
+		pmd = pmd_offset(pud, _brk_end - 1);
+		while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
+			pmd_clear(pmd);
+	}
+#endif
+	__flush_tlb_all();
+
+	if (!after_bootmem && e820_table_end > e820_table_start)
+		reserve_early(e820_table_start << PAGE_SHIFT,
+				 e820_table_end << PAGE_SHIFT, "PGTABLE");
+
+	if (!after_bootmem)
+		early_memtest(start, end);
+
+	return ret >> PAGE_SHIFT;
+}
+
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address
+ * is valid. The argument is a physical page number.
+ *
+ *
+ * On x86, access has to be given to the first megabyte of ram because that area
+ * contains bios code and data regions used by X and dosemu and similar apps.
+ * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+ * mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+	if (pagenr <= 256)
+		return 1;
+	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
+		return 0;
+	if (!page_is_ram(pagenr))
+		return 1;
+	return 0;
+}
+
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+	unsigned long addr = begin;
+
+	if (addr >= end)
+		return;
+
+	/*
+	 * If debugging page accesses then do not free this memory but
+	 * mark them not present - any buggy init-section access will
+	 * create a kernel page fault:
+	 */
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
+		begin, PAGE_ALIGN(end));
+	set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
+#else
+	/*
+	 * We just marked the kernel text read only above, now that
+	 * we are going to free part of that, we need to make that
+	 * writeable first.
+	 */
+	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
+
+	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
+
+	for (; addr < end; addr += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		init_page_count(virt_to_page(addr));
+		memset((void *)(addr & ~(PAGE_SIZE-1)),
+			POISON_FREE_INITMEM, PAGE_SIZE);
+		free_page(addr);
+		totalram_pages++;
+	}
+#endif
+}
+
+void free_initmem(void)
+{
+	free_init_pages("unused kernel memory",
+			(unsigned long)(&__init_begin),
+			(unsigned long)(&__init_end));
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	free_init_pages("initrd memory", start, end);
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/iomap_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/iomap_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/iomap_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/iomap_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,10 +19,11 @@
 #include <asm/iomap.h>
 #include <asm/pat.h>
 #include <linux/module.h>
+#include <linux/highmem.h>
 
 int is_io_mapping_possible(resource_size_t base, unsigned long size)
 {
-#ifndef CONFIG_X86_PAE
+#if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
 	/* There is no way to map greater than 1 << 32 address without PAE */
 	if (base + size > 0x100000000ULL)
 		return 0;
@@ -31,16 +32,28 @@ int is_io_mapping_possible(resource_size
 }
 EXPORT_SYMBOL_GPL(is_io_mapping_possible);
 
-/* Map 'pfn' using fixed map 'type' and protections 'prot'
- */
-void *
-iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
 {
 	enum fixed_addresses idx;
 	unsigned long vaddr;
 
 	pagefault_disable();
 
+	debug_kmap_atomic(type);
+	idx = type + KM_TYPE_NR * smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
+	arch_flush_lazy_mmu_mode();
+
+	return (void *)vaddr;
+}
+
+/*
+ * Map 'pfn' using fixed map 'type' and protections 'prot'
+ */
+void *
+iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+{
 	/*
 	 * For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS.
 	 * PAGE_KERNEL_WC maps to PWT, which translates to uncached if the
@@ -50,12 +63,7 @@ iomap_atomic_prot_pfn(unsigned long pfn,
 	if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC))
 		prot = PAGE_KERNEL_UC_MINUS;
 
-	idx = type + KM_TYPE_NR*smp_processor_id();
-	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	set_pte(kmap_pte-idx, pfn_pte(pfn, prot));
-	arch_flush_lazy_mmu_mode();
-
-	return (void*) vaddr;
+	return kmap_atomic_prot_pfn(pfn, type, prot);
 }
 EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/ioremap.c linux-libre-2.6.30-gnu1/arch/x86/mm/ioremap.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/ioremap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/ioremap.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,13 +22,17 @@
 #include <asm/pgalloc.h>
 #include <asm/pat.h>
 
-#ifdef CONFIG_X86_64
-
-static inline int phys_addr_valid(unsigned long addr)
+static inline int phys_addr_valid(resource_size_t addr)
 {
-	return addr < (1UL << boot_cpu_data.x86_phys_bits);
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	return !(addr >> boot_cpu_data.x86_phys_bits);
+#else
+	return 1;
+#endif
 }
 
+#ifdef CONFIG_X86_64
+
 unsigned long __phys_addr(unsigned long x)
 {
 	if (x >= __START_KERNEL_map) {
@@ -38,8 +42,7 @@ unsigned long __phys_addr(unsigned long
 	} else {
 		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
 		x -= PAGE_OFFSET;
-		VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :
-					!phys_addr_valid(x));
+		VIRTUAL_BUG_ON(!phys_addr_valid(x));
 	}
 	return x;
 }
@@ -56,10 +59,8 @@ bool __virt_addr_valid(unsigned long x)
 		if (x < PAGE_OFFSET)
 			return false;
 		x -= PAGE_OFFSET;
-		if (system_state == SYSTEM_BOOTING ?
-				x > MAXMEM : !phys_addr_valid(x)) {
+		if (!phys_addr_valid(x))
 			return false;
-		}
 	}
 
 	return pfn_valid(x >> PAGE_SHIFT);
@@ -68,18 +69,12 @@ EXPORT_SYMBOL(__virt_addr_valid);
 
 #else
 
-static inline int phys_addr_valid(unsigned long addr)
-{
-	return 1;
-}
-
 #ifdef CONFIG_DEBUG_VIRTUAL
 unsigned long __phys_addr(unsigned long x)
 {
-	/* VMALLOC_* aren't constants; not available at the boot time */
+	/* VMALLOC_* aren't constants  */
 	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
-	VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING &&
-		is_vmalloc_addr((void *) x));
+	VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
 	return x - PAGE_OFFSET;
 }
 EXPORT_SYMBOL(__phys_addr);
@@ -89,7 +84,9 @@ bool __virt_addr_valid(unsigned long x)
 {
 	if (x < PAGE_OFFSET)
 		return false;
-	if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x))
+	if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
+		return false;
+	if (x >= FIXADDR_START)
 		return false;
 	return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
 }
@@ -283,15 +280,16 @@ static void __iomem *__ioremap_caller(re
 		return NULL;
 	area->phys_addr = phys_addr;
 	vaddr = (unsigned long) area->addr;
-	if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
+
+	if (kernel_map_sync_memtype(phys_addr, size, prot_val)) {
 		free_memtype(phys_addr, phys_addr + size);
 		free_vm_area(area);
 		return NULL;
 	}
 
-	if (ioremap_change_attr(vaddr, size, prot_val) < 0) {
+	if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
 		free_memtype(phys_addr, phys_addr + size);
-		vunmap(area->addr);
+		free_vm_area(area);
 		return NULL;
 	}
 
@@ -348,7 +346,7 @@ EXPORT_SYMBOL(ioremap_nocache);
  *
  * Must be freed with iounmap.
  */
-void __iomem *ioremap_wc(unsigned long phys_addr, unsigned long size)
+void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
 {
 	if (pat_enabled)
 		return __ioremap_caller(phys_addr, size, _PAGE_CACHE_WC,
@@ -377,7 +375,8 @@ static void __iomem *ioremap_default(res
 	 * - 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, -1, &flags);
+	err = reserve_memtype(phys_addr, phys_addr + size,
+				_PAGE_CACHE_WB, &flags);
 	if (err < 0)
 		return NULL;
 
@@ -508,13 +507,19 @@ static inline pte_t * __init early_iorem
 	return &bm_pte[pte_index(addr)];
 }
 
+static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
+
 void __init early_ioremap_init(void)
 {
 	pmd_t *pmd;
+	int i;
 
 	if (early_ioremap_debug)
 		printk(KERN_INFO "early_ioremap_init()\n");
 
+	for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
+		slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
+
 	pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
 	memset(bm_pte, 0, sizeof(bm_pte));
 	pmd_populate_kernel(&init_mm, pmd, bm_pte);
@@ -544,7 +549,7 @@ void __init early_ioremap_reset(void)
 }
 
 static void __init __early_set_fixmap(enum fixed_addresses idx,
-				   unsigned long phys, pgprot_t flags)
+				      phys_addr_t phys, pgprot_t flags)
 {
 	unsigned long addr = __fix_to_virt(idx);
 	pte_t *pte;
@@ -563,7 +568,7 @@ static void __init __early_set_fixmap(en
 }
 
 static inline void __init early_set_fixmap(enum fixed_addresses idx,
-					   unsigned long phys, pgprot_t prot)
+					   phys_addr_t phys, pgprot_t prot)
 {
 	if (after_paging_init)
 		__set_fixmap(idx, phys, prot);
@@ -581,6 +586,7 @@ static inline void __init early_clear_fi
 
 static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
 static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
+
 static int __init check_early_ioremap_leak(void)
 {
 	int count = 0;
@@ -602,9 +608,11 @@ static int __init check_early_ioremap_le
 }
 late_initcall(check_early_ioremap_leak);
 
-static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
+static void __init __iomem *
+__early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot)
 {
-	unsigned long offset, last_addr;
+	unsigned long offset;
+	resource_size_t last_addr;
 	unsigned int nrpages;
 	enum fixed_addresses idx0, idx;
 	int i, slot;
@@ -620,15 +628,15 @@ static void __init __iomem *__early_iore
 	}
 
 	if (slot < 0) {
-		printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n",
-			 phys_addr, size);
+		printk(KERN_INFO "early_iomap(%08llx, %08lx) not found slot\n",
+			 (u64)phys_addr, size);
 		WARN_ON(1);
 		return NULL;
 	}
 
 	if (early_ioremap_debug) {
-		printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
-		       phys_addr, size, slot);
+		printk(KERN_INFO "early_ioremap(%08llx, %08lx) [%d] => ",
+		       (u64)phys_addr, size, slot);
 		dump_stack();
 	}
 
@@ -668,20 +676,22 @@ static void __init __iomem *__early_iore
 		--nrpages;
 	}
 	if (early_ioremap_debug)
-		printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
+		printk(KERN_CONT "%08lx + %08lx\n", offset, slot_virt[slot]);
 
-	prev_map[slot] = (void __iomem *)(offset + fix_to_virt(idx0));
+	prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]);
 	return prev_map[slot];
 }
 
 /* Remap an IO device */
-void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_ioremap(resource_size_t phys_addr, unsigned long size)
 {
 	return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
 }
 
 /* Remap memory */
-void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_memremap(resource_size_t phys_addr, unsigned long size)
 {
 	return __early_ioremap(phys_addr, size, PAGE_KERNEL);
 }
@@ -738,8 +748,3 @@ void __init early_iounmap(void __iomem *
 	}
 	prev_map[slot] = NULL;
 }
-
-void __this_fixmap_does_not_exist(void)
-{
-	WARN_ON(1);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/kmmio.c linux-libre-2.6.30-gnu1/arch/x86/mm/kmmio.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/kmmio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/kmmio.c	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,7 @@ static struct kmmio_probe *get_kmmio_pro
 {
 	struct kmmio_probe *p;
 	list_for_each_entry_rcu(p, &kmmio_probes, list) {
-		if (addr >= p->addr && addr <= (p->addr + p->len))
+		if (addr >= p->addr && addr < (p->addr + p->len))
 			return p;
 	}
 	return NULL;
@@ -310,7 +310,7 @@ static int post_kmmio_handler(unsigned l
 	struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
 
 	if (!ctx->active) {
-		pr_warning("kmmio: spurious debug trap on CPU %d.\n",
+		pr_debug("kmmio: spurious debug trap on CPU %d.\n",
 							smp_processor_id());
 		goto out;
 	}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/Makefile linux-libre-2.6.30-gnu1/arch/x86/mm/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/mm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,8 @@
-obj-y	:=  init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
+obj-y	:=  init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
 	    pat.o pgtable.o gup.o
 
+obj-$(CONFIG_SMP)		+= tlb.o
+
 obj-$(CONFIG_X86_32)		+= pgtable_32.o iomap_32.o
 
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
@@ -12,7 +14,7 @@ obj-$(CONFIG_MMIOTRACE)		+= mmiotrace.o
 mmiotrace-y			:= kmmio.o pf_in.o mmio-mod.o
 obj-$(CONFIG_MMIOTRACE_TEST)	+= testmmiotrace.o
 
-obj-$(CONFIG_NUMA)		+= numa_$(BITS).o
+obj-$(CONFIG_NUMA)		+= numa.o numa_$(BITS).o
 obj-$(CONFIG_K8_NUMA)		+= k8topology_64.o
 obj-$(CONFIG_ACPI_NUMA)		+= srat_$(BITS).o
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/memtest.c linux-libre-2.6.30-gnu1/arch/x86/mm/memtest.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/memtest.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/memtest.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,44 +9,44 @@
 
 #include <asm/e820.h>
 
-static void __init memtest(unsigned long start_phys, unsigned long size,
-				 unsigned pattern)
+static u64 patterns[] __initdata = {
+	0,
+	0xffffffffffffffffULL,
+	0x5555555555555555ULL,
+	0xaaaaaaaaaaaaaaaaULL,
+	0x1111111111111111ULL,
+	0x2222222222222222ULL,
+	0x4444444444444444ULL,
+	0x8888888888888888ULL,
+	0x3333333333333333ULL,
+	0x6666666666666666ULL,
+	0x9999999999999999ULL,
+	0xccccccccccccccccULL,
+	0x7777777777777777ULL,
+	0xbbbbbbbbbbbbbbbbULL,
+	0xddddddddddddddddULL,
+	0xeeeeeeeeeeeeeeeeULL,
+	0x7a6c7258554e494cULL, /* yeah ;-) */
+};
+
+static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad)
 {
-	unsigned long i;
-	unsigned long *start;
-	unsigned long start_bad;
-	unsigned long last_bad;
-	unsigned long val;
-	unsigned long start_phys_aligned;
-	unsigned long count;
-	unsigned long incr;
+	printk(KERN_INFO "  %016llx bad mem addr %010llx - %010llx reserved\n",
+	       (unsigned long long) pattern,
+	       (unsigned long long) start_bad,
+	       (unsigned long long) end_bad);
+	reserve_early(start_bad, end_bad, "BAD RAM");
+}
 
-	switch (pattern) {
-	case 0:
-		val = 0UL;
-		break;
-	case 1:
-		val = -1UL;
-		break;
-	case 2:
-#ifdef CONFIG_X86_64
-		val = 0x5555555555555555UL;
-#else
-		val = 0x55555555UL;
-#endif
-		break;
-	case 3:
-#ifdef CONFIG_X86_64
-		val = 0xaaaaaaaaaaaaaaaaUL;
-#else
-		val = 0xaaaaaaaaUL;
-#endif
-		break;
-	default:
-		return;
-	}
+static void __init memtest(u64 pattern, u64 start_phys, u64 size)
+{
+	u64 i, count;
+	u64 *start;
+	u64 start_bad, last_bad;
+	u64 start_phys_aligned;
+	size_t incr;
 
-	incr = sizeof(unsigned long);
+	incr = sizeof(pattern);
 	start_phys_aligned = ALIGN(start_phys, incr);
 	count = (size - (start_phys_aligned - start_phys))/incr;
 	start = __va(start_phys_aligned);
@@ -54,25 +54,42 @@ static void __init memtest(unsigned long
 	last_bad = 0;
 
 	for (i = 0; i < count; i++)
-		start[i] = val;
+		start[i] = pattern;
 	for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
-		if (*start != val) {
-			if (start_phys_aligned == last_bad + incr) {
-				last_bad += incr;
-			} else {
-				if (start_bad) {
-					printk(KERN_CONT "\n  %016lx bad mem addr %010lx - %010lx reserved",
-						val, start_bad, last_bad + incr);
-					reserve_early(start_bad, last_bad + incr, "BAD RAM");
-				}
-				start_bad = last_bad = start_phys_aligned;
-			}
+		if (*start == pattern)
+			continue;
+		if (start_phys_aligned == last_bad + incr) {
+			last_bad += incr;
+			continue;
 		}
+		if (start_bad)
+			reserve_bad_mem(pattern, start_bad, last_bad + incr);
+		start_bad = last_bad = start_phys_aligned;
 	}
-	if (start_bad) {
-		printk(KERN_CONT "\n  %016lx bad mem addr %010lx - %010lx reserved",
-			val, start_bad, last_bad + incr);
-		reserve_early(start_bad, last_bad + incr, "BAD RAM");
+	if (start_bad)
+		reserve_bad_mem(pattern, start_bad, last_bad + incr);
+}
+
+static void __init do_one_pass(u64 pattern, u64 start, u64 end)
+{
+	u64 size = 0;
+
+	while (start < end) {
+		start = find_e820_area_size(start, &size, 1);
+
+		/* done ? */
+		if (start >= end)
+			break;
+		if (start + size > end)
+			size = end - start;
+
+		printk(KERN_INFO "  %010llx - %010llx pattern %016llx\n",
+		       (unsigned long long) start,
+		       (unsigned long long) start + size,
+		       (unsigned long long) cpu_to_be64(pattern));
+		memtest(pattern, start, size);
+
+		start += size;
 	}
 }
 
@@ -83,6 +100,9 @@ static int __init parse_memtest(char *ar
 {
 	if (arg)
 		memtest_pattern = simple_strtoul(arg, NULL, 0);
+	else
+		memtest_pattern = ARRAY_SIZE(patterns);
+
 	return 0;
 }
 
@@ -90,33 +110,22 @@ early_param("memtest", parse_memtest);
 
 void __init early_memtest(unsigned long start, unsigned long end)
 {
-	u64 t_start, t_size;
-	unsigned pattern;
+	unsigned int i;
+	unsigned int idx = 0;
 
 	if (!memtest_pattern)
 		return;
 
-	printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern);
-	for (pattern = 0; pattern < memtest_pattern; pattern++) {
-		t_start = start;
-		t_size = 0;
-		while (t_start < end) {
-			t_start = find_e820_area_size(t_start, &t_size, 1);
-
-			/* done ? */
-			if (t_start >= end)
-				break;
-			if (t_start + t_size > end)
-				t_size = end - t_start;
-
-			printk(KERN_CONT "\n  %010llx - %010llx pattern %d",
-				(unsigned long long)t_start,
-				(unsigned long long)t_start + t_size, pattern);
-
-			memtest(t_start, t_size, pattern);
+	printk(KERN_INFO "early_memtest: # of tests: %d\n", memtest_pattern);
+	for (i = 0; i < memtest_pattern; i++) {
+		idx = i % ARRAY_SIZE(patterns);
+		do_one_pass(patterns[idx], start, end);
+	}
 
-			t_start += t_size;
-		}
+	if (idx > 0) {
+		printk(KERN_INFO "early_memtest: wipe out "
+		       "test pattern from memory\n");
+		/* additional test with pattern 0 will do this */
+		do_one_pass(0, start, end);
 	}
-	printk(KERN_CONT "\n");
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/mmap.c linux-libre-2.6.30-gnu1/arch/x86/mm/mmap.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/mmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/mmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * Based on code by Ingo Molnar and Andi Kleen, copyrighted
  * as follows:
  *
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * Copyright 2003-2009 Red Hat Inc.
  * All Rights Reserved.
  * Copyright 2005 Andi Kleen, SUSE Labs.
  * Copyright 2007 Jiri Kosina, SUSE Labs.
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/mmio-mod.c linux-libre-2.6.30-gnu1/arch/x86/mm/mmio-mod.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/mmio-mod.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/mmio-mod.c	2009-06-09 23:05:27.000000000 -0400
@@ -378,27 +378,34 @@ static void clear_trace_list(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static cpumask_t downed_cpus;
+static cpumask_var_t downed_cpus;
 
 static void enter_uniprocessor(void)
 {
 	int cpu;
 	int err;
 
+	if (downed_cpus == NULL &&
+	    !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
+		pr_notice(NAME "Failed to allocate mask\n");
+		goto out;
+	}
+
 	get_online_cpus();
-	downed_cpus = cpu_online_map;
-	cpu_clear(first_cpu(cpu_online_map), downed_cpus);
+	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");
 	put_online_cpus();
 
-	for_each_cpu_mask(cpu, downed_cpus) {
+	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_down(cpu);
 		if (!err)
 			pr_info(NAME "CPU%d is down.\n", cpu);
 		else
 			pr_err(NAME "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");
@@ -411,10 +418,10 @@ static void __ref leave_uniprocessor(voi
 	int cpu;
 	int err;
 
-	if (cpus_weight(downed_cpus) == 0)
+	if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
 		return;
 	pr_notice(NAME "Re-enabling CPUs...\n");
-	for_each_cpu_mask(cpu, downed_cpus) {
+	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_up(cpu);
 		if (!err)
 			pr_info(NAME "enabled CPU%d.\n", cpu);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/numa_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/numa_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/numa_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/numa_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -194,7 +194,7 @@ void *alloc_remap(int nid, unsigned long
 	size = ALIGN(size, L1_CACHE_BYTES);
 
 	if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
-		return 0;
+		return NULL;
 
 	node_remap_alloc_vaddr[nid] += size;
 	memset(allocation, 0, size);
@@ -257,7 +257,7 @@ void resume_map_numa_kva(pgd_t *pgd_base
 }
 #endif
 
-static unsigned long calculate_numa_remap_pages(void)
+static __init unsigned long calculate_numa_remap_pages(void)
 {
 	int nid;
 	unsigned long size, reserve_pages = 0;
@@ -416,39 +416,14 @@ void __init initmem_init(unsigned long s
 	for_each_online_node(nid)
 		propagate_e820_map_node(nid);
 
-	for_each_online_node(nid)
+	for_each_online_node(nid) {
 		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
+		NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
+	}
 
-	NODE_DATA(0)->bdata = &bootmem_node_data[0];
 	setup_bootmem_allocator();
 }
 
-void __init set_highmem_pages_init(void)
-{
-#ifdef CONFIG_HIGHMEM
-	struct zone *zone;
-	int nid;
-
-	for_each_zone(zone) {
-		unsigned long zone_start_pfn, zone_end_pfn;
-
-		if (!is_highmem(zone))
-			continue;
-
-		zone_start_pfn = zone->zone_start_pfn;
-		zone_end_pfn = zone_start_pfn + zone->spanned_pages;
-
-		nid = zone_to_nid(zone);
-		printk(KERN_INFO "Initializing %s for node %d (%08lx:%08lx)\n",
-				zone->name, nid, zone_start_pfn, zone_end_pfn);
-
-		add_highpages_with_active_regions(nid, zone_start_pfn,
-				 zone_end_pfn);
-	}
-	totalram_pages += totalhigh_pages;
-#endif
-}
-
 #ifdef CONFIG_MEMORY_HOTPLUG
 static int paddr_to_nid(u64 addr)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/numa_64.c linux-libre-2.6.30-gnu1/arch/x86/mm/numa_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/numa_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/numa_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,15 @@ int numa_off __initdata;
 static unsigned long __initdata nodemap_addr;
 static unsigned long __initdata nodemap_size;
 
+DEFINE_PER_CPU(int, node_number) = 0;
+EXPORT_PER_CPU_SYMBOL(node_number);
+
+/*
+ * Map cpu index to node index
+ */
+DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
+EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
+
 /*
  * Given a shift value, try to populate memnodemap[]
  * Returns :
@@ -179,6 +188,9 @@ void __init setup_node_bootmem(int nodei
 	const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
 	int nid;
 
+	if (!end)
+		return;
+
 	start = roundup(start, ZONE_ALIGN);
 
 	printk(KERN_INFO "Bootmem setup node %d %016lx-%016lx\n", nodeid,
@@ -640,3 +652,116 @@ void __init init_cpu_to_node(void)
 #endif
 
 
+void __cpuinit numa_set_node(int cpu, int node)
+{
+	int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
+
+	/* early setting, no percpu area yet */
+	if (cpu_to_node_map) {
+		cpu_to_node_map[cpu] = node;
+		return;
+	}
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+	if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) {
+		printk(KERN_ERR "numa_set_node: invalid cpu# (%d)\n", cpu);
+		dump_stack();
+		return;
+	}
+#endif
+	per_cpu(x86_cpu_to_node_map, cpu) = node;
+
+	if (node != NUMA_NO_NODE)
+		per_cpu(node_number, cpu) = node;
+}
+
+void __cpuinit numa_clear_node(int cpu)
+{
+	numa_set_node(cpu, NUMA_NO_NODE);
+}
+
+#ifndef CONFIG_DEBUG_PER_CPU_MAPS
+
+void __cpuinit numa_add_cpu(int cpu)
+{
+	cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+}
+
+void __cpuinit numa_remove_cpu(int cpu)
+{
+	cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+}
+
+#else /* CONFIG_DEBUG_PER_CPU_MAPS */
+
+/*
+ * --------- debug versions of the numa functions ---------
+ */
+static void __cpuinit numa_set_cpumask(int cpu, int enable)
+{
+	int node = early_cpu_to_node(cpu);
+	struct cpumask *mask;
+	char buf[64];
+
+	mask = node_to_cpumask_map[node];
+	if (mask == NULL) {
+		printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
+		dump_stack();
+		return;
+	}
+
+	if (enable)
+		cpumask_set_cpu(cpu, mask);
+	else
+		cpumask_clear_cpu(cpu, mask);
+
+	cpulist_scnprintf(buf, sizeof(buf), mask);
+	printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
+		enable ? "numa_add_cpu" : "numa_remove_cpu", cpu, node, buf);
+}
+
+void __cpuinit numa_add_cpu(int cpu)
+{
+	numa_set_cpumask(cpu, 1);
+}
+
+void __cpuinit numa_remove_cpu(int cpu)
+{
+	numa_set_cpumask(cpu, 0);
+}
+
+int cpu_to_node(int cpu)
+{
+	if (early_per_cpu_ptr(x86_cpu_to_node_map)) {
+		printk(KERN_WARNING
+			"cpu_to_node(%d): usage too early!\n", cpu);
+		dump_stack();
+		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
+	}
+	return per_cpu(x86_cpu_to_node_map, cpu);
+}
+EXPORT_SYMBOL(cpu_to_node);
+
+/*
+ * Same function as cpu_to_node() but used if called before the
+ * per_cpu areas are setup.
+ */
+int early_cpu_to_node(int cpu)
+{
+	if (early_per_cpu_ptr(x86_cpu_to_node_map))
+		return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
+
+	if (!cpu_possible(cpu)) {
+		printk(KERN_WARNING
+			"early_cpu_to_node(%d): no per_cpu area!\n", cpu);
+		dump_stack();
+		return NUMA_NO_NODE;
+	}
+	return per_cpu(x86_cpu_to_node_map, cpu);
+}
+
+/*
+ * --------- end of debug versions of the numa functions ---------
+ */
+
+#endif /* CONFIG_DEBUG_PER_CPU_MAPS */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/numa.c linux-libre-2.6.30-gnu1/arch/x86/mm/numa.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/numa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/numa.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/* Common code for 32 and 64-bit NUMA */
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
+#endif
+
+/*
+ * Which logical CPUs are on which nodes
+ */
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: node_to_cpumask() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int node, num = 0;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES) {
+		for_each_node_mask(node, node_possible_map)
+			num = node;
+		nr_node_ids = num + 1;
+	}
+
+	/* allocate the map */
+	for (node = 0; node < nr_node_ids; node++)
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (node >= nr_node_ids) {
+		printk(KERN_WARNING
+			"cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+			node, nr_node_ids);
+		dump_stack();
+		return cpu_none_mask;
+	}
+	if (node_to_cpumask_map[node] == NULL) {
+		printk(KERN_WARNING
+			"cpumask_of_node(%d): no node_to_cpumask_map!\n",
+			node);
+		dump_stack();
+		return cpu_online_mask;
+	}
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/pageattr.c linux-libre-2.6.30-gnu1/arch/x86/mm/pageattr.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/pageattr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/pageattr.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
+#include <asm/setup.h>
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
@@ -33,6 +34,7 @@ struct cpa_data {
 	unsigned long	pfn;
 	unsigned	force_split : 1;
 	int		curpage;
+	struct page	**pages;
 };
 
 /*
@@ -45,6 +47,7 @@ static DEFINE_SPINLOCK(cpa_lock);
 
 #define CPA_FLUSHTLB 1
 #define CPA_ARRAY 2
+#define CPA_PAGES_ARRAY 4
 
 #ifdef CONFIG_PROC_FS
 static unsigned long direct_pages_count[PG_LEVEL_NUM];
@@ -95,7 +98,7 @@ static inline unsigned long highmap_star
 
 static inline unsigned long highmap_end_pfn(void)
 {
-	return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
+	return __pa(roundup(_brk_end, PMD_SIZE)) >> PAGE_SHIFT;
 }
 
 #endif
@@ -150,7 +153,7 @@ static void __cpa_flush_all(void *arg)
 	 */
 	__flush_tlb_all();
 
-	if (cache && boot_cpu_data.x86_model >= 4)
+	if (cache && boot_cpu_data.x86 >= 4)
 		wbinvd();
 }
 
@@ -201,38 +204,41 @@ static void cpa_flush_range(unsigned lon
 	}
 }
 
-static void cpa_flush_array(unsigned long *start, int numpages, int cache)
+static void cpa_flush_array(unsigned long *start, int numpages, int cache,
+			    int in_flags, struct page **pages)
 {
 	unsigned int i, level;
-	unsigned long *addr;
+	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 
 	BUG_ON(irqs_disabled());
 
-	on_each_cpu(__cpa_flush_range, NULL, 1);
+	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
-	if (!cache)
+	if (!cache || do_wbinvd)
 		return;
 
-	/* 4M threshold */
-	if (numpages >= 1024) {
-		if (boot_cpu_data.x86_model >= 4)
-			wbinvd();
-		return;
-	}
 	/*
 	 * We only need to flush on one CPU,
 	 * clflush is a MESI-coherent instruction that
 	 * will cause all other CPUs to flush the same
 	 * cachelines:
 	 */
-	for (i = 0, addr = start; i < numpages; i++, addr++) {
-		pte_t *pte = lookup_address(*addr, &level);
+	for (i = 0; i < numpages; i++) {
+		unsigned long addr;
+		pte_t *pte;
+
+		if (in_flags & CPA_PAGES_ARRAY)
+			addr = (unsigned long)page_address(pages[i]);
+		else
+			addr = start[i];
+
+		pte = lookup_address(addr, &level);
 
 		/*
 		 * Only flush present addresses:
 		 */
 		if (pte && (pte_val(*pte) & _PAGE_PRESENT))
-			clflush_cache_range((void *) *addr, PAGE_SIZE);
+			clflush_cache_range((void *)addr, PAGE_SIZE);
 	}
 }
 
@@ -482,6 +488,13 @@ static int split_large_page(pte_t *kpte,
 	pbase = (pte_t *)page_address(base);
 	paravirt_alloc_pte(&init_mm, page_to_pfn(base));
 	ref_prot = pte_pgprot(pte_clrhuge(*kpte));
+	/*
+	 * If we ever want to utilize the PAT bit, we need to
+	 * update this function to make sure it's converted from
+	 * bit 12 to bit 7 when we cross from the 2MB level to
+	 * the 4K level:
+	 */
+	WARN_ON_ONCE(pgprot_val(ref_prot) & _PAGE_PAT_LARGE);
 
 #ifdef CONFIG_X86_64
 	if (level == PG_LEVEL_1G) {
@@ -577,7 +590,9 @@ static int __change_page_attr(struct cpa
 	unsigned int level;
 	pte_t *kpte, old_pte;
 
-	if (cpa->flags & CPA_ARRAY)
+	if (cpa->flags & CPA_PAGES_ARRAY)
+		address = (unsigned long)page_address(cpa->pages[cpa->curpage]);
+	else if (cpa->flags & CPA_ARRAY)
 		address = cpa->vaddr[cpa->curpage];
 	else
 		address = *cpa->vaddr;
@@ -680,7 +695,9 @@ static int cpa_process_alias(struct cpa_
 	 * No need to redo, when the primary call touched the direct
 	 * mapping already:
 	 */
-	if (cpa->flags & CPA_ARRAY)
+	if (cpa->flags & CPA_PAGES_ARRAY)
+		vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]);
+	else if (cpa->flags & CPA_ARRAY)
 		vaddr = cpa->vaddr[cpa->curpage];
 	else
 		vaddr = *cpa->vaddr;
@@ -691,7 +708,7 @@ static int cpa_process_alias(struct cpa_
 		alias_cpa = *cpa;
 		temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
 		alias_cpa.vaddr = &temp_cpa_vaddr;
-		alias_cpa.flags &= ~CPA_ARRAY;
+		alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY);
 
 
 		ret = __change_page_attr_set_clr(&alias_cpa, 0);
@@ -704,7 +721,7 @@ static int cpa_process_alias(struct cpa_
 	 * No need to redo, when the primary call touched the high
 	 * mapping already:
 	 */
-	if (within(vaddr, (unsigned long) _text, (unsigned long) _end))
+	if (within(vaddr, (unsigned long) _text, _brk_end))
 		return 0;
 
 	/*
@@ -717,7 +734,7 @@ static int cpa_process_alias(struct cpa_
 	alias_cpa = *cpa;
 	temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base;
 	alias_cpa.vaddr = &temp_cpa_vaddr;
-	alias_cpa.flags &= ~CPA_ARRAY;
+	alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY);
 
 	/*
 	 * The high mapping range is imprecise, so ignore the return value.
@@ -738,7 +755,7 @@ static int __change_page_attr_set_clr(st
 		 */
 		cpa->numpages = numpages;
 		/* for array changes, we can't use large page */
-		if (cpa->flags & CPA_ARRAY)
+		if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
 			cpa->numpages = 1;
 
 		if (!debug_pagealloc)
@@ -762,7 +779,7 @@ static int __change_page_attr_set_clr(st
 		 */
 		BUG_ON(cpa->numpages > numpages);
 		numpages -= cpa->numpages;
-		if (cpa->flags & CPA_ARRAY)
+		if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY))
 			cpa->curpage++;
 		else
 			*cpa->vaddr += cpa->numpages * PAGE_SIZE;
@@ -779,7 +796,8 @@ static inline int cache_attr(pgprot_t at
 
 static int change_page_attr_set_clr(unsigned long *addr, int numpages,
 				    pgprot_t mask_set, pgprot_t mask_clr,
-				    int force_split, int array)
+				    int force_split, int in_flag,
+				    struct page **pages)
 {
 	struct cpa_data cpa;
 	int ret, cache, checkalias;
@@ -794,15 +812,7 @@ static int change_page_attr_set_clr(unsi
 		return 0;
 
 	/* Ensure we are PAGE_SIZE aligned */
-	if (!array) {
-		if (*addr & ~PAGE_MASK) {
-			*addr &= PAGE_MASK;
-			/*
-			 * People should not be passing in unaligned addresses:
-			 */
-			WARN_ON_ONCE(1);
-		}
-	} else {
+	if (in_flag & CPA_ARRAY) {
 		int i;
 		for (i = 0; i < numpages; i++) {
 			if (addr[i] & ~PAGE_MASK) {
@@ -810,6 +820,18 @@ static int change_page_attr_set_clr(unsi
 				WARN_ON_ONCE(1);
 			}
 		}
+	} else if (!(in_flag & CPA_PAGES_ARRAY)) {
+		/*
+		 * in_flag of CPA_PAGES_ARRAY implies it is aligned.
+		 * No need to cehck in that case
+		 */
+		if (*addr & ~PAGE_MASK) {
+			*addr &= PAGE_MASK;
+			/*
+			 * People should not be passing in unaligned addresses:
+			 */
+			WARN_ON_ONCE(1);
+		}
 	}
 
 	/* Must avoid aliasing mappings in the highmem code */
@@ -825,6 +847,7 @@ static int change_page_attr_set_clr(unsi
 	arch_flush_lazy_mmu_mode();
 
 	cpa.vaddr = addr;
+	cpa.pages = pages;
 	cpa.numpages = numpages;
 	cpa.mask_set = mask_set;
 	cpa.mask_clr = mask_clr;
@@ -832,8 +855,8 @@ static int change_page_attr_set_clr(unsi
 	cpa.curpage = 0;
 	cpa.force_split = force_split;
 
-	if (array)
-		cpa.flags |= CPA_ARRAY;
+	if (in_flag & (CPA_ARRAY | CPA_PAGES_ARRAY))
+		cpa.flags |= in_flag;
 
 	/* No alias checking for _NX bit modifications */
 	checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
@@ -859,9 +882,10 @@ static int change_page_attr_set_clr(unsi
 	 * wbindv):
 	 */
 	if (!ret && cpu_has_clflush) {
-		if (cpa.flags & CPA_ARRAY)
-			cpa_flush_array(addr, numpages, cache);
-		else
+		if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) {
+			cpa_flush_array(addr, numpages, cache,
+					cpa.flags, pages);
+		} else
 			cpa_flush_range(*addr, numpages, cache);
 	} else
 		cpa_flush_all(cache);
@@ -881,14 +905,28 @@ static inline int change_page_attr_set(u
 				       pgprot_t mask, int array)
 {
 	return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0), 0,
-		array);
+		(array ? CPA_ARRAY : 0), NULL);
 }
 
 static inline int change_page_attr_clear(unsigned long *addr, int numpages,
 					 pgprot_t mask, int array)
 {
 	return change_page_attr_set_clr(addr, numpages, __pgprot(0), mask, 0,
-		array);
+		(array ? CPA_ARRAY : 0), NULL);
+}
+
+static inline int cpa_set_pages_array(struct page **pages, int numpages,
+				       pgprot_t mask)
+{
+	return change_page_attr_set_clr(NULL, numpages, mask, __pgprot(0), 0,
+		CPA_PAGES_ARRAY, pages);
+}
+
+static inline int cpa_clear_pages_array(struct page **pages, int numpages,
+					 pgprot_t mask)
+{
+	return change_page_attr_set_clr(NULL, numpages, __pgprot(0), mask, 0,
+		CPA_PAGES_ARRAY, pages);
 }
 
 int _set_memory_uc(unsigned long addr, int numpages)
@@ -902,71 +940,94 @@ int _set_memory_uc(unsigned long addr, i
 
 int set_memory_uc(unsigned long addr, int numpages)
 {
+	int ret;
+
 	/*
 	 * for now UC MINUS. see comments in ioremap_nocache()
 	 */
-	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
-			    _PAGE_CACHE_UC_MINUS, NULL))
-		return -EINVAL;
+	ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
+			    _PAGE_CACHE_UC_MINUS, NULL);
+	if (ret)
+		goto out_err;
 
-	return _set_memory_uc(addr, numpages);
+	ret = _set_memory_uc(addr, numpages);
+	if (ret)
+		goto out_free;
+
+	return 0;
+
+out_free:
+	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
+out_err:
+	return ret;
 }
 EXPORT_SYMBOL(set_memory_uc);
 
 int set_memory_array_uc(unsigned long *addr, int addrinarray)
 {
-	unsigned long start;
-	unsigned long end;
-	int i;
+	int i, j;
+	int ret;
+
 	/*
 	 * for now UC MINUS. see comments in ioremap_nocache()
 	 */
 	for (i = 0; i < addrinarray; i++) {
-		start = __pa(addr[i]);
-		for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
-			if (end != __pa(addr[i + 1]))
-				break;
-			i++;
-		}
-		if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
-			goto out;
+		ret = reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE,
+					_PAGE_CACHE_UC_MINUS, NULL);
+		if (ret)
+			goto out_free;
 	}
 
-	return change_page_attr_set(addr, addrinarray,
+	ret = change_page_attr_set(addr, addrinarray,
 				    __pgprot(_PAGE_CACHE_UC_MINUS), 1);
-out:
-	for (i = 0; i < addrinarray; i++) {
-		unsigned long tmp = __pa(addr[i]);
+	if (ret)
+		goto out_free;
 
-		if (tmp == start)
-			break;
-		for (end = tmp + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
-			if (end != __pa(addr[i + 1]))
-				break;
-			i++;
-		}
-		free_memtype(tmp, end);
-	}
-	return -EINVAL;
+	return 0;
+
+out_free:
+	for (j = 0; j < i; j++)
+		free_memtype(__pa(addr[j]), __pa(addr[j]) + PAGE_SIZE);
+
+	return ret;
 }
 EXPORT_SYMBOL(set_memory_array_uc);
 
 int _set_memory_wc(unsigned long addr, int numpages)
 {
-	return change_page_attr_set(&addr, numpages,
+	int ret;
+	ret = change_page_attr_set(&addr, numpages,
+				    __pgprot(_PAGE_CACHE_UC_MINUS), 0);
+
+	if (!ret) {
+		ret = change_page_attr_set(&addr, numpages,
 				    __pgprot(_PAGE_CACHE_WC), 0);
+	}
+	return ret;
 }
 
 int set_memory_wc(unsigned long addr, int numpages)
 {
+	int ret;
+
 	if (!pat_enabled)
 		return set_memory_uc(addr, numpages);
 
-	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
-		_PAGE_CACHE_WC, NULL))
-		return -EINVAL;
+	ret = reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
+		_PAGE_CACHE_WC, NULL);
+	if (ret)
+		goto out_err;
 
-	return _set_memory_wc(addr, numpages);
+	ret = _set_memory_wc(addr, numpages);
+	if (ret)
+		goto out_free;
+
+	return 0;
+
+out_free:
+	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
+out_err:
+	return ret;
 }
 EXPORT_SYMBOL(set_memory_wc);
 
@@ -978,29 +1039,31 @@ int _set_memory_wb(unsigned long addr, i
 
 int set_memory_wb(unsigned long addr, int numpages)
 {
-	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
+	int ret;
 
-	return _set_memory_wb(addr, numpages);
+	ret = _set_memory_wb(addr, numpages);
+	if (ret)
+		return ret;
+
+	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
+	return 0;
 }
 EXPORT_SYMBOL(set_memory_wb);
 
 int set_memory_array_wb(unsigned long *addr, int addrinarray)
 {
 	int i;
+	int ret;
 
-	for (i = 0; i < addrinarray; i++) {
-		unsigned long start = __pa(addr[i]);
-		unsigned long end;
-
-		for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
-			if (end != __pa(addr[i + 1]))
-				break;
-			i++;
-		}
-		free_memtype(start, end);
-	}
-	return change_page_attr_clear(addr, addrinarray,
+	ret = change_page_attr_clear(addr, addrinarray,
 				      __pgprot(_PAGE_CACHE_MASK), 1);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < addrinarray; i++)
+		free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE);
+
+	return 0;
 }
 EXPORT_SYMBOL(set_memory_array_wb);
 
@@ -1036,7 +1099,7 @@ int set_memory_np(unsigned long addr, in
 int set_memory_4k(unsigned long addr, int numpages)
 {
 	return change_page_attr_set_clr(&addr, numpages, __pgprot(0),
-					__pgprot(0), 1, 0);
+					__pgprot(0), 1, 0, NULL);
 }
 
 int set_pages_uc(struct page *page, int numpages)
@@ -1047,6 +1110,35 @@ int set_pages_uc(struct page *page, int
 }
 EXPORT_SYMBOL(set_pages_uc);
 
+int set_pages_array_uc(struct page **pages, int addrinarray)
+{
+	unsigned long start;
+	unsigned long end;
+	int i;
+	int free_idx;
+
+	for (i = 0; i < addrinarray; i++) {
+		start = (unsigned long)page_address(pages[i]);
+		end = start + PAGE_SIZE;
+		if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
+			goto err_out;
+	}
+
+	if (cpa_set_pages_array(pages, addrinarray,
+			__pgprot(_PAGE_CACHE_UC_MINUS)) == 0) {
+		return 0; /* Success */
+	}
+err_out:
+	free_idx = i;
+	for (i = 0; i < free_idx; i++) {
+		start = (unsigned long)page_address(pages[i]);
+		end = start + PAGE_SIZE;
+		free_memtype(start, end);
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(set_pages_array_uc);
+
 int set_pages_wb(struct page *page, int numpages)
 {
 	unsigned long addr = (unsigned long)page_address(page);
@@ -1055,6 +1147,28 @@ int set_pages_wb(struct page *page, int
 }
 EXPORT_SYMBOL(set_pages_wb);
 
+int set_pages_array_wb(struct page **pages, int addrinarray)
+{
+	int retval;
+	unsigned long start;
+	unsigned long end;
+	int i;
+
+	retval = cpa_clear_pages_array(pages, addrinarray,
+			__pgprot(_PAGE_CACHE_MASK));
+	if (retval)
+		return retval;
+
+	for (i = 0; i < addrinarray; i++) {
+		start = (unsigned long)page_address(pages[i]);
+		end = start + PAGE_SIZE;
+		free_memtype(start, end);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(set_pages_array_wb);
+
 int set_pages_x(struct page *page, int numpages)
 {
 	unsigned long addr = (unsigned long)page_address(page);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/pat.c linux-libre-2.6.30-gnu1/arch/x86/mm/pat.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/pat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/pat.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@
 #ifdef CONFIG_X86_PAT
 int __read_mostly pat_enabled = 1;
 
-void __cpuinit pat_disable(char *reason)
+static inline void pat_disable(const char *reason)
 {
 	pat_enabled = 0;
 	printk(KERN_INFO "%s\n", reason);
@@ -43,6 +43,11 @@ static int __init nopat(char *str)
 	return 0;
 }
 early_param("nopat", nopat);
+#else
+static inline void pat_disable(const char *reason)
+{
+	(void)reason;
+}
 #endif
 
 
@@ -79,16 +84,20 @@ void pat_init(void)
 	if (!pat_enabled)
 		return;
 
-	/* Paranoia check. */
-	if (!cpu_has_pat && boot_pat_state) {
-		/*
-		 * If this happens we are on a secondary CPU, but
-		 * switched to PAT on the boot CPU. We have no way to
-		 * undo PAT.
-		 */
-		printk(KERN_ERR "PAT enabled, "
-		       "but not supported by secondary CPU\n");
-		BUG();
+	if (!cpu_has_pat) {
+		if (!boot_pat_state) {
+			pat_disable("PAT not supported by CPU.");
+			return;
+		} else {
+			/*
+			 * If this happens we are on a secondary CPU, but
+			 * switched to PAT on the boot CPU. We have no way to
+			 * undo PAT.
+			 */
+			printk(KERN_ERR "PAT enabled, "
+			       "but not supported by secondary CPU\n");
+			BUG();
+		}
 	}
 
 	/* Set PWT to Write-Combining. All other bits stay the same */
@@ -173,10 +182,10 @@ static unsigned long pat_x_mtrr_type(u64
 		u8 mtrr_type;
 
 		mtrr_type = mtrr_type_lookup(start, end);
-		if (mtrr_type == MTRR_TYPE_UNCACHABLE)
-			return _PAGE_CACHE_UC;
-		if (mtrr_type == MTRR_TYPE_WRCOMB)
-			return _PAGE_CACHE_WC;
+		if (mtrr_type != MTRR_TYPE_WRBACK)
+			return _PAGE_CACHE_UC_MINUS;
+
+		return _PAGE_CACHE_WB;
 	}
 
 	return req_type;
@@ -343,23 +352,13 @@ int reserve_memtype(u64 start, u64 end,
 		return 0;
 	}
 
-	if (req_type == -1) {
-		/*
-		 * Call mtrr_lookup to get the type hint. This is an
-		 * optimization for /dev/mem mmap'ers into WB memory (BIOS
-		 * tools and ACPI tools). Use WB request for WB memory and use
-		 * UC_MINUS otherwise.
-		 */
-		u8 mtrr_type = mtrr_type_lookup(start, end);
-
-		if (mtrr_type == MTRR_TYPE_WRBACK)
-			actual_type = _PAGE_CACHE_WB;
-		else
-			actual_type = _PAGE_CACHE_UC_MINUS;
-	} else {
-		actual_type = pat_x_mtrr_type(start, end,
-					      req_type & _PAGE_CACHE_MASK);
-	}
+	/*
+	 * Call mtrr_lookup to get the type hint. This is an
+	 * optimization for /dev/mem mmap'ers into WB memory (BIOS
+	 * tools and ACPI tools). Use WB request for WB memory and use
+	 * UC_MINUS otherwise.
+	 */
+	actual_type = pat_x_mtrr_type(start, end, req_type & _PAGE_CACHE_MASK);
 
 	if (new_type)
 		*new_type = actual_type;
@@ -537,9 +536,7 @@ static inline int range_is_allowed(unsig
 int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 				unsigned long size, pgprot_t *vma_prot)
 {
-	u64 offset = ((u64) pfn) << PAGE_SHIFT;
-	unsigned long flags = -1;
-	int retval;
+	unsigned long flags = _PAGE_CACHE_WB;
 
 	if (!range_is_allowed(pfn, size))
 		return 0;
@@ -567,62 +564,36 @@ int phys_mem_access_prot_allowed(struct
 	}
 #endif
 
-	/*
-	 * With O_SYNC, we can only take UC_MINUS mapping. Fail if we cannot.
-	 *
-	 * Without O_SYNC, we want to get
-	 * - 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
-	 */
-	if (flags != -1) {
-		retval = reserve_memtype(offset, offset + size, flags, NULL);
-	} else {
-		retval = reserve_memtype(offset, offset + size, -1, &flags);
-	}
-
-	if (retval < 0)
-		return 0;
-
-	if (((pfn < max_low_pfn_mapped) ||
-	     (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) &&
-	    ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
-		free_memtype(offset, offset + size);
-		printk(KERN_INFO
-		"%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
-			current->comm, current->pid,
-			cattr_name(flags),
-			offset, (unsigned long long)(offset + size));
-		return 0;
-	}
-
 	*vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
 			     flags);
 	return 1;
 }
 
-void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
+/*
+ * Change the memory type for the physial address range in kernel identity
+ * mapping space if that range is a part of identity map.
+ */
+int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
 {
-	unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);
-	u64 addr = (u64)pfn << PAGE_SHIFT;
-	unsigned long flags;
+	unsigned long id_sz;
 
-	reserve_memtype(addr, addr + size, want_flags, &flags);
-	if (flags != want_flags) {
+	if (!pat_enabled || base >= __pa(high_memory))
+		return 0;
+
+	id_sz = (__pa(high_memory) < base + size) ?
+				__pa(high_memory) - base :
+				size;
+
+	if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
 		printk(KERN_INFO
-		"%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
+			"%s:%d ioremap_change_attr failed %s "
+			"for %Lx-%Lx\n",
 			current->comm, current->pid,
-			cattr_name(want_flags),
-			addr, (unsigned long long)(addr + size),
-			cattr_name(flags));
+			cattr_name(flags),
+			base, (unsigned long long)(base + size));
+		return -EINVAL;
 	}
-}
-
-void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
-{
-	u64 addr = (u64)pfn << PAGE_SHIFT;
-
-	free_memtype(addr, addr + size);
+	return 0;
 }
 
 /*
@@ -634,17 +605,18 @@ static int reserve_pfn_range(u64 paddr,
 				int strict_prot)
 {
 	int is_ram = 0;
-	int id_sz, ret;
-	unsigned long flags;
+	int ret;
 	unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
+	unsigned long flags = want_flags;
 
 	is_ram = pat_pagerange_is_ram(paddr, paddr + size);
 
 	/*
-	 * reserve_pfn_range() doesn't support RAM pages.
+	 * reserve_pfn_range() doesn't support RAM pages. Maintain the current
+	 * behavior with RAM pages by returning success.
 	 */
 	if (is_ram != 0)
-		return -EINVAL;
+		return 0;
 
 	ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
 	if (ret)
@@ -671,23 +643,8 @@ static int reserve_pfn_range(u64 paddr,
 				     flags);
 	}
 
-	/* Need to keep identity mapping in sync */
-	if (paddr >= __pa(high_memory))
-		return 0;
-
-	id_sz = (__pa(high_memory) < paddr + size) ?
-				__pa(high_memory) - paddr :
-				size;
-
-	if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
+	if (kernel_map_sync_memtype(paddr, size, flags) < 0) {
 		free_memtype(paddr, paddr + size);
-		printk(KERN_ERR
-			"%s:%d reserve_pfn_range ioremap_change_attr failed %s "
-			"for %Lx-%Lx\n",
-			current->comm, current->pid,
-			cattr_name(flags),
-			(unsigned long long)paddr,
-			(unsigned long long)(paddr + size));
 		return -EINVAL;
 	}
 	return 0;
@@ -712,29 +669,28 @@ static void free_pfn_range(u64 paddr, un
  *
  * If the vma has a linear pfn mapping for the entire range, we get the prot
  * from pte and reserve the entire vma range with single reserve_pfn_range call.
- * Otherwise, we reserve the entire vma range, my ging through the PTEs page
- * by page to get physical address and protection.
  */
 int track_pfn_vma_copy(struct vm_area_struct *vma)
 {
-	int retval = 0;
-	unsigned long i, j;
 	resource_size_t paddr;
 	unsigned long prot;
-	unsigned long vma_start = vma->vm_start;
-	unsigned long vma_end = vma->vm_end;
-	unsigned long vma_size = vma_end - vma_start;
+	unsigned long vma_size = vma->vm_end - vma->vm_start;
 	pgprot_t pgprot;
 
 	if (!pat_enabled)
 		return 0;
 
+	/*
+	 * For now, only handle remap_pfn_range() vmas where
+	 * is_linear_pfn_mapping() == TRUE. Handling of
+	 * vm_insert_pfn() is TBD.
+	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/*
 		 * reserve the whole chunk covered by vma. We need the
 		 * starting address and protection from pte.
 		 */
-		if (follow_phys(vma, vma_start, 0, &prot, &paddr)) {
+		if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
 			WARN_ON_ONCE(1);
 			return -EINVAL;
 		}
@@ -742,28 +698,7 @@ int track_pfn_vma_copy(struct vm_area_st
 		return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
 	}
 
-	/* reserve entire vma page by page, using pfn and prot from pte */
-	for (i = 0; i < vma_size; i += PAGE_SIZE) {
-		if (follow_phys(vma, vma_start + i, 0, &prot, &paddr))
-			continue;
-
-		pgprot = __pgprot(prot);
-		retval = reserve_pfn_range(paddr, PAGE_SIZE, &pgprot, 1);
-		if (retval)
-			goto cleanup_ret;
-	}
 	return 0;
-
-cleanup_ret:
-	/* Reserve error: Cleanup partial reservation and return error */
-	for (j = 0; j < i; j += PAGE_SIZE) {
-		if (follow_phys(vma, vma_start + j, 0, &prot, &paddr))
-			continue;
-
-		free_pfn_range(paddr, PAGE_SIZE);
-	}
-
-	return retval;
 }
 
 /*
@@ -773,50 +708,28 @@ cleanup_ret:
  * prot is passed in as a parameter for the new mapping. If the vma has a
  * linear pfn mapping for the entire range reserve the entire vma range with
  * single reserve_pfn_range call.
- * Otherwise, we look t the pfn and size and reserve only the specified range
- * page by page.
- *
- * Note that this function can be called with caller trying to map only a
- * subrange/page inside the vma.
  */
 int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
 			unsigned long pfn, unsigned long size)
 {
-	int retval = 0;
-	unsigned long i, j;
-	resource_size_t base_paddr;
 	resource_size_t paddr;
-	unsigned long vma_start = vma->vm_start;
-	unsigned long vma_end = vma->vm_end;
-	unsigned long vma_size = vma_end - vma_start;
+	unsigned long vma_size = vma->vm_end - vma->vm_start;
 
 	if (!pat_enabled)
 		return 0;
 
+	/*
+	 * For now, only handle remap_pfn_range() vmas where
+	 * is_linear_pfn_mapping() == TRUE. Handling of
+	 * vm_insert_pfn() is TBD.
+	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/* reserve the whole chunk starting from vm_pgoff */
 		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
 		return reserve_pfn_range(paddr, vma_size, prot, 0);
 	}
 
-	/* reserve page by page using pfn and size */
-	base_paddr = (resource_size_t)pfn << PAGE_SHIFT;
-	for (i = 0; i < size; i += PAGE_SIZE) {
-		paddr = base_paddr + i;
-		retval = reserve_pfn_range(paddr, PAGE_SIZE, prot, 0);
-		if (retval)
-			goto cleanup_ret;
-	}
 	return 0;
-
-cleanup_ret:
-	/* Reserve error: Cleanup partial reservation and return error */
-	for (j = 0; j < i; j += PAGE_SIZE) {
-		paddr = base_paddr + j;
-		free_pfn_range(paddr, PAGE_SIZE);
-	}
-
-	return retval;
 }
 
 /*
@@ -827,39 +740,23 @@ cleanup_ret:
 void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
 			unsigned long size)
 {
-	unsigned long i;
 	resource_size_t paddr;
-	unsigned long prot;
-	unsigned long vma_start = vma->vm_start;
-	unsigned long vma_end = vma->vm_end;
-	unsigned long vma_size = vma_end - vma_start;
+	unsigned long vma_size = vma->vm_end - vma->vm_start;
 
 	if (!pat_enabled)
 		return;
 
+	/*
+	 * For now, only handle remap_pfn_range() vmas where
+	 * is_linear_pfn_mapping() == TRUE. Handling of
+	 * vm_insert_pfn() is TBD.
+	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/* free the whole chunk starting from vm_pgoff */
 		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
 		free_pfn_range(paddr, vma_size);
 		return;
 	}
-
-	if (size != 0 && size != vma_size) {
-		/* free page by page, using pfn and size */
-		paddr = (resource_size_t)pfn << PAGE_SHIFT;
-		for (i = 0; i < size; i += PAGE_SIZE) {
-			paddr = paddr + i;
-			free_pfn_range(paddr, PAGE_SIZE);
-		}
-	} else {
-		/* free entire vma, page by page, using the pfn from pte */
-		for (i = 0; i < vma_size; i += PAGE_SIZE) {
-			if (follow_phys(vma, vma_start + i, 0, &prot, &paddr))
-				continue;
-
-			free_pfn_range(paddr, PAGE_SIZE);
-		}
-	}
 }
 
 pgprot_t pgprot_writecombine(pgprot_t prot)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/pgtable_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/pgtable_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/pgtable_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/pgtable_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
+unsigned int __VMALLOC_RESERVE = 128 << 20;
+
 /*
  * Associate a virtual page frame with a given physical page frame 
  * and protection flags for that frame.
@@ -48,7 +50,7 @@ void set_pte_vaddr(unsigned long vaddr,
 	}
 	pte = pte_offset_kernel(pmd, vaddr);
 	if (pte_val(pteval))
-		set_pte_present(&init_mm, vaddr, pte, pteval);
+		set_pte_at(&init_mm, vaddr, pte, pteval);
 	else
 		pte_clear(&init_mm, vaddr, pte);
 
@@ -97,22 +99,6 @@ void set_pmd_pfn(unsigned long vaddr, un
 unsigned long __FIXADDR_TOP = 0xfffff000;
 EXPORT_SYMBOL(__FIXADDR_TOP);
 
-/**
- * reserve_top_address - reserves a hole in the top of kernel address space
- * @reserve - size of hole to reserve
- *
- * Can be used to relocate the fixmap area and poke a hole in the top
- * of kernel address space to make room for a hypervisor.
- */
-void __init reserve_top_address(unsigned long reserve)
-{
-	BUG_ON(fixmaps_set > 0);
-	printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
-	       (int)-reserve);
-	__FIXADDR_TOP = -reserve - PAGE_SIZE;
-	__VMALLOC_RESERVE += reserve;
-}
-
 /*
  * vmalloc=size forces the vmalloc area to be exactly 'size'
  * bytes. This can be used to increase (or decrease) the
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/pgtable.c linux-libre-2.6.30-gnu1/arch/x86/mm/pgtable.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/pgtable.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/pgtable.c	2009-06-09 23:05:27.000000000 -0400
@@ -313,6 +313,24 @@ int ptep_clear_flush_young(struct vm_are
 	return young;
 }
 
+/**
+ * reserve_top_address - reserves a hole in the top of kernel address space
+ * @reserve - size of hole to reserve
+ *
+ * Can be used to relocate the fixmap area and poke a hole in the top
+ * of kernel address space to make room for a hypervisor.
+ */
+void __init reserve_top_address(unsigned long reserve)
+{
+#ifdef CONFIG_X86_32
+	BUG_ON(fixmaps_set > 0);
+	printk(KERN_INFO "Reserving virtual address space above 0x%08x\n",
+	       (int)-reserve);
+	__FIXADDR_TOP = -reserve - PAGE_SIZE;
+	__VMALLOC_RESERVE += reserve;
+#endif
+}
+
 int fixmaps_set;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
@@ -327,7 +345,8 @@ void __native_set_fixmap(enum fixed_addr
 	fixmaps_set++;
 }
 
-void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys,
+		       pgprot_t flags)
 {
 	__native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/srat_32.c linux-libre-2.6.30-gnu1/arch/x86/mm/srat_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/srat_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/srat_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -216,7 +216,7 @@ int __init get_memcfg_from_srat(void)
 
 	if (num_memory_chunks == 0) {
 		printk(KERN_WARNING
-			 "could not finy any ACPI SRAT memory areas.\n");
+			 "could not find any ACPI SRAT memory areas.\n");
 		goto out_fail;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/srat_64.c linux-libre-2.6.30-gnu1/arch/x86/mm/srat_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/srat_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/srat_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,13 +20,15 @@
 #include <asm/proto.h>
 #include <asm/numa.h>
 #include <asm/e820.h>
-#include <asm/genapic.h>
+#include <asm/apic.h>
+#include <asm/uv/uv.h>
 
 int acpi_numa __initdata;
 
 static struct acpi_table_slit *acpi_slit;
 
 static nodemask_t nodes_parsed __initdata;
+static nodemask_t cpu_nodes_parsed __initdata;
 static struct bootnode nodes[MAX_NUMNODES] __initdata;
 static struct bootnode nodes_add[MAX_NUMNODES];
 static int found_add_area __initdata;
@@ -115,6 +117,37 @@ void __init acpi_numa_slit_init(struct a
 	reserve_early(phys, phys + length, "ACPI SLIT");
 }
 
+/* Callback for Proximity Domain -> x2APIC mapping */
+void __init
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+	int pxm, node;
+	int apic_id;
+
+	if (srat_disabled())
+		return;
+	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
+		bad_srat();
+		return;
+	}
+	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+		return;
+	pxm = pa->proximity_domain;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+		bad_srat();
+		return;
+	}
+
+	apic_id = pa->apic_id;
+	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",
+	       pxm, apic_id, node);
+}
+
 /* Callback for Proximity Domain -> LAPIC mapping */
 void __init
 acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
@@ -143,6 +176,7 @@ acpi_numa_processor_affinity_init(struct
 	else
 		apic_id = pa->apic_id;
 	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",
 	       pxm, apic_id, node);
@@ -327,6 +361,7 @@ static void __init unparse_node(int node
 {
 	int i;
 	node_clear(node, nodes_parsed);
+	node_clear(node, cpu_nodes_parsed);
 	for (i = 0; i < MAX_LOCAL_APIC; i++) {
 		if (apicid_to_node[i] == node)
 			apicid_to_node[i] = NUMA_NO_NODE;
@@ -371,7 +406,8 @@ int __init acpi_scan_nodes(unsigned long
 		return -1;
 	}
 
-	node_possible_map = nodes_parsed;
+	/* Account for nodes with cpus and no memory */
+	nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed);
 
 	/* Finally register nodes */
 	for_each_node_mask(i, node_possible_map)
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/mm/tlb.c linux-libre-2.6.30-gnu1/arch/x86/mm/tlb.c
--- linux-libre-2.6.29-gnu1/arch/x86/mm/tlb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/mm/tlb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,290 @@
+#include <linux/init.h>
+
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/apic.h>
+#include <asm/uv/uv.h>
+
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
+			= { &init_mm, 0, };
+
+/*
+ *	Smarter SMP flushing macros.
+ *		c/o Linus Torvalds.
+ *
+ *	These mean you can really definitely utterly forget about
+ *	writing to user space from interrupts. (Its not allowed anyway).
+ *
+ *	Optimizations Manfred Spraul <manfred@colorfullife.com>
+ *
+ *	More scalable flush, from Andi Kleen
+ *
+ *	To avoid global state use 8 different call vectors.
+ *	Each CPU uses a specific vector to trigger flushes on other
+ *	CPUs. Depending on the received vector the target CPUs look into
+ *	the right array slot for the flush data.
+ *
+ *	With more than 8 CPUs they are hashed to the 8 available
+ *	vectors. The limited global vector space forces us to this right now.
+ *	In future when interrupts are split into per CPU domains this could be
+ *	fixed, at the cost of triggering multiple IPIs in some cases.
+ */
+
+union smp_flush_state {
+	struct {
+		struct mm_struct *flush_mm;
+		unsigned long flush_va;
+		spinlock_t tlbstate_lock;
+		DECLARE_BITMAP(flush_cpumask, NR_CPUS);
+	};
+	char pad[CONFIG_X86_INTERNODE_CACHE_BYTES];
+} ____cacheline_internodealigned_in_smp;
+
+/* State is put into the per CPU data section, but padded
+   to a full cache line because other CPUs can access it and we don't
+   want false sharing in the per cpu data segment. */
+static union smp_flush_state flush_state[NUM_INVALIDATE_TLB_VECTORS];
+
+/*
+ * We cannot call mmdrop() because we are in interrupt context,
+ * instead update mm->cpu_vm_mask.
+ */
+void leave_mm(int cpu)
+{
+	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+		BUG();
+	cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask);
+	load_cr3(swapper_pg_dir);
+}
+EXPORT_SYMBOL_GPL(leave_mm);
+
+/*
+ *
+ * The flush IPI assumes that a thread switch happens in this order:
+ * [cpu0: the cpu that switches]
+ * 1) switch_mm() either 1a) or 1b)
+ * 1a) thread switch to a different mm
+ * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
+ *	Stop ipi delivery for the old mm. This is not synchronized with
+ *	the other cpus, but smp_invalidate_interrupt ignore flush ipis
+ *	for the wrong mm, and in the worst case we perform a superfluous
+ *	tlb flush.
+ * 1a2) set cpu mmu_state to TLBSTATE_OK
+ *	Now the smp_invalidate_interrupt won't call leave_mm if cpu0
+ *	was in lazy tlb mode.
+ * 1a3) update cpu active_mm
+ *	Now cpu0 accepts tlb flushes for the new mm.
+ * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
+ *	Now the other cpus will send tlb flush ipis.
+ * 1a4) change cr3.
+ * 1b) thread switch without mm change
+ *	cpu active_mm is correct, cpu0 already handles
+ *	flush ipis.
+ * 1b1) set cpu mmu_state to TLBSTATE_OK
+ * 1b2) test_and_set the cpu bit in cpu_vm_mask.
+ *	Atomically set the bit [other cpus will start sending flush ipis],
+ *	and test the bit.
+ * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
+ * 2) switch %%esp, ie current
+ *
+ * The interrupt must handle 2 special cases:
+ * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm.
+ * - the cpu performs speculative tlb reads, i.e. even if the cpu only
+ *   runs in kernel space, the cpu could load tlb entries for user space
+ *   pages.
+ *
+ * The good news is that cpu mmu_state is local to each cpu, no
+ * write/read ordering problems.
+ */
+
+/*
+ * TLB flush IPI:
+ *
+ * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
+ * 2) Leave the mm if we are in the lazy tlb mode.
+ *
+ * Interrupts are disabled.
+ */
+
+/*
+ * FIXME: use of asmlinkage is not consistent.  On x86_64 it's noop
+ * but still used for documentation purpose but the usage is slightly
+ * inconsistent.  On x86_32, asmlinkage is regparm(0) but interrupt
+ * entry calls in with the first parameter in %eax.  Maybe define
+ * intrlinkage?
+ */
+#ifdef CONFIG_X86_64
+asmlinkage
+#endif
+void smp_invalidate_interrupt(struct pt_regs *regs)
+{
+	unsigned int cpu;
+	unsigned int sender;
+	union smp_flush_state *f;
+
+	cpu = smp_processor_id();
+	/*
+	 * orig_rax contains the negated interrupt vector.
+	 * Use that to determine where the sender put the data.
+	 */
+	sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
+	f = &flush_state[sender];
+
+	if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask)))
+		goto out;
+		/*
+		 * This was a BUG() but until someone can quote me the
+		 * line from the intel manual that guarantees an IPI to
+		 * multiple CPUs is retried _only_ on the erroring CPUs
+		 * its staying as a return
+		 *
+		 * BUG();
+		 */
+
+	if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) {
+		if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
+			if (f->flush_va == TLB_FLUSH_ALL)
+				local_flush_tlb();
+			else
+				__flush_tlb_one(f->flush_va);
+		} else
+			leave_mm(cpu);
+	}
+out:
+	ack_APIC_irq();
+	smp_mb__before_clear_bit();
+	cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask));
+	smp_mb__after_clear_bit();
+	inc_irq_stat(irq_tlb_count);
+}
+
+static void flush_tlb_others_ipi(const struct cpumask *cpumask,
+				 struct mm_struct *mm, unsigned long va)
+{
+	unsigned int sender;
+	union smp_flush_state *f;
+
+	/* Caller has disabled preemption */
+	sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
+	f = &flush_state[sender];
+
+	/*
+	 * Could avoid this lock when
+	 * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
+	 * probably not worth checking this for a cache-hot lock.
+	 */
+	spin_lock(&f->tlbstate_lock);
+
+	f->flush_mm = mm;
+	f->flush_va = va;
+	cpumask_andnot(to_cpumask(f->flush_cpumask),
+		       cpumask, cpumask_of(smp_processor_id()));
+
+	/*
+	 * We have to send the IPI only to
+	 * CPUs affected.
+	 */
+	apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
+		      INVALIDATE_TLB_VECTOR_START + sender);
+
+	while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
+		cpu_relax();
+
+	f->flush_mm = NULL;
+	f->flush_va = 0;
+	spin_unlock(&f->tlbstate_lock);
+}
+
+void native_flush_tlb_others(const struct cpumask *cpumask,
+			     struct mm_struct *mm, unsigned long va)
+{
+	if (is_uv_system()) {
+		unsigned int cpu;
+
+		cpu = get_cpu();
+		cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu);
+		if (cpumask)
+			flush_tlb_others_ipi(cpumask, mm, va);
+		put_cpu();
+		return;
+	}
+	flush_tlb_others_ipi(cpumask, mm, va);
+}
+
+static int __cpuinit init_smp_flush(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(flush_state); i++)
+		spin_lock_init(&flush_state[i].tlbstate_lock);
+
+	return 0;
+}
+core_initcall(init_smp_flush);
+
+void flush_tlb_current_task(void)
+{
+	struct mm_struct *mm = current->mm;
+
+	preempt_disable();
+
+	local_flush_tlb();
+	if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+		flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
+	preempt_enable();
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	preempt_disable();
+
+	if (current->active_mm == mm) {
+		if (current->mm)
+			local_flush_tlb();
+		else
+			leave_mm(smp_processor_id());
+	}
+	if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+		flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
+
+	preempt_enable();
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
+{
+	struct mm_struct *mm = vma->vm_mm;
+
+	preempt_disable();
+
+	if (current->active_mm == mm) {
+		if (current->mm)
+			__flush_tlb_one(va);
+		else
+			leave_mm(smp_processor_id());
+	}
+
+	if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+		flush_tlb_others(&mm->cpu_vm_mask, mm, va);
+
+	preempt_enable();
+}
+
+static void do_flush_tlb_all(void *info)
+{
+	unsigned long cpu = smp_processor_id();
+
+	__flush_tlb_all();
+	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
+		leave_mm(cpu);
+}
+
+void flush_tlb_all(void)
+{
+	on_each_cpu(do_flush_tlb_all, NULL, 1);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/oprofile/backtrace.c linux-libre-2.6.30-gnu1/arch/x86/oprofile/backtrace.c
--- linux-libre-2.6.29-gnu1/arch/x86/oprofile/backtrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/oprofile/backtrace.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,9 +76,9 @@ void
 x86_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
 	struct frame_head *head = (struct frame_head *)frame_pointer(regs);
-	unsigned long stack = kernel_trap_sp(regs);
 
 	if (!user_mode_vm(regs)) {
+		unsigned long stack = kernel_stack_pointer(regs);
 		if (depth)
 			dump_trace(NULL, regs, (unsigned long *)stack, 0,
 				   &backtrace_ops, &depth);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/oprofile/op_model_p4.c linux-libre-2.6.30-gnu1/arch/x86/oprofile/op_model_p4.c
--- linux-libre-2.6.29-gnu1/arch/x86/oprofile/op_model_p4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/oprofile/op_model_p4.c	2009-06-09 23:05:27.000000000 -0400
@@ -380,7 +380,7 @@ static unsigned int get_stagger(void)
 {
 #ifdef CONFIG_SMP
 	int cpu = smp_processor_id();
-	return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
+	return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
 #endif
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/amd_bus.c linux-libre-2.6.30-gnu1/arch/x86/pci/amd_bus.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/amd_bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/amd_bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,12 +94,16 @@ struct pci_root_info {
 static int pci_root_num;
 static struct pci_root_info pci_root_info[PCI_ROOT_NR];
 
-void set_pci_bus_resources_arch_default(struct pci_bus *b)
+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 */
+	if (pci_probe & PCI_USE__CRS)
+		return;
+
 	/* if only one root bus, don't need to anything */
 	if (pci_root_num < 2)
 		return;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/common.c linux-libre-2.6.30-gnu1/arch/x86/pci/common.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/common.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,7 @@ static int __devinit can_skip_ioresource
 	return 0;
 }
 
-static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
+static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitconst = {
 /*
  * Systems where PCI IO resource ISA alignment can be skipped
  * when the ISA enable bit in the bridge control is not set
@@ -147,10 +147,13 @@ static void __devinit pcibios_fixup_devi
  *  are examined.
  */
 
-void __devinit  pcibios_fixup_bus(struct pci_bus *b)
+void __devinit pcibios_fixup_bus(struct pci_bus *b)
 {
 	struct pci_dev *dev;
 
+	/* root bus? */
+	if (!b->parent)
+		x86_pci_root_bus_res_quirks(b);
 	pci_read_bridge_bases(b);
 	list_for_each_entry(dev, &b->devices, bus_list)
 		pcibios_fixup_device_resources(dev);
@@ -183,7 +186,7 @@ static int __devinit assign_all_busses(c
 }
 #endif
 
-static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
+static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = {
 #ifdef __i386__
 /*
  * Laptops which need pci=assign-busses to see Cardbus cards
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/early.c linux-libre-2.6.30-gnu1/arch/x86/pci/early.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/early.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/early.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,11 +69,12 @@ void early_dump_pci_device(u8 bus, u8 sl
 	int j;
 	u32 val;
 
-	printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func);
+	printk(KERN_INFO "pci 0000:%02x:%02x.%d config space:",
+	       bus, slot, func);
 
 	for (i = 0; i < 256; i += 4) {
 		if (!(i & 0x0f))
-			printk("\n%04x:",i);
+			printk("\n  %02x:",i);
 
 		val = read_pci_config(bus, slot, func, i);
 		for (j = 0; j < 4; j++) {
@@ -96,20 +97,22 @@ void early_dump_pci_devices(void)
 			for (func = 0; func < 8; func++) {
 				u32 class;
 				u8 type;
+
 				class = read_pci_config(bus, slot, func,
 							PCI_CLASS_REVISION);
 				if (class == 0xffffffff)
-					break;
+					continue;
 
 				early_dump_pci_device(bus, slot, func);
 
-				/* No multi-function device? */
-				type = read_pci_config_byte(bus, slot, func,
+				if (func == 0) {
+					type = read_pci_config_byte(bus, slot,
+								    func,
 							       PCI_HEADER_TYPE);
-				if (!(type & 0x80))
-					break;
+					if (!(type & 0x80))
+						break;
+				}
 			}
 		}
 	}
 }
-
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/fixup.c linux-libre-2.6.30-gnu1/arch/x86/pci/fixup.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/fixup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/fixup.c	2009-06-09 23:05:27.000000000 -0400
@@ -356,7 +356,7 @@ static void __devinit pci_fixup_video(st
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
 
 
-static struct dmi_system_id __devinitdata msi_k8t_dmi_table[] = {
+static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = {
 	{
 		.ident = "MSI-K8T-Neo2Fir",
 		.matches = {
@@ -413,7 +413,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_V
  */
 static u16 toshiba_line_size;
 
-static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
+static const struct dmi_system_id __devinitconst toshiba_ohci1394_dmi_table[] = {
 	{
 		.ident = "Toshiba PS5 based laptop",
 		.matches = {
@@ -495,26 +495,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S
 			  pci_siemens_interrupt_controller);
 
 /*
- * Regular PCI devices have 256 bytes, but AMD Family 10h/11h CPUs have
- * 4096 bytes configuration space for each function of their processor
- * configuration space.
- */
-static void amd_cpu_pci_cfg_space_size(struct pci_dev *dev)
-{
-	dev->cfg_size = pci_cfg_space_size_ext(dev);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1300, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1301, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1302, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1303, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1304, amd_cpu_pci_cfg_space_size);
-
-/*
  * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from
  * confusing the PCI engine:
  */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/i386.c linux-libre-2.6.30-gnu1/arch/x86/pci/i386.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/i386.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/i386.c	2009-06-09 23:05:27.000000000 -0400
@@ -238,6 +238,10 @@ void __init pcibios_resource_survey(void
  */
 fs_initcall(pcibios_assign_resources);
 
+void __weak x86_pci_root_bus_res_quirks(struct pci_bus *b)
+{
+}
+
 /*
  *  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.
@@ -258,24 +262,7 @@ void pcibios_set_master(struct pci_dev *
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
 
-static void pci_unmap_page_range(struct vm_area_struct *vma)
-{
-	u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
-	free_memtype(addr, addr + vma->vm_end - vma->vm_start);
-}
-
-static void pci_track_mmap_page_range(struct vm_area_struct *vma)
-{
-	u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long flags = pgprot_val(vma->vm_page_prot)
-						& _PAGE_CACHE_MASK;
-
-	reserve_memtype(addr, addr + vma->vm_end - vma->vm_start, flags, NULL);
-}
-
 static struct vm_operations_struct pci_mmap_ops = {
-	.open  = pci_track_mmap_page_range,
-	.close = pci_unmap_page_range,
 	.access = generic_access_phys,
 };
 
@@ -283,11 +270,6 @@ int pci_mmap_page_range(struct pci_dev *
 			enum pci_mmap_state mmap_state, int write_combine)
 {
 	unsigned long prot;
-	u64 addr = vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long len = vma->vm_end - vma->vm_start;
-	unsigned long flags;
-	unsigned long new_flags;
-	int retval;
 
 	/* I/O space cannot be accessed via normal processor loads and
 	 * stores on this platform.
@@ -308,27 +290,6 @@ int pci_mmap_page_range(struct pci_dev *
 
 	vma->vm_page_prot = __pgprot(prot);
 
-	flags = pgprot_val(vma->vm_page_prot) & _PAGE_CACHE_MASK;
-	retval = reserve_memtype(addr, addr + len, flags, &new_flags);
-	if (retval)
-		return retval;
-
-	if (flags != new_flags) {
-		if (!is_new_memtype_allowed(flags, new_flags)) {
-			free_memtype(addr, addr+len);
-			return -EINVAL;
-		}
-		flags = new_flags;
-	}
-
-	if (((vma->vm_pgoff < max_low_pfn_mapped) ||
-	     (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) &&
-	      vma->vm_pgoff < max_pfn_mapped)) &&
-	    ioremap_change_attr((unsigned long)__va(addr), len, flags)) {
-		free_memtype(addr, addr + len);
-		return -EINVAL;
-	}
-
 	if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot))
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/legacy.c linux-libre-2.6.30-gnu1/arch/x86/pci/legacy.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/legacy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/legacy.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,8 +50,6 @@ static int __init pci_legacy_init(void)
 	if (pci_root_bus)
 		pci_bus_add_devices(pci_root_bus);
 
-	pcibios_fixup_peer_bridges();
-
 	return 0;
 }
 
@@ -67,6 +65,7 @@ int __init pci_subsys_init(void)
 	pci_visws_init();
 #endif
 	pci_legacy_init();
+	pcibios_fixup_peer_bridges();
 	pcibios_irq_init();
 	pcibios_init();
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/mmconfig_64.c linux-libre-2.6.30-gnu1/arch/x86/pci/mmconfig_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/mmconfig_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/mmconfig_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,13 +112,18 @@ static struct pci_raw_ops pci_mmcfg = {
 static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
 {
 	void __iomem *addr;
-	u32 size;
+	u64 start, size;
 
-	size = (cfg->end_bus_number + 1) << 20;
-	addr = ioremap_nocache(cfg->address, size);
+	start = cfg->start_bus_number;
+	start <<= 20;
+	start += cfg->address;
+	size = cfg->end_bus_number + 1 - cfg->start_bus_number;
+	size <<= 20;
+	addr = ioremap_nocache(start, size);
 	if (addr) {
 		printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
-		       cfg->address, cfg->address + size - 1);
+		       start, start + size - 1);
+		addr -= cfg->start_bus_number << 20;
 	}
 	return addr;
 }
@@ -157,7 +162,7 @@ void __init pci_mmcfg_arch_free(void)
 
 	for (i = 0; i < pci_mmcfg_config_num; ++i) {
 		if (pci_mmcfg_virt[i].virt) {
-			iounmap(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;
 		}
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/mmconfig-shared.c linux-libre-2.6.30-gnu1/arch/x86/pci/mmconfig-shared.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/mmconfig-shared.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/mmconfig-shared.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
+#include <linux/sort.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
 
@@ -24,24 +25,49 @@
 /* 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)
+{
+	struct acpi_mcfg_allocation *new;
+	int new_num = pci_mmcfg_config_num + num;
+
+	new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL);
+	if (!new)
+		return -1;
+
+	if (pci_mmcfg_config) {
+		memcpy(new, pci_mmcfg_config,
+			 sizeof(pci_mmcfg_config[0]) * new_num);
+		kfree(pci_mmcfg_config);
+	}
+	pci_mmcfg_config = new;
+
+	return 0;
+}
+
+static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end)
+{
+	int i = pci_mmcfg_config_num;
+
+	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;
+}
+
 static const char __init *pci_mmcfg_e7520(void)
 {
 	u32 win;
 	raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win);
 
 	win = win & 0xf000;
-	if(win == 0x0000 || win == 0xf000)
-		pci_mmcfg_config_num = 0;
-	else {
-		pci_mmcfg_config_num = 1;
-		pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
-		if (!pci_mmcfg_config)
-			return NULL;
-		pci_mmcfg_config[0].address = win << 16;
-		pci_mmcfg_config[0].pci_segment = 0;
-		pci_mmcfg_config[0].start_bus_number = 0;
-		pci_mmcfg_config[0].end_bus_number = 255;
-	}
+	if (win == 0x0000 || win == 0xf000)
+		return NULL;
+
+	if (extend_mmcfg(1) == -1)
+		return NULL;
+
+	fill_one_mmcfg(win << 16, 0, 0, 255);
 
 	return "Intel Corporation E7520 Memory Controller Hub";
 }
@@ -50,13 +76,11 @@ static const char __init *pci_mmcfg_inte
 {
 	u32 pciexbar, mask = 0, len = 0;
 
-	pci_mmcfg_config_num = 1;
-
 	raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar);
 
 	/* Enable bit */
 	if (!(pciexbar & 1))
-		pci_mmcfg_config_num = 0;
+		return NULL;
 
 	/* Size bits */
 	switch ((pciexbar >> 1) & 3) {
@@ -73,28 +97,23 @@ static const char __init *pci_mmcfg_inte
 		len  = 0x04000000U;
 		break;
 	default:
-		pci_mmcfg_config_num = 0;
+		return NULL;
 	}
 
 	/* Errata #2, things break when not aligned on a 256Mb boundary */
 	/* Can only happen in 64M/128M mode */
 
 	if ((pciexbar & mask) & 0x0fffffffU)
-		pci_mmcfg_config_num = 0;
+		return NULL;
 
 	/* Don't hit the APIC registers and their friends */
 	if ((pciexbar & mask) >= 0xf0000000U)
-		pci_mmcfg_config_num = 0;
+		return NULL;
 
-	if (pci_mmcfg_config_num) {
-		pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
-		if (!pci_mmcfg_config)
-			return NULL;
-		pci_mmcfg_config[0].address = pciexbar & mask;
-		pci_mmcfg_config[0].pci_segment = 0;
-		pci_mmcfg_config[0].start_bus_number = 0;
-		pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
-	}
+	if (extend_mmcfg(1) == -1)
+		return NULL;
+
+	fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
 
 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
 }
@@ -138,22 +157,77 @@ static const char __init *pci_mmcfg_amd_
 		busnbits = 8;
 	}
 
-	pci_mmcfg_config_num = (1 << segnbits);
-	pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) *
-				   pci_mmcfg_config_num, GFP_KERNEL);
-	if (!pci_mmcfg_config)
+	if (extend_mmcfg(1 << segnbits) == -1)
 		return NULL;
 
-	for (i = 0; i < (1 << segnbits); i++) {
-		pci_mmcfg_config[i].address = base + (1<<28) * i;
-		pci_mmcfg_config[i].pci_segment = i;
-		pci_mmcfg_config[i].start_bus_number = 0;
-		pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1;
-	}
+	for (i = 0; i < (1 << segnbits); i++)
+		fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1);
 
 	return "AMD Family 10h NB";
 }
 
+static bool __initdata mcp55_checked;
+static const char __init *pci_mmcfg_nvidia_mcp55(void)
+{
+	int bus;
+	int mcp55_mmconf_found = 0;
+
+	static const u32 extcfg_regnum		= 0x90;
+	static const u32 extcfg_regsize		= 4;
+	static const u32 extcfg_enable_mask	= 1<<31;
+	static const u32 extcfg_start_mask	= 0xff<<16;
+	static const int extcfg_start_shift	= 16;
+	static const u32 extcfg_size_mask	= 0x3<<28;
+	static const int extcfg_size_shift	= 28;
+	static const int extcfg_sizebus[]	= {0x100, 0x80, 0x40, 0x20};
+	static const u32 extcfg_base_mask[]	= {0x7ff8, 0x7ffc, 0x7ffe, 0x7fff};
+	static const int extcfg_base_lshift	= 25;
+
+	/*
+	 * do check if amd fam10h already took over
+	 */
+	if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked)
+		return NULL;
+
+	mcp55_checked = true;
+	for (bus = 0; bus < 256; bus++) {
+		u64 base;
+		u32 l, extcfg;
+		u16 vendor, device;
+		int start, size_index, end;
+
+		raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), 0, 4, &l);
+		vendor = l & 0xffff;
+		device = (l >> 16) & 0xffff;
+
+		if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
+			continue;
+
+		raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), extcfg_regnum,
+				  extcfg_regsize, &extcfg);
+
+		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);
+		mcp55_mmconf_found++;
+	}
+
+	if (!mcp55_mmconf_found)
+		return NULL;
+
+	return "nVidia MCP55";
+}
+
 struct pci_mmcfg_hostbridge_probe {
 	u32 bus;
 	u32 devfn;
@@ -171,8 +245,52 @@ static struct pci_mmcfg_hostbridge_probe
 	  0x1200, pci_mmcfg_amd_fam10h },
 	{ 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD,
 	  0x1200, pci_mmcfg_amd_fam10h },
+	{ 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_NVIDIA,
+	  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);
+
+	/* 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;
+	}
+
+	/* 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 (cfg->end_bus_number < cfg->start_bus_number)
+			cfg->end_bus_number = 255;
+
+		if (cfg->end_bus_number >= cfgx->start_bus_number)
+			cfg->end_bus_number = cfgx->start_bus_number - 1;
+	}
+}
+
 static int __init pci_mmcfg_check_hostbridge(void)
 {
 	u32 l;
@@ -186,31 +304,33 @@ static int __init pci_mmcfg_check_hostbr
 
 	pci_mmcfg_config_num = 0;
 	pci_mmcfg_config = NULL;
-	name = NULL;
 
-	for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
+	for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
 		bus =  pci_mmcfg_probes[i].bus;
 		devfn = pci_mmcfg_probes[i].devfn;
 		raw_pci_ops->read(0, bus, devfn, 0, 4, &l);
 		vendor = l & 0xffff;
 		device = (l >> 16) & 0xffff;
 
+		name = NULL;
 		if (pci_mmcfg_probes[i].vendor == vendor &&
 		    pci_mmcfg_probes[i].device == device)
 			name = pci_mmcfg_probes[i].probe();
-	}
 
-	if (name) {
-		printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
-		       name, pci_mmcfg_config_num ? "with" : "without");
+		if (name)
+			printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n",
+			       name);
 	}
 
-	return name != NULL;
+	/* some end_bus_number is crazy, fix it */
+	pci_mmcfg_check_end_bus_number();
+
+	return pci_mmcfg_config_num != 0;
 }
 
 static void __init pci_mmcfg_insert_resources(void)
 {
-#define PCI_MMCFG_RESOURCE_NAME_LEN 19
+#define PCI_MMCFG_RESOURCE_NAME_LEN 24
 	int i;
 	struct resource *res;
 	char *names;
@@ -228,9 +348,10 @@ static void __init pci_mmcfg_insert_reso
 		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",
-			 cfg->pci_segment);
-		res->start = cfg->address;
+		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);
@@ -297,7 +418,7 @@ static int __init is_acpi_reserved(u64 s
 	struct resource mcfg_res;
 
 	mcfg_res.start = start;
-	mcfg_res.end = end;
+	mcfg_res.end = end - 1;
 	mcfg_res.flags = 0;
 
 	acpi_get_devices("PNP0C01", find_mboard_resource, &mcfg_res, NULL);
@@ -318,7 +439,7 @@ static int __init is_mmconf_reserved(che
 	u64 old_size = size;
 	int valid = 0;
 
-	while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) {
+	while (!is_reserved(addr, addr + size, E820_RESERVED)) {
 		size >>= 1;
 		if (size < (16UL<<20))
 			break;
@@ -354,8 +475,6 @@ static void __init pci_mmcfg_reject_brok
 	    (pci_mmcfg_config[0].address == 0))
 		return;
 
-	cfg = &pci_mmcfg_config[0];
-
 	for (i = 0; i < pci_mmcfg_config_num; i++) {
 		int valid = 0;
 		u64 addr, size;
@@ -423,10 +542,10 @@ static void __init __pci_mmcfg_init(int
 			known_bridge = 1;
 	}
 
-	if (!known_bridge) {
+	if (!known_bridge)
 		acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
-		pci_mmcfg_reject_broken(early);
-	}
+
+	pci_mmcfg_reject_broken(early);
 
 	if ((pci_mmcfg_config_num == 0) ||
 	    (pci_mmcfg_config == NULL) ||
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/numaq_32.c linux-libre-2.6.30-gnu1/arch/x86/pci/numaq_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/numaq_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/numaq_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/nodemask.h>
-#include <mach_apic.h>
+#include <asm/apic.h>
 #include <asm/mpspec.h>
 #include <asm/pci_x86.h>
 
@@ -18,10 +18,6 @@
 
 #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
 
-/* Where the IO area was mapped on multiquad, always 0 otherwise */
-void *xquad_portio;
-EXPORT_SYMBOL(xquad_portio);
-
 #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
 
 #define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/pci/pcbios.c linux-libre-2.6.30-gnu1/arch/x86/pci/pcbios.c
--- linux-libre-2.6.29-gnu1/arch/x86/pci/pcbios.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/pci/pcbios.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <asm/pci_x86.h>
-#include <asm/mach-default/pci-functions.h>
+#include <asm/pci-functions.h>
 
 /* BIOS32 signature: "_32_" */
 #define BIOS32_SIGNATURE	(('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/cpu_32.c linux-libre-2.6.30-gnu1/arch/x86/power/cpu_32.c
--- linux-libre-2.6.29-gnu1/arch/x86/power/cpu_32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/cpu_32.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <asm/mtrr.h>
 #include <asm/mce.h>
 #include <asm/xcr.h>
+#include <asm/suspend.h>
 
 static struct saved_context saved_context;
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/cpu_64.c linux-libre-2.6.30-gnu1/arch/x86/power/cpu_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/power/cpu_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/cpu_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/mtrr.h>
 #include <asm/xcr.h>
+#include <asm/suspend.h>
 
 static void fix_processor_context(void);
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_64.c linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_64.c
--- linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_64.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_64.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/mtrr.h>
+#include <asm/suspend.h>
 
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_asm_32.S linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_asm_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_asm_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_asm_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/asm-offsets.h>
 #include <asm/processor-flags.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_asm_64.S linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_asm_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/power/hibernate_asm_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/hibernate_asm_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 	.text
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 #include <asm/asm-offsets.h>
 #include <asm/processor-flags.h>
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/power/Makefile linux-libre-2.6.30-gnu1/arch/x86/power/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/power/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/power/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,2 +1,7 @@
+# __restore_processor_state() restores %gs after S3 resume and so should not
+# itself be stack-protected
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_cpu_$(BITS).o	:= $(nostackp)
+
 obj-$(CONFIG_PM_SLEEP)		+= cpu_$(BITS).o
 obj-$(CONFIG_HIBERNATION)	+= hibernate_$(BITS).o hibernate_asm_$(BITS).o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/vdso/Makefile linux-libre-2.6.30-gnu1/arch/x86/vdso/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/vdso/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/vdso/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
 	$(call if_changed,objcopy)
 
 CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-       $(filter -g%,$(KBUILD_CFLAGS))
+       $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector)
 
 $(vobjs): KBUILD_CFLAGS += $(CFL)
 
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/vdso/vclock_gettime.c linux-libre-2.6.30-gnu1/arch/x86/vdso/vclock_gettime.c
--- linux-libre-2.6.29-gnu1/arch/x86/vdso/vclock_gettime.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/vdso/vclock_gettime.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,11 +104,13 @@ notrace int __vdso_gettimeofday(struct t
 {
 	long ret;
 	if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
-		BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
-			     offsetof(struct timespec, tv_nsec) ||
-			     sizeof(*tv) != sizeof(struct timespec));
-		do_realtime((struct timespec *)tv);
-		tv->tv_usec /= 1000;
+		if (likely(tv != NULL)) {
+			BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
+				     offsetof(struct timespec, tv_nsec) ||
+				     sizeof(*tv) != sizeof(struct timespec));
+			do_realtime((struct timespec *)tv);
+			tv->tv_usec /= 1000;
+		}
 		if (unlikely(tz != NULL)) {
 			/* Avoid memcpy. Some old compilers fail to inline it */
 			tz->tz_minuteswest = gtod->sys_tz.tz_minuteswest;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/vdso/vma.c linux-libre-2.6.30-gnu1/arch/x86/vdso/vma.c
--- linux-libre-2.6.29-gnu1/arch/x86/vdso/vma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/vdso/vma.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,8 +85,8 @@ static unsigned long vdso_addr(unsigned
 	unsigned long addr, end;
 	unsigned offset;
 	end = (start + PMD_SIZE - 1) & PMD_MASK;
-	if (end >= TASK_SIZE64)
-		end = TASK_SIZE64;
+	if (end >= TASK_SIZE_MAX)
+		end = TASK_SIZE_MAX;
 	end -= len;
 	/* This loses some more bits than a modulo, but is cheaper */
 	offset = get_random_int() & (PTRS_PER_PTE - 1);
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/enlighten.c linux-libre-2.6.30-gnu1/arch/x86/xen/enlighten.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/enlighten.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/enlighten.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,7 @@
 #include <asm/xen/hypervisor.h>
 #include <asm/fixmap.h>
 #include <asm/processor.h>
+#include <asm/proto.h>
 #include <asm/msr-index.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
@@ -61,40 +62,13 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcp
 enum xen_domain_type xen_domain_type = XEN_NATIVE;
 EXPORT_SYMBOL_GPL(xen_domain_type);
 
-/*
- * Identity map, in addition to plain kernel map.  This needs to be
- * large enough to allocate page table pages to allocate the rest.
- * Each page can map 2MB.
- */
-static pte_t level1_ident_pgt[PTRS_PER_PTE * 4] __page_aligned_bss;
-
-#ifdef CONFIG_X86_64
-/* l3 pud for userspace vsyscall mapping */
-static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
-#endif /* CONFIG_X86_64 */
-
-/*
- * Note about cr3 (pagetable base) values:
- *
- * xen_cr3 contains the current logical cr3 value; it contains the
- * last set cr3.  This may not be the current effective cr3, because
- * its update may be being lazily deferred.  However, a vcpu looking
- * at its own cr3 can use this value knowing that it everything will
- * be self-consistent.
- *
- * xen_current_cr3 contains the actual vcpu cr3; it is set once the
- * hypercall to set the vcpu cr3 is complete (so it may be a little
- * out of date, but it will never be set early).  If one vcpu is
- * looking at another vcpu's cr3 value, it should use this variable.
- */
-DEFINE_PER_CPU(unsigned long, xen_cr3);	 /* cr3 stored as physaddr */
-DEFINE_PER_CPU(unsigned long, xen_current_cr3);	 /* actual vcpu cr3 */
-
 struct start_info *xen_start_info;
 EXPORT_SYMBOL_GPL(xen_start_info);
 
 struct shared_info xen_dummy_shared_info;
 
+void *xen_initial_gdt;
+
 /*
  * Point at some empty memory to start with. We map the real shared_info
  * page as soon as fixmap is up and running.
@@ -114,14 +88,7 @@ struct shared_info *HYPERVISOR_shared_in
  *
  * 0: not available, 1: available
  */
-static int have_vcpu_info_placement =
-#ifdef CONFIG_X86_32
-	1
-#else
-	0
-#endif
-	;
-
+static int have_vcpu_info_placement = 1;
 
 static void xen_vcpu_setup(int cpu)
 {
@@ -137,7 +104,7 @@ static void xen_vcpu_setup(int cpu)
 
 	vcpup = &per_cpu(xen_vcpu_info, cpu);
 
-	info.mfn = virt_to_mfn(vcpup);
+	info.mfn = arbitrary_virt_to_mfn(vcpup);
 	info.offset = offset_in_page(vcpup);
 
 	printk(KERN_DEBUG "trying to map vcpu_info %d at %p, mfn %llx, offset %d\n",
@@ -202,21 +169,23 @@ static void __init xen_banner(void)
 	       xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
 }
 
+static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
+static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
+
 static void xen_cpuid(unsigned int *ax, unsigned int *bx,
 		      unsigned int *cx, unsigned int *dx)
 {
+	unsigned maskecx = ~0;
 	unsigned maskedx = ~0;
 
 	/*
 	 * Mask out inconvenient features, to try and disable as many
 	 * unsupported kernel subsystems as possible.
 	 */
-	if (*ax == 1)
-		maskedx = ~((1 << X86_FEATURE_APIC) |  /* disable APIC */
-			    (1 << X86_FEATURE_ACPI) |  /* disable ACPI */
-			    (1 << X86_FEATURE_MCE)  |  /* disable MCE */
-			    (1 << X86_FEATURE_MCA)  |  /* disable MCA */
-			    (1 << X86_FEATURE_ACC));   /* thermal monitoring */
+	if (*ax == 1) {
+		maskecx = cpuid_leaf1_ecx_mask;
+		maskedx = cpuid_leaf1_edx_mask;
+	}
 
 	asm(XEN_EMULATE_PREFIX "cpuid"
 		: "=a" (*ax),
@@ -224,9 +193,43 @@ static void xen_cpuid(unsigned int *ax,
 		  "=c" (*cx),
 		  "=d" (*dx)
 		: "0" (*ax), "2" (*cx));
+
+	*cx &= maskecx;
 	*dx &= maskedx;
 }
 
+static __init void xen_init_cpuid_mask(void)
+{
+	unsigned int ax, bx, cx, dx;
+
+	cpuid_leaf1_edx_mask =
+		~((1 << X86_FEATURE_MCE)  |  /* disable MCE */
+		  (1 << X86_FEATURE_MCA)  |  /* disable MCA */
+		  (1 << X86_FEATURE_ACC));   /* thermal monitoring */
+
+	if (!xen_initial_domain())
+		cpuid_leaf1_edx_mask &=
+			~((1 << X86_FEATURE_APIC) |  /* disable local APIC */
+			  (1 << X86_FEATURE_ACPI));  /* disable ACPI */
+
+	ax = 1;
+	xen_cpuid(&ax, &bx, &cx, &dx);
+
+	/* cpuid claims we support xsave; try enabling it to see what happens */
+	if (cx & (1 << (X86_FEATURE_XSAVE % 32))) {
+		unsigned long cr4;
+
+		set_in_cr4(X86_CR4_OSXSAVE);
+		
+		cr4 = read_cr4();
+
+		if ((cr4 & X86_CR4_OSXSAVE) == 0)
+			cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32));
+
+		clear_in_cr4(X86_CR4_OSXSAVE);
+	}
+}
+
 static void xen_set_debugreg(int reg, unsigned long val)
 {
 	HYPERVISOR_set_debugreg(reg, val);
@@ -237,7 +240,7 @@ static unsigned long xen_get_debugreg(in
 	return HYPERVISOR_get_debugreg(reg);
 }
 
-static void xen_leave_lazy(void)
+void xen_leave_lazy(void)
 {
 	paravirt_leave_lazy(paravirt_get_lazy_mode());
 	xen_mc_flush();
@@ -318,12 +321,11 @@ static void xen_set_ldt(const void *addr
 
 static void xen_load_gdt(const struct desc_ptr *dtr)
 {
-	unsigned long *frames;
 	unsigned long va = dtr->address;
 	unsigned int size = dtr->size + 1;
 	unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+	unsigned long frames[pages];
 	int f;
-	struct multicall_space mcs;
 
 	/* A GDT can be up to 64k in size, which corresponds to 8192
 	   8-byte entries, or 16 4k pages.. */
@@ -331,24 +333,33 @@ static void xen_load_gdt(const struct de
 	BUG_ON(size > 65536);
 	BUG_ON(va & ~PAGE_MASK);
 
-	mcs = xen_mc_entry(sizeof(*frames) * pages);
-	frames = mcs.args;
-
 	for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
-		frames[f] = virt_to_mfn(va);
+		int level;
+		pte_t *ptep = lookup_address(va, &level);
+		unsigned long pfn, mfn;
+		void *virt;
+
+		BUG_ON(ptep == NULL);
+
+		pfn = pte_pfn(*ptep);
+		mfn = pfn_to_mfn(pfn);
+		virt = __va(PFN_PHYS(pfn));
+
+		frames[f] = mfn;
+
 		make_lowmem_page_readonly((void *)va);
+		make_lowmem_page_readonly(virt);
 	}
 
-	MULTI_set_gdt(mcs.mc, frames, size / sizeof(struct desc_struct));
-
-	xen_mc_issue(PARAVIRT_LAZY_CPU);
+	if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
+		BUG();
 }
 
 static void load_TLS_descriptor(struct thread_struct *t,
 				unsigned int cpu, unsigned int i)
 {
 	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
-	xmaddr_t maddr = virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
+	xmaddr_t maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
 	struct multicall_space mc = __xen_mc_entry(0);
 
 	MULTI_update_descriptor(mc.mc, maddr.maddr, t->tls_array[i]);
@@ -357,13 +368,14 @@ static void load_TLS_descriptor(struct t
 static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
 {
 	/*
-	 * XXX sleazy hack: If we're being called in a lazy-cpu zone,
-	 * it means we're in a context switch, and %gs has just been
-	 * saved.  This means we can zero it out to prevent faults on
-	 * exit from the hypervisor if the next process has no %gs.
-	 * Either way, it has been saved, and the new value will get
-	 * loaded properly.  This will go away as soon as Xen has been
-	 * modified to not save/restore %gs for normal hypercalls.
+	 * XXX sleazy hack: If we're being called in a lazy-cpu zone
+	 * and lazy gs handling is enabled, it means we're in a
+	 * context switch, and %gs has just been saved.  This means we
+	 * can zero it out to prevent faults on exit from the
+	 * hypervisor if the next process has no %gs.  Either way, it
+	 * has been saved, and the new value will get loaded properly.
+	 * This will go away as soon as Xen has been modified to not
+	 * save/restore %gs for normal hypercalls.
 	 *
 	 * On x86_64, this hack is not used for %gs, because gs points
 	 * to KERNEL_GS_BASE (and uses it for PDA references), so we
@@ -375,7 +387,7 @@ static void xen_load_tls(struct thread_s
 	 */
 	if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
 #ifdef CONFIG_X86_32
-		loadsegment(gs, 0);
+		lazy_load_gs(0);
 #else
 		loadsegment(fs, 0);
 #endif
@@ -416,7 +428,7 @@ static void xen_write_ldt_entry(struct d
 static int cvt_gate_to_trap(int vector, const gate_desc *val,
 			    struct trap_info *info)
 {
-	if (val->type != 0xf && val->type != 0xe)
+	if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
 		return 0;
 
 	info->vector = vector;
@@ -424,8 +436,8 @@ static int cvt_gate_to_trap(int vector,
 	info->cs = gate_segment(*val);
 	info->flags = val->dpl;
 	/* interrupt gates clear IF */
-	if (val->type == 0xe)
-		info->flags |= 4;
+	if (val->type == GATE_INTERRUPT)
+		info->flags |= 1 << 2;
 
 	return 1;
 }
@@ -521,7 +533,7 @@ static void xen_write_gdt_entry(struct d
 		break;
 
 	default: {
-		xmaddr_t maddr = virt_to_machine(&dt[entry]);
+		xmaddr_t maddr = arbitrary_virt_to_machine(&dt[entry]);
 
 		xen_mc_flush();
 		if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
@@ -587,94 +599,18 @@ static u32 xen_safe_apic_wait_icr_idle(v
         return 0;
 }
 
-static struct apic_ops xen_basic_apic_ops = {
-	.read = xen_apic_read,
-	.write = xen_apic_write,
-	.icr_read = xen_apic_icr_read,
-	.icr_write = xen_apic_icr_write,
-	.wait_icr_idle = xen_apic_wait_icr_idle,
-	.safe_wait_icr_idle = xen_safe_apic_wait_icr_idle,
-};
-
-#endif
-
-static void xen_flush_tlb(void)
-{
-	struct mmuext_op *op;
-	struct multicall_space mcs;
-
-	preempt_disable();
-
-	mcs = xen_mc_entry(sizeof(*op));
-
-	op = mcs.args;
-	op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
-	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
-
-	xen_mc_issue(PARAVIRT_LAZY_MMU);
-
-	preempt_enable();
-}
-
-static void xen_flush_tlb_single(unsigned long addr)
+static void set_xen_basic_apic_ops(void)
 {
-	struct mmuext_op *op;
-	struct multicall_space mcs;
-
-	preempt_disable();
-
-	mcs = xen_mc_entry(sizeof(*op));
-	op = mcs.args;
-	op->cmd = MMUEXT_INVLPG_LOCAL;
-	op->arg1.linear_addr = addr & PAGE_MASK;
-	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
-
-	xen_mc_issue(PARAVIRT_LAZY_MMU);
-
-	preempt_enable();
+	apic->read = xen_apic_read;
+	apic->write = xen_apic_write;
+	apic->icr_read = xen_apic_icr_read;
+	apic->icr_write = xen_apic_icr_write;
+	apic->wait_icr_idle = xen_apic_wait_icr_idle;
+	apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
 }
 
-static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
-				 unsigned long va)
-{
-	struct {
-		struct mmuext_op op;
-		cpumask_t mask;
-	} *args;
-	cpumask_t cpumask = *cpus;
-	struct multicall_space mcs;
-
-	/*
-	 * A couple of (to be removed) sanity checks:
-	 *
-	 * - current CPU must not be in mask
-	 * - mask must exist :)
-	 */
-	BUG_ON(cpus_empty(cpumask));
-	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
-	BUG_ON(!mm);
-
-	/* If a CPU which we ran on has gone down, OK. */
-	cpus_and(cpumask, cpumask, cpu_online_map);
-	if (cpus_empty(cpumask))
-		return;
-
-	mcs = xen_mc_entry(sizeof(*args));
-	args = mcs.args;
-	args->mask = cpumask;
-	args->op.arg2.vcpumask = &args->mask;
-
-	if (va == TLB_FLUSH_ALL) {
-		args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
-	} else {
-		args->op.cmd = MMUEXT_INVLPG_MULTI;
-		args->op.arg1.linear_addr = va;
-	}
-
-	MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
+#endif
 
-	xen_mc_issue(PARAVIRT_LAZY_MMU);
-}
 
 static void xen_clts(void)
 {
@@ -700,21 +636,6 @@ static void xen_write_cr0(unsigned long
 	xen_mc_issue(PARAVIRT_LAZY_CPU);
 }
 
-static void xen_write_cr2(unsigned long cr2)
-{
-	x86_read_percpu(xen_vcpu)->arch.cr2 = cr2;
-}
-
-static unsigned long xen_read_cr2(void)
-{
-	return x86_read_percpu(xen_vcpu)->arch.cr2;
-}
-
-static unsigned long xen_read_cr2_direct(void)
-{
-	return x86_read_percpu(xen_vcpu_info.arch.cr2);
-}
-
 static void xen_write_cr4(unsigned long cr4)
 {
 	cr4 &= ~X86_CR4_PGE;
@@ -723,71 +644,6 @@ static void xen_write_cr4(unsigned long
 	native_write_cr4(cr4);
 }
 
-static unsigned long xen_read_cr3(void)
-{
-	return x86_read_percpu(xen_cr3);
-}
-
-static void set_current_cr3(void *v)
-{
-	x86_write_percpu(xen_current_cr3, (unsigned long)v);
-}
-
-static void __xen_write_cr3(bool kernel, unsigned long cr3)
-{
-	struct mmuext_op *op;
-	struct multicall_space mcs;
-	unsigned long mfn;
-
-	if (cr3)
-		mfn = pfn_to_mfn(PFN_DOWN(cr3));
-	else
-		mfn = 0;
-
-	WARN_ON(mfn == 0 && kernel);
-
-	mcs = __xen_mc_entry(sizeof(*op));
-
-	op = mcs.args;
-	op->cmd = kernel ? MMUEXT_NEW_BASEPTR : MMUEXT_NEW_USER_BASEPTR;
-	op->arg1.mfn = mfn;
-
-	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
-
-	if (kernel) {
-		x86_write_percpu(xen_cr3, cr3);
-
-		/* Update xen_current_cr3 once the batch has actually
-		   been submitted. */
-		xen_mc_callback(set_current_cr3, (void *)cr3);
-	}
-}
-
-static void xen_write_cr3(unsigned long cr3)
-{
-	BUG_ON(preemptible());
-
-	xen_mc_batch();  /* disables interrupts */
-
-	/* Update while interrupts are disabled, so its atomic with
-	   respect to ipis */
-	x86_write_percpu(xen_cr3, cr3);
-
-	__xen_write_cr3(true, cr3);
-
-#ifdef CONFIG_X86_64
-	{
-		pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
-		if (user_pgd)
-			__xen_write_cr3(false, __pa(user_pgd));
-		else
-			__xen_write_cr3(false, 0);
-	}
-#endif
-
-	xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
-}
-
 static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 {
 	int ret;
@@ -829,185 +685,6 @@ static int xen_write_msr_safe(unsigned i
 	return ret;
 }
 
-/* Early in boot, while setting up the initial pagetable, assume
-   everything is pinned. */
-static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
-{
-#ifdef CONFIG_FLATMEM
-	BUG_ON(mem_map);	/* should only be used early */
-#endif
-	make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
-}
-
-/* Early release_pte assumes that all pts are pinned, since there's
-   only init_mm and anything attached to that is pinned. */
-static void xen_release_pte_init(unsigned long pfn)
-{
-	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
-}
-
-static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
-{
-	struct mmuext_op op;
-	op.cmd = cmd;
-	op.arg1.mfn = pfn_to_mfn(pfn);
-	if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
-		BUG();
-}
-
-/* This needs to make sure the new pte page is pinned iff its being
-   attached to a pinned pagetable. */
-static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level)
-{
-	struct page *page = pfn_to_page(pfn);
-
-	if (PagePinned(virt_to_page(mm->pgd))) {
-		SetPagePinned(page);
-
-		vm_unmap_aliases();
-		if (!PageHighMem(page)) {
-			make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn)));
-			if (level == PT_PTE && USE_SPLIT_PTLOCKS)
-				pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
-		} else {
-			/* make sure there are no stray mappings of
-			   this page */
-			kmap_flush_unused();
-		}
-	}
-}
-
-static void xen_alloc_pte(struct mm_struct *mm, unsigned long pfn)
-{
-	xen_alloc_ptpage(mm, pfn, PT_PTE);
-}
-
-static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
-{
-	xen_alloc_ptpage(mm, pfn, PT_PMD);
-}
-
-static int xen_pgd_alloc(struct mm_struct *mm)
-{
-	pgd_t *pgd = mm->pgd;
-	int ret = 0;
-
-	BUG_ON(PagePinned(virt_to_page(pgd)));
-
-#ifdef CONFIG_X86_64
-	{
-		struct page *page = virt_to_page(pgd);
-		pgd_t *user_pgd;
-
-		BUG_ON(page->private != 0);
-
-		ret = -ENOMEM;
-
-		user_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-		page->private = (unsigned long)user_pgd;
-
-		if (user_pgd != NULL) {
-			user_pgd[pgd_index(VSYSCALL_START)] =
-				__pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
-			ret = 0;
-		}
-
-		BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
-	}
-#endif
-
-	return ret;
-}
-
-static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-#ifdef CONFIG_X86_64
-	pgd_t *user_pgd = xen_get_user_pgd(pgd);
-
-	if (user_pgd)
-		free_page((unsigned long)user_pgd);
-#endif
-}
-
-/* This should never happen until we're OK to use struct page */
-static void xen_release_ptpage(unsigned long pfn, unsigned level)
-{
-	struct page *page = pfn_to_page(pfn);
-
-	if (PagePinned(page)) {
-		if (!PageHighMem(page)) {
-			if (level == PT_PTE && USE_SPLIT_PTLOCKS)
-				pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
-			make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
-		}
-		ClearPagePinned(page);
-	}
-}
-
-static void xen_release_pte(unsigned long pfn)
-{
-	xen_release_ptpage(pfn, PT_PTE);
-}
-
-static void xen_release_pmd(unsigned long pfn)
-{
-	xen_release_ptpage(pfn, PT_PMD);
-}
-
-#if PAGETABLE_LEVELS == 4
-static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
-{
-	xen_alloc_ptpage(mm, pfn, PT_PUD);
-}
-
-static void xen_release_pud(unsigned long pfn)
-{
-	xen_release_ptpage(pfn, PT_PUD);
-}
-#endif
-
-#ifdef CONFIG_HIGHPTE
-static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
-{
-	pgprot_t prot = PAGE_KERNEL;
-
-	if (PagePinned(page))
-		prot = PAGE_KERNEL_RO;
-
-	if (0 && PageHighMem(page))
-		printk("mapping highpte %lx type %d prot %s\n",
-		       page_to_pfn(page), type,
-		       (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ");
-
-	return kmap_atomic_prot(page, type, prot);
-}
-#endif
-
-#ifdef CONFIG_X86_32
-static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
-{
-	/* If there's an existing pte, then don't allow _PAGE_RW to be set */
-	if (pte_val_ma(*ptep) & _PAGE_PRESENT)
-		pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
-			       pte_val_ma(pte));
-
-	return pte;
-}
-
-/* Init-time set_pte while constructing initial pagetables, which
-   doesn't allow RO pagetable pages to be remapped RW */
-static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
-{
-	pte = mask_rw_pte(ptep, pte);
-
-	xen_set_pte(ptep, pte);
-}
-#endif
-
-static __init void xen_pagetable_setup_start(pgd_t *base)
-{
-}
-
 void xen_setup_shared_info(void)
 {
 	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -1028,37 +705,6 @@ void xen_setup_shared_info(void)
 	xen_setup_mfn_list_list();
 }
 
-static __init void xen_pagetable_setup_done(pgd_t *base)
-{
-	xen_setup_shared_info();
-}
-
-static __init void xen_post_allocator_init(void)
-{
-	pv_mmu_ops.set_pte = xen_set_pte;
-	pv_mmu_ops.set_pmd = xen_set_pmd;
-	pv_mmu_ops.set_pud = xen_set_pud;
-#if PAGETABLE_LEVELS == 4
-	pv_mmu_ops.set_pgd = xen_set_pgd;
-#endif
-
-	/* This will work as long as patching hasn't happened yet
-	   (which it hasn't) */
-	pv_mmu_ops.alloc_pte = xen_alloc_pte;
-	pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
-	pv_mmu_ops.release_pte = xen_release_pte;
-	pv_mmu_ops.release_pmd = xen_release_pmd;
-#if PAGETABLE_LEVELS == 4
-	pv_mmu_ops.alloc_pud = xen_alloc_pud;
-	pv_mmu_ops.release_pud = xen_release_pud;
-#endif
-
-#ifdef CONFIG_X86_64
-	SetPagePinned(virt_to_page(level3_user_vsyscall));
-#endif
-	xen_mark_init_mm_pinned();
-}
-
 /* This is called once we have the cpu_possible_map */
 void xen_setup_vcpu_info_placement(void)
 {
@@ -1072,10 +718,10 @@ void xen_setup_vcpu_info_placement(void)
 	if (have_vcpu_info_placement) {
 		printk(KERN_INFO "Xen: using vcpu_info placement\n");
 
-		pv_irq_ops.save_fl = xen_save_fl_direct;
-		pv_irq_ops.restore_fl = xen_restore_fl_direct;
-		pv_irq_ops.irq_disable = xen_irq_disable_direct;
-		pv_irq_ops.irq_enable = xen_irq_enable_direct;
+		pv_irq_ops.save_fl = __PV_IS_CALLEE_SAVE(xen_save_fl_direct);
+		pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(xen_restore_fl_direct);
+		pv_irq_ops.irq_disable = __PV_IS_CALLEE_SAVE(xen_irq_disable_direct);
+		pv_irq_ops.irq_enable = __PV_IS_CALLEE_SAVE(xen_irq_enable_direct);
 		pv_mmu_ops.read_cr2 = xen_read_cr2_direct;
 	}
 }
@@ -1133,49 +779,6 @@ static unsigned xen_patch(u8 type, u16 c
 	return ret;
 }
 
-static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
-{
-	pte_t pte;
-
-	phys >>= PAGE_SHIFT;
-
-	switch (idx) {
-	case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
-#ifdef CONFIG_X86_F00F_BUG
-	case FIX_F00F_IDT:
-#endif
-#ifdef CONFIG_X86_32
-	case FIX_WP_TEST:
-	case FIX_VDSO:
-# ifdef CONFIG_HIGHMEM
-	case FIX_KMAP_BEGIN ... FIX_KMAP_END:
-# endif
-#else
-	case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
-	case FIX_APIC_BASE:	/* maps dummy local APIC */
-#endif
-		pte = pfn_pte(phys, prot);
-		break;
-
-	default:
-		pte = mfn_pte(phys, prot);
-		break;
-	}
-
-	__native_set_fixmap(idx, pte);
-
-#ifdef CONFIG_X86_64
-	/* Replicate changes to map the vsyscall page into the user
-	   pagetable vsyscall mapping. */
-	if (idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) {
-		unsigned long vaddr = __fix_to_virt(idx);
-		set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte);
-	}
-#endif
-}
-
 static const struct pv_info xen_info __initdata = {
 	.paravirt_enabled = 1,
 	.shared_kernel_pmd = 0,
@@ -1271,87 +874,6 @@ static const struct pv_apic_ops xen_apic
 #endif
 };
 
-static const struct pv_mmu_ops xen_mmu_ops __initdata = {
-	.pagetable_setup_start = xen_pagetable_setup_start,
-	.pagetable_setup_done = xen_pagetable_setup_done,
-
-	.read_cr2 = xen_read_cr2,
-	.write_cr2 = xen_write_cr2,
-
-	.read_cr3 = xen_read_cr3,
-	.write_cr3 = xen_write_cr3,
-
-	.flush_tlb_user = xen_flush_tlb,
-	.flush_tlb_kernel = xen_flush_tlb,
-	.flush_tlb_single = xen_flush_tlb_single,
-	.flush_tlb_others = xen_flush_tlb_others,
-
-	.pte_update = paravirt_nop,
-	.pte_update_defer = paravirt_nop,
-
-	.pgd_alloc = xen_pgd_alloc,
-	.pgd_free = xen_pgd_free,
-
-	.alloc_pte = xen_alloc_pte_init,
-	.release_pte = xen_release_pte_init,
-	.alloc_pmd = xen_alloc_pte_init,
-	.alloc_pmd_clone = paravirt_nop,
-	.release_pmd = xen_release_pte_init,
-
-#ifdef CONFIG_HIGHPTE
-	.kmap_atomic_pte = xen_kmap_atomic_pte,
-#endif
-
-#ifdef CONFIG_X86_64
-	.set_pte = xen_set_pte,
-#else
-	.set_pte = xen_set_pte_init,
-#endif
-	.set_pte_at = xen_set_pte_at,
-	.set_pmd = xen_set_pmd_hyper,
-
-	.ptep_modify_prot_start = __ptep_modify_prot_start,
-	.ptep_modify_prot_commit = __ptep_modify_prot_commit,
-
-	.pte_val = xen_pte_val,
-	.pte_flags = native_pte_flags,
-	.pgd_val = xen_pgd_val,
-
-	.make_pte = xen_make_pte,
-	.make_pgd = xen_make_pgd,
-
-#ifdef CONFIG_X86_PAE
-	.set_pte_atomic = xen_set_pte_atomic,
-	.set_pte_present = xen_set_pte_at,
-	.pte_clear = xen_pte_clear,
-	.pmd_clear = xen_pmd_clear,
-#endif	/* CONFIG_X86_PAE */
-	.set_pud = xen_set_pud_hyper,
-
-	.make_pmd = xen_make_pmd,
-	.pmd_val = xen_pmd_val,
-
-#if PAGETABLE_LEVELS == 4
-	.pud_val = xen_pud_val,
-	.make_pud = xen_make_pud,
-	.set_pgd = xen_set_pgd_hyper,
-
-	.alloc_pud = xen_alloc_pte_init,
-	.release_pud = xen_release_pte_init,
-#endif	/* PAGETABLE_LEVELS == 4 */
-
-	.activate_mm = xen_activate_mm,
-	.dup_mmap = xen_dup_mmap,
-	.exit_mmap = xen_exit_mmap,
-
-	.lazy_mode = {
-		.enter = paravirt_enter_lazy_mmu,
-		.leave = xen_leave_lazy,
-	},
-
-	.set_fixmap = xen_set_fixmap,
-};
-
 static void xen_reboot(int reason)
 {
 	struct sched_shutdown r = { .reason = reason };
@@ -1393,224 +915,6 @@ static const struct machine_ops __initda
 	.emergency_restart = xen_emergency_restart,
 };
 
-
-static void __init xen_reserve_top(void)
-{
-#ifdef CONFIG_X86_32
-	unsigned long top = HYPERVISOR_VIRT_START;
-	struct xen_platform_parameters pp;
-
-	if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)
-		top = pp.virt_start;
-
-	reserve_top_address(-top);
-#endif	/* CONFIG_X86_32 */
-}
-
-/*
- * Like __va(), but returns address in the kernel mapping (which is
- * all we have until the physical memory mapping has been set up.
- */
-static void *__ka(phys_addr_t paddr)
-{
-#ifdef CONFIG_X86_64
-	return (void *)(paddr + __START_KERNEL_map);
-#else
-	return __va(paddr);
-#endif
-}
-
-/* Convert a machine address to physical address */
-static unsigned long m2p(phys_addr_t maddr)
-{
-	phys_addr_t paddr;
-
-	maddr &= PTE_PFN_MASK;
-	paddr = mfn_to_pfn(maddr >> PAGE_SHIFT) << PAGE_SHIFT;
-
-	return paddr;
-}
-
-/* Convert a machine address to kernel virtual */
-static void *m2v(phys_addr_t maddr)
-{
-	return __ka(m2p(maddr));
-}
-
-static void set_page_prot(void *addr, pgprot_t prot)
-{
-	unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
-	pte_t pte = pfn_pte(pfn, prot);
-
-	if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
-		BUG();
-}
-
-static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
-{
-	unsigned pmdidx, pteidx;
-	unsigned ident_pte;
-	unsigned long pfn;
-
-	ident_pte = 0;
-	pfn = 0;
-	for (pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
-		pte_t *pte_page;
-
-		/* Reuse or allocate a page of ptes */
-		if (pmd_present(pmd[pmdidx]))
-			pte_page = m2v(pmd[pmdidx].pmd);
-		else {
-			/* Check for free pte pages */
-			if (ident_pte == ARRAY_SIZE(level1_ident_pgt))
-				break;
-
-			pte_page = &level1_ident_pgt[ident_pte];
-			ident_pte += PTRS_PER_PTE;
-
-			pmd[pmdidx] = __pmd(__pa(pte_page) | _PAGE_TABLE);
-		}
-
-		/* Install mappings */
-		for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
-			pte_t pte;
-
-			if (pfn > max_pfn_mapped)
-				max_pfn_mapped = pfn;
-
-			if (!pte_none(pte_page[pteidx]))
-				continue;
-
-			pte = pfn_pte(pfn, PAGE_KERNEL_EXEC);
-			pte_page[pteidx] = pte;
-		}
-	}
-
-	for (pteidx = 0; pteidx < ident_pte; pteidx += PTRS_PER_PTE)
-		set_page_prot(&level1_ident_pgt[pteidx], PAGE_KERNEL_RO);
-
-	set_page_prot(pmd, PAGE_KERNEL_RO);
-}
-
-#ifdef CONFIG_X86_64
-static void convert_pfn_mfn(void *v)
-{
-	pte_t *pte = v;
-	int i;
-
-	/* All levels are converted the same way, so just treat them
-	   as ptes. */
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		pte[i] = xen_make_pte(pte[i].pte);
-}
-
-/*
- * Set up the inital kernel pagetable.
- *
- * We can construct this by grafting the Xen provided pagetable into
- * head_64.S's preconstructed pagetables.  We copy the Xen L2's into
- * level2_ident_pgt, level2_kernel_pgt and level2_fixmap_pgt.  This
- * means that only the kernel has a physical mapping to start with -
- * but that's enough to get __va working.  We need to fill in the rest
- * of the physical mapping once some sort of allocator has been set
- * up.
- */
-static __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
-						unsigned long max_pfn)
-{
-	pud_t *l3;
-	pmd_t *l2;
-
-	/* Zap identity mapping */
-	init_level4_pgt[0] = __pgd(0);
-
-	/* Pre-constructed entries are in pfn, so convert to mfn */
-	convert_pfn_mfn(init_level4_pgt);
-	convert_pfn_mfn(level3_ident_pgt);
-	convert_pfn_mfn(level3_kernel_pgt);
-
-	l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
-	l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
-
-	memcpy(level2_ident_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
-	memcpy(level2_kernel_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
-
-	l3 = m2v(pgd[pgd_index(__START_KERNEL_map + PMD_SIZE)].pgd);
-	l2 = m2v(l3[pud_index(__START_KERNEL_map + PMD_SIZE)].pud);
-	memcpy(level2_fixmap_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
-
-	/* Set up identity map */
-	xen_map_identity_early(level2_ident_pgt, max_pfn);
-
-	/* Make pagetable pieces RO */
-	set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
-	set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
-	set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
-	set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
-	set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
-	set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
-
-	/* Pin down new L4 */
-	pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
-			  PFN_DOWN(__pa_symbol(init_level4_pgt)));
-
-	/* Unpin Xen-provided one */
-	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
-
-	/* Switch over */
-	pgd = init_level4_pgt;
-
-	/*
-	 * At this stage there can be no user pgd, and no page
-	 * structure to attach it to, so make sure we just set kernel
-	 * pgd.
-	 */
-	xen_mc_batch();
-	__xen_write_cr3(true, __pa(pgd));
-	xen_mc_issue(PARAVIRT_LAZY_CPU);
-
-	reserve_early(__pa(xen_start_info->pt_base),
-		      __pa(xen_start_info->pt_base +
-			   xen_start_info->nr_pt_frames * PAGE_SIZE),
-		      "XEN PAGETABLES");
-
-	return pgd;
-}
-#else	/* !CONFIG_X86_64 */
-static pmd_t level2_kernel_pgt[PTRS_PER_PMD] __page_aligned_bss;
-
-static __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
-						unsigned long max_pfn)
-{
-	pmd_t *kernel_pmd;
-
-	init_pg_tables_start = __pa(pgd);
-	init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
-	max_pfn_mapped = PFN_DOWN(init_pg_tables_end + 512*1024);
-
-	kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
-	memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
-
-	xen_map_identity_early(level2_kernel_pgt, max_pfn);
-
-	memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
-	set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
-			__pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
-
-	set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
-	set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
-	set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
-
-	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
-
-	xen_write_cr3(__pa(swapper_pg_dir));
-
-	pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
-
-	return swapper_pg_dir;
-}
-#endif	/* CONFIG_X86_64 */
-
 /* First C function to be called on Xen boot */
 asmlinkage void __init xen_start_kernel(void)
 {
@@ -1635,11 +939,13 @@ asmlinkage void __init xen_start_kernel(
 
 	xen_init_irq_ops();
 
+	xen_init_cpuid_mask();
+
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * set up the basic apic ops.
 	 */
-	apic_ops = &xen_basic_apic_ops;
+	set_xen_basic_apic_ops();
 #endif
 
 	if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
@@ -1650,10 +956,18 @@ asmlinkage void __init xen_start_kernel(
 	machine_ops = xen_machine_ops;
 
 #ifdef CONFIG_X86_64
-	/* Disable until direct per-cpu data access. */
-	have_vcpu_info_placement = 0;
-	x86_64_init_pda();
+	/*
+	 * Setup percpu state.  We only need to do this for 64-bit
+	 * because 32-bit already has %fs set properly.
+	 */
+	load_percpu_segment(0);
 #endif
+	/*
+	 * The only reliable way to retain the initial address of the
+	 * percpu gdt_page is to remember it here, so we can go and
+	 * mark it RW later, when the initial percpu area is freed.
+	 */
+	xen_initial_gdt = &per_cpu(gdt_page, 0);
 
 	xen_smp_init();
 
@@ -1668,6 +982,11 @@ asmlinkage void __init xen_start_kernel(
 	if (!xen_initial_domain())
 		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
 
+#ifdef CONFIG_X86_64
+	/* Work out if we support NX */
+	check_efer();
+#endif
+
 	/* Don't do the full vcpu_info placement stuff until we have a
 	   possible map and a non-dummy shared_info. */
 	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/irq.c linux-libre-2.6.30-gnu1/arch/x86/xen/irq.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,27 +19,12 @@ void xen_force_evtchn_callback(void)
 	(void)HYPERVISOR_xen_version(0, NULL);
 }
 
-static void __init __xen_init_IRQ(void)
-{
-	int i;
-
-	/* Create identity vector->irq map */
-	for(i = 0; i < NR_VECTORS; i++) {
-		int cpu;
-
-		for_each_possible_cpu(cpu)
-			per_cpu(vector_irq, cpu)[i] = i;
-	}
-
-	xen_init_IRQ();
-}
-
 static unsigned long xen_save_fl(void)
 {
 	struct vcpu_info *vcpu;
 	unsigned long flags;
 
-	vcpu = x86_read_percpu(xen_vcpu);
+	vcpu = percpu_read(xen_vcpu);
 
 	/* flag has opposite sense of mask */
 	flags = !vcpu->evtchn_upcall_mask;
@@ -50,6 +35,7 @@ static unsigned long xen_save_fl(void)
 	*/
 	return (-flags) & X86_EFLAGS_IF;
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
 
 static void xen_restore_fl(unsigned long flags)
 {
@@ -62,7 +48,7 @@ static void xen_restore_fl(unsigned long
 	   make sure we're don't switch CPUs between getting the vcpu
 	   pointer and updating the mask. */
 	preempt_disable();
-	vcpu = x86_read_percpu(xen_vcpu);
+	vcpu = percpu_read(xen_vcpu);
 	vcpu->evtchn_upcall_mask = flags;
 	preempt_enable_no_resched();
 
@@ -76,6 +62,7 @@ static void xen_restore_fl(unsigned long
 			xen_force_evtchn_callback();
 	}
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl);
 
 static void xen_irq_disable(void)
 {
@@ -83,9 +70,10 @@ static void xen_irq_disable(void)
 	   make sure we're don't switch CPUs between getting the vcpu
 	   pointer and updating the mask. */
 	preempt_disable();
-	x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;
+	percpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
 	preempt_enable_no_resched();
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
 
 static void xen_irq_enable(void)
 {
@@ -96,7 +84,7 @@ static void xen_irq_enable(void)
 	   the caller is confused and is trying to re-enable interrupts
 	   on an indeterminate processor. */
 
-	vcpu = x86_read_percpu(xen_vcpu);
+	vcpu = percpu_read(xen_vcpu);
 	vcpu->evtchn_upcall_mask = 0;
 
 	/* Doesn't matter if we get preempted here, because any
@@ -106,6 +94,7 @@ static void xen_irq_enable(void)
 	if (unlikely(vcpu->evtchn_upcall_pending))
 		xen_force_evtchn_callback();
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_irq_enable);
 
 static void xen_safe_halt(void)
 {
@@ -123,11 +112,13 @@ static void xen_halt(void)
 }
 
 static const struct pv_irq_ops xen_irq_ops __initdata = {
-	.init_IRQ = __xen_init_IRQ,
-	.save_fl = xen_save_fl,
-	.restore_fl = xen_restore_fl,
-	.irq_disable = xen_irq_disable,
-	.irq_enable = xen_irq_enable,
+	.init_IRQ = xen_init_IRQ,
+
+	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
+	.restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
+	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
+	.irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
+
 	.safe_halt = xen_safe_halt,
 	.halt = xen_halt,
 #ifdef CONFIG_X86_64
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/Kconfig linux-libre-2.6.30-gnu1/arch/x86/xen/Kconfig
--- linux-libre-2.6.29-gnu1/arch/x86/xen/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@ config XEN
 	bool "Xen guest support"
 	select PARAVIRT
 	select PARAVIRT_CLOCK
-	depends on X86_64 || (X86_32 && X86_PAE && !(X86_VISWS || X86_VOYAGER))
+	depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
 	depends on X86_CMPXCHG && X86_TSC
 	help
 	  This is the Linux Xen port.  Enabling this will allow the
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/Makefile linux-libre-2.6.30-gnu1/arch/x86/xen/Makefile
--- linux-libre-2.6.29-gnu1/arch/x86/xen/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,9 @@ CFLAGS_REMOVE_irq.o = -pg
 endif
 
 obj-y		:= enlighten.o setup.o multicalls.o mmu.o irq.o \
-			time.o xen-asm_$(BITS).o grant-table.o suspend.o
+			time.o xen-asm.o xen-asm_$(BITS).o \
+			grant-table.o suspend.o
 
-obj-$(CONFIG_SMP)		+= smp.o spinlock.o
-obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o
\ No newline at end of file
+obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
+obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/mmu.c linux-libre-2.6.30-gnu1/arch/x86/xen/mmu.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/mmu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/mmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,11 +42,13 @@
 #include <linux/highmem.h>
 #include <linux/debugfs.h>
 #include <linux/bug.h>
+#include <linux/module.h>
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/fixmap.h>
 #include <asm/mmu_context.h>
+#include <asm/setup.h>
 #include <asm/paravirt.h>
 #include <asm/linkage.h>
 
@@ -55,6 +57,8 @@
 
 #include <xen/page.h>
 #include <xen/interface/xen.h>
+#include <xen/interface/version.h>
+#include <xen/hvc-console.h>
 
 #include "multicalls.h"
 #include "mmu.h"
@@ -114,6 +118,37 @@ static inline void check_zero(void)
 
 #endif /* CONFIG_XEN_DEBUG_FS */
 
+
+/*
+ * Identity map, in addition to plain kernel map.  This needs to be
+ * large enough to allocate page table pages to allocate the rest.
+ * Each page can map 2MB.
+ */
+static pte_t level1_ident_pgt[PTRS_PER_PTE * 4] __page_aligned_bss;
+
+#ifdef CONFIG_X86_64
+/* l3 pud for userspace vsyscall mapping */
+static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
+#endif /* CONFIG_X86_64 */
+
+/*
+ * Note about cr3 (pagetable base) values:
+ *
+ * xen_cr3 contains the current logical cr3 value; it contains the
+ * last set cr3.  This may not be the current effective cr3, because
+ * its update may be being lazily deferred.  However, a vcpu looking
+ * at its own cr3 can use this value knowing that it everything will
+ * be self-consistent.
+ *
+ * xen_current_cr3 contains the actual vcpu cr3; it is set once the
+ * hypercall to set the vcpu cr3 is complete (so it may be a little
+ * out of date, but it will never be set early).  If one vcpu is
+ * looking at another vcpu's cr3 value, it should use this variable.
+ */
+DEFINE_PER_CPU(unsigned long, xen_cr3);	 /* cr3 stored as physaddr */
+DEFINE_PER_CPU(unsigned long, xen_current_cr3);	 /* actual vcpu cr3 */
+
+
 /*
  * Just beyond the highest usermode address.  STACK_TOP_MAX has a
  * redzone above it, so round it up to a PGD boundary.
@@ -150,7 +185,7 @@ static inline unsigned p2m_index(unsigne
 }
 
 /* Build the parallel p2m_top_mfn structures */
-void xen_setup_mfn_list_list(void)
+static void __init xen_build_mfn_list_list(void)
 {
 	unsigned pfn, idx;
 
@@ -164,7 +199,10 @@ void xen_setup_mfn_list_list(void)
 		unsigned topidx = idx * P2M_ENTRIES_PER_PAGE;
 		p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]);
 	}
+}
 
+void xen_setup_mfn_list_list(void)
+{
 	BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
 
 	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
@@ -184,6 +222,8 @@ void __init xen_build_dynamic_phys_to_ma
 
 		p2m_top[topidx] = &mfn_list[pfn];
 	}
+
+	xen_build_mfn_list_list();
 }
 
 unsigned long get_phys_to_machine(unsigned long pfn)
@@ -199,47 +239,81 @@ unsigned long get_phys_to_machine(unsign
 }
 EXPORT_SYMBOL_GPL(get_phys_to_machine);
 
-static void alloc_p2m(unsigned long **pp, unsigned long *mfnp)
+/* install a  new p2m_top page */
+bool install_p2mtop_page(unsigned long pfn, unsigned long *p)
 {
-	unsigned long *p;
+	unsigned topidx = p2m_top_index(pfn);
+	unsigned long **pfnp, *mfnp;
 	unsigned i;
 
-	p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
-	BUG_ON(p == NULL);
+	pfnp = &p2m_top[topidx];
+	mfnp = &p2m_top_mfn[topidx];
 
 	for (i = 0; i < P2M_ENTRIES_PER_PAGE; i++)
 		p[i] = INVALID_P2M_ENTRY;
 
-	if (cmpxchg(pp, p2m_missing, p) != p2m_missing)
-		free_page((unsigned long)p);
-	else
+	if (cmpxchg(pfnp, p2m_missing, p) == p2m_missing) {
 		*mfnp = virt_to_mfn(p);
+		return true;
+	}
+
+	return false;
 }
 
-void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+static void alloc_p2m(unsigned long pfn)
 {
-	unsigned topidx, idx;
+	unsigned long *p;
 
-	if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
-		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
-		return;
-	}
+	p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL);
+	BUG_ON(p == NULL);
+
+	if (!install_p2mtop_page(pfn, p))
+		free_page((unsigned long)p);
+}
+
+/* Try to install p2m mapping; fail if intermediate bits missing */
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	unsigned topidx, idx;
 
 	if (unlikely(pfn >= MAX_DOMAIN_PAGES)) {
 		BUG_ON(mfn != INVALID_P2M_ENTRY);
-		return;
+		return true;
 	}
 
 	topidx = p2m_top_index(pfn);
 	if (p2m_top[topidx] == p2m_missing) {
-		/* no need to allocate a page to store an invalid entry */
 		if (mfn == INVALID_P2M_ENTRY)
-			return;
-		alloc_p2m(&p2m_top[topidx], &p2m_top_mfn[topidx]);
+			return true;
+		return false;
 	}
 
 	idx = p2m_index(pfn);
 	p2m_top[topidx][idx] = mfn;
+
+	return true;
+}
+
+void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
+{
+	if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) {
+		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+		return;
+	}
+
+	if (unlikely(!__set_phys_to_machine(pfn, mfn)))  {
+		alloc_p2m(pfn);
+
+		if (!__set_phys_to_machine(pfn, mfn))
+			BUG();
+	}
+}
+
+unsigned long arbitrary_virt_to_mfn(void *vaddr)
+{
+	xmaddr_t maddr = arbitrary_virt_to_machine(vaddr);
+
+	return PFN_DOWN(maddr.maddr);
 }
 
 xmaddr_t arbitrary_virt_to_machine(void *vaddr)
@@ -458,28 +532,33 @@ pteval_t xen_pte_val(pte_t pte)
 {
 	return pte_mfn_to_pfn(pte.pte);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
 
 pgdval_t xen_pgd_val(pgd_t pgd)
 {
 	return pte_mfn_to_pfn(pgd.pgd);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_pgd_val);
 
 pte_t xen_make_pte(pteval_t pte)
 {
 	pte = pte_pfn_to_mfn(pte);
 	return native_make_pte(pte);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
 
 pgd_t xen_make_pgd(pgdval_t pgd)
 {
 	pgd = pte_pfn_to_mfn(pgd);
 	return native_make_pgd(pgd);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_make_pgd);
 
 pmdval_t xen_pmd_val(pmd_t pmd)
 {
 	return pte_mfn_to_pfn(pmd.pmd);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_pmd_val);
 
 void xen_set_pud_hyper(pud_t *ptr, pud_t val)
 {
@@ -556,12 +635,14 @@ pmd_t xen_make_pmd(pmdval_t pmd)
 	pmd = pte_pfn_to_mfn(pmd);
 	return native_make_pmd(pmd);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
 
 #if PAGETABLE_LEVELS == 4
 pudval_t xen_pud_val(pud_t pud)
 {
 	return pte_mfn_to_pfn(pud.pud);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_pud_val);
 
 pud_t xen_make_pud(pudval_t pud)
 {
@@ -569,6 +650,7 @@ pud_t xen_make_pud(pudval_t pud)
 
 	return native_make_pud(pud);
 }
+PV_CALLEE_SAVE_REGS_THUNK(xen_make_pud);
 
 pgd_t *xen_get_user_pgd(pgd_t *pgd)
 {
@@ -938,7 +1020,7 @@ static __init int xen_mark_pinned(struct
 	return 0;
 }
 
-void __init xen_mark_init_mm_pinned(void)
+static void __init xen_mark_init_mm_pinned(void)
 {
 	xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP);
 }
@@ -1063,18 +1145,14 @@ static void drop_other_mm_ref(void *info
 	struct mm_struct *mm = info;
 	struct mm_struct *active_mm;
 
-#ifdef CONFIG_X86_64
-	active_mm = read_pda(active_mm);
-#else
-	active_mm = __get_cpu_var(cpu_tlbstate).active_mm;
-#endif
+	active_mm = percpu_read(cpu_tlbstate.active_mm);
 
 	if (active_mm == mm)
 		leave_mm(smp_processor_id());
 
 	/* If this cpu still has a stale cr3 reference, then make sure
 	   it has been flushed. */
-	if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) {
+	if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) {
 		load_cr3(swapper_pg_dir);
 		arch_flush_lazy_cpu_mode();
 	}
@@ -1156,6 +1234,728 @@ void xen_exit_mmap(struct mm_struct *mm)
 	spin_unlock(&mm->page_table_lock);
 }
 
+static __init void xen_pagetable_setup_start(pgd_t *base)
+{
+}
+
+static __init void xen_pagetable_setup_done(pgd_t *base)
+{
+	xen_setup_shared_info();
+}
+
+static void xen_write_cr2(unsigned long cr2)
+{
+	percpu_read(xen_vcpu)->arch.cr2 = cr2;
+}
+
+static unsigned long xen_read_cr2(void)
+{
+	return percpu_read(xen_vcpu)->arch.cr2;
+}
+
+unsigned long xen_read_cr2_direct(void)
+{
+	return percpu_read(xen_vcpu_info.arch.cr2);
+}
+
+static void xen_flush_tlb(void)
+{
+	struct mmuext_op *op;
+	struct multicall_space mcs;
+
+	preempt_disable();
+
+	mcs = xen_mc_entry(sizeof(*op));
+
+	op = mcs.args;
+	op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
+	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	preempt_enable();
+}
+
+static void xen_flush_tlb_single(unsigned long addr)
+{
+	struct mmuext_op *op;
+	struct multicall_space mcs;
+
+	preempt_disable();
+
+	mcs = xen_mc_entry(sizeof(*op));
+	op = mcs.args;
+	op->cmd = MMUEXT_INVLPG_LOCAL;
+	op->arg1.linear_addr = addr & PAGE_MASK;
+	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	preempt_enable();
+}
+
+static void xen_flush_tlb_others(const struct cpumask *cpus,
+				 struct mm_struct *mm, unsigned long va)
+{
+	struct {
+		struct mmuext_op op;
+		DECLARE_BITMAP(mask, NR_CPUS);
+	} *args;
+	struct multicall_space mcs;
+
+	if (cpumask_empty(cpus))
+		return;		/* nothing to do */
+
+	mcs = xen_mc_entry(sizeof(*args));
+	args = mcs.args;
+	args->op.arg2.vcpumask = to_cpumask(args->mask);
+
+	/* Remove us, and any offline CPUS. */
+	cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask));
+
+	if (va == TLB_FLUSH_ALL) {
+		args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
+	} else {
+		args->op.cmd = MMUEXT_INVLPG_MULTI;
+		args->op.arg1.linear_addr = va;
+	}
+
+	MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
+
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
+}
+
+static unsigned long xen_read_cr3(void)
+{
+	return percpu_read(xen_cr3);
+}
+
+static void set_current_cr3(void *v)
+{
+	percpu_write(xen_current_cr3, (unsigned long)v);
+}
+
+static void __xen_write_cr3(bool kernel, unsigned long cr3)
+{
+	struct mmuext_op *op;
+	struct multicall_space mcs;
+	unsigned long mfn;
+
+	if (cr3)
+		mfn = pfn_to_mfn(PFN_DOWN(cr3));
+	else
+		mfn = 0;
+
+	WARN_ON(mfn == 0 && kernel);
+
+	mcs = __xen_mc_entry(sizeof(*op));
+
+	op = mcs.args;
+	op->cmd = kernel ? MMUEXT_NEW_BASEPTR : MMUEXT_NEW_USER_BASEPTR;
+	op->arg1.mfn = mfn;
+
+	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+	if (kernel) {
+		percpu_write(xen_cr3, cr3);
+
+		/* Update xen_current_cr3 once the batch has actually
+		   been submitted. */
+		xen_mc_callback(set_current_cr3, (void *)cr3);
+	}
+}
+
+static void xen_write_cr3(unsigned long cr3)
+{
+	BUG_ON(preemptible());
+
+	xen_mc_batch();  /* disables interrupts */
+
+	/* Update while interrupts are disabled, so its atomic with
+	   respect to ipis */
+	percpu_write(xen_cr3, cr3);
+
+	__xen_write_cr3(true, cr3);
+
+#ifdef CONFIG_X86_64
+	{
+		pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
+		if (user_pgd)
+			__xen_write_cr3(false, __pa(user_pgd));
+		else
+			__xen_write_cr3(false, 0);
+	}
+#endif
+
+	xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
+}
+
+static int xen_pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd = mm->pgd;
+	int ret = 0;
+
+	BUG_ON(PagePinned(virt_to_page(pgd)));
+
+#ifdef CONFIG_X86_64
+	{
+		struct page *page = virt_to_page(pgd);
+		pgd_t *user_pgd;
+
+		BUG_ON(page->private != 0);
+
+		ret = -ENOMEM;
+
+		user_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+		page->private = (unsigned long)user_pgd;
+
+		if (user_pgd != NULL) {
+			user_pgd[pgd_index(VSYSCALL_START)] =
+				__pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
+			ret = 0;
+		}
+
+		BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
+	}
+#endif
+
+	return ret;
+}
+
+static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+#ifdef CONFIG_X86_64
+	pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+	if (user_pgd)
+		free_page((unsigned long)user_pgd);
+#endif
+}
+
+#ifdef CONFIG_HIGHPTE
+static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
+{
+	pgprot_t prot = PAGE_KERNEL;
+
+	if (PagePinned(page))
+		prot = PAGE_KERNEL_RO;
+
+	if (0 && PageHighMem(page))
+		printk("mapping highpte %lx type %d prot %s\n",
+		       page_to_pfn(page), type,
+		       (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ");
+
+	return kmap_atomic_prot(page, type, prot);
+}
+#endif
+
+#ifdef CONFIG_X86_32
+static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
+{
+	/* If there's an existing pte, then don't allow _PAGE_RW to be set */
+	if (pte_val_ma(*ptep) & _PAGE_PRESENT)
+		pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
+			       pte_val_ma(pte));
+
+	return pte;
+}
+
+/* Init-time set_pte while constructing initial pagetables, which
+   doesn't allow RO pagetable pages to be remapped RW */
+static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
+{
+	pte = mask_rw_pte(ptep, pte);
+
+	xen_set_pte(ptep, pte);
+}
+#endif
+
+static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
+{
+	struct mmuext_op op;
+	op.cmd = cmd;
+	op.arg1.mfn = pfn_to_mfn(pfn);
+	if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
+		BUG();
+}
+
+/* Early in boot, while setting up the initial pagetable, assume
+   everything is pinned. */
+static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
+{
+#ifdef CONFIG_FLATMEM
+	BUG_ON(mem_map);	/* should only be used early */
+#endif
+	make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
+	pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
+}
+
+/* Used for pmd and pud */
+static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn)
+{
+#ifdef CONFIG_FLATMEM
+	BUG_ON(mem_map);	/* should only be used early */
+#endif
+	make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
+}
+
+/* Early release_pte assumes that all pts are pinned, since there's
+   only init_mm and anything attached to that is pinned. */
+static __init void xen_release_pte_init(unsigned long pfn)
+{
+	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
+	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
+}
+
+static __init void xen_release_pmd_init(unsigned long pfn)
+{
+	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
+}
+
+/* This needs to make sure the new pte page is pinned iff its being
+   attached to a pinned pagetable. */
+static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned level)
+{
+	struct page *page = pfn_to_page(pfn);
+
+	if (PagePinned(virt_to_page(mm->pgd))) {
+		SetPagePinned(page);
+
+		vm_unmap_aliases();
+		if (!PageHighMem(page)) {
+			make_lowmem_page_readonly(__va(PFN_PHYS((unsigned long)pfn)));
+			if (level == PT_PTE && USE_SPLIT_PTLOCKS)
+				pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
+		} else {
+			/* make sure there are no stray mappings of
+			   this page */
+			kmap_flush_unused();
+		}
+	}
+}
+
+static void xen_alloc_pte(struct mm_struct *mm, unsigned long pfn)
+{
+	xen_alloc_ptpage(mm, pfn, PT_PTE);
+}
+
+static void xen_alloc_pmd(struct mm_struct *mm, unsigned long pfn)
+{
+	xen_alloc_ptpage(mm, pfn, PT_PMD);
+}
+
+/* This should never happen until we're OK to use struct page */
+static void xen_release_ptpage(unsigned long pfn, unsigned level)
+{
+	struct page *page = pfn_to_page(pfn);
+
+	if (PagePinned(page)) {
+		if (!PageHighMem(page)) {
+			if (level == PT_PTE && USE_SPLIT_PTLOCKS)
+				pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
+			make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
+		}
+		ClearPagePinned(page);
+	}
+}
+
+static void xen_release_pte(unsigned long pfn)
+{
+	xen_release_ptpage(pfn, PT_PTE);
+}
+
+static void xen_release_pmd(unsigned long pfn)
+{
+	xen_release_ptpage(pfn, PT_PMD);
+}
+
+#if PAGETABLE_LEVELS == 4
+static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
+{
+	xen_alloc_ptpage(mm, pfn, PT_PUD);
+}
+
+static void xen_release_pud(unsigned long pfn)
+{
+	xen_release_ptpage(pfn, PT_PUD);
+}
+#endif
+
+void __init xen_reserve_top(void)
+{
+#ifdef CONFIG_X86_32
+	unsigned long top = HYPERVISOR_VIRT_START;
+	struct xen_platform_parameters pp;
+
+	if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)
+		top = pp.virt_start;
+
+	reserve_top_address(-top);
+#endif	/* CONFIG_X86_32 */
+}
+
+/*
+ * Like __va(), but returns address in the kernel mapping (which is
+ * all we have until the physical memory mapping has been set up.
+ */
+static void *__ka(phys_addr_t paddr)
+{
+#ifdef CONFIG_X86_64
+	return (void *)(paddr + __START_KERNEL_map);
+#else
+	return __va(paddr);
+#endif
+}
+
+/* Convert a machine address to physical address */
+static unsigned long m2p(phys_addr_t maddr)
+{
+	phys_addr_t paddr;
+
+	maddr &= PTE_PFN_MASK;
+	paddr = mfn_to_pfn(maddr >> PAGE_SHIFT) << PAGE_SHIFT;
+
+	return paddr;
+}
+
+/* Convert a machine address to kernel virtual */
+static void *m2v(phys_addr_t maddr)
+{
+	return __ka(m2p(maddr));
+}
+
+static void set_page_prot(void *addr, pgprot_t prot)
+{
+	unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
+	pte_t pte = pfn_pte(pfn, prot);
+
+	if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
+		BUG();
+}
+
+static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+{
+	unsigned pmdidx, pteidx;
+	unsigned ident_pte;
+	unsigned long pfn;
+
+	ident_pte = 0;
+	pfn = 0;
+	for (pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
+		pte_t *pte_page;
+
+		/* Reuse or allocate a page of ptes */
+		if (pmd_present(pmd[pmdidx]))
+			pte_page = m2v(pmd[pmdidx].pmd);
+		else {
+			/* Check for free pte pages */
+			if (ident_pte == ARRAY_SIZE(level1_ident_pgt))
+				break;
+
+			pte_page = &level1_ident_pgt[ident_pte];
+			ident_pte += PTRS_PER_PTE;
+
+			pmd[pmdidx] = __pmd(__pa(pte_page) | _PAGE_TABLE);
+		}
+
+		/* Install mappings */
+		for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
+			pte_t pte;
+
+			if (pfn > max_pfn_mapped)
+				max_pfn_mapped = pfn;
+
+			if (!pte_none(pte_page[pteidx]))
+				continue;
+
+			pte = pfn_pte(pfn, PAGE_KERNEL_EXEC);
+			pte_page[pteidx] = pte;
+		}
+	}
+
+	for (pteidx = 0; pteidx < ident_pte; pteidx += PTRS_PER_PTE)
+		set_page_prot(&level1_ident_pgt[pteidx], PAGE_KERNEL_RO);
+
+	set_page_prot(pmd, PAGE_KERNEL_RO);
+}
+
+#ifdef CONFIG_X86_64
+static void convert_pfn_mfn(void *v)
+{
+	pte_t *pte = v;
+	int i;
+
+	/* All levels are converted the same way, so just treat them
+	   as ptes. */
+	for (i = 0; i < PTRS_PER_PTE; i++)
+		pte[i] = xen_make_pte(pte[i].pte);
+}
+
+/*
+ * Set up the inital kernel pagetable.
+ *
+ * We can construct this by grafting the Xen provided pagetable into
+ * head_64.S's preconstructed pagetables.  We copy the Xen L2's into
+ * level2_ident_pgt, level2_kernel_pgt and level2_fixmap_pgt.  This
+ * means that only the kernel has a physical mapping to start with -
+ * but that's enough to get __va working.  We need to fill in the rest
+ * of the physical mapping once some sort of allocator has been set
+ * up.
+ */
+__init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+					 unsigned long max_pfn)
+{
+	pud_t *l3;
+	pmd_t *l2;
+
+	/* Zap identity mapping */
+	init_level4_pgt[0] = __pgd(0);
+
+	/* Pre-constructed entries are in pfn, so convert to mfn */
+	convert_pfn_mfn(init_level4_pgt);
+	convert_pfn_mfn(level3_ident_pgt);
+	convert_pfn_mfn(level3_kernel_pgt);
+
+	l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
+	l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
+
+	memcpy(level2_ident_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+	memcpy(level2_kernel_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+
+	l3 = m2v(pgd[pgd_index(__START_KERNEL_map + PMD_SIZE)].pgd);
+	l2 = m2v(l3[pud_index(__START_KERNEL_map + PMD_SIZE)].pud);
+	memcpy(level2_fixmap_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+
+	/* Set up identity map */
+	xen_map_identity_early(level2_ident_pgt, max_pfn);
+
+	/* Make pagetable pieces RO */
+	set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
+	set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
+
+	/* Pin down new L4 */
+	pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
+			  PFN_DOWN(__pa_symbol(init_level4_pgt)));
+
+	/* Unpin Xen-provided one */
+	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+
+	/* Switch over */
+	pgd = init_level4_pgt;
+
+	/*
+	 * At this stage there can be no user pgd, and no page
+	 * structure to attach it to, so make sure we just set kernel
+	 * pgd.
+	 */
+	xen_mc_batch();
+	__xen_write_cr3(true, __pa(pgd));
+	xen_mc_issue(PARAVIRT_LAZY_CPU);
+
+	reserve_early(__pa(xen_start_info->pt_base),
+		      __pa(xen_start_info->pt_base +
+			   xen_start_info->nr_pt_frames * PAGE_SIZE),
+		      "XEN PAGETABLES");
+
+	return pgd;
+}
+#else	/* !CONFIG_X86_64 */
+static pmd_t level2_kernel_pgt[PTRS_PER_PMD] __page_aligned_bss;
+
+__init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+					 unsigned long max_pfn)
+{
+	pmd_t *kernel_pmd;
+
+	max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
+				  xen_start_info->nr_pt_frames * PAGE_SIZE +
+				  512*1024);
+
+	kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
+	memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+
+	xen_map_identity_early(level2_kernel_pgt, max_pfn);
+
+	memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
+	set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
+			__pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
+
+	set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
+	set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+	set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
+
+	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+
+	xen_write_cr3(__pa(swapper_pg_dir));
+
+	pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
+
+	reserve_early(__pa(xen_start_info->pt_base),
+		      __pa(xen_start_info->pt_base +
+			   xen_start_info->nr_pt_frames * PAGE_SIZE),
+		      "XEN PAGETABLES");
+
+	return swapper_pg_dir;
+}
+#endif	/* CONFIG_X86_64 */
+
+static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
+{
+	pte_t pte;
+
+	phys >>= PAGE_SHIFT;
+
+	switch (idx) {
+	case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
+#ifdef CONFIG_X86_F00F_BUG
+	case FIX_F00F_IDT:
+#endif
+#ifdef CONFIG_X86_32
+	case FIX_WP_TEST:
+	case FIX_VDSO:
+# ifdef CONFIG_HIGHMEM
+	case FIX_KMAP_BEGIN ... FIX_KMAP_END:
+# endif
+#else
+	case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+	case FIX_APIC_BASE:	/* maps dummy local APIC */
+#endif
+	case FIX_TEXT_POKE0:
+	case FIX_TEXT_POKE1:
+		/* All local page mappings */
+		pte = pfn_pte(phys, prot);
+		break;
+
+	default:
+		pte = mfn_pte(phys, prot);
+		break;
+	}
+
+	__native_set_fixmap(idx, pte);
+
+#ifdef CONFIG_X86_64
+	/* Replicate changes to map the vsyscall page into the user
+	   pagetable vsyscall mapping. */
+	if (idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) {
+		unsigned long vaddr = __fix_to_virt(idx);
+		set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte);
+	}
+#endif
+}
+
+__init void xen_post_allocator_init(void)
+{
+	pv_mmu_ops.set_pte = xen_set_pte;
+	pv_mmu_ops.set_pmd = xen_set_pmd;
+	pv_mmu_ops.set_pud = xen_set_pud;
+#if PAGETABLE_LEVELS == 4
+	pv_mmu_ops.set_pgd = xen_set_pgd;
+#endif
+
+	/* This will work as long as patching hasn't happened yet
+	   (which it hasn't) */
+	pv_mmu_ops.alloc_pte = xen_alloc_pte;
+	pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
+	pv_mmu_ops.release_pte = xen_release_pte;
+	pv_mmu_ops.release_pmd = xen_release_pmd;
+#if PAGETABLE_LEVELS == 4
+	pv_mmu_ops.alloc_pud = xen_alloc_pud;
+	pv_mmu_ops.release_pud = xen_release_pud;
+#endif
+
+#ifdef CONFIG_X86_64
+	SetPagePinned(virt_to_page(level3_user_vsyscall));
+#endif
+	xen_mark_init_mm_pinned();
+}
+
+const struct pv_mmu_ops xen_mmu_ops __initdata = {
+	.pagetable_setup_start = xen_pagetable_setup_start,
+	.pagetable_setup_done = xen_pagetable_setup_done,
+
+	.read_cr2 = xen_read_cr2,
+	.write_cr2 = xen_write_cr2,
+
+	.read_cr3 = xen_read_cr3,
+	.write_cr3 = xen_write_cr3,
+
+	.flush_tlb_user = xen_flush_tlb,
+	.flush_tlb_kernel = xen_flush_tlb,
+	.flush_tlb_single = xen_flush_tlb_single,
+	.flush_tlb_others = xen_flush_tlb_others,
+
+	.pte_update = paravirt_nop,
+	.pte_update_defer = paravirt_nop,
+
+	.pgd_alloc = xen_pgd_alloc,
+	.pgd_free = xen_pgd_free,
+
+	.alloc_pte = xen_alloc_pte_init,
+	.release_pte = xen_release_pte_init,
+	.alloc_pmd = xen_alloc_pmd_init,
+	.alloc_pmd_clone = paravirt_nop,
+	.release_pmd = xen_release_pmd_init,
+
+#ifdef CONFIG_HIGHPTE
+	.kmap_atomic_pte = xen_kmap_atomic_pte,
+#endif
+
+#ifdef CONFIG_X86_64
+	.set_pte = xen_set_pte,
+#else
+	.set_pte = xen_set_pte_init,
+#endif
+	.set_pte_at = xen_set_pte_at,
+	.set_pmd = xen_set_pmd_hyper,
+
+	.ptep_modify_prot_start = __ptep_modify_prot_start,
+	.ptep_modify_prot_commit = __ptep_modify_prot_commit,
+
+	.pte_val = PV_CALLEE_SAVE(xen_pte_val),
+	.pgd_val = PV_CALLEE_SAVE(xen_pgd_val),
+
+	.make_pte = PV_CALLEE_SAVE(xen_make_pte),
+	.make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
+
+#ifdef CONFIG_X86_PAE
+	.set_pte_atomic = xen_set_pte_atomic,
+	.pte_clear = xen_pte_clear,
+	.pmd_clear = xen_pmd_clear,
+#endif	/* CONFIG_X86_PAE */
+	.set_pud = xen_set_pud_hyper,
+
+	.make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
+	.pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
+
+#if PAGETABLE_LEVELS == 4
+	.pud_val = PV_CALLEE_SAVE(xen_pud_val),
+	.make_pud = PV_CALLEE_SAVE(xen_make_pud),
+	.set_pgd = xen_set_pgd_hyper,
+
+	.alloc_pud = xen_alloc_pmd_init,
+	.release_pud = xen_release_pmd_init,
+#endif	/* PAGETABLE_LEVELS == 4 */
+
+	.activate_mm = xen_activate_mm,
+	.dup_mmap = xen_dup_mmap,
+	.exit_mmap = xen_exit_mmap,
+
+	.lazy_mode = {
+		.enter = paravirt_enter_lazy_mmu,
+		.leave = xen_leave_lazy,
+	},
+
+	.set_fixmap = xen_set_fixmap,
+};
+
+
 #ifdef CONFIG_XEN_DEBUG_FS
 
 static struct dentry *d_mmu_debug;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/mmu.h linux-libre-2.6.30-gnu1/arch/x86/xen/mmu.h
--- linux-libre-2.6.29-gnu1/arch/x86/xen/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,9 @@ enum pt_level {
 };
 
 
+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+bool install_p2mtop_page(unsigned long pfn, unsigned long *p);
+
 void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
 
 
@@ -54,4 +57,7 @@ pte_t xen_ptep_modify_prot_start(struct
 void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 				  pte_t *ptep, pte_t pte);
 
+unsigned long xen_read_cr2_direct(void);
+
+extern const struct pv_mmu_ops xen_mmu_ops;
 #endif	/* _XEN_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/multicalls.c linux-libre-2.6.30-gnu1/arch/x86/xen/multicalls.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/multicalls.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/multicalls.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,7 @@ struct mc_buffer {
 	struct multicall_entry entries[MC_BATCH];
 #if MC_DEBUG
 	struct multicall_entry debug[MC_BATCH];
+	void *caller[MC_BATCH];
 #endif
 	unsigned char args[MC_ARGS];
 	struct callback {
@@ -154,11 +155,12 @@ void xen_mc_flush(void)
 			       ret, smp_processor_id());
 			dump_stack();
 			for (i = 0; i < b->mcidx; i++) {
-				printk(KERN_DEBUG "  call %2d/%d: op=%lu arg=[%lx] result=%ld\n",
+				printk(KERN_DEBUG "  call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n",
 				       i+1, b->mcidx,
 				       b->debug[i].op,
 				       b->debug[i].args[0],
-				       b->entries[i].result);
+				       b->entries[i].result,
+				       b->caller[i]);
 			}
 		}
 #endif
@@ -168,8 +170,6 @@ void xen_mc_flush(void)
 	} else
 		BUG_ON(b->argidx != 0);
 
-	local_irq_restore(flags);
-
 	for (i = 0; i < b->cbidx; i++) {
 		struct callback *cb = &b->callbacks[i];
 
@@ -177,7 +177,9 @@ void xen_mc_flush(void)
 	}
 	b->cbidx = 0;
 
-	BUG_ON(ret);
+	local_irq_restore(flags);
+
+	WARN_ON(ret);
 }
 
 struct multicall_space __xen_mc_entry(size_t args)
@@ -197,6 +199,9 @@ struct multicall_space __xen_mc_entry(si
 	}
 
 	ret.mc = &b->entries[b->mcidx];
+#ifdef MC_DEBUG
+	b->caller[b->mcidx] = __builtin_return_address(0);
+#endif
 	b->mcidx++;
 	ret.args = &b->args[argidx];
 	b->argidx = argidx + args;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/multicalls.h linux-libre-2.6.30-gnu1/arch/x86/xen/multicalls.h
--- linux-libre-2.6.29-gnu1/arch/x86/xen/multicalls.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/multicalls.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@ static inline void xen_mc_issue(unsigned
 		xen_mc_flush();
 
 	/* restore flags saved in xen_mc_batch */
-	local_irq_restore(x86_read_percpu(xen_mc_irq_flags));
+	local_irq_restore(percpu_read(xen_mc_irq_flags));
 }
 
 /* Set up a callback to be called when the current batch is flushed */
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/smp.c linux-libre-2.6.30-gnu1/arch/x86/xen/smp.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/smp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/smp.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,11 +50,7 @@ static irqreturn_t xen_call_function_sin
  */
 static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
 {
-#ifdef CONFIG_X86_32
-	__get_cpu_var(irq_stat).irq_resched_count++;
-#else
-	add_pda(irq_resched_count, 1);
-#endif
+	inc_irq_stat(irq_resched_count);
 
 	return IRQ_HANDLED;
 }
@@ -78,7 +74,7 @@ static __cpuinit void cpu_bringup(void)
 	xen_setup_cpu_clockevents();
 
 	cpu_set(cpu, cpu_online_map);
-	x86_write_percpu(cpu_state, CPU_ONLINE);
+	percpu_write(cpu_state, CPU_ONLINE);
 	wmb();
 
 	/* We can take interrupts now: we're officially "up". */
@@ -162,7 +158,7 @@ static void __init xen_fill_possible_map
 		rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
 		if (rc >= 0) {
 			num_processors++;
-			cpu_set(i, cpu_possible_map);
+			set_cpu_possible(i, true);
 		}
 	}
 }
@@ -174,7 +170,7 @@ static void __init xen_smp_prepare_boot_
 
 	/* We've switched to the "real" per-cpu gdt, so make sure the
 	   old memory can be recycled */
-	make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
+	make_lowmem_page_readwrite(xen_initial_gdt);
 
 	xen_setup_vcpu_info_placement();
 }
@@ -201,7 +197,7 @@ static void __init xen_smp_prepare_cpus(
 	while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) {
 		for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--)
 			continue;
-		cpu_clear(cpu, cpu_possible_map);
+		set_cpu_possible(cpu, false);
 	}
 
 	for_each_possible_cpu (cpu) {
@@ -214,7 +210,7 @@ static void __init xen_smp_prepare_cpus(
 		if (IS_ERR(idle))
 			panic("failed fork for CPU %d", cpu);
 
-		cpu_set(cpu, cpu_present_map);
+		set_cpu_present(cpu, true);
 	}
 }
 
@@ -223,6 +219,7 @@ cpu_initialize_context(unsigned int cpu,
 {
 	struct vcpu_guest_context *ctxt;
 	struct desc_struct *gdt;
+	unsigned long gdt_mfn;
 
 	if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map))
 		return 0;
@@ -239,6 +236,8 @@ cpu_initialize_context(unsigned int cpu,
 	ctxt->user_regs.ss = __KERNEL_DS;
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
+#else
+	ctxt->gs_base_kernel = per_cpu_offset(cpu);
 #endif
 	ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle;
 	ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */
@@ -250,9 +249,12 @@ cpu_initialize_context(unsigned int cpu,
 	ctxt->ldt_ents = 0;
 
 	BUG_ON((unsigned long)gdt & ~PAGE_MASK);
+
+	gdt_mfn = arbitrary_virt_to_mfn(gdt);
 	make_lowmem_page_readonly(gdt);
+	make_lowmem_page_readonly(mfn_to_virt(gdt_mfn));
 
-	ctxt->gdt_frames[0] = virt_to_mfn(gdt);
+	ctxt->gdt_frames[0] = gdt_mfn;
 	ctxt->gdt_ents      = GDT_ENTRIES;
 
 	ctxt->user_regs.cs = __KERNEL_CS;
@@ -283,23 +285,14 @@ static int __cpuinit xen_cpu_up(unsigned
 	struct task_struct *idle = idle_task(cpu);
 	int rc;
 
-#ifdef CONFIG_X86_64
-	/* Allocate node local memory for AP pdas */
-	WARN_ON(cpu == 0);
-	if (cpu > 0) {
-		rc = get_local_pda(cpu);
-		if (rc)
-			return rc;
-	}
-#endif
-
-#ifdef CONFIG_X86_32
-	init_gdt(cpu);
 	per_cpu(current_task, cpu) = idle;
+#ifdef CONFIG_X86_32
 	irq_ctx_init(cpu);
 #else
-	cpu_pda(cpu)->pcurrent = idle;
 	clear_tsk_thread_flag(idle, TIF_FORK);
+	per_cpu(kernel_stack, cpu) =
+		(unsigned long)task_stack_page(idle) -
+		KERNEL_STACK_OFFSET + THREAD_SIZE;
 #endif
 	xen_setup_timer(cpu);
 	xen_init_lock_cpu(cpu);
@@ -324,7 +317,7 @@ static int __cpuinit xen_cpu_up(unsigned
 	BUG_ON(rc);
 
 	while(per_cpu(cpu_state, cpu) != CPU_ONLINE) {
-		HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+		HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
 		barrier();
 	}
 
@@ -429,7 +422,7 @@ static void xen_smp_send_call_function_i
 	/* Make sure other vcpus get a chance to run if they need to. */
 	for_each_cpu(cpu, mask) {
 		if (xen_vcpu_stolen(cpu)) {
-			HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+			HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
 			break;
 		}
 	}
@@ -445,11 +438,7 @@ static irqreturn_t xen_call_function_int
 {
 	irq_enter();
 	generic_smp_call_function_interrupt();
-#ifdef CONFIG_X86_32
-	__get_cpu_var(irq_stat).irq_call_count++;
-#else
-	add_pda(irq_call_count, 1);
-#endif
+	inc_irq_stat(irq_call_count);
 	irq_exit();
 
 	return IRQ_HANDLED;
@@ -459,11 +448,7 @@ static irqreturn_t xen_call_function_sin
 {
 	irq_enter();
 	generic_smp_call_function_single_interrupt();
-#ifdef CONFIG_X86_32
-	__get_cpu_var(irq_stat).irq_call_count++;
-#else
-	add_pda(irq_call_count, 1);
-#endif
+	inc_irq_stat(irq_call_count);
 	irq_exit();
 
 	return IRQ_HANDLED;
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/suspend.c linux-libre-2.6.30-gnu1/arch/x86/xen/suspend.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/suspend.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/suspend.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
+#include <asm/fixmap.h>
 
 #include "xen-ops.h"
 #include "mmu.h"
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/time.c linux-libre-2.6.30-gnu1/arch/x86/xen/time.c
--- linux-libre-2.6.29-gnu1/arch/x86/xen/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -213,6 +213,11 @@ cycle_t xen_clocksource_read(void)
 	return ret;
 }
 
+static cycle_t xen_clocksource_get_cycles(struct clocksource *cs)
+{
+	return xen_clocksource_read();
+}
+
 static void xen_read_wallclock(struct timespec *ts)
 {
 	struct shared_info *s = HYPERVISOR_shared_info;
@@ -241,7 +246,7 @@ int xen_set_wallclock(unsigned long now)
 static struct clocksource xen_clocksource __read_mostly = {
 	.name = "xen",
 	.rating = 400,
-	.read = xen_clocksource_read,
+	.read = xen_clocksource_get_cycles,
 	.mask = ~0,
 	.mult = 1<<XEN_SHIFT,		/* time directly in nanoseconds */
 	.shift = XEN_SHIFT,
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm_32.S linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm_32.S
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm_32.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm_32.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,117 +1,43 @@
 /*
-	Asm versions of Xen pv-ops, suitable for either direct use or inlining.
-	The inline versions are the same as the direct-use versions, with the
-	pre- and post-amble chopped off.
-
-	This code is encoded for size rather than absolute efficiency,
-	with a view to being able to inline as much as possible.
-
-	We only bother with direct forms (ie, vcpu in pda) of the operations
-	here; the indirect forms are better handled in C, since they're
-	generally too large to inline anyway.
+ * Asm versions of Xen pv-ops, suitable for either direct use or
+ * inlining.  The inline versions are the same as the direct-use
+ * versions, with the pre- and post-amble chopped off.
+ *
+ * This code is encoded for size rather than absolute efficiency, with
+ * a view to being able to inline as much as possible.
+ *
+ * We only bother with direct forms (ie, vcpu in pda) of the
+ * operations here; the indirect forms are better handled in C, since
+ * they're generally too large to inline anyway.
  */
 
-#include <linux/linkage.h>
-
-#include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
-#include <asm/percpu.h>
 #include <asm/processor-flags.h>
 #include <asm/segment.h>
 
 #include <xen/interface/xen.h>
 
-#define RELOC(x, v)	.globl x##_reloc; x##_reloc=v
-#define ENDPATCH(x)	.globl x##_end; x##_end=.
-
-/* Pseudo-flag used for virtual NMI, which we don't implement yet */
-#define XEN_EFLAGS_NMI	0x80000000
-
-/*
-	Enable events.  This clears the event mask and tests the pending
-	event status with one and operation.  If there are pending
-	events, then enter the hypervisor to get them handled.
- */
-ENTRY(xen_irq_enable_direct)
-	/* Unmask events */
-	movb $0, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
-
-	/* Preempt here doesn't matter because that will deal with
-	   any pending interrupts.  The pending check may end up being
-	   run on the wrong CPU, but that doesn't hurt. */
-
-	/* Test for pending */
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
-	jz 1f
-
-2:	call check_events
-1:
-ENDPATCH(xen_irq_enable_direct)
-	ret
-	ENDPROC(xen_irq_enable_direct)
-	RELOC(xen_irq_enable_direct, 2b+1)
-
-
-/*
-	Disabling events is simply a matter of making the event mask
-	non-zero.
- */
-ENTRY(xen_irq_disable_direct)
-	movb $1, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
-ENDPATCH(xen_irq_disable_direct)
-	ret
-	ENDPROC(xen_irq_disable_direct)
-	RELOC(xen_irq_disable_direct, 0)
-
-/*
-	(xen_)save_fl is used to get the current interrupt enable status.
-	Callers expect the status to be in X86_EFLAGS_IF, and other bits
-	may be set in the return value.  We take advantage of this by
-	making sure that X86_EFLAGS_IF has the right value (and other bits
-	in that byte are 0), but other bits in the return value are
-	undefined.  We need to toggle the state of the bit, because
-	Xen and x86 use opposite senses (mask vs enable).
- */
-ENTRY(xen_save_fl_direct)
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
-	setz %ah
-	addb %ah,%ah
-ENDPATCH(xen_save_fl_direct)
-	ret
-	ENDPROC(xen_save_fl_direct)
-	RELOC(xen_save_fl_direct, 0)
-
+#include "xen-asm.h"
 
 /*
-	In principle the caller should be passing us a value return
-	from xen_save_fl_direct, but for robustness sake we test only
-	the X86_EFLAGS_IF flag rather than the whole byte. After
-	setting the interrupt mask state, it checks for unmasked
-	pending events and enters the hypervisor to get them delivered
-	if so.
+ * Force an event check by making a hypercall, but preserve regs
+ * before making the call.
  */
-ENTRY(xen_restore_fl_direct)
-	testb $X86_EFLAGS_IF>>8, %ah
-	setz PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
-	/* Preempt here doesn't matter because that will deal with
-	   any pending interrupts.  The pending check may end up being
-	   run on the wrong CPU, but that doesn't hurt. */
-
-	/* check for unmasked and pending */
-	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
-	jz 1f
-2:	call check_events
-1:
-ENDPATCH(xen_restore_fl_direct)
+check_events:
+	push %eax
+	push %ecx
+	push %edx
+	call xen_force_evtchn_callback
+	pop %edx
+	pop %ecx
+	pop %eax
 	ret
-	ENDPROC(xen_restore_fl_direct)
-	RELOC(xen_restore_fl_direct, 2b+1)
 
 /*
-	We can't use sysexit directly, because we're not running in ring0.
-	But we can easily fake it up using iret.  Assuming xen_sysexit
-	is jumped to with a standard stack frame, we can just strip it
-	back to a standard iret frame and use iret.
+ * We can't use sysexit directly, because we're not running in ring0.
+ * But we can easily fake it up using iret.  Assuming xen_sysexit is
+ * jumped to with a standard stack frame, we can just strip it back to
+ * a standard iret frame and use iret.
  */
 ENTRY(xen_sysexit)
 	movl PT_EAX(%esp), %eax			/* Shouldn't be necessary? */
@@ -122,33 +48,31 @@ ENTRY(xen_sysexit)
 ENDPROC(xen_sysexit)
 
 /*
-	This is run where a normal iret would be run, with the same stack setup:
-	      8: eflags
-	      4: cs
-	esp-> 0: eip
-
-	This attempts to make sure that any pending events are dealt
-	with on return to usermode, but there is a small window in
-	which an event can happen just before entering usermode.  If
-	the nested interrupt ends up setting one of the TIF_WORK_MASK
-	pending work flags, they will not be tested again before
-	returning to usermode. This means that a process can end up
-	with pending work, which will be unprocessed until the process
-	enters and leaves the kernel again, which could be an
-	unbounded amount of time.  This means that a pending signal or
-	reschedule event could be indefinitely delayed.
-
-	The fix is to notice a nested interrupt in the critical
-	window, and if one occurs, then fold the nested interrupt into
-	the current interrupt stack frame, and re-process it
-	iteratively rather than recursively.  This means that it will
-	exit via the normal path, and all pending work will be dealt
-	with appropriately.
-
-	Because the nested interrupt handler needs to deal with the
-	current stack state in whatever form its in, we keep things
-	simple by only using a single register which is pushed/popped
-	on the stack.
+ * This is run where a normal iret would be run, with the same stack setup:
+ *	8: eflags
+ *	4: cs
+ *	esp-> 0: eip
+ *
+ * This attempts to make sure that any pending events are dealt with
+ * on return to usermode, but there is a small window in which an
+ * event can happen just before entering usermode.  If the nested
+ * interrupt ends up setting one of the TIF_WORK_MASK pending work
+ * flags, they will not be tested again before returning to
+ * usermode. This means that a process can end up with pending work,
+ * which will be unprocessed until the process enters and leaves the
+ * kernel again, which could be an unbounded amount of time.  This
+ * means that a pending signal or reschedule event could be
+ * indefinitely delayed.
+ *
+ * The fix is to notice a nested interrupt in the critical window, and
+ * if one occurs, then fold the nested interrupt into the current
+ * interrupt stack frame, and re-process it iteratively rather than
+ * recursively.  This means that it will exit via the normal path, and
+ * all pending work will be dealt with appropriately.
+ *
+ * Because the nested interrupt handler needs to deal with the current
+ * stack state in whatever form its in, we keep things simple by only
+ * using a single register which is pushed/popped on the stack.
  */
 ENTRY(xen_iret)
 	/* test eflags for special cases */
@@ -158,13 +82,15 @@ ENTRY(xen_iret)
 	push %eax
 	ESP_OFFSET=4	# bytes pushed onto stack
 
-	/* Store vcpu_info pointer for easy access.  Do it this
-	   way to avoid having to reload %fs */
+	/*
+	 * Store vcpu_info pointer for easy access.  Do it this way to
+	 * avoid having to reload %fs
+	 */
 #ifdef CONFIG_SMP
 	GET_THREAD_INFO(%eax)
-	movl TI_cpu(%eax),%eax
-	movl __per_cpu_offset(,%eax,4),%eax
-	mov per_cpu__xen_vcpu(%eax),%eax
+	movl TI_cpu(%eax), %eax
+	movl __per_cpu_offset(,%eax,4), %eax
+	mov per_cpu__xen_vcpu(%eax), %eax
 #else
 	movl per_cpu__xen_vcpu, %eax
 #endif
@@ -172,37 +98,46 @@ ENTRY(xen_iret)
 	/* check IF state we're restoring */
 	testb $X86_EFLAGS_IF>>8, 8+1+ESP_OFFSET(%esp)
 
-	/* Maybe enable events.  Once this happens we could get a
-	   recursive event, so the critical region starts immediately
-	   afterwards.  However, if that happens we don't end up
-	   resuming the code, so we don't have to be worried about
-	   being preempted to another CPU. */
+	/*
+	 * Maybe enable events.  Once this happens we could get a
+	 * recursive event, so the critical region starts immediately
+	 * afterwards.  However, if that happens we don't end up
+	 * resuming the code, so we don't have to be worried about
+	 * being preempted to another CPU.
+	 */
 	setz XEN_vcpu_info_mask(%eax)
 xen_iret_start_crit:
 
 	/* check for unmasked and pending */
 	cmpw $0x0001, XEN_vcpu_info_pending(%eax)
 
-	/* If there's something pending, mask events again so we
-	   can jump back into xen_hypervisor_callback */
+	/*
+	 * If there's something pending, mask events again so we can
+	 * jump back into xen_hypervisor_callback
+	 */
 	sete XEN_vcpu_info_mask(%eax)
 
 	popl %eax
 
-	/* From this point on the registers are restored and the stack
-	   updated, so we don't need to worry about it if we're preempted */
+	/*
+	 * From this point on the registers are restored and the stack
+	 * updated, so we don't need to worry about it if we're
+	 * preempted
+	 */
 iret_restore_end:
 
-	/* Jump to hypervisor_callback after fixing up the stack.
-	   Events are masked, so jumping out of the critical
-	   region is OK. */
+	/*
+	 * Jump to hypervisor_callback after fixing up the stack.
+	 * Events are masked, so jumping out of the critical region is
+	 * OK.
+	 */
 	je xen_hypervisor_callback
 
 1:	iret
 xen_iret_end_crit:
-.section __ex_table,"a"
+.section __ex_table, "a"
 	.align 4
-	.long 1b,iret_exc
+	.long 1b, iret_exc
 .previous
 
 hyper_iret:
@@ -212,55 +147,55 @@ hyper_iret:
 	.globl xen_iret_start_crit, xen_iret_end_crit
 
 /*
-   This is called by xen_hypervisor_callback in entry.S when it sees
-   that the EIP at the time of interrupt was between xen_iret_start_crit
-   and xen_iret_end_crit.  We're passed the EIP in %eax so we can do
-   a more refined determination of what to do.
-
-   The stack format at this point is:
-	----------------
-	 ss		: (ss/esp may be present if we came from usermode)
-	 esp		:
-	 eflags		}  outer exception info
-	 cs		}
-	 eip		}
-	---------------- <- edi (copy dest)
-	 eax		:  outer eax if it hasn't been restored
-	----------------
-	 eflags		}  nested exception info
-	 cs		}   (no ss/esp because we're nested
-	 eip		}    from the same ring)
-	 orig_eax	}<- esi (copy src)
-	 - - - - - - - -
-	 fs		}
-	 es		}
-	 ds		}  SAVE_ALL state
-	 eax		}
-	  :		:
-	 ebx		}<- esp
-	----------------
-
-   In order to deliver the nested exception properly, we need to shift
-   everything from the return addr up to the error code so it
-   sits just under the outer exception info.  This means that when we
-   handle the exception, we do it in the context of the outer exception
-   rather than starting a new one.
-
-   The only caveat is that if the outer eax hasn't been
-   restored yet (ie, it's still on stack), we need to insert
-   its value into the SAVE_ALL state before going on, since
-   it's usermode state which we eventually need to restore.
+ * This is called by xen_hypervisor_callback in entry.S when it sees
+ * that the EIP at the time of interrupt was between
+ * xen_iret_start_crit and xen_iret_end_crit.  We're passed the EIP in
+ * %eax so we can do a more refined determination of what to do.
+ *
+ * The stack format at this point is:
+ *	----------------
+ *	 ss		: (ss/esp may be present if we came from usermode)
+ *	 esp		:
+ *	 eflags		}  outer exception info
+ *	 cs		}
+ *	 eip		}
+ *	---------------- <- edi (copy dest)
+ *	 eax		:  outer eax if it hasn't been restored
+ *	----------------
+ *	 eflags		}  nested exception info
+ *	 cs		}   (no ss/esp because we're nested
+ *	 eip		}    from the same ring)
+ *	 orig_eax	}<- esi (copy src)
+ *	 - - - - - - - -
+ *	 fs		}
+ *	 es		}
+ *	 ds		}  SAVE_ALL state
+ *	 eax		}
+ *	  :		:
+ *	 ebx		}<- esp
+ *	----------------
+ *
+ * In order to deliver the nested exception properly, we need to shift
+ * everything from the return addr up to the error code so it sits
+ * just under the outer exception info.  This means that when we
+ * handle the exception, we do it in the context of the outer
+ * exception rather than starting a new one.
+ *
+ * The only caveat is that if the outer eax hasn't been restored yet
+ * (ie, it's still on stack), we need to insert its value into the
+ * SAVE_ALL state before going on, since it's usermode state which we
+ * eventually need to restore.
  */
 ENTRY(xen_iret_crit_fixup)
 	/*
-	   Paranoia: Make sure we're really coming from kernel space.
-	   One could imagine a case where userspace jumps into the
-	   critical range address, but just before the CPU delivers a GP,
-	   it decides to deliver an interrupt instead.  Unlikely?
-	   Definitely.  Easy to avoid?  Yes.  The Intel documents
-	   explicitly say that the reported EIP for a bad jump is the
-	   jump instruction itself, not the destination, but some virtual
-	   environments get this wrong.
+	 * Paranoia: Make sure we're really coming from kernel space.
+	 * One could imagine a case where userspace jumps into the
+	 * critical range address, but just before the CPU delivers a
+	 * GP, it decides to deliver an interrupt instead.  Unlikely?
+	 * Definitely.  Easy to avoid?  Yes.  The Intel documents
+	 * explicitly say that the reported EIP for a bad jump is the
+	 * jump instruction itself, not the destination, but some
+	 * virtual environments get this wrong.
 	 */
 	movl PT_CS(%esp), %ecx
 	andl $SEGMENT_RPL_MASK, %ecx
@@ -270,15 +205,17 @@ ENTRY(xen_iret_crit_fixup)
 	lea PT_ORIG_EAX(%esp), %esi
 	lea PT_EFLAGS(%esp), %edi
 
-	/* If eip is before iret_restore_end then stack
-	   hasn't been restored yet. */
+	/*
+	 * If eip is before iret_restore_end then stack
+	 * hasn't been restored yet.
+	 */
 	cmp $iret_restore_end, %eax
 	jae 1f
 
-	movl 0+4(%edi),%eax		/* copy EAX (just above top of frame) */
+	movl 0+4(%edi), %eax		/* copy EAX (just above top of frame) */
 	movl %eax, PT_EAX(%esp)
 
-	lea ESP_OFFSET(%edi),%edi	/* move dest up over saved regs */
+	lea ESP_OFFSET(%edi), %edi	/* move dest up over saved regs */
 
 	/* set up the copy */
 1:	std
@@ -286,20 +223,6 @@ ENTRY(xen_iret_crit_fixup)
 	rep movsl
 	cld
 
-	lea 4(%edi),%esp		/* point esp to new frame */
+	lea 4(%edi), %esp		/* point esp to new frame */
 2:	jmp xen_do_upcall
 
-
-/*
-	Force an event check by making a hypercall,
-	but preserve regs before making the call.
- */
-check_events:
-	push %eax
-	push %ecx
-	push %edx
-	call xen_force_evtchn_callback
-	pop %edx
-	pop %ecx
-	pop %eax
-	ret
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm_64.S linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm_64.S
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm_64.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm_64.S	2009-06-09 23:05:27.000000000 -0400
@@ -1,174 +1,45 @@
 /*
-	Asm versions of Xen pv-ops, suitable for either direct use or inlining.
-	The inline versions are the same as the direct-use versions, with the
-	pre- and post-amble chopped off.
-
-	This code is encoded for size rather than absolute efficiency,
-	with a view to being able to inline as much as possible.
-
-	We only bother with direct forms (ie, vcpu in pda) of the operations
-	here; the indirect forms are better handled in C, since they're
-	generally too large to inline anyway.
+ * Asm versions of Xen pv-ops, suitable for either direct use or
+ * inlining.  The inline versions are the same as the direct-use
+ * versions, with the pre- and post-amble chopped off.
+ *
+ * This code is encoded for size rather than absolute efficiency, with
+ * a view to being able to inline as much as possible.
+ *
+ * We only bother with direct forms (ie, vcpu in pda) of the
+ * operations here; the indirect forms are better handled in C, since
+ * they're generally too large to inline anyway.
  */
 
-#include <linux/linkage.h>
-
-#include <asm/asm-offsets.h>
-#include <asm/processor-flags.h>
 #include <asm/errno.h>
+#include <asm/percpu.h>
+#include <asm/processor-flags.h>
 #include <asm/segment.h>
 
 #include <xen/interface/xen.h>
 
-#define RELOC(x, v)	.globl x##_reloc; x##_reloc=v
-#define ENDPATCH(x)	.globl x##_end; x##_end=.
-
-/* Pseudo-flag used for virtual NMI, which we don't implement yet */
-#define XEN_EFLAGS_NMI	0x80000000
-
-#if 1
-/*
-	x86-64 does not yet support direct access to percpu variables
-	via a segment override, so we just need to make sure this code
-	never gets used
- */
-#define BUG			ud2a
-#define PER_CPU_VAR(var, off)	0xdeadbeef
-#endif
-
-/*
-	Enable events.  This clears the event mask and tests the pending
-	event status with one and operation.  If there are pending
-	events, then enter the hypervisor to get them handled.
- */
-ENTRY(xen_irq_enable_direct)
-	BUG
-
-	/* Unmask events */
-	movb $0, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
-
-	/* Preempt here doesn't matter because that will deal with
-	   any pending interrupts.  The pending check may end up being
-	   run on the wrong CPU, but that doesn't hurt. */
-
-	/* Test for pending */
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
-	jz 1f
-
-2:	call check_events
-1:
-ENDPATCH(xen_irq_enable_direct)
-	ret
-	ENDPROC(xen_irq_enable_direct)
-	RELOC(xen_irq_enable_direct, 2b+1)
-
-/*
-	Disabling events is simply a matter of making the event mask
-	non-zero.
- */
-ENTRY(xen_irq_disable_direct)
-	BUG
-
-	movb $1, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
-ENDPATCH(xen_irq_disable_direct)
-	ret
-	ENDPROC(xen_irq_disable_direct)
-	RELOC(xen_irq_disable_direct, 0)
-
-/*
-	(xen_)save_fl is used to get the current interrupt enable status.
-	Callers expect the status to be in X86_EFLAGS_IF, and other bits
-	may be set in the return value.  We take advantage of this by
-	making sure that X86_EFLAGS_IF has the right value (and other bits
-	in that byte are 0), but other bits in the return value are
-	undefined.  We need to toggle the state of the bit, because
-	Xen and x86 use opposite senses (mask vs enable).
- */
-ENTRY(xen_save_fl_direct)
-	BUG
-
-	testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
-	setz %ah
-	addb %ah,%ah
-ENDPATCH(xen_save_fl_direct)
-	ret
-	ENDPROC(xen_save_fl_direct)
-	RELOC(xen_save_fl_direct, 0)
-
-/*
-	In principle the caller should be passing us a value return
-	from xen_save_fl_direct, but for robustness sake we test only
-	the X86_EFLAGS_IF flag rather than the whole byte. After
-	setting the interrupt mask state, it checks for unmasked
-	pending events and enters the hypervisor to get them delivered
-	if so.
- */
-ENTRY(xen_restore_fl_direct)
-	BUG
-
-	testb $X86_EFLAGS_IF>>8, %ah
-	setz PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
-	/* Preempt here doesn't matter because that will deal with
-	   any pending interrupts.  The pending check may end up being
-	   run on the wrong CPU, but that doesn't hurt. */
-
-	/* check for unmasked and pending */
-	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
-	jz 1f
-2:	call check_events
-1:
-ENDPATCH(xen_restore_fl_direct)
-	ret
-	ENDPROC(xen_restore_fl_direct)
-	RELOC(xen_restore_fl_direct, 2b+1)
-
-
-/*
-	Force an event check by making a hypercall,
-	but preserve regs before making the call.
- */
-check_events:
-	push %rax
-	push %rcx
-	push %rdx
-	push %rsi
-	push %rdi
-	push %r8
-	push %r9
-	push %r10
-	push %r11
-	call xen_force_evtchn_callback
-	pop %r11
-	pop %r10
-	pop %r9
-	pop %r8
-	pop %rdi
-	pop %rsi
-	pop %rdx
-	pop %rcx
-	pop %rax
-	ret
+#include "xen-asm.h"
 
 ENTRY(xen_adjust_exception_frame)
-	mov 8+0(%rsp),%rcx
-	mov 8+8(%rsp),%r11
+	mov 8+0(%rsp), %rcx
+	mov 8+8(%rsp), %r11
 	ret $16
 
 hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
 /*
-	Xen64 iret frame:
-
-	ss
-	rsp
-	rflags
-	cs
-	rip		<-- standard iret frame
-
-	flags
-
-	rcx		}
-	r11		}<-- pushed by hypercall page
-rsp ->	rax		}
+ * Xen64 iret frame:
+ *
+ *	ss
+ *	rsp
+ *	rflags
+ *	cs
+ *	rip		<-- standard iret frame
+ *
+ *	flags
+ *
+ *	rcx		}
+ *	r11		}<-- pushed by hypercall page
+ * rsp->rax		}
  */
 ENTRY(xen_iret)
 	pushq $0
@@ -177,8 +48,8 @@ ENDPATCH(xen_iret)
 RELOC(xen_iret, 1b+1)
 
 /*
-	sysexit is not used for 64-bit processes, so it's
-	only ever used to return to 32-bit compat userspace.
+ * sysexit is not used for 64-bit processes, so it's only ever used to
+ * return to 32-bit compat userspace.
  */
 ENTRY(xen_sysexit)
 	pushq $__USER32_DS
@@ -193,13 +64,15 @@ ENDPATCH(xen_sysexit)
 RELOC(xen_sysexit, 1b+1)
 
 ENTRY(xen_sysret64)
-	/* We're already on the usermode stack at this point, but still
-	   with the kernel gs, so we can easily switch back */
-	movq %rsp, %gs:pda_oldrsp
-	movq %gs:pda_kernelstack,%rsp
+	/*
+	 * We're already on the usermode stack at this point, but
+	 * still with the kernel gs, so we can easily switch back
+	 */
+	movq %rsp, PER_CPU_VAR(old_rsp)
+	movq PER_CPU_VAR(kernel_stack), %rsp
 
 	pushq $__USER_DS
-	pushq %gs:pda_oldrsp
+	pushq PER_CPU_VAR(old_rsp)
 	pushq %r11
 	pushq $__USER_CS
 	pushq %rcx
@@ -210,13 +83,15 @@ ENDPATCH(xen_sysret64)
 RELOC(xen_sysret64, 1b+1)
 
 ENTRY(xen_sysret32)
-	/* We're already on the usermode stack at this point, but still
-	   with the kernel gs, so we can easily switch back */
-	movq %rsp, %gs:pda_oldrsp
-	movq %gs:pda_kernelstack, %rsp
+	/*
+	 * We're already on the usermode stack at this point, but
+	 * still with the kernel gs, so we can easily switch back
+	 */
+	movq %rsp, PER_CPU_VAR(old_rsp)
+	movq PER_CPU_VAR(kernel_stack), %rsp
 
 	pushq $__USER32_DS
-	pushq %gs:pda_oldrsp
+	pushq PER_CPU_VAR(old_rsp)
 	pushq %r11
 	pushq $__USER32_CS
 	pushq %rcx
@@ -227,28 +102,27 @@ ENDPATCH(xen_sysret32)
 RELOC(xen_sysret32, 1b+1)
 
 /*
-	Xen handles syscall callbacks much like ordinary exceptions,
-	which means we have:
-	 - kernel gs
-	 - kernel rsp
-	 - an iret-like stack frame on the stack (including rcx and r11):
-		ss
-		rsp
-		rflags
-		cs
-		rip
-		r11
-	rsp->	rcx
-
-	In all the entrypoints, we undo all that to make it look
-	like a CPU-generated syscall/sysenter and jump to the normal
-	entrypoint.
+ * Xen handles syscall callbacks much like ordinary exceptions, which
+ * means we have:
+ * - kernel gs
+ * - kernel rsp
+ * - an iret-like stack frame on the stack (including rcx and r11):
+ *	ss
+ *	rsp
+ *	rflags
+ *	cs
+ *	rip
+ *	r11
+ * rsp->rcx
+ *
+ * In all the entrypoints, we undo all that to make it look like a
+ * CPU-generated syscall/sysenter and jump to the normal entrypoint.
  */
 
 .macro undo_xen_syscall
-	mov 0*8(%rsp),%rcx
-	mov 1*8(%rsp),%r11
-	mov 5*8(%rsp),%rsp
+	mov 0*8(%rsp), %rcx
+	mov 1*8(%rsp), %r11
+	mov 5*8(%rsp), %rsp
 .endm
 
 /* Normal 64-bit system call target */
@@ -275,7 +149,7 @@ ENDPROC(xen_sysenter_target)
 
 ENTRY(xen_syscall32_target)
 ENTRY(xen_sysenter_target)
-	lea 16(%rsp), %rsp	/* strip %rcx,%r11 */
+	lea 16(%rsp), %rsp	/* strip %rcx, %r11 */
 	mov $-ENOSYS, %rax
 	pushq $VGCF_in_syscall
 	jmp hypercall_iret
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm.h linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm.h
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef _XEN_XEN_ASM_H
+#define _XEN_XEN_ASM_H
+
+#include <linux/linkage.h>
+
+#define RELOC(x, v)	.globl x##_reloc; x##_reloc=v
+#define ENDPATCH(x)	.globl x##_end; x##_end=.
+
+/* Pseudo-flag used for virtual NMI, which we don't implement yet */
+#define XEN_EFLAGS_NMI	0x80000000
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm.S linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm.S
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-asm.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-asm.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,142 @@
+/*
+ * Asm versions of Xen pv-ops, suitable for either direct use or
+ * inlining.  The inline versions are the same as the direct-use
+ * versions, with the pre- and post-amble chopped off.
+ *
+ * This code is encoded for size rather than absolute efficiency, with
+ * a view to being able to inline as much as possible.
+ *
+ * We only bother with direct forms (ie, vcpu in percpu data) of the
+ * operations here; the indirect forms are better handled in C, since
+ * they're generally too large to inline anyway.
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/percpu.h>
+#include <asm/processor-flags.h>
+
+#include "xen-asm.h"
+
+/*
+ * Enable events.  This clears the event mask and tests the pending
+ * event status with one and operation.  If there are pending events,
+ * then enter the hypervisor to get them handled.
+ */
+ENTRY(xen_irq_enable_direct)
+	/* Unmask events */
+	movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+
+	/*
+	 * Preempt here doesn't matter because that will deal with any
+	 * pending interrupts.  The pending check may end up being run
+	 * on the wrong CPU, but that doesn't hurt.
+	 */
+
+	/* Test for pending */
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+	jz 1f
+
+2:	call check_events
+1:
+ENDPATCH(xen_irq_enable_direct)
+	ret
+	ENDPROC(xen_irq_enable_direct)
+	RELOC(xen_irq_enable_direct, 2b+1)
+
+
+/*
+ * Disabling events is simply a matter of making the event mask
+ * non-zero.
+ */
+ENTRY(xen_irq_disable_direct)
+	movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+ENDPATCH(xen_irq_disable_direct)
+	ret
+	ENDPROC(xen_irq_disable_direct)
+	RELOC(xen_irq_disable_direct, 0)
+
+/*
+ * (xen_)save_fl is used to get the current interrupt enable status.
+ * Callers expect the status to be in X86_EFLAGS_IF, and other bits
+ * may be set in the return value.  We take advantage of this by
+ * making sure that X86_EFLAGS_IF has the right value (and other bits
+ * in that byte are 0), but other bits in the return value are
+ * undefined.  We need to toggle the state of the bit, because Xen and
+ * x86 use opposite senses (mask vs enable).
+ */
+ENTRY(xen_save_fl_direct)
+	testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+	setz %ah
+	addb %ah, %ah
+ENDPATCH(xen_save_fl_direct)
+	ret
+	ENDPROC(xen_save_fl_direct)
+	RELOC(xen_save_fl_direct, 0)
+
+
+/*
+ * In principle the caller should be passing us a value return from
+ * xen_save_fl_direct, but for robustness sake we test only the
+ * X86_EFLAGS_IF flag rather than the whole byte. After setting the
+ * interrupt mask state, it checks for unmasked pending events and
+ * enters the hypervisor to get them delivered if so.
+ */
+ENTRY(xen_restore_fl_direct)
+#ifdef CONFIG_X86_64
+	testw $X86_EFLAGS_IF, %di
+#else
+	testb $X86_EFLAGS_IF>>8, %ah
+#endif
+	setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+	/*
+	 * Preempt here doesn't matter because that will deal with any
+	 * pending interrupts.  The pending check may end up being run
+	 * on the wrong CPU, but that doesn't hurt.
+	 */
+
+	/* check for unmasked and pending */
+	cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+	jz 1f
+2:	call check_events
+1:
+ENDPATCH(xen_restore_fl_direct)
+	ret
+	ENDPROC(xen_restore_fl_direct)
+	RELOC(xen_restore_fl_direct, 2b+1)
+
+
+/*
+ * Force an event check by making a hypercall, but preserve regs
+ * before making the call.
+ */
+check_events:
+#ifdef CONFIG_X86_32
+	push %eax
+	push %ecx
+	push %edx
+	call xen_force_evtchn_callback
+	pop %edx
+	pop %ecx
+	pop %eax
+#else
+	push %rax
+	push %rcx
+	push %rdx
+	push %rsi
+	push %rdi
+	push %r8
+	push %r9
+	push %r10
+	push %r11
+	call xen_force_evtchn_callback
+	pop %r11
+	pop %r10
+	pop %r9
+	pop %r8
+	pop %rdi
+	pop %rsi
+	pop %rdx
+	pop %rcx
+	pop %rax
+#endif
+	ret
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-head.S linux-libre-2.6.30-gnu1/arch/x86/xen/xen-head.S
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-head.S	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
 
 #include <asm/boot.h>
 #include <asm/asm.h>
-#include <asm/page.h>
+#include <asm/page_types.h>
 
 #include <xen/interface/elfnote.h>
 #include <asm/xen/interface.h>
diff -druNp linux-libre-2.6.29-gnu1/arch/x86/xen/xen-ops.h linux-libre-2.6.30-gnu1/arch/x86/xen/xen-ops.h
--- linux-libre-2.6.29-gnu1/arch/x86/xen/xen-ops.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/x86/xen/xen-ops.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,9 +10,12 @@
 extern const char xen_hypervisor_callback[];
 extern const char xen_failsafe_callback[];
 
+extern void *xen_initial_gdt;
+
 struct trap_info;
 void xen_copy_trap_info(struct trap_info *traps);
 
+DECLARE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 DECLARE_PER_CPU(unsigned long, xen_cr3);
 DECLARE_PER_CPU(unsigned long, xen_current_cr3);
 
@@ -22,6 +25,13 @@ extern struct shared_info *HYPERVISOR_sh
 
 void xen_setup_mfn_list_list(void);
 void xen_setup_shared_info(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);
+void xen_reserve_top(void);
+
+void xen_leave_lazy(void);
+void xen_post_allocator_init(void);
 
 char * __init xen_memory_setup(void);
 void __init xen_arch_setup(void);
@@ -47,22 +57,31 @@ irqreturn_t xen_debug_interrupt(int irq,
 
 bool xen_vcpu_stolen(int vcpu);
 
-void xen_mark_init_mm_pinned(void);
-
 void xen_setup_vcpu_info_placement(void);
 
 #ifdef CONFIG_SMP
 void xen_smp_init(void);
 
-void __init xen_init_spinlocks(void);
-__cpuinit void xen_init_lock_cpu(int cpu);
-void xen_uninit_lock_cpu(int cpu);
-
 extern cpumask_var_t xen_cpu_initialized_map;
 #else
 static inline void xen_smp_init(void) {}
 #endif
 
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
+void __init xen_init_spinlocks(void);
+__cpuinit void xen_init_lock_cpu(int cpu);
+void xen_uninit_lock_cpu(int cpu);
+#else
+static inline void xen_init_spinlocks(void)
+{
+}
+static inline void xen_init_lock_cpu(int cpu)
+{
+}
+static inline void xen_uninit_lock_cpu(int cpu)
+{
+}
+#endif
 
 /* Declare an asm function, along with symbols needed to make it
    inlineable */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/configs/s6105_defconfig linux-libre-2.6.30-gnu1/arch/xtensa/configs/s6105_defconfig
--- linux-libre-2.6.29-gnu1/arch/xtensa/configs/s6105_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/configs/s6105_defconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,529 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc7-s6
+# Tue Mar 10 11:09:26 2009
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_ZONE_DMA=y
+CONFIG_XTENSA=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_NO_IOPORT=y
+CONFIG_HZ=100
+CONFIG_GENERIC_TIME=y
+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_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 is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE 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=16
+# 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+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_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE 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=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
+# CONFIG_MMU is not set
+CONFIG_VARIANT_IRQ_SWITCH=y
+
+#
+# Processor type and features
+#
+# CONFIG_XTENSA_VARIANT_FSF is not set
+# CONFIG_XTENSA_VARIANT_DC232B is not set
+CONFIG_XTENSA_VARIANT_S6000=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+CONFIG_PREEMPT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_XTENSA_CALIBRATE_CCOUNT=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_XTENSA_ISS_NETWORK is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Platform options
+#
+# CONFIG_XTENSA_PLATFORM_ISS is not set
+# CONFIG_XTENSA_PLATFORM_XT2000 is not set
+CONFIG_XTENSA_PLATFORM_S6105=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"
+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
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+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 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_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_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_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_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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# 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 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 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 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=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# 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_RTC 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 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:
+#
+# 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
+
+#
+# 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
+# CONFIG_SOUND 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_CLASS is not set
+# CONFIG_DMADEVICES 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 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_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
+
+#
+# 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_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS 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
+
+#
+# Xtensa initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+# 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 is not set
+# CONFIG_HEADERS_CHECK is not set
+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_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=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_NOMMU_REGIONS=y
+# 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_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
+
+#
+# Tracers
+#
+# CONFIG_PREEMPT_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_DYNAMIC_PRINTK_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 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_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/cacheflush.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/cacheflush.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/cacheflush.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
@@ -65,13 +65,17 @@ extern void __flush_invalidate_dcache_ra
 # define __flush_invalidate_dcache_range(p,s)	__invalidate_dcache_range(p,s)
 #endif
 
-#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
 extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
+#else
+static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
+							unsigned long phys) { }
 #endif
-#if (ICACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE)
 extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
 #else
-# define __invalidate_icache_page_alias(v,p)	do { } while(0)
+static inline void __invalidate_icache_page_alias(unsigned long virt,
+						unsigned long phys) { }
 #endif
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/checksum.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/checksum.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/checksum.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/checksum.h	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(c
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
 		: "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
-		: "1" (iph), "2" (ihl));
+		: "1" (iph), "2" (ihl)
+		: "memory");
 
 	return	csum_fold(sum);
 }
@@ -227,7 +228,8 @@ static __inline__ __sum16 csum_ipv6_magi
 		"1:\t"
 		: "=r" (sum), "=&r" (__dummy)
 		: "r" (saddr), "r" (daddr),
-		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+		: "memory");
 
 	return csum_fold(sum);
 }
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/dma.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/dma.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,8 +44,9 @@
  *	the value desired).
  */
 
+#ifndef MAX_DMA_ADDRESS
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + XCHAL_KIO_SIZE - 1)
-
+#endif
 
 /* Reserve and release a DMA channel */
 extern int request_dma(unsigned int dmanr, const char * device_id);
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/flat.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/flat.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/flat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/flat.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef __ASM_XTENSA_FLAT_H
+#define __ASM_XTENSA_FLAT_H
+
+#define flat_argvp_envp_on_stack()			0
+#define flat_old_ram_flag(flags)			(flags)
+#define flat_reloc_valid(reloc, size)			((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, p)	get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval	)	put_unaligned(val, rp)
+#define flat_get_relocate_addr(rel)			(rel)
+#define flat_set_persistent(relval, p)			0
+
+#endif /* __ASM_XTENSA_FLAT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/ftrace.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/ftrace.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/ftrace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/ftrace.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+/* empty */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/gpio.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/gpio.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for xtensa.
+ *
+ * Stolen from x86, which is derived from the generic GPIO API for powerpc:
+ *
+ * Copyright (c) 2007-2008  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.
+ */
+
+#ifndef _ASM_XTENSA_GPIO_H
+#define _ASM_XTENSA_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ASM_XTENSA_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/io.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/io.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/io.h	2009-06-09 23:05:27.000000000 -0400
@@ -69,21 +69,28 @@ static inline void * phys_to_virt(unsign
 
 static inline void *ioremap(unsigned long offset, unsigned long size)
 {
+#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
 	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
-
 	else
 		BUG();
+#else
+	return (void *)offset;
+#endif
 }
 
 static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
 {
+#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
 	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
 	else
 		BUG();
+#else
+	return (void *)offset;
+#endif
 }
 
 static inline void iounmap(void *addr)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/irq.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/irq.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/irq.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,13 @@
 #include <platform/hardware.h>
 #include <variant/core.h>
 
+#ifdef CONFIG_VARIANT_IRQ_SWITCH
+#include <variant/irq.h>
+#else
+static inline void variant_irq_enable(unsigned int irq) { }
+static inline void variant_irq_disable(unsigned int irq) { }
+#endif
+
 #ifndef PLATFORM_NR_IRQS
 # define PLATFORM_NR_IRQS 0
 #endif
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/mmu_context.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/mmu_context.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/mmu_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/mmu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,16 +13,20 @@
 #ifndef _XTENSA_MMU_CONTEXT_H
 #define _XTENSA_MMU_CONTEXT_H
 
+#ifndef CONFIG_MMU
+#include <asm/nommu_context.h>
+#else
+
 #include <linux/stringify.h>
 #include <linux/sched.h>
 
+#include <variant/core.h>
+
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm-generic/mm_hooks.h>
 
-#define XCHAL_MMU_ASID_BITS	8
-
 #if (XCHAL_HAVE_TLBS != 1)
 # error "Linux must have an MMU!"
 #endif
@@ -133,4 +137,5 @@ static inline void enter_lazy_tlb(struct
 
 }
 
+#endif /* CONFIG_MMU */
 #endif /* _XTENSA_MMU_CONTEXT_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/mmu.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/mmu.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/mmu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/mmu.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,12 @@
 #ifndef _XTENSA_MMU_H
 #define _XTENSA_MMU_H
 
+#ifndef CONFIG_MMU
+#include <asm/nommu.h>
+#else
+
 /* Default "unsigned long" context */
 typedef unsigned long mm_context_t;
 
+#endif /* CONFIG_MMU */
 #endif	/* _XTENSA_MMU_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/nommu_context.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/nommu_context.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/nommu_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/nommu_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	return 0;
+}
+
+static inline void destroy_context(struct mm_struct *mm)
+{
+}
+
+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+				struct task_struct *tsk)
+{
+}
+
+static inline void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
+{
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/nommu.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/nommu.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/nommu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/nommu.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+typedef struct {
+	unsigned long end_brk;
+} mm_context_t;
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/page.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/page.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/page.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/page.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/types.h>
 #include <asm/cache.h>
+#include <platform/hardware.h>
 
 /*
  * Fixed TLB translations in the processor.
@@ -32,8 +33,14 @@
 #define PAGE_SIZE		(__XTENSA_UL_CONST(1) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 
+#ifdef CONFIG_MMU
 #define PAGE_OFFSET		XCHAL_KSEG_CACHED_VADDR
 #define MAX_MEM_PFN		XCHAL_KSEG_SIZE
+#else
+#define PAGE_OFFSET		0
+#define MAX_MEM_PFN		(PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
 #define PGTABLE_START		0x80000000
 
 /*
@@ -150,9 +157,11 @@ extern void copy_user_page(void*, void*,
  * addresses.
  */
 
+#define ARCH_PFN_OFFSET		(PLATFORM_DEFAULT_MEM_START >> PAGE_SHIFT)
+
 #define __pa(x)			((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
-#define pfn_valid(pfn)		((unsigned long)pfn < max_mapnr)
+#define pfn_valid(pfn)		((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
 #ifdef CONFIG_DISCONTIGMEM
 # error CONFIG_DISCONTIGMEM not supported
 #endif
@@ -162,8 +171,9 @@ extern void copy_user_page(void*, void*,
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
+#ifdef CONFIG_MMU
 #define WANT_PAGE_VIRTUAL
-
+#endif
 
 #endif /* __ASSEMBLY__ */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/pgtable.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/pgtable.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/pgtable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/pgtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -183,7 +183,15 @@ extern unsigned long empty_zero_page[102
 
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 
+#ifdef CONFIG_MMU
 extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+extern void paging_init(void);
+extern void pgtable_cache_init(void);
+#else
+# define swapper_pg_dir NULL
+static inline void paging_init(void) { }
+static inline void pgtable_cache_init(void) { }
+#endif
 
 /*
  * The pmd contains the kernel virtual address of the pte page.
@@ -383,8 +391,6 @@ ptep_set_wrprotect(struct mm_struct *mm,
 
 #else
 
-extern void paging_init(void);
-
 #define kern_addr_valid(addr)	(1)
 
 extern  void update_mmu_cache(struct vm_area_struct * vma,
@@ -398,9 +404,6 @@ extern  void update_mmu_cache(struct vm_
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
                 remap_pfn_range(vma, from, pfn, size, prot)
 
-
-extern void pgtable_cache_init(void);
-
 typedef pte_t *pte_addr_t;
 
 #endif /* !defined (__ASSEMBLY__) */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/platform.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/platform.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/platform.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/platform.h	2009-06-09 23:05:27.000000000 -0400
@@ -74,16 +74,5 @@ extern int platform_pcibios_fixup (void)
  */
 extern void platform_calibrate_ccount (void);
 
-/*
- * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
- */
-extern int platform_get_rtc_time(time_t*);
-
-/*
- * platform_set_rtc_time set RTC seconds (returns 0 for no error)
- */
-extern int platform_set_rtc_time(time_t);
-
-
 #endif	/* _XTENSA_PLATFORM_H */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/processor.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/processor.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/processor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <variant/core.h>
 #include <asm/coprocessor.h>
+#include <platform/hardware.h>
 
 #include <linux/compiler.h>
 #include <asm/ptrace.h>
@@ -25,6 +26,8 @@
 # error Linux requires the Xtensa Windowed Registers Option.
 #endif
 
+#define ARCH_SLAB_MINALIGN	XCHAL_DATA_WIDTH
+
 /*
  * User space process size: 1 GB.
  * Windowed call ABI requires caller and callee to be located within the same
@@ -33,7 +36,12 @@
  * the 1 GB requirement applies to the stack as well.
  */
 
+#ifdef CONFIG_MMU
 #define TASK_SIZE	__XTENSA_UL_CONST(0x40000000)
+#else
+#define TASK_SIZE	(PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
 #define STACK_TOP	TASK_SIZE
 #define STACK_TOP_MAX	STACK_TOP
 
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/socket.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/socket.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/socket.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/socket.h	2009-06-09 23:05:27.000000000 -0400
@@ -65,4 +65,7 @@
 
 #define SO_MARK			36
 
+#define SO_TIMESTAMPING		37
+#define SCM_TIMESTAMPING	SO_TIMESTAMPING
+
 #endif	/* _XTENSA_SOCKET_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/swab.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/swab.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/swab.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/swab.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,7 @@
 #ifndef _XTENSA_SWAB_H
 #define _XTENSA_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 #define __SWAB_64_THRU_32__
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/timex.h linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/timex.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/include/asm/timex.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/include/asm/timex.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,9 +39,9 @@
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 extern unsigned long ccount_per_jiffy;
-extern unsigned long ccount_nsec;
+extern unsigned long nsec_per_ccount;
 #define CCOUNT_PER_JIFFY ccount_per_jiffy
-#define NSEC_PER_CCOUNT  ccount_nsec
+#define NSEC_PER_CCOUNT  nsec_per_ccount
 #else
 #define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
 #define NSEC_PER_CCOUNT (1000UL / CONFIG_XTENSA_CPU_CLOCK)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/Kconfig linux-libre-2.6.30-gnu1/arch/xtensa/Kconfig
--- linux-libre-2.6.29-gnu1/arch/xtensa/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -4,16 +4,13 @@
 mainmenu "Linux/Xtensa Kernel Configuration"
 
 config FRAME_POINTER
-	bool
-	default n
+	def_bool n
 
 config ZONE_DMA
-	bool
-	default y
+	def_bool y
 
 config XTENSA
-	bool
-	default y
+	def_bool y
 	select HAVE_IDE
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
@@ -24,28 +21,25 @@ config XTENSA
 	  a home page at <http://xtensa.sourceforge.net/>.
 
 config RWSEM_XCHGADD_ALGORITHM
-	bool
-	default y
+	def_bool y
 
 config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
+	def_bool y
 
 config GENERIC_HWEIGHT
-	bool
-	default y
+	def_bool y
 
 config GENERIC_HARDIRQS
-	bool
-	default y
+	def_bool y
+
+config GENERIC_GPIO
+	def_bool y
 
 config ARCH_HAS_ILOG2_U32
-	bool
-	default n
+	def_bool n
 
 config ARCH_HAS_ILOG2_U64
-	bool
-	default n
+	def_bool n
 
 config NO_IOPORT
 	def_bool y
@@ -54,9 +48,18 @@ config HZ
 	int
 	default 100
 
+config GENERIC_TIME
+	def_bool y
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
+config MMU
+	def_bool n
+
+config VARIANT_IRQ_SWITCH
+	def_bool n
+
 menu "Processor type and features"
 
 choice
@@ -65,38 +68,42 @@ choice
 
 config XTENSA_VARIANT_FSF
 	bool "fsf - default (not generic) configuration"
+	select MMU
 
 config XTENSA_VARIANT_DC232B
 	bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
+	select MMU
 	help
-	This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-endchoice
+	  This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
 
-config MMU
-	bool
-	default y
+config XTENSA_VARIANT_S6000
+	bool "s6000 - Stretch software configurable processor"
+	select VARIANT_IRQ_SWITCH
+	select ARCH_REQUIRE_GPIOLIB
+	select XTENSA_CALIBRATE_CCOUNT
+endchoice
 
 config XTENSA_UNALIGNED_USER
 	bool "Unaligned memory access in use space"
-	---help---
-	   The Xtensa architecture currently does not handle unaligned
-	   memory accesses in hardware but through an exception handler.
-	   Per default, unaligned memory accesses are disabled in user space.
+	help
+	  The Xtensa architecture currently does not handle unaligned
+	  memory accesses in hardware but through an exception handler.
+	  Per default, unaligned memory accesses are disabled in user space.
 
-	   Say Y here to enable unaligned memory access in user space.
+	  Say Y here to enable unaligned memory access in user space.
 
 config PREEMPT
 	bool "Preemptible Kernel"
-	---help---
-           This option reduces the latency of the kernel when reacting to
-           real-time or interactive events by allowing a low priority process to
-           be preempted even if it is in kernel mode executing a system call.
-           Unfortunately the kernel code has some race conditions if both
-           CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
-           currently disabled if you are building an SMP kernel.
+	help
+          This option reduces the latency of the kernel when reacting to
+          real-time or interactive events by allowing a low priority process to
+          be preempted even if it is in kernel mode executing a system call.
+          Unfortunately the kernel code has some race conditions if both
+          CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+          currently disabled if you are building an SMP kernel.
 
-           Say Y here if you are building a kernel for a desktop, embedded
-           or real-time system.  Say N if you are unsure.
+          Say Y here if you are building a kernel for a desktop, embedded
+          or real-time system.  Say N if you are unsure.
 
 config MATH_EMULATION
 	bool "Math emulation"
@@ -105,6 +112,34 @@ config MATH_EMULATION
 
 endmenu
 
+config XTENSA_CALIBRATE_CCOUNT
+	def_bool n
+	help
+	  On some platforms (XT2000, for example), the CPU clock rate can
+	  vary.  The frequency can be determined, however, by measuring
+	  against a well known, fixed frequency, such as an UART oscillator.
+
+config SERIAL_CONSOLE
+	def_bool n
+
+config XTENSA_ISS_NETWORK
+	def_bool n
+
+menu "Bus options"
+
+config PCI
+	bool "PCI support"
+	default y
+	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. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+	  VESA. If you have PCI, say Y, otherwise N.
+
+source "drivers/pci/Kconfig"
+
+endmenu
+
 menu "Platform options"
 
 choice
@@ -113,6 +148,9 @@ choice
 
 config XTENSA_PLATFORM_ISS
 	bool "ISS"
+	select XTENSA_CALIBRATE_CCOUNT
+	select SERIAL_CONSOLE
+	select XTENSA_ISS_NETWORK
 	help
 	  ISS is an acronym for Tensilica's Instruction Set Simulator.
 
@@ -122,24 +160,21 @@ config XTENSA_PLATFORM_XT2000
 	  XT2000 is the name of Tensilica's feature-rich emulation platform.
 	  This hardware is capable of running a full Linux distribution.
 
-endchoice
+config XTENSA_PLATFORM_S6105
+	bool "S6105"
+	select SERIAL_CONSOLE
 
+endchoice
 
-config XTENSA_CALIBRATE_CCOUNT
-	bool "Auto calibration of the CPU clock rate"
-	---help---
-	  On some platforms (XT2000, for example), the CPU clock rate can
-	  vary.  The frequency can be determined, however, by measuring
-	  against a well known, fixed frequency, such as an UART oscillator.
 
 config XTENSA_CPU_CLOCK
 	int "CPU clock rate [MHz]"
 	depends on !XTENSA_CALIBRATE_CCOUNT
-	default "16"
+	default 16
 
 config GENERIC_CALIBRATE_DELAY
 	bool "Auto calibration of the BogoMIPS value"
-	---help---
+	help
 	  The BogoMIPS value can easily be derived from the CPU frequency.
 
 config CMDLINE_BOOL
@@ -156,52 +191,25 @@ config CMDLINE
 	  time by entering them here. As a minimum, you should specify the
 	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
-config SERIAL_CONSOLE
-	bool
-	depends on XTENSA_PLATFORM_ISS
-	default y
-
-config XTENSA_ISS_NETWORK
-	bool
-	depends on XTENSA_PLATFORM_ISS
-	default y
-
 source "mm/Kconfig"
 
-endmenu
-
-menu "Bus options"
-
-config PCI
-	bool "PCI support" if !XTENSA_PLATFORM_ISS
-	depends on !XTENSA_PLATFORM_ISS
-	default y
-	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. Other bus systems are ISA, EISA, MicroChannel (MCA) or
-	  VESA. If you have PCI, say Y, otherwise N.
-
-source "drivers/pci/Kconfig"
-
 config HOTPLUG
-
 	bool "Support for hot-pluggable devices"
-	---help---
-	Say Y here if you want to plug devices into your computer while
-	the system is running, and be able to use them quickly.  In many
-	cases, the devices can likewise be unplugged at any time too.
+	help
+	  Say Y here if you want to plug devices into your computer while
+	  the system is running, and be able to use them quickly.  In many
+	  cases, the devices can likewise be unplugged at any time too.
 
-	One well known example of this is PCMCIA- or PC-cards, credit-card
-	size devices such as network cards, modems or hard drives which are
-	plugged into slots found on all modern laptop computers.  Another
-	example, used on modern desktops as well as laptops, is USB.
+	  One well known example of this is PCMCIA- or PC-cards, credit-card
+	  size devices such as network cards, modems or hard drives which are
+	  plugged into slots found on all modern laptop computers.  Another
+	  example, used on modern desktops as well as laptops, is USB.
 
-	Enable HOTPLUG and build a modular kernel.  Get agent software
-	(from <http://linux-hotplug.sourceforge.net/>) and install it.
-	Then your kernel will automatically call out to a user mode "policy
-	agent" (/sbin/hotplug) to load modules and set up software needed
-	to use devices as you hotplug them.
+	  Enable HOTPLUG and build a modular kernel.  Get agent software
+	  (from <http://linux-hotplug.sourceforge.net/>) and install it.
+	  Then your kernel will automatically call out to a user mode "policy
+	  agent" (/sbin/hotplug) to load modules and set up software needed
+	  to use devices as you hotplug them.
 
 source "drivers/pcmcia/Kconfig"
 
@@ -213,9 +221,8 @@ menu "Executable file formats"
 
 # only elf supported
 config KCORE_ELF
-        bool
+	def_bool y
         depends on PROC_FS
-        default y
         help
           If you enabled support for /proc file system then the file
           /proc/kcore will contain the kernel core image in ELF format. This
@@ -240,7 +247,7 @@ source "fs/Kconfig"
 menu "Xtensa initrd options"
 	depends on BLK_DEV_INITRD
 
-	config EMBEDDED_RAMDISK
+config EMBEDDED_RAMDISK
 	bool "Embed root filesystem ramdisk into the kernel"
 
 config EMBEDDED_RAMDISK_IMAGE
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/entry.S linux-libre-2.6.30-gnu1/arch/xtensa/kernel/entry.S
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/entry.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/entry.S	2009-06-09 23:05:27.000000000 -0400
@@ -1463,6 +1463,7 @@ ENTRY(_spill_registers)
 	callx0	a0		# should not return
 1:	j	1b
 
+#ifdef CONFIG_MMU
 /*
  * We should never get here. Bail out!
  */
@@ -1775,7 +1776,7 @@ ENTRY(fast_store_prohibited)
 	bbsi.l	a2, PS_UM_BIT, 1f
 	j	_kernel_exception
 1:	j	_user_exception
-
+#endif /* CONFIG_MMU */
 
 /*
  * System Calls.
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/head.S linux-libre-2.6.30-gnu1/arch/xtensa/kernel/head.S
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/head.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/head.S	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/page.h>
 #include <asm/cacheasm.h>
 
+#include <linux/init.h>
 #include <linux/linkage.h>
 
 /*
@@ -45,7 +46,7 @@
 	 * instruction.
 	 */
 
-	.section .head.text, "ax"
+	__HEAD
 	.globl _start
 _start:	_j	2f
 	.align	4
@@ -53,7 +54,7 @@ _start:	_j	2f
 2:	l32r	a0, 1b
 	jx	a0
 
-	.text
+	.section .init.text, "ax"
 	.align 4
 _startup:
 
@@ -235,8 +236,9 @@ should_never_return:
  */
 	
 .section ".bss.page_aligned", "w"
+#ifdef CONFIG_MMU
 ENTRY(swapper_pg_dir)
 	.fill	PAGE_SIZE, 1, 0
+#endif
 ENTRY(empty_zero_page)
 	.fill	PAGE_SIZE, 1, 0
-
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/irq.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/irq.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p,
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+			seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
 		seq_printf(p, " %14s", irq_desc[i].chip->typename);
 		seq_printf(p, "  %s", action->name);
@@ -132,6 +132,18 @@ static void xtensa_irq_unmask(unsigned i
 	set_sr (cached_irq_mask, INTENABLE);
 }
 
+static void xtensa_irq_enable(unsigned int irq)
+{
+	variant_irq_enable(irq);
+	xtensa_irq_unmask(irq);
+}
+
+static void xtensa_irq_disable(unsigned int irq)
+{
+	xtensa_irq_mask(irq);
+	variant_irq_disable(irq);
+}
+
 static void xtensa_irq_ack(unsigned int irq)
 {
 	set_sr(1 << irq, INTCLEAR);
@@ -146,6 +158,8 @@ static int xtensa_irq_retrigger(unsigned
 
 static struct irq_chip xtensa_irq_chip = {
 	.name		= "xtensa",
+	.enable		= xtensa_irq_enable,
+	.disable	= xtensa_irq_disable,
 	.mask		= xtensa_irq_mask,
 	.unmask		= xtensa_irq_unmask,
 	.ack		= xtensa_irq_ack,
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/Makefile linux-libre-2.6.30-gnu1/arch/xtensa/kernel/Makefile
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,15 +4,30 @@
 
 extra-y := head.o vmlinux.lds
 
-
 obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
 	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
 	 pci-dma.o init_task.o io.o
 
-## windowspill.o
-
 obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
 
+# In the Xtensa architecture, assembly generates literals which must always
+# precede the L32R instruction with a relative offset less than 256 kB.
+# Therefore, the .text and .literal section must be combined in parenthesis
+# in the linker script, such as: *(.literal .text).
+#
+# We need to post-process the generated vmlinux.lds scripts to convert
+# *(xxx.text) to  *(xxx.literal xxx.text) for the following text sections:
+#   .text .ref.text .*init.text .*exit.text .text.*
+#
+# Replicate rules in scripts/Makefile.build
+
+sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g'	\
+	-e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g'
 
+quiet_cmd__cpp_lds_S = LDS     $@
+      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ $< | sed $(sed-y) >$@
+
+$(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
+	$(call if_changed_dep,_cpp_lds_S)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/platform.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/platform.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,8 +36,6 @@ _F(void, power_off, (void), { while(1);
 _F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
 _F(void, heartbeat, (void), { });
 _F(int,  pcibios_fixup, (void), { return 0; });
-_F(int, get_rtc_time, (time_t* t), { return 0; });
-_F(int, set_rtc_time, (time_t t), { return 0; });
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 _F(void, calibrate_ccount, (void),
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/process.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/process.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/process.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/process.c	2009-06-09 23:05:27.000000000 -0400
@@ -172,7 +172,7 @@ void prepare_to_copy(struct task_struct
  *       childregs.
  */
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused,
                 struct task_struct * p, struct pt_regs * regs)
 {
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/setup.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/setup.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,7 +84,13 @@ sysmem_info_t __initdata sysmem;
 int initrd_is_mapped;
 #endif
 
+#ifdef CONFIG_MMU
 extern void init_mmu(void);
+#else
+static inline void init_mmu(void) { }
+#endif
+
+extern void zones_init(void);
 
 /*
  * Boot parameter parsing.
@@ -286,6 +292,7 @@ void __init setup_arch(char **cmdline_p)
 
 
 	paging_init();
+	zones_init();
 
 #ifdef CONFIG_VT
 # if defined(CONFIG_VGA_CONSOLE)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/time.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/time.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/time.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/time.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,7 @@
 
 #include <linux/errno.h>
 #include <linux/time.h>
-#include <linux/timex.h>
+#include <linux/clocksource.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -25,27 +25,31 @@
 #include <asm/timex.h>
 #include <asm/platform.h>
 
-
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 unsigned long ccount_per_jiffy;		/* per 1/HZ */
 unsigned long nsec_per_ccount;		/* nsec per ccount increment */
 #endif
 
-static long last_rtc_update = 0;
-
-/*
- * Scheduler clock - returns current tim in nanosec units.
- */
-
-unsigned long long sched_clock(void)
+static cycle_t ccount_read(void)
 {
-	return (unsigned long long)jiffies * (1000000000 / HZ);
+	return (cycle_t)get_ccount();
 }
 
+static struct clocksource ccount_clocksource = {
+	.name = "ccount",
+	.rating = 200,
+	.read = ccount_read,
+	.mask = CLOCKSOURCE_MASK(32),
+	/*
+	 * With a shift of 22 the lower limit of the cpu clock is
+	 * 1MHz, where NSEC_PER_CCOUNT is 1000 or a bit less than
+	 * 2^10: Since we have 32 bits and the multiplicator can
+	 * already take up as much as 10 bits, this leaves us with
+	 * remaining upper 22 bits.
+	 */
+	.shift = 22,
+};
+
 static irqreturn_t timer_interrupt(int irq, void *dev_id);
 static struct irqaction timer_irqaction = {
 	.handler =	timer_interrupt,
@@ -55,11 +59,11 @@ static struct irqaction timer_irqaction
 
 void __init time_init(void)
 {
-	time_t sec_o, sec_n = 0;
+	xtime.tv_nsec = 0;
+	xtime.tv_sec = read_persistent_clock();
 
-	/* The platform must provide a function to calibrate the processor
-	 * speed for the CALIBRATE.
-	 */
+	set_normalized_timespec(&wall_to_monotonic,
+		-xtime.tv_sec, -xtime.tv_nsec);
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 	printk("Calibrating CPU frequency ");
@@ -67,19 +71,10 @@ void __init time_init(void)
 	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
 			(int)(ccount_per_jiffy/(10000/HZ))%100);
 #endif
-
-	/* Set time from RTC (if provided) */
-
-	if (platform_get_rtc_time(&sec_o) == 0)
-		while (platform_get_rtc_time(&sec_n))
-			if (sec_o != sec_n)
-				break;
-
-	xtime.tv_nsec = 0;
-	last_rtc_update = xtime.tv_sec = sec_n;
-
-	set_normalized_timespec(&wall_to_monotonic,
-		-xtime.tv_sec, -xtime.tv_nsec);
+	ccount_clocksource.mult =
+		clocksource_hz2mult(CCOUNT_PER_JIFFY * HZ,
+				ccount_clocksource.shift);
+	clocksource_register(&ccount_clocksource);
 
 	/* Initialize the linux timer interrupt. */
 
@@ -87,69 +82,6 @@ void __init time_init(void)
 	set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
 }
 
-
-int do_settimeofday(struct timespec *tv)
-{
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-	unsigned long delta;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	write_seqlock_irq(&xtime_lock);
-
-	/* 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!
-	 */
-
-	delta = CCOUNT_PER_JIFFY;
-	delta += get_ccount() - get_linux_timer();
-	nsec -= delta * NSEC_PER_CCOUNT;
-
-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-	set_normalized_timespec(&xtime, sec, nsec);
-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-	ntp_clear();
-	write_sequnlock_irq(&xtime_lock);
-	return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long volatile sec, usec, delta, seq;
-
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
-		sec = xtime.tv_sec;
-		usec = (xtime.tv_nsec / NSEC_PER_USEC);
-
-		delta = get_linux_timer() - get_ccount();
-
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	usec += (((unsigned long) CCOUNT_PER_JIFFY - delta)
-		 * (unsigned long) NSEC_PER_CCOUNT) / NSEC_PER_USEC;
-
-	for (; usec >= 1000000; sec++, usec -= 1000000)
-		;
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
 /*
  * The timer interrupt is called HZ times per second.
  */
@@ -178,16 +110,6 @@ again:
 		next += CCOUNT_PER_JIFFY;
 		set_linux_timer(next);
 
-		if (ntp_synced() &&
-		    xtime.tv_sec - last_rtc_update >= 659 &&
-		    abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
-
-			if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
-				last_rtc_update = xtime.tv_sec+1;
-			else
-				/* Do it again in 60 s */
-				last_rtc_update += 60;
-		}
 		write_sequnlock(&xtime_lock);
 	}
 
@@ -213,4 +135,3 @@ void __cpuinit calibrate_delay(void)
 	       (loops_per_jiffy/(10000/HZ)) % 100);
 }
 #endif
-
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/traps.c linux-libre-2.6.30-gnu1/arch/xtensa/kernel/traps.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,6 +104,7 @@ static dispatch_init_table_t __initdata
 #endif
 { EXCCAUSE_UNALIGNED,		KRNL,	   fast_unaligned },
 #endif
+#ifdef CONFIG_MMU
 { EXCCAUSE_ITLB_MISS,		0,	   do_page_fault },
 { EXCCAUSE_ITLB_MISS,		USER|KRNL, fast_second_level_miss},
 { EXCCAUSE_ITLB_MULTIHIT,		0,	   do_multihit },
@@ -118,6 +119,7 @@ static dispatch_init_table_t __initdata
 { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	USER|KRNL, fast_store_prohibited },
 { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	0,	   do_page_fault },
 { EXCCAUSE_LOAD_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+#endif /* CONFIG_MMU */
 /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
 #if XTENSA_HAVE_COPROCESSOR(0)
 COPROCESSOR(0),
@@ -367,16 +369,27 @@ void show_regs(struct pt_regs * regs)
 		       regs->syscall);
 }
 
+static __always_inline unsigned long *stack_pointer(struct task_struct *task)
+{
+	unsigned long *sp;
+
+	if (!task || task == current)
+		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
+	else
+		sp = (unsigned long *)task->thread.sp;
+
+	return sp;
+}
+
 void show_trace(struct task_struct *task, unsigned long *sp)
 {
 	unsigned long a0, a1, pc;
 	unsigned long sp_start, sp_end;
 
-	a1 = (unsigned long)sp;
-
-	if (a1 == 0)
-		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
-
+	if (sp)
+		a1 = (unsigned long)sp;
+	else
+		a1 = (unsigned long)stack_pointer(task);
 
 	sp_start = a1 & ~(THREAD_SIZE-1);
 	sp_end = sp_start + THREAD_SIZE;
@@ -418,9 +431,8 @@ void show_stack(struct task_struct *task
 	int i = 0;
 	unsigned long *stack;
 
-	if (sp == 0)
-		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
-
+	if (!sp)
+		sp = stack_pointer(task);
  	stack = sp;
 
 	printk("\nStack: ");
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/vectors.S linux-libre-2.6.30-gnu1/arch/xtensa/kernel/vectors.S
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/vectors.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/vectors.S	2009-06-09 23:05:27.000000000 -0400
@@ -309,6 +309,7 @@ ENTRY(_DoubleExceptionVector)
 	 * All other exceptions are unexpected and thus unrecoverable!
 	 */
 
+#ifdef CONFIG_MMU
 	.extern fast_second_level_miss_double_kernel
 
 .Lksp:	/* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
@@ -319,6 +320,9 @@ ENTRY(_DoubleExceptionVector)
 	bnez	a3, .Lunrecoverable
 1:	movi	a3, fast_second_level_miss_double_kernel
 	jx	a3
+#else
+.equ	.Lksp,	.Lunrecoverable
+#endif
 
 	/* Critical! We can't handle this situation. PANIC! */
 
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/kernel/vmlinux.lds.S linux-libre-2.6.30-gnu1/arch/xtensa/kernel/vmlinux.lds.S
--- linux-libre-2.6.29-gnu1/arch/xtensa/kernel/vmlinux.lds.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/kernel/vmlinux.lds.S	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 #include <asm-generic/vmlinux.lds.h>
 
 #include <variant/core.h>
+#include <platform/hardware.h>
 OUTPUT_ARCH(xtensa)
 ENTRY(_start)
 
@@ -26,7 +27,9 @@ jiffies = jiffies_64 + 4;
 jiffies = jiffies_64;
 #endif
 
+#ifndef KERNELOFFSET
 #define KERNELOFFSET 0xd0001000
+#endif
 
 /* Note: In the following macros, it would be nice to specify only the
    vector name and section kind and construct "sym" and "section" using
@@ -82,9 +85,9 @@ SECTIONS
 
   .text :
   {
-    /* The .head.text section must be the first section! */
-    *(.head.text)
-    *(.literal .text)
+    /* The HEAD_TEXT section must be the first section! */
+    HEAD_TEXT
+    TEXT_TEXT
     VMLINUX_SYMBOL(__sched_text_start) = .;
     *(.sched.literal .sched.text)
     VMLINUX_SYMBOL(__sched_text_end) = .;
@@ -136,8 +139,6 @@ SECTIONS
   __init_begin = .;
   .init.text : {
   	_sinittext = .;
-	*(.init.literal) *(.cpuinit.literal) 
-	*(.devinit.literal) *(.meminit.literal)
 	INIT_TEXT
 	_einittext = .;
   }
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/Makefile linux-libre-2.6.30-gnu1/arch/xtensa/Makefile
--- linux-libre-2.6.29-gnu1/arch/xtensa/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 
 variant-$(CONFIG_XTENSA_VARIANT_FSF)		:= fsf
 variant-$(CONFIG_XTENSA_VARIANT_DC232B)		:= dc232b
+variant-$(CONFIG_XTENSA_VARIANT_S6000)		:= s6000
 variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM)	:= custom
 
 VARIANT = $(variant-y)
@@ -24,6 +25,7 @@ export VARIANT
 
 platform-$(CONFIG_XTENSA_PLATFORM_XT2000)	:= xt2000
 platform-$(CONFIG_XTENSA_PLATFORM_ISS)		:= iss
+platform-$(CONFIG_XTENSA_PLATFORM_S6105)	:= s6105
 
 PLATFORM = $(platform-y)
 export PLATFORM
@@ -62,20 +64,23 @@ ifneq ($(VARIANT),)
   endif
 endif
 
-#
+# Only build variant and/or platform if it includes a Makefile
+
+buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
+buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/)
+
+# Find libgcc.a
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
 head-y		:= arch/xtensa/kernel/head.o
 core-y		+= arch/xtensa/kernel/ arch/xtensa/mm/
-ifneq ($(PLATFORM),)
-core-y		+= arch/xtensa/platforms/$(PLATFORM)/
-endif
+core-y		+= $(buildvar) $(buildplf)
+
 libs-y		+= arch/xtensa/lib/ $(LIBGCC)
 
 boot		:= arch/xtensa/boot
 
-
 all: zImage
 
 bzImage : zImage
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/mm/init.c linux-libre-2.6.30-gnu1/arch/xtensa/mm/init.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/mm/init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/mm/init.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,15 +24,8 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#include <asm/pgtable.h>
 #include <asm/bootparam.h>
-#include <asm/mmu_context.h>
-#include <asm/tlb.h>
 #include <asm/page.h>
-#include <asm/pgalloc.h>
-
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 /* References to section boundaries */
 
@@ -130,7 +123,8 @@ void __init bootmem_init(void)
 
 	/* Find an area to use for the bootmem bitmap. */
 
-	bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
+	bootmap_size = bootmem_bootmap_pages(max_low_pfn - min_low_pfn);
+	bootmap_size <<= PAGE_SHIFT;
 	bootmap_start = ~0;
 
 	for (i=0; i<sysmem.nr_banks; i++)
@@ -145,8 +139,9 @@ void __init bootmem_init(void)
 	/* Reserve the bootmem bitmap area */
 
 	mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
-	bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
 					 bootmap_start >> PAGE_SHIFT,
+					 min_low_pfn,
 					 max_low_pfn);
 
 	/* Add all remaining memory pieces into the bootmem map */
@@ -158,14 +153,14 @@ void __init bootmem_init(void)
 }
 
 
-void __init paging_init(void)
+void __init zones_init(void)
 {
 	unsigned long zones_size[MAX_NR_ZONES];
 	int i;
 
 	/* All pages are DMA-able, so we put them all in the DMA zone. */
 
-	zones_size[ZONE_DMA] = max_low_pfn;
+	zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET;
 	for (i = 1; i < MAX_NR_ZONES; i++)
 		zones_size[i] = 0;
 
@@ -173,40 +168,7 @@ void __init paging_init(void)
 	zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
 #endif
 
-	/* Initialize the kernel's page tables. */
-
-	memset(swapper_pg_dir, 0, PAGE_SIZE);
-
-	free_area_init(zones_size);
-}
-
-/*
- * Flush the mmu and reset associated register to default values.
- */
-
-void __init init_mmu (void)
-{
-	/* Writing zeros to the <t>TLBCFG special registers ensure
-	 * that valid values exist in the register.  For existing
-	 * PGSZID<w> fields, zero selects the first element of the
-	 * page-size array.  For nonexistent PGSZID<w> fields, zero is
-	 * the best value to write.  Also, when changing PGSZID<w>
-	 * fields, the corresponding TLB must be flushed.
-	 */
-	set_itlbcfg_register (0);
-	set_dtlbcfg_register (0);
-	flush_tlb_all ();
-
-	/* Set rasid register to a known value. */
-
-	set_rasid_register (ASID_USER_FIRST);
-
-	/* Set PTEVADDR special register to the start of the page
-	 * table, which is in kernel mappable space (ie. not
-	 * statically mapped).  This register's value is undefined on
-	 * reset.
-	 */
-	set_ptevaddr_register (PGTABLE_START);
+	free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
 }
 
 /*
@@ -218,8 +180,8 @@ void __init mem_init(void)
 	unsigned long codesize, reservedpages, datasize, initsize;
 	unsigned long highmemsize, tmp, ram;
 
-	max_mapnr = num_physpages = max_low_pfn;
-	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+	max_mapnr = num_physpages = max_low_pfn - ARCH_PFN_OFFSET;
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 	highmemsize = 0;
 
 #ifdef CONFIG_HIGHMEM
@@ -229,7 +191,7 @@ void __init mem_init(void)
 	totalram_pages += free_all_bootmem();
 
 	reservedpages = ram = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++) {
+	for (tmp = 0; tmp < max_mapnr; tmp++) {
 		ram++;
 		if (PageReserved(mem_map+tmp))
 			reservedpages++;
@@ -279,23 +241,3 @@ void free_initmem(void)
 	printk("Freeing unused kernel memory: %dk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
-
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void pgd_ctor(void* addr)
-{
-	pte_t* ptep = (pte_t*)addr;
-	int i;
-
-	for (i = 0; i < 1024; i++, ptep++)
-		pte_clear(NULL, 0, ptep);
-
-}
-
-void __init pgtable_cache_init(void)
-{
-	pgtable_cache = kmem_cache_create("pgd",
-			PAGE_SIZE, PAGE_SIZE,
-			SLAB_HWCACHE_ALIGN,
-			pgd_ctor);
-}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/mm/Makefile linux-libre-2.6.30-gnu1/arch/xtensa/mm/Makefile
--- linux-libre-2.6.29-gnu1/arch/xtensa/mm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/mm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,4 +2,5 @@
 # Makefile for the Linux/Xtensa-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o tlb.o misc.o cache.o
+obj-y			:= init.o cache.o misc.o
+obj-$(CONFIG_MMU)	+= fault.o mmu.o tlb.o
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/mm/misc.S linux-libre-2.6.30-gnu1/arch/xtensa/mm/misc.S
--- linux-libre-2.6.29-gnu1/arch/xtensa/mm/misc.S	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/mm/misc.S	2009-06-09 23:05:27.000000000 -0400
@@ -84,6 +84,7 @@ ENTRY(copy_page)
 
 	retw
 
+#ifdef CONFIG_MMU
 /*
  * If we have to deal with cache aliasing, we use temporary memory mappings
  * to ensure that the source and destination pages have the same color as
@@ -311,6 +312,7 @@ ENTRY(__invalidate_icache_page_alias)
 /* End of special treatment in tlb miss exception */
 
 ENTRY(__tlbtemp_mapping_end)
+#endif /* CONFIG_MMU
 
 /*
  * void __invalidate_icache_page(ulong start)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/mm/mmu.c linux-libre-2.6.30-gnu1/arch/xtensa/mm/mmu.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/mm/mmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/mm/mmu.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * xtensa mmu stuff
+ *
+ * Extracted from init.c
+ */
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/cache.h>
+
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+void __init paging_init(void)
+{
+	memset(swapper_pg_dir, 0, PAGE_SIZE);
+}
+
+/*
+ * Flush the mmu and reset associated register to default values.
+ */
+void __init init_mmu(void)
+{
+	/* Writing zeros to the <t>TLBCFG special registers ensure
+	 * that valid values exist in the register.  For existing
+	 * PGSZID<w> fields, zero selects the first element of the
+	 * page-size array.  For nonexistent PGSZID<w> fields, zero is
+	 * the best value to write.  Also, when changing PGSZID<w>
+	 * fields, the corresponding TLB must be flushed.
+	 */
+	set_itlbcfg_register(0);
+	set_dtlbcfg_register(0);
+	flush_tlb_all();
+
+	/* Set rasid register to a known value. */
+
+	set_rasid_register(ASID_USER_FIRST);
+
+	/* Set PTEVADDR special register to the start of the page
+	 * table, which is in kernel mappable space (ie. not
+	 * statically mapped).  This register's value is undefined on
+	 * reset.
+	 */
+	set_ptevaddr_register(PGTABLE_START);
+}
+
+struct kmem_cache *pgtable_cache __read_mostly;
+
+static void pgd_ctor(void *addr)
+{
+	pte_t *ptep = (pte_t *)addr;
+	int i;
+
+	for (i = 0; i < 1024; i++, ptep++)
+		pte_clear(NULL, 0, ptep);
+
+}
+
+void __init pgtable_cache_init(void)
+{
+	pgtable_cache = kmem_cache_create("pgd",
+			PAGE_SIZE, PAGE_SIZE,
+			SLAB_HWCACHE_ALIGN,
+			pgd_ctor);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/iss/console.c linux-libre-2.6.30-gnu1/arch/xtensa/platforms/iss/console.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/iss/console.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/iss/console.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/major.h>
 #include <linux/param.h>
+#include <linux/seq_file.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
 
@@ -176,22 +177,24 @@ static void rs_wait_until_sent(struct tt
 	/* Stub, once again.. */
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	off_t begin = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	*eof = 1;
-
-	if (off >= len + begin)
-		return 0;
+	seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+	return 0;
+}
 
-	*start = page + (off - begin);
-	return ((count < begin + len - off) ? count : begin + len - off);
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
 }
 
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 static struct tty_operations serial_ops = {
 	.open = rs_open,
@@ -203,7 +206,7 @@ static struct tty_operations serial_ops
 	.chars_in_buffer = rs_chars_in_buffer,
 	.hangup = rs_hangup,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc
+	.proc_fops = &rs_proc_fops,
 };
 
 int __init rs_init(void)
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/device.c linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/device.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/device.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/device.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * s6105 platform devices
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <variant/hardware.h>
+
+#define UART_INTNUM		4
+
+static const signed char uart_irq_mappings[] = {
+	S6_INTC_UART(0),
+	S6_INTC_UART(1),
+	-1,
+};
+
+const signed char *platform_irq_mappings[NR_IRQS] = {
+	[UART_INTNUM] = uart_irq_mappings,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase = (void *)S6_REG_UART + 0x0000,
+		.mapbase = S6_REG_UART + 0x0000,
+		.irq = UART_INTNUM,
+		.uartclk = S6_SCLK,
+		.regshift = 2,
+		.iotype = SERIAL_IO_MEM,
+		.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+	},
+	{
+		.membase = (void *)S6_REG_UART + 0x1000,
+		.mapbase = S6_REG_UART + 0x1000,
+		.irq = UART_INTNUM,
+		.uartclk = S6_SCLK,
+		.regshift = 2,
+		.iotype = SERIAL_IO_MEM,
+		.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+	},
+	{ },
+};
+
+static struct platform_device platform_devices[] = {
+	{
+		.name = "serial8250",
+		.id = PLAT8250_DEV_PLATFORM,
+		.dev = {
+			.platform_data = serial_platform_data,
+		},
+	},
+};
+
+static int __init device_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
+		platform_device_register(&platform_devices[i]);
+	return 0;
+}
+arch_initcall_sync(device_init);
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/gpio.h linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/gpio.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+#ifndef __ASM_XTENSA_S6105_GPIO_H
+#define __ASM_XTENSA_S6105_GPIO_H
+
+#define GPIO_BP_TEMP_ALARM	0
+#define GPIO_PB_RESET_IN	1
+#define GPIO_EXP_IRQ		2
+#define GPIO_TRIGGER_IRQ	3
+#define GPIO_RTC_IRQ		4
+#define GPIO_PHY_IRQ		5
+#define GPIO_IMAGER_RESET	6
+#define GPIO_SD_IRQ		7
+#define GPIO_MINI_BOOT_INH	8
+#define GPIO_BOARD_RESET	9
+#define GPIO_EXP_PRESENT	10
+#define GPIO_LED1_NGREEN	12
+#define GPIO_LED1_RED		13
+#define GPIO_LED0_NGREEN	14
+#define GPIO_LED0_NRED		15
+#define GPIO_SPI_CS0		16
+#define GPIO_SPI_CS1		17
+#define GPIO_SPI_CS3		19
+#define GPIO_SPI_CS4		20
+#define GPIO_SD_WP		21
+#define GPIO_BP_RESET		22
+#define GPIO_ALARM_OUT		23
+
+#endif /* __ASM_XTENSA_S6105_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/hardware.h linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/hardware.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,11 @@
+#ifndef __XTENSA_S6105_HARDWARE_H
+#define __XTENSA_S6105_HARDWARE_H
+
+#define PLATFORM_DEFAULT_MEM_START	0x40000000
+#define PLATFORM_DEFAULT_MEM_SIZE	0x08000000
+
+#define MAX_DMA_ADDRESS			0
+
+#define KERNELOFFSET			(PLATFORM_DEFAULT_MEM_START + 0x1000)
+
+#endif /* __XTENSA_S6105_HARDWARE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/serial.h linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/serial.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/include/platform/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/include/platform/serial.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef __ASM_XTENSA_S6105_SERIAL_H
+#define __ASM_XTENSA_S6105_SERIAL_H
+
+#include <variant/hardware.h>
+
+#define BASE_BAUD (S6_SCLK / 16)
+
+#endif /* __ASM_XTENSA_S6105_SERIAL_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/Makefile linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/Makefile
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+# Makefile for the Stretch S6105 eval board
+
+obj-y		:= setup.o device.o
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/setup.c linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/setup.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/s6105/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/s6105/setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,64 @@
+/*
+ * s6105 control routines
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/bootparam.h>
+
+#include <variant/hardware.h>
+#include <variant/gpio.h>
+
+#include <platform/gpio.h>
+
+void platform_halt(void)
+{
+	local_irq_disable();
+	while (1)
+		;
+}
+
+void platform_power_off(void)
+{
+	platform_halt();
+}
+
+void platform_restart(void)
+{
+	platform_halt();
+}
+
+void __init platform_setup(char **cmdline)
+{
+	unsigned long reg;
+
+	reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE);
+	reg &= ~(1 << S6_GREG1_BLOCK_SB);
+	writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE);
+
+	reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+	reg |= 1 << S6_GREG1_BLOCK_SB;
+	writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+
+	printk(KERN_NOTICE "S6105 on Stretch S6000 - "
+		"Copyright (C) 2009 emlix GmbH <info@emlix.com>\n");
+}
+
+void __init platform_init(bp_tag_t *first)
+{
+	s6_gpio_init();
+	gpio_request(GPIO_LED1_NGREEN, "led1_green");
+	gpio_request(GPIO_LED1_RED, "led1_red");
+	gpio_direction_output(GPIO_LED1_NGREEN, 1);
+}
+
+void platform_heartbeat(void)
+{
+	static unsigned int c;
+
+	if (!(++c & 0x4F))
+		gpio_direction_output(GPIO_LED1_RED, !(c & 0x10));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/platforms/xt2000/include/platform/hardware.h linux-libre-2.6.30-gnu1/arch/xtensa/platforms/xt2000/include/platform/hardware.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/platforms/xt2000/include/platform/hardware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/arch/xtensa/platforms/xt2000/include/platform/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,6 @@
 #define _XTENSA_XT2000_HARDWARE_H
 
 #include <variant/core.h>
-#include <asm/io.h>
 
 /* 
  * Memory configuration.
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/delay.c linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/delay.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/delay.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/delay.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,27 @@
+#include <asm/delay.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+#include <variant/hardware.h>
+
+#define LOOPS 10
+void platform_calibrate_ccount(void)
+{
+	u32 uninitialized_var(a);
+	u32 uninitialized_var(u);
+	u32 b;
+	u32 tstamp = S6_REG_GREG1 + S6_GREG1_GLOBAL_TIMER;
+	int i = LOOPS+1;
+	do {
+		u32 t = u;
+		asm volatile(
+		"1:	l32i %0, %2, 0 ;"
+		"	beq %0, %1, 1b ;"
+		: "=&a"(u) : "a"(t), "a"(tstamp));
+		b = xtensa_get_ccount();
+		if (i == LOOPS)
+			a = b;
+	} while (--i >= 0);
+	b -= a;
+	nsec_per_ccount = (LOOPS * 10000) / b;
+	ccount_per_jiffy = b * (100000UL / (LOOPS * HZ));
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/gpio.c linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/gpio.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * s6000 gpio driver
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors:	Oskar Schirmer <os@emlix.com>
+ *		Johannes Weiner <jw@emlix.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <variant/hardware.h>
+
+#define S6_GPIO_DATA		0x000
+#define S6_GPIO_IS		0x404
+#define S6_GPIO_IBE		0x408
+#define S6_GPIO_IEV		0x40C
+#define S6_GPIO_IE		0x410
+#define S6_GPIO_RIS		0x414
+#define S6_GPIO_MIS		0x418
+#define S6_GPIO_IC		0x41C
+#define S6_GPIO_AFSEL		0x420
+#define S6_GPIO_DIR		0x800
+#define S6_GPIO_BANK(nr)	((nr) * 0x1000)
+#define S6_GPIO_MASK(nr)	(4 << (nr))
+#define S6_GPIO_OFFSET(nr) \
+		(S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
+
+static int direction_input(struct gpio_chip *chip, unsigned int off)
+{
+	writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
+	return 0;
+}
+
+static int get(struct gpio_chip *chip, unsigned int off)
+{
+	return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
+{
+	unsigned rel = S6_GPIO_OFFSET(off);
+	writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
+	writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
+	return 0;
+}
+
+static void set(struct gpio_chip *chip, unsigned int off, int val)
+{
+	writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static struct gpio_chip gpiochip = {
+	.owner = THIS_MODULE,
+	.direction_input = direction_input,
+	.get = get,
+	.direction_output = direction_output,
+	.set = set,
+	.base = 0,
+	.ngpio = 24,
+	.can_sleep = 0, /* no blocking io needed */
+	.exported = 0, /* no exporting to userspace */
+};
+
+int s6_gpio_init(void)
+{
+	return gpiochip_add(&gpiochip);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/core.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/core.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/core.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,431 @@
+/*
+ * Xtensa processor core configuration information.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+	    Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ *  Note:  Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ *  configured, and a value of 0 otherwise.  These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+				ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE			0	/* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED		1	/* windowed registers option */
+#define XCHAL_NUM_AREGS			64	/* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2		6	/* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE	8	/* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG		1	/* debug option */
+#define XCHAL_HAVE_DENSITY		1	/* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS		1	/* zero-overhead loops */
+#define XCHAL_HAVE_NSA			1	/* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX		1	/* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT			1	/* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS		1	/* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16		1	/* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32		1	/* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH		1	/* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32		0	/* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R			1	/* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS	1	/* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16		0	/* CONST16 instruction */
+#define XCHAL_HAVE_ADDX			1	/* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES	0	/* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES	0	/* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12		1	/* (obsolete option) */
+#define XCHAL_HAVE_ABS			1	/* ABS instruction */
+/*#define XCHAL_HAVE_POPC		0*/	/* POPC instruction */
+/*#define XCHAL_HAVE_CRC		0*/	/* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC		0	/* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I		0	/* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION		0	/* speculation */
+#define XCHAL_HAVE_FULL_RESET		0	/* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS		1	/* */
+#define XCHAL_NUM_MISC_REGS		4	/* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER		0	/* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID			0	/* processor ID register */
+#define XCHAL_HAVE_THREADPTR		0	/* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS		1	/* boolean registers */
+#define XCHAL_HAVE_CP			1	/* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG			8	/* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16		0	/* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005	0	/* vector floating-point pkg */
+#define XCHAL_HAVE_FP			1	/* floating point pkg */
+#define XCHAL_HAVE_VECTRA1		0	/* Vectra I  pkg */
+#define XCHAL_HAVE_VECTRALX		0	/* Vectra LX pkg */
+#define XCHAL_HAVE_HIFI2		0	/* HiFi2 Audio Engine pkg */
+
+
+/*----------------------------------------------------------------------
+				MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES	8	/* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH		8	/* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH		16	/* data width in bytes */
+/*  In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION	1	/* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION	1	/* unaligned stores cause exc.*/
+
+#define XCHAL_SW_VERSION		701001	/* sw version of this header */
+
+#define XCHAL_CORE_ID			"stretch_bali"	/* alphanum core name
+						   (CoreID) set in the Xtensa
+						   Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID		0x000104B9	/* 22-bit sw build ID */
+
+/*
+ *  These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0		0xC2F3F9FE	/* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1		0x054104B9	/* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME		"LX1.0.2"	/* full version name */
+#define XCHAL_HW_VERSION_MAJOR		2100	/* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR		2	/* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION		210002	/* major*100+minor */
+#define XCHAL_HW_REL_LX1		1
+#define XCHAL_HW_REL_LX1_0		1
+#define XCHAL_HW_REL_LX1_0_2		1
+#define XCHAL_HW_CONFIGID_RELIABLE	1
+/*  If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR	2100	/* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR	2	/* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION		210002	/* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR	2100	/* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR	2	/* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION		210002	/* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+				CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE		32768	/* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE		32768	/* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK	1	/* writeback feature */
+
+
+
+
+/****************************************************************************
+    Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+				CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF			1	/* any outbound PIF present */
+
+/*  If present, cache size in bytes == (ways * 2^(linewidth + setwidth)).  */
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH		9
+#define XCHAL_DCACHE_SETWIDTH		10
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS		4
+#define XCHAL_DCACHE_WAYS		2
+
+/*  Cache features:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE	1
+#define XCHAL_DCACHE_LINE_LOCKABLE	0
+#define XCHAL_ICACHE_ECC_PARITY		0
+#define XCHAL_DCACHE_ECC_PARITY		0
+
+/*  Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits):  */
+#define XCHAL_CA_BITS			4
+
+
+/*----------------------------------------------------------------------
+			INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM		0	/* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM		0	/* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM		0	/* number of core data ROMs */
+#define XCHAL_NUM_DATARAM		1	/* number of core data RAMs */
+#define XCHAL_NUM_URAM			0	/* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI			1	/* number of core XLMI ports */
+
+/*  Data RAM 0:  */
+#define XCHAL_DATARAM0_VADDR		0x3FFF0000
+#define XCHAL_DATARAM0_PADDR		0x3FFF0000
+#define XCHAL_DATARAM0_SIZE		65536
+#define XCHAL_DATARAM0_ECC_PARITY	0
+
+/*  XLMI Port 0:  */
+#define XCHAL_XLMI0_VADDR		0x37F80000
+#define XCHAL_XLMI0_PADDR		0x37F80000
+#define XCHAL_XLMI0_SIZE		262144
+#define XCHAL_XLMI0_ECC_PARITY	0
+
+
+/*----------------------------------------------------------------------
+			INTERRUPTS and TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS		1	/* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS	1	/* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI			1	/* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT		1	/* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS		3	/* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS		27	/* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2	5	/* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS		20	/* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS		4	/* number of interrupt levels
+						   (not including level zero) */
+#define XCHAL_EXCM_LEVEL		1	/* level masked by PS.EXCM */
+	/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL1_MASK		0x01F07FFF
+#define XCHAL_INTLEVEL2_MASK		0x02018000
+#define XCHAL_INTLEVEL3_MASK		0x04060000
+#define XCHAL_INTLEVEL4_MASK		0x00000000
+#define XCHAL_INTLEVEL5_MASK		0x00080000
+#define XCHAL_INTLEVEL6_MASK		0x00000000
+#define XCHAL_INTLEVEL7_MASK		0x00000000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK	0x01F07FFF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK	0x03F1FFFF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK	0x07F7FFFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK	0x07F7FFFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK	0x07FFFFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK	0x07FFFFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK	0x07FFFFFF
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL		1
+#define XCHAL_INT1_LEVEL		1
+#define XCHAL_INT2_LEVEL		1
+#define XCHAL_INT3_LEVEL		1
+#define XCHAL_INT4_LEVEL		1
+#define XCHAL_INT5_LEVEL		1
+#define XCHAL_INT6_LEVEL		1
+#define XCHAL_INT7_LEVEL		1
+#define XCHAL_INT8_LEVEL		1
+#define XCHAL_INT9_LEVEL		1
+#define XCHAL_INT10_LEVEL		1
+#define XCHAL_INT11_LEVEL		1
+#define XCHAL_INT12_LEVEL		1
+#define XCHAL_INT13_LEVEL		1
+#define XCHAL_INT14_LEVEL		1
+#define XCHAL_INT15_LEVEL		2
+#define XCHAL_INT16_LEVEL		2
+#define XCHAL_INT17_LEVEL		3
+#define XCHAL_INT18_LEVEL		3
+#define XCHAL_INT19_LEVEL		5
+#define XCHAL_INT20_LEVEL		1
+#define XCHAL_INT21_LEVEL		1
+#define XCHAL_INT22_LEVEL		1
+#define XCHAL_INT23_LEVEL		1
+#define XCHAL_INT24_LEVEL		1
+#define XCHAL_INT25_LEVEL		2
+#define XCHAL_INT26_LEVEL		3
+#define XCHAL_DEBUGLEVEL		4	/* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT	1	/* OCD external db interrupt */
+#define XCHAL_NMILEVEL			5	/* NMI "level" (for use with
+						   EXCSAVE/EPS/EPC_n, RFI n) */
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT7_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT8_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT11_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT12_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT14_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT15_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT16_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT17_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT18_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT19_TYPE 	XTHAL_INTTYPE_NMI
+#define XCHAL_INT20_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT21_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT22_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT23_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT24_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT25_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT26_TYPE 	XTHAL_INTTYPE_TIMER
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED	0xF8000000
+#define XCHAL_INTTYPE_MASK_SOFTWARE	0x00F00000
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE	0x00000000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL	0x0007FFFF
+#define XCHAL_INTTYPE_MASK_TIMER	0x07000000
+#define XCHAL_INTTYPE_MASK_NMI		0x00080000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR	0x00000000
+
+/*  Interrupt numbers assigned to specific interrupt sources:  */
+#define XCHAL_TIMER0_INTERRUPT		24	/* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT		25	/* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT		26	/* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT		XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT		19	/* non-maskable interrupt */
+
+/*  Interrupt numbers for levels at which only one interrupt is configured:  */
+#define XCHAL_INTLEVEL5_NUM		19
+/*  (There are many interrupts each at level(s) 1, 2, 3.)  */
+
+
+/*
+ *  External interrupt vectors/levels.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL interrupt number:  */
+#define XCHAL_EXTINT0_NUM		0	/* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM		1	/* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM		2	/* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM		3	/* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM		4	/* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM		5	/* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM		6	/* (intlevel 1) */
+#define XCHAL_EXTINT7_NUM		7	/* (intlevel 1) */
+#define XCHAL_EXTINT8_NUM		8	/* (intlevel 1) */
+#define XCHAL_EXTINT9_NUM		9	/* (intlevel 1) */
+#define XCHAL_EXTINT10_NUM		10	/* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM		11	/* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM		12	/* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM		13	/* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM		14	/* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM		15	/* (intlevel 2) */
+#define XCHAL_EXTINT16_NUM		16	/* (intlevel 2) */
+#define XCHAL_EXTINT17_NUM		17	/* (intlevel 3) */
+#define XCHAL_EXTINT18_NUM		18	/* (intlevel 3) */
+#define XCHAL_EXTINT19_NUM		19	/* (intlevel 5) */
+
+
+/*----------------------------------------------------------------------
+			EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION		2	/* Xtensa Exception Architecture
+						   number: 1 == XEA1 (old)
+							   2 == XEA2 (new)
+							   0 == XEAX (extern) */
+#define XCHAL_HAVE_XEA1			0	/* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2			1	/* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX			0	/* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS		1	/* exception option */
+#define XCHAL_HAVE_MEM_ECC_PARITY	0	/* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT	0	/* relocatable vectors */
+#define XCHAL_HAVE_VECBASE		0	/* relocatable vectors */
+
+#define XCHAL_RESET_VECOFS		0x00000000
+#define XCHAL_RESET_VECTOR_VADDR	0x3FFE03D0
+#define XCHAL_RESET_VECTOR_PADDR	0x3FFE03D0
+#define XCHAL_USER_VECOFS		0x00000000
+#define XCHAL_USER_VECTOR_VADDR		0x40000220
+#define XCHAL_USER_VECTOR_PADDR		0x40000220
+#define XCHAL_KERNEL_VECOFS		0x00000000
+#define XCHAL_KERNEL_VECTOR_VADDR	0x40000200
+#define XCHAL_KERNEL_VECTOR_PADDR	0x40000200
+#define XCHAL_DOUBLEEXC_VECOFS		0x00000000
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR	0x400002A0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR	0x400002A0
+#define XCHAL_WINDOW_OF4_VECOFS		0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS		0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS		0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS		0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS	0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS	0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR	0x40000000
+#define XCHAL_WINDOW_VECTORS_PADDR	0x40000000
+#define XCHAL_INTLEVEL2_VECOFS		0x00000000
+#define XCHAL_INTLEVEL2_VECTOR_VADDR	0x40000240
+#define XCHAL_INTLEVEL2_VECTOR_PADDR	0x40000240
+#define XCHAL_INTLEVEL3_VECOFS		0x00000000
+#define XCHAL_INTLEVEL3_VECTOR_VADDR	0x40000260
+#define XCHAL_INTLEVEL3_VECTOR_PADDR	0x40000260
+#define XCHAL_INTLEVEL4_VECOFS		0x00000000
+#define XCHAL_INTLEVEL4_VECTOR_VADDR	0x40000390
+#define XCHAL_INTLEVEL4_VECTOR_PADDR	0x40000390
+#define XCHAL_DEBUG_VECOFS		XCHAL_INTLEVEL4_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR	XCHAL_INTLEVEL4_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR	XCHAL_INTLEVEL4_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS		0x00000000
+#define XCHAL_NMI_VECTOR_VADDR		0x400003B0
+#define XCHAL_NMI_VECTOR_PADDR		0x400003B0
+#define XCHAL_INTLEVEL5_VECOFS		XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL5_VECTOR_VADDR	XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL5_VECTOR_PADDR	XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+				DEBUG
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD			1	/* OnChipDebug option */
+#define XCHAL_NUM_IBREAK		2	/* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK		2	/* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY	1	/* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+				MMU
+  ----------------------------------------------------------------------*/
+
+/*  See core-matmap.h header file for more details.  */
+
+#define XCHAL_HAVE_TLBS			1	/* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY		1	/* one way maps I+D 4GB vaddr */
+#define XCHAL_HAVE_IDENTITY_MAP		1	/* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR		0	/* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR	1	/* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR	0	/* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU		0	/* full MMU (with page table
+						   [autorefill] and protection)
+						   usable for an MMU-based OS */
+/*  If none of the above last 4 are set, it's a custom TLB configuration.  */
+
+#define XCHAL_MMU_ASID_BITS		0	/* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS			1	/* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS		0	/* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/gpio.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/gpio.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _XTENSA_VARIANT_S6000_GPIO_H
+#define _XTENSA_VARIANT_S6000_GPIO_H
+
+extern int s6_gpio_init(void);
+
+#endif /* _XTENSA_VARIANT_S6000_GPIO_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/hardware.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/hardware.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/hardware.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/hardware.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,259 @@
+#ifndef __XTENSA_S6000_HARDWARE_H
+#define __XTENSA_S6000_HARDWARE_H
+
+#define S6_SCLK			1843200
+
+#define S6_MEM_REG              0x20000000
+#define S6_MEM_EFI              0x33F00000
+#define S6_MEM_PCIE_DATARAM1    0x34000000
+#define S6_MEM_XLMI             0x37F80000
+#define S6_MEM_PIF_DATARAM1     0x37FFC000
+#define S6_MEM_GMAC             0x38000000
+#define S6_MEM_I2S              0x3A000000
+#define S6_MEM_EGIB             0x3C000000
+#define S6_MEM_PCIE_CFG         0x3E000000
+#define S6_MEM_PIF_DATARAM      0x3FFE0000
+#define S6_MEM_XLMI_DATARAM     0x3FFF0000
+#define S6_MEM_DDR              0x40000000
+#define S6_MEM_PCIE_APER        0xC0000000
+#define S6_MEM_AUX              0xF0000000
+
+/* Device addresses */
+
+#define S6_REG_SCB              S6_MEM_REG
+#define S6_REG_NB               (S6_REG_SCB + 0x10000)
+#define S6_REG_LMSDMA           (S6_REG_SCB + 0x20000)
+#define S6_REG_NI               (S6_REG_SCB + 0x30000)
+#define S6_REG_NIDMA            (S6_REG_SCB + 0x40000)
+#define S6_REG_NS               (S6_REG_SCB + 0x50000)
+#define S6_REG_DDR              (S6_REG_SCB + 0x60000)
+#define S6_REG_GREG1            (S6_REG_SCB + 0x70000)
+#define S6_REG_DP               (S6_REG_SCB + 0x80000)
+#define S6_REG_DPDMA            (S6_REG_SCB + 0x90000)
+#define S6_REG_EGIB             (S6_REG_SCB + 0xA0000)
+#define S6_REG_PCIE             (S6_REG_SCB + 0xB0000)
+#define S6_REG_I2S              (S6_REG_SCB + 0xC0000)
+#define S6_REG_GMAC             (S6_REG_SCB + 0xD0000)
+#define S6_REG_HIFDMA           (S6_REG_SCB + 0xE0000)
+#define S6_REG_GREG2            (S6_REG_SCB + 0xF0000)
+
+#define S6_REG_APB              S6_REG_SCB
+#define S6_REG_UART             (S6_REG_APB + 0x0000)
+#define S6_REG_INTC             (S6_REG_APB + 0x2000)
+#define S6_REG_SPI              (S6_REG_APB + 0x3000)
+#define S6_REG_I2C              (S6_REG_APB + 0x4000)
+#define S6_REG_GPIO             (S6_REG_APB + 0x8000)
+
+/* Global register block */
+
+#define S6_GREG1_PLL_LOCKCLEAR	0x000
+#define S6_GREG1_PLL_LOCK_SYS		0
+#define S6_GREG1_PLL_LOCK_IO		1
+#define S6_GREG1_PLL_LOCK_AIM		2
+#define S6_GREG1_PLL_LOCK_DP0		3
+#define S6_GREG1_PLL_LOCK_DP2		4
+#define S6_GREG1_PLL_LOCK_DDR		5
+#define S6_GREG1_PLL_LOCKSTAT	0x004
+#define S6_GREG1_PLL_LOCKSTAT_CURLOCK	0
+#define S6_GREG1_PLL_LOCKSTAT_EVERUNLCK	8
+#define S6_GREG1_PLLSEL		0x010
+#define S6_GREG1_PLLSEL_AIM		0
+#define S6_GREG1_PLLSEL_AIM_DDR2		0
+#define S6_GREG1_PLLSEL_AIM_300MHZ		1
+#define S6_GREG1_PLLSEL_AIM_240MHZ		2
+#define S6_GREG1_PLLSEL_AIM_200MHZ		3
+#define S6_GREG1_PLLSEL_AIM_150MHZ		4
+#define S6_GREG1_PLLSEL_AIM_120MHZ		5
+#define S6_GREG1_PLLSEL_AIM_40MHZ		6
+#define S6_GREG1_PLLSEL_AIM_PLLAIMREF		7
+#define S6_GREG1_PLLSEL_AIM_MASK		7
+#define S6_GREG1_PLLSEL_DDR		8
+#define S6_GREG1_PLLSEL_DDR_HS			0
+#define S6_GREG1_PLLSEL_DDR_333MHZ		1
+#define S6_GREG1_PLLSEL_DDR_250MHZ		2
+#define S6_GREG1_PLLSEL_DDR_200MHZ		3
+#define S6_GREG1_PLLSEL_DDR_167MHZ		4
+#define S6_GREG1_PLLSEL_DDR_100MHZ		5
+#define S6_GREG1_PLLSEL_DDR_33MHZ		6
+#define S6_GREG1_PLLSEL_DDR_PLLIOREF		7
+#define S6_GREG1_PLLSEL_DDR_MASK		7
+#define S6_GREG1_PLLSEL_GMAC		16
+#define S6_GREG1_PLLSEL_GMAC_125MHZ		0
+#define S6_GREG1_PLLSEL_GMAC_25MHZ		1
+#define S6_GREG1_PLLSEL_GMAC_2500KHZ		2
+#define S6_GREG1_PLLSEL_GMAC_EXTERN		3
+#define S6_GREG1_PLLSEL_GMAC_MASK		3
+#define S6_GREG1_PLLSEL_GMII		18
+#define S6_GREG1_PLLSEL_GMII_111MHZ		0
+#define S6_GREG1_PLLSEL_GMII_IOREF		1
+#define S6_GREG1_PLLSEL_GMII_NONE		2
+#define S6_GREG1_PLLSEL_GMII_125MHZ		3
+#define S6_GREG1_PLLSEL_GMII_MASK		3
+#define S6_GREG1_SYSUNLOCKCNT	0x020
+#define S6_GREG1_IOUNLOCKCNT	0x024
+#define S6_GREG1_AIMUNLOCKCNT	0x028
+#define S6_GREG1_DP0UNLOCKCNT	0x02C
+#define S6_GREG1_DP2UNLOCKCNT	0x030
+#define S6_GREG1_DDRUNLOCKCNT	0x034
+#define S6_GREG1_CLKBAL0	0x040
+#define S6_GREG1_CLKBAL0_LSGB		0
+#define S6_GREG1_CLKBAL0_LSPX		8
+#define S6_GREG1_CLKBAL0_MEMDO		16
+#define S6_GREG1_CLKBAL0_HSXT1		24
+#define S6_GREG1_CLKBAL1	0x044
+#define S6_GREG1_CLKBAL1_HSISEF		0
+#define S6_GREG1_CLKBAL1_HSNI		8
+#define S6_GREG1_CLKBAL1_HSNS		16
+#define S6_GREG1_CLKBAL1_HSISEFCFG	24
+#define S6_GREG1_CLKBAL2	0x048
+#define S6_GREG1_CLKBAL2_LSNB		0
+#define S6_GREG1_CLKBAL2_LSSB		8
+#define S6_GREG1_CLKBAL2_LSREST		24
+#define S6_GREG1_CLKBAL3	0x04C
+#define S6_GREG1_CLKBAL3_ISEFXAD	0
+#define S6_GREG1_CLKBAL3_ISEFLMS	8
+#define S6_GREG1_CLKBAL3_ISEFISEF	16
+#define S6_GREG1_CLKBAL3_DDRDD		24
+#define S6_GREG1_CLKBAL4	0x050
+#define S6_GREG1_CLKBAL4_DDRDP		0
+#define S6_GREG1_CLKBAL4_DDRDO		8
+#define S6_GREG1_CLKBAL4_DDRNB		16
+#define S6_GREG1_CLKBAL4_DDRLMS		24
+#define S6_GREG1_BLOCKENA	0x100
+#define S6_GREG1_BLOCK_DDR		0
+#define S6_GREG1_BLOCK_DP		1
+#define S6_GREG1_BLOCK_NSNI		2
+#define S6_GREG1_BLOCK_PCIE		3
+#define S6_GREG1_BLOCK_GMAC		4
+#define S6_GREG1_BLOCK_I2S		5
+#define S6_GREG1_BLOCK_EGIB		6
+#define S6_GREG1_BLOCK_SB		7
+#define S6_GREG1_BLOCK_XT1		8
+#define S6_GREG1_CLKGATE	0x104
+#define S6_GREG1_BGATE_AIMNORTH		9
+#define S6_GREG1_BGATE_AIMEAST		10
+#define S6_GREG1_BGATE_AIMWEST		11
+#define S6_GREG1_BGATE_AIMSOUTH		12
+#define S6_GREG1_CHIPRES	0x108
+#define S6_GREG1_CHIPRES_SOFTRES	0
+#define S6_GREG1_CHIPRES_LOSTLOCK	1
+#define S6_GREG1_RESETCAUSE	0x10C
+#define S6_GREG1_RESETCAUSE_RESETN	0
+#define S6_GREG1_RESETCAUSE_GLOBAL	1
+#define S6_GREG1_RESETCAUSE_WDOGTIMER	2
+#define S6_GREG1_RESETCAUSE_SWCHIP	3
+#define S6_GREG1_RESETCAUSE_PLLSYSLOSS	4
+#define S6_GREG1_RESETCAUSE_PCIE	5
+#define S6_GREG1_RESETCAUSE_CREATEDGLOB	6
+#define S6_GREG1_REFCLOCKCNT	0x110
+#define S6_GREG1_RESETTIMER	0x114
+#define S6_GREG1_NMITIMER	0x118
+#define S6_GREG1_GLOBAL_TIMER	0x11C
+#define S6_GREG1_TIMER0		0x180
+#define S6_GREG1_TIMER1		0x184
+#define S6_GREG1_UARTCLOCKSEL	0x204
+#define S6_GREG1_CHIPVERSPACKG	0x208
+#define S6_GREG1_CHIPVERSPACKG_CHIPVID	0
+#define S6_GREG1_CHIPVERSPACKG_PACKSEL	8
+#define S6_GREG1_ONDIETERMCTRL	0x20C
+#define S6_GREG1_ONDIETERMCTRL_WEST	0
+#define S6_GREG1_ONDIETERMCTRL_NORTH	2
+#define S6_GREG1_ONDIETERMCTRL_EAST	4
+#define S6_GREG1_ONDIETERMCTRL_SOUTH	6
+#define S6_GREG1_ONDIETERMCTRL_NONE		0
+#define S6_GREG1_ONDIETERMCTRL_75OHM		2
+#define S6_GREG1_ONDIETERMCTRL_MASK		3
+#define S6_GREG1_BOOT_CFG0	0x210
+#define S6_GREG1_BOOT_CFG0_AIMSTRONG	1
+#define S6_GREG1_BOOT_CFG0_MINIBOOTDL	2
+#define S6_GREG1_BOOT_CFG0_OCDGPIO8SET	5
+#define S6_GREG1_BOOT_CFG0_OCDGPIOENA	6
+#define S6_GREG1_BOOT_CFG0_DOWNSTREAM	7
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV	8
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_300MHZ	1
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_240MHZ	2
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_200MHZ	3
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_150MHZ	4
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_120MHZ	5
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_40MHZ	6
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_MASK	7
+#define S6_GREG1_BOOT_CFG0_BALHSLMS	12
+#define S6_GREG1_BOOT_CFG0_BALHSNB	18
+#define S6_GREG1_BOOT_CFG0_BALHSXAD	24
+#define S6_GREG1_BOOT_CFG1	0x214
+#define S6_GREG1_BOOT_CFG1_PCIE1LANE	1
+#define S6_GREG1_BOOT_CFG1_MPLLPRESCALE	2
+#define S6_GREG1_BOOT_CFG1_MPLLNCY	4
+#define S6_GREG1_BOOT_CFG1_MPLLNCY5	9
+#define S6_GREG1_BOOT_CFG1_BALHSREST	14
+#define S6_GREG1_BOOT_CFG1_BALHSPSMEMS	20
+#define S6_GREG1_BOOT_CFG1_BALLSGI	26
+#define S6_GREG1_BOOT_CFG2	0x218
+#define S6_GREG1_BOOT_CFG2_PEID		0
+#define S6_GREG1_BOOT_CFG3	0x21C
+#define S6_GREG1_DRAMBUSYHOLDOF	0x220
+#define S6_GREG1_DRAMBUSYHOLDOF_XT0	0
+#define S6_GREG1_DRAMBUSYHOLDOF_XT1	4
+#define S6_GREG1_DRAMBUSYHOLDOF_XT_MASK		7
+#define S6_GREG1_PCIEBAR1SIZE	0x224
+#define S6_GREG1_PCIEBAR2SIZE	0x228
+#define S6_GREG1_PCIEVENDOR	0x22C
+#define S6_GREG1_PCIEDEVICE	0x230
+#define S6_GREG1_PCIEREV	0x234
+#define S6_GREG1_PCIECLASS	0x238
+#define S6_GREG1_XT1DCACHEMISS	0x240
+#define S6_GREG1_XT1ICACHEMISS	0x244
+#define S6_GREG1_HWSEMAPHORE(n)	(0x400 + 4 * (n))
+#define S6_GREG1_HWSEMAPHORE_NB		16
+
+/* peripheral interrupt numbers */
+
+#define S6_INTC_GPIO(n)			(n)		/* 0..3 */
+#define S6_INTC_I2C			4
+#define S6_INTC_SPI			5
+#define S6_INTC_NB_ERR			6
+#define S6_INTC_DMA_LMSERR		7
+#define S6_INTC_DMA_LMSLOWWMRK(n)	(8 + (n))	/* 0..11 */
+#define S6_INTC_DMA_LMSPENDCNT(n)	(20 + (n))	/* 0..11 */
+#define S6_INTC_DMA HOSTLOWWMRK(n)	(32 + (n))	/* 0..6 */
+#define S6_INTC_DMA_HOSTPENDCNT(n)	(39 + (n))	/* 0..6 */
+#define S6_INTC_DMA_HOSTERR		46
+#define S6_INTC_UART(n)			(47 + (n))	/* 0..1 */
+#define S6_INTC_XAD			49
+#define S6_INTC_NI_ERR			50
+#define S6_INTC_NI_INFIFOFULL		51
+#define S6_INTC_DMA_NIERR		52
+#define S6_INTC_DMA_NILOWWMRK(n)	(53 + (n))	/* 0..3 */
+#define S6_INTC_DMA_NIPENDCNT(n)	(57 + (n))	/* 0..3 */
+#define S6_INTC_DDR			61
+#define S6_INTC_NS_ERR			62
+#define S6_INTC_EFI_CFGERR		63
+#define S6_INTC_EFI_ISEFTEST		64
+#define S6_INTC_EFI_WRITEERR		65
+#define S6_INTC_NMI_TIMER		66
+#define S6_INTC_PLLLOCK_SYS		67
+#define S6_INTC_PLLLOCK_IO		68
+#define S6_INTC_PLLLOCK_AIM		69
+#define S6_INTC_PLLLOCK_DP0		70
+#define S6_INTC_PLLLOCK_DP2		71
+#define S6_INTC_I2S_ERR			72
+#define S6_INTC_GMAC_STAT		73
+#define S6_INTC_GMAC_ERR		74
+#define S6_INTC_GIB_ERR			75
+#define S6_INTC_PCIE_ERR		76
+#define S6_INTC_PCIE_MSI(n)		(77 + (n))	/* 0..3 */
+#define S6_INTC_PCIE_INTA		81
+#define S6_INTC_PCIE_INTB		82
+#define S6_INTC_PCIE_INTC		83
+#define S6_INTC_PCIE_INTD		84
+#define S6_INTC_SW(n)			(85 + (n))	/* 0..9 */
+#define S6_INTC_SW_ENABLE(n)		(85 + 256 + (n))
+#define S6_INTC_DMA_DP_ERR		95
+#define S6_INTC_DMA_DPLOWWMRK(n)	(96 + (n))	/* 0..3 */
+#define S6_INTC_DMA_DPPENDCNT(n)	(100 + (n))	/* 0..3 */
+#define S6_INTC_DMA_DPTERMCNT(n)	(104 + (n))	/* 0..3 */
+#define S6_INTC_TIMER0			108
+#define S6_INTC_TIMER1			109
+#define S6_INTC_DMA_HOSTTERMCNT(n)	(110 + (n))	/* 0..6 */
+
+#endif /* __XTENSA_S6000_HARDWARE_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/irq.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/irq.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/irq.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef __XTENSA_S6000_IRQ_H
+#define __XTENSA_S6000_IRQ_H
+
+#define NO_IRQ		(-1)
+
+extern void variant_irq_enable(unsigned int irq);
+extern void variant_irq_disable(unsigned int irq);
+
+#endif /* __XTENSA_S6000_IRQ_H */
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/tie-asm.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/tie-asm.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/tie-asm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/tie-asm.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,304 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options.  It is customized to this Xtensa processor configuration.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/*  Selection parameter values for save-area save/restore macros:  */
+/*  Option vs. TIE:  */
+#define XTHAL_SAS_TIE	0x0001	/* custom extension or coprocessor */
+#define XTHAL_SAS_OPT	0x0002	/* optional (and not a coprocessor) */
+/*  Whether used automatically by compiler:  */
+#define XTHAL_SAS_NOCC	0x0004	/* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC	0x0008	/* used by compiler without special opts/code */
+/*  ABI handling across function calls:  */
+#define XTHAL_SAS_CALR	0x0010	/* caller-saved */
+#define XTHAL_SAS_CALE	0x0020	/* callee-saved */
+#define XTHAL_SAS_GLOB	0x0040	/* global across function calls (in thread) */
+/*  Misc  */
+#define XTHAL_SAS_ALL	0xFFFF	/* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+	.macro xchal_ncp_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start	\continue, \ofs
+	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
+	rsr	\at1, BR		// boolean option
+	s32i	\at1, \ptr, .Lxchal_ofs_ + 0
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
+	.endif
+	.endm	// xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+	.macro xchal_ncp_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start	\continue, \ofs
+	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
+	l32i	\at1, \ptr, .Lxchal_ofs_ + 0
+	wsr	\at1, BR		// boolean option
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
+	.endif
+	.endm	// xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS	1
+
+
+
+/* Macro to save the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_store	xchal_cp0_store
+/* #define xchal_cp_FPU_store_a2	xchal_cp0_store a2 a3 a4 a5 a6 */
+	.macro	xchal_cp0_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	rur232	\at1		// FCR
+	s32i	\at1, \ptr, 0
+	rur233	\at1		// FSR
+	s32i	\at1, \ptr, 4
+	SSI f0, \ptr,  8
+	SSI f1, \ptr,  12
+	SSI f2, \ptr,  16
+	SSI f3, \ptr,  20
+	SSI f4, \ptr,  24
+	SSI f5, \ptr,  28
+	SSI f6, \ptr,  32
+	SSI f7, \ptr,  36
+	SSI f8, \ptr,  40
+	SSI f9, \ptr,  44
+	SSI f10, \ptr,  48
+	SSI f11, \ptr,  52
+	SSI f12, \ptr,  56
+	SSI f13, \ptr,  60
+	SSI f14, \ptr,  64
+	SSI f15, \ptr,  68
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 72
+	.endif
+	.endm	// xchal_cp0_store
+
+/* Macro to restore the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_load	xchal_cp0_load
+/* #define xchal_cp_FPU_load_a2	xchal_cp0_load a2 a3 a4 a5 a6 */
+	.macro	xchal_cp0_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	l32i	\at1, \ptr, 0
+	wur232	\at1		// FCR
+	l32i	\at1, \ptr, 4
+	wur233	\at1		// FSR
+	LSI f0, \ptr,  8
+	LSI f1, \ptr,  12
+	LSI f2, \ptr,  16
+	LSI f3, \ptr,  20
+	LSI f4, \ptr,  24
+	LSI f5, \ptr,  28
+	LSI f6, \ptr,  32
+	LSI f7, \ptr,  36
+	LSI f8, \ptr,  40
+	LSI f9, \ptr,  44
+	LSI f10, \ptr,  48
+	LSI f11, \ptr,  52
+	LSI f12, \ptr,  56
+	LSI f13, \ptr,  60
+	LSI f14, \ptr,  64
+	LSI f15, \ptr,  68
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 72
+	.endif
+	.endm	// xchal_cp0_load
+
+#define XCHAL_CP0_NUM_ATMPS	1
+
+/* Macro to save the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_store	xchal_cp6_store
+/* #define xchal_cp_XAD_store_a2	xchal_cp6_store a2 a3 a4 a5 a6 */
+	.macro	xchal_cp6_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	rur0	\at1		// LDCBHI
+	s32i	\at1, \ptr, 0
+	rur1	\at1		// LDCBLO
+	s32i	\at1, \ptr, 4
+	rur2	\at1		// STCBHI
+	s32i	\at1, \ptr, 8
+	rur3	\at1		// STCBLO
+	s32i	\at1, \ptr, 12
+	rur8	\at1		// LDBRBASE
+	s32i	\at1, \ptr, 16
+	rur9	\at1		// LDBROFF
+	s32i	\at1, \ptr, 20
+	rur10	\at1		// LDBRINC
+	s32i	\at1, \ptr, 24
+	rur11	\at1		// STBRBASE
+	s32i	\at1, \ptr, 28
+	rur12	\at1		// STBROFF
+	s32i	\at1, \ptr, 32
+	rur13	\at1		// STBRINC
+	s32i	\at1, \ptr, 36
+	rur24	\at1		// SCRATCH0
+	s32i	\at1, \ptr, 40
+	rur25	\at1		// SCRATCH1
+	s32i	\at1, \ptr, 44
+	rur26	\at1		// SCRATCH2
+	s32i	\at1, \ptr, 48
+	rur27	\at1		// SCRATCH3
+	s32i	\at1, \ptr, 52
+	WRAS128I wra0, \ptr,  64
+	WRAS128I wra1, \ptr,  80
+	WRAS128I wra2, \ptr,  96
+	WRAS128I wra3, \ptr,  112
+	WRAS128I wra4, \ptr,  128
+	WRAS128I wra5, \ptr,  144
+	WRAS128I wra6, \ptr,  160
+	WRAS128I wra7, \ptr,  176
+	WRAS128I wra8, \ptr,  192
+	WRAS128I wra9, \ptr,  208
+	WRAS128I wra10, \ptr,  224
+	WRAS128I wra11, \ptr,  240
+	WRAS128I wra12, \ptr,  256
+	WRAS128I wra13, \ptr,  272
+	WRAS128I wra14, \ptr,  288
+	WRAS128I wra15, \ptr,  304
+	WRBS128I wrb0, \ptr,  320
+	WRBS128I wrb1, \ptr,  336
+	WRBS128I wrb2, \ptr,  352
+	WRBS128I wrb3, \ptr,  368
+	WRBS128I wrb4, \ptr,  384
+	WRBS128I wrb5, \ptr,  400
+	WRBS128I wrb6, \ptr,  416
+	WRBS128I wrb7, \ptr,  432
+	WRBS128I wrb8, \ptr,  448
+	WRBS128I wrb9, \ptr,  464
+	WRBS128I wrb10, \ptr,  480
+	WRBS128I wrb11, \ptr,  496
+	WRBS128I wrb12, \ptr,  512
+	WRBS128I wrb13, \ptr,  528
+	WRBS128I wrb14, \ptr,  544
+	WRBS128I wrb15, \ptr,  560
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 576
+	.endif
+	.endm	// xchal_cp6_store
+
+/* Macro to restore the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_load	xchal_cp6_load
+/* #define xchal_cp_XAD_load_a2	xchal_cp6_load a2 a3 a4 a5 a6 */
+	.macro	xchal_cp6_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	l32i	\at1, \ptr, 0
+	wur0	\at1		// LDCBHI
+	l32i	\at1, \ptr, 4
+	wur1	\at1		// LDCBLO
+	l32i	\at1, \ptr, 8
+	wur2	\at1		// STCBHI
+	l32i	\at1, \ptr, 12
+	wur3	\at1		// STCBLO
+	l32i	\at1, \ptr, 16
+	wur8	\at1		// LDBRBASE
+	l32i	\at1, \ptr, 20
+	wur9	\at1		// LDBROFF
+	l32i	\at1, \ptr, 24
+	wur10	\at1		// LDBRINC
+	l32i	\at1, \ptr, 28
+	wur11	\at1		// STBRBASE
+	l32i	\at1, \ptr, 32
+	wur12	\at1		// STBROFF
+	l32i	\at1, \ptr, 36
+	wur13	\at1		// STBRINC
+	l32i	\at1, \ptr, 40
+	wur24	\at1		// SCRATCH0
+	l32i	\at1, \ptr, 44
+	wur25	\at1		// SCRATCH1
+	l32i	\at1, \ptr, 48
+	wur26	\at1		// SCRATCH2
+	l32i	\at1, \ptr, 52
+	wur27	\at1		// SCRATCH3
+	WRBL128I wrb0, \ptr,  320
+	WRBL128I wrb1, \ptr,  336
+	WRBL128I wrb2, \ptr,  352
+	WRBL128I wrb3, \ptr,  368
+	WRBL128I wrb4, \ptr,  384
+	WRBL128I wrb5, \ptr,  400
+	WRBL128I wrb6, \ptr,  416
+	WRBL128I wrb7, \ptr,  432
+	WRBL128I wrb8, \ptr,  448
+	WRBL128I wrb9, \ptr,  464
+	WRBL128I wrb10, \ptr,  480
+	WRBL128I wrb11, \ptr,  496
+	WRBL128I wrb12, \ptr,  512
+	WRBL128I wrb13, \ptr,  528
+	WRBL128I wrb14, \ptr,  544
+	WRBL128I wrb15, \ptr,  560
+	WRAL128I wra0, \ptr,  64
+	WRAL128I wra1, \ptr,  80
+	WRAL128I wra2, \ptr,  96
+	WRAL128I wra3, \ptr,  112
+	WRAL128I wra4, \ptr,  128
+	WRAL128I wra5, \ptr,  144
+	WRAL128I wra6, \ptr,  160
+	WRAL128I wra7, \ptr,  176
+	WRAL128I wra8, \ptr,  192
+	WRAL128I wra9, \ptr,  208
+	WRAL128I wra10, \ptr,  224
+	WRAL128I wra11, \ptr,  240
+	WRAL128I wra12, \ptr,  256
+	WRAL128I wra13, \ptr,  272
+	WRAL128I wra14, \ptr,  288
+	WRAL128I wra15, \ptr,  304
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 576
+	.endif
+	.endm	// xchal_cp6_load
+
+#define XCHAL_CP6_NUM_ATMPS	1
+#define XCHAL_SA_NUM_ATMPS	1
+
+	/*  Empty macros for unconfigured coprocessors:  */
+	.macro xchal_cp1_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp1_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp2_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp2_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp3_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp3_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp4_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp4_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp5_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp5_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp7_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp7_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/tie.h linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/tie.h
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/include/variant/tie.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/include/variant/tie.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,191 @@
+/*
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality.  It is customized to this
+ * Xtensa processor configuration.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM			2	/* number of coprocessors */
+#define XCHAL_CP_MAX			7	/* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK			0x41	/* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK		0x00	/* bitmask of only port CPs */
+
+/*  Basic parameters of each coprocessor:  */
+#define XCHAL_CP0_NAME			"FPU"
+#define XCHAL_CP0_IDENT			FPU
+#define XCHAL_CP0_SA_SIZE		72	/* size of state save area */
+#define XCHAL_CP0_SA_ALIGN		4	/* min alignment of save area */
+#define XCHAL_CP_ID_FPU			0	/* coprocessor ID (0..7) */
+#define XCHAL_CP6_NAME			"XAD"
+#define XCHAL_CP6_IDENT			XAD
+#define XCHAL_CP6_SA_SIZE		576	/* size of state save area */
+#define XCHAL_CP6_SA_ALIGN		16	/* min alignment of save area */
+#define XCHAL_CP_ID_XAD			6	/* coprocessor ID (0..7) */
+
+/*  Filler info for unassigned coprocessors, to simplify arrays etc:  */
+#define XCHAL_CP1_SA_SIZE		0
+#define XCHAL_CP1_SA_ALIGN		1
+#define XCHAL_CP2_SA_SIZE		0
+#define XCHAL_CP2_SA_ALIGN		1
+#define XCHAL_CP3_SA_SIZE		0
+#define XCHAL_CP3_SA_ALIGN		1
+#define XCHAL_CP4_SA_SIZE		0
+#define XCHAL_CP4_SA_ALIGN		1
+#define XCHAL_CP5_SA_SIZE		0
+#define XCHAL_CP5_SA_ALIGN		1
+#define XCHAL_CP7_SA_SIZE		0
+#define XCHAL_CP7_SA_ALIGN		1
+
+/*  Save area for non-coprocessor optional and custom (TIE) state:  */
+#define XCHAL_NCP_SA_SIZE		4
+#define XCHAL_NCP_SA_ALIGN		4
+
+/*  Total save area for optional and custom state (NCP + CPn):  */
+#define XCHAL_TOTAL_SA_SIZE		672	/* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN		16	/* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE:  caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ *		dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ *	s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ *	ccused = set if used by compiler without special options or code
+ *	abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ *	kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ *	opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ *	name = lowercase reg name (no quotes)
+ *	galign = group byte alignment (power of 2) (galign >= align)
+ *	align = register byte alignment (power of 2)
+ *	asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ *	  (not including any pad bytes required to galign this or next reg)
+ *	dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ *	base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ *	regnum = reg index in regfile, or special/TIE-user reg number
+ *	bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ *	gapsz = intervening bits, if bitsz bits not stored contiguously
+ *	(padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ *	reset = register reset value (or 0 if undefined at reset)
+ *	x = reserved for future use (0 until then)
+ *
+ *  To filter out certain registers, e.g. to expand only the non-global
+ *  registers used by the compiler, you can do something like this:
+ *
+ *  #define XCHAL_SA_REG(s,ccused,p...)	SELCC##ccused(p)
+ *  #define SELCC0(p...)
+ *  #define SELCC1(abikind,p...)	SELAK##abikind(p)
+ *  #define SELAK0(p...)		REG(p)
+ *  #define SELAK1(p...)		REG(p)
+ *  #define SELAK2(p...)
+ *  #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ *		...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM	1
+#define XCHAL_NCP_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,0,1,             br, 4, 4, 4,0x0204,  sr,4  , 16,0,0,0)
+
+#define XCHAL_CP0_SA_NUM	18
+#define XCHAL_CP0_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,1,0,            fcr, 4, 4, 4,0x03E8,  ur,232, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,            fsr, 4, 4, 4,0x03E9,  ur,233, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f0, 4, 4, 4,0x0030,   f,0  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f1, 4, 4, 4,0x0031,   f,1  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f2, 4, 4, 4,0x0032,   f,2  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f3, 4, 4, 4,0x0033,   f,3  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f4, 4, 4, 4,0x0034,   f,4  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f5, 4, 4, 4,0x0035,   f,5  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f6, 4, 4, 4,0x0036,   f,6  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f7, 4, 4, 4,0x0037,   f,7  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f8, 4, 4, 4,0x0038,   f,8  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f9, 4, 4, 4,0x0039,   f,9  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f10, 4, 4, 4,0x003A,   f,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f11, 4, 4, 4,0x003B,   f,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f12, 4, 4, 4,0x003C,   f,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f13, 4, 4, 4,0x003D,   f,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f14, 4, 4, 4,0x003E,   f,14 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f15, 4, 4, 4,0x003F,   f,15 , 32,0,0,0)
+
+#define XCHAL_CP1_SA_NUM	0
+#define XCHAL_CP1_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP2_SA_NUM	0
+#define XCHAL_CP2_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP3_SA_NUM	0
+#define XCHAL_CP3_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP4_SA_NUM	0
+#define XCHAL_CP4_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP5_SA_NUM	0
+#define XCHAL_CP5_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP6_SA_NUM	46
+#define XCHAL_CP6_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,1,0,         ldcbhi,16, 4, 4,0x0300,  ur,0  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         ldcblo, 4, 4, 4,0x0301,  ur,1  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         stcbhi, 4, 4, 4,0x0302,  ur,2  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         stcblo, 4, 4, 4,0x0303,  ur,3  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       ldbrbase, 4, 4, 4,0x0308,  ur,8  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        ldbroff, 4, 4, 4,0x0309,  ur,9  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        ldbrinc, 4, 4, 4,0x030A,  ur,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       stbrbase, 4, 4, 4,0x030B,  ur,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        stbroff, 4, 4, 4,0x030C,  ur,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        stbrinc, 4, 4, 4,0x030D,  ur,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch0, 4, 4, 4,0x0318,  ur,24 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch1, 4, 4, 4,0x0319,  ur,25 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch2, 4, 4, 4,0x031A,  ur,26 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch3, 4, 4, 4,0x031B,  ur,27 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra0,16,16,16,0x1010, wra,0  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra1,16,16,16,0x1011, wra,1  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra2,16,16,16,0x1012, wra,2  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra3,16,16,16,0x1013, wra,3  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra4,16,16,16,0x1014, wra,4  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra5,16,16,16,0x1015, wra,5  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra6,16,16,16,0x1016, wra,6  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra7,16,16,16,0x1017, wra,7  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra8,16,16,16,0x1018, wra,8  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra9,16,16,16,0x1019, wra,9  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra10,16,16,16,0x101A, wra,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra11,16,16,16,0x101B, wra,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra12,16,16,16,0x101C, wra,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra13,16,16,16,0x101D, wra,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra14,16,16,16,0x101E, wra,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra15,16,16,16,0x101F, wra,15 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb0,16,16,16,0x1020, wrb,0  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb1,16,16,16,0x1021, wrb,1  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb2,16,16,16,0x1022, wrb,2  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb3,16,16,16,0x1023, wrb,3  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb4,16,16,16,0x1024, wrb,4  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb5,16,16,16,0x1025, wrb,5  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb6,16,16,16,0x1026, wrb,6  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb7,16,16,16,0x1027, wrb,7  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb8,16,16,16,0x1028, wrb,8  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb9,16,16,16,0x1029, wrb,9  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb10,16,16,16,0x102A, wrb,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb11,16,16,16,0x102B, wrb,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb12,16,16,16,0x102C, wrb,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb13,16,16,16,0x102D, wrb,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb14,16,16,16,0x102E, wrb,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb15,16,16,16,0x102F, wrb,15 ,128,0,0,0)
+
+#define XCHAL_CP7_SA_NUM	0
+#define XCHAL_CP7_SA_LIST(s)	/* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX.  */
+#define XCHAL_OP0_FORMAT_LENGTHS	3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/irq.c linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/irq.c
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * s6000 irq crossbar
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors:	Johannes Weiner <jw@emlix.com>
+ *		Oskar Schirmer <os@emlix.com>
+ */
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <variant/hardware.h>
+
+/* S6_REG_INTC */
+#define INTC_STATUS	0x000
+#define INTC_RAW	0x010
+#define INTC_STATUS_AG	0x100
+#define INTC_CFG(n)	(0x200 + 4 * (n))
+
+/*
+ * The s6000 has a crossbar that multiplexes interrupt output lines
+ * from the peripherals to input lines on the xtensa core.
+ *
+ * We leave the mapping decisions to the platform as it depends on the
+ * actually connected peripherals which distribution makes sense.
+ */
+extern const signed char *platform_irq_mappings[NR_IRQS];
+
+static unsigned long scp_to_intc_enable[] = {
+#define	TO_INTC_ENABLE(n)	(((n) << 1) + 1)
+	TO_INTC_ENABLE(0),
+	TO_INTC_ENABLE(1),
+	TO_INTC_ENABLE(2),
+	TO_INTC_ENABLE(3),
+	TO_INTC_ENABLE(4),
+	TO_INTC_ENABLE(5),
+	TO_INTC_ENABLE(6),
+	TO_INTC_ENABLE(7),
+	TO_INTC_ENABLE(8),
+	TO_INTC_ENABLE(9),
+	TO_INTC_ENABLE(10),
+	TO_INTC_ENABLE(11),
+	TO_INTC_ENABLE(12),
+	-1,
+	-1,
+	TO_INTC_ENABLE(13),
+	-1,
+	TO_INTC_ENABLE(14),
+	-1,
+	TO_INTC_ENABLE(15),
+#undef	TO_INTC_ENABLE
+};
+
+static void irq_set(unsigned int irq, int enable)
+{
+	unsigned long en;
+	const signed char *m = platform_irq_mappings[irq];
+
+	if (!m)
+		return;
+	en = enable ? scp_to_intc_enable[irq] : 0;
+	while (*m >= 0) {
+		writel(en, S6_REG_INTC + INTC_CFG(*m));
+		m++;
+	}
+}
+
+void variant_irq_enable(unsigned int irq)
+{
+	irq_set(irq, 1);
+}
+
+void variant_irq_disable(unsigned int irq)
+{
+	irq_set(irq, 0);
+}
diff -druNp linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/Makefile linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/Makefile
--- linux-libre-2.6.29-gnu1/arch/xtensa/variants/s6000/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/arch/xtensa/variants/s6000/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4 @@
+# s6000 Makefile
+
+obj-y		+= irq.o gpio.o
+obj-$(CONFIG_XTENSA_CALIBRATE_CCOUNT)	+= delay.o
diff -druNp linux-libre-2.6.29-gnu1/block/as-iosched.c linux-libre-2.6.30-gnu1/block/as-iosched.c
--- linux-libre-2.6.29-gnu1/block/as-iosched.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/as-iosched.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,9 +17,6 @@
 #include <linux/rbtree.h>
 #include <linux/interrupt.h>
 
-#define REQ_SYNC	1
-#define REQ_ASYNC	0
-
 /*
  * See Documentation/block/as-iosched.txt
  */
@@ -93,7 +90,7 @@ struct as_data {
 	struct list_head fifo_list[2];
 
 	struct request *next_rq[2];	/* next in sort order */
-	sector_t last_sector[2];	/* last REQ_SYNC & REQ_ASYNC sectors */
+	sector_t last_sector[2];	/* last SYNC & ASYNC sectors */
 
 	unsigned long exit_prob;	/* probability a task will exit while
 					   being waited on */
@@ -109,7 +106,7 @@ struct as_data {
 	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 REQ_SYNC / REQ_ASYNC */
+	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? */
@@ -554,7 +551,7 @@ static void as_update_iohist(struct as_d
 	if (aic == NULL)
 		return;
 
-	if (data_dir == REQ_SYNC) {
+	if (data_dir == BLK_RW_SYNC) {
 		unsigned long in_flight = atomic_read(&aic->nr_queued)
 					+ atomic_read(&aic->nr_dispatched);
 		spin_lock(&aic->lock);
@@ -811,7 +808,7 @@ static void as_update_rq(struct as_data
  */
 static void update_write_batch(struct as_data *ad)
 {
-	unsigned long batch = ad->batch_expire[REQ_ASYNC];
+	unsigned long batch = ad->batch_expire[BLK_RW_ASYNC];
 	long write_time;
 
 	write_time = (jiffies - ad->current_batch_expires) + batch;
@@ -855,7 +852,7 @@ static void as_completed_request(struct
 		kblockd_schedule_work(q, &ad->antic_work);
 		ad->changed_batch = 0;
 
-		if (ad->batch_data_dir == REQ_SYNC)
+		if (ad->batch_data_dir == BLK_RW_SYNC)
 			ad->new_batch = 1;
 	}
 	WARN_ON(ad->nr_dispatched == 0);
@@ -869,7 +866,7 @@ static void as_completed_request(struct
 	if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) {
 		update_write_batch(ad);
 		ad->current_batch_expires = jiffies +
-				ad->batch_expire[REQ_SYNC];
+				ad->batch_expire[BLK_RW_SYNC];
 		ad->new_batch = 0;
 	}
 
@@ -960,7 +957,7 @@ static inline int as_batch_expired(struc
 	if (ad->changed_batch || ad->new_batch)
 		return 0;
 
-	if (ad->batch_data_dir == REQ_SYNC)
+	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);
 
@@ -986,7 +983,7 @@ static void as_move_to_dispatch(struct a
 	 */
 	ad->last_sector[data_dir] = rq->sector + rq->nr_sectors;
 
-	if (data_dir == REQ_SYNC) {
+	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);
@@ -1025,41 +1022,41 @@ static void as_move_to_dispatch(struct a
 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[REQ_SYNC]);
-	const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+	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 REQ_SYNC to avoid
+		 * 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 = REQ_SYNC;
+		ad->batch_data_dir = BLK_RW_SYNC;
 		ad->changed_batch = 0;
 		ad->new_batch = 0;
 
-		while (ad->next_rq[REQ_SYNC]) {
-			as_move_to_dispatch(ad, ad->next_rq[REQ_SYNC]);
+		while (ad->next_rq[BLK_RW_SYNC]) {
+			as_move_to_dispatch(ad, ad->next_rq[BLK_RW_SYNC]);
 			dispatched++;
 		}
-		ad->last_check_fifo[REQ_SYNC] = jiffies;
+		ad->last_check_fifo[BLK_RW_SYNC] = jiffies;
 
-		while (ad->next_rq[REQ_ASYNC]) {
-			as_move_to_dispatch(ad, ad->next_rq[REQ_ASYNC]);
+		while (ad->next_rq[BLK_RW_ASYNC]) {
+			as_move_to_dispatch(ad, ad->next_rq[BLK_RW_ASYNC]);
 			dispatched++;
 		}
-		ad->last_check_fifo[REQ_ASYNC] = jiffies;
+		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 == REQ_ASYNC && !reads) {
+	if (ad->batch_data_dir == BLK_RW_ASYNC && !reads) {
 		if (ad->current_write_count == 0 || !writes)
 			ad->write_batch_idled = 1;
 	}
@@ -1076,8 +1073,8 @@ static int as_dispatch_request(struct re
 		 */
 		rq = ad->next_rq[ad->batch_data_dir];
 
-		if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) {
-			if (as_fifo_expired(ad, REQ_SYNC))
+		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)) {
@@ -1090,7 +1087,7 @@ static int as_dispatch_request(struct re
 			/* we have a "next request" */
 			if (reads && !writes)
 				ad->current_batch_expires =
-					jiffies + ad->batch_expire[REQ_SYNC];
+					jiffies + ad->batch_expire[BLK_RW_SYNC];
 			goto dispatch_request;
 		}
 	}
@@ -1101,20 +1098,20 @@ static int as_dispatch_request(struct re
 	 */
 
 	if (reads) {
-		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[REQ_SYNC]));
+		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[BLK_RW_SYNC]));
 
-		if (writes && ad->batch_data_dir == REQ_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 == REQ_ASYNC) {
+		if (ad->batch_data_dir == BLK_RW_ASYNC) {
 			WARN_ON(ad->new_batch);
 			ad->changed_batch = 1;
 		}
-		ad->batch_data_dir = REQ_SYNC;
-		rq = rq_entry_fifo(ad->fifo_list[REQ_SYNC].next);
+		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;
 	}
@@ -1125,9 +1122,9 @@ static int as_dispatch_request(struct re
 
 	if (writes) {
 dispatch_writes:
-		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[REQ_ASYNC]));
+		BUG_ON(RB_EMPTY_ROOT(&ad->sort_list[BLK_RW_ASYNC]));
 
-		if (ad->batch_data_dir == REQ_SYNC) {
+		if (ad->batch_data_dir == BLK_RW_SYNC) {
 			ad->changed_batch = 1;
 
 			/*
@@ -1137,11 +1134,11 @@ dispatch_writes:
 			 */
 			ad->new_batch = 0;
 		}
-		ad->batch_data_dir = REQ_ASYNC;
+		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[REQ_ASYNC].next);
-		ad->last_check_fifo[REQ_ASYNC] = jiffies;
+		rq = rq_entry_fifo(ad->fifo_list[BLK_RW_ASYNC].next);
+		ad->last_check_fifo[BLK_RW_ASYNC] = jiffies;
 		goto dispatch_request;
 	}
 
@@ -1164,9 +1161,9 @@ fifo_expired:
 		if (ad->nr_dispatched)
 			return 0;
 
-		if (ad->batch_data_dir == REQ_ASYNC)
+		if (ad->batch_data_dir == BLK_RW_ASYNC)
 			ad->current_batch_expires = jiffies +
-					ad->batch_expire[REQ_ASYNC];
+					ad->batch_expire[BLK_RW_ASYNC];
 		else
 			ad->new_batch = 1;
 
@@ -1238,8 +1235,8 @@ static int as_queue_empty(struct request
 {
 	struct as_data *ad = q->elevator->elevator_data;
 
-	return list_empty(&ad->fifo_list[REQ_ASYNC])
-		&& list_empty(&ad->fifo_list[REQ_SYNC]);
+	return list_empty(&ad->fifo_list[BLK_RW_ASYNC])
+		&& list_empty(&ad->fifo_list[BLK_RW_SYNC]);
 }
 
 static int
@@ -1346,8 +1343,8 @@ static void as_exit_queue(struct elevato
 	del_timer_sync(&ad->antic_timer);
 	cancel_work_sync(&ad->antic_work);
 
-	BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC]));
-	BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC]));
+	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);
@@ -1372,18 +1369,18 @@ static void *as_init_queue(struct reques
 	init_timer(&ad->antic_timer);
 	INIT_WORK(&ad->antic_work, as_work_handler);
 
-	INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]);
-	INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
-	ad->sort_list[REQ_SYNC] = RB_ROOT;
-	ad->sort_list[REQ_ASYNC] = RB_ROOT;
-	ad->fifo_expire[REQ_SYNC] = default_read_expire;
-	ad->fifo_expire[REQ_ASYNC] = default_write_expire;
+	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[REQ_SYNC] = default_read_batch_expire;
-	ad->batch_expire[REQ_ASYNC] = default_write_batch_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[REQ_SYNC];
-	ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10;
+	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;
 
@@ -1432,11 +1429,11 @@ static ssize_t __FUNC(struct elevator_qu
 	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[REQ_SYNC]);
-SHOW_FUNCTION(as_write_expire_show, ad->fifo_expire[REQ_ASYNC]);
+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[REQ_SYNC]);
-SHOW_FUNCTION(as_write_batch_expire_show, ad->batch_expire[REQ_ASYNC]);
+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)				\
@@ -1451,13 +1448,14 @@ static ssize_t __FUNC(struct elevator_qu
 	*(__PTR) = msecs_to_jiffies(*(__PTR));				\
 	return ret;							\
 }
-STORE_FUNCTION(as_read_expire_store, &ad->fifo_expire[REQ_SYNC], 0, INT_MAX);
-STORE_FUNCTION(as_write_expire_store, &ad->fifo_expire[REQ_ASYNC], 0, INT_MAX);
+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[REQ_SYNC], 0, INT_MAX);
+			&ad->batch_expire[BLK_RW_SYNC], 0, INT_MAX);
 STORE_FUNCTION(as_write_batch_expire_store,
-			&ad->batch_expire[REQ_ASYNC], 0, INT_MAX);
+			&ad->batch_expire[BLK_RW_ASYNC], 0, INT_MAX);
 #undef STORE_FUNCTION
 
 #define AS_ATTR(name) \
diff -druNp linux-libre-2.6.29-gnu1/block/blk-barrier.c linux-libre-2.6.30-gnu1/block/blk-barrier.c
--- linux-libre-2.6.29-gnu1/block/blk-barrier.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-barrier.c	2009-06-09 23:05:27.000000000 -0400
@@ -319,9 +319,6 @@ int blkdev_issue_flush(struct block_devi
 		return -ENXIO;
 
 	bio = bio_alloc(GFP_KERNEL, 0);
-	if (!bio)
-		return -ENOMEM;
-
 	bio->bi_end_io = bio_end_empty_barrier;
 	bio->bi_private = &wait;
 	bio->bi_bdev = bdev;
diff -druNp linux-libre-2.6.29-gnu1/block/blk-core.c linux-libre-2.6.30-gnu1/block/blk-core.c
--- linux-libre-2.6.29-gnu1/block/blk-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,12 +64,11 @@ static struct workqueue_struct *kblockd_
 
 static void drive_stat_acct(struct request *rq, int new_io)
 {
-	struct gendisk *disk = rq->rq_disk;
 	struct hd_struct *part;
 	int rw = rq_data_dir(rq);
 	int cpu;
 
-	if (!blk_fs_request(rq) || !disk || !blk_do_io_stat(disk->queue))
+	if (!blk_fs_request(rq) || !blk_do_io_stat(rq))
 		return;
 
 	cpu = part_stat_lock();
@@ -132,6 +131,7 @@ void blk_rq_init(struct request_queue *q
 	INIT_HLIST_NODE(&rq->hash);
 	RB_CLEAR_NODE(&rq->rb_node);
 	rq->cmd = rq->__cmd;
+	rq->cmd_len = BLK_MAX_CDB;
 	rq->tag = -1;
 	rq->ref_count = 1;
 }
@@ -484,11 +484,11 @@ static int blk_init_free_list(struct req
 {
 	struct request_list *rl = &q->rq;
 
-	rl->count[READ] = rl->count[WRITE] = 0;
-	rl->starved[READ] = rl->starved[WRITE] = 0;
+	rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
+	rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
 	rl->elvpriv = 0;
-	init_waitqueue_head(&rl->wait[READ]);
-	init_waitqueue_head(&rl->wait[WRITE]);
+	init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
+	init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
 
 	rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
 				mempool_free_slab, request_cachep, q->node);
@@ -603,13 +603,10 @@ blk_init_queue_node(request_fn_proc *rfn
 	q->queue_flags		= QUEUE_FLAG_DEFAULT;
 	q->queue_lock		= lock;
 
-	blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK);
-
+	/*
+	 * This also sets hw/phys segments, boundary and size
+	 */
 	blk_queue_make_request(q, __make_request);
-	blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
-
-	blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
-	blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
 
 	q->sg_reserved_size = INT_MAX;
 
@@ -646,7 +643,7 @@ static inline void blk_free_request(stru
 }
 
 static struct request *
-blk_alloc_request(struct request_queue *q, int rw, int priv, gfp_t gfp_mask)
+blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask)
 {
 	struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
 
@@ -655,7 +652,7 @@ blk_alloc_request(struct request_queue *
 
 	blk_rq_init(q, rq);
 
-	rq->cmd_flags = rw | REQ_ALLOCED;
+	rq->cmd_flags = flags | REQ_ALLOCED;
 
 	if (priv) {
 		if (unlikely(elv_set_request(q, rq, gfp_mask))) {
@@ -702,18 +699,18 @@ static void ioc_set_batching(struct requ
 	ioc->last_waited = jiffies;
 }
 
-static void __freed_request(struct request_queue *q, int rw)
+static void __freed_request(struct request_queue *q, int sync)
 {
 	struct request_list *rl = &q->rq;
 
-	if (rl->count[rw] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, rw);
+	if (rl->count[sync] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, sync);
 
-	if (rl->count[rw] + 1 <= q->nr_requests) {
-		if (waitqueue_active(&rl->wait[rw]))
-			wake_up(&rl->wait[rw]);
+	if (rl->count[sync] + 1 <= q->nr_requests) {
+		if (waitqueue_active(&rl->wait[sync]))
+			wake_up(&rl->wait[sync]);
 
-		blk_clear_queue_full(q, rw);
+		blk_clear_queue_full(q, sync);
 	}
 }
 
@@ -721,21 +718,20 @@ static void __freed_request(struct reque
  * A request has just been released.  Account for it, update the full and
  * congestion status, wake up any waiters.   Called under q->queue_lock.
  */
-static void freed_request(struct request_queue *q, int rw, int priv)
+static void freed_request(struct request_queue *q, int sync, int priv)
 {
 	struct request_list *rl = &q->rq;
 
-	rl->count[rw]--;
+	rl->count[sync]--;
 	if (priv)
 		rl->elvpriv--;
 
-	__freed_request(q, rw);
+	__freed_request(q, sync);
 
-	if (unlikely(rl->starved[rw ^ 1]))
-		__freed_request(q, rw ^ 1);
+	if (unlikely(rl->starved[sync ^ 1]))
+		__freed_request(q, sync ^ 1);
 }
 
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
 /*
  * Get a free request, queue_lock must be held.
  * Returns NULL on failure, with queue_lock held.
@@ -747,15 +743,15 @@ static struct request *get_request(struc
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
 	struct io_context *ioc = NULL;
-	const int rw = rw_flags & 0x01;
+	const bool is_sync = rw_is_sync(rw_flags) != 0;
 	int may_queue, priv;
 
 	may_queue = elv_may_queue(q, rw_flags);
 	if (may_queue == ELV_MQUEUE_NO)
 		goto rq_starved;
 
-	if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
-		if (rl->count[rw]+1 >= q->nr_requests) {
+	if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
+		if (rl->count[is_sync]+1 >= q->nr_requests) {
 			ioc = current_io_context(GFP_ATOMIC, q->node);
 			/*
 			 * The queue will fill after this allocation, so set
@@ -763,9 +759,9 @@ static struct request *get_request(struc
 			 * This process will be allowed to complete a batch of
 			 * requests, others will be blocked.
 			 */
-			if (!blk_queue_full(q, rw)) {
+			if (!blk_queue_full(q, is_sync)) {
 				ioc_set_batching(q, ioc);
-				blk_set_queue_full(q, rw);
+				blk_set_queue_full(q, is_sync);
 			} else {
 				if (may_queue != ELV_MQUEUE_MUST
 						&& !ioc_batching(q, ioc)) {
@@ -778,7 +774,7 @@ static struct request *get_request(struc
 				}
 			}
 		}
-		blk_set_queue_congested(q, rw);
+		blk_set_queue_congested(q, is_sync);
 	}
 
 	/*
@@ -786,16 +782,18 @@ static struct request *get_request(struc
 	 * limit of requests, otherwise we could have thousands of requests
 	 * allocated with any setting of ->nr_requests
 	 */
-	if (rl->count[rw] >= (3 * q->nr_requests / 2))
+	if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
 		goto out;
 
-	rl->count[rw]++;
-	rl->starved[rw] = 0;
+	rl->count[is_sync]++;
+	rl->starved[is_sync] = 0;
 
 	priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
 	if (priv)
 		rl->elvpriv++;
 
+	if (blk_queue_io_stat(q))
+		rw_flags |= REQ_IO_STAT;
 	spin_unlock_irq(q->queue_lock);
 
 	rq = blk_alloc_request(q, rw_flags, priv, gfp_mask);
@@ -808,7 +806,7 @@ static struct request *get_request(struc
 		 * wait queue, but this is pretty rare.
 		 */
 		spin_lock_irq(q->queue_lock);
-		freed_request(q, rw, priv);
+		freed_request(q, is_sync, priv);
 
 		/*
 		 * in the very unlikely event that allocation failed and no
@@ -818,8 +816,8 @@ static struct request *get_request(struc
 		 * rq mempool into READ and WRITE
 		 */
 rq_starved:
-		if (unlikely(rl->count[rw] == 0))
-			rl->starved[rw] = 1;
+		if (unlikely(rl->count[is_sync] == 0))
+			rl->starved[is_sync] = 1;
 
 		goto out;
 	}
@@ -833,7 +831,7 @@ rq_starved:
 	if (ioc_batching(q, ioc))
 		ioc->nr_batch_requests--;
 
-	trace_block_getrq(q, bio, rw);
+	trace_block_getrq(q, bio, rw_flags & 1);
 out:
 	return rq;
 }
@@ -847,7 +845,7 @@ out:
 static struct request *get_request_wait(struct request_queue *q, int rw_flags,
 					struct bio *bio)
 {
-	const int rw = rw_flags & 0x01;
+	const bool is_sync = rw_is_sync(rw_flags) != 0;
 	struct request *rq;
 
 	rq = get_request(q, rw_flags, bio, GFP_NOIO);
@@ -856,10 +854,10 @@ static struct request *get_request_wait(
 		struct io_context *ioc;
 		struct request_list *rl = &q->rq;
 
-		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+		prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
 				TASK_UNINTERRUPTIBLE);
 
-		trace_block_sleeprq(q, bio, rw);
+		trace_block_sleeprq(q, bio, rw_flags & 1);
 
 		__generic_unplug_device(q);
 		spin_unlock_irq(q->queue_lock);
@@ -875,7 +873,7 @@ static struct request *get_request_wait(
 		ioc_set_batching(q, ioc);
 
 		spin_lock_irq(q->queue_lock);
-		finish_wait(&rl->wait[rw], &wait);
+		finish_wait(&rl->wait[is_sync], &wait);
 
 		rq = get_request(q, rw_flags, bio, GFP_NOIO);
 	};
@@ -1066,19 +1064,22 @@ void __blk_put_request(struct request_qu
 
 	elv_completed_request(q, req);
 
+	/* this is a bio leak */
+	WARN_ON(req->bio != NULL);
+
 	/*
 	 * Request may not have originated from ll_rw_blk. if not,
 	 * it didn't come out of our reserved rq pools
 	 */
 	if (req->cmd_flags & REQ_ALLOCED) {
-		int rw = rq_data_dir(req);
+		int is_sync = rq_is_sync(req) != 0;
 		int priv = req->cmd_flags & REQ_ELVPRIV;
 
 		BUG_ON(!list_empty(&req->queuelist));
 		BUG_ON(!hlist_unhashed(&req->hash));
 
 		blk_free_request(q, req);
-		freed_request(q, rw, priv);
+		freed_request(q, is_sync, priv);
 	}
 }
 EXPORT_SYMBOL_GPL(__blk_put_request);
@@ -1125,10 +1126,10 @@ void init_request_from_bio(struct reques
 
 	if (bio_sync(bio))
 		req->cmd_flags |= REQ_RW_SYNC;
-	if (bio_unplug(bio))
-		req->cmd_flags |= REQ_UNPLUG;
 	if (bio_rw_meta(bio))
 		req->cmd_flags |= REQ_RW_META;
+	if (bio_noidle(bio))
+		req->cmd_flags |= REQ_NOIDLE;
 
 	req->errors = 0;
 	req->hard_sector = req->sector = bio->bi_sector;
@@ -1137,6 +1138,15 @@ void init_request_from_bio(struct reques
 	blk_rq_bio_prep(req->q, req, bio);
 }
 
+/*
+ * Only disabling plugging for non-rotational devices if it does tagging
+ * as well, otherwise we do need the proper merging
+ */
+static inline bool queue_should_plug(struct request_queue *q)
+{
+	return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
+}
+
 static int __make_request(struct request_queue *q, struct bio *bio)
 {
 	struct request *req;
@@ -1243,11 +1253,11 @@ get_rq:
 	if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
 	    bio_flagged(bio, BIO_CPU_AFFINE))
 		req->cpu = blk_cpu_to_group(smp_processor_id());
-	if (!blk_queue_nonrot(q) && elv_queue_empty(q))
+	if (queue_should_plug(q) && elv_queue_empty(q))
 		blk_plug_device(q);
 	add_request(q, req);
 out:
-	if (unplug || blk_queue_nonrot(q))
+	if (unplug || !queue_should_plug(q))
 		__generic_unplug_device(q);
 	spin_unlock_irq(q->queue_lock);
 	return 0;
@@ -1665,9 +1675,7 @@ EXPORT_SYMBOL(blkdev_dequeue_request);
 
 static void blk_account_io_completion(struct request *req, unsigned int bytes)
 {
-	struct gendisk *disk = req->rq_disk;
-
-	if (!disk || !blk_do_io_stat(disk->queue))
+	if (!blk_do_io_stat(req))
 		return;
 
 	if (blk_fs_request(req)) {
@@ -1684,9 +1692,7 @@ static void blk_account_io_completion(st
 
 static void blk_account_io_done(struct request *req)
 {
-	struct gendisk *disk = req->rq_disk;
-
-	if (!disk || !blk_do_io_stat(disk->queue))
+	if (!blk_do_io_stat(req))
 		return;
 
 	/*
@@ -1701,7 +1707,7 @@ static void blk_account_io_done(struct r
 		int cpu;
 
 		cpu = part_stat_lock();
-		part = disk_map_sector_rcu(disk, req->sector);
+		part = disk_map_sector_rcu(req->rq_disk, req->sector);
 
 		part_stat_inc(cpu, part, ios[rw]);
 		part_stat_add(cpu, part, ticks[rw], duration);
@@ -1762,10 +1768,10 @@ static int __end_that_request_first(stru
 		} else {
 			int idx = bio->bi_idx + next_idx;
 
-			if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
+			if (unlikely(idx >= bio->bi_vcnt)) {
 				blk_dump_rq_flags(req, "__end_that");
 				printk(KERN_ERR "%s: bio idx %d >= vcnt %d\n",
-				       __func__, bio->bi_idx, bio->bi_vcnt);
+				       __func__, idx, bio->bi_vcnt);
 				break;
 			}
 
diff -druNp linux-libre-2.6.29-gnu1/block/blk.h linux-libre-2.6.30-gnu1/block/blk.h
--- linux-libre-2.6.29-gnu1/block/blk.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk.h	2009-06-09 23:05:27.000000000 -0400
@@ -70,6 +70,10 @@ void blk_queue_congestion_threshold(stru
 
 int blk_dev_init(void);
 
+void elv_quiesce_start(struct request_queue *q);
+void elv_quiesce_end(struct request_queue *q);
+
+
 /*
  * Return the threshold (number of used requests) at which the queue is
  * considered to be congested.  It include a little hysteresis to keep the
@@ -102,18 +106,15 @@ static inline int blk_cpu_to_group(int c
 	const struct cpumask *mask = cpu_coregroup_mask(cpu);
 	return cpumask_first(mask);
 #elif defined(CONFIG_SCHED_SMT)
-	return first_cpu(per_cpu(cpu_sibling_map, cpu));
+	return cpumask_first(topology_thread_cpumask(cpu));
 #else
 	return cpu;
 #endif
 }
 
-static inline int blk_do_io_stat(struct request_queue *q)
+static inline int blk_do_io_stat(struct request *rq)
 {
-	if (q)
-		return blk_queue_io_stat(q);
-
-	return 0;
+	return rq->rq_disk && blk_rq_io_stat(rq);
 }
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/block/blk-merge.c linux-libre-2.6.30-gnu1/block/blk-merge.c
--- linux-libre-2.6.29-gnu1/block/blk-merge.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-merge.c	2009-06-09 23:05:27.000000000 -0400
@@ -338,6 +338,22 @@ static int ll_merge_requests_fn(struct r
 	return 1;
 }
 
+static void blk_account_io_merge(struct request *req)
+{
+	if (blk_do_io_stat(req)) {
+		struct hd_struct *part;
+		int cpu;
+
+		cpu = part_stat_lock();
+		part = disk_map_sector_rcu(req->rq_disk, req->sector);
+
+		part_round_stats(cpu, part);
+		part_dec_in_flight(part);
+
+		part_stat_unlock();
+	}
+}
+
 /*
  * Has to be called with the request spinlock acquired
  */
@@ -386,23 +402,17 @@ static int attempt_merge(struct request_
 
 	elv_merge_requests(q, req, next);
 
-	if (req->rq_disk) {
-		struct hd_struct *part;
-		int cpu;
-
-		cpu = part_stat_lock();
-		part = disk_map_sector_rcu(req->rq_disk, req->sector);
-
-		part_round_stats(cpu, part);
-		part_dec_in_flight(part);
-
-		part_stat_unlock();
-	}
+	/*
+	 * 'next' is going away, so update stats accordingly
+	 */
+	blk_account_io_merge(next);
 
 	req->ioprio = ioprio_best(req->ioprio, next->ioprio);
 	if (blk_rq_cpu_valid(next))
 		req->cpu = next->cpu;
 
+	/* owner-ship of bio passed from next to req */
+	next->bio = NULL;
 	__blk_put_request(q, next);
 	return 1;
 }
diff -druNp linux-libre-2.6.29-gnu1/block/blk-settings.c linux-libre-2.6.30-gnu1/block/blk-settings.c
--- linux-libre-2.6.29-gnu1/block/blk-settings.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-settings.c	2009-06-09 23:05:27.000000000 -0400
@@ -156,26 +156,28 @@ EXPORT_SYMBOL(blk_queue_make_request);
 
 /**
  * blk_queue_bounce_limit - set bounce buffer limit for queue
- * @q:  the request queue for the device
- * @dma_addr:   bus address limit
+ * @q: the request queue for the device
+ * @dma_mask: the maximum address the device can handle
  *
  * Description:
  *    Different hardware can have different requirements as to what pages
  *    it can do I/O directly to. A low level driver can call
  *    blk_queue_bounce_limit to have lower memory pages allocated as bounce
- *    buffers for doing I/O to pages residing above @dma_addr.
+ *    buffers for doing I/O to pages residing above @dma_mask.
  **/
-void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr)
+void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
 {
-	unsigned long b_pfn = dma_addr >> PAGE_SHIFT;
+	unsigned long b_pfn = dma_mask >> PAGE_SHIFT;
 	int dma = 0;
 
 	q->bounce_gfp = GFP_NOIO;
 #if BITS_PER_LONG == 64
-	/* Assume anything <= 4GB can be handled by IOMMU.
-	   Actually some IOMMUs can handle everything, but I don't
-	   know of a way to test this here. */
-	if (b_pfn < (min_t(u64, 0x100000000UL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
+	/*
+	 * Assume anything <= 4GB can be handled by IOMMU.  Actually
+	 * some IOMMUs can handle everything, but I don't know of a
+	 * way to test this here.
+	 */
+	if (b_pfn < (min_t(u64, 0xffffffffUL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
 		dma = 1;
 	q->bounce_pfn = max_low_pfn;
 #else
@@ -431,7 +433,7 @@ EXPORT_SYMBOL(blk_queue_segment_boundary
  *
  * description:
  *    set required memory and length alignment for direct dma transactions.
- *    this is used when buiding direct io requests for the queue.
+ *    this is used when building direct io requests for the queue.
  *
  **/
 void blk_queue_dma_alignment(struct request_queue *q, int mask)
diff -druNp linux-libre-2.6.29-gnu1/block/blk-softirq.c linux-libre-2.6.30-gnu1/block/blk-softirq.c
--- linux-libre-2.6.29-gnu1/block/blk-softirq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-softirq.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,7 @@ static int raise_blk_irq(int cpu, struct
 		data->info = rq;
 		data->flags = 0;
 
-		__smp_call_function_single(cpu, data);
+		__smp_call_function_single(cpu, data, 0);
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/block/blk-sysfs.c linux-libre-2.6.30-gnu1/block/blk-sysfs.c
--- linux-libre-2.6.29-gnu1/block/blk-sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,28 +48,28 @@ queue_requests_store(struct request_queu
 	q->nr_requests = nr;
 	blk_queue_congestion_threshold(q);
 
-	if (rl->count[READ] >= queue_congestion_on_threshold(q))
-		blk_set_queue_congested(q, READ);
-	else if (rl->count[READ] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, READ);
+	if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q))
+		blk_set_queue_congested(q, BLK_RW_SYNC);
+	else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, BLK_RW_SYNC);
 
-	if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
-		blk_set_queue_congested(q, WRITE);
-	else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, WRITE);
+	if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q))
+		blk_set_queue_congested(q, BLK_RW_ASYNC);
+	else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, BLK_RW_ASYNC);
 
-	if (rl->count[READ] >= q->nr_requests) {
-		blk_set_queue_full(q, READ);
-	} else if (rl->count[READ]+1 <= q->nr_requests) {
-		blk_clear_queue_full(q, READ);
-		wake_up(&rl->wait[READ]);
+	if (rl->count[BLK_RW_SYNC] >= q->nr_requests) {
+		blk_set_queue_full(q, BLK_RW_SYNC);
+	} else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, BLK_RW_SYNC);
+		wake_up(&rl->wait[BLK_RW_SYNC]);
 	}
 
-	if (rl->count[WRITE] >= q->nr_requests) {
-		blk_set_queue_full(q, WRITE);
-	} else if (rl->count[WRITE]+1 <= q->nr_requests) {
-		blk_clear_queue_full(q, WRITE);
-		wake_up(&rl->wait[WRITE]);
+	if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) {
+		blk_set_queue_full(q, BLK_RW_ASYNC);
+	} else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, BLK_RW_ASYNC);
+		wake_up(&rl->wait[BLK_RW_ASYNC]);
 	}
 	spin_unlock_irq(q->queue_lock);
 	return ret;
diff -druNp linux-libre-2.6.29-gnu1/block/blk-timeout.c linux-libre-2.6.30-gnu1/block/blk-timeout.c
--- linux-libre-2.6.29-gnu1/block/blk-timeout.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blk-timeout.c	2009-06-09 23:05:27.000000000 -0400
@@ -211,6 +211,12 @@ void blk_abort_queue(struct request_queu
 	struct request *rq, *tmp;
 	LIST_HEAD(list);
 
+	/*
+	 * Not a request based block device, nothing to abort
+	 */
+	if (!q->request_fn)
+		return;
+
 	spin_lock_irqsave(q->queue_lock, flags);
 
 	elv_abort_queue(q);
@@ -224,6 +230,13 @@ void blk_abort_queue(struct request_queu
 	list_for_each_entry_safe(rq, tmp, &list, timeout_list)
 		blk_abort_request(rq);
 
+	/*
+	 * Occasionally, blk_abort_request() will return without
+	 * deleting the element from the list. Make sure we add those back
+	 * instead of leaving them on the local stack list.
+	 */
+	list_splice(&list, &q->timeout_list);
+
 	spin_unlock_irqrestore(q->queue_lock, flags);
 
 }
diff -druNp linux-libre-2.6.29-gnu1/block/blktrace.c linux-libre-2.6.30-gnu1/block/blktrace.c
--- linux-libre-2.6.29-gnu1/block/blktrace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/blktrace.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
- *
- * This program is free software; you can 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/blkdev.h>
-#include <linux/blktrace_api.h>
-#include <linux/percpu.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <linux/time.h>
-#include <trace/block.h>
-#include <asm/uaccess.h>
-
-static unsigned int blktrace_seq __read_mostly = 1;
-
-/* Global reference count of probes */
-static DEFINE_MUTEX(blk_probe_mutex);
-static atomic_t blk_probes_ref = ATOMIC_INIT(0);
-
-static int blk_register_tracepoints(void);
-static void blk_unregister_tracepoints(void);
-
-/*
- * Send out a notify message.
- */
-static void trace_note(struct blk_trace *bt, pid_t pid, int action,
-		       const void *data, size_t len)
-{
-	struct blk_io_trace *t;
-
-	t = relay_reserve(bt->rchan, sizeof(*t) + len);
-	if (t) {
-		const int cpu = smp_processor_id();
-
-		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
-		t->time = ktime_to_ns(ktime_get());
-		t->device = bt->dev;
-		t->action = action;
-		t->pid = pid;
-		t->cpu = cpu;
-		t->pdu_len = len;
-		memcpy((void *) t + sizeof(*t), data, len);
-	}
-}
-
-/*
- * Send out a notify for this process, if we haven't done so since a trace
- * started
- */
-static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk)
-{
-	tsk->btrace_seq = blktrace_seq;
-	trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm, sizeof(tsk->comm));
-}
-
-static void trace_note_time(struct blk_trace *bt)
-{
-	struct timespec now;
-	unsigned long flags;
-	u32 words[2];
-
-	getnstimeofday(&now);
-	words[0] = now.tv_sec;
-	words[1] = now.tv_nsec;
-
-	local_irq_save(flags);
-	trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words));
-	local_irq_restore(flags);
-}
-
-void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
-{
-	int n;
-	va_list args;
-	unsigned long flags;
-	char *buf;
-
-	local_irq_save(flags);
-	buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
-	va_start(args, fmt);
-	n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
-	va_end(args);
-
-	trace_note(bt, 0, BLK_TN_MESSAGE, buf, n);
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(__trace_note_message);
-
-static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
-			 pid_t pid)
-{
-	if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
-		return 1;
-	if (sector < bt->start_lba || sector > bt->end_lba)
-		return 1;
-	if (bt->pid && pid != bt->pid)
-		return 1;
-
-	return 0;
-}
-
-/*
- * Data direction bit lookup
- */
-static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) };
-
-/* The ilog2() calls fall out because they're constant */
-#define MASK_TC_BIT(rw, __name) ( (rw & (1 << BIO_RW_ ## __name)) << \
-	  (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name) )
-
-/*
- * The worker for the various blk_add_trace*() types. Fills out a
- * blk_io_trace structure and places it in a per-cpu subbuffer.
- */
-static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
-		     int rw, u32 what, int error, int pdu_len, void *pdu_data)
-{
-	struct task_struct *tsk = current;
-	struct blk_io_trace *t;
-	unsigned long flags;
-	unsigned long *sequence;
-	pid_t pid;
-	int cpu;
-
-	if (unlikely(bt->trace_state != Blktrace_running))
-		return;
-
-	what |= ddir_act[rw & WRITE];
-	what |= MASK_TC_BIT(rw, BARRIER);
-	what |= MASK_TC_BIT(rw, SYNCIO);
-	what |= MASK_TC_BIT(rw, AHEAD);
-	what |= MASK_TC_BIT(rw, META);
-	what |= MASK_TC_BIT(rw, DISCARD);
-
-	pid = tsk->pid;
-	if (unlikely(act_log_check(bt, what, sector, pid)))
-		return;
-
-	/*
-	 * A word about the locking here - we disable interrupts to reserve
-	 * some space in the relay per-cpu buffer, to prevent an irq
-	 * from coming in and stepping on our toes.
-	 */
-	local_irq_save(flags);
-
-	if (unlikely(tsk->btrace_seq != blktrace_seq))
-		trace_note_tsk(bt, tsk);
-
-	t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len);
-	if (t) {
-		cpu = smp_processor_id();
-		sequence = per_cpu_ptr(bt->sequence, cpu);
-
-		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
-		t->sequence = ++(*sequence);
-		t->time = ktime_to_ns(ktime_get());
-		t->sector = sector;
-		t->bytes = bytes;
-		t->action = what;
-		t->pid = pid;
-		t->device = bt->dev;
-		t->cpu = cpu;
-		t->error = error;
-		t->pdu_len = pdu_len;
-
-		if (pdu_len)
-			memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
-	}
-
-	local_irq_restore(flags);
-}
-
-static struct dentry *blk_tree_root;
-static DEFINE_MUTEX(blk_tree_mutex);
-
-static void blk_trace_cleanup(struct blk_trace *bt)
-{
-	debugfs_remove(bt->msg_file);
-	debugfs_remove(bt->dropped_file);
-	relay_close(bt->rchan);
-	free_percpu(bt->sequence);
-	free_percpu(bt->msg_data);
-	kfree(bt);
-	mutex_lock(&blk_probe_mutex);
-	if (atomic_dec_and_test(&blk_probes_ref))
-		blk_unregister_tracepoints();
-	mutex_unlock(&blk_probe_mutex);
-}
-
-int blk_trace_remove(struct request_queue *q)
-{
-	struct blk_trace *bt;
-
-	bt = xchg(&q->blk_trace, NULL);
-	if (!bt)
-		return -EINVAL;
-
-	if (bt->trace_state == Blktrace_setup ||
-	    bt->trace_state == Blktrace_stopped)
-		blk_trace_cleanup(bt);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(blk_trace_remove);
-
-static int blk_dropped_open(struct inode *inode, struct file *filp)
-{
-	filp->private_data = inode->i_private;
-
-	return 0;
-}
-
-static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
-				size_t count, loff_t *ppos)
-{
-	struct blk_trace *bt = filp->private_data;
-	char buf[16];
-
-	snprintf(buf, sizeof(buf), "%u\n", atomic_read(&bt->dropped));
-
-	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
-}
-
-static const struct file_operations blk_dropped_fops = {
-	.owner =	THIS_MODULE,
-	.open =		blk_dropped_open,
-	.read =		blk_dropped_read,
-};
-
-static int blk_msg_open(struct inode *inode, struct file *filp)
-{
-	filp->private_data = inode->i_private;
-
-	return 0;
-}
-
-static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
-				size_t count, loff_t *ppos)
-{
-	char *msg;
-	struct blk_trace *bt;
-
-	if (count > BLK_TN_MAX_MSG)
-		return -EINVAL;
-
-	msg = kmalloc(count, GFP_KERNEL);
-	if (msg == NULL)
-		return -ENOMEM;
-
-	if (copy_from_user(msg, buffer, count)) {
-		kfree(msg);
-		return -EFAULT;
-	}
-
-	bt = filp->private_data;
-	__trace_note_message(bt, "%s", msg);
-	kfree(msg);
-
-	return count;
-}
-
-static const struct file_operations blk_msg_fops = {
-	.owner =	THIS_MODULE,
-	.open =		blk_msg_open,
-	.write =	blk_msg_write,
-};
-
-/*
- * Keep track of how many times we encountered a full subbuffer, to aid
- * the user space app in telling how many lost events there were.
- */
-static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
-				     void *prev_subbuf, size_t prev_padding)
-{
-	struct blk_trace *bt;
-
-	if (!relay_buf_full(buf))
-		return 1;
-
-	bt = buf->chan->private_data;
-	atomic_inc(&bt->dropped);
-	return 0;
-}
-
-static int blk_remove_buf_file_callback(struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	debugfs_remove(dentry);
-
-	/*
-	* this will fail for all but the last file, but that is ok. what we
-	* care about is the top level buts->name directory going away, when
-	* the last trace file is gone. Then we don't have to rmdir() that
-	* manually on trace stop, so it nicely solves the issue with
-	* force killing of running traces.
-	*/
-
-	debugfs_remove(parent);
-	return 0;
-}
-
-static struct dentry *blk_create_buf_file_callback(const char *filename,
-						   struct dentry *parent,
-						   int mode,
-						   struct rchan_buf *buf,
-						   int *is_global)
-{
-	return debugfs_create_file(filename, mode, parent, buf,
-					&relay_file_operations);
-}
-
-static struct rchan_callbacks blk_relay_callbacks = {
-	.subbuf_start		= blk_subbuf_start_callback,
-	.create_buf_file	= blk_create_buf_file_callback,
-	.remove_buf_file	= blk_remove_buf_file_callback,
-};
-
-/*
- * Setup everything required to start tracing
- */
-int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
-			struct blk_user_trace_setup *buts)
-{
-	struct blk_trace *old_bt, *bt = NULL;
-	struct dentry *dir = NULL;
-	int ret, i;
-
-	if (!buts->buf_size || !buts->buf_nr)
-		return -EINVAL;
-
-	strncpy(buts->name, name, BLKTRACE_BDEV_SIZE);
-	buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0';
-
-	/*
-	 * some device names have larger paths - convert the slashes
-	 * to underscores for this to work as expected
-	 */
-	for (i = 0; i < strlen(buts->name); i++)
-		if (buts->name[i] == '/')
-			buts->name[i] = '_';
-
-	ret = -ENOMEM;
-	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
-	if (!bt)
-		goto err;
-
-	bt->sequence = alloc_percpu(unsigned long);
-	if (!bt->sequence)
-		goto err;
-
-	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG);
-	if (!bt->msg_data)
-		goto err;
-
-	ret = -ENOENT;
-
-	if (!blk_tree_root) {
-		blk_tree_root = debugfs_create_dir("block", NULL);
-		if (!blk_tree_root)
-			return -ENOMEM;
-	}
-
-	dir = debugfs_create_dir(buts->name, blk_tree_root);
-
-	if (!dir)
-		goto err;
-
-	bt->dir = dir;
-	bt->dev = dev;
-	atomic_set(&bt->dropped, 0);
-
-	ret = -EIO;
-	bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, &blk_dropped_fops);
-	if (!bt->dropped_file)
-		goto err;
-
-	bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops);
-	if (!bt->msg_file)
-		goto err;
-
-	bt->rchan = relay_open("trace", dir, buts->buf_size,
-				buts->buf_nr, &blk_relay_callbacks, bt);
-	if (!bt->rchan)
-		goto err;
-
-	bt->act_mask = buts->act_mask;
-	if (!bt->act_mask)
-		bt->act_mask = (u16) -1;
-
-	bt->start_lba = buts->start_lba;
-	bt->end_lba = buts->end_lba;
-	if (!bt->end_lba)
-		bt->end_lba = -1ULL;
-
-	bt->pid = buts->pid;
-	bt->trace_state = Blktrace_setup;
-
-	mutex_lock(&blk_probe_mutex);
-	if (atomic_add_return(1, &blk_probes_ref) == 1) {
-		ret = blk_register_tracepoints();
-		if (ret)
-			goto probe_err;
-	}
-	mutex_unlock(&blk_probe_mutex);
-
-	ret = -EBUSY;
-	old_bt = xchg(&q->blk_trace, bt);
-	if (old_bt) {
-		(void) xchg(&q->blk_trace, old_bt);
-		goto err;
-	}
-
-	return 0;
-probe_err:
-	atomic_dec(&blk_probes_ref);
-	mutex_unlock(&blk_probe_mutex);
-err:
-	if (bt) {
-		if (bt->msg_file)
-			debugfs_remove(bt->msg_file);
-		if (bt->dropped_file)
-			debugfs_remove(bt->dropped_file);
-		free_percpu(bt->sequence);
-		free_percpu(bt->msg_data);
-		if (bt->rchan)
-			relay_close(bt->rchan);
-		kfree(bt);
-	}
-	return ret;
-}
-
-int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
-		    char __user *arg)
-{
-	struct blk_user_trace_setup buts;
-	int ret;
-
-	ret = copy_from_user(&buts, arg, sizeof(buts));
-	if (ret)
-		return -EFAULT;
-
-	ret = do_blk_trace_setup(q, name, dev, &buts);
-	if (ret)
-		return ret;
-
-	if (copy_to_user(arg, &buts, sizeof(buts)))
-		return -EFAULT;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(blk_trace_setup);
-
-int blk_trace_startstop(struct request_queue *q, int start)
-{
-	struct blk_trace *bt;
-	int ret;
-
-	if ((bt = q->blk_trace) == NULL)
-		return -EINVAL;
-
-	/*
-	 * For starting a trace, we can transition from a setup or stopped
-	 * trace. For stopping a trace, the state must be running
-	 */
-	ret = -EINVAL;
-	if (start) {
-		if (bt->trace_state == Blktrace_setup ||
-		    bt->trace_state == Blktrace_stopped) {
-			blktrace_seq++;
-			smp_mb();
-			bt->trace_state = Blktrace_running;
-
-			trace_note_time(bt);
-			ret = 0;
-		}
-	} else {
-		if (bt->trace_state == Blktrace_running) {
-			bt->trace_state = Blktrace_stopped;
-			relay_flush(bt->rchan);
-			ret = 0;
-		}
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(blk_trace_startstop);
-
-/**
- * blk_trace_ioctl: - handle the ioctls associated with tracing
- * @bdev:	the block device
- * @cmd: 	the ioctl cmd
- * @arg:	the argument data, if any
- *
- **/
-int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
-{
-	struct request_queue *q;
-	int ret, start = 0;
-	char b[BDEVNAME_SIZE];
-
-	q = bdev_get_queue(bdev);
-	if (!q)
-		return -ENXIO;
-
-	mutex_lock(&bdev->bd_mutex);
-
-	switch (cmd) {
-	case BLKTRACESETUP:
-		bdevname(bdev, b);
-		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
-		break;
-	case BLKTRACESTART:
-		start = 1;
-	case BLKTRACESTOP:
-		ret = blk_trace_startstop(q, start);
-		break;
-	case BLKTRACETEARDOWN:
-		ret = blk_trace_remove(q);
-		break;
-	default:
-		ret = -ENOTTY;
-		break;
-	}
-
-	mutex_unlock(&bdev->bd_mutex);
-	return ret;
-}
-
-/**
- * blk_trace_shutdown: - stop and cleanup trace structures
- * @q:    the request queue associated with the device
- *
- **/
-void blk_trace_shutdown(struct request_queue *q)
-{
-	if (q->blk_trace) {
-		blk_trace_startstop(q, 0);
-		blk_trace_remove(q);
-	}
-}
-
-/*
- * blktrace probes
- */
-
-/**
- * blk_add_trace_rq - Add a trace for a request oriented action
- * @q:		queue the io is for
- * @rq:		the source request
- * @what:	the action
- *
- * Description:
- *     Records an action against a request. Will log the bio offset + size.
- *
- **/
-static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
-				    u32 what)
-{
-	struct blk_trace *bt = q->blk_trace;
-	int rw = rq->cmd_flags & 0x03;
-
-	if (likely(!bt))
-		return;
-
-	if (blk_discard_rq(rq))
-		rw |= (1 << BIO_RW_DISCARD);
-
-	if (blk_pc_request(rq)) {
-		what |= BLK_TC_ACT(BLK_TC_PC);
-		__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
-				sizeof(rq->cmd), rq->cmd);
-	} else  {
-		what |= BLK_TC_ACT(BLK_TC_FS);
-		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
-				rw, what, rq->errors, 0, NULL);
-	}
-}
-
-static void blk_add_trace_rq_abort(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_ABORT);
-}
-
-static void blk_add_trace_rq_insert(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_INSERT);
-}
-
-static void blk_add_trace_rq_issue(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
-}
-
-static void blk_add_trace_rq_requeue(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
-}
-
-static void blk_add_trace_rq_complete(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
-}
-
-/**
- * blk_add_trace_bio - Add a trace for a bio oriented action
- * @q:		queue the io is for
- * @bio:	the source bio
- * @what:	the action
- *
- * Description:
- *     Records an action against a bio. Will log the bio offset + size.
- *
- **/
-static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
-				     u32 what)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (likely(!bt))
-		return;
-
-	__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what,
-			!bio_flagged(bio, BIO_UPTODATE), 0, NULL);
-}
-
-static void blk_add_trace_bio_bounce(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_BOUNCE);
-}
-
-static void blk_add_trace_bio_complete(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_COMPLETE);
-}
-
-static void blk_add_trace_bio_backmerge(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
-}
-
-static void blk_add_trace_bio_frontmerge(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
-}
-
-static void blk_add_trace_bio_queue(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
-}
-
-static void blk_add_trace_getrq(struct request_queue *q, struct bio *bio, int rw)
-{
-	if (bio)
-		blk_add_trace_bio(q, bio, BLK_TA_GETRQ);
-	else {
-		struct blk_trace *bt = q->blk_trace;
-
-		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_GETRQ, 0, 0, NULL);
-	}
-}
-
-
-static void blk_add_trace_sleeprq(struct request_queue *q, struct bio *bio, int rw)
-{
-	if (bio)
-		blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ);
-	else {
-		struct blk_trace *bt = q->blk_trace;
-
-		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ, 0, 0, NULL);
-	}
-}
-
-static void blk_add_trace_plug(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt)
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL);
-}
-
-static void blk_add_trace_unplug_io(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_IO, 0,
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-static void blk_add_trace_unplug_timer(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_TIMER, 0,
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-static void blk_add_trace_split(struct request_queue *q, struct bio *bio,
-				unsigned int pdu)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
-				BLK_TA_SPLIT, !bio_flagged(bio, BIO_UPTODATE),
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-/**
- * blk_add_trace_remap - Add a trace for a remap operation
- * @q:		queue the io is for
- * @bio:	the source bio
- * @dev:	target device
- * @from:	source sector
- * @to:		target sector
- *
- * Description:
- *     Device mapper or raid target sometimes need to split a bio because
- *     it spans a stripe (or similar). Add a trace for that action.
- *
- **/
-static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
-				       dev_t dev, sector_t from, sector_t to)
-{
-	struct blk_trace *bt = q->blk_trace;
-	struct blk_io_trace_remap r;
-
-	if (likely(!bt))
-		return;
-
-	r.device = cpu_to_be32(dev);
-	r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev);
-	r.sector = cpu_to_be64(to);
-
-	__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP,
-			!bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
-}
-
-/**
- * blk_add_driver_data - Add binary message with driver-specific data
- * @q:		queue the io is for
- * @rq:		io request
- * @data:	driver-specific data
- * @len:	length of driver-specific data
- *
- * Description:
- *     Some drivers might want to write driver-specific data per request.
- *
- **/
-void blk_add_driver_data(struct request_queue *q,
-			 struct request *rq,
-			 void *data, size_t len)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (likely(!bt))
-		return;
-
-	if (blk_pc_request(rq))
-		__blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA,
-				rq->errors, len, data);
-	else
-		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
-				0, BLK_TA_DRV_DATA, rq->errors, len, data);
-}
-EXPORT_SYMBOL_GPL(blk_add_driver_data);
-
-static int blk_register_tracepoints(void)
-{
-	int ret;
-
-	ret = register_trace_block_rq_abort(blk_add_trace_rq_abort);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_insert(blk_add_trace_rq_insert);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_issue(blk_add_trace_rq_issue);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_complete(blk_add_trace_rq_complete);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_complete(blk_add_trace_bio_complete);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_queue(blk_add_trace_bio_queue);
-	WARN_ON(ret);
-	ret = register_trace_block_getrq(blk_add_trace_getrq);
-	WARN_ON(ret);
-	ret = register_trace_block_sleeprq(blk_add_trace_sleeprq);
-	WARN_ON(ret);
-	ret = register_trace_block_plug(blk_add_trace_plug);
-	WARN_ON(ret);
-	ret = register_trace_block_unplug_timer(blk_add_trace_unplug_timer);
-	WARN_ON(ret);
-	ret = register_trace_block_unplug_io(blk_add_trace_unplug_io);
-	WARN_ON(ret);
-	ret = register_trace_block_split(blk_add_trace_split);
-	WARN_ON(ret);
-	ret = register_trace_block_remap(blk_add_trace_remap);
-	WARN_ON(ret);
-	return 0;
-}
-
-static void blk_unregister_tracepoints(void)
-{
-	unregister_trace_block_remap(blk_add_trace_remap);
-	unregister_trace_block_split(blk_add_trace_split);
-	unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
-	unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer);
-	unregister_trace_block_plug(blk_add_trace_plug);
-	unregister_trace_block_sleeprq(blk_add_trace_sleeprq);
-	unregister_trace_block_getrq(blk_add_trace_getrq);
-	unregister_trace_block_bio_queue(blk_add_trace_bio_queue);
-	unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
-	unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
-	unregister_trace_block_bio_complete(blk_add_trace_bio_complete);
-	unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce);
-	unregister_trace_block_rq_complete(blk_add_trace_rq_complete);
-	unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue);
-	unregister_trace_block_rq_issue(blk_add_trace_rq_issue);
-	unregister_trace_block_rq_insert(blk_add_trace_rq_insert);
-	unregister_trace_block_rq_abort(blk_add_trace_rq_abort);
-
-	tracepoint_synchronize_unregister();
-}
diff -druNp linux-libre-2.6.29-gnu1/block/bsg.c linux-libre-2.6.30-gnu1/block/bsg.c
--- linux-libre-2.6.29-gnu1/block/bsg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/bsg.c	2009-06-09 23:05:27.000000000 -0400
@@ -218,9 +218,6 @@ bsg_validate_sgv4_hdr(struct request_que
 
 	if (hdr->guard != 'Q')
 		return -EINVAL;
-	if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
-	    hdr->din_xfer_len > (q->max_sectors << 9))
-		return -EIO;
 
 	switch (hdr->protocol) {
 	case BSG_PROTOCOL_SCSI:
@@ -318,6 +315,7 @@ out:
 	blk_put_request(rq);
 	if (next_rq) {
 		blk_rq_unmap_user(next_rq->bio);
+		next_rq->bio = NULL;
 		blk_put_request(next_rq);
 	}
 	return ERR_PTR(ret);
@@ -353,6 +351,8 @@ static void bsg_rq_end_io(struct request
 static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
 			    struct bsg_command *bc, struct request *rq)
 {
+	int at_head = (0 == (bc->hdr.flags & BSG_FLAG_Q_AT_TAIL));
+
 	/*
 	 * add bc command to busy queue and submit rq for io
 	 */
@@ -368,7 +368,7 @@ static void bsg_add_command(struct bsg_d
 	dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
 
 	rq->end_io_data = bc;
-	blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io);
+	blk_execute_rq_nowait(q, NULL, rq, at_head, bsg_rq_end_io);
 }
 
 static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
@@ -449,6 +449,7 @@ static int blk_complete_sgv4_hdr_rq(stru
 		hdr->dout_resid = rq->data_len;
 		hdr->din_resid = rq->next_rq->data_len;
 		blk_rq_unmap_user(bidi_bio);
+		rq->next_rq->bio = NULL;
 		blk_put_request(rq->next_rq);
 	} else if (rq_data_dir(rq) == READ)
 		hdr->din_resid = rq->data_len;
@@ -467,6 +468,7 @@ static int blk_complete_sgv4_hdr_rq(stru
 	blk_rq_unmap_user(bio);
 	if (rq->cmd != rq->__cmd)
 		kfree(rq->cmd);
+	rq->bio = NULL;
 	blk_put_request(rq);
 
 	return ret;
@@ -924,6 +926,7 @@ static long bsg_ioctl(struct file *file,
 		struct request *rq;
 		struct bio *bio, *bidi_bio = NULL;
 		struct sg_io_v4 hdr;
+		int at_head;
 		u8 sense[SCSI_SENSE_BUFFERSIZE];
 
 		if (copy_from_user(&hdr, uarg, sizeof(hdr)))
@@ -936,7 +939,9 @@ static long bsg_ioctl(struct file *file,
 		bio = rq->bio;
 		if (rq->next_rq)
 			bidi_bio = rq->next_rq->bio;
-		blk_execute_rq(bd->queue, NULL, rq, 0);
+
+		at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL));
+		blk_execute_rq(bd->queue, NULL, rq, at_head);
 		ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
 
 		if (copy_to_user(uarg, &hdr, sizeof(hdr)))
diff -druNp linux-libre-2.6.29-gnu1/block/cfq-iosched.c linux-libre-2.6.30-gnu1/block/cfq-iosched.c
--- linux-libre-2.6.29-gnu1/block/cfq-iosched.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/cfq-iosched.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,9 +56,6 @@ static DEFINE_SPINLOCK(ioc_gone_lock);
 #define cfq_class_idle(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
 #define cfq_class_rt(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
 
-#define ASYNC			(0)
-#define SYNC			(1)
-
 #define sample_valid(samples)	((samples) > 80)
 
 /*
@@ -83,6 +80,14 @@ struct cfq_data {
 	 * rr list of queues with requests and the count of them
 	 */
 	struct cfq_rb_root service_tree;
+
+	/*
+	 * Each priority tree is sorted by next_request position.  These
+	 * trees are used when determining if two or more queues are
+	 * interleaving requests (see cfq_close_cooperator).
+	 */
+	struct rb_root prio_trees[CFQ_PRIO_LISTS];
+
 	unsigned int busy_queues;
 	/*
 	 * Used to track any pending rt requests so we can pre-empt current
@@ -147,6 +152,10 @@ struct cfq_queue {
 	struct rb_node rb_node;
 	/* service_tree key */
 	unsigned long rb_key;
+	/* prio tree member */
+	struct rb_node p_node;
+	/* prio tree root we belong to, if any */
+	struct rb_root *p_root;
 	/* sorted list of pending requests */
 	struct rb_root sort_list;
 	/* if fifo isn't expired, next request to serve */
@@ -160,6 +169,7 @@ struct cfq_queue {
 
 	unsigned long slice_end;
 	long slice_resid;
+	unsigned int slice_dispatch;
 
 	/* pending metadata requests */
 	int meta_pending;
@@ -176,15 +186,15 @@ struct cfq_queue {
 enum cfqq_state_flags {
 	CFQ_CFQQ_FLAG_on_rr = 0,	/* on round-robin busy list */
 	CFQ_CFQQ_FLAG_wait_request,	/* waiting for a request */
+	CFQ_CFQQ_FLAG_must_dispatch,	/* must be allowed a dispatch */
 	CFQ_CFQQ_FLAG_must_alloc,	/* must be allowed rq alloc */
 	CFQ_CFQQ_FLAG_must_alloc_slice,	/* per-slice must_alloc flag */
-	CFQ_CFQQ_FLAG_must_dispatch,	/* must dispatch, even if expired */
 	CFQ_CFQQ_FLAG_fifo_expire,	/* FIFO checked in this slice */
 	CFQ_CFQQ_FLAG_idle_window,	/* slice idling enabled */
 	CFQ_CFQQ_FLAG_prio_changed,	/* task priority has changed */
-	CFQ_CFQQ_FLAG_queue_new,	/* queue never been serviced */
 	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 */
 };
 
 #define CFQ_CFQQ_FNS(name)						\
@@ -203,15 +213,15 @@ static inline int cfq_cfqq_##name(const
 
 CFQ_CFQQ_FNS(on_rr);
 CFQ_CFQQ_FNS(wait_request);
+CFQ_CFQQ_FNS(must_dispatch);
 CFQ_CFQQ_FNS(must_alloc);
 CFQ_CFQQ_FNS(must_alloc_slice);
-CFQ_CFQQ_FNS(must_dispatch);
 CFQ_CFQQ_FNS(fifo_expire);
 CFQ_CFQQ_FNS(idle_window);
 CFQ_CFQQ_FNS(prio_changed);
-CFQ_CFQQ_FNS(queue_new);
 CFQ_CFQQ_FNS(slice_new);
 CFQ_CFQQ_FNS(sync);
+CFQ_CFQQ_FNS(coop);
 #undef CFQ_CFQQ_FNS
 
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...)	\
@@ -420,13 +430,17 @@ static struct cfq_queue *cfq_rb_first(st
 	return NULL;
 }
 
+static void rb_erase_init(struct rb_node *n, struct rb_root *root)
+{
+	rb_erase(n, root);
+	RB_CLEAR_NODE(n);
+}
+
 static void cfq_rb_erase(struct rb_node *n, struct cfq_rb_root *root)
 {
 	if (root->left == n)
 		root->left = NULL;
-
-	rb_erase(n, &root->rb);
-	RB_CLEAR_NODE(n);
+	rb_erase_init(n, &root->rb);
 }
 
 /*
@@ -471,8 +485,8 @@ static unsigned long cfq_slice_offset(st
  * requests waiting to be processed. It is sorted in the order that
  * we will service the queues.
  */
-static void cfq_service_tree_add(struct cfq_data *cfqd,
-				    struct cfq_queue *cfqq, int add_front)
+static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+				 int add_front)
 {
 	struct rb_node **p, *parent;
 	struct cfq_queue *__cfqq;
@@ -545,6 +559,67 @@ static void cfq_service_tree_add(struct
 	rb_insert_color(&cfqq->rb_node, &cfqd->service_tree.rb);
 }
 
+static struct cfq_queue *
+cfq_prio_tree_lookup(struct cfq_data *cfqd, struct rb_root *root,
+		     sector_t sector, struct rb_node **ret_parent,
+		     struct rb_node ***rb_link)
+{
+	struct rb_node **p, *parent;
+	struct cfq_queue *cfqq = NULL;
+
+	parent = NULL;
+	p = &root->rb_node;
+	while (*p) {
+		struct rb_node **n;
+
+		parent = *p;
+		cfqq = rb_entry(parent, struct cfq_queue, p_node);
+
+		/*
+		 * Sort strictly based on sector.  Smallest to the left,
+		 * largest to the right.
+		 */
+		if (sector > cfqq->next_rq->sector)
+			n = &(*p)->rb_right;
+		else if (sector < cfqq->next_rq->sector)
+			n = &(*p)->rb_left;
+		else
+			break;
+		p = n;
+		cfqq = NULL;
+	}
+
+	*ret_parent = parent;
+	if (rb_link)
+		*rb_link = p;
+	return cfqq;
+}
+
+static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	struct rb_node **p, *parent;
+	struct cfq_queue *__cfqq;
+
+	if (cfqq->p_root) {
+		rb_erase(&cfqq->p_node, cfqq->p_root);
+		cfqq->p_root = NULL;
+	}
+
+	if (cfq_class_idle(cfqq))
+		return;
+	if (!cfqq->next_rq)
+		return;
+
+	cfqq->p_root = &cfqd->prio_trees[cfqq->org_ioprio];
+	__cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root, cfqq->next_rq->sector,
+					 &parent, &p);
+	if (!__cfqq) {
+		rb_link_node(&cfqq->p_node, parent, p);
+		rb_insert_color(&cfqq->p_node, cfqq->p_root);
+	} else
+		cfqq->p_root = NULL;
+}
+
 /*
  * Update cfqq's position in the service tree.
  */
@@ -553,8 +628,10 @@ static void cfq_resort_rr_list(struct cf
 	/*
 	 * Resorting requires the cfqq to be on the RR list already.
 	 */
-	if (cfq_cfqq_on_rr(cfqq))
+	if (cfq_cfqq_on_rr(cfqq)) {
 		cfq_service_tree_add(cfqd, cfqq, 0);
+		cfq_prio_tree_add(cfqd, cfqq);
+	}
 }
 
 /*
@@ -585,6 +662,10 @@ static void cfq_del_cfqq_rr(struct cfq_d
 
 	if (!RB_EMPTY_NODE(&cfqq->rb_node))
 		cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree);
+	if (cfqq->p_root) {
+		rb_erase(&cfqq->p_node, cfqq->p_root);
+		cfqq->p_root = NULL;
+	}
 
 	BUG_ON(!cfqd->busy_queues);
 	cfqd->busy_queues--;
@@ -614,7 +695,7 @@ static void cfq_add_rq_rb(struct request
 {
 	struct cfq_queue *cfqq = RQ_CFQQ(rq);
 	struct cfq_data *cfqd = cfqq->cfqd;
-	struct request *__alias;
+	struct request *__alias, *prev;
 
 	cfqq->queued[rq_is_sync(rq)]++;
 
@@ -631,7 +712,15 @@ 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);
+
+	/*
+	 * adjust priority tree position, if ->next_rq changes
+	 */
+	if (prev != cfqq->next_rq)
+		cfq_prio_tree_add(cfqd, cfqq);
+
 	BUG_ON(!cfqq->next_rq);
 }
 
@@ -774,10 +863,15 @@ static void __cfq_set_active_queue(struc
 	if (cfqq) {
 		cfq_log_cfqq(cfqd, cfqq, "set_active");
 		cfqq->slice_end = 0;
+		cfqq->slice_dispatch = 0;
+
+		cfq_clear_cfqq_wait_request(cfqq);
+		cfq_clear_cfqq_must_dispatch(cfqq);
 		cfq_clear_cfqq_must_alloc_slice(cfqq);
 		cfq_clear_cfqq_fifo_expire(cfqq);
 		cfq_mark_cfqq_slice_new(cfqq);
-		cfq_clear_cfqq_queue_new(cfqq);
+
+		del_timer(&cfqd->idle_slice_timer);
 	}
 
 	cfqd->active_queue = cfqq;
@@ -795,7 +889,6 @@ __cfq_slice_expired(struct cfq_data *cfq
 	if (cfq_cfqq_wait_request(cfqq))
 		del_timer(&cfqd->idle_slice_timer);
 
-	cfq_clear_cfqq_must_dispatch(cfqq);
 	cfq_clear_cfqq_wait_request(cfqq);
 
 	/*
@@ -840,11 +933,15 @@ static struct cfq_queue *cfq_get_next_qu
 /*
  * Get and set a new active queue for service.
  */
-static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
+static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
+					      struct cfq_queue *cfqq)
 {
-	struct cfq_queue *cfqq;
+	if (!cfqq) {
+		cfqq = cfq_get_next_queue(cfqd);
+		if (cfqq)
+			cfq_clear_cfqq_coop(cfqq);
+	}
 
-	cfqq = cfq_get_next_queue(cfqd);
 	__cfq_set_active_queue(cfqd, cfqq);
 	return cfqq;
 }
@@ -858,28 +955,100 @@ static inline sector_t cfq_dist_from_las
 		return cfqd->last_position - rq->sector;
 }
 
+#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)
 {
 	struct cfq_io_context *cic = cfqd->active_cic;
+	sector_t sdist = cic->seek_mean;
 
 	if (!sample_valid(cic->seek_samples))
-		return 0;
+		sdist = CIC_SEEK_THR;
 
-	return cfq_dist_from_last(cfqd, rq) <= cic->seek_mean;
+	return cfq_dist_from_last(cfqd, rq) <= sdist;
 }
 
-static int cfq_close_cooperator(struct cfq_data *cfq_data,
-				struct cfq_queue *cfqq)
+static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
+				    struct cfq_queue *cur_cfqq)
 {
+	struct rb_root *root = &cfqd->prio_trees[cur_cfqq->org_ioprio];
+	struct rb_node *parent, *node;
+	struct cfq_queue *__cfqq;
+	sector_t sector = cfqd->last_position;
+
+	if (RB_EMPTY_ROOT(root))
+		return NULL;
+
+	/*
+	 * First, if we find a request starting at the end of the last
+	 * request, choose it.
+	 */
+	__cfqq = cfq_prio_tree_lookup(cfqd, root, sector, &parent, NULL);
+	if (__cfqq)
+		return __cfqq;
+
+	/*
+	 * If the exact sector wasn't found, the parent of the NULL leaf
+	 * will contain the closest sector.
+	 */
+	__cfqq = rb_entry(parent, struct cfq_queue, p_node);
+	if (cfq_rq_close(cfqd, __cfqq->next_rq))
+		return __cfqq;
+
+	if (__cfqq->next_rq->sector < sector)
+		node = rb_next(&__cfqq->p_node);
+	else
+		node = rb_prev(&__cfqq->p_node);
+	if (!node)
+		return NULL;
+
+	__cfqq = rb_entry(node, struct cfq_queue, p_node);
+	if (cfq_rq_close(cfqd, __cfqq->next_rq))
+		return __cfqq;
+
+	return NULL;
+}
+
+/*
+ * cfqd - obvious
+ * cur_cfqq - passed in so that we don't decide that the current queue is
+ * 	      closely cooperating with itself.
+ *
+ * So, basically we're assuming that that cur_cfqq has dispatched at least
+ * one request, and that cfqd->last_position reflects a position on the disk
+ * associated with the I/O issued by cur_cfqq.  I'm not sure this is a valid
+ * assumption.
+ */
+static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
+					      struct cfq_queue *cur_cfqq,
+					      int probe)
+{
+	struct cfq_queue *cfqq;
+
+	/*
+	 * A valid cfq_io_context is necessary to compare requests against
+	 * the seek_mean of the current cfqq.
+	 */
+	if (!cfqd->active_cic)
+		return NULL;
+
 	/*
 	 * We should notice if some of the queues are cooperating, eg
 	 * working closely on the same area of the disk. In that case,
 	 * we can group them together and don't waste time idling.
 	 */
-	return 0;
-}
+	cfqq = cfqq_close(cfqd, cur_cfqq);
+	if (!cfqq)
+		return NULL;
 
-#define CIC_SEEKY(cic) ((cic)->seek_mean > (8 * 1024))
+	if (cfq_cfqq_coop(cfqq))
+		return NULL;
+
+	if (!probe)
+		cfq_mark_cfqq_coop(cfqq);
+	return cfqq;
+}
 
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 {
@@ -917,14 +1086,6 @@ static void cfq_arm_slice_timer(struct c
 	if (!cic || !atomic_read(&cic->ioc->nr_tasks))
 		return;
 
-	/*
-	 * See if this prio level has a good candidate
-	 */
-	if (cfq_close_cooperator(cfqd, cfqq) &&
-	    (sample_valid(cic->ttime_samples) && cic->ttime_mean > 2))
-		return;
-
-	cfq_mark_cfqq_must_dispatch(cfqq);
 	cfq_mark_cfqq_wait_request(cfqq);
 
 	/*
@@ -937,7 +1098,7 @@ static void cfq_arm_slice_timer(struct c
 		sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT));
 
 	mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
-	cfq_log(cfqd, "arm_idle: %lu", sl);
+	cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl);
 }
 
 /*
@@ -1001,7 +1162,7 @@ cfq_prio_to_maxrq(struct cfq_data *cfqd,
  */
 static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
 {
-	struct cfq_queue *cfqq;
+	struct cfq_queue *cfqq, *new_cfqq = NULL;
 
 	cfqq = cfqd->active_queue;
 	if (!cfqq)
@@ -1010,7 +1171,7 @@ static struct cfq_queue *cfq_select_queu
 	/*
 	 * The active queue has run out of time, expire it and select new.
 	 */
-	if (cfq_slice_used(cfqq))
+	if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
 		goto expire;
 
 	/*
@@ -1035,6 +1196,16 @@ static struct cfq_queue *cfq_select_queu
 		goto keep_queue;
 
 	/*
+	 * 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.
+	 */
+	new_cfqq = cfq_close_cooperator(cfqd, cfqq, 0);
+	if (new_cfqq)
+		goto expire;
+
+	/*
 	 * No requests pending. If the active queue still has requests in
 	 * flight or is idling for a new request, allow either of these
 	 * conditions to happen (or time out) before selecting a new queue.
@@ -1048,71 +1219,11 @@ static struct cfq_queue *cfq_select_queu
 expire:
 	cfq_slice_expired(cfqd, 0);
 new_queue:
-	cfqq = cfq_set_active_queue(cfqd);
+	cfqq = cfq_set_active_queue(cfqd, new_cfqq);
 keep_queue:
 	return cfqq;
 }
 
-/*
- * Dispatch some requests from cfqq, moving them to the request queue
- * dispatch list.
- */
-static int
-__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-			int max_dispatch)
-{
-	int dispatched = 0;
-
-	BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
-
-	do {
-		struct request *rq;
-
-		/*
-		 * follow expired path, else get first next available
-		 */
-		rq = cfq_check_fifo(cfqq);
-		if (rq == NULL)
-			rq = cfqq->next_rq;
-
-		/*
-		 * finally, insert request into driver dispatch list
-		 */
-		cfq_dispatch_insert(cfqd->queue, rq);
-
-		dispatched++;
-
-		if (!cfqd->active_cic) {
-			atomic_inc(&RQ_CIC(rq)->ioc->refcount);
-			cfqd->active_cic = RQ_CIC(rq);
-		}
-
-		if (RB_EMPTY_ROOT(&cfqq->sort_list))
-			break;
-
-		/*
-		 * If there is a non-empty RT cfqq waiting for current
-		 * cfqq's timeslice to complete, pre-empt this cfqq
-		 */
-		if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues)
-			break;
-
-	} while (dispatched < max_dispatch);
-
-	/*
-	 * expire an async queue immediately if it has used up its slice. idle
-	 * queue always expire after 1 dispatch round.
-	 */
-	if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
-	    dispatched >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
-	    cfq_class_idle(cfqq))) {
-		cfqq->slice_end = jiffies + 1;
-		cfq_slice_expired(cfqd, 0);
-	}
-
-	return dispatched;
-}
-
 static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
 {
 	int dispatched = 0;
@@ -1146,11 +1257,45 @@ static int cfq_forced_dispatch(struct cf
 	return dispatched;
 }
 
+/*
+ * Dispatch a request from cfqq, moving them to the request queue
+ * dispatch list.
+ */
+static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	struct request *rq;
+
+	BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
+
+	/*
+	 * follow expired path, else get first next available
+	 */
+	rq = cfq_check_fifo(cfqq);
+	if (!rq)
+		rq = cfqq->next_rq;
+
+	/*
+	 * insert request into driver dispatch list
+	 */
+	cfq_dispatch_insert(cfqd->queue, rq);
+
+	if (!cfqd->active_cic) {
+		struct cfq_io_context *cic = RQ_CIC(rq);
+
+		atomic_inc(&cic->ioc->refcount);
+		cfqd->active_cic = cic;
+	}
+}
+
+/*
+ * Find the cfqq that we need to service and move a request from that to the
+ * dispatch list
+ */
 static int cfq_dispatch_requests(struct request_queue *q, int force)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 	struct cfq_queue *cfqq;
-	int dispatched;
+	unsigned int max_dispatch;
 
 	if (!cfqd->busy_queues)
 		return 0;
@@ -1158,29 +1303,63 @@ static int cfq_dispatch_requests(struct
 	if (unlikely(force))
 		return cfq_forced_dispatch(cfqd);
 
-	dispatched = 0;
-	while ((cfqq = cfq_select_queue(cfqd)) != NULL) {
-		int max_dispatch;
+	cfqq = cfq_select_queue(cfqd);
+	if (!cfqq)
+		return 0;
 
-		max_dispatch = cfqd->cfq_quantum;
+	/*
+	 * If this is an async queue and we have sync IO in flight, let it wait
+	 */
+	if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
+		return 0;
+
+	max_dispatch = cfqd->cfq_quantum;
+	if (cfq_class_idle(cfqq))
+		max_dispatch = 1;
+
+	/*
+	 * Does this cfqq already have too much IO in flight?
+	 */
+	if (cfqq->dispatched >= max_dispatch) {
+		/*
+		 * idle queue must always only have a single IO in flight
+		 */
 		if (cfq_class_idle(cfqq))
-			max_dispatch = 1;
+			return 0;
 
-		if (cfqq->dispatched >= max_dispatch && cfqd->busy_queues > 1)
-			break;
+		/*
+		 * We have other queues, don't allow more IO from this one
+		 */
+		if (cfqd->busy_queues > 1)
+			return 0;
 
-		if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
-			break;
+		/*
+		 * we are the only queue, allow up to 4 times of 'quantum'
+		 */
+		if (cfqq->dispatched >= 4 * max_dispatch)
+			return 0;
+	}
 
-		cfq_clear_cfqq_must_dispatch(cfqq);
-		cfq_clear_cfqq_wait_request(cfqq);
-		del_timer(&cfqd->idle_slice_timer);
+	/*
+	 * Dispatch a request from this cfqq
+	 */
+	cfq_dispatch_request(cfqd, cfqq);
+	cfqq->slice_dispatch++;
+	cfq_clear_cfqq_must_dispatch(cfqq);
 
-		dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
+	/*
+	 * expire an async queue immediately if it has used up its slice. idle
+	 * queue always expire after 1 dispatch round.
+	 */
+	if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
+	    cfqq->slice_dispatch >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
+	    cfq_class_idle(cfqq))) {
+		cfqq->slice_end = jiffies + 1;
+		cfq_slice_expired(cfqd, 0);
 	}
 
-	cfq_log(cfqd, "dispatched=%d", dispatched);
-	return dispatched;
+	cfq_log(cfqd, "dispatched a request");
+	return 1;
 }
 
 /*
@@ -1323,14 +1502,14 @@ static void __cfq_exit_single_io_context
 	if (ioc->ioc_data == cic)
 		rcu_assign_pointer(ioc->ioc_data, NULL);
 
-	if (cic->cfqq[ASYNC]) {
-		cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
-		cic->cfqq[ASYNC] = NULL;
+	if (cic->cfqq[BLK_RW_ASYNC]) {
+		cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
+		cic->cfqq[BLK_RW_ASYNC] = NULL;
 	}
 
-	if (cic->cfqq[SYNC]) {
-		cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]);
-		cic->cfqq[SYNC] = NULL;
+	if (cic->cfqq[BLK_RW_SYNC]) {
+		cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_SYNC]);
+		cic->cfqq[BLK_RW_SYNC] = NULL;
 	}
 }
 
@@ -1439,17 +1618,18 @@ static void changed_ioprio(struct io_con
 
 	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 
-	cfqq = cic->cfqq[ASYNC];
+	cfqq = cic->cfqq[BLK_RW_ASYNC];
 	if (cfqq) {
 		struct cfq_queue *new_cfqq;
-		new_cfqq = cfq_get_queue(cfqd, ASYNC, cic->ioc, GFP_ATOMIC);
+		new_cfqq = cfq_get_queue(cfqd, BLK_RW_ASYNC, cic->ioc,
+						GFP_ATOMIC);
 		if (new_cfqq) {
-			cic->cfqq[ASYNC] = new_cfqq;
+			cic->cfqq[BLK_RW_ASYNC] = new_cfqq;
 			cfq_put_queue(cfqq);
 		}
 	}
 
-	cfqq = cic->cfqq[SYNC];
+	cfqq = cic->cfqq[BLK_RW_SYNC];
 	if (cfqq)
 		cfq_mark_cfqq_prio_changed(cfqq);
 
@@ -1500,13 +1680,13 @@ retry:
 		}
 
 		RB_CLEAR_NODE(&cfqq->rb_node);
+		RB_CLEAR_NODE(&cfqq->p_node);
 		INIT_LIST_HEAD(&cfqq->fifo);
 
 		atomic_set(&cfqq->ref, 0);
 		cfqq->cfqd = cfqd;
 
 		cfq_mark_cfqq_prio_changed(cfqq);
-		cfq_mark_cfqq_queue_new(cfqq);
 
 		cfq_init_prio_data(cfqq, ioc);
 
@@ -1736,7 +1916,9 @@ cfq_update_io_seektime(struct cfq_data *
 	sector_t sdist;
 	u64 total;
 
-	if (cic->last_request_pos < rq->sector)
+	if (!cic->last_request_pos)
+		sdist = 0;
+	else if (cic->last_request_pos < rq->sector)
 		sdist = rq->sector - cic->last_request_pos;
 	else
 		sdist = cic->last_request_pos - rq->sector;
@@ -1893,14 +2075,22 @@ cfq_rq_enqueued(struct cfq_data *cfqd, s
 
 	if (cfqq == cfqd->active_queue) {
 		/*
-		 * if we are waiting for a request for this queue, let it rip
-		 * immediately and flag that we must not expire this queue
-		 * just now
+		 * Remember that we saw a request from this process, but
+		 * don't start queuing just yet. Otherwise we risk seeing lots
+		 * of tiny requests, because we disrupt the normal plugging
+		 * and merging. If the request is already larger than a single
+		 * page, let it rip immediately. For that case we assume that
+		 * merging is already done. Ditto for a busy system that
+		 * has other work pending, don't risk delaying until the
+		 * idle timer unplug to continue working.
 		 */
 		if (cfq_cfqq_wait_request(cfqq)) {
+			if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE ||
+			    cfqd->busy_queues > 1) {
+				del_timer(&cfqd->idle_slice_timer);
+				blk_start_queueing(cfqd->queue);
+			}
 			cfq_mark_cfqq_must_dispatch(cfqq);
-			del_timer(&cfqd->idle_slice_timer);
-			blk_start_queueing(cfqd->queue);
 		}
 	} else if (cfq_should_preempt(cfqd, cfqq, rq)) {
 		/*
@@ -1910,7 +2100,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, s
 		 * this new queue is RT and the current one is BE
 		 */
 		cfq_preempt_queue(cfqd, cfqq);
-		cfq_mark_cfqq_must_dispatch(cfqq);
 		blk_start_queueing(cfqd->queue);
 	}
 }
@@ -1986,13 +2175,23 @@ static void cfq_completed_request(struct
 	 * or if we want to idle in case it has no pending requests.
 	 */
 	if (cfqd->active_queue == cfqq) {
+		const bool cfqq_empty = RB_EMPTY_ROOT(&cfqq->sort_list);
+
 		if (cfq_cfqq_slice_new(cfqq)) {
 			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.
+		 */
 		if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
 			cfq_slice_expired(cfqd, 1);
-		else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list))
+		else if (cfqq_empty && !cfq_close_cooperator(cfqd, cfqq, 1) &&
+			 sync && !rq_noidle(rq))
 			cfq_arm_slice_timer(cfqd);
 	}
 
@@ -2054,7 +2253,7 @@ static int cfq_may_queue(struct request_
 	if (!cic)
 		return ELV_MQUEUE_MAY;
 
-	cfqq = cic_to_cfqq(cic, rw & REQ_RW_SYNC);
+	cfqq = cic_to_cfqq(cic, rw_is_sync(rw));
 	if (cfqq) {
 		cfq_init_prio_data(cfqq, cic->ioc);
 		cfq_prio_boost(cfqq);
@@ -2144,11 +2343,10 @@ static void cfq_kick_queue(struct work_s
 	struct cfq_data *cfqd =
 		container_of(work, struct cfq_data, unplug_work);
 	struct request_queue *q = cfqd->queue;
-	unsigned long flags;
 
-	spin_lock_irqsave(q->queue_lock, flags);
+	spin_lock_irq(q->queue_lock);
 	blk_start_queueing(q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	spin_unlock_irq(q->queue_lock);
 }
 
 /*
@@ -2170,6 +2368,12 @@ static void cfq_idle_slice_timer(unsigne
 		timed_out = 0;
 
 		/*
+		 * We saw a request before the queue expired, let it through
+		 */
+		if (cfq_cfqq_must_dispatch(cfqq))
+			goto out_kick;
+
+		/*
 		 * expired
 		 */
 		if (cfq_slice_used(cfqq))
@@ -2185,10 +2389,8 @@ static void cfq_idle_slice_timer(unsigne
 		/*
 		 * not expired and it has a request pending, let it dispatch
 		 */
-		if (!RB_EMPTY_ROOT(&cfqq->sort_list)) {
-			cfq_mark_cfqq_must_dispatch(cfqq);
+		if (!RB_EMPTY_ROOT(&cfqq->sort_list))
 			goto out_kick;
-		}
 	}
 expire:
 	cfq_slice_expired(cfqd, timed_out);
@@ -2251,12 +2453,22 @@ static void cfq_exit_queue(struct elevat
 static void *cfq_init_queue(struct request_queue *q)
 {
 	struct cfq_data *cfqd;
+	int i;
 
 	cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
 	if (!cfqd)
 		return NULL;
 
 	cfqd->service_tree = CFQ_RB_ROOT;
+
+	/*
+	 * Not strictly needed (since RB_ROOT just clears the node and we
+	 * zeroed cfqd on alloc), but better be safe in case someone decides
+	 * to add magic to the rb code
+	 */
+	for (i = 0; i < CFQ_PRIO_LISTS; i++)
+		cfqd->prio_trees[i] = RB_ROOT;
+
 	INIT_LIST_HEAD(&cfqd->cic_list);
 
 	cfqd->queue = q;
diff -druNp linux-libre-2.6.29-gnu1/block/cmd-filter.c linux-libre-2.6.30-gnu1/block/cmd-filter.c
--- linux-libre-2.6.29-gnu1/block/cmd-filter.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/cmd-filter.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
+#include <linux/blkdev.h>
 
 #include <scsi/scsi.h>
 #include <linux/cdrom.h>
diff -druNp linux-libre-2.6.29-gnu1/block/elevator.c linux-libre-2.6.30-gnu1/block/elevator.c
--- linux-libre-2.6.29-gnu1/block/elevator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/elevator.c	2009-06-09 23:05:27.000000000 -0400
@@ -573,7 +573,7 @@ void elv_requeue_request(struct request_
 	elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
-static void elv_drain_elevator(struct request_queue *q)
+void elv_drain_elevator(struct request_queue *q)
 {
 	static int printed;
 	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
@@ -587,6 +587,31 @@ static void elv_drain_elevator(struct re
 	}
 }
 
+/*
+ * Call with queue lock held, interrupts disabled
+ */
+void elv_quiesce_start(struct request_queue *q)
+{
+	queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
+
+	/*
+	 * make sure we don't have any requests in flight
+	 */
+	elv_drain_elevator(q);
+	while (q->rq.elvpriv) {
+		blk_start_queueing(q);
+		spin_unlock_irq(q->queue_lock);
+		msleep(10);
+		spin_lock_irq(q->queue_lock);
+		elv_drain_elevator(q);
+	}
+}
+
+void elv_quiesce_end(struct request_queue *q)
+{
+	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
+}
+
 void elv_insert(struct request_queue *q, struct request *rq, int where)
 {
 	struct list_head *pos;
@@ -677,7 +702,7 @@ void elv_insert(struct request_queue *q,
 	}
 
 	if (unplug_it && blk_queue_plugged(q)) {
-		int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+		int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
 			- q->in_flight;
 
 		if (nrq >= q->unplug_thresh)
@@ -1101,18 +1126,7 @@ static int elevator_switch(struct reques
 	 * Turn on BYPASS and drain all requests w/ elevator private data
 	 */
 	spin_lock_irq(q->queue_lock);
-
-	queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
-
-	elv_drain_elevator(q);
-
-	while (q->rq.elvpriv) {
-		blk_start_queueing(q);
-		spin_unlock_irq(q->queue_lock);
-		msleep(10);
-		spin_lock_irq(q->queue_lock);
-		elv_drain_elevator(q);
-	}
+	elv_quiesce_start(q);
 
 	/*
 	 * Remember old elevator.
@@ -1136,7 +1150,7 @@ static int elevator_switch(struct reques
 	 */
 	elevator_exit(old_elevator);
 	spin_lock_irq(q->queue_lock);
-	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
+	elv_quiesce_end(q);
 	spin_unlock_irq(q->queue_lock);
 
 	blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
diff -druNp linux-libre-2.6.29-gnu1/block/genhd.c linux-libre-2.6.30-gnu1/block/genhd.c
--- linux-libre-2.6.29-gnu1/block/genhd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/genhd.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,7 +98,7 @@ void disk_part_iter_init(struct disk_par
 
 	if (flags & DISK_PITER_REVERSE)
 		piter->idx = ptbl->len - 1;
-	else if (flags & DISK_PITER_INCL_PART0)
+	else if (flags & (DISK_PITER_INCL_PART0 | DISK_PITER_INCL_EMPTY_PART0))
 		piter->idx = 0;
 	else
 		piter->idx = 1;
@@ -134,7 +134,8 @@ struct hd_struct *disk_part_iter_next(st
 	/* determine iteration parameters */
 	if (piter->flags & DISK_PITER_REVERSE) {
 		inc = -1;
-		if (piter->flags & DISK_PITER_INCL_PART0)
+		if (piter->flags & (DISK_PITER_INCL_PART0 |
+				    DISK_PITER_INCL_EMPTY_PART0))
 			end = -1;
 		else
 			end = 0;
@@ -150,7 +151,10 @@ struct hd_struct *disk_part_iter_next(st
 		part = rcu_dereference(ptbl->part[piter->idx]);
 		if (!part)
 			continue;
-		if (!(piter->flags & DISK_PITER_INCL_EMPTY) && !part->nr_sects)
+		if (!part->nr_sects &&
+		    !(piter->flags & DISK_PITER_INCL_EMPTY) &&
+		    !(piter->flags & DISK_PITER_INCL_EMPTY_PART0 &&
+		      piter->idx == 0))
 			continue;
 
 		get_device(part_to_dev(part));
@@ -1011,7 +1015,7 @@ static int diskstats_show(struct seq_fil
 				"\n\n");
 	*/
  
-	disk_part_iter_init(&piter, gp, DISK_PITER_INCL_PART0);
+	disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
 	while ((hd = disk_part_iter_next(&piter))) {
 		cpu = part_stat_lock();
 		part_round_stats(cpu, hd);
diff -druNp linux-libre-2.6.29-gnu1/block/ioctl.c linux-libre-2.6.30-gnu1/block/ioctl.c
--- linux-libre-2.6.29-gnu1/block/ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -146,8 +146,6 @@ static int blk_ioctl_discard(struct bloc
 		struct bio *bio;
 
 		bio = bio_alloc(GFP_KERNEL, 0);
-		if (!bio)
-			return -ENOMEM;
 
 		bio->bi_end_io = blk_ioc_discard_endio;
 		bio->bi_bdev = bdev;
diff -druNp linux-libre-2.6.29-gnu1/block/Kconfig linux-libre-2.6.30-gnu1/block/Kconfig
--- linux-libre-2.6.29-gnu1/block/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -44,22 +44,6 @@ config LBD
 
 	  If unsure, say N.
 
-config BLK_DEV_IO_TRACE
-	bool "Support for tracing block io actions"
-	depends on SYSFS
-	select RELAY
-	select DEBUG_FS
-	select TRACEPOINTS
-	help
-	  Say Y here if you want to be able to trace the block layer actions
-	  on a given queue. Tracing allows you to see any traffic happening
-	  on a block device queue. For more information (and the userspace
-	  support tools needed), fetch the blktrace tools from:
-
-	  git://git.kernel.dk/blktrace.git
-
-	  If unsure, say N.
-
 config BLK_DEV_BSG
 	bool "Block layer SG support v4 (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
diff -druNp linux-libre-2.6.29-gnu1/block/Makefile linux-libre-2.6.30-gnu1/block/Makefile
--- linux-libre-2.6.29-gnu1/block/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,5 @@ obj-$(CONFIG_IOSCHED_AS)	+= as-iosched.o
 obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
 obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
 
-obj-$(CONFIG_BLK_DEV_IO_TRACE)	+= blktrace.o
 obj-$(CONFIG_BLOCK_COMPAT)	+= compat_ioctl.o
 obj-$(CONFIG_BLK_DEV_INTEGRITY)	+= blk-integrity.o
diff -druNp linux-libre-2.6.29-gnu1/block/scsi_ioctl.c linux-libre-2.6.30-gnu1/block/scsi_ioctl.c
--- linux-libre-2.6.29-gnu1/block/scsi_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/block/scsi_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -214,17 +214,6 @@ static int blk_fill_sghdr_rq(struct requ
 	return 0;
 }
 
-/*
- * unmap a request that was previously mapped to this sg_io_hdr. handles
- * both sg and non-sg sg_io_hdr.
- */
-static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
-{
-	blk_rq_unmap_user(rq->bio);
-	blk_put_request(rq);
-	return 0;
-}
-
 static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
 				 struct bio *bio)
 {
@@ -253,12 +242,12 @@ static int blk_complete_sghdr_rq(struct
 			ret = -EFAULT;
 	}
 
-	rq->bio = bio;
-	r = blk_unmap_sghdr_rq(rq, hdr);
-	if (ret)
-		r = ret;
+	r = blk_rq_unmap_user(bio);
+	if (!ret)
+		ret = r;
+	blk_put_request(rq);
 
-	return r;
+	return ret;
 }
 
 static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
@@ -301,6 +290,7 @@ static int sg_io(struct request_queue *q
 
 	if (hdr->iovec_count) {
 		const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
+		size_t iov_data_len;
 		struct sg_iovec *iov;
 
 		iov = kmalloc(size, GFP_KERNEL);
@@ -315,8 +305,18 @@ static int sg_io(struct request_queue *q
 			goto out;
 		}
 
+		/* SG_IO howto says that the shorter of the two wins */
+		iov_data_len = iov_length((struct iovec *)iov,
+					  hdr->iovec_count);
+		if (hdr->dxfer_len < iov_data_len) {
+			hdr->iovec_count = iov_shorten((struct iovec *)iov,
+						       hdr->iovec_count,
+						       hdr->dxfer_len);
+			iov_data_len = hdr->dxfer_len;
+		}
+
 		ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count,
-					  hdr->dxfer_len, GFP_KERNEL);
+					  iov_data_len, GFP_KERNEL);
 		kfree(iov);
 	} else if (hdr->dxfer_len)
 		ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
diff -druNp linux-libre-2.6.29-gnu1/CREDITS linux-libre-2.6.30-gnu1/CREDITS
--- linux-libre-2.6.29-gnu1/CREDITS	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/CREDITS	2009-06-09 23:05:27.000000000 -0400
@@ -495,6 +495,11 @@ S: Kopmansg 2
 S: 411 13  Goteborg
 S: Sweden
 
+N: Paul Bristow
+E: paul@paulbristow.net
+W: http://paulbristow.net/linux/idefloppy.html
+D: Maintainer of IDE/ATAPI floppy driver
+
 N: Dominik Brodowski
 E: linux@brodo.de
 W: http://www.brodo.de/
@@ -1407,8 +1412,8 @@ P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 31
 D: National Language Support
 D: Linux Internationalization Project
 D: German Localization for Linux and GNU software
-S: Kriemhildring 12a
-S: 65795 Hattersheim am Main
+S: Auf der Fittel 18
+S: 53347 Alfter
 S: Germany
 
 N: Christoph Hellwig
@@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
 S: Valladolid 47009
 S: Spain
 
+N: Gadi Oxman
+E: gadio@netvision.net.il
+D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
+
 N: Greg Page
 E: gpage@sovereign.org
 D: IPX development and support
@@ -3571,6 +3580,12 @@ N: Dirk Verworner
 D: Co-author of German book ``Linux-Kernel-Programmierung''
 D: Co-founder of Berlin Linux User Group
 
+N: Riku Voipio
+E: riku.voipio@iki.fi
+D: Author of PCA9532 LED and Fintek f75375s hwmon driver
+D: Some random ARM board patches
+S: Finland
+
 N: Patrick Volkerding
 E: volkerdi@ftp.cdrom.com
 D: Produced the Slackware distribution, updated the SVGAlib
diff -druNp linux-libre-2.6.29-gnu1/crypto/ablkcipher.c linux-libre-2.6.30-gnu1/crypto/ablkcipher.c
--- linux-libre-2.6.29-gnu1/crypto/ablkcipher.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/ablkcipher.c	2009-06-09 23:05:27.000000000 -0400
@@ -282,6 +282,25 @@ static struct crypto_alg *crypto_lookup_
 					  alg->cra_ablkcipher.ivsize))
 		return alg;
 
+	crypto_mod_put(alg);
+	alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED,
+				    mask & ~CRYPTO_ALG_TESTED);
+	if (IS_ERR(alg))
+		return alg;
+
+	if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+	    CRYPTO_ALG_TYPE_GIVCIPHER) {
+		if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) {
+			crypto_mod_put(alg);
+			alg = ERR_PTR(-ENOENT);
+		}
+		return alg;
+	}
+
+	BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+		 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+					     alg->cra_ablkcipher.ivsize));
+
 	return ERR_PTR(crypto_givcipher_default(alg, type, mask));
 }
 
diff -druNp linux-libre-2.6.29-gnu1/crypto/aead.c linux-libre-2.6.30-gnu1/crypto/aead.c
--- linux-libre-2.6.29-gnu1/crypto/aead.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/aead.c	2009-06-09 23:05:27.000000000 -0400
@@ -422,6 +422,22 @@ static struct crypto_alg *crypto_lookup_
 	if (!alg->cra_aead.ivsize)
 		return alg;
 
+	crypto_mod_put(alg);
+	alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED,
+				    mask & ~CRYPTO_ALG_TESTED);
+	if (IS_ERR(alg))
+		return alg;
+
+	if (alg->cra_type == &crypto_aead_type) {
+		if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) {
+			crypto_mod_put(alg);
+			alg = ERR_PTR(-ENOENT);
+		}
+		return alg;
+	}
+
+	BUG_ON(!alg->cra_aead.ivsize);
+
 	return ERR_PTR(crypto_nivaead_default(alg, type, mask));
 }
 
diff -druNp linux-libre-2.6.29-gnu1/crypto/ahash.c linux-libre-2.6.30-gnu1/crypto/ahash.c
--- linux-libre-2.6.29-gnu1/crypto/ahash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/ahash.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,10 +82,11 @@ int crypto_hash_walk_done(struct crypto_
 	if (err)
 		return err;
 
-	walk->offset = 0;
-
-	if (nbytes)
+	if (nbytes) {
+		walk->offset = 0;
+		walk->pg++;
 		return hash_walk_next(walk);
+	}
 
 	if (!walk->total)
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/crypto/algboss.c linux-libre-2.6.30-gnu1/crypto/algboss.c
--- linux-libre-2.6.29-gnu1/crypto/algboss.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/algboss.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@
  *
  */
 
-#include <linux/crypto.h>
+#include <crypto/internal/aead.h>
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/init.h>
@@ -206,8 +206,7 @@ static int cryptomgr_test(void *data)
 	u32 type = param->type;
 	int err = 0;
 
-	if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
-	      CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV))
+	if (type & CRYPTO_ALG_TESTED)
 		goto skiptest;
 
 	err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED);
@@ -223,6 +222,7 @@ static int cryptomgr_schedule_test(struc
 {
 	struct task_struct *thread;
 	struct crypto_test_param *param;
+	u32 type;
 
 	if (!try_module_get(THIS_MODULE))
 		goto err;
@@ -233,7 +233,19 @@ static int cryptomgr_schedule_test(struc
 
 	memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver));
 	memcpy(param->alg, alg->cra_name, sizeof(param->alg));
-	param->type = alg->cra_flags;
+	type = alg->cra_flags;
+
+	/* This piece of crap needs to disappear into per-type test hooks. */
+	if ((!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
+	       CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV) &&
+	     ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+	      CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+					  alg->cra_ablkcipher.ivsize)) ||
+	    (!((type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) &&
+	     alg->cra_type == &crypto_nivaead_type && alg->cra_aead.ivsize))
+		type |= CRYPTO_ALG_TESTED;
+
+	param->type = type;
 
 	thread = kthread_run(cryptomgr_test, param, "cryptomgr_test");
 	if (IS_ERR(thread))
diff -druNp linux-libre-2.6.29-gnu1/crypto/ansi_cprng.c linux-libre-2.6.30-gnu1/crypto/ansi_cprng.c
--- linux-libre-2.6.29-gnu1/crypto/ansi_cprng.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/ansi_cprng.c	2009-06-09 23:05:27.000000000 -0400
@@ -132,9 +132,15 @@ static int _get_more_prng_bytes(struct p
 			 */
 			if (!memcmp(ctx->rand_data, ctx->last_rand_data,
 					DEFAULT_BLK_SZ)) {
+				if (fips_enabled) {
+					panic("cprng %p Failed repetition check!\n",
+						ctx);
+				}
+
 				printk(KERN_ERR
 					"ctx %p Failed repetition check!\n",
 					ctx);
+
 				ctx->flags |= PRNG_NEED_RESET;
 				return -EINVAL;
 			}
@@ -338,7 +344,16 @@ static int cprng_init(struct crypto_tfm
 
 	spin_lock_init(&ctx->prng_lock);
 
-	return reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL);
+	if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0)
+		return -EINVAL;
+
+	/*
+	 * after allocation, we should always force the user to reset
+	 * so they don't inadvertently use the insecure default values
+	 * without specifying them intentially
+	 */
+	ctx->flags |= PRNG_NEED_RESET;
+	return 0;
 }
 
 static void cprng_exit(struct crypto_tfm *tfm)
diff -druNp linux-libre-2.6.29-gnu1/crypto/api.c linux-libre-2.6.30-gnu1/crypto/api.c
--- linux-libre-2.6.29-gnu1/crypto/api.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/api.c	2009-06-09 23:05:27.000000000 -0400
@@ -221,7 +221,8 @@ struct crypto_alg *crypto_larval_lookup(
 
 		request_module(name);
 
-		if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) &&
+		if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask &
+		      CRYPTO_ALG_NEED_FALLBACK) &&
 		    snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp))
 			request_module(tmp);
 
@@ -255,7 +256,7 @@ struct crypto_alg *crypto_alg_mod_lookup
 	struct crypto_alg *larval;
 	int ok;
 
-	if (!(mask & CRYPTO_ALG_TESTED)) {
+	if (!((type | mask) & CRYPTO_ALG_TESTED)) {
 		type |= CRYPTO_ALG_TESTED;
 		mask |= CRYPTO_ALG_TESTED;
 	}
@@ -464,8 +465,8 @@ err:
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_base);
 
-struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
-				     const struct crypto_type *frontend)
+void *crypto_create_tfm(struct crypto_alg *alg,
+			const struct crypto_type *frontend)
 {
 	char *mem;
 	struct crypto_tfm *tfm = NULL;
@@ -499,9 +500,9 @@ out_free_tfm:
 		crypto_shoot_alg(alg);
 	kfree(mem);
 out_err:
-	tfm = ERR_PTR(err);
+	mem = ERR_PTR(err);
 out:
-	return tfm;
+	return mem;
 }
 EXPORT_SYMBOL_GPL(crypto_create_tfm);
 
@@ -525,12 +526,11 @@ EXPORT_SYMBOL_GPL(crypto_create_tfm);
  *
  *	In case of error the return value is an error pointer.
  */
-struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
-				    const struct crypto_type *frontend,
-				    u32 type, u32 mask)
+void *crypto_alloc_tfm(const char *alg_name,
+		       const struct crypto_type *frontend, u32 type, u32 mask)
 {
 	struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
-	struct crypto_tfm *tfm;
+	void *tfm;
 	int err;
 
 	type &= frontend->maskclear;
diff -druNp linux-libre-2.6.29-gnu1/crypto/async_tx/async_tx.c linux-libre-2.6.30-gnu1/crypto/async_tx/async_tx.c
--- linux-libre-2.6.29-gnu1/crypto/async_tx/async_tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/async_tx/async_tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,7 +30,7 @@
 #ifdef CONFIG_DMA_ENGINE
 static int __init async_tx_init(void)
 {
-	dmaengine_get();
+	async_dmaengine_get();
 
 	printk(KERN_INFO "async_tx: api initialized (async)\n");
 
@@ -39,7 +39,7 @@ static int __init async_tx_init(void)
 
 static void __exit async_tx_exit(void)
 {
-	dmaengine_put();
+	async_dmaengine_put();
 }
 
 /**
@@ -56,7 +56,7 @@ __async_tx_find_channel(struct dma_async
 	if (depend_tx &&
 	    dma_has_cap(tx_type, depend_tx->chan->device->cap_mask))
 		return depend_tx->chan;
-	return dma_find_channel(tx_type);
+	return async_dma_find_channel(tx_type);
 }
 EXPORT_SYMBOL_GPL(__async_tx_find_channel);
 #else
diff -druNp linux-libre-2.6.29-gnu1/crypto/async_tx/async_xor.c linux-libre-2.6.30-gnu1/crypto/async_tx/async_xor.c
--- linux-libre-2.6.29-gnu1/crypto/async_tx/async_xor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/async_tx/async_xor.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,11 +30,8 @@
 #include <linux/raid/xor.h>
 #include <linux/async_tx.h>
 
-/* do_async_xor - dma map the pages and perform the xor with an engine.
- * 	This routine is marked __always_inline so it can be compiled away
- * 	when CONFIG_DMA_ENGINE=n
- */
-static __always_inline struct dma_async_tx_descriptor *
+/* do_async_xor - dma map the pages and perform the xor with an engine */
+static __async_inline struct dma_async_tx_descriptor *
 do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
 	     unsigned int offset, int src_cnt, size_t len,
 	     enum async_tx_flags flags,
diff -druNp linux-libre-2.6.29-gnu1/crypto/blkcipher.c linux-libre-2.6.30-gnu1/crypto/blkcipher.c
--- linux-libre-2.6.29-gnu1/crypto/blkcipher.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/blkcipher.c	2009-06-09 23:05:27.000000000 -0400
@@ -521,7 +521,7 @@ static int crypto_grab_nivcipher(struct
 	int err;
 
 	type = crypto_skcipher_type(type);
-	mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV;
+	mask = crypto_skcipher_mask(mask)| CRYPTO_ALG_GENIV;
 
 	alg = crypto_alg_mod_lookup(name, type, mask);
 	if (IS_ERR(alg))
diff -druNp linux-libre-2.6.29-gnu1/crypto/chainiv.c linux-libre-2.6.30-gnu1/crypto/chainiv.c
--- linux-libre-2.6.29-gnu1/crypto/chainiv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/chainiv.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 
 #include <crypto/internal/skcipher.h>
 #include <crypto/rng.h>
+#include <crypto/crypto_wq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -133,7 +134,7 @@ static int async_chainiv_schedule_work(s
 			goto out;
 	}
 
-	queued = schedule_work(&ctx->postponed);
+	queued = queue_work(kcrypto_wq, &ctx->postponed);
 	BUG_ON(!queued);
 
 out:
diff -druNp linux-libre-2.6.29-gnu1/crypto/cryptd.c linux-libre-2.6.30-gnu1/crypto/cryptd.c
--- linux-libre-2.6.29-gnu1/crypto/cryptd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/cryptd.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,30 +12,31 @@
 
 #include <crypto/algapi.h>
 #include <crypto/internal/hash.h>
+#include <crypto/cryptd.h>
+#include <crypto/crypto_wq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/mutex.h>
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 
-#define CRYPTD_MAX_QLEN 100
+#define CRYPTD_MAX_CPU_QLEN 100
 
-struct cryptd_state {
-	spinlock_t lock;
-	struct mutex mutex;
+struct cryptd_cpu_queue {
 	struct crypto_queue queue;
-	struct task_struct *task;
+	struct work_struct work;
+};
+
+struct cryptd_queue {
+	struct cryptd_cpu_queue *cpu_queue;
 };
 
 struct cryptd_instance_ctx {
 	struct crypto_spawn spawn;
-	struct cryptd_state *state;
+	struct cryptd_queue *queue;
 };
 
 struct cryptd_blkcipher_ctx {
@@ -54,11 +55,85 @@ struct cryptd_hash_request_ctx {
 	crypto_completion_t complete;
 };
 
-static inline struct cryptd_state *cryptd_get_state(struct crypto_tfm *tfm)
+static void cryptd_queue_worker(struct work_struct *work);
+
+static int cryptd_init_queue(struct cryptd_queue *queue,
+			     unsigned int max_cpu_qlen)
+{
+	int cpu;
+	struct cryptd_cpu_queue *cpu_queue;
+
+	queue->cpu_queue = alloc_percpu(struct cryptd_cpu_queue);
+	if (!queue->cpu_queue)
+		return -ENOMEM;
+	for_each_possible_cpu(cpu) {
+		cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+		crypto_init_queue(&cpu_queue->queue, max_cpu_qlen);
+		INIT_WORK(&cpu_queue->work, cryptd_queue_worker);
+	}
+	return 0;
+}
+
+static void cryptd_fini_queue(struct cryptd_queue *queue)
+{
+	int cpu;
+	struct cryptd_cpu_queue *cpu_queue;
+
+	for_each_possible_cpu(cpu) {
+		cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+		BUG_ON(cpu_queue->queue.qlen);
+	}
+	free_percpu(queue->cpu_queue);
+}
+
+static int cryptd_enqueue_request(struct cryptd_queue *queue,
+				  struct crypto_async_request *request)
+{
+	int cpu, err;
+	struct cryptd_cpu_queue *cpu_queue;
+
+	cpu = get_cpu();
+	cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+	err = crypto_enqueue_request(&cpu_queue->queue, request);
+	queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
+	put_cpu();
+
+	return err;
+}
+
+/* Called in workqueue context, do one real cryption work (via
+ * req->complete) and reschedule itself if there are more work to
+ * do. */
+static void cryptd_queue_worker(struct work_struct *work)
+{
+	struct cryptd_cpu_queue *cpu_queue;
+	struct crypto_async_request *req, *backlog;
+
+	cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+	/* Only handle one request at a time to avoid hogging crypto
+	 * workqueue. preempt_disable/enable is used to prevent
+	 * being preempted by cryptd_enqueue_request() */
+	preempt_disable();
+	backlog = crypto_get_backlog(&cpu_queue->queue);
+	req = crypto_dequeue_request(&cpu_queue->queue);
+	preempt_enable();
+
+	if (!req)
+		return;
+
+	if (backlog)
+		backlog->complete(backlog, -EINPROGRESS);
+	req->complete(req, 0);
+
+	if (cpu_queue->queue.qlen)
+		queue_work(kcrypto_wq, &cpu_queue->work);
+}
+
+static inline struct cryptd_queue *cryptd_get_queue(struct crypto_tfm *tfm)
 {
 	struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
 	struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst);
-	return ictx->state;
+	return ictx->queue;
 }
 
 static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent,
@@ -130,19 +205,13 @@ static int cryptd_blkcipher_enqueue(stru
 {
 	struct cryptd_blkcipher_request_ctx *rctx = ablkcipher_request_ctx(req);
 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
-	struct cryptd_state *state =
-		cryptd_get_state(crypto_ablkcipher_tfm(tfm));
-	int err;
+	struct cryptd_queue *queue;
 
+	queue = cryptd_get_queue(crypto_ablkcipher_tfm(tfm));
 	rctx->complete = req->base.complete;
 	req->base.complete = complete;
 
-	spin_lock_bh(&state->lock);
-	err = ablkcipher_enqueue_request(&state->queue, req);
-	spin_unlock_bh(&state->lock);
-
-	wake_up_process(state->task);
-	return err;
+	return cryptd_enqueue_request(queue, &req->base);
 }
 
 static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req)
@@ -176,21 +245,12 @@ static int cryptd_blkcipher_init_tfm(str
 static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm)
 {
 	struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm);
-	struct cryptd_state *state = cryptd_get_state(tfm);
-	int active;
-
-	mutex_lock(&state->mutex);
-	active = ablkcipher_tfm_in_queue(&state->queue,
-					 __crypto_ablkcipher_cast(tfm));
-	mutex_unlock(&state->mutex);
-
-	BUG_ON(active);
 
 	crypto_free_blkcipher(ctx->child);
 }
 
 static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
-						     struct cryptd_state *state)
+						     struct cryptd_queue *queue)
 {
 	struct crypto_instance *inst;
 	struct cryptd_instance_ctx *ctx;
@@ -213,7 +273,7 @@ static struct crypto_instance *cryptd_al
 	if (err)
 		goto out_free_inst;
 
-	ctx->state = state;
+	ctx->queue = queue;
 
 	memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
 
@@ -231,7 +291,7 @@ out_free_inst:
 }
 
 static struct crypto_instance *cryptd_alloc_blkcipher(
-	struct rtattr **tb, struct cryptd_state *state)
+	struct rtattr **tb, struct cryptd_queue *queue)
 {
 	struct crypto_instance *inst;
 	struct crypto_alg *alg;
@@ -241,7 +301,7 @@ static struct crypto_instance *cryptd_al
 	if (IS_ERR(alg))
 		return ERR_CAST(alg);
 
-	inst = cryptd_alloc_instance(alg, state);
+	inst = cryptd_alloc_instance(alg, queue);
 	if (IS_ERR(inst))
 		goto out_put_alg;
 
@@ -289,15 +349,6 @@ static int cryptd_hash_init_tfm(struct c
 static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm)
 {
 	struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm);
-	struct cryptd_state *state = cryptd_get_state(tfm);
-	int active;
-
-	mutex_lock(&state->mutex);
-	active = ahash_tfm_in_queue(&state->queue,
-				__crypto_ahash_cast(tfm));
-	mutex_unlock(&state->mutex);
-
-	BUG_ON(active);
 
 	crypto_free_hash(ctx->child);
 }
@@ -323,19 +374,13 @@ static int cryptd_hash_enqueue(struct ah
 {
 	struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
-	struct cryptd_state *state =
-		cryptd_get_state(crypto_ahash_tfm(tfm));
-	int err;
+	struct cryptd_queue *queue =
+		cryptd_get_queue(crypto_ahash_tfm(tfm));
 
 	rctx->complete = req->base.complete;
 	req->base.complete = complete;
 
-	spin_lock_bh(&state->lock);
-	err = ahash_enqueue_request(&state->queue, req);
-	spin_unlock_bh(&state->lock);
-
-	wake_up_process(state->task);
-	return err;
+	return cryptd_enqueue_request(queue, &req->base);
 }
 
 static void cryptd_hash_init(struct crypto_async_request *req_async, int err)
@@ -468,7 +513,7 @@ static int cryptd_hash_digest_enqueue(st
 }
 
 static struct crypto_instance *cryptd_alloc_hash(
-	struct rtattr **tb, struct cryptd_state *state)
+	struct rtattr **tb, struct cryptd_queue *queue)
 {
 	struct crypto_instance *inst;
 	struct crypto_alg *alg;
@@ -478,7 +523,7 @@ static struct crypto_instance *cryptd_al
 	if (IS_ERR(alg))
 		return ERR_PTR(PTR_ERR(alg));
 
-	inst = cryptd_alloc_instance(alg, state);
+	inst = cryptd_alloc_instance(alg, queue);
 	if (IS_ERR(inst))
 		goto out_put_alg;
 
@@ -502,7 +547,7 @@ out_put_alg:
 	return inst;
 }
 
-static struct cryptd_state state;
+static struct cryptd_queue queue;
 
 static struct crypto_instance *cryptd_alloc(struct rtattr **tb)
 {
@@ -514,9 +559,9 @@ static struct crypto_instance *cryptd_al
 
 	switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
 	case CRYPTO_ALG_TYPE_BLKCIPHER:
-		return cryptd_alloc_blkcipher(tb, &state);
+		return cryptd_alloc_blkcipher(tb, &queue);
 	case CRYPTO_ALG_TYPE_DIGEST:
-		return cryptd_alloc_hash(tb, &state);
+		return cryptd_alloc_hash(tb, &queue);
 	}
 
 	return ERR_PTR(-EINVAL);
@@ -537,82 +582,58 @@ static struct crypto_template cryptd_tmp
 	.module = THIS_MODULE,
 };
 
-static inline int cryptd_create_thread(struct cryptd_state *state,
-				       int (*fn)(void *data), const char *name)
+struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name,
+						  u32 type, u32 mask)
 {
-	spin_lock_init(&state->lock);
-	mutex_init(&state->mutex);
-	crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN);
+	char cryptd_alg_name[CRYPTO_MAX_ALG_NAME];
+	struct crypto_ablkcipher *tfm;
 
-	state->task = kthread_run(fn, state, name);
-	if (IS_ERR(state->task))
-		return PTR_ERR(state->task);
+	if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME,
+		     "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME)
+		return ERR_PTR(-EINVAL);
+	tfm = crypto_alloc_ablkcipher(cryptd_alg_name, type, mask);
+	if (IS_ERR(tfm))
+		return ERR_CAST(tfm);
+	if (crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_module != THIS_MODULE) {
+		crypto_free_ablkcipher(tfm);
+		return ERR_PTR(-EINVAL);
+	}
 
-	return 0;
+	return __cryptd_ablkcipher_cast(tfm);
 }
+EXPORT_SYMBOL_GPL(cryptd_alloc_ablkcipher);
 
-static inline void cryptd_stop_thread(struct cryptd_state *state)
+struct crypto_blkcipher *cryptd_ablkcipher_child(struct cryptd_ablkcipher *tfm)
 {
-	BUG_ON(state->queue.qlen);
-	kthread_stop(state->task);
+	struct cryptd_blkcipher_ctx *ctx = crypto_ablkcipher_ctx(&tfm->base);
+	return ctx->child;
 }
+EXPORT_SYMBOL_GPL(cryptd_ablkcipher_child);
 
-static int cryptd_thread(void *data)
+void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm)
 {
-	struct cryptd_state *state = data;
-	int stop;
-
-	current->flags |= PF_NOFREEZE;
-
-	do {
-		struct crypto_async_request *req, *backlog;
-
-		mutex_lock(&state->mutex);
-		__set_current_state(TASK_INTERRUPTIBLE);
-
-		spin_lock_bh(&state->lock);
-		backlog = crypto_get_backlog(&state->queue);
-		req = crypto_dequeue_request(&state->queue);
-		spin_unlock_bh(&state->lock);
-
-		stop = kthread_should_stop();
-
-		if (stop || req) {
-			__set_current_state(TASK_RUNNING);
-			if (req) {
-				if (backlog)
-					backlog->complete(backlog,
-							  -EINPROGRESS);
-				req->complete(req, 0);
-			}
-		}
-
-		mutex_unlock(&state->mutex);
-
-		schedule();
-	} while (!stop);
-
-	return 0;
+	crypto_free_ablkcipher(&tfm->base);
 }
+EXPORT_SYMBOL_GPL(cryptd_free_ablkcipher);
 
 static int __init cryptd_init(void)
 {
 	int err;
 
-	err = cryptd_create_thread(&state, cryptd_thread, "cryptd");
+	err = cryptd_init_queue(&queue, CRYPTD_MAX_CPU_QLEN);
 	if (err)
 		return err;
 
 	err = crypto_register_template(&cryptd_tmpl);
 	if (err)
-		kthread_stop(state.task);
+		cryptd_fini_queue(&queue);
 
 	return err;
 }
 
 static void __exit cryptd_exit(void)
 {
-	cryptd_stop_thread(&state);
+	cryptd_fini_queue(&queue);
 	crypto_unregister_template(&cryptd_tmpl);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/crypto/crypto_wq.c linux-libre-2.6.30-gnu1/crypto/crypto_wq.c
--- linux-libre-2.6.29-gnu1/crypto/crypto_wq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/crypto/crypto_wq.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * Workqueue for crypto subsystem
+ *
+ * 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 as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <crypto/algapi.h>
+#include <crypto/crypto_wq.h>
+
+struct workqueue_struct *kcrypto_wq;
+EXPORT_SYMBOL_GPL(kcrypto_wq);
+
+static int __init crypto_wq_init(void)
+{
+	kcrypto_wq = create_workqueue("crypto");
+	if (unlikely(!kcrypto_wq))
+		return -ENOMEM;
+	return 0;
+}
+
+static void __exit crypto_wq_exit(void)
+{
+	destroy_workqueue(kcrypto_wq);
+}
+
+module_init(crypto_wq_init);
+module_exit(crypto_wq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Workqueue for crypto subsystem");
diff -druNp linux-libre-2.6.29-gnu1/crypto/eseqiv.c linux-libre-2.6.30-gnu1/crypto/eseqiv.c
--- linux-libre-2.6.29-gnu1/crypto/eseqiv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/eseqiv.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,7 +153,8 @@ static int eseqiv_givencrypt(struct skci
 	if (err)
 		goto out;
 
-	eseqiv_complete2(req);
+	if (giv != req->giv)
+		eseqiv_complete2(req);
 
 out:
 	return err;
diff -druNp linux-libre-2.6.29-gnu1/crypto/gf128mul.c linux-libre-2.6.30-gnu1/crypto/gf128mul.c
--- linux-libre-2.6.29-gnu1/crypto/gf128mul.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/gf128mul.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org>
  *
  * Based on Dr Brian Gladman's (GPL'd) work published at
- * http://fp.gladman.plus.com/cryptography_technology/index.htm
+ * http://gladman.plushost.co.uk/oldsite/cryptography_technology/index.php
  * See the original copyright notice below.
  *
  * This program is free software; you can redistribute it and/or modify it
diff -druNp linux-libre-2.6.29-gnu1/crypto/internal.h linux-libre-2.6.30-gnu1/crypto/internal.h
--- linux-libre-2.6.29-gnu1/crypto/internal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/internal.h	2009-06-09 23:05:27.000000000 -0400
@@ -109,8 +109,10 @@ void crypto_alg_tested(const char *name,
 void crypto_shoot_alg(struct crypto_alg *alg);
 struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
 				      u32 mask);
-struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
-				     const struct crypto_type *frontend);
+void *crypto_create_tfm(struct crypto_alg *alg,
+			const struct crypto_type *frontend);
+void *crypto_alloc_tfm(const char *alg_name,
+		       const struct crypto_type *frontend, u32 type, u32 mask);
 
 int crypto_register_instance(struct crypto_template *tmpl,
 			     struct crypto_instance *inst);
diff -druNp linux-libre-2.6.29-gnu1/crypto/Kconfig linux-libre-2.6.30-gnu1/crypto/Kconfig
--- linux-libre-2.6.29-gnu1/crypto/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,7 @@ config CRYPTO_BLKCIPHER2
 	tristate
 	select CRYPTO_ALGAPI2
 	select CRYPTO_RNG2
+	select CRYPTO_WORKQUEUE
 
 config CRYPTO_HASH
 	tristate
@@ -75,6 +76,10 @@ config CRYPTO_RNG2
 	tristate
 	select CRYPTO_ALGAPI2
 
+config CRYPTO_PCOMP
+	tristate
+	select CRYPTO_ALGAPI2
+
 config CRYPTO_MANAGER
 	tristate "Cryptographic algorithm manager"
 	select CRYPTO_MANAGER2
@@ -87,6 +92,7 @@ config CRYPTO_MANAGER2
 	select CRYPTO_AEAD2
 	select CRYPTO_HASH2
 	select CRYPTO_BLKCIPHER2
+	select CRYPTO_PCOMP
 
 config CRYPTO_GF128MUL
 	tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
@@ -106,11 +112,15 @@ config CRYPTO_NULL
 	help
 	  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_WORKQUEUE
+       tristate
+
 config CRYPTO_CRYPTD
 	tristate "Software async crypto daemon"
 	select CRYPTO_BLKCIPHER
 	select CRYPTO_HASH
 	select CRYPTO_MANAGER
+	select CRYPTO_WORKQUEUE
 	help
 	  This is a generic software asynchronous crypto daemon that
 	  converts an arbitrary synchronous software crypto algorithm
@@ -470,6 +480,31 @@ config CRYPTO_AES_X86_64
 
 	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
+config CRYPTO_AES_NI_INTEL
+	tristate "AES cipher algorithms (AES-NI)"
+	depends on (X86 || UML_X86) && 64BIT
+	select CRYPTO_AES_X86_64
+	select CRYPTO_CRYPTD
+	select CRYPTO_ALGAPI
+	help
+	  Use Intel AES-NI instructions for AES algorithm.
+
+	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
+	  algorithm.
+
+	  Rijndael appears to be consistently a very good performer in
+	  both hardware and software across a wide range of computing
+	  environments regardless of its use in feedback or non-feedback
+	  modes. Its key setup time is excellent, and its key agility is
+	  good. Rijndael's very low memory requirements make it very well
+	  suited for restricted-space environments, in which it also
+	  demonstrates excellent performance. Rijndael's operations are
+	  among the easiest to defend against power and timing attacks.
+
+	  The AES specifies three key sizes: 128, 192 and 256 bits
+
+	  See <http://csrc.nist.gov/encryption/aes/> for more information.
+
 config CRYPTO_ANUBIS
 	tristate "Anubis cipher algorithm"
 	select CRYPTO_ALGAPI
@@ -714,6 +749,15 @@ config CRYPTO_DEFLATE
 
 	  You will most probably want this if using IPSec.
 
+config CRYPTO_ZLIB
+	tristate "Zlib compression algorithm"
+	select CRYPTO_PCOMP
+	select ZLIB_INFLATE
+	select ZLIB_DEFLATE
+	select NLATTR
+	help
+	  This is the zlib algorithm.
+
 config CRYPTO_LZO
 	tristate "LZO compression algorithm"
 	select CRYPTO_ALGAPI
diff -druNp linux-libre-2.6.29-gnu1/crypto/Makefile linux-libre-2.6.30-gnu1/crypto/Makefile
--- linux-libre-2.6.29-gnu1/crypto/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,8 @@
 obj-$(CONFIG_CRYPTO) += crypto.o
 crypto-objs := api.o cipher.o digest.o compress.o
 
+obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
+
 obj-$(CONFIG_CRYPTO_FIPS) += fips.o
 
 crypto_algapi-$(CONFIG_PROC_FS) += proc.o
@@ -25,6 +27,8 @@ crypto_hash-objs += ahash.o
 crypto_hash-objs += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
+obj-$(CONFIG_CRYPTO_PCOMP) += pcompress.o
+
 cryptomgr-objs := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
@@ -70,6 +74,7 @@ obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
 obj-$(CONFIG_CRYPTO_SEED) += seed.o
 obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
 obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
+obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
 obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
diff -druNp linux-libre-2.6.29-gnu1/crypto/pcompress.c linux-libre-2.6.30-gnu1/crypto/pcompress.c
--- linux-libre-2.6.29-gnu1/crypto/pcompress.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/crypto/pcompress.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,97 @@
+/*
+ * Cryptographic API.
+ *
+ * Partial (de)compression operations.
+ *
+ * Copyright 2008 Sony 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+
+#include <crypto/compress.h>
+
+#include "internal.h"
+
+
+static int crypto_pcomp_init(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+	return 0;
+}
+
+static unsigned int crypto_pcomp_extsize(struct crypto_alg *alg,
+					 const struct crypto_type *frontend)
+{
+	return alg->cra_ctxsize;
+}
+
+static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm,
+				 const struct crypto_type *frontend)
+{
+	return 0;
+}
+
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+	__attribute__ ((unused));
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+{
+	seq_printf(m, "type         : pcomp\n");
+}
+
+static const struct crypto_type crypto_pcomp_type = {
+	.extsize	= crypto_pcomp_extsize,
+	.init		= crypto_pcomp_init,
+	.init_tfm	= crypto_pcomp_init_tfm,
+#ifdef CONFIG_PROC_FS
+	.show		= crypto_pcomp_show,
+#endif
+	.maskclear	= ~CRYPTO_ALG_TYPE_MASK,
+	.maskset	= CRYPTO_ALG_TYPE_MASK,
+	.type		= CRYPTO_ALG_TYPE_PCOMPRESS,
+	.tfmsize	= offsetof(struct crypto_pcomp, base),
+};
+
+struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type,
+					u32 mask)
+{
+	return crypto_alloc_tfm(alg_name, &crypto_pcomp_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_pcomp);
+
+int crypto_register_pcomp(struct pcomp_alg *alg)
+{
+	struct crypto_alg *base = &alg->base;
+
+	base->cra_type = &crypto_pcomp_type;
+	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+	base->cra_flags |= CRYPTO_ALG_TYPE_PCOMPRESS;
+
+	return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_pcomp);
+
+int crypto_unregister_pcomp(struct pcomp_alg *alg)
+{
+	return crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_pcomp);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Partial (de)compression type");
+MODULE_AUTHOR("Sony Corporation");
diff -druNp linux-libre-2.6.29-gnu1/crypto/sha256_generic.c linux-libre-2.6.30-gnu1/crypto/sha256_generic.c
--- linux-libre-2.6.29-gnu1/crypto/sha256_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/sha256_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  * Cryptographic API.
  *
  * SHA-256, as specified in
- * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
+ * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
  *
  * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
  *
diff -druNp linux-libre-2.6.29-gnu1/crypto/shash.c linux-libre-2.6.30-gnu1/crypto/shash.c
--- linux-libre-2.6.29-gnu1/crypto/shash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/shash.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,15 +18,10 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 
-static const struct crypto_type crypto_shash_type;
-
-static inline struct crypto_shash *__crypto_shash_cast(struct crypto_tfm *tfm)
-{
-	return container_of(tfm, struct crypto_shash, base);
-}
-
 #include "internal.h"
 
+static const struct crypto_type crypto_shash_type;
+
 static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
 				  unsigned int keylen)
 {
@@ -82,6 +77,9 @@ static int shash_update_unaligned(struct
 	u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
 		__attribute__ ((aligned));
 
+	if (unaligned_len > len)
+		unaligned_len = len;
+
 	memcpy(buf, data, unaligned_len);
 
 	return shash->update(desc, buf, unaligned_len) ?:
@@ -282,8 +280,7 @@ static int crypto_init_shash_ops_async(s
 	if (!crypto_mod_get(calg))
 		return -EAGAIN;
 
-	shash = __crypto_shash_cast(crypto_create_tfm(
-		calg, &crypto_shash_type));
+	shash = crypto_create_tfm(calg, &crypto_shash_type);
 	if (IS_ERR(shash)) {
 		crypto_mod_put(calg);
 		return PTR_ERR(shash);
@@ -391,8 +388,7 @@ static int crypto_init_shash_ops_compat(
 	if (!crypto_mod_get(calg))
 		return -EAGAIN;
 
-	shash = __crypto_shash_cast(crypto_create_tfm(
-		calg, &crypto_shash_type));
+	shash = crypto_create_tfm(calg, &crypto_shash_type);
 	if (IS_ERR(shash)) {
 		crypto_mod_put(calg);
 		return PTR_ERR(shash);
@@ -442,8 +438,6 @@ static unsigned int crypto_shash_ctxsize
 static int crypto_shash_init_tfm(struct crypto_tfm *tfm,
 				 const struct crypto_type *frontend)
 {
-	if (frontend->type != CRYPTO_ALG_TYPE_SHASH)
-		return -EINVAL;
 	return 0;
 }
 
@@ -482,8 +476,7 @@ static const struct crypto_type crypto_s
 struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
 					u32 mask)
 {
-	return __crypto_shash_cast(
-		crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask));
+	return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_shash);
 
diff -druNp linux-libre-2.6.29-gnu1/crypto/tcrypt.c linux-libre-2.6.30-gnu1/crypto/tcrypt.c
--- linux-libre-2.6.29-gnu1/crypto/tcrypt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/tcrypt.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,7 +53,7 @@ static char *check[] = {
 	"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
 	"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
 	"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
-	"lzo", "cts", NULL
+	"lzo", "cts", "zlib", NULL
 };
 
 static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
@@ -661,6 +661,10 @@ static void do_test(int m)
 		tcrypt_test("ecb(seed)");
 		break;
 
+	case 44:
+		tcrypt_test("zlib");
+		break;
+
 	case 100:
 		tcrypt_test("hmac(md5)");
 		break;
diff -druNp linux-libre-2.6.29-gnu1/crypto/testmgr.c linux-libre-2.6.30-gnu1/crypto/testmgr.c
--- linux-libre-2.6.29-gnu1/crypto/testmgr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/testmgr.c	2009-06-09 23:05:27.000000000 -0400
@@ -72,6 +72,13 @@ struct comp_test_suite {
 	} comp, decomp;
 };
 
+struct pcomp_test_suite {
+	struct {
+		struct pcomp_testvec *vecs;
+		unsigned int count;
+	} comp, decomp;
+};
+
 struct hash_test_suite {
 	struct hash_testvec *vecs;
 	unsigned int count;
@@ -86,6 +93,7 @@ struct alg_test_desc {
 		struct aead_test_suite aead;
 		struct cipher_test_suite cipher;
 		struct comp_test_suite comp;
+		struct pcomp_test_suite pcomp;
 		struct hash_test_suite hash;
 	} suite;
 };
@@ -898,6 +906,159 @@ out:
 	return ret;
 }
 
+static int test_pcomp(struct crypto_pcomp *tfm,
+		      struct pcomp_testvec *ctemplate,
+		      struct pcomp_testvec *dtemplate, int ctcount,
+		      int dtcount)
+{
+	const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+	unsigned int i;
+	char result[COMP_BUF_SIZE];
+	int error;
+
+	for (i = 0; i < ctcount; i++) {
+		struct comp_request req;
+
+		error = crypto_compress_setup(tfm, ctemplate[i].params,
+					      ctemplate[i].paramsize);
+		if (error) {
+			pr_err("alg: pcomp: compression setup failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		error = crypto_compress_init(tfm);
+		if (error) {
+			pr_err("alg: pcomp: compression init failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		memset(result, 0, sizeof(result));
+
+		req.next_in = ctemplate[i].input;
+		req.avail_in = ctemplate[i].inlen / 2;
+		req.next_out = result;
+		req.avail_out = ctemplate[i].outlen / 2;
+
+		error = crypto_compress_update(tfm, &req);
+		if (error && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: compression update failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		/* Add remaining input data */
+		req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+		error = crypto_compress_update(tfm, &req);
+		if (error && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: compression update failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		/* Provide remaining output space */
+		req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+		error = crypto_compress_final(tfm, &req);
+		if (error) {
+			pr_err("alg: pcomp: compression final failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+			pr_err("alg: comp: Compression test %d failed for %s: "
+			       "output len = %d (expected %d)\n", i + 1, algo,
+			       COMP_BUF_SIZE - req.avail_out,
+			       ctemplate[i].outlen);
+			return -EINVAL;
+		}
+
+		if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+			pr_err("alg: pcomp: Compression test %d failed for "
+			       "%s\n", i + 1, algo);
+			hexdump(result, ctemplate[i].outlen);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < dtcount; i++) {
+		struct comp_request req;
+
+		error = crypto_decompress_setup(tfm, dtemplate[i].params,
+						dtemplate[i].paramsize);
+		if (error) {
+			pr_err("alg: pcomp: decompression setup failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		error = crypto_decompress_init(tfm);
+		if (error) {
+			pr_err("alg: pcomp: decompression init failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		memset(result, 0, sizeof(result));
+
+		req.next_in = dtemplate[i].input;
+		req.avail_in = dtemplate[i].inlen / 2;
+		req.next_out = result;
+		req.avail_out = dtemplate[i].outlen / 2;
+
+		error = crypto_decompress_update(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression update failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		/* Add remaining input data */
+		req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+		error = crypto_decompress_update(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression update failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		/* Provide remaining output space */
+		req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+		error = crypto_decompress_final(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression final failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+			pr_err("alg: comp: Decompression test %d failed for "
+			       "%s: output len = %d (expected %d)\n", i + 1,
+			       algo, COMP_BUF_SIZE - req.avail_out,
+			       dtemplate[i].outlen);
+			return -EINVAL;
+		}
+
+		if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+			pr_err("alg: pcomp: Decompression test %d failed for "
+			       "%s\n", i + 1, algo);
+			hexdump(result, dtemplate[i].outlen);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
 			 u32 type, u32 mask)
 {
@@ -1007,6 +1168,28 @@ static int alg_test_comp(const struct al
 	return err;
 }
 
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+			  u32 type, u32 mask)
+{
+	struct crypto_pcomp *tfm;
+	int err;
+
+	tfm = crypto_alloc_pcomp(driver, type, mask);
+	if (IS_ERR(tfm)) {
+		pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+		       driver, PTR_ERR(tfm));
+		return PTR_ERR(tfm);
+	}
+
+	err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+			 desc->suite.pcomp.decomp.vecs,
+			 desc->suite.pcomp.comp.count,
+			 desc->suite.pcomp.decomp.count);
+
+	crypto_free_pcomp(tfm);
+	return err;
+}
+
 static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
 			 u32 type, u32 mask)
 {
@@ -1835,6 +2018,21 @@ static const struct alg_test_desc alg_te
 				}
 			}
 		}
+	}, {
+		.alg = "zlib",
+		.test = alg_test_pcomp,
+		.suite = {
+			.pcomp = {
+				.comp = {
+					.vecs = zlib_comp_tv_template,
+					.count = ZLIB_COMP_TEST_VECTORS
+				},
+				.decomp = {
+					.vecs = zlib_decomp_tv_template,
+					.count = ZLIB_DECOMP_TEST_VECTORS
+				}
+			}
+		}
 	}
 };
 
diff -druNp linux-libre-2.6.29-gnu1/crypto/testmgr.h linux-libre-2.6.30-gnu1/crypto/testmgr.h
--- linux-libre-2.6.29-gnu1/crypto/testmgr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/testmgr.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,11 @@
 #ifndef _CRYPTO_TESTMGR_H
 #define _CRYPTO_TESTMGR_H
 
+#include <linux/netlink.h>
+#include <linux/zlib.h>
+
+#include <crypto/compress.h>
+
 #define MAX_DIGEST_SIZE		64
 #define MAX_TAP			8
 
@@ -8347,10 +8352,19 @@ struct comp_testvec {
 	char output[COMP_BUF_SIZE];
 };
 
+struct pcomp_testvec {
+	void *params;
+	unsigned int paramsize;
+	int inlen, outlen;
+	char input[COMP_BUF_SIZE];
+	char output[COMP_BUF_SIZE];
+};
+
 /*
  * Deflate test vectors (null-terminated strings).
  * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
  */
+
 #define DEFLATE_COMP_TEST_VECTORS 2
 #define DEFLATE_DECOMP_TEST_VECTORS 2
 
@@ -8417,6 +8431,139 @@ static struct comp_testvec deflate_decom
 		.inlen	= 38,
 		.outlen	= 70,
 		.input	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+			  "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+			  "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+			  "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+			  "\x71\xbc\x08\x2b\x01\x00",
+		.output	= "Join us now and share the software "
+			"Join us now and share the software ",
+	},
+};
+
+#define ZLIB_COMP_TEST_VECTORS 2
+#define ZLIB_DECOMP_TEST_VECTORS 2
+
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_comp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_LEVEL,
+		},
+		.val			= Z_DEFAULT_COMPRESSION,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_METHOD,
+		},
+		.val			= Z_DEFLATED,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_MEMLEVEL,
+		},
+		.val			= MAX_MEM_LEVEL,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_STRATEGY,
+		},
+		.val			= Z_DEFAULT_STRATEGY,
+	}
+};
+
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_decomp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_DECOMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}
+};
+
+static struct pcomp_testvec zlib_comp_tv_template[] = {
+	{
+		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
+		.inlen	= 70,
+		.outlen	= 38,
+		.input	= "Join us now and share the software "
+			"Join us now and share the software ",
+		.output	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+			  "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+			  "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+			  "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+			  "\x71\xbc\x08\x2b\x01\x00",
+	}, {
+		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
+		.inlen	= 191,
+		.outlen	= 122,
+		.input	= "This document describes a compression method based on the DEFLATE"
+			"compression algorithm.  This document defines the application of "
+			"the DEFLATE algorithm to the IP Payload Compression Protocol.",
+		.output	= "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+			  "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+			  "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+			  "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+			  "\x68\x12\x51\xae\x76\x67\xd6\x27"
+			  "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+			  "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+			  "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+			  "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+			  "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+			  "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+			  "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+			  "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+			  "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+			  "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+			  "\xfa\x02",
+	},
+};
+
+static struct pcomp_testvec zlib_decomp_tv_template[] = {
+	{
+		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
+		.inlen	= 122,
+		.outlen	= 191,
+		.input	= "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+			  "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+			  "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+			  "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+			  "\x68\x12\x51\xae\x76\x67\xd6\x27"
+			  "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+			  "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+			  "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+			  "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+			  "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+			  "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+			  "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+			  "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+			  "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+			  "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+			  "\xfa\x02",
+		.output	= "This document describes a compression method based on the DEFLATE"
+			"compression algorithm.  This document defines the application of "
+			"the DEFLATE algorithm to the IP Payload Compression Protocol.",
+	}, {
+		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
+		.inlen	= 38,
+		.outlen	= 70,
+		.input	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
 			  "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
 			  "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
 			  "\x48\x55\x28\xce\x4f\x2b\x29\x07"
diff -druNp linux-libre-2.6.29-gnu1/crypto/xor.c linux-libre-2.6.30-gnu1/crypto/xor.c
--- linux-libre-2.6.29-gnu1/crypto/xor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/crypto/xor.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,8 +18,8 @@
 
 #define BH_TRACE 0
 #include <linux/module.h>
-#include <linux/raid/md.h>
 #include <linux/raid/xor.h>
+#include <linux/jiffies.h>
 #include <asm/xor.h>
 
 /* The xor routines to use.  */
diff -druNp linux-libre-2.6.29-gnu1/crypto/zlib.c linux-libre-2.6.30-gnu1/crypto/zlib.c
--- linux-libre-2.6.29-gnu1/crypto/zlib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/crypto/zlib.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,378 @@
+/*
+ * Cryptographic API.
+ *
+ * Zlib algorithm
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * Based on deflate.c, which is
+ * Copyright (c) 2003 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.
+ *
+ * FIXME: deflate transforms will require up to a total of about 436k of kernel
+ * memory on i386 (390k for compression, the rest for decompression), as the
+ * current zlib kernel code uses a worst case pre-allocation system by default.
+ * This needs to be fixed so that the amount of memory required is properly
+ * related to the winbits and memlevel parameters.
+ */
+
+#define pr_fmt(fmt)	"%s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/zlib.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+
+#include <crypto/internal/compress.h>
+
+#include <net/netlink.h>
+
+
+struct zlib_ctx {
+	struct z_stream_s comp_stream;
+	struct z_stream_s decomp_stream;
+	int decomp_windowBits;
+};
+
+
+static void zlib_comp_exit(struct zlib_ctx *ctx)
+{
+	struct z_stream_s *stream = &ctx->comp_stream;
+
+	if (stream->workspace) {
+		zlib_deflateEnd(stream);
+		vfree(stream->workspace);
+		stream->workspace = NULL;
+	}
+}
+
+static void zlib_decomp_exit(struct zlib_ctx *ctx)
+{
+	struct z_stream_s *stream = &ctx->decomp_stream;
+
+	if (stream->workspace) {
+		zlib_inflateEnd(stream);
+		kfree(stream->workspace);
+		stream->workspace = NULL;
+	}
+}
+
+static int zlib_init(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static void zlib_exit(struct crypto_tfm *tfm)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	zlib_comp_exit(ctx);
+	zlib_decomp_exit(ctx);
+}
+
+
+static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
+			       unsigned int len)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &ctx->comp_stream;
+	struct nlattr *tb[ZLIB_COMP_MAX + 1];
+	size_t workspacesize;
+	int ret;
+
+	ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
+
+	zlib_comp_exit(ctx);
+
+	workspacesize = zlib_deflate_workspacesize();
+	stream->workspace = vmalloc(workspacesize);
+	if (!stream->workspace)
+		return -ENOMEM;
+
+	memset(stream->workspace, 0, workspacesize);
+	ret = zlib_deflateInit2(stream,
+				tb[ZLIB_COMP_LEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_LEVEL])
+					: Z_DEFAULT_COMPRESSION,
+				tb[ZLIB_COMP_METHOD]
+					? nla_get_u32(tb[ZLIB_COMP_METHOD])
+					: Z_DEFLATED,
+				tb[ZLIB_COMP_WINDOWBITS]
+					? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS])
+					: MAX_WBITS,
+				tb[ZLIB_COMP_MEMLEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL])
+					: DEF_MEM_LEVEL,
+				tb[ZLIB_COMP_STRATEGY]
+					? nla_get_u32(tb[ZLIB_COMP_STRATEGY])
+					: Z_DEFAULT_STRATEGY);
+	if (ret != Z_OK) {
+		vfree(stream->workspace);
+		stream->workspace = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int zlib_compress_init(struct crypto_pcomp *tfm)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	ret = zlib_deflateReset(stream);
+	if (ret != Z_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int zlib_compress_update(struct crypto_pcomp *tfm,
+				struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_deflate(stream, Z_NO_FLUSH);
+	switch (ret) {
+	case Z_OK:
+		break;
+
+	case Z_BUF_ERROR:
+		pr_debug("zlib_deflate could not make progress\n");
+		return -EAGAIN;
+
+	default:
+		pr_debug("zlib_deflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+static int zlib_compress_final(struct crypto_pcomp *tfm,
+			       struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_deflate(stream, Z_FINISH);
+	if (ret != Z_STREAM_END) {
+		pr_debug("zlib_deflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+
+static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
+				 unsigned int len)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &ctx->decomp_stream;
+	struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
+	int ret = 0;
+
+	ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
+
+	zlib_decomp_exit(ctx);
+
+	ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
+				 ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
+				 : DEF_WBITS;
+
+	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	if (!stream->workspace)
+		return -ENOMEM;
+
+	ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
+	if (ret != Z_OK) {
+		kfree(stream->workspace);
+		stream->workspace = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int zlib_decompress_init(struct crypto_pcomp *tfm)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	ret = zlib_inflateReset(stream);
+	if (ret != Z_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int zlib_decompress_update(struct crypto_pcomp *tfm,
+				  struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+	switch (ret) {
+	case Z_OK:
+	case Z_STREAM_END:
+		break;
+
+	case Z_BUF_ERROR:
+		pr_debug("zlib_inflate could not make progress\n");
+		return -EAGAIN;
+
+	default:
+		pr_debug("zlib_inflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+static int zlib_decompress_final(struct crypto_pcomp *tfm,
+				 struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	if (dctx->decomp_windowBits < 0) {
+		ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+		/*
+		 * Work around a bug in zlib, which sometimes wants to taste an
+		 * extra byte when being used in the (undocumented) raw deflate
+		 * mode. (From USAGI).
+		 */
+		if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
+			const void *saved_next_in = stream->next_in;
+			u8 zerostuff = 0;
+
+			stream->next_in = &zerostuff;
+			stream->avail_in = 1;
+			ret = zlib_inflate(stream, Z_FINISH);
+			stream->next_in = saved_next_in;
+			stream->avail_in = 0;
+		}
+	} else
+		ret = zlib_inflate(stream, Z_FINISH);
+	if (ret != Z_STREAM_END) {
+		pr_debug("zlib_inflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+
+static struct pcomp_alg zlib_alg = {
+	.compress_setup		= zlib_compress_setup,
+	.compress_init		= zlib_compress_init,
+	.compress_update	= zlib_compress_update,
+	.compress_final		= zlib_compress_final,
+	.decompress_setup	= zlib_decompress_setup,
+	.decompress_init	= zlib_decompress_init,
+	.decompress_update	= zlib_decompress_update,
+	.decompress_final	= zlib_decompress_final,
+
+	.base			= {
+		.cra_name	= "zlib",
+		.cra_flags	= CRYPTO_ALG_TYPE_PCOMPRESS,
+		.cra_ctxsize	= sizeof(struct zlib_ctx),
+		.cra_module	= THIS_MODULE,
+		.cra_init	= zlib_init,
+		.cra_exit	= zlib_exit,
+	}
+};
+
+static int __init zlib_mod_init(void)
+{
+	return crypto_register_pcomp(&zlib_alg);
+}
+
+static void __exit zlib_mod_fini(void)
+{
+	crypto_unregister_pcomp(&zlib_alg);
+}
+
+module_init(zlib_mod_init);
+module_exit(zlib_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Zlib Compression Algorithm");
+MODULE_AUTHOR("Sony Corporation");
diff -druNp linux-libre-2.6.29-gnu1/Documentation/00-INDEX linux-libre-2.6.30-gnu1/Documentation/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -86,6 +86,8 @@ cachetlb.txt
 	- describes the cache/TLB flushing interfaces Linux uses.
 cdrom/
 	- directory with information on the CD-ROM drivers that Linux has.
+cgroups/
+	- cgroups features, including cpusets and memory controller.
 connector/
 	- docs on the netlink based userspace<->kernel space communication mod.
 console/
@@ -98,8 +100,6 @@ cpu-load.txt
 	- document describing how CPU load statistics are collected.
 cpuidle/
 	- info on CPU_IDLE, CPU idle state management subsystem.
-cpusets.txt
-	- documents the cpusets feature; assign CPUs and Mem to a set of tasks.
 cputopology.txt
 	- documentation on how CPU topology info is exported via sysfs.
 cris/
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/debugfs-kmemtrace linux-libre-2.6.30-gnu1/Documentation/ABI/testing/debugfs-kmemtrace
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/debugfs-kmemtrace	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/debugfs-kmemtrace	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,71 @@
+What:		/sys/kernel/debug/kmemtrace/
+Date:		July 2008
+Contact:	Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
+Description:
+
+In kmemtrace-enabled kernels, the following files are created:
+
+/sys/kernel/debug/kmemtrace/
+	cpu<n>		(0400)	Per-CPU tracing data, see below. (binary)
+	total_overruns	(0400)	Total number of bytes which were dropped from
+				cpu<n> files because of full buffer condition,
+				non-binary. (text)
+	abi_version	(0400)	Kernel's kmemtrace ABI version. (text)
+
+Each per-CPU file should be read according to the relay interface. That is,
+the reader should set affinity to that specific CPU and, as currently done by
+the userspace application (though there are other methods), use poll() with
+an infinite timeout before every read(). Otherwise, erroneous data may be
+read. The binary data has the following _core_ format:
+
+	Event ID	(1 byte)	Unsigned integer, one of:
+		0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
+		1 - represents a freeing of previously allocated memory
+		    (KMEMTRACE_EVENT_FREE)
+	Type ID		(1 byte)	Unsigned integer, one of:
+		0 - this is a kmalloc() / kfree()
+		1 - this is a kmem_cache_alloc() / kmem_cache_free()
+		2 - this is a __get_free_pages() et al.
+	Event size	(2 bytes)	Unsigned integer representing the
+					size of this event. Used to extend
+					kmemtrace. Discard the bytes you
+					don't know about.
+	Sequence number	(4 bytes)	Signed integer used to reorder data
+					logged on SMP machines. Wraparound
+					must be taken into account, although
+					it is unlikely.
+	Caller address	(8 bytes)	Return address to the caller.
+	Pointer to mem	(8 bytes)	Pointer to target memory area. Can be
+					NULL, but not all such calls might be
+					recorded.
+
+In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
+
+	Requested bytes	(8 bytes)	Total number of requested bytes,
+					unsigned, must not be zero.
+	Allocated bytes (8 bytes)	Total number of actually allocated
+					bytes, unsigned, must not be lower
+					than requested bytes.
+	Requested flags	(4 bytes)	GFP flags supplied by the caller.
+	Target CPU	(4 bytes)	Signed integer, valid for event id 1.
+					If equal to -1, target CPU is the same
+					as origin CPU, but the reverse might
+					not be true.
+
+The data is made available in the same endianness the machine has.
+
+Other event ids and type ids may be defined and added. Other fields may be
+added by increasing event size, but see below for details.
+Every modification to the ABI, including new id definitions, are followed
+by bumping the ABI version by one.
+
+Adding new data to the packet (features) is done at the end of the mandatory
+data:
+	Feature size	(2 byte)
+	Feature ID	(1 byte)
+	Feature data	(Feature size - 3 bytes)
+
+
+Users:
+	kmemtrace-user - git://repo.or.cz/kmemtrace-user.git
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/debugfs-pktcdvd linux-libre-2.6.30-gnu1/Documentation/ABI/testing/debugfs-pktcdvd
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/debugfs-pktcdvd	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/debugfs-pktcdvd	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,4 @@
-What:           /debug/pktcdvd/pktcdvd[0-7]
+What:           /sys/kernel/debug/pktcdvd/pktcdvd[0-7]
 Date:           Oct. 2006
 KernelVersion:  2.6.20
 Contact:        Thomas Maier <balagi@justmail.de>
@@ -10,10 +10,10 @@ debugfs interface
 The pktcdvd module (packet writing driver) creates
 these files in debugfs:
 
-/debug/pktcdvd/pktcdvd[0-7]/
+/sys/kernel/debug/pktcdvd/pktcdvd[0-7]/
     info            (0444) Lots of driver statistics and infos.
 
 Example:
 -------
 
-cat /debug/pktcdvd/pktcdvd0/info
+cat /sys/kernel/debug/pktcdvd/pktcdvd0/info
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/ima_policy linux-libre-2.6.30-gnu1/Documentation/ABI/testing/ima_policy
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/ima_policy	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/ima_policy	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,61 @@
+What:		security/ima/policy
+Date:		May 2008
+Contact:	Mimi Zohar <zohar@us.ibm.com>
+Description:
+		The Trusted Computing Group(TCG) runtime Integrity
+		Measurement Architecture(IMA) maintains a list of hash
+		values of executables and other sensitive system files
+		loaded into the run-time of this system.  At runtime,
+		the policy can be constrained based on LSM specific data.
+		Policies are loaded into the securityfs file ima/policy
+		by opening the file, writing the rules one at a time and
+		then closing the file.  The new policy takes effect after
+		the file ima/policy is closed.
+
+		rule format: action [condition ...]
+
+		action: measure | dont_measure
+		condition:= base | lsm
+			base:	[[func=] [mask=] [fsmagic=] [uid=]]
+			lsm:	[[subj_user=] [subj_role=] [subj_type=]
+				 [obj_user=] [obj_role=] [obj_type=]]
+
+		base: 	func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
+			mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
+			fsmagic:= hex value
+			uid:= decimal value
+		lsm:  	are LSM specific
+
+		default policy:
+			# PROC_SUPER_MAGIC
+			dont_measure fsmagic=0x9fa0
+			# SYSFS_MAGIC
+			dont_measure fsmagic=0x62656572
+			# DEBUGFS_MAGIC
+			dont_measure fsmagic=0x64626720
+			# TMPFS_MAGIC
+			dont_measure fsmagic=0x01021994
+			# SECURITYFS_MAGIC
+			dont_measure fsmagic=0x73636673
+
+			measure func=BPRM_CHECK
+			measure func=FILE_MMAP mask=MAY_EXEC
+			measure func=INODE_PERM 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.
+
+		Examples of LSM specific definitions:
+
+		SELinux:
+			# SELINUX_MAGIC
+			dont_measure fsmagic=0xF97CFF8C
+
+			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
+
+		Smack:
+			measure subj_user=_ func=INODE_PERM mask=MAY_READ
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-bus-pci linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-bus-pci
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-bus-pci	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-bus-pci	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,49 @@ Description:
 		for the device and attempt to bind to it.  For example:
 		# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
 
+What:		/sys/bus/pci/drivers/.../remove_id
+Date:		February 2009
+Contact:	Chris Wright <chrisw@sous-sol.org>
+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:
+		VVVV DDDD SVVV SDDD CCCC MMMM.	That is Vendor ID, Device
+		ID, Subsystem Vendor ID, Subsystem Device ID, Class,
+		and Class Mask.  The Vendor ID and Device ID fields are
+		required, the rest are optional.  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 "8086 10f5" > /sys/bus/pci/drivers/foo/remove_id
+
+What:		/sys/bus/pci/rescan
+Date:		January 2009
+Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of all PCI buses in the system, and
+		re-discover previously removed devices.
+		Depends on CONFIG_HOTPLUG.
+
+What:		/sys/bus/pci/devices/.../remove
+Date:		January 2009
+Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+		Writing a non-zero value to this attribute will
+		hot-remove the PCI device and any of its children.
+		Depends on CONFIG_HOTPLUG.
+
+What:		/sys/bus/pci/devices/.../rescan
+Date:		January 2009
+Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of the device's parent bus and all
+		child buses, and re-discover devices removed earlier
+		from this part of the device tree.
+		Depends on CONFIG_HOTPLUG.
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <bhutchings@solarflare.com>
@@ -52,3 +95,30 @@ Description:
 		that some devices may have malformatted data.  If the
 		underlying VPD has a writable section then the
 		corresponding section of this file will be writable.
+
+What:		/sys/bus/pci/devices/.../virtfnN
+Date:		March 2009
+Contact:	Yu Zhao <yu.zhao@intel.com>
+Description:
+		This symbolic link appears when hardware supports the SR-IOV
+		capability and the Physical Function driver has enabled it.
+		The symbolic link points to the PCI device sysfs entry of the
+		Virtual Function whose index is N (0...MaxVFs-1).
+
+What:		/sys/bus/pci/devices/.../dep_link
+Date:		March 2009
+Contact:	Yu Zhao <yu.zhao@intel.com>
+Description:
+		This symbolic link appears when hardware supports the SR-IOV
+		capability and the Physical Function driver has enabled it,
+		and this device has vendor specific dependencies with others.
+		The symbolic link points to the PCI device sysfs entry of
+		Physical Function this device depends on.
+
+What:		/sys/bus/pci/devices/.../physfn
+Date:		March 2009
+Contact:	Yu Zhao <yu.zhao@intel.com>
+Description:
+		This symbolic link appears when a device is a Virtual Function.
+		The symbolic link points to the PCI device sysfs entry of the
+		Physical Function this device associates with.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-class-regulator linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-class-regulator
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-class-regulator	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-class-regulator	2009-06-09 23:05:27.000000000 -0400
@@ -4,8 +4,8 @@ KernelVersion:	2.6.26
 Contact:	Liam Girdwood <lrg@slimlogic.co.uk>
 Description:
 		Some regulator directories will contain a field called
-		state. This reports the regulator enable status, for
-		regulators which can report that value.
+		state. This reports the regulator enable control, for
+		regulators which can report that input value.
 
 		This will be one of the following strings:
 
@@ -14,16 +14,54 @@ Description:
 		'unknown'
 
 		'enabled' means the regulator output is ON and is supplying
-		power to the system.
+		power to the system (assuming no error prevents it).
 
 		'disabled' means the regulator output is OFF and is not
-		supplying power to the system..
+		supplying power to the system (unless some non-Linux
+		control has enabled it).
 
 		'unknown' means software cannot determine the state, or
 		the reported state is invalid.
 
 		NOTE: this field can be used in conjunction with microvolts
-		and microamps to determine regulator output levels.
+		or microamps to determine configured regulator output levels.
+
+
+What:		/sys/class/regulator/.../status
+Description:
+		Some regulator directories will contain a field called
+		"status". This reports the current regulator status, for
+		regulators which can report that output value.
+
+		This will be one of the following strings:
+
+			off
+			on
+			error
+			fast
+			normal
+			idle
+			standby
+
+		"off" means the regulator is not supplying power to the
+		system.
+
+		"on" means the regulator is supplying power to the system,
+		and the regulator can't report a detailed operation mode.
+
+		"error" indicates an out-of-regulation status such as being
+		disabled due to thermal shutdown, or voltage being unstable
+		because of problems with the input power supply.
+
+		"fast", "normal", "idle", and "standby" are all detailed
+		regulator operation modes (described elsewhere).  They
+		imply "on", but provide more detail.
+
+		Note that regulator status is a function of many inputs,
+		not limited to control inputs from Linux.  For example,
+		the actual load presented may trigger "error" status; or
+		a regulator may be enabled by another user, even though
+		Linux did not enable it.
 
 
 What:		/sys/class/regulator/.../type
@@ -58,7 +96,7 @@ Description:
 		Some regulator directories will contain a field called
 		microvolts. This holds the regulator output voltage setting
 		measured in microvolts (i.e. E-6 Volts), for regulators
-		which can report that voltage.
+		which can report the control input for voltage.
 
 		NOTE: This value should not be used to determine the regulator
 		output voltage level as this value is the same regardless of
@@ -73,7 +111,7 @@ Description:
 		Some regulator directories will contain a field called
 		microamps. This holds the regulator output current limit
 		setting measured in microamps (i.e. E-6 Amps), for regulators
-		which can report that current.
+		which can report the control input for a current limit.
 
 		NOTE: This value should not be used to determine the regulator
 		output current level as this value is the same regardless of
@@ -87,7 +125,7 @@ Contact:	Liam Girdwood <lrg@slimlogic.co
 Description:
 		Some regulator directories will contain a field called
 		opmode. This holds the current regulator operating mode,
-		for regulators which can report it.
+		for regulators which can report that control input value.
 
 		The opmode value can be one of the following strings:
 
@@ -101,7 +139,8 @@ Description:
 
 		NOTE: This value should not be used to determine the regulator
 		output operating mode as this value is the same regardless of
-		whether the regulator is enabled or disabled.
+		whether the regulator is enabled or disabled.  A "status"
+		attribute may be available to determine the actual mode.
 
 
 What:		/sys/class/regulator/.../min_microvolts
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-firmware-acpi linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-firmware-acpi
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-firmware-acpi	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-firmware-acpi	2009-06-09 23:05:27.000000000 -0400
@@ -69,9 +69,13 @@ Description:
 		gpe1F:	     0	invalid
 		gpe_all:    1192
 		sci:	1194
+		sci_not:     0	
 
-		sci - The total number of times the ACPI SCI
-		has claimed an interrupt.
+		sci - The number of times the ACPI SCI
+		has been called and claimed an interrupt.
+
+		sci_not - The number of times the ACPI SCI
+		has been called and NOT claimed an interrupt.
 
 		gpe_all - count of SCI caused by GPEs.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-fs-ext4 linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-fs-ext4
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-fs-ext4	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-fs-ext4	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,81 @@
+What:		/sys/fs/ext4/<disk>/mb_stats
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		 Controls whether the multiblock allocator should
+		 collect statistics, which are shown during the unmount.
+		 1 means to collect statistics, 0 means not to collect
+		 statistics
+
+What:		/sys/fs/ext4/<disk>/mb_group_prealloc
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		The multiblock allocator will round up allocation
+		requests to a multiple of this tuning parameter if the
+		stripe size is not set in the ext4 superblock
+
+What:		/sys/fs/ext4/<disk>/mb_max_to_scan
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		The maximum number of extents the multiblock allocator
+		will search to find the best extent
+
+What:		/sys/fs/ext4/<disk>/mb_min_to_scan
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		The minimum number of extents the multiblock allocator
+		will search to find the best extent
+
+What:		/sys/fs/ext4/<disk>/mb_order2_req
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		Tuning parameter which controls the minimum size for 
+		requests (as a power of 2) where the buddy cache is
+		used
+
+What:		/sys/fs/ext4/<disk>/mb_stream_req
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		Files which have fewer blocks than this tunable
+		parameter will have their blocks allocated out of a
+		block group specific preallocation pool, so that small
+		files are packed closely together.  Each large file
+		 will have its blocks allocated out of its own unique
+		 preallocation pool.
+
+What:		/sys/fs/ext4/<disk>/inode_readahead
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		Tuning parameter which controls the maximum number of
+		inode table blocks that ext4's inode table readahead
+		algorithm will pre-read into the buffer cache
+
+What:		/sys/fs/ext4/<disk>/delayed_allocation_blocks
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		This file is read-only and shows the number of blocks
+		that are dirty in the page cache, but which do not
+		have their location in the filesystem allocated yet.
+
+What:		/sys/fs/ext4/<disk>/lifetime_write_kbytes
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		This file is read-only and shows the number of kilobytes
+		of data that have been written to this filesystem since it was
+		created.
+
+What:		/sys/fs/ext4/<disk>/session_write_kbytes
+Date:		March 2008
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		This file is read-only and shows the number of
+		kilobytes of data that have been written to this
+		filesystem since it was mounted.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-kernel-slab linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-kernel-slab
--- linux-libre-2.6.29-gnu1/Documentation/ABI/testing/sysfs-kernel-slab	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/ABI/testing/sysfs-kernel-slab	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,479 @@
+What:		/sys/kernel/slab
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The /sys/kernel/slab directory contains a snapshot of the
+		internal state of the SLUB allocator for each cache.  Certain
+		files may be modified to change the behavior of the cache (and
+		any cache it aliases, if any).
+Users:		kernel memory tuning tools
+
+What:		/sys/kernel/slab/cache/aliases
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The aliases file is read-only and specifies how many caches
+		have merged into this cache.
+
+What:		/sys/kernel/slab/cache/align
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The align file is read-only and specifies the cache's object
+		alignment in bytes.
+
+What:		/sys/kernel/slab/cache/alloc_calls
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The alloc_calls file is read-only and lists the kernel code
+		locations from which allocations for this cache were performed.
+		The alloc_calls file only contains information if debugging is
+		enabled for that cache (see Documentation/vm/slub.txt).
+
+What:		/sys/kernel/slab/cache/alloc_fastpath
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/alloc_from_partial
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/alloc_refill
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/alloc_slab
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/alloc_slowpath
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/cache_dma
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The cache_dma file is read-only and specifies whether objects
+		are from ZONE_DMA.
+		Available when CONFIG_ZONE_DMA is enabled.
+
+What:		/sys/kernel/slab/cache/cpu_slabs
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The cpu_slabs file is read-only and displays how many cpu slabs
+		are active and their NUMA locality.
+
+What:		/sys/kernel/slab/cache/cpuslab_flush
+Date:		April 2009
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/ctor
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The ctor file is read-only and specifies the cache's object
+		constructor function, which is invoked for each object when a
+		new slab is allocated.
+
+What:		/sys/kernel/slab/cache/deactivate_empty
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/deactivate_full
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/deactivate_remote_frees
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/deactivate_to_head
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/deactivate_to_tail
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/destroy_by_rcu
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The destroy_by_rcu file is read-only and specifies whether
+		slabs (not objects) are freed by rcu.
+
+What:		/sys/kernel/slab/cache/free_add_partial
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/free_calls
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The free_calls file is read-only and lists the locations of
+		object frees if slab debugging is enabled (see
+		Documentation/vm/slub.txt).
+
+What:		/sys/kernel/slab/cache/free_fastpath
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/free_frozen
+Date:		February 2008
+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).
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/free_remove_partial
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/free_slab
+Date:		February 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/free_slowpath
+Date:		February 2008
+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).
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/hwcache_align
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The hwcache_align file is read-only and specifies whether
+		objects are aligned on cachelines.
+
+What:		/sys/kernel/slab/cache/min_partial
+Date:		February 2009
+KernelVersion:	2.6.30
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		David Rientjes <rientjes@google.com>
+Description:
+		The min_partial file specifies how many empty slabs shall
+		remain on a node's partial list to avoid the overhead of
+		allocating new slabs.  Such slabs may be reclaimed by utilizing
+		the shrink file.
+
+What:		/sys/kernel/slab/cache/object_size
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The object_size file is read-only and specifies the cache's
+		object size.
+
+What:		/sys/kernel/slab/cache/objects
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The objects file is read-only and displays how many objects are
+		active and from which nodes they are from.
+
+What:		/sys/kernel/slab/cache/objects_partial
+Date:		April 2008
+KernelVersion:	2.6.26
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The objects_partial file is read-only and displays how many
+		objects are on partial slabs and from which nodes they are
+		from.
+
+What:		/sys/kernel/slab/cache/objs_per_slab
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The file objs_per_slab is read-only and specifies how many
+		objects may be allocated from a single slab of the order
+		specified in /sys/kernel/slab/cache/order.
+
+What:		/sys/kernel/slab/cache/order
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The order file specifies the page order at which new slabs are
+		allocated.  It is writable and can be changed to increase the
+		number of objects per slab.  If a slab cannot be allocated
+		because of fragmentation, SLUB will retry with the minimum order
+		possible depending on its characteristics.
+
+What:		/sys/kernel/slab/cache/order_fallback
+Date:		April 2008
+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.
+		Available when CONFIG_SLUB_STATS is enabled.
+
+What:		/sys/kernel/slab/cache/partial
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The partial file is read-only and displays how long many
+		partial slabs there are and how long each node's list is.
+
+What:		/sys/kernel/slab/cache/poison
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The poison file specifies whether objects should be poisoned
+		when a new slab is allocated.
+
+What:		/sys/kernel/slab/cache/reclaim_account
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The reclaim_account file specifies whether the cache's objects
+		are reclaimable (and grouped by their mobility).
+
+What:		/sys/kernel/slab/cache/red_zone
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The red_zone file specifies whether the cache's objects are red
+		zoned.
+
+What:		/sys/kernel/slab/cache/remote_node_defrag_ratio
+Date:		January 2008
+KernelVersion:	2.6.25
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The file remote_node_defrag_ratio specifies the percentage of
+		times SLUB will attempt to refill the cpu slab with a partial
+		slab from a remote node as opposed to allocating a new slab on
+		the local node.  This reduces the amount of wasted memory over
+		the entire system but can be expensive.
+		Available when CONFIG_NUMA is enabled.
+
+What:		/sys/kernel/slab/cache/sanity_checks
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The sanity_checks file specifies whether expensive checks
+		should be performed on free and, at minimum, enables double free
+		checks.  Caches that enable sanity_checks cannot be merged with
+		caches that do not.
+
+What:		/sys/kernel/slab/cache/shrink
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The shrink file is written when memory should be reclaimed from
+		a cache.  Empty partial slabs are freed and the partial list is
+		sorted so the slabs with the fewest available objects are used
+		first.
+
+What:		/sys/kernel/slab/cache/slab_size
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The slab_size file is read-only and specifies the object size
+		with metadata (debugging information and alignment) in bytes.
+
+What:		/sys/kernel/slab/cache/slabs
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The slabs file is read-only and displays how long many slabs
+		there are (both cpu and partial) and from which nodes they are
+		from.
+
+What:		/sys/kernel/slab/cache/store_user
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The store_user file specifies whether the location of
+		allocation or free should be tracked for a cache.
+
+What:		/sys/kernel/slab/cache/total_objects
+Date:		April 2008
+KernelVersion:	2.6.26
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The total_objects file is read-only and displays how many total
+		objects a cache has and from which nodes they are from.
+
+What:		/sys/kernel/slab/cache/trace
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		The trace file specifies whether object allocations and frees
+		should be traced.
+
+What:		/sys/kernel/slab/cache/validate
+Date:		May 2007
+KernelVersion:	2.6.22
+Contact:	Pekka Enberg <penberg@cs.helsinki.fi>,
+		Christoph Lameter <cl@linux-foundation.org>
+Description:
+		Writing to the validate file causes SLUB to traverse all of its
+		cache's objects and check the validity of metadata.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/arm/memory.txt linux-libre-2.6.30-gnu1/Documentation/arm/memory.txt
--- linux-libre-2.6.29-gnu1/Documentation/arm/memory.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/arm/memory.txt	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,14 @@ ffff0000	ffff0fff	CPU vector page.
 				CPU supports vector relocation (control
 				register V bit.)
 
-ffc00000	fffeffff	DMA memory mapping region.  Memory returned
+fffe0000	fffeffff	XScale cache flush area.  This is used
+				in proc-xscale.S to flush the whole data
+				cache.  Free for other usage on non-XScale.
+
+fff00000	fffdffff	Fixmap mapping region.  Addresses provided
+				by fix_to_virt() will be located here.
+
+ffc00000	ffefffff	DMA memory mapping region.  Memory returned
 				by the dma_alloc_xxx functions will be
 				dynamically mapped here.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt linux-libre-2.6.30-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt
--- linux-libre-2.6.29-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/arm/Samsung-S3C24XX/Suspend.txt	2009-06-09 23:05:27.000000000 -0400
@@ -40,13 +40,13 @@ Resuming
 Machine Support
 ---------------
 
-  The machine specific functions must call the s3c2410_pm_init() function
+  The machine specific functions must call the s3c_pm_init() function
   to say that its bootloader is capable of resuming. This can be as
   simple as adding the following to the machine's definition:
 
-  INITMACHINE(s3c2410_pm_init)
+  INITMACHINE(s3c_pm_init)
 
-  A board can do its own setup before calling s3c2410_pm_init, if it
+  A board can do its own setup before calling s3c_pm_init, if it
   needs to setup anything else for power management support.
 
   There is currently no support for over-riding the default method of
@@ -74,7 +74,7 @@ statuc void __init machine_init(void)
 
 	enable_irq_wake(IRQ_EINT0);
 
-	s3c2410_pm_init();
+	s3c_pm_init();
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/block/biodoc.txt linux-libre-2.6.30-gnu1/Documentation/block/biodoc.txt
--- linux-libre-2.6.29-gnu1/Documentation/block/biodoc.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/block/biodoc.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1040,23 +1040,21 @@ Front merges are handled by the binary t
 iii. Plugging the queue to batch requests in anticipation of opportunities for
      merge/sort optimizations
 
-This is just the same as in 2.4 so far, though per-device unplugging
-support is anticipated for 2.5. Also with a priority-based i/o scheduler,
-such decisions could be based on request priorities.
-
 Plugging is an approach that the current i/o scheduling algorithm resorts to so
 that it collects up enough requests in the queue to be able to take
 advantage of the sorting/merging logic in the elevator. If the
 queue is empty when a request comes in, then it plugs the request queue
-(sort of like plugging the bottom of a vessel to get fluid to build up)
+(sort of like plugging the bath tub of a vessel to get fluid to build up)
 till it fills up with a few more requests, before starting to service
 the requests. This provides an opportunity to merge/sort the requests before
 passing them down to the device. There are various conditions when the queue is
 unplugged (to open up the flow again), either through a scheduled task or
 could be on demand. For example wait_on_buffer sets the unplugging going
-(by running tq_disk) so the read gets satisfied soon. So in the read case,
-the queue gets explicitly unplugged as part of waiting for completion,
-in fact all queues get unplugged as a side-effect.
+through sync_buffer() running blk_run_address_space(mapping). Or the caller
+can do it explicity through blk_unplug(bdev). So in the read case,
+the queue gets explicitly unplugged as part of waiting for completion on that
+buffer. For page driven IO, the address space ->sync_page() takes care of
+doing the blk_run_address_space().
 
 Aside:
   This is kind of controversial territory, as it's not clear if plugging is
@@ -1067,11 +1065,6 @@ Aside:
   multi-page bios being queued in one shot, we may not need to wait to merge
   a big request from the broken up pieces coming by.
 
-  Per-queue granularity unplugging (still a Todo) may help reduce some of the
-  concerns with just a single tq_disk flush approach. Something like
-  blk_kick_queue() to unplug a specific queue (right away ?)
-  or optionally, all queues, is in the plan.
-
 4.4 I/O contexts
 I/O contexts provide a dynamically allocated per process data area. They may
 be used in I/O schedulers, and in the block layer (could be used for IO statis,
diff -druNp linux-libre-2.6.29-gnu1/Documentation/block/switching-sched.txt linux-libre-2.6.30-gnu1/Documentation/block/switching-sched.txt
--- linux-libre-2.6.29-gnu1/Documentation/block/switching-sched.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/block/switching-sched.txt	2009-06-09 23:05:27.000000000 -0400
@@ -35,9 +35,3 @@ noop anticipatory deadline [cfq]
 # echo anticipatory > /sys/block/hda/queue/scheduler
 # cat /sys/block/hda/queue/scheduler
 noop [anticipatory] deadline cfq
-
-Each io queue has a set of io scheduler tunables associated with it. These
-tunables control how the io scheduler works. You can find these entries
-in:
-
-/sys/block/<device>/queue/iosched
diff -druNp linux-libre-2.6.29-gnu1/Documentation/blockdev/00-INDEX linux-libre-2.6.30-gnu1/Documentation/blockdev/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/blockdev/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/blockdev/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,8 @@ cpqarray.txt
 	- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
 floppy.txt
 	- notes and driver options for the floppy disk driver.
+mflash.txt
+	- info on mGine m(g)flash driver for linux.
 nbd.txt
 	- info on a TCP implementation of a network block device.
 paride.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/blockdev/mflash.txt linux-libre-2.6.30-gnu1/Documentation/blockdev/mflash.txt
--- linux-libre-2.6.29-gnu1/Documentation/blockdev/mflash.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/blockdev/mflash.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,84 @@
+This document describes m[g]flash support in linux.
+
+Contents
+  1. Overview
+  2. Reserved area configuration
+  3. Example of mflash platform driver registration
+
+1. Overview
+
+Mflash and gflash are embedded flash drive. The only difference is mflash is
+MCP(Multi Chip Package) device. These two device operate exactly same way.
+So the rest mflash repersents mflash and gflash altogether.
+
+Internally, mflash has nand flash and other hardware logics and supports
+2 different operation (ATA, IO) modes. ATA mode doesn't need any new
+driver and currently works well under standard IDE subsystem. Actually it's
+one chip SSD. IO mode is ATA-like custom mode for the host that doesn't have
+IDE interface.
+
+Followings are brief descriptions about IO mode.
+A. IO mode based on ATA protocol and uses some custom command. (read confirm,
+write confirm)
+B. IO mode uses SRAM bus interface.
+C. IO mode supports 4kB boot area, so host can boot from mflash.
+
+2. Reserved area configuration
+If host boot from mflash, usually needs raw area for boot loader image. All of
+the mflash's block device operation will be taken this value as start offset.
+Note that boot loader's size of reserved area and kernel configuration value
+must be same.
+
+3. Example of mflash platform driver registration
+Working mflash is very straight forward. Adding platform device stuff to board
+configuration file is all. Here is some pseudo example.
+
+static struct mg_drv_data mflash_drv_data = {
+	/* If you want to polling driver set to 1 */
+	.use_polling = 0,
+	/* device attribution */
+	.dev_attr = MG_BOOT_DEV
+};
+
+static struct resource mg_mflash_rsc[] = {
+	/* Base address of mflash */
+	[0] = {
+		.start = 0x08000000,
+		.end = 0x08000000 + SZ_64K - 1,
+		.flags = IORESOURCE_MEM
+	},
+	/* mflash interrupt pin */
+	[1] = {
+		.start = IRQ_GPIO(84),
+		.end = IRQ_GPIO(84),
+		.flags = IORESOURCE_IRQ
+	},
+	/* mflash reset pin */
+	[2] = {
+		.start = 43,
+		.end = 43,
+		.name = MG_RST_PIN,
+		.flags = IORESOURCE_IO
+	},
+	/* mflash reset-out pin
+	 * If you use mflash as storage device (i.e. other than MG_BOOT_DEV),
+	 * should assign this */
+	[3] = {
+		.start = 51,
+		.end = 51,
+		.name = MG_RSTOUT_PIN,
+		.flags = IORESOURCE_IO
+	}
+};
+
+static struct platform_device mflash_dev = {
+	.name = MG_DEV_NAME,
+	.id = -1,
+	.dev = {
+		.platform_data = &mflash_drv_data,
+	},
+	.num_resources = ARRAY_SIZE(mg_mflash_rsc),
+	.resource = mg_mflash_rsc
+};
+
+platform_device_register(&mflash_dev);
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/00-INDEX linux-libre-2.6.30-gnu1/Documentation/cgroups/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/00-INDEX	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,18 @@
+00-INDEX
+	- this file
+cgroups.txt
+	- Control Groups definition, implementation details, examples and API.
+cpuacct.txt
+	- CPU Accounting Controller; account CPU usage for groups of tasks.
+cpusets.txt
+	- documents the cpusets feature; assign CPUs and Mem to a set of tasks.
+devices.txt
+	- Device Whitelist Controller; description, interface and security.
+freezer-subsystem.txt
+	- checkpointing; rationale to not use signals, interface.
+memcg_test.txt
+	- Memory Resource Controller; implementation details.
+memory.txt
+	- Memory Resource Controller; design, accounting, interface, testing.
+resource_counter.txt
+	- Resource Counter API.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/cgroups.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/cgroups.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/cgroups.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/cgroups.txt	2009-06-09 23:05:27.000000000 -0400
@@ -56,7 +56,7 @@ hierarchy, and a set of subsystems; each
 state attached to each cgroup in the hierarchy.  Each hierarchy has
 an instance of the cgroup virtual filesystem associated with it.
 
-At any one time there may be multiple active hierachies of task
+At any one time there may be multiple active hierarchies of task
 cgroups. Each hierarchy is a partition of all tasks in the system.
 
 User level code may create and destroy cgroups by name in an
@@ -124,10 +124,10 @@ following lines:
                                / \
                        Prof (15%) students (5%)
 
-Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd go
 into NFS network class.
 
-At the same time firefox/lynx will share an appropriate CPU/Memory class
+At the same time Firefox/Lynx will share an appropriate CPU/Memory class
 depending on who launched it (prof/student).
 
 With the ability to classify tasks differently for different resources
@@ -325,7 +325,7 @@ and then start a subshell 'sh' in that c
 Creating, modifying, using the cgroups can be done through the cgroup
 virtual filesystem.
 
-To mount a cgroup hierarchy will all available subsystems, type:
+To mount a cgroup hierarchy with all available subsystems, type:
 # mount -t cgroup xxx /dev/cgroup
 
 The "xxx" is not interpreted by the cgroup code, but will appear in
@@ -333,12 +333,23 @@ The "xxx" is not interpreted by the cgro
 
 To mount a cgroup hierarchy with just the cpuset and numtasks
 subsystems, type:
-# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
+# mount -t cgroup -o cpuset,memory hier1 /dev/cgroup
 
 To change the set of subsystems bound to a mounted hierarchy, just
 remount with different options:
+# mount -o remount,cpuset,ns hier1 /dev/cgroup
 
-# mount -o remount,cpuset,ns  /dev/cgroup
+Now memory is removed from the hierarchy and ns is added.
+
+Note this will add ns to the hierarchy but won't remove memory or
+cpuset, because the new options are appended to the old ones:
+# mount -o remount,ns /dev/cgroup
+
+To Specify a hierarchy's release_agent:
+# mount -t cgroup -o cpuset,release_agent="/sbin/cpuset_release_agent" \
+  xxx /dev/cgroup
+
+Note that specifying 'release_agent' more than once will return failure.
 
 Note that changing the set of subsystems is currently only supported
 when the hierarchy consists of a single (root) cgroup. Supporting
@@ -349,6 +360,11 @@ Then under /dev/cgroup you can find a tr
 tree of the cgroups in the system. For instance, /dev/cgroup
 is the cgroup that holds the whole system.
 
+If you want to change the value of release_agent:
+# echo "/sbin/new_release_agent" > /dev/cgroup/release_agent
+
+It can also be changed via remount.
+
 If you want to create a new cgroup under /dev/cgroup:
 # cd /dev/cgroup
 # mkdir my_cgroup
@@ -476,11 +492,13 @@ cgroup->parent is still valid. (Note - c
 newly-created cgroup if an error occurs after this subsystem's
 create() method has been called for the new cgroup).
 
-void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+int pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
 
 Called before checking the reference count on each subsystem. This may
 be useful for subsystems which have some extra references even if
-there are not tasks in the cgroup.
+there are not tasks in the cgroup. If pre_destroy() returns error code,
+rmdir() will fail with it. From this behavior, pre_destroy() can be
+called multiple times against a cgroup.
 
 int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	       struct task_struct *task)
@@ -521,7 +539,7 @@ always handled well.
 void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
-Called at the end of cgroup_clone() to do any paramater
+Called at the end of cgroup_clone() to do any parameter
 initialization which might be required before a task could attach.  For
 example in cpusets, no task may attach before 'cpus' and 'mems' are set
 up.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/cpuacct.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/cpuacct.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/cpuacct.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/cpuacct.txt	2009-06-09 23:05:27.000000000 -0400
@@ -30,3 +30,21 @@ The above steps create a new group g1 an
 process (bash) into it. CPU time consumed by this bash and its children
 can be obtained from g1/cpuacct.usage and the same is accumulated in
 /cgroups/cpuacct.usage also.
+
+cpuacct.stat file lists a few statistics which further divide the
+CPU time obtained by the cgroup into user and system times. Currently
+the following statistics are supported:
+
+user: Time spent by tasks of the cgroup in user mode.
+system: Time spent by tasks of the cgroup in kernel mode.
+
+user and system are in USER_HZ unit.
+
+cpuacct controller uses percpu_counter interface to collect user and
+system times. This has two side effects:
+
+- It is theoretically possible to see wrong values for user and system times.
+  This is because percpu_counter_read() on 32bit systems isn't safe
+  against concurrent writes.
+- It is possible to see slightly outdated values for user and system times
+  due to the batch processing nature of percpu_counter.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/cpusets.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/cpusets.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/cpusets.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/cpusets.txt	2009-06-09 23:05:27.000000000 -0400
@@ -131,7 +131,7 @@ Cpusets extends these two mechanisms as
  - The hierarchy of cpusets can be mounted at /dev/cpuset, for
    browsing and manipulation from user space.
  - A cpuset may be marked exclusive, which ensures that no other
-   cpuset (except direct ancestors and descendents) may contain
+   cpuset (except direct ancestors and descendants) may contain
    any overlapping CPUs or Memory Nodes.
  - You can list all the tasks (by pid) attached to any cpuset.
 
@@ -226,7 +226,7 @@ nodes with memory--using the cpuset_trac
 --------------------------------
 
 If a cpuset is cpu or mem exclusive, no other cpuset, other than
-a direct ancestor or descendent, may share any of the same CPUs or
+a direct ancestor or descendant, may share any of the same CPUs or
 Memory Nodes.
 
 A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled",
@@ -427,7 +427,7 @@ child cpusets have this flag enabled.
 When doing this, you don't usually want to leave any unpinned tasks in
 the top cpuset that might use non-trivial amounts of CPU, as such tasks
 may be artificially constrained to some subset of CPUs, depending on
-the particulars of this flag setting in descendent cpusets.  Even if
+the particulars of this flag setting in descendant cpusets.  Even if
 such a task could use spare CPU cycles in some other CPUs, the kernel
 scheduler might not consider the possibility of load balancing that
 task to that underused CPU.
@@ -531,9 +531,9 @@ be idle.
 
 Of course it takes some searching cost to find movable tasks and/or
 idle CPUs, the scheduler might not search all CPUs in the domain
-everytime.  In fact, in some architectures, the searching ranges on
+every time.  In fact, in some architectures, the searching ranges on
 events are limited in the same socket or node where the CPU locates,
-while the load balance on tick searchs all.
+while the load balance on tick searches all.
 
 For example, assume CPU Z is relatively far from CPU X.  Even if CPU Z
 is idle while CPU X and the siblings are busy, scheduler can't migrate
@@ -601,7 +601,7 @@ its new cpuset, then the task will conti
 of MPOL_BIND nodes are still allowed in the new cpuset.  If the task
 was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed
 in the new cpuset, then the task will be essentially treated as if it
-was MPOL_BIND bound to the new cpuset (even though its numa placement,
+was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
 as queried by get_mempolicy(), doesn't change).  If a task is moved
 from one cpuset to another, then the kernel will adjust the tasks
 memory placement, as above, the next time that the kernel attempts
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/devices.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/devices.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/devices.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/devices.txt	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ suffice, but we can decide the best way
 movement as people get some experience with this.  We may just want
 to require CAP_SYS_ADMIN, which at least is a separate bit from
 CAP_MKNOD.  We may want to just refuse moving to a cgroup which
-isn't a descendent of the current one.  Or we may want to use
+isn't a descendant of the current one.  Or we may want to use
 CAP_MAC_ADMIN, since we really are trying to lock down root.
 
 CAP_SYS_ADMIN is needed to modify the whitelist or move another
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/memcg_test.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/memcg_test.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/memcg_test.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/memcg_test.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 Memory Resource Controller(Memcg)  Implementation Memo.
-Last Updated: 2009/1/19
+Last Updated: 2009/1/20
 Base Kernel Version: based on 2.6.29-rc2.
 
 Because VM is getting complex (one of reasons is memcg...), memcg's behavior
@@ -356,7 +356,25 @@ Under below explanation, we assume CONFI
 	(Shell-B)
 	# move all tasks in /cgroup/test to /cgroup
 	# /sbin/swapoff -a
-	# rmdir /test/cgroup
+	# rmdir /cgroup/test
 	# kill malloc task.
 
 	Of course, tmpfs v.s. swapoff test should be tested, too.
+
+ 9.8 OOM-Killer
+	Out-of-memory caused by memcg's limit will kill tasks under
+	the memcg. When hierarchy is used, a task under hierarchy
+	will be killed by the kernel.
+	In this case, panic_on_oom shouldn't be invoked and tasks
+	in other groups shouldn't be killed.
+
+	It's not difficult to cause OOM under memcg as following.
+	Case A) when you can swapoff
+	#swapoff -a
+	#echo 50M > /memory.limit_in_bytes
+	run 51M of malloc
+
+	Case B) when you use mem+swap limitation.
+	#echo 50M > memory.limit_in_bytes
+	#echo 50M > memory.memsw.limit_in_bytes
+	run 51M of malloc
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/memory.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/memory.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/memory.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/memory.txt	2009-06-09 23:05:27.000000000 -0400
@@ -6,15 +6,14 @@ used here with the memory controller tha
 
 Salient features
 
-a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages
+a. Enable control of Anonymous, Page Cache (mapped and unmapped) and
+   Swap Cache memory pages.
 b. The infrastructure allows easy addition of other types of memory to control
 c. Provides *zero overhead* for non memory controller users
 d. Provides a double LRU: global memory pressure causes reclaim from the
    global LRU; a cgroup on hitting a limit, reclaims from the per
    cgroup LRU
 
-NOTE: Swap Cache (unmapped) is not accounted now.
-
 Benefits and Purpose of the memory controller
 
 The memory controller isolates the memory behaviour of a group of tasks
@@ -290,34 +289,44 @@ will be charged as a new owner of it.
   moved to the parent. If you want to avoid that, force_empty will be useful.
 
 5.2 stat file
-  memory.stat file includes following statistics (now)
-	cache			- # of pages from page-cache and shmem.
-	rss			- # of pages from anonymous memory.
-	pgpgin			- # of event of charging
-	pgpgout			- # of event of uncharging
-	active_anon		- # of pages on active lru of anon, shmem.
-	inactive_anon 		- # of pages on active lru of anon, shmem
-	active_file		- # of pages on active lru of file-cache
-	inactive_file		- # of pages on inactive lru of file cache
-	unevictable		- # of pages cannot be reclaimed.(mlocked etc)
 
-	Below is depend on CONFIG_DEBUG_VM.
-	inactive_ratio		- VM inernal parameter. (see mm/page_alloc.c)
-	recent_rotated_anon	- VM internal parameter. (see mm/vmscan.c)
-	recent_rotated_file	- VM internal parameter. (see mm/vmscan.c)
-	recent_scanned_anon 	- VM internal parameter. (see mm/vmscan.c)
-	recent_scanned_file 	- VM internal parameter. (see mm/vmscan.c)
+memory.stat file includes following statistics
 
-  Memo:
+cache		- # of bytes of page cache memory.
+rss		- # of bytes of anonymous and swap cache memory.
+pgpgin		- # of pages paged in (equivalent to # of charging events).
+pgpgout		- # of pages paged out (equivalent to # of uncharging events).
+active_anon	- # of bytes of anonymous and  swap cache memory on active
+		  lru list.
+inactive_anon	- # of bytes of anonymous memory and swap cache memory on
+		  inactive lru list.
+active_file	- # of bytes of file-backed memory on active lru list.
+inactive_file	- # of bytes of file-backed memory on inactive lru list.
+unevictable	- # of bytes of memory that cannot be reclaimed (mlocked etc).
+
+The following additional stats are dependent on CONFIG_DEBUG_VM.
+
+inactive_ratio		- VM internal parameter. (see mm/page_alloc.c)
+recent_rotated_anon	- VM internal parameter. (see mm/vmscan.c)
+recent_rotated_file	- VM internal parameter. (see mm/vmscan.c)
+recent_scanned_anon	- VM internal parameter. (see mm/vmscan.c)
+recent_scanned_file	- VM internal parameter. (see mm/vmscan.c)
+
+Memo:
 	recent_rotated means recent frequency of lru rotation.
 	recent_scanned means recent # of scans to lru.
 	showing for better debug please see the code for meanings.
 
+Note:
+	Only anonymous and swap cache memory is listed as part of 'rss' stat.
+	This should not be confused with the true 'resident set size' or the
+	amount of physical memory used by the cgroup. Per-cgroup rss
+	accounting is not done yet.
 
 5.3 swappiness
   Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
 
-  Following cgroup's swapiness can't be changed.
+  Following cgroups' swapiness can't be changed.
   - root cgroup (uses /proc/sys/vm/swappiness).
   - a cgroup which uses hierarchy and it has child cgroup.
   - a cgroup which uses hierarchy and not the root of hierarchy.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cgroups/resource_counter.txt linux-libre-2.6.30-gnu1/Documentation/cgroups/resource_counter.txt
--- linux-libre-2.6.29-gnu1/Documentation/cgroups/resource_counter.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cgroups/resource_counter.txt	2009-06-09 23:05:27.000000000 -0400
@@ -47,13 +47,18 @@ to work with it.
 
 2. Basic accounting routines
 
- a. void res_counter_init(struct res_counter *rc)
+ a. void res_counter_init(struct res_counter *rc,
+				struct res_counter *rc_parent)
 
  	Initializes the resource counter. As usual, should be the first
 	routine called for a new counter.
 
- b. int res_counter_charge[_locked]
-			(struct res_counter *rc, unsigned long val)
+	The struct res_counter *parent can be used to define a hierarchical
+	child -> parent relationship directly in the res_counter structure,
+	NULL can be used to define no relationship.
+
+ c. int res_counter_charge(struct res_counter *rc, unsigned long val,
+				struct res_counter **limit_fail_at)
 
 	When a resource is about to be allocated it has to be accounted
 	with the appropriate resource counter (controller should determine
@@ -67,15 +72,25 @@ to work with it.
 	  * if the charging is performed first, then it should be uncharged
 	    on error path (if the one is called).
 
- c. void res_counter_uncharge[_locked]
+	If the charging fails and a hierarchical dependency exists, the
+	limit_fail_at parameter is set to the particular res_counter element
+	where the charging failed.
+
+ d. int res_counter_charge_locked
+			(struct res_counter *rc, unsigned long val)
+
+	The same as res_counter_charge(), but it must not acquire/release the
+	res_counter->lock internally (it must be called with res_counter->lock
+	held).
+
+ e. void res_counter_uncharge[_locked]
 			(struct res_counter *rc, unsigned long val)
 
 	When a resource is released (freed) it should be de-accounted
 	from the resource counter it was accounted to.  This is called
 	"uncharging".
 
-    The _locked routines imply that the res_counter->lock is taken.
-
+	The _locked routines imply that the res_counter->lock is taken.
 
  2.1 Other accounting routines
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cpu-freq/governors.txt linux-libre-2.6.30-gnu1/Documentation/cpu-freq/governors.txt
--- linux-libre-2.6.29-gnu1/Documentation/cpu-freq/governors.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cpu-freq/governors.txt	2009-06-09 23:05:27.000000000 -0400
@@ -117,10 +117,28 @@ accessible parameters:
 sampling_rate: measured in uS (10^-6 seconds), this is how often you
 want the kernel to look at the CPU usage and to make decisions on
 what to do about the frequency.  Typically this is set to values of
-around '10000' or more.
+around '10000' or more. It's default value is (cmp. with users-guide.txt):
+transition_latency * 1000
+The lowest value you can set is:
+transition_latency * 100 or it may get restricted to a value where it
+makes not sense for the kernel anymore to poll that often which depends
+on your HZ config variable (HZ=1000: max=20000us, HZ=250: max=5000).
+Be aware that transition latency is in ns and sampling_rate is in us, so you
+get the same sysfs value by default.
+Sampling rate should always get adjusted considering the transition latency
+To set the sampling rate 750 times as high as the transition latency
+in the bash (as said, 1000 is default), do:
+echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) \
+    >ondemand/sampling_rate
 
-show_sampling_rate_(min|max): the minimum and maximum sampling rates
-available that you may set 'sampling_rate' to.
+show_sampling_rate_(min|max): THIS INTERFACE IS DEPRECATED, DON'T USE IT.
+You can use wider ranges now and the general
+cpuinfo_transition_latency variable (cmp. with user-guide.txt) can be
+used to obtain exactly the same info:
+show_sampling_rate_min = transtition_latency * 500    / 1000
+show_sampling_rate_max = transtition_latency * 500000 / 1000
+(divided by 1000 is to illustrate that sampling rate is in us and
+transition latency is exported ns).
 
 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
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cpu-freq/user-guide.txt linux-libre-2.6.30-gnu1/Documentation/cpu-freq/user-guide.txt
--- linux-libre-2.6.29-gnu1/Documentation/cpu-freq/user-guide.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cpu-freq/user-guide.txt	2009-06-09 23:05:27.000000000 -0400
@@ -152,6 +152,18 @@ cpuinfo_min_freq :		this file shows the
 				frequency the processor can run at(in kHz) 
 cpuinfo_max_freq :		this file shows the maximum operating
 				frequency the processor can run at(in kHz) 
+cpuinfo_transition_latency	The time it takes on this CPU to
+				switch between two frequencies in nano
+				seconds. If unknown or known to be
+				that high that the driver does not
+				work with the ondemand governor, -1
+				(CPUFREQ_ETERNAL) will be returned.
+				Using this information can be useful
+				to choose an appropriate polling
+				frequency for a kernel governor or
+				userspace daemon. Make sure to not
+				switch the frequency too often
+				resulting in performance loss.
 scaling_driver :		this file shows what cpufreq driver is
 				used to set the frequency on this CPU
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/cputopology.txt linux-libre-2.6.30-gnu1/Documentation/cputopology.txt
--- linux-libre-2.6.29-gnu1/Documentation/cputopology.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/cputopology.txt	2009-06-09 23:05:27.000000000 -0400
@@ -18,11 +18,11 @@ For an architecture to support this feat
 these macros in include/asm-XXX/topology.h:
 #define topology_physical_package_id(cpu)
 #define topology_core_id(cpu)
-#define topology_thread_siblings(cpu)
-#define topology_core_siblings(cpu)
+#define topology_thread_cpumask(cpu)
+#define topology_core_cpumask(cpu)
 
 The type of **_id is int.
-The type of siblings is cpumask_t.
+The type of siblings is (const) struct cpumask *.
 
 To be consistent on all architectures, include/linux/topology.h
 provides default definitions for any of the above macros that are
diff -druNp linux-libre-2.6.29-gnu1/Documentation/devices.txt linux-libre-2.6.30-gnu1/Documentation/devices.txt
--- linux-libre-2.6.29-gnu1/Documentation/devices.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/devices.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 
 		    LINUX ALLOCATED DEVICES (2.6+ version)
 
-	     Maintained by Torben Mathiasen <device@lanana.org>
+	     Maintained by Alan Cox <device@lanana.org>
 
-		      Last revised: 29 November 2006
+		      Last revised: 6th April 2009
 
 This list is the Linux Device List, the official registry of allocated
 device numbers and /dev directory nodes for the Linux operating
@@ -67,6 +67,11 @@ up to date.  Due to the number of regist
 in "batch mode", so there is likely additional registrations that
 haven't been listed yet.
 
+Fourth, remember that Linux now has extensive support for dynamic allocation
+of device numbering and can use sysfs and udev to handle the naming needs.
+There are still some exceptions in the serial and boot device area. Before
+asking for a device number make sure you actually need one.
+
 Finally, sometimes I have to play "namespace police."  Please don't be
 offended.  I often get submissions for /dev names that would be bound
 to cause conflicts down the road.  I am trying to avoid getting in a
@@ -101,7 +106,7 @@ Your cooperation is appreciated.
 		  0 = /dev/ram0		First RAM disk
 		  1 = /dev/ram1		Second RAM disk
 		    ...
-		250 = /dev/initrd	Initial RAM disk {2.6}
+		250 = /dev/initrd	Initial RAM disk
 
 		Older kernels had /dev/ramdisk (1, 1) here.
 		/dev/initrd refers to a RAM disk which was preloaded
@@ -340,7 +345,7 @@ Your cooperation is appreciated.
 		 14 = /dev/touchscreen/ucb1x00  UCB 1x00 touchscreen
 		 15 = /dev/touchscreen/mk712	MK712 touchscreen
 		128 = /dev/beep		Fancy beep device
-		129 = /dev/modreq	Kernel module load request {2.6}
+		129 =
 		130 = /dev/watchdog	Watchdog timer port
 		131 = /dev/temperature	Machine internal temperature
 		132 = /dev/hwtrap	Hardware fault trap
@@ -350,10 +355,10 @@ Your cooperation is appreciated.
 		139 = /dev/openprom	SPARC OpenBoot PROM
 		140 = /dev/relay8	Berkshire Products Octal relay card
 		141 = /dev/relay16	Berkshire Products ISO-16 relay card
-		142 = /dev/msr		x86 model-specific registers {2.6}
+		142 =
 		143 = /dev/pciconf	PCI configuration space
 		144 = /dev/nvram	Non-volatile configuration RAM
-		145 = /dev/hfmodem	Soundcard shortwave modem control {2.6}
+		145 = /dev/hfmodem	Soundcard shortwave modem control
 		146 = /dev/graphics	Linux/SGI graphics device
 		147 = /dev/opengl	Linux/SGI OpenGL pipe
 		148 = /dev/gfx		Linux/SGI graphics effects device
@@ -435,6 +440,9 @@ Your cooperation is appreciated.
 		228 = /dev/hpet		HPET driver
 		229 = /dev/fuse		Fuse (virtual filesystem in user-space)
 		230 = /dev/midishare	MidiShare driver
+		231 = /dev/snapshot	System memory snapshot device
+		232 = /dev/kvm		Kernel-based virtual machine (hardware virtualization extensions)
+		233 = /dev/kmview	View-OS A process with a view
 		240-254			Reserved for local use
 		255			Reserved for MISC_DYNAMIC_MINOR
 
@@ -466,10 +474,7 @@ Your cooperation is appreciated.
 		The device names specified are proposed -- if there
 		are "standard" names for these devices, please let me know.
 
- 12 block	MSCDEX CD-ROM callback support {2.6}
-		  0 = /dev/dos_cd0	First MSCDEX CD-ROM
-		  1 = /dev/dos_cd1	Second MSCDEX CD-ROM
-		    ...
+ 12 block
 
  13 char	Input core
 		  0 = /dev/input/js0	First joystick
@@ -498,7 +503,7 @@ Your cooperation is appreciated.
 		  2 = /dev/midi00	First MIDI port
 		  3 = /dev/dsp		Digital audio
 		  4 = /dev/audio	Sun-compatible digital audio
-		  6 = /dev/sndstat	Sound card status information {2.6}
+		  6 =
 		  7 = /dev/audioctl	SPARC audio control device
 		  8 = /dev/sequencer2	Sequencer -- alternate device
 		 16 = /dev/mixer1	Second soundcard mixer control
@@ -510,14 +515,7 @@ Your cooperation is appreciated.
 		 34 = /dev/midi02	Third MIDI port
 		 50 = /dev/midi03	Fourth MIDI port
 
- 14 block	BIOS harddrive callback support {2.6}
-		  0 = /dev/dos_hda	First BIOS harddrive whole disk
-		 64 = /dev/dos_hdb	Second BIOS harddrive whole disk
-		128 = /dev/dos_hdc	Third BIOS harddrive whole disk
-		192 = /dev/dos_hdd	Fourth BIOS harddrive whole disk
-
-		Partitions are handled in the same way as IDE disks
-		(see major number 3).
+ 14 block
 
  15 char	Joystick
 		  0 = /dev/js0		First analog joystick
@@ -535,14 +533,14 @@ Your cooperation is appreciated.
  16 block	GoldStar CD-ROM
 		  0 = /dev/gscd		GoldStar CD-ROM
 
- 17 char	Chase serial card
+ 17 char	OBSOLETE (was Chase serial card)
 		  0 = /dev/ttyH0	First Chase port
 		  1 = /dev/ttyH1	Second Chase port
 		    ...
  17 block	Optics Storage CD-ROM
 		  0 = /dev/optcd	Optics Storage CD-ROM
 
- 18 char	Chase serial card - alternate devices
+ 18 char	OBSOLETE (was Chase serial card - alternate devices)
 		  0 = /dev/cuh0		Callout device for ttyH0
 		  1 = /dev/cuh1		Callout device for ttyH1
 		    ...
@@ -644,8 +642,7 @@ Your cooperation is appreciated.
 		  2 = /dev/sbpcd2	Panasonic CD-ROM controller 0 unit 2
 		  3 = /dev/sbpcd3	Panasonic CD-ROM controller 0 unit 3
 
- 26 char	Quanta WinVision frame grabber {2.6}
-		  0 = /dev/wvisfgrab	Quanta WinVision frame grabber
+ 26 char
 
  26 block	Second Matsushita (Panasonic/SoundBlaster) CD-ROM
 		  0 = /dev/sbpcd4	Panasonic CD-ROM controller 1 unit 0
@@ -872,7 +869,7 @@ Your cooperation is appreciated.
 		and "user level packet I/O."  This board is also
 		accessible as a standard networking "eth" device.
 
- 38 block	Reserved for Linux/AP+
+ 38 block	OBSOLETE (was Linux/AP+)
 
  39 char	ML-16P experimental I/O board
 		  0 = /dev/ml16pa-a0	First card, first analog channel
@@ -892,29 +889,16 @@ Your cooperation is appreciated.
 		 50 = /dev/ml16pb-c1	Second card, second counter/timer
 		 51 = /dev/ml16pb-c2	Second card, third counter/timer
 		      ...
- 39 block	Reserved for Linux/AP+
-
- 40 char	Matrox Meteor frame grabber {2.6}
-		  0 = /dev/mmetfgrab	Matrox Meteor frame grabber
+ 39 block
 
- 40 block	Syquest EZ135 parallel port removable drive
-		  0 = /dev/eza		Parallel EZ135 drive, whole disk
+ 40 char
 
-		This device is obsolete and will be removed in a
-		future version of Linux.  It has been replaced with
-		the parallel port IDE disk driver at major number 45.
-		Partitions are handled in the same way as IDE disks
-		(see major number 3).
+ 40 block
 
  41 char	Yet Another Micro Monitor
 		  0 = /dev/yamm		Yet Another Micro Monitor
 
- 41 block	MicroSolutions BackPack parallel port CD-ROM
-		  0 = /dev/bpcd		BackPack CD-ROM
-
-		This device is obsolete and will be removed in a
-		future version of Linux.  It has been replaced with
-		the parallel port ATAPI CD-ROM driver at major number 46.
+ 41 block
 
  42 char	Demo/sample use
 
@@ -1681,13 +1665,7 @@ Your cooperation is appreciated.
 		disks (see major number 3) except that the limit on
 		partitions is 15.
 
- 93 char	IBM Smart Capture Card frame grabber {2.6}
-		  0 = /dev/iscc0	First Smart Capture Card
-		  1 = /dev/iscc1	Second Smart Capture Card
-		    ...
-		128 = /dev/isccctl0	First Smart Capture Card control
-		129 = /dev/isccctl1	Second Smart Capture Card control
-		    ...
+ 93 char
 
  93 block	NAND Flash Translation Layer filesystem
 		  0 = /dev/nftla	First NFTL layer
@@ -1695,10 +1673,7 @@ Your cooperation is appreciated.
 		    ...
 		240 = /dev/nftlp	16th NTFL layer
 
- 94 char	miroVIDEO DC10/30 capture/playback device {2.6}
-		  0 = /dev/dcxx0	First capture card
-		  1 = /dev/dcxx1	Second capture card
-		    ...
+ 94 char
 
  94 block	IBM S/390 DASD block storage
     		  0 = /dev/dasda First DASD device, major
@@ -1791,11 +1766,7 @@ Your cooperation is appreciated.
 		    ...
 		 15 = /dev/amiraid/ar?p15 15th partition
 
-102 char	Philips SAA5249 Teletext signal decoder {2.6}
-		  0 = /dev/tlk0		First Teletext decoder
-		  1 = /dev/tlk1		Second Teletext decoder
-		  2 = /dev/tlk2		Third Teletext decoder
-		  3 = /dev/tlk3		Fourth Teletext decoder
+102 char
 
 102 block	Compressed block device
 		  0 = /dev/cbd/a	First compressed block device, whole device
@@ -1916,10 +1887,7 @@ Your cooperation is appreciated.
 		DAC960 (see major number 48) except that the limit on
 		partitions is 15.
 
-111 char	Philips SAA7146-based audio/video card {2.6}
-		  0 = /dev/av0		First A/V card
-		  1 = /dev/av1		Second A/V card
-		    ...
+111 char
 
 111 block	Compaq Next Generation Drive Array, eighth controller
 		  0 = /dev/cciss/c7d0	First logical drive, whole disk
@@ -2079,8 +2047,8 @@ Your cooperation is appreciated.
 		    ...
 
 119 char	VMware virtual network control
-		  0 = /dev/vmnet0	1st virtual network
-		  1 = /dev/vmnet1	2nd virtual network
+		  0 = /dev/vnet0	1st virtual network
+		  1 = /dev/vnet1	2nd virtual network
 		    ...
 
 120-127 char	LOCAL/EXPERIMENTAL USE
@@ -2450,7 +2418,7 @@ Your cooperation is appreciated.
 		  2 = /dev/raw/raw2	Second raw I/O device
 		    ...
 
-163 char	UNASSIGNED (was Radio Tech BIM-XXX-RS232 radio modem - see 51)
+163 char
 
 164 char	Chase Research AT/PCI-Fast serial card
 		  0 = /dev/ttyCH0	AT/PCI-Fast board 0, port 0
@@ -2542,6 +2510,12 @@ Your cooperation is appreciated.
 		  1 = /dev/clanvi1	Second cLAN adapter
 		    ...
 
+179 block       MMC block devices
+		  0 = /dev/mmcblk0      First SD/MMC card
+		  1 = /dev/mmcblk0p1    First partition on first MMC card
+		  8 = /dev/mmcblk1      Second SD/MMC card
+		    ...
+
 179 char	CCube DVXChip-based PCI products
 		  0 = /dev/dvxirq0	First DVX device
 		  1 = /dev/dvxirq1	Second DVX device
@@ -2560,6 +2534,9 @@ Your cooperation is appreciated.
 		 96 = /dev/usb/hiddev0	1st USB HID device
 		    ...
 		111 = /dev/usb/hiddev15	16th USB HID device
+		112 = /dev/usb/auer0	1st auerswald ISDN device
+		    ...
+		127 = /dev/usb/auer15	16th auerswald ISDN device
 		128 = /dev/usb/brlvgr0	First Braille Voyager device
 		    ...
 		131 = /dev/usb/brlvgr3	Fourth Braille Voyager device
@@ -2810,6 +2787,20 @@ Your cooperation is appreciated.
 		    ...
 		 190 = /dev/ttyUL3		Xilinx uartlite - port 3
 		 191 = /dev/xvc0		Xen virtual console - port 0
+		 192 = /dev/ttyPZ0		pmac_zilog - port 0
+		    ...
+		 195 = /dev/ttyPZ3		pmac_zilog - port 3
+		 196 = /dev/ttyTX0		TX39/49 serial port 0
+		    ...
+		 204 = /dev/ttyTX7		TX39/49 serial port 7
+		 205 = /dev/ttySC0		SC26xx serial port 0
+		 206 = /dev/ttySC1		SC26xx serial port 1
+		 207 = /dev/ttySC2		SC26xx serial port 2
+		 208 = /dev/ttySC3		SC26xx serial port 3
+		 209 = /dev/ttyMAX0		MAX3100 serial port 0
+		 210 = /dev/ttyMAX1		MAX3100 serial port 1
+		 211 = /dev/ttyMAX2		MAX3100 serial port 2
+		 212 = /dev/ttyMAX3		MAX3100 serial port 3
 
 205 char	Low-density serial ports (alternate device)
 		  0 = /dev/culu0		Callout device for ttyLU0
@@ -3145,6 +3136,20 @@ Your cooperation is appreciated.
 		  1 = /dev/blockrom1	Second ROM card's translation layer interface
 		  ...
 
+259 block	Block Extended Major
+		  Used dynamically to hold additional partition minor
+		  numbers and allow large numbers of partitions per device
+
+259 char	FPGA configuration interfaces
+		  0 = /dev/icap0	First Xilinx internal configuration
+		  1 = /dev/icap1	Second Xilinx internal configuration
+
+260 char	OSD (Object-based-device) SCSI Device
+		  0 = /dev/osd0		First OSD Device
+		  1 = /dev/osd1		Second OSD Device
+		  ...
+		  255 = /dev/osd255	256th OSD Device
+
  ****	ADDITIONAL /dev DIRECTORY ENTRIES
 
 This section details additional entries that should or may exist in
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DMA-API.txt linux-libre-2.6.30-gnu1/Documentation/DMA-API.txt
--- linux-libre-2.6.29-gnu1/Documentation/DMA-API.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DMA-API.txt	2009-06-09 23:05:27.000000000 -0400
@@ -609,3 +609,109 @@ size is the size (and should be a page-s
 The return value will be either a pointer to the processor virtual
 address of the memory, or an error (via PTR_ERR()) if any part of the
 region is occupied.
+
+Part III - Debug drivers use of the DMA-API
+-------------------------------------------
+
+The DMA-API as described above as some constraints. DMA addresses must be
+released with the corresponding function with the same size for example. With
+the advent of hardware IOMMUs it becomes more and more important that drivers
+do not violate those constraints. In the worst case such a violation can
+result in data corruption up to destroyed filesystems.
+
+To debug drivers and find bugs in the usage of the DMA-API checking code can
+be compiled into the kernel which will tell the developer about those
+violations. If your architecture supports it you can select the "Enable
+debugging of DMA-API usage" option in your kernel configuration. Enabling this
+option has a performance impact. Do not enable it in production kernels.
+
+If you boot the resulting kernel will contain code which does some bookkeeping
+about what DMA memory was allocated for which device. If this code detects an
+error it prints a warning message with some details into your kernel log. An
+example warning message may look like this:
+
+------------[ cut here ]------------
+WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
+	check_unmap+0x203/0x490()
+Hardware name:
+forcedeth 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong
+	function [device address=0x00000000640444be] [size=66 bytes] [mapped as
+single] [unmapped as page]
+Modules linked in: nfsd exportfs bridge stp llc r8169
+Pid: 0, comm: swapper Tainted: G        W  2.6.28-dmatest-09289-g8bb99c0 #1
+Call Trace:
+ <IRQ>  [<ffffffff80240b22>] warn_slowpath+0xf2/0x130
+ [<ffffffff80647b70>] _spin_unlock+0x10/0x30
+ [<ffffffff80537e75>] usb_hcd_link_urb_to_ep+0x75/0xc0
+ [<ffffffff80647c22>] _spin_unlock_irqrestore+0x12/0x40
+ [<ffffffff8055347f>] ohci_urb_enqueue+0x19f/0x7c0
+ [<ffffffff80252f96>] queue_work+0x56/0x60
+ [<ffffffff80237e10>] enqueue_task_fair+0x20/0x50
+ [<ffffffff80539279>] usb_hcd_submit_urb+0x379/0xbc0
+ [<ffffffff803b78c3>] cpumask_next_and+0x23/0x40
+ [<ffffffff80235177>] find_busiest_group+0x207/0x8a0
+ [<ffffffff8064784f>] _spin_lock_irqsave+0x1f/0x50
+ [<ffffffff803c7ea3>] check_unmap+0x203/0x490
+ [<ffffffff803c8259>] debug_dma_unmap_page+0x49/0x50
+ [<ffffffff80485f26>] nv_tx_done_optimized+0xc6/0x2c0
+ [<ffffffff80486c13>] nv_nic_irq_optimized+0x73/0x2b0
+ [<ffffffff8026df84>] handle_IRQ_event+0x34/0x70
+ [<ffffffff8026ffe9>] handle_edge_irq+0xc9/0x150
+ [<ffffffff8020e3ab>] do_IRQ+0xcb/0x1c0
+ [<ffffffff8020c093>] ret_from_intr+0x0/0xa
+ <EOI> <4>---[ end trace f6435a98e2a38c0e ]---
+
+The driver developer can find the driver and the device including a stacktrace
+of the DMA-API call which caused this warning.
+
+Per default only the first error will result in a warning message. All other
+errors will only silently counted. This limitation exist to prevent the code
+from flooding your kernel log. To support debugging a device driver this can
+be disabled via debugfs. See the debugfs interface documentation below for
+details.
+
+The debugfs directory for the DMA-API debugging code is called dma-api/. In
+this directory the following files can currently be found:
+
+	dma-api/all_errors	This file contains a numeric value. If this
+				value is not equal to zero the debugging code
+				will print a warning for every error it finds
+				into the kernel log. Be carefull with this
+				option. It can easily flood your logs.
+
+	dma-api/disabled	This read-only file contains the character 'Y'
+				if the debugging code is disabled. This can
+				happen when it runs out of memory or if it was
+				disabled at boot time
+
+	dma-api/error_count	This file is read-only and shows the total
+				numbers of errors found.
+
+	dma-api/num_errors	The number in this file shows how many
+				warnings will be printed to the kernel log
+				before it stops. This number is initialized to
+				one at system boot and be set by writing into
+				this file
+
+	dma-api/min_free_entries
+				This read-only file can be read to get the
+				minimum number of free dma_debug_entries the
+				allocator has ever seen. If this value goes
+				down to zero the code will disable itself
+				because it is not longer reliable.
+
+	dma-api/num_free_entries
+				The current number of free dma_debug_entries
+				in the allocator.
+
+If you have this code compiled into your kernel it will be enabled by default.
+If you want to boot without the bookkeeping anyway you can provide
+'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
+Notice that you can not enable it again at runtime. You have to reboot to do
+so.
+
+When the code disables itself at runtime this is most likely because it ran
+out of dma_debug_entries. These entries are preallocated at boot. The number
+of preallocated entries is defined per architecture. If it is too low for you
+boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
+architectural default.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DMA-mapping.txt linux-libre-2.6.30-gnu1/Documentation/DMA-mapping.txt
--- linux-libre-2.6.29-gnu1/Documentation/DMA-mapping.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DMA-mapping.txt	2009-06-09 23:05:27.000000000 -0400
@@ -136,7 +136,7 @@ exactly why.
 The standard 32-bit addressing PCI device would do something like
 this:
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
 		goto ignore_this_device;
@@ -155,9 +155,9 @@ all 64-bits when accessing streaming DMA
 
 	int using_dac;
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		using_dac = 0;
 	} else {
 		printk(KERN_WARNING
@@ -170,14 +170,14 @@ the case would look like this:
 
 	int using_dac, consistent_using_dac;
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		using_dac = 1;
 	   	consistent_using_dac = 1;
-		pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+		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_32BIT_MASK);
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	} else {
 		printk(KERN_WARNING
 		       "mydev: No suitable DMA available.\n");
@@ -192,7 +192,7 @@ check the return value from pci_set_cons
 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_24BIT_MASK)) {
+	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;
@@ -213,7 +213,7 @@ most specific mask.
 
 Here is pseudo-code showing how this might be done:
 
-	#define PLAYBACK_ADDRESS_BITS	DMA_32BIT_MASK
+	#define PLAYBACK_ADDRESS_BITS	DMA_BIT_MASK(32)
 	#define RECORD_ADDRESS_BITS	0x00ffffff
 
 	struct my_sound_card *card;
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/alsa-driver-api.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/alsa-driver-api.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/alsa-driver-api.tmpl	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/alsa-driver-api.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,109 @@
+<?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" []>
+
+<!-- ****************************************************** -->
+<!-- Header  -->
+<!-- ****************************************************** -->
+<book id="ALSA-Driver-API">
+  <bookinfo>
+    <title>The ALSA Driver API</title>
+
+    <legalnotice>
+    <para>
+    This document is free; you can redistribute it and/or modify it
+    under the terms of the 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 document is distributed in the hope that it will be useful,
+    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
+    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
+    PARTICULAR PURPOSE</emphasis>. 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>
+    </legalnotice>
+
+  </bookinfo>
+
+<toc></toc>
+
+  <chapter><title>Management of Cards and Devices</title>
+     <sect1><title>Card Management</title>
+!Esound/core/init.c
+     </sect1>
+     <sect1><title>Device Components</title>
+!Esound/core/device.c
+     </sect1>
+     <sect1><title>Module requests and Device File Entries</title>
+!Esound/core/sound.c
+     </sect1>
+     <sect1><title>Memory Management Helpers</title>
+!Esound/core/memory.c
+!Esound/core/memalloc.c
+     </sect1>
+  </chapter>
+  <chapter><title>PCM API</title>
+     <sect1><title>PCM Core</title>
+!Esound/core/pcm.c
+!Esound/core/pcm_lib.c
+!Esound/core/pcm_native.c
+     </sect1>
+     <sect1><title>PCM Format Helpers</title>
+!Esound/core/pcm_misc.c
+     </sect1>
+     <sect1><title>PCM Memory Management</title>
+!Esound/core/pcm_memory.c
+     </sect1>
+  </chapter>
+  <chapter><title>Control/Mixer API</title>
+     <sect1><title>General Control Interface</title>
+!Esound/core/control.c
+     </sect1>
+     <sect1><title>AC97 Codec API</title>
+!Esound/pci/ac97/ac97_codec.c
+!Esound/pci/ac97/ac97_pcm.c
+     </sect1>
+     <sect1><title>Virtual Master Control API</title>
+!Esound/core/vmaster.c
+!Iinclude/sound/control.h
+     </sect1>
+  </chapter>
+  <chapter><title>MIDI API</title>
+     <sect1><title>Raw MIDI API</title>
+!Esound/core/rawmidi.c
+     </sect1>
+     <sect1><title>MPU401-UART API</title>
+!Esound/drivers/mpu401/mpu401_uart.c
+     </sect1>
+  </chapter>
+  <chapter><title>Proc Info API</title>
+     <sect1><title>Proc Info Interface</title>
+!Esound/core/info.c
+     </sect1>
+  </chapter>
+  <chapter><title>Miscellaneous Functions</title>
+     <sect1><title>Hardware-Dependent Devices API</title>
+!Esound/core/hwdep.c
+     </sect1>
+     <sect1><title>Jack Abstraction Layer API</title>
+!Esound/core/jack.c
+     </sect1>
+     <sect1><title>ISA DMA Helpers</title>
+!Esound/core/isadma.c
+     </sect1>
+     <sect1><title>Other Helper Macros</title>
+!Iinclude/sound/core.h
+     </sect1>
+  </chapter>
+
+</book>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/genericirq.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/genericirq.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/genericirq.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/genericirq.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -440,6 +440,7 @@ desc->chip->end();
      used in the generic IRQ layer.
      </para>
 !Iinclude/linux/irq.h
+!Iinclude/linux/interrupt.h
   </chapter>
 
   <chapter id="pubfunctions">
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/.gitignore linux-libre-2.6.30-gnu1/Documentation/DocBook/.gitignore
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/.gitignore	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/.gitignore	2009-06-09 23:05:27.000000000 -0400
@@ -4,3 +4,7 @@
 *.html
 *.9.gz
 *.9
+*.aux
+*.dvi
+*.log
+*.out
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/kernel-api.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/kernel-api.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/kernel-api.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/kernel-api.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -190,15 +190,20 @@ X!Ekernel/module.c
 !Edrivers/pci/pci.c
 !Edrivers/pci/pci-driver.c
 !Edrivers/pci/remove.c
-!Edrivers/pci/pci-acpi.c
 !Edrivers/pci/search.c
 !Edrivers/pci/msi.c
 !Edrivers/pci/bus.c
+!Edrivers/pci/access.c
+!Edrivers/pci/irq.c
+!Edrivers/pci/htirq.c
 <!-- FIXME: Removed for now since no structured comments in source
 X!Edrivers/pci/hotplug.c
 -->
 !Edrivers/pci/probe.c
+!Edrivers/pci/slot.c
 !Edrivers/pci/rom.c
+!Edrivers/pci/iov.c
+!Idrivers/pci/pci-sysfs.c
      </sect1>
      <sect1><title>PCI Hotplug Support Library</title>
 !Edrivers/pci/hotplug/pci_hotplug_core.c
@@ -258,7 +263,7 @@ X!Earch/x86/kernel/mca_32.c
 !Eblock/blk-tag.c
 !Iblock/blk-tag.c
 !Eblock/blk-integrity.c
-!Iblock/blktrace.c
+!Ikernel/trace/blktrace.c
 !Iblock/genhd.c
 !Eblock/genhd.c
   </chapter>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/kgdb.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/kgdb.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/kgdb.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/kgdb.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -281,7 +281,7 @@
     seriously wrong while debugging, it will most often be the case
     that you want to enable gdb to be verbose about its target
     communications.  You do this prior to issuing the <constant>target
-    remote</constant> command by typing in: <constant>set remote debug 1</constant>
+    remote</constant> command by typing in: <constant>set debug remote 1</constant>
     </para>
   </chapter>
   <chapter id="KGDBTestSuite">
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/mac80211.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/mac80211.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/mac80211.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/mac80211.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -17,8 +17,7 @@
     </authorgroup>
 
     <copyright>
-      <year>2007</year>
-      <year>2008</year>
+      <year>2007-2009</year>
       <holder>Johannes Berg</holder>
     </copyright>
 
@@ -165,8 +164,8 @@ usage should require reading the full do
 !Pinclude/net/mac80211.h Frame format
       </sect1>
       <sect1>
-        <title>Alignment issues</title>
-        <para>TBD</para>
+        <title>Packet alignment</title>
+!Pnet/mac80211/rx.c Packet alignment
       </sect1>
       <sect1>
         <title>Calling into mac80211 from interrupts</title>
@@ -223,6 +222,17 @@ usage should require reading the full do
 !Finclude/net/mac80211.h ieee80211_key_flags
     </chapter>
 
+    <chapter id="powersave">
+      <title>Powersave support</title>
+!Pinclude/net/mac80211.h Powersave support
+    </chapter>
+
+    <chapter id="beacon-filter">
+      <title>Beacon filter support</title>
+!Pinclude/net/mac80211.h Beacon filter support
+!Finclude/net/mac80211.h ieee80211_beacon_loss
+    </chapter>
+
     <chapter id="qos">
       <title>Multiple queues and QoS support</title>
       <para>TBD</para>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/Makefile linux-libre-2.6.30-gnu1/Documentation/DocBook/Makefile
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,8 @@ DOCBOOKS := z8530book.xml mcabook.xml de
 	    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 \
-	    mac80211.xml debugobjects.xml sh.xml regulator.xml
+	    mac80211.xml debugobjects.xml sh.xml regulator.xml \
+	    alsa-driver-api.xml writing-an-alsa-driver.xml
 
 ###
 # The build process is as follows (targets):
@@ -30,7 +31,7 @@ PS_METHOD	= $(prefer-db2x)
 
 ###
 # The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs
 
 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
 xmldocs: $(BOOKS)
@@ -142,7 +143,8 @@ quiet_cmd_db2pdf = PDF     $@
 	$(call cmd,db2pdf)
 
 
-main_idx = Documentation/DocBook/index.html
+index = index.html
+main_idx = Documentation/DocBook/$(index)
 build_main_index = rm -rf $(main_idx) && \
 		   echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
 		   echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
@@ -212,11 +214,12 @@ silent_gen_xml = :
 dochelp:
 	@echo  ' Linux kernel internal documentation in different formats:'
 	@echo  '  htmldocs        - HTML'
-	@echo  '  installmandocs  - install man pages generated by mandocs'
-	@echo  '  mandocs         - man pages'
 	@echo  '  pdfdocs         - PDF'
 	@echo  '  psdocs          - Postscript'
 	@echo  '  xmldocs         - XML DocBook'
+	@echo  '  mandocs         - man pages'
+	@echo  '  installmandocs  - install man pages generated by mandocs'
+	@echo  '  cleandocs       - clean all generated DocBook files'
 
 ###
 # Temporary files left by various tools
@@ -230,10 +233,14 @@ clean-files := $(DOCBOOKS) \
 	$(patsubst %.xml, %.pdf,  $(DOCBOOKS)) \
 	$(patsubst %.xml, %.html, $(DOCBOOKS)) \
 	$(patsubst %.xml, %.9,    $(DOCBOOKS)) \
-	$(C-procfs-example)
+	$(C-procfs-example) $(index)
 
 clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
 
+cleandocs:
+	$(Q)rm -f $(call objectify, $(clean-files))
+	$(Q)rm -rf $(call objectify, $(clean-dirs))
+
 # Declare the contents of the .PHONY variable as phony.  We keep that
 # information in a variable se we can use it in if_changed and friends.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/procfs_example.c linux-libre-2.6.30-gnu1/Documentation/DocBook/procfs_example.c
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/procfs_example.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/procfs_example.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,9 +117,6 @@ static int __init init_procfs_example(vo
 		rv = -ENOMEM;
 		goto out;
 	}
-	
-	example_dir->owner = THIS_MODULE;
-	
 	/* create jiffies using convenience function */
 	jiffies_file = create_proc_read_entry("jiffies", 
 					      0444, example_dir, 
@@ -130,8 +127,6 @@ static int __init init_procfs_example(vo
 		goto no_jiffies;
 	}
 
-	jiffies_file->owner = THIS_MODULE;
-
 	/* create foo and bar files using same callback
 	 * functions 
 	 */
@@ -146,7 +141,6 @@ static int __init init_procfs_example(vo
 	foo_file->data = &foo_data;
 	foo_file->read_proc = proc_read_foobar;
 	foo_file->write_proc = proc_write_foobar;
-	foo_file->owner = THIS_MODULE;
 		
 	bar_file = create_proc_entry("bar", 0644, example_dir);
 	if(bar_file == NULL) {
@@ -159,7 +153,6 @@ static int __init init_procfs_example(vo
 	bar_file->data = &bar_data;
 	bar_file->read_proc = proc_read_foobar;
 	bar_file->write_proc = proc_write_foobar;
-	bar_file->owner = THIS_MODULE;
 		
 	/* create symlink */
 	symlink = proc_symlink("jiffies_too", example_dir, 
@@ -169,8 +162,6 @@ static int __init init_procfs_example(vo
 		goto no_symlink;
 	}
 
-	symlink->owner = THIS_MODULE;
-
 	/* everything OK */
 	printk(KERN_INFO "%s %s initialised\n",
 	       MODULE_NAME, MODULE_VERS);
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/uio-howto.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/uio-howto.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/uio-howto.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/uio-howto.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,13 @@ GPL version 2.
 
 <revhistory>
 	<revision>
+	<revnumber>0.8</revnumber>
+	<date>2008-12-24</date>
+	<authorinitials>hjk</authorinitials>
+	<revremark>Added name attributes in mem and portio sysfs directories.
+		</revremark>
+	</revision>
+	<revision>
 	<revnumber>0.7</revnumber>
 	<date>2008-12-23</date>
 	<authorinitials>hjk</authorinitials>
@@ -303,12 +310,19 @@ interested in translating it, please ema
 	appear if the size of the mapping is not 0.
 </para>
 <para>
-	Each <filename>mapX/</filename> directory contains two read-only files
-	that show start address and size of the memory:
+	Each <filename>mapX/</filename> directory contains four read-only files
+	that show attributes of the memory:
 </para>
 <itemizedlist>
 <listitem>
 	<para>
+	<filename>name</filename>: A string identifier for this mapping. This
+	is optional, the string can be empty. Drivers can set this to make it
+	easier for userspace to find the correct mapping.
+	</para>
+</listitem>
+<listitem>
+	<para>
 	<filename>addr</filename>: The address of memory that can be mapped.
 	</para>
 </listitem>
@@ -366,12 +380,19 @@ offset = N * getpagesize();
 	<filename>/sys/class/uio/uioX/portio/</filename>.
 </para>
 <para>
-	Each <filename>portX/</filename> directory contains three read-only
-	files that show start, size, and type of the port region:
+	Each <filename>portX/</filename> directory contains four read-only
+	files that show name, start, size, and type of the port region:
 </para>
 <itemizedlist>
 <listitem>
 	<para>
+	<filename>name</filename>: A string identifier for this port region.
+	The string is optional and can be empty. Drivers can set it to make it
+	easier for userspace to find a certain port region.
+	</para>
+</listitem>
+<listitem>
+	<para>
 	<filename>start</filename>: The first port of this region.
 	</para>
 </listitem>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl linux-libre-2.6.30-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/DocBook/writing-an-alsa-driver.tmpl	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6216 @@
+<?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" []>
+
+<!-- ****************************************************** -->
+<!-- Header  -->
+<!-- ****************************************************** -->
+<book id="Writing-an-ALSA-Driver">
+  <bookinfo>
+    <title>Writing an ALSA Driver</title>
+    <author>
+      <firstname>Takashi</firstname>
+      <surname>Iwai</surname>
+      <affiliation>
+        <address>
+          <email>tiwai@suse.de</email>
+        </address>
+      </affiliation>
+     </author>
+
+     <date>Oct 15, 2007</date>
+     <edition>0.3.7</edition>
+
+    <abstract>
+      <para>
+        This document describes how to write an ALSA (Advanced Linux
+        Sound Architecture) driver.
+      </para>
+    </abstract>
+
+    <legalnotice>
+    <para>
+    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
+    </para>
+
+    <para>
+    This document is free; you can redistribute it and/or modify it
+    under the terms of the 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 document is distributed in the hope that it will be useful,
+    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
+    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
+    PARTICULAR PURPOSE</emphasis>. 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>
+    </legalnotice>
+
+  </bookinfo>
+
+<!-- ****************************************************** -->
+<!-- Preface  -->
+<!-- ****************************************************** -->
+  <preface id="preface">
+    <title>Preface</title>
+    <para>
+      This document describes how to write an
+      <ulink url="http://www.alsa-project.org/"><citetitle>
+      ALSA (Advanced Linux Sound Architecture)</citetitle></ulink>
+      driver. The document focuses mainly on PCI soundcards.
+      In the case of other device types, the API might
+      be different, too. However, at least the ALSA kernel API is
+      consistent, and therefore it would be still a bit help for
+      writing them.
+    </para>
+
+    <para>
+    This document targets people who already have enough
+    C language skills and have basic linux kernel programming
+    knowledge.  This document doesn't explain the general
+    topic of linux kernel coding and doesn't cover low-level
+    driver implementation details. It only describes
+    the standard way to write a PCI sound driver on ALSA.
+    </para>
+
+    <para>
+      If you are already familiar with the older ALSA ver.0.5.x API, you
+    can check the drivers such as <filename>sound/pci/es1938.c</filename> or
+    <filename>sound/pci/maestro3.c</filename> which have also almost the same
+    code-base in the ALSA 0.5.x tree, so you can compare the differences.
+    </para>
+
+    <para>
+      This document is still a draft version. Any feedback and
+    corrections, please!!
+    </para>
+  </preface>
+
+
+<!-- ****************************************************** -->
+<!-- File Tree Structure  -->
+<!-- ****************************************************** -->
+  <chapter id="file-tree">
+    <title>File Tree Structure</title>
+
+    <section id="file-tree-general">
+      <title>General</title>
+      <para>
+        The ALSA drivers are provided in two ways.
+      </para>
+
+      <para>
+        One is the trees provided as a tarball or via cvs from the
+      ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
+      tree. To synchronize both, the ALSA driver tree is split into
+      two different trees: alsa-kernel and alsa-driver. The former
+      contains purely the source code for the Linux 2.6 (or later)
+      tree. This tree is designed only for compilation on 2.6 or
+      later environment. The latter, alsa-driver, contains many subtle
+      files for compiling ALSA drivers outside of the Linux kernel tree,
+      wrapper functions for older 2.2 and 2.4 kernels, to adapt the latest kernel API,
+      and additional drivers which are still in development or in
+      tests.  The drivers in alsa-driver tree will be moved to
+      alsa-kernel (and eventually to the 2.6 kernel tree) when they are
+      finished and confirmed to work fine.
+      </para>
+
+      <para>
+        The file tree structure of ALSA driver is depicted below. Both
+        alsa-kernel and alsa-driver have almost the same file
+        structure, except for <quote>core</quote> directory. It's
+        named as <quote>acore</quote> in alsa-driver tree. 
+
+        <example>
+          <title>ALSA File Tree Structure</title>
+          <literallayout>
+        sound
+                /core
+                        /oss
+                        /seq
+                                /oss
+                                /instr
+                /ioctl32
+                /include
+                /drivers
+                        /mpu401
+                        /opl3
+                /i2c
+                        /l3
+                /synth
+                        /emux
+                /pci
+                        /(cards)
+                /isa
+                        /(cards)
+                /arm
+                /ppc
+                /sparc
+                /usb
+                /pcmcia /(cards)
+                /oss
+          </literallayout>
+        </example>
+      </para>
+    </section>
+
+    <section id="file-tree-core-directory">
+      <title>core directory</title>
+      <para>
+        This directory contains the middle layer which is the heart
+      of ALSA drivers. In this directory, the native ALSA modules are
+      stored. The sub-directories contain different modules and are
+      dependent upon the kernel config. 
+      </para>
+
+      <section id="file-tree-core-directory-oss">
+        <title>core/oss</title>
+
+        <para>
+          The codes for PCM and mixer OSS emulation modules are stored
+        in this directory. The rawmidi OSS emulation is included in
+        the ALSA rawmidi code since it's quite small. The sequencer
+        code is stored in <filename>core/seq/oss</filename> directory (see
+        <link linkend="file-tree-core-directory-seq-oss"><citetitle>
+        below</citetitle></link>).
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-ioctl32">
+        <title>core/ioctl32</title>
+
+        <para>
+          This directory contains the 32bit-ioctl wrappers for 64bit
+        architectures such like x86-64, ppc64 and sparc64. For 32bit
+        and alpha architectures, these are not compiled. 
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-seq">
+        <title>core/seq</title>
+        <para>
+          This directory and its sub-directories are for the ALSA
+        sequencer. This directory contains the sequencer core and
+        primary sequencer modules such like snd-seq-midi,
+        snd-seq-virmidi, etc. They are compiled only when
+        <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel
+        config. 
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-seq-oss">
+        <title>core/seq/oss</title>
+        <para>
+          This contains the OSS sequencer emulation codes.
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-deq-instr">
+        <title>core/seq/instr</title>
+        <para>
+          This directory contains the modules for the sequencer
+        instrument layer. 
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-include-directory">
+      <title>include directory</title>
+      <para>
+        This is the place for the public header files of ALSA drivers,
+      which are to be exported to user-space, or included by
+      several files at different directories. Basically, the private
+      header files should not be placed in this directory, but you may
+      still find files there, due to historical reasons :) 
+      </para>
+    </section>
+
+    <section id="file-tree-drivers-directory">
+      <title>drivers directory</title>
+      <para>
+        This directory contains code shared among different drivers
+      on different architectures.  They are hence supposed not to be
+      architecture-specific.
+      For example, the dummy pcm driver and the serial MIDI
+      driver are found in this directory. In the sub-directories,
+      there is code for components which are independent from
+      bus and cpu architectures. 
+      </para>
+
+      <section id="file-tree-drivers-directory-mpu401">
+        <title>drivers/mpu401</title>
+        <para>
+          The MPU401 and MPU401-UART modules are stored here.
+        </para>
+      </section>
+
+      <section id="file-tree-drivers-directory-opl3">
+        <title>drivers/opl3 and opl4</title>
+        <para>
+          The OPL3 and OPL4 FM-synth stuff is found here.
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-i2c-directory">
+      <title>i2c directory</title>
+      <para>
+        This contains the ALSA i2c components.
+      </para>
+
+      <para>
+        Although there is a standard i2c layer on Linux, ALSA has its
+      own i2c code for some cards, because the soundcard needs only a
+      simple operation and the standard i2c API is too complicated for
+      such a purpose. 
+      </para>
+
+      <section id="file-tree-i2c-directory-l3">
+        <title>i2c/l3</title>
+        <para>
+          This is a sub-directory for ARM L3 i2c.
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-synth-directory">
+        <title>synth directory</title>
+        <para>
+          This contains the synth middle-level modules.
+        </para>
+
+        <para>
+          So far, there is only Emu8000/Emu10k1 synth driver under
+        the <filename>synth/emux</filename> sub-directory. 
+        </para>
+    </section>
+
+    <section id="file-tree-pci-directory">
+      <title>pci directory</title>
+      <para>
+        This directory and its sub-directories hold the top-level card modules
+      for PCI soundcards and the code specific to the PCI BUS.
+      </para>
+
+      <para>
+        The drivers compiled from a single file are stored directly
+      in the pci directory, while the drivers with several source files are
+      stored on their own sub-directory (e.g. emu10k1, ice1712). 
+      </para>
+    </section>
+
+    <section id="file-tree-isa-directory">
+      <title>isa directory</title>
+      <para>
+        This directory and its sub-directories hold the top-level card modules
+      for ISA soundcards. 
+      </para>
+    </section>
+
+    <section id="file-tree-arm-ppc-sparc-directories">
+      <title>arm, ppc, and sparc directories</title>
+      <para>
+        They are used for top-level card modules which are
+      specific to one of these architectures. 
+      </para>
+    </section>
+
+    <section id="file-tree-usb-directory">
+      <title>usb directory</title>
+      <para>
+        This directory contains the USB-audio driver. In the latest version, the
+      USB MIDI driver is integrated in the usb-audio driver. 
+      </para>
+    </section>
+
+    <section id="file-tree-pcmcia-directory">
+      <title>pcmcia directory</title>
+      <para>
+        The PCMCIA, especially PCCard drivers will go here. CardBus
+      drivers will be in the pci directory, because their API is identical
+      to that of standard PCI cards. 
+      </para>
+    </section>
+
+    <section id="file-tree-oss-directory">
+      <title>oss directory</title>
+      <para>
+        The OSS/Lite source files are stored here in Linux 2.6 (or
+      later) tree. In the ALSA driver tarball, this directory is empty,
+      of course :) 
+      </para>
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Basic Flow for PCI Drivers  -->
+<!-- ****************************************************** -->
+  <chapter id="basic-flow">
+    <title>Basic Flow for PCI Drivers</title>
+
+    <section id="basic-flow-outline">
+      <title>Outline</title>
+      <para>
+        The minimum flow for PCI soundcards is as follows:
+
+        <itemizedlist>
+          <listitem><para>define the PCI ID table (see the section
+          <link linkend="pci-resource-entries"><citetitle>PCI Entries
+          </citetitle></link>).</para></listitem> 
+          <listitem><para>create <function>probe()</function> callback.</para></listitem>
+          <listitem><para>create <function>remove()</function> callback.</para></listitem>
+          <listitem><para>create a <structname>pci_driver</structname> structure
+	  containing the three pointers above.</para></listitem>
+          <listitem><para>create an <function>init()</function> function just calling
+	  the <function>pci_register_driver()</function> to register the pci_driver table
+	  defined above.</para></listitem>
+          <listitem><para>create an <function>exit()</function> function to call
+	  the <function>pci_unregister_driver()</function> function.</para></listitem>
+        </itemizedlist>
+      </para>
+    </section>
+
+    <section id="basic-flow-example">
+      <title>Full Code Example</title>
+      <para>
+        The code example is shown below. Some parts are kept
+      unimplemented at this moment but will be filled in the
+      next sections. The numbers in the comment lines of the
+      <function>snd_mychip_probe()</function> function
+      refer to details explained in the following section. 
+
+        <example>
+          <title>Basic Flow for PCI Drivers - Example</title>
+          <programlisting>
+<![CDATA[
+  #include <linux/init.h>
+  #include <linux/pci.h>
+  #include <linux/slab.h>
+  #include <sound/core.h>
+  #include <sound/initval.h>
+
+  /* module parameters (see "Module Parameters") */
+  /* SNDRV_CARDS: maximum number of cards supported by this module */
+  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+  static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+  /* definition of the chip-specific record */
+  struct mychip {
+          struct snd_card *card;
+          /* the rest of the implementation will be in section
+           * "PCI Resource Management"
+           */
+  };
+
+  /* chip-specific destructor
+   * (see "PCI Resource Management")
+   */
+  static int snd_mychip_free(struct mychip *chip)
+  {
+          .... /* will be implemented later... */
+  }
+
+  /* component-destructor
+   * (see "Management of Cards and Components")
+   */
+  static int snd_mychip_dev_free(struct snd_device *device)
+  {
+          return snd_mychip_free(device->device_data);
+  }
+
+  /* chip-specific constructor
+   * (see "Management of Cards and Components")
+   */
+  static int __devinit snd_mychip_create(struct snd_card *card,
+                                         struct pci_dev *pci,
+                                         struct mychip **rchip)
+  {
+          struct mychip *chip;
+          int err;
+          static struct snd_device_ops ops = {
+                 .dev_free = snd_mychip_dev_free,
+          };
+
+          *rchip = NULL;
+
+          /* check PCI availability here
+           * (see "PCI Resource Management")
+           */
+          ....
+
+          /* allocate a chip-specific data with zero filled */
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          if (chip == NULL)
+                  return -ENOMEM;
+
+          chip->card = card;
+
+          /* rest of initialization here; will be implemented
+           * later, see "PCI Resource Management"
+           */
+          ....
+
+          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+          if (err < 0) {
+                  snd_mychip_free(chip);
+                  return err;
+          }
+
+          snd_card_set_dev(card, &pci->dev);
+
+          *rchip = chip;
+          return 0;
+  }
+
+  /* constructor -- see "Constructor" sub-section */
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          static int dev;
+          struct snd_card *card;
+          struct mychip *chip;
+          int err;
+
+          /* (1) */
+          if (dev >= SNDRV_CARDS)
+                  return -ENODEV;
+          if (!enable[dev]) {
+                  dev++;
+                  return -ENOENT;
+          }
+
+          /* (2) */
+          err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+          if (err < 0)
+                  return err;
+
+          /* (3) */
+          err = snd_mychip_create(card, pci, &chip);
+          if (err < 0) {
+                  snd_card_free(card);
+                  return err;
+          }
+
+          /* (4) */
+          strcpy(card->driver, "My Chip");
+          strcpy(card->shortname, "My Own Chip 123");
+          sprintf(card->longname, "%s at 0x%lx irq %i",
+                  card->shortname, chip->ioport, chip->irq);
+
+          /* (5) */
+          .... /* implemented later */
+
+          /* (6) */
+          err = snd_card_register(card);
+          if (err < 0) {
+                  snd_card_free(card);
+                  return err;
+          }
+
+          /* (7) */
+          pci_set_drvdata(pci, card);
+          dev++;
+          return 0;
+  }
+
+  /* destructor -- see the "Destructor" sub-section */
+  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  {
+          snd_card_free(pci_get_drvdata(pci));
+          pci_set_drvdata(pci, NULL);
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="basic-flow-constructor">
+      <title>Constructor</title>
+      <para>
+        The real constructor of PCI drivers is the <function>probe</function> callback.
+      The <function>probe</function> callback and other component-constructors which are called
+      from the <function>probe</function> callback should be defined with
+      the <parameter>__devinit</parameter> prefix. You 
+      cannot use the <parameter>__init</parameter> prefix for them,
+      because any PCI device could be a hotplug device. 
+      </para>
+
+      <para>
+        In the <function>probe</function> callback, the following scheme is often used.
+      </para>
+
+      <section id="basic-flow-constructor-device-index">
+        <title>1) Check and increment the device index.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int dev;
+  ....
+  if (dev >= SNDRV_CARDS)
+          return -ENODEV;
+  if (!enable[dev]) {
+          dev++;
+          return -ENOENT;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+        where enable[dev] is the module option.
+        </para>
+
+        <para>
+          Each time the <function>probe</function> callback is called, check the
+        availability of the device. If not available, simply increment
+        the device index and returns. dev will be incremented also
+        later (<link
+        linkend="basic-flow-constructor-set-pci"><citetitle>step
+        7</citetitle></link>). 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-card">
+        <title>2) Create a card instance</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct snd_card *card;
+  int err;
+  ....
+  err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The details will be explained in the section
+          <link linkend="card-management-card-instance"><citetitle>
+          Management of Cards and Components</citetitle></link>.
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-main">
+        <title>3) Create a main component</title>
+        <para>
+          In this part, the PCI resources are allocated.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct mychip *chip;
+  ....
+  err = snd_mychip_create(card, pci, &chip);
+  if (err < 0) {
+          snd_card_free(card);
+          return err;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          The details will be explained in the section <link
+        linkend="pci-resource"><citetitle>PCI Resource
+        Management</citetitle></link>.
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-main-component">
+        <title>4) Set the driver ID and name strings.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  strcpy(card->driver, "My Chip");
+  strcpy(card->shortname, "My Own Chip 123");
+  sprintf(card->longname, "%s at 0x%lx irq %i",
+          card->shortname, chip->ioport, chip->irq);
+]]>
+            </programlisting>
+          </informalexample>
+
+          The driver field holds the minimal ID string of the
+        chip. This is used by alsa-lib's configurator, so keep it
+        simple but unique. 
+          Even the same driver can have different driver IDs to
+        distinguish the functionality of each chip type. 
+        </para>
+
+        <para>
+          The shortname field is a string shown as more verbose
+        name. The longname field contains the information
+        shown in <filename>/proc/asound/cards</filename>. 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-other">
+        <title>5) Create other components, such as mixer, MIDI, etc.</title>
+        <para>
+          Here you define the basic components such as
+          <link linkend="pcm-interface"><citetitle>PCM</citetitle></link>,
+          mixer (e.g. <link linkend="api-ac97"><citetitle>AC97</citetitle></link>),
+          MIDI (e.g. <link linkend="midi-interface"><citetitle>MPU-401</citetitle></link>),
+          and other interfaces.
+          Also, if you want a <link linkend="proc-interface"><citetitle>proc
+        file</citetitle></link>, define it here, too.
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-register-card">
+        <title>6) Register the card instance.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  err = snd_card_register(card);
+  if (err < 0) {
+          snd_card_free(card);
+          return err;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Will be explained in the section <link
+        linkend="card-management-registration"><citetitle>Management
+        of Cards and Components</citetitle></link>, too. 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-set-pci">
+        <title>7) Set the PCI driver data and return zero.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+        pci_set_drvdata(pci, card);
+        dev++;
+        return 0;
+]]>
+            </programlisting>
+          </informalexample>
+
+          In the above, the card record is stored. This pointer is
+        used in the remove callback and power-management
+        callbacks, too. 
+        </para>
+      </section>
+    </section>
+
+    <section id="basic-flow-destructor">
+      <title>Destructor</title>
+      <para>
+        The destructor, remove callback, simply releases the card
+      instance. Then the ALSA middle layer will release all the
+      attached components automatically. 
+      </para>
+
+      <para>
+        It would be typically like the following:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  {
+          snd_card_free(pci_get_drvdata(pci));
+          pci_set_drvdata(pci, NULL);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+        The above code assumes that the card pointer is set to the PCI
+	driver data.
+      </para>
+    </section>
+
+    <section id="basic-flow-header-files">
+      <title>Header Files</title>
+      <para>
+        For the above example, at least the following include files
+      are necessary. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  #include <linux/init.h>
+  #include <linux/pci.h>
+  #include <linux/slab.h>
+  #include <sound/core.h>
+  #include <sound/initval.h>
+]]>
+          </programlisting>
+        </informalexample>
+
+	where the last one is necessary only when module options are
+      defined in the source file.  If the code is split into several
+      files, the files without module options don't need them.
+      </para>
+
+      <para>
+        In addition to these headers, you'll need
+      <filename>&lt;linux/interrupt.h&gt;</filename> for interrupt
+      handling, and <filename>&lt;asm/io.h&gt;</filename> for I/O
+      access. If you use the <function>mdelay()</function> or
+      <function>udelay()</function> functions, you'll need to include
+      <filename>&lt;linux/delay.h&gt;</filename> too. 
+      </para>
+
+      <para>
+      The ALSA interfaces like the PCM and control APIs are defined in other
+      <filename>&lt;sound/xxx.h&gt;</filename> header files.
+      They have to be included after
+      <filename>&lt;sound/core.h&gt;</filename>.
+      </para>
+
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Management of Cards and Components  -->
+<!-- ****************************************************** -->
+  <chapter id="card-management">
+    <title>Management of Cards and Components</title>
+
+    <section id="card-management-card-instance">
+      <title>Card Instance</title>
+      <para>
+      For each soundcard, a <quote>card</quote> record must be allocated.
+      </para>
+
+      <para>
+      A card record is the headquarters of the soundcard.  It manages
+      the whole list of devices (components) on the soundcard, such as
+      PCM, mixers, MIDI, synthesizer, and so on.  Also, the card
+      record holds the ID and the name strings of the card, manages
+      the root of proc files, and controls the power-management states
+      and hotplug disconnections.  The component list on the card
+      record is used to manage the correct release of resources at
+      destruction. 
+      </para>
+
+      <para>
+        As mentioned above, to create a card instance, call
+      <function>snd_card_create()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_card *card;
+  int err;
+  err = snd_card_create(index, id, module, extra_size, &card);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The function takes five arguments, the card-index number, the
+        id string, the module pointer (usually
+        <constant>THIS_MODULE</constant>),
+        the size of extra-data space, and the pointer to return the
+        card instance.  The extra_size argument is used to
+        allocate card-&gt;private_data for the
+        chip-specific data.  Note that these data
+        are allocated by <function>snd_card_create()</function>.
+      </para>
+    </section>
+
+    <section id="card-management-component">
+      <title>Components</title>
+      <para>
+        After the card is created, you can attach the components
+      (devices) to the card instance. In an ALSA driver, a component is
+      represented as a struct <structname>snd_device</structname> object.
+      A component can be a PCM instance, a control interface, a raw
+      MIDI interface, etc.  Each such instance has one component
+      entry.
+      </para>
+
+      <para>
+        A component can be created via
+        <function>snd_device_new()</function> function. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        This takes the card pointer, the device-level
+      (<constant>SNDRV_DEV_XXX</constant>), the data pointer, and the
+      callback pointers (<parameter>&amp;ops</parameter>). The
+      device-level defines the type of components and the order of
+      registration and de-registration.  For most components, the
+      device-level is already defined.  For a user-defined component,
+      you can use <constant>SNDRV_DEV_LOWLEVEL</constant>.
+      </para>
+
+      <para>
+      This function itself doesn't allocate the data space. The data
+      must be allocated manually beforehand, and its pointer is passed
+      as the argument. This pointer is used as the
+      (<parameter>chip</parameter> identifier in the above example)
+      for the instance. 
+      </para>
+
+      <para>
+        Each pre-defined ALSA component such as ac97 and pcm calls
+      <function>snd_device_new()</function> inside its
+      constructor. The destructor for each component is defined in the
+      callback pointers.  Hence, you don't need to take care of
+      calling a destructor for such a component.
+      </para>
+
+      <para>
+        If you wish to create your own component, you need to
+      set the destructor function to the dev_free callback in
+      the <parameter>ops</parameter>, so that it can be released
+      automatically via <function>snd_card_free()</function>.
+      The next example will show an implementation of chip-specific
+      data.
+      </para>
+    </section>
+
+    <section id="card-management-chip-specific">
+      <title>Chip-Specific Data</title>
+      <para>
+      Chip-specific information, e.g. the I/O port address, its
+      resource pointer, or the irq number, is stored in the
+      chip-specific record.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct mychip {
+          ....
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        In general, there are two ways of allocating the chip record.
+      </para>
+
+      <section id="card-management-chip-specific-snd-card-new">
+        <title>1. Allocating via <function>snd_card_create()</function>.</title>
+        <para>
+          As mentioned above, you can pass the extra-data-length
+	  to the 4th argument of <function>snd_card_create()</function>, i.e.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  err = snd_card_create(index[dev], id[dev], THIS_MODULE,
+                        sizeof(struct mychip), &card);
+]]>
+            </programlisting>
+          </informalexample>
+
+          struct <structname>mychip</structname> is the type of the chip record.
+        </para>
+
+        <para>
+          In return, the allocated record can be accessed as
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct mychip *chip = card->private_data;
+]]>
+            </programlisting>
+          </informalexample>
+
+          With this method, you don't have to allocate twice.
+          The record is released together with the card instance.
+        </para>
+      </section>
+
+      <section id="card-management-chip-specific-allocate-extra">
+        <title>2. Allocating an extra device.</title>
+
+        <para>
+          After allocating a card instance via
+          <function>snd_card_create()</function> (with
+          <constant>0</constant> on the 4th arg), call
+          <function>kzalloc()</function>. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct snd_card *card;
+  struct mychip *chip;
+  err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+  .....
+  chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The chip record should have the field to hold the card
+          pointer at least, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct mychip {
+          struct snd_card *card;
+          ....
+  };
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Then, set the card pointer in the returned chip instance.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  chip->card = card;
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Next, initialize the fields, and register this chip
+          record as a low-level device with a specified
+          <parameter>ops</parameter>, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static struct snd_device_ops ops = {
+          .dev_free =        snd_mychip_dev_free,
+  };
+  ....
+  snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+]]>
+            </programlisting>
+          </informalexample>
+
+          <function>snd_mychip_dev_free()</function> is the
+        device-destructor function, which will call the real
+        destructor. 
+        </para>
+
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_mychip_dev_free(struct snd_device *device)
+  {
+          return snd_mychip_free(device->device_data);
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          where <function>snd_mychip_free()</function> is the real destructor.
+        </para>
+      </section>
+    </section>
+
+    <section id="card-management-registration">
+      <title>Registration and Release</title>
+      <para>
+        After all components are assigned, register the card instance
+      by calling <function>snd_card_register()</function>. Access
+      to the device files is enabled at this point. That is, before
+      <function>snd_card_register()</function> is called, the
+      components are safely inaccessible from external side. If this
+      call fails, exit the probe function after releasing the card via
+      <function>snd_card_free()</function>. 
+      </para>
+
+      <para>
+        For releasing the card instance, you can call simply
+      <function>snd_card_free()</function>. As mentioned earlier, all
+      components are released automatically by this call. 
+      </para>
+
+      <para>
+        As further notes, the destructors (both
+      <function>snd_mychip_dev_free</function> and
+      <function>snd_mychip_free</function>) cannot be defined with
+      the <parameter>__devexit</parameter> prefix, because they may be
+      called from the constructor, too, at the false path. 
+      </para>
+
+      <para>
+      For a device which allows hotplugging, you can use
+      <function>snd_card_free_when_closed</function>.  This one will
+      postpone the destruction until all devices are closed.
+      </para>
+
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- PCI Resource Management  -->
+<!-- ****************************************************** -->
+  <chapter id="pci-resource">
+    <title>PCI Resource Management</title>
+
+    <section id="pci-resource-example">
+      <title>Full Code Example</title>
+      <para>
+        In this section, we'll complete the chip-specific constructor,
+      destructor and PCI entries. Example code is shown first,
+      below. 
+
+        <example>
+          <title>PCI Resource Management Example</title>
+          <programlisting>
+<![CDATA[
+  struct mychip {
+          struct snd_card *card;
+          struct pci_dev *pci;
+
+          unsigned long port;
+          int irq;
+  };
+
+  static int snd_mychip_free(struct mychip *chip)
+  {
+          /* disable hardware here if any */
+          .... /* (not implemented in this document) */
+
+          /* release the irq */
+          if (chip->irq >= 0)
+                  free_irq(chip->irq, chip);
+          /* release the I/O ports & memory */
+          pci_release_regions(chip->pci);
+          /* disable the PCI entry */
+          pci_disable_device(chip->pci);
+          /* release the data */
+          kfree(chip);
+          return 0;
+  }
+
+  /* chip-specific constructor */
+  static int __devinit snd_mychip_create(struct snd_card *card,
+                                         struct pci_dev *pci,
+                                         struct mychip **rchip)
+  {
+          struct mychip *chip;
+          int err;
+          static struct snd_device_ops ops = {
+                 .dev_free = snd_mychip_dev_free,
+          };
+
+          *rchip = NULL;
+
+          /* initialize the PCI entry */
+          err = pci_enable_device(pci);
+          if (err < 0)
+                  return err;
+          /* check PCI availability (28bit DMA) */
+          if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+              pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
+                  printk(KERN_ERR "error to set 28bit mask DMA\n");
+                  pci_disable_device(pci);
+                  return -ENXIO;
+          }
+
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          if (chip == NULL) {
+                  pci_disable_device(pci);
+                  return -ENOMEM;
+          }
+
+          /* initialize the stuff */
+          chip->card = card;
+          chip->pci = pci;
+          chip->irq = -1;
+
+          /* (1) PCI resource allocation */
+          err = pci_request_regions(pci, "My Chip");
+          if (err < 0) {
+                  kfree(chip);
+                  pci_disable_device(pci);
+                  return err;
+          }
+          chip->port = pci_resource_start(pci, 0);
+          if (request_irq(pci->irq, snd_mychip_interrupt,
+                          IRQF_SHARED, "My Chip", chip)) {
+                  printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+                  snd_mychip_free(chip);
+                  return -EBUSY;
+          }
+          chip->irq = pci->irq;
+
+          /* (2) initialization of the chip hardware */
+          .... /*   (not implemented in this document) */
+
+          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+          if (err < 0) {
+                  snd_mychip_free(chip);
+                  return err;
+          }
+
+          snd_card_set_dev(card, &pci->dev);
+
+          *rchip = chip;
+          return 0;
+  }        
+
+  /* PCI IDs */
+  static struct pci_device_id snd_mychip_ids[] = {
+          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+          ....
+          { 0, }
+  };
+  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
+
+  /* pci_driver definition */
+  static struct pci_driver driver = {
+          .name = "My Own Chip",
+          .id_table = snd_mychip_ids,
+          .probe = snd_mychip_probe,
+          .remove = __devexit_p(snd_mychip_remove),
+  };
+
+  /* module initialization */
+  static int __init alsa_card_mychip_init(void)
+  {
+          return pci_register_driver(&driver);
+  }
+
+  /* module clean up */
+  static void __exit alsa_card_mychip_exit(void)
+  {
+          pci_unregister_driver(&driver);
+  }
+
+  module_init(alsa_card_mychip_init)
+  module_exit(alsa_card_mychip_exit)
+
+  EXPORT_NO_SYMBOLS; /* for old kernels only */
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pci-resource-some-haftas">
+      <title>Some Hafta's</title>
+      <para>
+        The allocation of PCI resources is done in the
+      <function>probe()</function> function, and usually an extra
+      <function>xxx_create()</function> function is written for this
+      purpose.
+      </para>
+
+      <para>
+        In the case of PCI devices, you first have to call
+      the <function>pci_enable_device()</function> function before
+      allocating resources. Also, you need to set the proper PCI DMA
+      mask to limit the accessed I/O range. In some cases, you might
+      need to call <function>pci_set_master()</function> function,
+      too.
+      </para>
+
+      <para>
+        Suppose the 28bit mask, and the code to be added would be like:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  err = pci_enable_device(pci);
+  if (err < 0)
+          return err;
+  if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 ||
+      pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) {
+          printk(KERN_ERR "error to set 28bit mask DMA\n");
+          pci_disable_device(pci);
+          return -ENXIO;
+  }
+  
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="pci-resource-resource-allocation">
+      <title>Resource Allocation</title>
+      <para>
+        The allocation of I/O ports and irqs is done via standard kernel
+      functions. Unlike ALSA ver.0.5.x., there are no helpers for
+      that. And these resources must be released in the destructor
+      function (see below). Also, on ALSA 0.9.x, you don't need to
+      allocate (pseudo-)DMA for PCI like in ALSA 0.5.x.
+      </para>
+
+      <para>
+        Now assume that the PCI device has an I/O port with 8 bytes
+        and an interrupt. Then struct <structname>mychip</structname> will have the
+        following fields:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct mychip {
+          struct snd_card *card;
+
+          unsigned long port;
+          int irq;
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        For an I/O port (and also a memory region), you need to have
+      the resource pointer for the standard resource management. For
+      an irq, you have to keep only the irq number (integer). But you
+      need to initialize this number as -1 before actual allocation,
+      since irq 0 is valid. The port address and its resource pointer
+      can be initialized as null by
+      <function>kzalloc()</function> automatically, so you
+      don't have to take care of resetting them. 
+      </para>
+
+      <para>
+        The allocation of an I/O port is done like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  err = pci_request_regions(pci, "My Chip");
+  if (err < 0) { 
+          kfree(chip);
+          pci_disable_device(pci);
+          return err;
+  }
+  chip->port = pci_resource_start(pci, 0);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        <!-- obsolete -->
+        It will reserve the I/O port region of 8 bytes of the given
+      PCI device. The returned value, chip-&gt;res_port, is allocated
+      via <function>kmalloc()</function> by
+      <function>request_region()</function>. The pointer must be
+      released via <function>kfree()</function>, but there is a
+      problem with this. This issue will be explained later.
+      </para>
+
+      <para>
+        The allocation of an interrupt source is done like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (request_irq(pci->irq, snd_mychip_interrupt,
+                  IRQF_SHARED, "My Chip", chip)) {
+          printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+          snd_mychip_free(chip);
+          return -EBUSY;
+  }
+  chip->irq = pci->irq;
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <function>snd_mychip_interrupt()</function> is the
+      interrupt handler defined <link
+      linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>.
+      Note that chip-&gt;irq should be defined
+      only when <function>request_irq()</function> succeeded.
+      </para>
+
+      <para>
+      On the PCI bus, interrupts can be shared. Thus,
+      <constant>IRQF_SHARED</constant> is used as the interrupt flag of
+      <function>request_irq()</function>. 
+      </para>
+
+      <para>
+        The last argument of <function>request_irq()</function> is the
+      data pointer passed to the interrupt handler. Usually, the
+      chip-specific record is used for that, but you can use what you
+      like, too. 
+      </para>
+
+      <para>
+        I won't give details about the interrupt handler at this
+        point, but at least its appearance can be explained now. The
+        interrupt handler looks usually like the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
+  {
+          struct mychip *chip = dev_id;
+          ....
+          return IRQ_HANDLED;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Now let's write the corresponding destructor for the resources
+      above. The role of destructor is simple: disable the hardware
+      (if already activated) and release the resources. So far, we
+      have no hardware part, so the disabling code is not written here. 
+      </para>
+
+      <para>
+        To release the resources, the <quote>check-and-release</quote>
+        method is a safer way. For the interrupt, do like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (chip->irq >= 0)
+          free_irq(chip->irq, chip);
+]]>
+          </programlisting>
+        </informalexample>
+
+        Since the irq number can start from 0, you should initialize
+        chip-&gt;irq with a negative value (e.g. -1), so that you can
+        check the validity of the irq number as above.
+      </para>
+
+      <para>
+        When you requested I/O ports or memory regions via
+	<function>pci_request_region()</function> or
+	<function>pci_request_regions()</function> like in this example,
+	release the resource(s) using the corresponding function,
+	<function>pci_release_region()</function> or
+	<function>pci_release_regions()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  pci_release_regions(chip->pci);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+	When you requested manually via <function>request_region()</function>
+	or <function>request_mem_region</function>, you can release it via
+	<function>release_resource()</function>.  Suppose that you keep
+	the resource pointer returned from <function>request_region()</function>
+	in chip-&gt;res_port, the release procedure looks like:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  release_and_free_resource(chip->res_port);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      Don't forget to call <function>pci_disable_device()</function>
+      before the end.
+      </para>
+
+      <para>
+        And finally, release the chip-specific record.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  kfree(chip);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      Again, remember that you cannot
+      use the <parameter>__devexit</parameter> prefix for this destructor. 
+      </para>
+
+      <para>
+      We didn't implement the hardware disabling part in the above.
+      If you need to do this, please note that the destructor may be
+      called even before the initialization of the chip is completed.
+      It would be better to have a flag to skip hardware disabling
+      if the hardware was not initialized yet.
+      </para>
+
+      <para>
+      When the chip-data is assigned to the card using
+      <function>snd_device_new()</function> with
+      <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is 
+      called at the last.  That is, it is assured that all other
+      components like PCMs and controls have already been released.
+      You don't have to stop PCMs, etc. explicitly, but just
+      call low-level hardware stopping.
+      </para>
+
+      <para>
+        The management of a memory-mapped region is almost as same as
+        the management of an I/O port. You'll need three fields like
+        the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct mychip {
+          ....
+          unsigned long iobase_phys;
+          void __iomem *iobase_virt;
+  };
+]]>
+          </programlisting>
+        </informalexample>
+
+        and the allocation would be like below:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if ((err = pci_request_regions(pci, "My Chip")) < 0) {
+          kfree(chip);
+          return err;
+  }
+  chip->iobase_phys = pci_resource_start(pci, 0);
+  chip->iobase_virt = ioremap_nocache(chip->iobase_phys,
+                                      pci_resource_len(pci, 0));
+]]>
+          </programlisting>
+        </informalexample>
+        
+        and the corresponding destructor would be:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_mychip_free(struct mychip *chip)
+  {
+          ....
+          if (chip->iobase_virt)
+                  iounmap(chip->iobase_virt);
+          ....
+          pci_release_regions(chip->pci);
+          ....
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+    </section>
+
+    <section id="pci-resource-device-struct">
+      <title>Registration of Device Struct</title>
+      <para>
+	At some point, typically after calling <function>snd_device_new()</function>,
+	you need to register the struct <structname>device</structname> of the chip
+	you're handling for udev and co.  ALSA provides a macro for compatibility with
+	older kernels.  Simply call like the following:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_card_set_dev(card, &pci->dev);
+]]>
+          </programlisting>
+        </informalexample>
+	so that it stores the PCI's device pointer to the card.  This will be
+	referred by ALSA core functions later when the devices are registered.
+      </para>
+      <para>
+	In the case of non-PCI, pass the proper device struct pointer of the BUS
+	instead.  (In the case of legacy ISA without PnP, you don't have to do
+	anything.)
+      </para>
+    </section>
+
+    <section id="pci-resource-entries">
+      <title>PCI Entries</title>
+      <para>
+        So far, so good. Let's finish the missing PCI
+      stuff. At first, we need a
+      <structname>pci_device_id</structname> table for this
+      chipset. It's a table of PCI vendor/device ID number, and some
+      masks. 
+      </para>
+
+      <para>
+        For example,
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct pci_device_id snd_mychip_ids[] = {
+          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+          ....
+          { 0, }
+  };
+  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first and second fields of
+      the <structname>pci_device_id</structname> structure are the vendor and
+      device IDs. If you have no reason to filter the matching
+      devices, you can leave the remaining fields as above. The last
+      field of the <structname>pci_device_id</structname> struct contains
+      private data for this entry. You can specify any value here, for
+      example, to define specific operations for supported device IDs.
+      Such an example is found in the intel8x0 driver. 
+      </para>
+
+      <para>
+        The last entry of this list is the terminator. You must
+      specify this all-zero entry. 
+      </para>
+
+      <para>
+        Then, prepare the <structname>pci_driver</structname> record:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct pci_driver driver = {
+          .name = "My Own Chip",
+          .id_table = snd_mychip_ids,
+          .probe = snd_mychip_probe,
+          .remove = __devexit_p(snd_mychip_remove),
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The <structfield>probe</structfield> and
+      <structfield>remove</structfield> functions have already
+      been defined in the previous sections.
+      The <structfield>remove</structfield> function should
+      be defined with the 
+      <function>__devexit_p()</function> macro, so that it's not
+      defined for built-in (and non-hot-pluggable) case. The
+      <structfield>name</structfield> 
+      field is the name string of this device. Note that you must not
+      use a slash <quote>/</quote> in this string. 
+      </para>
+
+      <para>
+        And at last, the module entries:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int __init alsa_card_mychip_init(void)
+  {
+          return pci_register_driver(&driver);
+  }
+
+  static void __exit alsa_card_mychip_exit(void)
+  {
+          pci_unregister_driver(&driver);
+  }
+
+  module_init(alsa_card_mychip_init)
+  module_exit(alsa_card_mychip_exit)
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Note that these module entries are tagged with
+      <parameter>__init</parameter> and 
+      <parameter>__exit</parameter> prefixes, not
+      <parameter>__devinit</parameter> nor
+      <parameter>__devexit</parameter>.
+      </para>
+
+      <para>
+        Oh, one thing was forgotten. If you have no exported symbols,
+        you need to declare it in 2.2 or 2.4 kernels (it's not necessary in 2.6 kernels).
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  EXPORT_NO_SYMBOLS;
+]]>
+          </programlisting>
+        </informalexample>
+
+        That's all!
+      </para>
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- PCM Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="pcm-interface">
+    <title>PCM Interface</title>
+
+    <section id="pcm-interface-general">
+      <title>General</title>
+      <para>
+        The PCM middle layer of ALSA is quite powerful and it is only
+      necessary for each driver to implement the low-level functions
+      to access its hardware.
+      </para>
+
+      <para>
+        For accessing to the PCM layer, you need to include
+      <filename>&lt;sound/pcm.h&gt;</filename> first. In addition,
+      <filename>&lt;sound/pcm_params.h&gt;</filename> might be needed
+      if you access to some functions related with hw_param. 
+      </para>
+
+      <para>
+        Each card device can have up to four pcm instances. A pcm
+      instance corresponds to a pcm device file. The limitation of
+      number of instances comes only from the available bit size of
+      the Linux's device numbers. Once when 64bit device number is
+      used, we'll have more pcm instances available. 
+      </para>
+
+      <para>
+        A pcm instance consists of pcm playback and capture streams,
+      and each pcm stream consists of one or more pcm substreams. Some
+      soundcards support multiple playback functions. For example,
+      emu10k1 has a PCM playback of 32 stereo substreams. In this case, at
+      each open, a free substream is (usually) automatically chosen
+      and opened. Meanwhile, when only one substream exists and it was
+      already opened, the successful open will either block
+      or error with <constant>EAGAIN</constant> according to the
+      file open mode. But you don't have to care about such details in your
+      driver. The PCM middle layer will take care of such work.
+      </para>
+    </section>
+
+    <section id="pcm-interface-example">
+      <title>Full Code Example</title>
+      <para>
+      The example code below does not include any hardware access
+      routines but shows only the skeleton, how to build up the PCM
+      interfaces.
+
+        <example>
+          <title>PCM Example Code</title>
+          <programlisting>
+<![CDATA[
+  #include <sound/pcm.h>
+  ....
+
+  /* hardware definition */
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
+          .info = (SNDRV_PCM_INFO_MMAP |
+                   SNDRV_PCM_INFO_INTERLEAVED |
+                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                   SNDRV_PCM_INFO_MMAP_VALID),
+          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
+          .rates =            SNDRV_PCM_RATE_8000_48000,
+          .rate_min =         8000,
+          .rate_max =         48000,
+          .channels_min =     2,
+          .channels_max =     2,
+          .buffer_bytes_max = 32768,
+          .period_bytes_min = 4096,
+          .period_bytes_max = 32768,
+          .periods_min =      1,
+          .periods_max =      1024,
+  };
+
+  /* hardware definition */
+  static struct snd_pcm_hardware snd_mychip_capture_hw = {
+          .info = (SNDRV_PCM_INFO_MMAP |
+                   SNDRV_PCM_INFO_INTERLEAVED |
+                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                   SNDRV_PCM_INFO_MMAP_VALID),
+          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
+          .rates =            SNDRV_PCM_RATE_8000_48000,
+          .rate_min =         8000,
+          .rate_max =         48000,
+          .channels_min =     2,
+          .channels_max =     2,
+          .buffer_bytes_max = 32768,
+          .period_bytes_min = 4096,
+          .period_bytes_max = 32768,
+          .periods_min =      1,
+          .periods_max =      1024,
+  };
+
+  /* open callback */
+  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
+
+          runtime->hw = snd_mychip_playback_hw;
+          /* more hardware-initialization will be done here */
+          ....
+          return 0;
+  }
+
+  /* close callback */
+  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          /* the hardware-specific codes will be here */
+          ....
+          return 0;
+
+  }
+
+  /* open callback */
+  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
+
+          runtime->hw = snd_mychip_capture_hw;
+          /* more hardware-initialization will be done here */
+          ....
+          return 0;
+  }
+
+  /* close callback */
+  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          /* the hardware-specific codes will be here */
+          ....
+          return 0;
+
+  }
+
+  /* hw_params callback */
+  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params)
+  {
+          return snd_pcm_lib_malloc_pages(substream,
+                                     params_buffer_bytes(hw_params));
+  }
+
+  /* hw_free callback */
+  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
+  {
+          return snd_pcm_lib_free_pages(substream);
+  }
+
+  /* prepare callback */
+  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
+
+          /* set up the hardware with the current configuration
+           * for example...
+           */
+          mychip_set_sample_format(chip, runtime->format);
+          mychip_set_sample_rate(chip, runtime->rate);
+          mychip_set_channels(chip, runtime->channels);
+          mychip_set_dma_setup(chip, runtime->dma_addr,
+                               chip->buffer_size,
+                               chip->period_size);
+          return 0;
+  }
+
+  /* trigger callback */
+  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
+                                    int cmd)
+  {
+          switch (cmd) {
+          case SNDRV_PCM_TRIGGER_START:
+                  /* do something to start the PCM engine */
+                  ....
+                  break;
+          case SNDRV_PCM_TRIGGER_STOP:
+                  /* do something to stop the PCM engine */
+                  ....
+                  break;
+          default:
+                  return -EINVAL;
+          }
+  }
+
+  /* pointer callback */
+  static snd_pcm_uframes_t
+  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          unsigned int current_ptr;
+
+          /* get the current hardware pointer */
+          current_ptr = mychip_get_hw_pointer(chip);
+          return current_ptr;
+  }
+
+  /* operators */
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
+          .open =        snd_mychip_playback_open,
+          .close =       snd_mychip_playback_close,
+          .ioctl =       snd_pcm_lib_ioctl,
+          .hw_params =   snd_mychip_pcm_hw_params,
+          .hw_free =     snd_mychip_pcm_hw_free,
+          .prepare =     snd_mychip_pcm_prepare,
+          .trigger =     snd_mychip_pcm_trigger,
+          .pointer =     snd_mychip_pcm_pointer,
+  };
+
+  /* operators */
+  static struct snd_pcm_ops snd_mychip_capture_ops = {
+          .open =        snd_mychip_capture_open,
+          .close =       snd_mychip_capture_close,
+          .ioctl =       snd_pcm_lib_ioctl,
+          .hw_params =   snd_mychip_pcm_hw_params,
+          .hw_free =     snd_mychip_pcm_hw_free,
+          .prepare =     snd_mychip_pcm_prepare,
+          .trigger =     snd_mychip_pcm_trigger,
+          .pointer =     snd_mychip_pcm_pointer,
+  };
+
+  /*
+   *  definitions of capture are omitted here...
+   */
+
+  /* create a pcm device */
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  {
+          struct snd_pcm *pcm;
+          int err;
+
+          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+          if (err < 0) 
+                  return err;
+          pcm->private_data = chip;
+          strcpy(pcm->name, "My Chip");
+          chip->pcm = pcm;
+          /* set operators */
+          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                          &snd_mychip_playback_ops);
+          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                          &snd_mychip_capture_ops);
+          /* pre-allocation of buffers */
+          /* NOTE: this may fail */
+          snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+                                                snd_dma_pci_data(chip->pci),
+                                                64*1024, 64*1024);
+          return 0;
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pcm-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        A pcm instance is allocated by the <function>snd_pcm_new()</function>
+      function. It would be better to create a constructor for pcm,
+      namely, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  {
+          struct snd_pcm *pcm;
+          int err;
+
+          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+          if (err < 0) 
+                  return err;
+          pcm->private_data = chip;
+          strcpy(pcm->name, "My Chip");
+          chip->pcm = pcm;
+	  ....
+          return 0;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The <function>snd_pcm_new()</function> function takes four
+      arguments. The first argument is the card pointer to which this
+      pcm is assigned, and the second is the ID string. 
+      </para>
+
+      <para>
+        The third argument (<parameter>index</parameter>, 0 in the
+      above) is the index of this new pcm. It begins from zero. If
+      you create more than one pcm instances, specify the
+      different numbers in this argument. For example,
+      <parameter>index</parameter> = 1 for the second PCM device.  
+      </para>
+
+      <para>
+        The fourth and fifth arguments are the number of substreams
+      for playback and capture, respectively. Here 1 is used for
+      both arguments. When no playback or capture substreams are available,
+      pass 0 to the corresponding argument.
+      </para>
+
+      <para>
+        If a chip supports multiple playbacks or captures, you can
+      specify more numbers, but they must be handled properly in
+      open/close, etc. callbacks.  When you need to know which
+      substream you are referring to, then it can be obtained from
+      struct <structname>snd_pcm_substream</structname> data passed to each callback
+      as follows: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_pcm_substream *substream;
+  int index = substream->number;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        After the pcm is created, you need to set operators for each
+        pcm stream. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                  &snd_mychip_playback_ops);
+  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                  &snd_mychip_capture_ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The operators are defined typically like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
+          .open =        snd_mychip_pcm_open,
+          .close =       snd_mychip_pcm_close,
+          .ioctl =       snd_pcm_lib_ioctl,
+          .hw_params =   snd_mychip_pcm_hw_params,
+          .hw_free =     snd_mychip_pcm_hw_free,
+          .prepare =     snd_mychip_pcm_prepare,
+          .trigger =     snd_mychip_pcm_trigger,
+          .pointer =     snd_mychip_pcm_pointer,
+  };
+]]>
+          </programlisting>
+        </informalexample>
+
+        All the callbacks are described in the
+        <link linkend="pcm-interface-operators"><citetitle>
+        Operators</citetitle></link> subsection.
+      </para>
+
+      <para>
+        After setting the operators, you probably will want to
+        pre-allocate the buffer. For the pre-allocation, simply call
+        the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+                                        snd_dma_pci_data(chip->pci),
+                                        64*1024, 64*1024);
+]]>
+          </programlisting>
+        </informalexample>
+
+        It will allocate a buffer up to 64kB as default.
+      Buffer management details will be described in the later section <link
+      linkend="buffer-and-memory"><citetitle>Buffer and Memory
+      Management</citetitle></link>. 
+      </para>
+
+      <para>
+        Additionally, you can set some extra information for this pcm
+        in pcm-&gt;info_flags.
+        The available values are defined as
+        <constant>SNDRV_PCM_INFO_XXX</constant> in
+        <filename>&lt;sound/asound.h&gt;</filename>, which is used for
+        the hardware definition (described later). When your soundchip
+        supports only half-duplex, specify like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="pcm-interface-destructor">
+      <title>... And the Destructor?</title>
+      <para>
+        The destructor for a pcm instance is not always
+      necessary. Since the pcm device will be released by the middle
+      layer code automatically, you don't have to call the destructor
+      explicitly.
+      </para>
+
+      <para>
+        The destructor would be necessary if you created
+        special records internally and needed to release them. In such a
+        case, set the destructor function to
+        pcm-&gt;private_free: 
+
+        <example>
+          <title>PCM Instance with a Destructor</title>
+          <programlisting>
+<![CDATA[
+  static void mychip_pcm_free(struct snd_pcm *pcm)
+  {
+          struct mychip *chip = snd_pcm_chip(pcm);
+          /* free your own data */
+          kfree(chip->my_private_pcm_data);
+          /* do what you like else */
+          ....
+  }
+
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  {
+          struct snd_pcm *pcm;
+          ....
+          /* allocate your own data */
+          chip->my_private_pcm_data = kmalloc(...);
+          /* set the destructor */
+          pcm->private_data = chip;
+          pcm->private_free = mychip_pcm_free;
+          ....
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pcm-interface-runtime">
+      <title>Runtime Pointer - The Chest of PCM Information</title>
+	<para>
+	  When the PCM substream is opened, a PCM runtime instance is
+	allocated and assigned to the substream. This pointer is
+	accessible via <constant>substream-&gt;runtime</constant>.
+	This runtime pointer holds most information you need
+	to control the PCM: the copy of hw_params and sw_params configurations, the buffer
+	pointers, mmap records, spinlocks, etc.
+	</para>
+
+	<para>
+	The definition of runtime instance is found in
+	<filename>&lt;sound/pcm.h&gt;</filename>.  Here are
+       the contents of this file:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+struct _snd_pcm_runtime {
+	/* -- Status -- */
+	struct snd_pcm_substream *trigger_master;
+	snd_timestamp_t trigger_tstamp;	/* trigger timestamp */
+	int overrange;
+	snd_pcm_uframes_t avail_max;
+	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
+	snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/
+
+	/* -- HW params -- */
+	snd_pcm_access_t access;	/* access mode */
+	snd_pcm_format_t format;	/* SNDRV_PCM_FORMAT_* */
+	snd_pcm_subformat_t subformat;	/* subformat */
+	unsigned int rate;		/* rate in Hz */
+	unsigned int channels;		/* channels */
+	snd_pcm_uframes_t period_size;	/* period size */
+	unsigned int periods;		/* periods */
+	snd_pcm_uframes_t buffer_size;	/* buffer size */
+	unsigned int tick_time;		/* tick time */
+	snd_pcm_uframes_t min_align;	/* Min alignment for the format */
+	size_t byte_align;
+	unsigned int frame_bits;
+	unsigned int sample_bits;
+	unsigned int info;
+	unsigned int rate_num;
+	unsigned int rate_den;
+
+	/* -- SW params -- */
+	struct timespec tstamp_mode;	/* mmap timestamp is updated */
+  	unsigned int period_step;
+	unsigned int sleep_min;		/* min ticks to sleep */
+	snd_pcm_uframes_t start_threshold;
+	snd_pcm_uframes_t stop_threshold;
+	snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
+						noise is nearest than this */
+	snd_pcm_uframes_t silence_size;	/* Silence filling size */
+	snd_pcm_uframes_t boundary;	/* pointers wrap point */
+
+	snd_pcm_uframes_t silenced_start;
+	snd_pcm_uframes_t silenced_size;
+
+	snd_pcm_sync_id_t sync;		/* hardware synchronization ID */
+
+	/* -- mmap -- */
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
+	atomic_t mmap_count;
+
+	/* -- locking / scheduling -- */
+	spinlock_t lock;
+	wait_queue_head_t sleep;
+	struct timer_list tick_timer;
+	struct fasync_struct *fasync;
+
+	/* -- private section -- */
+	void *private_data;
+	void (*private_free)(struct snd_pcm_runtime *runtime);
+
+	/* -- hardware description -- */
+	struct snd_pcm_hardware hw;
+	struct snd_pcm_hw_constraints hw_constraints;
+
+	/* -- interrupt callbacks -- */
+	void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
+	void (*transfer_ack_end)(struct snd_pcm_substream *substream);
+
+	/* -- timer -- */
+	unsigned int timer_resolution;	/* timer resolution */
+
+	/* -- DMA -- */           
+	unsigned char *dma_area;	/* DMA area */
+	dma_addr_t dma_addr;		/* physical bus address (not accessible from main CPU) */
+	size_t dma_bytes;		/* size of DMA area */
+
+	struct snd_dma_buffer *dma_buffer_p;	/* allocated buffer */
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+	/* -- OSS things -- */
+	struct snd_pcm_oss_runtime oss;
+#endif
+};
+]]>
+            </programlisting>
+          </informalexample>
+	</para>
+
+	<para>
+	  For the operators (callbacks) of each sound driver, most of
+	these records are supposed to be read-only.  Only the PCM
+	middle-layer changes / updates them.  The exceptions are
+	the hardware description (hw), interrupt callbacks
+	(transfer_ack_xxx), DMA buffer information, and the private
+	data.  Besides, if you use the standard buffer allocation
+	method via <function>snd_pcm_lib_malloc_pages()</function>,
+	you don't need to set the DMA buffer information by yourself.
+	</para>
+
+	<para>
+	In the sections below, important records are explained.
+	</para>
+
+	<section id="pcm-interface-runtime-hw">
+	<title>Hardware Description</title>
+	<para>
+	  The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
+	contains the definitions of the fundamental hardware
+	configuration.  Above all, you'll need to define this in
+	<link linkend="pcm-interface-operators-open-callback"><citetitle>
+	the open callback</citetitle></link>.
+	Note that the runtime instance holds the copy of the
+	descriptor, not the pointer to the existing descriptor.  That
+	is, in the open callback, you can modify the copied descriptor
+	(<constant>runtime-&gt;hw</constant>) as you need.  For example, if the maximum
+	number of channels is 1 only on some chip models, you can
+	still use the same hardware descriptor and change the
+	channels_max later:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+          struct snd_pcm_runtime *runtime = substream->runtime;
+          ...
+          runtime->hw = snd_mychip_playback_hw; /* common definition */
+          if (chip->model == VERY_OLD_ONE)
+                  runtime->hw.channels_max = 1;
+]]>
+            </programlisting>
+          </informalexample>
+	</para>
+
+	<para>
+	  Typically, you'll have a hardware descriptor as below:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
+          .info = (SNDRV_PCM_INFO_MMAP |
+                   SNDRV_PCM_INFO_INTERLEAVED |
+                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                   SNDRV_PCM_INFO_MMAP_VALID),
+          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
+          .rates =            SNDRV_PCM_RATE_8000_48000,
+          .rate_min =         8000,
+          .rate_max =         48000,
+          .channels_min =     2,
+          .channels_max =     2,
+          .buffer_bytes_max = 32768,
+          .period_bytes_min = 4096,
+          .period_bytes_max = 32768,
+          .periods_min =      1,
+          .periods_max =      1024,
+  };
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+	<itemizedlist>
+	<listitem><para>
+          The <structfield>info</structfield> field contains the type and
+        capabilities of this pcm. The bit flags are defined in
+        <filename>&lt;sound/asound.h&gt;</filename> as
+        <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you
+        have to specify whether the mmap is supported and which
+        interleaved format is supported.
+        When the is supported, add the
+        <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the
+        hardware supports the interleaved or the non-interleaved
+        formats, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or
+        <constant>SNDRV_PCM_INFO_NONINTERLEAVED</constant> flag must
+        be set, respectively. If both are supported, you can set both,
+        too. 
+        </para>
+
+        <para>
+          In the above example, <constant>MMAP_VALID</constant> and
+        <constant>BLOCK_TRANSFER</constant> are specified for the OSS mmap
+        mode. Usually both are set. Of course,
+        <constant>MMAP_VALID</constant> is set only if the mmap is
+        really supported. 
+        </para>
+
+        <para>
+          The other possible flags are
+        <constant>SNDRV_PCM_INFO_PAUSE</constant> and
+        <constant>SNDRV_PCM_INFO_RESUME</constant>. The
+        <constant>PAUSE</constant> bit means that the pcm supports the
+        <quote>pause</quote> operation, while the
+        <constant>RESUME</constant> bit means that the pcm supports
+        the full <quote>suspend/resume</quote> operation.
+	If the <constant>PAUSE</constant> flag is set,
+	the <structfield>trigger</structfield> callback below
+        must handle the corresponding (pause push/release) commands.
+	The suspend/resume trigger commands can be defined even without
+	the <constant>RESUME</constant> flag.  See <link
+	linkend="power-management"><citetitle>
+	Power Management</citetitle></link> section for details.
+        </para>
+
+	<para>
+	  When the PCM substreams can be synchronized (typically,
+	synchronized start/stop of a playback and a capture streams),
+	you can give <constant>SNDRV_PCM_INFO_SYNC_START</constant>,
+	too.  In this case, you'll need to check the linked-list of
+	PCM substreams in the trigger callback.  This will be
+	described in the later section.
+	</para>
+	</listitem>
+
+	<listitem>
+        <para>
+          <structfield>formats</structfield> field contains the bit-flags
+        of supported formats (<constant>SNDRV_PCM_FMTBIT_XXX</constant>).
+        If the hardware supports more than one format, give all or'ed
+        bits.  In the example above, the signed 16bit little-endian
+        format is specified.
+        </para>
+	</listitem>
+
+	<listitem>
+        <para>
+        <structfield>rates</structfield> field contains the bit-flags of
+        supported rates (<constant>SNDRV_PCM_RATE_XXX</constant>).
+        When the chip supports continuous rates, pass
+        <constant>CONTINUOUS</constant> bit additionally.
+        The pre-defined rate bits are provided only for typical
+	rates. If your chip supports unconventional rates, you need to add
+        the <constant>KNOT</constant> bit and set up the hardware
+        constraint manually (explained later).
+        </para>
+	</listitem>
+
+	<listitem>
+	<para>
+	<structfield>rate_min</structfield> and
+	<structfield>rate_max</structfield> define the minimum and
+	maximum sample rate.  This should correspond somehow to
+	<structfield>rates</structfield> bits.
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	<structfield>channel_min</structfield> and
+	<structfield>channel_max</structfield> 
+	define, as you might already expected, the minimum and maximum
+	number of channels.
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	<structfield>buffer_bytes_max</structfield> defines the
+	maximum buffer size in bytes.  There is no
+	<structfield>buffer_bytes_min</structfield> field, since
+	it can be calculated from the minimum period size and the
+	minimum number of periods.
+	Meanwhile, <structfield>period_bytes_min</structfield> and
+	define the minimum and maximum size of the period in bytes.
+	<structfield>periods_max</structfield> and
+	<structfield>periods_min</structfield> define the maximum and
+	minimum number of periods in the buffer.
+        </para>
+
+	<para>
+	The <quote>period</quote> is a term that corresponds to
+	a fragment in the OSS world. The period defines the size at
+	which a PCM interrupt is generated. This size strongly
+	depends on the hardware. 
+	Generally, the smaller period size will give you more
+	interrupts, that is, more controls. 
+	In the case of capture, this size defines the input latency.
+	On the other hand, the whole buffer size defines the
+	output latency for the playback direction.
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	There is also a field <structfield>fifo_size</structfield>.
+	This specifies the size of the hardware FIFO, but currently it
+	is neither used in the driver nor in the alsa-lib.  So, you
+	can ignore this field.
+	</para>
+	</listitem>
+	</itemizedlist>
+	</para>
+	</section>
+
+	<section id="pcm-interface-runtime-config">
+	<title>PCM Configurations</title>
+	<para>
+	Ok, let's go back again to the PCM runtime records.
+	The most frequently referred records in the runtime instance are
+	the PCM configurations.
+	The PCM configurations are stored in the runtime instance
+	after the application sends <type>hw_params</type> data via
+	alsa-lib.  There are many fields copied from hw_params and
+	sw_params structs.  For example,
+	<structfield>format</structfield> holds the format type
+	chosen by the application.  This field contains the enum value
+	<constant>SNDRV_PCM_FORMAT_XXX</constant>.
+	</para>
+
+	<para>
+	One thing to be noted is that the configured buffer and period
+	sizes are stored in <quote>frames</quote> in the runtime.
+        In the ALSA world, 1 frame = channels * samples-size.
+	For conversion between frames and bytes, you can use the
+	<function>frames_to_bytes()</function> and
+          <function>bytes_to_frames()</function> helper functions. 
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  period_bytes = frames_to_bytes(runtime, runtime->period_size);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+	<para>
+	Also, many software parameters (sw_params) are
+	stored in frames, too.  Please check the type of the field.
+	<type>snd_pcm_uframes_t</type> is for the frames as unsigned
+	integer while <type>snd_pcm_sframes_t</type> is for the frames
+	as signed integer.
+	</para>
+	</section>
+
+	<section id="pcm-interface-runtime-dma">
+	<title>DMA Buffer Information</title>
+	<para>
+	The DMA buffer is defined by the following four fields,
+	<structfield>dma_area</structfield>,
+	<structfield>dma_addr</structfield>,
+	<structfield>dma_bytes</structfield> and
+	<structfield>dma_private</structfield>.
+	The <structfield>dma_area</structfield> holds the buffer
+	pointer (the logical address).  You can call
+	<function>memcpy</function> from/to 
+	this pointer.  Meanwhile, <structfield>dma_addr</structfield>
+	holds the physical address of the buffer.  This field is
+	specified only when the buffer is a linear buffer.
+	<structfield>dma_bytes</structfield> holds the size of buffer
+	in bytes.  <structfield>dma_private</structfield> is used for
+	the ALSA DMA allocator.
+	</para>
+
+	<para>
+	If you use a standard ALSA function,
+	<function>snd_pcm_lib_malloc_pages()</function>, for
+	allocating the buffer, these fields are set by the ALSA middle
+	layer, and you should <emphasis>not</emphasis> change them by
+	yourself.  You can read them but not write them.
+	On the other hand, if you want to allocate the buffer by
+	yourself, you'll need to manage it in hw_params callback.
+	At least, <structfield>dma_bytes</structfield> is mandatory.
+	<structfield>dma_area</structfield> is necessary when the
+	buffer is mmapped.  If your driver doesn't support mmap, this
+	field is not necessary.  <structfield>dma_addr</structfield>
+	is also optional.  You can use
+	<structfield>dma_private</structfield> as you like, too.
+	</para>
+	</section>
+
+	<section id="pcm-interface-runtime-status">
+	<title>Running Status</title>
+	<para>
+	The running status can be referred via <constant>runtime-&gt;status</constant>.
+	This is the pointer to the struct <structname>snd_pcm_mmap_status</structname>
+	record.  For example, you can get the current DMA hardware
+	pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
+	</para>
+
+	<para>
+	The DMA application pointer can be referred via
+	<constant>runtime-&gt;control</constant>, which points to the
+	struct <structname>snd_pcm_mmap_control</structname> record.
+	However, accessing directly to this value is not recommended.
+	</para>
+	</section>
+
+	<section id="pcm-interface-runtime-private">
+	<title>Private Data</title> 
+	<para>
+	You can allocate a record for the substream and store it in
+	<constant>runtime-&gt;private_data</constant>.  Usually, this
+	is done in
+	<link linkend="pcm-interface-operators-open-callback"><citetitle>
+	the open callback</citetitle></link>.
+	Don't mix this with <constant>pcm-&gt;private_data</constant>.
+	The <constant>pcm-&gt;private_data</constant> usually points to the
+	chip instance assigned statically at the creation of PCM, while the 
+	<constant>runtime-&gt;private_data</constant> points to a dynamic
+	data structure created at the PCM open callback.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
+  {
+          struct my_pcm_data *data;
+          ....
+          data = kmalloc(sizeof(*data), GFP_KERNEL);
+          substream->runtime->private_data = data;
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The allocated object must be released in
+	<link linkend="pcm-interface-operators-open-callback"><citetitle>
+	the close callback</citetitle></link>.
+        </para>
+	</section>
+
+	<section id="pcm-interface-runtime-intr">
+	<title>Interrupt Callbacks</title>
+	<para>
+	The field <structfield>transfer_ack_begin</structfield> and
+	<structfield>transfer_ack_end</structfield> are called at
+	the beginning and at the end of
+	<function>snd_pcm_period_elapsed()</function>, respectively. 
+	</para>
+	</section>
+
+    </section>
+
+    <section id="pcm-interface-operators">
+      <title>Operators</title>
+      <para>
+        OK, now let me give details about each pcm callback
+      (<parameter>ops</parameter>). In general, every callback must
+      return 0 if successful, or a negative error number
+      such as <constant>-EINVAL</constant>. To choose an appropriate
+      error number, it is advised to check what value other parts of
+      the kernel return when the same kind of request fails.
+      </para>
+
+      <para>
+        The callback function takes at least the argument with
+        <structname>snd_pcm_substream</structname> pointer. To retrieve
+        the chip record from the given substream instance, you can use the
+        following macro. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  int xxx() {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          ....
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+	The macro reads <constant>substream-&gt;private_data</constant>,
+	which is a copy of <constant>pcm-&gt;private_data</constant>.
+	You can override the former if you need to assign different data
+	records per PCM substream.  For example, the cmi8330 driver assigns
+	different private_data for playback and capture directions,
+	because it uses two different codecs (SB- and AD-compatible) for
+	different directions.
+      </para>
+
+      <section id="pcm-interface-operators-open-callback">
+        <title>open callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_pcm_substream *substream);
+]]>
+            </programlisting>
+          </informalexample>
+
+          This is called when a pcm substream is opened.
+        </para>
+
+        <para>
+          At least, here you have to initialize the runtime-&gt;hw
+          record. Typically, this is done by like this: 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
+  {
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
+
+          runtime->hw = snd_mychip_playback_hw;
+          return 0;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          where <parameter>snd_mychip_playback_hw</parameter> is the
+          pre-defined hardware description.
+	</para>
+
+	<para>
+	You can allocate a private data in this callback, as described
+	in <link linkend="pcm-interface-runtime-private"><citetitle>
+	Private Data</citetitle></link> section.
+	</para>
+
+	<para>
+	If the hardware configuration needs more constraints, set the
+	hardware constraints here, too.
+	See <link linkend="pcm-interface-constraints"><citetitle>
+	Constraints</citetitle></link> for more details.
+	</para>
+      </section>
+
+      <section id="pcm-interface-operators-close-callback">
+        <title>close callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_close(struct snd_pcm_substream *substream);
+]]>
+            </programlisting>
+          </informalexample>
+
+          Obviously, this is called when a pcm substream is closed.
+        </para>
+
+        <para>
+          Any private instance for a pcm substream allocated in the
+          open callback will be released here. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_close(struct snd_pcm_substream *substream)
+  {
+          ....
+          kfree(substream->runtime->private_data);
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-ioctl-callback">
+        <title>ioctl callback</title>
+        <para>
+          This is used for any special call to pcm ioctls. But
+        usually you can pass a generic ioctl callback, 
+        <function>snd_pcm_lib_ioctl</function>.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-hw-params-callback">
+        <title>hw_params callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This is called when the hardware parameter
+        (<structfield>hw_params</structfield>) is set
+        up by the application, 
+        that is, once when the buffer size, the period size, the
+        format, etc. are defined for the pcm substream. 
+        </para>
+
+        <para>
+          Many hardware setups should be done in this callback,
+        including the allocation of buffers. 
+        </para>
+
+        <para>
+          Parameters to be initialized are retrieved by
+          <function>params_xxx()</function> macros. To allocate
+          buffer, you can call a helper function, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+]]>
+            </programlisting>
+          </informalexample>
+
+          <function>snd_pcm_lib_malloc_pages()</function> is available
+	  only when the DMA buffers have been pre-allocated.
+	  See the section <link
+	  linkend="buffer-and-memory-buffer-types"><citetitle>
+	  Buffer Types</citetitle></link> for more details.
+        </para>
+
+        <para>
+          Note that this and <structfield>prepare</structfield> callbacks
+        may be called multiple times per initialization.
+        For example, the OSS emulation may
+        call these callbacks at each change via its ioctl. 
+        </para>
+
+        <para>
+          Thus, you need to be careful not to allocate the same buffers
+        many times, which will lead to memory leaks!  Calling the
+        helper function above many times is OK. It will release the
+        previous buffer automatically when it was already allocated. 
+        </para>
+
+        <para>
+          Another note is that this callback is non-atomic
+        (schedulable). This is important, because the
+        <structfield>trigger</structfield> callback 
+        is atomic (non-schedulable). That is, mutexes or any
+        schedule-related functions are not available in
+        <structfield>trigger</structfield> callback.
+	Please see the subsection
+	<link linkend="pcm-interface-atomicity"><citetitle>
+	Atomicity</citetitle></link> for details.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-hw-free-callback">
+        <title>hw_free callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This is called to release the resources allocated via
+          <structfield>hw_params</structfield>. For example, releasing the
+          buffer via 
+          <function>snd_pcm_lib_malloc_pages()</function> is done by
+          calling the following: 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_pcm_lib_free_pages(substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This function is always called before the close callback is called.
+          Also, the callback may be called multiple times, too.
+          Keep track whether the resource was already released. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-prepare-callback">
+       <title>prepare callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_prepare(struct snd_pcm_substream *substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This callback is called when the pcm is
+        <quote>prepared</quote>. You can set the format type, sample
+        rate, etc. here. The difference from
+        <structfield>hw_params</structfield> is that the 
+        <structfield>prepare</structfield> callback will be called each
+        time 
+        <function>snd_pcm_prepare()</function> is called, i.e. when
+        recovering after underruns, etc. 
+        </para>
+
+        <para>
+	Note that this callback is now non-atomic.
+	You can use schedule-related functions safely in this callback.
+        </para>
+
+        <para>
+          In this and the following callbacks, you can refer to the
+        values via the runtime record,
+        substream-&gt;runtime.
+        For example, to get the current
+        rate, format or channels, access to
+        runtime-&gt;rate,
+        runtime-&gt;format or
+        runtime-&gt;channels, respectively. 
+        The physical address of the allocated buffer is set to
+	runtime-&gt;dma_area.  The buffer and period sizes are
+	in runtime-&gt;buffer_size and runtime-&gt;period_size,
+	respectively.
+        </para>
+
+        <para>
+          Be careful that this callback will be called many times at
+        each setup, too. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-trigger-callback">
+        <title>trigger callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
+]]>
+            </programlisting>
+          </informalexample>
+
+          This is called when the pcm is started, stopped or paused.
+        </para>
+
+        <para>
+          Which action is specified in the second argument,
+          <constant>SNDRV_PCM_TRIGGER_XXX</constant> in
+          <filename>&lt;sound/pcm.h&gt;</filename>. At least,
+          the <constant>START</constant> and <constant>STOP</constant>
+          commands must be defined in this callback. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  switch (cmd) {
+  case SNDRV_PCM_TRIGGER_START:
+          /* do something to start the PCM engine */
+          break;
+  case SNDRV_PCM_TRIGGER_STOP:
+          /* do something to stop the PCM engine */
+          break;
+  default:
+          return -EINVAL;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          When the pcm supports the pause operation (given in the info
+        field of the hardware table), the <constant>PAUSE_PUSE</constant>
+        and <constant>PAUSE_RELEASE</constant> commands must be
+        handled here, too. The former is the command to pause the pcm,
+        and the latter to restart the pcm again. 
+        </para>
+
+        <para>
+          When the pcm supports the suspend/resume operation,
+	regardless of full or partial suspend/resume support,
+        the <constant>SUSPEND</constant> and <constant>RESUME</constant>
+        commands must be handled, too.
+        These commands are issued when the power-management status is
+        changed.  Obviously, the <constant>SUSPEND</constant> and
+        <constant>RESUME</constant> commands
+        suspend and resume the pcm substream, and usually, they
+        are identical to the <constant>STOP</constant> and
+        <constant>START</constant> commands, respectively.
+	  See the <link linkend="power-management"><citetitle>
+	Power Management</citetitle></link> section for details.
+        </para>
+
+        <para>
+          As mentioned, this callback is atomic.  You cannot call
+	  functions which may sleep.
+	  The trigger callback should be as minimal as possible,
+	  just really triggering the DMA.  The other stuff should be
+	  initialized hw_params and prepare callbacks properly
+	  beforehand.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-pointer-callback">
+        <title>pointer callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
+]]>
+            </programlisting>
+          </informalexample>
+
+          This callback is called when the PCM middle layer inquires
+        the current hardware position on the buffer. The position must
+        be returned in frames,
+        ranging from 0 to buffer_size - 1.
+        </para>
+
+        <para>
+          This is called usually from the buffer-update routine in the
+        pcm middle layer, which is invoked when
+        <function>snd_pcm_period_elapsed()</function> is called in the
+        interrupt routine. Then the pcm middle layer updates the
+        position and calculates the available space, and wakes up the
+        sleeping poll threads, etc. 
+        </para>
+
+        <para>
+          This callback is also atomic.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-copy-silence">
+        <title>copy and silence callbacks</title>
+        <para>
+          These callbacks are not mandatory, and can be omitted in
+        most cases. These callbacks are used when the hardware buffer
+        cannot be in the normal memory space. Some chips have their
+        own buffer on the hardware which is not mappable. In such a
+        case, you have to transfer the data manually from the memory
+        buffer to the hardware buffer. Or, if the buffer is
+        non-contiguous on both physical and virtual memory spaces,
+        these callbacks must be defined, too. 
+        </para>
+
+        <para>
+          If these two callbacks are defined, copy and set-silence
+        operations are done by them. The detailed will be described in
+        the later section <link
+        linkend="buffer-and-memory"><citetitle>Buffer and Memory
+        Management</citetitle></link>. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-ack">
+        <title>ack callback</title>
+        <para>
+          This callback is also not mandatory. This callback is called
+        when the appl_ptr is updated in read or write operations.
+        Some drivers like emu10k1-fx and cs46xx need to track the
+	current appl_ptr for the internal buffer, and this callback
+	is useful only for such a purpose.
+	</para>
+	<para>
+	  This callback is atomic.
+	</para>
+      </section>
+
+      <section id="pcm-interface-operators-page-callback">
+        <title>page callback</title>
+
+        <para>
+          This callback is optional too. This callback is used
+        mainly for non-contiguous buffers. The mmap calls this
+        callback to get the page address. Some examples will be
+        explained in the later section <link
+        linkend="buffer-and-memory"><citetitle>Buffer and Memory
+        Management</citetitle></link>, too. 
+        </para>
+      </section>
+    </section>
+
+    <section id="pcm-interface-interrupt-handler">
+      <title>Interrupt Handler</title>
+      <para>
+        The rest of pcm stuff is the PCM interrupt handler. The
+      role of PCM interrupt handler in the sound driver is to update
+      the buffer position and to tell the PCM middle layer when the
+      buffer position goes across the prescribed period size. To
+      inform this, call the <function>snd_pcm_period_elapsed()</function>
+      function. 
+      </para>
+
+      <para>
+        There are several types of sound chips to generate the interrupts.
+      </para>
+
+      <section id="pcm-interface-interrupt-handler-boundary">
+        <title>Interrupts at the period (fragment) boundary</title>
+        <para>
+          This is the most frequently found type:  the hardware
+        generates an interrupt at each period boundary.
+	In this case, you can call
+        <function>snd_pcm_period_elapsed()</function> at each 
+        interrupt. 
+        </para>
+
+        <para>
+          <function>snd_pcm_period_elapsed()</function> takes the
+        substream pointer as its argument. Thus, you need to keep the
+        substream pointer accessible from the chip instance. For
+        example, define substream field in the chip record to hold the
+        current running substream pointer, and set the pointer value
+        at open callback (and reset at close callback). 
+        </para>
+
+        <para>
+          If you acquire a spinlock in the interrupt handler, and the
+        lock is used in other pcm callbacks, too, then you have to
+        release the lock before calling
+        <function>snd_pcm_period_elapsed()</function>, because
+        <function>snd_pcm_period_elapsed()</function> calls other pcm
+        callbacks inside. 
+        </para>
+
+        <para>
+          Typical code would be like:
+
+          <example>
+	    <title>Interrupt Handler Case #1</title>
+            <programlisting>
+<![CDATA[
+  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
+  {
+          struct mychip *chip = dev_id;
+          spin_lock(&chip->lock);
+          ....
+          if (pcm_irq_invoked(chip)) {
+                  /* call updater, unlock before it */
+                  spin_unlock(&chip->lock);
+                  snd_pcm_period_elapsed(chip->substream);
+                  spin_lock(&chip->lock);
+                  /* acknowledge the interrupt if necessary */
+          }
+          ....
+          spin_unlock(&chip->lock);
+          return IRQ_HANDLED;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+      </section>
+
+      <section id="pcm-interface-interrupt-handler-timer">
+        <title>High frequency timer interrupts</title>
+        <para>
+	This happense when the hardware doesn't generate interrupts
+        at the period boundary but issues timer interrupts at a fixed
+        timer rate (e.g. es1968 or ymfpci drivers). 
+        In this case, you need to check the current hardware
+        position and accumulate the processed sample length at each
+        interrupt.  When the accumulated size exceeds the period
+        size, call 
+        <function>snd_pcm_period_elapsed()</function> and reset the
+        accumulator. 
+        </para>
+
+        <para>
+          Typical code would be like the following.
+
+          <example>
+	    <title>Interrupt Handler Case #2</title>
+            <programlisting>
+<![CDATA[
+  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
+  {
+          struct mychip *chip = dev_id;
+          spin_lock(&chip->lock);
+          ....
+          if (pcm_irq_invoked(chip)) {
+                  unsigned int last_ptr, size;
+                  /* get the current hardware pointer (in frames) */
+                  last_ptr = get_hw_ptr(chip);
+                  /* calculate the processed frames since the
+                   * last update
+                   */
+                  if (last_ptr < chip->last_ptr)
+                          size = runtime->buffer_size + last_ptr 
+                                   - chip->last_ptr; 
+                  else
+                          size = last_ptr - chip->last_ptr;
+                  /* remember the last updated point */
+                  chip->last_ptr = last_ptr;
+                  /* accumulate the size */
+                  chip->size += size;
+                  /* over the period boundary? */
+                  if (chip->size >= runtime->period_size) {
+                          /* reset the accumulator */
+                          chip->size %= runtime->period_size;
+                          /* call updater */
+                          spin_unlock(&chip->lock);
+                          snd_pcm_period_elapsed(substream);
+                          spin_lock(&chip->lock);
+                  }
+                  /* acknowledge the interrupt if necessary */
+          }
+          ....
+          spin_unlock(&chip->lock);
+          return IRQ_HANDLED;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+      </section>
+
+      <section id="pcm-interface-interrupt-handler-both">
+        <title>On calling <function>snd_pcm_period_elapsed()</function></title>
+        <para>
+          In both cases, even if more than one period are elapsed, you
+        don't have to call
+        <function>snd_pcm_period_elapsed()</function> many times. Call
+        only once. And the pcm layer will check the current hardware
+        pointer and update to the latest status. 
+        </para>
+      </section>
+    </section>
+
+    <section id="pcm-interface-atomicity">
+      <title>Atomicity</title>
+      <para>
+      One of the most important (and thus difficult to debug) problems
+      in kernel programming are race conditions.
+      In the Linux kernel, they are usually avoided via spin-locks, mutexes
+      or semaphores.  In general, if a race condition can happen
+      in an interrupt handler, it has to be managed atomically, and you
+      have to use a spinlock to protect the critical session. If the
+      critical section is not in interrupt handler code and
+      if taking a relatively long time to execute is acceptable, you
+      should use mutexes or semaphores instead.
+      </para>
+
+      <para>
+      As already seen, some pcm callbacks are atomic and some are
+      not.  For example, the <parameter>hw_params</parameter> callback is
+      non-atomic, while <parameter>trigger</parameter> callback is
+      atomic.  This means, the latter is called already in a spinlock
+      held by the PCM middle layer. Please take this atomicity into
+      account when you choose a locking scheme in the callbacks.
+      </para>
+
+      <para>
+      In the atomic callbacks, you cannot use functions which may call
+      <function>schedule</function> or go to
+      <function>sleep</function>.  Semaphores and mutexes can sleep,
+      and hence they cannot be used inside the atomic callbacks
+      (e.g. <parameter>trigger</parameter> callback).
+      To implement some delay in such a callback, please use
+      <function>udelay()</function> or <function>mdelay()</function>.
+      </para>
+
+      <para>
+      All three atomic callbacks (trigger, pointer, and ack) are
+      called with local interrupts disabled.
+      </para>
+
+    </section>
+    <section id="pcm-interface-constraints">
+      <title>Constraints</title>
+      <para>
+        If your chip supports unconventional sample rates, or only the
+      limited samples, you need to set a constraint for the
+      condition. 
+      </para>
+
+      <para>
+        For example, in order to restrict the sample rates in the some
+        supported values, use
+	<function>snd_pcm_hw_constraint_list()</function>.
+	You need to call this function in the open callback.
+
+        <example>
+	  <title>Example of Hardware Constraints</title>
+          <programlisting>
+<![CDATA[
+  static unsigned int rates[] =
+          {4000, 10000, 22050, 44100};
+  static struct snd_pcm_hw_constraint_list constraints_rates = {
+          .count = ARRAY_SIZE(rates),
+          .list = rates,
+          .mask = 0,
+  };
+
+  static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
+  {
+          int err;
+          ....
+          err = snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                           SNDRV_PCM_HW_PARAM_RATE,
+                                           &constraints_rates);
+          if (err < 0)
+                  return err;
+          ....
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+
+      <para>
+        There are many different constraints.
+        Look at <filename>sound/pcm.h</filename> for a complete list.
+        You can even define your own constraint rules.
+        For example, let's suppose my_chip can manage a substream of 1 channel
+        if and only if the format is S16_LE, otherwise it supports any format
+        specified in the <structname>snd_pcm_hardware</structname> structure (or in any
+        other constraint_list). You can build a rule like this:
+
+        <example>
+	  <title>Example of Hardware Constraints for Channels</title>
+	  <programlisting>
+<![CDATA[
+  static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
+  {
+          struct snd_interval *c = hw_param_interval(params,
+                SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_mask fmt;
+
+          snd_mask_any(&fmt);    /* Init the struct */
+          if (c->min < 2) {
+                  fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE;
+                  return snd_mask_refine(f, &fmt);
+          }
+          return 0;
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+ 
+      <para>
+        Then you need to call this function to add your rule:
+
+       <informalexample>
+	 <programlisting>
+<![CDATA[
+  snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                      hw_rule_channels_by_format, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+                      -1);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The rule function is called when an application sets the number of
+        channels. But an application can set the format before the number of
+        channels. Thus you also need to define the inverse rule:
+
+       <example>
+	 <title>Example of Hardware Constraints for Channels</title>
+	 <programlisting>
+<![CDATA[
+  static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
+  {
+          struct snd_interval *c = hw_param_interval(params,
+                        SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_interval ch;
+
+          snd_interval_any(&ch);
+          if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
+                  ch.min = ch.max = 1;
+                  ch.integer = 1;
+                  return snd_interval_refine(c, &ch);
+          }
+          return 0;
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+
+      <para>
+      ...and in the open callback:
+       <informalexample>
+	 <programlisting>
+<![CDATA[
+  snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+                      hw_rule_format_by_channels, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                      -1);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        I won't give more details here, rather I
+        would like to say, <quote>Luke, use the source.</quote>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Control Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="control-interface">
+    <title>Control Interface</title>
+
+    <section id="control-interface-general">
+      <title>General</title>
+      <para>
+        The control interface is used widely for many switches,
+      sliders, etc. which are accessed from user-space. Its most
+      important use is the mixer interface. In other words, since ALSA
+      0.9.x, all the mixer stuff is implemented on the control kernel API.
+      </para>
+
+      <para>
+        ALSA has a well-defined AC97 control module. If your chip
+      supports only the AC97 and nothing else, you can skip this
+      section. 
+      </para>
+
+      <para>
+        The control API is defined in
+      <filename>&lt;sound/control.h&gt;</filename>.
+      Include this file if you want to add your own controls.
+      </para>
+    </section>
+
+    <section id="control-interface-definition">
+      <title>Definition of Controls</title>
+      <para>
+        To create a new control, you need to define the
+	following three
+      callbacks: <structfield>info</structfield>,
+      <structfield>get</structfield> and
+      <structfield>put</structfield>. Then, define a
+      struct <structname>snd_kcontrol_new</structname> record, such as: 
+
+        <example>
+	  <title>Definition of a Control</title>
+          <programlisting>
+<![CDATA[
+  static struct snd_kcontrol_new my_control __devinitdata = {
+          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+          .name = "PCM Playback Switch",
+          .index = 0,
+          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+          .private_value = 0xffff,
+          .info = my_control_info,
+          .get = my_control_get,
+          .put = my_control_put
+  };
+]]>
+          </programlisting>
+        </example>
+      </para>
+
+      <para>
+        Most likely the control is created via
+      <function>snd_ctl_new1()</function>, and in such a case, you can
+      add the <parameter>__devinitdata</parameter> prefix to the
+      definition as above. 
+      </para>
+
+      <para>
+        The <structfield>iface</structfield> field specifies the control
+      type, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
+      is usually <constant>MIXER</constant>.
+      Use <constant>CARD</constant> for global controls that are not
+      logically part of the mixer.
+      If the control is closely associated with some specific device on
+      the sound card, use <constant>HWDEP</constant>,
+      <constant>PCM</constant>, <constant>RAWMIDI</constant>,
+      <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
+      specify the device number with the
+      <structfield>device</structfield> and
+      <structfield>subdevice</structfield> fields.
+      </para>
+
+      <para>
+        The <structfield>name</structfield> is the name identifier
+      string. Since ALSA 0.9.x, the control name is very important,
+      because its role is classified from its name. There are
+      pre-defined standard control names. The details are described in
+      the <link linkend="control-interface-control-names"><citetitle>
+      Control Names</citetitle></link> subsection.
+      </para>
+
+      <para>
+        The <structfield>index</structfield> field holds the index number
+      of this control. If there are several different controls with
+      the same name, they can be distinguished by the index
+      number. This is the case when 
+      several codecs exist on the card. If the index is zero, you can
+      omit the definition above. 
+      </para>
+
+      <para>
+        The <structfield>access</structfield> field contains the access
+      type of this control. Give the combination of bit masks,
+      <constant>SNDRV_CTL_ELEM_ACCESS_XXX</constant>, there.
+      The details will be explained in
+      the <link linkend="control-interface-access-flags"><citetitle>
+      Access Flags</citetitle></link> subsection.
+      </para>
+
+      <para>
+        The <structfield>private_value</structfield> field contains
+      an arbitrary long integer value for this record. When using
+      the generic <structfield>info</structfield>,
+      <structfield>get</structfield> and
+      <structfield>put</structfield> callbacks, you can pass a value 
+      through this field. If several small numbers are necessary, you can
+      combine them in bitwise. Or, it's possible to give a pointer
+      (casted to unsigned long) of some record to this field, too. 
+      </para>
+
+      <para>
+      The <structfield>tlv</structfield> field can be used to provide
+      metadata about the control; see the
+      <link linkend="control-interface-tlv">
+      <citetitle>Metadata</citetitle></link> subsection.
+      </para>
+
+      <para>
+        The other three are
+	<link linkend="control-interface-callbacks"><citetitle>
+	callback functions</citetitle></link>.
+      </para>
+    </section>
+
+    <section id="control-interface-control-names">
+      <title>Control Names</title>
+      <para>
+        There are some standards to define the control names. A
+      control is usually defined from the three parts as
+      <quote>SOURCE DIRECTION FUNCTION</quote>. 
+      </para>
+
+      <para>
+        The first, <constant>SOURCE</constant>, specifies the source
+      of the control, and is a string such as <quote>Master</quote>,
+      <quote>PCM</quote>, <quote>CD</quote> and
+      <quote>Line</quote>. There are many pre-defined sources. 
+      </para>
+
+      <para>
+        The second, <constant>DIRECTION</constant>, is one of the
+      following strings according to the direction of the control:
+      <quote>Playback</quote>, <quote>Capture</quote>, <quote>Bypass
+      Playback</quote> and <quote>Bypass Capture</quote>. Or, it can
+      be omitted, meaning both playback and capture directions. 
+      </para>
+
+      <para>
+        The third, <constant>FUNCTION</constant>, is one of the
+      following strings according to the function of the control:
+      <quote>Switch</quote>, <quote>Volume</quote> and
+      <quote>Route</quote>. 
+      </para>
+
+      <para>
+        The example of control names are, thus, <quote>Master Capture
+      Switch</quote> or <quote>PCM Playback Volume</quote>. 
+      </para>
+
+      <para>
+        There are some exceptions:
+      </para>
+
+      <section id="control-interface-control-names-global">
+        <title>Global capture and playback</title>
+        <para>
+          <quote>Capture Source</quote>, <quote>Capture Switch</quote>
+        and <quote>Capture Volume</quote> are used for the global
+        capture (input) source, switch and volume. Similarly,
+        <quote>Playback Switch</quote> and <quote>Playback
+        Volume</quote> are used for the global output gain switch and
+        volume. 
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-tone">
+        <title>Tone-controls</title>
+        <para>
+          tone-control switch and volumes are specified like
+        <quote>Tone Control - XXX</quote>, e.g. <quote>Tone Control -
+        Switch</quote>, <quote>Tone Control - Bass</quote>,
+        <quote>Tone Control - Center</quote>.  
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-3d">
+        <title>3D controls</title>
+        <para>
+          3D-control switches and volumes are specified like <quote>3D
+        Control - XXX</quote>, e.g. <quote>3D Control -
+        Switch</quote>, <quote>3D Control - Center</quote>, <quote>3D
+        Control - Space</quote>. 
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-mic">
+        <title>Mic boost</title>
+        <para>
+          Mic-boost switch is set as <quote>Mic Boost</quote> or
+        <quote>Mic Boost (6dB)</quote>. 
+        </para>
+
+        <para>
+          More precise information can be found in
+        <filename>Documentation/sound/alsa/ControlNames.txt</filename>.
+        </para>
+      </section>
+    </section>
+
+    <section id="control-interface-access-flags">
+      <title>Access Flags</title>
+
+      <para>
+      The access flag is the bitmask which specifies the access type
+      of the given control.  The default access type is
+      <constant>SNDRV_CTL_ELEM_ACCESS_READWRITE</constant>, 
+      which means both read and write are allowed to this control.
+      When the access flag is omitted (i.e. = 0), it is
+      considered as <constant>READWRITE</constant> access as default. 
+      </para>
+
+      <para>
+      When the control is read-only, pass
+      <constant>SNDRV_CTL_ELEM_ACCESS_READ</constant> instead.
+      In this case, you don't have to define
+      the <structfield>put</structfield> callback.
+      Similarly, when the control is write-only (although it's a rare
+      case), you can use the <constant>WRITE</constant> flag instead, and
+      you don't need the <structfield>get</structfield> callback.
+      </para>
+
+      <para>
+      If the control value changes frequently (e.g. the VU meter),
+      <constant>VOLATILE</constant> flag should be given.  This means
+      that the control may be changed without
+      <link linkend="control-interface-change-notification"><citetitle>
+      notification</citetitle></link>. Applications should poll such
+      a control constantly.
+      </para>
+
+      <para>
+      When the control is inactive, set
+      the <constant>INACTIVE</constant> flag, too.
+      There are <constant>LOCK</constant> and
+      <constant>OWNER</constant> flags to change the write
+      permissions.
+      </para>
+
+    </section>
+
+    <section id="control-interface-callbacks">
+      <title>Callbacks</title>
+
+      <section id="control-interface-callbacks-info">
+        <title>info callback</title>
+        <para>
+          The <structfield>info</structfield> callback is used to get
+        detailed information on this control. This must store the
+        values of the given struct <structname>snd_ctl_elem_info</structname>
+        object. For example, for a boolean control with a single
+        element: 
+
+          <example>
+	    <title>Example of info callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
+  {
+          uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+          uinfo->count = 1;
+          uinfo->value.integer.min = 0;
+          uinfo->value.integer.max = 1;
+          return 0;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+
+        <para>
+          The <structfield>type</structfield> field specifies the type
+        of the control. There are <constant>BOOLEAN</constant>,
+        <constant>INTEGER</constant>, <constant>ENUMERATED</constant>,
+        <constant>BYTES</constant>, <constant>IEC958</constant> and
+        <constant>INTEGER64</constant>. The
+        <structfield>count</structfield> field specifies the 
+        number of elements in this control. For example, a stereo
+        volume would have count = 2. The
+        <structfield>value</structfield> field is a union, and 
+        the values stored are depending on the type. The boolean and
+        integer types are identical. 
+        </para>
+
+        <para>
+          The enumerated type is a bit different from others.  You'll
+          need to set the string for the currently given item index. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
+  {
+          static char *texts[4] = {
+                  "First", "Second", "Third", "Fourth"
+          };
+          uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+          uinfo->count = 1;
+          uinfo->value.enumerated.items = 4;
+          if (uinfo->value.enumerated.item > 3)
+                  uinfo->value.enumerated.item = 3;
+          strcpy(uinfo->value.enumerated.name,
+                 texts[uinfo->value.enumerated.item]);
+          return 0;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+	  Some common info callbacks are available for your convenience:
+	<function>snd_ctl_boolean_mono_info()</function> and
+	<function>snd_ctl_boolean_stereo_info()</function>.
+	Obviously, the former is an info callback for a mono channel
+	boolean item, just like <function>snd_myctl_mono_info</function>
+	above, and the latter is for a stereo channel boolean item.
+	</para>
+
+      </section>
+
+      <section id="control-interface-callbacks-get">
+        <title>get callback</title>
+
+        <para>
+          This callback is used to read the current value of the
+        control and to return to user-space. 
+        </para>
+
+        <para>
+          For example,
+
+          <example>
+	    <title>Example of get callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+  {
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
+          ucontrol->value.integer.value[0] = get_some_value(chip);
+          return 0;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+
+        <para>
+	The <structfield>value</structfield> field depends on 
+        the type of control as well as on the info callback.  For example,
+	the sb driver uses this field to store the register offset,
+        the bit-shift and the bit-mask.  The
+        <structfield>private_value</structfield> field is set as follows:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  .private_value = reg | (shift << 16) | (mask << 24)
+]]>
+            </programlisting>
+          </informalexample>
+	and is retrieved in callbacks like
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
+  {
+          int reg = kcontrol->private_value & 0xff;
+          int shift = (kcontrol->private_value >> 16) & 0xff;
+          int mask = (kcontrol->private_value >> 24) & 0xff;
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+	</para>
+
+	<para>
+	In the <structfield>get</structfield> callback,
+	you have to fill all the elements if the
+        control has more than one elements,
+        i.e. <structfield>count</structfield> &gt; 1.
+	In the example above, we filled only one element
+        (<structfield>value.integer.value[0]</structfield>) since it's
+        assumed as <structfield>count</structfield> = 1.
+        </para>
+      </section>
+
+      <section id="control-interface-callbacks-put">
+        <title>put callback</title>
+
+        <para>
+          This callback is used to write a value from user-space.
+        </para>
+
+        <para>
+          For example,
+
+          <example>
+	    <title>Example of put callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_put(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+  {
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
+          int changed = 0;
+          if (chip->current_value !=
+               ucontrol->value.integer.value[0]) {
+                  change_current_value(chip,
+                              ucontrol->value.integer.value[0]);
+                  changed = 1;
+          }
+          return changed;
+  }
+]]>
+            </programlisting>
+          </example>
+
+          As seen above, you have to return 1 if the value is
+        changed. If the value is not changed, return 0 instead. 
+	If any fatal error happens, return a negative error code as
+        usual.
+        </para>
+
+        <para>
+	As in the <structfield>get</structfield> callback,
+	when the control has more than one elements,
+	all elements must be evaluated in this callback, too.
+        </para>
+      </section>
+
+      <section id="control-interface-callbacks-all">
+        <title>Callbacks are not atomic</title>
+        <para>
+          All these three callbacks are basically not atomic.
+        </para>
+      </section>
+    </section>
+
+    <section id="control-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        When everything is ready, finally we can create a new
+      control. To create a control, there are two functions to be
+      called, <function>snd_ctl_new1()</function> and
+      <function>snd_ctl_add()</function>. 
+      </para>
+
+      <para>
+        In the simplest way, you can do like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
+  if (err < 0)
+          return err;
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <parameter>my_control</parameter> is the
+      struct <structname>snd_kcontrol_new</structname> object defined above, and chip
+      is the object pointer to be passed to
+      kcontrol-&gt;private_data 
+      which can be referred to in callbacks. 
+      </para>
+
+      <para>
+        <function>snd_ctl_new1()</function> allocates a new
+      <structname>snd_kcontrol</structname> instance (that's why the definition
+      of <parameter>my_control</parameter> can be with
+      the <parameter>__devinitdata</parameter> 
+      prefix), and <function>snd_ctl_add</function> assigns the given
+      control component to the card. 
+      </para>
+    </section>
+
+    <section id="control-interface-change-notification">
+      <title>Change Notification</title>
+      <para>
+        If you need to change and update a control in the interrupt
+      routine, you can call <function>snd_ctl_notify()</function>. For
+      example, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
+]]>
+          </programlisting>
+        </informalexample>
+
+        This function takes the card pointer, the event-mask, and the
+      control id pointer for the notification. The event-mask
+      specifies the types of notification, for example, in the above
+      example, the change of control values is notified.
+      The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
+      to be notified.
+      You can find some examples in <filename>es1938.c</filename> or
+      <filename>es1968.c</filename> for hardware volume interrupts. 
+      </para>
+    </section>
+
+    <section id="control-interface-tlv">
+      <title>Metadata</title>
+      <para>
+      To provide information about the dB values of a mixer control, use
+      on of the <constant>DECLARE_TLV_xxx</constant> macros from
+      <filename>&lt;sound/tlv.h&gt;</filename> to define a variable
+      containing this information, set the<structfield>tlv.p
+      </structfield> field to point to this variable, and include the
+      <constant>SNDRV_CTL_ELEM_ACCESS_TLV_READ</constant> flag in the
+      <structfield>access</structfield> field; like this:
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
+
+  static struct snd_kcontrol_new my_control __devinitdata = {
+          ...
+          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                    SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+          ...
+          .tlv.p = db_scale_my_control,
+  };
+]]>
+        </programlisting>
+      </informalexample>
+      </para>
+
+      <para>
+      The <function>DECLARE_TLV_DB_SCALE</function> macro defines
+      information about a mixer control where each step in the control's
+      value changes the dB value by a constant dB amount.
+      The first parameter is the name of the variable to be defined.
+      The second parameter is the minimum value, in units of 0.01 dB.
+      The third parameter is the step size, in units of 0.01 dB.
+      Set the fourth parameter to 1 if the minimum value actually mutes
+      the control.
+      </para>
+
+      <para>
+      The <function>DECLARE_TLV_DB_LINEAR</function> macro defines
+      information about a mixer control where the control's value affects
+      the output linearly.
+      The first parameter is the name of the variable to be defined.
+      The second parameter is the minimum value, in units of 0.01 dB.
+      The third parameter is the maximum value, in units of 0.01 dB.
+      If the minimum value mutes the control, set the second parameter to
+      <constant>TLV_DB_GAIN_MUTE</constant>.
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- API for AC97 Codec  -->
+<!-- ****************************************************** -->
+  <chapter id="api-ac97">
+    <title>API for AC97 Codec</title>
+
+    <section>
+      <title>General</title>
+      <para>
+        The ALSA AC97 codec layer is a well-defined one, and you don't
+      have to write much code to control it. Only low-level control
+      routines are necessary. The AC97 codec API is defined in
+      <filename>&lt;sound/ac97_codec.h&gt;</filename>. 
+      </para>
+    </section>
+
+    <section id="api-ac97-example">
+      <title>Full Code Example</title>
+      <para>
+          <example>
+	    <title>Example of AC97 Interface</title>
+            <programlisting>
+<![CDATA[
+  struct mychip {
+          ....
+          struct snd_ac97 *ac97;
+          ....
+  };
+
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
+                                             unsigned short reg)
+  {
+          struct mychip *chip = ac97->private_data;
+          ....
+          /* read a register value here from the codec */
+          return the_register_value;
+  }
+
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
+                                   unsigned short reg, unsigned short val)
+  {
+          struct mychip *chip = ac97->private_data;
+          ....
+          /* write the given register value to the codec */
+  }
+
+  static int snd_mychip_ac97(struct mychip *chip)
+  {
+          struct snd_ac97_bus *bus;
+          struct snd_ac97_template ac97;
+          int err;
+          static struct snd_ac97_bus_ops ops = {
+                  .write = snd_mychip_ac97_write,
+                  .read = snd_mychip_ac97_read,
+          };
+
+          err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
+          if (err < 0)
+                  return err;
+          memset(&ac97, 0, sizeof(ac97));
+          ac97.private_data = chip;
+          return snd_ac97_mixer(bus, &ac97, &chip->ac97);
+  }
+
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="api-ac97-constructor">
+      <title>Constructor</title>
+      <para>
+        To create an ac97 instance, first call <function>snd_ac97_bus</function>
+      with an <type>ac97_bus_ops_t</type> record with callback functions.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_ac97_bus *bus;
+  static struct snd_ac97_bus_ops ops = {
+        .write = snd_mychip_ac97_write,
+        .read = snd_mychip_ac97_read,
+  };
+
+  snd_ac97_bus(card, 0, &ops, NULL, &pbus);
+]]>
+          </programlisting>
+        </informalexample>
+
+      The bus record is shared among all belonging ac97 instances.
+      </para>
+
+      <para>
+      And then call <function>snd_ac97_mixer()</function> with an
+      struct <structname>snd_ac97_template</structname>
+      record together with the bus pointer created above.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_ac97_template ac97;
+  int err;
+
+  memset(&ac97, 0, sizeof(ac97));
+  ac97.private_data = chip;
+  snd_ac97_mixer(bus, &ac97, &chip->ac97);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where chip-&gt;ac97 is a pointer to a newly created
+        <type>ac97_t</type> instance.
+        In this case, the chip pointer is set as the private data, so that
+        the read/write callback functions can refer to this chip instance.
+        This instance is not necessarily stored in the chip
+	record.  If you need to change the register values from the
+        driver, or need the suspend/resume of ac97 codecs, keep this
+        pointer to pass to the corresponding functions.
+      </para>
+    </section>
+
+    <section id="api-ac97-callbacks">
+      <title>Callbacks</title>
+      <para>
+        The standard callbacks are <structfield>read</structfield> and
+      <structfield>write</structfield>. Obviously they 
+      correspond to the functions for read and write accesses to the
+      hardware low-level codes. 
+      </para>
+
+      <para>
+        The <structfield>read</structfield> callback returns the
+        register value specified in the argument. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
+                                             unsigned short reg)
+  {
+          struct mychip *chip = ac97->private_data;
+          ....
+          return the_register_value;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+        Here, the chip can be cast from ac97-&gt;private_data.
+      </para>
+
+      <para>
+        Meanwhile, the <structfield>write</structfield> callback is
+        used to set the register value. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
+                       unsigned short reg, unsigned short val)
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      These callbacks are non-atomic like the control API callbacks.
+      </para>
+
+      <para>
+        There are also other callbacks:
+      <structfield>reset</structfield>,
+      <structfield>wait</structfield> and
+      <structfield>init</structfield>. 
+      </para>
+
+      <para>
+        The <structfield>reset</structfield> callback is used to reset
+      the codec. If the chip requires a special kind of reset, you can
+      define this callback. 
+      </para>
+
+      <para>
+        The <structfield>wait</structfield> callback is used to
+      add some waiting time in the standard initialization of the codec. If the
+      chip requires the extra waiting time, define this callback. 
+      </para>
+
+      <para>
+        The <structfield>init</structfield> callback is used for
+      additional initialization of the codec.
+      </para>
+    </section>
+
+    <section id="api-ac97-updating-registers">
+      <title>Updating Registers in The Driver</title>
+      <para>
+        If you need to access to the codec from the driver, you can
+      call the following functions:
+      <function>snd_ac97_write()</function>,
+      <function>snd_ac97_read()</function>,
+      <function>snd_ac97_update()</function> and
+      <function>snd_ac97_update_bits()</function>. 
+      </para>
+
+      <para>
+        Both <function>snd_ac97_write()</function> and
+        <function>snd_ac97_update()</function> functions are used to
+        set a value to the given register
+        (<constant>AC97_XXX</constant>). The difference between them is
+        that <function>snd_ac97_update()</function> doesn't write a
+        value if the given value has been already set, while
+        <function>snd_ac97_write()</function> always rewrites the
+        value. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_write(ac97, AC97_MASTER, 0x8080);
+  snd_ac97_update(ac97, AC97_MASTER, 0x8080);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        <function>snd_ac97_read()</function> is used to read the value
+        of the given register. For example, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  value = snd_ac97_read(ac97, AC97_MASTER);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        <function>snd_ac97_update_bits()</function> is used to update
+        some bits in the given register.  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_update_bits(ac97, reg, mask, value);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Also, there is a function to change the sample rate (of a
+        given register such as
+        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or
+        DRA is supported by the codec:
+        <function>snd_ac97_set_rate()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The following registers are available to set the rate:
+      <constant>AC97_PCM_MIC_ADC_RATE</constant>,
+      <constant>AC97_PCM_FRONT_DAC_RATE</constant>,
+      <constant>AC97_PCM_LR_ADC_RATE</constant>,
+      <constant>AC97_SPDIF</constant>. When
+      <constant>AC97_SPDIF</constant> is specified, the register is
+      not really changed but the corresponding IEC958 status bits will
+      be updated. 
+      </para>
+    </section>
+
+    <section id="api-ac97-clock-adjustment">
+      <title>Clock Adjustment</title>
+      <para>
+        In some chips, the clock of the codec isn't 48000 but using a
+      PCI clock (to save a quartz!). In this case, change the field
+      bus-&gt;clock to the corresponding
+      value. For example, intel8x0 
+      and es1968 drivers have their own function to read from the clock.
+      </para>
+    </section>
+
+    <section id="api-ac97-proc-files">
+      <title>Proc Files</title>
+      <para>
+        The ALSA AC97 interface will create a proc file such as
+      <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
+      <filename>ac97#0-0+regs</filename>. You can refer to these files to
+      see the current status and registers of the codec. 
+      </para>
+    </section>
+
+    <section id="api-ac97-multiple-codecs">
+      <title>Multiple Codecs</title>
+      <para>
+        When there are several codecs on the same card, you need to
+      call <function>snd_ac97_mixer()</function> multiple times with
+      ac97.num=1 or greater. The <structfield>num</structfield> field
+      specifies the codec number. 
+      </para>
+
+      <para>
+        If you set up multiple codecs, you either need to write
+      different callbacks for each codec or check
+      ac97-&gt;num in the callback routines. 
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- MIDI (MPU401-UART) Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="midi-interface">
+    <title>MIDI (MPU401-UART) Interface</title>
+
+    <section id="midi-interface-general">
+      <title>General</title>
+      <para>
+        Many soundcards have built-in MIDI (MPU401-UART)
+      interfaces. When the soundcard supports the standard MPU401-UART
+      interface, most likely you can use the ALSA MPU401-UART API. The
+      MPU401-UART API is defined in
+      <filename>&lt;sound/mpu401.h&gt;</filename>. 
+      </para>
+
+      <para>
+        Some soundchips have a similar but slightly different
+      implementation of mpu401 stuff. For example, emu10k1 has its own
+      mpu401 routines. 
+      </para>
+    </section>
+
+    <section id="midi-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        To create a rawmidi object, call
+      <function>snd_mpu401_uart_new()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi *rmidi;
+  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
+                      irq, irq_flags, &rmidi);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the card pointer, and the second is the
+      index of this component. You can create up to 8 rawmidi
+      devices. 
+      </para>
+
+      <para>
+        The third argument is the type of the hardware,
+      <constant>MPU401_HW_XXX</constant>. If it's not a special one,
+      you can use <constant>MPU401_HW_MPU401</constant>. 
+      </para>
+
+      <para>
+        The 4th argument is the I/O port address. Many
+      backward-compatible MPU401 have an I/O port such as 0x330. Or, it
+      might be a part of its own PCI I/O region. It depends on the
+      chip design. 
+      </para>
+
+      <para>
+	The 5th argument is a bitflag for additional information.
+        When the I/O port address above is part of the PCI I/O
+      region, the MPU401 I/O port might have been already allocated
+      (reserved) by the driver itself. In such a case, pass a bit flag
+      <constant>MPU401_INFO_INTEGRATED</constant>,
+      and the mpu401-uart layer will allocate the I/O ports by itself. 
+      </para>
+
+	<para>
+	When the controller supports only the input or output MIDI stream,
+	pass the <constant>MPU401_INFO_INPUT</constant> or
+	<constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
+	Then the rawmidi instance is created as a single stream.
+	</para>
+
+	<para>
+	<constant>MPU401_INFO_MMIO</constant> bitflag is used to change
+	the access method to MMIO (via readb and writeb) instead of
+	iob and outb. In this case, you have to pass the iomapped address
+	to <function>snd_mpu401_uart_new()</function>.
+	</para>
+
+	<para>
+	When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
+	stream isn't checked in the default interrupt handler.  The driver
+	needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
+	by itself to start processing the output stream in the irq handler.
+	</para>
+
+      <para>
+        Usually, the port address corresponds to the command port and
+        port + 1 corresponds to the data port. If not, you may change
+        the <structfield>cport</structfield> field of
+        struct <structname>snd_mpu401</structname> manually 
+        afterward. However, <structname>snd_mpu401</structname> pointer is not
+        returned explicitly by
+        <function>snd_mpu401_uart_new()</function>. You need to cast
+        rmidi-&gt;private_data to
+        <structname>snd_mpu401</structname> explicitly, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_mpu401 *mpu;
+  mpu = rmidi->private_data;
+]]>
+          </programlisting>
+        </informalexample>
+
+        and reset the cport as you like:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  mpu->cport = my_own_control_port;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The 6th argument specifies the irq number for UART. If the irq
+      is already allocated, pass 0 to the 7th argument
+      (<parameter>irq_flags</parameter>). Otherwise, pass the flags
+      for irq allocation 
+      (<constant>SA_XXX</constant> bits) to it, and the irq will be
+      reserved by the mpu401-uart layer. If the card doesn't generate
+      UART interrupts, pass -1 as the irq number. Then a timer
+      interrupt will be invoked for polling. 
+      </para>
+    </section>
+
+    <section id="midi-interface-interrupt-handler">
+      <title>Interrupt Handler</title>
+      <para>
+        When the interrupt is allocated in
+      <function>snd_mpu401_uart_new()</function>, the private
+      interrupt handler is used, hence you don't have anything else to do
+      than creating the mpu401 stuff. Otherwise, you have to call
+      <function>snd_mpu401_uart_interrupt()</function> explicitly when
+      a UART interrupt is invoked and checked in your own interrupt
+      handler.  
+      </para>
+
+      <para>
+        In this case, you need to pass the private_data of the
+        returned rawmidi object from
+        <function>snd_mpu401_uart_new()</function> as the second
+        argument of <function>snd_mpu401_uart_interrupt()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- RawMIDI Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="rawmidi-interface">
+    <title>RawMIDI Interface</title>
+
+    <section id="rawmidi-interface-overview">
+      <title>Overview</title>
+
+      <para>
+      The raw MIDI interface is used for hardware MIDI ports that can
+      be accessed as a byte stream.  It is not used for synthesizer
+      chips that do not directly understand MIDI.
+      </para>
+
+      <para>
+      ALSA handles file and buffer management.  All you have to do is
+      to write some code to move data between the buffer and the
+      hardware.
+      </para>
+
+      <para>
+      The rawmidi API is defined in
+      <filename>&lt;sound/rawmidi.h&gt;</filename>.
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-constructor">
+      <title>Constructor</title>
+
+      <para>
+      To create a rawmidi device, call the
+      <function>snd_rawmidi_new</function> function:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi *rmidi;
+  err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
+  if (err < 0)
+          return err;
+  rmidi->private_data = chip;
+  strcpy(rmidi->name, "My MIDI");
+  rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+                      SNDRV_RAWMIDI_INFO_INPUT |
+                      SNDRV_RAWMIDI_INFO_DUPLEX;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The first argument is the card pointer, the second argument is
+      the ID string.
+      </para>
+
+      <para>
+      The third argument is the index of this component.  You can
+      create up to 8 rawmidi devices.
+      </para>
+
+      <para>
+      The fourth and fifth arguments are the number of output and
+      input substreams, respectively, of this device (a substream is
+      the equivalent of a MIDI port).
+      </para>
+
+      <para>
+      Set the <structfield>info_flags</structfield> field to specify
+      the capabilities of the device.
+      Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is
+      at least one output port,
+      <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at
+      least one input port,
+      and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device
+      can handle output and input at the same time.
+      </para>
+
+      <para>
+      After the rawmidi device is created, you need to set the
+      operators (callbacks) for each substream.  There are helper
+      functions to set the operators for all the substreams of a device:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The operators are usually defined like this:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
+          .open =    snd_mymidi_output_open,
+          .close =   snd_mymidi_output_close,
+          .trigger = snd_mymidi_output_trigger,
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      These callbacks are explained in the <link
+      linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link>
+      section.
+      </para>
+
+      <para>
+      If there are more than one substream, you should give a
+      unique name to each of them:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi_substream *substream;
+  list_for_each_entry(substream,
+                      &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
+                      list {
+          sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
+  }
+  /* same for SNDRV_RAWMIDI_STREAM_INPUT */
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-callbacks">
+      <title>Callbacks</title>
+
+      <para>
+      In all the callbacks, the private data that you've set for the
+      rawmidi device can be accessed as
+      substream-&gt;rmidi-&gt;private_data.
+      <!-- <code> isn't available before DocBook 4.3 -->
+      </para>
+
+      <para>
+      If there is more than one port, your callbacks can determine the
+      port index from the struct snd_rawmidi_substream data passed to each
+      callback:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi_substream *substream;
+  int index = substream->number;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <section id="rawmidi-interface-op-open">
+      <title><function>open</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called when a substream is opened.
+        You can initialize the hardware here, but you shouldn't
+        start transmitting/receiving data yet.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-close">
+      <title><function>close</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_close(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        Guess what.
+        </para>
+
+        <para>
+        The <function>open</function> and <function>close</function>
+        callbacks of a rawmidi device are serialized with a mutex,
+        and can sleep.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-out">
+      <title><function>trigger</function> callback for output
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter when there is some data in the substream buffer that
+        must be transmitted.
+        </para>
+
+        <para>
+        To read data from the buffer, call
+        <function>snd_rawmidi_transmit_peek</function>.  It will
+        return the number of bytes that have been read; this will be
+        less than the number of bytes requested when there are no more
+        data in the buffer.
+        After the data have been transmitted successfully, call
+        <function>snd_rawmidi_transmit_ack</function> to remove the
+        data from the substream buffer:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  unsigned char data;
+  while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
+          if (snd_mychip_try_to_transmit(data))
+                  snd_rawmidi_transmit_ack(substream, 1);
+          else
+                  break; /* hardware FIFO full */
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand that the hardware will accept data, you
+        can use the <function>snd_rawmidi_transmit</function> function
+        which reads some data and removes them from the buffer at once:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  while (snd_mychip_transmit_possible()) {
+          unsigned char data;
+          if (snd_rawmidi_transmit(substream, &data, 1) != 1)
+                  break; /* no more data */
+          snd_mychip_transmit(data);
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand how many bytes you can accept, you can
+        use a buffer size greater than one with the
+        <function>snd_rawmidi_transmit*</function> functions.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep.  If
+        the hardware FIFO is full before the substream buffer has been
+        emptied, you have to continue transmitting data later, either
+        in an interrupt handler, or with a timer if the hardware
+        doesn't have a MIDI transmit interrupt.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback is called with a
+        zero <parameter>up</parameter> parameter when the transmission
+        of data should be aborted.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-in">
+      <title><function>trigger</function> callback for input
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter to enable receiving data, or with a zero
+        <parameter>up</parameter> parameter do disable receiving data.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep; the
+        actual reading of data from the device is usually done in an
+        interrupt handler.
+        </para>
+
+        <para>
+        When data reception is enabled, your interrupt handler should
+        call <function>snd_rawmidi_receive</function> for all received
+        data:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  void snd_mychip_midi_interrupt(...)
+  {
+          while (mychip_midi_available()) {
+                  unsigned char data;
+                  data = mychip_midi_read();
+                  snd_rawmidi_receive(substream, &data, 1);
+          }
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-drain">
+      <title><function>drain</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is only used with output substreams.  This function should wait
+        until all data read from the substream buffer have been transmitted.
+        This ensures that the device can be closed and the driver unloaded
+        without losing data.
+        </para>
+
+        <para>
+        This callback is optional. If you do not set
+        <structfield>drain</structfield> in the struct snd_rawmidi_ops
+        structure, ALSA will simply wait for 50&nbsp;milliseconds
+        instead.
+        </para>
+      </section>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Miscellaneous Devices  -->
+<!-- ****************************************************** -->
+  <chapter id="misc-devices">
+    <title>Miscellaneous Devices</title>
+
+    <section id="misc-devices-opl3">
+      <title>FM OPL3</title>
+      <para>
+        The FM OPL3 is still used in many chips (mainly for backward
+      compatibility). ALSA has a nice OPL3 FM control layer, too. The
+      OPL3 API is defined in
+      <filename>&lt;sound/opl3.h&gt;</filename>. 
+      </para>
+
+      <para>
+        FM registers can be directly accessed through the direct-FM API,
+      defined in <filename>&lt;sound/asound_fm.h&gt;</filename>. In
+      ALSA native mode, FM registers are accessed through
+      the Hardware-Dependant Device direct-FM extension API, whereas in
+      OSS compatible mode, FM registers can be accessed with the OSS
+      direct-FM compatible API in <filename>/dev/dmfmX</filename> device. 
+      </para>
+
+      <para>
+        To create the OPL3 component, you have two functions to
+        call. The first one is a constructor for the <type>opl3_t</type>
+        instance. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_opl3 *opl3;
+  snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
+                  integrated, &opl3);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the card pointer, the second one is the
+      left port address, and the third is the right port address. In
+      most cases, the right port is placed at the left port + 2. 
+      </para>
+
+      <para>
+        The fourth argument is the hardware type.
+      </para>
+
+      <para>
+        When the left and right ports have been already allocated by
+      the card driver, pass non-zero to the fifth argument
+      (<parameter>integrated</parameter>). Otherwise, the opl3 module will
+      allocate the specified ports by itself. 
+      </para>
+
+      <para>
+        When the accessing the hardware requires special method
+        instead of the standard I/O access, you can create opl3 instance
+        separately with <function>snd_opl3_new()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_opl3 *opl3;
+  snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+	Then set <structfield>command</structfield>,
+	<structfield>private_data</structfield> and
+	<structfield>private_free</structfield> for the private
+	access function, the private data and the destructor.
+	The l_port and r_port are not necessarily set.  Only the
+	command must be set properly.  You can retrieve the data
+	from the opl3-&gt;private_data field.
+      </para>
+
+      <para>
+	After creating the opl3 instance via <function>snd_opl3_new()</function>,
+	call <function>snd_opl3_init()</function> to initialize the chip to the
+	proper state. Note that <function>snd_opl3_create()</function> always
+	calls it internally.
+      </para>
+
+      <para>
+        If the opl3 instance is created successfully, then create a
+        hwdep device for this opl3. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_hwdep *opl3hwdep;
+  snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the <type>opl3_t</type> instance you
+      created, and the second is the index number, usually 0. 
+      </para>
+
+      <para>
+        The third argument is the index-offset for the sequencer
+      client assigned to the OPL3 port. When there is an MPU401-UART,
+      give 1 for here (UART always takes 0). 
+      </para>
+    </section>
+
+    <section id="misc-devices-hardware-dependent">
+      <title>Hardware-Dependent Devices</title>
+      <para>
+        Some chips need user-space access for special
+      controls or for loading the micro code. In such a case, you can
+      create a hwdep (hardware-dependent) device. The hwdep API is
+      defined in <filename>&lt;sound/hwdep.h&gt;</filename>. You can
+      find examples in opl3 driver or
+      <filename>isa/sb/sb16_csp.c</filename>. 
+      </para>
+
+      <para>
+        The creation of the <type>hwdep</type> instance is done via
+        <function>snd_hwdep_new()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_hwdep *hw;
+  snd_hwdep_new(card, "My HWDEP", 0, &hw);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where the third argument is the index number.
+      </para>
+
+      <para>
+        You can then pass any pointer value to the
+        <parameter>private_data</parameter>.
+        If you assign a private data, you should define the
+        destructor, too. The destructor function is set in
+        the <structfield>private_free</structfield> field.  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
+  hw->private_data = p;
+  hw->private_free = mydata_free;
+]]>
+          </programlisting>
+        </informalexample>
+
+        and the implementation of the destructor would be:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void mydata_free(struct snd_hwdep *hw)
+  {
+          struct mydata *p = hw->private_data;
+          kfree(p);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The arbitrary file operations can be defined for this
+        instance. The file operators are defined in
+        the <parameter>ops</parameter> table. For example, assume that
+        this chip needs an ioctl. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  hw->ops.open = mydata_open;
+  hw->ops.ioctl = mydata_ioctl;
+  hw->ops.release = mydata_release;
+]]>
+          </programlisting>
+        </informalexample>
+
+        And implement the callback functions as you like.
+      </para>
+    </section>
+
+    <section id="misc-devices-IEC958">
+      <title>IEC958 (S/PDIF)</title>
+      <para>
+        Usually the controls for IEC958 devices are implemented via
+      the control interface. There is a macro to compose a name string for
+      IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function>
+      defined in <filename>&lt;include/asound.h&gt;</filename>.  
+      </para>
+
+      <para>
+        There are some standard controls for IEC958 status bits. These
+      controls use the type <type>SNDRV_CTL_ELEM_TYPE_IEC958</type>,
+      and the size of element is fixed as 4 bytes array
+      (value.iec958.status[x]). For the <structfield>info</structfield>
+      callback, you don't specify 
+      the value field for this type (the count field must be set,
+      though). 
+      </para>
+
+      <para>
+        <quote>IEC958 Playback Con Mask</quote> is used to return the
+      bit-mask for the IEC958 status bits of consumer mode. Similarly,
+      <quote>IEC958 Playback Pro Mask</quote> returns the bitmask for
+      professional mode. They are read-only controls, and are defined
+      as MIXER controls (iface =
+      <constant>SNDRV_CTL_ELEM_IFACE_MIXER</constant>).  
+      </para>
+
+      <para>
+        Meanwhile, <quote>IEC958 Playback Default</quote> control is
+      defined for getting and setting the current default IEC958
+      bits. Note that this one is usually defined as a PCM control
+      (iface = <constant>SNDRV_CTL_ELEM_IFACE_PCM</constant>),
+      although in some places it's defined as a MIXER control. 
+      </para>
+
+      <para>
+        In addition, you can define the control switches to
+      enable/disable or to set the raw bit mode. The implementation
+      will depend on the chip, but the control should be named as
+      <quote>IEC958 xxx</quote>, preferably using
+      the <function>SNDRV_CTL_NAME_IEC958()</function> macro. 
+      </para>
+
+      <para>
+        You can find several cases, for example,
+      <filename>pci/emu10k1</filename>,
+      <filename>pci/ice1712</filename>, or
+      <filename>pci/cmipci.c</filename>.  
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Buffer and Memory Management  -->
+<!-- ****************************************************** -->
+  <chapter id="buffer-and-memory">
+    <title>Buffer and Memory Management</title>
+
+    <section id="buffer-and-memory-buffer-types">
+      <title>Buffer Types</title>
+      <para>
+        ALSA provides several different buffer allocation functions
+      depending on the bus and the architecture. All these have a
+      consistent API. The allocation of physically-contiguous pages is
+      done via 
+      <function>snd_malloc_xxx_pages()</function> function, where xxx
+      is the bus type. 
+      </para>
+
+      <para>
+        The allocation of pages with fallback is
+      <function>snd_malloc_xxx_pages_fallback()</function>. This
+      function tries to allocate the specified pages but if the pages
+      are not available, it tries to reduce the page sizes until
+      enough space is found.
+      </para>
+
+      <para>
+      The release the pages, call
+      <function>snd_free_xxx_pages()</function> function. 
+      </para>
+
+      <para>
+      Usually, ALSA drivers try to allocate and reserve
+       a large contiguous physical space
+       at the time the module is loaded for the later use.
+       This is called <quote>pre-allocation</quote>.
+       As already written, you can call the following function at 
+       pcm instance construction time (in the case of PCI bus). 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+                                        snd_dma_pci_data(pci), size, max);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <parameter>size</parameter> is the byte size to be
+      pre-allocated and the <parameter>max</parameter> is the maximum
+      size to be changed via the <filename>prealloc</filename> proc file.
+      The allocator will try to get an area as large as possible
+      within the given size. 
+      </para>
+
+      <para>
+      The second argument (type) and the third argument (device pointer)
+      are dependent on the bus.
+      In the case of the ISA bus, pass <function>snd_dma_isa_data()</function>
+      as the third argument with <constant>SNDRV_DMA_TYPE_DEV</constant> type.
+      For the continuous buffer unrelated to the bus can be pre-allocated
+      with <constant>SNDRV_DMA_TYPE_CONTINUOUS</constant> type and the
+      <function>snd_dma_continuous_data(GFP_KERNEL)</function> device pointer,
+      where <constant>GFP_KERNEL</constant> is the kernel allocation flag to
+      use.
+      For the PCI scatter-gather buffers, use
+      <constant>SNDRV_DMA_TYPE_DEV_SG</constant> with
+      <function>snd_dma_pci_data(pci)</function>
+      (see the 
+          <link linkend="buffer-and-memory-non-contiguous"><citetitle>Non-Contiguous Buffers
+          </citetitle></link> section).
+      </para>
+
+      <para>
+        Once the buffer is pre-allocated, you can use the
+        allocator in the <structfield>hw_params</structfield> callback: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_malloc_pages(substream, size);
+]]>
+          </programlisting>
+        </informalexample>
+
+        Note that you have to pre-allocate to use this function.
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-external-hardware">
+      <title>External Hardware Buffers</title>
+      <para>
+        Some chips have their own hardware buffers and the DMA
+      transfer from the host memory is not available. In such a case,
+      you need to either 1) copy/set the audio data directly to the
+      external hardware buffer, or 2) make an intermediate buffer and
+      copy/set the data from it to the external hardware buffer in
+      interrupts (or in tasklets, preferably).
+      </para>
+
+      <para>
+        The first case works fine if the external hardware buffer is large
+      enough.  This method doesn't need any extra buffers and thus is
+      more effective. You need to define the
+      <structfield>copy</structfield> and
+      <structfield>silence</structfield> callbacks for 
+      the data transfer. However, there is a drawback: it cannot
+      be mmapped. The examples are GUS's GF1 PCM or emu8000's
+      wavetable PCM. 
+      </para>
+
+      <para>
+        The second case allows for mmap on the buffer, although you have
+      to handle an interrupt or a tasklet to transfer the data
+      from the intermediate buffer to the hardware buffer. You can find an
+      example in the vxpocket driver. 
+      </para>
+
+      <para>
+        Another case is when the chip uses a PCI memory-map
+      region for the buffer instead of the host memory. In this case,
+      mmap is available only on certain architectures like the Intel one.
+      In non-mmap mode, the data cannot be transferred as in the normal
+      way. Thus you need to define the <structfield>copy</structfield> and
+      <structfield>silence</structfield> callbacks as well, 
+      as in the cases above. The examples are found in
+      <filename>rme32.c</filename> and <filename>rme96.c</filename>. 
+      </para>
+
+      <para>
+        The implementation of the <structfield>copy</structfield> and
+        <structfield>silence</structfield> callbacks depends upon 
+        whether the hardware supports interleaved or non-interleaved
+        samples. The <structfield>copy</structfield> callback is
+        defined like below, a bit 
+        differently depending whether the direction is playback or
+        capture: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int playback_copy(struct snd_pcm_substream *substream, int channel,
+               snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
+  static int capture_copy(struct snd_pcm_substream *substream, int channel,
+               snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        In the case of interleaved samples, the second argument
+      (<parameter>channel</parameter>) is not used. The third argument
+      (<parameter>pos</parameter>) points the 
+      current position offset in frames. 
+      </para>
+
+      <para>
+        The meaning of the fourth argument is different between
+      playback and capture. For playback, it holds the source data
+      pointer, and for capture, it's the destination data pointer. 
+      </para>
+
+      <para>
+        The last argument is the number of frames to be copied.
+      </para>
+
+      <para>
+        What you have to do in this callback is again different
+        between playback and capture directions. In the
+        playback case, you copy the given amount of data
+        (<parameter>count</parameter>) at the specified pointer
+        (<parameter>src</parameter>) to the specified offset
+        (<parameter>pos</parameter>) on the hardware buffer. When
+        coded like memcpy-like way, the copy would be like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src,
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        For the capture direction, you copy the given amount of
+        data (<parameter>count</parameter>) at the specified offset
+        (<parameter>pos</parameter>) on the hardware buffer to the
+        specified pointer (<parameter>dst</parameter>). 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos),
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+
+        Note that both the position and the amount of data are given
+      in frames. 
+      </para>
+
+      <para>
+        In the case of non-interleaved samples, the implementation
+      will be a bit more complicated. 
+      </para>
+
+      <para>
+        You need to check the channel argument, and if it's -1, copy
+      the whole channels. Otherwise, you have to copy only the
+      specified channel. Please check
+      <filename>isa/gus/gus_pcm.c</filename> as an example. 
+      </para>
+
+      <para>
+        The <structfield>silence</structfield> callback is also
+        implemented in a similar way. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int silence(struct snd_pcm_substream *substream, int channel,
+                     snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The meanings of arguments are the same as in the
+      <structfield>copy</structfield> 
+      callback, although there is no <parameter>src/dst</parameter>
+      argument. In the case of interleaved samples, the channel
+      argument has no meaning, as well as on
+      <structfield>copy</structfield> callback.  
+      </para>
+
+      <para>
+        The role of <structfield>silence</structfield> callback is to
+        set the given amount 
+        (<parameter>count</parameter>) of silence data at the
+        specified offset (<parameter>pos</parameter>) on the hardware
+        buffer. Suppose that the data format is signed (that is, the
+        silent-data is 0), and the implementation using a memset-like
+        function would be like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0,
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        In the case of non-interleaved samples, again, the
+      implementation becomes a bit more complicated. See, for example,
+      <filename>isa/gus/gus_pcm.c</filename>. 
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-non-contiguous">
+      <title>Non-Contiguous Buffers</title>
+      <para>
+        If your hardware supports the page table as in emu10k1 or the
+      buffer descriptors as in via82xx, you can use the scatter-gather
+      (SG) DMA. ALSA provides an interface for handling SG-buffers.
+      The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>. 
+      </para>
+
+      <para>
+        For creating the SG-buffer handler, call
+        <function>snd_pcm_lib_preallocate_pages()</function> or
+        <function>snd_pcm_lib_preallocate_pages_for_all()</function>
+        with <constant>SNDRV_DMA_TYPE_DEV_SG</constant>
+	in the PCM constructor like other PCI pre-allocator.
+        You need to pass <function>snd_dma_pci_data(pci)</function>,
+        where pci is the struct <structname>pci_dev</structname> pointer
+        of the chip as well.
+        The <type>struct snd_sg_buf</type> instance is created as
+        substream-&gt;dma_private. You can cast
+        the pointer like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Then call <function>snd_pcm_lib_malloc_pages()</function>
+      in the <structfield>hw_params</structfield> callback
+      as well as in the case of normal PCI buffer.
+      The SG-buffer handler will allocate the non-contiguous kernel
+      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.
+      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>. 
+      </para>
+
+      <para>
+        When a SG-handler is used, you need to set
+      <function>snd_pcm_sgbuf_ops_page</function> as
+      the <structfield>page</structfield> callback.
+      (See <link linkend="pcm-interface-operators-page-callback">
+      <citetitle>page callback section</citetitle></link>.)
+      </para>
+
+      <para>
+        To release the data, call
+      <function>snd_pcm_lib_free_pages()</function> in the
+      <structfield>hw_free</structfield> callback as usual.
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-vmalloced">
+      <title>Vmalloc'ed Buffers</title>
+      <para>
+        It's possible to use a buffer allocated via
+      <function>vmalloc</function>, for example, for an intermediate
+      buffer. Since the allocated pages are not contiguous, you need
+      to set the <structfield>page</structfield> callback to obtain
+      the physical address at every offset. 
+      </para>
+
+      <para>
+        The implementation of <structfield>page</structfield> callback
+        would be like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  #include <linux/vmalloc.h>
+
+  /* get the physical page pointer on the given offset */
+  static struct page *mychip_page(struct snd_pcm_substream *substream,
+                                  unsigned long offset)
+  {
+          void *pageptr = substream->runtime->dma_area + offset;
+          return vmalloc_to_page(pageptr);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Proc Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="proc-interface">
+    <title>Proc Interface</title>
+    <para>
+      ALSA provides an easy interface for procfs. The proc files are
+      very useful for debugging. I recommend you set up proc files if
+      you write a driver and want to get a running status or register
+      dumps. The API is found in
+      <filename>&lt;sound/info.h&gt;</filename>. 
+    </para>
+
+    <para>
+      To create a proc file, call
+      <function>snd_card_proc_new()</function>. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  struct snd_info_entry *entry;
+  int err = snd_card_proc_new(card, "my-file", &entry);
+]]>
+        </programlisting>
+      </informalexample>
+
+      where the second argument specifies the name of the proc file to be
+    created. The above example will create a file
+    <filename>my-file</filename> under the card directory,
+    e.g. <filename>/proc/asound/card0/my-file</filename>. 
+    </para>
+
+    <para>
+    Like other components, the proc entry created via
+    <function>snd_card_proc_new()</function> will be registered and
+    released automatically in the card registration and release
+    functions.
+    </para>
+
+    <para>
+      When the creation is successful, the function stores a new
+    instance in the pointer given in the third argument.
+    It is initialized as a text proc file for read only.  To use
+    this proc file as a read-only text file as it is, set the read
+    callback with a private data via 
+     <function>snd_info_set_text_ops()</function>.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  snd_info_set_text_ops(entry, chip, my_proc_read);
+]]>
+        </programlisting>
+      </informalexample>
+    
+    where the second argument (<parameter>chip</parameter>) is the
+    private data to be used in the callbacks. The third parameter
+    specifies the read buffer size and the fourth
+    (<parameter>my_proc_read</parameter>) is the callback function, which
+    is defined like
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer);
+]]>
+        </programlisting>
+      </informalexample>
+    
+    </para>
+
+    <para>
+    In the read callback, use <function>snd_iprintf()</function> for
+    output strings, which works just like normal
+    <function>printf()</function>.  For example,
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer)
+  {
+          struct my_chip *chip = entry->private_data;
+
+          snd_iprintf(buffer, "This is my chip!\n");
+          snd_iprintf(buffer, "Port = %ld\n", chip->port);
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+    The file permissions can be changed afterwards.  As default, it's
+    set as read only for all users.  If you want to add write
+    permission for the user (root as default), do as follows:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+ entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+]]>
+        </programlisting>
+      </informalexample>
+
+    and set the write buffer size and the callback
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  entry->c.text.write = my_proc_write;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      For the write callback, you can use
+    <function>snd_info_get_line()</function> to get a text line, and
+    <function>snd_info_get_str()</function> to retrieve a string from
+    the line. Some examples are found in
+    <filename>core/oss/mixer_oss.c</filename>, core/oss/and
+    <filename>pcm_oss.c</filename>. 
+    </para>
+
+    <para>
+      For a raw-data proc-file, set the attributes as follows:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static struct snd_info_entry_ops my_file_io_ops = {
+          .read = my_file_io_read,
+  };
+
+  entry->content = SNDRV_INFO_CONTENT_DATA;
+  entry->private_data = chip;
+  entry->c.ops = &my_file_io_ops;
+  entry->size = 4096;
+  entry->mode = S_IFREG | S_IRUGO;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      The callback is much more complicated than the text-file
+      version. You need to use a low-level I/O functions such as
+      <function>copy_from/to_user()</function> to transfer the
+      data.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static long my_file_io_read(struct snd_info_entry *entry,
+                              void *file_private_data,
+                              struct file *file,
+                              char *buf,
+                              unsigned long count,
+                              unsigned long pos)
+  {
+          long size = count;
+          if (pos + size > local_max_size)
+                  size = local_max_size - pos;
+          if (copy_to_user(buf, local_data + pos, size))
+                  return -EFAULT;
+          return size;
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Power Management  -->
+<!-- ****************************************************** -->
+  <chapter id="power-management">
+    <title>Power Management</title>
+    <para>
+      If the chip is supposed to work with suspend/resume
+      functions, you need to add power-management code to the
+      driver. The additional code for power-management should be
+      <function>ifdef</function>'ed with
+      <constant>CONFIG_PM</constant>. 
+    </para>
+
+	<para>
+	If the driver <emphasis>fully</emphasis> supports suspend/resume
+	that is, the device can be
+	properly resumed to its state when suspend was called,
+	you can set the <constant>SNDRV_PCM_INFO_RESUME</constant> flag
+	in the pcm info field.  Usually, this is possible when the
+	registers of the chip can be safely saved and restored to
+	RAM. If this is set, the trigger callback is called with
+	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> after the resume
+	callback completes. 
+	</para>
+
+	<para>
+	Even if the driver doesn't support PM fully but 
+	partial suspend/resume is still possible, it's still worthy to
+	implement suspend/resume callbacks. In such a case, applications
+	would reset the status by calling
+	<function>snd_pcm_prepare()</function> and restart the stream
+	appropriately.  Hence, you can define suspend/resume callbacks
+	below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
+	info flag to the PCM.
+	</para>
+	
+	<para>
+	Note that the trigger with SUSPEND can always be called when
+	<function>snd_pcm_suspend_all</function> is called,
+	regardless of the <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
+	The <constant>RESUME</constant> flag affects only the behavior
+	of <function>snd_pcm_resume()</function>.
+	(Thus, in theory,
+	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
+	to be handled in the trigger callback when no
+	<constant>SNDRV_PCM_INFO_RESUME</constant> flag is set.  But,
+	it's better to keep it for compatibility reasons.)
+	</para>
+    <para>
+      In the earlier version of ALSA drivers, a common
+      power-management layer was provided, but it has been removed.
+      The driver needs to define the suspend/resume hooks according to
+      the bus the device is connected to.  In the case of PCI drivers, the
+      callbacks look like below:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  #ifdef CONFIG_PM
+  static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
+  {
+          .... /* do things for suspend */
+          return 0;
+  }
+  static int snd_my_resume(struct pci_dev *pci)
+  {
+          .... /* do things for suspend */
+          return 0;
+  }
+  #endif
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      The scheme of the real suspend job is as follows.
+
+      <orderedlist>
+        <listitem><para>Retrieve the card and the chip data.</para></listitem>
+        <listitem><para>Call <function>snd_power_change_state()</function> with
+	  <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
+	  power status.</para></listitem>
+        <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
+	<listitem><para>If AC97 codecs are used, call
+	<function>snd_ac97_suspend()</function> for each codec.</para></listitem>
+        <listitem><para>Save the register values if necessary.</para></listitem>
+        <listitem><para>Stop the hardware if necessary.</para></listitem>
+        <listitem><para>Disable the PCI device by calling
+	  <function>pci_disable_device()</function>.  Then, call
+          <function>pci_save_state()</function> at last.</para></listitem>
+      </orderedlist>
+    </para>
+
+    <para>
+      A typical code would be like:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
+  {
+          /* (1) */
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
+          /* (2) */
+          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+          /* (3) */
+          snd_pcm_suspend_all(chip->pcm);
+          /* (4) */
+          snd_ac97_suspend(chip->ac97);
+          /* (5) */
+          snd_mychip_save_registers(chip);
+          /* (6) */
+          snd_mychip_stop_hardware(chip);
+          /* (7) */
+          pci_disable_device(pci);
+          pci_save_state(pci);
+          return 0;
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+    The scheme of the real resume job is as follows.
+
+    <orderedlist>
+    <listitem><para>Retrieve the card and the chip data.</para></listitem>
+    <listitem><para>Set up PCI. First, call <function>pci_restore_state()</function>.
+    	Then enable the pci device again by calling <function>pci_enable_device()</function>.
+	Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
+    <listitem><para>Re-initialize the chip.</para></listitem>
+    <listitem><para>Restore the saved registers if necessary.</para></listitem>
+    <listitem><para>Resume the mixer, e.g. calling
+    <function>snd_ac97_resume()</function>.</para></listitem>
+    <listitem><para>Restart the hardware (if any).</para></listitem>
+    <listitem><para>Call <function>snd_power_change_state()</function> with
+	<constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
+    </orderedlist>
+    </para>
+
+    <para>
+    A typical code would be like:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int mychip_resume(struct pci_dev *pci)
+  {
+          /* (1) */
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
+          /* (2) */
+          pci_restore_state(pci);
+          pci_enable_device(pci);
+          pci_set_master(pci);
+          /* (3) */
+          snd_mychip_reinit_chip(chip);
+          /* (4) */
+          snd_mychip_restore_registers(chip);
+          /* (5) */
+          snd_ac97_resume(chip->ac97);
+          /* (6) */
+          snd_mychip_restart_chip(chip);
+          /* (7) */
+          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+          return 0;
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+	As shown in the above, it's better to save registers after
+	suspending the PCM operations via
+	<function>snd_pcm_suspend_all()</function> or
+	<function>snd_pcm_suspend()</function>.  It means that the PCM
+	streams are already stoppped when the register snapshot is
+	taken.  But, remember that you don't have to restart the PCM
+	stream in the resume callback. It'll be restarted via 
+	trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
+	when necessary.
+    </para>
+
+    <para>
+      OK, we have all callbacks now. Let's set them up. In the
+      initialization of the card, make sure that you can get the chip
+      data from the card instance, typically via
+      <structfield>private_data</structfield> field, in case you
+      created the chip data individually.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          ....
+          struct snd_card *card;
+          struct mychip *chip;
+          int err;
+          ....
+          err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+          ....
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          ....
+          card->private_data = chip;
+          ....
+  }
+]]>
+        </programlisting>
+      </informalexample>
+
+	When you created the chip data with
+	<function>snd_card_create()</function>, it's anyway accessible
+	via <structfield>private_data</structfield> field.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          ....
+          struct snd_card *card;
+          struct mychip *chip;
+          int err;
+          ....
+          err = snd_card_create(index[dev], id[dev], THIS_MODULE,
+                                sizeof(struct mychip), &card);
+          ....
+          chip = card->private_data;
+          ....
+  }
+]]>
+        </programlisting>
+      </informalexample>
+
+    </para>
+
+    <para>
+      If you need a space to save the registers, allocate the
+	buffer for it here, too, since it would be fatal
+    if you cannot allocate a memory in the suspend phase.
+    The allocated buffer should be released in the corresponding
+    destructor.
+    </para>
+
+    <para>
+      And next, set suspend/resume callbacks to the pci_driver.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static struct pci_driver driver = {
+          .name = "My Chip",
+          .id_table = snd_my_ids,
+          .probe = snd_my_probe,
+          .remove = __devexit_p(snd_my_remove),
+  #ifdef CONFIG_PM
+          .suspend = snd_my_suspend,
+          .resume = snd_my_resume,
+  #endif
+  };
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Module Parameters  -->
+<!-- ****************************************************** -->
+  <chapter id="module-parameters">
+    <title>Module Parameters</title>
+    <para>
+      There are standard module options for ALSA. At least, each
+      module should have the <parameter>index</parameter>,
+      <parameter>id</parameter> and <parameter>enable</parameter>
+      options. 
+    </para>
+
+    <para>
+      If the module supports multiple cards (usually up to
+      8 = <constant>SNDRV_CARDS</constant> cards), they should be
+      arrays. The default initial values are defined already as
+      constants for easier programming:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+  static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      If the module supports only a single card, they could be single
+    variables, instead.  <parameter>enable</parameter> option is not
+    always necessary in this case, but it would be better to have a
+    dummy option for compatibility.
+    </para>
+
+    <para>
+      The module parameters must be declared with the standard
+    <function>module_param()()</function>,
+    <function>module_param_array()()</function> and
+    <function>MODULE_PARM_DESC()</function> macros.
+    </para>
+
+    <para>
+      The typical coding would be like below:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  #define CARD_NAME "My Chip"
+
+  module_param_array(index, int, NULL, 0444);
+  MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
+  module_param_array(id, charp, NULL, 0444);
+  MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
+  module_param_array(enable, bool, NULL, 0444);
+  MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      Also, don't forget to define the module description, classes,
+      license and devices. Especially, the recent modprobe requires to
+      define the module license as GPL, etc., otherwise the system is
+      shown as <quote>tainted</quote>. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  MODULE_DESCRIPTION("My Chip");
+  MODULE_LICENSE("GPL");
+  MODULE_SUPPORTED_DEVICE("{{Vendor,My Chip Name}}");
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- How To Put Your Driver  -->
+<!-- ****************************************************** -->
+  <chapter id="how-to-put-your-driver">
+    <title>How To Put Your Driver Into ALSA Tree</title>
+	<section>
+	<title>General</title>
+	<para>
+	So far, you've learned how to write the driver codes.
+	And you might have a question now: how to put my own
+	driver into the ALSA driver tree?
+	Here (finally :) the standard procedure is described briefly.
+	</para>
+
+	<para>
+	Suppose that you create a new PCI driver for the card
+	<quote>xyz</quote>.  The card module name would be
+	snd-xyz.  The new driver is usually put into the alsa-driver
+	tree, <filename>alsa-driver/pci</filename> directory in
+	the case of PCI cards.
+	Then the driver is evaluated, audited and tested
+	by developers and users.  After a certain time, the driver
+	will go to the alsa-kernel tree (to the corresponding directory,
+	such as <filename>alsa-kernel/pci</filename>) and eventually
+ 	will be integrated into the Linux 2.6 tree (the directory would be
+	<filename>linux/sound/pci</filename>).
+	</para>
+
+	<para>
+	In the following sections, the driver code is supposed
+	to be put into alsa-driver tree. The two cases are covered:
+	a driver consisting of a single source file and one consisting
+	of several source files.
+	</para>
+	</section>
+
+	<section>
+	<title>Driver with A Single Source File</title>
+	<para>
+	<orderedlist>
+	<listitem>
+	<para>
+	Modify alsa-driver/pci/Makefile
+	</para>
+
+	<para>
+	Suppose you have a file xyz.c.  Add the following
+	two lines
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  snd-xyz-objs := xyz.o
+  obj-$(CONFIG_SND_XYZ) += snd-xyz.o
+]]>
+        </programlisting>
+      </informalexample>
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	Create the Kconfig entry
+	</para>
+
+	<para>
+	Add the new entry of Kconfig for your xyz driver.
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  config SND_XYZ
+          tristate "Foobar XYZ"
+          depends on SND
+          select SND_PCM
+          help
+            Say Y here to include support for Foobar XYZ soundcard.
+
+            To compile this driver as a module, choose M here: the module
+            will be called snd-xyz.
+]]>
+        </programlisting>
+      </informalexample>
+
+	the line, select SND_PCM, specifies that the driver xyz supports
+	PCM.  In addition to SND_PCM, the following components are
+	supported for select command:
+	SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART,
+	SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC.
+	Add the select command for each supported component.
+	</para>
+
+	<para>
+	Note that some selections imply the lowlevel selections.
+	For example, PCM includes TIMER, MPU401_UART includes RAWMIDI,
+	AC97_CODEC includes PCM, and OPL3_LIB includes HWDEP.
+	You don't need to give the lowlevel selections again.
+	</para>
+
+	<para>
+	For the details of Kconfig script, refer to the kbuild
+	documentation.
+	</para>
+
+	</listitem>
+
+	<listitem>
+	<para>
+	Run cvscompile script to re-generate the configure script and
+	build the whole stuff again.
+	</para>
+	</listitem>
+	</orderedlist>
+	</para>
+	</section>
+
+	<section>
+	<title>Drivers with Several Source Files</title>
+	<para>
+	Suppose that the driver snd-xyz have several source files.
+	They are located in the new subdirectory,
+	pci/xyz.
+
+	<orderedlist>
+	<listitem>
+	<para>
+	Add a new directory (<filename>xyz</filename>) in
+	<filename>alsa-driver/pci/Makefile</filename> as below
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  obj-$(CONFIG_SND) += xyz/
+]]>
+        </programlisting>
+      </informalexample>
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	Under the directory <filename>xyz</filename>, create a Makefile
+
+      <example>
+	<title>Sample Makefile for a driver xyz</title>
+        <programlisting>
+<![CDATA[
+  ifndef SND_TOPDIR
+  SND_TOPDIR=../..
+  endif
+
+  include $(SND_TOPDIR)/toplevel.config
+  include $(SND_TOPDIR)/Makefile.conf
+
+  snd-xyz-objs := xyz.o abc.o def.o
+
+  obj-$(CONFIG_SND_XYZ) += snd-xyz.o
+
+  include $(SND_TOPDIR)/Rules.make
+]]>
+        </programlisting>
+      </example>
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	Create the Kconfig entry
+	</para>
+
+	<para>
+	This procedure is as same as in the last section.
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	Run cvscompile script to re-generate the configure script and
+	build the whole stuff again.
+	</para>
+	</listitem>
+	</orderedlist>
+	</para>
+	</section>
+
+  </chapter>
+
+<!-- ****************************************************** -->
+<!-- Useful Functions  -->
+<!-- ****************************************************** -->
+  <chapter id="useful-functions">
+    <title>Useful Functions</title>
+
+    <section id="useful-functions-snd-printk">
+      <title><function>snd_printk()</function> and friends</title>
+      <para>
+        ALSA provides a verbose version of the
+      <function>printk()</function> function. If a kernel config
+      <constant>CONFIG_SND_VERBOSE_PRINTK</constant> is set, this
+      function prints the given message together with the file name
+      and the line of the caller. The <constant>KERN_XXX</constant>
+      prefix is processed as 
+      well as the original <function>printk()</function> does, so it's
+      recommended to add this prefix, e.g. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_printk(KERN_ERR "Oh my, sorry, it's extremely bad!\n");
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        There are also <function>printk()</function>'s for
+      debugging. <function>snd_printd()</function> can be used for
+      general debugging purposes. If
+      <constant>CONFIG_SND_DEBUG</constant> is set, this function is
+      compiled, and works just like
+      <function>snd_printk()</function>. If the ALSA is compiled
+      without the debugging flag, it's ignored. 
+      </para>
+
+      <para>
+        <function>snd_printdd()</function> is compiled in only when
+      <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is set. Please note
+      that <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is not set as default
+      even if you configure the alsa-driver with
+      <option>--with-debug=full</option> option. You need to give
+      explicitly <option>--with-debug=detect</option> option instead. 
+      </para>
+    </section>
+
+    <section id="useful-functions-snd-bug">
+      <title><function>snd_BUG()</function></title>
+      <para>
+        It shows the <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_BUG_ON</function> at the point.
+      It's useful to show that a fatal error happens there. 
+      </para>
+      <para>
+	 When no debug flag is set, this macro is ignored. 
+      </para>
+    </section>
+
+    <section id="useful-functions-snd-bug-on">
+      <title><function>snd_BUG_ON()</function></title>
+      <para>
+        <function>snd_BUG_ON()</function> macro is similar with
+	<function>WARN_ON()</function> macro. For example,  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_BUG_ON(!pointer);
+]]>
+          </programlisting>
+        </informalexample>
+
+	or it can be used as the condition,
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (snd_BUG_ON(non_zero_is_bug))
+          return -EINVAL;
+]]>
+          </programlisting>
+        </informalexample>
+
+      </para>
+
+      <para>
+        The macro takes an conditional expression to evaluate.
+	When <constant>CONFIG_SND_DEBUG</constant>, is set, the
+	expression is actually evaluated. If it's non-zero, it shows
+	the warning message such as
+	<computeroutput>BUG? (xxx)</computeroutput>
+	normally followed by stack trace.  It returns the evaluated
+	value.
+	When no <constant>CONFIG_SND_DEBUG</constant> is set, this
+	macro always returns zero.
+      </para>
+
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Acknowledgments  -->
+<!-- ****************************************************** -->
+  <chapter id="acknowledgments">
+    <title>Acknowledgments</title>
+    <para>
+      I would like to thank Phil Kerr for his help for improvement and
+      corrections of this document. 
+    </para>
+    <para>
+    Kevin Conder reformatted the original plain-text to the
+    DocBook format.
+    </para>
+    <para>
+    Giuliano Pochini corrected typos and contributed the example codes
+    in the hardware constraints section.
+    </para>
+  </chapter>
+</book>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/dontdiff linux-libre-2.6.30-gnu1/Documentation/dontdiff
--- linux-libre-2.6.29-gnu1/Documentation/dontdiff	2013-05-03 17:59:59.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/dontdiff	2013-05-03 16:43:47.000000000 -0400
@@ -62,7 +62,6 @@ aic7*reg_print.c*
 aic7*seq.h*
 aicasm
 aicdb.h*
-asm
 asm-offsets.h
 asm_offsets.h
 autoconf.h*
diff -druNp linux-libre-2.6.29-gnu1/Documentation/driver-model/platform.txt linux-libre-2.6.30-gnu1/Documentation/driver-model/platform.txt
--- linux-libre-2.6.29-gnu1/Documentation/driver-model/platform.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/driver-model/platform.txt	2009-06-09 23:05:27.000000000 -0400
@@ -169,3 +169,62 @@ three different ways to find such a matc
       be probed later if another device registers.  (Which is OK, since
       this interface is only for use with non-hotpluggable devices.)
 
+
+Early Platform Devices and Drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The early platform interfaces provide platform data to platform device
+drivers early on during the system boot. The code is built on top of the
+early_param() command line parsing and can be executed very early on.
+
+Example: "earlyprintk" class early serial console in 6 steps
+
+1. Registering early platform device data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The architecture code registers platform device data using the function
+early_platform_add_devices(). In the case of early serial console this
+should be hardware configuration for the serial port. Devices registered
+at this point will later on be matched against early platform drivers.
+
+2. Parsing kernel command line
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The architecture code calls parse_early_param() to parse the kernel
+command line. This will execute all matching early_param() callbacks.
+User specified early platform devices will be registered at this point.
+For the early serial console case the user can specify port on the
+kernel command line as "earlyprintk=serial.0" where "earlyprintk" is
+the class string, "serial" is the name of the platfrom driver and
+0 is the platform device id. If the id is -1 then the dot and the
+id can be omitted.
+
+3. Installing early platform drivers belonging to a certain class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The architecture code may optionally force registration of all early
+platform drivers belonging to a certain class using the function
+early_platform_driver_register_all(). User specified devices from
+step 2 have priority over these. This step is omitted by the serial
+driver example since the early serial driver code should be disabled
+unless the user has specified port on the kernel command line.
+
+4. Early platform driver registration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Compiled-in platform drivers making use of early_platform_init() are
+automatically registered during step 2 or 3. The serial driver example
+should use early_platform_init("earlyprintk", &platform_driver).
+
+5. Probing of early platform drivers belonging to a certain class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The architecture code calls early_platform_driver_probe() to match
+registered early platform devices associated with a certain class with
+registered early platform drivers. Matched devices will get probed().
+This step can be executed at any point during the early boot. As soon
+as possible may be good for the serial port case.
+
+6. Inside the early platform driver probe()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The driver code needs to take special care during early boot, especially
+when it comes to memory allocation and interrupt registration. The code
+in the probe() function can use is_early_platform_device() to check if
+it is called at early platform device or at the regular platform device
+time. The early serial driver performs register_console() at this point.
+
+For further information, see <linux/platform_device.h>.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/dynamic-debug-howto.txt linux-libre-2.6.30-gnu1/Documentation/dynamic-debug-howto.txt
--- linux-libre-2.6.29-gnu1/Documentation/dynamic-debug-howto.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/dynamic-debug-howto.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,240 @@
+
+Introduction
+============
+
+This document describes how to use the dynamic debug (ddebug) feature.
+
+Dynamic debug is designed to allow you to dynamically enable/disable kernel
+code to obtain additional kernel information. Currently, if
+CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be
+dynamically enabled per-callsite.
+
+Dynamic debug has even more useful features:
+
+ * Simple query language allows turning on and off debugging statements by
+   matching any combination of:
+
+   - source filename
+   - function name
+   - line number (including ranges of line numbers)
+   - module name
+   - format string
+
+ * Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be
+   read to display the complete list of known debug statements, to help guide you
+
+Controlling dynamic debug Behaviour
+===============================
+
+The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
+control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
+filesystem, in order to make use of this feature. Subsequently, we refer to the
+control file as: <debugfs>/dynamic_debug/control. For example, if you want to
+enable printing from source file 'svcsock.c', line 1603 you simply do:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
+				<debugfs>/dynamic_debug/control
+
+If you make a mistake with the syntax, the write will fail thus:
+
+nullarbor:~ # echo 'file svcsock.c wtf 1 +p' >
+				<debugfs>/dynamic_debug/control
+-bash: echo: write error: Invalid argument
+
+Viewing Dynamic Debug Behaviour
+===========================
+
+You can view the currently configured behaviour of all the debug statements
+via:
+
+nullarbor:~ # cat <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline       : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth         : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests     : %d\012"
+...
+
+
+You can also apply standard Unix text manipulation filters to this
+data, e.g.
+
+nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control  | wc -l
+62
+
+nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l
+42
+
+Note in particular that the third column shows the enabled behaviour
+flags for each debug statement callsite (see below for definitions of the
+flags).  The default value, no extra behaviour enabled, is "-".  So
+you can view all the debug statement callsites with any non-default flags:
+
+nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012"
+
+
+Command Language Reference
+==========================
+
+At the lexical level, a command comprises a sequence of words separated
+by whitespace characters.  Note that newlines are treated as word
+separators and do *not* end a command or allow multiple commands to
+be done together.  So these are all equivalent:
+
+nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
+				<debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c '  file   svcsock.c     line  1603 +p  ' >
+				<debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
+				<debugfs>/dynamic_debug/control
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+				<debugfs>/dynamic_debug/control
+
+Commands are bounded by a write() system call.  If you want to do
+multiple commands you need to do a separate "echo" for each, like:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
+> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
+
+or even like:
+
+nullarbor:~ # (
+> echo 'file svcsock.c line 1603 +p' ;\
+> echo 'file svcsock.c line 1563 +p' ;\
+> ) > /proc/dprintk
+
+At the syntactical level, a command comprises a sequence of match
+specifications, followed by a flags change specification.
+
+command ::= match-spec* flags-spec
+
+The match-spec's are used to choose a subset of the known dprintk()
+callsites to which to apply the flags-spec.  Think of them as a query
+with implicit ANDs between each pair.  Note that an empty list of
+match-specs is possible, but is not very useful because it will not
+match any debug statement callsites.
+
+A match specification comprises a keyword, which controls the attribute
+of the callsite to be compared, and a value to compare against.  Possible
+keywords are:
+
+match-spec ::= 'func' string |
+	       'file' string |
+	       'module' string |
+	       'format' string |
+	       'line' line-range
+
+line-range ::= lineno |
+	       '-'lineno |
+	       lineno'-' |
+	       lineno'-'lineno
+// Note: line-range cannot contain space, e.g.
+// "1-30" is valid range but "1 - 30" is not.
+
+lineno ::= unsigned-int
+
+The meanings of each keyword are:
+
+func
+    The given string is compared against the function name
+    of each callsite.  Example:
+
+    func svc_tcp_accept
+
+file
+    The given string is compared against either the full
+    pathname or the basename of the source file of each
+    callsite.  Examples:
+
+    file svcsock.c
+    file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
+
+module
+    The given string is compared against the module name
+    of each callsite.  The module name is the string as
+    seen in "lsmod", i.e. without the directory or the .ko
+    suffix and with '-' changed to '_'.  Examples:
+
+    module sunrpc
+    module nfsd
+
+format
+    The given string is searched for in the dynamic debug format
+    string.  Note that the string does not need to match the
+    entire format, only some part.  Whitespace and other
+    special characters can be escaped using C octal character
+    escape \ooo notation, e.g. the space character is \040.
+    Alternatively, the string can be enclosed in double quote
+    characters (") or single quote characters (').
+    Examples:
+
+    format svcrdma:	    // many of the NFS/RDMA server dprintks
+    format readahead	    // some dprintks in the readahead cache
+    format nfsd:\040SETATTR // one way to match a format with whitespace
+    format "nfsd: SETATTR"  // a neater way to match a format with whitespace
+    format 'nfsd: SETATTR'  // yet another way to match a format with whitespace
+
+line
+    The given line number or range of line numbers is compared
+    against the line number of each dprintk() callsite.  A single
+    line number matches the callsite line number exactly.  A
+    range of line numbers matches any callsite between the first
+    and last line number inclusive.  An empty first number means
+    the first line in the file, an empty line number means the
+    last number in the file.  Examples:
+
+    line 1603	    // exactly line 1603
+    line 1600-1605  // the six lines from line 1600 to line 1605
+    line -1605	    // the 1605 lines from line 1 to line 1605
+    line 1600-	    // all lines from line 1600 to the end of the file
+
+The flags specification comprises a change operation followed
+by one or more flag characters.  The change operation is one
+of the characters:
+
+-
+    remove the given flags
+
++
+    add the given flags
+
+=
+    set the flags to the given flags
+
+The flags are:
+
+p
+    Causes a printk() message to be emitted to dmesg
+
+Note the regexp ^[-+=][scp]+$ matches a flags specification.
+Note also that there is no convenient syntax to remove all
+the flags at once, you need to use "-psc".
+
+Examples
+========
+
+// enable the message at line 1603 of file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+				<debugfs>/dynamic_debug/control
+
+// enable all the messages in file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c +p' >
+				<debugfs>/dynamic_debug/control
+
+// enable all the messages in the NFS server module
+nullarbor:~ # echo -n 'module nfsd +p' >
+				<debugfs>/dynamic_debug/control
+
+// enable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process +p' >
+				<debugfs>/dynamic_debug/control
+
+// disable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process -p' >
+				<debugfs>/dynamic_debug/control
+
+// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
+nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
+				<debugfs>/dynamic_debug/control
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/00-INDEX linux-libre-2.6.30-gnu1/Documentation/fb/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/fb/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -11,8 +11,6 @@ aty128fb.txt
 	- info on the ATI Rage128 frame buffer driver.
 cirrusfb.txt
 	- info on the driver for Cirrus Logic chipsets.
-cyblafb/
-	- directory with documentation files related to the cyblafb driver.
 deferred_io.txt
 	- an introduction to deferred IO.
 fbcon.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/bugs linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/bugs
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/bugs	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/bugs	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-Bugs
-====
-
-I currently don't know of any bug. Please do send reports to:
- - linux-fbdev-devel@lists.sourceforge.net
- - Knut_Petersen@t-online.de.
-
-
-Untested features
-=================
-
-All LCD stuff is untested. If it worked in tridentfb, it should work in
-cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/credits linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/credits
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/credits	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/credits	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-Thanks to
-=========
-   * 	Alan Hourihane, for writing the X trident driver
-   *	Jani Monoses, for writing the tridentfb driver
-   *	Antonino A. Daplas, for review of the first published
-	version of cyblafb and some code
-   *	Jochen Hein, for testing and a helpfull bug report
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/documentation linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/documentation
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/documentation	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/documentation	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-Available Documentation
-=======================
-
-Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
-2001, available from VIA:
-
-	http://www.viavpsd.com/product/6/15/DS8601A182.pdf
-
-The datasheet is incomplete, some registers that need to be programmed are not
-explained at all and important bits are listed as "reserved". But you really
-need the datasheet to understand the code.  "p. xxx" comments refer to page
-numbers of this document.
-
-XFree/XOrg drivers are available and of good quality, looking at the code
-there is a good idea if the datasheet does not provide enough information
-or if the datasheet seems to be wrong.
-
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/fb.modes linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/fb.modes
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/fb.modes	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/fb.modes	1969-12-31 19:00:00.000000000 -0500
@@ -1,154 +0,0 @@
-#
-#   Sample fb.modes file
-#
-#	Provides an incomplete list of working modes for
-#	the cyberblade/i1 graphics core.
-#
-#	The value 4294967256 is used instead of -40. Of course, -40 is not
-#	a really reasonable value, but chip design does not always follow
-#	logic. Believe me, it's ok, and it's the way the BIOS does it.
-#
-#	fbset requires 4294967256 in fb.modes and -40 as an argument to
-#	the -t parameter. That's also not too reasonable, and it might change
-#	in the future or might even be differt for your current version.
-#
-
-mode "640x480-50"
-    geometry 640 480 2048 4096 8
-    timings 47619 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-60"
-    geometry 640 480 2048 4096 8
-    timings 39682 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-70"
-    geometry 640 480 2048 4096 8
-    timings 34013 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-72"
-    geometry 640 480 2048 4096 8
-    timings 33068 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-75"
-    geometry 640 480 2048 4096 8
-    timings 31746 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-80"
-    geometry 640 480 2048 4096 8
-    timings 29761 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-85"
-    geometry 640 480 2048 4096 8
-    timings 28011 4294967256 24 17 0 216 3
-endmode
-
-mode "800x600-50"
-    geometry 800 600 2048 4096 8
-    timings 30303 96 24 14 0 136 11
-endmode
-
-mode "800x600-60"
-    geometry 800 600 2048 4096 8
-    timings 25252 96 24 14 0 136 11
-endmode
-
-mode "800x600-70"
-    geometry 800 600 2048 4096 8
-    timings 21645 96 24 14 0 136 11
-endmode
-
-mode "800x600-72"
-    geometry 800 600 2048 4096 8
-    timings 21043 96 24 14 0 136 11
-endmode
-
-mode "800x600-75"
-    geometry 800 600 2048 4096 8
-    timings 20202 96 24 14 0 136 11
-endmode
-
-mode "800x600-80"
-    geometry 800 600 2048 4096 8
-    timings 18939 96 24 14 0 136 11
-endmode
-
-mode "800x600-85"
-    geometry 800 600 2048 4096 8
-    timings 17825 96 24 14 0 136 11
-endmode
-
-mode "1024x768-50"
-    geometry 1024 768 2048 4096 8
-    timings 19054 144 24 29 0 120 3
-endmode
-
-mode "1024x768-60"
-    geometry 1024 768 2048 4096 8
-    timings 15880 144 24 29 0 120 3
-endmode
-
-mode "1024x768-70"
-    geometry 1024 768 2048 4096 8
-    timings 13610 144 24 29 0 120 3
-endmode
-
-mode "1024x768-72"
-    geometry 1024 768 2048 4096 8
-    timings 13232 144 24 29 0 120 3
-endmode
-
-mode "1024x768-75"
-    geometry 1024 768 2048 4096 8
-    timings 12703 144 24 29 0 120 3
-endmode
-
-mode "1024x768-80"
-    geometry 1024 768 2048 4096 8
-    timings 11910 144 24 29 0 120 3
-endmode
-
-mode "1024x768-85"
-    geometry 1024 768 2048 4096 8
-    timings 11209 144 24 29 0 120 3
-endmode
-
-mode "1280x1024-50"
-    geometry 1280 1024 2048 4096 8
-    timings 11114 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-60"
-    geometry 1280 1024 2048 4096 8
-    timings 9262 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-70"
-    geometry 1280 1024 2048 4096 8
-    timings 7939 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-72"
-    geometry 1280 1024 2048 4096 8
-    timings 7719 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-75"
-    geometry 1280 1024 2048 4096 8
-    timings 7410 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-80"
-    geometry 1280 1024 2048 4096 8
-    timings 6946 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-85"
-    geometry 1280 1024 2048 4096 8
-    timings 6538 232 16 39 0 160 3
-endmode
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/performance linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/performance
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/performance	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/performance	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-Speed
-=====
-
-CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
-for mode 1280x1024-[8,16,32]@61 Hz.
-
-Test 1: Cat a file with 2000 lines of 0 characters.
-Test 2: Cat a file with 2000 lines of 80 characters.
-Test 3: Cat a file with 2000 lines of 160 characters.
-
-All values show system time use in seconds, kernel 2.6.12 was used for
-the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
-patch that speeds up kernel bitblitting a lot ( > 20%).
-
-+-----------+-----------------------------------------------------+
-|	    |			not accelerated 		  |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	4.31 |	 4.33 |   6.05 |  12.81 |  ----  |  ----  |
-|    Test 2 |  67.94 |	 5.44 | 123.16 |  14.79 |  ----  |  ----  |
-|    Test 3 | 131.36 |	 6.55 | 240.12 |  16.76 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments |		      | 		| completely bro- |
-|	    |		      | 		| ken, monitor	  |
-|	    |		      | 		| switches off	  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			  accelerated			  |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |  ----  |	----  |  20.62 |   1.22 |  ----  |  ----  |
-|    Test 2 |  ----  |	----  |  22.61 |   3.19 |  ----  |  ----  |
-|    Test 3 |  ----  |	----  |  24.59 |   5.16 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments | broken, writing | broken, ok only | completely bro- |
-|	    | to wrong places | if bgcolor is	| ken, monitor	  |
-|	    | on screen + bug | black, bug in	| switches off	  |
-|	    | in fillrect()   | fillrect()	|		  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			not accelerated 		  |
-|   VESAFB  +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	4.26 |	 3.76 |   5.99 |   7.23 |  ----  |  ----  |
-|    Test 2 |  65.65 |	 4.89 | 120.88 |   9.08 |  ----  |  ----  |
-|    Test 3 | 126.91 |	 5.94 | 235.77 |  11.03 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments | vga=0x307       | vga=0x31a	| vga=0x31b not   |
-|	    | fh=80kHz	      | fh=80kHz	| supported by	  |
-|	    | fv=75kHz	      | fv=75kHz	| video BIOS and  |
-|	    |		      | 		| hardware	  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			  accelerated			  |
-|  CYBLAFB  +-----------------+-----------------+-----------------+
-|	    |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	8.02 |	 0.23 |  19.04 |   0.61 |  57.12 |   2.74 |
-|    Test 2 |	8.38 |	 0.55 |  19.39 |   0.92 |  57.54 |   3.13 |
-|    Test 3 |	8.73 |	 0.86 |  19.74 |   1.24 |  57.95 |   3.51 |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments |		      | 		|		  |
-|	    |		      | 		|		  |
-|	    |		      | 		|		  |
-|	    |		      | 		|		  |
-+-----------+-----------------+-----------------+-----------------+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/todo linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/todo
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/todo	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/todo	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-TODO / Missing features
-=======================
-
-Verify LCD stuff		"stretch" and "center" options are
-				completely untested ... this code needs to be
-				verified. As I don't have access to such
-				hardware, please contact me if you are
-				willing run some tests.
-
-Interlaced video modes		The reason that interleaved
-				modes are disabled is that I do not know
-				the meaning of the vertical interlace
-				parameter. Also the datasheet mentions a
-				bit d8 of a horizontal interlace parameter,
-				but nowhere the lower 8 bits. Please help
-				if you can.
-
-low-res double scan modes	Who needs it?
-
-accelerated color blitting	Who needs it? The console driver does use color
-				blitting for nothing but drawing the penguine,
-				everything else is done using color expanding
-				blitting of 1bpp character bitmaps.
-
-ioctls				Who needs it?
-
-TV-out				Will be done later. Use "vga= " at boot time
-				to set a suitable video mode.
-
-???				Feel free to contact me if you have any
-				feature requests
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/usage linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/usage
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/usage	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/usage	1969-12-31 19:00:00.000000000 -0500
@@ -1,217 +0,0 @@
-CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
-into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
-tested using a VIA EPIA 5000 board.
-
-Cyblafb - compiled into the kernel or as a module?
-==================================================
-
-You might compile cyblafb either as a module or compile it permanently into the
-kernel.
-
-Unless you have a real reason to do so you should not compile both vesafb and
-cyblafb permanently into the kernel. It's possible and it helps during the
-developement cycle, but it's useless and will at least block some otherwise
-usefull memory for ordinary users.
-
-Selecting Modes
-===============
-
-	Startup Mode
-	============
-
-	First of all, you might use the "vga=???" boot parameter as it is
-	documented in vesafb.txt and svga.txt. Cyblafb will detect the video
-	mode selected and will use the geometry and timings found by
-	inspecting the hardware registers.
-
-		video=cyblafb vga=0x317
-
-	Alternatively you might use a combination of the mode, ref and bpp
-	parameters. If you compiled the driver into the kernel, add something
-	like this to the kernel command line:
-
-		video=cyblafb:1280x1024,bpp=16,ref=50 ...
-
-	If you compiled the driver as a module, the same mode would be
-	selected by the following command:
-
-		modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
-
-	None of the modes possible to select as startup modes are affected by
-	the problems described at the end of the next subsection.
-
-	For all startup modes cyblafb chooses a virtual x resolution of 2048,
-	the only exception is mode 1280x1024 in combination with 32 bpp. This
-	allows ywrap scrolling for all those modes if rotation is 0 or 2, and
-	also fast scrolling if rotation is 1 or 3. The default virtual y reso-
-	lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
-	again with the only exception of 1280x1024 at 32 bpp.
-
-	Please do set your video memory size to 8 Mb in the Bios setup. Other
-	values will work, but performace is decreased for a lot of modes.
-
-	Mode changes using fbset
-	========================
-
-	You might use fbset to change the video mode, see "man fbset". Cyblafb
-	generally does assume that you know what you are doing. But it does
-	some checks, especially those that are needed to prevent you from
-	damaging your hardware.
-
-		- only 8, 16, 24 and 32 bpp video modes are accepted
-		- interlaced video modes are not accepted
-		- double scan video modes are not accepted
-		- if a flat panel is found, cyblafb does not allow you
-		  to program a resolution higher than the physical
-		  resolution of the flat panel monitor
-		- cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
-		  and (currently) 24 bit modes use a doubled vclk internally,
-		  the dotclock limit as seen by fbset is 115 MHz for those
-		  modes and 230 MHz for 8 and 16 bpp modes.
-		- cyblafb will allow you to select very high resolutions as
-		  long as the hardware can be programmed to these modes. The
-		  documented limit 1600x1200 is not enforced, but don't expect
-		  perfect signal quality.
-
-	Any request that violates the rules given above will be either changed
-	to something the hardware supports or an error value will be returned.
-
-	If you program a virtual y resolution higher than the hardware limit,
-	cyblafb will silently decrease that value to the highest possible
-	value. The same is true for a virtual x resolution that is not
-	supported by the hardware. Cyblafb tries to adapt vyres first because
-	vxres decides if ywrap scrolling is possible or not.
-
-	Attempts to disable acceleration are ignored, I believe that this is
-	safe.
-
-	Some video modes that should work do not work as expected. If you use
-	the standard fb.modes, fbset 640x480-60 will program that mode, but
-	you will see a vertical area, about two characters wide, with only
-	much darker characters than the other characters on the screen.
-	Cyblafb does allow that mode to be set, as it does not violate the
-	official specifications. It would need a lot of code to reliably sort
-	out all invalid modes, playing around with the margin values will
-	give a valid mode quickly. And if cyblafb would detect such an invalid
-	mode, should it silently alter the requested values or should it
-	report an error? Both options have some pros and cons. As stated
-	above, none of the startup modes are affected, and if you set
-	verbosity to 1 or higher, cyblafb will print the fbset command that
-	would be needed to program that mode using fbset.
-
-
-Other Parameters
-================
-
-
-crt		don't autodetect, assume monitor connected to
-		standard VGA connector
-
-fp		don't autodetect, assume flat panel display
-		connected to flat panel monitor interface
-
-nativex 	inform driver about native x resolution of
-		flat panel monitor connected to special
-		interface (should be autodetected)
-
-stretch 	stretch image to adapt low resolution modes to
-		higer resolutions of flat panel monitors
-		connected to special interface
-
-center		center image to adapt low resolution modes to
-		higer resolutions of flat panel monitors
-		connected to special interface
-
-memsize 	use if autodetected memsize is wrong ...
-		should never be necessary
-
-nopcirr 	disable PCI read retry
-nopciwr 	disable PCI write retry
-nopcirb 	disable PCI read bursts
-nopciwb 	disable PCI write bursts
-
-bpp		bpp for specified modes
-		valid values: 8 || 16 || 24 || 32
-
-ref		refresh rate for specified mode
-		valid values: 50 <= ref <= 85
-
-mode		640x480 or 800x600 or 1024x768 or 1280x1024
-		if not specified, the startup mode will be detected
-		and used, so you might also use the vga=??? parameter
-		described in vesafb.txt. If you do not specify a mode,
-		bpp and ref parameters are ignored.
-
-verbosity	0 is the default, increase to at least 2 for every
-		bug report!
-
-Development hints
-=================
-
-It's much faster do compile a module and to load the new version after
-unloading the old module than to compile a new kernel and to reboot. So if you
-try to work on cyblafb, it might be a good idea to use cyblafb as a module.
-In real life, fast often means dangerous, and that's also the case here. If
-you introduce a serious bug when cyblafb is compiled into the kernel, the
-kernel will lock or oops with a high probability before the file system is
-mounted, and the danger for your data is low. If you load a broken own version
-of cyblafb on a running system, the danger for the integrity of the file
-system is much higher as you might need a hard reset afterwards. Decide
-yourself.
-
-Module unloading, the vfb method
-================================
-
-If you want to unload/reload cyblafb using the virtual framebuffer, you need
-to enable vfb support in the kernel first. After that, load the modules as
-shown below:
-
-	modprobe vfb vfb_enable=1
-	modprobe fbcon
-	modprobe cyblafb
-	fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
-	con2fb /dev/fb1 /dev/tty1
-	...
-
-If you now made some changes to cyblafb and want to reload it, you might do it
-as show below:
-
-	con2fb /dev/fb0 /dev/tty1
-	...
-	rmmod cyblafb
-	modprobe cyblafb
-	con2fb /dev/fb1 /dev/tty1
-	...
-
-Of course, you might choose another mode, and most certainly you also want to
-map some other /dev/tty* to the real framebuffer device. You might also choose
-to compile fbcon as a kernel module or place it permanently in the kernel.
-
-I do not know of any way to unload fbcon, and fbcon will prevent the
-framebuffer device loaded first from unloading. [If there is a way, then
-please add a description here!]
-
-Module unloading, the vesafb method
-===================================
-
-Configure the kernel:
-
-	<*> Support for frame buffer devices
-	[*]   VESA VGA graphics support
-	<M>   Cyberblade/i1 support
-
-Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
-parameter is important, choose any vga parameter you like as long as it is
-a graphics mode.
-
-After booting, load cyblafb without any mode and bpp parameter and assign
-cyblafb to individual ttys using con2fb, e.g.:
-
-	modprobe cyblafb
-	con2fb /dev/fb1 /dev/tty1
-
-Unloading cyblafb works without problems after you assign vesafb to all
-ttys again, e.g.:
-
-	con2fb /dev/fb0 /dev/tty1
-	rmmod cyblafb
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/whatsnew linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/whatsnew
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/whatsnew	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/whatsnew	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-0.62
-====
-
-      - the vesafb parameter has been removed as I decided to allow the
-      	feature without any special parameter.
-
-      - Cyblafb does not use the vga style of panning any longer, now the
-      	"right view" register in the graphics engine IO space is used. Without
-	that change it was impossible to use all available memory, and without
-	access to all available memory it is impossible to ywrap.
-
-      - The imageblit function now uses hardware acceleration for all font
-        widths. Hardware blitting across pixel column 2048 is broken in the
-	cyberblade/i1 graphics core, but we work around that hardware bug.
-
-      - modes with vxres != xres are supported now.
-
-      - ywrap scrolling is supported now and the default. This is a big
-        performance gain.
-
-      - default video modes use vyres > yres and vxres > xres to allow
-        almost optimal scrolling speed for normal and rotated screens
-
-      - some features mainly usefull for debugging the upper layers of the
-        framebuffer system have been added, have a look at the code
-
-      - fixed: Oops after unloading cyblafb when reading /proc/io*
-
-      - we work around some bugs of the higher framebuffer layers.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/whycyblafb linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/whycyblafb
--- linux-libre-2.6.29-gnu1/Documentation/fb/cyblafb/whycyblafb	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/cyblafb/whycyblafb	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-I tried the following framebuffer drivers:
-
-	- TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
-	  graphics cores like the cyberblade/i1. It claims to support a great
-	  number of devices, but documentation for most of these devices is
-	  unfortunately not available. There is _no_ reason to use tridentfb
-	  for cyberblade/i1 + CRT users. VESAFB is faster, and the one
-	  advantage, mode switching, is broken in tridentfb.
-
-	- VESAFB is used by many distributions as a standard. Vesafb does
-	  not support mode switching. VESAFB is a bit faster than the working
-	  configurations of TRIDENTFB, but it is still too slow, even if you
-	  use ypan.
-
-	- EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
-	  graphics core, but it still has serious bugs and developement seems
-	  to have stopped. This is the one driver with TV-out support. If you
-	  do need this feature, try epiafb.
-
-None of these drivers was a real option for me.
-
-I believe that is unreasonable to change code that announces to support 20
-devices if I only have more or less sufficient documentation for exactly one
-of these. The risk of breaking device foo while fixing device bar is too high.
-
-So I decided to start CyBlaFB as a stripped down tridentfb.
-
-All code specific to other Trident chips has been removed. After that there
-were a lot of cosmetic changes to increase the readability of the code. All
-register names were changed to those mnemonics used in the datasheet. Function
-and macro names were changed if they hindered easy understanding of the code.
-
-After that I debugged the code and implemented some new features. I'll try to
-give a little summary of the main changes:
-
-	- calculation of vertical and horizontal timings was fixed
-
-	- video signal quality has been improved dramatically
-
-	- acceleration:
-
-		- fillrect and copyarea were fixed and reenabled
-
-		- color expanding imageblit was newly implemented, color
-		  imageblit (only used to draw the penguine) still uses the
-		  generic code.
-
-		- init of the acceleration engine was improved and moved to a
-		  place where it really works ...
-
-		- sync function has a timeout now and tries to reset and
-		  reinit the accel engine if necessary
-
-		- fewer slow copyarea calls when doing ypan scrolling by using
-		  undocumented bit d21 of screen start address stored in
-		  CR2B[5]. BIOS does use it also, so this should be safe.
-
-	- cyblafb rejects any attempt to set modes that would cause vclk
-	  values above reasonable 230 MHz. 32bit modes use a clock
-	  multiplicator of 2, so fbset does show the correct values for
-	  pixclock but not for vclk in this case. The fbset limit is 115 MHz
-	  for 32 bpp modes.
-
-	- cyblafb rejects modes known to be broken or unimplemented (all
-	  interlaced modes, all doublescan modes for now)
-
-	- cyblafb now works independant of the video mode in effect at startup
-	  time (tridentfb does not init all needed registers to reasonable
-	  values)
-
-	- switching between video modes does work reliably now
-
-	- the first video mode now is the one selected on startup using the
-	  vga=???? mechanism or any of
-		- 640x480, 800x600, 1024x768, 1280x1024
-		- 8, 16, 24 or 32 bpp
-		- refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
-		  is limited to 63Hz)
-
-	- pci retry and pci burst mode are settable (try to disable if you
-	  experience latency problems)
-
-	- built as a module cyblafb might be unloaded and reloaded using
-	  the vfb module and con2vt or might be used together with vesafb
-
diff -druNp linux-libre-2.6.29-gnu1/Documentation/fb/uvesafb.txt linux-libre-2.6.30-gnu1/Documentation/fb/uvesafb.txt
--- linux-libre-2.6.29-gnu1/Documentation/fb/uvesafb.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/fb/uvesafb.txt	2009-06-09 23:05:27.000000000 -0400
@@ -59,7 +59,8 @@ Accepted options:
 ypan    Enable display panning using the VESA protected mode
         interface.  The visible screen is just a window of the
         video memory, console scrolling is done by changing the
-        start of the window.  Available on x86 only.
+        start of the window.  This option is available on x86
+        only and is the default option on that architecture.
 
 ywrap   Same as ypan, but assumes your gfx board can wrap-around
         the video memory (i.e. starts reading from top if it
@@ -67,7 +68,7 @@ ywrap   Same as ypan, but assumes your g
         Available on x86 only.
 
 redraw  Scroll by redrawing the affected part of the screen, this
-        is the safe (and slow) default.
+        is the default on non-x86.
 
 (If you're using uvesafb as a module, the above three options are
  used a parameter of the scroll option, e.g. scroll=ypan.)
@@ -182,7 +183,7 @@ from the Video BIOS if you set pixclock
 
 --
  Michal Januszewski <spock@gentoo.org>
- Last updated: 2007-06-16
+ Last updated: 2009-03-30
 
  Documentation of the uvesafb options is loosely based on vesafb.txt.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/feature-removal-schedule.txt linux-libre-2.6.30-gnu1/Documentation/feature-removal-schedule.txt
--- linux-libre-2.6.29-gnu1/Documentation/feature-removal-schedule.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/feature-removal-schedule.txt	2009-06-09 23:05:27.000000000 -0400
@@ -6,20 +6,47 @@ be removed from this file.
 
 ---------------------------
 
-What:	old static regulatory information and ieee80211_regdom module parameter
-When:	2.6.29
+What:	The ieee80211_regdom module parameter
+When:	March 2010 / desktop catchup
+
+Why:	This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code,
+	and currently serves as an option for users to define an
+	ISO / IEC 3166 alpha2 code for the country they are currently
+	present in. Although there are userspace API replacements for this
+	through nl80211 distributions haven't yet caught up with implementing
+	decent alternatives through standard GUIs. Although available as an
+	option through iw or wpa_supplicant its just a matter of time before
+	distributions pick up good GUI options for this. The ideal solution
+	would actually consist of intelligent designs which would do this for
+	the user automatically even when travelling through different countries.
+	Until then we leave this module parameter as a compromise.
+
+	When userspace improves with reasonable widely-available alternatives for
+	this we will no longer need this module parameter. This entry hopes that
+	by the super-futuristically looking date of "March 2010" we will have
+	such replacements widely available.
+
+Who:	Luis R. Rodriguez <lrodriguez@atheros.com>
+
+---------------------------
+
+What:	CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information
+When:	March 2010 / desktop catchup
+
 Why:	The old regulatory infrastructure has been replaced with a new one
 	which does not require statically defined regulatory domains. We do
 	not want to keep static regulatory domains in the kernel due to the
 	the dynamic nature of regulatory law and localization. We kept around
 	the old static definitions for the regulatory domains of:
+
 		* US
 		* JP
 		* EU
+
 	and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
-	set. We also kept around the ieee80211_regdom module parameter in case
-	some applications were relying on it. Changing regulatory domains
-	can now be done instead by using nl80211, as is done with iw.
+	set. We will remove this option once the standard Linux desktop catches
+	up with the new userspace APIs we have implemented.
+
 Who:	Luis R. Rodriguez <lrodriguez@atheros.com>
 
 ---------------------------
@@ -37,10 +64,10 @@ Who:	Pavel Machek <pavel@suse.cz>
 
 ---------------------------
 
-What:	Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When:	December 2008
-Files:	include/linux/video_decoder.h include/linux/videodev.h
-Check:	include/linux/video_decoder.h include/linux/videodev.h
+What:	Video4Linux API 1 ioctls and from Video devices.
+When:	July 2009
+Files:	include/linux/videodev.h
+Check:	include/linux/videodev.h
 Why:	V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
 	series. The old API have lots of drawbacks and don't provide enough
 	means to work with all video and audio standards. The newer API is
@@ -228,8 +255,20 @@ Who:	Jan Engelhardt <jengelh@computergmb
 
 ---------------------------
 
+What:	GPIO autorequest on gpio_direction_{input,output}() in gpiolib
+When:	February 2010
+Why:	All callers should use explicit gpio_request()/gpio_free().
+	The autorequest mechanism in gpiolib was provided mostly as a
+	migration aid for legacy GPIO interfaces (for SOC based GPIOs).
+	Those users have now largely migrated.  Platforms implementing
+	the GPIO interfaces without using gpiolib will see no changes.
+Who:	David Brownell <dbrownell@users.sourceforge.net>
+---------------------------
+
 What:	b43 support for firmware revision < 410
-When:	July 2008
+When:	The schedule was July 2008, but it was decided that we are going to keep the
+        code as long as there are no major maintanance headaches.
+	So it _could_ be removed _any_ time now, if it conflicts with something new.
 Why:	The support code for the old firmware hurts code readability/maintainability
 	and slightly hurts runtime performance. Bugfixes for the old firmware
 	are not provided by Broadcom anymore.
@@ -244,13 +283,6 @@ Who:	Glauber Costa <gcosta@redhat.com>
 
 ---------------------------
 
-What:	remove HID compat support
-When:	2.6.29
-Why:	needed only as a temporary solution until distros fix themselves up
-Who:	Jiri Slaby <jirislaby@gmail.com>
-
----------------------------
-
 What: print_fn_descriptor_symbol()
 When: October 2009
 Why:  The %pF vsprintf format provides the same functionality in a
@@ -282,6 +314,18 @@ Who:	Vlad Yasevich <vladislav.yasevich@h
 
 ---------------------------
 
+What:	Ability for non root users to shm_get hugetlb pages based on mlock
+	resource limits
+When:	2.6.31
+Why:	Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or
+	have CAP_IPC_LOCK to be able to allocate shm segments backed by
+	huge pages.  The mlock based rlimit check to allow shm hugetlb is
+	inconsistent with mmap based allocations.  Hence it is being
+	deprecated.
+Who:	Ravikiran Thirumalai <kiran@scalex86.org>
+
+---------------------------
+
 What:	CONFIG_THERMAL_HWMON
 When:	January 2009
 Why:	This option was introduced just to allow older lm-sensors userspace
@@ -310,8 +354,10 @@ Who:  Krzysztof Piotr Oledzki <ole@ans.p
 
 ---------------------------
 
-What:	i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
-When:	2.6.29 (ideally) or 2.6.30 (more likely)
+What:	i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client(),
+	i2c_adapter->client_register(), i2c_adapter->client_unregister
+When:	2.6.30
+Check:	i2c_attach_client i2c_detach_client
 Why:	Deprecated by the new (standard) device driver binding model. Use
 	i2c_driver->probe() and ->remove() instead.
 Who:	Jean Delvare <khali@linux-fr.org>
@@ -326,17 +372,6 @@ Who:	Hans de Goede <hdegoede@redhat.com>
 
 ---------------------------
 
-What:	SELinux "compat_net" functionality
-When:	2.6.30 at the earliest
-Why:	In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
-	network access control functionality of SELinux.  Secmark offers both
-	better performance and greater flexibility than the "compat_net"
-	mechanism.  Now that the major Linux distributions have moved to
-	Secmark, it is time to deprecate the older mechanism and start the
-	process of removing the old code.
-Who:	Paul Moore <paul.moore@hp.com>
----------------------------
-
 What:	sysfs ui for changing p4-clockmod parameters
 When:	September 2009
 Why:	See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
@@ -344,3 +379,61 @@ Why:	See commits 129f8ae9b1b5be94517da76
 	Removal is subject to fixing any remaining bugs in ACPI which may
 	cause the thermal throttling not to happen at the right time.
 Who:	Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
+
+-----------------------------
+
+What:	__do_IRQ all in one fits nothing interrupt handler
+When:	2.6.32
+Why:	__do_IRQ was kept for easy migration to the type flow handlers.
+	More than two years of migration time is enough.
+Who:	Thomas Gleixner <tglx@linutronix.de>
+
+-----------------------------
+
+What:	obsolete generic irq defines and typedefs
+When:	2.6.30
+Why:	The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
+	have been kept around for migration reasons. After more than two years
+	it's time to remove them finally
+Who:	Thomas Gleixner <tglx@linutronix.de>
+
+---------------------------
+
+What:	fakephp and associated sysfs files in /sys/bus/pci/slots/
+When:	2011
+Why:	In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
+	represent a machine's physical PCI slots. The change in semantics
+	had userspace implications, as the hotplug core no longer allowed
+	drivers to create multiple sysfs files per physical slot (required
+	for multi-function devices, e.g.). fakephp was seen as a developer's
+	tool only, and its interface changed. Too late, we learned that
+	there were some users of the fakephp interface.
+
+	In 2.6.30, the original fakephp interface was restored. At the same
+	time, the PCI core gained the ability that fakephp provided, namely
+	function-level hot-remove and hot-add.
+
+	Since the PCI core now provides the same functionality, exposed in:
+
+		/sys/bus/pci/rescan
+		/sys/bus/pci/devices/.../remove
+		/sys/bus/pci/devices/.../rescan
+
+	there is no functional reason to maintain fakephp as well.
+
+	We will keep the existing module so that 'modprobe fakephp' will
+	present the old /sys/bus/pci/slots/... interface for compatibility,
+	but users are urged to migrate their applications to the API above.
+
+	After a reasonable transition period, we will remove the legacy
+	fakephp interface.
+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>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/00-INDEX linux-libre-2.6.30-gnu1/Documentation/filesystems/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -68,6 +68,8 @@ ncpfs.txt
 	- info on Novell Netware(tm) filesystem using NCP protocol.
 nfsroot.txt
 	- short guide on setting up a diskless box with NFS root filesystem.
+nilfs2.txt
+	- info and mount options for the NILFS2 filesystem.
 ntfs.txt
 	- info and mount options for the NTFS filesystem (Windows NT).
 ocfs2.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/backend-api.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/backend-api.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/backend-api.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/backend-api.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,658 @@
+			  ==========================
+			  FS-CACHE CACHE BACKEND API
+			  ==========================
+
+The FS-Cache system provides an API by which actual caches can be supplied to
+FS-Cache for it to then serve out to network filesystems and other interested
+parties.
+
+This API is declared in <linux/fscache-cache.h>.
+
+
+====================================
+INITIALISING AND REGISTERING A CACHE
+====================================
+
+To start off, a cache definition must be initialised and registered for each
+cache the backend wants to make available.  For instance, CacheFS does this in
+the fill_super() operation on mounting.
+
+The cache definition (struct fscache_cache) should be initialised by calling:
+
+	void fscache_init_cache(struct fscache_cache *cache,
+				struct fscache_cache_ops *ops,
+				const char *idfmt,
+				...);
+
+Where:
+
+ (*) "cache" is a pointer to the cache definition;
+
+ (*) "ops" is a pointer to the table of operations that the backend supports on
+     this cache; and
+
+ (*) "idfmt" is a format and printf-style arguments for constructing a label
+     for the cache.
+
+
+The cache should then be registered with FS-Cache by passing a pointer to the
+previously initialised cache definition to:
+
+	int fscache_add_cache(struct fscache_cache *cache,
+			      struct fscache_object *fsdef,
+			      const char *tagname);
+
+Two extra arguments should also be supplied:
+
+ (*) "fsdef" which should point to the object representation for the FS-Cache
+     master index in this cache.  Netfs primary index entries will be created
+     here.  FS-Cache keeps the caller's reference to the index object if
+     successful and will release it upon withdrawal of the cache.
+
+ (*) "tagname" which, if given, should be a text string naming this cache.  If
+     this is NULL, the identifier will be used instead.  For CacheFS, the
+     identifier is set to name the underlying block device and the tag can be
+     supplied by mount.
+
+This function may return -ENOMEM if it ran out of memory or -EEXIST if the tag
+is already in use.  0 will be returned on success.
+
+
+=====================
+UNREGISTERING A CACHE
+=====================
+
+A cache can be withdrawn from the system by calling this function with a
+pointer to the cache definition:
+
+	void fscache_withdraw_cache(struct fscache_cache *cache);
+
+In CacheFS's case, this is called by put_super().
+
+
+========
+SECURITY
+========
+
+The cache methods are executed one of two contexts:
+
+ (1) that of the userspace process that issued the netfs operation that caused
+     the cache method to be invoked, or
+
+ (2) that of one of the processes in the FS-Cache thread pool.
+
+In either case, this may not be an appropriate context in which to access the
+cache.
+
+The calling process's fsuid, fsgid and SELinux security identities may need to
+be masqueraded for the duration of the cache driver's access to the cache.
+This is left to the cache to handle; FS-Cache makes no effort in this regard.
+
+
+===================================
+CONTROL AND STATISTICS PRESENTATION
+===================================
+
+The cache may present data to the outside world through FS-Cache's interfaces
+in sysfs and procfs - the former for control and the latter for statistics.
+
+A sysfs directory called /sys/fs/fscache/<cachetag>/ is created if CONFIG_SYSFS
+is enabled.  This is accessible through the kobject struct fscache_cache::kobj
+and is for use by the cache as it sees fit.
+
+
+========================
+RELEVANT DATA STRUCTURES
+========================
+
+ (*) Index/Data file FS-Cache representation cookie:
+
+	struct fscache_cookie {
+		struct fscache_object_def	*def;
+		struct fscache_netfs		*netfs;
+		void				*netfs_data;
+		...
+	};
+
+     The fields that might be of use to the backend describe the object
+     definition, the netfs definition and the netfs's data for this cookie.
+     The object definition contain functions supplied by the netfs for loading
+     and matching index entries; these are required to provide some of the
+     cache operations.
+
+
+ (*) In-cache object representation:
+
+	struct fscache_object {
+		int				debug_id;
+		enum {
+			FSCACHE_OBJECT_RECYCLING,
+			...
+		}				state;
+		spinlock_t			lock
+		struct fscache_cache		*cache;
+		struct fscache_cookie		*cookie;
+		...
+	};
+
+     Structures of this type should be allocated by the cache backend and
+     passed to FS-Cache when requested by the appropriate cache operation.  In
+     the case of CacheFS, they're embedded in CacheFS's internal object
+     structures.
+
+     The debug_id is a simple integer that can be used in debugging messages
+     that refer to a particular object.  In such a case it should be printed
+     using "OBJ%x" to be consistent with FS-Cache.
+
+     Each object contains a pointer to the cookie that represents the object it
+     is backing.  An object should retired when put_object() is called if it is
+     in state FSCACHE_OBJECT_RECYCLING.  The fscache_object struct should be
+     initialised by calling fscache_object_init(object).
+
+
+ (*) FS-Cache operation record:
+
+	struct fscache_operation {
+		atomic_t		usage;
+		struct fscache_object	*object;
+		unsigned long		flags;
+	#define FSCACHE_OP_EXCLUSIVE
+		void (*processor)(struct fscache_operation *op);
+		void (*release)(struct fscache_operation *op);
+		...
+	};
+
+     FS-Cache has a pool of threads that it uses to give CPU time to the
+     various asynchronous operations that need to be done as part of driving
+     the cache.  These are represented by the above structure.  The processor
+     method is called to give the op CPU time, and the release method to get
+     rid of it when its usage count reaches 0.
+
+     An operation can be made exclusive upon an object by setting the
+     appropriate flag before enqueuing it with fscache_enqueue_operation().  If
+     an operation needs more processing time, it should be enqueued again.
+
+
+ (*) FS-Cache retrieval operation record:
+
+	struct fscache_retrieval {
+		struct fscache_operation op;
+		struct address_space	*mapping;
+		struct list_head	*to_do;
+		...
+	};
+
+     A structure of this type is allocated by FS-Cache to record retrieval and
+     allocation requests made by the netfs.  This struct is then passed to the
+     backend to do the operation.  The backend may get extra refs to it by
+     calling fscache_get_retrieval() and refs may be discarded by calling
+     fscache_put_retrieval().
+
+     A retrieval operation can be used by the backend to do retrieval work.  To
+     do this, the retrieval->op.processor method pointer should be set
+     appropriately by the backend and fscache_enqueue_retrieval() called to
+     submit it to the thread pool.  CacheFiles, for example, uses this to queue
+     page examination when it detects PG_lock being cleared.
+
+     The to_do field is an empty list available for the cache backend to use as
+     it sees fit.
+
+
+ (*) FS-Cache storage operation record:
+
+	struct fscache_storage {
+		struct fscache_operation op;
+		pgoff_t			store_limit;
+		...
+	};
+
+     A structure of this type is allocated by FS-Cache to record outstanding
+     writes to be made.  FS-Cache itself enqueues this operation and invokes
+     the write_page() method on the object at appropriate times to effect
+     storage.
+
+
+================
+CACHE OPERATIONS
+================
+
+The cache backend provides FS-Cache with a table of operations that can be
+performed on the denizens of the cache.  These are held in a structure of type:
+
+	struct fscache_cache_ops
+
+ (*) Name of cache provider [mandatory]:
+
+	const char *name
+
+     This isn't strictly an operation, but should be pointed at a string naming
+     the backend.
+
+
+ (*) Allocate a new object [mandatory]:
+
+	struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+					       struct fscache_cookie *cookie)
+
+     This method is used to allocate a cache object representation to back a
+     cookie in a particular cache.  fscache_object_init() should be called on
+     the object to initialise it prior to returning.
+
+     This function may also be used to parse the index key to be used for
+     multiple lookup calls to turn it into a more convenient form.  FS-Cache
+     will call the lookup_complete() method to allow the cache to release the
+     form once lookup is complete or aborted.
+
+
+ (*) Look up and create object [mandatory]:
+
+	void (*lookup_object)(struct fscache_object *object)
+
+     This method is used to look up an object, given that the object is already
+     allocated and attached to the cookie.  This should instantiate that object
+     in the cache if it can.
+
+     The method should call fscache_object_lookup_negative() as soon as
+     possible if it determines the object doesn't exist in the cache.  If the
+     object is found to exist and the netfs indicates that it is valid then
+     fscache_obtained_object() should be called once the object is in a
+     position to have data stored in it.  Similarly, fscache_obtained_object()
+     should also be called once a non-present object has been created.
+
+     If a lookup error occurs, fscache_object_lookup_error() should be called
+     to abort the lookup of that object.
+
+
+ (*) Release lookup data [mandatory]:
+
+	void (*lookup_complete)(struct fscache_object *object)
+
+     This method is called to ask the cache to release any resources it was
+     using to perform a lookup.
+
+
+ (*) Increment object refcount [mandatory]:
+
+	struct fscache_object *(*grab_object)(struct fscache_object *object)
+
+     This method is called to increment the reference count on an object.  It
+     may fail (for instance if the cache is being withdrawn) by returning NULL.
+     It should return the object pointer if successful.
+
+
+ (*) Lock/Unlock object [mandatory]:
+
+	void (*lock_object)(struct fscache_object *object)
+	void (*unlock_object)(struct fscache_object *object)
+
+     These methods are used to exclusively lock an object.  It must be possible
+     to schedule with the lock held, so a spinlock isn't sufficient.
+
+
+ (*) Pin/Unpin object [optional]:
+
+	int (*pin_object)(struct fscache_object *object)
+	void (*unpin_object)(struct fscache_object *object)
+
+     These methods are used to pin an object into the cache.  Once pinned an
+     object cannot be reclaimed to make space.  Return -ENOSPC if there's not
+     enough space in the cache to permit this.
+
+
+ (*) Update object [mandatory]:
+
+	int (*update_object)(struct fscache_object *object)
+
+     This is called to update the index entry for the specified object.  The
+     new information should be in object->cookie->netfs_data.  This can be
+     obtained by calling object->cookie->def->get_aux()/get_attr().
+
+
+ (*) Discard object [mandatory]:
+
+	void (*drop_object)(struct fscache_object *object)
+
+     This method is called to indicate that an object has been unbound from its
+     cookie, and that the cache should release the object's resources and
+     retire it if it's in state FSCACHE_OBJECT_RECYCLING.
+
+     This method should not attempt to release any references held by the
+     caller.  The caller will invoke the put_object() method as appropriate.
+
+
+ (*) Release object reference [mandatory]:
+
+	void (*put_object)(struct fscache_object *object)
+
+     This method is used to discard a reference to an object.  The object may
+     be freed when all the references to it are released.
+
+
+ (*) Synchronise a cache [mandatory]:
+
+	void (*sync)(struct fscache_cache *cache)
+
+     This is called to ask the backend to synchronise a cache with its backing
+     device.
+
+
+ (*) Dissociate a cache [mandatory]:
+
+	void (*dissociate_pages)(struct fscache_cache *cache)
+
+     This is called to ask a cache to perform any page dissociations as part of
+     cache withdrawal.
+
+
+ (*) Notification that the attributes on a netfs file changed [mandatory]:
+
+	int (*attr_changed)(struct fscache_object *object);
+
+     This is called to indicate to the cache that certain attributes on a netfs
+     file have changed (for example the maximum size a file may reach).  The
+     cache can read these from the netfs by calling the cookie's get_attr()
+     method.
+
+     The cache may use the file size information to reserve space on the cache.
+     It should also call fscache_set_store_limit() to indicate to FS-Cache the
+     highest byte it's willing to store for an object.
+
+     This method may return -ve if an error occurred or the cache object cannot
+     be expanded.  In such a case, the object will be withdrawn from service.
+
+     This operation is run asynchronously from FS-Cache's thread pool, and
+     storage and retrieval operations from the netfs are excluded during the
+     execution of this operation.
+
+
+ (*) Reserve cache space for an object's data [optional]:
+
+	int (*reserve_space)(struct fscache_object *object, loff_t size);
+
+     This is called to request that cache space be reserved to hold the data
+     for an object and the metadata used to track it.  Zero size should be
+     taken as request to cancel a reservation.
+
+     This should return 0 if successful, -ENOSPC if there isn't enough space
+     available, or -ENOMEM or -EIO on other errors.
+
+     The reservation may exceed the current size of the object, thus permitting
+     future expansion.  If the amount of space consumed by an object would
+     exceed the reservation, it's permitted to refuse requests to allocate
+     pages, but not required.  An object may be pruned down to its reservation
+     size if larger than that already.
+
+
+ (*) Request page be read from cache [mandatory]:
+
+	int (*read_or_alloc_page)(struct fscache_retrieval *op,
+				  struct page *page,
+				  gfp_t gfp)
+
+     This is called to attempt to read a netfs page from the cache, or to
+     reserve a backing block if not.  FS-Cache will have done as much checking
+     as it can before calling, but most of the work belongs to the backend.
+
+     If there's no page in the cache, then -ENODATA should be returned if the
+     backend managed to reserve a backing block; -ENOBUFS or -ENOMEM if it
+     didn't.
+
+     If there is suitable data in the cache, then a read operation should be
+     queued and 0 returned.  When the read finishes, fscache_end_io() should be
+     called.
+
+     The fscache_mark_pages_cached() should be called for the page if any cache
+     metadata is retained.  This will indicate to the netfs that the page needs
+     explicit uncaching.  This operation takes a pagevec, thus allowing several
+     pages to be marked at once.
+
+     The retrieval record pointed to by op should be retained for each page
+     queued and released when I/O on the page has been formally ended.
+     fscache_get/put_retrieval() are available for this purpose.
+
+     The retrieval record may be used to get CPU time via the FS-Cache thread
+     pool.  If this is desired, the op->op.processor should be set to point to
+     the appropriate processing routine, and fscache_enqueue_retrieval() should
+     be called at an appropriate point to request CPU time.  For instance, the
+     retrieval routine could be enqueued upon the completion of a disk read.
+     The to_do field in the retrieval record is provided to aid in this.
+
+     If an I/O error occurs, fscache_io_error() should be called and -ENOBUFS
+     returned if possible or fscache_end_io() called with a suitable error
+     code..
+
+
+ (*) Request pages be read from cache [mandatory]:
+
+	int (*read_or_alloc_pages)(struct fscache_retrieval *op,
+				   struct list_head *pages,
+				   unsigned *nr_pages,
+				   gfp_t gfp)
+
+     This is like the read_or_alloc_page() method, except it is handed a list
+     of pages instead of one page.  Any pages on which a read operation is
+     started must be added to the page cache for the specified mapping and also
+     to the LRU.  Such pages must also be removed from the pages list and
+     *nr_pages decremented per page.
+
+     If there was an error such as -ENOMEM, then that should be returned; else
+     if one or more pages couldn't be read or allocated, then -ENOBUFS should
+     be returned; else if one or more pages couldn't be read, then -ENODATA
+     should be returned.  If all the pages are dispatched then 0 should be
+     returned.
+
+
+ (*) Request page be allocated in the cache [mandatory]:
+
+	int (*allocate_page)(struct fscache_retrieval *op,
+			     struct page *page,
+			     gfp_t gfp)
+
+     This is like the read_or_alloc_page() method, except that it shouldn't
+     read from the cache, even if there's data there that could be retrieved.
+     It should, however, set up any internal metadata required such that
+     the write_page() method can write to the cache.
+
+     If there's no backing block available, then -ENOBUFS should be returned
+     (or -ENOMEM if there were other problems).  If a block is successfully
+     allocated, then the netfs page should be marked and 0 returned.
+
+
+ (*) Request pages be allocated in the cache [mandatory]:
+
+	int (*allocate_pages)(struct fscache_retrieval *op,
+			      struct list_head *pages,
+			      unsigned *nr_pages,
+			      gfp_t gfp)
+
+     This is an multiple page version of the allocate_page() method.  pages and
+     nr_pages should be treated as for the read_or_alloc_pages() method.
+
+
+ (*) Request page be written to cache [mandatory]:
+
+	int (*write_page)(struct fscache_storage *op,
+			  struct page *page);
+
+     This is called to write from a page on which there was a previously
+     successful read_or_alloc_page() call or similar.  FS-Cache filters out
+     pages that don't have mappings.
+
+     This method is called asynchronously from the FS-Cache thread pool.  It is
+     not required to actually store anything, provided -ENODATA is then
+     returned to the next read of this page.
+
+     If an error occurred, then a negative error code should be returned,
+     otherwise zero should be returned.  FS-Cache will take appropriate action
+     in response to an error, such as withdrawing this object.
+
+     If this method returns success then FS-Cache will inform the netfs
+     appropriately.
+
+
+ (*) Discard retained per-page metadata [mandatory]:
+
+	void (*uncache_page)(struct fscache_object *object, struct page *page)
+
+     This is called when a netfs page is being evicted from the pagecache.  The
+     cache backend should tear down any internal representation or tracking it
+     maintains for this page.
+
+
+==================
+FS-CACHE UTILITIES
+==================
+
+FS-Cache provides some utilities that a cache backend may make use of:
+
+ (*) Note occurrence of an I/O error in a cache:
+
+	void fscache_io_error(struct fscache_cache *cache)
+
+     This tells FS-Cache that an I/O error occurred in the cache.  After this
+     has been called, only resource dissociation operations (object and page
+     release) will be passed from the netfs to the cache backend for the
+     specified cache.
+
+     This does not actually withdraw the cache.  That must be done separately.
+
+
+ (*) Invoke the retrieval I/O completion function:
+
+	void fscache_end_io(struct fscache_retrieval *op, struct page *page,
+			    int error);
+
+     This is called to note the end of an attempt to retrieve a page.  The
+     error value should be 0 if successful and an error otherwise.
+
+
+ (*) Set highest store limit:
+
+	void fscache_set_store_limit(struct fscache_object *object,
+				     loff_t i_size);
+
+     This sets the limit FS-Cache imposes on the highest byte it's willing to
+     try and store for a netfs.  Any page over this limit is automatically
+     rejected by fscache_read_alloc_page() and co with -ENOBUFS.
+
+
+ (*) Mark pages as being cached:
+
+	void fscache_mark_pages_cached(struct fscache_retrieval *op,
+				       struct pagevec *pagevec);
+
+     This marks a set of pages as being cached.  After this has been called,
+     the netfs must call fscache_uncache_page() to unmark the pages.
+
+
+ (*) Perform coherency check on an object:
+
+	enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+						const void *data,
+						uint16_t datalen);
+
+     This asks the netfs to perform a coherency check on an object that has
+     just been looked up.  The cookie attached to the object will determine the
+     netfs to use.  data and datalen should specify where the auxiliary data
+     retrieved from the cache can be found.
+
+     One of three values will be returned:
+
+	(*) FSCACHE_CHECKAUX_OKAY
+
+	    The coherency data indicates the object is valid as is.
+
+	(*) FSCACHE_CHECKAUX_NEEDS_UPDATE
+
+	    The coherency data needs updating, but otherwise the object is
+	    valid.
+
+	(*) FSCACHE_CHECKAUX_OBSOLETE
+
+	    The coherency data indicates that the object is obsolete and should
+	    be discarded.
+
+
+ (*) Initialise a freshly allocated object:
+
+	void fscache_object_init(struct fscache_object *object);
+
+     This initialises all the fields in an object representation.
+
+
+ (*) Indicate the destruction of an object:
+
+	void fscache_object_destroyed(struct fscache_cache *cache);
+
+     This must be called to inform FS-Cache that an object that belonged to a
+     cache has been destroyed and deallocated.  This will allow continuation
+     of the cache withdrawal process when it is stopped pending destruction of
+     all the objects.
+
+
+ (*) Indicate negative lookup on an object:
+
+	void fscache_object_lookup_negative(struct fscache_object *object);
+
+     This is called to indicate to FS-Cache that a lookup process for an object
+     found a negative result.
+
+     This changes the state of an object to permit reads pending on lookup
+     completion to go off and start fetching data from the netfs server as it's
+     known at this point that there can't be any data in the cache.
+
+     This may be called multiple times on an object.  Only the first call is
+     significant - all subsequent calls are ignored.
+
+
+ (*) Indicate an object has been obtained:
+
+	void fscache_obtained_object(struct fscache_object *object);
+
+     This is called to indicate to FS-Cache that a lookup process for an object
+     produced a positive result, or that an object was created.  This should
+     only be called once for any particular object.
+
+     This changes the state of an object to indicate:
+
+	(1) if no call to fscache_object_lookup_negative() has been made on
+	    this object, that there may be data available, and that reads can
+	    now go and look for it; and
+
+        (2) that writes may now proceed against this object.
+
+
+ (*) Indicate that object lookup failed:
+
+	void fscache_object_lookup_error(struct fscache_object *object);
+
+     This marks an object as having encountered a fatal error (usually EIO)
+     and causes it to move into a state whereby it will be withdrawn as soon
+     as possible.
+
+
+ (*) Get and release references on a retrieval record:
+
+	void fscache_get_retrieval(struct fscache_retrieval *op);
+	void fscache_put_retrieval(struct fscache_retrieval *op);
+
+     These two functions are used to retain a retrieval record whilst doing
+     asynchronous data retrieval and block allocation.
+
+
+ (*) Enqueue a retrieval record for processing.
+
+	void fscache_enqueue_retrieval(struct fscache_retrieval *op);
+
+     This enqueues a retrieval record for processing by the FS-Cache thread
+     pool.  One of the threads in the pool will invoke the retrieval record's
+     op->op.processor callback function.  This function may be called from
+     within the callback function.
+
+
+ (*) List of object state names:
+
+	const char *fscache_object_states[];
+
+     For debugging purposes, this may be used to turn the state that an object
+     is in into a text string for display purposes.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/cachefiles.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/cachefiles.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/cachefiles.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/cachefiles.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,501 @@
+	       ===============================================
+	       CacheFiles: CACHE ON ALREADY MOUNTED FILESYSTEM
+	       ===============================================
+
+Contents:
+
+ (*) Overview.
+
+ (*) Requirements.
+
+ (*) Configuration.
+
+ (*) Starting the cache.
+
+ (*) Things to avoid.
+
+ (*) Cache culling.
+
+ (*) Cache structure.
+
+ (*) Security model and SELinux.
+
+ (*) A note on security.
+
+ (*) Statistical information.
+
+ (*) Debugging.
+
+
+========
+OVERVIEW
+========
+
+CacheFiles is a caching backend that's meant to use as a cache a directory on
+an already mounted filesystem of a local type (such as Ext3).
+
+CacheFiles uses a userspace daemon to do some of the cache management - such as
+reaping stale nodes and culling.  This is called cachefilesd and lives in
+/sbin.
+
+The filesystem and data integrity of the cache are only as good as those of the
+filesystem providing the backing services.  Note that CacheFiles does not
+attempt to journal anything since the journalling interfaces of the various
+filesystems are very specific in nature.
+
+CacheFiles creates a misc character device - "/dev/cachefiles" - that is used
+to communication with the daemon.  Only one thing may have this open at once,
+and whilst it is open, a cache is at least partially in existence.  The daemon
+opens this and sends commands down it to control the cache.
+
+CacheFiles is currently limited to a single cache.
+
+CacheFiles attempts to maintain at least a certain percentage of free space on
+the filesystem, shrinking the cache by culling the objects it contains to make
+space if necessary - see the "Cache Culling" section.  This means it can be
+placed on the same medium as a live set of data, and will expand to make use of
+spare space and automatically contract when the set of data requires more
+space.
+
+
+============
+REQUIREMENTS
+============
+
+The use of CacheFiles and its daemon requires the following features to be
+available in the system and in the cache filesystem:
+
+	- dnotify.
+
+	- extended attributes (xattrs).
+
+	- openat() and friends.
+
+	- bmap() support on files in the filesystem (FIBMAP ioctl).
+
+	- The use of bmap() to detect a partial page at the end of the file.
+
+It is strongly recommended that the "dir_index" option is enabled on Ext3
+filesystems being used as a cache.
+
+
+=============
+CONFIGURATION
+=============
+
+The cache is configured by a script in /etc/cachefilesd.conf.  These commands
+set up cache ready for use.  The following script commands are available:
+
+ (*) brun <N>%
+ (*) bcull <N>%
+ (*) bstop <N>%
+ (*) frun <N>%
+ (*) fcull <N>%
+ (*) fstop <N>%
+
+	Configure the culling limits.  Optional.  See the section on culling
+	The defaults are 7% (run), 5% (cull) and 1% (stop) respectively.
+
+	The commands beginning with a 'b' are file space (block) limits, those
+	beginning with an 'f' are file count limits.
+
+ (*) dir <path>
+
+	Specify the directory containing the root of the cache.  Mandatory.
+
+ (*) tag <name>
+
+	Specify a tag to FS-Cache to use in distinguishing multiple caches.
+	Optional.  The default is "CacheFiles".
+
+ (*) debug <mask>
+
+	Specify a numeric bitmask to control debugging in the kernel module.
+	Optional.  The default is zero (all off).  The following values can be
+	OR'd into the mask to collect various information:
+
+		1	Turn on trace of function entry (_enter() macros)
+		2	Turn on trace of function exit (_leave() macros)
+		4	Turn on trace of internal debug points (_debug())
+
+	This mask can also be set through sysfs, eg:
+
+		echo 5 >/sys/modules/cachefiles/parameters/debug
+
+
+==================
+STARTING THE CACHE
+==================
+
+The cache is started by running the daemon.  The daemon opens the cache device,
+configures the cache and tells it to begin caching.  At that point the cache
+binds to fscache and the cache becomes live.
+
+The daemon is run as follows:
+
+	/sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>]
+
+The flags are:
+
+ (*) -d
+
+	Increase the debugging level.  This can be specified multiple times and
+	is cumulative with itself.
+
+ (*) -s
+
+	Send messages to stderr instead of syslog.
+
+ (*) -n
+
+	Don't daemonise and go into background.
+
+ (*) -f <configfile>
+
+	Use an alternative configuration file rather than the default one.
+
+
+===============
+THINGS TO AVOID
+===============
+
+Do not mount other things within the cache as this will cause problems.  The
+kernel module contains its own very cut-down path walking facility that ignores
+mountpoints, but the daemon can't avoid them.
+
+Do not create, rename or unlink files and directories in the cache whilst the
+cache is active, as this may cause the state to become uncertain.
+
+Renaming files in the cache might make objects appear to be other objects (the
+filename is part of the lookup key).
+
+Do not change or remove the extended attributes attached to cache files by the
+cache as this will cause the cache state management to get confused.
+
+Do not create files or directories in the cache, lest the cache get confused or
+serve incorrect data.
+
+Do not chmod files in the cache.  The module creates things with minimal
+permissions to prevent random users being able to access them directly.
+
+
+=============
+CACHE CULLING
+=============
+
+The cache may need culling occasionally to make space.  This involves
+discarding objects from the cache that have been used less recently than
+anything else.  Culling is based on the access time of data objects.  Empty
+directories are culled if not in use.
+
+Cache culling is done on the basis of the percentage of blocks and the
+percentage of files available in the underlying filesystem.  There are six
+"limits":
+
+ (*) brun
+ (*) frun
+
+     If the amount of free space and the number of available files in the cache
+     rises above both these limits, then culling is turned off.
+
+ (*) bcull
+ (*) fcull
+
+     If the amount of available space or the number of available files in the
+     cache falls below either of these limits, then culling is started.
+
+ (*) bstop
+ (*) fstop
+
+     If the amount of available space or the number of available files in the
+     cache falls below either of these limits, then no further allocation of
+     disk space or files is permitted until culling has raised things above
+     these limits again.
+
+These must be configured thusly:
+
+	0 <= bstop < bcull < brun < 100
+	0 <= fstop < fcull < frun < 100
+
+Note that these are percentages of available space and available files, and do
+_not_ appear as 100 minus the percentage displayed by the "df" program.
+
+The userspace daemon scans the cache to build up a table of cullable objects.
+These are then culled in least recently used order.  A new scan of the cache is
+started as soon as space is made in the table.  Objects will be skipped if
+their atimes have changed or if the kernel module says it is still using them.
+
+
+===============
+CACHE STRUCTURE
+===============
+
+The CacheFiles module will create two directories in the directory it was
+given:
+
+ (*) cache/
+
+ (*) graveyard/
+
+The active cache objects all reside in the first directory.  The CacheFiles
+kernel module moves any retired or culled objects that it can't simply unlink
+to the graveyard from which the daemon will actually delete them.
+
+The daemon uses dnotify to monitor the graveyard directory, and will delete
+anything that appears therein.
+
+
+The module represents index objects as directories with the filename "I..." or
+"J...".  Note that the "cache/" directory is itself a special index.
+
+Data objects are represented as files if they have no children, or directories
+if they do.  Their filenames all begin "D..." or "E...".  If represented as a
+directory, data objects will have a file in the directory called "data" that
+actually holds the data.
+
+Special objects are similar to data objects, except their filenames begin
+"S..." or "T...".
+
+
+If an object has children, then it will be represented as a directory.
+Immediately in the representative directory are a collection of directories
+named for hash values of the child object keys with an '@' prepended.  Into
+this directory, if possible, will be placed the representations of the child
+objects:
+
+	INDEX     INDEX      INDEX                             DATA FILES
+	========= ========== ================================= ================
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry
+
+
+If the key is so long that it exceeds NAME_MAX with the decorations added on to
+it, then it will be cut into pieces, the first few of which will be used to
+make a nest of directories, and the last one of which will be the objects
+inside the last directory.  The names of the intermediate directories will have
+'+' prepended:
+
+	J1223/@23/+xy...z/+kl...m/Epqr
+
+
+Note that keys are raw data, and not only may they exceed NAME_MAX in size,
+they may also contain things like '/' and NUL characters, and so they may not
+be suitable for turning directly into a filename.
+
+To handle this, CacheFiles will use a suitably printable filename directly and
+"base-64" encode ones that aren't directly suitable.  The two versions of
+object filenames indicate the encoding:
+
+	OBJECT TYPE	PRINTABLE	ENCODED
+	===============	===============	===============
+	Index		"I..."		"J..."
+	Data		"D..."		"E..."
+	Special		"S..."		"T..."
+
+Intermediate directories are always "@" or "+" as appropriate.
+
+
+Each object in the cache has an extended attribute label that holds the object
+type ID (required to distinguish special objects) and the auxiliary data from
+the netfs.  The latter is used to detect stale objects in the cache and update
+or retire them.
+
+
+Note that CacheFiles will erase from the cache any file it doesn't recognise or
+any file of an incorrect type (such as a FIFO file or a device file).
+
+
+==========================
+SECURITY MODEL AND SELINUX
+==========================
+
+CacheFiles is implemented to deal properly with the LSM security features of
+the Linux kernel and the SELinux facility.
+
+One of the problems that CacheFiles faces is that it is generally acting on
+behalf of a process, and running in that process's context, and that includes a
+security context that is not appropriate for accessing the cache - either
+because the files in the cache are inaccessible to that process, or because if
+the process creates a file in the cache, that file may be inaccessible to other
+processes.
+
+The way CacheFiles works is to temporarily change the security context (fsuid,
+fsgid and actor security label) that the process acts as - without changing the
+security context of the process when it the target of an operation performed by
+some other process (so signalling and suchlike still work correctly).
+
+
+When the CacheFiles module is asked to bind to its cache, it:
+
+ (1) Finds the security label attached to the root cache directory and uses
+     that as the security label with which it will create files.  By default,
+     this is:
+
+	cachefiles_var_t
+
+ (2) Finds the security label of the process which issued the bind request
+     (presumed to be the cachefilesd daemon), which by default will be:
+
+	cachefilesd_t
+
+     and asks LSM to supply a security ID as which it should act given the
+     daemon's label.  By default, this will be:
+
+	cachefiles_kernel_t
+
+     SELinux transitions the daemon's security ID to the module's security ID
+     based on a rule of this form in the policy.
+
+	type_transition <daemon's-ID> kernel_t : process <module's-ID>;
+
+     For instance:
+
+	type_transition cachefilesd_t kernel_t : process cachefiles_kernel_t;
+
+
+The module's security ID gives it permission to create, move and remove files
+and directories in the cache, to find and access directories and files in the
+cache, to set and access extended attributes on cache objects, and to read and
+write files in the cache.
+
+The daemon's security ID gives it only a very restricted set of permissions: it
+may scan directories, stat files and erase files and directories.  It may
+not read or write files in the cache, and so it is precluded from accessing the
+data cached therein; nor is it permitted to create new files in the cache.
+
+
+There are policy source files available in:
+
+	http://people.redhat.com/~dhowells/fscache/cachefilesd-0.8.tar.bz2
+
+and later versions.  In that tarball, see the files:
+
+	cachefilesd.te
+	cachefilesd.fc
+	cachefilesd.if
+
+They are built and installed directly by the RPM.
+
+If a non-RPM based system is being used, then copy the above files to their own
+directory and run:
+
+	make -f /usr/share/selinux/devel/Makefile
+	semodule -i cachefilesd.pp
+
+You will need checkpolicy and selinux-policy-devel installed prior to the
+build.
+
+
+By default, the cache is located in /var/fscache, but if it is desirable that
+it should be elsewhere, than either the above policy files must be altered, or
+an auxiliary policy must be installed to label the alternate location of the
+cache.
+
+For instructions on how to add an auxiliary policy to enable the cache to be
+located elsewhere when SELinux is in enforcing mode, please see:
+
+	/usr/share/doc/cachefilesd-*/move-cache.txt
+
+When the cachefilesd rpm is installed; alternatively, the document can be found
+in the sources.
+
+
+==================
+A NOTE ON SECURITY
+==================
+
+CacheFiles makes use of the split security in the task_struct.  It allocates
+its own task_security structure, and redirects current->cred to point to it
+when it acts on behalf of another process, in that process's context.
+
+The reason it does this is that it calls vfs_mkdir() and suchlike rather than
+bypassing security and calling inode ops directly.  Therefore the VFS and LSM
+may deny the CacheFiles access to the cache data because under some
+circumstances the caching code is running in the security context of whatever
+process issued the original syscall on the netfs.
+
+Furthermore, should CacheFiles create a file or directory, the security
+parameters with that object is created (UID, GID, security label) would be
+derived from that process that issued the system call, thus potentially
+preventing other processes from accessing the cache - including CacheFiles's
+cache management daemon (cachefilesd).
+
+What is required is to temporarily override the security of the process that
+issued the system call.  We can't, however, just do an in-place change of the
+security data as that affects the process as an object, not just as a subject.
+This means it may lose signals or ptrace events for example, and affects what
+the process looks like in /proc.
+
+So CacheFiles makes use of a logical split in the security between the
+objective security (task->real_cred) and the subjective security (task->cred).
+The objective security holds the intrinsic security properties of a process and
+is never overridden.  This is what appears in /proc, and is what is used when a
+process is the target of an operation by some other process (SIGKILL for
+example).
+
+The subjective security holds the active security properties of a process, and
+may be overridden.  This is not seen externally, and is used whan a process
+acts upon another object, for example SIGKILLing another process or opening a
+file.
+
+LSM hooks exist that allow SELinux (or Smack or whatever) to reject a request
+for CacheFiles to run in a context of a specific security label, or to create
+files and directories with another security label.
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following option enabled:
+
+	CONFIG_CACHEFILES_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a proc file.
+
+ (*) /proc/fs/cachefiles/histogram
+
+	cat /proc/fs/cachefiles/histogram
+	JIFS  SECS  LOOKUPS   MKDIRS    CREATES
+	===== ===== ========= ========= =========
+
+     This shows the breakdown of the number of times each amount of time
+     between 0 jiffies and HZ-1 jiffies a variety of tasks took to run.  The
+     columns are as follows:
+
+	COLUMN		TIME MEASUREMENT
+	=======		=======================================================
+	LOOKUPS		Length of time to perform a lookup on the backing fs
+	MKDIRS		Length of time to perform a mkdir on the backing fs
+	CREATES		Length of time to perform a create on the backing fs
+
+     Each row shows the number of events that took a particular range of times.
+     Each step is 1 jiffy in size.  The JIFS column indicates the particular
+     jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_CACHEFILES_DEBUG is enabled, the CacheFiles facility can have runtime
+debugging enabled by adjusting the value in:
+
+	/sys/module/cachefiles/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+	BIT	VALUE	STREAM				POINT
+	=======	=======	===============================	=======================
+	0	1	General				Function entry trace
+	1	2					Function exit trace
+	2	4					General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file.  For example:
+
+	echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
+
+will turn on all function entry debugging.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/fscache.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/fscache.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/fscache.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/fscache.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,333 @@
+			  ==========================
+			  General Filesystem Caching
+			  ==========================
+
+========
+OVERVIEW
+========
+
+This facility is a general purpose cache for network filesystems, though it
+could be used for caching other things such as ISO9660 filesystems too.
+
+FS-Cache mediates between cache backends (such as CacheFS) and network
+filesystems:
+
+	+---------+
+	|         |                        +--------------+
+	|   NFS   |--+                     |              |
+	|         |  |                 +-->|   CacheFS    |
+	+---------+  |   +----------+  |   |  /dev/hda5   |
+	             |   |          |  |   +--------------+
+	+---------+  +-->|          |  |
+	|         |      |          |--+
+	|   AFS   |----->| FS-Cache |
+	|         |      |          |--+
+	+---------+  +-->|          |  |
+	             |   |          |  |   +--------------+
+	+---------+  |   +----------+  |   |              |
+	|         |  |                 +-->|  CacheFiles  |
+	|  ISOFS  |--+                     |  /var/cache  |
+	|         |                        +--------------+
+	+---------+
+
+Or to look at it another way, FS-Cache is a module that provides a caching
+facility to a network filesystem such that the cache is transparent to the
+user:
+
+	+---------+
+	|         |
+	| Server  |
+	|         |
+	+---------+
+	     |                  NETWORK
+	~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	     |
+	     |           +----------+
+	     V           |          |
+	+---------+      |          |
+	|         |      |          |
+	|   NFS   |----->| FS-Cache |
+	|         |      |          |--+
+	+---------+      |          |  |   +--------------+   +--------------+
+	     |           |          |  |   |              |   |              |
+	     V           +----------+  +-->|  CacheFiles  |-->|  Ext3        |
+	+---------+                        |  /var/cache  |   |  /dev/sda6   |
+	|         |                        +--------------+   +--------------+
+	|   VFS   |                                ^                     ^
+	|         |                                |                     |
+	+---------+                                +--------------+      |
+	     |                  KERNEL SPACE                      |      |
+	~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~|~~~~
+	     |                  USER SPACE                        |      |
+	     V                                                    |      |
+	+---------+                                           +--------------+
+	|         |                                           |              |
+	| Process |                                           | cachefilesd  |
+	|         |                                           |              |
+	+---------+                                           +--------------+
+
+
+FS-Cache does not follow the idea of completely loading every netfs file
+opened in its entirety into a cache before permitting it to be accessed and
+then serving the pages out of that cache rather than the netfs inode because:
+
+ (1) It must be practical to operate without a cache.
+
+ (2) The size of any accessible file must not be limited to the size of the
+     cache.
+
+ (3) The combined size of all opened files (this includes mapped libraries)
+     must not be limited to the size of the cache.
+
+ (4) The user should not be forced to download an entire file just to do a
+     one-off access of a small portion of it (such as might be done with the
+     "file" program).
+
+It instead serves the cache out in PAGE_SIZE chunks as and when requested by
+the netfs('s) using it.
+
+
+FS-Cache provides the following facilities:
+
+ (1) More than one cache can be used at once.  Caches can be selected
+     explicitly by use of tags.
+
+ (2) Caches can be added / removed at any time.
+
+ (3) The netfs is provided with an interface that allows either party to
+     withdraw caching facilities from a file (required for (2)).
+
+ (4) The interface to the netfs returns as few errors as possible, preferring
+     rather to let the netfs remain oblivious.
+
+ (5) Cookies are used to represent indices, files and other objects to the
+     netfs.  The simplest cookie is just a NULL pointer - indicating nothing
+     cached there.
+
+ (6) The netfs is allowed to propose - dynamically - any index hierarchy it
+     desires, though it must be aware that the index search function is
+     recursive, stack space is limited, and indices can only be children of
+     indices.
+
+ (7) Data I/O is done direct to and from the netfs's pages.  The netfs
+     indicates that page A is at index B of the data-file represented by cookie
+     C, and that it should be read or written.  The cache backend may or may
+     not start I/O on that page, but if it does, a netfs callback will be
+     invoked to indicate completion.  The I/O may be either synchronous or
+     asynchronous.
+
+ (8) Cookies can be "retired" upon release.  At this point FS-Cache will mark
+     them as obsolete and the index hierarchy rooted at that point will get
+     recycled.
+
+ (9) The netfs provides a "match" function for index searches.  In addition to
+     saying whether a match was made or not, this can also specify that an
+     entry should be updated or deleted.
+
+(10) As much as possible is done asynchronously.
+
+
+FS-Cache maintains a virtual indexing tree in which all indices, files, objects
+and pages are kept.  Bits of this tree may actually reside in one or more
+caches.
+
+                                           FSDEF
+                                             |
+                        +------------------------------------+
+                        |                                    |
+                       NFS                                  AFS
+                        |                                    |
+           +--------------------------+                +-----------+
+           |                          |                |           |
+        homedir                     mirror          afs.org   redhat.com
+           |                          |                            |
+     +------------+           +---------------+              +----------+
+     |            |           |               |              |          |
+   00001        00002       00007           00125        vol00001   vol00002
+     |            |           |               |                         |
+ +---+---+     +-----+      +---+      +------+------+            +-----+----+
+ |   |   |     |     |      |   |      |      |      |            |     |    |
+PG0 PG1 PG2   PG0  XATTR   PG0 PG1   DIRENT DIRENT DIRENT        R/W   R/O  Bak
+                     |                                            |
+                    PG0                                       +-------+
+                                                              |       |
+                                                            00001   00003
+                                                              |
+                                                          +---+---+
+                                                          |   |   |
+                                                         PG0 PG1 PG2
+
+In the example above, you can see two netfs's being backed: NFS and AFS.  These
+have different index hierarchies:
+
+ (*) The NFS primary index contains per-server indices.  Each server index is
+     indexed by NFS file handles to get data file objects.  Each data file
+     objects can have an array of pages, but may also have further child
+     objects, such as extended attributes and directory entries.  Extended
+     attribute objects themselves have page-array contents.
+
+ (*) The AFS primary index contains per-cell indices.  Each cell index contains
+     per-logical-volume indices.  Each of volume index contains up to three
+     indices for the read-write, read-only and backup mirrors of those volumes.
+     Each of these contains vnode data file objects, each of which contains an
+     array of pages.
+
+The very top index is the FS-Cache master index in which individual netfs's
+have entries.
+
+Any index object may reside in more than one cache, provided it only has index
+children.  Any index with non-index object children will be assumed to only
+reside in one cache.
+
+
+The netfs API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/netfs-api.txt
+
+The cache backend API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/backend-api.txt
+
+A description of the internal representations and object state machine can be
+found in:
+
+	Documentation/filesystems/caching/object.txt
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following options enabled:
+
+	CONFIG_FSCACHE_STATS=y
+	CONFIG_FSCACHE_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a number of
+proc files.
+
+ (*) /proc/fs/fscache/stats
+
+     This shows counts of a number of events that can happen in FS-Cache:
+
+	CLASS	EVENT	MEANING
+	=======	=======	=======================================================
+	Cookies	idx=N	Number of index cookies allocated
+		dat=N	Number of data storage cookies allocated
+		spc=N	Number of special cookies allocated
+	Objects	alc=N	Number of objects allocated
+		nal=N	Number of object allocation failures
+		avl=N	Number of objects that reached the available state
+		ded=N	Number of objects that reached the dead state
+	ChkAux	non=N	Number of objects that didn't have a coherency check
+		ok=N	Number of objects that passed a coherency check
+		upd=N	Number of objects that needed a coherency data update
+		obs=N	Number of objects that were declared obsolete
+	Pages	mrk=N	Number of pages marked as being cached
+		unc=N	Number of uncache page requests seen
+	Acquire	n=N	Number of acquire cookie requests seen
+		nul=N	Number of acq reqs given a NULL parent
+		noc=N	Number of acq reqs rejected due to no cache available
+		ok=N	Number of acq reqs succeeded
+		nbf=N	Number of acq reqs rejected due to error
+		oom=N	Number of acq reqs failed on ENOMEM
+	Lookups	n=N	Number of lookup calls made on cache backends
+		neg=N	Number of negative lookups made
+		pos=N	Number of positive lookups made
+		crt=N	Number of objects created by lookup
+	Updates	n=N	Number of update cookie requests seen
+		nul=N	Number of upd reqs given a NULL parent
+		run=N	Number of upd reqs granted CPU time
+	Relinqs	n=N	Number of relinquish cookie requests seen
+		nul=N	Number of rlq reqs given a NULL parent
+		wcr=N	Number of rlq reqs waited on completion of creation
+	AttrChg	n=N	Number of attribute changed requests seen
+		ok=N	Number of attr changed requests queued
+		nbf=N	Number of attr changed rejected -ENOBUFS
+		oom=N	Number of attr changed failed -ENOMEM
+		run=N	Number of attr changed ops given CPU time
+	Allocs	n=N	Number of allocation requests seen
+		ok=N	Number of successful alloc reqs
+		wt=N	Number of alloc reqs that waited on lookup completion
+		nbf=N	Number of alloc reqs rejected -ENOBUFS
+		ops=N	Number of alloc reqs submitted
+		owt=N	Number of alloc reqs waited for CPU time
+	Retrvls	n=N	Number of retrieval (read) requests seen
+		ok=N	Number of successful retr reqs
+		wt=N	Number of retr reqs that waited on lookup completion
+		nod=N	Number of retr reqs returned -ENODATA
+		nbf=N	Number of retr reqs rejected -ENOBUFS
+		int=N	Number of retr reqs aborted -ERESTARTSYS
+		oom=N	Number of retr reqs failed -ENOMEM
+		ops=N	Number of retr reqs submitted
+		owt=N	Number of retr reqs waited for CPU time
+	Stores	n=N	Number of storage (write) requests seen
+		ok=N	Number of successful store reqs
+		agn=N	Number of store reqs on a page already pending storage
+		nbf=N	Number of store reqs rejected -ENOBUFS
+		oom=N	Number of store reqs failed -ENOMEM
+		ops=N	Number of store reqs submitted
+		run=N	Number of store reqs granted CPU time
+	Ops	pend=N	Number of times async ops added to pending queues
+		run=N	Number of times async ops given CPU time
+		enq=N	Number of times async ops queued for processing
+		dfr=N	Number of async ops queued for deferred release
+		rel=N	Number of async ops released
+		gc=N	Number of deferred-release async ops garbage collected
+
+
+ (*) /proc/fs/fscache/histogram
+
+	cat /proc/fs/fscache/histogram
+	JIFS  SECS  OBJ INST  OP RUNS   OBJ RUNS  RETRV DLY RETRIEVLS
+	===== ===== ========= ========= ========= ========= =========
+
+     This shows the breakdown of the number of times each amount of time
+     between 0 jiffies and HZ-1 jiffies a variety of tasks took to run.  The
+     columns are as follows:
+
+	COLUMN		TIME MEASUREMENT
+	=======		=======================================================
+	OBJ INST	Length of time to instantiate an object
+	OP RUNS		Length of time a call to process an operation took
+	OBJ RUNS	Length of time a call to process an object event took
+	RETRV DLY	Time between an requesting a read and lookup completing
+	RETRIEVLS	Time between beginning and end of a retrieval
+
+     Each row shows the number of events that took a particular range of times.
+     Each step is 1 jiffy in size.  The JIFS column indicates the particular
+     jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_FSCACHE_DEBUG is enabled, the FS-Cache facility can have runtime
+debugging enabled by adjusting the value in:
+
+	/sys/module/fscache/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+	BIT	VALUE	STREAM				POINT
+	=======	=======	===============================	=======================
+	0	1	Cache management		Function entry trace
+	1	2					Function exit trace
+	2	4					General
+	3	8	Cookie management		Function entry trace
+	4	16					Function exit trace
+	5	32					General
+	6	64	Page handling			Function entry trace
+	7	128					Function exit trace
+	8	256					General
+	9	512	Operation management		Function entry trace
+	10	1024					Function exit trace
+	11	2048					General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file.  For example:
+
+	echo $((1|8|64)) >/sys/module/fscache/parameters/debug
+
+will turn on all function entry debugging.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/netfs-api.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/netfs-api.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/netfs-api.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/netfs-api.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,778 @@
+			===============================
+			FS-CACHE NETWORK FILESYSTEM API
+			===============================
+
+There's an API by which a network filesystem can make use of the FS-Cache
+facilities.  This is based around a number of principles:
+
+ (1) Caches can store a number of different object types.  There are two main
+     object types: indices and files.  The first is a special type used by
+     FS-Cache to make finding objects faster and to make retiring of groups of
+     objects easier.
+
+ (2) Every index, file or other object is represented by a cookie.  This cookie
+     may or may not have anything associated with it, but the netfs doesn't
+     need to care.
+
+ (3) Barring the top-level index (one entry per cached netfs), the index
+     hierarchy for each netfs is structured according the whim of the netfs.
+
+This API is declared in <linux/fscache.h>.
+
+This document contains the following sections:
+
+	 (1) Network filesystem definition
+	 (2) Index definition
+	 (3) Object definition
+	 (4) Network filesystem (un)registration
+	 (5) Cache tag lookup
+	 (6) Index registration
+	 (7) Data file registration
+	 (8) Miscellaneous object registration
+	 (9) Setting the data file size
+	(10) Page alloc/read/write
+	(11) Page uncaching
+	(12) Index and data file update
+	(13) Miscellaneous cookie operations
+	(14) Cookie unregistration
+	(15) Index and data file invalidation
+	(16) FS-Cache specific page flags.
+
+
+=============================
+NETWORK FILESYSTEM DEFINITION
+=============================
+
+FS-Cache needs a description of the network filesystem.  This is specified
+using a record of the following structure:
+
+	struct fscache_netfs {
+		uint32_t			version;
+		const char			*name;
+		struct fscache_cookie		*primary_index;
+		...
+	};
+
+This first two fields should be filled in before registration, and the third
+will be filled in by the registration function; any other fields should just be
+ignored and are for internal use only.
+
+The fields are:
+
+ (1) The name of the netfs (used as the key in the toplevel index).
+
+ (2) The version of the netfs (if the name matches but the version doesn't, the
+     entire in-cache hierarchy for this netfs will be scrapped and begun
+     afresh).
+
+ (3) The cookie representing the primary index will be allocated according to
+     another parameter passed into the registration function.
+
+For example, kAFS (linux/fs/afs/) uses the following definitions to describe
+itself:
+
+	struct fscache_netfs afs_cache_netfs = {
+		.version	= 0,
+		.name		= "afs",
+	};
+
+
+================
+INDEX DEFINITION
+================
+
+Indices are used for two purposes:
+
+ (1) To aid the finding of a file based on a series of keys (such as AFS's
+     "cell", "volume ID", "vnode ID").
+
+ (2) To make it easier to discard a subset of all the files cached based around
+     a particular key - for instance to mirror the removal of an AFS volume.
+
+However, since it's unlikely that any two netfs's are going to want to define
+their index hierarchies in quite the same way, FS-Cache tries to impose as few
+restraints as possible on how an index is structured and where it is placed in
+the tree.  The netfs can even mix indices and data files at the same level, but
+it's not recommended.
+
+Each index entry consists of a key of indeterminate length plus some auxilliary
+data, also of indeterminate length.
+
+There are some limits on indices:
+
+ (1) Any index containing non-index objects should be restricted to a single
+     cache.  Any such objects created within an index will be created in the
+     first cache only.  The cache in which an index is created can be
+     controlled by cache tags (see below).
+
+ (2) The entry data must be atomically journallable, so it is limited to about
+     400 bytes at present.  At least 400 bytes will be available.
+
+ (3) The depth of the index tree should be judged with care as the search
+     function is recursive.  Too many layers will run the kernel out of stack.
+
+
+=================
+OBJECT DEFINITION
+=================
+
+To define an object, a structure of the following type should be filled out:
+
+	struct fscache_cookie_def
+	{
+		uint8_t name[16];
+		uint8_t type;
+
+		struct fscache_cache_tag *(*select_cache)(
+			const void *parent_netfs_data,
+			const void *cookie_netfs_data);
+
+		uint16_t (*get_key)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		void (*get_attr)(const void *cookie_netfs_data,
+				 uint64_t *size);
+
+		uint16_t (*get_aux)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+						   const void *data,
+						   uint16_t datalen);
+
+		void (*get_context)(void *cookie_netfs_data, void *context);
+
+		void (*put_context)(void *cookie_netfs_data, void *context);
+
+		void (*mark_pages_cached)(void *cookie_netfs_data,
+					  struct address_space *mapping,
+					  struct pagevec *cached_pvec);
+
+		void (*now_uncached)(void *cookie_netfs_data);
+	};
+
+This has the following fields:
+
+ (1) The type of the object [mandatory].
+
+     This is one of the following values:
+
+	(*) FSCACHE_COOKIE_TYPE_INDEX
+
+	    This defines an index, which is a special FS-Cache type.
+
+	(*) FSCACHE_COOKIE_TYPE_DATAFILE
+
+	    This defines an ordinary data file.
+
+	(*) Any other value between 2 and 255
+
+	    This defines an extraordinary object such as an XATTR.
+
+ (2) The name of the object type (NUL terminated unless all 16 chars are used)
+     [optional].
+
+ (3) A function to select the cache in which to store an index [optional].
+
+     This function is invoked when an index needs to be instantiated in a cache
+     during the instantiation of a non-index object.  Only the immediate index
+     parent for the non-index object will be queried.  Any indices above that
+     in the hierarchy may be stored in multiple caches.  This function does not
+     need to be supplied for any non-index object or any index that will only
+     have index children.
+
+     If this function is not supplied or if it returns NULL then the first
+     cache in the parent's list will be chosed, or failing that, the first
+     cache in the master list.
+
+ (4) A function to retrieve an object's key from the netfs [mandatory].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of key data that it may
+     provide.  It should write the required key data into the given buffer and
+     return the quantity it wrote.
+
+ (5) A function to retrieve attribute data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function.  It should return the size of the file if
+     this is a data file.  The size may be used to govern how much cache must
+     be reserved for this file in the cache.
+
+     If the function is absent, a file size of 0 is assumed.
+
+ (6) A function to retrieve auxilliary data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of auxilliary data that
+     it may provide.  It should write the auxilliary data into the given buffer
+     and return the quantity it wrote.
+
+     If this function is absent, the auxilliary data length will be set to 0.
+
+     The length of the auxilliary data buffer may be dependent on the key
+     length.  A netfs mustn't rely on being able to provide more than 400 bytes
+     for both.
+
+ (7) A function to check the auxilliary data [optional].
+
+     This function will be called to check that a match found in the cache for
+     this object is valid.  For instance with AFS it could check the auxilliary
+     data against the data version number returned by the server to determine
+     whether the index entry in a cache is still valid.
+
+     If this function is absent, it will be assumed that matching objects in a
+     cache are always valid.
+
+     If present, the function should return one of the following values:
+
+	(*) FSCACHE_CHECKAUX_OKAY		- the entry is okay as is
+	(*) FSCACHE_CHECKAUX_NEEDS_UPDATE	- the entry requires update
+	(*) FSCACHE_CHECKAUX_OBSOLETE		- the entry should be deleted
+
+     This function can also be used to extract data from the auxilliary data in
+     the cache and copy it into the netfs's structures.
+
+ (8) A pair of functions to manage contexts for the completion callback
+     [optional].
+
+     The cache read/write functions are passed a context which is then passed
+     to the I/O completion callback function.  To ensure this context remains
+     valid until after the I/O completion is called, two functions may be
+     provided: one to get an extra reference on the context, and one to drop a
+     reference to it.
+
+     If the context is not used or is a type of object that won't go out of
+     scope, then these functions are not required.  These functions are not
+     required for indices as indices may not contain data.  These functions may
+     be called in interrupt context and so may not sleep.
+
+ (9) A function to mark a page as retaining cache metadata [optional].
+
+     This is called by the cache to indicate that it is retaining in-memory
+     information for this page and that the netfs should uncache the page when
+     it has finished.  This does not indicate whether there's data on the disk
+     or not.  Note that several pages at once may be presented for marking.
+
+     The PG_fscache bit is set on the pages before this function would be
+     called, so the function need not be provided if this is sufficient.
+
+     This function is not required for indices as they're not permitted data.
+
+(10) A function to unmark all the pages retaining cache metadata [mandatory].
+
+     This is called by FS-Cache to indicate that a backing store is being
+     unbound from a cookie and that all the marks on the pages should be
+     cleared to prevent confusion.  Note that the cache will have torn down all
+     its tracking information so that the pages don't need to be explicitly
+     uncached.
+
+     This function is not required for indices as they're not permitted data.
+
+
+===================================
+NETWORK FILESYSTEM (UN)REGISTRATION
+===================================
+
+The first step is to declare the network filesystem to the cache.  This also
+involves specifying the layout of the primary index (for AFS, this would be the
+"cell" level).
+
+The registration function is:
+
+	int fscache_register_netfs(struct fscache_netfs *netfs);
+
+It just takes a pointer to the netfs definition.  It returns 0 or an error as
+appropriate.
+
+For kAFS, registration is done as follows:
+
+	ret = fscache_register_netfs(&afs_cache_netfs);
+
+The last step is, of course, unregistration:
+
+	void fscache_unregister_netfs(struct fscache_netfs *netfs);
+
+
+================
+CACHE TAG LOOKUP
+================
+
+FS-Cache permits the use of more than one cache.  To permit particular index
+subtrees to be bound to particular caches, the second step is to look up cache
+representation tags.  This step is optional; it can be left entirely up to
+FS-Cache as to which cache should be used.  The problem with doing that is that
+FS-Cache will always pick the first cache that was registered.
+
+To get the representation for a named tag:
+
+	struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name);
+
+This takes a text string as the name and returns a representation of a tag.  It
+will never return an error.  It may return a dummy tag, however, if it runs out
+of memory; this will inhibit caching with this tag.
+
+Any representation so obtained must be released by passing it to this function:
+
+	void fscache_release_cache_tag(struct fscache_cache_tag *tag);
+
+The tag will be retrieved by FS-Cache when it calls the object definition
+operation select_cache().
+
+
+==================
+INDEX REGISTRATION
+==================
+
+The third step is to inform FS-Cache about part of an index hierarchy that can
+be used to locate files.  This is done by requesting a cookie for each index in
+the path to the file:
+
+	struct fscache_cookie *
+	fscache_acquire_cookie(struct fscache_cookie *parent,
+			       const struct fscache_object_def *def,
+			       void *netfs_data);
+
+This function creates an index entry in the index represented by parent,
+filling in the index entry by calling the operations pointed to by def.
+
+Note that this function never returns an error - all errors are handled
+internally.  It may, however, return NULL to indicate no cookie.  It is quite
+acceptable to pass this token back to this function as the parent to another
+acquisition (or even to the relinquish cookie, read page and write page
+functions - see below).
+
+Note also that no indices are actually created in a cache until a non-index
+object needs to be created somewhere down the hierarchy.  Furthermore, an index
+may be created in several different caches independently at different times.
+This is all handled transparently, and the netfs doesn't see any of it.
+
+For example, with AFS, a cell would be added to the primary index.  This index
+entry would have a dependent inode containing a volume location index for the
+volume mappings within this cell:
+
+	cell->cache =
+		fscache_acquire_cookie(afs_cache_netfs.primary_index,
+				       &afs_cell_cache_index_def,
+				       cell);
+
+Then when a volume location was accessed, it would be entered into the cell's
+index and an inode would be allocated that acts as a volume type and hash chain
+combination:
+
+	vlocation->cache =
+		fscache_acquire_cookie(cell->cache,
+				       &afs_vlocation_cache_index_def,
+				       vlocation);
+
+And then a particular flavour of volume (R/O for example) could be added to
+that index, creating another index for vnodes (AFS inode equivalents):
+
+	volume->cache =
+		fscache_acquire_cookie(vlocation->cache,
+				       &afs_volume_cache_index_def,
+				       volume);
+
+
+======================
+DATA FILE REGISTRATION
+======================
+
+The fourth step is to request a data file be created in the cache.  This is
+identical to index cookie acquisition.  The only difference is that the type in
+the object definition should be something other than index type.
+
+	vnode->cache =
+		fscache_acquire_cookie(volume->cache,
+				       &afs_vnode_cache_object_def,
+				       vnode);
+
+
+=================================
+MISCELLANEOUS OBJECT REGISTRATION
+=================================
+
+An optional step is to request an object of miscellaneous type be created in
+the cache.  This is almost identical to index cookie acquisition.  The only
+difference is that the type in the object definition should be something other
+than index type.  Whilst the parent object could be an index, it's more likely
+it would be some other type of object such as a data file.
+
+	xattr->cache =
+		fscache_acquire_cookie(vnode->cache,
+				       &afs_xattr_cache_object_def,
+				       xattr);
+
+Miscellaneous objects might be used to store extended attributes or directory
+entries for example.
+
+
+==========================
+SETTING THE DATA FILE SIZE
+==========================
+
+The fifth step is to set the physical attributes of the file, such as its size.
+This doesn't automatically reserve any space in the cache, but permits the
+cache to adjust its metadata for data tracking appropriately:
+
+	int fscache_attr_changed(struct fscache_cookie *cookie);
+
+The cache will return -ENOBUFS if there is no backing cache or if there is no
+space to allocate any extra metadata required in the cache.  The attributes
+will be accessed with the get_attr() cookie definition operation.
+
+Note that attempts to read or write data pages in the cache over this size may
+be rebuffed with -ENOBUFS.
+
+This operation schedules an attribute adjustment to happen asynchronously at
+some point in the future, and as such, it may happen after the function returns
+to the caller.  The attribute adjustment excludes read and write operations.
+
+
+=====================
+PAGE READ/ALLOC/WRITE
+=====================
+
+And the sixth step is to store and retrieve pages in the cache.  There are
+three functions that are used to do this.
+
+Note:
+
+ (1) A page should not be re-read or re-allocated without uncaching it first.
+
+ (2) A read or allocated page must be uncached when the netfs page is released
+     from the pagecache.
+
+ (3) A page should only be written to the cache if previous read or allocated.
+
+This permits the cache to maintain its page tracking in proper order.
+
+
+PAGE READ
+---------
+
+Firstly, the netfs should ask FS-Cache to examine the caches and read the
+contents cached for a particular page of a particular file if present, or else
+allocate space to store the contents if not:
+
+	typedef
+	void (*fscache_rw_complete_t)(struct page *page,
+				      void *context,
+				      int error);
+
+	int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+				       struct page *page,
+				       fscache_rw_complete_t end_io_func,
+				       void *context,
+				       gfp_t gfp);
+
+The cookie argument must specify a cookie for an object that isn't an index,
+the page specified will have the data loaded into it (and is also used to
+specify the page number), and the gfp argument is used to control how any
+memory allocations made are satisfied.
+
+If the cookie indicates the inode is not cached:
+
+ (1) The function will return -ENOBUFS.
+
+Else if there's a copy of the page resident in the cache:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) The function will submit a request to read the data from the cache's
+     backing device directly into the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the read is complete, end_io_func() will be invoked with:
+
+     (*) The netfs data supplied when the cookie was created.
+
+     (*) The page descriptor.
+
+     (*) The context argument passed to the above function.  This will be
+         maintained with the get_context/put_context functions mentioned above.
+
+     (*) An argument that's 0 on success or negative for an error code.
+
+     If an error occurs, it should be assumed that the page contains no usable
+     data.
+
+     end_io_func() will be called in process context if the read is results in
+     an error, but it might be called in interrupt context if the read is
+     successful.
+
+Otherwise, if there's not a copy available in cache, but the cache may be able
+to store the page:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) A block may be reserved in the cache and attached to the object at the
+     appropriate place.
+
+ (3) The function will return -ENODATA.
+
+This function may also return -ENOMEM or -EINTR, in which case it won't have
+read any data from the cache.
+
+
+PAGE ALLOCATE
+-------------
+
+Alternatively, if there's not expected to be any data in the cache for a page
+because the file has been extended, a block can simply be allocated instead:
+
+	int fscache_alloc_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       gfp_t gfp);
+
+This is similar to the fscache_read_or_alloc_page() function, except that it
+never reads from the cache.  It will return 0 if a block has been allocated,
+rather than -ENODATA as the other would.  One or the other must be performed
+before writing to the cache.
+
+The mark_pages_cached() cookie operation will be called on the page if
+successful.
+
+
+PAGE WRITE
+----------
+
+Secondly, if the netfs changes the contents of the page (either due to an
+initial download or if a user performs a write), then the page should be
+written back to the cache:
+
+	int fscache_write_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       gfp_t gfp);
+
+The cookie argument must specify a data file cookie, the page specified should
+contain the data to be written (and is also used to specify the page number),
+and the gfp argument is used to control how any memory allocations made are
+satisfied.
+
+The page must have first been read or allocated successfully and must not have
+been uncached before writing is performed.
+
+If the cookie indicates the inode is not cached then:
+
+ (1) The function will return -ENOBUFS.
+
+Else if space can be allocated in the cache to hold this page:
+
+ (1) PG_fscache_write will be set on the page.
+
+ (2) The function will submit a request to write the data to cache's backing
+     device directly from the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the write is complete PG_fscache_write is cleared on the page and
+     anyone waiting for that bit will be woken up.
+
+Else if there's no space available in the cache, -ENOBUFS will be returned.  It
+is also possible for the PG_fscache_write bit to be cleared when no write took
+place if unforeseen circumstances arose (such as a disk error).
+
+Writing takes place asynchronously.
+
+
+MULTIPLE PAGE READ
+------------------
+
+A facility is provided to read several pages at once, as requested by the
+readpages() address space operation:
+
+	int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+					struct address_space *mapping,
+					struct list_head *pages,
+					int *nr_pages,
+					fscache_rw_complete_t end_io_func,
+					void *context,
+					gfp_t gfp);
+
+This works in a similar way to fscache_read_or_alloc_page(), except:
+
+ (1) Any page it can retrieve data for is removed from pages and nr_pages and
+     dispatched for reading to the disk.  Reads of adjacent pages on disk may
+     be merged for greater efficiency.
+
+ (2) The mark_pages_cached() cookie operation will be called on several pages
+     at once if they're being read or allocated.
+
+ (3) If there was an general error, then that error will be returned.
+
+     Else if some pages couldn't be allocated or read, then -ENOBUFS will be
+     returned.
+
+     Else if some pages couldn't be read but were allocated, then -ENODATA will
+     be returned.
+
+     Otherwise, if all pages had reads dispatched, then 0 will be returned, the
+     list will be empty and *nr_pages will be 0.
+
+ (4) end_io_func will be called once for each page being read as the reads
+     complete.  It will be called in process context if error != 0, but it may
+     be called in interrupt context if there is no error.
+
+Note that a return of -ENODATA, -ENOBUFS or any other error does not preclude
+some of the pages being read and some being allocated.  Those pages will have
+been marked appropriately and will need uncaching.
+
+
+==============
+PAGE UNCACHING
+==============
+
+To uncache a page, this function should be called:
+
+	void fscache_uncache_page(struct fscache_cookie *cookie,
+				  struct page *page);
+
+This function permits the cache to release any in-memory representation it
+might be holding for this netfs page.  This function must be called once for
+each page on which the read or write page functions above have been called to
+make sure the cache's in-memory tracking information gets torn down.
+
+Note that pages can't be explicitly deleted from the a data file.  The whole
+data file must be retired (see the relinquish cookie function below).
+
+Furthermore, note that this does not cancel the asynchronous read or write
+operation started by the read/alloc and write functions, so the page
+invalidation and release functions must use:
+
+	bool fscache_check_page_write(struct fscache_cookie *cookie,
+				      struct page *page);
+
+to see if a page is being written to the cache, and:
+
+	void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+					struct page *page);
+
+to wait for it to finish if it is.
+
+
+==========================
+INDEX AND DATA FILE UPDATE
+==========================
+
+To request an update of the index data for an index or other object, the
+following function should be called:
+
+	void fscache_update_cookie(struct fscache_cookie *cookie);
+
+This function will refer back to the netfs_data pointer stored in the cookie by
+the acquisition function to obtain the data to write into each revised index
+entry.  The update method in the parent index definition will be called to
+transfer the data.
+
+Note that partial updates may happen automatically at other times, such as when
+data blocks are added to a data file object.
+
+
+===============================
+MISCELLANEOUS COOKIE OPERATIONS
+===============================
+
+There are a number of operations that can be used to control cookies:
+
+ (*) Cookie pinning:
+
+	int fscache_pin_cookie(struct fscache_cookie *cookie);
+	void fscache_unpin_cookie(struct fscache_cookie *cookie);
+
+     These operations permit data cookies to be pinned into the cache and to
+     have the pinning removed.  They are not permitted on index cookies.
+
+     The pinning function will return 0 if successful, -ENOBUFS in the cookie
+     isn't backed by a cache, -EOPNOTSUPP if the cache doesn't support pinning,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+ (*) Data space reservation:
+
+	int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+
+     This permits a netfs to request cache space be reserved to store up to the
+     given amount of a file.  It is permitted to ask for more than the current
+     size of the file to allow for future file expansion.
+
+     If size is given as zero then the reservation will be cancelled.
+
+     The function will return 0 if successful, -ENOBUFS in the cookie isn't
+     backed by a cache, -EOPNOTSUPP if the cache doesn't support reservations,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+     Note that this doesn't pin an object in a cache; it can still be culled to
+     make space if it's not in use.
+
+
+=====================
+COOKIE UNREGISTRATION
+=====================
+
+To get rid of a cookie, this function should be called.
+
+	void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+				       int retire);
+
+If retire is non-zero, then the object will be marked for recycling, and all
+copies of it will be removed from all active caches in which it is present.
+Not only that but all child objects will also be retired.
+
+If retire is zero, then the object may be available again when next the
+acquisition function is called.  Retirement here will overrule the pinning on a
+cookie.
+
+One very important note - relinquish must NOT be called for a cookie unless all
+the cookies for "child" indices, objects and pages have been relinquished
+first.
+
+
+================================
+INDEX AND DATA FILE INVALIDATION
+================================
+
+There is no direct way to invalidate an index subtree or a data file.  To do
+this, the caller should relinquish and retire the cookie they have, and then
+acquire a new one.
+
+
+===========================
+FS-CACHE SPECIFIC PAGE FLAG
+===========================
+
+FS-Cache makes use of a page flag, PG_private_2, for its own purpose.  This is
+given the alternative name PG_fscache.
+
+PG_fscache is used to indicate that the page is known by the cache, and that
+the cache must be informed if the page is going to go away.  It's an indication
+to the netfs that the cache has an interest in this page, where an interest may
+be a pointer to it, resources allocated or reserved for it, or I/O in progress
+upon it.
+
+The netfs can use this information in methods such as releasepage() to
+determine whether it needs to uncache a page or update it.
+
+Furthermore, if this bit is set, releasepage() and invalidatepage() operations
+will be called on a page to get rid of it, even if PG_private is not set.  This
+allows caching to attempted on a page before read_cache_pages() to be called
+after fscache_read_or_alloc_pages() as the former will try and release pages it
+was given under certain circumstances.
+
+This bit does not overlap with such as PG_private.  This means that FS-Cache
+can be used with a filesystem that uses the block buffering code.
+
+There are a number of operations defined on this flag:
+
+	int PageFsCache(struct page *page);
+	void SetPageFsCache(struct page *page)
+	void ClearPageFsCache(struct page *page)
+	int TestSetPageFsCache(struct page *page)
+	int TestClearPageFsCache(struct page *page)
+
+These functions are bit test, bit set, bit clear, bit test and set and bit
+test and clear operations on PG_fscache.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/object.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/object.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/object.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/object.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,313 @@
+	     ====================================================
+	     IN-KERNEL CACHE OBJECT REPRESENTATION AND MANAGEMENT
+	     ====================================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Representation
+
+ (*) Object management state machine.
+
+     - Provision of cpu time.
+     - Locking simplification.
+
+ (*) The set of states.
+
+ (*) The set of events.
+
+
+==============
+REPRESENTATION
+==============
+
+FS-Cache maintains an in-kernel representation of each object that a netfs is
+currently interested in.  Such objects are represented by the fscache_cookie
+struct and are referred to as cookies.
+
+FS-Cache also maintains a separate in-kernel representation of the objects that
+a cache backend is currently actively caching.  Such objects are represented by
+the fscache_object struct.  The cache backends allocate these upon request, and
+are expected to embed them in their own representations.  These are referred to
+as objects.
+
+There is a 1:N relationship between cookies and objects.  A cookie may be
+represented by multiple objects - an index may exist in more than one cache -
+or even by no objects (it may not be cached).
+
+Furthermore, both cookies and objects are hierarchical.  The two hierarchies
+correspond, but the cookies tree is a superset of the union of the object trees
+of multiple caches:
+
+	    NETFS INDEX TREE               :      CACHE 1     :      CACHE 2
+	                                   :                  :
+	                                   :   +-----------+  :
+	                          +----------->|  IObject  |  :
+	      +-----------+       |        :   +-----------+  :
+	      |  ICookie  |-------+        :         |        :
+	      +-----------+       |        :         |        :   +-----------+
+	            |             +------------------------------>|  IObject  |
+	            |                      :         |        :   +-----------+
+	            |                      :         V        :         |
+	            |                      :   +-----------+  :         |
+	            V             +----------->|  IObject  |  :         |
+	      +-----------+       |        :   +-----------+  :         |
+	      |  ICookie  |-------+        :         |        :         V
+	      +-----------+       |        :         |        :   +-----------+
+	            |             +------------------------------>|  IObject  |
+	      +-----+-----+                :         |        :   +-----------+
+	      |           |                :         |        :         |
+	      V           |                :         V        :         |
+	+-----------+     |                :   +-----------+  :         |
+	|  ICookie  |------------------------->|  IObject  |  :         |
+	+-----------+     |                :   +-----------+  :         |
+	      |           V                :         |        :         V
+	      |     +-----------+          :         |        :   +-----------+
+	      |     |  ICookie  |-------------------------------->|  IObject  |
+	      |     +-----------+          :         |        :   +-----------+
+	      V           |                :         V        :         |
+	+-----------+     |                :   +-----------+  :         |
+	|  DCookie  |------------------------->|  DObject  |  :         |
+	+-----------+     |                :   +-----------+  :         |
+	                  |                :                  :         |
+	          +-------+-------+        :                  :         |
+	          |               |        :                  :         |
+	          V               V        :                  :         V
+	    +-----------+   +-----------+  :                  :   +-----------+
+	    |  DCookie  |   |  DCookie  |------------------------>|  DObject  |
+	    +-----------+   +-----------+  :                  :   +-----------+
+	                                   :                  :
+
+In the above illustration, ICookie and IObject represent indices and DCookie
+and DObject represent data storage objects.  Indices may have representation in
+multiple caches, but currently, non-index objects may not.  Objects of any type
+may also be entirely unrepresented.
+
+As far as the netfs API goes, the netfs is only actually permitted to see
+pointers to the cookies.  The cookies themselves and any objects attached to
+those cookies are hidden from it.
+
+
+===============================
+OBJECT MANAGEMENT STATE MACHINE
+===============================
+
+Within FS-Cache, each active object is managed by its own individual state
+machine.  The state for an object is kept in the fscache_object struct, in
+object->state.  A cookie may point to a set of objects that are in different
+states.
+
+Each state has an action associated with it that is invoked when the machine
+wakes up in that state.  There are four logical sets of states:
+
+ (1) Preparation: states that wait for the parent objects to become ready.  The
+     representations are hierarchical, and it is expected that an object must
+     be created or accessed with respect to its parent object.
+
+ (2) Initialisation: states that perform lookups in the cache and validate
+     what's found and that create on disk any missing metadata.
+
+ (3) Normal running: states that allow netfs operations on objects to proceed
+     and that update the state of objects.
+
+ (4) Termination: states that detach objects from their netfs cookies, that
+     delete objects from disk, that handle disk and system errors and that free
+     up in-memory resources.
+
+
+In most cases, transitioning between states is in response to signalled events.
+When a state has finished processing, it will usually set the mask of events in
+which it is interested (object->event_mask) and relinquish the worker thread.
+Then when an event is raised (by calling fscache_raise_event()), if the event
+is not masked, the object will be queued for processing (by calling
+fscache_enqueue_object()).
+
+
+PROVISION OF CPU TIME
+---------------------
+
+The work to be done by the various states is given CPU time by the threads of
+the slow work facility (see Documentation/slow-work.txt).  This is used in
+preference to the workqueue facility because:
+
+ (1) Threads may be completely occupied for very long periods of time by a
+     particular work item.  These state actions may be doing sequences of
+     synchronous, journalled disk accesses (lookup, mkdir, create, setxattr,
+     getxattr, truncate, unlink, rmdir, rename).
+
+ (2) Threads may do little actual work, but may rather spend a lot of time
+     sleeping on I/O.  This means that single-threaded and 1-per-CPU-threaded
+     workqueues don't necessarily have the right numbers of threads.
+
+
+LOCKING SIMPLIFICATION
+----------------------
+
+Because only one worker thread may be operating on any particular object's
+state machine at once, this simplifies the locking, particularly with respect
+to disconnecting the netfs's representation of a cache object (fscache_cookie)
+from the cache backend's representation (fscache_object) - which may be
+requested from either end.
+
+
+=================
+THE SET OF STATES
+=================
+
+The object state machine has a set of states that it can be in.  There are
+preparation states in which the object sets itself up and waits for its parent
+object to transit to a state that allows access to its children:
+
+ (1) State FSCACHE_OBJECT_INIT.
+
+     Initialise the object and wait for the parent object to become active.  In
+     the cache, it is expected that it will not be possible to look an object
+     up from the parent object, until that parent object itself has been looked
+     up.
+
+There are initialisation states in which the object sets itself up and accesses
+disk for the object metadata:
+
+ (2) State FSCACHE_OBJECT_LOOKING_UP.
+
+     Look up the object on disk, using the parent as a starting point.
+     FS-Cache expects the cache backend to probe the cache to see whether this
+     object is represented there, and if it is, to see if it's valid (coherency
+     management).
+
+     The cache should call fscache_object_lookup_negative() to indicate lookup
+     failure for whatever reason, and should call fscache_obtained_object() to
+     indicate success.
+
+     At the completion of lookup, FS-Cache will let the netfs go ahead with
+     read operations, no matter whether the file is yet cached.  If not yet
+     cached, read operations will be immediately rejected with ENODATA until
+     the first known page is uncached - as to that point there can be no data
+     to be read out of the cache for that file that isn't currently also held
+     in the pagecache.
+
+ (3) State FSCACHE_OBJECT_CREATING.
+
+     Create an object on disk, using the parent as a starting point.  This
+     happens if the lookup failed to find the object, or if the object's
+     coherency data indicated what's on disk is out of date.  In this state,
+     FS-Cache expects the cache to create
+
+     The cache should call fscache_obtained_object() if creation completes
+     successfully, fscache_object_lookup_negative() otherwise.
+
+     At the completion of creation, FS-Cache will start processing write
+     operations the netfs has queued for an object.  If creation failed, the
+     write ops will be transparently discarded, and nothing recorded in the
+     cache.
+
+There are some normal running states in which the object spends its time
+servicing netfs requests:
+
+ (4) State FSCACHE_OBJECT_AVAILABLE.
+
+     A transient state in which pending operations are started, child objects
+     are permitted to advance from FSCACHE_OBJECT_INIT state, and temporary
+     lookup data is freed.
+
+ (5) State FSCACHE_OBJECT_ACTIVE.
+
+     The normal running state.  In this state, requests the netfs makes will be
+     passed on to the cache.
+
+ (6) State FSCACHE_OBJECT_UPDATING.
+
+     The state machine comes here to update the object in the cache from the
+     netfs's records.  This involves updating the auxiliary data that is used
+     to maintain coherency.
+
+And there are terminal states in which an object cleans itself up, deallocates
+memory and potentially deletes stuff from disk:
+
+ (7) State FSCACHE_OBJECT_LC_DYING.
+
+     The object comes here if it is dying because of a lookup or creation
+     error.  This would be due to a disk error or system error of some sort.
+     Temporary data is cleaned up, and the parent is released.
+
+ (8) State FSCACHE_OBJECT_DYING.
+
+     The object comes here if it is dying due to an error, because its parent
+     cookie has been relinquished by the netfs or because the cache is being
+     withdrawn.
+
+     Any child objects waiting on this one are given CPU time so that they too
+     can destroy themselves.  This object waits for all its children to go away
+     before advancing to the next state.
+
+ (9) State FSCACHE_OBJECT_ABORT_INIT.
+
+     The object comes to this state if it was waiting on its parent in
+     FSCACHE_OBJECT_INIT, but its parent died.  The object will destroy itself
+     so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
+
+(10) State FSCACHE_OBJECT_RELEASING.
+(11) State FSCACHE_OBJECT_RECYCLING.
+
+     The object comes to one of these two states when dying once it is rid of
+     all its children, if it is dying because the netfs relinquished its
+     cookie.  In the first state, the cached data is expected to persist, and
+     in the second it will be deleted.
+
+(12) State FSCACHE_OBJECT_WITHDRAWING.
+
+     The object transits to this state if the cache decides it wants to
+     withdraw the object from service, perhaps to make space, but also due to
+     error or just because the whole cache is being withdrawn.
+
+(13) State FSCACHE_OBJECT_DEAD.
+
+     The object transits to this state when the in-memory object record is
+     ready to be deleted.  The object processor shouldn't ever see an object in
+     this state.
+
+
+THE SET OF EVENTS
+-----------------
+
+There are a number of events that can be raised to an object state machine:
+
+ (*) FSCACHE_OBJECT_EV_UPDATE
+
+     The netfs requested that an object be updated.  The state machine will ask
+     the cache backend to update the object, and the cache backend will ask the
+     netfs for details of the change through its cookie definition ops.
+
+ (*) FSCACHE_OBJECT_EV_CLEARED
+
+     This is signalled in two circumstances:
+
+     (a) when an object's last child object is dropped and
+
+     (b) when the last operation outstanding on an object is completed.
+
+     This is used to proceed from the dying state.
+
+ (*) FSCACHE_OBJECT_EV_ERROR
+
+     This is signalled when an I/O error occurs during the processing of some
+     object.
+
+ (*) FSCACHE_OBJECT_EV_RELEASE
+ (*) FSCACHE_OBJECT_EV_RETIRE
+
+     These are signalled when the netfs relinquishes a cookie it was using.
+     The event selected depends on whether the netfs asks for the backing
+     object to be retired (deleted) or retained.
+
+ (*) FSCACHE_OBJECT_EV_WITHDRAW
+
+     This is signalled when the cache backend wants to withdraw an object.
+     This means that the object will have to be detached from the netfs's
+     cookie.
+
+Because the withdrawing releasing/retiring events are all handled by the object
+state machine, it doesn't matter if there's a collision with both ends trying
+to sever the connection at the same time.  The state machine can just pick
+which one it wants to honour, and that effects the other.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/operations.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/operations.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/caching/operations.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/caching/operations.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,213 @@
+		       ================================
+		       ASYNCHRONOUS OPERATIONS HANDLING
+		       ================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Overview.
+
+ (*) Operation record initialisation.
+
+ (*) Parameters.
+
+ (*) Procedure.
+
+ (*) Asynchronous callback.
+
+
+========
+OVERVIEW
+========
+
+FS-Cache has an asynchronous operations handling facility that it uses for its
+data storage and retrieval routines.  Its operations are represented by
+fscache_operation structs, though these are usually embedded into some other
+structure.
+
+This facility is available to and expected to be be used by the cache backends,
+and FS-Cache will create operations and pass them off to the appropriate cache
+backend for completion.
+
+To make use of this facility, <linux/fscache-cache.h> should be #included.
+
+
+===============================
+OPERATION RECORD INITIALISATION
+===============================
+
+An operation is recorded in an fscache_operation struct:
+
+	struct fscache_operation {
+		union {
+			struct work_struct fast_work;
+			struct slow_work slow_work;
+		};
+		unsigned long		flags;
+		fscache_operation_processor_t processor;
+		...
+	};
+
+Someone wanting to issue an operation should allocate something with this
+struct embedded in it.  They should initialise it by calling:
+
+	void fscache_operation_init(struct fscache_operation *op,
+				    fscache_operation_release_t release);
+
+with the operation to be initialised and the release function to use.
+
+The op->flags parameter should be set to indicate the CPU time provision and
+the exclusivity (see the Parameters section).
+
+The op->fast_work, op->slow_work and op->processor flags should be set as
+appropriate for the CPU time provision (see the Parameters section).
+
+FSCACHE_OP_WAITING may be set in op->flags prior to each submission of the
+operation and waited for afterwards.
+
+
+==========
+PARAMETERS
+==========
+
+There are a number of parameters that can be set in the operation record's flag
+parameter.  There are three options for the provision of CPU time in these
+operations:
+
+ (1) The operation may be done synchronously (FSCACHE_OP_MYTHREAD).  A thread
+     may decide it wants to handle an operation itself without deferring it to
+     another thread.
+
+     This is, for example, used in read operations for calling readpages() on
+     the backing filesystem in CacheFiles.  Although readpages() does an
+     asynchronous data fetch, the determination of whether pages exist is done
+     synchronously - and the netfs does not proceed until this has been
+     determined.
+
+     If this option is to be used, FSCACHE_OP_WAITING must be set in op->flags
+     before submitting the operation, and the operating thread must wait for it
+     to be cleared before proceeding:
+
+		wait_on_bit(&op->flags, FSCACHE_OP_WAITING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+
+
+ (2) The operation may be fast asynchronous (FSCACHE_OP_FAST), in which case it
+     will be given to keventd to process.  Such an operation is not permitted
+     to sleep on I/O.
+
+     This is, for example, used by CacheFiles to copy data from a backing fs
+     page to a netfs page after the backing fs has read the page in.
+
+     If this option is used, op->fast_work and op->processor must be
+     initialised before submitting the operation:
+
+		INIT_WORK(&op->fast_work, do_some_work);
+
+
+ (3) The operation may be slow asynchronous (FSCACHE_OP_SLOW), in which case it
+     will be given to the slow work facility to process.  Such an operation is
+     permitted to sleep on I/O.
+
+     This is, for example, used by FS-Cache to handle background writes of
+     pages that have just been fetched from a remote server.
+
+     If this option is used, op->slow_work and op->processor must be
+     initialised before submitting the operation:
+
+		fscache_operation_init_slow(op, processor)
+
+
+Furthermore, operations may be one of two types:
+
+ (1) Exclusive (FSCACHE_OP_EXCLUSIVE).  Operations of this type may not run in
+     conjunction with any other operation on the object being operated upon.
+
+     An example of this is the attribute change operation, in which the file
+     being written to may need truncation.
+
+ (2) Shareable.  Operations of this type may be running simultaneously.  It's
+     up to the operation implementation to prevent interference between other
+     operations running at the same time.
+
+
+=========
+PROCEDURE
+=========
+
+Operations are used through the following procedure:
+
+ (1) The submitting thread must allocate the operation and initialise it
+     itself.  Normally this would be part of a more specific structure with the
+     generic op embedded within.
+
+ (2) The submitting thread must then submit the operation for processing using
+     one of the following two functions:
+
+	int fscache_submit_op(struct fscache_object *object,
+			      struct fscache_operation *op);
+
+	int fscache_submit_exclusive_op(struct fscache_object *object,
+					struct fscache_operation *op);
+
+     The first function should be used to submit non-exclusive ops and the
+     second to submit exclusive ones.  The caller must still set the
+     FSCACHE_OP_EXCLUSIVE flag.
+
+     If successful, both functions will assign the operation to the specified
+     object and return 0.  -ENOBUFS will be returned if the object specified is
+     permanently unavailable.
+
+     The operation manager will defer operations on an object that is still
+     undergoing lookup or creation.  The operation will also be deferred if an
+     operation of conflicting exclusivity is in progress on the object.
+
+     If the operation is asynchronous, the manager will retain a reference to
+     it, so the caller should put their reference to it by passing it to:
+
+	void fscache_put_operation(struct fscache_operation *op);
+
+ (3) If the submitting thread wants to do the work itself, and has marked the
+     operation with FSCACHE_OP_MYTHREAD, then it should monitor
+     FSCACHE_OP_WAITING as described above and check the state of the object if
+     necessary (the object might have died whilst the thread was waiting).
+
+     When it has finished doing its processing, it should call
+     fscache_put_operation() on it.
+
+ (4) The operation holds an effective lock upon the object, preventing other
+     exclusive ops conflicting until it is released.  The operation can be
+     enqueued for further immediate asynchronous processing by adjusting the
+     CPU time provisioning option if necessary, eg:
+
+	op->flags &= ~FSCACHE_OP_TYPE;
+	op->flags |= ~FSCACHE_OP_FAST;
+
+     and calling:
+
+	void fscache_enqueue_operation(struct fscache_operation *op)
+
+     This can be used to allow other things to have use of the worker thread
+     pools.
+
+
+=====================
+ASYNCHRONOUS CALLBACK
+=====================
+
+When used in asynchronous mode, the worker thread pool will invoke the
+processor method with a pointer to the operation.  This should then get at the
+container struct by using container_of():
+
+	static void fscache_write_op(struct fscache_operation *_op)
+	{
+		struct fscache_storage *op =
+			container_of(_op, struct fscache_storage, op);
+	...
+	}
+
+The caller holds a reference on the operation, and will invoke
+fscache_put_operation() when the processor function returns.  The processor
+function is at liberty to call fscache_enqueue_operation() or to take extra
+references.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/exofs.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/exofs.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/exofs.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/exofs.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,176 @@
+===============================================================================
+WHAT IS EXOFS?
+===============================================================================
+
+exofs is a file system that uses an OSD and exports the API of a normal Linux
+file system. Users access exofs like any other local file system, and exofs
+will in turn issue commands to the local OSD initiator.
+
+OSD is a new T10 command set that views storage devices not as a large/flat
+array of sectors but as a container of objects, each having a length, quota,
+time attributes and more. Each object is addressed by a 64bit ID, and is
+contained in a 64bit ID partition. Each object has associated attributes
+attached to it, which are integral part of the object and provide metadata about
+the object. The standard defines some common obligatory attributes, but user
+attributes can be added as needed.
+
+===============================================================================
+ENVIRONMENT
+===============================================================================
+
+To use this file system, you need to have an object store to run it on.  You
+may download a target from:
+http://open-osd.org
+
+See Documentation/scsi/osd.txt for how to setup a working osd environment.
+
+===============================================================================
+USAGE
+===============================================================================
+
+1. Download and compile exofs and open-osd initiator:
+  You need an external Kernel source tree or kernel headers from your
+  distribution. (anything based on 2.6.26 or later).
+
+  a. download open-osd including exofs source using:
+     [parent-directory]$ git clone git://git.open-osd.org/open-osd.git
+
+  b. Build the library module like this:
+     [parent-directory]$ make -C KSRC=$(KER_DIR) open-osd
+
+     This will build both the open-osd initiator as well as the exofs kernel
+     module. Use whatever parameters you compiled your Kernel with and
+     $(KER_DIR) above pointing to the Kernel you compile against. See the file
+     open-osd/top-level-Makefile for an example.
+
+2. Get the OSD initiator and target set up properly, and login to the target.
+  See Documentation/scsi/osd.txt for farther instructions. Also see ./do-osd
+  for example script that does all these steps.
+
+3. Insmod the exofs.ko module:
+   [exofs]$ insmod exofs.ko
+
+4. Make sure the directory where you want to mount exists. If not, create it.
+   (For example, mkdir /mnt/exofs)
+
+5. At first run you will need to invoke the mkfs.exofs application
+
+   As an example, this will create the file system on:
+   /dev/osd0 partition ID 65536
+
+   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,
+   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.
+
+   An exofs lives inside a single OSD partition. You can create multiple exofs
+   filesystems on the same device using multiple pids.
+
+   (run mkfs.exofs without any parameters for usage help message)
+
+6. Mount the file system.
+
+   For example, to mount /dev/osd0, partition ID 0x10000 on /mnt/exofs:
+
+	mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/
+
+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 format - an example of how to format and mkfs a new exofs.
+
+8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
+	CONFIG_EXOFS_DEBUG - for debug messages and extra checks.
+
+===============================================================================
+exofs mount options
+===============================================================================
+Similar to any mount command:
+	mount -t exofs -o exofs_options /dev/osdX mount_exofs_directory
+
+Where:
+    -t exofs: specifies the exofs file system
+
+    /dev/osdX: X is a decimal number. /dev/osdX was created after a successful
+               login into an OSD target.
+
+    mount_exofs_directory: The directory to mount the file system on
+
+    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
+                                default is (60 * HZ) [for debugging only]
+
+===============================================================================
+DESIGN
+===============================================================================
+
+* The file system control block (AKA on-disk superblock) resides in an object
+  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's magic number
+	- The next inode number to be allocated
+
+* Each file resides in its own object and contains the data (and it will be
+  possible to extend the file over multiple objects, though this has not been
+  implemented yet).
+
+* A directory is treated as a file, and essentially contains a list of <file
+  name, inode #> pairs for files that are found in that directory. The object
+  IDs correspond to the files' inode numbers and will be allocated according to
+  a bitmap (stored in a separate object). Now they are allocated using a
+  counter.
+
+* Each file's control block (AKA on-disk inode) is stored in its object's
+  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
+  operations and is used as long as the object remains in memory.
+
+* Async OSD operations are used whenever possible, but the target may execute
+  them out of order. The operations that concern us are create, delete,
+  readpage, writepage, update_inode, and truncate. The following pairs of
+  operations should execute in the order written, and we need to prevent them
+  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.
+	  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
+		  on the OSD.
+		- create/readpage: readpage should be able to return a page
+		  full of zeroes in this case. If there was a write already
+		  en-route (i.e. create, writepage, readpage) then the page
+		  would be locked, and so it would really be the same as
+		  create/writepage.
+		- create/writepage: if writepage is called for a sync write, it
+		  should wait until the object is created on the OSD.
+		  Otherwise, it should just return.
+		- create/truncate: truncate should wait until the object is
+		  created on the OSD.
+		- create/update_inode: update_inode should wait until the
+		  object is created on the OSD.
+	- Handled by VFS locks:
+		- readpage/delete: shouldn't happen because of page lock.
+		- writepage/delete: shouldn't happen because of page lock.
+		- readpage/writepage: shouldn't happen because of page lock.
+
+===============================================================================
+LICENSE/COPYRIGHT
+===============================================================================
+The exofs file system is based on ext2 v0.5b (distributed with the Linux kernel
+version 2.6.10).  All files include the original copyrights, and the license
+is GPL version 2 (only version 2, as is true for the Linux kernel).  The
+Linux kernel can be downloaded from www.kernel.org.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/ext3.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/ext3.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/ext3.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/ext3.txt	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,11 @@ Options
 When mounting an ext3 filesystem, the following option are accepted:
 (*) == default
 
+ro			Mount filesystem read only. Note that ext3 will replay
+			the journal (and thus write to the partition) even when
+			mounted "read only". Mount options "ro,noload" can be
+			used to prevent writes to the filesystem.
+
 journal=update		Update the ext3 file system's journal to the current
 			format.
 
@@ -27,7 +32,9 @@ 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.
+noload			Don't load the journal on mounting. Note that this forces
+			mount of inconsistent filesystem, which can lead to
+			various problems.
 
 data=journal		All data are committed into the journal prior to being
 			written into the main file system.
@@ -92,9 +99,12 @@ nocheck
 
 debug			Extra debugging information is sent to syslog.
 
-errors=remount-ro(*)	Remount the filesystem read-only on an error.
+errors=remount-ro	Remount the filesystem read-only on an error.
 errors=continue		Keep going on a filesystem error.
 errors=panic		Panic and halt the machine if an error occurs.
+			(These mount options override the errors behavior
+			specified in the superblock, which can be
+			configured using tune2fs.)
 
 data_err=ignore(*)	Just print an error message if an error occurs
 			in a file data buffer in ordered mode.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/ext4.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/ext4.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/ext4.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/ext4.txt	2009-06-09 23:05:27.000000000 -0400
@@ -85,7 +85,7 @@ Note: More extensive information for get
 * extent format more robust in face of on-disk corruption due to magics,
 * internal redundancy in tree
 * improved file allocation (multi-block alloc)
-* fix 32000 subdirectory limit
+* lift 32000 subdirectory limit imposed by i_links_count[1]
 * nsec timestamps for mtime, atime, ctime, create time
 * inode version field on disk (NFSv4, Lustre)
 * reduced e2fsck time via uninit_bg feature
@@ -100,6 +100,9 @@ Note: More extensive information for get
 * efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
   the ordering)
 
+[1] Filesystems with a block size of 1k may see a limit imposed by the
+directory hash tree having a maximum depth of two.
+
 2.2 Candidate features for future inclusion
 
 * Online defrag (patches available but not well tested)
@@ -180,8 +183,8 @@ commit=nrsec	(*)	Ext4 can be told to syn
 			performance.
 
 barrier=<0|1(*)>	This enables/disables the use of write barriers in
-			the jbd code.  barrier=0 disables, barrier=1 enables.
-			This also requires an IO stack which can support
+barrier(*)		the jbd code.  barrier=0 disables, barrier=1 enables.
+nobarrier		This also requires an IO stack which can support
 			barriers, and if jbd gets an error on a barrier
 			write, it will disable again with a warning.
 			Write barriers enforce proper on-disk ordering
@@ -189,6 +192,9 @@ barrier=<0|1(*)>	This enables/disables t
 			safe to use, at some performance penalty.  If
 			your disks are battery-backed in one way or another,
 			disabling barriers may safely improve performance.
+			The mount options "barrier" and "nobarrier" can
+			also be used to enable or disable barriers, for
+			consistency with other ext4 mount options.
 
 inode_readahead=n	This tuning parameter controls the maximum
 			number of inode table blocks that ext4's inode
@@ -310,6 +316,24 @@ journal_ioprio=prio	The I/O priority (fr
 			a slightly higher priority than the default I/O
 			priority.
 
+auto_da_alloc(*)	Many broken applications don't use fsync() when 
+noauto_da_alloc		replacing existing files via patterns such as
+			fd = open("foo.new")/write(fd,..)/close(fd)/
+			rename("foo.new", "foo"), or worse yet,
+			fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
+			If auto_da_alloc is enabled, ext4 will detect
+			the replace-via-rename and replace-via-truncate
+			patterns and force that any delayed allocation
+			blocks are allocated such that at the next
+			journal commit, in the default data=ordered
+			mode, the data blocks of the new file are forced
+			to disk before the rename() operation is
+			commited.  This provides roughly the same level
+			of guarantees as ext3, and avoids the
+			"zero-length" problem that can happen when a
+			system crashes before the delayed allocation
+			blocks are forced to disk.
+
 Data Mode
 =========
 There are 3 different data modes:
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/knfsd-stats.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/knfsd-stats.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/knfsd-stats.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/knfsd-stats.txt	2009-06-09 23:05:27.000000000 -0400
@@ -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.29-gnu1/Documentation/filesystems/Locking linux-libre-2.6.30-gnu1/Documentation/filesystems/Locking
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/Locking	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/Locking	2009-06-09 23:05:27.000000000 -0400
@@ -437,8 +437,11 @@ grab BKL for cases when we close a file
 can and should be done using the internal locking with smaller critical areas).
 Current worst offender is ext2_get_block()...
 
-->fasync() is a mess. This area needs a big cleanup and that will probably
-affect locking.
+->fasync() is called without BKL protection, and is responsible for
+maintaining the FASYNC bit in filp->f_flags.  Most instances call
+fasync_helper(), which does that maintenance, so it's not normally
+something one needs to worry about.  Return values > 0 will be mapped to
+zero in the VFS layer.
 
 ->readdir() and ->ioctl() on directories must be changed. Ideally we would
 move ->readdir() to inode_operations and use a separate method for directory
@@ -502,23 +505,31 @@ prototypes:
 	void (*open)(struct vm_area_struct*);
 	void (*close)(struct vm_area_struct*);
 	int (*fault)(struct vm_area_struct*, struct vm_fault *);
-	int (*page_mkwrite)(struct vm_area_struct *, struct page *);
+	int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
 	int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
 
 locking rules:
 		BKL	mmap_sem	PageLocked(page)
 open:		no	yes
 close:		no	yes
-fault:		no	yes
-page_mkwrite:	no	yes		no
+fault:		no	yes		can return with page locked
+page_mkwrite:	no	yes		can return with page locked
 access:		no	yes
 
-	->page_mkwrite() is called when a previously read-only page is
-about to become writeable. The file system is responsible for
-protecting against truncate races. Once appropriate action has been
-taking to lock out truncate, the page range should be verified to be
-within i_size. The page mapping should also be checked that it is not
-NULL.
+	->fault() is called when a previously not present pte is about
+to be faulted in. The filesystem must find and return the page associated
+with the passed in "pgoff" in the vm_fault structure. If it is possible that
+the page may be truncated and/or invalidated, then the filesystem must lock
+the page, then ensure it is not already truncated (the page lock will block
+subsequent truncate), and then return with VM_FAULT_LOCKED, and the page
+locked. The VM will unlock the page.
+
+	->page_mkwrite() is called when a previously read-only pte is
+about to become writeable. The filesystem again must ensure that there are
+no truncate/invalidate races, and then return with the page locked. If
+the page has been truncated, the filesystem should not look up a new page
+like the ->fault() handler, but simply return with VM_FAULT_NOPAGE, which
+will cause the VM to retry the fault.
 
 	->access() is called when get_user_pages() fails in
 acces_process_vm(), typically used to debug a process through
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/nfs41-server.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/nfs41-server.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/nfs41-server.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/nfs41-server.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,161 @@
+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)
+
+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 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:
+
+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.29-gnu1/Documentation/filesystems/nilfs2.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/nilfs2.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/nilfs2.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/nilfs2.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,200 @@
+NILFS2
+------
+
+NILFS2 is a log-structured file system (LFS) supporting continuous
+snapshotting.  In addition to versioning capability of the entire file
+system, users can even restore files mistakenly overwritten or
+destroyed just a few seconds ago.  Since NILFS2 can keep consistency
+like conventional LFS, it achieves quick recovery after system
+crashes.
+
+NILFS2 creates a number of checkpoints every few seconds or per
+synchronous write basis (unless there is no change).  Users can select
+significant versions among continuously created checkpoints, and can
+change them into snapshots which will be preserved until they are
+changed back to checkpoints.
+
+There is no limit on the number of snapshots until the volume gets
+full.  Each snapshot is mountable as a read-only file system
+concurrently with its writable mount, and this feature is convenient
+for online backup.
+
+The userland tools are included in nilfs-utils package, which is
+available from the following download page.  At least "mkfs.nilfs2",
+"mount.nilfs2", "umount.nilfs2", and "nilfs_cleanerd" (so called
+cleaner or garbage collector) are required.  Details on the tools are
+described in the man pages included in the package.
+
+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
+
+Caveats
+=======
+
+Features which NILFS2 does not support yet:
+
+	- atime
+	- extended attributes
+	- POSIX ACLs
+	- quotas
+	- writable snapshots
+	- remote backup (CDP)
+	- data integrity
+	- defragmentation
+
+Mount options
+=============
+
+NILFS2 supports the following mount options:
+(*) == default
+
+barrier=on(*)		This enables/disables barriers. barrier=off disables
+			it, barrier=on enables it.
+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.
+cp=n			Specify the checkpoint-number of the snapshot to be
+			mounted.  Checkpoints and snapshots are listed by lscp
+			user command.  Only the checkpoints marked as snapshot
+			are mountable with this option.  Snapshot is read-only,
+			so a read-only mount option must be specified together.
+order=relaxed(*)	Apply relaxed order semantics that allows modified data
+			blocks to be written to disk without making a
+			checkpoint if no metadata update is going.  This mode
+			is equivalent to the ordered data mode of the ext3
+			filesystem except for the updates on data blocks still
+			conserve atomicity.  This will improve synchronous
+			write performance for overwriting.
+order=strict		Apply strict in-order semantics that preserves sequence
+			of all file operations including overwriting of data
+			blocks.  That means, it is guaranteed that no
+			overtaking of events occurs in the recovered file
+			system after a crash.
+
+NILFS2 usage
+============
+
+To use nilfs2 as a local file system, simply:
+
+ # mkfs -t nilfs2 /dev/block_device
+ # mount -t nilfs2 /dev/block_device /dir
+
+This will also invoke the cleaner through the mount helper program
+(mount.nilfs2).
+
+Checkpoints and snapshots are managed by the following commands.
+Their manpages are included in the nilfs-utils package above.
+
+  lscp     list checkpoints or snapshots.
+  mkcp     make a checkpoint or a snapshot.
+  chcp     change an existing checkpoint to a snapshot or vice versa.
+  rmcp     invalidate specified checkpoint(s).
+
+To mount a snapshot,
+
+ # mount -t nilfs2 -r -o cp=<cno> /dev/block_device /snap_dir
+
+where <cno> is the checkpoint number of the snapshot.
+
+To unmount the NILFS2 mount point or snapshot, simply:
+
+ # umount /dir
+
+Then, the cleaner daemon is automatically shut down by the umount
+helper program (umount.nilfs2).
+
+Disk format
+===========
+
+A nilfs2 volume is equally divided into a number of segments except
+for the super block (SB) and segment #0.  A segment is the container
+of logs.  Each log is composed of summary information blocks, payload
+blocks, and an optional super root block (SR):
+
+   ______________________________________________________
+  | |SB| | Segment | Segment | Segment | ... | Segment | |
+  |_|__|_|____0____|____1____|____2____|_____|____N____|_|
+  0 +1K +4K       +8M       +16M      +24M  +(8MB x N)
+       .             .            (Typical offsets for 4KB-block)
+    .                  .
+  .______________________.
+  | log | log |... | log |
+  |__1__|__2__|____|__m__|
+        .       .
+      .               .
+    .                       .
+  .______________________________.
+  | Summary | Payload blocks  |SR|
+  |_blocks__|_________________|__|
+
+The payload blocks are organized per file, and each file consists of
+data blocks and B-tree node blocks:
+
+    |<---       File-A        --->|<---       File-B        --->|
+   _______________________________________________________________
+    | Data blocks | B-tree blocks | Data blocks | B-tree blocks | ...
+   _|_____________|_______________|_____________|_______________|_
+
+
+Since only the modified blocks are written in the log, it may have
+files without data blocks or B-tree node blocks.
+
+The organization of the blocks is recorded in the summary information
+blocks, which contains a header structure (nilfs_segment_summary), per
+file structures (nilfs_finfo), and per block structures (nilfs_binfo):
+
+  _________________________________________________________________________
+ | Summary | finfo | binfo | ... | binfo | finfo | binfo | ... | binfo |...
+ |_blocks__|___A___|_(A,1)_|_____|(A,Na)_|___B___|_(B,1)_|_____|(B,Nb)_|___
+
+
+The logs include regular files, directory files, symbolic link files
+and several meta data files.  The mata data files are the files used
+to maintain file system meta data.  The current version of NILFS2 uses
+the following meta data files:
+
+ 1) Inode file (ifile)             -- Stores on-disk inodes
+ 2) Checkpoint file (cpfile)       -- Stores checkpoints
+ 3) Segment usage file (sufile)    -- Stores allocation state of segments
+ 4) Data address translation file  -- Maps virtual block numbers to usual
+    (DAT)                             block numbers.  This file serves to
+                                      make on-disk blocks relocatable.
+
+The following figure shows a typical organization of the logs:
+
+  _________________________________________________________________________
+ | Summary | regular file | file  | ... | ifile | cpfile | sufile | DAT |SR|
+ |_blocks__|_or_directory_|_______|_____|_______|________|________|_____|__|
+
+
+To stride over segment boundaries, this sequence of files may be split
+into multiple logs.  The sequence of logs that should be treated as
+logically one log, is delimited with flags marked in the segment
+summary.  The recovery code of nilfs2 looks this boundary information
+to ensure atomicity of updates.
+
+The super root block is inserted for every checkpoints.  It includes
+three special inodes, inodes for the DAT, cpfile, and sufile.  Inodes
+of regular files, directories, symlinks and other special files, are
+included in the ifile.  The inode of ifile itself is included in the
+corresponding checkpoint entry in the cpfile.  Thus, the hierarchy
+among NILFS2 files can be depicted as follows:
+
+  Super block (SB)
+       |
+       v
+  Super root block (the latest cno=xx)
+       |-- DAT
+       |-- sufile
+       `-- cpfile
+              |-- ifile (cno=c1)
+              |-- ifile (cno=c2) ---- file (ino=i1)
+              :        :          |-- file (ino=i2)
+              `-- ifile (cno=xx)  |-- file (ino=i3)
+                                  :        :
+                                  `-- file (ino=yy)
+                                    ( regular file, directory, or symlink )
+
+For detail on the format of each file, please see include/linux/nilfs2_fs.h.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/design_notes.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/design_notes.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/design_notes.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/design_notes.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,71 @@
+POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
+
+		Evgeniy Polyakov <zbr@ioremap.net>
+
+Homepage: http://www.ioremap.net/projects/pohmelfs
+
+POHMELFS first began as a network filesystem with coherent local data and
+metadata caches but is now evolving into a parallel distributed filesystem.
+
+Main features of this FS include:
+ * Locally coherent cache for data and metadata with (potentially) byte-range locks.
+	Since all Linux filesystems lock the whole inode during writing, algorithm
+	is very simple and does not use byte-ranges, although they are sent in
+	locking messages.
+ * Completely async processing of all events except creation of hard and symbolic
+	links, and rename events.
+	Object creation and data reading and writing are processed asynchronously.
+ * Flexible object architecture optimized for network processing.
+	Ability to create long paths to objects and remove arbitrarily huge
+	directories with a single network command.
+	(like removing the whole kernel tree via a single network command).
+ * Very high performance.
+ * Fast and scalable multithreaded userspace server. Being in userspace it works
+	with any underlying filesystem and still is much faster than async in-kernel NFS one.
+ * Client is able to switch between different servers (if one goes down, client
+	automatically reconnects to second and so on).
+ * Transactions support. Full failover for all operations.
+	Resending transactions to different servers on timeout or error.
+ * Read request (data read, directory listing, lookup requests) balancing between multiple servers.
+ * Write requests are replicated to multiple servers and completed only when all of them are acked.
+ * Ability to add and/or remove servers from the working set at run-time.
+ * Strong authentification and possible data encryption in network channel.
+ * Extended attributes support.
+
+POHMELFS is based on transactions, which are potentially long-standing objects that live
+in the client's memory. Each transaction contains all the information needed to process a given
+command (or set of commands, which is frequently used during data writing: single transactions
+can contain creation and data writing commands). Transactions are committed by all the servers
+to which they are sent and, in case of failures, are eventually resent or dropped with an error.
+For example, reading will return an error if no servers are available.
+
+POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
+possible to detach replies from requests and, if the command requires data to be received, the
+caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
+servers and async threads will pick up replies in parallel, find appropriate transactions in the
+system and put the data where it belongs (like the page or inode cache).
+
+The main feature of POHMELFS is writeback data and the metadata cache.
+Only a few non-performance critical operations use the write-through cache and
+are synchronous: hard and symbolic link creation, and object rename. Creation,
+removal of objects and data writing are asynchronous and are sent to
+the server during system writeback. Only one writer at a time is allowed for any
+given inode, which is guarded by an appropriate locking protocol.
+Because of this feature, POHMELFS is extremely fast at metadata intensive
+workloads and can fully utilize the bandwidth to the servers when doing bulk
+data transfers.
+
+POHMELFS clients operate with a working set of servers and are capable of balancing read-only
+operations (like lookups or directory listings) between them according to IO priorities.
+Administrators can add or remove servers from the set at run-time via special commands (described
+in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers, which are connected
+with write permission turned on. IO priority and permissions can be changed in run-time.
+
+POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
+One can select any kernel supported cipher, encryption mode, hash type and operation mode
+(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
+is checked during mount time and, if the server does not support it, appropriate capabilities
+will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
+Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
+crypto operations and send the resulting data to server or submit it up the stack. This number
+can be controlled via a mount option.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/info.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/info.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/info.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/info.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,99 @@
+POHMELFS usage information.
+
+Mount options.
+All but index, number of crypto threads and maximum IO size can changed via remount.
+
+idx=%u
+ Each mountpoint is associated with a special index via this option.
+ Administrator can add or remove servers from the given index, so all mounts,
+ which were attached to it, are updated.
+ Default it is 0.
+
+trans_scan_timeout=%u
+ This timeout, expressed in milliseconds, specifies time to scan transaction
+ trees looking for stale requests, which have to be resent, or if number of
+ retries exceed specified limit, dropped with error.
+ Default is 5 seconds.
+
+drop_scan_timeout=%u
+ Internal timeout, expressed in milliseconds, which specifies how frequently
+ inodes marked to be dropped are freed. It also specifies how frequently
+ the system checks that servers have to be added or removed from current working set.
+ Default is 1 second.
+
+wait_on_page_timeout=%u
+ Number of milliseconds to wait for reply from remote server for data reading command.
+ If this timeout is exceeded, reading returns an error.
+ Default is 5 seconds.
+
+trans_retries=%u
+ This is the number of times that a transaction will be resent to a server that did
+ not answer for the last @trans_scan_timeout milliseconds.
+ When the number of resends exceeds this limit, the transaction is completed with error.
+ Default is 5 resends.
+
+crypto_thread_num=%u
+ Number of crypto processing threads. Threads are used both for RX and TX traffic.
+ Default is 2, or no threads if crypto operations are not supported.
+
+trans_max_pages=%u
+ Maximum number of pages in a single transaction. This parameter also controls
+ the number of pages,  allocated for crypto processing (each crypto thread has
+ pool of pages, the number of which is equal to 'trans_max_pages'.
+ Default is 100 pages.
+
+crypto_fail_unsupported
+ If specified, mount will fail if the server does not support requested crypto operations.
+ By default mount will disable non-matching crypto operations.
+
+mcache_timeout=%u
+ Maximum number of milliseconds to wait for the mcache objects to be processed.
+ Mcache includes locks (given lock should be granted by server), attributes (they should be
+ fully received in the given timeframe).
+ Default is 5 seconds.
+
+Usage examples.
+
+Add server server1.net:1025 into the working set with index $idx
+with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
+$cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
+
+Mount filesystem with given index $idx to /mnt mountpoint.
+Client will connect to all servers specified in the working set via previous command:
+mount -t pohmel -o idx=$idx q /mnt
+
+Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw):
+$cfg A modify -a server1.net -p 1025 -i $idx -I 1
+
+Change IO priority to 123 (node with the highest priority gets read requests).
+$cfg A modify -a server1.net -p 1025 -i $idx -P 123
+
+One can check currect status of all connections in the mountstats file:
+# cat /proc/$PID/mountstats
+...
+device none mounted on /mnt with fstype pohmel
+idx addr(:port) socket_type protocol active priority permissions
+0 server1.net:1026 1 6 1 250 1
+0 server2.net:1025 1 6 1 123 3
+
+Server installation.
+
+Creating a server, which listens at port 1025 and 0.0.0.0 address.
+Working root directory (note, that server chroots there, so you have to have appropriate permissions)
+is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
+are appropriate key files.
+Number of working threads is set to 10.
+
+# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
+
+ -A 6			 - listen on ipv6 address. Default: Disabled.
+ -r root                 - path to root directory. Default: /tmp.
+ -a addr                 - listen address. Default: 0.0.0.0.
+ -p port                 - listen port. Default: 1025.
+ -w workers              - number of workers per connected client. Default: 1.
+ -K file		 - hash key size. Default: none.
+ -k file		 - cipher key size. Default: none.
+ -h                      - this help.
+
+Number of worker threads specifies how many workers will be created for each client.
+Bulk single-client transafers usually are better handled with smaller number (like 1-3).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/network_protocol.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/network_protocol.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/pohmelfs/network_protocol.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/pohmelfs/network_protocol.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,227 @@
+POHMELFS network protocol.
+
+Basic structure used in network communication is following command:
+
+struct netfs_cmd
+{
+	__u16			cmd;	/* Command number */
+	__u16			csize;	/* Attached crypto information size */
+	__u16			cpad;	/* Attached padding size */
+	__u16			ext;	/* External flags */
+	__u32			size;	/* Size of the attached data */
+	__u32			trans;	/* Transaction id */
+	__u64			id;	/* Object ID to operate on. Used for feedback.*/
+	__u64			start;	/* Start of the object. */
+	__u64			iv;	/* IV sequence */
+	__u8			data[0];
+};
+
+Commands can be embedded into transaction command (which in turn has own command),
+so one can extend protocol as needed without breaking backward compatibility as long
+as old commands are supported. All string lengths include tail 0 byte.
+
+All commans are transfered over the network in big-endian. CPU endianess is used at the end peers.
+
+@cmd - command number, which specifies command to be processed. Following
+	commands are used currently:
+
+	NETFS_READDIR	= 1,	/* Read directory for given inode number */
+	NETFS_READ_PAGE,	/* Read data page from the server */
+	NETFS_WRITE_PAGE,	/* Write data page to the server */
+	NETFS_CREATE,		/* Create directory entry */
+	NETFS_REMOVE,		/* Remove directory entry */
+	NETFS_LOOKUP,		/* Lookup single object */
+	NETFS_LINK,		/* Create a link */
+	NETFS_TRANS,		/* Transaction */
+	NETFS_OPEN,		/* Open intent */
+	NETFS_INODE_INFO,	/* Metadata cache coherency synchronization message */
+	NETFS_PAGE_CACHE,	/* Page cache invalidation message */
+	NETFS_READ_PAGES,	/* Read multiple contiguous pages in one go */
+	NETFS_RENAME,		/* Rename object */
+	NETFS_CAPABILITIES,	/* Capabilities of the client, for example supported crypto */
+	NETFS_LOCK,		/* Distributed lock message */
+	NETFS_XATTR_SET,	/* Set extended attribute */
+	NETFS_XATTR_GET,	/* Get extended attribute */
+
+@ext - external flags. Used by different commands to specify some extra arguments
+	like partial size of the embedded objects or creation flags.
+
+@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
+	but size of the requested data is incorporated here. It does not include size of the command
+	header (struct netfs_cmd) itself.
+
+@id - id of the object this command operates on. Each command can use it for own purpose.
+
+@start - start of the object this command operates on. Each command can use it for own purpose.
+
+@csize, @cpad - size and padding size of the (attached if needed) crypto information.
+
+Command specifications.
+
+@NETFS_READDIR
+This command is used to sync content of the remote dir to the client.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to read.
+@start - zero.
+
+
+@NETFS_READ_PAGE
+This command is used to read data from remote server.
+Data size does not exceed local page cache size.
+
+@id - inode number.
+@start - first byte offset.
+@size - number of bytes to read plus length of the path to object.
+@ext - object path length.
+
+
+@NETFS_CREATE
+Used to create object.
+It does not require that all directories on top of the object were
+already created, it will create them automatically. Each object has
+associated @netfs_path_entry data structure, which contains creation
+mode (permissions and type) and length of the name as long as name itself.
+
+@start - 0
+@size - size of the all data structures needed to create a path
+@id - local inode number
+@ext - 0
+
+
+@NETFS_REMOVE
+Used to remove object.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number.
+@start - zero.
+
+
+@NETFS_LOOKUP
+Lookup information about object on server.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to look object in.
+@start - local inode number of the object to look at.
+
+
+@NETFS_LINK
+Create hard of symlink.
+Command is sent as "object_path|target_path".
+
+@size - size of the above string.
+@id - parent local inode number.
+@start - 1 for symlink, 0 for hardlink.
+@ext - size of the "object_path" above.
+
+
+@NETFS_TRANS
+Transaction header.
+
+@size - incorporates all embedded command sizes including theirs header sizes.
+@start - transaction generation number - unique id used to find transaction.
+@ext - transaction flags. Unused at the moment.
+@id - 0.
+
+
+@NETFS_OPEN
+Open intent for given transaction.
+
+@id - local inode number.
+@start - 0.
+@size - path length to the object.
+@ext - open flags (O_RDWR and so on).
+
+
+@NETFS_INODE_INFO
+Metadata update command.
+It is sent to servers when attributes of the object are changed and received
+when data or metadata were updated. It operates with the following structure:
+
+struct netfs_inode_info
+{
+	unsigned int		mode;
+	unsigned int		nlink;
+	unsigned int		uid;
+	unsigned int		gid;
+	unsigned int		blocksize;
+	unsigned int		padding;
+	__u64			ino;
+	__u64			blocks;
+	__u64			rdev;
+	__u64			size;
+	__u64			version;
+};
+
+It effectively mirrors stat(2) returned data.
+
+
+@ext - path length to the object.
+@size - the same plus size of the netfs_inode_info structure.
+@id - local inode number.
+@start - 0.
+
+
+@NETFS_PAGE_CACHE
+Command is only received by clients. It contains information about
+page to be marked as not up-to-date.
+
+@id - client's inode number.
+@start - last byte of the page to be invalidated. If it is not equal to
+	current inode size, it will be vmtruncated().
+@size - 0
+@ext - 0
+
+
+@NETFS_READ_PAGES
+Used to read multiple contiguous pages in one go.
+
+@start - first byte of the contiguous region to read.
+@size - contains of two fields: lower 8 bits are used to represent page cache shift
+	used by client, another 3 bytes are used to get number of pages.
+@id - local inode number.
+@ext - path length to the object.
+
+
+@NETFS_RENAME
+Used to rename object.
+Attached data is formed into following string: "old_path|new_path".
+
+@id - local inode number.
+@start - parent inode number.
+@size - length of the above string.
+@ext - length of the old path part.
+
+
+@NETFS_CAPABILITIES
+Used to exchange crypto capabilities with server.
+If crypto capabilities are not supported by server, then client will disable it
+or fail (if 'crypto_fail_unsupported' mount options was specified).
+
+@id - superblock index. Used to specify crypto information for group of servers.
+@size - size of the attached capabilities structure.
+@start - 0.
+@size - 0.
+@scsize - 0.
+
+@NETFS_LOCK
+Used to send lock request/release messages. Although it sends byte range request
+and is capable of flushing pages based on that, it is not used, since all Linux
+filesystems lock the whole inode.
+
+@id - lock generation number.
+@start - start of the locked range.
+@size - size of the locked range.
+@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
+	if it is lock request (1) or release (0).
+
+@NETFS_XATTR_SET
+@NETFS_XATTR_GET
+Used to set/get extended attributes for given inode.
+@id - attribute generation number or xattr setting type
+@start - size of the attribute (request or attached)
+@size - name length, path len and data size for given attribute
+@ext - path length for given object
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/proc.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/proc.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/proc.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/proc.txt	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
                   Bodo Bauer <bb@ricochet.net>
 
 2.4.x update	  Jorge Nerin <comandante@zaralinux.com>      November 14 2000
+move /proc/sys	  Shen Feng <shen@cn.fujitsu.com>		    April 1 2009
 ------------------------------------------------------------------------------
 Version 1.3                                              Kernel version 2.2.12
 					      Kernel version 2.4.0-test11-pre4
@@ -26,25 +27,17 @@ Table of Contents
   1.6	Parallel port info in /proc/parport
   1.7	TTY info in /proc/tty
   1.8	Miscellaneous kernel statistics in /proc/stat
+  1.9 Ext4 file system parameters
 
   2	Modifying System Parameters
-  2.1	/proc/sys/fs - File system data
-  2.2	/proc/sys/fs/binfmt_misc - Miscellaneous binary formats
-  2.3	/proc/sys/kernel - general kernel parameters
-  2.4	/proc/sys/vm - The virtual memory subsystem
-  2.5	/proc/sys/dev - Device specific parameters
-  2.6	/proc/sys/sunrpc - Remote procedure calls
-  2.7	/proc/sys/net - Networking stuff
-  2.8	/proc/sys/net/ipv4 - IPV4 settings
-  2.9	Appletalk
-  2.10	IPX
-  2.11	/proc/sys/fs/mqueue - POSIX message queues filesystem
-  2.12	/proc/<pid>/oom_adj - Adjust the oom-killer score
-  2.13	/proc/<pid>/oom_score - Display current oom-killer score
-  2.14	/proc/<pid>/io - Display the IO accounting fields
-  2.15	/proc/<pid>/coredump_filter - Core dump filtering settings
-  2.16	/proc/<pid>/mountinfo - Information about mounts
-  2.17	/proc/sys/fs/epoll - Configuration options for the epoll interface
+
+  3	Per-Process Parameters
+  3.1	/proc/<pid>/oom_adj - Adjust the oom-killer score
+  3.2	/proc/<pid>/oom_score - Display current oom-killer score
+  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
+
 
 ------------------------------------------------------------------------------
 Preface
@@ -940,27 +933,6 @@ Table 1-10: Files in /proc/fs/ext4/<devn
  File            Content                                        
  mb_groups       details of multiblock allocator buddy cache of free blocks
  mb_history      multiblock allocation history
- stats           controls whether the multiblock allocator should start
-                 collecting statistics, which are shown during the unmount
- group_prealloc  the multiblock allocator will round up allocation
-                 requests to a multiple of this tuning parameter if the
-                 stripe size is not set in the ext4 superblock
- max_to_scan     The maximum number of extents the multiblock allocator
-                 will search to find the best extent
- min_to_scan     The minimum number of extents the multiblock allocator
-                 will search to find the best extent
- order2_req      Tuning parameter which controls the minimum size for 
-                 requests (as a power of 2) where the buddy cache is
-                 used
- stream_req      Files which have fewer blocks than this tunable
-                 parameter will have their blocks allocated out of a
-                 block group specific preallocation pool, so that small
-                 files are packed closely together.  Each large file
-                 will have its blocks allocated out of its own unique
-                 preallocation pool.
-inode_readahead  Tuning parameter which controls the maximum number of
-                 inode table blocks that ext4's inode table readahead
-                 algorithm will pre-read into the buffer cache
 ..............................................................................
 
 
@@ -1011,1021 +983,24 @@ review the kernel documentation in the d
 This chapter  is  heavily  based  on the documentation included in the pre 2.2
 kernels, and became part of it in version 2.2.1 of the Linux kernel.
 
-2.1 /proc/sys/fs - File system data
------------------------------------
-
-This subdirectory  contains  specific  file system, file handle, inode, dentry
-and quota information.
-
-Currently, these files are in /proc/sys/fs:
-
-dentry-state
-------------
-
-Status of  the  directory  cache.  Since  directory  entries  are  dynamically
-allocated and  deallocated,  this  file indicates the current status. It holds
-six values, in which the last two are not used and are always zero. The others
-are listed in table 2-1.
-
-
-Table 2-1: Status files of the directory cache 
-..............................................................................
- File       Content                                                            
- nr_dentry  Almost always zero                                                 
- nr_unused  Number of unused cache entries                                     
- age_limit  
-            in seconds after the entry may be reclaimed, when memory is short 
- want_pages internally                                                         
-..............................................................................
-
-dquot-nr and dquot-max
-----------------------
-
-The file dquot-max shows the maximum number of cached disk quota entries.
-
-The file  dquot-nr  shows  the  number of allocated disk quota entries and the
-number of free disk quota entries.
-
-If the number of available cached disk quotas is very low and you have a large
-number of simultaneous system users, you might want to raise the limit.
-
-file-nr and file-max
---------------------
-
-The kernel  allocates file handles dynamically, but doesn't free them again at
-this time.
-
-The value  in  file-max  denotes  the  maximum number of file handles that the
-Linux kernel will allocate. When you get a lot of error messages about running
-out of  file handles, you might want to raise this limit. The default value is
-10% of  RAM in kilobytes.  To  change it, just  write the new number  into the
-file:
-
-  # cat /proc/sys/fs/file-max 
-  4096 
-  # echo 8192 > /proc/sys/fs/file-max 
-  # cat /proc/sys/fs/file-max 
-  8192 
-
-
-This method  of  revision  is  useful  for  all customizable parameters of the
-kernel - simply echo the new value to the corresponding file.
-
-Historically, the three values in file-nr denoted the number of allocated file
-handles,  the number of  allocated but  unused file  handles, and  the maximum
-number of file handles. Linux 2.6 always  reports 0 as the number of free file
-handles -- this  is not an error,  it just means that the  number of allocated
-file handles exactly matches the number of used file handles.
-
-Attempts to  allocate more  file descriptors than  file-max are  reported with
-printk, look for "VFS: file-max limit <number> reached".
-
-inode-state and inode-nr
-------------------------
-
-The file inode-nr contains the first two items from inode-state, so we'll skip
-to that file...
-
-inode-state contains  two  actual numbers and five dummy values. The numbers
-are nr_inodes and nr_free_inodes (in order of appearance).
-
-nr_inodes
-~~~~~~~~~
-
-Denotes the  number  of  inodes the system has allocated. This number will
-grow and shrink dynamically.
-
-nr_open
--------
-
-Denotes the maximum number of file-handles a process can
-allocate. Default value is 1024*1024 (1048576) which should be
-enough for most machines. Actual limit depends on RLIMIT_NOFILE
-resource limit.
-
-nr_free_inodes
---------------
-
-Represents the  number of free inodes. Ie. The number of inuse inodes is
-(nr_inodes - nr_free_inodes).
-
-aio-nr and aio-max-nr
----------------------
-
-aio-nr is the running total of the number of events specified on the
-io_setup system call for all currently active aio contexts.  If aio-nr
-reaches aio-max-nr then io_setup will fail with EAGAIN.  Note that
-raising aio-max-nr does not result in the pre-allocation or re-sizing
-of any kernel data structures.
-
-2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats
------------------------------------------------------------
-
-Besides these  files, there is the subdirectory /proc/sys/fs/binfmt_misc. This
-handles the kernel support for miscellaneous binary formats.
-
-Binfmt_misc provides  the ability to register additional binary formats to the
-Kernel without  compiling  an additional module/kernel. Therefore, binfmt_misc
-needs to  know magic numbers at the beginning or the filename extension of the
-binary.
-
-It works by maintaining a linked list of structs that contain a description of
-a binary  format,  including  a  magic  with size (or the filename extension),
-offset and  mask,  and  the  interpreter name. On request it invokes the given
-interpreter with  the  original  program  as  argument,  as  binfmt_java  and
-binfmt_em86 and  binfmt_mz  do.  Since binfmt_misc does not define any default
-binary-formats, you have to register an additional binary-format.
-
-There are two general files in binfmt_misc and one file per registered format.
-The two general files are register and status.
-
-Registering a new binary format
--------------------------------
-
-To register a new binary format you have to issue the command
-
-  echo :name:type:offset:magic:mask:interpreter: > /proc/sys/fs/binfmt_misc/register 
-
-
-
-with appropriate  name (the name for the /proc-dir entry), offset (defaults to
-0, if  omitted),  magic, mask (which can be omitted, defaults to all 0xff) and
-last but  not  least,  the  interpreter that is to be invoked (for example and
-testing /bin/echo).  Type  can be M for usual magic matching or E for filename
-extension matching (give extension in place of magic).
-
-Check or reset the status of the binary format handler
-------------------------------------------------------
-
-If you  do a cat on the file /proc/sys/fs/binfmt_misc/status, you will get the
-current status (enabled/disabled) of binfmt_misc. Change the status by echoing
-0 (disables)  or  1  (enables)  or  -1  (caution:  this  clears all previously
-registered binary  formats)  to status. For example echo 0 > status to disable
-binfmt_misc (temporarily).
-
-Status of a single handler
---------------------------
-
-Each registered  handler has an entry in /proc/sys/fs/binfmt_misc. These files
-perform the  same function as status, but their scope is limited to the actual
-binary format.  By  cating this file, you also receive all related information
-about the interpreter/magic of the binfmt.
-
-Example usage of binfmt_misc (emulate binfmt_java)
---------------------------------------------------
-
-  cd /proc/sys/fs/binfmt_misc  
-  echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:' > register  
-  echo ':HTML:E::html::/usr/local/java/bin/appletviewer:' > register  
-  echo ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:' > register 
-  echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register 
-
-
-These four  lines  add  support  for  Java  executables and Java applets (like
-binfmt_java, additionally  recognizing the .html extension with no need to put
-<!--applet> to  every  applet  file).  You  have  to  install  the JDK and the
-shell-script /usr/local/java/bin/javawrapper  too.  It  works  around  the
-brokenness of  the Java filename handling. To add a Java binary, just create a
-link to the class-file somewhere in the path.
-
-2.3 /proc/sys/kernel - general kernel parameters
-------------------------------------------------
-
-This directory  reflects  general  kernel  behaviors. As I've said before, the
-contents depend  on  your  configuration.  Here you'll find the most important
-files, along with descriptions of what they mean and how to use them.
-
-acct
-----
-
-The file contains three values; highwater, lowwater, and frequency.
-
-It exists  only  when  BSD-style  process  accounting is enabled. These values
-control its behavior. If the free space on the file system where the log lives
-goes below  lowwater  percentage,  accounting  suspends.  If  it  goes  above
-highwater percentage,  accounting  resumes. Frequency determines how often you
-check the amount of free space (value is in seconds). Default settings are: 4,
-2, and  30.  That is, suspend accounting if there is less than 2 percent free;
-resume it  if we have a value of 3 or more percent; consider information about
-the amount of free space valid for 30 seconds
-
-ctrl-alt-del
-------------
-
-When the value in this file is 0, ctrl-alt-del is trapped and sent to the init
-program to  handle a graceful restart. However, when the value is greater that
-zero, Linux's  reaction  to  this key combination will be an immediate reboot,
-without syncing its dirty buffers.
-
-[NOTE]
-    When a  program  (like  dosemu)  has  the  keyboard  in  raw  mode,  the
-    ctrl-alt-del is  intercepted  by  the  program  before it ever reaches the
-    kernel tty  layer,  and  it is up to the program to decide what to do with
-    it.
-
-domainname and hostname
------------------------
-
-These files  can  be controlled to set the NIS domainname and hostname of your
-box. For the classic darkstar.frop.org a simple:
-
-  # echo "darkstar" > /proc/sys/kernel/hostname 
-  # echo "frop.org" > /proc/sys/kernel/domainname 
-
-
-would suffice to set your hostname and NIS domainname.
-
-osrelease, ostype and version
------------------------------
-
-The names make it pretty obvious what these fields contain:
-
-  > cat /proc/sys/kernel/osrelease 
-  2.2.12 
-   
-  > cat /proc/sys/kernel/ostype 
-  Linux 
-   
-  > cat /proc/sys/kernel/version 
-  #4 Fri Oct 1 12:41:14 PDT 1999 
-
-
-The files  osrelease and ostype should be clear enough. Version needs a little
-more clarification.  The  #4 means that this is the 4th kernel built from this
-source base and the date after it indicates the time the kernel was built. The
-only way to tune these values is to rebuild the kernel.
-
-panic
------
-
-The value  in  this  file  represents  the  number of seconds the kernel waits
-before rebooting  on  a  panic.  When  you  use  the  software  watchdog,  the
-recommended setting  is  60. If set to 0, the auto reboot after a kernel panic
-is disabled, which is the default setting.
-
-printk
-------
-
-The four values in printk denote
-* console_loglevel,
-* default_message_loglevel,
-* minimum_console_loglevel and
-* default_console_loglevel
-respectively.
-
-These values  influence  printk()  behavior  when  printing  or  logging error
-messages, which  come  from  inside  the  kernel.  See  syslog(2)  for  more
-information on the different log levels.
-
-console_loglevel
-----------------
-
-Messages with a higher priority than this will be printed to the console.
-
-default_message_level
----------------------
-
-Messages without an explicit priority will be printed with this priority.
-
-minimum_console_loglevel
-------------------------
-
-Minimum (highest) value to which the console_loglevel can be set.
-
-default_console_loglevel
-------------------------
-
-Default value for console_loglevel.
-
-sg-big-buff
------------
-
-This file  shows  the size of the generic SCSI (sg) buffer. At this point, you
-can't tune  it  yet,  but  you  can  change  it  at  compile  time  by editing
-include/scsi/sg.h and changing the value of SG_BIG_BUFF.
-
-If you use a scanner with SANE (Scanner Access Now Easy) you might want to set
-this to a higher value. Refer to the SANE documentation on this issue.
-
-modprobe
---------
-
-The location  where  the  modprobe  binary  is  located.  The kernel uses this
-program to load modules on demand.
-
-unknown_nmi_panic
------------------
-
-The value in this file affects behavior of handling NMI. When the value is
-non-zero, unknown NMI is trapped and then panic occurs. At that time, kernel
-debugging information is displayed on console.
-
-NMI switch that most IA32 servers have fires unknown NMI up, for example.
-If a system hangs up, try pressing the NMI switch.
-
-panic_on_unrecovered_nmi
-------------------------
-
-The default Linux behaviour on an NMI of either memory or unknown is to continue
-operation. For many environments such as scientific computing it is preferable
-that the box is taken out and the error dealt with than an uncorrected
-parity/ECC error get propogated.
-
-A small number of systems do generate NMI's for bizarre random reasons such as
-power management so the default is off. That sysctl works like the existing
-panic controls already in that directory.
-
-nmi_watchdog
-------------
-
-Enables/Disables the NMI watchdog on x86 systems.  When the value is non-zero
-the NMI watchdog is enabled and will continuously test all online cpus to
-determine whether or not they are still functioning properly. Currently,
-passing "nmi_watchdog=" parameter at boot time is required for this function
-to work.
-
-If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel parameter), the
-NMI watchdog shares registers with oprofile. By disabling the NMI watchdog,
-oprofile may have more registers to utilize.
-
-msgmni
-------
-
-Maximum number of message queue ids on the system.
-This value scales to the amount of lowmem. It is automatically recomputed
-upon memory add/remove or ipc namespace creation/removal.
-When a value is written into this file, msgmni's value becomes fixed, i.e. it
-is not recomputed anymore when one of the above events occurs.
-Use auto_msgmni to change this behavior.
-
-auto_msgmni
------------
-
-Enables/Disables automatic recomputing of msgmni upon memory add/remove or
-upon ipc namespace creation/removal (see the msgmni description above).
-Echoing "1" into this file enables msgmni automatic recomputing.
-Echoing "0" turns it off.
-auto_msgmni default value is 1.
-
-
-2.4 /proc/sys/vm - The virtual memory subsystem
------------------------------------------------
-
-Please see: Documentation/sysctls/vm.txt for a description of these
+Please see: Documentation/sysctls/ directory for descriptions of these
 entries.
 
+------------------------------------------------------------------------------
+Summary
+------------------------------------------------------------------------------
+Certain aspects  of  kernel  behavior  can be modified at runtime, without the
+need to  recompile  the kernel, or even to reboot the system. The files in the
+/proc/sys tree  can  not only be read, but also modified. You can use the echo
+command to write value into these files, thereby changing the default settings
+of the kernel.
+------------------------------------------------------------------------------
 
-2.5 /proc/sys/dev - Device specific parameters
-----------------------------------------------
-
-Currently there is only support for CDROM drives, and for those, there is only
-one read-only  file containing information about the CD-ROM drives attached to
-the system:
-
-  >cat /proc/sys/dev/cdrom/info 
-  CD-ROM information, Id: cdrom.c 2.55 1999/04/25 
-   
-  drive name:             sr0     hdb 
-  drive speed:            32      40 
-  drive # of slots:       1       0 
-  Can close tray:         1       1 
-  Can open tray:          1       1 
-  Can lock tray:          1       1 
-  Can change speed:       1       1 
-  Can select disk:        0       1 
-  Can read multisession:  1       1 
-  Can read MCN:           1       1 
-  Reports media changed:  1       1 
-  Can play audio:         1       1 
-
-
-You see two drives, sr0 and hdb, along with a list of their features.
-
-2.6 /proc/sys/sunrpc - Remote procedure calls
----------------------------------------------
-
-This directory  contains four files, which enable or disable debugging for the
-RPC functions NFS, NFS-daemon, RPC and NLM. The default values are 0. They can
-be set to one to turn debugging on. (The default value is 0 for each)
-
-2.7 /proc/sys/net - Networking stuff
-------------------------------------
-
-The interface  to  the  networking  parts  of  the  kernel  is  located  in
-/proc/sys/net. Table  2-3  shows all possible subdirectories. You may see only
-some of them, depending on your kernel's configuration.
-
-
-Table 2-3: Subdirectories in /proc/sys/net 
-..............................................................................
- Directory Content             Directory  Content            
- core      General parameter   appletalk  Appletalk protocol 
- unix      Unix domain sockets netrom     NET/ROM            
- 802       E802 protocol       ax25       AX25               
- ethernet  Ethernet protocol   rose       X.25 PLP layer     
- ipv4      IP version 4        x25        X.25 protocol      
- ipx       IPX                 token-ring IBM token ring     
- bridge    Bridging            decnet     DEC net            
- ipv6      IP version 6                   
-..............................................................................
-
-We will  concentrate  on IP networking here. Since AX15, X.25, and DEC Net are
-only minor players in the Linux world, we'll skip them in this chapter. You'll
-find some  short  info on Appletalk and IPX further on in this chapter. Review
-the online  documentation  and the kernel source to get a detailed view of the
-parameters for  those  protocols.  In  this  section  we'll  discuss  the
-subdirectories printed  in  bold letters in the table above. As default values
-are suitable for most needs, there is no need to change these values.
-
-/proc/sys/net/core - Network core options
------------------------------------------
-
-rmem_default
-------------
-
-The default setting of the socket receive buffer in bytes.
-
-rmem_max
---------
-
-The maximum receive socket buffer size in bytes.
-
-wmem_default
-------------
-
-The default setting (in bytes) of the socket send buffer.
-
-wmem_max
---------
-
-The maximum send socket buffer size in bytes.
-
-message_burst and message_cost
-------------------------------
-
-These parameters  are used to limit the warning messages written to the kernel
-log from  the  networking  code.  They  enforce  a  rate  limit  to  make  a
-denial-of-service attack  impossible. A higher message_cost factor, results in
-fewer messages that will be written. Message_burst controls when messages will
-be dropped.  The  default  settings  limit  warning messages to one every five
-seconds.
-
-warnings
---------
-
-This controls console messages from the networking stack that can occur because
-of problems on the network like duplicate address or bad checksums. Normally,
-this should be enabled, but if the problem persists the messages can be
-disabled.
-
-netdev_budget
--------------
-
-Maximum number of packets taken from all interfaces in one polling cycle (NAPI
-poll). In one polling cycle interfaces which are registered to polling are
-probed in a round-robin manner. The limit of packets in one such probe can be
-set per-device via sysfs class/net/<device>/weight .
-
-netdev_max_backlog
-------------------
-
-Maximum number  of  packets,  queued  on  the  INPUT  side, when the interface
-receives packets faster than kernel can process them.
-
-optmem_max
-----------
-
-Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence
-of struct cmsghdr structures with appended data.
-
-/proc/sys/net/unix - Parameters for Unix domain sockets
--------------------------------------------------------
-
-There are  only  two  files  in this subdirectory. They control the delays for
-deleting and destroying socket descriptors.
-
-2.8 /proc/sys/net/ipv4 - IPV4 settings
---------------------------------------
-
-IP version  4  is  still the most used protocol in Unix networking. It will be
-replaced by  IP version 6 in the next couple of years, but for the moment it's
-the de  facto  standard  for  the  internet  and  is  used  in most networking
-environments around  the  world.  Because  of the importance of this protocol,
-we'll have a deeper look into the subtree controlling the behavior of the IPv4
-subsystem of the Linux kernel.
-
-Let's start with the entries in /proc/sys/net/ipv4.
-
-ICMP settings
--------------
-
-icmp_echo_ignore_all and icmp_echo_ignore_broadcasts
-----------------------------------------------------
-
-Turn on (1) or off (0), if the kernel should ignore all ICMP ECHO requests, or
-just those to broadcast and multicast addresses.
-
-Please note that if you accept ICMP echo requests with a broadcast/multi\-cast
-destination address  your  network  may  be  used as an exploder for denial of
-service packet flooding attacks to other hosts.
-
-icmp_destunreach_rate, icmp_echoreply_rate, icmp_paramprob_rate and icmp_timeexeed_rate
----------------------------------------------------------------------------------------
-
-Sets limits  for  sending  ICMP  packets  to specific targets. A value of zero
-disables all  limiting.  Any  positive  value sets the maximum package rate in
-hundredth of a second (on Intel systems).
-
-IP settings
------------
-
-ip_autoconfig
--------------
-
-This file contains the number one if the host received its IP configuration by
-RARP, BOOTP, DHCP or a similar mechanism. Otherwise it is zero.
-
-ip_default_ttl
---------------
-
-TTL (Time  To  Live) for IPv4 interfaces. This is simply the maximum number of
-hops a packet may travel.
-
-ip_dynaddr
-----------
-
-Enable dynamic  socket  address rewriting on interface address change. This is
-useful for dialup interface with changing IP addresses.
-
-ip_forward
-----------
-
-Enable or  disable forwarding of IP packages between interfaces. Changing this
-value resets  all other parameters to their default values. They differ if the
-kernel is configured as host or router.
-
-ip_local_port_range
--------------------
-
-Range of  ports  used  by  TCP  and UDP to choose the local port. Contains two
-numbers, the  first  number  is the lowest port, the second number the highest
-local port.  Default  is  1024-4999.  Should  be  changed  to  32768-61000 for
-high-usage systems.
-
-ip_no_pmtu_disc
----------------
-
-Global switch  to  turn  path  MTU  discovery off. It can also be set on a per
-socket basis by the applications or on a per route basis.
-
-ip_masq_debug
--------------
-
-Enable/disable debugging of IP masquerading.
-
-IP fragmentation settings
--------------------------
-
-ipfrag_high_trash and ipfrag_low_trash
---------------------------------------
-
-Maximum memory  used to reassemble IP fragments. When ipfrag_high_thresh bytes
-of memory  is  allocated  for  this  purpose,  the  fragment handler will toss
-packets until ipfrag_low_thresh is reached.
-
-ipfrag_time
------------
-
-Time in seconds to keep an IP fragment in memory.
-
-TCP settings
-------------
-
-tcp_ecn
--------
-
-This file controls the use of the ECN bit in the IPv4 headers. This is a new
-feature about Explicit Congestion Notification, but some routers and firewalls
-block traffic that has this bit set, so it could be necessary to echo 0 to
-/proc/sys/net/ipv4/tcp_ecn if you want to talk to these sites. For more info
-you could read RFC2481.
-
-tcp_retrans_collapse
---------------------
-
-Bug-to-bug compatibility with some broken printers. On retransmit, try to send
-larger packets to work around bugs in certain TCP stacks. Can be turned off by
-setting it to zero.
-
-tcp_keepalive_probes
---------------------
-
-Number of  keep  alive  probes  TCP  sends  out,  until  it  decides  that the
-connection is broken.
-
-tcp_keepalive_time
-------------------
-
-How often  TCP  sends out keep alive messages, when keep alive is enabled. The
-default is 2 hours.
-
-tcp_syn_retries
----------------
-
-Number of  times  initial  SYNs  for  a  TCP  connection  attempt  will  be
-retransmitted. Should  not  be  higher  than 255. This is only the timeout for
-outgoing connections,  for  incoming  connections the number of retransmits is
-defined by tcp_retries1.
-
-tcp_sack
---------
-
-Enable select acknowledgments after RFC2018.
-
-tcp_timestamps
---------------
-
-Enable timestamps as defined in RFC1323.
-
-tcp_stdurg
-----------
-
-Enable the  strict  RFC793 interpretation of the TCP urgent pointer field. The
-default is  to  use  the  BSD  compatible interpretation of the urgent pointer
-pointing to the first byte after the urgent data. The RFC793 interpretation is
-to have  it  point  to  the last byte of urgent data. Enabling this option may
-lead to interoperability problems. Disabled by default.
-
-tcp_syncookies
---------------
-
-Only valid  when  the  kernel  was  compiled  with CONFIG_SYNCOOKIES. Send out
-syncookies when  the  syn backlog queue of a socket overflows. This is to ward
-off the common 'syn flood attack'. Disabled by default.
-
-Note that  the  concept  of a socket backlog is abandoned. This means the peer
-may not  receive  reliable  error  messages  from  an  over loaded server with
-syncookies enabled.
-
-tcp_window_scaling
-------------------
-
-Enable window scaling as defined in RFC1323.
-
-tcp_fin_timeout
----------------
-
-The length  of  time  in  seconds  it  takes to receive a final FIN before the
-socket is  always  closed.  This  is  strictly  a  violation  of  the  TCP
-specification, but required to prevent denial-of-service attacks.
-
-tcp_max_ka_probes
------------------
-
-Indicates how  many  keep alive probes are sent per slow timer run. Should not
-be set too high to prevent bursts.
-
-tcp_max_syn_backlog
--------------------
-
-Length of  the per socket backlog queue. Since Linux 2.2 the backlog specified
-in listen(2)  only  specifies  the  length  of  the  backlog  queue of already
-established sockets. When more connection requests arrive Linux starts to drop
-packets. When  syncookies  are  enabled the packets are still answered and the
-maximum queue is effectively ignored.
-
-tcp_retries1
-------------
-
-Defines how  often  an  answer  to  a  TCP connection request is retransmitted
-before giving up.
-
-tcp_retries2
-------------
-
-Defines how often a TCP packet is retransmitted before giving up.
-
-Interface specific settings
----------------------------
-
-In the directory /proc/sys/net/ipv4/conf you'll find one subdirectory for each
-interface the  system  knows about and one directory calls all. Changes in the
-all subdirectory  affect  all  interfaces,  whereas  changes  in  the  other
-subdirectories affect  only  one  interface.  All  directories  have  the same
-entries:
-
-accept_redirects
-----------------
-
-This switch  decides  if the kernel accepts ICMP redirect messages or not. The
-default is 'yes' if the kernel is configured for a regular host and 'no' for a
-router configuration.
-
-accept_source_route
--------------------
-
-Should source  routed  packages  be  accepted  or  declined.  The  default  is
-dependent on  the  kernel  configuration.  It's 'yes' for routers and 'no' for
-hosts.
-
-bootp_relay
-~~~~~~~~~~~
-
-Accept packets  with source address 0.b.c.d with destinations not to this host
-as local ones. It is supposed that a BOOTP relay daemon will catch and forward
-such packets.
-
-The default  is  0,  since this feature is not implemented yet (kernel version
-2.2.12).
-
-forwarding
-----------
-
-Enable or disable IP forwarding on this interface.
-
-log_martians
-------------
-
-Log packets with source addresses with no known route to kernel log.
-
-mc_forwarding
--------------
-
-Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE and a
-multicast routing daemon is required.
-
-proxy_arp
----------
-
-Does (1) or does not (0) perform proxy ARP.
-
-rp_filter
----------
-
-Integer value determines if a source validation should be made. 1 means yes, 0
-means no.  Disabled by default, but local/broadcast address spoofing is always
-on.
-
-If you  set this to 1 on a router that is the only connection for a network to
-the net,  it  will  prevent  spoofing  attacks  against your internal networks
-(external addresses  can  still  be  spoofed), without the need for additional
-firewall rules.
-
-secure_redirects
-----------------
-
-Accept ICMP  redirect  messages  only  for gateways, listed in default gateway
-list. Enabled by default.
-
-shared_media
-------------
-
-If it  is  not  set  the kernel does not assume that different subnets on this
-device can communicate directly. Default setting is 'yes'.
-
-send_redirects
---------------
-
-Determines whether to send ICMP redirects to other hosts.
-
-Routing settings
-----------------
-
-The directory  /proc/sys/net/ipv4/route  contains  several  file  to  control
-routing issues.
-
-error_burst and error_cost
---------------------------
-
-These  parameters  are used to limit how many ICMP destination unreachable to 
-send  from  the  host  in question. ICMP destination unreachable messages are 
-sent  when  we  cannot reach  the next hop while trying to transmit a packet. 
-It  will also print some error messages to kernel logs if someone is ignoring 
-our   ICMP  redirects.  The  higher  the  error_cost  factor  is,  the  fewer 
-destination  unreachable  and error messages will be let through. Error_burst 
-controls  when  destination  unreachable  messages and error messages will be
-dropped. The default settings limit warning messages to five every second.
-
-flush
------
-
-Writing to this file results in a flush of the routing cache.
-
-gc_elasticity, gc_interval, gc_min_interval_ms, gc_timeout, gc_thresh
----------------------------------------------------------------------
-
-Values to  control  the  frequency  and  behavior  of  the  garbage collection
-algorithm for the routing cache. gc_min_interval is deprecated and replaced
-by gc_min_interval_ms.
-
-
-max_size
---------
-
-Maximum size  of  the routing cache. Old entries will be purged once the cache
-reached has this size.
-
-redirect_load, redirect_number
-------------------------------
-
-Factors which  determine  if  more ICPM redirects should be sent to a specific
-host. No  redirects  will be sent once the load limit or the maximum number of
-redirects has been reached.
-
-redirect_silence
-----------------
-
-Timeout for redirects. After this period redirects will be sent again, even if
-this has been stopped, because the load or number limit has been reached.
-
-Network Neighbor handling
--------------------------
-
-Settings about how to handle connections with direct neighbors (nodes attached
-to the same link) can be found in the directory /proc/sys/net/ipv4/neigh.
-
-As we  saw  it  in  the  conf directory, there is a default subdirectory which
-holds the  default  values, and one directory for each interface. The contents
-of the  directories  are identical, with the single exception that the default
-settings contain additional options to set garbage collection parameters.
-
-In the interface directories you'll find the following entries:
-
-base_reachable_time, base_reachable_time_ms
--------------------------------------------
-
-A base  value  used for computing the random reachable time value as specified
-in RFC2461.
-
-Expression of base_reachable_time, which is deprecated, is in seconds.
-Expression of base_reachable_time_ms is in milliseconds.
-
-retrans_time, retrans_time_ms
------------------------------
-
-The time between retransmitted Neighbor Solicitation messages.
-Used for address resolution and to determine if a neighbor is
-unreachable.
-
-Expression of retrans_time, which is deprecated, is in 1/100 seconds (for
-IPv4) or in jiffies (for IPv6).
-Expression of retrans_time_ms is in milliseconds.
-
-unres_qlen
-----------
-
-Maximum queue  length  for a pending arp request - the number of packets which
-are accepted from other layers while the ARP address is still resolved.
-
-anycast_delay
--------------
-
-Maximum for  random  delay  of  answers  to  neighbor solicitation messages in
-jiffies (1/100  sec). Not yet implemented (Linux does not have anycast support
-yet).
-
-ucast_solicit
--------------
-
-Maximum number of retries for unicast solicitation.
-
-mcast_solicit
--------------
-
-Maximum number of retries for multicast solicitation.
-
-delay_first_probe_time
-----------------------
-
-Delay for  the  first  time  probe  if  the  neighbor  is  reachable.  (see
-gc_stale_time)
-
-locktime
---------
-
-An ARP/neighbor  entry  is only replaced with a new one if the old is at least
-locktime old. This prevents ARP cache thrashing.
-
-proxy_delay
------------
-
-Maximum time  (real  time is random [0..proxytime]) before answering to an ARP
-request for  which  we have an proxy ARP entry. In some cases, this is used to
-prevent network flooding.
-
-proxy_qlen
-----------
-
-Maximum queue length of the delayed proxy arp timer. (see proxy_delay).
-
-app_solicit
-----------
-
-Determines the  number of requests to send to the user level ARP daemon. Use 0
-to turn off.
-
-gc_stale_time
--------------
-
-Determines how  often  to  check  for stale ARP entries. After an ARP entry is
-stale it  will  be resolved again (which is useful when an IP address migrates
-to another  machine).  When  ucast_solicit is greater than 0 it first tries to
-send an  ARP  packet  directly  to  the  known  host  When  that  fails  and
-mcast_solicit is greater than 0, an ARP request is broadcasted.
-
-2.9 Appletalk
--------------
-
-The /proc/sys/net/appletalk  directory  holds the Appletalk configuration data
-when Appletalk is loaded. The configurable parameters are:
-
-aarp-expiry-time
-----------------
-
-The amount  of  time  we keep an ARP entry before expiring it. Used to age out
-old hosts.
-
-aarp-resolve-time
------------------
-
-The amount of time we will spend trying to resolve an Appletalk address.
-
-aarp-retransmit-limit
----------------------
-
-The number of times we will retransmit a query before giving up.
-
-aarp-tick-time
---------------
-
-Controls the rate at which expires are checked.
-
-The directory  /proc/net/appletalk  holds the list of active Appletalk sockets
-on a machine.
-
-The fields  indicate  the DDP type, the local address (in network:node format)
-the remote  address,  the  size of the transmit pending queue, the size of the
-received queue  (bytes waiting for applications to read) the state and the uid
-owning the socket.
-
-/proc/net/atalk_iface lists  all  the  interfaces  configured for appletalk.It
-shows the  name  of the interface, its Appletalk address, the network range on
-that address  (or  network number for phase 1 networks), and the status of the
-interface.
-
-/proc/net/atalk_route lists  each  known  network  route.  It lists the target
-(network) that the route leads to, the router (may be directly connected), the
-route flags, and the device the route is using.
-
-2.10 IPX
---------
-
-The IPX protocol has no tunable values in proc/sys/net.
-
-The IPX  protocol  does,  however,  provide  proc/net/ipx. This lists each IPX
-socket giving  the  local  and  remote  addresses  in  Novell  format (that is
-network:node:port). In  accordance  with  the  strange  Novell  tradition,
-everything but the port is in hex. Not_Connected is displayed for sockets that
-are not  tied to a specific remote address. The Tx and Rx queue sizes indicate
-the number  of  bytes  pending  for  transmission  and  reception.  The  state
-indicates the  state  the  socket  is  in and the uid is the owning uid of the
-socket.
-
-The /proc/net/ipx_interface  file lists all IPX interfaces. For each interface
-it gives  the network number, the node number, and indicates if the network is
-the primary  network.  It  also  indicates  which  device  it  is bound to (or
-Internal for  internal  networks)  and  the  Frame  Type if appropriate. Linux
-supports 802.3,  802.2,  802.2  SNAP  and DIX (Blue Book) ethernet framing for
-IPX.
-
-The /proc/net/ipx_route  table  holds  a list of IPX routes. For each route it
-gives the  destination  network, the router node (or Directly) and the network
-address of the router (or Connected) for internal networks.
-
-2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
-----------------------------------------------------------
-
-The "mqueue"  filesystem provides  the necessary kernel features to enable the
-creation of a  user space  library that  implements  the  POSIX message queues
-API (as noted by the  MSG tag in the  POSIX 1003.1-2001 version  of the System
-Interfaces specification.)
-
-The "mqueue" filesystem contains values for determining/setting  the amount of
-resources used by the file system.
-
-/proc/sys/fs/mqueue/queues_max is a read/write  file for  setting/getting  the
-maximum number of message queues allowed on the system.
-
-/proc/sys/fs/mqueue/msg_max  is  a  read/write file  for  setting/getting  the
-maximum number of messages in a queue value.  In fact it is the limiting value
-for another (user) limit which is set in mq_open invocation. This attribute of
-a queue must be less or equal then msg_max.
-
-/proc/sys/fs/mqueue/msgsize_max is  a read/write  file for setting/getting the
-maximum  message size value (it is every  message queue's attribute set during
-its creation).
+------------------------------------------------------------------------------
+CHAPTER 3: PER-PROCESS PARAMETERS
+------------------------------------------------------------------------------
 
-2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+3.1 /proc/<pid>/oom_adj - Adjust the oom-killer score
 ------------------------------------------------------
 
 This file can be used to adjust the score used to select which processes
@@ -2062,25 +1037,15 @@ The task with the highest badness score
 are killed, process itself will be killed in an OOM situation when it does
 not have children or some of them disabled oom like described above.
 
-2.13 /proc/<pid>/oom_score - Display current oom-killer score
+3.2 /proc/<pid>/oom_score - Display current oom-killer score
 -------------------------------------------------------------
 
-------------------------------------------------------------------------------
 This file can be used to check the current score used by the oom-killer is for
 any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
 process should be killed in an out-of-memory situation.
 
-------------------------------------------------------------------------------
-Summary
-------------------------------------------------------------------------------
-Certain aspects  of  kernel  behavior  can be modified at runtime, without the
-need to  recompile  the kernel, or even to reboot the system. The files in the
-/proc/sys tree  can  not only be read, but also modified. You can use the echo
-command to write value into these files, thereby changing the default settings
-of the kernel.
-------------------------------------------------------------------------------
 
-2.14  /proc/<pid>/io - Display the IO accounting fields
+3.3  /proc/<pid>/io - Display the IO accounting fields
 -------------------------------------------------------
 
 This file contains IO statistics for each running process
@@ -2182,7 +1147,7 @@ those 64-bit counters, process A could s
 More information about this can be found within the taskstats documentation in
 Documentation/accounting.
 
-2.15 /proc/<pid>/coredump_filter - Core dump filtering settings
+3.4 /proc/<pid>/coredump_filter - Core dump filtering settings
 ---------------------------------------------------------------
 When a process is dumped, all anonymous memory is written to a core file as
 long as the size of the core file isn't limited. But sometimes we don't want
@@ -2226,7 +1191,7 @@ For example:
   $ echo 0x7 > /proc/self/coredump_filter
   $ ./some_program
 
-2.16	/proc/<pid>/mountinfo - Information about mounts
+3.5	/proc/<pid>/mountinfo - Information about mounts
 --------------------------------------------------------
 
 This file contains lines of the form:
@@ -2263,30 +1228,3 @@ For more information on mount propagatio
 
   Documentation/filesystems/sharedsubtree.txt
 
-2.17	/proc/sys/fs/epoll - Configuration options for the epoll interface
---------------------------------------------------------
-
-This directory contains configuration options for the epoll(7) interface.
-
-max_user_instances
-------------------
-
-This is the maximum number of epoll file descriptors that a single user can
-have open at a given time. The default value is 128, and should be enough
-for normal users.
-
-max_user_watches
-----------------
-
-Every epoll file descriptor can store a number of files to be monitored
-for event readiness. Each one of these monitored files constitutes a "watch".
-This configuration option sets the maximum number of "watches" that are
-allowed for each user.
-Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes
-on a 64bit one.
-The current default value for  max_user_watches  is the 1/32 of the available
-low memory, divided for the "watch" cost in bytes.
-
-
-------------------------------------------------------------------------------
-
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/sysfs-pci.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/sysfs-pci.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/sysfs-pci.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/sysfs-pci.txt	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@ that support it.  For example, a given b
      |   |-- enable
      |   |-- irq
      |   |-- local_cpus
+     |   |-- remove
      |   |-- resource
      |   |-- resource0
      |   |-- resource1
@@ -36,6 +37,7 @@ files, each with their own function.
        enable	           Whether the device is enabled (ascii, rw)
        irq		   IRQ number (ascii, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
+       remove		   remove device from kernel's list (ascii, wo)
        resource		   PCI resource host addresses (ascii, ro)
        resource0..N	   PCI resource N, if present (binary, mmap)
        resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
@@ -46,6 +48,7 @@ files, each with their own function.
 
   ro - read only file
   rw - file is readable and writable
+  wo - write only file
   mmap - file is mmapable
   ascii - file contains ascii text
   binary - file contains binary data
@@ -73,6 +76,13 @@ that the device must be enabled for a ro
 In the event a driver is not bound to the device, it can be enabled using the
 'enable' file, documented above.
 
+The 'remove' file is used to remove the PCI device, by writing a non-zero
+integer to the file.  This does not involve any kind of hot-plug functionality,
+e.g. powering off the device.  The device is removed from the kernel's list of
+PCI devices, the sysfs directory for it is removed, and the device will be
+removed from any drivers attached to it. Removal of PCI root buses is
+disallowed.
+
 Accessing legacy resources through sysfs
 ----------------------------------------
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/tmpfs.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/tmpfs.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/tmpfs.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/tmpfs.txt	2009-06-09 23:05:27.000000000 -0400
@@ -133,4 +133,4 @@ RAM/SWAP in 10240 inodes and it is only
 Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
 Updated:
-   Hugh Dickins <hugh@veritas.com>, 4 June 2007
+   Hugh Dickins, 4 June 2007
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/udf.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/udf.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/udf.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/udf.txt	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,8 @@ The following mount options are supporte
 
 	gid=		Set the default group.
 	umask=		Set the default umask.
+	mode=		Set the default file permissions.
+	dmode=		Set the default directory permissions.
 	uid=		Set the default user.
 	bs=		Set the block size.
 	unhide		Show otherwise hidden files.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/filesystems/vfs.txt linux-libre-2.6.30-gnu1/Documentation/filesystems/vfs.txt
--- linux-libre-2.6.29-gnu1/Documentation/filesystems/vfs.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/filesystems/vfs.txt	2009-06-09 23:05:27.000000000 -0400
@@ -277,8 +277,7 @@ or bottom half).
   unfreeze_fs: called when VFS is unlocking a filesystem and making it writable
   	again.
 
-  statfs: called when the VFS needs to get filesystem statistics. This
-	is called with the kernel lock held
+  statfs: called when the VFS needs to get filesystem statistics.
 
   remount_fs: called when the filesystem is remounted. This is called
 	with the kernel lock held
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ftrace.txt linux-libre-2.6.30-gnu1/Documentation/ftrace.txt
--- linux-libre-2.6.29-gnu1/Documentation/ftrace.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ftrace.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,1424 +0,0 @@
-		ftrace - Function Tracer
-		========================
-
-Copyright 2008 Red Hat Inc.
-   Author:   Steven Rostedt <srostedt@redhat.com>
-  License:   The GNU Free Documentation License, Version 1.2
-               (dual licensed under the GPL v2)
-Reviewers:   Elias Oltmanns, Randy Dunlap, Andrew Morton,
-	     John Kacur, and David Teigland.
-
-Written for: 2.6.28-rc2
-
-Introduction
-------------
-
-Ftrace is an internal tracer designed to help out developers and
-designers of systems to find what is going on inside the kernel.
-It can be used for debugging or analyzing latencies and performance
-issues that take place outside of user-space.
-
-Although ftrace is the function tracer, it also includes an
-infrastructure that allows for other types of tracing. Some of the
-tracers that are currently in ftrace include a tracer to trace
-context switches, the time it takes for a high priority task to
-run after it was woken up, the time interrupts are disabled, and
-more (ftrace allows for tracer plugins, which means that the list of
-tracers can always grow).
-
-
-The File System
----------------
-
-Ftrace uses the debugfs file system to hold the control files as well
-as the files to display output.
-
-To mount the debugfs system:
-
-  # mkdir /debug
-  # mount -t debugfs nodev /debug
-
-(Note: it is more common to mount at /sys/kernel/debug, but for simplicity
- this document will use /debug)
-
-That's it! (assuming that you have ftrace configured into your kernel)
-
-After mounting the debugfs, you can see a directory called
-"tracing".  This directory contains the control and output files
-of ftrace. Here is a list of some of the key files:
-
-
- Note: all time values are in microseconds.
-
-  current_tracer: This is used to set or display the current tracer
-		that is configured.
-
-  available_tracers: This holds the different types of tracers that
-		have been compiled into the kernel. The tracers
-		listed here can be configured by echoing their name
-		into current_tracer.
-
-  tracing_enabled: This sets or displays whether the current_tracer
-		is activated and tracing or not. Echo 0 into this
-		file to disable the tracer or 1 to enable it.
-
-  trace: This file holds the output of the trace in a human readable
-		format (described below).
-
-  latency_trace: This file shows the same trace but the information
-		is organized more to display possible latencies
-		in the system (described below).
-
-  trace_pipe: The output is the same as the "trace" file but this
-		file is meant to be streamed with live tracing.
-		Reads from this file will block until new data
-		is retrieved. Unlike the "trace" and "latency_trace"
-		files, this file is a consumer. This means reading
-		from this file causes sequential reads to display
-		more current data. Once data is read from this
-		file, it is consumed, and will not be read
-		again with a sequential read. The "trace" and
-		"latency_trace" files are static, and if the
-		tracer is not adding more data, they will display
-		the same information every time they are read.
-
-  trace_options: This file lets the user control the amount of data
-		that is displayed in one of the above output
-		files.
-
-  trace_max_latency: Some of the tracers record the max latency.
-		For example, the time interrupts are disabled.
-		This time is saved in this file. The max trace
-		will also be stored, and displayed by either
-		"trace" or "latency_trace".  A new max trace will
-		only be recorded if the latency is greater than
-		the value in this file. (in microseconds)
-
-  buffer_size_kb: This sets or displays the number of kilobytes each CPU
-		buffer can hold. The tracer buffers are the same size
-		for each CPU. The displayed number is the size of the
-		CPU buffer and not total size of all buffers. The
-		trace buffers are allocated in pages (blocks of memory
-		that the kernel uses for allocation, usually 4 KB in size).
-		If the last page allocated has room for more bytes
-		than requested, the rest of the page will be used,
-		making the actual allocation bigger than requested.
-		(Note, the size may not be a multiple of the page size due
-		to buffer managment overhead.)
-
-		This can only be updated when the current_tracer
-		is set to "nop".
-
-  tracing_cpumask: This is a mask that lets the user only trace
-		on specified CPUS. The format is a hex string
-		representing the CPUS.
-
-  set_ftrace_filter: When dynamic ftrace is configured in (see the
-		section below "dynamic ftrace"), the code is dynamically
-		modified (code text rewrite) to disable calling of the
-		function profiler (mcount). This lets tracing be configured
-		in with practically no overhead in performance.  This also
-		has a side effect of enabling or disabling specific functions
-		to be traced. Echoing names of functions into this file
-		will limit the trace to only those functions.
-
-  set_ftrace_notrace: This has an effect opposite to that of
-		set_ftrace_filter. Any function that is added here will not
-		be traced. If a function exists in both set_ftrace_filter
-		and set_ftrace_notrace,	the function will _not_ be traced.
-
-  set_ftrace_pid: Have the function tracer only trace a single thread.
-
-  available_filter_functions: This lists the functions that ftrace
-		has processed and can trace. These are the function
-		names that you can pass to "set_ftrace_filter" or
-		"set_ftrace_notrace". (See the section "dynamic ftrace"
-		below for more details.)
-
-
-The Tracers
------------
-
-Here is the list of current tracers that may be configured.
-
-  function - function tracer that uses mcount to trace all functions.
-
-  sched_switch - traces the context switches between tasks.
-
-  irqsoff - traces the areas that disable interrupts and saves
-  		the trace with the longest max latency.
-		See tracing_max_latency.  When a new max is recorded,
-		it replaces the old trace. It is best to view this
-		trace via the latency_trace file.
-
-  preemptoff - Similar to irqsoff but traces and records the amount of
-		time for which preemption is disabled.
-
-  preemptirqsoff - Similar to irqsoff and preemptoff, but traces and
-		 records the largest time for which irqs and/or preemption
-		 is disabled.
-
-  wakeup - Traces and records the max latency that it takes for
-		the highest priority task to get scheduled after
-		it has been woken up.
-
-  nop - This is not a tracer. To remove all tracers from tracing
-		simply echo "nop" into current_tracer.
-
-
-Examples of using the tracer
-----------------------------
-
-Here are typical examples of using the tracers when controlling them only
-with the debugfs interface (without using any user-land utilities).
-
-Output format:
---------------
-
-Here is an example of the output format of the file "trace"
-
-                             --------
-# tracer: function
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-            bash-4251  [01] 10152.583854: path_put <-path_walk
-            bash-4251  [01] 10152.583855: dput <-path_put
-            bash-4251  [01] 10152.583855: _atomic_dec_and_lock <-dput
-                             --------
-
-A header is printed with the tracer name that is represented by the trace.
-In this case the tracer is "function". Then a header showing the format. Task
-name "bash", the task PID "4251", the CPU that it was running on
-"01", the timestamp in <secs>.<usecs> format, the function name that was
-traced "path_put" and the parent function that called this function
-"path_walk". The timestamp is the time at which the function was
-entered.
-
-The sched_switch tracer also includes tracing of task wakeups and
-context switches.
-
-     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +  2916:115:S
-     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +    10:115:S
-     ksoftirqd/1-7     [01]  1453.070013:      7:115:R ==>    10:115:R
-        events/1-10    [01]  1453.070013:     10:115:S ==>  2916:115:R
-     kondemand/1-2916  [01]  1453.070013:   2916:115:S ==>     7:115:R
-     ksoftirqd/1-7     [01]  1453.070013:      7:115:S ==>     0:140:R
-
-Wake ups are represented by a "+" and the context switches are shown as
-"==>".  The format is:
-
- Context switches:
-
-       Previous task              Next Task
-
-  <pid>:<prio>:<state>  ==>  <pid>:<prio>:<state>
-
- Wake ups:
-
-       Current task               Task waking up
-
-  <pid>:<prio>:<state>    +  <pid>:<prio>:<state>
-
-The prio is the internal kernel priority, which is the inverse of the
-priority that is usually displayed by user-space tools. Zero represents
-the highest priority (99). Prio 100 starts the "nice" priorities with
-100 being equal to nice -20 and 139 being nice 19. The prio "140" is
-reserved for the idle task which is the lowest priority thread (pid 0).
-
-
-Latency trace format
---------------------
-
-For traces that display latency times, the latency_trace file gives
-somewhat more information to see why a latency happened. Here is a typical
-trace.
-
-# tracer: irqsoff
-#
-irqsoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 97 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: apic_timer_interrupt
- => ended at:   do_softirq
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-  <idle>-0     0d..1    0us+: trace_hardirqs_off_thunk (apic_timer_interrupt)
-  <idle>-0     0d.s.   97us : __do_softirq (do_softirq)
-  <idle>-0     0d.s1   98us : trace_hardirqs_on (do_softirq)
-
-
-
-This shows that the current tracer is "irqsoff" tracing the time for which
-interrupts were disabled. It gives the trace version and the version
-of the kernel upon which this was executed on (2.6.26-rc8). Then it displays
-the max latency in microsecs (97 us). The number of trace entries displayed
-and the total number recorded (both are three: #3/3). The type of
-preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero
-and are reserved for later use. #P is the number of online CPUS (#P:2).
-
-The task is the process that was running when the latency occurred.
-(swapper pid: 0).
-
-The start and stop (the functions in which the interrupts were disabled and
-enabled respectively) that caused the latencies:
-
-  apic_timer_interrupt is where the interrupts were disabled.
-  do_softirq is where they were enabled again.
-
-The next lines after the header are the trace itself. The header
-explains which is which.
-
-  cmd: The name of the process in the trace.
-
-  pid: The PID of that process.
-
-  CPU#: The CPU which the process was running on.
-
-  irqs-off: 'd' interrupts are disabled. '.' otherwise.
-	    Note: If the architecture does not support a way to
-		  read the irq flags variable, an 'X' will always
-		  be printed here.
-
-  need-resched: 'N' task need_resched is set, '.' otherwise.
-
-  hardirq/softirq:
-	'H' - hard irq occurred inside a softirq.
-	'h' - hard irq is running
-	's' - soft irq is running
-	'.' - normal context.
-
-  preempt-depth: The level of preempt_disabled
-
-The above is mostly meaningful for kernel developers.
-
-  time: This differs from the trace file output. The trace file output
-	includes an absolute timestamp. The timestamp used by the
-	latency_trace file is relative to the start of the trace.
-
-  delay: This is just to help catch your eye a bit better. And
-	needs to be fixed to be only relative to the same CPU.
-	The marks are determined by the difference between this
-	current trace and the next trace.
-	 '!' - greater than preempt_mark_thresh (default 100)
-	 '+' - greater than 1 microsecond
-	 ' ' - less than or equal to 1 microsecond.
-
-  The rest is the same as the 'trace' file.
-
-
-trace_options
--------------
-
-The trace_options file is used to control what gets printed in the trace
-output. To see what is available, simply cat the file:
-
-  cat /debug/tracing/trace_options
-  print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
- noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
-
-To disable one of the options, echo in the option prepended with "no".
-
-  echo noprint-parent > /debug/tracing/trace_options
-
-To enable an option, leave off the "no".
-
-  echo sym-offset > /debug/tracing/trace_options
-
-Here are the available options:
-
-  print-parent - On function traces, display the calling function
-		as well as the function being traced.
-
-  print-parent:
-   bash-4000  [01]  1477.606694: simple_strtoul <-strict_strtoul
-
-  noprint-parent:
-   bash-4000  [01]  1477.606694: simple_strtoul
-
-
-  sym-offset - Display not only the function name, but also the offset
-		in the function. For example, instead of seeing just
-		"ktime_get", you will see "ktime_get+0xb/0x20".
-
-  sym-offset:
-   bash-4000  [01]  1477.606694: simple_strtoul+0x6/0xa0
-
-  sym-addr - this will also display the function address as well as
-		the function name.
-
-  sym-addr:
-   bash-4000  [01]  1477.606694: simple_strtoul <c0339346>
-
-  verbose - This deals with the latency_trace file.
-
-    bash  4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
-    (+0.000ms): simple_strtoul (strict_strtoul)
-
-  raw - This will display raw numbers. This option is best for use with
-	user applications that can translate the raw numbers better than
-	having it done in the kernel.
-
-  hex - Similar to raw, but the numbers will be in a hexadecimal format.
-
-  bin - This will print out the formats in raw binary.
-
-  block - TBD (needs update)
-
-  stacktrace - This is one of the options that changes the trace itself.
-		When a trace is recorded, so is the stack of functions.
-		This allows for back traces of trace sites.
-
-  userstacktrace - This option changes the trace.
-		   It records a stacktrace of the current userspace thread.
-
-  sym-userobj - when user stacktrace are enabled, look up which object the
-		address belongs to, and print a relative address
-		This is especially useful when ASLR is on, otherwise you don't
-		get a chance to resolve the address to object/file/line after the app is no
-		longer running
-
-		The lookup is performed when you read trace,trace_pipe,latency_trace. Example:
-
-		a.out-1623  [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
-x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
-
-  sched-tree - TBD (any users??)
-
-
-sched_switch
-------------
-
-This tracer simply records schedule switches. Here is an example
-of how to use it.
-
- # echo sched_switch > /debug/tracing/current_tracer
- # echo 1 > /debug/tracing/tracing_enabled
- # sleep 1
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/trace
-
-# tracer: sched_switch
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-            bash-3997  [01]   240.132281:   3997:120:R   +  4055:120:R
-            bash-3997  [01]   240.132284:   3997:120:R ==>  4055:120:R
-           sleep-4055  [01]   240.132371:   4055:120:S ==>  3997:120:R
-            bash-3997  [01]   240.132454:   3997:120:R   +  4055:120:S
-            bash-3997  [01]   240.132457:   3997:120:R ==>  4055:120:R
-           sleep-4055  [01]   240.132460:   4055:120:D ==>  3997:120:R
-            bash-3997  [01]   240.132463:   3997:120:R   +  4055:120:D
-            bash-3997  [01]   240.132465:   3997:120:R ==>  4055:120:R
-          <idle>-0     [00]   240.132589:      0:140:R   +     4:115:S
-          <idle>-0     [00]   240.132591:      0:140:R ==>     4:115:R
-     ksoftirqd/0-4     [00]   240.132595:      4:115:S ==>     0:140:R
-          <idle>-0     [00]   240.132598:      0:140:R   +     4:115:S
-          <idle>-0     [00]   240.132599:      0:140:R ==>     4:115:R
-     ksoftirqd/0-4     [00]   240.132603:      4:115:S ==>     0:140:R
-           sleep-4055  [01]   240.133058:   4055:120:S ==>  3997:120:R
- [...]
-
-
-As we have discussed previously about this format, the header shows
-the name of the trace and points to the options. The "FUNCTION"
-is a misnomer since here it represents the wake ups and context
-switches.
-
-The sched_switch file only lists the wake ups (represented with '+')
-and context switches ('==>') with the previous task or current task
-first followed by the next task or task waking up. The format for both
-of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO
-is the inverse of the actual priority with zero (0) being the highest
-priority and the nice values starting at 100 (nice -20). Below is
-a quick chart to map the kernel priority to user land priorities.
-
-  Kernel priority: 0 to 99    ==> user RT priority 99 to 0
-  Kernel priority: 100 to 139 ==> user nice -20 to 19
-  Kernel priority: 140        ==> idle task priority
-
-The task states are:
-
- R - running : wants to run, may not actually be running
- S - sleep   : process is waiting to be woken up (handles signals)
- D - disk sleep (uninterruptible sleep) : process must be woken up
-					(ignores signals)
- T - stopped : process suspended
- t - traced  : process is being traced (with something like gdb)
- Z - zombie  : process waiting to be cleaned up
- X - unknown
-
-
-ftrace_enabled
---------------
-
-The following tracers (listed below) give different output depending
-on whether or not the sysctl ftrace_enabled is set. To set ftrace_enabled,
-one can either use the sysctl function or set it via the proc
-file system interface.
-
-  sysctl kernel.ftrace_enabled=1
-
- or
-
-  echo 1 > /proc/sys/kernel/ftrace_enabled
-
-To disable ftrace_enabled simply replace the '1' with '0' in
-the above commands.
-
-When ftrace_enabled is set the tracers will also record the functions
-that are within the trace. The descriptions of the tracers
-will also show an example with ftrace enabled.
-
-
-irqsoff
--------
-
-When interrupts are disabled, the CPU can not react to any other
-external event (besides NMIs and SMIs). This prevents the timer
-interrupt from triggering or the mouse interrupt from letting the
-kernel know of a new mouse event. The result is a latency with the
-reaction time.
-
-The irqsoff tracer tracks the time for which interrupts are disabled.
-When a new maximum latency is hit, the tracer saves the trace leading up
-to that latency point so that every time a new maximum is reached, the old
-saved trace is discarded and the new trace is saved.
-
-To reset the maximum, echo 0 into tracing_max_latency. Here is an
-example:
-
- # echo irqsoff > /debug/tracing/current_tracer
- # echo 0 > /debug/tracing/tracing_max_latency
- # echo 1 > /debug/tracing/tracing_enabled
- # ls -ltr
- [...]
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/latency_trace
-# tracer: irqsoff
-#
-irqsoff latency trace v1.1.5 on 2.6.26
---------------------------------------------------------------------
- latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: sys_setpgid
- => ended at:   sys_setpgid
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-    bash-3730  1d...    0us : _write_lock_irq (sys_setpgid)
-    bash-3730  1d..1    1us+: _write_unlock_irq (sys_setpgid)
-    bash-3730  1d..2   14us : trace_hardirqs_on (sys_setpgid)
-
-
-Here we see that that we had a latency of 12 microsecs (which is
-very good). The _write_lock_irq in sys_setpgid disabled interrupts.
-The difference between the 12 and the displayed timestamp 14us occurred
-because the clock was incremented between the time of recording the max
-latency and the time of recording the function that had that latency.
-
-Note the above example had ftrace_enabled not set. If we set the
-ftrace_enabled, we get a much larger output:
-
-# tracer: irqsoff
-#
-irqsoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 50 us, #101/101, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: ls-4339 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: __alloc_pages_internal
- => ended at:   __alloc_pages_internal
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-      ls-4339  0...1    0us+: get_page_from_freelist (__alloc_pages_internal)
-      ls-4339  0d..1    3us : rmqueue_bulk (get_page_from_freelist)
-      ls-4339  0d..1    3us : _spin_lock (rmqueue_bulk)
-      ls-4339  0d..1    4us : add_preempt_count (_spin_lock)
-      ls-4339  0d..2    4us : __rmqueue (rmqueue_bulk)
-      ls-4339  0d..2    5us : __rmqueue_smallest (__rmqueue)
-      ls-4339  0d..2    5us : __mod_zone_page_state (__rmqueue_smallest)
-      ls-4339  0d..2    6us : __rmqueue (rmqueue_bulk)
-      ls-4339  0d..2    6us : __rmqueue_smallest (__rmqueue)
-      ls-4339  0d..2    7us : __mod_zone_page_state (__rmqueue_smallest)
-      ls-4339  0d..2    7us : __rmqueue (rmqueue_bulk)
-      ls-4339  0d..2    8us : __rmqueue_smallest (__rmqueue)
-[...]
-      ls-4339  0d..2   46us : __rmqueue_smallest (__rmqueue)
-      ls-4339  0d..2   47us : __mod_zone_page_state (__rmqueue_smallest)
-      ls-4339  0d..2   47us : __rmqueue (rmqueue_bulk)
-      ls-4339  0d..2   48us : __rmqueue_smallest (__rmqueue)
-      ls-4339  0d..2   48us : __mod_zone_page_state (__rmqueue_smallest)
-      ls-4339  0d..2   49us : _spin_unlock (rmqueue_bulk)
-      ls-4339  0d..2   49us : sub_preempt_count (_spin_unlock)
-      ls-4339  0d..1   50us : get_page_from_freelist (__alloc_pages_internal)
-      ls-4339  0d..2   51us : trace_hardirqs_on (__alloc_pages_internal)
-
-
-
-Here we traced a 50 microsecond latency. But we also see all the
-functions that were called during that time. Note that by enabling
-function tracing, we incur an added overhead. This overhead may
-extend the latency times. But nevertheless, this trace has provided
-some very helpful debugging information.
-
-
-preemptoff
-----------
-
-When preemption is disabled, we may be able to receive interrupts but
-the task cannot be preempted and a higher priority task must wait
-for preemption to be enabled again before it can preempt a lower
-priority task.
-
-The preemptoff tracer traces the places that disable preemption.
-Like the irqsoff tracer, it records the maximum latency for which preemption
-was disabled. The control of preemptoff tracer is much like the irqsoff
-tracer.
-
- # echo preemptoff > /debug/tracing/current_tracer
- # echo 0 > /debug/tracing/tracing_max_latency
- # echo 1 > /debug/tracing/tracing_enabled
- # ls -ltr
- [...]
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/latency_trace
-# tracer: preemptoff
-#
-preemptoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 29 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: do_IRQ
- => ended at:   __do_softirq
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-    sshd-4261  0d.h.    0us+: irq_enter (do_IRQ)
-    sshd-4261  0d.s.   29us : _local_bh_enable (__do_softirq)
-    sshd-4261  0d.s1   30us : trace_preempt_on (__do_softirq)
-
-
-This has some more changes. Preemption was disabled when an interrupt
-came in (notice the 'h'), and was enabled while doing a softirq.
-(notice the 's'). But we also see that interrupts have been disabled
-when entering the preempt off section and leaving it (the 'd').
-We do not know if interrupts were enabled in the mean time.
-
-# tracer: preemptoff
-#
-preemptoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 63 us, #87/87, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: remove_wait_queue
- => ended at:   __do_softirq
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-    sshd-4261  0d..1    0us : _spin_lock_irqsave (remove_wait_queue)
-    sshd-4261  0d..1    1us : _spin_unlock_irqrestore (remove_wait_queue)
-    sshd-4261  0d..1    2us : do_IRQ (common_interrupt)
-    sshd-4261  0d..1    2us : irq_enter (do_IRQ)
-    sshd-4261  0d..1    2us : idle_cpu (irq_enter)
-    sshd-4261  0d..1    3us : add_preempt_count (irq_enter)
-    sshd-4261  0d.h1    3us : idle_cpu (irq_enter)
-    sshd-4261  0d.h.    4us : handle_fasteoi_irq (do_IRQ)
-[...]
-    sshd-4261  0d.h.   12us : add_preempt_count (_spin_lock)
-    sshd-4261  0d.h1   12us : ack_ioapic_quirk_irq (handle_fasteoi_irq)
-    sshd-4261  0d.h1   13us : move_native_irq (ack_ioapic_quirk_irq)
-    sshd-4261  0d.h1   13us : _spin_unlock (handle_fasteoi_irq)
-    sshd-4261  0d.h1   14us : sub_preempt_count (_spin_unlock)
-    sshd-4261  0d.h1   14us : irq_exit (do_IRQ)
-    sshd-4261  0d.h1   15us : sub_preempt_count (irq_exit)
-    sshd-4261  0d..2   15us : do_softirq (irq_exit)
-    sshd-4261  0d...   15us : __do_softirq (do_softirq)
-    sshd-4261  0d...   16us : __local_bh_disable (__do_softirq)
-    sshd-4261  0d...   16us+: add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s4   20us : add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s4   21us : sub_preempt_count (local_bh_enable)
-    sshd-4261  0d.s5   21us : sub_preempt_count (local_bh_enable)
-[...]
-    sshd-4261  0d.s6   41us : add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s6   42us : sub_preempt_count (local_bh_enable)
-    sshd-4261  0d.s7   42us : sub_preempt_count (local_bh_enable)
-    sshd-4261  0d.s5   43us : add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s5   43us : sub_preempt_count (local_bh_enable_ip)
-    sshd-4261  0d.s6   44us : sub_preempt_count (local_bh_enable_ip)
-    sshd-4261  0d.s5   44us : add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s5   45us : sub_preempt_count (local_bh_enable)
-[...]
-    sshd-4261  0d.s.   63us : _local_bh_enable (__do_softirq)
-    sshd-4261  0d.s1   64us : trace_preempt_on (__do_softirq)
-
-
-The above is an example of the preemptoff trace with ftrace_enabled
-set. Here we see that interrupts were disabled the entire time.
-The irq_enter code lets us know that we entered an interrupt 'h'.
-Before that, the functions being traced still show that it is not
-in an interrupt, but we can see from the functions themselves that
-this is not the case.
-
-Notice that __do_softirq when called does not have a preempt_count.
-It may seem that we missed a preempt enabling. What really happened
-is that the preempt count is held on the thread's stack and we
-switched to the softirq stack (4K stacks in effect). The code
-does not copy the preempt count, but because interrupts are disabled,
-we do not need to worry about it. Having a tracer like this is good
-for letting people know what really happens inside the kernel.
-
-
-preemptirqsoff
---------------
-
-Knowing the locations that have interrupts disabled or preemption
-disabled for the longest times is helpful. But sometimes we would
-like to know when either preemption and/or interrupts are disabled.
-
-Consider the following code:
-
-    local_irq_disable();
-    call_function_with_irqs_off();
-    preempt_disable();
-    call_function_with_irqs_and_preemption_off();
-    local_irq_enable();
-    call_function_with_preemption_off();
-    preempt_enable();
-
-The irqsoff tracer will record the total length of
-call_function_with_irqs_off() and
-call_function_with_irqs_and_preemption_off().
-
-The preemptoff tracer will record the total length of
-call_function_with_irqs_and_preemption_off() and
-call_function_with_preemption_off().
-
-But neither will trace the time that interrupts and/or preemption
-is disabled. This total time is the time that we can not schedule.
-To record this time, use the preemptirqsoff tracer.
-
-Again, using this trace is much like the irqsoff and preemptoff tracers.
-
- # echo preemptirqsoff > /debug/tracing/current_tracer
- # echo 0 > /debug/tracing/tracing_max_latency
- # echo 1 > /debug/tracing/tracing_enabled
- # ls -ltr
- [...]
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/latency_trace
-# tracer: preemptirqsoff
-#
-preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 293 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: ls-4860 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: apic_timer_interrupt
- => ended at:   __do_softirq
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-      ls-4860  0d...    0us!: trace_hardirqs_off_thunk (apic_timer_interrupt)
-      ls-4860  0d.s.  294us : _local_bh_enable (__do_softirq)
-      ls-4860  0d.s1  294us : trace_preempt_on (__do_softirq)
-
-
-
-The trace_hardirqs_off_thunk is called from assembly on x86 when
-interrupts are disabled in the assembly code. Without the function
-tracing, we do not know if interrupts were enabled within the preemption
-points. We do see that it started with preemption enabled.
-
-Here is a trace with ftrace_enabled set:
-
-
-# tracer: preemptirqsoff
-#
-preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 105 us, #183/183, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
-    -----------------
- => started at: write_chan
- => ended at:   __do_softirq
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-      ls-4473  0.N..    0us : preempt_schedule (write_chan)
-      ls-4473  0dN.1    1us : _spin_lock (schedule)
-      ls-4473  0dN.1    2us : add_preempt_count (_spin_lock)
-      ls-4473  0d..2    2us : put_prev_task_fair (schedule)
-[...]
-      ls-4473  0d..2   13us : set_normalized_timespec (ktime_get_ts)
-      ls-4473  0d..2   13us : __switch_to (schedule)
-    sshd-4261  0d..2   14us : finish_task_switch (schedule)
-    sshd-4261  0d..2   14us : _spin_unlock_irq (finish_task_switch)
-    sshd-4261  0d..1   15us : add_preempt_count (_spin_lock_irqsave)
-    sshd-4261  0d..2   16us : _spin_unlock_irqrestore (hrtick_set)
-    sshd-4261  0d..2   16us : do_IRQ (common_interrupt)
-    sshd-4261  0d..2   17us : irq_enter (do_IRQ)
-    sshd-4261  0d..2   17us : idle_cpu (irq_enter)
-    sshd-4261  0d..2   18us : add_preempt_count (irq_enter)
-    sshd-4261  0d.h2   18us : idle_cpu (irq_enter)
-    sshd-4261  0d.h.   18us : handle_fasteoi_irq (do_IRQ)
-    sshd-4261  0d.h.   19us : _spin_lock (handle_fasteoi_irq)
-    sshd-4261  0d.h.   19us : add_preempt_count (_spin_lock)
-    sshd-4261  0d.h1   20us : _spin_unlock (handle_fasteoi_irq)
-    sshd-4261  0d.h1   20us : sub_preempt_count (_spin_unlock)
-[...]
-    sshd-4261  0d.h1   28us : _spin_unlock (handle_fasteoi_irq)
-    sshd-4261  0d.h1   29us : sub_preempt_count (_spin_unlock)
-    sshd-4261  0d.h2   29us : irq_exit (do_IRQ)
-    sshd-4261  0d.h2   29us : sub_preempt_count (irq_exit)
-    sshd-4261  0d..3   30us : do_softirq (irq_exit)
-    sshd-4261  0d...   30us : __do_softirq (do_softirq)
-    sshd-4261  0d...   31us : __local_bh_disable (__do_softirq)
-    sshd-4261  0d...   31us+: add_preempt_count (__local_bh_disable)
-    sshd-4261  0d.s4   34us : add_preempt_count (__local_bh_disable)
-[...]
-    sshd-4261  0d.s3   43us : sub_preempt_count (local_bh_enable_ip)
-    sshd-4261  0d.s4   44us : sub_preempt_count (local_bh_enable_ip)
-    sshd-4261  0d.s3   44us : smp_apic_timer_interrupt (apic_timer_interrupt)
-    sshd-4261  0d.s3   45us : irq_enter (smp_apic_timer_interrupt)
-    sshd-4261  0d.s3   45us : idle_cpu (irq_enter)
-    sshd-4261  0d.s3   46us : add_preempt_count (irq_enter)
-    sshd-4261  0d.H3   46us : idle_cpu (irq_enter)
-    sshd-4261  0d.H3   47us : hrtimer_interrupt (smp_apic_timer_interrupt)
-    sshd-4261  0d.H3   47us : ktime_get (hrtimer_interrupt)
-[...]
-    sshd-4261  0d.H3   81us : tick_program_event (hrtimer_interrupt)
-    sshd-4261  0d.H3   82us : ktime_get (tick_program_event)
-    sshd-4261  0d.H3   82us : ktime_get_ts (ktime_get)
-    sshd-4261  0d.H3   83us : getnstimeofday (ktime_get_ts)
-    sshd-4261  0d.H3   83us : set_normalized_timespec (ktime_get_ts)
-    sshd-4261  0d.H3   84us : clockevents_program_event (tick_program_event)
-    sshd-4261  0d.H3   84us : lapic_next_event (clockevents_program_event)
-    sshd-4261  0d.H3   85us : irq_exit (smp_apic_timer_interrupt)
-    sshd-4261  0d.H3   85us : sub_preempt_count (irq_exit)
-    sshd-4261  0d.s4   86us : sub_preempt_count (irq_exit)
-    sshd-4261  0d.s3   86us : add_preempt_count (__local_bh_disable)
-[...]
-    sshd-4261  0d.s1   98us : sub_preempt_count (net_rx_action)
-    sshd-4261  0d.s.   99us : add_preempt_count (_spin_lock_irq)
-    sshd-4261  0d.s1   99us+: _spin_unlock_irq (run_timer_softirq)
-    sshd-4261  0d.s.  104us : _local_bh_enable (__do_softirq)
-    sshd-4261  0d.s.  104us : sub_preempt_count (_local_bh_enable)
-    sshd-4261  0d.s.  105us : _local_bh_enable (__do_softirq)
-    sshd-4261  0d.s1  105us : trace_preempt_on (__do_softirq)
-
-
-This is a very interesting trace. It started with the preemption of
-the ls task. We see that the task had the "need_resched" bit set
-via the 'N' in the trace.  Interrupts were disabled before the spin_lock
-at the beginning of the trace. We see that a schedule took place to run
-sshd.  When the interrupts were enabled, we took an interrupt.
-On return from the interrupt handler, the softirq ran. We took another
-interrupt while running the softirq as we see from the capital 'H'.
-
-
-wakeup
-------
-
-In a Real-Time environment it is very important to know the wakeup
-time it takes for the highest priority task that is woken up to the
-time that it executes. This is also known as "schedule latency".
-I stress the point that this is about RT tasks. It is also important
-to know the scheduling latency of non-RT tasks, but the average
-schedule latency is better for non-RT tasks. Tools like
-LatencyTop are more appropriate for such measurements.
-
-Real-Time environments are interested in the worst case latency.
-That is the longest latency it takes for something to happen, and
-not the average. We can have a very fast scheduler that may only
-have a large latency once in a while, but that would not work well
-with Real-Time tasks.  The wakeup tracer was designed to record
-the worst case wakeups of RT tasks. Non-RT tasks are not recorded
-because the tracer only records one worst case and tracing non-RT
-tasks that are unpredictable will overwrite the worst case latency
-of RT tasks.
-
-Since this tracer only deals with RT tasks, we will run this slightly
-differently than we did with the previous tracers. Instead of performing
-an 'ls', we will run 'sleep 1' under 'chrt' which changes the
-priority of the task.
-
- # echo wakeup > /debug/tracing/current_tracer
- # echo 0 > /debug/tracing/tracing_max_latency
- # echo 1 > /debug/tracing/tracing_enabled
- # chrt -f 5 sleep 1
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/latency_trace
-# tracer: wakeup
-#
-wakeup latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 4 us, #2/2, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: sleep-4901 (uid:0 nice:0 policy:1 rt_prio:5)
-    -----------------
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-  <idle>-0     1d.h4    0us+: try_to_wake_up (wake_up_process)
-  <idle>-0     1d..4    4us : schedule (cpu_idle)
-
-
-
-Running this on an idle system, we see that it only took 4 microseconds
-to perform the task switch.  Note, since the trace marker in the
-schedule is before the actual "switch", we stop the tracing when
-the recorded task is about to schedule in. This may change if
-we add a new marker at the end of the scheduler.
-
-Notice that the recorded task is 'sleep' with the PID of 4901 and it
-has an rt_prio of 5. This priority is user-space priority and not
-the internal kernel priority. The policy is 1 for SCHED_FIFO and 2
-for SCHED_RR.
-
-Doing the same with chrt -r 5 and ftrace_enabled set.
-
-# tracer: wakeup
-#
-wakeup latency trace v1.1.5 on 2.6.26-rc8
---------------------------------------------------------------------
- latency: 50 us, #60/60, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
-    -----------------
-    | task: sleep-4068 (uid:0 nice:0 policy:2 rt_prio:5)
-    -----------------
-
-#                _------=> CPU#
-#               / _-----=> irqs-off
-#              | / _----=> need-resched
-#              || / _---=> hardirq/softirq
-#              ||| / _--=> preempt-depth
-#              |||| /
-#              |||||     delay
-#  cmd     pid ||||| time  |   caller
-#     \   /    |||||   \   |   /
-ksoftirq-7     1d.H3    0us : try_to_wake_up (wake_up_process)
-ksoftirq-7     1d.H4    1us : sub_preempt_count (marker_probe_cb)
-ksoftirq-7     1d.H3    2us : check_preempt_wakeup (try_to_wake_up)
-ksoftirq-7     1d.H3    3us : update_curr (check_preempt_wakeup)
-ksoftirq-7     1d.H3    4us : calc_delta_mine (update_curr)
-ksoftirq-7     1d.H3    5us : __resched_task (check_preempt_wakeup)
-ksoftirq-7     1d.H3    6us : task_wake_up_rt (try_to_wake_up)
-ksoftirq-7     1d.H3    7us : _spin_unlock_irqrestore (try_to_wake_up)
-[...]
-ksoftirq-7     1d.H2   17us : irq_exit (smp_apic_timer_interrupt)
-ksoftirq-7     1d.H2   18us : sub_preempt_count (irq_exit)
-ksoftirq-7     1d.s3   19us : sub_preempt_count (irq_exit)
-ksoftirq-7     1..s2   20us : rcu_process_callbacks (__do_softirq)
-[...]
-ksoftirq-7     1..s2   26us : __rcu_process_callbacks (rcu_process_callbacks)
-ksoftirq-7     1d.s2   27us : _local_bh_enable (__do_softirq)
-ksoftirq-7     1d.s2   28us : sub_preempt_count (_local_bh_enable)
-ksoftirq-7     1.N.3   29us : sub_preempt_count (ksoftirqd)
-ksoftirq-7     1.N.2   30us : _cond_resched (ksoftirqd)
-ksoftirq-7     1.N.2   31us : __cond_resched (_cond_resched)
-ksoftirq-7     1.N.2   32us : add_preempt_count (__cond_resched)
-ksoftirq-7     1.N.2   33us : schedule (__cond_resched)
-ksoftirq-7     1.N.2   33us : add_preempt_count (schedule)
-ksoftirq-7     1.N.3   34us : hrtick_clear (schedule)
-ksoftirq-7     1dN.3   35us : _spin_lock (schedule)
-ksoftirq-7     1dN.3   36us : add_preempt_count (_spin_lock)
-ksoftirq-7     1d..4   37us : put_prev_task_fair (schedule)
-ksoftirq-7     1d..4   38us : update_curr (put_prev_task_fair)
-[...]
-ksoftirq-7     1d..5   47us : _spin_trylock (tracing_record_cmdline)
-ksoftirq-7     1d..5   48us : add_preempt_count (_spin_trylock)
-ksoftirq-7     1d..6   49us : _spin_unlock (tracing_record_cmdline)
-ksoftirq-7     1d..6   49us : sub_preempt_count (_spin_unlock)
-ksoftirq-7     1d..4   50us : schedule (__cond_resched)
-
-The interrupt went off while running ksoftirqd. This task runs at
-SCHED_OTHER. Why did not we see the 'N' set early? This may be
-a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks
-configured, the interrupt and softirq run with their own stack.
-Some information is held on the top of the task's stack (need_resched
-and preempt_count are both stored there). The setting of the NEED_RESCHED
-bit is done directly to the task's stack, but the reading of the
-NEED_RESCHED is done by looking at the current stack, which in this case
-is the stack for the hard interrupt. This hides the fact that NEED_RESCHED
-has been set. We do not see the 'N' until we switch back to the task's
-assigned stack.
-
-function
---------
-
-This tracer is the function tracer. Enabling the function tracer
-can be done from the debug file system. Make sure the ftrace_enabled is
-set; otherwise this tracer is a nop.
-
- # sysctl kernel.ftrace_enabled=1
- # echo function > /debug/tracing/current_tracer
- # echo 1 > /debug/tracing/tracing_enabled
- # usleep 1
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/trace
-# tracer: function
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-            bash-4003  [00]   123.638713: finish_task_switch <-schedule
-            bash-4003  [00]   123.638714: _spin_unlock_irq <-finish_task_switch
-            bash-4003  [00]   123.638714: sub_preempt_count <-_spin_unlock_irq
-            bash-4003  [00]   123.638715: hrtick_set <-schedule
-            bash-4003  [00]   123.638715: _spin_lock_irqsave <-hrtick_set
-            bash-4003  [00]   123.638716: add_preempt_count <-_spin_lock_irqsave
-            bash-4003  [00]   123.638716: _spin_unlock_irqrestore <-hrtick_set
-            bash-4003  [00]   123.638717: sub_preempt_count <-_spin_unlock_irqrestore
-            bash-4003  [00]   123.638717: hrtick_clear <-hrtick_set
-            bash-4003  [00]   123.638718: sub_preempt_count <-schedule
-            bash-4003  [00]   123.638718: sub_preempt_count <-preempt_schedule
-            bash-4003  [00]   123.638719: wait_for_completion <-__stop_machine_run
-            bash-4003  [00]   123.638719: wait_for_common <-wait_for_completion
-            bash-4003  [00]   123.638720: _spin_lock_irq <-wait_for_common
-            bash-4003  [00]   123.638720: add_preempt_count <-_spin_lock_irq
-[...]
-
-
-Note: function tracer uses ring buffers to store the above entries.
-The newest data may overwrite the oldest data. Sometimes using echo to
-stop the trace is not sufficient because the tracing could have overwritten
-the data that you wanted to record. For this reason, it is sometimes better to
-disable tracing directly from a program. This allows you to stop the
-tracing at the point that you hit the part that you are interested in.
-To disable the tracing directly from a C program, something like following
-code snippet can be used:
-
-int trace_fd;
-[...]
-int main(int argc, char *argv[]) {
-	[...]
-	trace_fd = open("/debug/tracing/tracing_enabled", O_WRONLY);
-	[...]
-	if (condition_hit()) {
-		write(trace_fd, "0", 1);
-	}
-	[...]
-}
-
-Note: Here we hard coded the path name. The debugfs mount is not
-guaranteed to be at /debug (and is more commonly at /sys/kernel/debug).
-For simple one time traces, the above is sufficent. For anything else,
-a search through /proc/mounts may be needed to find where the debugfs
-file-system is mounted.
-
-
-Single thread tracing
----------------------
-
-By writing into /debug/tracing/set_ftrace_pid you can trace a
-single thread. For example:
-
-# cat /debug/tracing/set_ftrace_pid
-no pid
-# echo 3111 > /debug/tracing/set_ftrace_pid
-# cat /debug/tracing/set_ftrace_pid
-3111
-# echo function > /debug/tracing/current_tracer
-# cat /debug/tracing/trace | head
- # tracer: function
- #
- #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
- #              | |       |          |         |
-     yum-updatesd-3111  [003]  1637.254676: finish_task_switch <-thread_return
-     yum-updatesd-3111  [003]  1637.254681: hrtimer_cancel <-schedule_hrtimeout_range
-     yum-updatesd-3111  [003]  1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel
-     yum-updatesd-3111  [003]  1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel
-     yum-updatesd-3111  [003]  1637.254685: fget_light <-do_sys_poll
-     yum-updatesd-3111  [003]  1637.254686: pipe_poll <-do_sys_poll
-# echo -1 > /debug/tracing/set_ftrace_pid
-# cat /debug/tracing/trace |head
- # tracer: function
- #
- #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
- #              | |       |          |         |
- ##### CPU 3 buffer started ####
-     yum-updatesd-3111  [003]  1701.957688: free_poll_entry <-poll_freewait
-     yum-updatesd-3111  [003]  1701.957689: remove_wait_queue <-free_poll_entry
-     yum-updatesd-3111  [003]  1701.957691: fput <-free_poll_entry
-     yum-updatesd-3111  [003]  1701.957692: audit_syscall_exit <-sysret_audit
-     yum-updatesd-3111  [003]  1701.957693: path_put <-audit_syscall_exit
-
-If you want to trace a function when executing, you could use
-something like this simple program:
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main (int argc, char **argv)
-{
-        if (argc < 1)
-                exit(-1);
-
-        if (fork() > 0) {
-                int fd, ffd;
-                char line[64];
-                int s;
-
-                ffd = open("/debug/tracing/current_tracer", O_WRONLY);
-                if (ffd < 0)
-                        exit(-1);
-                write(ffd, "nop", 3);
-
-                fd = open("/debug/tracing/set_ftrace_pid", O_WRONLY);
-                s = sprintf(line, "%d\n", getpid());
-                write(fd, line, s);
-
-                write(ffd, "function", 8);
-
-                close(fd);
-                close(ffd);
-
-                execvp(argv[1], argv+1);
-        }
-
-        return 0;
-}
-
-dynamic ftrace
---------------
-
-If CONFIG_DYNAMIC_FTRACE is set, the system will run with
-virtually no overhead when function tracing is disabled. The way
-this works is the mcount function call (placed at the start of
-every kernel function, produced by the -pg switch in gcc), starts
-of pointing to a simple return. (Enabling FTRACE will include the
--pg switch in the compiling of the kernel.)
-
-At compile time every C file object is run through the
-recordmcount.pl script (located in the scripts directory). This
-script will process the C object using objdump to find all the
-locations in the .text section that call mcount. (Note, only
-the .text section is processed, since processing other sections
-like .init.text may cause races due to those sections being freed).
-
-A new section called "__mcount_loc" is created that holds references
-to all the mcount call sites in the .text section. This section is
-compiled back into the original object. The final linker will add
-all these references into a single table.
-
-On boot up, before SMP is initialized, the dynamic ftrace code
-scans this table and updates all the locations into nops. It also
-records the locations, which are added to the available_filter_functions
-list.  Modules are processed as they are loaded and before they are
-executed.  When a module is unloaded, it also removes its functions from
-the ftrace function list. This is automatic in the module unload
-code, and the module author does not need to worry about it.
-
-When tracing is enabled, kstop_machine is called to prevent races
-with the CPUS executing code being modified (which can cause the
-CPU to do undesireable things), and the nops are patched back
-to calls. But this time, they do not call mcount (which is just
-a function stub). They now call into the ftrace infrastructure.
-
-One special side-effect to the recording of the functions being
-traced is that we can now selectively choose which functions we
-wish to trace and which ones we want the mcount calls to remain as
-nops.
-
-Two files are used, one for enabling and one for disabling the tracing
-of specified functions. They are:
-
-  set_ftrace_filter
-
-and
-
-  set_ftrace_notrace
-
-A list of available functions that you can add to these files is listed
-in:
-
-   available_filter_functions
-
- # cat /debug/tracing/available_filter_functions
-put_prev_task_idle
-kmem_cache_create
-pick_next_task_rt
-get_online_cpus
-pick_next_task_fair
-mutex_lock
-[...]
-
-If I am only interested in sys_nanosleep and hrtimer_interrupt:
-
- # echo sys_nanosleep hrtimer_interrupt \
-		> /debug/tracing/set_ftrace_filter
- # echo ftrace > /debug/tracing/current_tracer
- # echo 1 > /debug/tracing/tracing_enabled
- # usleep 1
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/trace
-# tracer: ftrace
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-          usleep-4134  [00]  1317.070017: hrtimer_interrupt <-smp_apic_timer_interrupt
-          usleep-4134  [00]  1317.070111: sys_nanosleep <-syscall_call
-          <idle>-0     [00]  1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt
-
-To see which functions are being traced, you can cat the file:
-
- # cat /debug/tracing/set_ftrace_filter
-hrtimer_interrupt
-sys_nanosleep
-
-
-Perhaps this is not enough. The filters also allow simple wild cards.
-Only the following are currently available
-
-  <match>*  - will match functions that begin with <match>
-  *<match>  - will match functions that end with <match>
-  *<match>* - will match functions that have <match> in it
-
-These are the only wild cards which are supported.
-
-  <match>*<match> will not work.
-
-Note: It is better to use quotes to enclose the wild cards, otherwise
-  the shell may expand the parameters into names of files in the local
-  directory.
-
- # echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
-
-Produces:
-
-# tracer: ftrace
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-            bash-4003  [00]  1480.611794: hrtimer_init <-copy_process
-            bash-4003  [00]  1480.611941: hrtimer_start <-hrtick_set
-            bash-4003  [00]  1480.611956: hrtimer_cancel <-hrtick_clear
-            bash-4003  [00]  1480.611956: hrtimer_try_to_cancel <-hrtimer_cancel
-          <idle>-0     [00]  1480.612019: hrtimer_get_next_event <-get_next_timer_interrupt
-          <idle>-0     [00]  1480.612025: hrtimer_get_next_event <-get_next_timer_interrupt
-          <idle>-0     [00]  1480.612032: hrtimer_get_next_event <-get_next_timer_interrupt
-          <idle>-0     [00]  1480.612037: hrtimer_get_next_event <-get_next_timer_interrupt
-          <idle>-0     [00]  1480.612382: hrtimer_get_next_event <-get_next_timer_interrupt
-
-
-Notice that we lost the sys_nanosleep.
-
- # cat /debug/tracing/set_ftrace_filter
-hrtimer_run_queues
-hrtimer_run_pending
-hrtimer_init
-hrtimer_cancel
-hrtimer_try_to_cancel
-hrtimer_forward
-hrtimer_start
-hrtimer_reprogram
-hrtimer_force_reprogram
-hrtimer_get_next_event
-hrtimer_interrupt
-hrtimer_nanosleep
-hrtimer_wakeup
-hrtimer_get_remaining
-hrtimer_get_res
-hrtimer_init_sleeper
-
-
-This is because the '>' and '>>' act just like they do in bash.
-To rewrite the filters, use '>'
-To append to the filters, use '>>'
-
-To clear out a filter so that all functions will be recorded again:
-
- # echo > /debug/tracing/set_ftrace_filter
- # cat /debug/tracing/set_ftrace_filter
- #
-
-Again, now we want to append.
-
- # echo sys_nanosleep > /debug/tracing/set_ftrace_filter
- # cat /debug/tracing/set_ftrace_filter
-sys_nanosleep
- # echo 'hrtimer_*' >> /debug/tracing/set_ftrace_filter
- # cat /debug/tracing/set_ftrace_filter
-hrtimer_run_queues
-hrtimer_run_pending
-hrtimer_init
-hrtimer_cancel
-hrtimer_try_to_cancel
-hrtimer_forward
-hrtimer_start
-hrtimer_reprogram
-hrtimer_force_reprogram
-hrtimer_get_next_event
-hrtimer_interrupt
-sys_nanosleep
-hrtimer_nanosleep
-hrtimer_wakeup
-hrtimer_get_remaining
-hrtimer_get_res
-hrtimer_init_sleeper
-
-
-The set_ftrace_notrace prevents those functions from being traced.
-
- # echo '*preempt*' '*lock*' > /debug/tracing/set_ftrace_notrace
-
-Produces:
-
-# tracer: ftrace
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-            bash-4043  [01]   115.281644: finish_task_switch <-schedule
-            bash-4043  [01]   115.281645: hrtick_set <-schedule
-            bash-4043  [01]   115.281645: hrtick_clear <-hrtick_set
-            bash-4043  [01]   115.281646: wait_for_completion <-__stop_machine_run
-            bash-4043  [01]   115.281647: wait_for_common <-wait_for_completion
-            bash-4043  [01]   115.281647: kthread_stop <-stop_machine_run
-            bash-4043  [01]   115.281648: init_waitqueue_head <-kthread_stop
-            bash-4043  [01]   115.281648: wake_up_process <-kthread_stop
-            bash-4043  [01]   115.281649: try_to_wake_up <-wake_up_process
-
-We can see that there's no more lock or preempt tracing.
-
-trace_pipe
-----------
-
-The trace_pipe outputs the same content as the trace file, but the effect
-on the tracing is different. Every read from trace_pipe is consumed.
-This means that subsequent reads will be different. The trace
-is live.
-
- # echo function > /debug/tracing/current_tracer
- # cat /debug/tracing/trace_pipe > /tmp/trace.out &
-[1] 4153
- # echo 1 > /debug/tracing/tracing_enabled
- # usleep 1
- # echo 0 > /debug/tracing/tracing_enabled
- # cat /debug/tracing/trace
-# tracer: function
-#
-#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
-#              | |      |          |         |
-
- #
- # cat /tmp/trace.out
-            bash-4043  [00] 41.267106: finish_task_switch <-schedule
-            bash-4043  [00] 41.267106: hrtick_set <-schedule
-            bash-4043  [00] 41.267107: hrtick_clear <-hrtick_set
-            bash-4043  [00] 41.267108: wait_for_completion <-__stop_machine_run
-            bash-4043  [00] 41.267108: wait_for_common <-wait_for_completion
-            bash-4043  [00] 41.267109: kthread_stop <-stop_machine_run
-            bash-4043  [00] 41.267109: init_waitqueue_head <-kthread_stop
-            bash-4043  [00] 41.267110: wake_up_process <-kthread_stop
-            bash-4043  [00] 41.267110: try_to_wake_up <-wake_up_process
-            bash-4043  [00] 41.267111: select_task_rq_rt <-try_to_wake_up
-
-
-Note, reading the trace_pipe file will block until more input is added.
-By changing the tracer, trace_pipe will issue an EOF. We needed
-to set the function tracer _before_ we "cat" the trace_pipe file.
-
-
-trace entries
--------------
-
-Having too much or not enough data can be troublesome in diagnosing
-an issue in the kernel. The file buffer_size_kb is used to modify
-the size of the internal trace buffers. The number listed
-is the number of entries that can be recorded per CPU. To know
-the full size, multiply the number of possible CPUS with the
-number of entries.
-
- # cat /debug/tracing/buffer_size_kb
-1408 (units kilobytes)
-
-Note, to modify this, you must have tracing completely disabled. To do that,
-echo "nop" into the current_tracer. If the current_tracer is not set
-to "nop", an EINVAL error will be returned.
-
- # echo nop > /debug/tracing/current_tracer
- # echo 10000 > /debug/tracing/buffer_size_kb
- # cat /debug/tracing/buffer_size_kb
-10000 (units kilobytes)
-
-The number of pages which will be allocated is limited to a percentage
-of available memory. Allocating too much will produce an error.
-
- # echo 1000000000000 > /debug/tracing/buffer_size_kb
--bash: echo: write error: Cannot allocate memory
- # cat /debug/tracing/buffer_size_kb
-85
-
diff -druNp linux-libre-2.6.29-gnu1/Documentation/gpio.txt linux-libre-2.6.30-gnu1/Documentation/gpio.txt
--- linux-libre-2.6.29-gnu1/Documentation/gpio.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/gpio.txt	2009-06-09 23:05:27.000000000 -0400
@@ -123,7 +123,10 @@ platform-specific implementation issue.
 
 Using GPIOs
 -----------
-One of the first things to do with a GPIO, often in board setup code when
+The first thing a system should do with a GPIO is allocate it, using
+the gpio_request() call; see later.
+
+One of the next things to do with a GPIO, often in board setup code when
 setting up a platform_device using the GPIO, is mark its direction:
 
 	/* set as input or output, returning 0 or negative errno */
@@ -141,8 +144,8 @@ This helps avoid signal glitching during
 
 For compatibility with legacy interfaces to GPIOs, setting the direction
 of a GPIO implicitly requests that GPIO (see below) if it has not been
-requested already.  That compatibility may be removed in the future;
-explicitly requesting GPIOs is strongly preferred.
+requested already.  That compatibility is being removed from the optional
+gpiolib framework.
 
 Setting the direction can fail if the GPIO number is invalid, or when
 that particular GPIO can't be used in that mode.  It's generally a bad
@@ -195,7 +198,7 @@ This requires sleeping, which can't be d
 
 Platforms that support this type of GPIO distinguish them from other GPIOs
 by returning nonzero from this call (which requires a valid GPIO number,
-either explicitly or implicitly requested):
+which should have been previously allocated with gpio_request):
 
 	int gpio_cansleep(unsigned gpio);
 
@@ -212,10 +215,9 @@ for GPIOs that can't be accessed from IR
 same as the spinlock-safe calls.
 
 
-Claiming and Releasing GPIOs (OPTIONAL)
----------------------------------------
+Claiming and Releasing GPIOs
+----------------------------
 To help catch system configuration errors, two calls are defined.
-However, many platforms don't currently support this mechanism.
 
 	/* request GPIO, returning 0 or negative errno.
 	 * non-null labels may be useful for diagnostics.
@@ -244,13 +246,6 @@ Some platforms may also use knowledge ab
 power management, such as by powering down unused chip sectors and, more
 easily, gating off unused clocks.
 
-These two calls are optional because not not all current Linux platforms
-offer such functionality in their GPIO support; a valid implementation
-could return success for all gpio_request() calls.  Unlike the other calls,
-the state they represent doesn't normally match anything from a hardware
-register; it's just a software bitmap which clearly is not necessary for
-correct operation of hardware or (bug free) drivers.
-
 Note that requesting a GPIO does NOT cause it to be configured in any
 way; it just marks that GPIO as in use.  Separate code must handle any
 pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/ds1621 linux-libre-2.6.30-gnu1/Documentation/hwmon/ds1621
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/ds1621	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/ds1621	2009-06-09 23:05:27.000000000 -0400
@@ -49,12 +49,9 @@ of up to +/- 0.5 degrees even when compa
 readings. Be sure to have a high vs. low temperature limit gap of al least
 1.0 degree Celsius to avoid Tout "bouncing", though!
 
-As for alarms, you can read the alarm status of the DS1621 via the 'alarms'
-/sys file interface. The result consists mainly of bit 6 and 5 of the
-configuration register of the chip; bit 6 (0x40 or 64) is the high alarm
-bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
-low limits are met or exceeded and are reset by the module as soon as the
-respective temperature ranges are left.
+The alarm bits are set when the high or low limits are met or exceeded and
+are reset by the module as soon as the respective temperature ranges are
+left.
 
 The alarm registers are in no way suitable to find out about the actual
 status of Tout. They will only tell you about its history, whether or not
@@ -64,45 +61,3 @@ with neither of the alarms set.
 
 Temperature conversion of the DS1621 takes up to 1000ms; internal access to
 non-volatile registers may last for 10ms or below.
-
-High Accuracy Temperature Reading
----------------------------------
-
-As said before, the temperature issued via the 9-bit i2c-bus data is
-somewhat arbitrary. Internally, the temperature conversion is of a
-different kind that is explained (not so...) well in the DS1621 data sheet.
-To cut the long story short: Inside the DS1621 there are two oscillators,
-both of them biassed by a temperature coefficient.
-
-Higher resolution of the temperature reading can be achieved using the
-internal projection, which means taking account of REG_COUNT and REG_SLOPE
-(the driver manages them):
-
-Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
-Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
-Measurement with Dallas Direct-to-Digital Temperature Sensors'
-
-- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
-- The resulting value is TEMP_READ.
-- Then, read REG_COUNT.
-- And then, REG_SLOPE.
-
-      TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
-
-Note that this is what the DONE bit in the DS1621 configuration register is
-good for: Internally, one temperature conversion takes up to 1000ms. Before
-that conversion is complete you will not be able to read valid things out
-of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
-tells you whether the conversion is complete ("done", in plain English) and
-thus, whether the values you read are good or not.
-
-The DS1621 has two modes of operation: "Continuous" conversion, which can
-be understood as the default stand-alone mode where the chip gets the
-temperature and controls external devices via its Tout pin or tells other
-i2c's about it if they care. The other mode is called "1SHOT", that means
-that it only figures out about the temperature when it is explicitly told
-to do so; this can be seen as power saving mode.
-
-Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
-the continuous conversions until the contents of these registers are valid,
-or, in 1SHOT mode, you have to have one conversion made.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/g760a linux-libre-2.6.30-gnu1/Documentation/hwmon/g760a
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/g760a	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/g760a	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,36 @@
+Kernel driver g760a
+===================
+
+Supported chips:
+  * Global Mixed-mode Technology Inc. G760A
+    Prefix: 'g760a'
+    Datasheet: Publicly available at the GMT website
+      http://www.gmt.com.tw/datasheet/g760a.pdf
+
+Author: Herbert Valerio Riedel <hvr@gnu.org>
+
+Description
+-----------
+
+The GMT G760A Fan Speed PWM Controller is connected directly to a fan
+and performs closed-loop control of the fan speed.
+
+The fan speed is programmed by setting the period via 'pwm1' of two
+consecutive speed pulses. The period is defined in terms of clock
+cycle counts of an assumed 32kHz clock source.
+
+Setting a period of 0 stops the fan; setting the period to 255 sets
+fan to maximum speed.
+
+The measured fan rotation speed returned via 'fan1_input' is derived
+from the measured speed pulse period by assuming again a 32kHz clock
+source and a 2 pulse-per-revolution fan.
+
+The 'alarms' file provides access to the two alarm bits provided by
+the G760A chip's status register: Bit 0 is set when the actual fan
+speed differs more than 20% with respect to the programmed fan speed;
+bit 1 is set when fan speed is below 1920 RPM.
+
+The g760a driver will not update its values more frequently than every
+other second; reading them more often will do no harm, but will return
+'old' values.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/lis3lv02d linux-libre-2.6.30-gnu1/Documentation/hwmon/lis3lv02d
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/lis3lv02d	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/lis3lv02d	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,11 @@
 Kernel driver lis3lv02d
-==================
+=======================
 
 Supported chips:
 
   * STMicroelectronics LIS3LV02DL and LIS3LV02DQ
 
-Author:
+Authors:
         Yan Burman <burman.yan@gmail.com>
 	Eric Piel <eric.piel@tremplin-utc.net>
 
@@ -15,7 +15,7 @@ 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 detect automatically
+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
@@ -27,7 +27,7 @@ position - 3D position that the accelero
 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.
+		   position.
 rate - reports the sampling rate of the accelerometer device in HZ
 
 This driver also provides an absolute input class device, allowing
@@ -48,7 +48,7 @@ For better compatibility between the var
 the accelerometer are converted into a "standard" organisation of the axes
 (aka "can play neverball out of the box"):
  * When the laptop is horizontal the position reported is about 0 for X and Y
-and a positive value for Z
+	and a positive value for Z
  * If the left side is elevated, X increases (becomes positive)
  * If the front side (where the touchpad is) is elevated, Y decreases
 	(becomes negative)
@@ -59,3 +59,13 @@ email to the authors to add it to the da
 laptop, please include the output of "dmidecode" plus the value of
 /sys/devices/platform/lis3lv02d/position in these four cases.
 
+Q&A
+---
+
+Q: How do I safely simulate freefall? I have an HP "portable
+workstation" which has about 3.5kg and a plastic case, so letting it
+fall to the ground is out of question...
+
+A: The sensor is pretty sensitive, so your hands can do it. Lift it
+into free space, follow the fall with your hands for like 10
+centimeters. That should be enough to trigger the detection.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/ltc4215 linux-libre-2.6.30-gnu1/Documentation/hwmon/ltc4215
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/ltc4215	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/ltc4215	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,50 @@
+Kernel driver ltc4215
+=====================
+
+Supported chips:
+  * Linear Technology LTC4215
+    Prefix: 'ltc4215'
+    Addresses scanned: 0x44
+    Datasheet:
+        http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+
+Author: Ira W. Snyder <iws@ovro.caltech.edu>
+
+
+Description
+-----------
+
+The LTC4215 controller allows a board to be safely inserted and removed
+from a live backplane.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for LTC4215 devices, due to the fact that some
+of the possible addresses are unfriendly to probing. You will need to use
+the "force" parameter to tell the driver where to find the device.
+
+Example: the following will load the driver for an LTC4215 at address 0x44
+on I2C bus #0:
+$ modprobe ltc4215 force=0,0x44
+
+
+Sysfs entries
+-------------
+
+The LTC4215 has built-in limits for overvoltage, undervoltage, and
+undercurrent warnings. This makes it very likely that the reference
+circuit will be used.
+
+in1_input		input voltage
+in2_input		output voltage
+
+in1_min_alarm		input undervoltage alarm
+in1_max_alarm		input overvoltage alarm
+
+curr1_input		current
+curr1_max_alarm		overcurrent alarm
+
+power1_input		power usage
+power1_alarm		power bad alarm
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/pcf8591 linux-libre-2.6.30-gnu1/Documentation/hwmon/pcf8591
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/pcf8591	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/pcf8591	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,90 @@
+Kernel driver pcf8591
+=====================
+
+Supported chips:
+  * Philips PCF8591
+    Prefix: 'pcf8591'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Philips Semiconductor website
+               http://www.semiconductors.philips.com/pip/PCF8591P.html
+
+Authors:
+        Aurelien Jarno <aurelien@aurel32.net>
+        valuable contributions by Jan M. Sendler <sendler@sendler.de>,
+        Jean Delvare <khali@linux-fr.org>
+
+
+Description
+-----------
+The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
+analog output) for the I2C bus produced by Philips Semiconductors. It
+is designed to provide a byte I2C interface to up to 4 separate devices.
+
+The PCF8591 has 4 analog inputs programmable as single-ended or
+differential inputs :
+- mode 0 : four single ended inputs
+        Pins AIN0 to AIN3 are single ended inputs for channels 0 to 3
+
+- mode 1 : three differential inputs
+        Pins AIN3 is the common negative differential input
+        Pins AIN0 to AIN2 are positive differential inputs for channels 0 to 2
+
+- mode 2 : single ended and differential mixed
+        Pins AIN0 and AIN1 are single ended inputs for channels 0 and 1
+        Pins AIN2 is the positive differential input for channel 3
+        Pins AIN3 is the negative differential input for channel 3
+
+- mode 3 : two differential inputs
+        Pins AIN0 is the positive differential input for channel 0
+        Pins AIN1 is the negative differential input for channel 0
+        Pins AIN2 is the positive differential input for channel 1
+        Pins AIN3 is the negative differential input for channel 1
+
+See the datasheet for details.
+
+Module parameters
+-----------------
+
+* input_mode int
+
+    Analog input mode:
+         0 = four single ended inputs
+         1 = three differential inputs
+         2 = single ended and differential mixed
+         3 = two differential inputs
+
+
+Accessing PCF8591 via /sys interface
+-------------------------------------
+
+! Be careful !
+The PCF8591 is plainly impossible to detect ! Stupid chip.
+So every chip with address in the interval [48..4f] is
+detected as PCF8591. If you have other chips in this address
+range, the workaround is to load this module after the one
+for your others chips.
+
+On detection (i.e. insmod, modprobe et al.), directories are being
+created for each detected PCF8591:
+
+/sys/bus/devices/<0>-<1>/
+where <0> is the bus the chip was detected on (e. g. i2c-0)
+and <1> the chip address ([48..4f])
+
+Inside these directories, there are such files:
+in0, in1, in2, in3, out0_enable, out0_output, name
+
+Name contains chip name.
+
+The in0, in1, in2 and in3 files are RO. Reading gives the value of the
+corresponding channel. Depending on the current analog inputs configuration,
+files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
+ended inputs and -128 to +127 for differential inputs (8-bit ADC).
+
+The out0_enable file is RW. Reading gives "1" for analog output enabled and
+"0" for analog output disabled. Writing accepts "0" and "1" accordingly.
+
+The out0_output file is RW. Writing a number between 0 and 255 (8-bit DAC), send
+the value to the digital-to-analog converter. Note that a voltage will
+only appears on AOUT pin if aout0_enable equals 1. Reading returns the last
+value written.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/sysfs-interface linux-libre-2.6.30-gnu1/Documentation/hwmon/sysfs-interface
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/sysfs-interface	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/sysfs-interface	2009-06-09 23:05:27.000000000 -0400
@@ -150,6 +150,11 @@ fan[1-*]_min	Fan minimum value
 		Unit: revolution/min (RPM)
 		RW
 
+fan[1-*]_max	Fan maximum value
+		Unit: revolution/min (RPM)
+		Only rarely supported by the hardware.
+		RW
+
 fan[1-*]_input	Fan input value.
 		Unit: revolution/min (RPM)
 		RO
@@ -365,6 +370,7 @@ energy[1-*]_input		Cumulative energy use
 				Unit: microJoule
 				RO
 
+
 **********
 * Alarms *
 **********
@@ -389,6 +395,7 @@ OR
 in[0-*]_min_alarm
 in[0-*]_max_alarm
 fan[1-*]_min_alarm
+fan[1-*]_max_alarm
 temp[1-*]_min_alarm
 temp[1-*]_max_alarm
 temp[1-*]_crit_alarm
@@ -453,6 +460,27 @@ beep_mask	Bitmask for beep.
 		RW
 
 
+***********************
+* Intrusion detection *
+***********************
+
+intrusion[0-*]_alarm
+		Chassis intrusion detection
+		0: OK
+		1: intrusion detected
+		RW
+		Contrary to regular alarm flags which clear themselves
+		automatically when read, this one sticks until cleared by
+		the user. This is done by writing 0 to the file. Writing
+		other values is unsupported.
+
+intrusion[0-*]_beep
+		Chassis intrusion beep
+		0: disable
+		1: enable
+		RW
+
+
 sysfs attribute writes interpretation
 -------------------------------------
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/hwmon/w83627ehf linux-libre-2.6.30-gnu1/Documentation/hwmon/w83627ehf
--- linux-libre-2.6.29-gnu1/Documentation/hwmon/w83627ehf	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/hwmon/w83627ehf	2009-06-09 23:05:27.000000000 -0400
@@ -2,30 +2,40 @@ Kernel driver w83627ehf
 =======================
 
 Supported chips:
-  * Winbond W83627EHF/EHG/DHG (ISA access ONLY)
+  * Winbond W83627EHF/EHG (ISA access ONLY)
     Prefix: 'w83627ehf'
     Addresses scanned: ISA address retrieved from Super I/O registers
     Datasheet:
-        http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
-        DHG datasheet confidential.
+        http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
+  * Winbond W83627DHG
+    Prefix: 'w83627dhg'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet:
+        http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
+  * Winbond W83667HG
+    Prefix: 'w83667hg'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: not available
 
 Authors:
         Jean Delvare <khali@linux-fr.org>
         Yuan Mu (Winbond)
         Rudolf Marek <r.marek@assembler.cz>
         David Hubbard <david.c.hubbard@gmail.com>
+        Gong Jun <JGong@nuvoton.com>
 
 Description
 -----------
 
-This driver implements support for the Winbond W83627EHF, W83627EHG, and
-W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
+This driver implements support for the Winbond W83627EHF, W83627EHG,
+W83627DHG and W83667HG super I/O chips. We will refer to them collectively
+as Winbond chips.
 
 The chips implement three temperature sensors, five fan rotation
 speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
-VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep
-warnings (control unimplemented), and some automatic fan regulation
-strategies (plus manual fan control mode).
+VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
+with beep warnings (control unimplemented), and some automatic fan
+regulation strategies (plus manual fan control mode).
 
 Temperatures are measured in degrees Celsius and measurement resolution is 1
 degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
@@ -54,7 +64,8 @@ follows:
 temp1 -> pwm1
 temp2 -> pwm2
 temp3 -> pwm3
-prog  -> pwm4 (the programmable setting is not supported by the driver)
+prog  -> pwm4 (not on 667HG; the programmable setting is not supported by
+	       the driver)
 
 /sys files
 ----------
diff -druNp linux-libre-2.6.29-gnu1/Documentation/i2c/busses/i2c-nforce2 linux-libre-2.6.30-gnu1/Documentation/i2c/busses/i2c-nforce2
--- linux-libre-2.6.29-gnu1/Documentation/i2c/busses/i2c-nforce2	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/i2c/busses/i2c-nforce2	2009-06-09 23:05:27.000000000 -0400
@@ -7,10 +7,14 @@ Supported adapters:
   * nForce3 250Gb MCP          10de:00E4 
   * nForce4 MCP                10de:0052
   * nForce4 MCP-04             10de:0034
-  * nForce4 MCP51              10de:0264
-  * nForce4 MCP55              10de:0368
-  * nForce4 MCP61              10de:03EB
-  * nForce4 MCP65              10de:0446
+  * nForce MCP51               10de:0264
+  * nForce MCP55               10de:0368
+  * nForce MCP61               10de:03EB
+  * nForce MCP65               10de:0446
+  * nForce MCP67               10de:0542
+  * nForce MCP73               10de:07D8
+  * nForce MCP78S              10de:0752
+  * nForce MCP79               10de:0AA2
 
 Datasheet: not publicly available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/i2c/busses/i2c-piix4 linux-libre-2.6.30-gnu1/Documentation/i2c/busses/i2c-piix4
--- linux-libre-2.6.29-gnu1/Documentation/i2c/busses/i2c-piix4	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/i2c/busses/i2c-piix4	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@ Supported adapters:
   * Intel 82371AB PIIX4 and PIIX4E
   * Intel 82443MX (440MX)
     Datasheet: Publicly available at the Intel website
-  * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
+  * ServerWorks OSB4, CSB5, CSB6, HT-1000 and HT-1100 southbridges
     Datasheet: Only available via NDA from ServerWorks
   * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
     Datasheet: Not publicly available
diff -druNp linux-libre-2.6.29-gnu1/Documentation/i2c/chips/pcf8591 linux-libre-2.6.30-gnu1/Documentation/i2c/chips/pcf8591
--- linux-libre-2.6.29-gnu1/Documentation/i2c/chips/pcf8591	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/i2c/chips/pcf8591	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-Kernel driver pcf8591
-=====================
-
-Supported chips:
-  * Philips PCF8591
-    Prefix: 'pcf8591'
-    Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Philips Semiconductor website
-               http://www.semiconductors.philips.com/pip/PCF8591P.html
-
-Authors:
-        Aurelien Jarno <aurelien@aurel32.net>
-        valuable contributions by Jan M. Sendler <sendler@sendler.de>,
-        Jean Delvare <khali@linux-fr.org>
-
-
-Description
------------
-The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
-analog output) for the I2C bus produced by Philips Semiconductors. It
-is designed to provide a byte I2C interface to up to 4 separate devices.
-
-The PCF8591 has 4 analog inputs programmable as single-ended or
-differential inputs :
-- mode 0 : four single ended inputs
-        Pins AIN0 to AIN3 are single ended inputs for channels 0 to 3
-
-- mode 1 : three differential inputs
-        Pins AIN3 is the common negative differential input
-        Pins AIN0 to AIN2 are positive differential inputs for channels 0 to 2
-
-- mode 2 : single ended and differential mixed
-        Pins AIN0 and AIN1 are single ended inputs for channels 0 and 1
-        Pins AIN2 is the positive differential input for channel 3
-        Pins AIN3 is the negative differential input for channel 3
-
-- mode 3 : two differential inputs
-        Pins AIN0 is the positive differential input for channel 0
-        Pins AIN1 is the negative differential input for channel 0
-        Pins AIN2 is the positive differential input for channel 1
-        Pins AIN3 is the negative differential input for channel 1
-
-See the datasheet for details.
-
-Module parameters
------------------
-
-* input_mode int
-
-    Analog input mode:
-         0 = four single ended inputs
-         1 = three differential inputs
-         2 = single ended and differential mixed
-         3 = two differential inputs
-
-
-Accessing PCF8591 via /sys interface
--------------------------------------
-
-! Be careful !
-The PCF8591 is plainly impossible to detect ! Stupid chip.
-So every chip with address in the interval [48..4f] is
-detected as PCF8591. If you have other chips in this address
-range, the workaround is to load this module after the one
-for your others chips.
-
-On detection (i.e. insmod, modprobe et al.), directories are being
-created for each detected PCF8591:
-
-/sys/bus/devices/<0>-<1>/
-where <0> is the bus the chip was detected on (e. g. i2c-0)
-and <1> the chip address ([48..4f])
-
-Inside these directories, there are such files:
-in0, in1, in2, in3, out0_enable, out0_output, name
-
-Name contains chip name.
-
-The in0, in1, in2 and in3 files are RO. Reading gives the value of the
-corresponding channel. Depending on the current analog inputs configuration,
-files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
-ended inputs and -128 to +127 for differential inputs (8-bit ADC).
-
-The out0_enable file is RW. Reading gives "1" for analog output enabled and
-"0" for analog output disabled. Writing accepts "0" and "1" accordingly.
-
-The out0_output file is RW. Writing a number between 0 and 255 (8-bit DAC), send
-the value to the digital-to-analog converter. Note that a voltage will
-only appears on AOUT pin if aout0_enable equals 1. Reading returns the last
-value written.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/i2c/instantiating-devices linux-libre-2.6.30-gnu1/Documentation/i2c/instantiating-devices
--- linux-libre-2.6.29-gnu1/Documentation/i2c/instantiating-devices	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/i2c/instantiating-devices	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,167 @@
+How to instantiate I2C devices
+==============================
+
+Unlike PCI or USB devices, I2C devices are not enumerated at the hardware
+level. Instead, the software must know which devices are connected on each
+I2C bus segment, and what address these devices are using. For this
+reason, the kernel code must instantiate I2C devices explicitly. There are
+several ways to achieve this, depending on the context and requirements.
+
+
+Method 1: Declare the I2C devices by bus number
+-----------------------------------------------
+
+This method is appropriate when the I2C bus is a system bus as is the case
+for many embedded systems. On such systems, each I2C bus has a number
+which is known in advance. It is thus possible to pre-declare the I2C
+devices which live on this bus. This is done with an array of struct
+i2c_board_info which is registered by calling i2c_register_board_info().
+
+Example (from omap2 h4):
+
+static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+	{
+		I2C_BOARD_INFO("isp1301_omap", 0x2d),
+		.irq		= OMAP_GPIO_IRQ(125),
+	},
+	{	/* EEPROM on mainboard */
+		I2C_BOARD_INFO("24c01", 0x52),
+		.platform_data	= &m24c01,
+	},
+	{	/* EEPROM on cpu card */
+		I2C_BOARD_INFO("24c01", 0x57),
+		.platform_data	= &m24c01,
+	},
+};
+
+static void __init omap_h4_init(void)
+{
+	(...)
+	i2c_register_board_info(1, h4_i2c_board_info,
+			ARRAY_SIZE(h4_i2c_board_info));
+	(...)
+}
+
+The above code declares 3 devices on I2C bus 1, including their respective
+addresses and custom data needed by their drivers. When the I2C bus in
+question is registered, the I2C devices will be instantiated automatically
+by i2c-core.
+
+The devices will be automatically unbound and destroyed when the I2C bus
+they sit on goes away (if ever.)
+
+
+Method 2: Instantiate the devices explicitly
+--------------------------------------------
+
+This method is appropriate when a larger device uses an I2C bus for
+internal communication. A typical case is TV adapters. These can have a
+tuner, a video decoder, an audio decoder, etc. usually connected to the
+main chip by the means of an I2C bus. You won't know the number of the I2C
+bus in advance, so the method 1 described above can't be used. Instead,
+you can instantiate your I2C devices explicitly. This is done by filling
+a struct i2c_board_info and calling i2c_new_device().
+
+Example (from the sfe4001 network driver):
+
+static struct i2c_board_info sfe4001_hwmon_info = {
+	I2C_BOARD_INFO("max6647", 0x4e),
+};
+
+int sfe4001_init(struct efx_nic *efx)
+{
+	(...)
+	efx->board_info.hwmon_client =
+		i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+
+	(...)
+}
+
+The above code instantiates 1 I2C device on the I2C bus which is on the
+network adapter in question.
+
+A variant of this is when you don't know for sure if an I2C device is
+present or not (for example for an optional feature which is not present
+on cheap variants of a board but you have no way to tell them apart), or
+it may have different addresses from one board to the next (manufacturer
+changing its design without notice). In this case, you can call
+i2c_new_probed_device() instead of i2c_new_device().
+
+Example (from the pnx4008 OHCI driver):
+
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+
+static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
+{
+	(...)
+	struct i2c_adapter *i2c_adap;
+	struct i2c_board_info i2c_info;
+
+	(...)
+	i2c_adap = i2c_get_adapter(2);
+	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
+	strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
+	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
+						   normal_i2c);
+	i2c_put_adapter(i2c_adap);
+	(...)
+}
+
+The above code instantiates up to 1 I2C device on the I2C bus which is on
+the OHCI adapter in question. It first tries at address 0x2c, if nothing
+is found there it tries address 0x2d, and if still nothing is found, it
+simply gives up.
+
+The driver which instantiated the I2C device is responsible for destroying
+it on cleanup. This is done by calling i2c_unregister_device() on the
+pointer that was earlier returned by i2c_new_device() or
+i2c_new_probed_device().
+
+
+Method 3: Probe an I2C bus for certain devices
+----------------------------------------------
+
+Sometimes you do not have enough information about an I2C device, not even
+to call i2c_new_probed_device(). The typical case is hardware monitoring
+chips on PC mainboards. There are several dozen models, which can live
+at 25 different addresses. Given the huge number of mainboards out there,
+it is next to impossible to build an exhaustive list of the hardware
+monitoring chips being used. Fortunately, most of these chips have
+manufacturer and device ID registers, so they can be identified by
+probing.
+
+In that case, I2C devices are neither declared nor instantiated
+explicitly. Instead, i2c-core will probe for such devices as soon as their
+drivers are loaded, and if any is found, an I2C device will be
+instantiated automatically. In order to prevent any misbehavior of this
+mechanism, the following restrictions apply:
+* The I2C device driver must implement the detect() method, which
+  identifies a supported device by reading from arbitrary registers.
+* Only buses which are likely to have a supported device and agree to be
+  probed, will be probed. For example this avoids probing for hardware
+  monitoring chips on a TV adapter.
+
+Example:
+See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c
+
+I2C devices instantiated as a result of such a successful probe will be
+destroyed automatically when the driver which detected them is removed,
+or when the underlying I2C bus is itself destroyed, whichever happens
+first.
+
+Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6
+kernels will find out that this method 3 is essentially similar to what
+was done there. Two significant differences are:
+* Probing is only one way to instantiate I2C devices now, while it was the
+  only way back then. Where possible, methods 1 and 2 should be preferred.
+  Method 3 should only be used when there is no other way, as it can have
+  undesirable side effects.
+* I2C buses must now explicitly say which I2C driver classes can probe
+  them (by the means of the class bitfield), while all I2C buses were
+  probed by default back then. The default is an empty class which means
+  that no probing happens. The purpose of the class bitfield is to limit
+  the aforementioned undesirable side effects.
+
+Once again, method 3 should be avoided wherever possible. Explicit device
+instantiation (methods 1 and 2) is much preferred for it is safer and
+faster.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/i2c/writing-clients linux-libre-2.6.30-gnu1/Documentation/i2c/writing-clients
--- linux-libre-2.6.29-gnu1/Documentation/i2c/writing-clients	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/i2c/writing-clients	2009-06-09 23:05:27.000000000 -0400
@@ -207,15 +207,26 @@ You simply have to define a detect callb
 identify supported devices (returning 0 for supported ones and -ENODEV
 for unsupported ones), a list of addresses to probe, and a device type
 (or class) so that only I2C buses which may have that type of device
-connected (and not otherwise enumerated) will be probed.  The i2c
-core will then call you back as needed and will instantiate a device
-for you for every successful detection.
+connected (and not otherwise enumerated) will be probed.  For example,
+a driver for a hardware monitoring chip for which auto-detection is
+needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
+with a class including I2C_CLASS_HWMON would be probed by this driver.
+Note that the absence of matching classes does not prevent the use of
+a device of that type on the given I2C adapter.  All it prevents is
+auto-detection; explicit instantiation of devices is still possible.
 
 Note that this mechanism is purely optional and not suitable for all
 devices.  You need some reliable way to identify the supported devices
 (typically using device-specific, dedicated identification registers),
 otherwise misdetections are likely to occur and things can get wrong
-quickly.
+quickly.  Keep in mind that the I2C protocol doesn't include any
+standard way to detect the presence of a chip at a given address, let
+alone a standard way to identify devices.  Even worse is the lack of
+semantics associated to bus transfers, which means that the same
+transfer can be seen as a read operation by a chip and as a write
+operation by another chip.  For these reasons, explicit device
+instantiation should always be preferred to auto-detection where
+possible.
 
 
 Device Deletion
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ia64/kvm.txt linux-libre-2.6.30-gnu1/Documentation/ia64/kvm.txt
--- linux-libre-2.6.29-gnu1/Documentation/ia64/kvm.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ia64/kvm.txt	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@ Note: For step 2, please make sure that
 		hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg
 	    you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries.
 
-	(3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu
+	(3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu
 
 4. Boot up Linux or Windows guests:
 	4.1 Create or install a image for guest boot. If you have xen experience, it should be easy.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/infiniband/ipoib.txt linux-libre-2.6.30-gnu1/Documentation/infiniband/ipoib.txt
--- linux-libre-2.6.29-gnu1/Documentation/infiniband/ipoib.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/infiniband/ipoib.txt	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,49 @@ Partitions and P_Keys
   The P_Key for any interface is given by the "pkey" file, and the
   main interface for a subinterface is in "parent."
 
+Datagram vs Connected modes
+
+  The IPoIB driver supports two modes of operation: datagram and
+  connected.  The mode is set and read through an interface's
+  /sys/class/net/<intf name>/mode file.
+
+  In datagram mode, the IB UD (Unreliable Datagram) transport is used
+  and so the interface MTU has is equal to the IB L2 MTU minus the
+  IPoIB encapsulation header (4 bytes).  For example, in a typical IB
+  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.
+
+  In connected mode, the interface's UD QP is still used for multicast
+  and communication with peers that don't support connected mode. In
+  this case, RX emulation of ICMP PMTU packets is used to cause the
+  networking stack to use the smaller UD MTU for these neighbours.
+
+Stateless offloads
+
+  If the IB HW supports IPoIB stateless offloads, IPoIB advertises
+  TCP/IP checksum and/or Large Send (LSO) offloading capability to the
+  network stack.
+
+  Large Receive (LRO) offloading is also implemented and may be turned
+  on/off using ethtool calls.  Currently LRO is supported only for
+  checksum offload capable devices.
+
+  Stateless offloads are supported only in datagram mode.  
+
+Interrupt moderation
+
+  If the underlying IB device supports CQ event moderation, one can
+  use ethtool to set interrupt mitigation parameters and thus reduce
+  the overhead incurred by handling interrupts.  The main code path of
+  IPoIB doesn't use events for TX completion signaling so only RX
+  moderation is supported.
+
 Debugging Information
 
   By compiling the IPoIB driver with CONFIG_INFINIBAND_IPOIB_DEBUG set
@@ -55,3 +98,5 @@ References
     http://ietf.org/rfc/rfc4391.txt 
   IP over InfiniBand (IPoIB) Architecture (RFC 4392)
     http://ietf.org/rfc/rfc4392.txt 
+  IP over InfiniBand: Connected Mode (RFC 4755)
+    http://ietf.org/rfc/rfc4755.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/input/bcm5974.txt linux-libre-2.6.30-gnu1/Documentation/input/bcm5974.txt
--- linux-libre-2.6.29-gnu1/Documentation/input/bcm5974.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/input/bcm5974.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+BCM5974 Driver (bcm5974)
+------------------------
+	Copyright (C) 2008-2009	Henrik Rydberg <rydberg@euromail.se>
+
+The USB initialization and package decoding was made by Scott Shawcroft as
+part of the touchd user-space driver project:
+	Copyright (C) 2008	Scott Shawcroft (scott.shawcroft@gmail.com)
+
+The BCM5974 driver is based on the appletouch driver:
+	Copyright (C) 2001-2004	Greg Kroah-Hartman (greg@kroah.com)
+	Copyright (C) 2005	Johannes Berg (johannes@sipsolutions.net)
+	Copyright (C) 2005	Stelian Pop (stelian@popies.net)
+	Copyright (C) 2005	Frank Arnold (frank@scirocco-5v-turbo.de)
+	Copyright (C) 2005	Peter Osterlund (petero2@telia.com)
+	Copyright (C) 2005	Michael Hanselmann (linux-kernel@hansmi.ch)
+	Copyright (C) 2006	Nicolas Boichat (nicolas@boichat.ch)
+
+This driver adds support for the multi-touch trackpad on the new Apple
+Macbook Air and Macbook Pro laptops. It replaces the appletouch driver on
+those computers, and integrates well with the synaptics driver of the Xorg
+system.
+
+Known to work on Macbook Air, Macbook Pro Penryn and the new unibody
+Macbook 5 and Macbook Pro 5.
+
+Usage
+-----
+
+The driver loads automatically for the supported usb device ids, and
+becomes available both as an event device (/dev/input/event*) and as a
+mouse via the mousedev driver (/dev/input/mice).
+
+USB Race
+--------
+
+The Apple multi-touch trackpads report both mouse and keyboard events via
+different interfaces of the same usb device. This creates a race condition
+with the HID driver, which, if not told otherwise, will find the standard
+HID mouse and keyboard, and claim the whole device. To remedy, the usb
+product id must be listed in the mouse_ignore list of the hid driver.
+
+Debug output
+------------
+
+To ease the development for new hardware version, verbose packet output can
+be switched on with the debug kernel module parameter. The range [1-9]
+yields different levels of verbosity. Example (as root):
+
+echo -n 9 > /sys/module/bcm5974/parameters/debug
+
+tail -f /var/log/debug
+
+echo -n 0 > /sys/module/bcm5974/parameters/debug
+
+Trivia
+------
+
+The driver was developed at the ubuntu forums in June 2008 [1], and now has
+a more permanent home at bitmath.org [2].
+
+Links
+-----
+
+[1] http://ubuntuforums.org/showthread.php?t=840040
+[2] http://http://bitmath.org/code/
diff -druNp linux-libre-2.6.29-gnu1/Documentation/input/multi-touch-protocol.txt linux-libre-2.6.30-gnu1/Documentation/input/multi-touch-protocol.txt
--- linux-libre-2.6.29-gnu1/Documentation/input/multi-touch-protocol.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/input/multi-touch-protocol.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,195 @@
+Multi-touch (MT) Protocol
+-------------------------
+	Copyright (C) 2009	Henrik Rydberg <rydberg@euromail.se>
+
+
+Introduction
+------------
+
+In order to utilize the full power of the new multi-touch devices, a way to
+report detailed finger data to user space is needed. This document
+describes the multi-touch (MT) protocol which allows kernel drivers to
+report details for an arbitrary number of fingers.
+
+
+Usage
+-----
+
+Anonymous finger details are sent sequentially as separate packets of ABS
+events. Only the ABS_MT events are recognized as part of a finger
+packet. The end of a packet is marked by calling the input_mt_sync()
+function, which generates a SYN_MT_REPORT event. This instructs the
+receiver to accept the data for the current finger and prepare to receive
+another. The end of a multi-touch transfer is marked by calling the usual
+input_sync() function. This instructs the receiver to act upon events
+accumulated since last EV_SYN/SYN_REPORT and prepare to receive a new
+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
+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
+that currently support it, the ABS_MT_TRACKING_ID event may be used to
+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
+   SYN_REPORT
+
+
+Event Semantics
+---------------
+
+The word "contact" is used to describe a tool which is in direct contact
+with the surface. A finger, a pen or a rubber all classify as contacts.
+
+ABS_MT_TOUCH_MAJOR
+
+The length of the major axis of the contact. The length should be given in
+surface units. If the surface has an X times Y resolution, the largest
+possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal [4].
+
+ABS_MT_TOUCH_MINOR
+
+The length, in surface units, of the minor axis of the contact. If the
+contact is circular, this event can be omitted [4].
+
+ABS_MT_WIDTH_MAJOR
+
+The length, in surface units, of the major axis of the approaching
+tool. This should be understood as the size of the tool itself. The
+orientation of the contact and the approaching tool are assumed to be the
+same [4].
+
+ABS_MT_WIDTH_MINOR
+
+The length, in surface units, of the minor axis of the approaching
+tool. Omit if circular [4].
+
+The above four values can be used to derive additional information about
+the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates
+the notion of pressure. The fingers of the hand and the palm all have
+different characteristic widths [1].
+
+ABS_MT_ORIENTATION
+
+The orientation of the ellipse. The value should describe a signed quarter
+of a revolution clockwise around the touch center. The signed value range
+is arbitrary, but zero should be returned for a finger aligned along the Y
+axis of the surface, a negative value when finger is turned to the left, and
+a positive value when finger turned to the right. When completely aligned with
+the X axis, the range max should be returned.  Orientation can be omitted
+if the touching object is circular, or if the information is not available
+in the kernel driver. Partial orientation support is possible if the device
+can distinguish between the two axis, but not (uniquely) any values in
+between. In such cases, the range of ABS_MT_ORIENTATION should be [0, 1]
+[4].
+
+ABS_MT_POSITION_X
+
+The surface X coordinate of the center of the touching ellipse.
+
+ABS_MT_POSITION_Y
+
+The surface Y coordinate of the center of the touching ellipse.
+
+ABS_MT_TOOL_TYPE
+
+The type of approaching tool. A lot of kernel drivers cannot distinguish
+between different tool types, such as a finger or a pen. In such cases, the
+event should be omitted. The protocol currently supports MT_TOOL_FINGER and
+MT_TOOL_PEN [2].
+
+ABS_MT_BLOB_ID
+
+The BLOB_ID groups several packets together into one arbitrarily shaped
+contact. This is a low-level anonymous grouping, and should not be confused
+with the high-level trackingID [5]. Most kernel drivers will not have blob
+capability, and can safely omit the event.
+
+ABS_MT_TRACKING_ID
+
+The TRACKING_ID identifies an initiated contact throughout its life cycle
+[5]. There are currently only a few devices that support it, so this event
+should normally be omitted.
+
+
+Event Computation
+-----------------
+
+The flora of different hardware unavoidably leads to some devices fitting
+better to the MT protocol than others. To simplify and unify the mapping,
+this section gives recipes for how to compute certain events.
+
+For devices reporting contacts as rectangular shapes, signed orientation
+cannot be obtained. Assuming X and Y are the lengths of the sides of the
+touching rectangle, here is a simple formula that retains the most
+information possible:
+
+   ABS_MT_TOUCH_MAJOR := max(X, Y)
+   ABS_MT_TOUCH_MINOR := min(X, Y)
+   ABS_MT_ORIENTATION := bool(X > Y)
+
+The range of ABS_MT_ORIENTATION should be set to [0, 1], to indicate that
+the device can distinguish between a finger along the Y axis (0) and a
+finger along the X axis (1).
+
+
+Finger Tracking
+---------------
+
+The kernel driver should generate an arbitrary enumeration of the set of
+anonymous contacts currently on the surface. The order in which the packets
+appear in the event stream is not important.
+
+The process of finger tracking, i.e., to assign a unique trackingID to each
+initiated contact on the surface, is left to user space; preferably the
+multi-touch X driver [3]. In that driver, the trackingID stays the same and
+unique until the contact vanishes (when the finger leaves the surface). The
+problem of assigning a set of anonymous fingers to a set of identified
+fingers is a euclidian bipartite matching problem at each event update, and
+relies on a sufficiently rapid update rate.
+
+There are a few devices that support trackingID in hardware. User space can
+make use of these native identifiers to reduce bandwidth and cpu usage.
+
+
+Notes
+-----
+
+In order to stay compatible with existing applications, the data
+reported in a finger packet must not be recognized as single-touch
+events. In addition, all finger data must bypass input filtering,
+since subsequent events of the same type refer to different fingers.
+
+The first kernel driver to utilize the MT protocol is the bcm5974 driver,
+where examples can be found.
+
+[1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the
+difference between the contact position and the approaching tool position
+could be used to derive tilt.
+[2] The list can of course be extended.
+[3] The multi-touch X driver is currently in the prototyping stage. At the
+time of writing (April 2009), the MT protocol is not yet merged, and the
+prototype implements finger matching, basic mouse support and two-finger
+scrolling. The project aims at improving the quality of current multi-touch
+functionality available in the Synaptics X driver, and in addition
+implement more advanced gestures.
+[4] See the section on event computation.
+[5] See the section on finger tracking.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/input/rotary-encoder.txt linux-libre-2.6.30-gnu1/Documentation/input/rotary-encoder.txt
--- linux-libre-2.6.29-gnu1/Documentation/input/rotary-encoder.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/input/rotary-encoder.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,101 @@
+rotary-encoder - a generic driver for GPIO connected devices
+Daniel Mack <daniel@caiaq.de>, Feb 2009
+
+0. Function
+-----------
+
+Rotary encoders are devices which are connected to the CPU or other
+peripherals with two wires. The outputs are phase-shifted by 90 degrees
+and by triggering on falling and rising edges, the turn direction can
+be determined.
+
+The phase diagram of these two outputs look like this:
+
+                  _____       _____       _____
+                 |     |     |     |     |     |
+  Channel A  ____|     |_____|     |_____|     |____
+
+                 :  :  :  :  :  :  :  :  :  :  :  :
+            __       _____       _____       _____
+              |     |     |     |     |     |     |
+  Channel B   |_____|     |_____|     |_____|     |__
+
+                 :  :  :  :  :  :  :  :  :  :  :  :
+  Event          a  b  c  d  a  b  c  d  a  b  c  d
+
+                |<-------->|
+	          one step
+
+
+For more information, please see
+	http://en.wikipedia.org/wiki/Rotary_encoder
+
+
+1. Events / state machine
+-------------------------
+
+a) Rising edge on channel A, channel B in low state
+	This state is used to recognize a clockwise turn
+
+b) Rising edge on channel B, channel A in high state
+	When entering this state, the encoder is put into 'armed' state,
+	meaning that there it has seen half the way of a one-step transition.
+
+c) Falling edge on channel A, channel B in high state
+	This state is used to recognize a counter-clockwise turn
+
+d) Falling edge on channel B, channel A in low state
+	Parking position. If the encoder enters this state, a full transition
+	should have happend, unless it flipped back on half the way. The
+	'armed' state tells us about that.
+
+2. Platform requirements
+------------------------
+
+As there is no hardware dependent call in this driver, the platform it is
+used with must support gpiolib. Another requirement is that IRQs must be
+able to fire on both edges.
+
+
+3. Board integration
+--------------------
+
+To use this driver in your system, register a platform_device with the
+name 'rotary-encoder' and associate the IRQs and some specific platform
+data with it.
+
+struct rotary_encoder_platform_data is declared in
+include/linux/rotary-encoder.h and needs to be filled with the number of
+steps the encoder has and can carry information about externally inverted
+signals (because of used invertig buffer or other reasons).
+
+Because GPIO to IRQ mapping is platform specific, this information must
+be given in seperately to the driver. See the example below.
+
+---------<snip>---------
+
+/* board support file example */
+
+#include <linux/input.h>
+#include <linux/rotary_encoder.h>
+
+#define GPIO_ROTARY_A 1
+#define GPIO_ROTARY_B 2
+
+static struct rotary_encoder_platform_data my_rotary_encoder_info = {
+	.steps		= 24,
+	.axis		= ABS_X,
+	.gpio_a		= GPIO_ROTARY_A,
+	.gpio_b		= GPIO_ROTARY_B,
+	.inverted_a	= 0,
+	.inverted_b	= 0,
+};
+
+static struct platform_device rotary_encoder_device = {
+	.name		= "rotary-encoder",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &my_rotary_encoder_info,
+	}
+};
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/ioctl/ioctl-number.txt linux-libre-2.6.30-gnu1/Documentation/ioctl/ioctl-number.txt
--- linux-libre-2.6.29-gnu1/Documentation/ioctl/ioctl-number.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/ioctl/ioctl-number.txt	2009-06-09 23:05:27.000000000 -0400
@@ -122,10 +122,8 @@ Code	Seq#	Include File		Comments
 'c'	00-7F	linux/coda.h		conflict!
 'c'	80-9F	arch/s390/include/asm/chsc.h
 'd'	00-FF	linux/char/drm/drm/h	conflict!
-'d'	00-DF	linux/video_decoder.h	conflict!
 'd'	F0-FF	linux/digi1.h
 'e'	all	linux/digi1.h		conflict!
-'e'	00-1F	linux/video_encoder.h	conflict!
 'e'	00-1F	net/irda/irtty.h	conflict!
 'f'	00-1F	linux/ext2_fs.h
 'h'	00-7F				Charon filesystem
diff -druNp linux-libre-2.6.29-gnu1/Documentation/isdn/00-INDEX linux-libre-2.6.30-gnu1/Documentation/isdn/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/isdn/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/isdn/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -2,8 +2,14 @@
 	- this file (info on ISDN implementation for Linux)
 CREDITS
 	- list of the kind folks that brought you this stuff.
+HiSax.cert
+	- information about the ITU approval certification of the HiSax driver.
 INTERFACE
-	- description of Linklevel and Hardwarelevel ISDN interface.
+	- description of isdn4linux Link Level and Hardware Level interfaces.
+INTERFACE.fax
+	- description of the fax subinterface of isdn4linux.
+INTERFACE.CAPI
+	- description of kernel CAPI Link Level to Hardware Level interface.
 README
 	- general info on what you need and what to do for Linux ISDN.
 README.FAQ
@@ -12,6 +18,8 @@ README.audio
 	- info for running audio over ISDN.
 README.fax
 	- info for using Fax over ISDN.
+README.gigaset
+	- info on the drivers for Siemens Gigaset ISDN adapters.
 README.icn
 	- info on the ICN-ISDN-card and its driver.
 README.HiSax
@@ -37,7 +45,8 @@ README.diversion
 README.sc
 	- info on driver for Spellcaster cards.
 README.x25
-    _ info for running X.25 over ISDN.
+	- info for running X.25 over ISDN.
 README.hysdn
-        - info on driver for Hypercope active HYSDN cards
- 
+	- info on driver for Hypercope active HYSDN cards
+README.mISDN
+	- info on the Modular ISDN subsystem (mISDN).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/isdn/INTERFACE.CAPI linux-libre-2.6.30-gnu1/Documentation/isdn/INTERFACE.CAPI
--- linux-libre-2.6.29-gnu1/Documentation/isdn/INTERFACE.CAPI	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/isdn/INTERFACE.CAPI	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,213 @@
+Kernel CAPI Interface to Hardware Drivers
+-----------------------------------------
+
+1. Overview
+
+From the CAPI 2.0 specification:
+COMMON-ISDN-API (CAPI) is an application programming interface standard used
+to access ISDN equipment connected to basic rate interfaces (BRI) and primary
+rate interfaces (PRI).
+
+Kernel CAPI operates as a dispatching layer between CAPI applications and CAPI
+hardware drivers. Hardware drivers register ISDN devices (controllers, in CAPI
+lingo) with Kernel CAPI to indicate their readiness to provide their service
+to CAPI applications. CAPI applications also register with Kernel CAPI,
+requesting association with a CAPI device. Kernel CAPI then dispatches the
+application registration to an available device, forwarding it to the
+corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
+directions between the application and the hardware driver.
+
+Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
+This standard is freely available from http://www.capi.org.
+
+
+2. Driver and Device Registration
+
+CAPI drivers optionally register themselves with Kernel CAPI by calling the
+Kernel CAPI function register_capi_driver() with a pointer to a struct
+capi_driver. This structure must be filled with the name and revision of the
+driver, and optionally a pointer to a callback function, add_card(). The
+registration can be revoked by calling the function unregister_capi_driver()
+with a pointer to the same struct capi_driver.
+
+CAPI drivers must register each of the ISDN devices they control with Kernel
+CAPI by calling the Kernel CAPI function attach_capi_ctr() with a pointer to a
+struct capi_ctr before they can be used. This structure must be filled with
+the names of the driver and controller, and a number of callback function
+pointers which are subsequently used by Kernel CAPI for communicating with the
+driver. The registration can be revoked by calling the function
+detach_capi_ctr() with a pointer to the same struct capi_ctr.
+
+Before the device can be actually used, the driver must fill in the device
+information fields 'manu', 'version', 'profile' and 'serial' in the capi_ctr
+structure of the device, and signal its readiness by calling capi_ctr_ready().
+From then on, Kernel CAPI may call the registered callback functions for the
+device.
+
+If the device becomes unusable for any reason (shutdown, disconnect ...), the
+driver has to call capi_ctr_reseted(). This will prevent further calls to the
+callback functions by Kernel CAPI.
+
+
+3. Application Registration and Communication
+
+Kernel CAPI forwards registration requests from applications (calls to CAPI
+operation CAPI_REGISTER) to an appropriate hardware driver by calling its
+register_appl() callback function. A unique Application ID (ApplID, u16) is
+allocated by Kernel CAPI and passed to register_appl() along with the
+parameter structure provided by the application. This is analogous to the
+open() operation on regular files or character devices.
+
+After a successful return from register_appl(), CAPI messages from the
+application may be passed to the driver for the device via calls to the
+send_message() callback function. The CAPI message to send is stored in the
+data portion of an skb. Conversely, the driver may call Kernel CAPI's
+capi_ctr_handle_message() function to pass a received CAPI message to Kernel
+CAPI for forwarding to an application, specifying its ApplID.
+
+Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
+forwarded as calls to the release_appl() callback function, passing the same
+ApplID as with register_appl(). After return from release_appl(), no CAPI
+messages for that application may be passed to or from the device anymore.
+
+
+4. Data Structures
+
+4.1 struct capi_driver
+
+This structure describes a Kernel CAPI driver itself. It is used in the
+register_capi_driver() and unregister_capi_driver() functions, and contains
+the following non-private fields, all to be set by the driver before calling
+register_capi_driver():
+
+char name[32]
+	the name of the driver, as a zero-terminated ASCII string
+char revision[32]
+	the revision number of the driver, as a zero-terminated ASCII string
+int (*add_card)(struct capi_driver *driver, capicardparams *data)
+	a callback function pointer (may be NULL)
+
+
+4.2 struct capi_ctr
+
+This structure describes an ISDN device (controller) handled by a Kernel CAPI
+driver. After registration via the attach_capi_ctr() function it is passed to
+all controller specific lower layer interface and callback functions to
+identify the controller to operate on.
+
+It contains the following non-private fields:
+
+- to be set by the driver before calling attach_capi_ctr():
+
+struct module *owner
+	pointer to the driver module owning the device
+
+void *driverdata
+	an opaque pointer to driver specific data, not touched by Kernel CAPI
+
+char name[32]
+	the name of the controller, as a zero-terminated ASCII string
+
+char *driver_name
+	the name of the driver, as a zero-terminated ASCII string
+
+int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)
+	(optional) pointer to a callback function for sending firmware and
+	configuration data to the device
+
+void (*reset_ctr)(struct capi_ctr *ctrlr)
+	pointer to a callback function for performing a reset on the device,
+	releasing all registered applications
+
+void (*register_appl)(struct capi_ctr *ctrlr, u16 applid,
+			capi_register_params *rparam)
+void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)
+	pointers to callback functions for registration and deregistration of
+	applications with the device
+
+u16  (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
+	pointer to a callback function for sending a CAPI message to the
+	device
+
+char *(*procinfo)(struct capi_ctr *ctrlr)
+	pointer to a callback function returning the entry for the device in
+	the CAPI controller info table, /proc/capi/controller
+
+read_proc_t *ctr_read_proc
+	pointer to the read_proc callback function for the device's proc file
+	system entry, /proc/capi/controllers/<n>; will be called with a
+	pointer to the device's capi_ctr structure as the last (data) argument
+
+- to be filled in before calling capi_ctr_ready():
+
+u8 manu[CAPI_MANUFACTURER_LEN]
+	value to return for CAPI_GET_MANUFACTURER
+
+capi_version version
+	value to return for CAPI_GET_VERSION
+
+capi_profile profile
+	value to return for CAPI_GET_PROFILE
+
+u8 serial[CAPI_SERIAL_LEN]
+	value to return for CAPI_GET_SERIAL
+
+
+5. Lower Layer Interface Functions
+
+(declared in <linux/isdn/capilli.h>)
+
+void register_capi_driver(struct capi_driver *drvr)
+void unregister_capi_driver(struct capi_driver *drvr)
+	register/unregister a driver with Kernel CAPI
+
+int attach_capi_ctr(struct capi_ctr *ctrlr)
+int detach_capi_ctr(struct capi_ctr *ctrlr)
+	register/unregister a device (controller) with Kernel CAPI
+
+void capi_ctr_ready(struct capi_ctr *ctrlr)
+void capi_ctr_reseted(struct capi_ctr *ctrlr)
+	signal controller ready/not ready
+
+void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
+void capi_ctr_resume_output(struct capi_ctr *ctrlr)
+	signal suspend/resume
+
+void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
+				struct sk_buff *skb)
+	pass a received CAPI message to Kernel CAPI
+	for forwarding to the specified application
+
+
+6. Helper Functions and Macros
+
+Library functions (from <linux/isdn/capilli.h>):
+
+void capilib_new_ncci(struct list_head *head, u16 applid,
+			u32 ncci, u32 winsize)
+void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
+void capilib_release_appl(struct list_head *head, u16 applid)
+void capilib_release(struct list_head *head)
+void capilib_data_b3_conf(struct list_head *head, u16 applid,
+			u32 ncci, u16 msgid)
+u16  capilib_data_b3_req(struct list_head *head, u16 applid,
+			u32 ncci, u16 msgid)
+
+
+Macros to extract/set element values from/in a CAPI message header
+(from <linux/isdn/capiutil.h>):
+
+Get Macro		Set Macro			Element (Type)
+
+CAPIMSG_LEN(m)		CAPIMSG_SETLEN(m, len)		Total Length (u16)
+CAPIMSG_APPID(m)	CAPIMSG_SETAPPID(m, applid)	ApplID (u16)
+CAPIMSG_COMMAND(m)	CAPIMSG_SETCOMMAND(m,cmd)	Command (u8)
+CAPIMSG_SUBCOMMAND(m)	CAPIMSG_SETSUBCOMMAND(m, cmd)	Subcommand (u8)
+CAPIMSG_CMD(m)		-				Command*256
+							+ Subcommand (u16)
+CAPIMSG_MSGID(m)	CAPIMSG_SETMSGID(m, msgid)	Message Number (u16)
+
+CAPIMSG_CONTROL(m)	CAPIMSG_SETCONTROL(m, contr)	Controller/PLCI/NCCI
+							(u32)
+CAPIMSG_DATALEN(m)	CAPIMSG_SETDATALEN(m, len)	Data Length (u16)
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/isdn/README.gigaset linux-libre-2.6.30-gnu1/Documentation/isdn/README.gigaset
--- linux-libre-2.6.29-gnu1/Documentation/isdn/README.gigaset	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/isdn/README.gigaset	2009-06-09 23:05:27.000000000 -0400
@@ -61,24 +61,28 @@ GigaSet 307x Device Driver
      ---------------------
 2.1. Modules
      -------
-     To get the device working, you have to load the proper kernel module. You
-     can do this using
-         modprobe modulename
-     where modulename is ser_gigaset (M101), usb_gigaset (M105), or
-     bas_gigaset (direct USB connection to the base).
+     For the devices to work, the proper kernel modules have to be loaded.
+     This normally happens automatically when the system detects the USB
+     device (base, M105) or when the line discipline is attached (M101). It
+     can also be triggered manually using the modprobe(8) command, for example
+     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. To use it,
-     run the Gigaset M101 daemon "gigasetm101d" (also available from
-     http://sourceforge.net/projects/gigaset307x/) with the device file of the
-     RS232 port to the M101 as an argument, for example:
-	 gigasetm101d /dev/ttyS1
-     This will open the device file, set its line discipline to N_GIGASET_M101,
-     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 gigasetm101d
-     before disconnecting the device.
+     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
+     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
+     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.
 
 2.2. Device nodes for user space programs
      ------------------------------------
@@ -194,10 +198,11 @@ GigaSet 307x Device Driver
      operation (for wireless access to the base), but are needed for access
      to the M105's own configuration mode (registration to the base, baudrate
      and line format settings, device status queries) via the gigacontr
-     utility. Their use is disabled in the driver by default for safety
-     reasons but can be enabled by setting the kernel configuration option
-     "Support for undocumented USB requests" (GIGASET_UNDOCREQ) to "Y" and
-     recompiling.
+     utility. Their use is controlled by the kernel configuration option
+     "Support for undocumented USB requests" (CONFIG_GIGASET_UNDOCREQ). If you
+     encounter error code -ENOTTY when trying to use some features of the
+     M105, try setting that option to "y" via 'make {x,menu}config' and
+     recompiling the driver.
 
 
 3.   Troubleshooting
@@ -228,6 +233,13 @@ GigaSet 307x Device Driver
      Solution:
         Select Unimodem mode for all DECT data adapters. (see section 2.4.)
 
+     Problem:
+        You want to configure your USB DECT data adapter (M105) but gigacontr
+        reports an error: "/dev/ttyGU0: Inappropriate ioctl for device".
+     Solution:
+        Recompile the usb_gigaset driver with the kernel configuration option
+        CONFIG_GIGASET_UNDOCREQ set to 'y'. (see section 2.6.)
+
 3.2. Telling the driver to provide more information
      ----------------------------------------------
      Building the driver with the "Gigaset debugging" kernel configuration
diff -druNp linux-libre-2.6.29-gnu1/Documentation/kbuild/makefiles.txt linux-libre-2.6.30-gnu1/Documentation/kbuild/makefiles.txt
--- linux-libre-2.6.29-gnu1/Documentation/kbuild/makefiles.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/kbuild/makefiles.txt	2009-06-09 23:05:27.000000000 -0400
@@ -40,10 +40,16 @@ This document describes the Linux kernel
 	   --- 6.7 Custom kbuild commands
 	   --- 6.8 Preprocessing linker scripts
 
-	=== 7 Kbuild Variables
-	=== 8 Makefile language
-	=== 9 Credits
-	=== 10 TODO
+	=== 7 Kbuild syntax for exported headers
+		--- 7.1 header-y
+		--- 7.2 objhdr-y
+		--- 7.3 destination-y
+		--- 7.4 unifdef-y (deprecated)
+
+	=== 8 Kbuild Variables
+	=== 9 Makefile language
+	=== 10 Credits
+	=== 11 TODO
 
 === 1 Overview
 
@@ -310,6 +316,16 @@ more details, with real examples.
 		#arch/m68k/fpsp040/Makefile
 		ldflags-y := -x
 
+    subdir-ccflags-y, subdir-asflags-y
+	The two flags listed above are similar to ccflags-y and as-falgs-y.
+	The difference is that the subdir- variants has effect for the kbuild
+	file where tey are present and all subdirectories.
+	Options specified using subdir-* are added to the commandline before
+	the options specified using the non-subdir variants.
+
+	Example:
+		subdir-ccflags-y := -Werror
+
     CFLAGS_$@, AFLAGS_$@
 
 	CFLAGS_$@ and AFLAGS_$@ only apply to commands in current
@@ -1143,8 +1159,69 @@ When kbuild executes, the following step
 	The kbuild infrastructure for *lds file are used in several
 	architecture-specific files.
 
+=== 7 Kbuild syntax for exported headers
 
-=== 7 Kbuild Variables
+The kernel include a set of headers that is exported to userspace.
+Many headers can be exported as-is but other headers requires  a
+minimal pre-processing before they are ready for user-space.
+The pre-processing does:
+- drop kernel specific annotations
+- drop include of compiler.h
+- drop all sections that is kernel internat (guarded by ifdef __KERNEL__)
+
+Each relevant directory contain a file name "Kbuild" which specify the
+headers to be exported.
+See subsequent chapter for the syntax of the Kbuild file.
+
+	--- 7.1 header-y
+
+	header-y specify header files to be exported.
+
+		Example:
+			#include/linux/Kbuild
+			header-y += usb/
+			header-y += aio_abi.h
+
+	The convention is to list one file per line and
+	preferably in alphabetic order.
+
+	header-y also specify which subdirectories to visit.
+	A subdirectory is identified by a trailing '/' which
+	can be seen in the example above for the usb subdirectory.
+
+	Subdirectories are visited before their parent directories.
+
+	--- 7.2 objhdr-y
+
+	objhdr-y specifies generated files to be exported.
+	Generated files are special as they need to be looked
+	up in another directory when doing 'make O=...' builds.
+
+		Example:
+			#include/linux/Kbuild
+			objhdr-y += version.h
+
+	--- 7.3 destination-y
+
+	When an architecture have a set of exported headers that needs to be
+	exported to a different directory destination-y is used.
+	destination-y specify the destination directory for all exported
+	headers in the file where it is present.
+
+		Example:
+			#arch/xtensa/platforms/s6105/include/platform/Kbuild
+			destination-y := include/linux
+
+	In the example above all exported headers in the Kbuild file
+	will be located in the directory "include/linux" when exported.
+
+
+	--- 7.4 unifdef-y (deprecated)
+
+	unifdef-y is deprecated. A direct replacement is header-y.
+
+
+=== 8 Kbuild Variables
 
 The top Makefile exports the following variables:
 
@@ -1206,7 +1283,7 @@ The top Makefile exports the following v
 	INSTALL_MOD_STRIP will used as the option(s) to the strip command.
 
 
-=== 8 Makefile language
+=== 9 Makefile language
 
 The kernel Makefiles are designed to be run with GNU Make.  The Makefiles
 use only the documented features of GNU Make, but they do use many
@@ -1225,14 +1302,14 @@ time the left-hand side is used.
 There are some cases where "=" is appropriate.  Usually, though, ":="
 is the right choice.
 
-=== 9 Credits
+=== 10 Credits
 
 Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
 Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
 Updates by Sam Ravnborg <sam@ravnborg.org>
 Language QA by Jan Engelhardt <jengelh@gmx.de>
 
-=== 10 TODO
+=== 11 TODO
 
 - Describe how kbuild supports shipped files with _shipped.
 - Generating offset header files.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/kernel-doc-nano-HOWTO.txt linux-libre-2.6.30-gnu1/Documentation/kernel-doc-nano-HOWTO.txt
--- linux-libre-2.6.29-gnu1/Documentation/kernel-doc-nano-HOWTO.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/kernel-doc-nano-HOWTO.txt	2009-06-09 23:05:27.000000000 -0400
@@ -269,7 +269,10 @@ Use the argument mechanism to document m
 
 Inside a struct description, you can use the "private:" and "public:"
 comment tags.  Structure fields that are inside a "private:" area
-are not listed in the generated output documentation.
+are not listed in the generated output documentation.  The "private:"
+and "public:" tags must begin immediately following a "/*" comment
+marker.  They may optionally include comments between the ":" and the
+ending "*/" marker.
 
 Example:
 
@@ -283,7 +286,7 @@ Example:
 struct my_struct {
     int a;
     int b;
-/* private: */
+/* private: internal use only */
     int c;
 };
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/kernel-parameters.txt linux-libre-2.6.30-gnu1/Documentation/kernel-parameters.txt
--- linux-libre-2.6.29-gnu1/Documentation/kernel-parameters.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/kernel-parameters.txt	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,12 @@ are specified on the kernel command line
 
 	usbcore.blinkenlights=1
 
+Hyphens (dashes) and underscores are equivalent in parameter names, so
+	log_buf_len=1M print-fatal-signals=1
+can also be entered as
+	log-buf-len=1M print_fatal_signals=1
+
+
 This document may not be entirely up to date and comprehensive. The command
 "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
 module. Loadable modules, after being loaded into the running kernel, also
@@ -44,11 +50,13 @@ parameter is applicable:
 	FB	The frame buffer device is enabled.
 	HW	Appropriate hardware is enabled.
 	IA-64	IA-64 architecture is enabled.
+	IMA     Integrity measurement architecture is enabled.
 	IOSCHED	More than one I/O scheduler is enabled.
 	IP_PNP	IP DHCP, BOOTP, or RARP is enabled.
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
+	KMEMTRACE kmemtrace is enabled.
 	LIBATA  Libata driver is enabled
 	LP	Printer support is enabled.
 	LOOP	Loopback device support is enabled.
@@ -132,7 +140,7 @@ and is between 256 and 4096 characters.
 ./include/asm/setup.h as COMMAND_LINE_SIZE.
 
 
-	acpi=		[HW,ACPI,X86-64,i386]
+	acpi=		[HW,ACPI,X86]
 			Advanced Configuration and Power Interface
 			Format: { force | off | ht | strict | noirq | rsdt }
 			force -- enable ACPI if default was off
@@ -151,60 +159,6 @@ and is between 256 and 4096 characters.
 			1,0: use 1st APIC table
 			default: 0
 
-	acpi_sleep=	[HW,ACPI] Sleep options
-			Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
-				  old_ordering, s4_nonvs }
-			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
-			as soon as the kernel's real-mode entry point is called.
-			s4_nohwsig prevents ACPI hardware signature from being
-			used during resume from hibernation.
-			old_ordering causes the ACPI 1.0 ordering of the _PTS
-			control method, with respect to putting devices into
-			low power states, to be enforced (the ACPI 2.0 ordering
-			of _PTS is used by default).
-			s4_nonvs prevents the kernel from saving/restoring the
-			ACPI NVS memory during hibernation.
-
-	acpi_sci=	[HW,ACPI] ACPI System Control Interrupt trigger mode
-			Format: { level | edge | high | low }
-
-	acpi_irq_balance [HW,ACPI]
-			ACPI will balance active IRQs
-			default in APIC mode
-
-	acpi_irq_nobalance [HW,ACPI]
-			ACPI will not move active IRQs (default)
-			default in PIC mode
-
-	acpi_irq_pci=	[HW,ACPI] If irq_balance, clear listed IRQs for
-			use by PCI
-			Format: <irq>,<irq>...
-
-	acpi_irq_isa=	[HW,ACPI] If irq_balance, mark listed IRQs used by ISA
-			Format: <irq>,<irq>...
-
-	acpi_no_auto_ssdt	[HW,ACPI] Disable automatic loading of SSDT
-
-	acpi_os_name=	[HW,ACPI] Tell ACPI BIOS the name of the OS
-			Format: To spoof as Windows 98: ="Microsoft Windows"
-
-	acpi_osi=	[HW,ACPI] Modify list of supported OS interface strings
-			acpi_osi="string1"	# add string1 -- only one string
-			acpi_osi="!string2"	# remove built-in string2
-			acpi_osi=		# disable all strings
-
-	acpi_serialize	[HW,ACPI] force serialization of AML methods
-
-	acpi_skip_timer_override [HW,ACPI]
-			Recognize and ignore IRQ0/pin2 Interrupt Override.
-			For broken nForce2 BIOS resulting in XT-PIC timer.
-	acpi_use_timer_override [HW,ACPI]
-			Use timer override. For some broken Nvidia NF5 boards
-			that require a timer override, but don't have
-			HPET
-
 	acpi_backlight=	[HW,ACPI]
 			acpi_backlight=vendor
 			acpi_backlight=video
@@ -212,11 +166,6 @@ and is between 256 and 4096 characters.
 			(e.g. thinkpad_acpi, sony_acpi, etc.) instead
 			of the ACPI video.ko driver.
 
-	acpi_display_output=	[HW,ACPI]
-			acpi_display_output=vendor
-			acpi_display_output=video
-			See above.
-
 	acpi.debug_layer=	[HW,ACPI,ACPI_DEBUG]
 	acpi.debug_level=	[HW,ACPI,ACPI_DEBUG]
 			Format: <int>
@@ -245,6 +194,41 @@ and is between 256 and 4096 characters.
 			unusable.  The "log_buf_len" parameter may be useful
 			if you need to capture more output.
 
+	acpi_display_output=	[HW,ACPI]
+			acpi_display_output=vendor
+			acpi_display_output=video
+			See above.
+
+	acpi_irq_balance [HW,ACPI]
+			ACPI will balance active IRQs
+			default in APIC mode
+
+	acpi_irq_nobalance [HW,ACPI]
+			ACPI will not move active IRQs (default)
+			default in PIC mode
+
+	acpi_irq_isa=	[HW,ACPI] If irq_balance, mark listed IRQs used by ISA
+			Format: <irq>,<irq>...
+
+	acpi_irq_pci=	[HW,ACPI] If irq_balance, clear listed IRQs for
+			use by PCI
+			Format: <irq>,<irq>...
+
+	acpi_no_auto_ssdt	[HW,ACPI] Disable automatic loading of SSDT
+
+	acpi_os_name=	[HW,ACPI] Tell ACPI BIOS the name of the OS
+			Format: To spoof as Windows 98: ="Microsoft Windows"
+
+	acpi_osi=	[HW,ACPI] Modify list of supported OS interface strings
+			acpi_osi="string1"	# add string1 -- only one string
+			acpi_osi="!string2"	# remove built-in string2
+			acpi_osi=		# disable all strings
+
+	acpi_pm_good	[X86]
+			Override the pmtimer bug detection: force the kernel
+			to assume that this machine's pmtimer latches its value
+			and always returns good values.
+
  	acpi.power_nocheck=	[HW,ACPI]
  			Format: 1/0 enable/disable the check of power state.
  			On some bogus BIOS the _PSC object/_STA object of
@@ -253,30 +237,57 @@ and is between 256 and 4096 characters.
  			power state again in power transition.
  			1 : disable the power state check
 
-	acpi_pm_good	[X86-32,X86-64]
-			Override the pmtimer bug detection: force the kernel
-			to assume that this machine's pmtimer latches its value
-			and always returns good values.
+	acpi_sci=	[HW,ACPI] ACPI System Control Interrupt trigger mode
+			Format: { level | edge | high | low }
 
-	agp=		[AGP]
-			{ off | try_unsupported }
-			off: disable AGP support
-			try_unsupported: try to drive unsupported chipsets
-				(may crash computer or cause data corruption)
+	acpi_serialize	[HW,ACPI] force serialization of AML methods
 
-	enable_timer_pin_1 [i386,x86-64]
-			Enable PIN 1 of APIC timer
-			Can be useful to work around chipset bugs
-			(in particular on some ATI chipsets).
-			The kernel tries to set a reasonable default.
+	acpi_skip_timer_override [HW,ACPI]
+			Recognize and ignore IRQ0/pin2 Interrupt Override.
+			For broken nForce2 BIOS resulting in XT-PIC timer.
 
-	disable_timer_pin_1 [i386,x86-64]
-			Disable PIN 1 of APIC timer
-			Can be useful to work around chipset bugs.
+	acpi_sleep=	[HW,ACPI] Sleep options
+			Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
+				  old_ordering, s4_nonvs }
+			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
+			as soon as the kernel's real-mode entry point is called.
+			s4_nohwsig prevents ACPI hardware signature from being
+			used during resume from hibernation.
+			old_ordering causes the ACPI 1.0 ordering of the _PTS
+			control method, with respect to putting devices into
+			low power states, to be enforced (the ACPI 2.0 ordering
+			of _PTS is used by default).
+			s4_nonvs prevents the kernel from saving/restoring the
+			ACPI NVS memory during hibernation.
+
+	acpi_use_timer_override [HW,ACPI]
+			Use timer override. For some broken Nvidia NF5 boards
+			that require a timer override, but don't have HPET
+
+	acpi_enforce_resources=	[ACPI]
+			{ strict | lax | no }
+			Check for resource conflicts between native drivers
+			and ACPI OperationRegions (SystemIO and SystemMemory
+			only). IO ports and memory declared in ACPI might be
+			used by the ACPI subsystem in arbitrary AML code and
+			can interfere with legacy drivers.
+			strict (default): access to resources claimed by ACPI
+			is denied; legacy drivers trying to access reserved
+			resources will fail to bind to device using them.
+			lax: access to resources claimed by ACPI is allowed;
+			legacy drivers trying to access reserved resources
+			will bind successfully but a warning message is logged.
+			no: ACPI OperationRegions are not marked as reserved,
+			no further checks are performed.
 
 	ad1848=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>,<type>
 
+	add_efi_memmap	[EFI; X86] Include EFI memory map in
+			kernel's map of available physical RAM.
+
 	advansys=	[HW,SCSI]
 			See header of drivers/scsi/advansys.c.
 
@@ -287,6 +298,12 @@ and is between 256 and 4096 characters.
 			Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
 			See also header of sound/oss/aedsp16.c.
 
+	agp=		[AGP]
+			{ off | try_unsupported }
+			off: disable AGP support
+			try_unsupported: try to drive unsupported chipsets
+				(may crash computer or cause data corruption)
+
 	aha152x=	[HW,SCSI]
 			See Documentation/scsi/aha152x.txt.
 
@@ -334,7 +351,7 @@ and is between 256 and 4096 characters.
 			not play well with APC CPU idle - disable it if you have
 			APC and your system crashes randomly.
 
-	apic=		[APIC,i386] Advanced Programmable Interrupt Controller
+	apic=		[APIC,X86-32] Advanced Programmable Interrupt Controller
 			Change the output verbosity whilst booting
 			Format: { quiet (default) | verbose | debug }
 			Change the amount of debugging information output
@@ -414,12 +431,6 @@ and is between 256 and 4096 characters.
 			possible to determine what the correct size should be.
 			This option provides an override for these situations.
 
-	security=	[SECURITY] Choose a security module to enable at boot.
-			If this boot parameter is not specified, only the first
-			security module asking for security registration will be
-			loaded. An invalid security module name will be treated
-			as if no module has been chosen.
-
 	capability.disable=
 			[SECURITY] Disable capabilities.  This would normally
 			be used only if an alternative security model is to be
@@ -486,17 +497,11 @@ and is between 256 and 4096 characters.
 			Also note the kernel might malfunction if you disable
 			some critical bits.
 
-	code_bytes	[IA32/X86_64] How many bytes of object code to print
+	code_bytes	[X86] How many bytes of object code to print
 			in an oops report.
 			Range: 0 - 8192
 			Default: 64
 
-	hpet=		[X86-32,HPET] option to control HPET usage
-			Format: { enable (default) | disable | force }
-			disable: disable HPET and use PIT instead
-			force: allow force enabled of undocumented chips (ICH4,
-			VIA, nVidia)
-
 	com20020=	[HW,NET] ARCnet - COM20020 chipset
 			Format:
 			<io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
@@ -540,23 +545,6 @@ and is between 256 and 4096 characters.
 			console=brl,ttyS0
 		For now, only VisioBraille is supported.
 
-	earlycon=	[KNL] Output early console device and options.
-		uart[8250],io,<addr>[,options]
-		uart[8250],mmio,<addr>[,options]
-			Start an early, polled-mode console on the 8250/16550
-			UART at the specified I/O port or MMIO address.
-			The options are the same as for ttyS, above.
-
-	no_console_suspend
-			[HW] Never suspend the console
-			Disable suspending of consoles during suspend and
-			hibernate operations.  Once disabled, debugging
-			messages can reach various consoles while the rest
-			of the system is being put to sleep (ie, while
-			debugging driver suspend/resume hooks).  This may
-			not work reliably with all consoles, but is known
-			to work with serial and VGA consoles.
-
 	coredump_filter=
 			[KNL] Change the default value for
 			/proc/<pid>/coredump_filter.
@@ -604,36 +592,22 @@ and is between 256 and 4096 characters.
 
 	debug_objects	[KNL] Enable object debugging
 
+	no_debug_objects
+			[KNL] Disable object debugging
+
 	debugpat	[X86] Enable PAT debugging
 
 	decnet.addr=	[HW,NET]
 			Format: <area>[,<node>]
 			See also Documentation/networking/decnet.txt.
 
-	vt.default_blu=	[VT]
-			Format: <blue0>,<blue1>,<blue2>,...,<blue15>
-			Change the default blue palette of the console.
-			This is a 16-member array composed of values
-			ranging from 0-255.
-
-	vt.default_grn=	[VT]
-			Format: <green0>,<green1>,<green2>,...,<green15>
-			Change the default green palette of the console.
-			This is a 16-member array composed of values
-			ranging from 0-255.
-
-	vt.default_red=	[VT]
-			Format: <red0>,<red1>,<red2>,...,<red15>
-			Change the default red palette of the console.
-			This is a 16-member array composed of values
-			ranging from 0-255.
-
-	vt.default_utf8=
-			[VT]
-			Format=<0|1>
-			Set system-wide default UTF-8 mode for all tty's.
-			Default is 1, i.e. UTF-8 mode is enabled for all
-			newly opened terminals.
+	default_hugepagesz=
+			[same as hugepagesz=] The size of the default
+			HugeTLB page size. This is the size represented by
+			the legacy /proc/ hugepages APIs, used for SHM, and
+			default size when mounting hugetlbfs filesystems.
+			Defaults to the default architecture's huge page size
+			if not specified.
 
 	dhash_entries=	[KNL]
 			Set number of hash buckets for dentry cache.
@@ -646,27 +620,9 @@ and is between 256 and 4096 characters.
 			Documentation/serial/digiepca.txt.
 
 	disable_mtrr_cleanup [X86]
-	enable_mtrr_cleanup [X86]
 			The kernel tries to adjust MTRR layout from continuous
 			to discrete, to make X server driver able to add WB
-			entry later. This parameter enables/disables that.
-
-	mtrr_chunk_size=nn[KMG] [X86]
-			used for mtrr cleanup. It is largest continous chunk
-			that could hold holes aka. UC entries.
-
-	mtrr_gran_size=nn[KMG] [X86]
-			Used for mtrr cleanup. It is granularity of mtrr block.
-			Default is 1.
-			Large value could prevent small alignment from
-			using up MTRRs.
-
-	mtrr_spare_reg_nr=n [X86]
-			Format: <integer>
-			Range: 0,7 : spare reg number
-			Default : 1
-			Used for mtrr cleanup. It is spare mtrr entries number.
-			Set to 2 or more if your graphical card needs more.
+			entry later. This parameter disables that.
 
 	disable_mtrr_trim [X86, Intel and AMD only]
 			By default the kernel will trim any uncacheable
@@ -674,13 +630,39 @@ and is between 256 and 4096 characters.
 			MTRR settings.  This parameter disables that behavior,
 			possibly causing your machine to run very slowly.
 
+	disable_timer_pin_1 [X86]
+			Disable PIN 1 of APIC timer
+			Can be useful to work around chipset bugs.
+
 	dmasound=	[HW,OSS] Sound subsystem buffers
 
+	dma_debug=off	If the kernel is compiled with DMA_API_DEBUG support,
+			this option disables the debugging code at boot.
+
+	dma_debug_entries=<number>
+			This option allows to tune the number of preallocated
+			entries for DMA-API debugging code. One entry is
+			required per DMA-API allocation. Use this if the
+			DMA-API debugging code disables itself because the
+			architectural default is too low.
+
 	dscc4.setup=	[NET]
 
 	dtc3181e=	[HW,SCSI]
 
-	earlyprintk=	[X86-32,X86-64,SH,BLACKFIN]
+	dynamic_printk	Enables pr_debug()/dev_dbg() calls if
+			CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
+			These can also be switched on/off via
+			<debugfs>/dynamic_printk/modules
+
+	earlycon=	[KNL] Output early console device and options.
+		uart[8250],io,<addr>[,options]
+		uart[8250],mmio,<addr>[,options]
+			Start an early, polled-mode console on the 8250/16550
+			UART at the specified I/O port or MMIO address.
+			The options are the same as for ttyS, above.
+
+	earlyprintk=	[X86,SH,BLACKFIN]
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 			earlyprintk=dbgp
@@ -715,12 +697,23 @@ and is between 256 and 4096 characters.
 			See Documentation/block/as-iosched.txt and
 			Documentation/block/deadline-iosched.txt for details.
 
-	elfcorehdr=	[IA64,PPC,SH,X86-32,X86_64]
+	elfcorehdr=	[IA64,PPC,SH,X86]
 			Specifies physical address of start of kernel core
 			image elf header. Generally kexec loader will
 			pass this option to capture kernel.
 			See Documentation/kdump/kdump.txt for details.
 
+	enable_mtrr_cleanup [X86]
+			The kernel tries to adjust MTRR layout from continuous
+			to discrete, to make X server driver able to add WB
+			entry later. This parameter enables that.
+
+	enable_timer_pin_1 [X86]
+			Enable PIN 1 of APIC timer
+			Can be useful to work around chipset bugs
+			(in particular on some ATI chipsets).
+			The kernel tries to set a reasonable default.
+
 	enforcing	[SELINUX] Set initial enforcing status.
 			Format: {"0" | "1"}
 			See security/selinux/Kconfig help text.
@@ -788,7 +781,7 @@ and is between 256 and 4096 characters.
 
 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
 			are distributed across NUMA nodes.  Defaults on
-			for IA-64, off otherwise.
+			for 64bit NUMA, off otherwise.
 			Format: 0 | 1 (for off | on)
 
 	hcl=		[IA-64] SGI's Hardware Graph compatibility layer
@@ -808,6 +801,16 @@ and is between 256 and 4096 characters.
 	hisax=		[HW,ISDN]
 			See Documentation/isdn/README.HiSax.
 
+	hlt		[BUGS=ARM,SH]
+
+	hpet=		[X86-32,HPET] option to control HPET usage
+			Format: { enable (default) | disable | force |
+				verbose }
+			disable: disable HPET and use PIT instead
+			force: allow force enabled of undocumented chips (ICH4,
+				VIA, nVidia)
+			verbose: show contents of HPET registers during setup
+
 	hugepages=	[HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
 	hugepagesz=	[HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
 			On x86-64 and powerpc, this option can be specified
@@ -817,18 +820,18 @@ and is between 256 and 4096 characters.
 			(when the CPU supports the "pdpe1gb" cpuinfo flag)
 			Note that 1GB pages can only be allocated at boot time
 			using hugepages= and not freed afterwards.
-	default_hugepagesz=
-			[same as hugepagesz=] The size of the default
-			HugeTLB page size. This is the size represented by
-			the legacy /proc/ hugepages APIs, used for SHM, and
-			default size when mounting hugetlbfs filesystems.
-			Defaults to the default architecture's huge page size
-			if not specified.
-
-	hlt		[BUGS=ARM,SH]
 
 	hvc_iucv=	[S390] Number of z/VM IUCV hypervisor console (HVC)
 			       terminal devices. Valid values: 0..8
+	hvc_iucv_allow=	[S390] Comma-separated list of z/VM user IDs.
+			       If specified, z/VM IUCV HVC accepts connections
+			       from listed z/VM user IDs only.
+
+	i2c_bus=	[HW] Override the default board specific I2C bus speed
+			     or register an additional I2C bus that is not
+			     registered from board initialization code.
+			     Format:
+			     <bus_id>,<clkrate>
 
 	i8042.debug	[HW] Toggle i8042 debug mode
 	i8042.direct	[HW] Put keyboard port into non-translated mode
@@ -877,6 +880,9 @@ and is between 256 and 4096 characters.
 	idebus=		[HW] (E)IDE subsystem - VLB/PCI bus speed
 			See Documentation/ide/ide.txt.
 
+	ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
+			Claim all unknown PCI IDE storage controllers.
+
 	idle=		[X86]
 			Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
 			Poll forces a polling idle loop that can slightly
@@ -892,9 +898,6 @@ and is between 256 and 4096 characters.
 			In such case C2/C3 won't be used again.
 			idle=nomwait: Disable mwait for CPU C-states
 
-	ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
-			Claim all unknown PCI IDE storage controllers.
-
 	ignore_loglevel	[KNL]
 			Ignore loglevel setting - this will print /all/
 			kernel messages to the console. Useful for debugging.
@@ -902,6 +905,15 @@ and is between 256 and 4096 characters.
 	ihash_entries=	[KNL]
 			Set number of hash buckets for inode cache.
 
+	ima_audit=	[IMA]
+			Format: { "0" | "1" }
+			0 -- integrity auditing messages. (Default)
+			1 -- enable informational integrity auditing messages.
+
+	ima_hash=	[IMA]
+			Formt: { "sha1" | "md5" }
+			default: "sha1"
+
 	in2000=		[HW,SCSI]
 			See header of drivers/scsi/in2000.c.
 
@@ -919,25 +931,6 @@ and is between 256 and 4096 characters.
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 			Format: <irq>
 
-	inttest=	[IA64]
-
-	iomem=		Disable strict checking of access to MMIO memory
-		strict	regions from userspace.
-		relaxed
-
-	iommu=		[x86]
-		off
-		force
-		noforce
-		biomerge
-		panic
-		nopanic
-		merge
-		nomerge
-		forcesac
-		soft
-
-
 	intel_iommu=	[DMAR] Intel IOMMU driver (DMAR) option
 		on
 			Enable intel iommu driver.
@@ -961,7 +954,29 @@ and is between 256 and 4096 characters.
 			result in a hardware IOTLB flush operation as opposed
 			to batching them for performance.
 
-	io_delay=	[X86-32,X86-64] I/O delay method
+	inttest=	[IA64]
+
+	iomem=		Disable strict checking of access to MMIO memory
+		strict	regions from userspace.
+		relaxed
+
+	iommu=		[x86]
+		off
+		force
+		noforce
+		biomerge
+		panic
+		nopanic
+		merge
+		nomerge
+		forcesac
+		soft
+
+	io7=		[HW] IO7 for Marvel based alpha systems
+			See comment before marvel_specify_io7 in
+			arch/alpha/kernel/core_marvel.c.
+
+	io_delay=	[X86] I/O delay method
 		0x80
 			Standard port 0x80 based delay
 		0xed
@@ -971,10 +986,6 @@ and is between 256 and 4096 characters.
 		none
 			No delay
 
-	io7=		[HW] IO7 for Marvel based alpha systems
-			See comment before marvel_specify_io7 in
-			arch/alpha/kernel/core_marvel.c.
-
 	ip=		[IP_PNP]
 			See Documentation/filesystems/nfsroot.txt.
 
@@ -985,12 +996,6 @@ and is between 256 and 4096 characters.
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
-	ports=		[IP_VS_FTP] IPVS ftp helper module
-			Default is 21.
-			Up to 8 (IP_VS_APP_MAX_PORTS) ports
-			may be specified.
-			Format: <port>,<port>....
-
 	irqfixup	[HW]
 			When an interrupt is not handled search all handlers
 			for it. Intended to get systems with badly broken
@@ -1031,7 +1036,9 @@ and is between 256 and 4096 characters.
 	js=		[HW,JOY] Analog joystick
 			See Documentation/input/joystick.txt.
 
-	kernelcore=nn[KMG]	[KNL,X86-32,IA-64,PPC,X86-64] This parameter
+	keepinitrd	[HW,ARM]
+
+	kernelcore=nn[KMG]	[KNL,X86,IA-64,PPC] This parameter
 			specifies the amount of memory usable by the kernel
 			for non-movable allocations.  The requested amount is
 			spread evenly throughout all nodes in the system. The
@@ -1047,20 +1054,14 @@ and is between 256 and 4096 characters.
 			use the HighMem zone if it exists, and the Normal
 			zone if it does not.
 
-	movablecore=nn[KMG]	[KNL,X86-32,IA-64,PPC,X86-64] This parameter
-			is similar to kernelcore except it specifies the
-			amount of memory used for migratable allocations.
-			If both kernelcore and movablecore is specified,
-			then kernelcore will be at *least* the specified
-			value but may be more. If movablecore on its own
-			is specified, the administrator must be careful
-			that the amount of memory usable for all allocations
-			is not too small.
-
-	keepinitrd	[HW,ARM]
+	kmemtrace.enable=	[KNL,KMEMTRACE] Format: { yes | no }
+				Controls whether kmemtrace is enabled
+				at boot-time.
 
-	kstack=N	[X86-32,X86-64] Print N words from the kernel stack
-			in oops dumps.
+	kmemtrace.subbufs=n	[KNL,KMEMTRACE] Overrides the number of
+			subbufs kmemtrace's relay channel has. Set this
+			higher than default (KMEMTRACE_N_SUBBUFS in code) if
+			you experience buffer overruns.
 
 	kgdboc=		[HW] kgdb over consoles.
 			Requires a tty driver that supports console polling.
@@ -1071,6 +1072,9 @@ and is between 256 and 4096 characters.
 			Configure the RouterBoard 532 series on-chip
 			Ethernet adapter MAC address.
 
+	kstack=N	[X86] Print N words from the kernel stack
+			in oops dumps.
+
 	l2cr=		[PPC]
 
 	l3cr=		[PPC]
@@ -1078,7 +1082,7 @@ and is between 256 and 4096 characters.
 	lapic		[X86-32,APIC] Enable the local APIC even if BIOS
 			disabled it.
 
-	lapic_timer_c2_ok	[X86-32,x86-64,APIC] trust the local apic timer
+	lapic_timer_c2_ok	[X86,APIC] trust the local apic timer
 			in C2 power state.
 
 	libata.dma=	[LIBATA] DMA control
@@ -1216,9 +1220,8 @@ and is between 256 and 4096 characters.
 			(machvec) in a generic kernel.
 			Example: machvec=hpzx1_swiotlb
 
-	max_loop=	[LOOP] Maximum number of loopback devices that can
-			be mounted
-			Format: <1-256>
+	max_addr=nn[KMG]	[KNL,BOOT,ia64] All physical memory greater
+			than or equal to this physical address is ignored.
 
 	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
 			should make use of.  maxcpus=n : n >= 0 limits the
@@ -1226,8 +1229,9 @@ and is between 256 and 4096 characters.
 			it is equivalent to "nosmp", which also disables
 			the IO APIC.
 
-	max_addr=nn[KMG]	[KNL,BOOT,ia64] All physical memory greater than
-			or equal to this physical address is ignored.
+	max_loop=	[LOOP] Maximum number of loopback devices that can
+			be mounted
+			Format: <1-256>
 
 	max_luns=	[SCSI] Maximum number of LUNs to probe.
 			Should be between 1 and 2^32-1.
@@ -1263,7 +1267,7 @@ and is between 256 and 4096 characters.
 			[KNL,SH] Allow user to override the default size for
 			per-device physically contiguous DMA buffers.
 
-	memmap=exactmap	[KNL,X86-32,X86_64] Enable setting of an exact
+	memmap=exactmap	[KNL,X86] Enable setting of an exact
 			E820 memory map, as specified by the user.
 			Such memmap=exactmap lines can be constructed based on
 			BIOS output or other requirements. See the memmap=nn@ss
@@ -1310,8 +1314,13 @@ and is between 256 and 4096 characters.
 
 	memtest=	[KNL,X86] Enable memtest
 			Format: <integer>
-			range: 0,4 : pattern number
 			default : 0 <disable>
+			Specifies the number of memtest passes to be
+			performed. Each pass selects another test
+			pattern from a given set of patterns. Memtest
+			fills the memory with this pattern, validates
+			memory contents and reserves bad memory
+			regions that are detected.
 
 	meye.*=		[HW] Set MotionEye Camera parameters
 			See Documentation/video4linux/meye.txt.
@@ -1349,6 +1358,16 @@ and is between 256 and 4096 characters.
 	mousedev.yres=	[MOUSE] Vertical screen resolution, used for devices
 			reporting absolute coordinates, such as tablets
 
+	movablecore=nn[KMG]	[KNL,X86,IA-64,PPC] This parameter
+			is similar to kernelcore except it specifies the
+			amount of memory used for migratable allocations.
+			If both kernelcore and movablecore is specified,
+			then kernelcore will be at *least* the specified
+			value but may be more. If movablecore on its own
+			is specified, the administrator must be careful
+			that the amount of memory usable for all allocations
+			is not too small.
+
 	mpu401=		[HW,OSS]
 			Format: <io>,<irq>
 
@@ -1370,6 +1389,23 @@ and is between 256 and 4096 characters.
 			[HW] Make the MicroTouch USB driver use raw coordinates
 			('y', default) or cooked coordinates ('n')
 
+	mtrr_chunk_size=nn[KMG] [X86]
+			used for mtrr cleanup. It is largest continous chunk
+			that could hold holes aka. UC entries.
+
+	mtrr_gran_size=nn[KMG] [X86]
+			Used for mtrr cleanup. It is granularity of mtrr block.
+			Default is 1.
+			Large value could prevent small alignment from
+			using up MTRRs.
+
+	mtrr_spare_reg_nr=n [X86]
+			Format: <integer>
+			Range: 0,7 : spare reg number
+			Default : 1
+			Used for mtrr cleanup. It is spare mtrr entries number.
+			Set to 2 or more if your graphical card needs more.
+
 	n2=		[NET] SDL Inc. RISCom/N2 synchronous serial card
 
 	NCR_D700=	[HW,SCSI]
@@ -1424,17 +1460,19 @@ and is between 256 and 4096 characters.
 			when a NMI is triggered.
 			Format: [state][,regs][,debounce][,die]
 
-	nmi_watchdog=	[KNL,BUGS=X86-32,X86-64] Debugging features for SMP kernels
+	nmi_watchdog=	[KNL,BUGS=X86] Debugging features for SMP kernels
 			Format: [panic,][num]
 			Valid num: 0,1,2
 			0 - turn nmi_watchdog off
 			1 - use the IO-APIC timer for the NMI watchdog
 			2 - use the local APIC for the NMI watchdog using
-			a performance counter. Note: This will use one performance
-			counter and the local APIC's performance vector.
-			When panic is specified panic when an NMI watchdog timeout occurs.
-			This is useful when you use a panic=... timeout and need the box
-			quickly up again.
+			a performance counter. Note: This will use one
+			performance counter and the local APIC's performance
+			vector.
+			When panic is specified, panic when an NMI watchdog
+			timeout occurs.
+			This is useful when you use a panic=... timeout and
+			need the box quickly up again.
 			Instead of 1 and 2 it is possible to use the following
 			symbolic names: lapic and ioapic
 			Example: nmi_watchdog=2 or nmi_watchdog=panic,lapic
@@ -1443,6 +1481,16 @@ and is between 256 and 4096 characters.
 			emulation library even if a 387 maths coprocessor
 			is present.
 
+	no_console_suspend
+			[HW] Never suspend the console
+			Disable suspending of consoles during suspend and
+			hibernate operations.  Once disabled, debugging
+			messages can reach various consoles while the rest
+			of the system is being put to sleep (ie, while
+			debugging driver suspend/resume hooks).  This may
+			not work reliably with all consoles, but is known
+			to work with serial and VGA consoles.
+
 	noaliencache	[MM, NUMA, SLAB] Disables the allocation of alien
 			caches in the slab allocator.  Saves per-node memory,
 			but will impact performance.
@@ -1457,17 +1505,19 @@ and is between 256 and 4096 characters.
 
 	nocache		[ARM]
 
+	noclflush	[BUGS=X86] Don't use the CLFLUSH instruction
+
 	nodelayacct	[KNL] Disable per-task delay accounting
 
 	nodisconnect	[HW,SCSI,M68K] Disables SCSI disconnects.
 
 	nodsp		[SH] Disable hardware DSP at boot time.
 
-	noefi		[X86-32,X86-64] Disable EFI runtime services support.
+	noefi		[X86] Disable EFI runtime services support.
 
 	noexec		[IA-64]
 
-	noexec		[X86-32,X86-64]
+	noexec		[X86]
 			On X86-32 available only on PAE configured kernels.
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable non-executable mappings
@@ -1485,9 +1535,13 @@ and is between 256 and 4096 characters.
 			register save and restore. The kernel will only save
 			legacy floating-point registers on task switch.
 
-	noclflush	[BUGS=X86] Don't use the CLFLUSH instruction
+	noxsave		[BUGS=X86] Disables x86 extended register state save
+			and restore using xsave. The kernel will fallback to
+			enabling legacy floating-point and sse state.
 
-	nohlt		[BUGS=ARM,SH]
+	nohlt		[BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
+			wfi(ARM) instruction doesn't work correctly and not to
+			use it. This is also useful when using JTAG debugger.
 
 	no-hlt		[BUGS=X86-32] Tells the kernel that the hlt
 			instruction doesn't work correctly and not to
@@ -1508,10 +1562,12 @@ and is between 256 and 4096 characters.
 			Valid arguments: on, off
 			Default: on
 
+	noiotrap	[SH] Disables trapped I/O port accesses.
+
 	noirqdebug	[X86-32] Disables the code which attempts to detect and
 			disable unhandled interrupt sources.
 
-	no_timer_check	[X86-32,X86_64,APIC] Disables the code which tests for
+	no_timer_check	[X86,APIC] Disables the code which tests for
 			broken timer IRQ sources.
 
 	noisapnp	[ISAPNP] Disables ISA PnP code.
@@ -1527,12 +1583,6 @@ and is between 256 and 4096 characters.
 
 	nolapic_timer	[X86-32,APIC] Do not use the local APIC timer.
 
-	nox2apic	[X86-64,APIC] Do not enable x2APIC mode.
-
-	x2apic_phys	[X86-64,APIC] Use x2apic physical mode instead of
-			default x2apic cluster mode on platforms
-			supporting x2apic.
-
 	noltlbs		[PPC] Do not use large page/tlb entries for kernel
 			lowmem mapping on PPC40x.
 
@@ -1543,6 +1593,9 @@ and is between 256 and 4096 characters.
 	nomfgpt		[X86-32] Disable Multi-Function General Purpose
 			Timer usage (for AMD Geode machines).
 
+	norandmaps	Don't use address space randomization.  Equivalent to
+			echo 0 > /proc/sys/kernel/randomize_va_space
+
 	noreplace-paravirt	[X86-32,PV_OPS] Don't patch paravirt_ops
 
 	noreplace-smp	[X86-32,SMP] Don't replace SMP instructions
@@ -1567,7 +1620,7 @@ and is between 256 and 4096 characters.
 	nosoftlockup	[KNL] Disable the soft-lockup detector.
 
 	noswapaccount	[KNL] Disable accounting of swap in memory resource
-			controller. (See Documentation/controllers/memory.txt)
+			controller. (See Documentation/cgroups/memory.txt)
 
 	nosync		[HW,M68K] Disables sync negotiation for all devices.
 
@@ -1577,17 +1630,19 @@ and is between 256 and 4096 characters.
 
 	nowb		[ARM]
 
+	nox2apic	[X86-64,APIC] Do not enable x2APIC mode.
+
 	nptcg=		[IA64] Override max number of concurrent global TLB
 			purges which is reported from either PAL_VM_SUMMARY or
 			SAL PALO.
 
+	nr_uarts=	[SERIAL] maximum number of UARTs to be registered.
+
 	numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
 			one of ['zone', 'node', 'default'] can be specified
 			This can be set from sysctl after boot.
 			See Documentation/sysctl/vm.txt for details.
 
-	nr_uarts=	[SERIAL] maximum number of UARTs to be registered.
-
 	ohci1394_dma=early	[HW] enable debugging via the ohci1394 driver.
 			See Documentation/debugging-via-ohci1394.txt for more
 			info.
@@ -1659,6 +1714,8 @@ and is between 256 and 4096 characters.
 			See also Documentation/blockdev/paride.txt.
 
 	pci=option[,option...]	[PCI] various PCI subsystem options:
+		earlydump	[X86] dump PCI config space before the kernel
+			        changes anything
 		off		[X86] don't probe for the PCI bus
 		bios		[X86-32] force use of PCI BIOS, don't access
 				the hardware directly. Use this if your machine
@@ -1676,7 +1733,7 @@ and is between 256 and 4096 characters.
 				disable the use of PCIE advanced error reporting.
 		nodomains	[PCI] Disable support for multiple PCI
 				root domains (aka PCI segments, in ACPI-speak).
-		nommconf	[X86-32,X86_64] Disable use of MMCONFIG for PCI
+		nommconf	[X86] Disable use of MMCONFIG for PCI
 				Configuration
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 				enabled, this kernel boot option can be used to
@@ -1758,6 +1815,15 @@ and is between 256 and 4096 characters.
 		cbmemsize=nn[KMG]	The fixed amount of bus space which is
 				reserved for the CardBus bridge's memory
 				window. The default value is 64 megabytes.
+		resource_alignment=
+				Format:
+				[<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
+				Specifies alignment and device to reassign
+				aligned memory resources.
+				If <order of align> is not specified,
+				PAGE_SIZE is used as alignment.
+				PCI-PCI bridge can be specified, if resource
+				windows need to be expanded.
 
 	pcie_aspm=	[PCIE] Forcibly enable or disable PCIe Active State Power
 			Management.
@@ -1816,10 +1882,11 @@ and is between 256 and 4096 characters.
 			autoconfiguration.
 			Ranges are in pairs (memory base and size).
 
-	dynamic_printk	Enables pr_debug()/dev_dbg() calls if
-			CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
-			These can also be switched on/off via
-			<debugfs>/dynamic_printk/modules
+	ports=		[IP_VS_FTP] IPVS ftp helper module
+			Default is 21.
+			Up to 8 (IP_VS_APP_MAX_PORTS) ports
+			may be specified.
+			Format: <port>,<port>....
 
 	print-fatal-signals=
 			[KNL] debug: print fatal signals
@@ -1830,6 +1897,14 @@ and is between 256 and 4096 characters.
 	printk.time=	Show timing data prefixed to each printk message line
 			Format: <bool>  (1/Y/y=enable, 0/N/n=disable)
 
+	processor.max_cstate=	[HW,ACPI]
+			Limit processor to maximum C-state
+			max_cstate=9 overrides any DMI blacklist limit.
+
+	processor.nocst	[HW,ACPI]
+			Ignore the _CST method to determine C-states,
+			instead using the legacy FADT method
+
 	profile=	[KNL] Enable kernel profiling via /proc/profile
 			Format: [schedule,]<number>
 			Param: "schedule" - profile schedule points.
@@ -1839,14 +1914,6 @@ and is between 256 and 4096 characters.
 				Requires CONFIG_SCHEDSTATS
 			Param: "kvm" - profile VM exits.
 
-	processor.max_cstate=	[HW,ACPI]
-			Limit processor to maximum C-state
-			max_cstate=9 overrides any DMI blacklist limit.
-
-	processor.nocst	[HW,ACPI]
-			Ignore the _CST method to determine C-states,
-			instead using the legacy FADT method
-
 	prompt_ramdisk=	[RAM] List of RAM disks to prompt for floppy disk
 			before loading.
 			See Documentation/blockdev/ramdisk.txt.
@@ -1911,7 +1978,7 @@ and is between 256 and 4096 characters.
 
 	relax_domain_level=
 			[KNL, SMP] Set scheduler's default relax_domain_level.
-			See Documentation/cpusets.txt.
+			See Documentation/cgroups/cpusets.txt.
 
 	reserve=	[KNL,BUGS] Force the kernel to ignore some iomem area
 
@@ -2000,7 +2067,13 @@ and is between 256 and 4096 characters.
 			allowing boot to proceed.  none ignores them, expecting
 			user space to do the scan.
 
-	selinux		[SELINUX] Disable or enable SELinux at boot time.
+	security=	[SECURITY] Choose a security module to enable at boot.
+			If this boot parameter is not specified, only the first
+			security module asking for security registration will be
+			loaded. An invalid security module name will be treated
+			as if no module has been chosen.
+
+	selinux=	[SELINUX] Disable or enable SELinux at boot time.
 			Format: { "0" | "1" }
 			See security/selinux/Kconfig help text.
 			0 -- disable.
@@ -2009,15 +2082,6 @@ and is between 256 and 4096 characters.
 			If enabled at boot time, /selinux/disable can be used
 			later to disable prior to initial policy load.
 
-	selinux_compat_net =
-			[SELINUX] Set initial selinux_compat_net flag value.
-                        Format: { "0" | "1" }
-                        0 -- use new secmark-based packet controls
-                        1 -- use legacy packet controls
-                        Default value is 0 (preferred).
-                        Value can be changed at runtime via
-                        /selinux/compat_net.
-
 	serialnumber	[BUGS=X86-32]
 
 	shapers=	[NET]
@@ -2329,6 +2393,8 @@ and is between 256 and 4096 characters.
 
 	tp720=		[HW,PS2]
 
+	trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size.
+
 	trix=		[HW,OSS] MediaTrix AudioTrix Pro
 			Format:
 			<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
@@ -2364,7 +2430,7 @@ and is between 256 and 4096 characters.
 			reported either.
 
 	unknown_nmi_panic
-			[X86-32,X86-64]
+			[X86]
 			Set unknown_nmi_panic=1 early on boot.
 
 	usbcore.autosuspend=
@@ -2431,15 +2497,12 @@ and is between 256 and 4096 characters.
 					medium is write-protected).
 			Example: quirks=0419:aaf5:rl,0421:0433:rc
 
-	add_efi_memmap	[EFI; x86-32,X86-64] Include EFI memory map in
-			kernel's map of available physical RAM.
-
-	vdso=		[X86-32,SH,x86-64]
+	vdso=		[X86,SH]
 			vdso=2: enable compat VDSO (default with COMPAT_VDSO)
 			vdso=1: enable VDSO (default)
 			vdso=0: disable VDSO mapping
 
-	vdso32=		[X86-32,X86-64]
+	vdso32=		[X86]
 			vdso32=2: enable compat VDSO (default with COMPAT_VDSO)
 			vdso32=1: enable 32-bit VDSO (default)
 			vdso32=0: disable 32-bit VDSO mapping
@@ -2472,6 +2535,31 @@ and is between 256 and 4096 characters.
 	vmpoff=		[KNL,S390] Perform z/VM CP command after power off.
 			Format: <command>
 
+	vt.default_blu=	[VT]
+			Format: <blue0>,<blue1>,<blue2>,...,<blue15>
+			Change the default blue palette of the console.
+			This is a 16-member array composed of values
+			ranging from 0-255.
+
+	vt.default_grn=	[VT]
+			Format: <green0>,<green1>,<green2>,...,<green15>
+			Change the default green palette of the console.
+			This is a 16-member array composed of values
+			ranging from 0-255.
+
+	vt.default_red=	[VT]
+			Format: <red0>,<red1>,<red2>,...,<red15>
+			Change the default red palette of the console.
+			This is a 16-member array composed of values
+			ranging from 0-255.
+
+	vt.default_utf8=
+			[VT]
+			Format=<0|1>
+			Set system-wide default UTF-8 mode for all tty's.
+			Default is 1, i.e. UTF-8 mode is enabled for all
+			newly opened terminals.
+
 	waveartist=	[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 
@@ -2484,6 +2572,10 @@ and is between 256 and 4096 characters.
 	wdt=		[WDT] Watchdog
 			See Documentation/watchdog/wdt.txt.
 
+	x2apic_phys	[X86-64,APIC] Use x2apic physical mode instead of
+			default x2apic cluster mode on platforms
+			supporting x2apic.
+
 	xd=		[HW,XT] Original XT pre-IDE (RLL encoded) disks.
 	xd_geo=		See header of drivers/block/xd.c.
 
@@ -2491,9 +2583,6 @@ and is between 256 and 4096 characters.
 			Format:
 			<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
 
-	norandmaps	Don't use address space randomization.  Equivalent to
-			echo 0 > /proc/sys/kernel/randomize_va_space
-
 ______________________________________________________________________
 
 TODO:
diff -druNp linux-libre-2.6.29-gnu1/Documentation/kprobes.txt linux-libre-2.6.30-gnu1/Documentation/kprobes.txt
--- linux-libre-2.6.29-gnu1/Documentation/kprobes.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/kprobes.txt	2009-06-09 23:05:27.000000000 -0400
@@ -212,7 +212,9 @@ hit, Kprobes calls kp->pre_handler.  Aft
 is single-stepped, Kprobe calls kp->post_handler.  If a fault
 occurs during execution of kp->pre_handler or kp->post_handler,
 or during single-stepping of the probed instruction, Kprobes calls
-kp->fault_handler.  Any or all handlers can be NULL.
+kp->fault_handler.  Any or all handlers can be NULL. If kp->flags
+is set KPROBE_FLAG_DISABLED, that kp will be registered but disabled,
+so, it's handlers aren't hit until calling enable_kprobe(kp).
 
 NOTE:
 1. With the introduction of the "symbol_name" field to struct kprobe,
@@ -363,6 +365,26 @@ probes) in the specified array, they cle
 incorrect probes. However, other probes in the array are
 unregistered correctly.
 
+4.7 disable_*probe
+
+#include <linux/kprobes.h>
+int disable_kprobe(struct kprobe *kp);
+int disable_kretprobe(struct kretprobe *rp);
+int disable_jprobe(struct jprobe *jp);
+
+Temporarily disables the specified *probe. You can enable it again by using
+enable_*probe(). You must specify the probe which has been registered.
+
+4.8 enable_*probe
+
+#include <linux/kprobes.h>
+int enable_kprobe(struct kprobe *kp);
+int enable_kretprobe(struct kretprobe *rp);
+int enable_jprobe(struct jprobe *jp);
+
+Enables *probe which has been disabled by disable_*probe(). You must specify
+the probe which has been registered.
+
 5. Kprobes Features and Limitations
 
 Kprobes allows multiple probes at the same address.  Currently,
@@ -500,10 +522,14 @@ the probe. If the probed function belong
 is also specified. Following columns show probe status. If the probe is on
 a virtual address that is no longer valid (module init sections, module
 virtual addresses that correspond to modules that've been unloaded),
-such probes are marked with [GONE].
+such probes are marked with [GONE]. If the probe is temporarily disabled,
+such probes are marked with [DISABLED].
 
-/debug/kprobes/enabled: Turn kprobes ON/OFF
+/debug/kprobes/enabled: Turn kprobes ON/OFF forcibly.
 
-Provides a knob to globally turn registered kprobes ON or OFF. By default,
-all kprobes are enabled. By echoing "0" to this file, all registered probes
-will be disarmed, till such time a "1" is echoed to this file.
+Provides a knob to globally and forcibly turn registered kprobes ON or OFF.
+By default, all kprobes are enabled. By echoing "0" to this file, all
+registered probes will be disarmed, till such time a "1" is echoed to this
+file. Note that this knob just disarms and arms all kprobes and doesn't
+change each probe's disabling state. This means that disabled kprobes (marked
+[DISABLED]) will be not enabled if you turn ON all kprobes by this knob.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/laptops/acer-wmi.txt linux-libre-2.6.30-gnu1/Documentation/laptops/acer-wmi.txt
--- linux-libre-2.6.29-gnu1/Documentation/laptops/acer-wmi.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/laptops/acer-wmi.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 Acer Laptop WMI Extras Driver
 http://code.google.com/p/aceracpi
-Version 0.2
-18th August 2008
+Version 0.3
+4th April 2009
 
-Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
 
 acer-wmi is a driver to allow you to control various parts of your Acer laptop
 hardware under Linux which are exposed via ACPI-WMI.
@@ -36,6 +36,10 @@ not possible in kernel space from a 64 b
 Supported Hardware
 ******************
 
+NOTE: The Acer Aspire One is not supported hardware. It cannot work with
+acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
+blacklisted until that happens.
+
 Please see the website for the current list of known working hardare:
 
 http://code.google.com/p/aceracpi/wiki/SupportedHardware
diff -druNp linux-libre-2.6.29-gnu1/Documentation/laptops/thinkpad-acpi.txt linux-libre-2.6.30-gnu1/Documentation/laptops/thinkpad-acpi.txt
--- linux-libre-2.6.29-gnu1/Documentation/laptops/thinkpad-acpi.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/laptops/thinkpad-acpi.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 		     ThinkPad ACPI Extras Driver
 
-                            Version 0.22
-                        November 23rd,  2008
+                            Version 0.23
+                          April 10th, 2009
 
                Borislav Deianov <borislav@users.sf.net>
              Henrique de Moraes Holschuh <hmh@hmh.eng.br>
@@ -20,7 +20,8 @@ moved to the drivers/misc tree and renam
 kernel 2.6.29 and release 0.22.
 
 The driver is named "thinkpad-acpi".  In some places, like module
-names, "thinkpad_acpi" is used because of userspace issues.
+names and log messages, "thinkpad_acpi" is used because of userspace
+issues.
 
 "tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
 long due to length limitations on some Linux kernel versions.
@@ -37,7 +38,7 @@ detailed description):
 	- ThinkLight on and off
 	- limited docking and undocking
 	- UltraBay eject
-	- CMOS control
+	- CMOS/UCMS control
 	- LED control
 	- ACPI sounds
 	- temperature sensors
@@ -46,6 +47,7 @@ detailed description):
 	- Volume control
 	- Fan control and monitoring: fan speed, fan enable/disable
 	- WAN enable and disable
+	- UWB enable and disable
 
 A compatibility table by model and feature is maintained on the web
 site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -53,7 +55,7 @@ reports, especially if they add to or co
 Please include the following information in your report:
 
 	- ThinkPad model name
-	- a copy of your DSDT, from /proc/acpi/dsdt
+	- a copy of your ACPI tables, using the "acpidump" utility
 	- a copy of the output of dmidecode, with serial numbers
 	  and UUIDs masked off
 	- which driver features work and which don't
@@ -66,17 +68,18 @@ Installation
 ------------
 
 If you are compiling this driver as included in the Linux kernel
-sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
-enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
-thinkpad-specific bay functionality.
+sources, look for the CONFIG_THINKPAD_ACPI Kconfig option.
+It is located on the menu path: "Device Drivers" -> "X86 Platform
+Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras".
+
 
 Features
 --------
 
 The driver exports two different interfaces to userspace, which can be
 used to access the features it provides.  One is a legacy procfs-based
-interface, which will be removed at some time in the distant future.
-The other is a new sysfs-based interface which is not complete yet.
+interface, which will be removed at some time in the future.  The other
+is a new sysfs-based interface which is not complete yet.
 
 The procfs interface creates the /proc/acpi/ibm directory.  There is a
 file under that directory for each feature it supports.  The procfs
@@ -111,15 +114,17 @@ The version of thinkpad-acpi's sysfs int
 as a driver attribute (see below).
 
 Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and
 /sys/bus/platform/drivers/thinkpad_hwmon/
 
 Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
 
 Sysfs device attributes for the sensors and fan are on the
 thinkpad_hwmon device's sysfs attribute space, but you should locate it
-looking for a hwmon device with the name attribute of "thinkpad".
+looking for a hwmon device with the name attribute of "thinkpad", or
+better yet, through libsensors.
+
 
 Driver version
 --------------
@@ -129,6 +134,7 @@ sysfs driver attribute: version
 
 The driver name and version. No commands can be written to this file.
 
+
 Sysfs interface version
 -----------------------
 
@@ -160,6 +166,7 @@ expect that an attribute might not be th
 (an attribute not being there *is* a valid way to make it clear that a
 feature is not available in sysfs).
 
+
 Hot keys
 --------
 
@@ -172,17 +179,14 @@ system.  Enabling the hotkey functionali
 firmware that such a driver is present, and modifies how the ThinkPad
 firmware will behave in many situations.
 
-The driver enables the hot key feature automatically when loaded.  The
-feature can later be disabled and enabled back at runtime.  The driver
-will also restore the hot key feature to its previous state and mask
-when it is unloaded.
+The driver enables the HKEY ("hot key") event reporting automatically
+when loaded, and disables it when it is removed.
 
-When the hotkey feature is enabled and the hot key mask is set (see
-below), the driver will report HKEY events in the following format:
+The driver will report HKEY events in the following format:
 
 	ibm/hotkey HKEY 00000080 0000xxxx
 
-Some of these events refer to hot key presses, but not all.
+Some of these events refer to hot key presses, but not all of them.
 
 The driver will generate events over the input layer for hot keys and
 radio switches, and over the ACPI netlink layer for other events.  The
@@ -214,13 +218,17 @@ procfs notes:
 
 The following commands can be written to the /proc/acpi/ibm/hotkey file:
 
-	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
-	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
 	echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
 	echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
 	... any other 8-hex-digit mask ...
 	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
 
+The following commands have been deprecated and will cause the kernel
+to log a warning:
+
+	echo enable > /proc/acpi/ibm/hotkey -- does nothing
+	echo disable > /proc/acpi/ibm/hotkey -- returns an error
+
 The procfs interface does not support NVRAM polling control.  So as to
 maintain maximum bug-to-bug compatibility, it does not report any masks,
 nor does it allow one to manipulate the hot key mask when the firmware
@@ -229,12 +237,9 @@ does not support masks at all, even if N
 sysfs notes:
 
 	hotkey_bios_enabled:
-		Returns the status of the hot keys feature when
-		thinkpad-acpi was loaded.  Upon module unload, the hot
-		key feature status will be restored to this value.
+		DEPRECATED, WILL BE REMOVED SOON.
 
-		0: hot keys were disabled
-		1: hot keys were enabled (unusual)
+		Returns 0.
 
 	hotkey_bios_mask:
 		Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -242,13 +247,10 @@ sysfs notes:
 		to this value.
 
 	hotkey_enable:
-		Enables/disables the hot keys feature in the ACPI
-		firmware, and reports current status of the hot keys
-		feature.  Has no effect on the NVRAM hot key polling
-		functionality.
+		DEPRECATED, WILL BE REMOVED SOON.
 
-		0: disables the hot keys feature / feature disabled
-		1: enables the hot keys feature / feature enabled
+		0: returns -EPERM
+		1: does nothing
 
 	hotkey_mask:
 		bit mask to enable driver-handling (and depending on
@@ -618,6 +620,7 @@ For Lenovo models *with* ACPI backlight
    and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN.  Process
    these keys on userspace somehow (e.g. by calling xbacklight).
 
+
 Bluetooth
 ---------
 
@@ -628,6 +631,9 @@ sysfs rfkill class: switch "tpacpi_bluet
 This feature shows the presence and current state of a ThinkPad
 Bluetooth device in the internal ThinkPad CDC slot.
 
+If the ThinkPad supports it, the Bluetooth state is stored in NVRAM,
+so it is kept across reboots and power-off.
+
 Procfs notes:
 
 If Bluetooth is installed, the following commands can be used:
@@ -652,6 +658,7 @@ Sysfs notes:
 	rfkill controller switch "tpacpi_bluetooth_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 Video output control -- /proc/acpi/ibm/video
 --------------------------------------------
 
@@ -693,11 +700,8 @@ Fn-F7 from working. This also disables t
 features of this driver, as it uses the same ACPI methods as
 Fn-F7. Video switching on the console should still work.
 
-UPDATE: There's now a patch for the X.org Radeon driver which
-addresses this issue. Some people are reporting success with the patch
-while others are still having problems. For more information:
+UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000
 
-https://bugs.freedesktop.org/show_bug.cgi?id=2000
 
 ThinkLight control
 ------------------
@@ -720,10 +724,11 @@ The ThinkLight sysfs interface is docume
 documentation, in Documentation/leds-class.txt.  The ThinkLight LED name
 is "tpacpi::thinklight".
 
-Due to limitations in the sysfs LED class, if the status of the thinklight
+Due to limitations in the sysfs LED class, if the status of the ThinkLight
 cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
 It is impossible to know if the status returned through sysfs is valid.
 
+
 Docking / undocking -- /proc/acpi/ibm/dock
 ------------------------------------------
 
@@ -784,6 +789,7 @@ the only docking stations currently supp
 UltraBase docks and "dumb" port replicators like the Mini Dock (the
 latter don't need any ACPI support, actually).
 
+
 UltraBay eject -- /proc/acpi/ibm/bay
 ------------------------------------
 
@@ -847,8 +853,9 @@ supported. Use "eject2" instead of "ejec
 Note: the UltraBay eject support on the 600e/x, A22p and A3x is
 EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
 
-CMOS control
-------------
+
+CMOS/UCMS control
+-----------------
 
 procfs: /proc/acpi/ibm/cmos
 sysfs device attribute: cmos_command
@@ -882,6 +889,7 @@ The cmos command interface is prone to f
 in newer ThinkPads it is just a compatibility layer.  Do not use it, it is
 exported just as a debug tool.
 
+
 LED control
 -----------
 
@@ -893,6 +901,17 @@ some older ThinkPad models, it is possib
 LED indicators as well.  Newer ThinkPads cannot query the real status
 of the LED indicators.
 
+Because misuse of the LEDs could induce an unaware user to perform
+dangerous actions (like undocking or ejecting a bay device while the
+buses are still active), or mask an important alarm (such as a nearly
+empty battery, or a broken battery), access to most LEDs is
+restricted.
+
+Unrestricted access to all LEDs requires that thinkpad-acpi be
+compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
+Distributions must never enable this option.  Individual users that
+are aware of the consequences are welcome to enabling it.
+
 procfs notes:
 
 The available commands are:
@@ -939,6 +958,7 @@ ThinkPad indicator LED should blink in h
 "timer" trigger, and leave the delay_on and delay_off parameters set to
 zero (to request hardware acceleration autodetection).
 
+
 ACPI sounds -- /proc/acpi/ibm/beep
 ----------------------------------
 
@@ -968,6 +988,7 @@ X40:
 	16 - one medium-pitched beep repeating constantly, stop with 17
 	17 - stop 16
 
+
 Temperature sensors
 -------------------
 
@@ -1115,6 +1136,7 @@ registers contain the current battery ca
 with this, do send me your results (including some complete dumps with
 a description of the conditions when they were taken.)
 
+
 LCD brightness control
 ----------------------
 
@@ -1124,10 +1146,9 @@ sysfs backlight device "thinkpad_screen"
 This feature allows software control of the LCD brightness on ThinkPad
 models which don't have a hardware brightness slider.
 
-It has some limitations: the LCD backlight cannot be actually turned on or
-off by this interface, and in many ThinkPad models, the "dim while on
-battery" functionality will be enabled by the BIOS when this interface is
-used, and cannot be controlled.
+It has some limitations: the LCD backlight cannot be actually turned
+on or off by this interface, it just controls the backlight brightness
+level.
 
 On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
 has eight brightness levels, ranging from 0 to 7.  Some of the levels
@@ -1136,10 +1157,15 @@ display backlight brightness control met
 from 0 to 15.
 
 There are two interfaces to the firmware for direct brightness control,
-EC and CMOS.  To select which one should be used, use the
+EC and UCMS (or CMOS).  To select which one should be used, use the
 brightness_mode module parameter: brightness_mode=1 selects EC mode,
-brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
-and CMOS.  The driver tries to auto-detect which interface to use.
+brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
+mode with NVRAM backing (so that brightness changes are remembered
+across shutdown/reboot).
+
+The driver tries to select which interface to use from a table of
+defaults for each ThinkPad model.  If it makes a wrong choice, please
+report this as a bug, so that we can fix it.
 
 When display backlight brightness controls are available through the
 standard ACPI interface, it is best to use it instead of this direct
@@ -1201,6 +1227,7 @@ WARNING:
     and maybe reduce the life of the backlight lamps by needlessly kicking
     its level up and down at every change.
 
+
 Volume control -- /proc/acpi/ibm/volume
 ---------------------------------------
 
@@ -1217,6 +1244,11 @@ distinct. The unmute the volume after th
 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 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.
+
+
 Fan control and monitoring: fan speed, fan enable/disable
 ---------------------------------------------------------
 
@@ -1383,8 +1415,11 @@ procfs: /proc/acpi/ibm/wan
 sysfs device attribute: wwan_enable (deprecated)
 sysfs rfkill class: switch "tpacpi_wwan_sw"
 
-This feature shows the presence and current state of a W-WAN (Sierra
-Wireless EV-DO) device.
+This feature shows the presence and current state of the built-in
+Wireless WAN device.
+
+If the ThinkPad supports it, the WWAN state is stored in NVRAM,
+so it is kept across reboots and power-off.
 
 It was tested on a Lenovo ThinkPad X60. It should probably work on other
 ThinkPad models which come with this module installed.
@@ -1413,6 +1448,7 @@ Sysfs notes:
 	rfkill controller switch "tpacpi_wwan_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 EXPERIMENTAL: UWB
 -----------------
 
@@ -1431,6 +1467,7 @@ Sysfs notes:
 	rfkill controller switch "tpacpi_uwb_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 Multiple Commands, Module Parameters
 ------------------------------------
 
@@ -1445,6 +1482,7 @@ for example:
 
 	modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
 
+
 Enabling debugging output
 -------------------------
 
@@ -1457,8 +1495,15 @@ will enable all debugging output classes
 to enable more than one output class, just add their values.
 
 	Debug bitmask		Description
+	0x8000			Disclose PID of userspace programs
+				accessing some functions of the driver
 	0x0001			Initialization and probing
 	0x0002			Removal
+	0x0004			RF Transmitter control (RFKILL)
+				(bluetooth, WWAN, UWB...)
+	0x0008			HKEY event interface, hotkeys
+	0x0010			Fan control
+	0x0020			Backlight brightness
 
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
@@ -1467,6 +1512,7 @@ The level of debugging information outpu
 at runtime through sysfs, using the driver attribute debug_level.  The
 attribute takes the same bitmask as the debug module parameter above.
 
+
 Force loading of module
 -----------------------
 
@@ -1505,3 +1551,7 @@ Sysfs interface changelog:
 
 0x020200:	Add poll()/select() support to the following attributes:
 		hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
+
+0x020300:	hotkey enable/disable support removed, attributes
+		hotkey_bios_enabled and hotkey_enable deprecated and
+		marked for removal.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/lguest/.gitignore linux-libre-2.6.30-gnu1/Documentation/lguest/.gitignore
--- linux-libre-2.6.29-gnu1/Documentation/lguest/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/lguest/.gitignore	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+lguest
diff -druNp linux-libre-2.6.29-gnu1/Documentation/lguest/lguest.c linux-libre-2.6.30-gnu1/Documentation/lguest/lguest.c
--- linux-libre-2.6.29-gnu1/Documentation/lguest/lguest.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/lguest/lguest.c	2009-06-09 23:05:27.000000000 -0400
@@ -1630,6 +1630,13 @@ static bool service_io(struct device *de
 		}
 	}
 
+	/* OK, so we noted that it was pretty poor to use an fdatasync as a
+	 * barrier.  But Christoph Hellwig points out that we need a sync
+	 * *afterwards* as well: "Barriers specify no reordering to the front
+	 * or the back."  And Jens Axboe confirmed it, so here we are: */
+	if (out->type & VIRTIO_BLK_T_BARRIER)
+		fdatasync(vblk->fd);
+
 	/* We can't trigger an IRQ, because we're not the Launcher.  It does
 	 * that when we tell it we're done. */
 	add_used(dev->vq, head, wlen);
diff -druNp linux-libre-2.6.29-gnu1/Documentation/lguest/lguest.txt linux-libre-2.6.30-gnu1/Documentation/lguest/lguest.txt
--- linux-libre-2.6.29-gnu1/Documentation/lguest/lguest.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/lguest/lguest.txt	2009-06-09 23:05:27.000000000 -0400
@@ -3,11 +3,11 @@
  /,    /`      - or, A Young Coder's Illustrated Hypervisor
  \\"--\\    http://lguest.ozlabs.org
 
-Lguest is designed to be a minimal hypervisor for the Linux kernel, for
-Linux developers and users to experiment with virtualization with the
-minimum of complexity.  Nonetheless, it should have sufficient
-features to make it useful for specific tasks, and, of course, you are
-encouraged to fork and enhance it (see drivers/lguest/README).
+Lguest is designed to be a minimal 32-bit x86 hypervisor for the Linux kernel,
+for Linux developers and users to experiment with virtualization with the
+minimum of complexity.  Nonetheless, it should have sufficient features to
+make it useful for specific tasks, and, of course, you are encouraged to fork
+and enhance it (see drivers/lguest/README).
 
 Features:
 
@@ -37,6 +37,7 @@ Running Lguest:
      "Paravirtualized guest support" = Y
         "Lguest guest support" = Y
      "High Memory Support" = off/4GB
+     "PAE (Physical Address Extension) Support" = N
      "Alignment value to which kernel should be aligned" = 0x100000
         (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and
          CONFIG_PHYSICAL_ALIGN=0x100000)
diff -druNp linux-libre-2.6.29-gnu1/Documentation/lockdep-design.txt linux-libre-2.6.30-gnu1/Documentation/lockdep-design.txt
--- linux-libre-2.6.29-gnu1/Documentation/lockdep-design.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/lockdep-design.txt	2009-06-09 23:05:27.000000000 -0400
@@ -27,33 +27,37 @@ lock-class.
 State
 -----
 
-The validator tracks lock-class usage history into 5 separate state bits:
+The validator tracks lock-class usage history into 4n + 1 separate state bits:
 
-- 'ever held in hardirq context'                    [ == hardirq-safe   ]
-- 'ever held in softirq context'                    [ == softirq-safe   ]
-- 'ever held with hardirqs enabled'                 [ == hardirq-unsafe ]
-- 'ever held with softirqs and hardirqs enabled'    [ == softirq-unsafe ]
+- 'ever held in STATE context'
+- 'ever head as readlock in STATE context'
+- 'ever head with STATE enabled'
+- 'ever head as readlock with STATE enabled'
+
+Where STATE can be either one of (kernel/lockdep_states.h)
+ - hardirq
+ - softirq
+ - reclaim_fs
 
 - 'ever used'                                       [ == !unused        ]
 
-When locking rules are violated, these 4 state bits are presented in the
-locking error messages, inside curlies.  A contrived example:
+When locking rules are violated, these state bits are presented in the
+locking error messages, inside curlies. A contrived example:
 
    modprobe/2287 is trying to acquire lock:
-    (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+    (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
 
    but task is already holding lock:
-    (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+    (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
 
 
-The bit position indicates hardirq, softirq, hardirq-read,
-softirq-read respectively, and the character displayed in each
-indicates:
+The bit position indicates STATE, STATE-read, for each of the states listed
+above, and the character displayed in each indicates:
 
-   '.'  acquired while irqs disabled
-   '+'  acquired in irq context
-   '-'  acquired with irqs enabled
-   '?' read acquired in irq context with irqs enabled.
+   '.'  acquired while irqs disabled and not in irq context
+   '-'  acquired in irq context
+   '+'  acquired with irqs enabled
+   '?'  acquired in irq context with irqs enabled.
 
 Unused mutexes cannot be part of the cause of an error.
 
Binary files linux-libre-2.6.29-gnu1/Documentation/logo.gif and linux-libre-2.6.30-gnu1/Documentation/logo.gif differ
diff -druNp linux-libre-2.6.29-gnu1/Documentation/logo.svg linux-libre-2.6.30-gnu1/Documentation/logo.svg
--- linux-libre-2.6.29-gnu1/Documentation/logo.svg	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/logo.svg	1969-12-31 19:00:00.000000000 -0500
@@ -1,2911 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="1771.6534"
-   height="1417.3228"
-   id="svg2"
-   sodipodi:version="0.32"
-   inkscape:version="0.46"
-   sodipodi:docname="tuz.svg"
-   inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   version="1.0"
-   style="display:inline;enable-background:new"
-   inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_final.png"
-   inkscape:export-xdpi="100.03588"
-   inkscape:export-ydpi="100.03588">
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     gridtolerance="10000"
-     guidetolerance="10"
-     objecttolerance="10"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="0.25"
-     inkscape:cx="-174.7931"
-     inkscape:cy="784.26325"
-     inkscape:document-units="px"
-     inkscape:current-layer="svg2"
-     showgrid="false"
-     inkscape:window-width="1280"
-     inkscape:window-height="823"
-     inkscape:window-x="-4"
-     inkscape:window-y="25"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     units="mm" />
-  <defs
-     id="defs4">
-    <filter
-       inkscape:collect="always"
-       x="-0.084654994"
-       width="1.16931"
-       y="-0.36592469"
-       height="1.7318494"
-       id="filter11361">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="4.5740586"
-         id="feGaussianBlur11363" />
-    </filter>
-    <inkscape:perspective
-       sodipodi:type="inkscape:persp3d"
-       inkscape:vp_x="0 : 564.0976 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_z="1445.8591 : 564.0976 : 1"
-       inkscape:persp3d-origin="722.92957 : 376.06506 : 1"
-       id="perspective8145" />
-    <linearGradient
-       id="linearGradient7622">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop7624" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop7626" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4113">
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="0"
-         id="stop4115" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop4117" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient3660">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3662" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop3664" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3627">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop3629" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop3631" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient2843">
-      <stop
-         id="stop2845"
-         offset="0"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0.02188784"
-         id="stop2847" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0.75866222"
-         id="stop2849" />
-      <stop
-         id="stop2851"
-         offset="0.88508981"
-         style="stop-color:#232323;stop-opacity:1;" />
-      <stop
-         id="stop2853"
-         offset="1"
-         style="stop-color:#595959;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient8964">
-      <stop
-         style="stop-color:#1a1a1a;stop-opacity:1;"
-         offset="0"
-         id="stop8966" />
-      <stop
-         style="stop-color:#1a1a1a;stop-opacity:0;"
-         offset="1"
-         id="stop8968" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient8952">
-      <stop
-         style="stop-color:#0a0c0c;stop-opacity:1;"
-         offset="0"
-         id="stop8954" />
-      <stop
-         style="stop-color:#1f2727;stop-opacity:0;"
-         offset="1"
-         id="stop8956" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient8430">
-      <stop
-         style="stop-color:#1e2323;stop-opacity:1;"
-         offset="0"
-         id="stop8432" />
-      <stop
-         id="stop8438"
-         offset="0.55992389"
-         style="stop-color:#181d1d;stop-opacity:1;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop8434" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient8398">
-      <stop
-         style="stop-color:#283131;stop-opacity:0;"
-         offset="0"
-         id="stop8400" />
-      <stop
-         id="stop8402"
-         offset="0.5125587"
-         style="stop-color:#1e2424;stop-opacity:0;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop8404" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4870">
-      <stop
-         style="stop-color:#c7bd80;stop-opacity:1;"
-         offset="0"
-         id="stop4872" />
-      <stop
-         style="stop-color:#c7bd80;stop-opacity:0;"
-         offset="1"
-         id="stop4874" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       id="linearGradient4862">
-      <stop
-         style="stop-color:#e2e2e2;stop-opacity:1;"
-         offset="0"
-         id="stop4864" />
-      <stop
-         style="stop-color:#e2e2e2;stop-opacity:0;"
-         offset="1"
-         id="stop4866" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4478">
-      <stop
-         style="stop-color:#f9eed3;stop-opacity:1;"
-         offset="0"
-         id="stop4480" />
-      <stop
-         style="stop-color:#000000;stop-opacity:0;"
-         offset="1"
-         id="stop4482" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4106">
-      <stop
-         style="stop-color:#d9e002;stop-opacity:1;"
-         offset="0"
-         id="stop4108" />
-      <stop
-         id="stop4114"
-         offset="0.5"
-         style="stop-color:#a9ae01;stop-opacity:1;" />
-      <stop
-         style="stop-color:#717501;stop-opacity:1;"
-         offset="1"
-         id="stop4110" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4084">
-      <stop
-         style="stop-color:#7d7d00;stop-opacity:1;"
-         offset="0"
-         id="stop4086" />
-      <stop
-         id="stop4088"
-         offset="0.3636601"
-         style="stop-color:#c6c700;stop-opacity:1;" />
-      <stop
-         style="stop-color:#f6f800;stop-opacity:1;"
-         offset="1"
-         id="stop4090" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4041">
-      <stop
-         id="stop4043"
-         offset="0"
-         style="stop-color:#ffff00;stop-opacity:1;" />
-      <stop
-         id="stop4045"
-         offset="1"
-         style="stop-color:#ffff00;stop-opacity:0;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4025">
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="0"
-         id="stop4027" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:0;"
-         offset="1"
-         id="stop4031" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient4013">
-      <stop
-         style="stop-color:#ffff00;stop-opacity:1;"
-         offset="0"
-         id="stop4015" />
-      <stop
-         style="stop-color:#b2b200;stop-opacity:1;"
-         offset="1"
-         id="stop4017" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3985">
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0"
-         id="stop3987" />
-      <stop
-         style="stop-color:#1d1d1d;stop-opacity:1;"
-         offset="1"
-         id="stop3989" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3961">
-      <stop
-         style="stop-color:#283131;stop-opacity:0;"
-         offset="0"
-         id="stop3963" />
-      <stop
-         id="stop3965"
-         offset="0.5"
-         style="stop-color:#1e2424;stop-opacity:1;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop3967" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3951">
-      <stop
-         id="stop3953"
-         offset="0"
-         style="stop-color:#344040;stop-opacity:1;" />
-      <stop
-         style="stop-color:#222929;stop-opacity:1;"
-         offset="0.5"
-         id="stop3955" />
-      <stop
-         id="stop3957"
-         offset="1"
-         style="stop-color:#000000;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3909">
-      <stop
-         style="stop-color:#283131;stop-opacity:1;"
-         offset="0"
-         id="stop3911" />
-      <stop
-         id="stop3917"
-         offset="0.5"
-         style="stop-color:#1e2424;stop-opacity:1;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="1"
-         id="stop3913" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3537">
-      <stop
-         style="stop-color:#ada469;stop-opacity:1;"
-         offset="0"
-         id="stop3539" />
-      <stop
-         id="stop3545"
-         offset="0.81132078"
-         style="stop-color:#ada469;stop-opacity:1;" />
-      <stop
-         style="stop-color:#ffffff;stop-opacity:1;"
-         offset="1"
-         id="stop3541" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3317">
-      <stop
-         style="stop-color:#cfc690;stop-opacity:1"
-         offset="0"
-         id="stop3319" />
-      <stop
-         id="stop3321"
-         offset="0.21161865"
-         style="stop-color:#afa775;stop-opacity:1;" />
-      <stop
-         id="stop3323"
-         offset="0.53408515"
-         style="stop-color:#615c3a;stop-opacity:1;" />
-      <stop
-         style="stop-color:#000000;stop-opacity:1;"
-         offset="0.76504093"
-         id="stop3325" />
-      <stop
-         id="stop3327"
-         offset="1"
-         style="stop-color:#403518;stop-opacity:1;" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3239">
-      <stop
-         id="stop3251"
-         offset="0"
-         style="stop-color:#cfc690;stop-opacity:1;" />
-      <stop
-         style="stop-color:#afa775;stop-opacity:1;"
-         offset="0.21161865"
-         id="stop3267" />
-      <stop
-         style="stop-color:#615c3a;stop-opacity:1;"
-         offset="0.53408515"
-         id="stop3261" />
-      <stop
-         id="stop3265"
-         offset="0.76504093"
-         style="stop-color:#000000;stop-opacity:1;" />
-      <stop
-         style="stop-color:#403518;stop-opacity:1;"
-         offset="1"
-         id="stop3243" />
-    </linearGradient>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3239"
-       id="radialGradient3281"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.5480423,1.7414304,-1.9683515,1.7497638,-1130.5586,-1872.5121)"
-       spreadMethod="pad"
-       cx="806.52582"
-       cy="212.68117"
-       fx="806.52582"
-       fy="212.68117"
-       r="48.363216" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3317"
-       id="radialGradient3315"
-       cx="543.6698"
-       cy="147.3131"
-       fx="543.6698"
-       fy="147.3131"
-       r="47.863216"
-       gradientTransform="matrix(2.1382256,0,0,2.3382884,-77.03847,-101.68704)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3537"
-       id="radialGradient3543"
-       cx="385"
-       cy="237.00504"
-       fx="385"
-       fy="237.00504"
-       r="86.928574"
-       gradientTransform="matrix(1,0,0,0.8562038,0,34.080427)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3909"
-       id="radialGradient3915"
-       cx="418.30365"
-       cy="342.47794"
-       fx="418.30365"
-       fy="342.47794"
-       r="131.4509"
-       gradientTransform="matrix(1.3957347,0.6211056,-0.4244067,0.9537174,-15.061913,-227.96711)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3951"
-       id="radialGradient3933"
-       cx="397.16388"
-       cy="336.95245"
-       fx="397.16388"
-       fy="336.95245"
-       r="36.75"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.9449972,2.4894837e-7,-2.4894833e-7,1.9449969,-375.31868,-318.41912)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3961"
-       id="linearGradient3959"
-       x1="398.21429"
-       y1="343.52289"
-       x2="379.28571"
-       y2="265.30862"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(450.03125,73.843964)" />
-    <filter
-       inkscape:collect="always"
-       id="filter3981"
-       x="-0.30000001"
-       width="1.6"
-       y="-0.30000001"
-       height="1.6">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="2"
-         id="feGaussianBlur3983" />
-    </filter>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3985"
-       id="radialGradient3991"
-       cx="402.48898"
-       cy="317.23578"
-       fx="402.48898"
-       fy="317.23578"
-       r="23.714285"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(4.3776616,0,0,4.3776616,-1358.3025,-1070.7357)" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3999">
-      <path
-         style="opacity:1;fill:#f5ff04;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
-         d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 339.75316,358.17469 330.35714,331.29075 C 320.9229,304.29747 295.38973,272.16627 263.92857,261.6479 C 232.8953,251.27258 198.91081,256.79953 179.64286,267.36218 z"
-         id="path4001"
-         sodipodi:nodetypes="czzczzzzc" />
-    </clipPath>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4013"
-       id="radialGradient4056"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
-       cx="228.81355"
-       cy="440.26971"
-       fx="228.81355"
-       fy="440.26971"
-       r="119.17509" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4041"
-       id="radialGradient4060"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(5.911206e-2,2.6869855,-0.7234268,1.5914947e-2,408.72779,-424.56452)"
-       cx="275.4422"
-       cy="335.34866"
-       fx="275.4422"
-       fy="335.34866"
-       r="36.75" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4025"
-       id="radialGradient4062"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(5.911206e-2,2.6869855,-0.7234268,1.5914947e-2,408.72779,-424.56452)"
-       cx="275.4422"
-       cy="335.34866"
-       fx="275.4422"
-       fy="335.34866"
-       r="36.75" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4084"
-       id="linearGradient4082"
-       gradientUnits="userSpaceOnUse"
-       x1="182.35046"
-       y1="256.11136"
-       x2="145.53348"
-       y2="542.20502" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath4100">
-      <path
-         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.9000755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-         d="M 265.93541,126.68393 L 247.1682,295.54701 L 421.27363,222.42633 L 483.22803,311.08516 L 541.11243,279.09486 L 503.57801,99.035183 L 265.93541,126.68393 z"
-         id="path4102"
-         sodipodi:nodetypes="ccccccc" />
-    </clipPath>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4106"
-       id="radialGradient4112"
-       cx="250.22678"
-       cy="475.09763"
-       fx="250.22678"
-       fy="475.09763"
-       r="95.98877"
-       gradientTransform="matrix(1.2259004,-0.7077739,0.1413989,0.2449102,322.22326,608.91815)"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4478"
-       id="linearGradient4484"
-       x1="412.08926"
-       y1="404.91574"
-       x2="417.375"
-       y2="401.82648"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4478"
-       id="linearGradient4486"
-       x1="411.91071"
-       y1="404.91577"
-       x2="417.375"
-       y2="401.82648"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4478"
-       id="linearGradient4488"
-       x1="411.91071"
-       y1="405.54077"
-       x2="417.375"
-       y2="401.82648"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4478"
-       id="linearGradient4490"
-       x1="412.08926"
-       y1="405.54077"
-       x2="417.375"
-       y2="401.82648"
-       gradientUnits="userSpaceOnUse" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4478"
-       id="linearGradient4492"
-       x1="411.73212"
-       y1="405.54077"
-       x2="417.375"
-       y2="401.82648"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4862"
-       id="radialGradient4868"
-       cx="429.56738"
-       cy="377.42877"
-       fx="429.56738"
-       fy="377.42877"
-       r="72.079735"
-       gradientTransform="matrix(1,0,0,0.618034,0,144.16496)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4870"
-       id="radialGradient4876"
-       cx="437.6991"
-       cy="391.21735"
-       fx="437.6991"
-       fy="391.21735"
-       r="36.611931"
-       gradientTransform="matrix(1,0,0,0.618034,0,149.43174)"
-       gradientUnits="userSpaceOnUse" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4013"
-       id="radialGradient3585"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
-       cx="228.81355"
-       cy="440.26971"
-       fx="228.81355"
-       fy="440.26971"
-       r="119.17509" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4084"
-       id="linearGradient3587"
-       gradientUnits="userSpaceOnUse"
-       x1="182.35046"
-       y1="256.11136"
-       x2="145.53348"
-       y2="542.20502" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3317"
-       id="radialGradient8410"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-753.99632,-302.76972)"
-       cx="317.78754"
-       cy="129.65378"
-       fx="317.78754"
-       fy="129.65378"
-       r="47.863216" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8398"
-       id="radialGradient8412"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-1144.2358,-272.29325)"
-       cx="325.30847"
-       cy="80.909554"
-       fx="325.30847"
-       fy="80.909554"
-       r="26.937988" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8514">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z"
-         id="path8516"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8604">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z"
-         id="path8606"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8610">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z"
-         id="path8612"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8616">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z"
-         id="path8618"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8622">
-      <path
-         style="opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 821.64329,477.88997 C 821.64329,477.88997 844.26276,471.38316 857.38604,472.01724 C 870.50932,472.65133 888.02762,473.95586 901.09489,484.20343 C 914.16216,494.45099 926.16263,511.3435 935.20728,542.57308 C 944.25193,573.80266 936.9056,641.82509 929.03125,685.92043 C 921.1569,730.01577 900.76615,792.03341 884.03125,825.92043 C 867.29635,859.80745 834.23354,903.41563 823.46182,915.79659 C 812.0976,928.85856 767.25593,952.22276 744.03125,958.06326 C 749.33455,947.45666 792.93101,907.47442 779.03125,897.349 C 765.01228,887.13674 733.27116,943.33136 694.7381,926.38217 C 716.12041,913.25005 736.5175,875.19611 728.77871,859.78772 C 720.93846,844.17733 698.07378,908.54529 635.24317,896.8006 C 665.29521,869.27394 690.65023,825.89659 676.50587,813.8209 C 662.09071,801.51403 616.04412,868.11405 616.04412,868.11405 C 616.04412,868.11405 613.22222,826.41287 629.81732,799.50673 C 646.45667,772.52886 709.47029,717.89146 729.37045,687.80331 C 749.2706,657.71517 762.98301,621.79429 771.50587,595.28537 C 780.02873,568.77645 787.30681,518.18583 787.30681,518.18583"
-         id="path8624"
-         sodipodi:nodetypes="czzzzzzczczczczzzc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8642">
-      <path
-         style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 366.88839,504.13471 C 366.88839,504.13471 337.33433,544.70776 319.03125,578.42042 C 300.72816,612.13309 260.41016,704.77736 248.67411,749.49185 C 236.91471,794.29529 186.17411,873.06329 186.17411,873.06329 L 262.24554,891.27757 C 262.24554,891.27757 274.05266,878.45422 293.31696,845.20614 C 312.58126,811.95806 353.67411,706.63471 353.67411,706.63471 L 366.88839,504.13471 z"
-         id="path8644"
-         sodipodi:nodetypes="czzcczcc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8658">
-      <path
-         style="opacity:1;fill:#0b0b0b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 569.03125,1018.7776 C 564.74554,1019.4919 541.4031,1022.3957 511.17411,1028.7776 C 480.94512,1035.1595 411.39918,1054.7395 368.31696,1064.4919 C 325.23474,1074.2443 251.05253,1099.3079 211.40434,1091.7573 C 171.75616,1084.2067 121.88839,1027.349 121.88839,1027.349 L 126.17411,933.06329 C 126.17411,933.06329 212.05962,916.86235 238.31696,899.49186 C 264.57431,882.12137 283.89934,849.82588 297.60268,828.06329 C 311.30602,806.3007 330.45982,756.63471 330.45982,756.63471 L 569.03125,1018.7776 z"
-         id="path8660"
-         sodipodi:nodetypes="czzzcczzcc" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8802"
-       x="-0.35311759"
-       width="1.7062352"
-       y="-0.1817714"
-       height="1.3635428">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="48.038491"
-         id="feGaussianBlur8804" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8806"
-       x="-0.61142862"
-       width="2.2228572"
-       y="-0.14930232"
-       height="1.2986046">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="37.830213"
-         id="feGaussianBlur8808" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8810"
-       x="-0.23519406"
-       width="1.4703881"
-       y="-0.24500646"
-       height="1.4900129">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="58.328041"
-         id="feGaussianBlur8812" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8814"
-       x="-0.20466694"
-       width="1.4093339"
-       y="-0.29007819"
-       height="1.5801564">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="22.300169"
-         id="feGaussianBlur8816" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8818"
-       x="-0.34381232"
-       width="1.6876246"
-       y="-0.18433961"
-       height="1.3686792">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="34.542167"
-         id="feGaussianBlur8820" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8822"
-       x="-0.2742857"
-       width="1.5485713"
-       y="-0.21333334"
-       height="1.4266667">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="11.313708"
-         id="feGaussianBlur8824" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8826"
-       x="-0.25894088"
-       width="1.5178818"
-       y="-0.2236412"
-       height="1.4472824">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="19.631544"
-         id="feGaussianBlur8828" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8856"
-       x="-0.3253231"
-       width="1.6506462"
-       y="-0.19013336"
-       height="1.3802667">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="28.712591"
-         id="feGaussianBlur8858" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8860"
-       x="-0.38093024"
-       width="1.7618605"
-       y="-0.17518716"
-       height="1.3503743">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="19.304015"
-         id="feGaussianBlur8862" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8888"
-       x="-0.2112188"
-       width="1.4224375"
-       y="-0.16808605"
-       height="1.3361721">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="8.3693583"
-         id="feGaussianBlur8890" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8892"
-       x="-0.18692794"
-       width="1.3738559"
-       y="-0.23646873"
-       height="1.4729375">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="31.21228"
-         id="feGaussianBlur8894" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8906">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z"
-         id="path8908"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8940"
-       x="-0.25152978"
-       width="1.5030596"
-       y="-0.053035267"
-       height="1.1060705">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="13.024603"
-         id="feGaussianBlur8942" />
-    </filter>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8952"
-       id="linearGradient8958"
-       x1="609.31244"
-       y1="239.46866"
-       x2="560.83142"
-       y2="262.86206"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(450.03125,73.843964)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8964"
-       id="linearGradient8970"
-       x1="603.84064"
-       y1="627.85303"
-       x2="616.24396"
-       y2="585.42664"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(450.03125,73.843964)" />
-    <filter
-       inkscape:collect="always"
-       id="filter9020"
-       x="-0.32861114"
-       width="1.6572223"
-       y="-0.182"
-       height="1.364">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="20.912684"
-         id="feGaussianBlur9022" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter9024"
-       x="-0.55453134"
-       width="2.1090627"
-       y="-0.51434779"
-       height="2.0286956">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="20.912684"
-         id="feGaussianBlur9026" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter9044"
-       x="-0.32631579"
-       width="1.6526316"
-       y="-0.84545463"
-       height="2.6909094">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="21.92031"
-         id="feGaussianBlur9046" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter9048"
-       x="-0.40879121"
-       width="1.8175824"
-       y="-0.71538466"
-       height="2.4307692">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="21.92031"
-         id="feGaussianBlur9050" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter3587"
-       x="-0.1">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="8.881432"
-         id="feGaussianBlur3589" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3602">
-      <path
-         sodipodi:nodetypes="czzzzzzczczczczzzc"
-         id="path3604"
-         d="M 647.61204,540.04601 C 647.61204,540.04601 670.23151,533.5392 683.35479,534.17328 C 696.47807,534.80737 713.99637,536.1119 727.06364,546.35947 C 740.13091,556.60703 752.13138,573.49954 761.17603,604.72912 C 770.22068,635.9587 762.87435,703.98113 755,748.07647 C 747.12565,792.17181 726.7349,854.18945 710,888.07647 C 693.2651,921.96349 660.20229,965.57167 649.43057,977.95263 C 638.06635,991.0146 593.22468,1014.3788 570,1020.2193 C 575.3033,1009.6127 618.89976,969.63046 605,959.50504 C 590.98103,949.29278 559.23991,1005.4874 520.70685,988.53821 C 542.08916,975.40609 562.48625,937.35215 554.74746,921.94376 C 546.90721,906.33337 524.04253,970.70133 461.21192,958.95664 C 491.26396,931.42998 516.61898,888.05263 502.47462,875.97694 C 488.05946,863.67007 442.01287,930.27009 442.01287,930.27009 C 442.01287,930.27009 439.19097,888.56891 455.78607,861.66277 C 472.42542,834.6849 535.43904,780.0475 555.3392,749.95935 C 575.23935,719.87121 588.95176,683.95033 597.47462,657.44141 C 605.99748,630.93249 613.27556,580.34187 613.27556,580.34187"
-         style="opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter4120"
-       x="-0.2770822"
-       width="1.5541644"
-       y="-0.32482043"
-       height="1.6496409">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="19.956289"
-         id="feGaussianBlur4122" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3631">
-      <path
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z"
-         id="path3633"
-         sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3665">
-      <path
-         sodipodi:nodetypes="czzcczcc"
-         id="path3667"
-         d="M 366.88839,504.13471 C 366.88839,504.13471 337.33433,544.70776 319.03125,578.42042 C 300.72816,612.13309 260.41016,704.77736 248.67411,749.49185 C 236.91471,794.29529 186.17411,873.06329 186.17411,873.06329 L 262.24554,891.27757 C 262.24554,891.27757 274.05266,878.45422 293.31696,845.20614 C 312.58126,811.95806 353.67411,706.63471 353.67411,706.63471 L 366.88839,504.13471 z"
-         style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3677">
-      <path
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 586.13271,997.98981 C 592.92681,1016.8926 596.6264,1031.2895 598.02301,1049.2017 C 599.41963,1067.114 594.24033,1101.0025 595.12255,1119.8578 C 596.0043,1138.703 603.25624,1159.9568 622.46718,1168.8267 C 641.88605,1177.7925 671.78642,1179.038 696.58702,1165.6811 C 721.38762,1152.3241 753.98804,1095.3556 767.56128,1068.3724 C 781.18513,1041.2885 806.32235,953.87507 812.22208,918.60385 C 818.12181,883.33264 814.77262,877.30308 807.6046,869.54836 C 810.2449,841.70821 806.10488,814.61293 820.71429,782.36218 C 790.46528,794.18788 783.332,822.52288 772.3954,847.86726 C 764.39449,796.93433 772.60456,776.59407 775.71429,746.6479 C 746.64953,761.42581 732.85278,793.76192 730.71429,839.50504 C 719.79034,838.20084 709.32285,835.07081 697.14286,838.79075 C 696.87882,792.76741 695.6793,761.90134 706.05349,724.58426 C 652.79802,745.61112 643.10621,831.17836 650,837.36218 C 639.11718,837.89718 628.62892,836.06488 617.14286,840.21933 C 617.78178,797.64798 616.8824,755.31072 587.14286,717.36218 C 587.14286,717.36218 556.1848,798.28452 555.71429,820.93361 C 555.24378,843.5827 565.16588,861.09949 565.16588,861.09949 C 565.16588,861.09949 556.59781,897.84 558.86729,919.33172 C 561.16314,941.07318 579.31019,979.00789 586.13271,997.98981 z"
-         id="path3679"
-         sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter3898">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="10.892985"
-         id="feGaussianBlur3900" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4130"
-       x="-0.49509686"
-       width="1.9901937"
-       y="-0.26708817"
-       height="1.5341763">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="10.730622"
-         id="feGaussianBlur4132" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4141"
-       x="-0.40611032"
-       width="1.8122206"
-       y="-0.30260596"
-       height="1.6052119">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="9.8586086"
-         id="feGaussianBlur4143" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath4177">
-      <path
-         sodipodi:nodetypes="czzzzzzcccccccccczczz"
-         id="path4179"
-         d="M 586.13271,997.98981 C 592.92681,1016.8926 596.6264,1031.2895 598.02301,1049.2017 C 599.41963,1067.114 594.24033,1101.0025 595.12255,1119.8578 C 596.0043,1138.703 603.25624,1159.9568 622.46718,1168.8267 C 641.88605,1177.7925 671.78642,1179.038 696.58702,1165.6811 C 721.38762,1152.3241 753.98804,1095.3556 767.56128,1068.3724 C 781.18513,1041.2885 806.32235,953.87507 812.22208,918.60385 C 818.12181,883.33264 814.77262,877.30308 807.6046,869.54836 C 810.2449,841.70821 806.10488,814.61293 820.71429,782.36218 C 790.46528,794.18788 783.332,822.52288 772.3954,847.86726 C 764.39449,796.93433 772.60456,776.59407 775.71429,746.6479 C 746.64953,761.42581 732.85278,793.76192 730.71429,839.50504 C 719.79034,838.20084 709.32285,835.07081 697.14286,838.79075 C 696.87882,792.76741 695.6793,761.90134 706.05349,724.58426 C 652.79802,745.61112 643.10621,831.17836 650,837.36218 C 639.11718,837.89718 628.62892,836.06488 617.14286,840.21933 C 617.78178,797.64798 616.8824,755.31072 587.14286,717.36218 C 587.14286,717.36218 556.1848,798.28452 555.71429,820.93361 C 555.24378,843.5827 565.16588,861.09949 565.16588,861.09949 C 565.16588,861.09949 556.59781,897.84 558.86729,919.33172 C 561.16314,941.07318 579.31019,979.00789 586.13271,997.98981 z"
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter4185">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="3.6164709"
-         id="feGaussianBlur4187" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4105">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="3.8640966"
-         id="feGaussianBlur4107" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath2833">
-      <path
-         style="opacity:1;fill:#292929;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 569.03125,1018.7776 C 564.74554,1019.4919 541.4031,1022.3957 511.17411,1028.7776 C 480.94512,1035.1595 453.86016,1033.7437 375.38803,1046.1072 C 295.53625,1058.688 281.32367,1088.6495 267.26578,1093.1715 C 252.56564,1097.9001 121.88839,1027.349 121.88839,1027.349 L 126.17411,933.06329 C 126.17411,933.06329 212.05962,916.86235 238.31696,899.49186 C 264.57431,882.12137 283.89934,849.82588 297.60268,828.06329 C 311.30602,806.3007 330.45982,756.63471 330.45982,756.63471 L 569.03125,1018.7776 z"
-         id="path2835"
-         sodipodi:nodetypes="czzzcczzcc" />
-    </clipPath>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient2843"
-       id="linearGradient2841"
-       gradientUnits="userSpaceOnUse"
-       x1="347.89655"
-       y1="1070.2124"
-       x2="275.58191"
-       y2="867.97992" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3627"
-       id="linearGradient3688"
-       gradientUnits="userSpaceOnUse"
-       x1="699.32867"
-       y1="269.76755"
-       x2="698.97504"
-       y2="346.1351" />
-    <mask
-       maskUnits="userSpaceOnUse"
-       id="mask3684">
-      <path
-         sodipodi:type="arc"
-         style="opacity:1;fill:url(#linearGradient3688);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.43724918px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         id="path3686"
-         sodipodi:cx="579.474"
-         sodipodi:cy="260.57516"
-         sodipodi:rx="192.6866"
-         sodipodi:ry="164.04877"
-         d="M 772.1606,260.57516 A 192.6866,164.04877 0 1 1 386.7874,260.57516 A 192.6866,164.04877 0 1 1 772.1606,260.57516 z"
-         transform="translate(-174.03125,62.156036)" />
-    </mask>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3622">
-      <path
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 266.27183,924.57186 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87514 C 271.58022,990.42748 284.75965,1019.7825 288.68797,1037.0589 C 292.61419,1054.326 291.3821,1075.3685 276.22853,1088.2071 C 260.91092,1101.1845 234.17726,1109.806 208.39623,1103.9409 C 182.61517,1098.0756 138.84716,1054.7175 119.80604,1033.7126 C 100.6939,1012.6293 56.045183,939.86194 41.867508,909.43681 C 27.689836,879.01169 29.207903,872.71824 33.747793,863.90708 C 24.381071,839.38658 21.334081,813.84027 0.035335518,788.33044 C 30.360815,791.44488 43.915625,815.28677 60.161025,835.47019 C 54.631129,787.39416 42.10631,771.05369 31.787073,744.74589 C 61.781368,750.82755 82.366433,776.61829 95.766856,817.45839 C 105.32101,813.54048 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.00481,738.48135 89.267015,707.32725 C 142.70898,712.99758 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.42601,751.28936 177.62716,712.76848 195.01526,670.9882 C 195.01526,670.9882 243.30204,736.42507 249.40492,756.79397 C 255.50779,777.16288 250.92373,795.49449 250.92373,795.49449 C 250.92373,795.49449 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82997 267.68496,905.69194 266.27183,924.57186 z"
-         id="path3624"
-         sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3636">
-      <path
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z"
-         id="path3638"
-         sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    </clipPath>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3660"
-       id="linearGradient3666"
-       x1="1255.7386"
-       y1="667.09216"
-       x2="893.69995"
-       y2="858.01099"
-       gradientUnits="userSpaceOnUse" />
-    <filter
-       inkscape:collect="always"
-       id="filter3779"
-       x="-0.087980822"
-       width="1.1759616"
-       y="-0.17728332"
-       height="1.3545666">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="16.340344"
-         id="feGaussianBlur3781" />
-    </filter>
-    <filter
-       id="filter3785"
-       inkscape:label="White Fur">
-      <feTurbulence
-         id="feTurbulence3787"
-         in="SourceAlpha"
-         type="fractalNoise"
-         baseFrequency="0.24044943820224721"
-         numOctaves="10"
-         seed="655"
-         result="result0" />
-      <feDisplacementMap
-         id="feDisplacementMap3789"
-         in="SourceGraphic"
-         in2="result0"
-         scale="62"
-         xChannelSelector="B"
-         yChannelSelector="G" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter3677">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="2.0397518"
-         id="feGaussianBlur3679" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3722">
-      <path
-         style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z"
-         id="path3724"
-         sodipodi:nodetypes="czzzzzzzzcc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3986">
-      <path
-         style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z"
-         id="path3988"
-         sodipodi:nodetypes="czzzzzzzzcc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3992">
-      <path
-         style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z"
-         id="path3994"
-         sodipodi:nodetypes="czzzzzzzzcc" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath3998">
-      <path
-         style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         d="M 178.21428,274.14789 C 174.40985,248.88366 161.40456,223.50987 161.05748,198.62266 C 160.87122,185.26714 164.33033,172.05175 174.81301,159.06861 C 211.16003,93.772775 291.75392,74.373925 360.74767,67.603183 C 447.67006,56.586382 545.66034,85.543255 594.11901,163.00447 C 648.24303,238.73777 650.79377,335.54359 674.73105,422.53242 C 704.16884,549.66002 729.51019,678.74656 735.12329,809.38277 C 732.05981,887.56462 726.69695,974.56692 674.62008,1037.5169 C 626.59354,1087.8743 551.83361,1087.5699 487.5502,1096.5192 C 396.99481,1101.1742 303.19867,1080.3734 225.7663,1032.321 C 160.99066,994.38099 130.03611,918.84237 128.4869,846.30142 C 120.09773,766.42626 154.87842,692.49291 180.1073,619.14181 C 187.57791,536.38074 189.52016,452.89406 189.76064,369.75697 C 188.92382,337.56153 182.67111,305.93964 178.21428,274.14789 z"
-         id="path4000"
-         sodipodi:nodetypes="cscccccccccccc" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter4002"
-       x="-0.24334238"
-       width="1.4866848"
-       y="-0.39104807"
-       height="1.7820961">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="14.589518"
-         id="feGaussianBlur4004" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4010"
-       x="-0.14577261"
-       width="1.2915452"
-       y="-0.23523259"
-       height="1.4704652">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="4.4442907"
-         id="feGaussianBlur4012" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4053">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.6062947"
-         id="feGaussianBlur4055" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4079">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="6.5887624"
-         id="feGaussianBlur4081" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter4083">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.5052066"
-         id="feGaussianBlur4085" />
-    </filter>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient4113"
-       id="radialGradient4119"
-       cx="296.33783"
-       cy="427.17749"
-       fx="296.33783"
-       fy="427.17749"
-       r="19.704132"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.9797125,0,0,2.9797125,-599.28727,-827.0855)" />
-    <filter
-       inkscape:collect="always"
-       id="filter6949"
-       x="-0.10294895"
-       width="1.2058979"
-       y="-0.34224695"
-       height="1.6844939">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6951" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6953"
-       x="-0.098320946"
-       width="1.1966419"
-       y="-0.19750816"
-       height="1.3950163">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6955" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6957"
-       x="-0.098213427"
-       width="1.1964267"
-       y="-0.19838208"
-       height="1.3967642">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6959" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6961"
-       x="-0.09919104"
-       width="1.1983821"
-       y="-0.22643611"
-       height="1.4528722">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6963" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6965"
-       x="-0.099081434"
-       width="1.1981629"
-       y="-0.22529824"
-       height="1.4505965">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6967" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6969"
-       x="-0.10450897"
-       width="1.2090179"
-       y="-0.40468886"
-       height="1.8093777">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6971" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6973"
-       x="-0.10330495"
-       width="1.2066098"
-       y="-0.36439717"
-       height="1.7287945">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6975" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6977"
-       x="-0.10224481"
-       width="1.2044896"
-       y="-0.32371372"
-       height="1.6474274">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6979" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6981"
-       x="-0.10052545"
-       width="1.2010509"
-       y="-0.2742162"
-       height="1.5484324">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6983" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6985"
-       x="-0.098428868"
-       width="1.1968577"
-       y="-0.20853186"
-       height="1.4170637">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6987" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6989"
-       x="-0.098428868"
-       width="1.1968577"
-       y="-0.20287035"
-       height="1.4057407">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6991" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6993"
-       x="-0.098213255"
-       width="1.1964265"
-       y="-0.19838208"
-       height="1.3967642">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6995" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter6997">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur6999" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7001">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.1675612"
-         id="feGaussianBlur7003" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7285"
-       x="-0.030884685"
-       width="1.0617694"
-       y="-0.10267408"
-       height="1.2053483">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7287" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7289">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7291" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7293">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7295" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7297">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7299" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7301">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7303" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7305">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7307" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7309">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7311" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7313">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7315" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7317">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7319" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7321">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7323" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7325"
-       x="-0.031352691"
-       width="1.0627054"
-       y="-0.12140666"
-       height="1.2428133">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7327" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7329"
-       x="-0.030991485"
-       width="1.061983"
-       y="-0.10931916"
-       height="1.2186383">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7331" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7333">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7335" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7337">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.35026836"
-         id="feGaussianBlur7339" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7345">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.7233839"
-         id="feGaussianBlur7347" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath7421">
-      <path
-         sodipodi:type="inkscape:offset"
-         inkscape:radius="0"
-         inkscape:original="M 1111.4062 -285.9375 L 1107.4688 -284.0625 C 1107.4283 -284.05228 1107.3692 -284.04201 1107.3438 -284.03125 C 1106.925 -283.8184 1107.1791 -283.93067 1106.6875 -283.71875 C 1106.2014 -283.50919 1104.9499 -283.13456 1102.5938 -282.25 C 1099.2626 -280.99942 1096.7895 -280.10016 1095.5938 -279.1875 C 1094.0576 -279.16623 1091.8733 -278.95419 1089.9375 -278.46875 C 1086.956 -277.72108 1085.0823 -277.29474 1083.1875 -276.875 C 1081.2927 -276.45527 1081.512 -276.23281 1080.3125 -276 C 1079.0159 -275.74833 1078.5911 -276.00899 1074.875 -275.21875 C 1071.3851 -274.4766 1065.9802 -273.28768 1064.7188 -272.53125 C 1063.1348 -272.71203 1060.8513 -272.85303 1058.875 -272.5625 C 1055.8346 -272.11554 1053.9588 -271.88974 1052.0312 -271.65625 C 1051.3758 -271.57687 1050.9902 -271.45547 1050.6875 -271.375 C 1050.2613 -271.24334 1050.0017 -271.11498 1049.3125 -271.03125 C 1048.0009 -270.87188 1047.5503 -271.18808 1043.7812 -270.75 C 1040.2273 -270.33691 1034.7758 -269.47718 1033.5312 -268.8125 C 1031.9322 -269.10979 1029.6735 -269.34669 1027.6875 -269.15625 C 1024.6287 -268.86293 1022.7155 -268.67226 1020.7812 -268.5 C 1018.847 -268.32773 1019.0926 -268.07763 1017.875 -267.96875 C 1016.5588 -267.85105 1016.1152 -268.13238 1012.3438 -267.71875 C 1008.8017 -267.3303 1003.3359 -266.50948 1002.0625 -265.84375 C 1000.4636 -266.13844 998.1753 -266.35076 996.1875 -266.15625 C 993.12921 -265.857 991.2463 -265.67601 989.3125 -265.5 C 988.65501 -265.44015 988.27245 -265.32144 987.96875 -265.25 C 987.54105 -265.13104 987.28525 -265.03193 986.59375 -264.96875 C 985.27775 -264.84849 984.834 -265.16363 981.0625 -264.75 C 977.50631 -264.35998 972.0569 -263.51084 970.8125 -262.84375 C 969.21381 -263.13793 966.95265 -263.36747 964.96875 -263.15625 C 961.91305 -262.83092 959.9947 -262.63001 958.0625 -262.4375 C 956.13031 -262.24499 956.37275 -261.99662 955.15625 -261.875 C 953.84137 -261.74353 953.3932 -262.03954 949.625 -261.59375 C 946.08611 -261.17509 940.6473 -260.30158 939.375 -259.625 C 937.77741 -259.90604 935.51505 -260.04543 933.53125 -259.8125 C 930.47927 -259.45413 928.58625 -259.24464 926.65625 -259.03125 C 926.00007 -258.95869 925.6156 -258.85856 925.3125 -258.78125 C 924.88571 -258.65402 924.6276 -258.51405 923.9375 -258.4375 C 922.62411 -258.29181 922.17015 -258.61152 918.40625 -258.125 C 914.85737 -257.66624 909.4276 -256.70598 908.1875 -256 C 906.59441 -256.24424 904.3537 -256.38135 902.375 -256.125 C 899.32741 -255.73018 897.4243 -255.47655 895.5 -255.21875 C 893.57571 -254.96096 893.7739 -254.72522 892.5625 -254.5625 C 891.25301 -254.3866 890.8153 -254.66688 887.0625 -254.09375 C 883.53821 -253.55551 878.1393 -252.39458 876.875 -251.65625 C 875.28751 -251.85979 873.0295 -251.91098 871.0625 -251.5625 C 868.03631 -251.02638 866.1636 -250.70081 864.25 -250.375 C 863.59941 -250.26423 863.2363 -250.10406 862.9375 -250 C 862.51681 -249.83512 862.27405 -249.6687 861.59375 -249.53125 C 860.29905 -249.26966 859.86665 -249.53745 856.15625 -248.71875 C 852.65777 -247.9468 847.31035 -246.33582 846.09375 -245.5 C 844.53085 -245.57745 842.33625 -245.41472 840.40625 -244.90625 C 837.43387 -244.12312 835.58855 -243.67416 833.71875 -243.15625 C 831.84875 -242.63835 832.0521 -242.38897 830.875 -242.0625 C 829.60251 -241.7096 829.17795 -241.95541 825.53125 -240.875 C 822.10657 -239.86037 816.88185 -237.94183 815.65625 -237.03125 C 814.11747 -237.01851 811.93645 -236.75903 810.03125 -236.15625 C 807.10027 -235.22891 805.2809 -234.69783 803.4375 -234.09375 C 802.81071 -233.88837 802.44585 -233.70117 802.15625 -233.5625 C 801.74867 -233.34889 801.50295 -233.15375 800.84375 -232.9375 C 799.58925 -232.52596 799.1576 -232.74846 795.5625 -231.5 C 792.17261 -230.32283 786.96755 -228.2863 785.78125 -227.34375 C 784.25737 -227.28408 782.1312 -226.94888 780.25 -226.28125 C 777.35261 -225.25296 775.55095 -224.60577 773.71875 -223.96875 C 771.88655 -223.33174 772.0909 -223.12021 770.9375 -222.71875 C 769.69071 -222.28479 769.27395 -222.51903 765.71875 -221.15625 C 762.38005 -219.87645 757.23165 -217.6737 756.03125 -216.6875 C 754.52407 -216.57981 752.39555 -216.1887 750.53125 -215.46875 C 747.66307 -214.36115 745.90735 -213.68719 744.09375 -213 C 743.47705 -212.76637 743.0973 -212.55797 742.8125 -212.40625 C 742.81251 -212.40625 742.8125 -212.37673 742.8125 -212.375 L 734.8125 -209.1875 L 736.625 -194.46875 C 736.36701 -194.52956 742.8125 -191.15625 742.8125 -191.15625 C 743.03891 -191.30093 743.26145 -191.42886 743.53125 -191.53125 C 744.61177 -191.94123 745.70285 -191.74702 749.53125 -193.21875 C 753.35977 -194.69049 754.7553 -195.22373 755.4375 -195.625 C 756.11711 -196.02478 757.04925 -196.50437 757.65625 -197.15625 C 759.48317 -197.294 761.22705 -197.64948 762.59375 -198.15625 C 765.56175 -199.25677 767.4691 -199.96244 769.375 -200.625 C 771.28081 -201.28754 771.72915 -202.03987 772.78125 -202.40625 C 773.87287 -202.78636 774.97635 -202.57163 778.84375 -203.9375 C 782.71115 -205.30336 784.1269 -205.76458 784.8125 -206.15625 C 785.51361 -206.55677 786.5133 -207.08923 787.125 -207.75 C 789.09581 -207.80466 790.94195 -208.13463 792.40625 -208.625 C 795.40777 -209.63008 797.3324 -210.24671 799.25 -210.875 C 800.78861 -211.3791 801.42415 -211.92177 802.15625 -212.3125 C 802.38647 -212.44681 802.63215 -212.56623 802.90625 -212.65625 C 804.00457 -213.01673 805.0877 -212.73762 809 -213.96875 C 812.91231 -215.19988 814.366 -215.6417 815.0625 -216 C 815.75641 -216.35697 816.6926 -216.79261 817.3125 -217.40625 C 819.17771 -217.42891 820.94835 -217.67308 822.34375 -218.09375 C 825.37415 -219.00729 827.33615 -219.52385 829.28125 -220.0625 C 831.22637 -220.60114 831.70745 -221.32702 832.78125 -221.625 C 833.89527 -221.93415 835.00125 -221.61761 838.96875 -222.65625 C 842.93625 -223.69488 844.38625 -224.08898 845.09375 -224.40625 C 845.82855 -224.73584 846.90765 -225.15997 847.53125 -225.78125 C 849.52907 -225.66525 851.3887 -225.80134 852.875 -226.15625 C 855.95311 -226.89125 857.9584 -227.25719 859.9375 -227.65625 C 861.52541 -227.97643 862.1818 -228.4468 862.9375 -228.75 C 863.17501 -228.8568 863.4044 -228.94276 863.6875 -229 C 864.82091 -229.22919 865.99215 -228.79107 870.03125 -229.5 C 874.07067 -230.20893 875.5315 -230.42709 876.25 -230.6875 C 876.96581 -230.94694 877.95435 -231.25474 878.59375 -231.78125 C 880.51795 -231.54176 882.34165 -231.55672 883.78125 -231.78125 C 886.90767 -232.26887 888.9358 -232.48192 890.9375 -232.75 C 892.93921 -233.01807 893.42625 -233.69514 894.53125 -233.84375 C 895.67767 -233.99793 896.8071 -233.54218 900.875 -234.0625 C 904.94281 -234.58282 906.43525 -234.75823 907.15625 -235 C 907.89337 -235.24714 908.95435 -235.58623 909.59375 -236.125 C 911.64375 -235.78947 913.56745 -235.72704 915.09375 -235.90625 C 918.23595 -236.27521 920.27375 -236.46561 922.28125 -236.6875 C 923.89207 -236.86552 924.5459 -237.2957 925.3125 -237.53125 C 925.55341 -237.61677 925.80655 -237.68685 926.09375 -237.71875 C 927.24345 -237.84647 928.39505 -237.3721 932.46875 -237.84375 C 936.54245 -238.3154 938.0278 -238.45435 938.75 -238.6875 C 939.46941 -238.91977 940.45025 -239.16096 941.09375 -239.65625 C 943.03005 -239.32279 944.8638 -239.25201 946.3125 -239.40625 C 949.45851 -239.7412 951.49 -239.92484 953.5 -240.125 C 955.50991 -240.32514 955.98415 -240.95139 957.09375 -241.0625 C 958.24485 -241.17778 959.39025 -240.69744 963.46875 -241.125 C 967.54725 -241.55256 969.05765 -241.68709 969.78125 -241.90625 C 970.52047 -242.13011 971.57685 -242.4195 972.21875 -242.9375 C 974.27575 -242.53883 976.2206 -242.4441 977.75 -242.59375 C 980.89871 -242.90185 982.9258 -243.067 984.9375 -243.25 C 986.55151 -243.39682 987.20055 -243.81055 987.96875 -244.03125 C 988.21005 -244.11211 988.4623 -244.16116 988.75 -244.1875 C 989.90211 -244.29295 991.0429 -243.79475 995.125 -244.1875 C 999.20711 -244.58025 1000.7139 -244.71834 1001.4375 -244.9375 C 1002.1584 -245.15583 1003.1371 -245.3852 1003.7812 -245.875 C 1005.7193 -245.52501 1007.5501 -245.42062 1009 -245.5625 C 1012.1487 -245.8706 1014.1758 -246.03575 1016.1875 -246.21875 C 1018.1991 -246.40174 1018.7017 -247.05677 1019.8125 -247.15625 C 1020.9648 -247.25948 1022.1047 -246.77142 1026.1875 -247.15625 C 1030.2704 -247.54107 1031.7762 -247.65725 1032.5 -247.875 C 1033.2393 -248.09743 1034.2956 -248.38949 1034.9375 -248.90625 C 1036.9949 -248.50448 1038.9404 -248.40292 1040.4688 -248.5625 C 1043.6153 -248.89102 1045.6458 -249.0852 1047.6562 -249.28125 C 1049.2692 -249.43854 1049.9219 -249.91273 1050.6875 -250.15625 C 1050.9282 -250.24429 1051.1507 -250.27762 1051.4375 -250.3125 C 1052.5858 -250.4522 1053.7542 -249.97259 1057.8125 -250.5625 C 1061.8708 -251.15242 1063.3743 -251.33964 1064.0938 -251.59375 C 1064.8104 -251.84691 1065.7684 -252.15182 1066.4062 -252.6875 C 1068.3259 -252.47556 1070.1262 -252.53609 1071.5625 -252.78125 C 1074.6816 -253.31365 1076.6741 -253.70986 1078.6562 -254.09375 C 1080.6383 -254.47762 1081.1305 -255.1334 1082.2188 -255.375 C 1083.3475 -255.62566 1084.489 -255.25871 1088.4688 -256.25 C 1092.4483 -257.24127 1093.8983 -257.6693 1094.5938 -258.03125 C 1095.316 -258.40725 1096.3555 -258.90183 1096.9688 -259.5625 C 1098.9317 -259.57454 1100.7625 -259.85355 1102.1875 -260.40625 C 1105.1387 -261.55085 1107.0607 -262.27567 1108.875 -263.15625 C 1110.3307 -263.86277 1111.1941 -264.85828 1111.4062 -265.15625 C 1111.6185 -265.4542 1111.5051 -265.8848 1111.5312 -265.90625 C 1111.5742 -265.94148 1111.8716 -266.00028 1112.0312 -266.34375 C 1112.8902 -268.19082 1114.3544 -271.97139 1114.4688 -272.65625 C 1114.5825 -273.33839 1114.6368 -274.00902 1114.6875 -274.40625 C 1114.7169 -274.63575 1114.5404 -275.28515 1114.5625 -275.34375 C 1114.5934 -275.42579 1114.8508 -275.59432 1114.9062 -275.84375 C 1115.1725 -277.04206 1114.9953 -278.05111 1114.7812 -279.46875 C 1114.5673 -280.88638 1113.8096 -284.08338 1113.1562 -284.9375 C 1112.4973 -285.79922 1111.9314 -285.94801 1111.4062 -285.9375 z "
-         style="fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         id="path7423"
-         d="M 1111.4062,-285.9375 L 1107.4688,-284.0625 C 1107.4283,-284.05228 1107.3692,-284.04201 1107.3438,-284.03125 C 1106.925,-283.8184 1107.1791,-283.93067 1106.6875,-283.71875 C 1106.2014,-283.50919 1104.9499,-283.13456 1102.5938,-282.25 C 1099.2626,-280.99942 1096.7895,-280.10016 1095.5938,-279.1875 C 1094.0576,-279.16623 1091.8733,-278.95419 1089.9375,-278.46875 C 1086.956,-277.72108 1085.0823,-277.29474 1083.1875,-276.875 C 1081.2927,-276.45527 1081.512,-276.23281 1080.3125,-276 C 1079.0159,-275.74833 1078.5911,-276.00899 1074.875,-275.21875 C 1071.3851,-274.4766 1065.9802,-273.28768 1064.7188,-272.53125 C 1063.1348,-272.71203 1060.8513,-272.85303 1058.875,-272.5625 C 1055.8346,-272.11554 1053.9588,-271.88974 1052.0312,-271.65625 C 1051.3758,-271.57687 1050.9902,-271.45547 1050.6875,-271.375 C 1050.2613,-271.24334 1050.0017,-271.11498 1049.3125,-271.03125 C 1048.0009,-270.87188 1047.5503,-271.18808 1043.7812,-270.75 C 1040.2273,-270.33691 1034.7758,-269.47718 1033.5312,-268.8125 C 1031.9322,-269.10979 1029.6735,-269.34669 1027.6875,-269.15625 C 1024.6287,-268.86293 1022.7155,-268.67226 1020.7812,-268.5 C 1018.847,-268.32773 1019.0926,-268.07763 1017.875,-267.96875 C 1016.5588,-267.85105 1016.1152,-268.13238 1012.3438,-267.71875 C 1008.8017,-267.3303 1003.3359,-266.50948 1002.0625,-265.84375 C 1000.4636,-266.13844 998.1753,-266.35076 996.1875,-266.15625 C 993.12921,-265.857 991.2463,-265.67601 989.3125,-265.5 C 988.65501,-265.44015 988.27245,-265.32144 987.96875,-265.25 C 987.54105,-265.13104 987.28525,-265.03193 986.59375,-264.96875 C 985.27775,-264.84849 984.834,-265.16363 981.0625,-264.75 C 977.50631,-264.35998 972.0569,-263.51084 970.8125,-262.84375 C 969.21381,-263.13793 966.95265,-263.36747 964.96875,-263.15625 C 961.91305,-262.83092 959.9947,-262.63001 958.0625,-262.4375 C 956.13031,-262.24499 956.37275,-261.99662 955.15625,-261.875 C 953.84137,-261.74353 953.3932,-262.03954 949.625,-261.59375 C 946.08611,-261.17509 940.6473,-260.30158 939.375,-259.625 C 937.77741,-259.90604 935.51505,-260.04543 933.53125,-259.8125 C 930.47927,-259.45413 928.58625,-259.24464 926.65625,-259.03125 C 926.00007,-258.95869 925.6156,-258.85856 925.3125,-258.78125 C 924.88571,-258.65402 924.6276,-258.51405 923.9375,-258.4375 C 922.62411,-258.29181 922.17015,-258.61152 918.40625,-258.125 C 914.85737,-257.66624 909.4276,-256.70598 908.1875,-256 C 906.59441,-256.24424 904.3537,-256.38135 902.375,-256.125 C 899.32741,-255.73018 897.4243,-255.47655 895.5,-255.21875 C 893.57571,-254.96096 893.7739,-254.72522 892.5625,-254.5625 C 891.25301,-254.3866 890.8153,-254.66688 887.0625,-254.09375 C 883.53821,-253.55551 878.1393,-252.39458 876.875,-251.65625 C 875.28751,-251.85979 873.0295,-251.91098 871.0625,-251.5625 C 868.03631,-251.02638 866.1636,-250.70081 864.25,-250.375 C 863.59941,-250.26423 863.2363,-250.10406 862.9375,-250 C 862.51681,-249.83512 862.27405,-249.6687 861.59375,-249.53125 C 860.29905,-249.26966 859.86665,-249.53745 856.15625,-248.71875 C 852.65777,-247.9468 847.31035,-246.33582 846.09375,-245.5 C 844.53085,-245.57745 842.33625,-245.41472 840.40625,-244.90625 C 837.43387,-244.12312 835.58855,-243.67416 833.71875,-243.15625 C 831.84875,-242.63835 832.0521,-242.38897 830.875,-242.0625 C 829.60251,-241.7096 829.17795,-241.95541 825.53125,-240.875 C 822.10657,-239.86037 816.88185,-237.94183 815.65625,-237.03125 C 814.11747,-237.01851 811.93645,-236.75903 810.03125,-236.15625 C 807.10027,-235.22891 805.2809,-234.69783 803.4375,-234.09375 C 802.81071,-233.88837 802.44585,-233.70117 802.15625,-233.5625 C 801.74867,-233.34889 801.50295,-233.15375 800.84375,-232.9375 C 799.58925,-232.52596 799.1576,-232.74846 795.5625,-231.5 C 792.17261,-230.32283 786.96755,-228.2863 785.78125,-227.34375 C 784.25737,-227.28408 782.1312,-226.94888 780.25,-226.28125 C 777.35261,-225.25296 775.55095,-224.60577 773.71875,-223.96875 C 771.88655,-223.33174 772.0909,-223.12021 770.9375,-222.71875 C 769.69071,-222.28479 769.27395,-222.51903 765.71875,-221.15625 C 762.38005,-219.87645 757.23165,-217.6737 756.03125,-216.6875 C 754.52407,-216.57981 752.39555,-216.1887 750.53125,-215.46875 C 747.66307,-214.36115 745.90735,-213.68719 744.09375,-213 C 743.47705,-212.76637 743.0973,-212.55797 742.8125,-212.40625 C 742.81251,-212.40625 742.8125,-212.37673 742.8125,-212.375 L 734.8125,-209.1875 L 736.625,-194.46875 C 736.36701,-194.52956 742.8125,-191.15625 742.8125,-191.15625 C 743.03891,-191.30093 743.26145,-191.42886 743.53125,-191.53125 C 744.61177,-191.94123 745.70285,-191.74702 749.53125,-193.21875 C 753.35977,-194.69049 754.7553,-195.22373 755.4375,-195.625 C 756.11711,-196.02478 757.04925,-196.50437 757.65625,-197.15625 C 759.48317,-197.294 761.22705,-197.64948 762.59375,-198.15625 C 765.56175,-199.25677 767.4691,-199.96244 769.375,-200.625 C 771.28081,-201.28754 771.72915,-202.03987 772.78125,-202.40625 C 773.87287,-202.78636 774.97635,-202.57163 778.84375,-203.9375 C 782.71115,-205.30336 784.1269,-205.76458 784.8125,-206.15625 C 785.51361,-206.55677 786.5133,-207.08923 787.125,-207.75 C 789.09581,-207.80466 790.94195,-208.13463 792.40625,-208.625 C 795.40777,-209.63008 797.3324,-210.24671 799.25,-210.875 C 800.78861,-211.3791 801.42415,-211.92177 802.15625,-212.3125 C 802.38647,-212.44681 802.63215,-212.56623 802.90625,-212.65625 C 804.00457,-213.01673 805.0877,-212.73762 809,-213.96875 C 812.91231,-215.19988 814.366,-215.6417 815.0625,-216 C 815.75641,-216.35697 816.6926,-216.79261 817.3125,-217.40625 C 819.17771,-217.42891 820.94835,-217.67308 822.34375,-218.09375 C 825.37415,-219.00729 827.33615,-219.52385 829.28125,-220.0625 C 831.22637,-220.60114 831.70745,-221.32702 832.78125,-221.625 C 833.89527,-221.93415 835.00125,-221.61761 838.96875,-222.65625 C 842.93625,-223.69488 844.38625,-224.08898 845.09375,-224.40625 C 845.82855,-224.73584 846.90765,-225.15997 847.53125,-225.78125 C 849.52907,-225.66525 851.3887,-225.80134 852.875,-226.15625 C 855.95311,-226.89125 857.9584,-227.25719 859.9375,-227.65625 C 861.52541,-227.97643 862.1818,-228.4468 862.9375,-228.75 C 863.17501,-228.8568 863.4044,-228.94276 863.6875,-229 C 864.82091,-229.22919 865.99215,-228.79107 870.03125,-229.5 C 874.07067,-230.20893 875.5315,-230.42709 876.25,-230.6875 C 876.96581,-230.94694 877.95435,-231.25474 878.59375,-231.78125 C 880.51795,-231.54176 882.34165,-231.55672 883.78125,-231.78125 C 886.90767,-232.26887 888.9358,-232.48192 890.9375,-232.75 C 892.93921,-233.01807 893.42625,-233.69514 894.53125,-233.84375 C 895.67767,-233.99793 896.8071,-233.54218 900.875,-234.0625 C 904.94281,-234.58282 906.43525,-234.75823 907.15625,-235 C 907.89337,-235.24714 908.95435,-235.58623 909.59375,-236.125 C 911.64375,-235.78947 913.56745,-235.72704 915.09375,-235.90625 C 918.23595,-236.27521 920.27375,-236.46561 922.28125,-236.6875 C 923.89207,-236.86552 924.5459,-237.2957 925.3125,-237.53125 C 925.55341,-237.61677 925.80655,-237.68685 926.09375,-237.71875 C 927.24345,-237.84647 928.39505,-237.3721 932.46875,-237.84375 C 936.54245,-238.3154 938.0278,-238.45435 938.75,-238.6875 C 939.46941,-238.91977 940.45025,-239.16096 941.09375,-239.65625 C 943.03005,-239.32279 944.8638,-239.25201 946.3125,-239.40625 C 949.45851,-239.7412 951.49,-239.92484 953.5,-240.125 C 955.50991,-240.32514 955.98415,-240.95139 957.09375,-241.0625 C 958.24485,-241.17778 959.39025,-240.69744 963.46875,-241.125 C 967.54725,-241.55256 969.05765,-241.68709 969.78125,-241.90625 C 970.52047,-242.13011 971.57685,-242.4195 972.21875,-242.9375 C 974.27575,-242.53883 976.2206,-242.4441 977.75,-242.59375 C 980.89871,-242.90185 982.9258,-243.067 984.9375,-243.25 C 986.55151,-243.39682 987.20055,-243.81055 987.96875,-244.03125 C 988.21005,-244.11211 988.4623,-244.16116 988.75,-244.1875 C 989.90211,-244.29295 991.0429,-243.79475 995.125,-244.1875 C 999.20711,-244.58025 1000.7139,-244.71834 1001.4375,-244.9375 C 1002.1584,-245.15583 1003.1371,-245.3852 1003.7812,-245.875 C 1005.7193,-245.52501 1007.5501,-245.42062 1009,-245.5625 C 1012.1487,-245.8706 1014.1758,-246.03575 1016.1875,-246.21875 C 1018.1991,-246.40174 1018.7017,-247.05677 1019.8125,-247.15625 C 1020.9648,-247.25948 1022.1047,-246.77142 1026.1875,-247.15625 C 1030.2704,-247.54107 1031.7762,-247.65725 1032.5,-247.875 C 1033.2393,-248.09743 1034.2956,-248.38949 1034.9375,-248.90625 C 1036.9949,-248.50448 1038.9404,-248.40292 1040.4688,-248.5625 C 1043.6153,-248.89102 1045.6458,-249.0852 1047.6562,-249.28125 C 1049.2692,-249.43854 1049.9219,-249.91273 1050.6875,-250.15625 C 1050.9282,-250.24429 1051.1507,-250.27762 1051.4375,-250.3125 C 1052.5858,-250.4522 1053.7542,-249.97259 1057.8125,-250.5625 C 1061.8708,-251.15242 1063.3743,-251.33964 1064.0938,-251.59375 C 1064.8104,-251.84691 1065.7684,-252.15182 1066.4062,-252.6875 C 1068.3259,-252.47556 1070.1262,-252.53609 1071.5625,-252.78125 C 1074.6816,-253.31365 1076.6741,-253.70986 1078.6562,-254.09375 C 1080.6383,-254.47762 1081.1305,-255.1334 1082.2188,-255.375 C 1083.3475,-255.62566 1084.489,-255.25871 1088.4688,-256.25 C 1092.4483,-257.24127 1093.8983,-257.6693 1094.5938,-258.03125 C 1095.316,-258.40725 1096.3555,-258.90183 1096.9688,-259.5625 C 1098.9317,-259.57454 1100.7625,-259.85355 1102.1875,-260.40625 C 1105.1387,-261.55085 1107.0607,-262.27567 1108.875,-263.15625 C 1110.3307,-263.86277 1111.1941,-264.85828 1111.4062,-265.15625 C 1111.6185,-265.4542 1111.5051,-265.8848 1111.5312,-265.90625 C 1111.5742,-265.94148 1111.8716,-266.00028 1112.0312,-266.34375 C 1112.8902,-268.19082 1114.3544,-271.97139 1114.4688,-272.65625 C 1114.5825,-273.33839 1114.6368,-274.00902 1114.6875,-274.40625 C 1114.7169,-274.63575 1114.5404,-275.28515 1114.5625,-275.34375 C 1114.5934,-275.42579 1114.8508,-275.59432 1114.9062,-275.84375 C 1115.1725,-277.04206 1114.9953,-278.05111 1114.7812,-279.46875 C 1114.5673,-280.88638 1113.8096,-284.08338 1113.1562,-284.9375 C 1112.4973,-285.79922 1111.9314,-285.94801 1111.4062,-285.9375 z"
-         transform="translate(8.0045714e-2,-3.125e-2)" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter7578"
-       x="-0.08160872"
-       width="1.1632174"
-       y="-0.22659944"
-       height="1.4531989">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="2.437399"
-         id="feGaussianBlur7580" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter7594"
-       x="-0.040804356"
-       width="1.0816087"
-       y="-0.11329972"
-       height="1.2265995">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="1.2186995"
-         id="feGaussianBlur7596" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath7606">
-      <path
-         id="path7608"
-         d="M 1049.205,-282.26672 L 1049.1152,-282.25891 C 1047.7278,-281.37446 1042.5119,-280.65171 1042.4862,-272.73547 C 1042.462,-265.31022 1057.4991,-255.64401 1059.6425,-254.64172 C 1061.3727,-253.83263 1063.2341,-253.23296 1065.0488,-252.92297 L 1066.4862,-252.70422 C 1068.4059,-252.49228 1070.2062,-252.55281 1071.6425,-252.79797 C 1074.7616,-253.33037 1076.7541,-253.72658 1078.7362,-254.11047 C 1080.7183,-254.49434 1081.2105,-255.15012 1082.2988,-255.39172 C 1083.4275,-255.64238 1084.569,-255.27543 1088.5488,-256.26672 C 1092.5283,-257.258 1093.9782,-257.68602 1094.6738,-258.04797 C 1095.396,-258.42398 1096.4355,-258.91855 1097.0488,-259.57922 C 1099.0117,-259.59127 1100.8425,-259.87027 1102.2675,-260.42297 C 1105.2187,-261.56758 1107.1407,-262.29239 1108.955,-263.17297 C 1110.4107,-263.8795 1111.2741,-264.875 1111.4862,-265.17297 C 1111.6985,-265.47093 1111.5852,-265.90152 1111.6112,-265.92297 C 1111.6542,-265.95821 1111.9517,-266.017 1112.1112,-266.36047 C 1112.9702,-268.20755 1114.4344,-271.98811 1114.5488,-272.67297 C 1114.6625,-273.35512 1114.7168,-274.02574 1114.7675,-274.42297 C 1114.7969,-274.65248 1114.6204,-275.30187 1114.6425,-275.36047 C 1114.6734,-275.44252 1114.9308,-275.61104 1114.9862,-275.86047 C 1115.2525,-277.05879 1115.0754,-278.06783 1114.8612,-279.48547 C 1114.6473,-280.90311 1113.8896,-284.1001 1113.2362,-284.95422 C 1112.8168,-285.50279 1112.4369,-285.74672 1112.08,-285.86047 C 1112.0129,-285.87776 1111.9561,-285.90721 1111.8925,-285.92297 C 1111.8715,-285.92695 1111.8508,-285.91983 1111.83,-285.92297 C 1111.5184,-285.99847 1111.2215,-286.08164 1110.6738,-286.14172 C 1109.6883,-286.24984 1108.2491,-286.40112 1106.705,-286.39172 C 1106.1903,-286.38859 1105.6679,-286.34408 1105.1425,-286.29797 C 1101.5836,-285.98569 1096.1327,-285.30689 1094.9238,-284.67297 C 1093.2907,-285.00699 1090.9756,-285.2852 1088.9862,-285.14172 C 1085.9222,-284.92075 1084.0185,-284.79953 1082.08,-284.67297 C 1080.1416,-284.54642 1080.3939,-284.28433 1079.1738,-284.20422 C 1077.8547,-284.11762 1077.3869,-284.42747 1073.6112,-284.11047 C 1070.0655,-283.81275 1064.6306,-283.1173 1063.3925,-282.48547 C 1061.7591,-282.81998 1059.4466,-283.09786 1057.455,-282.95422 C 1054.3908,-282.73324 1052.4872,-282.58078 1050.5488,-282.45422 C 1049.8896,-282.41119 1049.5064,-282.33029 1049.205,-282.26672 z"
-         style="opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter7610"
-       x="-0.021942979"
-       width="1.0438859"
-       y="-0.10017137"
-       height="1.2003427">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="0.57530213"
-         id="feGaussianBlur7612" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath7616">
-      <path
-         id="path7618"
-         d="M 205.47016,-408.97318 L 205.38003,-408.97164 C 203.9344,-408.18598 198.68082,-407.82829 198.10378,-399.93307 C 197.56244,-392.52754 211.88973,-381.83741 213.95811,-380.68826 C 215.62775,-379.76062 217.44286,-379.03275 219.23156,-378.59711 L 220.65023,-378.27877 C 222.5505,-377.93363 224.35065,-377.86862 225.80054,-378.01314 C 228.94914,-378.32698 230.9644,-378.58345 232.96843,-378.82834 C 234.97245,-379.07322 235.50913,-379.69312 236.61162,-379.85833 C 237.75504,-380.02976 238.86821,-379.58419 242.90739,-380.29586 C 246.94627,-381.00755 248.42246,-381.33354 249.14158,-381.64616 C 249.88822,-381.97095 250.95964,-382.39191 251.61747,-383.00826 C 253.57644,-382.88355 255.42223,-383.03435 256.88227,-383.48645 C 259.90603,-384.42272 261.87384,-385.01189 263.74507,-385.76396 C 265.24645,-386.36738 266.17709,-387.30032 266.40943,-387.58279 C 266.64197,-387.86524 266.55894,-388.30268 266.58637,-388.32227 C 266.63172,-388.35443 266.93259,-388.39235 267.11563,-388.72388 C 268.1012,-390.50664 269.82518,-394.17603 269.987,-394.85126 C 270.14794,-395.52383 270.24882,-396.18904 270.32707,-396.58177 C 270.37238,-396.80868 270.24154,-397.46878 270.26767,-397.5257 C 270.30421,-397.6054 270.57272,-397.75558 270.64536,-398.00055 C 270.99449,-399.17741 270.8881,-400.19633 270.77316,-401.62545 C 270.65853,-403.05454 270.12535,-406.29655 269.53303,-407.1941 C 269.15286,-407.77056 268.79088,-408.04035 268.44277,-408.17869 C 268.37703,-408.20061 268.32242,-408.23394 268.26007,-408.2541 C 268.2394,-408.25953 268.21826,-408.25387 268.19773,-408.25845 C 267.89214,-408.35547 267.60176,-408.45912 267.05957,-408.5572 C 266.084,-408.7337 264.65883,-408.98486 263.11782,-409.08304 C 262.60416,-409.11577 262.07992,-409.10775 261.55259,-409.09835 C 257.98058,-409.03472 252.49564,-408.73725 251.24552,-408.18907 C 249.63965,-408.63604 247.34955,-409.07483 245.35499,-409.07027 C 242.28304,-409.06325 240.37552,-409.07493 238.43292,-409.0837 C 236.49041,-409.09248 236.72384,-408.81345 235.50112,-408.81852 C 234.1792,-408.82401 233.73411,-409.16569 229.9455,-409.11245 C 226.38768,-409.06243 220.91754,-408.74723 219.63844,-408.20318 C 218.0323,-408.65065 215.74477,-409.08893 213.74801,-409.08436 C 210.67586,-409.07735 208.76626,-409.05786 206.82375,-409.06662 C 206.16316,-409.06961 205.77525,-409.0156 205.47016,-408.97318 z"
-         style="opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient7622"
-       id="linearGradient7708"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-19.091883,4.2426407)"
-       x1="774.97668"
-       y1="-211.87105"
-       x2="755.11584"
-       y2="-202.67865" />
-    <mask
-       maskUnits="userSpaceOnUse"
-       id="mask7704">
-      <path
-         style="fill:url(#linearGradient7708);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-         d="M 718.40812,-224.31217 L 751.65812,-168.31217 L 1027.6581,-192.31217 L 1187.1581,-240.56217 L 1120.6581,-323.31217 L 718.40812,-224.31217 z"
-         id="path7706" />
-    </mask>
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8430"
-       id="radialGradient7904"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(-0.3324832,0.9022288,-0.9582407,-0.3531242,305.29227,19.909497)"
-       cx="142.95833"
-       cy="107.09234"
-       fx="142.95833"
-       fy="107.09234"
-       r="66.981766" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3317"
-       id="radialGradient7906"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-160.53487,-96.205369)"
-       cx="317.78754"
-       cy="129.65378"
-       fx="317.78754"
-       fy="129.65378"
-       r="47.863216" />
-    <radialGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient8398"
-       id="radialGradient7908"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-550.77432,-65.728909)"
-       cx="325.30847"
-       cy="80.909554"
-       fx="325.30847"
-       fy="80.909554"
-       r="26.937988" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8209">
-      <path
-         sodipodi:nodetypes="czcc"
-         id="path8211"
-         d="M 734.03125,519.49186 C 734.03125,519.49186 750.78638,556.50992 762.73266,573.44581 C 774.67895,590.3817 815.45982,629.49186 815.45982,629.49186 L 816.05699,490.90211"
-         style="opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8225">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="10.661912"
-         id="feGaussianBlur8227" />
-    </filter>
-    <filter
-       inkscape:collect="always"
-       id="filter8333">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="7.18"
-         id="feGaussianBlur8335" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8338">
-      <path
-         sodipodi:nodetypes="czzzzzzcccccccccczczz"
-         id="path8340"
-         d="M 266.27183,924.57185 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87513 C 271.58023,990.42751 284.75966,1019.7825 288.68798,1037.0589 C 292.61419,1054.326 291.38211,1075.3686 276.22854,1088.2071 C 260.91093,1101.1846 234.17727,1109.8061 208.39624,1103.9409 C 182.61518,1098.0756 138.84716,1054.7175 119.80605,1033.7126 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 C 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 C 24.38107,839.38658 21.33408,813.84026 0.035334479,788.33044 C 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 C 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 C 61.781367,750.82754 82.366432,776.61828 95.766855,817.45839 C 105.32101,813.54047 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.0048,738.48134 89.267014,707.32725 C 142.70898,712.99757 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.426,751.28935 177.62715,712.76848 195.01526,670.98819 C 195.01526,670.98819 243.30204,736.42507 249.40491,756.79397 C 255.50779,777.16287 250.92373,795.49448 250.92373,795.49448 C 250.92373,795.49448 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82996 267.68496,905.69193 266.27183,924.57185 z"
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8354">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="6.82"
-         id="feGaussianBlur8356" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8359">
-      <path
-         sodipodi:nodetypes="czzzzzzcccccccccczczz"
-         id="path8361"
-         d="M 266.27183,924.57185 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87513 C 271.58023,990.42751 284.75966,1019.7825 288.68798,1037.0589 C 292.61419,1054.326 291.38211,1075.3686 276.22854,1088.2071 C 260.91093,1101.1846 234.17727,1109.8061 208.39624,1103.9409 C 182.61518,1098.0756 138.84716,1054.7175 119.80605,1033.7126 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 C 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 C 24.38107,839.38658 21.33408,813.84026 0.035334479,788.33044 C 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 C 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 C 61.781367,750.82754 82.366432,776.61828 95.766855,817.45839 C 105.32101,813.54047 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.0048,738.48134 89.267014,707.32725 C 142.70898,712.99757 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.426,751.28935 177.62715,712.76848 195.01526,670.98819 C 195.01526,670.98819 243.30204,736.42507 249.40491,756.79397 C 255.50779,777.16287 250.92373,795.49448 250.92373,795.49448 C 250.92373,795.49448 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82996 267.68496,905.69193 266.27183,924.57185 z"
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8379"
-       x="-0.14413793"
-       width="1.288276"
-       y="-0.10278689"
-       height="1.2055738">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="7.389266"
-         id="feGaussianBlur8381" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8392">
-      <path
-         sodipodi:nodetypes="czzzzzzcccccccccczczz"
-         id="path8394"
-         d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z"
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-    <filter
-       inkscape:collect="always"
-       id="filter8404"
-       x="-0.090268657"
-       width="1.1805373"
-       y="-0.10250848"
-       height="1.205017">
-      <feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="5.3457272"
-         id="feGaussianBlur8406" />
-    </filter>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath8417">
-      <path
-         sodipodi:nodetypes="czzzzzzcccccccccczczz"
-         id="path8419"
-         d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z"
-         style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </clipPath>
-  </defs>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:groupmode="layer"
-     id="layer1"
-     inkscape:label="Shadow">
-    <path
-       style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter11361);enable-background:new"
-       d="M 304.64285,526.6479 C 294.64285,527.00505 286.42857,529.50504 286.42857,529.50504 L 293.92857,535.57647 L 304.28571,539.1479 L 320.35714,539.50504 L 342.85714,534.1479 L 350.71428,535.21933 L 371.07143,533.07647 L 360.71428,539.86219 C 366.17351,538.83858 378.10757,543.4313 370.35714,545.21933 C 368.61714,545.62075 384.28571,540.57648 384.28571,540.57648 L 386.78571,535.93361 L 390.35714,526.6479 L 401.78571,526.6479 L 419.99999,522.00504 L 423.57143,517.00505 L 407.49999,518.07647 L 395.35714,520.21933 L 380.71428,515.21933 L 310.02218,531.92707 L 304.64285,526.6479 z"
-       id="path10326"
-       sodipodi:nodetypes="cccccccccsccccccccccc"
-       transform="matrix(10.726753,0,0,10.726753,-2882.1235,-4565.4583)"
-       inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_new.png"
-       inkscape:export-xdpi="142.10527"
-       inkscape:export-ydpi="142.10527" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer20"
-     inkscape:label="New Ear">
-    <g
-       style="opacity:1;display:inline;enable-background:new"
-       id="g7882"
-       transform="matrix(0.71084,-0.1937433,0.262963,0.9648058,503.68027,136.48399)">
-      <path
-         sodipodi:nodetypes="czzzzcc"
-         id="path7876"
-         d="M 245.12255,100.05344 C 245.12255,100.05344 197.99444,68.406519 177.9079,64.252501 C 157.86998,60.108538 139.435,60.934923 125.97426,77.859824 C 112.51352,94.784725 113.89687,139.12502 112.43872,164.82937 C 110.98057,190.53372 114.98817,235.00638 130.04332,253.49489 C 145.09848,271.98339 175.92966,267.07991 179.97027,274.90859 C 182.1831,279.19595 245.12255,100.05344 245.12255,100.05344 z"
-         style="opacity:1;fill:url(#radialGradient7904);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <path
-         sodipodi:nodetypes="czzzzzc"
-         id="path7878"
-         d="M 135.37935,82.017807 C 135.37935,82.017807 161.7229,83.95659 173.01242,95.920995 C 184.42736,108.01833 186.74699,117.25251 188.30828,133.65558 C 189.87165,150.08057 187.45871,162.0737 180.49446,169.69292 C 173.53021,177.31214 179.49017,189.27624 154.57841,181.76399 C 129.66665,174.25174 127.54617,153.98101 128.06318,135.45924 C 128.58039,116.93026 135.37935,82.017807 135.37935,82.017807 z"
-         style="opacity:1;fill:url(#radialGradient7906);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <path
-         sodipodi:nodetypes="czccssc"
-         id="path7880"
-         d="M 135.648,81.927211 C 135.648,81.927211 131.00335,98.292286 136.23625,110.49031 C 141.72419,123.28285 163.4605,154.75038 163.4605,165.14596 L 186.11675,160.14596 C 188.65893,153.17952 189.32727,144.3939 188.30425,133.64596 C 186.74296,117.24289 184.43795,108.02455 173.023,95.927211 C 163.36812,85.695164 141.42989,82.552354 135.648,81.927211 z"
-         style="opacity:1;fill:url(#radialGradient7908);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-    </g>
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer21"
-     inkscape:label="Rendered2"
-     style="display:inline">
-    <path
-       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 845.03125,1154.7776 C 840.74554,1155.4919 817.4031,1158.3957 787.17411,1164.7776 C 756.94512,1171.1595 729.86016,1169.7437 651.38803,1182.1072 C 571.53625,1194.688 557.32367,1224.6495 543.26578,1229.1715 C 528.56564,1233.9001 397.88839,1163.349 397.88839,1163.349 L 402.17411,1069.0633 C 402.17411,1069.0633 488.05962,1052.8624 514.31696,1035.4919 C 540.57431,1018.1214 559.89934,985.82588 573.60268,964.06329 C 587.30602,942.3007 606.45982,892.63471 606.45982,892.63471 L 845.03125,1154.7776 z"
-       id="path7917"
-       sodipodi:nodetypes="czzzcczzcc" />
-    <path
-       style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8888);enable-background:accumulate"
-       d="M 332.34019,898.38549 L 299.60838,837.08593 L 261.99104,882.19239 C 264.16779,883.5095 267.76529,861.33636 307.59144,817.77531 L 332.34019,898.38549 z"
-       id="path7919"
-       clip-path="url(#clipPath8658)"
-       sodipodi:nodetypes="ccccc"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:url(#linearGradient2841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8892);enable-background:accumulate"
-       d="M 200.81833,863.03015 L 347.18943,811.41136 L 591.14127,1037.6855 L 349.31075,1177.6927 L 168.29141,1090.0114 L 200.81833,863.03015 z"
-       id="path7923"
-       clip-path="url(#clipPath2833)"
-       sodipodi:nodetypes="cccccc"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 642.88839,640.13471 C 642.88839,640.13471 613.33433,680.70776 595.03125,714.42042 C 576.72816,748.13309 536.41016,840.77736 524.67411,885.49185 C 512.91471,930.29529 462.17411,1009.0633 462.17411,1009.0633 L 538.24554,1027.2776 C 538.24554,1027.2776 550.05266,1014.4542 569.31696,981.20614 C 588.58126,947.95806 629.67411,842.63471 629.67411,842.63471 L 642.88839,640.13471 z"
-       id="path7921"
-       sodipodi:nodetypes="czzcczcc" />
-    <path
-       style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8856);enable-background:accumulate"
-       d="M 430.28131,381.94122 C 423.21025,384.76965 194.10007,414.09303 194.10007,414.09303 L 154.46046,773.92607 L 244.65895,866.56568 L 296.98485,752.01438 L 397.45289,565.62246 L 430.28131,381.94122 z"
-       id="path7925"
-       sodipodi:nodetypes="ccccccc"
-       clip-path="url(#clipPath3665)"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 969.67051,1164.0346 C 969.67051,1164.0346 992.92679,1175.4283 1005.7383,1184.5107 C 1018.4357,1193.5122 1035.2107,1209.1598 1047.4307,1221.8712 C 1059.7362,1234.6714 1067.5434,1244.4699 1088.9634,1246.032 C 1110.3956,1247.5949 1142.2458,1237.2444 1162.2594,1221.3678 C 1182.2729,1205.4912 1207.9063,1152.135 1207.9063,1152.135 L 1080.7455,1009.0633"
-       id="path7927"
-       sodipodi:nodetypes="czzzzcc" />
-    <path
-       style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8860);enable-background:accumulate"
-       d="M 331.34019,641.50471 L 216.17367,835.36467 L 260.2153,925.96265 L 357.79603,732.21539 L 331.34019,641.50471 z"
-       id="path7929"
-       clip-path="url(#clipPath8642)"
-       sodipodi:nodetypes="ccccc"
-       transform="translate(276,136)" />
-    <g
-       style="opacity:1;display:inline;enable-background:new"
-       id="g7931"
-       transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
-       inkscape:transform-center-x="-347.89063"
-       inkscape:transform-center-y="-28.255779">
-      <path
-         style="opacity:1;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 1049.205,-282.26672 L 1049.1152,-282.25891 C 1047.7278,-281.37446 1042.5119,-280.65171 1042.4862,-272.73547 C 1042.462,-265.31022 1057.4991,-255.64401 1059.6425,-254.64172 C 1061.3727,-253.83263 1063.2341,-253.23296 1065.0488,-252.92297 L 1066.4862,-252.70422 C 1068.4059,-252.49228 1070.2062,-252.55281 1071.6425,-252.79797 C 1074.7616,-253.33037 1076.7541,-253.72658 1078.7362,-254.11047 C 1080.7183,-254.49434 1081.2105,-255.15012 1082.2988,-255.39172 C 1083.4275,-255.64238 1084.569,-255.27543 1088.5488,-256.26672 C 1092.5283,-257.258 1093.9782,-257.68602 1094.6738,-258.04797 C 1095.396,-258.42398 1096.4355,-258.91855 1097.0488,-259.57922 C 1099.0117,-259.59127 1100.8425,-259.87027 1102.2675,-260.42297 C 1105.2187,-261.56758 1107.1407,-262.29239 1108.955,-263.17297 C 1110.4107,-263.8795 1111.2741,-264.875 1111.4862,-265.17297 C 1111.6985,-265.47093 1111.5852,-265.90152 1111.6112,-265.92297 C 1111.6542,-265.95821 1111.9517,-266.017 1112.1112,-266.36047 C 1112.9702,-268.20755 1114.4344,-271.98811 1114.5488,-272.67297 C 1114.6625,-273.35512 1114.7168,-274.02574 1114.7675,-274.42297 C 1114.7969,-274.65248 1114.6204,-275.30187 1114.6425,-275.36047 C 1114.6734,-275.44252 1114.9308,-275.61104 1114.9862,-275.86047 C 1115.2525,-277.05879 1115.0754,-278.06783 1114.8612,-279.48547 C 1114.6473,-280.90311 1113.8896,-284.1001 1113.2362,-284.95422 C 1112.8168,-285.50279 1112.4369,-285.74672 1112.08,-285.86047 C 1112.0129,-285.87776 1111.9561,-285.90721 1111.8925,-285.92297 C 1111.8715,-285.92695 1111.8508,-285.91983 1111.83,-285.92297 C 1111.5184,-285.99847 1111.2215,-286.08164 1110.6738,-286.14172 C 1109.6883,-286.24984 1108.2491,-286.40112 1106.705,-286.39172 C 1106.1903,-286.38859 1105.6679,-286.34408 1105.1425,-286.29797 C 1101.5836,-285.98569 1096.1327,-285.30689 1094.9238,-284.67297 C 1093.2907,-285.00699 1090.9756,-285.2852 1088.9862,-285.14172 C 1085.9222,-284.92075 1084.0185,-284.79953 1082.08,-284.67297 C 1080.1416,-284.54642 1080.3939,-284.28433 1079.1738,-284.20422 C 1077.8547,-284.11762 1077.3869,-284.42747 1073.6112,-284.11047 C 1070.0655,-283.81275 1064.6306,-283.1173 1063.3925,-282.48547 C 1061.7591,-282.81998 1059.4466,-283.09786 1057.455,-282.95422 C 1054.3908,-282.73324 1052.4872,-282.58078 1050.5488,-282.45422 C 1049.8896,-282.41119 1049.5064,-282.33029 1049.205,-282.26672 z"
-         id="path7933" />
-      <g
-         clip-path="url(#clipPath7616)"
-         style="display:inline;filter:url(#filter7610);enable-background:new"
-         id="g7935"
-         transform="matrix(0.9975712,-6.9654277e-2,6.9654277e-2,0.9975712,872.72062,140.02502)">
-        <path
-           sodipodi:nodetypes="ccssscsssscscsscsssccscssccsscssscc"
-           id="path7937"
-           d="M 229.94262,-409.12268 C 226.38481,-409.07267 220.91842,-408.76259 219.63928,-408.21854 C 218.03319,-408.66601 215.73612,-409.09985 213.73933,-409.09528 C 210.66734,-409.08826 208.77464,-409.08651 206.83206,-409.09528 C 206.17159,-409.09827 205.78447,-409.02811 205.47939,-408.98569 C 205.47939,-408.98569 205.47939,-407.88976 205.47939,-407.88976 C 205.59911,-408.06923 205.87191,-408.58022 206.42914,-408.65691 C 207.17672,-408.7598 211.59842,-408.80814 213.73933,-408.76651 C 215.51393,-408.73198 218.19456,-408.49224 220.12854,-407.80756 C 220.44994,-407.69378 220.74779,-407.53378 221.02073,-407.39659 C 222.98415,-406.40966 228.96409,-403.09505 228.96409,-403.09505 C 228.96409,-403.09505 222.33134,-407.04273 221.48122,-407.53358 C 221.27791,-407.65097 220.90658,-407.79127 220.44513,-407.94456 C 221.66576,-408.39235 225.5211,-408.56427 228.27336,-408.65691 C 231.29786,-408.75873 231.62112,-408.7465 233.68405,-408.46512 C 235.81336,-408.17469 237.02256,-407.86236 237.02256,-407.86236 C 237.02255,-407.86236 236.9442,-408.50354 238.05865,-408.65691 C 238.80622,-408.7598 243.22794,-408.80814 245.36884,-408.76651 C 247.43834,-408.72625 250.73489,-408.35935 252.65024,-407.39659 C 253.65356,-406.89226 255.68588,-405.82796 257.44559,-404.86088 L 257.5412,-404.88031 C 257.5412,-404.88031 253.96086,-407.04273 253.11073,-407.53358 C 252.90742,-407.65097 252.5361,-407.79127 252.07464,-407.94456 C 253.29526,-408.39235 257.12183,-408.56427 259.87409,-408.65691 C 262.89859,-408.75873 263.22184,-408.7465 265.28478,-408.46512 C 267.23794,-408.19872 268.2977,-407.93506 268.47939,-407.88976 C 268.47939,-407.88976 268.4523,-408.20122 268.4523,-408.20122 C 268.04327,-408.33767 267.73806,-408.43457 267.05192,-408.5587 C 265.75111,-408.79403 263.6528,-409.16026 261.54335,-409.12268 C 257.9714,-409.05904 252.49007,-408.76672 251.24001,-408.21854 C 249.63418,-408.66549 247.36339,-409.09984 245.36884,-409.09528 C 242.29685,-409.08826 240.37536,-409.08651 238.43279,-409.09528 C 236.49023,-409.10406 236.72011,-408.81621 235.49721,-408.8213 C 234.1753,-408.8268 233.73109,-409.17593 229.94262,-409.12268 C 229.94262,-409.12268 229.94262,-409.12268 229.94262,-409.12268"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-        <path
-           id="path7939"
-           d="M 206.1989,-407.47878 C 208.11911,-406.66172 210.77605,-405.28595 212.35787,-404.08139 C 213.93971,-402.87683 215.26544,-402.30771 217.91246,-400.16344 C 218.79803,-399.44606 219.66111,-398.81359 220.50439,-398.2417 L 221.04496,-398.43181 C 220.33173,-398.9152 219.5772,-399.45212 218.77587,-400.05384 C 215.95364,-402.17305 215.14932,-402.86357 212.7608,-404.32798 C 210.37226,-405.79238 208.66132,-406.69374 206.1989,-407.47878 C 206.1989,-407.47878 206.1989,-407.47878 206.1989,-407.47878"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-           sodipodi:nodetypes="cssccsscc" />
-        <path
-           id="path7941"
-           d="M 237.79963,-407.47878 C 239.71984,-406.66172 242.40557,-405.28595 243.98738,-404.08139 C 244.80045,-403.46223 245.54587,-403.01097 246.43784,-402.42738 L 247.08684,-402.54404 C 246.28853,-403.12041 245.51507,-403.63839 244.39031,-404.32798 C 242.00177,-405.79238 240.26205,-406.69374 237.79963,-407.47878 C 237.79963,-407.47878 237.79963,-407.47878 237.79963,-407.47878"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-           sodipodi:nodetypes="csccscc" />
-      </g>
-      <g
-         clip-path="url(#clipPath7606)"
-         id="g7943">
-        <path
-           style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7578);enable-background:new"
-           d="M 1056.25,-278.80481 C 1060.3946,-280.28358 1066.25,-275.67981 1066.25,-275.67981 C 1067.149,-275.39889 1068.9751,-276.57428 1068.8743,-277.36595 C 1068.8743,-277.36595 1067.324,-279.22657 1068.5,-280.30481 C 1069.676,-281.38305 1073.796,-278.79743 1076,-278.67981 C 1078.204,-278.56219 1081.5621,-278.90922 1083,-279.42981 C 1084.4379,-279.9504 1084.1129,-280.8544 1085.625,-281.17981 C 1087.1371,-281.50522 1090.7439,-280.14227 1092.6855,-280.01098 C 1094.6271,-279.87969 1097.3336,-279.67671 1098.5,-280.17981 C 1099.6664,-280.68291 1098.6782,-281.33902 1100.375,-282.05481 C 1102.0718,-282.7706 1108.1352,-283.01143 1110,-282.17981 C 1111.8648,-281.34819 1111.8099,-281.66061 1112.625,-279.17981 C 1113.4401,-276.69901 1120.0648,-274.01696 1111.5,-265.80481 C 1102.9352,-257.59266 1052.1221,-252.01887 1045.875,-263.05481 C 1039.6279,-274.09075 1052.1054,-277.32604 1056.25,-278.80481 z"
-           id="path7945"
-           sodipodi:nodetypes="czzzzzzzzzzzzzz" />
-        <path
-           style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7594);enable-background:new"
-           d="M 1058.5,-275.42981 C 1062.6446,-276.90858 1068.5,-272.30481 1068.5,-272.30481 C 1069.399,-272.02389 1071.2251,-273.19928 1071.1243,-273.99095 C 1071.1243,-273.99095 1069.574,-275.85157 1070.75,-276.92981 C 1071.926,-278.00805 1076.046,-275.42243 1078.25,-275.30481 C 1080.454,-275.18719 1083.8121,-275.53422 1085.25,-276.05481 C 1086.6879,-276.5754 1086.3629,-277.4794 1087.875,-277.80481 C 1089.3871,-278.13022 1092.9939,-276.76727 1094.9355,-276.63598 C 1096.8771,-276.50469 1099.5836,-276.30171 1100.75,-276.80481 C 1101.9164,-277.30791 1100.9282,-277.96402 1102.625,-278.67981 C 1104.3218,-279.3956 1110.3852,-279.63643 1112.25,-278.80481 C 1114.1148,-277.97319 1114.0599,-278.28561 1114.875,-275.80481 C 1115.6901,-273.32401 1122.3148,-270.64196 1113.75,-262.42981 C 1105.1852,-254.21766 1054.3721,-248.64387 1048.125,-259.67981 C 1041.8779,-270.71575 1054.3554,-273.95104 1058.5,-275.42981 z"
-           id="path7947"
-           sodipodi:nodetypes="czzzzzzzzzzzzzz" />
-      </g>
-    </g>
-    <path
-       style="opacity:1;fill:#101414;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 628.24553,347.99185 C 624.4411,322.72762 611.43581,297.35383 611.08873,272.46662 C 610.90247,259.1111 614.36158,245.89571 624.84426,232.91257 C 661.19128,167.61674 741.78517,148.21789 810.77892,141.44715 C 897.70131,130.43035 995.69159,159.38722 1044.1503,236.84843 C 1098.2743,312.58173 1100.825,409.38755 1124.7623,496.37638 C 1154.2001,623.50398 1179.5414,752.59052 1185.1545,883.22673 C 1182.0911,961.40858 1176.7282,1048.4109 1124.6513,1111.3609 C 1076.6248,1161.7183 1001.8649,1161.4139 937.58145,1170.3632 C 847.02606,1175.0182 753.22992,1154.2174 675.79755,1106.165 C 611.02191,1068.225 580.06736,992.68633 578.51815,920.14538 C 570.12898,840.27022 604.90967,766.33687 630.13855,692.98577 C 637.60916,610.2247 639.55141,526.73802 639.79189,443.60093 C 638.95507,411.40549 632.70236,379.7836 628.24553,347.99185 z"
-       id="path7949"
-       sodipodi:nodetypes="cscccccccccccc" />
-    <path
-       style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8940);enable-background:accumulate"
-       d="M 311.83409,415.43155 L 321.73359,537.05392 L 261.62951,673.52553 L 277.18586,848.1809 C 292.79912,910.0601 309.37131,946.84995 351.56201,965.23473 C 355.88112,928.99475 312.95049,822.27485 312.31937,776.11489 C 311.68792,729.93044 323.14971,667.50703 342.99704,617.81842 C 363.04539,567.62654 379.89378,572.972 385.12193,525.22549 C 390.35008,477.47898 367.69553,375.83357 367.69553,375.83357 L 311.83409,415.43155 z"
-       id="path7951"
-       sodipodi:nodetypes="ccccczzzcc"
-       clip-path="url(#clipPath8616)"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:url(#linearGradient8970);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 1010.0312,655.49186 C 1010.0312,655.49186 1026.7864,692.50992 1038.7327,709.44581 C 1050.6789,726.3817 1091.4598,765.49186 1091.4598,765.49186 L 1144.057,637.90211"
-       id="path7953"
-       sodipodi:nodetypes="czcc" />
-    <path
-       style="opacity:0.07999998;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8822);enable-background:accumulate"
-       d="M 730.31998,536.56864 C 730.31998,545.05392 772.86772,595.03667 772.86772,595.03667 L 785.47431,566.26713 L 730.31998,536.56864 z"
-       id="path7955"
-       sodipodi:nodetypes="cccc"
-       clip-path="url(#clipPath8209)"
-       transform="translate(276,136)" />
-    <g
-       transform="translate(450.03125,73.843964)"
-       style="opacity:1;display:inline;enable-background:new"
-       id="g7957"
-       clip-path="url(#clipPath3998)">
-      <g
-         transform="translate(-174.03125,62.156036)"
-         style="filter:url(#filter3677)"
-         id="g7959">
-        <g
-           id="g7961"
-           style="filter:url(#filter3785)">
-          <path
-             sodipodi:nodetypes="czzzzzzzzzz"
-             id="path7963"
-             d="M 425.88244,476.99186 C 436.68787,475.5132 450.62645,480.34637 470.5253,480.20614 C 490.42415,480.06591 527.97852,463.29492 552.66815,463.06328 C 577.35778,462.83164 615.41985,475.34734 631.95387,478.06328 C 648.48789,480.77922 654.80219,477.90476 659.45386,485.92043 C 664.10553,493.9361 661.38057,496.66767 649.09672,506.63472 C 636.81287,516.60177 608.30704,519.27104 583.02529,519.49186 C 557.74295,519.71268 512.644,526.57038 487.66815,523.42042 C 462.6923,520.27046 430.73059,515.59775 418.73958,505.56328 C 406.74857,495.52881 398.88874,488.83146 401.23958,481.63471 C 403.59042,474.43796 415.07701,478.47052 425.88244,476.99186 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <rect
-             y="412.60312"
-             x="343.6539"
-             height="181.01935"
-             width="381.83765"
-             id="rect7965"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-        <g
-           id="g7967"
-           style="filter:url(#filter3785)">
-          <path
-             sodipodi:nodetypes="czzzcc"
-             id="path7969"
-             d="M 687.14286,452.36218 C 676.68117,462.07661 600.16326,471.36732 586.42857,481.6479 C 572.69388,491.92848 571.67605,494.53616 574.28571,501.6479 C 576.89537,508.75964 580.83098,511.05362 600,510.21932 C 619.16902,509.38502 698.57143,482.5976 698.57143,488.79075 L 687.14286,452.36218 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-             transform="translate(174.03125,-62.156036)" />
-          <rect
-             y="344.82138"
-             x="702.86414"
-             height="162.63455"
-             width="207.8894"
-             id="rect7971"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-      </g>
-      <g
-         transform="translate(-174.03125,62.156036)"
-         style="opacity:0.18000004;display:inline;enable-background:new"
-         id="g7973">
-        <g
-           id="g7975"
-           style="filter:url(#filter3785)">
-          <path
-             sodipodi:nodetypes="czzzzzzzzzz"
-             id="path7977"
-             d="M 425.88244,476.99186 C 436.68787,475.5132 450.62645,480.34637 470.5253,480.20614 C 490.42415,480.06591 527.97852,463.29492 552.66815,463.06328 C 577.35778,462.83164 615.41985,475.34734 631.95387,478.06328 C 648.48789,480.77922 654.80219,477.90476 659.45386,485.92043 C 664.10553,493.9361 661.38057,496.66767 649.09672,506.63472 C 636.81287,516.60177 608.30704,519.27104 583.02529,519.49186 C 557.74295,519.71268 512.644,526.57038 487.66815,523.42042 C 462.6923,520.27046 430.73059,515.59775 418.73958,505.56328 C 406.74857,495.52881 398.88874,488.83146 401.23958,481.63471 C 403.59042,474.43796 415.07701,478.47052 425.88244,476.99186 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <rect
-             y="412.60312"
-             x="343.6539"
-             height="181.01935"
-             width="381.83765"
-             id="rect7979"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-        <g
-           id="g7981"
-           style="filter:url(#filter3785)">
-          <path
-             sodipodi:nodetypes="czzzcc"
-             id="path7983"
-             d="M 687.14286,452.36218 C 676.68117,462.07661 600.16326,471.36732 586.42857,481.6479 C 572.69388,491.92848 571.67605,494.53616 574.28571,501.6479 C 576.89537,508.75964 580.83098,511.05362 600,510.21932 C 619.16902,509.38502 698.57143,482.5976 698.57143,488.79075 L 687.14286,452.36218 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-             transform="translate(174.03125,-62.156036)" />
-          <rect
-             y="344.82138"
-             x="702.86414"
-             height="162.63455"
-             width="207.8894"
-             id="rect7985"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-      </g>
-    </g>
-    <path
-       style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8802);enable-background:accumulate"
-       d="M 582.65599,-7.4183011 L 695.79307,78.848726 L 804.68752,337.64981 L 842.87128,545.5392 L 963.07944,637.46308 C 963.07944,637.46308 950.35151,350.37773 943.28044,323.50767 C 936.20938,296.63761 793.37381,-69.643698 793.37381,-69.643698 L 582.65599,-7.4183011 z"
-       id="path7987"
-       clip-path="url(#clipPath8604)"
-       sodipodi:nodetypes="cccccscc"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:url(#linearGradient8958);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 964.13839,239.599 C 964.13839,239.599 972.81571,250.49562 988.24554,251.56328 C 1003.6754,252.63094 1037.9672,211.61061 1058.4241,199.42043 C 1078.9034,187.2169 1105.4705,172.81818 1122.3527,179.06329 C 1139.2348,185.30839 1144.5105,205.49938 1150.2098,227.099 C 1155.9092,248.69861 1156.9284,288.91289 1147.5313,319.95615 C 1138.1341,350.9994 1097.028,393.0599 1082.1741,423.349 C 1067.3202,453.6381 1070.567,463.17043 1070.567,463.17043"
-       id="path7989"
-       sodipodi:nodetypes="czzzzzzc" />
-    <path
-       style="opacity:1;fill:url(#radialGradient3315);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 1124.4955,207.63471 C 1108.6027,206.74185 1074.7767,219.74054 1058.4241,231.92043 C 1041.9855,244.16433 1029.2032,256.03483 1029.1384,284.06328 C 1029.0732,312.26932 1042.2575,323.13969 1058.2455,331.02757 C 1074.2335,338.91546 1091.9317,338.14685 1110.2098,319.24186 C 1128.488,300.33686 1124.4955,207.63471 1124.4955,207.63471 z"
-       id="path7991"
-       sodipodi:nodetypes="czzzzc" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:0.75;fill:url(#radialGradient3543);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4120);enable-background:accumulate"
-       id="path7993"
-       sodipodi:cx="385"
-       sodipodi:cy="237.00504"
-       sodipodi:rx="86.428574"
-       sodipodi:ry="73.928574"
-       d="M 471.42857,237.00504 A 86.428574,73.928574 0 1 1 298.57143,237.00504 A 86.428574,73.928574 0 1 1 471.42857,237.00504 z"
-       transform="matrix(0.9434749,-0.1239943,0.1440089,1.0957669,451.94827,134.5988)"
-       clip-path="url(#clipPath4100)" />
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:1;fill:url(#radialGradient3915);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 527.60588,407.44884 C 527.60588,407.44884 405.56444,445.85232 340.09154,417.08065 C 274.61865,388.30899 265.71429,292.36218 265.71429,292.36218 C 265.71429,292.36218 339.09587,211.85825 395.63507,208.74742 C 451.46212,205.67578 486.20893,228.89074 510.50508,274.59913 C 534.85708,320.41261 527.60588,407.44884 527.60588,407.44884 z"
-       id="path7995"
-       sodipodi:nodetypes="csczzc"
-       mask="url(#mask3684)" />
-    <path
-       style="opacity:1;fill:url(#linearGradient3959);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 772.17411,393.349 C 772.17411,393.349 808.39165,365.96653 823.78125,357.45614 C 838.95859,349.06313 849.49553,345.849 859.6741,345.849 L 844.13839,412.81328"
-       id="path7997"
-       sodipodi:nodetypes="czcc" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient3933);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path7999"
-       sodipodi:cx="409.28571"
-       sodipodi:cy="306.64789"
-       sodipodi:rx="36.25"
-       sodipodi:ry="36.25"
-       d="M 445.53571,306.64789 A 36.25,36.25 0 1 1 373.03571,306.64789 A 36.25,36.25 0 1 1 445.53571,306.64789 z"
-       transform="translate(449.49554,74.915393)" />
-    <path
-       style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8806);enable-background:accumulate"
-       d="M 311.83409,415.43155 L 321.73359,537.05392 L 261.62951,673.52553 L 277.18586,848.1809 C 292.79912,910.0601 309.37131,946.84995 351.56201,965.23473 C 355.88112,928.99475 360.24362,892.86709 320.31937,742.11489 L 337.99704,672.81842 L 410.12193,534.22549 L 367.69553,375.83357 L 311.83409,415.43155 z"
-       id="path8001"
-       sodipodi:nodetypes="cccccccccc"
-       clip-path="url(#clipPath8616)"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8826);enable-background:accumulate"
-       d="M 635.21025,581.13004 C 621.06811,593.85796 674.44372,615.71019 711.57778,605.17167 C 748.71184,594.63315 816.22265,569.6073 814.81537,525.97571 C 813.40809,482.34413 738.44784,397.28228 738.44784,397.28228 L 635.21025,581.13004 z"
-       id="path8003"
-       sodipodi:nodetypes="czzcc" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient3991);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8005"
-       sodipodi:cx="410"
-       sodipodi:cy="306.64789"
-       sodipodi:rx="23.214285"
-       sodipodi:ry="23.214285"
-       d="M 433.21428,306.64789 A 23.214285,23.214285 0 1 1 386.78572,306.64789 A 23.214285,23.214285 0 1 1 433.21428,306.64789 z"
-       transform="translate(449.67411,74.915393)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3981);enable-background:accumulate"
-       id="path8007"
-       sodipodi:cx="414.28571"
-       sodipodi:cy="303.07648"
-       sodipodi:rx="7.5"
-       sodipodi:ry="7.5"
-       d="M 421.78571,303.07648 A 7.5,7.5 0 1 1 406.78571,303.07648 A 7.5,7.5 0 1 1 421.78571,303.07648 z"
-       transform="translate(451.99554,73.486821)" />
-    <path
-       style="opacity:1;fill:url(#radialGradient4112);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 789.31696,478.349 C 789.31696,478.349 796.33977,497.91759 788.24553,513.349 C 780.15129,528.78041 745.92236,552.33722 720.74554,563.349 C 695.43582,574.41891 635.27254,596.31293 618.95982,605.31328 C 602.49834,614.39571 600.74554,617.99185 600.74554,617.99185 C 600.74554,617.99185 593.59861,598.92744 629.49553,566.20615 C 665.66764,533.23401 771.52265,518.15665 789.31696,478.349 z"
-       id="path8009"
-       sodipodi:nodetypes="czzzczc" />
-    <g
-       style="opacity:1;display:inline;enable-background:new"
-       id="g8011"
-       transform="translate(780.74553,74.55825)">
-      <path
-         transform="translate(-329.81481,0)"
-         clip-path="url(#clipPath3999)"
-         sodipodi:nodetypes="czzczzzszc"
-         id="path8013"
-         d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 335.34872,345.57268 330.35714,331.29075 C 325.36556,317.00882 329.12051,327.91101 328.41112,326.19774 C 317.72184,300.38182 294.1968,271.76744 263.92857,261.6479 C 233.66034,251.52836 198.91081,256.79953 179.64286,267.36218 z"
-         style="opacity:1;fill:url(#radialGradient3585);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
-      <path
-         transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-166.62245,2.387362)"
-         d="M 248.28731,338.07648 A 64.715881,134.00607 0 1 1 118.85555,338.07648 A 64.715881,134.00607 0 1 1 248.28731,338.07648 z"
-         sodipodi:ry="134.00607"
-         sodipodi:rx="64.715881"
-         sodipodi:cy="338.07648"
-         sodipodi:cx="183.57143"
-         id="path8015"
-         style="opacity:1;fill:url(#radialGradient4060);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-162.19388,-18.755495)"
-         d="M 248.28731,338.07648 A 64.715881,134.00607 0 1 1 118.85555,338.07648 A 64.715881,134.00607 0 1 1 248.28731,338.07648 z"
-         sodipodi:ry="134.00607"
-         sodipodi:rx="64.715881"
-         sodipodi:cy="338.07648"
-         sodipodi:cx="183.57143"
-         id="path8017"
-         style="opacity:1;fill:url(#radialGradient4062);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="translate(-329.81481,3e-7)"
-         clip-path="url(#clipPath3999)"
-         sodipodi:nodetypes="czzczzzszc"
-         id="path8019"
-         d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 335.34872,345.57268 330.35714,331.29075 C 325.36556,317.00882 329.12051,327.91101 328.41112,326.19774 C 317.72184,300.38182 294.1968,271.76744 263.92857,261.6479 C 233.66034,251.52836 198.91081,256.79953 179.64286,267.36218 z"
-         style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3587);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4079);enable-background:new" />
-    </g>
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8021"
-       sodipodi:cx="310.71429"
-       sodipodi:cy="398.07648"
-       sodipodi:rx="19.704132"
-       sodipodi:ry="19.704132"
-       d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z"
-       transform="translate(452.55663,72.581273)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient4056);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4082);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4083);enable-background:accumulate"
-       id="path8023"
-       sodipodi:cx="310.71429"
-       sodipodi:cy="398.07648"
-       sodipodi:rx="19.704132"
-       sodipodi:ry="19.704132"
-       d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z"
-       transform="translate(450.55663,72.581273)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient4119);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       id="path8025"
-       sodipodi:cx="310.71429"
-       sodipodi:cy="398.07648"
-       sodipodi:rx="19.704132"
-       sodipodi:ry="19.704132"
-       d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z"
-       transform="translate(450.55663,72.581273)" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4002);enable-background:accumulate"
-       id="path8027"
-       sodipodi:cx="429.56738"
-       sodipodi:cy="377.42877"
-       sodipodi:rx="72.079735"
-       sodipodi:ry="44.547726"
-       d="M 501.64712,377.42877 A 72.079735,44.547726 0 1 1 357.48765,377.42877 A 72.079735,44.547726 0 1 1 501.64712,377.42877 z"
-       transform="matrix(0.9969564,-7.7961675e-2,7.7961675e-2,0.9969564,436.61877,125.29509)"
-       inkscape:transform-center-x="-47.231976"
-       inkscape:transform-center-y="-3.6935079" />
-    <path
-       sodipodi:type="arc"
-       style="opacity:1;fill:url(#radialGradient4876);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4010);enable-background:accumulate"
-       id="path8029"
-       sodipodi:cx="437.6991"
-       sodipodi:cy="391.21735"
-       sodipodi:rx="36.611931"
-       sodipodi:ry="22.627417"
-       d="M 474.31103,391.21735 A 36.611931,22.627417 0 1 1 401.08717,391.21735 A 36.611931,22.627417 0 1 1 474.31103,391.21735 z"
-       transform="matrix(1.4357951,-6.9991037e-2,6.9991037e-2,1.4357951,235.18065,-63.86546)"
-       inkscape:transform-center-x="-20.955902"
-       inkscape:transform-center-y="-13.056625" />
-    <g
-       transform="translate(450.03125,73.843964)"
-       id="g8031"
-       style="opacity:1;display:inline;filter:url(#filter4053);enable-background:new">
-      <path
-         d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z"
-         sodipodi:ry="3.2142856"
-         sodipodi:rx="3.2142856"
-         sodipodi:cy="401.82648"
-         sodipodi:cx="413.66071"
-         id="path8033"
-         style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4484);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="translate(13.125009,8.1249913)"
-         d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z"
-         sodipodi:ry="3.2142856"
-         sodipodi:rx="3.2142856"
-         sodipodi:cy="401.82648"
-         sodipodi:cx="413.66071"
-         id="path8035"
-         style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4486);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="translate(32.946437,7.4999913)"
-         d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z"
-         sodipodi:ry="3.2142856"
-         sodipodi:rx="3.2142856"
-         sodipodi:cy="401.82648"
-         sodipodi:cx="413.66071"
-         id="path8037"
-         style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4488);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="translate(24.910723,-10.267866)"
-         d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z"
-         sodipodi:ry="3.2142856"
-         sodipodi:rx="3.2142856"
-         sodipodi:cy="401.82648"
-         sodipodi:cx="413.66071"
-         id="path8039"
-         style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4490);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-      <path
-         transform="translate(47.589294,-0.6250087)"
-         d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z"
-         sodipodi:ry="3.2142856"
-         sodipodi:rx="3.2142856"
-         sodipodi:cy="401.82648"
-         sodipodi:cx="413.66071"
-         id="path8041"
-         style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4492);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-         sodipodi:type="arc" />
-    </g>
-    <path
-       style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 896.20301,482.92837 C 897.1881,487.27845 900.74008,489.10785 903.58974,490.82019 C 908.05042,493.33311 910.1099,492.3423 912.74425,490.06258 C 914.3462,488.14141 923.42736,485.36393 928.33848,482.99151 C 932.66809,481.5326 937.24178,477.63278 941.723,474.65775 C 945.11814,473.03051 947.06964,475.01239 949.55168,475.6679 C 952.4958,476.38451 953.96285,477.83965 955.6126,479.20344 C 958.00876,480.37863 954.6847,482.34657 958.8956,483.49658 C 960.08651,483.71452 961.31255,484.07303 962.17859,482.99151"
-       id="path8043"
-       sodipodi:nodetypes="ccccccccc" />
-    <path
-       style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 910.85021,475.35223 C 913.16515,475.32025 914.02799,475.99476 916.34292,474.53148 C 919.79856,471.45035 921.74546,471.38671 924.29787,470.11206 C 927.32444,468.79683 930.83357,478.26375 934.3994,479.96105 C 936.79449,479.13963 935.68854,481.75484 935.85149,482.6127 C 935.90862,485.25954 938.65843,486.29076 940.20777,488.04227 C 943.52381,490.29776 947.583,494.33773 951.31945,493.34557 C 957.7647,490.4145 961.59867,492.06411 967.60816,485.95883 C 968.31221,484.77749 967.02391,479.06423 970.70175,478.76149 C 973.22574,479.01487 974.86842,478.81164 976.76267,479.32971 C 982.20367,481.4469 984.50045,485.77971 991.47301,487.28466 C 997.65591,488.25105 999.08565,491.07892 1005.3626,492.33542"
-       id="path8045"
-       sodipodi:nodetypes="cccccccccccc" />
-    <path
-       style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 876.98133,483.52197 C 879.37991,482.72817 883.08746,487.71407 885.15446,490.56765 C 885.74727,493.24717 886.30823,496.0541 885.91207,502.68948 C 886.6972,505.10702 888.59256,505.72043 890.7103,505.97248 C 893.82775,505.4357 896.58699,504.64818 898.0339,502.94202 C 899.9055,501.00035 903.34643,505.33596 906.11512,506.98263 C 909.72521,508.89472 913.8889,508.96149 917.98442,509.25547 C 919.688,509.02483 920.35482,513.77062 921.26741,517.3367 C 921.65155,521.71476 920.38197,524.23239 919.49965,527.18568 C 919.20535,529.68223 922.48815,530.71542 925.8131,531.73137 C 928.99554,532.47261 932.35734,533.39321 934.90447,533.49914 C 940.04633,534.37405 942.99321,536.18966 947.0263,537.53975 C 949.26544,538.3563 950.28649,539.78191 951.57199,541.07528"
-       id="path8047"
-       sodipodi:nodetypes="ccccccccccccc" />
-    <path
-       style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter8814);enable-background:new"
-       d="M 332,187.69519 C 332,187.69519 389.5,162.19519 389.5,159.69519 C 389.5,157.19519 395,107.69519 395,107.69519 C 395,107.69519 486,59.195189 486.5,57.195189 C 487,55.195189 572.5,-4.8048114 572.5,-4.8048114 L 386.5,17.195189 L 311,123.19519 L 332,187.69519 z"
-       id="path8049"
-       clip-path="url(#clipPath8514)"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 1697.2846,722.5514 C 1697.2846,722.5514 1581.3191,796.0905 1574.2481,800.33314 C 1567.177,804.57578 1343.7312,937.51186 1343.7312,937.51186 L 1347.9739,977.10984 L 1564.3486,876.70067 L 1681.7283,774.8773 L 1697.2846,722.5514 z"
-       id="path8051" />
-    <path
-       style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8810);enable-background:accumulate"
-       d="M 528.91587,556.85291 C 523.25902,555.4387 347.89654,631.80623 347.89654,631.80623 L 313.95541,812.82557 L 365.05087,1006.7738 L 622.25397,1074.4551 C 622.25397,1074.4551 828.72915,1227.1901 834.386,1222.9475 C 840.04286,1218.7049 1002.6774,1029.2002 1002.6774,1029.2002 L 842.87128,845.35248 L 796.20224,667.16157 L 528.91587,556.85291 z"
-       id="path8053"
-       clip-path="url(#clipPath8610)"
-       sodipodi:nodetypes="cccccscccc"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:#0c0c0c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 1097.6433,613.88997 C 1097.6433,613.88997 1120.2628,607.38316 1133.386,608.01724 C 1146.5093,608.65133 1164.0276,609.95586 1177.0949,620.20343 C 1190.1622,630.45099 1202.1626,647.3435 1211.2073,678.57308 C 1220.2519,709.80266 1212.9056,777.82509 1205.0312,821.92043 C 1197.1569,866.01577 1176.7661,928.03341 1160.0312,961.92043 C 1143.2964,995.80745 1110.2335,1039.4156 1099.4618,1051.7966 C 1088.0976,1064.8586 1043.2559,1088.2228 1020.0312,1094.0633 C 1025.3346,1083.4567 1068.931,1043.4744 1055.0312,1033.349 C 1041.0123,1023.1367 1009.2712,1079.3314 970.7381,1062.3822 C 992.12041,1049.2501 1012.5175,1011.1961 1004.7787,995.78772 C 996.93846,980.17733 974.07378,1044.5453 911.24317,1032.8006 C 941.29521,1005.2739 966.65023,961.89659 952.50587,949.8209 C 938.09071,937.51403 892.04412,1004.1141 892.04412,1004.1141 C 892.04412,1004.1141 889.22222,962.41287 905.81732,935.50673 C 922.45667,908.52886 985.47029,853.89146 1005.3704,823.80331 C 1025.2706,793.71517 1038.983,757.79429 1047.5059,731.28537 C 1056.0287,704.77645 1063.3068,654.18583 1063.3068,654.18583"
-       id="path8055"
-       sodipodi:nodetypes="czzzzzzczczczczzzc" />
-    <path
-       style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8818);enable-background:accumulate"
-       d="M 770.74639,609.17881 L 719.8347,706.75955 L 639.93163,817.77531 L 674.57987,889.19309 L 717.00628,968.38906 L 789.13117,923.13422 L 803.27331,730.80117 L 824.48651,592.20825 L 810.34437,502.05213 L 770.74639,609.17881 z"
-       id="path8057"
-       clip-path="url(#clipPath8622)"
-       sodipodi:nodetypes="cccccccccc"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8810);enable-background:accumulate"
-       d="M 295,846.19519 L 301.64488,777.27234 C 301.64488,777.27234 391.96439,866.27691 464,900.19519 C 536.03561,934.11347 772,962.19519 772,962.19519 L 926,936.19519 L 890,1098.1952 L 604,1124.1952 L 306,1035.1952 L 295,846.19519 z"
-       id="path8059"
-       clip-path="url(#clipPath8906)"
-       sodipodi:nodetypes="cczcccccc"
-       transform="translate(276,136)" />
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter3587);enable-background:new"
-       d="M 405.79629,845.99023 L 480.74961,911.04406 L 483.24924,927.92446 L 502.6526,938.08337 L 509.14464,961.13446 L 540.85369,952.76336 L 555.70293,1000.8466 C 567.95945,1013.5745 645.49637,887.7369 611.56436,1039.0304 L 550.75318,1055.2939 L 461.55026,960.60104 L 398.72523,906.80141 L 405.79629,845.99023 z"
-       id="path8061"
-       sodipodi:nodetypes="cccccccccccc"
-       clip-path="url(#clipPath3602)" />
-    <path
-       style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
-       d="M 1159.317,918.349 C 1213.6027,916.92043 1285.352,903.29701 1329.317,891.56328 C 1373.3697,879.80614 1455.2033,855.21604 1504.674,833.70614 C 1554.0133,812.25342 1618.2778,774.42454 1658.9599,741.56329 C 1699.468,708.8426 1711.3498,685.74348 1719.6741,707.99186 C 1728.0432,730.35965 1703.2672,764.31748 1681.817,789.06329 C 1660.2128,813.98669 1629.0856,841.76862 1582.8883,878.349 C 1536.691,914.92938 1426.8058,979.93363 1370.0312,1006.9204 C 1312.9652,1034.0458 1241.8279,1065.1589 1197.8884,1079.4205 C 1153.9489,1093.6821 1066.4598,1110.4919 1066.4598,1110.4919 L 1159.317,918.349 z"
-       id="path8063"
-       sodipodi:nodetypes="czzzzzzzzcc" />
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:0.5;fill:url(#linearGradient3666);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3779);enable-background:accumulate"
-       d="M 1241.5965,652.95007 C 1241.5965,652.95007 1176.875,707.28713 1095.9326,751.94501 C 1013.9082,797.19985 811.67556,845.28311 811.67556,845.28311 C 811.67556,845.28311 796.57419,866.33507 856.93045,873.56739 C 917.28671,880.79971 1081.0124,820.2667 1135.5306,777.40085 C 1190.0488,734.535 1255.7387,665.67799 1255.7387,665.67799 L 1241.5965,652.95007 z"
-       id="path8065"
-       sodipodi:nodetypes="czczzcc"
-       clip-path="url(#clipPath3992)" />
-    <g
-       transform="translate(450.03125,73.843964)"
-       style="opacity:1;display:inline;enable-background:new"
-       id="g8067"
-       clip-path="url(#clipPath3986)">
-      <g
-         transform="translate(-174.03125,62.156036)"
-         style="filter:url(#filter3677)"
-         id="g8069">
-        <g
-           style="filter:url(#filter3785)"
-           id="g8071">
-          <path
-             sodipodi:nodetypes="czzccccc"
-             id="path8073"
-             d="M 1094.2857,725.93361 C 1094.2857,725.93361 1093.9896,752.09452 1098.9285,763.79076 C 1103.8674,775.487 1118.9666,790.27741 1127.5,795.21933 C 1136.0334,800.16125 1146.4286,803.79075 1146.4286,803.79075 L 1264.2857,688.79075 L 1282.1429,613.07647 L 1185.7143,651.6479 L 1094.2857,725.93361 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-             transform="translate(174.03125,-62.156036)" />
-          <rect
-             y="486.14224"
-             x="1197.8389"
-             height="309.71277"
-             width="333.75412"
-             id="rect8075"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-      </g>
-      <g
-         transform="translate(-174.03125,62.156036)"
-         style="opacity:0.18000004;display:inline;enable-background:new"
-         id="g8077">
-        <g
-           style="filter:url(#filter3785)"
-           id="g8079">
-          <path
-             sodipodi:nodetypes="czzccccc"
-             id="path8081"
-             d="M 1094.2857,725.93361 C 1094.2857,725.93361 1093.9896,752.09452 1098.9285,763.79076 C 1103.8674,775.487 1118.9666,790.27741 1127.5,795.21933 C 1136.0334,800.16125 1146.4286,803.79075 1146.4286,803.79075 L 1264.2857,688.79075 L 1282.1429,613.07647 L 1185.7143,651.6479 L 1094.2857,725.93361 z"
-             style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-             transform="translate(174.03125,-62.156036)" />
-          <rect
-             y="486.14224"
-             x="1197.8389"
-             height="309.71277"
-             width="333.75412"
-             id="rect8083"
-             style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-        </g>
-      </g>
-    </g>
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:0.83300003;fill:#050505;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:15;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8225);enable-background:accumulate"
-       d="M 1264.1875,605 C 1259.6964,605.73268 1256.0305,608.45509 1252.25,611.40625 C 1242.1687,619.27601 1224.0805,645.83149 1204.2188,661.875 C 1164.3514,694.07816 1100.2228,731.85201 1051.6562,752.96875 C 1003.0422,774.10613 921.11498,798.78676 877.34375,810.46875 C 833.94554,822.05121 762.29972,835.59982 709.09375,837 L 704.53125,837.125 L 702.53125,841.25 L 609.6875,1033.375 L 603.1875,1046.8438 L 617.84375,1044 C 617.84375,1044 705.11343,1027.3486 750.1875,1012.7188 C 794.9127,998.20213 865.97836,967.05197 923.21875,939.84375 C 980.82199,912.46306 1090.1551,847.86412 1137.5,810.375 C 1183.8608,773.66518 1215.3049,745.65818 1237.4375,720.125 C 1248.3386,707.549 1260.1823,692.59356 1268.4688,677.375 C 1276.7552,662.15644 1287.6285,633.15692 1282.1562,618.53125 C 1280.9385,615.27651 1279.6048,612.46995 1277.5625,610.03125 C 1275.5202,607.59255 1269.0878,608.45926 1269,605 C 1268.7902,596.73518 1265.6845,604.75577 1264.1875,605 z M 1266.3438,620.21875 C 1266.7586,620.80449 1267.3749,621.77641 1268.125,623.78125 C 1271.0218,631.52338 1266.6843,655.68 1259.3125,669.21875 C 1251.9407,682.7575 1236.6741,698.14269 1226.125,710.3125 C 1205.0496,734.62606 1174.2213,762.17406 1128.1875,798.625 C 1083.1379,834.29659 972.72717,899.71959 916.78125,926.3125 C 859.88952,953.35499 788.68509,984.4309 745.53125,998.4375 C 709.16634,1010.2406 649.68654,1022.2713 629.8125,1026.2188 L 714.09375,851.75 C 768.80066,849.7007 837.88634,836.53365 881.21875,824.96875 C 925.55297,813.1365 1007.2974,788.63242 1057.625,766.75 C 1107.737,744.96129 1170.1594,705.58184 1211.6562,672.0625 C 1232.3026,655.38529 1253.4011,629.51662 1261.4688,623.21875 C 1263.9058,621.31633 1265.5494,620.58295 1266.3438,620.21875 z"
-       id="path8085"
-       clip-path="url(#clipPath3722)"
-       sodipodi:nodetypes="cssssccccccssssssssccssssssccssssc" />
-    <g
-       style="opacity:1;display:inline;enable-background:new"
-       id="g8087"
-       mask="url(#mask7704)"
-       transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
-       inkscape:transform-center-x="-185.09603"
-       inkscape:transform-center-y="-12.859654">
-      <path
-         transform="translate(8.0045714e-2,-3.125e-2)"
-         style="fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-         d="M 1111.4062,-285.9375 L 1107.4688,-284.0625 C 1107.4283,-284.05228 1107.3692,-284.04201 1107.3438,-284.03125 C 1106.925,-283.8184 1107.1791,-283.93067 1106.6875,-283.71875 C 1106.2014,-283.50919 1104.9499,-283.13456 1102.5938,-282.25 C 1099.2626,-280.99942 1096.7895,-280.10016 1095.5938,-279.1875 C 1094.0576,-279.16623 1091.8733,-278.95419 1089.9375,-278.46875 C 1086.956,-277.72108 1085.0823,-277.29474 1083.1875,-276.875 C 1081.2927,-276.45527 1081.512,-276.23281 1080.3125,-276 C 1079.0159,-275.74833 1078.5911,-276.00899 1074.875,-275.21875 C 1071.3851,-274.4766 1065.9802,-273.28768 1064.7188,-272.53125 C 1063.1348,-272.71203 1060.8513,-272.85303 1058.875,-272.5625 C 1055.8346,-272.11554 1053.9588,-271.88974 1052.0312,-271.65625 C 1051.3758,-271.57687 1050.9902,-271.45547 1050.6875,-271.375 C 1050.2613,-271.24334 1050.0017,-271.11498 1049.3125,-271.03125 C 1048.0009,-270.87188 1047.5503,-271.18808 1043.7812,-270.75 C 1040.2273,-270.33691 1034.7758,-269.47718 1033.5312,-268.8125 C 1031.9322,-269.10979 1029.6735,-269.34669 1027.6875,-269.15625 C 1024.6287,-268.86293 1022.7155,-268.67226 1020.7812,-268.5 C 1018.847,-268.32773 1019.0926,-268.07763 1017.875,-267.96875 C 1016.5588,-267.85105 1016.1152,-268.13238 1012.3438,-267.71875 C 1008.8017,-267.3303 1003.3359,-266.50948 1002.0625,-265.84375 C 1000.4636,-266.13844 998.1753,-266.35076 996.1875,-266.15625 C 993.12921,-265.857 991.2463,-265.67601 989.3125,-265.5 C 988.65501,-265.44015 988.27245,-265.32144 987.96875,-265.25 C 987.54105,-265.13104 987.28525,-265.03193 986.59375,-264.96875 C 985.27775,-264.84849 984.834,-265.16363 981.0625,-264.75 C 977.50631,-264.35998 972.0569,-263.51084 970.8125,-262.84375 C 969.21381,-263.13793 966.95265,-263.36747 964.96875,-263.15625 C 961.91305,-262.83092 959.9947,-262.63001 958.0625,-262.4375 C 956.13031,-262.24499 956.37275,-261.99662 955.15625,-261.875 C 953.84137,-261.74353 953.3932,-262.03954 949.625,-261.59375 C 946.08611,-261.17509 940.6473,-260.30158 939.375,-259.625 C 937.77741,-259.90604 935.51505,-260.04543 933.53125,-259.8125 C 930.47927,-259.45413 928.58625,-259.24464 926.65625,-259.03125 C 926.00007,-258.95869 925.6156,-258.85856 925.3125,-258.78125 C 924.88571,-258.65402 924.6276,-258.51405 923.9375,-258.4375 C 922.62411,-258.29181 922.17015,-258.61152 918.40625,-258.125 C 914.85737,-257.66624 909.4276,-256.70598 908.1875,-256 C 906.59441,-256.24424 904.3537,-256.38135 902.375,-256.125 C 899.32741,-255.73018 897.4243,-255.47655 895.5,-255.21875 C 893.57571,-254.96096 893.7739,-254.72522 892.5625,-254.5625 C 891.25301,-254.3866 890.8153,-254.66688 887.0625,-254.09375 C 883.53821,-253.55551 878.1393,-252.39458 876.875,-251.65625 C 875.28751,-251.85979 873.0295,-251.91098 871.0625,-251.5625 C 868.03631,-251.02638 866.1636,-250.70081 864.25,-250.375 C 863.59941,-250.26423 863.2363,-250.10406 862.9375,-250 C 862.51681,-249.83512 862.27405,-249.6687 861.59375,-249.53125 C 860.29905,-249.26966 859.86665,-249.53745 856.15625,-248.71875 C 852.65777,-247.9468 847.31035,-246.33582 846.09375,-245.5 C 844.53085,-245.57745 842.33625,-245.41472 840.40625,-244.90625 C 837.43387,-244.12312 835.58855,-243.67416 833.71875,-243.15625 C 831.84875,-242.63835 832.0521,-242.38897 830.875,-242.0625 C 829.60251,-241.7096 829.17795,-241.95541 825.53125,-240.875 C 822.10657,-239.86037 816.88185,-237.94183 815.65625,-237.03125 C 814.11747,-237.01851 811.93645,-236.75903 810.03125,-236.15625 C 807.10027,-235.22891 805.2809,-234.69783 803.4375,-234.09375 C 802.81071,-233.88837 802.44585,-233.70117 802.15625,-233.5625 C 801.74867,-233.34889 801.50295,-233.15375 800.84375,-232.9375 C 799.58925,-232.52596 799.1576,-232.74846 795.5625,-231.5 C 792.17261,-230.32283 786.96755,-228.2863 785.78125,-227.34375 C 784.25737,-227.28408 782.1312,-226.94888 780.25,-226.28125 C 777.35261,-225.25296 775.55095,-224.60577 773.71875,-223.96875 C 771.88655,-223.33174 772.0909,-223.12021 770.9375,-222.71875 C 769.69071,-222.28479 769.27395,-222.51903 765.71875,-221.15625 C 762.38005,-219.87645 757.23165,-217.6737 756.03125,-216.6875 C 754.52407,-216.57981 752.39555,-216.1887 750.53125,-215.46875 C 747.66307,-214.36115 745.90735,-213.68719 744.09375,-213 C 743.47705,-212.76637 743.0973,-212.55797 742.8125,-212.40625 C 742.81251,-212.40625 742.8125,-212.37673 742.8125,-212.375 L 734.8125,-209.1875 L 722.3366,-205.69561 L 730.26626,-186.41789 C 729.67463,-184.44432 742.8125,-191.15625 742.8125,-191.15625 C 743.03891,-191.30093 743.26145,-191.42886 743.53125,-191.53125 C 744.61177,-191.94123 745.70285,-191.74702 749.53125,-193.21875 C 753.35977,-194.69049 754.7553,-195.22373 755.4375,-195.625 C 756.11711,-196.02478 757.04925,-196.50437 757.65625,-197.15625 C 759.48317,-197.294 761.22705,-197.64948 762.59375,-198.15625 C 765.56175,-199.25677 767.4691,-199.96244 769.375,-200.625 C 771.28081,-201.28754 771.72915,-202.03987 772.78125,-202.40625 C 773.87287,-202.78636 774.97635,-202.57163 778.84375,-203.9375 C 782.71115,-205.30336 784.1269,-205.76458 784.8125,-206.15625 C 785.51361,-206.55677 786.5133,-207.08923 787.125,-207.75 C 789.09581,-207.80466 790.94195,-208.13463 792.40625,-208.625 C 795.40777,-209.63008 797.3324,-210.24671 799.25,-210.875 C 800.78861,-211.3791 801.42415,-211.92177 802.15625,-212.3125 C 802.38647,-212.44681 802.63215,-212.56623 802.90625,-212.65625 C 804.00457,-213.01673 805.0877,-212.73762 809,-213.96875 C 812.91231,-215.19988 814.366,-215.6417 815.0625,-216 C 815.75641,-216.35697 816.6926,-216.79261 817.3125,-217.40625 C 819.17771,-217.42891 820.94835,-217.67308 822.34375,-218.09375 C 825.37415,-219.00729 827.33615,-219.52385 829.28125,-220.0625 C 831.22637,-220.60114 831.70745,-221.32702 832.78125,-221.625 C 833.89527,-221.93415 835.00125,-221.61761 838.96875,-222.65625 C 842.93625,-223.69488 844.38625,-224.08898 845.09375,-224.40625 C 845.82855,-224.73584 846.90765,-225.15997 847.53125,-225.78125 C 849.52907,-225.66525 851.3887,-225.80134 852.875,-226.15625 C 855.95311,-226.89125 857.9584,-227.25719 859.9375,-227.65625 C 861.52541,-227.97643 862.1818,-228.4468 862.9375,-228.75 C 863.17501,-228.8568 863.4044,-228.94276 863.6875,-229 C 864.82091,-229.22919 865.99215,-228.79107 870.03125,-229.5 C 874.07067,-230.20893 875.5315,-230.42709 876.25,-230.6875 C 876.96581,-230.94694 877.95435,-231.25474 878.59375,-231.78125 C 880.51795,-231.54176 882.34165,-231.55672 883.78125,-231.78125 C 886.90767,-232.26887 888.9358,-232.48192 890.9375,-232.75 C 892.93921,-233.01807 893.42625,-233.69514 894.53125,-233.84375 C 895.67767,-233.99793 896.8071,-233.54218 900.875,-234.0625 C 904.94281,-234.58282 906.43525,-234.75823 907.15625,-235 C 907.89337,-235.24714 908.95435,-235.58623 909.59375,-236.125 C 911.64375,-235.78947 913.56745,-235.72704 915.09375,-235.90625 C 918.23595,-236.27521 920.27375,-236.46561 922.28125,-236.6875 C 923.89207,-236.86552 924.5459,-237.2957 925.3125,-237.53125 C 925.55341,-237.61677 925.80655,-237.68685 926.09375,-237.71875 C 927.24345,-237.84647 928.39505,-237.3721 932.46875,-237.84375 C 936.54245,-238.3154 938.0278,-238.45435 938.75,-238.6875 C 939.46941,-238.91977 940.45025,-239.16096 941.09375,-239.65625 C 943.03005,-239.32279 944.8638,-239.25201 946.3125,-239.40625 C 949.45851,-239.7412 951.49,-239.92484 953.5,-240.125 C 955.50991,-240.32514 955.98415,-240.95139 957.09375,-241.0625 C 958.24485,-241.17778 959.39025,-240.69744 963.46875,-241.125 C 967.54725,-241.55256 969.05765,-241.68709 969.78125,-241.90625 C 970.52047,-242.13011 971.57685,-242.4195 972.21875,-242.9375 C 974.27575,-242.53883 976.2206,-242.4441 977.75,-242.59375 C 980.89871,-242.90185 982.9258,-243.067 984.9375,-243.25 C 986.55151,-243.39682 987.20055,-243.81055 987.96875,-244.03125 C 988.21005,-244.11211 988.4623,-244.16116 988.75,-244.1875 C 989.90211,-244.29295 991.0429,-243.79475 995.125,-244.1875 C 999.20711,-244.58025 1000.7139,-244.71834 1001.4375,-244.9375 C 1002.1584,-245.15583 1003.1371,-245.3852 1003.7812,-245.875 C 1005.7193,-245.52501 1007.5501,-245.42062 1009,-245.5625 C 1012.1487,-245.8706 1014.1758,-246.03575 1016.1875,-246.21875 C 1018.1991,-246.40174 1018.7017,-247.05677 1019.8125,-247.15625 C 1020.9648,-247.25948 1022.1047,-246.77142 1026.1875,-247.15625 C 1030.2704,-247.54107 1031.7762,-247.65725 1032.5,-247.875 C 1033.2393,-248.09743 1034.2956,-248.38949 1034.9375,-248.90625 C 1036.9949,-248.50448 1038.9404,-248.40292 1040.4688,-248.5625 C 1043.6153,-248.89102 1045.6458,-249.0852 1047.6562,-249.28125 C 1049.2692,-249.43854 1049.9219,-249.91273 1050.6875,-250.15625 C 1050.9282,-250.24429 1051.1507,-250.27762 1051.4375,-250.3125 C 1052.5858,-250.4522 1053.7542,-249.97259 1057.8125,-250.5625 C 1061.8708,-251.15242 1063.3743,-251.33964 1064.0938,-251.59375 C 1064.8104,-251.84691 1065.7684,-252.15182 1066.4062,-252.6875 C 1068.3259,-252.47556 1070.1262,-252.53609 1071.5625,-252.78125 C 1074.6816,-253.31365 1076.6741,-253.70986 1078.6562,-254.09375 C 1080.6383,-254.47762 1081.1305,-255.1334 1082.2188,-255.375 C 1083.3475,-255.62566 1084.489,-255.25871 1088.4688,-256.25 C 1092.4483,-257.24127 1093.8983,-257.6693 1094.5938,-258.03125 C 1095.316,-258.40725 1096.3555,-258.90183 1096.9688,-259.5625 C 1098.9317,-259.57454 1100.7625,-259.85355 1102.1875,-260.40625 C 1105.1387,-261.55085 1107.0607,-262.27567 1108.875,-263.15625 C 1110.3307,-263.86277 1111.1941,-264.85828 1111.4062,-265.15625 C 1111.6185,-265.4542 1111.5051,-265.8848 1111.5312,-265.90625 C 1111.5742,-265.94148 1111.8716,-266.00028 1112.0312,-266.34375 C 1112.8902,-268.19082 1114.3544,-271.97139 1114.4688,-272.65625 C 1114.5825,-273.33839 1114.6368,-274.00902 1114.6875,-274.40625 C 1114.7169,-274.63575 1114.5404,-275.28515 1114.5625,-275.34375 C 1114.5934,-275.42579 1114.8508,-275.59432 1114.9062,-275.84375 C 1115.1725,-277.04206 1114.9953,-278.05111 1114.7812,-279.46875 C 1114.5673,-280.88638 1113.8096,-284.08338 1113.1562,-284.9375 C 1112.4973,-285.79922 1111.9314,-285.94801 1111.4062,-285.9375 z"
-         id="path8089"
-         sodipodi:nodetypes="ccssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssscccccssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssssssssc" />
-      <g
-         clip-path="url(#clipPath7421)"
-         id="g8091">
-        <path
-           id="path8093"
-           d="M 1107.409,-284.04961 C 1106.9903,-283.83678 1107.2534,-283.95572 1106.7618,-283.7438 C 1106.2757,-283.53426 1105.0384,-283.16941 1102.6822,-282.28485 C 1099.3511,-281.03428 1096.852,-280.13141 1095.6563,-279.21875 C 1094.1202,-279.19749 1091.9358,-278.98544 1090,-278.5 C 1087.0185,-277.75234 1085.1448,-277.32599 1083.25,-276.90625 C 1081.3552,-276.48653 1081.5745,-276.26406 1080.375,-276.03125 C 1079.0784,-275.77959 1078.6536,-276.04024 1074.9375,-275.25 C 1071.4476,-274.50786 1066.0427,-273.31893 1064.7813,-272.5625 C 1063.1974,-272.74329 1060.9138,-272.88428 1058.9375,-272.59375 C 1055.8971,-272.1468 1054.0213,-271.92099 1052.0938,-271.6875 C 1051.4384,-271.60813 1051.0527,-271.48672 1050.75,-271.40625 C 1050.3238,-271.2746 1050.0642,-271.14623 1049.375,-271.0625 C 1048.0634,-270.90314 1047.6128,-271.21933 1043.8438,-270.78125 C 1040.2899,-270.36817 1034.8384,-269.50843 1033.5938,-268.84375 C 1031.9948,-269.14105 1029.736,-269.37794 1027.75,-269.1875 C 1024.6912,-268.89419 1022.778,-268.70351 1020.8438,-268.53125 C 1018.9095,-268.35899 1019.1551,-268.10888 1017.9375,-268 C 1016.6213,-267.88231 1016.1777,-268.16363 1012.4063,-267.75 C 1008.8644,-267.36156 1003.3984,-266.54073 1002.125,-265.875 C 1000.5261,-266.1697 998.23783,-266.38201 996.25,-266.1875 C 993.19176,-265.88826 991.30887,-265.70726 989.375,-265.53125 C 988.71751,-265.47141 988.33496,-265.35269 988.03125,-265.28125 C 987.6036,-265.1623 987.34774,-265.06318 986.65625,-265 C 985.34029,-264.87975 984.89649,-265.19488 981.125,-264.78125 C 977.56886,-264.39124 972.11946,-263.54209 970.875,-262.875 C 969.27637,-263.16919 967.01516,-263.39872 965.03125,-263.1875 C 961.97565,-262.86218 960.05721,-262.66126 958.125,-262.46875 C 956.19279,-262.27625 956.43513,-262.02787 955.21875,-261.90625 C 953.90387,-261.77479 953.45577,-262.07079 949.6875,-261.625 C 946.14863,-261.20635 940.70982,-260.33283 939.4375,-259.65625 C 937.83995,-259.9373 935.57754,-260.07668 933.59375,-259.84375 C 930.54177,-259.48539 928.64867,-259.27589 926.71875,-259.0625 C 926.06255,-258.98995 925.67809,-258.88981 925.375,-258.8125 C 924.94823,-258.68528 924.69009,-258.5453 924,-258.46875 C 922.68667,-258.32307 922.23254,-258.64277 918.46875,-258.15625 C 914.91986,-257.6975 909.49012,-256.73723 908.25,-256.03125 C 906.65695,-256.27549 904.41619,-256.4126 902.4375,-256.15625 C 899.38991,-255.76144 897.48679,-255.5078 895.5625,-255.25 C 893.63822,-254.99221 893.83639,-254.75647 892.625,-254.59375 C 891.31554,-254.41785 890.87781,-254.69813 887.125,-254.125 C 883.60071,-253.58676 878.20185,-252.42583 876.9375,-251.6875 C 875.35,-251.89104 873.092,-251.94223 871.125,-251.59375 C 868.09883,-251.05763 866.22611,-250.73206 864.3125,-250.40625 C 863.66189,-250.29548 863.29879,-250.13531 863,-250.03125 C 862.57933,-249.86637 862.33655,-249.69995 861.65625,-249.5625 C 860.3616,-249.30091 859.92913,-249.5687 856.21875,-248.75 C 852.72022,-247.97805 847.3728,-246.36707 846.15625,-245.53125 C 844.59347,-245.6087 842.39867,-245.44597 840.46875,-244.9375 C 837.49631,-244.15437 835.65114,-243.70541 833.78125,-243.1875 C 831.91137,-242.6696 832.11465,-242.42022 830.9375,-242.09375 C 829.66504,-241.74085 829.24047,-241.98666 825.59375,-240.90625 C 822.16905,-239.89162 816.94431,-237.97308 815.71875,-237.0625 C 814.17992,-237.04976 811.99892,-236.79028 810.09375,-236.1875 C 807.16269,-235.26016 805.34344,-234.72908 803.5,-234.125 C 802.87324,-233.91962 802.50827,-233.73242 802.21875,-233.59375 C 801.81112,-233.38014 801.56541,-233.185 800.90625,-232.96875 C 799.65179,-232.55721 799.22014,-232.77971 795.625,-231.53125 C 792.23515,-230.35408 787.03002,-228.31755 785.84375,-227.375 C 784.31986,-227.31533 782.1937,-226.98013 780.3125,-226.3125 C 777.41511,-225.28421 775.61342,-224.63702 773.78125,-224 C 771.94908,-223.36299 772.1534,-223.15146 771,-222.75 C 769.75322,-222.31604 769.33639,-222.55028 765.78125,-221.1875 C 762.44258,-219.9077 757.2941,-217.70495 756.09375,-216.71875 C 754.58657,-216.61106 752.45806,-216.21995 750.59375,-215.5 C 747.72557,-214.3924 745.96995,-213.71844 744.15625,-213.03125 C 743.53959,-212.79762 743.15984,-212.58922 742.875,-212.4375 C 742.875,-212.4375 742.875,-211.34375 742.875,-211.34375 C 742.98678,-211.56611 743.26099,-212.16118 743.78125,-212.4375 C 744.47922,-212.80822 748.59488,-214.43087 750.59375,-215.15625 C 752.25061,-215.7575 754.74764,-216.48493 756.5625,-216.46875 C 756.86412,-216.46606 757.15012,-216.41785 757.40625,-216.375 C 759.24874,-216.06675 764.875,-214.8125 764.875,-214.8125 C 764.87499,-214.8125 758.64151,-216.45925 757.84375,-216.65625 C 757.65296,-216.70336 757.30803,-216.72497 756.875,-216.71875 C 758.02046,-217.58846 761.636,-219.11226 764.21875,-220.15625 C 767.05697,-221.30352 767.33556,-221.40807 769.28125,-221.8125 C 771.28955,-222.22994 772.4375,-222.3125 772.4375,-222.3125 C 772.4375,-222.31249 772.35514,-222.91364 773.40625,-223.4375 C 774.11135,-223.78891 778.29327,-225.3299 780.3125,-226 C 782.2644,-226.64773 785.3699,-227.3585 787.1875,-227 C 789.05073,-226.6325 794.71875,-225.1875 794.71875,-225.1875 C 794.71876,-225.1875 788.43175,-227.05861 787.625,-227.28125 C 787.43208,-227.3345 787.09416,-227.36729 786.65625,-227.375 C 787.81459,-228.20788 791.45069,-229.57032 794.0625,-230.53125 C 796.93266,-231.58726 797.22984,-231.69305 799.1875,-232.0625 C 801.04099,-232.41229 802.04634,-232.48798 802.21875,-232.5 C 802.33235,-232.71724 802.5962,-233.31002 803.125,-233.5625 C 803.83444,-233.90124 808.05107,-235.27525 810.09375,-235.875 C 811.78692,-236.37211 814.33452,-236.91177 816.1875,-236.78125 C 816.49545,-236.75957 816.80099,-236.68399 817.0625,-236.625 C 818.94368,-236.20068 824.65625,-234.59375 824.65625,-234.59375 C 824.65626,-234.59375 818.31451,-236.659 817.5,-236.90625 C 817.30521,-236.96539 816.94212,-237.01019 816.5,-237.03125 C 817.66949,-237.8288 821.36302,-239.08747 824,-239.96875 C 826.89781,-240.93722 827.23301,-240.97207 829.21875,-241.25 C 831.2684,-241.53689 832.40625,-241.5625 832.40625,-241.5625 C 832.40623,-241.5625 832.3335,-242.16947 833.40625,-242.625 C 834.12585,-242.93057 838.39723,-244.12575 840.46875,-244.625 C 842.47119,-245.10758 845.66724,-245.55329 847.53125,-245.03125 C 849.44203,-244.4961 855.25,-242.53125 855.25,-242.53125 C 855.25,-242.53125 848.82734,-244.95476 848,-245.25 C 847.80216,-245.32061 847.41784,-245.39039 846.96875,-245.4375 C 848.15665,-246.16615 851.88402,-247.21158 854.5625,-247.9375 C 857.50592,-248.73525 857.85458,-248.70833 859.875,-248.84375 C 861.78789,-248.97198 862.82205,-248.91484 863,-248.90625 C 863.11728,-249.10991 863.39176,-249.68573 863.9375,-249.875 C 864.66969,-250.12894 869.01602,-250.92289 871.125,-251.25 C 872.87313,-251.52111 875.52588,-251.7347 877.4375,-251.34375 C 877.75516,-251.27879 878.04272,-251.15824 878.3125,-251.0625 C 880.25324,-250.37377 886.15625,-247.96875 886.15625,-247.96875 C 886.15626,-247.96875 879.62154,-250.91952 878.78125,-251.28125 C 878.58028,-251.36776 878.20612,-251.44804 877.75,-251.53125 C 878.9565,-252.16443 882.77956,-252.92685 885.5,-253.4375 C 888.48953,-253.99869 888.80023,-253.96704 890.84375,-253.96875 C 892.95301,-253.97052 894.15625,-253.84375 894.15625,-253.84375 C 894.15625,-253.84374 894.08354,-254.47494 895.1875,-254.78125 C 895.92802,-254.98672 900.31362,-255.61512 902.4375,-255.84375 C 904.49052,-256.06474 907.75613,-256.09597 909.65625,-255.375 C 911.60404,-254.63593 917.5,-252 917.5,-252 C 917.50002,-252 910.93712,-255.17897 910.09375,-255.5625 C 909.89207,-255.65423 909.55154,-255.74871 909.09375,-255.84375 C 910.30467,-256.44563 914.07817,-257.09259 916.8125,-257.5 C 919.8173,-257.94772 920.13801,-257.9517 922.1875,-257.90625 C 924.12795,-257.86323 925.19449,-257.71202 925.375,-257.6875 C 925.49392,-257.88066 925.7589,-258.45333 926.3125,-258.59375 C 927.05521,-258.78213 931.46679,-259.32803 933.59375,-259.53125 C 935.35678,-259.69967 938.01384,-259.76554 939.9375,-259.28125 C 940.25718,-259.20077 940.54101,-259.07766 940.8125,-258.96875 C 942.76543,-258.18526 948.71875,-255.5 948.71875,-255.5 C 948.71873,-255.5 942.12684,-258.75348 941.28125,-259.15625 C 941.07903,-259.25257 940.70899,-259.36328 940.25,-259.46875 C 941.46414,-260.04302 945.29366,-260.59094 948.03125,-260.96875 C 951.03963,-261.38395 951.35432,-261.41138 953.40625,-261.34375 C 955.52423,-261.27394 956.71875,-261.09375 956.71875,-261.09375 C 956.71873,-261.09375 956.6415,-261.73116 957.75,-262 C 958.49362,-262.18035 962.90176,-262.66355 965.03125,-262.84375 C 967.08972,-263.01792 970.37449,-262.96807 972.28125,-262.1875 C 974.23584,-261.38734 980.15625,-258.65625 980.15625,-258.65625 C 980.15623,-258.65625 973.59632,-261.96501 972.75,-262.375 C 972.54763,-262.47305 972.17814,-262.5781 971.71875,-262.6875 C 972.93392,-263.2514 976.72883,-263.8018 979.46875,-264.15625 C 982.47966,-264.54577 982.79006,-264.5539 984.84375,-264.46875 C 986.78814,-264.38815 987.85038,-264.21551 988.03125,-264.1875 C 988.15041,-264.37836 988.41402,-264.93281 988.96875,-265.0625 C 989.71301,-265.2365 994.11868,-265.71297 996.25,-265.875 C 998.01662,-266.00927 1000.6997,-266.00071 1002.625,-265.5 C 1002.945,-265.41679 1003.2283,-265.29873 1003.5,-265.1875 C 1005.4546,-264.38734 1011.4063,-261.625 1011.4063,-261.625 C 1011.4062,-261.625 1004.8151,-264.96501 1003.9688,-265.375 C 1003.7664,-265.47305 1003.3969,-265.57811 1002.9375,-265.6875 C 1004.1526,-266.2514 1007.9788,-266.77056 1010.7188,-267.125 C 1013.7297,-267.51453 1014.0713,-267.5539 1016.125,-267.46875 C 1018.2447,-267.38087 1019.4375,-267.15625 1019.4375,-267.15625 C 1019.4375,-267.15625 1019.3591,-267.80527 1020.4688,-268.0625 C 1021.2131,-268.23506 1025.6183,-268.68586 1027.75,-268.84375 C 1029.8106,-268.99635 1033.0929,-268.94052 1035,-268.15625 C 1036.955,-267.3523 1042.875,-264.65625 1042.875,-264.65625 C 1042.875,-264.65625 1036.3152,-267.93212 1035.4688,-268.34375 C 1035.2663,-268.44219 1034.897,-268.54597 1034.4375,-268.65625 C 1035.6529,-269.21779 1039.4494,-269.78403 1042.1875,-270.15625 C 1045.1965,-270.5653 1045.5102,-270.57183 1047.5625,-270.5 C 1049.5056,-270.43201 1050.5697,-270.33515 1050.75,-270.3125 C 1050.8688,-270.5069 1051.1346,-271.04131 1051.6875,-271.1875 C 1052.4293,-271.38362 1056.8186,-272.01628 1058.9375,-272.28125 C 1060.6939,-272.50086 1063.3428,-272.61356 1065.25,-272.25 C 1065.5669,-272.18959 1065.8558,-272.06062 1066.125,-271.96875 C 1068.0612,-271.30783 1073.9688,-269.03125 1073.9688,-269.03125 C 1073.9687,-269.03125 1067.4321,-271.8378 1066.5938,-272.1875 C 1066.3933,-272.27113 1066.0176,-272.36083 1065.5625,-272.4375 C 1066.7662,-273.08796 1070.5816,-273.80945 1073.2813,-274.4375 C 1076.248,-275.1277 1076.5702,-275.19257 1078.5938,-275.3125 C 1080.6824,-275.4363 1081.875,-275.34375 1081.875,-275.34375 C 1081.875,-275.34374 1081.788,-275.9758 1082.875,-276.375 C 1083.6042,-276.6428 1087.9222,-277.71297 1090,-278.1875 C 1092.0085,-278.64619 1095.1679,-279.2168 1097,-278.8125 C 1098.8781,-278.39804 1110.5782,-275.79687 1110.5782,-275.79687 C 1110.5782,-275.79687 1098.2507,-278.81953 1097.4375,-279.0625 C 1097.243,-279.12062 1096.8789,-279.16876 1096.4375,-279.1875 C 1097.6051,-279.99119 1099.9517,-280.8748 1102.5469,-281.89062 C 1104.2283,-282.5488 1103.4706,-282.26721 1105.3228,-282.89422 C 1107.0764,-283.48788 1107.8082,-283.90493 1107.9532,-284.00721 C 1108.2993,-284.21372 1107.5972,-284.12909 1107.409,-284.04961 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7001);enable-background:new"
-           sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" />
-        <path
-           id="path8095"
-           d="M 1082.625,-275.125 C 1084.498,-274.73152 1087.1211,-273.97945 1088.6563,-273.15625 C 1090.1915,-272.33306 1091.4785,-272.10025 1094.0313,-270.65625 C 1096.5579,-269.22699 1098.8271,-268.64929 1101,-268.125 C 1103.3476,-267.55858 1106.4354,-267.40977 1109.8438,-266.9375 C 1108.7549,-267.77725 1103.2364,-268.10995 1101.4375,-268.5 C 1099.6386,-268.89006 1097.5434,-269.51616 1094.8438,-270.8125 C 1092.1441,-272.10884 1091.3494,-272.61146 1089.0313,-273.5 C 1086.7131,-274.38854 1085.0269,-274.88314 1082.625,-275.125 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6949);enable-background:new" />
-        <path
-           id="path8097"
-           d="M 1051.4688,-270 C 1053.3741,-269.42241 1055.9969,-268.38428 1057.5625,-267.40625 C 1059.1281,-266.42823 1060.4427,-266.04644 1063.0625,-264.28125 C 1065.6555,-262.53409 1068.0484,-261.57198 1070.3125,-260.6875 C 1072.7586,-259.73193 1075.9951,-259.03037 1079.7188,-257.625 C 1078.5292,-258.76284 1072.6557,-260.31175 1070.7813,-261 C 1068.9068,-261.68825 1066.6995,-262.5662 1063.9063,-264.28125 C 1061.113,-265.99629 1060.3327,-266.56515 1057.9688,-267.6875 C 1055.6047,-268.80984 1053.9121,-269.52205 1051.4688,-270 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6961);enable-background:new" />
-        <path
-           id="path8099"
-           d="M 1020.2188,-266.84375 C 1022.1307,-266.20564 1024.8,-265.08839 1026.375,-264.03125 C 1027.9501,-262.9741 1029.2706,-262.52258 1031.9063,-260.625 C 1034.5149,-258.74679 1036.9347,-257.59497 1039.2188,-256.5625 C 1041.6865,-255.44705 1044.9833,-254.3892 1048.75,-252.71875 C 1047.5467,-253.94128 1041.5472,-256.03298 1039.6563,-256.84375 C 1037.7653,-257.65452 1035.5914,-258.73754 1032.7813,-260.59375 C 1029.9711,-262.44995 1029.1595,-263.07068 1026.7813,-264.3125 C 1024.403,-265.5543 1022.6706,-266.28819 1020.2188,-266.84375 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6957);enable-background:new" />
-        <path
-           id="path8101"
-           d="M 1110.1719,-266.89063 C 1110.3227,-266.84207 1110.8599,-266.25963 1110.2813,-265.40625 C 1109.4712,-264.21166 1104.5764,-262.08196 1101.7188,-261.28125 C 1098.8739,-260.48413 1095.4287,-260.30351 1091.1563,-261.65625 C 1086.8547,-263.0182 1085.6866,-264.12497 1080.5,-265.96875 C 1085.164,-263.85358 1086.6953,-262.01642 1090.625,-260.625 C 1092.2457,-260.05113 1093.9921,-259.6854 1095.6875,-259.59375 C 1095.2424,-259.26812 1094.1572,-258.61045 1092.125,-258 C 1089.3295,-257.16031 1085.4759,-256.46622 1083.875,-256.375 C 1082.3604,-256.28868 1080.733,-256.88749 1080.4375,-257 C 1080.6042,-256.89692 1080.8107,-256.62266 1080.1875,-255.96875 C 1079.2882,-255.02512 1074.0401,-254.04575 1071.0625,-253.71875 C 1068.0982,-253.3932 1064.5409,-253.73471 1060.1563,-255.625 C 1056.1783,-257.33997 1054.8173,-258.54036 1050.75,-260.375 C 1050.75,-260.375 1050.75,-260.21875 1050.75,-260.21875 C 1054.3931,-258.12346 1056.034,-256.33548 1059.625,-254.65625 C 1061.3552,-253.84716 1063.2167,-253.24749 1065.0313,-252.9375 C 1064.4964,-252.65074 1063.4735,-252.22599 1061.5938,-251.90625 C 1058.7248,-251.41829 1054.7848,-251.09011 1053.1563,-251.15625 C 1052.3056,-251.19079 1051.4277,-251.34062 1050.75,-251.5625 C 1050.0652,-251.77738 1049.5603,-252.00717 1049.4375,-252.0625 C 1049.6069,-251.95529 1049.8686,-251.65962 1049.2188,-251.03125 C 1048.3091,-250.15163 1042.9727,-249.69487 1039.9688,-249.5625 C 1036.9783,-249.43071 1033.3799,-250.01313 1028.9688,-252.125 C 1024.5276,-254.25126 1023.3273,-255.5266 1018.0625,-257.90625 C 1022.7968,-255.30921 1024.349,-253.27715 1028.4063,-251.1875 C 1030.0796,-250.32565 1031.8915,-249.69325 1033.6563,-249.25 C 1033.193,-249.01668 1032.0669,-248.56186 1029.9688,-248.3125 C 1027.0825,-247.96952 1023.1342,-247.81962 1021.5,-247.9375 C 1019.9538,-248.049 1018.2688,-248.79446 1017.9688,-248.9375 C 1018.1379,-248.81721 1018.3826,-248.52702 1017.75,-247.9375 C 1016.8372,-247.08677 1011.5059,-246.67538 1008.5,-246.5625 C 1005.5075,-246.45013 1001.9103,-247.05293 997.5,-249.15625 C 993.49875,-251.06448 992.11197,-252.29408 988.03125,-254.25 C 988.03122,-254.25 988.03125,-254.09375 988.03125,-254.09375 C 991.68631,-251.88983 993.32546,-250.0412 996.9375,-248.1875 C 998.67779,-247.29435 1000.5745,-246.65923 1002.4063,-246.21875 C 1001.8663,-245.97045 1000.8282,-245.60342 998.9375,-245.375 C 996.05182,-245.02642 992.07145,-244.85405 990.4375,-244.96875 C 989.58405,-245.02865 988.71119,-245.22666 988.03125,-245.46875 C 987.34415,-245.70405 986.8419,-245.94101 986.71875,-246 C 986.88873,-245.88773 987.18323,-245.57775 986.53125,-244.96875 C 985.6186,-244.11625 980.25592,-243.67538 977.25,-243.5625 C 974.25754,-243.45013 970.65654,-244.09055 966.25,-246.15625 C 961.81347,-248.23603 960.60312,-249.48796 955.34375,-251.8125 C 960.07313,-249.26501 961.63449,-247.2347 965.6875,-245.1875 C 967.35905,-244.34317 969.17304,-243.72107 970.9375,-243.28125 C 970.47427,-243.04703 969.3478,-242.59718 967.25,-242.34375 C 964.36431,-241.99517 960.4138,-241.77423 958.78125,-241.875 C 957.23669,-241.97032 955.58094,-242.70385 955.28125,-242.84375 C 955.45024,-242.72522 955.66317,-242.4399 955.03125,-241.84375 C 954.11939,-240.98347 948.7846,-240.5135 945.78125,-240.375 C 942.7913,-240.2371 939.2138,-240.82568 934.8125,-242.84375 C 930.81942,-244.67464 929.44739,-245.87295 925.375,-247.75 C 925.37498,-247.75 925.375,-247.59375 925.375,-247.59375 C 929.02261,-245.46048 930.64533,-243.65888 934.25,-241.875 C 935.98675,-241.01549 937.85727,-240.42486 939.6875,-240 C 939.14803,-239.7471 938.13687,-239.35871 936.25,-239.09375 C 933.37022,-238.68939 929.41187,-238.44813 927.78125,-238.53125 C 926.92953,-238.57466 926.05355,-238.7398 925.375,-238.96875 C 924.68931,-239.19076 924.1854,-239.41214 924.0625,-239.46875 C 924.23209,-239.35976 924.4944,-239.0591 923.84375,-238.4375 C 922.93296,-237.56736 917.59354,-237.04598 914.59375,-236.875 C 911.60742,-236.70479 908.01994,-237.19077 903.625,-239.15625 C 899.20011,-241.13513 898.01904,-242.38444 892.78125,-244.53125 C 897.49122,-242.14358 899.05142,-240.14252 903.09375,-238.1875 C 904.7609,-237.38119 906.55418,-236.79092 908.3125,-236.40625 C 907.85087,-236.15755 906.7155,-235.694 904.625,-235.375 C 901.7494,-234.93624 897.8446,-234.6419 896.21875,-234.6875 C 894.68052,-234.73062 892.98595,-235.43272 892.6875,-235.5625 C 892.85583,-235.44968 893.09807,-235.14875 892.46875,-234.53125 C 891.56063,-233.64015 886.2658,-233.003 883.28125,-232.71875 C 880.31007,-232.43577 876.70783,-232.89455 872.34375,-234.65625 C 868.38441,-236.25456 867.0146,-237.45112 863,-238.96875 C 863.00003,-238.96875 863,-238.8125 863,-238.8125 C 866.5959,-237.00115 868.23831,-235.23017 871.8125,-233.65625 C 873.53457,-232.8979 875.39998,-232.3673 877.21875,-232.03125 C 876.68266,-231.75217 875.65217,-231.34362 873.78125,-230.96875 C 870.92586,-230.39665 866.99183,-229.94936 865.375,-229.9375 C 864.53049,-229.93129 863.66892,-230.01844 863,-230.1875 C 862.32409,-230.34901 861.83991,-230.51673 861.71875,-230.5625 C 861.88597,-230.46848 862.14142,-230.17902 861.5,-229.5 C 860.60213,-228.54948 855.31352,-227.58292 852.375,-227.0625 C 849.44966,-226.54441 845.94285,-226.68826 841.65625,-228.09375 C 837.34045,-229.50882 836.18348,-230.62369 831.09375,-232.0625 C 835.6706,-230.31149 837.1823,-228.50244 841.125,-227.0625 C 842.75108,-226.46861 844.49385,-226.10685 846.21875,-225.90625 C 845.7659,-225.60923 844.66397,-225.02286 842.625,-224.4375 C 839.82028,-223.63233 835.98614,-222.86167 834.40625,-222.6875 C 832.9115,-222.5227 831.29002,-223.00431 831,-223.09375 C 831.16356,-223.00368 831.39278,-222.73382 830.78125,-222.03125 C 829.89878,-221.0174 824.73673,-219.6596 821.84375,-218.96875 C 818.96373,-218.28097 815.50815,-218.20873 811.28125,-219.40625 C 807.4464,-220.4927 806.10867,-221.47862 802.21875,-222.53125 C 802.21874,-222.53125 802.21875,-222.375 802.21875,-222.375 C 805.70293,-220.98015 807.28816,-219.4556 810.75,-218.34375 C 812.41793,-217.80803 814.20578,-217.55701 815.96875,-217.46875 C 815.44911,-217.11663 814.46836,-216.55423 812.65625,-215.9375 C 809.89059,-214.99625 806.06601,-214.00213 804.5,-213.78125 C 803.68206,-213.66586 802.8669,-213.65842 802.21875,-213.75 C 801.56379,-213.83321 801.08615,-213.96827 800.96875,-214 C 801.13079,-213.92536 801.40274,-213.65956 800.78125,-212.90625 C 799.91125,-211.85172 794.77162,-210.247 791.90625,-209.46875 C 789.05372,-208.69399 785.64713,-208.51055 781.46875,-209.5625 C 777.26192,-210.62163 776.11206,-211.60416 771.125,-212.71875 C 775.60954,-211.25929 777.09435,-209.58352 780.9375,-208.46875 C 782.52254,-208.00898 784.22429,-207.8305 785.90625,-207.78125 C 785.46468,-207.44449 784.39374,-206.75352 782.40625,-206 C 779.67232,-204.96351 775.95427,-203.83731 774.40625,-203.5625 C 772.94163,-203.30248 771.34667,-203.67904 771.0625,-203.75 C 771.22275,-203.67035 771.44294,-203.42902 770.84375,-202.6875 C 769.97909,-201.61744 764.92723,-199.86935 762.09375,-199 C 759.27295,-198.13453 755.88625,-197.84369 751.75,-198.78125 C 747.99741,-199.63186 746.70215,-200.49772 742.875,-201.375 C 742.875,-201.375 742.875,-201.21875 742.875,-201.21875 C 746.30296,-199.98096 747.86241,-198.58645 751.25,-197.6875 C 752.88216,-197.25436 754.61704,-197.10449 756.34375,-197.125 C 755.83482,-196.74083 754.867,-196.10318 753.09375,-195.375 C 750.38741,-194.26366 746.65742,-193.06719 745.125,-192.75 C 744.3246,-192.58431 743.51269,-192.53138 742.875,-192.59375 C 742.875,-192.59375 742.875,-192.07823 742.875,-191.67146 C 742.875,-191.40639 742.875,-191.1875 742.875,-191.1875 C 743.10145,-191.33218 743.32391,-191.46011 743.59375,-191.5625 C 744.67427,-191.97248 745.76536,-191.77827 749.59375,-193.25 C 753.42218,-194.72174 754.81787,-195.25498 755.5,-195.65625 C 756.1796,-196.05603 757.11165,-196.53562 757.71875,-197.1875 C 759.5456,-197.32525 761.2895,-197.68073 762.65625,-198.1875 C 765.62437,-199.28802 767.53162,-199.99369 769.4375,-200.65625 C 771.34336,-201.31879 771.79159,-202.07112 772.84375,-202.4375 C 773.9353,-202.81761 775.03886,-202.60288 778.90625,-203.96875 C 782.7737,-205.33461 784.18941,-205.79583 784.875,-206.1875 C 785.57609,-206.58802 786.57581,-207.12048 787.1875,-207.78125 C 789.1583,-207.83591 791.00435,-208.16588 792.46875,-208.65625 C 795.47023,-209.66133 797.3949,-210.27796 799.3125,-210.90625 C 800.8511,-211.41035 801.48652,-211.95302 802.21875,-212.34375 C 802.44891,-212.47806 802.69449,-212.59748 802.96875,-212.6875 C 804.06698,-213.04798 805.1502,-212.76887 809.0625,-214 C 812.97483,-215.23113 814.42855,-215.67295 815.125,-216.03125 C 815.81888,-216.38822 816.75515,-216.82386 817.375,-217.4375 C 819.24021,-217.46016 821.01081,-217.70433 822.40625,-218.125 C 825.43668,-219.03854 827.39863,-219.5551 829.34375,-220.09375 C 831.28886,-220.63239 831.76993,-221.35827 832.84375,-221.65625 C 833.95776,-221.9654 835.06369,-221.64886 839.03125,-222.6875 C 842.99886,-223.72613 844.44883,-224.12023 845.15625,-224.4375 C 845.89112,-224.76709 846.97008,-225.19122 847.59375,-225.8125 C 849.59149,-225.6965 851.45118,-225.83259 852.9375,-226.1875 C 856.01561,-226.9225 858.02094,-227.28844 860,-227.6875 C 861.58792,-228.00768 862.24429,-228.47805 863,-228.78125 C 863.23757,-228.88805 863.46695,-228.97401 863.75,-229.03125 C 864.88347,-229.26044 866.05448,-228.82232 870.09375,-229.53125 C 874.13308,-230.24018 875.594,-230.45834 876.3125,-230.71875 C 877.02836,-230.97819 878.01678,-231.28599 878.65625,-231.8125 C 880.58052,-231.57301 882.40413,-231.58797 883.84375,-231.8125 C 886.97008,-232.30012 888.9983,-232.51317 891,-232.78125 C 893.00171,-233.04932 893.48869,-233.72639 894.59375,-233.875 C 895.74014,-234.02918 896.86967,-233.57343 900.9375,-234.09375 C 905.00534,-234.61407 906.49763,-234.78948 907.21875,-235.03125 C 907.95585,-235.27839 909.01684,-235.61748 909.65625,-236.15625 C 911.70632,-235.82072 913.63003,-235.75829 915.15625,-235.9375 C 918.29856,-236.30646 920.33619,-236.49686 922.34375,-236.71875 C 923.95451,-236.89677 924.60842,-237.32695 925.375,-237.5625 C 925.61594,-237.64802 925.86912,-237.7181 926.15625,-237.75 C 927.30603,-237.87772 928.45754,-237.40335 932.53125,-237.875 C 936.60499,-238.34665 938.09034,-238.4856 938.8125,-238.71875 C 939.53196,-238.95102 940.51274,-239.19221 941.15625,-239.6875 C 943.09262,-239.35404 944.92631,-239.28326 946.375,-239.4375 C 949.52102,-239.77245 951.55256,-239.95609 953.5625,-240.15625 C 955.57246,-240.35639 956.04664,-240.98264 957.15625,-241.09375 C 958.30739,-241.20903 959.45268,-240.72869 963.53125,-241.15625 C 967.60986,-241.58381 969.12011,-241.71834 969.84375,-241.9375 C 970.5829,-242.16136 971.63947,-242.45075 972.28125,-242.96875 C 974.33835,-242.57008 976.28312,-242.47535 977.8125,-242.625 C 980.96123,-242.9331 982.98834,-243.09825 985,-243.28125 C 986.61407,-243.42807 987.2631,-243.8418 988.03125,-244.0625 C 988.27267,-244.14336 988.52478,-244.19241 988.8125,-244.21875 C 989.96461,-244.3242 991.10546,-243.826 995.1875,-244.21875 C 999.26958,-244.6115 1000.7764,-244.74959 1001.5,-244.96875 C 1002.2209,-245.18708 1003.1997,-245.41645 1003.8438,-245.90625 C 1005.7818,-245.55626 1007.6126,-245.45187 1009.0625,-245.59375 C 1012.2112,-245.90185 1014.2383,-246.067 1016.25,-246.25 C 1018.2616,-246.43299 1018.7642,-247.08802 1019.875,-247.1875 C 1021.0273,-247.29073 1022.1672,-246.80267 1026.25,-247.1875 C 1030.3329,-247.57232 1031.8387,-247.6885 1032.5625,-247.90625 C 1033.3018,-248.12868 1034.3581,-248.42074 1035,-248.9375 C 1037.0574,-248.53573 1039.0029,-248.43417 1040.5313,-248.59375 C 1043.6779,-248.92227 1045.7084,-249.11645 1047.7188,-249.3125 C 1049.3318,-249.46979 1049.9844,-249.94398 1050.75,-250.1875 C 1050.9907,-250.27554 1051.2132,-250.30887 1051.5,-250.34375 C 1052.6483,-250.48345 1053.8167,-250.00384 1057.875,-250.59375 C 1061.9333,-251.18367 1063.4368,-251.37089 1064.1563,-251.625 C 1064.873,-251.87816 1065.8308,-252.18307 1066.4688,-252.71875 C 1068.3885,-252.50681 1070.1887,-252.56734 1071.625,-252.8125 C 1074.7441,-253.3449 1076.7366,-253.74111 1078.7188,-254.125 C 1080.7009,-254.50887 1081.1931,-255.16465 1082.2813,-255.40625 C 1083.4101,-255.65691 1084.5516,-255.28996 1088.5313,-256.28125 C 1092.5109,-257.27253 1093.9609,-257.70055 1094.6563,-258.0625 C 1095.3786,-258.43851 1096.4182,-258.93308 1097.0313,-259.59375 C 1098.9943,-259.6058 1100.825,-259.8848 1102.25,-260.4375 C 1105.2012,-261.58211 1107.1232,-262.30692 1108.9375,-263.1875 C 1110.3932,-263.89403 1111.2723,-264.87391 1111.4844,-265.17188 C 1111.6966,-265.46984 1111.5962,-265.91718 1111.6223,-265.93863 C 1111.6652,-265.97387 1111.9416,-266.0236 1112.1013,-266.36707 C 1112.9602,-268.21415 1114.4223,-272.01166 1114.5365,-272.69652 C 1114.6502,-273.37868 1114.7003,-274.04426 1114.751,-274.44149 C 1114.7804,-274.67101 1114.6043,-275.30693 1114.6264,-275.36553 C 1114.6573,-275.44759 1114.9309,-275.63081 1114.9863,-275.88024 C 1115.2526,-277.07857 1115.0752,-278.07153 1114.8612,-279.48917 C 1114.6472,-280.90681 1113.8775,-284.11131 1113.2243,-284.96543 C 1112.5654,-285.82715 1112.0014,-285.9766 1111.4764,-285.96609 C 1111.2678,-285.69633 1111.6132,-285.703 1111.639,-285.65348 C 1112.3196,-285.60269 1112.573,-285.28484 1113.0582,-284.75686 C 1113.5434,-284.22888 1114.501,-280.8173 1114.6376,-279.36691 C 1114.7742,-277.91652 1114.8276,-276.50671 1114.5496,-275.89827 C 1114.2715,-275.28982 1113.6054,-275.46963 1113.313,-275.40375 C 1113.844,-275.21786 1114.2038,-275.19053 1114.2654,-274.34607 C 1114.3247,-273.53269 1114.1322,-272.70638 1113.7456,-271.54045 C 1113.3544,-270.36044 1111.9004,-267.19047 1111.4599,-266.94168 C 1111.0076,-266.68617 1110.5075,-266.75969 1110.1719,-266.89063 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6997);enable-background:new"
-           sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" />
-        <path
-           id="path8103"
-           d="M 988.75,-263.84375 C 990.66161,-263.20935 993.30027,-262.08534 994.875,-261.03125 C 996.44977,-259.97716 997.7711,-259.54873 1000.4063,-257.65625 C 1003.0145,-255.78311 1005.4332,-254.64103 1007.7188,-253.59375 C 1010.1881,-252.46228 1013.4709,-251.43901 1017.25,-249.65625 C 1016.0428,-250.91465 1010.111,-253.0207 1008.2188,-253.84375 C 1006.3266,-254.66679 1004.0908,-255.77424 1001.2813,-257.625 C 998.47169,-259.47575 997.65906,-260.10654 995.28125,-261.34375 C 992.90343,-262.58094 991.20137,-263.29295 988.75,-263.84375 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6953);enable-background:new" />
-        <path
-           id="path8105"
-           d="M 957.5,-260.78125 C 959.41,-260.16315 962.08288,-259.07191 963.65625,-258.03125 C 965.22964,-256.99059 966.55233,-256.54873 969.1875,-254.65625 C 971.79573,-252.7831 974.21442,-251.64104 976.5,-250.59375 C 978.96931,-249.46228 982.25213,-248.439 986.03125,-246.65625 C 984.82397,-247.91465 978.82971,-250.05195 976.9375,-250.875 C 975.04533,-251.69804 972.84084,-252.8055 970.03125,-254.65625 C 967.22167,-256.507 966.4383,-257.09557 964.0625,-258.3125 C 961.68672,-259.52941 959.94929,-260.25135 957.5,-260.78125 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6993);enable-background:new" />
-        <path
-           id="path8107"
-           d="M 926.09375,-257.375 C 928.00147,-256.77755 930.64723,-255.71116 932.21875,-254.6875 C 933.79025,-253.66385 935.08897,-253.24779 937.71875,-251.40625 C 940.32166,-249.58352 942.74762,-248.43405 945.03125,-247.40625 C 947.49845,-246.29584 950.7866,-245.31302 954.5625,-243.5625 C 953.35627,-244.8106 947.3906,-246.88059 945.5,-247.6875 C 943.60942,-248.4944 941.39758,-249.57854 938.59375,-251.375 C 935.7899,-253.17144 934.96671,-253.77751 932.59375,-254.96875 C 930.22078,-256.15999 928.54013,-256.87158 926.09375,-257.375 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6989);enable-background:new" />
-        <path
-           id="path8109"
-           d="M 894.90625,-253.5625 C 896.80838,-253.00895 899.49326,-251.97363 901.0625,-250.96875 C 902.63173,-249.96388 903.93651,-249.56011 906.5625,-247.75 C 909.16162,-245.95836 911.56284,-244.87811 913.84375,-243.875 C 916.30803,-242.79126 919.60359,-241.83471 923.375,-240.125 C 922.1702,-241.36007 916.20084,-243.36978 914.3125,-244.15625 C 912.42418,-244.94272 910.2373,-245.98705 907.4375,-247.75 C 904.63773,-249.51294 903.83831,-250.11836 901.46875,-251.28125 C 899.09918,-252.44413 897.3455,-253.11537 894.90625,-253.5625 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6985);enable-background:new" />
-        <path
-           id="path8111"
-           d="M 863.71875,-248.65625 C 865.59937,-248.22716 868.22302,-247.27587 869.78125,-246.34375 C 871.33948,-245.41164 872.63358,-245.08599 875.25,-243.34375 C 877.83971,-241.61931 880.23067,-240.63573 882.5,-239.71875 C 884.95176,-238.72806 888.23959,-237.84168 892,-236.21875 C 890.79869,-237.42609 884.84751,-239.28484 882.96875,-240 C 881.09,-240.71517 878.88335,-241.68442 876.09375,-243.375 C 873.30412,-245.06557 872.50914,-245.60322 870.15625,-246.65625 C 867.80333,-247.70926 866.13041,-248.36873 863.71875,-248.65625 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6965);enable-background:new" />
-        <path
-           id="path8113"
-           d="M 833.15625,-241.375 C 835.00461,-241.07856 837.6257,-240.39868 839.15625,-239.59375 C 840.68683,-238.78882 841.96999,-238.53802 844.53125,-237.0625 C 847.06629,-235.60204 849.42193,-234.73741 851.65625,-234 C 854.07024,-233.20332 857.31336,-232.53311 861.03125,-231.15625 C 859.84354,-232.28498 853.94353,-233.746 852.09375,-234.3125 C 850.24398,-234.879 848.09033,-235.68642 845.34375,-237.15625 C 842.59718,-238.62608 841.84239,-239.07653 839.53125,-239.9375 C 837.2201,-240.79845 835.52654,-241.25759 833.15625,-241.375 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6981);enable-background:new" />
-        <path
-           id="path8115"
-           d="M 802.90625,-232.3125 C 804.72845,-232.10123 807.27201,-231.51193 808.78125,-230.78125 C 810.2905,-230.05059 811.53693,-229.85127 814.0625,-228.5 C 816.56226,-227.16254 818.89404,-226.45157 821.09375,-225.84375 C 823.47028,-225.18708 826.65839,-224.77087 830.3125,-223.65625 C 829.14515,-224.70121 823.38362,-225.75954 821.5625,-226.21875 C 819.74139,-226.67796 817.61025,-227.34571 814.90625,-228.65625 C 812.20222,-229.96677 811.43519,-230.37615 809.15625,-231.125 C 806.8773,-231.87383 805.243,-232.30431 802.90625,-232.3125 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6977);enable-background:new" />
-        <path
-           id="path8117"
-           d="M 773.1875,-222.1875 C 774.99859,-222.0088 777.50809,-221.52244 779,-220.84375 C 780.49194,-220.16506 781.7534,-220.04553 784.25,-218.78125 C 786.72107,-217.52987 789.04005,-216.88511 791.21875,-216.34375 C 793.57262,-215.75887 796.71009,-215.44623 800.3125,-214.5 C 799.16166,-215.49116 793.45999,-216.2833 791.65625,-216.6875 C 789.85253,-217.0917 787.74072,-217.70866 785.0625,-218.9375 C 782.38432,-220.16634 781.65905,-220.54839 779.40625,-221.21875 C 777.15346,-221.88909 775.50998,-222.22107 773.1875,-222.1875 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6973);enable-background:new" />
-        <path
-           id="path8119"
-           d="M 743.5625,-211.1875 C 745.35531,-211.05839 747.83563,-210.63785 749.3125,-210 C 750.7894,-209.36215 752.0286,-209.25844 754.5,-208.0625 C 756.94618,-206.87878 759.22054,-206.31584 761.375,-205.84375 C 763.70267,-205.33372 766.7946,-205.16311 770.375,-204.28125 C 769.23121,-205.25185 763.62741,-205.8719 761.84375,-206.21875 C 760.06008,-206.56559 757.9609,-207.10631 755.3125,-208.25 C 752.66409,-209.39368 751.91755,-209.76631 749.6875,-210.375 C 747.45742,-210.98368 745.86156,-211.28466 743.5625,-211.1875 z"
-           style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6969);enable-background:new" />
-        <g
-           id="g8121"
-           style="fill:#ffffff;fill-opacity:1;filter:url(#filter7345)">
-          <path
-             sodipodi:nodetypes="czzzczzc"
-             id="path8123"
-             d="M 744.9375,-212.11731 C 744.9375,-212.11731 752.15979,-215.34049 754,-215.61731 C 755.84021,-215.89413 757.35225,-215.62054 760,-215.05481 C 762.64775,-214.48908 768.7357,-212.83963 771.1875,-211.67981 C 773.6393,-210.51999 776.5,-208.11731 776.5,-208.11731 C 776.5,-208.11731 769.35356,-210.8975 766.3125,-211.67981 C 763.27144,-212.46212 758.66789,-213.76355 755.9375,-213.99231 C 753.20711,-214.22107 744.9375,-212.11731 744.9375,-212.11731 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-          <path
-             sodipodi:nodetypes="czzzczzc"
-             id="path8125"
-             d="M 735.46875,-206.95416 C 735.46875,-206.95416 739.12854,-209.17734 740.96875,-209.45416 C 742.80896,-209.73098 744.6335,-209.20739 747.28125,-208.64166 C 749.929,-208.07593 756.01695,-206.42648 758.46875,-205.26666 C 760.92055,-204.10684 765.03125,-203.14166 765.03125,-203.14166 C 765.03125,-203.14166 756.63481,-204.48435 753.59375,-205.26666 C 750.55269,-206.04897 745.63664,-207.6004 742.90625,-207.82916 C 740.17586,-208.05792 735.46875,-206.95416 735.46875,-206.95416 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             sodipodi:nodetypes="czzzczzc"
-             id="path8127"
-             d="M 759.85042,-217.61116 C 759.85042,-217.61116 768.39412,-220.90973 770.2482,-221.06902 C 772.10229,-221.22832 773.88986,-220.58982 776.4963,-219.85694 C 779.10274,-219.12406 785.07354,-217.091 787.44666,-215.77769 C 789.81978,-214.46438 793.86083,-213.23987 793.86083,-213.23987 C 793.86083,-213.23987 785.5667,-215.11352 782.58152,-216.08754 C 779.59633,-217.06156 774.78883,-218.92232 772.0785,-219.32416 C 769.36817,-219.726 759.85042,-217.61116 759.85042,-217.61116 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             sodipodi:nodetypes="czzzczzc"
-             id="path8129"
-             d="M 775.19813,-223.2266 C 775.19813,-223.2266 782.96946,-226.00904 784.82644,-226.13009 C 786.68341,-226.25113 788.45744,-225.57592 791.04822,-224.78947 C 793.63899,-224.00302 799.56662,-221.8473 801.91216,-220.48535 C 804.25771,-219.1234 808.27265,-217.81585 808.27265,-217.81585 C 808.27265,-217.81585 800.01892,-219.86008 797.05444,-220.89543 C 794.08997,-221.93078 789.32185,-223.89024 786.62038,-224.34786 C 783.91891,-224.80549 775.19813,-223.2266 775.19813,-223.2266 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.3190906"
-             inkscape:transform-center-x="13.852145"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8131"
-             d="M 789.64298,-227.95417 C 789.64298,-227.95417 798.32554,-231.47448 800.18452,-231.55952 C 802.04349,-231.64455 803.8041,-230.9351 806.37915,-230.09859 C 808.9542,-229.2621 814.83894,-226.99193 817.15766,-225.58479 C 819.47638,-224.17764 823.46523,-222.79255 823.46523,-222.79255 C 823.46523,-222.79255 815.25266,-224.99632 812.3088,-226.08891 C 809.36494,-227.1815 804.63568,-229.23299 801.94358,-229.74288 C 799.25149,-230.25276 789.64298,-227.95417 789.64298,-227.95417 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.3190906"
-             inkscape:transform-center-x="13.852145"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8133"
-             d="M 804.49513,-233.32948 C 804.49513,-233.32948 812.30269,-235.91229 814.16167,-235.99733 C 816.02064,-236.08236 817.78125,-235.37291 820.3563,-234.5364 C 822.93135,-233.69991 828.81609,-231.42974 831.13481,-230.0226 C 833.45353,-228.61545 837.44238,-227.23036 837.44238,-227.23036 C 837.44238,-227.23036 829.22981,-229.43413 826.28595,-230.52672 C 823.34209,-231.61931 818.61283,-233.6708 815.92073,-234.18069 C 813.22864,-234.69057 804.49513,-233.32948 804.49513,-233.32948 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.3190906"
-             inkscape:transform-center-x="13.852145"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8135"
-             d="M 819.55763,-237.57948 C 819.55763,-237.57948 828.11519,-240.16229 829.97417,-240.24733 C 831.83314,-240.33236 833.59375,-239.62291 836.1688,-238.7864 C 838.74385,-237.94991 844.62859,-235.67974 846.94731,-234.2726 C 849.26603,-232.86545 853.25488,-231.48036 853.25488,-231.48036 C 853.25488,-231.48036 845.04231,-233.68413 842.09845,-234.77672 C 839.15459,-235.86931 834.42533,-237.9208 831.73323,-238.43069 C 829.04114,-238.94057 819.55763,-237.57948 819.55763,-237.57948 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.9269042"
-             inkscape:transform-center-x="13.64141"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8137"
-             d="M 836.23395,-242.60125 C 836.23395,-242.60125 843.20097,-244.58848 845.06179,-244.56882 C 846.9226,-244.54915 848.64052,-243.7418 851.16444,-242.76177 C 853.68837,-241.78177 859.4361,-239.18419 861.672,-237.64886 C 863.9079,-236.11351 867.81253,-234.50625 867.81253,-234.50625 C 867.81253,-234.50625 859.73692,-237.16847 856.85917,-238.42491 C 853.98143,-239.68136 849.37505,-241.99561 846.71589,-242.65612 C 844.05674,-243.31661 836.23395,-242.60125 836.23395,-242.60125 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.1542119"
-             inkscape:transform-center-x="13.55068"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8139"
-             d="M 850.73028,-246.00461 C 850.73028,-246.00461 858.41812,-248.03229 860.2781,-247.97315 C 862.13807,-247.914 863.83848,-247.07036 866.34103,-246.03699 C 868.84358,-245.00365 874.5349,-242.28467 876.73771,-240.70224 C 878.94053,-239.11979 882.81016,-237.43004 882.81016,-237.43004 C 882.81016,-237.43004 874.79287,-240.26302 871.94244,-241.58026 C 869.09201,-242.89749 864.53578,-245.30898 861.89124,-246.02576 C 859.2467,-246.74254 850.73028,-246.00461 850.73028,-246.00461 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.4740887"
-             inkscape:transform-center-x="13.41151"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8141"
-             d="M 864.82496,-249.21081 C 864.82496,-249.21081 872.99448,-251.17987 874.85184,-251.06477 C 876.70919,-250.94965 878.38342,-250.05521 880.85374,-248.94698 C 883.32405,-247.83877 888.93094,-244.94971 891.08512,-243.30167 C 893.2393,-241.65363 897.05632,-239.84815 897.05632,-239.84815 C 897.05632,-239.84815 889.12793,-242.92121 886.31845,-244.32365 C 883.50896,-245.72609 879.02739,-248.27364 876.40562,-249.06971 C 873.78386,-249.86577 864.82496,-249.21081 864.82496,-249.21081 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.79376"
-             inkscape:transform-center-x="13.258805"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8143"
-             d="M 881.38485,-251.60282 C 881.38485,-251.60282 889.47021,-253.51091 891.32322,-253.33946 C 893.17622,-253.16799 894.82252,-252.22313 897.25804,-251.04038 C 899.69357,-249.85767 905.21013,-246.79968 907.31327,-245.08699 C 909.41641,-243.37429 913.17684,-241.45373 913.17684,-241.45373 C 913.17684,-241.45373 905.34544,-244.76613 902.57984,-246.25323 C 899.81423,-247.74035 895.41209,-250.42282 892.8157,-251.29814 C 890.21933,-252.17345 881.38485,-251.60282 881.38485,-251.60282 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8145"
-             d="M 896.58415,-254.34724 C 896.58415,-254.34724 904.22581,-255.77494 906.07962,-255.61239 C 907.93342,-255.44983 909.58424,-254.51289 912.02541,-253.34186 C 914.46659,-252.17086 919.99779,-249.1394 922.10913,-247.43684 C 924.22047,-245.73426 927.99009,-243.83179 927.99009,-243.83179 C 927.99009,-243.83179 920.14286,-247.10653 917.37014,-248.58034 C 914.59743,-250.05414 910.18245,-252.71543 907.58189,-253.57827 C 904.98134,-254.44109 896.58415,-254.34724 896.58415,-254.34724 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8147"
-             d="M 911.45328,-255.98544 C 911.45328,-255.98544 920.09494,-257.53814 921.94875,-257.37559 C 923.80255,-257.21303 925.45337,-256.27609 927.89454,-255.10506 C 930.33572,-253.93406 935.86692,-250.9026 937.97826,-249.20004 C 940.0896,-247.49746 943.85922,-245.59499 943.85922,-245.59499 C 943.85922,-245.59499 936.01199,-248.86973 933.23927,-250.34354 C 930.46656,-251.81734 926.05158,-254.47863 923.45102,-255.34147 C 920.85047,-256.20429 911.45328,-255.98544 911.45328,-255.98544 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8149"
-             d="M 927.70328,-258.29794 C 927.70328,-258.29794 935.34494,-259.16314 937.19875,-259.00059 C 939.05255,-258.83803 940.70337,-257.90109 943.14454,-256.73006 C 945.58572,-255.55906 951.11692,-252.5276 953.22826,-250.82504 C 955.3396,-249.12246 959.10922,-247.21999 959.10922,-247.21999 C 959.10922,-247.21999 951.26199,-250.49473 948.48927,-251.96854 C 945.71656,-253.44234 941.30158,-256.10363 938.70102,-256.96647 C 936.10047,-257.82929 927.70328,-258.29794 927.70328,-258.29794 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8151"
-             d="M 942.82828,-259.48544 C 942.82828,-259.48544 951.40744,-260.97564 953.26125,-260.81309 C 955.11505,-260.65053 956.76587,-259.71359 959.20704,-258.54256 C 961.64822,-257.37156 967.17942,-254.3401 969.29076,-252.63754 C 971.4021,-250.93496 975.17172,-249.03249 975.17172,-249.03249 C 975.17172,-249.03249 967.32449,-252.30723 964.55177,-253.78104 C 961.77906,-255.25484 957.36408,-257.91613 954.76352,-258.77897 C 952.16297,-259.64179 942.82828,-259.48544 942.82828,-259.48544 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8153"
-             d="M 959.07828,-261.54794 C 959.07828,-261.54794 966.90744,-262.35064 968.76125,-262.18809 C 970.61505,-262.02553 972.26587,-261.08859 974.70704,-259.91756 C 977.14822,-258.74656 982.67942,-255.7151 984.79076,-254.01254 C 986.9021,-252.30996 990.67172,-250.40749 990.67172,-250.40749 C 990.67172,-250.40749 982.82449,-253.68223 980.05177,-255.15604 C 977.27906,-256.62984 972.86408,-259.29113 970.26352,-260.15397 C 967.66297,-261.01679 959.07828,-261.54794 959.07828,-261.54794 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8155"
-             d="M 974.45328,-262.79794 C 974.45328,-262.79794 982.84494,-263.97564 984.69875,-263.81309 C 986.55255,-263.65053 988.20337,-262.71359 990.64454,-261.54256 C 993.08572,-260.37156 998.61692,-257.3401 1000.7283,-255.63754 C 1002.8396,-253.93496 1006.6092,-252.03249 1006.6092,-252.03249 C 1006.6092,-252.03249 998.76199,-255.30723 995.98927,-256.78104 C 993.21656,-258.25484 988.80158,-260.91613 986.20102,-261.77897 C 983.60047,-262.64179 974.45328,-262.79794 974.45328,-262.79794 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8157"
-             d="M 990.64078,-264.86044 C 990.64078,-264.86044 997.53244,-265.85064 999.38625,-265.68809 C 1001.2401,-265.52553 1002.8909,-264.58859 1005.332,-263.41756 C 1007.7732,-262.24656 1013.3044,-259.2151 1015.4158,-257.51254 C 1017.5271,-255.80996 1021.2967,-253.90749 1021.2967,-253.90749 C 1021.2967,-253.90749 1013.4495,-257.18223 1010.6768,-258.65604 C 1007.9041,-260.12984 1003.4891,-262.79113 1000.8885,-263.65397 C 998.28797,-264.51679 990.64078,-264.86044 990.64078,-264.86044 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8159"
-             d="M 1007.7658,-265.79794 C 1007.7658,-265.79794 1014.5949,-266.97564 1016.4488,-266.81309 C 1018.3026,-266.65053 1019.9534,-265.71359 1022.3945,-264.54256 C 1024.8357,-263.37156 1030.3669,-260.3401 1032.4783,-258.63754 C 1034.5896,-256.93496 1038.3592,-255.03249 1038.3592,-255.03249 C 1038.3592,-255.03249 1030.512,-258.30723 1027.7393,-259.78104 C 1024.9666,-261.25484 1020.5516,-263.91613 1017.951,-264.77897 C 1015.3505,-265.64179 1007.7658,-265.79794 1007.7658,-265.79794 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8161"
-             d="M 1023.8908,-267.79794 C 1023.8908,-267.79794 1029.9699,-268.22564 1031.8238,-268.06309 C 1033.6776,-267.90053 1035.3284,-266.96359 1037.7695,-265.79256 C 1040.2107,-264.62156 1045.7419,-261.5901 1047.8533,-259.88754 C 1049.9646,-258.18496 1053.7342,-256.28249 1053.7342,-256.28249 C 1053.7342,-256.28249 1045.887,-259.55723 1043.1143,-261.03104 C 1040.3416,-262.50484 1035.9266,-265.16613 1033.326,-266.02897 C 1030.7255,-266.89179 1023.8908,-267.79794 1023.8908,-267.79794 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.7433893"
-             inkscape:transform-center-x="13.28378"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8163"
-             d="M 1039.7033,-269.17294 C 1039.7033,-269.17294 1046.1574,-269.85064 1048.0113,-269.68809 C 1049.8651,-269.52553 1051.5159,-268.58859 1053.957,-267.41756 C 1056.3982,-266.24656 1061.9294,-263.2151 1064.0408,-261.51254 C 1066.1521,-259.80996 1069.9217,-257.90749 1069.9217,-257.90749 C 1069.9217,-257.90749 1062.0745,-261.18223 1059.3018,-262.65604 C 1056.5291,-264.12984 1052.1141,-266.79113 1049.5135,-267.65397 C 1046.913,-268.51679 1039.7033,-269.17294 1039.7033,-269.17294 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-5.1360724"
-             inkscape:transform-center-x="13.55813"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8165"
-             d="M 1055.2718,-271.03319 C 1055.2718,-271.03319 1060.7694,-271.94264 1062.6296,-271.88667 C 1064.4897,-271.83067 1066.1915,-270.98993 1068.6957,-269.96081 C 1071.2001,-268.93171 1076.896,-266.22241 1079.1015,-264.64372 C 1081.307,-263.06501 1085.1795,-261.38182 1085.1795,-261.38182 C 1085.1795,-261.38182 1077.1575,-264.20121 1074.3047,-265.5136 C 1071.4521,-266.82598 1066.8918,-269.22973 1064.246,-269.94203 C 1061.6003,-270.65431 1055.2718,-271.03319 1055.2718,-271.03319 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.6370147"
-             inkscape:transform-center-x="13.74758"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8167"
-             d="M 1072.7007,-273.48537 C 1072.7007,-273.48537 1077.2479,-274.64118 1079.1087,-274.67158 C 1080.9694,-274.70196 1082.7083,-273.94109 1085.2576,-273.02927 C 1087.807,-272.1175 1093.6225,-269.67541 1095.899,-268.20077 C 1098.1753,-266.72609 1102.1217,-265.22441 1102.1217,-265.22441 C 1102.1217,-265.22441 1093.9775,-267.66852 1091.067,-268.84713 C 1088.1565,-270.02573 1083.4896,-272.21528 1080.8136,-272.80404 C 1078.1377,-273.39279 1072.7007,-273.48537 1072.7007,-273.48537 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             inkscape:transform-center-y="-4.4842392"
-             inkscape:transform-center-x="13.79933"
-             sodipodi:nodetypes="czzzczzc"
-             id="path8169"
-             d="M 1087.1585,-276.5244 C 1087.1585,-276.5244 1093.1185,-278.29795 1094.9787,-278.35464 C 1096.8387,-278.41131 1098.5883,-277.67509 1101.1502,-276.79939 C 1103.7122,-275.92373 1103.6728,-275.94226 1106.4837,-275.30924 C 1109.2806,-274.67938 1113.5604,-273.79611 1113.5604,-273.79611 C 1113.5604,-273.79611 1109.9449,-273.81239 1106.7681,-274.26225 C 1103.6526,-274.70344 1099.3938,-275.9605 1096.7097,-276.51138 C 1094.0258,-277.06226 1087.1585,-276.5244 1087.1585,-276.5244 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
-          <path
-             sodipodi:nodetypes="czczc"
-             id="path8171"
-             d="M 1099.25,-279.92981 C 1099.4112,-279.66119 1110.4581,-284.53027 1111.4375,-284.61731 C 1112.4169,-284.70435 1113.4375,-281.49231 1113.4375,-281.49231 C 1113.4375,-281.49231 1112.6624,-282.99665 1110.5625,-282.55481 C 1108.4626,-282.11297 1099.2616,-279.8834 1099.25,-279.92981 z"
-             style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-        </g>
-        <path
-           id="path8173"
-           d="M 1107.4532,-284.0938 C 1107.0345,-283.88097 1107.2976,-283.99991 1106.806,-283.78799 C 1106.3199,-283.57845 1105.0826,-283.2136 1102.7264,-282.32904 C 1099.3953,-281.07847 1096.8962,-280.1756 1095.7005,-279.26294 C 1094.1644,-279.24168 1091.98,-279.02963 1090.0442,-278.54419 C 1087.0627,-277.79653 1085.189,-277.37018 1083.2942,-276.95044 C 1081.3994,-276.53072 1081.6187,-276.30825 1080.4192,-276.07544 C 1079.1226,-275.82378 1078.6978,-276.08443 1074.9817,-275.29419 C 1071.4918,-274.55205 1066.0869,-273.36312 1064.8255,-272.60669 C 1063.2416,-272.78748 1060.958,-272.92847 1058.9817,-272.63794 C 1055.9413,-272.19099 1054.0655,-271.96518 1052.138,-271.73169 C 1051.4826,-271.65232 1051.0969,-271.53091 1050.7942,-271.45044 C 1050.368,-271.31879 1050.1084,-271.19042 1049.4192,-271.10669 C 1048.1076,-270.94733 1047.657,-271.26352 1043.888,-270.82544 C 1040.3341,-270.41236 1034.8826,-269.55262 1033.638,-268.88794 C 1032.039,-269.18524 1029.7802,-269.42213 1027.7942,-269.23169 C 1024.7354,-268.93838 1022.8222,-268.7477 1020.888,-268.57544 C 1018.9537,-268.40318 1019.1993,-268.15307 1017.9817,-268.04419 C 1016.6655,-267.9265 1016.2219,-268.20782 1012.4505,-267.79419 C 1008.9086,-267.40575 1003.4426,-266.58492 1002.1692,-265.91919 C 1000.5703,-266.21389 998.28202,-266.4262 996.29419,-266.23169 C 993.23595,-265.93245 991.35306,-265.75145 989.41919,-265.57544 C 988.7617,-265.5156 988.37915,-265.39688 988.07544,-265.32544 C 987.64779,-265.20649 987.39193,-265.10737 986.70044,-265.04419 C 985.38448,-264.92394 984.94068,-265.23907 981.16919,-264.82544 C 977.61305,-264.43543 972.16365,-263.58628 970.91919,-262.91919 C 969.32056,-263.21338 967.05935,-263.44291 965.07544,-263.23169 C 962.01984,-262.90637 960.1014,-262.70545 958.16919,-262.51294 C 956.23698,-262.32044 956.47932,-262.07206 955.26294,-261.95044 C 953.94806,-261.81898 953.49996,-262.11498 949.73169,-261.66919 C 946.19282,-261.25054 940.75401,-260.37702 939.48169,-259.70044 C 937.88414,-259.98149 935.62173,-260.12087 933.63794,-259.88794 C 930.58596,-259.52958 928.69286,-259.32008 926.76294,-259.10669 C 926.10674,-259.03414 925.72228,-258.934 925.41919,-258.85669 C 924.99242,-258.72947 924.73428,-258.58949 924.04419,-258.51294 C 922.73086,-258.36726 922.27673,-258.68696 918.51294,-258.20044 C 914.96405,-257.74169 909.53431,-256.78142 908.29419,-256.07544 C 906.70114,-256.31968 904.46038,-256.45679 902.48169,-256.20044 C 899.4341,-255.80563 897.53098,-255.55199 895.60669,-255.29419 C 893.68241,-255.0364 893.88058,-254.80066 892.66919,-254.63794 C 891.35973,-254.46204 890.922,-254.74232 887.16919,-254.16919 C 883.6449,-253.63095 878.24604,-252.47002 876.98169,-251.73169 C 875.39419,-251.93523 873.13619,-251.98642 871.16919,-251.63794 C 868.14302,-251.10182 866.2703,-250.77625 864.35669,-250.45044 C 863.70608,-250.33967 863.34298,-250.1795 863.04419,-250.07544 C 862.62352,-249.91056 862.38074,-249.74414 861.70044,-249.60669 C 860.40579,-249.3451 859.97332,-249.61289 856.26294,-248.79419 C 852.76441,-248.02224 847.41699,-246.41126 846.20044,-245.57544 C 844.63766,-245.65289 842.44286,-245.49016 840.51294,-244.98169 C 837.5405,-244.19856 835.69533,-243.7496 833.82544,-243.23169 C 831.95556,-242.71379 832.15884,-242.46441 830.98169,-242.13794 C 829.70923,-241.78504 829.28466,-242.03085 825.63794,-240.95044 C 822.21324,-239.93581 816.9885,-238.01727 815.76294,-237.10669 C 814.22411,-237.09395 812.04311,-236.83447 810.13794,-236.23169 C 807.20688,-235.30435 805.38763,-234.77327 803.54419,-234.16919 C 802.91743,-233.96381 802.55246,-233.77661 802.26294,-233.63794 C 801.85531,-233.42433 801.6096,-233.22919 800.95044,-233.01294 C 799.69598,-232.6014 799.26433,-232.8239 795.66919,-231.57544 C 792.27934,-230.39827 787.07421,-228.36174 785.88794,-227.41919 C 784.36405,-227.35952 782.23789,-227.02432 780.35669,-226.35669 C 777.4593,-225.3284 775.65761,-224.68121 773.82544,-224.04419 C 771.99327,-223.40718 772.19759,-223.19565 771.04419,-222.79419 C 769.79741,-222.36023 769.38058,-222.59447 765.82544,-221.23169 C 762.48677,-219.95189 757.33829,-217.74914 756.13794,-216.76294 C 754.63076,-216.65525 752.50225,-216.26414 750.63794,-215.54419 C 747.76976,-214.43659 746.01414,-213.76263 744.20044,-213.07544 C 743.58378,-212.84181 743.20403,-212.63341 742.91919,-212.48169 C 742.91919,-212.48169 742.91919,-211.38794 742.91919,-211.38794 C 743.03097,-211.6103 743.30518,-212.20537 743.82544,-212.48169 C 744.52341,-212.85241 748.63907,-214.47506 750.63794,-215.20044 C 752.2948,-215.80169 754.79183,-216.52912 756.60669,-216.51294 C 756.90831,-216.51025 757.19431,-216.46204 757.45044,-216.41919 C 759.29293,-216.11094 764.91919,-214.85669 764.91919,-214.85669 C 764.91918,-214.85669 758.6857,-216.50344 757.88794,-216.70044 C 757.69715,-216.74755 757.35222,-216.76916 756.91919,-216.76294 C 758.06465,-217.63265 761.68019,-219.15645 764.26294,-220.20044 C 767.10116,-221.34771 767.37975,-221.45226 769.32544,-221.85669 C 771.33374,-222.27413 772.48169,-222.35669 772.48169,-222.35669 C 772.48169,-222.35668 772.39933,-222.95783 773.45044,-223.48169 C 774.15554,-223.8331 778.33746,-225.37409 780.35669,-226.04419 C 782.30859,-226.69192 785.41409,-227.40269 787.23169,-227.04419 C 789.09492,-226.67669 794.76294,-225.23169 794.76294,-225.23169 C 794.76295,-225.23169 788.47594,-227.1028 787.66919,-227.32544 C 787.47627,-227.37869 787.13835,-227.41148 786.70044,-227.41919 C 787.85878,-228.25207 791.49488,-229.61451 794.10669,-230.57544 C 796.97685,-231.63145 797.27403,-231.73724 799.23169,-232.10669 C 801.08518,-232.45648 802.09053,-232.53217 802.26294,-232.54419 C 802.37654,-232.76143 802.64039,-233.35421 803.16919,-233.60669 C 803.87863,-233.94543 808.09526,-235.31944 810.13794,-235.91919 C 811.83111,-236.4163 814.37871,-236.95596 816.23169,-236.82544 C 816.53964,-236.80376 816.84518,-236.72818 817.10669,-236.66919 C 818.98787,-236.24487 824.70044,-234.63794 824.70044,-234.63794 C 824.70045,-234.63794 818.3587,-236.70319 817.54419,-236.95044 C 817.3494,-237.00958 816.98631,-237.05438 816.54419,-237.07544 C 817.71368,-237.87299 821.40721,-239.13166 824.04419,-240.01294 C 826.942,-240.98141 827.2772,-241.01626 829.26294,-241.29419 C 831.31259,-241.58108 832.45044,-241.60669 832.45044,-241.60669 C 832.45042,-241.60669 832.37769,-242.21366 833.45044,-242.66919 C 834.17004,-242.97476 838.44142,-244.16994 840.51294,-244.66919 C 842.51538,-245.15177 845.71143,-245.59748 847.57544,-245.07544 C 849.48622,-244.54029 855.29419,-242.57544 855.29419,-242.57544 C 855.29419,-242.57544 848.87153,-244.99895 848.04419,-245.29419 C 847.84635,-245.3648 847.46203,-245.43458 847.01294,-245.48169 C 848.20084,-246.21034 851.92821,-247.25577 854.60669,-247.98169 C 857.55011,-248.77944 857.89877,-248.75252 859.91919,-248.88794 C 861.83208,-249.01617 862.86624,-248.95903 863.04419,-248.95044 C 863.16147,-249.1541 863.43595,-249.72992 863.98169,-249.91919 C 864.71388,-250.17313 869.06021,-250.96708 871.16919,-251.29419 C 872.91732,-251.5653 875.57007,-251.77889 877.48169,-251.38794 C 877.79935,-251.32298 878.08691,-251.20243 878.35669,-251.10669 C 880.29743,-250.41796 886.20044,-248.01294 886.20044,-248.01294 C 886.20045,-248.01294 879.66573,-250.96371 878.82544,-251.32544 C 878.62447,-251.41195 878.25031,-251.49223 877.79419,-251.57544 C 879.00069,-252.20862 882.82375,-252.97104 885.54419,-253.48169 C 888.53372,-254.04288 888.84442,-254.01123 890.88794,-254.01294 C 892.9972,-254.01471 894.20044,-253.88794 894.20044,-253.88794 C 894.20044,-253.88793 894.12773,-254.51913 895.23169,-254.82544 C 895.97221,-255.03091 900.35781,-255.65931 902.48169,-255.88794 C 904.53471,-256.10893 907.80032,-256.14016 909.70044,-255.41919 C 911.64823,-254.68012 917.54419,-252.04419 917.54419,-252.04419 C 917.54421,-252.04419 910.98131,-255.22316 910.13794,-255.60669 C 909.93626,-255.69842 909.59573,-255.7929 909.13794,-255.88794 C 910.34886,-256.48982 914.12236,-257.13678 916.85669,-257.54419 C 919.86149,-257.99191 920.1822,-257.99589 922.23169,-257.95044 C 924.17214,-257.90742 925.23868,-257.75621 925.41919,-257.73169 C 925.53811,-257.92485 925.80309,-258.49752 926.35669,-258.63794 C 927.0994,-258.82632 931.51098,-259.37222 933.63794,-259.57544 C 935.40097,-259.74386 938.05803,-259.80973 939.98169,-259.32544 C 940.30137,-259.24496 940.5852,-259.12185 940.85669,-259.01294 C 942.80962,-258.22945 948.76294,-255.54419 948.76294,-255.54419 C 948.76292,-255.54419 942.17103,-258.79767 941.32544,-259.20044 C 941.12322,-259.29676 940.75318,-259.40747 940.29419,-259.51294 C 941.50833,-260.08721 945.33785,-260.63513 948.07544,-261.01294 C 951.08382,-261.42814 951.39851,-261.45557 953.45044,-261.38794 C 955.56842,-261.31813 956.76294,-261.13794 956.76294,-261.13794 C 956.76292,-261.13794 956.68569,-261.77535 957.79419,-262.04419 C 958.53781,-262.22454 962.94595,-262.70774 965.07544,-262.88794 C 967.13391,-263.06211 970.41868,-263.01226 972.32544,-262.23169 C 974.28003,-261.43153 980.20044,-258.70044 980.20044,-258.70044 C 980.20042,-258.70044 973.64051,-262.0092 972.79419,-262.41919 C 972.59182,-262.51724 972.22233,-262.62229 971.76294,-262.73169 C 972.97811,-263.29559 976.77302,-263.84599 979.51294,-264.20044 C 982.52385,-264.58996 982.83425,-264.59809 984.88794,-264.51294 C 986.83233,-264.43234 987.89457,-264.2597 988.07544,-264.23169 C 988.1946,-264.42255 988.45821,-264.977 989.01294,-265.10669 C 989.7572,-265.28069 994.16287,-265.75716 996.29419,-265.91919 C 998.06081,-266.05346 1000.7439,-266.0449 1002.6692,-265.54419 C 1002.9892,-265.46098 1003.2725,-265.34292 1003.5442,-265.23169 C 1005.4988,-264.43153 1011.4505,-261.66919 1011.4505,-261.66919 C 1011.4504,-261.66919 1004.8593,-265.0092 1004.013,-265.41919 C 1003.8106,-265.51724 1003.4411,-265.6223 1002.9817,-265.73169 C 1004.1968,-266.29559 1008.023,-266.81475 1010.763,-267.16919 C 1013.7739,-267.55872 1014.1155,-267.59809 1016.1692,-267.51294 C 1018.2889,-267.42506 1019.4817,-267.20044 1019.4817,-267.20044 C 1019.4817,-267.20044 1019.4033,-267.84946 1020.513,-268.10669 C 1021.2573,-268.27925 1025.6625,-268.73005 1027.7942,-268.88794 C 1029.8548,-269.04054 1033.1371,-268.98471 1035.0442,-268.20044 C 1036.9992,-267.39649 1042.9192,-264.70044 1042.9192,-264.70044 C 1042.9192,-264.70044 1036.3594,-267.97631 1035.513,-268.38794 C 1035.3105,-268.48638 1034.9412,-268.59016 1034.4817,-268.70044 C 1035.6971,-269.26198 1039.4936,-269.82822 1042.2317,-270.20044 C 1045.2407,-270.60949 1045.5544,-270.61602 1047.6067,-270.54419 C 1049.5498,-270.4762 1050.6139,-270.37934 1050.7942,-270.35669 C 1050.913,-270.55109 1051.1788,-271.0855 1051.7317,-271.23169 C 1052.4735,-271.42781 1056.8628,-272.06047 1058.9817,-272.32544 C 1060.7381,-272.54505 1063.387,-272.65775 1065.2942,-272.29419 C 1065.6111,-272.23378 1065.9,-272.10481 1066.1692,-272.01294 C 1068.1054,-271.35202 1074.013,-269.07544 1074.013,-269.07544 C 1074.0129,-269.07544 1067.4763,-271.88199 1066.638,-272.23169 C 1066.4375,-272.31532 1066.0618,-272.40502 1065.6067,-272.48169 C 1066.8104,-273.13215 1070.6258,-273.85364 1073.3255,-274.48169 C 1076.2922,-275.17189 1076.6144,-275.23676 1078.638,-275.35669 C 1080.7266,-275.48049 1081.9192,-275.38794 1081.9192,-275.38794 C 1081.9192,-275.38793 1081.8322,-276.01999 1082.9192,-276.41919 C 1083.6484,-276.68699 1087.9664,-277.75716 1090.0442,-278.23169 C 1092.0527,-278.69038 1095.2121,-279.26099 1097.0442,-278.85669 C 1098.9223,-278.44223 1110.6224,-275.84106 1110.6224,-275.84106 C 1110.6224,-275.84106 1098.2949,-278.86372 1097.4817,-279.10669 C 1097.2872,-279.16481 1096.9231,-279.21295 1096.4817,-279.23169 C 1097.6493,-280.03538 1099.9959,-280.91899 1102.5911,-281.93481 C 1104.2725,-282.59299 1103.5148,-282.3114 1105.367,-282.93841 C 1107.1206,-283.53207 1107.8524,-283.94912 1107.9974,-284.0514 C 1108.3435,-284.25791 1107.6414,-284.17328 1107.4532,-284.0938 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7333);enable-background:new"
-           sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" />
-        <path
-           id="path8175"
-           d="M 1082.625,-275.125 C 1084.498,-274.73152 1087.1211,-273.97945 1088.6563,-273.15625 C 1090.1915,-272.33306 1091.4785,-272.10025 1094.0313,-270.65625 C 1096.5579,-269.22699 1098.8271,-268.64929 1101,-268.125 C 1103.3476,-267.55858 1106.4354,-267.40977 1109.8438,-266.9375 C 1108.7549,-267.77725 1103.2364,-268.10995 1101.4375,-268.5 C 1099.6386,-268.89006 1097.5434,-269.51616 1094.8438,-270.8125 C 1092.1441,-272.10884 1091.3494,-272.61146 1089.0313,-273.5 C 1086.7131,-274.38854 1085.0269,-274.88314 1082.625,-275.125 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7285);enable-background:new" />
-        <path
-           id="path8177"
-           d="M 1051.4688,-270 C 1053.3741,-269.42241 1055.9969,-268.38428 1057.5625,-267.40625 C 1059.1281,-266.42823 1060.4427,-266.04644 1063.0625,-264.28125 C 1065.6555,-262.53409 1068.0484,-261.57198 1070.3125,-260.6875 C 1072.7586,-259.73193 1075.9951,-259.03037 1079.7188,-257.625 C 1078.5292,-258.76284 1072.6557,-260.31175 1070.7813,-261 C 1068.9068,-261.68825 1066.6995,-262.5662 1063.9063,-264.28125 C 1061.113,-265.99629 1060.3327,-266.56515 1057.9688,-267.6875 C 1055.6047,-268.80984 1053.9121,-269.52205 1051.4688,-270 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7289);enable-background:new" />
-        <path
-           id="path8179"
-           d="M 1020.2188,-266.84375 C 1022.1307,-266.20564 1024.8,-265.08839 1026.375,-264.03125 C 1027.9501,-262.9741 1029.2706,-262.52258 1031.9063,-260.625 C 1034.5149,-258.74679 1036.9347,-257.59497 1039.2188,-256.5625 C 1041.6865,-255.44705 1044.9833,-254.3892 1048.75,-252.71875 C 1047.5467,-253.94128 1041.5472,-256.03298 1039.6563,-256.84375 C 1037.7653,-257.65452 1035.5914,-258.73754 1032.7813,-260.59375 C 1029.9711,-262.44995 1029.1595,-263.07068 1026.7813,-264.3125 C 1024.403,-265.5543 1022.6706,-266.28819 1020.2188,-266.84375 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7293);enable-background:new" />
-        <path
-           id="path8181"
-           d="M 1110.1719,-266.89063 C 1110.3227,-266.84207 1110.8599,-266.25963 1110.2813,-265.40625 C 1109.4712,-264.21166 1104.5764,-262.08196 1101.7188,-261.28125 C 1098.8739,-260.48413 1095.4287,-260.30351 1091.1563,-261.65625 C 1086.8547,-263.0182 1085.6866,-264.12497 1080.5,-265.96875 C 1085.164,-263.85358 1086.6953,-262.01642 1090.625,-260.625 C 1092.2457,-260.05113 1093.9921,-259.6854 1095.6875,-259.59375 C 1095.2424,-259.26812 1094.1572,-258.61045 1092.125,-258 C 1089.3295,-257.16031 1085.4759,-256.46622 1083.875,-256.375 C 1082.3604,-256.28868 1080.733,-256.88749 1080.4375,-257 C 1080.6042,-256.89692 1080.8107,-256.62266 1080.1875,-255.96875 C 1079.2882,-255.02512 1074.0401,-254.04575 1071.0625,-253.71875 C 1068.0982,-253.3932 1064.5409,-253.73471 1060.1563,-255.625 C 1056.1783,-257.33997 1054.8173,-258.54036 1050.75,-260.375 C 1050.75,-260.375 1050.75,-260.21875 1050.75,-260.21875 C 1054.3931,-258.12346 1056.034,-256.33548 1059.625,-254.65625 C 1061.3552,-253.84716 1063.2167,-253.24749 1065.0313,-252.9375 C 1064.4964,-252.65074 1063.4735,-252.22599 1061.5938,-251.90625 C 1058.7248,-251.41829 1054.7848,-251.09011 1053.1563,-251.15625 C 1052.3056,-251.19079 1051.4277,-251.34062 1050.75,-251.5625 C 1050.0652,-251.77738 1049.5603,-252.00717 1049.4375,-252.0625 C 1049.6069,-251.95529 1049.8686,-251.65962 1049.2188,-251.03125 C 1048.3091,-250.15163 1042.9727,-249.69487 1039.9688,-249.5625 C 1036.9783,-249.43071 1033.3799,-250.01313 1028.9688,-252.125 C 1024.5276,-254.25126 1023.3273,-255.5266 1018.0625,-257.90625 C 1022.7968,-255.30921 1024.349,-253.27715 1028.4063,-251.1875 C 1030.0796,-250.32565 1031.8915,-249.69325 1033.6563,-249.25 C 1033.193,-249.01668 1032.0669,-248.56186 1029.9688,-248.3125 C 1027.0825,-247.96952 1023.1342,-247.81962 1021.5,-247.9375 C 1019.9538,-248.049 1018.2688,-248.79446 1017.9688,-248.9375 C 1018.1379,-248.81721 1018.3826,-248.52702 1017.75,-247.9375 C 1016.8372,-247.08677 1011.5059,-246.67538 1008.5,-246.5625 C 1005.5075,-246.45013 1001.9103,-247.05293 997.5,-249.15625 C 993.49875,-251.06448 992.11197,-252.29408 988.03125,-254.25 C 988.03122,-254.25 988.03125,-254.09375 988.03125,-254.09375 C 991.68631,-251.88983 993.32546,-250.0412 996.9375,-248.1875 C 998.67779,-247.29435 1000.5745,-246.65923 1002.4063,-246.21875 C 1001.8663,-245.97045 1000.8282,-245.60342 998.9375,-245.375 C 996.05182,-245.02642 992.07145,-244.85405 990.4375,-244.96875 C 989.58405,-245.02865 988.71119,-245.22666 988.03125,-245.46875 C 987.34415,-245.70405 986.8419,-245.94101 986.71875,-246 C 986.88873,-245.88773 987.18323,-245.57775 986.53125,-244.96875 C 985.6186,-244.11625 980.25592,-243.67538 977.25,-243.5625 C 974.25754,-243.45013 970.65654,-244.09055 966.25,-246.15625 C 961.81347,-248.23603 960.60312,-249.48796 955.34375,-251.8125 C 960.07313,-249.26501 961.63449,-247.2347 965.6875,-245.1875 C 967.35905,-244.34317 969.17304,-243.72107 970.9375,-243.28125 C 970.47427,-243.04703 969.3478,-242.59718 967.25,-242.34375 C 964.36431,-241.99517 960.4138,-241.77423 958.78125,-241.875 C 957.23669,-241.97032 955.58094,-242.70385 955.28125,-242.84375 C 955.45024,-242.72522 955.66317,-242.4399 955.03125,-241.84375 C 954.11939,-240.98347 948.7846,-240.5135 945.78125,-240.375 C 942.7913,-240.2371 939.2138,-240.82568 934.8125,-242.84375 C 930.81942,-244.67464 929.44739,-245.87295 925.375,-247.75 C 925.37498,-247.75 925.375,-247.59375 925.375,-247.59375 C 929.02261,-245.46048 930.64533,-243.65888 934.25,-241.875 C 935.98675,-241.01549 937.85727,-240.42486 939.6875,-240 C 939.14803,-239.7471 938.13687,-239.35871 936.25,-239.09375 C 933.37022,-238.68939 929.41187,-238.44813 927.78125,-238.53125 C 926.92953,-238.57466 926.05355,-238.7398 925.375,-238.96875 C 924.68931,-239.19076 924.1854,-239.41214 924.0625,-239.46875 C 924.23209,-239.35976 924.4944,-239.0591 923.84375,-238.4375 C 922.93296,-237.56736 917.59354,-237.04598 914.59375,-236.875 C 911.60742,-236.70479 908.01994,-237.19077 903.625,-239.15625 C 899.20011,-241.13513 898.01904,-242.38444 892.78125,-244.53125 C 897.49122,-242.14358 899.05142,-240.14252 903.09375,-238.1875 C 904.7609,-237.38119 906.55418,-236.79092 908.3125,-236.40625 C 907.85087,-236.15755 906.7155,-235.694 904.625,-235.375 C 901.7494,-234.93624 897.8446,-234.6419 896.21875,-234.6875 C 894.68052,-234.73062 892.98595,-235.43272 892.6875,-235.5625 C 892.85583,-235.44968 893.09807,-235.14875 892.46875,-234.53125 C 891.56063,-233.64015 886.2658,-233.003 883.28125,-232.71875 C 880.31007,-232.43577 876.70783,-232.89455 872.34375,-234.65625 C 868.38441,-236.25456 867.0146,-237.45112 863,-238.96875 C 863.00003,-238.96875 863,-238.8125 863,-238.8125 C 866.5959,-237.00115 868.23831,-235.23017 871.8125,-233.65625 C 873.53457,-232.8979 875.39998,-232.3673 877.21875,-232.03125 C 876.68266,-231.75217 875.65217,-231.34362 873.78125,-230.96875 C 870.92586,-230.39665 866.99183,-229.94936 865.375,-229.9375 C 864.53049,-229.93129 863.66892,-230.01844 863,-230.1875 C 862.32409,-230.34901 861.83991,-230.51673 861.71875,-230.5625 C 861.88597,-230.46848 862.14142,-230.17902 861.5,-229.5 C 860.60213,-228.54948 855.31352,-227.58292 852.375,-227.0625 C 849.44966,-226.54441 845.94285,-226.68826 841.65625,-228.09375 C 837.34045,-229.50882 836.18348,-230.62369 831.09375,-232.0625 C 835.6706,-230.31149 837.1823,-228.50244 841.125,-227.0625 C 842.75108,-226.46861 844.49385,-226.10685 846.21875,-225.90625 C 845.7659,-225.60923 844.66397,-225.02286 842.625,-224.4375 C 839.82028,-223.63233 835.98614,-222.86167 834.40625,-222.6875 C 832.9115,-222.5227 831.29002,-223.00431 831,-223.09375 C 831.16356,-223.00368 831.39278,-222.73382 830.78125,-222.03125 C 829.89878,-221.0174 824.73673,-219.6596 821.84375,-218.96875 C 818.96373,-218.28097 815.50815,-218.20873 811.28125,-219.40625 C 807.4464,-220.4927 806.10867,-221.47862 802.21875,-222.53125 C 802.21874,-222.53125 802.21875,-222.375 802.21875,-222.375 C 805.70293,-220.98015 807.28816,-219.4556 810.75,-218.34375 C 812.41793,-217.80803 814.20578,-217.55701 815.96875,-217.46875 C 815.44911,-217.11663 814.46836,-216.55423 812.65625,-215.9375 C 809.89059,-214.99625 806.06601,-214.00213 804.5,-213.78125 C 803.68206,-213.66586 802.8669,-213.65842 802.21875,-213.75 C 801.56379,-213.83321 801.08615,-213.96827 800.96875,-214 C 801.13079,-213.92536 801.40274,-213.65956 800.78125,-212.90625 C 799.91125,-211.85172 794.77162,-210.247 791.90625,-209.46875 C 789.05372,-208.69399 785.64713,-208.51055 781.46875,-209.5625 C 777.26192,-210.62163 776.11206,-211.60416 771.125,-212.71875 C 775.60954,-211.25929 777.09435,-209.58352 780.9375,-208.46875 C 782.52254,-208.00898 784.22429,-207.8305 785.90625,-207.78125 C 785.46468,-207.44449 784.39374,-206.75352 782.40625,-206 C 779.67232,-204.96351 775.95427,-203.83731 774.40625,-203.5625 C 772.94163,-203.30248 771.34667,-203.67904 771.0625,-203.75 C 771.22275,-203.67035 771.44294,-203.42902 770.84375,-202.6875 C 769.97909,-201.61744 764.92723,-199.86935 762.09375,-199 C 759.27295,-198.13453 755.88625,-197.84369 751.75,-198.78125 C 747.99741,-199.63186 746.70215,-200.49772 742.875,-201.375 C 742.875,-201.375 742.875,-201.21875 742.875,-201.21875 C 746.30296,-199.98096 747.86241,-198.58645 751.25,-197.6875 C 752.88216,-197.25436 754.61704,-197.10449 756.34375,-197.125 C 755.83482,-196.74083 754.867,-196.10318 753.09375,-195.375 C 750.38741,-194.26366 746.65742,-193.06719 745.125,-192.75 C 744.3246,-192.58431 743.51269,-192.53138 742.875,-192.59375 C 742.875,-192.59375 742.875,-192.07823 742.875,-191.67146 C 742.875,-191.40639 742.875,-191.1875 742.875,-191.1875 C 743.10145,-191.33218 743.32391,-191.46011 743.59375,-191.5625 C 744.67427,-191.97248 745.76536,-191.77827 749.59375,-193.25 C 753.42218,-194.72174 754.81787,-195.25498 755.5,-195.65625 C 756.1796,-196.05603 757.11165,-196.53562 757.71875,-197.1875 C 759.5456,-197.32525 761.2895,-197.68073 762.65625,-198.1875 C 765.62437,-199.28802 767.53162,-199.99369 769.4375,-200.65625 C 771.34336,-201.31879 771.79159,-202.07112 772.84375,-202.4375 C 773.9353,-202.81761 775.03886,-202.60288 778.90625,-203.96875 C 782.7737,-205.33461 784.18941,-205.79583 784.875,-206.1875 C 785.57609,-206.58802 786.57581,-207.12048 787.1875,-207.78125 C 789.1583,-207.83591 791.00435,-208.16588 792.46875,-208.65625 C 795.47023,-209.66133 797.3949,-210.27796 799.3125,-210.90625 C 800.8511,-211.41035 801.48652,-211.95302 802.21875,-212.34375 C 802.44891,-212.47806 802.69449,-212.59748 802.96875,-212.6875 C 804.06698,-213.04798 805.1502,-212.76887 809.0625,-214 C 812.97483,-215.23113 814.42855,-215.67295 815.125,-216.03125 C 815.81888,-216.38822 816.75515,-216.82386 817.375,-217.4375 C 819.24021,-217.46016 821.01081,-217.70433 822.40625,-218.125 C 825.43668,-219.03854 827.39863,-219.5551 829.34375,-220.09375 C 831.28886,-220.63239 831.76993,-221.35827 832.84375,-221.65625 C 833.95776,-221.9654 835.06369,-221.64886 839.03125,-222.6875 C 842.99886,-223.72613 844.44883,-224.12023 845.15625,-224.4375 C 845.89112,-224.76709 846.97008,-225.19122 847.59375,-225.8125 C 849.59149,-225.6965 851.45118,-225.83259 852.9375,-226.1875 C 856.01561,-226.9225 858.02094,-227.28844 860,-227.6875 C 861.58792,-228.00768 862.24429,-228.47805 863,-228.78125 C 863.23757,-228.88805 863.46695,-228.97401 863.75,-229.03125 C 864.88347,-229.26044 866.05448,-228.82232 870.09375,-229.53125 C 874.13308,-230.24018 875.594,-230.45834 876.3125,-230.71875 C 877.02836,-230.97819 878.01678,-231.28599 878.65625,-231.8125 C 880.58052,-231.57301 882.40413,-231.58797 883.84375,-231.8125 C 886.97008,-232.30012 888.9983,-232.51317 891,-232.78125 C 893.00171,-233.04932 893.48869,-233.72639 894.59375,-233.875 C 895.74014,-234.02918 896.86967,-233.57343 900.9375,-234.09375 C 905.00534,-234.61407 906.49763,-234.78948 907.21875,-235.03125 C 907.95585,-235.27839 909.01684,-235.61748 909.65625,-236.15625 C 911.70632,-235.82072 913.63003,-235.75829 915.15625,-235.9375 C 918.29856,-236.30646 920.33619,-236.49686 922.34375,-236.71875 C 923.95451,-236.89677 924.60842,-237.32695 925.375,-237.5625 C 925.61594,-237.64802 925.86912,-237.7181 926.15625,-237.75 C 927.30603,-237.87772 928.45754,-237.40335 932.53125,-237.875 C 936.60499,-238.34665 938.09034,-238.4856 938.8125,-238.71875 C 939.53196,-238.95102 940.51274,-239.19221 941.15625,-239.6875 C 943.09262,-239.35404 944.92631,-239.28326 946.375,-239.4375 C 949.52102,-239.77245 951.55256,-239.95609 953.5625,-240.15625 C 955.57246,-240.35639 956.04664,-240.98264 957.15625,-241.09375 C 958.30739,-241.20903 959.45268,-240.72869 963.53125,-241.15625 C 967.60986,-241.58381 969.12011,-241.71834 969.84375,-241.9375 C 970.5829,-242.16136 971.63947,-242.45075 972.28125,-242.96875 C 974.33835,-242.57008 976.28312,-242.47535 977.8125,-242.625 C 980.96123,-242.9331 982.98834,-243.09825 985,-243.28125 C 986.61407,-243.42807 987.2631,-243.8418 988.03125,-244.0625 C 988.27267,-244.14336 988.52478,-244.19241 988.8125,-244.21875 C 989.96461,-244.3242 991.10546,-243.826 995.1875,-244.21875 C 999.26958,-244.6115 1000.7764,-244.74959 1001.5,-244.96875 C 1002.2209,-245.18708 1003.1997,-245.41645 1003.8438,-245.90625 C 1005.7818,-245.55626 1007.6126,-245.45187 1009.0625,-245.59375 C 1012.2112,-245.90185 1014.2383,-246.067 1016.25,-246.25 C 1018.2616,-246.43299 1018.7642,-247.08802 1019.875,-247.1875 C 1021.0273,-247.29073 1022.1672,-246.80267 1026.25,-247.1875 C 1030.3329,-247.57232 1031.8387,-247.6885 1032.5625,-247.90625 C 1033.3018,-248.12868 1034.3581,-248.42074 1035,-248.9375 C 1037.0574,-248.53573 1039.0029,-248.43417 1040.5313,-248.59375 C 1043.6779,-248.92227 1045.7084,-249.11645 1047.7188,-249.3125 C 1049.3318,-249.46979 1049.9844,-249.94398 1050.75,-250.1875 C 1050.9907,-250.27554 1051.2132,-250.30887 1051.5,-250.34375 C 1052.6483,-250.48345 1053.8167,-250.00384 1057.875,-250.59375 C 1061.9333,-251.18367 1063.4368,-251.37089 1064.1563,-251.625 C 1064.873,-251.87816 1065.8308,-252.18307 1066.4688,-252.71875 C 1068.3885,-252.50681 1070.1887,-252.56734 1071.625,-252.8125 C 1074.7441,-253.3449 1076.7366,-253.74111 1078.7188,-254.125 C 1080.7009,-254.50887 1081.1931,-255.16465 1082.2813,-255.40625 C 1083.4101,-255.65691 1084.5516,-255.28996 1088.5313,-256.28125 C 1092.5109,-257.27253 1093.9609,-257.70055 1094.6563,-258.0625 C 1095.3786,-258.43851 1096.4182,-258.93308 1097.0313,-259.59375 C 1098.9943,-259.6058 1100.825,-259.8848 1102.25,-260.4375 C 1105.2012,-261.58211 1107.1232,-262.30692 1108.9375,-263.1875 C 1110.3932,-263.89403 1111.2723,-264.87391 1111.4844,-265.17188 C 1111.6966,-265.46984 1111.5962,-265.91718 1111.6223,-265.93863 C 1111.6652,-265.97387 1111.9416,-266.0236 1112.1013,-266.36707 C 1112.9602,-268.21415 1114.4223,-272.01166 1114.5365,-272.69652 C 1114.6502,-273.37868 1114.7003,-274.04426 1114.751,-274.44149 C 1114.7804,-274.67101 1114.6043,-275.30693 1114.6264,-275.36553 C 1114.6573,-275.44759 1114.9309,-275.63081 1114.9863,-275.88024 C 1115.2526,-277.07857 1115.0752,-278.07153 1114.8612,-279.48917 C 1114.6472,-280.90681 1113.8775,-284.11131 1113.2243,-284.96543 C 1112.5654,-285.82715 1112.0014,-285.9766 1111.4764,-285.96609 C 1111.2678,-285.69633 1111.6132,-285.703 1111.639,-285.65348 C 1112.3196,-285.60269 1112.573,-285.28484 1113.0582,-284.75686 C 1113.5434,-284.22888 1114.28,-280.90569 1114.4166,-279.4553 C 1114.5532,-278.00491 1114.6066,-276.5951 1114.3286,-275.98666 C 1114.0505,-275.37821 1113.6054,-275.46963 1113.313,-275.40375 C 1113.844,-275.21786 1113.9828,-275.27892 1114.0444,-274.43446 C 1114.1037,-273.62108 1113.9112,-272.79477 1113.5246,-271.62884 C 1113.1334,-270.44883 1111.6794,-267.27886 1111.2389,-267.03007 C 1110.7866,-266.77456 1110.5075,-266.75969 1110.1719,-266.89063 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7337);enable-background:new"
-           sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" />
-        <path
-           id="path8183"
-           d="M 988.75,-263.84375 C 990.66161,-263.20935 993.30027,-262.08534 994.875,-261.03125 C 996.44977,-259.97716 997.7711,-259.54873 1000.4063,-257.65625 C 1003.0145,-255.78311 1005.4332,-254.64103 1007.7188,-253.59375 C 1010.1881,-252.46228 1013.4709,-251.43901 1017.25,-249.65625 C 1016.0428,-250.91465 1010.111,-253.0207 1008.2188,-253.84375 C 1006.3266,-254.66679 1004.0908,-255.77424 1001.2813,-257.625 C 998.47169,-259.47575 997.65906,-260.10654 995.28125,-261.34375 C 992.90343,-262.58094 991.20137,-263.29295 988.75,-263.84375 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7297);enable-background:new" />
-        <path
-           id="path8185"
-           d="M 957.5,-260.78125 C 959.41,-260.16315 962.08288,-259.07191 963.65625,-258.03125 C 965.22964,-256.99059 966.55233,-256.54873 969.1875,-254.65625 C 971.79573,-252.7831 974.21442,-251.64104 976.5,-250.59375 C 978.96931,-249.46228 982.25213,-248.439 986.03125,-246.65625 C 984.82397,-247.91465 978.82971,-250.05195 976.9375,-250.875 C 975.04533,-251.69804 972.84084,-252.8055 970.03125,-254.65625 C 967.22167,-256.507 966.4383,-257.09557 964.0625,-258.3125 C 961.68672,-259.52941 959.94929,-260.25135 957.5,-260.78125 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7301);enable-background:new" />
-        <path
-           id="path8187"
-           d="M 926.09375,-257.375 C 928.00147,-256.77755 930.64723,-255.71116 932.21875,-254.6875 C 933.79025,-253.66385 935.08897,-253.24779 937.71875,-251.40625 C 940.32166,-249.58352 942.74762,-248.43405 945.03125,-247.40625 C 947.49845,-246.29584 950.7866,-245.31302 954.5625,-243.5625 C 953.35627,-244.8106 947.3906,-246.88059 945.5,-247.6875 C 943.60942,-248.4944 941.39758,-249.57854 938.59375,-251.375 C 935.7899,-253.17144 934.96671,-253.77751 932.59375,-254.96875 C 930.22078,-256.15999 928.54013,-256.87158 926.09375,-257.375 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7305);enable-background:new" />
-        <path
-           id="path8189"
-           d="M 894.90625,-253.5625 C 896.80838,-253.00895 899.49326,-251.97363 901.0625,-250.96875 C 902.63173,-249.96388 903.93651,-249.56011 906.5625,-247.75 C 909.16162,-245.95836 911.56284,-244.87811 913.84375,-243.875 C 916.30803,-242.79126 919.60359,-241.83471 923.375,-240.125 C 922.1702,-241.36007 916.20084,-243.36978 914.3125,-244.15625 C 912.42418,-244.94272 910.2373,-245.98705 907.4375,-247.75 C 904.63773,-249.51294 903.83831,-250.11836 901.46875,-251.28125 C 899.09918,-252.44413 897.3455,-253.11537 894.90625,-253.5625 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7309);enable-background:new" />
-        <path
-           id="path8191"
-           d="M 863.71875,-248.65625 C 865.59937,-248.22716 868.22302,-247.27587 869.78125,-246.34375 C 871.33948,-245.41164 872.63358,-245.08599 875.25,-243.34375 C 877.83971,-241.61931 880.23067,-240.63573 882.5,-239.71875 C 884.95176,-238.72806 888.23959,-237.84168 892,-236.21875 C 890.79869,-237.42609 884.84751,-239.28484 882.96875,-240 C 881.09,-240.71517 878.88335,-241.68442 876.09375,-243.375 C 873.30412,-245.06557 872.50914,-245.60322 870.15625,-246.65625 C 867.80333,-247.70926 866.13041,-248.36873 863.71875,-248.65625 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7313);enable-background:new" />
-        <path
-           id="path8193"
-           d="M 833.15625,-241.375 C 835.00461,-241.07856 837.6257,-240.39868 839.15625,-239.59375 C 840.68683,-238.78882 841.96999,-238.53802 844.53125,-237.0625 C 847.06629,-235.60204 849.42193,-234.73741 851.65625,-234 C 854.07024,-233.20332 857.31336,-232.53311 861.03125,-231.15625 C 859.84354,-232.28498 853.94353,-233.746 852.09375,-234.3125 C 850.24398,-234.879 848.09033,-235.68642 845.34375,-237.15625 C 842.59718,-238.62608 841.84239,-239.07653 839.53125,-239.9375 C 837.2201,-240.79845 835.52654,-241.25759 833.15625,-241.375 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7317);enable-background:new" />
-        <path
-           id="path8195"
-           d="M 802.90625,-232.3125 C 804.72845,-232.10123 807.27201,-231.51193 808.78125,-230.78125 C 810.2905,-230.05059 811.53693,-229.85127 814.0625,-228.5 C 816.56226,-227.16254 818.89404,-226.45157 821.09375,-225.84375 C 823.47028,-225.18708 826.65839,-224.77087 830.3125,-223.65625 C 829.14515,-224.70121 823.38362,-225.75954 821.5625,-226.21875 C 819.74139,-226.67796 817.61025,-227.34571 814.90625,-228.65625 C 812.20222,-229.96677 811.43519,-230.37615 809.15625,-231.125 C 806.8773,-231.87383 805.243,-232.30431 802.90625,-232.3125 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7321);enable-background:new" />
-        <path
-           id="path8197"
-           d="M 773.1875,-222.1875 C 774.99859,-222.0088 777.50809,-221.52244 779,-220.84375 C 780.49194,-220.16506 781.7534,-220.04553 784.25,-218.78125 C 786.72107,-217.52987 789.04005,-216.88511 791.21875,-216.34375 C 793.57262,-215.75887 796.71009,-215.44623 800.3125,-214.5 C 799.16166,-215.49116 793.45999,-216.2833 791.65625,-216.6875 C 789.85253,-217.0917 787.74072,-217.70866 785.0625,-218.9375 C 782.38432,-220.16634 781.65905,-220.54839 779.40625,-221.21875 C 777.15346,-221.88909 775.50998,-222.22107 773.1875,-222.1875 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7329);enable-background:new" />
-        <path
-           id="path8199"
-           d="M 743.5625,-211.1875 C 745.35531,-211.05839 747.83563,-210.63785 749.3125,-210 C 750.7894,-209.36215 752.0286,-209.25844 754.5,-208.0625 C 756.94618,-206.87878 759.22054,-206.31584 761.375,-205.84375 C 763.70267,-205.33372 766.7946,-205.16311 770.375,-204.28125 C 769.23121,-205.25185 763.62741,-205.8719 761.84375,-206.21875 C 760.06008,-206.56559 757.9609,-207.10631 755.3125,-208.25 C 752.66409,-209.39368 751.91755,-209.76631 749.6875,-210.375 C 747.45742,-210.98368 745.86156,-211.28466 743.5625,-211.1875 z"
-           style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7325);enable-background:new" />
-      </g>
-    </g>
-    <path
-       style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 863.87812,475.6679 C 865.52024,472.4499 867.39593,469.93261 868.73948,465.81892 C 869.5382,462.16103 872.05152,463.78819 875.99995,457.42202 C 877.40188,455.18252 881.47648,457.81338 884.96505,455.02291 C 886.23577,454.21972 887.84993,454.6186 889.44761,454.95978 C 893.213,456.27874 895.27337,458.66333 897.78137,460.76815 C 903.92043,466.73838 918.31551,468.71142 921.26741,467.08161 C 922.70146,464.17687 929.14869,461.67273 933.64178,455.96993 C 934.38989,454.84726 945.37114,447.22547 948.28899,449.40394"
-       id="path8201"
-       sodipodi:nodetypes="ccccccccc" />
-    <path
-       style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 888.50059,465.25071 C 895.864,462.01774 902.31149,456.34231 909.20872,451.86619 C 912.51929,449.89665 916.07855,455.0822 920.00472,455.46485 C 922.30245,455.24672 923.71762,456.66744 925.68683,457.10635 C 930.84319,458.42414 928.08476,460.97123 935.66209,463.54607 C 941.8177,465.26647 944.56949,456.7476 950.56184,456.22247 C 955.43923,455.71948 958.66076,455.90644 962.17859,455.96993 C 966.10555,456.10882 966.25714,452.47233 968.23951,450.66663 C 971.22007,447.86141 975.39512,448.81691 978.38436,445.92573 C 979.4019,444.54105 980.33894,442.91488 981.11895,440.81764 C 982.00096,438.8173 984.15901,441.12362 985.91718,442.08033"
-       id="path8203"
-       sodipodi:nodetypes="ccccccccccc" />
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer15"
-     inkscape:label="Feet"
-     style="display:inline">
-    <path
-       style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9048);enable-background:accumulate"
-       d="M 403.27922,1056.3058 L 459.84776,1013.8794 L 531.97265,1028.0215 L 485.30361,1080.3474 L 431.56349,1087.4185 L 403.27922,1056.3058 z"
-       id="path8994" />
-    <path
-       style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 542.27183,1060.5719 C 540.86456,1079.3731 541.12693,1093.3229 544.35357,1109.8752 C 547.58023,1126.4275 560.75966,1155.7825 564.68798,1173.0589 C 568.61419,1190.326 567.38211,1211.3686 552.22854,1224.2072 C 536.91093,1237.1846 510.17726,1245.8061 484.39623,1239.9409 C 458.61518,1234.0757 414.84716,1190.7175 395.80604,1169.7126 C 376.6939,1148.6293 332.04518,1075.862 317.86751,1045.4368 C 303.68984,1015.0117 305.2079,1008.7182 309.74779,999.90708 C 300.38107,975.38658 297.33408,949.84027 276.03534,924.33044 C 306.36081,927.44488 319.91562,951.28677 336.16102,971.47019 C 330.63113,923.39416 318.10631,907.05369 307.78707,880.74589 C 337.78137,886.82754 358.36643,912.61828 371.76686,953.45839 C 381.32101,949.54048 390.00462,944.08545 401.95427,944.39719 C 390.65677,902.70139 384.00481,874.48135 365.26702,843.32725 C 418.70898,848.99758 448.92404,923.96657 444.23844,931.28805 C 454.21641,929.04406 463.24409,924.75767 474.67497,925.63638 C 463.426,887.28936 453.62716,848.76848 471.01526,806.98819 C 471.01526,806.98819 519.30204,872.42507 525.40492,892.79397 C 531.50779,913.16287 526.92373,931.49448 526.92373,931.49448 C 526.92373,931.49448 543.8833,962.57978 547.21765,982.58862 C 550.59075,1002.83 543.68496,1041.6919 542.27183,1060.5719 z"
-       id="path4189"
-       sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3587);enable-background:accumulate"
-       d="M 719.5,738.69519 L 737.81177,754.12715 L 782.2228,738.73894 L 805.5,713.19519 L 816.96397,732.41584 L 847.63558,745.19938 L 872.73295,750.92775 L 892,723.19519 L 908.02309,747.02126 L 947,752.19519 L 957.24541,745.99667 L 964.00012,754.69487 L 989.5,765.69519 L 991.5,725.19519 L 955.94866,710.6576 L 923.45591,689.1305 L 883.0038,677.66492 L 861.69668,662.13148 L 840,685.19519 L 755.02878,638.61208 L 722,676.69519 L 719.5,738.69519 z"
-       id="path4191"
-       sodipodi:nodetypes="cccccccccccccccccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
-    <path
-       style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3898);enable-background:new"
-       d="M 584,696.5 L 577.4375,713.65625 C 577.4375,713.65625 569.62598,734.02113 561.75,757.3125 C 557.81201,768.95818 553.86698,781.35395 550.8125,792.4375 C 547.75802,803.52105 545.47664,812.81736 545.3125,820.71875 C 544.91443,839.88071 551.05903,855.60705 554.25,862.46875 C 553.47847,866.02398 552.25863,871.92307 550.90625,880.5625 C 548.98583,892.83071 547.18798,907.71691 548.53125,920.4375 C 549.91334,933.52585 555.34347,948.62515 561.125,963.46875 C 566.90653,978.31235 573.17935,992.69586 576.34375,1001.5 C 582.97581,1019.9519 586.33671,1033.0763 587.65625,1050 C 588.2376,1057.4561 587.41398,1070.336 586.40625,1083.375 C 585.39852,1096.414 584.21964,1109.6764 584.71875,1120.3438 C 585.70786,1141.4836 594.04673,1167.1785 618.09375,1178.2812 C 640.86858,1188.7966 673.42057,1189.9834 701.53125,1174.8438 C 717.69117,1166.1404 731.60759,1147.7462 744.90625,1127.9375 C 758.20491,1108.1288 769.87542,1086.8841 776.84375,1073.0312 C 792.19667,1042.51 816.23728,957.56702 822.46875,920.3125 C 825.48734,902.26597 826.39041,891.24695 825.09375,882.28125 C 824.11522,875.51521 821.26556,870.13385 818.21875,866.0625 C 820.26149,838.55459 817.48668,814.69372 830.1875,786.65625 L 840.75,763.375 L 816.9375,772.6875 C 799.44775,779.52503 788.03586,791.73286 780.34375,804.75 C 780.02124,805.29577 779.78061,805.85776 779.46875,806.40625 C 779.69078,783.89104 783.87659,768.76866 786.0625,747.71875 L 788.03125,728.71875 L 771,737.375 C 740.40551,752.93071 725.30511,785.56821 721.28125,827.59375 C 717.03593,826.96828 712.44985,826.5741 707.46875,826.75 C 707.17726,787.56964 707.07246,759.71315 716.0625,727.375 L 721.65625,707.25 L 702.21875,714.90625 C 671.30938,727.11019 654.35921,756.83698 645.59375,783.28125 C 641.21102,796.50339 638.84793,809.08246 638,819.21875 C 637.76797,821.99248 637.68894,824.53007 637.6875,826.9375 C 634.44563,826.90109 631.26698,827.07339 627.625,827.4375 C 627.66662,788.43277 624.14076,747.68335 595.34375,710.9375 L 584,696.5 z M 589.8125,740.3125 C 606.61941,770.95633 607.28701,804.27978 606.75,840.0625 L 606.53125,855.125 L 618.56618,848.58579 C 627.22823,845.45277 638.12676,848.35827 650.5,847.75 L 665.17465,857.1066 L 658.84375,831.3125 C 658.7541,831.08253 658.62329,830.89581 658.59375,830.59375 C 658.39424,828.55389 658.37143,825.12068 658.71875,820.96875 C 659.41339,812.66489 661.50832,801.38351 665.34375,789.8125 C 670.49907,774.25956 678.83176,758.62002 690.46875,747.28125 C 685.78494,775.91923 687.25316,807.54059 687.45711,843.08639 L 684.69118,856.34803 L 700.1875,848.75 C 709.2169,845.99229 717.37647,848.40004 729.46875,849.84375 L 742.71507,859.28798 L 741.09375,840 C 742.54168,809.02823 749.31524,786.32192 761.8125,771.125 C 758.82562,790.90384 756.38207,812.9098 762.125,849.46875 L 763.19052,855.84193 L 760.25237,867.35878 L 770.86948,859.1906 L 780.05921,869.41258 L 778.51093,858.94898 L 781.9375,852 C 787.63852,838.78851 792.11032,825.78663 798.28125,815.34375 C 799.24111,813.71941 800.31278,812.27939 801.34375,810.78125 C 797.66309,831.9366 798.91659,850.9894 797.25,868.5625 L 792.56986,876.36948 L 799.96875,876.59375 C 803.1888,880.07736 803.83625,880.44443 804.53125,885.25 C 805.22625,890.05557 804.84987,899.65035 801.96875,916.875 C 796.40076,950.16292 770.12313,994.71481 758.22835,1018.3614 C 751.62344,1031.4918 739.70002,1075.8473 727.105,1094.6079 C 714.50998,1113.3684 698.57363,1134.3752 689.93296,1139.0288 C 668.44244,1150.603 645.37702,1164.5347 629.31407,1157.1183 C 614.93921,1150.4813 606.27438,1135.9256 605.5,1119.375 C 605.11689,1111.187 606.11279,1098.0658 607.125,1084.9688 C 608.13721,1071.8717 618.41391,1062.398 622.54839,1048.4062 C 627.92068,1030.2254 621.10152,1011.8118 610.04839,994.46875 C 603.56184,984.29097 586.07159,970.21085 580.5,955.90625 C 574.92841,941.60165 570.13249,926.9031 569.21875,918.25 C 568.29254,909.47887 569.64125,895.22498 571.4375,883.75 C 573.23375,872.27503 575.28125,863.46875 575.28125,863.46875 L 584.70403,859.85355 L 574.21875,855.96875 C 574.21875,855.96875 565.71986,840.65865 566.125,821.15625 C 566.19611,817.73309 567.96126,808.4282 570.84375,797.96875 C 573.72624,787.5093 577.60841,775.41604 581.46875,764 C 584.51314,754.99692 587.24938,747.39655 589.8125,740.3125 z"
-       id="path4193"
-       clip-path="url(#clipPath3677)"
-       sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" />
-    <g
-       id="g3617"
-       clip-path="url(#clipPath3622)"
-       transform="translate(276,136)">
-      <path
-         transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-52.200498,74.09707)"
-         id="path4195"
-         d="M -15.66751,843.48852 L -65.16499,827.93217 L -92.03504,880.25807 L -51.02285,925.51291 L -1.52538,887.32914 L -15.66751,843.48852 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9024);enable-background:accumulate" />
-      <path
-         sodipodi:nodetypes="ccccccccccccc"
-         transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-46.92842,75.511284)"
-         id="path4197"
-         d="M 118.70648,859.93048 L 63.552152,813.26144 L 19.711532,850.03099 L 53.652662,903.7711 L 40.055848,989.23313 L 0.61048221,1017.5253 L -40.401718,1028.839 L -43.230138,1075.508 L 13.338402,1100.9639 L 32.282389,1031.3139 L 55.738939,972.45727 L 102.08648,899.84236 L 118.70648,859.93048 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9020);enable-background:accumulate" />
-    </g>
-    <path
-       style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9044);enable-background:accumulate"
-       d="M -70.82184,932.58397 L -10.01066,905.71392 L 90.3985,936.82662 L 26.75889,967.93931 L -55.26549,950.96875 L -70.82184,932.58397 z"
-       id="path4199"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,229.07158,211.51128)" />
-    <path
-       style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4105);enable-background:new"
-       d="M 583.0625,715.75 C 570.95641,750.19974 556.348,784.28333 551.3125,820.59375 C 550.48042,835.52242 555.90165,849.75318 560.15625,863.65625 C 554.24001,890.85751 550.01944,920.5562 561.3125,946.78125 C 574.82967,984.9421 596.31397,1022.4634 593.73529,1064.2495 C 592.78699,1093.5437 584.72085,1125.2436 599.125,1152.5312 C 609.32364,1171.866 632.26456,1179.8429 653.09285,1180.1988 C 680.95504,1181.3729 709.55546,1168.5772 725.09375,1144.9375 C 747.68924,1115.5658 766.89426,1083.4402 780.3324,1048.8777 C 797.22293,1003.3717 810.0042,956.31698 818.26642,908.4788 C 820.09082,895.53774 821.3675,881.00895 813.6875,869.65625 C 810.25635,862.31993 813.72957,854.09611 813.00293,846.34648 C 813.67693,821.35182 817.01525,795.68272 829.65625,773.75 C 811.92312,780.1946 794.58357,790.30971 785.65318,807.61425 C 781.7181,814.3238 778.04836,821.18838 774.28125,828 C 770.73126,797.98592 778.00088,768.35172 781.0625,738.71875 C 760.89646,747.77338 744.18578,764.37397 736.88755,785.40075 C 730.58292,800.98078 728.08533,817.71793 726.625,834.4375 C 718.37166,832.91825 709.94053,832.33595 701.5625,832.9375 C 700.59942,794.23963 701.09554,753.53035 712.53125,717.03125 C 693.85012,723.24901 677.36504,735.76676 666.90322,752.41848 C 653.05068,773.29827 645.64182,798.17243 643.84375,823.03125 C 644.42909,827.35579 643.78249,834.87134 637.5,832.90625 C 632.16882,832.9238 626.87092,833.58508 621.5625,834 C 622.71034,794.61852 618.22106,752.3718 594.5,719.78125 C 591.43929,716.14408 588.86315,712.09687 585.875,708.4375 C 584.9375,710.875 584,713.3125 583.0625,715.75 z M 590.8125,729.59375 C 609.37777,758.89004 613.295,794.41387 612.9375,828.46875 C 613.14159,833.64401 612.42094,840.29795 613.0625,844.53125 C 625.38106,838.4285 639.80162,842.09135 652.84375,842.34375 C 655.16087,843.567 656.03585,843.99618 654.75,840.9375 C 650.58545,826.98465 652.90172,812.3245 656.55504,798.52986 C 662.92191,772.23922 677.18332,747.44188 699.375,731.5 C 690.75791,768.73706 693.65842,808.06161 693.28125,845.46875 C 705.53469,838.55885 720.56004,842.02262 733.3125,845.21875 C 736.70472,848.75355 735.60185,844.48927 735.5,841.40625 C 735.01691,820.03567 739.63133,798.33662 749.1875,779.25 C 755.15016,768.56273 763.43088,759.44621 771.625,750.375 C 763.75344,784.2131 762.4221,819.71093 768.90625,853.875 C 770.6311,852.46382 773.51306,853.42086 774.5625,853.5 C 784.24619,832.26318 790.91362,808.11938 809.45266,792.75815 C 811.32595,792.38693 808.00448,801.2831 807.96875,804.65625 C 804.43387,826.50206 800.79359,848.79859 799.18454,870.87536 C 790.40075,873.21707 802.03289,873.1989 802.65329,874.93786 C 810.5764,885.50366 807.31628,899.34258 806.28494,911.2912 C 799.22089,956.32475 784.14263,998.65314 770.33139,1041.971 C 758.25663,1074.9203 742.95719,1100.8235 722.44331,1129.1725 C 711.49074,1142.7239 699.19859,1157.0238 681.59956,1161.6725 C 661.44355,1167.9138 637.3928,1172.5494 619,1161.7188 C 601.71034,1149.3774 597.97607,1126.0099 599.73774,1106.0324 C 599.78653,1090.2062 604.6766,1077.5203 604.14834,1062.5406 C 603.6101,1047.2777 601.85699,1031.9759 597.60573,1015.6743 C 593.35447,999.37268 588.56248,990.75636 581.48667,974.10092 C 574.24556,957.05636 566.41652,937.35229 563.28125,917.8125 C 561.53177,899.18536 566.17296,880.68988 569.0625,862.5625 C 572.35873,859.72554 567.46451,857.36591 566.75,854.375 C 559.14887,837.35992 558.34253,817.6001 564.00766,799.81502 C 571.13786,774.74272 579.76853,750.18261 588.6875,725.6875 C 589.39583,726.98958 590.10417,728.29167 590.8125,729.59375 z"
-       id="path4201"
-       sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
-       clip-path="url(#clipPath4177)"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4130);enable-background:accumulate"
-       d="M 735.05635,733.03834 L 737.81177,754.12715 L 782.2228,738.73894 L 787.07343,716.34919 L 783.13726,694.29697 L 760.68563,657.70396 L 752.40559,688.0089 L 735.05635,733.03834 z"
-       id="path4203"
-       sodipodi:nodetypes="cccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4141);enable-background:accumulate"
-       d="M 831.81321,730.29452 L 847.63558,745.19938 L 868.49031,748.09932 L 866.90002,708.17334 L 875.22563,677.66492 L 868.06064,671.32386 L 846.36395,692.26626 L 831.81321,730.29452 z"
-       id="path4205"
-       sodipodi:nodetypes="cccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
-    <g
-       id="g8317"
-       style="filter:url(#filter8333)"
-       clip-path="url(#clipPath8338)"
-       transform="translate(276,136)">
-      <path
-         transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
-         clip-path="none"
-         sodipodi:nodetypes="ccccc"
-         id="path4209"
-         d="M 964.00012,754.69487 L 982.42893,762.15966 L 991.5,725.19519 L 976.62969,730.03405 L 964.00012,754.69487 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <rect
-         y="757.19519"
-         x="-55"
-         height="177"
-         width="182"
-         id="rect8315"
-         style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </g>
-    <g
-       id="g8346"
-       style="filter:url(#filter8354)"
-       clip-path="url(#clipPath8359)"
-       transform="translate(276,136)">
-      <path
-         transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
-         clip-path="none"
-         sodipodi:nodetypes="ccccccc"
-         id="path4207"
-         d="M 910.14441,746.31415 L 942.75736,751.48808 L 942.39617,727.61189 L 949.5847,697.92968 L 941.13358,692.66603 L 919.31164,719.1768 L 910.14441,746.31415 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <rect
-         y="696.19519"
-         x="-22"
-         height="176"
-         width="165"
-         id="rect8344"
-         style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </g>
-  </g>
-  <g
-     inkscape:groupmode="layer"
-     id="layer16"
-     inkscape:label="Left Foot"
-     style="display:inline">
-    <path
-       style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new"
-       d="M 1036.164,1071.8338 C 1042.9581,1090.7366 1046.6577,1105.1335 1048.0543,1123.0457 C 1049.4509,1140.958 1044.2716,1174.8465 1045.1538,1193.7018 C 1046.0356,1212.547 1053.2875,1233.8008 1072.4984,1242.6707 C 1091.9173,1251.6365 1121.8177,1252.882 1146.6183,1239.5251 C 1171.4189,1226.1681 1204.0193,1169.1996 1217.5925,1142.2164 C 1231.2164,1115.1325 1256.3536,1027.719 1262.2533,992.44781 C 1268.1531,957.1766 1264.8039,951.14704 1257.6359,943.39232 C 1260.2762,915.55217 1256.1361,888.45689 1270.7455,856.20614 C 1240.4965,868.03184 1233.3632,896.36684 1222.4266,921.71122 C 1214.4257,870.77829 1222.6358,850.43803 1225.7455,820.49186 C 1196.6808,835.26977 1182.884,867.60588 1180.7455,913.349 C 1169.8216,912.0448 1159.3541,908.91477 1147.1741,912.63471 C 1146.9101,866.61137 1145.7106,835.7453 1156.0847,798.42822 C 1102.8293,819.45508 1093.1375,905.02232 1100.0312,911.20614 C 1089.1484,911.74114 1078.6602,909.90884 1067.1741,914.06329 C 1067.813,871.49194 1066.9136,829.15468 1037.1741,791.20614 C 1037.1741,791.20614 1006.2161,872.12848 1005.7455,894.77757 C 1005.275,917.42666 1015.1971,934.94345 1015.1971,934.94345 C 1015.1971,934.94345 1006.6291,971.68396 1008.8985,993.17568 C 1011.1944,1014.9171 1029.3414,1052.8519 1036.164,1071.8338 z"
-       id="path8848"
-       sodipodi:nodetypes="czzzzzzcccccccccczczz" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3587);enable-background:accumulate"
-       d="M 719.5,738.69519 L 737.81177,754.12715 L 782.2228,738.73894 L 805.5,713.19519 L 816.96397,732.41584 L 847.63558,745.19938 L 872.73295,750.92775 L 892,723.19519 L 908.02309,747.02126 L 947,752.19519 L 957.24541,745.99667 L 964.00012,754.69487 L 989.5,765.69519 L 991.5,725.19519 L 955.94866,710.6576 L 923.45591,689.1305 L 883.0038,677.66492 L 861.69668,662.13148 L 840,685.19519 L 755.02878,638.61208 L 722,676.69519 L 719.5,738.69519 z"
-       id="path3635"
-       sodipodi:nodetypes="cccccccccccccccccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="translate(276,136)" />
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3898);enable-background:new"
-       d="M 584,696.5 L 577.4375,713.65625 C 577.4375,713.65625 569.62598,734.02113 561.75,757.3125 C 557.81201,768.95818 553.86698,781.35395 550.8125,792.4375 C 547.75802,803.52105 545.47664,812.81736 545.3125,820.71875 C 544.91443,839.88071 551.05903,855.60705 554.25,862.46875 C 553.47847,866.02398 552.25863,871.92307 550.90625,880.5625 C 548.98583,892.83071 547.18798,907.71691 548.53125,920.4375 C 549.91334,933.52585 555.34347,948.62515 561.125,963.46875 C 566.90653,978.31235 573.17935,992.69586 576.34375,1001.5 C 582.97581,1019.9519 586.33671,1033.0763 587.65625,1050 C 588.2376,1057.4561 587.41398,1070.336 586.40625,1083.375 C 585.39852,1096.414 584.21964,1109.6764 584.71875,1120.3438 C 585.70786,1141.4836 594.04673,1167.1785 618.09375,1178.2812 C 640.86858,1188.7966 673.42057,1189.9834 701.53125,1174.8438 C 717.69117,1166.1404 731.60759,1147.7462 744.90625,1127.9375 C 758.20491,1108.1288 769.87542,1086.8841 776.84375,1073.0312 C 792.19667,1042.51 816.23728,957.56702 822.46875,920.3125 C 825.48734,902.26597 826.39041,891.24695 825.09375,882.28125 C 824.11522,875.51521 821.26556,870.13385 818.21875,866.0625 C 820.26149,838.55459 817.48668,814.69372 830.1875,786.65625 L 840.75,763.375 L 816.9375,772.6875 C 799.44775,779.52503 788.03586,791.73286 780.34375,804.75 C 780.02124,805.29577 779.78061,805.85776 779.46875,806.40625 C 779.69078,783.89104 783.87659,768.76866 786.0625,747.71875 L 788.03125,728.71875 L 771,737.375 C 740.40551,752.93071 725.30511,785.56821 721.28125,827.59375 C 717.03593,826.96828 712.44985,826.5741 707.46875,826.75 C 707.17726,787.56964 707.07246,759.71315 716.0625,727.375 L 721.65625,707.25 L 702.21875,714.90625 C 671.30938,727.11019 654.35921,756.83698 645.59375,783.28125 C 641.21102,796.50339 638.84793,809.08246 638,819.21875 C 637.76797,821.99248 637.68894,824.53007 637.6875,826.9375 C 634.44563,826.90109 631.26698,827.07339 627.625,827.4375 C 627.66662,788.43277 624.14076,747.68335 595.34375,710.9375 L 584,696.5 z M 589.8125,740.3125 C 606.61941,770.95633 607.28701,804.27978 606.75,840.0625 L 606.53125,855.125 L 618.56618,848.58579 C 627.22823,845.45277 638.12676,848.35827 650.5,847.75 L 665.17465,857.1066 L 658.84375,831.3125 C 658.7541,831.08253 658.62329,830.89581 658.59375,830.59375 C 658.39424,828.55389 658.37143,825.12068 658.71875,820.96875 C 659.41339,812.66489 661.50832,801.38351 665.34375,789.8125 C 670.49907,774.25956 678.83176,758.62002 690.46875,747.28125 C 685.78494,775.91923 687.25316,807.54059 687.45711,843.08639 L 684.69118,856.34803 L 700.1875,848.75 C 709.2169,845.99229 717.37647,848.40004 729.46875,849.84375 L 742.71507,859.28798 L 741.09375,840 C 742.54168,809.02823 749.31524,786.32192 761.8125,771.125 C 758.82562,790.90384 756.38207,812.9098 762.125,849.46875 L 763.19052,855.84193 L 760.25237,867.35878 L 770.86948,859.1906 L 780.05921,869.41258 L 778.51093,858.94898 L 781.9375,852 C 787.63852,838.78851 792.11032,825.78663 798.28125,815.34375 C 799.24111,813.71941 800.31278,812.27939 801.34375,810.78125 C 797.66309,831.9366 798.91659,850.9894 797.25,868.5625 L 792.56986,876.36948 L 799.96875,876.59375 C 803.1888,880.07736 803.83625,880.44443 804.53125,885.25 C 805.22625,890.05557 804.84987,899.65035 801.96875,916.875 C 796.40076,950.16292 770.17603,1040.0409 758.28125,1063.6875 C 751.67634,1076.8179 740.25127,1097.5832 727.65625,1116.3438 C 715.06123,1135.1043 700.29692,1151.8776 691.65625,1156.5312 C 670.16573,1168.1054 642.87545,1166.7914 626.8125,1159.375 C 612.43764,1152.738 606.27438,1135.9256 605.5,1119.375 C 605.11689,1111.187 606.11279,1098.0658 607.125,1084.9688 C 608.13721,1071.8717 618.41391,1062.398 622.54839,1048.4062 C 627.92068,1030.2254 621.10152,1011.8118 610.04839,994.46875 C 603.56184,984.29097 586.07159,970.21085 580.5,955.90625 C 574.92841,941.60165 570.13249,926.9031 569.21875,918.25 C 568.29254,909.47887 569.64125,895.22498 571.4375,883.75 C 573.23375,872.27503 575.28125,863.46875 575.28125,863.46875 L 584.70403,859.85355 L 574.21875,855.96875 C 574.21875,855.96875 565.71986,840.65865 566.125,821.15625 C 566.19611,817.73309 567.96126,808.4282 570.84375,797.96875 C 573.72624,787.5093 577.60841,775.41604 581.46875,764 C 584.51314,754.99692 587.24938,747.39655 589.8125,740.3125 z"
-       id="path3669"
-       clip-path="url(#clipPath3677)"
-       sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc" />
-    <g
-       id="g3628"
-       clip-path="url(#clipPath3636)"
-       transform="translate(276,136)">
-      <path
-         id="path8988"
-         d="M 824.48651,818.48242 L 774.98903,802.92607 L 748.11898,855.25197 L 789.13117,900.50681 L 838.62864,862.32304 L 824.48651,818.48242 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9024);enable-background:accumulate" />
-      <path
-         id="path8990"
-         d="M 964.49365,855.25197 L 909.33932,808.58293 L 865.4987,845.35248 L 899.43983,899.09259 L 906.51089,965.56063 L 855.59921,1000.916 L 814.58701,1012.2297 L 811.75859,1058.8987 L 868.32713,1084.3546 L 931.96674,1007.987 L 956.00837,913.23473 L 964.49365,855.25197 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9020);enable-background:accumulate" />
-    </g>
-    <path
-       style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9044);enable-background:accumulate"
-       d="M 1045.3322,1043.5779 L 1106.1434,1016.7078 L 1206.5525,1047.8205 L 1142.9129,1078.9332 L 1060.8885,1061.9626 L 1045.3322,1043.5779 z"
-       id="path8992" />
-    <path
-       transform="translate(450.03125,73.843964)"
-       style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4185);enable-background:new"
-       d="M 583.0625,715.75 C 570.95641,750.19974 556.348,784.28333 551.3125,820.59375 C 550.48042,835.52242 555.90165,849.75318 560.15625,863.65625 C 554.24001,890.85751 550.01944,920.5562 561.3125,946.78125 C 574.82967,984.9421 596.31397,1022.4634 593.73529,1064.2495 C 592.78699,1093.5437 584.72085,1125.2436 599.125,1152.5312 C 609.32364,1171.866 632.26456,1179.8429 653.09285,1180.1988 C 680.95504,1181.3729 709.55546,1168.5772 725.09375,1144.9375 C 747.68924,1115.5658 766.89426,1083.4402 780.3324,1048.8777 C 797.22293,1003.3717 810.0042,956.31698 818.26642,908.4788 C 820.09082,895.53774 821.3675,881.00895 813.6875,869.65625 C 810.25635,862.31993 813.72957,854.09611 813.00293,846.34648 C 813.67693,821.35182 817.01525,795.68272 829.65625,773.75 C 811.92312,780.1946 794.58357,790.30971 785.65318,807.61425 C 781.7181,814.3238 778.04836,821.18838 774.28125,828 C 770.73126,797.98592 778.00088,768.35172 781.0625,738.71875 C 760.89646,747.77338 744.18578,764.37397 736.88755,785.40075 C 730.58292,800.98078 728.08533,817.71793 726.625,834.4375 C 718.37166,832.91825 709.94053,832.33595 701.5625,832.9375 C 700.59942,794.23963 701.09554,753.53035 712.53125,717.03125 C 693.85012,723.24901 677.36504,735.76676 666.90322,752.41848 C 653.05068,773.29827 645.64182,798.17243 643.84375,823.03125 C 644.42909,827.35579 643.78249,834.87134 637.5,832.90625 C 632.16882,832.9238 626.87092,833.58508 621.5625,834 C 622.71034,794.61852 618.22106,752.3718 594.5,719.78125 C 591.43929,716.14408 588.86315,712.09687 585.875,708.4375 C 584.9375,710.875 584,713.3125 583.0625,715.75 z M 590.8125,729.59375 C 609.37777,758.89004 613.295,794.41387 612.9375,828.46875 C 613.14159,833.64401 612.42094,840.29795 613.0625,844.53125 C 625.38106,838.4285 639.80162,842.09135 652.84375,842.34375 C 655.16087,843.567 656.03585,843.99618 654.75,840.9375 C 650.58545,826.98465 652.90172,812.3245 656.55504,798.52986 C 662.92191,772.23922 677.18332,747.44188 699.375,731.5 C 690.75791,768.73706 693.65842,808.06161 693.28125,845.46875 C 705.53469,838.55885 720.56004,842.02262 733.3125,845.21875 C 736.70472,848.75355 735.60185,844.48927 735.5,841.40625 C 735.01691,820.03567 739.63133,798.33662 749.1875,779.25 C 755.15016,768.56273 763.43088,759.44621 771.625,750.375 C 763.75344,784.2131 762.4221,819.71093 768.90625,853.875 C 770.6311,852.46382 773.51306,853.42086 774.5625,853.5 C 784.24619,832.26318 790.91362,808.11938 809.45266,792.75815 C 811.32595,792.38693 808.00448,801.2831 807.96875,804.65625 C 804.43387,826.50206 804.67155,848.82948 803.0625,870.90625 C 801.75012,872.28304 805.91085,873.22979 806.53125,874.96875 C 814.45436,885.53455 809.65419,899.80024 808.62285,911.74886 C 801.5588,956.78241 786.85732,1000.1282 773.04608,1043.446 C 760.97132,1076.3953 742.32638,1106.526 721.8125,1134.875 C 710.85993,1148.4264 698.56778,1162.7263 680.96875,1167.375 C 660.81274,1173.6163 637.3928,1172.5494 619,1161.7188 C 601.71034,1149.3774 597.97607,1126.0099 599.73774,1106.0324 C 599.78653,1090.2062 602.10985,1078.2316 607.65521,1063.2271 C 613.20056,1048.2226 610.12626,1031.8954 605.875,1015.5938 C 601.62374,999.2922 593.69597,989.33378 584.05342,973.38963 C 574.41087,957.44548 566.41652,937.35229 563.28125,917.8125 C 561.53177,899.18536 566.17296,880.68988 569.0625,862.5625 C 572.35873,859.72554 567.46451,857.36591 566.75,854.375 C 559.14887,837.35992 558.34253,817.6001 564.00766,799.81502 C 571.13786,774.74272 579.76853,750.18261 588.6875,725.6875 C 589.39583,726.98958 590.10417,728.29167 590.8125,729.59375 z"
-       id="path4149"
-       sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
-       clip-path="url(#clipPath4177)" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4130);enable-background:accumulate"
-       d="M 735.05635,733.03834 L 737.81177,754.12715 L 782.2228,738.73894 L 787.07343,716.34919 L 783.13726,694.29697 L 760.68563,657.70396 L 752.40559,688.0089 L 735.05635,733.03834 z"
-       id="path3902"
-       sodipodi:nodetypes="cccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="translate(276,136)" />
-    <path
-       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4141);enable-background:accumulate"
-       d="M 831.81321,730.29452 L 847.63558,745.19938 L 868.49031,748.09932 L 866.90002,708.17334 L 875.22563,677.66492 L 868.06064,671.32386 L 846.36395,692.26626 L 831.81321,730.29452 z"
-       id="path4135"
-       sodipodi:nodetypes="cccccccc"
-       clip-path="url(#clipPath3631)"
-       transform="translate(276,136)" />
-    <g
-       id="g8367"
-       style="filter:url(#filter8379)"
-       clip-path="url(#clipPath8392)"
-       transform="translate(276,136)">
-      <path
-         clip-path="none"
-         sodipodi:nodetypes="ccccccc"
-         id="path4145"
-         d="M 910.14441,746.31415 L 942.75736,751.48808 L 942.39617,727.61189 L 949.5847,697.92968 L 941.13358,692.66603 L 919.31164,719.1768 L 910.14441,746.31415 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <rect
-         y="650.19098"
-         x="877.51953"
-         height="172.53406"
-         width="123.03658"
-         id="rect8365"
-         style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </g>
-    <g
-       id="g8400"
-       style="filter:url(#filter8404)"
-       clip-path="url(#clipPath8417)"
-       transform="translate(276,136)">
-      <path
-         clip-path="none"
-         sodipodi:nodetypes="ccccc"
-         id="path4147"
-         d="M 964.00012,754.69487 L 982.42893,762.15966 L 991.5,725.19519 L 976.62969,730.03405 L 964.00012,754.69487 z"
-         style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-      <rect
-         y="677.06104"
-         x="924.89569"
-         height="125.1579"
-         width="142.12846"
-         id="rect8398"
-         style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
-    </g>
-  </g>
-</svg>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/logo.txt linux-libre-2.6.30-gnu1/Documentation/logo.txt
--- linux-libre-2.6.29-gnu1/Documentation/logo.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/logo.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,13 @@
-Tux is taking a three month sabbatical to work as a barber, so Tuz is
-standing in.  He's taken pains to ensure you'll hardly notice.
+This is the full-colour version of the currently unofficial Linux logo
+("currently unofficial" just means that there has been no paperwork and
+that I have not really announced it yet).  It was created by Larry Ewing,
+and is freely usable as long as you acknowledge Larry as the original
+artist. 
+
+Note that there are black-and-white versions of this available that
+scale down to smaller sizes and are better for letterheads or whatever
+you want to use it for: for the full range of logos take a look at
+Larry's web-page:
+
+	http://www.isc.tamu.edu/~lewing/linux/
 
-Image by Andrew McGown and Josh Bush.  Image is licensed CC BY-SA.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/md.txt linux-libre-2.6.30-gnu1/Documentation/md.txt
--- linux-libre-2.6.29-gnu1/Documentation/md.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/md.txt	2009-06-09 23:05:27.000000000 -0400
@@ -164,15 +164,19 @@ All md devices contain:
   raid_disks
      a text file with a simple number indicating the number of devices
      in a fully functional array.  If this is not yet known, the file
-     will be empty.  If an array is being resized (not currently
-     possible) this will contain the larger of the old and new sizes.
-     Some raid level (RAID1) allow this value to be set while the
-     array is active.  This will reconfigure the array.   Otherwise
-     it can only be set while assembling an array.
+     will be empty.  If an array is being resized this will contain
+     the new number of devices.
+     Some raid levels allow this value to be set while the array is
+     active.  This will reconfigure the array.   Otherwise it can only
+     be set while assembling an array.
+     A change to this attribute will not be permitted if it would
+     reduce the size of the array.  To reduce the number of drives
+     in an e.g. raid5, the array size must first be reduced by
+     setting the 'array_size' attribute.
 
   chunk_size
-     This is the size if bytes for 'chunks' and is only relevant to
-     raid levels that involve striping (1,4,5,6,10). The address space
+     This is the size in bytes for 'chunks' and is only relevant to
+     raid levels that involve striping (0,4,5,6,10). The address space
      of the array is conceptually divided into chunks and consecutive
      chunks are striped onto neighbouring devices.
      The size should be at least PAGE_SIZE (4k) and should be a power
@@ -183,6 +187,20 @@ All md devices contain:
      simply a number that is interpretted differently by different
      levels.  It can be written while assembling an array.
 
+  array_size
+     This can be used to artificially constrain the available space in
+     the array to be less than is actually available on the combined
+     devices.  Writing a number (in Kilobytes) which is less than
+     the available size will set the size.  Any reconfiguration of the
+     array (e.g. adding devices) will not cause the size to change.
+     Writing the word 'default' will cause the effective size of the
+     array to be whatever size is actually available based on
+     'level', 'chunk_size' and 'component_size'.
+
+     This can be used to reduce the size of the array before reducing
+     the number of devices in a raid4/5/6, or to support external
+     metadata formats which mandate such clipping.
+
   reshape_position
      This is either "none" or a sector number within the devices of
      the array where "reshape" is up to.  If this is set, the three
@@ -207,6 +225,11 @@ All md devices contain:
      about the array.  It can be 0.90 (traditional format), 1.0, 1.1,
      1.2 (newer format in varying locations) or "none" indicating that
      the kernel isn't managing metadata at all.
+     Alternately it can be "external:" followed by a string which
+     is set by user-space.  This indicates that metadata is managed
+     by a user-space program.  Any device failure or other event that
+     requires a metadata update will cause array activity to be
+     suspended until the event is acknowledged.
 
   resync_start
      The point at which resync should start.  If no resync is needed,
diff -druNp linux-libre-2.6.29-gnu1/Documentation/misc-devices/isl29003 linux-libre-2.6.30-gnu1/Documentation/misc-devices/isl29003
--- linux-libre-2.6.29-gnu1/Documentation/misc-devices/isl29003	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/misc-devices/isl29003	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+Kernel driver isl29003
+=====================
+
+Supported chips:
+* Intersil ISL29003
+Prefix: 'isl29003'
+Addresses scanned: none
+Datasheet:
+http://www.intersil.com/data/fn/fn7464.pdf
+
+Author: Daniel Mack <daniel@caiaq.de>
+
+
+Description
+-----------
+The ISL29003 is an integrated light sensor with a 16-bit integrating type
+ADC, I2C user programmable lux range select for optimized counts/lux, and
+I2C multi-function control and monitoring capabilities. The internal ADC
+provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
+artificial light sources.
+
+The driver allows to set the lux range, the bit resolution, the operational
+mode (see below) and the power state of device and can read the current lux
+value, of course.
+
+
+Detection
+---------
+
+The ISL29003 does not have an ID register which could be used to identify
+it, so the detection routine will just try to read from the configured I2C
+addess and consider the device to be present as soon as it ACKs the
+transfer.
+
+
+Sysfs entries
+-------------
+
+range:
+	0: 0 lux to 1000 lux (default)
+	1: 0 lux to 4000 lux
+	2: 0 lux to 16,000 lux
+	3: 0 lux to 64,000 lux
+
+resolution:
+	0: 2^16 cycles (default)
+	1: 2^12 cycles
+	2: 2^8 cycles
+	3: 2^4 cycles
+
+mode:
+	0: diode1's current (unsigned 16bit) (default)
+	1: diode1's current (unsigned 16bit)
+	2: difference between diodes (l1 - l2, signed 15bit)
+
+power_state:
+	0: device is disabled (default)
+	1: device is enabled
+
+lux (read only):
+	returns the value from the last sensor reading
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/bonding.txt linux-libre-2.6.30-gnu1/Documentation/networking/bonding.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/bonding.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/networking/bonding.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1242,7 +1242,7 @@ monitoring is enabled, and vice-versa.
 To add ARP targets:
 # echo +192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target
 # echo +192.168.0.101 > /sys/class/net/bond0/bonding/arp_ip_target
-	NOTE:  up to 10 target addresses may be specified.
+	NOTE:  up to 16 target addresses may be specified.
 
 To remove an ARP target:
 # echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/dccp.txt linux-libre-2.6.30-gnu1/Documentation/networking/dccp.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/dccp.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/networking/dccp.txt	2009-06-09 23:05:27.000000000 -0400
@@ -141,7 +141,8 @@ rx_ccid = 2
 	Default CCID for the receiver-sender half-connection; see tx_ccid.
 
 seq_window = 100
-	The initial sequence window (sec. 7.5.2).
+	The initial sequence window (sec. 7.5.2) of the sender. This influences
+	the local ackno validity and the remote seqno validity windows (7.5.1).
 
 tx_qlen = 5
 	The size of the transmit buffer in packets. A value of 0 corresponds
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/ip-sysctl.txt linux-libre-2.6.30-gnu1/Documentation/networking/ip-sysctl.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/ip-sysctl.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/networking/ip-sysctl.txt	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
 
 ip_forward - BOOLEAN
 	0 - disabled (default)
-	not 0 - enabled 
+	not 0 - enabled
 
 	Forward Packets between interfaces.
 
@@ -36,49 +36,49 @@ rt_cache_rebuild_count - INTEGER
 IP Fragmentation:
 
 ipfrag_high_thresh - INTEGER
-	Maximum memory used to reassemble IP fragments. When 
+	Maximum memory used to reassemble IP fragments. When
 	ipfrag_high_thresh bytes of memory is allocated for this purpose,
 	the fragment handler will toss packets until ipfrag_low_thresh
 	is reached.
-	
+
 ipfrag_low_thresh - INTEGER
-	See ipfrag_high_thresh	
+	See ipfrag_high_thresh
 
 ipfrag_time - INTEGER
-	Time in seconds to keep an IP fragment in memory.	
+	Time in seconds to keep an IP fragment in memory.
 
 ipfrag_secret_interval - INTEGER
-	Regeneration interval (in seconds) of the hash secret (or lifetime 
+	Regeneration interval (in seconds) of the hash secret (or lifetime
 	for the hash secret) for IP fragments.
 	Default: 600
 
 ipfrag_max_dist - INTEGER
-	ipfrag_max_dist is a non-negative integer value which defines the 
-	maximum "disorder" which is allowed among fragments which share a 
-	common IP source address. Note that reordering of packets is 
-	not unusual, but if a large number of fragments arrive from a source 
-	IP address while a particular fragment queue remains incomplete, it 
-	probably indicates that one or more fragments belonging to that queue 
-	have been lost. When ipfrag_max_dist is positive, an additional check 
-	is done on fragments before they are added to a reassembly queue - if 
-	ipfrag_max_dist (or more) fragments have arrived from a particular IP 
-	address between additions to any IP fragment queue using that source 
-	address, it's presumed that one or more fragments in the queue are 
-	lost. The existing fragment queue will be dropped, and a new one 
+	ipfrag_max_dist is a non-negative integer value which defines the
+	maximum "disorder" which is allowed among fragments which share a
+	common IP source address. Note that reordering of packets is
+	not unusual, but if a large number of fragments arrive from a source
+	IP address while a particular fragment queue remains incomplete, it
+	probably indicates that one or more fragments belonging to that queue
+	have been lost. When ipfrag_max_dist is positive, an additional check
+	is done on fragments before they are added to a reassembly queue - if
+	ipfrag_max_dist (or more) fragments have arrived from a particular IP
+	address between additions to any IP fragment queue using that source
+	address, it's presumed that one or more fragments in the queue are
+	lost. The existing fragment queue will be dropped, and a new one
 	started. An ipfrag_max_dist value of zero disables this check.
 
 	Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
 	result in unnecessarily dropping fragment queues when normal
-	reordering of packets occurs, which could lead to poor application 
-	performance. Using a very large value, e.g. 50000, increases the 
-	likelihood of incorrectly reassembling IP fragments that originate 
+	reordering of packets occurs, which could lead to poor application
+	performance. Using a very large value, e.g. 50000, increases the
+	likelihood of incorrectly reassembling IP fragments that originate
 	from different IP datagrams, which could result in data corruption.
 	Default: 64
 
 INET peer storage:
 
 inet_peer_threshold - INTEGER
-	The approximate size of the storage.  Starting from this threshold	
+	The approximate size of the storage.  Starting from this threshold
 	entries will be thrown aggressively.  This threshold also determines
 	entries' time-to-live and time intervals between garbage collection
 	passes.  More entries, less time-to-live, less GC interval.
@@ -105,7 +105,7 @@ inet_peer_gc_maxtime - INTEGER
 	in effect under low (or absent) memory pressure on the pool.
 	Measured in seconds.
 
-TCP variables: 
+TCP variables:
 
 somaxconn - INTEGER
 	Limit of socket listen() backlog, known in userspace as SOMAXCONN.
@@ -310,7 +310,7 @@ tcp_orphan_retries - INTEGER
 
 tcp_reordering - INTEGER
 	Maximal reordering of packets in a TCP stream.
-	Default: 3	
+	Default: 3
 
 tcp_retrans_collapse - BOOLEAN
 	Bug-to-bug compatibility with some broken printers.
@@ -521,7 +521,7 @@ IP Variables:
 
 ip_local_port_range - 2 INTEGERS
 	Defines the local port range that is used by TCP and UDP to
-	choose the local port. The first number is the first, the 
+	choose the local port. The first number is the first, the
 	second the last local port number. Default value depends on
 	amount of memory available on the system:
 	> 128Mb 32768-61000
@@ -594,12 +594,12 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN
 
 	If zero, icmp error messages are sent with the primary address of
 	the exiting interface.
- 
+
 	If non-zero, the message will be sent with the primary address of
 	the interface that received the packet that caused the icmp error.
 	This is the behaviour network many administrators will expect from
 	a router. And it can make debugging complicated network layouts
-	much easier. 
+	much easier.
 
 	Note that if no primary address exists for the interface selected,
 	then the primary address of the first non-loopback interface that
@@ -611,7 +611,7 @@ igmp_max_memberships - INTEGER
 	Change the maximum number of multicast groups we can subscribe to.
 	Default: 20
 
-conf/interface/*  changes special settings per interface (where "interface" is 
+conf/interface/*  changes special settings per interface (where "interface" is
 		  the name of your network interface)
 conf/all/*	  is special, changes the settings for all interfaces
 
@@ -625,11 +625,11 @@ log_martians - BOOLEAN
 accept_redirects - BOOLEAN
 	Accept ICMP redirect messages.
 	accept_redirects for the interface will be enabled if:
-	- both conf/{all,interface}/accept_redirects are TRUE in the case forwarding
-	  for the interface is enabled
+	- both conf/{all,interface}/accept_redirects are TRUE in the case
+	  forwarding for the interface is enabled
 	or
-	- at least one of conf/{all,interface}/accept_redirects is TRUE in the case
-	  forwarding for the interface is disabled
+	- at least one of conf/{all,interface}/accept_redirects is TRUE in the
+	  case forwarding for the interface is disabled
 	accept_redirects for the interface will be disabled otherwise
 	default TRUE (host)
 		FALSE (router)
@@ -640,8 +640,8 @@ forwarding - BOOLEAN
 mc_forwarding - BOOLEAN
 	Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
 	and a multicast routing daemon is required.
-	conf/all/mc_forwarding must also be set to TRUE to enable multicast routing
-	for the interface
+	conf/all/mc_forwarding must also be set to TRUE to enable multicast
+	routing	for the interface
 
 medium_id - INTEGER
 	Integer value used to differentiate the devices by the medium they
@@ -649,7 +649,7 @@ medium_id - INTEGER
 	the broadcast packets are received only on one of them.
 	The default value 0 means that the device is the only interface
 	to its medium, value of -1 means that medium is not known.
-	
+
 	Currently, it is used to change the proxy_arp behavior:
 	the proxy_arp feature is enabled for packets forwarded between
 	two devices attached to different media.
@@ -699,16 +699,22 @@ accept_source_route - BOOLEAN
 	default TRUE (router)
 		FALSE (host)
 
-rp_filter - BOOLEAN
-	1 - do source validation by reversed path, as specified in RFC1812
-	    Recommended option for single homed hosts and stub network
-	    routers. Could cause troubles for complicated (not loop free)
-	    networks running a slow unreliable protocol (sort of RIP),
-	    or using static routes.
-
+rp_filter - INTEGER
 	0 - No source validation.
+	1 - Strict mode as defined in RFC3704 Strict Reverse Path
+	    Each incoming packet is tested against the FIB and if the interface
+	    is not the best reverse path the packet check will fail.
+	    By default failed packets are discarded.
+	2 - Loose mode as defined in RFC3704 Loose Reverse Path
+	    Each incoming packet's source address is also tested against the FIB
+	    and if the source address is not reachable via any interface
+	    the packet check will fail.
 
-	conf/all/rp_filter must also be set to TRUE to do source validation
+	Current recommended practice in RFC3704 is to enable strict mode
+	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
 
 	Default value is 0. Note that some distributions enable it
@@ -782,6 +788,12 @@ arp_ignore - INTEGER
 	The max value from conf/{all,interface}/arp_ignore is used
 	when ARP request is received on the {interface}
 
+arp_notify - BOOLEAN
+	Define mode for notification of address and device changes.
+	0 - (default): do nothing
+	1 - Generate gratuitous arp replies when device is brought up
+	    or hardware address changes.
+
 arp_accept - BOOLEAN
 	Define behavior when gratuitous arp replies are received:
 	0 - drop gratuitous arp frames
@@ -823,7 +835,7 @@ apply to IPv6 [XXX?].
 
 bindv6only - BOOLEAN
 	Default value for IPV6_V6ONLY socket option,
-	which restricts use of the IPv6 socket to IPv6 communication 
+	which restricts use of the IPv6 socket to IPv6 communication
 	only.
 		TRUE: disable IPv4-mapped address feature
 		FALSE: enable IPv4-mapped address feature
@@ -833,19 +845,19 @@ bindv6only - BOOLEAN
 IPv6 Fragmentation:
 
 ip6frag_high_thresh - INTEGER
-	Maximum memory used to reassemble IPv6 fragments. When 
+	Maximum memory used to reassemble IPv6 fragments. When
 	ip6frag_high_thresh bytes of memory is allocated for this purpose,
 	the fragment handler will toss packets until ip6frag_low_thresh
 	is reached.
-	
+
 ip6frag_low_thresh - INTEGER
-	See ip6frag_high_thresh	
+	See ip6frag_high_thresh
 
 ip6frag_time - INTEGER
 	Time in seconds to keep an IPv6 fragment in memory.
 
 ip6frag_secret_interval - INTEGER
-	Regeneration interval (in seconds) of the hash secret (or lifetime 
+	Regeneration interval (in seconds) of the hash secret (or lifetime
 	for the hash secret) for IPv6 fragments.
 	Default: 600
 
@@ -854,17 +866,17 @@ conf/default/*:
 
 
 conf/all/*:
-	Change all the interface-specific settings.  
+	Change all the interface-specific settings.
 
 	[XXX:  Other special features than forwarding?]
 
 conf/all/forwarding - BOOLEAN
-	Enable global IPv6 forwarding between all interfaces.  
+	Enable global IPv6 forwarding between all interfaces.
 
-	IPv4 and IPv6 work differently here; e.g. netfilter must be used 
+	IPv4 and IPv6 work differently here; e.g. netfilter must be used
 	to control which interfaces may forward packets and which not.
 
-	This also sets all interfaces' Host/Router setting 
+	This also sets all interfaces' Host/Router setting
 	'forwarding' to the specified value.  See below for details.
 
 	This referred to as global forwarding.
@@ -875,12 +887,12 @@ proxy_ndp - BOOLEAN
 conf/interface/*:
 	Change special settings per interface.
 
-	The functional behaviour for certain settings is different 
+	The functional behaviour for certain settings is different
 	depending on whether local forwarding is enabled or not.
 
 accept_ra - BOOLEAN
 	Accept Router Advertisements; autoconfigure using them.
-	
+
 	Functional default: enabled if local forwarding is disabled.
 			    disabled if local forwarding is enabled.
 
@@ -926,7 +938,7 @@ accept_source_route - INTEGER
 	Default: 0
 
 autoconf - BOOLEAN
-	Autoconfigure addresses using Prefix Information in Router 
+	Autoconfigure addresses using Prefix Information in Router
 	Advertisements.
 
 	Functional default: enabled if accept_ra_pinfo is enabled.
@@ -935,11 +947,11 @@ autoconf - BOOLEAN
 dad_transmits - INTEGER
 	The amount of Duplicate Address Detection probes to send.
 	Default: 1
-	
+
 forwarding - BOOLEAN
-	Configure interface-specific Host/Router behaviour.  
+	Configure interface-specific Host/Router behaviour.
 
-	Note: It is recommended to have the same setting on all 
+	Note: It is recommended to have the same setting on all
 	interfaces; mixed router/host scenarios are rather uncommon.
 
 	FALSE:
@@ -948,13 +960,13 @@ forwarding - BOOLEAN
 
 	1. IsRouter flag is not set in Neighbour Advertisements.
 	2. Router Solicitations are being sent when necessary.
-	3. If accept_ra is TRUE (default), accept Router 
+	3. If accept_ra is TRUE (default), accept Router
 	   Advertisements (and do autoconfiguration).
 	4. If accept_redirects is TRUE (default), accept Redirects.
 
 	TRUE:
 
-	If local forwarding is enabled, Router behaviour is assumed. 
+	If local forwarding is enabled, Router behaviour is assumed.
 	This means exactly the reverse from the above:
 
 	1. IsRouter flag is set in Neighbour Advertisements.
@@ -989,7 +1001,7 @@ router_solicitation_interval - INTEGER
 	Default: 4
 
 router_solicitations - INTEGER
-	Number of Router Solicitations to send until assuming no 
+	Number of Router Solicitations to send until assuming no
 	routers are present.
 	Default: 3
 
@@ -1013,11 +1025,11 @@ temp_prefered_lft - INTEGER
 
 max_desync_factor - INTEGER
 	Maximum value for DESYNC_FACTOR, which is a random value
-	that ensures that clients don't synchronize with each 
+	that ensures that clients don't synchronize with each
 	other and generate new addresses at exactly the same time.
 	value is in seconds.
 	Default: 600
-	
+
 regen_max_retry - INTEGER
 	Number of attempts before give up attempting to generate
 	valid temporary addresses.
@@ -1025,13 +1037,15 @@ regen_max_retry - INTEGER
 
 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 
+	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.
 	Default: 16
 
 disable_ipv6 - BOOLEAN
-	Disable IPv6 operation.
+	Disable IPv6 operation.  If accept_dad is set to 2, this value
+	will be dynamically set to TRUE if DAD fails for the link-local
+	address.
 	Default: FALSE (enable IPv6 operation)
 
 accept_dad - INTEGER
@@ -1252,13 +1266,22 @@ sctp_rmem - vector of 3 INTEGERs: min, d
 sctp_wmem  - vector of 3 INTEGERs: min, default, max
 	See tcp_wmem for a description.
 
-UNDOCUMENTED:
 
 /proc/sys/net/core/*
-	dev_weight FIXME
+dev_weight - INTEGER
+	The maximum number of packets that kernel can handle on a NAPI
+	interrupt, it's a Per-CPU variable.
+
+	Default: 64
 
 /proc/sys/net/unix/*
-	max_dgram_qlen FIXME
+max_dgram_qlen - INTEGER
+	The maximum length of dgram socket receive queue
+
+	Default: 10
+
+
+UNDOCUMENTED:
 
 /proc/sys/net/irda/*
 	fast_poll_increase FIXME
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/ixgbe.txt linux-libre-2.6.30-gnu1/Documentation/networking/ixgbe.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/ixgbe.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/ixgbe.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,199 @@
+Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection
+========================================================================
+
+March 10, 2009
+
+
+Contents
+========
+
+- In This Release
+- Identifying Your Adapter
+- Building and Installation
+- Additional Configurations
+- Support
+
+
+
+In This Release
+===============
+
+This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI
+Express Intel(R) Network Connection.  This driver includes support for
+Itanium(R)2-based systems.
+
+For questions related to hardware requirements, refer to the documentation
+supplied with your 10 Gigabit adapter.  All hardware requirements listed apply
+to use with Linux.
+
+The following features are available in this kernel:
+ - Native VLANs
+ - Channel Bonding (teaming)
+ - SNMP
+ - Generic Receive Offload
+ - Data Center Bridging
+
+Channel Bonding documentation can be found in the Linux kernel source:
+/Documentation/networking/bonding.txt
+
+Ethtool, lspci, and ifconfig can be used to display device and driver
+specific information.
+
+
+Identifying Your Adapter
+========================
+
+This driver supports devices based on the 82598 controller and the 82599
+controller.
+
+For specific information on identifying which adapter you have, please visit:
+
+    http://support.intel.com/support/network/sb/CS-008441.htm
+
+
+Building and Installation
+=========================
+
+select m for "Intel(R) 10GbE PCI Express adapters support" located at:
+      Location:
+        -> Device Drivers
+          -> Network device support (NETDEVICES [=y])
+            -> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
+
+1. make modules & make modules_install
+
+2. Load the module:
+
+# modprobe ixgbe
+
+   The insmod command can be used if the full
+   path to the driver module is specified.  For example:
+
+     insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgbe/ixgbe.ko
+
+   With 2.6 based kernels also make sure that older ixgbe drivers are
+   removed from the kernel, before loading the new module:
+
+     rmmod ixgbe; modprobe ixgbe
+
+3. Assign an IP address to the interface by entering the following, where
+   x is the interface number:
+
+     ifconfig ethx <IP_address>
+
+4. Verify that the interface works. Enter the following, where <IP_address>
+   is the IP address for another machine on the same subnet as the interface
+   that is being tested:
+
+     ping  <IP_address>
+
+
+Additional Configurations
+=========================
+
+  Viewing Link Messages
+  ---------------------
+  Link messages will not be displayed to the console if the distribution is
+  restricting system messages. In order to see network driver link messages on
+  your console, set dmesg to eight by entering the following:
+
+       dmesg -n 8
+
+  NOTE: This setting is not saved across reboots.
+
+
+  Jumbo Frames
+  ------------
+  The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
+  enabled by changing the MTU to a value larger than the default of 1500.
+  The maximum value for the MTU is 16110.  Use the ifconfig command to
+  increase the MTU size.  For example:
+
+        ifconfig ethx mtu 9000 up
+
+  The maximum MTU setting for Jumbo Frames is 16110.  This value coincides
+  with the maximum Jumbo Frames size of 16128.
+
+  Generic Receive Offload, aka GRO
+  --------------------------------
+  The driver supports the in-kernel software implementation of GRO.  GRO has
+  shown that by coalescing Rx traffic into larger chunks of data, CPU
+  utilization can be significantly reduced when under large Rx load.  GRO is an
+  evolution of the previously-used LRO interface.  GRO is able to coalesce
+  other protocols besides TCP.  It's also safe to use with configurations that
+  are problematic for LRO, namely bridging and iSCSI.
+
+  GRO is enabled by default in the driver.  Future versions of ethtool will
+  support disabling and re-enabling GRO on the fly.
+
+
+  Data Center Bridging, aka DCB
+  -----------------------------
+
+  DCB is a configuration Quality of Service implementation in hardware.
+  It uses the VLAN priority tag (802.1p) to filter traffic.  That means
+  that there are 8 different priorities that traffic can be filtered into.
+  It also enables priority flow control which can limit or eliminate the
+  number of dropped packets during network stress.  Bandwidth can be
+  allocated to each of these priorities, which is enforced at the hardware
+  level.
+
+  To enable DCB support in ixgbe, you must enable the DCB netlink layer to
+  allow the userspace tools (see below) to communicate with the driver.
+  This can be found in the kernel configuration here:
+
+        -> Networking support
+          -> Networking options
+            -> Data Center Bridging support
+
+  Once this is selected, DCB support must be selected for ixgbe.  This can
+  be found here:
+
+        -> Device Drivers
+          -> Network device support (NETDEVICES [=y])
+            -> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
+              -> Intel(R) 10GbE PCI Express adapters support
+                -> Data Center Bridging (DCB) Support
+
+  After these options are selected, you must rebuild your kernel and your
+  modules.
+
+  In order to use DCB, userspace tools must be downloaded and installed.
+  The dcbd tools can be found at:
+
+        http://e1000.sf.net
+
+
+  Ethtool
+  -------
+  The driver utilizes the ethtool interface for driver configuration and
+  diagnostics, as well as displaying statistical information.  Ethtool
+  version 3.0 or later is required for this functionality.
+
+  The latest release of ethtool can be found from
+  http://sourceforge.net/projects/gkernel.
+
+
+  NAPI
+  ----
+
+  NAPI (Rx polling mode) is supported in the ixgbe driver.  NAPI is enabled
+  by default in the driver.
+
+  See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
+
+
+Support
+=======
+
+For general information, go to the Intel support website at:
+
+    http://support.intel.com
+
+or the Intel Wired Networking project hosted by Sourceforge at:
+
+    http://e1000.sourceforge.net
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related
+to the issue to e1000-devel@lists.sf.net
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/rds.txt linux-libre-2.6.30-gnu1/Documentation/networking/rds.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/rds.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/rds.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,356 @@
+
+Overview
+========
+
+This readme tries to provide some background on the hows and whys of RDS,
+and will hopefully help you find your way around the code.
+
+In addition, please see this email about RDS origins:
+http://oss.oracle.com/pipermail/rds-devel/2007-November/000228.html
+
+RDS Architecture
+================
+
+RDS provides reliable, ordered datagram delivery by using a single
+reliable connection between any two nodes in the cluster. This allows
+applications to use a single socket to talk to any other process in the
+cluster - so in a cluster with N processes you need N sockets, in contrast
+to N*N if you use a connection-oriented socket transport like TCP.
+
+RDS is not Infiniband-specific; it was designed to support different
+transports.  The current implementation used to support RDS over TCP as well
+as IB. Work is in progress to support RDS over iWARP, and using DCE to
+guarantee no dropped packets on Ethernet, it may be possible to use RDS over
+UDP in the future.
+
+The high-level semantics of RDS from the application's point of view are
+
+ *	Addressing
+        RDS uses IPv4 addresses and 16bit port numbers to identify
+        the end point of a connection. All socket operations that involve
+        passing addresses between kernel and user space generally
+        use a struct sockaddr_in.
+
+        The fact that IPv4 addresses are used does not mean the underlying
+        transport has to be IP-based. In fact, RDS over IB uses a
+        reliable IB connection; the IP address is used exclusively to
+        locate the remote node's GID (by ARPing for the given IP).
+
+        The port space is entirely independent of UDP, TCP or any other
+        protocol.
+
+ *	Socket interface
+        RDS sockets work *mostly* as you would expect from a BSD
+        socket. The next section will cover the details. At any rate,
+        all I/O is performed through the standard BSD socket API.
+        Some additions like zerocopy support are implemented through
+        control messages, while other extensions use the getsockopt/
+        setsockopt calls.
+
+        Sockets must be bound before you can send or receive data.
+        This is needed because binding also selects a transport and
+        attaches it to the socket. Once bound, the transport assignment
+        does not change. RDS will tolerate IPs moving around (eg in
+        a active-active HA scenario), but only as long as the address
+        doesn't move to a different transport.
+
+ *	sysctls
+        RDS supports a number of sysctls in /proc/sys/net/rds
+
+
+Socket Interface
+================
+
+  AF_RDS, PF_RDS, SOL_RDS
+        These constants haven't been assigned yet, because RDS isn't in
+        mainline yet. Currently, the kernel module assigns some constant
+        and publishes it to user space through two sysctl files
+                /proc/sys/net/rds/pf_rds
+                /proc/sys/net/rds/sol_rds
+
+  fd = socket(PF_RDS, SOCK_SEQPACKET, 0);
+        This creates a new, unbound RDS socket.
+
+  setsockopt(SOL_SOCKET): send and receive buffer size
+        RDS honors the send and receive buffer size socket options.
+        You are not allowed to queue more than SO_SNDSIZE bytes to
+        a socket. A message is queued when sendmsg is called, and
+        it leaves the queue when the remote system acknowledges
+        its arrival.
+
+        The SO_RCVSIZE option controls the maximum receive queue length.
+        This is a soft limit rather than a hard limit - RDS will
+        continue to accept and queue incoming messages, even if that
+        takes the queue length over the limit. However, it will also
+        mark the port as "congested" and send a congestion update to
+        the source node. The source node is supposed to throttle any
+        processes sending to this congested port.
+
+  bind(fd, &sockaddr_in, ...)
+        This binds the socket to a local IP address and port, and a
+        transport.
+
+  sendmsg(fd, ...)
+        Sends a message to the indicated recipient. The kernel will
+        transparently establish the underlying reliable connection
+        if it isn't up yet.
+
+        An attempt to send a message that exceeds SO_SNDSIZE will
+        return with -EMSGSIZE
+
+        An attempt to send a message that would take the total number
+        of queued bytes over the SO_SNDSIZE threshold will return
+        EAGAIN.
+
+        An attempt to send a message to a destination that is marked
+        as "congested" will return ENOBUFS.
+
+  recvmsg(fd, ...)
+        Receives a message that was queued to this socket. The sockets
+        recv queue accounting is adjusted, and if the queue length
+        drops below SO_SNDSIZE, the port is marked uncongested, and
+        a congestion update is sent to all peers.
+
+        Applications can ask the RDS kernel module to receive
+        notifications via control messages (for instance, there is a
+        notification when a congestion update arrived, or when a RDMA
+        operation completes). These notifications are received through
+        the msg.msg_control buffer of struct msghdr. The format of the
+        messages is described in manpages.
+
+  poll(fd)
+        RDS supports the poll interface to allow the application
+        to implement async I/O.
+
+        POLLIN handling is pretty straightforward. When there's an
+        incoming message queued to the socket, or a pending notification,
+        we signal POLLIN.
+
+        POLLOUT is a little harder. Since you can essentially send
+        to any destination, RDS will always signal POLLOUT as long as
+        there's room on the send queue (ie the number of bytes queued
+        is less than the sendbuf size).
+
+        However, the kernel will refuse to accept messages to
+        a destination marked congested - in this case you will loop
+        forever if you rely on poll to tell you what to do.
+        This isn't a trivial problem, but applications can deal with
+        this - by using congestion notifications, and by checking for
+        ENOBUFS errors returned by sendmsg.
+
+  setsockopt(SOL_RDS, RDS_CANCEL_SENT_TO, &sockaddr_in)
+        This allows the application to discard all messages queued to a
+        specific destination on this particular socket.
+
+        This allows the application to cancel outstanding messages if
+        it detects a timeout. For instance, if it tried to send a message,
+        and the remote host is unreachable, RDS will keep trying forever.
+        The application may decide it's not worth it, and cancel the
+        operation. In this case, it would use RDS_CANCEL_SENT_TO to
+        nuke any pending messages.
+
+
+RDMA for RDS
+============
+
+  see rds-rdma(7) manpage (available in rds-tools)
+
+
+Congestion Notifications
+========================
+
+  see rds(7) manpage
+
+
+RDS Protocol
+============
+
+  Message header
+
+    The message header is a 'struct rds_header' (see rds.h):
+    Fields:
+      h_sequence:
+          per-packet sequence number
+      h_ack:
+          piggybacked acknowledgment of last packet received
+      h_len:
+          length of data, not including header
+      h_sport:
+          source port
+      h_dport:
+          destination port
+      h_flags:
+          CONG_BITMAP - this is a congestion update bitmap
+          ACK_REQUIRED - receiver must ack this packet
+          RETRANSMITTED - packet has previously been sent
+      h_credit:
+          indicate to other end of connection that
+          it has more credits available (i.e. there is
+          more send room)
+      h_padding[4]:
+          unused, for future use
+      h_csum:
+          header checksum
+      h_exthdr:
+          optional data can be passed here. This is currently used for
+          passing RDMA-related information.
+
+  ACK and retransmit handling
+
+      One might think that with reliable IB connections you wouldn't need
+      to ack messages that have been received.  The problem is that IB
+      hardware generates an ack message before it has DMAed the message
+      into memory.  This creates a potential message loss if the HCA is
+      disabled for any reason between when it sends the ack and before
+      the message is DMAed and processed.  This is only a potential issue
+      if another HCA is available for fail-over.
+
+      Sending an ack immediately would allow the sender to free the sent
+      message from their send queue quickly, but could cause excessive
+      traffic to be used for acks. RDS piggybacks acks on sent data
+      packets.  Ack-only packets are reduced by only allowing one to be
+      in flight at a time, and by the sender only asking for acks when
+      its send buffers start to fill up. All retransmissions are also
+      acked.
+
+  Flow Control
+
+      RDS's IB transport uses a credit-based mechanism to verify that
+      there is space in the peer's receive buffers for more data. This
+      eliminates the need for hardware retries on the connection.
+
+  Congestion
+
+      Messages waiting in the receive queue on the receiving socket
+      are accounted against the sockets SO_RCVBUF option value.  Only
+      the payload bytes in the message are accounted for.  If the
+      number of bytes queued equals or exceeds rcvbuf then the socket
+      is congested.  All sends attempted to this socket's address
+      should return block or return -EWOULDBLOCK.
+
+      Applications are expected to be reasonably tuned such that this
+      situation very rarely occurs.  An application encountering this
+      "back-pressure" is considered a bug.
+
+      This is implemented by having each node maintain bitmaps which
+      indicate which ports on bound addresses are congested.  As the
+      bitmap changes it is sent through all the connections which
+      terminate in the local address of the bitmap which changed.
+
+      The bitmaps are allocated as connections are brought up.  This
+      avoids allocation in the interrupt handling path which queues
+      sages on sockets.  The dense bitmaps let transports send the
+      entire bitmap on any bitmap change reasonably efficiently.  This
+      is much easier to implement than some finer-grained
+      communication of per-port congestion.  The sender does a very
+      inexpensive bit test to test if the port it's about to send to
+      is congested or not.
+
+
+RDS Transport Layer
+==================
+
+  As mentioned above, RDS is not IB-specific. Its code is divided
+  into a general RDS layer and a transport layer.
+
+  The general layer handles the socket API, congestion handling,
+  loopback, stats, usermem pinning, and the connection state machine.
+
+  The transport layer handles the details of the transport. The IB
+  transport, for example, handles all the queue pairs, work requests,
+  CM event handlers, and other Infiniband details.
+
+
+RDS Kernel Structures
+=====================
+
+  struct rds_message
+    aka possibly "rds_outgoing", the generic RDS layer copies data to
+    be sent and sets header fields as needed, based on the socket API.
+    This is then queued for the individual connection and sent by the
+    connection's transport.
+  struct rds_incoming
+    a generic struct referring to incoming data that can be handed from
+    the transport to the general code and queued by the general code
+    while the socket is awoken. It is then passed back to the transport
+    code to handle the actual copy-to-user.
+  struct rds_socket
+    per-socket information
+  struct rds_connection
+    per-connection information
+  struct rds_transport
+    pointers to transport-specific functions
+  struct rds_statistics
+    non-transport-specific statistics
+  struct rds_cong_map
+    wraps the raw congestion bitmap, contains rbnode, waitq, etc.
+
+Connection management
+=====================
+
+  Connections may be in UP, DOWN, CONNECTING, DISCONNECTING, and
+  ERROR states.
+
+  The first time an attempt is made by an RDS socket to send data to
+  a node, a connection is allocated and connected. That connection is
+  then maintained forever -- if there are transport errors, the
+  connection will be dropped and re-established.
+
+  Dropping a connection while packets are queued will cause queued or
+  partially-sent datagrams to be retransmitted when the connection is
+  re-established.
+
+
+The send path
+=============
+
+  rds_sendmsg()
+    struct rds_message built from incoming data
+    CMSGs parsed (e.g. RDMA ops)
+    transport connection alloced and connected if not already
+    rds_message placed on send queue
+    send worker awoken
+  rds_send_worker()
+    calls rds_send_xmit() until queue is empty
+  rds_send_xmit()
+    transmits congestion map if one is pending
+    may set ACK_REQUIRED
+    calls transport to send either non-RDMA or RDMA message
+    (RDMA ops never retransmitted)
+  rds_ib_xmit()
+    allocs work requests from send ring
+    adds any new send credits available to peer (h_credits)
+    maps the rds_message's sg list
+    piggybacks ack
+    populates work requests
+    post send to connection's queue pair
+
+The recv path
+=============
+
+  rds_ib_recv_cq_comp_handler()
+    looks at write completions
+    unmaps recv buffer from device
+    no errors, call rds_ib_process_recv()
+    refill recv ring
+  rds_ib_process_recv()
+    validate header checksum
+    copy header to rds_ib_incoming struct if start of a new datagram
+    add to ibinc's fraglist
+    if competed datagram:
+      update cong map if datagram was cong update
+      call rds_recv_incoming() otherwise
+      note if ack is required
+  rds_recv_incoming()
+    drop duplicate packets
+    respond to pings
+    find the sock associated with this datagram
+    add to sock queue
+    wake up sock
+    do some congestion calculations
+  rds_recvmsg
+    copy data into user iovec
+    handle CMSGs
+    return to application
+
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/.gitignore linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/.gitignore
--- linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/.gitignore	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1 @@
+timestamping
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/Makefile linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/Makefile
--- linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,6 @@
+CPPFLAGS = -I../../../include
+
+timestamping: timestamping.c
+
+clean:
+	rm -f timestamping
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/timestamping.c linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/timestamping.c
--- linux-libre-2.6.29-gnu1/Documentation/networking/timestamping/timestamping.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/timestamping/timestamping.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,533 @@
+/*
+ * This program demonstrates how the various time stamping features in
+ * the Linux kernel work. It emulates the behavior of a PTP
+ * implementation in stand-alone master mode by sending PTPv1 Sync
+ * multicasts once every second. It looks for similar packets, but
+ * beyond that doesn't actually implement PTP.
+ *
+ * Outgoing packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support.
+ *
+ * Incoming packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
+ * SO_TIMESTAMP[NS].
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Author: Patrick Ohly <patrick.ohly@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include "asm/types.h"
+#include "linux/net_tstamp.h"
+#include "linux/errqueue.h"
+
+#ifndef SO_TIMESTAMPING
+# define SO_TIMESTAMPING         37
+# define SCM_TIMESTAMPING        SO_TIMESTAMPING
+#endif
+
+#ifndef SO_TIMESTAMPNS
+# define SO_TIMESTAMPNS 35
+#endif
+
+#ifndef SIOCGSTAMPNS
+# define SIOCGSTAMPNS 0x8907
+#endif
+
+#ifndef SIOCSHWTSTAMP
+# define SIOCSHWTSTAMP 0x89b0
+#endif
+
+static void usage(const char *error)
+{
+	if (error)
+		printf("invalid option: %s\n", error);
+	printf("timestamping interface option*\n\n"
+	       "Options:\n"
+	       "  IP_MULTICAST_LOOP - looping outgoing multicasts\n"
+	       "  SO_TIMESTAMP - normal software time stamping, ms resolution\n"
+	       "  SO_TIMESTAMPNS - more accurate software time stamping\n"
+	       "  SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
+	       "  SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
+	       "  SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
+	       "  SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
+	       "  SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
+	       "  SOF_TIMESTAMPING_SYS_HARDWARE - request reporting of transformed HW time stamps\n"
+	       "  SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
+	       "  SIOCGSTAMP - check last socket time stamp\n"
+	       "  SIOCGSTAMPNS - more accurate socket time stamp\n");
+	exit(1);
+}
+
+static void bail(const char *error)
+{
+	printf("%s: %s\n", error, strerror(errno));
+	exit(1);
+}
+
+static const unsigned char sync[] = {
+	0x00, 0x01, 0x00, 0x01,
+	0x5f, 0x44, 0x46, 0x4c,
+	0x54, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x01, 0x01,
+
+	/* fake uuid */
+	0x00, 0x01,
+	0x02, 0x03, 0x04, 0x05,
+
+	0x00, 0x01, 0x00, 0x37,
+	0x00, 0x00, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00,
+	0x49, 0x05, 0xcd, 0x01,
+	0x29, 0xb1, 0x8d, 0xb0,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x01,
+
+	/* fake uuid */
+	0x00, 0x01,
+	0x02, 0x03, 0x04, 0x05,
+
+	0x00, 0x00, 0x00, 0x37,
+	0x00, 0x00, 0x00, 0x04,
+	0x44, 0x46, 0x4c, 0x54,
+	0x00, 0x00, 0xf0, 0x60,
+	0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01,
+	0x00, 0x00, 0xf0, 0x60,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x04,
+	0x44, 0x46, 0x4c, 0x54,
+	0x00, 0x01,
+
+	/* fake uuid */
+	0x00, 0x01,
+	0x02, 0x03, 0x04, 0x05,
+
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
+{
+	struct timeval now;
+	int res;
+
+	res = sendto(sock, sync, sizeof(sync), 0,
+		addr, addr_len);
+	gettimeofday(&now, 0);
+	if (res < 0)
+		printf("%s: %s\n", "send", strerror(errno));
+	else
+		printf("%ld.%06ld: sent %d bytes\n",
+		       (long)now.tv_sec, (long)now.tv_usec,
+		       res);
+}
+
+static void printpacket(struct msghdr *msg, int res,
+			char *data,
+			int sock, int recvmsg_flags,
+			int siocgstamp, int siocgstampns)
+{
+	struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
+	struct cmsghdr *cmsg;
+	struct timeval tv;
+	struct timespec ts;
+	struct timeval now;
+
+	gettimeofday(&now, 0);
+
+	printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+	       (long)now.tv_sec, (long)now.tv_usec,
+	       (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+	       res,
+	       inet_ntoa(from_addr->sin_addr),
+	       msg->msg_controllen);
+	for (cmsg = CMSG_FIRSTHDR(msg);
+	     cmsg;
+	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
+		printf("   cmsg len %d: ", cmsg->cmsg_len);
+		switch (cmsg->cmsg_level) {
+		case SOL_SOCKET:
+			printf("SOL_SOCKET ");
+			switch (cmsg->cmsg_type) {
+			case SO_TIMESTAMP: {
+				struct timeval *stamp =
+					(struct timeval *)CMSG_DATA(cmsg);
+				printf("SO_TIMESTAMP %ld.%06ld",
+				       (long)stamp->tv_sec,
+				       (long)stamp->tv_usec);
+				break;
+			}
+			case SO_TIMESTAMPNS: {
+				struct timespec *stamp =
+					(struct timespec *)CMSG_DATA(cmsg);
+				printf("SO_TIMESTAMPNS %ld.%09ld",
+				       (long)stamp->tv_sec,
+				       (long)stamp->tv_nsec);
+				break;
+			}
+			case SO_TIMESTAMPING: {
+				struct timespec *stamp =
+					(struct timespec *)CMSG_DATA(cmsg);
+				printf("SO_TIMESTAMPING ");
+				printf("SW %ld.%09ld ",
+				       (long)stamp->tv_sec,
+				       (long)stamp->tv_nsec);
+				stamp++;
+				printf("HW transformed %ld.%09ld ",
+				       (long)stamp->tv_sec,
+				       (long)stamp->tv_nsec);
+				stamp++;
+				printf("HW raw %ld.%09ld",
+				       (long)stamp->tv_sec,
+				       (long)stamp->tv_nsec);
+				break;
+			}
+			default:
+				printf("type %d", cmsg->cmsg_type);
+				break;
+			}
+			break;
+		case IPPROTO_IP:
+			printf("IPPROTO_IP ");
+			switch (cmsg->cmsg_type) {
+			case IP_RECVERR: {
+				struct sock_extended_err *err =
+					(struct sock_extended_err *)CMSG_DATA(cmsg);
+				printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
+					strerror(err->ee_errno),
+					err->ee_origin,
+#ifdef SO_EE_ORIGIN_TIMESTAMPING
+					err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
+					"bounced packet" : "unexpected origin"
+#else
+					"probably SO_EE_ORIGIN_TIMESTAMPING"
+#endif
+					);
+				if (res < sizeof(sync))
+					printf(" => truncated data?!");
+				else if (!memcmp(sync, data + res - sizeof(sync),
+							sizeof(sync)))
+					printf(" => GOT OUR DATA BACK (HURRAY!)");
+				break;
+			}
+			case IP_PKTINFO: {
+				struct in_pktinfo *pktinfo =
+					(struct in_pktinfo *)CMSG_DATA(cmsg);
+				printf("IP_PKTINFO interface index %u",
+					pktinfo->ipi_ifindex);
+				break;
+			}
+			default:
+				printf("type %d", cmsg->cmsg_type);
+				break;
+			}
+			break;
+		default:
+			printf("level %d type %d",
+				cmsg->cmsg_level,
+				cmsg->cmsg_type);
+			break;
+		}
+		printf("\n");
+	}
+
+	if (siocgstamp) {
+		if (ioctl(sock, SIOCGSTAMP, &tv))
+			printf("   %s: %s\n", "SIOCGSTAMP", strerror(errno));
+		else
+			printf("SIOCGSTAMP %ld.%06ld\n",
+			       (long)tv.tv_sec,
+			       (long)tv.tv_usec);
+	}
+	if (siocgstampns) {
+		if (ioctl(sock, SIOCGSTAMPNS, &ts))
+			printf("   %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
+		else
+			printf("SIOCGSTAMPNS %ld.%09ld\n",
+			       (long)ts.tv_sec,
+			       (long)ts.tv_nsec);
+	}
+}
+
+static void recvpacket(int sock, int recvmsg_flags,
+		       int siocgstamp, int siocgstampns)
+{
+	char data[256];
+	struct msghdr msg;
+	struct iovec entry;
+	struct sockaddr_in from_addr;
+	struct {
+		struct cmsghdr cm;
+		char control[512];
+	} control;
+	int res;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = &entry;
+	msg.msg_iovlen = 1;
+	entry.iov_base = data;
+	entry.iov_len = sizeof(data);
+	msg.msg_name = (caddr_t)&from_addr;
+	msg.msg_namelen = sizeof(from_addr);
+	msg.msg_control = &control;
+	msg.msg_controllen = sizeof(control);
+
+	res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
+	if (res < 0) {
+		printf("%s %s: %s\n",
+		       "recvmsg",
+		       (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+		       strerror(errno));
+	} else {
+		printpacket(&msg, res, data,
+			    sock, recvmsg_flags,
+			    siocgstamp, siocgstampns);
+	}
+}
+
+int main(int argc, char **argv)
+{
+	int so_timestamping_flags = 0;
+	int so_timestamp = 0;
+	int so_timestampns = 0;
+	int siocgstamp = 0;
+	int siocgstampns = 0;
+	int ip_multicast_loop = 0;
+	char *interface;
+	int i;
+	int enabled = 1;
+	int sock;
+	struct ifreq device;
+	struct ifreq hwtstamp;
+	struct hwtstamp_config hwconfig, hwconfig_requested;
+	struct sockaddr_in addr;
+	struct ip_mreq imr;
+	struct in_addr iaddr;
+	int val;
+	socklen_t len;
+	struct timeval next;
+
+	if (argc < 2)
+		usage(0);
+	interface = argv[1];
+
+	for (i = 2; i < argc; i++) {
+		if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
+			so_timestamp = 1;
+		else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
+			so_timestampns = 1;
+		else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
+			siocgstamp = 1;
+		else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
+			siocgstampns = 1;
+		else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
+			ip_multicast_loop = 1;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SYS_HARDWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_SYS_HARDWARE;
+		else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
+			so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+		else
+			usage(argv[i]);
+	}
+
+	sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (socket < 0)
+		bail("socket");
+
+	memset(&device, 0, sizeof(device));
+	strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
+	if (ioctl(sock, SIOCGIFADDR, &device) < 0)
+		bail("getting interface IP address");
+
+	memset(&hwtstamp, 0, sizeof(hwtstamp));
+	strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
+	hwtstamp.ifr_data = (void *)&hwconfig;
+	memset(&hwconfig, 0, sizeof(&hwconfig));
+	hwconfig.tx_type =
+		(so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
+		HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+	hwconfig.rx_filter =
+		(so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
+		HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
+	hwconfig_requested = hwconfig;
+	if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
+		if ((errno == EINVAL || errno == ENOTSUP) &&
+		    hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
+		    hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
+			printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
+		else
+			bail("SIOCSHWTSTAMP");
+	}
+	printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
+	       hwconfig_requested.tx_type, hwconfig.tx_type,
+	       hwconfig_requested.rx_filter, hwconfig.rx_filter);
+
+	/* bind to PTP port */
+	addr.sin_family = AF_INET;
+	addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	addr.sin_port = htons(319 /* PTP event port */);
+	if (bind(sock,
+		 (struct sockaddr *)&addr,
+		 sizeof(struct sockaddr_in)) < 0)
+		bail("bind");
+
+	/* set multicast group for outgoing packets */
+	inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
+	addr.sin_addr = iaddr;
+	imr.imr_multiaddr.s_addr = iaddr.s_addr;
+	imr.imr_interface.s_addr =
+		((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
+	if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
+		       &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
+		bail("set multicast");
+
+	/* join multicast group, loop our own packet */
+	if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+		       &imr, sizeof(struct ip_mreq)) < 0)
+		bail("join multicast group");
+
+	if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
+		       &ip_multicast_loop, sizeof(enabled)) < 0) {
+		bail("loop multicast");
+	}
+
+	/* set socket options for time stamping */
+	if (so_timestamp &&
+		setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
+			   &enabled, sizeof(enabled)) < 0)
+		bail("setsockopt SO_TIMESTAMP");
+
+	if (so_timestampns &&
+		setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
+			   &enabled, sizeof(enabled)) < 0)
+		bail("setsockopt SO_TIMESTAMPNS");
+
+	if (so_timestamping_flags &&
+		setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
+			   &so_timestamping_flags,
+			   sizeof(so_timestamping_flags)) < 0)
+		bail("setsockopt SO_TIMESTAMPING");
+
+	/* request IP_PKTINFO for debugging purposes */
+	if (setsockopt(sock, SOL_IP, IP_PKTINFO,
+		       &enabled, sizeof(enabled)) < 0)
+		printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
+
+	/* verify socket options */
+	len = sizeof(val);
+	if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
+		printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
+	else
+		printf("SO_TIMESTAMP %d\n", val);
+
+	if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
+		printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
+		       strerror(errno));
+	else
+		printf("SO_TIMESTAMPNS %d\n", val);
+
+	if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
+		printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
+		       strerror(errno));
+	} else {
+		printf("SO_TIMESTAMPING %d\n", val);
+		if (val != so_timestamping_flags)
+			printf("   not the expected value %d\n",
+			       so_timestamping_flags);
+	}
+
+	/* send packets forever every five seconds */
+	gettimeofday(&next, 0);
+	next.tv_sec = (next.tv_sec + 1) / 5 * 5;
+	next.tv_usec = 0;
+	while (1) {
+		struct timeval now;
+		struct timeval delta;
+		long delta_us;
+		int res;
+		fd_set readfs, errorfs;
+
+		gettimeofday(&now, 0);
+		delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
+			(long)(next.tv_usec - now.tv_usec);
+		if (delta_us > 0) {
+			/* continue waiting for timeout or data */
+			delta.tv_sec = delta_us / 1000000;
+			delta.tv_usec = delta_us % 1000000;
+
+			FD_ZERO(&readfs);
+			FD_ZERO(&errorfs);
+			FD_SET(sock, &readfs);
+			FD_SET(sock, &errorfs);
+			printf("%ld.%06ld: select %ldus\n",
+			       (long)now.tv_sec, (long)now.tv_usec,
+			       delta_us);
+			res = select(sock + 1, &readfs, 0, &errorfs, &delta);
+			gettimeofday(&now, 0);
+			printf("%ld.%06ld: select returned: %d, %s\n",
+			       (long)now.tv_sec, (long)now.tv_usec,
+			       res,
+			       res < 0 ? strerror(errno) : "success");
+			if (res > 0) {
+				if (FD_ISSET(sock, &readfs))
+					printf("ready for reading\n");
+				if (FD_ISSET(sock, &errorfs))
+					printf("has error\n");
+				recvpacket(sock, 0,
+					   siocgstamp,
+					   siocgstampns);
+				recvpacket(sock, MSG_ERRQUEUE,
+					   siocgstamp,
+					   siocgstampns);
+			}
+		} else {
+			/* write one packet */
+			sendpacket(sock,
+				   (struct sockaddr *)&addr,
+				   sizeof(addr));
+			next.tv_sec += 5;
+			continue;
+		}
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/timestamping.txt linux-libre-2.6.30-gnu1/Documentation/networking/timestamping.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/timestamping.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/timestamping.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,180 @@
+The existing interfaces for getting network packages time stamped are:
+
+* SO_TIMESTAMP
+  Generate time stamp for each incoming packet using the (not necessarily
+  monotonous!) system time. Result is returned via recv_msg() in a
+  control message as timeval (usec resolution).
+
+* SO_TIMESTAMPNS
+  Same time stamping mechanism as SO_TIMESTAMP, but returns result as
+  timespec (nsec resolution).
+
+* IP_MULTICAST_LOOP + SO_TIMESTAMP[NS]
+  Only for multicasts: approximate send time stamp by receiving the looped
+  packet and using its receive time stamp.
+
+The following interface complements the existing ones: receive time
+stamps can be generated and returned for arbitrary packets and much
+closer to the point where the packet is really sent. Time stamps can
+be generated in software (as before) or in hardware (if the hardware
+has such a feature).
+
+SO_TIMESTAMPING:
+
+Instructs the socket layer which kind of information is wanted. The
+parameter is an integer with some of the following bits set. Setting
+other bits is an error and doesn't change the current state.
+
+SOF_TIMESTAMPING_TX_HARDWARE:  try to obtain send time stamp in hardware
+SOF_TIMESTAMPING_TX_SOFTWARE:  if SOF_TIMESTAMPING_TX_HARDWARE is off or
+                               fails, then do it in software
+SOF_TIMESTAMPING_RX_HARDWARE:  return the original, unmodified time stamp
+                               as generated by the hardware
+SOF_TIMESTAMPING_RX_SOFTWARE:  if SOF_TIMESTAMPING_RX_HARDWARE is off or
+                               fails, then do it in software
+SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp
+SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to
+                               the system time base
+SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
+                               software
+
+SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
+SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
+following control message:
+    struct scm_timestamping {
+           struct timespec systime;
+           struct timespec hwtimetrans;
+           struct timespec hwtimeraw;
+    };
+
+recvmsg() can be used to get this control message for regular incoming
+packets. For send time stamps the outgoing packet is looped back to
+the socket's error queue with the send time stamp(s) attached. It can
+be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the
+original outgoing packet data including all headers preprended down to
+and including the link layer, the scm_timestamping control message and
+a sock_extended_err control message with ee_errno==ENOMSG and
+ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending
+bounced packet is ready for reading as far as select() is concerned.
+If the outgoing packet has to be fragmented, then only the first
+fragment is time stamped and returned to the sending socket.
+
+All three values correspond to the same event in time, but were
+generated in different ways. Each of these values may be empty (= all
+zero), in which case no such value was available. If the application
+is not interested in some of these values, they can be left blank to
+avoid the potential overhead of calculating them.
+
+systime is the value of the system time at that moment. This
+corresponds to the value also returned via SO_TIMESTAMP[NS]. If the
+time stamp was generated by hardware, then this field is
+empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is
+set.
+
+hwtimeraw is the original hardware time stamp. Filled in if
+SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its
+relation to system time should be made.
+
+hwtimetrans is the hardware time stamp transformed so that it
+corresponds as good as possible to system time. This correlation is
+not perfect; as a consequence, sorting packets received via different
+NICs by their hwtimetrans may differ from the order in which they were
+received. hwtimetrans may be non-monotonic even for the same NIC.
+Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
+by the network device and will be empty without that support.
+
+
+SIOCSHWTSTAMP:
+
+Hardware time stamping must also be initialized for each device driver
+that is expected to do hardware time stamping. The parameter is:
+
+struct hwtstamp_config {
+    int flags;           /* no flags defined right now, must be zero */
+    int tx_type;         /* HWTSTAMP_TX_* */
+    int rx_filter;       /* HWTSTAMP_FILTER_* */
+};
+
+Desired behavior is passed into the kernel and to a specific device by
+calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
+ifr_data points to a struct hwtstamp_config. The tx_type and
+rx_filter are hints to the driver what it is expected to do. If
+the requested fine-grained filtering for incoming packets is not
+supported, the driver may time stamp more than just the requested types
+of packets.
+
+A driver which supports hardware time stamping shall update the struct
+with the actual, possibly more permissive configuration. If the
+requested packets cannot be time stamped, then nothing should be
+changed and ERANGE shall be returned (in contrast to EINVAL, which
+indicates that SIOCSHWTSTAMP is not supported at all).
+
+Only a processes with admin rights may change the configuration. User
+space is responsible to ensure that multiple processes don't interfere
+with each other and that the settings are reset.
+
+/* possible values for hwtstamp_config->tx_type */
+enum {
+	/*
+	 * no outgoing packet will need hardware time stamping;
+	 * should a packet arrive which asks for it, no hardware
+	 * time stamping will be done
+	 */
+	HWTSTAMP_TX_OFF,
+
+	/*
+	 * enables hardware time stamping for outgoing packets;
+	 * the sender of the packet decides which are to be
+	 * time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE
+	 * before sending the packet
+	 */
+	HWTSTAMP_TX_ON,
+};
+
+/* possible values for hwtstamp_config->rx_filter */
+enum {
+	/* time stamp no incoming packet at all */
+	HWTSTAMP_FILTER_NONE,
+
+	/* time stamp any incoming packet */
+	HWTSTAMP_FILTER_ALL,
+
+        /* return value: time stamp all packets requested plus some others */
+        HWTSTAMP_FILTER_SOME,
+
+	/* PTP v1, UDP, any kind of event packet */
+	HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
+
+        ...
+};
+
+
+DEVICE IMPLEMENTATION
+
+A driver which supports hardware time stamping must support the
+SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
+in the skb with skb_hwtstamp_set().
+
+Time stamps for outgoing packets are to be generated as follows:
+- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
+  returns non-zero. If yes, then the driver is expected
+  to do hardware time stamping.
+- If this is possible for the skb and requested, then declare
+  that the driver is doing the time stamping by calling
+  skb_hwtstamp_tx_in_progress(). A driver not supporting
+  hardware time stamping doesn't do that. A driver must never
+  touch sk_buff::tstamp! It is used to store how time stamping
+  for an outgoing packets is to be done.
+- As soon as the driver has sent the packet and/or obtained a
+  hardware time stamp for it, it passes the time stamp back by
+  calling skb_hwtstamp_tx() with the original skb, the raw
+  hardware time stamp and a handle to the device (necessary
+  to convert the hardware time stamp to system time). If obtaining
+  the hardware time stamp somehow fails, then the driver should
+  not fall back to software time stamping. The rationale is that
+  this would occur at a later time in the processing pipeline
+  than other software time stamping and therefore could lead
+  to unexpected deltas between time stamps.
+- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+  dev_hard_start_xmit() checks whether software time stamping
+  is wanted as fallback and potentially generates the time stamp.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/networking/vxge.txt linux-libre-2.6.30-gnu1/Documentation/networking/vxge.txt
--- linux-libre-2.6.29-gnu1/Documentation/networking/vxge.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/networking/vxge.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,100 @@
+Neterion's (Formerly S2io) X3100 Series 10GbE PCIe Server Adapter Linux driver
+==============================================================================
+
+Contents
+--------
+
+1) Introduction
+2) Features supported
+3) Configurable driver parameters
+4) Troubleshooting
+
+1) Introduction:
+----------------
+This Linux driver supports all Neterion's X3100 series 10 GbE PCIe I/O
+Virtualized Server adapters.
+The X3100 series supports four modes of operation, configurable via
+firmware -
+	Single function mode
+	Multi function mode
+	SRIOV mode
+	MRIOV mode
+The functions share a 10GbE link and the pci-e bus, but hardly anything else
+inside the ASIC. Features like independent hw reset, statistics, bandwidth/
+priority allocation and guarantees, GRO, TSO, interrupt moderation etc are
+supported independently on each function.
+
+(See below for a complete list of features supported for both IPv4 and IPv6)
+
+2) Features supported:
+----------------------
+
+i)   Single function mode (up to 17 queues)
+
+ii)  Multi function mode (up to 17 functions)
+
+iii) PCI-SIG's I/O Virtualization
+       - Single Root mode: v1.0 (up to 17 functions)
+       - Multi-Root mode: v1.0 (up to 17 functions)
+
+iv)  Jumbo frames
+       X3100 Series supports MTU up to 9600 bytes, modifiable using
+       ifconfig command.
+
+v)   Offloads supported: (Enabled by default)
+       Checksum offload (TCP/UDP/IP) on transmit and receive paths
+       TCP Segmentation Offload (TSO) on transmit path
+       Generic Receive Offload (GRO) on receive path
+
+vi)  MSI-X: (Enabled by default)
+       Resulting in noticeable performance improvement (up to 7% on certain
+       platforms).
+
+vii) NAPI: (Enabled by default)
+       For better Rx interrupt moderation.
+
+viii)RTH (Receive Traffic Hash): (Enabled by default)
+       Receive side steering for better scaling.
+
+ix)  Statistics
+       Comprehensive MAC-level and software statistics displayed using
+       "ethtool -S" option.
+
+x)   Multiple hardware queues: (Enabled by default)
+       Up to 17 hardware based transmit and receive data channels, with
+       multiple steering options (transmit multiqueue enabled by default).
+
+3) Configurable driver parameters:
+----------------------------------
+
+i)  max_config_dev
+       Specifies maximum device functions to be enabled.
+       Valid range: 1-8
+
+ii) max_config_port
+       Specifies number of ports to be enabled.
+       Valid range: 1,2
+       Default: 1
+
+iii)max_config_vpath
+       Specifies maximum VPATH(s) configured for each device function.
+       Valid range: 1-17
+
+iv) vlan_tag_strip
+       Enables/disables vlan tag stripping from all received tagged frames that
+       are not replicated at the internal L2 switch.
+       Valid range: 0,1 (disabled, enabled respectively)
+       Default: 1
+
+v)  addr_learn_en
+       Enable learning the mac address of the guest OS interface in
+       virtualization environment.
+       Valid range: 0,1 (disabled, enabled respectively)
+       Default: 0
+
+4) Troubleshooting:
+-------------------
+
+To resolve an issue with the source code or X3100 series adapter, please collect
+the statistics, register dumps using ethool, relevant logs and email them to
+support@neterion.com.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/PCI/MSI-HOWTO.txt linux-libre-2.6.30-gnu1/Documentation/PCI/MSI-HOWTO.txt
--- linux-libre-2.6.29-gnu1/Documentation/PCI/MSI-HOWTO.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/PCI/MSI-HOWTO.txt	2009-06-09 23:05:27.000000000 -0400
@@ -4,506 +4,356 @@
 	Revised Feb 12, 2004 by Martine Silbermann
 		email: Martine.Silbermann@hp.com
 	Revised Jun 25, 2004 by Tom L Nguyen
+	Revised Jul  9, 2008 by Matthew Wilcox <willy@linux.intel.com>
+		Copyright 2003, 2008 Intel Corporation
 
 1. About this guide
 
-This guide describes the basics of Message Signaled Interrupts (MSI),
-the advantages of using MSI over traditional interrupt mechanisms,
-and how to enable your driver to use MSI or MSI-X. Also included is
-a Frequently Asked Questions (FAQ) section.
-
-1.1 Terminology
-
-PCI devices can be single-function or multi-function.  In either case,
-when this text talks about enabling or disabling MSI on a "device
-function," it is referring to one specific PCI device and function and
-not to all functions on a PCI device (unless the PCI device has only
-one function).
-
-2. Copyright 2003 Intel Corporation
-
-3. What is MSI/MSI-X?
-
-Message Signaled Interrupt (MSI), as described in the PCI Local Bus
-Specification Revision 2.3 or later, is an optional feature, and a
-required feature for PCI Express devices. MSI enables a device function
-to request service by sending an Inbound Memory Write on its PCI bus to
-the FSB as a Message Signal Interrupt transaction. Because MSI is
-generated in the form of a Memory Write, all transaction conditions,
-such as a Retry, Master-Abort, Target-Abort or normal completion, are
-supported.
-
-A PCI device that supports MSI must also support pin IRQ assertion
-interrupt mechanism to provide backward compatibility for systems that
-do not support MSI. In systems which support MSI, the bus driver is
-responsible for initializing the message address and message data of
-the device function's MSI/MSI-X capability structure during device
-initial configuration.
+This guide describes the basics of Message Signaled Interrupts (MSIs),
+the advantages of using MSI over traditional interrupt mechanisms, how
+to change your driver to use MSI or MSI-X and some basic diagnostics to
+try if a device doesn't support MSIs.
 
-An MSI capable device function indicates MSI support by implementing
-the MSI/MSI-X capability structure in its PCI capability list. The
-device function may implement both the MSI capability structure and
-the MSI-X capability structure; however, the bus driver should not
-enable both.
 
-The MSI capability structure contains Message Control register,
-Message Address register and Message Data register. These registers
-provide the bus driver control over MSI. The Message Control register
-indicates the MSI capability supported by the device. The Message
-Address register specifies the target address and the Message Data
-register specifies the characteristics of the message. To request
-service, the device function writes the content of the Message Data
-register to the target address. The device and its software driver
-are prohibited from writing to these registers.
+2. What are MSIs?
 
-The MSI-X capability structure is an optional extension to MSI. It
-uses an independent and separate capability structure. There are
-some key advantages to implementing the MSI-X capability structure
-over the MSI capability structure as described below.
+A Message Signaled Interrupt is a write from the device to a special
+address which causes an interrupt to be received by the CPU.
 
-	- Support a larger maximum number of vectors per function.
+The MSI capability was first specified in PCI 2.2 and was later enhanced
+in PCI 3.0 to allow each interrupt to be masked individually.  The MSI-X
+capability was also introduced with PCI 3.0.  It supports more interrupts
+per device than MSI and allows interrupts to be independently configured.
 
-	- Provide the ability for system software to configure
-	each vector with an independent message address and message
-	data, specified by a table that resides in Memory Space.
+Devices may support both MSI and MSI-X, but only one can be enabled at
+a time.
 
-        - MSI and MSI-X both support per-vector masking. Per-vector
-	masking is an optional extension of MSI but a required
-	feature for MSI-X. Per-vector masking provides the kernel the
-	ability to mask/unmask a single MSI while running its
-	interrupt service routine. If per-vector masking is
-	not supported, then the device driver should provide the
-	hardware/software synchronization to ensure that the device
-	generates MSI when the driver wants it to do so.
 
-4. Why use MSI?
+3. Why use MSIs?
 
-As a benefit to the simplification of board design, MSI allows board
-designers to remove out-of-band interrupt routing. MSI is another
-step towards a legacy-free environment.
+There are three reasons why using MSIs can give an advantage over
+traditional pin-based interrupts.
 
-Due to increasing pressure on chipset and processor packages to
-reduce pin count, the need for interrupt pins is expected to
-diminish over time. Devices, due to pin constraints, may implement
-messages to increase performance.
+Pin-based PCI interrupts are often shared amongst several devices.
+To support this, the kernel must call each interrupt handler associated
+with an interrupt, which leads to reduced performance for the system as
+a whole.  MSIs are never shared, so this problem cannot arise.
 
-PCI Express endpoints uses INTx emulation (in-band messages) instead
-of IRQ pin assertion. Using INTx emulation requires interrupt
-sharing among devices connected to the same node (PCI bridge) while
-MSI is unique (non-shared) and does not require BIOS configuration
-support. As a result, the PCI Express technology requires MSI
-support for better interrupt performance.
+When a device writes data to memory, then raises a pin-based interrupt,
+it is possible that the interrupt may arrive before all the data has
+arrived in memory (this becomes more likely with devices behind PCI-PCI
+bridges).  In order to ensure that all the data has arrived in memory,
+the interrupt handler must read a register on the device which raised
+the interrupt.  PCI transaction ordering rules require that all the data
+arrives in memory before the value can be returned from the register.
+Using MSIs avoids this problem as the interrupt-generating write cannot
+pass the data writes, so by the time the interrupt is raised, the driver
+knows that all the data has arrived in memory.
 
-Using MSI enables the device functions to support two or more
-vectors, which can be configured to target different CPUs to
-increase scalability.
+PCI devices can only support a single pin-based interrupt per function.
+Often drivers have to query the device to find out what event has
+occurred, slowing down interrupt handling for the common case.  With
+MSIs, a device can support more interrupts, allowing each interrupt
+to be specialised to a different purpose.  One possible design gives
+infrequent conditions (such as errors) their own interrupt which allows
+the driver to handle the normal interrupt handling path more efficiently.
+Other possible designs include giving one interrupt to each packet queue
+in a network card or each port in a storage controller.
 
-5. Configuring a driver to use MSI/MSI-X
 
-By default, the kernel will not enable MSI/MSI-X on all devices that
-support this capability. The CONFIG_PCI_MSI kernel option
-must be selected to enable MSI/MSI-X support.
+4. How to use MSIs
 
-5.1 Including MSI/MSI-X support into the kernel
+PCI devices are initialised to use pin-based interrupts.  The device
+driver has to set up the device to use MSI or MSI-X.  Not all machines
+support MSIs correctly, and for those machines, the APIs described below
+will simply fail and the device will continue to use pin-based interrupts.
 
-To allow MSI/MSI-X capable device drivers to selectively enable
-MSI/MSI-X (using pci_enable_msi()/pci_enable_msix() as described
-below), the VECTOR based scheme needs to be enabled by setting
-CONFIG_PCI_MSI during kernel config.
+4.1 Include kernel support for MSIs
 
-Since the target of the inbound message is the local APIC, providing
-CONFIG_X86_LOCAL_APIC must be enabled as well as CONFIG_PCI_MSI.
+To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
+option enabled.  This option is only available on some architectures,
+and it may depend on some other options also being set.  For example,
+on x86, you must also enable X86_UP_APIC or SMP in order to see the
+CONFIG_PCI_MSI option.
 
-5.2 Configuring for MSI support
+4.2 Using MSI
 
-Due to the non-contiguous fashion in vector assignment of the
-existing Linux kernel, this version does not support multiple
-messages regardless of a device function is capable of supporting
-more than one vector. To enable MSI on a device function's MSI
-capability structure requires a device driver to call the function
-pci_enable_msi() explicitly.
+Most of the hard work is done for the driver in the PCI layer.  It simply
+has to request that the PCI layer set up the MSI capability for this
+device.
 
-5.2.1 API pci_enable_msi
+4.2.1 pci_enable_msi
 
 int pci_enable_msi(struct pci_dev *dev)
 
-With this new API, a device driver that wants to have MSI
-enabled on its device function must call this API to enable MSI.
-A successful call will initialize the MSI capability structure
-with ONE vector, regardless of whether a device function is
-capable of supporting multiple messages. This vector replaces the
-pre-assigned dev->irq with a new MSI vector. To avoid a conflict
-of the new assigned vector with existing pre-assigned vector requires
-a device driver to call this API before calling request_irq().
-
-5.2.2 API pci_disable_msi
-
-void pci_disable_msi(struct pci_dev *dev)
-
-This API should always be used to undo the effect of pci_enable_msi()
-when a device driver is unloading. This API restores dev->irq with
-the pre-assigned IOAPIC vector and switches a device's interrupt
-mode to PCI pin-irq assertion/INTx emulation mode.
-
-Note that a device driver should always call free_irq() on the MSI vector
-that it has done request_irq() on before calling this API. Failure to do
-so results in a BUG_ON() and a device will be left with MSI enabled and
-leaks its vector.
-
-5.2.3 MSI mode vs. legacy mode diagram
-
-The below diagram shows the events which switch the interrupt
-mode on the MSI-capable device function between MSI mode and
-PIN-IRQ assertion mode.
-
-	 ------------   pci_enable_msi 	 ------------------------
-	|	     | <===============	| 			 |
-	| MSI MODE   |	  	     	| PIN-IRQ ASSERTION MODE |
-	| 	     | ===============>	|			 |
- 	 ------------	pci_disable_msi  ------------------------
-
-
-Figure 1. MSI Mode vs. Legacy Mode
-
-In Figure 1, a device operates by default in legacy mode. Legacy
-in this context means PCI pin-irq assertion or PCI-Express INTx
-emulation. A successful MSI request (using pci_enable_msi()) switches
-a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
-stored in dev->irq will be saved by the PCI subsystem and a new
-assigned MSI vector will replace dev->irq.
-
-To return back to its default mode, a device driver should always call
-pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
-device driver should always call free_irq() on the MSI vector it has
-done request_irq() on before calling pci_disable_msi(). Failure to do
-so results in a BUG_ON() and a device will be left with MSI enabled and
-leaks its vector. Otherwise, the PCI subsystem restores a device's
-dev->irq with a pre-assigned IOAPIC vector and marks the released
-MSI vector as unused.
-
-Once being marked as unused, there is no guarantee that the PCI
-subsystem will reserve this MSI vector for a device. Depending on
-the availability of current PCI vector resources and the number of
-MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
-
-For the case where the PCI subsystem re-assigns this MSI vector to
-another driver, a request to switch back to MSI mode may result
-in being assigned a different MSI vector or a failure if no more
-vectors are available.
+A successful call will allocate ONE interrupt to the device, regardless
+of how many MSIs the device supports.  The device will be switched from
+pin-based interrupt mode to MSI mode.  The dev->irq number is changed
+to a new number which represents the message signaled interrupt.
+This function should be called before the driver calls request_irq()
+since enabling MSIs disables the pin-based IRQ and the driver will not
+receive interrupts on the old interrupt.
 
-5.3 Configuring for MSI-X support
+4.2.2 pci_enable_msi_block
 
-Due to the ability of the system software to configure each vector of
-the MSI-X capability structure with an independent message address
-and message data, the non-contiguous fashion in vector assignment of
-the existing Linux kernel has no impact on supporting multiple
-messages on an MSI-X capable device functions. To enable MSI-X on
-a device function's MSI-X capability structure requires its device
-driver to call the function pci_enable_msix() explicitly.
+int pci_enable_msi_block(struct pci_dev *dev, int count)
 
-The function pci_enable_msix(), once invoked, enables either
-all or nothing, depending on the current availability of PCI vector
-resources. If the PCI vector resources are available for the number
-of vectors requested by a device driver, this function will configure
-the MSI-X table of the MSI-X capability structure of a device with
-requested messages. To emphasize this reason, for example, a device
-may be capable for supporting the maximum of 32 vectors while its
-software driver usually may request 4 vectors. It is recommended
-that the device driver should call this function once during the
-initialization phase of the device driver.
+This variation on the above call allows a device driver to request multiple
+MSIs.  The MSI specification only allows interrupts to be allocated in
+powers of two, up to a maximum of 2^5 (32).
 
-Unlike the function pci_enable_msi(), the function pci_enable_msix()
-does not replace the pre-assigned IOAPIC dev->irq with a new MSI
-vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
-into the field vector of each element contained in a second argument.
-Note that the pre-assigned IOAPIC dev->irq is valid only if the device
-operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
-using dev->irq by the device driver to request for interrupt service
-may result in unpredictable behavior.
+If this function returns 0, it has succeeded in allocating at least as many
+interrupts as the driver requested (it may have allocated more in order
+to satisfy the power-of-two requirement).  In this case, the function
+enables MSI on this device and updates dev->irq to be the lowest of
+the new interrupts assigned to it.  The other interrupts assigned to
+the device are in the range dev->irq to dev->irq + count - 1.
 
-For each MSI-X vector granted, a device driver is responsible for calling
-other functions like request_irq(), enable_irq(), etc. to enable
-this vector with its corresponding interrupt service handler. It is
-a device driver's choice to assign all vectors with the same
-interrupt service handler or each vector with a unique interrupt
-service handler.
+If this function returns a negative number, it indicates an error and
+the driver should not attempt to request any more MSI interrupts for
+this device.  If this function returns a positive number, it will be
+less than 'count' and indicate the number of interrupts that could have
+been allocated.  In neither case will the irq value have been
+updated, nor will the device have been switched into MSI mode.
 
-5.3.1 Handling MMIO address space of MSI-X Table
+The device driver must decide what action to take if
+pci_enable_msi_block() returns a value less than the number asked for.
+Some devices can make use of fewer interrupts than the maximum they
+request; in this case the driver should call pci_enable_msi_block()
+again.  Note that it is not guaranteed to succeed, even when the
+'count' has been reduced to the value returned from a previous call to
+pci_enable_msi_block().  This is because there are multiple constraints
+on the number of vectors that can be allocated; pci_enable_msi_block()
+will return as soon as it finds any constraint that doesn't allow the
+call to succeed.
 
-The PCI 3.0 specification has implementation notes that MMIO address
-space for a device's MSI-X structure should be isolated so that the
-software system can set different pages for controlling accesses to the
-MSI-X structure. The implementation of MSI support requires the PCI
-subsystem, not a device driver, to maintain full control of the MSI-X
-table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
-table/MSI-X PBA.  A device driver should not access the MMIO address
-space of the MSI-X table/MSI-X PBA.
+4.2.3 pci_disable_msi
 
-5.3.2 API pci_enable_msix
+void pci_disable_msi(struct pci_dev *dev)
 
-int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
+This function should be used to undo the effect of pci_enable_msi() or
+pci_enable_msi_block().  Calling it restores dev->irq to the pin-based
+interrupt number and frees the previously allocated message signaled
+interrupt(s).  The interrupt may subsequently be assigned to another
+device, so drivers should not cache the value of dev->irq.
 
-This API enables a device driver to request the PCI subsystem
-to enable MSI-X messages on its hardware device. Depending on
-the availability of PCI vectors resources, the PCI subsystem enables
-either all or none of the requested vectors.
+A device driver must always call free_irq() on the interrupt(s)
+for which it has called request_irq() before calling this function.
+Failure to do so will result in a BUG_ON(), the device will be left with
+MSI enabled and will leak its vector.
 
-Argument 'dev' points to the device (pci_dev) structure.
+4.3 Using MSI-X
 
-Argument 'entries' is a pointer to an array of msix_entry structs.
-The number of entries is indicated in argument 'nvec'.
-struct msix_entry is defined in /driver/pci/msi.h:
+The MSI-X capability is much more flexible than the MSI capability.
+It supports up to 2048 interrupts, each of which can be controlled
+independently.  To support this flexibility, drivers must use an array of
+`struct msix_entry':
 
 struct msix_entry {
 	u16 	vector; /* kernel uses to write alloc vector */
 	u16	entry; /* driver uses to specify entry */
 };
 
-A device driver is responsible for initializing the field 'entry' of
-each element with a unique entry supported by MSI-X table. Otherwise,
--EINVAL will be returned as a result. A successful return of zero
-indicates the PCI subsystem completed initializing each of the requested
-entries of the MSI-X table with message address and message data.
-Last but not least, the PCI subsystem will write the 1:1
-vector-to-entry mapping into the field 'vector' of each element. A
-device driver is responsible for keeping track of allocated MSI-X
-vectors in its internal data structure.
-
-A return of zero indicates that the number of MSI-X vectors was
-successfully allocated. A return of greater than zero indicates
-MSI-X vector shortage. Or a return of less than zero indicates
-a failure. This failure may be a result of duplicate entries
-specified in second argument, or a result of no available vector,
-or a result of failing to initialize MSI-X table entries.
-
-5.3.3 API pci_disable_msix
+This allows for the device to use these interrupts in a sparse fashion;
+for example it could use interrupts 3 and 1027 and allocate only a
+two-element array.  The driver is expected to fill in the 'entry' value
+in each element of the array to indicate which entries it wants the kernel
+to assign interrupts for.  It is invalid to fill in two entries with the
+same number.
 
-void pci_disable_msix(struct pci_dev *dev)
+4.3.1 pci_enable_msix
 
-This API should always be used to undo the effect of pci_enable_msix()
-when a device driver is unloading. Note that a device driver should
-always call free_irq() on all MSI-X vectors it has done request_irq()
-on before calling this API. Failure to do so results in a BUG_ON() and
-a device will be left with MSI-X enabled and leaks its vectors.
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 
-5.3.4 MSI-X mode vs. legacy mode diagram
+Calling this function asks the PCI subsystem to allocate 'nvec' MSIs.
+The 'entries' argument is a pointer to an array of msix_entry structs
+which should be at least 'nvec' entries in size.  On success, the
+function will return 0 and the device will have been switched into
+MSI-X interrupt mode.  The 'vector' elements in each entry will have
+been filled in with the interrupt number.  The driver should then call
+request_irq() for each 'vector' that it decides to use.
 
-The below diagram shows the events which switch the interrupt
-mode on the MSI-X capable device function between MSI-X mode and
-PIN-IRQ assertion mode (legacy).
+If this function returns a negative number, it indicates an error and
+the driver should not attempt to allocate any more MSI-X interrupts for
+this device.  If it returns a positive number, it indicates the maximum
+number of interrupt vectors that could have been allocated. See example
+below.
 
-	 ------------   pci_enable_msix(,,n) ------------------------
-	|	     | <===============	    | 			     |
-	| MSI-X MODE |	  	     	    | PIN-IRQ ASSERTION MODE |
-	| 	     | ===============>	    |			     |
- 	 ------------	pci_disable_msix     ------------------------
+This function, in contrast with pci_enable_msi(), does not adjust
+dev->irq.  The device will not generate interrupts for this interrupt
+number once MSI-X is enabled.  The device driver is responsible for
+keeping track of the interrupts assigned to the MSI-X vectors so it can
+free them again later.
 
-Figure 2. MSI-X Mode vs. Legacy Mode
+Device drivers should normally call this function once per device
+during the initialization phase.
 
-In Figure 2, a device operates by default in legacy mode. A
-successful MSI-X request (using pci_enable_msix()) switches a
-device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
-stored in dev->irq will be saved by the PCI subsystem; however,
-unlike MSI mode, the PCI subsystem will not replace dev->irq with
-assigned MSI-X vector because the PCI subsystem already writes the 1:1
-vector-to-entry mapping into the field 'vector' of each element
-specified in second argument.
+It is ideal if drivers can cope with a variable number of MSI-X interrupts,
+there are many reasons why the platform may not be able to provide the
+exact number a driver asks for.
 
-To return back to its default mode, a device driver should always call
-pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
-a device driver should always call free_irq() on all MSI-X vectors it
-has done request_irq() on before calling pci_disable_msix(). Failure
-to do so results in a BUG_ON() and a device will be left with MSI-X
-enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
-device function's interrupt mode from MSI-X mode to legacy mode and
-marks all allocated MSI-X vectors as unused.
+A request loop to achieve that might look like:
 
-Once being marked as unused, there is no guarantee that the PCI
-subsystem will reserve these MSI-X vectors for a device. Depending on
-the availability of current PCI vector resources and the number of
-MSI/MSI-X requests from other drivers, these MSI-X vectors may be
-re-assigned.
+static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
+{
+	while (nvec >= FOO_DRIVER_MINIMUM_NVEC) {
+		rc = pci_enable_msix(adapter->pdev,
+				     adapter->msix_entries, nvec);
+		if (rc > 0)
+			nvec = rc;
+		else
+			return rc;
+	}
 
-For the case where the PCI subsystem re-assigned these MSI-X vectors
-to other drivers, a request to switch back to MSI-X mode may result
-being assigned with another set of MSI-X vectors or a failure if no
-more vectors are available.
+	return -ENOSPC;
+}
 
-5.4 Handling function implementing both MSI and MSI-X capabilities
+4.3.2 pci_disable_msix
 
-For the case where a function implements both MSI and MSI-X
-capabilities, the PCI subsystem enables a device to run either in MSI
-mode or MSI-X mode but not both. A device driver determines whether it
-wants MSI or MSI-X enabled on its hardware device. Once a device
-driver requests for MSI, for example, it is prohibited from requesting
-MSI-X; in other words, a device driver is not permitted to ping-pong
-between MSI mod MSI-X mode during a run-time.
+void pci_disable_msix(struct pci_dev *dev)
 
-5.5 Hardware requirements for MSI/MSI-X support
+This API should be used to undo the effect of pci_enable_msix().  It frees
+the previously allocated message signaled interrupts.  The interrupts may
+subsequently be assigned to another device, so drivers should not cache
+the value of the 'vector' elements over a call to pci_disable_msix().
 
-MSI/MSI-X support requires support from both system hardware and
-individual hardware device functions.
+A device driver must always call free_irq() on the interrupt(s)
+for which it has called request_irq() before calling this function.
+Failure to do so will result in a BUG_ON(), the device will be left with
+MSI enabled and will leak its vector.
 
-5.5.1 Required x86 hardware support
+4.3.3 The MSI-X Table
 
-Since the target of MSI address is the local APIC CPU, enabling
-MSI/MSI-X support in the Linux kernel is dependent on whether existing
-system hardware supports local APIC. Users should verify that their
-system supports local APIC operation by testing that it runs when
-CONFIG_X86_LOCAL_APIC=y.
+The MSI-X capability specifies a BAR and offset within that BAR for the
+MSI-X Table.  This address is mapped by the PCI subsystem, and should not
+be accessed directly by the device driver.  If the driver wishes to
+mask or unmask an interrupt, it should call disable_irq() / enable_irq().
 
-In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
-however, in UP environment, users must manually set
-CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
-CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
-MSI-capable device drivers to selectively enable MSI/MSI-X.
+4.4 Handling devices implementing both MSI and MSI-X capabilities
 
-Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
-vector is allocated new during runtime and MSI/MSI-X support does not
-depend on BIOS support. This key independency enables MSI/MSI-X
-support on future IOxAPIC free platforms.
+If a device implements both MSI and MSI-X capabilities, it can
+run in either MSI mode or MSI-X mode but not both simultaneously.
+This is a requirement of the PCI spec, and it is enforced by the
+PCI layer.  Calling pci_enable_msi() when MSI-X is already enabled or
+pci_enable_msix() when MSI is already enabled will result in an error.
+If a device driver wishes to switch between MSI and MSI-X at runtime,
+it must first quiesce the device, then switch it back to pin-interrupt
+mode, before calling pci_enable_msi() or pci_enable_msix() and resuming
+operation.  This is not expected to be a common operation but may be
+useful for debugging or testing during development.
 
-5.5.2 Device hardware support
+4.5 Considerations when using MSIs
 
-The hardware device function supports MSI by indicating the
-MSI/MSI-X capability structure on its PCI capability list. By
-default, this capability structure will not be initialized by
-the kernel to enable MSI during the system boot. In other words,
-the device function is running on its default pin assertion mode.
-Note that in many cases the hardware supporting MSI have bugs,
-which may result in system hangs. The software driver of specific
-MSI-capable hardware is responsible for deciding whether to call
-pci_enable_msi or not. A return of zero indicates the kernel
-successfully initialized the MSI/MSI-X capability structure of the
-device function. The device function is now running on MSI/MSI-X mode.
+4.5.1 Choosing between MSI-X and MSI
 
-5.6 How to tell whether MSI/MSI-X is enabled on device function
+If your device supports both MSI-X and MSI capabilities, you should use
+the MSI-X facilities in preference to the MSI facilities.  As mentioned
+above, MSI-X supports any number of interrupts between 1 and 2048.
+In constrast, MSI is restricted to a maximum of 32 interrupts (and
+must be a power of two).  In addition, the MSI interrupt vectors must
+be allocated consecutively, so the system may not be able to allocate
+as many vectors for MSI as it could for MSI-X.  On some platforms, MSI
+interrupts must all be targetted at the same set of CPUs whereas MSI-X
+interrupts can all be targetted at different CPUs.
 
-At the driver level, a return of zero from the function call of
-pci_enable_msi()/pci_enable_msix() indicates to a device driver that
-its device function is initialized successfully and ready to run in
-MSI/MSI-X mode.
+4.5.2 Spinlocks
 
-At the user level, users can use the command 'cat /proc/interrupts'
-to display the vectors allocated for devices and their interrupt
-MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
-enabled on a SCSI Adaptec 39320D Ultra320 controller.
+Most device drivers have a per-device spinlock which is taken in the
+interrupt handler.  With pin-based interrupts or a single MSI, it is not
+necessary to disable interrupts (Linux guarantees the same interrupt will
+not be re-entered).  If a device uses multiple interrupts, the driver
+must disable interrupts while the lock is held.  If the device sends
+a different interrupt, the driver will deadlock trying to recursively
+acquire the spinlock.
 
-           CPU0       CPU1
-  0:     324639          0    IO-APIC-edge  timer
-  1:       1186          0    IO-APIC-edge  i8042
-  2:          0          0          XT-PIC  cascade
- 12:       2797          0    IO-APIC-edge  i8042
- 14:       6543          0    IO-APIC-edge  ide0
- 15:          1          0    IO-APIC-edge  ide1
-169:          0          0   IO-APIC-level  uhci-hcd
-185:          0          0   IO-APIC-level  uhci-hcd
-193:        138         10         PCI-MSI  aic79xx
-201:         30          0         PCI-MSI  aic79xx
-225:         30          0   IO-APIC-level  aic7xxx
-233:         30          0   IO-APIC-level  aic7xxx
-NMI:          0          0
-LOC:     324553     325068
-ERR:          0
-MIS:          0
+There are two solutions.  The first is to take the lock with
+spin_lock_irqsave() or spin_lock_irq() (see
+Documentation/DocBook/kernel-locking).  The second is to specify
+IRQF_DISABLED to request_irq() so that the kernel runs the entire
+interrupt routine with interrupts disabled.
 
-6. MSI quirks
+If your MSI interrupt routine does not hold the lock for the whole time
+it is running, the first solution may be best.  The second solution is
+normally preferred as it avoids making two transitions from interrupt
+disabled to enabled and back again.
 
-Several PCI chipsets or devices are known to not support MSI.
-The PCI stack provides 3 possible levels of MSI disabling:
-* on a single device
-* on all devices behind a specific bridge
-* globally
+4.6 How to tell whether MSI/MSI-X is enabled on a device
 
-6.1. Disabling MSI on a single device
+Using 'lspci -v' (as root) may show some devices with "MSI", "Message
+Signalled Interrupts" or "MSI-X" capabilities.  Each of these capabilities
+has an 'Enable' flag which will be followed with either "+" (enabled)
+or "-" (disabled).
 
-Under some circumstances it might be required to disable MSI on a
-single device.  This may be achieved by either not calling pci_enable_msi()
-or all, or setting the pci_dev->no_msi flag before (most of the time
-in a quirk).
 
-6.2. Disabling MSI below a bridge
+5. MSI quirks
 
-The vast majority of MSI quirks are required by PCI bridges not
-being able to route MSI between busses. In this case, MSI have to be
-disabled on all devices behind this bridge. It is achieves by setting
-the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge
-subordinate bus. There is no need to set the same flag on bridges that
-are below the broken bridge. When pci_enable_msi() is called to enable
-MSI on a device, pci_msi_supported() takes care of checking the NO_MSI
-flag in all parent busses of the device.
+Several PCI chipsets or devices are known not to support MSIs.
+The PCI stack provides three ways to disable MSIs:
 
-Some bridges actually support dynamic MSI support enabling/disabling
-by changing some bits in their PCI configuration space (especially
-the Hypertransport chipsets such as the nVidia nForce and Serverworks
-HT2000). It may then be required to update the NO_MSI flag on the
-corresponding devices in the sysfs hierarchy. To enable MSI support
-on device "0000:00:0e", do:
+1. globally
+2. on all devices behind a specific bridge
+3. on a single device
 
-	echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus
+5.1. Disabling MSIs globally
 
-To disable MSI support, echo 0 instead of 1. Note that it should be
-used with caution since changing this value might break interrupts.
+Some host chipsets simply don't support MSIs properly.  If we're
+lucky, the manufacturer knows this and has indicated it in the ACPI
+FADT table.  In this case, Linux will automatically disable MSIs.
+Some boards don't include this information in the table and so we have
+to detect them ourselves.  The complete list of these is found near the
+quirk_disable_all_msi() function in drivers/pci/quirks.c.
 
-6.3. Disabling MSI globally
+If you have a board which has problems with MSIs, you can pass pci=nomsi
+on the kernel command line to disable MSIs on all devices.  It would be
+in your best interests to report the problem to linux-pci@vger.kernel.org
+including a full 'lspci -v' so we can add the quirks to the kernel.
 
-Some extreme cases may require to disable MSI globally on the system.
-For now, the only known case is a Serverworks PCI-X chipsets (MSI are
-not supported on several busses that are not all connected to the
-chipset in the Linux PCI hierarchy). In the vast majority of other
-cases, disabling only behind a specific bridge is enough.
+5.2. Disabling MSIs below a bridge
 
-For debugging purpose, the user may also pass pci=nomsi on the kernel
-command-line to explicitly disable MSI globally. But, once the appro-
-priate quirks are added to the kernel, this option should not be
-required anymore.
+Some PCI bridges are not able to route MSIs between busses properly.
+In this case, MSIs must be disabled on all devices behind the bridge.
 
-6.4. Finding why MSI cannot be enabled on a device
+Some bridges allow you to enable MSIs by changing some bits in their
+PCI configuration space (especially the Hypertransport chipsets such
+as the nVidia nForce and Serverworks HT2000).  As with host chipsets,
+Linux mostly knows about them and automatically enables MSIs if it can.
+If you have a bridge which Linux doesn't yet know about, you can enable
+MSIs in configuration space using whatever method you know works, then
+enable MSIs on that bridge by doing:
 
-Assuming that MSI are not enabled on a device, you should look at
-dmesg to find messages that quirks may output when disabling MSI
-on some devices, some bridges or even globally.
-Then, lspci -t gives the list of bridges above a device. Reading
-/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI
-are enabled (1) or disabled (0). In 0 is found in a single bridge
-msi_bus file above the device, MSI cannot be enabled.
+       echo 1 > /sys/bus/pci/devices/$bridge/msi_bus
 
-7. FAQ
+where $bridge is the PCI address of the bridge you've enabled (eg
+0000:00:0e.0).
 
-Q1. Are there any limitations on using the MSI?
+To disable MSIs, echo 0 instead of 1.  Changing this value should be
+done with caution as it can break interrupt handling for all devices
+below this bridge.
 
-A1. If the PCI device supports MSI and conforms to the
-specification and the platform supports the APIC local bus,
-then using MSI should work.
+Again, please notify linux-pci@vger.kernel.org of any bridges that need
+special handling.
 
-Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
-AMD processors)? In P3 IPI's are transmitted on the APIC local
-bus and in P4 and Xeon they are transmitted on the system
-bus. Are there any implications with this?
+5.3. Disabling MSIs on a single device
 
-A2. MSI support enables a PCI device sending an inbound
-memory write (0xfeexxxxx as target address) on its PCI bus
-directly to the FSB. Since the message address has a
-redirection hint bit cleared, it should work.
+Some devices are known to have faulty MSI implementations.  Usually this
+is handled in the individual device driver but occasionally it's necessary
+to handle this with a quirk.  Some drivers have an option to disable use
+of MSI.  While this is a convenient workaround for the driver author,
+it is not good practise, and should not be emulated.
 
-Q3. The target address 0xfeexxxxx will be translated by the
-Host Bridge into an interrupt message. Are there any
-limitations on the chipsets such as Intel 8xx, Intel e7xxx,
-or VIA?
+5.4. Finding why MSIs are disabled on a device
 
-A3. If these chipsets support an inbound memory write with
-target address set as 0xfeexxxxx, as conformed to PCI
-specification 2.3 or latest, then it should work.
+From the above three sections, you can see that there are many reasons
+why MSIs may not be enabled for a given device.  Your first step should
+be to examine your dmesg carefully to determine whether MSIs are enabled
+for your machine.  You should also check your .config to be sure you
+have enabled CONFIG_PCI_MSI.
 
-Q4. From the driver point of view, if the MSI is lost because
-of errors occurring during inbound memory write, then it may
-wait forever. Is there a mechanism for it to recover?
+Then, 'lspci -t' gives the list of bridges above a device.  Reading
+/sys/bus/pci/devices/*/msi_bus will tell you whether MSI are enabled (1)
+or disabled (0).  If 0 is found in any of the msi_bus files belonging
+to bridges between the PCI root and the device, MSIs are disabled.
 
-A4. Since the target of the transaction is an inbound memory
-write, all transaction termination conditions (Retry,
-Master-Abort, Target-Abort, or normal completion) are
-supported. A device sending an MSI must abide by all the PCI
-rules and conditions regarding that inbound memory write. So,
-if a retry is signaled it must retry, etc... We believe that
-the recommendation for Abort is also a retry (refer to PCI
-specification 2.3 or latest).
+It is also worth checking the device driver to see whether it supports MSIs.
+For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or
+pci_enable_msi_block().
diff -druNp linux-libre-2.6.29-gnu1/Documentation/PCI/pci-iov-howto.txt linux-libre-2.6.30-gnu1/Documentation/PCI/pci-iov-howto.txt
--- linux-libre-2.6.29-gnu1/Documentation/PCI/pci-iov-howto.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/PCI/pci-iov-howto.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,99 @@
+		PCI Express I/O Virtualization Howto
+		Copyright (C) 2009 Intel Corporation
+		    Yu Zhao <yu.zhao@intel.com>
+
+
+1. Overview
+
+1.1 What is SR-IOV
+
+Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
+capability which makes one physical device appear as multiple virtual
+devices. The physical device is referred to as Physical Function (PF)
+while the virtual devices are referred to as Virtual Functions (VF).
+Allocation of the VF can be dynamically controlled by the PF via
+registers encapsulated in the capability. By default, this feature is
+not enabled and the PF behaves as traditional PCIe device. Once it's
+turned on, each VF's PCI configuration space can be accessed by its own
+Bus, Device and Function Number (Routing ID). And each VF also has PCI
+Memory Space, which is used to map its register set. VF device driver
+operates on the register set so it can be functional and appear as a
+real existing PCI device.
+
+2. User Guide
+
+2.1 How can I enable SR-IOV capability
+
+The device driver (PF driver) will control the enabling and disabling
+of the capability via API provided by SR-IOV core. If the hardware
+has SR-IOV capability, loading its PF driver would enable it and all
+VFs associated with the PF.
+
+2.2 How can I use the Virtual Functions
+
+The VF is treated as hot-plugged PCI devices in the kernel, so they
+should be able to work in the same way as real PCI devices. The VF
+requires device driver that is same as a normal PCI device's.
+
+3. Developer Guide
+
+3.1 SR-IOV API
+
+To enable SR-IOV capability:
+	int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
+	'nr_virtfn' is number of VFs to be enabled.
+
+To disable SR-IOV capability:
+	void pci_disable_sriov(struct pci_dev *dev);
+
+To notify SR-IOV core of Virtual Function Migration:
+	irqreturn_t pci_sriov_migration(struct pci_dev *dev);
+
+3.2 Usage example
+
+Following piece of code illustrates the usage of the SR-IOV API.
+
+static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	pci_enable_sriov(dev, NR_VIRTFN);
+
+	...
+
+	return 0;
+}
+
+static void __devexit dev_remove(struct pci_dev *dev)
+{
+	pci_disable_sriov(dev);
+
+	...
+}
+
+static int dev_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	...
+
+	return 0;
+}
+
+static int dev_resume(struct pci_dev *dev)
+{
+	...
+
+	return 0;
+}
+
+static void dev_shutdown(struct pci_dev *dev)
+{
+	...
+}
+
+static struct pci_driver dev_driver = {
+	.name =		"SR-IOV Physical Function driver",
+	.id_table =	dev_id_table,
+	.probe =	dev_probe,
+	.remove =	__devexit_p(dev_remove),
+	.suspend =	dev_suspend,
+	.resume =	dev_resume,
+	.shutdown =	dev_shutdown,
+};
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/booting-without-of.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/booting-without-of.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/booting-without-of.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/booting-without-of.txt	2009-06-09 23:05:27.000000000 -0400
@@ -43,12 +43,11 @@ Table of Contents
     2) Representing devices without a current OF specification
       a) PHY nodes
       b) Interrupt controllers
-      c) CFI or JEDEC memory-mapped NOR flash
-      d) 4xx/Axon EMAC ethernet nodes
-      e) Xilinx IP cores
-      f) USB EHCI controllers
-      g) MDIO on GPIOs
-      h) SPI busses
+      c) 4xx/Axon EMAC ethernet nodes
+      d) Xilinx IP cores
+      e) USB EHCI controllers
+      f) MDIO on GPIOs
+      g) SPI busses
 
   VII - Marvell Discovery mv64[345]6x System Controller chips
     1) The /system-controller node
@@ -999,7 +998,7 @@ compatibility.
       translation of SOC addresses for memory mapped SOC registers.
     - bus-frequency: Contains the bus frequency for the SOC node.
       Typically, the value of this field is filled in by the boot
-      loader. 
+      loader.
 
 
   Recommended properties:
@@ -1287,71 +1286,7 @@ platforms are moved over to use the flat
 		device_type = "open-pic";
 	};
 
-   c) CFI or JEDEC memory-mapped NOR flash
-
-    Flash chips (Memory Technology Devices) are often used for solid state
-    file systems on embedded devices.
-
-     - compatible : should contain the specific model of flash chip(s)
-       used, if known, followed by either "cfi-flash" or "jedec-flash"
-     - reg : Address range of the flash chip
-     - bank-width : Width (in bytes) of the flash bank.  Equal to the
-       device width times the number of interleaved chips.
-     - device-width : (optional) Width of a single flash chip.  If
-       omitted, assumed to be equal to 'bank-width'.
-     - #address-cells, #size-cells : Must be present if the flash has
-       sub-nodes representing partitions (see below).  In this case
-       both #address-cells and #size-cells must be equal to 1.
-
-    For JEDEC compatible devices, the following additional properties
-    are defined:
-
-     - vendor-id : Contains the flash chip's vendor id (1 byte).
-     - device-id : Contains the flash chip's device id (1 byte).
-
-    In addition to the information on the flash bank itself, the
-    device tree may optionally contain additional information
-    describing partitions of the flash address space.  This can be
-    used on platforms which have strong conventions about which
-    portions of the flash are used for what purposes, but which don't
-    use an on-flash partition table such as RedBoot.
-
-    Each partition is represented as a sub-node of the flash device.
-    Each node's name represents the name of the corresponding
-    partition of the flash device.
-
-    Flash partitions
-     - reg : The partition's offset and size within the flash bank.
-     - label : (optional) The label / name for this flash partition.
-       If omitted, the label is taken from the node name (excluding
-       the unit address).
-     - read-only : (optional) This parameter, if present, is a hint to
-       Linux that this flash partition should only be mounted
-       read-only.  This is usually used for flash partitions
-       containing early-boot firmware images or data which should not
-       be clobbered.
-
-    Example:
-
-	flash@ff000000 {
-		compatible = "amd,am29lv128ml", "cfi-flash";
-		reg = <ff000000 01000000>;
-		bank-width = <4>;
-		device-width = <1>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		fs@0 {
-			label = "fs";
-			reg = <0 f80000>;
-		};
-		firmware@f80000 {
-			label ="firmware";
-			reg = <f80000 80000>;
-			read-only;
-		};
-	};
-
-    d) 4xx/Axon EMAC ethernet nodes
+    c) 4xx/Axon EMAC ethernet nodes
 
     The EMAC ethernet controller in IBM and AMCC 4xx chips, and also
     the Axon bridge.  To operate this needs to interact with a ths
@@ -1499,7 +1434,7 @@ platforms are moved over to use the flat
 			   available.
 			   For Axon: 0x0000012a
 
-   e) Xilinx IP cores
+   d) Xilinx IP cores
 
    The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
    in Xilinx Spartan and Virtex FPGAs.  The devices cover the whole range
@@ -1761,7 +1696,7 @@ platforms are moved over to use the flat
       listed above, nodes for these devices should include a phy-handle
       property, and may include other common network device properties
       like local-mac-address.
-      
+
       iv) Xilinx Uartlite
 
       Xilinx uartlite devices are simple fixed speed serial ports.
@@ -1793,7 +1728,7 @@ platforms are moved over to use the flat
        - reg-offset : A value of 3 is required
        - reg-shift : A value of 2 is required
 
-    f) USB EHCI controllers
+    e) USB EHCI controllers
 
     Required properties:
       - compatible : should be "usb-ehci".
@@ -1819,7 +1754,7 @@ platforms are moved over to use the flat
 		   big-endian;
 	   };
 
-   g) MDIO on GPIOs
+   f) MDIO on GPIOs
 
    Currently defined compatibles:
    - virtual,gpio-mdio
@@ -1839,7 +1774,7 @@ platforms are moved over to use the flat
 			 &qe_pio_c 6>;
 	};
 
-    h) SPI (Serial Peripheral Interface) busses
+    g) SPI (Serial Peripheral Interface) busses
 
     SPI busses can be described with a node for the SPI master device
     and a set of child nodes for each SPI slave on the bus.  For this
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 * Uploaded QE firmware
 
-      If a new firwmare has been uploaded to the QE (usually by the
+      If a new firmware has been uploaded to the QE (usually by the
       boot loader), then a 'firmware' child node should be added to the QE
       node.  This node provides information on the uploaded firmware that
       device drivers may need.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/dma.txt	2009-06-09 23:05:27.000000000 -0400
@@ -35,30 +35,30 @@ Example:
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
-		reg = <82a8 4>;
-		ranges = <0 8100 1a4>;
+		reg = <0x82a8 4>;
+		ranges = <0 0x8100 0x1a4>;
 		interrupt-parent = <&ipic>;
-		interrupts = <47 8>;
+		interrupts = <71 8>;
 		cell-index = <0>;
 		dma-channel@0 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <0>;
-			reg = <0 80>;
+			reg = <0 0x80>;
 		};
 		dma-channel@80 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <1>;
-			reg = <80 80>;
+			reg = <0x80 0x80>;
 		};
 		dma-channel@100 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <2>;
-			reg = <100 80>;
+			reg = <0x100 0x80>;
 		};
 		dma-channel@180 {
 			compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
 			cell-index = <3>;
-			reg = <180 80>;
+			reg = <0x180 0x80>;
 		};
 	};
 
@@ -93,36 +93,36 @@ Example:
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
-		reg = <21300 4>;
-		ranges = <0 21100 200>;
+		reg = <0x21300 4>;
+		ranges = <0 0x21100 0x200>;
 		cell-index = <0>;
 		dma-channel@0 {
 			compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
-			reg = <0 80>;
+			reg = <0 0x80>;
 			cell-index = <0>;
 			interrupt-parent = <&mpic>;
-			interrupts = <14 2>;
+			interrupts = <20 2>;
 		};
 		dma-channel@80 {
 			compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
-			reg = <80 80>;
+			reg = <0x80 0x80>;
 			cell-index = <1>;
 			interrupt-parent = <&mpic>;
-			interrupts = <15 2>;
+			interrupts = <21 2>;
 		};
 		dma-channel@100 {
 			compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
-			reg = <100 80>;
+			reg = <0x100 0x80>;
 			cell-index = <2>;
 			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
+			interrupts = <22 2>;
 		};
 		dma-channel@180 {
 			compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
-			reg = <180 80>;
+			reg = <0x180 0x80>;
 			cell-index = <3>;
 			interrupt-parent = <&mpic>;
-			interrupts = <17 2>;
+			interrupts = <23 2>;
 		};
 	};
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/esdhc.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/esdhc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/esdhc.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,24 @@
+* Freescale Enhanced Secure Digital Host Controller (eSDHC)
+
+The Enhanced Secure Digital Host Controller provides an interface
+for MMC, SD, and SDIO types of memory cards.
+
+Required properties:
+  - compatible : should be
+    "fsl,<chip>-esdhc", "fsl,mpc8379-esdhc" for MPC83xx processors.
+    "fsl,<chip>-esdhc", "fsl,mpc8536-esdhc" for MPC85xx processors.
+  - reg : should contain eSDHC registers location and length.
+  - interrupts : should contain eSDHC interrupt.
+  - interrupt-parent : interrupt source phandle.
+  - clock-frequency : specifies eSDHC base clock frequency.
+
+Example:
+
+sdhci@2e000 {
+	compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+	reg = <0x2e000 0x1000>;
+	interrupts = <42 0x8>;
+	interrupt-parent = <&ipic>;
+	/* Filled in by U-Boot */
+	clock-frequency = <0>;
+};
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/i2c.txt	2009-06-09 23:05:27.000000000 -0400
@@ -7,8 +7,10 @@ Required properties :
 
 Recommended properties :
 
- - compatible : Should be "fsl-i2c" for parts compatible with
-   Freescale I2C specifications.
+ - compatible : compatibility list with 2 entries, the first should
+   be "fsl,CHIP-i2c" where CHIP is the name of a compatible processor,
+   e.g. mpc8313, mpc8543, mpc8544, mpc5200 or mpc5200b. The second one
+   should be "fsl-i2c".
  - interrupts : <a b> where a is the interrupt number and b is a
    field that represents an encoding of the sense and level
    information for the interrupt.  This should be encoded based on
@@ -16,17 +18,31 @@ Recommended properties :
    controller you have.
  - interrupt-parent : the phandle for the interrupt controller that
    services interrupts for this device.
- - dfsrr : boolean; if defined, indicates that this I2C device has
-   a digital filter sampling rate register
- - fsl5200-clocking : boolean; if defined, indicated that this device
-   uses the FSL 5200 clocking mechanism.
+ - fsl,preserve-clocking : boolean; if defined, the clock settings
+   from the bootloader are preserved (not touched).
+ - clock-frequency : desired I2C bus clock frequency in Hz.
 
-Example :
-	i2c@3000 {
-		interrupt-parent = <40000>;
-		interrupts = <1b 3>;
-		reg = <3000 18>;
-		device_type = "i2c";
-		compatible  = "fsl-i2c";
-		dfsrr;
+Examples :
+
+	i2c@3d00 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+		cell-index = <0>;
+		reg = <0x3d00 0x40>;
+		interrupts = <2 15 0>;
+		interrupt-parent = <&mpc5200_pic>;
+		fsl,preserve-clocking;
+	};
+
+	i2c@3100 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cell-index = <1>;
+		compatible = "fsl,mpc8544-i2c", "fsl-i2c";
+		reg = <0x3100 0x100>;
+		interrupts = <43 2>;
+		interrupt-parent = <&mpic>;
+		clock-frequency = <400000>;
 	};
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/ssi.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/ssi.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/ssi.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/ssi.txt	2009-06-09 23:05:27.000000000 -0400
@@ -4,44 +4,56 @@ The SSI is a serial device that communic
 be programmed in AC97, I2S, left-justified, or right-justified modes.
 
 Required properties:
-- compatible	  : compatible list, containing "fsl,ssi"
-- cell-index	  : the SSI, <0> = SSI1, <1> = SSI2, and so on
-- reg		  : offset and length of the register set for the device
-- interrupts	  : <a b> where a is the interrupt number and b is a
-                     field that represents an encoding of the sense and
-		    level information for the interrupt.  This should be
-		    encoded based on the information in section 2)
-		    depending on the type of interrupt controller you
-		    have.
-- interrupt-parent : the phandle for the interrupt controller that
-                     services interrupts for this device.
-- fsl,mode	  : the operating mode for the SSI interface
-		    "i2s-slave" - I2S mode, SSI is clock slave
-		    "i2s-master" - I2S mode, SSI is clock master
-		    "lj-slave" - left-justified mode, SSI is clock slave
-		    "lj-master" - l.j. mode, SSI is clock master
-		    "rj-slave" - right-justified mode, SSI is clock slave
-		    "rj-master" - r.j., SSI is clock master
-		    "ac97-slave" - AC97 mode, SSI is clock slave
-		    "ac97-master" - AC97 mode, SSI is clock master
-- fsl,playback-dma: phandle to a node for the DMA channel to use for
+- compatible:       Compatible list, contains "fsl,ssi".
+- cell-index:       The SSI, <0> = SSI1, <1> = SSI2, and so on.
+- reg:              Offset and length of the register set for the device.
+- interrupts:       <a b> where a is the interrupt number and b is a
+                    field that represents an encoding of the sense and
+                    level information for the interrupt.  This should be
+                    encoded based on the information in section 2)
+                    depending on the type of interrupt controller you
+                    have.
+- interrupt-parent: The phandle for the interrupt controller that
+                    services interrupts for this device.
+- fsl,mode:         The operating mode for the SSI interface.
+                    "i2s-slave" - I2S mode, SSI is clock slave
+                    "i2s-master" - I2S mode, SSI is clock master
+                    "lj-slave" - left-justified mode, SSI is clock slave
+                    "lj-master" - l.j. mode, SSI is clock master
+                    "rj-slave" - right-justified mode, SSI is clock slave
+                    "rj-master" - r.j., SSI is clock master
+                    "ac97-slave" - AC97 mode, SSI is clock slave
+                    "ac97-master" - AC97 mode, SSI is clock master
+- fsl,playback-dma: Phandle to a node for the DMA channel to use for
                     playback of audio.  This is typically dictated by SOC
                     design.  See the notes below.
-- fsl,capture-dma:  phandle to a node for the DMA channel to use for
+- fsl,capture-dma:  Phandle to a node for the DMA channel to use for
                     capture (recording) of audio.  This is typically dictated
                     by SOC design.  See the notes below.
+- fsl,fifo-depth:   The number of elements in the transmit and receive FIFOs.
+                    This number is the maximum allowed value for SFCSR[TFWM0].
+- fsl,ssi-asynchronous:
+                    If specified, the SSI is to be programmed in asynchronous
+                    mode.  In this mode, pins SRCK, STCK, SRFS, and STFS must
+                    all be connected to valid signals.  In synchronous mode,
+                    SRCK and SRFS are ignored.  Asynchronous mode allows
+                    playback and capture to use different sample sizes and
+                    sample rates.  Some drivers may require that SRCK and STCK
+                    be connected together, and SRFS and STFS be connected
+                    together.  This would still allow different sample sizes,
+                    but not different sample rates.
 
 Optional properties:
-- codec-handle	  : phandle to a 'codec' node that defines an audio
-		    codec connected to this SSI.  This node is typically
-		    a child of an I2C or other control node.
+- codec-handle:     Phandle to a 'codec' node that defines an audio
+                    codec connected to this SSI.  This node is typically
+                    a child of an I2C or other control node.
 
 Child 'codec' node required properties:
-- compatible	  : compatible list, contains the name of the codec
+- compatible:       Compatible list, contains the name of the codec
 
 Child 'codec' node optional properties:
-- clock-frequency  : The frequency of the input clock, which typically
-                     comes from an on-board dedicated oscillator.
+- clock-frequency:  The frequency of the input clock, which typically comes
+                    from an on-board dedicated oscillator.
 
 Notes on fsl,playback-dma and fsl,capture-dma:
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/tsec.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/tsec.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/tsec.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/tsec.txt	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,12 @@ Properties:
     hardware.
   - fsl,magic-packet : If present, indicates that the hardware supports
     waking up via magic packet.
+  - bd-stash : If present, indicates that the hardware supports stashing
+    buffer descriptors in the L2.
+  - rx-stash-len : Denotes the number of bytes of a received buffer to stash
+    in the L2.
+  - rx-stash-idx : Denotes the index of the first byte from the received
+    buffer to stash in the L2.
 
 Example:
 	ethernet@24000 {
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt	2009-06-09 23:05:27.000000000 -0400
@@ -5,9 +5,21 @@ Required properties:
 - reg : should specify localbus chip select and size used for the chip.
 - fsl,upm-addr-offset : UPM pattern offset for the address latch.
 - fsl,upm-cmd-offset : UPM pattern offset for the command latch.
-- gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
 
-Example:
+Optional properties:
+- fsl,upm-wait-flags : add chip-dependent short delays after running the
+	UPM pattern (0x1), after writing a data byte (0x2) or after
+	writing out a buffer (0x4).
+- fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support.
+	The corresponding address lines are used to select the chip.
+- gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins
+	(R/B#). For multi-chip devices, "n" GPIO definitions are required
+	according to the number of chips.
+- chip-delay : chip dependent delay for transfering data from array to
+	read registers (tR). Required if property "gpios" is not used
+	(R/B# pins not connected).
+
+Examples:
 
 upm@1,0 {
 	compatible = "fsl,upm-nand";
@@ -26,3 +38,26 @@ upm@1,0 {
 		};
 	};
 };
+
+upm@3,0 {
+	#address-cells = <0>;
+	#size-cells = <0>;
+	compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
+	reg = <3 0x0 0x800>;
+	fsl,upm-addr-offset = <0x10>;
+	fsl,upm-cmd-offset = <0x08>;
+	/* Multi-chip NAND device */
+	fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+	fsl,upm-wait-flags = <0x5>;
+	chip-delay = <25>; // in micro-seconds
+
+	nand@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			    label = "fs";
+			    reg = <0x00000000 0x10000000>;
+		};
+	};
+};
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/gpio/led.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/gpio/led.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/gpio/led.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/gpio/led.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,15 +1,43 @@
-LED connected to GPIO
+LEDs connected to GPIO lines
 
 Required properties:
-- compatible : should be "gpio-led".
-- label : (optional) the label for this LED. If omitted, the label is
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device.  Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios :  Should specify the LED's GPIO, see "Specifying GPIO information
+  for devices" in Documentation/powerpc/booting-without-of.txt.  Active
+  low LEDs should be indicated using flags in the GPIO specifier.
+- label :  (optional) The label for this LED.  If omitted, the label is
   taken from the node name (excluding the unit address).
-- gpios : should specify LED GPIO.
+- linux,default-trigger :  (optional) This parameter, if present, is a
+  string defining the trigger assigned to the LED.  Current triggers are:
+    "backlight" - LED will act as a back-light, controlled by the framebuffer
+		  system
+    "default-on" - LED will turn on
+    "heartbeat" - LED "double" flashes at a load average based rate
+    "ide-disk" - LED indicates disk activity
+    "timer" - LED flashes at a fixed, configurable rate
 
-Example:
+Examples:
 
-led@0 {
-	compatible = "gpio-led";
-	label = "hdd";
-	gpios = <&mcu_pio 0 1>;
+leds {
+	compatible = "gpio-leds";
+	hdd {
+		label = "IDE Activity";
+		gpios = <&mcu_pio 0 1>; /* Active low */
+		linux,default-trigger = "ide-disk";
+	};
 };
+
+run-control {
+	compatible = "gpio-leds";
+	red {
+		gpios = <&mpc8572 6 0>;
+	};
+	green {
+		gpios = <&mpc8572 7 0>;
+	};
+}
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+MMC/SD/SDIO slot directly connected to a SPI bus
+
+Required properties:
+- compatible : should be "mmc-spi-slot".
+- reg : should specify SPI address (chip-select number).
+- spi-max-frequency : maximum frequency for this device (Hz).
+- voltage-ranges : two cells are required, first cell specifies minimum
+  slot voltage (mV), second cell specifies maximum slot voltage (mV).
+  Several ranges could be specified.
+- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO,
+  Write-Protect GPIO.
+
+Example:
+
+	mmc-slot@0 {
+		compatible = "fsl,mpc8323rdb-mmc-slot",
+			     "mmc-spi-slot";
+		reg = <0>;
+		gpios = <&qe_pio_d 14 1
+			 &qe_pio_d 15 0>;
+		voltage-ranges = <3300 3300>;
+		spi-max-frequency = <50000000>;
+	};
diff -druNp linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/mtd-physmap.txt linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/mtd-physmap.txt
--- linux-libre-2.6.29-gnu1/Documentation/powerpc/dts-bindings/mtd-physmap.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/powerpc/dts-bindings/mtd-physmap.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,80 @@
+CFI or JEDEC memory-mapped NOR flash
+
+Flash chips (Memory Technology Devices) are often used for solid state
+file systems on embedded devices.
+
+ - compatible : should contain the specific model of flash chip(s)
+   used, if known, followed by either "cfi-flash" or "jedec-flash"
+ - reg : Address range(s) of the flash chip(s)
+   It's possible to (optionally) define multiple "reg" tuples so that
+   non-identical NOR chips can be described in one flash node.
+ - bank-width : Width (in bytes) of the flash bank.  Equal to the
+   device width times the number of interleaved chips.
+ - device-width : (optional) Width of a single flash chip.  If
+   omitted, assumed to be equal to 'bank-width'.
+ - #address-cells, #size-cells : Must be present if the flash has
+   sub-nodes representing partitions (see below).  In this case
+   both #address-cells and #size-cells must be equal to 1.
+
+For JEDEC compatible devices, the following additional properties
+are defined:
+
+ - vendor-id : Contains the flash chip's vendor id (1 byte).
+ - device-id : Contains the flash chip's device id (1 byte).
+
+In addition to the information on the flash bank itself, the
+device tree may optionally contain additional information
+describing partitions of the flash address space.  This can be
+used on platforms which have strong conventions about which
+portions of the flash are used for what purposes, but which don't
+use an on-flash partition table such as RedBoot.
+
+Each partition is represented as a sub-node of the flash device.
+Each node's name represents the name of the corresponding
+partition of the flash device.
+
+Flash partitions
+ - reg : The partition's offset and size within the flash bank.
+ - label : (optional) The label / name for this flash partition.
+   If omitted, the label is taken from the node name (excluding
+   the unit address).
+ - read-only : (optional) This parameter, if present, is a hint to
+   Linux that this flash partition should only be mounted
+   read-only.  This is usually used for flash partitions
+   containing early-boot firmware images or data which should not
+   be clobbered.
+
+Example:
+
+	flash@ff000000 {
+		compatible = "amd,am29lv128ml", "cfi-flash";
+		reg = <ff000000 01000000>;
+		bank-width = <4>;
+		device-width = <1>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		fs@0 {
+			label = "fs";
+			reg = <0 f80000>;
+		};
+		firmware@f80000 {
+			label ="firmware";
+			reg = <f80000 80000>;
+			read-only;
+		};
+	};
+
+Here an example with multiple "reg" tuples:
+
+	flash@f0000000,0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "intel,PC48F4400P0VB", "cfi-flash";
+		reg = <0 0x00000000 0x02000000
+		       0 0x02000000 0x02000000>;
+		bank-width = <2>;
+		partition@0 {
+			label = "test-part1";
+			reg = <0 0x04000000>;
+		};
+	};
diff -druNp linux-libre-2.6.29-gnu1/Documentation/RCU/listRCU.txt linux-libre-2.6.30-gnu1/Documentation/RCU/listRCU.txt
--- linux-libre-2.6.29-gnu1/Documentation/RCU/listRCU.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/RCU/listRCU.txt	2009-06-09 23:05:27.000000000 -0400
@@ -118,7 +118,7 @@ Following are the RCU equivalents for th
 		list_for_each_entry(e, list, list) {
 			if (!audit_compare_rule(rule, &e->rule)) {
 				list_del_rcu(&e->list);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
@@ -206,7 +206,7 @@ RCU ("read-copy update") its name.  The
 				ne->rule.action = newaction;
 				ne->rule.file_count = newfield_count;
 				list_replace_rcu(e, ne);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
@@ -283,7 +283,7 @@ flag under the spinlock as follows:
 				list_del_rcu(&e->list);
 				e->deleted = 1;
 				spin_unlock(&e->lock);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
diff -druNp linux-libre-2.6.29-gnu1/Documentation/RCU/rculist_nulls.txt linux-libre-2.6.30-gnu1/Documentation/RCU/rculist_nulls.txt
--- linux-libre-2.6.29-gnu1/Documentation/RCU/rculist_nulls.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/RCU/rculist_nulls.txt	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,7 @@ if (obj) {
   /*
    * Because a writer could delete object, and a writer could
    * reuse these object before the RCU grace period, we
-   * must check key after geting the reference on object
+   * must check key after getting the reference on object
    */
   if (obj->key != key) { // not the object we expected
      put_ref(obj);
@@ -117,7 +117,7 @@ a race (some writer did a delete and/or
 to another chain) checking the final 'nulls' value if
 the lookup met the end of chain. If final 'nulls' value
 is not the slot number, then we must restart the lookup at
-the begining. If the object was moved to same chain,
+the beginning. If the object was moved to the same chain,
 then the reader doesnt care : It might eventually
 scan the list again without harm.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/RCU/rcu.txt linux-libre-2.6.30-gnu1/Documentation/RCU/rcu.txt
--- linux-libre-2.6.29-gnu1/Documentation/RCU/rcu.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/RCU/rcu.txt	2009-06-09 23:05:27.000000000 -0400
@@ -81,7 +81,7 @@ o	I hear that RCU needs work in order to
 	This work is largely completed.  Realtime-friendly RCU can be
 	enabled via the CONFIG_PREEMPT_RCU kernel configuration parameter.
 	However, work is in progress for enabling priority boosting of
-	preempted RCU read-side critical sections.This is needed if you
+	preempted RCU read-side critical sections.  This is needed if you
 	have CPU-bound realtime threads.
 
 o	Where can I find more information on RCU?
diff -druNp linux-libre-2.6.29-gnu1/Documentation/scheduler/00-INDEX linux-libre-2.6.30-gnu1/Documentation/scheduler/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/scheduler/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/scheduler/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -2,8 +2,6 @@
 	- this file.
 sched-arch.txt
 	- CPU Scheduler implementation hints for architecture specific code.
-sched-coding.txt
-	- reference for various scheduler-related methods in the O(1) scheduler.
 sched-design-CFS.txt
 	- goals, design and implementation of the Complete Fair Scheduler.
 sched-domains.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/scheduler/sched-coding.txt linux-libre-2.6.30-gnu1/Documentation/scheduler/sched-coding.txt
--- linux-libre-2.6.29-gnu1/Documentation/scheduler/sched-coding.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/scheduler/sched-coding.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,126 +0,0 @@
-     Reference for various scheduler-related methods in the O(1) scheduler
-		Robert Love <rml@tech9.net>, MontaVista Software
-
-
-Note most of these methods are local to kernel/sched.c - this is by design.
-The scheduler is meant to be self-contained and abstracted away.  This document
-is primarily for understanding the scheduler, not interfacing to it.  Some of
-the discussed interfaces, however, are general process/scheduling methods.
-They are typically defined in include/linux/sched.h.
-
-
-Main Scheduling Methods
------------------------
-
-void load_balance(runqueue_t *this_rq, int idle)
-	Attempts to pull tasks from one cpu to another to balance cpu usage,
-	if needed.  This method is called explicitly if the runqueues are
-	imbalanced or periodically by the timer tick.  Prior to calling,
-	the current runqueue must be locked and interrupts disabled.
-
-void schedule()
-	The main scheduling function.  Upon return, the highest priority
-	process will be active.
-
-
-Locking
--------
-
-Each runqueue has its own lock, rq->lock.  When multiple runqueues need
-to be locked, lock acquires must be ordered by ascending &runqueue value.
-
-A specific runqueue is locked via
-
-	task_rq_lock(task_t pid, unsigned long *flags)
-
-which disables preemption, disables interrupts, and locks the runqueue pid is
-running on.  Likewise,
-
-	task_rq_unlock(task_t pid, unsigned long *flags)
-
-unlocks the runqueue pid is running on, restores interrupts to their previous
-state, and reenables preemption.
-
-The routines
-
-	double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
-
-and
-
-	double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
-
-safely lock and unlock, respectively, the two specified runqueues.  They do
-not, however, disable and restore interrupts.  Users are required to do so
-manually before and after calls.
-
-
-Values
-------
-
-MAX_PRIO
-	The maximum priority of the system, stored in the task as task->prio.
-	Lower priorities are higher.  Normal (non-RT) priorities range from
-	MAX_RT_PRIO to (MAX_PRIO - 1).
-MAX_RT_PRIO
-	The maximum real-time priority of the system.  Valid RT priorities
-	range from 0 to (MAX_RT_PRIO - 1).
-MAX_USER_RT_PRIO
-	The maximum real-time priority that is exported to user-space.  Should
-	always be equal to or less than MAX_RT_PRIO.  Setting it less allows
-	kernel threads to have higher priorities than any user-space task.
-MIN_TIMESLICE
-MAX_TIMESLICE
-	Respectively, the minimum and maximum timeslices (quanta) of a process.
-
-Data
-----
-
-struct runqueue
-	The main per-CPU runqueue data structure.
-struct task_struct
-	The main per-process data structure.
-
-
-General Methods
----------------
-
-cpu_rq(cpu)
-	Returns the runqueue of the specified cpu.
-this_rq()
-	Returns the runqueue of the current cpu.
-task_rq(pid)
-	Returns the runqueue which holds the specified pid.
-cpu_curr(cpu)
-	Returns the task currently running on the given cpu.
-rt_task(pid)
-	Returns true if pid is real-time, false if not.
-
-
-Process Control Methods
------------------------
-
-void set_user_nice(task_t *p, long nice)
-	Sets the "nice" value of task p to the given value.
-int setscheduler(pid_t pid, int policy, struct sched_param *param)
-	Sets the scheduling policy and parameters for the given pid.
-int set_cpus_allowed(task_t *p, unsigned long new_mask)
-	Sets a given task's CPU affinity and migrates it to a proper cpu.
-	Callers must have a valid reference to the task and assure the
-	task not exit prematurely.  No locks can be held during the call.
-set_task_state(tsk, state_value)
-	Sets the given task's state to the given value.
-set_current_state(state_value)
-	Sets the current task's state to the given value.
-void set_tsk_need_resched(struct task_struct *tsk)
-	Sets need_resched in the given task.
-void clear_tsk_need_resched(struct task_struct *tsk)
-	Clears need_resched in the given task.
-void set_need_resched()
-	Sets need_resched in the current task.
-void clear_need_resched()
-	Clears need_resched in the current task.
-int need_resched()
-	Returns true if need_resched is set in the current task, false
-	otherwise.
-yield()
-	Place the current process at the end of the runqueue and call schedule.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/scheduler/sched-rt-group.txt linux-libre-2.6.30-gnu1/Documentation/scheduler/sched-rt-group.txt
--- linux-libre-2.6.29-gnu1/Documentation/scheduler/sched-rt-group.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/scheduler/sched-rt-group.txt	2009-06-09 23:05:27.000000000 -0400
@@ -126,7 +126,7 @@ This uses the /cgroup virtual file syste
 to control the CPU time reserved for each control group instead.
 
 For more information on working with control groups, you should read
-Documentation/cgroups.txt as well.
+Documentation/cgroups/cgroups.txt as well.
 
 Group settings are checked against the following limits in order to keep the configuration
 schedulable:
diff -druNp linux-libre-2.6.29-gnu1/Documentation/scsi/aacraid.txt linux-libre-2.6.30-gnu1/Documentation/scsi/aacraid.txt
--- linux-libre-2.6.29-gnu1/Documentation/scsi/aacraid.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/scsi/aacraid.txt	2009-06-09 23:05:27.000000000 -0400
@@ -60,17 +60,9 @@ Supported Cards/Chipsets
 	9005:0285:9005:02d5	Adaptec	ASR-2405 (Voodoo40 Lite)
 	9005:0285:9005:02d6	Adaptec	ASR-2445 (Voodoo44 Lite)
 	9005:0285:9005:02d7	Adaptec	ASR-2805 (Voodoo80 Lite)
-	9005:0285:9005:02d8	Adaptec	5405G (Voodoo40 PM)
-	9005:0285:9005:02d9	Adaptec	5445G (Voodoo44 PM)
-	9005:0285:9005:02da	Adaptec	5805G (Voodoo80 PM)
-	9005:0285:9005:02db	Adaptec	5085G (Voodoo08 PM)
-	9005:0285:9005:02dc	Adaptec	51245G (Voodoo124 PM)
-	9005:0285:9005:02dd	Adaptec	51645G (Voodoo164 PM)
-	9005:0285:9005:02de	Adaptec	52445G (Voodoo244 PM)
-	9005:0285:9005:02df	Adaptec	ASR-2045G (Voodoo04 Lite PM)
-	9005:0285:9005:02e0	Adaptec	ASR-2405G (Voodoo40 Lite PM)
-	9005:0285:9005:02e1	Adaptec	ASR-2445G (Voodoo44 Lite PM)
-	9005:0285:9005:02e2	Adaptec	ASR-2805G (Voodoo80 Lite PM)
+	9005:0285:9005:02d8	Adaptec	5405Z (Voodoo40 BLBU)
+	9005:0285:9005:02d9	Adaptec	5445Z (Voodoo44 BLBU)
+	9005:0285:9005:02da	Adaptec	5805Z (Voodoo80 BLBU)
 	1011:0046:9005:0364	Adaptec	5400S (Mustang)
 	1011:0046:9005:0365	Adaptec	5400S (Mustang)
 	9005:0287:9005:0800	Adaptec	Themisto (Jupiter)
@@ -140,6 +132,7 @@ Deanna Bonds
 					 where fibs that go to the hardware are consistently called hw_fibs and
 					 not just fibs like the name of the driver tracking structure)
 Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
+Achim Leubner <Achim_Leubner@adaptec.com>
 
 Original Driver
 -------------------------
diff -druNp linux-libre-2.6.29-gnu1/Documentation/scsi/osd.txt linux-libre-2.6.30-gnu1/Documentation/scsi/osd.txt
--- linux-libre-2.6.29-gnu1/Documentation/scsi/osd.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/scsi/osd.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,198 @@
+The OSD Standard
+================
+OSD (Object-Based Storage Device) is a T10 SCSI command set that is designed
+to provide efficient operation of input/output logical units that manage the
+allocation, placement, and accessing of variable-size data-storage containers,
+called objects. Objects are intended to contain operating system and application
+constructs. Each object has associated attributes attached to it, which are
+integral part of the object and provide metadata about the object. The standard
+defines some common obligatory attributes, but user attributes can be added as
+needed.
+
+See: http://www.t10.org/ftp/t10/drafts/osd2/ for the latest draft for OSD 2
+or search the web for "OSD SCSI"
+
+OSD in the Linux Kernel
+=======================
+osd-initiator:
+  The main component of OSD in Kernel is the osd-initiator library. Its main
+user is intended to be the pNFS-over-objects layout driver, which uses objects
+as its back-end data storage. Other clients are the other osd parts listed below.
+
+osd-uld:
+  This is a SCSI ULD that registers for OSD type devices and provides a testing
+platform, both for the in-kernel initiator as well as connected targets. It
+currently has no useful user-mode API, though it could have if need be.
+
+exofs:
+  Is an OSD based Linux file system. It uses the osd-initiator and osd-uld,
+to export a usable file system for users.
+See Documentation/filesystems/exofs.txt for more details
+
+osd target:
+  There are no current plans for an OSD target implementation in kernel. For all
+needs, a user-mode target that is based on the scsi tgt target framework is
+available from Ohio Supercomputer Center (OSC) at:
+http://www.open-osd.org/bin/view/Main/OscOsdProject
+There are several other target implementations. See http://open-osd.org for more
+links.
+
+Files and Folders
+=================
+This is the complete list of files included in this work:
+include/scsi/
+	osd_initiator.h   Main API for the initiator library
+	osd_types.h	  Common OSD types
+	osd_sec.h	  Security Manager API
+	osd_protocol.h	  Wire definitions of the OSD standard protocol
+	osd_attributes.h  Wire definitions of OSD attributes
+
+drivers/scsi/osd/
+	osd_initiator.c   OSD-Initiator library implementation
+	osd_uld.c	  The OSD scsi ULD
+	osd_ktest.{h,c}	  In-kernel test suite (called by osd_uld)
+	osd_debug.h	  Some printk macros
+	Makefile	  For both in-tree and out-of-tree compilation
+	Kconfig		  Enables inclusion of the different pieces
+	osd_test.c	  User-mode application to call the kernel tests
+
+The OSD-Initiator Library
+=========================
+osd_initiator is a low level implementation of an osd initiator encoder.
+But even though, it should be intuitive and easy to use. Perhaps over time an
+higher lever will form that automates some of the more common recipes.
+
+init/fini:
+- osd_dev_init() associates a scsi_device with an osd_dev structure
+  and initializes some global pools. This should be done once per scsi_device
+  (OSD LUN). The osd_dev structure is needed for calling osd_start_request().
+
+- osd_dev_fini() cleans up before a osd_dev/scsi_device destruction.
+
+OSD commands encoding, execution, and decoding of results:
+
+struct osd_request's is used to iteratively encode an OSD command and carry
+its state throughout execution. Each request goes through these stages:
+
+a. osd_start_request() allocates the request.
+
+b. Any of the osd_req_* methods is used to encode a request of the specified
+   type.
+
+c. osd_req_add_{get,set}_attr_* may be called to add get/set attributes to the
+   CDB. "List" or "Page" mode can be used exclusively. The attribute-list API
+   can be called multiple times on the same request. However, only one
+   attribute-page can be read, as mandated by the OSD standard.
+
+d. osd_finalize_request() computes offsets into the data-in and data-out buffers
+   and signs the request using the provided capability key and integrity-
+   check parameters.
+
+e. osd_execute_request() may be called to execute the request via the block
+   layer and wait for its completion.  The request can be executed
+   asynchronously by calling the block layer API directly.
+
+f. After execution, osd_req_decode_sense() can be called to decode the request's
+   sense information.
+
+g. osd_req_decode_get_attr() may be called to retrieve osd_add_get_attr_list()
+   values.
+
+h. osd_end_request() must be called to deallocate the request and any resource
+   associated with it. Note that osd_end_request cleans up the request at any
+   stage and it must always be called after a successful osd_start_request().
+
+osd_request's structure:
+
+The OSD standard defines a complex structure of IO segments pointed to by
+members in the CDB. Up to 3 segments can be deployed in the IN-Buffer and up to
+4 in the OUT-Buffer. The ASCII illustration below depicts a secure-read with
+associated get+set of attributes-lists. Other combinations very on the same
+basic theme. From no-segments-used up to all-segments-used.
+
+|________OSD-CDB__________|
+|                         |
+|read_len (offset=0)     -|---------\
+|                         |         |
+|get_attrs_list_length    |         |
+|get_attrs_list_offset   -|----\    |
+|                         |    |    |
+|retrieved_attrs_alloc_len|    |    |
+|retrieved_attrs_offset  -|----|----|-\
+|                         |    |    | |
+|set_attrs_list_length    |    |    | |
+|set_attrs_list_offset   -|-\  |    | |
+|                         | |  |    | |
+|in_data_integ_offset    -|-|--|----|-|-\
+|out_data_integ_offset   -|-|--|--\ | | |
+\_________________________/ |  |  | | | |
+                            |  |  | | | |
+|_______OUT-BUFFER________| |  |  | | | |
+|      Set attr list      |</  |  | | | |
+|                         |    |  | | | |
+|-------------------------|    |  | | | |
+|   Get attr descriptors  |<---/  | | | |
+|                         |       | | | |
+|-------------------------|       | | | |
+|    Out-data integrity   |<------/ | | |
+|                         |         | | |
+\_________________________/         | | |
+                                    | | |
+|________IN-BUFFER________|         | | |
+|      In-Data read       |<--------/ | |
+|                         |           | |
+|-------------------------|           | |
+|      Get attr list      |<----------/ |
+|                         |             |
+|-------------------------|             |
+|    In-data integrity    |<------------/
+|                         |
+\_________________________/
+
+A block device request can carry bidirectional payload by means of associating
+a bidi_read request with a main write-request. Each in/out request is described
+by a chain of BIOs associated with each request.
+The CDB is of a SCSI VARLEN CDB format, as described by OSD standard.
+The OSD standard also mandates alignment restrictions at start of each segment.
+
+In the code, in struct osd_request, there are two _osd_io_info structures to
+describe the IN/OUT buffers above, two BIOs for the data payload and up to five
+_osd_req_data_segment structures to hold the different segments allocation and
+information.
+
+Important: We have chosen to disregard the assumption that a BIO-chain (and
+the resulting sg-list) describes a linear memory buffer. Meaning only first and
+last scatter chain can be incomplete and all the middle chains are of PAGE_SIZE.
+For us, a scatter-gather-list, as its name implies and as used by the Networking
+layer, is to describe a vector of buffers that will be transferred to/from the
+wire. It works very well with current iSCSI transport. iSCSI is currently the
+only deployed OSD transport. In the future we anticipate SAS and FC attached OSD
+devices as well.
+
+The OSD Testing ULD
+===================
+TODO: More user-mode control on tests.
+
+Authors, Mailing list
+=====================
+Please communicate with us on any deployment of osd, whether using this code
+or not.
+
+Any problems, questions, bug reports, lonely OSD nights, please email:
+   OSD Dev List <osd-dev@open-osd.org>
+
+More up-to-date information can be found on:
+http://open-osd.org
+
+Boaz Harrosh <bharrosh@panasas.com>
+Benny Halevy <bhalevy@panasas.com>
+
+References
+==========
+Weber, R., "SCSI Object-Based Storage Device Commands",
+T10/1355-D ANSI/INCITS 400-2004,
+http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf
+
+Weber, R., "SCSI Object-Based Storage Device Commands -2 (OSD-2)"
+T10/1729-D, Working Draft, rev. 3
+http://www.t10.org/ftp/t10/drafts/osd2/osd2r03.pdf
diff -druNp linux-libre-2.6.29-gnu1/Documentation/slow-work.txt linux-libre-2.6.30-gnu1/Documentation/slow-work.txt
--- linux-libre-2.6.29-gnu1/Documentation/slow-work.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/slow-work.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,174 @@
+		     ====================================
+		     SLOW WORK ITEM EXECUTION THREAD POOL
+		     ====================================
+
+By: David Howells <dhowells@redhat.com>
+
+The slow work item execution thread pool is a pool of threads for performing
+things that take a relatively long time, such as making mkdir calls.
+Typically, when processing something, these items will spend a lot of time
+blocking a thread on I/O, thus making that thread unavailable for doing other
+work.
+
+The standard workqueue model is unsuitable for this class of work item as that
+limits the owner to a single thread or a single thread per CPU.  For some
+tasks, however, more threads - or fewer - are required.
+
+There is just one pool per system.  It contains no threads unless something
+wants to use it - and that something must register its interest first.  When
+the pool is active, the number of threads it contains is dynamic, varying
+between a maximum and minimum setting, depending on the load.
+
+
+====================
+CLASSES OF WORK ITEM
+====================
+
+This pool support two classes of work items:
+
+ (*) Slow work items.
+
+ (*) Very slow work items.
+
+The former are expected to finish much quicker than the latter.
+
+An operation of the very slow class may do a batch combination of several
+lookups, mkdirs, and a create for instance.
+
+An operation of the ordinarily slow class may, for example, write stuff or
+expand files, provided the time taken to do so isn't too long.
+
+Operations of both types may sleep during execution, thus tying up the thread
+loaned to it.
+
+
+THREAD-TO-CLASS ALLOCATION
+--------------------------
+
+Not all the threads in the pool are available to work on very slow work items.
+The number will be between one and one fewer than the number of active threads.
+This is configurable (see the "Pool Configuration" section).
+
+All the threads are available to work on ordinarily slow work items, but a
+percentage of the threads will prefer to work on very slow work items.
+
+The configuration ensures that at least one thread will be available to work on
+very slow work items, and at least one thread will be available that won't work
+on very slow work items at all.
+
+
+=====================
+USING SLOW WORK ITEMS
+=====================
+
+Firstly, a module or subsystem wanting to make use of slow work items must
+register its interest:
+
+	 int ret = slow_work_register_user();
+
+This will return 0 if successful, or a -ve error upon failure.
+
+
+Slow work items may then be set up by:
+
+ (1) Declaring a slow_work struct type variable:
+
+	#include <linux/slow-work.h>
+
+	struct slow_work myitem;
+
+ (2) Declaring the operations to be used for this item:
+
+	struct slow_work_ops myitem_ops = {
+		.get_ref = myitem_get_ref,
+		.put_ref = myitem_put_ref,
+		.execute = myitem_execute,
+	};
+
+     [*] For a description of the ops, see section "Item Operations".
+
+ (3) Initialising the item:
+
+	slow_work_init(&myitem, &myitem_ops);
+
+     or:
+
+	vslow_work_init(&myitem, &myitem_ops);
+
+     depending on its class.
+
+A suitably set up work item can then be enqueued for processing:
+
+	int ret = slow_work_enqueue(&myitem);
+
+This will return a -ve error if the thread pool is unable to gain a reference
+on the item, 0 otherwise.
+
+
+The items are reference counted, so there ought to be no need for a flush
+operation.  When all a module's slow work items have been processed, and the
+module has no further interest in the facility, it should unregister its
+interest:
+
+	slow_work_unregister_user();
+
+
+===============
+ITEM OPERATIONS
+===============
+
+Each work item requires a table of operations of type struct slow_work_ops.
+All members are required:
+
+ (*) Get a reference on an item:
+
+	int (*get_ref)(struct slow_work *work);
+
+     This allows the thread pool to attempt to pin an item by getting a
+     reference on it.  This function should return 0 if the reference was
+     granted, or a -ve error otherwise.  If an error is returned,
+     slow_work_enqueue() will fail.
+
+     The reference is held whilst the item is queued and whilst it is being
+     executed.  The item may then be requeued with the same reference held, or
+     the reference will be released.
+
+ (*) Release a reference on an item:
+
+	void (*put_ref)(struct slow_work *work);
+
+     This allows the thread pool to unpin an item by releasing the reference on
+     it.  The thread pool will not touch the item again once this has been
+     called.
+
+ (*) Execute an item:
+
+	void (*execute)(struct slow_work *work);
+
+     This should perform the work required of the item.  It may sleep, it may
+     perform disk I/O and it may wait for locks.
+
+
+==================
+POOL CONFIGURATION
+==================
+
+The slow-work thread pool has a number of configurables:
+
+ (*) /proc/sys/kernel/slow-work/min-threads
+
+     The minimum number of threads that should be in the pool whilst it is in
+     use.  This may be anywhere between 2 and max-threads.
+
+ (*) /proc/sys/kernel/slow-work/max-threads
+
+     The maximum number of threads that should in the pool.  This may be
+     anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
+
+ (*) /proc/sys/kernel/slow-work/vslow-percentage
+
+     The percentage of active threads in the pool that may be used to execute
+     very slow work items.  This may be between 1 and 99.  The resultant number
+     is bounded to between 1 and one fewer than the number of active threads.
+     This ensures there is always at least one thread that can process very
+     slow work items, and always at least one thread that won't.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/Smack.txt linux-libre-2.6.30-gnu1/Documentation/Smack.txt
--- linux-libre-2.6.29-gnu1/Documentation/Smack.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/Smack.txt	2009-06-09 23:05:27.000000000 -0400
@@ -184,14 +184,16 @@ length. Single character labels using sp
 other than a letter or digit, are reserved for use by the Smack development
 team. Smack labels are unstructured, case sensitive, and the only operation
 ever performed on them is comparison for equality. Smack labels cannot
-contain unprintable characters or the "/" (slash) character.
+contain unprintable characters or the "/" (slash) character. Smack labels
+cannot begin with a '-', which is reserved for special options.
 
 There are some predefined labels:
 
-	_ Pronounced "floor", a single underscore character.
-	^ Pronounced "hat", a single circumflex character.
-	* Pronounced "star", a single asterisk character.
-	? Pronounced "huh", a single question mark character.
+	_ 	Pronounced "floor", a single underscore character.
+	^ 	Pronounced "hat", a single circumflex character.
+	* 	Pronounced "star", a single asterisk character.
+	? 	Pronounced "huh", a single question mark character.
+	@ 	Pronounced "Internet", a single at sign character.
 
 Every task on a Smack system is assigned a label. System tasks, such as
 init(8) and systems daemons, are run with the floor ("_") label. User tasks
@@ -412,6 +414,36 @@ sockets.
 	A privileged program may set this to match the label of another
 	task with which it hopes to communicate.
 
+Smack Netlabel Exceptions
+
+You will often find that your labeled application has to talk to the outside,
+unlabeled world. To do this there's a special file /smack/netlabel where you can
+add some exceptions in the form of :
+@IP1	   LABEL1 or
+@IP2/MASK  LABEL2
+
+It means that your application will have unlabeled access to @IP1 if it has
+write access on LABEL1, and access to the subnet @IP2/MASK if it has write
+access on LABEL2.
+
+Entries in the /smack/netlabel file are matched by longest mask first, like in
+classless IPv4 routing.
+
+A special label '@' and an option '-CIPSO' can be used there :
+@      means Internet, any application with any label has access to it
+-CIPSO means standard CIPSO networking
+
+If you don't know what CIPSO is and don't plan to use it, you can just do :
+echo 127.0.0.1 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0 @      > /smack/netlabel
+
+If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
+Internet access, you can have :
+echo 127.0.0.1      -CIPSO > /smack/netlabel
+echo 192.168.0.0/16 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0      @      > /smack/netlabel
+
+
 Writing Applications for Smack
 
 There are three sorts of applications that will run on a Smack system. How an
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 18:08:57.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/ALSA-Configuration.txt	2013-05-03 16:53:27.000000000 -0400
@@ -346,6 +346,9 @@ Prior to version 0.9.0rc4 options had a
     sbirq	- IRQ # for CMI8330 chip (SB16)
     sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
     sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
+    fmport	- (optional) OPL3 I/O port
+    mpuport	- (optional) MPU401 I/O port
+    mpuirq	- (optional) MPU401 irq #
 
     This module supports multiple cards and autoprobe.
 
@@ -388,34 +391,11 @@ Prior to version 0.9.0rc4 options had a
 
     The power-management is supported.
     
-  Module snd-cs4232
-  -----------------
-
-    Module for sound cards based on CS4232/CS4232A ISA chips.
-
-    isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
-
-    with isapnp=0, the following options are available:
-
-    port	- port # for CS4232 chip (PnP setup - 0x534)
-    cport	- control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00)
-    mpu_port	- port # for MPU-401 UART (PnP setup - 0x300), -1 = disable
-    fm_port	- FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable
-    irq		- IRQ # for CS4232 chip (5,7,9,11,12,15)
-    mpu_irq	- IRQ # for MPU-401 UART (9,11,12,15)
-    dma1	- first DMA # for CS4232 chip (0,1,3)
-    dma2	- second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
-    
-    This module supports multiple cards. This module does not support autoprobe
-    (if ISA PnP is not used) thus main port must be specified!!! Other ports are
-    optional.
-
-    The power-management is supported.
-    
   Module snd-cs4236
   -----------------
 
-    Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/
+    Module for sound cards based on CS4232/CS4232A,
+    	       	     	   	   CS4235/CS4236/CS4236B/CS4237B/
                                    CS4238B/CS4239 ISA chips.
 
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
@@ -437,6 +417,9 @@ Prior to version 0.9.0rc4 options had a
 
     The power-management is supported.
 
+    This module is aliased as snd-cs4232 since it provides the old
+    snd-cs4232 functionality, too.
+
   Module snd-cs4281
   -----------------
 
@@ -606,6 +589,7 @@ Prior to version 0.9.0rc4 options had a
     Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
 
     port	- port # for ES-1688 chip (0x220,0x240,0x260)
+    fm_port	- port # for OPL3 (option; share the same port as default)
     mpu_port	- port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
     irq		- IRQ # for ES-1688 chip (5,7,9,10)
     mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
@@ -757,6 +741,9 @@ Prior to version 0.9.0rc4 options had a
     model	- force the model name
     position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
     probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
+    		  When the bit 8 (0x100) is set, the lower 8 bits are used
+		  as the "fixed" codec slots; i.e. the driver probes the
+		  slots regardless what hardware reports back
     probe_only	- Only probing and no codec initialization (default=off);
 		  Useful to check the initial codec status for debugging
     bdl_pos_adj	- Specifies the DMA IRQ timing delay in samples.
@@ -1185,6 +1172,54 @@ Prior to version 0.9.0rc4 options had a
 
     This module supports multiple devices and PnP.
     
+  Module snd-msnd-classic
+  -----------------------
+
+    Module for Turtle Beach MultiSound Classic, Tahiti or Monterey
+    soundcards.
+
+    io		- Port # for msnd-classic card
+    irq		- IRQ # for msnd-classic card
+    mem		- Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
+		  0xe0000 or 0xe8000)
+    write_ndelay - enable write ndelay (default = 1)
+    calibrate_signal - calibrate signal (default = 0)
+    isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
+    digital	- Digital daughterboard present (default = 0)
+    cfg		- Config port (0x250, 0x260 or 0x270) default = PnP
+    reset	- Reset all devices
+    mpu_io	- MPU401 I/O port
+    mpu_irq	- MPU401 irq#
+    ide_io0	- IDE port #0
+    ide_io1	- IDE port #1
+    ide_irq	- IDE irq#
+    joystick_io	- Joystick I/O port
+
+    The driver requires firmware files "/*(DEBLOBBED)*/" and
+    "/*(DEBLOBBED)*/" in the proper firmware directory.
+
+    See Documentation/sound/oss/MultiSound for important information
+    about this driver.  Note that it has been discontinued, but the 
+    Voyetra Turtle Beach knowledge base entry for it is still available
+    at
+	http://www.turtlebeach.com/site/kb_ftp/790.asp
+
+  Module snd-msnd-pinnacle
+  ------------------------
+
+    Module for Turtle Beach MultiSound Pinnacle/Fiji soundcards.
+
+    io		- Port # for pinnacle/fiji card
+    irq		- IRQ # for pinnalce/fiji card
+    mem		- Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
+		  0xe0000 or 0xe8000)
+    write_ndelay - enable write ndelay (default = 1)
+    calibrate_signal - calibrate signal (default = 0)
+    isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
+
+    The driver requires firmware files "/*(DEBLOBBED)*/" and
+    "/*(DEBLOBBED)*/" in the proper firmware directory.
+
   Module snd-mtpav
   ----------------
 
@@ -1815,7 +1850,7 @@ Prior to version 0.9.0rc4 options had a
   -------------------
 
     Module for sound cards based on the Asus AV100/AV200 chips,
-    i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe).
+    i.e., Xonar D1, DX, D2, D2X, HDAV1.3 (Deluxe), and Essence STX.
 
     This module supports autoprobe and multiple cards.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl linux-libre-2.6.30-gnu1/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<book>
-<?dbhtml filename="index.html">
-
-<!-- ****************************************************** -->
-<!-- Header  -->
-<!-- ****************************************************** -->
-  <bookinfo>
-    <title>The ALSA Driver API</title>
-
-    <legalnotice>
-    <para>
-    This document is free; you can redistribute it and/or modify it
-    under the terms of the 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 document is distributed in the hope that it will be useful,
-    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
-    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
-    PARTICULAR PURPOSE</emphasis>. 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>
-    </legalnotice>
-
-  </bookinfo>
-
-  <chapter><title>Management of Cards and Devices</title>
-     <sect1><title>Card Management</title>
-!Esound/core/init.c
-     </sect1>
-     <sect1><title>Device Components</title>
-!Esound/core/device.c
-     </sect1>
-     <sect1><title>Module requests and Device File Entries</title>
-!Esound/core/sound.c
-     </sect1>
-     <sect1><title>Memory Management Helpers</title>
-!Esound/core/memory.c
-!Esound/core/memalloc.c
-     </sect1>
-  </chapter>
-  <chapter><title>PCM API</title>
-     <sect1><title>PCM Core</title>
-!Esound/core/pcm.c
-!Esound/core/pcm_lib.c
-!Esound/core/pcm_native.c
-     </sect1>
-     <sect1><title>PCM Format Helpers</title>
-!Esound/core/pcm_misc.c
-     </sect1>
-     <sect1><title>PCM Memory Management</title>
-!Esound/core/pcm_memory.c
-     </sect1>
-  </chapter>
-  <chapter><title>Control/Mixer API</title>
-     <sect1><title>General Control Interface</title>
-!Esound/core/control.c
-     </sect1>
-     <sect1><title>AC97 Codec API</title>
-!Esound/pci/ac97/ac97_codec.c
-!Esound/pci/ac97/ac97_pcm.c
-     </sect1>
-  </chapter>
-  <chapter><title>MIDI API</title>
-     <sect1><title>Raw MIDI API</title>
-!Esound/core/rawmidi.c
-     </sect1>
-     <sect1><title>MPU401-UART API</title>
-!Esound/drivers/mpu401/mpu401_uart.c
-     </sect1>
-  </chapter>
-  <chapter><title>Proc Info API</title>
-     <sect1><title>Proc Info Interface</title>
-!Esound/core/info.c
-     </sect1>
-  </chapter>
-  <chapter><title>Miscellaneous Functions</title>
-     <sect1><title>Hardware-Dependent Devices API</title>
-!Esound/core/hwdep.c
-     </sect1>
-     <sect1><title>ISA DMA Helpers</title>
-!Esound/core/isadma.c
-     </sect1>
-     <sect1><title>Other Helper Macros</title>
-!Iinclude/sound/core.h
-     </sect1>
-  </chapter>
-
-</book>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl linux-libre-2.6.30-gnu1/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	1969-12-31 19:00:00.000000000 -0500
@@ -1,6210 +0,0 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<book>
-<?dbhtml filename="index.html">
-
-<!-- ****************************************************** -->
-<!-- Header  -->
-<!-- ****************************************************** -->
-  <bookinfo>
-    <title>Writing an ALSA Driver</title>
-    <author>
-      <firstname>Takashi</firstname>
-      <surname>Iwai</surname>
-      <affiliation>
-        <address>
-          <email>tiwai@suse.de</email>
-        </address>
-      </affiliation>
-     </author>
-
-     <date>Oct 15, 2007</date>
-     <edition>0.3.7</edition>
-
-    <abstract>
-      <para>
-        This document describes how to write an ALSA (Advanced Linux
-        Sound Architecture) driver.
-      </para>
-    </abstract>
-
-    <legalnotice>
-    <para>
-    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
-    </para>
-
-    <para>
-    This document is free; you can redistribute it and/or modify it
-    under the terms of the 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 document is distributed in the hope that it will be useful,
-    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
-    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
-    PARTICULAR PURPOSE</emphasis>. 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>
-    </legalnotice>
-
-  </bookinfo>
-
-<!-- ****************************************************** -->
-<!-- Preface  -->
-<!-- ****************************************************** -->
-  <preface id="preface">
-    <title>Preface</title>
-    <para>
-      This document describes how to write an
-      <ulink url="http://www.alsa-project.org/"><citetitle>
-      ALSA (Advanced Linux Sound Architecture)</citetitle></ulink>
-      driver. The document focuses mainly on PCI soundcards.
-      In the case of other device types, the API might
-      be different, too. However, at least the ALSA kernel API is
-      consistent, and therefore it would be still a bit help for
-      writing them.
-    </para>
-
-    <para>
-    This document targets people who already have enough
-    C language skills and have basic linux kernel programming
-    knowledge.  This document doesn't explain the general
-    topic of linux kernel coding and doesn't cover low-level
-    driver implementation details. It only describes
-    the standard way to write a PCI sound driver on ALSA.
-    </para>
-
-    <para>
-      If you are already familiar with the older ALSA ver.0.5.x API, you
-    can check the drivers such as <filename>sound/pci/es1938.c</filename> or
-    <filename>sound/pci/maestro3.c</filename> which have also almost the same
-    code-base in the ALSA 0.5.x tree, so you can compare the differences.
-    </para>
-
-    <para>
-      This document is still a draft version. Any feedback and
-    corrections, please!!
-    </para>
-  </preface>
-
-
-<!-- ****************************************************** -->
-<!-- File Tree Structure  -->
-<!-- ****************************************************** -->
-  <chapter id="file-tree">
-    <title>File Tree Structure</title>
-
-    <section id="file-tree-general">
-      <title>General</title>
-      <para>
-        The ALSA drivers are provided in two ways.
-      </para>
-
-      <para>
-        One is the trees provided as a tarball or via cvs from the
-      ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
-      tree. To synchronize both, the ALSA driver tree is split into
-      two different trees: alsa-kernel and alsa-driver. The former
-      contains purely the source code for the Linux 2.6 (or later)
-      tree. This tree is designed only for compilation on 2.6 or
-      later environment. The latter, alsa-driver, contains many subtle
-      files for compiling ALSA drivers outside of the Linux kernel tree,
-      wrapper functions for older 2.2 and 2.4 kernels, to adapt the latest kernel API,
-      and additional drivers which are still in development or in
-      tests.  The drivers in alsa-driver tree will be moved to
-      alsa-kernel (and eventually to the 2.6 kernel tree) when they are
-      finished and confirmed to work fine.
-      </para>
-
-      <para>
-        The file tree structure of ALSA driver is depicted below. Both
-        alsa-kernel and alsa-driver have almost the same file
-        structure, except for <quote>core</quote> directory. It's
-        named as <quote>acore</quote> in alsa-driver tree. 
-
-        <example>
-          <title>ALSA File Tree Structure</title>
-          <literallayout>
-        sound
-                /core
-                        /oss
-                        /seq
-                                /oss
-                                /instr
-                /ioctl32
-                /include
-                /drivers
-                        /mpu401
-                        /opl3
-                /i2c
-                        /l3
-                /synth
-                        /emux
-                /pci
-                        /(cards)
-                /isa
-                        /(cards)
-                /arm
-                /ppc
-                /sparc
-                /usb
-                /pcmcia /(cards)
-                /oss
-          </literallayout>
-        </example>
-      </para>
-    </section>
-
-    <section id="file-tree-core-directory">
-      <title>core directory</title>
-      <para>
-        This directory contains the middle layer which is the heart
-      of ALSA drivers. In this directory, the native ALSA modules are
-      stored. The sub-directories contain different modules and are
-      dependent upon the kernel config. 
-      </para>
-
-      <section id="file-tree-core-directory-oss">
-        <title>core/oss</title>
-
-        <para>
-          The codes for PCM and mixer OSS emulation modules are stored
-        in this directory. The rawmidi OSS emulation is included in
-        the ALSA rawmidi code since it's quite small. The sequencer
-        code is stored in <filename>core/seq/oss</filename> directory (see
-        <link linkend="file-tree-core-directory-seq-oss"><citetitle>
-        below</citetitle></link>).
-        </para>
-      </section>
-
-      <section id="file-tree-core-directory-ioctl32">
-        <title>core/ioctl32</title>
-
-        <para>
-          This directory contains the 32bit-ioctl wrappers for 64bit
-        architectures such like x86-64, ppc64 and sparc64. For 32bit
-        and alpha architectures, these are not compiled. 
-        </para>
-      </section>
-
-      <section id="file-tree-core-directory-seq">
-        <title>core/seq</title>
-        <para>
-          This directory and its sub-directories are for the ALSA
-        sequencer. This directory contains the sequencer core and
-        primary sequencer modules such like snd-seq-midi,
-        snd-seq-virmidi, etc. They are compiled only when
-        <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel
-        config. 
-        </para>
-      </section>
-
-      <section id="file-tree-core-directory-seq-oss">
-        <title>core/seq/oss</title>
-        <para>
-          This contains the OSS sequencer emulation codes.
-        </para>
-      </section>
-
-      <section id="file-tree-core-directory-deq-instr">
-        <title>core/seq/instr</title>
-        <para>
-          This directory contains the modules for the sequencer
-        instrument layer. 
-        </para>
-      </section>
-    </section>
-
-    <section id="file-tree-include-directory">
-      <title>include directory</title>
-      <para>
-        This is the place for the public header files of ALSA drivers,
-      which are to be exported to user-space, or included by
-      several files at different directories. Basically, the private
-      header files should not be placed in this directory, but you may
-      still find files there, due to historical reasons :) 
-      </para>
-    </section>
-
-    <section id="file-tree-drivers-directory">
-      <title>drivers directory</title>
-      <para>
-        This directory contains code shared among different drivers
-      on different architectures.  They are hence supposed not to be
-      architecture-specific.
-      For example, the dummy pcm driver and the serial MIDI
-      driver are found in this directory. In the sub-directories,
-      there is code for components which are independent from
-      bus and cpu architectures. 
-      </para>
-
-      <section id="file-tree-drivers-directory-mpu401">
-        <title>drivers/mpu401</title>
-        <para>
-          The MPU401 and MPU401-UART modules are stored here.
-        </para>
-      </section>
-
-      <section id="file-tree-drivers-directory-opl3">
-        <title>drivers/opl3 and opl4</title>
-        <para>
-          The OPL3 and OPL4 FM-synth stuff is found here.
-        </para>
-      </section>
-    </section>
-
-    <section id="file-tree-i2c-directory">
-      <title>i2c directory</title>
-      <para>
-        This contains the ALSA i2c components.
-      </para>
-
-      <para>
-        Although there is a standard i2c layer on Linux, ALSA has its
-      own i2c code for some cards, because the soundcard needs only a
-      simple operation and the standard i2c API is too complicated for
-      such a purpose. 
-      </para>
-
-      <section id="file-tree-i2c-directory-l3">
-        <title>i2c/l3</title>
-        <para>
-          This is a sub-directory for ARM L3 i2c.
-        </para>
-      </section>
-    </section>
-
-    <section id="file-tree-synth-directory">
-        <title>synth directory</title>
-        <para>
-          This contains the synth middle-level modules.
-        </para>
-
-        <para>
-          So far, there is only Emu8000/Emu10k1 synth driver under
-        the <filename>synth/emux</filename> sub-directory. 
-        </para>
-    </section>
-
-    <section id="file-tree-pci-directory">
-      <title>pci directory</title>
-      <para>
-        This directory and its sub-directories hold the top-level card modules
-      for PCI soundcards and the code specific to the PCI BUS.
-      </para>
-
-      <para>
-        The drivers compiled from a single file are stored directly
-      in the pci directory, while the drivers with several source files are
-      stored on their own sub-directory (e.g. emu10k1, ice1712). 
-      </para>
-    </section>
-
-    <section id="file-tree-isa-directory">
-      <title>isa directory</title>
-      <para>
-        This directory and its sub-directories hold the top-level card modules
-      for ISA soundcards. 
-      </para>
-    </section>
-
-    <section id="file-tree-arm-ppc-sparc-directories">
-      <title>arm, ppc, and sparc directories</title>
-      <para>
-        They are used for top-level card modules which are
-      specific to one of these architectures. 
-      </para>
-    </section>
-
-    <section id="file-tree-usb-directory">
-      <title>usb directory</title>
-      <para>
-        This directory contains the USB-audio driver. In the latest version, the
-      USB MIDI driver is integrated in the usb-audio driver. 
-      </para>
-    </section>
-
-    <section id="file-tree-pcmcia-directory">
-      <title>pcmcia directory</title>
-      <para>
-        The PCMCIA, especially PCCard drivers will go here. CardBus
-      drivers will be in the pci directory, because their API is identical
-      to that of standard PCI cards. 
-      </para>
-    </section>
-
-    <section id="file-tree-oss-directory">
-      <title>oss directory</title>
-      <para>
-        The OSS/Lite source files are stored here in Linux 2.6 (or
-      later) tree. In the ALSA driver tarball, this directory is empty,
-      of course :) 
-      </para>
-    </section>
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Basic Flow for PCI Drivers  -->
-<!-- ****************************************************** -->
-  <chapter id="basic-flow">
-    <title>Basic Flow for PCI Drivers</title>
-
-    <section id="basic-flow-outline">
-      <title>Outline</title>
-      <para>
-        The minimum flow for PCI soundcards is as follows:
-
-        <itemizedlist>
-          <listitem><para>define the PCI ID table (see the section
-          <link linkend="pci-resource-entries"><citetitle>PCI Entries
-          </citetitle></link>).</para></listitem> 
-          <listitem><para>create <function>probe()</function> callback.</para></listitem>
-          <listitem><para>create <function>remove()</function> callback.</para></listitem>
-          <listitem><para>create a <structname>pci_driver</structname> structure
-	  containing the three pointers above.</para></listitem>
-          <listitem><para>create an <function>init()</function> function just calling
-	  the <function>pci_register_driver()</function> to register the pci_driver table
-	  defined above.</para></listitem>
-          <listitem><para>create an <function>exit()</function> function to call
-	  the <function>pci_unregister_driver()</function> function.</para></listitem>
-        </itemizedlist>
-      </para>
-    </section>
-
-    <section id="basic-flow-example">
-      <title>Full Code Example</title>
-      <para>
-        The code example is shown below. Some parts are kept
-      unimplemented at this moment but will be filled in the
-      next sections. The numbers in the comment lines of the
-      <function>snd_mychip_probe()</function> function
-      refer to details explained in the following section. 
-
-        <example>
-          <title>Basic Flow for PCI Drivers - Example</title>
-          <programlisting>
-<![CDATA[
-  #include <linux/init.h>
-  #include <linux/pci.h>
-  #include <linux/slab.h>
-  #include <sound/core.h>
-  #include <sound/initval.h>
-
-  /* module parameters (see "Module Parameters") */
-  /* SNDRV_CARDS: maximum number of cards supported by this module */
-  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-  static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-  /* definition of the chip-specific record */
-  struct mychip {
-          struct snd_card *card;
-          /* the rest of the implementation will be in section
-           * "PCI Resource Management"
-           */
-  };
-
-  /* chip-specific destructor
-   * (see "PCI Resource Management")
-   */
-  static int snd_mychip_free(struct mychip *chip)
-  {
-          .... /* will be implemented later... */
-  }
-
-  /* component-destructor
-   * (see "Management of Cards and Components")
-   */
-  static int snd_mychip_dev_free(struct snd_device *device)
-  {
-          return snd_mychip_free(device->device_data);
-  }
-
-  /* chip-specific constructor
-   * (see "Management of Cards and Components")
-   */
-  static int __devinit snd_mychip_create(struct snd_card *card,
-                                         struct pci_dev *pci,
-                                         struct mychip **rchip)
-  {
-          struct mychip *chip;
-          int err;
-          static struct snd_device_ops ops = {
-                 .dev_free = snd_mychip_dev_free,
-          };
-
-          *rchip = NULL;
-
-          /* check PCI availability here
-           * (see "PCI Resource Management")
-           */
-          ....
-
-          /* allocate a chip-specific data with zero filled */
-          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-          if (chip == NULL)
-                  return -ENOMEM;
-
-          chip->card = card;
-
-          /* rest of initialization here; will be implemented
-           * later, see "PCI Resource Management"
-           */
-          ....
-
-          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-          if (err < 0) {
-                  snd_mychip_free(chip);
-                  return err;
-          }
-
-          snd_card_set_dev(card, &pci->dev);
-
-          *rchip = chip;
-          return 0;
-  }
-
-  /* constructor -- see "Constructor" sub-section */
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
-  {
-          static int dev;
-          struct snd_card *card;
-          struct mychip *chip;
-          int err;
-
-          /* (1) */
-          if (dev >= SNDRV_CARDS)
-                  return -ENODEV;
-          if (!enable[dev]) {
-                  dev++;
-                  return -ENOENT;
-          }
-
-          /* (2) */
-          card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-          if (card == NULL)
-                  return -ENOMEM;
-
-          /* (3) */
-          err = snd_mychip_create(card, pci, &chip);
-          if (err < 0) {
-                  snd_card_free(card);
-                  return err;
-          }
-
-          /* (4) */
-          strcpy(card->driver, "My Chip");
-          strcpy(card->shortname, "My Own Chip 123");
-          sprintf(card->longname, "%s at 0x%lx irq %i",
-                  card->shortname, chip->ioport, chip->irq);
-
-          /* (5) */
-          .... /* implemented later */
-
-          /* (6) */
-          err = snd_card_register(card);
-          if (err < 0) {
-                  snd_card_free(card);
-                  return err;
-          }
-
-          /* (7) */
-          pci_set_drvdata(pci, card);
-          dev++;
-          return 0;
-  }
-
-  /* destructor -- see the "Destructor" sub-section */
-  static void __devexit snd_mychip_remove(struct pci_dev *pci)
-  {
-          snd_card_free(pci_get_drvdata(pci));
-          pci_set_drvdata(pci, NULL);
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
-    </section>
-
-    <section id="basic-flow-constructor">
-      <title>Constructor</title>
-      <para>
-        The real constructor of PCI drivers is the <function>probe</function> callback.
-      The <function>probe</function> callback and other component-constructors which are called
-      from the <function>probe</function> callback should be defined with
-      the <parameter>__devinit</parameter> prefix. You 
-      cannot use the <parameter>__init</parameter> prefix for them,
-      because any PCI device could be a hotplug device. 
-      </para>
-
-      <para>
-        In the <function>probe</function> callback, the following scheme is often used.
-      </para>
-
-      <section id="basic-flow-constructor-device-index">
-        <title>1) Check and increment the device index.</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int dev;
-  ....
-  if (dev >= SNDRV_CARDS)
-          return -ENODEV;
-  if (!enable[dev]) {
-          dev++;
-          return -ENOENT;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-
-        where enable[dev] is the module option.
-        </para>
-
-        <para>
-          Each time the <function>probe</function> callback is called, check the
-        availability of the device. If not available, simply increment
-        the device index and returns. dev will be incremented also
-        later (<link
-        linkend="basic-flow-constructor-set-pci"><citetitle>step
-        7</citetitle></link>). 
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-create-card">
-        <title>2) Create a card instance</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  struct snd_card *card;
-  ....
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          The details will be explained in the section
-          <link linkend="card-management-card-instance"><citetitle>
-          Management of Cards and Components</citetitle></link>.
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-create-main">
-        <title>3) Create a main component</title>
-        <para>
-          In this part, the PCI resources are allocated.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  struct mychip *chip;
-  ....
-  err = snd_mychip_create(card, pci, &chip);
-  if (err < 0) {
-          snd_card_free(card);
-          return err;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-
-          The details will be explained in the section <link
-        linkend="pci-resource"><citetitle>PCI Resource
-        Management</citetitle></link>.
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-main-component">
-        <title>4) Set the driver ID and name strings.</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  strcpy(card->driver, "My Chip");
-  strcpy(card->shortname, "My Own Chip 123");
-  sprintf(card->longname, "%s at 0x%lx irq %i",
-          card->shortname, chip->ioport, chip->irq);
-]]>
-            </programlisting>
-          </informalexample>
-
-          The driver field holds the minimal ID string of the
-        chip. This is used by alsa-lib's configurator, so keep it
-        simple but unique. 
-          Even the same driver can have different driver IDs to
-        distinguish the functionality of each chip type. 
-        </para>
-
-        <para>
-          The shortname field is a string shown as more verbose
-        name. The longname field contains the information
-        shown in <filename>/proc/asound/cards</filename>. 
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-create-other">
-        <title>5) Create other components, such as mixer, MIDI, etc.</title>
-        <para>
-          Here you define the basic components such as
-          <link linkend="pcm-interface"><citetitle>PCM</citetitle></link>,
-          mixer (e.g. <link linkend="api-ac97"><citetitle>AC97</citetitle></link>),
-          MIDI (e.g. <link linkend="midi-interface"><citetitle>MPU-401</citetitle></link>),
-          and other interfaces.
-          Also, if you want a <link linkend="proc-interface"><citetitle>proc
-        file</citetitle></link>, define it here, too.
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-register-card">
-        <title>6) Register the card instance.</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  err = snd_card_register(card);
-  if (err < 0) {
-          snd_card_free(card);
-          return err;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          Will be explained in the section <link
-        linkend="card-management-registration"><citetitle>Management
-        of Cards and Components</citetitle></link>, too. 
-        </para>
-      </section>
-
-      <section id="basic-flow-constructor-set-pci">
-        <title>7) Set the PCI driver data and return zero.</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-        pci_set_drvdata(pci, card);
-        dev++;
-        return 0;
-]]>
-            </programlisting>
-          </informalexample>
-
-          In the above, the card record is stored. This pointer is
-        used in the remove callback and power-management
-        callbacks, too. 
-        </para>
-      </section>
-    </section>
-
-    <section id="basic-flow-destructor">
-      <title>Destructor</title>
-      <para>
-        The destructor, remove callback, simply releases the card
-      instance. Then the ALSA middle layer will release all the
-      attached components automatically. 
-      </para>
-
-      <para>
-        It would be typically like the following:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void __devexit snd_mychip_remove(struct pci_dev *pci)
-  {
-          snd_card_free(pci_get_drvdata(pci));
-          pci_set_drvdata(pci, NULL);
-  }
-]]>
-          </programlisting>
-        </informalexample>
-
-        The above code assumes that the card pointer is set to the PCI
-	driver data.
-      </para>
-    </section>
-
-    <section id="basic-flow-header-files">
-      <title>Header Files</title>
-      <para>
-        For the above example, at least the following include files
-      are necessary. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  #include <linux/init.h>
-  #include <linux/pci.h>
-  #include <linux/slab.h>
-  #include <sound/core.h>
-  #include <sound/initval.h>
-]]>
-          </programlisting>
-        </informalexample>
-
-	where the last one is necessary only when module options are
-      defined in the source file.  If the code is split into several
-      files, the files without module options don't need them.
-      </para>
-
-      <para>
-        In addition to these headers, you'll need
-      <filename>&lt;linux/interrupt.h&gt;</filename> for interrupt
-      handling, and <filename>&lt;asm/io.h&gt;</filename> for I/O
-      access. If you use the <function>mdelay()</function> or
-      <function>udelay()</function> functions, you'll need to include
-      <filename>&lt;linux/delay.h&gt;</filename> too. 
-      </para>
-
-      <para>
-      The ALSA interfaces like the PCM and control APIs are defined in other
-      <filename>&lt;sound/xxx.h&gt;</filename> header files.
-      They have to be included after
-      <filename>&lt;sound/core.h&gt;</filename>.
-      </para>
-
-    </section>
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Management of Cards and Components  -->
-<!-- ****************************************************** -->
-  <chapter id="card-management">
-    <title>Management of Cards and Components</title>
-
-    <section id="card-management-card-instance">
-      <title>Card Instance</title>
-      <para>
-      For each soundcard, a <quote>card</quote> record must be allocated.
-      </para>
-
-      <para>
-      A card record is the headquarters of the soundcard.  It manages
-      the whole list of devices (components) on the soundcard, such as
-      PCM, mixers, MIDI, synthesizer, and so on.  Also, the card
-      record holds the ID and the name strings of the card, manages
-      the root of proc files, and controls the power-management states
-      and hotplug disconnections.  The component list on the card
-      record is used to manage the correct release of resources at
-      destruction. 
-      </para>
-
-      <para>
-        As mentioned above, to create a card instance, call
-      <function>snd_card_new()</function>.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_card *card;
-  card = snd_card_new(index, id, module, extra_size);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The function takes four arguments, the card-index number, the
-        id string, the module pointer (usually
-        <constant>THIS_MODULE</constant>),
-        and the size of extra-data space.  The last argument is used to
-        allocate card-&gt;private_data for the
-        chip-specific data.  Note that these data
-        are allocated by <function>snd_card_new()</function>.
-      </para>
-    </section>
-
-    <section id="card-management-component">
-      <title>Components</title>
-      <para>
-        After the card is created, you can attach the components
-      (devices) to the card instance. In an ALSA driver, a component is
-      represented as a struct <structname>snd_device</structname> object.
-      A component can be a PCM instance, a control interface, a raw
-      MIDI interface, etc.  Each such instance has one component
-      entry.
-      </para>
-
-      <para>
-        A component can be created via
-        <function>snd_device_new()</function> function. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        This takes the card pointer, the device-level
-      (<constant>SNDRV_DEV_XXX</constant>), the data pointer, and the
-      callback pointers (<parameter>&amp;ops</parameter>). The
-      device-level defines the type of components and the order of
-      registration and de-registration.  For most components, the
-      device-level is already defined.  For a user-defined component,
-      you can use <constant>SNDRV_DEV_LOWLEVEL</constant>.
-      </para>
-
-      <para>
-      This function itself doesn't allocate the data space. The data
-      must be allocated manually beforehand, and its pointer is passed
-      as the argument. This pointer is used as the
-      (<parameter>chip</parameter> identifier in the above example)
-      for the instance. 
-      </para>
-
-      <para>
-        Each pre-defined ALSA component such as ac97 and pcm calls
-      <function>snd_device_new()</function> inside its
-      constructor. The destructor for each component is defined in the
-      callback pointers.  Hence, you don't need to take care of
-      calling a destructor for such a component.
-      </para>
-
-      <para>
-        If you wish to create your own component, you need to
-      set the destructor function to the dev_free callback in
-      the <parameter>ops</parameter>, so that it can be released
-      automatically via <function>snd_card_free()</function>.
-      The next example will show an implementation of chip-specific
-      data.
-      </para>
-    </section>
-
-    <section id="card-management-chip-specific">
-      <title>Chip-Specific Data</title>
-      <para>
-      Chip-specific information, e.g. the I/O port address, its
-      resource pointer, or the irq number, is stored in the
-      chip-specific record.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct mychip {
-          ....
-  };
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        In general, there are two ways of allocating the chip record.
-      </para>
-
-      <section id="card-management-chip-specific-snd-card-new">
-        <title>1. Allocating via <function>snd_card_new()</function>.</title>
-        <para>
-          As mentioned above, you can pass the extra-data-length
-	  to the 4th argument of <function>snd_card_new()</function>, i.e.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
-]]>
-            </programlisting>
-          </informalexample>
-
-          struct <structname>mychip</structname> is the type of the chip record.
-        </para>
-
-        <para>
-          In return, the allocated record can be accessed as
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  struct mychip *chip = card->private_data;
-]]>
-            </programlisting>
-          </informalexample>
-
-          With this method, you don't have to allocate twice.
-          The record is released together with the card instance.
-        </para>
-      </section>
-
-      <section id="card-management-chip-specific-allocate-extra">
-        <title>2. Allocating an extra device.</title>
-
-        <para>
-          After allocating a card instance via
-          <function>snd_card_new()</function> (with
-          <constant>NULL</constant> on the 4th arg), call
-          <function>kzalloc()</function>. 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  struct snd_card *card;
-  struct mychip *chip;
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
-  .....
-  chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          The chip record should have the field to hold the card
-          pointer at least, 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  struct mychip {
-          struct snd_card *card;
-          ....
-  };
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          Then, set the card pointer in the returned chip instance.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  chip->card = card;
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          Next, initialize the fields, and register this chip
-          record as a low-level device with a specified
-          <parameter>ops</parameter>, 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static struct snd_device_ops ops = {
-          .dev_free =        snd_mychip_dev_free,
-  };
-  ....
-  snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-]]>
-            </programlisting>
-          </informalexample>
-
-          <function>snd_mychip_dev_free()</function> is the
-        device-destructor function, which will call the real
-        destructor. 
-        </para>
-
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_mychip_dev_free(struct snd_device *device)
-  {
-          return snd_mychip_free(device->device_data);
-  }
-]]>
-            </programlisting>
-          </informalexample>
-
-          where <function>snd_mychip_free()</function> is the real destructor.
-        </para>
-      </section>
-    </section>
-
-    <section id="card-management-registration">
-      <title>Registration and Release</title>
-      <para>
-        After all components are assigned, register the card instance
-      by calling <function>snd_card_register()</function>. Access
-      to the device files is enabled at this point. That is, before
-      <function>snd_card_register()</function> is called, the
-      components are safely inaccessible from external side. If this
-      call fails, exit the probe function after releasing the card via
-      <function>snd_card_free()</function>. 
-      </para>
-
-      <para>
-        For releasing the card instance, you can call simply
-      <function>snd_card_free()</function>. As mentioned earlier, all
-      components are released automatically by this call. 
-      </para>
-
-      <para>
-        As further notes, the destructors (both
-      <function>snd_mychip_dev_free</function> and
-      <function>snd_mychip_free</function>) cannot be defined with
-      the <parameter>__devexit</parameter> prefix, because they may be
-      called from the constructor, too, at the false path. 
-      </para>
-
-      <para>
-      For a device which allows hotplugging, you can use
-      <function>snd_card_free_when_closed</function>.  This one will
-      postpone the destruction until all devices are closed.
-      </para>
-
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- PCI Resource Management  -->
-<!-- ****************************************************** -->
-  <chapter id="pci-resource">
-    <title>PCI Resource Management</title>
-
-    <section id="pci-resource-example">
-      <title>Full Code Example</title>
-      <para>
-        In this section, we'll complete the chip-specific constructor,
-      destructor and PCI entries. Example code is shown first,
-      below. 
-
-        <example>
-          <title>PCI Resource Management Example</title>
-          <programlisting>
-<![CDATA[
-  struct mychip {
-          struct snd_card *card;
-          struct pci_dev *pci;
-
-          unsigned long port;
-          int irq;
-  };
-
-  static int snd_mychip_free(struct mychip *chip)
-  {
-          /* disable hardware here if any */
-          .... /* (not implemented in this document) */
-
-          /* release the irq */
-          if (chip->irq >= 0)
-                  free_irq(chip->irq, chip);
-          /* release the I/O ports & memory */
-          pci_release_regions(chip->pci);
-          /* disable the PCI entry */
-          pci_disable_device(chip->pci);
-          /* release the data */
-          kfree(chip);
-          return 0;
-  }
-
-  /* chip-specific constructor */
-  static int __devinit snd_mychip_create(struct snd_card *card,
-                                         struct pci_dev *pci,
-                                         struct mychip **rchip)
-  {
-          struct mychip *chip;
-          int err;
-          static struct snd_device_ops ops = {
-                 .dev_free = snd_mychip_dev_free,
-          };
-
-          *rchip = NULL;
-
-          /* initialize the PCI entry */
-          err = pci_enable_device(pci);
-          if (err < 0)
-                  return err;
-          /* check PCI availability (28bit DMA) */
-          if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
-              pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
-                  printk(KERN_ERR "error to set 28bit mask DMA\n");
-                  pci_disable_device(pci);
-                  return -ENXIO;
-          }
-
-          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-          if (chip == NULL) {
-                  pci_disable_device(pci);
-                  return -ENOMEM;
-          }
-
-          /* initialize the stuff */
-          chip->card = card;
-          chip->pci = pci;
-          chip->irq = -1;
-
-          /* (1) PCI resource allocation */
-          err = pci_request_regions(pci, "My Chip");
-          if (err < 0) {
-                  kfree(chip);
-                  pci_disable_device(pci);
-                  return err;
-          }
-          chip->port = pci_resource_start(pci, 0);
-          if (request_irq(pci->irq, snd_mychip_interrupt,
-                          IRQF_SHARED, "My Chip", chip)) {
-                  printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
-                  snd_mychip_free(chip);
-                  return -EBUSY;
-          }
-          chip->irq = pci->irq;
-
-          /* (2) initialization of the chip hardware */
-          .... /*   (not implemented in this document) */
-
-          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
-          if (err < 0) {
-                  snd_mychip_free(chip);
-                  return err;
-          }
-
-          snd_card_set_dev(card, &pci->dev);
-
-          *rchip = chip;
-          return 0;
-  }        
-
-  /* PCI IDs */
-  static struct pci_device_id snd_mychip_ids[] = {
-          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
-            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-          ....
-          { 0, }
-  };
-  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
-
-  /* pci_driver definition */
-  static struct pci_driver driver = {
-          .name = "My Own Chip",
-          .id_table = snd_mychip_ids,
-          .probe = snd_mychip_probe,
-          .remove = __devexit_p(snd_mychip_remove),
-  };
-
-  /* module initialization */
-  static int __init alsa_card_mychip_init(void)
-  {
-          return pci_register_driver(&driver);
-  }
-
-  /* module clean up */
-  static void __exit alsa_card_mychip_exit(void)
-  {
-          pci_unregister_driver(&driver);
-  }
-
-  module_init(alsa_card_mychip_init)
-  module_exit(alsa_card_mychip_exit)
-
-  EXPORT_NO_SYMBOLS; /* for old kernels only */
-]]>
-          </programlisting>
-        </example>
-      </para>
-    </section>
-
-    <section id="pci-resource-some-haftas">
-      <title>Some Hafta's</title>
-      <para>
-        The allocation of PCI resources is done in the
-      <function>probe()</function> function, and usually an extra
-      <function>xxx_create()</function> function is written for this
-      purpose.
-      </para>
-
-      <para>
-        In the case of PCI devices, you first have to call
-      the <function>pci_enable_device()</function> function before
-      allocating resources. Also, you need to set the proper PCI DMA
-      mask to limit the accessed I/O range. In some cases, you might
-      need to call <function>pci_set_master()</function> function,
-      too.
-      </para>
-
-      <para>
-        Suppose the 28bit mask, and the code to be added would be like:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  err = pci_enable_device(pci);
-  if (err < 0)
-          return err;
-  if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
-      pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
-          printk(KERN_ERR "error to set 28bit mask DMA\n");
-          pci_disable_device(pci);
-          return -ENXIO;
-  }
-  
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-    </section>
-
-    <section id="pci-resource-resource-allocation">
-      <title>Resource Allocation</title>
-      <para>
-        The allocation of I/O ports and irqs is done via standard kernel
-      functions. Unlike ALSA ver.0.5.x., there are no helpers for
-      that. And these resources must be released in the destructor
-      function (see below). Also, on ALSA 0.9.x, you don't need to
-      allocate (pseudo-)DMA for PCI like in ALSA 0.5.x.
-      </para>
-
-      <para>
-        Now assume that the PCI device has an I/O port with 8 bytes
-        and an interrupt. Then struct <structname>mychip</structname> will have the
-        following fields:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct mychip {
-          struct snd_card *card;
-
-          unsigned long port;
-          int irq;
-  };
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        For an I/O port (and also a memory region), you need to have
-      the resource pointer for the standard resource management. For
-      an irq, you have to keep only the irq number (integer). But you
-      need to initialize this number as -1 before actual allocation,
-      since irq 0 is valid. The port address and its resource pointer
-      can be initialized as null by
-      <function>kzalloc()</function> automatically, so you
-      don't have to take care of resetting them. 
-      </para>
-
-      <para>
-        The allocation of an I/O port is done like this:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  err = pci_request_regions(pci, "My Chip");
-  if (err < 0) { 
-          kfree(chip);
-          pci_disable_device(pci);
-          return err;
-  }
-  chip->port = pci_resource_start(pci, 0);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        <!-- obsolete -->
-        It will reserve the I/O port region of 8 bytes of the given
-      PCI device. The returned value, chip-&gt;res_port, is allocated
-      via <function>kmalloc()</function> by
-      <function>request_region()</function>. The pointer must be
-      released via <function>kfree()</function>, but there is a
-      problem with this. This issue will be explained later.
-      </para>
-
-      <para>
-        The allocation of an interrupt source is done like this:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  if (request_irq(pci->irq, snd_mychip_interrupt,
-                  IRQF_SHARED, "My Chip", chip)) {
-          printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
-          snd_mychip_free(chip);
-          return -EBUSY;
-  }
-  chip->irq = pci->irq;
-]]>
-          </programlisting>
-        </informalexample>
-
-        where <function>snd_mychip_interrupt()</function> is the
-      interrupt handler defined <link
-      linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>.
-      Note that chip-&gt;irq should be defined
-      only when <function>request_irq()</function> succeeded.
-      </para>
-
-      <para>
-      On the PCI bus, interrupts can be shared. Thus,
-      <constant>IRQF_SHARED</constant> is used as the interrupt flag of
-      <function>request_irq()</function>. 
-      </para>
-
-      <para>
-        The last argument of <function>request_irq()</function> is the
-      data pointer passed to the interrupt handler. Usually, the
-      chip-specific record is used for that, but you can use what you
-      like, too. 
-      </para>
-
-      <para>
-        I won't give details about the interrupt handler at this
-        point, but at least its appearance can be explained now. The
-        interrupt handler looks usually like the following: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
-  {
-          struct mychip *chip = dev_id;
-          ....
-          return IRQ_HANDLED;
-  }
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        Now let's write the corresponding destructor for the resources
-      above. The role of destructor is simple: disable the hardware
-      (if already activated) and release the resources. So far, we
-      have no hardware part, so the disabling code is not written here. 
-      </para>
-
-      <para>
-        To release the resources, the <quote>check-and-release</quote>
-        method is a safer way. For the interrupt, do like this: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  if (chip->irq >= 0)
-          free_irq(chip->irq, chip);
-]]>
-          </programlisting>
-        </informalexample>
-
-        Since the irq number can start from 0, you should initialize
-        chip-&gt;irq with a negative value (e.g. -1), so that you can
-        check the validity of the irq number as above.
-      </para>
-
-      <para>
-        When you requested I/O ports or memory regions via
-	<function>pci_request_region()</function> or
-	<function>pci_request_regions()</function> like in this example,
-	release the resource(s) using the corresponding function,
-	<function>pci_release_region()</function> or
-	<function>pci_release_regions()</function>.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  pci_release_regions(chip->pci);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-	When you requested manually via <function>request_region()</function>
-	or <function>request_mem_region</function>, you can release it via
-	<function>release_resource()</function>.  Suppose that you keep
-	the resource pointer returned from <function>request_region()</function>
-	in chip-&gt;res_port, the release procedure looks like:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  release_and_free_resource(chip->res_port);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-      Don't forget to call <function>pci_disable_device()</function>
-      before the end.
-      </para>
-
-      <para>
-        And finally, release the chip-specific record.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  kfree(chip);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-      Again, remember that you cannot
-      use the <parameter>__devexit</parameter> prefix for this destructor. 
-      </para>
-
-      <para>
-      We didn't implement the hardware disabling part in the above.
-      If you need to do this, please note that the destructor may be
-      called even before the initialization of the chip is completed.
-      It would be better to have a flag to skip hardware disabling
-      if the hardware was not initialized yet.
-      </para>
-
-      <para>
-      When the chip-data is assigned to the card using
-      <function>snd_device_new()</function> with
-      <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is 
-      called at the last.  That is, it is assured that all other
-      components like PCMs and controls have already been released.
-      You don't have to stop PCMs, etc. explicitly, but just
-      call low-level hardware stopping.
-      </para>
-
-      <para>
-        The management of a memory-mapped region is almost as same as
-        the management of an I/O port. You'll need three fields like
-        the following: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct mychip {
-          ....
-          unsigned long iobase_phys;
-          void __iomem *iobase_virt;
-  };
-]]>
-          </programlisting>
-        </informalexample>
-
-        and the allocation would be like below:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  if ((err = pci_request_regions(pci, "My Chip")) < 0) {
-          kfree(chip);
-          return err;
-  }
-  chip->iobase_phys = pci_resource_start(pci, 0);
-  chip->iobase_virt = ioremap_nocache(chip->iobase_phys,
-                                      pci_resource_len(pci, 0));
-]]>
-          </programlisting>
-        </informalexample>
-        
-        and the corresponding destructor would be:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int snd_mychip_free(struct mychip *chip)
-  {
-          ....
-          if (chip->iobase_virt)
-                  iounmap(chip->iobase_virt);
-          ....
-          pci_release_regions(chip->pci);
-          ....
-  }
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-    </section>
-
-    <section id="pci-resource-device-struct">
-      <title>Registration of Device Struct</title>
-      <para>
-	At some point, typically after calling <function>snd_device_new()</function>,
-	you need to register the struct <structname>device</structname> of the chip
-	you're handling for udev and co.  ALSA provides a macro for compatibility with
-	older kernels.  Simply call like the following:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_card_set_dev(card, &pci->dev);
-]]>
-          </programlisting>
-        </informalexample>
-	so that it stores the PCI's device pointer to the card.  This will be
-	referred by ALSA core functions later when the devices are registered.
-      </para>
-      <para>
-	In the case of non-PCI, pass the proper device struct pointer of the BUS
-	instead.  (In the case of legacy ISA without PnP, you don't have to do
-	anything.)
-      </para>
-    </section>
-
-    <section id="pci-resource-entries">
-      <title>PCI Entries</title>
-      <para>
-        So far, so good. Let's finish the missing PCI
-      stuff. At first, we need a
-      <structname>pci_device_id</structname> table for this
-      chipset. It's a table of PCI vendor/device ID number, and some
-      masks. 
-      </para>
-
-      <para>
-        For example,
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static struct pci_device_id snd_mychip_ids[] = {
-          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
-            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-          ....
-          { 0, }
-  };
-  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The first and second fields of
-      the <structname>pci_device_id</structname> structure are the vendor and
-      device IDs. If you have no reason to filter the matching
-      devices, you can leave the remaining fields as above. The last
-      field of the <structname>pci_device_id</structname> struct contains
-      private data for this entry. You can specify any value here, for
-      example, to define specific operations for supported device IDs.
-      Such an example is found in the intel8x0 driver. 
-      </para>
-
-      <para>
-        The last entry of this list is the terminator. You must
-      specify this all-zero entry. 
-      </para>
-
-      <para>
-        Then, prepare the <structname>pci_driver</structname> record:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static struct pci_driver driver = {
-          .name = "My Own Chip",
-          .id_table = snd_mychip_ids,
-          .probe = snd_mychip_probe,
-          .remove = __devexit_p(snd_mychip_remove),
-  };
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The <structfield>probe</structfield> and
-      <structfield>remove</structfield> functions have already
-      been defined in the previous sections.
-      The <structfield>remove</structfield> function should
-      be defined with the 
-      <function>__devexit_p()</function> macro, so that it's not
-      defined for built-in (and non-hot-pluggable) case. The
-      <structfield>name</structfield> 
-      field is the name string of this device. Note that you must not
-      use a slash <quote>/</quote> in this string. 
-      </para>
-
-      <para>
-        And at last, the module entries:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int __init alsa_card_mychip_init(void)
-  {
-          return pci_register_driver(&driver);
-  }
-
-  static void __exit alsa_card_mychip_exit(void)
-  {
-          pci_unregister_driver(&driver);
-  }
-
-  module_init(alsa_card_mychip_init)
-  module_exit(alsa_card_mychip_exit)
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        Note that these module entries are tagged with
-      <parameter>__init</parameter> and 
-      <parameter>__exit</parameter> prefixes, not
-      <parameter>__devinit</parameter> nor
-      <parameter>__devexit</parameter>.
-      </para>
-
-      <para>
-        Oh, one thing was forgotten. If you have no exported symbols,
-        you need to declare it in 2.2 or 2.4 kernels (it's not necessary in 2.6 kernels).
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  EXPORT_NO_SYMBOLS;
-]]>
-          </programlisting>
-        </informalexample>
-
-        That's all!
-      </para>
-    </section>
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- PCM Interface  -->
-<!-- ****************************************************** -->
-  <chapter id="pcm-interface">
-    <title>PCM Interface</title>
-
-    <section id="pcm-interface-general">
-      <title>General</title>
-      <para>
-        The PCM middle layer of ALSA is quite powerful and it is only
-      necessary for each driver to implement the low-level functions
-      to access its hardware.
-      </para>
-
-      <para>
-        For accessing to the PCM layer, you need to include
-      <filename>&lt;sound/pcm.h&gt;</filename> first. In addition,
-      <filename>&lt;sound/pcm_params.h&gt;</filename> might be needed
-      if you access to some functions related with hw_param. 
-      </para>
-
-      <para>
-        Each card device can have up to four pcm instances. A pcm
-      instance corresponds to a pcm device file. The limitation of
-      number of instances comes only from the available bit size of
-      the Linux's device numbers. Once when 64bit device number is
-      used, we'll have more pcm instances available. 
-      </para>
-
-      <para>
-        A pcm instance consists of pcm playback and capture streams,
-      and each pcm stream consists of one or more pcm substreams. Some
-      soundcards support multiple playback functions. For example,
-      emu10k1 has a PCM playback of 32 stereo substreams. In this case, at
-      each open, a free substream is (usually) automatically chosen
-      and opened. Meanwhile, when only one substream exists and it was
-      already opened, the successful open will either block
-      or error with <constant>EAGAIN</constant> according to the
-      file open mode. But you don't have to care about such details in your
-      driver. The PCM middle layer will take care of such work.
-      </para>
-    </section>
-
-    <section id="pcm-interface-example">
-      <title>Full Code Example</title>
-      <para>
-      The example code below does not include any hardware access
-      routines but shows only the skeleton, how to build up the PCM
-      interfaces.
-
-        <example>
-          <title>PCM Example Code</title>
-          <programlisting>
-<![CDATA[
-  #include <sound/pcm.h>
-  ....
-
-  /* hardware definition */
-  static struct snd_pcm_hardware snd_mychip_playback_hw = {
-          .info = (SNDRV_PCM_INFO_MMAP |
-                   SNDRV_PCM_INFO_INTERLEAVED |
-                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                   SNDRV_PCM_INFO_MMAP_VALID),
-          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
-          .rates =            SNDRV_PCM_RATE_8000_48000,
-          .rate_min =         8000,
-          .rate_max =         48000,
-          .channels_min =     2,
-          .channels_max =     2,
-          .buffer_bytes_max = 32768,
-          .period_bytes_min = 4096,
-          .period_bytes_max = 32768,
-          .periods_min =      1,
-          .periods_max =      1024,
-  };
-
-  /* hardware definition */
-  static struct snd_pcm_hardware snd_mychip_capture_hw = {
-          .info = (SNDRV_PCM_INFO_MMAP |
-                   SNDRV_PCM_INFO_INTERLEAVED |
-                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                   SNDRV_PCM_INFO_MMAP_VALID),
-          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
-          .rates =            SNDRV_PCM_RATE_8000_48000,
-          .rate_min =         8000,
-          .rate_max =         48000,
-          .channels_min =     2,
-          .channels_max =     2,
-          .buffer_bytes_max = 32768,
-          .period_bytes_min = 4096,
-          .period_bytes_max = 32768,
-          .periods_min =      1,
-          .periods_max =      1024,
-  };
-
-  /* open callback */
-  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          struct snd_pcm_runtime *runtime = substream->runtime;
-
-          runtime->hw = snd_mychip_playback_hw;
-          /* more hardware-initialization will be done here */
-          ....
-          return 0;
-  }
-
-  /* close callback */
-  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          /* the hardware-specific codes will be here */
-          ....
-          return 0;
-
-  }
-
-  /* open callback */
-  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          struct snd_pcm_runtime *runtime = substream->runtime;
-
-          runtime->hw = snd_mychip_capture_hw;
-          /* more hardware-initialization will be done here */
-          ....
-          return 0;
-  }
-
-  /* close callback */
-  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          /* the hardware-specific codes will be here */
-          ....
-          return 0;
-
-  }
-
-  /* hw_params callback */
-  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *hw_params)
-  {
-          return snd_pcm_lib_malloc_pages(substream,
-                                     params_buffer_bytes(hw_params));
-  }
-
-  /* hw_free callback */
-  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
-  {
-          return snd_pcm_lib_free_pages(substream);
-  }
-
-  /* prepare callback */
-  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          struct snd_pcm_runtime *runtime = substream->runtime;
-
-          /* set up the hardware with the current configuration
-           * for example...
-           */
-          mychip_set_sample_format(chip, runtime->format);
-          mychip_set_sample_rate(chip, runtime->rate);
-          mychip_set_channels(chip, runtime->channels);
-          mychip_set_dma_setup(chip, runtime->dma_addr,
-                               chip->buffer_size,
-                               chip->period_size);
-          return 0;
-  }
-
-  /* trigger callback */
-  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
-                                    int cmd)
-  {
-          switch (cmd) {
-          case SNDRV_PCM_TRIGGER_START:
-                  /* do something to start the PCM engine */
-                  ....
-                  break;
-          case SNDRV_PCM_TRIGGER_STOP:
-                  /* do something to stop the PCM engine */
-                  ....
-                  break;
-          default:
-                  return -EINVAL;
-          }
-  }
-
-  /* pointer callback */
-  static snd_pcm_uframes_t
-  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          unsigned int current_ptr;
-
-          /* get the current hardware pointer */
-          current_ptr = mychip_get_hw_pointer(chip);
-          return current_ptr;
-  }
-
-  /* operators */
-  static struct snd_pcm_ops snd_mychip_playback_ops = {
-          .open =        snd_mychip_playback_open,
-          .close =       snd_mychip_playback_close,
-          .ioctl =       snd_pcm_lib_ioctl,
-          .hw_params =   snd_mychip_pcm_hw_params,
-          .hw_free =     snd_mychip_pcm_hw_free,
-          .prepare =     snd_mychip_pcm_prepare,
-          .trigger =     snd_mychip_pcm_trigger,
-          .pointer =     snd_mychip_pcm_pointer,
-  };
-
-  /* operators */
-  static struct snd_pcm_ops snd_mychip_capture_ops = {
-          .open =        snd_mychip_capture_open,
-          .close =       snd_mychip_capture_close,
-          .ioctl =       snd_pcm_lib_ioctl,
-          .hw_params =   snd_mychip_pcm_hw_params,
-          .hw_free =     snd_mychip_pcm_hw_free,
-          .prepare =     snd_mychip_pcm_prepare,
-          .trigger =     snd_mychip_pcm_trigger,
-          .pointer =     snd_mychip_pcm_pointer,
-  };
-
-  /*
-   *  definitions of capture are omitted here...
-   */
-
-  /* create a pcm device */
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
-  {
-          struct snd_pcm *pcm;
-          int err;
-
-          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
-          if (err < 0) 
-                  return err;
-          pcm->private_data = chip;
-          strcpy(pcm->name, "My Chip");
-          chip->pcm = pcm;
-          /* set operators */
-          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                          &snd_mychip_playback_ops);
-          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
-                          &snd_mychip_capture_ops);
-          /* pre-allocation of buffers */
-          /* NOTE: this may fail */
-          snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                                snd_dma_pci_data(chip->pci),
-                                                64*1024, 64*1024);
-          return 0;
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
-    </section>
-
-    <section id="pcm-interface-constructor">
-      <title>Constructor</title>
-      <para>
-        A pcm instance is allocated by the <function>snd_pcm_new()</function>
-      function. It would be better to create a constructor for pcm,
-      namely, 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
-  {
-          struct snd_pcm *pcm;
-          int err;
-
-          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
-          if (err < 0) 
-                  return err;
-          pcm->private_data = chip;
-          strcpy(pcm->name, "My Chip");
-          chip->pcm = pcm;
-	  ....
-          return 0;
-  }
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The <function>snd_pcm_new()</function> function takes four
-      arguments. The first argument is the card pointer to which this
-      pcm is assigned, and the second is the ID string. 
-      </para>
-
-      <para>
-        The third argument (<parameter>index</parameter>, 0 in the
-      above) is the index of this new pcm. It begins from zero. If
-      you create more than one pcm instances, specify the
-      different numbers in this argument. For example,
-      <parameter>index</parameter> = 1 for the second PCM device.  
-      </para>
-
-      <para>
-        The fourth and fifth arguments are the number of substreams
-      for playback and capture, respectively. Here 1 is used for
-      both arguments. When no playback or capture substreams are available,
-      pass 0 to the corresponding argument.
-      </para>
-
-      <para>
-        If a chip supports multiple playbacks or captures, you can
-      specify more numbers, but they must be handled properly in
-      open/close, etc. callbacks.  When you need to know which
-      substream you are referring to, then it can be obtained from
-      struct <structname>snd_pcm_substream</structname> data passed to each callback
-      as follows: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_pcm_substream *substream;
-  int index = substream->number;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        After the pcm is created, you need to set operators for each
-        pcm stream. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                  &snd_mychip_playback_ops);
-  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
-                  &snd_mychip_capture_ops);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The operators are defined typically like this:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static struct snd_pcm_ops snd_mychip_playback_ops = {
-          .open =        snd_mychip_pcm_open,
-          .close =       snd_mychip_pcm_close,
-          .ioctl =       snd_pcm_lib_ioctl,
-          .hw_params =   snd_mychip_pcm_hw_params,
-          .hw_free =     snd_mychip_pcm_hw_free,
-          .prepare =     snd_mychip_pcm_prepare,
-          .trigger =     snd_mychip_pcm_trigger,
-          .pointer =     snd_mychip_pcm_pointer,
-  };
-]]>
-          </programlisting>
-        </informalexample>
-
-        All the callbacks are described in the
-        <link linkend="pcm-interface-operators"><citetitle>
-        Operators</citetitle></link> subsection.
-      </para>
-
-      <para>
-        After setting the operators, you probably will want to
-        pre-allocate the buffer. For the pre-allocation, simply call
-        the following: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                        snd_dma_pci_data(chip->pci),
-                                        64*1024, 64*1024);
-]]>
-          </programlisting>
-        </informalexample>
-
-        It will allocate a buffer up to 64kB as default.
-      Buffer management details will be described in the later section <link
-      linkend="buffer-and-memory"><citetitle>Buffer and Memory
-      Management</citetitle></link>. 
-      </para>
-
-      <para>
-        Additionally, you can set some extra information for this pcm
-        in pcm-&gt;info_flags.
-        The available values are defined as
-        <constant>SNDRV_PCM_INFO_XXX</constant> in
-        <filename>&lt;sound/asound.h&gt;</filename>, which is used for
-        the hardware definition (described later). When your soundchip
-        supports only half-duplex, specify like this: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-    </section>
-
-    <section id="pcm-interface-destructor">
-      <title>... And the Destructor?</title>
-      <para>
-        The destructor for a pcm instance is not always
-      necessary. Since the pcm device will be released by the middle
-      layer code automatically, you don't have to call the destructor
-      explicitly.
-      </para>
-
-      <para>
-        The destructor would be necessary if you created
-        special records internally and needed to release them. In such a
-        case, set the destructor function to
-        pcm-&gt;private_free: 
-
-        <example>
-          <title>PCM Instance with a Destructor</title>
-          <programlisting>
-<![CDATA[
-  static void mychip_pcm_free(struct snd_pcm *pcm)
-  {
-          struct mychip *chip = snd_pcm_chip(pcm);
-          /* free your own data */
-          kfree(chip->my_private_pcm_data);
-          /* do what you like else */
-          ....
-  }
-
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
-  {
-          struct snd_pcm *pcm;
-          ....
-          /* allocate your own data */
-          chip->my_private_pcm_data = kmalloc(...);
-          /* set the destructor */
-          pcm->private_data = chip;
-          pcm->private_free = mychip_pcm_free;
-          ....
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
-    </section>
-
-    <section id="pcm-interface-runtime">
-      <title>Runtime Pointer - The Chest of PCM Information</title>
-	<para>
-	  When the PCM substream is opened, a PCM runtime instance is
-	allocated and assigned to the substream. This pointer is
-	accessible via <constant>substream-&gt;runtime</constant>.
-	This runtime pointer holds most information you need
-	to control the PCM: the copy of hw_params and sw_params configurations, the buffer
-	pointers, mmap records, spinlocks, etc.
-	</para>
-
-	<para>
-	The definition of runtime instance is found in
-	<filename>&lt;sound/pcm.h&gt;</filename>.  Here are
-       the contents of this file:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-struct _snd_pcm_runtime {
-	/* -- Status -- */
-	struct snd_pcm_substream *trigger_master;
-	snd_timestamp_t trigger_tstamp;	/* trigger timestamp */
-	int overrange;
-	snd_pcm_uframes_t avail_max;
-	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
-	snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/
-
-	/* -- HW params -- */
-	snd_pcm_access_t access;	/* access mode */
-	snd_pcm_format_t format;	/* SNDRV_PCM_FORMAT_* */
-	snd_pcm_subformat_t subformat;	/* subformat */
-	unsigned int rate;		/* rate in Hz */
-	unsigned int channels;		/* channels */
-	snd_pcm_uframes_t period_size;	/* period size */
-	unsigned int periods;		/* periods */
-	snd_pcm_uframes_t buffer_size;	/* buffer size */
-	unsigned int tick_time;		/* tick time */
-	snd_pcm_uframes_t min_align;	/* Min alignment for the format */
-	size_t byte_align;
-	unsigned int frame_bits;
-	unsigned int sample_bits;
-	unsigned int info;
-	unsigned int rate_num;
-	unsigned int rate_den;
-
-	/* -- SW params -- */
-	struct timespec tstamp_mode;	/* mmap timestamp is updated */
-  	unsigned int period_step;
-	unsigned int sleep_min;		/* min ticks to sleep */
-	snd_pcm_uframes_t start_threshold;
-	snd_pcm_uframes_t stop_threshold;
-	snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
-						noise is nearest than this */
-	snd_pcm_uframes_t silence_size;	/* Silence filling size */
-	snd_pcm_uframes_t boundary;	/* pointers wrap point */
-
-	snd_pcm_uframes_t silenced_start;
-	snd_pcm_uframes_t silenced_size;
-
-	snd_pcm_sync_id_t sync;		/* hardware synchronization ID */
-
-	/* -- mmap -- */
-	volatile struct snd_pcm_mmap_status *status;
-	volatile struct snd_pcm_mmap_control *control;
-	atomic_t mmap_count;
-
-	/* -- locking / scheduling -- */
-	spinlock_t lock;
-	wait_queue_head_t sleep;
-	struct timer_list tick_timer;
-	struct fasync_struct *fasync;
-
-	/* -- private section -- */
-	void *private_data;
-	void (*private_free)(struct snd_pcm_runtime *runtime);
-
-	/* -- hardware description -- */
-	struct snd_pcm_hardware hw;
-	struct snd_pcm_hw_constraints hw_constraints;
-
-	/* -- interrupt callbacks -- */
-	void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
-	void (*transfer_ack_end)(struct snd_pcm_substream *substream);
-
-	/* -- timer -- */
-	unsigned int timer_resolution;	/* timer resolution */
-
-	/* -- DMA -- */           
-	unsigned char *dma_area;	/* DMA area */
-	dma_addr_t dma_addr;		/* physical bus address (not accessible from main CPU) */
-	size_t dma_bytes;		/* size of DMA area */
-
-	struct snd_dma_buffer *dma_buffer_p;	/* allocated buffer */
-
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-	/* -- OSS things -- */
-	struct snd_pcm_oss_runtime oss;
-#endif
-};
-]]>
-            </programlisting>
-          </informalexample>
-	</para>
-
-	<para>
-	  For the operators (callbacks) of each sound driver, most of
-	these records are supposed to be read-only.  Only the PCM
-	middle-layer changes / updates them.  The exceptions are
-	the hardware description (hw), interrupt callbacks
-	(transfer_ack_xxx), DMA buffer information, and the private
-	data.  Besides, if you use the standard buffer allocation
-	method via <function>snd_pcm_lib_malloc_pages()</function>,
-	you don't need to set the DMA buffer information by yourself.
-	</para>
-
-	<para>
-	In the sections below, important records are explained.
-	</para>
-
-	<section id="pcm-interface-runtime-hw">
-	<title>Hardware Description</title>
-	<para>
-	  The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
-	contains the definitions of the fundamental hardware
-	configuration.  Above all, you'll need to define this in
-	<link linkend="pcm-interface-operators-open-callback"><citetitle>
-	the open callback</citetitle></link>.
-	Note that the runtime instance holds the copy of the
-	descriptor, not the pointer to the existing descriptor.  That
-	is, in the open callback, you can modify the copied descriptor
-	(<constant>runtime-&gt;hw</constant>) as you need.  For example, if the maximum
-	number of channels is 1 only on some chip models, you can
-	still use the same hardware descriptor and change the
-	channels_max later:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-          struct snd_pcm_runtime *runtime = substream->runtime;
-          ...
-          runtime->hw = snd_mychip_playback_hw; /* common definition */
-          if (chip->model == VERY_OLD_ONE)
-                  runtime->hw.channels_max = 1;
-]]>
-            </programlisting>
-          </informalexample>
-	</para>
-
-	<para>
-	  Typically, you'll have a hardware descriptor as below:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static struct snd_pcm_hardware snd_mychip_playback_hw = {
-          .info = (SNDRV_PCM_INFO_MMAP |
-                   SNDRV_PCM_INFO_INTERLEAVED |
-                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                   SNDRV_PCM_INFO_MMAP_VALID),
-          .formats =          SNDRV_PCM_FMTBIT_S16_LE,
-          .rates =            SNDRV_PCM_RATE_8000_48000,
-          .rate_min =         8000,
-          .rate_max =         48000,
-          .channels_min =     2,
-          .channels_max =     2,
-          .buffer_bytes_max = 32768,
-          .period_bytes_min = 4096,
-          .period_bytes_max = 32768,
-          .periods_min =      1,
-          .periods_max =      1024,
-  };
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-	<itemizedlist>
-	<listitem><para>
-          The <structfield>info</structfield> field contains the type and
-        capabilities of this pcm. The bit flags are defined in
-        <filename>&lt;sound/asound.h&gt;</filename> as
-        <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you
-        have to specify whether the mmap is supported and which
-        interleaved format is supported.
-        When the is supported, add the
-        <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the
-        hardware supports the interleaved or the non-interleaved
-        formats, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or
-        <constant>SNDRV_PCM_INFO_NONINTERLEAVED</constant> flag must
-        be set, respectively. If both are supported, you can set both,
-        too. 
-        </para>
-
-        <para>
-          In the above example, <constant>MMAP_VALID</constant> and
-        <constant>BLOCK_TRANSFER</constant> are specified for the OSS mmap
-        mode. Usually both are set. Of course,
-        <constant>MMAP_VALID</constant> is set only if the mmap is
-        really supported. 
-        </para>
-
-        <para>
-          The other possible flags are
-        <constant>SNDRV_PCM_INFO_PAUSE</constant> and
-        <constant>SNDRV_PCM_INFO_RESUME</constant>. The
-        <constant>PAUSE</constant> bit means that the pcm supports the
-        <quote>pause</quote> operation, while the
-        <constant>RESUME</constant> bit means that the pcm supports
-        the full <quote>suspend/resume</quote> operation.
-	If the <constant>PAUSE</constant> flag is set,
-	the <structfield>trigger</structfield> callback below
-        must handle the corresponding (pause push/release) commands.
-	The suspend/resume trigger commands can be defined even without
-	the <constant>RESUME</constant> flag.  See <link
-	linkend="power-management"><citetitle>
-	Power Management</citetitle></link> section for details.
-        </para>
-
-	<para>
-	  When the PCM substreams can be synchronized (typically,
-	synchronized start/stop of a playback and a capture streams),
-	you can give <constant>SNDRV_PCM_INFO_SYNC_START</constant>,
-	too.  In this case, you'll need to check the linked-list of
-	PCM substreams in the trigger callback.  This will be
-	described in the later section.
-	</para>
-	</listitem>
-
-	<listitem>
-        <para>
-          <structfield>formats</structfield> field contains the bit-flags
-        of supported formats (<constant>SNDRV_PCM_FMTBIT_XXX</constant>).
-        If the hardware supports more than one format, give all or'ed
-        bits.  In the example above, the signed 16bit little-endian
-        format is specified.
-        </para>
-	</listitem>
-
-	<listitem>
-        <para>
-        <structfield>rates</structfield> field contains the bit-flags of
-        supported rates (<constant>SNDRV_PCM_RATE_XXX</constant>).
-        When the chip supports continuous rates, pass
-        <constant>CONTINUOUS</constant> bit additionally.
-        The pre-defined rate bits are provided only for typical
-	rates. If your chip supports unconventional rates, you need to add
-        the <constant>KNOT</constant> bit and set up the hardware
-        constraint manually (explained later).
-        </para>
-	</listitem>
-
-	<listitem>
-	<para>
-	<structfield>rate_min</structfield> and
-	<structfield>rate_max</structfield> define the minimum and
-	maximum sample rate.  This should correspond somehow to
-	<structfield>rates</structfield> bits.
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	<structfield>channel_min</structfield> and
-	<structfield>channel_max</structfield> 
-	define, as you might already expected, the minimum and maximum
-	number of channels.
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	<structfield>buffer_bytes_max</structfield> defines the
-	maximum buffer size in bytes.  There is no
-	<structfield>buffer_bytes_min</structfield> field, since
-	it can be calculated from the minimum period size and the
-	minimum number of periods.
-	Meanwhile, <structfield>period_bytes_min</structfield> and
-	define the minimum and maximum size of the period in bytes.
-	<structfield>periods_max</structfield> and
-	<structfield>periods_min</structfield> define the maximum and
-	minimum number of periods in the buffer.
-        </para>
-
-	<para>
-	The <quote>period</quote> is a term that corresponds to
-	a fragment in the OSS world. The period defines the size at
-	which a PCM interrupt is generated. This size strongly
-	depends on the hardware. 
-	Generally, the smaller period size will give you more
-	interrupts, that is, more controls. 
-	In the case of capture, this size defines the input latency.
-	On the other hand, the whole buffer size defines the
-	output latency for the playback direction.
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	There is also a field <structfield>fifo_size</structfield>.
-	This specifies the size of the hardware FIFO, but currently it
-	is neither used in the driver nor in the alsa-lib.  So, you
-	can ignore this field.
-	</para>
-	</listitem>
-	</itemizedlist>
-	</para>
-	</section>
-
-	<section id="pcm-interface-runtime-config">
-	<title>PCM Configurations</title>
-	<para>
-	Ok, let's go back again to the PCM runtime records.
-	The most frequently referred records in the runtime instance are
-	the PCM configurations.
-	The PCM configurations are stored in the runtime instance
-	after the application sends <type>hw_params</type> data via
-	alsa-lib.  There are many fields copied from hw_params and
-	sw_params structs.  For example,
-	<structfield>format</structfield> holds the format type
-	chosen by the application.  This field contains the enum value
-	<constant>SNDRV_PCM_FORMAT_XXX</constant>.
-	</para>
-
-	<para>
-	One thing to be noted is that the configured buffer and period
-	sizes are stored in <quote>frames</quote> in the runtime.
-        In the ALSA world, 1 frame = channels * samples-size.
-	For conversion between frames and bytes, you can use the
-	<function>frames_to_bytes()</function> and
-          <function>bytes_to_frames()</function> helper functions. 
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  period_bytes = frames_to_bytes(runtime, runtime->period_size);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-	<para>
-	Also, many software parameters (sw_params) are
-	stored in frames, too.  Please check the type of the field.
-	<type>snd_pcm_uframes_t</type> is for the frames as unsigned
-	integer while <type>snd_pcm_sframes_t</type> is for the frames
-	as signed integer.
-	</para>
-	</section>
-
-	<section id="pcm-interface-runtime-dma">
-	<title>DMA Buffer Information</title>
-	<para>
-	The DMA buffer is defined by the following four fields,
-	<structfield>dma_area</structfield>,
-	<structfield>dma_addr</structfield>,
-	<structfield>dma_bytes</structfield> and
-	<structfield>dma_private</structfield>.
-	The <structfield>dma_area</structfield> holds the buffer
-	pointer (the logical address).  You can call
-	<function>memcpy</function> from/to 
-	this pointer.  Meanwhile, <structfield>dma_addr</structfield>
-	holds the physical address of the buffer.  This field is
-	specified only when the buffer is a linear buffer.
-	<structfield>dma_bytes</structfield> holds the size of buffer
-	in bytes.  <structfield>dma_private</structfield> is used for
-	the ALSA DMA allocator.
-	</para>
-
-	<para>
-	If you use a standard ALSA function,
-	<function>snd_pcm_lib_malloc_pages()</function>, for
-	allocating the buffer, these fields are set by the ALSA middle
-	layer, and you should <emphasis>not</emphasis> change them by
-	yourself.  You can read them but not write them.
-	On the other hand, if you want to allocate the buffer by
-	yourself, you'll need to manage it in hw_params callback.
-	At least, <structfield>dma_bytes</structfield> is mandatory.
-	<structfield>dma_area</structfield> is necessary when the
-	buffer is mmapped.  If your driver doesn't support mmap, this
-	field is not necessary.  <structfield>dma_addr</structfield>
-	is also optional.  You can use
-	<structfield>dma_private</structfield> as you like, too.
-	</para>
-	</section>
-
-	<section id="pcm-interface-runtime-status">
-	<title>Running Status</title>
-	<para>
-	The running status can be referred via <constant>runtime-&gt;status</constant>.
-	This is the pointer to the struct <structname>snd_pcm_mmap_status</structname>
-	record.  For example, you can get the current DMA hardware
-	pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
-	</para>
-
-	<para>
-	The DMA application pointer can be referred via
-	<constant>runtime-&gt;control</constant>, which points to the
-	struct <structname>snd_pcm_mmap_control</structname> record.
-	However, accessing directly to this value is not recommended.
-	</para>
-	</section>
-
-	<section id="pcm-interface-runtime-private">
-	<title>Private Data</title> 
-	<para>
-	You can allocate a record for the substream and store it in
-	<constant>runtime-&gt;private_data</constant>.  Usually, this
-	is done in
-	<link linkend="pcm-interface-operators-open-callback"><citetitle>
-	the open callback</citetitle></link>.
-	Don't mix this with <constant>pcm-&gt;private_data</constant>.
-	The <constant>pcm-&gt;private_data</constant> usually points to the
-	chip instance assigned statically at the creation of PCM, while the 
-	<constant>runtime-&gt;private_data</constant> points to a dynamic
-	data structure created at the PCM open callback.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_open(struct snd_pcm_substream *substream)
-  {
-          struct my_pcm_data *data;
-          ....
-          data = kmalloc(sizeof(*data), GFP_KERNEL);
-          substream->runtime->private_data = data;
-          ....
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          The allocated object must be released in
-	<link linkend="pcm-interface-operators-open-callback"><citetitle>
-	the close callback</citetitle></link>.
-        </para>
-	</section>
-
-	<section id="pcm-interface-runtime-intr">
-	<title>Interrupt Callbacks</title>
-	<para>
-	The field <structfield>transfer_ack_begin</structfield> and
-	<structfield>transfer_ack_end</structfield> are called at
-	the beginning and at the end of
-	<function>snd_pcm_period_elapsed()</function>, respectively. 
-	</para>
-	</section>
-
-    </section>
-
-    <section id="pcm-interface-operators">
-      <title>Operators</title>
-      <para>
-        OK, now let me give details about each pcm callback
-      (<parameter>ops</parameter>). In general, every callback must
-      return 0 if successful, or a negative error number
-      such as <constant>-EINVAL</constant>. To choose an appropriate
-      error number, it is advised to check what value other parts of
-      the kernel return when the same kind of request fails.
-      </para>
-
-      <para>
-        The callback function takes at least the argument with
-        <structname>snd_pcm_substream</structname> pointer. To retrieve
-        the chip record from the given substream instance, you can use the
-        following macro. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  int xxx() {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          ....
-  }
-]]>
-          </programlisting>
-        </informalexample>
-
-	The macro reads <constant>substream-&gt;private_data</constant>,
-	which is a copy of <constant>pcm-&gt;private_data</constant>.
-	You can override the former if you need to assign different data
-	records per PCM substream.  For example, the cmi8330 driver assigns
-	different private_data for playback and capture directions,
-	because it uses two different codecs (SB- and AD-compatible) for
-	different directions.
-      </para>
-
-      <section id="pcm-interface-operators-open-callback">
-        <title>open callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_open(struct snd_pcm_substream *substream);
-]]>
-            </programlisting>
-          </informalexample>
-
-          This is called when a pcm substream is opened.
-        </para>
-
-        <para>
-          At least, here you have to initialize the runtime-&gt;hw
-          record. Typically, this is done by like this: 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_open(struct snd_pcm_substream *substream)
-  {
-          struct mychip *chip = snd_pcm_substream_chip(substream);
-          struct snd_pcm_runtime *runtime = substream->runtime;
-
-          runtime->hw = snd_mychip_playback_hw;
-          return 0;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-
-          where <parameter>snd_mychip_playback_hw</parameter> is the
-          pre-defined hardware description.
-	</para>
-
-	<para>
-	You can allocate a private data in this callback, as described
-	in <link linkend="pcm-interface-runtime-private"><citetitle>
-	Private Data</citetitle></link> section.
-	</para>
-
-	<para>
-	If the hardware configuration needs more constraints, set the
-	hardware constraints here, too.
-	See <link linkend="pcm-interface-constraints"><citetitle>
-	Constraints</citetitle></link> for more details.
-	</para>
-      </section>
-
-      <section id="pcm-interface-operators-close-callback">
-        <title>close callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_close(struct snd_pcm_substream *substream);
-]]>
-            </programlisting>
-          </informalexample>
-
-          Obviously, this is called when a pcm substream is closed.
-        </para>
-
-        <para>
-          Any private instance for a pcm substream allocated in the
-          open callback will be released here. 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_close(struct snd_pcm_substream *substream)
-  {
-          ....
-          kfree(substream->runtime->private_data);
-          ....
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-ioctl-callback">
-        <title>ioctl callback</title>
-        <para>
-          This is used for any special call to pcm ioctls. But
-        usually you can pass a generic ioctl callback, 
-        <function>snd_pcm_lib_ioctl</function>.
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-hw-params-callback">
-        <title>hw_params callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *hw_params);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          This is called when the hardware parameter
-        (<structfield>hw_params</structfield>) is set
-        up by the application, 
-        that is, once when the buffer size, the period size, the
-        format, etc. are defined for the pcm substream. 
-        </para>
-
-        <para>
-          Many hardware setups should be done in this callback,
-        including the allocation of buffers. 
-        </para>
-
-        <para>
-          Parameters to be initialized are retrieved by
-          <function>params_xxx()</function> macros. To allocate
-          buffer, you can call a helper function, 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-]]>
-            </programlisting>
-          </informalexample>
-
-          <function>snd_pcm_lib_malloc_pages()</function> is available
-	  only when the DMA buffers have been pre-allocated.
-	  See the section <link
-	  linkend="buffer-and-memory-buffer-types"><citetitle>
-	  Buffer Types</citetitle></link> for more details.
-        </para>
-
-        <para>
-          Note that this and <structfield>prepare</structfield> callbacks
-        may be called multiple times per initialization.
-        For example, the OSS emulation may
-        call these callbacks at each change via its ioctl. 
-        </para>
-
-        <para>
-          Thus, you need to be careful not to allocate the same buffers
-        many times, which will lead to memory leaks!  Calling the
-        helper function above many times is OK. It will release the
-        previous buffer automatically when it was already allocated. 
-        </para>
-
-        <para>
-          Another note is that this callback is non-atomic
-        (schedulable). This is important, because the
-        <structfield>trigger</structfield> callback 
-        is atomic (non-schedulable). That is, mutexes or any
-        schedule-related functions are not available in
-        <structfield>trigger</structfield> callback.
-	Please see the subsection
-	<link linkend="pcm-interface-atomicity"><citetitle>
-	Atomicity</citetitle></link> for details.
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-hw-free-callback">
-        <title>hw_free callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          This is called to release the resources allocated via
-          <structfield>hw_params</structfield>. For example, releasing the
-          buffer via 
-          <function>snd_pcm_lib_malloc_pages()</function> is done by
-          calling the following: 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  snd_pcm_lib_free_pages(substream);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          This function is always called before the close callback is called.
-          Also, the callback may be called multiple times, too.
-          Keep track whether the resource was already released. 
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-prepare-callback">
-       <title>prepare callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_prepare(struct snd_pcm_substream *substream);
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          This callback is called when the pcm is
-        <quote>prepared</quote>. You can set the format type, sample
-        rate, etc. here. The difference from
-        <structfield>hw_params</structfield> is that the 
-        <structfield>prepare</structfield> callback will be called each
-        time 
-        <function>snd_pcm_prepare()</function> is called, i.e. when
-        recovering after underruns, etc. 
-        </para>
-
-        <para>
-	Note that this callback is now non-atomic.
-	You can use schedule-related functions safely in this callback.
-        </para>
-
-        <para>
-          In this and the following callbacks, you can refer to the
-        values via the runtime record,
-        substream-&gt;runtime.
-        For example, to get the current
-        rate, format or channels, access to
-        runtime-&gt;rate,
-        runtime-&gt;format or
-        runtime-&gt;channels, respectively. 
-        The physical address of the allocated buffer is set to
-	runtime-&gt;dma_area.  The buffer and period sizes are
-	in runtime-&gt;buffer_size and runtime-&gt;period_size,
-	respectively.
-        </para>
-
-        <para>
-          Be careful that this callback will be called many times at
-        each setup, too. 
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-trigger-callback">
-        <title>trigger callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
-]]>
-            </programlisting>
-          </informalexample>
-
-          This is called when the pcm is started, stopped or paused.
-        </para>
-
-        <para>
-          Which action is specified in the second argument,
-          <constant>SNDRV_PCM_TRIGGER_XXX</constant> in
-          <filename>&lt;sound/pcm.h&gt;</filename>. At least,
-          the <constant>START</constant> and <constant>STOP</constant>
-          commands must be defined in this callback. 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  switch (cmd) {
-  case SNDRV_PCM_TRIGGER_START:
-          /* do something to start the PCM engine */
-          break;
-  case SNDRV_PCM_TRIGGER_STOP:
-          /* do something to stop the PCM engine */
-          break;
-  default:
-          return -EINVAL;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-          When the pcm supports the pause operation (given in the info
-        field of the hardware table), the <constant>PAUSE_PUSE</constant>
-        and <constant>PAUSE_RELEASE</constant> commands must be
-        handled here, too. The former is the command to pause the pcm,
-        and the latter to restart the pcm again. 
-        </para>
-
-        <para>
-          When the pcm supports the suspend/resume operation,
-	regardless of full or partial suspend/resume support,
-        the <constant>SUSPEND</constant> and <constant>RESUME</constant>
-        commands must be handled, too.
-        These commands are issued when the power-management status is
-        changed.  Obviously, the <constant>SUSPEND</constant> and
-        <constant>RESUME</constant> commands
-        suspend and resume the pcm substream, and usually, they
-        are identical to the <constant>STOP</constant> and
-        <constant>START</constant> commands, respectively.
-	  See the <link linkend="power-management"><citetitle>
-	Power Management</citetitle></link> section for details.
-        </para>
-
-        <para>
-          As mentioned, this callback is atomic.  You cannot call
-	  functions which may sleep.
-	  The trigger callback should be as minimal as possible,
-	  just really triggering the DMA.  The other stuff should be
-	  initialized hw_params and prepare callbacks properly
-	  beforehand.
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-pointer-callback">
-        <title>pointer callback</title>
-        <para>
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
-]]>
-            </programlisting>
-          </informalexample>
-
-          This callback is called when the PCM middle layer inquires
-        the current hardware position on the buffer. The position must
-        be returned in frames,
-        ranging from 0 to buffer_size - 1.
-        </para>
-
-        <para>
-          This is called usually from the buffer-update routine in the
-        pcm middle layer, which is invoked when
-        <function>snd_pcm_period_elapsed()</function> is called in the
-        interrupt routine. Then the pcm middle layer updates the
-        position and calculates the available space, and wakes up the
-        sleeping poll threads, etc. 
-        </para>
-
-        <para>
-          This callback is also atomic.
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-copy-silence">
-        <title>copy and silence callbacks</title>
-        <para>
-          These callbacks are not mandatory, and can be omitted in
-        most cases. These callbacks are used when the hardware buffer
-        cannot be in the normal memory space. Some chips have their
-        own buffer on the hardware which is not mappable. In such a
-        case, you have to transfer the data manually from the memory
-        buffer to the hardware buffer. Or, if the buffer is
-        non-contiguous on both physical and virtual memory spaces,
-        these callbacks must be defined, too. 
-        </para>
-
-        <para>
-          If these two callbacks are defined, copy and set-silence
-        operations are done by them. The detailed will be described in
-        the later section <link
-        linkend="buffer-and-memory"><citetitle>Buffer and Memory
-        Management</citetitle></link>. 
-        </para>
-      </section>
-
-      <section id="pcm-interface-operators-ack">
-        <title>ack callback</title>
-        <para>
-          This callback is also not mandatory. This callback is called
-        when the appl_ptr is updated in read or write operations.
-        Some drivers like emu10k1-fx and cs46xx need to track the
-	current appl_ptr for the internal buffer, and this callback
-	is useful only for such a purpose.
-	</para>
-	<para>
-	  This callback is atomic.
-	</para>
-      </section>
-
-      <section id="pcm-interface-operators-page-callback">
-        <title>page callback</title>
-
-        <para>
-          This callback is optional too. This callback is used
-        mainly for non-contiguous buffers. The mmap calls this
-        callback to get the page address. Some examples will be
-        explained in the later section <link
-        linkend="buffer-and-memory"><citetitle>Buffer and Memory
-        Management</citetitle></link>, too. 
-        </para>
-      </section>
-    </section>
-
-    <section id="pcm-interface-interrupt-handler">
-      <title>Interrupt Handler</title>
-      <para>
-        The rest of pcm stuff is the PCM interrupt handler. The
-      role of PCM interrupt handler in the sound driver is to update
-      the buffer position and to tell the PCM middle layer when the
-      buffer position goes across the prescribed period size. To
-      inform this, call the <function>snd_pcm_period_elapsed()</function>
-      function. 
-      </para>
-
-      <para>
-        There are several types of sound chips to generate the interrupts.
-      </para>
-
-      <section id="pcm-interface-interrupt-handler-boundary">
-        <title>Interrupts at the period (fragment) boundary</title>
-        <para>
-          This is the most frequently found type:  the hardware
-        generates an interrupt at each period boundary.
-	In this case, you can call
-        <function>snd_pcm_period_elapsed()</function> at each 
-        interrupt. 
-        </para>
-
-        <para>
-          <function>snd_pcm_period_elapsed()</function> takes the
-        substream pointer as its argument. Thus, you need to keep the
-        substream pointer accessible from the chip instance. For
-        example, define substream field in the chip record to hold the
-        current running substream pointer, and set the pointer value
-        at open callback (and reset at close callback). 
-        </para>
-
-        <para>
-          If you acquire a spinlock in the interrupt handler, and the
-        lock is used in other pcm callbacks, too, then you have to
-        release the lock before calling
-        <function>snd_pcm_period_elapsed()</function>, because
-        <function>snd_pcm_period_elapsed()</function> calls other pcm
-        callbacks inside. 
-        </para>
-
-        <para>
-          Typical code would be like:
-
-          <example>
-	    <title>Interrupt Handler Case #1</title>
-            <programlisting>
-<![CDATA[
-  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
-  {
-          struct mychip *chip = dev_id;
-          spin_lock(&chip->lock);
-          ....
-          if (pcm_irq_invoked(chip)) {
-                  /* call updater, unlock before it */
-                  spin_unlock(&chip->lock);
-                  snd_pcm_period_elapsed(chip->substream);
-                  spin_lock(&chip->lock);
-                  /* acknowledge the interrupt if necessary */
-          }
-          ....
-          spin_unlock(&chip->lock);
-          return IRQ_HANDLED;
-  }
-]]>
-            </programlisting>
-          </example>
-        </para>
-      </section>
-
-      <section id="pcm-interface-interrupt-handler-timer">
-        <title>High frequency timer interrupts</title>
-        <para>
-	This happense when the hardware doesn't generate interrupts
-        at the period boundary but issues timer interrupts at a fixed
-        timer rate (e.g. es1968 or ymfpci drivers). 
-        In this case, you need to check the current hardware
-        position and accumulate the processed sample length at each
-        interrupt.  When the accumulated size exceeds the period
-        size, call 
-        <function>snd_pcm_period_elapsed()</function> and reset the
-        accumulator. 
-        </para>
-
-        <para>
-          Typical code would be like the following.
-
-          <example>
-	    <title>Interrupt Handler Case #2</title>
-            <programlisting>
-<![CDATA[
-  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
-  {
-          struct mychip *chip = dev_id;
-          spin_lock(&chip->lock);
-          ....
-          if (pcm_irq_invoked(chip)) {
-                  unsigned int last_ptr, size;
-                  /* get the current hardware pointer (in frames) */
-                  last_ptr = get_hw_ptr(chip);
-                  /* calculate the processed frames since the
-                   * last update
-                   */
-                  if (last_ptr < chip->last_ptr)
-                          size = runtime->buffer_size + last_ptr 
-                                   - chip->last_ptr; 
-                  else
-                          size = last_ptr - chip->last_ptr;
-                  /* remember the last updated point */
-                  chip->last_ptr = last_ptr;
-                  /* accumulate the size */
-                  chip->size += size;
-                  /* over the period boundary? */
-                  if (chip->size >= runtime->period_size) {
-                          /* reset the accumulator */
-                          chip->size %= runtime->period_size;
-                          /* call updater */
-                          spin_unlock(&chip->lock);
-                          snd_pcm_period_elapsed(substream);
-                          spin_lock(&chip->lock);
-                  }
-                  /* acknowledge the interrupt if necessary */
-          }
-          ....
-          spin_unlock(&chip->lock);
-          return IRQ_HANDLED;
-  }
-]]>
-            </programlisting>
-          </example>
-        </para>
-      </section>
-
-      <section id="pcm-interface-interrupt-handler-both">
-        <title>On calling <function>snd_pcm_period_elapsed()</function></title>
-        <para>
-          In both cases, even if more than one period are elapsed, you
-        don't have to call
-        <function>snd_pcm_period_elapsed()</function> many times. Call
-        only once. And the pcm layer will check the current hardware
-        pointer and update to the latest status. 
-        </para>
-      </section>
-    </section>
-
-    <section id="pcm-interface-atomicity">
-      <title>Atomicity</title>
-      <para>
-      One of the most important (and thus difficult to debug) problems
-      in kernel programming are race conditions.
-      In the Linux kernel, they are usually avoided via spin-locks, mutexes
-      or semaphores.  In general, if a race condition can happen
-      in an interrupt handler, it has to be managed atomically, and you
-      have to use a spinlock to protect the critical session. If the
-      critical section is not in interrupt handler code and
-      if taking a relatively long time to execute is acceptable, you
-      should use mutexes or semaphores instead.
-      </para>
-
-      <para>
-      As already seen, some pcm callbacks are atomic and some are
-      not.  For example, the <parameter>hw_params</parameter> callback is
-      non-atomic, while <parameter>trigger</parameter> callback is
-      atomic.  This means, the latter is called already in a spinlock
-      held by the PCM middle layer. Please take this atomicity into
-      account when you choose a locking scheme in the callbacks.
-      </para>
-
-      <para>
-      In the atomic callbacks, you cannot use functions which may call
-      <function>schedule</function> or go to
-      <function>sleep</function>.  Semaphores and mutexes can sleep,
-      and hence they cannot be used inside the atomic callbacks
-      (e.g. <parameter>trigger</parameter> callback).
-      To implement some delay in such a callback, please use
-      <function>udelay()</function> or <function>mdelay()</function>.
-      </para>
-
-      <para>
-      All three atomic callbacks (trigger, pointer, and ack) are
-      called with local interrupts disabled.
-      </para>
-
-    </section>
-    <section id="pcm-interface-constraints">
-      <title>Constraints</title>
-      <para>
-        If your chip supports unconventional sample rates, or only the
-      limited samples, you need to set a constraint for the
-      condition. 
-      </para>
-
-      <para>
-        For example, in order to restrict the sample rates in the some
-        supported values, use
-	<function>snd_pcm_hw_constraint_list()</function>.
-	You need to call this function in the open callback.
-
-        <example>
-	  <title>Example of Hardware Constraints</title>
-          <programlisting>
-<![CDATA[
-  static unsigned int rates[] =
-          {4000, 10000, 22050, 44100};
-  static struct snd_pcm_hw_constraint_list constraints_rates = {
-          .count = ARRAY_SIZE(rates),
-          .list = rates,
-          .mask = 0,
-  };
-
-  static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
-  {
-          int err;
-          ....
-          err = snd_pcm_hw_constraint_list(substream->runtime, 0,
-                                           SNDRV_PCM_HW_PARAM_RATE,
-                                           &constraints_rates);
-          if (err < 0)
-                  return err;
-          ....
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
-
-      <para>
-        There are many different constraints.
-        Look at <filename>sound/pcm.h</filename> for a complete list.
-        You can even define your own constraint rules.
-        For example, let's suppose my_chip can manage a substream of 1 channel
-        if and only if the format is S16_LE, otherwise it supports any format
-        specified in the <structname>snd_pcm_hardware</structname> structure (or in any
-        other constraint_list). You can build a rule like this:
-
-        <example>
-	  <title>Example of Hardware Constraints for Channels</title>
-	  <programlisting>
-<![CDATA[
-  static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
-                                        struct snd_pcm_hw_rule *rule)
-  {
-          struct snd_interval *c = hw_param_interval(params,
-                SNDRV_PCM_HW_PARAM_CHANNELS);
-          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          struct snd_mask fmt;
-
-          snd_mask_any(&fmt);    /* Init the struct */
-          if (c->min < 2) {
-                  fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE;
-                  return snd_mask_refine(f, &fmt);
-          }
-          return 0;
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
- 
-      <para>
-        Then you need to call this function to add your rule:
-
-       <informalexample>
-	 <programlisting>
-<![CDATA[
-  snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                      hw_rule_channels_by_format, 0, SNDRV_PCM_HW_PARAM_FORMAT,
-                      -1);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The rule function is called when an application sets the number of
-        channels. But an application can set the format before the number of
-        channels. Thus you also need to define the inverse rule:
-
-       <example>
-	 <title>Example of Hardware Constraints for Channels</title>
-	 <programlisting>
-<![CDATA[
-  static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
-                                        struct snd_pcm_hw_rule *rule)
-  {
-          struct snd_interval *c = hw_param_interval(params,
-                        SNDRV_PCM_HW_PARAM_CHANNELS);
-          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          struct snd_interval ch;
-
-          snd_interval_any(&ch);
-          if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
-                  ch.min = ch.max = 1;
-                  ch.integer = 1;
-                  return snd_interval_refine(c, &ch);
-          }
-          return 0;
-  }
-]]>
-          </programlisting>
-        </example>
-      </para>
-
-      <para>
-      ...and in the open callback:
-       <informalexample>
-	 <programlisting>
-<![CDATA[
-  snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
-                      hw_rule_format_by_channels, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                      -1);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        I won't give more details here, rather I
-        would like to say, <quote>Luke, use the source.</quote>
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Control Interface  -->
-<!-- ****************************************************** -->
-  <chapter id="control-interface">
-    <title>Control Interface</title>
-
-    <section id="control-interface-general">
-      <title>General</title>
-      <para>
-        The control interface is used widely for many switches,
-      sliders, etc. which are accessed from user-space. Its most
-      important use is the mixer interface. In other words, since ALSA
-      0.9.x, all the mixer stuff is implemented on the control kernel API.
-      </para>
-
-      <para>
-        ALSA has a well-defined AC97 control module. If your chip
-      supports only the AC97 and nothing else, you can skip this
-      section. 
-      </para>
-
-      <para>
-        The control API is defined in
-      <filename>&lt;sound/control.h&gt;</filename>.
-      Include this file if you want to add your own controls.
-      </para>
-    </section>
-
-    <section id="control-interface-definition">
-      <title>Definition of Controls</title>
-      <para>
-        To create a new control, you need to define the
-	following three
-      callbacks: <structfield>info</structfield>,
-      <structfield>get</structfield> and
-      <structfield>put</structfield>. Then, define a
-      struct <structname>snd_kcontrol_new</structname> record, such as: 
-
-        <example>
-	  <title>Definition of a Control</title>
-          <programlisting>
-<![CDATA[
-  static struct snd_kcontrol_new my_control __devinitdata = {
-          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-          .name = "PCM Playback Switch",
-          .index = 0,
-          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-          .private_value = 0xffff,
-          .info = my_control_info,
-          .get = my_control_get,
-          .put = my_control_put
-  };
-]]>
-          </programlisting>
-        </example>
-      </para>
-
-      <para>
-        Most likely the control is created via
-      <function>snd_ctl_new1()</function>, and in such a case, you can
-      add the <parameter>__devinitdata</parameter> prefix to the
-      definition as above. 
-      </para>
-
-      <para>
-        The <structfield>iface</structfield> field specifies the control
-      type, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
-      is usually <constant>MIXER</constant>.
-      Use <constant>CARD</constant> for global controls that are not
-      logically part of the mixer.
-      If the control is closely associated with some specific device on
-      the sound card, use <constant>HWDEP</constant>,
-      <constant>PCM</constant>, <constant>RAWMIDI</constant>,
-      <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
-      specify the device number with the
-      <structfield>device</structfield> and
-      <structfield>subdevice</structfield> fields.
-      </para>
-
-      <para>
-        The <structfield>name</structfield> is the name identifier
-      string. Since ALSA 0.9.x, the control name is very important,
-      because its role is classified from its name. There are
-      pre-defined standard control names. The details are described in
-      the <link linkend="control-interface-control-names"><citetitle>
-      Control Names</citetitle></link> subsection.
-      </para>
-
-      <para>
-        The <structfield>index</structfield> field holds the index number
-      of this control. If there are several different controls with
-      the same name, they can be distinguished by the index
-      number. This is the case when 
-      several codecs exist on the card. If the index is zero, you can
-      omit the definition above. 
-      </para>
-
-      <para>
-        The <structfield>access</structfield> field contains the access
-      type of this control. Give the combination of bit masks,
-      <constant>SNDRV_CTL_ELEM_ACCESS_XXX</constant>, there.
-      The details will be explained in
-      the <link linkend="control-interface-access-flags"><citetitle>
-      Access Flags</citetitle></link> subsection.
-      </para>
-
-      <para>
-        The <structfield>private_value</structfield> field contains
-      an arbitrary long integer value for this record. When using
-      the generic <structfield>info</structfield>,
-      <structfield>get</structfield> and
-      <structfield>put</structfield> callbacks, you can pass a value 
-      through this field. If several small numbers are necessary, you can
-      combine them in bitwise. Or, it's possible to give a pointer
-      (casted to unsigned long) of some record to this field, too. 
-      </para>
-
-      <para>
-      The <structfield>tlv</structfield> field can be used to provide
-      metadata about the control; see the
-      <link linkend="control-interface-tlv">
-      <citetitle>Metadata</citetitle></link> subsection.
-      </para>
-
-      <para>
-        The other three are
-	<link linkend="control-interface-callbacks"><citetitle>
-	callback functions</citetitle></link>.
-      </para>
-    </section>
-
-    <section id="control-interface-control-names">
-      <title>Control Names</title>
-      <para>
-        There are some standards to define the control names. A
-      control is usually defined from the three parts as
-      <quote>SOURCE DIRECTION FUNCTION</quote>. 
-      </para>
-
-      <para>
-        The first, <constant>SOURCE</constant>, specifies the source
-      of the control, and is a string such as <quote>Master</quote>,
-      <quote>PCM</quote>, <quote>CD</quote> and
-      <quote>Line</quote>. There are many pre-defined sources. 
-      </para>
-
-      <para>
-        The second, <constant>DIRECTION</constant>, is one of the
-      following strings according to the direction of the control:
-      <quote>Playback</quote>, <quote>Capture</quote>, <quote>Bypass
-      Playback</quote> and <quote>Bypass Capture</quote>. Or, it can
-      be omitted, meaning both playback and capture directions. 
-      </para>
-
-      <para>
-        The third, <constant>FUNCTION</constant>, is one of the
-      following strings according to the function of the control:
-      <quote>Switch</quote>, <quote>Volume</quote> and
-      <quote>Route</quote>. 
-      </para>
-
-      <para>
-        The example of control names are, thus, <quote>Master Capture
-      Switch</quote> or <quote>PCM Playback Volume</quote>. 
-      </para>
-
-      <para>
-        There are some exceptions:
-      </para>
-
-      <section id="control-interface-control-names-global">
-        <title>Global capture and playback</title>
-        <para>
-          <quote>Capture Source</quote>, <quote>Capture Switch</quote>
-        and <quote>Capture Volume</quote> are used for the global
-        capture (input) source, switch and volume. Similarly,
-        <quote>Playback Switch</quote> and <quote>Playback
-        Volume</quote> are used for the global output gain switch and
-        volume. 
-        </para>
-      </section>
-
-      <section id="control-interface-control-names-tone">
-        <title>Tone-controls</title>
-        <para>
-          tone-control switch and volumes are specified like
-        <quote>Tone Control - XXX</quote>, e.g. <quote>Tone Control -
-        Switch</quote>, <quote>Tone Control - Bass</quote>,
-        <quote>Tone Control - Center</quote>.  
-        </para>
-      </section>
-
-      <section id="control-interface-control-names-3d">
-        <title>3D controls</title>
-        <para>
-          3D-control switches and volumes are specified like <quote>3D
-        Control - XXX</quote>, e.g. <quote>3D Control -
-        Switch</quote>, <quote>3D Control - Center</quote>, <quote>3D
-        Control - Space</quote>. 
-        </para>
-      </section>
-
-      <section id="control-interface-control-names-mic">
-        <title>Mic boost</title>
-        <para>
-          Mic-boost switch is set as <quote>Mic Boost</quote> or
-        <quote>Mic Boost (6dB)</quote>. 
-        </para>
-
-        <para>
-          More precise information can be found in
-        <filename>Documentation/sound/alsa/ControlNames.txt</filename>.
-        </para>
-      </section>
-    </section>
-
-    <section id="control-interface-access-flags">
-      <title>Access Flags</title>
-
-      <para>
-      The access flag is the bitmask which specifies the access type
-      of the given control.  The default access type is
-      <constant>SNDRV_CTL_ELEM_ACCESS_READWRITE</constant>, 
-      which means both read and write are allowed to this control.
-      When the access flag is omitted (i.e. = 0), it is
-      considered as <constant>READWRITE</constant> access as default. 
-      </para>
-
-      <para>
-      When the control is read-only, pass
-      <constant>SNDRV_CTL_ELEM_ACCESS_READ</constant> instead.
-      In this case, you don't have to define
-      the <structfield>put</structfield> callback.
-      Similarly, when the control is write-only (although it's a rare
-      case), you can use the <constant>WRITE</constant> flag instead, and
-      you don't need the <structfield>get</structfield> callback.
-      </para>
-
-      <para>
-      If the control value changes frequently (e.g. the VU meter),
-      <constant>VOLATILE</constant> flag should be given.  This means
-      that the control may be changed without
-      <link linkend="control-interface-change-notification"><citetitle>
-      notification</citetitle></link>. Applications should poll such
-      a control constantly.
-      </para>
-
-      <para>
-      When the control is inactive, set
-      the <constant>INACTIVE</constant> flag, too.
-      There are <constant>LOCK</constant> and
-      <constant>OWNER</constant> flags to change the write
-      permissions.
-      </para>
-
-    </section>
-
-    <section id="control-interface-callbacks">
-      <title>Callbacks</title>
-
-      <section id="control-interface-callbacks-info">
-        <title>info callback</title>
-        <para>
-          The <structfield>info</structfield> callback is used to get
-        detailed information on this control. This must store the
-        values of the given struct <structname>snd_ctl_elem_info</structname>
-        object. For example, for a boolean control with a single
-        element: 
-
-          <example>
-	    <title>Example of info callback</title>
-            <programlisting>
-<![CDATA[
-  static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,
-                          struct snd_ctl_elem_info *uinfo)
-  {
-          uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-          uinfo->count = 1;
-          uinfo->value.integer.min = 0;
-          uinfo->value.integer.max = 1;
-          return 0;
-  }
-]]>
-            </programlisting>
-          </example>
-        </para>
-
-        <para>
-          The <structfield>type</structfield> field specifies the type
-        of the control. There are <constant>BOOLEAN</constant>,
-        <constant>INTEGER</constant>, <constant>ENUMERATED</constant>,
-        <constant>BYTES</constant>, <constant>IEC958</constant> and
-        <constant>INTEGER64</constant>. The
-        <structfield>count</structfield> field specifies the 
-        number of elements in this control. For example, a stereo
-        volume would have count = 2. The
-        <structfield>value</structfield> field is a union, and 
-        the values stored are depending on the type. The boolean and
-        integer types are identical. 
-        </para>
-
-        <para>
-          The enumerated type is a bit different from others.  You'll
-          need to set the string for the currently given item index. 
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
-                          struct snd_ctl_elem_info *uinfo)
-  {
-          static char *texts[4] = {
-                  "First", "Second", "Third", "Fourth"
-          };
-          uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-          uinfo->count = 1;
-          uinfo->value.enumerated.items = 4;
-          if (uinfo->value.enumerated.item > 3)
-                  uinfo->value.enumerated.item = 3;
-          strcpy(uinfo->value.enumerated.name,
-                 texts[uinfo->value.enumerated.item]);
-          return 0;
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-	  Some common info callbacks are available for your convenience:
-	<function>snd_ctl_boolean_mono_info()</function> and
-	<function>snd_ctl_boolean_stereo_info()</function>.
-	Obviously, the former is an info callback for a mono channel
-	boolean item, just like <function>snd_myctl_mono_info</function>
-	above, and the latter is for a stereo channel boolean item.
-	</para>
-
-      </section>
-
-      <section id="control-interface-callbacks-get">
-        <title>get callback</title>
-
-        <para>
-          This callback is used to read the current value of the
-        control and to return to user-space. 
-        </para>
-
-        <para>
-          For example,
-
-          <example>
-	    <title>Example of get callback</title>
-            <programlisting>
-<![CDATA[
-  static int snd_myctl_get(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-  {
-          struct mychip *chip = snd_kcontrol_chip(kcontrol);
-          ucontrol->value.integer.value[0] = get_some_value(chip);
-          return 0;
-  }
-]]>
-            </programlisting>
-          </example>
-        </para>
-
-        <para>
-	The <structfield>value</structfield> field depends on 
-        the type of control as well as on the info callback.  For example,
-	the sb driver uses this field to store the register offset,
-        the bit-shift and the bit-mask.  The
-        <structfield>private_value</structfield> field is set as follows:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  .private_value = reg | (shift << 16) | (mask << 24)
-]]>
-            </programlisting>
-          </informalexample>
-	and is retrieved in callbacks like
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
-                                    struct snd_ctl_elem_value *ucontrol)
-  {
-          int reg = kcontrol->private_value & 0xff;
-          int shift = (kcontrol->private_value >> 16) & 0xff;
-          int mask = (kcontrol->private_value >> 24) & 0xff;
-          ....
-  }
-]]>
-            </programlisting>
-          </informalexample>
-	</para>
-
-	<para>
-	In the <structfield>get</structfield> callback,
-	you have to fill all the elements if the
-        control has more than one elements,
-        i.e. <structfield>count</structfield> &gt; 1.
-	In the example above, we filled only one element
-        (<structfield>value.integer.value[0]</structfield>) since it's
-        assumed as <structfield>count</structfield> = 1.
-        </para>
-      </section>
-
-      <section id="control-interface-callbacks-put">
-        <title>put callback</title>
-
-        <para>
-          This callback is used to write a value from user-space.
-        </para>
-
-        <para>
-          For example,
-
-          <example>
-	    <title>Example of put callback</title>
-            <programlisting>
-<![CDATA[
-  static int snd_myctl_put(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-  {
-          struct mychip *chip = snd_kcontrol_chip(kcontrol);
-          int changed = 0;
-          if (chip->current_value !=
-               ucontrol->value.integer.value[0]) {
-                  change_current_value(chip,
-                              ucontrol->value.integer.value[0]);
-                  changed = 1;
-          }
-          return changed;
-  }
-]]>
-            </programlisting>
-          </example>
-
-          As seen above, you have to return 1 if the value is
-        changed. If the value is not changed, return 0 instead. 
-	If any fatal error happens, return a negative error code as
-        usual.
-        </para>
-
-        <para>
-	As in the <structfield>get</structfield> callback,
-	when the control has more than one elements,
-	all elements must be evaluated in this callback, too.
-        </para>
-      </section>
-
-      <section id="control-interface-callbacks-all">
-        <title>Callbacks are not atomic</title>
-        <para>
-          All these three callbacks are basically not atomic.
-        </para>
-      </section>
-    </section>
-
-    <section id="control-interface-constructor">
-      <title>Constructor</title>
-      <para>
-        When everything is ready, finally we can create a new
-      control. To create a control, there are two functions to be
-      called, <function>snd_ctl_new1()</function> and
-      <function>snd_ctl_add()</function>. 
-      </para>
-
-      <para>
-        In the simplest way, you can do like this:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
-  if (err < 0)
-          return err;
-]]>
-          </programlisting>
-        </informalexample>
-
-        where <parameter>my_control</parameter> is the
-      struct <structname>snd_kcontrol_new</structname> object defined above, and chip
-      is the object pointer to be passed to
-      kcontrol-&gt;private_data 
-      which can be referred to in callbacks. 
-      </para>
-
-      <para>
-        <function>snd_ctl_new1()</function> allocates a new
-      <structname>snd_kcontrol</structname> instance (that's why the definition
-      of <parameter>my_control</parameter> can be with
-      the <parameter>__devinitdata</parameter> 
-      prefix), and <function>snd_ctl_add</function> assigns the given
-      control component to the card. 
-      </para>
-    </section>
-
-    <section id="control-interface-change-notification">
-      <title>Change Notification</title>
-      <para>
-        If you need to change and update a control in the interrupt
-      routine, you can call <function>snd_ctl_notify()</function>. For
-      example, 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
-]]>
-          </programlisting>
-        </informalexample>
-
-        This function takes the card pointer, the event-mask, and the
-      control id pointer for the notification. The event-mask
-      specifies the types of notification, for example, in the above
-      example, the change of control values is notified.
-      The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
-      to be notified.
-      You can find some examples in <filename>es1938.c</filename> or
-      <filename>es1968.c</filename> for hardware volume interrupts. 
-      </para>
-    </section>
-
-    <section id="control-interface-tlv">
-      <title>Metadata</title>
-      <para>
-      To provide information about the dB values of a mixer control, use
-      on of the <constant>DECLARE_TLV_xxx</constant> macros from
-      <filename>&lt;sound/tlv.h&gt;</filename> to define a variable
-      containing this information, set the<structfield>tlv.p
-      </structfield> field to point to this variable, and include the
-      <constant>SNDRV_CTL_ELEM_ACCESS_TLV_READ</constant> flag in the
-      <structfield>access</structfield> field; like this:
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
-
-  static struct snd_kcontrol_new my_control __devinitdata = {
-          ...
-          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                    SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-          ...
-          .tlv.p = db_scale_my_control,
-  };
-]]>
-        </programlisting>
-      </informalexample>
-      </para>
-
-      <para>
-      The <function>DECLARE_TLV_DB_SCALE</function> macro defines
-      information about a mixer control where each step in the control's
-      value changes the dB value by a constant dB amount.
-      The first parameter is the name of the variable to be defined.
-      The second parameter is the minimum value, in units of 0.01 dB.
-      The third parameter is the step size, in units of 0.01 dB.
-      Set the fourth parameter to 1 if the minimum value actually mutes
-      the control.
-      </para>
-
-      <para>
-      The <function>DECLARE_TLV_DB_LINEAR</function> macro defines
-      information about a mixer control where the control's value affects
-      the output linearly.
-      The first parameter is the name of the variable to be defined.
-      The second parameter is the minimum value, in units of 0.01 dB.
-      The third parameter is the maximum value, in units of 0.01 dB.
-      If the minimum value mutes the control, set the second parameter to
-      <constant>TLV_DB_GAIN_MUTE</constant>.
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- API for AC97 Codec  -->
-<!-- ****************************************************** -->
-  <chapter id="api-ac97">
-    <title>API for AC97 Codec</title>
-
-    <section>
-      <title>General</title>
-      <para>
-        The ALSA AC97 codec layer is a well-defined one, and you don't
-      have to write much code to control it. Only low-level control
-      routines are necessary. The AC97 codec API is defined in
-      <filename>&lt;sound/ac97_codec.h&gt;</filename>. 
-      </para>
-    </section>
-
-    <section id="api-ac97-example">
-      <title>Full Code Example</title>
-      <para>
-          <example>
-	    <title>Example of AC97 Interface</title>
-            <programlisting>
-<![CDATA[
-  struct mychip {
-          ....
-          struct snd_ac97 *ac97;
-          ....
-  };
-
-  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
-                                             unsigned short reg)
-  {
-          struct mychip *chip = ac97->private_data;
-          ....
-          /* read a register value here from the codec */
-          return the_register_value;
-  }
-
-  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
-                                   unsigned short reg, unsigned short val)
-  {
-          struct mychip *chip = ac97->private_data;
-          ....
-          /* write the given register value to the codec */
-  }
-
-  static int snd_mychip_ac97(struct mychip *chip)
-  {
-          struct snd_ac97_bus *bus;
-          struct snd_ac97_template ac97;
-          int err;
-          static struct snd_ac97_bus_ops ops = {
-                  .write = snd_mychip_ac97_write,
-                  .read = snd_mychip_ac97_read,
-          };
-
-          err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
-          if (err < 0)
-                  return err;
-          memset(&ac97, 0, sizeof(ac97));
-          ac97.private_data = chip;
-          return snd_ac97_mixer(bus, &ac97, &chip->ac97);
-  }
-
-]]>
-          </programlisting>
-        </example>
-      </para>
-    </section>
-
-    <section id="api-ac97-constructor">
-      <title>Constructor</title>
-      <para>
-        To create an ac97 instance, first call <function>snd_ac97_bus</function>
-      with an <type>ac97_bus_ops_t</type> record with callback functions.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_ac97_bus *bus;
-  static struct snd_ac97_bus_ops ops = {
-        .write = snd_mychip_ac97_write,
-        .read = snd_mychip_ac97_read,
-  };
-
-  snd_ac97_bus(card, 0, &ops, NULL, &pbus);
-]]>
-          </programlisting>
-        </informalexample>
-
-      The bus record is shared among all belonging ac97 instances.
-      </para>
-
-      <para>
-      And then call <function>snd_ac97_mixer()</function> with an
-      struct <structname>snd_ac97_template</structname>
-      record together with the bus pointer created above.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_ac97_template ac97;
-  int err;
-
-  memset(&ac97, 0, sizeof(ac97));
-  ac97.private_data = chip;
-  snd_ac97_mixer(bus, &ac97, &chip->ac97);
-]]>
-          </programlisting>
-        </informalexample>
-
-        where chip-&gt;ac97 is a pointer to a newly created
-        <type>ac97_t</type> instance.
-        In this case, the chip pointer is set as the private data, so that
-        the read/write callback functions can refer to this chip instance.
-        This instance is not necessarily stored in the chip
-	record.  If you need to change the register values from the
-        driver, or need the suspend/resume of ac97 codecs, keep this
-        pointer to pass to the corresponding functions.
-      </para>
-    </section>
-
-    <section id="api-ac97-callbacks">
-      <title>Callbacks</title>
-      <para>
-        The standard callbacks are <structfield>read</structfield> and
-      <structfield>write</structfield>. Obviously they 
-      correspond to the functions for read and write accesses to the
-      hardware low-level codes. 
-      </para>
-
-      <para>
-        The <structfield>read</structfield> callback returns the
-        register value specified in the argument. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
-                                             unsigned short reg)
-  {
-          struct mychip *chip = ac97->private_data;
-          ....
-          return the_register_value;
-  }
-]]>
-          </programlisting>
-        </informalexample>
-
-        Here, the chip can be cast from ac97-&gt;private_data.
-      </para>
-
-      <para>
-        Meanwhile, the <structfield>write</structfield> callback is
-        used to set the register value. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
-                       unsigned short reg, unsigned short val)
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-      These callbacks are non-atomic like the control API callbacks.
-      </para>
-
-      <para>
-        There are also other callbacks:
-      <structfield>reset</structfield>,
-      <structfield>wait</structfield> and
-      <structfield>init</structfield>. 
-      </para>
-
-      <para>
-        The <structfield>reset</structfield> callback is used to reset
-      the codec. If the chip requires a special kind of reset, you can
-      define this callback. 
-      </para>
-
-      <para>
-        The <structfield>wait</structfield> callback is used to
-      add some waiting time in the standard initialization of the codec. If the
-      chip requires the extra waiting time, define this callback. 
-      </para>
-
-      <para>
-        The <structfield>init</structfield> callback is used for
-      additional initialization of the codec.
-      </para>
-    </section>
-
-    <section id="api-ac97-updating-registers">
-      <title>Updating Registers in The Driver</title>
-      <para>
-        If you need to access to the codec from the driver, you can
-      call the following functions:
-      <function>snd_ac97_write()</function>,
-      <function>snd_ac97_read()</function>,
-      <function>snd_ac97_update()</function> and
-      <function>snd_ac97_update_bits()</function>. 
-      </para>
-
-      <para>
-        Both <function>snd_ac97_write()</function> and
-        <function>snd_ac97_update()</function> functions are used to
-        set a value to the given register
-        (<constant>AC97_XXX</constant>). The difference between them is
-        that <function>snd_ac97_update()</function> doesn't write a
-        value if the given value has been already set, while
-        <function>snd_ac97_write()</function> always rewrites the
-        value. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_ac97_write(ac97, AC97_MASTER, 0x8080);
-  snd_ac97_update(ac97, AC97_MASTER, 0x8080);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        <function>snd_ac97_read()</function> is used to read the value
-        of the given register. For example, 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  value = snd_ac97_read(ac97, AC97_MASTER);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        <function>snd_ac97_update_bits()</function> is used to update
-        some bits in the given register.  
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_ac97_update_bits(ac97, reg, mask, value);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        Also, there is a function to change the sample rate (of a
-        given register such as
-        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or
-        DRA is supported by the codec:
-        <function>snd_ac97_set_rate()</function>. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The following registers are available to set the rate:
-      <constant>AC97_PCM_MIC_ADC_RATE</constant>,
-      <constant>AC97_PCM_FRONT_DAC_RATE</constant>,
-      <constant>AC97_PCM_LR_ADC_RATE</constant>,
-      <constant>AC97_SPDIF</constant>. When
-      <constant>AC97_SPDIF</constant> is specified, the register is
-      not really changed but the corresponding IEC958 status bits will
-      be updated. 
-      </para>
-    </section>
-
-    <section id="api-ac97-clock-adjustment">
-      <title>Clock Adjustment</title>
-      <para>
-        In some chips, the clock of the codec isn't 48000 but using a
-      PCI clock (to save a quartz!). In this case, change the field
-      bus-&gt;clock to the corresponding
-      value. For example, intel8x0 
-      and es1968 drivers have their own function to read from the clock.
-      </para>
-    </section>
-
-    <section id="api-ac97-proc-files">
-      <title>Proc Files</title>
-      <para>
-        The ALSA AC97 interface will create a proc file such as
-      <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
-      <filename>ac97#0-0+regs</filename>. You can refer to these files to
-      see the current status and registers of the codec. 
-      </para>
-    </section>
-
-    <section id="api-ac97-multiple-codecs">
-      <title>Multiple Codecs</title>
-      <para>
-        When there are several codecs on the same card, you need to
-      call <function>snd_ac97_mixer()</function> multiple times with
-      ac97.num=1 or greater. The <structfield>num</structfield> field
-      specifies the codec number. 
-      </para>
-
-      <para>
-        If you set up multiple codecs, you either need to write
-      different callbacks for each codec or check
-      ac97-&gt;num in the callback routines. 
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- MIDI (MPU401-UART) Interface  -->
-<!-- ****************************************************** -->
-  <chapter id="midi-interface">
-    <title>MIDI (MPU401-UART) Interface</title>
-
-    <section id="midi-interface-general">
-      <title>General</title>
-      <para>
-        Many soundcards have built-in MIDI (MPU401-UART)
-      interfaces. When the soundcard supports the standard MPU401-UART
-      interface, most likely you can use the ALSA MPU401-UART API. The
-      MPU401-UART API is defined in
-      <filename>&lt;sound/mpu401.h&gt;</filename>. 
-      </para>
-
-      <para>
-        Some soundchips have a similar but slightly different
-      implementation of mpu401 stuff. For example, emu10k1 has its own
-      mpu401 routines. 
-      </para>
-    </section>
-
-    <section id="midi-interface-constructor">
-      <title>Constructor</title>
-      <para>
-        To create a rawmidi object, call
-      <function>snd_mpu401_uart_new()</function>. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_rawmidi *rmidi;
-  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
-                      irq, irq_flags, &rmidi);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The first argument is the card pointer, and the second is the
-      index of this component. You can create up to 8 rawmidi
-      devices. 
-      </para>
-
-      <para>
-        The third argument is the type of the hardware,
-      <constant>MPU401_HW_XXX</constant>. If it's not a special one,
-      you can use <constant>MPU401_HW_MPU401</constant>. 
-      </para>
-
-      <para>
-        The 4th argument is the I/O port address. Many
-      backward-compatible MPU401 have an I/O port such as 0x330. Or, it
-      might be a part of its own PCI I/O region. It depends on the
-      chip design. 
-      </para>
-
-      <para>
-	The 5th argument is a bitflag for additional information.
-        When the I/O port address above is part of the PCI I/O
-      region, the MPU401 I/O port might have been already allocated
-      (reserved) by the driver itself. In such a case, pass a bit flag
-      <constant>MPU401_INFO_INTEGRATED</constant>,
-      and the mpu401-uart layer will allocate the I/O ports by itself. 
-      </para>
-
-	<para>
-	When the controller supports only the input or output MIDI stream,
-	pass the <constant>MPU401_INFO_INPUT</constant> or
-	<constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
-	Then the rawmidi instance is created as a single stream.
-	</para>
-
-	<para>
-	<constant>MPU401_INFO_MMIO</constant> bitflag is used to change
-	the access method to MMIO (via readb and writeb) instead of
-	iob and outb. In this case, you have to pass the iomapped address
-	to <function>snd_mpu401_uart_new()</function>.
-	</para>
-
-	<para>
-	When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
-	stream isn't checked in the default interrupt handler.  The driver
-	needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
-	by itself to start processing the output stream in the irq handler.
-	</para>
-
-      <para>
-        Usually, the port address corresponds to the command port and
-        port + 1 corresponds to the data port. If not, you may change
-        the <structfield>cport</structfield> field of
-        struct <structname>snd_mpu401</structname> manually 
-        afterward. However, <structname>snd_mpu401</structname> pointer is not
-        returned explicitly by
-        <function>snd_mpu401_uart_new()</function>. You need to cast
-        rmidi-&gt;private_data to
-        <structname>snd_mpu401</structname> explicitly, 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_mpu401 *mpu;
-  mpu = rmidi->private_data;
-]]>
-          </programlisting>
-        </informalexample>
-
-        and reset the cport as you like:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  mpu->cport = my_own_control_port;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The 6th argument specifies the irq number for UART. If the irq
-      is already allocated, pass 0 to the 7th argument
-      (<parameter>irq_flags</parameter>). Otherwise, pass the flags
-      for irq allocation 
-      (<constant>SA_XXX</constant> bits) to it, and the irq will be
-      reserved by the mpu401-uart layer. If the card doesn't generate
-      UART interrupts, pass -1 as the irq number. Then a timer
-      interrupt will be invoked for polling. 
-      </para>
-    </section>
-
-    <section id="midi-interface-interrupt-handler">
-      <title>Interrupt Handler</title>
-      <para>
-        When the interrupt is allocated in
-      <function>snd_mpu401_uart_new()</function>, the private
-      interrupt handler is used, hence you don't have anything else to do
-      than creating the mpu401 stuff. Otherwise, you have to call
-      <function>snd_mpu401_uart_interrupt()</function> explicitly when
-      a UART interrupt is invoked and checked in your own interrupt
-      handler.  
-      </para>
-
-      <para>
-        In this case, you need to pass the private_data of the
-        returned rawmidi object from
-        <function>snd_mpu401_uart_new()</function> as the second
-        argument of <function>snd_mpu401_uart_interrupt()</function>. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- RawMIDI Interface  -->
-<!-- ****************************************************** -->
-  <chapter id="rawmidi-interface">
-    <title>RawMIDI Interface</title>
-
-    <section id="rawmidi-interface-overview">
-      <title>Overview</title>
-
-      <para>
-      The raw MIDI interface is used for hardware MIDI ports that can
-      be accessed as a byte stream.  It is not used for synthesizer
-      chips that do not directly understand MIDI.
-      </para>
-
-      <para>
-      ALSA handles file and buffer management.  All you have to do is
-      to write some code to move data between the buffer and the
-      hardware.
-      </para>
-
-      <para>
-      The rawmidi API is defined in
-      <filename>&lt;sound/rawmidi.h&gt;</filename>.
-      </para>
-    </section>
-
-    <section id="rawmidi-interface-constructor">
-      <title>Constructor</title>
-
-      <para>
-      To create a rawmidi device, call the
-      <function>snd_rawmidi_new</function> function:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_rawmidi *rmidi;
-  err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
-  if (err < 0)
-          return err;
-  rmidi->private_data = chip;
-  strcpy(rmidi->name, "My MIDI");
-  rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
-                      SNDRV_RAWMIDI_INFO_INPUT |
-                      SNDRV_RAWMIDI_INFO_DUPLEX;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-      The first argument is the card pointer, the second argument is
-      the ID string.
-      </para>
-
-      <para>
-      The third argument is the index of this component.  You can
-      create up to 8 rawmidi devices.
-      </para>
-
-      <para>
-      The fourth and fifth arguments are the number of output and
-      input substreams, respectively, of this device (a substream is
-      the equivalent of a MIDI port).
-      </para>
-
-      <para>
-      Set the <structfield>info_flags</structfield> field to specify
-      the capabilities of the device.
-      Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is
-      at least one output port,
-      <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at
-      least one input port,
-      and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device
-      can handle output and input at the same time.
-      </para>
-
-      <para>
-      After the rawmidi device is created, you need to set the
-      operators (callbacks) for each substream.  There are helper
-      functions to set the operators for all the substreams of a device:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
-  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-      The operators are usually defined like this:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
-          .open =    snd_mymidi_output_open,
-          .close =   snd_mymidi_output_close,
-          .trigger = snd_mymidi_output_trigger,
-  };
-]]>
-          </programlisting>
-        </informalexample>
-      These callbacks are explained in the <link
-      linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link>
-      section.
-      </para>
-
-      <para>
-      If there are more than one substream, you should give a
-      unique name to each of them:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_rawmidi_substream *substream;
-  list_for_each_entry(substream,
-                      &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
-                      list {
-          sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
-  }
-  /* same for SNDRV_RAWMIDI_STREAM_INPUT */
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-    </section>
-
-    <section id="rawmidi-interface-callbacks">
-      <title>Callbacks</title>
-
-      <para>
-      In all the callbacks, the private data that you've set for the
-      rawmidi device can be accessed as
-      substream-&gt;rmidi-&gt;private_data.
-      <!-- <code> isn't available before DocBook 4.3 -->
-      </para>
-
-      <para>
-      If there is more than one port, your callbacks can determine the
-      port index from the struct snd_rawmidi_substream data passed to each
-      callback:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_rawmidi_substream *substream;
-  int index = substream->number;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <section id="rawmidi-interface-op-open">
-      <title><function>open</function> callback</title>
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int snd_xxx_open(struct snd_rawmidi_substream *substream);
-]]>
-          </programlisting>
-        </informalexample>
-
-        <para>
-        This is called when a substream is opened.
-        You can initialize the hardware here, but you shouldn't
-        start transmitting/receiving data yet.
-        </para>
-      </section>
-
-      <section id="rawmidi-interface-op-close">
-      <title><function>close</function> callback</title>
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int snd_xxx_close(struct snd_rawmidi_substream *substream);
-]]>
-          </programlisting>
-        </informalexample>
-
-        <para>
-        Guess what.
-        </para>
-
-        <para>
-        The <function>open</function> and <function>close</function>
-        callbacks of a rawmidi device are serialized with a mutex,
-        and can sleep.
-        </para>
-      </section>
-
-      <section id="rawmidi-interface-op-trigger-out">
-      <title><function>trigger</function> callback for output
-      substreams</title>
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
-]]>
-          </programlisting>
-        </informalexample>
-
-        <para>
-        This is called with a nonzero <parameter>up</parameter>
-        parameter when there is some data in the substream buffer that
-        must be transmitted.
-        </para>
-
-        <para>
-        To read data from the buffer, call
-        <function>snd_rawmidi_transmit_peek</function>.  It will
-        return the number of bytes that have been read; this will be
-        less than the number of bytes requested when there are no more
-        data in the buffer.
-        After the data have been transmitted successfully, call
-        <function>snd_rawmidi_transmit_ack</function> to remove the
-        data from the substream buffer:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  unsigned char data;
-  while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
-          if (snd_mychip_try_to_transmit(data))
-                  snd_rawmidi_transmit_ack(substream, 1);
-          else
-                  break; /* hardware FIFO full */
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-        If you know beforehand that the hardware will accept data, you
-        can use the <function>snd_rawmidi_transmit</function> function
-        which reads some data and removes them from the buffer at once:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  while (snd_mychip_transmit_possible()) {
-          unsigned char data;
-          if (snd_rawmidi_transmit(substream, &data, 1) != 1)
-                  break; /* no more data */
-          snd_mychip_transmit(data);
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-
-        <para>
-        If you know beforehand how many bytes you can accept, you can
-        use a buffer size greater than one with the
-        <function>snd_rawmidi_transmit*</function> functions.
-        </para>
-
-        <para>
-        The <function>trigger</function> callback must not sleep.  If
-        the hardware FIFO is full before the substream buffer has been
-        emptied, you have to continue transmitting data later, either
-        in an interrupt handler, or with a timer if the hardware
-        doesn't have a MIDI transmit interrupt.
-        </para>
-
-        <para>
-        The <function>trigger</function> callback is called with a
-        zero <parameter>up</parameter> parameter when the transmission
-        of data should be aborted.
-        </para>
-      </section>
-
-      <section id="rawmidi-interface-op-trigger-in">
-      <title><function>trigger</function> callback for input
-      substreams</title>
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
-]]>
-          </programlisting>
-        </informalexample>
-
-        <para>
-        This is called with a nonzero <parameter>up</parameter>
-        parameter to enable receiving data, or with a zero
-        <parameter>up</parameter> parameter do disable receiving data.
-        </para>
-
-        <para>
-        The <function>trigger</function> callback must not sleep; the
-        actual reading of data from the device is usually done in an
-        interrupt handler.
-        </para>
-
-        <para>
-        When data reception is enabled, your interrupt handler should
-        call <function>snd_rawmidi_receive</function> for all received
-        data:
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  void snd_mychip_midi_interrupt(...)
-  {
-          while (mychip_midi_available()) {
-                  unsigned char data;
-                  data = mychip_midi_read();
-                  snd_rawmidi_receive(substream, &data, 1);
-          }
-  }
-]]>
-            </programlisting>
-          </informalexample>
-        </para>
-      </section>
-
-      <section id="rawmidi-interface-op-drain">
-      <title><function>drain</function> callback</title>
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
-]]>
-          </programlisting>
-        </informalexample>
-
-        <para>
-        This is only used with output substreams.  This function should wait
-        until all data read from the substream buffer have been transmitted.
-        This ensures that the device can be closed and the driver unloaded
-        without losing data.
-        </para>
-
-        <para>
-        This callback is optional. If you do not set
-        <structfield>drain</structfield> in the struct snd_rawmidi_ops
-        structure, ALSA will simply wait for 50&nbsp;milliseconds
-        instead.
-        </para>
-      </section>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Miscellaneous Devices  -->
-<!-- ****************************************************** -->
-  <chapter id="misc-devices">
-    <title>Miscellaneous Devices</title>
-
-    <section id="misc-devices-opl3">
-      <title>FM OPL3</title>
-      <para>
-        The FM OPL3 is still used in many chips (mainly for backward
-      compatibility). ALSA has a nice OPL3 FM control layer, too. The
-      OPL3 API is defined in
-      <filename>&lt;sound/opl3.h&gt;</filename>. 
-      </para>
-
-      <para>
-        FM registers can be directly accessed through the direct-FM API,
-      defined in <filename>&lt;sound/asound_fm.h&gt;</filename>. In
-      ALSA native mode, FM registers are accessed through
-      the Hardware-Dependant Device direct-FM extension API, whereas in
-      OSS compatible mode, FM registers can be accessed with the OSS
-      direct-FM compatible API in <filename>/dev/dmfmX</filename> device. 
-      </para>
-
-      <para>
-        To create the OPL3 component, you have two functions to
-        call. The first one is a constructor for the <type>opl3_t</type>
-        instance. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_opl3 *opl3;
-  snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
-                  integrated, &opl3);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The first argument is the card pointer, the second one is the
-      left port address, and the third is the right port address. In
-      most cases, the right port is placed at the left port + 2. 
-      </para>
-
-      <para>
-        The fourth argument is the hardware type.
-      </para>
-
-      <para>
-        When the left and right ports have been already allocated by
-      the card driver, pass non-zero to the fifth argument
-      (<parameter>integrated</parameter>). Otherwise, the opl3 module will
-      allocate the specified ports by itself. 
-      </para>
-
-      <para>
-        When the accessing the hardware requires special method
-        instead of the standard I/O access, you can create opl3 instance
-        separately with <function>snd_opl3_new()</function>.
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_opl3 *opl3;
-  snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-	Then set <structfield>command</structfield>,
-	<structfield>private_data</structfield> and
-	<structfield>private_free</structfield> for the private
-	access function, the private data and the destructor.
-	The l_port and r_port are not necessarily set.  Only the
-	command must be set properly.  You can retrieve the data
-	from the opl3-&gt;private_data field.
-      </para>
-
-      <para>
-	After creating the opl3 instance via <function>snd_opl3_new()</function>,
-	call <function>snd_opl3_init()</function> to initialize the chip to the
-	proper state. Note that <function>snd_opl3_create()</function> always
-	calls it internally.
-      </para>
-
-      <para>
-        If the opl3 instance is created successfully, then create a
-        hwdep device for this opl3. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_hwdep *opl3hwdep;
-  snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The first argument is the <type>opl3_t</type> instance you
-      created, and the second is the index number, usually 0. 
-      </para>
-
-      <para>
-        The third argument is the index-offset for the sequencer
-      client assigned to the OPL3 port. When there is an MPU401-UART,
-      give 1 for here (UART always takes 0). 
-      </para>
-    </section>
-
-    <section id="misc-devices-hardware-dependent">
-      <title>Hardware-Dependent Devices</title>
-      <para>
-        Some chips need user-space access for special
-      controls or for loading the micro code. In such a case, you can
-      create a hwdep (hardware-dependent) device. The hwdep API is
-      defined in <filename>&lt;sound/hwdep.h&gt;</filename>. You can
-      find examples in opl3 driver or
-      <filename>isa/sb/sb16_csp.c</filename>. 
-      </para>
-
-      <para>
-        The creation of the <type>hwdep</type> instance is done via
-        <function>snd_hwdep_new()</function>. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_hwdep *hw;
-  snd_hwdep_new(card, "My HWDEP", 0, &hw);
-]]>
-          </programlisting>
-        </informalexample>
-
-        where the third argument is the index number.
-      </para>
-
-      <para>
-        You can then pass any pointer value to the
-        <parameter>private_data</parameter>.
-        If you assign a private data, you should define the
-        destructor, too. The destructor function is set in
-        the <structfield>private_free</structfield> field.  
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
-  hw->private_data = p;
-  hw->private_free = mydata_free;
-]]>
-          </programlisting>
-        </informalexample>
-
-        and the implementation of the destructor would be:
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static void mydata_free(struct snd_hwdep *hw)
-  {
-          struct mydata *p = hw->private_data;
-          kfree(p);
-  }
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The arbitrary file operations can be defined for this
-        instance. The file operators are defined in
-        the <parameter>ops</parameter> table. For example, assume that
-        this chip needs an ioctl. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  hw->ops.open = mydata_open;
-  hw->ops.ioctl = mydata_ioctl;
-  hw->ops.release = mydata_release;
-]]>
-          </programlisting>
-        </informalexample>
-
-        And implement the callback functions as you like.
-      </para>
-    </section>
-
-    <section id="misc-devices-IEC958">
-      <title>IEC958 (S/PDIF)</title>
-      <para>
-        Usually the controls for IEC958 devices are implemented via
-      the control interface. There is a macro to compose a name string for
-      IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function>
-      defined in <filename>&lt;include/asound.h&gt;</filename>.  
-      </para>
-
-      <para>
-        There are some standard controls for IEC958 status bits. These
-      controls use the type <type>SNDRV_CTL_ELEM_TYPE_IEC958</type>,
-      and the size of element is fixed as 4 bytes array
-      (value.iec958.status[x]). For the <structfield>info</structfield>
-      callback, you don't specify 
-      the value field for this type (the count field must be set,
-      though). 
-      </para>
-
-      <para>
-        <quote>IEC958 Playback Con Mask</quote> is used to return the
-      bit-mask for the IEC958 status bits of consumer mode. Similarly,
-      <quote>IEC958 Playback Pro Mask</quote> returns the bitmask for
-      professional mode. They are read-only controls, and are defined
-      as MIXER controls (iface =
-      <constant>SNDRV_CTL_ELEM_IFACE_MIXER</constant>).  
-      </para>
-
-      <para>
-        Meanwhile, <quote>IEC958 Playback Default</quote> control is
-      defined for getting and setting the current default IEC958
-      bits. Note that this one is usually defined as a PCM control
-      (iface = <constant>SNDRV_CTL_ELEM_IFACE_PCM</constant>),
-      although in some places it's defined as a MIXER control. 
-      </para>
-
-      <para>
-        In addition, you can define the control switches to
-      enable/disable or to set the raw bit mode. The implementation
-      will depend on the chip, but the control should be named as
-      <quote>IEC958 xxx</quote>, preferably using
-      the <function>SNDRV_CTL_NAME_IEC958()</function> macro. 
-      </para>
-
-      <para>
-        You can find several cases, for example,
-      <filename>pci/emu10k1</filename>,
-      <filename>pci/ice1712</filename>, or
-      <filename>pci/cmipci.c</filename>.  
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Buffer and Memory Management  -->
-<!-- ****************************************************** -->
-  <chapter id="buffer-and-memory">
-    <title>Buffer and Memory Management</title>
-
-    <section id="buffer-and-memory-buffer-types">
-      <title>Buffer Types</title>
-      <para>
-        ALSA provides several different buffer allocation functions
-      depending on the bus and the architecture. All these have a
-      consistent API. The allocation of physically-contiguous pages is
-      done via 
-      <function>snd_malloc_xxx_pages()</function> function, where xxx
-      is the bus type. 
-      </para>
-
-      <para>
-        The allocation of pages with fallback is
-      <function>snd_malloc_xxx_pages_fallback()</function>. This
-      function tries to allocate the specified pages but if the pages
-      are not available, it tries to reduce the page sizes until
-      enough space is found.
-      </para>
-
-      <para>
-      The release the pages, call
-      <function>snd_free_xxx_pages()</function> function. 
-      </para>
-
-      <para>
-      Usually, ALSA drivers try to allocate and reserve
-       a large contiguous physical space
-       at the time the module is loaded for the later use.
-       This is called <quote>pre-allocation</quote>.
-       As already written, you can call the following function at 
-       pcm instance construction time (in the case of PCI bus). 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                        snd_dma_pci_data(pci), size, max);
-]]>
-          </programlisting>
-        </informalexample>
-
-        where <parameter>size</parameter> is the byte size to be
-      pre-allocated and the <parameter>max</parameter> is the maximum
-      size to be changed via the <filename>prealloc</filename> proc file.
-      The allocator will try to get an area as large as possible
-      within the given size. 
-      </para>
-
-      <para>
-      The second argument (type) and the third argument (device pointer)
-      are dependent on the bus.
-      In the case of the ISA bus, pass <function>snd_dma_isa_data()</function>
-      as the third argument with <constant>SNDRV_DMA_TYPE_DEV</constant> type.
-      For the continuous buffer unrelated to the bus can be pre-allocated
-      with <constant>SNDRV_DMA_TYPE_CONTINUOUS</constant> type and the
-      <function>snd_dma_continuous_data(GFP_KERNEL)</function> device pointer,
-      where <constant>GFP_KERNEL</constant> is the kernel allocation flag to
-      use.
-      For the PCI scatter-gather buffers, use
-      <constant>SNDRV_DMA_TYPE_DEV_SG</constant> with
-      <function>snd_dma_pci_data(pci)</function>
-      (see the 
-          <link linkend="buffer-and-memory-non-contiguous"><citetitle>Non-Contiguous Buffers
-          </citetitle></link> section).
-      </para>
-
-      <para>
-        Once the buffer is pre-allocated, you can use the
-        allocator in the <structfield>hw_params</structfield> callback: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_pcm_lib_malloc_pages(substream, size);
-]]>
-          </programlisting>
-        </informalexample>
-
-        Note that you have to pre-allocate to use this function.
-      </para>
-    </section>
-
-    <section id="buffer-and-memory-external-hardware">
-      <title>External Hardware Buffers</title>
-      <para>
-        Some chips have their own hardware buffers and the DMA
-      transfer from the host memory is not available. In such a case,
-      you need to either 1) copy/set the audio data directly to the
-      external hardware buffer, or 2) make an intermediate buffer and
-      copy/set the data from it to the external hardware buffer in
-      interrupts (or in tasklets, preferably).
-      </para>
-
-      <para>
-        The first case works fine if the external hardware buffer is large
-      enough.  This method doesn't need any extra buffers and thus is
-      more effective. You need to define the
-      <structfield>copy</structfield> and
-      <structfield>silence</structfield> callbacks for 
-      the data transfer. However, there is a drawback: it cannot
-      be mmapped. The examples are GUS's GF1 PCM or emu8000's
-      wavetable PCM. 
-      </para>
-
-      <para>
-        The second case allows for mmap on the buffer, although you have
-      to handle an interrupt or a tasklet to transfer the data
-      from the intermediate buffer to the hardware buffer. You can find an
-      example in the vxpocket driver. 
-      </para>
-
-      <para>
-        Another case is when the chip uses a PCI memory-map
-      region for the buffer instead of the host memory. In this case,
-      mmap is available only on certain architectures like the Intel one.
-      In non-mmap mode, the data cannot be transferred as in the normal
-      way. Thus you need to define the <structfield>copy</structfield> and
-      <structfield>silence</structfield> callbacks as well, 
-      as in the cases above. The examples are found in
-      <filename>rme32.c</filename> and <filename>rme96.c</filename>. 
-      </para>
-
-      <para>
-        The implementation of the <structfield>copy</structfield> and
-        <structfield>silence</structfield> callbacks depends upon 
-        whether the hardware supports interleaved or non-interleaved
-        samples. The <structfield>copy</structfield> callback is
-        defined like below, a bit 
-        differently depending whether the direction is playback or
-        capture: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int playback_copy(struct snd_pcm_substream *substream, int channel,
-               snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
-  static int capture_copy(struct snd_pcm_substream *substream, int channel,
-               snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        In the case of interleaved samples, the second argument
-      (<parameter>channel</parameter>) is not used. The third argument
-      (<parameter>pos</parameter>) points the 
-      current position offset in frames. 
-      </para>
-
-      <para>
-        The meaning of the fourth argument is different between
-      playback and capture. For playback, it holds the source data
-      pointer, and for capture, it's the destination data pointer. 
-      </para>
-
-      <para>
-        The last argument is the number of frames to be copied.
-      </para>
-
-      <para>
-        What you have to do in this callback is again different
-        between playback and capture directions. In the
-        playback case, you copy the given amount of data
-        (<parameter>count</parameter>) at the specified pointer
-        (<parameter>src</parameter>) to the specified offset
-        (<parameter>pos</parameter>) on the hardware buffer. When
-        coded like memcpy-like way, the copy would be like: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src,
-            frames_to_bytes(runtime, count));
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        For the capture direction, you copy the given amount of
-        data (<parameter>count</parameter>) at the specified offset
-        (<parameter>pos</parameter>) on the hardware buffer to the
-        specified pointer (<parameter>dst</parameter>). 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos),
-            frames_to_bytes(runtime, count));
-]]>
-          </programlisting>
-        </informalexample>
-
-        Note that both the position and the amount of data are given
-      in frames. 
-      </para>
-
-      <para>
-        In the case of non-interleaved samples, the implementation
-      will be a bit more complicated. 
-      </para>
-
-      <para>
-        You need to check the channel argument, and if it's -1, copy
-      the whole channels. Otherwise, you have to copy only the
-      specified channel. Please check
-      <filename>isa/gus/gus_pcm.c</filename> as an example. 
-      </para>
-
-      <para>
-        The <structfield>silence</structfield> callback is also
-        implemented in a similar way. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  static int silence(struct snd_pcm_substream *substream, int channel,
-                     snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        The meanings of arguments are the same as in the
-      <structfield>copy</structfield> 
-      callback, although there is no <parameter>src/dst</parameter>
-      argument. In the case of interleaved samples, the channel
-      argument has no meaning, as well as on
-      <structfield>copy</structfield> callback.  
-      </para>
-
-      <para>
-        The role of <structfield>silence</structfield> callback is to
-        set the given amount 
-        (<parameter>count</parameter>) of silence data at the
-        specified offset (<parameter>pos</parameter>) on the hardware
-        buffer. Suppose that the data format is signed (that is, the
-        silent-data is 0), and the implementation using a memset-like
-        function would be like: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0,
-            frames_to_bytes(runtime, count));
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        In the case of non-interleaved samples, again, the
-      implementation becomes a bit more complicated. See, for example,
-      <filename>isa/gus/gus_pcm.c</filename>. 
-      </para>
-    </section>
-
-    <section id="buffer-and-memory-non-contiguous">
-      <title>Non-Contiguous Buffers</title>
-      <para>
-        If your hardware supports the page table as in emu10k1 or the
-      buffer descriptors as in via82xx, you can use the scatter-gather
-      (SG) DMA. ALSA provides an interface for handling SG-buffers.
-      The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>. 
-      </para>
-
-      <para>
-        For creating the SG-buffer handler, call
-        <function>snd_pcm_lib_preallocate_pages()</function> or
-        <function>snd_pcm_lib_preallocate_pages_for_all()</function>
-        with <constant>SNDRV_DMA_TYPE_DEV_SG</constant>
-	in the PCM constructor like other PCI pre-allocator.
-        You need to pass <function>snd_dma_pci_data(pci)</function>,
-        where pci is the struct <structname>pci_dev</structname> pointer
-        of the chip as well.
-        The <type>struct snd_sg_buf</type> instance is created as
-        substream-&gt;dma_private. You can cast
-        the pointer like: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        Then call <function>snd_pcm_lib_malloc_pages()</function>
-      in the <structfield>hw_params</structfield> callback
-      as well as in the case of normal PCI buffer.
-      The SG-buffer handler will allocate the non-contiguous kernel
-      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.
-      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>. 
-      </para>
-
-      <para>
-        When a SG-handler is used, you need to set
-      <function>snd_pcm_sgbuf_ops_page</function> as
-      the <structfield>page</structfield> callback.
-      (See <link linkend="pcm-interface-operators-page-callback">
-      <citetitle>page callback section</citetitle></link>.)
-      </para>
-
-      <para>
-        To release the data, call
-      <function>snd_pcm_lib_free_pages()</function> in the
-      <structfield>hw_free</structfield> callback as usual.
-      </para>
-    </section>
-
-    <section id="buffer-and-memory-vmalloced">
-      <title>Vmalloc'ed Buffers</title>
-      <para>
-        It's possible to use a buffer allocated via
-      <function>vmalloc</function>, for example, for an intermediate
-      buffer. Since the allocated pages are not contiguous, you need
-      to set the <structfield>page</structfield> callback to obtain
-      the physical address at every offset. 
-      </para>
-
-      <para>
-        The implementation of <structfield>page</structfield> callback
-        would be like this: 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  #include <linux/vmalloc.h>
-
-  /* get the physical page pointer on the given offset */
-  static struct page *mychip_page(struct snd_pcm_substream *substream,
-                                  unsigned long offset)
-  {
-          void *pageptr = substream->runtime->dma_area + offset;
-          return vmalloc_to_page(pageptr);
-  }
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Proc Interface  -->
-<!-- ****************************************************** -->
-  <chapter id="proc-interface">
-    <title>Proc Interface</title>
-    <para>
-      ALSA provides an easy interface for procfs. The proc files are
-      very useful for debugging. I recommend you set up proc files if
-      you write a driver and want to get a running status or register
-      dumps. The API is found in
-      <filename>&lt;sound/info.h&gt;</filename>. 
-    </para>
-
-    <para>
-      To create a proc file, call
-      <function>snd_card_proc_new()</function>. 
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  struct snd_info_entry *entry;
-  int err = snd_card_proc_new(card, "my-file", &entry);
-]]>
-        </programlisting>
-      </informalexample>
-
-      where the second argument specifies the name of the proc file to be
-    created. The above example will create a file
-    <filename>my-file</filename> under the card directory,
-    e.g. <filename>/proc/asound/card0/my-file</filename>. 
-    </para>
-
-    <para>
-    Like other components, the proc entry created via
-    <function>snd_card_proc_new()</function> will be registered and
-    released automatically in the card registration and release
-    functions.
-    </para>
-
-    <para>
-      When the creation is successful, the function stores a new
-    instance in the pointer given in the third argument.
-    It is initialized as a text proc file for read only.  To use
-    this proc file as a read-only text file as it is, set the read
-    callback with a private data via 
-     <function>snd_info_set_text_ops()</function>.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  snd_info_set_text_ops(entry, chip, my_proc_read);
-]]>
-        </programlisting>
-      </informalexample>
-    
-    where the second argument (<parameter>chip</parameter>) is the
-    private data to be used in the callbacks. The third parameter
-    specifies the read buffer size and the fourth
-    (<parameter>my_proc_read</parameter>) is the callback function, which
-    is defined like
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static void my_proc_read(struct snd_info_entry *entry,
-                           struct snd_info_buffer *buffer);
-]]>
-        </programlisting>
-      </informalexample>
-    
-    </para>
-
-    <para>
-    In the read callback, use <function>snd_iprintf()</function> for
-    output strings, which works just like normal
-    <function>printf()</function>.  For example,
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static void my_proc_read(struct snd_info_entry *entry,
-                           struct snd_info_buffer *buffer)
-  {
-          struct my_chip *chip = entry->private_data;
-
-          snd_iprintf(buffer, "This is my chip!\n");
-          snd_iprintf(buffer, "Port = %ld\n", chip->port);
-  }
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-    The file permissions can be changed afterwards.  As default, it's
-    set as read only for all users.  If you want to add write
-    permission for the user (root as default), do as follows:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-]]>
-        </programlisting>
-      </informalexample>
-
-    and set the write buffer size and the callback
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  entry->c.text.write = my_proc_write;
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-      For the write callback, you can use
-    <function>snd_info_get_line()</function> to get a text line, and
-    <function>snd_info_get_str()</function> to retrieve a string from
-    the line. Some examples are found in
-    <filename>core/oss/mixer_oss.c</filename>, core/oss/and
-    <filename>pcm_oss.c</filename>. 
-    </para>
-
-    <para>
-      For a raw-data proc-file, set the attributes as follows:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static struct snd_info_entry_ops my_file_io_ops = {
-          .read = my_file_io_read,
-  };
-
-  entry->content = SNDRV_INFO_CONTENT_DATA;
-  entry->private_data = chip;
-  entry->c.ops = &my_file_io_ops;
-  entry->size = 4096;
-  entry->mode = S_IFREG | S_IRUGO;
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-      The callback is much more complicated than the text-file
-      version. You need to use a low-level I/O functions such as
-      <function>copy_from/to_user()</function> to transfer the
-      data.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static long my_file_io_read(struct snd_info_entry *entry,
-                              void *file_private_data,
-                              struct file *file,
-                              char *buf,
-                              unsigned long count,
-                              unsigned long pos)
-  {
-          long size = count;
-          if (pos + size > local_max_size)
-                  size = local_max_size - pos;
-          if (copy_to_user(buf, local_data + pos, size))
-                  return -EFAULT;
-          return size;
-  }
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Power Management  -->
-<!-- ****************************************************** -->
-  <chapter id="power-management">
-    <title>Power Management</title>
-    <para>
-      If the chip is supposed to work with suspend/resume
-      functions, you need to add power-management code to the
-      driver. The additional code for power-management should be
-      <function>ifdef</function>'ed with
-      <constant>CONFIG_PM</constant>. 
-    </para>
-
-	<para>
-	If the driver <emphasis>fully</emphasis> supports suspend/resume
-	that is, the device can be
-	properly resumed to its state when suspend was called,
-	you can set the <constant>SNDRV_PCM_INFO_RESUME</constant> flag
-	in the pcm info field.  Usually, this is possible when the
-	registers of the chip can be safely saved and restored to
-	RAM. If this is set, the trigger callback is called with
-	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> after the resume
-	callback completes. 
-	</para>
-
-	<para>
-	Even if the driver doesn't support PM fully but 
-	partial suspend/resume is still possible, it's still worthy to
-	implement suspend/resume callbacks. In such a case, applications
-	would reset the status by calling
-	<function>snd_pcm_prepare()</function> and restart the stream
-	appropriately.  Hence, you can define suspend/resume callbacks
-	below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
-	info flag to the PCM.
-	</para>
-	
-	<para>
-	Note that the trigger with SUSPEND can always be called when
-	<function>snd_pcm_suspend_all</function> is called,
-	regardless of the <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
-	The <constant>RESUME</constant> flag affects only the behavior
-	of <function>snd_pcm_resume()</function>.
-	(Thus, in theory,
-	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
-	to be handled in the trigger callback when no
-	<constant>SNDRV_PCM_INFO_RESUME</constant> flag is set.  But,
-	it's better to keep it for compatibility reasons.)
-	</para>
-    <para>
-      In the earlier version of ALSA drivers, a common
-      power-management layer was provided, but it has been removed.
-      The driver needs to define the suspend/resume hooks according to
-      the bus the device is connected to.  In the case of PCI drivers, the
-      callbacks look like below:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  #ifdef CONFIG_PM
-  static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
-  {
-          .... /* do things for suspend */
-          return 0;
-  }
-  static int snd_my_resume(struct pci_dev *pci)
-  {
-          .... /* do things for suspend */
-          return 0;
-  }
-  #endif
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-      The scheme of the real suspend job is as follows.
-
-      <orderedlist>
-        <listitem><para>Retrieve the card and the chip data.</para></listitem>
-        <listitem><para>Call <function>snd_power_change_state()</function> with
-	  <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
-	  power status.</para></listitem>
-        <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
-	<listitem><para>If AC97 codecs are used, call
-	<function>snd_ac97_suspend()</function> for each codec.</para></listitem>
-        <listitem><para>Save the register values if necessary.</para></listitem>
-        <listitem><para>Stop the hardware if necessary.</para></listitem>
-        <listitem><para>Disable the PCI device by calling
-	  <function>pci_disable_device()</function>.  Then, call
-          <function>pci_save_state()</function> at last.</para></listitem>
-      </orderedlist>
-    </para>
-
-    <para>
-      A typical code would be like:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
-  {
-          /* (1) */
-          struct snd_card *card = pci_get_drvdata(pci);
-          struct mychip *chip = card->private_data;
-          /* (2) */
-          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-          /* (3) */
-          snd_pcm_suspend_all(chip->pcm);
-          /* (4) */
-          snd_ac97_suspend(chip->ac97);
-          /* (5) */
-          snd_mychip_save_registers(chip);
-          /* (6) */
-          snd_mychip_stop_hardware(chip);
-          /* (7) */
-          pci_disable_device(pci);
-          pci_save_state(pci);
-          return 0;
-  }
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-    The scheme of the real resume job is as follows.
-
-    <orderedlist>
-    <listitem><para>Retrieve the card and the chip data.</para></listitem>
-    <listitem><para>Set up PCI. First, call <function>pci_restore_state()</function>.
-    	Then enable the pci device again by calling <function>pci_enable_device()</function>.
-	Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
-    <listitem><para>Re-initialize the chip.</para></listitem>
-    <listitem><para>Restore the saved registers if necessary.</para></listitem>
-    <listitem><para>Resume the mixer, e.g. calling
-    <function>snd_ac97_resume()</function>.</para></listitem>
-    <listitem><para>Restart the hardware (if any).</para></listitem>
-    <listitem><para>Call <function>snd_power_change_state()</function> with
-	<constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
-    </orderedlist>
-    </para>
-
-    <para>
-    A typical code would be like:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static int mychip_resume(struct pci_dev *pci)
-  {
-          /* (1) */
-          struct snd_card *card = pci_get_drvdata(pci);
-          struct mychip *chip = card->private_data;
-          /* (2) */
-          pci_restore_state(pci);
-          pci_enable_device(pci);
-          pci_set_master(pci);
-          /* (3) */
-          snd_mychip_reinit_chip(chip);
-          /* (4) */
-          snd_mychip_restore_registers(chip);
-          /* (5) */
-          snd_ac97_resume(chip->ac97);
-          /* (6) */
-          snd_mychip_restart_chip(chip);
-          /* (7) */
-          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-          return 0;
-  }
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-	As shown in the above, it's better to save registers after
-	suspending the PCM operations via
-	<function>snd_pcm_suspend_all()</function> or
-	<function>snd_pcm_suspend()</function>.  It means that the PCM
-	streams are already stoppped when the register snapshot is
-	taken.  But, remember that you don't have to restart the PCM
-	stream in the resume callback. It'll be restarted via 
-	trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
-	when necessary.
-    </para>
-
-    <para>
-      OK, we have all callbacks now. Let's set them up. In the
-      initialization of the card, make sure that you can get the chip
-      data from the card instance, typically via
-      <structfield>private_data</structfield> field, in case you
-      created the chip data individually.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
-  {
-          ....
-          struct snd_card *card;
-          struct mychip *chip;
-          ....
-          card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
-          ....
-          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-          ....
-          card->private_data = chip;
-          ....
-  }
-]]>
-        </programlisting>
-      </informalexample>
-
-	When you created the chip data with
-	<function>snd_card_new()</function>, it's anyway accessible
-	via <structfield>private_data</structfield> field.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
-  {
-          ....
-          struct snd_card *card;
-          struct mychip *chip;
-          ....
-          card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-                              sizeof(struct mychip));
-          ....
-          chip = card->private_data;
-          ....
-  }
-]]>
-        </programlisting>
-      </informalexample>
-
-    </para>
-
-    <para>
-      If you need a space to save the registers, allocate the
-	buffer for it here, too, since it would be fatal
-    if you cannot allocate a memory in the suspend phase.
-    The allocated buffer should be released in the corresponding
-    destructor.
-    </para>
-
-    <para>
-      And next, set suspend/resume callbacks to the pci_driver.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static struct pci_driver driver = {
-          .name = "My Chip",
-          .id_table = snd_my_ids,
-          .probe = snd_my_probe,
-          .remove = __devexit_p(snd_my_remove),
-  #ifdef CONFIG_PM
-          .suspend = snd_my_suspend,
-          .resume = snd_my_resume,
-  #endif
-  };
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Module Parameters  -->
-<!-- ****************************************************** -->
-  <chapter id="module-parameters">
-    <title>Module Parameters</title>
-    <para>
-      There are standard module options for ALSA. At least, each
-      module should have the <parameter>index</parameter>,
-      <parameter>id</parameter> and <parameter>enable</parameter>
-      options. 
-    </para>
-
-    <para>
-      If the module supports multiple cards (usually up to
-      8 = <constant>SNDRV_CARDS</constant> cards), they should be
-      arrays. The default initial values are defined already as
-      constants for easier programming:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-  static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-      If the module supports only a single card, they could be single
-    variables, instead.  <parameter>enable</parameter> option is not
-    always necessary in this case, but it would be better to have a
-    dummy option for compatibility.
-    </para>
-
-    <para>
-      The module parameters must be declared with the standard
-    <function>module_param()()</function>,
-    <function>module_param_array()()</function> and
-    <function>MODULE_PARM_DESC()</function> macros.
-    </para>
-
-    <para>
-      The typical coding would be like below:
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  #define CARD_NAME "My Chip"
-
-  module_param_array(index, int, NULL, 0444);
-  MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-  module_param_array(id, charp, NULL, 0444);
-  MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-  module_param_array(enable, bool, NULL, 0444);
-  MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-    <para>
-      Also, don't forget to define the module description, classes,
-      license and devices. Especially, the recent modprobe requires to
-      define the module license as GPL, etc., otherwise the system is
-      shown as <quote>tainted</quote>. 
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  MODULE_DESCRIPTION("My Chip");
-  MODULE_LICENSE("GPL");
-  MODULE_SUPPORTED_DEVICE("{{Vendor,My Chip Name}}");
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- How To Put Your Driver  -->
-<!-- ****************************************************** -->
-  <chapter id="how-to-put-your-driver">
-    <title>How To Put Your Driver Into ALSA Tree</title>
-	<section>
-	<title>General</title>
-	<para>
-	So far, you've learned how to write the driver codes.
-	And you might have a question now: how to put my own
-	driver into the ALSA driver tree?
-	Here (finally :) the standard procedure is described briefly.
-	</para>
-
-	<para>
-	Suppose that you create a new PCI driver for the card
-	<quote>xyz</quote>.  The card module name would be
-	snd-xyz.  The new driver is usually put into the alsa-driver
-	tree, <filename>alsa-driver/pci</filename> directory in
-	the case of PCI cards.
-	Then the driver is evaluated, audited and tested
-	by developers and users.  After a certain time, the driver
-	will go to the alsa-kernel tree (to the corresponding directory,
-	such as <filename>alsa-kernel/pci</filename>) and eventually
- 	will be integrated into the Linux 2.6 tree (the directory would be
-	<filename>linux/sound/pci</filename>).
-	</para>
-
-	<para>
-	In the following sections, the driver code is supposed
-	to be put into alsa-driver tree. The two cases are covered:
-	a driver consisting of a single source file and one consisting
-	of several source files.
-	</para>
-	</section>
-
-	<section>
-	<title>Driver with A Single Source File</title>
-	<para>
-	<orderedlist>
-	<listitem>
-	<para>
-	Modify alsa-driver/pci/Makefile
-	</para>
-
-	<para>
-	Suppose you have a file xyz.c.  Add the following
-	two lines
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  snd-xyz-objs := xyz.o
-  obj-$(CONFIG_SND_XYZ) += snd-xyz.o
-]]>
-        </programlisting>
-      </informalexample>
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	Create the Kconfig entry
-	</para>
-
-	<para>
-	Add the new entry of Kconfig for your xyz driver.
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  config SND_XYZ
-          tristate "Foobar XYZ"
-          depends on SND
-          select SND_PCM
-          help
-            Say Y here to include support for Foobar XYZ soundcard.
-
-            To compile this driver as a module, choose M here: the module
-            will be called snd-xyz.
-]]>
-        </programlisting>
-      </informalexample>
-
-	the line, select SND_PCM, specifies that the driver xyz supports
-	PCM.  In addition to SND_PCM, the following components are
-	supported for select command:
-	SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART,
-	SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC.
-	Add the select command for each supported component.
-	</para>
-
-	<para>
-	Note that some selections imply the lowlevel selections.
-	For example, PCM includes TIMER, MPU401_UART includes RAWMIDI,
-	AC97_CODEC includes PCM, and OPL3_LIB includes HWDEP.
-	You don't need to give the lowlevel selections again.
-	</para>
-
-	<para>
-	For the details of Kconfig script, refer to the kbuild
-	documentation.
-	</para>
-
-	</listitem>
-
-	<listitem>
-	<para>
-	Run cvscompile script to re-generate the configure script and
-	build the whole stuff again.
-	</para>
-	</listitem>
-	</orderedlist>
-	</para>
-	</section>
-
-	<section>
-	<title>Drivers with Several Source Files</title>
-	<para>
-	Suppose that the driver snd-xyz have several source files.
-	They are located in the new subdirectory,
-	pci/xyz.
-
-	<orderedlist>
-	<listitem>
-	<para>
-	Add a new directory (<filename>xyz</filename>) in
-	<filename>alsa-driver/pci/Makefile</filename> as below
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  obj-$(CONFIG_SND) += xyz/
-]]>
-        </programlisting>
-      </informalexample>
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	Under the directory <filename>xyz</filename>, create a Makefile
-
-      <example>
-	<title>Sample Makefile for a driver xyz</title>
-        <programlisting>
-<![CDATA[
-  ifndef SND_TOPDIR
-  SND_TOPDIR=../..
-  endif
-
-  include $(SND_TOPDIR)/toplevel.config
-  include $(SND_TOPDIR)/Makefile.conf
-
-  snd-xyz-objs := xyz.o abc.o def.o
-
-  obj-$(CONFIG_SND_XYZ) += snd-xyz.o
-
-  include $(SND_TOPDIR)/Rules.make
-]]>
-        </programlisting>
-      </example>
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	Create the Kconfig entry
-	</para>
-
-	<para>
-	This procedure is as same as in the last section.
-	</para>
-	</listitem>
-
-	<listitem>
-	<para>
-	Run cvscompile script to re-generate the configure script and
-	build the whole stuff again.
-	</para>
-	</listitem>
-	</orderedlist>
-	</para>
-	</section>
-
-  </chapter>
-
-<!-- ****************************************************** -->
-<!-- Useful Functions  -->
-<!-- ****************************************************** -->
-  <chapter id="useful-functions">
-    <title>Useful Functions</title>
-
-    <section id="useful-functions-snd-printk">
-      <title><function>snd_printk()</function> and friends</title>
-      <para>
-        ALSA provides a verbose version of the
-      <function>printk()</function> function. If a kernel config
-      <constant>CONFIG_SND_VERBOSE_PRINTK</constant> is set, this
-      function prints the given message together with the file name
-      and the line of the caller. The <constant>KERN_XXX</constant>
-      prefix is processed as 
-      well as the original <function>printk()</function> does, so it's
-      recommended to add this prefix, e.g. 
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_printk(KERN_ERR "Oh my, sorry, it's extremely bad!\n");
-]]>
-          </programlisting>
-        </informalexample>
-      </para>
-
-      <para>
-        There are also <function>printk()</function>'s for
-      debugging. <function>snd_printd()</function> can be used for
-      general debugging purposes. If
-      <constant>CONFIG_SND_DEBUG</constant> is set, this function is
-      compiled, and works just like
-      <function>snd_printk()</function>. If the ALSA is compiled
-      without the debugging flag, it's ignored. 
-      </para>
-
-      <para>
-        <function>snd_printdd()</function> is compiled in only when
-      <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is set. Please note
-      that <constant>CONFIG_SND_DEBUG_VERBOSE</constant> is not set as default
-      even if you configure the alsa-driver with
-      <option>--with-debug=full</option> option. You need to give
-      explicitly <option>--with-debug=detect</option> option instead. 
-      </para>
-    </section>
-
-    <section id="useful-functions-snd-bug">
-      <title><function>snd_BUG()</function></title>
-      <para>
-        It shows the <computeroutput>BUG?</computeroutput> message and
-      stack trace as well as <function>snd_BUG_ON</function> at the point.
-      It's useful to show that a fatal error happens there. 
-      </para>
-      <para>
-	 When no debug flag is set, this macro is ignored. 
-      </para>
-    </section>
-
-    <section id="useful-functions-snd-bug-on">
-      <title><function>snd_BUG_ON()</function></title>
-      <para>
-        <function>snd_BUG_ON()</function> macro is similar with
-	<function>WARN_ON()</function> macro. For example,  
-
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_BUG_ON(!pointer);
-]]>
-          </programlisting>
-        </informalexample>
-
-	or it can be used as the condition,
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  if (snd_BUG_ON(non_zero_is_bug))
-          return -EINVAL;
-]]>
-          </programlisting>
-        </informalexample>
-
-      </para>
-
-      <para>
-        The macro takes an conditional expression to evaluate.
-	When <constant>CONFIG_SND_DEBUG</constant>, is set, the
-	expression is actually evaluated. If it's non-zero, it shows
-	the warning message such as
-	<computeroutput>BUG? (xxx)</computeroutput>
-	normally followed by stack trace.  It returns the evaluated
-	value.
-	When no <constant>CONFIG_SND_DEBUG</constant> is set, this
-	macro always returns zero.
-      </para>
-
-    </section>
-
-  </chapter>
-
-
-<!-- ****************************************************** -->
-<!-- Acknowledgments  -->
-<!-- ****************************************************** -->
-  <chapter id="acknowledgments">
-    <title>Acknowledgments</title>
-    <para>
-      I would like to thank Phil Kerr for his help for improvement and
-      corrections of this document. 
-    </para>
-    <para>
-    Kevin Conder reformatted the original plain-text to the
-    DocBook format.
-    </para>
-    <para>
-    Giuliano Pochini corrected typos and contributed the example codes
-    in the hardware constraints section.
-    </para>
-  </chapter>
-</book>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/HD-Audio-Models.txt	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,7 @@ ALC262
   sony-assamd	Sony ASSAMD
   toshiba-s06	Toshiba S06
   toshiba-rx1	Toshiba RX1
+  tyan		Tyan Thunder n6650W (S2915-E)
   ultra		Samsung Q1 Ultra Vista model
   lenovo-3000	Lenovo 3000 y410
   nec		NEC Versa S9100
@@ -261,6 +262,8 @@ Conexant 5051
 =============
   laptop	Basic Laptop config (default)
   hp		HP Spartan laptop
+  hp-dv6736	HP dv6736
+  lenovo-x200	Lenovo X200 laptop
 
 STAC9200
 ========
@@ -278,6 +281,7 @@ STAC9200
   gateway-m4	Gateway laptops with EAPD control
   gateway-m4-2	Gateway laptops with EAPD control
   panasonic	Panasonic CF-74
+  auto		BIOS setup (default)
 
 STAC9205/9254
 =============
@@ -285,6 +289,8 @@ STAC9205/9254
   dell-m42	Dell (unknown)
   dell-m43	Dell Precision
   dell-m44	Dell Inspiron
+  eapd		Keep EAPD on (e.g. Gateway T1616)
+  auto		BIOS setup (default)
 
 STAC9220/9221
 =============
@@ -308,6 +314,7 @@ STAC9220/9221
   dell-d82	Dell (unknown)
   dell-m81	Dell (unknown)
   dell-m82	Dell XPS M1210
+  auto		BIOS setup (default)
 
 STAC9202/9250/9251
 ==================
@@ -319,6 +326,7 @@ STAC9202/9250/9251
   m3		Some Gateway MX series laptops
   m5		Some Gateway MX series laptops (MP6954)
   m6		Some Gateway NX series laptops
+  auto		BIOS setup (default)
 
 STAC9227/9228/9229/927x
 =======================
@@ -326,8 +334,10 @@ STAC9227/9228/9229/927x
   ref-no-jd	Reference board without HP/Mic jack detection
   3stack	D965 3stack
   5stack	D965 5stack + SPDIF
+  5stack-no-fp	D965 5stack without front panel
   dell-3stack	Dell Dimension E520
   dell-bios	Fixes with Dell BIOS setup
+  auto		BIOS setup (default)
 
 STAC92HD71B*
 ============
@@ -335,7 +345,10 @@ STAC92HD71B*
   dell-m4-1	Dell desktops
   dell-m4-2	Dell desktops
   dell-m4-3	Dell desktops
-  hp-m4		HP dv laptops
+  hp-m4		HP mini 1000
+  hp-dv5	HP dv series
+  hp-hdx	HP HDX series
+  auto		BIOS setup (default)
 
 STAC92HD73*
 ===========
@@ -345,13 +358,16 @@ STAC92HD73*
   dell-m6-dmic	Dell desktops/laptops with digital mics
   dell-m6	Dell desktops/laptops with both type of mics
   dell-eq	Dell desktops/laptops
+  auto		BIOS setup (default)
 
 STAC92HD83*
 ===========
   ref		Reference board
   mic-ref	Reference board with power managment for ports
+  dell-s14	Dell laptop
+  auto		BIOS setup (default)
 
 STAC9872
 ========
-  vaio		Setup for VAIO FE550G/SZ110
-  vaio-ar Setup for VAIO AR
+  vaio		VAIO laptop without SPDIF
+  auto		BIOS setup (default)
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/HD-Audio.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/HD-Audio.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/HD-Audio.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/HD-Audio.txt	2009-06-09 23:05:27.000000000 -0400
@@ -109,6 +109,13 @@ slot, pass `probe_mask=1`.  For the firs
 Since 2.6.29 kernel, the driver has a more robust probing method, so
 this error might happen rarely, though.
 
+On a machine with a broken BIOS, sometimes you need to force the
+driver to probe the codec slots the hardware doesn't report for use.
+In such a case, turn the bit 8 (0x100) of `probe_mask` option on.
+Then the rest 8 bits are passed as the codec slots to probe
+unconditionally.  For example, `probe_mask=0x103` will force to probe
+the codec slots 0 and 1 no matter what the hardware reports.
+
 
 Interrupt Handling
 ~~~~~~~~~~~~~~~~~~
@@ -162,7 +169,7 @@ PCI SSID look-up.
 What `model` option values are available depends on the codec chip.
 Check your codec chip from the codec proc file (see "Codec Proc-File"
 section below).  It will show the vendor/product name of your codec
-chip.  Then, see Documentation/sound/alsa/HD-Audio-Modelstxt file,
+chip.  Then, see Documentation/sound/alsa/HD-Audio-Models.txt file,
 the section of HD-audio driver.  You can find a list of codecs
 and `model` options belonging to each codec.  For example, for Realtek
 ALC262 codec chip, pass `model=ultra` for devices that are compatible
@@ -170,7 +177,7 @@ with Samsung Q1 Ultra.
 
 Thus, the first thing you can do for any brand-new, unsupported and
 non-working HD-audio hardware is to check HD-audio codec and several
-different `model` option values.  If you have a luck, some of them
+different `model` option values.  If you have any luck, some of them
 might suit with your device well.
 
 Some codecs such as ALC880 have a special model option `model=test`.
@@ -358,10 +365,26 @@ modelname::
   to this file.
 init_verbs::
   The extra verbs to execute at initialization.  You can add a verb by
-  writing to this file.  Pass tree numbers, nid, verb and parameter.
+  writing to this file.  Pass three numbers: nid, verb and parameter
+  (separated with a space).
 hints::
-  Shows hint strings for codec parsers for any use.  Right now it's
-  not used.
+  Shows / stores hint strings for codec parsers for any use.
+  Its format is `key = value`.  For example, passing `hp_detect = yes`
+  to IDT/STAC codec parser will result in the disablement of the
+  headphone detection.
+init_pin_configs::
+  Shows the initial pin default config values set by BIOS.
+driver_pin_configs::
+  Shows the pin default values set by the codec parser explicitly.
+  This doesn't show all pin values but only the changed values by
+  the parser.  That is, if the parser doesn't change the pin default
+  config values by itself, this will contain nothing.
+user_pin_configs::
+  Shows the pin default config values to override the BIOS setup.
+  Writing this (with two numbers, NID and value) appends the new
+  value.  The given will be used instead of the initial BIOS value at
+  the next reconfiguration time.  Note that this config will override
+  even the driver pin configs, too.
 reconfig::
   Triggers the codec re-configuration.  When any value is written to
   this file, the driver re-initialize and parses the codec tree
@@ -371,6 +394,14 @@ clear::
   Resets the codec, removes the mixer elements and PCM stuff of the
   specified codec, and clear all init verbs and hints.
 
+For example, when you want to change the pin default configuration
+value of the pin widget 0x14 to 0x9993013f, and let the driver
+re-configure based on that state, run like below:
+------------------------------------------------------------------------
+  # echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs
+  # echo 1 > /sys/class/sound/hwC0D0/reconfig  
+------------------------------------------------------------------------
+
 
 Power-Saving
 ~~~~~~~~~~~~
@@ -461,6 +492,16 @@ run with `--no-upload` option, and attac
 There are some other useful options.  See `--help` option output for
 details.
 
+When a probe error occurs or when the driver obviously assigns a
+mismatched model, it'd be helpful to load the driver with
+`probe_only=1` option (at best after the cold reboot) and run
+alsa-info at this state.  With this option, the driver won't configure
+the mixer and PCM but just tries to probe the codec slot.  After
+probing, the proc file is available, so you can get the raw codec
+information before modified by the driver.  Of course, the driver
+isn't usable with `probe_only=1`.  But you can continue the
+configuration via hwdep sysfs file if hda-reconfig option is enabled.
+
 
 hda-verb
 ~~~~~~~~
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/Procfile.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/Procfile.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/Procfile.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/Procfile.txt	2009-06-09 23:05:27.000000000 -0400
@@ -104,6 +104,11 @@ card*/pcm*/xrun_debug
 	When this value is greater than 1, the driver will show the
 	stack trace additionally.  This may help the debugging.
 
+	Since 2.6.30, this option also enables the hwptr check using
+	jiffies.  This detects spontaneous invalid pointer callback
+	values, but can be lead to too much corrections for a (mostly
+	buggy) hardware that doesn't give smooth pointer updates.
+
 card*/pcm*/sub*/info
 	The general information of this PCM sub-stream.
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/soc/dapm.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/soc/dapm.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/soc/dapm.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/soc/dapm.txt	2009-06-09 23:05:27.000000000 -0400
@@ -116,6 +116,9 @@ SOC_DAPM_SINGLE("HiFi Playback Switch",
 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
 	ARRAY_SIZE(wm8731_output_mixer_controls)),
 
+If you dont want the mixer elements prefixed with the name of the mixer widget,
+you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
+as for SND_SOC_DAPM_MIXER.
 
 2.3 Platform/Machine domain Widgets
 -----------------------------------
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/alsa/soc/jack.txt linux-libre-2.6.30-gnu1/Documentation/sound/alsa/soc/jack.txt
--- linux-libre-2.6.29-gnu1/Documentation/sound/alsa/soc/jack.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/sound/alsa/soc/jack.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,71 @@
+ASoC jack detection
+===================
+
+ALSA has a standard API for representing physical jacks to user space,
+the kernel side of which can be seen in include/sound/jack.h.  ASoC
+provides a version of this API adding two additional features:
+
+ - It allows more than one jack detection method to work together on one
+   user visible jack.  In embedded systems it is common for multiple
+   to be present on a single jack but handled by separate bits of
+   hardware.
+
+ - Integration with DAPM, allowing DAPM endpoints to be updated
+   automatically based on the detected jack status (eg, turning off the
+   headphone outputs if no headphones are present).
+
+This is done by splitting the jacks up into three things working
+together: the jack itself represented by a struct snd_soc_jack, sets of
+snd_soc_jack_pins representing DAPM endpoints to update and blocks of
+code providing jack reporting mechanisms.
+
+For example, a system may have a stereo headset jack with two reporting
+mechanisms, one for the headphone and one for the microphone.  Some
+systems won't be able to use their speaker output while a headphone is
+connected and so will want to make sure to update both speaker and
+headphone when the headphone jack status changes.
+
+The jack - struct snd_soc_jack
+==============================
+
+This represents a physical jack on the system and is what is visible to
+user space.  The jack itself is completely passive, it is set up by the
+machine driver and updated by jack detection methods.
+
+Jacks are created by the machine driver calling snd_soc_jack_new().
+
+snd_soc_jack_pin
+================
+
+These represent a DAPM pin to update depending on some of the status
+bits supported by the jack.  Each snd_soc_jack has zero or more of these
+which are updated automatically.  They are created by the machine driver
+and associated with the jack using snd_soc_jack_add_pins().  The status
+of the endpoint may configured to be the opposite of the jack status if
+required (eg, enabling a built in microphone if a microphone is not
+connected via a jack).
+
+Jack detection methods
+======================
+
+Actual jack detection is done by code which is able to monitor some
+input to the system and update a jack by calling snd_soc_jack_report(),
+specifying a subset of bits to update.  The jack detection code should
+be set up by the machine driver, taking configuration for the jack to
+update and the set of things to report when the jack is connected.
+
+Often this is done based on the status of a GPIO - a handler for this is
+provided by the snd_soc_jack_add_gpio() function.  Other methods are
+also available, for example integrated into CODECs.  One example of
+CODEC integrated jack detection can be see in the WM8350 driver.
+
+Each jack may have multiple reporting mechanisms, though it will need at
+least one to be useful.
+
+Machine drivers
+===============
+
+These are all hooked together by the machine driver depending on the
+system hardware.  The machine driver will set up the snd_soc_jack and
+the list of pins to update then set up one or more jack detection
+mechanisms to update that jack based on their current status.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/oss/CS4232 linux-libre-2.6.30-gnu1/Documentation/sound/oss/CS4232
--- linux-libre-2.6.29-gnu1/Documentation/sound/oss/CS4232	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/oss/CS4232	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-To configure the Crystal CS423x sound chip and activate its DSP functions,
-modules may be loaded in this order:
-  
-	modprobe sound
-	insmod ad1848
-	insmod uart401
-	insmod cs4232 io=* irq=* dma=* dma2=*
-  
-This is the meaning of the parameters:
-  
-	io--I/O address of the Windows Sound System (normally 0x534)
-	irq--IRQ of this device
-	dma and dma2--DMA channels (DMA2 may be 0)
-  
-On some cards, the board attempts to do non-PnP setup, and fails.  If you
-have problems, use Linux' PnP facilities. 
-  
-To get MIDI facilities add
-  
-	insmod opl3 io=*
-  
-where "io" is the I/O address of the OPL3 synthesizer. This will be shown
-in /proc/sys/pnp and is normally 0x388.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sound/oss/Introduction linux-libre-2.6.30-gnu1/Documentation/sound/oss/Introduction
--- linux-libre-2.6.29-gnu1/Documentation/sound/oss/Introduction	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sound/oss/Introduction	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@ Notes:
     additional features.
 
 2.  The commercial OSS driver may be obtained from the site:
-    http://www/opensound.com.  This may be used for cards that
+    http://www.opensound.com.  This may be used for cards that
     are unsupported by the kernel driver, or may be used
     by other operating systems.  
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sparse.txt linux-libre-2.6.30-gnu1/Documentation/sparse.txt
--- linux-libre-2.6.29-gnu1/Documentation/sparse.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sparse.txt	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,14 @@ sure that bitwise types don't get mixed
 vs cpu-endian vs whatever), and there the constant "0" really _is_
 special.
 
+__bitwise__ - to be used for relatively compact stuff (gfp_t, etc.) that
+is mostly warning-free and is supposed to stay that way.  Warnings will
+be generated without __CHECK_ENDIAN__.
+
+__bitwise - noisy stuff; in particular, __le*/__be* are that.  We really
+don't want to drown in noise unless we'd explicitly asked for it.
+
+
 Getting sparse
 ~~~~~~~~~~~~~~
 
diff -druNp linux-libre-2.6.29-gnu1/Documentation/spi/spi-summary linux-libre-2.6.30-gnu1/Documentation/spi/spi-summary
--- linux-libre-2.6.29-gnu1/Documentation/spi/spi-summary	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/spi/spi-summary	2009-06-09 23:05:27.000000000 -0400
@@ -511,10 +511,16 @@ SPI MASTER METHODS
 	This sets up the device clock rate, SPI mode, and word sizes.
 	Drivers may change the defaults provided by board_info, and then
 	call spi_setup(spi) to invoke this routine.  It may sleep.
+
 	Unless each SPI slave has its own configuration registers, don't
 	change them right away ... otherwise drivers could corrupt I/O
 	that's in progress for other SPI devices.
 
+		** BUG ALERT:  for some reason the first version of
+		** many spi_master drivers seems to get this wrong.
+		** When you code setup(), ASSUME that the controller
+		** is actively processing transfers for another device.
+
     master->transfer(struct spi_device *spi, struct spi_message *message)
     	This must not sleep.  Its responsibility is arrange that the
 	transfer happens and its complete() callback is issued.  The two
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysctl/00-INDEX linux-libre-2.6.30-gnu1/Documentation/sysctl/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/sysctl/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysctl/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,8 @@ fs.txt
 	- documentation for /proc/sys/fs/*.
 kernel.txt
 	- documentation for /proc/sys/kernel/*.
+net.txt
+	- documentation for /proc/sys/net/*.
 sunrpc.txt
 	- documentation for /proc/sys/sunrpc/*.
 vm.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysctl/fs.txt linux-libre-2.6.30-gnu1/Documentation/sysctl/fs.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysctl/fs.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysctl/fs.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 Documentation for /proc/sys/fs/*	kernel version 2.2.10
 	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
+	(c) 2009,        Shen Feng<shen@cn.fujitsu.com>
 
 For general info and legal blurb, please look in README.
 
@@ -14,7 +15,12 @@ kernel. Since some of the files _can_ be
 system, it is advisable to read both documentation and source
 before actually making adjustments.
 
+1. /proc/sys/fs
+----------------------------------------------------------
+
 Currently, these files are in /proc/sys/fs:
+- aio-max-nr
+- aio-nr
 - dentry-state
 - dquot-max
 - dquot-nr
@@ -30,8 +36,15 @@ Currently, these files are in /proc/sys/
 - super-max
 - super-nr
 
-Documentation for the files in /proc/sys/fs/binfmt_misc is
-in Documentation/binfmt_misc.txt.
+==============================================================
+
+aio-nr & aio-max-nr:
+
+aio-nr is the running total of the number of events specified on the
+io_setup system call for all currently active aio contexts.  If aio-nr
+reaches aio-max-nr then io_setup will fail with EAGAIN.  Note that
+raising aio-max-nr does not result in the pre-allocation or re-sizing
+of any kernel data structures.
 
 ==============================================================
 
@@ -178,3 +191,60 @@ requests.  aio-max-nr allows you to chan
 aio-nr can grow to.
 
 ==============================================================
+
+
+2. /proc/sys/fs/binfmt_misc
+----------------------------------------------------------
+
+Documentation for the files in /proc/sys/fs/binfmt_misc is
+in Documentation/binfmt_misc.txt.
+
+
+3. /proc/sys/fs/mqueue - POSIX message queues filesystem
+----------------------------------------------------------
+
+The "mqueue"  filesystem provides  the necessary kernel features to enable the
+creation of a  user space  library that  implements  the  POSIX message queues
+API (as noted by the  MSG tag in the  POSIX 1003.1-2001 version  of the System
+Interfaces specification.)
+
+The "mqueue" filesystem contains values for determining/setting  the amount of
+resources used by the file system.
+
+/proc/sys/fs/mqueue/queues_max is a read/write  file for  setting/getting  the
+maximum number of message queues allowed on the system.
+
+/proc/sys/fs/mqueue/msg_max  is  a  read/write file  for  setting/getting  the
+maximum number of messages in a queue value.  In fact it is the limiting value
+for another (user) limit which is set in mq_open invocation. This attribute of
+a queue must be less or equal then msg_max.
+
+/proc/sys/fs/mqueue/msgsize_max is  a read/write  file for setting/getting the
+maximum  message size value (it is every  message queue's attribute set during
+its creation).
+
+
+4. /proc/sys/fs/epoll - Configuration options for the epoll interface
+--------------------------------------------------------
+
+This directory contains configuration options for the epoll(7) interface.
+
+max_user_instances
+------------------
+
+This is the maximum number of epoll file descriptors that a single user can
+have open at a given time. The default value is 128, and should be enough
+for normal users.
+
+max_user_watches
+----------------
+
+Every epoll file descriptor can store a number of files to be monitored
+for event readiness. Each one of these monitored files constitutes a "watch".
+This configuration option sets the maximum number of "watches" that are
+allowed for each user.
+Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes
+on a 64bit one.
+The current default value for  max_user_watches  is the 1/32 of the available
+low memory, divided for the "watch" cost in bytes.
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysctl/kernel.txt linux-libre-2.6.30-gnu1/Documentation/sysctl/kernel.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysctl/kernel.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysctl/kernel.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 Documentation for /proc/sys/kernel/*	kernel version 2.2.10
 	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
+	(c) 2009,        Shen Feng<shen@cn.fujitsu.com>
 
 For general info and legal blurb, please look in README.
 
@@ -18,6 +19,7 @@ Currently, these files might (depending
 show up in /proc/sys/kernel:
 - acpi_video_flags
 - acct
+- auto_msgmni
 - core_pattern
 - core_uses_pid
 - ctrl-alt-del
@@ -33,6 +35,7 @@ show up in /proc/sys/kernel:
 - msgmax
 - msgmnb
 - msgmni
+- nmi_watchdog
 - osrelease
 - ostype
 - overflowgid
@@ -40,6 +43,7 @@ show up in /proc/sys/kernel:
 - panic
 - pid_max
 - powersave-nap               [ PPC only ]
+- panic_on_unrecovered_nmi
 - printk
 - randomize_va_space
 - real-root-dev               ==> Documentation/initrd.txt
@@ -55,6 +59,7 @@ show up in /proc/sys/kernel:
 - sysrq                       ==> Documentation/sysrq.txt
 - tainted
 - threads-max
+- unknown_nmi_panic
 - version
 
 ==============================================================
@@ -381,3 +386,51 @@ can be ORed together:
  512 - A kernel warning has occurred.
 1024 - A module from drivers/staging was loaded.
 
+==============================================================
+
+auto_msgmni:
+
+Enables/Disables automatic recomputing of msgmni upon memory add/remove or
+upon ipc namespace creation/removal (see the msgmni description above).
+Echoing "1" into this file enables msgmni automatic recomputing.
+Echoing "0" turns it off.
+auto_msgmni default value is 1.
+
+==============================================================
+
+nmi_watchdog:
+
+Enables/Disables the NMI watchdog on x86 systems.  When the value is non-zero
+the NMI watchdog is enabled and will continuously test all online cpus to
+determine whether or not they are still functioning properly. Currently,
+passing "nmi_watchdog=" parameter at boot time is required for this function
+to work.
+
+If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel parameter), the
+NMI watchdog shares registers with oprofile. By disabling the NMI watchdog,
+oprofile may have more registers to utilize.
+
+==============================================================
+
+unknown_nmi_panic:
+
+The value in this file affects behavior of handling NMI. When the value is
+non-zero, unknown NMI is trapped and then panic occurs. At that time, kernel
+debugging information is displayed on console.
+
+NMI switch that most IA32 servers have fires unknown NMI up, for example.
+If a system hangs up, try pressing the NMI switch.
+
+==============================================================
+
+panic_on_unrecovered_nmi:
+
+The default Linux behaviour on an NMI of either memory or unknown is to continue
+operation. For many environments such as scientific computing it is preferable
+that the box is taken out and the error dealt with than an uncorrected
+parity/ECC error get propogated.
+
+A small number of systems do generate NMI's for bizarre random reasons such as
+power management so the default is off. That sysctl works like the existing
+panic controls already in that directory.
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysctl/net.txt linux-libre-2.6.30-gnu1/Documentation/sysctl/net.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysctl/net.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/sysctl/net.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,175 @@
+Documentation for /proc/sys/net/*	kernel version 2.4.0-test11-pre4
+	(c) 1999		Terrehon Bowden <terrehon@pacbell.net>
+				Bodo Bauer <bb@ricochet.net>
+	(c) 2000		Jorge Nerin <comandante@zaralinux.com>
+	(c) 2009		Shen Feng <shen@cn.fujitsu.com>
+
+For general info and legal blurb, please look in README.
+
+==============================================================
+
+This file contains the documentation for the sysctl files in
+/proc/sys/net and is valid for Linux kernel version 2.4.0-test11-pre4.
+
+The interface  to  the  networking  parts  of  the  kernel  is  located  in
+/proc/sys/net. The following table shows all possible subdirectories.You may
+see only some of them, depending on your kernel's configuration.
+
+
+Table : Subdirectories in /proc/sys/net
+..............................................................................
+ Directory Content             Directory  Content
+ core      General parameter   appletalk  Appletalk protocol
+ unix      Unix domain sockets netrom     NET/ROM
+ 802       E802 protocol       ax25       AX25
+ ethernet  Ethernet protocol   rose       X.25 PLP layer
+ ipv4      IP version 4        x25        X.25 protocol
+ ipx       IPX                 token-ring IBM token ring
+ bridge    Bridging            decnet     DEC net
+ ipv6      IP version 6
+..............................................................................
+
+1. /proc/sys/net/core - Network core options
+-------------------------------------------------------
+
+rmem_default
+------------
+
+The default setting of the socket receive buffer in bytes.
+
+rmem_max
+--------
+
+The maximum receive socket buffer size in bytes.
+
+wmem_default
+------------
+
+The default setting (in bytes) of the socket send buffer.
+
+wmem_max
+--------
+
+The maximum send socket buffer size in bytes.
+
+message_burst and message_cost
+------------------------------
+
+These parameters  are used to limit the warning messages written to the kernel
+log from  the  networking  code.  They  enforce  a  rate  limit  to  make  a
+denial-of-service attack  impossible. A higher message_cost factor, results in
+fewer messages that will be written. Message_burst controls when messages will
+be dropped.  The  default  settings  limit  warning messages to one every five
+seconds.
+
+warnings
+--------
+
+This controls console messages from the networking stack that can occur because
+of problems on the network like duplicate address or bad checksums. Normally,
+this should be enabled, but if the problem persists the messages can be
+disabled.
+
+netdev_budget
+-------------
+
+Maximum number of packets taken from all interfaces in one polling cycle (NAPI
+poll). In one polling cycle interfaces which are registered to polling are
+probed in a round-robin manner. The limit of packets in one such probe can be
+set per-device via sysfs class/net/<device>/weight .
+
+netdev_max_backlog
+------------------
+
+Maximum number  of  packets,  queued  on  the  INPUT  side, when the interface
+receives packets faster than kernel can process them.
+
+optmem_max
+----------
+
+Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence
+of struct cmsghdr structures with appended data.
+
+2. /proc/sys/net/unix - Parameters for Unix domain sockets
+-------------------------------------------------------
+
+There is only one file in this directory.
+unix_dgram_qlen limits the max number of datagrams queued in Unix domain
+socket's buffer. It will not take effect unless PF_UNIX flag is specified.
+
+
+3. /proc/sys/net/ipv4 - IPV4 settings
+-------------------------------------------------------
+Please see: Documentation/networking/ip-sysctl.txt and ipvs-sysctl.txt for
+descriptions of these entries.
+
+
+4. Appletalk
+-------------------------------------------------------
+
+The /proc/sys/net/appletalk  directory  holds the Appletalk configuration data
+when Appletalk is loaded. The configurable parameters are:
+
+aarp-expiry-time
+----------------
+
+The amount  of  time  we keep an ARP entry before expiring it. Used to age out
+old hosts.
+
+aarp-resolve-time
+-----------------
+
+The amount of time we will spend trying to resolve an Appletalk address.
+
+aarp-retransmit-limit
+---------------------
+
+The number of times we will retransmit a query before giving up.
+
+aarp-tick-time
+--------------
+
+Controls the rate at which expires are checked.
+
+The directory  /proc/net/appletalk  holds the list of active Appletalk sockets
+on a machine.
+
+The fields  indicate  the DDP type, the local address (in network:node format)
+the remote  address,  the  size of the transmit pending queue, the size of the
+received queue  (bytes waiting for applications to read) the state and the uid
+owning the socket.
+
+/proc/net/atalk_iface lists  all  the  interfaces  configured for appletalk.It
+shows the  name  of the interface, its Appletalk address, the network range on
+that address  (or  network number for phase 1 networks), and the status of the
+interface.
+
+/proc/net/atalk_route lists  each  known  network  route.  It lists the target
+(network) that the route leads to, the router (may be directly connected), the
+route flags, and the device the route is using.
+
+
+5. IPX
+-------------------------------------------------------
+
+The IPX protocol has no tunable values in proc/sys/net.
+
+The IPX  protocol  does,  however,  provide  proc/net/ipx. This lists each IPX
+socket giving  the  local  and  remote  addresses  in  Novell  format (that is
+network:node:port). In  accordance  with  the  strange  Novell  tradition,
+everything but the port is in hex. Not_Connected is displayed for sockets that
+are not  tied to a specific remote address. The Tx and Rx queue sizes indicate
+the number  of  bytes  pending  for  transmission  and  reception.  The  state
+indicates the  state  the  socket  is  in and the uid is the owning uid of the
+socket.
+
+The /proc/net/ipx_interface  file lists all IPX interfaces. For each interface
+it gives  the network number, the node number, and indicates if the network is
+the primary  network.  It  also  indicates  which  device  it  is bound to (or
+Internal for  internal  networks)  and  the  Frame  Type if appropriate. Linux
+supports 802.3,  802.2,  802.2  SNAP  and DIX (Blue Book) ethernet framing for
+IPX.
+
+The /proc/net/ipx_route  table  holds  a list of IPX routes. For each route it
+gives the  destination  network, the router node (or Directly) and the network
+address of the router (or Connected) for internal networks.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysctl/vm.txt linux-libre-2.6.30-gnu1/Documentation/sysctl/vm.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysctl/vm.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysctl/vm.txt	2009-06-09 23:05:27.000000000 -0400
@@ -88,6 +88,10 @@ will itself start writeback.
 If dirty_bytes is written, dirty_ratio becomes a function of its value
 (dirty_bytes / the amount of dirtyable system memory).
 
+Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any
+value lower than this limit will be ignored and the old configuration will be
+retained.
+
 ==============================================================
 
 dirty_expire_centisecs
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysfs-rules.txt linux-libre-2.6.30-gnu1/Documentation/sysfs-rules.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysfs-rules.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysfs-rules.txt	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,7 @@ versions of the sysfs interface.
   "devices" directory at /sys/subsystem/<name>/devices.
 
   If /sys/subsystem exists, /sys/bus, /sys/class and /sys/block can be
-  ignored. If it does not exist, you have always to scan all three
+  ignored. If it does not exist, you always have to scan all three
   places, as the kernel is free to move a subsystem from one place to
   the other, as long as the devices are still reachable by the same
   subsystem name.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/sysrq.txt linux-libre-2.6.30-gnu1/Documentation/sysrq.txt
--- linux-libre-2.6.29-gnu1/Documentation/sysrq.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/sysrq.txt	2009-06-09 23:05:27.000000000 -0400
@@ -81,6 +81,8 @@ On all -  write a character to /proc/sys
 
 'i'     - Send a SIGKILL to all processes, except for init.
 
+'j'     - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl.
+
 'k'     - Secure Access Key (SAK) Kills all programs on the current virtual
           console. NOTE: See important comments below in SAK section.
 
@@ -113,6 +115,8 @@ On all -  write a character to /proc/sys
 
 'x'	- Used by xmon interface on ppc/powerpc platforms.
 
+'z'	- Dump the ftrace buffer
+
 '0'-'9' - Sets the console log level, controlling which kernel messages
           will be printed to your console. ('0', for example would make
           it so that only emergency messages like PANICs or OOPSes would
@@ -160,6 +164,9 @@ t'E'rm and k'I'll are useful if you have
 are unable to kill any other way, especially if it's spawning other
 processes.
 
+"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen
+(probably root) filesystem via the FIFREEZE ioctl.
+
 *  Sometimes SysRq seems to get 'stuck' after using it, what can I do?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 That happens to me, also. I've found that tapping shift, alt, and control
diff -druNp linux-libre-2.6.29-gnu1/Documentation/tomoyo.txt linux-libre-2.6.30-gnu1/Documentation/tomoyo.txt
--- linux-libre-2.6.29-gnu1/Documentation/tomoyo.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/tomoyo.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+--- What is TOMOYO? ---
+
+TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.
+
+LiveCD-based tutorials are available at
+http://tomoyo.sourceforge.jp/en/1.6.x/1st-step/ubuntu8.04-live/
+http://tomoyo.sourceforge.jp/en/1.6.x/1st-step/centos5-live/ .
+Though these tutorials use non-LSM version of TOMOYO, they are useful for you
+to know what TOMOYO is.
+
+--- How to enable TOMOYO? ---
+
+Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on
+kernel's command line.
+
+Please see http://tomoyo.sourceforge.jp/en/2.2.x/ for details.
+
+--- Where is documentation? ---
+
+User <-> Kernel interface documentation is available at
+http://tomoyo.sourceforge.jp/en/2.2.x/policy-reference.html .
+
+Materials we prepared for seminars and symposiums are available at
+http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
+Below lists are chosen from three aspects.
+
+What is TOMOYO?
+  TOMOYO Linux Overview
+    http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf
+  TOMOYO Linux: pragmatic and manageable security for Linux
+    http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
+  TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
+    http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
+
+What can TOMOYO do?
+  Deep inside TOMOYO Linux
+    http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
+  The role of "pathname based access control" in security.
+    http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf
+
+History of TOMOYO?
+  Realities of Mainlining
+    http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf
+
+--- What is future plan? ---
+
+We believe that inode based security and name based security are complementary
+and both should be used together. But unfortunately, so far, we cannot enable
+multiple LSM modules at the same time. We feel sorry that you have to give up
+SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.
+
+We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
+version of TOMOYO, available at http://tomoyo.sourceforge.jp/en/1.6.x/ .
+LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
+to port non-LSM version's functionalities to LSM versions.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/trace/ftrace.txt linux-libre-2.6.30-gnu1/Documentation/trace/ftrace.txt
--- linux-libre-2.6.29-gnu1/Documentation/trace/ftrace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/trace/ftrace.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1828 @@
+		ftrace - Function Tracer
+		========================
+
+Copyright 2008 Red Hat Inc.
+   Author:   Steven Rostedt <srostedt@redhat.com>
+  License:   The GNU Free Documentation License, Version 1.2
+               (dual licensed under the GPL v2)
+Reviewers:   Elias Oltmanns, Randy Dunlap, Andrew Morton,
+	     John Kacur, and David Teigland.
+
+Written for: 2.6.28-rc2
+
+Introduction
+------------
+
+Ftrace is an internal tracer designed to help out developers and
+designers of systems to find what is going on inside the kernel.
+It can be used for debugging or analyzing latencies and
+performance issues that take place outside of user-space.
+
+Although ftrace is the function tracer, it also includes an
+infrastructure that allows for other types of tracing. Some of
+the tracers that are currently in ftrace include a tracer to
+trace context switches, the time it takes for a high priority
+task to run after it was woken up, the time interrupts are
+disabled, and more (ftrace allows for tracer plugins, which
+means that the list of tracers can always grow).
+
+
+The File System
+---------------
+
+Ftrace uses the debugfs file system to hold the control files as
+well as the files to display output.
+
+To mount the debugfs system:
+
+  # mkdir /debug
+  # mount -t debugfs nodev /debug
+
+( Note: it is more common to mount at /sys/kernel/debug, but for
+  simplicity this document will use /debug)
+
+That's it! (assuming that you have ftrace configured into your kernel)
+
+After mounting the debugfs, you can see a directory called
+"tracing".  This directory contains the control and output files
+of ftrace. Here is a list of some of the key files:
+
+
+ Note: all time values are in microseconds.
+
+  current_tracer:
+
+	This is used to set or display the current tracer
+	that is configured.
+
+  available_tracers:
+
+	This holds the different types of tracers that
+	have been compiled into the kernel. The
+	tracers listed here can be configured by
+	echoing their name into current_tracer.
+
+  tracing_enabled:
+
+	This sets or displays whether the current_tracer
+	is activated and tracing or not. Echo 0 into this
+	file to disable the tracer or 1 to enable it.
+
+  trace:
+
+	This file holds the output of the trace in a human
+	readable format (described below).
+
+  latency_trace:
+
+	This file shows the same trace but the information
+	is organized more to display possible latencies
+	in the system (described below).
+
+  trace_pipe:
+
+	The output is the same as the "trace" file but this
+	file is meant to be streamed with live tracing.
+	Reads from this file will block until new data
+	is retrieved. Unlike the "trace" and "latency_trace"
+	files, this file is a consumer. This means reading
+	from this file causes sequential reads to display
+	more current data. Once data is read from this
+	file, it is consumed, and will not be read
+	again with a sequential read. The "trace" and
+	"latency_trace" files are static, and if the
+	tracer is not adding more data, they will display
+	the same information every time they are read.
+
+  trace_options:
+
+	This file lets the user control the amount of data
+	that is displayed in one of the above output
+	files.
+
+  tracing_max_latency:
+
+	Some of the tracers record the max latency.
+	For example, the time interrupts are disabled.
+	This time is saved in this file. The max trace
+	will also be stored, and displayed by either
+	"trace" or "latency_trace".  A new max trace will
+	only be recorded if the latency is greater than
+	the value in this file. (in microseconds)
+
+  buffer_size_kb:
+
+	This sets or displays the number of kilobytes each CPU
+	buffer can hold. The tracer buffers are the same size
+	for each CPU. The displayed number is the size of the
+	CPU buffer and not total size of all buffers. The
+	trace buffers are allocated in pages (blocks of memory
+	that the kernel uses for allocation, usually 4 KB in size).
+	If the last page allocated has room for more bytes
+	than requested, the rest of the page will be used,
+	making the actual allocation bigger than requested.
+	( Note, the size may not be a multiple of the page size
+	  due to buffer managment overhead. )
+
+	This can only be updated when the current_tracer
+	is set to "nop".
+
+  tracing_cpumask:
+
+	This is a mask that lets the user only trace
+	on specified CPUS. The format is a hex string
+	representing the CPUS.
+
+  set_ftrace_filter:
+
+	When dynamic ftrace is configured in (see the
+	section below "dynamic ftrace"), the code is dynamically
+	modified (code text rewrite) to disable calling of the
+	function profiler (mcount). This lets tracing be configured
+	in with practically no overhead in performance.  This also
+	has a side effect of enabling or disabling specific functions
+	to be traced. Echoing names of functions into this file
+	will limit the trace to only those functions.
+
+  set_ftrace_notrace:
+
+	This has an effect opposite to that of
+	set_ftrace_filter. Any function that is added here will not
+	be traced. If a function exists in both set_ftrace_filter
+	and set_ftrace_notrace,	the function will _not_ be traced.
+
+  set_ftrace_pid:
+
+	Have the function tracer only trace a single thread.
+
+  set_graph_function:
+
+	Set a "trigger" function where tracing should start
+	with the function graph tracer (See the section
+	"dynamic ftrace" for more details).
+
+  available_filter_functions:
+
+	This lists the functions that ftrace
+	has processed and can trace. These are the function
+	names that you can pass to "set_ftrace_filter" or
+	"set_ftrace_notrace". (See the section "dynamic ftrace"
+	below for more details.)
+
+
+The Tracers
+-----------
+
+Here is the list of current tracers that may be configured.
+
+  "function"
+
+	Function call tracer to trace all kernel functions.
+
+  "function_graph_tracer"
+
+	Similar to the function tracer except that the
+	function tracer probes the functions on their entry
+	whereas the function graph tracer traces on both entry
+	and exit of the functions. It then provides the ability
+	to draw a graph of function calls similar to C code
+	source.
+
+  "sched_switch"
+
+	Traces the context switches and wakeups between tasks.
+
+  "irqsoff"
+
+	Traces the areas that disable interrupts and saves
+	the trace with the longest max latency.
+	See tracing_max_latency. When a new max is recorded,
+	it replaces the old trace. It is best to view this
+	trace via the latency_trace file.
+
+  "preemptoff"
+
+	Similar to irqsoff but traces and records the amount of
+	time for which preemption is disabled.
+
+  "preemptirqsoff"
+
+	Similar to irqsoff and preemptoff, but traces and
+	records the largest time for which irqs and/or preemption
+	is disabled.
+
+  "wakeup"
+
+	Traces and records the max latency that it takes for
+	the highest priority task to get scheduled after
+	it has been woken up.
+
+  "hw-branch-tracer"
+
+	Uses the BTS CPU feature on x86 CPUs to traces all
+	branches executed.
+
+  "nop"
+
+	This is the "trace nothing" tracer. To remove all
+	tracers from tracing simply echo "nop" into
+	current_tracer.
+
+
+Examples of using the tracer
+----------------------------
+
+Here are typical examples of using the tracers when controlling
+them only with the debugfs interface (without using any
+user-land utilities).
+
+Output format:
+--------------
+
+Here is an example of the output format of the file "trace"
+
+                             --------
+# tracer: function
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+            bash-4251  [01] 10152.583854: path_put <-path_walk
+            bash-4251  [01] 10152.583855: dput <-path_put
+            bash-4251  [01] 10152.583855: _atomic_dec_and_lock <-dput
+                             --------
+
+A header is printed with the tracer name that is represented by
+the trace. In this case the tracer is "function". Then a header
+showing the format. Task name "bash", the task PID "4251", the
+CPU that it was running on "01", the timestamp in <secs>.<usecs>
+format, the function name that was traced "path_put" and the
+parent function that called this function "path_walk". The
+timestamp is the time at which the function was entered.
+
+The sched_switch tracer also includes tracing of task wakeups
+and context switches.
+
+     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +  2916:115:S
+     ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +    10:115:S
+     ksoftirqd/1-7     [01]  1453.070013:      7:115:R ==>    10:115:R
+        events/1-10    [01]  1453.070013:     10:115:S ==>  2916:115:R
+     kondemand/1-2916  [01]  1453.070013:   2916:115:S ==>     7:115:R
+     ksoftirqd/1-7     [01]  1453.070013:      7:115:S ==>     0:140:R
+
+Wake ups are represented by a "+" and the context switches are
+shown as "==>".  The format is:
+
+ Context switches:
+
+       Previous task              Next Task
+
+  <pid>:<prio>:<state>  ==>  <pid>:<prio>:<state>
+
+ Wake ups:
+
+       Current task               Task waking up
+
+  <pid>:<prio>:<state>    +  <pid>:<prio>:<state>
+
+The prio is the internal kernel priority, which is the inverse
+of the priority that is usually displayed by user-space tools.
+Zero represents the highest priority (99). Prio 100 starts the
+"nice" priorities with 100 being equal to nice -20 and 139 being
+nice 19. The prio "140" is reserved for the idle task which is
+the lowest priority thread (pid 0).
+
+
+Latency trace format
+--------------------
+
+For traces that display latency times, the latency_trace file
+gives somewhat more information to see why a latency happened.
+Here is a typical trace.
+
+# tracer: irqsoff
+#
+irqsoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 97 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: apic_timer_interrupt
+ => ended at:   do_softirq
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+  <idle>-0     0d..1    0us+: trace_hardirqs_off_thunk (apic_timer_interrupt)
+  <idle>-0     0d.s.   97us : __do_softirq (do_softirq)
+  <idle>-0     0d.s1   98us : trace_hardirqs_on (do_softirq)
+
+
+This shows that the current tracer is "irqsoff" tracing the time
+for which interrupts were disabled. It gives the trace version
+and the version of the kernel upon which this was executed on
+(2.6.26-rc8). Then it displays the max latency in microsecs (97
+us). The number of trace entries displayed and the total number
+recorded (both are three: #3/3). The type of preemption that was
+used (PREEMPT). VP, KP, SP, and HP are always zero and are
+reserved for later use. #P is the number of online CPUS (#P:2).
+
+The task is the process that was running when the latency
+occurred. (swapper pid: 0).
+
+The start and stop (the functions in which the interrupts were
+disabled and enabled respectively) that caused the latencies:
+
+  apic_timer_interrupt is where the interrupts were disabled.
+  do_softirq is where they were enabled again.
+
+The next lines after the header are the trace itself. The header
+explains which is which.
+
+  cmd: The name of the process in the trace.
+
+  pid: The PID of that process.
+
+  CPU#: The CPU which the process was running on.
+
+  irqs-off: 'd' interrupts are disabled. '.' otherwise.
+	    Note: If the architecture does not support a way to
+		  read the irq flags variable, an 'X' will always
+		  be printed here.
+
+  need-resched: 'N' task need_resched is set, '.' otherwise.
+
+  hardirq/softirq:
+	'H' - hard irq occurred inside a softirq.
+	'h' - hard irq is running
+	's' - soft irq is running
+	'.' - normal context.
+
+  preempt-depth: The level of preempt_disabled
+
+The above is mostly meaningful for kernel developers.
+
+  time: This differs from the trace file output. The trace file output
+	includes an absolute timestamp. The timestamp used by the
+	latency_trace file is relative to the start of the trace.
+
+  delay: This is just to help catch your eye a bit better. And
+	 needs to be fixed to be only relative to the same CPU.
+	 The marks are determined by the difference between this
+	 current trace and the next trace.
+	  '!' - greater than preempt_mark_thresh (default 100)
+	  '+' - greater than 1 microsecond
+	  ' ' - less than or equal to 1 microsecond.
+
+  The rest is the same as the 'trace' file.
+
+
+trace_options
+-------------
+
+The trace_options file is used to control what gets printed in
+the trace output. To see what is available, simply cat the file:
+
+  cat /debug/tracing/trace_options
+  print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
+  noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
+
+To disable one of the options, echo in the option prepended with
+"no".
+
+  echo noprint-parent > /debug/tracing/trace_options
+
+To enable an option, leave off the "no".
+
+  echo sym-offset > /debug/tracing/trace_options
+
+Here are the available options:
+
+  print-parent - On function traces, display the calling (parent)
+		 function as well as the function being traced.
+
+  print-parent:
+   bash-4000  [01]  1477.606694: simple_strtoul <-strict_strtoul
+
+  noprint-parent:
+   bash-4000  [01]  1477.606694: simple_strtoul
+
+
+  sym-offset - Display not only the function name, but also the
+	       offset in the function. For example, instead of
+	       seeing just "ktime_get", you will see
+	       "ktime_get+0xb/0x20".
+
+  sym-offset:
+   bash-4000  [01]  1477.606694: simple_strtoul+0x6/0xa0
+
+  sym-addr - this will also display the function address as well
+	     as the function name.
+
+  sym-addr:
+   bash-4000  [01]  1477.606694: simple_strtoul <c0339346>
+
+  verbose - This deals with the latency_trace file.
+
+    bash  4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
+    (+0.000ms): simple_strtoul (strict_strtoul)
+
+  raw - This will display raw numbers. This option is best for
+	use with user applications that can translate the raw
+	numbers better than having it done in the kernel.
+
+  hex - Similar to raw, but the numbers will be in a hexadecimal
+	format.
+
+  bin - This will print out the formats in raw binary.
+
+  block - TBD (needs update)
+
+  stacktrace - This is one of the options that changes the trace
+	       itself. When a trace is recorded, so is the stack
+	       of functions. This allows for back traces of
+	       trace sites.
+
+  userstacktrace - This option changes the trace. It records a
+		   stacktrace of the current userspace thread.
+
+  sym-userobj - when user stacktrace are enabled, look up which
+		object the address belongs to, and print a
+		relative address. This is especially useful when
+		ASLR is on, otherwise you don't get a chance to
+		resolve the address to object/file/line after
+		the app is no longer running
+
+		The lookup is performed when you read
+		trace,trace_pipe,latency_trace. Example:
+
+		a.out-1623  [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
+x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
+
+  sched-tree - trace all tasks that are on the runqueue, at
+	       every scheduling event. Will add overhead if
+	       there's a lot of tasks running at once.
+
+
+sched_switch
+------------
+
+This tracer simply records schedule switches. Here is an example
+of how to use it.
+
+ # echo sched_switch > /debug/tracing/current_tracer
+ # echo 1 > /debug/tracing/tracing_enabled
+ # sleep 1
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/trace
+
+# tracer: sched_switch
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+            bash-3997  [01]   240.132281:   3997:120:R   +  4055:120:R
+            bash-3997  [01]   240.132284:   3997:120:R ==>  4055:120:R
+           sleep-4055  [01]   240.132371:   4055:120:S ==>  3997:120:R
+            bash-3997  [01]   240.132454:   3997:120:R   +  4055:120:S
+            bash-3997  [01]   240.132457:   3997:120:R ==>  4055:120:R
+           sleep-4055  [01]   240.132460:   4055:120:D ==>  3997:120:R
+            bash-3997  [01]   240.132463:   3997:120:R   +  4055:120:D
+            bash-3997  [01]   240.132465:   3997:120:R ==>  4055:120:R
+          <idle>-0     [00]   240.132589:      0:140:R   +     4:115:S
+          <idle>-0     [00]   240.132591:      0:140:R ==>     4:115:R
+     ksoftirqd/0-4     [00]   240.132595:      4:115:S ==>     0:140:R
+          <idle>-0     [00]   240.132598:      0:140:R   +     4:115:S
+          <idle>-0     [00]   240.132599:      0:140:R ==>     4:115:R
+     ksoftirqd/0-4     [00]   240.132603:      4:115:S ==>     0:140:R
+           sleep-4055  [01]   240.133058:   4055:120:S ==>  3997:120:R
+ [...]
+
+
+As we have discussed previously about this format, the header
+shows the name of the trace and points to the options. The
+"FUNCTION" is a misnomer since here it represents the wake ups
+and context switches.
+
+The sched_switch file only lists the wake ups (represented with
+'+') and context switches ('==>') with the previous task or
+current task first followed by the next task or task waking up.
+The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
+Remember that the KERNEL-PRIO is the inverse of the actual
+priority with zero (0) being the highest priority and the nice
+values starting at 100 (nice -20). Below is a quick chart to map
+the kernel priority to user land priorities.
+
+  Kernel priority: 0 to 99    ==> user RT priority 99 to 0
+  Kernel priority: 100 to 139 ==> user nice -20 to 19
+  Kernel priority: 140        ==> idle task priority
+
+The task states are:
+
+ R - running : wants to run, may not actually be running
+ S - sleep   : process is waiting to be woken up (handles signals)
+ D - disk sleep (uninterruptible sleep) : process must be woken up
+					(ignores signals)
+ T - stopped : process suspended
+ t - traced  : process is being traced (with something like gdb)
+ Z - zombie  : process waiting to be cleaned up
+ X - unknown
+
+
+ftrace_enabled
+--------------
+
+The following tracers (listed below) give different output
+depending on whether or not the sysctl ftrace_enabled is set. To
+set ftrace_enabled, one can either use the sysctl function or
+set it via the proc file system interface.
+
+  sysctl kernel.ftrace_enabled=1
+
+ or
+
+  echo 1 > /proc/sys/kernel/ftrace_enabled
+
+To disable ftrace_enabled simply replace the '1' with '0' in the
+above commands.
+
+When ftrace_enabled is set the tracers will also record the
+functions that are within the trace. The descriptions of the
+tracers will also show an example with ftrace enabled.
+
+
+irqsoff
+-------
+
+When interrupts are disabled, the CPU can not react to any other
+external event (besides NMIs and SMIs). This prevents the timer
+interrupt from triggering or the mouse interrupt from letting
+the kernel know of a new mouse event. The result is a latency
+with the reaction time.
+
+The irqsoff tracer tracks the time for which interrupts are
+disabled. When a new maximum latency is hit, the tracer saves
+the trace leading up to that latency point so that every time a
+new maximum is reached, the old saved trace is discarded and the
+new trace is saved.
+
+To reset the maximum, echo 0 into tracing_max_latency. Here is
+an example:
+
+ # echo irqsoff > /debug/tracing/current_tracer
+ # echo 0 > /debug/tracing/tracing_max_latency
+ # echo 1 > /debug/tracing/tracing_enabled
+ # ls -ltr
+ [...]
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/latency_trace
+# tracer: irqsoff
+#
+irqsoff latency trace v1.1.5 on 2.6.26
+--------------------------------------------------------------------
+ latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: sys_setpgid
+ => ended at:   sys_setpgid
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+    bash-3730  1d...    0us : _write_lock_irq (sys_setpgid)
+    bash-3730  1d..1    1us+: _write_unlock_irq (sys_setpgid)
+    bash-3730  1d..2   14us : trace_hardirqs_on (sys_setpgid)
+
+
+Here we see that that we had a latency of 12 microsecs (which is
+very good). The _write_lock_irq in sys_setpgid disabled
+interrupts. The difference between the 12 and the displayed
+timestamp 14us occurred because the clock was incremented
+between the time of recording the max latency and the time of
+recording the function that had that latency.
+
+Note the above example had ftrace_enabled not set. If we set the
+ftrace_enabled, we get a much larger output:
+
+# tracer: irqsoff
+#
+irqsoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 50 us, #101/101, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: ls-4339 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: __alloc_pages_internal
+ => ended at:   __alloc_pages_internal
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+      ls-4339  0...1    0us+: get_page_from_freelist (__alloc_pages_internal)
+      ls-4339  0d..1    3us : rmqueue_bulk (get_page_from_freelist)
+      ls-4339  0d..1    3us : _spin_lock (rmqueue_bulk)
+      ls-4339  0d..1    4us : add_preempt_count (_spin_lock)
+      ls-4339  0d..2    4us : __rmqueue (rmqueue_bulk)
+      ls-4339  0d..2    5us : __rmqueue_smallest (__rmqueue)
+      ls-4339  0d..2    5us : __mod_zone_page_state (__rmqueue_smallest)
+      ls-4339  0d..2    6us : __rmqueue (rmqueue_bulk)
+      ls-4339  0d..2    6us : __rmqueue_smallest (__rmqueue)
+      ls-4339  0d..2    7us : __mod_zone_page_state (__rmqueue_smallest)
+      ls-4339  0d..2    7us : __rmqueue (rmqueue_bulk)
+      ls-4339  0d..2    8us : __rmqueue_smallest (__rmqueue)
+[...]
+      ls-4339  0d..2   46us : __rmqueue_smallest (__rmqueue)
+      ls-4339  0d..2   47us : __mod_zone_page_state (__rmqueue_smallest)
+      ls-4339  0d..2   47us : __rmqueue (rmqueue_bulk)
+      ls-4339  0d..2   48us : __rmqueue_smallest (__rmqueue)
+      ls-4339  0d..2   48us : __mod_zone_page_state (__rmqueue_smallest)
+      ls-4339  0d..2   49us : _spin_unlock (rmqueue_bulk)
+      ls-4339  0d..2   49us : sub_preempt_count (_spin_unlock)
+      ls-4339  0d..1   50us : get_page_from_freelist (__alloc_pages_internal)
+      ls-4339  0d..2   51us : trace_hardirqs_on (__alloc_pages_internal)
+
+
+
+Here we traced a 50 microsecond latency. But we also see all the
+functions that were called during that time. Note that by
+enabling function tracing, we incur an added overhead. This
+overhead may extend the latency times. But nevertheless, this
+trace has provided some very helpful debugging information.
+
+
+preemptoff
+----------
+
+When preemption is disabled, we may be able to receive
+interrupts but the task cannot be preempted and a higher
+priority task must wait for preemption to be enabled again
+before it can preempt a lower priority task.
+
+The preemptoff tracer traces the places that disable preemption.
+Like the irqsoff tracer, it records the maximum latency for
+which preemption was disabled. The control of preemptoff tracer
+is much like the irqsoff tracer.
+
+ # echo preemptoff > /debug/tracing/current_tracer
+ # echo 0 > /debug/tracing/tracing_max_latency
+ # echo 1 > /debug/tracing/tracing_enabled
+ # ls -ltr
+ [...]
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/latency_trace
+# tracer: preemptoff
+#
+preemptoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 29 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: do_IRQ
+ => ended at:   __do_softirq
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+    sshd-4261  0d.h.    0us+: irq_enter (do_IRQ)
+    sshd-4261  0d.s.   29us : _local_bh_enable (__do_softirq)
+    sshd-4261  0d.s1   30us : trace_preempt_on (__do_softirq)
+
+
+This has some more changes. Preemption was disabled when an
+interrupt came in (notice the 'h'), and was enabled while doing
+a softirq. (notice the 's'). But we also see that interrupts
+have been disabled when entering the preempt off section and
+leaving it (the 'd'). We do not know if interrupts were enabled
+in the mean time.
+
+# tracer: preemptoff
+#
+preemptoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 63 us, #87/87, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: remove_wait_queue
+ => ended at:   __do_softirq
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+    sshd-4261  0d..1    0us : _spin_lock_irqsave (remove_wait_queue)
+    sshd-4261  0d..1    1us : _spin_unlock_irqrestore (remove_wait_queue)
+    sshd-4261  0d..1    2us : do_IRQ (common_interrupt)
+    sshd-4261  0d..1    2us : irq_enter (do_IRQ)
+    sshd-4261  0d..1    2us : idle_cpu (irq_enter)
+    sshd-4261  0d..1    3us : add_preempt_count (irq_enter)
+    sshd-4261  0d.h1    3us : idle_cpu (irq_enter)
+    sshd-4261  0d.h.    4us : handle_fasteoi_irq (do_IRQ)
+[...]
+    sshd-4261  0d.h.   12us : add_preempt_count (_spin_lock)
+    sshd-4261  0d.h1   12us : ack_ioapic_quirk_irq (handle_fasteoi_irq)
+    sshd-4261  0d.h1   13us : move_native_irq (ack_ioapic_quirk_irq)
+    sshd-4261  0d.h1   13us : _spin_unlock (handle_fasteoi_irq)
+    sshd-4261  0d.h1   14us : sub_preempt_count (_spin_unlock)
+    sshd-4261  0d.h1   14us : irq_exit (do_IRQ)
+    sshd-4261  0d.h1   15us : sub_preempt_count (irq_exit)
+    sshd-4261  0d..2   15us : do_softirq (irq_exit)
+    sshd-4261  0d...   15us : __do_softirq (do_softirq)
+    sshd-4261  0d...   16us : __local_bh_disable (__do_softirq)
+    sshd-4261  0d...   16us+: add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s4   20us : add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s4   21us : sub_preempt_count (local_bh_enable)
+    sshd-4261  0d.s5   21us : sub_preempt_count (local_bh_enable)
+[...]
+    sshd-4261  0d.s6   41us : add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s6   42us : sub_preempt_count (local_bh_enable)
+    sshd-4261  0d.s7   42us : sub_preempt_count (local_bh_enable)
+    sshd-4261  0d.s5   43us : add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s5   43us : sub_preempt_count (local_bh_enable_ip)
+    sshd-4261  0d.s6   44us : sub_preempt_count (local_bh_enable_ip)
+    sshd-4261  0d.s5   44us : add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s5   45us : sub_preempt_count (local_bh_enable)
+[...]
+    sshd-4261  0d.s.   63us : _local_bh_enable (__do_softirq)
+    sshd-4261  0d.s1   64us : trace_preempt_on (__do_softirq)
+
+
+The above is an example of the preemptoff trace with
+ftrace_enabled set. Here we see that interrupts were disabled
+the entire time. The irq_enter code lets us know that we entered
+an interrupt 'h'. Before that, the functions being traced still
+show that it is not in an interrupt, but we can see from the
+functions themselves that this is not the case.
+
+Notice that __do_softirq when called does not have a
+preempt_count. It may seem that we missed a preempt enabling.
+What really happened is that the preempt count is held on the
+thread's stack and we switched to the softirq stack (4K stacks
+in effect). The code does not copy the preempt count, but
+because interrupts are disabled, we do not need to worry about
+it. Having a tracer like this is good for letting people know
+what really happens inside the kernel.
+
+
+preemptirqsoff
+--------------
+
+Knowing the locations that have interrupts disabled or
+preemption disabled for the longest times is helpful. But
+sometimes we would like to know when either preemption and/or
+interrupts are disabled.
+
+Consider the following code:
+
+    local_irq_disable();
+    call_function_with_irqs_off();
+    preempt_disable();
+    call_function_with_irqs_and_preemption_off();
+    local_irq_enable();
+    call_function_with_preemption_off();
+    preempt_enable();
+
+The irqsoff tracer will record the total length of
+call_function_with_irqs_off() and
+call_function_with_irqs_and_preemption_off().
+
+The preemptoff tracer will record the total length of
+call_function_with_irqs_and_preemption_off() and
+call_function_with_preemption_off().
+
+But neither will trace the time that interrupts and/or
+preemption is disabled. This total time is the time that we can
+not schedule. To record this time, use the preemptirqsoff
+tracer.
+
+Again, using this trace is much like the irqsoff and preemptoff
+tracers.
+
+ # echo preemptirqsoff > /debug/tracing/current_tracer
+ # echo 0 > /debug/tracing/tracing_max_latency
+ # echo 1 > /debug/tracing/tracing_enabled
+ # ls -ltr
+ [...]
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/latency_trace
+# tracer: preemptirqsoff
+#
+preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 293 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: ls-4860 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: apic_timer_interrupt
+ => ended at:   __do_softirq
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+      ls-4860  0d...    0us!: trace_hardirqs_off_thunk (apic_timer_interrupt)
+      ls-4860  0d.s.  294us : _local_bh_enable (__do_softirq)
+      ls-4860  0d.s1  294us : trace_preempt_on (__do_softirq)
+
+
+
+The trace_hardirqs_off_thunk is called from assembly on x86 when
+interrupts are disabled in the assembly code. Without the
+function tracing, we do not know if interrupts were enabled
+within the preemption points. We do see that it started with
+preemption enabled.
+
+Here is a trace with ftrace_enabled set:
+
+
+# tracer: preemptirqsoff
+#
+preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 105 us, #183/183, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
+    -----------------
+ => started at: write_chan
+ => ended at:   __do_softirq
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+      ls-4473  0.N..    0us : preempt_schedule (write_chan)
+      ls-4473  0dN.1    1us : _spin_lock (schedule)
+      ls-4473  0dN.1    2us : add_preempt_count (_spin_lock)
+      ls-4473  0d..2    2us : put_prev_task_fair (schedule)
+[...]
+      ls-4473  0d..2   13us : set_normalized_timespec (ktime_get_ts)
+      ls-4473  0d..2   13us : __switch_to (schedule)
+    sshd-4261  0d..2   14us : finish_task_switch (schedule)
+    sshd-4261  0d..2   14us : _spin_unlock_irq (finish_task_switch)
+    sshd-4261  0d..1   15us : add_preempt_count (_spin_lock_irqsave)
+    sshd-4261  0d..2   16us : _spin_unlock_irqrestore (hrtick_set)
+    sshd-4261  0d..2   16us : do_IRQ (common_interrupt)
+    sshd-4261  0d..2   17us : irq_enter (do_IRQ)
+    sshd-4261  0d..2   17us : idle_cpu (irq_enter)
+    sshd-4261  0d..2   18us : add_preempt_count (irq_enter)
+    sshd-4261  0d.h2   18us : idle_cpu (irq_enter)
+    sshd-4261  0d.h.   18us : handle_fasteoi_irq (do_IRQ)
+    sshd-4261  0d.h.   19us : _spin_lock (handle_fasteoi_irq)
+    sshd-4261  0d.h.   19us : add_preempt_count (_spin_lock)
+    sshd-4261  0d.h1   20us : _spin_unlock (handle_fasteoi_irq)
+    sshd-4261  0d.h1   20us : sub_preempt_count (_spin_unlock)
+[...]
+    sshd-4261  0d.h1   28us : _spin_unlock (handle_fasteoi_irq)
+    sshd-4261  0d.h1   29us : sub_preempt_count (_spin_unlock)
+    sshd-4261  0d.h2   29us : irq_exit (do_IRQ)
+    sshd-4261  0d.h2   29us : sub_preempt_count (irq_exit)
+    sshd-4261  0d..3   30us : do_softirq (irq_exit)
+    sshd-4261  0d...   30us : __do_softirq (do_softirq)
+    sshd-4261  0d...   31us : __local_bh_disable (__do_softirq)
+    sshd-4261  0d...   31us+: add_preempt_count (__local_bh_disable)
+    sshd-4261  0d.s4   34us : add_preempt_count (__local_bh_disable)
+[...]
+    sshd-4261  0d.s3   43us : sub_preempt_count (local_bh_enable_ip)
+    sshd-4261  0d.s4   44us : sub_preempt_count (local_bh_enable_ip)
+    sshd-4261  0d.s3   44us : smp_apic_timer_interrupt (apic_timer_interrupt)
+    sshd-4261  0d.s3   45us : irq_enter (smp_apic_timer_interrupt)
+    sshd-4261  0d.s3   45us : idle_cpu (irq_enter)
+    sshd-4261  0d.s3   46us : add_preempt_count (irq_enter)
+    sshd-4261  0d.H3   46us : idle_cpu (irq_enter)
+    sshd-4261  0d.H3   47us : hrtimer_interrupt (smp_apic_timer_interrupt)
+    sshd-4261  0d.H3   47us : ktime_get (hrtimer_interrupt)
+[...]
+    sshd-4261  0d.H3   81us : tick_program_event (hrtimer_interrupt)
+    sshd-4261  0d.H3   82us : ktime_get (tick_program_event)
+    sshd-4261  0d.H3   82us : ktime_get_ts (ktime_get)
+    sshd-4261  0d.H3   83us : getnstimeofday (ktime_get_ts)
+    sshd-4261  0d.H3   83us : set_normalized_timespec (ktime_get_ts)
+    sshd-4261  0d.H3   84us : clockevents_program_event (tick_program_event)
+    sshd-4261  0d.H3   84us : lapic_next_event (clockevents_program_event)
+    sshd-4261  0d.H3   85us : irq_exit (smp_apic_timer_interrupt)
+    sshd-4261  0d.H3   85us : sub_preempt_count (irq_exit)
+    sshd-4261  0d.s4   86us : sub_preempt_count (irq_exit)
+    sshd-4261  0d.s3   86us : add_preempt_count (__local_bh_disable)
+[...]
+    sshd-4261  0d.s1   98us : sub_preempt_count (net_rx_action)
+    sshd-4261  0d.s.   99us : add_preempt_count (_spin_lock_irq)
+    sshd-4261  0d.s1   99us+: _spin_unlock_irq (run_timer_softirq)
+    sshd-4261  0d.s.  104us : _local_bh_enable (__do_softirq)
+    sshd-4261  0d.s.  104us : sub_preempt_count (_local_bh_enable)
+    sshd-4261  0d.s.  105us : _local_bh_enable (__do_softirq)
+    sshd-4261  0d.s1  105us : trace_preempt_on (__do_softirq)
+
+
+This is a very interesting trace. It started with the preemption
+of the ls task. We see that the task had the "need_resched" bit
+set via the 'N' in the trace.  Interrupts were disabled before
+the spin_lock at the beginning of the trace. We see that a
+schedule took place to run sshd.  When the interrupts were
+enabled, we took an interrupt. On return from the interrupt
+handler, the softirq ran. We took another interrupt while
+running the softirq as we see from the capital 'H'.
+
+
+wakeup
+------
+
+In a Real-Time environment it is very important to know the
+wakeup time it takes for the highest priority task that is woken
+up to the time that it executes. This is also known as "schedule
+latency". I stress the point that this is about RT tasks. It is
+also important to know the scheduling latency of non-RT tasks,
+but the average schedule latency is better for non-RT tasks.
+Tools like LatencyTop are more appropriate for such
+measurements.
+
+Real-Time environments are interested in the worst case latency.
+That is the longest latency it takes for something to happen,
+and not the average. We can have a very fast scheduler that may
+only have a large latency once in a while, but that would not
+work well with Real-Time tasks.  The wakeup tracer was designed
+to record the worst case wakeups of RT tasks. Non-RT tasks are
+not recorded because the tracer only records one worst case and
+tracing non-RT tasks that are unpredictable will overwrite the
+worst case latency of RT tasks.
+
+Since this tracer only deals with RT tasks, we will run this
+slightly differently than we did with the previous tracers.
+Instead of performing an 'ls', we will run 'sleep 1' under
+'chrt' which changes the priority of the task.
+
+ # echo wakeup > /debug/tracing/current_tracer
+ # echo 0 > /debug/tracing/tracing_max_latency
+ # echo 1 > /debug/tracing/tracing_enabled
+ # chrt -f 5 sleep 1
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/latency_trace
+# tracer: wakeup
+#
+wakeup latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 4 us, #2/2, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: sleep-4901 (uid:0 nice:0 policy:1 rt_prio:5)
+    -----------------
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+  <idle>-0     1d.h4    0us+: try_to_wake_up (wake_up_process)
+  <idle>-0     1d..4    4us : schedule (cpu_idle)
+
+
+Running this on an idle system, we see that it only took 4
+microseconds to perform the task switch.  Note, since the trace
+marker in the schedule is before the actual "switch", we stop
+the tracing when the recorded task is about to schedule in. This
+may change if we add a new marker at the end of the scheduler.
+
+Notice that the recorded task is 'sleep' with the PID of 4901
+and it has an rt_prio of 5. This priority is user-space priority
+and not the internal kernel priority. The policy is 1 for
+SCHED_FIFO and 2 for SCHED_RR.
+
+Doing the same with chrt -r 5 and ftrace_enabled set.
+
+# tracer: wakeup
+#
+wakeup latency trace v1.1.5 on 2.6.26-rc8
+--------------------------------------------------------------------
+ latency: 50 us, #60/60, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
+    -----------------
+    | task: sleep-4068 (uid:0 nice:0 policy:2 rt_prio:5)
+    -----------------
+
+#                _------=> CPU#
+#               / _-----=> irqs-off
+#              | / _----=> need-resched
+#              || / _---=> hardirq/softirq
+#              ||| / _--=> preempt-depth
+#              |||| /
+#              |||||     delay
+#  cmd     pid ||||| time  |   caller
+#     \   /    |||||   \   |   /
+ksoftirq-7     1d.H3    0us : try_to_wake_up (wake_up_process)
+ksoftirq-7     1d.H4    1us : sub_preempt_count (marker_probe_cb)
+ksoftirq-7     1d.H3    2us : check_preempt_wakeup (try_to_wake_up)
+ksoftirq-7     1d.H3    3us : update_curr (check_preempt_wakeup)
+ksoftirq-7     1d.H3    4us : calc_delta_mine (update_curr)
+ksoftirq-7     1d.H3    5us : __resched_task (check_preempt_wakeup)
+ksoftirq-7     1d.H3    6us : task_wake_up_rt (try_to_wake_up)
+ksoftirq-7     1d.H3    7us : _spin_unlock_irqrestore (try_to_wake_up)
+[...]
+ksoftirq-7     1d.H2   17us : irq_exit (smp_apic_timer_interrupt)
+ksoftirq-7     1d.H2   18us : sub_preempt_count (irq_exit)
+ksoftirq-7     1d.s3   19us : sub_preempt_count (irq_exit)
+ksoftirq-7     1..s2   20us : rcu_process_callbacks (__do_softirq)
+[...]
+ksoftirq-7     1..s2   26us : __rcu_process_callbacks (rcu_process_callbacks)
+ksoftirq-7     1d.s2   27us : _local_bh_enable (__do_softirq)
+ksoftirq-7     1d.s2   28us : sub_preempt_count (_local_bh_enable)
+ksoftirq-7     1.N.3   29us : sub_preempt_count (ksoftirqd)
+ksoftirq-7     1.N.2   30us : _cond_resched (ksoftirqd)
+ksoftirq-7     1.N.2   31us : __cond_resched (_cond_resched)
+ksoftirq-7     1.N.2   32us : add_preempt_count (__cond_resched)
+ksoftirq-7     1.N.2   33us : schedule (__cond_resched)
+ksoftirq-7     1.N.2   33us : add_preempt_count (schedule)
+ksoftirq-7     1.N.3   34us : hrtick_clear (schedule)
+ksoftirq-7     1dN.3   35us : _spin_lock (schedule)
+ksoftirq-7     1dN.3   36us : add_preempt_count (_spin_lock)
+ksoftirq-7     1d..4   37us : put_prev_task_fair (schedule)
+ksoftirq-7     1d..4   38us : update_curr (put_prev_task_fair)
+[...]
+ksoftirq-7     1d..5   47us : _spin_trylock (tracing_record_cmdline)
+ksoftirq-7     1d..5   48us : add_preempt_count (_spin_trylock)
+ksoftirq-7     1d..6   49us : _spin_unlock (tracing_record_cmdline)
+ksoftirq-7     1d..6   49us : sub_preempt_count (_spin_unlock)
+ksoftirq-7     1d..4   50us : schedule (__cond_resched)
+
+The interrupt went off while running ksoftirqd. This task runs
+at SCHED_OTHER. Why did not we see the 'N' set early? This may
+be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K
+stacks configured, the interrupt and softirq run with their own
+stack. Some information is held on the top of the task's stack
+(need_resched and preempt_count are both stored there). The
+setting of the NEED_RESCHED bit is done directly to the task's
+stack, but the reading of the NEED_RESCHED is done by looking at
+the current stack, which in this case is the stack for the hard
+interrupt. This hides the fact that NEED_RESCHED has been set.
+We do not see the 'N' until we switch back to the task's
+assigned stack.
+
+function
+--------
+
+This tracer is the function tracer. Enabling the function tracer
+can be done from the debug file system. Make sure the
+ftrace_enabled is set; otherwise this tracer is a nop.
+
+ # sysctl kernel.ftrace_enabled=1
+ # echo function > /debug/tracing/current_tracer
+ # echo 1 > /debug/tracing/tracing_enabled
+ # usleep 1
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/trace
+# tracer: function
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+            bash-4003  [00]   123.638713: finish_task_switch <-schedule
+            bash-4003  [00]   123.638714: _spin_unlock_irq <-finish_task_switch
+            bash-4003  [00]   123.638714: sub_preempt_count <-_spin_unlock_irq
+            bash-4003  [00]   123.638715: hrtick_set <-schedule
+            bash-4003  [00]   123.638715: _spin_lock_irqsave <-hrtick_set
+            bash-4003  [00]   123.638716: add_preempt_count <-_spin_lock_irqsave
+            bash-4003  [00]   123.638716: _spin_unlock_irqrestore <-hrtick_set
+            bash-4003  [00]   123.638717: sub_preempt_count <-_spin_unlock_irqrestore
+            bash-4003  [00]   123.638717: hrtick_clear <-hrtick_set
+            bash-4003  [00]   123.638718: sub_preempt_count <-schedule
+            bash-4003  [00]   123.638718: sub_preempt_count <-preempt_schedule
+            bash-4003  [00]   123.638719: wait_for_completion <-__stop_machine_run
+            bash-4003  [00]   123.638719: wait_for_common <-wait_for_completion
+            bash-4003  [00]   123.638720: _spin_lock_irq <-wait_for_common
+            bash-4003  [00]   123.638720: add_preempt_count <-_spin_lock_irq
+[...]
+
+
+Note: function tracer uses ring buffers to store the above
+entries. The newest data may overwrite the oldest data.
+Sometimes using echo to stop the trace is not sufficient because
+the tracing could have overwritten the data that you wanted to
+record. For this reason, it is sometimes better to disable
+tracing directly from a program. This allows you to stop the
+tracing at the point that you hit the part that you are
+interested in. To disable the tracing directly from a C program,
+something like following code snippet can be used:
+
+int trace_fd;
+[...]
+int main(int argc, char *argv[]) {
+	[...]
+	trace_fd = open("/debug/tracing/tracing_enabled", O_WRONLY);
+	[...]
+	if (condition_hit()) {
+		write(trace_fd, "0", 1);
+	}
+	[...]
+}
+
+Note: Here we hard coded the path name. The debugfs mount is not
+guaranteed to be at /debug (and is more commonly at
+/sys/kernel/debug). For simple one time traces, the above is
+sufficent. For anything else, a search through /proc/mounts may
+be needed to find where the debugfs file-system is mounted.
+
+
+Single thread tracing
+---------------------
+
+By writing into /debug/tracing/set_ftrace_pid you can trace a
+single thread. For example:
+
+# cat /debug/tracing/set_ftrace_pid
+no pid
+# echo 3111 > /debug/tracing/set_ftrace_pid
+# cat /debug/tracing/set_ftrace_pid
+3111
+# echo function > /debug/tracing/current_tracer
+# cat /debug/tracing/trace | head
+ # tracer: function
+ #
+ #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
+ #              | |       |          |         |
+     yum-updatesd-3111  [003]  1637.254676: finish_task_switch <-thread_return
+     yum-updatesd-3111  [003]  1637.254681: hrtimer_cancel <-schedule_hrtimeout_range
+     yum-updatesd-3111  [003]  1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel
+     yum-updatesd-3111  [003]  1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel
+     yum-updatesd-3111  [003]  1637.254685: fget_light <-do_sys_poll
+     yum-updatesd-3111  [003]  1637.254686: pipe_poll <-do_sys_poll
+# echo -1 > /debug/tracing/set_ftrace_pid
+# cat /debug/tracing/trace |head
+ # tracer: function
+ #
+ #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
+ #              | |       |          |         |
+ ##### CPU 3 buffer started ####
+     yum-updatesd-3111  [003]  1701.957688: free_poll_entry <-poll_freewait
+     yum-updatesd-3111  [003]  1701.957689: remove_wait_queue <-free_poll_entry
+     yum-updatesd-3111  [003]  1701.957691: fput <-free_poll_entry
+     yum-updatesd-3111  [003]  1701.957692: audit_syscall_exit <-sysret_audit
+     yum-updatesd-3111  [003]  1701.957693: path_put <-audit_syscall_exit
+
+If you want to trace a function when executing, you could use
+something like this simple program:
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main (int argc, char **argv)
+{
+        if (argc < 1)
+                exit(-1);
+
+        if (fork() > 0) {
+                int fd, ffd;
+                char line[64];
+                int s;
+
+                ffd = open("/debug/tracing/current_tracer", O_WRONLY);
+                if (ffd < 0)
+                        exit(-1);
+                write(ffd, "nop", 3);
+
+                fd = open("/debug/tracing/set_ftrace_pid", O_WRONLY);
+                s = sprintf(line, "%d\n", getpid());
+                write(fd, line, s);
+
+                write(ffd, "function", 8);
+
+                close(fd);
+                close(ffd);
+
+                execvp(argv[1], argv+1);
+        }
+
+        return 0;
+}
+
+
+hw-branch-tracer (x86 only)
+---------------------------
+
+This tracer uses the x86 last branch tracing hardware feature to
+collect a branch trace on all cpus with relatively low overhead.
+
+The tracer uses a fixed-size circular buffer per cpu and only
+traces ring 0 branches. The trace file dumps that buffer in the
+following format:
+
+# tracer: hw-branch-tracer
+#
+# CPU#        TO  <-  FROM
+   0  scheduler_tick+0xb5/0x1bf	  <-  task_tick_idle+0x5/0x6
+   2  run_posix_cpu_timers+0x2b/0x72a	  <-  run_posix_cpu_timers+0x25/0x72a
+   0  scheduler_tick+0x139/0x1bf	  <-  scheduler_tick+0xed/0x1bf
+   0  scheduler_tick+0x17c/0x1bf	  <-  scheduler_tick+0x148/0x1bf
+   2  run_posix_cpu_timers+0x9e/0x72a	  <-  run_posix_cpu_timers+0x5e/0x72a
+   0  scheduler_tick+0x1b6/0x1bf	  <-  scheduler_tick+0x1aa/0x1bf
+
+
+The tracer may be used to dump the trace for the oops'ing cpu on
+a kernel oops into the system log. To enable this,
+ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
+can either use the sysctl function or set it via the proc system
+interface.
+
+  sysctl kernel.ftrace_dump_on_oops=1
+
+or
+
+  echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
+
+
+Here's an example of such a dump after a null pointer
+dereference in a kernel module:
+
+[57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+[57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0
+[57848.106019] Oops: 0002 [#1] SMP
+[57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus
+[57848.106019] Dumping ftrace buffer:
+[57848.106019] ---------------------------------
+[...]
+[57848.106019]    0  chrdev_open+0xe6/0x165	  <-  cdev_put+0x23/0x24
+[57848.106019]    0  chrdev_open+0x117/0x165	  <-  chrdev_open+0xfa/0x165
+[57848.106019]    0  chrdev_open+0x120/0x165	  <-  chrdev_open+0x11c/0x165
+[57848.106019]    0  chrdev_open+0x134/0x165	  <-  chrdev_open+0x12b/0x165
+[57848.106019]    0  open+0x0/0x14 [oops]	  <-  chrdev_open+0x144/0x165
+[57848.106019]    0  page_fault+0x0/0x30	  <-  open+0x6/0x14 [oops]
+[57848.106019]    0  error_entry+0x0/0x5b	  <-  page_fault+0x4/0x30
+[57848.106019]    0  error_kernelspace+0x0/0x31	  <-  error_entry+0x59/0x5b
+[57848.106019]    0  error_sti+0x0/0x1	  <-  error_kernelspace+0x2d/0x31
+[57848.106019]    0  page_fault+0x9/0x30	  <-  error_sti+0x0/0x1
+[57848.106019]    0  do_page_fault+0x0/0x881	  <-  page_fault+0x1a/0x30
+[...]
+[57848.106019]    0  do_page_fault+0x66b/0x881	  <-  is_prefetch+0x1ee/0x1f2
+[57848.106019]    0  do_page_fault+0x6e0/0x881	  <-  do_page_fault+0x67a/0x881
+[57848.106019]    0  oops_begin+0x0/0x96	  <-  do_page_fault+0x6e0/0x881
+[57848.106019]    0  trace_hw_branch_oops+0x0/0x2d	  <-  oops_begin+0x9/0x96
+[...]
+[57848.106019]    0  ds_suspend_bts+0x2a/0xe3	  <-  ds_suspend_bts+0x1a/0xe3
+[57848.106019] ---------------------------------
+[57848.106019] CPU 0
+[57848.106019] Modules linked in: oops
+[57848.106019] Pid: 5542, comm: cat Tainted: G        W  2.6.28 #23
+[57848.106019] RIP: 0010:[<ffffffffa0000006>]  [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] RSP: 0018:ffff880235457d48  EFLAGS: 00010246
+[...]
+
+
+function graph tracer
+---------------------------
+
+This tracer is similar to the function tracer except that it
+probes a function on its entry and its exit. This is done by
+using a dynamically allocated stack of return addresses in each
+task_struct. On function entry the tracer overwrites the return
+address of each function traced to set a custom probe. Thus the
+original return address is stored on the stack of return address
+in the task_struct.
+
+Probing on both ends of a function leads to special features
+such as:
+
+- measure of a function's time execution
+- having a reliable call stack to draw function calls graph
+
+This tracer is useful in several situations:
+
+- you want to find the reason of a strange kernel behavior and
+  need to see what happens in detail on any areas (or specific
+  ones).
+
+- you are experiencing weird latencies but it's difficult to
+  find its origin.
+
+- you want to find quickly which path is taken by a specific
+  function
+
+- you just want to peek inside a working kernel and want to see
+  what happens there.
+
+# tracer: function_graph
+#
+# CPU  DURATION                  FUNCTION CALLS
+# |     |   |                     |   |   |   |
+
+ 0)               |  sys_open() {
+ 0)               |    do_sys_open() {
+ 0)               |      getname() {
+ 0)               |        kmem_cache_alloc() {
+ 0)   1.382 us    |          __might_sleep();
+ 0)   2.478 us    |        }
+ 0)               |        strncpy_from_user() {
+ 0)               |          might_fault() {
+ 0)   1.389 us    |            __might_sleep();
+ 0)   2.553 us    |          }
+ 0)   3.807 us    |        }
+ 0)   7.876 us    |      }
+ 0)               |      alloc_fd() {
+ 0)   0.668 us    |        _spin_lock();
+ 0)   0.570 us    |        expand_files();
+ 0)   0.586 us    |        _spin_unlock();
+
+
+There are several columns that can be dynamically
+enabled/disabled. You can use every combination of options you
+want, depending on your needs.
+
+- The cpu number on which the function executed is default
+  enabled.  It is sometimes better to only trace one cpu (see
+  tracing_cpu_mask file) or you might sometimes see unordered
+  function calls while cpu tracing switch.
+
+	hide: echo nofuncgraph-cpu > /debug/tracing/trace_options
+	show: echo funcgraph-cpu > /debug/tracing/trace_options
+
+- The duration (function's time of execution) is displayed on
+  the closing bracket line of a function or on the same line
+  than the current function in case of a leaf one. It is default
+  enabled.
+
+	hide: echo nofuncgraph-duration > /debug/tracing/trace_options
+	show: echo funcgraph-duration > /debug/tracing/trace_options
+
+- The overhead field precedes the duration field in case of
+  reached duration thresholds.
+
+	hide: echo nofuncgraph-overhead > /debug/tracing/trace_options
+	show: echo funcgraph-overhead > /debug/tracing/trace_options
+	depends on: funcgraph-duration
+
+  ie:
+
+  0)               |    up_write() {
+  0)   0.646 us    |      _spin_lock_irqsave();
+  0)   0.684 us    |      _spin_unlock_irqrestore();
+  0)   3.123 us    |    }
+  0)   0.548 us    |    fput();
+  0) + 58.628 us   |  }
+
+  [...]
+
+  0)               |      putname() {
+  0)               |        kmem_cache_free() {
+  0)   0.518 us    |          __phys_addr();
+  0)   1.757 us    |        }
+  0)   2.861 us    |      }
+  0) ! 115.305 us  |    }
+  0) ! 116.402 us  |  }
+
+  + means that the function exceeded 10 usecs.
+  ! means that the function exceeded 100 usecs.
+
+
+- The task/pid field displays the thread cmdline and pid which
+  executed the function. It is default disabled.
+
+	hide: echo nofuncgraph-proc > /debug/tracing/trace_options
+	show: echo funcgraph-proc > /debug/tracing/trace_options
+
+  ie:
+
+  # tracer: function_graph
+  #
+  # CPU  TASK/PID        DURATION                  FUNCTION CALLS
+  # |    |    |           |   |                     |   |   |   |
+  0)    sh-4802     |               |                  d_free() {
+  0)    sh-4802     |               |                    call_rcu() {
+  0)    sh-4802     |               |                      __call_rcu() {
+  0)    sh-4802     |   0.616 us    |                        rcu_process_gp_end();
+  0)    sh-4802     |   0.586 us    |                        check_for_new_grace_period();
+  0)    sh-4802     |   2.899 us    |                      }
+  0)    sh-4802     |   4.040 us    |                    }
+  0)    sh-4802     |   5.151 us    |                  }
+  0)    sh-4802     | + 49.370 us   |                }
+
+
+- The absolute time field is an absolute timestamp given by the
+  system clock since it started. A snapshot of this time is
+  given on each entry/exit of functions
+
+	hide: echo nofuncgraph-abstime > /debug/tracing/trace_options
+	show: echo funcgraph-abstime > /debug/tracing/trace_options
+
+  ie:
+
+  #
+  #      TIME       CPU  DURATION                  FUNCTION CALLS
+  #       |         |     |   |                     |   |   |   |
+  360.774522 |   1)   0.541 us    |                                          }
+  360.774522 |   1)   4.663 us    |                                        }
+  360.774523 |   1)   0.541 us    |                                        __wake_up_bit();
+  360.774524 |   1)   6.796 us    |                                      }
+  360.774524 |   1)   7.952 us    |                                    }
+  360.774525 |   1)   9.063 us    |                                  }
+  360.774525 |   1)   0.615 us    |                                  journal_mark_dirty();
+  360.774527 |   1)   0.578 us    |                                  __brelse();
+  360.774528 |   1)               |                                  reiserfs_prepare_for_journal() {
+  360.774528 |   1)               |                                    unlock_buffer() {
+  360.774529 |   1)               |                                      wake_up_bit() {
+  360.774529 |   1)               |                                        bit_waitqueue() {
+  360.774530 |   1)   0.594 us    |                                          __phys_addr();
+
+
+You can put some comments on specific functions by using
+trace_printk() For example, if you want to put a comment inside
+the __might_sleep() function, you just have to include
+<linux/ftrace.h> and call trace_printk() inside __might_sleep()
+
+trace_printk("I'm a comment!\n")
+
+will produce:
+
+ 1)               |             __might_sleep() {
+ 1)               |                /* I'm a comment! */
+ 1)   1.449 us    |             }
+
+
+You might find other useful features for this tracer in the
+following "dynamic ftrace" section such as tracing only specific
+functions or tasks.
+
+dynamic ftrace
+--------------
+
+If CONFIG_DYNAMIC_FTRACE is set, the system will run with
+virtually no overhead when function tracing is disabled. The way
+this works is the mcount function call (placed at the start of
+every kernel function, produced by the -pg switch in gcc),
+starts of pointing to a simple return. (Enabling FTRACE will
+include the -pg switch in the compiling of the kernel.)
+
+At compile time every C file object is run through the
+recordmcount.pl script (located in the scripts directory). This
+script will process the C object using objdump to find all the
+locations in the .text section that call mcount. (Note, only the
+.text section is processed, since processing other sections like
+.init.text may cause races due to those sections being freed).
+
+A new section called "__mcount_loc" is created that holds
+references to all the mcount call sites in the .text section.
+This section is compiled back into the original object. The
+final linker will add all these references into a single table.
+
+On boot up, before SMP is initialized, the dynamic ftrace code
+scans this table and updates all the locations into nops. It
+also records the locations, which are added to the
+available_filter_functions list.  Modules are processed as they
+are loaded and before they are executed.  When a module is
+unloaded, it also removes its functions from the ftrace function
+list. This is automatic in the module unload code, and the
+module author does not need to worry about it.
+
+When tracing is enabled, kstop_machine is called to prevent
+races with the CPUS executing code being modified (which can
+cause the CPU to do undesireable things), and the nops are
+patched back to calls. But this time, they do not call mcount
+(which is just a function stub). They now call into the ftrace
+infrastructure.
+
+One special side-effect to the recording of the functions being
+traced is that we can now selectively choose which functions we
+wish to trace and which ones we want the mcount calls to remain
+as nops.
+
+Two files are used, one for enabling and one for disabling the
+tracing of specified functions. They are:
+
+  set_ftrace_filter
+
+and
+
+  set_ftrace_notrace
+
+A list of available functions that you can add to these files is
+listed in:
+
+   available_filter_functions
+
+ # cat /debug/tracing/available_filter_functions
+put_prev_task_idle
+kmem_cache_create
+pick_next_task_rt
+get_online_cpus
+pick_next_task_fair
+mutex_lock
+[...]
+
+If I am only interested in sys_nanosleep and hrtimer_interrupt:
+
+ # echo sys_nanosleep hrtimer_interrupt \
+		> /debug/tracing/set_ftrace_filter
+ # echo ftrace > /debug/tracing/current_tracer
+ # echo 1 > /debug/tracing/tracing_enabled
+ # usleep 1
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/trace
+# tracer: ftrace
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+          usleep-4134  [00]  1317.070017: hrtimer_interrupt <-smp_apic_timer_interrupt
+          usleep-4134  [00]  1317.070111: sys_nanosleep <-syscall_call
+          <idle>-0     [00]  1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt
+
+To see which functions are being traced, you can cat the file:
+
+ # cat /debug/tracing/set_ftrace_filter
+hrtimer_interrupt
+sys_nanosleep
+
+
+Perhaps this is not enough. The filters also allow simple wild
+cards. Only the following are currently available
+
+  <match>*  - will match functions that begin with <match>
+  *<match>  - will match functions that end with <match>
+  *<match>* - will match functions that have <match> in it
+
+These are the only wild cards which are supported.
+
+  <match>*<match> will not work.
+
+Note: It is better to use quotes to enclose the wild cards,
+      otherwise the shell may expand the parameters into names
+      of files in the local directory.
+
+ # echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
+
+Produces:
+
+# tracer: ftrace
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+            bash-4003  [00]  1480.611794: hrtimer_init <-copy_process
+            bash-4003  [00]  1480.611941: hrtimer_start <-hrtick_set
+            bash-4003  [00]  1480.611956: hrtimer_cancel <-hrtick_clear
+            bash-4003  [00]  1480.611956: hrtimer_try_to_cancel <-hrtimer_cancel
+          <idle>-0     [00]  1480.612019: hrtimer_get_next_event <-get_next_timer_interrupt
+          <idle>-0     [00]  1480.612025: hrtimer_get_next_event <-get_next_timer_interrupt
+          <idle>-0     [00]  1480.612032: hrtimer_get_next_event <-get_next_timer_interrupt
+          <idle>-0     [00]  1480.612037: hrtimer_get_next_event <-get_next_timer_interrupt
+          <idle>-0     [00]  1480.612382: hrtimer_get_next_event <-get_next_timer_interrupt
+
+
+Notice that we lost the sys_nanosleep.
+
+ # cat /debug/tracing/set_ftrace_filter
+hrtimer_run_queues
+hrtimer_run_pending
+hrtimer_init
+hrtimer_cancel
+hrtimer_try_to_cancel
+hrtimer_forward
+hrtimer_start
+hrtimer_reprogram
+hrtimer_force_reprogram
+hrtimer_get_next_event
+hrtimer_interrupt
+hrtimer_nanosleep
+hrtimer_wakeup
+hrtimer_get_remaining
+hrtimer_get_res
+hrtimer_init_sleeper
+
+
+This is because the '>' and '>>' act just like they do in bash.
+To rewrite the filters, use '>'
+To append to the filters, use '>>'
+
+To clear out a filter so that all functions will be recorded
+again:
+
+ # echo > /debug/tracing/set_ftrace_filter
+ # cat /debug/tracing/set_ftrace_filter
+ #
+
+Again, now we want to append.
+
+ # echo sys_nanosleep > /debug/tracing/set_ftrace_filter
+ # cat /debug/tracing/set_ftrace_filter
+sys_nanosleep
+ # echo 'hrtimer_*' >> /debug/tracing/set_ftrace_filter
+ # cat /debug/tracing/set_ftrace_filter
+hrtimer_run_queues
+hrtimer_run_pending
+hrtimer_init
+hrtimer_cancel
+hrtimer_try_to_cancel
+hrtimer_forward
+hrtimer_start
+hrtimer_reprogram
+hrtimer_force_reprogram
+hrtimer_get_next_event
+hrtimer_interrupt
+sys_nanosleep
+hrtimer_nanosleep
+hrtimer_wakeup
+hrtimer_get_remaining
+hrtimer_get_res
+hrtimer_init_sleeper
+
+
+The set_ftrace_notrace prevents those functions from being
+traced.
+
+ # echo '*preempt*' '*lock*' > /debug/tracing/set_ftrace_notrace
+
+Produces:
+
+# tracer: ftrace
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+            bash-4043  [01]   115.281644: finish_task_switch <-schedule
+            bash-4043  [01]   115.281645: hrtick_set <-schedule
+            bash-4043  [01]   115.281645: hrtick_clear <-hrtick_set
+            bash-4043  [01]   115.281646: wait_for_completion <-__stop_machine_run
+            bash-4043  [01]   115.281647: wait_for_common <-wait_for_completion
+            bash-4043  [01]   115.281647: kthread_stop <-stop_machine_run
+            bash-4043  [01]   115.281648: init_waitqueue_head <-kthread_stop
+            bash-4043  [01]   115.281648: wake_up_process <-kthread_stop
+            bash-4043  [01]   115.281649: try_to_wake_up <-wake_up_process
+
+We can see that there's no more lock or preempt tracing.
+
+
+Dynamic ftrace with the function graph tracer
+---------------------------------------------
+
+Although what has been explained above concerns both the
+function tracer and the function-graph-tracer, there are some
+special features only available in the function-graph tracer.
+
+If you want to trace only one function and all of its children,
+you just have to echo its name into set_graph_function:
+
+ echo __do_fault > set_graph_function
+
+will produce the following "expanded" trace of the __do_fault()
+function:
+
+ 0)               |  __do_fault() {
+ 0)               |    filemap_fault() {
+ 0)               |      find_lock_page() {
+ 0)   0.804 us    |        find_get_page();
+ 0)               |        __might_sleep() {
+ 0)   1.329 us    |        }
+ 0)   3.904 us    |      }
+ 0)   4.979 us    |    }
+ 0)   0.653 us    |    _spin_lock();
+ 0)   0.578 us    |    page_add_file_rmap();
+ 0)   0.525 us    |    native_set_pte_at();
+ 0)   0.585 us    |    _spin_unlock();
+ 0)               |    unlock_page() {
+ 0)   0.541 us    |      page_waitqueue();
+ 0)   0.639 us    |      __wake_up_bit();
+ 0)   2.786 us    |    }
+ 0) + 14.237 us   |  }
+ 0)               |  __do_fault() {
+ 0)               |    filemap_fault() {
+ 0)               |      find_lock_page() {
+ 0)   0.698 us    |        find_get_page();
+ 0)               |        __might_sleep() {
+ 0)   1.412 us    |        }
+ 0)   3.950 us    |      }
+ 0)   5.098 us    |    }
+ 0)   0.631 us    |    _spin_lock();
+ 0)   0.571 us    |    page_add_file_rmap();
+ 0)   0.526 us    |    native_set_pte_at();
+ 0)   0.586 us    |    _spin_unlock();
+ 0)               |    unlock_page() {
+ 0)   0.533 us    |      page_waitqueue();
+ 0)   0.638 us    |      __wake_up_bit();
+ 0)   2.793 us    |    }
+ 0) + 14.012 us   |  }
+
+You can also expand several functions at once:
+
+ echo sys_open > set_graph_function
+ echo sys_close >> set_graph_function
+
+Now if you want to go back to trace all functions you can clear
+this special filter via:
+
+ echo > set_graph_function
+
+
+trace_pipe
+----------
+
+The trace_pipe outputs the same content as the trace file, but
+the effect on the tracing is different. Every read from
+trace_pipe is consumed. This means that subsequent reads will be
+different. The trace is live.
+
+ # echo function > /debug/tracing/current_tracer
+ # cat /debug/tracing/trace_pipe > /tmp/trace.out &
+[1] 4153
+ # echo 1 > /debug/tracing/tracing_enabled
+ # usleep 1
+ # echo 0 > /debug/tracing/tracing_enabled
+ # cat /debug/tracing/trace
+# tracer: function
+#
+#           TASK-PID   CPU#    TIMESTAMP  FUNCTION
+#              | |      |          |         |
+
+ #
+ # cat /tmp/trace.out
+            bash-4043  [00] 41.267106: finish_task_switch <-schedule
+            bash-4043  [00] 41.267106: hrtick_set <-schedule
+            bash-4043  [00] 41.267107: hrtick_clear <-hrtick_set
+            bash-4043  [00] 41.267108: wait_for_completion <-__stop_machine_run
+            bash-4043  [00] 41.267108: wait_for_common <-wait_for_completion
+            bash-4043  [00] 41.267109: kthread_stop <-stop_machine_run
+            bash-4043  [00] 41.267109: init_waitqueue_head <-kthread_stop
+            bash-4043  [00] 41.267110: wake_up_process <-kthread_stop
+            bash-4043  [00] 41.267110: try_to_wake_up <-wake_up_process
+            bash-4043  [00] 41.267111: select_task_rq_rt <-try_to_wake_up
+
+
+Note, reading the trace_pipe file will block until more input is
+added. By changing the tracer, trace_pipe will issue an EOF. We
+needed to set the function tracer _before_ we "cat" the
+trace_pipe file.
+
+
+trace entries
+-------------
+
+Having too much or not enough data can be troublesome in
+diagnosing an issue in the kernel. The file buffer_size_kb is
+used to modify the size of the internal trace buffers. The
+number listed is the number of entries that can be recorded per
+CPU. To know the full size, multiply the number of possible CPUS
+with the number of entries.
+
+ # cat /debug/tracing/buffer_size_kb
+1408 (units kilobytes)
+
+Note, to modify this, you must have tracing completely disabled.
+To do that, echo "nop" into the current_tracer. If the
+current_tracer is not set to "nop", an EINVAL error will be
+returned.
+
+ # echo nop > /debug/tracing/current_tracer
+ # echo 10000 > /debug/tracing/buffer_size_kb
+ # cat /debug/tracing/buffer_size_kb
+10000 (units kilobytes)
+
+The number of pages which will be allocated is limited to a
+percentage of available memory. Allocating too much will produce
+an error.
+
+ # echo 1000000000000 > /debug/tracing/buffer_size_kb
+-bash: echo: write error: Cannot allocate memory
+ # cat /debug/tracing/buffer_size_kb
+85
+
+-----------
+
+More details can be found in the source code, in the
+kernel/tracing/*.c files.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/trace/kmemtrace.txt linux-libre-2.6.30-gnu1/Documentation/trace/kmemtrace.txt
--- linux-libre-2.6.29-gnu1/Documentation/trace/kmemtrace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/trace/kmemtrace.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,126 @@
+			kmemtrace - Kernel Memory Tracer
+
+			  by Eduard - Gabriel Munteanu
+			     <eduard.munteanu@linux360.ro>
+
+I. Introduction
+===============
+
+kmemtrace helps kernel developers figure out two things:
+1) how different allocators (SLAB, SLUB etc.) perform
+2) how kernel code allocates memory and how much
+
+To do this, we trace every allocation and export information to the userspace
+through the relay interface. We export things such as the number of requested
+bytes, the number of bytes actually allocated (i.e. including internal
+fragmentation), whether this is a slab allocation or a plain kmalloc() and so
+on.
+
+The actual analysis is performed by a userspace tool (see section III for
+details on where to get it from). It logs the data exported by the kernel,
+processes it and (as of writing this) can provide the following information:
+- the total amount of memory allocated and fragmentation per call-site
+- the amount of memory allocated and fragmentation per allocation
+- total memory allocated and fragmentation in the collected dataset
+- number of cross-CPU allocation and frees (makes sense in NUMA environments)
+
+Moreover, it can potentially find inconsistent and erroneous behavior in
+kernel code, such as using slab free functions on kmalloc'ed memory or
+allocating less memory than requested (but not truly failed allocations).
+
+kmemtrace also makes provisions for tracing on some arch and analysing the
+data on another.
+
+II. Design and goals
+====================
+
+kmemtrace was designed to handle rather large amounts of data. Thus, it uses
+the relay interface to export whatever is logged to userspace, which then
+stores it. Analysis and reporting is done asynchronously, that is, after the
+data is collected and stored. By design, it allows one to log and analyse
+on different machines and different arches.
+
+As of writing this, the ABI is not considered stable, though it might not
+change much. However, no guarantees are made about compatibility yet. When
+deemed stable, the ABI should still allow easy extension while maintaining
+backward compatibility. This is described further in Documentation/ABI.
+
+Summary of design goals:
+	- allow logging and analysis to be done across different machines
+	- be fast and anticipate usage in high-load environments (*)
+	- be reasonably extensible
+	- make it possible for GNU/Linux distributions to have kmemtrace
+	included in their repositories
+
+(*) - one of the reasons Pekka Enberg's original userspace data analysis
+    tool's code was rewritten from Perl to C (although this is more than a
+    simple conversion)
+
+
+III. Quick usage guide
+======================
+
+1) Get a kernel that supports kmemtrace and build it accordingly (i.e. enable
+CONFIG_KMEMTRACE).
+
+2) Get the userspace tool and build it:
+$ git-clone git://repo.or.cz/kmemtrace-user.git		# current repository
+$ cd kmemtrace-user/
+$ ./autogen.sh
+$ ./configure
+$ make
+
+3) Boot the kmemtrace-enabled kernel if you haven't, preferably in the
+'single' runlevel (so that relay buffers don't fill up easily), and run
+kmemtrace:
+# '$' does not mean user, but root here.
+$ mount -t debugfs none /sys/kernel/debug
+$ mount -t proc none /proc
+$ cd path/to/kmemtrace-user/
+$ ./kmemtraced
+Wait a bit, then stop it with CTRL+C.
+$ cat /sys/kernel/debug/kmemtrace/total_overruns	# Check if we didn't
+							# overrun, should
+							# be zero.
+$ (Optionally) [Run kmemtrace_check separately on each cpu[0-9]*.out file to
+		check its correctness]
+$ ./kmemtrace-report
+
+Now you should have a nice and short summary of how the allocator performs.
+
+IV. FAQ and known issues
+========================
+
+Q: 'cat /sys/kernel/debug/kmemtrace/total_overruns' is non-zero, how do I fix
+this? Should I worry?
+A: If it's non-zero, this affects kmemtrace's accuracy, depending on how
+large the number is. You can fix it by supplying a higher
+'kmemtrace.subbufs=N' kernel parameter.
+---
+
+Q: kmemtrace_check reports errors, how do I fix this? Should I worry?
+A: This is a bug and should be reported. It can occur for a variety of
+reasons:
+	- possible bugs in relay code
+	- possible misuse of relay by kmemtrace
+	- timestamps being collected unorderly
+Or you may fix it yourself and send us a patch.
+---
+
+Q: kmemtrace_report shows many errors, how do I fix this? Should I worry?
+A: This is a known issue and I'm working on it. These might be true errors
+in kernel code, which may have inconsistent behavior (e.g. allocating memory
+with kmem_cache_alloc() and freeing it with kfree()). Pekka Enberg pointed
+out this behavior may work with SLAB, but may fail with other allocators.
+
+It may also be due to lack of tracing in some unusual allocator functions.
+
+We don't want bug reports regarding this issue yet.
+---
+
+V. See also
+===========
+
+Documentation/kernel-parameters.txt
+Documentation/ABI/testing/debugfs-kmemtrace
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/trace/mmiotrace.txt linux-libre-2.6.30-gnu1/Documentation/trace/mmiotrace.txt
--- linux-libre-2.6.29-gnu1/Documentation/trace/mmiotrace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/trace/mmiotrace.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,163 @@
+		In-kernel memory-mapped I/O tracing
+
+
+Home page and links to optional user space tools:
+
+	http://nouveau.freedesktop.org/wiki/MmioTrace
+
+MMIO tracing was originally developed by Intel around 2003 for their Fault
+Injection Test Harness. In Dec 2006 - Jan 2007, using the code from Intel,
+Jeff Muizelaar created a tool for tracing MMIO accesses with the Nouveau
+project in mind. Since then many people have contributed.
+
+Mmiotrace was built for reverse engineering any memory-mapped IO device with
+the Nouveau project as the first real user. Only x86 and x86_64 architectures
+are supported.
+
+Out-of-tree mmiotrace was originally modified for mainline inclusion and
+ftrace framework by Pekka Paalanen <pq@iki.fi>.
+
+
+Preparation
+-----------
+
+Mmiotrace feature is compiled in by the CONFIG_MMIOTRACE option. Tracing is
+disabled by default, so it is safe to have this set to yes. SMP systems are
+supported, but tracing is unreliable and may miss events if more than one CPU
+is on-line, therefore mmiotrace takes all but one CPU off-line during run-time
+activation. You can re-enable CPUs by hand, but you have been warned, there
+is no way to automatically detect if you are losing events due to CPUs racing.
+
+
+Usage Quick Reference
+---------------------
+
+$ mount -t debugfs debugfs /debug
+$ echo mmiotrace > /debug/tracing/current_tracer
+$ cat /debug/tracing/trace_pipe > mydump.txt &
+Start X or whatever.
+$ echo "X is up" > /debug/tracing/trace_marker
+$ echo nop > /debug/tracing/current_tracer
+Check for lost events.
+
+
+Usage
+-----
+
+Make sure debugfs is mounted to /debug. If not, (requires root privileges)
+$ mount -t debugfs debugfs /debug
+
+Check that the driver you are about to trace is not loaded.
+
+Activate mmiotrace (requires root privileges):
+$ echo mmiotrace > /debug/tracing/current_tracer
+
+Start storing the trace:
+$ cat /debug/tracing/trace_pipe > mydump.txt &
+The 'cat' process should stay running (sleeping) in the background.
+
+Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
+accesses to areas that are ioremapped while mmiotrace is active.
+
+During tracing you can place comments (markers) into the trace by
+$ echo "X is up" > /debug/tracing/trace_marker
+This makes it easier to see which part of the (huge) trace corresponds to
+which action. It is recommended to place descriptive markers about what you
+do.
+
+Shut down mmiotrace (requires root privileges):
+$ echo nop > /debug/tracing/current_tracer
+The 'cat' process exits. If it does not, kill it by issuing 'fg' command and
+pressing ctrl+c.
+
+Check that mmiotrace did not lose events due to a buffer filling up. Either
+$ grep -i lost mydump.txt
+which tells you exactly how many events were lost, or use
+$ dmesg
+to view your kernel log and look for "mmiotrace has lost events" warning. If
+events were lost, the trace is incomplete. You should enlarge the buffers and
+try again. Buffers are enlarged by first seeing how large the current buffers
+are:
+$ cat /debug/tracing/buffer_size_kb
+gives you a number. Approximately double this number and write it back, for
+instance:
+$ echo 128000 > /debug/tracing/buffer_size_kb
+Then start again from the top.
+
+If you are doing a trace for a driver project, e.g. Nouveau, you should also
+do the following before sending your results:
+$ lspci -vvv > lspci.txt
+$ 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.
+
+
+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
+are not caught, since the mapping always exists and is returned directly.
+
+MMIO accesses are recorded via page faults. Just before __ioremap() returns,
+the mapped pages are marked as not present. Any access to the pages causes a
+fault. The page fault handler calls mmiotrace to handle the fault. Mmiotrace
+marks the page present, sets TF flag to achieve single stepping and exits the
+fault handler. The instruction that faulted is executed and debug trap is
+entered. Here mmiotrace again marks the page as not present. The instruction
+is decoded to get the type of operation (read/write), data width and the value
+read or written. These are stored to the trace log.
+
+Setting the page present in the page fault handler has a race condition on SMP
+machines. During the single stepping other CPUs may run freely on that page
+and events can be missed without a notice. Re-enabling other CPUs during
+tracing is discouraged.
+
+
+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
+end of line. The format for version 20070824 is as follows:
+
+Explanation	Keyword	Space separated arguments
+---------------------------------------------------------------------------
+
+read event	R	width, timestamp, map id, physical, value, PC, PID
+write event	W	width, timestamp, map id, physical, value, PC, PID
+ioremap event	MAP	timestamp, map id, physical, virtual, length, PC, PID
+iounmap event	UNMAP	timestamp, map id, PC, PID
+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
+unk. opcode	UNKNOWN	timestamp, map id, physical, data, PC, PID
+
+Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual
+is a kernel virtual address. Width is the data width in bytes and value is the
+data value. Map id is an arbitrary id number identifying the mapping that was
+used in an operation. PC is the program counter and PID is process id. PC is
+zero if it is not recorded. PID is always zero as tracing MMIO accesses
+originating in user space memory is not yet supported.
+
+For instance, the following awk filter will pass all 32-bit writes that target
+physical addresses in the range [0xfb73ce40, 0xfb800000[
+
+$ awk '/W 4 / { adr=strtonum($5); if (adr >= 0xfb73ce40 &&
+adr < 0xfb800000) print; }'
+
+
+Tools for Developers
+--------------------
+
+The user space tools include utilities for:
+- replacing numeric addresses and values with hardware register names
+- replaying MMIO logs, i.e., re-executing the recorded writes
+
+
diff -druNp linux-libre-2.6.29-gnu1/Documentation/trace/tracepoints.txt linux-libre-2.6.30-gnu1/Documentation/trace/tracepoints.txt
--- linux-libre-2.6.29-gnu1/Documentation/trace/tracepoints.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/trace/tracepoints.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,116 @@
+	             Using the Linux Kernel Tracepoints
+
+			    Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Tracepoints and their use. It
+provides examples of how to insert tracepoints in the kernel and
+connect probe functions to them and provides some examples of probe
+functions.
+
+
+* Purpose of tracepoints
+
+A tracepoint placed in code provides a hook to call a function (probe)
+that you can provide at runtime. A tracepoint can be "on" (a probe is
+connected to it) or "off" (no probe is attached). When a tracepoint is
+"off" it has no effect, except for adding a tiny time penalty
+(checking a condition for a branch) and space penalty (adding a few
+bytes for the function call at the end of the instrumented function
+and adds a data structure in a separate section).  When a tracepoint
+is "on", the function you provide is called each time the tracepoint
+is executed, in the execution context of the caller. When the function
+provided ends its execution, it returns to the caller (continuing from
+the tracepoint site).
+
+You can put tracepoints at important locations in the code. They are
+lightweight hooks that can pass an arbitrary number of parameters,
+which prototypes are described in a tracepoint declaration placed in a
+header file.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+Two elements are required for tracepoints :
+
+- A tracepoint definition, placed in a header file.
+- The tracepoint statement, in C code.
+
+In order to use tracepoints, you should include linux/tracepoint.h.
+
+In include/trace/subsys.h :
+
+#include <linux/tracepoint.h>
+
+DECLARE_TRACE(subsys_eventname,
+	TP_PROTO(int firstarg, struct task_struct *p),
+	TP_ARGS(firstarg, p));
+
+In subsys/file.c (where the tracing statement must be added) :
+
+#include <trace/subsys.h>
+
+DEFINE_TRACE(subsys_eventname);
+
+void somefct(void)
+{
+	...
+	trace_subsys_eventname(arg, task);
+	...
+}
+
+Where :
+- subsys_eventname is an identifier unique to your event
+    - subsys is the name of your subsystem.
+    - eventname is the name of the event to trace.
+
+- TP_PROTO(int firstarg, struct task_struct *p) is the prototype of the
+  function called by this tracepoint.
+
+- TP_ARGS(firstarg, p) are the parameters names, same as found in the
+  prototype.
+
+Connecting a function (probe) to a tracepoint is done by providing a
+probe (function to call) for the specific tracepoint through
+register_trace_subsys_eventname().  Removing a probe is done through
+unregister_trace_subsys_eventname(); it will remove the probe.
+
+tracepoint_synchronize_unregister() must be called before the end of
+the module exit function to make sure there is no caller left using
+the probe. This, and the fact that preemption is disabled around the
+probe call, make sure that probe removal and module unload are safe.
+See the "Probe example" section below for a sample probe module.
+
+The tracepoint mechanism supports inserting multiple instances of the
+same tracepoint, but a single definition must be made of a given
+tracepoint name over all the kernel to make sure no type conflict will
+occur. Name mangling of the tracepoints is done using the prototypes
+to make sure typing is correct. Verification of probe type correctness
+is done at the registration site by the compiler. Tracepoints can be
+put in inline functions, inlined static functions, and unrolled loops
+as well as regular functions.
+
+The naming scheme "subsys_event" is suggested here as a convention
+intended to limit collisions. Tracepoint names are global to the
+kernel: they are considered as being the same whether they are in the
+core kernel image or in modules.
+
+If the tracepoint has to be used in kernel modules, an
+EXPORT_TRACEPOINT_SYMBOL_GPL() or EXPORT_TRACEPOINT_SYMBOL() can be
+used to export the defined tracepoints.
+
+* Probe / tracepoint example
+
+See the example provided in samples/tracepoints
+
+Compile them with your kernel.  They are built during 'make' (not
+'make modules') when CONFIG_SAMPLE_TRACEPOINTS=m.
+
+Run, as root :
+modprobe tracepoint-sample (insmod order is not important)
+modprobe tracepoint-probe-sample
+cat /proc/tracepoint-sample (returns an expected error)
+rmmod tracepoint-sample tracepoint-probe-sample
+dmesg
diff -druNp linux-libre-2.6.29-gnu1/Documentation/tracepoints.txt linux-libre-2.6.30-gnu1/Documentation/tracepoints.txt
--- linux-libre-2.6.29-gnu1/Documentation/tracepoints.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/tracepoints.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,115 +0,0 @@
-	             Using the Linux Kernel Tracepoints
-
-			    Mathieu Desnoyers
-
-
-This document introduces Linux Kernel Tracepoints and their use. It
-provides examples of how to insert tracepoints in the kernel and
-connect probe functions to them and provides some examples of probe
-functions.
-
-
-* Purpose of tracepoints
-
-A tracepoint placed in code provides a hook to call a function (probe)
-that you can provide at runtime. A tracepoint can be "on" (a probe is
-connected to it) or "off" (no probe is attached). When a tracepoint is
-"off" it has no effect, except for adding a tiny time penalty
-(checking a condition for a branch) and space penalty (adding a few
-bytes for the function call at the end of the instrumented function
-and adds a data structure in a separate section).  When a tracepoint
-is "on", the function you provide is called each time the tracepoint
-is executed, in the execution context of the caller. When the function
-provided ends its execution, it returns to the caller (continuing from
-the tracepoint site).
-
-You can put tracepoints at important locations in the code. They are
-lightweight hooks that can pass an arbitrary number of parameters,
-which prototypes are described in a tracepoint declaration placed in a
-header file.
-
-They can be used for tracing and performance accounting.
-
-
-* Usage
-
-Two elements are required for tracepoints :
-
-- A tracepoint definition, placed in a header file.
-- The tracepoint statement, in C code.
-
-In order to use tracepoints, you should include linux/tracepoint.h.
-
-In include/trace/subsys.h :
-
-#include <linux/tracepoint.h>
-
-DECLARE_TRACE(subsys_eventname,
-	TPPROTO(int firstarg, struct task_struct *p),
-	TPARGS(firstarg, p));
-
-In subsys/file.c (where the tracing statement must be added) :
-
-#include <trace/subsys.h>
-
-DEFINE_TRACE(subsys_eventname);
-
-void somefct(void)
-{
-	...
-	trace_subsys_eventname(arg, task);
-	...
-}
-
-Where :
-- subsys_eventname is an identifier unique to your event
-    - subsys is the name of your subsystem.
-    - eventname is the name of the event to trace.
-
-- TPPROTO(int firstarg, struct task_struct *p) is the prototype of the
-  function called by this tracepoint.
-
-- TPARGS(firstarg, p) are the parameters names, same as found in the
-  prototype.
-
-Connecting a function (probe) to a tracepoint is done by providing a
-probe (function to call) for the specific tracepoint through
-register_trace_subsys_eventname().  Removing a probe is done through
-unregister_trace_subsys_eventname(); it will remove the probe.
-
-tracepoint_synchronize_unregister() must be called before the end of
-the module exit function to make sure there is no caller left using
-the probe. This, and the fact that preemption is disabled around the
-probe call, make sure that probe removal and module unload are safe.
-See the "Probe example" section below for a sample probe module.
-
-The tracepoint mechanism supports inserting multiple instances of the
-same tracepoint, but a single definition must be made of a given
-tracepoint name over all the kernel to make sure no type conflict will
-occur. Name mangling of the tracepoints is done using the prototypes
-to make sure typing is correct. Verification of probe type correctness
-is done at the registration site by the compiler. Tracepoints can be
-put in inline functions, inlined static functions, and unrolled loops
-as well as regular functions.
-
-The naming scheme "subsys_event" is suggested here as a convention
-intended to limit collisions. Tracepoint names are global to the
-kernel: they are considered as being the same whether they are in the
-core kernel image or in modules.
-
-If the tracepoint has to be used in kernel modules, an
-EXPORT_TRACEPOINT_SYMBOL_GPL() or EXPORT_TRACEPOINT_SYMBOL() can be
-used to export the defined tracepoints.
-
-* Probe / tracepoint example
-
-See the example provided in samples/tracepoints/src
-
-Compile them with your kernel.
-
-Run, as root :
-modprobe tracepoint-example (insmod order is not important)
-modprobe tracepoint-probe-example
-cat /proc/tracepoint-example (returns an expected error)
-rmmod tracepoint-example tracepoint-probe-example
-dmesg
diff -druNp linux-libre-2.6.29-gnu1/Documentation/tracers/mmiotrace.txt linux-libre-2.6.30-gnu1/Documentation/tracers/mmiotrace.txt
--- linux-libre-2.6.29-gnu1/Documentation/tracers/mmiotrace.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/tracers/mmiotrace.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,163 +0,0 @@
-		In-kernel memory-mapped I/O tracing
-
-
-Home page and links to optional user space tools:
-
-	http://nouveau.freedesktop.org/wiki/MmioTrace
-
-MMIO tracing was originally developed by Intel around 2003 for their Fault
-Injection Test Harness. In Dec 2006 - Jan 2007, using the code from Intel,
-Jeff Muizelaar created a tool for tracing MMIO accesses with the Nouveau
-project in mind. Since then many people have contributed.
-
-Mmiotrace was built for reverse engineering any memory-mapped IO device with
-the Nouveau project as the first real user. Only x86 and x86_64 architectures
-are supported.
-
-Out-of-tree mmiotrace was originally modified for mainline inclusion and
-ftrace framework by Pekka Paalanen <pq@iki.fi>.
-
-
-Preparation
------------
-
-Mmiotrace feature is compiled in by the CONFIG_MMIOTRACE option. Tracing is
-disabled by default, so it is safe to have this set to yes. SMP systems are
-supported, but tracing is unreliable and may miss events if more than one CPU
-is on-line, therefore mmiotrace takes all but one CPU off-line during run-time
-activation. You can re-enable CPUs by hand, but you have been warned, there
-is no way to automatically detect if you are losing events due to CPUs racing.
-
-
-Usage Quick Reference
----------------------
-
-$ mount -t debugfs debugfs /debug
-$ echo mmiotrace > /debug/tracing/current_tracer
-$ cat /debug/tracing/trace_pipe > mydump.txt &
-Start X or whatever.
-$ echo "X is up" > /debug/tracing/trace_marker
-$ echo nop > /debug/tracing/current_tracer
-Check for lost events.
-
-
-Usage
------
-
-Make sure debugfs is mounted to /debug. If not, (requires root privileges)
-$ mount -t debugfs debugfs /debug
-
-Check that the driver you are about to trace is not loaded.
-
-Activate mmiotrace (requires root privileges):
-$ echo mmiotrace > /debug/tracing/current_tracer
-
-Start storing the trace:
-$ cat /debug/tracing/trace_pipe > mydump.txt &
-The 'cat' process should stay running (sleeping) in the background.
-
-Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
-accesses to areas that are ioremapped while mmiotrace is active.
-
-During tracing you can place comments (markers) into the trace by
-$ echo "X is up" > /debug/tracing/trace_marker
-This makes it easier to see which part of the (huge) trace corresponds to
-which action. It is recommended to place descriptive markers about what you
-do.
-
-Shut down mmiotrace (requires root privileges):
-$ echo nop > /debug/tracing/current_tracer
-The 'cat' process exits. If it does not, kill it by issuing 'fg' command and
-pressing ctrl+c.
-
-Check that mmiotrace did not lose events due to a buffer filling up. Either
-$ grep -i lost mydump.txt
-which tells you exactly how many events were lost, or use
-$ dmesg
-to view your kernel log and look for "mmiotrace has lost events" warning. If
-events were lost, the trace is incomplete. You should enlarge the buffers and
-try again. Buffers are enlarged by first seeing how large the current buffers
-are:
-$ cat /debug/tracing/buffer_size_kb
-gives you a number. Approximately double this number and write it back, for
-instance:
-$ echo 128000 > /debug/tracing/buffer_size_kb
-Then start again from the top.
-
-If you are doing a trace for a driver project, e.g. Nouveau, you should also
-do the following before sending your results:
-$ lspci -vvv > lspci.txt
-$ 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.
-
-
-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
-are not caught, since the mapping always exists and is returned directly.
-
-MMIO accesses are recorded via page faults. Just before __ioremap() returns,
-the mapped pages are marked as not present. Any access to the pages causes a
-fault. The page fault handler calls mmiotrace to handle the fault. Mmiotrace
-marks the page present, sets TF flag to achieve single stepping and exits the
-fault handler. The instruction that faulted is executed and debug trap is
-entered. Here mmiotrace again marks the page as not present. The instruction
-is decoded to get the type of operation (read/write), data width and the value
-read or written. These are stored to the trace log.
-
-Setting the page present in the page fault handler has a race condition on SMP
-machines. During the single stepping other CPUs may run freely on that page
-and events can be missed without a notice. Re-enabling other CPUs during
-tracing is discouraged.
-
-
-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
-end of line. The format for version 20070824 is as follows:
-
-Explanation	Keyword	Space separated arguments
----------------------------------------------------------------------------
-
-read event	R	width, timestamp, map id, physical, value, PC, PID
-write event	W	width, timestamp, map id, physical, value, PC, PID
-ioremap event	MAP	timestamp, map id, physical, virtual, length, PC, PID
-iounmap event	UNMAP	timestamp, map id, PC, PID
-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
-unk. opcode	UNKNOWN	timestamp, map id, physical, data, PC, PID
-
-Timestamp is in seconds with decimals. Physical is a PCI bus address, virtual
-is a kernel virtual address. Width is the data width in bytes and value is the
-data value. Map id is an arbitrary id number identifying the mapping that was
-used in an operation. PC is the program counter and PID is process id. PC is
-zero if it is not recorded. PID is always zero as tracing MMIO accesses
-originating in user space memory is not yet supported.
-
-For instance, the following awk filter will pass all 32-bit writes that target
-physical addresses in the range [0xfb73ce40, 0xfb800000[
-
-$ awk '/W 4 / { adr=strtonum($5); if (adr >= 0xfb73ce40 &&
-adr < 0xfb800000) print; }'
-
-
-Tools for Developers
---------------------
-
-The user space tools include utilities for:
-- replacing numeric addresses and values with hardware register names
-- replaying MMIO logs, i.e., re-executing the recorded writes
-
-
diff -druNp linux-libre-2.6.29-gnu1/Documentation/usb/usbmon.txt linux-libre-2.6.30-gnu1/Documentation/usb/usbmon.txt
--- linux-libre-2.6.29-gnu1/Documentation/usb/usbmon.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/usb/usbmon.txt	2009-06-09 23:05:27.000000000 -0400
@@ -229,16 +229,26 @@ struct usbmon_packet {
 	int status;		/* 28: */
 	unsigned int length;	/* 32: Length of data (submitted or actual) */
 	unsigned int len_cap;	/* 36: Delivered length */
-	unsigned char setup[8];	/* 40: Only for Control 'S' */
-};				/* 48 bytes total */
+	union {			/* 40: */
+		unsigned char setup[SETUP_LEN];	/* Only for Control S-type */
+		struct iso_rec {		/* Only for ISO */
+			int error_count;
+			int numdesc;
+		} iso;
+	} s;
+	int interval;		/* 48: Only for Interrupt and ISO */
+	int start_frame;	/* 52: For ISO */
+	unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
+	unsigned int ndesc;	/* 60: Actual number of ISO descriptors */
+};				/* 64 total length */
 
 These events can be received from a character device by reading with read(2),
-with an ioctl(2), or by accessing the buffer with mmap.
+with an ioctl(2), or by accessing the buffer with mmap. However, read(2)
+only returns first 48 bytes for compatibility reasons.
 
 The character device is usually called /dev/usbmonN, where N is the USB bus
 number. Number zero (/dev/usbmon0) is special and means "all buses".
-However, this feature is not implemented yet. Note that specific naming
-policy is set by your Linux distribution.
+Note that specific naming policy is set by your Linux distribution.
 
 If you create /dev/usbmon0 by hand, make sure that it is owned by root
 and has mode 0600. Otherwise, unpriviledged users will be able to snoop
@@ -279,9 +289,10 @@ size is out of [unspecified] bounds for
 This call returns the current size of the buffer in bytes.
 
  MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
+ MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg)
 
-This call waits for events to arrive if none were in the kernel buffer,
-then returns the first event. Its argument is a pointer to the following
+These calls wait for events to arrive if none were in the kernel buffer,
+then return the first event. The argument is a pointer to the following
 structure:
 
 struct mon_get_arg {
@@ -294,6 +305,8 @@ Before the call, hdr, data, and alloc sh
 pointed by hdr contains the next event structure, and the data buffer contains
 the data, if any. The event is removed from the kernel buffer.
 
+The MON_IOCX_GET copies 48 bytes, MON_IOCX_GETX copies 64 bytes.
+
  MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
 
 This ioctl is primarily used when the application accesses the buffer
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/bttv/Insmod-options linux-libre-2.6.30-gnu1/Documentation/video4linux/bttv/Insmod-options
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/bttv/Insmod-options	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/bttv/Insmod-options	2009-06-09 23:05:27.000000000 -0400
@@ -81,16 +81,6 @@ tuner.o
 		pal=[bdgil]	select PAL variant (used for some tuners
 				only, important for the audio carrier).
 
-tvmixer.o
-	registers a mixer device for the TV card's volume/bass/treble
-	controls (requires a i2c audio control chip like the msp3400).
-
-	insmod args:
-		debug=1		print some debug info to the syslog.
-		devnr=n		allocate device #n (0 == /dev/mixer,
-				1 = /dev/mixer1, ...), default is to
-				use the first free one.
-
 tvaudio.o
 	new, experimental module which is supported to provide a single
 	driver for all simple i2c audio control chips (tda/tea*).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/bttv/README linux-libre-2.6.30-gnu1/Documentation/video4linux/bttv/README
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/bttv/README	2013-05-03 18:01:46.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/bttv/README	2013-05-03 16:45:36.000000000 -0400
@@ -59,8 +59,8 @@ If you have some knowledge and spare tim
 yourself (patches very welcome of course...)  You know: The linux
 slogan is "Do it yourself".
 
-There is a mailing list: video4linux-list@redhat.com.
-https://listman.redhat.com/mailman/listinfo/video4linux-list
+There is a mailing list: linux-media@vger.kernel.org
+http://vger.kernel.org/vger-lists.html#linux-media
 
 If you have trouble with some specific TV card, try to ask there
 instead of mailing me directly.  The chance that someone with the
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.bttv linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.bttv
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.bttv	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.bttv	2009-06-09 23:05:27.000000000 -0400
@@ -135,7 +135,7 @@
 134 -> Adlink RTV24
 135 -> DViCO FusionHDTV 5 Lite                             [18ac:d500]
 136 -> Acorp Y878F                                         [9511:1540]
-137 -> Conceptronic CTVFMi v2
+137 -> Conceptronic CTVFMi v2                              [036e:109e]
 138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
 139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
 140 -> Osprey 440                                          [0070:ff07]
@@ -154,3 +154,7 @@
 153 -> PHYTEC VD-012 (bt878)
 154 -> PHYTEC VD-012-X1 (bt878)
 155 -> PHYTEC VD-012-X2 (bt878)
+156 -> IVCE-8784                                           [0000:f050,0001:f050,0002:f050,0003:f050]
+157 -> Geovision GV-800(S) (master)                        [800a:763d]
+158 -> Geovision GV-800(S) (slave)                         [800b:763d,800c:763d,800d:763d]
+159 -> ProVideo PV183                                      [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.cx23885 linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.cx23885
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.cx23885	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.cx23885	2009-06-09 23:05:27.000000000 -0400
@@ -12,3 +12,7 @@
  11 -> DViCO FusionHDTV DVB-T Dual Express                 [18ac:db78]
  12 -> Leadtek Winfast PxDVR3200 H                         [107d:6681]
  13 -> Compro VideoMate E650F                              [185b:e800]
+ 14 -> TurboSight TBS 6920                                 [6920:8888]
+ 15 -> TeVii S470                                          [d470:9022]
+ 16 -> DVBWorld DVB-S2 2005                                [0001:2005]
+ 17 -> NetUP Dual DVB-S2 CI                                [1b55:2a2c]
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.cx88 linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.cx88
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.cx88	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.cx88	2009-06-09 23:05:27.000000000 -0400
@@ -77,3 +77,4 @@
  76 -> SATTRADE ST4200 DVB-S/S2                            [b200:4200]
  77 -> TBS 8910 DVB-S                                      [8910:8888]
  78 -> Prof 6200 DVB-S                                     [b022:3022]
+ 79 -> Terratec Cinergy HT PCI MKII                        [153b:1177]
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.em28xx linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.em28xx
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.em28xx	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.em28xx	2009-06-09 23:05:27.000000000 -0400
@@ -7,12 +7,12 @@
   6 -> Terratec Cinergy 200 USB                 (em2800)
   7 -> Leadtek Winfast USB II                   (em2800)        [0413:6023]
   8 -> Kworld USB2800                           (em2800)
-  9 -> Pinnacle Dazzle DVC 90/DVC 100           (em2820/em2840) [2304:0207,2304:021a]
+  9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,2304:0207,2304:021a]
  10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
  11 -> Terratec Hybrid XS                       (em2880)        [0ccd:0042]
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
- 14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
+ 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
  15 -> V-Gear PocketTV                          (em2800)
  16 -> Hauppauge WinTV HVR 950                  (em2883)        [2040:6513,2040:6517,2040:651b]
  17 -> Pinnacle PCTV HD Pro Stick               (em2880)        [2304:0227]
@@ -30,7 +30,6 @@
  30 -> Videology 20K14XUSB USB2.0               (em2820/em2840)
  31 -> Usbgear VD204v9                          (em2821)
  32 -> Supercomp USB 2.0 TV                     (em2821)
- 33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0  (em2821)
  34 -> Terratec Cinergy A Hybrid XS             (em2860)        [0ccd:004f]
  35 -> Typhoon DVD Maker                        (em2860)
  36 -> NetGMBH Cam                              (em2860)
@@ -58,3 +57,7 @@
  58 -> Compro VideoMate ForYou/Stereo           (em2820/em2840) [185b:2041]
  60 -> Hauppauge WinTV HVR 850                  (em2883)        [2040:651f]
  61 -> Pixelview PlayTV Box 4 USB 2.0           (em2820/em2840)
+ 62 -> Gadmei TVR200                            (em2820/em2840)
+ 63 -> Kaiomy TVnPC U2                          (em2860)        [eb1a:e303]
+ 64 -> Easy Cap Capture DC-60                   (em2860)
+ 65 -> IO-DATA GV-MVP/SZ                        (em2820/em2840) [04bb:0515]
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.saa7134 linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.saa7134
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/CARDLIST.saa7134	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/CARDLIST.saa7134	2009-06-09 23:05:27.000000000 -0400
@@ -153,3 +153,5 @@
 152 -> Asus Tiger Rev:1.00                      [1043:4857]
 153 -> Kworld Plus TV Analog Lite PCI           [17de:7128]
 154 -> Avermedia AVerTV GO 007 FM Plus          [1461:f31d]
+155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
+156 -> Hauppauge WinTV-HVR1110r3                [0070:6707,0070:6709,0070:670a]
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/cx2341x/README.hm12 linux-libre-2.6.30-gnu1/Documentation/video4linux/cx2341x/README.hm12
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/cx2341x/README.hm12	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/cx2341x/README.hm12	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,10 @@ Y, U and V planes. This code assumes fra
 The width of a frame is always 720 pixels, regardless of the actual specified
 width.
 
+If the height is not a multiple of 32 lines, then the captured video is
+missing macroblocks at the end and is unusable. So the height must be a
+multiple of 32.
+
 --------------------------------------------------------------------------
 
 #include <stdio.h>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/gspca.txt linux-libre-2.6.30-gnu1/Documentation/video4linux/gspca.txt
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/gspca.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/gspca.txt	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@ spca561		041e:403b	Creative Webcam Vista
 zc3xx		041e:4051	Creative Live!Cam Notebook Pro (VF0250)
 ov519		041e:4052	Creative Live! VISTA IM
 zc3xx		041e:4053	Creative Live!Cam Video IM
+vc032x		041e:405b	Creative Live! Cam Notebook Ultra (VC0130)
 ov519		041e:405f	Creative Live! VISTA VF0330
 ov519		041e:4060	Creative Live! VISTA VF0350
 ov519		041e:4061	Creative Live! VISTA VF0400
@@ -193,6 +194,7 @@ 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:0111	Aiptek PenCam VGA+
 sunplus		08ca:2008	Aiptek Mini PenCam 2 M
 sunplus		08ca:2010	Aiptek PocketCam 3M
 sunplus		08ca:2016	Aiptek PocketCam 2 Mega
@@ -215,6 +217,7 @@ pac207		093a:2468	PAC207
 pac207		093a:2470	Genius GF112
 pac207		093a:2471	Genius VideoCam ge111
 pac207		093a:2472	Genius VideoCam ge110
+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
@@ -279,6 +282,7 @@ spca561		10fd:7e50	FlyCam Usb 100
 zc3xx		10fd:8050	Typhoon Webshot II USB 300k
 ov534		1415:2000	Sony HD Eye for PS3 (SLEH 00201)
 pac207		145f:013a	Trust WB-1300N
+vc032x		15b8:6001	HP 2.0 Megapixel
 vc032x		15b8:6002	HP 2.0 Megapixel rz406aa
 spca501		1776:501c	Arowana 300K CMOS Camera
 t613		17a1:0128	TASCORP JPEG Webcam, NGS Cyclops
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/pxa_camera.txt linux-libre-2.6.30-gnu1/Documentation/video4linux/pxa_camera.txt
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/pxa_camera.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/pxa_camera.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+                              PXA-Camera Host Driver
+                              ======================
+
+Constraints
+-----------
+  a) Image size for YUV422P format
+     All YUV422P images are enforced to have width x height % 16 = 0.
+     This is due to DMA constraints, which transfers only planes of 8 byte
+     multiples.
+
+
+Global video workflow
+---------------------
+  a) QCI stopped
+     Initialy, the QCI interface is stopped.
+     When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+
+  b) QCI started
+     More buffers can be queued while the QCI is started without halting the
+     capture.  The new buffers are "appended" at the tail of the DMA chain, and
+     smoothly captured one frame after the other.
+
+     Once a buffer is filled in the QCI interface, it is marked as "DONE" and
+     removed from the active buffers list. It can be then requeud or dequeued by
+     userland application.
+
+     Once the last buffer is filled in, the QCI interface stops.
+
+
+DMA usage
+---------
+  a) DMA flow
+     - first buffer queued for capture
+       Once a first buffer is queued for capture, the QCI is started, but data
+       transfer is not started. On "End Of Frame" interrupt, the irq handler
+       starts the DMA chain.
+     - capture of one videobuffer
+       The DMA chain starts transfering data into videobuffer RAM pages.
+       When all pages are transfered, the DMA irq is raised on "ENDINTR" status
+     - finishing one videobuffer
+       The DMA irq handler marks the videobuffer as "done", and removes it from
+       the active running queue
+       Meanwhile, the next videobuffer (if there is one), is transfered by DMA
+     - finishing the last videobuffer
+       On the DMA irq of the last videobuffer, the QCI is stopped.
+
+  b) DMA prepared buffer will have this structure
+
+     +------------+-----+---------------+-----------------+
+     | desc-sg[0] | ... | desc-sg[last] | finisher/linker |
+     +------------+-----+---------------+-----------------+
+
+     This structure is pointed by dma->sg_cpu.
+     The descriptors are used as follows :
+      - desc-sg[i]: i-th descriptor, transfering the i-th sg
+        element to the video buffer scatter gather
+      - finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
+      - linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
+
+     For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
+     "f" stands for finisher and "l" for linker.
+     A typical running chain is :
+
+         Videobuffer 1         Videobuffer 2
+     +---------+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+---+
+                      |    |
+                      +----+
+
+     After the chaining is finished, the chain looks like :
+
+         Videobuffer 1         Videobuffer 2         Videobuffer 3
+     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
+                      |    |                |    |
+                      +----+                +----+
+                                           new_link
+
+  c) DMA hot chaining timeslice issue
+
+     As DMA chaining is done while DMA _is_ running, the linking may be done
+     while the DMA jumps from one Videobuffer to another. On the schema, that
+     would be a problem if the following sequence is encountered :
+
+      - DMA chain is Videobuffer1 + Videobuffer2
+      - pxa_videobuf_queue() is called to queue Videobuffer3
+      - DMA controller finishes Videobuffer2, and DMA stops
+      =>
+         Videobuffer 1         Videobuffer 2
+     +---------+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-^-+
+                      |    |                |
+                      +----+                +-- DMA DDADR loads DDADR_STOP
+
+      - pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
+        replaced by a "linker" to Videobuffer3 (creation of new_link)
+      - pxa_videobuf_queue() finishes
+      - the DMA irq handler is called, which terminates Videobuffer2
+      - Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
+
+         Videobuffer 1         Videobuffer 2         Videobuffer 3
+     +---------+----+---+  +----+----+----+---+  +----+----+----+---+
+     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
+     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
+                      |    |                |    |
+                      +----+                +----+
+                                           new_link
+                                          DMA DDADR still is DDADR_STOP
+
+      - pxa_camera_check_link_miss() is called
+        This checks if the DMA is finished and a buffer is still on the
+        pcdev->capture list. If that's the case, the capture will be restarted,
+        and Videobuffer3 is scheduled on DMA chain.
+      - the DMA irq handler finishes
+
+     Note: if DMA stops just after pxa_camera_check_link_miss() reads DDADR()
+     value, we have the guarantee that the DMA irq handler will be called back
+     when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
+     be called again, to reschedule Videobuffer3.
+
+--
+Author: Robert Jarzmik <robert.jarzmik@free.fr>
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/si470x.txt linux-libre-2.6.30-gnu1/Documentation/video4linux/si470x.txt
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/si470x.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/si470x.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers
 
-Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
 
 
 Information from Silicon Labs
@@ -41,7 +41,7 @@ chips are known to work:
 - 10c4:818a: Silicon Labs USB FM Radio Reference Design
 - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
 - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
-- 10c5:819a: DealExtreme USB Radio
+- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
 
 
 Software
@@ -52,6 +52,7 @@ Testing is usually done with most applic
 - gradio - GTK FM radio tuner
 - kradio - Comfortable Radio Application for KDE
 - radio - ncurses-based radio application
+- mplayer - The Ultimate Movie Player For Linux
 
 There is also a library libv4l, which can be used. It's going to have a function
 for frequency seeking, either by using hardware functionality as in radio-si470x
@@ -69,7 +70,7 @@ Audio Listing
 USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
 also select SND_USB_AUDIO, as this is required to get sound from the radio. For
 listing you have to redirect the sound, for example using one of the following
-commands.
+commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x).
 
 If you just want to test audio (very poor quality):
 cat /dev/dsp1 > /dev/dsp
@@ -80,6 +81,10 @@ sox -2 --endian little -r 96000 -t oss /
 If you use arts try:
 arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
 
+If you use mplayer try:
+mplayer -radio adevice=hw=1.0:arate=96000 \
+	-rawaudio rate=96000 \
+	radio://<frequency>/capture
 
 Module Parameters
 =================
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/v4l2-framework.txt linux-libre-2.6.30-gnu1/Documentation/video4linux/v4l2-framework.txt
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/v4l2-framework.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/v4l2-framework.txt	2009-06-09 23:05:27.000000000 -0400
@@ -47,7 +47,9 @@ All drivers have the following structure
 3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
    /dev/vtxX) and keeping track of device-node specific data.
 
-4) Filehandle-specific structs containing per-filehandle data.
+4) Filehandle-specific structs containing per-filehandle data;
+
+5) video buffer handling.
 
 This is a rough schematic of how it all relates:
 
@@ -82,12 +84,20 @@ You must register the device instance:
 	v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
 
 Registration will initialize the v4l2_device struct and link dev->driver_data
-to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from
-dev (driver name followed by the bus_id, to be precise). You may change the
-name after registration if you want.
+to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived
+from dev (driver name followed by the bus_id, to be precise). If you set it
+up before calling v4l2_device_register then it will be untouched. If dev is
+NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
 
 The first 'dev' argument is normally the struct device pointer of a pci_dev,
-usb_device or platform_device.
+usb_interface or platform_device. It is rare for dev to be NULL, but it happens
+with ISA devices or when one device creates multiple PCI devices, thus making
+it impossible to associate v4l2_dev with a particular parent.
+
+You can also supply a notify() callback that can be called by sub-devices to
+notify you of events. Whether you need to set this depends on the sub-device.
+Any notifications a sub-device supports must be defined in a header in
+include/media/<subdevice>.h.
 
 You unregister with:
 
@@ -95,6 +105,17 @@ You unregister with:
 
 Unregistering will also automatically unregister all subdevs from the device.
 
+If you have a hotpluggable device (e.g. a USB device), then when a disconnect
+happens the parent device becomes invalid. Since v4l2_device has a pointer to
+that parent device it has to be cleared as well to mark that the parent is
+gone. To do this call:
+
+	v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
+This does *not* unregister the subdevs, so you still need to call the
+v4l2_device_unregister() function for that. If your driver is not hotpluggable,
+then there is no need to call v4l2_device_disconnect().
+
 Sometimes you need to iterate over all devices registered by a specific
 driver. This is usually the case if multiple device drivers use the same
 hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
@@ -134,7 +155,7 @@ The recommended approach is as follows:
 
 static atomic_t drv_instance = ATOMIC_INIT(0);
 
-static int __devinit drv_probe(struct pci_dev *dev,
+static int __devinit drv_probe(struct pci_dev *pdev,
 				const struct pci_device_id *pci_id)
 {
 	...
@@ -218,7 +239,7 @@ to add new ops and categories.
 
 A sub-device driver initializes the v4l2_subdev struct using:
 
-	v4l2_subdev_init(subdev, &ops);
+	v4l2_subdev_init(sd, &ops);
 
 Afterwards you need to initialize subdev->name with a unique name and set the
 module owner. This is done for you if you use the i2c helper functions.
@@ -226,7 +247,7 @@ module owner. This is done for you if yo
 A device (bridge) driver needs to register the v4l2_subdev with the
 v4l2_device:
 
-	int err = v4l2_device_register_subdev(device, subdev);
+	int err = v4l2_device_register_subdev(v4l2_dev, sd);
 
 This can fail if the subdev module disappeared before it could be registered.
 After this function was called successfully the subdev->dev field points to
@@ -234,17 +255,17 @@ the v4l2_device.
 
 You can unregister a sub-device using:
 
-	v4l2_device_unregister_subdev(subdev);
+	v4l2_device_unregister_subdev(sd);
 
-Afterwards the subdev module can be unloaded and subdev->dev == NULL.
+Afterwards the subdev module can be unloaded and sd->dev == NULL.
 
 You can call an ops function either directly:
 
-	err = subdev->ops->core->g_chip_ident(subdev, &chip);
+	err = sd->ops->core->g_chip_ident(sd, &chip);
 
 but it is better and easier to use this macro:
 
-	err = v4l2_subdev_call(subdev, core, g_chip_ident, &chip);
+	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
 
 The macro will to the right NULL pointer checks and returns -ENODEV if subdev
 is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
@@ -252,19 +273,19 @@ NULL, or the actual result of the subdev
 
 It is also possible to call all or a subset of the sub-devices:
 
-	v4l2_device_call_all(dev, 0, core, g_chip_ident, &chip);
+	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
 
 Any subdev that does not support this ops is skipped and error results are
 ignored. If you want to check for errors use this:
 
-	err = v4l2_device_call_until_err(dev, 0, core, g_chip_ident, &chip);
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
 
 Any error except -ENOIOCTLCMD will exit the loop with that error. If no
 errors (except -ENOIOCTLCMD) occured, then 0 is returned.
 
 The second argument to both calls is a group ID. If 0, then all subdevs are
 called. If non-zero, then only those whose group ID match that value will
-be called. Before a bridge driver registers a subdev it can set subdev->grp_id
+be called. Before a bridge driver registers a subdev it can set sd->grp_id
 to whatever value it wants (it's 0 by default). This value is owned by the
 bridge driver and the sub-device driver will never modify or use it.
 
@@ -276,6 +297,11 @@ e.g. AUDIO_CONTROLLER and specify that a
 v4l2_device_call_all(). That ensures that it will only go to the subdev
 that needs it.
 
+If the sub-device needs to notify its v4l2_device parent of an event, then
+it can call v4l2_subdev_notify(sd, notification, arg). This macro checks
+whether there is a notify() callback defined and returns -ENODEV if not.
+Otherwise the result of the notify() call is returned.
+
 The advantage of using v4l2_subdev is that it is a generic struct and does
 not contain any knowledge about the underlying hardware. So a driver might
 contain several subdevs that use an I2C bus, but also a subdev that is
@@ -325,32 +351,25 @@ And this to go from an i2c_client to a v
 
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-Finally you need to make a command function to make driver->command()
-call the right subdev_ops functions:
-
-static int subdev_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
-If driver->command is never used then you can leave this out. Eventually the
-driver->command usage should be removed from v4l.
-
 Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback
 is called. This will unregister the sub-device from the bridge driver. It is
 safe to call this even if the sub-device was never registered.
 
+You need to do this because when the bridge driver destroys the i2c adapter
+the remove() callbacks are called of the i2c devices on that adapter.
+After that the corresponding v4l2_subdev structures are invalid, so they
+have to be unregistered first. Calling v4l2_device_unregister_subdev(sd)
+from the remove() callback ensures that this is always done correctly.
+
 
 The bridge driver also has some helper functions it can use:
 
-struct v4l2_subdev *sd = v4l2_i2c_new_subdev(adapter, "module_foo", "chipid", 0x36);
+struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
+	       "module_foo", "chipid", 0x36);
 
 This loads the given module (can be NULL if no module needs to be loaded) and
 calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
-If all goes well, then it registers the subdev with the v4l2_device. It gets
-the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
-that adapdata is set to v4l2_device when you setup the i2c_adapter in your
-driver.
+If all goes well, then it registers the subdev with the v4l2_device.
 
 You can also use v4l2_i2c_new_probed_subdev() which is very similar to
 v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
@@ -358,6 +377,14 @@ that it should probe. Internally it call
 
 Both functions return NULL if something went wrong.
 
+Note that the chipid you pass to v4l2_i2c_new_(probed_)subdev() is usually
+the same as the module name. It allows you to specify a chip variant, e.g.
+"saa7114" or "saa7115". In general though the i2c driver autodetects this.
+The use of chipid is something that needs to be looked at more closely at a
+later date. It differs between i2c drivers and as such can be confusing.
+To see which chip variants are supported you can look in the i2c driver code
+for the i2c_device_id table. This lists all the possibilities.
+
 
 struct video_device
 -------------------
@@ -396,6 +423,15 @@ You should also set these fields:
 - ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
   (highly recommended to use this and it might become compulsory in the
   future!), then set this to your v4l2_ioctl_ops struct.
+- parent: you only set this if v4l2_device was registered with NULL as
+  the parent device struct. This only happens in cases where one hardware
+  device has multiple PCI devices that all share the same v4l2_device core.
+
+  The cx88 driver is an example of this: one core v4l2_device struct, but
+  it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
+  (cx8802). Since the v4l2_device cannot be associated with a particular
+  PCI device it is setup without a parent device. But when the struct
+  video_device is setup you do know which parent PCI device to use.
 
 If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
 .ioctl to video_ioctl2 in your v4l2_file_operations struct.
@@ -499,8 +535,8 @@ There are a few useful helper functions:
 
 You can set/get driver private data in the video_device struct using:
 
-void *video_get_drvdata(struct video_device *dev);
-void video_set_drvdata(struct video_device *dev, void *data);
+void *video_get_drvdata(struct video_device *vdev);
+void video_set_drvdata(struct video_device *vdev, void *data);
 
 Note that you can safely call video_set_drvdata() before calling
 video_register_device().
@@ -519,3 +555,103 @@ void *video_drvdata(struct file *file);
 You can go from a video_device struct to the v4l2_device struct using:
 
 struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
+
+video buffer helper functions
+-----------------------------
+
+The v4l2 core API provides a standard method for dealing with video
+buffers. Those methods allow a driver to implement read(), mmap() and
+overlay() on a consistent way.
+
+There are currently methods for using video buffers on devices that
+supports DMA with scatter/gather method (videobuf-dma-sg), DMA with
+linear access (videobuf-dma-contig), and vmalloced buffers, mostly
+used on USB drivers (videobuf-vmalloc).
+
+Any driver using videobuf should provide operations (callbacks) for
+four handlers:
+
+ops->buf_setup   - calculates the size of the video buffers and avoid they
+		   to waste more than some maximum limit of RAM;
+ops->buf_prepare - fills the video buffer structs and calls
+		   videobuf_iolock() to alloc and prepare mmaped memory;
+ops->buf_queue   - advices the driver that another buffer were
+		   requested (by read() or by QBUF);
+ops->buf_release - frees any buffer that were allocated.
+
+In order to use it, the driver need to have a code (generally called at
+interrupt context) that will properly handle the buffer request lists,
+announcing that a new buffer were filled.
+
+The irq handling code should handle the videobuf task lists, in order
+to advice videobuf that a new frame were filled, in order to honor to a
+request. The code is generally like this one:
+	if (list_empty(&dma_q->active))
+		return;
+
+	buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue);
+
+	if (!waitqueue_active(&buf->vb.done))
+		return;
+
+	/* Some logic to handle the buf may be needed here */
+
+	list_del(&buf->vb.queue);
+	do_gettimeofday(&buf->vb.ts);
+	wake_up(&buf->vb.done);
+
+Those are the videobuffer functions used on drivers, implemented on
+videobuf-core:
+
+- Videobuf init functions
+  videobuf_queue_sg_init()
+      Initializes the videobuf infrastructure. This function should be
+      called before any other videobuf function on drivers that uses DMA
+      Scatter/Gather buffers.
+
+  videobuf_queue_dma_contig_init
+      Initializes the videobuf infrastructure. This function should be
+      called before any other videobuf function on drivers that need DMA
+      contiguous buffers.
+
+  videobuf_queue_vmalloc_init()
+      Initializes the videobuf infrastructure. This function should be
+      called before any other videobuf function on USB (and other drivers)
+      that need a vmalloced type of videobuf.
+
+- videobuf_iolock()
+  Prepares the videobuf memory for the proper method (read, mmap, overlay).
+
+- videobuf_queue_is_busy()
+  Checks if a videobuf is streaming.
+
+- videobuf_queue_cancel()
+  Stops video handling.
+
+- videobuf_mmap_free()
+  frees mmap buffers.
+
+- videobuf_stop()
+  Stops video handling, ends mmap and frees mmap and other buffers.
+
+- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls:
+   videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(),
+   videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff().
+
+- V4L1 api function (corresponds to VIDIOCMBUF ioctl):
+   videobuf_cgmbuf()
+      This function is used to provide backward compatibility with V4L1
+      API.
+
+- Some help functions for read()/poll() operations:
+   videobuf_read_stream()
+      For continuous stream read()
+   videobuf_read_one()
+      For snapshot read()
+   videobuf_poll_stream()
+      polling help function
+
+The better way to understand it is to take a look at vivi driver. One
+of the main reasons for vivi is to be a videobuf usage example. the
+vivi_thread_tick() does the task that the IRQ callback would do on PCI
+drivers (or the irq callback on USB).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/v4lgrab.c linux-libre-2.6.30-gnu1/Documentation/video4linux/v4lgrab.c
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/v4lgrab.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/v4lgrab.c	2009-06-09 23:05:27.000000000 -0400
@@ -105,8 +105,8 @@ int main(int argc, char ** argv)
   struct video_picture vpic;
 
   unsigned char *buffer, *src;
-  int bpp = 24, r, g, b;
-  unsigned int i, src_depth;
+  int bpp = 24, r = 0, g = 0, b = 0;
+  unsigned int i, src_depth = 16;
 
   if (fd < 0) {
     perror(VIDEO_DEV);
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/Zoran linux-libre-2.6.30-gnu1/Documentation/video4linux/Zoran
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/Zoran	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/Zoran	2009-06-09 23:05:27.000000000 -0400
@@ -401,8 +401,7 @@ Additional notes for software developers
    first set the correct norm. Well, it seems logically correct: TV
    standard is "more constant" for current country than geometry
    settings of a variety of TV capture cards which may work in ITU or
-   square pixel format. Remember that users now can lock the norm to
-   avoid any ambiguity.
+   square pixel format.
 --
 Please note that lavplay/lavrec are also included in the MJPEG-tools
 (http://mjpeg.sf.net/).
diff -druNp linux-libre-2.6.29-gnu1/Documentation/video4linux/zr364xx.txt linux-libre-2.6.30-gnu1/Documentation/video4linux/zr364xx.txt
--- linux-libre-2.6.29-gnu1/Documentation/video4linux/zr364xx.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/video4linux/zr364xx.txt	2009-06-09 23:05:27.000000000 -0400
@@ -65,3 +65,4 @@ Vendor  Product  Distributor     Model
 0x06d6  0x003b   Trust           Powerc@m 970Z
 0x0a17  0x004e   Pentax          Optio 50
 0x041e  0x405d   Creative        DiVi CAM 516
+0x08ca  0x2102   Aiptek          DV T300
diff -druNp linux-libre-2.6.29-gnu1/Documentation/vm/00-INDEX linux-libre-2.6.30-gnu1/Documentation/vm/00-INDEX
--- linux-libre-2.6.29-gnu1/Documentation/vm/00-INDEX	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/vm/00-INDEX	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,7 @@
 00-INDEX
 	- this file.
+active_mm.txt
+	- An explanation from Linus about tsk->active_mm vs tsk->mm.
 balance
 	- various information on memory balancing.
 hugetlbpage.txt
diff -druNp linux-libre-2.6.29-gnu1/Documentation/vm/active_mm.txt linux-libre-2.6.30-gnu1/Documentation/vm/active_mm.txt
--- linux-libre-2.6.29-gnu1/Documentation/vm/active_mm.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/vm/active_mm.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,83 @@
+List:       linux-kernel
+Subject:    Re: active_mm
+From:       Linus Torvalds <torvalds () transmeta ! com>
+Date:       1999-07-30 21:36:24
+
+Cc'd to linux-kernel, because I don't write explanations all that often,
+and when I do I feel better about more people reading them.
+
+On Fri, 30 Jul 1999, David Mosberger wrote:
+>
+> Is there a brief description someplace on how "mm" vs. "active_mm" in
+> the task_struct are supposed to be used?  (My apologies if this was
+> discussed on the mailing lists---I just returned from vacation and
+> wasn't able to follow linux-kernel for a while).
+
+Basically, the new setup is:
+
+ - we have "real address spaces" and "anonymous address spaces". The
+   difference is that an anonymous address space doesn't care about the
+   user-level page tables at all, so when we do a context switch into an
+   anonymous address space we just leave the previous address space
+   active.
+
+   The obvious use for a "anonymous address space" is any thread that
+   doesn't need any user mappings - all kernel threads basically fall into
+   this category, but even "real" threads can temporarily say that for
+   some amount of time they are not going to be interested in user space,
+   and that the scheduler might as well try to avoid wasting time on
+   switching the VM state around. Currently only the old-style bdflush
+   sync does that.
+
+ - "tsk->mm" points to the "real address space". For an anonymous process,
+   tsk->mm will be NULL, for the logical reason that an anonymous process
+   really doesn't _have_ a real address space at all.
+
+ - however, we obviously need to keep track of which address space we
+   "stole" for such an anonymous user. For that, we have "tsk->active_mm",
+   which shows what the currently active address space is.
+
+   The rule is that for a process with a real address space (ie tsk->mm is
+   non-NULL) the active_mm obviously always has to be the same as the real
+   one.
+
+   For a anonymous process, tsk->mm == NULL, and tsk->active_mm is the
+   "borrowed" mm while the anonymous process is running. When the
+   anonymous process gets scheduled away, the borrowed address space is
+   returned and cleared.
+
+To support all that, the "struct mm_struct" now has two counters: a
+"mm_users" counter that is how many "real address space users" there are,
+and a "mm_count" counter that is the number of "lazy" users (ie anonymous
+users) plus one if there are any real users.
+
+Usually there is at least one real user, but it could be that the real
+user exited on another CPU while a lazy user was still active, so you do
+actually get cases where you have a address space that is _only_ used by
+lazy users. That is often a short-lived state, because once that thread
+gets scheduled away in favour of a real thread, the "zombie" mm gets
+released because "mm_users" becomes zero.
+
+Also, a new rule is that _nobody_ ever has "init_mm" as a real MM any
+more. "init_mm" should be considered just a "lazy context when no other
+context is available", and in fact it is mainly used just at bootup when
+no real VM has yet been created. So code that used to check
+
+	if (current->mm == &init_mm)
+
+should generally just do
+
+	if (!current->mm)
+
+instead (which makes more sense anyway - the test is basically one of "do
+we have a user context", and is generally done by the page fault handler
+and things like that).
+
+Anyway, I put a pre-patch-2.3.13-1 on ftp.kernel.org just a moment ago,
+because it slightly changes the interfaces to accomodate the alpha (who
+would have thought it, but the alpha actually ends up having one of the
+ugliest context switch codes - unlike the other architectures where the MM
+and register state is separate, the alpha PALcode joins the two, and you
+need to switch both together).
+
+(From http://marc.info/?l=linux-kernel&m=93337278602211&w=2)
diff -druNp linux-libre-2.6.29-gnu1/Documentation/vm/numa_memory_policy.txt linux-libre-2.6.30-gnu1/Documentation/vm/numa_memory_policy.txt
--- linux-libre-2.6.29-gnu1/Documentation/vm/numa_memory_policy.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/vm/numa_memory_policy.txt	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,8 @@ The current memory policy support was ad
 document attempts to describe the concepts and APIs of the 2.6 memory policy
 support.
 
-Memory policies should not be confused with cpusets (Documentation/cpusets.txt)
+Memory policies should not be confused with cpusets
+(Documentation/cgroups/cpusets.txt)
 which is an administrative mechanism for restricting the nodes from which
 memory may be allocated by a set of processes. Memory policies are a
 programming interface that a NUMA-aware application can take advantage of.  When
diff -druNp linux-libre-2.6.29-gnu1/Documentation/vm/page_migration linux-libre-2.6.30-gnu1/Documentation/vm/page_migration
--- linux-libre-2.6.29-gnu1/Documentation/vm/page_migration	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/vm/page_migration	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,8 @@ locations.
 
 Larger installations usually partition the system using cpusets into
 sections of nodes. Paul Jackson has equipped cpusets with the ability to
-move pages when a task is moved to another cpuset (See ../cpusets.txt).
+move pages when a task is moved to another cpuset (See
+Documentation/cgroups/cpusets.txt).
 Cpusets allows the automation of process locality. If a task is moved to
 a new cpuset then also all its pages are moved with it so that the
 performance of the process does not sink dramatically. Also the pages
diff -druNp linux-libre-2.6.29-gnu1/Documentation/vm/unevictable-lru.txt linux-libre-2.6.30-gnu1/Documentation/vm/unevictable-lru.txt
--- linux-libre-2.6.29-gnu1/Documentation/vm/unevictable-lru.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/vm/unevictable-lru.txt	2009-06-09 23:05:27.000000000 -0400
@@ -1,588 +1,691 @@
+			==============================
+			UNEVICTABLE LRU INFRASTRUCTURE
+			==============================
 
-This document describes the Linux memory management "Unevictable LRU"
-infrastructure and the use of this infrastructure to manage several types
-of "unevictable" pages.  The document attempts to provide the overall
-rationale behind this mechanism and the rationale for some of the design
-decisions that drove the implementation.  The latter design rationale is
-discussed in the context of an implementation description.  Admittedly, one
-can obtain the implementation details--the "what does it do?"--by reading the
-code.  One hopes that the descriptions below add value by provide the answer
-to "why does it do that?".
+========
+CONTENTS
+========
 
-Unevictable LRU Infrastructure:
+ (*) The Unevictable LRU
 
-The Unevictable LRU adds an additional LRU list to track unevictable pages
-and to hide these pages from vmscan.  This mechanism is based on a patch by
-Larry Woodman of Red Hat to address several scalability problems with page
+     - The unevictable page list.
+     - Memory control group interaction.
+     - Marking address spaces unevictable.
+     - Detecting Unevictable Pages.
+     - vmscan's handling of unevictable pages.
+
+ (*) mlock()'d pages.
+
+     - History.
+     - Basic management.
+     - mlock()/mlockall() system call handling.
+     - Filtering special vmas.
+     - munlock()/munlockall() system call handling.
+     - Migrating mlocked pages.
+     - mmap(MAP_LOCKED) system call handling.
+     - munmap()/exit()/exec() system call handling.
+     - try_to_unmap().
+     - try_to_munlock() reverse map scan.
+     - Page reclaim in shrink_*_list().
+
+
+============
+INTRODUCTION
+============
+
+This document describes the Linux memory manager's "Unevictable LRU"
+infrastructure and the use of this to manage several types of "unevictable"
+pages.
+
+The document attempts to provide the overall rationale behind this mechanism
+and the rationale for some of the design decisions that drove the
+implementation.  The latter design rationale is discussed in the context of an
+implementation description.  Admittedly, one can obtain the implementation
+details - the "what does it do?" - by reading the code.  One hopes that the
+descriptions below add value by provide the answer to "why does it do that?".
+
+
+===================
+THE UNEVICTABLE LRU
+===================
+
+The Unevictable LRU facility adds an additional LRU list to track unevictable
+pages and to hide these pages from vmscan.  This mechanism is based on a patch
+by Larry Woodman of Red Hat to address several scalability problems with page
 reclaim in Linux.  The problems have been observed at customer sites on large
-memory x86_64 systems.  For example, a non-numal x86_64 platform with 128GB
-of main memory will have over 32 million 4k pages in a single zone.  When a
-large fraction of these pages are not evictable for any reason [see below],
-vmscan will spend a lot of time scanning the LRU lists looking for the small
-fraction of pages that are evictable.  This can result in a situation where
-all cpus are spending 100% of their time in vmscan for hours or days on end,
-with the system completely unresponsive.
+memory x86_64 systems.
 
-The Unevictable LRU infrastructure addresses the following classes of
-unevictable pages:
+To illustrate this with an example, a non-NUMA x86_64 platform with 128GB of
+main memory will have over 32 million 4k pages in a single zone.  When a large
+fraction of these pages are not evictable for any reason [see below], vmscan
+will spend a lot of time scanning the LRU lists looking for the small fraction
+of pages that are evictable.  This can result in a situation where all CPUs are
+spending 100% of their time in vmscan for hours or days on end, with the system
+completely unresponsive.
 
-+ page owned by ramfs
-+ page mapped into SHM_LOCKed shared memory regions
-+ page mapped into VM_LOCKED [mlock()ed] vmas
+The unevictable list addresses the following classes of unevictable pages:
 
-The infrastructure might be able to handle other conditions that make pages
+ (*) Those owned by ramfs.
+
+ (*) Those mapped into SHM_LOCK'd shared memory regions.
+
+ (*) Those mapped into VM_LOCKED [mlock()ed] VMAs.
+
+The infrastructure may also be able to handle other conditions that make pages
 unevictable, either by definition or by circumstance, in the future.
 
 
-The Unevictable LRU List
+THE UNEVICTABLE PAGE LIST
+-------------------------
 
 The Unevictable LRU infrastructure consists of an additional, per-zone, LRU list
 called the "unevictable" list and an associated page flag, PG_unevictable, to
-indicate that the page is being managed on the unevictable list.  The
-PG_unevictable flag is analogous to, and mutually exclusive with, the PG_active
-flag in that it indicates on which LRU list a page resides when PG_lru is set.
-The unevictable LRU list is source configurable based on the UNEVICTABLE_LRU
-Kconfig option.
+indicate that the page is being managed on the unevictable list.
+
+The PG_unevictable flag is analogous to, and mutually exclusive with, the
+PG_active flag in that it indicates on which LRU list a page resides when
+PG_lru is set.  The unevictable list is compile-time configurable based on the
+UNEVICTABLE_LRU Kconfig option.
 
 The Unevictable LRU infrastructure maintains unevictable pages on an additional
 LRU list for a few reasons:
 
-1) We get to "treat unevictable pages just like we treat other pages in the
-   system, which means we get to use the same code to manipulate them, the
-   same code to isolate them (for migrate, etc.), the same code to keep track
-   of the statistics, etc..." [Rik van Riel]
+ (1) We get to "treat unevictable pages just like we treat other pages in the
+     system - which means we get to use the same code to manipulate them, the
+     same code to isolate them (for migrate, etc.), the same code to keep track
+     of the statistics, etc..." [Rik van Riel]
 
-2) We want to be able to migrate unevictable pages between nodes--for memory
-   defragmentation, workload management and memory hotplug.  The linux kernel
-   can only migrate pages that it can successfully isolate from the lru lists.
-   If we were to maintain pages elsewise than on an lru-like list, where they
-   can be found by isolate_lru_page(), we would prevent their migration, unless
-   we reworked migration code to find the unevictable pages.
+ (2) We want to be able to migrate unevictable pages between nodes for memory
+     defragmentation, workload management and memory hotplug.  The linux kernel
+     can only migrate pages that it can successfully isolate from the LRU
+     lists.  If we were to maintain pages elsewhere than on an LRU-like list,
+     where they can be found by isolate_lru_page(), we would prevent their
+     migration, unless we reworked migration code to find the unevictable pages
+     itself.
 
 
-The unevictable LRU list does not differentiate between file backed and swap
-backed [anon] pages.  This differentiation is only important while the pages
-are, in fact, evictable.
+The unevictable list does not differentiate between file-backed and anonymous,
+swap-backed pages.  This differentiation is only important while the pages are,
+in fact, evictable.
 
-The unevictable LRU list benefits from the "arrayification" of the per-zone
-LRU lists and statistics originally proposed and posted by Christoph Lameter.
+The unevictable list benefits from the "arrayification" of the per-zone LRU
+lists and statistics originally proposed and posted by Christoph Lameter.
 
-The unevictable list does not use the lru pagevec mechanism. Rather,
-unevictable pages are placed directly on the page's zone's unevictable
-list under the zone lru_lock.  The reason for this is to prevent stranding
-of pages on the unevictable list when one task has the page isolated from the
-lru and other tasks are changing the "evictability" state of the page.
+The unevictable list does not use the LRU pagevec mechanism. Rather,
+unevictable pages are placed directly on the page's zone's unevictable list
+under the zone lru_lock.  This allows us to prevent the stranding of pages on
+the unevictable list when one task has the page isolated from the LRU and other
+tasks are changing the "evictability" state of the page.
 
 
-Unevictable LRU and Memory Controller Interaction
+MEMORY CONTROL GROUP INTERACTION
+--------------------------------
+
+The unevictable LRU facility interacts with the memory control group [aka
+memory controller; see Documentation/cgroups/memory.txt] by extending the
+lru_list enum.
+
+The memory controller data structure automatically gets a per-zone unevictable
+list as a result of the "arrayification" of the per-zone LRU lists (one per
+lru_list enum element).  The memory controller tracks the movement of pages to
+and from the unevictable list.
 
-The memory controller data structure automatically gets a per zone unevictable
-lru list as a result of the "arrayification" of the per-zone LRU lists.  The
-memory controller tracks the movement of pages to and from the unevictable list.
 When a memory control group comes under memory pressure, the controller will
 not attempt to reclaim pages on the unevictable list.  This has a couple of
-effects.  Because the pages are "hidden" from reclaim on the unevictable list,
-the reclaim process can be more efficient, dealing only with pages that have
-a chance of being reclaimed.  On the other hand, if too many of the pages
-charged to the control group are unevictable, the evictable portion of the
-working set of the tasks in the control group may not fit into the available
-memory.  This can cause the control group to thrash or to oom-kill tasks.
+effects:
 
+ (1) Because the pages are "hidden" from reclaim on the unevictable list, the
+     reclaim process can be more efficient, dealing only with pages that have a
+     chance of being reclaimed.
 
-Unevictable LRU:  Detecting Unevictable Pages
+ (2) On the other hand, if too many of the pages charged to the control group
+     are unevictable, the evictable portion of the working set of the tasks in
+     the control group may not fit into the available memory.  This can cause
+     the control group to thrash or to OOM-kill tasks.
 
-The function page_evictable(page, vma) in vmscan.c determines whether a
-page is evictable or not.  For ramfs pages and pages in SHM_LOCKed regions,
-page_evictable() tests a new address space flag, AS_UNEVICTABLE, in the page's
-address space using a wrapper function.  Wrapper functions are used to set,
-clear and test the flag to reduce the requirement for #ifdef's throughout the
-source code.  AS_UNEVICTABLE is set on ramfs inode/mapping when it is created.
-This flag remains for the life of the inode.
 
-For shared memory regions, AS_UNEVICTABLE is set when an application
-successfully SHM_LOCKs the region and is removed when the region is
-SHM_UNLOCKed.  Note that shmctl(SHM_LOCK, ...) does not populate the page
-tables for the region as does, for example, mlock().   So, we make no special
-effort to push any pages in the SHM_LOCKed region to the unevictable list.
-Vmscan will do this when/if it encounters the pages during reclaim.  On
-SHM_UNLOCK, shmctl() scans the pages in the region and "rescues" them from the
-unevictable list if no other condition keeps them unevictable.  If a SHM_LOCKed
-region is destroyed, the pages are also "rescued" from the unevictable list in
-the process of freeing them.
+MARKING ADDRESS SPACES UNEVICTABLE
+----------------------------------
 
-page_evictable() detects mlock()ed pages by testing an additional page flag,
-PG_mlocked via the PageMlocked() wrapper.  If the page is NOT mlocked, and a
-non-NULL vma is supplied, page_evictable() will check whether the vma is
+For facilities such as ramfs none of the pages attached to the address space
+may be evicted.  To prevent eviction of any such pages, the AS_UNEVICTABLE
+address space flag is provided, and this can be manipulated by a filesystem
+using a number of wrapper functions:
+
+ (*) void mapping_set_unevictable(struct address_space *mapping);
+
+	Mark the address space as being completely unevictable.
+
+ (*) void mapping_clear_unevictable(struct address_space *mapping);
+
+	Mark the address space as being evictable.
+
+ (*) int mapping_unevictable(struct address_space *mapping);
+
+	Query the address space, and return true if it is completely
+	unevictable.
+
+These are currently used in two places in the kernel:
+
+ (1) By ramfs to mark the address spaces of its inodes when they are created,
+     and this mark remains for the life of the inode.
+
+ (2) By SYSV SHM to mark SHM_LOCK'd address spaces until SHM_UNLOCK is called.
+
+     Note that SHM_LOCK is not required to page in the locked pages if they're
+     swapped out; the application must touch the pages manually if it wants to
+     ensure they're in memory.
+
+
+DETECTING UNEVICTABLE PAGES
+---------------------------
+
+The function page_evictable() in vmscan.c determines whether a page is
+evictable or not using the query function outlined above [see section "Marking
+address spaces unevictable"] to check the AS_UNEVICTABLE flag.
+
+For address spaces that are so marked after being populated (as SHM regions
+might be), the lock action (eg: SHM_LOCK) can be lazy, and need not populate
+the page tables for the region as does, for example, mlock(), nor need it make
+any special effort to push any pages in the SHM_LOCK'd area to the unevictable
+list.  Instead, vmscan will do this if and when it encounters the pages during
+a reclamation scan.
+
+On an unlock action (such as SHM_UNLOCK), the unlocker (eg: shmctl()) must scan
+the pages in the region and "rescue" them from the unevictable list if no other
+condition is keeping them unevictable.  If an unevictable region is destroyed,
+the pages are also "rescued" from the unevictable list in the process of
+freeing them.
+
+page_evictable() also checks for mlocked pages by testing an additional page
+flag, PG_mlocked (as wrapped by PageMlocked()).  If the page is NOT mlocked,
+and a non-NULL VMA is supplied, page_evictable() will check whether the VMA is
 VM_LOCKED via is_mlocked_vma().  is_mlocked_vma() will SetPageMlocked() and
 update the appropriate statistics if the vma is VM_LOCKED.  This method allows
 efficient "culling" of pages in the fault path that are being faulted in to
-VM_LOCKED vmas.
+VM_LOCKED VMAs.
 
 
-Unevictable Pages and Vmscan [shrink_*_list()]
+VMSCAN'S HANDLING OF UNEVICTABLE PAGES
+--------------------------------------
 
 If unevictable pages are culled in the fault path, or moved to the unevictable
-list at mlock() or mmap() time, vmscan will never encounter the pages until
-they have become evictable again, for example, via munlock() and have been
-"rescued" from the unevictable list.  However, there may be situations where we
-decide, for the sake of expediency, to leave a unevictable page on one of the
-regular active/inactive LRU lists for vmscan to deal with.  Vmscan checks for
-such pages in all of the shrink_{active|inactive|page}_list() functions and
-will "cull" such pages that it encounters--that is, it diverts those pages to
-the unevictable list for the zone being scanned.
+list at mlock() or mmap() time, vmscan will not encounter the pages until they
+have become evictable again (via munlock() for example) and have been "rescued"
+from the unevictable list.  However, there may be situations where we decide,
+for the sake of expediency, to leave a unevictable page on one of the regular
+active/inactive LRU lists for vmscan to deal with.  vmscan checks for such
+pages in all of the shrink_{active|inactive|page}_list() functions and will
+"cull" such pages that it encounters: that is, it diverts those pages to the
+unevictable list for the zone being scanned.
 
-There may be situations where a page is mapped into a VM_LOCKED vma, but the
-page is not marked as PageMlocked.  Such pages will make it all the way to
+There may be situations where a page is mapped into a VM_LOCKED VMA, but the
+page is not marked as PG_mlocked.  Such pages will make it all the way to
 shrink_page_list() where they will be detected when vmscan walks the reverse
-map in try_to_unmap().  If try_to_unmap() returns SWAP_MLOCK, shrink_page_list()
-will cull the page at that point.
+map in try_to_unmap().  If try_to_unmap() returns SWAP_MLOCK,
+shrink_page_list() will cull the page at that point.
 
-To "cull" an unevictable page, vmscan simply puts the page back on the lru
-list using putback_lru_page()--the inverse operation to isolate_lru_page()--
-after dropping the page lock.  Because the condition which makes the page
-unevictable may change once the page is unlocked, putback_lru_page() will
-recheck the unevictable state of a page that it places on the unevictable lru
-list.  If the page has become unevictable, putback_lru_page() removes it from
-the list and retries, including the page_unevictable() test.  Because such a
-race is a rare event and movement of pages onto the unevictable list should be
-rare, these extra evictabilty checks should not occur in the majority of calls
-to putback_lru_page().
+To "cull" an unevictable page, vmscan simply puts the page back on the LRU list
+using putback_lru_page() - the inverse operation to isolate_lru_page() - after
+dropping the page lock.  Because the condition which makes the page unevictable
+may change once the page is unlocked, putback_lru_page() will recheck the
+unevictable state of a page that it places on the unevictable list.  If the
+page has become unevictable, putback_lru_page() removes it from the list and
+retries, including the page_unevictable() test.  Because such a race is a rare
+event and movement of pages onto the unevictable list should be rare, these
+extra evictabilty checks should not occur in the majority of calls to
+putback_lru_page().
 
 
-Mlocked Page:  Prior Work
+=============
+MLOCKED PAGES
+=============
 
-The "Unevictable Mlocked Pages" infrastructure is based on work originally
+The unevictable page list is also useful for mlock(), in addition to ramfs and
+SYSV SHM.  Note that mlock() is only available in CONFIG_MMU=y situations; in
+NOMMU situations, all mappings are effectively mlocked.
+
+
+HISTORY
+-------
+
+The "Unevictable mlocked Pages" infrastructure is based on work originally
 posted by Nick Piggin in an RFC patch entitled "mm: mlocked pages off LRU".
-Nick posted his patch as an alternative to a patch posted by Christoph
-Lameter to achieve the same objective--hiding mlocked pages from vmscan.
-In Nick's patch, he used one of the struct page lru list link fields as a count
-of VM_LOCKED vmas that map the page.  This use of the link field for a count
-prevented the management of the pages on an LRU list.  Thus, mlocked pages were
-not migratable as isolate_lru_page() could not find them and the lru list link
-field was not available to the migration subsystem.  Nick resolved this by
-putting mlocked pages back on the lru list before attempting to isolate them,
-thus abandoning the count of VM_LOCKED vmas.  When Nick's patch was integrated
-with the Unevictable LRU work, the count was replaced by walking the reverse
-map to determine whether any VM_LOCKED vmas mapped the page.  More on this
-below.
+Nick posted his patch as an alternative to a patch posted by Christoph Lameter
+to achieve the same objective: hiding mlocked pages from vmscan.
 
+In Nick's patch, he used one of the struct page LRU list link fields as a count
+of VM_LOCKED VMAs that map the page.  This use of the link field for a count
+prevented the management of the pages on an LRU list, and thus mlocked pages
+were not migratable as isolate_lru_page() could not find them, and the LRU list
+link field was not available to the migration subsystem.
 
-Mlocked Pages:  Basic Management
+Nick resolved this by putting mlocked pages back on the lru list before
+attempting to isolate them, thus abandoning the count of VM_LOCKED VMAs.  When
+Nick's patch was integrated with the Unevictable LRU work, the count was
+replaced by walking the reverse map to determine whether any VM_LOCKED VMAs
+mapped the page.  More on this below.
 
-Mlocked pages--pages mapped into a VM_LOCKED vma--represent one class of
-unevictable pages.  When such a page has been "noticed" by the memory
-management subsystem, the page is marked with the PG_mlocked [PageMlocked()]
-flag.  A PageMlocked() page will be placed on the unevictable LRU list when
-it is added to the LRU.   Pages can be "noticed" by memory management in
-several places:
 
-1) in the mlock()/mlockall() system call handlers.
-2) in the mmap() system call handler when mmap()ing a region with the
-   MAP_LOCKED flag, or mmap()ing a region in a task that has called
-   mlockall() with the MCL_FUTURE flag.  Both of these conditions result
-   in the VM_LOCKED flag being set for the vma.
-3) in the fault path, if mlocked pages are "culled" in the fault path,
-   and when a VM_LOCKED stack segment is expanded.
-4) as mentioned above, in vmscan:shrink_page_list() when attempting to
-   reclaim a page in a VM_LOCKED vma via try_to_unmap().
+BASIC MANAGEMENT
+----------------
 
-Mlocked pages become unlocked and rescued from the unevictable list when:
+mlocked pages - pages mapped into a VM_LOCKED VMA - are a class of unevictable
+pages.  When such a page has been "noticed" by the memory management subsystem,
+the page is marked with the PG_mlocked flag.  This can be manipulated using the
+PageMlocked() functions.
 
-1) mapped in a range unlocked via the munlock()/munlockall() system calls.
-2) munmapped() out of the last VM_LOCKED vma that maps the page, including
-   unmapping at task exit.
-3) when the page is truncated from the last VM_LOCKED vma of an mmap()ed file.
-4) before a page is COWed in a VM_LOCKED vma.
+A PG_mlocked page will be placed on the unevictable list when it is added to
+the LRU.  Such pages can be "noticed" by memory management in several places:
 
+ (1) in the mlock()/mlockall() system call handlers;
 
-Mlocked Pages:  mlock()/mlockall() System Call Handling
+ (2) in the mmap() system call handler when mmapping a region with the
+     MAP_LOCKED flag;
+
+ (3) mmapping a region in a task that has called mlockall() with the MCL_FUTURE
+     flag
+
+ (4) in the fault path, if mlocked pages are "culled" in the fault path,
+     and when a VM_LOCKED stack segment is expanded; or
+
+ (5) as mentioned above, in vmscan:shrink_page_list() when attempting to
+     reclaim a page in a VM_LOCKED VMA via try_to_unmap()
+
+all of which result in the VM_LOCKED flag being set for the VMA if it doesn't
+already have it set.
+
+mlocked pages become unlocked and rescued from the unevictable list when:
+
+ (1) mapped in a range unlocked via the munlock()/munlockall() system calls;
+
+ (2) munmap()'d out of the last VM_LOCKED VMA that maps the page, including
+     unmapping at task exit;
+
+ (3) when the page is truncated from the last VM_LOCKED VMA of an mmapped file;
+     or
+
+ (4) before a page is COW'd in a VM_LOCKED VMA.
+
+
+mlock()/mlockall() SYSTEM CALL HANDLING
+---------------------------------------
 
 Both [do_]mlock() and [do_]mlockall() system call handlers call mlock_fixup()
-for each vma in the range specified by the call.  In the case of mlockall(),
+for each VMA in the range specified by the call.  In the case of mlockall(),
 this is the entire active address space of the task.  Note that mlock_fixup()
-is used for both mlock()ing and munlock()ing a range of memory.  A call to
-mlock() an already VM_LOCKED vma, or to munlock() a vma that is not VM_LOCKED
-is treated as a no-op--mlock_fixup() simply returns.
+is used for both mlocking and munlocking a range of memory.  A call to mlock()
+an already VM_LOCKED VMA, or to munlock() a VMA that is not VM_LOCKED is
+treated as a no-op, and mlock_fixup() simply returns.
 
-If the vma passes some filtering described in "Mlocked Pages:  Filtering Vmas"
-below, mlock_fixup() will attempt to merge the vma with its neighbors or split
-off a subset of the vma if the range does not cover the entire vma.  Once the
-vma has been merged or split or neither, mlock_fixup() will call
-__mlock_vma_pages_range() to fault in the pages via get_user_pages() and
-to mark the pages as mlocked via mlock_vma_page().
+If the VMA passes some filtering as described in "Filtering Special Vmas"
+below, mlock_fixup() will attempt to merge the VMA with its neighbors or split
+off a subset of the VMA if the range does not cover the entire VMA.  Once the
+VMA has been merged or split or neither, mlock_fixup() will call
+__mlock_vma_pages_range() to fault in the pages via get_user_pages() and to
+mark the pages as mlocked via mlock_vma_page().
 
-Note that the vma being mlocked might be mapped with PROT_NONE.  In this case,
-get_user_pages() will be unable to fault in the pages.  That's OK.  If pages
-do end up getting faulted into this VM_LOCKED vma, we'll handle them in the
+Note that the VMA being mlocked might be mapped with PROT_NONE.  In this case,
+get_user_pages() will be unable to fault in the pages.  That's okay.  If pages
+do end up getting faulted into this VM_LOCKED VMA, we'll handle them in the
 fault path or in vmscan.
 
 Also note that a page returned by get_user_pages() could be truncated or
-migrated out from under us, while we're trying to mlock it.  To detect
-this, __mlock_vma_pages_range() tests the page_mapping after acquiring
-the page lock.  If the page is still associated with its mapping, we'll
-go ahead and call mlock_vma_page().  If the mapping is gone, we just
-unlock the page and move on.  Worse case, this results in page mapped
-in a VM_LOCKED vma remaining on a normal LRU list without being
-PageMlocked().  Again, vmscan will detect and cull such pages.
+migrated out from under us, while we're trying to mlock it.  To detect this,
+__mlock_vma_pages_range() checks page_mapping() after acquiring the page lock.
+If the page is still associated with its mapping, we'll go ahead and call
+mlock_vma_page().  If the mapping is gone, we just unlock the page and move on.
+In the worst case, this will result in a page mapped in a VM_LOCKED VMA
+remaining on a normal LRU list without being PageMlocked().  Again, vmscan will
+detect and cull such pages.
 
-mlock_vma_page(), called with the page locked [N.B., not "mlocked"], will
-TestSetPageMlocked() for each page returned by get_user_pages().  We use
-TestSetPageMlocked() because the page might already be mlocked by another
-task/vma and we don't want to do extra work.  We especially do not want to
-count an mlocked page more than once in the statistics.  If the page was
-already mlocked, mlock_vma_page() is done.
+mlock_vma_page() will call TestSetPageMlocked() for each page returned by
+get_user_pages().  We use TestSetPageMlocked() because the page might already
+be mlocked by another task/VMA and we don't want to do extra work.  We
+especially do not want to count an mlocked page more than once in the
+statistics.  If the page was already mlocked, mlock_vma_page() need do nothing
+more.
 
 If the page was NOT already mlocked, mlock_vma_page() attempts to isolate the
 page from the LRU, as it is likely on the appropriate active or inactive list
-at that time.  If the isolate_lru_page() succeeds, mlock_vma_page() will
-putback the page--putback_lru_page()--which will notice that the page is now
-mlocked and divert the page to the zone's unevictable LRU list.  If
+at that time.  If the isolate_lru_page() succeeds, mlock_vma_page() will put
+back the page - by calling putback_lru_page() - which will notice that the page
+is now mlocked and divert the page to the zone's unevictable list.  If
 mlock_vma_page() is unable to isolate the page from the LRU, vmscan will handle
-it later if/when it attempts to reclaim the page.
+it later if and when it attempts to reclaim the page.
 
 
-Mlocked Pages:  Filtering Special Vmas
+FILTERING SPECIAL VMAS
+----------------------
 
-mlock_fixup() filters several classes of "special" vmas:
+mlock_fixup() filters several classes of "special" VMAs:
 
-1) vmas with VM_IO|VM_PFNMAP set are skipped entirely.  The pages behind
+1) VMAs with VM_IO or VM_PFNMAP set are skipped entirely.  The pages behind
    these mappings are inherently pinned, so we don't need to mark them as
-   mlocked.  In any case, most of the pages have no struct page in which to
-   so mark the page.  Because of this, get_user_pages() will fail for these
-   vmas, so there is no sense in attempting to visit them.
+   mlocked.  In any case, most of the pages have no struct page in which to so
+   mark the page.  Because of this, get_user_pages() will fail for these VMAs,
+   so there is no sense in attempting to visit them.
 
-2) vmas mapping hugetlbfs page are already effectively pinned into memory.
-   We don't need nor want to mlock() these pages.  However, to preserve the
-   prior behavior of mlock()--before the unevictable/mlock changes--
-   mlock_fixup() will call make_pages_present() in the hugetlbfs vma range
-   to allocate the huge pages and populate the ptes.
+2) VMAs mapping hugetlbfs page are already effectively pinned into memory.  We
+   neither need nor want to mlock() these pages.  However, to preserve the
+   prior behavior of mlock() - before the unevictable/mlock changes -
+   mlock_fixup() will call make_pages_present() in the hugetlbfs VMA range to
+   allocate the huge pages and populate the ptes.
 
-3) vmas with VM_DONTEXPAND|VM_RESERVED are generally user space mappings of
-   kernel pages, such as the vdso page, relay channel pages, etc.  These pages
+3) VMAs with VM_DONTEXPAND or VM_RESERVED are generally userspace mappings of
+   kernel pages, such as the VDSO page, relay channel pages, etc.  These pages
    are inherently unevictable and are not managed on the LRU lists.
-   mlock_fixup() treats these vmas the same as hugetlbfs vmas.  It calls
+   mlock_fixup() treats these VMAs the same as hugetlbfs VMAs.  It calls
    make_pages_present() to populate the ptes.
 
-Note that for all of these special vmas, mlock_fixup() does not set the
+Note that for all of these special VMAs, mlock_fixup() does not set the
 VM_LOCKED flag.  Therefore, we won't have to deal with them later during
-munlock() or munmap()--for example, at task exit.  Neither does mlock_fixup()
-account these vmas against the task's "locked_vm".
-
-Mlocked Pages:  Downgrading the Mmap Semaphore.
-
-mlock_fixup() must be called with the mmap semaphore held for write, because
-it may have to merge or split vmas.  However, mlocking a large region of
-memory can take a long time--especially if vmscan must reclaim pages to
-satisfy the regions requirements.  Faulting in a large region with the mmap
-semaphore held for write can hold off other faults on the address space, in
-the case of a multi-threaded task.  It can also hold off scans of the task's
-address space via /proc.  While testing under heavy load, it was observed that
-the ps(1) command could be held off for many minutes while a large segment was
-mlock()ed down.
-
-To address this issue, and to make the system more responsive during mlock()ing
-of large segments, mlock_fixup() downgrades the mmap semaphore to read mode
-during the call to __mlock_vma_pages_range().  This works fine.  However, the
-callers of mlock_fixup() expect the semaphore to be returned in write mode.
-So, mlock_fixup() "upgrades" the semphore to write mode.  Linux does not
-support an atomic upgrade_sem() call, so mlock_fixup() must drop the semaphore
-and reacquire it in write mode.  In a multi-threaded task, it is possible for
-the task memory map to change while the semaphore is dropped.  Therefore,
-mlock_fixup() looks up the vma at the range start address after reacquiring
-the semaphore in write mode and verifies that it still covers the original
-range.  If not, mlock_fixup() returns an error [-EAGAIN].  All callers of
-mlock_fixup() have been changed to deal with this new error condition.
-
-Note:  when munlocking a region, all of the pages should already be resident--
-unless we have racing threads mlocking() and munlocking() regions.  So,
-unlocking should not have to wait for page allocations nor faults  of any kind.
-Therefore mlock_fixup() does not downgrade the semaphore for munlock().
+munlock(), munmap() or task exit.  Neither does mlock_fixup() account these
+VMAs against the task's "locked_vm".
 
 
-Mlocked Pages:  munlock()/munlockall() System Call Handling
+munlock()/munlockall() SYSTEM CALL HANDLING
+-------------------------------------------
 
-The munlock() and munlockall() system calls are handled by the same functions--
-do_mlock[all]()--as the mlock() and mlockall() system calls with the unlock
-vs lock operation indicated by an argument.  So, these system calls are also
-handled by mlock_fixup().  Again, if called for an already munlock()ed vma,
-mlock_fixup() simply returns.  Because of the vma filtering discussed above,
-VM_LOCKED will not be set in any "special" vmas.  So, these vmas will be
+The munlock() and munlockall() system calls are handled by the same functions -
+do_mlock[all]() - as the mlock() and mlockall() system calls with the unlock vs
+lock operation indicated by an argument.  So, these system calls are also
+handled by mlock_fixup().  Again, if called for an already munlocked VMA,
+mlock_fixup() simply returns.  Because of the VMA filtering discussed above,
+VM_LOCKED will not be set in any "special" VMAs.  So, these VMAs will be
 ignored for munlock.
 
-If the vma is VM_LOCKED, mlock_fixup() again attempts to merge or split off
-the specified range.  The range is then munlocked via the function
-__mlock_vma_pages_range()--the same function used to mlock a vma range--
+If the VMA is VM_LOCKED, mlock_fixup() again attempts to merge or split off the
+specified range.  The range is then munlocked via the function
+__mlock_vma_pages_range() - the same function used to mlock a VMA range -
 passing a flag to indicate that munlock() is being performed.
 
-Because the vma access protections could have been changed to PROT_NONE after
+Because the VMA access protections could have been changed to PROT_NONE after
 faulting in and mlocking pages, get_user_pages() was unreliable for visiting
-these pages for munlocking.  Because we don't want to leave pages mlocked(),
+these pages for munlocking.  Because we don't want to leave pages mlocked,
 get_user_pages() was enhanced to accept a flag to ignore the permissions when
-fetching the pages--all of which should be resident as a result of previous
-mlock()ing.
+fetching the pages - all of which should be resident as a result of previous
+mlocking.
 
 For munlock(), __mlock_vma_pages_range() unlocks individual pages by calling
 munlock_vma_page().  munlock_vma_page() unconditionally clears the PG_mlocked
-flag using TestClearPageMlocked().  As with mlock_vma_page(), munlock_vma_page()
-use the Test*PageMlocked() function to handle the case where the page might
-have already been unlocked by another task.  If the page was mlocked,
-munlock_vma_page() updates that zone statistics for the number of mlocked
-pages.  Note, however, that at this point we haven't checked whether the page
-is mapped by other VM_LOCKED vmas.
+flag using TestClearPageMlocked().  As with mlock_vma_page(),
+munlock_vma_page() use the Test*PageMlocked() function to handle the case where
+the page might have already been unlocked by another task.  If the page was
+mlocked, munlock_vma_page() updates that zone statistics for the number of
+mlocked pages.  Note, however, that at this point we haven't checked whether
+the page is mapped by other VM_LOCKED VMAs.
 
-We can't call try_to_munlock(), the function that walks the reverse map to check
-for other VM_LOCKED vmas, without first isolating the page from the LRU.
+We can't call try_to_munlock(), the function that walks the reverse map to
+check for other VM_LOCKED VMAs, without first isolating the page from the LRU.
 try_to_munlock() is a variant of try_to_unmap() and thus requires that the page
-not be on an lru list.  [More on these below.]  However, the call to
-isolate_lru_page() could fail, in which case we couldn't try_to_munlock().
-So, we go ahead and clear PG_mlocked up front, as this might be the only chance
-we have.  If we can successfully isolate the page, we go ahead and
+not be on an LRU list [more on these below].  However, the call to
+isolate_lru_page() could fail, in which case we couldn't try_to_munlock().  So,
+we go ahead and clear PG_mlocked up front, as this might be the only chance we
+have.  If we can successfully isolate the page, we go ahead and
 try_to_munlock(), which will restore the PG_mlocked flag and update the zone
-page statistics if it finds another vma holding the page mlocked.  If we fail
+page statistics if it finds another VMA holding the page mlocked.  If we fail
 to isolate the page, we'll have left a potentially mlocked page on the LRU.
-This is fine, because we'll catch it later when/if vmscan tries to reclaim the
-page.  This should be relatively rare.
+This is fine, because we'll catch it later if and if vmscan tries to reclaim
+the page.  This should be relatively rare.
 
-Mlocked Pages:  Migrating Them...
 
-A page that is being migrated has been isolated from the lru lists and is
-held locked across unmapping of the page, updating the page's mapping
-[address_space] entry and copying the contents and state, until the
-page table entry has been replaced with an entry that refers to the new
-page.  Linux supports migration of mlocked pages and other unevictable
-pages.  This involves simply moving the PageMlocked and PageUnevictable states
-from the old page to the new page.
+MIGRATING MLOCKED PAGES
+-----------------------
 
-Note that page migration can race with mlocking or munlocking of the same
-page.  This has been discussed from the mlock/munlock perspective in the
-respective sections above.  Both processes [migration, m[un]locking], hold
-the page locked.  This provides the first level of synchronization.  Page
-migration zeros out the page_mapping of the old page before unlocking it,
-so m[un]lock can skip these pages by testing the page mapping under page
-lock.
+A page that is being migrated has been isolated from the LRU lists and is held
+locked across unmapping of the page, updating the page's address space entry
+and copying the contents and state, until the page table entry has been
+replaced with an entry that refers to the new page.  Linux supports migration
+of mlocked pages and other unevictable pages.  This involves simply moving the
+PG_mlocked and PG_unevictable states from the old page to the new page.
 
-When completing page migration, we place the new and old pages back onto the
-lru after dropping the page lock.  The "unneeded" page--old page on success,
-new page on failure--will be freed when the reference count held by the
-migration process is released.  To ensure that we don't strand pages on the
-unevictable list because of a race between munlock and migration, page
-migration uses the putback_lru_page() function to add migrated pages back to
-the lru.
+Note that page migration can race with mlocking or munlocking of the same page.
+This has been discussed from the mlock/munlock perspective in the respective
+sections above.  Both processes (migration and m[un]locking) hold the page
+locked.  This provides the first level of synchronization.  Page migration
+zeros out the page_mapping of the old page before unlocking it, so m[un]lock
+can skip these pages by testing the page mapping under page lock.
 
+To complete page migration, we place the new and old pages back onto the LRU
+after dropping the page lock.  The "unneeded" page - old page on success, new
+page on failure - will be freed when the reference count held by the migration
+process is released.  To ensure that we don't strand pages on the unevictable
+list because of a race between munlock and migration, page migration uses the
+putback_lru_page() function to add migrated pages back to the LRU.
 
-Mlocked Pages:  mmap(MAP_LOCKED) System Call Handling
+
+mmap(MAP_LOCKED) SYSTEM CALL HANDLING
+-------------------------------------
 
 In addition the the mlock()/mlockall() system calls, an application can request
-that a region of memory be mlocked using the MAP_LOCKED flag with the mmap()
+that a region of memory be mlocked supplying the MAP_LOCKED flag to the mmap()
 call.  Furthermore, any mmap() call or brk() call that expands the heap by a
 task that has previously called mlockall() with the MCL_FUTURE flag will result
-in the newly mapped memory being mlocked.  Before the unevictable/mlock changes,
-the kernel simply called make_pages_present() to allocate pages and populate
-the page table.
+in the newly mapped memory being mlocked.  Before the unevictable/mlock
+changes, the kernel simply called make_pages_present() to allocate pages and
+populate the page table.
 
 To mlock a range of memory under the unevictable/mlock infrastructure, the
 mmap() handler and task address space expansion functions call
 mlock_vma_pages_range() specifying the vma and the address range to mlock.
-mlock_vma_pages_range() filters vmas like mlock_fixup(), as described above in
-"Mlocked Pages:  Filtering Vmas".  It will clear the VM_LOCKED flag, which will
-have already been set by the caller, in filtered vmas.  Thus these vma's need
-not be visited for munlock when the region is unmapped.
+mlock_vma_pages_range() filters VMAs like mlock_fixup(), as described above in
+"Filtering Special VMAs".  It will clear the VM_LOCKED flag, which will have
+already been set by the caller, in filtered VMAs.  Thus these VMA's need not be
+visited for munlock when the region is unmapped.
 
-For "normal" vmas, mlock_vma_pages_range() calls __mlock_vma_pages_range() to
+For "normal" VMAs, mlock_vma_pages_range() calls __mlock_vma_pages_range() to
 fault/allocate the pages and mlock them.  Again, like mlock_fixup(),
 mlock_vma_pages_range() downgrades the mmap semaphore to read mode before
-attempting to fault/allocate and mlock the pages; and "upgrades" the semaphore
+attempting to fault/allocate and mlock the pages and "upgrades" the semaphore
 back to write mode before returning.
 
-The callers of mlock_vma_pages_range() will have already added the memory
-range to be mlocked to the task's "locked_vm".  To account for filtered vmas,
+The callers of mlock_vma_pages_range() will have already added the memory range
+to be mlocked to the task's "locked_vm".  To account for filtered VMAs,
 mlock_vma_pages_range() returns the number of pages NOT mlocked.  All of the
-callers then subtract a non-negative return value from the task's locked_vm.
-A negative return value represent an error--for example, from get_user_pages()
-attempting to fault in a vma with PROT_NONE access.  In this case, we leave
-the memory range accounted as locked_vm, as the protections could be changed
-later and pages allocated into that region.
+callers then subtract a non-negative return value from the task's locked_vm.  A
+negative return value represent an error - for example, from get_user_pages()
+attempting to fault in a VMA with PROT_NONE access.  In this case, we leave the
+memory range accounted as locked_vm, as the protections could be changed later
+and pages allocated into that region.
 
 
-Mlocked Pages:  munmap()/exit()/exec() System Call Handling
+munmap()/exit()/exec() SYSTEM CALL HANDLING
+-------------------------------------------
 
 When unmapping an mlocked region of memory, whether by an explicit call to
 munmap() or via an internal unmap from exit() or exec() processing, we must
-munlock the pages if we're removing the last VM_LOCKED vma that maps the pages.
+munlock the pages if we're removing the last VM_LOCKED VMA that maps the pages.
 Before the unevictable/mlock changes, mlocking did not mark the pages in any
 way, so unmapping them required no processing.
 
 To munlock a range of memory under the unevictable/mlock infrastructure, the
-munmap() hander and task address space tear down function call
+munmap() handler and task address space call tear down function
 munlock_vma_pages_all().  The name reflects the observation that one always
-specifies the entire vma range when munlock()ing during unmap of a region.
-Because of the vma filtering when mlocking() regions, only "normal" vmas that
+specifies the entire VMA range when munlock()ing during unmap of a region.
+Because of the VMA filtering when mlocking() regions, only "normal" VMAs that
 actually contain mlocked pages will be passed to munlock_vma_pages_all().
 
-munlock_vma_pages_all() clears the VM_LOCKED vma flag and, like mlock_fixup()
+munlock_vma_pages_all() clears the VM_LOCKED VMA flag and, like mlock_fixup()
 for the munlock case, calls __munlock_vma_pages_range() to walk the page table
-for the vma's memory range and munlock_vma_page() each resident page mapped by
-the vma.  This effectively munlocks the page, only if this is the last
-VM_LOCKED vma that maps the page.
-
+for the VMA's memory range and munlock_vma_page() each resident page mapped by
+the VMA.  This effectively munlocks the page, only if this is the last
+VM_LOCKED VMA that maps the page.
 
-Mlocked Page:  try_to_unmap()
 
-[Note:  the code changes represented by this section are really quite small
-compared to the text to describe what happening and why, and to discuss the
-implications.]
+try_to_unmap()
+--------------
 
-Pages can, of course, be mapped into multiple vmas.  Some of these vmas may
+Pages can, of course, be mapped into multiple VMAs.  Some of these VMAs may
 have VM_LOCKED flag set.  It is possible for a page mapped into one or more
-VM_LOCKED vmas not to have the PG_mlocked flag set and therefore reside on one
-of the active or inactive LRU lists.  This could happen if, for example, a
-task in the process of munlock()ing the page could not isolate the page from
-the LRU.  As a result, vmscan/shrink_page_list() might encounter such a page
-as described in "Unevictable Pages and Vmscan [shrink_*_list()]".  To
-handle this situation, try_to_unmap() has been enhanced to check for VM_LOCKED
-vmas while it is walking a page's reverse map.
+VM_LOCKED VMAs not to have the PG_mlocked flag set and therefore reside on one
+of the active or inactive LRU lists.  This could happen if, for example, a task
+in the process of munlocking the page could not isolate the page from the LRU.
+As a result, vmscan/shrink_page_list() might encounter such a page as described
+in section "vmscan's handling of unevictable pages".  To handle this situation,
+try_to_unmap() checks for VM_LOCKED VMAs while it is walking a page's reverse
+map.
 
 try_to_unmap() is always called, by either vmscan for reclaim or for page
-migration, with the argument page locked and isolated from the LRU.  BUG_ON()
-assertions enforce this requirement.  Separate functions handle anonymous and
-mapped file pages, as these types of pages have different reverse map
-mechanisms.
+migration, with the argument page locked and isolated from the LRU.  Separate
+functions handle anonymous and mapped file pages, as these types of pages have
+different reverse map mechanisms.
 
-	try_to_unmap_anon()
+ (*) try_to_unmap_anon()
 
-To unmap anonymous pages, each vma in the list anchored in the anon_vma must be
-visited--at least until a VM_LOCKED vma is encountered.  If the page is being
-unmapped for migration, VM_LOCKED vmas do not stop the process because mlocked
-pages are migratable.  However, for reclaim, if the page is mapped into a
-VM_LOCKED vma, the scan stops.  try_to_unmap() attempts to acquire the mmap
-semphore of the mm_struct to which the vma belongs in read mode.  If this is
-successful, try_to_unmap() will mlock the page via mlock_vma_page()--we
-wouldn't have gotten to try_to_unmap() if the page were already mlocked--and
-will return SWAP_MLOCK, indicating that the page is unevictable.  If the
-mmap semaphore cannot be acquired, we are not sure whether the page is really
-unevictable or not.  In this case, try_to_unmap() will return SWAP_AGAIN.
+     To unmap anonymous pages, each VMA in the list anchored in the anon_vma
+     must be visited - at least until a VM_LOCKED VMA is encountered.  If the
+     page is being unmapped for migration, VM_LOCKED VMAs do not stop the
+     process because mlocked pages are migratable.  However, for reclaim, if
+     the page is mapped into a VM_LOCKED VMA, the scan stops.
 
-	try_to_unmap_file() -- linear mappings
+     try_to_unmap_anon() attempts to acquire in read mode the mmap semphore of
+     the mm_struct to which the VMA belongs.  If this is successful, it will
+     mlock the page via mlock_vma_page() - we wouldn't have gotten to
+     try_to_unmap_anon() if the page were already mlocked - and will return
+     SWAP_MLOCK, indicating that the page is unevictable.
 
-Unmapping of a mapped file page works the same, except that the scan visits
-all vmas that maps the page's index/page offset in the page's mapping's
-reverse map priority search tree.  It must also visit each vma in the page's
-mapping's non-linear list, if the list is non-empty.  As for anonymous pages,
-on encountering a VM_LOCKED vma for a mapped file page, try_to_unmap() will
-attempt to acquire the associated mm_struct's mmap semaphore to mlock the page,
-returning SWAP_MLOCK if this is successful, and SWAP_AGAIN, if not.
+     If the mmap semaphore cannot be acquired, we are not sure whether the page
+     is really unevictable or not.  In this case, try_to_unmap_anon() will
+     return SWAP_AGAIN.
 
-	try_to_unmap_file() -- non-linear mappings
+ (*) try_to_unmap_file() - linear mappings
 
-If a page's mapping contains a non-empty non-linear mapping vma list, then
-try_to_un{map|lock}() must also visit each vma in that list to determine
-whether the page is mapped in a VM_LOCKED vma.  Again, the scan must visit
-all vmas in the non-linear list to ensure that the pages is not/should not be
-mlocked.  If a VM_LOCKED vma is found in the list, the scan could terminate.
-However, there is no easy way to determine whether the page is actually mapped
-in a given vma--either for unmapping or testing whether the VM_LOCKED vma
-actually pins the page.
+     Unmapping of a mapped file page works the same as for anonymous mappings,
+     except that the scan visits all VMAs that map the page's index/page offset
+     in the page's mapping's reverse map priority search tree.  It also visits
+     each VMA in the page's mapping's non-linear list, if the list is
+     non-empty.
 
-So, try_to_unmap_file() handles non-linear mappings by scanning a certain
-number of pages--a "cluster"--in each non-linear vma associated with the page's
-mapping, for each file mapped page that vmscan tries to unmap.  If this happens
-to unmap the page we're trying to unmap, try_to_unmap() will notice this on
-return--(page_mapcount(page) == 0)--and return SWAP_SUCCESS.  Otherwise, it
-will return SWAP_AGAIN, causing vmscan to recirculate this page.  We take
-advantage of the cluster scan in try_to_unmap_cluster() as follows:
+     As for anonymous pages, on encountering a VM_LOCKED VMA for a mapped file
+     page, try_to_unmap_file() will attempt to acquire the associated
+     mm_struct's mmap semaphore to mlock the page, returning SWAP_MLOCK if this
+     is successful, and SWAP_AGAIN, if not.
 
-For each non-linear vma, try_to_unmap_cluster() attempts to acquire the mmap
-semaphore of the associated mm_struct for read without blocking.  If this
-attempt is successful and the vma is VM_LOCKED, try_to_unmap_cluster() will
-retain the mmap semaphore for the scan; otherwise it drops it here.  Then,
-for each page in the cluster, if we're holding the mmap semaphore for a locked
-vma, try_to_unmap_cluster() calls mlock_vma_page() to mlock the page.  This
-call is a no-op if the page is already locked, but will mlock any pages in
-the non-linear mapping that happen to be unlocked.  If one of the pages so
-mlocked is the page passed in to try_to_unmap(), try_to_unmap_cluster() will
-return SWAP_MLOCK, rather than the default SWAP_AGAIN.  This will allow vmscan
-to cull the page, rather than recirculating it on the inactive list.  Again,
-if try_to_unmap_cluster() cannot acquire the vma's mmap sem, it returns
-SWAP_AGAIN, indicating that the page is mapped by a VM_LOCKED vma, but
-couldn't be mlocked.
+ (*) try_to_unmap_file() - non-linear mappings
+
+     If a page's mapping contains a non-empty non-linear mapping VMA list, then
+     try_to_un{map|lock}() must also visit each VMA in that list to determine
+     whether the page is mapped in a VM_LOCKED VMA.  Again, the scan must visit
+     all VMAs in the non-linear list to ensure that the pages is not/should not
+     be mlocked.
 
+     If a VM_LOCKED VMA is found in the list, the scan could terminate.
+     However, there is no easy way to determine whether the page is actually
+     mapped in a given VMA - either for unmapping or testing whether the
+     VM_LOCKED VMA actually pins the page.
 
-Mlocked pages:  try_to_munlock() Reverse Map Scan
+     try_to_unmap_file() handles non-linear mappings by scanning a certain
+     number of pages - a "cluster" - in each non-linear VMA associated with the
+     page's mapping, for each file mapped page that vmscan tries to unmap.  If
+     this happens to unmap the page we're trying to unmap, try_to_unmap() will
+     notice this on return (page_mapcount(page) will be 0) and return
+     SWAP_SUCCESS.  Otherwise, it will return SWAP_AGAIN, causing vmscan to
+     recirculate this page.  We take advantage of the cluster scan in
+     try_to_unmap_cluster() as follows:
 
-TODO/FIXME:  a better name might be page_mlocked()--analogous to the
-page_referenced() reverse map walker.
+	For each non-linear VMA, try_to_unmap_cluster() attempts to acquire the
+	mmap semaphore of the associated mm_struct for read without blocking.
 
-When munlock_vma_page()--see "Mlocked Pages:  munlock()/munlockall()
-System Call Handling" above--tries to munlock a page, it needs to
-determine whether or not the page is mapped by any VM_LOCKED vma, without
-actually attempting to unmap all ptes from the page.  For this purpose, the
-unevictable/mlock infrastructure introduced a variant of try_to_unmap() called
-try_to_munlock().
+	If this attempt is successful and the VMA is VM_LOCKED,
+	try_to_unmap_cluster() will retain the mmap semaphore for the scan;
+	otherwise it drops it here.
+
+	Then, for each page in the cluster, if we're holding the mmap semaphore
+	for a locked VMA, try_to_unmap_cluster() calls mlock_vma_page() to
+	mlock the page.  This call is a no-op if the page is already locked,
+	but will mlock any pages in the non-linear mapping that happen to be
+	unlocked.
+
+	If one of the pages so mlocked is the page passed in to try_to_unmap(),
+	try_to_unmap_cluster() will return SWAP_MLOCK, rather than the default
+	SWAP_AGAIN.  This will allow vmscan to cull the page, rather than
+	recirculating it on the inactive list.
+
+	Again, if try_to_unmap_cluster() cannot acquire the VMA's mmap sem, it
+	returns SWAP_AGAIN, indicating that the page is mapped by a VM_LOCKED
+	VMA, but couldn't be mlocked.
+
+
+try_to_munlock() REVERSE MAP SCAN
+---------------------------------
+
+ [!] TODO/FIXME: a better name might be page_mlocked() - analogous to the
+     page_referenced() reverse map walker.
+
+When munlock_vma_page() [see section "munlock()/munlockall() System Call
+Handling" above] tries to munlock a page, it needs to determine whether or not
+the page is mapped by any VM_LOCKED VMA without actually attempting to unmap
+all PTEs from the page.  For this purpose, the unevictable/mlock infrastructure
+introduced a variant of try_to_unmap() called try_to_munlock().
 
 try_to_munlock() calls the same functions as try_to_unmap() for anonymous and
 mapped file pages with an additional argument specifing unlock versus unmap
 processing.  Again, these functions walk the respective reverse maps looking
-for VM_LOCKED vmas.  When such a vma is found for anonymous pages and file
+for VM_LOCKED VMAs.  When such a VMA is found for anonymous pages and file
 pages mapped in linear VMAs, as in the try_to_unmap() case, the functions
 attempt to acquire the associated mmap semphore, mlock the page via
 mlock_vma_page() and return SWAP_MLOCK.  This effectively undoes the
 pre-clearing of the page's PG_mlocked done by munlock_vma_page.
 
-If try_to_unmap() is unable to acquire a VM_LOCKED vma's associated mmap
-semaphore, it will return SWAP_AGAIN.  This will allow shrink_page_list()
-to recycle the page on the inactive list and hope that it has better luck
-with the page next time.
+If try_to_unmap() is unable to acquire a VM_LOCKED VMA's associated mmap
+semaphore, it will return SWAP_AGAIN.  This will allow shrink_page_list() to
+recycle the page on the inactive list and hope that it has better luck with the
+page next time.
 
-For file pages mapped into non-linear vmas, the try_to_munlock() logic works
-slightly differently.  On encountering a VM_LOCKED non-linear vma that might
-map the page, try_to_munlock() returns SWAP_AGAIN without actually mlocking
-the page.  munlock_vma_page() will just leave the page unlocked and let
-vmscan deal with it--the usual fallback position.
+For file pages mapped into non-linear VMAs, the try_to_munlock() logic works
+slightly differently.  On encountering a VM_LOCKED non-linear VMA that might
+map the page, try_to_munlock() returns SWAP_AGAIN without actually mlocking the
+page.  munlock_vma_page() will just leave the page unlocked and let vmscan deal
+with it - the usual fallback position.
 
-Note that try_to_munlock()'s reverse map walk must visit every vma in a pages'
-reverse map to determine that a page is NOT mapped into any VM_LOCKED vma.
-However, the scan can terminate when it encounters a VM_LOCKED vma and can
-successfully acquire the vma's mmap semphore for read and mlock the page.
-Although try_to_munlock() can be called many [very many!] times when
-munlock()ing a large region or tearing down a large address space that has been
-mlocked via mlockall(), overall this is a fairly rare event.
+Note that try_to_munlock()'s reverse map walk must visit every VMA in a page's
+reverse map to determine that a page is NOT mapped into any VM_LOCKED VMA.
+However, the scan can terminate when it encounters a VM_LOCKED VMA and can
+successfully acquire the VMA's mmap semphore for read and mlock the page.
+Although try_to_munlock() might be called a great many times when munlocking a
+large region or tearing down a large address space that has been mlocked via
+mlockall(), overall this is a fairly rare event.
 
-Mlocked Page:  Page Reclaim in shrink_*_list()
 
-shrink_active_list() culls any obviously unevictable pages--i.e.,
-!page_evictable(page, NULL)--diverting these to the unevictable lru
-list.  However, shrink_active_list() only sees unevictable pages that
-made it onto the active/inactive lru lists.  Note that these pages do not
-have PageUnevictable set--otherwise, they would be on the unevictable list and
-shrink_active_list would never see them.
+PAGE RECLAIM IN shrink_*_list()
+-------------------------------
+
+shrink_active_list() culls any obviously unevictable pages - i.e.
+!page_evictable(page, NULL) - diverting these to the unevictable list.
+However, shrink_active_list() only sees unevictable pages that made it onto the
+active/inactive lru lists.  Note that these pages do not have PageUnevictable
+set - otherwise they would be on the unevictable list and shrink_active_list
+would never see them.
 
 Some examples of these unevictable pages on the LRU lists are:
 
-1) ramfs pages that have been placed on the lru lists when first allocated.
+ (1) ramfs pages that have been placed on the LRU lists when first allocated.
 
-2) SHM_LOCKed shared memory pages.  shmctl(SHM_LOCK) does not attempt to
-   allocate or fault in the pages in the shared memory region.  This happens
-   when an application accesses the page the first time after SHM_LOCKing
-   the segment.
+ (2) SHM_LOCK'd shared memory pages.  shmctl(SHM_LOCK) does not attempt to
+     allocate or fault in the pages in the shared memory region.  This happens
+     when an application accesses the page the first time after SHM_LOCK'ing
+     the segment.
 
-3) Mlocked pages that could not be isolated from the lru and moved to the
-   unevictable list in mlock_vma_page().
+ (3) mlocked pages that could not be isolated from the LRU and moved to the
+     unevictable list in mlock_vma_page().
 
-3) Pages mapped into multiple VM_LOCKED vmas, but try_to_munlock() couldn't
-   acquire the vma's mmap semaphore to test the flags and set PageMlocked.
-   munlock_vma_page() was forced to let the page back on to the normal
-   LRU list for vmscan to handle.
+ (4) Pages mapped into multiple VM_LOCKED VMAs, but try_to_munlock() couldn't
+     acquire the VMA's mmap semaphore to test the flags and set PageMlocked.
+     munlock_vma_page() was forced to let the page back on to the normal LRU
+     list for vmscan to handle.
 
-shrink_inactive_list() also culls any unevictable pages that it finds on
-the inactive lists, again diverting them to the appropriate zone's unevictable
-lru list.  shrink_inactive_list() should only see SHM_LOCKed pages that became
-SHM_LOCKed after shrink_active_list() had moved them to the inactive list, or
-pages mapped into VM_LOCKED vmas that munlock_vma_page() couldn't isolate from
-the lru to recheck via try_to_munlock().  shrink_inactive_list() won't notice
-the latter, but will pass on to shrink_page_list().
+shrink_inactive_list() also diverts any unevictable pages that it finds on the
+inactive lists to the appropriate zone's unevictable list.
+
+shrink_inactive_list() should only see SHM_LOCK'd pages that became SHM_LOCK'd
+after shrink_active_list() had moved them to the inactive list, or pages mapped
+into VM_LOCKED VMAs that munlock_vma_page() couldn't isolate from the LRU to
+recheck via try_to_munlock().  shrink_inactive_list() won't notice the latter,
+but will pass on to shrink_page_list().
 
 shrink_page_list() again culls obviously unevictable pages that it could
 encounter for similar reason to shrink_inactive_list().  Pages mapped into
-VM_LOCKED vmas but without PG_mlocked set will make it all the way to
+VM_LOCKED VMAs but without PG_mlocked set will make it all the way to
 try_to_unmap().  shrink_page_list() will divert them to the unevictable list
 when try_to_unmap() returns SWAP_MLOCK, as discussed above.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/x86/boot.txt linux-libre-2.6.30-gnu1/Documentation/x86/boot.txt
--- linux-libre-2.6.29-gnu1/Documentation/x86/boot.txt	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/x86/boot.txt	2009-06-09 23:05:27.000000000 -0400
@@ -158,7 +158,7 @@ Offset	Proto	Name		Meaning
 0202/4	2.00+	header		Magic signature "HdrS"
 0206/2	2.00+	version		Boot protocol version supported
 0208/4	2.00+	realmode_swtch	Boot loader hook (see below)
-020C/2	2.00+	start_sys	The load-low segment (0x1000) (obsolete)
+020C/2	2.00+	start_sys_seg	The load-low segment (0x1000) (obsolete)
 020E/2	2.00+	kernel_version	Pointer to kernel version string
 0210/1	2.00+	type_of_loader	Boot loader identifier
 0211/1	2.00+	loadflags	Boot protocol option flags
@@ -170,10 +170,11 @@ Offset	Proto	Name		Meaning
 0224/2	2.01+	heap_end_ptr	Free memory after setup end
 0226/2	N/A	pad1		Unused
 0228/4	2.02+	cmd_line_ptr	32-bit pointer to the kernel command line
-022C/4	2.03+	initrd_addr_max	Highest legal initrd address
+022C/4	2.03+	ramdisk_max	Highest legal initrd address
 0230/4	2.05+	kernel_alignment Physical addr alignment required for kernel
 0234/1	2.05+	relocatable_kernel Whether kernel is relocatable or not
-0235/3	N/A	pad2		Unused
+0235/1	N/A	pad2		Unused
+0236/2	N/A	pad3		Unused
 0238/4	2.06+	cmdline_size	Maximum size of the kernel command line
 023C/4	2.07+	hardware_subarch Hardware subarchitecture
 0240/8	2.07+	hardware_subarch_data Subarchitecture-specific data
@@ -299,14 +300,14 @@ Protocol:	2.00+
   e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
   10.17.
 
-Field name:	readmode_swtch
+Field name:	realmode_swtch
 Type:		modify (optional)
 Offset/size:	0x208/4
 Protocol:	2.00+
 
   Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
 
-Field name:	start_sys
+Field name:	start_sys_seg
 Type:		read
 Offset/size:	0x20c/2
 Protocol:	2.00+
@@ -468,7 +469,7 @@ Protocol:	2.02+
   zero, the kernel will assume that your boot loader does not support
   the 2.02+ protocol.
 
-Field name:	initrd_addr_max
+Field name:	ramdisk_max
 Type:		read
 Offset/size:	0x22c/4
 Protocol:	2.03+
@@ -542,7 +543,10 @@ Protocol:	2.08+
 
   The payload may be compressed. The format of both the compressed and
   uncompressed data should be determined using the standard magic
-  numbers. Currently only gzip compressed ELF is used.
+  numbers.  The currently supported compression formats are gzip
+  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A) and LZMA
+  (magic number 5D 00).  The uncompressed payload is currently always ELF
+  (magic number 7F 45 4C 46).
   
 Field name:	payload_length
 Type:		read
diff -druNp linux-libre-2.6.29-gnu1/Documentation/x86/earlyprintk.txt linux-libre-2.6.30-gnu1/Documentation/x86/earlyprintk.txt
--- linux-libre-2.6.29-gnu1/Documentation/x86/earlyprintk.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/Documentation/x86/earlyprintk.txt	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,101 @@
+
+Mini-HOWTO for using the earlyprintk=dbgp boot option with a
+USB2 Debug port key and a debug cable, on x86 systems.
+
+You need two computers, the 'USB debug key' special gadget and
+and two USB cables, connected like this:
+
+  [host/target] <-------> [USB debug key] <-------> [client/console]
+
+1. There are three specific hardware requirements:
+
+ a.) Host/target system needs to have USB debug port capability.
+
+ You can check this capability by looking at a 'Debug port' bit in
+ the lspci -vvv output:
+
+ # lspci -vvv
+ ...
+ 00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 03) (prog-if 20 [EHCI])
+         Subsystem: Lenovo ThinkPad T61
+         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
+         Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
+         Latency: 0
+         Interrupt: pin D routed to IRQ 19
+         Region 0: Memory at fe227000 (32-bit, non-prefetchable) [size=1K]
+         Capabilities: [50] Power Management version 2
+                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
+                 Status: D0 PME-Enable- DSel=0 DScale=0 PME+
+         Capabilities: [58] Debug port: BAR=1 offset=00a0
+                            ^^^^^^^^^^^ <==================== [ HERE ]
+	 Kernel driver in use: ehci_hcd
+         Kernel modules: ehci-hcd
+ ...
+
+( If your system does not list a debug port capability then you probably
+  wont be able to use the USB debug key. )
+
+ b.) You also need a Netchip USB debug cable/key:
+
+        http://www.plxtech.com/products/NET2000/NET20DC/default.asp
+
+     This is a small blue plastic connector with two USB connections,
+     it draws power from its USB connections.
+
+ c.) Thirdly, you need a second client/console system with a regular USB port.
+
+2. Software requirements:
+
+ a.) On the host/target system:
+
+    You need to enable the following kernel config option:
+
+      CONFIG_EARLY_PRINTK_DBGP=y
+
+    And you need to add the boot command line: "earlyprintk=dbgp".
+    (If you are using Grub, append it to the 'kernel' line in
+     /etc/grub.conf)
+
+    NOTE: normally earlyprintk console gets turned off once the
+    regular console is alive - use "earlyprintk=dbgp,keep" to keep
+    this channel open beyond early bootup. This can be useful for
+    debugging crashes under Xorg, etc.
+
+ b.) On the client/console system:
+
+    You should enable the following kernel config option:
+
+      CONFIG_USB_SERIAL_DEBUG=y
+
+    On the next bootup with the modified kernel you should
+    get a /dev/ttyUSBx device(s).
+
+    Now this channel of kernel messages is ready to be used: start
+    your favorite terminal emulator (minicom, etc.) and set
+    it up to use /dev/ttyUSB0 - or use a raw 'cat /dev/ttyUSBx' to
+    see the raw output.
+
+ c.) On Nvidia Southbridge based systems: the kernel will try to probe
+     and find out which port has debug device connected.
+
+3. Testing that it works fine:
+
+   You can test the output by using earlyprintk=dbgp,keep and provoking
+   kernel messages on the host/target system. You can provoke a harmless
+   kernel message by for example doing:
+
+     echo h > /proc/sysrq-trigger
+
+   On the host/target system you should see this help line in "dmesg" output:
+
+     SysRq : HELP : loglevel(0-9) reBoot Crashdump terminate-all-tasks(E) memory-full-oom-kill(F) kill-all-tasks(I) saK show-backtrace-all-active-cpus(L) show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registers(P) show-all-timers(Q) unRaw Sync show-task-states(T) Unmount show-blocked-tasks(W) dump-ftrace-buffer(Z)
+
+   On the client/console system do:
+
+       cat /dev/ttyUSB0
+
+   And you should see the help line above displayed shortly after you've
+   provoked it on the host system.
+
+If it does not work then please ask about it on the linux-kernel@vger.kernel.org
+mailing list or contact the x86 maintainers.
diff -druNp linux-libre-2.6.29-gnu1/Documentation/x86/x86_64/fake-numa-for-cpusets linux-libre-2.6.30-gnu1/Documentation/x86/x86_64/fake-numa-for-cpusets
--- linux-libre-2.6.29-gnu1/Documentation/x86/x86_64/fake-numa-for-cpusets	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/Documentation/x86/x86_64/fake-numa-for-cpusets	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,8 @@ you can create fake NUMA nodes that repr
 assign them to cpusets and their attached tasks.  This is a way of limiting the
 amount of system memory that are available to a certain class of tasks.
 
-For more information on the features of cpusets, see Documentation/cpusets.txt.
+For more information on the features of cpusets, see
+Documentation/cgroups/cpusets.txt.
 There are a number of different configurations you can use for your needs.  For
 more information on the numa=fake command line option and its various ways of
 configuring fake nodes, see Documentation/x86/x86_64/boot-options.txt.
@@ -32,7 +33,7 @@ A machine may be split as follows with "
 	On node 3 totalpages: 131072
 
 Now following the instructions for mounting the cpusets filesystem from
-Documentation/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
+Documentation/cgroups/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
 address spaces) to individual cpusets:
 
 	[root@xroads /]# mkdir exampleset
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/ac.c linux-libre-2.6.30-gnu1/drivers/acpi/ac.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/ac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/ac.c	2009-06-09 23:05:27.000000000 -0400
@@ -191,7 +191,6 @@ static int acpi_ac_add_fs(struct acpi_de
 						     acpi_ac_dir);
 		if (!acpi_device_dir(device))
 			return -ENODEV;
-		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'state' [R] */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acglobal.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acglobal.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acglobal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acglobal.h	2009-06-09 23:05:27.000000000 -0400
@@ -148,9 +148,12 @@ ACPI_EXTERN struct acpi_internal_rsdt ac
 ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
 ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
 
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
 
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
 
 /*
@@ -162,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_widt
 ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
 ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
 
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
 /*****************************************************************************
  *
  * Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_cal
 ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
 ACPI_EXTERN u8 acpi_gbl_events_initialized;
 ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
 
 #ifndef DEFINE_ACPI_GLOBALS
 
@@ -371,7 +379,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
 ACPI_EXTERN char *acpi_gbl_db_filename;
 ACPI_EXTERN u32 acpi_gbl_db_debug_level;
 ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
 ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/achware.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/achware.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/achware.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/achware.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,14 +64,22 @@ u32 acpi_hw_get_mode(void);
  */
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
 
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
 
 acpi_status acpi_hw_register_write(u32 register_id, u32 value);
 
 acpi_status acpi_hw_clear_acpi_status(void);
 
 /*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
  * hwgpe - GPE support
  */
 acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/aclocal.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/aclocal.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/aclocal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/aclocal.h	2009-06-09 23:05:27.000000000 -0400
@@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_N
 #endif
 #endif
 
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+	acpi_mutex writer_mutex;
+	acpi_mutex reader_mutex;
+	u32 num_readers;
+};
+
 /*
  * Predefined handles for spinlocks used within the subsystem.
  * These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,24 @@ struct acpi_bit_register_info {
  * must be preserved.
  */
 #define ACPI_PM1_STATUS_PRESERVED_BITS          0x0800	/* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS         0x0200	/* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS         0x2004	/* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+/*
+ * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0)
+ * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly
+ * as a BIOS workaround on some machines.
+ */
+#define ACPI_PM1_CONTROL_IGNORED_BITS           0x0200	/* Bits 9 */
+#define ACPI_PM1_CONTROL_RESERVED_BITS          0xC1F8	/* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+	       (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS         0xFFFFFFFE	/* All except bit 0 */
 
 /*
  * Register IDs
@@ -781,12 +806,10 @@ struct acpi_bit_register_info {
 #define ACPI_REGISTER_PM1_STATUS                0x01
 #define ACPI_REGISTER_PM1_ENABLE                0x02
 #define ACPI_REGISTER_PM1_CONTROL               0x03
-#define ACPI_REGISTER_PM1A_CONTROL              0x04
-#define ACPI_REGISTER_PM1B_CONTROL              0x05
-#define ACPI_REGISTER_PM2_CONTROL               0x06
-#define ACPI_REGISTER_PM_TIMER                  0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
+#define ACPI_REGISTER_PM2_CONTROL               0x04
+#define ACPI_REGISTER_PM_TIMER                  0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK           0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x07
 
 /* Masks used to access the bit_registers */
 
@@ -818,7 +841,7 @@ struct acpi_bit_register_info {
 #define ACPI_BITMASK_SCI_ENABLE                 0x0001
 #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
 #define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X               0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE                 0x1C00
 #define ACPI_BITMASK_SLEEP_ENABLE               0x2000
 
 #define ACPI_BITMASK_ARB_DISABLE                0x0001
@@ -844,11 +867,35 @@ struct acpi_bit_register_info {
 #define ACPI_BITPOSITION_SCI_ENABLE             0x00
 #define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
 #define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE    0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X           0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE             0x0A
 #define ACPI_BITPOSITION_SLEEP_ENABLE           0x0D
 
 #define ACPI_BITPOSITION_ARB_DISABLE            0x00
 
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000               0x01
+#define ACPI_OSI_WIN_XP                 0x02
+#define ACPI_OSI_WIN_XP_SP1             0x03
+#define ACPI_OSI_WINSRV_2003            0x04
+#define ACPI_OSI_WIN_XP_SP2             0x05
+#define ACPI_OSI_WINSRV_2003_SP1        0x06
+#define ACPI_OSI_WIN_VISTA              0x07
+
+#define ACPI_ALWAYS_ILLEGAL             0x00
+
+struct acpi_interface_info {
+	char *name;
+	u8 value;
+};
+
+struct acpi_port_info {
+	char *name;
+	u16 start;
+	u16 end;
+	u8 osi_dependency;
+};
+
 /*****************************************************************************
  *
  * Resource descriptors
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acmacros.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acmacros.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acmacros.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acmacros.h	2009-06-09 23:05:27.000000000 -0400
@@ -292,10 +292,6 @@
 #define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
 #define ACPI_SET_DESCRIPTOR_TYPE(d, t)  (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
 
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
-
 /*
  * Macros for the master AML opcode table
  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acobject.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acobject.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acobject.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acobject.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,7 +97,6 @@
 #define AOPOBJ_OBJECT_INITIALIZED   0x08
 #define AOPOBJ_SETUP_COMPLETE       0x10
 #define AOPOBJ_SINGLE_DATUM         0x20
-#define AOPOBJ_INVALID              0x40	/* Used if host OS won't allow an op_region address */
 
 /******************************************************************************
  *
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acpredef.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acpredef.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acpredef.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acpredef.h	2009-06-09 23:05:27.000000000 -0400
@@ -52,41 +52,44 @@
  * 1) PTYPE1 packages do not contain sub-packages.
  *
  * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
  *
  * ACPI_PTYPE1_VAR: Variable length:
- *    object type (Int/Buf/Ref)
+ *      object type (Int/Buf/Ref)
  *
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- *      Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ *      (Used for _PRW)
  *
  *
  * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
  *    different types describe the contents of each of the sub-packages.
  *
  * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
  *
  * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- *     object type
+ *      object type
+ *      (Used for _CSD,_PSD,_TSD)
  *
  * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _CST)
  *
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- *      Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ *      (Used for _PRT)
  *
  * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- *      Used for _HPX
+ *      (Used for _HPX)
  *
  *****************************************************************************/
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/actables.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/actables.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/actables.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/actables.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_ta
 
 void acpi_tb_terminate(void);
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
 
 acpi_status acpi_tb_allocate_owner_id(u32 table_index);
 
@@ -109,9 +109,8 @@ acpi_tb_verify_checksum(struct acpi_tabl
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index);
+		      char *signature, u32 table_index);
 
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
 
 #endif				/* __ACTABLES_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acutils.h linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acutils.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/acutils.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/acutils.h	2009-06-09 23:05:27.000000000 -0400
@@ -346,6 +346,21 @@ acpi_status
 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
 
 /*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
  * utobject - internal object create/delete/cache routines
  */
 union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsinit.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsinit.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsinit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsinit.c	2009-06-09 23:05:27.000000000 -0400
@@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_ind
 
 	/* Walk entire namespace from the supplied root */
 
-	status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-				     acpi_ds_init_one_object, &info, NULL);
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * We don't use acpi_walk_namespace since we do not want to acquire
+	 * the namespace reader lock.
+	 */
+	status =
+	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+				   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+				   &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 	status = acpi_get_table_by_index(table_index, &table);
 	if (ACPI_FAILURE(status)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsmthdat.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsmthdat.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsmthdat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsmthdat.c	2009-06-09 23:05:27.000000000 -0400
@@ -713,6 +713,6 @@ acpi_ds_method_data_get_type(u16 opcode,
 
 	/* Get the object type */
 
-	return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+	return_VALUE(object->type);
 }
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsobject.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsobject.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsobject.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsobject.c	2009-06-09 23:05:27.000000000 -0400
@@ -565,7 +565,7 @@ acpi_ds_create_node(struct acpi_walk_sta
 
 	/* Re-type the object according to its argument */
 
-	node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	node->type = obj_desc->common.type;
 
 	/* Attach obj to node */
 
@@ -619,7 +619,7 @@ acpi_ds_init_object_from_op(struct acpi_
 
 	/* Perform per-object initialization */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/*
@@ -803,7 +803,7 @@ acpi_ds_init_object_from_op(struct acpi_
 	default:
 
 		ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsopcode.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsopcode.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsopcode.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsopcode.c	2009-06-09 23:05:27.000000000 -0400
@@ -397,30 +397,6 @@ acpi_status acpi_ds_get_region_arguments
 	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	/* Validate the region address/length via the host OS */
-
-	status = acpi_os_validate_address(obj_desc->region.space_id,
-					  obj_desc->region.address,
-					  (acpi_size) obj_desc->region.length,
-					  acpi_ut_get_node_name(node));
-
-	if (ACPI_FAILURE(status)) {
-		/*
-		 * Invalid address/length. We will emit an error message and mark
-		 * the region as invalid, so that it will cause an additional error if
-		 * it is ever used. Then return AE_OK.
-		 */
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During address validation of OpRegion [%4.4s]",
-				node->name.ascii));
-		obj_desc->common.flags |= AOPOBJ_INVALID;
-		status = AE_OK;
-	}
-
 	return_ACPI_STATUS(status);
 }
 
@@ -484,7 +460,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode
 
 	/* Host object must be a Buffer */
 
-	if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+	if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
 		ACPI_ERROR((AE_INFO,
 			    "Target of Create Field is not a Buffer object - %s",
 			    acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@ acpi_ds_exec_end_control_op(struct acpi_
 			if ((ACPI_GET_DESCRIPTOR_TYPE
 			     (walk_state->results->results.obj_desc[0]) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    &&
-			    (ACPI_GET_OBJECT_TYPE
-			     (walk_state->results->results.obj_desc[0]) ==
-			     ACPI_TYPE_LOCAL_REFERENCE)
+			    && ((walk_state->results->results.obj_desc[0])->
+				common.type == ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((walk_state->results->results.obj_desc[0])->
 				reference.class != ACPI_REFCLASS_INDEX)) {
 				status =
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsutils.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsutils.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dsutils.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dsutils.c	2009-06-09 23:05:27.000000000 -0400
@@ -816,7 +816,7 @@ acpi_status acpi_ds_evaluate_name_path(s
 		goto push_result;
 	}
 
-	type = ACPI_GET_OBJECT_TYPE(*operand);
+	type = (*operand)->common.type;
 
 	status = acpi_ex_resolve_to_value(operand, walk_state);
 	if (ACPI_FAILURE(status)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dswexec.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dswexec.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/dswexec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/dswexec.c	2009-06-09 23:05:27.000000000 -0400
@@ -138,11 +138,10 @@ acpi_ds_get_predicate_value(struct acpi_
 		goto cleanup;
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+	if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
 		ACPI_ERROR((AE_INFO,
 			    "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
-			    obj_desc, walk_state,
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc, walk_state, obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evevent.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evevent.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evevent.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evevent.c	2009-06-09 23:05:27.000000000 -0400
@@ -183,7 +183,7 @@ acpi_status acpi_ev_install_xrupt_handle
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
  *
  ******************************************************************************/
 
@@ -200,12 +200,13 @@ static acpi_status acpi_ev_fixed_event_i
 		acpi_gbl_fixed_event_handlers[i].handler = NULL;
 		acpi_gbl_fixed_event_handlers[i].context = NULL;
 
-		/* Enable the fixed event */
+		/* Disable the fixed event */
 
 		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
 			status =
-			    acpi_set_register(acpi_gbl_fixed_event_info[i].
-					      enable_register_id, 0);
+			    acpi_write_bit_register(acpi_gbl_fixed_event_info
+						    [i].enable_register_id,
+						    ACPI_DISABLE_EVENT);
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
@@ -288,16 +289,17 @@ static u32 acpi_ev_fixed_event_dispatch(
 
 	/* Clear the status bit */
 
-	(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-				status_register_id, 1);
+	(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				      status_register_id, ACPI_CLEAR_STATUS);
 
 	/*
 	 * Make sure we've got a handler. If not, report an error. The event is
 	 * disabled to prevent further interrupts.
 	 */
 	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
-		(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-					enable_register_id, 0);
+		(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+					      enable_register_id,
+					      ACPI_DISABLE_EVENT);
 
 		ACPI_ERROR((AE_INFO,
 			    "No installed handler for fixed event [%08X]",
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evgpeblk.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evgpeblk.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evgpeblk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evgpeblk.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,9 +104,9 @@ u8 acpi_ev_valid_gpe_event(struct acpi_g
 
 		while (gpe_block) {
 			if ((&gpe_block->event_info[0] <= gpe_event_info) &&
-			    (&gpe_block->
-			     event_info[((acpi_size) gpe_block->
-					 register_count) * 8] >
+			    (&gpe_block->event_info[((acpi_size)
+						     gpe_block->
+						     register_count) * 8] >
 			     gpe_event_info)) {
 				return (TRUE);
 			}
@@ -210,10 +210,9 @@ acpi_ev_delete_gpe_handlers(struct acpi_
 		/* Now look at the individual GPEs in this byte register */
 
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
 			    ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@ acpi_ev_save_method_info(acpi_handle obj
 		/* Unknown method type, just ignore it! */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
-				  name));
+				  "Ignoring unknown GPE method type: %s "
+				  "(name not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -306,17 +305,16 @@ acpi_ev_save_method_info(acpi_handle obj
 		/* Conversion failed; invalid method, just ignore it */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
-				  name));
+				  "Could not extract GPE number from name: %s "
+				  "(name is not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
 	/* Ensure that we have a valid GPE number for this GPE block */
 
 	if ((gpe_number < gpe_block->block_base_number) ||
-	    (gpe_number >=
-	     (gpe_block->block_base_number +
-	      (gpe_block->register_count * 8)))) {
+	    (gpe_number >= (gpe_block->block_base_number +
+			    (gpe_block->register_count * 8)))) {
 		/*
 		 * Not valid for this GPE block, just ignore it. However, it may be
 		 * valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
 	 */
 	obj_desc = pkg_desc->package.elements[0];
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Use FADT-defined GPE device (from definition of _PRW) */
 
@@ -417,15 +415,15 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
 		/* Integer is the GPE number in the FADT described GPE blocks */
 
 		gpe_number = (u32) obj_desc->integer.value;
-	} else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	} else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Package contains a GPE reference and GPE number within a GPE block */
 
 		if ((obj_desc->package.count < 2) ||
-		    (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
-		     ACPI_TYPE_LOCAL_REFERENCE)
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
-			ACPI_TYPE_INTEGER)) {
+		    ((obj_desc->package.elements[0])->common.type !=
+		     ACPI_TYPE_LOCAL_REFERENCE) ||
+		    ((obj_desc->package.elements[1])->common.type !=
+		     ACPI_TYPE_INTEGER)) {
 			goto cleanup;
 		}
 
@@ -450,11 +448,11 @@ acpi_ev_match_prw_and_gpe(acpi_handle ob
 	 */
 	if ((gpe_device == target_gpe_device) &&
 	    (gpe_number >= gpe_block->block_base_number) &&
-	    (gpe_number <
-	     gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-		gpe_event_info =
-		    &gpe_block->event_info[gpe_number -
-					   gpe_block->block_base_number];
+	    (gpe_number < gpe_block->block_base_number +
+	     (gpe_block->register_count * 8))) {
+		gpe_event_info = &gpe_block->event_info[gpe_number -
+							gpe_block->
+							block_base_number];
 
 		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
 
@@ -1033,8 +1031,8 @@ acpi_ev_initialize_gpe_block(struct acpi
 	 * 1) are "runtime" or "run/wake" GPEs, and
 	 * 2) have a corresponding _Lxx or _Exx method
 	 *
-	 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
-	 * external interface.
+	 * Any other GPEs within this block must be enabled via the
+	 * acpi_enable_gpe() external interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@ acpi_ev_initialize_gpe_block(struct acpi
 
 			/* Get the info block for this particular GPE */
 
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
-			     ACPI_GPE_DISPATCH_METHOD)
-			    && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+			     ACPI_GPE_DISPATCH_METHOD) &&
+			    (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
 				gpe_enabled_count++;
 			}
 
@@ -1105,8 +1102,8 @@ acpi_status acpi_ev_gpe_initialize(void)
 	/*
 	 * Initialize the GPE Block(s) defined in the FADT
 	 *
-	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
-	 * section "General-Purpose Event Registers", we have:
+	 * Why the GPE register block lengths are divided by 2:  From the ACPI
+	 * Spec, section "General-Purpose Event Registers", we have:
 	 *
 	 * "Each register block contains two registers of equal length
 	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@ acpi_status acpi_ev_gpe_initialize(void)
 		if ((register_count0) &&
 		    (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
 			ACPI_ERROR((AE_INFO,
-				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+				    "(GPE %d to %d) - Ignoring GPE1",
 				    gpe_number_max, acpi_gbl_FADT.gpe1_base,
 				    acpi_gbl_FADT.gpe1_base +
 				    ((register_count1 *
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evgpe.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evgpe.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evgpe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evgpe.c	2009-06-09 23:05:27.000000000 -0400
@@ -88,10 +88,10 @@ acpi_ev_set_gpe_type(struct acpi_gpe_eve
 
 	status = acpi_ev_disable_gpe(gpe_event_info);
 
-	/* Type was validated above */
+	/* Clear the type bits and insert the new Type */
 
-	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;	/* Clear type bits */
-	gpe_event_info->flags |= type;	/* Insert type */
+	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+	gpe_event_info->flags |= type;
 	return_ACPI_STATUS(status);
 }
 
@@ -122,6 +122,7 @@ acpi_ev_update_gpe_enable_masks(struct a
 	if (!gpe_register_info) {
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
+
 	register_bit = (u8)
 	    (1 <<
 	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evmisc.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evmisc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evmisc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evmisc.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,10 +163,10 @@ acpi_ev_queue_notify_request(struct acpi
 	 * 2) Global device notify handler
 	 * 3) Per-device notify handler
 	 */
-	if ((acpi_gbl_system_notify.handler
-	     && (notify_value <= ACPI_MAX_SYS_NOTIFY))
-	    || (acpi_gbl_device_notify.handler
-		&& (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+	if ((acpi_gbl_system_notify.handler &&
+	     (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+	    (acpi_gbl_device_notify.handler &&
+	     (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
 		notify_info = acpi_ut_create_generic_state();
 		if (!notify_info) {
 			return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@ acpi_ev_queue_notify_request(struct acpi
 
 		if (!handler_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+					  "Executing system notify handler for Notify (%4.4s, %X) "
+					  "node %p\n",
 					  acpi_ut_get_node_name(node),
 					  notify_value, node));
 		}
@@ -534,8 +535,9 @@ acpi_status acpi_ev_release_global_lock(
 		 */
 		if (pending) {
 			status =
-			    acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
-					      1);
+			    acpi_write_bit_register
+			    (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+			     ACPI_ENABLE_EVENT);
 		}
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evregion.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evregion.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evregion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evregion.c	2009-06-09 23:05:27.000000000 -0400
@@ -691,7 +691,7 @@ acpi_ev_install_handler(acpi_handle obj_
 
 	/* Devices are handled different than regions */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+	if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
 
 		/* Check if this Device already has a handler for this address space */
 
@@ -703,7 +703,8 @@ acpi_ev_install_handler(acpi_handle obj_
 			if (next_handler_obj->address_space.space_id ==
 			    handler_obj->address_space.space_id) {
 				ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-						  "Found handler for region [%s] in device %p(%p) handler %p\n",
+						  "Found handler for region [%s] in device %p(%p) "
+						  "handler %p\n",
 						  acpi_ut_get_region_name
 						  (handler_obj->address_space.
 						   space_id), obj_desc,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evrgnini.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evrgnini.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evrgnini.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evrgnini.c	2009-06-09 23:05:27.000000000 -0400
@@ -241,7 +241,8 @@ acpi_ev_pci_config_region_setup(acpi_han
 						status = AE_OK;
 					} else {
 						ACPI_EXCEPTION((AE_INFO, status,
-								"Could not install PciConfig handler for Root Bridge %4.4s",
+								"Could not install PciConfig handler "
+								"for Root Bridge %4.4s",
 								acpi_ut_get_node_name
 								(pci_root_node)));
 					}
@@ -293,9 +294,8 @@ acpi_ev_pci_config_region_setup(acpi_han
 	 * Get the PCI device and function numbers from the _ADR object contained
 	 * in the parent's scope.
 	 */
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+						 pci_device_node, &pci_value);
 
 	/*
 	 * The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@ acpi_ev_pci_config_region_setup(acpi_han
 
 	/* The PCI segment number comes from the _SEG method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->segment = ACPI_LOWORD(pci_value);
 	}
 
 	/* The PCI bus number comes from the _BBN method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->bus = ACPI_LOWORD(pci_value);
 	}
@@ -632,8 +630,8 @@ acpi_ev_initialize_region(union acpi_ope
 								  acpi_ns_locked);
 
 					/*
-					 * Tell all users that this region is usable by running the _REG
-					 * method
+					 * Tell all users that this region is usable by
+					 * running the _REG method
 					 */
 					if (acpi_ns_locked) {
 						status =
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxface.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxface.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxface.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxface.c	2009-06-09 23:05:27.000000000 -0400
@@ -631,7 +631,8 @@ acpi_install_gpe_handler(acpi_handle gpe
 
 	/* Setup up dispatch flags to indicate handler (vs. method) */
 
-	gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);	/* Clear bits */
+	gpe_event_info->flags &=
+	    ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
 
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxfevnt.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxfevnt.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxfevnt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxfevnt.c	2009-06-09 23:05:27.000000000 -0400
@@ -172,8 +172,8 @@ acpi_status acpi_enable_event(u32 event,
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_ENABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -181,8 +181,8 @@ acpi_status acpi_enable_event(u32 event,
 	/* Make sure that the hardware responded */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -354,15 +354,15 @@ acpi_status acpi_disable_event(u32 event
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 0);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_DISABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -407,8 +407,8 @@ acpi_status acpi_clear_event(u32 event)
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    status_register_id, ACPI_CLEAR_STATUS);
 
 	return_ACPI_STATUS(status);
 }
@@ -495,7 +495,7 @@ acpi_status acpi_get_event_status(u32 ev
 	/* Get the status of the requested fixed event */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      enable_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@ acpi_status acpi_get_event_status(u32 ev
 	*event_status = value;
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      status_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxfregn.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxfregn.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/evxfregn.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/evxfregn.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,8 @@ acpi_remove_address_space_handler(acpi_h
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-					  "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+					  "Removing address handler %p(%p) for region %s "
+					  "on Device %p(%p)\n",
 					  handler_obj, handler,
 					  acpi_ut_get_region_name(space_id),
 					  node, obj_desc));
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exconfig.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exconfig.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exconfig.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exconfig.c	2009-06-09 23:05:27.000000000 -0400
@@ -291,7 +291,7 @@ acpi_ex_load_op(union acpi_operand_objec
 
 	/* Source Object can be either an op_region or a Buffer/Field */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_REGION:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@ acpi_status acpi_ex_unload_table(union a
 	 */
 	if ((!ddb_handle) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+	    (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union a
 		}
 	}
 
-	/*
-	 * Delete the entire namespace under this table Node
-	 * (Offset contains the table_id)
-	 */
-	acpi_tb_delete_namespace_by_owner(table_index);
-	(void)acpi_tb_release_owner_id(table_index);
+	/* Delete the portion of the namespace owned by this table */
+
+	status = acpi_tb_delete_namespace_by_owner(table_index);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
+	(void)acpi_tb_release_owner_id(table_index);
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
 	/* Table unloaded, remove a reference to the ddb_handle object */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exconvrt.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exconvrt.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exconvrt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exconvrt.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,7 +82,7 @@ acpi_ex_convert_to_integer(union acpi_op
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* No conversion necessary */
@@ -116,7 +116,7 @@ acpi_ex_convert_to_integer(union acpi_op
 
 	/* String conversion is different than Buffer conversion */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/*
@@ -206,7 +206,7 @@ acpi_ex_convert_to_buffer(union acpi_ope
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/* No conversion necessary */
@@ -409,7 +409,7 @@ acpi_ex_convert_to_string(union acpi_ope
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/* No conversion necessary */
@@ -605,8 +605,7 @@ acpi_ex_convert_to_target_type(acpi_obje
 		default:
 			/* No conversion allowed for these types */
 
-			if (destination_type !=
-			    ACPI_GET_OBJECT_TYPE(source_desc)) {
+			if (destination_type != source_desc->common.type) {
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "Explicit operator, will store (%s) over existing type (%s)\n",
 						  acpi_ut_get_object_type_name
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exdump.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exdump.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exdump.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exdump.c	2009-06-09 23:05:27.000000000 -0400
@@ -350,6 +350,7 @@ acpi_ex_dump_object(union acpi_operand_o
 			break;
 
 		case ACPI_EXD_TYPE:
+
 			acpi_ex_out_string("Type",
 					   acpi_ut_get_object_type_name
 					   (obj_desc));
@@ -422,6 +423,7 @@ acpi_ex_dump_object(union acpi_operand_o
 			break;
 
 		default:
+
 			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
 				       info->opcode);
 			return;
@@ -492,7 +494,7 @@ void acpi_ex_dump_operand(union acpi_ope
 
 	/* Decode object type */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		acpi_os_printf("Reference: [%s] ",
@@ -527,44 +529,16 @@ void acpi_ex_dump_operand(union acpi_ope
 							     type));
 			break;
 
-		case ACPI_REFCLASS_ARG:
-
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
+		case ACPI_REFCLASS_NAME:
 
-			acpi_os_printf("\n");
+			acpi_os_printf("- [%4.4s]\n",
+				       obj_desc->reference.node->name.ascii);
 			break;
 
+		case ACPI_REFCLASS_ARG:
 		case ACPI_REFCLASS_LOCAL:
 
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
-
-			acpi_os_printf("\n");
-			break;
-
-		case ACPI_REFCLASS_NAME:
-
-			acpi_os_printf("- [%4.4s]\n",
-				       obj_desc->reference.node->name.ascii);
+			acpi_os_printf("%X\n", obj_desc->reference.value);
 			break;
 
 		default:	/* Unknown reference class */
@@ -661,8 +635,8 @@ void acpi_ex_dump_operand(union acpi_ope
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 
 		acpi_os_printf
-		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
-		     obj_desc->field.bit_length,
+		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+		     "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
 		     obj_desc->field.access_byte_width,
 		     obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
 		     obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@ void acpi_ex_dump_operand(union acpi_ope
 
 		if (!obj_desc->buffer_field.buffer_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
-		} else
-		    if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
-			!= ACPI_TYPE_BUFFER) {
+		} else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+			   ACPI_TYPE_BUFFER) {
 			acpi_os_printf("*not a Buffer*\n");
 		} else {
 			acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@ void acpi_ex_dump_operand(union acpi_ope
 	default:
 		/* Unknown Type */
 
-		acpi_os_printf("Unknown Type %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
 		break;
 	}
 
@@ -939,7 +911,7 @@ acpi_ex_dump_package_obj(union acpi_oper
 
 	/* Packages may only contain a few object types */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@ acpi_ex_dump_package_obj(union acpi_oper
 
 	default:
 
-		acpi_os_printf("[Unknown Type] %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exfield.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exfield.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exfield.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exfield.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,7 +84,7 @@ acpi_ex_read_data_from_field(struct acpi
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -95,9 +95,8 @@ acpi_ex_read_data_from_field(struct acpi
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus read.  We must create a buffer to hold the data
@@ -163,7 +162,7 @@ acpi_ex_read_data_from_field(struct acpi
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [TO]:   Obj %p, Type %X, Buf %p, ByteLen %X\n",
-			  obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+			  obj_desc, obj_desc->common.type, buffer,
 			  (u32) length));
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@ acpi_ex_write_data_to_field(union acpi_o
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -233,9 +232,8 @@ acpi_ex_write_data_to_field(union acpi_o
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus write.  We will bypass the entire field mechanism
@@ -243,7 +241,7 @@ acpi_ex_write_data_to_field(union acpi_o
 		 *
 		 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO,
 				    "SMBus write requires Buffer, found type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@ acpi_ex_write_data_to_field(union acpi_o
 
 	/* Get a pointer to the data to be written */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 		buffer = &source_desc->integer.value;
 		length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@ acpi_ex_write_data_to_field(union acpi_o
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
 			  source_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						(source_desc)),
-			  ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+			  acpi_ut_get_type_name(source_desc->common.type),
+			  source_desc->common.type, buffer, length));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
 			  obj_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
-			  ACPI_GET_OBJECT_TYPE(obj_desc),
+			  acpi_ut_get_type_name(obj_desc->common.type),
+			  obj_desc->common.type,
 			  obj_desc->common_field.bit_length,
 			  obj_desc->common_field.start_field_bit_offset,
 			  obj_desc->common_field.base_byte_offset));
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exfldio.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exfldio.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exfldio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exfldio.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_
 
 	/* We must have a valid region */
 
-	if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+	if (rgn_desc->common.type != ACPI_TYPE_REGION) {
 		ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
-			    ACPI_GET_OBJECT_TYPE(rgn_desc),
+			    rgn_desc->common.type,
 			    acpi_ut_get_object_type_name(rgn_desc)));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@ acpi_ex_setup_region(union acpi_operand_
 		}
 	}
 
-	/* Exit if Address/Length have been disallowed by the host OS */
-
-	if (rgn_desc->common.flags & AOPOBJ_INVALID) {
-		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
-	}
-
 	/*
 	 * Exit now for SMBus address space, it has a non-linear address space
 	 * and the request cannot be directly validated
@@ -390,7 +384,7 @@ acpi_ex_field_datum_io(union acpi_operan
 	 * index_field - Write to an Index Register, then read/write from/to a
 	 *               Data Register
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER_FIELD:
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@ acpi_ex_field_datum_io(union acpi_operan
 	default:
 
 		ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 		status = AE_AML_INTERNAL;
 		break;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exmisc.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exmisc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exmisc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exmisc.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,7 @@ acpi_ex_get_object_reference(union acpi_
 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
 
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+		if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -260,7 +260,7 @@ acpi_ex_do_concatenate(union acpi_operan
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@ acpi_ex_do_concatenate(union acpi_operan
 
 	default:
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 	}
 
@@ -298,7 +298,7 @@ acpi_ex_do_concatenate(union acpi_operan
 	 * 2) Two Strings concatenated to produce a new String
 	 * 3) Two Buffers concatenated to produce a new Buffer
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@ acpi_ex_do_concatenate(union acpi_operan
 		/* Invalid object type, should not happen here */
 
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 		goto cleanup;
 	}
@@ -581,7 +581,7 @@ acpi_ex_do_logical_op(u16 opcode,
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@ acpi_ex_do_logical_op(u16 opcode,
 	/*
 	 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
 	 */
-	if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+	if (operand0->common.type == ACPI_TYPE_INTEGER) {
 		/*
 		 * 1) Both operands are of type integer
 		 *    Note: local_operand1 may have changed above
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg1.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg1.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg1.c	2009-06-09 23:05:27.000000000 -0400
@@ -807,11 +807,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 							 acpi_namespace_node *)
 							operand[0]);
 			if (temp_desc
-			    &&
-			    ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
-			      ACPI_TYPE_STRING)
-			     || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
-				 ACPI_TYPE_LOCAL_REFERENCE))) {
+			    && ((temp_desc->common.type == ACPI_TYPE_STRING)
+				|| (temp_desc->common.type ==
+				    ACPI_TYPE_LOCAL_REFERENCE))) {
 				operand[0] = temp_desc;
 				acpi_ut_add_reference(temp_desc);
 			} else {
@@ -819,7 +817,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 				goto cleanup;
 			}
 		} else {
-			switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+			switch ((operand[0])->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 				/*
 				 * This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 
 		if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
 		    ACPI_DESC_TYPE_NAMED) {
-			if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
-			    ACPI_TYPE_STRING) {
+			if ((operand[0])->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * This is a deref_of (String). The string is a reference
 				 * to a named ACPI object.
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg2.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg2.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg2.c	2009-06-09 23:05:27.000000000 -0400
@@ -399,7 +399,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 		 * At this point, the Source operand is a String, Buffer, or Package.
 		 * Verify that the index is within range.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			if (index >= operand[0]->string.length) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg3.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg3.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exoparg3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exoparg3.c	2009-06-09 23:05:27.000000000 -0400
@@ -161,9 +161,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 		 * Create the return object.  The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
 		 */
-		return_desc =
-		    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-						   (operand[0]));
+		return_desc = acpi_ut_create_internal_object((operand[0])->
+							     common.type);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -191,7 +190,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 
 		/* Strings always have a sub-pointer, not so for buffers */
 
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			/* Always allocate a new buffer for the String */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exprep.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exprep.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exprep.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exprep.c	2009-06-09 23:05:27.000000000 -0400
@@ -279,7 +279,7 @@ acpi_ex_decode_field_access(union acpi_o
 		return_UINT32(0);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * buffer_field access can be on any byte boundary, so the
 		 * byte_alignment is always 1 byte -- regardless of any byte_alignment
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exregion.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exregion.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exregion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exregion.c	2009-06-09 23:05:27.000000000 -0400
@@ -294,14 +294,14 @@ acpi_ex_system_io_space_handler(u32 func
 	switch (function) {
 	case ACPI_READ:
 
-		status = acpi_os_read_port((acpi_io_address) address,
+		status = acpi_hw_read_port((acpi_io_address) address,
 					   &value32, bit_width);
 		*value = value32;
 		break;
 
 	case ACPI_WRITE:
 
-		status = acpi_os_write_port((acpi_io_address) address,
+		status = acpi_hw_write_port((acpi_io_address) address,
 					    (u32) * value, bit_width);
 		break;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresnte.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresnte.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresnte.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresnte.c	2009-06-09 23:05:27.000000000 -0400
@@ -136,7 +136,7 @@ acpi_ex_resolve_node_to_value(struct acp
 	switch (entry_type) {
 	case ACPI_TYPE_PACKAGE:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+		if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@ acpi_ex_resolve_node_to_value(struct acp
 
 	case ACPI_TYPE_BUFFER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@ acpi_ex_resolve_node_to_value(struct acp
 
 	case ACPI_TYPE_STRING:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+		if (source_desc->common.type != ACPI_TYPE_STRING) {
 			ACPI_ERROR((AE_INFO, "Object not a String, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@ acpi_ex_resolve_node_to_value(struct acp
 
 	case ACPI_TYPE_INTEGER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+		if (source_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresolv.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresolv.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresolv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresolv.c	2009-06-09 23:05:27.000000000 -0400
@@ -149,7 +149,7 @@ acpi_ex_resolve_object_to_value(union ac
 
 	/* This is a union acpi_operand_object    */
 
-	switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+	switch (stack_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@ acpi_ex_resolve_object_to_value(union ac
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "FieldRead SourceDesc=%p Type=%X\n",
-				  stack_desc,
-				  ACPI_GET_OBJECT_TYPE(stack_desc)));
+				  stack_desc, stack_desc->common.type));
 
 		status =
 		    acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@ acpi_ex_resolve_multiple(struct acpi_wal
 	 * specification of the object_type and size_of operators). This means
 	 * traversing the list of possibly many nested references.
 	 */
-	while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+	while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		switch (obj_desc->reference.class) {
 		case ACPI_REFCLASS_REFOF:
 		case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@ acpi_ex_resolve_multiple(struct acpi_wal
 	 * Now we are guaranteed to have an object that has not been created
 	 * via the ref_of or Index operators.
 	 */
-	type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	type = obj_desc->common.type;
 
       exit:
 	/* Convert internal types to external types */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresop.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresop.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exresop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exresop.c	2009-06-09 23:05:27.000000000 -0400
@@ -212,7 +212,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* ACPI internal object */
 
-			object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			object_type = obj_desc->common.type;
 
 			/* Check for bad acpi_object_type */
 
@@ -287,8 +287,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
-				ACPI_TYPE_STRING)) {
+			    && (obj_desc->common.type == ACPI_TYPE_STRING)) {
 				/*
 				 * String found - the string references a named object and
 				 * must be resolved to a node
@@ -336,7 +335,7 @@ acpi_ex_resolve_operands(u16 opcode,
 			 * -- All others must be resolved below.
 			 */
 			if ((opcode == AML_STORE_OP) &&
-			    (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+			    ((*stack_ptr)->common.type ==
 			     ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
 				goto next_operand;
@@ -490,7 +489,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Need an operand of type INTEGER, STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Need an operand of type STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
 
@@ -553,7 +552,7 @@ acpi_ex_resolve_operands(u16 opcode,
 			 * The only reference allowed here is a direct reference to
 			 * a namespace node.
 			 */
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Need a buffer or package or (ACPI 2.0) String */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_BUFFER:
 			case ACPI_TYPE_REGION:
 
@@ -619,7 +618,7 @@ acpi_ex_resolve_operands(u16 opcode,
 
 			/* Used by the Store() operator only */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@ acpi_ex_resolve_operands(u16 opcode,
 		 * required object type (Simple cases only).
 		 */
 		status = acpi_ex_check_object_type(type_needed,
-						   ACPI_GET_OBJECT_TYPE
-						   (*stack_ptr), *stack_ptr);
+						   (*stack_ptr)->common.type,
+						   *stack_ptr);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exstore.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exstore.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exstore.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exstore.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,7 @@ acpi_ex_do_debug_object(union acpi_opera
 
 	/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Output correct integer width */
@@ -324,7 +324,7 @@ acpi_ex_store(union acpi_operand_object
 
 	/* Destination object must be a Reference or a Constant object */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 		break;
 
@@ -460,9 +460,8 @@ acpi_ex_store_object_to_index(union acpi
 		 */
 		obj_desc = *(index_desc->reference.where);
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE
-		    && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 
 			/* This is a DDBHandle, just add a reference to it */
 
@@ -520,8 +519,8 @@ acpi_ex_store_object_to_index(union acpi
 		 * by the INDEX_OP code.
 		 */
 		obj_desc = index_desc->reference.object;
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -529,7 +528,7 @@ acpi_ex_store_object_to_index(union acpi
 		 * The assignment of the individual elements will be slightly
 		 * different for each source type.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+		switch (source_desc->common.type) {
 		case ACPI_TYPE_INTEGER:
 
 			/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@ acpi_ex_store_object_to_node(union acpi_
 		/* No conversions for all other types.  Just attach the source object */
 
 		status = acpi_ns_attach_object(node, source_desc,
-					       ACPI_GET_OBJECT_TYPE
-					       (source_desc));
+					       source_desc->common.type);
 		break;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exstoren.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exstoren.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exstoren.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exstoren.c	2009-06-09 23:05:27.000000000 -0400
@@ -96,8 +96,7 @@ acpi_ex_resolve_object(union acpi_operan
 		 * are all essentially the same.  This case handles the
 		 * "interchangeable" types Integer, String, and Buffer.
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 
 			/* Resolve a reference object first */
 
@@ -117,13 +116,11 @@ acpi_ex_resolve_object(union acpi_operan
 
 		/* Must have a Integer, Buffer, or String */
 
-		if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
-		    !((ACPI_GET_OBJECT_TYPE(source_desc) ==
-		       ACPI_TYPE_LOCAL_REFERENCE)
-		      && (source_desc->reference.class ==
-			  ACPI_REFCLASS_TABLE))) {
+		if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+		    (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (source_desc->common.type != ACPI_TYPE_STRING) &&
+		    !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+		      (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
 
 			/* Conversion successful but still not a valid type */
 
@@ -218,8 +215,7 @@ acpi_ex_store_object_to_object(union acp
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) !=
-	    ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	if (source_desc->common.type != dest_desc->common.type) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@ acpi_ex_store_object_to_object(union acp
 		 * Otherwise, actual_src_desc is a temporary object to hold the
 		 * converted object.
 		 */
-		status =
-		    acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
-						   (dest_desc), source_desc,
-						   &actual_src_desc,
-						   walk_state);
+		status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+							source_desc,
+							&actual_src_desc,
+							walk_state);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -252,7 +247,7 @@ acpi_ex_store_object_to_object(union acp
 	 * We now have two objects of identical types, and we can perform a
 	 * copy of the *value* of the source object.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		dest_desc->integer.value = actual_src_desc->integer.value;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exutils.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exutils.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/exutils.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/exutils.c	2009-06-09 23:05:27.000000000 -0400
@@ -221,7 +221,7 @@ void acpi_ex_truncate_for32bit_table(uni
 	 */
 	if ((!obj_desc) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+	    (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 		return;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwacpi.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwacpi.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwacpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwacpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
 	 */
 	if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
 		ACPI_ERROR((AE_INFO,
-			    "No ACPI mode transition supported in this system (enable/disable both zero)"));
+			    "No ACPI mode transition supported in this system "
+			    "(enable/disable both zero)"));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -95,7 +96,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
 
 		/* BIOS should have disabled ALL fixed and GP events */
 
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_enable, 8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
 		 * BIOS should clear all fixed status bits and restore fixed event
 		 * enable bits to default
 		 */
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_disable,
 					    8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@ u32 acpi_hw_get_mode(void)
 		return_UINT32(ACPI_SYS_MODE_ACPI);
 	}
 
-	status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+	status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
 	if (ACPI_FAILURE(status)) {
 		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwgpe.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwgpe.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwgpe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwgpe.c	2009-06-09 23:05:27.000000000 -0400
@@ -89,10 +89,9 @@ acpi_status acpi_hw_low_disable_gpe(stru
 
 	/* Clear just the bit that corresponds to this GPE */
 
-	ACPI_CLEAR_BIT(enable_mask,
-		       ((u32) 1 <<
-			(gpe_event_info->gpe_number -
-			 gpe_register_info->base_gpe_number)));
+	ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+				     (gpe_event_info->gpe_number -
+				      gpe_register_info->base_gpe_number)));
 
 	/* Write the updated enable mask */
 
@@ -156,10 +155,9 @@ acpi_status acpi_hw_clear_gpe(struct acp
 
 	ACPI_FUNCTION_ENTRY();
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/*
 	 * Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@ acpi_hw_get_gpe_status(struct acpi_gpe_e
 
 	/* Get the register bitmask for this GPE */
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/* GPE currently enabled? (enabled for runtime?) */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwregs.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwregs.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwregs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwregs.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,17 @@
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwregs")
 
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@ ACPI_MODULE_NAME("hwregs")
  * RETURN:      Status
  *
  * DESCRIPTION: Clears all fixed and general purpose status bits
- *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
+
 acpi_status acpi_hw_clear_acpi_status(void)
 {
 	acpi_status status;
@@ -70,28 +81,20 @@ acpi_status acpi_hw_clear_acpi_status(vo
 
 	ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
 			  ACPI_BITMASK_ALL_FIXED_STATUS,
-			  (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+			  acpi_gbl_xpm1a_status.address));
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
+	/* Clear the fixed events in PM1 A/B */
+
 	status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 					ACPI_BITMASK_ALL_FIXED_STATUS);
 	if (ACPI_FAILURE(status)) {
 		goto unlock_and_exit;
 	}
 
-	/* Clear the fixed events */
-
-	if (acpi_gbl_FADT.xpm1b_event_block.address) {
-		status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
-				    &acpi_gbl_FADT.xpm1b_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
-		}
-	}
-
 	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
 	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@ struct acpi_bit_register_info *acpi_hw_g
 
 /******************************************************************************
  *
+ * FUNCTION:    acpi_hw_write_pm1_control
+ *
+ * PARAMETERS:  pm1a_control        - Value to be written to PM1A control
+ *              pm1b_control        - Value to be written to PM1B control
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ *              different than than the PM1 A/B status and enable registers
+ *              in that different values can be written to the A/B registers.
+ *              Most notably, the SLP_TYP bits can be different, as per the
+ *              values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+	status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (acpi_gbl_FADT.xpm1b_control_block.address) {
+		status =
+		    acpi_write(pm1b_control,
+			       &acpi_gbl_FADT.xpm1b_control_block);
+	}
+	return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    acpi_hw_register_read
  *
  * PARAMETERS:  register_id         - ACPI Register ID
@@ -141,64 +180,56 @@ struct acpi_bit_register_info *acpi_hw_g
 acpi_status
 acpi_hw_register_read(u32 register_id, u32 * return_value)
 {
-	u32 value1 = 0;
-	u32 value2 = 0;
+	u32 value = 0;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(hw_register_read);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
-
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_status,
+					       &acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
-
-		status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_enable,
+					       &acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
-		value1 |= value2;
+		/*
+		 * Zero the write-only bits. From the ACPI specification, "Hardware
+		 * Write-Only Bits": "Upon reads to registers with write-only bits,
+		 * software masks out all write-only bits."
+		 */
+		value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
 
 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
 
 		status =
-		    acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+		    acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
 		break;
 
 	default:
@@ -207,10 +238,8 @@ acpi_hw_register_read(u32 register_id, u
 		break;
 	}
 
-      exit:
-
 	if (ACPI_SUCCESS(status)) {
-		*return_value = value1;
+		*return_value = value;
 	}
 
 	return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@ acpi_status acpi_hw_register_write(u32 r
 	ACPI_FUNCTION_TRACE(hw_register_write);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
-
-		/* Perform a read first to preserve certain bits (per ACPI spec) */
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
-					       &read_value);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* Insert the bits to be preserved */
-
-		ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
-				 read_value);
-
-		/* Now we can write the data */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
+		/*
+		 * Handle the "ignored" bit in PM1 Status. According to the ACPI
+		 * specification, ignored bits are to be preserved when writing.
+		 * Normally, this would mean a read/modify/write sequence. However,
+		 * preserving a bit in the status register is different. Writing a
+		 * one clears the status, and writing a zero preserves the status.
+		 * Therefore, we must always write zero to the ignored bit.
+		 *
+		 * This behavior is clarified in the ACPI 4.0 specification.
+		 */
+		value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_status,
+						&acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access */
 
-		status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_enable,
+						&acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
 		/*
 		 * Perform a read first to preserve certain bits (per ACPI spec)
+		 * Note: This includes SCI_EN, we never want to change this bit
 		 */
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &read_value);
+		status = acpi_hw_read_multiple(&read_value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
 		}
@@ -307,25 +326,29 @@ acpi_status acpi_hw_register_write(u32 r
 
 		/* Now we can write the data */
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_FADT.
+						xpm1a_control_block,
+						&acpi_gbl_FADT.
+						xpm1b_control_block);
 		break;
 
-	case ACPI_REGISTER_PM1A_CONTROL:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
-		break;
+	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
 
-	case ACPI_REGISTER_PM1B_CONTROL:	/* 16-bit access */
+		/*
+		 * For control registers, all reserved bits must be preserved,
+		 * as per the ACPI spec.
+		 */
+		status =
+		    acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
+		if (ACPI_FAILURE(status)) {
+			goto exit;
+		}
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
-		break;
+		/* Insert the bits to be preserved */
 
-	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
+		ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+				 read_value);
 
 		status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
@@ -340,10 +363,11 @@ acpi_status acpi_hw_register_write(u32 r
 		/* SMI_CMD is currently always in IO space */
 
 		status =
-		    acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+		    acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
 		break;
 
 	default:
+		ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -351,3 +375,103 @@ acpi_status acpi_hw_register_write(u32 r
       exit:
 	return_ACPI_STATUS(status);
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_multiple
+ *
+ * PARAMETERS:  Value               - Where the register value is returned
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b)
+{
+	u32 value_a = 0;
+	u32 value_b = 0;
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_read(&value_a, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Second register is optional */
+
+	if (register_b->address) {
+		status = acpi_read(&value_b, register_b);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * OR the two return values together. No shifting or masking is necessary,
+	 * because of how the PM1 registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	*value = (value_a | value_b);
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_multiple
+ *
+ * PARAMETERS:  Value               - The value to write
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b)
+{
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_write(value, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/*
+	 * Second register is optional
+	 *
+	 * No bit shifting or clearing is necessary, because of how the PM1
+	 * registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	if (register_b->address) {
+		status = acpi_write(value, register_b);
+	}
+
+	return (status);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwsleep.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwsleep.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwsleep.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwsleep.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 phys
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
 
+#if ACPI_MACHINE_WIDTH == 64
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_wak
  * RETURN:      Status
  *
  * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- *              it exists in the table.
+ *              it exists in the table. This function is intended for use with
+ *              64-bit host operating systems.
  *
  ******************************************************************************/
 acpi_status
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 ph
 }
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
 
 /*******************************************************************************
  *
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
 
-	/*
-	 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
-	 */
+	/* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
 	status = acpi_get_sleep_type_data(sleep_state,
 					  &acpi_gbl_sleep_type_a,
 					  &acpi_gbl_sleep_type_b);
@@ -209,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
 
+static unsigned int gts, bfs;
+module_param(gts, uint, 0644);
+module_param(bfs, uint, 0644);
+MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend.");
+MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_enter_sleep_state
@@ -223,8 +231,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_stat
  ******************************************************************************/
 acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 {
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
 	u32 in_value;
@@ -242,13 +250,14 @@ acpi_status asmlinkage acpi_enter_sleep_
 	}
 
 	sleep_type_reg_info =
-	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 	sleep_enable_reg_info =
 	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 	/* Clear wake status */
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -275,38 +284,41 @@ acpi_status asmlinkage acpi_enter_sleep_
 		return_ACPI_STATUS(status);
 	}
 
-	/* Execute the _GTS method */
+	if (gts) {
+		/* Execute the _GTS method */
 
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = sleep_state;
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = sleep_state;
 
-	status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		return_ACPI_STATUS(status);
+		status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
+		if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+			return_ACPI_STATUS(status);
+		}
 	}
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+				       &pm1a_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 			  "Entering sleep state [S%d]\n", sleep_state));
 
-	/* Clear SLP_EN and SLP_TYP fields */
+	/* Clear the SLP_EN and SLP_TYP fields */
 
-	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-			 sleep_enable_reg_info->access_bit_mask);
-	PM1Bcontrol = PM1Acontrol;
+	pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+			  sleep_enable_reg_info->access_bit_mask);
+	pm1b_control = pm1a_control;
 
-	/* Insert SLP_TYP bits */
+	/* Insert the SLP_TYP bits */
 
-	PM1Acontrol |=
+	pm1a_control |=
 	    (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
-	PM1Bcontrol |=
+	pm1b_control |=
 	    (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
 
 	/*
@@ -314,37 +326,25 @@ acpi_status asmlinkage acpi_enter_sleep_
 	 * poorly implemented hardware.
 	 */
 
-	/* Write #1: fill in SLP_TYP data */
-
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Write #1: write the SLP_TYP data to the PM1 Control registers */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	/* Insert SLP_ENABLE bit */
+	/* Insert the sleep enable (SLP_EN) bit */
 
-	PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
-	PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
+	pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+	pm1b_control |= sleep_enable_reg_info->access_bit_mask;
 
-	/* Write #2: SLP_TYP + SLP_EN */
+	/* Flush caches, as per ACPI specification */
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Write #2: Write both SLP_TYP + SLP_EN */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -357,8 +357,8 @@ acpi_status asmlinkage acpi_enter_sleep_
 		 * Wait ten seconds, then try again. This is to get S4/S5 to work on
 		 * all machines.
 		 *
-		 * We wait so long to allow chipsets that poll this reg very slowly to
-		 * still read the right value. Ideally, this block would go
+		 * We wait so long to allow chipsets that poll this reg very slowly
+		 * to still read the right value. Ideally, this block would go
 		 * away entirely.
 		 */
 		acpi_os_stall(10000000);
@@ -374,7 +374,7 @@ acpi_status asmlinkage acpi_enter_sleep_
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+		status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
 						    &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
@@ -408,7 +408,10 @@ acpi_status asmlinkage acpi_enter_sleep_
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	/* Clear the wake status bit (PM1) */
+
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -435,12 +438,13 @@ acpi_status asmlinkage acpi_enter_sleep_
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+	status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 				    (u32) acpi_gbl_FADT.S4bios_request, 8);
 
 	do {
 		acpi_os_stall(1000);
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+		status =
+		    acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -471,8 +475,8 @@ acpi_status acpi_leave_sleep_state_prep(
 	acpi_status status;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 
 	ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
 
@@ -486,53 +490,50 @@ acpi_status acpi_leave_sleep_state_prep(
 					  &acpi_gbl_sleep_type_b);
 	if (ACPI_SUCCESS(status)) {
 		sleep_type_reg_info =
-		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 		sleep_enable_reg_info =
 		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 		/* Get current value of PM1A control */
 
 		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &PM1Acontrol);
+					       &pm1a_control);
 		if (ACPI_SUCCESS(status)) {
 
-			/* Clear SLP_EN and SLP_TYP fields */
+			/* Clear the SLP_EN and SLP_TYP fields */
 
-			PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-					 sleep_enable_reg_info->
-					 access_bit_mask);
-			PM1Bcontrol = PM1Acontrol;
+			pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+					  sleep_enable_reg_info->
+					  access_bit_mask);
+			pm1b_control = pm1a_control;
 
-			/* Insert SLP_TYP bits */
+			/* Insert the SLP_TYP bits */
 
-			PM1Acontrol |=
-			    (acpi_gbl_sleep_type_a << sleep_type_reg_info->
-			     bit_position);
-			PM1Bcontrol |=
-			    (acpi_gbl_sleep_type_b << sleep_type_reg_info->
-			     bit_position);
+			pm1a_control |= (acpi_gbl_sleep_type_a <<
+					 sleep_type_reg_info->bit_position);
+			pm1b_control |= (acpi_gbl_sleep_type_b <<
+					 sleep_type_reg_info->bit_position);
 
-			/* Just ignore any errors */
+			/* Write the control registers and ignore any errors */
 
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-						     PM1Acontrol);
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-						     PM1Bcontrol);
+			(void)acpi_hw_write_pm1_control(pm1a_control,
+							pm1b_control);
 		}
 	}
 
-	/* Execute the _BFS method */
+	if (bfs) {
+		/* Execute the _BFS method */
 
-	arg_list.count = 1;
-	arg_list.pointer = &arg;
-	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = sleep_state;
+		arg_list.count = 1;
+		arg_list.pointer = &arg;
+		arg.type = ACPI_TYPE_INTEGER;
+		arg.integer.value = sleep_state;
 
-	status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+		status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
+		if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+			ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
+		}
 	}
-
 	return_ACPI_STATUS(status);
 }
 
@@ -603,19 +604,21 @@ acpi_status acpi_leave_sleep_state(u8 sl
 	 * it to determine whether the system is rebooting or resuming. Clear
 	 * it for compatibility.
 	 */
-	acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
 
 	acpi_gbl_system_awake_and_running = TRUE;
 
 	/* Enable power button */
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      enable_register_id, ACPI_ENABLE_EVENT);
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      status_register_id, ACPI_CLEAR_STATUS);
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwvalid.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwvalid.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwvalid.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwvalid.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,315 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * 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"
+
+#define _COMPONENT          ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ *  DMA:   DMA controller
+ *  PIC0:  Programmable Interrupt Controller (8259_a)
+ *  PIT1:  System Timer 1
+ *  PIT2:  System Timer 2 failsafe
+ *  RTC:   Real-time clock
+ *  CMOS:  Extended CMOS
+ *  DMA1:  DMA 1 page registers
+ *  DMA1L: DMA 1 Ch 0 low page
+ *  DMA2:  DMA 2 page registers
+ *  DMA2L: DMA 2 low page refresh
+ *  ARBC:  Arbitration control
+ *  SETUP: Reserved system board setup
+ *  POS:   POS channel select
+ *  PIC1:  Cascaded PIC
+ *  IDMA:  ISA DMA
+ *  ELCR:  PIC edge/level registers
+ *  PCI:   PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+	{"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+	{"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+	{"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+	{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+	{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+	{"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+	{"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+	{"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+	{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+	{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+	{"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+	{"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+	{"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+	{"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+	{"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+	{"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+	{"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES  ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_validate_io_request
+ *
+ * PARAMETERS:  Address             Address of I/O port/register
+ *              bit_width           Number of bits (8,16,32)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ *              always illegal and some ports are only illegal depending on
+ *              the requests the BIOS AML code makes to the predefined
+ *              _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+	u32 i;
+	u32 byte_width;
+	acpi_io_address last_address;
+	const struct acpi_port_info *port_info;
+
+	ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+	/* Supported widths are 8/16/32 */
+
+	if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+		return AE_BAD_PARAMETER;
+	}
+
+	port_info = acpi_protected_ports;
+	byte_width = ACPI_DIV_8(bit_width);
+	last_address = address + byte_width - 1;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+			  ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+								      last_address),
+			  byte_width));
+
+	/* Maximum 16-bit address in I/O space */
+
+	if (last_address > ACPI_UINT16_MAX) {
+		ACPI_ERROR((AE_INFO,
+			    "Illegal I/O port address/length above 64K: 0x%p/%X",
+			    ACPI_CAST_PTR(void, address), byte_width));
+		return_ACPI_STATUS(AE_LIMIT);
+	}
+
+	/* Exit if requested address is not within the protected port table */
+
+	if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Check request against the list of protected I/O ports */
+
+	for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+		/*
+		 * Check if the requested address range will write to a reserved
+		 * port. Four cases to consider:
+		 *
+		 * 1) Address range is contained completely in the port address range
+		 * 2) Address range overlaps port range at the port range start
+		 * 3) Address range overlaps port range at the port range end
+		 * 4) Address range completely encompasses the port range
+		 */
+		if ((address <= port_info->end)
+		    && (last_address >= port_info->start)) {
+
+			/* Port illegality may depend on the _OSI calls made by the BIOS */
+
+			if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+				ACPI_DEBUG_PRINT((ACPI_DB_IO,
+						  "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+						  ACPI_CAST_PTR(void, address),
+						  byte_width, port_info->name,
+						  port_info->start,
+						  port_info->end));
+
+				return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+			}
+		}
+
+		/* Finished if address range ends before the end of this port */
+
+		if (last_address <= port_info->end) {
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to read
+ *              Value               Where value is placed
+ *              Width               Number of bits
+ *
+ * RETURN:      Status and value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ *              to acpi_os_read_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+	acpi_status status;
+	u32 one_byte;
+	u32 i;
+
+	/* Validate the entire request and perform the I/O */
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_os_read_port(address, value, width);
+		return status;
+	}
+
+	if (status != AE_AML_ILLEGAL_ADDRESS) {
+		return status;
+	}
+
+	/*
+	 * There has been a protection violation within the request. Fall
+	 * back to byte granularity port I/O and ignore the failing bytes.
+	 * This provides Windows compatibility.
+	 */
+	for (i = 0, *value = 0; i < width; i += 8) {
+
+		/* Validate and read one byte */
+
+		if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+			status = acpi_os_read_port(address, &one_byte, 8);
+			if (ACPI_FAILURE(status)) {
+				return status;
+			}
+
+			*value |= (one_byte << i);
+		}
+
+		address++;
+	}
+
+	return AE_OK;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to write
+ *              Value               Value to write
+ *              Width               Number of bits
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ *              to acpi_os_write_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+	acpi_status status;
+	u32 i;
+
+	/* Validate the entire request and perform the I/O */
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_os_write_port(address, value, width);
+		return status;
+	}
+
+	if (status != AE_AML_ILLEGAL_ADDRESS) {
+		return status;
+	}
+
+	/*
+	 * There has been a protection violation within the request. Fall
+	 * back to byte granularity port I/O and ignore the failing bytes.
+	 * This provides Windows compatibility.
+	 */
+	for (i = 0; i < width; i += 8) {
+
+		/* Validate and write one byte */
+
+		if (acpi_hw_validate_io_request(address, 8) == AE_OK) {
+			status =
+			    acpi_os_write_port(address, (value >> i) & 0xFF, 8);
+			if (ACPI_FAILURE(status)) {
+				return status;
+			}
+		}
+
+		address++;
+	}
+
+	return AE_OK;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwxface.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwxface.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/hwxface.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/hwxface.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct
 	ACPI_FUNCTION_NAME(acpi_read);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct
 	*value = 0;
 
 	/*
-	 * Two address spaces supported: Memory or IO.
-	 * PCI_Config is not supported here because the GAS struct is insufficient
+	 * Two address spaces supported: Memory or IO. PCI_Config is
+	 * not supported here because the GAS structure is insufficient
 	 */
 	switch (reg->space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
 		status =
-		    acpi_os_read_port((acpi_io_address) address, value, width);
+		    acpi_hw_read_port((acpi_io_address) address, value, width);
 		break;
 
 	default:
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct
 	ACPI_FUNCTION_NAME(acpi_write);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		status = acpi_os_write_port((acpi_io_address) address, value,
+		status = acpi_hw_write_port((acpi_io_address) address, value,
 					    width);
 		break;
 
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_register_unlocked
+ * FUNCTION:    acpi_read_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              return_value    - Value that was read from the register,
+ *                                normalized to bit position zero.
  *
- * RETURN:      Status and the value read from specified Register. Value
+ * RETURN:      Status and the value read from the specified Register. Value
  *              returned is normalized to bit0 (is shifted all the way right)
  *
  * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
  *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ *       since almost all of them are single bit and it does not matter that
+ *       the parent hardware register can be split across two physical
+ *       registers. The only multi-bit field is SLP_TYP in the PM1 control
+ *       register, but this field does not cross an 8-bit boundary (nor does
+ *       it make much sense to actually read this field.)
+ *
  ******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
+	u32 register_value;
+	u32 value;
 	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+	ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Read from the register */
+	/* Read the entire parent register */
 
 	status = acpi_hw_register_read(bit_reg_info->parent_register,
 				       &register_value);
-
-	if (ACPI_SUCCESS(status)) {
-
-		/* Normalize the value that was read */
-
-		register_value =
-		    ((register_value & bit_reg_info->access_bit_mask)
-		     >> bit_reg_info->bit_position);
-
-		*return_value = register_value;
-
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
-				  register_value,
-				  bit_reg_info->parent_register));
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
-	return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+	/* Normalize the value that was read, mask off other bits */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_get_register
- *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
- *
- * RETURN:      Status and the value read from specified Register. Value
- *              returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
-	acpi_status status;
-	acpi_cpu_flags flags;
+	value = ((register_value & bit_reg_info->access_bit_mask)
+		 >> bit_reg_info->bit_position);
 
-	flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-	status = acpi_get_register_unlocked(register_id, return_value);
-	acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+			  register_id, bit_reg_info->parent_register,
+			  register_value, value));
 
-	return (status);
+	*return_value = value;
+	return_ACPI_STATUS(AE_OK);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_get_register)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_set_register
+ * FUNCTION:    acpi_write_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              Value           - (only used on write) value to write to the
- *                                Register, NOT pre-normalized to the bit pos
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              Value           - Value to write to the register, in bit
+ *                                position zero. The bit is automaticallly
+ *                                shifted to the correct position.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ *              since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
  *
  ******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
-	acpi_status status;
 	acpi_cpu_flags lock_flags;
+	u32 register_value;
+	acpi_status status = AE_OK;
 
-	ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+	ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
 	bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 	if (!bit_reg_info) {
-		ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
-			    register_id));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
-	/* Always do a register read first so we can insert the new bits  */
-
-	status = acpi_hw_register_read(bit_reg_info->parent_register,
-				       &register_value);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
 	/*
-	 * Decode the Register ID
-	 * Register ID = [Register block ID] | [bit ID]
-	 *
-	 * Check bit ID to fine locate Register offset.
-	 * Check Mask to determine Register offset, and then read-write.
+	 * At this point, we know that the parent register is one of the
+	 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
 	 */
-	switch (bit_reg_info->parent_register) {
-	case ACPI_REGISTER_PM1_STATUS:
-
-		/*
-		 * Status Registers are different from the rest. Clear by
-		 * writing 1, and writing 0 has no effect. So, the only relevant
-		 * information is the single bit we're interested in, all others should
-		 * be written as 0 so they will be left unchanged.
-		 */
-		value = ACPI_REGISTER_PREPARE_BITS(value,
-						   bit_reg_info->bit_position,
-						   bit_reg_info->
-						   access_bit_mask);
-		if (value) {
-			status =
-			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
-						   (u16) value);
-			register_value = 0;
-		}
-		break;
-
-	case ACPI_REGISTER_PM1_ENABLE:
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM1_CONTROL:
-
+	if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
 		/*
-		 * Write the PM1 Control register.
-		 * Note that at this level, the fact that there are actually TWO
-		 * registers (A and B - and B may not exist) is abstracted.
+		 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+		 *
+		 * Perform a register read to preserve the bits that we are not
+		 * interested in
 		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
-				  register_value));
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM2_CONTROL:
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+		status = acpi_hw_register_read(bit_reg_info->parent_register,
 					       &register_value);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "PM2 control: Read %X from %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
-
+		/*
+		 * Insert the input bit into the value that was just read
+		 * and write the register
+		 */
 		ACPI_REGISTER_INSERT_VALUE(register_value,
 					   bit_reg_info->bit_position,
 					   bit_reg_info->access_bit_mask,
 					   value);
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "About to write %4.4X to %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
+		status = acpi_hw_register_write(bit_reg_info->parent_register,
+						register_value);
+	} else {
+		/*
+		 * 2) Case for PM1 Status
+		 *
+		 * The Status register is different from the rest. Clear an event
+		 * by writing 1, writing 0 has no effect. So, the only relevant
+		 * information is the single bit we're interested in, all others
+		 * should be written as 0 so they will be left unchanged.
+		 */
+		register_value = ACPI_REGISTER_PREPARE_BITS(value,
+							    bit_reg_info->
+							    bit_position,
+							    bit_reg_info->
+							    access_bit_mask);
 
-		status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
-						(u8) (register_value));
-		break;
+		/* No need to write the register if value is all zeros */
 
-	default:
-		break;
+		if (register_value) {
+			status =
+			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+						   register_value);
+		}
 	}
 
-      unlock_and_exit:
-
-	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
-	/* Normalize the value that was read */
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+			  register_id, bit_reg_info->parent_register, value,
+			  register_value));
 
-	ACPI_DEBUG_EXEC(register_value =
-			((register_value & bit_reg_info->access_bit_mask) >>
-			 bit_reg_info->bit_position));
+unlock_and_exit:
 
-	ACPI_DEBUG_PRINT((ACPI_DB_IO,
-			  "Set bits: %8.8X actual %8.8X register %X\n", value,
-			  register_value, bit_reg_info->parent_register));
+	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
 	return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
 
 /*******************************************************************************
  *
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 
 	/* It must be of type Package */
 
-	else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+	else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
 		ACPI_ERROR((AE_INFO,
 			    "Sleep State return object is not a Package"));
 		status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state,
 
 	/* The first two elements must both be of type Integer */
 
-	else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+	else if (((info->return_object->package.elements[0])->common.type
 		  != ACPI_TYPE_INTEGER) ||
-		 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+		 ((info->return_object->package.elements[1])->common.type
 		  != ACPI_TYPE_INTEGER)) {
 		ACPI_ERROR((AE_INFO,
-			    "Sleep State return package elements are not both Integers (%s, %s)",
+			    "Sleep State return package elements are not both Integers "
+			    "(%s, %s)",
 			    acpi_ut_get_object_type_name(info->return_object->
 							 package.elements[0]),
 			    acpi_ut_get_object_type_name(info->return_object->
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/Makefile linux-libre-2.6.30-gnu1/drivers/acpi/acpica/Makefile
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,40 +5,43 @@
 ccflags-y			:= -Os
 ccflags-$(CONFIG_ACPI_DEBUG)	+= -DACPI_DEBUG_OUTPUT
 
-obj-y := dsfield.o   dsmthdat.o  dsopcode.o  dswexec.o  dswscope.o \
+# use acpi.o to put all files here into acpi.o modparam namespace
+obj-y	+= acpi.o
+
+acpi-y := dsfield.o   dsmthdat.o  dsopcode.o  dswexec.o  dswscope.o \
 	 dsmethod.o  dsobject.o  dsutils.o   dswload.o  dswstate.o \
 	 dsinit.o
 
-obj-y += evevent.o  evregion.o  evsci.o    evxfevnt.o \
+acpi-y += evevent.o  evregion.o  evsci.o    evxfevnt.o \
 	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
 	 evgpe.o    evgpeblk.o
 
-obj-y += exconfig.o  exfield.o  exnames.o   exoparg6.o  exresolv.o  exstorob.o\
+acpi-y += exconfig.o  exfield.o  exnames.o   exoparg6.o  exresolv.o  exstorob.o\
 	 exconvrt.o  exfldio.o  exoparg1.o  exprep.o    exresop.o   exsystem.o\
 	 excreate.o  exmisc.o   exoparg2.o  exregion.o  exstore.o   exutils.o \
 	 exdump.o    exmutex.o  exoparg3.o  exresnte.o  exstoren.o
 
-obj-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o
+acpi-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o hwvalid.o
 
-obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
+acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
 
-obj-y += nsaccess.o  nsload.o    nssearch.o  nsxfeval.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
 
-obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
+acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
 
-obj-y += psargs.o    psparse.o  psloop.o pstree.o   pswalk.o  \
+acpi-y += psargs.o    psparse.o  psloop.o pstree.o   pswalk.o  \
 	 psopcode.o  psscope.o  psutils.o  psxface.o
 
-obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
+acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
 	 rscalc.o  rsirq.o  rsmemory.o  rsutils.o
 
-obj-$(ACPI_FUTURE_USAGE) += rsdump.o
+acpi-$(ACPI_FUTURE_USAGE) += rsdump.o
 
-obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
+acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
 
-obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
+acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
 		utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
-		utstate.o utmutex.o utobject.o utresrc.o
+		utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsaccess.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsaccess.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsaccess.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsaccess.c	2009-06-09 23:05:27.000000000 -0400
@@ -118,9 +118,8 @@ acpi_status acpi_ns_root_initialize(void
 		}
 
 		/*
-		 * Name entered successfully.
-		 * If entry in pre_defined_names[] specifies an
-		 * initial value, create the initial value.
+		 * Name entered successfully. If entry in pre_defined_names[] specifies
+		 * an initial value, create the initial value.
 		 */
 		if (init_val->val) {
 			status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@ acpi_status acpi_ns_root_initialize(void
 
 			case ACPI_TYPE_STRING:
 
-				/*
-				 * Build an object around the static string
-				 */
+				/* Build an object around the static string */
+
 				obj_desc->string.length =
 				    (u32) ACPI_STRLEN(val);
 				obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@ acpi_status acpi_ns_root_initialize(void
 			/* Store pointer to value descriptor in the Node */
 
 			status = acpi_ns_attach_object(new_node, obj_desc,
-						       ACPI_GET_OBJECT_TYPE
-						       (obj_desc));
+						       obj_desc->common.type);
 
 			/* Remove local reference to the object */
 
@@ -315,10 +312,8 @@ acpi_ns_lookup(union acpi_generic_state
 		return_ACPI_STATUS(AE_NO_NAMESPACE);
 	}
 
-	/*
-	 * Get the prefix scope.
-	 * A null scope means use the root scope
-	 */
+	/* Get the prefix scope. A null scope means use the root scope */
+
 	if ((!scope_info) || (!scope_info->scope.node)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 				  "Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@ acpi_ns_lookup(union acpi_generic_state
 		if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
 			/*
 			 * This node might not be a actual "scope" node (such as a
-			 * Device/Method, etc.)  It could be a Package or other object node.
-			 * Backup up the tree to find the containing scope node.
+			 * Device/Method, etc.)  It could be a Package or other object
+			 * node. Backup up the tree to find the containing scope node.
 			 */
 			while (!acpi_ns_opens_scope(prefix_node->type) &&
 			       prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@ acpi_ns_lookup(union acpi_generic_state
 		}
 	}
 
-	/* Save type   TBD: may be no longer necessary */
+	/* Save type. TBD: may be no longer necessary */
 
 	type_to_check_for = type;
 
@@ -414,6 +409,7 @@ acpi_ns_lookup(union acpi_generic_state
 				/* Name is fully qualified, no search rules apply */
 
 				search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
 				/*
 				 * Point past this prefix to the name segment
 				 * part or the next Parent Prefix
@@ -429,7 +425,8 @@ acpi_ns_lookup(union acpi_generic_state
 					/* Current scope has no parent scope */
 
 					ACPI_ERROR((AE_INFO,
-						    "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+						    "ACPI path has too many parent prefixes (^) "
+						    "- reached beyond root node"));
 					return_ACPI_STATUS(AE_NOT_FOUND);
 				}
 			}
@@ -531,9 +528,9 @@ acpi_ns_lookup(union acpi_generic_state
 	while (num_segments && current_node) {
 		num_segments--;
 		if (!num_segments) {
-			/*
-			 * This is the last segment, enable typechecking
-			 */
+
+			/* This is the last segment, enable typechecking */
+
 			this_search_type = type;
 
 			/*
@@ -584,9 +581,9 @@ acpi_ns_lookup(union acpi_generic_state
 		if (num_segments > 0) {
 			/*
 			 * If we have an alias to an object that opens a scope (such as a
-			 * device or processor), we need to dereference the alias here so that
-			 * we can access any children of the original node (via the remaining
-			 * segments).
+			 * device or processor), we need to dereference the alias here so
+			 * that we can access any children of the original node (via the
+			 * remaining segments).
 			 */
 			if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
 				if (!this_node->object) {
@@ -594,8 +591,8 @@ acpi_ns_lookup(union acpi_generic_state
 				}
 
 				if (acpi_ns_opens_scope
-				    (((struct acpi_namespace_node *)this_node->
-				      object)->type)) {
+				    (((struct acpi_namespace_node *)
+				      this_node->object)->type)) {
 					this_node =
 					    (struct acpi_namespace_node *)
 					    this_node->object;
@@ -639,8 +636,8 @@ acpi_ns_lookup(union acpi_generic_state
 
 			/*
 			 * If this is the last name segment and we are not looking for a
-			 * specific type, but the type of found object is known, use that type
-			 * to (later) see if it opens a scope.
+			 * specific type, but the type of found object is known, use that
+			 * type to (later) see if it opens a scope.
 			 */
 			if (type == ACPI_TYPE_ANY) {
 				type = this_node->type;
@@ -653,9 +650,8 @@ acpi_ns_lookup(union acpi_generic_state
 		current_node = this_node;
 	}
 
-	/*
-	 * Always check if we need to open a new scope
-	 */
+	/* Always check if we need to open a new scope */
+
 	if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
 		/*
 		 * If entry is a type which opens a scope, push the new scope on the
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsalloc.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsalloc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsalloc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsalloc.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,8 +76,7 @@ struct acpi_namespace_node *acpi_ns_crea
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
 
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
-	temp =
-	    acpi_gbl_ns_node_list->total_allocated -
+	temp = acpi_gbl_ns_node_list->total_allocated -
 	    acpi_gbl_ns_node_list->total_freed;
 	if (temp > acpi_gbl_ns_node_list->max_occupied) {
 		acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@ void acpi_ns_delete_node(struct acpi_nam
 
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
 
-	/*
-	 * Detach an object if there is one, then delete the node
-	 */
+	/* Detach an object if there is one, then delete the node */
+
 	acpi_ns_detach_object(node);
 	(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
 	return_VOID;
@@ -183,9 +181,8 @@ void acpi_ns_install_node(struct acpi_wa
 	ACPI_FUNCTION_TRACE(ns_install_node);
 
 	/*
-	 * Get the owner ID from the Walk state
-	 * The owner ID is used to track table deletion and
-	 * deletion of objects created by methods
+	 * Get the owner ID from the Walk state. The owner ID is used to track
+	 * table deletion and deletion of objects created by methods.
 	 */
 	if (walk_state) {
 		owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@ void acpi_ns_delete_children(struct acpi
 		return_VOID;
 	}
 
-	/*
-	 * Deallocate all children at this level
-	 */
+	/* Deallocate all children at this level */
+
 	do {
 
 		/* Get the things we need */
@@ -285,9 +281,8 @@ void acpi_ns_delete_children(struct acpi
 				  "Object %p, Remaining %X\n", child_node,
 				  acpi_gbl_current_node_count));
 
-		/*
-		 * Detach an object if there is one, then free the child node
-		 */
+		/* Detach an object if there is one, then free the child node */
+
 		acpi_ns_detach_object(child_node);
 
 		/* Now we can delete the node */
@@ -304,7 +299,6 @@ void acpi_ns_delete_children(struct acpi
 	/* Clear the parent's child pointer */
 
 	parent_node->child = NULL;
-
 	return_VOID;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsdump.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsdump.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsdump.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsdump.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,6 +181,12 @@ acpi_ns_dump_one_object(acpi_handle obj_
 	}
 
 	this_node = acpi_ns_map_handle_to_node(obj_handle);
+	if (!this_node) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+				  obj_handle));
+		return (AE_OK);
+	}
+
 	type = this_node->type;
 
 	/* Check if the owner matches */
@@ -214,9 +220,8 @@ acpi_ns_dump_one_object(acpi_handle obj_
 		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
 	}
 
-	/*
-	 * Now we can print out the pertinent information
-	 */
+	/* Now we can print out the pertinent information */
+
 	acpi_os_printf(" %-12s %p %2.2X ",
 		       acpi_ut_get_type_name(type), this_node,
 		       this_node->owner_id);
@@ -509,7 +514,7 @@ acpi_ns_dump_one_object(acpi_handle obj_
 
 		case ACPI_DESC_TYPE_OPERAND:
 
-			obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			obj_type = obj_desc->common.type;
 
 			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
 				acpi_os_printf
@@ -539,9 +544,8 @@ acpi_ns_dump_one_object(acpi_handle obj_
 			goto cleanup;
 		}
 
-		/*
-		 * Valid object, get the pointer to next level, if any
-		 */
+		/* Valid object, get the pointer to next level, if any */
+
 		switch (obj_type) {
 		case ACPI_TYPE_BUFFER:
 		case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@ acpi_ns_dump_one_object(acpi_handle obj_
  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
  *                                    for an effectively unlimited depth.
- *              owner_id            - Dump only objects owned by this ID.  Use
+ *              owner_id            - Dump only objects owned by this ID. Use
  *                                    ACPI_UINT32_MAX to match all owners.
  *              start_handle        - Where in namespace to start/end search
  *
  * RETURN:      None
  *
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
  *
  ******************************************************************************/
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nseval.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nseval.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nseval.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nseval.c	2009-06-09 23:05:27.000000000 -0400
@@ -155,7 +155,7 @@ acpi_status acpi_ns_evaluate(struct acpi
 		}
 
 
-		ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+		ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
 				   ACPI_LV_INFO, _COMPONENT);
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsinit.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsinit.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsinit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsinit.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,8 @@ acpi_status acpi_ns_initialize_objects(v
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+			      "Buffers %hd/%hd Packages (%hd nodes)\n",
 			      info.op_region_init, info.op_region_count,
 			      info.field_init, info.field_count,
 			      info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@ acpi_status acpi_ns_initialize_devices(v
 	info.num_INI = 0;
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+			      "Initializing Device/Processor/Thermal objects "
+			      "by executing _INI methods:"));
 
 	/* Tree analysis: find all subtrees that contain _INI methods */
 
@@ -180,7 +182,8 @@ acpi_status acpi_ns_initialize_devices(v
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+			      "\nExecuted %hd _INI methods requiring %hd _STA executions "
+			      "(examined %hd objects)\n",
 			      info.num_INI, info.num_STA, info.device_count));
 
 	return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@ acpi_ns_init_one_object(acpi_handle obj_
 		return (AE_OK);
 	}
 
-	/*
-	 * If the object is already initialized, nothing else to do
-	 */
+	/* If the object is already initialized, nothing else to do */
+
 	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 		return (AE_OK);
 	}
 
-	/*
-	 * Must lock the interpreter before executing AML code
-	 */
+	/* Must lock the interpreter before executing AML code */
+
 	acpi_ex_enter_interpreter();
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsload.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsload.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsload.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsload.c	2009-06-09 23:05:27.000000000 -0400
@@ -128,12 +128,12 @@ acpi_ns_load_table(u32 table_index, stru
 	 * parse trees.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Begin Table Method Parsing and Object Initialization ****\n"));
+			  "**** Begin Table Method Parsing and Object Initialization\n"));
 
 	status = acpi_ds_initialize_objects(table_index, node);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Completed Table Method Parsing and Object Initialization ****\n"));
+			  "**** Completed Table Method Parsing and Object Initialization\n"));
 
 	return_ACPI_STATUS(status);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsobject.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsobject.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsobject.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsobject.c	2009-06-09 23:05:27.000000000 -0400
@@ -209,8 +209,7 @@ void acpi_ns_detach_object(struct acpi_n
 
 	obj_desc = node->object;
 
-	if (!obj_desc ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+	if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_VOID;
 	}
 
@@ -220,8 +219,7 @@ void acpi_ns_detach_object(struct acpi_n
 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
 		node->object = obj_desc->common.next_object;
 		if (node->object &&
-		    (ACPI_GET_OBJECT_TYPE(node->object) !=
-		     ACPI_TYPE_LOCAL_DATA)) {
+		    ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
 			node->object = node->object->common.next_object;
 		}
 	}
@@ -267,7 +265,7 @@ union acpi_operand_object *acpi_ns_get_a
 	    ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
 	     && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
 		 ACPI_DESC_TYPE_NAMED))
-	    || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+	    || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
 
@@ -294,9 +292,9 @@ union acpi_operand_object *acpi_ns_get_s
 	ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
 
 	if ((!obj_desc) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+	    (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
 	    (!obj_desc->common.next_object) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+	    ((obj_desc->common.next_object)->common.type ==
 	     ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
@@ -331,7 +329,7 @@ acpi_ns_attach_data(struct acpi_namespac
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			return (AE_ALREADY_EXISTS);
 		}
@@ -385,7 +383,7 @@ acpi_ns_detach_data(struct acpi_namespac
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			if (prev_obj_desc) {
 				prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@ acpi_ns_get_attached_data(struct acpi_na
 
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			*data = obj_desc->data.pointer;
 			return (AE_OK);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsparse.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsparse.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsparse.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsparse.c	2009-06-09 23:05:27.000000000 -0400
@@ -176,9 +176,8 @@ acpi_ns_parse_table(u32 table_index, str
 	 * performs another complete parse of the AML.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -193,9 +192,8 @@ acpi_ns_parse_table(u32 table_index, str
 	 * parse objects are all cached.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nspredef.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nspredef.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nspredef.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nspredef.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,7 +79,9 @@ acpi_ns_check_package(char *pathname,
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2);
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index);
 
 static acpi_status
 acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@ acpi_ns_check_predefined_names(struct ac
 
 	/* For returned Package objects, check the type of all sub-objects */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+	if (return_object->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ns_check_package(pathname, return_object_ptr,
 					  predefined);
@@ -302,7 +304,8 @@ acpi_ns_check_parameter_count(char *path
 		if ((user_param_count != required_params_current) &&
 		    (user_param_count != required_params_old)) {
 			ACPI_WARNING((AE_INFO,
-				      "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+				      "%s: Parameter count mismatch - "
+				      "caller passed %d, ACPI requires %d",
 				      pathname, user_param_count,
 				      required_params_current));
 		}
@@ -472,7 +475,7 @@ acpi_ns_check_package(char *pathname,
 							package->ret_info.
 							object_type2,
 							package->ret_info.
-							count2);
+							count2, 0);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -623,7 +626,7 @@ acpi_ns_check_package(char *pathname,
 								   object_type2,
 								   package->
 								   ret_info.
-								   count2);
+								   count2, 0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -672,7 +675,8 @@ acpi_ns_check_package(char *pathname,
 								   object_type1,
 								   sub_package->
 								   package.
-								   count, 0, 0);
+								   count, 0, 0,
+								   0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -710,7 +714,8 @@ acpi_ns_check_package(char *pathname,
 								   ret_info.
 								   object_type1,
 								   (expected_count
-								    - 1), 0, 0);
+								    - 1), 0, 0,
+								   1);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -758,6 +763,7 @@ acpi_ns_check_package(char *pathname,
  *              Count1          - Count for first group
  *              Type2           - Object type for second group
  *              Count2          - Count for second group
+ *              start_index     - Start of the first group of elements
  *
  * RETURN:      Status
  *
@@ -769,7 +775,9 @@ acpi_ns_check_package(char *pathname,
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2)
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index)
 {
 	union acpi_operand_object **this_element = elements;
 	acpi_status status;
@@ -782,7 +790,7 @@ acpi_ns_check_package_elements(char *pat
 	 */
 	for (i = 0; i < count1; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type1, i);
+						   type1, i + start_index);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -791,7 +799,8 @@ acpi_ns_check_package_elements(char *pat
 
 	for (i = 0; i < count2; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type2, (i + count1));
+						   type2,
+						   (i + count1 + start_index));
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -858,7 +867,7 @@ acpi_ns_check_object_type(char *pathname
 	 * from all of the predefined names (including elements of returned
 	 * packages)
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_RTYPE_INTEGER;
 		break;
@@ -901,7 +910,7 @@ acpi_ns_check_object_type(char *pathname
 
 	/* For reference objects, check that the reference type is correct */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+	if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		status = acpi_ns_check_reference(pathname, return_object);
 	}
 
@@ -974,7 +983,8 @@ acpi_ns_check_reference(char *pathname,
 	}
 
 	ACPI_WARNING((AE_INFO,
-		      "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+		      "%s: Return type mismatch - "
+		      "unexpected reference object type [%s] %2.2X",
 		      pathname, acpi_ut_get_reference_name(return_object),
 		      return_object->reference.class));
 
@@ -1006,7 +1016,7 @@ acpi_ns_repair_object(u32 expected_btype
 	union acpi_operand_object *new_object;
 	acpi_size length;
 
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nssearch.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nssearch.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nssearch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nssearch.c	2009-06-09 23:05:27.000000000 -0400
@@ -167,7 +167,8 @@ acpi_ns_search_one_scope(u32 target_name
 	/* Searched entire namespace level, not found */
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+			  "%p first child %p\n",
 			  ACPI_CAST_PTR(char, &target_name),
 			  acpi_ut_get_type_name(type),
 			  acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@ acpi_ns_search_parent_tree(u32 target_na
 			  acpi_ut_get_node_name(parent_node),
 			  ACPI_CAST_PTR(char, &target_name)));
 
-	/*
-	 * Search parents until target is found or we have backed up to the root
-	 */
+	/* Search parents until target is found or we have backed up to the root */
+
 	while (parent_node) {
 		/*
 		 * Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@ acpi_ns_search_and_enter(u32 target_name
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 #ifdef ACPI_ASL_COMPILER
-	/*
-	 * Node is an object defined by an External() statement
-	 */
+
+	/* Node is an object defined by an External() statement */
+
 	if (flags & ACPI_NS_EXTERNAL) {
 		new_node->flags |= ANOBJ_IS_EXTERNAL;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsutils.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsutils.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsutils.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsutils.c	2009-06-09 23:05:27.000000000 -0400
@@ -325,9 +325,8 @@ void acpi_ns_get_internal_name_length(st
 			next_external_char++;
 		}
 	} else {
-		/*
-		 * Handle Carat prefixes
-		 */
+		/* Handle Carat prefixes */
+
 		while (*next_external_char == '^') {
 			info->num_carats++;
 			next_external_char++;
@@ -552,9 +551,8 @@ acpi_ns_externalize_name(u32 internal_na
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Check for a prefix (one '\' | one or more '^').
-	 */
+	/* Check for a prefix (one '\' | one or more '^') */
+
 	switch (internal_name[0]) {
 	case '\\':
 		prefix_length = 1;
@@ -580,7 +578,7 @@ acpi_ns_externalize_name(u32 internal_na
 	}
 
 	/*
-	 * Check for object names.  Note that there could be 0-255 of these
+	 * Check for object names. Note that there could be 0-255 of these
 	 * 4-byte elements.
 	 */
 	if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@ acpi_ns_externalize_name(u32 internal_na
 		return_ACPI_STATUS(AE_BAD_PATHNAME);
 	}
 
-	/*
-	 * Build converted_name
-	 */
+	/* Build the converted_name */
+
 	*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
 	if (!(*converted_name)) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@ acpi_ns_externalize_name(u32 internal_na
  *       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.
+ *
  ******************************************************************************/
 
 struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@ struct acpi_namespace_node *acpi_ns_map_
 
 	ACPI_FUNCTION_ENTRY();
 
-	/*
-	 * Simple implementation
-	 */
+	/* Parameter validation */
+
 	if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
 		return (acpi_gbl_root_node);
 	}
@@ -872,7 +871,7 @@ acpi_ns_get_node(struct acpi_namespace_n
 				(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
 				return_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
 				  pathname, acpi_format_exception(status)));
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nswalk.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nswalk.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nswalk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nswalk.c	2009-06-09 23:05:27.000000000 -0400
@@ -135,8 +135,8 @@ struct acpi_namespace_node *acpi_ns_get_
  *              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
- *              a non-zero value, the search is terminated immediately and this
- *              value is returned to the caller.
+ *              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
@@ -200,10 +200,10 @@ acpi_ns_walk_namespace(acpi_object_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.
+			 * 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)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsxfeval.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsxfeval.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/nsxfeval.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/nsxfeval.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,7 +53,6 @@ ACPI_MODULE_NAME("nsxfeval")
 /* Local prototypes */
 static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_evaluate_object_typed
@@ -147,7 +146,7 @@ acpi_evaluate_object_typed(acpi_handle h
 }
 
 ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
-#endif				/*  ACPI_FUTURE_USAGE  */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_evaluate_object
@@ -387,8 +386,7 @@ static void acpi_ns_resolve_references(s
 
 	/* We are interested in reference objects only */
 
-	if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
-	    ACPI_TYPE_LOCAL_REFERENCE) {
+	if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 		return;
 	}
 
@@ -476,21 +474,40 @@ acpi_walk_namespace(acpi_object_type typ
 	}
 
 	/*
-	 * Lock the namespace around the walk.
-	 * The namespace will be unlocked/locked around each call
-	 * to the user function - since this function
-	 * must be allowed to make Acpi calls itself.
+	 * Need to acquire the namespace reader lock to prevent interference
+	 * with any concurrent table unloads (which causes the deletion of
+	 * namespace objects). We cannot allow the deletion of a namespace node
+	 * while the user function is using it. The exception to this are the
+	 * nodes created and deleted during control method execution -- these
+	 * nodes are marked as temporary nodes and are ignored by the namespace
+	 * walk. Thus, control methods can be executed while holding the
+	 * namespace deletion lock (and the user function can execute control
+	 * methods.)
+	 */
+	status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/*
+	 * Lock the namespace around the walk. The namespace will be
+	 * unlocked/locked around each call to the user function - since the user
+	 * function must be allowed to make ACPICA calls itself (for example, it
+	 * will typically execute control methods during device enumeration.)
 	 */
 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto unlock_and_exit;
 	}
 
 	status = acpi_ns_walk_namespace(type, start_object, max_depth,
-					ACPI_NS_WALK_UNLOCK,
-					user_function, context, return_value);
+					ACPI_NS_WALK_UNLOCK, user_function,
+					context, return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+      unlock_and_exit:
+	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/rscalc.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/rscalc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/rscalc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/rscalc.c	2009-06-09 23:05:27.000000000 -0400
@@ -543,6 +543,13 @@ acpi_rs_get_pci_routing_table_length(uni
 
 		package_element = *top_object_list;
 
+		/* We must have a valid Package object */
+
+		if (!package_element ||
+		    (package_element->common.type != ACPI_TYPE_PACKAGE)) {
+			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+		}
+
 		/*
 		 * The sub_object_list will now point to an array of the
 		 * four IRQ elements: Address, Pin, Source and source_index
@@ -557,9 +564,9 @@ acpi_rs_get_pci_routing_table_length(uni
 		     table_index++) {
 			if (*sub_object_list &&	/* Null object allowed */
 			    ((ACPI_TYPE_STRING ==
-			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+			      (*sub_object_list)->common.type) ||
 			     ((ACPI_TYPE_LOCAL_REFERENCE ==
-			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+			       (*sub_object_list)->common.type) &&
 			      ((*sub_object_list)->reference.class ==
 			       ACPI_REFCLASS_NAME)))) {
 				name_found = TRUE;
@@ -575,8 +582,7 @@ acpi_rs_get_pci_routing_table_length(uni
 		/* Was a String type found? */
 
 		if (name_found) {
-			if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
-			    ACPI_TYPE_STRING) {
+			if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * The length String.Length field does not include the
 				 * terminating NULL, add 1
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/rscreate.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/rscreate.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/rscreate.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/rscreate.c	2009-06-09 23:05:27.000000000 -0400
@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union a
 	user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
 
 	for (index = 0; index < number_of_elements; index++) {
-		int source_name_index = 2;
-		int source_index_index = 3;
 
 		/*
 		 * Point user_prt past this current structure
@@ -212,7 +210,7 @@ acpi_rs_create_pci_routing_table(union a
 
 		/* Each element of the top-level package must also be a package */
 
-		if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+		if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X]) Need sub-package, found %s",
 				    index,
@@ -240,7 +238,7 @@ acpi_rs_create_pci_routing_table(union a
 		/* 1) First subobject: Dereference the PRT.Address */
 
 		obj_desc = sub_object_list[0];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Address) Need Integer, found %s",
 				    index,
@@ -253,7 +251,7 @@ acpi_rs_create_pci_routing_table(union a
 		/* 2) Second subobject: Dereference the PRT.Pin */
 
 		obj_desc = sub_object_list[1];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Pin) Need Integer, found %s",
 				    index,
@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union a
 			return_ACPI_STATUS(AE_BAD_DATA);
 		}
 
-		/*
-		 * If BIOS erroneously reversed the _PRT source_name and source_index,
-		 * then reverse them back.
-		 */
-		if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
-		    ACPI_TYPE_INTEGER) {
-			if (acpi_gbl_enable_interpreter_slack) {
-				source_name_index = 3;
-				source_index_index = 2;
-				printk(KERN_WARNING
-				       "ACPI: Handling Garbled _PRT entry\n");
-			} else {
-				ACPI_ERROR((AE_INFO,
-					    "(PRT[%X].source_index) Need Integer, found %s",
-					    index,
-					    acpi_ut_get_object_type_name
-					    (sub_object_list[3])));
-				return_ACPI_STATUS(AE_BAD_DATA);
-			}
-		}
-
 		user_prt->pin = (u32) obj_desc->integer.value;
 
 		/*
@@ -291,8 +268,7 @@ acpi_rs_create_pci_routing_table(union a
 		 * other ACPI implementations.
 		 */
 		obj_desc = sub_object_list[3];
-		if (!obj_desc
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+		if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 			sub_object_list[3] = sub_object_list[2];
 			sub_object_list[2] = obj_desc;
 
@@ -305,9 +281,9 @@ acpi_rs_create_pci_routing_table(union a
 		 * 3) Third subobject: Dereference the PRT.source_name
 		 * The name may be unresolved (slack mode), so allow a null object
 		 */
-		obj_desc = sub_object_list[source_name_index];
+		obj_desc = sub_object_list[2];
 		if (obj_desc) {
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 
 				if (obj_desc->reference.class !=
@@ -379,8 +355,8 @@ acpi_rs_create_pci_routing_table(union a
 
 		/* 4) Fourth subobject: Dereference the PRT.source_index */
 
-		obj_desc = sub_object_list[source_index_index];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		obj_desc = sub_object_list[3];
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].SourceIndex) Need Integer, found %s",
 				    index,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbfadt.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbfadt.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbfadt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbfadt.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
 
 static void acpi_tb_validate_fadt(void);
 
+static void acpi_tb_setup_fadt_registers(void);
+
 /* Table for conversion of FADT to common internal format and FADT validation */
 
 typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_t
 	 ACPI_FADT_SEPARATE_LENGTH}
 };
 
-#define ACPI_FADT_INFO_ENTRIES        (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+			(sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+	struct acpi_generic_address *target;
+	u8 source;
+	u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+	{&acpi_gbl_xpm1a_status,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1a_enable,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 1},
+
+	{&acpi_gbl_xpm1b_status,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1b_enable,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+			(sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
 
 /*******************************************************************************
  *
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi
  * FUNCTION:    acpi_tb_parse_fadt
  *
  * PARAMETERS:  table_index         - Index for the FADT
- *              Flags               - Flags
  *
  * RETURN:      None
  *
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi
  *
  ******************************************************************************/
 
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
 {
 	u32 length;
 	struct acpi_table_header *table;
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index,
 	 */
 	(void)acpi_tb_verify_checksum(table, length);
 
-	/* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+	/* Create a local copy of the FADT in common ACPI 2.0+ format */
 
 	acpi_tb_create_local_fadt(table, length);
 
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index,
 	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
-			      flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+			      ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
-			      flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+			      ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
 }
 
 /*******************************************************************************
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct ac
 	ACPI_MEMCPY(&acpi_gbl_FADT, table,
 		    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
 
-	/*
-	 * 1) Convert the local copy of the FADT to the common internal format
-	 * 2) Validate some of the important values within the FADT
-	 */
+	/* Convert the local copy of the FADT to the common internal format */
+
 	acpi_tb_convert_fadt();
+
+	/* Validate FADT values now, before we make any changes */
+
+	acpi_tb_validate_fadt();
+
+	/* Initialize the global ACPI register structures */
+
+	acpi_tb_setup_fadt_registers();
 }
 
 /*******************************************************************************
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct ac
  * RETURN:      None
  *
  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
- *              Expand all 32-bit addresses to 64-bit.
+ *              Expand 32-bit addresses to 64-bit as necessary.
  *
  * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
  *              and must contain a copy of the actual FADT.
  *
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
  *
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
  *
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
  *
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
+ *
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
  *
  ******************************************************************************/
 
 static void acpi_tb_convert_fadt(void)
 {
-	u8 pm1_register_bit_width;
-	u8 pm1_register_byte_width;
-	struct acpi_generic_address *target64;
+	struct acpi_generic_address *address64;
+	u32 address32;
 	u32 i;
 
 	/* Update the local FADT table header length */
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void)
 	 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
 	 * generic address structures as necessary. Later code will always use
 	 * the 64-bit address structures.
+	 *
+	 * March 2009:
+	 * We now always use the 32-bit address if it is valid (non-null). This
+	 * is not in accordance with the ACPI specification which states that
+	 * the 64-bit address supersedes the 32-bit version, but we do this for
+	 * compatibility with other ACPI implementations. Most notably, in the
+	 * case where both the 32 and 64 versions are non-null, we use the 32-bit
+	 * version. This is the only address that is guaranteed to have been
+	 * tested by the BIOS manufacturer.
 	 */
 	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-		target64 =
-		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
-				 fadt_info_table[i].address64);
+		address32 = *ACPI_ADD_PTR(u32,
+					  &acpi_gbl_FADT,
+					  fadt_info_table[i].address32);
 
-		/* Expand only if the 64-bit X target is null */
+		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
 
-		if (!target64->address) {
+		/*
+		 * If both 32- and 64-bit addresses are valid (non-zero),
+		 * they must match.
+		 */
+		if (address64->address && address32 &&
+		    (address64->address != (u64) address32)) {
+			ACPI_ERROR((AE_INFO,
+				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+				    fadt_info_table[i].name, address32,
+				    ACPI_FORMAT_UINT64(address64->address)));
+		}
 
-			/* The space_id is always I/O for the 32-bit legacy address fields */
+		/* Always use 32-bit address if it is valid (non-null) */
 
-			acpi_tb_init_generic_address(target64,
+		if (address32) {
+			/*
+			 * Copy the 32-bit address to the 64-bit GAS structure. The
+			 * Space ID is always I/O for 32-bit legacy address fields
+			*/
+			acpi_tb_init_generic_address(address64,
 						     ACPI_ADR_SPACE_SYSTEM_IO,
 						     *ACPI_ADD_PTR(u8,
 								   &acpi_gbl_FADT,
 								   fadt_info_table
 								   [i].length),
-						     (u64) * ACPI_ADD_PTR(u32,
-									  &acpi_gbl_FADT,
-									  fadt_info_table
-									  [i].
-									  address32));
-		}
-	}
-
-	/* Validate FADT values now, before we make any changes */
-
-	acpi_tb_validate_fadt();
-
-	/*
-	 * Optionally check all register lengths against the default values and
-	 * update them if they are incorrect.
-	 */
-	if (acpi_gbl_use_default_register_widths) {
-		for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-			target64 =
-			    ACPI_ADD_PTR(struct acpi_generic_address,
-					 &acpi_gbl_FADT,
-					 fadt_info_table[i].address64);
-
-			/*
-			 * If a valid register (Address != 0) and the (default_length > 0)
-			 * (Not a GPE register), then check the width against the default.
-			 */
-			if ((target64->address) &&
-			    (fadt_info_table[i].default_length > 0) &&
-			    (fadt_info_table[i].default_length !=
-			     target64->bit_width)) {
-				ACPI_WARNING((AE_INFO,
-					      "Invalid length for %s: %d, using default %d",
-					      fadt_info_table[i].name,
-					      target64->bit_width,
-					      fadt_info_table[i].
-					      default_length));
-
-				/* Incorrect size, set width to the default */
-
-				target64->bit_width =
-				    fadt_info_table[i].default_length;
-			}
+						     address32);
 		}
 	}
-
-	/*
-	 * Get the length of the individual PM1 registers (enable and status).
-	 * Each register is defined to be (event block length / 2).
-	 */
-	pm1_register_bit_width =
-	    (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
-	pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
-
-	/*
-	 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
-	 * access the PM1 status register(s). Use (width / 2)
-	 */
-	acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
-	acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
-	/*
-	 * Calculate separate GAS structs for the PM1 Enable registers.
-	 * These addresses do not appear (directly) in the FADT, so it is
-	 * useful to calculate them once, here.
-	 *
-	 * The PM event blocks are split into two register blocks, first is the
-	 * PM Status Register block, followed immediately by the PM Enable
-	 * Register block. Each is of length (xpm1x_event_block.bit_width/2).
-	 *
-	 * On various systems the v2 fields (and particularly the bit widths)
-	 * cannot be relied upon, though. Hence resort to using the v1 length
-	 * here (and warn about the inconsistency).
-	 */
-	if (acpi_gbl_FADT.xpm1a_event_block.bit_width
-	    != acpi_gbl_FADT.pm1_event_length * 8)
-		printk(KERN_WARNING "FADT: "
-		       "X_PM1a_EVT_BLK.bit_width (%u) does not match"
-		       " PM1_EVT_LEN (%u)\n",
-		       acpi_gbl_FADT.xpm1a_event_block.bit_width,
-		       acpi_gbl_FADT.pm1_event_length);
-
-	/* The PM1A register block is required */
-
-	acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
-				     acpi_gbl_FADT.xpm1a_event_block.space_id,
-				     pm1_register_byte_width,
-				     (acpi_gbl_FADT.xpm1a_event_block.address +
-				      pm1_register_byte_width));
-	/* Don't forget to copy space_id of the GAS */
-	acpi_gbl_xpm1a_enable.space_id =
-	    acpi_gbl_FADT.xpm1a_event_block.space_id;
-
-	/* The PM1B register block is optional, ignore if not present */
-
-	if (acpi_gbl_FADT.xpm1b_event_block.address) {
-		if (acpi_gbl_FADT.xpm1b_event_block.bit_width
-		    != acpi_gbl_FADT.pm1_event_length * 8)
-			printk(KERN_WARNING "FADT: "
-			       "X_PM1b_EVT_BLK.bit_width (%u) does not match"
-			       " PM1_EVT_LEN (%u)\n",
-			       acpi_gbl_FADT.xpm1b_event_block.bit_width,
-			       acpi_gbl_FADT.pm1_event_length);
-		acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
-					     acpi_gbl_FADT.xpm1b_event_block.space_id,
-					     pm1_register_byte_width,
-					     (acpi_gbl_FADT.xpm1b_event_block.
-					      address + pm1_register_byte_width));
-		/* Don't forget to copy space_id of the GAS */
-		acpi_gbl_xpm1b_enable.space_id =
-		    acpi_gbl_FADT.xpm1b_event_block.space_id;
-
-	}
 }
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_tb_validate_fadt
  *
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void)
 	    (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
 		ACPI_WARNING((AE_INFO,
 			      "32/64X FACS address mismatch in FADT - "
-			      "two FACS tables! %8.8X/%8.8X%8.8X",
+			      "%8.8X/%8.8X%8.8X, using 32",
 			      acpi_gbl_FADT.facs,
 			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+		acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
 	}
 
 	if (acpi_gbl_FADT.dsdt &&
 	    (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
 		ACPI_WARNING((AE_INFO,
 			      "32/64X DSDT address mismatch in FADT - "
-			      "two DSDT tables! %8.8X/%8.8X%8.8X",
+			      "%8.8X/%8.8X%8.8X, using 32",
 			      acpi_gbl_FADT.dsdt,
 			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+		acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
 	}
 
 	/* Examine all of the 64-bit extended address fields (X fields) */
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void)
 		 * For each extended field, check for length mismatch between the
 		 * legacy length field and the corresponding 64-bit X length field.
 		 */
-		if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
+		if (address64->address &&
+		    (address64->bit_width != ACPI_MUL_8(length))) {
 			ACPI_WARNING((AE_INFO,
 				      "32/64X length mismatch in %s: %d/%d",
 				      name, ACPI_MUL_8(length),
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void)
 			 */
 			if (!address64->address || !length) {
 				ACPI_ERROR((AE_INFO,
-					    "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
+					    "Required field %s has zero address and/or length:"
+					    " %8.8X%8.8X/%X",
 					    name,
 					    ACPI_FORMAT_UINT64(address64->
 							       address),
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void)
 		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
 			/*
 			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
-			 * length field. If present, both the address and length must be valid.
+			 * length field. If present, both the address and length must
+			 * be valid.
 			 */
-			if ((address64->address && !length)
-			    || (!address64->address && length)) {
+			if ((address64->address && !length) ||
+			    (!address64->address && length)) {
 				ACPI_WARNING((AE_INFO,
-					      "Optional field %s has zero address or length: %8.8X%8.8X/%X",
+					      "Optional field %s has zero address or length: "
+					      "%8.8X%8.8X/%X",
 					      name,
 					      ACPI_FORMAT_UINT64(address64->
 								 address),
 					      length));
 			}
 		}
+	}
+}
 
-		/* If both 32- and 64-bit addresses are valid (non-zero), they must match */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS:  None, uses acpi_gbl_FADT.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ *              force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
 
-		if (address64->address && *address32 &&
-		    (address64->address != (u64) * address32)) {
-			ACPI_ERROR((AE_INFO,
-				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
-				    name, *address32,
-				    ACPI_FORMAT_UINT64(address64->address)));
+static void acpi_tb_setup_fadt_registers(void)
+{
+	struct acpi_generic_address *target64;
+	struct acpi_generic_address *source64;
+	u8 pm1_register_byte_width;
+	u32 i;
+
+	/*
+	 * Optionally check all register lengths against the default values and
+	 * update them if they are incorrect.
+	 */
+	if (acpi_gbl_use_default_register_widths) {
+		for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+			target64 =
+			    ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
+
+			/*
+			 * If a valid register (Address != 0) and the (default_length > 0)
+			 * (Not a GPE register), then check the width against the default.
+			 */
+			if ((target64->address) &&
+			    (fadt_info_table[i].default_length > 0) &&
+			    (fadt_info_table[i].default_length !=
+			     target64->bit_width)) {
+				ACPI_WARNING((AE_INFO,
+					      "Invalid length for %s: %d, using default %d",
+					      fadt_info_table[i].name,
+					      target64->bit_width,
+					      fadt_info_table[i].
+					      default_length));
+
+				/* Incorrect size, set width to the default */
+
+				target64->bit_width =
+				    fadt_info_table[i].default_length;
+			}
+		}
+	}
+
+	/*
+	 * Get the length of the individual PM1 registers (enable and status).
+	 * Each register is defined to be (event block length / 2). Extra divide
+	 * by 8 converts bits to bytes.
+	 */
+	pm1_register_byte_width = (u8)
+	    ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
+
+	/*
+	 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+	 * registers. These addresses do not appear (directly) in the FADT, so it
+	 * is useful to pre-calculate them from the PM1 Event Block definitions.
+	 *
+	 * The PM event blocks are split into two register blocks, first is the
+	 * PM Status Register block, followed immediately by the PM Enable
+	 * Register block. Each is of length (pm1_event_length/2)
+	 *
+	 * Note: The PM1A event block is required by the ACPI specification.
+	 * However, the PM1B event block is optional and is rarely, if ever,
+	 * used.
+	 */
+
+	for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+		source64 =
+		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+				 fadt_pm_info_table[i].source);
+
+		if (source64->address) {
+			acpi_tb_init_generic_address(fadt_pm_info_table[i].
+						     target, source64->space_id,
+						     pm1_register_byte_width,
+						     source64->address +
+						     (fadt_pm_info_table[i].
+						      register_num *
+						      pm1_register_byte_width));
 		}
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbinstal.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbinstal.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbinstal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbinstal.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ *              dynamically load tables via the Load and load_table AML
+ *              operators.
  *
  ******************************************************************************/
 
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc
 {
 	u32 i;
 	acpi_status status = AE_OK;
+	struct acpi_table_header *override_table = NULL;
 
 	ACPI_FUNCTION_TRACE(tb_add_table);
 
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc
 		}
 	}
 
+	/*
+	 * ACPI Table Override:
+	 * Allow the host to override dynamically loaded tables.
+	 */
+	status = acpi_os_table_override(table_desc->pointer, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   table_desc->pointer->signature,
+			   ACPI_CAST_PTR(void, table_desc->address)));
+
+		/* We can delete the table that was passed as a parameter */
+
+		acpi_tb_delete_table(table_desc);
+
+		/* Setup descriptor for the new table */
+
+		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+		table_desc->pointer = override_table;
+		table_desc->length = override_table->length;
+		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	}
+
 	/* Add the table to the global root table list */
 
 	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_li
 	/* Increase the Table Array size */
 
 	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
-				       size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
-				      * sizeof(struct acpi_table_desc));
+				       size +
+				       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+				      sizeof(struct acpi_table_desc));
 	if (!tables) {
 		ACPI_ERROR((AE_INFO,
 			    "Could not allocate new root table array"));
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void)
  *
  * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
  *
  ******************************************************************************/
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
 {
 	acpi_owner_id owner_id;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (table_index >= acpi_gbl_root_table_list.count) {
+
+		/* The table index does not exist */
 
-	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-	if (table_index < acpi_gbl_root_table_list.count) {
-		owner_id =
-		    acpi_gbl_root_table_list.tables[table_index].owner_id;
-	} else {
 		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-		return;
+		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
+	/* Get the owner ID for this table, used to delete namespace nodes */
+
+	owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+	/*
+	 * Need to acquire the namespace writer lock to prevent interference
+	 * with any concurrent namespace walks. The interpreter must be
+	 * released during the deletion since the acquisition of the deletion
+	 * lock may block, and also since the execution of a namespace walk
+	 * must be allowed to use the interpreter.
+	 */
+	acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+	status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
 	acpi_ns_delete_namespace_by_owner(owner_id);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_ind
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	if (table_index < acpi_gbl_root_table_list.count) {
 		is_loaded = (u8)
-		    (acpi_gbl_root_table_list.tables[table_index].
-		     flags & ACPI_TABLE_IS_LOADED);
+		    (acpi_gbl_root_table_list.tables[table_index].flags &
+		     ACPI_TABLE_IS_LOADED);
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbutils.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbutils.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbutils.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbutils.c	2009-06-09 23:05:27.000000000 -0400
@@ -177,19 +177,23 @@ acpi_tb_print_table_header(acpi_physical
 			   struct acpi_table_header *header)
 {
 
+	/*
+	 * The reason that the Address is cast to a void pointer is so that we
+	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
+	 */
 	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
 
-		/* FACS only has signature and length fields of common table header */
+		/* FACS only has signature and length fields */
 
-		ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
-			   header->signature, (unsigned long)address,
+		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+			   header->signature, ACPI_CAST_PTR(void, address),
 			   header->length));
 	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
 
 		/* RSDP has no common fields */
 
-		ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
-			   (unsigned long)address,
+		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+			   ACPI_CAST_PTR (void, address),
 			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
 			    revision >
 			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@ acpi_tb_print_table_header(acpi_physical
 		/* Standard ACPI table with full common header */
 
 		ACPI_INFO((AE_INFO,
-			   "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
-			   header->signature, (unsigned long)address,
+			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+			   header->signature, ACPI_CAST_PTR (void, address),
 			   header->length, header->revision, header->oem_id,
 			   header->oem_table_id, header->oem_revision,
 			   header->asl_compiler_id,
@@ -280,22 +284,28 @@ u8 acpi_tb_checksum(u8 *buffer, u32 leng
  * FUNCTION:    acpi_tb_install_table
  *
  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
- *              Flags                   - Flags
  *              Signature               - Table signature, NULL if no need to
  *                                        match
  *              table_index             - Index into root table array
  *
  * RETURN:      None
  *
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ *              table override mechanism is implemented here to allow the host
+ *              OS to replace any table before it is installed in the root
+ *              table array.
  *
  ******************************************************************************/
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index)
+		      char *signature, u32 table_index)
 {
-	struct acpi_table_header *table;
+	u8 flags;
+	acpi_status status;
+	struct acpi_table_header *table_to_install;
+	struct acpi_table_header *mapped_table;
+	struct acpi_table_header *override_table = NULL;
 
 	if (!address) {
 		ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@ acpi_tb_install_table(acpi_physical_addr
 
 	/* Map just the table header */
 
-	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
-	if (!table) {
+	mapped_table =
+	    acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!mapped_table) {
 		return;
 	}
 
-	/* If a particular signature is expected, signature must match */
+	/* If a particular signature is expected (DSDT/FACS), it must match */
 
-	if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+	if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
 		ACPI_ERROR((AE_INFO,
-			    "Invalid signature 0x%X for ACPI table [%s]",
-			    *ACPI_CAST_PTR(u32, table->signature), signature));
+			    "Invalid signature 0x%X for ACPI table, expected [%s]",
+			    *ACPI_CAST_PTR(u32, mapped_table->signature),
+			    signature));
 		goto unmap_and_exit;
 	}
 
+	/*
+	 * ACPI Table Override:
+	 *
+	 * Before we install the table, let the host OS override it with a new
+	 * one if desired. Any table within the RSDT/XSDT can be replaced,
+	 * including the DSDT which is pointed to by the FADT.
+	 */
+	status = acpi_os_table_override(mapped_table, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   mapped_table->signature, ACPI_CAST_PTR(void,
+								  address)));
+
+		acpi_gbl_root_table_list.tables[table_index].pointer =
+		    override_table;
+		address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+		table_to_install = override_table;
+		flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	} else {
+		table_to_install = mapped_table;
+		flags = ACPI_TABLE_ORIGIN_MAPPED;
+	}
+
 	/* Initialize the table entry */
 
 	acpi_gbl_root_table_list.tables[table_index].address = address;
-	acpi_gbl_root_table_list.tables[table_index].length = table->length;
+	acpi_gbl_root_table_list.tables[table_index].length =
+	    table_to_install->length;
 	acpi_gbl_root_table_list.tables[table_index].flags = flags;
 
 	ACPI_MOVE_32_TO_32(&
 			   (acpi_gbl_root_table_list.tables[table_index].
-			    signature), table->signature);
+			    signature), table_to_install->signature);
 
-	acpi_tb_print_table_header(address, table);
+	acpi_tb_print_table_header(address, table_to_install);
 
 	if (table_index == ACPI_TABLE_INDEX_DSDT) {
 
 		/* Global integer width is based upon revision of the DSDT */
 
-		acpi_ut_set_integer_width(table->revision);
+		acpi_ut_set_integer_width(table_to_install->revision);
 	}
 
       unmap_and_exit:
-	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+	acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
 }
 
 /*******************************************************************************
@@ -379,7 +417,8 @@ acpi_tb_get_root_table_entry(u8 *table_e
 	} else {
 		/*
 		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
-		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+		 *  return 64-bit
 		 */
 		ACPI_MOVE_64_TO_64(&address64, table_entry);
 
@@ -389,7 +428,8 @@ acpi_tb_get_root_table_entry(u8 *table_e
 			/* Will truncate 64-bit address to 32 bits, issue warning */
 
 			ACPI_WARNING((AE_INFO,
-				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+				      " truncating",
 				      ACPI_FORMAT_UINT64(address64)));
 		}
 #endif
@@ -402,7 +442,6 @@ acpi_tb_get_root_table_entry(u8 *table_e
  * FUNCTION:    acpi_tb_parse_root_table
  *
  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
- *              Flags                   - Flags
  *
  * RETURN:      Status
  *
@@ -416,7 +455,7 @@ acpi_tb_get_root_table_entry(u8 *table_e
  ******************************************************************************/
 
 acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
 {
 	struct acpi_table_rsdp *rsdp;
 	u32 table_entry_size;
@@ -513,13 +552,12 @@ acpi_tb_parse_root_table(acpi_physical_a
 
 	/* Calculate the number of tables described in the root table */
 
-	table_count =
-	    (u32) ((table->length -
-		    sizeof(struct acpi_table_header)) / table_entry_size);
-
+	table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+			    table_entry_size);
 	/*
-	 * First two entries in the table array are reserved for the DSDT and FACS,
-	 * which are not actually present in the RSDT/XSDT - they come from the FADT
+	 * First two entries in the table array are reserved for the DSDT
+	 * and FACS, which are not actually present in the RSDT/XSDT - they
+	 * come from the FADT
 	 */
 	table_entry =
 	    ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@ acpi_tb_parse_root_table(acpi_physical_a
 	 */
 	for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
 		acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
-				      address, flags, NULL, i);
+				      address, NULL, i);
 
 		/* Special case for FADT - get the DSDT and FACS */
 
 		if (ACPI_COMPARE_NAME
 		    (&acpi_gbl_root_table_list.tables[i].signature,
 		     ACPI_SIG_FADT)) {
-			acpi_tb_parse_fadt(i, flags);
+			acpi_tb_parse_fadt(i);
 		}
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbxface.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbxface.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbxface.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbxface.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,8 +150,7 @@ acpi_initialize_tables(struct acpi_table
 	 * Root Table Array. This array contains the information of the RSDT/XSDT
 	 * in a common, more useable format.
 	 */
-	status =
-	    acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+	status = acpi_tb_parse_root_table(rsdp_address);
 	return_ACPI_STATUS(status);
 }
 
@@ -247,7 +246,7 @@ acpi_status acpi_load_table(struct acpi_
 
 ACPI_EXPORT_SYMBOL(acpi_load_table)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_get_table_header
  *
@@ -262,7 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
  * NOTE:        Caller is responsible in unmapping the header with
  *              acpi_os_unmap_memory
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
 acpi_get_table_header(char *signature,
 		      u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@ acpi_get_table_header(char *signature,
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@ acpi_get_table_header(char *signature,
 		}
 
 		if (!acpi_gbl_root_table_list.tables[i].pointer) {
-			if ((acpi_gbl_root_table_list.tables[i].
-			     flags & ACPI_TABLE_ORIGIN_MASK) ==
+			if ((acpi_gbl_root_table_list.tables[i].flags &
+			     ACPI_TABLE_ORIGIN_MASK) ==
 			    ACPI_TABLE_ORIGIN_MAPPED) {
 				header =
 				    acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@ acpi_get_table_header(char *signature,
 
 ACPI_EXPORT_SYMBOL(acpi_get_table_header)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_unload_table_id
  *
@@ -365,7 +363,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_table
+ * FUNCTION:    acpi_get_table_with_size
  *
  * PARAMETERS:  Signature           - ACPI signature of needed table
  *              Instance            - Which instance (for SSDTs)
@@ -375,10 +373,11 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
  *
  * DESCRIPTION: Finds and verifies an ACPI table.
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
-acpi_get_table(char *signature,
-	       u32 instance, struct acpi_table_header **out_table)
+acpi_get_table_with_size(char *signature,
+	       u32 instance, struct acpi_table_header **out_table,
+	       acpi_size *tbl_size)
 {
        u32 i;
        u32 j;
@@ -390,9 +389,8 @@ acpi_get_table(char *signature,
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -408,6 +406,7 @@ acpi_get_table(char *signature,
 		    acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
 		if (ACPI_SUCCESS(status)) {
 			*out_table = acpi_gbl_root_table_list.tables[i].pointer;
+			*tbl_size = acpi_gbl_root_table_list.tables[i].length;
 		}
 
 		if (!acpi_gbl_permanent_mmap) {
@@ -420,6 +419,15 @@ acpi_get_table(char *signature,
 	return (AE_NOT_FOUND);
 }
 
+acpi_status
+acpi_get_table(char *signature,
+	       u32 instance, struct acpi_table_header **out_table)
+{
+	acpi_size tbl_size;
+
+	return acpi_get_table_with_size(signature,
+		       instance, out_table, &tbl_size);
+}
 ACPI_EXPORT_SYMBOL(acpi_get_table)
 
 /*******************************************************************************
@@ -491,7 +499,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_ind
 static acpi_status acpi_tb_load_namespace(void)
 {
 	acpi_status status;
-	struct acpi_table_header *table;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -515,58 +522,28 @@ static acpi_status acpi_tb_load_namespac
 		goto unlock_and_exit;
 	}
 
-	/*
-	 * Find DSDT table
-	 */
-	status =
-	    acpi_os_table_override(acpi_gbl_root_table_list.
-				   tables[ACPI_TABLE_INDEX_DSDT].pointer,
-				   &table);
-	if (ACPI_SUCCESS(status) && table) {
-		/*
-		 * DSDT table has been found
-		 */
-		acpi_tb_delete_table(&acpi_gbl_root_table_list.
-				     tables[ACPI_TABLE_INDEX_DSDT]);
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
-		    table;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
-		    table->length;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
-		    ACPI_TABLE_ORIGIN_UNKNOWN;
-
-		ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
-		acpi_tb_print_table_header(0, table);
-
-		if (no_auto_ssdt == 0) {
-			printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
-		}
-	}
+	/* A valid DSDT is required */
 
 	status =
 	    acpi_tb_verify_table(&acpi_gbl_root_table_list.
 				 tables[ACPI_TABLE_INDEX_DSDT]);
 	if (ACPI_FAILURE(status)) {
 
-		/* A valid DSDT is required */
-
 		status = AE_NO_ACPI_TABLES;
 		goto unlock_and_exit;
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 
-	/*
-	 * Load and parse tables.
-	 */
+	/* Load and parse tables */
+
 	status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	/*
-	 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
-	 */
+	/* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
 		if ((!ACPI_COMPARE_NAME
@@ -619,9 +596,8 @@ acpi_status acpi_load_tables(void)
 
 	ACPI_FUNCTION_TRACE(acpi_load_tables);
 
-	/*
-	 * Load the namespace from the tables
-	 */
+	/* Load the namespace from the tables */
+
 	status = acpi_tb_load_namespace();
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbxfroot.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbxfroot.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/tbxfroot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/tbxfroot.c	2009-06-09 23:05:27.000000000 -0400
@@ -75,8 +75,8 @@ static acpi_status acpi_tb_validate_rsdp
 	 * Note: Sometimes there exists more than one RSDP in memory; the valid
 	 * RSDP has a valid checksum, all others have an invalid checksum.
 	 */
-	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
-	    != 0) {
+	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+			 sizeof(ACPI_SIG_RSDP) - 1) != 0) {
 
 		/* Nope, BAD Signature */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utcopy.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utcopy.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utcopy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utcopy.c	2009-06-09 23:05:27.000000000 -0400
@@ -135,11 +135,11 @@ acpi_ut_copy_isimple_to_esimple(union ac
 	 * In general, the external object will be the same type as
 	 * the internal object
 	 */
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 
 	/* However, only a limited number of external types are supported */
 
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@ acpi_ut_copy_isimple_to_esimple(union ac
 		 */
 		ACPI_ERROR((AE_INFO,
 			    "Unsupported object type, cannot convert to external object: %s",
-			    acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						  (internal_object))));
+			    acpi_ut_get_type_name(internal_object->common.
+						  type)));
 
 		return_ACPI_STATUS(AE_SUPPORT);
 	}
@@ -355,7 +355,7 @@ acpi_ut_copy_ipackage_to_epackage(union
 	info.object_space = 0;
 	info.num_packages = 1;
 
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 	external_object->package.count = internal_object->package.count;
 	external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
 							  info.free_space);
@@ -399,7 +399,7 @@ acpi_ut_copy_iobject_to_eobject(union ac
 
 	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
 
-	if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
 		/*
 		 * Package object:  Copy all subobjects (including
 		 * nested packages)
@@ -496,8 +496,9 @@ acpi_ut_copy_esimple_to_isimple(union ac
 	case ACPI_TYPE_STRING:
 
 		internal_object->string.pointer =
-		    ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
-					 length + 1);
+		    ACPI_ALLOCATE_ZEROED((acpi_size)
+					 external_object->string.length + 1);
+
 		if (!internal_object->string.pointer) {
 			goto error_exit;
 		}
@@ -697,7 +698,7 @@ acpi_ut_copy_simple_object(union acpi_op
 
 	/* Handle the objects with extra data */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 		/*
 		 * Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@ acpi_ut_copy_ielement_to_ielement(u8 obj
 			 * This is a simple object, just copy it
 			 */
 			target_object =
-			    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-							   (source_object));
+			    acpi_ut_create_internal_object(source_object->
+							   common.type);
 			if (!target_object) {
 				return (AE_NO_MEMORY);
 			}
@@ -892,7 +893,7 @@ acpi_ut_copy_ipackage_to_ipackage(union
 
 	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
 
-	dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+	dest_obj->common.type = source_obj->common.type;
 	dest_obj->common.flags = source_obj->common.flags;
 	dest_obj->package.count = source_obj->package.count;
 
@@ -950,15 +951,14 @@ acpi_ut_copy_iobject_to_iobject(union ac
 
 	/* Create the top level object */
 
-	*dest_desc =
-	    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+	*dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
 	if (!*dest_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
 	/* Copy the object and possible subobjects */
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
 						      walk_state);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utdelete.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utdelete.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utdelete.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utdelete.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ static void acpi_ut_delete_internal_obj(
 	 * Must delete or free any pointers within the object that are not
 	 * actual ACPI objects (for example, a raw buffer pointer).
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(object)) {
+	switch (object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@ acpi_ut_update_ref_count(union acpi_oper
 					  object, new_count));
 		}
 
-		if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+		if (object->common.type == ACPI_TYPE_METHOD) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
 					  "Method Obj %p Refs=%X, [Decremented]\n",
 					  object, new_count));
@@ -469,7 +469,7 @@ acpi_ut_update_object_reference(union ac
 		 * All sub-objects must have their reference count incremented also.
 		 * Different object types have different subobjects.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(object)) {
+		switch (object->common.type) {
 		case ACPI_TYPE_DEVICE:
 		case ACPI_TYPE_PROCESSOR:
 		case ACPI_TYPE_POWER:
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/uteval.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/uteval.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/uteval.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/uteval.c	2009-06-09 23:05:27.000000000 -0400
@@ -59,26 +59,35 @@ acpi_ut_translate_one_cid(union acpi_ope
 
 /*
  * Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
  */
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
 	/* Operating System Vendor Strings */
 
-	"Windows 2000",		/* Windows 2000 */
-	"Windows 2001",		/* Windows XP */
-	"Windows 2001 SP1",	/* Windows XP SP1 */
-	"Windows 2001 SP2",	/* Windows XP SP2 */
-	"Windows 2001.1",	/* Windows Server 2003 */
-	"Windows 2001.1 SP1",	/* Windows Server 2003 SP1 - Added 03/2006 */
-	"Windows 2006",		/* Windows Vista - Added 03/2006 */
+	{"Windows 2000", ACPI_OSI_WIN_2000},	/* Windows 2000 */
+	{"Windows 2001", ACPI_OSI_WIN_XP},	/* Windows XP */
+	{"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
+	{"Windows 2001.1", ACPI_OSI_WINSRV_2003},	/* Windows Server 2003 */
+	{"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2},	/* Windows XP SP2 */
+	{"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1},	/* Windows Server 2003 SP1 - Added 03/2006 */
+	{"Windows 2006", ACPI_OSI_WIN_VISTA},	/* Windows Vista - Added 03/2006 */
 
 	/* Feature Group Strings */
 
-	"Extended Address Space Descriptor"
-	    /*
-	     * All "optional" feature group strings (features that are implemented
-	     * by the host) should be implemented in the host version of
-	     * acpi_os_validate_interface and should not be added here.
-	     */
+	{"Extended Address Space Descriptor", 0}
+
+	/*
+	 * All "optional" feature group strings (features that are implemented
+	 * by the host) should be implemented in the host version of
+	 * acpi_os_validate_interface and should not be added here.
+	 */
 };
 
 /*******************************************************************************
@@ -98,6 +107,7 @@ acpi_status acpi_ut_osi_implementation(s
 	acpi_status status;
 	union acpi_operand_object *string_desc;
 	union acpi_operand_object *return_desc;
+	u32 return_value;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@ acpi_status acpi_ut_osi_implementation(s
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	/* Default return value is 0, NOT-SUPPORTED */
+	/* Default return value is 0, NOT SUPPORTED */
 
-	return_desc->integer.value = 0;
-	walk_state->return_desc = return_desc;
+	return_value = 0;
 
 	/* Compare input string to static table of supported interfaces */
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP
-		    (string_desc->string.pointer,
-		     acpi_interfaces_supported[i])) {
-			return_desc->integer.value = ACPI_UINT32_MAX;
-			goto done;
+		if (!ACPI_STRCMP(string_desc->string.pointer,
+				 acpi_interfaces_supported[i].name)) {
+			/*
+			 * The interface is supported.
+			 * Update the osi_data if necessary. We keep track of the latest
+			 * version of Windows that has been requested by the BIOS.
+			 */
+			if (acpi_interfaces_supported[i].value >
+			    acpi_gbl_osi_data) {
+				acpi_gbl_osi_data =
+				    acpi_interfaces_supported[i].value;
+			}
+
+			return_value = ACPI_UINT32_MAX;
+			goto exit;
 		}
 	}
 
@@ -139,15 +158,22 @@ acpi_status acpi_ut_osi_implementation(s
 	 */
 	status = acpi_os_validate_interface(string_desc->string.pointer);
 	if (ACPI_SUCCESS(status)) {
-		return_desc->integer.value = ACPI_UINT32_MAX;
+
+		/* The interface is supported */
+
+		return_value = ACPI_UINT32_MAX;
 	}
 
-done:
-	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
-		string_desc->string.pointer,
-		return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+		"ACPI: BIOS _OSI(%s) is %ssupported\n",
+		string_desc->string.pointer, return_value == 0 ? "not " : ""));
 
-	return_ACPI_STATUS(AE_OK);
+	/* Complete the return value */
+
+	return_desc->integer.value = return_value;
+	walk_state->return_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
 }
 
 /*******************************************************************************
@@ -167,8 +193,8 @@ acpi_status acpi_osi_invalidate(char *in
 	int i;
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
-			*acpi_interfaces_supported[i] = '\0';
+		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+			*acpi_interfaces_supported[i].name = '\0';
 			return AE_OK;
 		}
 	}
@@ -248,7 +274,7 @@ acpi_ut_evaluate_object(struct acpi_name
 
 	/* Map the return object type to the bitmapped type */
 
-	switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+	switch ((info->return_object)->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_BTYPE_INTEGER;
 		break;
@@ -418,7 +444,7 @@ acpi_ut_execute_HID(struct acpi_namespac
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric HID to string */
 
@@ -459,7 +485,7 @@ acpi_ut_translate_one_cid(union acpi_ope
 			  struct acpi_compatible_id *one_cid)
 {
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@ acpi_ut_execute_CID(struct acpi_namespac
 	/* Get the number of _CIDs returned */
 
 	count = 1;
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 		count = obj_desc->package.count;
 	}
 
@@ -555,7 +581,7 @@ acpi_ut_execute_CID(struct acpi_namespac
 
 	/* The _CID object can be either a single CID or a package (list) of CIDs */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Translate each package element */
 
@@ -620,7 +646,7 @@ acpi_ut_execute_UID(struct acpi_namespac
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric UID to string */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utglobal.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utglobal.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utglobal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utglobal.c	2009-06-09 23:05:27.000000000 -0400
@@ -294,12 +294,9 @@ struct acpi_bit_register_info acpi_gbl_b
 	/* ACPI_BITREG_GLOBAL_LOCK_RELEASE  */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
 						ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
-	/* ACPI_BITREG_SLEEP_TYPE_A         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
-	/* ACPI_BITREG_SLEEP_TYPE_B         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
+	/* ACPI_BITREG_SLEEP_TYPE           */ {ACPI_REGISTER_PM1_CONTROL,
+						ACPI_BITPOSITION_SLEEP_TYPE,
+						ACPI_BITMASK_SLEEP_TYPE},
 	/* ACPI_BITREG_SLEEP_ENABLE         */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_SLEEP_ENABLE,
 						ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@ char *acpi_ut_get_object_type_name(union
 		return ("[NULL Object Descriptor]");
 	}
 
-	return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+	return (acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
@@ -749,7 +746,10 @@ acpi_status acpi_ut_init_globals(void)
 	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
 		acpi_gbl_owner_id_mask[i] = 0;
 	}
-	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;	/* Last ID is never valid */
+
+	/* Last owner_iD is never valid */
+
+	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
 
 	/* GPE support */
 
@@ -789,6 +789,7 @@ acpi_status acpi_ut_init_globals(void)
 	acpi_gbl_trace_dbg_layer = 0;
 	acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
 	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+	acpi_gbl_osi_data = 0;
 
 	/* Hardware oriented */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utlock.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utlock.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utlock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utlock.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * 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"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_rw_lock
+ *              acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	lock->num_readers = 0;
+	status = acpi_os_create_mutex(&lock->reader_mutex);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_create_mutex(&lock->writer_mutex);
+	return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_delete_mutex(lock->reader_mutex);
+	acpi_os_delete_mutex(lock->writer_mutex);
+
+	lock->num_readers = 0;
+	lock->reader_mutex = NULL;
+	lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_read_lock
+ *              acpi_ut_release_read_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ *              only the first reader acquires the write mutex. On release,
+ *              only the last reader releases the write mutex. Although this
+ *              algorithm can in theory starve writers, this should not be a
+ *              problem with ACPICA since the subsystem is infrequently used
+ *              in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Acquire the write lock only for the first reader */
+
+	lock->num_readers++;
+	if (lock->num_readers == 1) {
+		status =
+		    acpi_os_acquire_mutex(lock->writer_mutex,
+					  ACPI_WAIT_FOREVER);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Release the write lock only for the very last reader */
+
+	lock->num_readers--;
+	if (lock->num_readers == 0) {
+		acpi_os_release_mutex(lock->writer_mutex);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_write_lock
+ *              acpi_ut_release_write_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ *              release the writer mutex associated with the lock. Acquisition
+ *              of the lock is fully exclusive and will block all readers and
+ *              writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+	return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_release_mutex(lock->writer_mutex);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utmisc.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utmisc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utmisc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utmisc.c	2009-06-09 23:05:27.000000000 -0400
@@ -938,8 +938,7 @@ acpi_ut_walk_package_tree(union acpi_ope
 		if ((!this_source_obj) ||
 		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
 		     ACPI_DESC_TYPE_OPERAND)
-		    || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
-			ACPI_TYPE_PACKAGE)) {
+		    || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
 			status =
 			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
 					  this_source_obj, state, context);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utmutex.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utmutex.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utmutex.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utmutex.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,7 +60,8 @@ static acpi_status acpi_ut_delete_mutex(
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -71,9 +72,8 @@ acpi_status acpi_ut_mutex_initialize(voi
 
 	ACPI_FUNCTION_TRACE(ut_mutex_initialize);
 
-	/*
-	 * Create each of the predefined mutex objects
-	 */
+	/* Create each of the predefined mutex objects */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		status = acpi_ut_create_mutex(i);
 		if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@ acpi_status acpi_ut_mutex_initialize(voi
 	spin_lock_init(acpi_gbl_gpe_lock);
 	spin_lock_init(acpi_gbl_hardware_lock);
 
+	/* Create the reader/writer lock for namespace access */
+
+	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
@@ -97,7 +100,8 @@ acpi_status acpi_ut_mutex_initialize(voi
  *
  * RETURN:      None.
  *
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -107,9 +111,8 @@ void acpi_ut_mutex_terminate(void)
 
 	ACPI_FUNCTION_TRACE(ut_mutex_terminate);
 
-	/*
-	 * Delete each predefined mutex object
-	 */
+	/* Delete each predefined mutex object */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		(void)acpi_ut_delete_mutex(i);
 	}
@@ -118,6 +121,10 @@ void acpi_ut_mutex_terminate(void)
 
 	acpi_os_delete_lock(acpi_gbl_gpe_lock);
 	acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+	/* Delete the reader/writer lock */
+
+	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_VOID;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utobject.c linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utobject.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/acpica/utobject.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/acpica/utobject.c	2009-06-09 23:05:27.000000000 -0400
@@ -310,7 +310,7 @@ u8 acpi_ut_valid_internal_object(void *o
 	/* Check for a null pointer */
 
 	if (!object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
 		return (FALSE);
 	}
 
@@ -324,7 +324,7 @@ u8 acpi_ut_valid_internal_object(void *o
 		return (TRUE);
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "%p is not not an ACPI operand obj [%s]\n",
 				  object, acpi_ut_get_descriptor_name(object)));
 		break;
@@ -457,7 +457,7 @@ acpi_ut_get_simple_object_size(union acp
 	 * must be accessed bytewise or there may be alignment problems on
 	 * certain processors
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@ acpi_ut_get_simple_object_size(union acp
 		ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
 			    "unsupported type [%s] %X in object %p",
 			    acpi_ut_get_object_type_name(internal_object),
-			    ACPI_GET_OBJECT_TYPE(internal_object),
-			    internal_object));
+			    internal_object->common.type, internal_object));
 		status = AE_TYPE;
 		break;
 	}
@@ -664,7 +663,7 @@ acpi_ut_get_object_size(union acpi_opera
 
 	if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
 	     ACPI_DESC_TYPE_OPERAND)
-	    && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+	    && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
 		status =
 		    acpi_ut_get_package_object_size(internal_object,
 						    obj_length);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/battery.c linux-libre-2.6.30-gnu1/drivers/acpi/battery.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/battery.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/battery.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/jiffies.h>
+#include <linux/async.h>
 
 #ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
@@ -92,7 +93,7 @@ struct acpi_battery {
 #endif
 	struct acpi_device *device;
 	unsigned long update_time;
-	int current_now;
+	int rate_now;
 	int capacity_now;
 	int voltage_now;
 	int design_capacity;
@@ -196,7 +197,8 @@ static int acpi_battery_get_property(str
 		val->intval = battery->voltage_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = battery->current_now * 1000;
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = battery->rate_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +249,7 @@ static enum power_supply_property energy
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_POWER_NOW,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
 	POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +276,7 @@ struct acpi_offsets {
 
 static struct acpi_offsets state_offsets[] = {
 	{offsetof(struct acpi_battery, state), 0},
-	{offsetof(struct acpi_battery, current_now), 0},
+	{offsetof(struct acpi_battery, rate_now), 0},
 	{offsetof(struct acpi_battery, capacity_now), 0},
 	{offsetof(struct acpi_battery, voltage_now), 0},
 };
@@ -605,11 +608,11 @@ static int acpi_battery_print_state(stru
 	else
 		seq_printf(seq, "charging state:          charged\n");
 
-	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   battery->current_now, acpi_battery_units(battery));
+			   battery->rate_now, acpi_battery_units(battery));
 
 	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
@@ -740,7 +743,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
 static struct battery_file {
 	struct file_operations ops;
 	mode_t mode;
-	char *name;
+	const char *name;
 } acpi_battery_file[] = {
 	FILE_DESCRIPTION_RO(info),
 	FILE_DESCRIPTION_RO(state),
@@ -760,7 +763,6 @@ static int acpi_battery_add_fs(struct ac
 						     acpi_battery_dir);
 		if (!acpi_device_dir(device))
 			return -ENODEV;
-		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
@@ -901,21 +903,27 @@ static struct acpi_driver acpi_battery_d
 		},
 };
 
-static int __init acpi_battery_init(void)
+static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
 {
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 #ifdef CONFIG_ACPI_PROCFS_POWER
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir)
-		return -ENODEV;
+		return;
 #endif
 	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
 #ifdef CONFIG_ACPI_PROCFS_POWER
 		acpi_unlock_battery_dir(acpi_battery_dir);
 #endif
-		return -ENODEV;
+		return;
 	}
+	return;
+}
+
+static int __init acpi_battery_init(void)
+{
+	async_schedule(acpi_battery_init_async, NULL);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/bus.c linux-libre-2.6.30-gnu1/drivers/acpi/bus.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,8 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("bus");
 
@@ -310,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handl
       end:
 	if (result)
 		printk(KERN_WARNING PREFIX
-			      "Transitioning device [%s] to D%d\n",
+			      "Device [%s] failed to transition to D%d\n",
 			      device->pnp.bus_id, state);
 	else {
 		device->power.state = state;
@@ -846,6 +848,7 @@ static int __init acpi_init(void)
 		acpi_kobj = NULL;
 	}
 
+	init_acpi_device_notify();
 	result = acpi_bus_init();
 
 	if (!result) {
@@ -860,11 +863,23 @@ static int __init acpi_init(void)
 		}
 	} else
 		disable_acpi();
+
+	if (acpi_disabled)
+		return result;
+
 	/*
 	 * If the laptop falls into the DMI check table, the power state check
 	 * will be disabled in the course of device power transistion.
 	 */
 	dmi_check_system(power_nocheck_dmi_table);
+
+	acpi_scan_init();
+	acpi_ec_init();
+	acpi_power_init();
+	acpi_system_init();
+	acpi_debug_init();
+	acpi_sleep_proc_init();
+	acpi_wakeup_device_init();
 	return result;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/button.c linux-libre-2.6.30-gnu1/drivers/acpi/button.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/button.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/button.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- *  acpi_button.c - ACPI Button Driver ($Revision: 30 $)
+ *  button.c - ACPI Button Driver
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -41,17 +41,13 @@
 
 #define ACPI_BUTTON_SUBCLASS_POWER	"power"
 #define ACPI_BUTTON_HID_POWER		"PNP0C0C"
-#define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_POWERF	"Power Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_POWER	"Power Button"
 #define ACPI_BUTTON_TYPE_POWER		0x01
-#define ACPI_BUTTON_TYPE_POWERF		0x02
 
 #define ACPI_BUTTON_SUBCLASS_SLEEP	"sleep"
 #define ACPI_BUTTON_HID_SLEEP		"PNP0C0E"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button (CM)"
-#define ACPI_BUTTON_DEVICE_NAME_SLEEPF	"Sleep Button (FF)"
+#define ACPI_BUTTON_DEVICE_NAME_SLEEP	"Sleep Button"
 #define ACPI_BUTTON_TYPE_SLEEP		0x03
-#define ACPI_BUTTON_TYPE_SLEEPF		0x04
 
 #define ACPI_BUTTON_SUBCLASS_LID	"lid"
 #define ACPI_BUTTON_HID_LID		"PNP0C0D"
@@ -78,6 +74,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
 static int acpi_button_resume(struct acpi_device *device);
+static void acpi_button_notify(struct acpi_device *device, u32 event);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -89,11 +86,11 @@ static struct acpi_driver acpi_button_dr
 		.add = acpi_button_add,
 		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
+		.notify = acpi_button_notify,
 	},
 };
 
 struct acpi_button {
-	struct acpi_device *device;	/* Fixed button kludge */
 	unsigned int type;
 	struct input_dev *input;
 	char phys[32];			/* for input device */
@@ -124,14 +121,10 @@ static struct proc_dir_entry *acpi_butto
 
 static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = seq->private;
-
-	if (!button || !button->device)
-		return 0;
+	struct acpi_device *device = seq->private;
 
 	seq_printf(seq, "type:                    %s\n",
-		   acpi_device_name(button->device));
-
+		   acpi_device_name(device));
 	return 0;
 }
 
@@ -142,14 +135,11 @@ static int acpi_button_info_open_fs(stru
 
 static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = seq->private;
+	struct acpi_device *device = seq->private;
 	acpi_status status;
 	unsigned long long state;
 
-	if (!button || !button->device)
-		return 0;
-
-	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
+	status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
 	seq_printf(seq, "state:      %s\n",
 		   ACPI_FAILURE(status) ? "unsupported" :
 			(state ? "open" : "closed"));
@@ -167,24 +157,17 @@ static struct proc_dir_entry *acpi_lid_d
 
 static int acpi_button_add_fs(struct acpi_device *device)
 {
+	struct acpi_button *button = acpi_driver_data(device);
 	struct proc_dir_entry *entry = NULL;
-	struct acpi_button *button;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	button = acpi_driver_data(device);
 
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
 		if (!acpi_power_dir)
 			acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
 						    acpi_button_dir);
 		entry = acpi_power_dir;
 		break;
 	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
 		if (!acpi_sleep_dir)
 			acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
 						    acpi_button_dir);
@@ -200,18 +183,15 @@ static int acpi_button_add_fs(struct acp
 
 	if (!entry)
 		return -ENODEV;
-	entry->owner = THIS_MODULE;
 
 	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
 	if (!acpi_device_dir(device))
 		return -ENODEV;
-	acpi_device_dir(device)->owner = THIS_MODULE;
 
 	/* 'info' [R] */
 	entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
 				 S_IRUGO, acpi_device_dir(device),
-				 &acpi_button_info_fops,
-				 acpi_driver_data(device));
+				 &acpi_button_info_fops, device);
 	if (!entry)
 		return -ENODEV;
 
@@ -219,8 +199,7 @@ static int acpi_button_add_fs(struct acp
 	if (button->type == ACPI_BUTTON_TYPE_LID) {
 		entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
 					 S_IRUGO, acpi_device_dir(device),
-					 &acpi_button_state_fops,
-					 acpi_driver_data(device));
+					 &acpi_button_state_fops, device);
 		if (!entry)
 			return -ENODEV;
 	}
@@ -250,34 +229,35 @@ static int acpi_button_remove_fs(struct
 /* --------------------------------------------------------------------------
                                 Driver Interface
    -------------------------------------------------------------------------- */
-static int acpi_lid_send_state(struct acpi_button *button)
+static int acpi_lid_send_state(struct acpi_device *device)
 {
+	struct acpi_button *button = acpi_driver_data(device);
 	unsigned long long state;
 	acpi_status status;
 
-	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
-					&state);
+	status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
+
 	/* input layer checks if event is redundant */
 	input_report_switch(button->input, SW_LID, !state);
 	input_sync(button->input);
 	return 0;
 }
 
-static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_button_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_button *button = data;
+	struct acpi_button *button = acpi_driver_data(device);
 	struct input_dev *input;
 
-	if (!button || !button->device)
-		return;
-
 	switch (event) {
+	case ACPI_FIXED_HARDWARE_EVENT:
+		event = ACPI_BUTTON_NOTIFY_STATUS;
+		/* fall through */
 	case ACPI_BUTTON_NOTIFY_STATUS:
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
-			acpi_lid_send_state(button);
+			acpi_lid_send_state(device);
 		} else {
 			int keycode = test_bit(KEY_SLEEP, input->keybit) ?
 						KEY_SLEEP : KEY_POWER;
@@ -288,102 +268,35 @@ static void acpi_button_notify(acpi_hand
 			input_sync(input);
 		}
 
-		acpi_bus_generate_proc_event(button->device, event,
-					++button->pushed);
+		acpi_bus_generate_proc_event(device, event, ++button->pushed);
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
-
-	return;
-}
-
-static acpi_status acpi_button_notify_fixed(void *data)
-{
-	struct acpi_button *button = data;
-
-	if (!button)
-		return AE_BAD_PARAMETER;
-
-	acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
-
-	return AE_OK;
-}
-
-static int acpi_button_install_notify_handlers(struct acpi_button *button)
-{
-	acpi_status status;
-
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
-		break;
-	default:
-		status = acpi_install_notify_handler(button->device->handle,
-						     ACPI_DEVICE_NOTIFY,
-						     acpi_button_notify,
-						     button);
-		break;
-	}
-
-	return ACPI_FAILURE(status) ? -ENODEV : 0;
 }
 
 static int acpi_button_resume(struct acpi_device *device)
 {
-	struct acpi_button *button;
-	if (!device)
-		return -EINVAL;
-	button = acpi_driver_data(device);
-	if (button && button->type == ACPI_BUTTON_TYPE_LID)
-		return acpi_lid_send_state(button);
-	return 0;
-}
+	struct acpi_button *button = acpi_driver_data(device);
 
-static void acpi_button_remove_notify_handlers(struct acpi_button *button)
-{
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	default:
-		acpi_remove_notify_handler(button->device->handle,
-					   ACPI_DEVICE_NOTIFY,
-					   acpi_button_notify);
-		break;
-	}
+	if (button->type == ACPI_BUTTON_TYPE_LID)
+		return acpi_lid_send_state(device);
+	return 0;
 }
 
 static int acpi_button_add(struct acpi_device *device)
 {
-	int error;
 	struct acpi_button *button;
 	struct input_dev *input;
-
-	if (!device)
-		return -EINVAL;
+	char *hid, *name, *class;
+	int error;
 
 	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
 	if (!button)
 		return -ENOMEM;
 
-	button->device = device;
 	device->driver_data = button;
 
 	button->input = input = input_allocate_device();
@@ -392,40 +305,29 @@ static int acpi_button_add(struct acpi_d
 		goto err_free_button;
 	}
 
-	/*
-	 * Determine the button type (via hid), as fixed-feature buttons
-	 * need to be handled a bit differently than generic-space.
-	 */
-	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
+	hid = acpi_device_hid(device);
+	name = acpi_device_name(device);
+	class = acpi_device_class(device);
+
+	if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
+	    !strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
 		button->type = ACPI_BUTTON_TYPE_POWER;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_POWER);
-		sprintf(acpi_device_class(device), "%s/%s",
-			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
-		button->type = ACPI_BUTTON_TYPE_POWERF;
-		strcpy(acpi_device_name(device),
-		       ACPI_BUTTON_DEVICE_NAME_POWERF);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
+	} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
+		   !strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
 		button->type = ACPI_BUTTON_TYPE_SLEEP;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_SLEEP);
-		sprintf(acpi_device_class(device), "%s/%s",
-			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
-		button->type = ACPI_BUTTON_TYPE_SLEEPF;
-		strcpy(acpi_device_name(device),
-		       ACPI_BUTTON_DEVICE_NAME_SLEEPF);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
-	} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
+	} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
 		button->type = ACPI_BUTTON_TYPE_LID;
-		strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_LID);
-		sprintf(acpi_device_class(device), "%s/%s",
+		strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
+		sprintf(class, "%s/%s",
 			ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
 	} else {
-		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
-			    acpi_device_hid(device));
+		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
 		error = -ENODEV;
 		goto err_free_input;
 	}
@@ -434,14 +336,9 @@ static int acpi_button_add(struct acpi_d
 	if (error)
 		goto err_free_input;
 
-	error = acpi_button_install_notify_handlers(button);
-	if (error)
-		goto err_remove_fs;
-
-	snprintf(button->phys, sizeof(button->phys),
-		 "%s/button/input0", acpi_device_hid(device));
+	snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
 
-	input->name = acpi_device_name(device);
+	input->name = name;
 	input->phys = button->phys;
 	input->id.bustype = BUS_HOST;
 	input->id.product = button->type;
@@ -449,13 +346,11 @@ static int acpi_button_add(struct acpi_d
 
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
 		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_POWER, input->keybit);
 		break;
 
 	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
 		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_SLEEP, input->keybit);
 		break;
@@ -468,9 +363,9 @@ static int acpi_button_add(struct acpi_d
 
 	error = input_register_device(input);
 	if (error)
-		goto err_remove_handlers;
+		goto err_remove_fs;
 	if (button->type == ACPI_BUTTON_TYPE_LID)
-		acpi_lid_send_state(button);
+		acpi_lid_send_state(device);
 
 	if (device->wakeup.flags.valid) {
 		/* Button's GPE is run-wake GPE */
@@ -482,13 +377,9 @@ static int acpi_button_add(struct acpi_d
 		device->wakeup.state.enabled = 1;
 	}
 
-	printk(KERN_INFO PREFIX "%s [%s]\n",
-	       acpi_device_name(device), acpi_device_bid(device));
-
+	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
 	return 0;
 
- err_remove_handlers:
-	acpi_button_remove_notify_handlers(button);
  err_remove_fs:
 	acpi_button_remove_fs(device);
  err_free_input:
@@ -500,18 +391,11 @@ static int acpi_button_add(struct acpi_d
 
 static int acpi_button_remove(struct acpi_device *device, int type)
 {
-	struct acpi_button *button;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	button = acpi_driver_data(device);
+	struct acpi_button *button = acpi_driver_data(device);
 
-	acpi_button_remove_notify_handlers(button);
 	acpi_button_remove_fs(device);
 	input_unregister_device(button->input);
 	kfree(button);
-
 	return 0;
 }
 
@@ -522,7 +406,7 @@ static int __init acpi_button_init(void)
 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
 	if (!acpi_button_dir)
 		return -ENODEV;
-	acpi_button_dir->owner = THIS_MODULE;
+
 	result = acpi_bus_register_driver(&acpi_button_driver);
 	if (result < 0) {
 		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/debug.c linux-libre-2.6.30-gnu1/drivers/acpi/debug.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,11 +13,6 @@
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("debug");
 
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
-
 struct acpi_dlayer {
 	const char *name;
 	unsigned long value;
@@ -297,17 +292,15 @@ acpi_system_write_debug(struct file *fil
 
 	return count;
 }
+#endif
 
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *entry;
 	int error = 0;
 	char *name;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	/* 'debug_layer' [R/W] */
 	name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
 	entry =
@@ -338,7 +331,7 @@ static int __init acpi_debug_init(void)
 	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
 	error = -ENODEV;
 	goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+	return 0;
 #endif
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/dock.c linux-libre-2.6.30-gnu1/drivers/acpi/dock.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/dock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/dock.c	2009-06-09 23:05:27.000000000 -0400
@@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle)
 		sizeof(struct dock_station *));
 
 	/* we want the dock device to send uevents */
-	dock_device->dev.uevent_suppress = 0;
+	dev_set_uevent_suppress(&dock_device->dev, 0);
 
 	if (is_dock(handle))
 		dock_station->flags |= DOCK_IS_DOCK;
@@ -1146,9 +1146,10 @@ static int __init dock_init(void)
 static void __exit dock_exit(void)
 {
 	struct dock_station *dock_station;
+	struct dock_station *tmp;
 
 	unregister_acpi_bus_notifier(&dock_acpi_notifier);
-	list_for_each_entry(dock_station, &dock_stations, sibiling)
+	list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
 		dock_remove(dock_station);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/ec.c linux-libre-2.6.30-gnu1/drivers/acpi/ec.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/ec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/ec.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,7 +67,7 @@ enum ec_command {
 
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY		100	/* Wait 100us before polling EC again */
+#define ACPI_EC_CDELAY		10	/* Wait 10us before polling EC */
 
 #define ACPI_EC_STORM_THRESHOLD 8	/* number of false interrupts
 					   per one transaction */
@@ -236,13 +236,23 @@ static int ec_check_sci(struct acpi_ec *
 	return 0;
 }
 
+static void ec_delay(void)
+{
+	/* EC in MSI notebooks don't tolerate delays other than 550 usec */
+	if (EC_FLAGS_MSI)
+		udelay(ACPI_EC_DELAY);
+	else
+		/* Use shortest sleep available */
+		msleep(1);
+}
+
 static int ec_poll(struct acpi_ec *ec)
 {
 	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
-	udelay(ACPI_EC_UDELAY);
+	udelay(ACPI_EC_CDELAY);
 	while (time_before(jiffies, delay)) {
 		gpe_transaction(ec, acpi_ec_read_status(ec));
-		udelay(ACPI_EC_UDELAY);
+		ec_delay();
 		if (ec_transaction_done(ec))
 			return 0;
 	}
@@ -672,7 +682,7 @@ static int acpi_ec_info_open_fs(struct i
 	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
 	.open = acpi_ec_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -755,6 +765,10 @@ ec_parse_device(acpi_handle handle, u32
 	unsigned long long tmp = 0;
 
 	struct acpi_ec *ec = context;
+
+	/* clear addr values, ec_parse_io_ports depend on it */
+	ec->command_addr = ec->data_addr = 0;
+
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 				     ec_parse_io_ports, ec);
 	if (ACPI_FAILURE(status))
@@ -804,11 +818,11 @@ static int acpi_ec_add(struct acpi_devic
 		ec = make_acpi_ec();
 		if (!ec)
 			return -ENOMEM;
-		if (ec_parse_device(device->handle, 0, ec, NULL) !=
-		    AE_CTRL_TERMINATE) {
+	}
+	if (ec_parse_device(device->handle, 0, ec, NULL) !=
+		AE_CTRL_TERMINATE) {
 			kfree(ec);
 			return -EINVAL;
-		}
 	}
 
 	ec->handle = device->handle;
@@ -986,12 +1000,12 @@ int __init acpi_ec_ecdt_probe(void)
 		boot_ec->handle = ACPI_ROOT_OBJECT;
 		acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
 		/* Don't trust ECDT, which comes from ASUSTek */
-		if (!dmi_name_in_vendors("ASUS"))
+		if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
 			goto install;
 		saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 		if (!saved_ec)
 			return -ENOMEM;
-		memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
+		memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
 	/* fall through */
 	}
 	/* This workaround is needed only on some broken machines,
@@ -1051,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_de
 	struct acpi_ec *ec = acpi_driver_data(device);
 	/* Enable use of GPE back */
 	clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
+	set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
 	acpi_enable_gpe(NULL, ec->gpe);
 	return 0;
 }
@@ -1069,13 +1084,10 @@ static struct acpi_driver acpi_ec_driver
 		},
 };
 
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
 {
 	int result = 0;
 
-	if (acpi_disabled)
-		return 0;
-
 	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
 	if (!acpi_ec_dir)
 		return -ENODEV;
@@ -1090,8 +1102,6 @@ static int __init acpi_ec_init(void)
 	return result;
 }
 
-subsys_initcall(acpi_ec_init);
-
 /* EC driver currently not unloadable */
 #if 0
 static void __exit acpi_ec_exit(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/event.c linux-libre-2.6.30-gnu1/drivers/acpi/event.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/event.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/event.c	2009-06-09 23:05:27.000000000 -0400
@@ -235,11 +235,7 @@ int acpi_bus_generate_netlink_event(cons
 		return result;
 	}
 
-	result =
-	    genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
-	if (result)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Failed to send a Genetlink message!\n"));
+	genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/fan.c linux-libre-2.6.30-gnu1/drivers/acpi/fan.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/fan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/fan.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_drive
 };
 
 /* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	/* ACPI fan device only support two states: ON/OFF */
-	return sprintf(buf, "1\n");
+	*state = 1;
+	return 0;
 }
 
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	struct acpi_device *device = cdev->devdata;
-	int state;
 	int result;
+	int acpi_state;
 
 	if (!device)
 		return -EINVAL;
 
-	result = acpi_bus_get_power(device->handle, &state);
+	result = acpi_bus_get_power(device->handle, &acpi_state);
 	if (result)
 		return result;
 
-	return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
-			 (state == ACPI_STATE_D0 ? "1" : "unknown"));
+	*state = (acpi_state == ACPI_STATE_D3 ? 0 :
+		 (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+	return 0;
 }
 
 static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	int result;
@@ -193,7 +197,6 @@ static int acpi_fan_add_fs(struct acpi_d
 						     acpi_fan_dir);
 		if (!acpi_device_dir(device))
 			return -ENODEV;
-		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'status' [R/W] */
@@ -347,7 +350,6 @@ static int __init acpi_fan_init(void)
 	acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
 	if (!acpi_fan_dir)
 		return -ENODEV;
-	acpi_fan_dir->owner = THIS_MODULE;
 #endif
 
 	result = acpi_bus_register_driver(&acpi_fan_driver);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/glue.c linux-libre-2.6.30-gnu1/drivers/acpi/glue.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/glue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/glue.c	2009-06-09 23:05:27.000000000 -0400
@@ -286,10 +286,8 @@ static int acpi_platform_notify_remove(s
 	return 0;
 }
 
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
 {
-	if (acpi_disabled)
-		return 0;
 	if (platform_notify || platform_notify_remove) {
 		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
 		return 0;
@@ -298,5 +296,3 @@ static int __init init_acpi_device_notif
 	platform_notify_remove = acpi_platform_notify_remove;
 	return 0;
 }
-
-arch_initcall(init_acpi_device_notify);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/internal.h linux-libre-2.6.30-gnu1/drivers/acpi/internal.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/acpi/internal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+                                  Power Resource
+   -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+                           int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+                                  Embedded Controller
+   -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+                                  Suspend/Resume
+  -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/Kconfig linux-libre-2.6.30-gnu1/drivers/acpi/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/acpi/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -11,9 +11,9 @@ menuconfig ACPI
 	select PNP
 	select CPU_IDLE
 	default y
-	---help---
+	help
 	  Advanced Configuration and Power Interface (ACPI) support for 
-	  Linux requires an ACPI compliant platform (hardware/firmware),
+	  Linux requires an ACPI-compliant platform (hardware/firmware),
 	  and assumes the presence of OS-directed configuration and power
 	  management (OSPM) software.  This option will enlarge your 
 	  kernel by about 70K.
@@ -23,20 +23,19 @@ menuconfig ACPI
 	  the Plug-and-Play BIOS specification (PnP BIOS), the 
 	  MultiProcessor Specification (MPS), and the Advanced Power 
 	  Management (APM) specification.  If both ACPI and APM support 
-	  are configured, whichever is loaded first shall be used.
+	  are configured, ACPI is used.
 
-	  The ACPI SourceForge project contains the latest source code, 
-	  documentation, tools, mailing list subscription, and other 
-	  information.  This project is available at:
-	  <http://sourceforge.net/projects/acpi>
+	  The project home page for the Linux ACPI subsystem is here:
+	  <http://www.lesswatts.org/projects/acpi/>
 
 	  Linux support for ACPI is based on Intel Corporation's ACPI
-	  Component Architecture (ACPI CA).  For more information see:
-	  <http://developer.intel.com/technology/iapc/acpi>
+	  Component Architecture (ACPI CA).  For more information on the
+	  ACPI CA, see:
+	  <http://acpica.org/>
 
-	  ACPI is an open industry specification co-developed by Compaq, 
-	  Intel, Microsoft, Phoenix, and Toshiba.  The specification is 
-	  available at:
+	  ACPI is an open industry specification co-developed by
+	  Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+	  The specification is available at:
 	  <http://www.acpi.info>
 
 if ACPI
@@ -49,14 +48,14 @@ config ACPI_SLEEP
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
 	depends on PROC_FS
-	---help---
+	help
 	  For backwards compatibility, this option allows
 	  deprecated /proc/acpi/ files to exist, even when
 	  they have been replaced by functions in /sys.
 	  The deprecated files (and their replacements) include:
 
 	  /proc/acpi/sleep (/sys/power/state)
-	  /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+	  /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
 	  /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
 	  /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
 	  /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@ config ACPI_PROCFS
 	  and functions which do not yet exist in /sys.
 
 	  Say N to delete /proc/acpi/ files that have moved to /sys/
+
 config ACPI_PROCFS_POWER
 	bool "Deprecated power /proc/acpi directories"
 	depends on PROC_FS
 	default y
-	---help---
+	help
 	  For backwards compatibility, this option allows
           deprecated power /proc/acpi/ directories to exist, even when
           they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@ config ACPI_SYSFS_POWER
 	bool "Future power /sys interface"
 	select POWER_SUPPLY
 	default y
-	---help---
+	help
 	  Say N to disable power /sys interface
 
 config ACPI_PROC_EVENT
 	bool "Deprecated /proc/acpi/event support"
 	depends on PROC_FS
 	default y
-	---help---
-	  A user-space daemon, acpi, typically read /proc/acpi/event
-	  and handled all ACPI sub-system generated events.
+	help
+	  A user-space daemon, acpid, typically reads /proc/acpi/event
+	  and handles all ACPI-generated events.
 
-	  These events are now delivered to user-space via
-	  either the input layer, or as netlink events.
+	  These events are now delivered to user-space either
+	  via the input layer or as netlink events.
 
 	  This build option enables the old code for legacy
 	  user-space implementation.  After some time, this will
@@ -112,10 +112,13 @@ config ACPI_AC
 	depends on X86
 	default y
 	help
-	  This driver adds support for the AC Adapter object, which indicates
-	  whether a system is on AC, or not. If you have a system that can
+	  This driver supports the AC Adapter object, which indicates
+	  whether a system is on AC or not.  If you have a system that can
 	  switch between A/C and battery, say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called ac.
+
 config ACPI_BATTERY
 	tristate "Battery"
 	depends on X86
@@ -125,15 +128,21 @@ config ACPI_BATTERY
 	  /proc/acpi/battery. If you have a mobile system with a battery, 
 	  say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called battery.
+
 config ACPI_BUTTON
 	tristate "Button"
 	depends on INPUT
 	default y
 	help
-	  This driver handles events on the power, sleep and lid buttons.
+	  This driver handles events on the power, sleep, and lid buttons.
 	  A daemon reads /proc/acpi/event and perform user-defined actions
 	  such as shutting down the system.  This is necessary for
-	  software controlled poweroff.
+	  software-controlled poweroff.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called button.
 
 config ACPI_VIDEO
 	tristate "Video"
@@ -141,38 +150,45 @@ config ACPI_VIDEO
 	depends on INPUT
 	select THERMAL
 	help
-	  This driver implement the ACPI Extensions For Display Adapters
+	  This driver implements the ACPI Extensions For Display Adapters
 	  for integrated graphics devices on motherboard, as specified in
-	  ACPI 2.0 Specification, Appendix B, allowing to perform some basic
-	  control like defining the video POST device, retrieving EDID information
-	  or to setup a video output, etc.
-	  Note that this is an ref. implementation only.  It may or may not work
-	  for your integrated video device.
+	  ACPI 2.0 Specification, Appendix B.  This supports basic operations
+	  such as defining the video POST device, retrieving EDID information,
+	  and setting up a video output.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called video.
 
 config ACPI_FAN
 	tristate "Fan"
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI fan devices, allowing user-mode 
+	  This driver supports ACPI fan devices, allowing user-mode
 	  applications to perform basic fan control (on, off, status).
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called fan.
+
 config ACPI_DOCK
 	bool "Dock"
 	depends on EXPERIMENTAL
 	help
-	  This driver adds support for ACPI controlled docking stations and removable
-	  drive bays such as the IBM ultrabay or the Dell Module Bay.
+	  This driver supports ACPI-controlled docking stations and removable
+	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
 
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	default y
 	help
-	  This driver installs ACPI as the idle handler for Linux, and uses
-	  ACPI C2 and C3 processor states to save power, on systems that
+	  This driver installs ACPI as the idle handler for Linux and uses
+	  ACPI C2 and C3 processor states to save power on systems that
 	  support it.  It is required by several flavors of cpufreq
-	  Performance-state drivers.
+	  performance-state drivers.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called processor.
 
 config ACPI_HOTPLUG_CPU
 	bool
@@ -186,11 +202,14 @@ config ACPI_THERMAL
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI thermal zones.  Most mobile and
+	  This driver supports ACPI thermal zones.  Most mobile and
 	  some desktop systems support ACPI thermal zones.  It is HIGHLY
 	  recommended that this option be enabled, as your processor(s)
 	  may be damaged without it.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called thermal.
+
 config ACPI_NUMA
 	bool "NUMA support"
 	depends on NUMA
@@ -218,7 +237,7 @@ config ACPI_BLACKLIST_YEAR
 	int "Disable ACPI for systems before Jan 1st this year" if X86_32
 	default 0
 	help
-	  enter a 4-digit year, eg. 2001 to disable ACPI by default
+	  Enter a 4-digit year, e.g., 2001, to disable ACPI by default
 	  on platforms with DMI BIOS date before January 1st that year.
 	  "acpi=force" can be used to override this mechanism.
 
@@ -249,10 +268,13 @@ config ACPI_PCI_SLOT
 	tristate "PCI slot detection driver"
 	default n
 	help
-	  This driver will attempt to discover all PCI slots in your system,
-	  and creates entries in /sys/bus/pci/slots/. This feature can
-	  help you correlate PCI bus addresses with the physical geography
-	  of your slots. If you are unsure, say N.
+	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
+	  slots in the system.  This can help correlate PCI bus addresses,
+	  i.e., segment/bus/device/function tuples, with physical slots in
+	  the system.  If you are unsure, say N.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called pci_slot.
 
 config X86_PM_TIMER
 	bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@ config X86_PM_TIMER
 	  systems require this timer. 
 
 config ACPI_CONTAINER
-	tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+	tristate "Container and Module Devices (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
-	 ---help---
-	  This allows _physical_ insertion and removal of CPUs and memory.
-	  This can be useful, for example, on NUMA machines that support
-	  ACPI based physical hotplug of nodes, or non-NUMA machines that
-	  support physical cpu/memory hot-plug.
+	help
+	  This driver supports ACPI Container and Module devices (IDs
+	  ACPI0004, PNP0A05, and PNP0A06).
 
-	  If one selects "m", this driver can be loaded with
-	  "modprobe container".
+	  This helps support hotplug of nodes, CPUs, and memory.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called container.
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
 	depends on MEMORY_HOTPLUG
 	default n
 	help
-	  This driver adds supports for ACPI Memory Hotplug.  This driver
-	  provides support for fielding notifications on ACPI memory
-	  devices (PNP0C80) which represent memory ranges that may be
-	  onlined or offlined during runtime.  
+	  This driver supports ACPI memory hotplug.  The driver
+	  fields notifications on ACPI memory devices (PNP0C80),
+	  which represent memory ranges that may be onlined or
+	  offlined during runtime.
 
-	  Enabling this driver assumes that your platform hardware
-	  and firmware have support for hot-plugging physical memory. If
-	  your system does not support physically adding or ripping out 
-	  memory DIMMs at some platform defined granularity (individually 
-	  or as a bank) at runtime, then you need not enable this driver.
+	  If your hardware and firmware do not support adding or
+	  removing memory devices at runtime, you need not enable
+	  this driver.
 
-	  If one selects "m," this driver can be loaded using the following
-	  command: 
-		$>modprobe acpi_memhotplug 
+	  To compile this driver as a module, choose M here:
+	  the module will be called acpi_memhotplug.
 
 config ACPI_SBS
 	tristate "Smart Battery System"
 	depends on X86
 	help
-	  This driver adds support for the Smart Battery System, another
+	  This driver supports the Smart Battery System, another
 	  type of access to battery information, found on some laptops.
 
+	  To compile this driver as a module, choose M here:
+	  the modules will be called sbs and sbshc.
+
 endif	# ACPI
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/Makefile linux-libre-2.6.30-gnu1/drivers/acpi/Makefile
--- linux-libre-2.6.29-gnu1/drivers/acpi/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,48 +14,50 @@ obj-$(CONFIG_X86)		+= blacklist.o
 #
 # ACPI Core Subsystem (Interpreter)
 #
-obj-y				+= osl.o utils.o reboot.o\
+obj-y				+= acpi.o \
 					acpica/
 
+# All the builtin files are in the "acpi." module_param namespace.
+acpi-y				+= osl.o utils.o reboot.o
+
 # sleep related files
-obj-y				+= wakeup.o
-obj-y				+= sleep.o
-obj-$(CONFIG_ACPI_SLEEP)	+= proc.o
+acpi-y				+= wakeup.o
+acpi-y				+= sleep.o
+acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 
 
 #
 # ACPI Bus and Device Drivers
 #
-processor-objs	+= processor_core.o processor_throttling.o \
-				processor_idle.o processor_thermal.o
-ifdef CONFIG_CPU_FREQ
-processor-objs	+= processor_perflib.o
+acpi-y				+= bus.o glue.o
+acpi-y				+= scan.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
+acpi-y				+= power.o
+acpi-y				+= system.o event.o
+acpi-$(CONFIG_ACPI_DEBUG)	+= debug.o
+acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
+acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+ifdef CONFIG_ACPI_VIDEO
+acpi-y				+= video_detect.o
 endif
 
-obj-y				+= bus.o glue.o
-obj-y				+= scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y				+= ec.o
+# These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
-obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
-obj-$(CONFIG_ACPI_DOCK)		+= dock.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
-ifdef CONFIG_ACPI_VIDEO
-obj-y				+= video_detect.o
-endif
-
-obj-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_PCI_SLOT)	+= pci_slot.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
-obj-y				+= power.o
-obj-y				+= system.o event.o
-obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
-obj-$(CONFIG_ACPI_NUMA)		+= numa.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
-obj-$(CONFIG_ACPI_PROCFS_POWER)	+= cm_sbs.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_SBS)		+= sbshc.o
 obj-$(CONFIG_ACPI_SBS)		+= sbs.o
+
+# processor has its own "processor." module_param namespace
+processor-y			:= processor_core.o processor_throttling.o
+processor-y			+= processor_idle.o processor_thermal.o
+processor-$(CONFIG_CPU_FREQ)	+= processor_perflib.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/numa.c linux-libre-2.6.30-gnu1/drivers/acpi/numa.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/numa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/numa.c	2009-06-09 23:05:27.000000000 -0400
@@ -131,6 +131,21 @@ acpi_table_print_srat_entry(struct acpi_
 #endif				/* ACPI_DEBUG_OUTPUT */
 		break;
 
+	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+		{
+			struct acpi_srat_x2apic_cpu_affinity *p =
+			    (struct acpi_srat_x2apic_cpu_affinity *)header;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "SRAT Processor (x2apicid[0x%08x]) in"
+					  " proximity domain %d %s\n",
+					  p->apic_id,
+					  p->proximity_domain,
+					  (p->flags & ACPI_SRAT_CPU_ENABLED) ?
+					  "enabled" : "disabled"));
+		}
+#endif				/* ACPI_DEBUG_OUTPUT */
+		break;
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported SRAT entry (type = 0x%x)\n",
@@ -180,8 +195,35 @@ static int __init acpi_parse_slit(struct
 	return 0;
 }
 
+void __init __attribute__ ((weak))
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+	printk(KERN_WARNING PREFIX
+	       "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
+	return;
+}
+
+
+static int __init
+acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
+			   const unsigned long end)
+{
+	struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
+
+	processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
+	if (!processor_affinity)
+		return -EINVAL;
+
+	acpi_table_print_srat_entry(header);
+
+	/* let architecture-dependent part to do it */
+	acpi_numa_x2apic_affinity_init(processor_affinity);
+
+	return 0;
+}
+
 static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
+acpi_parse_processor_affinity(struct acpi_subtable_header *header,
 			      const unsigned long end)
 {
 	struct acpi_srat_cpu_affinity *processor_affinity;
@@ -241,6 +283,8 @@ int __init acpi_numa_init(void)
 {
 	/* 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,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/osl.c linux-libre-2.6.30-gnu1/drivers/acpi/osl.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/osl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/osl.c	2009-06-09 23:05:27.000000000 -0400
@@ -272,14 +272,21 @@ acpi_os_map_memory(acpi_physical_address
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
-void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
+void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 {
-	if (acpi_gbl_permanent_mmap) {
+	if (acpi_gbl_permanent_mmap)
 		iounmap(virt);
-	}
+	else
+		__acpi_unmap_table(virt, size);
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
+void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+{
+	if (!acpi_gbl_permanent_mmap)
+		__acpi_unmap_table(virt, size);
+}
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
@@ -346,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, voi
 	if (handled) {
 		acpi_irq_handled++;
 		return IRQ_HANDLED;
-	} else
+	} else {
+		acpi_irq_not_handled++;
 		return IRQ_NONE;
+	}
 }
 
 acpi_status
@@ -1063,9 +1072,9 @@ __setup("acpi_wake_gpes_always_on", acpi
  * in arbitrary AML code and can interfere with legacy drivers.
  * acpi_enforce_resources= can be set to:
  *
- *   - strict           (2)
+ *   - strict (default) (2)
  *     -> further driver trying to access the resources will not load
- *   - lax (default)    (1)
+ *   - lax              (1)
  *     -> further driver trying to access the resources will load, but you
  *     get a system message that something might go wrong...
  *
@@ -1077,7 +1086,7 @@ __setup("acpi_wake_gpes_always_on", acpi
 #define ENFORCE_RESOURCES_LAX    1
 #define ENFORCE_RESOURCES_NO     0
 
-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
+static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
 
 static int __init acpi_enforce_resources_setup(char *str)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/pci_bind.c linux-libre-2.6.30-gnu1/drivers/acpi/pci_bind.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/pci_bind.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/pci_bind.c	2009-06-09 23:05:27.000000000 -0400
@@ -116,9 +116,6 @@ int acpi_pci_bind(struct acpi_device *de
 	struct acpi_pci_data *pdata;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	acpi_handle handle;
-	struct pci_dev *dev;
-	struct pci_bus *bus;
-
 
 	if (!device || !device->parent)
 		return -EINVAL;
@@ -176,20 +173,9 @@ int acpi_pci_bind(struct acpi_device *de
 	 * Locate matching device in PCI namespace.  If it doesn't exist
 	 * this typically means that the device isn't currently inserted
 	 * (e.g. docking station, port replicator, etc.).
-	 * We cannot simply search the global pci device list, since
-	 * PCI devices are added to the global pci list when the root
-	 * bridge start ops are run, which may not have happened yet.
 	 */
-	bus = pci_find_bus(data->id.segment, data->id.bus);
-	if (bus) {
-		list_for_each_entry(dev, &bus->devices, bus_list) {
-			if (dev->devfn == PCI_DEVFN(data->id.device,
-						    data->id.function)) {
-				data->dev = dev;
-				break;
-			}
-		}
-	}
+	data->dev = pci_get_slot(pdata->bus,
+				PCI_DEVFN(data->id.device, data->id.function));
 	if (!data->dev) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Device %04x:%02x:%02x.%d not present in PCI namespace\n",
@@ -259,9 +245,10 @@ int acpi_pci_bind(struct acpi_device *de
 
       end:
 	kfree(buffer.pointer);
-	if (result)
+	if (result) {
+		pci_dev_put(data->dev);
 		kfree(data);
-
+	}
 	return result;
 }
 
@@ -303,6 +290,7 @@ static int acpi_pci_unbind(struct acpi_d
 	if (data->dev->subordinate) {
 		acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
 	}
+	pci_dev_put(data->dev);
 	kfree(data);
 
       end:
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/pci_irq.c linux-libre-2.6.30-gnu1/drivers/acpi/pci_irq.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/pci_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/pci_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ static struct acpi_prt_entry *acpi_pci_i
 }
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
-static struct dmi_system_id medion_md9580[] = {
+static const struct dmi_system_id medion_md9580[] = {
 	{
 		.ident = "Medion MD9580-F laptop",
 		.matches = {
@@ -98,7 +98,7 @@ static struct dmi_system_id medion_md958
 };
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
-static struct dmi_system_id dell_optiplex[] = {
+static const struct dmi_system_id dell_optiplex[] = {
 	{
 		.ident = "Dell Optiplex GX1",
 		.matches = {
@@ -110,7 +110,7 @@ static struct dmi_system_id dell_optiple
 };
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
-static struct dmi_system_id hp_t5710[] = {
+static const struct dmi_system_id hp_t5710[] = {
 	{
 		.ident = "HP t5710",
 		.matches = {
@@ -123,13 +123,13 @@ static struct dmi_system_id hp_t5710[] =
 };
 
 struct prt_quirk {
-	struct dmi_system_id	*system;
+	const struct dmi_system_id *system;
 	unsigned int		segment;
 	unsigned int		bus;
 	unsigned int		device;
 	unsigned char		pin;
-	char			*source;	/* according to BIOS */
-	char			*actual_source;
+	const char		*source;	/* according to BIOS */
+	const char		*actual_source;
 };
 
 #define PCI_INTX_PIN(c)		(c - 'A' + 1)
@@ -139,7 +139,7 @@ struct prt_quirk {
  * interrupt at the listed segment/bus/device/pin is connected to the first
  * link device, but it is actually connected to the second.
  */
-static struct prt_quirk prt_quirks[] = {
+static const struct prt_quirk prt_quirks[] = {
 	{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
 		"\\_SB_.PCI0.ISA_.LNKA",
 		"\\_SB_.PCI0.ISA_.LNKB"},
@@ -155,7 +155,7 @@ static void do_prt_fixups(struct acpi_pr
 			  struct acpi_pci_routing_table *prt)
 {
 	int i;
-	struct prt_quirk *quirk;
+	const struct prt_quirk *quirk;
 
 	for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
 		quirk = &prt_quirks[i];
@@ -319,7 +319,7 @@ static struct acpi_prt_entry *acpi_pci_i
 	 */
 	bridge = dev->bus->self;
 	while (bridge) {
-		pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+		pin = pci_swizzle_interrupt_pin(dev, pin);
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
 			/* PC card has the same IRQ as its cardbridge */
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/pci_link.c linux-libre-2.6.30-gnu1/drivers/acpi/pci_link.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/pci_link.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/pci_link.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,13 +43,14 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define _COMPONENT		ACPI_PCI_COMPONENT
+#define _COMPONENT			ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
 #define ACPI_PCI_LINK_DEVICE_NAME	"PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO		"info"
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE	16
+
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_
 	.ops = {
 		.add = acpi_pci_link_add,
 		.remove = acpi_pci_link_remove,
-		},
+	},
 };
 
 /*
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_
 struct acpi_pci_link_irq {
 	u8 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
-	u8 polarity;	/* All IRQs */
+	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
 	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq {
 };
 
 struct acpi_pci_link {
-	struct list_head node;
-	struct acpi_device *device;
-	struct acpi_pci_link_irq irq;
-	int refcnt;
+	struct list_head		list;
+	struct acpi_device		*device;
+	struct acpi_pci_link_irq	irq;
+	int				refcnt;
 };
 
-static struct {
-	int count;
-	struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
 static DEFINE_MUTEX(acpi_link_lock);
 
 /* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock);
 /*
  * set context (link) possible list from resource list
  */
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+						void *context)
 {
 	struct acpi_pci_link *link = context;
-	u32 i = 0;
-
+	u32 i;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(st
 {
 	acpi_status status;
 
-
-	if (!link)
-		return -EINVAL;
-
 	status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
 				     acpi_pci_link_check_possible, link);
 	if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(st
 	return 0;
 }
 
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+					       void *context)
 {
-	int *irq = (int *)context;
-
+	int *irq = context;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_
 static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	int irq = 0;
 
-	if (!link)
-		return -EINVAL;
-
 	link->irq.active = 0;
 
 	/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(str
 
 static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
+	int result;
+	acpi_status status;
 	struct {
 		struct acpi_resource res;
 		struct acpi_resource end;
 	} *resource;
 	struct acpi_buffer buffer = { 0, NULL };
 
-
-	if (!link || !irq)
+	if (!irq)
 		return -EINVAL;
 
 	resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQ
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ9  PCI, often acpi */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ10 PCI */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ11 PCI */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ12 mouse */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ13 fpe, sometimes */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ14 ide0 */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ15 ide1 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ12 mouse */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ13 fpe, sometimes */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ14 ide0 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ15 ide1 */
 	/* >IRQ15 */
 };
 
 int __init acpi_irq_penalty_init(void)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
-
+	struct acpi_pci_link *link;
+	int i;
 
 	/*
 	 * Update penalties to facilitate IRQ balancing.
 	 */
-	list_for_each(node, &acpi_link.entries) {
-
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 
 		/*
 		 * reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void)
 	}
 	/* Add a penalty for the SCI */
 	acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
 	return 0;
 }
 
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct
 	int irq;
 	int i;
 
-
 	if (link->irq.initialized) {
 		if (link->refcnt == 0)
 			/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct
 	/*
 	 * if active found, use it; else pick entry from end of possible list.
 	 */
-	if (link->irq.active) {
+	if (link->irq.active)
 		irq = link->irq.active;
-	} else {
+	else
 		irq = link->irq.possible[link->irq.possible_count - 1];
-	}
 
 	if (acpi_irq_balance || !link->irq.active) {
 		/*
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct
 	}
 
 	link->irq.initialized = 1;
-
 	return 0;
 }
 
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct
  * success: return IRQ >= 0
  * failure: return -1
  */
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
-			   int index,
-			   int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+			       int *polarity, char **name)
 {
-	int result = 0;
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
-
+	int result;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle h
  */
 int acpi_pci_link_free_irq(acpi_handle handle)
 {
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 	acpi_status result;
 
-
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
 		printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle h
 			  "Link %s is dereferenced\n",
 			  acpi_device_bid(link->device)));
 
-	if (link->refcnt == 0) {
+	if (link->refcnt == 0)
 		acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
-	}
+
 	mutex_unlock(&acpi_link_lock);
 	return (link->irq.active);
 }
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle h
 
 static int acpi_pci_link_add(struct acpi_device *device)
 {
-	int result = 0;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
+	int result;
+	struct acpi_pci_link *link;
+	int i;
 	int found = 0;
 
-
-	if (!device)
-		return -EINVAL;
-
 	link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi
 
 	printk("\n");
 
-	/* TBD: Acquire/release lock */
-	list_add_tail(&link->node, &acpi_link.entries);
-	acpi_link.count++;
+	list_add_tail(&link->list, &acpi_link_list);
 
       end:
 	/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi
 
 static int acpi_pci_link_resume(struct acpi_pci_link *link)
 {
-
 	if (link->refcnt && link->irq.active && link->irq.initialized)
 		return (acpi_pci_link_set(link, link->irq.active));
-	else
-		return 0;
+
+	return 0;
 }
 
 static int irqrouter_resume(struct sys_device *dev)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_pci_link *link;
 
-	list_for_each(node, &acpi_link.entries) {
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 		acpi_pci_link_resume(link);
 	}
 	return 0;
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_d
 
 static int acpi_pci_link_remove(struct acpi_device *device, int type)
 {
-	struct acpi_pci_link *link = NULL;
-
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	struct acpi_pci_link *link;
 
 	link = acpi_driver_data(device);
 
 	mutex_lock(&acpi_link_lock);
-	list_del(&link->node);
+	list_del(&link->list);
 	mutex_unlock(&acpi_link_lock);
 
 	kfree(link);
-
 	return 0;
 }
 
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(v
 {
 	int error;
 
-
 	if (acpi_disabled || acpi_noirq)
 		return 0;
 
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(voi
 			acpi_irq_balance = 0;
 	}
 
-	acpi_link.count = 0;
-	INIT_LIST_HEAD(&acpi_link.entries);
-
 	if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
 		return -ENODEV;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/pci_root.c linux-libre-2.6.30-gnu1/drivers/acpi/pci_root.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/pci_root.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/pci_root.c	2009-06-09 23:05:27.000000000 -0400
@@ -66,11 +66,18 @@ struct acpi_pci_root {
 	struct acpi_device * device;
 	struct acpi_pci_id id;
 	struct pci_bus *bus;
+
+	u32 osc_support_set;	/* _OSC state of support bits */
+	u32 osc_control_set;	/* _OSC state of control bits */
+	u32 osc_control_qry;	/* the latest _OSC query result */
+
+	u32 osc_queried:1;	/* has _OSC control been queried? */
 };
 
 static LIST_HEAD(acpi_pci_roots);
 
 static struct acpi_pci_driver *sub_driver;
+static DEFINE_MUTEX(osc_lock);
 
 int acpi_pci_register_driver(struct acpi_pci_driver *driver)
 {
@@ -185,6 +192,175 @@ 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 acpi_status acpi_pci_run_osc(acpi_handle handle,
+				    const u32 *capbuf, u32 *retval)
+{
+	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;
+	}
+out_success:
+	*retval = *((u32 *)(out_obj->buffer.pointer + 8));
+	status = AE_OK;
+
+out_kfree:
+	kfree(output.pointer);
+	return status;
+}
+
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+{
+	acpi_status status;
+	u32 support_set, result, capbuf[3];
+
+	/* do _OSC query for all possible controls */
+	support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS);
+	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+	capbuf[OSC_SUPPORT_TYPE] = support_set;
+	capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+
+	status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
+	if (ACPI_SUCCESS(status)) {
+		root->osc_support_set = support_set;
+		root->osc_control_qry = result;
+		root->osc_queried = 1;
+	}
+	return status;
+}
+
+static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
+{
+	acpi_status status;
+	acpi_handle tmp;
+
+	status = acpi_get_handle(root->device->handle, "_OSC", &tmp);
+	if (ACPI_FAILURE(status))
+		return status;
+	mutex_lock(&osc_lock);
+	status = acpi_pci_query_osc(root, flags);
+	mutex_unlock(&osc_lock);
+	return status;
+}
+
+static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
+{
+	struct acpi_pci_root *root;
+	list_for_each_entry(root, &acpi_pci_roots, node) {
+		if (root->device->handle == handle)
+			return root;
+	}
+	return NULL;
+}
+
+/**
+ * acpi_pci_osc_control_set - commit requested control to Firmware
+ * @handle: acpi_handle for the target ACPI object
+ * @flags: driver's requested control bits
+ *
+ * Attempt to take control from Firmware on requested control bits.
+ **/
+acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
+{
+	acpi_status status;
+	u32 control_req, result, capbuf[3];
+	acpi_handle tmp;
+	struct acpi_pci_root *root;
+
+	status = acpi_get_handle(handle, "_OSC", &tmp);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	control_req = (flags & OSC_CONTROL_MASKS);
+	if (!control_req)
+		return AE_TYPE;
+
+	root = acpi_pci_find_root(handle);
+	if (!root)
+		return AE_NOT_EXIST;
+
+	mutex_lock(&osc_lock);
+	/* No need to evaluate _OSC if the control was already granted. */
+	if ((root->osc_control_set & control_req) == control_req)
+		goto out;
+
+	/* Need to query controls first before requesting them */
+	if (!root->osc_queried) {
+		status = acpi_pci_query_osc(root, root->osc_support_set);
+		if (ACPI_FAILURE(status))
+			goto out;
+	}
+	if ((root->osc_control_qry & control_req) != control_req) {
+		printk(KERN_DEBUG
+		       "Firmware did not grant requested _OSC control\n");
+		status = AE_SUPPORT;
+		goto out;
+	}
+
+	capbuf[OSC_QUERY_TYPE] = 0;
+	capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
+	capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
+	status = acpi_pci_run_osc(handle, capbuf, &result);
+	if (ACPI_SUCCESS(status))
+		root->osc_control_set = result;
+out:
+	mutex_unlock(&osc_lock);
+	return status;
+}
+EXPORT_SYMBOL(acpi_pci_osc_control_set);
+
 static int __devinit acpi_pci_root_add(struct acpi_device *device)
 {
 	int result = 0;
@@ -217,7 +393,7 @@ static int __devinit acpi_pci_root_add(s
 	 * PCI domains, so we indicate this in _OSC support capabilities.
 	 */
 	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
-	pci_acpi_osc_support(device->handle, flags);
+	acpi_pci_osc_support(root, flags);
 
 	/* 
 	 * Segment
@@ -353,7 +529,7 @@ static int __devinit acpi_pci_root_add(s
 	if (pci_msi_enabled())
 		flags |= OSC_MSI_SUPPORT;
 	if (flags != base_flags)
-		pci_acpi_osc_support(device->handle, flags);
+		acpi_pci_osc_support(root, flags);
 
       end:
 	if (result) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/pci_slot.c linux-libre-2.6.30-gnu1/drivers/acpi/pci_slot.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/pci_slot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/pci_slot.c	2009-06-09 23:05:27.000000000 -0400
@@ -164,6 +164,8 @@ register_slot(acpi_handle handle, u32 lv
 	list_add(&slot->list, &slot_list);
 	mutex_unlock(&slot_list_lock);
 
+	get_device(&pci_bus->dev);
+
 	dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n",
 		pci_slot, pci_bus->number, device, name);
 
@@ -310,12 +312,15 @@ static void
 acpi_pci_slot_remove(acpi_handle handle)
 {
 	struct acpi_pci_slot *slot, *tmp;
+	struct pci_bus *pbus;
 
 	mutex_lock(&slot_list_lock);
 	list_for_each_entry_safe(slot, tmp, &slot_list, list) {
 		if (slot->root_handle == handle) {
 			list_del(&slot->list);
+			pbus = slot->pci_slot->bus;
 			pci_destroy_slot(slot->pci_slot);
+			put_device(&pbus->dev);
 			kfree(slot);
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/power.c linux-libre-2.6.30-gnu1/drivers/acpi/power.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/power.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/power.c	2009-06-09 23:05:27.000000000 -0400
@@ -54,10 +54,6 @@ ACPI_MODULE_NAME("power");
 #define ACPI_POWER_RESOURCE_STATE_ON	0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
 int acpi_power_nocheck;
 module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
 
@@ -773,14 +769,10 @@ static int acpi_power_resume(struct acpi
 	return 0;
 }
 
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
 {
 	int result = 0;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	INIT_LIST_HEAD(&acpi_power_resource_list);
 
 	acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +787,3 @@ static int __init acpi_power_init(void)
 
 	return 0;
 }
-
-subsys_initcall(acpi_power_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/proc.c linux-libre-2.6.30-gnu1/drivers/acpi/proc.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -343,9 +343,6 @@ acpi_system_write_alarm(struct file *fil
 }
 #endif				/* HAVE_ACPI_LEGACY_ALARM */
 
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
 static int
 acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 {
@@ -353,7 +350,7 @@ acpi_system_wakeup_device_seq_show(struc
 
 	seq_printf(seq, "Device\tS-state\t  Status   Sysfs node\n");
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
@@ -361,7 +358,6 @@ acpi_system_wakeup_device_seq_show(struc
 
 		if (!dev->wakeup.flags.valid)
 			continue;
-		spin_unlock(&acpi_device_lock);
 
 		ldev = acpi_get_physical_device(dev->handle);
 		seq_printf(seq, "%s\t  S%d\t%c%-8s  ",
@@ -376,9 +372,8 @@ acpi_system_wakeup_device_seq_show(struc
 		seq_printf(seq, "\n");
 		put_device(ldev);
 
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return 0;
 }
 
@@ -409,7 +404,7 @@ acpi_system_write_wakeup_device(struct f
 	strbuf[len] = '\0';
 	sscanf(strbuf, "%s", str);
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
@@ -446,7 +441,7 @@ acpi_system_write_wakeup_device(struct f
 			}
 		}
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return count;
 }
 
@@ -496,11 +491,8 @@ static u32 rtc_handler(void *context)
 }
 #endif				/* HAVE_ACPI_LEGACY_ALARM */
 
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
 {
-	if (acpi_disabled)
-		return 0;
-
 #ifdef	CONFIG_ACPI_PROCFS
 	/* 'sleep' [R/W] */
 	proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +519,3 @@ static int __init acpi_sleep_proc_init(v
 
 	return 0;
 }
-
-late_initcall(acpi_sleep_proc_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/processor_core.c linux-libre-2.6.30-gnu1/drivers/acpi/processor_core.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/processor_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/processor_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,7 +82,7 @@ static int acpi_processor_add(struct acp
 static int acpi_processor_start(struct acpi_device *device);
 static int acpi_processor_remove(struct acpi_device *device, int type);
 static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
 
@@ -104,6 +104,7 @@ static struct acpi_driver acpi_processor
 		.start = acpi_processor_start,
 		.suspend = acpi_processor_suspend,
 		.resume = acpi_processor_resume,
+		.notify = acpi_processor_notify,
 		},
 };
 
@@ -359,7 +360,6 @@ static int acpi_processor_add_fs(struct
 		if (!acpi_device_dir(device))
 			return -ENODEV;
 	}
-	acpi_device_dir(device)->owner = THIS_MODULE;
 
 	/* 'info' [R] */
 	entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
@@ -427,6 +427,29 @@ static int map_lapic_id(struct acpi_subt
 	return 0;
 }
 
+static int map_x2apic_id(struct acpi_subtable_header *entry,
+			 int device_declaration, u32 acpi_id, int *apic_id)
+{
+	struct acpi_madt_local_x2apic *apic =
+		(struct acpi_madt_local_x2apic *)entry;
+	u32 tmp = apic->local_apic_id;
+
+	/* Only check enabled APICs*/
+	if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
+		return 0;
+
+	/* Device statement declaration type */
+	if (device_declaration) {
+		if (apic->uid == acpi_id)
+			goto found;
+	}
+
+	return 0;
+found:
+	*apic_id = tmp;
+	return 1;
+}
+
 static int map_lsapic_id(struct acpi_subtable_header *entry,
 		int device_declaration, u32 acpi_id, int *apic_id)
 {
@@ -476,6 +499,9 @@ static int map_madt_entry(int type, u32
 		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
 			if (map_lapic_id(header, acpi_id, &apic_id))
 				break;
+		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+			if (map_x2apic_id(header, type, acpi_id, &apic_id))
+				break;
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 			if (map_lsapic_id(header, type, acpi_id, &apic_id))
 				break;
@@ -666,7 +692,6 @@ static DEFINE_PER_CPU(void *, processor_
 static int __cpuinit acpi_processor_start(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
 	struct acpi_processor *pr;
 	struct sys_device *sysdev;
 
@@ -703,9 +728,6 @@ static int __cpuinit acpi_processor_star
 	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
 		return -EFAULT;
 
-	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
-					     acpi_processor_notify, pr);
-
 	/* _PDC call should be done before doing anything else (if reqd.). */
 	arch_acpi_processor_init_pdc(pr);
 	acpi_processor_set_pdc(pr);
@@ -751,18 +773,14 @@ static int __cpuinit acpi_processor_star
 	return result;
 }
 
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_processor *pr = data;
-	struct acpi_device *device = NULL;
+	struct acpi_processor *pr = acpi_driver_data(device);
 	int saved;
 
 	if (!pr)
 		return;
 
-	if (acpi_bus_get_device(pr->handle, &device))
-		return;
-
 	switch (event) {
 	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
 		saved = pr->performance_platform_limit;
@@ -826,7 +844,7 @@ static int acpi_processor_add(struct acp
 	if (!pr)
 		return -ENOMEM;
 
-	if (!alloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
+	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
 		kfree(pr);
 		return -ENOMEM;
 	}
@@ -841,7 +859,6 @@ static int acpi_processor_add(struct acp
 
 static int acpi_processor_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = AE_OK;
 	struct acpi_processor *pr = NULL;
 
 
@@ -860,9 +877,6 @@ static int acpi_processor_remove(struct
 
 	acpi_processor_power_exit(pr, device);
 
-	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
-					    acpi_processor_notify);
-
 	sysfs_remove_link(&device->dev.kobj, "sysdev");
 
 	acpi_processor_remove_fs(device);
@@ -1137,7 +1151,6 @@ static int __init acpi_processor_init(vo
 	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 	if (!acpi_processor_dir)
 		return -ENOMEM;
-	acpi_processor_dir->owner = THIS_MODULE;
 
 	/*
 	 * Check whether the system is DMI table. If yes, OSPM
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/processor_idle.c linux-libre-2.6.30-gnu1/drivers/acpi/processor_idle.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/processor_idle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/processor_idle.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,6 @@
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER	"power"
-#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)
 #define C2_OVERHEAD			1	/* 1us */
 #define C3_OVERHEAD			1	/* 1us */
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);
 static unsigned int latency_factor __read_mostly = 2;
 module_param(latency_factor, uint, 0644);
 
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+	return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
  * For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct d
 /* Actually this shouldn't be __cpuinitdata, would be better to fix the
    callers to only run once -AK */
 static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
-	{ set_max_cstate, "Medion 41700", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
 	{ set_max_cstate, "Clevo 5600D", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdat
 	{},
 };
 
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return (t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return PM_TIMER_TICKS_TO_US(t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
 
 /*
  * Callers should disable interrupts before the call and enable
@@ -212,6 +145,12 @@ static void acpi_timer_check_state(int s
 	struct acpi_processor_power *pwr = &pr->power;
 	u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
 
+	if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_AMDC1E))
+		type = ACPI_STATE_C1;
+
 	/*
 	 * Check, if one of the previous states already marked the lapic
 	 * unstable
@@ -266,21 +205,44 @@ static void acpi_state_timer_broadcast(s
  * Suspend / resume control
  */
 static int acpi_idle_suspend;
+static u32 saved_bm_rld;
+
+static void acpi_idle_bm_rld_save(void)
+{
+	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
+}
+static void acpi_idle_bm_rld_restore(void)
+{
+	u32 resumed_bm_rld;
+
+	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
+
+	if (resumed_bm_rld != saved_bm_rld)
+		acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
+}
 
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
 {
+	if (acpi_idle_suspend == 1)
+		return 0;
+
+	acpi_idle_bm_rld_save();
 	acpi_idle_suspend = 1;
 	return 0;
 }
 
 int acpi_processor_resume(struct acpi_device * device)
 {
+	if (acpi_idle_suspend == 0)
+		return 0;
+
+	acpi_idle_bm_rld_restore();
 	acpi_idle_suspend = 0;
 	return 0;
 }
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-static int tsc_halts_in_c(int state)
+static void tsc_check_state(int state)
 {
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
@@ -290,13 +252,17 @@ static int tsc_halts_in_c(int state)
 		 * C/P/S0/S1 states when this bit is set.
 		 */
 		if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
-			return 0;
+			return;
 
 		/*FALL THROUGH*/
 	default:
-		return state > ACPI_STATE_C1;
+		/* TSC could halt in idle, so notify users */
+		if (state > ACPI_STATE_C1)
+			mark_tsc_unstable("TSC halts in idle");
 	}
 }
+#else
+static void tsc_check_state(int state) { return; }
 #endif
 
 static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
@@ -630,7 +596,7 @@ static void acpi_processor_power_verify_
 	 * In either case, the proper way to
 	 * handle BM_RLD is to set it and leave it set.
 	 */
-	acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+	acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 
 	return;
 }
@@ -642,12 +608,13 @@ static int acpi_processor_power_verify(s
 
 	pr->power.timer_broadcast_on_state = INT_MAX;
 
-	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
 		struct acpi_processor_cx *cx = &pr->power.states[i];
 
 		switch (cx->type) {
 		case ACPI_STATE_C1:
 			cx->valid = 1;
+			acpi_timer_check_state(i, pr, cx);
 			break;
 
 		case ACPI_STATE_C2:
@@ -662,6 +629,8 @@ static int acpi_processor_power_verify(s
 				acpi_timer_check_state(i, pr, cx);
 			break;
 		}
+		if (cx->valid)
+			tsc_check_state(cx->type);
 
 		if (cx->valid)
 			working++;
@@ -721,11 +690,9 @@ static int acpi_processor_power_seq_show
 
 	seq_printf(seq, "active state:            C%zd\n"
 		   "max_cstate:              C%d\n"
-		   "bus master activity:     %08x\n"
 		   "maximum allowed latency: %d usec\n",
 		   pr->power.state ? pr->power.state - pr->power.states : 0,
-		   max_cstate, (unsigned)pr->power.bm_activity,
-		   pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
+		   max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
 
 	seq_puts(seq, "states:\n");
 
@@ -800,9 +767,9 @@ static int acpi_idle_bm_check(void)
 {
 	u32 bm_status = 0;
 
-	acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 	if (bm_status)
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+		acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 	/*
 	 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
 	 * the true state of bus mastering activity; forcing us to
@@ -853,7 +820,8 @@ static inline void acpi_idle_do_entry(st
 static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 			      struct cpuidle_state *state)
 {
-	u32 t1, t2;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
 
@@ -866,19 +834,22 @@ static int acpi_idle_enter_c1(struct cpu
 
 	/* Do not access any ACPI IO ports in suspend path */
 	if (acpi_idle_suspend) {
-		acpi_safe_halt();
 		local_irq_enable();
+		cpu_relax();
 		return 0;
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	acpi_state_timer_broadcast(pr, cx, 1);
+	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	local_irq_enable();
 	cx->usage++;
+	acpi_state_timer_broadcast(pr, cx, 0);
 
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 /**
@@ -891,8 +862,9 @@ static int acpi_idle_enter_simple(struct
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
 
 	pr = __get_cpu_var(processors);
 
@@ -925,18 +897,14 @@ static int acpi_idle_enter_simple(struct
 	if (cx->type == ACPI_STATE_C3)
 		ACPI_FLUSH_CPU_CACHE();
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	/* Tell the scheduler that we are going deep-idle: */
 	sched_clock_idle_sleep_event();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-	/* TSC could halt in idle, so notify users */
-	if (tsc_halts_in_c(cx->type))
-		mark_tsc_unstable("TSC halts in idle");;
-#endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +916,7 @@ static int acpi_idle_enter_simple(struct
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 static int c3_cpu_count;
@@ -966,8 +934,10 @@ static int acpi_idle_enter_bm(struct cpu
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
+
 
 	pr = __get_cpu_var(processors);
 
@@ -1013,6 +983,7 @@ static int acpi_idle_enter_bm(struct cpu
 	 */
 	acpi_state_timer_broadcast(pr, cx, 1);
 
+	kt1 = ktime_get_real();
 	/*
 	 * disable bus master
 	 * bm_check implies we need ARB_DIS
@@ -1028,30 +999,25 @@ static int acpi_idle_enter_bm(struct cpu
 		c3_cpu_count++;
 		/* Disable bus master arbitration when all CPUs are in C3 */
 		if (c3_cpu_count == num_online_cpus())
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+			acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 		spin_unlock(&c3_lock);
 	} else if (!pr->flags.bm_check) {
 		ACPI_FLUSH_CPU_CACHE();
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
 	/* Re-enable bus master arbitration */
 	if (pr->flags.bm_check && pr->flags.bm_control) {
 		spin_lock(&c3_lock);
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 		c3_cpu_count--;
 		spin_unlock(&c3_lock);
 	}
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-	/* TSC could halt in idle, so notify users */
-	if (tsc_halts_in_c(ACPI_STATE_C3))
-		mark_tsc_unstable("TSC halts in idle");
-#endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
@@ -1062,7 +1028,7 @@ static int acpi_idle_enter_bm(struct cpu
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 struct cpuidle_driver acpi_idle_driver = {
@@ -1094,6 +1060,9 @@ static int acpi_processor_setup_cpuidle(
 		dev->states[i].desc[0] = '\0';
 	}
 
+	if (max_cstate == 0)
+		max_cstate = 1;
+
 	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
 		cx = &pr->power.states[i];
 		state = &dev->states[count];
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/processor_perflib.c linux-libre-2.6.30-gnu1/drivers/acpi/processor_perflib.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/processor_perflib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/processor_perflib.c	2009-06-09 23:05:27.000000000 -0400
@@ -309,9 +309,15 @@ static int acpi_processor_get_performanc
 				  (u32) px->bus_master_latency,
 				  (u32) px->control, (u32) px->status));
 
-		if (!px->core_frequency) {
-			printk(KERN_ERR PREFIX
-				    "Invalid _PSS data: freq is zero\n");
+		/*
+ 		 * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
+		 */
+		if (!px->core_frequency ||
+		    ((u32)(px->core_frequency * 1000) !=
+		     (px->core_frequency * 1000))) {
+			printk(KERN_ERR FW_BUG PREFIX
+			       "Invalid BIOS _PSS frequency: 0x%llx MHz\n",
+			       px->core_frequency);
 			result = -EFAULT;
 			kfree(pr->performance->states);
 			goto end;
@@ -479,6 +485,13 @@ static int acpi_processor_get_psd(struct
 		goto end;
 	}
 
+	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+		printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+		result = -EFAULT;
+		goto end;
+	}
 end:
 	kfree(buffer.pointer);
 	return result;
@@ -501,9 +514,10 @@ int acpi_processor_preregister_performan
 
 	mutex_lock(&performance_mutex);
 
-	retval = 0;
-
-	/* Call _PSD for all CPUs */
+	/*
+	 * Check if another driver has already registered, and abort before
+	 * changing pr->performance if it has. Check input data as well.
+	 */
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
 		if (!pr) {
@@ -513,15 +527,22 @@ int acpi_processor_preregister_performan
 
 		if (pr->performance) {
 			retval = -EBUSY;
-			continue;
+			goto err_out;
 		}
 
-		if (!performance || !percpu_ptr(performance, i)) {
+		if (!performance || !per_cpu_ptr(performance, i)) {
 			retval = -EINVAL;
-			continue;
+			goto err_out;
 		}
+	}
 
-		pr->performance = percpu_ptr(performance, i);
+	/* Call _PSD for all CPUs */
+	for_each_possible_cpu(i) {
+		pr = per_cpu(processors, i);
+		if (!pr)
+			continue;
+
+		pr->performance = per_cpu_ptr(performance, i);
 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
 		if (acpi_processor_get_psd(pr)) {
 			retval = -EINVAL;
@@ -535,26 +556,6 @@ int acpi_processor_preregister_performan
 	 * Now that we have _PSD data from all CPUs, lets setup P-state 
 	 * domain info.
 	 */
-	for_each_possible_cpu(i) {
-		pr = per_cpu(processors, i);
-		if (!pr)
-			continue;
-
-		/* Basic validity check for domain info */
-		pdomain = &(pr->performance->domain_info);
-		if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
-		    (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-		if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-	}
-
 	cpumask_clear(covered_cpus);
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
@@ -643,6 +644,7 @@ err_ret:
 		pr->performance = NULL; /* Will be set for real in register */
 	}
 
+err_out:
 	mutex_unlock(&performance_mutex);
 	free_cpumask_var(covered_cpus);
 	return retval;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/processor_thermal.c linux-libre-2.6.30-gnu1/drivers/acpi/processor_thermal.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/processor_thermal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/processor_thermal.c	2009-06-09 23:05:27.000000000 -0400
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(stru
 	return max_state;
 }
 static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+			unsigned long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_c
 	if (!device || !pr)
 		return -EINVAL;
 
-	return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+	*state = acpi_processor_max_state(pr);
+	return 0;
 }
 
 static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long *cur_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
-	int cur_state;
 
 	if (!device || !pr)
 		return -EINVAL;
 
-	cur_state = cpufreq_get_cur_state(pr->id);
+	*cur_state = cpufreq_get_cur_state(pr->id);
 	if (pr->flags.throttling)
-		cur_state += pr->throttling.state;
-
-	return sprintf(buf, "%d\n", cur_state);
+		*cur_state += pr->throttling.state;
+	return 0;
 }
 
 static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
@@ -507,7 +509,7 @@ static ssize_t acpi_processor_write_limi
 	return count;
 }
 
-struct file_operations acpi_processor_limit_fops = {
+const struct file_operations acpi_processor_limit_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_processor_limit_open_fs,
 	.read = seq_read,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/processor_throttling.c linux-libre-2.6.30-gnu1/drivers/acpi/processor_throttling.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/processor_throttling.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/processor_throttling.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,6 +45,14 @@
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_throttling");
 
+/* ignore_tpc:
+ *  0 -> acpi processor driver doesn't ignore _TPC values
+ *  1 -> acpi processor driver ignores _TPC values
+ */
+static int ignore_tpc;
+module_param(ignore_tpc, int, 0644);
+MODULE_PARM_DESC(ignore_tpc, "Disable broken BIOS _TPC throttling support");
+
 struct throttling_tstate {
 	unsigned int cpu;		/* cpu nr */
 	int target_state;		/* target T-state */
@@ -283,6 +291,10 @@ static int acpi_processor_get_platform_l
 
 	if (!pr)
 		return -EINVAL;
+
+	if (ignore_tpc)
+		goto end;
+
 	status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
 	if (ACPI_FAILURE(status)) {
 		if (status != AE_NOT_FOUND) {
@@ -290,6 +302,8 @@ static int acpi_processor_get_platform_l
 		}
 		return -ENODEV;
 	}
+
+end:
 	pr->throttling_platform_limit = (int)tpc;
 	return 0;
 }
@@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(st
 	struct acpi_processor_limit *limit;
 	int target_state;
 
+	if (ignore_tpc)
+		return 0;
+
 	result = acpi_processor_get_platform_limit(pr);
 	if (result) {
 		/* Throttling Limit is unsupported */
@@ -783,11 +800,9 @@ static int acpi_get_throttling_state(str
 		    (struct acpi_processor_tx_tss *)&(pr->throttling.
 						      states_tss[i]);
 		if (tx->control == value)
-			break;
+			return i;
 	}
-	if (i > pr->throttling.state_count)
-		i = -1;
-	return i;
+	return -1;
 }
 
 static int acpi_get_throttling_value(struct acpi_processor *pr,
@@ -823,6 +838,14 @@ static int acpi_processor_get_throttling
 	ret = acpi_read_throttling_status(pr, &value);
 	if (ret >= 0) {
 		state = acpi_get_throttling_state(pr, value);
+		if (state == -1) {
+			ACPI_WARNING((AE_INFO,
+				"Invalid throttling state, reset"));
+			state = 0;
+			ret = acpi_processor_set_throttling(pr, state);
+			if (ret)
+				return ret;
+		}
 		pr->throttling.state = state;
 	}
 
@@ -1291,7 +1314,7 @@ static ssize_t acpi_processor_write_thro
 	return count;
 }
 
-struct file_operations acpi_processor_throttling_fops = {
+const struct file_operations acpi_processor_throttling_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_processor_throttling_open_fs,
 	.read = seq_read,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/sbs.c linux-libre-2.6.30-gnu1/drivers/acpi/sbs.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/sbs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/sbs.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,8 +102,8 @@ struct acpi_battery {
 	u16 cycle_count;
 	u16 temp_now;
 	u16 voltage_now;
-	s16 current_now;
-	s16 current_avg;
+	s16 rate_now;
+	s16 rate_avg;
 	u16 capacity_now;
 	u16 state_of_charge;
 	u16 state;
@@ -202,9 +202,9 @@ static int acpi_sbs_battery_get_property
 		return -ENODEV;
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		if (battery->current_now < 0)
+		if (battery->rate_now < 0)
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-		else if (battery->current_now > 0)
+		else if (battery->rate_now > 0)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
 		else
 			val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@ static int acpi_sbs_battery_get_property
 				acpi_battery_vscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = abs(battery->current_now) *
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = abs(battery->rate_now) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_AVG:
-		val->intval = abs(battery->current_avg) *
+	case POWER_SUPPLY_PROP_POWER_AVG:
+		val->intval = abs(battery->rate_avg) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@ static enum power_supply_property sbs_en
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_POWER_NOW,
+	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@ static enum power_supply_property sbs_en
 	POWER_SUPPLY_PROP_MODEL_NAME,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
+
 #endif
 
 /* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@ static struct acpi_battery_reader info_r
 static struct acpi_battery_reader state_readers[] = {
 	{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
 	{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
-	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
-	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
 	{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
 	{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
 	{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -479,16 +484,15 @@ static int
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
 		struct proc_dir_entry *parent_dir,
 		char *dir_name,
-		struct file_operations *info_fops,
-		struct file_operations *state_fops,
-		struct file_operations *alarm_fops, void *data)
+		const struct file_operations *info_fops,
+		const struct file_operations *state_fops,
+		const struct file_operations *alarm_fops, void *data)
 {
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
 		if (!*dir) {
 			return -ENODEV;
 		}
-		(*dir)->owner = THIS_MODULE;
 	}
 
 	/* 'info' [R] */
@@ -589,9 +593,9 @@ static int acpi_battery_read_state(struc
 	seq_printf(seq, "capacity state:          %s\n",
 		   (battery->state & 0x0010) ? "critical" : "ok");
 	seq_printf(seq, "charging state:          %s\n",
-		   (battery->current_now < 0) ? "discharging" :
-		   ((battery->current_now > 0) ? "charging" : "charged"));
-	rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+		   (battery->rate_now < 0) ? "discharging" :
+		   ((battery->rate_now > 0) ? "charging" : "charged"));
+	rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
 	rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
 			acpi_battery_vscale(battery)/1000):1;
 	seq_printf(seq, "present rate:            %d%s\n", rate,
@@ -677,7 +681,7 @@ static int acpi_battery_alarm_open_fs(st
 	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
 }
 
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
 	.open = acpi_battery_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -685,7 +689,7 @@ static struct file_operations acpi_batte
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
 	.open = acpi_battery_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -693,7 +697,7 @@ static struct file_operations acpi_batte
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
 	.open = acpi_battery_alarm_open_fs,
 	.read = seq_read,
 	.write = acpi_battery_write_alarm,
@@ -725,7 +729,7 @@ static int acpi_ac_state_open_fs(struct
 	return single_open(file, acpi_ac_read_state, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
 	.open = acpi_ac_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/scan.c linux-libre-2.6.30-gnu1/drivers/acpi/scan.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/scan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
 
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("scan");
 #define STRUCT_TO_INT(s)	(*((int*)&s))
@@ -22,7 +24,7 @@ extern struct acpi_device *acpi_root;
 
 static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_bus_id_list);
-DEFINE_SPINLOCK(acpi_device_lock);
+DEFINE_MUTEX(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
 struct acpi_device_bus_id{
@@ -357,6 +359,61 @@ static int acpi_device_uevent(struct dev
 	return 0;
 }
 
+static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_device *device = data;
+
+	device->driver->ops.notify(device, event);
+}
+
+static acpi_status acpi_device_notify_fixed(void *data)
+{
+	struct acpi_device *device = data;
+
+	acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+	return AE_OK;
+}
+
+static int acpi_device_install_notify_handler(struct acpi_device *device)
+{
+	acpi_status status;
+	char *hid;
+
+	hid = acpi_device_hid(device);
+	if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						     acpi_device_notify_fixed,
+						     device);
+	else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						     acpi_device_notify_fixed,
+						     device);
+	else
+		status = acpi_install_notify_handler(device->handle,
+						     ACPI_DEVICE_NOTIFY,
+						     acpi_device_notify,
+						     device);
+
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+	return 0;
+}
+
+static void acpi_device_remove_notify_handler(struct acpi_device *device)
+{
+	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						acpi_device_notify_fixed);
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						acpi_device_notify_fixed);
+	else
+		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+					   acpi_device_notify);
+}
+
 static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
 static int acpi_start_single_object(struct acpi_device *);
 static int acpi_device_probe(struct device * dev)
@@ -369,6 +426,20 @@ static int acpi_device_probe(struct devi
 	if (!ret) {
 		if (acpi_dev->bus_ops.acpi_op_start)
 			acpi_start_single_object(acpi_dev);
+
+		if (acpi_drv->ops.notify) {
+			ret = acpi_device_install_notify_handler(acpi_dev);
+			if (ret) {
+				if (acpi_drv->ops.stop)
+					acpi_drv->ops.stop(acpi_dev,
+						   acpi_dev->removal_type);
+				if (acpi_drv->ops.remove)
+					acpi_drv->ops.remove(acpi_dev,
+						     acpi_dev->removal_type);
+				return ret;
+			}
+		}
+
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			"Found driver [%s] for device [%s]\n",
 			acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -383,6 +454,8 @@ static int acpi_device_remove(struct dev
 	struct acpi_driver *acpi_drv = acpi_dev->driver;
 
 	if (acpi_drv) {
+		if (acpi_drv->ops.notify)
+			acpi_device_remove_notify_handler(acpi_dev);
 		if (acpi_drv->ops.stop)
 			acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
 		if (acpi_drv->ops.remove)
@@ -395,22 +468,10 @@ static int acpi_device_remove(struct dev
 	return 0;
 }
 
-static void acpi_device_shutdown(struct device *dev)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_driver *acpi_drv = acpi_dev->driver;
-
-	if (acpi_drv && acpi_drv->ops.shutdown)
-		acpi_drv->ops.shutdown(acpi_dev);
-
-	return ;
-}
-
 struct bus_type acpi_bus_type = {
 	.name		= "acpi",
 	.suspend	= acpi_device_suspend,
 	.resume		= acpi_device_resume,
-	.shutdown	= acpi_device_shutdown,
 	.match		= acpi_bus_match,
 	.probe		= acpi_device_probe,
 	.remove		= acpi_device_remove,
@@ -430,7 +491,6 @@ static int acpi_device_register(struct a
 	 */
 	INIT_LIST_HEAD(&device->children);
 	INIT_LIST_HEAD(&device->node);
-	INIT_LIST_HEAD(&device->g_list);
 	INIT_LIST_HEAD(&device->wakeup_list);
 
 	new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
@@ -439,7 +499,7 @@ static int acpi_device_register(struct a
 		return -ENOMEM;
 	}
 
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	/*
 	 * Find suitable bus_id and instance number in acpi_bus_id_list
 	 * If failed, create one and link it into acpi_bus_id_list
@@ -460,14 +520,12 @@ static int acpi_device_register(struct a
 	}
 	dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
 
-	if (device->parent) {
+	if (device->parent)
 		list_add_tail(&device->node, &device->parent->children);
-		list_add_tail(&device->g_list, &device->parent->g_list);
-	} else
-		list_add_tail(&device->g_list, &acpi_device_list);
+
 	if (device->wakeup.flags.valid)
 		list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 
 	if (device->parent)
 		device->dev.parent = &parent->dev;
@@ -488,28 +546,22 @@ static int acpi_device_register(struct a
 	device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
 	return 0;
   end:
-	spin_lock(&acpi_device_lock);
-	if (device->parent) {
+	mutex_lock(&acpi_device_lock);
+	if (device->parent)
 		list_del(&device->node);
-		list_del(&device->g_list);
-	} else
-		list_del(&device->g_list);
 	list_del(&device->wakeup_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return result;
 }
 
 static void acpi_device_unregister(struct acpi_device *device, int type)
 {
-	spin_lock(&acpi_device_lock);
-	if (device->parent) {
+	mutex_lock(&acpi_device_lock);
+	if (device->parent)
 		list_del(&device->node);
-		list_del(&device->g_list);
-	} else
-		list_del(&device->g_list);
 
 	list_del(&device->wakeup_list);
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 
 	acpi_detach_data(device->handle, acpi_bus_data_handler);
 
@@ -1524,16 +1576,11 @@ static int acpi_bus_scan_fixed(struct ac
 	return result;
 }
 
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
 {
 	int result;
 	struct acpi_bus_ops ops;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 	ops.acpi_op_start = 1;
@@ -1566,5 +1613,3 @@ static int __init acpi_scan_init(void)
       Done:
 	return result;
 }
-
-subsys_initcall(acpi_scan_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/sleep.c linux-libre-2.6.30-gnu1/drivers/acpi/sleep.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/sleep.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/sleep.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,8 @@
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+
+#include "internal.h"
 #include "sleep.h"
 
 u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@ static int acpi_suspend_enter(suspend_st
 
 	/* If ACPI is not enabled by the BIOS, we need to enable it here. */
 	if (set_sci_en_on_resume)
-		acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
 	else
 		acpi_enable();
 
@@ -298,9 +300,9 @@ static int acpi_suspend_state_valid(susp
 static struct platform_suspend_ops acpi_suspend_ops = {
 	.valid = acpi_suspend_state_valid,
 	.begin = acpi_suspend_begin,
-	.prepare = acpi_pm_prepare,
+	.prepare_late = acpi_pm_prepare,
 	.enter = acpi_suspend_enter,
-	.finish = acpi_pm_finish,
+	.wake = acpi_pm_finish,
 	.end = acpi_pm_end,
 };
 
@@ -326,9 +328,9 @@ static int acpi_suspend_begin_old(suspen
 static struct platform_suspend_ops acpi_suspend_ops_old = {
 	.valid = acpi_suspend_state_valid,
 	.begin = acpi_suspend_begin_old,
-	.prepare = acpi_pm_disable_gpes,
+	.prepare_late = acpi_pm_disable_gpes,
 	.enter = acpi_suspend_enter,
-	.finish = acpi_pm_finish,
+	.wake = acpi_pm_finish,
 	.end = acpi_pm_end,
 	.recover = acpi_pm_finish,
 };
@@ -394,6 +396,15 @@ static struct dmi_system_id __initdata a
 		DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
 		},
 	},
+	{
+	.callback = init_old_suspend_ordering,
+	.ident = "Panasonic CF51-2L",
+	.matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR,
+				"Matsushita Electric Industrial Co.,Ltd."),
+		DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+		},
+	},
 	{},
 };
 #endif /* CONFIG_SUSPEND */
@@ -702,6 +713,32 @@ static void acpi_power_off(void)
 	acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
+/*
+ * ACPI 2.0 created the optional _GTS and _BFS,
+ * but industry adoption has been neither rapid nor broad.
+ *
+ * Linux gets into trouble when it executes poorly validated
+ * paths through the BIOS, so disable _GTS and _BFS by default,
+ * but do speak up and offer the option to enable them.
+ */
+void __init acpi_gts_bfs_check(void)
+{
+	acpi_handle dummy;
+
+	if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy)))
+	{
+		printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n");
+		printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, "
+			"please notify linux-acpi@vger.kernel.org\n");
+	}
+	if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy)))
+	{
+		printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n");
+		printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, "
+			"please notify linux-acpi@vger.kernel.org\n");
+	}
+}
+
 int __init acpi_sleep_init(void)
 {
 	acpi_status status;
@@ -760,5 +797,6 @@ int __init acpi_sleep_init(void)
 	 * object can also be evaluated when the system enters S5.
 	 */
 	register_reboot_notifier(&tts_notifier);
+	acpi_gts_bfs_check();
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/sleep.h linux-libre-2.6.30-gnu1/drivers/acpi/sleep.h
--- linux-libre-2.6.29-gnu1/drivers/acpi/sleep.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/sleep.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,3 +5,6 @@ extern int acpi_suspend (u32 state);
 extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
 extern void acpi_enable_wakeup_device(u8 sleep_state);
 extern void acpi_disable_wakeup_device(u8 sleep_state);
+
+extern struct list_head acpi_wakeup_device_list;
+extern struct mutex acpi_device_lock;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/system.c linux-libre-2.6.30-gnu1/drivers/acpi/system.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/system.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/system.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,15 +33,12 @@
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("system");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
 
 #define ACPI_SYSTEM_CLASS		"system"
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
 
 u32 acpi_irq_handled;
+u32 acpi_irq_not_handled;
 
 /*
  * Make ACPICA version work as module param
@@ -62,6 +59,7 @@ module_param_call(acpica_version, NULL,
    -------------------------------------------------------------------------- */
 static LIST_HEAD(acpi_table_attr_list);
 static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
 
 struct acpi_table_attr {
 	struct bin_attribute attr;
@@ -128,6 +126,40 @@ static void acpi_table_attr_init(struct
 	return;
 }
 
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+	struct acpi_table_attr *table_attr;
+
+	switch (event) {
+	case ACPI_TABLE_EVENT_LOAD:
+		table_attr =
+			kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+		if (!table_attr)
+			return AE_NO_MEMORY;
+
+		acpi_table_attr_init(table_attr, table);
+		if (sysfs_create_bin_file(dynamic_tables_kobj,
+					&table_attr->attr)) {
+			kfree(table_attr);
+			return AE_ERROR;
+		} else
+			list_add_tail(&table_attr->node,
+					&acpi_table_attr_list);
+		break;
+	case ACPI_TABLE_EVENT_UNLOAD:
+		/*
+		 * we do not need to do anything right now
+		 * because the table is not deleted from the
+		 * global table list when unloading it.
+		 */
+		break;
+	default:
+		return AE_BAD_PARAMETER;
+	}
+	return AE_OK;
+}
+
 static int acpi_system_sysfs_init(void)
 {
 	struct acpi_table_attr *table_attr;
@@ -137,7 +169,11 @@ static int acpi_system_sysfs_init(void)
 
 	tables_kobj = kobject_create_and_add("tables", acpi_kobj);
 	if (!tables_kobj)
-		return -ENOMEM;
+		goto err;
+
+	dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+	if (!dynamic_tables_kobj)
+		goto err_dynamic_tables;
 
 	do {
 		result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +198,14 @@ static int acpi_system_sysfs_init(void)
 		}
 	} while (!result);
 	kobject_uevent(tables_kobj, KOBJ_ADD);
+	kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+	result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
 
-	return 0;
+	return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+	kobject_put(tables_kobj);
+err:
+	return -ENOMEM;
 }
 
 /*
@@ -173,8 +215,9 @@ static int acpi_system_sysfs_init(void)
 
 #define COUNT_GPE 0
 #define COUNT_SCI 1	/* acpi_irq_handled */
-#define COUNT_ERROR 2	/* other */
-#define NUM_COUNTERS_EXTRA 3
+#define COUNT_SCI_NOT 2	/* acpi_irq_not_handled */
+#define COUNT_ERROR 3	/* other */
+#define NUM_COUNTERS_EXTRA 4
 
 struct event_counter {
 	u32 count;
@@ -276,6 +319,8 @@ static ssize_t counter_show(struct kobje
 
 	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
 		acpi_irq_handled;
+	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
+		acpi_irq_not_handled;
 	all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
 		acpi_gpe_count;
 
@@ -322,6 +367,7 @@ static ssize_t counter_set(struct kobjec
 			all_counters[i].count = 0;
 		acpi_gpe_count = 0;
 		acpi_irq_handled = 0;
+		acpi_irq_not_handled = 0;
 		goto end;
 	}
 
@@ -415,6 +461,8 @@ void acpi_irq_stats_init(void)
 			sprintf(buffer, "gpe_all");
 		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
 			sprintf(buffer, "sci");
+		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
+			sprintf(buffer, "sci_not");
 		else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
 			sprintf(buffer, "error");
 		else
@@ -571,12 +619,9 @@ static int acpi_system_procfs_init(void)
 }
 #endif
 
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
 {
-	int result = 0;
-
-	if (acpi_disabled)
-		return 0;
+	int result;
 
 	result = acpi_system_procfs_init();
 	if (result)
@@ -586,5 +631,3 @@ static int __init acpi_system_init(void)
 
 	return result;
 }
-
-subsys_initcall(acpi_system_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/tables.c linux-libre-2.6.30-gnu1/drivers/acpi/tables.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/tables.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/tables.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct
 		}
 		break;
 
+	case ACPI_MADT_TYPE_LOCAL_X2APIC:
+		{
+			struct acpi_madt_local_x2apic *p =
+			    (struct acpi_madt_local_x2apic *)header;
+			printk(KERN_INFO PREFIX
+			       "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+			       p->local_apic_id, p->uid,
+			       (p->lapic_flags & ACPI_MADT_ENABLED) ?
+			       "enabled" : "disabled");
+		}
+		break;
+
 	case ACPI_MADT_TYPE_IO_APIC:
 		{
 			struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct
 		}
 		break;
 
+	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+		{
+			u16 polarity, trigger;
+			struct acpi_madt_local_x2apic_nmi *p =
+			    (struct acpi_madt_local_x2apic_nmi *)header;
+
+			polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+			trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+			printk(KERN_INFO PREFIX
+			       "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+			       p->uid,
+			       mps_inti_flags_polarity[polarity],
+			       mps_inti_flags_trigger[trigger],
+			       p->lint);
+		}
+		break;
+
 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
 		{
 			struct acpi_madt_local_apic_override *p =
@@ -181,14 +211,15 @@ acpi_table_parse_entries(char *id,
 	struct acpi_subtable_header *entry;
 	unsigned int count = 0;
 	unsigned long table_end;
+	acpi_size tbl_size;
 
 	if (!handler)
 		return -EINVAL;
 
 	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table(id, acpi_apic_instance, &table_header);
+		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
 	else
-		acpi_get_table(id, 0, &table_header);
+		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
 
 	if (!table_header) {
 		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
@@ -206,8 +237,10 @@ acpi_table_parse_entries(char *id,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, table_end))
+			if (handler(entry, table_end)) {
+				early_acpi_os_unmap_memory((char *)table_header, tbl_size);
 				return -EINVAL;
+			}
 
 		entry = (struct acpi_subtable_header *)
 		    ((unsigned long)entry + entry->length);
@@ -217,6 +250,7 @@ acpi_table_parse_entries(char *id,
 		       "%i found\n", id, entry_id, count - max_entries, count);
 	}
 
+	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
 	return count;
 }
 
@@ -241,17 +275,19 @@ acpi_table_parse_madt(enum acpi_madt_typ
 int __init acpi_table_parse(char *id, acpi_table_handler handler)
 {
 	struct acpi_table_header *table = NULL;
+	acpi_size tbl_size;
 
 	if (!handler)
 		return -EINVAL;
 
 	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table(id, acpi_apic_instance, &table);
+		acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size);
 	else
-		acpi_get_table(id, 0, &table);
+		acpi_get_table_with_size(id, 0, &table, &tbl_size);
 
 	if (table) {
 		handler(table);
+		early_acpi_os_unmap_memory(table, tbl_size);
 		return 0;
 	} else
 		return 1;
@@ -265,8 +301,9 @@ int __init acpi_table_parse(char *id, ac
 static void __init check_multiple_madt(void)
 {
 	struct acpi_table_header *table = NULL;
+	acpi_size tbl_size;
 
-	acpi_get_table(ACPI_SIG_MADT, 2, &table);
+	acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size);
 	if (table) {
 		printk(KERN_WARNING PREFIX
 		       "BIOS bug: multiple APIC/MADT found,"
@@ -275,6 +312,7 @@ static void __init check_multiple_madt(v
 		       "If \"acpi_apic_instance=%d\" works better, "
 		       "notify linux-acpi@vger.kernel.org\n",
 		       acpi_apic_instance ? 0 : 2);
+		early_acpi_os_unmap_memory(table, tbl_size);
 
 	} else
 		acpi_apic_instance = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/thermal.c linux-libre-2.6.30-gnu1/drivers/acpi/thermal.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/thermal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/thermal.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,11 +37,11 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
 #include <linux/reboot.h>
+#include <linux/device.h>
 #include <asm/uaccess.h>
 #include <linux/thermal.h>
 #include <acpi/acpi_bus.h>
@@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or overri
 static int acpi_thermal_add(struct acpi_device *device);
 static int acpi_thermal_remove(struct acpi_device *device, int type);
 static int acpi_thermal_resume(struct acpi_device *device);
+static void acpi_thermal_notify(struct acpi_device *device, u32 event);
 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -123,6 +124,7 @@ static struct acpi_driver acpi_thermal_d
 		.add = acpi_thermal_add,
 		.remove = acpi_thermal_remove,
 		.resume = acpi_thermal_resume,
+		.notify = acpi_thermal_notify,
 		},
 };
 
@@ -190,9 +192,9 @@ struct acpi_thermal {
 	struct acpi_thermal_state state;
 	struct acpi_thermal_trips trips;
 	struct acpi_handle_list devices;
-	struct timer_list timer;
 	struct thermal_zone_device *thermal_zone;
 	int tz_enabled;
+	int kelvin_offset;
 	struct mutex lock;
 };
 
@@ -290,6 +292,11 @@ static int acpi_thermal_set_polling(stru
 
 	tz->polling_frequency = seconds * 10;	/* Convert value to deci-seconds */
 
+	tz->thermal_zone->polling_delay = seconds * 1000;
+
+	if (tz->tz_enabled)
+		thermal_zone_device_update(tz->thermal_zone);
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Polling frequency set to %lu seconds\n",
 			  tz->polling_frequency/10));
@@ -367,7 +374,7 @@ static int acpi_thermal_trips_update(str
 		/*
 		 * Treat freezing temperatures as invalid as well; some
 		 * BIOSes return really low values and cause reboots at startup.
-		 * Below zero (Celcius) values clearly aren't right for sure..
+		 * Below zero (Celsius) values clearly aren't right for sure..
 		 * ... so lets discard those as invalid.
 		 */
 		if (ACPI_FAILURE(status) ||
@@ -569,392 +576,18 @@ static int acpi_thermal_get_trip_points(
 	return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
 }
 
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.critical.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.critical.temperature) {
-		printk(KERN_WARNING PREFIX "Critical trip point\n");
-		tz->trips.critical.flags.enabled = 1;
-	} else if (tz->trips.critical.flags.enabled)
-		tz->trips.critical.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
-				tz->trips.critical.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_CRITICAL,
-					  tz->trips.critical.flags.enabled);
-
-	/* take no action if nocrt is set */
-	if(!nocrt) {
-		printk(KERN_EMERG
-			"Critical temperature reached (%ld C), shutting down.\n",
-			KELVIN_TO_CELSIUS(tz->temperature));
-		orderly_poweroff(true);
-	}
-
-	return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.hot.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.hot.temperature) {
-		printk(KERN_WARNING PREFIX "Hot trip point\n");
-		tz->trips.hot.flags.enabled = 1;
-	} else if (tz->trips.hot.flags.enabled)
-		tz->trips.hot.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
-				tz->trips.hot.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_HOT,
-					  tz->trips.hot.flags.enabled);
-
-	/* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
-	return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
-	int result = 1;
-	struct acpi_thermal_passive *passive = NULL;
-	int trend = 0;
-	int i = 0;
-
-
-	if (!tz || !tz->trips.passive.flags.valid)
-		return;
-
-	passive = &(tz->trips.passive);
-
-	/*
-	 * Above Trip?
-	 * -----------
-	 * Calculate the thermal trend (using the passive cooling equation)
-	 * and modify the performance limit for all passive cooling devices
-	 * accordingly.  Note that we assume symmetry.
-	 */
-	if (tz->temperature >= passive->temperature) {
-		trend =
-		    (passive->tc1 * (tz->temperature - tz->last_temperature)) +
-		    (passive->tc2 * (tz->temperature - passive->temperature));
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
-				  trend, passive->tc1, tz->temperature,
-				  tz->last_temperature, passive->tc2,
-				  tz->temperature, passive->temperature));
-		passive->flags.enabled = 1;
-		/* Heating up? */
-		if (trend > 0)
-			for (i = 0; i < passive->devices.count; i++)
-				acpi_processor_set_thermal_limit(passive->
-								 devices.
-								 handles[i],
-								 ACPI_PROCESSOR_LIMIT_INCREMENT);
-		/* Cooling off? */
-		else if (trend < 0) {
-			for (i = 0; i < passive->devices.count; i++)
-				/*
-				 * assume that we are on highest
-				 * freq/lowest thrott and can leave
-				 * passive mode, even in error case
-				 */
-				if (!acpi_processor_set_thermal_limit
-				    (passive->devices.handles[i],
-				     ACPI_PROCESSOR_LIMIT_DECREMENT))
-					result = 0;
-			/*
-			 * Leave cooling mode, even if the temp might
-			 * higher than trip point This is because some
-			 * machines might have long thermal polling
-			 * frequencies (tsp) defined. We will fall back
-			 * into passive mode in next cycle (probably quicker)
-			 */
-			if (result) {
-				passive->flags.enabled = 0;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Disabling passive cooling, still above threshold,"
-						  " but we are cooling down\n"));
-			}
-		}
-		return;
-	}
-
-	/*
-	 * Below Trip?
-	 * -----------
-	 * Implement passive cooling hysteresis to slowly increase performance
-	 * and avoid thrashing around the passive trip point.  Note that we
-	 * assume symmetry.
-	 */
-	if (!passive->flags.enabled)
-		return;
-	for (i = 0; i < passive->devices.count; i++)
-		if (!acpi_processor_set_thermal_limit
-		    (passive->devices.handles[i],
-		     ACPI_PROCESSOR_LIMIT_DECREMENT))
-			result = 0;
-	if (result) {
-		passive->flags.enabled = 0;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Disabling passive cooling (zone is cool)\n"));
-	}
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
-	int result = 0;
-	struct acpi_thermal_active *active = NULL;
-	int i = 0;
-	int j = 0;
-	unsigned long maxtemp = 0;
-
-
-	if (!tz)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * Above Threshold?
-			 * ----------------
-			 * If not already enabled, turn ON all cooling devices
-			 * associated with this active threshold.
-			 */
-			if (active->temperature > maxtemp)
-				tz->state.active_index = i;
-			maxtemp = active->temperature;
-			if (active->flags.enabled)
-				continue;
-			for (j = 0; j < active->devices.count; j++) {
-				result =
-				    acpi_bus_set_power(active->devices.
-						       handles[j],
-						       ACPI_STATE_D0);
-				if (result) {
-					printk(KERN_WARNING PREFIX
-						      "Unable to turn cooling device [%p] 'on'\n",
-						      active->devices.
-						      handles[j]);
-					continue;
-				}
-				active->flags.enabled = 1;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Cooling device [%p] now 'on'\n",
-						  active->devices.handles[j]));
-			}
-			continue;
-		}
-		if (!active->flags.enabled)
-			continue;
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++) {
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-			if (result) {
-				printk(KERN_WARNING PREFIX
-					      "Unable to turn cooling device [%p] 'off'\n",
-					      active->devices.handles[j]);
-				continue;
-			}
-			active->flags.enabled = 0;
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Cooling device [%p] now 'off'\n",
-					  active->devices.handles[j]));
-		}
-	}
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
-	struct acpi_thermal *tz = (struct acpi_thermal *)data;
-	if (!tz->zombie)
-		acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
-	int result = 0;
-	struct acpi_thermal *tz = data;
-	int i = 0;
-	int j = 0;
-	struct acpi_thermal_active *active = NULL;
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * If the thermal temperature is greater than the
-			 * active threshod, unnecessary to turn off the
-			 * the active cooling device.
-			 */
-			continue;
-		}
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++)
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-	}
-}
-
 static void acpi_thermal_check(void *data)
 {
-	int result = 0;
 	struct acpi_thermal *tz = data;
-	unsigned long sleep_time = 0;
-	unsigned long timeout_jiffies = 0;
-	int i = 0;
-	struct acpi_thermal_state state;
 
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	/* Check if someone else is already running */
-	if (!mutex_trylock(&tz->lock))
-		return;
-
-	state = tz->state;
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		goto unlock;
-
-	if (!tz->tz_enabled)
-		goto unlock;
-
-	memset(&tz->state, 0, sizeof(tz->state));
-
-	/*
-	 * Check Trip Points
-	 * -----------------
-	 * Compare the current temperature to the trip point values to see
-	 * if we've entered one of the thermal policy states.  Note that
-	 * this function determines when a state is entered, but the 
-	 * individual policy decides when it is exited (e.g. hysteresis).
-	 */
-	if (tz->trips.critical.flags.valid)
-		state.critical |=
-		    (tz->temperature >= tz->trips.critical.temperature);
-	if (tz->trips.hot.flags.valid)
-		state.hot |= (tz->temperature >= tz->trips.hot.temperature);
-	if (tz->trips.passive.flags.valid)
-		state.passive |=
-		    (tz->temperature >= tz->trips.passive.temperature);
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		if (tz->trips.active[i].flags.valid)
-			state.active |=
-			    (tz->temperature >=
-			     tz->trips.active[i].temperature);
-
-	/*
-	 * Invoke Policy
-	 * -------------
-	 * Separated from the above check to allow individual policy to 
-	 * determine when to exit a given state.
-	 */
-	if (state.critical)
-		acpi_thermal_critical(tz);
-	if (state.hot)
-		acpi_thermal_hot(tz);
-	if (state.passive)
-		acpi_thermal_passive(tz);
-	if (state.active)
-		acpi_thermal_active(tz);
-
-	/*
-	 * Calculate State
-	 * ---------------
-	 * Again, separated from the above two to allow independent policy
-	 * decisions.
-	 */
-	tz->state.critical = tz->trips.critical.flags.enabled;
-	tz->state.hot = tz->trips.hot.flags.enabled;
-	tz->state.passive = tz->trips.passive.flags.enabled;
-	tz->state.active = 0;
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		tz->state.active |= tz->trips.active[i].flags.enabled;
-
-	/*
-	 * Calculate Sleep Time
-	 * --------------------
-	 * If we're in the passive state, use _TSP's value.  Otherwise
-	 * use the default polling frequency (e.g. _TZP).  If no polling
-	 * frequency is specified then we'll wait forever (at least until
-	 * a thermal event occurs).  Note that _TSP and _TZD values are
-	 * given in 1/10th seconds (we must covert to milliseconds).
-	 */
-	if (tz->state.passive) {
-		sleep_time = tz->trips.passive.tsp * 100;
-		timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
-	} else if (tz->polling_frequency > 0) {
-		sleep_time = tz->polling_frequency * 100;
-		timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
-			  tz->name, tz->temperature, sleep_time));
-
-	/*
-	 * Schedule Next Poll
-	 * ------------------
-	 */
-	if (!sleep_time) {
-		if (timer_pending(&(tz->timer)))
-			del_timer(&(tz->timer));
-	} else {
-		if (timer_pending(&(tz->timer)))
-			mod_timer(&(tz->timer), timeout_jiffies);
-		else {
-			tz->timer.data = (unsigned long)tz;
-			tz->timer.function = acpi_thermal_run;
-			tz->timer.expires = timeout_jiffies;
-			add_timer(&(tz->timer));
-		}
-	}
-      unlock:
-	mutex_unlock(&tz->lock);
+	thermal_zone_device_update(tz->thermal_zone);
 }
 
 /* sys I/F for generic thermal sysfs support */
-#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
 
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+			    unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int result;
@@ -966,25 +599,28 @@ static int thermal_get_temp(struct therm
 	if (result)
 		return result;
 
-	return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
+	return 0;
 }
 
 static const char enabled[] = "kernel";
 static const char disabled[] = "user";
 static int thermal_get_mode(struct thermal_zone_device *thermal,
-				char *buf)
+				enum thermal_device_mode *mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 
 	if (!tz)
 		return -EINVAL;
 
-	return sprintf(buf, "%s\n", tz->tz_enabled ?
-			enabled : disabled);
+	*mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+		THERMAL_DEVICE_DISABLED;
+
+	return 0;
 }
 
 static int thermal_set_mode(struct thermal_zone_device *thermal,
-				const char *buf)
+				enum thermal_device_mode mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int enable;
@@ -995,9 +631,9 @@ static int thermal_set_mode(struct therm
 	/*
 	 * enable/disable thermal management from ACPI thermal driver
 	 */
-	if (!strncmp(buf, enabled, sizeof enabled - 1))
+	if (mode == THERMAL_DEVICE_ENABLED)
 		enable = 1;
-	else if (!strncmp(buf, disabled, sizeof disabled - 1))
+	else if (mode == THERMAL_DEVICE_DISABLED)
 		enable = 0;
 	else
 		return -EINVAL;
@@ -1013,7 +649,7 @@ static int thermal_set_mode(struct therm
 }
 
 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, enum thermal_trip_type *type)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1022,27 +658,35 @@ static int thermal_get_trip_type(struct
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "critical\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_CRITICAL;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "hot\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_HOT;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "passive\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_PASSIVE;
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "active%d\n", i);
+		if (!trip) {
+			*type = THERMAL_TRIP_ACTIVE;
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1050,7 +694,7 @@ static int thermal_get_trip_type(struct
 }
 
 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1059,31 +703,43 @@ static int thermal_get_trip_temp(struct
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.critical.temperature,
+				tz->kelvin_offset);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.hot.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.hot.temperature,
+				tz->kelvin_offset);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.passive.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.passive.temperature,
+				tz->kelvin_offset);
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.active[i].temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.active[i].temperature,
+				tz->kelvin_offset);
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1096,12 +752,36 @@ static int thermal_get_crit_temp(struct
 
 	if (tz->trips.critical.flags.valid) {
 		*temperature = KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature);
+				tz->trips.critical.temperature,
+				tz->kelvin_offset);
 		return 0;
 	} else
 		return -EINVAL;
 }
 
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+			   enum thermal_trip_type trip_type)
+{
+	u8 type = 0;
+	struct acpi_thermal *tz = thermal->devdata;
+
+	if (trip_type == THERMAL_TRIP_CRITICAL)
+		type = ACPI_THERMAL_NOTIFY_CRITICAL;
+	else if (trip_type == THERMAL_TRIP_HOT)
+		type = ACPI_THERMAL_NOTIFY_HOT;
+	else
+		return 0;
+
+	acpi_bus_generate_proc_event(tz->device, type, 1);
+	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+					dev_name(&tz->device->dev), type, 1);
+
+	if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+		return 1;
+
+	return 0;
+}
+
 typedef int (*cb)(struct thermal_zone_device *, int,
 		  struct thermal_cooling_device *);
 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +874,7 @@ static struct thermal_zone_device_ops ac
 	.get_trip_type = thermal_get_trip_type,
 	.get_trip_temp = thermal_get_trip_temp,
 	.get_crit_temp = thermal_get_crit_temp,
+	.notify = thermal_notify,
 };
 
 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +895,21 @@ static int acpi_thermal_register_thermal
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 			tz->trips.active[i].flags.valid; i++, trips++);
-	tz->thermal_zone = thermal_zone_device_register("acpitz",
-					trips, tz, &acpi_thermal_zone_ops);
+
+	if (tz->trips.passive.flags.valid)
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     tz->trips.passive.tc1,
+						     tz->trips.passive.tc2,
+						     tz->trips.passive.tsp*100,
+						     tz->polling_frequency*100);
+	else
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     0, 0, 0,
+						     tz->polling_frequency*100);
 	if (IS_ERR(tz->thermal_zone))
 		return -ENODEV;
 
@@ -1447,13 +1141,13 @@ static int acpi_thermal_polling_seq_show
 	if (!tz)
 		goto end;
 
-	if (!tz->polling_frequency) {
+	if (!tz->thermal_zone->polling_delay) {
 		seq_puts(seq, "<polling disabled>\n");
 		goto end;
 	}
 
-	seq_printf(seq, "polling frequency:       %lu seconds\n",
-		   (tz->polling_frequency / 10));
+	seq_printf(seq, "polling frequency:       %d seconds\n",
+		   (tz->thermal_zone->polling_delay / 1000));
 
       end:
 	return 0;
@@ -1506,7 +1200,6 @@ static int acpi_thermal_add_fs(struct ac
 						     acpi_thermal_dir);
 		if (!acpi_device_dir(device))
 			return -ENODEV;
-		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'state' [R] */
@@ -1579,17 +1272,14 @@ static int acpi_thermal_remove_fs(struct
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
-static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_thermal_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_thermal *tz = data;
-	struct acpi_device *device = NULL;
+	struct acpi_thermal *tz = acpi_driver_data(device);
 
 
 	if (!tz)
 		return;
 
-	device = tz->device;
-
 	switch (event) {
 	case ACPI_THERMAL_NOTIFY_TEMPERATURE:
 		acpi_thermal_check(tz);
@@ -1613,8 +1303,6 @@ static void acpi_thermal_notify(acpi_han
 				  "Unsupported event [0x%x]\n", event));
 		break;
 	}
-
-	return;
 }
 
 static int acpi_thermal_get_info(struct acpi_thermal *tz)
@@ -1649,10 +1337,28 @@ static int acpi_thermal_get_info(struct
 	return 0;
 }
 
+/*
+ * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
+ * handles temperature values with a single decimal place. As a consequence,
+ * some implementations use an offset of 273.1 and others use an offset of
+ * 273.2. Try to find out which one is being used, to present the most
+ * accurate and visually appealing number.
+ *
+ * The heuristic below should work for all ACPI thermal zones which have a
+ * critical trip point with a value being a multiple of 0.5 degree Celsius.
+ */
+static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
+{
+	if (tz->trips.critical.flags.valid &&
+	    (tz->trips.critical.temperature % 5) == 1)
+		tz->kelvin_offset = 2731;
+	else
+		tz->kelvin_offset = 2732;
+}
+
 static int acpi_thermal_add(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
 
@@ -1675,6 +1381,8 @@ static int acpi_thermal_add(struct acpi_
 	if (result)
 		goto free_memory;
 
+	acpi_thermal_guess_offset(tz);
+
 	result = acpi_thermal_register_thermal_zone(tz);
 	if (result)
 		goto free_memory;
@@ -1683,27 +1391,11 @@ static int acpi_thermal_add(struct acpi_
 	if (result)
 		goto unregister_thermal_zone;
 
-	init_timer(&tz->timer);
-
-	acpi_thermal_active_off(tz);
-
-	acpi_thermal_check(tz);
-
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_thermal_notify, tz);
-	if (ACPI_FAILURE(status)) {
-		result = -ENODEV;
-		goto remove_fs;
-	}
-
 	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       KELVIN_TO_CELSIUS(tz->temperature));
 	goto end;
 
-remove_fs:
-	acpi_thermal_remove_fs(device);
 unregister_thermal_zone:
 	thermal_zone_device_unregister(tz->thermal_zone);
 free_memory:
@@ -1714,39 +1406,13 @@ end:
 
 static int acpi_thermal_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
-
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	tz = acpi_driver_data(device);
 
-	/* avoid timer adding new defer task */
-	tz->zombie = 1;
-	/* wait for running timer (on other CPUs) finish */
-	del_timer_sync(&(tz->timer));
-	/* synchronize deferred task */
-	acpi_os_wait_events_complete(NULL);
-	/* deferred task may reinsert timer */
-	del_timer_sync(&(tz->timer));
-
-	status = acpi_remove_notify_handler(device->handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_thermal_notify);
-
-	/* Terminate policy */
-	if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
-		tz->trips.passive.flags.enabled = 0;
-		acpi_thermal_passive(tz);
-	}
-	if (tz->trips.active[0].flags.valid
-	    && tz->trips.active[0].flags.enabled) {
-		tz->trips.active[0].flags.enabled = 0;
-		acpi_thermal_active(tz);
-	}
-
 	acpi_thermal_remove_fs(device);
 	acpi_thermal_unregister_thermal_zone(tz);
 	mutex_destroy(&tz->lock);
@@ -1875,7 +1541,6 @@ static int __init acpi_thermal_init(void
 	acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
 	if (!acpi_thermal_dir)
 		return -ENODEV;
-	acpi_thermal_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_thermal_driver);
 	if (result < 0) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/video.c linux-libre-2.6.30-gnu1/drivers/acpi/video.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/video.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,8 @@
 #include <linux/thermal.h>
 #include <linux/video_output.h>
 #include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_bus.h>
@@ -77,6 +79,7 @@ module_param(brightness_switch_enabled,
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
 static int acpi_video_resume(struct acpi_device *device);
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id video_device_ids[] = {
 	{ACPI_VIDEO_HID, 0},
@@ -92,6 +95,7 @@ static struct acpi_driver acpi_video_bus
 		.add = acpi_video_bus_add,
 		.remove = acpi_video_bus_remove,
 		.resume = acpi_video_resume,
+		.notify = acpi_video_bus_notify,
 		},
 };
 
@@ -162,16 +166,26 @@ struct acpi_video_device_cap {
 	u8 _BCL:1;		/*Query list of brightness control levels supported */
 	u8 _BCM:1;		/*Set the brightness level */
 	u8 _BQC:1;		/* Get current brightness level */
+	u8 _BCQ:1;		/* Some buggy BIOS uses _BCQ instead of _BQC */
 	u8 _DDC:1;		/*Return the EDID for this device */
 	u8 _DCS:1;		/*Return status of output device */
 	u8 _DGS:1;		/*Query graphics state */
 	u8 _DSS:1;		/*Device state set */
 };
 
+struct acpi_video_brightness_flags {
+	u8 _BCL_no_ac_battery_levels:1;	/* no AC/Battery levels in _BCL */
+	u8 _BCL_reversed:1;		/* _BCL package is in a reversed order*/
+	u8 _BCL_use_index:1;		/* levels in _BCL are index values */
+	u8 _BCM_use_index:1;		/* input of _BCM is an index value */
+	u8 _BQC_use_index:1;		/* _BQC returns an index value */
+};
+
 struct acpi_video_device_brightness {
 	int curr;
 	int count;
 	int *levels;
+	struct acpi_video_brightness_flags flags;
 };
 
 struct acpi_video_device {
@@ -189,7 +203,7 @@ struct acpi_video_device {
 
 /* bus */
 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_info_fops = {
+static const struct file_operations acpi_video_bus_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_info_open_fs,
 	.read = seq_read,
@@ -198,7 +212,7 @@ static struct file_operations acpi_video
 };
 
 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_ROM_fops = {
+static const struct file_operations acpi_video_bus_ROM_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_ROM_open_fs,
 	.read = seq_read,
@@ -208,7 +222,7 @@ static struct file_operations acpi_video
 
 static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
 					    struct file *file);
-static struct file_operations acpi_video_bus_POST_info_fops = {
+static const struct file_operations acpi_video_bus_POST_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_POST_info_open_fs,
 	.read = seq_read,
@@ -217,19 +231,25 @@ static struct file_operations acpi_video
 };
 
 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_POST_fops = {
+static ssize_t acpi_video_bus_write_POST(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_POST_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_POST_open_fs,
 	.read = seq_read,
+	.write = acpi_video_bus_write_POST,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_DOS_fops = {
+static ssize_t acpi_video_bus_write_DOS(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_DOS_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_DOS_open_fs,
 	.read = seq_read,
+	.write = acpi_video_bus_write_DOS,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
@@ -237,7 +257,7 @@ static struct file_operations acpi_video
 /* device */
 static int acpi_video_device_info_open_fs(struct inode *inode,
 					  struct file *file);
-static struct file_operations acpi_video_device_info_fops = {
+static const struct file_operations acpi_video_device_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_info_open_fs,
 	.read = seq_read,
@@ -247,27 +267,33 @@ static struct file_operations acpi_video
 
 static int acpi_video_device_state_open_fs(struct inode *inode,
 					   struct file *file);
-static struct file_operations acpi_video_device_state_fops = {
+static ssize_t acpi_video_device_write_state(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_device_state_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_state_open_fs,
 	.read = seq_read,
+	.write = acpi_video_device_write_state,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_device_brightness_open_fs(struct inode *inode,
 						struct file *file);
+static ssize_t acpi_video_device_write_brightness(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
 static struct file_operations acpi_video_device_brightness_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_brightness_open_fs,
 	.read = seq_read,
+	.write = acpi_video_device_write_brightness,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_device_EDID_open_fs(struct inode *inode,
 					  struct file *file);
-static struct file_operations acpi_video_device_EDID_fops = {
+static const struct file_operations acpi_video_device_EDID_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_EDID_open_fs,
 	.read = seq_read,
@@ -275,7 +301,7 @@ static struct file_operations acpi_video
 	.release = single_release,
 };
 
-static char device_decode[][30] = {
+static const char device_decode[][30] = {
 	"motherboard VGA device",
 	"PCI VGA device",
 	"AGP VGA device",
@@ -294,7 +320,7 @@ static int acpi_video_device_lcd_get_lev
 			unsigned long long *level);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
 				     u32 level_current, u32 event);
-static void acpi_video_switch_brightness(struct acpi_video_device *device,
+static int acpi_video_switch_brightness(struct acpi_video_device *device,
 					 int event);
 static int acpi_video_device_get_state(struct acpi_video_device *device,
 			    unsigned long long *state);
@@ -308,7 +334,9 @@ static int acpi_video_get_brightness(str
 	int i;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+	if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+		return -EINVAL;
 	for (i = 2; i < vd->brightness->count; i++) {
 		if (vd->brightness->levels[i] == cur_level)
 			/* The first two entries are special - see page 575
@@ -320,12 +348,12 @@ static int acpi_video_get_brightness(str
 
 static int acpi_video_set_brightness(struct backlight_device *bd)
 {
-	int request_level = bd->props.brightness+2;
+	int request_level = bd->props.brightness + 2;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_set_level(vd,
-					vd->brightness->levels[request_level]);
-	return 0;
+
+	return acpi_video_device_lcd_set_level(vd,
+				vd->brightness->levels[request_level]);
 }
 
 static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +386,37 @@ static struct output_properties acpi_out
 
 
 /* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 
-	return sprintf(buf, "%d\n", video->brightness->count - 3);
+	*state = video->brightness->count - 3;
+	return 0;
 }
 
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 	unsigned long long level;
-	int state;
+	int offset;
 
-	acpi_video_device_lcd_get_level_current(video, &level);
-	for (state = 2; state < video->brightness->count; state++)
-		if (level == video->brightness->levels[state])
-			return sprintf(buf, "%d\n",
-				       video->brightness->count - state - 1);
+	if (acpi_video_device_lcd_get_level_current(video, &level))
+		return -EINVAL;
+	for (offset = 2; offset < video->brightness->count; offset++)
+		if (level == video->brightness->levels[offset]) {
+			*state = video->brightness->count - offset - 1;
+			return 0;
+		}
 
 	return -EINVAL;
 }
 
 static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +512,120 @@ acpi_video_device_lcd_query_levels(struc
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-	int status = AE_OK;
+	int status;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 	int state;
 
-
 	arg0.integer.value = level;
 
-	if (device->cap._BCM)
-		status = acpi_evaluate_object(device->dev->handle, "_BCM",
-					      &args, NULL);
+	status = acpi_evaluate_object(device->dev->handle, "_BCM",
+				      &args, NULL);
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+		return -EIO;
+	}
+
 	device->brightness->curr = level;
 	for (state = 2; state < device->brightness->count; state++)
-		if (level == device->brightness->levels[state])
-			device->backlight->props.brightness = state - 2;
+		if (level == device->brightness->levels[state]) {
+			if (device->backlight)
+				device->backlight->props.brightness = state - 2;
+			return 0;
+		}
 
-	return status;
+	ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+	return -EINVAL;
 }
 
+/*
+ * For some buggy _BQC methods, we need to add a constant value to
+ * the _BQC return value to get the actual current brightness level
+ */
+
+static int bqc_offset_aml_bug_workaround;
+static int __init video_set_bqc_offset(const struct dmi_system_id *d)
+{
+	bqc_offset_aml_bug_workaround = 9;
+	return 0;
+}
+
+static struct dmi_system_id video_dmi_table[] __initdata = {
+	/*
+	 * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
+	 */
+	{
+	 .callback = video_set_bqc_offset,
+	 .ident = "Acer Aspire 5720",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+		},
+	},
+	{
+	 .callback = video_set_bqc_offset,
+	 .ident = "Acer Aspire 5710Z",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
+		},
+	},
+	{
+	 .callback = video_set_bqc_offset,
+	 .ident = "eMachines E510",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),
+		},
+	},
+	{
+	 .callback = video_set_bqc_offset,
+	 .ident = "Acer Aspire 5315",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
+		},
+	},
+	{}
+};
+
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
 					unsigned long long *level)
 {
-	if (device->cap._BQC)
-		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
-					     level);
+	acpi_status status = AE_OK;
+
+	if (device->cap._BQC || device->cap._BCQ) {
+		char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+		status = acpi_evaluate_integer(device->dev->handle, buf,
+						NULL, level);
+		if (ACPI_SUCCESS(status)) {
+			if (device->brightness->flags._BQC_use_index) {
+				if (device->brightness->flags._BCL_reversed)
+					*level = device->brightness->count
+								 - 3 - (*level);
+				*level = device->brightness->levels[*level + 2];
+
+			}
+			*level += bqc_offset_aml_bug_workaround;
+			device->brightness->curr = *level;
+			return 0;
+		} else {
+			/* Fixme:
+			 * should we return an error or ignore this failure?
+			 * dev->brightness->curr is a cached value which stores
+			 * the correct current backlight level in most cases.
+			 * ACPI video backlight still works w/ buggy _BQC.
+			 * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+			 */
+			ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+			device->cap._BQC = device->cap._BCQ = 0;
+		}
+	}
+
 	*level = device->brightness->curr;
-	return AE_OK;
+	return 0;
 }
 
 static int
@@ -655,9 +774,11 @@ static int
 acpi_video_init_brightness(struct acpi_video_device *device)
 {
 	union acpi_object *obj = NULL;
-	int i, max_level = 0, count = 0;
+	int i, max_level = 0, count = 0, level_ac_battery = 0;
+	unsigned long long level, level_old;
 	union acpi_object *o;
 	struct acpi_video_device_brightness *br = NULL;
+	int result = -EINVAL;
 
 	if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +792,16 @@ acpi_video_init_brightness(struct acpi_v
 	br = kzalloc(sizeof(*br), GFP_KERNEL);
 	if (!br) {
 		printk(KERN_ERR "can't allocate memory\n");
+		result = -ENOMEM;
 		goto out;
 	}
 
-	br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+	br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
 				GFP_KERNEL);
-	if (!br->levels)
+	if (!br->levels) {
+		result = -ENOMEM;
 		goto out_free;
+	}
 
 	for (i = 0; i < obj->package.count; i++) {
 		o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +816,89 @@ acpi_video_init_brightness(struct acpi_v
 		count++;
 	}
 
-	/* don't sort the first two brightness levels */
-	sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
-		acpi_video_cmp_level, NULL);
+	/*
+	 * some buggy BIOS don't export the levels
+	 * when machine is on AC/Battery in _BCL package.
+	 * In this case, the first two elements in _BCL packages
+	 * are also supported brightness levels that OS should take care of.
+	 */
+	for (i = 2; i < count; i++) {
+		if (br->levels[i] == br->levels[0])
+			level_ac_battery++;
+		if (br->levels[i] == br->levels[1])
+			level_ac_battery++;
+	}
 
-	if (count < 2)
-		goto out_free_levels;
+	if (level_ac_battery < 2) {
+		level_ac_battery = 2 - level_ac_battery;
+		br->flags._BCL_no_ac_battery_levels = 1;
+		for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+			br->levels[i] = br->levels[i - level_ac_battery];
+		count += level_ac_battery;
+	} else if (level_ac_battery > 2)
+		ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+	/* Check if the _BCL package is in a reversed order */
+	if (max_level == br->levels[2]) {
+		br->flags._BCL_reversed = 1;
+		sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+			acpi_video_cmp_level, NULL);
+	} else if (max_level != br->levels[count - 1])
+		ACPI_ERROR((AE_INFO,
+			    "Found unordered _BCL package\n"));
 
 	br->count = count;
 	device->brightness = br;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+	/* Check the input/output of _BQC/_BCL/_BCM */
+	if ((max_level < 100) && (max_level <= (count - 2)))
+		br->flags._BCL_use_index = 1;
+
+	/*
+	 * _BCM is always consistent with _BCL,
+	 * at least for all the laptops we have ever seen.
+	 */
+	br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+	/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+	br->curr = level_old = max_level;
+
+	if (!device->cap._BQC)
+		goto set_level;
+
+	result = acpi_video_device_lcd_get_level_current(device, &level_old);
+	if (result)
+		goto out_free_levels;
+
+	/*
+	 * Set the level to maximum and check if _BQC uses indexed value
+	 */
+	result = acpi_video_device_lcd_set_level(device, max_level);
+	if (result)
+		goto out_free_levels;
+
+	result = acpi_video_device_lcd_get_level_current(device, &level);
+	if (result)
+		goto out_free_levels;
+
+	br->flags._BQC_use_index = (level == max_level ? 0 : 1);
+
+	if (!br->flags._BQC_use_index)
+		goto set_level;
+
+	if (br->flags._BCL_reversed)
+		level_old = (br->count - 1) - level_old;
+	level_old = br->levels[level_old];
+
+set_level:
+	result = acpi_video_device_lcd_set_level(device, level_old);
+	if (result)
+		goto out_free_levels;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "found %d brightness levels\n", count - 2));
 	kfree(obj);
-	return max_level;
+	return result;
 
 out_free_levels:
 	kfree(br->levels);
@@ -712,7 +907,7 @@ out_free:
 out:
 	device->brightness = NULL;
 	kfree(obj);
-	return 0;
+	return result;
 }
 
 /*
@@ -729,7 +924,6 @@ out:
 static void acpi_video_device_find_cap(struct acpi_video_device *device)
 {
 	acpi_handle h_dummy1;
-	u32 max_level = 0;
 
 
 	memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +939,12 @@ static void acpi_video_device_find_cap(s
 	}
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
 		device->cap._BQC = 1;
+	else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+				&h_dummy1))) {
+		printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+		device->cap._BCQ = 1;
+	}
+
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
 		device->cap._DDC = 1;
 	}
@@ -758,13 +958,14 @@ static void acpi_video_device_find_cap(s
 		device->cap._DSS = 1;
 	}
 
-	if (acpi_video_backlight_support())
-		max_level = acpi_video_init_brightness(device);
-
-	if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+	if (acpi_video_backlight_support()) {
 		int result;
 		static int count = 0;
 		char *name;
+
+		result = acpi_video_init_brightness(device);
+		if (result)
+			return;
 		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
 		if (!name)
 			return;
@@ -773,18 +974,6 @@ static void acpi_video_device_find_cap(s
 		device->backlight = backlight_device_register(name,
 			NULL, device, &acpi_backlight_ops);
 		device->backlight->props.max_brightness = device->brightness->count-3;
-		/*
-		 * If there exists the _BQC object, the _BQC object will be
-		 * called to get the current backlight brightness. Otherwise
-		 * the brightness will be set to the maximum.
-		 */
-		if (device->cap._BQC)
-			device->backlight->props.brightness =
-				acpi_video_get_brightness(device->backlight);
-		else
-			device->backlight->props.brightness =
-				device->backlight->props.max_brightness;
-		backlight_update_status(device->backlight);
 		kfree(name);
 
 		device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1250,12 @@ acpi_video_device_write_brightness(struc
 	/* validate through the list of available levels */
 	for (i = 2; i < dev->brightness->count; i++)
 		if (level == dev->brightness->levels[i]) {
-			if (ACPI_SUCCESS
-			    (acpi_video_device_lcd_set_level(dev, level)))
-				dev->brightness->curr = level;
+			if (!acpi_video_device_lcd_set_level(dev, level))
+				return count;
 			break;
 		}
 
-	return count;
+	return -EINVAL;
 }
 
 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1125,8 +1313,6 @@ static int acpi_video_device_add_fs(stru
 	if (!device_dir)
 		return -ENOMEM;
 
-	device_dir->owner = THIS_MODULE;
-
 	/* 'info' [R] */
 	entry = proc_create_data("info", S_IRUGO, device_dir,
 			&acpi_video_device_info_fops, acpi_driver_data(device));
@@ -1134,7 +1320,6 @@ static int acpi_video_device_add_fs(stru
 		goto err_remove_dir;
 
 	/* 'state' [R/W] */
-	acpi_video_device_state_fops.write = acpi_video_device_write_state;
 	entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_device_state_fops,
@@ -1143,8 +1328,6 @@ static int acpi_video_device_add_fs(stru
 		goto err_remove_info;
 
 	/* 'brightness' [R/W] */
-	acpi_video_device_brightness_fops.write =
-		acpi_video_device_write_brightness;
 	entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_device_brightness_fops,
@@ -1403,8 +1586,6 @@ static int acpi_video_bus_add_fs(struct
 	if (!device_dir)
 		return -ENOMEM;
 
-	device_dir->owner = THIS_MODULE;
-
 	/* 'info' [R] */
 	entry = proc_create_data("info", S_IRUGO, device_dir,
 				 &acpi_video_bus_info_fops,
@@ -1427,7 +1608,6 @@ static int acpi_video_bus_add_fs(struct
 		goto err_remove_rom;
 
 	/* 'POST' [R/W] */
-	acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
 	entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_bus_POST_fops,
@@ -1436,7 +1616,6 @@ static int acpi_video_bus_add_fs(struct
 		goto err_remove_post_info;
 
 	/* 'DOS' [R/W] */
-	acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
 	entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_bus_DOS_fops,
@@ -1749,15 +1928,29 @@ acpi_video_get_next_level(struct acpi_vi
 	}
 }
 
-static void
+static int
 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 {
 	unsigned long long level_current, level_next;
+	int result = -EINVAL;
+
 	if (!device->brightness)
-		return;
-	acpi_video_device_lcd_get_level_current(device, &level_current);
+		goto out;
+
+	result = acpi_video_device_lcd_get_level_current(device,
+							 &level_current);
+	if (result)
+		goto out;
+
 	level_next = acpi_video_get_next_level(device, level_current, event);
-	acpi_video_device_lcd_set_level(device, level_next);
+
+	result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+	if (result)
+		printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+	return result;
 }
 
 static int
@@ -1850,17 +2043,15 @@ static int acpi_video_bus_stop_devices(s
 	return acpi_video_bus_DOS(video, 0, 1);
 }
 
-static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_video_bus *video = data;
-	struct acpi_device *device = NULL;
+	struct acpi_video_bus *video = acpi_driver_data(device);
 	struct input_dev *input;
 	int keycode;
 
 	if (!video)
 		return;
 
-	device = video->device;
 	input = video->input;
 
 	switch (event) {
@@ -1991,7 +2182,6 @@ static int acpi_video_resume(struct acpi
 
 static int acpi_video_bus_add(struct acpi_device *device)
 {
-	acpi_status status;
 	struct acpi_video_bus *video;
 	struct input_dev *input;
 	int error;
@@ -2033,20 +2223,10 @@ static int acpi_video_bus_add(struct acp
 	acpi_video_bus_get_devices(video, device);
 	acpi_video_bus_start_devices(video);
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_video_bus_notify, video);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX
-				  "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop_video;
-	}
-
 	video->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_stop_video;
 	}
 
 	snprintf(video->phys, sizeof(video->phys),
@@ -2082,9 +2262,6 @@ static int acpi_video_bus_add(struct acp
 
  err_free_input_dev:
 	input_free_device(input);
- err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_video_bus_notify);
  err_stop_video:
 	acpi_video_bus_stop_devices(video);
 	acpi_video_bus_put_devices(video);
@@ -2099,7 +2276,6 @@ static int acpi_video_bus_add(struct acp
 
 static int acpi_video_bus_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = 0;
 	struct acpi_video_bus *video = NULL;
 
 
@@ -2109,11 +2285,6 @@ static int acpi_video_bus_remove(struct
 	video = acpi_driver_data(device);
 
 	acpi_video_bus_stop_devices(video);
-
-	status = acpi_remove_notify_handler(video->device->handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_video_bus_notify);
-
 	acpi_video_bus_put_devices(video);
 	acpi_video_bus_remove_fs(device);
 
@@ -2124,14 +2295,33 @@ static int acpi_video_bus_remove(struct
 	return 0;
 }
 
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+	struct pci_dev *dev = NULL;
+	u32 address;
+
+	for_each_pci_dev(dev) {
+		if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+			continue;
+		if (dev->vendor != PCI_VENDOR_ID_INTEL)
+			continue;
+		pci_read_config_dword(dev, 0xfc, &address);
+		if (!address)
+			continue;
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+int acpi_video_register(void)
 {
 	int result = 0;
 
 	acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
 	if (!acpi_video_dir)
 		return -ENODEV;
-	acpi_video_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_video_bus);
 	if (result < 0) {
@@ -2141,8 +2331,26 @@ static int __init acpi_video_init(void)
 
 	return 0;
 }
+EXPORT_SYMBOL(acpi_video_register);
 
-static void __exit acpi_video_exit(void)
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+	dmi_check_system(video_dmi_table);
+
+	if (intel_opregion_present())
+		return 0;
+
+	return acpi_video_register();
+}
+
+void acpi_video_exit(void)
 {
 
 	acpi_bus_unregister_driver(&acpi_video_bus);
@@ -2151,6 +2359,7 @@ static void __exit acpi_video_exit(void)
 
 	return;
 }
+EXPORT_SYMBOL(acpi_video_exit);
 
 module_init(acpi_video_init);
 module_exit(acpi_video_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/video_detect.c linux-libre-2.6.30-gnu1/drivers/acpi/video_detect.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/video_detect.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/video_detect.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,6 +55,9 @@ acpi_backlight_cap_match(acpi_handle han
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
 				  "support\n"));
 		*cap |= ACPI_VIDEO_BACKLIGHT;
+		if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+			printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+					"control misses _BQC function\n");
 		/* We have backlight support, no need to scan further */
 		return AE_CTRL_TERMINATE;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/acpi/wakeup.c linux-libre-2.6.30-gnu1/drivers/acpi/wakeup.c
--- linux-libre-2.6.29-gnu1/drivers/acpi/wakeup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/acpi/wakeup.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,14 +8,18 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+
+#include "internal.h"
 #include "sleep.h"
 
+/*
+ * We didn't lock acpi_device_lock in the file, because it invokes oops in
+ * suspend/resume and isn't really required as this is called in S-state. At
+ * that time, there is no device hotplug
+ **/
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("wakeup_devices")
 
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
 /**
  * acpi_enable_wakeup_device_prep - prepare wakeup devices
  *	@sleep_state:	ACPI state
@@ -27,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 s
 {
 	struct list_head *node, *next;
 
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
 						       struct acpi_device,
@@ -38,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 s
 		    (sleep_state > (u32) dev->wakeup.sleep_state))
 			continue;
 
-		spin_unlock(&acpi_device_lock);
 		acpi_enable_wakeup_device_power(dev, sleep_state);
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -58,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_
 	 * Caution: this routine must be invoked when interrupt is disabled 
 	 * Refer ACPI2.0: P212
 	 */
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 			container_of(node, struct acpi_device, wakeup_list);
@@ -72,22 +71,17 @@ void acpi_enable_wakeup_device(u8 sleep_
 		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
-				spin_unlock(&acpi_device_lock);
 				/* set_gpe_type will disable GPE, leave it like that */
 				acpi_set_gpe_type(dev->wakeup.gpe_device,
 						  dev->wakeup.gpe_number,
 						  ACPI_GPE_TYPE_RUNTIME);
-				spin_lock(&acpi_device_lock);
 			}
 			continue;
 		}
-		spin_unlock(&acpi_device_lock);
 		if (!dev->wakeup.flags.run_wake)
 			acpi_enable_gpe(dev->wakeup.gpe_device,
 					dev->wakeup.gpe_number);
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
 /**
@@ -99,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep
 {
 	struct list_head *node, *next;
 
-	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 			container_of(node, struct acpi_device, wakeup_list);
@@ -110,19 +103,16 @@ void acpi_disable_wakeup_device(u8 sleep
 		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
-				spin_unlock(&acpi_device_lock);
 				acpi_set_gpe_type(dev->wakeup.gpe_device,
 						  dev->wakeup.gpe_number,
 						  ACPI_GPE_TYPE_WAKE_RUN);
 				/* Re-enable it, since set_gpe_type will disable it */
 				acpi_enable_gpe(dev->wakeup.gpe_device,
 						dev->wakeup.gpe_number);
-				spin_lock(&acpi_device_lock);
 			}
 			continue;
 		}
 
-		spin_unlock(&acpi_device_lock);
 		acpi_disable_wakeup_device_power(dev);
 		/* Never disable run-wake GPE */
 		if (!dev->wakeup.flags.run_wake) {
@@ -131,19 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep
 			acpi_clear_gpe(dev->wakeup.gpe_device,
 				       dev->wakeup.gpe_number, ACPI_NOT_ISR);
 		}
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
 }
 
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
 {
 	struct list_head *node, *next;
 
-	if (acpi_disabled)
-		return 0;
-
-	spin_lock(&acpi_device_lock);
+	mutex_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
 						       struct acpi_device,
@@ -151,17 +136,13 @@ static int __init acpi_wakeup_device_ini
 		/* In case user doesn't load button driver */
 		if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
 			continue;
-		spin_unlock(&acpi_device_lock);
 		acpi_set_gpe_type(dev->wakeup.gpe_device,
 				  dev->wakeup.gpe_number,
 				  ACPI_GPE_TYPE_WAKE_RUN);
 		acpi_enable_gpe(dev->wakeup.gpe_device,
 				dev->wakeup.gpe_number);
 		dev->wakeup.state.enabled = 1;
-		spin_lock(&acpi_device_lock);
 	}
-	spin_unlock(&acpi_device_lock);
+	mutex_unlock(&acpi_device_lock);
 	return 0;
 }
-
-late_initcall(acpi_wakeup_device_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/amba/bus.c linux-libre-2.6.30-gnu1/drivers/amba/bus.c
--- linux-libre-2.6.29-gnu1/drivers/amba/bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/amba/bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_dev
 	dev->dev.release = amba_device_release;
 	dev->dev.bus = &amba_bustype;
 	dev->dev.dma_mask = &dev->dma_mask;
-	dev->res.name = dev->dev.bus_id;
+	dev->res.name = dev_name(&dev->dev);
 
 	if (!dev->dev.coherent_dma_mask && dev->dma_mask)
 		dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device
 	if (d->parent)
 		r &= d->parent == dev->parent;
 	if (d->busid)
-		r &= strcmp(dev->bus_id, d->busid) == 0;
+		r &= strcmp(dev_name(dev), d->busid) == 0;
 
 	if (r) {
 		get_device(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/ahci.c linux-libre-2.6.30-gnu1/drivers/ata/ahci.c
--- linux-libre-2.6.29-gnu1/drivers/ata/ahci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/ahci.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,6 +78,7 @@ static ssize_t ahci_led_store(struct ata
 static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
 					ssize_t size);
 #define MAX_SLOTS 8
+#define MAX_RETRY 15
 
 enum {
 	AHCI_PCI_BAR		= 5,
@@ -113,6 +114,7 @@ enum {
 	board_ahci_sb700	= 5, /* for SB700 and SB800 */
 	board_ahci_mcp65	= 6,
 	board_ahci_nopmp	= 7,
+	board_ahci_yesncq	= 8,
 
 	/* global controller registers */
 	HOST_CAP		= 0x00, /* host capabilities */
@@ -218,6 +220,7 @@ enum {
 	AHCI_HFLAG_NO_HOTPLUG		= (1 << 7), /* ignore PxSERR.DIAG.N */
 	AHCI_HFLAG_SECT255		= (1 << 8), /* max 255 sectors */
 	AHCI_HFLAG_YES_NCQ		= (1 << 9), /* force NCQ cap on */
+	AHCI_HFLAG_NO_SUSPEND		= (1 << 10), /* don't suspend */
 
 	/* ap->flags bits */
 
@@ -404,7 +407,7 @@ static const struct ata_port_info ahci_p
 	/* board_ahci */
 	{
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
@@ -412,7 +415,7 @@ static const struct ata_port_info ahci_p
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_vt8251_ops,
 	},
@@ -420,7 +423,7 @@ static const struct ata_port_info ahci_p
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_IGN_IRQ_IF_ERR),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
@@ -430,7 +433,7 @@ static const struct ata_port_info ahci_p
 				 AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
 				 AHCI_HFLAG_SECT255),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_sb600_ops,
 	},
@@ -440,7 +443,7 @@ static const struct ata_port_info ahci_p
 				 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
@@ -448,7 +451,7 @@ static const struct ata_port_info ahci_p
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_IGN_SERR_INTERNAL),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_sb600_ops,
 	},
@@ -456,7 +459,7 @@ static const struct ata_port_info ahci_p
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_YES_NCQ),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
@@ -464,7 +467,15 @@ static const struct ata_port_info ahci_p
 	{
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_PMP),
 		.flags		= AHCI_FLAG_COMMON,
-		.pio_mask	= 0x1f, /* pio0-4 */
+		.pio_mask	= ATA_PIO4,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &ahci_ops,
+	},
+	/* board_ahci_yesncq */
+	{
+		AHCI_HFLAGS	(AHCI_HFLAG_YES_NCQ),
+		.flags		= AHCI_FLAG_COMMON,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_ops,
 	},
@@ -534,30 +545,30 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 },	/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 },	/* MCP65 */
 	{ PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 },	/* MCP65 */
-	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci },		/* MCP73 */
-	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci },		/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq },	/* MCP67 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_yesncq },	/* MCP73 */
+	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_yesncq },	/* MCP73 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci },		/* MCP77 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci },		/* MCP77 */
 	{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci },		/* MCP77 */
@@ -1115,6 +1126,8 @@ static void ahci_start_port(struct ata_p
 	struct ahci_port_priv *pp = ap->private_data;
 	struct ata_link *link;
 	struct ahci_em_priv *emp;
+	ssize_t rc;
+	int i;
 
 	/* enable FIS reception */
 	ahci_start_fis_rx(ap);
@@ -1126,7 +1139,17 @@ static void ahci_start_port(struct ata_p
 	if (ap->flags & ATA_FLAG_EM) {
 		ata_for_each_link(link, ap, EDGE) {
 			emp = &pp->em_priv[link->pmp];
-			ahci_transmit_led_message(ap, emp->led_state, 4);
+
+			/* EM Transmit bit maybe busy during init */
+			for (i = 0; i < MAX_RETRY; i++) {
+				rc = ahci_transmit_led_message(ap,
+							       emp->led_state,
+							       4);
+				if (rc == -EBUSY)
+					udelay(100);
+				else
+					break;
+			}
 		}
 	}
 
@@ -1331,7 +1354,7 @@ static ssize_t ahci_transmit_led_message
 	em_ctl = readl(mmio + HOST_EM_CTL);
 	if (em_ctl & EM_CTL_TM) {
 		spin_unlock_irqrestore(ap->lock, flags);
-		return -EINVAL;
+		return -EBUSY;
 	}
 
 	/*
@@ -1348,7 +1371,7 @@ static ssize_t ahci_transmit_led_message
 	writel(message[1], mmio + hpriv->em_loc+4);
 
 	/* save off new led state for port/slot */
-	emp->led_state = message[1];
+	emp->led_state = state;
 
 	/*
 	 * tell hardware to transmit the message
@@ -2294,9 +2317,17 @@ static int ahci_port_suspend(struct ata_
 static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
 	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ahci_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
 	u32 ctl;
 
+	if (mesg.event & PM_EVENT_SUSPEND &&
+	    hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
+		dev_printk(KERN_ERR, &pdev->dev,
+			   "BIOS update required for suspend/resume\n");
+		return -EIO;
+	}
+
 	if (mesg.event & PM_EVENT_SLEEP) {
 		/* AHCI spec rev1.1 section 8.3.3:
 		 * Software must disable interrupts prior to requesting a
@@ -2405,10 +2436,10 @@ static int ahci_configure_dma_masks(stru
 	int rc;
 
 	if (using_dac &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (rc) {
-			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (rc) {
 				dev_printk(KERN_ERR, &pdev->dev,
 					   "64-bit DMA enable failed\n");
@@ -2416,13 +2447,13 @@ static int ahci_configure_dma_masks(stru
 			}
 		}
 	} else {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit DMA enable failed\n");
 			return rc;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit consistent DMA enable failed\n");
@@ -2565,6 +2596,15 @@ static bool ahci_broken_system_poweroff(
 			/* PCI slot number of the controller */
 			.driver_data = (void *)0x1FUL,
 		},
+		{
+			.ident = "HP Compaq 6720s",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
+			},
+			/* PCI slot number of the controller */
+			.driver_data = (void *)0x1FUL,
+		},
 
 		{ }	/* terminate list */
 	};
@@ -2579,6 +2619,63 @@ static bool ahci_broken_system_poweroff(
 	return false;
 }
 
+static bool ahci_broken_suspend(struct pci_dev *pdev)
+{
+	static const struct dmi_system_id sysids[] = {
+		/*
+		 * On HP dv[4-6] and HDX18 with earlier BIOSen, link
+		 * to the harddisk doesn't become online after
+		 * resuming from STR.  Warn and fail suspend.
+		 */
+		{
+			.ident = "dv4",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME,
+					  "HP Pavilion dv4 Notebook PC"),
+			},
+			.driver_data = "F.30", /* cutoff BIOS version */
+		},
+		{
+			.ident = "dv5",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME,
+					  "HP Pavilion dv5 Notebook PC"),
+			},
+			.driver_data = "F.16", /* cutoff BIOS version */
+		},
+		{
+			.ident = "dv6",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME,
+					  "HP Pavilion dv6 Notebook PC"),
+			},
+			.driver_data = "F.21",	/* cutoff BIOS version */
+		},
+		{
+			.ident = "HDX18",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME,
+					  "HP HDX18 Notebook PC"),
+			},
+			.driver_data = "F.23",	/* cutoff BIOS version */
+		},
+		{ }	/* terminate list */
+	};
+	const struct dmi_system_id *dmi = dmi_first_match(sysids);
+	const char *ver;
+
+	if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
+		return false;
+
+	ver = dmi_get_system_info(DMI_BIOS_VERSION);
+
+	return !ver || strcmp(ver, dmi->driver_data) < 0;
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	static int printed_version;
@@ -2647,8 +2744,8 @@ static int ahci_init_one(struct pci_dev
 	if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
 		hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
 
-	if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
-		pci_intx(pdev, 1);
+	if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+		pci_enable_msi(pdev);
 
 	/* save initial config */
 	ahci_save_initial_config(pdev, hpriv);
@@ -2684,6 +2781,12 @@ static int ahci_init_one(struct pci_dev
 			"quirky BIOS, skipping spindown on poweroff\n");
 	}
 
+	if (ahci_broken_suspend(pdev)) {
+		hpriv->flags |= AHCI_HFLAG_NO_SUSPEND;
+		dev_printk(KERN_WARNING, &pdev->dev,
+			   "BIOS update required for suspend/resume\n");
+	}
+
 	/* CAP.NP sometimes indicate the index of the last enabled
 	 * port, at other times, that of the last possible port, so
 	 * determining the maximum port number requires looking at
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/ata_generic.c linux-libre-2.6.30-gnu1/drivers/ata/ata_generic.c
--- linux-libre-2.6.29-gnu1/drivers/ata/ata_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/ata_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -118,8 +118,8 @@ static int ata_generic_init_one(struct p
 	u16 command;
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &generic_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/ata_piix.c linux-libre-2.6.30-gnu1/drivers/ata/ata_piix.c
--- linux-libre-2.6.29-gnu1/drivers/ata/ata_piix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/ata_piix.c	2009-06-09 23:05:27.000000000 -0400
@@ -72,6 +72,7 @@
  *	ICH2    spec c #20	- IDE PRD must not cross a 64K boundary
  *				  and must be dword aligned
  *	ICH2    spec c #24	- UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ *	ICH7	errata #16	- MWDMA1 timings are incorrect
  *
  * Should have been BIOS fixed:
  *	450NX:	errata #19	- DMA hangs on old 450NX
@@ -94,7 +95,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME	"ata_piix"
-#define DRV_VERSION	"2.12"
+#define DRV_VERSION	"2.13"
 
 enum {
 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
@@ -136,6 +137,7 @@ enum piix_controller_ids {
 	ich_pata_33,		/* ICH up to UDMA 33 only */
 	ich_pata_66,		/* ICH up to 66 Mhz */
 	ich_pata_100,		/* ICH up to UDMA 100 */
+	ich_pata_100_nomwdma1,	/* ICH up to UDMA 100 but with no MWDMA1*/
 	ich5_sata,
 	ich6_sata,
 	ich6m_sata,
@@ -216,8 +218,8 @@ static const struct pci_device_id piix_p
 	/* ICH6 (and 6) (i915) UDMA 100 */
 	{ 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
 	/* ICH7/7-R (i945, i975) UDMA 100*/
-	{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
-	{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+	{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
+	{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
 	/* ICH8 Mobile PATA Controller */
 	{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
 
@@ -446,34 +448,34 @@ static struct ata_port_info piix_port_in
 	[piix_pata_mwdma] = 	/* PIIX3 MWDMA only */
 	{
 		.flags		= PIIX_PATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
 		.port_ops	= &piix_pata_ops,
 	},
 
 	[piix_pata_33] =	/* PIIX4 at 33MHz */
 	{
 		.flags		= PIIX_PATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
-		.udma_mask	= ATA_UDMA_MASK_40C,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+		.udma_mask	= ATA_UDMA2,
 		.port_ops	= &piix_pata_ops,
 	},
 
 	[ich_pata_33] = 	/* ICH0 - ICH at 33Mhz*/
 	{
 		.flags		= PIIX_PATA_FLAGS,
-		.pio_mask 	= 0x1f,	/* pio 0-4 */
-		.mwdma_mask	= 0x06, /* Check: maybe 0x07  */
-		.udma_mask	= ATA_UDMA2, /* UDMA33 */
+		.pio_mask 	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok  */
+		.udma_mask	= ATA_UDMA2,
 		.port_ops	= &ich_pata_ops,
 	},
 
 	[ich_pata_66] = 	/* ICH controllers up to 66MHz */
 	{
 		.flags		= PIIX_PATA_FLAGS,
-		.pio_mask 	= 0x1f,	/* pio 0-4 */
-		.mwdma_mask	= 0x06, /* MWDMA0 is broken on chip */
+		.pio_mask 	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */
 		.udma_mask	= ATA_UDMA4,
 		.port_ops	= &ich_pata_ops,
 	},
@@ -481,17 +483,26 @@ static struct ata_port_info piix_port_in
 	[ich_pata_100] =
 	{
 		.flags		= PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x06, /* mwdma1-2 */
-		.udma_mask	= ATA_UDMA5, /* udma0-5 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY,
+		.udma_mask	= ATA_UDMA5,
+		.port_ops	= &ich_pata_ops,
+	},
+
+	[ich_pata_100_nomwdma1] =
+	{
+		.flags		= PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2_ONLY,
+		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &ich_pata_ops,
 	},
 
 	[ich5_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -499,8 +510,8 @@ static struct ata_port_info piix_port_in
 	[ich6_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -508,8 +519,8 @@ static struct ata_port_info piix_port_in
 	[ich6m_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -517,8 +528,8 @@ static struct ata_port_info piix_port_in
 	[ich8_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -526,8 +537,8 @@ static struct ata_port_info piix_port_in
 	[ich8_2port_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -535,8 +546,8 @@ static struct ata_port_info piix_port_in
 	[tolapai_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -544,8 +555,8 @@ static struct ata_port_info piix_port_in
 	[ich8m_apple_sata] =
 	{
 		.flags		= PIIX_SATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &piix_sata_ops,
 	},
@@ -553,9 +564,9 @@ static struct ata_port_info piix_port_in
 	[piix_pata_vmw] =
 	{
 		.flags		= PIIX_PATA_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
-		.udma_mask	= ATA_UDMA_MASK_40C,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+		.udma_mask	= ATA_UDMA2,
 		.port_ops	= &piix_vmw_ops,
 	},
 
@@ -594,6 +605,7 @@ static const struct ich_laptop ich_lapto
 	{ 0x24CA, 0x1025, 0x003d },	/* ICH4 on ACER TM290 */
 	{ 0x266F, 0x1025, 0x0066 },	/* ICH6 on ACER Aspire 1694WLMi */
 	{ 0x2653, 0x1043, 0x82D8 },	/* ICH6M on Asus Eee 701 */
+	{ 0x27df, 0x104d, 0x900e },	/* ICH7 on Sony TZ-90 */
 	/* end marker */
 	{ 0, }
 };
@@ -1053,6 +1065,13 @@ static int piix_broken_suspend(void)
 				DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"),
 			},
 		},
+		{
+			.ident = "VGN-BX297XP",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-BX297XP"),
+			},
+		},
 
 		{ }	/* terminate list */
 	};
@@ -1435,6 +1454,15 @@ static bool piix_broken_system_poweroff(
 			},
 			/* PCI slot number of the controller */
 			.driver_data = (void *)0x1FUL,
+		},
+		{
+			.ident = "HP Compaq nc6000",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6000"),
+			},
+			/* PCI slot number of the controller */
+			.driver_data = (void *)0x1FUL,
 		},
 
 		{ }	/* terminate list */
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/Kconfig linux-libre-2.6.30-gnu1/drivers/ata/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/ata/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ config ATA_SFF
 
 	  For users with exclusively modern controllers like AHCI,
 	  Silicon Image 3124, or Marvell 6440, you may choose to
-	  disable this uneeded SFF support.
+	  disable this unneeded SFF support.
 
 	  If unsure, say Y.
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/libata-core.c linux-libre-2.6.30-gnu1/drivers/ata/libata-core.c
--- linux-libre-2.6.29-gnu1/drivers/ata/libata-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/libata-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,6 +57,7 @@
 #include <linux/scatterlist.h>
 #include <linux/io.h>
 #include <linux/async.h>
+#include <linux/log2.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -1230,6 +1231,9 @@ unsigned int ata_dev_classify(const stru
 	 *
 	 * We follow the current spec and consider that 0x69/0x96
 	 * identifies a port multiplier and 0x3c/0xc3 a SEMB device.
+	 * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports
+	 * SEMB signature.  This is worked around in
+	 * ata_dev_read_id().
 	 */
 	if ((tf->lbam == 0) && (tf->lbah == 0)) {
 		DPRINTK("found ATA device by sig\n");
@@ -1247,8 +1251,8 @@ unsigned int ata_dev_classify(const stru
 	}
 
 	if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) {
-		printk(KERN_INFO "ata: SEMB device ignored\n");
-		return ATA_DEV_SEMB_UNSUP; /* not yet */
+		DPRINTK("found SEMB device by sig (could be ATA device)\n");
+		return ATA_DEV_SEMB;
 	}
 
 	DPRINTK("unknown device\n");
@@ -1652,8 +1656,8 @@ unsigned long ata_id_xfermask(const u16
 		/*
 		 *	Process compact flash extended modes
 		 */
-		int pio = id[163] & 0x7;
-		int dma = (id[163] >> 3) & 7;
+		int pio = (id[ATA_ID_CFA_MODES] >> 0) & 0x7;
+		int dma = (id[ATA_ID_CFA_MODES] >> 3) & 0x7;
 
 		if (pio)
 			pio_mask |= (1 << 5);
@@ -2079,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *d
 	struct ata_taskfile tf;
 	unsigned int err_mask = 0;
 	const char *reason;
+	bool is_semb = class == ATA_DEV_SEMB;
 	int may_fallback = 1, tried_spinup = 0;
 	int rc;
 
@@ -2089,6 +2094,8 @@ retry:
 	ata_tf_init(dev, &tf);
 
 	switch (class) {
+	case ATA_DEV_SEMB:
+		class = ATA_DEV_ATA;	/* some hard drives report SEMB sig */
 	case ATA_DEV_ATA:
 		tf.command = ATA_CMD_ID_ATA;
 		break;
@@ -2125,6 +2132,14 @@ retry:
 			return -ENOENT;
 		}
 
+		if (is_semb) {
+			ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on "
+				       "device w/ SEMB sig, disabled\n");
+			/* SEMB is not supported yet */
+			*p_class = ATA_DEV_SEMB_UNSUP;
+			return 0;
+		}
+
 		if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
 			/* Device or controller might have reported
 			 * the wrong device class.  Give a shot at the
@@ -2389,6 +2404,7 @@ int ata_dev_configure(struct ata_device
 	dev->cylinders = 0;
 	dev->heads = 0;
 	dev->sectors = 0;
+	dev->multi_count = 0;
 
 	/*
 	 * common ATA, ATAPI feature tests
@@ -2410,7 +2426,8 @@ int ata_dev_configure(struct ata_device
 	/* ATA-specific feature tests */
 	if (dev->class == ATA_DEV_ATA) {
 		if (ata_id_is_cfa(id)) {
-			if (id[162] & 1) /* CPRM may make this media unusable */
+			/* CPRM may make this media unusable */
+			if (id[ATA_ID_CFA_KEY_MGMT] & 1)
 				ata_dev_printk(dev, KERN_WARNING,
 					       "supports DRM functions and may "
 					       "not be fully accessable.\n");
@@ -2426,8 +2443,15 @@ int ata_dev_configure(struct ata_device
 
 		dev->n_sectors = ata_id_n_sectors(id);
 
-		if (dev->id[59] & 0x100)
-			dev->multi_count = dev->id[59] & 0xff;
+		/* get current R/W Multiple count setting */
+		if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) {
+			unsigned int max = dev->id[47] & 0xff;
+			unsigned int cnt = dev->id[59] & 0xff;
+			/* only recognize/allow powers of two here */
+			if (is_power_of_2(max) && is_power_of_2(cnt))
+				if (cnt <= max)
+					dev->multi_count = cnt;
+		}
 
 		if (ata_id_has_lba(id)) {
 			const char *lba_desc;
@@ -4067,7 +4091,9 @@ int ata_dev_revalidate(struct ata_device
 
 	/* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */
 	if (ata_class_enabled(new_class) &&
-	    new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATAPI) {
+	    new_class != ATA_DEV_ATA &&
+	    new_class != ATA_DEV_ATAPI &&
+	    new_class != ATA_DEV_SEMB) {
 		ata_dev_printk(dev, KERN_INFO, "class mismatch %u != %u\n",
 			       dev->class, new_class);
 		rc = -ENODEV;
@@ -6101,13 +6127,11 @@ int ata_host_register(struct ata_host *h
 			ata_port_printk(ap, KERN_INFO, "DUMMY\n");
 	}
 
-	/* perform each probe synchronously */
-	DPRINTK("probe begin\n");
+	/* perform each probe asynchronously */
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 		async_schedule(async_port_probe, ap);
 	}
-	DPRINTK("probe end\n");
 
 	return 0;
 }
@@ -6709,6 +6733,7 @@ EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
+EXPORT_SYMBOL_GPL(ata_pio_queue_task);
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
 EXPORT_SYMBOL_GPL(ata_timing_find_mode);
 EXPORT_SYMBOL_GPL(ata_timing_compute);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/libata-eh.c linux-libre-2.6.30-gnu1/drivers/ata/libata-eh.c
--- linux-libre-2.6.29-gnu1/drivers/ata/libata-eh.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/libata-eh.c	2009-06-09 23:05:27.000000000 -0400
@@ -547,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *ho
 
 	/* For new EH, all qcs are finished in one of three ways -
 	 * normal completion, error completion, and SCSI timeout.
-	 * Both cmpletions can race against SCSI timeout.  When normal
+	 * Both completions can race against SCSI timeout.  When normal
 	 * completion wins, the qc never reaches EH.  When error
 	 * completion wins, the qc has ATA_QCFLAG_FAILED set.
 	 *
@@ -562,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *ho
 		int nr_timedout = 0;
 
 		spin_lock_irqsave(ap->lock, flags);
+		
+		/* This must occur under the ap->lock as we don't want
+		   a polled recovery to race the real interrupt handler
+		   
+		   The lost_interrupt handler checks for any completed but
+		   non-notified command and completes much like an IRQ handler.
+		   
+		   We then fall into the error recovery code which will treat
+		   this as if normal completion won the race */
 
+		if (ap->ops->lost_interrupt)
+			ap->ops->lost_interrupt(ap);
+			
 		list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
 			struct ata_queued_cmd *qc;
 
@@ -606,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *ho
 		ap->eh_tries = ATA_EH_MAX_TRIES;
 	} else
 		spin_unlock_wait(ap->lock);
+		
+	/* If we timed raced normal completion and there is nothing to
+	   recover nr_timedout == 0 why exactly are we doing error recovery ? */
 
  repeat:
 	/* invoke error handler */
@@ -2768,6 +2783,12 @@ static int ata_eh_revalidate_and_attach(
 		} else if (dev->class == ATA_DEV_UNKNOWN &&
 			   ehc->tries[dev->devno] &&
 			   ata_class_enabled(ehc->classes[dev->devno])) {
+			/* Temporarily set dev->class, it will be
+			 * permanently set once all configurations are
+			 * complete.  This is necessary because new
+			 * device configuration is done in two
+			 * separate loops.
+			 */
 			dev->class = ehc->classes[dev->devno];
 
 			if (dev->class == ATA_DEV_PMP)
@@ -2775,6 +2796,11 @@ static int ata_eh_revalidate_and_attach(
 			else
 				rc = ata_dev_read_id(dev, &dev->class,
 						     readid_flags, dev->id);
+
+			/* read_id might have changed class, store and reset */
+			ehc->classes[dev->devno] = dev->class;
+			dev->class = ATA_DEV_UNKNOWN;
+
 			switch (rc) {
 			case 0:
 				/* clear error info accumulated during probe */
@@ -2784,13 +2810,11 @@ static int ata_eh_revalidate_and_attach(
 			case -ENOENT:
 				/* IDENTIFY was issued to non-existent
 				 * device.  No need to reset.  Just
-				 * thaw and kill the device.
+				 * thaw and ignore the device.
 				 */
 				ata_eh_thaw_port(ap);
-				dev->class = ATA_DEV_UNKNOWN;
 				break;
 			default:
-				dev->class = ATA_DEV_UNKNOWN;
 				goto err;
 			}
 		}
@@ -2811,11 +2835,15 @@ static int ata_eh_revalidate_and_attach(
 		    dev->class == ATA_DEV_PMP)
 			continue;
 
+		dev->class = ehc->classes[dev->devno];
+
 		ehc->i.flags |= ATA_EHI_PRINTINFO;
 		rc = ata_dev_configure(dev);
 		ehc->i.flags &= ~ATA_EHI_PRINTINFO;
-		if (rc)
+		if (rc) {
+			dev->class = ATA_DEV_UNKNOWN;
 			goto err;
+		}
 
 		spin_lock_irqsave(ap->lock, flags);
 		ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
@@ -3479,6 +3507,8 @@ static void ata_eh_handle_port_suspend(s
  */
 static void ata_eh_handle_port_resume(struct ata_port *ap)
 {
+	struct ata_link *link;
+	struct ata_device *dev;
 	unsigned long flags;
 	int rc = 0;
 
@@ -3493,6 +3523,17 @@ static void ata_eh_handle_port_resume(st
 
 	WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
 
+	/*
+	 * Error timestamps are in jiffies which doesn't run while
+	 * suspended and PHY events during resume isn't too uncommon.
+	 * When the two are combined, it can lead to unnecessary speed
+	 * downs if the machine is suspended and resumed repeatedly.
+	 * Clear error history.
+	 */
+	ata_for_each_link(link, ap, HOST_FIRST)
+		ata_for_each_dev(dev, link, ALL)
+			ata_ering_clear(&dev->ering);
+
 	ata_acpi_set_state(ap, PMSG_ON);
 
 	if (ap->ops->port_resume)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/libata.h linux-libre-2.6.30-gnu1/drivers/ata/libata.h
--- linux-libre-2.6.29-gnu1/drivers/ata/libata.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/libata.h	2009-06-09 23:05:27.000000000 -0400
@@ -79,8 +79,6 @@ extern int ata_build_rw_tf(struct ata_ta
 			   u64 block, u32 n_block, unsigned int tf_flags,
 			   unsigned int tag);
 extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
-extern void ata_pio_queue_task(struct ata_port *ap, void *data,
-			       unsigned long delay);
 extern void ata_port_flush_task(struct ata_port *ap);
 extern unsigned ata_exec_internal(struct ata_device *dev,
 				  struct ata_taskfile *tf, const u8 *cdb,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/libata-scsi.c linux-libre-2.6.30-gnu1/drivers/ata/libata-scsi.c
--- linux-libre-2.6.29-gnu1/drivers/ata/libata-scsi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/libata-scsi.c	2009-06-09 23:05:27.000000000 -0400
@@ -313,7 +313,7 @@ ata_scsi_em_message_show(struct device *
 		return ap->ops->em_show(ap, buf);
 	return -EINVAL;
 }
-DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO,
+DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR,
 		ata_scsi_em_message_show, ata_scsi_em_message_store);
 EXPORT_SYMBOL_GPL(dev_attr_em_message);
 
@@ -366,7 +366,7 @@ ata_scsi_activity_store(struct device *d
 	}
 	return -EINVAL;
 }
-DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
+DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show,
 			ata_scsi_activity_store);
 EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
 
@@ -647,23 +647,45 @@ int ata_task_ioctl(struct scsi_device *s
 	return rc;
 }
 
+static int ata_ioc32(struct ata_port *ap)
+{
+	if (ap->flags & ATA_FLAG_PIO_DMA)
+		return 1;
+	if (ap->pflags & ATA_PFLAG_PIO32)
+		return 1;
+	return 0;
+}
+
 int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
 		     int cmd, void __user *arg)
 {
 	int val = -EINVAL, rc = -EINVAL;
+	unsigned long flags;
 
 	switch (cmd) {
 	case ATA_IOC_GET_IO32:
-		val = 0;
+		spin_lock_irqsave(ap->lock, flags);
+		val = ata_ioc32(ap);
+		spin_unlock_irqrestore(ap->lock, flags);
 		if (copy_to_user(arg, &val, 1))
 			return -EFAULT;
 		return 0;
 
 	case ATA_IOC_SET_IO32:
 		val = (unsigned long) arg;
-		if (val != 0)
-			return -EINVAL;
-		return 0;
+		rc = 0;
+		spin_lock_irqsave(ap->lock, flags);
+		if (ap->pflags & ATA_PFLAG_PIO32CHANGE) {
+			if (val)
+				ap->pflags |= ATA_PFLAG_PIO32;
+			else
+				ap->pflags &= ~ATA_PFLAG_PIO32;
+		} else {
+			if (val != ata_ioc32(ap))
+				rc = -EINVAL;
+		}
+		spin_unlock_irqrestore(ap->lock, flags);
+		return rc;
 
 	case HDIO_GET_IDENTITY:
 		return ata_get_identity(ap, scsidev, arg);
@@ -2120,13 +2142,14 @@ static unsigned int ata_scsiop_inq_89(st
 
 static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
 {
+	int form_factor = ata_id_form_factor(args->id);
+	int media_rotation_rate = ata_id_rotation_rate(args->id);
+
 	rbuf[1] = 0xb1;
 	rbuf[3] = 0x3c;
-	if (ata_id_major_version(args->id) > 7) {
-		rbuf[4] = args->id[217] >> 8;
-		rbuf[5] = args->id[217];
-		rbuf[7] = args->id[168] & 0xf;
-	}
+	rbuf[4] = media_rotation_rate >> 8;
+	rbuf[5] = media_rotation_rate;
+	rbuf[7] = form_factor;
 
 	return 0;
 }
@@ -2354,7 +2377,23 @@ saving_not_supp:
  */
 static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
 {
-	u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
+	struct ata_device *dev = args->dev;
+	u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
+	u8 log_per_phys = 0;
+	u16 lowest_aligned = 0;
+	u16 word_106 = dev->id[106];
+	u16 word_209 = dev->id[209];
+
+	if ((word_106 & 0xc000) == 0x4000) {
+		/* Number and offset of logical sectors per physical sector */
+		if (word_106 & (1 << 13))
+			log_per_phys = word_106 & 0xf;
+		if ((word_209 & 0xc000) == 0x4000) {
+			u16 first = dev->id[209] & 0x3fff;
+			if (first > 0)
+				lowest_aligned = (1 << log_per_phys) - first;
+		}
+	}
 
 	VPRINTK("ENTER\n");
 
@@ -2385,6 +2424,11 @@ static unsigned int ata_scsiop_read_cap(
 		/* sector size */
 		rbuf[10] = ATA_SECT_SIZE >> 8;
 		rbuf[11] = ATA_SECT_SIZE & 0xff;
+
+		rbuf[12] = 0;
+		rbuf[13] = log_per_phys;
+		rbuf[14] = (lowest_aligned >> 8) & 0x3f;
+		rbuf[15] = lowest_aligned;
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/libata-sff.c linux-libre-2.6.30-gnu1/drivers/ata/libata-sff.c
--- linux-libre-2.6.29-gnu1/drivers/ata/libata-sff.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/libata-sff.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff
 	.softreset		= ata_sff_softreset,
 	.hardreset		= sata_sff_hardreset,
 	.postreset		= ata_sff_postreset,
+	.drain_fifo		= ata_sff_drain_fifo,
 	.error_handler		= ata_sff_error_handler,
 	.post_internal_cmd	= ata_sff_post_internal_cmd,
 
@@ -64,6 +65,8 @@ const struct ata_port_operations ata_sff
 	.sff_irq_on		= ata_sff_irq_on,
 	.sff_irq_clear		= ata_sff_irq_clear,
 
+	.lost_interrupt		= ata_sff_lost_interrupt,
+
 	.port_start		= ata_sff_port_start,
 };
 EXPORT_SYMBOL_GPL(ata_sff_port_ops);
@@ -84,6 +87,7 @@ const struct ata_port_operations ata_bmd
 	.inherits		= &ata_bmdma_port_ops,
 
 	.sff_data_xfer		= ata_sff_data_xfer32,
+	.port_start		= ata_sff_port_start32,
 };
 EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
 
@@ -766,6 +770,9 @@ 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);
 
 	/* Transfer multiple of 4 bytes */
 	if (rw == READ)
@@ -1646,7 +1653,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
  *	RETURNS:
  *	One if interrupt was handled, zero if not (shared irq).
  */
-inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+unsigned int ata_sff_host_intr(struct ata_port *ap,
 				      struct ata_queued_cmd *qc)
 {
 	struct ata_eh_info *ehi = &ap->link.eh_info;
@@ -1775,6 +1782,48 @@ irqreturn_t ata_sff_interrupt(int irq, v
 EXPORT_SYMBOL_GPL(ata_sff_interrupt);
 
 /**
+ *	ata_sff_lost_interrupt	-	Check for an apparent lost interrupt
+ *	@ap: port that appears to have timed out
+ *
+ *	Called from the libata error handlers when the core code suspects
+ *	an interrupt has been lost. If it has complete anything we can and
+ *	then return. Interface must support altstatus for this faster
+ *	recovery to occur.
+ *
+ *	Locking:
+ *	Caller holds host lock
+ */
+
+void ata_sff_lost_interrupt(struct ata_port *ap)
+{
+	u8 status;
+	struct ata_queued_cmd *qc;
+
+	/* Only one outstanding command per SFF channel */
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
+	/* Check we have a live one.. */
+	if (qc == NULL ||  !(qc->flags & ATA_QCFLAG_ACTIVE))
+		return;
+	/* We cannot lose an interrupt on a polled command */
+	if (qc->tf.flags & ATA_TFLAG_POLLING)
+		return;
+	/* See if the controller thinks it is still busy - if so the command
+	   isn't a lost IRQ but is still in progress */
+	status = ata_sff_altstatus(ap);
+	if (status & ATA_BUSY)
+		return;
+
+	/* There was a command running, we are no longer busy and we have
+	   no interrupt. */
+	ata_port_printk(ap, KERN_WARNING, "lost interrupt (Status 0x%x)\n",
+								status);
+	/* Run the host interrupt logic as if the interrupt had not been
+	   lost */
+	ata_sff_host_intr(ap, qc);
+}
+EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
+
+/**
  *	ata_sff_freeze - Freeze SFF controller port
  *	@ap: port to freeze
  *
@@ -2199,6 +2248,39 @@ void ata_sff_postreset(struct ata_link *
 EXPORT_SYMBOL_GPL(ata_sff_postreset);
 
 /**
+ *	ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers
+ *	@qc: command
+ *
+ *	Drain the FIFO and device of any stuck data following a command
+ *	failing to complete. In some cases this is neccessary before a
+ *	reset will recover the device.
+ *
+ */
+
+void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
+{
+	int count;
+	struct ata_port *ap;
+
+	/* We only need to flush incoming data when a command was running */
+	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+		return;
+
+	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++)
+		ioread16(ap->ioaddr.data_addr);
+
+	/* Can become DEBUG later */
+	if (count)
+		ata_port_printk(ap, KERN_DEBUG,
+			"drained %d bytes to clear DRQ.\n", count);
+
+}
+EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
+
+/**
  *	ata_sff_error_handler - Stock error handler for BMDMA controller
  *	@ap: port to handle error for
  *
@@ -2239,7 +2321,8 @@ void ata_sff_error_handler(struct ata_po
 		 * really a timeout event, adjust error mask and
 		 * cancel frozen state.
 		 */
-		if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+		if (qc->err_mask == AC_ERR_TIMEOUT
+						&& (host_stat & ATA_DMA_ERR)) {
 			qc->err_mask = AC_ERR_HOST_BUS;
 			thaw = 1;
 		}
@@ -2250,6 +2333,13 @@ void ata_sff_error_handler(struct ata_po
 	ata_sff_sync(ap);		/* FIXME: We don't need this */
 	ap->ops->sff_check_status(ap);
 	ap->ops->sff_irq_clear(ap);
+	/* We *MUST* do FIFO draining before we issue a reset as several
+	 * devices helpfully clear their internal state and will lock solid
+	 * if we touch the data port post reset. Pass qc in case anyone wants
+	 *  to do different PIO/DMA recovery or has per command fixups
+	 */
+	if (ap->ops->drain_fifo)
+		ap->ops->drain_fifo(qc);
 
 	spin_unlock_irqrestore(ap->lock, flags);
 
@@ -2316,6 +2406,29 @@ int ata_sff_port_start(struct ata_port *
 EXPORT_SYMBOL_GPL(ata_sff_port_start);
 
 /**
+ *	ata_sff_port_start32 - Set port up for dma.
+ *	@ap: Port to initialize
+ *
+ *	Called just after data structures for each port are
+ *	initialized.  Allocates space for PRD table if the device
+ *	is DMA capable SFF.
+ *
+ *	May be used as the port_start() entry in ata_port_operations for
+ *	devices that are capable of 32bit PIO.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+int ata_sff_port_start32(struct ata_port *ap)
+{
+	ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
+	if (ap->ioaddr.bmdma_addr)
+		return ata_port_start(ap);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ata_sff_port_start32);
+
+/**
  *	ata_sff_std_ports - initialize ioaddr with standard port offsets.
  *	@ioaddr: IO address structure to be initialized
  *
@@ -2959,4 +3072,3 @@ out:
 EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
 
 #endif /* CONFIG_PCI */
-
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_acpi.c linux-libre-2.6.30-gnu1/drivers/ata/pata_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -246,9 +246,9 @@ static int pacpi_init_one (struct pci_de
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
 
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
-		.udma_mask 	= 0x7f,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask 	= ATA_UDMA6,
 
 		.port_ops	= &pacpi_ops,
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_ali.c linux-libre-2.6.30-gnu1/drivers/ata/pata_ali.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_ali.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_ali.c	2009-06-09 23:05:27.000000000 -0400
@@ -492,53 +492,58 @@ static int ali_init_one(struct pci_dev *
 {
 	static const struct ata_port_info info_early = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &ali_early_port_ops
 	};
 	/* Revision 0x20 added DMA */
 	static const struct ata_port_info info_20 = {
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 |
+							ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &ali_20_port_ops
 	};
 	/* Revision 0x20 with support logic added UDMA */
 	static const struct ata_port_info info_20_udma = {
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
-		.udma_mask = 0x07,	/* UDMA33 */
+		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 |
+							ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
 		.port_ops = &ali_20_port_ops
 	};
 	/* Revision 0xC2 adds UDMA66 */
 	static const struct ata_port_info info_c2 = {
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 |
+							ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA4,
 		.port_ops = &ali_c2_port_ops
 	};
 	/* Revision 0xC3 is UDMA66 for now */
 	static const struct ata_port_info info_c3 = {
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 |
+							ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA4,
 		.port_ops = &ali_c2_port_ops
 	};
 	/* Revision 0xC4 is UDMA100 */
 	static const struct ata_port_info info_c4 = {
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 |
+							ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &ali_c4_port_ops
 	};
 	/* Revision 0xC5 is UDMA133 with LBA48 DMA */
 	static const struct ata_port_info info_c5 = {
-		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.flags = ATA_FLAG_SLAVE_POSS | 	ATA_FLAG_IGN_SIMPLEX,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &ali_c5_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_amd.c linux-libre-2.6.30-gnu1/drivers/ata/pata_amd.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_amd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_amd.c	2009-06-09 23:05:27.000000000 -0400
@@ -455,74 +455,74 @@ static void amd_clear_fifo(struct pci_de
 static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	static const struct ata_port_info info[10] = {
-		{	/* 0: AMD 7401 */
+		{	/* 0: AMD 7401 - no swdma */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,	/* No SWDMA */
-			.udma_mask = 0x07,	/* UDMA 33 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA2,
 			.port_ops = &amd33_port_ops
 		},
 		{	/* 1: Early AMD7409 - no swdma */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA4,	/* UDMA 66 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA4,
 			.port_ops = &amd66_port_ops
 		},
-		{	/* 2: AMD 7409, no swdma errata */
+		{	/* 2: AMD 7409 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA4,	/* UDMA 66 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA4,
 			.port_ops = &amd66_port_ops
 		},
 		{	/* 3: AMD 7411 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA5,	/* UDMA 100 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA5,
 			.port_ops = &amd100_port_ops
 		},
 		{	/* 4: AMD 7441 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA5,	/* UDMA 100 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA5,
 			.port_ops = &amd100_port_ops
 		},
-		{	/* 5: AMD 8111*/
+		{	/* 5: AMD 8111 - no swdma */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA6,	/* UDMA 133, no swdma */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA6,
 			.port_ops = &amd133_port_ops
 		},
-		{	/* 6: AMD 8111 UDMA 100 (Serenade) */
+		{	/* 6: AMD 8111 UDMA 100 (Serenade) - no swdma */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA5,	/* UDMA 100, no swdma */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA5,
 			.port_ops = &amd133_port_ops
 		},
 		{	/* 7: Nvidia Nforce */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA5,	/* UDMA 100 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA5,
 			.port_ops = &nv100_port_ops
 		},
-		{	/* 8: Nvidia Nforce2 and later */
+		{	/* 8: Nvidia Nforce2 and later - no swdma */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA6,	/* UDMA 133, no swdma */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA6,
 			.port_ops = &nv133_port_ops
 		},
 		{	/* 9: AMD CS5536 (Geode companion) */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = ATA_UDMA5,	/* UDMA 100 */
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA5,
 			.port_ops = &amd100_port_ops
 		}
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_artop.c linux-libre-2.6.30-gnu1/drivers/ata/pata_artop.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_artop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_artop.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,6 @@
  *		performance Alessandro Zummo <alessandro.zummo@towertech.it>
  *
  *	TODO
- *	850 serialization once the core supports it
  *	Investigate no_dsc on 850R
  *	Clock detect
  */
@@ -29,7 +28,7 @@
 #include <linux/ata.h>
 
 #define DRV_NAME	"pata_artop"
-#define DRV_VERSION	"0.4.4"
+#define DRV_VERSION	"0.4.5"
 
 /*
  *	The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -283,6 +282,31 @@ static void artop6260_set_dmamode (struc
 	pci_write_config_byte(pdev, 0x44 + ap->port_no, ultra);
 }
 
+/**
+ *	artop_6210_qc_defer	-	implement serialization
+ *	@qc: command
+ *
+ *	Issue commands per host on this chip.
+ */
+
+static int artop6210_qc_defer(struct ata_queued_cmd *qc)
+{
+	struct ata_host *host = qc->ap->host;
+	struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+	int rc;
+
+	/* First apply the usual rules */
+	rc = ata_std_qc_defer(qc);
+	if (rc != 0)
+		return rc;
+
+	/* Now apply serialization rules. Only allow a command if the
+	   other channel state machine is idle */
+	if (alt && alt->qc_active)
+		return	ATA_DEFER_PORT;
+	return 0;
+}
+
 static struct scsi_host_template artop_sht = {
 	ATA_BMDMA_SHT(DRV_NAME),
 };
@@ -293,6 +317,7 @@ static struct ata_port_operations artop6
 	.set_piomode		= artop6210_set_piomode,
 	.set_dmamode		= artop6210_set_dmamode,
 	.prereset		= artop6210_pre_reset,
+	.qc_defer		= artop6210_qc_defer,
 };
 
 static struct ata_port_operations artop6260_ops = {
@@ -323,29 +348,29 @@ static int artop_init_one (struct pci_de
 	static int printed_version;
 	static const struct ata_port_info info_6210 = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA2,
 		.port_ops	= &artop6210_ops,
 	};
 	static const struct ata_port_info info_626x = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA4,
 		.port_ops	= &artop6260_ops,
 	};
 	static const struct ata_port_info info_628x = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA5,
 		.port_ops	= &artop6260_ops,
 	};
 	static const struct ata_port_info info_628x_fast = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA6,
 		.port_ops	= &artop6260_ops,
 	};
@@ -362,12 +387,8 @@ static int artop_init_one (struct pci_de
 
 	if (id->driver_data == 0) {	/* 6210 variant */
 		ppi[0] = &info_6210;
-		ppi[1] = &ata_dummy_port_info;
 		/* BIOS may have left us in UDMA, clear it before libata probe */
 		pci_write_config_byte(pdev, 0x54, 0);
-		/* For the moment (also lacks dsc) */
-		printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
-		printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
 	}
 	else if (id->driver_data == 1)	/* 6260 */
 		ppi[0] = &info_626x;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_at32.c linux-libre-2.6.30-gnu1/drivers/ata/pata_at32.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_at32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_at32.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,7 +67,9 @@
  *
  * Alter PIO_MASK below according to table to set maximal PIO mode.
  */
-#define PIO_MASK (0x1f)
+enum {
+  PIO_MASK = ATA_PIO4,
+};
 
 /*
  * Struct containing private information about device.
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_atiixp.c linux-libre-2.6.30-gnu1/drivers/ata/pata_atiixp.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_atiixp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_atiixp.c	2009-06-09 23:05:27.000000000 -0400
@@ -220,9 +220,9 @@ static int atiixp_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x06,	/* No MWDMA0 support */
-		.udma_mask = 0x3F,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA12_ONLY,
+		.udma_mask = ATA_UDMA5,
 		.port_ops = &atiixp_port_ops
 	};
 	static const struct pci_bits atiixp_enable_bits[] = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_bf54x.c linux-libre-2.6.30-gnu1/drivers/ata/pata_bf54x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_bf54x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_bf54x.c	2009-06-09 23:05:27.000000000 -0400
@@ -1502,7 +1502,7 @@ static struct ata_port_info bfin_port_in
 		.flags		= ATA_FLAG_SLAVE_POSS
 				| ATA_FLAG_MMIO
 				| ATA_FLAG_NO_LEGACY,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= 0,
 		.udma_mask	= 0,
 		.port_ops	= &bfin_pata_ops,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cmd640.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cmd640.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cmd640.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cmd640.c	2009-06-09 23:05:27.000000000 -0400
@@ -211,7 +211,7 @@ static int cmd640_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &cmd640_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cmd64x.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cmd64x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cmd64x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cmd64x.c	2009-06-09 23:05:27.000000000 -0400
@@ -299,40 +299,40 @@ static int cmd64x_init_one(struct pci_de
 	static const struct ata_port_info cmd_info[6] = {
 		{	/* CMD 643 - no UDMA */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.port_ops = &cmd64x_port_ops
 		},
 		{	/* CMD 646 with broken UDMA */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.port_ops = &cmd64x_port_ops
 		},
 		{	/* CMD 646 with working UDMA */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA2,
 			.port_ops = &cmd64x_port_ops
 		},
 		{	/* CMD 646 rev 1  */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.port_ops = &cmd646r1_port_ops
 		},
 		{	/* CMD 648 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA4,
 			.port_ops = &cmd648_port_ops
 		},
 		{	/* CMD 649 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA5,
 			.port_ops = &cmd648_port_ops
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5520.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5520.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5520.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5520.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,7 +158,7 @@ static int __devinit cs5520_init_one(str
 	static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
 	struct ata_port_info pi = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,
+		.pio_mask	= ATA_PIO4,
 		.port_ops	= &cs5520_port_ops,
 	};
 	const struct ata_port_info *ppi[2];
@@ -203,11 +203,11 @@ static int __devinit cs5520_init_one(str
 		return -ENODEV;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
 		return -ENODEV;
 	}
-	if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
 		return -ENODEV;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5530.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5530.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5530.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5530.c	2009-06-09 23:05:27.000000000 -0400
@@ -298,15 +298,15 @@ static int cs5530_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
-		.udma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
 		.port_ops = &cs5530_port_ops
 	};
 	/* The docking connector doesn't do UDMA, and it seems not MWDMA */
 	static const struct ata_port_info info_palmax_secondary = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &cs5530_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5535.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5535.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5535.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5535.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,8 +181,8 @@ static int cs5535_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA4,
 		.port_ops = &cs5535_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5536.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5536.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cs5536.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cs5536.c	2009-06-09 23:05:27.000000000 -0400
@@ -241,8 +241,8 @@ static int cs5536_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &cs5536_port_ops,
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_cypress.c linux-libre-2.6.30-gnu1/drivers/ata/pata_cypress.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_cypress.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_cypress.c	2009-06-09 23:05:27.000000000 -0400
@@ -124,8 +124,8 @@ static int cy82c693_init_one(struct pci_
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &cy82c693_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_efar.c linux-libre-2.6.30-gnu1/drivers/ata/pata_efar.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_efar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_efar.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/ata.h>
 
 #define DRV_NAME	"pata_efar"
-#define DRV_VERSION	"0.4.4"
+#define DRV_VERSION	"0.4.5"
 
 /**
  *	efar_pre_reset	-	Enable bits
@@ -98,18 +98,17 @@ static void efar_set_piomode (struct ata
 			    { 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;	/* IE enable */
-	/* Intel specifies that the PPE functionality is for disk only */
+		control |= 2;	/* IE */
+	/* Intel specifies that the prefetch/posting is for disk only */
 	if (adev->class == ATA_DEV_ATA)
-		control |= 4;	/* PPE enable */
+		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;
@@ -129,7 +128,7 @@ static void efar_set_piomode (struct ata
 		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);
 }
 
@@ -251,9 +250,9 @@ static int efar_init_one (struct pci_dev
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma1-2 */
-		.udma_mask 	= 0x0f, /* UDMA 66 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask 	= ATA_UDMA4,
 		.port_ops	= &efar_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt366.c linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt366.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt366.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt366.c	2009-06-09 23:05:27.000000000 -0400
@@ -336,8 +336,8 @@ static int hpt36x_init_one(struct pci_de
 {
 	static const struct ata_port_info info_hpt366 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA4,
 		.port_ops = &hpt366_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt37x.c linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt37x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt37x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt37x.c	2009-06-09 23:05:27.000000000 -0400
@@ -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
  *	Look into engine reset on timeout errors. Should not be	required.
@@ -24,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt37x"
-#define DRV_VERSION	"0.6.11"
+#define DRV_VERSION	"0.6.12"
 
 struct hpt_clock {
 	u8	xfer_speed;
@@ -445,23 +445,6 @@ static void hpt370_set_dmamode(struct at
 }
 
 /**
- *	hpt370_bmdma_start		-	DMA engine begin
- *	@qc: ATA command
- *
- *	The 370 and 370A want us to reset the DMA engine each time we
- *	use it. The 372 and later are fine.
- */
-
-static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
-{
-	struct ata_port *ap = qc->ap;
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
-	udelay(10);
-	ata_bmdma_start(qc);
-}
-
-/**
  *	hpt370_bmdma_end		-	DMA engine stop
  *	@qc: ATA command
  *
@@ -598,7 +581,6 @@ static struct scsi_host_template hpt37x_
 static struct ata_port_operations hpt370_port_ops = {
 	.inherits	= &ata_bmdma_port_ops,
 
-	.bmdma_start 	= hpt370_bmdma_start,
 	.bmdma_stop	= hpt370_bmdma_stop,
 
 	.mode_filter	= hpt370_filter,
@@ -753,55 +735,55 @@ static int hpt37x_init_one(struct pci_de
 	/* HPT370 - UDMA100 */
 	static const struct ata_port_info info_hpt370 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt370_port_ops
 	};
 	/* HPT370A - UDMA100 */
 	static const struct ata_port_info info_hpt370a = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt370a_port_ops
 	};
 	/* HPT370 - UDMA100 */
 	static const struct ata_port_info info_hpt370_33 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt370_port_ops
 	};
 	/* HPT370A - UDMA100 */
 	static const struct ata_port_info info_hpt370a_33 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt370a_port_ops
 	};
 	/* HPT371, 372 and friends - UDMA133 */
 	static const struct ata_port_info info_hpt372 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &hpt372_port_ops
 	};
 	/* HPT374 - UDMA100, function 1 uses different prereset method */
 	static const struct ata_port_info info_hpt374_fn0 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt372_port_ops
 	};
 	static const struct ata_port_info info_hpt374_fn1 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &hpt374_fn1_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt3x2n.c linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt3x2n.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt3x2n.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt3x2n.c	2009-06-09 23:05:27.000000000 -0400
@@ -441,8 +441,8 @@ static int hpt3x2n_init_one(struct pci_d
 	/* HPT372N and friends - UDMA133 */
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &hpt3x2n_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt3x3.c linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt3x3.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_hpt3x3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_hpt3x3.c	2009-06-09 23:05:27.000000000 -0400
@@ -188,11 +188,11 @@ static int hpt3x3_init_one(struct pci_de
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 #if defined(CONFIG_PATA_HPT3X3_DMA)
 		/* Further debug needed */
-		.mwdma_mask = 0x07,
-		.udma_mask = 0x07,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
 #endif
 		.port_ops = &hpt3x3_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_icside.c linux-libre-2.6.30-gnu1/drivers/ata/pata_icside.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_icside.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_icside.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,8 +45,6 @@ static const struct portinfo pata_icside
 	.stepping	= 6,
 };
 
-#define PATA_ICSIDE_MAX_SG	128
-
 struct pata_icside_state {
 	void __iomem *irq_port;
 	void __iomem *ioc_base;
@@ -57,7 +55,6 @@ struct pata_icside_state {
 		u8 disabled;
 		unsigned int speed[ATA_MAX_DEVICES];
 	} port[2];
-	struct scatterlist sg[PATA_ICSIDE_MAX_SG];
 };
 
 struct pata_icside_info {
@@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(stru
 {
 	struct ata_port *ap = qc->ap;
 	struct pata_icside_state *state = ap->host->private_data;
-	struct scatterlist *sg, *rsg = state->sg;
 	unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
-	unsigned int si;
 
 	/*
 	 * We are simplex; BUG if we try to fiddle with DMA
@@ -233,20 +228,12 @@ static void pata_icside_bmdma_setup(stru
 	BUG_ON(dma_channel_active(state->dma));
 
 	/*
-	 * Copy ATAs scattered sg list into a contiguous array of sg
-	 */
-	for_each_sg(qc->sg, sg, qc->n_elem, si) {
-		memcpy(rsg, sg, sizeof(*sg));
-		rsg++;
-	}
-
-	/*
 	 * Route the DMA signals to the correct interface
 	 */
 	writeb(state->port[ap->port_no].port_sel, state->ioc_base);
 
 	set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
-	set_dma_sg(state->dma, state->sg, rsg - state->sg);
+	set_dma_sg(state->dma, qc->sg, qc->n_elem);
 	set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
 
 	/* issue r/w command */
@@ -297,7 +284,7 @@ static int icside_dma_init(struct pata_i
 
 	if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
 		state->dma = ec->dma;
-		info->mwdma_mask = 0x07;	/* MW0..2 */
+		info->mwdma_mask = ATA_MWDMA2;
 	}
 
 	return 0;
@@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_i
 
 static struct scsi_host_template pata_icside_sht = {
 	ATA_BASE_SHT(DRV_NAME),
-	.sg_tablesize		= PATA_ICSIDE_MAX_SG,
-	.dma_boundary		= ~0, /* no dma boundaries */
+	.sg_tablesize		= SCSI_MAX_SG_CHAIN_SEGMENTS,
+	.dma_boundary		= IOMD_DMA_BOUNDARY,
 };
 
 static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
@@ -473,7 +460,7 @@ static int __devinit pata_icside_add_por
 	for (i = 0; i < info->nr_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		ap->pio_mask = 0x1f;
+		ap->pio_mask = ATA_PIO4;
 		ap->mwdma_mask = info->mwdma_mask;
 		ap->flags |= ATA_FLAG_SLAVE_POSS;
 		ap->ops = &pata_icside_port_ops;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_isapnp.c linux-libre-2.6.30-gnu1/drivers/ata/pata_isapnp.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_isapnp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_isapnp.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_isapnp"
-#define DRV_VERSION "0.2.2"
+#define DRV_VERSION "0.2.5"
 
 static struct scsi_host_template isapnp_sht = {
 	ATA_PIO_SHT(DRV_NAME),
@@ -28,6 +28,13 @@ static struct ata_port_operations isapnp
 	.cable_detect	= ata_cable_40wire,
 };
 
+static struct ata_port_operations isapnp_noalt_port_ops = {
+	.inherits	= &ata_sff_port_ops,
+	.cable_detect	= ata_cable_40wire,
+	/* No altstatus so we don't want to use the lost interrupt poll */
+	.lost_interrupt = ATA_OP_NULL,
+};
+
 /**
  *	isapnp_init_one		-	attach an isapnp interface
  *	@idev: PnP device
@@ -65,8 +72,8 @@ static int isapnp_init_one(struct pnp_de
 
 	ap = host->ports[0];
 
-	ap->ops = &isapnp_port_ops;
-	ap->pio_mask = 1;
+	ap->ops = &isapnp_noalt_port_ops;
+	ap->pio_mask = ATA_PIO0;
 	ap->flags |= ATA_FLAG_SLAVE_POSS;
 
 	ap->ioaddr.cmd_addr = cmd_addr;
@@ -76,6 +83,7 @@ static int isapnp_init_one(struct pnp_de
 					   pnp_port_start(idev, 1), 1);
 		ap->ioaddr.altstatus_addr = ctl_addr;
 		ap->ioaddr.ctl_addr = ctl_addr;
+		ap->ops = &isapnp_port_ops;
 	}
 
 	ata_sff_std_ports(&ap->ioaddr);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_it8213.c linux-libre-2.6.30-gnu1/drivers/ata/pata_it8213.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_it8213.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_it8213.c	2009-06-09 23:05:27.000000000 -0400
@@ -262,8 +262,8 @@ static int it8213_init_one (struct pci_d
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA4, /* FIXME: want UDMA 100? */
 		.port_ops	= &it8213_ops,
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_it821x.c linux-libre-2.6.30-gnu1/drivers/ata/pata_it821x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_it821x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_it821x.c	2009-06-09 23:05:27.000000000 -0400
@@ -875,29 +875,29 @@ static int it821x_init_one(struct pci_de
 
 	static const struct ata_port_info info_smart = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &it821x_smart_port_ops
 	};
 	static const struct ata_port_info info_passthru = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &it821x_passthru_port_ops
 	};
 	static const struct ata_port_info info_rdc = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &it821x_rdc_port_ops
 	};
 	static const struct ata_port_info info_rdc_11 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		/* No UDMA */
 		.port_ops = &it821x_rdc_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_ixp4xx_cf.c linux-libre-2.6.30-gnu1/drivers/ata/pata_ixp4xx_cf.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_ixp4xx_cf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_ixp4xx_cf.c	2009-06-09 23:05:27.000000000 -0400
@@ -157,7 +157,7 @@ static __devinit int ixp4xx_pata_probe(s
 		return -ENOMEM;
 
 	/* acquire resources and fill host */
-	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 	data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
 	data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
@@ -176,7 +176,7 @@ static __devinit int ixp4xx_pata_probe(s
 	ap = host->ports[0];
 
 	ap->ops	= &ixp4xx_port_ops;
-	ap->pio_mask = 0x1f; /* PIO4 */
+	ap->pio_mask = ATA_PIO4;
 	ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
 
 	ixp4xx_setup_port(ap, data, cs0->start, cs1->start);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_jmicron.c linux-libre-2.6.30-gnu1/drivers/ata/pata_jmicron.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_jmicron.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_jmicron.c	2009-06-09 23:05:27.000000000 -0400
@@ -136,8 +136,8 @@ static int jmicron_init_one (struct pci_
 	static const struct ata_port_info info = {
 		.flags	= ATA_FLAG_SLAVE_POSS,
 
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA5,
 
 		.port_ops	= &jmicron_ops,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_legacy.c linux-libre-2.6.30-gnu1/drivers/ata/pata_legacy.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_legacy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_legacy.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,7 @@
  *
  */
 
+#include <linux/async.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -108,6 +109,7 @@ struct legacy_controller {
 	struct ata_port_operations *ops;
 	unsigned int pio_mask;
 	unsigned int flags;
+	unsigned int pflags;
 	int (*setup)(struct platform_device *, struct legacy_probe *probe,
 		struct legacy_data *data);
 };
@@ -129,7 +131,7 @@ static int qdi;			/* Set to probe QDI co
 static int winbond;		/* Set to probe Winbond controllers,
 					give I/O port if non standard */
 static int autospeed;		/* Chip present which snoops speed changes */
-static int pio_mask = 0x1F;	/* PIO range for autospeed devices */
+static int pio_mask = ATA_PIO4;	/* PIO range for autospeed devices */
 static int iordy_mask = 0xFFFFFFFF;	/* Use iordy if available */
 
 /**
@@ -284,9 +286,11 @@ static unsigned int pdc_data_xfer_vlb(st
 			unsigned char *buf, unsigned int buflen, int rw)
 {
 	int slop = buflen & 3;
+	struct ata_port *ap = dev->link->ap;
+
 	/* 32bit I/O capable *and* we need to write a whole number of dwords */
-	if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) {
-		struct ata_port *ap = dev->link->ap;
+	if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)
+					&& (ap->pflags & ATA_PFLAG_PIO32)) {
 		unsigned long flags;
 
 		local_irq_save(flags);
@@ -736,7 +740,8 @@ static unsigned int vlb32_data_xfer(stru
 	struct ata_port *ap = adev->link->ap;
 	int slop = buflen & 3;
 
-	if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) {
+	if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)
+					&& (ap->pflags & ATA_PFLAG_PIO32)) {
 		if (rw == WRITE)
 			iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
 		else
@@ -858,27 +863,30 @@ static struct ata_port_operations winbon
 
 static struct legacy_controller controllers[] = {
 	{"BIOS",	&legacy_port_ops, 	0x1F,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"Snooping", 	&simple_port_ops, 	0x1F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"PDC20230",	&pdc20230_port_ops,	0x7,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,
+			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,	NULL },
 	{"HT6560A",	&ht6560a_port_ops,	0x07,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"HT6560B",	&ht6560b_port_ops,	0x1F,
-						ATA_FLAG_NO_IORDY,	NULL },
+			ATA_FLAG_NO_IORDY,	0,			NULL },
 	{"OPTI82C611A",	&opti82c611a_port_ops,	0x0F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"OPTI82C46X",	&opti82c46x_port_ops,	0x0F,
-						0	       ,	NULL },
+			0,			0,			NULL },
 	{"QDI6500",	&qdi6500_port_ops,	0x07,
-					ATA_FLAG_NO_IORDY,	qdi_port },
+			ATA_FLAG_NO_IORDY,
+			ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,    qdi_port },
 	{"QDI6580",	&qdi6580_port_ops,	0x1F,
-					0	       ,	qdi_port },
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
 	{"QDI6580DP",	&qdi6580dp_port_ops,	0x1F,
-					0	       ,	qdi_port },
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
 	{"W83759A",	&winbond_port_ops,	0x1F,
-					0	       ,	winbond_port }
+			0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,
+								winbond_port }
 };
 
 /**
@@ -1008,6 +1016,7 @@ static __init int legacy_init_one(struct
 	ap->ops = ops;
 	ap->pio_mask = pio_modes;
 	ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
+	ap->pflags |= controller->pflags;
 	ap->ioaddr.cmd_addr = io_addr;
 	ap->ioaddr.altstatus_addr = ctrl_addr;
 	ap->ioaddr.ctl_addr = ctrl_addr;
@@ -1020,6 +1029,7 @@ static __init int legacy_init_one(struct
 				&legacy_sht);
 	if (ret)
 		goto fail;
+	async_synchronize_full();
 	ld->platform_dev = pdev;
 
 	/* Nothing found means we drop the port as its probably not there */
@@ -1032,6 +1042,7 @@ static __init int legacy_init_one(struct
 			return 0;
 		}
 	}
+	ata_host_detach(host);
 fail:
 	platform_device_unregister(pdev);
 	return ret;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_marvell.c linux-libre-2.6.30-gnu1/drivers/ata/pata_marvell.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_marvell.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_marvell.c	2009-06-09 23:05:27.000000000 -0400
@@ -126,8 +126,8 @@ static int marvell_init_one (struct pci_
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
 
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA5,
 
 		.port_ops	= &marvell_ops,
@@ -136,8 +136,8 @@ static int marvell_init_one (struct pci_
 		/* Slave possible as its magically mapped not real */
 		.flags		= ATA_FLAG_SLAVE_POSS,
 
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA6,
 
 		.port_ops	= &marvell_ops,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_mpc52xx.c linux-libre-2.6.30-gnu1/drivers/ata/pata_mpc52xx.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_mpc52xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_mpc52xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -737,10 +737,10 @@ mpc52xx_ata_probe(struct of_device *op,
 	 */
 	prop = of_get_property(op->node, "mwdma-mode", &proplen);
 	if ((prop) && (proplen >= 4))
-		mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+		mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1);
 	prop = of_get_property(op->node, "udma-mode", &proplen);
 	if ((prop) && (proplen >= 4))
-		udma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+		udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1);
 
 	ata_irq = irq_of_parse_and_map(op->node, 0);
 	if (ata_irq == NO_IRQ) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_mpiix.c linux-libre-2.6.30-gnu1/drivers/ata/pata_mpiix.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_mpiix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_mpiix.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,7 +200,7 @@ static int mpiix_init_one(struct pci_dev
 	   the MPIIX your box goes castors up */
 
 	ap->ops = &mpiix_port_ops;
-	ap->pio_mask = 0x1F;
+	ap->pio_mask = ATA_PIO4;
 	ap->flags |= ATA_FLAG_SLAVE_POSS;
 
 	ap->ioaddr.cmd_addr = cmd_addr;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_netcell.c linux-libre-2.6.30-gnu1/drivers/ata/pata_netcell.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_netcell.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_netcell.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,13 +20,24 @@
 
 /* No PIO or DMA methods needed for this device */
 
+static unsigned int netcell_read_id(struct ata_device *adev,
+					struct ata_taskfile *tf, u16 *id)
+{
+	unsigned int err_mask = ata_do_dev_read_id(adev, tf, id);
+	/* Firmware forgets to mark words 85-87 valid */
+	if (err_mask == 0)
+		id[ATA_ID_CSF_DEFAULT] |= 0x4000;
+	return err_mask;
+}
+
 static struct scsi_host_template netcell_sht = {
 	ATA_BMDMA_SHT(DRV_NAME),
 };
 
 static struct ata_port_operations netcell_ops = {
 	.inherits	= &ata_bmdma_port_ops,
-	.cable_detect		= ata_cable_80wire,
+	.cable_detect	= ata_cable_80wire,
+	.read_id	= netcell_read_id,
 };
 
 
@@ -51,8 +62,8 @@ static int netcell_init_one (struct pci_
 		.flags		= ATA_FLAG_SLAVE_POSS,
 		/* Actually we don't really care about these as the
 		   firmware deals with it */
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask 	= ATA_UDMA5, /* UDMA 133 */
 		.port_ops	= &netcell_ops,
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_ninja32.c linux-libre-2.6.30-gnu1/drivers/ata/pata_ninja32.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_ninja32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_ninja32.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_ninja32"
-#define DRV_VERSION "0.1.3"
+#define DRV_VERSION "0.1.5"
 
 
 /**
@@ -86,6 +86,7 @@ static struct ata_port_operations ninja3
 	.sff_dev_select = ninja32_dev_select,
 	.cable_detect	= ata_cable_40wire,
 	.set_piomode	= ninja32_set_piomode,
+	.sff_data_xfer	= ata_sff_data_xfer32
 };
 
 static void ninja32_program(void __iomem *base)
@@ -136,7 +137,7 @@ static int ninja32_init_one(struct pci_d
 	if (!base)
 		return -ENOMEM;
 	ap->ops = &ninja32_port_ops;
-	ap->pio_mask = 0x1F;
+	ap->pio_mask = ATA_PIO4;
 	ap->flags |= ATA_FLAG_SLAVE_POSS;
 
 	ap->ioaddr.cmd_addr = base + 0x10;
@@ -144,6 +145,7 @@ static int ninja32_init_one(struct pci_d
 	ap->ioaddr.altstatus_addr = base + 0x1E;
 	ap->ioaddr.bmdma_addr = base;
 	ata_sff_std_ports(&ap->ioaddr);
+	ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
 
 	ninja32_program(base);
 	/* FIXME: Should we disable them at remove ? */
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_ns87410.c linux-libre-2.6.30-gnu1/drivers/ata/pata_ns87410.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_ns87410.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_ns87410.c	2009-06-09 23:05:27.000000000 -0400
@@ -144,7 +144,7 @@ static int ns87410_init_one(struct pci_d
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x0F,
+		.pio_mask = ATA_PIO3,
 		.port_ops = &ns87410_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_ns87415.c linux-libre-2.6.30-gnu1/drivers/ata/pata_ns87415.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_ns87415.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_ns87415.c	2009-06-09 23:05:27.000000000 -0400
@@ -346,8 +346,8 @@ static int ns87415_init_one (struct pci_
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.port_ops	= &ns87415_pata_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
@@ -355,8 +355,8 @@ static int ns87415_init_one (struct pci_
 #if defined(CONFIG_SUPERIO)
 	static const struct ata_port_info info87560 = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.port_ops	= &ns87560_pata_ops,
 	};
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_octeon_cf.c linux-libre-2.6.30-gnu1/drivers/ata/pata_octeon_cf.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_octeon_cf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_octeon_cf.c	2009-06-09 23:05:27.000000000 -0400
@@ -503,7 +503,7 @@ static void octeon_cf_dma_setup(struct a
 	struct ata_port *ap = qc->ap;
 	struct octeon_cf_port *cf_port;
 
-	cf_port = (struct octeon_cf_port *)ap->private_data;
+	cf_port = ap->private_data;
 	DPRINTK("ENTER\n");
 	/* issue r/w command */
 	qc->cursg = qc->sg;
@@ -596,7 +596,7 @@ static unsigned int octeon_cf_dma_finish
 	if (ap->hsm_task_state != HSM_ST_LAST)
 		return 0;
 
-	cf_port = (struct octeon_cf_port *)ap->private_data;
+	cf_port = ap->private_data;
 
 	dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine));
 	if (dma_cfg.s.size != 0xfffff) {
@@ -657,7 +657,7 @@ static irqreturn_t octeon_cf_interrupt(i
 			continue;
 
 		ocd = ap->dev->platform_data;
-		cf_port = (struct octeon_cf_port *)ap->private_data;
+		cf_port = ap->private_data;
 		dma_int.u64 =
 			cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine));
 		dma_cfg.u64 =
@@ -871,7 +871,7 @@ static int __devinit octeon_cf_probe(str
 	ap->private_data = cf_port;
 	cf_port->ap = ap;
 	ap->ops = &octeon_cf_ops;
-	ap->pio_mask = 0x7f; /* Support PIO 0-6 */
+	ap->pio_mask = ATA_PIO6;
 	ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
 		  | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING;
 
@@ -900,7 +900,7 @@ static int __devinit octeon_cf_probe(str
 		ap->ioaddr.ctl_addr	= cs1 + (6 << 1) + 1;
 		octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16;
 
-		ap->mwdma_mask	= 0x1f; /* Support MWDMA 0-4 */
+		ap->mwdma_mask	= ATA_MWDMA4;
 		irq = platform_get_irq(pdev, 0);
 		irq_handler = octeon_cf_interrupt;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_oldpiix.c linux-libre-2.6.30-gnu1/drivers/ata/pata_oldpiix.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_oldpiix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_oldpiix.c	2009-06-09 23:05:27.000000000 -0400
@@ -238,8 +238,8 @@ static int oldpiix_init_one (struct pci_
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma1-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.port_ops	= &oldpiix_pata_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_opti.c linux-libre-2.6.30-gnu1/drivers/ata/pata_opti.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_opti.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_opti.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,7 +163,7 @@ static int opti_init_one(struct pci_dev
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &opti_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_optidma.c linux-libre-2.6.30-gnu1/drivers/ata/pata_optidma.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_optidma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_optidma.c	2009-06-09 23:05:27.000000000 -0400
@@ -399,15 +399,15 @@ static int optidma_init_one(struct pci_d
 {
 	static const struct ata_port_info info_82c700 = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &optidma_port_ops
 	};
 	static const struct ata_port_info info_82c700_udma = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
-		.udma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
 		.port_ops = &optiplus_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info_82c700, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_pcmcia.c linux-libre-2.6.30-gnu1/drivers/ata/pata_pcmcia.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_pcmcia.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_pcmcia.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@
 
 
 #define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.5"
 
 /*
  *	Private data structure to glue stuff together
@@ -126,6 +126,37 @@ static unsigned int ata_data_xfer_8bit(s
 	return buflen;
 }
 
+/**
+ *	pcmcia_8bit_drain_fifo - Stock FIFO drain logic for SFF controllers
+ *	@qc: command
+ *
+ *	Drain the FIFO and device of any stuck data following a command
+ *	failing to complete. In some cases this is neccessary before a
+ *	reset will recover the device.
+ *
+ */
+ 
+void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
+{
+	int count;
+	struct ata_port *ap;
+
+	/* We only need to flush incoming data when a command was running */
+	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+		return;
+
+	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++ < 65536;)
+		ioread8(ap->ioaddr.data_addr);
+
+	if (count)
+		ata_port_printk(ap, KERN_WARNING, "drained %d bytes to clear DRQ.\n",
+								count);
+
+}
 
 static struct scsi_host_template pcmcia_sht = {
 	ATA_PIO_SHT(DRV_NAME),
@@ -143,6 +174,7 @@ static struct ata_port_operations pcmcia
 	.sff_data_xfer	= ata_data_xfer_8bit,
 	.cable_detect	= ata_cable_40wire,
 	.set_mode	= pcmcia_set_mode_8bit,
+	.drain_fifo	= pcmcia_8bit_drain_fifo,
 };
 
 #define CS_CHECK(fn, ret) \
@@ -299,7 +331,7 @@ static int pcmcia_init_one(struct pcmcia
 		ap = host->ports[p];
 
 		ap->ops = ops;
-		ap->pio_mask = 1;		/* ISA so PIO 0 cycles */
+		ap->pio_mask = ATA_PIO0;	/* ISA so PIO 0 cycles */
 		ap->flags |= ATA_FLAG_SLAVE_POSS;
 		ap->ioaddr.cmd_addr = io_addr + 0x10 * p;
 		ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_pdc2027x.c linux-libre-2.6.30-gnu1/drivers/ata/pata_pdc2027x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_pdc2027x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_pdc2027x.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,18 +152,18 @@ static struct ata_port_info pdc2027x_por
 	{
 		.flags		= ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
 		                  ATA_FLAG_MMIO,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
-		.udma_mask	= ATA_UDMA5, /* udma0-5 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &pdc2027x_pata100_ops,
 	},
 	/* PDC_UDMA_133 */
 	{
 		.flags		= ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
                         	  ATA_FLAG_MMIO,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
-		.udma_mask	= ATA_UDMA6, /* udma0-6 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc2027x_pata133_ops,
 	},
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_pdc202xx_old.c linux-libre-2.6.30-gnu1/drivers/ata/pata_pdc202xx_old.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_pdc202xx_old.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_pdc202xx_old.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  * pata_pdc202xx_old.c 	- Promise PDC202xx PATA for new ATA layer
  *			  (C) 2005 Red Hat Inc
  *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
- *			  (C) 2007 Bartlomiej Zolnierkiewicz
+ *			  (C) 2007,2009 Bartlomiej Zolnierkiewicz
  *
  * Based in part on linux/drivers/ide/pci/pdc202xx_old.c
  *
@@ -158,7 +158,7 @@ static void pdc2026x_bmdma_start(struct
 	u32 len;
 
 	/* Check we keep host level locking here */
-	if (adev->dma_mode >= XFER_UDMA_2)
+	if (adev->dma_mode > XFER_UDMA_2)
 		iowrite8(ioread8(clock) | sel66, clock);
 	else
 		iowrite8(ioread8(clock) & ~sel66, clock);
@@ -212,7 +212,7 @@ static void pdc2026x_bmdma_stop(struct a
 		iowrite8(ioread8(clock) & ~sel66, clock);
 	}
 	/* Flip back to 33Mhz for PIO */
-	if (adev->dma_mode >= XFER_UDMA_2)
+	if (adev->dma_mode > XFER_UDMA_2)
 		iowrite8(ioread8(clock) & ~sel66, clock);
 	ata_bmdma_stop(qc);
 	pdc202xx_set_piomode(ap, adev);
@@ -291,22 +291,22 @@ static int pdc202xx_init_one(struct pci_
 	static const struct ata_port_info info[3] = {
 		{
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA2,
 			.port_ops = &pdc2024x_port_ops
 		},
 		{
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA4,
 			.port_ops = &pdc2026x_port_ops
 		},
 		{
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA5,
 			.port_ops = &pdc2026x_port_ops
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_qdi.c linux-libre-2.6.30-gnu1/drivers/ata/pata_qdi.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_qdi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_qdi.c	2009-06-09 23:05:27.000000000 -0400
@@ -212,11 +212,11 @@ static __init int qdi_init_one(unsigned
 
 	if (type == 6580) {
 		ap->ops = &qdi6580_port_ops;
-		ap->pio_mask = 0x1F;
+		ap->pio_mask = ATA_PIO4;
 		ap->flags |= ATA_FLAG_SLAVE_POSS;
 	} else {
 		ap->ops = &qdi6500_port_ops;
-		ap->pio_mask = 0x07;	/* Actually PIO3 !IORDY is possible */
+		ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */
 		ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_radisys.c linux-libre-2.6.30-gnu1/drivers/ata/pata_radisys.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_radisys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_radisys.c	2009-06-09 23:05:27.000000000 -0400
@@ -216,9 +216,9 @@ static int radisys_init_one (struct pci_
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags		= ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma1-2 */
-		.udma_mask	= 0x14, /* UDMA33/66 only */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA12_ONLY,
+		.udma_mask	= ATA_UDMA24_ONLY,
 		.port_ops	= &radisys_pata_ops,
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_rb532_cf.c linux-libre-2.6.30-gnu1/drivers/ata/pata_rb532_cf.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_rb532_cf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_rb532_cf.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,63 +48,11 @@
 struct rb532_cf_info {
 	void __iomem	*iobase;
 	unsigned int	gpio_line;
-	int		frozen;
 	unsigned int	irq;
 };
 
 /* ------------------------------------------------------------------------ */
 
-static inline void rb532_pata_finish_io(struct ata_port *ap)
-{
-	struct ata_host *ah = ap->host;
-	struct rb532_cf_info *info = ah->private_data;
-
-	/* FIXME: Keep previous delay. If this is merely a fence then
-	   ata_sff_sync might be sufficient. */
-	ata_sff_dma_pause(ap);
-	ndelay(RB500_CF_IO_DELAY);
-}
-
-static void rb532_pata_exec_command(struct ata_port *ap,
-				const struct ata_taskfile *tf)
-{
-	writeb(tf->command, ap->ioaddr.command_addr);
-	rb532_pata_finish_io(ap);
-}
-
-static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf,
-				unsigned int buflen, int write_data)
-{
-	struct ata_port *ap = adev->link->ap;
-	void __iomem *ioaddr = ap->ioaddr.data_addr;
-	int retlen = buflen;
-
-	if (write_data) {
-		for (; buflen > 0; buflen--, buf++)
-			writeb(*buf, ioaddr);
-	} else {
-		for (; buflen > 0; buflen--, buf++)
-			*buf = readb(ioaddr);
-	}
-
-	rb532_pata_finish_io(adev->link->ap);
-	return retlen;
-}
-
-static void rb532_pata_freeze(struct ata_port *ap)
-{
-	struct rb532_cf_info *info = ap->host->private_data;
-
-	info->frozen = 1;
-}
-
-static void rb532_pata_thaw(struct ata_port *ap)
-{
-	struct rb532_cf_info *info = ap->host->private_data;
-
-	info->frozen = 0;
-}
-
 static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
 {
 	struct ata_host *ah = dev_instance;
@@ -112,8 +60,7 @@ static irqreturn_t rb532_pata_irq_handle
 
 	if (gpio_get_value(info->gpio_line)) {
 		set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
-		if (!info->frozen)
-			ata_sff_interrupt(info->irq, dev_instance);
+		ata_sff_interrupt(info->irq, dev_instance);
 	} else {
 		set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
 	}
@@ -123,10 +70,7 @@ static irqreturn_t rb532_pata_irq_handle
 
 static struct ata_port_operations rb532_pata_port_ops = {
 	.inherits		= &ata_sff_port_ops,
-	.sff_exec_command	= rb532_pata_exec_command,
-	.sff_data_xfer		= rb532_pata_data_xfer,
-	.freeze			= rb532_pata_freeze,
-	.thaw			= rb532_pata_thaw,
+	.sff_data_xfer		= ata_sff_data_xfer32,
 };
 
 /* ------------------------------------------------------------------------ */
@@ -145,7 +89,7 @@ static void rb532_pata_setup_ports(struc
 	ap = ah->ports[0];
 
 	ap->ops		= &rb532_pata_port_ops;
-	ap->pio_mask	= 0x1f; /* PIO4 */
+	ap->pio_mask	= ATA_PIO4;
 	ap->flags	= ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
 
 	ap->ioaddr.cmd_addr	= info->iobase + RB500_CF_REG_BASE;
@@ -160,7 +104,7 @@ static void rb532_pata_setup_ports(struc
 
 static __devinit int rb532_pata_driver_probe(struct platform_device *pdev)
 {
-	unsigned int irq;
+	int irq;
 	int gpio;
 	struct resource *res;
 	struct ata_host *ah;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_rz1000.c linux-libre-2.6.30-gnu1/drivers/ata/pata_rz1000.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_rz1000.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_rz1000.c	2009-06-09 23:05:27.000000000 -0400
@@ -88,7 +88,7 @@ static int rz1000_init_one (struct pci_d
 	static int printed_version;
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &rz1000_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_sc1200.c linux-libre-2.6.30-gnu1/drivers/ata/pata_sc1200.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_sc1200.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_sc1200.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,6 @@
  * New ATA layer SC1200 driver		Alan Cox <alan@lxorguk.ukuu.org.uk>
  *
  * TODO: Mode selection filtering
- * TODO: Can't enable second channel until ATA core has serialize
  * TODO: Needs custom DMA cleanup code
  *
  * Based very heavily on
@@ -178,6 +177,31 @@ static unsigned int sc1200_qc_issue(stru
 	return ata_sff_qc_issue(qc);
 }
 
+/**
+ *	sc1200_qc_defer	-	implement serialization
+ *	@qc: command
+ *
+ *	Serialize command issue on this controller.
+ */
+
+static int sc1200_qc_defer(struct ata_queued_cmd *qc)
+{
+	struct ata_host *host = qc->ap->host;
+	struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+	int rc;
+
+	/* First apply the usual rules */
+	rc = ata_std_qc_defer(qc);
+	if (rc != 0)
+		return rc;
+
+	/* Now apply serialization rules. Only allow a command if the
+	   other channel state machine is idle */
+	if (alt && alt->qc_active)
+		return	ATA_DEFER_PORT;
+	return 0;
+}
+
 static struct scsi_host_template sc1200_sht = {
 	ATA_BMDMA_SHT(DRV_NAME),
 	.sg_tablesize	= LIBATA_DUMB_MAX_PRD,
@@ -187,6 +211,7 @@ static struct ata_port_operations sc1200
 	.inherits	= &ata_bmdma_port_ops,
 	.qc_prep 	= ata_sff_dumb_qc_prep,
 	.qc_issue	= sc1200_qc_issue,
+	.qc_defer	= sc1200_qc_defer,
 	.cable_detect	= ata_cable_40wire,
 	.set_piomode	= sc1200_set_piomode,
 	.set_dmamode	= sc1200_set_dmamode,
@@ -205,13 +230,13 @@ static int sc1200_init_one(struct pci_de
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
-		.udma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
+		.udma_mask = ATA_UDMA2,
 		.port_ops = &sc1200_port_ops
 	};
 	/* Can't enable port 2 yet, see top comments */
-	const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+	const struct ata_port_info *ppi[] = { &info, };
 
 	return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_scc.c linux-libre-2.6.30-gnu1/drivers/ata/pata_scc.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_scc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_scc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1001,8 +1001,8 @@ static struct ata_port_operations scc_pa
 static struct ata_port_info scc_port_info[] = {
 	{
 		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x00,
+		.pio_mask	= ATA_PIO4,
+		/* No MWDMA */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &scc_pata_ops,
 	},
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_sch.c linux-libre-2.6.30-gnu1/drivers/ata/pata_sch.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_sch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_sch.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,9 +84,9 @@ static struct ata_port_operations sch_pa
 
 static struct ata_port_info sch_port_info = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= ATA_PIO4,   /* pio0-4 */
-	.mwdma_mask	= ATA_MWDMA2, /* mwdma0-2 */
-	.udma_mask	= ATA_UDMA5,  /* udma0-5 */
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA5,
 	.port_ops	= &sch_pata_ops,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_serverworks.c linux-libre-2.6.30-gnu1/drivers/ata/pata_serverworks.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_serverworks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_serverworks.c	2009-06-09 23:05:27.000000000 -0400
@@ -398,26 +398,26 @@ static int serverworks_init_one(struct p
 	static const struct ata_port_info info[4] = {
 		{ /* OSB4 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			.udma_mask = ATA_UDMA2,
 			.port_ops = &serverworks_osb4_port_ops
 		}, { /* OSB4 no UDMA */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
-			.udma_mask = 0x00,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
+			/* No UDMA */
 			.port_ops = &serverworks_osb4_port_ops
 		}, { /* CSB5 */
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA4,
 			.port_ops = &serverworks_csb_port_ops
 		}, { /* CSB5 - later revisions*/
 			.flags = ATA_FLAG_SLAVE_POSS,
-			.pio_mask = 0x1f,
-			.mwdma_mask = 0x07,
+			.pio_mask = ATA_PIO4,
+			.mwdma_mask = ATA_MWDMA2,
 			.udma_mask = ATA_UDMA5,
 			.port_ops = &serverworks_csb_port_ops
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_sil680.c linux-libre-2.6.30-gnu1/drivers/ata/pata_sil680.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_sil680.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_sil680.c	2009-06-09 23:05:27.000000000 -0400
@@ -282,15 +282,15 @@ static int __devinit sil680_init_one(str
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,
 		.port_ops = &sil680_port_ops
 	};
 	static const struct ata_port_info info_slow = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &sil680_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_sis.c linux-libre-2.6.30-gnu1/drivers/ata/pata_sis.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_sis.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_sis.c	2009-06-09 23:05:27.000000000 -0400
@@ -552,51 +552,57 @@ static struct ata_port_operations sis_ol
 
 static const struct ata_port_info sis_info = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
-	.mwdma_mask	= 0x07,
-	.udma_mask	= 0,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	/* No UDMA */
 	.port_ops	= &sis_old_ops,
 };
 static const struct ata_port_info sis_info33 = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
-	.mwdma_mask	= 0x07,
-	.udma_mask	= ATA_UDMA2,	/* UDMA 33 */
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA2,
 	.port_ops	= &sis_old_ops,
 };
 static const struct ata_port_info sis_info66 = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
-	.udma_mask	= ATA_UDMA4,	/* UDMA 66 */
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
+	.udma_mask	= ATA_UDMA4,
 	.port_ops	= &sis_66_ops,
 };
 static const struct ata_port_info sis_info100 = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA5,
 	.port_ops	= &sis_100_ops,
 };
 static const struct ata_port_info sis_info100_early = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA5,
-	.pio_mask	= 0x1f,	/* pio0-4 */
 	.port_ops	= &sis_66_ops,
 };
 static const struct ata_port_info sis_info133 = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &sis_133_ops,
 };
 const struct ata_port_info sis_info133_for_sata = {
 	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
-	.pio_mask	= 0x1f,	/* pio0-4 */
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &sis_133_for_sata_ops,
 };
 static const struct ata_port_info sis_info133_early = {
 	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,	/* pio0-4 */
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &sis_133_early_ops,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_sl82c105.c linux-libre-2.6.30-gnu1/drivers/ata/pata_sl82c105.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_sl82c105.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_sl82c105.c	2009-06-09 23:05:27.000000000 -0400
@@ -283,13 +283,13 @@ static int sl82c105_init_one(struct pci_
 {
 	static const struct ata_port_info info_dma = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &sl82c105_port_ops
 	};
 	static const struct ata_port_info info_early = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
+		.pio_mask = ATA_PIO4,
 		.port_ops = &sl82c105_port_ops
 	};
 	/* for now use only the first port */
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_triflex.c linux-libre-2.6.30-gnu1/drivers/ata/pata_triflex.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_triflex.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_triflex.c	2009-06-09 23:05:27.000000000 -0400
@@ -191,8 +191,8 @@ static int triflex_init_one(struct pci_d
 {
 	static const struct ata_port_info info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &triflex_port_ops
 	};
 	const struct ata_port_info *ppi[] = { &info, NULL };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_via.c linux-libre-2.6.30-gnu1/drivers/ata/pata_via.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_via.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_via.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,7 +62,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME "pata_via"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.4"
 
 /*
  *	The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -136,6 +136,9 @@ static const struct via_isa_bridge {
 	{ NULL }
 };
 
+struct via_port {
+	u8 cached_device;
+};
 
 /*
  *	Cable special cases
@@ -346,14 +349,70 @@ static void via_set_dmamode(struct ata_p
  */
 static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-	struct ata_taskfile tmp_tf;
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	struct via_port *vp = ap->private_data;
+	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+	int newctl = 0;
 
-	if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
-		tmp_tf = *tf;
-		tmp_tf.flags |= ATA_TFLAG_DEVICE;
-		tf = &tmp_tf;
+	if (tf->ctl != ap->last_ctl) {
+		iowrite8(tf->ctl, ioaddr->ctl_addr);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+		newctl = 1;
 	}
-	ata_sff_tf_load(ap, tf);
+
+	if (tf->flags & ATA_TFLAG_DEVICE) {
+		iowrite8(tf->device, ioaddr->device_addr);
+		vp->cached_device = tf->device;
+	} else if (newctl)
+		iowrite8(vp->cached_device, ioaddr->device_addr);
+
+	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+		WARN_ON_ONCE(!ioaddr->ctl_addr);
+		iowrite8(tf->hob_feature, ioaddr->feature_addr);
+		iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
+		iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
+		iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
+		iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
+		VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+			tf->hob_feature,
+			tf->hob_nsect,
+			tf->hob_lbal,
+			tf->hob_lbam,
+			tf->hob_lbah);
+	}
+
+	if (is_addr) {
+		iowrite8(tf->feature, ioaddr->feature_addr);
+		iowrite8(tf->nsect, ioaddr->nsect_addr);
+		iowrite8(tf->lbal, ioaddr->lbal_addr);
+		iowrite8(tf->lbam, ioaddr->lbam_addr);
+		iowrite8(tf->lbah, ioaddr->lbah_addr);
+		VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+			tf->feature,
+			tf->nsect,
+			tf->lbal,
+			tf->lbam,
+			tf->lbah);
+	}
+
+	ata_wait_idle(ap);
+}
+
+static int via_port_start(struct ata_port *ap)
+{
+	struct via_port *vp;
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+	int ret = ata_sff_port_start(ap);
+	if (ret < 0)
+		return ret;
+
+	vp = devm_kzalloc(&pdev->dev, sizeof(struct via_port), GFP_KERNEL);
+	if (vp == NULL)
+		return -ENOMEM;
+	ap->private_data = vp;
+	return 0;
 }
 
 static struct scsi_host_template via_sht = {
@@ -367,6 +426,7 @@ static struct ata_port_operations via_po
 	.set_dmamode	= via_set_dmamode,
 	.prereset	= via_pre_reset,
 	.sff_tf_load	= via_tf_load,
+	.port_start	= via_port_start,
 };
 
 static struct ata_port_operations via_port_ops_noirq = {
@@ -422,46 +482,46 @@ static int via_init_one(struct pci_dev *
 	/* Early VIA without UDMA support */
 	static const struct ata_port_info via_mwdma_info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &via_port_ops
 	};
 	/* Ditto with IRQ masking required */
 	static const struct ata_port_info via_mwdma_info_borked = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.port_ops = &via_port_ops_noirq,
 	};
 	/* VIA UDMA 33 devices (and borked 66) */
 	static const struct ata_port_info via_udma33_info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA2,
 		.port_ops = &via_port_ops
 	};
 	/* VIA UDMA 66 devices */
 	static const struct ata_port_info via_udma66_info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA4,
 		.port_ops = &via_port_ops
 	};
 	/* VIA UDMA 100 devices */
 	static const struct ata_port_info via_udma100_info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA5,
 		.port_ops = &via_port_ops
 	};
 	/* UDMA133 with bad AST (All current 133) */
 	static const struct ata_port_info via_udma133_info = {
 		.flags = ATA_FLAG_SLAVE_POSS,
-		.pio_mask = 0x1f,
-		.mwdma_mask = 0x07,
+		.pio_mask = ATA_PIO4,
+		.mwdma_mask = ATA_MWDMA2,
 		.udma_mask = ATA_UDMA6,	/* FIXME: should check north bridge */
 		.port_ops = &via_port_ops
 	};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pata_winbond.c linux-libre-2.6.30-gnu1/drivers/ata/pata_winbond.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pata_winbond.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pata_winbond.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ static __init int winbond_init_one(unsig
 		ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port);
 
 		ap->ops = &winbond_port_ops;
-		ap->pio_mask = 0x1F;
+		ap->pio_mask = ATA_PIO4;
 		ap->flags |= ATA_FLAG_SLAVE_POSS;
 		ap->ioaddr.cmd_addr = cmd_addr;
 		ap->ioaddr.altstatus_addr = ctl_addr;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/pdc_adma.c linux-libre-2.6.30-gnu1/drivers/ata/pdc_adma.c
--- linux-libre-2.6.29-gnu1/drivers/ata/pdc_adma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/pdc_adma.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,6 +148,8 @@ static struct scsi_host_template adma_at
 static struct ata_port_operations adma_ata_ops = {
 	.inherits		= &ata_sff_port_ops,
 
+	.lost_interrupt		= ATA_OP_NULL,
+
 	.check_atapi_dma	= adma_check_atapi_dma,
 	.qc_prep		= adma_qc_prep,
 	.qc_issue		= adma_qc_issue,
@@ -166,7 +168,7 @@ static struct ata_port_info adma_port_in
 		.flags		= ATA_FLAG_SLAVE_POSS |
 				  ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
 				  ATA_FLAG_PIO_POLLING,
-		.pio_mask	= 0x10, /* pio4 */
+		.pio_mask	= ATA_PIO4_ONLY,
 		.udma_mask	= ATA_UDMA4,
 		.port_ops	= &adma_ata_ops,
 	},
@@ -605,13 +607,13 @@ static int adma_set_dma_masks(struct pci
 {
 	int rc;
 
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			"32-bit DMA enable failed\n");
 		return rc;
 	}
-	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			"32-bit consistent DMA enable failed\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_fsl.c linux-libre-2.6.30-gnu1/drivers/ata/sata_fsl.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_fsl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_fsl.c	2009-06-09 23:05:27.000000000 -0400
@@ -205,6 +205,7 @@ struct cmdhdr_tbl_entry {
  * Description information bitdefs
  */
 enum {
+	CMD_DESC_RES = (1 << 11),
 	VENDOR_SPECIFIC_BIST = (1 << 10),
 	CMD_DESC_SNOOP_ENABLE = (1 << 9),
 	FPDMA_QUEUED_CMD = (1 << 8),
@@ -332,13 +333,14 @@ static unsigned int sata_fsl_fill_sg(str
 		dma_addr_t sg_addr = sg_dma_address(sg);
 		u32 sg_len = sg_dma_len(sg);
 
-		VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n",
-			sg_addr, sg_len);
+		VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%llx, sg_len = %d\n",
+			(unsigned long long)sg_addr, sg_len);
 
 		/* warn if each s/g element is not dword aligned */
 		if (sg_addr & 0x03)
 			ata_port_printk(qc->ap, KERN_ERR,
-					"s/g addr unaligned : 0x%x\n", sg_addr);
+					"s/g addr unaligned : 0x%llx\n",
+					(unsigned long long)sg_addr);
 		if (sg_len & 0x03)
 			ata_port_printk(qc->ap, KERN_ERR,
 					"s/g len unaligned : 0x%x\n", sg_len);
@@ -387,7 +389,7 @@ static void sata_fsl_qc_prep(struct ata_
 	void __iomem *hcr_base = host_priv->hcr_base;
 	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
 	struct command_desc *cd;
-	u32 desc_info = CMD_DESC_SNOOP_ENABLE;
+	u32 desc_info = CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE;
 	u32 num_prde = 0;
 	u32 ttl_dwords = 0;
 	dma_addr_t cd_paddr;
@@ -840,7 +842,7 @@ issue_srst:
 
 	/* device reset/SRST is a control register update FIS, uses tag0 */
 	sata_fsl_setup_cmd_hdr_entry(pp, 0,
-				     SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+		SRST_CMD | CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
 
 	tf.ctl |= ATA_SRST;	/* setup SRST bit in taskfile control reg */
 	ata_tf_to_fis(&tf, pmp, 0, cfis);
@@ -886,7 +888,8 @@ issue_srst:
 	 * using ATA signature D2H register FIS to the host controller.
 	 */
 
-	sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+	sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE,
+				      0, 0, 5);
 
 	tf.ctl &= ~ATA_SRST;	/* 2nd H2D Ctl. register FIS */
 	ata_tf_to_fis(&tf, pmp, 0, cfis);
@@ -1279,8 +1282,8 @@ static struct ata_port_operations sata_f
 static const struct ata_port_info sata_fsl_port_info[] = {
 	{
 	 .flags = SATA_FSL_HOST_FLAGS,
-	 .pio_mask = 0x1f,	/* pio 0-4 */
-	 .udma_mask = 0x7f,	/* udma 0-6 */
+	 .pio_mask = ATA_PIO4,
+	 .udma_mask = ATA_UDMA6,
 	 .port_ops = &sata_fsl_ops,
 	 },
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_inic162x.c linux-libre-2.6.30-gnu1/drivers/ata/sata_inic162x.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_inic162x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_inic162x.c	2009-06-09 23:05:27.000000000 -0400
@@ -744,8 +744,8 @@ static struct ata_port_operations inic_p
 
 static struct ata_port_info inic_port_info = {
 	.flags			= ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
-	.pio_mask		= 0x1f,	/* pio0-4 */
-	.mwdma_mask		= 0x07, /* mwdma0-2 */
+	.pio_mask		= ATA_PIO4,
+	.mwdma_mask		= ATA_MWDMA2,
 	.udma_mask		= ATA_UDMA6,
 	.port_ops		= &inic_port_ops
 };
@@ -861,14 +861,14 @@ static int inic_init_one(struct pci_dev
 	}
 
 	/* Set dma_mask.  This devices doesn't support 64bit addressing. */
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			   "32-bit DMA enable failed\n");
 		return rc;
 	}
 
-	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			   "32-bit consistent DMA enable failed\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_mv.c linux-libre-2.6.30-gnu1/drivers/ata/sata_mv.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_mv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_mv.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,13 @@
 /*
  * sata_mv.c - Marvell SATA support
  *
- * Copyright 2008: Marvell Corporation, all rights reserved.
+ * Copyright 2008-2009: Marvell Corporation, all rights reserved.
  * Copyright 2005: EMC Corporation, all rights reserved.
  * Copyright 2005 Red Hat, Inc.  All rights reserved.
  *
+ * Originally written by Brett Russ.
+ * Extensive overhaul and enhancement by Mark Lord <mlord@pobox.com>.
+ *
  * Please ALWAYS copy linux-ide@vger.kernel.org on emails.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,20 +28,9 @@
 /*
  * sata_mv TODO list:
  *
- * --> Errata workaround for NCQ device errors.
- *
- * --> More errata workarounds for PCI-X.
- *
- * --> Complete a full errata audit for all chipsets to identify others.
- *
- * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it).
- *
  * --> Develop a low-power-consumption strategy, and implement it.
  *
- * --> [Experiment, low priority] Investigate interrupt coalescing.
- *       Quite often, especially with PCI Message Signalled Interrupts (MSI),
- *       the overhead reduced by interrupt mitigation is quite often not
- *       worth the latency cost.
+ * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
  *
  * --> [Experiment, Marvell value added] Is it possible to use target
  *       mode to cross-connect two Linux boxes with Marvell cards?  If so,
@@ -48,6 +40,15 @@
  *       connect two SATA ports.
  */
 
+/*
+ * 80x1-B2 errata PCI#11:
+ *
+ * Users of the 6041/6081 Rev.B2 chips (current is C0)
+ * should be careful to insert those cards only onto PCI-X bus #0,
+ * and only in device slots 0..7, not higher.  The chips may not
+ * work correctly otherwise  (note: this is a pretty rare condition).
+ */
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -68,7 +69,27 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_mv"
-#define DRV_VERSION	"1.25"
+#define DRV_VERSION	"1.28"
+
+/*
+ * module options
+ */
+
+static int msi;
+#ifdef CONFIG_PCI
+module_param(msi, int, S_IRUGO);
+MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
+#endif
+
+static int irq_coalescing_io_count;
+module_param(irq_coalescing_io_count, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_io_count,
+		 "IRQ coalescing I/O count threshold (0..255)");
+
+static int irq_coalescing_usecs;
+module_param(irq_coalescing_usecs, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_usecs,
+		 "IRQ coalescing time threshold in usecs");
 
 enum {
 	/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -79,18 +100,37 @@ enum {
 	MV_MAJOR_REG_AREA_SZ	= 0x10000,	/* 64KB */
 	MV_MINOR_REG_AREA_SZ	= 0x2000,	/* 8KB */
 
+	/* For use with both IRQ coalescing methods ("all ports" or "per-HC" */
+	COAL_CLOCKS_PER_USEC	= 150,		/* for calculating COAL_TIMEs */
+	MAX_COAL_TIME_THRESHOLD	= ((1 << 24) - 1), /* internal clocks count */
+	MAX_COAL_IO_COUNT	= 255,		/* completed I/O count */
+
 	MV_PCI_REG_BASE		= 0,
-	MV_IRQ_COAL_REG_BASE	= 0x18000,	/* 6xxx part only */
-	MV_IRQ_COAL_CAUSE		= (MV_IRQ_COAL_REG_BASE + 0x08),
-	MV_IRQ_COAL_CAUSE_LO		= (MV_IRQ_COAL_REG_BASE + 0x88),
-	MV_IRQ_COAL_CAUSE_HI		= (MV_IRQ_COAL_REG_BASE + 0x8c),
-	MV_IRQ_COAL_THRESHOLD		= (MV_IRQ_COAL_REG_BASE + 0xcc),
-	MV_IRQ_COAL_TIME_THRESHOLD	= (MV_IRQ_COAL_REG_BASE + 0xd0),
 
-	MV_SATAHC0_REG_BASE	= 0x20000,
-	MV_FLASH_CTL_OFS	= 0x1046c,
-	MV_GPIO_PORT_CTL_OFS	= 0x104f0,
-	MV_RESET_CFG_OFS	= 0x180d8,
+	/*
+	 * Per-chip ("all ports") interrupt coalescing feature.
+	 * This is only for GEN_II / GEN_IIE hardware.
+	 *
+	 * Coalescing defers the interrupt until either the IO_THRESHOLD
+	 * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+	 */
+	COAL_REG_BASE		= 0x18000,
+	IRQ_COAL_CAUSE		= (COAL_REG_BASE + 0x08),
+	ALL_PORTS_COAL_IRQ	= (1 << 4),	/* all ports irq event */
+
+	IRQ_COAL_IO_THRESHOLD   = (COAL_REG_BASE + 0xcc),
+	IRQ_COAL_TIME_THRESHOLD = (COAL_REG_BASE + 0xd0),
+
+	/*
+	 * Registers for the (unused here) transaction coalescing feature:
+	 */
+	TRAN_COAL_CAUSE_LO	= (COAL_REG_BASE + 0x88),
+	TRAN_COAL_CAUSE_HI	= (COAL_REG_BASE + 0x8c),
+
+	SATAHC0_REG_BASE	= 0x20000,
+	FLASH_CTL		= 0x1046c,
+	GPIO_PORT_CTL		= 0x104f0,
+	RESET_CFG		= 0x180d8,
 
 	MV_PCI_REG_SZ		= MV_MAJOR_REG_AREA_SZ,
 	MV_SATAHC_REG_SZ	= MV_MAJOR_REG_AREA_SZ,
@@ -117,17 +157,16 @@ enum {
 
 	/* Host Flags */
 	MV_FLAG_DUAL_HC		= (1 << 30),  /* two SATA Host Controllers */
-	MV_FLAG_IRQ_COALESCE	= (1 << 29),  /* IRQ coalescing capability */
 
 	MV_COMMON_FLAGS		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
-				  ATA_FLAG_PIO_POLLING,
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
 
-	MV_6XXX_FLAGS		= MV_FLAG_IRQ_COALESCE,
+	MV_GEN_I_FLAGS		= MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI,
 
-	MV_GENIIE_FLAGS		= MV_COMMON_FLAGS | MV_6XXX_FLAGS |
-				  ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
-				  ATA_FLAG_NCQ | ATA_FLAG_AN,
+	MV_GEN_II_FLAGS		= MV_COMMON_FLAGS | ATA_FLAG_NCQ |
+				  ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA,
+
+	MV_GEN_IIE_FLAGS	= MV_GEN_II_FLAGS | ATA_FLAG_AN,
 
 	CRQB_FLAG_READ		= (1 << 0),
 	CRQB_TAG_SHIFT		= 1,
@@ -146,50 +185,53 @@ enum {
 
 	/* PCI interface registers */
 
-	PCI_COMMAND_OFS		= 0xc00,
-	PCI_COMMAND_MRDTRIG	= (1 << 7),	/* PCI Master Read Trigger */
+	MV_PCI_COMMAND		= 0xc00,
+	MV_PCI_COMMAND_MWRCOM	= (1 << 4),	/* PCI Master Write Combining */
+	MV_PCI_COMMAND_MRDTRIG	= (1 << 7),	/* PCI Master Read Trigger */
 
-	PCI_MAIN_CMD_STS_OFS	= 0xd30,
+	PCI_MAIN_CMD_STS	= 0xd30,
 	STOP_PCI_MASTER		= (1 << 2),
 	PCI_MASTER_EMPTY	= (1 << 3),
 	GLOB_SFT_RST		= (1 << 4),
 
-	MV_PCI_MODE_OFS		= 0xd00,
+	MV_PCI_MODE		= 0xd00,
 	MV_PCI_MODE_MASK	= 0x30,
 
 	MV_PCI_EXP_ROM_BAR_CTL	= 0xd2c,
 	MV_PCI_DISC_TIMER	= 0xd04,
 	MV_PCI_MSI_TRIGGER	= 0xc38,
 	MV_PCI_SERR_MASK	= 0xc28,
-	MV_PCI_XBAR_TMOUT_OFS	= 0x1d04,
+	MV_PCI_XBAR_TMOUT	= 0x1d04,
 	MV_PCI_ERR_LOW_ADDRESS	= 0x1d40,
 	MV_PCI_ERR_HIGH_ADDRESS	= 0x1d44,
 	MV_PCI_ERR_ATTRIBUTE	= 0x1d48,
 	MV_PCI_ERR_COMMAND	= 0x1d50,
 
-	PCI_IRQ_CAUSE_OFS	= 0x1d58,
-	PCI_IRQ_MASK_OFS	= 0x1d5c,
+	PCI_IRQ_CAUSE		= 0x1d58,
+	PCI_IRQ_MASK		= 0x1d5c,
 	PCI_UNMASK_ALL_IRQS	= 0x7fffff,	/* bits 22-0 */
 
-	PCIE_IRQ_CAUSE_OFS	= 0x1900,
-	PCIE_IRQ_MASK_OFS	= 0x1910,
+	PCIE_IRQ_CAUSE		= 0x1900,
+	PCIE_IRQ_MASK		= 0x1910,
 	PCIE_UNMASK_ALL_IRQS	= 0x40a,	/* assorted bits */
 
 	/* Host Controller Main Interrupt Cause/Mask registers (1 per-chip) */
-	PCI_HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
-	PCI_HC_MAIN_IRQ_MASK_OFS  = 0x1d64,
-	SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020,
-	SOC_HC_MAIN_IRQ_MASK_OFS  = 0x20024,
-	ERR_IRQ			= (1 << 0),	/* shift by port # */
-	DONE_IRQ		= (1 << 1),	/* shift by port # */
+	PCI_HC_MAIN_IRQ_CAUSE	= 0x1d60,
+	PCI_HC_MAIN_IRQ_MASK	= 0x1d64,
+	SOC_HC_MAIN_IRQ_CAUSE	= 0x20020,
+	SOC_HC_MAIN_IRQ_MASK	= 0x20024,
+	ERR_IRQ			= (1 << 0),	/* shift by (2 * port #) */
+	DONE_IRQ		= (1 << 1),	/* shift by (2 * port #) */
 	HC0_IRQ_PEND		= 0x1ff,	/* bits 0-8 = HC0's ports */
 	HC_SHIFT		= 9,		/* bits 9-17 = HC1's ports */
+	DONE_IRQ_0_3		= 0x000000aa,	/* DONE_IRQ ports 0,1,2,3 */
+	DONE_IRQ_4_7		= (DONE_IRQ_0_3 << HC_SHIFT),  /* 4,5,6,7 */
 	PCI_ERR			= (1 << 18),
-	TRAN_LO_DONE		= (1 << 19),	/* 6xxx: IRQ coalescing */
-	TRAN_HI_DONE		= (1 << 20),	/* 6xxx: IRQ coalescing */
-	PORTS_0_3_COAL_DONE	= (1 << 8),
-	PORTS_4_7_COAL_DONE	= (1 << 17),
-	PORTS_0_7_COAL_DONE	= (1 << 21),	/* 6xxx: IRQ coalescing */
+	TRAN_COAL_LO_DONE	= (1 << 19),	/* transaction coalescing */
+	TRAN_COAL_HI_DONE	= (1 << 20),	/* transaction coalescing */
+	PORTS_0_3_COAL_DONE	= (1 << 8),	/* HC0 IRQ coalescing */
+	PORTS_4_7_COAL_DONE	= (1 << 17),	/* HC1 IRQ coalescing */
+	ALL_PORTS_COAL_DONE	= (1 << 21),	/* GEN_II(E) IRQ coalescing */
 	GPIO_INT		= (1 << 22),
 	SELF_INT		= (1 << 23),
 	TWSI_INT		= (1 << 24),
@@ -198,52 +240,72 @@ enum {
 	HC_MAIN_RSVD_SOC	= (0x3fffffb << 6),     /* bits 31-9, 7-6 */
 
 	/* SATAHC registers */
-	HC_CFG_OFS		= 0,
+	HC_CFG			= 0x00,
 
-	HC_IRQ_CAUSE_OFS	= 0x14,
+	HC_IRQ_CAUSE		= 0x14,
 	DMA_IRQ			= (1 << 0),	/* shift by port # */
 	HC_COAL_IRQ		= (1 << 4),	/* IRQ coalescing */
 	DEV_IRQ			= (1 << 8),	/* shift by port # */
 
+	/*
+	 * Per-HC (Host-Controller) interrupt coalescing feature.
+	 * This is present on all chip generations.
+	 *
+	 * Coalescing defers the interrupt until either the IO_THRESHOLD
+	 * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+	 */
+	HC_IRQ_COAL_IO_THRESHOLD	= 0x000c,
+	HC_IRQ_COAL_TIME_THRESHOLD	= 0x0010,
+
+	SOC_LED_CTRL		= 0x2c,
+	SOC_LED_CTRL_BLINK	= (1 << 0),	/* Active LED blink */
+	SOC_LED_CTRL_ACT_PRESENCE = (1 << 2),	/* Multiplex dev presence */
+						/*  with dev activity LED */
+
 	/* Shadow block registers */
-	SHD_BLK_OFS		= 0x100,
-	SHD_CTL_AST_OFS		= 0x20,		/* ofs from SHD_BLK_OFS */
+	SHD_BLK			= 0x100,
+	SHD_CTL_AST		= 0x20,		/* ofs from SHD_BLK */
 
 	/* SATA registers */
-	SATA_STATUS_OFS		= 0x300,  /* ctrl, err regs follow status */
-	SATA_ACTIVE_OFS		= 0x350,
-	SATA_FIS_IRQ_CAUSE_OFS	= 0x364,
-	SATA_FIS_IRQ_AN		= (1 << 9),	/* async notification */
+	SATA_STATUS		= 0x300,  /* ctrl, err regs follow status */
+	SATA_ACTIVE		= 0x350,
+	FIS_IRQ_CAUSE		= 0x364,
+	FIS_IRQ_CAUSE_AN	= (1 << 9),	/* async notification */
 
-	LTMODE_OFS		= 0x30c,
+	LTMODE			= 0x30c,	/* requires read-after-write */
 	LTMODE_BIT8		= (1 << 8),	/* unknown, but necessary */
 
+	PHY_MODE2		= 0x330,
 	PHY_MODE3		= 0x310,
-	PHY_MODE4		= 0x314,
+
+	PHY_MODE4		= 0x314,	/* requires read-after-write */
 	PHY_MODE4_CFG_MASK	= 0x00000003,	/* phy internal config field */
 	PHY_MODE4_CFG_VALUE	= 0x00000001,	/* phy internal config field */
 	PHY_MODE4_RSVD_ZEROS	= 0x5de3fffa,	/* Gen2e always write zeros */
 	PHY_MODE4_RSVD_ONES	= 0x00000005,	/* Gen2e always write ones */
 
-	PHY_MODE2		= 0x330,
-	SATA_IFCTL_OFS		= 0x344,
-	SATA_TESTCTL_OFS	= 0x348,
-	SATA_IFSTAT_OFS		= 0x34c,
-	VENDOR_UNIQUE_FIS_OFS	= 0x35c,
+	SATA_IFCTL		= 0x344,
+	SATA_TESTCTL		= 0x348,
+	SATA_IFSTAT		= 0x34c,
+	VENDOR_UNIQUE_FIS	= 0x35c,
 
-	FISCFG_OFS		= 0x360,
+	FISCFG			= 0x360,
 	FISCFG_WAIT_DEV_ERR	= (1 << 8),	/* wait for host on DevErr */
 	FISCFG_SINGLE_SYNC	= (1 << 16),	/* SYNC on DMA activation */
 
+	PHY_MODE9_GEN2		= 0x398,
+	PHY_MODE9_GEN1		= 0x39c,
+	PHYCFG_OFS		= 0x3a0,	/* only in 65n devices */
+
 	MV5_PHY_MODE		= 0x74,
-	MV5_LTMODE_OFS		= 0x30,
-	MV5_PHY_CTL_OFS		= 0x0C,
-	SATA_INTERFACE_CFG_OFS	= 0x050,
+	MV5_LTMODE		= 0x30,
+	MV5_PHY_CTL		= 0x0C,
+	SATA_IFCFG		= 0x050,
 
 	MV_M2_PREAMP_MASK	= 0x7e0,
 
 	/* Port registers */
-	EDMA_CFG_OFS		= 0,
+	EDMA_CFG		= 0,
 	EDMA_CFG_Q_DEPTH	= 0x1f,		/* max device queue depth */
 	EDMA_CFG_NCQ		= (1 << 5),	/* for R/W FPDMA queued */
 	EDMA_CFG_NCQ_GO_ON_ERR	= (1 << 14),	/* continue on error */
@@ -252,8 +314,8 @@ enum {
 	EDMA_CFG_EDMA_FBS	= (1 << 16),	/* EDMA FIS-Based Switching */
 	EDMA_CFG_FBS		= (1 << 26),	/* FIS-Based Switching */
 
-	EDMA_ERR_IRQ_CAUSE_OFS	= 0x8,
-	EDMA_ERR_IRQ_MASK_OFS	= 0xc,
+	EDMA_ERR_IRQ_CAUSE	= 0x8,
+	EDMA_ERR_IRQ_MASK	= 0xc,
 	EDMA_ERR_D_PAR		= (1 << 0),	/* UDMA data parity err */
 	EDMA_ERR_PRD_PAR	= (1 << 1),	/* UDMA PRD parity err */
 	EDMA_ERR_DEV		= (1 << 2),	/* device error */
@@ -322,30 +384,36 @@ enum {
 				  EDMA_ERR_INTRL_PAR |
 				  EDMA_ERR_IORDY,
 
-	EDMA_REQ_Q_BASE_HI_OFS	= 0x10,
-	EDMA_REQ_Q_IN_PTR_OFS	= 0x14,		/* also contains BASE_LO */
+	EDMA_REQ_Q_BASE_HI	= 0x10,
+	EDMA_REQ_Q_IN_PTR	= 0x14,		/* also contains BASE_LO */
 
-	EDMA_REQ_Q_OUT_PTR_OFS	= 0x18,
+	EDMA_REQ_Q_OUT_PTR	= 0x18,
 	EDMA_REQ_Q_PTR_SHIFT	= 5,
 
-	EDMA_RSP_Q_BASE_HI_OFS	= 0x1c,
-	EDMA_RSP_Q_IN_PTR_OFS	= 0x20,
-	EDMA_RSP_Q_OUT_PTR_OFS	= 0x24,		/* also contains BASE_LO */
+	EDMA_RSP_Q_BASE_HI	= 0x1c,
+	EDMA_RSP_Q_IN_PTR	= 0x20,
+	EDMA_RSP_Q_OUT_PTR	= 0x24,		/* also contains BASE_LO */
 	EDMA_RSP_Q_PTR_SHIFT	= 3,
 
-	EDMA_CMD_OFS		= 0x28,		/* EDMA command register */
+	EDMA_CMD		= 0x28,		/* EDMA command register */
 	EDMA_EN			= (1 << 0),	/* enable EDMA */
 	EDMA_DS			= (1 << 1),	/* disable EDMA; self-negated */
 	EDMA_RESET		= (1 << 2),	/* reset eng/trans/link/phy */
 
-	EDMA_STATUS_OFS		= 0x30,		/* EDMA engine status */
+	EDMA_STATUS		= 0x30,		/* EDMA engine status */
 	EDMA_STATUS_CACHE_EMPTY	= (1 << 6),	/* GenIIe command cache empty */
 	EDMA_STATUS_IDLE	= (1 << 7),	/* GenIIe EDMA enabled/idle */
 
-	EDMA_IORDY_TMOUT_OFS	= 0x34,
-	EDMA_ARB_CFG_OFS	= 0x38,
+	EDMA_IORDY_TMOUT	= 0x34,
+	EDMA_ARB_CFG		= 0x38,
 
-	EDMA_HALTCOND_OFS	= 0x60,		/* GenIIe halt conditions */
+	EDMA_HALTCOND		= 0x60,		/* GenIIe halt conditions */
+	EDMA_UNKNOWN_RSVD	= 0x6C,		/* GenIIe unknown/reserved */
+
+	BMDMA_CMD		= 0x224,	/* bmdma command register */
+	BMDMA_STATUS		= 0x228,	/* bmdma status register */
+	BMDMA_PRD_LOW		= 0x22c,	/* bmdma PRD addr 31:0 */
+	BMDMA_PRD_HIGH		= 0x230,	/* bmdma PRD addr 63:32 */
 
 	/* Host private flags (hp_flags) */
 	MV_HP_FLAG_MSI		= (1 << 0),
@@ -359,12 +427,14 @@ enum {
 	MV_HP_PCIE		= (1 << 9),	/* PCIe bus/regs: 7042 */
 	MV_HP_CUT_THROUGH	= (1 << 10),	/* can use EDMA cut-through */
 	MV_HP_FLAG_SOC		= (1 << 11),	/* SystemOnChip, no PCI */
+	MV_HP_QUIRK_LED_BLINK_EN = (1 << 12),	/* is led blinking enabled? */
 
 	/* Port private flags (pp_flags) */
 	MV_PP_FLAG_EDMA_EN	= (1 << 0),	/* is EDMA engine enabled? */
 	MV_PP_FLAG_NCQ_EN	= (1 << 1),	/* is EDMA set up for NCQ? */
 	MV_PP_FLAG_FBS_EN	= (1 << 2),	/* is EDMA set up for FBS? */
 	MV_PP_FLAG_DELAYED_EH	= (1 << 3),	/* delayed dev err handling */
+	MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4),	/* ignore initial ATA_DRDY */
 };
 
 #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
@@ -433,6 +503,18 @@ struct mv_sg {
 	__le32			reserved;
 };
 
+/*
+ * We keep a local cache of a few frequently accessed port
+ * registers here, to avoid having to read them (very slow)
+ * when switching between EDMA and non-EDMA modes.
+ */
+struct mv_cached_regs {
+	u32			fiscfg;
+	u32			ltmode;
+	u32			haltcond;
+	u32			unknown_rsvd;
+};
+
 struct mv_port_priv {
 	struct mv_crqb		*crqb;
 	dma_addr_t		crqb_dma;
@@ -445,6 +527,7 @@ struct mv_port_priv {
 	unsigned int		resp_idx;
 
 	u32			pp_flags;
+	struct mv_cached_regs	cached;
 	unsigned int		delayed_eh_pmp_map;
 };
 
@@ -462,8 +545,8 @@ struct mv_host_priv {
 	void __iomem		*base;
 	void __iomem		*main_irq_cause_addr;
 	void __iomem		*main_irq_mask_addr;
-	u32			irq_cause_ofs;
-	u32			irq_mask_ofs;
+	u32			irq_cause_offset;
+	u32			irq_mask_offset;
 	u32			unmask_all_irqs;
 	/*
 	 * These consistent DMA memory pools give us guaranteed
@@ -530,12 +613,14 @@ static int mv_soc_reset_hc(struct mv_hos
 static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
 				      void __iomem *mmio);
 static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+				  void __iomem *mmio, unsigned int port);
 static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
 			     unsigned int port_no);
 static int mv_stop_edma(struct ata_port *ap);
 static int mv_stop_edma_engine(void __iomem *port_mmio);
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma);
 
 static void mv_pmp_select(struct ata_port *ap, int pmp);
 static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -546,6 +631,14 @@ static void mv_pmp_error_handler(struct
 static void mv_process_crpb_entries(struct ata_port *ap,
 					struct mv_port_priv *pp);
 
+static void mv_sff_irq_clear(struct ata_port *ap);
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc);
+static void mv_bmdma_setup(struct ata_queued_cmd *qc);
+static void mv_bmdma_start(struct ata_queued_cmd *qc);
+static void mv_bmdma_stop(struct ata_queued_cmd *qc);
+static u8   mv_bmdma_status(struct ata_port *ap);
+static u8 mv_sff_check_status(struct ata_port *ap);
+
 /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
  * because we have to allow room for worst case splitting of
  * PRDs for 64K boundaries in mv_fill_sg().
@@ -566,6 +659,8 @@ static struct scsi_host_template mv6_sht
 static struct ata_port_operations mv5_ops = {
 	.inherits		= &ata_sff_port_ops,
 
+	.lost_interrupt		= ATA_OP_NULL,
+
 	.qc_defer		= mv_qc_defer,
 	.qc_prep		= mv_qc_prep,
 	.qc_issue		= mv_qc_issue,
@@ -593,6 +688,14 @@ static struct ata_port_operations mv6_op
 	.pmp_softreset		= mv_softreset,
 	.softreset		= mv_softreset,
 	.error_handler		= mv_pmp_error_handler,
+
+	.sff_check_status	= mv_sff_check_status,
+	.sff_irq_clear		= mv_sff_irq_clear,
+	.check_atapi_dma	= mv_check_atapi_dma,
+	.bmdma_setup		= mv_bmdma_setup,
+	.bmdma_start		= mv_bmdma_start,
+	.bmdma_stop		= mv_bmdma_stop,
+	.bmdma_status		= mv_bmdma_status,
 };
 
 static struct ata_port_operations mv_iie_ops = {
@@ -603,54 +706,50 @@ static struct ata_port_operations mv_iie
 
 static const struct ata_port_info mv_port_info[] = {
 	{  /* chip_504x */
-		.flags		= MV_COMMON_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_I_FLAGS,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_508x */
-		.flags		= MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_5080 */
-		.flags		= MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_604x */
-		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS |
-				  ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
-				  ATA_FLAG_NCQ,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_II_FLAGS,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv6_ops,
 	},
 	{  /* chip_608x */
-		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS |
-				  ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
-				  ATA_FLAG_NCQ | MV_FLAG_DUAL_HC,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv6_ops,
 	},
 	{  /* chip_6042 */
-		.flags		= MV_GENIIE_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_IIE_FLAGS,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv_iie_ops,
 	},
 	{  /* chip_7042 */
-		.flags		= MV_GENIIE_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_IIE_FLAGS,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv_iie_ops,
 	},
 	{  /* chip_soc */
-		.flags		= MV_GENIIE_FLAGS,
-		.pio_mask	= 0x1f,	/* pio0-4 */
+		.flags		= MV_GEN_IIE_FLAGS,
+		.pio_mask	= ATA_PIO4,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv_iie_ops,
 	},
@@ -714,6 +813,14 @@ static const struct mv_hw_ops mv_soc_ops
 	.reset_bus		= mv_soc_reset_bus,
 };
 
+static const struct mv_hw_ops mv_soc_65n_ops = {
+	.phy_errata		= mv_soc_65n_phy_errata,
+	.enable_leds		= mv_soc_enable_leds,
+	.reset_hc		= mv_soc_reset_hc,
+	.reset_flash		= mv_soc_reset_flash,
+	.reset_bus		= mv_soc_reset_bus,
+};
+
 /*
  * Functions
  */
@@ -754,7 +861,7 @@ static inline unsigned int mv_hardport_f
 
 static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
 {
-	return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
+	return (base + SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
 }
 
 static inline void __iomem *mv_hc_base_from_port(void __iomem *base,
@@ -794,6 +901,62 @@ static inline int mv_get_hc_count(unsign
 	return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
 }
 
+/**
+ *      mv_save_cached_regs - (re-)initialize cached port registers
+ *      @ap: the port whose registers we are caching
+ *
+ *	Initialize the local cache of port registers,
+ *	so that reading them over and over again can
+ *	be avoided on the hotter paths of this driver.
+ *	This saves a few microseconds each time we switch
+ *	to/from EDMA mode to perform (eg.) a drive cache flush.
+ */
+static void mv_save_cached_regs(struct ata_port *ap)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+	struct mv_port_priv *pp = ap->private_data;
+
+	pp->cached.fiscfg = readl(port_mmio + FISCFG);
+	pp->cached.ltmode = readl(port_mmio + LTMODE);
+	pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND);
+	pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD);
+}
+
+/**
+ *      mv_write_cached_reg - write to a cached port register
+ *      @addr: hardware address of the register
+ *      @old: pointer to cached value of the register
+ *      @new: new value for the register
+ *
+ *	Write a new value to a cached register,
+ *	but only if the value is different from before.
+ */
+static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
+{
+	if (new != *old) {
+		unsigned long laddr;
+		*old = new;
+		/*
+		 * Workaround for 88SX60x1-B2 FEr SATA#13:
+		 * Read-after-write is needed to prevent generating 64-bit
+		 * write cycles on the PCI bus for SATA interface registers
+		 * at offsets ending in 0x4 or 0xc.
+		 *
+		 * Looks like a lot of fuss, but it avoids an unnecessary
+		 * +1 usec read-after-write delay for unaffected registers.
+		 */
+		laddr = (long)addr & 0xffff;
+		if (laddr >= 0x300 && laddr <= 0x33c) {
+			laddr &= 0x000f;
+			if (laddr == 0x4 || laddr == 0xc) {
+				writelfl(new, addr); /* read after write */
+				return;
+			}
+		}
+		writel(new, addr); /* unaffected by the errata */
+	}
+}
+
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)
@@ -807,10 +970,10 @@ static void mv_set_edma_ptrs(void __iome
 	index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
 
 	WARN_ON(pp->crqb_dma & 0x3ff);
-	writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+	writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI);
 	writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index,
-		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
-	writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+		 port_mmio + EDMA_REQ_Q_IN_PTR);
+	writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR);
 
 	/*
 	 * initialize response queue
@@ -819,10 +982,27 @@ static void mv_set_edma_ptrs(void __iome
 	index = pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT;
 
 	WARN_ON(pp->crpb_dma & 0xff);
-	writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
-	writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+	writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI);
+	writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR);
 	writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index,
-		 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+		 port_mmio + EDMA_RSP_Q_OUT_PTR);
+}
+
+static void mv_write_main_irq_mask(u32 mask, struct mv_host_priv *hpriv)
+{
+	/*
+	 * When writing to the main_irq_mask in hardware,
+	 * we must ensure exclusivity between the interrupt coalescing bits
+	 * and the corresponding individual port DONE_IRQ bits.
+	 *
+	 * Note that this register is really an "IRQ enable" register,
+	 * not an "IRQ mask" register as Marvell's naming might suggest.
+	 */
+	if (mask & (ALL_PORTS_COAL_DONE | PORTS_0_3_COAL_DONE))
+		mask &= ~DONE_IRQ_0_3;
+	if (mask & (ALL_PORTS_COAL_DONE | PORTS_4_7_COAL_DONE))
+		mask &= ~DONE_IRQ_4_7;
+	writelfl(mask, hpriv->main_irq_mask_addr);
 }
 
 static void mv_set_main_irq_mask(struct ata_host *host,
@@ -835,7 +1015,7 @@ static void mv_set_main_irq_mask(struct
 	new_mask = (old_mask & ~disable_bits) | enable_bits;
 	if (new_mask != old_mask) {
 		hpriv->main_irq_mask = new_mask;
-		writelfl(new_mask, hpriv->main_irq_mask_addr);
+		mv_write_main_irq_mask(new_mask, hpriv);
 	}
 }
 
@@ -852,8 +1032,94 @@ static void mv_enable_port_irqs(struct a
 	mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
 }
 
+static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
+					  void __iomem *port_mmio,
+					  unsigned int port_irqs)
+{
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	int hardport = mv_hardport_from_port(ap->port_no);
+	void __iomem *hc_mmio = mv_hc_base_from_port(
+				mv_host_base(ap->host), ap->port_no);
+	u32 hc_irq_cause;
+
+	/* clear EDMA event indicators, if any */
+	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
+
+	/* clear pending irq events */
+	hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
+	writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE);
+
+	/* clear FIS IRQ Cause */
+	if (IS_GEN_IIE(hpriv))
+		writelfl(0, port_mmio + FIS_IRQ_CAUSE);
+
+	mv_enable_port_irqs(ap, port_irqs);
+}
+
+static void mv_set_irq_coalescing(struct ata_host *host,
+				  unsigned int count, unsigned int usecs)
+{
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *mmio = hpriv->base, *hc_mmio;
+	u32 coal_enable = 0;
+	unsigned long flags;
+	unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC;
+	const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
+							ALL_PORTS_COAL_DONE;
+
+	/* Disable IRQ coalescing if either threshold is zero */
+	if (!usecs || !count) {
+		clks = count = 0;
+	} else {
+		/* Respect maximum limits of the hardware */
+		clks = usecs * COAL_CLOCKS_PER_USEC;
+		if (clks > MAX_COAL_TIME_THRESHOLD)
+			clks = MAX_COAL_TIME_THRESHOLD;
+		if (count > MAX_COAL_IO_COUNT)
+			count = MAX_COAL_IO_COUNT;
+	}
+
+	spin_lock_irqsave(&host->lock, flags);
+	mv_set_main_irq_mask(host, coal_disable, 0);
+
+	if (is_dual_hc && !IS_GEN_I(hpriv)) {
+		/*
+		 * GEN_II/GEN_IIE with dual host controllers:
+		 * one set of global thresholds for the entire chip.
+		 */
+		writel(clks,  mmio + IRQ_COAL_TIME_THRESHOLD);
+		writel(count, mmio + IRQ_COAL_IO_THRESHOLD);
+		/* clear leftover coal IRQ bit */
+		writel(~ALL_PORTS_COAL_IRQ, mmio + IRQ_COAL_CAUSE);
+		if (count)
+			coal_enable = ALL_PORTS_COAL_DONE;
+		clks = count = 0; /* force clearing of regular regs below */
+	}
+
+	/*
+	 * All chips: independent thresholds for each HC on the chip.
+	 */
+	hc_mmio = mv_hc_base_from_port(mmio, 0);
+	writel(clks,  hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD);
+	writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD);
+	writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE);
+	if (count)
+		coal_enable |= PORTS_0_3_COAL_DONE;
+	if (is_dual_hc) {
+		hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC);
+		writel(clks,  hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD);
+		writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD);
+		writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE);
+		if (count)
+			coal_enable |= PORTS_4_7_COAL_DONE;
+	}
+
+	mv_set_main_irq_mask(host, 0, coal_enable);
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
 /**
- *      mv_start_dma - Enable eDMA engine
+ *      mv_start_edma - Enable eDMA engine
  *      @base: port base address
  *      @pp: port private data
  *
@@ -863,7 +1129,7 @@ static void mv_enable_port_irqs(struct a
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
+static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
 			 struct mv_port_priv *pp, u8 protocol)
 {
 	int want_ncq = (protocol == ATA_PROT_NCQ);
@@ -875,28 +1141,13 @@ static void mv_start_dma(struct ata_port
 	}
 	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
 		struct mv_host_priv *hpriv = ap->host->private_data;
-		int hardport = mv_hardport_from_port(ap->port_no);
-		void __iomem *hc_mmio = mv_hc_base_from_port(
-					mv_host_base(ap->host), ap->port_no);
-		u32 hc_irq_cause;
 
-		/* clear EDMA event indicators, if any */
-		writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
-
-		/* clear pending irq events */
-		hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
-		writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
-
-		mv_edma_cfg(ap, want_ncq);
-
-		/* clear FIS IRQ Cause */
-		if (IS_GEN_IIE(hpriv))
-			writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+		mv_edma_cfg(ap, want_ncq, 1);
 
 		mv_set_edma_ptrs(port_mmio, hpriv, pp);
-		mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
+		mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
 
-		writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
+		writelfl(EDMA_EN, port_mmio + EDMA_CMD);
 		pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
 	}
 }
@@ -916,7 +1167,7 @@ static void mv_wait_for_edma_empty_idle(
 	 * as a rough guess at what even more drives might require.
 	 */
 	for (i = 0; i < timeout; ++i) {
-		u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS);
+		u32 edma_stat = readl(port_mmio + EDMA_STATUS);
 		if ((edma_stat & empty_idle) == empty_idle)
 			break;
 		udelay(per_loop);
@@ -936,11 +1187,11 @@ static int mv_stop_edma_engine(void __io
 	int i;
 
 	/* Disable eDMA.  The disable bit auto clears. */
-	writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
+	writelfl(EDMA_DS, port_mmio + EDMA_CMD);
 
 	/* Wait for the chip to confirm eDMA is off. */
 	for (i = 10000; i > 0; i--) {
-		u32 reg = readl(port_mmio + EDMA_CMD_OFS);
+		u32 reg = readl(port_mmio + EDMA_CMD);
 		if (!(reg & EDMA_EN))
 			return 0;
 		udelay(10);
@@ -952,6 +1203,7 @@ static int mv_stop_edma(struct ata_port
 {
 	void __iomem *port_mmio = mv_ap_base(ap);
 	struct mv_port_priv *pp = ap->private_data;
+	int err = 0;
 
 	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
 		return 0;
@@ -959,9 +1211,10 @@ static int mv_stop_edma(struct ata_port
 	mv_wait_for_edma_empty_idle(ap);
 	if (mv_stop_edma_engine(port_mmio)) {
 		ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
-		return -EIO;
+		err = -EIO;
 	}
-	return 0;
+	mv_edma_cfg(ap, 0, 0);
+	return err;
 }
 
 #ifdef ATA_DEBUG
@@ -1048,10 +1301,10 @@ static unsigned int mv_scr_offset(unsign
 	case SCR_STATUS:
 	case SCR_CONTROL:
 	case SCR_ERROR:
-		ofs = SATA_STATUS_OFS + (sc_reg_in * sizeof(u32));
+		ofs = SATA_STATUS + (sc_reg_in * sizeof(u32));
 		break;
 	case SCR_ACTIVE:
-		ofs = SATA_ACTIVE_OFS;   /* active is not with the others */
+		ofs = SATA_ACTIVE;   /* active is not with the others */
 		break;
 	default:
 		ofs = 0xffffffffU;
@@ -1076,7 +1329,25 @@ static int mv_scr_write(struct ata_link
 	unsigned int ofs = mv_scr_offset(sc_reg_in);
 
 	if (ofs != 0xffffffffU) {
-		writelfl(val, mv_ap_base(link->ap) + ofs);
+		void __iomem *addr = mv_ap_base(link->ap) + ofs;
+		if (sc_reg_in == SCR_CONTROL) {
+			/*
+			 * Workaround for 88SX60x1 FEr SATA#26:
+			 *
+			 * COMRESETs have to take care not to accidently
+			 * put the drive to sleep when writing SCR_CONTROL.
+			 * Setting bits 12..15 prevents this problem.
+			 *
+			 * So if we see an outbound COMMRESET, set those bits.
+			 * Ditto for the followup write that clears the reset.
+			 *
+			 * The proprietary driver does this for
+			 * all chip versions, and so do we.
+			 */
+			if ((val & 0xf) == 1 || (readl(addr) & 0xf) == 1)
+				val |= 0xf000;
+		}
+		writelfl(val, addr);
 		return 0;
 	} else
 		return -EINVAL;
@@ -1130,35 +1401,33 @@ static int mv_qc_defer(struct ata_queued
 	return ATA_DEFER_PORT;
 }
 
-static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs)
 {
-	u32 new_fiscfg, old_fiscfg;
-	u32 new_ltmode, old_ltmode;
-	u32 new_haltcond, old_haltcond;
+	struct mv_port_priv *pp = ap->private_data;
+	void __iomem *port_mmio;
 
-	old_fiscfg   = readl(port_mmio + FISCFG_OFS);
-	old_ltmode   = readl(port_mmio + LTMODE_OFS);
-	old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+	u32 fiscfg,   *old_fiscfg   = &pp->cached.fiscfg;
+	u32 ltmode,   *old_ltmode   = &pp->cached.ltmode;
+	u32 haltcond, *old_haltcond = &pp->cached.haltcond;
 
-	new_fiscfg   = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
-	new_ltmode   = old_ltmode & ~LTMODE_BIT8;
-	new_haltcond = old_haltcond | EDMA_ERR_DEV;
+	ltmode   = *old_ltmode & ~LTMODE_BIT8;
+	haltcond = *old_haltcond | EDMA_ERR_DEV;
 
 	if (want_fbs) {
-		new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
-		new_ltmode = old_ltmode | LTMODE_BIT8;
+		fiscfg = *old_fiscfg | FISCFG_SINGLE_SYNC;
+		ltmode = *old_ltmode | LTMODE_BIT8;
 		if (want_ncq)
-			new_haltcond &= ~EDMA_ERR_DEV;
+			haltcond &= ~EDMA_ERR_DEV;
 		else
-			new_fiscfg |=  FISCFG_WAIT_DEV_ERR;
+			fiscfg |=  FISCFG_WAIT_DEV_ERR;
+	} else {
+		fiscfg = *old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
 	}
 
-	if (new_fiscfg != old_fiscfg)
-		writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
-	if (new_ltmode != old_ltmode)
-		writelfl(new_ltmode, port_mmio + LTMODE_OFS);
-	if (new_haltcond != old_haltcond)
-		writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+	port_mmio = mv_ap_base(ap);
+	mv_write_cached_reg(port_mmio + FISCFG, old_fiscfg, fiscfg);
+	mv_write_cached_reg(port_mmio + LTMODE, old_ltmode, ltmode);
+	mv_write_cached_reg(port_mmio + EDMA_HALTCOND, old_haltcond, haltcond);
 }
 
 static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
@@ -1167,16 +1436,95 @@ static void mv_60x1_errata_sata25(struct
 	u32 old, new;
 
 	/* workaround for 88SX60x1 FEr SATA#25 (part 1) */
-	old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS);
+	old = readl(hpriv->base + GPIO_PORT_CTL);
 	if (want_ncq)
 		new = old | (1 << 22);
 	else
 		new = old & ~(1 << 22);
 	if (new != old)
-		writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
+		writel(new, hpriv->base + GPIO_PORT_CTL);
 }
 
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
+/**
+ *	mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma
+ *	@ap: Port being initialized
+ *
+ *	There are two DMA modes on these chips:  basic DMA, and EDMA.
+ *
+ *	Bit-0 of the "EDMA RESERVED" register enables/disables use
+ *	of basic DMA on the GEN_IIE versions of the chips.
+ *
+ *	This bit survives EDMA resets, and must be set for basic DMA
+ *	to function, and should be cleared when EDMA is active.
+ */
+static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma)
+{
+	struct mv_port_priv *pp = ap->private_data;
+	u32 new, *old = &pp->cached.unknown_rsvd;
+
+	if (enable_bmdma)
+		new = *old | 1;
+	else
+		new = *old & ~1;
+	mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD, old, new);
+}
+
+/*
+ * SOC chips have an issue whereby the HDD LEDs don't always blink
+ * during I/O when NCQ is enabled. Enabling a special "LED blink" mode
+ * of the SOC takes care of it, generating a steady blink rate when
+ * any drive on the chip is active.
+ *
+ * Unfortunately, the blink mode is a global hardware setting for the SOC,
+ * so we must use it whenever at least one port on the SOC has NCQ enabled.
+ *
+ * We turn "LED blink" off when NCQ is not in use anywhere, because the normal
+ * LED operation works then, and provides better (more accurate) feedback.
+ *
+ * Note that this code assumes that an SOC never has more than one HC onboard.
+ */
+static void mv_soc_led_blink_enable(struct ata_port *ap)
+{
+	struct ata_host *host = ap->host;
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *hc_mmio;
+	u32 led_ctrl;
+
+	if (hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN)
+		return;
+	hpriv->hp_flags |= MV_HP_QUIRK_LED_BLINK_EN;
+	hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+	led_ctrl = readl(hc_mmio + SOC_LED_CTRL);
+	writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL);
+}
+
+static void mv_soc_led_blink_disable(struct ata_port *ap)
+{
+	struct ata_host *host = ap->host;
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *hc_mmio;
+	u32 led_ctrl;
+	unsigned int port;
+
+	if (!(hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN))
+		return;
+
+	/* disable led-blink only if no ports are using NCQ */
+	for (port = 0; port < hpriv->n_ports; port++) {
+		struct ata_port *this_ap = host->ports[port];
+		struct mv_port_priv *pp = this_ap->private_data;
+
+		if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
+			return;
+	}
+
+	hpriv->hp_flags &= ~MV_HP_QUIRK_LED_BLINK_EN;
+	hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+	led_ctrl = readl(hc_mmio + SOC_LED_CTRL);
+	writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL);
+}
+
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
 {
 	u32 cfg;
 	struct mv_port_priv *pp    = ap->private_data;
@@ -1185,7 +1533,8 @@ static void mv_edma_cfg(struct ata_port
 
 	/* set up non-NCQ EDMA configuration */
 	cfg = EDMA_CFG_Q_DEPTH;		/* always 0x1f for *all* chips */
-	pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
+	pp->pp_flags &=
+	  ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
 
 	if (IS_GEN_I(hpriv))
 		cfg |= (1 << 8);	/* enab config burst size mask */
@@ -1206,7 +1555,7 @@ static void mv_edma_cfg(struct ata_port
 		 */
 		want_fbs &= want_ncq;
 
-		mv_config_fbs(port_mmio, want_ncq, want_fbs);
+		mv_config_fbs(ap, want_ncq, want_fbs);
 
 		if (want_fbs) {
 			pp->pp_flags |= MV_PP_FLAG_FBS_EN;
@@ -1214,20 +1563,29 @@ static void mv_edma_cfg(struct ata_port
 		}
 
 		cfg |= (1 << 23);	/* do not mask PM field in rx'd FIS */
-		cfg |= (1 << 22);	/* enab 4-entry host queue cache */
-		if (!IS_SOC(hpriv))
-			cfg |= (1 << 18);	/* enab early completion */
+		if (want_edma) {
+			cfg |= (1 << 22); /* enab 4-entry host queue cache */
+			if (!IS_SOC(hpriv))
+				cfg |= (1 << 18); /* enab early completion */
+		}
 		if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
 			cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
+		mv_bmdma_enable_iie(ap, !want_edma);
+
+		if (IS_SOC(hpriv)) {
+			if (want_ncq)
+				mv_soc_led_blink_enable(ap);
+			else
+				mv_soc_led_blink_disable(ap);
+		}
 	}
 
 	if (want_ncq) {
 		cfg |= EDMA_CFG_NCQ;
 		pp->pp_flags |=  MV_PP_FLAG_NCQ_EN;
-	} else
-		pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN;
+	}
 
-	writelfl(cfg, port_mmio + EDMA_CFG_OFS);
+	writelfl(cfg, port_mmio + EDMA_CFG);
 }
 
 static void mv_port_free_dma_mem(struct ata_port *ap)
@@ -1274,6 +1632,7 @@ static int mv_port_start(struct ata_port
 	struct device *dev = ap->host->dev;
 	struct mv_host_priv *hpriv = ap->host->private_data;
 	struct mv_port_priv *pp;
+	unsigned long flags;
 	int tag;
 
 	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
@@ -1309,6 +1668,12 @@ static int mv_port_start(struct ata_port
 			pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
 		}
 	}
+
+	spin_lock_irqsave(ap->lock, flags);
+	mv_save_cached_regs(ap);
+	mv_edma_cfg(ap, 0, 0);
+	spin_unlock_irqrestore(ap->lock, flags);
+
 	return 0;
 
 out_port_free_dma_mem:
@@ -1327,8 +1692,12 @@ out_port_free_dma_mem:
  */
 static void mv_port_stop(struct ata_port *ap)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(ap->lock, flags);
 	mv_stop_edma(ap);
 	mv_enable_port_irqs(ap, 0);
+	spin_unlock_irqrestore(ap->lock, flags);
 	mv_port_free_dma_mem(ap);
 }
 
@@ -1357,12 +1726,13 @@ static void mv_fill_sg(struct ata_queued
 			u32 offset = addr & 0xffff;
 			u32 len = sg_len;
 
-			if ((offset + sg_len > 0x10000))
+			if (offset + len > 0x10000)
 				len = 0x10000 - offset;
 
 			mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
 			mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
 			mv_sg->flags_size = cpu_to_le32(len & 0xffff);
+			mv_sg->reserved = 0;
 
 			sg_len -= len;
 			addr += len;
@@ -1374,6 +1744,7 @@ static void mv_fill_sg(struct ata_queued
 
 	if (likely(last_sg))
 		last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+	mb(); /* ensure data structure is visible to the chipset */
 }
 
 static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
@@ -1384,6 +1755,180 @@ static void mv_crqb_pack_cmd(__le16 *cmd
 }
 
 /**
+ *	mv_sff_irq_clear - Clear hardware interrupt after DMA.
+ *	@ap: Port associated with this ATA transaction.
+ *
+ *	We need this only for ATAPI bmdma transactions,
+ *	as otherwise we experience spurious interrupts
+ *	after libata-sff handles the bmdma interrupts.
+ */
+static void mv_sff_irq_clear(struct ata_port *ap)
+{
+	mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ);
+}
+
+/**
+ *	mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA.
+ *	@qc: queued command to check for chipset/DMA compatibility.
+ *
+ *	The bmdma engines cannot handle speculative data sizes
+ *	(bytecount under/over flow).  So only allow DMA for
+ *	data transfer commands with known data sizes.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	struct scsi_cmnd *scmd = qc->scsicmd;
+
+	if (scmd) {
+		switch (scmd->cmnd[0]) {
+		case READ_6:
+		case READ_10:
+		case READ_12:
+		case WRITE_6:
+		case WRITE_10:
+		case WRITE_12:
+		case GPCMD_READ_CD:
+		case GPCMD_SEND_DVD_STRUCTURE:
+		case GPCMD_SEND_CUE_SHEET:
+			return 0; /* DMA is safe */
+		}
+	}
+	return -EOPNOTSUPP; /* use PIO instead */
+}
+
+/**
+ *	mv_bmdma_setup - Set up BMDMA transaction
+ *	@qc: queued command to prepare DMA for.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+static void mv_bmdma_setup(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	void __iomem *port_mmio = mv_ap_base(ap);
+	struct mv_port_priv *pp = ap->private_data;
+
+	mv_fill_sg(qc);
+
+	/* clear all DMA cmd bits */
+	writel(0, port_mmio + BMDMA_CMD);
+
+	/* load PRD table addr. */
+	writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16,
+		port_mmio + BMDMA_PRD_HIGH);
+	writelfl(pp->sg_tbl_dma[qc->tag],
+		port_mmio + BMDMA_PRD_LOW);
+
+	/* issue r/w command */
+	ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+/**
+ *	mv_bmdma_start - Start a BMDMA transaction
+ *	@qc: queued command to start DMA on.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+static void mv_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	void __iomem *port_mmio = mv_ap_base(ap);
+	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+	u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START;
+
+	/* start host DMA transaction */
+	writelfl(cmd, port_mmio + BMDMA_CMD);
+}
+
+/**
+ *	mv_bmdma_stop - Stop BMDMA transfer
+ *	@qc: queued command to stop DMA on.
+ *
+ *	Clears the ATA_DMA_START flag in the bmdma control register
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+static void mv_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	void __iomem *port_mmio = mv_ap_base(ap);
+	u32 cmd;
+
+	/* clear start/stop bit */
+	cmd = readl(port_mmio + BMDMA_CMD);
+	cmd &= ~ATA_DMA_START;
+	writelfl(cmd, port_mmio + BMDMA_CMD);
+
+	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+	ata_sff_dma_pause(ap);
+}
+
+/**
+ *	mv_bmdma_status - Read BMDMA status
+ *	@ap: port for which to retrieve DMA status.
+ *
+ *	Read and return equivalent of the sff BMDMA status register.
+ *
+ *	LOCKING:
+ *	Inherited from caller.
+ */
+static u8 mv_bmdma_status(struct ata_port *ap)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+	u32 reg, status;
+
+	/*
+	 * Other bits are valid only if ATA_DMA_ACTIVE==0,
+	 * and the ATA_DMA_INTR bit doesn't exist.
+	 */
+	reg = readl(port_mmio + BMDMA_STATUS);
+	if (reg & ATA_DMA_ACTIVE)
+		status = ATA_DMA_ACTIVE;
+	else
+		status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR;
+	return status;
+}
+
+static void mv_rw_multi_errata_sata24(struct ata_queued_cmd *qc)
+{
+	struct ata_taskfile *tf = &qc->tf;
+	/*
+	 * Workaround for 88SX60x1 FEr SATA#24.
+	 *
+	 * Chip may corrupt WRITEs if multi_count >= 4kB.
+	 * Note that READs are unaffected.
+	 *
+	 * It's not clear if this errata really means "4K bytes",
+	 * or if it always happens for multi_count > 7
+	 * regardless of device sector_size.
+	 *
+	 * So, for safety, any write with multi_count > 7
+	 * gets converted here into a regular PIO write instead:
+	 */
+	if ((tf->flags & ATA_TFLAG_WRITE) && is_multi_taskfile(tf)) {
+		if (qc->dev->multi_count > 7) {
+			switch (tf->command) {
+			case ATA_CMD_WRITE_MULTI:
+				tf->command = ATA_CMD_PIO_WRITE;
+				break;
+			case ATA_CMD_WRITE_MULTI_FUA_EXT:
+				tf->flags &= ~ATA_TFLAG_FUA; /* ugh */
+				/* fall through */
+			case ATA_CMD_WRITE_MULTI_EXT:
+				tf->command = ATA_CMD_PIO_WRITE_EXT;
+				break;
+			}
+		}
+	}
+}
+
+/**
  *      mv_qc_prep - Host specific command preparation.
  *      @qc: queued command to prepare
  *
@@ -1400,17 +1945,24 @@ static void mv_qc_prep(struct ata_queued
 	struct ata_port *ap = qc->ap;
 	struct mv_port_priv *pp = ap->private_data;
 	__le16 *cw;
-	struct ata_taskfile *tf;
+	struct ata_taskfile *tf = &qc->tf;
 	u16 flags = 0;
 	unsigned in_index;
 
-	if ((qc->tf.protocol != ATA_PROT_DMA) &&
-	    (qc->tf.protocol != ATA_PROT_NCQ))
+	switch (tf->protocol) {
+	case ATA_PROT_DMA:
+	case ATA_PROT_NCQ:
+		break;	/* continue below */
+	case ATA_PROT_PIO:
+		mv_rw_multi_errata_sata24(qc);
+		return;
+	default:
 		return;
+	}
 
 	/* Fill in command request block
 	 */
-	if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+	if (!(tf->flags & ATA_TFLAG_WRITE))
 		flags |= CRQB_FLAG_READ;
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
 	flags |= qc->tag << CRQB_TAG_SHIFT;
@@ -1426,7 +1978,6 @@ static void mv_qc_prep(struct ata_queued
 	pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags);
 
 	cw = &pp->crqb[in_index].ata_cmd[0];
-	tf = &qc->tf;
 
 	/* Sadly, the CRQB cannot accomodate all registers--there are
 	 * only 11 bytes...so we must pick and choose required
@@ -1492,16 +2043,16 @@ static void mv_qc_prep_iie(struct ata_qu
 	struct ata_port *ap = qc->ap;
 	struct mv_port_priv *pp = ap->private_data;
 	struct mv_crqb_iie *crqb;
-	struct ata_taskfile *tf;
+	struct ata_taskfile *tf = &qc->tf;
 	unsigned in_index;
 	u32 flags = 0;
 
-	if ((qc->tf.protocol != ATA_PROT_DMA) &&
-	    (qc->tf.protocol != ATA_PROT_NCQ))
+	if ((tf->protocol != ATA_PROT_DMA) &&
+	    (tf->protocol != ATA_PROT_NCQ))
 		return;
 
 	/* Fill in Gen IIE command request block */
-	if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+	if (!(tf->flags & ATA_TFLAG_WRITE))
 		flags |= CRQB_FLAG_READ;
 
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
@@ -1517,7 +2068,6 @@ static void mv_qc_prep_iie(struct ata_qu
 	crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16);
 	crqb->flags = cpu_to_le32(flags);
 
-	tf = &qc->tf;
 	crqb->ata_cmd[0] = cpu_to_le32(
 			(tf->command << 16) |
 			(tf->feature << 24)
@@ -1545,6 +2095,132 @@ static void mv_qc_prep_iie(struct ata_qu
 }
 
 /**
+ *	mv_sff_check_status - fetch device status, if valid
+ *	@ap: ATA port to fetch status from
+ *
+ *	When using command issue via mv_qc_issue_fis(),
+ *	the initial ATA_BUSY state does not show up in the
+ *	ATA status (shadow) register.  This can confuse libata!
+ *
+ *	So we have a hook here to fake ATA_BUSY for that situation,
+ *	until the first time a BUSY, DRQ, or ERR bit is seen.
+ *
+ *	The rest of the time, it simply returns the ATA status register.
+ */
+static u8 mv_sff_check_status(struct ata_port *ap)
+{
+	u8 stat = ioread8(ap->ioaddr.status_addr);
+	struct mv_port_priv *pp = ap->private_data;
+
+	if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) {
+		if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR))
+			pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY;
+		else
+			stat = ATA_BUSY;
+	}
+	return stat;
+}
+
+/**
+ *	mv_send_fis - Send a FIS, using the "Vendor-Unique FIS" register
+ *	@fis: fis to be sent
+ *	@nwords: number of 32-bit words in the fis
+ */
+static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+	u32 ifctl, old_ifctl, ifstat;
+	int i, timeout = 200, final_word = nwords - 1;
+
+	/* Initiate FIS transmission mode */
+	old_ifctl = readl(port_mmio + SATA_IFCTL);
+	ifctl = 0x100 | (old_ifctl & 0xf);
+	writelfl(ifctl, port_mmio + SATA_IFCTL);
+
+	/* Send all words of the FIS except for the final word */
+	for (i = 0; i < final_word; ++i)
+		writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS);
+
+	/* Flag end-of-transmission, and then send the final word */
+	writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL);
+	writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS);
+
+	/*
+	 * Wait for FIS transmission to complete.
+	 * This typically takes just a single iteration.
+	 */
+	do {
+		ifstat = readl(port_mmio + SATA_IFSTAT);
+	} while (!(ifstat & 0x1000) && --timeout);
+
+	/* Restore original port configuration */
+	writelfl(old_ifctl, port_mmio + SATA_IFCTL);
+
+	/* See if it worked */
+	if ((ifstat & 0x3000) != 0x1000) {
+		ata_port_printk(ap, KERN_WARNING,
+				"%s transmission error, ifstat=%08x\n",
+				__func__, ifstat);
+		return AC_ERR_OTHER;
+	}
+	return 0;
+}
+
+/**
+ *	mv_qc_issue_fis - Issue a command directly as a FIS
+ *	@qc: queued command to start
+ *
+ *	Note that the ATA shadow registers are not updated
+ *	after command issue, so the device will appear "READY"
+ *	if polled, even while it is BUSY processing the command.
+ *
+ *	So we use a status hook to fake ATA_BUSY until the drive changes state.
+ *
+ *	Note: we don't get updated shadow regs on *completion*
+ *	of non-data commands. So avoid sending them via this function,
+ *	as they will appear to have completed immediately.
+ *
+ *	GEN_IIE has special registers that we could get the result tf from,
+ *	but earlier chipsets do not.  For now, we ignore those registers.
+ */
+static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct mv_port_priv *pp = ap->private_data;
+	struct ata_link *link = qc->dev->link;
+	u32 fis[5];
+	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]));
+	if (err)
+		return err;
+
+	switch (qc->tf.protocol) {
+	case ATAPI_PROT_PIO:
+		pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+		/* fall through */
+	case ATAPI_PROT_NODATA:
+		ap->hsm_task_state = HSM_ST_FIRST;
+		break;
+	case ATA_PROT_PIO:
+		pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+		if (qc->tf.flags & ATA_TFLAG_WRITE)
+			ap->hsm_task_state = HSM_ST_FIRST;
+		else
+			ap->hsm_task_state = HSM_ST;
+		break;
+	default:
+		ap->hsm_task_state = HSM_ST_LAST;
+		break;
+	}
+
+	if (qc->tf.flags & ATA_TFLAG_POLLING)
+		ata_pio_queue_task(ap, qc, 0);
+	return 0;
+}
+
+/**
  *      mv_qc_issue - Initiate a command to the host
  *      @qc: queued command to start
  *
@@ -1558,14 +2234,28 @@ static void mv_qc_prep_iie(struct ata_qu
  */
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 {
+	static int limit_warnings = 10;
 	struct ata_port *ap = qc->ap;
 	void __iomem *port_mmio = mv_ap_base(ap);
 	struct mv_port_priv *pp = ap->private_data;
 	u32 in_index;
+	unsigned int port_irqs;
 
-	if ((qc->tf.protocol != ATA_PROT_DMA) &&
-	    (qc->tf.protocol != ATA_PROT_NCQ)) {
-		static int limit_warnings = 10;
+	pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */
+
+	switch (qc->tf.protocol) {
+	case ATA_PROT_DMA:
+	case ATA_PROT_NCQ:
+		mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
+		pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
+		in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+
+		/* Write the request in pointer to kick the EDMA to life */
+		writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+					port_mmio + EDMA_REQ_Q_IN_PTR);
+		return 0;
+
+	case ATA_PROT_PIO:
 		/*
 		 * Errata SATA#16, SATA#24: warn if multiple DRQs expected.
 		 *
@@ -1583,27 +2273,46 @@ static unsigned int mv_qc_issue(struct a
 					": attempting PIO w/multiple DRQ: "
 					"this may fail due to h/w errata\n");
 		}
-		/*
-		 * We're about to send a non-EDMA capable command to the
-		 * port.  Turn off EDMA so there won't be problems accessing
-		 * shadow block, etc registers.
-		 */
-		mv_stop_edma(ap);
-		mv_enable_port_irqs(ap, ERR_IRQ);
-		mv_pmp_select(ap, qc->dev->link->pmp);
-		return ata_sff_qc_issue(qc);
+		/* drop through */
+	case ATA_PROT_NODATA:
+	case ATAPI_PROT_PIO:
+	case ATAPI_PROT_NODATA:
+		if (ap->flags & ATA_FLAG_PIO_POLLING)
+			qc->tf.flags |= ATA_TFLAG_POLLING;
+		break;
 	}
 
-	mv_start_dma(ap, port_mmio, pp, qc->tf.protocol);
-
-	pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
-	in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+	if (qc->tf.flags & ATA_TFLAG_POLLING)
+		port_irqs = ERR_IRQ;	/* mask device interrupt when polling */
+	else
+		port_irqs = ERR_IRQ | DONE_IRQ;	/* unmask all interrupts */
 
-	/* and write the request in pointer to kick the EDMA to life */
-	writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
-		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+	/*
+	 * We're about to send a non-EDMA capable command to the
+	 * port.  Turn off EDMA so there won't be problems accessing
+	 * shadow block, etc registers.
+	 */
+	mv_stop_edma(ap);
+	mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
+	mv_pmp_select(ap, qc->dev->link->pmp);
 
-	return 0;
+	if (qc->tf.command == ATA_CMD_READ_LOG_EXT) {
+		struct mv_host_priv *hpriv = ap->host->private_data;
+		/*
+		 * Workaround for 88SX60x1 FEr SATA#25 (part 2).
+		 *
+		 * After any NCQ error, the READ_LOG_EXT command
+		 * from libata-eh *must* use mv_qc_issue_fis().
+		 * Otherwise it might fail, due to chip errata.
+		 *
+		 * Rather than special-case it, we'll just *always*
+		 * use this method here for READ_LOG_EXT, making for
+		 * easier testing.
+		 */
+		if (IS_GEN_II(hpriv))
+			return mv_qc_issue_fis(qc);
+	}
+	return ata_sff_qc_issue(qc);
 }
 
 static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
@@ -1614,8 +2323,12 @@ static struct ata_queued_cmd *mv_get_act
 	if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
 		return NULL;
 	qc = ata_qc_from_tag(ap, ap->link.active_tag);
-	if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
-		qc = NULL;
+	if (qc) {
+		if (qc->tf.flags & ATA_TFLAG_POLLING)
+			qc = NULL;
+		else if (!(qc->flags & ATA_QCFLAG_ACTIVE))
+			qc = NULL;
+	}
 	return qc;
 }
 
@@ -1650,7 +2363,7 @@ static unsigned int mv_get_err_pmp_map(s
 {
 	void __iomem *port_mmio = mv_ap_base(ap);
 
-	return readl(port_mmio + SATA_TESTCTL_OFS) >> 16;
+	return readl(port_mmio + SATA_TESTCTL) >> 16;
 }
 
 static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
@@ -1683,9 +2396,9 @@ static int mv_req_q_empty(struct ata_por
 	void __iomem *port_mmio = mv_ap_base(ap);
 	u32 in_ptr, out_ptr;
 
-	in_ptr  = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS)
+	in_ptr  = (readl(port_mmio + EDMA_REQ_Q_IN_PTR)
 			>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
-	out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
+	out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR)
 			>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
 	return (in_ptr == out_ptr);	/* 1 == queue_is_empty */
 }
@@ -1847,12 +2560,12 @@ static void mv_err_intr(struct ata_port
 	sata_scr_read(&ap->link, SCR_ERROR, &serr);
 	sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
 
-	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE);
 	if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
-		fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
-		writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+		fis_cause = readl(port_mmio + FIS_IRQ_CAUSE);
+		writelfl(~fis_cause, port_mmio + FIS_IRQ_CAUSE);
 	}
-	writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+	writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE);
 
 	if (edma_err_cause & EDMA_ERR_DEV) {
 		/*
@@ -1870,7 +2583,7 @@ static void mv_err_intr(struct ata_port
 
 	if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
 		ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause);
-		if (fis_cause & SATA_FIS_IRQ_AN) {
+		if (fis_cause & FIS_IRQ_CAUSE_AN) {
 			u32 ec = edma_err_cause &
 			       ~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT);
 			sata_async_notification(ap);
@@ -1972,7 +2685,7 @@ static void mv_process_crpb_response(str
 		u16 edma_status = le16_to_cpu(response->flags);
 		/*
 		 * edma_status from a response queue entry:
-		 *   LSB is from EDMA_ERR_IRQ_CAUSE_OFS (non-NCQ only).
+		 *   LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only).
 		 *   MSB is saved ATA status from command completion.
 		 */
 		if (!ncq_enabled) {
@@ -2004,7 +2717,7 @@ static void mv_process_crpb_entries(stru
 	int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN);
 
 	/* Get the hardware queue position index */
-	in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
+	in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR)
 			>> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
 
 	/* Process new responses from since the last time we looked */
@@ -2029,7 +2742,7 @@ static void mv_process_crpb_entries(stru
 	if (work_done)
 		writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
 			 (pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT),
-			 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+			 port_mmio + EDMA_RSP_Q_OUT_PTR);
 }
 
 static void mv_port_intr(struct ata_port *ap, u32 port_cause)
@@ -2084,6 +2797,10 @@ static int mv_host_intr(struct ata_host
 	void __iomem *mmio = hpriv->base, *hc_mmio;
 	unsigned int handled = 0, port;
 
+	/* If asserted, clear the "all ports" IRQ coalescing bit */
+	if (main_irq_cause & ALL_PORTS_COAL_DONE)
+		writel(~ALL_PORTS_COAL_IRQ, mmio + IRQ_COAL_CAUSE);
+
 	for (port = 0; port < hpriv->n_ports; port++) {
 		struct ata_port *ap = host->ports[port];
 		unsigned int p, shift, hardport, port_cause;
@@ -2116,6 +2833,8 @@ static int mv_host_intr(struct ata_host
 			 * to ack (only) those ports via hc_irq_cause.
 			 */
 			ack_irqs = 0;
+			if (hc_cause & PORTS_0_3_COAL_DONE)
+				ack_irqs = HC_COAL_IRQ;
 			for (p = 0; p < MV_PORTS_PER_HC; ++p) {
 				if ((port + p) >= hpriv->n_ports)
 					break;
@@ -2124,7 +2843,7 @@ static int mv_host_intr(struct ata_host
 					ack_irqs |= (DMA_IRQ | DEV_IRQ) << p;
 			}
 			hc_mmio = mv_hc_base_from_port(mmio, port);
-			writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS);
+			writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE);
 			handled = 1;
 		}
 		/*
@@ -2146,7 +2865,7 @@ static int mv_pci_error(struct ata_host
 	unsigned int i, err_mask, printed = 0;
 	u32 err_cause;
 
-	err_cause = readl(mmio + hpriv->irq_cause_ofs);
+	err_cause = readl(mmio + hpriv->irq_cause_offset);
 
 	dev_printk(KERN_ERR, host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n",
 		   err_cause);
@@ -2154,7 +2873,7 @@ static int mv_pci_error(struct ata_host
 	DPRINTK("All regs @ PCI error\n");
 	mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
 
-	writelfl(0, mmio + hpriv->irq_cause_ofs);
+	writelfl(0, mmio + hpriv->irq_cause_offset);
 
 	for (i = 0; i < host->n_ports; i++) {
 		ap = host->ports[i];
@@ -2204,7 +2923,7 @@ static irqreturn_t mv_interrupt(int irq,
 
 	/* for MSI:  block new interrupts while in here */
 	if (using_msi)
-		writel(0, hpriv->main_irq_mask_addr);
+		mv_write_main_irq_mask(0, hpriv);
 
 	main_irq_cause = readl(hpriv->main_irq_cause_addr);
 	pending_irqs   = main_irq_cause & hpriv->main_irq_mask;
@@ -2221,7 +2940,7 @@ static irqreturn_t mv_interrupt(int irq,
 
 	/* for MSI: unmask; interrupt cause bits will retrigger now */
 	if (using_msi)
-		writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr);
+		mv_write_main_irq_mask(hpriv->main_irq_mask, hpriv);
 
 	spin_unlock(&host->lock);
 
@@ -2291,7 +3010,7 @@ static void mv5_reset_bus(struct ata_hos
 
 static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-	writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS);
+	writel(0x0fcfffff, mmio + FLASH_CTL);
 }
 
 static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
@@ -2310,7 +3029,7 @@ static void mv5_enable_leds(struct mv_ho
 {
 	u32 tmp;
 
-	writel(0, mmio + MV_GPIO_PORT_CTL_OFS);
+	writel(0, mmio + GPIO_PORT_CTL);
 
 	/* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
 
@@ -2328,14 +3047,14 @@ static void mv5_phy_errata(struct mv_hos
 	int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0);
 
 	if (fix_apm_sq) {
-		tmp = readl(phy_mmio + MV5_LTMODE_OFS);
+		tmp = readl(phy_mmio + MV5_LTMODE);
 		tmp |= (1 << 19);
-		writel(tmp, phy_mmio + MV5_LTMODE_OFS);
+		writel(tmp, phy_mmio + MV5_LTMODE);
 
-		tmp = readl(phy_mmio + MV5_PHY_CTL_OFS);
+		tmp = readl(phy_mmio + MV5_PHY_CTL);
 		tmp &= ~0x3;
 		tmp |= 0x1;
-		writel(tmp, phy_mmio + MV5_PHY_CTL_OFS);
+		writel(tmp, phy_mmio + MV5_PHY_CTL);
 	}
 
 	tmp = readl(phy_mmio + MV5_PHY_MODE);
@@ -2356,7 +3075,7 @@ static void mv5_reset_hc_port(struct mv_
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);	/* command */
-	writel(0x11f, port_mmio + EDMA_CFG_OFS);
+	writel(0x11f, port_mmio + EDMA_CFG);
 	ZERO(0x004);	/* timer */
 	ZERO(0x008);	/* irq err cause */
 	ZERO(0x00c);	/* irq err mask */
@@ -2367,7 +3086,7 @@ static void mv5_reset_hc_port(struct mv_
 	ZERO(0x024);	/* respq outp */
 	ZERO(0x020);	/* respq inp */
 	ZERO(0x02c);	/* test control */
-	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS);
+	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
 }
 #undef ZERO
 
@@ -2413,16 +3132,16 @@ static void mv_reset_pci_bus(struct ata_
 	struct mv_host_priv *hpriv = host->private_data;
 	u32 tmp;
 
-	tmp = readl(mmio + MV_PCI_MODE_OFS);
+	tmp = readl(mmio + MV_PCI_MODE);
 	tmp &= 0xff00ffff;
-	writel(tmp, mmio + MV_PCI_MODE_OFS);
+	writel(tmp, mmio + MV_PCI_MODE);
 
 	ZERO(MV_PCI_DISC_TIMER);
 	ZERO(MV_PCI_MSI_TRIGGER);
-	writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS);
+	writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
 	ZERO(MV_PCI_SERR_MASK);
-	ZERO(hpriv->irq_cause_ofs);
-	ZERO(hpriv->irq_mask_ofs);
+	ZERO(hpriv->irq_cause_offset);
+	ZERO(hpriv->irq_mask_offset);
 	ZERO(MV_PCI_ERR_LOW_ADDRESS);
 	ZERO(MV_PCI_ERR_HIGH_ADDRESS);
 	ZERO(MV_PCI_ERR_ATTRIBUTE);
@@ -2436,10 +3155,10 @@ static void mv6_reset_flash(struct mv_ho
 
 	mv5_reset_flash(hpriv, mmio);
 
-	tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS);
+	tmp = readl(mmio + GPIO_PORT_CTL);
 	tmp &= 0x3;
 	tmp |= (1 << 5) | (1 << 6);
-	writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS);
+	writel(tmp, mmio + GPIO_PORT_CTL);
 }
 
 /**
@@ -2454,7 +3173,7 @@ static void mv6_reset_flash(struct mv_ho
 static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
 			unsigned int n_hc)
 {
-	void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS;
+	void __iomem *reg = mmio + PCI_MAIN_CMD_STS;
 	int i, rc = 0;
 	u32 t;
 
@@ -2512,7 +3231,7 @@ static void mv6_read_preamp(struct mv_ho
 	void __iomem *port_mmio;
 	u32 tmp;
 
-	tmp = readl(mmio + MV_RESET_CFG_OFS);
+	tmp = readl(mmio + RESET_CFG);
 	if ((tmp & (1 << 0)) == 0) {
 		hpriv->signal[idx].amps = 0x7 << 8;
 		hpriv->signal[idx].pre = 0x1 << 5;
@@ -2528,7 +3247,7 @@ static void mv6_read_preamp(struct mv_ho
 
 static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
 {
-	writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS);
+	writel(0x00000060, mmio + GPIO_PORT_CTL);
 }
 
 static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -2586,6 +3305,7 @@ static void mv6_phy_errata(struct mv_hos
 	 * Workaround for 60x1-B2 errata SATA#13:
 	 * Any write to PHY_MODE4 (above) may corrupt PHY_MODE3,
 	 * so we must always rewrite PHY_MODE3 after PHY_MODE4.
+	 * Or ensure we use writelfl() when writing PHY_MODE4.
 	 */
 	writel(m3, port_mmio + PHY_MODE3);
 
@@ -2637,7 +3357,7 @@ static void mv_soc_reset_hc_port(struct
 	mv_reset_channel(hpriv, mmio, port);
 
 	ZERO(0x028);		/* command */
-	writel(0x101f, port_mmio + EDMA_CFG_OFS);
+	writel(0x101f, port_mmio + EDMA_CFG);
 	ZERO(0x004);		/* timer */
 	ZERO(0x008);		/* irq err cause */
 	ZERO(0x00c);		/* irq err mask */
@@ -2648,7 +3368,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_OFS);
+	writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
 }
 
 #undef ZERO
@@ -2691,14 +3411,61 @@ static void mv_soc_reset_bus(struct ata_
 	return;
 }
 
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+				  void __iomem *mmio, unsigned int port)
+{
+	void __iomem *port_mmio = mv_port_base(mmio, port);
+	u32	reg;
+
+	reg = readl(port_mmio + PHY_MODE3);
+	reg &= ~(0x3 << 27);	/* SELMUPF (bits 28:27) to 1 */
+	reg |= (0x1 << 27);
+	reg &= ~(0x3 << 29);	/* SELMUPI (bits 30:29) to 1 */
+	reg |= (0x1 << 29);
+	writel(reg, port_mmio + PHY_MODE3);
+
+	reg = readl(port_mmio + PHY_MODE4);
+	reg &= ~0x1;	/* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+	reg |= (0x1 << 16);
+	writel(reg, port_mmio + PHY_MODE4);
+
+	reg = readl(port_mmio + PHY_MODE9_GEN2);
+	reg &= ~0xf;	/* TXAMP[3:0] (bits 3:0) to 8 */
+	reg |= 0x8;
+	reg &= ~(0x1 << 14);	/* TXAMP[4] (bit 14) to 0 */
+	writel(reg, port_mmio + PHY_MODE9_GEN2);
+
+	reg = readl(port_mmio + PHY_MODE9_GEN1);
+	reg &= ~0xf;	/* TXAMP[3:0] (bits 3:0) to 8 */
+	reg |= 0x8;
+	reg &= ~(0x1 << 14);	/* TXAMP[4] (bit 14) to 0 */
+	writel(reg, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ *	soc_is_65 - check if the soc is 65 nano device
+ *
+ *	Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ *	register, this register should contain non-zero value and it exists only
+ *	in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+	void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+	if (readl(port0_mmio + PHYCFG_OFS))
+		return true;
+	return false;
+}
+
 static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
 {
-	u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS);
+	u32 ifcfg = readl(port_mmio + SATA_IFCFG);
 
 	ifcfg = (ifcfg & 0xf7f) | 0x9b1000;	/* from chip spec */
 	if (want_gen2i)
 		ifcfg |= (1 << 7);		/* enable gen2i speed */
-	writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS);
+	writelfl(ifcfg, port_mmio + SATA_IFCFG);
 }
 
 static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -2712,7 +3479,7 @@ static void mv_reset_channel(struct mv_h
 	 * to disable the EDMA engine before doing the EDMA_RESET operation.
 	 */
 	mv_stop_edma_engine(port_mmio);
-	writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
+	writelfl(EDMA_RESET, port_mmio + EDMA_CMD);
 
 	if (!IS_GEN_I(hpriv)) {
 		/* Enable 3.0gb/s link speed: this survives EDMA_RESET */
@@ -2721,11 +3488,11 @@ static void mv_reset_channel(struct mv_h
 	/*
 	 * Strobing EDMA_RESET here causes a hard reset of the SATA transport,
 	 * link, and physical layers.  It resets all SATA interface registers
-	 * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
+	 * (except for SATA_IFCFG), and issues a COMRESET to the dev.
 	 */
-	writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS);
+	writelfl(EDMA_RESET, port_mmio + EDMA_CMD);
 	udelay(25);	/* allow reset propagation */
-	writelfl(0, port_mmio + EDMA_CMD_OFS);
+	writelfl(0, port_mmio + EDMA_CMD);
 
 	hpriv->ops->phy_errata(hpriv, mmio, port_no);
 
@@ -2737,12 +3504,12 @@ static void mv_pmp_select(struct ata_por
 {
 	if (sata_pmp_supported(ap)) {
 		void __iomem *port_mmio = mv_ap_base(ap);
-		u32 reg = readl(port_mmio + SATA_IFCTL_OFS);
+		u32 reg = readl(port_mmio + SATA_IFCTL);
 		int old = reg & 0xf;
 
 		if (old != pmp) {
 			reg = (reg & ~0xf) | pmp;
-			writelfl(reg, port_mmio + SATA_IFCTL_OFS);
+			writelfl(reg, port_mmio + SATA_IFCTL);
 		}
 	}
 }
@@ -2774,6 +3541,8 @@ static int mv_hardreset(struct ata_link
 
 	mv_reset_channel(hpriv, mmio, ap->port_no);
 	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+	pp->pp_flags &=
+	  ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
 
 	/* Workaround for errata FEr SATA#10 (part 2) */
 	do {
@@ -2793,6 +3562,8 @@ static int mv_hardreset(struct ata_link
 				extra = HZ; /* only extend it once, max */
 		}
 	} while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
+	mv_save_cached_regs(ap);
+	mv_edma_cfg(ap, 0, 0);
 
 	return rc;
 }
@@ -2813,11 +3584,11 @@ static void mv_eh_thaw(struct ata_port *
 	u32 hc_irq_cause;
 
 	/* clear EDMA errors on this port */
-	writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+	writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
 
 	/* clear pending irq events */
 	hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
-	writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+	writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE);
 
 	mv_enable_port_irqs(ap, ERR_IRQ);
 }
@@ -2836,8 +3607,7 @@ static void mv_eh_thaw(struct ata_port *
  */
 static void mv_port_init(struct ata_ioports *port,  void __iomem *port_mmio)
 {
-	void __iomem *shd_base = port_mmio + SHD_BLK_OFS;
-	unsigned serr_ofs;
+	void __iomem *serr, *shd_base = port_mmio + SHD_BLK;
 
 	/* PIO related setup
 	 */
@@ -2852,23 +3622,23 @@ static void mv_port_init(struct ata_iopo
 	port->status_addr =
 		port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS);
 	/* special case: control/altstatus doesn't have ATA_REG_ address */
-	port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
+	port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST;
 
 	/* unused: */
 	port->cmd_addr = port->bmdma_addr = port->scr_addr = NULL;
 
 	/* Clear any currently outstanding port interrupt conditions */
-	serr_ofs = mv_scr_offset(SCR_ERROR);
-	writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
-	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+	serr = port_mmio + mv_scr_offset(SCR_ERROR);
+	writelfl(readl(serr), serr);
+	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE);
 
 	/* unmask all non-transient EDMA error interrupts */
-	writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
+	writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK);
 
 	VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
-		readl(port_mmio + EDMA_CFG_OFS),
-		readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS),
-		readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
+		readl(port_mmio + EDMA_CFG),
+		readl(port_mmio + EDMA_ERR_IRQ_CAUSE),
+		readl(port_mmio + EDMA_ERR_IRQ_MASK));
 }
 
 static unsigned int mv_in_pcix_mode(struct ata_host *host)
@@ -2879,7 +3649,7 @@ static unsigned int mv_in_pcix_mode(stru
 
 	if (IS_SOC(hpriv) || !IS_PCIE(hpriv))
 		return 0;	/* not PCI-X capable */
-	reg = readl(mmio + MV_PCI_MODE_OFS);
+	reg = readl(mmio + MV_PCI_MODE);
 	if ((reg & MV_PCI_MODE_MASK) == 0)
 		return 0;	/* conventional PCI mode */
 	return 1;	/* chip is in PCI-X mode */
@@ -2892,13 +3662,25 @@ static int mv_pci_cut_through_okay(struc
 	u32 reg;
 
 	if (!mv_in_pcix_mode(host)) {
-		reg = readl(mmio + PCI_COMMAND_OFS);
-		if (reg & PCI_COMMAND_MRDTRIG)
+		reg = readl(mmio + MV_PCI_COMMAND);
+		if (reg & MV_PCI_COMMAND_MRDTRIG)
 			return 0; /* not okay */
 	}
 	return 1; /* okay */
 }
 
+static void mv_60x1b2_errata_pci7(struct ata_host *host)
+{
+	struct mv_host_priv *hpriv = host->private_data;
+	void __iomem *mmio = hpriv->base;
+
+	/* workaround for 60x1-B2 errata PCI#7 */
+	if (mv_in_pcix_mode(host)) {
+		u32 reg = readl(mmio + MV_PCI_COMMAND);
+		writelfl(reg & ~MV_PCI_COMMAND_MWRCOM, mmio + MV_PCI_COMMAND);
+	}
+}
+
 static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
 	struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -2952,6 +3734,7 @@ static int mv_chip_id(struct ata_host *h
 
 		switch (pdev->revision) {
 		case 0x7:
+			mv_60x1b2_errata_pci7(host);
 			hp_flags |= MV_HP_ERRATA_60X1B2;
 			break;
 		case 0x9:
@@ -3015,7 +3798,10 @@ static int mv_chip_id(struct ata_host *h
 		}
 		break;
 	case chip_soc:
-		hpriv->ops = &mv_soc_ops;
+		if (soc_is_65n(hpriv))
+			hpriv->ops = &mv_soc_65n_ops;
+		else
+			hpriv->ops = &mv_soc_ops;
 		hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
 			MV_HP_ERRATA_60X1C0;
 		break;
@@ -3028,12 +3814,12 @@ static int mv_chip_id(struct ata_host *h
 
 	hpriv->hp_flags = hp_flags;
 	if (hp_flags & MV_HP_PCIE) {
-		hpriv->irq_cause_ofs	= PCIE_IRQ_CAUSE_OFS;
-		hpriv->irq_mask_ofs	= PCIE_IRQ_MASK_OFS;
+		hpriv->irq_cause_offset	= PCIE_IRQ_CAUSE;
+		hpriv->irq_mask_offset	= PCIE_IRQ_MASK;
 		hpriv->unmask_all_irqs	= PCIE_UNMASK_ALL_IRQS;
 	} else {
-		hpriv->irq_cause_ofs	= PCI_IRQ_CAUSE_OFS;
-		hpriv->irq_mask_ofs	= PCI_IRQ_MASK_OFS;
+		hpriv->irq_cause_offset	= PCI_IRQ_CAUSE;
+		hpriv->irq_mask_offset	= PCI_IRQ_MASK;
 		hpriv->unmask_all_irqs	= PCI_UNMASK_ALL_IRQS;
 	}
 
@@ -3062,11 +3848,11 @@ static int mv_init_host(struct ata_host
 		goto done;
 
 	if (IS_SOC(hpriv)) {
-		hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS;
-		hpriv->main_irq_mask_addr  = mmio + SOC_HC_MAIN_IRQ_MASK_OFS;
+		hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE;
+		hpriv->main_irq_mask_addr  = mmio + SOC_HC_MAIN_IRQ_MASK;
 	} else {
-		hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS;
-		hpriv->main_irq_mask_addr  = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
+		hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE;
+		hpriv->main_irq_mask_addr  = mmio + PCI_HC_MAIN_IRQ_MASK;
 	}
 
 	/* initialize shadow irq mask with register's value */
@@ -3078,7 +3864,8 @@ static int mv_init_host(struct ata_host
 	n_hc = mv_get_hc_count(host->ports[0]->flags);
 
 	for (port = 0; port < host->n_ports; port++)
-		hpriv->ops->read_preamp(hpriv, port, mmio);
+		if (hpriv->ops->read_preamp)
+			hpriv->ops->read_preamp(hpriv, port, mmio);
 
 	rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
 	if (rc)
@@ -3108,24 +3895,28 @@ static int mv_init_host(struct ata_host
 
 		VPRINTK("HC%i: HC config=0x%08x HC IRQ cause "
 			"(before clear)=0x%08x\n", hc,
-			readl(hc_mmio + HC_CFG_OFS),
-			readl(hc_mmio + HC_IRQ_CAUSE_OFS));
+			readl(hc_mmio + HC_CFG),
+			readl(hc_mmio + HC_IRQ_CAUSE));
 
 		/* Clear any currently outstanding hc interrupt conditions */
-		writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
+		writelfl(0, hc_mmio + HC_IRQ_CAUSE);
 	}
 
-	/* Clear any currently outstanding host interrupt conditions */
-	writelfl(0, mmio + hpriv->irq_cause_ofs);
+	if (!IS_SOC(hpriv)) {
+		/* Clear any currently outstanding host interrupt conditions */
+		writelfl(0, mmio + hpriv->irq_cause_offset);
 
-	/* and unmask interrupt generation for host regs */
-	writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
+		/* and unmask interrupt generation for host regs */
+		writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_offset);
+	}
 
 	/*
 	 * enable only global host interrupts for now.
 	 * The per-port interrupts get done later as ports are set up.
 	 */
 	mv_set_main_irq_mask(host, 0, PCI_ERR);
+	mv_set_irq_coalescing(host, irq_coalescing_io_count,
+				    irq_coalescing_usecs);
 done:
 	return rc;
 }
@@ -3223,7 +4014,7 @@ static int mv_platform_probe(struct plat
 	host->iomap = NULL;
 	hpriv->base = devm_ioremap(&pdev->dev, res->start,
 				   res->end - res->start + 1);
-	hpriv->base -= MV_SATAHC0_REG_BASE;
+	hpriv->base -= SATAHC0_REG_BASE;
 
 	/*
 	 * (Re-)program MBUS remapping windows if we are asked to.
@@ -3287,21 +4078,15 @@ static struct pci_driver mv_pci_driver =
 	.remove			= ata_pci_remove_one,
 };
 
-/*
- * module options
- */
-static int msi;	      /* Use PCI msi; either zero (off, default) or non-zero */
-
-
 /* move to PCI layer or libata core? */
 static int pci_go_64(struct pci_dev *pdev)
 {
 	int rc;
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (rc) {
-			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (rc) {
 				dev_printk(KERN_ERR, &pdev->dev,
 					   "64-bit DMA enable failed\n");
@@ -3309,13 +4094,13 @@ static int pci_go_64(struct pci_dev *pde
 			}
 		}
 	} else {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit DMA enable failed\n");
 			return rc;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit consistent DMA enable failed\n");
@@ -3474,10 +4259,5 @@ MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:" DRV_NAME);
 
-#ifdef CONFIG_PCI
-module_param(msi, int, 0444);
-MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
-#endif
-
 module_init(mv_init);
 module_exit(mv_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_nv.c linux-libre-2.6.30-gnu1/drivers/ata/sata_nv.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_nv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_nv.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,9 +57,9 @@ enum {
 	NV_MMIO_BAR			= 5,
 
 	NV_PORTS			= 2,
-	NV_PIO_MASK			= 0x1f,
-	NV_MWDMA_MASK			= 0x07,
-	NV_UDMA_MASK			= 0x7f,
+	NV_PIO_MASK			= ATA_PIO4,
+	NV_MWDMA_MASK			= ATA_MWDMA2,
+	NV_UDMA_MASK			= ATA_UDMA6,
 	NV_PORT0_SCR_REG_OFFSET		= 0x00,
 	NV_PORT1_SCR_REG_OFFSET		= 0x40,
 
@@ -408,6 +408,7 @@ static struct scsi_host_template nv_swnc
 
 static struct ata_port_operations nv_common_ops = {
 	.inherits		= &ata_bmdma_port_ops,
+	.lost_interrupt		= ATA_OP_NULL,
 	.scr_read		= nv_scr_read,
 	.scr_write		= nv_scr_write,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_promise.c linux-libre-2.6.30-gnu1/drivers/ata/sata_promise.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_promise.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_promise.c	2009-06-09 23:05:27.000000000 -0400
@@ -176,7 +176,9 @@ static const struct ata_port_operations
 	.check_atapi_dma	= pdc_check_atapi_dma,
 	.qc_prep		= pdc_qc_prep,
 	.qc_issue		= pdc_qc_issue,
+
 	.sff_irq_clear		= pdc_irq_clear,
+	.lost_interrupt		= ATA_OP_NULL,
 
 	.post_internal_cmd	= pdc_post_internal_cmd,
 	.error_handler		= pdc_error_handler,
@@ -213,8 +215,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SATA |
 				  PDC_FLAG_SATA_PATA,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_old_sata_ops,
 	},
@@ -222,8 +224,8 @@ static const struct ata_port_info pdc_po
 	[board_2037x_pata] =
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_pata_ops,
 	},
@@ -232,8 +234,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SATA |
 				  PDC_FLAG_4_PORTS,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_old_sata_ops,
 	},
@@ -242,8 +244,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
 				  PDC_FLAG_4_PORTS,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_pata_ops,
 	},
@@ -252,8 +254,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SATA |
 				  PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_sata_ops,
 	},
@@ -262,8 +264,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
 				  PDC_FLAG_GEN_II,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_pata_ops,
 	},
@@ -272,8 +274,8 @@ static const struct ata_port_info pdc_po
 	{
 		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SATA |
 				  PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_sata_ops,
 	},
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_qstor.c linux-libre-2.6.30-gnu1/drivers/ata/sata_qstor.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_qstor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_qstor.c	2009-06-09 23:05:27.000000000 -0400
@@ -147,6 +147,7 @@ static struct ata_port_operations qs_ata
 	.softreset		= ATA_OP_NULL,
 	.error_handler		= qs_error_handler,
 	.post_internal_cmd	= ATA_OP_NULL,
+	.lost_interrupt		= ATA_OP_NULL,
 
 	.scr_read		= qs_scr_read,
 	.scr_write		= qs_scr_write,
@@ -160,7 +161,7 @@ static const struct ata_port_info qs_por
 	{
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
-		.pio_mask	= 0x10, /* pio4 */
+		.pio_mask	= ATA_PIO4_ONLY,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &qs_ata_ops,
 	},
@@ -583,10 +584,10 @@ static int qs_set_dma_masks(struct pci_d
 	int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT);
 
 	if (have_64bit_bus &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (rc) {
-			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (rc) {
 				dev_printk(KERN_ERR, &pdev->dev,
 					   "64-bit DMA enable failed\n");
@@ -594,13 +595,13 @@ static int qs_set_dma_masks(struct pci_d
 			}
 		}
 	} else {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				"32-bit DMA enable failed\n");
 			return rc;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				"32-bit consistent DMA enable failed\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_sil24.c linux-libre-2.6.30-gnu1/drivers/ata/sata_sil24.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_sil24.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_sil24.c	2009-06-09 23:05:27.000000000 -0400
@@ -429,25 +429,25 @@ static const struct ata_port_info sil24_
 	{
 		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
 				  SIL24_FLAG_PCIX_IRQ_WOC,
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
-		.udma_mask	= ATA_UDMA5,		/* udma0-5 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil24_ops,
 	},
 	/* sil_3132 */
 	{
 		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
-		.udma_mask	= ATA_UDMA5,		/* udma0-5 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil24_ops,
 	},
 	/* sil_3131/sil_3531 */
 	{
 		.flags		= SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
-		.udma_mask	= ATA_UDMA5,		/* udma0-5 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil24_ops,
 	},
 };
@@ -1297,10 +1297,10 @@ static int sil24_init_one(struct pci_dev
 	host->iomap = iomap;
 
 	/* configure and activate the device */
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (rc) {
-			rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (rc) {
 				dev_printk(KERN_ERR, &pdev->dev,
 					   "64-bit DMA enable failed\n");
@@ -1308,13 +1308,13 @@ static int sil24_init_one(struct pci_dev
 			}
 		}
 	} else {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit DMA enable failed\n");
 			return rc;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_printk(KERN_ERR, &pdev->dev,
 				   "32-bit consistent DMA enable failed\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_sil.c linux-libre-2.6.30-gnu1/drivers/ata/sata_sil.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_sil.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_sil.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,8 +200,8 @@ static const struct ata_port_info sil_po
 	/* sil_3112 */
 	{
 		.flags		= SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil_ops,
 	},
@@ -209,24 +209,24 @@ static const struct ata_port_info sil_po
 	{
 		.flags		= SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
 				  SIL_FLAG_NO_SATA_IRQ,
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil_ops,
 	},
 	/* sil_3512 */
 	{
 		.flags		= SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil_ops,
 	},
 	/* sil_3114 */
 	{
 		.flags		= SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
-		.pio_mask	= 0x1f,			/* pio0-4 */
-		.mwdma_mask	= 0x07,			/* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
 		.port_ops	= &sil_ops,
 	},
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_sis.c linux-libre-2.6.30-gnu1/drivers/ata/sata_sis.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_sis.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_sis.c	2009-06-09 23:05:27.000000000 -0400
@@ -97,8 +97,8 @@ static struct ata_port_operations sis_op
 
 static const struct ata_port_info sis_port_info = {
 	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
-	.pio_mask	= 0x1f,
-	.mwdma_mask	= 0x7,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &sis_ops,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_svw.c linux-libre-2.6.30-gnu1/drivers/ata/sata_svw.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_svw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_svw.c	2009-06-09 23:05:27.000000000 -0400
@@ -361,8 +361,8 @@ static const struct ata_port_info k2_por
 	{
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &k2_sata_ops,
 	},
@@ -371,8 +371,8 @@ static const struct ata_port_info k2_por
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
 				  K2_FLAG_SATA_8_PORTS,
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &k2_sata_ops,
 	},
@@ -380,8 +380,8 @@ static const struct ata_port_info k2_por
 	{
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &k2_sata_ops,
 	},
@@ -389,8 +389,8 @@ static const struct ata_port_info k2_por
 	{
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO,
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &k2_sata_ops,
 	},
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_sx4.c linux-libre-2.6.30-gnu1/drivers/ata/sata_sx4.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_sx4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_sx4.c	2009-06-09 23:05:27.000000000 -0400
@@ -213,8 +213,9 @@ struct pdc_host_priv {
 
 
 static int pdc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void pdc_eng_timeout(struct ata_port *ap);
-static void pdc_20621_phy_reset(struct ata_port *ap);
+static void pdc_error_handler(struct ata_port *ap);
+static void pdc_freeze(struct ata_port *ap);
+static void pdc_thaw(struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
 static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
@@ -233,6 +234,10 @@ static void pdc20621_put_to_dimm(struct
 				 void *psource, u32 offset, u32 size);
 static void pdc20621_irq_clear(struct ata_port *ap);
 static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc);
+static int pdc_softreset(struct ata_link *link, unsigned int *class,
+			 unsigned long deadline);
+static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
+static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
 
 
 static struct scsi_host_template pdc_sata_sht = {
@@ -243,20 +248,24 @@ static struct scsi_host_template pdc_sat
 
 /* TODO: inherit from base port_ops after converting to new EH */
 static struct ata_port_operations pdc_20621_ops = {
-	.sff_tf_load		= pdc_tf_load_mmio,
-	.sff_tf_read		= ata_sff_tf_read,
-	.sff_check_status	= ata_sff_check_status,
-	.sff_exec_command	= pdc_exec_command_mmio,
-	.sff_dev_select		= ata_sff_dev_select,
-	.phy_reset		= pdc_20621_phy_reset,
+	.inherits		= &ata_sff_port_ops,
+
+	.check_atapi_dma	= pdc_check_atapi_dma,
 	.qc_prep		= pdc20621_qc_prep,
 	.qc_issue		= pdc20621_qc_issue,
-	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
-	.sff_data_xfer		= ata_sff_data_xfer,
-	.eng_timeout		= pdc_eng_timeout,
-	.sff_irq_clear		= pdc20621_irq_clear,
-	.sff_irq_on		= ata_sff_irq_on,
+
+	.freeze			= pdc_freeze,
+	.thaw			= pdc_thaw,
+	.softreset		= pdc_softreset,
+	.error_handler		= pdc_error_handler,
+	.lost_interrupt		= ATA_OP_NULL,
+	.post_internal_cmd	= pdc_post_internal_cmd,
+
 	.port_start		= pdc_port_start,
+
+	.sff_tf_load		= pdc_tf_load_mmio,
+	.sff_exec_command	= pdc_exec_command_mmio,
+	.sff_irq_clear		= pdc20621_irq_clear,
 };
 
 static const struct ata_port_info pdc_port_info[] = {
@@ -265,8 +274,8 @@ static const struct ata_port_info pdc_po
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
 				  ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
-		.pio_mask	= 0x1f, /* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &pdc_20621_ops,
 	},
@@ -310,14 +319,6 @@ static int pdc_port_start(struct ata_por
 	return 0;
 }
 
-static void pdc_20621_phy_reset(struct ata_port *ap)
-{
-	VPRINTK("ENTER\n");
-	ap->cbl = ATA_CBL_SATA;
-	ata_port_probe(ap);
-	ata_bus_reset(ap);
-}
-
 static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf,
 				   unsigned int portno,
 					   unsigned int total_len)
@@ -686,8 +687,11 @@ static void pdc20621_packet_start(struct
 static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc)
 {
 	switch (qc->tf.protocol) {
-	case ATA_PROT_DMA:
 	case ATA_PROT_NODATA:
+		if (qc->tf.flags & ATA_TFLAG_POLLING)
+			break;
+		/*FALLTHROUGH*/
+	case ATA_PROT_DMA:
 		pdc20621_packet_start(qc);
 		return 0;
 
@@ -786,12 +790,7 @@ static inline unsigned int pdc20621_host
 
 static void pdc20621_irq_clear(struct ata_port *ap)
 {
-	struct ata_host *host = ap->host;
-	void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
-
-	mmio += PDC_CHIP0_OFS;
-
-	readl(mmio + PDC_20621_SEQMASK);
+	ioread8(ap->ioaddr.status_addr);
 }
 
 static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance)
@@ -859,46 +858,119 @@ static irqreturn_t pdc20621_interrupt(in
 	return IRQ_RETVAL(handled);
 }
 
-static void pdc_eng_timeout(struct ata_port *ap)
+static void pdc_freeze(struct ata_port *ap)
 {
-	u8 drv_stat;
-	struct ata_host *host = ap->host;
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
+	void __iomem *mmio = ap->ioaddr.cmd_addr;
+	u32 tmp;
 
-	DPRINTK("ENTER\n");
+	/* FIXME: if all 4 ATA engines are stopped, also stop HDMA engine */
 
-	spin_lock_irqsave(&host->lock, flags);
+	tmp = readl(mmio + PDC_CTLSTAT);
+	tmp |= PDC_MASK_INT;
+	tmp &= ~PDC_DMA_ENABLE;
+	writel(tmp, mmio + PDC_CTLSTAT);
+	readl(mmio + PDC_CTLSTAT); /* flush */
+}
 
-	qc = ata_qc_from_tag(ap, ap->link.active_tag);
+static void pdc_thaw(struct ata_port *ap)
+{
+	void __iomem *mmio = ap->ioaddr.cmd_addr;
+	u32 tmp;
 
-	switch (qc->tf.protocol) {
-	case ATA_PROT_DMA:
-	case ATA_PROT_NODATA:
-		ata_port_printk(ap, KERN_ERR, "command timeout\n");
-		qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
-		break;
+	/* FIXME: start HDMA engine, if zero ATA engines running */
 
-	default:
-		drv_stat = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+	/* clear IRQ */
+	ioread8(ap->ioaddr.status_addr);
 
-		ata_port_printk(ap, KERN_ERR,
-				"unknown timeout, cmd 0x%x stat 0x%x\n",
-				qc->tf.command, drv_stat);
+	/* turn IRQ back on */
+	tmp = readl(mmio + PDC_CTLSTAT);
+	tmp &= ~PDC_MASK_INT;
+	writel(tmp, mmio + PDC_CTLSTAT);
+	readl(mmio + PDC_CTLSTAT); /* flush */
+}
 
-		qc->err_mask |= ac_err_mask(drv_stat);
-		break;
+static void pdc_reset_port(struct ata_port *ap)
+{
+	void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
+	unsigned int i;
+	u32 tmp;
+
+	/* FIXME: handle HDMA copy engine */
+
+	for (i = 11; i > 0; i--) {
+		tmp = readl(mmio);
+		if (tmp & PDC_RESET)
+			break;
+
+		udelay(100);
+
+		tmp |= PDC_RESET;
+		writel(tmp, mmio);
 	}
 
-	spin_unlock_irqrestore(&host->lock, flags);
-	ata_eh_qc_complete(qc);
-	DPRINTK("EXIT\n");
+	tmp &= ~PDC_RESET;
+	writel(tmp, mmio);
+	readl(mmio);	/* flush */
+}
+
+static int pdc_softreset(struct ata_link *link, unsigned int *class,
+			 unsigned long deadline)
+{
+	pdc_reset_port(link->ap);
+	return ata_sff_softreset(link, class, deadline);
+}
+
+static void pdc_error_handler(struct ata_port *ap)
+{
+	if (!(ap->pflags & ATA_PFLAG_FROZEN))
+		pdc_reset_port(ap);
+
+	ata_std_error_handler(ap);
+}
+
+static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+
+	/* make DMA engine forget about the failed command */
+	if (qc->flags & ATA_QCFLAG_FAILED)
+		pdc_reset_port(ap);
+}
+
+static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	u8 *scsicmd = qc->scsicmd->cmnd;
+	int pio = 1; /* atapi dma off by default */
+
+	/* Whitelist commands that may use DMA. */
+	switch (scsicmd[0]) {
+	case WRITE_12:
+	case WRITE_10:
+	case WRITE_6:
+	case READ_12:
+	case READ_10:
+	case READ_6:
+	case 0xad: /* READ_DVD_STRUCTURE */
+	case 0xbe: /* READ_CD */
+		pio = 0;
+	}
+	/* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */
+	if (scsicmd[0] == WRITE_10) {
+		unsigned int lba =
+			(scsicmd[2] << 24) |
+			(scsicmd[3] << 16) |
+			(scsicmd[4] << 8) |
+			scsicmd[5];
+		if (lba >= 0xFFFF4FA2)
+			pio = 1;
+	}
+	return pio;
 }
 
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
 	WARN_ON(tf->protocol == ATA_PROT_DMA ||
-		tf->protocol == ATA_PROT_NODATA);
+		tf->protocol == ATAPI_PROT_DMA);
 	ata_sff_tf_load(ap, tf);
 }
 
@@ -906,7 +978,7 @@ static void pdc_tf_load_mmio(struct ata_
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
 	WARN_ON(tf->protocol == ATA_PROT_DMA ||
-		tf->protocol == ATA_PROT_NODATA);
+		tf->protocol == ATAPI_PROT_DMA);
 	ata_sff_exec_command(ap, tf);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_uli.c linux-libre-2.6.30-gnu1/drivers/ata/sata_uli.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_uli.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_uli.c	2009-06-09 23:05:27.000000000 -0400
@@ -89,7 +89,7 @@ static struct ata_port_operations uli_op
 static const struct ata_port_info uli_port_info = {
 	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 			  ATA_FLAG_IGN_SIMPLEX,
-	.pio_mask       = 0x1f,		/* pio0-4 */
+	.pio_mask       = ATA_PIO4,
 	.udma_mask      = ATA_UDMA6,
 	.port_ops       = &uli_ops,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_via.c linux-libre-2.6.30-gnu1/drivers/ata/sata_via.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_via.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_via.c	2009-06-09 23:05:27.000000000 -0400
@@ -146,24 +146,24 @@ static struct ata_port_operations vt8251
 
 static const struct ata_port_info vt6420_port_info = {
 	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
-	.pio_mask	= 0x1f,
-	.mwdma_mask	= 0x07,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &vt6420_sata_ops,
 };
 
 static struct ata_port_info vt6421_sport_info = {
 	.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
-	.pio_mask	= 0x1f,
-	.mwdma_mask	= 0x07,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &vt6421_sata_ops,
 };
 
 static struct ata_port_info vt6421_pport_info = {
 	.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
-	.pio_mask	= 0x1f,
-	.mwdma_mask	= 0,
+	.pio_mask	= ATA_PIO4,
+	/* No MWDMA */
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &vt6421_pata_ops,
 };
@@ -171,8 +171,8 @@ static struct ata_port_info vt6421_pport
 static struct ata_port_info vt8251_port_info = {
 	.flags		= ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
 			  ATA_FLAG_NO_LEGACY,
-	.pio_mask	= 0x1f,
-	.mwdma_mask	= 0x07,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA6,
 	.port_ops	= &vt8251_ops,
 };
@@ -566,7 +566,7 @@ static int svia_init_one(struct pci_dev
 	static int printed_version;
 	unsigned int i;
 	int rc;
-	struct ata_host *host;
+	struct ata_host *host = NULL;
 	int board_id = (int) ent->driver_data;
 	const unsigned *bar_sizes;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ata/sata_vsc.c linux-libre-2.6.30-gnu1/drivers/ata/sata_vsc.c
--- linux-libre-2.6.29-gnu1/drivers/ata/sata_vsc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ata/sata_vsc.c	2009-06-09 23:05:27.000000000 -0400
@@ -308,6 +308,9 @@ static struct scsi_host_template vsc_sat
 
 static struct ata_port_operations vsc_sata_ops = {
 	.inherits		= &ata_bmdma_port_ops,
+	/* The IRQ handling is not quite standard SFF behaviour so we
+	   cannot use the default lost interrupt handler */
+	.lost_interrupt		= ATA_OP_NULL,
 	.sff_tf_load		= vsc_sata_tf_load,
 	.sff_tf_read		= vsc_sata_tf_read,
 	.freeze			= vsc_freeze,
@@ -345,8 +348,8 @@ static int __devinit vsc_sata_init_one(s
 	static const struct ata_port_info pi = {
 		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO,
-		.pio_mask	= 0x1f,
-		.mwdma_mask	= 0x07,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &vsc_sata_ops,
 	};
@@ -396,10 +399,10 @@ static int __devinit vsc_sata_init_one(s
 	/*
 	 * Use 32 bit DMA mask, because 64 bit address support is poor.
 	 */
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc)
 		return rc;
-	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc)
 		return rc;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/firestream.c linux-libre-2.6.30-gnu1/drivers/atm/firestream.c
--- linux-libre-2.6.29-gnu1/drivers/atm/firestream.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/atm/firestream.c	2009-06-09 23:05:27.000000000 -0400
@@ -1690,17 +1690,17 @@ static int __devinit fs_init (struct fs_
 		  | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
 		  | (1 * SARMODE0_INTMODE_READCLEAR)
 		  | (1 * SARMODE0_CWRE)
-		  | IS_FS50(dev)?SARMODE0_PRPWT_FS50_5: 
-		                 SARMODE0_PRPWT_FS155_3
+		  | (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
+			  SARMODE0_PRPWT_FS155_3)
 		  | (1 * SARMODE0_CALSUP_1)
-		  | IS_FS50 (dev)?(0
+		  | (IS_FS50(dev) ? (0
 				   | SARMODE0_RXVCS_32
 				   | SARMODE0_ABRVCS_32 
 				   | SARMODE0_TXVCS_32):
 		                  (0
 				   | SARMODE0_RXVCS_1k
 				   | SARMODE0_ABRVCS_1k 
-				   | SARMODE0_TXVCS_1k));
+				   | SARMODE0_TXVCS_1k)));
 
 	/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
 	   1ms. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/he.c linux-libre-2.6.30-gnu1/drivers/atm/he.c
--- linux-libre-2.6.29-gnu1/drivers/atm/he.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/atm/he.c	2009-06-09 23:05:27.000000000 -0400
@@ -358,7 +358,7 @@ he_init_one(struct pci_dev *pci_dev, con
 
 	if (pci_enable_device(pci_dev))
 		return -EIO;
-	if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK) != 0) {
+	if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)) != 0) {
 		printk(KERN_WARNING "he: no suitable dma available\n");
 		err = -EIO;
 		goto init_one_failure;
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/iphase.c linux-libre-2.6.30-gnu1/drivers/atm/iphase.c
--- linux-libre-2.6.29-gnu1/drivers/atm/iphase.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/atm/iphase.c	2009-06-09 23:05:27.000000000 -0400
@@ -977,9 +977,7 @@ static void xdump( u_char*  cp, int  len
             else
                 pBuf += sprintf( pBuf, "." );
                 }
-        sprintf( pBuf, "\n" );
-        // SPrint(prntBuf);
-        printk(prntBuf);
+        printk("%s\n", prntBuf);
         count += col;
         pBuf = prntBuf;
     }
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/lanai.c linux-libre-2.6.30-gnu1/drivers/atm/lanai.c
--- linux-libre-2.6.29-gnu1/drivers/atm/lanai.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/atm/lanai.c	2009-06-09 23:05:27.000000000 -0400
@@ -1957,12 +1957,12 @@ static int __devinit lanai_pci_start(str
 		return -ENXIO;
 	}
 	pci_set_master(pci);
-	if (pci_set_dma_mask(pci, DMA_32BIT_MASK) != 0) {
+	if (pci_set_dma_mask(pci, DMA_BIT_MASK(32)) != 0) {
 		printk(KERN_WARNING DEV_LABEL
 		    "(itf %d): No suitable DMA available.\n", lanai->number);
 		return -EBUSY;
 	}
-	if (pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) != 0) {
+	if (pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)) != 0) {
 		printk(KERN_WARNING DEV_LABEL
 		    "(itf %d): No suitable DMA available.\n", lanai->number);
 		return -EBUSY;
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/solos-attrlist.c linux-libre-2.6.30-gnu1/drivers/atm/solos-attrlist.c
--- linux-libre-2.6.29-gnu1/drivers/atm/solos-attrlist.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/atm/solos-attrlist.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,70 @@
+SOLOS_ATTR_RO(DriverVersion)
+SOLOS_ATTR_RO(APIVersion)
+SOLOS_ATTR_RO(FirmwareVersion)
+// SOLOS_ATTR_RO(DspVersion)
+// SOLOS_ATTR_RO(CommonHandshake)
+SOLOS_ATTR_RO(Connected)
+SOLOS_ATTR_RO(OperationalMode)
+SOLOS_ATTR_RO(State)
+SOLOS_ATTR_RO(Watchdog)
+SOLOS_ATTR_RO(OperationProgress)
+SOLOS_ATTR_RO(LastFailed)
+SOLOS_ATTR_RO(TxBitRate)
+SOLOS_ATTR_RO(RxBitRate)
+// SOLOS_ATTR_RO(DeltACTATPds)
+// SOLOS_ATTR_RO(DeltACTATPus)
+SOLOS_ATTR_RO(TxATTNDR)
+SOLOS_ATTR_RO(RxATTNDR)
+SOLOS_ATTR_RO(AnnexType)
+SOLOS_ATTR_RO(GeneralFailure)
+SOLOS_ATTR_RO(InterleaveDpDn)
+SOLOS_ATTR_RO(InterleaveDpUp)
+SOLOS_ATTR_RO(RSCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSCorrectedErrorsUp)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
+SOLOS_ATTR_RO(InterleaveRDn)
+SOLOS_ATTR_RO(InterleaveRUp)
+SOLOS_ATTR_RO(ShowtimeStart)
+SOLOS_ATTR_RO(ATURVendor)
+SOLOS_ATTR_RO(ATUCCountry)
+SOLOS_ATTR_RO(ATURANSIRev)
+SOLOS_ATTR_RO(ATURANSISTD)
+SOLOS_ATTR_RO(ATUCANSIRev)
+SOLOS_ATTR_RO(ATUCANSIId)
+SOLOS_ATTR_RO(ATUCANSISTD)
+SOLOS_ATTR_RO(DataBoost)
+SOLOS_ATTR_RO(LocalITUCountryCode)
+SOLOS_ATTR_RO(LocalSEF)
+SOLOS_ATTR_RO(LocalEndLOS)
+SOLOS_ATTR_RO(LocalSNRMargin)
+SOLOS_ATTR_RO(LocalLineAttn)
+SOLOS_ATTR_RO(RawAttn)
+SOLOS_ATTR_RO(LocalTxPower)
+SOLOS_ATTR_RO(RemoteTxPower)
+SOLOS_ATTR_RO(RemoteSEF)
+SOLOS_ATTR_RO(RemoteLOS)
+SOLOS_ATTR_RO(RemoteLineAttn)
+SOLOS_ATTR_RO(RemoteSNRMargin)
+SOLOS_ATTR_RO(LineUpCount)
+SOLOS_ATTR_RO(SRACnt)
+SOLOS_ATTR_RO(SRACntUp)
+SOLOS_ATTR_RO(ProfileStatus)
+SOLOS_ATTR_RW(Action)
+SOLOS_ATTR_RW(ActivateLine)
+SOLOS_ATTR_RO(LineStatus)
+SOLOS_ATTR_RW(HostControl)
+SOLOS_ATTR_RW(AutoStart)
+SOLOS_ATTR_RW(Failsafe)
+SOLOS_ATTR_RW(ShowtimeLed)
+SOLOS_ATTR_RW(Retrain)
+SOLOS_ATTR_RW(Defaults)
+SOLOS_ATTR_RW(LineMode)
+SOLOS_ATTR_RW(Profile)
+SOLOS_ATTR_RW(DetectNoise)
+SOLOS_ATTR_RO(SupportedAnnexes)
+SOLOS_ATTR_RO(Status)
+SOLOS_ATTR_RO(TotalStart)
+SOLOS_ATTR_RO(RecentShowtimeStart)
+SOLOS_ATTR_RO(TotalRxBlocks)
+SOLOS_ATTR_RO(TotalTxBlocks)
diff -druNp linux-libre-2.6.29-gnu1/drivers/atm/solos-pci.c linux-libre-2.6.30-gnu1/drivers/atm/solos-pci.c
--- linux-libre-2.6.29-gnu1/drivers/atm/solos-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/atm/solos-pci.c	2013-05-03 16:43:49.000000000 -0400
@@ -9,6 +9,7 @@
  *
  * Authors: Nathan Williams <nathan@traverse.com.au>
  *          David Woodhouse <dwmw2@infradead.org>
+ *          Treker Chen <treker@xrio.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,8 +37,11 @@
 #include <linux/sysfs.h>
 #include <linux/device.h>
 #include <linux/kobject.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/swab.h>
 
-#define VERSION "0.04"
+#define VERSION "0.07"
 #define PTAG "solos-pci"
 
 #define CONFIG_RAM_SIZE	128
@@ -45,16 +49,31 @@
 #define IRQ_EN_ADDR	0x78
 #define FPGA_VER	0x74
 #define IRQ_CLEAR	0x70
-#define BUG_FLAG	0x6C
+#define WRITE_FLASH	0x6C
+#define PORTS		0x68
+#define FLASH_BLOCK	0x64
+#define FLASH_BUSY	0x60
+#define FPGA_MODE	0x5C
+#define FLASH_MODE	0x58
+#define TX_DMA_ADDR(port)	(0x40 + (4 * (port)))
+#define RX_DMA_ADDR(port)	(0x30 + (4 * (port)))
 
 #define DATA_RAM_SIZE	32768
 #define BUF_SIZE	4096
+#define FPGA_PAGE	528 /* FPGA flash page size*/
+#define SOLOS_PAGE	512 /* Solos flash page size*/
+#define FPGA_BLOCK	(FPGA_PAGE * 8) /* FPGA flash block size*/
+#define SOLOS_BLOCK	(SOLOS_PAGE * 8) /* Solos flash block size*/
 
 #define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2)
 #define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE)
 
-static int debug = 0;
+#define RX_DMA_SIZE	2048
+
+static int reset = 0;
 static int atmdebug = 0;
+static int firmware_upgrade = 0;
+static int fpga_upgrade = 0;
 
 struct pkt_hdr {
 	__le16 size;
@@ -63,23 +82,48 @@ struct pkt_hdr {
 	__le16 type;
 };
 
+struct solos_skb_cb {
+	struct atm_vcc *vcc;
+	uint32_t dma_addr;
+};
+
+
+#define SKB_CB(skb)		((struct solos_skb_cb *)skb->cb)
+
 #define PKT_DATA	0
 #define PKT_COMMAND	1
 #define PKT_POPEN	3
 #define PKT_PCLOSE	4
+#define PKT_STATUS	5
 
 struct solos_card {
 	void __iomem *config_regs;
 	void __iomem *buffers;
 	int nr_ports;
+	int tx_mask;
 	struct pci_dev *dev;
 	struct atm_dev *atmdev[4];
 	struct tasklet_struct tlet;
 	spinlock_t tx_lock;
 	spinlock_t tx_queue_lock;
 	spinlock_t cli_queue_lock;
+	spinlock_t param_queue_lock;
+	struct list_head param_queue;
 	struct sk_buff_head tx_queue[4];
 	struct sk_buff_head cli_queue[4];
+	struct sk_buff *tx_skb[4];
+	struct sk_buff *rx_skb[4];
+	wait_queue_head_t param_wq;
+	wait_queue_head_t fw_wq;
+	int using_dma;
+};
+
+
+struct solos_param {
+	struct list_head list;
+	pid_t pid;
+	int port;
+	struct sk_buff *response;
 };
 
 #define SOLOS_CHAN(atmdev) ((int)(unsigned long)(atmdev)->phy_data)
@@ -88,19 +132,22 @@ MODULE_AUTHOR("Traverse Technologies <su
 MODULE_DESCRIPTION("Solos PCI driver");
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(debug, "Enable Loopback");
+MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
 MODULE_PARM_DESC(atmdebug, "Print ATM data");
-module_param(debug, int, 0444);
-module_param(atmdebug, int, 0444);
-
-static int opens;
+MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
+MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
+module_param(reset, int, 0444);
+module_param(atmdebug, int, 0644);
+module_param(firmware_upgrade, int, 0444);
+module_param(fpga_upgrade, int, 0444);
 
 static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
 		       struct atm_vcc *vcc);
-static int fpga_tx(struct solos_card *);
+static uint32_t fpga_tx(struct solos_card *);
 static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
+static void release_vccs(struct atm_dev *dev);
 static int atm_init(struct solos_card *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -115,6 +162,264 @@ static inline void solos_pop(struct atm_
                 dev_kfree_skb_any(skb);
 }
 
+static ssize_t solos_param_show(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+	struct solos_card *card = atmdev->dev_data;
+	struct solos_param prm;
+	struct sk_buff *skb;
+	struct pkt_hdr *header;
+	int buflen;
+
+	buflen = strlen(attr->attr.name) + 10;
+
+	skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+	if (!skb) {
+		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_show()\n");
+		return -ENOMEM;
+	}
+
+	header = (void *)skb_put(skb, sizeof(*header));
+
+	buflen = snprintf((void *)&header[1], buflen - 1,
+			  "L%05d\n%s\n", current->pid, attr->attr.name);
+	skb_put(skb, buflen);
+
+	header->size = cpu_to_le16(buflen);
+	header->vpi = cpu_to_le16(0);
+	header->vci = cpu_to_le16(0);
+	header->type = cpu_to_le16(PKT_COMMAND);
+
+	prm.pid = current->pid;
+	prm.response = NULL;
+	prm.port = SOLOS_CHAN(atmdev);
+
+	spin_lock_irq(&card->param_queue_lock);
+	list_add(&prm.list, &card->param_queue);
+	spin_unlock_irq(&card->param_queue_lock);
+
+	fpga_queue(card, prm.port, skb, NULL);
+
+	wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+	spin_lock_irq(&card->param_queue_lock);
+	list_del(&prm.list);
+	spin_unlock_irq(&card->param_queue_lock);
+
+	if (!prm.response)
+		return -EIO;
+
+	buflen = prm.response->len;
+	memcpy(buf, prm.response->data, buflen);
+	kfree_skb(prm.response);
+
+	return buflen;
+}
+
+static ssize_t solos_param_store(struct device *dev, struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+	struct solos_card *card = atmdev->dev_data;
+	struct solos_param prm;
+	struct sk_buff *skb;
+	struct pkt_hdr *header;
+	int buflen;
+	ssize_t ret;
+
+	buflen = strlen(attr->attr.name) + 11 + count;
+
+	skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+	if (!skb) {
+		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_store()\n");
+		return -ENOMEM;
+	}
+
+	header = (void *)skb_put(skb, sizeof(*header));
+
+	buflen = snprintf((void *)&header[1], buflen - 1,
+			  "L%05d\n%s\n%s\n", current->pid, attr->attr.name, buf);
+
+	skb_put(skb, buflen);
+	header->size = cpu_to_le16(buflen);
+	header->vpi = cpu_to_le16(0);
+	header->vci = cpu_to_le16(0);
+	header->type = cpu_to_le16(PKT_COMMAND);
+
+	prm.pid = current->pid;
+	prm.response = NULL;
+	prm.port = SOLOS_CHAN(atmdev);
+
+	spin_lock_irq(&card->param_queue_lock);
+	list_add(&prm.list, &card->param_queue);
+	spin_unlock_irq(&card->param_queue_lock);
+
+	fpga_queue(card, prm.port, skb, NULL);
+
+	wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+	spin_lock_irq(&card->param_queue_lock);
+	list_del(&prm.list);
+	spin_unlock_irq(&card->param_queue_lock);
+
+	skb = prm.response;
+
+	if (!skb)
+		return -EIO;
+
+	buflen = skb->len;
+
+	/* Sometimes it has a newline, sometimes it doesn't. */
+	if (skb->data[buflen - 1] == '\n')
+		buflen--;
+
+	if (buflen == 2 && !strncmp(skb->data, "OK", 2))
+		ret = count;
+	else if (buflen == 5 && !strncmp(skb->data, "ERROR", 5))
+		ret = -EIO;
+	else {
+		/* We know we have enough space allocated for this; we allocated 
+		   it ourselves */
+		skb->data[buflen] = 0;
+	
+		dev_warn(&card->dev->dev, "Unexpected parameter response: '%s'\n",
+			 skb->data);
+		ret = -EIO;
+	}
+	kfree_skb(skb);
+
+	return ret;
+}
+
+static char *next_string(struct sk_buff *skb)
+{
+	int i = 0;
+	char *this = skb->data;
+	
+	for (i = 0; i < skb->len; i++) {
+		if (this[i] == '\n') {
+			this[i] = 0;
+			skb_pull(skb, i + 1);
+			return this;
+		}
+		if (!isprint(this[i]))
+			return NULL;
+	}
+	return NULL;
+}
+
+/*
+ * Status packet has fields separated by \n, starting with a version number
+ * for the information therein. Fields are....
+ *
+ *     packet version
+ *     RxBitRate	(version >= 1)
+ *     TxBitRate	(version >= 1)
+ *     State		(version >= 1)
+ *     LocalSNRMargin	(version >= 1)
+ *     LocalLineAttn	(version >= 1)
+ */       
+static int process_status(struct solos_card *card, int port, struct sk_buff *skb)
+{
+	char *str, *end, *state_str, *snr, *attn;
+	int ver, rate_up, rate_down;
+
+	if (!card->atmdev[port])
+		return -ENODEV;
+
+	str = next_string(skb);
+	if (!str)
+		return -EIO;
+
+	ver = simple_strtol(str, NULL, 10);
+	if (ver < 1) {
+		dev_warn(&card->dev->dev, "Unexpected status interrupt version %d\n",
+			 ver);
+		return -EIO;
+	}
+
+	str = next_string(skb);
+	if (!str)
+		return -EIO;
+	if (!strcmp(str, "ERROR")) {
+		dev_dbg(&card->dev->dev, "Status packet indicated Solos error on port %d (starting up?)\n",
+			 port);
+		return 0;
+	}
+
+	rate_down = simple_strtol(str, &end, 10);
+	if (*end)
+		return -EIO;
+
+	str = next_string(skb);
+	if (!str)
+		return -EIO;
+	rate_up = simple_strtol(str, &end, 10);
+	if (*end)
+		return -EIO;
+
+	state_str = next_string(skb);
+	if (!state_str)
+		return -EIO;
+
+	/* Anything but 'Showtime' is down */
+	if (strcmp(state_str, "Showtime")) {
+		card->atmdev[port]->signal = ATM_PHY_SIG_LOST;
+		release_vccs(card->atmdev[port]);
+		dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
+		return 0;
+	}
+
+	snr = next_string(skb);
+	if (!str)
+		return -EIO;
+	attn = next_string(skb);
+	if (!attn)
+		return -EIO;
+
+	dev_info(&card->dev->dev, "Port %d: %s @%d/%d kb/s%s%s%s%s\n",
+		 port, state_str, rate_down/1000, rate_up/1000,
+		 snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn);
+	
+	card->atmdev[port]->link_rate = rate_down / 424;
+	card->atmdev[port]->signal = ATM_PHY_SIG_FOUND;
+
+	return 0;
+}
+
+static int process_command(struct solos_card *card, int port, struct sk_buff *skb)
+{
+	struct solos_param *prm;
+	unsigned long flags;
+	int cmdpid;
+	int found = 0;
+
+	if (skb->len < 7)
+		return 0;
+
+	if (skb->data[0] != 'L'    || !isdigit(skb->data[1]) ||
+	    !isdigit(skb->data[2]) || !isdigit(skb->data[3]) ||
+	    !isdigit(skb->data[4]) || !isdigit(skb->data[5]) ||
+	    skb->data[6] != '\n')
+		return 0;
+
+	cmdpid = simple_strtol(&skb->data[1], NULL, 10);
+
+	spin_lock_irqsave(&card->param_queue_lock, flags);
+	list_for_each_entry(prm, &card->param_queue, list) {
+		if (prm->port == port && prm->pid == cmdpid) {
+			prm->response = skb;
+			skb_pull(skb, 7);
+			wake_up(&card->param_wq);
+			found = 1;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&card->param_queue_lock, flags);
+	return found;
+}
+
 static ssize_t console_show(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
@@ -140,8 +445,6 @@ static int send_command(struct solos_car
 	struct sk_buff *skb;
 	struct pkt_hdr *header;
 
-//	dev_dbg(&card->dev->dev, "size: %d\n", size);
-
 	if (size > (BUF_SIZE - sizeof(*header))) {
 		dev_dbg(&card->dev->dev, "Command is too big.  Dropping request\n");
 		return 0;
@@ -180,82 +483,181 @@ static ssize_t console_store(struct devi
 
 static DEVICE_ATTR(console, 0644, console_show, console_store);
 
+
+#define SOLOS_ATTR_RO(x) static DEVICE_ATTR(x, 0444, solos_param_show, NULL);
+#define SOLOS_ATTR_RW(x) static DEVICE_ATTR(x, 0644, solos_param_show, solos_param_store);
+
+#include "solos-attrlist.c"
+
+#undef SOLOS_ATTR_RO
+#undef SOLOS_ATTR_RW
+
+#define SOLOS_ATTR_RO(x) &dev_attr_##x.attr,
+#define SOLOS_ATTR_RW(x) &dev_attr_##x.attr,
+
+static struct attribute *solos_attrs[] = {
+#include "solos-attrlist.c"
+	NULL
+};
+
+static struct attribute_group solos_attr_group = {
+	.attrs = solos_attrs,
+	.name = "parameters",
+};
+
+static int flash_upgrade(struct solos_card *card, int chip)
+{
+	const struct firmware *fw;
+	const char *fw_name;
+	uint32_t data32 = 0;
+	int blocksize = 0;
+	int numblocks = 0;
+	int offset;
+
+	if (chip == 0) {
+		fw_name = "/*(DEBLOBBED)*/";
+		blocksize = FPGA_BLOCK;
+	} else {
+		fw_name = "/*(DEBLOBBED)*/";
+		blocksize = SOLOS_BLOCK;
+	}
+
+	if (reject_firmware(&fw, fw_name, &card->dev->dev))
+		return -ENOENT;
+
+	dev_info(&card->dev->dev, "Flash upgrade starting\n");
+
+	numblocks = fw->size / blocksize;
+	dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
+	dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
+	
+	dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
+	iowrite32(1, card->config_regs + FPGA_MODE);
+	data32 = ioread32(card->config_regs + FPGA_MODE); 
+
+	/* Set mode to Chip Erase */
+	dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n",
+		 chip?"Solos":"FPGA");
+	iowrite32((chip * 2), card->config_regs + FLASH_MODE);
+
+
+	iowrite32(1, card->config_regs + WRITE_FLASH);
+	wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+
+	for (offset = 0; offset < fw->size; offset += blocksize) {
+		int i;
+
+		/* Clear write flag */
+		iowrite32(0, card->config_regs + WRITE_FLASH);
+
+		/* Set mode to Block Write */
+		/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
+		iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
+
+		/* Copy block to buffer, swapping each 16 bits */
+		for(i = 0; i < blocksize; i += 4) {
+			uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
+			iowrite32(word, RX_BUF(card, 3) + i);
+		}
+
+		/* Specify block number and then trigger flash write */
+		iowrite32(offset / blocksize, card->config_regs + FLASH_BLOCK);
+		iowrite32(1, card->config_regs + WRITE_FLASH);
+		wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+	}
+
+	release_firmware(fw);
+	iowrite32(0, card->config_regs + WRITE_FLASH);
+	iowrite32(0, card->config_regs + FPGA_MODE);
+	iowrite32(0, card->config_regs + FLASH_MODE);
+	dev_info(&card->dev->dev, "Returning FPGA to Data mode\n");
+	return 0;
+}
+
 static irqreturn_t solos_irq(int irq, void *dev_id)
 {
 	struct solos_card *card = dev_id;
 	int handled = 1;
 
-	//ACK IRQ
 	iowrite32(0, card->config_regs + IRQ_CLEAR);
-	//Disable IRQs from FPGA
-	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
 
-	/* If we only do it when the device is open, we lose console
-	   messages */
-	if (1 || opens)
+	/* If we're up and running, just kick the tasklet to process TX/RX */
+	if (card->atmdev[0])
 		tasklet_schedule(&card->tlet);
+	else
+		wake_up(&card->fw_wq);
 
-	//Enable IRQs from FPGA
-	iowrite32(1, card->config_regs + IRQ_EN_ADDR);
 	return IRQ_RETVAL(handled);
 }
 
 void solos_bh(unsigned long card_arg)
 {
 	struct solos_card *card = (void *)card_arg;
-	int port;
 	uint32_t card_flags;
-	uint32_t tx_mask;
 	uint32_t rx_done = 0;
+	int port;
 
-	card_flags = ioread32(card->config_regs + FLAGS_ADDR);
-
-	/* The TX bits are set if the channel is busy; clear if not. We want to
-	   invoke fpga_tx() unless _all_ the bits for active channels are set */
-	tx_mask = (1 << card->nr_ports) - 1;
-	if ((card_flags & tx_mask) != tx_mask)
-		fpga_tx(card);
+	/*
+	 * Since fpga_tx() is going to need to read the flags under its lock,
+	 * it can return them to us so that we don't have to hit PCI MMIO
+	 * again for the same information
+	 */
+	card_flags = fpga_tx(card);
 
 	for (port = 0; port < card->nr_ports; port++) {
 		if (card_flags & (0x10 << port)) {
-			struct pkt_hdr header;
+			struct pkt_hdr _hdr, *header;
 			struct sk_buff *skb;
 			struct atm_vcc *vcc;
 			int size;
 
-			rx_done |= 0x10 << port;
+			if (card->using_dma) {
+				skb = card->rx_skb[port];
+				card->rx_skb[port] = NULL;
 
-			memcpy_fromio(&header, RX_BUF(card, port), sizeof(header));
+				pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+						 RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
 
-			size = le16_to_cpu(header.size);
+				header = (void *)skb->data;
+				size = le16_to_cpu(header->size);
+				skb_put(skb, size + sizeof(*header));
+				skb_pull(skb, sizeof(*header));
+			} else {
+				header = &_hdr;
 
-			skb = alloc_skb(size, GFP_ATOMIC);
-			if (!skb) {
-				if (net_ratelimit())
-					dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
-				continue;
-			}
+				rx_done |= 0x10 << port;
 
-			memcpy_fromio(skb_put(skb, size),
-				      RX_BUF(card, port) + sizeof(header),
-				      size);
+				memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
+
+				size = le16_to_cpu(header->size);
+
+				skb = alloc_skb(size + 1, GFP_ATOMIC);
+				if (!skb) {
+					if (net_ratelimit())
+						dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
+					continue;
+				}
 
+				memcpy_fromio(skb_put(skb, size),
+					      RX_BUF(card, port) + sizeof(*header),
+					      size);
+			}
 			if (atmdebug) {
 				dev_info(&card->dev->dev, "Received: device %d\n", port);
 				dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
-					 size, le16_to_cpu(header.vpi),
-					 le16_to_cpu(header.vci));
+					 size, le16_to_cpu(header->vpi),
+					 le16_to_cpu(header->vci));
 				print_buffer(skb);
 			}
 
-			switch (le16_to_cpu(header.type)) {
+			switch (le16_to_cpu(header->type)) {
 			case PKT_DATA:
-				vcc = find_vcc(card->atmdev[port], le16_to_cpu(header.vpi),
-					       le16_to_cpu(header.vci));
+				vcc = find_vcc(card->atmdev[port], le16_to_cpu(header->vpi),
+					       le16_to_cpu(header->vci));
 				if (!vcc) {
 					if (net_ratelimit())
 						dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
-							 le16_to_cpu(header.vci), le16_to_cpu(header.vpi),
+							 le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
 							 port);
 					continue;
 				}
@@ -264,19 +666,50 @@ void solos_bh(unsigned long card_arg)
 				atomic_inc(&vcc->stats->rx);
 				break;
 
+			case PKT_STATUS:
+				if (process_status(card, port, skb) &&
+				    net_ratelimit()) {
+					dev_warn(&card->dev->dev, "Bad status packet of %d bytes on port %d:\n", skb->len, port);
+					print_buffer(skb);
+				}
+				dev_kfree_skb_any(skb);
+				break;
+
 			case PKT_COMMAND:
 			default: /* FIXME: Not really, surely? */
+				if (process_command(card, port, skb))
+					break;
 				spin_lock(&card->cli_queue_lock);
 				if (skb_queue_len(&card->cli_queue[port]) > 10) {
 					if (net_ratelimit())
 						dev_warn(&card->dev->dev, "Dropping console response on port %d\n",
 							 port);
+					dev_kfree_skb_any(skb);
 				} else
 					skb_queue_tail(&card->cli_queue[port], skb);
 				spin_unlock(&card->cli_queue_lock);
 				break;
 			}
 		}
+		/* Allocate RX skbs for any ports which need them */
+		if (card->using_dma && card->atmdev[port] &&
+		    !card->rx_skb[port]) {
+			struct sk_buff *skb = alloc_skb(RX_DMA_SIZE, GFP_ATOMIC);
+			if (skb) {
+				SKB_CB(skb)->dma_addr =
+					pci_map_single(card->dev, skb->data,
+						       RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+				iowrite32(SKB_CB(skb)->dma_addr,
+					  card->config_regs + RX_DMA_ADDR(port));
+				card->rx_skb[port] = skb;
+			} else {
+				if (net_ratelimit())
+					dev_warn(&card->dev->dev, "Failed to allocate RX skb");
+
+				/* We'll have to try again later */
+				tasklet_schedule(&card->tlet);
+			}
+		}
 	}
 	if (rx_done)
 		iowrite32(rx_done, card->config_regs + FLAGS_ADDR);
@@ -326,7 +759,7 @@ static int list_vccs(int vci)
 			       vcc->vci);
 		}
 	} else {
-		for(i=0; i<32; i++){
+		for(i = 0; i < VCC_HTABLE_SIZE; i++){
 			head = &vcc_hash[i];
 			sk_for_each(s, node, head) {
 				num_found ++;
@@ -342,6 +775,28 @@ static int list_vccs(int vci)
 	return num_found;
 }
 
+static void release_vccs(struct atm_dev *dev)
+{
+        int i;
+
+        write_lock_irq(&vcc_sklist_lock);
+        for (i = 0; i < VCC_HTABLE_SIZE; i++) {
+                struct hlist_head *head = &vcc_hash[i];
+                struct hlist_node *node, *tmp;
+                struct sock *s;
+                struct atm_vcc *vcc;
+
+                sk_for_each_safe(s, node, tmp, head) {
+                        vcc = atm_sk(s);
+                        if (vcc->dev == dev) {
+                                vcc_release_async(vcc, -EPIPE);
+                                sk_del_node_init(s);
+                        }
+                }
+        }
+        write_unlock_irq(&vcc_sklist_lock);
+}
+
 
 static int popen(struct atm_vcc *vcc)
 {
@@ -349,6 +804,12 @@ static int popen(struct atm_vcc *vcc)
 	struct sk_buff *skb;
 	struct pkt_hdr *header;
 
+	if (vcc->qos.aal != ATM_AAL5) {
+		dev_warn(&card->dev->dev, "Unsupported ATM type %d\n",
+			 vcc->qos.aal);
+		return -EINVAL;
+	}
+
 	skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
 	if (!skb && net_ratelimit()) {
 		dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
@@ -356,22 +817,17 @@ static int popen(struct atm_vcc *vcc)
 	}
 	header = (void *)skb_put(skb, sizeof(*header));
 
-	header->size = cpu_to_le16(sizeof(*header));
+	header->size = cpu_to_le16(0);
 	header->vpi = cpu_to_le16(vcc->vpi);
 	header->vci = cpu_to_le16(vcc->vci);
 	header->type = cpu_to_le16(PKT_POPEN);
 
 	fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
 
-//	dev_dbg(&card->dev->dev, "Open for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
-	set_bit(ATM_VF_ADDR, &vcc->flags); // accept the vpi / vci
+	set_bit(ATM_VF_ADDR, &vcc->flags);
 	set_bit(ATM_VF_READY, &vcc->flags);
 	list_vccs(0);
 
-	if (!opens)
-		iowrite32(1, card->config_regs + IRQ_EN_ADDR);
-
-	opens++; //count open PVCs
 
 	return 0;
 }
@@ -389,17 +845,13 @@ static void pclose(struct atm_vcc *vcc)
 	}
 	header = (void *)skb_put(skb, sizeof(*header));
 
-	header->size = cpu_to_le16(sizeof(*header));
+	header->size = cpu_to_le16(0);
 	header->vpi = cpu_to_le16(vcc->vpi);
 	header->vci = cpu_to_le16(vcc->vci);
 	header->type = cpu_to_le16(PKT_PCLOSE);
 
 	fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
 
-//	dev_dbg(&card->dev->dev, "Close for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
-	if (!--opens)
-		iowrite32(0, card->config_regs + IRQ_EN_ADDR);
-
 	clear_bit(ATM_VF_ADDR, &vcc->flags);
 	clear_bit(ATM_VF_READY, &vcc->flags);
 
@@ -439,22 +891,26 @@ static void fpga_queue(struct solos_card
 		       struct atm_vcc *vcc)
 {
 	int old_len;
+	unsigned long flags;
 
-	*(void **)skb->cb = vcc;
+	SKB_CB(skb)->vcc = vcc;
 
-	spin_lock(&card->tx_queue_lock);
+	spin_lock_irqsave(&card->tx_queue_lock, flags);
 	old_len = skb_queue_len(&card->tx_queue[port]);
 	skb_queue_tail(&card->tx_queue[port], skb);
-	spin_unlock(&card->tx_queue_lock);
+	if (!old_len)
+		card->tx_mask |= (1 << port);
+	spin_unlock_irqrestore(&card->tx_queue_lock, flags);
 
-	/* If TX might need to be started, do so */
+	/* Theoretically we could just schedule the tasklet here, but
+	   that introduces latency we don't want -- it's noticeable */
 	if (!old_len)
 		fpga_tx(card);
 }
 
-static int fpga_tx(struct solos_card *card)
+static uint32_t fpga_tx(struct solos_card *card)
 {
-	uint32_t tx_pending;
+	uint32_t tx_pending, card_flags;
 	uint32_t tx_started = 0;
 	struct sk_buff *skb;
 	struct atm_vcc *vcc;
@@ -462,69 +918,77 @@ static int fpga_tx(struct solos_card *ca
 	unsigned long flags;
 
 	spin_lock_irqsave(&card->tx_lock, flags);
+	
+	card_flags = ioread32(card->config_regs + FLAGS_ADDR);
+	/*
+	 * The queue lock is required for _writing_ to tx_mask, but we're
+	 * OK to read it here without locking. The only potential update
+	 * that we could race with is in fpga_queue() where it sets a bit
+	 * for a new port... but it's going to call this function again if
+	 * it's doing that, anyway.
+	 */
+	tx_pending = card->tx_mask & ~card_flags;
 
-	tx_pending = ioread32(card->config_regs + FLAGS_ADDR);
-
-	dev_vdbg(&card->dev->dev, "TX Flags are %X\n", tx_pending);
-
-	for (port = 0; port < card->nr_ports; port++) {
-		if (!(tx_pending & (1 << port))) {
+	for (port = 0; tx_pending; tx_pending >>= 1, port++) {
+		if (tx_pending & 1) {
+			struct sk_buff *oldskb = card->tx_skb[port];
+			if (oldskb)
+				pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
+						 oldskb->len, PCI_DMA_TODEVICE);
 
 			spin_lock(&card->tx_queue_lock);
 			skb = skb_dequeue(&card->tx_queue[port]);
+			if (!skb)
+				card->tx_mask &= ~(1 << port);
 			spin_unlock(&card->tx_queue_lock);
 
-			if (!skb)
+			if (skb && !card->using_dma) {
+				memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
+				tx_started |= 1 << port;
+				oldskb = skb; /* We're done with this skb already */
+			} else if (skb && card->using_dma) {
+				SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
+								       skb->len, PCI_DMA_TODEVICE);
+				iowrite32(SKB_CB(skb)->dma_addr,
+					  card->config_regs + TX_DMA_ADDR(port));
+			}
+
+			if (!oldskb)
 				continue;
 
+			/* Clean up and free oldskb now it's gone */
 			if (atmdebug) {
 				dev_info(&card->dev->dev, "Transmitted: port %d\n",
 					 port);
-				print_buffer(skb);
+				print_buffer(oldskb);
 			}
-			memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
 
-			vcc = *(void **)skb->cb;
+			vcc = SKB_CB(oldskb)->vcc;
 
 			if (vcc) {
 				atomic_inc(&vcc->stats->tx);
-				solos_pop(vcc, skb);
+				solos_pop(vcc, oldskb);
 			} else
-				dev_kfree_skb_irq(skb);
+				dev_kfree_skb_irq(oldskb);
 
-			tx_started |= 1 << port; //Set TX full flag
 		}
 	}
+	/* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
 	if (tx_started)
 		iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
 
 	spin_unlock_irqrestore(&card->tx_lock, flags);
-	return 0;
+	return card_flags;
 }
 
 static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
 {
 	struct solos_card *card = vcc->dev->dev_data;
-	struct sk_buff *skb2 = NULL;
 	struct pkt_hdr *header;
+	int pktlen;
 
-	//dev_dbg(&card->dev->dev, "psend called.\n");
-	//dev_dbg(&card->dev->dev, "dev,vpi,vci = %d,%d,%d\n",SOLOS_CHAN(vcc->dev),vcc->vpi,vcc->vci);
-
-	if (debug) {
-		skb2 = atm_alloc_charge(vcc, skb->len, GFP_ATOMIC);
-		if (skb2) {
-			memcpy(skb2->data, skb->data, skb->len);
-			skb_put(skb2, skb->len);
-			vcc->push(vcc, skb2);
-			atomic_inc(&vcc->stats->rx);
-		}
-		atomic_inc(&vcc->stats->tx);
-		solos_pop(vcc, skb);
-		return 0;
-	}
-
-	if (skb->len > (BUF_SIZE - sizeof(*header))) {
+	pktlen = skb->len;
+	if (pktlen > (BUF_SIZE - sizeof(*header))) {
 		dev_warn(&card->dev->dev, "Length of PDU is too large. Dropping PDU.\n");
 		solos_pop(vcc, skb);
 		return 0;
@@ -539,6 +1003,7 @@ static int psend(struct atm_vcc *vcc, st
 
 		ret = pskb_expand_head(skb, expand_by, 0, GFP_ATOMIC);
 		if (ret) {
+			dev_warn(&card->dev->dev, "pskb_expand_head failed.\n");
 			solos_pop(vcc, skb);
 			return ret;
 		}
@@ -546,7 +1011,8 @@ static int psend(struct atm_vcc *vcc, st
 
 	header = (void *)skb_push(skb, sizeof(*header));
 
-	header->size = cpu_to_le16(skb->len);
+	/* This does _not_ include the size of the header */
+	header->size = cpu_to_le16(pktlen);
 	header->vpi = cpu_to_le16(vcc->vpi);
 	header->vci = cpu_to_le16(vcc->vci);
 	header->type = cpu_to_le16(PKT_DATA);
@@ -573,20 +1039,19 @@ static struct atmdev_ops fpga_ops = {
 
 static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	int err, i;
+	int err;
 	uint16_t fpga_ver;
 	uint8_t major_ver, minor_ver;
 	uint32_t data32;
 	struct solos_card *card;
 
-	if (debug)
-		return 0;
-
 	card = kzalloc(sizeof(*card), GFP_KERNEL);
 	if (!card)
 		return -ENOMEM;
 
 	card->dev = dev;
+	init_waitqueue_head(&card->fw_wq);
+	init_waitqueue_head(&card->param_wq);
 
 	err = pci_enable_device(dev);
 	if (err) {
@@ -594,6 +1059,12 @@ static int fpga_probe(struct pci_dev *de
 		goto out;
 	}
 
+	err = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
+	if (err) {
+		dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
+		goto out;
+	}
+
 	err = pci_request_regions(dev, "solos");
 	if (err) {
 		dev_warn(&dev->dev, "Failed to request regions\n");
@@ -611,17 +1082,13 @@ static int fpga_probe(struct pci_dev *de
 		goto out_unmap_config;
 	}
 
-//	for(i=0;i<64 ;i+=4){
-//		data32=ioread32(card->buffers + i);
-//		dev_dbg(&card->dev->dev, "%08lX\n",(unsigned long)data32);
-//	}
-
-	//Fill Config Mem with zeros
-	for(i = 0; i < 128; i += 4)
-		iowrite32(0, card->config_regs + i);
+	if (reset) {
+		iowrite32(1, card->config_regs + FPGA_MODE);
+		data32 = ioread32(card->config_regs + FPGA_MODE); 
 
-	//Set RX empty flags
-	iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+		iowrite32(0, card->config_regs + FPGA_MODE);
+		data32 = ioread32(card->config_regs + FPGA_MODE); 
+	}
 
 	data32 = ioread32(card->config_regs + FPGA_VER);
 	fpga_ver = (data32 & 0x0000FFFF);
@@ -630,55 +1097,53 @@ static int fpga_probe(struct pci_dev *de
 	dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
 		 major_ver, minor_ver, fpga_ver);
 
-	card->nr_ports = 2; /* FIXME: Detect daughterboard */
+	if (0 && fpga_ver > 27)
+		card->using_dma = 1;
+	else {
+		/* Set RX empty flag for all ports */
+		iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+	}
 
-	err = atm_init(card);
-	if (err)
-		goto out_unmap_both;
+	data32 = ioread32(card->config_regs + PORTS);
+	card->nr_ports = (data32 & 0x000000FF);
 
 	pci_set_drvdata(dev, card);
+
 	tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
 	spin_lock_init(&card->tx_lock);
 	spin_lock_init(&card->tx_queue_lock);
 	spin_lock_init(&card->cli_queue_lock);
-/*
-	// Set Loopback mode
-	data32 = 0x00010000;
-	iowrite32(data32,card->config_regs + FLAGS_ADDR);
-*/
-/*
-	// Fill Buffers with zeros
-	for (i = 0; i < BUF_SIZE * 8; i += 4)
-		iowrite32(0, card->buffers + i);
-*/
-/*
-	for(i = 0; i < (BUF_SIZE * 1); i += 4)
-		iowrite32(0x12345678, card->buffers + i + (0*BUF_SIZE));
-	for(i = 0; i < (BUF_SIZE * 1); i += 4)
-		iowrite32(0xabcdef98, card->buffers + i + (1*BUF_SIZE));
+	spin_lock_init(&card->param_queue_lock);
+	INIT_LIST_HEAD(&card->param_queue);
 
-	// Read Config Memory
-	printk(KERN_DEBUG "Reading Config MEM\n");
-	i = 0;
-	for(i = 0; i < 16; i++) {
-		data32=ioread32(card->buffers + i*(BUF_SIZE/2));
-		printk(KERN_ALERT "Addr: %lX Data: %08lX\n",
-		       (unsigned long)(addr_start + i*(BUF_SIZE/2)),
-		       (unsigned long)data32);
-	}
-*/
-	//dev_dbg(&card->dev->dev, "Requesting IRQ: %d\n",dev->irq);
-	err = request_irq(dev->irq, solos_irq, IRQF_DISABLED|IRQF_SHARED,
+	err = request_irq(dev->irq, solos_irq, IRQF_SHARED,
 			  "solos-pci", card);
-	if (err)
+	if (err) {
 		dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
+		goto out_unmap_both;
+	}
 
-	// Enable IRQs
 	iowrite32(1, card->config_regs + IRQ_EN_ADDR);
 
+	if (fpga_upgrade)
+		flash_upgrade(card, 0);
+
+	if (firmware_upgrade)
+		flash_upgrade(card, 1);
+
+	err = atm_init(card);
+	if (err)
+		goto out_free_irq;
+
 	return 0;
 
+ out_free_irq:
+	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
+	free_irq(dev->irq, card);
+	tasklet_kill(&card->tlet);
+	
  out_unmap_both:
+	pci_set_drvdata(dev, NULL);
 	pci_iounmap(dev, card->config_regs);
  out_unmap_config:
 	pci_iounmap(dev, card->buffers);
@@ -693,9 +1158,10 @@ static int atm_init(struct solos_card *c
 {
 	int i;
 
-	opens = 0;
-
 	for (i = 0; i < card->nr_ports; i++) {
+		struct sk_buff *skb;
+		struct pkt_hdr *header;
+
 		skb_queue_head_init(&card->tx_queue[i]);
 		skb_queue_head_init(&card->cli_queue[i]);
 
@@ -707,6 +1173,8 @@ static int atm_init(struct solos_card *c
 		}
 		if (device_create_file(&card->atmdev[i]->class_dev, &dev_attr_console))
 			dev_err(&card->dev->dev, "Could not register console for ATM device %d\n", i);
+		if (sysfs_create_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group))
+			dev_err(&card->dev->dev, "Could not register parameter group for ATM device %d\n", i);
 
 		dev_info(&card->dev->dev, "Registered ATM device %d\n", card->atmdev[i]->number);
 
@@ -714,6 +1182,22 @@ static int atm_init(struct solos_card *c
 		card->atmdev[i]->ci_range.vci_bits = 16;
 		card->atmdev[i]->dev_data = card;
 		card->atmdev[i]->phy_data = (void *)(unsigned long)i;
+		card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN;
+
+		skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+		if (!skb) {
+			dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
+			continue;
+		}
+
+		header = (void *)skb_put(skb, sizeof(*header));
+
+		header->size = cpu_to_le16(0);
+		header->vpi = cpu_to_le16(0);
+		header->vci = cpu_to_le16(0);
+		header->type = cpu_to_le16(PKT_STATUS);
+
+		fpga_queue(card, i, skb, NULL);
 	}
 	return 0;
 }
@@ -724,8 +1208,28 @@ static void atm_remove(struct solos_card
 
 	for (i = 0; i < card->nr_ports; i++) {
 		if (card->atmdev[i]) {
+			struct sk_buff *skb;
+
 			dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number);
+
+			sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group);
 			atm_dev_deregister(card->atmdev[i]);
+
+			skb = card->rx_skb[i];
+			if (skb) {
+				pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+						 RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+				dev_kfree_skb(skb);
+			}
+			skb = card->tx_skb[i];
+			if (skb) {
+				pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+						 skb->len, PCI_DMA_TODEVICE);
+				dev_kfree_skb(skb);
+			}
+			while ((skb = skb_dequeue(&card->tx_queue[i])))
+				dev_kfree_skb(skb);
+ 
 		}
 	}
 }
@@ -733,31 +1237,31 @@ static void atm_remove(struct solos_card
 static void fpga_remove(struct pci_dev *dev)
 {
 	struct solos_card *card = pci_get_drvdata(dev);
+	
+	/* Disable IRQs */
+	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
 
-	if (debug)
-		return;
+	/* Reset FPGA */
+	iowrite32(1, card->config_regs + FPGA_MODE);
+	(void)ioread32(card->config_regs + FPGA_MODE); 
 
 	atm_remove(card);
 
-	dev_vdbg(&dev->dev, "Freeing IRQ\n");
-	// Disable IRQs from FPGA
-	iowrite32(0, card->config_regs + IRQ_EN_ADDR);
 	free_irq(dev->irq, card);
 	tasklet_kill(&card->tlet);
 
-	//	iowrite32(0x01,pciregs);
-	dev_vdbg(&dev->dev, "Unmapping PCI resource\n");
+	/* Release device from reset */
+	iowrite32(0, card->config_regs + FPGA_MODE);
+	(void)ioread32(card->config_regs + FPGA_MODE); 
+
 	pci_iounmap(dev, card->buffers);
 	pci_iounmap(dev, card->config_regs);
 
-	dev_vdbg(&dev->dev, "Releasing PCI Region\n");
 	pci_release_regions(dev);
 	pci_disable_device(dev);
 
 	pci_set_drvdata(dev, NULL);
 	kfree(card);
-//	dev_dbg(&card->dev->dev, "fpga_remove\n");
-	return;
 }
 
 static struct pci_device_id fpga_pci_tbl[] __devinitdata = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/auxdisplay/Kconfig linux-libre-2.6.30-gnu1/drivers/auxdisplay/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/auxdisplay/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/auxdisplay/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,6 @@
 #
 
 menuconfig AUXDISPLAY
-	depends on PARPORT
 	bool "Auxiliary Display support"
 	---help---
 	  Say Y here to get to see options for auxiliary display drivers.
@@ -14,7 +13,7 @@ menuconfig AUXDISPLAY
 
 	  If you say N, all options in this submenu will be skipped and disabled.
 
-if AUXDISPLAY && PARPORT
+if AUXDISPLAY
 
 config KS0108
 	tristate "KS0108 LCD Controller"
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/base.h linux-libre-2.6.30-gnu1/drivers/base/base.h
--- linux-libre-2.6.29-gnu1/drivers/base/base.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/base.h	2009-06-09 23:05:27.000000000 -0400
@@ -63,6 +63,32 @@ struct class_private {
 #define to_class(obj)	\
 	container_of(obj, struct class_private, class_subsys.kobj)
 
+/**
+ * struct device_private - structure to hold the private to the driver core portions of the device structure.
+ *
+ * @klist_children - klist containing all children of this device
+ * @knode_parent - node in sibling list
+ * @knode_driver - node in driver list
+ * @knode_bus - node in bus list
+ * @device - pointer back to the struct class that this structure is
+ * associated with.
+ *
+ * Nothing outside of the driver core should ever touch these fields.
+ */
+struct device_private {
+	struct klist klist_children;
+	struct klist_node knode_parent;
+	struct klist_node knode_driver;
+	struct klist_node knode_bus;
+	struct device *device;
+};
+#define to_device_private_parent(obj)	\
+	container_of(obj, struct device_private, knode_parent)
+#define to_device_private_driver(obj)	\
+	container_of(obj, struct device_private, knode_driver)
+#define to_device_private_bus(obj)	\
+	container_of(obj, struct device_private, knode_bus)
+
 /* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
@@ -86,6 +112,11 @@ extern void bus_remove_driver(struct dev
 
 extern void driver_detach(struct device_driver *drv);
 extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+				      struct device *dev)
+{
+	return drv->bus->match ? drv->bus->match(dev, drv) : 1;
+}
 
 extern void sysdev_shutdown(void);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/bus.c linux-libre-2.6.30-gnu1/drivers/base/bus.c
--- linux-libre-2.6.29-gnu1/drivers/base/bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device
 	int err = -ENODEV;
 
 	dev = bus_find_device_by_name(bus, NULL, buf);
-	if (dev && dev->driver == NULL) {
+	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
 		if (dev->parent)	/* Needed for USB */
 			down(&dev->parent->sem);
 		down(&dev->sem);
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struc
 static struct device *next_device(struct klist_iter *i)
 {
 	struct klist_node *n = klist_next(i);
-	return n ? container_of(n, struct device, knode_bus) : NULL;
+	struct device *dev = NULL;
+	struct device_private *dev_prv;
+
+	if (n) {
+		dev_prv = to_device_private_bus(n);
+		dev = dev_prv->device;
+	}
+	return dev;
 }
 
 /**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bu
 		return -EINVAL;
 
 	klist_iter_init_node(&bus->p->klist_devices, &i,
-			     (start ? &start->knode_bus : NULL));
+			     (start ? &start->p->knode_bus : NULL));
 	while ((dev = next_device(&i)) && !error)
 		error = fn(dev, data);
 	klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bu
 		return NULL;
 
 	klist_iter_init_node(&bus->p->klist_devices, &i,
-			     (start ? &start->knode_bus : NULL));
+			     (start ? &start->p->knode_bus : NULL));
 	while ((dev = next_device(&i)))
 		if (match(dev, data) && get_device(dev))
 			break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *de
 			ret = device_attach(dev);
 		WARN_ON(ret < 0);
 		if (ret >= 0)
-			klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
+			klist_add_tail(&dev->p->knode_bus,
+				       &bus->p->klist_devices);
 	}
 }
 
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *de
 		sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
 				  dev_name(dev));
 		device_remove_attrs(dev->bus, dev);
-		if (klist_node_attached(&dev->knode_bus))
-			klist_del(&dev->knode_bus);
+		if (klist_node_attached(&dev->p->knode_bus))
+			klist_del(&dev->p->knode_bus);
 
 		pr_debug("bus: '%s': remove device %s\n",
 			 dev->bus->name, dev_name(dev));
@@ -692,8 +700,10 @@ int bus_add_driver(struct device_driver
 	}
 
 	kobject_uevent(&priv->kobj, KOBJ_ADD);
-	return error;
+	return 0;
 out_unregister:
+	kfree(drv->p);
+	drv->p = NULL;
 	kobject_put(&priv->kobj);
 out_put_bus:
 	bus_put(bus);
@@ -831,14 +841,16 @@ static void bus_remove_attrs(struct bus_
 
 static void klist_devices_get(struct klist_node *n)
 {
-	struct device *dev = container_of(n, struct device, knode_bus);
+	struct device_private *dev_prv = to_device_private_bus(n);
+	struct device *dev = dev_prv->device;
 
 	get_device(dev);
 }
 
 static void klist_devices_put(struct klist_node *n)
 {
-	struct device *dev = container_of(n, struct device, knode_bus);
+	struct device_private *dev_prv = to_device_private_bus(n);
+	struct device *dev = dev_prv->device;
 
 	put_device(dev);
 }
@@ -932,6 +944,7 @@ bus_uevent_fail:
 	kset_unregister(&bus->p->subsys);
 	kfree(bus->p);
 out:
+	bus->p = NULL;
 	return retval;
 }
 EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +966,7 @@ void bus_unregister(struct bus_type *bus
 	bus_remove_file(bus, &bus_attr_uevent);
 	kset_unregister(&bus->p->subsys);
 	kfree(bus->p);
+	bus->p = NULL;
 }
 EXPORT_SYMBOL_GPL(bus_unregister);
 
@@ -993,18 +1007,20 @@ static void device_insertion_sort_klist(
 {
 	struct list_head *pos;
 	struct klist_node *n;
+	struct device_private *dev_prv;
 	struct device *b;
 
 	list_for_each(pos, list) {
 		n = container_of(pos, struct klist_node, n_node);
-		b = container_of(n, struct device, knode_bus);
+		dev_prv = to_device_private_bus(n);
+		b = dev_prv->device;
 		if (compare(a, b) <= 0) {
-			list_move_tail(&a->knode_bus.n_node,
-				       &b->knode_bus.n_node);
+			list_move_tail(&a->p->knode_bus.n_node,
+				       &b->p->knode_bus.n_node);
 			return;
 		}
 	}
-	list_move_tail(&a->knode_bus.n_node, list);
+	list_move_tail(&a->p->knode_bus.n_node, list);
 }
 
 void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1014,6 +1030,7 @@ void bus_sort_breadthfirst(struct bus_ty
 	LIST_HEAD(sorted_devices);
 	struct list_head *pos, *tmp;
 	struct klist_node *n;
+	struct device_private *dev_prv;
 	struct device *dev;
 	struct klist *device_klist;
 
@@ -1022,7 +1039,8 @@ void bus_sort_breadthfirst(struct bus_ty
 	spin_lock(&device_klist->k_lock);
 	list_for_each_safe(pos, tmp, &device_klist->k_list) {
 		n = container_of(pos, struct klist_node, n_node);
-		dev = container_of(n, struct device, knode_bus);
+		dev_prv = to_device_private_bus(n);
+		dev = dev_prv->device;
 		device_insertion_sort_klist(dev, &sorted_devices, compare);
 	}
 	list_splice(&sorted_devices, &device_klist->k_list);
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/core.c linux-libre-2.6.30-gnu1/drivers/base/core.c
--- linux-libre-2.6.29-gnu1/drivers/base/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops =
 static void device_release(struct kobject *kobj)
 {
 	struct device *dev = to_dev(kobj);
+	struct device_private *p = dev->p;
 
 	if (dev->release)
 		dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobjec
 		WARN(1, KERN_ERR "Device '%s' does not have a release() "
 			"function, it is broken and must be fixed.\n",
 			dev_name(dev));
+	kfree(p);
 }
 
 static struct kobj_type device_ktype = {
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset
 
 	if (ktype == &device_ktype) {
 		struct device *dev = to_dev(kobj);
-		if (dev->uevent_suppress)
-			return 0;
 		if (dev->bus)
 			return 1;
 		if (dev->class)
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callba
 
 static void klist_children_get(struct klist_node *n)
 {
-	struct device *dev = container_of(n, struct device, knode_parent);
+	struct device_private *p = to_device_private_parent(n);
+	struct device *dev = p->device;
 
 	get_device(dev);
 }
 
 static void klist_children_put(struct klist_node *n)
 {
-	struct device *dev = container_of(n, struct device, knode_parent);
+	struct device_private *p = to_device_private_parent(n);
+	struct device *dev = p->device;
 
 	put_device(dev);
 }
@@ -538,8 +540,6 @@ void device_initialize(struct device *de
 {
 	dev->kobj.kset = devices_kset;
 	kobject_init(&dev->kobj, &device_ktype);
-	klist_init(&dev->klist_children, klist_children_get,
-		   klist_children_put);
 	INIT_LIST_HEAD(&dev->dma_pools);
 	init_MUTEX(&dev->sem);
 	spin_lock_init(&dev->devres_lock);
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks
 int dev_set_name(struct device *dev, const char *fmt, ...)
 {
 	va_list vargs;
-	char *s;
+	int err;
 
 	va_start(vargs, fmt);
-	vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+	err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
 	va_end(vargs);
-
-	/* ewww... some of these buggers have / in the name... */
-	while ((s = strchr(dev->bus_id, '/')))
-		*s = '!';
-
-	return 0;
+	return err;
 }
 EXPORT_SYMBOL_GPL(dev_set_name);
 
@@ -864,13 +859,27 @@ int device_add(struct device *dev)
 	if (!dev)
 		goto done;
 
-	/* Temporarily support init_name if it is set.
-	 * It will override bus_id for now */
-	if (dev->init_name)
-		dev_set_name(dev, "%s", dev->init_name);
-
-	if (!strlen(dev->bus_id))
+	dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+	if (!dev->p) {
+		error = -ENOMEM;
 		goto done;
+	}
+	dev->p->device = dev;
+	klist_init(&dev->p->klist_children, klist_children_get,
+		   klist_children_put);
+
+	/*
+	 * for statically allocated devices, which should all be converted
+	 * some day, we need to initialize the name. We prevent reading back
+	 * the name, and force the use of dev_name()
+	 */
+	if (dev->init_name) {
+		dev_set_name(dev, dev->init_name);
+		dev->init_name = NULL;
+	}
+
+	if (!dev_name(dev))
+		goto name_error;
 
 	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
 
@@ -882,7 +891,8 @@ int device_add(struct device *dev)
 		set_dev_node(dev, dev_to_node(parent));
 
 	/* first, register with generic layer. */
-	error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev_name(dev));
+	/* we require the name to be set before, and pass NULL */
+	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
 	if (error)
 		goto Error;
 
@@ -928,7 +938,8 @@ int device_add(struct device *dev)
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	bus_attach_device(dev);
 	if (parent)
-		klist_add_tail(&dev->knode_parent, &parent->klist_children);
+		klist_add_tail(&dev->p->knode_parent,
+			       &parent->p->klist_children);
 
 	if (dev->class) {
 		mutex_lock(&dev->class->p->class_mutex);
@@ -967,6 +978,9 @@ done:
 	cleanup_device_parent(dev);
 	if (parent)
 		put_device(parent);
+name_error:
+	kfree(dev->p);
+	dev->p = NULL;
 	goto done;
 }
 
@@ -1042,7 +1056,7 @@ void device_del(struct device *dev)
 	device_pm_remove(dev);
 	dpm_sysfs_remove(dev);
 	if (parent)
-		klist_del(&dev->knode_parent);
+		klist_del(&dev->p->knode_parent);
 	if (MAJOR(dev->devt)) {
 		device_remove_sys_dev_entry(dev);
 		device_remove_file(dev, &devt_attr);
@@ -1103,7 +1117,14 @@ void device_unregister(struct device *de
 static struct device *next_device(struct klist_iter *i)
 {
 	struct klist_node *n = klist_next(i);
-	return n ? container_of(n, struct device, knode_parent) : NULL;
+	struct device *dev = NULL;
+	struct device_private *p;
+
+	if (n) {
+		p = to_device_private_parent(n);
+		dev = p->device;
+	}
+	return dev;
 }
 
 /**
@@ -1125,7 +1146,10 @@ int device_for_each_child(struct device
 	struct device *child;
 	int error = 0;
 
-	klist_iter_init(&parent->klist_children, &i);
+	if (!parent->p)
+		return 0;
+
+	klist_iter_init(&parent->p->klist_children, &i);
 	while ((child = next_device(&i)) && !error)
 		error = fn(child, data);
 	klist_iter_exit(&i);
@@ -1156,7 +1180,7 @@ struct device *device_find_child(struct
 	if (!parent)
 		return NULL;
 
-	klist_iter_init(&parent->klist_children, &i);
+	klist_iter_init(&parent->p->klist_children, &i);
 	while ((child = next_device(&i)))
 		if (match(child, data) && get_device(child))
 			break;
@@ -1348,7 +1372,10 @@ struct device *device_create_vargs(struc
 	dev->release = device_create_release;
 	dev_set_drvdata(dev, drvdata);
 
-	vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
+	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+	if (retval)
+		goto error;
+
 	retval = device_register(dev);
 	if (retval)
 		goto error;
@@ -1452,19 +1479,15 @@ int device_rename(struct device *dev, ch
 		old_class_name = make_class_name(dev->class->name, &dev->kobj);
 #endif
 
-	old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+	old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
 	if (!old_device_name) {
 		error = -ENOMEM;
 		goto out;
 	}
-	strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
-	strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
 
 	error = kobject_rename(&dev->kobj, new_name);
-	if (error) {
-		strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
+	if (error)
 		goto out;
-	}
 
 #ifdef CONFIG_SYSFS_DEPRECATED
 	if (old_class_name) {
@@ -1545,8 +1568,10 @@ out:
  * device_move - moves a device to a new parent
  * @dev: the pointer to the struct device to be moved
  * @new_parent: the new parent of the device (can by NULL)
+ * @dpm_order: how to reorder the dpm_list
  */
-int device_move(struct device *dev, struct device *new_parent)
+int device_move(struct device *dev, struct device *new_parent,
+		enum dpm_order dpm_order)
 {
 	int error;
 	struct device *old_parent;
@@ -1556,6 +1581,7 @@ int device_move(struct device *dev, stru
 	if (!dev)
 		return -EINVAL;
 
+	device_pm_lock();
 	new_parent = get_device(new_parent);
 	new_parent_kobj = get_device_parent(dev, new_parent);
 
@@ -1570,9 +1596,10 @@ int device_move(struct device *dev, stru
 	old_parent = dev->parent;
 	dev->parent = new_parent;
 	if (old_parent)
-		klist_remove(&dev->knode_parent);
+		klist_remove(&dev->p->knode_parent);
 	if (new_parent) {
-		klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+		klist_add_tail(&dev->p->knode_parent,
+			       &new_parent->p->klist_children);
 		set_dev_node(dev, dev_to_node(new_parent));
 	}
 
@@ -1584,11 +1611,11 @@ int device_move(struct device *dev, stru
 		device_move_class_links(dev, new_parent, old_parent);
 		if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
 			if (new_parent)
-				klist_remove(&dev->knode_parent);
+				klist_remove(&dev->p->knode_parent);
 			dev->parent = old_parent;
 			if (old_parent) {
-				klist_add_tail(&dev->knode_parent,
-					       &old_parent->klist_children);
+				klist_add_tail(&dev->p->knode_parent,
+					       &old_parent->p->klist_children);
 				set_dev_node(dev, dev_to_node(old_parent));
 			}
 		}
@@ -1596,9 +1623,23 @@ int device_move(struct device *dev, stru
 		put_device(new_parent);
 		goto out;
 	}
+	switch (dpm_order) {
+	case DPM_ORDER_NONE:
+		break;
+	case DPM_ORDER_DEV_AFTER_PARENT:
+		device_pm_move_after(dev, new_parent);
+		break;
+	case DPM_ORDER_PARENT_BEFORE_DEV:
+		device_pm_move_before(new_parent, dev);
+		break;
+	case DPM_ORDER_DEV_LAST:
+		device_pm_move_last(dev);
+		break;
+	}
 out_put:
 	put_device(old_parent);
 out:
+	device_pm_unlock();
 	put_device(dev);
 	return error;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/cpu.c linux-libre-2.6.30-gnu1/drivers/base/cpu.c
--- linux-libre-2.6.29-gnu1/drivers/base/cpu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/cpu.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,7 +107,7 @@ static SYSDEV_ATTR(crash_notes, 0400, sh
 /*
  * Print cpu online, possible, present, and system maps
  */
-static ssize_t print_cpus_map(char *buf, cpumask_t *map)
+static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
 {
 	int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
 
@@ -119,7 +119,7 @@ static ssize_t print_cpus_map(char *buf,
 #define	print_cpus_func(type) \
 static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf)	\
 {									\
-	return print_cpus_map(buf, &cpu_##type##_map);			\
+	return print_cpus_map(buf, cpu_##type##_mask);			\
 }									\
 static struct sysdev_class_attribute attr_##type##_map = 		\
 	_SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/dd.c linux-libre-2.6.30-gnu1/drivers/base/dd.c
--- linux-libre-2.6.29-gnu1/drivers/base/dd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/dd.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,7 +30,7 @@
 
 static void driver_bound(struct device *dev)
 {
-	if (klist_node_attached(&dev->knode_driver)) {
+	if (klist_node_attached(&dev->p->knode_driver)) {
 		printk(KERN_WARNING "%s: device %s already bound\n",
 			__func__, kobject_name(&dev->kobj));
 		return;
@@ -43,7 +43,7 @@ static void driver_bound(struct device *
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_BOUND_DRIVER, dev);
 
-	klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
+	klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
 }
 
 static int driver_sysfs_add(struct device *dev)
@@ -172,31 +172,22 @@ int driver_probe_done(void)
 /**
  * wait_for_device_probe
  * Wait for device probing to be completed.
- *
- * Note: this function polls at 100 msec intervals.
  */
-int wait_for_device_probe(void)
+void wait_for_device_probe(void)
 {
 	/* wait for the known devices to complete their probing */
-	while (driver_probe_done() != 0)
-		msleep(100);
+	wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
 	async_synchronize_full();
-	return 0;
 }
+EXPORT_SYMBOL_GPL(wait_for_device_probe);
 
 /**
  * driver_probe_device - attempt to bind device & driver together
  * @drv: driver to bind a device to
  * @dev: device to try to bind to the driver
  *
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully 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.
@@ -207,21 +198,22 @@ int driver_probe_device(struct device_dr
 
 	if (!device_is_registered(dev))
 		return -ENODEV;
-	if (drv->bus->match && !drv->bus->match(dev, drv))
-		goto done;
 
 	pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
 		 drv->bus->name, __func__, dev_name(dev), drv->name);
 
 	ret = really_probe(dev, drv);
 
-done:
 	return ret;
 }
 
 static int __device_attach(struct device_driver *drv, void *data)
 {
 	struct device *dev = data;
+
+	if (!driver_match_device(drv, dev))
+		return 0;
+
 	return driver_probe_device(drv, dev);
 }
 
@@ -274,7 +266,7 @@ static int __driver_attach(struct device
 	 * is an error.
 	 */
 
-	if (drv->bus->match && !drv->bus->match(dev, drv))
+	if (!driver_match_device(drv, dev))
 		return 0;
 
 	if (dev->parent)	/* Needed for USB */
@@ -327,7 +319,7 @@ static void __device_release_driver(stru
 			drv->remove(dev);
 		devres_release_all(dev);
 		dev->driver = NULL;
-		klist_remove(&dev->knode_driver);
+		klist_remove(&dev->p->knode_driver);
 	}
 }
 
@@ -357,6 +349,7 @@ EXPORT_SYMBOL_GPL(device_release_driver)
  */
 void driver_detach(struct device_driver *drv)
 {
+	struct device_private *dev_prv;
 	struct device *dev;
 
 	for (;;) {
@@ -365,8 +358,10 @@ void driver_detach(struct device_driver
 			spin_unlock(&drv->p->klist_devices.k_lock);
 			break;
 		}
-		dev = list_entry(drv->p->klist_devices.k_list.prev,
-				struct device, knode_driver.n_node);
+		dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
+				     struct device_private,
+				     knode_driver.n_node);
+		dev = dev_prv->device;
 		get_device(dev);
 		spin_unlock(&drv->p->klist_devices.k_lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/driver.c linux-libre-2.6.30-gnu1/drivers/base/driver.c
--- linux-libre-2.6.29-gnu1/drivers/base/driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,14 @@
 static struct device *next_device(struct klist_iter *i)
 {
 	struct klist_node *n = klist_next(i);
-	return n ? container_of(n, struct device, knode_driver) : NULL;
+	struct device *dev = NULL;
+	struct device_private *dev_prv;
+
+	if (n) {
+		dev_prv = to_device_private_driver(n);
+		dev = dev_prv->device;
+	}
+	return dev;
 }
 
 /**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device
 		return -EINVAL;
 
 	klist_iter_init_node(&drv->p->klist_devices, &i,
-			     start ? &start->knode_driver : NULL);
+			     start ? &start->p->knode_driver : NULL);
 	while ((dev = next_device(&i)) && !error)
 		error = fn(dev, data);
 	klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct
 		return NULL;
 
 	klist_iter_init_node(&drv->p->klist_devices, &i,
-			     (start ? &start->knode_driver : NULL));
+			     (start ? &start->p->knode_driver : NULL));
 	while ((dev = next_device(&i)))
 		if (match(dev, data) && get_device(dev))
 			break;
@@ -216,6 +223,8 @@ int driver_register(struct device_driver
 	int ret;
 	struct device_driver *other;
 
+	BUG_ON(!drv->bus->p);
+
 	if ((drv->bus->probe && drv->probe) ||
 	    (drv->bus->remove && drv->remove) ||
 	    (drv->bus->shutdown && drv->shutdown))
@@ -248,6 +257,10 @@ EXPORT_SYMBOL_GPL(driver_register);
  */
 void driver_unregister(struct device_driver *drv)
 {
+	if (!drv || !drv->p) {
+		WARN(1, "Unexpected driver unregister!\n");
+		return;
+	}
 	driver_remove_groups(drv, drv->groups);
 	bus_remove_driver(drv);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/firmware_class.c linux-libre-2.6.30-gnu1/drivers/base/firmware_class.c
--- linux-libre-2.6.29-gnu1/drivers/base/firmware_class.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/firmware_class.c	2009-06-09 23:05:27.000000000 -0400
@@ -319,7 +319,7 @@ static int fw_register_device(struct dev
 	f_dev->parent = device;
 	f_dev->class = &firmware_class;
 	dev_set_drvdata(f_dev, fw_priv);
-	f_dev->uevent_suppress = 1;
+	dev_set_uevent_suppress(f_dev, 1);
 	retval = device_register(f_dev);
 	if (retval) {
 		dev_err(device, "%s: device_register failed\n", __func__);
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmwa
 	}
 
 	if (uevent)
-		f_dev->uevent_suppress = 0;
+		dev_set_uevent_suppress(f_dev, 0);
 	*dev_p = f_dev;
 	goto out;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/iommu.c linux-libre-2.6.30-gnu1/drivers/base/iommu.c
--- linux-libre-2.6.29-gnu1/drivers/base/iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,8 @@
 
 #include <linux/bug.h>
 #include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/iommu.h>
 
@@ -31,7 +33,7 @@ void register_iommu(struct iommu_ops *op
 	iommu_ops = ops;
 }
 
-bool iommu_found()
+bool iommu_found(void)
 {
 	return iommu_ops != NULL;
 }
@@ -98,3 +100,10 @@ phys_addr_t iommu_iova_to_phys(struct io
 	return iommu_ops->iova_to_phys(domain, iova);
 }
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+			 unsigned long cap)
+{
+	return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/isa.c linux-libre-2.6.30-gnu1/drivers/base/isa.c
--- linux-libre-2.6.29-gnu1/drivers/base/isa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/isa.c	2009-06-09 23:05:27.000000000 -0400
@@ -141,7 +141,7 @@ int isa_register_driver(struct isa_drive
 		isa_dev->dev.release		= isa_dev_release;
 		isa_dev->id			= id;
 
-		isa_dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
+		isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24);
 		isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask;
 
 		error = device_register(&isa_dev->dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/node.c linux-libre-2.6.30-gnu1/drivers/base/node.c
--- linux-libre-2.6.29-gnu1/drivers/base/node.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/node.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,7 @@ static struct sysdev_class node_class =
 static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
 {
 	struct node *node_dev = to_node(dev);
-	node_to_cpumask_ptr(mask, node_dev->sysdev.id);
+	const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
 	int len;
 
 	/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/platform.c linux-libre-2.6.30-gnu1/drivers/base/platform.c
--- linux-libre-2.6.29-gnu1/drivers/base/platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -584,10 +584,25 @@ static int platform_uevent(struct device
 {
 	struct platform_device	*pdev = to_platform_device(dev);
 
-	add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+	add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+		(pdev->id_entry) ? pdev->id_entry->name : pdev->name);
 	return 0;
 }
 
+static const struct platform_device_id *platform_match_id(
+			struct platform_device_id *id,
+			struct platform_device *pdev)
+{
+	while (id->name[0]) {
+		if (strcmp(pdev->name, id->name) == 0) {
+			pdev->id_entry = id;
+			return id;
+		}
+		id++;
+	}
+	return NULL;
+}
+
 /**
  * platform_match - bind platform device to platform driver.
  * @dev: device.
@@ -603,9 +618,14 @@ static int platform_uevent(struct device
  */
 static int platform_match(struct device *dev, struct device_driver *drv)
 {
-	struct platform_device *pdev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct platform_driver *pdrv = to_platform_driver(drv);
 
-	pdev = container_of(dev, struct platform_device, dev);
+	/* match against the id table first */
+	if (pdrv->id_table)
+		return platform_match_id(pdrv->id_table, pdev) != NULL;
+
+	/* fall-back to driver name match */
 	return (strcmp(pdev->name, drv->name) == 0);
 }
 
@@ -623,26 +643,24 @@ static int platform_legacy_suspend(struc
 
 static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
 {
-	struct platform_driver *drv = to_platform_driver(dev->driver);
-	struct platform_device *pdev;
+	struct platform_driver *pdrv = to_platform_driver(dev->driver);
+	struct platform_device *pdev = to_platform_device(dev);
 	int ret = 0;
 
-	pdev = container_of(dev, struct platform_device, dev);
-	if (dev->driver && drv->suspend_late)
-		ret = drv->suspend_late(pdev, mesg);
+	if (dev->driver && pdrv->suspend_late)
+		ret = pdrv->suspend_late(pdev, mesg);
 
 	return ret;
 }
 
 static int platform_legacy_resume_early(struct device *dev)
 {
-	struct platform_driver *drv = to_platform_driver(dev->driver);
-	struct platform_device *pdev;
+	struct platform_driver *pdrv = to_platform_driver(dev->driver);
+	struct platform_device *pdev = to_platform_device(dev);
 	int ret = 0;
 
-	pdev = container_of(dev, struct platform_device, dev);
-	if (dev->driver && drv->resume_early)
-		ret = drv->resume_early(pdev);
+	if (dev->driver && pdrv->resume_early)
+		ret = pdrv->resume_early(pdev);
 
 	return ret;
 }
@@ -956,6 +974,8 @@ int __init platform_bus_init(void)
 {
 	int error;
 
+	early_platform_cleanup();
+
 	error = device_register(&platform_bus);
 	if (error)
 		return error;
@@ -986,3 +1006,240 @@ u64 dma_get_required_mask(struct device
 }
 EXPORT_SYMBOL_GPL(dma_get_required_mask);
 #endif
+
+static __initdata LIST_HEAD(early_platform_driver_list);
+static __initdata LIST_HEAD(early_platform_device_list);
+
+/**
+ * early_platform_driver_register
+ * @epdrv: early_platform driver structure
+ * @buf: string passed from early_param()
+ */
+int __init early_platform_driver_register(struct early_platform_driver *epdrv,
+					  char *buf)
+{
+	unsigned long index;
+	int n;
+
+	/* Simply add the driver to the end of the global list.
+	 * Drivers will by default be put on the list in compiled-in order.
+	 */
+	if (!epdrv->list.next) {
+		INIT_LIST_HEAD(&epdrv->list);
+		list_add_tail(&epdrv->list, &early_platform_driver_list);
+	}
+
+	/* If the user has specified device then make sure the driver
+	 * gets prioritized. The driver of the last device specified on
+	 * command line will be put first on the list.
+	 */
+	n = strlen(epdrv->pdrv->driver.name);
+	if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
+		list_move(&epdrv->list, &early_platform_driver_list);
+
+		if (!strcmp(buf, epdrv->pdrv->driver.name))
+			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;
+	}
+
+	return 0;
+}
+
+/**
+ * early_platform_add_devices - add a numbers of early platform devices
+ * @devs: array of early platform devices to add
+ * @num: number of early platform devices in array
+ */
+void __init early_platform_add_devices(struct platform_device **devs, int num)
+{
+	struct device *dev;
+	int i;
+
+	/* simply add the devices to list */
+	for (i = 0; i < num; i++) {
+		dev = &devs[i]->dev;
+
+		if (!dev->devres_head.next) {
+			INIT_LIST_HEAD(&dev->devres_head);
+			list_add_tail(&dev->devres_head,
+				      &early_platform_device_list);
+		}
+	}
+}
+
+/**
+ * early_platform_driver_register_all
+ * @class_str: string to identify early platform driver class
+ */
+void __init early_platform_driver_register_all(char *class_str)
+{
+	/* The "class_str" parameter may or may not be present on the kernel
+	 * command line. If it is present then there may be more than one
+	 * matching parameter.
+	 *
+	 * Since we register our early platform drivers using early_param()
+	 * we need to make sure that they also get registered in the case
+	 * when the parameter is missing from the kernel command line.
+	 *
+	 * We use parse_early_options() to make sure the early_param() gets
+	 * called at least once. The early_param() may be called more than
+	 * once since the name of the preferred device may be specified on
+	 * the kernel command line. early_platform_driver_register() handles
+	 * this case for us.
+	 */
+	parse_early_options(class_str);
+}
+
+/**
+ * early_platform_match
+ * @epdrv: early platform driver structure
+ * @id: id to match against
+ */
+static  __init struct platform_device *
+early_platform_match(struct early_platform_driver *epdrv, int id)
+{
+	struct platform_device *pd;
+
+	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+			if (pd->id == id)
+				return pd;
+
+	return NULL;
+}
+
+/**
+ * early_platform_left
+ * @epdrv: early platform driver structure
+ * @id: return true if id or above exists
+ */
+static  __init int early_platform_left(struct early_platform_driver *epdrv,
+				       int id)
+{
+	struct platform_device *pd;
+
+	list_for_each_entry(pd, &early_platform_device_list, dev.devres_head)
+		if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+			if (pd->id >= id)
+				return 1;
+
+	return 0;
+}
+
+/**
+ * early_platform_driver_probe_id
+ * @class_str: string to identify early platform driver class
+ * @id: id to match against
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ */
+static int __init early_platform_driver_probe_id(char *class_str,
+						 int id,
+						 int nr_probe)
+{
+	struct early_platform_driver *epdrv;
+	struct platform_device *match;
+	int match_id;
+	int n = 0;
+	int left = 0;
+
+	list_for_each_entry(epdrv, &early_platform_driver_list, list) {
+		/* only use drivers matching our class_str */
+		if (strcmp(class_str, epdrv->class_str))
+			continue;
+
+		if (id == -2) {
+			match_id = epdrv->requested_id;
+			left = 1;
+
+		} else {
+			match_id = id;
+			left += early_platform_left(epdrv, id);
+
+			/* skip requested id */
+			switch (epdrv->requested_id) {
+			case EARLY_PLATFORM_ID_ERROR:
+			case EARLY_PLATFORM_ID_UNSET:
+				break;
+			default:
+				if (epdrv->requested_id == id)
+					match_id = EARLY_PLATFORM_ID_UNSET;
+			}
+		}
+
+		switch (match_id) {
+		case EARLY_PLATFORM_ID_ERROR:
+			pr_warning("%s: unable to parse %s parameter\n",
+				   class_str, epdrv->pdrv->driver.name);
+			/* fall-through */
+		case EARLY_PLATFORM_ID_UNSET:
+			match = NULL;
+			break;
+		default:
+			match = early_platform_match(epdrv, match_id);
+		}
+
+		if (match) {
+			if (epdrv->pdrv->probe(match))
+				pr_warning("%s: unable to probe %s early.\n",
+					   class_str, match->name);
+			else
+				n++;
+		}
+
+		if (n >= nr_probe)
+			break;
+	}
+
+	if (left)
+		return n;
+	else
+		return -ENODEV;
+}
+
+/**
+ * early_platform_driver_probe
+ * @class_str: string to identify early platform driver class
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ * @user_only: only probe user specified early platform devices
+ */
+int __init early_platform_driver_probe(char *class_str,
+				       int nr_probe,
+				       int user_only)
+{
+	int k, n, i;
+
+	n = 0;
+	for (i = -2; n < nr_probe; i++) {
+		k = early_platform_driver_probe_id(class_str, i, nr_probe - n);
+
+		if (k < 0)
+			break;
+
+		n += k;
+
+		if (user_only)
+			break;
+	}
+
+	return n;
+}
+
+/**
+ * early_platform_cleanup - clean up early platform code
+ */
+void __init early_platform_cleanup(void)
+{
+	struct platform_device *pd, *pd2;
+
+	/* clean up the devres list used to chain devices */
+	list_for_each_entry_safe(pd, pd2, &early_platform_device_list,
+				 dev.devres_head) {
+		list_del(&pd->dev.devres_head);
+		memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
+	}
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/power/main.c linux-libre-2.6.30-gnu1/drivers/base/power/main.c
--- linux-libre-2.6.29-gnu1/drivers/base/power/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/power/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pm.h>
 #include <linux/resume-trace.h>
 #include <linux/rwsem.h>
+#include <linux/interrupt.h>
 
 #include "../base.h"
 #include "power.h"
@@ -107,6 +108,50 @@ void device_pm_remove(struct device *dev
 }
 
 /**
+ *	device_pm_move_before - move device in dpm_list
+ *	@deva:  Device to move in dpm_list
+ *	@devb:  Device @deva should come before
+ */
+void device_pm_move_before(struct device *deva, struct device *devb)
+{
+	pr_debug("PM: Moving %s:%s before %s:%s\n",
+		 deva->bus ? deva->bus->name : "No Bus",
+		 kobject_name(&deva->kobj),
+		 devb->bus ? devb->bus->name : "No Bus",
+		 kobject_name(&devb->kobj));
+	/* Delete deva from dpm_list and reinsert before devb. */
+	list_move_tail(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ *	device_pm_move_after - move device in dpm_list
+ *	@deva:  Device to move in dpm_list
+ *	@devb:  Device @deva should come after
+ */
+void device_pm_move_after(struct device *deva, struct device *devb)
+{
+	pr_debug("PM: Moving %s:%s after %s:%s\n",
+		 deva->bus ? deva->bus->name : "No Bus",
+		 kobject_name(&deva->kobj),
+		 devb->bus ? devb->bus->name : "No Bus",
+		 kobject_name(&devb->kobj));
+	/* Delete deva from dpm_list and reinsert after devb. */
+	list_move(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * 	device_pm_move_last - move device to end of dpm_list
+ * 	@dev:   Device to move in dpm_list
+ */
+void device_pm_move_last(struct device *dev)
+{
+	pr_debug("PM: Moving %s:%s to end of list\n",
+		 dev->bus ? dev->bus->name : "No Bus",
+		 kobject_name(&dev->kobj));
+	list_move_tail(&dev->power.entry, &dpm_list);
+}
+
+/**
  *	pm_op - execute the PM operation appropiate for given PM event
  *	@dev:	Device.
  *	@ops:	PM operations to choose from.
@@ -305,12 +350,14 @@ static int resume_device_noirq(struct de
  *	Execute the appropriate "noirq resume" callback for all devices marked
  *	as DPM_OFF_IRQ.
  *
- *	Must be called with interrupts disabled and only one CPU running.
+ *	Must be called under dpm_list_mtx.  Device drivers should not receive
+ *	interrupts while it's being executed.
  */
 static void dpm_power_up(pm_message_t state)
 {
 	struct device *dev;
 
+	mutex_lock(&dpm_list_mtx);
 	list_for_each_entry(dev, &dpm_list, power.entry)
 		if (dev->power.status > DPM_OFF) {
 			int error;
@@ -320,20 +367,20 @@ static void dpm_power_up(pm_message_t st
 			if (error)
 				pm_dev_err(dev, state, " early", error);
 		}
+	mutex_unlock(&dpm_list_mtx);
 }
 
 /**
  *	device_power_up - Turn on all devices that need special attention.
  *	@state: PM transition of the system being carried out.
  *
- *	Power on system devices, then devices that required we shut them down
- *	with interrupts disabled.
- *
- *	Must be called with interrupts disabled.
+ *	Call the "early" resume handlers and enable device drivers to receive
+ *	interrupts.
  */
 void device_power_up(pm_message_t state)
 {
 	dpm_power_up(state);
+	resume_device_irqs();
 }
 EXPORT_SYMBOL_GPL(device_power_up);
 
@@ -558,16 +605,18 @@ static int suspend_device_noirq(struct d
  *	device_power_down - Shut down special devices.
  *	@state: PM transition of the system being carried out.
  *
- *	Power down devices that require interrupts to be disabled.
- *	Then power down system devices.
+ *	Prevent device drivers from receiving interrupts and call the "late"
+ *	suspend handlers.
  *
- *	Must be called with interrupts disabled and only one CPU running.
+ *	Must be called under dpm_list_mtx.
  */
 int device_power_down(pm_message_t state)
 {
 	struct device *dev;
 	int error = 0;
 
+	suspend_device_irqs();
+	mutex_lock(&dpm_list_mtx);
 	list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
 		error = suspend_device_noirq(dev, state);
 		if (error) {
@@ -576,8 +625,9 @@ int device_power_down(pm_message_t state
 		}
 		dev->power.status = DPM_OFF_IRQ;
 	}
+	mutex_unlock(&dpm_list_mtx);
 	if (error)
-		dpm_power_up(resume_event(state));
+		device_power_up(resume_event(state));
 	return error;
 }
 EXPORT_SYMBOL_GPL(device_power_down);
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/power/power.h linux-libre-2.6.30-gnu1/drivers/base/power/power.h
--- linux-libre-2.6.29-gnu1/drivers/base/power/power.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/power/power.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,11 +18,19 @@ static inline struct device *to_device(s
 
 extern void device_pm_add(struct device *);
 extern void device_pm_remove(struct device *);
+extern void device_pm_move_before(struct device *, struct device *);
+extern void device_pm_move_after(struct device *, struct device *);
+extern void device_pm_move_last(struct device *);
 
 #else /* CONFIG_PM_SLEEP */
 
 static inline void device_pm_add(struct device *dev) {}
 static inline void device_pm_remove(struct device *dev) {}
+static inline void device_pm_move_before(struct device *deva,
+					 struct device *devb) {}
+static inline void device_pm_move_after(struct device *deva,
+					struct device *devb) {}
+static inline void device_pm_move_last(struct device *dev) {}
 
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/sys.c linux-libre-2.6.30-gnu1/drivers/base/sys.c
--- linux-libre-2.6.29-gnu1/drivers/base/sys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/sys.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/pm.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/interrupt.h>
 
 #include "base.h"
 
@@ -30,10 +31,10 @@
 
 
 static ssize_t
-sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
 {
-	struct sys_device * sysdev = to_sysdev(kobj);
-	struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+	struct sys_device *sysdev = to_sysdev(kobj);
+	struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
 
 	if (sysdev_attr->show)
 		return sysdev_attr->show(sysdev, sysdev_attr, buffer);
@@ -42,11 +43,11 @@ sysdev_show(struct kobject * kobj, struc
 
 
 static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
-	     const char * buffer, size_t count)
+sysdev_store(struct kobject *kobj, struct attribute *attr,
+	     const char *buffer, size_t count)
 {
-	struct sys_device * sysdev = to_sysdev(kobj);
-	struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+	struct sys_device *sysdev = to_sysdev(kobj);
+	struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
 
 	if (sysdev_attr->store)
 		return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
@@ -63,13 +64,13 @@ static struct kobj_type ktype_sysdev = {
 };
 
 
-int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
+int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
 {
 	return sysfs_create_file(&s->kobj, &a->attr);
 }
 
 
-void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
+void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
 {
 	sysfs_remove_file(&s->kobj, &a->attr);
 }
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
 static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
 				 char *buffer)
 {
-	struct sysdev_class * class = to_sysdev_class(kobj);
+	struct sysdev_class *class = to_sysdev_class(kobj);
 	struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
 
 	if (class_attr->show)
@@ -95,8 +96,8 @@ static ssize_t sysdev_class_show(struct
 static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
 				  const char *buffer, size_t count)
 {
-	struct sysdev_class * class = to_sysdev_class(kobj);
-	struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
+	struct sysdev_class *class = to_sysdev_class(kobj);
+	struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
 
 	if (class_attr->store)
 		return class_attr->store(class, buffer, count);
@@ -128,7 +129,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_fi
 
 static struct kset *system_kset;
 
-int sysdev_class_register(struct sysdev_class * cls)
+int sysdev_class_register(struct sysdev_class *cls)
 {
 	pr_debug("Registering sysdev class '%s'\n", cls->name);
 
@@ -141,7 +142,7 @@ int sysdev_class_register(struct sysdev_
 	return kset_register(&cls->kset);
 }
 
-void sysdev_class_unregister(struct sysdev_class * cls)
+void sysdev_class_unregister(struct sysdev_class *cls)
 {
 	pr_debug("Unregistering sysdev class '%s'\n",
 		 kobject_name(&cls->kset.kobj));
@@ -203,8 +204,8 @@ int sysdev_driver_register(struct sysdev
  *	@cls:	Class driver belongs to.
  *	@drv:	Driver.
  */
-void sysdev_driver_unregister(struct sysdev_class * cls,
-			      struct sysdev_driver * drv)
+void sysdev_driver_unregister(struct sysdev_class *cls,
+			      struct sysdev_driver *drv)
 {
 	mutex_lock(&sysdev_drivers_lock);
 	list_del_init(&drv->entry);
@@ -229,10 +230,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregist
  *	@sysdev:	device in question
  *
  */
-int sysdev_register(struct sys_device * sysdev)
+int sysdev_register(struct sys_device *sysdev)
 {
 	int error;
-	struct sysdev_class * cls = sysdev->cls;
+	struct sysdev_class *cls = sysdev->cls;
 
 	if (!cls)
 		return -EINVAL;
@@ -252,7 +253,7 @@ int sysdev_register(struct sys_device *
 				     sysdev->id);
 
 	if (!error) {
-		struct sysdev_driver * drv;
+		struct sysdev_driver *drv;
 
 		pr_debug("Registering sys device '%s'\n",
 			 kobject_name(&sysdev->kobj));
@@ -274,9 +275,9 @@ int sysdev_register(struct sys_device *
 	return error;
 }
 
-void sysdev_unregister(struct sys_device * sysdev)
+void sysdev_unregister(struct sys_device *sysdev)
 {
-	struct sysdev_driver * drv;
+	struct sysdev_driver *drv;
 
 	mutex_lock(&sysdev_drivers_lock);
 	list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
@@ -299,25 +300,25 @@ void sysdev_unregister(struct sys_device
  *	and the class driver.
  *
  *	Note: The list is iterated in reverse order, so that we shut down
- *	child devices before we shut down thier parents. The list ordering
+ *	child devices before we shut down their parents. The list ordering
  *	is guaranteed by virtue of the fact that child devices are registered
  *	after their parents.
  */
 void sysdev_shutdown(void)
 {
-	struct sysdev_class * cls;
+	struct sysdev_class *cls;
 
 	pr_debug("Shutting Down System Devices\n");
 
 	mutex_lock(&sysdev_drivers_lock);
 	list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
-		struct sys_device * sysdev;
+		struct sys_device *sysdev;
 
 		pr_debug("Shutting down type '%s':\n",
 			 kobject_name(&cls->kset.kobj));
 
 		list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-			struct sysdev_driver * drv;
+			struct sysdev_driver *drv;
 			pr_debug(" %s\n", kobject_name(&sysdev->kobj));
 
 			/* Call auxillary drivers first */
@@ -364,11 +365,18 @@ static void __sysdev_resume(struct sys_d
  */
 int sysdev_suspend(pm_message_t state)
 {
-	struct sysdev_class * cls;
+	struct sysdev_class *cls;
 	struct sys_device *sysdev, *err_dev;
 	struct sysdev_driver *drv, *err_drv;
 	int ret;
 
+	pr_debug("Checking wake-up interrupts\n");
+
+	/* Return error code if there are any wake-up interrupts pending */
+	ret = check_wakeup_irqs();
+	if (ret)
+		return ret;
+
 	pr_debug("Suspending System Devices\n");
 
 	list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
@@ -442,12 +450,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend);
  */
 int sysdev_resume(void)
 {
-	struct sysdev_class * cls;
+	struct sysdev_class *cls;
 
 	pr_debug("Resuming System Devices\n");
 
 	list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
-		struct sys_device * sysdev;
+		struct sys_device *sysdev;
 
 		pr_debug("Resuming type '%s':\n",
 			 kobject_name(&cls->kset.kobj));
diff -druNp linux-libre-2.6.29-gnu1/drivers/base/topology.c linux-libre-2.6.30-gnu1/drivers/base/topology.c
--- linux-libre-2.6.29-gnu1/drivers/base/topology.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/base/topology.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,10 @@
 #include <linux/hardirq.h>
 #include <linux/topology.h>
 
-#define define_one_ro(_name) 		\
+#define define_one_ro_named(_name, _func)				\
+static SYSDEV_ATTR(_name, 0444, _func, NULL)
+
+#define define_one_ro(_name)				\
 static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
 
 #define define_id_show_func(name)				\
@@ -42,8 +45,8 @@ static ssize_t show_##name(struct sys_de
 	return sprintf(buf, "%d\n", topology_##name(cpu));	\
 }
 
-#if defined(topology_thread_siblings) || defined(topology_core_siblings)
-static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
+#if defined(topology_thread_cpumask) || defined(topology_core_cpumask)
+static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf)
 {
 	ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
 	int n = 0;
@@ -65,7 +68,7 @@ static ssize_t show_##name(struct sys_de
 			   struct sysdev_attribute *attr, char *buf)	\
 {									\
 	unsigned int cpu = dev->id;					\
-	return show_cpumap(0, &(topology_##name(cpu)), buf);		\
+	return show_cpumap(0, topology_##name(cpu), buf);		\
 }
 
 #define define_siblings_show_list(name)					\
@@ -74,7 +77,7 @@ static ssize_t show_##name##_list(struct
 				  char *buf)				\
 {									\
 	unsigned int cpu = dev->id;					\
-	return show_cpumap(1, &(topology_##name(cpu)), buf);		\
+	return show_cpumap(1, topology_##name(cpu), buf);		\
 }
 
 #else
@@ -82,9 +85,7 @@ static ssize_t show_##name##_list(struct
 static ssize_t show_##name(struct sys_device *dev,			\
 			   struct sysdev_attribute *attr, char *buf)	\
 {									\
-	unsigned int cpu = dev->id;					\
-	cpumask_t mask = topology_##name(cpu);				\
-	return show_cpumap(0, &mask, buf);				\
+	return show_cpumap(0, topology_##name(dev->id), buf);		\
 }
 
 #define define_siblings_show_list(name)					\
@@ -92,9 +93,7 @@ static ssize_t show_##name##_list(struct
 				  struct sysdev_attribute *attr,	\
 				  char *buf)				\
 {									\
-	unsigned int cpu = dev->id;					\
-	cpumask_t mask = topology_##name(cpu);				\
-	return show_cpumap(1, &mask, buf);				\
+	return show_cpumap(1, topology_##name(dev->id), buf);		\
 }
 #endif
 
@@ -107,13 +106,13 @@ define_one_ro(physical_package_id);
 define_id_show_func(core_id);
 define_one_ro(core_id);
 
-define_siblings_show_func(thread_siblings);
-define_one_ro(thread_siblings);
-define_one_ro(thread_siblings_list);
+define_siblings_show_func(thread_cpumask);
+define_one_ro_named(thread_siblings, show_thread_cpumask);
+define_one_ro_named(thread_siblings_list, show_thread_cpumask_list);
 
-define_siblings_show_func(core_siblings);
-define_one_ro(core_siblings);
-define_one_ro(core_siblings_list);
+define_siblings_show_func(core_cpumask);
+define_one_ro_named(core_siblings, show_core_cpumask);
+define_one_ro_named(core_siblings_list, show_core_cpumask_list);
 
 static struct attribute *default_attrs[] = {
 	&attr_physical_package_id.attr,
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/aoe/aoecmd.c linux-libre-2.6.30-gnu1/drivers/block/aoe/aoecmd.c
--- linux-libre-2.6.29-gnu1/drivers/block/aoe/aoecmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/aoe/aoecmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,7 @@
  * Filesystem request handling methods
  */
 
+#include <linux/ata.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/skbuff.h>
@@ -267,7 +268,7 @@ aoecmd_ata_rw(struct aoedev *d)
 		writebit = 0;
 	}
 
-	ah->cmdstat = WIN_READ | writebit | extbit;
+	ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
 
 	/* mark all tracking fields and load out */
 	buf->nframesout += 1;
@@ -362,10 +363,10 @@ resend(struct aoedev *d, struct aoetgt *
 	switch (ah->cmdstat) {
 	default:
 		break;
-	case WIN_READ:
-	case WIN_READ_EXT:
-	case WIN_WRITE:
-	case WIN_WRITE_EXT:
+	case ATA_CMD_PIO_READ:
+	case ATA_CMD_PIO_READ_EXT:
+	case ATA_CMD_PIO_WRITE:
+	case ATA_CMD_PIO_WRITE_EXT:
 		put_lba(ah, f->lba);
 
 		n = f->bcnt;
@@ -812,8 +813,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 			d->htgt = NULL;
 		n = ahout->scnt << 9;
 		switch (ahout->cmdstat) {
-		case WIN_READ:
-		case WIN_READ_EXT:
+		case ATA_CMD_PIO_READ:
+		case ATA_CMD_PIO_READ_EXT:
 			if (skb->len - sizeof *hin - sizeof *ahin < n) {
 				printk(KERN_ERR
 					"aoe: %s.  skb->len=%d need=%ld\n",
@@ -823,8 +824,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 				return;
 			}
 			memcpy(f->bufaddr, ahin+1, n);
-		case WIN_WRITE:
-		case WIN_WRITE_EXT:
+		case ATA_CMD_PIO_WRITE:
+		case ATA_CMD_PIO_WRITE_EXT:
 			ifp = getif(t, skb->dev);
 			if (ifp) {
 				ifp->lost = 0;
@@ -838,7 +839,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 				goto xmit;
 			}
 			break;
-		case WIN_IDENTIFY:
+		case ATA_CMD_ID_ATA:
 			if (skb->len - sizeof *hin - sizeof *ahin < 512) {
 				printk(KERN_INFO
 					"aoe: runt data size in ataid.  skb->len=%d\n",
@@ -914,7 +915,7 @@ aoecmd_ata_id(struct aoedev *d)
 
 	/* set up ata header */
 	ah->scnt = 1;
-	ah->cmdstat = WIN_IDENTIFY;
+	ah->cmdstat = ATA_CMD_ID_ATA;
 	ah->lba3 = 0xa0;
 
 	skb->dev = t->ifp->nd;
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/aoe/aoenet.c linux-libre-2.6.30-gnu1/drivers/block/aoe/aoenet.c
--- linux-libre-2.6.29-gnu1/drivers/block/aoe/aoenet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/aoe/aoenet.c	2009-06-09 23:05:27.000000000 -0400
@@ -151,7 +151,7 @@ exit:
 	return 0;
 }
 
-static struct packet_type aoe_pt = {
+static struct packet_type aoe_pt __read_mostly = {
 	.type = __constant_htons(ETH_P_AOE),
 	.func = aoenet_rcv,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/brd.c linux-libre-2.6.30-gnu1/drivers/block/brd.c
--- linux-libre-2.6.29-gnu1/drivers/block/brd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/brd.c	2009-06-09 23:05:27.000000000 -0400
@@ -275,8 +275,10 @@ static int brd_do_bvec(struct brd_device
 	if (rw == READ) {
 		copy_from_brd(mem + off, brd, sector, len);
 		flush_dcache_page(page);
-	} else
+	} else {
+		flush_dcache_page(page);
 		copy_to_brd(brd, mem + off, sector, len);
+	}
 	kunmap_atomic(mem, KM_USER0);
 
 out:
@@ -436,6 +438,7 @@ static struct brd_device *brd_alloc(int
 	if (!brd->brd_queue)
 		goto out_free_dev;
 	blk_queue_make_request(brd->brd_queue, brd_make_request);
+	blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL);
 	blk_queue_max_sectors(brd->brd_queue, 1024);
 	blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/cciss.c linux-libre-2.6.30-gnu1/drivers/block/cciss.c
--- linux-libre-2.6.29-gnu1/drivers/block/cciss.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/cciss.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,7 @@
 #include <scsi/scsi_ioctl.h>
 #include <linux/cdrom.h>
 #include <linux/scatterlist.h>
+#include <linux/kthread.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 #define DRIVER_NAME "HP CISS Driver (v 3.6.20)"
@@ -186,6 +187,8 @@ static int sendcmd_withirq(__u8 cmd, int
 			   __u8 page_code, int cmd_type);
 
 static void fail_all_cmds(unsigned long ctlr);
+static int scan_thread(void *data);
+static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
 
 #ifdef CONFIG_PROC_FS
 static void cciss_procinit(int i);
@@ -735,6 +738,12 @@ static int cciss_getgeo(struct block_dev
 	return 0;
 }
 
+static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c)
+{
+	if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+			c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
+		(void)check_for_unit_attention(host, c);
+}
 /*
  * ioctl
  */
@@ -1029,6 +1038,8 @@ static int cciss_ioctl(struct block_devi
 					 iocommand.buf_size,
 					 PCI_DMA_BIDIRECTIONAL);
 
+			check_ioctl_unit_attention(host, c);
+
 			/* Copy the error information out */
 			iocommand.error_info = *(c->err_info);
 			if (copy_to_user
@@ -1180,6 +1191,7 @@ static int cciss_ioctl(struct block_devi
 					(dma_addr_t) temp64.val, buff_size[i],
 					PCI_DMA_BIDIRECTIONAL);
 			}
+			check_ioctl_unit_attention(host, c);
 			/* Copy the error information out */
 			ioc->error_info = *(c->err_info);
 			if (copy_to_user(argp, ioc, sizeof(*ioc))) {
@@ -1287,6 +1299,7 @@ static void cciss_softirq_done(struct re
 {
 	CommandList_struct *cmd = rq->completion_data;
 	ctlr_info_t *h = hba[cmd->ctlr];
+	unsigned int nr_bytes;
 	unsigned long flags;
 	u64bit temp64;
 	int i, ddir;
@@ -1308,7 +1321,14 @@ static void cciss_softirq_done(struct re
 	printk("Done with %p\n", rq);
 #endif				/* CCISS_DEBUG */
 
-	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
+	/*
+	 * Store the full size and set the residual count for pc requests
+	 */
+	nr_bytes = blk_rq_bytes(rq);
+	if (blk_pc_request(rq))
+		rq->data_len = cmd->err_info->ResidualCnt;
+
+	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes))
 		BUG();
 
 	spin_lock_irqsave(&h->lock, flags);
@@ -2585,12 +2605,14 @@ static inline unsigned int make_status_b
 		((driver_byte & 0xff) << 24);
 }
 
-static inline int evaluate_target_status(CommandList_struct *cmd)
+static inline int evaluate_target_status(ctlr_info_t *h,
+			CommandList_struct *cmd, int *retry_cmd)
 {
 	unsigned char sense_key;
 	unsigned char status_byte, msg_byte, host_byte, driver_byte;
 	int error_value;
 
+	*retry_cmd = 0;
 	/* If we get in here, it means we got "target status", that is, scsi status */
 	status_byte = cmd->err_info->ScsiStatus;
 	driver_byte = DRIVER_OK;
@@ -2618,6 +2640,11 @@ static inline int evaluate_target_status
 	if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq))
 		error_value = 0;
 
+	if (check_for_unit_attention(h, cmd)) {
+		*retry_cmd = !blk_pc_request(cmd->rq);
+		return 0;
+	}
+
 	if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
 		if (error_value != 0)
 			printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
@@ -2657,7 +2684,7 @@ static inline void complete_command(ctlr
 
 	switch (cmd->err_info->CommandStatus) {
 	case CMD_TARGET_STATUS:
-		rq->errors = evaluate_target_status(cmd);
+		rq->errors = evaluate_target_status(h, cmd, &retry_cmd);
 		break;
 	case CMD_DATA_UNDERRUN:
 		if (blk_fs_request(cmd->rq)) {
@@ -3008,6 +3035,63 @@ static irqreturn_t do_cciss_intr(int irq
 	return IRQ_HANDLED;
 }
 
+static int scan_thread(void *data)
+{
+	ctlr_info_t *h = data;
+	int rc;
+	DECLARE_COMPLETION_ONSTACK(wait);
+	h->rescan_wait = &wait;
+
+	for (;;) {
+		rc = wait_for_completion_interruptible(&wait);
+		if (kthread_should_stop())
+			break;
+		if (!rc)
+			rebuild_lun_table(h, 0);
+	}
+	return 0;
+}
+
+static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
+{
+	if (c->err_info->SenseInfo[2] != UNIT_ATTENTION)
+		return 0;
+
+	switch (c->err_info->SenseInfo[12]) {
+	case STATE_CHANGED:
+		printk(KERN_WARNING "cciss%d: a state change "
+			"detected, command retried\n", h->ctlr);
+		return 1;
+	break;
+	case LUN_FAILED:
+		printk(KERN_WARNING "cciss%d: LUN failure "
+			"detected, action required\n", h->ctlr);
+		return 1;
+	break;
+	case REPORT_LUNS_CHANGED:
+		printk(KERN_WARNING "cciss%d: report LUN data "
+			"changed\n", h->ctlr);
+		if (h->rescan_wait)
+			complete(h->rescan_wait);
+		return 1;
+	break;
+	case POWER_OR_RESET:
+		printk(KERN_WARNING "cciss%d: a power on "
+			"or device reset detected\n", h->ctlr);
+		return 1;
+	break;
+	case UNIT_ATTENTION_CLEARED:
+		printk(KERN_WARNING "cciss%d: unit attention "
+		    "cleared by another initiator\n", h->ctlr);
+		return 1;
+	break;
+	default:
+		printk(KERN_WARNING "cciss%d: unknown "
+			"unit attention detected\n", h->ctlr);
+				return 1;
+	}
+}
+
 /*
  *  We cannot read the structure directly, for portability we must use
  *   the io functions.
@@ -3181,12 +3265,21 @@ static int __devinit cciss_pci_init(ctlr
  */
 	cciss_interrupt_mode(c, pdev, board_id);
 
-	/*
-	 * Memory base addr is first addr , the second points to the config
-	 *   table
-	 */
+	/* 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) {
+		printk(KERN_WARNING "cciss: No memory BAR found\n");
+		err = -ENODEV;
+		goto err_out_free_res;
+	}
+
+	c->paddr = pci_resource_start(pdev, i); /* addressing mode bits
+						 * already removed
+						 */
 
-	c->paddr = pci_resource_start(pdev, 0);	/* addressing mode bits already removed */
 #ifdef CCISS_DEBUG
 	printk("address 0 = %lx\n", c->paddr);
 #endif				/* CCISS_DEBUG */
@@ -3412,7 +3505,7 @@ static __devinit int cciss_message(struc
 	/* 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_32BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		iounmap(vaddr);
 		return -ENOMEM;
@@ -3637,9 +3730,9 @@ static int __devinit cciss_init_one(stru
 	hba[i]->pdev = pdev;
 
 	/* configure PCI DMA stuff */
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
 		dac = 1;
-	else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+	else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
 		dac = 0;
 	else {
 		printk(KERN_ERR "cciss: no suitable DMA available\n");
@@ -3753,6 +3846,11 @@ static int __devinit cciss_init_one(stru
 	hba[i]->busy_initializing = 0;
 
 	rebuild_lun_table(hba[i], 1);
+	hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
+				"cciss_scan%02d", i);
+	if (IS_ERR(hba[i]->cciss_scan_thread))
+		return PTR_ERR(hba[i]->cciss_scan_thread);
+
 	return 1;
 
 clean4:
@@ -3828,6 +3926,7 @@ static void __devexit cciss_remove_one(s
 		printk(KERN_ERR "cciss: Unable to remove device \n");
 		return;
 	}
+
 	tmp_ptr = pci_get_drvdata(pdev);
 	i = tmp_ptr->ctlr;
 	if (hba[i] == NULL) {
@@ -3836,6 +3935,8 @@ static void __devexit cciss_remove_one(s
 		return;
 	}
 
+	kthread_stop(hba[i]->cciss_scan_thread);
+
 	remove_proc_entry(hba[i]->devname, proc_cciss);
 	unregister_blkdev(hba[i]->major, hba[i]->devname);
 
@@ -3898,6 +3999,13 @@ static struct pci_driver cciss_pci_drive
  */
 static int __init cciss_init(void)
 {
+	/*
+	 * The hardware requires that commands are aligned on a 64-bit
+	 * boundary. Given that we use pci_alloc_consistent() to allocate an
+	 * array of them, the size must be a multiple of 8 bytes.
+	 */
+	BUILD_BUG_ON(sizeof(CommandList_struct) % 8);
+
 	printk(KERN_INFO DRIVER_NAME "\n");
 
 	/* Register for our PCI devices */
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/cciss_cmd.h linux-libre-2.6.30-gnu1/drivers/block/cciss_cmd.h
--- linux-libre-2.6.29-gnu1/drivers/block/cciss_cmd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/cciss_cmd.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,29 @@
 #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
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/cciss.h linux-libre-2.6.30-gnu1/drivers/block/cciss.h
--- linux-libre-2.6.29-gnu1/drivers/block/cciss.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/cciss.h	2009-06-09 23:05:27.000000000 -0400
@@ -121,6 +121,8 @@ struct ctlr_info
 	struct sendcmd_reject_list scsi_rejects;
 #endif
 	unsigned char alive;
+	struct completion *rescan_wait;
+	struct task_struct *cciss_scan_thread;
 };
 
 /*  Defining the diffent access_menthods */
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/cpqarray.c linux-libre-2.6.30-gnu1/drivers/block/cpqarray.c
--- linux-libre-2.6.29-gnu1/drivers/block/cpqarray.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/cpqarray.c	2009-06-09 23:05:27.000000000 -0400
@@ -617,6 +617,7 @@ static int cpqarray_pci_init(ctlr_info_t
 	int i;
 
 	c->pci_dev = pdev;
+	pci_set_master(pdev);
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n");
 		return -1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/DAC960.c linux-libre-2.6.30-gnu1/drivers/block/DAC960.c
--- linux-libre-2.6.29-gnu1/drivers/block/DAC960.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/DAC960.c	2009-06-09 23:05:27.000000000 -0400
@@ -1169,9 +1169,9 @@ static bool DAC960_V1_EnableMemoryMailbo
   int i;
 
   
-  if (pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
+  if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
 	return DAC960_Failure(Controller, "DMA mask out of range");
-  Controller->BounceBufferLimit = DMA_32BIT_MASK;
+  Controller->BounceBufferLimit = DMA_BIT_MASK(32);
 
   if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) {
     CommandMailboxesSize =  0;
@@ -1372,10 +1372,10 @@ static bool DAC960_V2_EnableMemoryMailbo
   dma_addr_t	CommandMailboxDMA;
   DAC960_V2_CommandStatus_T CommandStatus;
 
-	if (!pci_set_dma_mask(Controller->PCIDevice, DMA_64BIT_MASK))
-		Controller->BounceBufferLimit = DMA_64BIT_MASK;
-	else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_32BIT_MASK))
-		Controller->BounceBufferLimit = DMA_32BIT_MASK;
+	if (!pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(64)))
+		Controller->BounceBufferLimit = DMA_BIT_MASK(64);
+	else if (!pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
+		Controller->BounceBufferLimit = DMA_BIT_MASK(32);
 	else
 		return DAC960_Failure(Controller, "DMA mask out of range");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/floppy.c linux-libre-2.6.30-gnu1/drivers/block/floppy.c
--- linux-libre-2.6.29-gnu1/drivers/block/floppy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/floppy.c	2009-06-09 23:05:27.000000000 -0400
@@ -177,6 +177,7 @@ static int print_unex = 1;
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
 #include <linux/buffer_head.h>	/* for invalidate_buffers() */
 #include <linux/mutex.h>
 
@@ -4135,10 +4136,9 @@ static int have_no_fdc = -ENODEV;
 static ssize_t floppy_cmos_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	struct platform_device *p;
+	struct platform_device *p = to_platform_device(dev);
 	int drive;
 
-	p = container_of(dev, struct platform_device,dev);
 	drive = p->id;
 	return sprintf(buf, "%X\n", UDP->cmos);
 }
@@ -4598,6 +4598,13 @@ MODULE_AUTHOR("Alain L. Knaff");
 MODULE_SUPPORTED_DEVICE("fd");
 MODULE_LICENSE("GPL");
 
+/* This doesn't actually get used other than for module information */
+static const struct pnp_device_id floppy_pnpids[] = {
+	{ "PNP0700", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
+
 #else
 
 __setup("floppy=", floppy_setup);
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/hd.c linux-libre-2.6.30-gnu1/drivers/block/hd.c
--- linux-libre-2.6.29-gnu1/drivers/block/hd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/hd.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,8 @@
 #include <linux/ata.h>
 #include <linux/hdreg.h>
 
+#define HD_IRQ 14
+
 #define REALLY_SLOW_IO
 #include <asm/system.h>
 #include <asm/io.h>
@@ -507,7 +509,6 @@ ok_to_write:
 	if (i > 0) {
 		SET_HANDLER(&write_intr);
 		outsw(HD_DATA, req->buffer, 256);
-		local_irq_enable();
 	} else {
 #if (HD_DELAY > 0)
 		last_req = read_timer();
@@ -539,8 +540,7 @@ static void hd_times_out(unsigned long d
 	if (!CURRENT)
 		return;
 
-	disable_irq(HD_IRQ);
-	local_irq_enable();
+	spin_lock_irq(hd_queue->queue_lock);
 	reset = 1;
 	name = CURRENT->rq_disk->disk_name;
 	printk("%s: timeout\n", name);
@@ -550,9 +550,8 @@ static void hd_times_out(unsigned long d
 #endif
 		end_request(CURRENT, 0);
 	}
-	local_irq_disable();
 	hd_request();
-	enable_irq(HD_IRQ);
+	spin_unlock_irq(hd_queue->queue_lock);
 }
 
 static int do_special_op(struct hd_i_struct *disk, struct request *req)
@@ -590,7 +589,6 @@ static void hd_request(void)
 		return;
 repeat:
 	del_timer(&device_timer);
-	local_irq_enable();
 
 	req = CURRENT;
 	if (!req) {
@@ -599,7 +597,6 @@ repeat:
 	}
 
 	if (reset) {
-		local_irq_disable();
 		reset_hd();
 		return;
 	}
@@ -658,9 +655,7 @@ repeat:
 
 static void do_hd_request(struct request_queue *q)
 {
-	disable_irq(HD_IRQ);
 	hd_request();
-	enable_irq(HD_IRQ);
 }
 
 static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -682,12 +677,16 @@ static irqreturn_t hd_interrupt(int irq,
 {
 	void (*handler)(void) = do_hd;
 
+	spin_lock(hd_queue->queue_lock);
+
 	do_hd = NULL;
 	del_timer(&device_timer);
 	if (!handler)
 		handler = unexpected_hd_interrupt;
 	handler();
-	local_irq_enable();
+
+	spin_unlock(hd_queue->queue_lock);
+
 	return IRQ_HANDLED;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/Kconfig linux-libre-2.6.30-gnu1/drivers/block/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/block/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -45,6 +45,13 @@ config MAC_FLOPPY
 	  If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
 	  floppy controller, say Y here. Most commonly found in PowerMacs.
 
+config BLK_DEV_SWIM
+	tristate "Support for SWIM Macintosh floppy"
+	depends on M68K && MAC
+	help
+	  You should select this option if you want floppy support
+	  and you don't have a II, IIfx, Q900, Q950 or AV series.
+
 config AMIGA_Z2RAM
 	tristate "Amiga Zorro II ramdisk support"
 	depends on ZORRO
@@ -403,6 +410,23 @@ config ATA_OVER_ETH
 	This driver provides Support for ATA over Ethernet block
 	devices like the Coraid EtherDrive (R) Storage Blade.
 
+config MG_DISK
+	tristate "mGine mflash, gflash support"
+	depends on ARM && ATA && GPIOLIB
+	help
+	  mGine mFlash(gFlash) block device driver
+
+config MG_DISK_RES
+	int "Size of reserved area before MBR"
+	depends on MG_DISK
+	default 0
+	help
+	  Define size of reserved area that usually used for boot. Unit is KB.
+	  All of the block device operation will be taken this value as start
+	  offset
+	  Examples:
+			1024 => 1 MB
+
 config SUNVDC
 	tristate "Sun Virtual Disk Client support"
 	depends on SUN_LDOMS
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/loop.c linux-libre-2.6.30-gnu1/drivers/block/loop.c
--- linux-libre-2.6.29-gnu1/drivers/block/loop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/loop.c	2009-06-09 23:05:27.000000000 -0400
@@ -474,10 +474,35 @@ static int do_bio_filebacked(struct loop
 	int ret;
 
 	pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
-	if (bio_rw(bio) == WRITE)
+
+	if (bio_rw(bio) == WRITE) {
+		int barrier = bio_barrier(bio);
+		struct file *file = lo->lo_backing_file;
+
+		if (barrier) {
+			if (unlikely(!file->f_op->fsync)) {
+				ret = -EOPNOTSUPP;
+				goto out;
+			}
+
+			ret = vfs_fsync(file, file->f_path.dentry, 0);
+			if (unlikely(ret)) {
+				ret = -EIO;
+				goto out;
+			}
+		}
+
 		ret = lo_send(lo, bio, pos);
-	else
+
+		if (barrier && !ret) {
+			ret = vfs_fsync(file, file->f_path.dentry, 0);
+			if (unlikely(ret))
+				ret = -EIO;
+		}
+	} else
 		ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
+
+out:
 	return ret;
 }
 
@@ -826,6 +851,9 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_queue->queuedata = lo;
 	lo->lo_queue->unplug_fn = loop_unplug;
 
+	if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
+		blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);
+
 	set_capacity(lo->lo_disk, size);
 	bd_set_size(bdev, size << 9);
 
@@ -941,11 +969,18 @@ static int loop_clr_fd(struct loop_devic
 		bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(filp->f_mapping, gfp);
 	lo->lo_state = Lo_unbound;
-	fput(filp);
 	/* This is safe: open() is still holding a reference. */
 	module_put(THIS_MODULE);
 	if (max_part > 0)
 		ioctl_by_bdev(bdev, BLKRRPART, 0);
+	mutex_unlock(&lo->lo_ctl_mutex);
+	/*
+	 * Need not hold lo_ctl_mutex to fput backing file.
+	 * Calling fput holding lo_ctl_mutex triggers a circular
+	 * lock dependency possibility warning as fput can take
+	 * bd_mutex which is usually taken before lo_ctl_mutex.
+	 */
+	fput(filp);
 	return 0;
 }
 
@@ -1157,13 +1192,37 @@ loop_get_status64(struct loop_device *lo
 	return err;
 }
 
+static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
+{
+	int err;
+	sector_t sec;
+	loff_t sz;
+
+	err = -ENXIO;
+	if (unlikely(lo->lo_state != Lo_bound))
+		goto out;
+	err = figure_loop_size(lo);
+	if (unlikely(err))
+		goto out;
+	sec = get_capacity(lo->lo_disk);
+	/* the width of sector_t may be narrow for bit-shift */
+	sz = sec;
+	sz <<= 9;
+	mutex_lock(&bdev->bd_mutex);
+	bd_set_size(bdev, sz);
+	mutex_unlock(&bdev->bd_mutex);
+
+ out:
+	return err;
+}
+
 static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 	unsigned int cmd, unsigned long arg)
 {
 	struct loop_device *lo = bdev->bd_disk->private_data;
 	int err;
 
-	mutex_lock(&lo->lo_ctl_mutex);
+	mutex_lock_nested(&lo->lo_ctl_mutex, 1);
 	switch (cmd) {
 	case LOOP_SET_FD:
 		err = loop_set_fd(lo, mode, bdev, arg);
@@ -1172,7 +1231,10 @@ static int lo_ioctl(struct block_device
 		err = loop_change_fd(lo, bdev, arg);
 		break;
 	case LOOP_CLR_FD:
+		/* loop_clr_fd would have unlocked lo_ctl_mutex on success */
 		err = loop_clr_fd(lo, bdev);
+		if (!err)
+			goto out_unlocked;
 		break;
 	case LOOP_SET_STATUS:
 		err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1186,10 +1248,17 @@ static int lo_ioctl(struct block_device
 	case LOOP_GET_STATUS64:
 		err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
 		break;
+	case LOOP_SET_CAPACITY:
+		err = -EPERM;
+		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+			err = loop_set_capacity(lo, bdev);
+		break;
 	default:
 		err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
 	}
 	mutex_unlock(&lo->lo_ctl_mutex);
+
+out_unlocked:
 	return err;
 }
 
@@ -1331,6 +1400,7 @@ static int lo_compat_ioctl(struct block_
 			lo, (struct compat_loop_info __user *) arg);
 		mutex_unlock(&lo->lo_ctl_mutex);
 		break;
+	case LOOP_SET_CAPACITY:
 	case LOOP_CLR_FD:
 	case LOOP_GET_STATUS64:
 	case LOOP_SET_STATUS64:
@@ -1361,6 +1431,7 @@ static int lo_open(struct block_device *
 static int lo_release(struct gendisk *disk, fmode_t mode)
 {
 	struct loop_device *lo = disk->private_data;
+	int err;
 
 	mutex_lock(&lo->lo_ctl_mutex);
 
@@ -1372,7 +1443,9 @@ static int lo_release(struct gendisk *di
 		 * In autoclear mode, stop the loop thread
 		 * and remove configuration after last close.
 		 */
-		loop_clr_fd(lo, NULL);
+		err = loop_clr_fd(lo, NULL);
+		if (!err)
+			goto out_unlocked;
 	} else {
 		/*
 		 * Otherwise keep thread (if running) and config,
@@ -1383,7 +1456,7 @@ static int lo_release(struct gendisk *di
 
 out:
 	mutex_unlock(&lo->lo_ctl_mutex);
-
+out_unlocked:
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/Makefile linux-libre-2.6.30-gnu1/drivers/block/Makefile
--- linux-libre-2.6.29-gnu1/drivers/block/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@
 # 
 
 obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
+obj-$(CONFIG_BLK_DEV_SWIM)	+= swim_mod.o
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
 obj-$(CONFIG_PS3_DISK)		+= ps3disk.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_BLK_CPQ_CISS_DA)  += cciss.
 obj-$(CONFIG_BLK_DEV_DAC960)	+= DAC960.o
 obj-$(CONFIG_XILINX_SYSACE)	+= xsysace.o
 obj-$(CONFIG_CDROM_PKTCDVD)	+= pktcdvd.o
+obj-$(CONFIG_MG_DISK)		+= mg_disk.o
 obj-$(CONFIG_SUNVDC)		+= sunvdc.o
 
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
@@ -33,3 +35,5 @@ obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 obj-$(CONFIG_BLK_DEV_HD)	+= hd.o
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
+
+swim_mod-objs	:= swim.o swim_asm.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/mg_disk.c linux-libre-2.6.30-gnu1/drivers/block/mg_disk.c
--- linux-libre-2.6.29-gnu1/drivers/block/mg_disk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/block/mg_disk.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1014 @@
+/*
+ *  drivers/block/mg_disk.c
+ *
+ *  Support for the mGine m[g]flash IO mode.
+ *  Based on legacy hd.c
+ *
+ * (c) 2008 mGine Co.,LTD
+ * (c) 2008 unsik Kim <donari75@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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/libata.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mg_disk.h>
+
+#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
+
+static void mg_request(struct request_queue *);
+
+static void mg_dump_status(const char *msg, unsigned int stat,
+		struct mg_host *host)
+{
+	char *name = MG_DISK_NAME;
+	struct request *req;
+
+	if (host->breq) {
+		req = elv_next_request(host->breq);
+		if (req)
+			name = req->rq_disk->disk_name;
+	}
+
+	printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
+	if (stat & MG_REG_STATUS_BIT_BUSY)
+		printk("Busy ");
+	if (stat & MG_REG_STATUS_BIT_READY)
+		printk("DriveReady ");
+	if (stat & MG_REG_STATUS_BIT_WRITE_FAULT)
+		printk("WriteFault ");
+	if (stat & MG_REG_STATUS_BIT_SEEK_DONE)
+		printk("SeekComplete ");
+	if (stat & MG_REG_STATUS_BIT_DATA_REQ)
+		printk("DataRequest ");
+	if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR)
+		printk("CorrectedError ");
+	if (stat & MG_REG_STATUS_BIT_ERROR)
+		printk("Error ");
+	printk("}\n");
+	if ((stat & MG_REG_STATUS_BIT_ERROR) == 0) {
+		host->error = 0;
+	} else {
+		host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR);
+		printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg,
+				host->error & 0xff);
+		if (host->error & MG_REG_ERR_BBK)
+			printk("BadSector ");
+		if (host->error & MG_REG_ERR_UNC)
+			printk("UncorrectableError ");
+		if (host->error & MG_REG_ERR_IDNF)
+			printk("SectorIdNotFound ");
+		if (host->error & MG_REG_ERR_ABRT)
+			printk("DriveStatusError ");
+		if (host->error & MG_REG_ERR_AMNF)
+			printk("AddrMarkNotFound ");
+		printk("}");
+		if (host->error &
+				(MG_REG_ERR_BBK | MG_REG_ERR_UNC |
+				 MG_REG_ERR_IDNF | MG_REG_ERR_AMNF)) {
+			if (host->breq) {
+				req = elv_next_request(host->breq);
+				if (req)
+					printk(", sector=%u", (u32)req->sector);
+			}
+
+		}
+		printk("\n");
+	}
+}
+
+static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
+{
+	u8 status;
+	unsigned long expire, cur_jiffies;
+	struct mg_drv_data *prv_data = host->dev->platform_data;
+
+	host->error = MG_ERR_NONE;
+	expire = jiffies + msecs_to_jiffies(msec);
+
+	status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+
+	do {
+		cur_jiffies = jiffies;
+		if (status & MG_REG_STATUS_BIT_BUSY) {
+			if (expect == MG_REG_STATUS_BIT_BUSY)
+				break;
+		} else {
+			/* Check the error condition! */
+			if (status & MG_REG_STATUS_BIT_ERROR) {
+				mg_dump_status("mg_wait", status, host);
+				break;
+			}
+
+			if (expect == MG_STAT_READY)
+				if (MG_READY_OK(status))
+					break;
+
+			if (expect == MG_REG_STATUS_BIT_DATA_REQ)
+				if (status & MG_REG_STATUS_BIT_DATA_REQ)
+					break;
+		}
+		if (!msec) {
+			mg_dump_status("not ready", status, host);
+			return MG_ERR_INV_STAT;
+		}
+		if (prv_data->use_polling)
+			msleep(1);
+
+		status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+	} while (time_before(cur_jiffies, expire));
+
+	if (time_after_eq(cur_jiffies, expire) && msec)
+		host->error = MG_ERR_TIMEOUT;
+
+	return host->error;
+}
+
+static unsigned int mg_wait_rstout(u32 rstout, u32 msec)
+{
+	unsigned long expire;
+
+	expire = jiffies + msecs_to_jiffies(msec);
+	while (time_before(jiffies, expire)) {
+		if (gpio_get_value(rstout) == 1)
+			return MG_ERR_NONE;
+		msleep(10);
+	}
+
+	return MG_ERR_RSTOUT;
+}
+
+static void mg_unexpected_intr(struct mg_host *host)
+{
+	u32 status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+
+	mg_dump_status("mg_unexpected_intr", status, host);
+}
+
+static irqreturn_t mg_irq(int irq, void *dev_id)
+{
+	struct mg_host *host = dev_id;
+	void (*handler)(struct mg_host *) = host->mg_do_intr;
+
+	spin_lock(&host->lock);
+
+	host->mg_do_intr = NULL;
+	del_timer(&host->timer);
+	if (!handler)
+		handler = mg_unexpected_intr;
+	handler(host);
+
+	spin_unlock(&host->lock);
+
+	return IRQ_HANDLED;
+}
+
+static int mg_get_disk_id(struct mg_host *host)
+{
+	u32 i;
+	s32 err;
+	const u16 *id = host->id;
+	struct mg_drv_data *prv_data = host->dev->platform_data;
+	char fwrev[ATA_ID_FW_REV_LEN + 1];
+	char model[ATA_ID_PROD_LEN + 1];
+	char serial[ATA_ID_SERNO_LEN + 1];
+
+	if (!prv_data->use_polling)
+		outb(MG_REG_CTRL_INTR_DISABLE,
+				(unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+
+	outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND);
+	err = mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_RD_DRQ);
+	if (err)
+		return err;
+
+	for (i = 0; i < (MG_SECTOR_SIZE >> 1); i++)
+		host->id[i] = le16_to_cpu(inw((unsigned long)host->dev_base +
+					MG_BUFF_OFFSET + i * 2));
+
+	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+	err = mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD);
+	if (err)
+		return err;
+
+	if ((id[ATA_ID_FIELD_VALID] & 1) == 0)
+		return MG_ERR_TRANSLATION;
+
+	host->n_sectors = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
+	host->cyls = id[ATA_ID_CYLS];
+	host->heads = id[ATA_ID_HEADS];
+	host->sectors = id[ATA_ID_SECTORS];
+
+	if (MG_RES_SEC && host->heads && host->sectors) {
+		/* modify cyls, n_sectors */
+		host->cyls = (host->n_sectors - MG_RES_SEC) /
+			host->heads / host->sectors;
+		host->nres_sectors = host->n_sectors - host->cyls *
+			host->heads * host->sectors;
+		host->n_sectors -= host->nres_sectors;
+	}
+
+	ata_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev));
+	ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
+	ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+	printk(KERN_INFO "mg_disk: model: %s\n", model);
+	printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev);
+	printk(KERN_INFO "mg_disk: serial: %s\n", serial);
+	printk(KERN_INFO "mg_disk: %d + reserved %d sectors\n",
+			host->n_sectors, host->nres_sectors);
+
+	if (!prv_data->use_polling)
+		outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+
+	return err;
+}
+
+
+static int mg_disk_init(struct mg_host *host)
+{
+	struct mg_drv_data *prv_data = host->dev->platform_data;
+	s32 err;
+	u8 init_status;
+
+	/* hdd rst low */
+	gpio_set_value(host->rst, 0);
+	err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+	if (err)
+		return err;
+
+	/* hdd rst high */
+	gpio_set_value(host->rst, 1);
+	err = mg_wait(host, MG_STAT_READY, MG_TMAX_HDRST_TO_RDY);
+	if (err)
+		return err;
+
+	/* soft reset on */
+	outb(MG_REG_CTRL_RESET |
+			(prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
+			 MG_REG_CTRL_INTR_ENABLE),
+			(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
+	err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY);
+	if (err)
+		return err;
+
+	/* soft reset off */
+	outb(prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE :
+			MG_REG_CTRL_INTR_ENABLE,
+			(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
+	err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY);
+	if (err)
+		return err;
+
+	init_status = inb((unsigned long)host->dev_base + MG_REG_STATUS) & 0xf;
+
+	if (init_status == 0xf)
+		return MG_ERR_INIT_STAT;
+
+	return err;
+}
+
+static void mg_bad_rw_intr(struct mg_host *host)
+{
+	struct request *req = elv_next_request(host->breq);
+	if (req != NULL)
+		if (++req->errors >= MG_MAX_ERRORS ||
+				host->error == MG_ERR_TIMEOUT)
+			end_request(req, 0);
+}
+
+static unsigned int mg_out(struct mg_host *host,
+		unsigned int sect_num,
+		unsigned int sect_cnt,
+		unsigned int cmd,
+		void (*intr_addr)(struct mg_host *))
+{
+	struct mg_drv_data *prv_data = host->dev->platform_data;
+
+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+		return host->error;
+
+	if (!prv_data->use_polling) {
+		host->mg_do_intr = intr_addr;
+		mod_timer(&host->timer, jiffies + 3 * HZ);
+	}
+	if (MG_RES_SEC)
+		sect_num += MG_RES_SEC;
+	outb((u8)sect_cnt, (unsigned long)host->dev_base + MG_REG_SECT_CNT);
+	outb((u8)sect_num, (unsigned long)host->dev_base + MG_REG_SECT_NUM);
+	outb((u8)(sect_num >> 8), (unsigned long)host->dev_base +
+			MG_REG_CYL_LOW);
+	outb((u8)(sect_num >> 16), (unsigned long)host->dev_base +
+			MG_REG_CYL_HIGH);
+	outb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE),
+			(unsigned long)host->dev_base + MG_REG_DRV_HEAD);
+	outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND);
+	return MG_ERR_NONE;
+}
+
+static void mg_read(struct request *req)
+{
+	u32 remains, j;
+	struct mg_host *host = req->rq_disk->private_data;
+
+	remains = req->nr_sectors;
+
+	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
+			MG_ERR_NONE)
+		mg_bad_rw_intr(host);
+
+	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
+			remains, req->sector, req->buffer);
+
+	while (remains) {
+		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
+					MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
+			mg_bad_rw_intr(host);
+			return;
+		}
+		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
+			*(u16 *)req->buffer =
+				inw((unsigned long)host->dev_base +
+						MG_BUFF_OFFSET + (j << 1));
+			req->buffer += 2;
+		}
+
+		req->sector++;
+		req->errors = 0;
+		remains = --req->nr_sectors;
+		--req->current_nr_sectors;
+
+		if (req->current_nr_sectors <= 0) {
+			MG_DBG("remain : %d sects\n", remains);
+			end_request(req, 1);
+			if (remains > 0)
+				req = elv_next_request(host->breq);
+		}
+
+		outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
+				MG_REG_COMMAND);
+	}
+}
+
+static void mg_write(struct request *req)
+{
+	u32 remains, j;
+	struct mg_host *host = req->rq_disk->private_data;
+
+	remains = req->nr_sectors;
+
+	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
+			MG_ERR_NONE) {
+		mg_bad_rw_intr(host);
+		return;
+	}
+
+
+	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
+			remains, req->sector, req->buffer);
+	while (remains) {
+		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
+					MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
+			mg_bad_rw_intr(host);
+			return;
+		}
+		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
+			outw(*(u16 *)req->buffer,
+					(unsigned long)host->dev_base +
+					MG_BUFF_OFFSET + (j << 1));
+			req->buffer += 2;
+		}
+		req->sector++;
+		remains = --req->nr_sectors;
+		--req->current_nr_sectors;
+
+		if (req->current_nr_sectors <= 0) {
+			MG_DBG("remain : %d sects\n", remains);
+			end_request(req, 1);
+			if (remains > 0)
+				req = elv_next_request(host->breq);
+		}
+
+		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
+				MG_REG_COMMAND);
+	}
+}
+
+static void mg_read_intr(struct mg_host *host)
+{
+	u32 i;
+	struct request *req;
+
+	/* check status */
+	do {
+		i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+		if (i & MG_REG_STATUS_BIT_BUSY)
+			break;
+		if (!MG_READY_OK(i))
+			break;
+		if (i & MG_REG_STATUS_BIT_DATA_REQ)
+			goto ok_to_read;
+	} while (0);
+	mg_dump_status("mg_read_intr", i, host);
+	mg_bad_rw_intr(host);
+	mg_request(host->breq);
+	return;
+
+ok_to_read:
+	/* get current segment of request */
+	req = elv_next_request(host->breq);
+
+	/* read 1 sector */
+	for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
+		*(u16 *)req->buffer =
+			inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
+					(i << 1));
+		req->buffer += 2;
+	}
+
+	/* manipulate request */
+	MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
+			req->sector, req->nr_sectors - 1, req->buffer);
+
+	req->sector++;
+	req->errors = 0;
+	i = --req->nr_sectors;
+	--req->current_nr_sectors;
+
+	/* let know if current segment done */
+	if (req->current_nr_sectors <= 0)
+		end_request(req, 1);
+
+	/* set handler if read remains */
+	if (i > 0) {
+		host->mg_do_intr = mg_read_intr;
+		mod_timer(&host->timer, jiffies + 3 * HZ);
+	}
+
+	/* send read confirm */
+	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+
+	/* goto next request */
+	if (!i)
+		mg_request(host->breq);
+}
+
+static void mg_write_intr(struct mg_host *host)
+{
+	u32 i, j;
+	u16 *buff;
+	struct request *req;
+
+	/* get current segment of request */
+	req = elv_next_request(host->breq);
+
+	/* check status */
+	do {
+		i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
+		if (i & MG_REG_STATUS_BIT_BUSY)
+			break;
+		if (!MG_READY_OK(i))
+			break;
+		if ((req->nr_sectors <= 1) || (i & MG_REG_STATUS_BIT_DATA_REQ))
+			goto ok_to_write;
+	} while (0);
+	mg_dump_status("mg_write_intr", i, host);
+	mg_bad_rw_intr(host);
+	mg_request(host->breq);
+	return;
+
+ok_to_write:
+	/* manipulate request */
+	req->sector++;
+	i = --req->nr_sectors;
+	--req->current_nr_sectors;
+	req->buffer += MG_SECTOR_SIZE;
+
+	/* let know if current segment or all done */
+	if (!i || (req->bio && req->current_nr_sectors <= 0))
+		end_request(req, 1);
+
+	/* write 1 sector and set handler if remains */
+	if (i > 0) {
+		buff = (u16 *)req->buffer;
+		for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
+			outw(*buff, (unsigned long)host->dev_base +
+					MG_BUFF_OFFSET + (j << 1));
+			buff++;
+		}
+		MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
+				req->sector, req->nr_sectors, req->buffer);
+		host->mg_do_intr = mg_write_intr;
+		mod_timer(&host->timer, jiffies + 3 * HZ);
+	}
+
+	/* send write confirm */
+	outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
+
+	if (!i)
+		mg_request(host->breq);
+}
+
+void mg_times_out(unsigned long data)
+{
+	struct mg_host *host = (struct mg_host *)data;
+	char *name;
+	struct request *req;
+
+	spin_lock_irq(&host->lock);
+
+	req = elv_next_request(host->breq);
+	if (!req)
+		goto out_unlock;
+
+	host->mg_do_intr = NULL;
+
+	name = req->rq_disk->disk_name;
+	printk(KERN_DEBUG "%s: timeout\n", name);
+
+	host->error = MG_ERR_TIMEOUT;
+	mg_bad_rw_intr(host);
+
+	mg_request(host->breq);
+out_unlock:
+	spin_unlock_irq(&host->lock);
+}
+
+static void mg_request_poll(struct request_queue *q)
+{
+	struct request *req;
+	struct mg_host *host;
+
+	while ((req = elv_next_request(q)) != NULL) {
+		host = req->rq_disk->private_data;
+		if (blk_fs_request(req)) {
+			switch (rq_data_dir(req)) {
+			case READ:
+				mg_read(req);
+				break;
+			case WRITE:
+				mg_write(req);
+				break;
+			default:
+				printk(KERN_WARNING "%s:%d unknown command\n",
+						__func__, __LINE__);
+				end_request(req, 0);
+				break;
+			}
+		}
+	}
+}
+
+static unsigned int mg_issue_req(struct request *req,
+		struct mg_host *host,
+		unsigned int sect_num,
+		unsigned int sect_cnt)
+{
+	u16 *buff;
+	u32 i;
+
+	switch (rq_data_dir(req)) {
+	case READ:
+		if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr)
+				!= MG_ERR_NONE) {
+			mg_bad_rw_intr(host);
+			return host->error;
+		}
+		break;
+	case WRITE:
+		/* TODO : handler */
+		outb(MG_REG_CTRL_INTR_DISABLE,
+				(unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+		if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr)
+				!= MG_ERR_NONE) {
+			mg_bad_rw_intr(host);
+			return host->error;
+		}
+		del_timer(&host->timer);
+		mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_WR_DRQ);
+		outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+		if (host->error) {
+			mg_bad_rw_intr(host);
+			return host->error;
+		}
+		buff = (u16 *)req->buffer;
+		for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
+			outw(*buff, (unsigned long)host->dev_base +
+					MG_BUFF_OFFSET + (i << 1));
+			buff++;
+		}
+		mod_timer(&host->timer, jiffies + 3 * HZ);
+		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
+				MG_REG_COMMAND);
+		break;
+	default:
+		printk(KERN_WARNING "%s:%d unknown command\n",
+				__func__, __LINE__);
+		end_request(req, 0);
+		break;
+	}
+	return MG_ERR_NONE;
+}
+
+/* This function also called from IRQ context */
+static void mg_request(struct request_queue *q)
+{
+	struct request *req;
+	struct mg_host *host;
+	u32 sect_num, sect_cnt;
+
+	while (1) {
+		req = elv_next_request(q);
+		if (!req)
+			return;
+
+		host = req->rq_disk->private_data;
+
+		/* check unwanted request call */
+		if (host->mg_do_intr)
+			return;
+
+		del_timer(&host->timer);
+
+		sect_num = req->sector;
+		/* deal whole segments */
+		sect_cnt = req->nr_sectors;
+
+		/* sanity check */
+		if (sect_num >= get_capacity(req->rq_disk) ||
+				((sect_num + sect_cnt) >
+				 get_capacity(req->rq_disk))) {
+			printk(KERN_WARNING
+					"%s: bad access: sector=%d, count=%d\n",
+					req->rq_disk->disk_name,
+					sect_num, sect_cnt);
+			end_request(req, 0);
+			continue;
+		}
+
+		if (!blk_fs_request(req))
+			return;
+
+		if (!mg_issue_req(req, host, sect_num, sect_cnt))
+			return;
+	}
+}
+
+static int mg_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct mg_host *host = bdev->bd_disk->private_data;
+
+	geo->cylinders = (unsigned short)host->cyls;
+	geo->heads = (unsigned char)host->heads;
+	geo->sectors = (unsigned char)host->sectors;
+	return 0;
+}
+
+static struct block_device_operations mg_disk_ops = {
+	.getgeo = mg_getgeo
+};
+
+static int mg_suspend(struct platform_device *plat_dev, pm_message_t state)
+{
+	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+	struct mg_host *host = prv_data->host;
+
+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+		return -EIO;
+
+	if (!prv_data->use_polling)
+		outb(MG_REG_CTRL_INTR_DISABLE,
+				(unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+
+	outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND);
+	/* wait until mflash deep sleep */
+	msleep(1);
+
+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) {
+		if (!prv_data->use_polling)
+			outb(MG_REG_CTRL_INTR_ENABLE,
+					(unsigned long)host->dev_base +
+					MG_REG_DRV_CTRL);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int mg_resume(struct platform_device *plat_dev)
+{
+	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+	struct mg_host *host = prv_data->host;
+
+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+		return -EIO;
+
+	outb(MG_CMD_WAKEUP, (unsigned long)host->dev_base + MG_REG_COMMAND);
+	/* wait until mflash wakeup */
+	msleep(1);
+
+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
+		return -EIO;
+
+	if (!prv_data->use_polling)
+		outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base +
+				MG_REG_DRV_CTRL);
+
+	return 0;
+}
+
+static int mg_probe(struct platform_device *plat_dev)
+{
+	struct mg_host *host;
+	struct resource *rsc;
+	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+	int err = 0;
+
+	if (!prv_data) {
+		printk(KERN_ERR	"%s:%d fail (no driver_data)\n",
+				__func__, __LINE__);
+		err = -EINVAL;
+		goto probe_err;
+	}
+
+	/* alloc mg_host */
+	host = kzalloc(sizeof(struct mg_host), GFP_KERNEL);
+	if (!host) {
+		printk(KERN_ERR "%s:%d fail (no memory for mg_host)\n",
+				__func__, __LINE__);
+		err = -ENOMEM;
+		goto probe_err;
+	}
+	host->major = MG_DISK_MAJ;
+
+	/* link each other */
+	prv_data->host = host;
+	host->dev = &plat_dev->dev;
+
+	/* io remap */
+	rsc = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
+	if (!rsc) {
+		printk(KERN_ERR "%s:%d platform_get_resource fail\n",
+				__func__, __LINE__);
+		err = -EINVAL;
+		goto probe_err_2;
+	}
+	host->dev_base = ioremap(rsc->start , rsc->end + 1);
+	if (!host->dev_base) {
+		printk(KERN_ERR "%s:%d ioremap fail\n",
+				__func__, __LINE__);
+		err = -EIO;
+		goto probe_err_2;
+	}
+	MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base);
+
+	/* get reset pin */
+	rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
+			MG_RST_PIN);
+	if (!rsc) {
+		printk(KERN_ERR "%s:%d get reset pin fail\n",
+				__func__, __LINE__);
+		err = -EIO;
+		goto probe_err_3;
+	}
+	host->rst = rsc->start;
+
+	/* init rst pin */
+	err = gpio_request(host->rst, MG_RST_PIN);
+	if (err)
+		goto probe_err_3;
+	gpio_direction_output(host->rst, 1);
+
+	/* reset out pin */
+	if (!(prv_data->dev_attr & MG_DEV_MASK))
+		goto probe_err_3a;
+
+	if (prv_data->dev_attr != MG_BOOT_DEV) {
+		rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
+				MG_RSTOUT_PIN);
+		if (!rsc) {
+			printk(KERN_ERR "%s:%d get reset-out pin fail\n",
+					__func__, __LINE__);
+			err = -EIO;
+			goto probe_err_3a;
+		}
+		host->rstout = rsc->start;
+		err = gpio_request(host->rstout, MG_RSTOUT_PIN);
+		if (err)
+			goto probe_err_3a;
+		gpio_direction_input(host->rstout);
+	}
+
+	/* disk reset */
+	if (prv_data->dev_attr == MG_STORAGE_DEV) {
+		/* If POR seq. not yet finised, wait */
+		err = mg_wait_rstout(host->rstout, MG_TMAX_RSTOUT);
+		if (err)
+			goto probe_err_3b;
+		err = mg_disk_init(host);
+		if (err) {
+			printk(KERN_ERR "%s:%d fail (err code : %d)\n",
+					__func__, __LINE__, err);
+			err = -EIO;
+			goto probe_err_3b;
+		}
+	}
+
+	/* get irq resource */
+	if (!prv_data->use_polling) {
+		host->irq = platform_get_irq(plat_dev, 0);
+		if (host->irq == -ENXIO) {
+			err = host->irq;
+			goto probe_err_3b;
+		}
+		err = request_irq(host->irq, mg_irq,
+				IRQF_DISABLED | IRQF_TRIGGER_RISING,
+				MG_DEV_NAME, host);
+		if (err) {
+			printk(KERN_ERR "%s:%d fail (request_irq err=%d)\n",
+					__func__, __LINE__, err);
+			goto probe_err_3b;
+		}
+
+	}
+
+	/* get disk id */
+	err = mg_get_disk_id(host);
+	if (err) {
+		printk(KERN_ERR "%s:%d fail (err code : %d)\n",
+				__func__, __LINE__, err);
+		err = -EIO;
+		goto probe_err_4;
+	}
+
+	err = register_blkdev(host->major, MG_DISK_NAME);
+	if (err < 0) {
+		printk(KERN_ERR "%s:%d register_blkdev fail (err code : %d)\n",
+				__func__, __LINE__, err);
+		goto probe_err_4;
+	}
+	if (!host->major)
+		host->major = err;
+
+	spin_lock_init(&host->lock);
+
+	if (prv_data->use_polling)
+		host->breq = blk_init_queue(mg_request_poll, &host->lock);
+	else
+		host->breq = blk_init_queue(mg_request, &host->lock);
+
+	if (!host->breq) {
+		err = -ENOMEM;
+		printk(KERN_ERR "%s:%d (blk_init_queue) fail\n",
+				__func__, __LINE__);
+		goto probe_err_5;
+	}
+
+	/* mflash is random device, thanx for the noop */
+	elevator_exit(host->breq->elevator);
+	err = elevator_init(host->breq, "noop");
+	if (err) {
+		printk(KERN_ERR "%s:%d (elevator_init) fail\n",
+				__func__, __LINE__);
+		goto probe_err_6;
+	}
+	blk_queue_max_sectors(host->breq, MG_MAX_SECTS);
+	blk_queue_hardsect_size(host->breq, MG_SECTOR_SIZE);
+
+	init_timer(&host->timer);
+	host->timer.function = mg_times_out;
+	host->timer.data = (unsigned long)host;
+
+	host->gd = alloc_disk(MG_DISK_MAX_PART);
+	if (!host->gd) {
+		printk(KERN_ERR "%s:%d (alloc_disk) fail\n",
+				__func__, __LINE__);
+		err = -ENOMEM;
+		goto probe_err_7;
+	}
+	host->gd->major = host->major;
+	host->gd->first_minor = 0;
+	host->gd->fops = &mg_disk_ops;
+	host->gd->queue = host->breq;
+	host->gd->private_data = host;
+	sprintf(host->gd->disk_name, MG_DISK_NAME"a");
+
+	set_capacity(host->gd, host->n_sectors);
+
+	add_disk(host->gd);
+
+	return err;
+
+probe_err_7:
+	del_timer_sync(&host->timer);
+probe_err_6:
+	blk_cleanup_queue(host->breq);
+probe_err_5:
+	unregister_blkdev(MG_DISK_MAJ, MG_DISK_NAME);
+probe_err_4:
+	if (!prv_data->use_polling)
+		free_irq(host->irq, host);
+probe_err_3b:
+	gpio_free(host->rstout);
+probe_err_3a:
+	gpio_free(host->rst);
+probe_err_3:
+	iounmap(host->dev_base);
+probe_err_2:
+	kfree(host);
+probe_err:
+	return err;
+}
+
+static int mg_remove(struct platform_device *plat_dev)
+{
+	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
+	struct mg_host *host = prv_data->host;
+	int err = 0;
+
+	/* delete timer */
+	del_timer_sync(&host->timer);
+
+	/* remove disk */
+	if (host->gd) {
+		del_gendisk(host->gd);
+		put_disk(host->gd);
+	}
+	/* remove queue */
+	if (host->breq)
+		blk_cleanup_queue(host->breq);
+
+	/* unregister blk device */
+	unregister_blkdev(host->major, MG_DISK_NAME);
+
+	/* free irq */
+	if (!prv_data->use_polling)
+		free_irq(host->irq, host);
+
+	/* free reset-out pin */
+	if (prv_data->dev_attr != MG_BOOT_DEV)
+		gpio_free(host->rstout);
+
+	/* free rst pin */
+	if (host->rst)
+		gpio_free(host->rst);
+
+	/* unmap io */
+	if (host->dev_base)
+		iounmap(host->dev_base);
+
+	/* free mg_host */
+	kfree(host);
+
+	return err;
+}
+
+static struct platform_driver mg_disk_driver = {
+	.probe = mg_probe,
+	.remove = mg_remove,
+	.suspend = mg_suspend,
+	.resume = mg_resume,
+	.driver = {
+		.name = MG_DEV_NAME,
+		.owner = THIS_MODULE,
+	}
+};
+
+/****************************************************************************
+ *
+ * Module stuff
+ *
+ ****************************************************************************/
+
+static int __init mg_init(void)
+{
+	printk(KERN_INFO "mGine mflash driver, (c) 2008 mGine Co.\n");
+	return platform_driver_register(&mg_disk_driver);
+}
+
+static void __exit mg_exit(void)
+{
+	printk(KERN_INFO "mflash driver : bye bye\n");
+	platform_driver_unregister(&mg_disk_driver);
+}
+
+module_init(mg_init);
+module_exit(mg_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("unsik Kim <donari75@gmail.com>");
+MODULE_DESCRIPTION("mGine m[g]flash device driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/nbd.c linux-libre-2.6.30-gnu1/drivers/block/nbd.c
--- linux-libre-2.6.29-gnu1/drivers/block/nbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/nbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * Note that you can not swap over this thing, yet. Seems to work but
  * deadlocks sometimes - you can not swap over TCP in general.
  * 
- * Copyright 1997-2000 Pavel Machek <pavel@ucw.cz>
+ * Copyright 1997-2000, 2008 Pavel Machek <pavel@suse.cz>
  * Parts copyright 2001 Steven Whitehouse <steve@chygwyn.com>
  *
  * This file is released under GPLv2 or later.
@@ -276,7 +276,7 @@ static int nbd_send_req(struct nbd_devic
 	return 0;
 
 error_out:
-	return 1;
+	return -EIO;
 }
 
 static struct request *nbd_find_request(struct nbd_device *lo,
@@ -467,9 +467,7 @@ static void nbd_handle_req(struct nbd_de
 		mutex_unlock(&lo->tx_lock);
 		printk(KERN_ERR "%s: Attempted send on closed socket\n",
 		       lo->disk->disk_name);
-		req->errors++;
-		nbd_end_request(req);
-		return;
+		goto error_out;
 	}
 
 	lo->active_req = req;
@@ -531,7 +529,7 @@ static int nbd_thread(void *data)
  *   { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
  */
 
-static void do_nbd_request(struct request_queue * q)
+static void do_nbd_request(struct request_queue *q)
 {
 	struct request *req;
 	
@@ -568,27 +566,17 @@ static void do_nbd_request(struct reques
 	}
 }
 
-static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
-		     unsigned int cmd, unsigned long arg)
-{
-	struct nbd_device *lo = bdev->bd_disk->private_data;
-	struct file *file;
-	int error;
-	struct request sreq ;
-	struct task_struct *thread;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	BUG_ON(lo->magic != LO_MAGIC);
-
-	/* Anyone capable of this syscall can do *real bad* things */
-	dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
-			lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+/* Must be called with tx_lock held */
 
+static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
+		       unsigned int cmd, unsigned long arg)
+{
 	switch (cmd) {
-	case NBD_DISCONNECT:
+	case NBD_DISCONNECT: {
+		struct request sreq;
+
 	        printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name);
+
 		blk_rq_init(NULL, &sreq);
 		sreq.cmd_type = REQ_TYPE_SPECIAL;
 		nbd_cmd(&sreq) = NBD_CMD_DISC;
@@ -599,29 +587,29 @@ static int nbd_ioctl(struct block_device
 		 */
 		sreq.sector = 0;
 		sreq.nr_sectors = 0;
-                if (!lo->sock)
+		if (!lo->sock)
 			return -EINVAL;
-		mutex_lock(&lo->tx_lock);
-                nbd_send_req(lo, &sreq);
-		mutex_unlock(&lo->tx_lock);
+		nbd_send_req(lo, &sreq);
                 return 0;
+	}
  
-	case NBD_CLEAR_SOCK:
-		error = 0;
-		mutex_lock(&lo->tx_lock);
+	case NBD_CLEAR_SOCK: {
+		struct file *file;
+
 		lo->sock = NULL;
-		mutex_unlock(&lo->tx_lock);
 		file = lo->file;
 		lo->file = NULL;
 		nbd_clear_que(lo);
 		BUG_ON(!list_empty(&lo->queue_head));
 		if (file)
 			fput(file);
-		return error;
-	case NBD_SET_SOCK:
+		return 0;
+	}
+
+	case NBD_SET_SOCK: {
+		struct file *file;
 		if (lo->file)
 			return -EBUSY;
-		error = -EINVAL;
 		file = fget(arg);
 		if (file) {
 			struct inode *inode = file->f_path.dentry->d_inode;
@@ -630,12 +618,14 @@ static int nbd_ioctl(struct block_device
 				lo->sock = SOCKET_I(inode);
 				if (max_part > 0)
 					bdev->bd_invalidated = 1;
-				error = 0;
+				return 0;
 			} else {
 				fput(file);
 			}
 		}
-		return error;
+		return -EINVAL;
+	}
+
 	case NBD_SET_BLKSIZE:
 		lo->blksize = arg;
 		lo->bytesize &= ~(lo->blksize-1);
@@ -643,35 +633,50 @@ static int nbd_ioctl(struct block_device
 		set_blocksize(bdev, lo->blksize);
 		set_capacity(lo->disk, lo->bytesize >> 9);
 		return 0;
+
 	case NBD_SET_SIZE:
 		lo->bytesize = arg & ~(lo->blksize-1);
 		bdev->bd_inode->i_size = lo->bytesize;
 		set_blocksize(bdev, lo->blksize);
 		set_capacity(lo->disk, lo->bytesize >> 9);
 		return 0;
+
 	case NBD_SET_TIMEOUT:
 		lo->xmit_timeout = arg * HZ;
 		return 0;
+
 	case NBD_SET_SIZE_BLOCKS:
 		lo->bytesize = ((u64) arg) * lo->blksize;
 		bdev->bd_inode->i_size = lo->bytesize;
 		set_blocksize(bdev, lo->blksize);
 		set_capacity(lo->disk, lo->bytesize >> 9);
 		return 0;
-	case NBD_DO_IT:
+
+	case NBD_DO_IT: {
+		struct task_struct *thread;
+		struct file *file;
+		int error;
+
 		if (lo->pid)
 			return -EBUSY;
 		if (!lo->file)
 			return -EINVAL;
+
+		mutex_unlock(&lo->tx_lock);
+
 		thread = kthread_create(nbd_thread, lo, lo->disk->disk_name);
-		if (IS_ERR(thread))
+		if (IS_ERR(thread)) {
+			mutex_lock(&lo->tx_lock);
 			return PTR_ERR(thread);
+		}
 		wake_up_process(thread);
 		error = nbd_do_it(lo);
 		kthread_stop(thread);
+
+		mutex_lock(&lo->tx_lock);
 		if (error)
 			return error;
-		sock_shutdown(lo, 1);
+		sock_shutdown(lo, 0);
 		file = lo->file;
 		lo->file = NULL;
 		nbd_clear_que(lo);
@@ -684,6 +689,8 @@ static int nbd_ioctl(struct block_device
 		if (max_part > 0)
 			ioctl_by_bdev(bdev, BLKRRPART, 0);
 		return lo->harderror;
+	}
+
 	case NBD_CLEAR_QUE:
 		/*
 		 * This is for compatibility only.  The queue is always cleared
@@ -691,6 +698,7 @@ static int nbd_ioctl(struct block_device
 		 */
 		BUG_ON(!lo->sock && !list_empty(&lo->queue_head));
 		return 0;
+
 	case NBD_PRINT_DEBUG:
 		printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
 			bdev->bd_disk->disk_name,
@@ -698,7 +706,29 @@ static int nbd_ioctl(struct block_device
 			&lo->queue_head);
 		return 0;
 	}
-	return -EINVAL;
+	return -ENOTTY;
+}
+
+static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
+		     unsigned int cmd, unsigned long arg)
+{
+	struct nbd_device *lo = bdev->bd_disk->private_data;
+	int error;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	BUG_ON(lo->magic != LO_MAGIC);
+
+	/* Anyone capable of this syscall can do *real bad* things */
+	dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
+			lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+
+	mutex_lock(&lo->tx_lock);
+	error = __nbd_ioctl(bdev, lo, cmd, arg);
+	mutex_unlock(&lo->tx_lock);
+
+	return error;
 }
 
 static struct block_device_operations nbd_fops =
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/ps3vram.c linux-libre-2.6.30-gnu1/drivers/block/ps3vram.c
--- linux-libre-2.6.29-gnu1/drivers/block/ps3vram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/ps3vram.c	2009-06-09 23:05:27.000000000 -0400
@@ -551,8 +551,6 @@ static void __devinit ps3vram_proc_init(
 		dev_warn(&dev->core, "failed to create /proc entry\n");
 		return;
 	}
-
-	pde->owner = THIS_MODULE;
 	pde->data = priv;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/swim_asm.S linux-libre-2.6.30-gnu1/drivers/block/swim_asm.S
--- linux-libre-2.6.29-gnu1/drivers/block/swim_asm.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/block/swim_asm.S	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,247 @@
+/*
+ * low-level functions for the SWIM floppy controller
+ *
+ * needs assembly language because is very timing dependent
+ * this controller exists only on macintosh 680x0 based
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-11-05 (lv) - add get_swim_mode
+ */
+
+	.equ	write_data,	0x0000
+	.equ	write_mark,	0x0200
+	.equ	write_CRC,	0x0400
+	.equ	write_parameter,0x0600
+	.equ	write_phase,	0x0800
+	.equ	write_setup,	0x0a00
+	.equ	write_mode0,	0x0c00
+	.equ	write_mode1,	0x0e00
+	.equ	read_data,	0x1000
+	.equ	read_mark,	0x1200
+	.equ	read_error,	0x1400
+	.equ	read_parameter,	0x1600
+	.equ	read_phase,	0x1800
+	.equ	read_setup,	0x1a00
+	.equ	read_status,	0x1c00
+	.equ	read_handshake,	0x1e00
+
+	.equ	o_side, 0
+	.equ	o_track, 1
+	.equ	o_sector, 2
+	.equ	o_size, 3
+	.equ	o_crc0, 4
+	.equ	o_crc1, 5
+
+	.equ	seek_time, 30000
+	.equ	max_retry, 40
+	.equ	sector_size, 512
+
+	.global swim_read_sector_header
+swim_read_sector_header:
+	link	%a6, #0
+	moveml	%d1-%d5/%a0-%a4,%sp@-
+	movel	%a6@(0x0c), %a4
+	bsr	mfm_read_addrmark
+	moveml	%sp@+, %d1-%d5/%a0-%a4
+	unlk	%a6
+	rts
+
+sector_address_mark:
+	.byte	0xa1, 0xa1, 0xa1, 0xfe
+sector_data_mark:
+	.byte	0xa1, 0xa1, 0xa1, 0xfb
+
+mfm_read_addrmark:
+	movel	%a6@(0x08), %a3
+	lea	%a3@(read_handshake), %a2
+	lea	%a3@(read_mark), %a3
+	moveq	#-1, %d0
+	movew	#seek_time, %d2
+
+wait_header_init:
+	tstb	%a3@(read_error - read_mark)
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+	moveb	#0x01, %a3@(write_mode1 - read_mark)
+	moveb	#0x01, %a3@(write_mode0 - read_mark)
+	tstb	%a3@(read_error - read_mark)
+	moveb	#0x08, %a3@(write_mode1 - read_mark)
+
+	lea	sector_address_mark, %a0
+	moveq	#3, %d1
+
+wait_addr_mark_byte:
+
+	tstb	%a2@
+	dbmi	%d2, wait_addr_mark_byte
+	bpl	header_exit
+
+	moveb	%a3@, %d3
+	cmpb	%a0@+, %d3
+	dbne	%d1, wait_addr_mark_byte
+	bne	wait_header_init
+
+	moveq	#max_retry, %d2
+
+amark0:	tstb	%a2@
+	dbmi	%d2, amark0
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_track)
+
+	moveq	#max_retry, %d2
+
+amark1:	tstb	%a2@
+	dbmi	%d2, amark1
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_side)
+
+	moveq	#max_retry, %d2
+
+amark2:	tstb	%a2@
+	dbmi	%d2, amark2
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_sector)
+
+	moveq	#max_retry, %d2
+
+amark3:	tstb	%a2@
+	dbmi	%d2, amark3
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_size)
+
+	moveq	#max_retry, %d2
+
+crc0:	tstb	%a2@
+	dbmi	%d2, crc0
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_crc0)
+
+	moveq	#max_retry, %d2
+
+crc1:	tstb	%a2@
+	dbmi	%d2, crc1
+	bpl	signal_nonyb
+
+	moveb	%a3@, %a4@(o_crc1)
+
+	tstb	%a3@(read_error - read_mark)
+
+header_exit:
+	moveq	#0, %d0
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+	rts
+signal_nonyb:
+	moveq	#-1, %d0
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+	rts
+
+	.global swim_read_sector_data
+swim_read_sector_data:
+	link	%a6, #0
+	moveml	%d1-%d5/%a0-%a5,%sp@-
+	movel	%a6@(0x0c), %a4
+	bsr	mfm_read_data
+	moveml	%sp@+, %d1-%d5/%a0-%a5
+	unlk	%a6
+	rts
+
+mfm_read_data:
+	movel	%a6@(0x08), %a3
+	lea	%a3@(read_handshake), %a2
+	lea	%a3@(read_data), %a5
+	lea	%a3@(read_mark), %a3
+	movew	#seek_time, %d2
+
+wait_data_init:
+	tstb	%a3@(read_error - read_mark)
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+	moveb	#0x01, %a3@(write_mode1 - read_mark)
+	moveb	#0x01, %a3@(write_mode0 - read_mark)
+	tstb	%a3@(read_error - read_mark)
+	moveb	#0x08, %a3@(write_mode1 - read_mark)
+
+	lea	sector_data_mark, %a0
+	moveq	#3, %d1
+
+	/* wait data address mark */
+
+wait_data_mark_byte:
+
+	tstb	%a2@
+	dbmi	%d2, wait_data_mark_byte
+	bpl	data_exit
+
+	moveb	%a3@, %d3
+	cmpb	%a0@+, %d3
+	dbne	%d1, wait_data_mark_byte
+	bne	wait_data_init
+
+	/* read data */
+
+	tstb	%a3@(read_error - read_mark)
+
+	movel	#sector_size-1, %d4		/* sector size */
+read_new_data:
+	movew	#max_retry, %d2
+read_data_loop:
+	moveb	%a2@, %d5
+	andb	#0xc0, %d5
+	dbne	%d2, read_data_loop
+	beq	data_exit
+	moveb	%a5@, %a4@+
+	andb	#0x40, %d5
+	dbne	%d4, read_new_data
+	beq	exit_loop
+	moveb	%a5@, %a4@+
+	dbra	%d4, read_new_data
+exit_loop:
+
+	/* read CRC */
+
+	movew	#max_retry, %d2
+data_crc0:
+
+	tstb	%a2@
+	dbmi	%d2, data_crc0
+	bpl	data_exit
+
+	moveb	%a3@, %d5
+
+	moveq	#max_retry, %d2
+
+data_crc1:
+
+	tstb	%a2@
+	dbmi	%d2, data_crc1
+	bpl	data_exit
+
+	moveb	%a3@, %d5
+
+	tstb	%a3@(read_error - read_mark)
+
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+
+	/* return number of bytes read */
+
+	movel	#sector_size, %d0
+	addw	#1, %d4
+	subl	%d4, %d0
+	rts
+data_exit:
+	moveb	#0x18, %a3@(write_mode0 - read_mark)
+	moveq	#-1, %d0
+	rts
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/swim.c linux-libre-2.6.30-gnu1/drivers/block/swim.c
--- linux-libre-2.6.29-gnu1/drivers/block/swim.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/block/swim.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,995 @@
+/*
+ * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on SWIM3 driver (c) Paul Mackerras, 1996
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-10-30 (lv) - Port to 2.6
+ */
+
+#include <linux/module.h>
+#include <linux/fd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/macintosh.h>
+#include <asm/mac_via.h>
+
+#define CARDNAME "swim"
+
+struct sector_header {
+	unsigned char side;
+	unsigned char track;
+	unsigned char sector;
+	unsigned char size;
+	unsigned char crc0;
+	unsigned char crc1;
+} __attribute__((packed));
+
+#define DRIVER_VERSION "Version 0.2 (2008-10-30)"
+
+#define REG(x)	unsigned char x, x ## _pad[0x200 - 1];
+
+struct swim {
+	REG(write_data)
+	REG(write_mark)
+	REG(write_CRC)
+	REG(write_parameter)
+	REG(write_phase)
+	REG(write_setup)
+	REG(write_mode0)
+	REG(write_mode1)
+
+	REG(read_data)
+	REG(read_mark)
+	REG(read_error)
+	REG(read_parameter)
+	REG(read_phase)
+	REG(read_setup)
+	REG(read_status)
+	REG(read_handshake)
+} __attribute__((packed));
+
+#define swim_write(base, reg, v) 	out_8(&(base)->write_##reg, (v))
+#define swim_read(base, reg)		in_8(&(base)->read_##reg)
+
+/* IWM registers */
+
+struct iwm {
+	REG(ph0L)
+	REG(ph0H)
+	REG(ph1L)
+	REG(ph1H)
+	REG(ph2L)
+	REG(ph2H)
+	REG(ph3L)
+	REG(ph3H)
+	REG(mtrOff)
+	REG(mtrOn)
+	REG(intDrive)
+	REG(extDrive)
+	REG(q6L)
+	REG(q6H)
+	REG(q7L)
+	REG(q7H)
+} __attribute__((packed));
+
+#define iwm_write(base, reg, v) 	out_8(&(base)->reg, (v))
+#define iwm_read(base, reg)		in_8(&(base)->reg)
+
+/* bits in phase register */
+
+#define SEEK_POSITIVE	0x070
+#define SEEK_NEGATIVE	0x074
+#define STEP		0x071
+#define MOTOR_ON	0x072
+#define MOTOR_OFF	0x076
+#define INDEX		0x073
+#define EJECT		0x077
+#define SETMFM		0x171
+#define SETGCR		0x175
+
+#define RELAX		0x033
+#define LSTRB		0x008
+
+#define CA_MASK		0x077
+
+/* Select values for swim_select and swim_readbit */
+
+#define READ_DATA_0	0x074
+#define TWOMEG_DRIVE	0x075
+#define SINGLE_SIDED	0x076
+#define DRIVE_PRESENT	0x077
+#define DISK_IN		0x170
+#define WRITE_PROT	0x171
+#define TRACK_ZERO	0x172
+#define TACHO		0x173
+#define READ_DATA_1	0x174
+#define MFM_MODE	0x175
+#define SEEK_COMPLETE	0x176
+#define ONEMEG_MEDIA	0x177
+
+/* Bits in handshake register */
+
+#define MARK_BYTE	0x01
+#define CRC_ZERO	0x02
+#define RDDATA		0x04
+#define SENSE		0x08
+#define MOTEN		0x10
+#define ERROR		0x20
+#define DAT2BYTE	0x40
+#define DAT1BYTE	0x80
+
+/* bits in setup register */
+
+#define S_INV_WDATA	0x01
+#define S_3_5_SELECT	0x02
+#define S_GCR		0x04
+#define S_FCLK_DIV2	0x08
+#define S_ERROR_CORR	0x10
+#define S_IBM_DRIVE	0x20
+#define S_GCR_WRITE	0x40
+#define S_TIMEOUT	0x80
+
+/* bits in mode register */
+
+#define CLFIFO		0x01
+#define ENBL1		0x02
+#define ENBL2		0x04
+#define ACTION		0x08
+#define WRITE_MODE	0x10
+#define HEDSEL		0x20
+#define MOTON		0x80
+
+/*----------------------------------------------------------------------------*/
+
+enum drive_location {
+	INTERNAL_DRIVE = 0x02,
+	EXTERNAL_DRIVE = 0x04,
+};
+
+enum media_type {
+	DD_MEDIA,
+	HD_MEDIA,
+};
+
+struct floppy_state {
+
+	/* physical properties */
+
+	enum drive_location location;	/* internal or external drive */
+	int		 head_number;	/* single- or double-sided drive */
+
+	/* media */
+
+	int		 disk_in;
+	int		 ejected;
+	enum media_type	 type;
+	int		 write_protected;
+
+	int		 total_secs;
+	int		 secpercyl;
+	int		 secpertrack;
+
+	/* in-use information */
+
+	int		track;
+	int		ref_count;
+
+	struct gendisk *disk;
+
+	/* parent controller */
+
+	struct swim_priv *swd;
+};
+
+enum motor_action {
+	OFF,
+	ON,
+};
+
+enum head {
+	LOWER_HEAD = 0,
+	UPPER_HEAD = 1,
+};
+
+#define FD_MAX_UNIT	2
+
+struct swim_priv {
+	struct swim __iomem *base;
+	spinlock_t lock;
+	struct request_queue *queue;
+	int floppy_count;
+	struct floppy_state unit[FD_MAX_UNIT];
+};
+
+extern int swim_read_sector_header(struct swim __iomem *base,
+				   struct sector_header *header);
+extern int swim_read_sector_data(struct swim __iomem *base,
+				 unsigned char *data);
+
+static inline void set_swim_mode(struct swim __iomem *base, int enable)
+{
+	struct iwm __iomem *iwm_base;
+	unsigned long flags;
+
+	if (!enable) {
+		swim_write(base, mode0, 0xf8);
+		return;
+	}
+
+	iwm_base = (struct iwm __iomem *)base;
+	local_irq_save(flags);
+
+	iwm_read(iwm_base, q7L);
+	iwm_read(iwm_base, mtrOff);
+	iwm_read(iwm_base, q6H);
+
+	iwm_write(iwm_base, q7H, 0x57);
+	iwm_write(iwm_base, q7H, 0x17);
+	iwm_write(iwm_base, q7H, 0x57);
+	iwm_write(iwm_base, q7H, 0x57);
+
+	local_irq_restore(flags);
+}
+
+static inline int get_swim_mode(struct swim __iomem *base)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	swim_write(base, phase, 0xf5);
+	if (swim_read(base, phase) != 0xf5)
+		goto is_iwm;
+	swim_write(base, phase, 0xf6);
+	if (swim_read(base, phase) != 0xf6)
+		goto is_iwm;
+	swim_write(base, phase, 0xf7);
+	if (swim_read(base, phase) != 0xf7)
+		goto is_iwm;
+	local_irq_restore(flags);
+	return 1;
+is_iwm:
+	local_irq_restore(flags);
+	return 0;
+}
+
+static inline void swim_select(struct swim __iomem *base, int sel)
+{
+	swim_write(base, phase, RELAX);
+
+	via1_set_head(sel & 0x100);
+
+	swim_write(base, phase, sel & CA_MASK);
+}
+
+static inline void swim_action(struct swim __iomem *base, int action)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	swim_select(base, action);
+	udelay(1);
+	swim_write(base, phase, (LSTRB<<4) | LSTRB);
+	udelay(1);
+	swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
+	udelay(1);
+
+	local_irq_restore(flags);
+}
+
+static inline int swim_readbit(struct swim __iomem *base, int bit)
+{
+	int stat;
+
+	swim_select(base, bit);
+
+	udelay(10);
+
+	stat = swim_read(base, handshake);
+
+	return (stat & SENSE) == 0;
+}
+
+static inline void swim_drive(struct swim __iomem *base,
+			      enum drive_location location)
+{
+	if (location == INTERNAL_DRIVE) {
+		swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */
+		swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */
+	} else if (location == EXTERNAL_DRIVE) {
+		swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */
+		swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */
+	}
+}
+
+static inline void swim_motor(struct swim __iomem *base,
+			      enum motor_action action)
+{
+	if (action == ON) {
+		int i;
+
+		swim_action(base, MOTOR_ON);
+
+		for (i = 0; i < 2*HZ; i++) {
+			swim_select(base, RELAX);
+			if (swim_readbit(base, MOTOR_ON))
+				break;
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(1);
+		}
+	} else if (action == OFF) {
+		swim_action(base, MOTOR_OFF);
+		swim_select(base, RELAX);
+	}
+}
+
+static inline void swim_eject(struct swim __iomem *base)
+{
+	int i;
+
+	swim_action(base, EJECT);
+
+	for (i = 0; i < 2*HZ; i++) {
+		swim_select(base, RELAX);
+		if (!swim_readbit(base, DISK_IN))
+			break;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+	swim_select(base, RELAX);
+}
+
+static inline void swim_head(struct swim __iomem *base, enum head head)
+{
+	/* wait drive is ready */
+
+	if (head == UPPER_HEAD)
+		swim_select(base, READ_DATA_1);
+	else if (head == LOWER_HEAD)
+		swim_select(base, READ_DATA_0);
+}
+
+static inline int swim_step(struct swim __iomem *base)
+{
+	int wait;
+
+	swim_action(base, STEP);
+
+	for (wait = 0; wait < HZ; wait++) {
+
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+
+		swim_select(base, RELAX);
+		if (!swim_readbit(base, STEP))
+			return 0;
+	}
+	return -1;
+}
+
+static inline int swim_track00(struct swim __iomem *base)
+{
+	int try;
+
+	swim_action(base, SEEK_NEGATIVE);
+
+	for (try = 0; try < 100; try++) {
+
+		swim_select(base, RELAX);
+		if (swim_readbit(base, TRACK_ZERO))
+			break;
+
+		if (swim_step(base))
+			return -1;
+	}
+
+	if (swim_readbit(base, TRACK_ZERO))
+		return 0;
+
+	return -1;
+}
+
+static inline int swim_seek(struct swim __iomem *base, int step)
+{
+	if (step == 0)
+		return 0;
+
+	if (step < 0) {
+		swim_action(base, SEEK_NEGATIVE);
+		step = -step;
+	} else
+		swim_action(base, SEEK_POSITIVE);
+
+	for ( ; step > 0; step--) {
+		if (swim_step(base))
+			return -1;
+	}
+
+	return 0;
+}
+
+static inline int swim_track(struct floppy_state *fs,  int track)
+{
+	struct swim __iomem *base = fs->swd->base;
+	int ret;
+
+	ret = swim_seek(base, track - fs->track);
+
+	if (ret == 0)
+		fs->track = track;
+	else {
+		swim_track00(base);
+		fs->track = 0;
+	}
+
+	return ret;
+}
+
+static int floppy_eject(struct floppy_state *fs)
+{
+	struct swim __iomem *base = fs->swd->base;
+
+	swim_drive(base, fs->location);
+	swim_motor(base, OFF);
+	swim_eject(base);
+
+	fs->disk_in = 0;
+	fs->ejected = 1;
+
+	return 0;
+}
+
+static inline int swim_read_sector(struct floppy_state *fs,
+				   int side, int track,
+				   int sector, unsigned char *buffer)
+{
+	struct swim __iomem *base = fs->swd->base;
+	unsigned long flags;
+	struct sector_header header;
+	int ret = -1;
+	short i;
+
+	swim_track(fs, track);
+
+	swim_write(base, mode1, MOTON);
+	swim_head(base, side);
+	swim_write(base, mode0, side);
+
+	local_irq_save(flags);
+	for (i = 0; i < 36; i++) {
+		ret = swim_read_sector_header(base, &header);
+		if (!ret && (header.sector == sector)) {
+			/* found */
+
+			ret = swim_read_sector_data(base, buffer);
+			break;
+		}
+	}
+	local_irq_restore(flags);
+
+	swim_write(base, mode0, MOTON);
+
+	if ((header.side != side)  || (header.track != track) ||
+	     (header.sector != sector))
+		return 0;
+
+	return ret;
+}
+
+static int floppy_read_sectors(struct floppy_state *fs,
+			       int req_sector, int sectors_nb,
+			       unsigned char *buffer)
+{
+	struct swim __iomem *base = fs->swd->base;
+	int ret;
+	int side, track, sector;
+	int i, try;
+
+
+	swim_drive(base, fs->location);
+	for (i = req_sector; i < req_sector + sectors_nb; i++) {
+		int x;
+		track = i / fs->secpercyl;
+		x = i % fs->secpercyl;
+		side = x / fs->secpertrack;
+		sector = x % fs->secpertrack + 1;
+
+		try = 5;
+		do {
+			ret = swim_read_sector(fs, side, track, sector,
+						buffer);
+			if (try-- == 0)
+				return -1;
+		} while (ret != 512);
+
+		buffer += ret;
+	}
+
+	return 0;
+}
+
+static void redo_fd_request(struct request_queue *q)
+{
+	struct request *req;
+	struct floppy_state *fs;
+
+	while ((req = elv_next_request(q))) {
+
+		fs = req->rq_disk->private_data;
+		if (req->sector < 0 || req->sector >= fs->total_secs) {
+			end_request(req, 0);
+			continue;
+		}
+		if (req->current_nr_sectors == 0) {
+			end_request(req, 1);
+			continue;
+		}
+		if (!fs->disk_in) {
+			end_request(req, 0);
+			continue;
+		}
+		if (rq_data_dir(req) == WRITE) {
+			if (fs->write_protected) {
+				end_request(req, 0);
+				continue;
+			}
+		}
+		switch (rq_data_dir(req)) {
+		case WRITE:
+			/* NOT IMPLEMENTED */
+			end_request(req, 0);
+			break;
+		case READ:
+			if (floppy_read_sectors(fs, req->sector,
+						req->current_nr_sectors,
+						req->buffer)) {
+				end_request(req, 0);
+				continue;
+			}
+			req->nr_sectors -= req->current_nr_sectors;
+			req->sector += req->current_nr_sectors;
+			req->buffer += req->current_nr_sectors * 512;
+			end_request(req, 1);
+			break;
+		}
+	}
+}
+
+static void do_fd_request(struct request_queue *q)
+{
+	redo_fd_request(q);
+}
+
+static struct floppy_struct floppy_type[4] = {
+	{    0,  0, 0,  0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing   */
+	{  720,  9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
+	{ 1440,  9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5"   */
+	{ 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5"  */
+};
+
+static int get_floppy_geometry(struct floppy_state *fs, int type,
+			       struct floppy_struct **g)
+{
+	if (type >= ARRAY_SIZE(floppy_type))
+		return -EINVAL;
+
+	if (type)
+		*g = &floppy_type[type];
+	else if (fs->type == HD_MEDIA) /* High-Density media */
+		*g = &floppy_type[3];
+	else if (fs->head_number == 2) /* double-sided */
+		*g = &floppy_type[2];
+	else
+		*g = &floppy_type[1];
+
+	return 0;
+}
+
+static void setup_medium(struct floppy_state *fs)
+{
+	struct swim __iomem *base = fs->swd->base;
+
+	if (swim_readbit(base, DISK_IN)) {
+		struct floppy_struct *g;
+		fs->disk_in = 1;
+		fs->write_protected = swim_readbit(base, WRITE_PROT);
+		fs->type = swim_readbit(base, ONEMEG_MEDIA);
+
+		if (swim_track00(base))
+			printk(KERN_ERR
+				"SWIM: cannot move floppy head to track 0\n");
+
+		swim_track00(base);
+
+		get_floppy_geometry(fs, 0, &g);
+		fs->total_secs = g->size;
+		fs->secpercyl = g->head * g->sect;
+		fs->secpertrack = g->sect;
+		fs->track = 0;
+	} else {
+		fs->disk_in = 0;
+	}
+}
+
+static int floppy_open(struct block_device *bdev, fmode_t mode)
+{
+	struct floppy_state *fs = bdev->bd_disk->private_data;
+	struct swim __iomem *base = fs->swd->base;
+	int err;
+
+	if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL))
+		return -EBUSY;
+
+	if (mode & FMODE_EXCL)
+		fs->ref_count = -1;
+	else
+		fs->ref_count++;
+
+	swim_write(base, setup, S_IBM_DRIVE  | S_FCLK_DIV2);
+	udelay(10);
+	swim_drive(base, INTERNAL_DRIVE);
+	swim_motor(base, ON);
+	swim_action(base, SETMFM);
+	if (fs->ejected)
+		setup_medium(fs);
+	if (!fs->disk_in) {
+		err = -ENXIO;
+		goto out;
+	}
+
+	if (mode & FMODE_NDELAY)
+		return 0;
+
+	if (mode & (FMODE_READ|FMODE_WRITE)) {
+		check_disk_change(bdev);
+		if ((mode & FMODE_WRITE) && fs->write_protected) {
+			err = -EROFS;
+			goto out;
+		}
+	}
+	return 0;
+out:
+	if (fs->ref_count < 0)
+		fs->ref_count = 0;
+	else if (fs->ref_count > 0)
+		--fs->ref_count;
+
+	if (fs->ref_count == 0)
+		swim_motor(base, OFF);
+	return err;
+}
+
+static int floppy_release(struct gendisk *disk, fmode_t mode)
+{
+	struct floppy_state *fs = disk->private_data;
+	struct swim __iomem *base = fs->swd->base;
+
+	if (fs->ref_count < 0)
+		fs->ref_count = 0;
+	else if (fs->ref_count > 0)
+		--fs->ref_count;
+
+	if (fs->ref_count == 0)
+		swim_motor(base, OFF);
+
+	return 0;
+}
+
+static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
+			unsigned int cmd, unsigned long param)
+{
+	struct floppy_state *fs = bdev->bd_disk->private_data;
+	int err;
+
+	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+	switch (cmd) {
+	case FDEJECT:
+		if (fs->ref_count != 1)
+			return -EBUSY;
+		err = floppy_eject(fs);
+		return err;
+
+	case FDGETPRM:
+		if (copy_to_user((void __user *) param, (void *) &floppy_type,
+				 sizeof(struct floppy_struct)))
+			return -EFAULT;
+		break;
+
+	default:
+		printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
+		       cmd);
+		return -ENOSYS;
+	}
+	return 0;
+}
+
+static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct floppy_state *fs = bdev->bd_disk->private_data;
+	struct floppy_struct *g;
+	int ret;
+
+	ret = get_floppy_geometry(fs, 0, &g);
+	if (ret)
+		return ret;
+
+	geo->heads = g->head;
+	geo->sectors = g->sect;
+	geo->cylinders = g->track;
+
+	return 0;
+}
+
+static int floppy_check_change(struct gendisk *disk)
+{
+	struct floppy_state *fs = disk->private_data;
+
+	return fs->ejected;
+}
+
+static int floppy_revalidate(struct gendisk *disk)
+{
+	struct floppy_state *fs = disk->private_data;
+	struct swim __iomem *base = fs->swd->base;
+
+	swim_drive(base, fs->location);
+
+	if (fs->ejected)
+		setup_medium(fs);
+
+	if (!fs->disk_in)
+		swim_motor(base, OFF);
+	else
+		fs->ejected = 0;
+
+	return !fs->disk_in;
+}
+
+static struct block_device_operations floppy_fops = {
+	.owner		 = THIS_MODULE,
+	.open		 = floppy_open,
+	.release	 = floppy_release,
+	.locked_ioctl	 = floppy_ioctl,
+	.getgeo		 = floppy_getgeo,
+	.media_changed	 = floppy_check_change,
+	.revalidate_disk = floppy_revalidate,
+};
+
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+{
+	struct swim_priv *swd = data;
+	int drive = (*part & 3);
+
+	if (drive > swd->floppy_count)
+		return NULL;
+
+	*part = 0;
+	return get_disk(swd->unit[drive].disk);
+}
+
+static int __devinit swim_add_floppy(struct swim_priv *swd,
+				     enum drive_location location)
+{
+	struct floppy_state *fs = &swd->unit[swd->floppy_count];
+	struct swim __iomem *base = swd->base;
+
+	fs->location = location;
+
+	swim_drive(base, location);
+
+	swim_motor(base, OFF);
+
+	if (swim_readbit(base, SINGLE_SIDED))
+		fs->head_number = 1;
+	else
+		fs->head_number = 2;
+	fs->ref_count = 0;
+	fs->ejected = 1;
+
+	swd->floppy_count++;
+
+	return 0;
+}
+
+static int __devinit swim_floppy_init(struct swim_priv *swd)
+{
+	int err;
+	int drive;
+	struct swim __iomem *base = swd->base;
+
+	/* scan floppy drives */
+
+	swim_drive(base, INTERNAL_DRIVE);
+	if (swim_readbit(base, DRIVE_PRESENT))
+		swim_add_floppy(swd, INTERNAL_DRIVE);
+	swim_drive(base, EXTERNAL_DRIVE);
+	if (swim_readbit(base, DRIVE_PRESENT))
+		swim_add_floppy(swd, EXTERNAL_DRIVE);
+
+	/* register floppy drives */
+
+	err = register_blkdev(FLOPPY_MAJOR, "fd");
+	if (err) {
+		printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
+		       FLOPPY_MAJOR);
+		return -EBUSY;
+	}
+
+	for (drive = 0; drive < swd->floppy_count; drive++) {
+		swd->unit[drive].disk = alloc_disk(1);
+		if (swd->unit[drive].disk == NULL) {
+			err = -ENOMEM;
+			goto exit_put_disks;
+		}
+		swd->unit[drive].swd = swd;
+	}
+
+	swd->queue = blk_init_queue(do_fd_request, &swd->lock);
+	if (!swd->queue) {
+		err = -ENOMEM;
+		goto exit_put_disks;
+	}
+
+	for (drive = 0; drive < swd->floppy_count; drive++) {
+		swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
+		swd->unit[drive].disk->major = FLOPPY_MAJOR;
+		swd->unit[drive].disk->first_minor = drive;
+		sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
+		swd->unit[drive].disk->fops = &floppy_fops;
+		swd->unit[drive].disk->private_data = &swd->unit[drive];
+		swd->unit[drive].disk->queue = swd->queue;
+		set_capacity(swd->unit[drive].disk, 2880);
+		add_disk(swd->unit[drive].disk);
+	}
+
+	blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
+			    floppy_find, NULL, swd);
+
+	return 0;
+
+exit_put_disks:
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
+	while (drive--)
+		put_disk(swd->unit[drive].disk);
+	return err;
+}
+
+static int __devinit swim_probe(struct platform_device *dev)
+{
+	struct resource *res;
+	struct swim __iomem *swim_base;
+	struct swim_priv *swd;
+	int ret;
+
+	res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+	if (!res) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res), CARDNAME)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	swim_base = ioremap(res->start, resource_size(res));
+	if (!swim_base) {
+		return -ENOMEM;
+		goto out_release_io;
+	}
+
+	/* probe device */
+
+	set_swim_mode(swim_base, 1);
+	if (!get_swim_mode(swim_base)) {
+		printk(KERN_INFO "SWIM device not found !\n");
+		ret = -ENODEV;
+		goto out_iounmap;
+	}
+
+	/* set platform driver data */
+
+	swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
+	if (!swd) {
+		ret = -ENOMEM;
+		goto out_iounmap;
+	}
+	platform_set_drvdata(dev, swd);
+
+	swd->base = swim_base;
+
+	ret = swim_floppy_init(swd);
+	if (ret)
+		goto out_kfree;
+
+	return 0;
+
+out_kfree:
+	platform_set_drvdata(dev, NULL);
+	kfree(swd);
+out_iounmap:
+	iounmap(swim_base);
+out_release_io:
+	release_mem_region(res->start, resource_size(res));
+out:
+	return ret;
+}
+
+static int __devexit swim_remove(struct platform_device *dev)
+{
+	struct swim_priv *swd = platform_get_drvdata(dev);
+	int drive;
+	struct resource *res;
+
+	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+
+	for (drive = 0; drive < swd->floppy_count; drive++) {
+		del_gendisk(swd->unit[drive].disk);
+		put_disk(swd->unit[drive].disk);
+	}
+
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
+
+	blk_cleanup_queue(swd->queue);
+
+	/* eject floppies */
+
+	for (drive = 0; drive < swd->floppy_count; drive++)
+		floppy_eject(&swd->unit[drive]);
+
+	iounmap(swd->base);
+
+	res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+
+	platform_set_drvdata(dev, NULL);
+	kfree(swd);
+
+	return 0;
+}
+
+static struct platform_driver swim_driver = {
+	.probe  = swim_probe,
+	.remove = __devexit_p(swim_remove),
+	.driver   = {
+		.name	= CARDNAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init swim_init(void)
+{
+	printk(KERN_INFO "SWIM floppy driver %s\n", DRIVER_VERSION);
+
+	return platform_driver_register(&swim_driver);
+}
+module_init(swim_init);
+
+static void __exit swim_exit(void)
+{
+	platform_driver_unregister(&swim_driver);
+}
+module_exit(swim_exit);
+
+MODULE_DESCRIPTION("Driver for SWIM floppy controller");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laurent Vivier <laurent@lvivier.info>");
+MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/sx8.c linux-libre-2.6.30-gnu1/drivers/block/sx8.c
--- linux-libre-2.6.29-gnu1/drivers/block/sx8.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/sx8.c	2009-06-09 23:05:27.000000000 -0400
@@ -1586,9 +1586,9 @@ static int carm_init_one (struct pci_dev
 		goto err_out;
 
 #ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
-	rc = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!rc) {
-		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (rc) {
 			printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n",
 				pci_name(pdev));
@@ -1597,7 +1597,7 @@ static int carm_init_one (struct pci_dev
 		pci_dac = 1;
 	} else {
 #endif
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n",
 				pci_name(pdev));
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/ub.c linux-libre-2.6.30-gnu1/drivers/block/ub.c
--- linux-libre-2.6.29-gnu1/drivers/block/ub.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/ub.c	2009-06-09 23:05:27.000000000 -0400
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *s
  */
 #ifdef CONFIG_USB_LIBUSUAL
 
-#define ub_usb_ids  storage_usb_ids
+#define ub_usb_ids  usb_storage_usb_ids
 #else
 
 static struct usb_device_id ub_usb_ids[] = {
@@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_
 {
 	struct urb *urb = &sc->work_urb;
 	struct bulk_cs_wrap *bcs;
+	int endp;
 	int len;
 	int rc;
 
@@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_
 		return;
 	}
 
+	endp = usb_pipeendpoint(sc->last_pipe);
+	if (usb_pipein(sc->last_pipe))
+		endp |= USB_DIR_IN;
+
 	if (cmd->state == UB_CMDST_CLEAR) {
 		if (urb->status == -EPIPE) {
 			/*
@@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_sense(sc, cmd);
 
@@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_stat(sc, cmd);
 
@@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_
 		 * We ignore the result for the halt clear.
 		 */
 
-		/* reset the endpoint toggle */
-		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
-			usb_pipeout(sc->last_pipe), 0);
+		usb_reset_endpoint(sc->dev, endp);
 
 		ub_state_stat_counted(sc, cmd);
 
@@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct u
 	del_timer_sync(&timer);
 	usb_kill_urb(&sc->work_urb);
 
-	/* reset the endpoint toggle */
-	usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);
+	usb_reset_endpoint(sc->dev, endp);
 
 	return 0;
 }
@@ -2146,10 +2144,9 @@ static int ub_get_pipes(struct ub_dev *s
 		ep = &altsetting->endpoint[i].desc;
 
 		/* Is it a BULK endpoint? */
-		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-				== USB_ENDPOINT_XFER_BULK) {
+		if (usb_endpoint_xfer_bulk(ep)) {
 			/* BULK in or out? */
-			if (ep->bEndpointAddress & USB_DIR_IN) {
+			if (usb_endpoint_dir_in(ep)) {
 				if (ep_in == NULL)
 					ep_in = ep;
 			} else {
@@ -2168,9 +2165,9 @@ static int ub_get_pipes(struct ub_dev *s
 	sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);
 	sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);
 	sc->send_bulk_pipe = usb_sndbulkpipe(dev,
-		ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		usb_endpoint_num(ep_out));
 	sc->recv_bulk_pipe = usb_rcvbulkpipe(dev, 
-		ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		usb_endpoint_num(ep_in));
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/umem.c linux-libre-2.6.30-gnu1/drivers/block/umem.c
--- linux-libre-2.6.29-gnu1/drivers/block/umem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/umem.c	2009-06-09 23:05:27.000000000 -0400
@@ -829,8 +829,8 @@ static int __devinit mm_pci_probe(struct
 	dev_printk(KERN_INFO, &dev->dev,
 	  "Micro Memory(tm) controller found (PCI Mem Module (Battery Backup))\n");
 
-	if (pci_set_dma_mask(dev, DMA_64BIT_MASK) &&
-	    pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(dev, DMA_BIT_MASK(64)) &&
+	    pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
 		dev_printk(KERN_WARNING, &dev->dev, "NO suitable DMA found\n");
 		return  -ENOMEM;
 	}
@@ -906,6 +906,7 @@ static int __devinit mm_pci_probe(struct
 		goto failed_alloc;
 
 	blk_queue_make_request(card->queue, mm_make_request);
+	card->queue->queue_lock = &card->lock;
 	card->queue->queuedata = card;
 	card->queue->unplug_fn = mm_unplug_device;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/xen-blkfront.c linux-libre-2.6.30-gnu1/drivers/block/xen-blkfront.c
--- linux-libre-2.6.29-gnu1/drivers/block/xen-blkfront.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/xen-blkfront.c	2009-06-09 23:05:27.000000000 -0400
@@ -934,8 +934,6 @@ static void blkfront_closing(struct xenb
 
 	spin_lock_irqsave(&blkif_io_lock, flags);
 
-	del_gendisk(info->gd);
-
 	/* No more blkif_request(). */
 	blk_stop_queue(info->rq);
 
@@ -949,6 +947,8 @@ static void blkfront_closing(struct xenb
 	blk_cleanup_queue(info->rq);
 	info->rq = NULL;
 
+	del_gendisk(info->gd);
+
  out:
 	xenbus_frontend_closed(dev);
 }
@@ -977,8 +977,10 @@ static void backend_changed(struct xenbu
 		break;
 
 	case XenbusStateClosing:
-		if (info->gd == NULL)
-			xenbus_dev_fatal(dev, -ENODEV, "gd is NULL");
+		if (info->gd == NULL) {
+			xenbus_frontend_closed(dev);
+			break;
+		}
 		bd = bdget_disk(info->gd, 0);
 		if (bd == NULL)
 			xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
diff -druNp linux-libre-2.6.29-gnu1/drivers/block/xsysace.c linux-libre-2.6.30-gnu1/drivers/block/xsysace.c
--- linux-libre-2.6.29-gnu1/drivers/block/xsysace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/block/xsysace.c	2009-06-09 23:05:27.000000000 -0400
@@ -89,6 +89,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/ata.h>
 #include <linux/hdreg.h>
 #include <linux/platform_device.h>
 #if defined(CONFIG_OF)
@@ -208,7 +209,7 @@ struct ace_device {
 	struct gendisk *gd;
 
 	/* Inserted CF card parameters */
-	struct hd_driveid cf_id;
+	u16 cf_id[ATA_ID_WORDS];
 };
 
 static int ace_major;
@@ -402,21 +403,14 @@ static void ace_dump_regs(struct ace_dev
 		 ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
 }
 
-void ace_fix_driveid(struct hd_driveid *id)
+void ace_fix_driveid(u16 *id)
 {
 #if defined(__BIG_ENDIAN)
-	u16 *buf = (void *)id;
 	int i;
 
 	/* All half words have wrong byte order; swap the bytes */
-	for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
-		*buf = le16_to_cpu(*buf);
-
-	/* Some of the data values are 32bit; swap the half words  */
-	id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
-	    ((id->lba_capacity << 16) & 0xFFFF0000);
-	id->spg = ((id->spg >> 16) & 0x0000FFFF) |
-	    ((id->spg << 16) & 0xFFFF0000);
+	for (i = 0; i < ATA_ID_WORDS; i++, id++)
+		*id = le16_to_cpu(*id);
 #endif
 }
 
@@ -569,7 +563,7 @@ static void ace_fsm_dostate(struct ace_d
 	case ACE_FSM_STATE_IDENTIFY_PREPARE:
 		/* Send identify command */
 		ace->fsm_task = ACE_TASK_IDENTIFY;
-		ace->data_ptr = &ace->cf_id;
+		ace->data_ptr = ace->cf_id;
 		ace->data_count = ACE_BUF_PER_SECTOR;
 		ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY);
 
@@ -614,8 +608,8 @@ static void ace_fsm_dostate(struct ace_d
 		break;
 
 	case ACE_FSM_STATE_IDENTIFY_COMPLETE:
-		ace_fix_driveid(&ace->cf_id);
-		ace_dump_mem(&ace->cf_id, 512);	/* Debug: Dump out disk ID */
+		ace_fix_driveid(ace->cf_id);
+		ace_dump_mem(ace->cf_id, 512);	/* Debug: Dump out disk ID */
 
 		if (ace->data_result) {
 			/* Error occured, disable the disk */
@@ -627,9 +621,10 @@ static void ace_fsm_dostate(struct ace_d
 			ace->media_change = 0;
 
 			/* Record disk parameters */
-			set_capacity(ace->gd, ace->cf_id.lba_capacity);
+			set_capacity(ace->gd,
+				ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
 			dev_info(ace->dev, "capacity: %i sectors\n",
-				 ace->cf_id.lba_capacity);
+				ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY));
 		}
 
 		/* We're done, drop to IDLE state and notify waiters */
@@ -928,12 +923,13 @@ static int ace_release(struct gendisk *d
 static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	struct ace_device *ace = bdev->bd_disk->private_data;
+	u16 *cf_id = ace->cf_id;
 
 	dev_dbg(ace->dev, "ace_getgeo()\n");
 
-	geo->heads = ace->cf_id.heads;
-	geo->sectors = ace->cf_id.sectors;
-	geo->cylinders = ace->cf_id.cyls;
+	geo->heads	= cf_id[ATA_ID_HEADS];
+	geo->sectors	= cf_id[ATA_ID_SECTORS];
+	geo->cylinders	= cf_id[ATA_ID_CYLS];
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/bluetooth/bfusb.c linux-libre-2.6.30-gnu1/drivers/bluetooth/bfusb.c
--- linux-libre-2.6.29-gnu1/drivers/bluetooth/bfusb.c	2013-05-03 18:05:19.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/bluetooth/bfusb.c	2013-05-03 16:49:19.000000000 -0400
@@ -257,8 +257,7 @@ static inline int bfusb_recv_block(struc
 
 	if (hdr & 0x10) {
 		BT_ERR("%s error in block", data->hdev->name);
-		if (data->reassembly)
-			kfree_skb(data->reassembly);
+		kfree_skb(data->reassembly);
 		data->reassembly = NULL;
 		return -EIO;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/bluetooth/bt3c_cs.c linux-libre-2.6.30-gnu1/drivers/bluetooth/bt3c_cs.c
--- linux-libre-2.6.29-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 18:05:21.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/bluetooth/bt3c_cs.c	2013-05-03 16:49:21.000000000 -0400
@@ -359,9 +359,9 @@ static irqreturn_t bt3c_interrupt(int ir
 			BT_ERR("Very strange (stat=0x%04x)", stat);
 		} else if ((stat & 0xff) != 0xff) {
 			if (stat & 0x0020) {
-				int stat = bt3c_read(iobase, 0x7002) & 0x10;
+				int status = bt3c_read(iobase, 0x7002) & 0x10;
 				BT_INFO("%s: Antenna %s", info->hdev->name,
-							stat ? "out" : "in");
+							status ? "out" : "in");
 			}
 			if (stat & 0x0001)
 				bt3c_receive(info);
diff -druNp linux-libre-2.6.29-gnu1/drivers/bluetooth/btusb.c linux-libre-2.6.30-gnu1/drivers/bluetooth/btusb.c
--- linux-libre-2.6.29-gnu1/drivers/bluetooth/btusb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/bluetooth/btusb.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-#define VERSION "0.4"
+#define VERSION "0.5"
 
 static int ignore_dga;
 static int ignore_csr;
@@ -171,6 +171,7 @@ struct btusb_data {
 
 	__u8 cmdreq_type;
 
+	unsigned int sco_num;
 	int isoc_altsetting;
 	int suspend_count;
 };
@@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hd
 		return 0;
 
 	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
+	if (err < 0)
+		goto failed;
+
+	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
 	if (err < 0) {
-		clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-		clear_bit(HCI_RUNNING, &hdev->flags);
+		usb_kill_anchored_urbs(&data->intr_anchor);
+		goto failed;
 	}
 
+	set_bit(BTUSB_BULK_RUNNING, &data->flags);
+	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
+
+	return 0;
+
+failed:
+	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+	clear_bit(HCI_RUNNING, &hdev->flags);
 	return err;
 }
 
@@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev
 
 	BT_DBG("%s evt %d", hdev->name, evt);
 
-	if (hdev->conn_hash.acl_num > 0) {
-		if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-			if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
-				clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-			else
-				btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
-		}
-	} else {
-		clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-		usb_unlink_anchored_urbs(&data->bulk_anchor);
+	if (hdev->conn_hash.sco_num != data->sco_num) {
+		data->sco_num = hdev->conn_hash.sco_num;
+		schedule_work(&data->work);
 	}
-
-	schedule_work(&data->work);
 }
 
 static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
@@ -982,9 +986,11 @@ static int btusb_resume(struct usb_inter
 	}
 
 	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-		if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
+		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+		if (err < 0) {
 			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-		else
+			return err;
+		} else
 			btusb_submit_bulk_urb(hdev, GFP_NOIO);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/bluetooth/hci_h4.c linux-libre-2.6.30-gnu1/drivers/bluetooth/hci_h4.c
--- linux-libre-2.6.29-gnu1/drivers/bluetooth/hci_h4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/bluetooth/hci_h4.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,8 +102,7 @@ static int h4_close(struct hci_uart *hu)
 
 	skb_queue_purge(&h4->txq);
 
-	if (h4->rx_skb)
-		kfree_skb(h4->rx_skb);
+	kfree_skb(h4->rx_skb);
 
 	hu->priv = NULL;
 	kfree(h4);
diff -druNp linux-libre-2.6.29-gnu1/drivers/bluetooth/hci_ll.c linux-libre-2.6.30-gnu1/drivers/bluetooth/hci_ll.c
--- linux-libre-2.6.29-gnu1/drivers/bluetooth/hci_ll.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/bluetooth/hci_ll.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,8 +163,7 @@ static int ll_close(struct hci_uart *hu)
 	skb_queue_purge(&ll->tx_wait_q);
 	skb_queue_purge(&ll->txq);
 
-	if (ll->rx_skb)
-		kfree_skb(ll->rx_skb);
+	kfree_skb(ll->rx_skb);
 
 	hu->priv = NULL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/cdrom/viocd.c linux-libre-2.6.30-gnu1/drivers/cdrom/viocd.c
--- linux-libre-2.6.29-gnu1/drivers/cdrom/viocd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cdrom/viocd.c	2009-06-09 23:05:27.000000000 -0400
@@ -587,7 +587,7 @@ static int viocd_probe(struct vio_dev *v
 	struct device_node *node = vdev->dev.archdata.of_node;
 
 	deviceno = vdev->unit_address;
-	if (deviceno > VIOCD_MAX_CD)
+	if (deviceno >= VIOCD_MAX_CD)
 		return -ENODEV;
 	if (!node)
 		return -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/agp/generic.c linux-libre-2.6.30-gnu1/drivers/char/agp/generic.c
--- linux-libre-2.6.29-gnu1/drivers/char/agp/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/agp/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_b
 	int i, ret = -ENOMEM;
 
 	for (i = 0; i < num_pages; i++) {
-		page = alloc_page(GFP_KERNEL | GFP_DMA32);
+		page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
 		/* agp_free_memory() needs gart address */
 		if (page == NULL)
 			goto out;
@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_
 {
 	struct page * page;
 
-	page = alloc_page(GFP_KERNEL | GFP_DMA32);
+	page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
 	if (page == NULL)
 		return NULL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/agp/intel-agp.c linux-libre-2.6.30-gnu1/drivers/char/agp/intel-agp.c
--- linux-libre-2.6.29-gnu1/drivers/char/agp/intel-agp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/agp/intel-agp.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,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_G33_HB          0x29C0
 #define PCI_DEVICE_ID_INTEL_G33_IG          0x29C2
 #define PCI_DEVICE_ID_INTEL_Q35_HB          0x29B0
@@ -60,7 +64,12 @@
 
 #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_Q33_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
+		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_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_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
 		agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
@@ -510,7 +519,7 @@ static void intel_i830_init_gtt_entries(
 			size = 512;
 		}
 		size += 4; /* add in BIOS popup space */
-	} else if (IS_G33) {
+	} else if (IS_G33 && !IS_IGD) {
 	/* G33's GTT size defined in gmch_ctrl */
 		switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
 		case G33_PGETBL_SIZE_1M:
@@ -526,7 +535,7 @@ static void intel_i830_init_gtt_entries(
 			size = 512;
 		}
 		size += 4;
-	} else if (IS_G4X) {
+	} else if (IS_G4X || IS_IGD) {
 		/* 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.
@@ -2122,6 +2131,8 @@ static const struct intel_driver_descrip
 	{ PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M",
 		&intel_845_driver, &intel_830_driver },
 	{ PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL },
+	{ PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, 0, "854",
+		&intel_845_driver, &intel_830_driver },
 	{ PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL },
 	{ PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM",
 		&intel_845_driver, &intel_830_driver },
@@ -2161,6 +2172,10 @@ 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",
+		NULL, &intel_g33_driver },
+	{ PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+		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,
@@ -2342,6 +2357,7 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_82845_HB),
 	ID(PCI_DEVICE_ID_INTEL_82845G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82850_HB),
+	ID(PCI_DEVICE_ID_INTEL_82854_HB),
 	ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82860_HB),
@@ -2355,6 +2371,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_82946GZ_HB),
 	ID(PCI_DEVICE_ID_INTEL_82G35_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/amiserial.c linux-libre-2.6.30-gnu1/drivers/char/amiserial.c
--- linux-libre-2.6.29-gnu1/drivers/char/amiserial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/amiserial.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,6 +79,7 @@ static char *serial_version = "4.30";
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
@@ -1825,14 +1826,13 @@ static int rs_open(struct tty_struct *tt
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
 {
 	struct async_struct *info = state->info, scr_info;
 	char	stat_buf[30], control, status;
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%d: uart:amiga_builtin",state->line);
+	seq_printf(m, "%d: uart:amiga_builtin",state->line);
 
 	/*
 	 * Figure out the current RS-232 lines
@@ -1864,55 +1864,49 @@ static inline int line_info(char *buf, s
 		strcat(stat_buf, "|CD");
 
 	if (info->quot) {
-		ret += sprintf(buf+ret, " baud:%d",
-			       state->baud_base / info->quot);
+		seq_printf(m, " baud:%d", state->baud_base / info->quot);
 	}
 
-	ret += sprintf(buf+ret, " tx:%d rx:%d",
-		      state->icount.tx, state->icount.rx);
+	seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
 
 	if (state->icount.frame)
-		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+		seq_printf(m, " fe:%d", state->icount.frame);
 
 	if (state->icount.parity)
-		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+		seq_printf(m, " pe:%d", state->icount.parity);
 
 	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+		seq_printf(m, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
-		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+		seq_printf(m, " oe:%d", state->icount.overrun);
 
 	/*
 	 * Last thing is the RS-232 status lines
 	 */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
-	return ret;
+	seq_printf(m, " %s\n", stat_buf+1);
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
+	seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+	line_info(m, &rs_table[0]);
+	return 0;
+}
 
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	l = line_info(page + len, &rs_table[0]);
-	len += l;
-	if (len+begin > off+count)
-	  goto done;
-	if (len+begin < off) {
-	  begin += len;
-	  len = 0;
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
 }
 
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * ---------------------------------------------------------------------
  * rs_init() and friends
@@ -1951,9 +1945,9 @@ static const struct tty_operations seria
 	.break_ctl = rs_break,
 	.send_xchar = rs_send_xchar,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc,
 	.tiocmget = rs_tiocmget,
 	.tiocmset = rs_tiocmset,
+	.proc_fops = &rs_proc_fops,
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/applicom.c linux-libre-2.6.30-gnu1/drivers/char/applicom.c
--- linux-libre-2.6.29-gnu1/drivers/char/applicom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/applicom.c	2009-06-09 23:05:27.000000000 -0400
@@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(pci, applicom_pci_tb
 MODULE_AUTHOR("David Woodhouse & Applicom International");
 MODULE_DESCRIPTION("Driver for Applicom Profibus card");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(AC_MINOR);
 
 MODULE_SUPPORTED_DEVICE("ac");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/bsr.c linux-libre-2.6.30-gnu1/drivers/char/bsr.c
--- linux-libre-2.6.29-gnu1/drivers/char/bsr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/bsr.c	2009-06-09 23:05:27.000000000 -0400
@@ -140,7 +140,7 @@ static int bsr_open(struct inode * inode
 	return 0;
 }
 
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
 	.owner = THIS_MODULE,
 	.mmap  = bsr_mmap,
 	.open  = bsr_open,
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/cyclades.c linux-libre-2.6.30-gnu1/drivers/char/cyclades.c
--- linux-libre-2.6.29-gnu1/drivers/char/cyclades.c	2013-05-03 18:00:07.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/cyclades.c	2013-05-03 16:43:57.000000000 -0400
@@ -646,6 +646,7 @@
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/firmware.h>
+#include <linux/device.h>
 
 #include <asm/system.h>
 #include <linux/io.h>
@@ -657,6 +658,7 @@
 
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 static void cy_throttle(struct tty_struct *tty);
 static void cy_send_xchar(struct tty_struct *tty, char ch);
@@ -868,8 +870,6 @@ static int cyz_issue_cmd(struct cyclades
 static unsigned detect_isa_irq(void __iomem *);
 #endif				/* CONFIG_ISA */
 
-static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
-
 #ifndef CONFIG_CYZ_INTR
 static void cyz_poll(unsigned long);
 
@@ -5216,31 +5216,22 @@ static struct pci_driver cy_pci_driver =
 };
 #endif
 
-static int
-cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
-		int *eof, void *data)
+static int cyclades_proc_show(struct seq_file *m, void *v)
 {
 	struct cyclades_port *info;
 	unsigned int i, j;
-	int len = 0;
-	off_t begin = 0;
-	off_t pos = 0;
-	int size;
 	__u32 cur_jifs = jiffies;
 
-	size = sprintf(buf, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   "
+	seq_puts(m, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   "
 			"IdleIn  Overruns  Ldisc\n");
 
-	pos += size;
-	len += size;
-
 	/* Output one line for each known port */
 	for (i = 0; i < NR_CARDS; i++)
 		for (j = 0; j < cy_card[i].nports; j++) {
 			info = &cy_card[i].ports[j];
 
 			if (info->port.count)
-				size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+				seq_printf(m, "%3d %8lu %10lu %8lu "
 					"%10lu %8lu %9lu %6ld\n", info->line,
 					(cur_jifs - info->idle_stats.in_use) /
 					HZ, info->idle_stats.xmit_bytes,
@@ -5251,30 +5242,26 @@ cyclades_get_proc_info(char *buf, char *
 					/* FIXME: double check locking */
 					(long)info->port.tty->ldisc.ops->num);
 			else
-				size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+				seq_printf(m, "%3d %8lu %10lu %8lu "
 					"%10lu %8lu %9lu %6ld\n",
 					info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
-			len += size;
-			pos = begin + len;
-
-			if (pos < offset) {
-				len = 0;
-				begin = pos;
-			}
-			if (pos > offset + length)
-				goto done;
 		}
-	*eof = 1;
-done:
-	*start = buf + (offset - begin);	/* Start of wanted data */
-	len -= (offset - begin);	/* Start slop */
-	if (len > length)
-		len = length;	/* Ending slop */
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
+}
+
+static int cyclades_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cyclades_proc_show, NULL);
 }
 
+static const struct file_operations cyclades_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= cyclades_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* The serial driver boot-time initialization code!
     Hardware I/O ports are mapped to character special devices on a
     first found, first allocated manner.  That is, this code searches
@@ -5311,9 +5298,9 @@ static const struct tty_operations cy_op
 	.hangup = cy_hangup,
 	.break_ctl = cy_break,
 	.wait_until_sent = cy_wait_until_sent,
-	.read_proc = cyclades_get_proc_info,
 	.tiocmget = cy_tiocmget,
 	.tiocmset = cy_tiocmset,
+	.proc_fops = &cyclades_proc_fops,
 };
 
 static int __init cy_init(void)
@@ -5422,3 +5409,4 @@ module_exit(cy_cleanup_module);
 
 MODULE_LICENSE("GPL");
 MODULE_VERSION(CY_VERSION);
+MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/esp.c linux-libre-2.6.30-gnu1/drivers/char/esp.c
--- linux-libre-2.6.29-gnu1/drivers/char/esp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/esp.c	2009-06-09 23:05:27.000000000 -0400
@@ -2258,7 +2258,7 @@ static int esp_open(struct tty_struct *t
  * driver.
  */
 
-static void show_serial_version(void)
+static void __init show_serial_version(void)
 {
 	printk(KERN_INFO "%s version %s (DMA %u)\n",
 		serial_name, serial_version, dma);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hpet.c linux-libre-2.6.30-gnu1/drivers/char/hpet.c
--- linux-libre-2.6.29-gnu1/drivers/char/hpet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hpet.c	2009-06-09 23:05:27.000000000 -0400
@@ -72,7 +72,7 @@ static u32 hpet_nhpet, hpet_max_freq = H
 #ifdef CONFIG_IA64
 static void __iomem *hpet_mctr;
 
-static cycle_t read_hpet(void)
+static cycle_t read_hpet(struct clocksource *cs)
 {
 	return (cycle_t)read_counter((void __iomem *)hpet_mctr);
 }
@@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_h
  */
 #define	TICK_CALIBRATE	(1000UL)
 
-static unsigned long hpet_calibrate(struct hpets *hpetp)
+static unsigned long __hpet_calibrate(struct hpets *hpetp)
 {
 	struct hpet_timer __iomem *timer = NULL;
 	unsigned long t, m, count, i, flags, start;
@@ -750,6 +750,26 @@ static unsigned long hpet_calibrate(stru
 	return (m - start) / i;
 }
 
+static unsigned long hpet_calibrate(struct hpets *hpetp)
+{
+	unsigned long ret = -1;
+	unsigned long tmp;
+
+	/*
+	 * Try to calibrate until return value becomes stable small value.
+	 * If SMI interruption occurs in calibration loop, the return value
+	 * will be big. This avoids its impact.
+	 */
+	for ( ; ; ) {
+		tmp = __hpet_calibrate(hpetp);
+		if (ret <= tmp)
+			break;
+		ret = tmp;
+	}
+
+	return ret;
+}
+
 int hpet_alloc(struct hpet_data *hdp)
 {
 	u64 cap, mcfg;
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hvc_iucv.c linux-libre-2.6.30-gnu1/drivers/char/hvc_iucv.c
--- linux-libre-2.6.29-gnu1/drivers/char/hvc_iucv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hvc_iucv.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,10 +13,11 @@
 
 #include <linux/types.h>
 #include <asm/ebcdic.h>
+#include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/mempool.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/tty.h>
 #include <linux/wait.h>
 #include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices =
 /* Array of allocated hvc iucv tty lines... */
 static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
 #define IUCV_HVC_CON_IDX	(0)
+/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
+#define MAX_VMID_FILTER		(500)
+static size_t hvc_iucv_filter_size;
+static void *hvc_iucv_filter;
+static const char *hvc_iucv_filter_string;
+static DEFINE_RWLOCK(hvc_iucv_filter_lock);
 
 /* Kmem cache and mempool for iucv_tty_buffer elements */
 static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct
 }
 
 /**
+ * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
+ * @ipvmid:	Originating z/VM user ID (right padded with blanks)
+ *
+ * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
+ * non-zero.
+ */
+static int hvc_iucv_filter_connreq(u8 ipvmid[8])
+{
+	size_t i;
+
+	/* Note: default policy is ACCEPT if no filter is set */
+	if (!hvc_iucv_filter_size)
+		return 0;
+
+	for (i = 0; i < hvc_iucv_filter_size; i++)
+		if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+			return 0;
+	return 1;
+}
+
+/**
  * hvc_iucv_path_pending() - IUCV handler to process a connection request.
  * @path:	Pending path (struct iucv_path)
  * @ipvmid:	z/VM system identifier of originator
@@ -641,6 +669,7 @@ static	int hvc_iucv_path_pending(struct
 {
 	struct hvc_iucv_private *priv;
 	u8 nuser_data[16];
+	u8 vm_user_id[9];
 	int i, rc;
 
 	priv = NULL;
@@ -653,6 +682,20 @@ static	int hvc_iucv_path_pending(struct
 	if (!priv)
 		return -ENODEV;
 
+	/* Enforce that ipvmid is allowed to connect to us */
+	read_lock(&hvc_iucv_filter_lock);
+	rc = hvc_iucv_filter_connreq(ipvmid);
+	read_unlock(&hvc_iucv_filter_lock);
+	if (rc) {
+		iucv_path_sever(path, ipuser);
+		iucv_path_free(path);
+		memcpy(vm_user_id, ipvmid, 8);
+		vm_user_id[8] = 0;
+		pr_info("A connection request from z/VM user ID %s "
+			"was refused\n", vm_user_id);
+		return 0;
+	}
+
 	spin_lock(&priv->lock);
 
 	/* If the terminal is already connected or being severed, then sever
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id,
 }
 
 /**
+ * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
+ * @filter:	String containing a comma-separated list of z/VM user IDs
+ */
+static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
+{
+	const char *nextdelim, *residual;
+	size_t len;
+
+	nextdelim = strchr(filter, ',');
+	if (nextdelim) {
+		len = nextdelim - filter;
+		residual = nextdelim + 1;
+	} else {
+		len = strlen(filter);
+		residual = filter + len;
+	}
+
+	if (len == 0)
+		return ERR_PTR(-EINVAL);
+
+	/* check for '\n' (if called from sysfs) */
+	if (filter[len - 1] == '\n')
+		len--;
+
+	if (len > 8)
+		return ERR_PTR(-EINVAL);
+
+	/* pad with blanks and save upper case version of user ID */
+	memset(dest, ' ', 8);
+	while (len--)
+		dest[len] = toupper(filter[len]);
+	return residual;
+}
+
+/**
+ * hvc_iucv_setup_filter() - Set up z/VM user ID filter
+ * @filter:	String consisting of a comma-separated list of z/VM user IDs
+ *
+ * The function parses the @filter string and creates an array containing
+ * the list of z/VM user ID filter entries.
+ * Return code 0 means success, -EINVAL if the filter is syntactically
+ * incorrect, -ENOMEM if there was not enough memory to allocate the
+ * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
+ */
+static int hvc_iucv_setup_filter(const char *val)
+{
+	const char *residual;
+	int err;
+	size_t size, count;
+	void *array, *old_filter;
+
+	count = strlen(val);
+	if (count == 0 || (count == 1 && val[0] == '\n')) {
+		size  = 0;
+		array = NULL;
+		goto out_replace_filter;	/* clear filter */
+	}
+
+	/* count user IDs in order to allocate sufficient memory */
+	size = 1;
+	residual = val;
+	while ((residual = strchr(residual, ',')) != NULL) {
+		residual++;
+		size++;
+	}
+
+	/* check if the specified list exceeds the filter limit */
+	if (size > MAX_VMID_FILTER)
+		return -ENOSPC;
+
+	array = kzalloc(size * 8, GFP_KERNEL);
+	if (!array)
+		return -ENOMEM;
+
+	count = size;
+	residual = val;
+	while (*residual && count) {
+		residual = hvc_iucv_parse_filter(residual,
+						 array + ((size - count) * 8));
+		if (IS_ERR(residual)) {
+			err = PTR_ERR(residual);
+			kfree(array);
+			goto out_err;
+		}
+		count--;
+	}
+
+out_replace_filter:
+	write_lock_bh(&hvc_iucv_filter_lock);
+	old_filter = hvc_iucv_filter;
+	hvc_iucv_filter_size = size;
+	hvc_iucv_filter = array;
+	write_unlock_bh(&hvc_iucv_filter_lock);
+	kfree(old_filter);
+
+	err = 0;
+out_err:
+	return err;
+}
+
+/**
+ * param_set_vmidfilter() - Set z/VM user ID filter parameter
+ * @val:	String consisting of a comma-separated list of z/VM user IDs
+ * @kp:		Kernel parameter pointing to hvc_iucv_filter array
+ *
+ * The function sets up the z/VM user ID filter specified as comma-separated
+ * list of user IDs in @val.
+ * Note: If it is called early in the boot process, @val is stored and
+ *	 parsed later in hvc_iucv_init().
+ */
+static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
+{
+	int rc;
+
+	if (!MACHINE_IS_VM || !hvc_iucv_devices)
+		return -ENODEV;
+
+	if (!val)
+		return -EINVAL;
+
+	rc = 0;
+	if (slab_is_available())
+		rc = hvc_iucv_setup_filter(val);
+	else
+		hvc_iucv_filter_string = val;	/* defer... */
+	return rc;
+}
+
+/**
+ * param_get_vmidfilter() - Get z/VM user ID filter
+ * @buffer:	Buffer to store z/VM user ID filter,
+ *		(buffer size assumption PAGE_SIZE)
+ * @kp:		Kernel parameter pointing to the hvc_iucv_filter array
+ *
+ * The function stores the filter as a comma-separated list of z/VM user IDs
+ * in @buffer. Typically, sysfs routines call this function for attr show.
+ */
+static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
+{
+	int rc;
+	size_t index, len;
+	void *start, *end;
+
+	if (!MACHINE_IS_VM || !hvc_iucv_devices)
+		return -ENODEV;
+
+	rc = 0;
+	read_lock_bh(&hvc_iucv_filter_lock);
+	for (index = 0; index < hvc_iucv_filter_size; index++) {
+		start = hvc_iucv_filter + (8 * index);
+		end   = memchr(start, ' ', 8);
+		len   = (end) ? end - start : 8;
+		memcpy(buffer + rc, start, len);
+		rc += len;
+		buffer[rc++] = ',';
+	}
+	read_unlock_bh(&hvc_iucv_filter_lock);
+	if (rc)
+		buffer[--rc] = '\0';	/* replace last comma and update rc */
+	return rc;
+}
+
+#define param_check_vmidfilter(name, p) __param_check(name, p, void)
+
+/**
  * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
  */
 static int __init hvc_iucv_init(void)
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
 	int rc;
 	unsigned int i;
 
+	if (!hvc_iucv_devices)
+		return -ENODEV;
+
 	if (!MACHINE_IS_VM) {
-		pr_info("The z/VM IUCV HVC device driver cannot "
+		pr_notice("The z/VM IUCV HVC device driver cannot "
 			   "be used without z/VM\n");
-		return -ENODEV;
+		rc = -ENODEV;
+		goto out_error;
 	}
 
-	if (!hvc_iucv_devices)
-		return -ENODEV;
+	if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
+		pr_err("%lu is not a valid value for the hvc_iucv= "
+			"kernel parameter\n", hvc_iucv_devices);
+		rc = -EINVAL;
+		goto out_error;
+	}
 
-	if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
-		return -EINVAL;
+	/* parse hvc_iucv_allow string and create z/VM user ID filter list */
+	if (hvc_iucv_filter_string) {
+		rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
+		switch (rc) {
+		case 0:
+			break;
+		case -ENOMEM:
+			pr_err("Allocating memory failed with "
+				"reason code=%d\n", 3);
+			goto out_error;
+		case -EINVAL:
+			pr_err("hvc_iucv_allow= does not specify a valid "
+				"z/VM user ID list\n");
+			goto out_error;
+		case -ENOSPC:
+			pr_err("hvc_iucv_allow= specifies too many "
+				"z/VM user IDs\n");
+			goto out_error;
+		default:
+			goto out_error;
+		}
+	}
 
 	hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
 					   sizeof(struct iucv_tty_buffer),
 					   0, 0, NULL);
 	if (!hvc_iucv_buffer_cache) {
 		pr_err("Allocating memory failed with reason code=%d\n", 1);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out_error;
 	}
 
 	hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
 	if (!hvc_iucv_mempool) {
 		pr_err("Allocating memory failed with reason code=%d\n", 2);
 		kmem_cache_destroy(hvc_iucv_buffer_cache);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out_error;
 	}
 
 	/* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
 out_error_memory:
 	mempool_destroy(hvc_iucv_mempool);
 	kmem_cache_destroy(hvc_iucv_buffer_cache);
+out_error:
+	hvc_iucv_devices = 0; /* ensure that we do not provide any device */
 	return rc;
 }
 
@@ -968,3 +1208,4 @@ static	int __init hvc_iucv_config(char *
 
 device_initcall(hvc_iucv_init);
 __setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hw_random/Kconfig linux-libre-2.6.30-gnu1/drivers/char/hw_random/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/char/hw_random/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hw_random/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,20 @@ config HW_RANDOM
 
 	  If unsure, say Y.
 
+config HW_RANDOM_TIMERIOMEM
+	tristate "Timer IOMEM HW Random Number Generator support"
+	depends on HW_RANDOM && HAS_IOMEM
+	---help---
+	  This driver provides kernel-side support for a generic Random
+	  Number Generator used by reading a 'dumb' iomem address that
+	  is to be read no faster than, for example, once a second;
+	  the default FPGA bitstream on the TS-7800 has such functionality.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called timeriomem-rng.
+
+	  If unsure, say Y.
+
 config HW_RANDOM_INTEL
 	tristate "Intel HW Random Number Generator support"
 	depends on HW_RANDOM && (X86 || IA64) && PCI
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hw_random/Makefile linux-libre-2.6.30-gnu1/drivers/char/hw_random/Makefile
--- linux-libre-2.6.29-gnu1/drivers/char/hw_random/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hw_random/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_HW_RANDOM) += rng-core.o
 rng-core-y := core.o
+obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
 obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
 obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
 obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hw_random/omap-rng.c linux-libre-2.6.30-gnu1/drivers/char/hw_random/omap-rng.c
--- linux-libre-2.6.29-gnu1/drivers/char/hw_random/omap-rng.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hw_random/omap-rng.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct
 		return -EBUSY;
 
 	if (cpu_is_omap24xx()) {
-		rng_ick = clk_get(&pdev->dev, "rng_ick");
+		rng_ick = clk_get(&pdev->dev, "ick");
 		if (IS_ERR(rng_ick)) {
 			dev_err(&pdev->dev, "Could not get rng_ick\n");
 			ret = PTR_ERR(rng_ick);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hw_random/timeriomem-rng.c linux-libre-2.6.30-gnu1/drivers/char/hw_random/timeriomem-rng.c
--- linux-libre-2.6.29-gnu1/drivers/char/hw_random/timeriomem-rng.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/char/hw_random/timeriomem-rng.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,182 @@
+/*
+ * drivers/char/hw_random/timeriomem-rng.c
+ *
+ * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk>
+ *
+ * Derived from drivers/char/hw_random/omap-rng.c
+ *   Copyright 2005 (c) MontaVista Software, Inc.
+ *   Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Overview:
+ *   This driver is useful for platforms that have an IO range that provides
+ *   periodic random data from a single IO memory address.  All the platform
+ *   has to do is provide the address and 'wait time' that new data becomes
+ *   available.
+ *
+ * TODO: add support for reading sizes other than 32bits and masking
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/timeriomem-rng.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+
+static struct timeriomem_rng_data *timeriomem_rng_data;
+
+static void timeriomem_rng_trigger(unsigned long);
+static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0);
+
+/*
+ * have data return 1, however return 0 if we have nothing
+ */
+static int timeriomem_rng_data_present(struct hwrng *rng, int wait)
+{
+	if (rng->priv == 0)
+		return 1;
+
+	if (!wait || timeriomem_rng_data->present)
+		return timeriomem_rng_data->present;
+
+	wait_for_completion(&timeriomem_rng_data->completion);
+
+	return 1;
+}
+
+static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	unsigned long cur;
+	s32 delay;
+
+	*data = readl(timeriomem_rng_data->address);
+
+	if (rng->priv != 0) {
+		cur = jiffies;
+
+		delay = cur - timeriomem_rng_timer.expires;
+		delay = rng->priv - (delay % rng->priv);
+
+		timeriomem_rng_timer.expires = cur + delay;
+		timeriomem_rng_data->present = 0;
+
+		init_completion(&timeriomem_rng_data->completion);
+		add_timer(&timeriomem_rng_timer);
+	}
+
+	return 4;
+}
+
+static void timeriomem_rng_trigger(unsigned long dummy)
+{
+	timeriomem_rng_data->present = 1;
+	complete(&timeriomem_rng_data->completion);
+}
+
+static struct hwrng timeriomem_rng_ops = {
+	.name		= "timeriomem",
+	.data_present	= timeriomem_rng_data_present,
+	.data_read	= timeriomem_rng_data_read,
+	.priv		= 0,
+};
+
+static int __init timeriomem_rng_probe(struct platform_device *pdev)
+{
+	struct resource *res, *mem;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res)
+		return -ENOENT;
+
+	mem = request_mem_region(res->start, res->end - res->start + 1,
+				 pdev->name);
+	if (mem == NULL)
+		return -EBUSY;
+
+	dev_set_drvdata(&pdev->dev, mem);
+
+	timeriomem_rng_data = pdev->dev.platform_data;
+
+	timeriomem_rng_data->address = ioremap(res->start,
+						res->end - res->start + 1);
+	if (!timeriomem_rng_data->address) {
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	if (timeriomem_rng_data->period != 0
+		&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
+		timeriomem_rng_timer.expires = jiffies;
+
+		timeriomem_rng_ops.priv = usecs_to_jiffies(
+						timeriomem_rng_data->period);
+	}
+	timeriomem_rng_data->present = 1;
+
+	ret = hwrng_register(&timeriomem_rng_ops);
+	if (ret)
+		goto err_register;
+
+	dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
+			timeriomem_rng_data->address,
+			timeriomem_rng_data->period);
+
+	return 0;
+
+err_register:
+	dev_err(&pdev->dev, "problem registering\n");
+	iounmap(timeriomem_rng_data->address);
+err_ioremap:
+	release_resource(mem);
+
+	return ret;
+}
+
+static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
+{
+	struct resource *mem = dev_get_drvdata(&pdev->dev);
+
+	del_timer_sync(&timeriomem_rng_timer);
+	hwrng_unregister(&timeriomem_rng_ops);
+
+	iounmap(timeriomem_rng_data->address);
+	release_resource(mem);
+
+	return 0;
+}
+
+static struct platform_driver timeriomem_rng_driver = {
+	.driver = {
+		.name		= "timeriomem_rng",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= timeriomem_rng_probe,
+	.remove		= __devexit_p(timeriomem_rng_remove),
+};
+
+static int __init timeriomem_rng_init(void)
+{
+	return platform_driver_register(&timeriomem_rng_driver);
+}
+
+static void __exit timeriomem_rng_exit(void)
+{
+	platform_driver_unregister(&timeriomem_rng_driver);
+}
+
+module_init(timeriomem_rng_init);
+module_exit(timeriomem_rng_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/hw_random/virtio-rng.c linux-libre-2.6.30-gnu1/drivers/char/hw_random/virtio-rng.c
--- linux-libre-2.6.29-gnu1/drivers/char/hw_random/virtio-rng.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/hw_random/virtio-rng.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,9 +37,9 @@ static void random_recv_done(struct virt
 {
 	int len;
 
-	/* We never get spurious callbacks. */
+	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
 	if (!vq->vq_ops->get_buf(vq, &len))
-		BUG();
+		return;
 
 	data_left = len / sizeof(random_data[0]);
 	complete(&have_data);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/ip2/ip2main.c linux-libre-2.6.30-gnu1/drivers/char/ip2/ip2main.c
--- linux-libre-2.6.29-gnu1/drivers/char/ip2/ip2main.c	2013-05-03 18:00:02.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/ip2/ip2main.c	2013-05-03 16:43:52.000000000 -0400
@@ -139,7 +139,7 @@
 #include <linux/seq_file.h>
 
 static const struct file_operations ip2mem_proc_fops;
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static const struct file_operations ip2_proc_fops;
 
 /********************/
 /* Type Definitions */
@@ -446,9 +446,9 @@ static const struct tty_operations ip2_o
 	.stop            = ip2_stop,
 	.start           = ip2_start,
 	.hangup          = ip2_hangup,
-	.read_proc       = ip2_read_proc,
 	.tiocmget	 = ip2_tiocmget,
 	.tiocmset	 = ip2_tiocmset,
+	.proc_fops	 = &ip2_proc_fops,
 };
 
 /******************************************************************************/
@@ -3029,19 +3029,17 @@ static const struct file_operations ip2m
  * different sources including ip2mkdev.c and a couple of other drivers.
  * The bugs are all mine.  :-)	=mhw=
  */
-static int ip2_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+static int ip2_proc_show(struct seq_file *m, void *v)
 {
 	int	i, j, box;
-	int	len = 0;
 	int	boxes = 0;
 	int	ports = 0;
 	int	tports = 0;
-	off_t	begin = 0;
 	i2eBordStrPtr  pB;
+	char *sep;
 
-	len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
-	len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+	seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
+	seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
 			IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
 			IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
 
@@ -3053,7 +3051,8 @@ static int ip2_read_proc(char *page, cha
 			switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
 			{
 			case POR_ID_FIIEX:
-				len += sprintf( page+len, "Board %d: EX ports=", i );
+				seq_printf(m, "Board %d: EX ports=", i);
+				sep = "";
 				for( box = 0; box < ABS_MAX_BOXES; ++box )
 				{
 					ports = 0;
@@ -3065,79 +3064,74 @@ static int ip2_read_proc(char *page, cha
 							++ports;
 						}
 					}
-					len += sprintf( page+len, "%d,", ports );
+					seq_printf(m, "%s%d", sep, ports);
+					sep = ",";
 					tports += ports;
 				}
-
-				--len;	/* Backup over that last comma */
-
-				len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+				seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
 				break;
 
 			case POR_ID_II_4:
-				len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
 				tports = ports = 4;
 				break;
 
 			case POR_ID_II_8:
-				len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
 				tports = ports = 8;
 				break;
 
 			case POR_ID_II_8R:
-				len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
 				tports = ports = 8;
 				break;
 
 			default:
-				len += sprintf(page+len, "Board %d: unknown", i );
+				seq_printf(m, "Board %d: unknown", i);
 				/* Don't try and probe for minor numbers */
 				tports = ports = 0;
 			}
 
 		} else {
 			/* Don't try and probe for minor numbers */
-			len += sprintf(page+len, "Board %d: vacant", i );
+			seq_printf(m, "Board %d: vacant", i);
 			tports = ports = 0;
 		}
 
 		if( tports ) {
-			len += sprintf(page+len, " minors=" );
-
+			seq_puts(m, " minors=");
+			sep = "";
 			for ( box = 0; box < ABS_MAX_BOXES; ++box )
 			{
 				for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
 				{
 					if ( pB->i2eChannelMap[box] & (1 << j) )
 					{
-						len += sprintf (page+len,"%d,",
+						seq_printf(m, "%s%d", sep,
 							j + ABS_BIGGEST_BOX *
 							(box+i*ABS_MAX_BOXES));
+						sep = ",";
 					}
 				}
 			}
-
-			page[ len - 1 ] = '\n';	/* Overwrite that last comma */
-		} else {
-			len += sprintf (page+len,"\n" );
-		}
-
-		if (len+begin > off+count)
-			break;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
 		}
+		seq_putc(m, '\n');
 	}
+	return 0;
+ }
 
-	if (i >= IP2_MAX_BOARDS)
-		*eof = 1;
-	if (off >= len+begin)
-		return 0;
+static int ip2_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ip2_proc_show, NULL);
+}
 
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
- }
+static const struct file_operations ip2_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ip2_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
  
 /******************************************************************************/
 /* Function:   ip2trace()                                                     */
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/ipmi/ipmi_msghandler.c linux-libre-2.6.30-gnu1/drivers/char/ipmi/ipmi_msghandler.c
--- linux-libre-2.6.29-gnu1/drivers/char/ipmi/ipmi_msghandler.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/ipmi/ipmi_msghandler.c	2009-06-09 23:05:27.000000000 -0400
@@ -285,6 +285,11 @@ enum ipmi_stat_indexes {
 	/* Events that were received with the proper format. */
 	IPMI_STAT_events,
 
+	/* Retransmissions on IPMB that failed. */
+	IPMI_STAT_dropped_rexmit_ipmb_commands,
+
+	/* Retransmissions on LAN that failed. */
+	IPMI_STAT_dropped_rexmit_lan_commands,
 
 	/* This *must* remain last, add new values above this. */
 	IPMI_NUM_STATS
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex);
 #define ipmi_get_stat(intf, stat) \
 	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
 
+static int is_lan_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_LAN_ADDR_TYPE;
+}
+
+static int is_ipmb_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
+}
+
+static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
+{
+	return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
+}
 
 static void free_recv_msg_list(struct list_head *q)
 {
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1,
 		return (smi_addr1->lun == smi_addr2->lun);
 	}
 
-	if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
 		struct ipmi_ipmb_addr *ipmb_addr1
 		    = (struct ipmi_ipmb_addr *) addr1;
 		struct ipmi_ipmb_addr *ipmb_addr2
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1,
 			&& (ipmb_addr1->lun == ipmb_addr2->lun));
 	}
 
-	if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr1)) {
 		struct ipmi_lan_addr *lan_addr1
 			= (struct ipmi_lan_addr *) addr1;
 		struct ipmi_lan_addr *lan_addr2
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr
 	    || (addr->channel < 0))
 		return -EINVAL;
 
-	if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-	    || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		if (len < sizeof(struct ipmi_ipmb_addr))
 			return -EINVAL;
 		return 0;
 	}
 
-	if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	if (is_lan_addr(addr)) {
 		if (len < sizeof(struct ipmi_lan_addr))
 			return -EINVAL;
 		return 0;
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t
 			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
 		smi_msg->data_size = msg->data_len + 2;
 		ipmi_inc_stat(intf, sent_local_commands);
-	} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
-		   || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) {
+	} else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
 		struct ipmi_ipmb_addr *ipmb_addr;
 		unsigned char         ipmb_seq;
 		long                  seqid;
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
-			ipmi_inc_stat(intf, sent_ipmb_commands);
-
 			/*
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t
 				goto out_err;
 			}
 
+			ipmi_inc_stat(intf, sent_ipmb_commands);
+
 			/*
 			 * Store the sequence number in the message,
 			 * so that when the send message response
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t
 			 */
 			spin_unlock_irqrestore(&(intf->seq_lock), flags);
 		}
-	} else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) {
+	} else if (is_lan_addr(addr)) {
 		struct ipmi_lan_addr  *lan_addr;
 		unsigned char         ipmb_seq;
 		long                  seqid;
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t
 
 			spin_lock_irqsave(&(intf->seq_lock), flags);
 
-			ipmi_inc_stat(intf, sent_lan_commands);
-
 			/*
 			 * Create a sequence number with a 1 second
 			 * timeout and 4 retries.
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t
 				goto out_err;
 			}
 
+			ipmi_inc_stat(intf, sent_lan_commands);
+
 			/*
 			 * Store the sequence number in the message,
 			 * so that when the send message response
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *pag
 		       ipmi_get_stat(intf, invalid_events));
 	out += sprintf(out, "events:                      %u\n",
 		       ipmi_get_stat(intf, events));
+	out += sprintf(out, "failed rexmit LAN msgs:      %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_lan_commands));
+	out += sprintf(out, "failed rexmit IPMB msgs:     %u\n",
+		       ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
 
 	return (out - ((char *) page));
 }
@@ -1944,7 +1964,7 @@ static int stat_file_read_proc(char *pag
 
 int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
 			    read_proc_t *read_proc,
-			    void *data, struct module *owner)
+			    void *data)
 {
 	int                    rv = 0;
 #ifdef CONFIG_PROC_FS
@@ -1970,7 +1990,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t s
 	} else {
 		file->data = data;
 		file->read_proc = read_proc;
-		file->owner = owner;
 
 		mutex_lock(&smi->proc_entry_lock);
 		/* Stick it on the list. */
@@ -1993,23 +2012,21 @@ static int add_proc_entries(ipmi_smi_t s
 	smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
 	if (!smi->proc_dir)
 		rv = -ENOMEM;
-	else
-		smi->proc_dir->owner = THIS_MODULE;
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "stats",
 					     stat_file_read_proc,
-					     smi, THIS_MODULE);
+					     smi);
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "ipmb",
 					     ipmb_file_read_proc,
-					     smi, THIS_MODULE);
+					     smi);
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "version",
 					     version_file_read_proc,
-					     smi, THIS_MODULE);
+					     smi);
 #endif /* CONFIG_PROC_FS */
 
 	return rv;
@@ -2839,6 +2856,7 @@ int ipmi_register_smi(struct ipmi_smi_ha
 		/* Assume a single IPMB channel at zero. */
 		intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
 		intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
+		intf->curr_channel = IPMI_MAX_CHANNELS;
 	}
 
 	if (rv == 0)
@@ -3267,6 +3285,114 @@ static int handle_lan_get_msg_cmd(ipmi_s
 	return rv;
 }
 
+/*
+ * This routine will handle "Get Message" command responses with
+ * channels that use an OEM Medium. The message format belongs to
+ * the OEM.  See IPMI 2.0 specification, Chapter 6 and
+ * Chapter 22, sections 22.6 and 22.24 for more details.
+ */
+static int handle_oem_get_msg_cmd(ipmi_smi_t          intf,
+				  struct ipmi_smi_msg *msg)
+{
+	struct cmd_rcvr       *rcvr;
+	int                   rv = 0;
+	unsigned char         netfn;
+	unsigned char         cmd;
+	unsigned char         chan;
+	ipmi_user_t           user = NULL;
+	struct ipmi_system_interface_addr *smi_addr;
+	struct ipmi_recv_msg  *recv_msg;
+
+	/*
+	 * We expect the OEM SW to perform error checking
+	 * so we just do some basic sanity checks
+	 */
+	if (msg->rsp_size < 4) {
+		/* Message not big enough, just ignore it. */
+		ipmi_inc_stat(intf, invalid_commands);
+		return 0;
+	}
+
+	if (msg->rsp[2] != 0) {
+		/* An error getting the response, just ignore it. */
+		return 0;
+	}
+
+	/*
+	 * This is an OEM Message so the OEM needs to know how
+	 * handle the message. We do no interpretation.
+	 */
+	netfn = msg->rsp[0] >> 2;
+	cmd = msg->rsp[1];
+	chan = msg->rsp[3] & 0xf;
+
+	rcu_read_lock();
+	rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
+	if (rcvr) {
+		user = rcvr->user;
+		kref_get(&user->refcount);
+	} else
+		user = NULL;
+	rcu_read_unlock();
+
+	if (user == NULL) {
+		/* We didn't find a user, just give up. */
+		ipmi_inc_stat(intf, unhandled_commands);
+
+		/*
+		 * Don't do anything with these messages, just allow
+		 * them to be freed.
+		 */
+
+		rv = 0;
+	} else {
+		/* Deliver the message to the user. */
+		ipmi_inc_stat(intf, handled_commands);
+
+		recv_msg = ipmi_alloc_recv_msg();
+		if (!recv_msg) {
+			/*
+			 * We couldn't allocate memory for the
+			 * message, so requeue it for handling
+			 * later.
+			 */
+			rv = 1;
+			kref_put(&user->refcount, free_user);
+		} else {
+			/*
+			 * OEM Messages are expected to be delivered via
+			 * the system interface to SMS software.  We might
+			 * need to visit this again depending on OEM
+			 * requirements
+			 */
+			smi_addr = ((struct ipmi_system_interface_addr *)
+				    &(recv_msg->addr));
+			smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+			smi_addr->channel = IPMI_BMC_CHANNEL;
+			smi_addr->lun = msg->rsp[0] & 3;
+
+			recv_msg->user = user;
+			recv_msg->user_msg_data = NULL;
+			recv_msg->recv_type = IPMI_OEM_RECV_TYPE;
+			recv_msg->msg.netfn = msg->rsp[0] >> 2;
+			recv_msg->msg.cmd = msg->rsp[1];
+			recv_msg->msg.data = recv_msg->msg_data;
+
+			/*
+			 * The message starts at byte 4 which follows the
+			 * the Channel Byte in the "GET MESSAGE" command
+			 */
+			recv_msg->msg.data_len = msg->rsp_size - 4;
+			memcpy(recv_msg->msg_data,
+			       &(msg->rsp[4]),
+			       msg->rsp_size - 4);
+			deliver_response(recv_msg);
+		}
+	}
+
+	return rv;
+}
+
 static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
 				     struct ipmi_smi_msg  *msg)
 {
@@ -3522,6 +3648,17 @@ static int handle_new_recv_msg(ipmi_smi_
 			goto out;
 		}
 
+		/*
+		 * We need to make sure the channels have been initialized.
+		 * The channel_handler routine will set the "curr_channel"
+		 * equal to or greater than IPMI_MAX_CHANNELS when all the
+		 * channels for this interface have been initialized.
+		 */
+		if (intf->curr_channel < IPMI_MAX_CHANNELS) {
+			requeue = 0; /* Throw the message away */
+			goto out;
+		}
+
 		switch (intf->channels[chan].medium) {
 		case IPMI_CHANNEL_MEDIUM_IPMB:
 			if (msg->rsp[4] & 0x04) {
@@ -3557,11 +3694,20 @@ static int handle_new_recv_msg(ipmi_smi_
 			break;
 
 		default:
-			/*
-			 * We don't handle the channel type, so just
-			 * free the message.
-			 */
-			requeue = 0;
+			/* Check for OEM Channels.  Clients had better
+			   register for these commands. */
+			if ((intf->channels[chan].medium
+			     >= IPMI_CHANNEL_MEDIUM_OEM_MIN)
+			    && (intf->channels[chan].medium
+				<= IPMI_CHANNEL_MEDIUM_OEM_MAX)) {
+				requeue = handle_oem_get_msg_cmd(intf, msg);
+			} else {
+				/*
+				 * We don't handle the channel type, so just
+				 * free the message.
+				 */
+				requeue = 0;
+			}
 		}
 
 	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
@@ -3733,7 +3879,7 @@ static void check_msg_timeout(ipmi_smi_t
 		list_add_tail(&msg->link, timeouts);
 		if (ent->broadcast)
 			ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
-		else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+		else if (is_lan_addr(&ent->recv_msg->addr))
 			ipmi_inc_stat(intf, timed_out_lan_commands);
 		else
 			ipmi_inc_stat(intf, timed_out_ipmb_commands);
@@ -3747,15 +3893,17 @@ static void check_msg_timeout(ipmi_smi_t
 		 */
 		ent->timeout = MAX_MSG_TIMEOUT;
 		ent->retries_left--;
-		if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
-			ipmi_inc_stat(intf, retransmitted_lan_commands);
-		else
-			ipmi_inc_stat(intf, retransmitted_ipmb_commands);
-
 		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
 					    ent->seqid);
-		if (!smi_msg)
+		if (!smi_msg) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      dropped_rexmit_ipmb_commands);
 			return;
+		}
 
 		spin_unlock_irqrestore(&intf->seq_lock, *flags);
 
@@ -3767,10 +3915,17 @@ static void check_msg_timeout(ipmi_smi_t
 		 * resent.
 		 */
 		handlers = intf->handlers;
-		if (handlers)
+		if (handlers) {
+			if (is_lan_addr(&ent->recv_msg->addr))
+				ipmi_inc_stat(intf,
+					      retransmitted_lan_commands);
+			else
+				ipmi_inc_stat(intf,
+					      retransmitted_ipmb_commands);
+
 			intf->handlers->sender(intf->send_info,
 					       smi_msg, 0);
-		else
+		} else
 			ipmi_free_smi_msg(smi_msg);
 
 		spin_lock_irqsave(&intf->seq_lock, *flags);
@@ -4265,7 +4420,6 @@ static int ipmi_init_msghandler(void)
 	    return -ENOMEM;
 	}
 
-	proc_ipmi_root->owner = THIS_MODULE;
 #endif /* CONFIG_PROC_FS */
 
 	setup_timer(&ipmi_timer, ipmi_timeout, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/ipmi/ipmi_si_intf.c linux-libre-2.6.30-gnu1/drivers/char/ipmi/ipmi_si_intf.c
--- linux-libre-2.6.29-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/ipmi/ipmi_si_intf.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,12 +82,6 @@
 #define SI_SHORT_TIMEOUT_USEC  250 /* .25ms when the SM request a
 				      short timeout */
 
-/* Bit for BMC global enables. */
-#define IPMI_BMC_RCV_MSG_INTR     0x01
-#define IPMI_BMC_EVT_MSG_INTR     0x02
-#define IPMI_BMC_EVT_MSG_BUFF     0x04
-#define IPMI_BMC_SYS_LOG          0x08
-
 enum si_intf_state {
 	SI_NORMAL,
 	SI_GETTING_FLAGS,
@@ -220,6 +214,9 @@ struct smi_info {
 			     OEM2_DATA_AVAIL)
 	unsigned char       msg_flags;
 
+	/* Does the BMC have an event buffer? */
+	char		    has_event_buffer;
+
 	/*
 	 * If set to true, this will request events the next time the
 	 * state machine is idle.
@@ -968,7 +965,8 @@ static void request_events(void *send_in
 {
 	struct smi_info *smi_info = send_info;
 
-	if (atomic_read(&smi_info->stop_operation))
+	if (atomic_read(&smi_info->stop_operation) ||
+				!smi_info->has_event_buffer)
 		return;
 
 	atomic_set(&smi_info->req_events, 1);
@@ -2407,26 +2405,9 @@ static struct of_platform_driver ipmi_of
 };
 #endif /* CONFIG_PPC_OF */
 
-
-static int try_get_dev_id(struct smi_info *smi_info)
+static int wait_for_msg_done(struct smi_info *smi_info)
 {
-	unsigned char         msg[2];
-	unsigned char         *resp;
-	unsigned long         resp_len;
 	enum si_sm_result     smi_result;
-	int                   rv = 0;
-
-	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
-	if (!resp)
-		return -ENOMEM;
-
-	/*
-	 * Do a Get Device ID command, since it comes back with some
-	 * useful info.
-	 */
-	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
-	msg[1] = IPMI_GET_DEVICE_ID_CMD;
-	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
 
 	smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
 	for (;;) {
@@ -2441,16 +2422,39 @@ static int try_get_dev_id(struct smi_inf
 		} else
 			break;
 	}
-	if (smi_result == SI_SM_HOSED) {
+	if (smi_result == SI_SM_HOSED)
 		/*
 		 * We couldn't get the state machine to run, so whatever's at
 		 * the port is probably not an IPMI SMI interface.
 		 */
-		rv = -ENODEV;
+		return -ENODEV;
+
+	return 0;
+}
+
+static int try_get_dev_id(struct smi_info *smi_info)
+{
+	unsigned char         msg[2];
+	unsigned char         *resp;
+	unsigned long         resp_len;
+	int                   rv = 0;
+
+	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	/*
+	 * Do a Get Device ID command, since it comes back with some
+	 * useful info.
+	 */
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_GET_DEVICE_ID_CMD;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv)
 		goto out;
-	}
 
-	/* Otherwise, we got some data. */
 	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
 						  resp, IPMI_MAX_MSG_LENGTH);
 
@@ -2462,6 +2466,88 @@ static int try_get_dev_id(struct smi_inf
 	return rv;
 }
 
+static int try_enable_event_buffer(struct smi_info *smi_info)
+{
+	unsigned char         msg[3];
+	unsigned char         *resp;
+	unsigned long         resp_len;
+	int                   rv = 0;
+
+	resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv) {
+		printk(KERN_WARNING
+		       "ipmi_si: Error getting response from get global,"
+		       " enables command, the event buffer is not"
+		       " enabled.\n");
+		goto out;
+	}
+
+	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+						  resp, IPMI_MAX_MSG_LENGTH);
+
+	if (resp_len < 4 ||
+			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+			resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD   ||
+			resp[2] != 0) {
+		printk(KERN_WARNING
+		       "ipmi_si: Invalid return from get global"
+		       " enables command, cannot enable the event"
+		       " buffer.\n");
+		rv = -EINVAL;
+		goto out;
+	}
+
+	if (resp[3] & IPMI_BMC_EVT_MSG_BUFF)
+		/* buffer is already enabled, nothing to do. */
+		goto out;
+
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+	msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF;
+	smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
+
+	rv = wait_for_msg_done(smi_info);
+	if (rv) {
+		printk(KERN_WARNING
+		       "ipmi_si: Error getting response from set global,"
+		       " enables command, the event buffer is not"
+		       " enabled.\n");
+		goto out;
+	}
+
+	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
+						  resp, IPMI_MAX_MSG_LENGTH);
+
+	if (resp_len < 3 ||
+			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
+			resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
+		printk(KERN_WARNING
+		       "ipmi_si: Invalid return from get global,"
+		       "enables command, not enable the event"
+		       " buffer.\n");
+		rv = -EINVAL;
+		goto out;
+	}
+
+	if (resp[2] != 0)
+		/*
+		 * An error when setting the event buffer bit means
+		 * that the event buffer is not supported.
+		 */
+		rv = -ENOENT;
+ out:
+	kfree(resp);
+	return rv;
+}
+
 static int type_file_read_proc(char *page, char **start, off_t off,
 			       int count, int *eof, void *data)
 {
@@ -2847,6 +2933,10 @@ static int try_smi_init(struct smi_info
 	new_smi->intf_num = smi_num;
 	smi_num++;
 
+	rv = try_enable_event_buffer(new_smi);
+	if (rv == 0)
+		new_smi->has_event_buffer = 1;
+
 	/*
 	 * Start clearing the flags before we enable interrupts or the
 	 * timer to avoid racing with the timer.
@@ -2863,7 +2953,7 @@ static int try_smi_init(struct smi_info
 		 */
 		new_smi->pdev = platform_device_alloc("ipmi_si",
 						      new_smi->intf_num);
-		if (rv) {
+		if (!new_smi->pdev) {
 			printk(KERN_ERR
 			       "ipmi_si_intf:"
 			       " Unable to allocate platform device\n");
@@ -2899,7 +2989,7 @@ static int try_smi_init(struct smi_info
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
 				     type_file_read_proc,
-				     new_smi, THIS_MODULE);
+				     new_smi);
 	if (rv) {
 		printk(KERN_ERR
 		       "ipmi_si: Unable to create proc entry: %d\n",
@@ -2909,7 +2999,7 @@ static int try_smi_init(struct smi_info
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
 				     stat_file_read_proc,
-				     new_smi, THIS_MODULE);
+				     new_smi);
 	if (rv) {
 		printk(KERN_ERR
 		       "ipmi_si: Unable to create proc entry: %d\n",
@@ -2919,7 +3009,7 @@ static int try_smi_init(struct smi_info
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
 				     param_read_proc,
-				     new_smi, THIS_MODULE);
+				     new_smi);
 	if (rv) {
 		printk(KERN_ERR
 		       "ipmi_si: Unable to create proc entry: %d\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/isicom.c linux-libre-2.6.30-gnu1/drivers/char/isicom.c
--- linux-libre-2.6.29-gnu1/drivers/char/isicom.c	2013-05-03 18:00:10.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/isicom.c	2013-05-03 16:44:00.000000000 -0400
@@ -925,6 +925,7 @@ static void isicom_shutdown_port(struct
 		if (!card->count)
 			isicom_shutdown_board(card);
 	}
+	tty_kref_put(tty);
 }
 
 static void isicom_flush_buffer(struct tty_struct *tty)
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/istallion.c linux-libre-2.6.30-gnu1/drivers/char/istallion.c
--- linux-libre-2.6.29-gnu1/drivers/char/istallion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/istallion.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/seq_file.h>
 #include <linux/cdk.h>
 #include <linux/comstats.h>
 #include <linux/istallion.h>
@@ -613,7 +614,6 @@ static int	stli_breakctl(struct tty_stru
 static void	stli_waituntilsent(struct tty_struct *tty, int timeout);
 static void	stli_sendxchar(struct tty_struct *tty, char ch);
 static void	stli_hangup(struct tty_struct *tty);
-static int	stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
 
 static int	stli_brdinit(struct stlibrd *brdp);
 static int	stli_startbrd(struct stlibrd *brdp);
@@ -1893,20 +1893,10 @@ static void stli_sendxchar(struct tty_st
 	stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
 }
 
-/*****************************************************************************/
-
-#define	MAXLINE		80
-
-/*
- *	Format info for a specified port. The line is deliberately limited
- *	to 80 characters. (If it is too long it will be truncated, if too
- *	short then padded with spaces).
- */
-
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
+static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
 {
-	char *sp, *uart;
-	int rc, cnt;
+	char *uart;
+	int rc;
 
 	rc = stli_portcmdstats(NULL, portp);
 
@@ -1918,44 +1908,50 @@ static int stli_portinfo(struct stlibrd
 		default:uart = "CD1400"; break;
 		}
 	}
-
-	sp = pos;
-	sp += sprintf(sp, "%d: uart:%s ", portnr, uart);
+	seq_printf(m, "%d: uart:%s ", portnr, uart);
 
 	if ((brdp->state & BST_STARTED) && (rc >= 0)) {
-		sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal,
+		char sep;
+
+		seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
 			(int) stli_comstats.rxtotal);
 
 		if (stli_comstats.rxframing)
-			sp += sprintf(sp, " fe:%d",
+			seq_printf(m, " fe:%d",
 				(int) stli_comstats.rxframing);
 		if (stli_comstats.rxparity)
-			sp += sprintf(sp, " pe:%d",
+			seq_printf(m, " pe:%d",
 				(int) stli_comstats.rxparity);
 		if (stli_comstats.rxbreaks)
-			sp += sprintf(sp, " brk:%d",
+			seq_printf(m, " brk:%d",
 				(int) stli_comstats.rxbreaks);
 		if (stli_comstats.rxoverrun)
-			sp += sprintf(sp, " oe:%d",
+			seq_printf(m, " oe:%d",
 				(int) stli_comstats.rxoverrun);
 
-		cnt = sprintf(sp, "%s%s%s%s%s ",
-			(stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "",
-			(stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "",
-			(stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "",
-			(stli_comstats.signals & TIOCM_CD) ? "|DCD" : "",
-			(stli_comstats.signals & TIOCM_DSR) ? "|DSR" : "");
-		*sp = ' ';
-		sp += cnt;
+		sep = ' ';
+		if (stli_comstats.signals & TIOCM_RTS) {
+			seq_printf(m, "%c%s", sep, "RTS");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_CTS) {
+			seq_printf(m, "%c%s", sep, "CTS");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_DTR) {
+			seq_printf(m, "%c%s", sep, "DTR");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_CD) {
+			seq_printf(m, "%c%s", sep, "DCD");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_DSR) {
+			seq_printf(m, "%c%s", sep, "DSR");
+			sep = '|';
+		}
 	}
-
-	for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
-		*sp++ = ' ';
-	if (cnt >= MAXLINE)
-		pos[(MAXLINE - 2)] = '+';
-	pos[(MAXLINE - 1)] = '\n';
-
-	return(MAXLINE);
+	seq_putc(m, '\n');
 }
 
 /*****************************************************************************/
@@ -1964,26 +1960,15 @@ static int stli_portinfo(struct stlibrd
  *	Port info, read from the /proc file system.
  */
 
-static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stli_proc_show(struct seq_file *m, void *v)
 {
 	struct stlibrd *brdp;
 	struct stliport *portp;
 	unsigned int brdnr, portnr, totalport;
-	int curoff, maxoff;
-	char *pos;
 
-	pos = page;
 	totalport = 0;
-	curoff = 0;
 
-	if (off == 0) {
-		pos += sprintf(pos, "%s: version %s", stli_drvtitle,
-			stli_drvversion);
-		while (pos < (page + MAXLINE - 1))
-			*pos++ = ' ';
-		*pos++ = '\n';
-	}
-	curoff =  MAXLINE;
+	seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
 
 /*
  *	We scan through for each board, panel and port. The offset is
@@ -1996,33 +1981,31 @@ static int stli_readproc(char *page, cha
 		if (brdp->state == 0)
 			continue;
 
-		maxoff = curoff + (brdp->nrports * MAXLINE);
-		if (off >= maxoff) {
-			curoff = maxoff;
-			continue;
-		}
-
 		totalport = brdnr * STL_MAXPORTS;
 		for (portnr = 0; (portnr < brdp->nrports); portnr++,
 		    totalport++) {
 			portp = brdp->ports[portnr];
 			if (portp == NULL)
 				continue;
-			if (off >= (curoff += MAXLINE))
-				continue;
-			if ((pos - page + MAXLINE) > count)
-				goto stli_readdone;
-			pos += stli_portinfo(brdp, portp, totalport, pos);
+			stli_portinfo(m, brdp, portp, totalport);
 		}
 	}
+	return 0;
+}
 
-	*eof = 1;
-
-stli_readdone:
-	*start = page;
-	return(pos - page);
+static int stli_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, stli_proc_show, NULL);
 }
 
+static const struct file_operations stli_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stli_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*****************************************************************************/
 
 /*
@@ -4427,9 +4410,9 @@ static const struct tty_operations stli_
 	.break_ctl = stli_breakctl,
 	.wait_until_sent = stli_waituntilsent,
 	.send_xchar = stli_sendxchar,
-	.read_proc = stli_readproc,
 	.tiocmget = stli_tiocmget,
 	.tiocmset = stli_tiocmset,
+	.proc_fops = &stli_proc_fops,
 };
 
 static const struct tty_port_operations stli_port_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/mem.c linux-libre-2.6.30-gnu1/drivers/char/mem.c
--- linux-libre-2.6.29-gnu1/drivers/char/mem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/mem.c	2009-06-09 23:05:27.000000000 -0400
@@ -301,33 +301,7 @@ static inline int private_mapping_ok(str
 }
 #endif
 
-void __attribute__((weak))
-map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
-	/* nothing. architectures can override. */
-}
-
-void __attribute__((weak))
-unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot)
-{
-	/* nothing. architectures can override. */
-}
-
-static void mmap_mem_open(struct vm_area_struct *vma)
-{
-	map_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
-			vma->vm_page_prot);
-}
-
-static void mmap_mem_close(struct vm_area_struct *vma)
-{
-	unmap_devmem(vma->vm_pgoff,  vma->vm_end - vma->vm_start,
-			vma->vm_page_prot);
-}
-
 static struct vm_operations_struct mmap_mem_ops = {
-	.open  = mmap_mem_open,
-	.close = mmap_mem_close,
 #ifdef CONFIG_HAVE_IOREMAP_PROT
 	.access = generic_access_phys
 #endif
@@ -362,7 +336,6 @@ static int mmap_mem(struct file * file,
 			    vma->vm_pgoff,
 			    size,
 			    vma->vm_page_prot)) {
-		unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot);
 		return -EAGAIN;
 	}
 	return 0;
@@ -721,6 +694,9 @@ static ssize_t read_zero(struct file * f
 		written += chunk - unwritten;
 		if (unwritten)
 			break;
+		/* Consider changing this to just 'signal_pending()' with lots of testing */
+		if (fatal_signal_pending(current))
+			return written ? written : -EINTR;
 		buf += chunk;
 		count -= chunk;
 		cond_resched();
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/moxa.c linux-libre-2.6.30-gnu1/drivers/char/moxa.c
--- linux-libre-2.6.29-gnu1/drivers/char/moxa.c	2013-05-03 18:00:12.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/moxa.c	2013-05-03 16:44:03.000000000 -0400
@@ -1486,11 +1486,11 @@ static int moxa_poll_port(struct moxa_po
 	}
 
 	if (!handle) /* nothing else to do */
-		return 0;
+		goto put;
 
 	intr = readw(ip); /* port irq status */
 	if (intr == 0)
-		return 0;
+		goto put;
 
 	writew(0, ip); /* ACK port */
 	ofsAddr = p->tableAddr;
@@ -1499,16 +1499,17 @@ static int moxa_poll_port(struct moxa_po
 				ofsAddr + HostStat);
 
 	if (!inited)
-		return 0;
+		goto put;
 
 	if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
 		tty_insert_flip_char(tty, 0, TTY_BREAK);
 		tty_schedule_flip(tty);
 	}
-	tty_kref_put(tty);
 
 	if (intr & IntrLine)
 		moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+put:
+	tty_kref_put(tty);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/mxser.c linux-libre-2.6.30-gnu1/drivers/char/mxser.c
--- linux-libre-2.6.29-gnu1/drivers/char/mxser.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/mxser.c	2009-06-09 23:05:27.000000000 -0400
@@ -820,7 +820,6 @@ static void mxser_check_modem_status(str
 			wake_up_interruptible(&port->port.open_wait);
 	}
 
-	tty = tty_port_tty_get(&port->port);
 	if (port->port.flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status & UART_MSR_CTS) {
@@ -2712,7 +2711,7 @@ static int __init mxser_module_init(void
 			continue;
 
 		brd = &mxser_boards[m];
-		retval = mxser_get_ISA_conf(!ioaddr[b], brd);
+		retval = mxser_get_ISA_conf(ioaddr[b], brd);
 		if (retval <= 0) {
 			brd->info = NULL;
 			continue;
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/pcmcia/synclink_cs.c linux-libre-2.6.30-gnu1/drivers/char/pcmcia/synclink_cs.c
--- linux-libre-2.6.29-gnu1/drivers/char/pcmcia/synclink_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/pcmcia/synclink_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -2619,13 +2620,12 @@ cleanup:
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, MGSLPC_INFO *info)
+static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s:io:%04X irq:%d",
+	seq_printf(m, "%s:io:%04X irq:%d",
 		      info->device_name, info->io_base, info->irq_level);
 
 	/* output current serial signal states */
@@ -2649,75 +2649,70 @@ static inline int line_info(char *buf, M
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode == MGSL_MODE_HDLC) {
-		ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+		seq_printf(m, " HDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+		seq_printf(m, " ASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 		       info->tx_active,info->bh_requested,info->bh_running,
 		       info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+static int mgslpc_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	MGSLPC_INFO *info;
 
-	len += sprintf(page, "synclink driver:%s\n", driver_version);
+	seq_printf(m, "synclink driver:%s\n", driver_version);
 
 	info = mgslpc_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
+	return 0;
+}
 
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+static int mgslpc_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mgslpc_proc_show, NULL);
 }
 
+static const struct file_operations mgslpc_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mgslpc_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int rx_alloc_buffers(MGSLPC_INFO *info)
 {
 	/* each buffer has header and data */
@@ -2861,13 +2856,13 @@ static const struct tty_operations mgslp
 	.send_xchar = mgslpc_send_xchar,
 	.break_ctl = mgslpc_break,
 	.wait_until_sent = mgslpc_wait_until_sent,
-	.read_proc = mgslpc_read_proc,
 	.set_termios = mgslpc_set_termios,
 	.stop = tx_pause,
 	.start = tx_release,
 	.hangup = mgslpc_hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &mgslpc_proc_fops,
 };
 
 static void synclink_cs_cleanup(void)
@@ -4311,10 +4306,17 @@ static void hdlcdev_rx(MGSLPC_INFO *info
 	dev->stats.rx_bytes += size;
 
 	netif_rx(skb);
-
-	dev->last_rx = jiffies;
 }
 
+static const struct net_device_ops hdlcdev_ops = {
+	.ndo_open       = hdlcdev_open,
+	.ndo_stop       = hdlcdev_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hdlcdev_ioctl,
+	.ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
 /**
  * called by device driver when adding device instance
  * do generic HDLC initialization
@@ -4341,11 +4343,8 @@ static int hdlcdev_init(MGSLPC_INFO *inf
 	dev->irq       = info->irq_level;
 
 	/* network layer callbacks and settings */
-	dev->do_ioctl       = hdlcdev_ioctl;
-	dev->open           = hdlcdev_open;
-	dev->stop           = hdlcdev_close;
-	dev->tx_timeout     = hdlcdev_tx_timeout;
-	dev->watchdog_timeo = 10*HZ;
+	dev->netdev_ops	    = &hdlcdev_ops;
+	dev->watchdog_timeo = 10 * HZ;
 	dev->tx_queue_len   = 50;
 
 	/* generic HDLC layer callbacks and settings */
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/random.c linux-libre-2.6.30-gnu1/drivers/char/random.c
--- linux-libre-2.6.29-gnu1/drivers/char/random.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/random.c	2009-06-09 23:05:27.000000000 -0400
@@ -241,6 +241,10 @@
 #include <linux/percpu.h>
 #include <linux/cryptohash.h>
 
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
 	unsigned dont_count_entropy:1;
 };
 
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
 
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
@@ -1484,7 +1488,8 @@ static void rekey_seq_generator(struct w
 	keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
 	smp_wmb();
 	ip_cnt++;
-	schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
+	schedule_delayed_work(&rekey_work,
+			      round_jiffies_relative(REKEY_INTERVAL));
 }
 
 static inline struct keydata *get_keyptr(void)
@@ -1660,15 +1665,20 @@ EXPORT_SYMBOL(secure_dccp_sequence_numbe
  * value is not cryptographically secure but for several uses the cost of
  * depleting entropy is too high
  */
+DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
 unsigned int get_random_int(void)
 {
-	/*
-	 * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
-	 * every second, from the entropy pool (and thus creates a limited
-	 * drain on it), and uses halfMD4Transform within the second. We
-	 * also mix it with jiffies and the PID:
-	 */
-	return secure_ip_id((__force __be32)(current->pid + jiffies));
+	struct keydata *keyptr;
+	__u32 *hash = get_cpu_var(get_random_int_hash);
+	int ret;
+
+	keyptr = get_keyptr();
+	hash[0] += current->pid + jiffies + get_cycles();
+
+	ret = half_md4_transform(hash, keyptr->secret);
+	put_cpu_var(get_random_int_hash);
+
+	return ret;
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/raw.c linux-libre-2.6.30-gnu1/drivers/char/raw.c
--- linux-libre-2.6.29-gnu1/drivers/char/raw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/raw.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,6 +90,7 @@ out1:
 	blkdev_put(bdev, filp->f_mode);
 out:
 	mutex_unlock(&raw_mutex);
+	unlock_kernel();
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/rio/rio_linux.c linux-libre-2.6.30-gnu1/drivers/char/rio/rio_linux.c
--- linux-libre-2.6.29-gnu1/drivers/char/rio/rio_linux.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/rio/rio_linux.c	2009-06-09 23:05:27.000000000 -0400
@@ -333,7 +333,7 @@ void rio_copy_to_card(void *from, void _
 
 int rio_minor(struct tty_struct *tty)
 {
-	return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+	return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
 }
 
 static int rio_set_real_termios(void *ptr)
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/riscom8.c linux-libre-2.6.30-gnu1/drivers/char/riscom8.c
--- linux-libre-2.6.29-gnu1/drivers/char/riscom8.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/riscom8.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/delay.h>
 #include <linux/tty_flip.h>
 #include <linux/spinlock.h>
+#include <linux/device.h>
 
 #include <linux/uaccess.h>
 
@@ -1524,6 +1525,7 @@ module_param(iobase2, int, 0);
 module_param(iobase3, int, 0);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
 #endif /* MODULE */
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/sonypi.c linux-libre-2.6.30-gnu1/drivers/char/sonypi.c
--- linux-libre-2.6.29-gnu1/drivers/char/sonypi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/sonypi.c	2009-06-09 23:05:27.000000000 -0400
@@ -888,12 +888,7 @@ found:
 
 static int sonypi_misc_fasync(int fd, struct file *filp, int on)
 {
-	int retval;
-
-	retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
-	if (retval < 0)
-		return retval;
-	return 0;
+	return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
 }
 
 static int sonypi_misc_release(struct inode *inode, struct file *file)
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/specialix.c linux-libre-2.6.30-gnu1/drivers/char/specialix.c
--- linux-libre-2.6.29-gnu1/drivers/char/specialix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/specialix.c	2009-06-09 23:05:27.000000000 -0400
@@ -2365,3 +2365,4 @@ module_init(specialix_init_module);
 module_exit(specialix_exit_module);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/stallion.c linux-libre-2.6.30-gnu1/drivers/char/stallion.c
--- linux-libre-2.6.29-gnu1/drivers/char/stallion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/stallion.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/seq_file.h>
 #include <linux/cd1400.h>
 #include <linux/sc26198.h>
 #include <linux/comstats.h>
@@ -1379,52 +1380,47 @@ static void stl_sendxchar(struct tty_str
 		stl_putchar(tty, ch);
 }
 
-/*****************************************************************************/
-
-#define	MAXLINE		80
-
-/*
- *	Format info for a specified port. The line is deliberately limited
- *	to 80 characters. (If it is too long it will be truncated, if too
- *	short then padded with spaces).
- */
-
-static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
+static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr)
 {
-	char	*sp;
-	int	sigs, cnt;
+	int	sigs;
+	char sep;
 
-	sp = pos;
-	sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
+	seq_printf(m, "%d: uart:%s tx:%d rx:%d",
 		portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
 		(int) portp->stats.txtotal, (int) portp->stats.rxtotal);
 
 	if (portp->stats.rxframing)
-		sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
+		seq_printf(m, " fe:%d", (int) portp->stats.rxframing);
 	if (portp->stats.rxparity)
-		sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
+		seq_printf(m, " pe:%d", (int) portp->stats.rxparity);
 	if (portp->stats.rxbreaks)
-		sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
+		seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks);
 	if (portp->stats.rxoverrun)
-		sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
+		seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun);
 
 	sigs = stl_getsignals(portp);
-	cnt = sprintf(sp, "%s%s%s%s%s ",
-		(sigs & TIOCM_RTS) ? "|RTS" : "",
-		(sigs & TIOCM_CTS) ? "|CTS" : "",
-		(sigs & TIOCM_DTR) ? "|DTR" : "",
-		(sigs & TIOCM_CD) ? "|DCD" : "",
-		(sigs & TIOCM_DSR) ? "|DSR" : "");
-	*sp = ' ';
-	sp += cnt;
-
-	for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
-		*sp++ = ' ';
-	if (cnt >= MAXLINE)
-		pos[(MAXLINE - 2)] = '+';
-	pos[(MAXLINE - 1)] = '\n';
-
-	return MAXLINE;
+	sep = ' ';
+	if (sigs & TIOCM_RTS) {
+		seq_printf(m, "%c%s", sep, "RTS");
+		sep = '|';
+	}
+	if (sigs & TIOCM_CTS) {
+		seq_printf(m, "%c%s", sep, "CTS");
+		sep = '|';
+	}
+	if (sigs & TIOCM_DTR) {
+		seq_printf(m, "%c%s", sep, "DTR");
+		sep = '|';
+	}
+	if (sigs & TIOCM_CD) {
+		seq_printf(m, "%c%s", sep, "DCD");
+		sep = '|';
+	}
+	if (sigs & TIOCM_DSR) {
+		seq_printf(m, "%c%s", sep, "DSR");
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 }
 
 /*****************************************************************************/
@@ -1433,30 +1429,17 @@ static int stl_portinfo(struct stlport *
  *	Port info, read from the /proc file system.
  */
 
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stl_proc_show(struct seq_file *m, void *v)
 {
 	struct stlbrd	*brdp;
 	struct stlpanel	*panelp;
 	struct stlport	*portp;
 	unsigned int	brdnr, panelnr, portnr;
-	int		totalport, curoff, maxoff;
-	char		*pos;
-
-	pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
-		"data=%p\n", page, start, off, count, eof, data);
+	int		totalport;
 
-	pos = page;
 	totalport = 0;
-	curoff = 0;
 
-	if (off == 0) {
-		pos += sprintf(pos, "%s: version %s", stl_drvtitle,
-			stl_drvversion);
-		while (pos < (page + MAXLINE - 1))
-			*pos++ = ' ';
-		*pos++ = '\n';
-	}
-	curoff =  MAXLINE;
+	seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion);
 
 /*
  *	We scan through for each board, panel and port. The offset is
@@ -1469,46 +1452,37 @@ static int stl_readproc(char *page, char
 		if (brdp->state == 0)
 			continue;
 
-		maxoff = curoff + (brdp->nrports * MAXLINE);
-		if (off >= maxoff) {
-			curoff = maxoff;
-			continue;
-		}
-
 		totalport = brdnr * STL_MAXPORTS;
 		for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
 			panelp = brdp->panels[panelnr];
 			if (panelp == NULL)
 				continue;
 
-			maxoff = curoff + (panelp->nrports * MAXLINE);
-			if (off >= maxoff) {
-				curoff = maxoff;
-				totalport += panelp->nrports;
-				continue;
-			}
-
 			for (portnr = 0; portnr < panelp->nrports; portnr++,
 			    totalport++) {
 				portp = panelp->ports[portnr];
 				if (portp == NULL)
 					continue;
-				if (off >= (curoff += MAXLINE))
-					continue;
-				if ((pos - page + MAXLINE) > count)
-					goto stl_readdone;
-				pos += stl_portinfo(portp, totalport, pos);
+				stl_portinfo(m, portp, totalport);
 			}
 		}
 	}
+	return 0;
+}
 
-	*eof = 1;
-
-stl_readdone:
-	*start = page;
-	return pos - page;
+static int stl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, stl_proc_show, NULL);
 }
 
+static const struct file_operations stl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*****************************************************************************/
 
 /*
@@ -2566,9 +2540,9 @@ static const struct tty_operations stl_o
 	.break_ctl = stl_breakctl,
 	.wait_until_sent = stl_waituntilsent,
 	.send_xchar = stl_sendxchar,
-	.read_proc = stl_readproc,
 	.tiocmget = stl_tiocmget,
 	.tiocmset = stl_tiocmset,
+	.proc_fops = &stl_proc_fops,
 };
 
 static const struct tty_port_operations stl_port_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/synclink.c linux-libre-2.6.30-gnu1/drivers/char/synclink.c
--- linux-libre-2.6.29-gnu1/drivers/char/synclink.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/synclink.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,6 +79,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -3459,18 +3460,17 @@ cleanup:
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct mgsl_struct *info)
+static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
 	if (info->bus_type == MGSL_BUS_TYPE_PCI) {
-		ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
+		seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
 			info->device_name, info->io_base, info->irq_level,
 			info->phys_memory_base, info->phys_lcr_base);
 	} else {
-		ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d",
+		seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
 			info->device_name, info->io_base, 
 			info->irq_level, info->dma_level);
 	}
@@ -3497,37 +3497,37 @@ static inline int line_info(char *buf, s
 
 	if (info->params.mode == MGSL_MODE_HDLC ||
 	    info->params.mode == MGSL_MODE_RAW ) {
-		ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+		seq_printf(m, " HDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);	
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+		seq_printf(m, " ASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);	
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 	
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 	
-	ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 	 info->tx_active,info->bh_requested,info->bh_running,
 	 info->pending_bh);
 	 
@@ -3544,60 +3544,40 @@ static inline int line_info(char *buf, s
 	u16 Tmr = usc_InReg( info, TMR );
 	u16 Tccr = usc_InReg( info, TCCR );
 	u16 Ccar = inw( info->io_base + CCAR );
-	ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
+	seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
                         "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n",
 	 		Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar );
 	}
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
-	
-	return ret;
-	
-}	/* end of line_info() */
+}
 
-/* mgsl_read_proc()
- * 
- * Called to print information about devices
- * 
- * Arguments:
- * 	page	page of memory to hold returned info
- * 	start	
- * 	off
- * 	count
- * 	eof
- * 	data
- * 	
- * Return Value:
- */
-static int mgsl_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+/* Called to print information about devices */
+static int mgsl_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	struct mgsl_struct *info;
 	
-	len += sprintf(page, "synclink driver:%s\n", driver_version);
+	seq_printf(m, "synclink driver:%s\n", driver_version);
 	
 	info = mgsl_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
+	return 0;
+}
 
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-	
-}	/* end of mgsl_read_proc() */
+static int mgsl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mgsl_proc_show, NULL);
+}
+
+static const struct file_operations mgsl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mgsl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 /* mgsl_allocate_dma_buffers()
  * 
@@ -4335,13 +4315,13 @@ static const struct tty_operations mgsl_
 	.send_xchar = mgsl_send_xchar,
 	.break_ctl = mgsl_break,
 	.wait_until_sent = mgsl_wait_until_sent,
- 	.read_proc = mgsl_read_proc,
 	.set_termios = mgsl_set_termios,
 	.stop = mgsl_stop,
 	.start = mgsl_start,
 	.hangup = mgsl_hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &mgsl_proc_fops,
 };
 
 /*
@@ -8007,10 +7987,17 @@ static void hdlcdev_rx(struct mgsl_struc
 	dev->stats.rx_bytes += size;
 
 	netif_rx(skb);
-
-	dev->last_rx = jiffies;
 }
 
+static const struct net_device_ops hdlcdev_ops = {
+	.ndo_open       = hdlcdev_open,
+	.ndo_stop       = hdlcdev_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hdlcdev_ioctl,
+	.ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
 /**
  * called by device driver when adding device instance
  * do generic HDLC initialization
@@ -8038,11 +8025,8 @@ static int hdlcdev_init(struct mgsl_stru
 	dev->dma       = info->dma_level;
 
 	/* network layer callbacks and settings */
-	dev->do_ioctl       = hdlcdev_ioctl;
-	dev->open           = hdlcdev_open;
-	dev->stop           = hdlcdev_close;
-	dev->tx_timeout     = hdlcdev_tx_timeout;
-	dev->watchdog_timeo = 10*HZ;
+	dev->netdev_ops     = &hdlcdev_ops;
+	dev->watchdog_timeo = 10 * HZ;
 	dev->tx_queue_len   = 50;
 
 	/* generic HDLC layer callbacks and settings */
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/synclink_gt.c linux-libre-2.6.30-gnu1/drivers/char/synclink_gt.c
--- linux-libre-2.6.29-gnu1/drivers/char/synclink_gt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/synclink_gt.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,6 +60,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -154,7 +155,6 @@ static void tx_hold(struct tty_struct *t
 static void tx_release(struct tty_struct *tty);
 
 static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
@@ -298,6 +298,7 @@ struct slgt_info {
 
 	unsigned int rbuf_fill_level;
 	unsigned int if_mode;
+	unsigned int base_clock;
 
 	/* device status */
 
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_inf
 		return -EFAULT;
 
 	spin_lock(&info->lock);
-	info->params.mode            = tmp_params.mode;
-	info->params.loopback        = tmp_params.loopback;
-	info->params.flags           = tmp_params.flags;
-	info->params.encoding        = tmp_params.encoding;
-	info->params.clock_speed     = tmp_params.clock_speed;
-	info->params.addr_filter     = tmp_params.addr_filter;
-	info->params.crc_type        = tmp_params.crc_type;
-	info->params.preamble_length = tmp_params.preamble_length;
-	info->params.preamble        = tmp_params.preamble;
-	info->params.data_rate       = tmp_params.data_rate;
-	info->params.data_bits       = tmp_params.data_bits;
-	info->params.stop_bits       = tmp_params.stop_bits;
-	info->params.parity          = tmp_params.parity;
+	if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) {
+		info->base_clock = tmp_params.clock_speed;
+	} else {
+		info->params.mode            = tmp_params.mode;
+		info->params.loopback        = tmp_params.loopback;
+		info->params.flags           = tmp_params.flags;
+		info->params.encoding        = tmp_params.encoding;
+		info->params.clock_speed     = tmp_params.clock_speed;
+		info->params.addr_filter     = tmp_params.addr_filter;
+		info->params.crc_type        = tmp_params.crc_type;
+		info->params.preamble_length = tmp_params.preamble_length;
+		info->params.preamble        = tmp_params.preamble;
+		info->params.data_rate       = tmp_params.data_rate;
+		info->params.data_bits       = tmp_params.data_bits;
+		info->params.stop_bits       = tmp_params.stop_bits;
+		info->params.parity          = tmp_params.parity;
+	}
 	spin_unlock(&info->lock);
 
- 	change_params(info);
+	program_hw(info);
 
 	return 0;
 }
@@ -1229,13 +1234,12 @@ static long slgt_compat_ioctl(struct tty
 /*
  * proc fs support
  */
-static inline int line_info(char *buf, struct slgt_info *info)
+static inline void line_info(struct seq_file *m, struct slgt_info *info)
 {
 	char stat_buf[30];
-	int ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+	seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
 		      info->device_name, info->phys_reg_addr,
 		      info->irq_level, info->max_frame_size);
 
@@ -1260,75 +1264,70 @@ static inline int line_info(char *buf, s
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode != MGSL_MODE_ASYNC) {
-		ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+		seq_printf(m, "\tHDLC txok:%d rxok:%d",
 			       info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+		seq_printf(m, "\tASYNC tx:%d rx:%d",
 			       info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 		       info->tx_active,info->bh_requested,info->bh_running,
 		       info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int read_proc(char *page, char **start, off_t off, int count,
-		     int *eof, void *data)
+static int synclink_gt_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	struct slgt_info *info;
 
-	len += sprintf(page, "synclink_gt driver\n");
+	seq_puts(m, "synclink_gt driver\n");
 
 	info = slgt_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
+	return 0;
+}
 
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+static int synclink_gt_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, synclink_gt_proc_show, NULL);
 }
 
+static const struct file_operations synclink_gt_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= synclink_gt_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * return count of bytes in transmit buffer
  */
@@ -1763,10 +1762,17 @@ static void hdlcdev_rx(struct slgt_info
 	dev->stats.rx_bytes += size;
 
 	netif_rx(skb);
-
-	dev->last_rx = jiffies;
 }
 
+static const struct net_device_ops hdlcdev_ops = {
+	.ndo_open       = hdlcdev_open,
+	.ndo_stop       = hdlcdev_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hdlcdev_ioctl,
+	.ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
 /**
  * called by device driver when adding device instance
  * do generic HDLC initialization
@@ -1794,11 +1800,8 @@ static int hdlcdev_init(struct slgt_info
 	dev->irq       = info->irq_level;
 
 	/* network layer callbacks and settings */
-	dev->do_ioctl       = hdlcdev_ioctl;
-	dev->open           = hdlcdev_open;
-	dev->stop           = hdlcdev_close;
-	dev->tx_timeout     = hdlcdev_tx_timeout;
-	dev->watchdog_timeo = 10*HZ;
+	dev->netdev_ops	    = &hdlcdev_ops;
+	dev->watchdog_timeo = 10 * HZ;
 	dev->tx_queue_len   = 50;
 
 	/* generic HDLC layer callbacks and settings */
@@ -2561,10 +2564,13 @@ static int set_params(struct slgt_info *
 		return -EFAULT;
 
 	spin_lock_irqsave(&info->lock, flags);
-	memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
+	if (tmp_params.mode == MGSL_MODE_BASE_CLOCK)
+		info->base_clock = tmp_params.clock_speed;
+	else
+		memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
 	spin_unlock_irqrestore(&info->lock, flags);
 
- 	change_params(info);
+	program_hw(info);
 
 	return 0;
 }
@@ -3434,6 +3440,7 @@ static struct slgt_info *alloc_dev(int a
 		info->magic = MGSL_MAGIC;
 		INIT_WORK(&info->task, bh_handler);
 		info->max_frame_size = 4096;
+		info->base_clock = 14745600;
 		info->rbuf_fill_level = DMABUFSIZE;
 		info->port.close_delay = 5*HZ/10;
 		info->port.closing_wait = 30*HZ;
@@ -3558,13 +3565,13 @@ static const struct tty_operations ops =
 	.send_xchar = send_xchar,
 	.break_ctl = set_break,
 	.wait_until_sent = wait_until_sent,
- 	.read_proc = read_proc,
 	.set_termios = set_termios,
 	.stop = tx_hold,
 	.start = tx_release,
 	.hangup = hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &synclink_gt_proc_fops,
 };
 
 static void slgt_cleanup(void)
@@ -3781,7 +3788,7 @@ static void enable_loopback(struct slgt_
 static void set_rate(struct slgt_info *info, u32 rate)
 {
 	unsigned int div;
-	static unsigned int osc = 14745600;
+	unsigned int osc = info->base_clock;
 
 	/* div = osc/rate - 1
 	 *
@@ -4085,18 +4092,27 @@ static void async_mode(struct slgt_info
 	 * 06  CTS      IRQ enable
 	 * 05  DCD      IRQ enable
 	 * 04  RI       IRQ enable
-	 * 03  reserved, must be zero
+	 * 03  0=16x sampling, 1=8x sampling
 	 * 02  1=txd->rxd internal loopback enable
 	 * 01  reserved, must be zero
 	 * 00  1=master IRQ enable
 	 */
 	val = BIT15 + BIT14 + BIT0;
+	/* JCR[8] : 1 = x8 async mode feature available */
+	if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate &&
+	    ((info->base_clock < (info->params.data_rate * 16)) ||
+	     (info->base_clock % (info->params.data_rate * 16)))) {
+		/* use 8x sampling */
+		val |= BIT3;
+		set_rate(info, info->params.data_rate * 8);
+	} else {
+		/* use 16x sampling */
+		set_rate(info, info->params.data_rate * 16);
+	}
 	wr_reg16(info, SCR, val);
 
 	slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
 
-	set_rate(info, info->params.data_rate * 16);
-
 	if (info->params.loopback)
 		enable_loopback(info);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/synclinkmp.c linux-libre-2.6.30-gnu1/drivers/char/synclinkmp.c
--- linux-libre-2.6.29-gnu1/drivers/char/synclinkmp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/synclinkmp.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -520,7 +521,6 @@ static void tx_hold(struct tty_struct *t
 static void tx_release(struct tty_struct *tty);
 
 static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
@@ -1354,13 +1354,12 @@ static int ioctl(struct tty_struct *tty,
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, SLMP_INFO *info)
+static inline void line_info(struct seq_file *m, SLMP_INFO *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
+	seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
 		       "\tIRQ=%d MaxFrameSize=%u\n",
 		info->device_name,
 		info->phys_sca_base,
@@ -1391,75 +1390,70 @@ static inline int line_info(char *buf, S
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode == MGSL_MODE_HDLC) {
-		ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+		seq_printf(m, "\tHDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+			seq_printf(m, " rxlong:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+		seq_printf(m, "\tASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 	 info->tx_active,info->bh_requested,info->bh_running,
 	 info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int read_proc(char *page, char **start, off_t off, int count,
-	      int *eof, void *data)
+static int synclinkmp_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	SLMP_INFO *info;
 
-	len += sprintf(page, "synclinkmp driver:%s\n", driver_version);
+	seq_printf(m, "synclinkmp driver:%s\n", driver_version);
 
 	info = synclinkmp_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
+	return 0;
+}
 
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+static int synclinkmp_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, synclinkmp_proc_show, NULL);
 }
 
+static const struct file_operations synclinkmp_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= synclinkmp_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* Return the count of bytes in transmit buffer
  */
 static int chars_in_buffer(struct tty_struct *tty)
@@ -1907,10 +1901,17 @@ static void hdlcdev_rx(SLMP_INFO *info,
 	dev->stats.rx_bytes += size;
 
 	netif_rx(skb);
-
-	dev->last_rx = jiffies;
 }
 
+static const struct net_device_ops hdlcdev_ops = {
+	.ndo_open       = hdlcdev_open,
+	.ndo_stop       = hdlcdev_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hdlcdev_ioctl,
+	.ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
 /**
  * called by device driver when adding device instance
  * do generic HDLC initialization
@@ -1938,11 +1939,8 @@ static int hdlcdev_init(SLMP_INFO *info)
 	dev->irq       = info->irq_level;
 
 	/* network layer callbacks and settings */
-	dev->do_ioctl       = hdlcdev_ioctl;
-	dev->open           = hdlcdev_open;
-	dev->stop           = hdlcdev_close;
-	dev->tx_timeout     = hdlcdev_tx_timeout;
-	dev->watchdog_timeo = 10*HZ;
+	dev->netdev_ops	    = &hdlcdev_ops;
+	dev->watchdog_timeo = 10 * HZ;
 	dev->tx_queue_len   = 50;
 
 	/* generic HDLC layer callbacks and settings */
@@ -3901,13 +3899,13 @@ static const struct tty_operations ops =
 	.send_xchar = send_xchar,
 	.break_ctl = set_break,
 	.wait_until_sent = wait_until_sent,
- 	.read_proc = read_proc,
 	.set_termios = set_termios,
 	.stop = tx_hold,
 	.start = tx_release,
 	.hangup = hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &synclinkmp_proc_fops,
 };
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/sysrq.c linux-libre-2.6.30-gnu1/drivers/char/sysrq.c
--- linux-libre-2.6.29-gnu1/drivers/char/sysrq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/sysrq.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/vt_kern.h>
 #include <linux/workqueue.h>
 #include <linux/kexec.h>
-#include <linux/irq.h>
 #include <linux/hrtimer.h>
 #include <linux/oom.h>
 
@@ -283,7 +282,7 @@ static void sysrq_ftrace_dump(int key, s
 }
 static struct sysrq_key_op sysrq_ftrace_dump_op = {
 	.handler	= sysrq_ftrace_dump,
-	.help_msg	= "dumpZ-ftrace-buffer",
+	.help_msg	= "dump-ftrace-buffer(Z)",
 	.action_msg	= "Dump ftrace buffer",
 	.enable_mask	= SYSRQ_ENABLE_DUMP,
 };
@@ -346,6 +345,19 @@ static struct sysrq_key_op sysrq_moom_op
 	.enable_mask	= SYSRQ_ENABLE_SIGNAL,
 };
 
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key, struct tty_struct *tty)
+{
+	emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+	.handler	= sysrq_handle_thaw,
+	.help_msg	= "thaw-filesystems(J)",
+	.action_msg	= "Emergency Thaw of all frozen filesystems",
+	.enable_mask	= SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
 static void sysrq_handle_kill(int key, struct tty_struct *tty)
 {
 	send_sig_all(SIGKILL);
@@ -394,11 +406,15 @@ static struct sysrq_key_op *sysrq_key_ta
 	&sysrq_showlocks_op,		/* d */
 	&sysrq_term_op,			/* e */
 	&sysrq_moom_op,			/* f */
-	/* g: May be registered by ppc for kgdb */
+	/* g: May be registered for the kernel debugger */
 	NULL,				/* g */
-	NULL,				/* h */
+	NULL,				/* h - reserved for help */
 	&sysrq_kill_op,			/* i */
+#ifdef CONFIG_BLOCK
+	&sysrq_thaw_op,			/* j */
+#else
 	NULL,				/* j */
+#endif
 	&sysrq_SAK_op,			/* k */
 #ifdef CONFIG_SMP
 	&sysrq_showallcpus_op,		/* l */
@@ -415,7 +431,7 @@ static struct sysrq_key_op *sysrq_key_ta
 	&sysrq_sync_op,			/* s */
 	&sysrq_showstate_op,		/* t */
 	&sysrq_mountro_op,		/* u */
-	/* v: May be registered at init time by SMP VOYAGER */
+	/* v: May be registered for frame buffer console restore */
 	NULL,				/* v */
 	&sysrq_showstate_blocked_op,	/* w */
 	/* x: May be registered on ppc/powerpc for xmon */
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_atmel.c linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_atmel.c
--- linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_atmel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_atmel.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
 	}
 }
 
-static struct device_driver atml_drv = {
-	.name = "tpm_atmel",
-	.bus = &platform_bus_type,
-	.owner = THIS_MODULE,
-	.suspend = tpm_pm_suspend,
-	.resume = tpm_pm_resume,
+static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
+{
+	return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_atml_resume(struct platform_device *dev)
+{
+	return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver atml_drv = {
+	.driver = {
+		.name = "tpm_atmel",
+		.owner		= THIS_MODULE,
+	},
+	.suspend = tpm_atml_suspend,
+	.resume = tpm_atml_resume,
 };
 
 static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
 	unsigned long base;
 	struct  tpm_chip *chip;
 
-	rc = driver_register(&atml_drv);
+	rc = platform_driver_register(&atml_drv);
 	if (rc)
 		return rc;
 
@@ -223,13 +233,13 @@ err_rel_reg:
 		atmel_release_region(base,
 				     region_size);
 err_unreg_drv:
-	driver_unregister(&atml_drv);
+	platform_driver_unregister(&atml_drv);
 	return rc;
 }
 
 static void __exit cleanup_atmel(void)
 {
-	driver_unregister(&atml_drv);
+	platform_driver_unregister(&atml_drv);
 	atml_plat_remove();
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_bios.c linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_bios.c
--- linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_bios.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_bios.c	2009-06-09 23:05:27.000000000 -0400
@@ -212,7 +212,8 @@ static int get_event_name(char *dest, st
 			unsigned char * event_entry)
 {
 	const char *name = "";
-	char data[40] = "";
+	/* 41 so there is room for 40 data and 1 nul */
+	char data[41] = "";
 	int i, n_len = 0, d_len = 0;
 	struct tcpa_pc_event *pc_event;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm.c linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm.c
--- linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm.c	2009-06-09 23:05:27.000000000 -0400
@@ -429,134 +429,148 @@ out:
 #define TPM_DIGEST_SIZE 20
 #define TPM_ERROR_SIZE 10
 #define TPM_RET_CODE_IDX 6
-#define TPM_GET_CAP_RET_SIZE_IDX 10
-#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-
-#define TPM_CAP_IDX 13
-#define TPM_CAP_SUBCAP_IDX 21
 
 enum tpm_capabilities {
-	TPM_CAP_FLAG = 4,
-	TPM_CAP_PROP = 5,
+	TPM_CAP_FLAG = cpu_to_be32(4),
+	TPM_CAP_PROP = cpu_to_be32(5),
+	CAP_VERSION_1_1 = cpu_to_be32(0x06),
+	CAP_VERSION_1_2 = cpu_to_be32(0x1A)
 };
 
 enum tpm_sub_capabilities {
-	TPM_CAP_PROP_PCR = 0x1,
-	TPM_CAP_PROP_MANUFACTURER = 0x3,
-	TPM_CAP_FLAG_PERM = 0x8,
-	TPM_CAP_FLAG_VOL = 0x9,
-	TPM_CAP_PROP_OWNER = 0x11,
-	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
-	TPM_CAP_PROP_TIS_DURATION = 0x20,
-};
-
-/*
- * This is a semi generic GetCapability command for use
- * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
- * and their associated sub_capabilities.
- */
+	TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
+	TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
+	TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
+	TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
+	TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
+	TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+	TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
 
-static const u8 tpm_cap[] = {
-	0, 193,			/* TPM_TAG_RQU_COMMAND */
-	0, 0, 0, 22,		/* length */
-	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
-	0, 0, 0, 0,		/* TPM_CAP_<TYPE> */
-	0, 0, 0, 4,		/* TPM_CAP_SUB_<TYPE> size */
-	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
 };
 
-static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
-			    char *desc)
+static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
+			    int len, const char *desc)
 {
 	int err;
 
-	len = tpm_transmit(chip, data, len);
+	len = tpm_transmit(chip,(u8 *) cmd, len);
 	if (len <  0)
 		return len;
 	if (len == TPM_ERROR_SIZE) {
-		err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
+		err = be32_to_cpu(cmd->header.out.return_code);
 		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
 		return err;
 	}
 	return 0;
 }
 
+#define TPM_INTERNAL_RESULT_SIZE 200
+#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
+#define TPM_ORD_GET_CAP cpu_to_be32(101)
+
+static const struct tpm_input_header tpm_getcap_header = {
+	.tag = TPM_TAG_RQU_COMMAND,
+	.length = cpu_to_be32(22),
+	.ordinal = TPM_ORD_GET_CAP
+};
+
+ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
+		   const char *desc)
+{
+	struct tpm_cmd_t tpm_cmd;
+	int rc;
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+
+	tpm_cmd.header.in = tpm_getcap_header;
+	if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
+		tpm_cmd.params.getcap_in.cap = subcap_id;
+		/*subcap field not necessary */
+		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
+		tpm_cmd.header.in.length -= cpu_to_be32(sizeof(__be32));
+	} else {
+		if (subcap_id == TPM_CAP_FLAG_PERM ||
+		    subcap_id == TPM_CAP_FLAG_VOL)
+			tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
+		else
+			tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+		tpm_cmd.params.getcap_in.subcap = subcap_id;
+	}
+	rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
+	if (!rc)
+		*cap = tpm_cmd.params.getcap_out.cap;
+	return rc;
+}
+
 void tpm_gen_interrupt(struct tpm_chip *chip)
 {
-	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+	struct	tpm_cmd_t tpm_cmd;
 	ssize_t rc;
 
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+	tpm_cmd.header.in = tpm_getcap_header;
+	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
 
-	rc = transmit_cmd(chip, data, sizeof(data),
+	rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
 			"attempting to determine the timeouts");
 }
 EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
 
 void tpm_get_timeouts(struct tpm_chip *chip)
 {
-	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+	struct tpm_cmd_t tpm_cmd;
+	struct timeout_t *timeout_cap;
+	struct duration_t *duration_cap;
 	ssize_t rc;
 	u32 timeout;
 
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+	tpm_cmd.header.in = tpm_getcap_header;
+	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
 
-	rc = transmit_cmd(chip, data, sizeof(data),
+	rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
 			"attempting to determine the timeouts");
 	if (rc)
 		goto duration;
 
-	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+	if (be32_to_cpu(tpm_cmd.header.out.length)
 	    != 4 * sizeof(u32))
 		goto duration;
 
+	timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
 	/* Don't overwrite default if value is 0 */
-	timeout =
-	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+	timeout = be32_to_cpu(timeout_cap->a);
 	if (timeout)
 		chip->vendor.timeout_a = usecs_to_jiffies(timeout);
-	timeout =
-	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+	timeout = be32_to_cpu(timeout_cap->b);
 	if (timeout)
 		chip->vendor.timeout_b = usecs_to_jiffies(timeout);
-	timeout =
-	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+	timeout = be32_to_cpu(timeout_cap->c);
 	if (timeout)
 		chip->vendor.timeout_c = usecs_to_jiffies(timeout);
-	timeout =
-	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+	timeout = be32_to_cpu(timeout_cap->d);
 	if (timeout)
 		chip->vendor.timeout_d = usecs_to_jiffies(timeout);
 
 duration:
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+	tpm_cmd.header.in = tpm_getcap_header;
+	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
 
-	rc = transmit_cmd(chip, data, sizeof(data),
+	rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
 			"attempting to determine the durations");
 	if (rc)
 		return;
 
-	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+	if (be32_to_cpu(tpm_cmd.header.out.return_code)
 	    != 3 * sizeof(u32))
 		return;
-
+	duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
 	chip->vendor.duration[TPM_SHORT] =
-	    usecs_to_jiffies(be32_to_cpu
-			     (*((__be32 *) (data +
-					    TPM_GET_CAP_RET_UINT32_1_IDX))));
+	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
 	/* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
 	 * value wrong and apparently reports msecs rather than usecs. So we
 	 * fix up the resulting too-small TPM_SHORT value to make things work.
@@ -565,13 +579,9 @@ duration:
 		chip->vendor.duration[TPM_SHORT] = HZ;
 
 	chip->vendor.duration[TPM_MEDIUM] =
-	    usecs_to_jiffies(be32_to_cpu
-			     (*((__be32 *) (data +
-					    TPM_GET_CAP_RET_UINT32_2_IDX))));
+	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
 	chip->vendor.duration[TPM_LONG] =
-	    usecs_to_jiffies(be32_to_cpu
-			     (*((__be32 *) (data +
-					    TPM_GET_CAP_RET_UINT32_3_IDX))));
+	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
 }
 EXPORT_SYMBOL_GPL(tpm_get_timeouts);
 
@@ -587,36 +597,18 @@ void tpm_continue_selftest(struct tpm_ch
 }
 EXPORT_SYMBOL_GPL(tpm_continue_selftest);
 
-#define  TPM_INTERNAL_RESULT_SIZE 200
-
 ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
 			char *buf)
 {
-	u8 *data;
+	cap_t cap;
 	ssize_t rc;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-			"attemtping to determine the permanent enabled state");
-	if (rc) {
-		kfree(data);
+	rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+			 "attempting to determine the permanent enabled state");
+	if (rc)
 		return 0;
-	}
-
-	rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
 
-	kfree(data);
+	rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_enabled);
@@ -624,31 +616,15 @@ EXPORT_SYMBOL_GPL(tpm_show_enabled);
 ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
 			char *buf)
 {
-	u8 *data;
+	cap_t cap;
 	ssize_t rc;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-			"attemtping to determine the permanent active state");
-	if (rc) {
-		kfree(data);
+	rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+			 "attempting to determine the permanent active state");
+	if (rc)
 		return 0;
-	}
-
-	rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
 
-	kfree(data);
+	rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_active);
@@ -656,31 +632,15 @@ EXPORT_SYMBOL_GPL(tpm_show_active);
 ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
 			char *buf)
 {
-	u8 *data;
+	cap_t cap;
 	ssize_t rc;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-			"attempting to determine the owner state");
-	if (rc) {
-		kfree(data);
+	rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
+			 "attempting to determine the owner state");
+	if (rc)
 		return 0;
-	}
 
-	rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
-
-	kfree(data);
+	rc = sprintf(buf, "%d\n", cap.owned);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_owned);
@@ -688,116 +648,180 @@ EXPORT_SYMBOL_GPL(tpm_show_owned);
 ssize_t tpm_show_temp_deactivated(struct device * dev,
 				struct device_attribute * attr, char *buf)
 {
-	u8 *data;
+	cap_t cap;
 	ssize_t rc;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
+	rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
+			 "attempting to determine the temporary state");
+	if (rc)
+		return 0;
 
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
+	rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
 
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+/*
+ * tpm_chip_find_get - return tpm_chip for given chip number
+ */
+static struct tpm_chip *tpm_chip_find_get(int chip_num)
+{
+	struct tpm_chip *pos, *chip = NULL;
 
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-			"attempting to determine the temporary state");
-	if (rc) {
-		kfree(data);
-		return 0;
+	rcu_read_lock();
+	list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
+		if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
+			continue;
+
+		if (try_module_get(pos->dev->driver->owner)) {
+			chip = pos;
+			break;
+		}
 	}
+	rcu_read_unlock();
+	return chip;
+}
 
-	rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+#define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
+#define READ_PCR_RESULT_SIZE 30
+static struct tpm_input_header pcrread_header = {
+	.tag = TPM_TAG_RQU_COMMAND,
+	.length = cpu_to_be32(14),
+	.ordinal = TPM_ORDINAL_PCRREAD
+};
 
-	kfree(data);
+int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+{
+	int rc;
+	struct tpm_cmd_t cmd;
+
+	cmd.header.in = pcrread_header;
+	cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+	BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
+	rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+			  "attempting to read a pcr value");
+
+	if (rc == 0)
+		memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
+		       TPM_DIGEST_SIZE);
 	return rc;
 }
-EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
 
-static const u8 pcrread[] = {
-	0, 193,			/* TPM_TAG_RQU_COMMAND */
-	0, 0, 0, 14,		/* length */
-	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
-	0, 0, 0, 0		/* PCR index */
+/**
+ * tpm_pcr_read - read a pcr value
+ * @chip_num: 	tpm idx # or ANY
+ * @pcr_idx:	pcr idx to retrieve
+ * @res_buf: 	TPM_PCR value
+ * 		size of res_buf is 20 bytes (or NULL if you don't care)
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
+{
+	struct tpm_chip *chip;
+	int rc;
+
+	chip = tpm_chip_find_get(chip_num);
+	if (chip == NULL)
+		return -ENODEV;
+	rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
+	module_put(chip->dev->driver->owner);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_read);
+
+/**
+ * tpm_pcr_extend - extend pcr value with hash
+ * @chip_num: 	tpm idx # or AN&
+ * @pcr_idx:	pcr idx to extend
+ * @hash: 	hash value used to extend pcr value
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+#define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
+#define EXTEND_PCR_SIZE 34
+static struct tpm_input_header pcrextend_header = {
+	.tag = TPM_TAG_RQU_COMMAND,
+	.length = cpu_to_be32(34),
+	.ordinal = TPM_ORD_PCR_EXTEND
 };
 
+int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+{
+	struct tpm_cmd_t cmd;
+	int rc;
+	struct tpm_chip *chip;
+
+	chip = tpm_chip_find_get(chip_num);
+	if (chip == NULL)
+		return -ENODEV;
+
+	cmd.header.in = pcrextend_header;
+	BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
+	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+	memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+	rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+			  "attempting extend a PCR value");
+
+	module_put(chip->dev->driver->owner);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_extend);
+
 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
 		      char *buf)
 {
-	u8 *data;
+	cap_t cap;
+	u8 digest[TPM_DIGEST_SIZE];
 	ssize_t rc;
 	int i, j, num_pcrs;
-	__be32 index;
 	char *str = buf;
-
 	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
 
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+	rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
 			"attempting to determine the number of PCRS");
-	if (rc) {
-		kfree(data);
+	if (rc)
 		return 0;
-	}
 
-	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
+	num_pcrs = be32_to_cpu(cap.num_pcrs);
 	for (i = 0; i < num_pcrs; i++) {
-		memcpy(data, pcrread, sizeof(pcrread));
-		index = cpu_to_be32(i);
-		memcpy(data + 10, &index, 4);
-		rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-				"attempting to read a PCR");
+		rc = __tpm_pcr_read(chip, i, digest);
 		if (rc)
-			goto out;
+			break;
 		str += sprintf(str, "PCR-%02d: ", i);
 		for (j = 0; j < TPM_DIGEST_SIZE; j++)
-			str += sprintf(str, "%02X ", *(data + 10 + j));
+			str += sprintf(str, "%02X ", digest[j]);
 		str += sprintf(str, "\n");
 	}
-out:
-	kfree(data);
 	return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pcrs);
 
 #define  READ_PUBEK_RESULT_SIZE 314
-static const u8 readpubek[] = {
-	0, 193,			/* TPM_TAG_RQU_COMMAND */
-	0, 0, 0, 30,		/* length */
-	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
+#define TPM_ORD_READPUBEK cpu_to_be32(124)
+struct tpm_input_header tpm_readpubek_header = {
+	.tag = TPM_TAG_RQU_COMMAND,
+	.length = cpu_to_be32(30),
+	.ordinal = TPM_ORD_READPUBEK
 };
 
 ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
 		       char *buf)
 {
 	u8 *data;
+	struct tpm_cmd_t tpm_cmd;
 	ssize_t err;
 	int i, rc;
 	char *str = buf;
 
 	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, readpubek, sizeof(readpubek));
 
-	err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+	tpm_cmd.header.in = tpm_readpubek_header;
+	err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
 			"attempting to read the PUBEK");
 	if (err)
 		goto out;
@@ -812,7 +836,7 @@ ssize_t tpm_show_pubek(struct device *de
 	   256 byte modulus
 	   ignore checksum 20 bytes
 	 */
-
+	data = tpm_cmd.params.readpubek_out_buffer;
 	str +=
 	    sprintf(str,
 		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -832,65 +856,33 @@ ssize_t tpm_show_pubek(struct device *de
 	}
 out:
 	rc = str - buf;
-	kfree(data);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
-#define CAP_VERSION_1_1 6
-#define CAP_VERSION_1_2 0x1A
-#define CAP_VERSION_IDX 13
-static const u8 cap_version[] = {
-	0, 193,			/* TPM_TAG_RQU_COMMAND */
-	0, 0, 0, 18,		/* length */
-	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
-	0, 0, 0, 0,
-	0, 0, 0, 0
-};
 
 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
 		      char *buf)
 {
-	u8 *data;
+	cap_t cap;
 	ssize_t rc;
 	char *str = buf;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+	rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
 			"attempting to determine the manufacturer");
-	if (rc) {
-		kfree(data);
+	if (rc)
 		return 0;
-	}
-
 	str += sprintf(str, "Manufacturer: 0x%x\n",
-		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+		       be32_to_cpu(cap.manufacturer_id));
 
-	memcpy(data, cap_version, sizeof(cap_version));
-	data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
-	rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
-			"attempting to determine the 1.1 version");
+	rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
+		        "attempting to determine the 1.1 version");
 	if (rc)
-		goto out;
-
+		return 0;
 	str += sprintf(str,
 		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
-		       (int) data[14], (int) data[15], (int) data[16],
-		       (int) data[17]);
-
-out:
-	kfree(data);
+		       cap.tpm_version.Major, cap.tpm_version.Minor,
+		       cap.tpm_version.revMajor, cap.tpm_version.revMinor);
 	return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps);
@@ -898,51 +890,25 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
 ssize_t tpm_show_caps_1_2(struct device * dev,
 			  struct device_attribute * attr, char *buf)
 {
-	u8 *data;
-	ssize_t len;
+	cap_t cap;
+	ssize_t rc;
 	char *str = buf;
 
-	struct tpm_chip *chip = dev_get_drvdata(dev);
-	if (chip == NULL)
-		return -ENODEV;
-
-	data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	memcpy(data, tpm_cap, sizeof(tpm_cap));
-	data[TPM_CAP_IDX] = TPM_CAP_PROP;
-	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
-	len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
-	if (len <= TPM_ERROR_SIZE) {
-		dev_dbg(chip->dev, "A TPM error (%d) occurred "
-			"attempting to determine the manufacturer\n",
-			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-		kfree(data);
+	rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
+			"attempting to determine the manufacturer");
+	if (rc)
 		return 0;
-	}
-
 	str += sprintf(str, "Manufacturer: 0x%x\n",
-		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
-
-	memcpy(data, cap_version, sizeof(cap_version));
-	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
-
-	len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
-	if (len <= TPM_ERROR_SIZE) {
-		dev_err(chip->dev, "A TPM error (%d) occurred "
-			"attempting to determine the 1.2 version\n",
-			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-		goto out;
-	}
+		       be32_to_cpu(cap.manufacturer_id));
+	rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
+			 "attempting to determine the 1.2 version");
+	if (rc)
+		return 0;
 	str += sprintf(str,
 		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
-		       (int) data[16], (int) data[17], (int) data[18],
-		       (int) data[19]);
-
-out:
-	kfree(data);
+		       cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor,
+		       cap.tpm_version_1_2.revMajor,
+		       cap.tpm_version_1_2.revMinor);
 	return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm.h linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm.h
--- linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/miscdevice.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/tpm.h>
 
 enum tpm_timeout {
 	TPM_TIMEOUT = 5,	/* msecs */
@@ -123,6 +124,147 @@ static inline void tpm_write_index(int b
 	outb(index, base);
 	outb(value & 0xFF, base+1);
 }
+struct tpm_input_header {
+	__be16	tag;
+	__be32	length;
+	__be32	ordinal;
+}__attribute__((packed));
+
+struct tpm_output_header {
+	__be16	tag;
+	__be32	length;
+	__be32	return_code;
+}__attribute__((packed));
+
+struct	stclear_flags_t {
+	__be16	tag;
+	u8	deactivated;
+	u8	disableForceClear;
+	u8	physicalPresence;
+	u8	physicalPresenceLock;
+	u8	bGlobalLock;
+}__attribute__((packed));
+
+struct	tpm_version_t {
+	u8	Major;
+	u8	Minor;
+	u8	revMajor;
+	u8	revMinor;
+}__attribute__((packed));
+
+struct	tpm_version_1_2_t {
+	__be16	tag;
+	u8	Major;
+	u8	Minor;
+	u8	revMajor;
+	u8	revMinor;
+}__attribute__((packed));
+
+struct	timeout_t {
+	__be32	a;
+	__be32	b;
+	__be32	c;
+	__be32	d;
+}__attribute__((packed));
+
+struct duration_t {
+	__be32	tpm_short;
+	__be32	tpm_medium;
+	__be32	tpm_long;
+}__attribute__((packed));
+
+struct permanent_flags_t {
+	__be16	tag;
+	u8	disable;
+	u8	ownership;
+	u8	deactivated;
+	u8	readPubek;
+	u8	disableOwnerClear;
+	u8	allowMaintenance;
+	u8	physicalPresenceLifetimeLock;
+	u8	physicalPresenceHWEnable;
+	u8	physicalPresenceCMDEnable;
+	u8	CEKPUsed;
+	u8	TPMpost;
+	u8	TPMpostLock;
+	u8	FIPS;
+	u8	operator;
+	u8	enableRevokeEK;
+	u8	nvLocked;
+	u8	readSRKPub;
+	u8	tpmEstablished;
+	u8	maintenanceDone;
+	u8	disableFullDALogicInfo;
+}__attribute__((packed));
+
+typedef union {
+	struct	permanent_flags_t perm_flags;
+	struct	stclear_flags_t	stclear_flags;
+	bool	owned;
+	__be32	num_pcrs;
+	struct	tpm_version_t	tpm_version;
+	struct	tpm_version_1_2_t tpm_version_1_2;
+	__be32	manufacturer_id;
+	struct timeout_t  timeout;
+	struct duration_t duration;
+} cap_t;
+
+struct	tpm_getcap_params_in {
+	__be32	cap;
+	__be32	subcap_size;
+	__be32	subcap;
+}__attribute__((packed));
+
+struct	tpm_getcap_params_out {
+	__be32	cap_size;
+	cap_t	cap;
+}__attribute__((packed));
+
+struct	tpm_readpubek_params_out {
+	u8	algorithm[4];
+	u8	encscheme[2];
+	u8	sigscheme[2];
+	u8	parameters[12]; /*assuming RSA*/
+	__be32	keysize;
+	u8	modulus[256];
+	u8	checksum[20];
+}__attribute__((packed));
+
+typedef union {
+	struct	tpm_input_header in;
+	struct	tpm_output_header out;
+} tpm_cmd_header;
+
+#define TPM_DIGEST_SIZE 20
+struct tpm_pcrread_out {
+	u8	pcr_result[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+struct tpm_pcrread_in {
+	__be32	pcr_idx;
+}__attribute__((packed));
+
+struct tpm_pcrextend_in {
+	__be32	pcr_idx;
+	u8	hash[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+typedef union {
+	struct	tpm_getcap_params_out getcap_out;
+	struct	tpm_readpubek_params_out readpubek_out;
+	u8	readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
+	struct	tpm_getcap_params_in getcap_in;
+	struct	tpm_pcrread_in	pcrread_in;
+	struct	tpm_pcrread_out	pcrread_out;
+	struct	tpm_pcrextend_in pcrextend_in;
+} tpm_cmd_params;
+
+struct tpm_cmd_t {
+	tpm_cmd_header	header;
+	tpm_cmd_params	params;
+}__attribute__((packed));
+
+ssize_t	tpm_getcap(struct device *, __be32, cap_t *, const char *);
 
 extern void tpm_get_timeouts(struct tpm_chip *);
 extern void tpm_gen_interrupt(struct tpm_chip *);
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_tis.c linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_tis.c
--- linux-libre-2.6.29-gnu1/drivers/char/tpm/tpm_tis.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_tis.c	2009-06-09 23:05:27.000000000 -0400
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS
 		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 
-static struct device_driver tis_drv = {
-	.name = "tpm_tis",
-	.bus = &platform_bus_type,
-	.owner = THIS_MODULE,
-	.suspend = tpm_pm_suspend,
-	.resume = tpm_pm_resume,
+static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
+{
+	return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_resume(struct platform_device *dev)
+{
+	return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver tis_drv = {
+	.driver = {
+		.name = "tpm_tis",
+		.owner		= THIS_MODULE,
+	},
+	.suspend = tpm_tis_suspend,
+	.resume = tpm_tis_resume,
 };
 
 static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
 	int rc;
 
 	if (force) {
-		rc = driver_register(&tis_drv);
+		rc = platform_driver_register(&tis_drv);
 		if (rc < 0)
 			return rc;
 		if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
 			return PTR_ERR(pdev);
 		if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
 			platform_device_unregister(pdev);
-			driver_unregister(&tis_drv);
+			platform_driver_unregister(&tis_drv);
 		}
 		return rc;
 	}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
 
 	if (force) {
 		platform_device_unregister(pdev);
-		driver_unregister(&tis_drv);
+		platform_driver_unregister(&tis_drv);
 	} else
 		pnp_unregister_driver(&tis_pnp_driver);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tty_audit.c linux-libre-2.6.30-gnu1/drivers/char/tty_audit.c
--- linux-libre-2.6.29-gnu1/drivers/char/tty_audit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tty_audit.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,8 +10,6 @@
  */
 
 #include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
 #include <linux/tty.h>
 
 struct tty_audit_buf {
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tty_io.c linux-libre-2.6.30-gnu1/drivers/char/tty_io.c
--- linux-libre-2.6.29-gnu1/drivers/char/tty_io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tty_io.c	2009-06-09 23:05:27.000000000 -0400
@@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty)
 			tty_ldisc_deref(ld);
 		}
 	}
-	wake_up_interruptible(&tty->write_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 }
 
 EXPORT_SYMBOL_GPL(tty_wakeup);
@@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_st
 	 * FIXME: Once we trust the LDISC code better we can wait here for
 	 * ldisc completion and fix the driver call race
 	 */
-	wake_up_interruptible(&tty->write_wait);
-	wake_up_interruptible(&tty->read_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+	wake_up_interruptible_poll(&tty->read_wait, POLLIN);
 	/*
 	 * Shutdown the current line discipline, and reset it to
 	 * N_TTY.
@@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty)
 	if (tty->link && tty->link->packet) {
 		tty->ctrl_status &= ~TIOCPKT_START;
 		tty->ctrl_status |= TIOCPKT_STOP;
-		wake_up_interruptible(&tty->link->read_wait);
+		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
 	}
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	if (tty->ops->stop)
@@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty)
 	if (tty->link && tty->link->packet) {
 		tty->ctrl_status &= ~TIOCPKT_STOP;
 		tty->ctrl_status |= TIOCPKT_START;
-		wake_up_interruptible(&tty->link->read_wait);
+		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
 	}
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	if (tty->ops->start)
@@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *fil
 void tty_write_unlock(struct tty_struct *tty)
 {
 	mutex_unlock(&tty->atomic_write_lock);
-	wake_up_interruptible(&tty->write_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 }
 
 int tty_write_lock(struct tty_struct *tty, int ndelay)
@@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp)
 
 		if (tty_closing) {
 			if (waitqueue_active(&tty->read_wait)) {
-				wake_up(&tty->read_wait);
+				wake_up_poll(&tty->read_wait, POLLIN);
 				do_sleep++;
 			}
 			if (waitqueue_active(&tty->write_wait)) {
-				wake_up(&tty->write_wait);
+				wake_up_poll(&tty->write_wait, POLLOUT);
 				do_sleep++;
 			}
 		}
 		if (o_tty_closing) {
 			if (waitqueue_active(&o_tty->read_wait)) {
-				wake_up(&o_tty->read_wait);
+				wake_up_poll(&o_tty->read_wait, POLLIN);
 				do_sleep++;
 			}
 			if (waitqueue_active(&o_tty->write_wait)) {
-				wake_up(&o_tty->write_wait);
+				wake_up_poll(&o_tty->write_wait, POLLOUT);
 				do_sleep++;
 			}
 		}
@@ -1758,7 +1758,7 @@ static int __tty_open(struct inode *inod
 	struct tty_driver *driver;
 	int index;
 	dev_t device = inode->i_rdev;
-	unsigned short saved_flags = filp->f_flags;
+	unsigned saved_flags = filp->f_flags;
 
 	nonseekable_open(inode, filp);
 
@@ -2162,13 +2162,12 @@ static int fionbio(struct file *file, in
 	if (get_user(nonblock, p))
 		return -EFAULT;
 
-	/* file->f_flags is still BKL protected in the fs layer - vomit */
-	lock_kernel();
+	spin_lock(&file->f_lock);
 	if (nonblock)
 		file->f_flags |= O_NONBLOCK;
 	else
 		file->f_flags &= ~O_NONBLOCK;
-	unlock_kernel();
+	spin_unlock(&file->f_lock);
 	return 0;
 }
 
@@ -2682,7 +2681,7 @@ void __do_SAK(struct tty_struct *tty)
 	/* Kill the entire session */
 	do_each_pid_task(session, PIDTYPE_SID, p) {
 		printk(KERN_NOTICE "SAK: killed process %d"
-			" (%s): task_session_nr(p)==tty->session\n",
+			" (%s): task_session(p)==tty->session\n",
 			task_pid_nr(p), p->comm);
 		send_sig(SIGKILL, p, 1);
 	} while_each_pid_task(session, PIDTYPE_SID, p);
@@ -2692,7 +2691,7 @@ void __do_SAK(struct tty_struct *tty)
 	do_each_thread(g, p) {
 		if (p->signal->tty == tty) {
 			printk(KERN_NOTICE "SAK: killed process %d"
-			    " (%s): task_session_nr(p)==tty->session\n",
+			    " (%s): task_session(p)==tty->session\n",
 			    task_pid_nr(p), p->comm);
 			send_sig(SIGKILL, p, 1);
 			continue;
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/tty_ldisc.c linux-libre-2.6.30-gnu1/drivers/char/tty_ldisc.c
--- linux-libre-2.6.29-gnu1/drivers/char/tty_ldisc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/tty_ldisc.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/tty_flip.h>
 #include <linux/devpts_fs.h>
 #include <linux/file.h>
-#include <linux/fdtable.h>
 #include <linux/console.h>
 #include <linux/timer.h>
 #include <linux/ctype.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/vc_screen.c linux-libre-2.6.30-gnu1/drivers/char/vc_screen.c
--- linux-libre-2.6.29-gnu1/drivers/char/vc_screen.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/vc_screen.c	2009-06-09 23:05:27.000000000 -0400
@@ -479,18 +479,18 @@ static const struct file_operations vcs_
 
 static struct class *vc_class;
 
-void vcs_make_sysfs(struct tty_struct *tty)
+void vcs_make_sysfs(int index)
 {
-	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
-		      "vcs%u", tty->index + 1);
-	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
-		      "vcsa%u", tty->index + 1);
+	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
+		      "vcs%u", index + 1);
+	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
+		      "vcsa%u", index + 1);
 }
 
-void vcs_remove_sysfs(struct tty_struct *tty)
+void vcs_remove_sysfs(int index)
 {
-	device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
-	device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
+	device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
+	device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
 }
 
 int __init vcs_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/vt.c linux-libre-2.6.30-gnu1/drivers/char/vt.c
--- linux-libre-2.6.29-gnu1/drivers/char/vt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/vt.c	2009-06-09 23:05:27.000000000 -0400
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons)	/
 	    }
 	    vc->vc_kmalloced = 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);
 	}
 	return 0;
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons
 	if (vc_cons_allocated(currcons)) {
 		struct vc_data *vc = vc_cons[currcons].d;
 		struct vt_notifier_param param = { .vc = vc };
+
 		atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+		vcs_remove_sysfs(currcons);
 		vc->vc_sw->con_deinit(vc);
 		put_pid(vc->vt_pid);
 		module_put(vc->vc_sw->owner);
@@ -2271,7 +2274,7 @@ rescan_last_byte:
 				    continue; /* nothing to display */
 				}
 				/* Glyph not found */
-				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) && c < 128) && !(c & ~charmask)) {
+				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
 				    /* In legacy mode use the glyph we get by a 1:1 mapping.
 				       This would make absolutely no sense with Unicode in mind,
 				       but do this for ASCII characters since a font may lack
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *t
 				tty->termios->c_iflag |= IUTF8;
 			else
 				tty->termios->c_iflag &= ~IUTF8;
-			vcs_make_sysfs(tty);
 			release_console_sem();
 			return ret;
 		}
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_stru
 	BUG_ON(vc == NULL);
 	acquire_console_sem();
 	vc->vc_tty = NULL;
-	vcs_remove_sysfs(tty);
 	release_console_sem();
 	tty_shutdown(tty);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/char/vt_ioctl.c linux-libre-2.6.30-gnu1/drivers/char/vt_ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/char/vt_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/char/vt_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -400,6 +400,9 @@ int vt_ioctl(struct tty_struct *tty, str
 	case KIOCSOUND:
 		if (!perm)
 			goto eperm;
+		/* FIXME: This is an old broken API but we need to keep it
+		   supported and somehow separate the historic advertised
+		   tick rate from any real one */
 		if (arg)
 			arg = CLOCK_TICK_RATE / arg;
 		kd_mksound(arg, 0);
@@ -417,6 +420,9 @@ int vt_ioctl(struct tty_struct *tty, str
 		 */
 		ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
 		count = ticks ? (arg & 0xffff) : 0;
+		/* FIXME: This is an old broken API but we need to keep it
+		   supported and somehow separate the historic advertised
+		   tick rate from any real one */
 		if (count)
 			count = CLOCK_TICK_RATE / count;
 		kd_mksound(count, ticks);
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/acpi_pm.c linux-libre-2.6.30-gnu1/drivers/clocksource/acpi_pm.c
--- linux-libre-2.6.29-gnu1/drivers/clocksource/acpi_pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/acpi_pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@ u32 acpi_pm_read_verified(void)
 	return v2;
 }
 
-static cycle_t acpi_pm_read(void)
+static cycle_t acpi_pm_read(struct clocksource *cs)
 {
 	return (cycle_t)read_pmtmr();
 }
@@ -83,7 +83,7 @@ static int __init acpi_pm_good_setup(cha
 }
 __setup("acpi_pm_good", acpi_pm_good_setup);
 
-static cycle_t acpi_pm_read_slow(void)
+static cycle_t acpi_pm_read_slow(struct clocksource *cs)
 {
 	return (cycle_t)acpi_pm_read_verified();
 }
@@ -143,7 +143,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE
 #endif
 
 #ifndef CONFIG_X86_64
-#include "mach_timer.h"
+#include <asm/mach_timer.h>
 #define PMTMR_EXPECTED_RATE \
   ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
 /*
@@ -156,9 +156,9 @@ static int verify_pmtmr_rate(void)
 	unsigned long count, delta;
 
 	mach_prepare_counter();
-	value1 = clocksource_acpi_pm.read();
+	value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 	mach_countup(&count);
-	value2 = clocksource_acpi_pm.read();
+	value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 	delta = (value2 - value1) & ACPI_PM_MASK;
 
 	/* Check that the PMTMR delta is within 5% of what we expect */
@@ -195,9 +195,9 @@ static int __init init_acpi_pm_clocksour
 	/* "verify" this timing source: */
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 		udelay(100 * j);
-		value1 = clocksource_acpi_pm.read();
+		value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 		for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
-			value2 = clocksource_acpi_pm.read();
+			value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 			if (value2 == value1)
 				continue;
 			if (value2 > value1)
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/cyclone.c linux-libre-2.6.30-gnu1/drivers/clocksource/cyclone.c
--- linux-libre-2.6.29-gnu1/drivers/clocksource/cyclone.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/cyclone.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
-#include "mach_timer.h"
+#include <asm/mach_timer.h>
 
 #define CYCLONE_CBAR_ADDR	0xFEB00CD0	/* base address ptr */
 #define CYCLONE_PMCC_OFFSET	0x51A0		/* offset to control register */
@@ -19,7 +19,7 @@
 int use_cyclone = 0;
 static void __iomem *cyclone_ptr;
 
-static cycle_t read_cyclone(void)
+static cycle_t read_cyclone(struct clocksource *cs)
 {
 	return (cycle_t)readl(cyclone_ptr);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/Makefile linux-libre-2.6.30-gnu1/drivers/clocksource/Makefile
--- linux-libre-2.6.29-gnu1/drivers/clocksource/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,3 +2,4 @@ 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_SH_TIMER_CMT)	+= sh_cmt.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/scx200_hrt.c linux-libre-2.6.30-gnu1/drivers/clocksource/scx200_hrt.c
--- linux-libre-2.6.29-gnu1/drivers/clocksource/scx200_hrt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/scx200_hrt.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(ppm, "+-adjust to actua
 /* The base timer frequency, * 27 if selected */
 #define HRT_FREQ   1000000
 
-static cycle_t read_hrt(void)
+static cycle_t read_hrt(struct clocksource *cs)
 {
 	/* Read the timer value */
 	return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/sh_cmt.c linux-libre-2.6.30-gnu1/drivers/clocksource/sh_cmt.c
--- linux-libre-2.6.29-gnu1/drivers/clocksource/sh_cmt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/sh_cmt.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,614 @@
+/*
+ * SuperH Timer Support - CMT
+ *
+ *  Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/sh_cmt.h>
+
+struct sh_cmt_priv {
+	void __iomem *mapbase;
+	struct clk *clk;
+	unsigned long width; /* 16 or 32 bit version of hardware block */
+	unsigned long overflow_bit;
+	unsigned long clear_bits;
+	struct irqaction irqaction;
+	struct platform_device *pdev;
+
+	unsigned long flags;
+	unsigned long match_value;
+	unsigned long next_match_value;
+	unsigned long max_match_value;
+	unsigned long rate;
+	spinlock_t lock;
+	struct clock_event_device ced;
+	unsigned long total_cycles;
+};
+
+static DEFINE_SPINLOCK(sh_cmt_lock);
+
+#define CMSTR -1 /* shared register */
+#define CMCSR 0 /* channel register */
+#define CMCNT 1 /* channel register */
+#define CMCOR 2 /* channel register */
+
+static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
+{
+	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+	void __iomem *base = p->mapbase;
+	unsigned long offs;
+
+	if (reg_nr == CMSTR) {
+		offs = 0;
+		base -= cfg->channel_offset;
+	} else
+		offs = reg_nr;
+
+	if (p->width == 16)
+		offs <<= 1;
+	else {
+		offs <<= 2;
+		if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
+			return ioread32(base + offs);
+	}
+
+	return ioread16(base + offs);
+}
+
+static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
+				unsigned long value)
+{
+	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+	void __iomem *base = p->mapbase;
+	unsigned long offs;
+
+	if (reg_nr == CMSTR) {
+		offs = 0;
+		base -= cfg->channel_offset;
+	} else
+		offs = reg_nr;
+
+	if (p->width == 16)
+		offs <<= 1;
+	else {
+		offs <<= 2;
+		if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
+			iowrite32(value, base + offs);
+			return;
+		}
+	}
+
+	iowrite16(value, base + offs);
+}
+
+static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+					int *has_wrapped)
+{
+	unsigned long v1, v2, v3;
+
+	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
+	do {
+		v1 = sh_cmt_read(p, CMCNT);
+		v2 = sh_cmt_read(p, CMCNT);
+		v3 = sh_cmt_read(p, CMCNT);
+	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+			  || (v3 > v1 && v3 < v2)));
+
+	*has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+	return v2;
+}
+
+
+static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+{
+	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+	unsigned long flags, value;
+
+	/* start stop register shared by multiple timer channels */
+	spin_lock_irqsave(&sh_cmt_lock, flags);
+	value = sh_cmt_read(p, CMSTR);
+
+	if (start)
+		value |= 1 << cfg->timer_bit;
+	else
+		value &= ~(1 << cfg->timer_bit);
+
+	sh_cmt_write(p, CMSTR, value);
+	spin_unlock_irqrestore(&sh_cmt_lock, flags);
+}
+
+static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+{
+	struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+	int ret;
+
+	/* enable clock */
+	ret = clk_enable(p->clk);
+	if (ret) {
+		pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
+		return ret;
+	}
+	*rate = clk_get_rate(p->clk) / 8;
+
+	/* make sure channel is disabled */
+	sh_cmt_start_stop_ch(p, 0);
+
+	/* configure channel, periodic mode and maximum timeout */
+	if (p->width == 16)
+		sh_cmt_write(p, CMCSR, 0);
+	else
+		sh_cmt_write(p, CMCSR, 0x01a4);
+
+	sh_cmt_write(p, CMCOR, 0xffffffff);
+	sh_cmt_write(p, CMCNT, 0);
+
+	/* enable channel */
+	sh_cmt_start_stop_ch(p, 1);
+	return 0;
+}
+
+static void sh_cmt_disable(struct sh_cmt_priv *p)
+{
+	/* disable channel */
+	sh_cmt_start_stop_ch(p, 0);
+
+	/* stop clock */
+	clk_disable(p->clk);
+}
+
+/* private flags */
+#define FLAG_CLOCKEVENT (1 << 0)
+#define FLAG_CLOCKSOURCE (1 << 1)
+#define FLAG_REPROGRAM (1 << 2)
+#define FLAG_SKIPEVENT (1 << 3)
+#define FLAG_IRQCONTEXT (1 << 4)
+
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+					      int absolute)
+{
+	unsigned long new_match;
+	unsigned long value = p->next_match_value;
+	unsigned long delay = 0;
+	unsigned long now = 0;
+	int has_wrapped;
+
+	now = sh_cmt_get_counter(p, &has_wrapped);
+	p->flags |= FLAG_REPROGRAM; /* force reprogram */
+
+	if (has_wrapped) {
+		/* we're competing with the interrupt handler.
+		 *  -> let the interrupt handler reprogram the timer.
+		 *  -> interrupt number two handles the event.
+		 */
+		p->flags |= FLAG_SKIPEVENT;
+		return;
+	}
+
+	if (absolute)
+		now = 0;
+
+	do {
+		/* reprogram the timer hardware,
+		 * but don't save the new match value yet.
+		 */
+		new_match = now + value + delay;
+		if (new_match > p->max_match_value)
+			new_match = p->max_match_value;
+
+		sh_cmt_write(p, CMCOR, new_match);
+
+		now = sh_cmt_get_counter(p, &has_wrapped);
+		if (has_wrapped && (new_match > p->match_value)) {
+			/* we are changing to a greater match value,
+			 * so this wrap must be caused by the counter
+			 * matching the old value.
+			 * -> first interrupt reprograms the timer.
+			 * -> interrupt number two handles the event.
+			 */
+			p->flags |= FLAG_SKIPEVENT;
+			break;
+		}
+
+		if (has_wrapped) {
+			/* we are changing to a smaller match value,
+			 * so the wrap must be caused by the counter
+			 * matching the new value.
+			 * -> save programmed match value.
+			 * -> let isr handle the event.
+			 */
+			p->match_value = new_match;
+			break;
+		}
+
+		/* be safe: verify hardware settings */
+		if (now < new_match) {
+			/* timer value is below match value, all good.
+			 * this makes sure we won't miss any match events.
+			 * -> save programmed match value.
+			 * -> let isr handle the event.
+			 */
+			p->match_value = new_match;
+			break;
+		}
+
+		/* the counter has reached a value greater
+		 * than our new match value. and since the
+		 * has_wrapped flag isn't set we must have
+		 * programmed a too close event.
+		 * -> increase delay and retry.
+		 */
+		if (delay)
+			delay <<= 1;
+		else
+			delay = 1;
+
+		if (!delay)
+			pr_warning("sh_cmt: too long delay\n");
+
+	} while (delay);
+}
+
+static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+{
+	unsigned long flags;
+
+	if (delta > p->max_match_value)
+		pr_warning("sh_cmt: delta out of range\n");
+
+	spin_lock_irqsave(&p->lock, flags);
+	p->next_match_value = delta;
+	sh_cmt_clock_event_program_verify(p, 0);
+	spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
+{
+	struct sh_cmt_priv *p = dev_id;
+
+	/* clear flags */
+	sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+
+	/* update clock source counter to begin with if enabled
+	 * the wrap flag should be cleared by the timer specific
+	 * isr before we end up here.
+	 */
+	if (p->flags & FLAG_CLOCKSOURCE)
+		p->total_cycles += p->match_value;
+
+	if (!(p->flags & FLAG_REPROGRAM))
+		p->next_match_value = p->max_match_value;
+
+	p->flags |= FLAG_IRQCONTEXT;
+
+	if (p->flags & FLAG_CLOCKEVENT) {
+		if (!(p->flags & FLAG_SKIPEVENT)) {
+			if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+				p->next_match_value = p->max_match_value;
+				p->flags |= FLAG_REPROGRAM;
+			}
+
+			p->ced.event_handler(&p->ced);
+		}
+	}
+
+	p->flags &= ~FLAG_SKIPEVENT;
+
+	if (p->flags & FLAG_REPROGRAM) {
+		p->flags &= ~FLAG_REPROGRAM;
+		sh_cmt_clock_event_program_verify(p, 1);
+
+		if (p->flags & FLAG_CLOCKEVENT)
+			if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+			    || (p->match_value == p->next_match_value))
+				p->flags &= ~FLAG_REPROGRAM;
+	}
+
+	p->flags &= ~FLAG_IRQCONTEXT;
+
+	return IRQ_HANDLED;
+}
+
+static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&p->lock, flags);
+
+	if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		ret = sh_cmt_enable(p, &p->rate);
+
+	if (ret)
+		goto out;
+	p->flags |= flag;
+
+	/* setup timeout if no clockevent */
+	if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
+		sh_cmt_set_next(p, p->max_match_value);
+ out:
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	return ret;
+}
+
+static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+{
+	unsigned long flags;
+	unsigned long f;
+
+	spin_lock_irqsave(&p->lock, flags);
+
+	f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+	p->flags &= ~flag;
+
+	if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+		sh_cmt_disable(p);
+
+	/* adjust the timeout to maximum if only clocksource left */
+	if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
+		sh_cmt_set_next(p, p->max_match_value);
+
+	spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+{
+	return container_of(ced, struct sh_cmt_priv, ced);
+}
+
+static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+{
+	struct clock_event_device *ced = &p->ced;
+
+	sh_cmt_start(p, FLAG_CLOCKEVENT);
+
+	/* TODO: calculate good shift from rate and counter bit width */
+
+	ced->shift = 32;
+	ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+	ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+	ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
+
+	if (periodic)
+		sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+	else
+		sh_cmt_set_next(p, p->max_match_value);
+}
+
+static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
+				    struct clock_event_device *ced)
+{
+	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+	/* deal with old setting first */
+	switch (ced->mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+	case CLOCK_EVT_MODE_ONESHOT:
+		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		break;
+	default:
+		break;
+	}
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		pr_info("sh_cmt: %s used for periodic clock events\n",
+			ced->name);
+		sh_cmt_clock_event_start(p, 1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		pr_info("sh_cmt: %s used for oneshot clock events\n",
+			ced->name);
+		sh_cmt_clock_event_start(p, 0);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		sh_cmt_stop(p, FLAG_CLOCKEVENT);
+		break;
+	default:
+		break;
+	}
+}
+
+static int sh_cmt_clock_event_next(unsigned long delta,
+				   struct clock_event_device *ced)
+{
+	struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+	BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+	if (likely(p->flags & FLAG_IRQCONTEXT))
+		p->next_match_value = delta;
+	else
+		sh_cmt_set_next(p, delta);
+
+	return 0;
+}
+
+static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+				       char *name, unsigned long rating)
+{
+	struct clock_event_device *ced = &p->ced;
+
+	memset(ced, 0, sizeof(*ced));
+
+	ced->name = name;
+	ced->features = CLOCK_EVT_FEAT_PERIODIC;
+	ced->features |= CLOCK_EVT_FEAT_ONESHOT;
+	ced->rating = rating;
+	ced->cpumask = cpumask_of(0);
+	ced->set_next_event = sh_cmt_clock_event_next;
+	ced->set_mode = sh_cmt_clock_event_mode;
+
+	pr_info("sh_cmt: %s used for clock events\n", ced->name);
+	clockevents_register_device(ced);
+}
+
+int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+		    unsigned long clockevent_rating,
+		    unsigned long clocksource_rating)
+{
+	if (p->width == (sizeof(p->max_match_value) * 8))
+		p->max_match_value = ~0;
+	else
+		p->max_match_value = (1 << p->width) - 1;
+
+	p->match_value = p->max_match_value;
+	spin_lock_init(&p->lock);
+
+	if (clockevent_rating)
+		sh_cmt_register_clockevent(p, name, clockevent_rating);
+
+	return 0;
+}
+
+static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+{
+	struct sh_cmt_config *cfg = pdev->dev.platform_data;
+	struct resource *res;
+	int irq, ret;
+	ret = -ENXIO;
+
+	memset(p, 0, sizeof(*p));
+	p->pdev = pdev;
+
+	if (!cfg) {
+		dev_err(&p->pdev->dev, "missing platform data\n");
+		goto err0;
+	}
+
+	platform_set_drvdata(pdev, p);
+
+	res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+		goto err0;
+	}
+
+	irq = platform_get_irq(p->pdev, 0);
+	if (irq < 0) {
+		dev_err(&p->pdev->dev, "failed to get irq\n");
+		goto err0;
+	}
+
+	/* map memory, let mapbase point to our channel */
+	p->mapbase = ioremap_nocache(res->start, resource_size(res));
+	if (p->mapbase == NULL) {
+		pr_err("sh_cmt: failed to remap I/O memory\n");
+		goto err0;
+	}
+
+	/* request irq using setup_irq() (too early for request_irq()) */
+	p->irqaction.name = cfg->name;
+	p->irqaction.handler = sh_cmt_interrupt;
+	p->irqaction.dev_id = p;
+	p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+	p->irqaction.mask = CPU_MASK_NONE;
+	ret = setup_irq(irq, &p->irqaction);
+	if (ret) {
+		pr_err("sh_cmt: failed to request irq %d\n", irq);
+		goto err1;
+	}
+
+	/* get hold of clock */
+	p->clk = clk_get(&p->pdev->dev, cfg->clk);
+	if (IS_ERR(p->clk)) {
+		pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
+		ret = PTR_ERR(p->clk);
+		goto err2;
+	}
+
+	if (resource_size(res) == 6) {
+		p->width = 16;
+		p->overflow_bit = 0x80;
+		p->clear_bits = ~0xc0;
+	} else {
+		p->width = 32;
+		p->overflow_bit = 0x8000;
+		p->clear_bits = ~0xc000;
+	}
+
+	return sh_cmt_register(p, cfg->name,
+			       cfg->clockevent_rating,
+			       cfg->clocksource_rating);
+ err2:
+	remove_irq(irq, &p->irqaction);
+ err1:
+	iounmap(p->mapbase);
+ err0:
+	return ret;
+}
+
+static int __devinit sh_cmt_probe(struct platform_device *pdev)
+{
+	struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+	int ret;
+
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(&pdev->dev, "failed to allocate driver data\n");
+		return -ENOMEM;
+	}
+
+	ret = sh_cmt_setup(p, pdev);
+	if (ret) {
+		kfree(p);
+
+		platform_set_drvdata(pdev, NULL);
+	}
+	return ret;
+}
+
+static int __devexit sh_cmt_remove(struct platform_device *pdev)
+{
+	return -EBUSY; /* cannot unregister clockevent and clocksource */
+}
+
+static struct platform_driver sh_cmt_device_driver = {
+	.probe		= sh_cmt_probe,
+	.remove		= __devexit_p(sh_cmt_remove),
+	.driver		= {
+		.name	= "sh_cmt",
+	}
+};
+
+static int __init sh_cmt_init(void)
+{
+	return platform_driver_register(&sh_cmt_device_driver);
+}
+
+static void __exit sh_cmt_exit(void)
+{
+	platform_driver_unregister(&sh_cmt_device_driver);
+}
+
+module_init(sh_cmt_init);
+module_exit(sh_cmt_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH CMT Timer Driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.29-gnu1/drivers/clocksource/tcb_clksrc.c linux-libre-2.6.30-gnu1/drivers/clocksource/tcb_clksrc.c
--- linux-libre-2.6.29-gnu1/drivers/clocksource/tcb_clksrc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/clocksource/tcb_clksrc.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@
 
 static void __iomem *tcaddr;
 
-static cycle_t tc_get_cycles(void)
+static cycle_t tc_get_cycles(struct clocksource *cs)
 {
 	unsigned long	flags;
 	u32		lower, upper;
diff -druNp linux-libre-2.6.29-gnu1/drivers/connector/cn_queue.c linux-libre-2.6.30-gnu1/drivers/connector/cn_queue.c
--- linux-libre-2.6.29-gnu1/drivers/connector/cn_queue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/connector/cn_queue.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 /*
  * 	cn_queue.c
- * 
+ *
  * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
  * 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
@@ -31,6 +31,48 @@
 #include <linux/connector.h>
 #include <linux/delay.h>
 
+
+/*
+ * This job is sent to the kevent workqueue.
+ * While no event is once sent to any callback, the connector workqueue
+ * is not created to avoid a useless waiting kernel task.
+ * Once the first event is received, we create this dedicated workqueue which
+ * is necessary because the flow of data can be high and we don't want
+ * to encumber keventd with that.
+ */
+static void cn_queue_create(struct work_struct *work)
+{
+	struct cn_queue_dev *dev;
+
+	dev = container_of(work, struct cn_queue_dev, wq_creation);
+
+	dev->cn_queue = create_singlethread_workqueue(dev->name);
+	/* If we fail, we will use keventd for all following connector jobs */
+	WARN_ON(!dev->cn_queue);
+}
+
+/*
+ * Queue a data sent to a callback.
+ * If the connector workqueue is already created, we queue the job on it.
+ * Otherwise, we queue the job to kevent and queue the connector workqueue
+ * creation too.
+ */
+int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work)
+{
+	struct cn_queue_dev *pdev = cbq->pdev;
+
+	if (likely(pdev->cn_queue))
+		return queue_work(pdev->cn_queue, work);
+
+	/* Don't create the connector workqueue twice */
+	if (atomic_inc_return(&pdev->wq_requested) == 1)
+		schedule_work(&pdev->wq_creation);
+	else
+		atomic_dec(&pdev->wq_requested);
+
+	return schedule_work(work);
+}
+
 void cn_queue_wrapper(struct work_struct *work)
 {
 	struct cn_callback_entry *cbq =
@@ -58,14 +100,17 @@ static struct cn_callback_entry *cn_queu
 	snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
 	memcpy(&cbq->id.id, id, sizeof(struct cb_id));
 	cbq->data.callback = callback;
-	
+
 	INIT_WORK(&cbq->work, &cn_queue_wrapper);
 	return cbq;
 }
 
 static void cn_queue_free_callback(struct cn_callback_entry *cbq)
 {
-	flush_workqueue(cbq->pdev->cn_queue);
+	/* The first jobs have been sent to kevent, flush them too */
+	flush_scheduled_work();
+	if (cbq->pdev->cn_queue)
+		flush_workqueue(cbq->pdev->cn_queue);
 
 	kfree(cbq);
 }
@@ -143,14 +188,11 @@ struct cn_queue_dev *cn_queue_alloc_dev(
 	atomic_set(&dev->refcnt, 0);
 	INIT_LIST_HEAD(&dev->queue_list);
 	spin_lock_init(&dev->queue_lock);
+	init_waitqueue_head(&dev->wq_created);
 
 	dev->nls = nls;
 
-	dev->cn_queue = create_singlethread_workqueue(dev->name);
-	if (!dev->cn_queue) {
-		kfree(dev);
-		return NULL;
-	}
+	INIT_WORK(&dev->wq_creation, cn_queue_create);
 
 	return dev;
 }
@@ -158,9 +200,25 @@ struct cn_queue_dev *cn_queue_alloc_dev(
 void cn_queue_free_dev(struct cn_queue_dev *dev)
 {
 	struct cn_callback_entry *cbq, *n;
+	long timeout;
+	DEFINE_WAIT(wait);
 
-	flush_workqueue(dev->cn_queue);
-	destroy_workqueue(dev->cn_queue);
+	/* Flush the first pending jobs queued on kevent */
+	flush_scheduled_work();
+
+	/* If the connector workqueue creation is still pending, wait for it */
+	prepare_to_wait(&dev->wq_created, &wait, TASK_UNINTERRUPTIBLE);
+	if (atomic_read(&dev->wq_requested) && !dev->cn_queue) {
+		timeout = schedule_timeout(HZ * 2);
+		if (!timeout && !dev->cn_queue)
+			WARN_ON(1);
+	}
+	finish_wait(&dev->wq_created, &wait);
+
+	if (dev->cn_queue) {
+		flush_workqueue(dev->cn_queue);
+		destroy_workqueue(dev->cn_queue);
+	}
 
 	spin_lock_bh(&dev->queue_lock);
 	list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
diff -druNp linux-libre-2.6.29-gnu1/drivers/connector/connector.c linux-libre-2.6.30-gnu1/drivers/connector/connector.c
--- linux-libre-2.6.29-gnu1/drivers/connector/connector.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/connector/connector.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,9 @@
 /*
  * 	connector.c
- * 
+ *
  * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
  * 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
@@ -145,14 +145,13 @@ static int cn_call_callback(struct cn_ms
 				__cbq->data.ddata = data;
 				__cbq->data.destruct_data = destruct_data;
 
-				if (queue_work(dev->cbdev->cn_queue,
-							&__cbq->work))
+				if (queue_cn_work(__cbq, &__cbq->work))
 					err = 0;
 				else
 					err = -EINVAL;
 			} else {
 				struct cn_callback_data *d;
-				
+
 				err = -ENOMEM;
 				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
 				if (__new_cbq) {
@@ -163,10 +162,12 @@ static int cn_call_callback(struct cn_ms
 					d->destruct_data = destruct_data;
 					d->free = __new_cbq;
 
+					__new_cbq->pdev = __cbq->pdev;
+
 					INIT_WORK(&__new_cbq->work,
 							&cn_queue_wrapper);
 
-					if (queue_work(dev->cbdev->cn_queue,
+					if (queue_cn_work(__new_cbq,
 						    &__new_cbq->work))
 						err = 0;
 					else {
@@ -237,7 +238,7 @@ static void cn_notify(struct cb_id *id,
 
 		req = (struct cn_notify_req *)ctl->data;
 		for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
-			if (id->idx >= req->first && 
+			if (id->idx >= req->first &&
 					id->idx < req->first + req->range) {
 				idx_found = 1;
 				break;
@@ -245,7 +246,7 @@ static void cn_notify(struct cb_id *id,
 		}
 
 		for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
-			if (id->val >= req->first && 
+			if (id->val >= req->first &&
 					id->val < req->first + req->range) {
 				val_found = 1;
 				break;
@@ -459,7 +460,7 @@ static int __devinit cn_init(void)
 		netlink_kernel_release(dev->nls);
 		return -EINVAL;
 	}
-	
+
 	cn_already_initialized = 1;
 
 	err = cn_add_callback(&dev->id, "connector", &cn_callback);
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq.c linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,8 @@ EXPORT_SYMBOL_GPL(unlock_policy_rwsem_wr
 
 
 /* internal prototypes */
-static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
+static int __cpufreq_governor(struct cpufreq_policy *policy,
+		unsigned int event);
 static unsigned int __cpufreq_get(unsigned int cpu);
 static void handle_update(struct work_struct *work);
 
@@ -128,7 +129,7 @@ static int __init init_cpufreq_transitio
 pure_initcall(init_cpufreq_transition_notifier_list);
 
 static LIST_HEAD(cpufreq_governor_list);
-static DEFINE_MUTEX (cpufreq_governor_mutex);
+static DEFINE_MUTEX(cpufreq_governor_mutex);
 
 struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
 {
@@ -371,7 +372,7 @@ static struct cpufreq_governor *__find_g
 	struct cpufreq_governor *t;
 
 	list_for_each_entry(t, &cpufreq_governor_list, governor_list)
-		if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
+		if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
 			return t;
 
 	return NULL;
@@ -429,15 +430,11 @@ static int cpufreq_parse_governor(char *
 
 		mutex_unlock(&cpufreq_governor_mutex);
 	}
-  out:
+out:
 	return err;
 }
 
 
-/* drivers/base/cpu.c */
-extern struct sysdev_class cpu_sysdev_class;
-
-
 /**
  * cpufreq_per_cpu_attr_read() / show_##file_name() -
  * print out cpufreq information
@@ -450,11 +447,12 @@ extern struct sysdev_class cpu_sysdev_cl
 static ssize_t show_##file_name				\
 (struct cpufreq_policy *policy, char *buf)		\
 {							\
-	return sprintf (buf, "%u\n", policy->object);	\
+	return sprintf(buf, "%u\n", policy->object);	\
 }
 
 show_one(cpuinfo_min_freq, cpuinfo.min_freq);
 show_one(cpuinfo_max_freq, cpuinfo.max_freq);
+show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
 show_one(scaling_min_freq, min);
 show_one(scaling_max_freq, max);
 show_one(scaling_cur_freq, cur);
@@ -476,7 +474,7 @@ static ssize_t store_##file_name					\
 	if (ret)							\
 		return -EINVAL;						\
 									\
-	ret = sscanf (buf, "%u", &new_policy.object);			\
+	ret = sscanf(buf, "%u", &new_policy.object);			\
 	if (ret != 1)							\
 		return -EINVAL;						\
 									\
@@ -486,8 +484,8 @@ static ssize_t store_##file_name					\
 	return ret ? ret : count;					\
 }
 
-store_one(scaling_min_freq,min);
-store_one(scaling_max_freq,max);
+store_one(scaling_min_freq, min);
+store_one(scaling_max_freq, max);
 
 /**
  * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
@@ -507,12 +505,13 @@ static ssize_t show_cpuinfo_cur_freq(str
  */
 static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
 {
-	if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
+	if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
 		return sprintf(buf, "powersave\n");
 	else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
 		return sprintf(buf, "performance\n");
 	else if (policy->governor)
-		return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
+		return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
+				policy->governor->name);
 	return -EINVAL;
 }
 
@@ -531,7 +530,7 @@ static ssize_t store_scaling_governor(st
 	if (ret)
 		return ret;
 
-	ret = sscanf (buf, "%15s", str_governor);
+	ret = sscanf(buf, "%15s", str_governor);
 	if (ret != 1)
 		return -EINVAL;
 
@@ -575,7 +574,8 @@ static ssize_t show_scaling_available_go
 	}
 
 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
-		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
+		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
+		    - (CPUFREQ_NAME_LEN + 2)))
 			goto out;
 		i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
 	}
@@ -594,7 +594,7 @@ static ssize_t show_cpus(const struct cp
 			i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
 		i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
 		if (i >= (PAGE_SIZE - 5))
-		    break;
+			break;
 	}
 	i += sprintf(&buf[i], "\n");
 	return i;
@@ -660,6 +660,7 @@ __ATTR(_name, 0644, show_##_name, store_
 define_one_ro0400(cpuinfo_cur_freq);
 define_one_ro(cpuinfo_min_freq);
 define_one_ro(cpuinfo_max_freq);
+define_one_ro(cpuinfo_transition_latency);
 define_one_ro(scaling_available_governors);
 define_one_ro(scaling_driver);
 define_one_ro(scaling_cur_freq);
@@ -673,6 +674,7 @@ define_one_rw(scaling_setspeed);
 static struct attribute *default_attrs[] = {
 	&cpuinfo_min_freq.attr,
 	&cpuinfo_max_freq.attr,
+	&cpuinfo_transition_latency.attr,
 	&scaling_min_freq.attr,
 	&scaling_max_freq.attr,
 	&affected_cpus.attr,
@@ -684,10 +686,10 @@ static struct attribute *default_attrs[]
 	NULL
 };
 
-#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
-#define to_attr(a) container_of(a,struct freq_attr,attr)
+#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
+#define to_attr(a) container_of(a, struct freq_attr, attr)
 
-static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf)
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
 {
 	struct cpufreq_policy *policy = to_policy(kobj);
 	struct freq_attr *fattr = to_attr(attr);
@@ -806,7 +808,7 @@ static int cpufreq_add_dev(struct sys_de
 		ret = -ENOMEM;
 		goto nomem_out;
 	}
-	if (!alloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
+	if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
 		free_cpumask_var(policy->cpus);
 		kfree(policy);
 		ret = -ENOMEM;
@@ -853,10 +855,10 @@ static int cpufreq_add_dev(struct sys_de
 		if (cpu == j)
 			continue;
 
-		/* check for existing affected CPUs.  They may not be aware
-		 * of it due to CPU Hotplug.
+		/* Check for existing affected CPUs.
+		 * They may not be aware of it due to CPU Hotplug.
 		 */
-		managed_policy = cpufreq_cpu_get(j);		// FIXME: Where is this released?  What about error paths?
+		managed_policy = cpufreq_cpu_get(j);		/* FIXME: Where is this released?  What about error paths? */
 		if (unlikely(managed_policy)) {
 
 			/* Set proper policy_cpu */
@@ -1068,11 +1070,11 @@ static int __cpufreq_remove_dev(struct s
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
+	unlock_policy_rwsem_write(cpu);
+
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-	unlock_policy_rwsem_write(cpu);
-
 	kobject_put(&data->kobj);
 
 	/* we need to make sure that the underlying kobj is actually
@@ -1127,8 +1129,8 @@ static void handle_update(struct work_st
  *	@old_freq: CPU frequency the kernel thinks the CPU runs at
  *	@new_freq: CPU frequency the CPU actually runs at
  *
- *	We adjust to current frequency first, and need to clean up later. So either call
- *	to cpufreq_update_policy() or schedule handle_update()).
+ *	We adjust to current frequency first, and need to clean up later.
+ *	So either call to cpufreq_update_policy() or schedule handle_update()).
  */
 static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
 				unsigned int new_freq)
@@ -1610,7 +1612,8 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_gov
 
 /**
  * cpufreq_get_policy - get the current cpufreq_policy
- * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
+ * @policy: struct cpufreq_policy into which the current cpufreq_policy
+ *	is written
  *
  * Reads the current cpufreq policy.
  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_conservative.c linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_conservative.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_conservative.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_conservative.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  *  Copyright (C)  2001 Russell King
  *            (C)  2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
  *                      Jun Nakajima <jun.nakajima@intel.com>
- *            (C)  2004 Alexander Clouter <alex-kernel@digriz.org.uk>
+ *            (C)  2009 Alexander Clouter <alex@digriz.org.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
@@ -13,22 +13,17 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/smp.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ctype.h>
 #include <linux/cpufreq.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
 #include <linux/cpu.h>
-#include <linux/kmod.h>
-#include <linux/workqueue.h>
 #include <linux/jiffies.h>
 #include <linux/kernel_stat.h>
-#include <linux/percpu.h>
 #include <linux/mutex.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/ktime.h>
+#include <linux/sched.h>
+
 /*
  * dbs is used in this file as a shortform for demandbased switching
  * It helps to keep variable names smaller, simpler
@@ -43,19 +38,31 @@
  * latency of the processor. The governor will work on any processor with
  * transition latency <= 10mS, using appropriate sampling
  * rate.
- * For CPUs with transition latency > 10mS (mostly drivers
- * with CPUFREQ_ETERNAL), this governor will not work.
+ * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
+ * this governor will not work.
  * All times here are in uS.
  */
 static unsigned int def_sampling_rate;
 #define MIN_SAMPLING_RATE_RATIO			(2)
 /* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE			\
+#define MIN_STAT_SAMPLING_RATE 			\
 			(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
 #define MIN_SAMPLING_RATE			\
 			(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ *   - "HW transition latency" * 100 (same as default sampling / 10)
+ *   - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+	return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
 #define MAX_SAMPLING_RATE			(500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER	(1000)
+#define LATENCY_MULTIPLIER			(1000)
 #define DEF_SAMPLING_DOWN_FACTOR		(1)
 #define MAX_SAMPLING_DOWN_FACTOR		(10)
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000 * 1000)
@@ -63,12 +70,15 @@ static unsigned int def_sampling_rate;
 static void do_dbs_timer(struct work_struct *work);
 
 struct cpu_dbs_info_s {
+	cputime64_t prev_cpu_idle;
+	cputime64_t prev_cpu_wall;
+	cputime64_t prev_cpu_nice;
 	struct cpufreq_policy *cur_policy;
-	unsigned int prev_cpu_idle_up;
-	unsigned int prev_cpu_idle_down;
-	unsigned int enable;
+	struct delayed_work work;
 	unsigned int down_skip;
 	unsigned int requested_freq;
+	int cpu;
+	unsigned int enable:1;
 };
 static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
 
@@ -81,20 +91,22 @@ static unsigned int dbs_enable;	/* numbe
  * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
  * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
  * is recursive for the same process. -Venki
+ * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
+ * would deadlock with cancel_delayed_work_sync(), which is needed for proper
+ * raceless workqueue teardown.
  */
-static DEFINE_MUTEX (dbs_mutex);
-static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer);
+static DEFINE_MUTEX(dbs_mutex);
 
-struct dbs_tuners {
+static struct workqueue_struct	*kconservative_wq;
+
+static struct dbs_tuners {
 	unsigned int sampling_rate;
 	unsigned int sampling_down_factor;
 	unsigned int up_threshold;
 	unsigned int down_threshold;
 	unsigned int ignore_nice;
 	unsigned int freq_step;
-};
-
-static struct dbs_tuners dbs_tuners_ins = {
+} dbs_tuners_ins = {
 	.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
 	.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
 	.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
@@ -102,18 +114,37 @@ static struct dbs_tuners dbs_tuners_ins
 	.freq_step = 5,
 };
 
-static inline unsigned int get_cpu_idle_time(unsigned int cpu)
+static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
+							cputime64_t *wall)
 {
-	unsigned int add_nice = 0, ret;
+	cputime64_t idle_time;
+	cputime64_t cur_wall_time;
+	cputime64_t busy_time;
 
-	if (dbs_tuners_ins.ignore_nice)
-		add_nice = kstat_cpu(cpu).cpustat.nice;
+	cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+	busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+			kstat_cpu(cpu).cpustat.system);
 
-	ret = kstat_cpu(cpu).cpustat.idle +
-		kstat_cpu(cpu).cpustat.iowait +
-		add_nice;
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice);
 
-	return ret;
+	idle_time = cputime64_sub(cur_wall_time, busy_time);
+	if (wall)
+		*wall = cur_wall_time;
+
+	return idle_time;
+}
+
+static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
+{
+	u64 idle_time = get_cpu_idle_time_us(cpu, wall);
+
+	if (idle_time == -1ULL)
+		return get_cpu_idle_time_jiffy(cpu, wall);
+
+	return idle_time;
 }
 
 /* keep track of frequency transitions */
@@ -125,10 +156,21 @@ dbs_cpufreq_notifier(struct notifier_blo
 	struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info,
 							freq->cpu);
 
+	struct cpufreq_policy *policy;
+
 	if (!this_dbs_info->enable)
 		return 0;
 
-	this_dbs_info->requested_freq = freq->new;
+	policy = this_dbs_info->cur_policy;
+
+	/*
+	 * we only care if our internally tracked freq moves outside
+	 * the 'valid' ranges of freqency available to us otherwise
+	 * we do not change it
+	*/
+	if (this_dbs_info->requested_freq > policy->max
+			|| this_dbs_info->requested_freq < policy->min)
+		this_dbs_info->requested_freq = freq->new;
 
 	return 0;
 }
@@ -140,16 +182,31 @@ static struct notifier_block dbs_cpufreq
 /************************** sysfs interface ************************/
 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
 {
-	return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+	static int print_once;
+
+	if (!print_once) {
+		printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+		       "sysfs file is deprecated - used by: %s\n",
+		       current->comm);
+		print_once = 1;
+	}
+	return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
 }
 
 static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
 {
-	return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+	static int print_once;
+
+	if (!print_once) {
+		printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+		       "sysfs file is deprecated - used by: %s\n", current->comm);
+		print_once = 1;
+	}
+	return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
 }
 
-#define define_one_ro(_name)				\
-static struct freq_attr _name =				\
+#define define_one_ro(_name)		\
+static struct freq_attr _name =		\
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -174,7 +231,8 @@ static ssize_t store_sampling_down_facto
 {
 	unsigned int input;
 	int ret;
-	ret = sscanf (buf, "%u", &input);
+	ret = sscanf(buf, "%u", &input);
+
 	if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
 		return -EINVAL;
 
@@ -190,15 +248,13 @@ static ssize_t store_sampling_rate(struc
 {
 	unsigned int input;
 	int ret;
-	ret = sscanf (buf, "%u", &input);
+	ret = sscanf(buf, "%u", &input);
 
-	mutex_lock(&dbs_mutex);
-	if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
-		mutex_unlock(&dbs_mutex);
+	if (ret != 1)
 		return -EINVAL;
-	}
 
-	dbs_tuners_ins.sampling_rate = input;
+	mutex_lock(&dbs_mutex);
+	dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
 	mutex_unlock(&dbs_mutex);
 
 	return count;
@@ -209,10 +265,11 @@ static ssize_t store_up_threshold(struct
 {
 	unsigned int input;
 	int ret;
-	ret = sscanf (buf, "%u", &input);
+	ret = sscanf(buf, "%u", &input);
 
 	mutex_lock(&dbs_mutex);
-	if (ret != 1 || input > 100 || input <= dbs_tuners_ins.down_threshold) {
+	if (ret != 1 || input > 100 ||
+			input <= dbs_tuners_ins.down_threshold) {
 		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
@@ -228,10 +285,12 @@ static ssize_t store_down_threshold(stru
 {
 	unsigned int input;
 	int ret;
-	ret = sscanf (buf, "%u", &input);
+	ret = sscanf(buf, "%u", &input);
 
 	mutex_lock(&dbs_mutex);
-	if (ret != 1 || input > 100 || input >= dbs_tuners_ins.up_threshold) {
+	/* cannot be lower than 11 otherwise freq will not fall */
+	if (ret != 1 || input < 11 || input > 100 ||
+			input >= dbs_tuners_ins.up_threshold) {
 		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
@@ -264,12 +323,14 @@ static ssize_t store_ignore_nice_load(st
 	}
 	dbs_tuners_ins.ignore_nice = input;
 
-	/* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */
+	/* we need to re-evaluate prev_cpu_idle */
 	for_each_online_cpu(j) {
-		struct cpu_dbs_info_s *j_dbs_info;
-		j_dbs_info = &per_cpu(cpu_dbs_info, j);
-		j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
-		j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
+		struct cpu_dbs_info_s *dbs_info;
+		dbs_info = &per_cpu(cpu_dbs_info, j);
+		dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+						&dbs_info->prev_cpu_wall);
+		if (dbs_tuners_ins.ignore_nice)
+			dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
 	}
 	mutex_unlock(&dbs_mutex);
 
@@ -281,7 +342,6 @@ static ssize_t store_freq_step(struct cp
 {
 	unsigned int input;
 	int ret;
-
 	ret = sscanf(buf, "%u", &input);
 
 	if (ret != 1)
@@ -310,7 +370,7 @@ define_one_rw(down_threshold);
 define_one_rw(ignore_nice_load);
 define_one_rw(freq_step);
 
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
 	&sampling_rate_max.attr,
 	&sampling_rate_min.attr,
 	&sampling_rate.attr,
@@ -329,55 +389,78 @@ static struct attribute_group dbs_attr_g
 
 /************************** sysfs end ************************/
 
-static void dbs_check_cpu(int cpu)
+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
-	unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
-	unsigned int tmp_idle_ticks, total_idle_ticks;
+	unsigned int load = 0;
 	unsigned int freq_target;
-	unsigned int freq_down_sampling_rate;
-	struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
-	struct cpufreq_policy *policy;
 
-	if (!this_dbs_info->enable)
-		return;
+	struct cpufreq_policy *policy;
+	unsigned int j;
 
 	policy = this_dbs_info->cur_policy;
 
 	/*
-	 * The default safe range is 20% to 80%
-	 * Every sampling_rate, we check
-	 *	- If current idle time is less than 20%, then we try to
-	 *	  increase frequency
-	 * Every sampling_rate*sampling_down_factor, we check
-	 *	- If current idle time is more than 80%, then we try to
-	 *	  decrease frequency
+	 * Every sampling_rate, we check, if current idle time is less
+	 * than 20% (default), then we try to increase frequency
+	 * Every sampling_rate*sampling_down_factor, we check, if current
+	 * idle time is more than 80%, then we try to decrease frequency
 	 *
 	 * Any frequency increase takes it to the maximum frequency.
 	 * Frequency reduction happens at minimum steps of
-	 * 5% (default) of max_frequency
+	 * 5% (default) of maximum frequency
 	 */
 
-	/* Check for frequency increase */
-	idle_ticks = UINT_MAX;
+	/* Get Absolute Load */
+	for_each_cpu(j, policy->cpus) {
+		struct cpu_dbs_info_s *j_dbs_info;
+		cputime64_t cur_wall_time, cur_idle_time;
+		unsigned int idle_time, wall_time;
 
-	/* Check for frequency increase */
-	total_idle_ticks = get_cpu_idle_time(cpu);
-	tmp_idle_ticks = total_idle_ticks -
-		this_dbs_info->prev_cpu_idle_up;
-	this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
 
-	if (tmp_idle_ticks < idle_ticks)
-		idle_ticks = tmp_idle_ticks;
+		cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
 
-	/* Scale idle ticks by 100 and compare with up and down ticks */
-	idle_ticks *= 100;
-	up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
-			usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+		wall_time = (unsigned int) cputime64_sub(cur_wall_time,
+				j_dbs_info->prev_cpu_wall);
+		j_dbs_info->prev_cpu_wall = cur_wall_time;
 
-	if (idle_ticks < up_idle_ticks) {
+		idle_time = (unsigned int) cputime64_sub(cur_idle_time,
+				j_dbs_info->prev_cpu_idle);
+		j_dbs_info->prev_cpu_idle = cur_idle_time;
+
+		if (dbs_tuners_ins.ignore_nice) {
+			cputime64_t cur_nice;
+			unsigned long cur_nice_jiffies;
+
+			cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice,
+					 j_dbs_info->prev_cpu_nice);
+			/*
+			 * Assumption: nice time between sampling periods will
+			 * be less than 2^32 jiffies for 32 bit sys
+			 */
+			cur_nice_jiffies = (unsigned long)
+					cputime64_to_jiffies64(cur_nice);
+
+			j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+			idle_time += jiffies_to_usecs(cur_nice_jiffies);
+		}
+
+		if (unlikely(!wall_time || wall_time < idle_time))
+			continue;
+
+		load = 100 * (wall_time - idle_time) / wall_time;
+	}
+
+	/*
+	 * break out if we 'cannot' reduce the speed as the user might
+	 * want freq_step to be zero
+	 */
+	if (dbs_tuners_ins.freq_step == 0)
+		return;
+
+	/* Check for frequency increase */
+	if (load > dbs_tuners_ins.up_threshold) {
 		this_dbs_info->down_skip = 0;
-		this_dbs_info->prev_cpu_idle_down =
-			this_dbs_info->prev_cpu_idle_up;
 
 		/* if we are already at full speed then break out early */
 		if (this_dbs_info->requested_freq == policy->max)
@@ -398,49 +481,24 @@ static void dbs_check_cpu(int cpu)
 		return;
 	}
 
-	/* Check for frequency decrease */
-	this_dbs_info->down_skip++;
-	if (this_dbs_info->down_skip < dbs_tuners_ins.sampling_down_factor)
-		return;
-
-	/* Check for frequency decrease */
-	total_idle_ticks = this_dbs_info->prev_cpu_idle_up;
-	tmp_idle_ticks = total_idle_ticks -
-		this_dbs_info->prev_cpu_idle_down;
-	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
-
-	if (tmp_idle_ticks < idle_ticks)
-		idle_ticks = tmp_idle_ticks;
-
-	/* Scale idle ticks by 100 and compare with up and down ticks */
-	idle_ticks *= 100;
-	this_dbs_info->down_skip = 0;
-
-	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
-		dbs_tuners_ins.sampling_down_factor;
-	down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
-		usecs_to_jiffies(freq_down_sampling_rate);
-
-	if (idle_ticks > down_idle_ticks) {
-		/*
-		 * if we are already at the lowest speed then break out early
-		 * or if we 'cannot' reduce the speed as the user might want
-		 * freq_target to be zero
-		 */
-		if (this_dbs_info->requested_freq == policy->min
-				|| dbs_tuners_ins.freq_step == 0)
-			return;
-
+	/*
+	 * The optimal frequency is the frequency that is the lowest that
+	 * can support the current CPU usage without triggering the up
+	 * policy. To be safe, we focus 10 points under the threshold.
+	 */
+	if (load < (dbs_tuners_ins.down_threshold - 10)) {
 		freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
 
-		/* max freq cannot be less than 100. But who knows.... */
-		if (unlikely(freq_target == 0))
-			freq_target = 5;
-
 		this_dbs_info->requested_freq -= freq_target;
 		if (this_dbs_info->requested_freq < policy->min)
 			this_dbs_info->requested_freq = policy->min;
 
+		/*
+		 * if we cannot reduce the frequency anymore, break out early
+		 */
+		if (policy->cur == policy->min)
+			return;
+
 		__cpufreq_driver_target(policy, this_dbs_info->requested_freq,
 				CPUFREQ_RELATION_H);
 		return;
@@ -449,27 +507,45 @@ static void dbs_check_cpu(int cpu)
 
 static void do_dbs_timer(struct work_struct *work)
 {
-	int i;
-	mutex_lock(&dbs_mutex);
-	for_each_online_cpu(i)
-		dbs_check_cpu(i);
-	schedule_delayed_work(&dbs_work,
-			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
-	mutex_unlock(&dbs_mutex);
+	struct cpu_dbs_info_s *dbs_info =
+		container_of(work, struct cpu_dbs_info_s, work.work);
+	unsigned int cpu = dbs_info->cpu;
+
+	/* We want all CPUs to do sampling nearly on same jiffy */
+	int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+	delay -= jiffies % delay;
+
+	if (lock_policy_rwsem_write(cpu) < 0)
+		return;
+
+	if (!dbs_info->enable) {
+		unlock_policy_rwsem_write(cpu);
+		return;
+	}
+
+	dbs_check_cpu(dbs_info);
+
+	queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay);
+	unlock_policy_rwsem_write(cpu);
 }
 
-static inline void dbs_timer_init(void)
+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
 {
-	init_timer_deferrable(&dbs_work.timer);
-	schedule_delayed_work(&dbs_work,
-			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
-	return;
+	/* We want all CPUs to do sampling nearly on same jiffy */
+	int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+	delay -= jiffies % delay;
+
+	dbs_info->enable = 1;
+	INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
+	queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work,
+				delay);
 }
 
-static inline void dbs_timer_exit(void)
+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
 {
-	cancel_delayed_work(&dbs_work);
-	return;
+	dbs_info->enable = 0;
+	cancel_delayed_work_sync(&dbs_info->work);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -503,11 +579,13 @@ static int cpufreq_governor_dbs(struct c
 			j_dbs_info = &per_cpu(cpu_dbs_info, j);
 			j_dbs_info->cur_policy = policy;
 
-			j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu);
-			j_dbs_info->prev_cpu_idle_down
-				= j_dbs_info->prev_cpu_idle_up;
+			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+						&j_dbs_info->prev_cpu_wall);
+			if (dbs_tuners_ins.ignore_nice) {
+				j_dbs_info->prev_cpu_nice =
+						kstat_cpu(j).cpustat.nice;
+			}
 		}
-		this_dbs_info->enable = 1;
 		this_dbs_info->down_skip = 0;
 		this_dbs_info->requested_freq = policy->cur;
 
@@ -523,38 +601,36 @@ static int cpufreq_governor_dbs(struct c
 			if (latency == 0)
 				latency = 1;
 
-			def_sampling_rate = 10 * latency *
-					DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
-			if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
-				def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+			def_sampling_rate =
+				max(latency * LATENCY_MULTIPLIER,
+				    MIN_STAT_SAMPLING_RATE);
 
 			dbs_tuners_ins.sampling_rate = def_sampling_rate;
 
-			dbs_timer_init();
 			cpufreq_register_notifier(
 					&dbs_cpufreq_notifier_block,
 					CPUFREQ_TRANSITION_NOTIFIER);
 		}
+		dbs_timer_init(this_dbs_info);
 
 		mutex_unlock(&dbs_mutex);
+
 		break;
 
 	case CPUFREQ_GOV_STOP:
 		mutex_lock(&dbs_mutex);
-		this_dbs_info->enable = 0;
+		dbs_timer_exit(this_dbs_info);
 		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable--;
+
 		/*
 		 * Stop the timerschedule work, when this governor
 		 * is used for first time
 		 */
-		if (dbs_enable == 0) {
-			dbs_timer_exit();
+		if (dbs_enable == 0)
 			cpufreq_unregister_notifier(
 					&dbs_cpufreq_notifier_block,
 					CPUFREQ_TRANSITION_NOTIFIER);
-		}
 
 		mutex_unlock(&dbs_mutex);
 
@@ -571,6 +647,7 @@ static int cpufreq_governor_dbs(struct c
 					this_dbs_info->cur_policy,
 					policy->min, CPUFREQ_RELATION_L);
 		mutex_unlock(&dbs_mutex);
+
 		break;
 	}
 	return 0;
@@ -588,23 +665,33 @@ struct cpufreq_governor cpufreq_gov_cons
 
 static int __init cpufreq_gov_dbs_init(void)
 {
-	return cpufreq_register_governor(&cpufreq_gov_conservative);
+	int err;
+
+	kconservative_wq = create_workqueue("kconservative");
+	if (!kconservative_wq) {
+		printk(KERN_ERR "Creation of kconservative failed\n");
+		return -EFAULT;
+	}
+
+	err = cpufreq_register_governor(&cpufreq_gov_conservative);
+	if (err)
+		destroy_workqueue(kconservative_wq);
+
+	return err;
 }
 
 static void __exit cpufreq_gov_dbs_exit(void)
 {
-	/* Make sure that the scheduled work is indeed not running */
-	flush_scheduled_work();
-
 	cpufreq_unregister_governor(&cpufreq_gov_conservative);
+	destroy_workqueue(kconservative_wq);
 }
 
 
-MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>");
-MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for "
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
 		"Low Latency Frequency Transition capable processors "
 		"optimised for use in a battery environment");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
 fs_initcall(cpufreq_gov_dbs_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_ondemand.c linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_ondemand.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_ondemand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_ondemand.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/hrtimer.h>
 #include <linux/tick.h>
 #include <linux/ktime.h>
+#include <linux/sched.h>
 
 /*
  * dbs is used in this file as a shortform for demandbased switching
@@ -51,8 +52,20 @@ static unsigned int def_sampling_rate;
 			(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
 #define MIN_SAMPLING_RATE			\
 			(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ *   - "HW transition latency" * 100 (same as default sampling / 10)
+ *   - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+	return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
 #define MAX_SAMPLING_RATE			(500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER	(1000)
+#define LATENCY_MULTIPLIER			(1000)
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
@@ -65,14 +78,14 @@ struct cpu_dbs_info_s {
 	cputime64_t prev_cpu_wall;
 	cputime64_t prev_cpu_nice;
 	struct cpufreq_policy *cur_policy;
- 	struct delayed_work work;
+	struct delayed_work work;
 	struct cpufreq_frequency_table *freq_table;
 	unsigned int freq_lo;
 	unsigned int freq_lo_jiffies;
 	unsigned int freq_hi_jiffies;
 	int cpu;
 	unsigned int enable:1,
-	             sample_type:1;
+		sample_type:1;
 };
 static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
 
@@ -85,6 +98,9 @@ static unsigned int dbs_enable;	/* numbe
  * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
  * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
  * is recursive for the same process. -Venki
+ * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
+ * would deadlock with cancel_delayed_work_sync(), which is needed for proper
+ * raceless workqueue teardown.
  */
 static DEFINE_MUTEX(dbs_mutex);
 
@@ -203,12 +219,28 @@ static void ondemand_powersave_bias_init
 /************************** sysfs interface ************************/
 static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
 {
-	return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+	static int print_once;
+
+	if (!print_once) {
+		printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
+		       "sysfs file is deprecated - used by: %s\n",
+		       current->comm);
+		print_once = 1;
+	}
+	return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
 }
 
 static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
 {
-	return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+	static int print_once;
+
+	if (!print_once) {
+		printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_min "
+		       "sysfs file is deprecated - used by: %s\n",
+		       current->comm);
+		print_once = 1;
+	}
+	return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
 }
 
 #define define_one_ro(_name)		\
@@ -238,13 +270,11 @@ static ssize_t store_sampling_rate(struc
 	ret = sscanf(buf, "%u", &input);
 
 	mutex_lock(&dbs_mutex);
-	if (ret != 1 || input > MAX_SAMPLING_RATE
-		     || input < MIN_SAMPLING_RATE) {
+	if (ret != 1) {
 		mutex_unlock(&dbs_mutex);
 		return -EINVAL;
 	}
-
-	dbs_tuners_ins.sampling_rate = input;
+	dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
 	mutex_unlock(&dbs_mutex);
 
 	return count;
@@ -279,14 +309,14 @@ static ssize_t store_ignore_nice_load(st
 	unsigned int j;
 
 	ret = sscanf(buf, "%u", &input);
-	if ( ret != 1 )
+	if (ret != 1)
 		return -EINVAL;
 
-	if ( input > 1 )
+	if (input > 1)
 		input = 1;
 
 	mutex_lock(&dbs_mutex);
-	if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
+	if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
 		mutex_unlock(&dbs_mutex);
 		return count;
 	}
@@ -337,7 +367,7 @@ define_one_rw(up_threshold);
 define_one_rw(ignore_nice_load);
 define_one_rw(powersave_bias);
 
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
 	&sampling_rate_max.attr,
 	&sampling_rate_min.attr,
 	&sampling_rate.attr,
@@ -512,8 +542,7 @@ static void do_dbs_timer(struct work_str
 		}
 	} else {
 		__cpufreq_driver_target(dbs_info->cur_policy,
-	                        	dbs_info->freq_lo,
-	                        	CPUFREQ_RELATION_H);
+			dbs_info->freq_lo, CPUFREQ_RELATION_H);
 	}
 	queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
 	unlock_policy_rwsem_write(cpu);
@@ -530,13 +559,13 @@ static inline void dbs_timer_init(struct
 	dbs_info->sample_type = DBS_NORMAL_SAMPLE;
 	INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
 	queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
-	                      delay);
+		delay);
 }
 
 static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
 {
 	dbs_info->enable = 0;
-	cancel_delayed_work(&dbs_info->work);
+	cancel_delayed_work_sync(&dbs_info->work);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -591,11 +620,9 @@ static int cpufreq_governor_dbs(struct c
 			if (latency == 0)
 				latency = 1;
 
-			def_sampling_rate = latency *
-					DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
-			if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
-				def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+			def_sampling_rate =
+				max(latency * LATENCY_MULTIPLIER,
+				    MIN_STAT_SAMPLING_RATE);
 
 			dbs_tuners_ins.sampling_rate = def_sampling_rate;
 		}
@@ -617,12 +644,10 @@ static int cpufreq_governor_dbs(struct c
 		mutex_lock(&dbs_mutex);
 		if (policy->max < this_dbs_info->cur_policy->cur)
 			__cpufreq_driver_target(this_dbs_info->cur_policy,
-			                        policy->max,
-			                        CPUFREQ_RELATION_H);
+				policy->max, CPUFREQ_RELATION_H);
 		else if (policy->min > this_dbs_info->cur_policy->cur)
 			__cpufreq_driver_target(this_dbs_info->cur_policy,
-			                        policy->min,
-			                        CPUFREQ_RELATION_L);
+				policy->min, CPUFREQ_RELATION_L);
 		mutex_unlock(&dbs_mutex);
 		break;
 	}
@@ -677,7 +702,7 @@ static void __exit cpufreq_gov_dbs_exit(
 MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
 MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
 MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
-                   "Low Latency Frequency Transition capable processors");
+	"Low Latency Frequency Transition capable processors");
 MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_stats.c linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_stats.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_stats.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_stats.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *  drivers/cpufreq/cpufreq_stats.c
  *
  *  Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
- *	      (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
+ *  (C) 2004 Zou Nan hai <nanhai.zou@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
@@ -23,7 +23,7 @@
 
 static spinlock_t cpufreq_stats_lock;
 
-#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+#define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
 static struct freq_attr _attr_##_name = {\
 	.attr = {.name = __stringify(_name), .mode = _mode, }, \
 	.show = _show,\
@@ -50,8 +50,7 @@ struct cpufreq_stats_attribute {
 	ssize_t(*show) (struct cpufreq_stats *, char *);
 };
 
-static int
-cpufreq_stats_update (unsigned int cpu)
+static int cpufreq_stats_update(unsigned int cpu)
 {
 	struct cpufreq_stats *stat;
 	unsigned long long cur_time;
@@ -68,8 +67,7 @@ cpufreq_stats_update (unsigned int cpu)
 	return 0;
 }
 
-static ssize_t
-show_total_trans(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
 {
 	struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
 	if (!stat)
@@ -78,8 +76,7 @@ show_total_trans(struct cpufreq_policy *
 			per_cpu(cpufreq_stats_table, stat->cpu)->total_trans);
 }
 
-static ssize_t
-show_time_in_state(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
 {
 	ssize_t len = 0;
 	int i;
@@ -89,14 +86,14 @@ show_time_in_state(struct cpufreq_policy
 	cpufreq_stats_update(stat->cpu);
 	for (i = 0; i < stat->state_num; i++) {
 		len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i],
-			(unsigned long long)cputime64_to_clock_t(stat->time_in_state[i]));
+			(unsigned long long)
+			cputime64_to_clock_t(stat->time_in_state[i]));
 	}
 	return len;
 }
 
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-static ssize_t
-show_trans_table(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
 {
 	ssize_t len = 0;
 	int i, j;
@@ -139,11 +136,11 @@ show_trans_table(struct cpufreq_policy *
 		return PAGE_SIZE;
 	return len;
 }
-CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+CPUFREQ_STATDEVICE_ATTR(trans_table, 0444, show_trans_table);
 #endif
 
-CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
-CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+CPUFREQ_STATDEVICE_ATTR(total_trans, 0444, show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state, 0444, show_time_in_state);
 
 static struct attribute *default_attrs[] = {
 	&_attr_total_trans.attr,
@@ -158,8 +155,7 @@ static struct attribute_group stats_attr
 	.name = "stats"
 };
 
-static int
-freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
 {
 	int index;
 	for (index = 0; index < stat->max_state; index++)
@@ -183,8 +179,7 @@ static void cpufreq_stats_free_table(uns
 		cpufreq_cpu_put(policy);
 }
 
-static int
-cpufreq_stats_create_table (struct cpufreq_policy *policy,
+static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
 		struct cpufreq_frequency_table *table)
 {
 	unsigned int i, j, count = 0, ret = 0;
@@ -194,7 +189,8 @@ cpufreq_stats_create_table (struct cpufr
 	unsigned int cpu = policy->cpu;
 	if (per_cpu(cpufreq_stats_table, cpu))
 		return -EBUSY;
-	if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+	stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
+	if ((stat) == NULL)
 		return -ENOMEM;
 
 	data = cpufreq_cpu_get(cpu);
@@ -203,13 +199,14 @@ cpufreq_stats_create_table (struct cpufr
 		goto error_get_fail;
 	}
 
-	if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+	ret = sysfs_create_group(&data->kobj, &stats_attr_group);
+	if (ret)
 		goto error_out;
 
 	stat->cpu = cpu;
 	per_cpu(cpufreq_stats_table, cpu) = stat;
 
-	for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
 		unsigned int freq = table[i].frequency;
 		if (freq == CPUFREQ_ENTRY_INVALID)
 			continue;
@@ -255,9 +252,8 @@ error_get_fail:
 	return ret;
 }
 
-static int
-cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
-		void *data)
+static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
+		unsigned long val, void *data)
 {
 	int ret;
 	struct cpufreq_policy *policy = data;
@@ -268,14 +264,14 @@ cpufreq_stat_notifier_policy (struct not
 	table = cpufreq_frequency_get_table(cpu);
 	if (!table)
 		return 0;
-	if ((ret = cpufreq_stats_create_table(policy, table)))
+	ret = cpufreq_stats_create_table(policy, table);
+	if (ret)
 		return ret;
 	return 0;
 }
 
-static int
-cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
-		void *data)
+static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
+		unsigned long val, void *data)
 {
 	struct cpufreq_freqs *freq = data;
 	struct cpufreq_stats *stat;
@@ -340,19 +336,20 @@ static struct notifier_block notifier_tr
 	.notifier_call = cpufreq_stat_notifier_trans
 };
 
-static int
-__init cpufreq_stats_init(void)
+static int __init cpufreq_stats_init(void)
 {
 	int ret;
 	unsigned int cpu;
 
 	spin_lock_init(&cpufreq_stats_lock);
-	if ((ret = cpufreq_register_notifier(&notifier_policy_block,
-				CPUFREQ_POLICY_NOTIFIER)))
+	ret = cpufreq_register_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER);
+	if (ret)
 		return ret;
 
-	if ((ret = cpufreq_register_notifier(&notifier_trans_block,
-				CPUFREQ_TRANSITION_NOTIFIER))) {
+	ret = cpufreq_register_notifier(&notifier_trans_block,
+				CPUFREQ_TRANSITION_NOTIFIER);
+	if (ret) {
 		cpufreq_unregister_notifier(&notifier_policy_block,
 				CPUFREQ_POLICY_NOTIFIER);
 		return ret;
@@ -364,8 +361,7 @@ __init cpufreq_stats_init(void)
 	}
 	return 0;
 }
-static void
-__exit cpufreq_stats_exit(void)
+static void __exit cpufreq_stats_exit(void)
 {
 	unsigned int cpu;
 
@@ -379,10 +375,10 @@ __exit cpufreq_stats_exit(void)
 	}
 }
 
-MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
-MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats "
+MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats "
 				"through sysfs filesystem");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
 
 module_init(cpufreq_stats_init);
 module_exit(cpufreq_stats_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_userspace.c linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_userspace.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/cpufreq_userspace.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/cpufreq_userspace.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,9 +24,6 @@
 #include <linux/sysfs.h>
 #include <linux/mutex.h>
 
-#include <asm/uaccess.h>
-
-
 /**
  * A few values needed by the userspace governor
  */
@@ -37,7 +34,7 @@ static DEFINE_PER_CPU(unsigned int, cpu_
 							userspace */
 static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
 
-static DEFINE_MUTEX	(userspace_mutex);
+static DEFINE_MUTEX(userspace_mutex);
 static int cpus_using_userspace_governor;
 
 #define dprintk(msg...) \
@@ -46,9 +43,9 @@ static int cpus_using_userspace_governor
 /* keep track of frequency transitions */
 static int
 userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
-                       void *data)
+	void *data)
 {
-        struct cpufreq_freqs *freq = data;
+	struct cpufreq_freqs *freq = data;
 
 	if (!per_cpu(cpu_is_managed, freq->cpu))
 		return 0;
@@ -57,11 +54,11 @@ userspace_cpufreq_notifier(struct notifi
 			freq->cpu, freq->new);
 	per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
 
-        return 0;
+	return 0;
 }
 
 static struct notifier_block userspace_cpufreq_notifier_block = {
-        .notifier_call  = userspace_cpufreq_notifier
+	.notifier_call  = userspace_cpufreq_notifier
 };
 
 
@@ -93,8 +90,11 @@ static int cpufreq_set(struct cpufreq_po
 	 * We're safe from concurrent calls to ->target() here
 	 * as we hold the userspace_mutex lock. If we were calling
 	 * cpufreq_driver_target, a deadlock situation might occur:
-	 * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
-	 * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
+	 * A: cpufreq_set (lock userspace_mutex) ->
+	 *      cpufreq_driver_target(lock policy->lock)
+	 * B: cpufreq_set_policy(lock policy->lock) ->
+	 *      __cpufreq_governor ->
+	 *         cpufreq_governor_userspace (lock userspace_mutex)
 	 */
 	ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
 
@@ -210,9 +210,10 @@ static void __exit cpufreq_gov_userspace
 }
 
 
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
+		"Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
+MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
 fs_initcall(cpufreq_gov_userspace_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/cpufreq/freq_table.c linux-libre-2.6.30-gnu1/drivers/cpufreq/freq_table.c
--- linux-libre-2.6.29-gnu1/drivers/cpufreq/freq_table.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/cpufreq/freq_table.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@ int cpufreq_frequency_table_cpuinfo(stru
 	unsigned int max_freq = 0;
 	unsigned int i;
 
-	for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		unsigned int freq = table[i].frequency;
 		if (freq == CPUFREQ_ENTRY_INVALID) {
 			dprintk("table entry %u is invalid, skipping\n", i);
@@ -70,7 +70,7 @@ int cpufreq_frequency_table_verify(struc
 	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
 				     policy->cpuinfo.max_freq);
 
-	for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		unsigned int freq = table[i].frequency;
 		if (freq == CPUFREQ_ENTRY_INVALID)
 			continue;
@@ -125,13 +125,13 @@ int cpufreq_frequency_table_target(struc
 	if (!cpu_online(policy->cpu))
 		return -EINVAL;
 
-	for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		unsigned int freq = table[i].frequency;
 		if (freq == CPUFREQ_ENTRY_INVALID)
 			continue;
 		if ((freq < policy->min) || (freq > policy->max))
 			continue;
-		switch(relation) {
+		switch (relation) {
 		case CPUFREQ_RELATION_H:
 			if (freq <= target_freq) {
 				if (freq >= optimal.frequency) {
@@ -178,7 +178,7 @@ static DEFINE_PER_CPU(struct cpufreq_fre
 /**
  * show_available_freqs - show available frequencies for the specified CPU
  */
-static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
+static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
 {
 	unsigned int i = 0;
 	unsigned int cpu = policy->cpu;
@@ -190,7 +190,7 @@ static ssize_t show_available_freqs (str
 
 	table = per_cpu(show_table, cpu);
 
-	for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
 			continue;
 		count += sprintf(&buf[count], "%d ", table[i].frequency);
@@ -234,6 +234,6 @@ struct cpufreq_frequency_table *cpufreq_
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("CPUfreq frequency table helpers");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_alg.c linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_alg.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_alg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_alg.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,293 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file implements the Linux crypto algorithms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/hash.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+void set_dynamic_sa_command_0(struct dynamic_sa_ctl *sa, u32 save_h,
+			      u32 save_iv, u32 ld_h, u32 ld_iv, u32 hdr_proc,
+			      u32 h, u32 c, u32 pad_type, u32 op_grp, u32 op,
+			      u32 dir)
+{
+	sa->sa_command_0.w = 0;
+	sa->sa_command_0.bf.save_hash_state = save_h;
+	sa->sa_command_0.bf.save_iv = save_iv;
+	sa->sa_command_0.bf.load_hash_state = ld_h;
+	sa->sa_command_0.bf.load_iv = ld_iv;
+	sa->sa_command_0.bf.hdr_proc = hdr_proc;
+	sa->sa_command_0.bf.hash_alg = h;
+	sa->sa_command_0.bf.cipher_alg = c;
+	sa->sa_command_0.bf.pad_type = pad_type & 3;
+	sa->sa_command_0.bf.extend_pad = pad_type >> 2;
+	sa->sa_command_0.bf.op_group = op_grp;
+	sa->sa_command_0.bf.opcode = op;
+	sa->sa_command_0.bf.dir = dir;
+}
+
+void set_dynamic_sa_command_1(struct dynamic_sa_ctl *sa, u32 cm, u32 hmac_mc,
+			      u32 cfb, u32 esn, u32 sn_mask, u32 mute,
+			      u32 cp_pad, u32 cp_pay, u32 cp_hdr)
+{
+	sa->sa_command_1.w = 0;
+	sa->sa_command_1.bf.crypto_mode31 = (cm & 4) >> 2;
+	sa->sa_command_1.bf.crypto_mode9_8 = cm & 3;
+	sa->sa_command_1.bf.feedback_mode = cfb,
+	sa->sa_command_1.bf.sa_rev = 1;
+	sa->sa_command_1.bf.extended_seq_num = esn;
+	sa->sa_command_1.bf.seq_num_mask = sn_mask;
+	sa->sa_command_1.bf.mutable_bit_proc = mute;
+	sa->sa_command_1.bf.copy_pad = cp_pad;
+	sa->sa_command_1.bf.copy_payload = cp_pay;
+	sa->sa_command_1.bf.copy_hdr = cp_hdr;
+}
+
+int crypto4xx_encrypt(struct ablkcipher_request *req)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+	ctx->direction = DIR_OUTBOUND;
+	ctx->hash_final = 0;
+	ctx->is_hash = 0;
+	ctx->pd_ctl = 0x1;
+
+	return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+				  req->nbytes, req->info,
+				  get_dynamic_sa_iv_size(ctx));
+}
+
+int crypto4xx_decrypt(struct ablkcipher_request *req)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+	ctx->direction = DIR_INBOUND;
+	ctx->hash_final = 0;
+	ctx->is_hash = 0;
+	ctx->pd_ctl = 1;
+
+	return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+				  req->nbytes, req->info,
+				  get_dynamic_sa_iv_size(ctx));
+}
+
+/**
+ * AES Functions
+ */
+static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher,
+				const u8 *key,
+				unsigned int keylen,
+				unsigned char cm,
+				u8 fb)
+{
+	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dynamic_sa_ctl *sa;
+	int    rc;
+
+	if (keylen != AES_KEYSIZE_256 &&
+		keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_128) {
+		crypto_ablkcipher_set_flags(cipher,
+				CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
+	/* Create SA */
+	if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+		crypto4xx_free_sa(ctx);
+
+	rc = crypto4xx_alloc_sa(ctx, SA_AES128_LEN + (keylen-16) / 4);
+	if (rc)
+		return rc;
+
+	if (ctx->state_record_dma_addr == 0) {
+		rc = crypto4xx_alloc_state_record(ctx);
+		if (rc) {
+			crypto4xx_free_sa(ctx);
+			return rc;
+		}
+	}
+	/* Setup SA */
+	sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+	ctx->hash_final = 0;
+
+	set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
+				 SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
+				 SA_NO_HEADER_PROC, SA_HASH_ALG_NULL,
+				 SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO,
+				 SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT,
+				 DIR_INBOUND);
+
+	set_dynamic_sa_command_1(sa, cm, SA_HASH_MODE_HASH,
+				 fb, SA_EXTENDED_SN_OFF,
+				 SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+				 SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+				 SA_NOT_COPY_HDR);
+	crypto4xx_memcpy_le(ctx->sa_in + get_dynamic_sa_offset_key_field(ctx),
+			    key, keylen);
+	sa->sa_contents = SA_AES_CONTENTS | (keylen << 2);
+	sa->sa_command_1.bf.key_len = keylen >> 3;
+	ctx->is_hash = 0;
+	ctx->direction = DIR_INBOUND;
+	memcpy(ctx->sa_in + get_dynamic_sa_offset_state_ptr_field(ctx),
+			(void *)&ctx->state_record_dma_addr, 4);
+	ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+	memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4);
+	sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+	sa->sa_command_0.bf.dir = DIR_OUTBOUND;
+
+	return 0;
+}
+
+int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+			     const u8 *key, unsigned int keylen)
+{
+	return crypto4xx_setkey_aes(cipher, key, keylen, CRYPTO_MODE_CBC,
+				    CRYPTO_FEEDBACK_MODE_NO_FB);
+}
+
+/**
+ * HASH SHA1 Functions
+ */
+static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm,
+				   unsigned int sa_len,
+				   unsigned char ha,
+				   unsigned char hm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct crypto4xx_alg *my_alg = crypto_alg_to_crypto4xx_alg(alg);
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct dynamic_sa_ctl *sa;
+	struct dynamic_sa_hash160 *sa_in;
+	int rc;
+
+	ctx->dev   = my_alg->dev;
+	ctx->is_hash = 1;
+	ctx->hash_final = 0;
+
+	/* Create SA */
+	if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+		crypto4xx_free_sa(ctx);
+
+	rc = crypto4xx_alloc_sa(ctx, sa_len);
+	if (rc)
+		return rc;
+
+	if (ctx->state_record_dma_addr == 0) {
+		crypto4xx_alloc_state_record(ctx);
+		if (!ctx->state_record_dma_addr) {
+			crypto4xx_free_sa(ctx);
+			return -ENOMEM;
+		}
+	}
+
+	tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+	sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+	set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV,
+				 SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA,
+				 SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL,
+				 SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC,
+				 SA_OPCODE_HASH, DIR_INBOUND);
+	set_dynamic_sa_command_1(sa, 0, SA_HASH_MODE_HASH,
+				 CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF,
+				 SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+				 SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+				 SA_NOT_COPY_HDR);
+	ctx->direction = DIR_INBOUND;
+	sa->sa_contents = SA_HASH160_CONTENTS;
+	sa_in = (struct dynamic_sa_hash160 *) ctx->sa_in;
+	/* Need to zero hash digest in SA */
+	memset(sa_in->inner_digest, 0, sizeof(sa_in->inner_digest));
+	memset(sa_in->outer_digest, 0, sizeof(sa_in->outer_digest));
+	sa_in->state_ptr = ctx->state_record_dma_addr;
+	ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+	return 0;
+}
+
+int crypto4xx_hash_init(struct ahash_request *req)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+	int ds;
+	struct dynamic_sa_ctl *sa;
+
+	sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+	ds = crypto_ahash_digestsize(
+			__crypto_ahash_cast(req->base.tfm));
+	sa->sa_command_0.bf.digest_len = ds >> 2;
+	sa->sa_command_0.bf.load_hash_state = SA_LOAD_HASH_FROM_SA;
+	ctx->is_hash = 1;
+	ctx->direction = DIR_INBOUND;
+
+	return 0;
+}
+
+int crypto4xx_hash_update(struct ahash_request *req)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+	ctx->is_hash = 1;
+	ctx->hash_final = 0;
+	ctx->pd_ctl = 0x11;
+	ctx->direction = DIR_INBOUND;
+
+	return crypto4xx_build_pd(&req->base, ctx, req->src,
+				  (struct scatterlist *) req->result,
+				  req->nbytes, NULL, 0);
+}
+
+int crypto4xx_hash_final(struct ahash_request *req)
+{
+	return 0;
+}
+
+int crypto4xx_hash_digest(struct ahash_request *req)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+	ctx->hash_final = 1;
+	ctx->pd_ctl = 0x11;
+	ctx->direction = DIR_INBOUND;
+
+	return crypto4xx_build_pd(&req->base, ctx, req->src,
+				  (struct scatterlist *) req->result,
+				  req->nbytes, NULL, 0);
+}
+
+/**
+ * SHA1 Algorithm
+ */
+int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm)
+{
+	return crypto4xx_hash_alg_init(tfm, SA_HASH160_LEN, SA_HASH_ALG_SHA1,
+				       SA_HASH_MODE_HASH);
+}
+
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_core.c linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_core.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1310 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file implements AMCC crypto offload Linux device driver for use with
+ * Linux CryptoAPI.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+#include <asm/cacheflush.h>
+#include <crypto/internal/hash.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_core.h"
+#include "crypto4xx_sa.h"
+
+#define PPC4XX_SEC_VERSION_STR			"0.5"
+
+/**
+ * PPC4xx Crypto Engine Initialization Routine
+ */
+static void crypto4xx_hw_init(struct crypto4xx_device *dev)
+{
+	union ce_ring_size ring_size;
+	union ce_ring_contol ring_ctrl;
+	union ce_part_ring_size part_ring_size;
+	union ce_io_threshold io_threshold;
+	u32 rand_num;
+	union ce_pe_dma_cfg pe_dma_cfg;
+
+	writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG);
+	/* setup pe dma, include reset sg, pdr and pe, then release reset */
+	pe_dma_cfg.w = 0;
+	pe_dma_cfg.bf.bo_sgpd_en = 1;
+	pe_dma_cfg.bf.bo_data_en = 0;
+	pe_dma_cfg.bf.bo_sa_en = 1;
+	pe_dma_cfg.bf.bo_pd_en = 1;
+	pe_dma_cfg.bf.dynamic_sa_en = 1;
+	pe_dma_cfg.bf.reset_sg = 1;
+	pe_dma_cfg.bf.reset_pdr = 1;
+	pe_dma_cfg.bf.reset_pe = 1;
+	writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+	/* un reset pe,sg and pdr */
+	pe_dma_cfg.bf.pe_mode = 0;
+	pe_dma_cfg.bf.reset_sg = 0;
+	pe_dma_cfg.bf.reset_pdr = 0;
+	pe_dma_cfg.bf.reset_pe = 0;
+	pe_dma_cfg.bf.bo_td_en = 0;
+	writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+	writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_PDR_BASE);
+	writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_RDR_BASE);
+	writel(PPC4XX_PRNG_CTRL_AUTO_EN, dev->ce_base + CRYPTO4XX_PRNG_CTRL);
+	get_random_bytes(&rand_num, sizeof(rand_num));
+	writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_L);
+	get_random_bytes(&rand_num, sizeof(rand_num));
+	writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_H);
+	ring_size.w = 0;
+	ring_size.bf.ring_offset = PPC4XX_PD_SIZE;
+	ring_size.bf.ring_size   = PPC4XX_NUM_PD;
+	writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE);
+	ring_ctrl.w = 0;
+	writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL);
+	writel(PPC4XX_DC_3DES_EN, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
+	writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE);
+	writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE);
+	part_ring_size.w = 0;
+	part_ring_size.bf.sdr_size = PPC4XX_SDR_SIZE;
+	part_ring_size.bf.gdr_size = PPC4XX_GDR_SIZE;
+	writel(part_ring_size.w, dev->ce_base + CRYPTO4XX_PART_RING_SIZE);
+	writel(PPC4XX_SD_BUFFER_SIZE, dev->ce_base + CRYPTO4XX_PART_RING_CFG);
+	io_threshold.w = 0;
+	io_threshold.bf.output_threshold = PPC4XX_OUTPUT_THRESHOLD;
+	io_threshold.bf.input_threshold  = PPC4XX_INPUT_THRESHOLD;
+	writel(io_threshold.w, dev->ce_base + CRYPTO4XX_IO_THRESHOLD);
+	writel(0, dev->ce_base + CRYPTO4XX_PDR_BASE_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_RDR_BASE_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_PKT_SRC_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_PKT_DEST_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_SA_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_GATH_RING_BASE_UADDR);
+	writel(0, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE_UADDR);
+	/* un reset pe,sg and pdr */
+	pe_dma_cfg.bf.pe_mode = 1;
+	pe_dma_cfg.bf.reset_sg = 0;
+	pe_dma_cfg.bf.reset_pdr = 0;
+	pe_dma_cfg.bf.reset_pe = 0;
+	pe_dma_cfg.bf.bo_td_en = 0;
+	writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+	/*clear all pending interrupt*/
+	writel(PPC4XX_INTERRUPT_CLR, dev->ce_base + CRYPTO4XX_INT_CLR);
+	writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+	writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+	writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG);
+	writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN);
+}
+
+int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size)
+{
+	ctx->sa_in = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+					&ctx->sa_in_dma_addr, GFP_ATOMIC);
+	if (ctx->sa_in == NULL)
+		return -ENOMEM;
+
+	ctx->sa_out = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+					 &ctx->sa_out_dma_addr, GFP_ATOMIC);
+	if (ctx->sa_out == NULL) {
+		dma_free_coherent(ctx->dev->core_dev->device,
+				  ctx->sa_len * 4,
+				  ctx->sa_in, ctx->sa_in_dma_addr);
+		return -ENOMEM;
+	}
+
+	memset(ctx->sa_in, 0, size * 4);
+	memset(ctx->sa_out, 0, size * 4);
+	ctx->sa_len = size;
+
+	return 0;
+}
+
+void crypto4xx_free_sa(struct crypto4xx_ctx *ctx)
+{
+	if (ctx->sa_in != NULL)
+		dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+				  ctx->sa_in, ctx->sa_in_dma_addr);
+	if (ctx->sa_out != NULL)
+		dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+				  ctx->sa_out, ctx->sa_out_dma_addr);
+
+	ctx->sa_in_dma_addr = 0;
+	ctx->sa_out_dma_addr = 0;
+	ctx->sa_len = 0;
+}
+
+u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx)
+{
+	ctx->state_record = dma_alloc_coherent(ctx->dev->core_dev->device,
+				sizeof(struct sa_state_record),
+				&ctx->state_record_dma_addr, GFP_ATOMIC);
+	if (!ctx->state_record_dma_addr)
+		return -ENOMEM;
+	memset(ctx->state_record, 0, sizeof(struct sa_state_record));
+
+	return 0;
+}
+
+void crypto4xx_free_state_record(struct crypto4xx_ctx *ctx)
+{
+	if (ctx->state_record != NULL)
+		dma_free_coherent(ctx->dev->core_dev->device,
+				  sizeof(struct sa_state_record),
+				  ctx->state_record,
+				  ctx->state_record_dma_addr);
+	ctx->state_record_dma_addr = 0;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev)
+{
+	int i;
+	struct pd_uinfo *pd_uinfo;
+	dev->pdr = dma_alloc_coherent(dev->core_dev->device,
+				      sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+				      &dev->pdr_pa, GFP_ATOMIC);
+	if (!dev->pdr)
+		return -ENOMEM;
+
+	dev->pdr_uinfo = kzalloc(sizeof(struct pd_uinfo) * PPC4XX_NUM_PD,
+				GFP_KERNEL);
+	if (!dev->pdr_uinfo) {
+		dma_free_coherent(dev->core_dev->device,
+				  sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+				  dev->pdr,
+				  dev->pdr_pa);
+		return -ENOMEM;
+	}
+	memset(dev->pdr, 0,  sizeof(struct ce_pd) * PPC4XX_NUM_PD);
+	dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
+				   256 * PPC4XX_NUM_PD,
+				   &dev->shadow_sa_pool_pa,
+				   GFP_ATOMIC);
+	if (!dev->shadow_sa_pool)
+		return -ENOMEM;
+
+	dev->shadow_sr_pool = dma_alloc_coherent(dev->core_dev->device,
+			 sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+			 &dev->shadow_sr_pool_pa, GFP_ATOMIC);
+	if (!dev->shadow_sr_pool)
+		return -ENOMEM;
+	for (i = 0; i < PPC4XX_NUM_PD; i++) {
+		pd_uinfo = (struct pd_uinfo *) (dev->pdr_uinfo +
+						sizeof(struct pd_uinfo) * i);
+
+		/* alloc 256 bytes which is enough for any kind of dynamic sa */
+		pd_uinfo->sa_va = dev->shadow_sa_pool + 256 * i;
+		pd_uinfo->sa_pa = dev->shadow_sa_pool_pa + 256 * i;
+
+		/* alloc state record */
+		pd_uinfo->sr_va = dev->shadow_sr_pool +
+		    sizeof(struct sa_state_record) * i;
+		pd_uinfo->sr_pa = dev->shadow_sr_pool_pa +
+		    sizeof(struct sa_state_record) * i;
+	}
+
+	return 0;
+}
+
+static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev)
+{
+	if (dev->pdr != NULL)
+		dma_free_coherent(dev->core_dev->device,
+				  sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+				  dev->pdr, dev->pdr_pa);
+	if (dev->shadow_sa_pool)
+		dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD,
+				  dev->shadow_sa_pool, dev->shadow_sa_pool_pa);
+	if (dev->shadow_sr_pool)
+		dma_free_coherent(dev->core_dev->device,
+			sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+			dev->shadow_sr_pool, dev->shadow_sr_pool_pa);
+
+	kfree(dev->pdr_uinfo);
+}
+
+static u32 crypto4xx_get_pd_from_pdr_nolock(struct crypto4xx_device *dev)
+{
+	u32 retval;
+	u32 tmp;
+
+	retval = dev->pdr_head;
+	tmp = (dev->pdr_head + 1) % PPC4XX_NUM_PD;
+
+	if (tmp == dev->pdr_tail)
+		return ERING_WAS_FULL;
+
+	dev->pdr_head = tmp;
+
+	return retval;
+}
+
+static u32 crypto4xx_put_pd_to_pdr(struct crypto4xx_device *dev, u32 idx)
+{
+	struct pd_uinfo *pd_uinfo;
+	unsigned long flags;
+
+	pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+				       sizeof(struct pd_uinfo) * idx);
+	spin_lock_irqsave(&dev->core_dev->lock, flags);
+	if (dev->pdr_tail != PPC4XX_LAST_PD)
+		dev->pdr_tail++;
+	else
+		dev->pdr_tail = 0;
+	pd_uinfo->state = PD_ENTRY_FREE;
+	spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+	return 0;
+}
+
+static struct ce_pd *crypto4xx_get_pdp(struct crypto4xx_device *dev,
+				       dma_addr_t *pd_dma, u32 idx)
+{
+	*pd_dma = dev->pdr_pa + sizeof(struct ce_pd) * idx;
+
+	return dev->pdr + sizeof(struct ce_pd) * idx;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_gdr(struct crypto4xx_device *dev)
+{
+	dev->gdr = dma_alloc_coherent(dev->core_dev->device,
+				      sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+				      &dev->gdr_pa, GFP_ATOMIC);
+	if (!dev->gdr)
+		return -ENOMEM;
+
+	memset(dev->gdr, 0, sizeof(struct ce_gd) * PPC4XX_NUM_GD);
+
+	return 0;
+}
+
+static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev)
+{
+	dma_free_coherent(dev->core_dev->device,
+			  sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+			  dev->gdr, dev->gdr_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+u32 crypto4xx_get_n_gd(struct crypto4xx_device *dev, int n)
+{
+	u32 retval;
+	u32 tmp;
+	if (n >= PPC4XX_NUM_GD)
+		return ERING_WAS_FULL;
+
+	retval = dev->gdr_head;
+	tmp = (dev->gdr_head + n) % PPC4XX_NUM_GD;
+	if (dev->gdr_head > dev->gdr_tail) {
+		if (tmp < dev->gdr_head && tmp >= dev->gdr_tail)
+			return ERING_WAS_FULL;
+	} else if (dev->gdr_head < dev->gdr_tail) {
+		if (tmp < dev->gdr_head || tmp >= dev->gdr_tail)
+			return ERING_WAS_FULL;
+	}
+	dev->gdr_head = tmp;
+
+	return retval;
+}
+
+static u32 crypto4xx_put_gd_to_gdr(struct crypto4xx_device *dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->core_dev->lock, flags);
+	if (dev->gdr_tail == dev->gdr_head) {
+		spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+		return 0;
+	}
+
+	if (dev->gdr_tail != PPC4XX_LAST_GD)
+		dev->gdr_tail++;
+	else
+		dev->gdr_tail = 0;
+
+	spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+	return 0;
+}
+
+static inline struct ce_gd *crypto4xx_get_gdp(struct crypto4xx_device *dev,
+					      dma_addr_t *gd_dma, u32 idx)
+{
+	*gd_dma = dev->gdr_pa + sizeof(struct ce_gd) * idx;
+
+	return (struct ce_gd *) (dev->gdr + sizeof(struct ce_gd) * idx);
+}
+
+/**
+ * alloc memory for the scatter ring
+ * need to alloc buf for the ring
+ * sdr_tail, sdr_head and sdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev)
+{
+	int i;
+	struct ce_sd *sd_array;
+
+	/* alloc memory for scatter descriptor ring */
+	dev->sdr = dma_alloc_coherent(dev->core_dev->device,
+				      sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+				      &dev->sdr_pa, GFP_ATOMIC);
+	if (!dev->sdr)
+		return -ENOMEM;
+
+	dev->scatter_buffer_size = PPC4XX_SD_BUFFER_SIZE;
+	dev->scatter_buffer_va =
+		dma_alloc_coherent(dev->core_dev->device,
+			dev->scatter_buffer_size * PPC4XX_NUM_SD,
+			&dev->scatter_buffer_pa, GFP_ATOMIC);
+	if (!dev->scatter_buffer_va) {
+		dma_free_coherent(dev->core_dev->device,
+				  sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+				  dev->sdr, dev->sdr_pa);
+		return -ENOMEM;
+	}
+
+	sd_array = dev->sdr;
+
+	for (i = 0; i < PPC4XX_NUM_SD; i++) {
+		sd_array[i].ptr = dev->scatter_buffer_pa +
+				  dev->scatter_buffer_size * i;
+	}
+
+	return 0;
+}
+
+static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev)
+{
+	if (dev->sdr != NULL)
+		dma_free_coherent(dev->core_dev->device,
+				  sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+				  dev->sdr, dev->sdr_pa);
+
+	if (dev->scatter_buffer_va != NULL)
+		dma_free_coherent(dev->core_dev->device,
+				  dev->scatter_buffer_size * PPC4XX_NUM_SD,
+				  dev->scatter_buffer_va,
+				  dev->scatter_buffer_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+static u32 crypto4xx_get_n_sd(struct crypto4xx_device *dev, int n)
+{
+	u32 retval;
+	u32 tmp;
+
+	if (n >= PPC4XX_NUM_SD)
+		return ERING_WAS_FULL;
+
+	retval = dev->sdr_head;
+	tmp = (dev->sdr_head + n) % PPC4XX_NUM_SD;
+	if (dev->sdr_head > dev->gdr_tail) {
+		if (tmp < dev->sdr_head && tmp >= dev->sdr_tail)
+			return ERING_WAS_FULL;
+	} else if (dev->sdr_head < dev->sdr_tail) {
+		if (tmp < dev->sdr_head || tmp >= dev->sdr_tail)
+			return ERING_WAS_FULL;
+	} /* the head = tail, or empty case is already take cared */
+	dev->sdr_head = tmp;
+
+	return retval;
+}
+
+static u32 crypto4xx_put_sd_to_sdr(struct crypto4xx_device *dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->core_dev->lock, flags);
+	if (dev->sdr_tail == dev->sdr_head) {
+		spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+		return 0;
+	}
+	if (dev->sdr_tail != PPC4XX_LAST_SD)
+		dev->sdr_tail++;
+	else
+		dev->sdr_tail = 0;
+	spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+	return 0;
+}
+
+static inline struct ce_sd *crypto4xx_get_sdp(struct crypto4xx_device *dev,
+					      dma_addr_t *sd_dma, u32 idx)
+{
+	*sd_dma = dev->sdr_pa + sizeof(struct ce_sd) * idx;
+
+	return  (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx);
+}
+
+static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev,
+				   dma_addr_t *addr, u32 *length,
+				   u32 *idx, u32 *offset, u32 *nbytes)
+{
+	u32 len;
+
+	if (*length > dev->scatter_buffer_size) {
+		memcpy(phys_to_virt(*addr),
+			dev->scatter_buffer_va +
+			*idx * dev->scatter_buffer_size + *offset,
+			dev->scatter_buffer_size);
+		*offset = 0;
+		*length -= dev->scatter_buffer_size;
+		*nbytes -= dev->scatter_buffer_size;
+		if (*idx == PPC4XX_LAST_SD)
+			*idx = 0;
+		else
+			(*idx)++;
+		*addr = *addr +  dev->scatter_buffer_size;
+		return 1;
+	} else if (*length < dev->scatter_buffer_size) {
+		memcpy(phys_to_virt(*addr),
+			dev->scatter_buffer_va +
+			*idx * dev->scatter_buffer_size + *offset, *length);
+		if ((*offset + *length) == dev->scatter_buffer_size) {
+			if (*idx == PPC4XX_LAST_SD)
+				*idx = 0;
+			else
+				(*idx)++;
+			*nbytes -= *length;
+			*offset = 0;
+		} else {
+			*nbytes -= *length;
+			*offset += *length;
+		}
+
+		return 0;
+	} else {
+		len = (*nbytes <= dev->scatter_buffer_size) ?
+				(*nbytes) : dev->scatter_buffer_size;
+		memcpy(phys_to_virt(*addr),
+			dev->scatter_buffer_va +
+			*idx * dev->scatter_buffer_size + *offset,
+			len);
+		*offset = 0;
+		*nbytes -= len;
+
+		if (*idx == PPC4XX_LAST_SD)
+			*idx = 0;
+		else
+			(*idx)++;
+
+		return 0;
+    }
+}
+
+static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev,
+				      struct ce_pd *pd,
+				      struct pd_uinfo *pd_uinfo,
+				      u32 nbytes,
+				      struct scatterlist *dst)
+{
+	dma_addr_t addr;
+	u32 this_sd;
+	u32 offset;
+	u32 len;
+	u32 i;
+	u32 sg_len;
+	struct scatterlist *sg;
+
+	this_sd = pd_uinfo->first_sd;
+	offset = 0;
+	i = 0;
+
+	while (nbytes) {
+		sg = &dst[i];
+		sg_len = sg->length;
+		addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+				sg->offset, sg->length, DMA_TO_DEVICE);
+
+		if (offset == 0) {
+			len = (nbytes <= sg->length) ? nbytes : sg->length;
+			while (crypto4xx_fill_one_page(dev, &addr, &len,
+				&this_sd, &offset, &nbytes))
+				;
+			if (!nbytes)
+				return;
+			i++;
+		} else {
+			len = (nbytes <= (dev->scatter_buffer_size - offset)) ?
+				nbytes : (dev->scatter_buffer_size - offset);
+			len = (sg->length < len) ? sg->length : len;
+			while (crypto4xx_fill_one_page(dev, &addr, &len,
+					       &this_sd, &offset, &nbytes))
+				;
+			if (!nbytes)
+				return;
+			sg_len -= len;
+			if (sg_len) {
+				addr += len;
+				while (crypto4xx_fill_one_page(dev, &addr,
+					&sg_len, &this_sd, &offset, &nbytes))
+					;
+			}
+			i++;
+		}
+	}
+}
+
+static u32 crypto4xx_copy_digest_to_dst(struct pd_uinfo *pd_uinfo,
+					struct crypto4xx_ctx *ctx)
+{
+	struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+	struct sa_state_record *state_record =
+				(struct sa_state_record *) pd_uinfo->sr_va;
+
+	if (sa->sa_command_0.bf.hash_alg == SA_HASH_ALG_SHA1) {
+		memcpy((void *) pd_uinfo->dest_va, state_record->save_digest,
+		       SA_HASH_ALG_SHA1_DIGEST_SIZE);
+	}
+
+	return 0;
+}
+
+static void crypto4xx_ret_sg_desc(struct crypto4xx_device *dev,
+				  struct pd_uinfo *pd_uinfo)
+{
+	int i;
+	if (pd_uinfo->num_gd) {
+		for (i = 0; i < pd_uinfo->num_gd; i++)
+			crypto4xx_put_gd_to_gdr(dev);
+		pd_uinfo->first_gd = 0xffffffff;
+		pd_uinfo->num_gd = 0;
+	}
+	if (pd_uinfo->num_sd) {
+		for (i = 0; i < pd_uinfo->num_sd; i++)
+			crypto4xx_put_sd_to_sdr(dev);
+
+		pd_uinfo->first_sd = 0xffffffff;
+		pd_uinfo->num_sd = 0;
+	}
+}
+
+static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev,
+				     struct pd_uinfo *pd_uinfo,
+				     struct ce_pd *pd)
+{
+	struct crypto4xx_ctx *ctx;
+	struct ablkcipher_request *ablk_req;
+	struct scatterlist *dst;
+	dma_addr_t addr;
+
+	ablk_req = ablkcipher_request_cast(pd_uinfo->async_req);
+	ctx  = crypto_tfm_ctx(ablk_req->base.tfm);
+
+	if (pd_uinfo->using_sd) {
+		crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo, ablk_req->nbytes,
+					  ablk_req->dst);
+	} else {
+		dst = pd_uinfo->dest_va;
+		addr = dma_map_page(dev->core_dev->device, sg_page(dst),
+				    dst->offset, dst->length, DMA_FROM_DEVICE);
+	}
+	crypto4xx_ret_sg_desc(dev, pd_uinfo);
+	if (ablk_req->base.complete != NULL)
+		ablk_req->base.complete(&ablk_req->base, 0);
+
+	return 0;
+}
+
+static u32 crypto4xx_ahash_done(struct crypto4xx_device *dev,
+				struct pd_uinfo *pd_uinfo)
+{
+	struct crypto4xx_ctx *ctx;
+	struct ahash_request *ahash_req;
+
+	ahash_req = ahash_request_cast(pd_uinfo->async_req);
+	ctx  = crypto_tfm_ctx(ahash_req->base.tfm);
+
+	crypto4xx_copy_digest_to_dst(pd_uinfo,
+				     crypto_tfm_ctx(ahash_req->base.tfm));
+	crypto4xx_ret_sg_desc(dev, pd_uinfo);
+	/* call user provided callback function x */
+	if (ahash_req->base.complete != NULL)
+		ahash_req->base.complete(&ahash_req->base, 0);
+
+	return 0;
+}
+
+static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx)
+{
+	struct ce_pd *pd;
+	struct pd_uinfo *pd_uinfo;
+
+	pd =  dev->pdr + sizeof(struct ce_pd)*idx;
+	pd_uinfo = dev->pdr_uinfo + sizeof(struct pd_uinfo)*idx;
+	if (crypto_tfm_alg_type(pd_uinfo->async_req->tfm) ==
+			CRYPTO_ALG_TYPE_ABLKCIPHER)
+		return crypto4xx_ablkcipher_done(dev, pd_uinfo, pd);
+	else
+		return crypto4xx_ahash_done(dev, pd_uinfo);
+}
+
+/**
+ * Note: Only use this function to copy items that is word aligned.
+ */
+void crypto4xx_memcpy_le(unsigned int *dst,
+			 const unsigned char *buf,
+			 int len)
+{
+	u8 *tmp;
+	for (; len >= 4; buf += 4, len -= 4)
+		*dst++ = cpu_to_le32(*(unsigned int *) buf);
+
+	tmp = (u8 *)dst;
+	switch (len) {
+	case 3:
+		*tmp++ = 0;
+		*tmp++ = *(buf+2);
+		*tmp++ = *(buf+1);
+		*tmp++ = *buf;
+		break;
+	case 2:
+		*tmp++ = 0;
+		*tmp++ = 0;
+		*tmp++ = *(buf+1);
+		*tmp++ = *buf;
+		break;
+	case 1:
+		*tmp++ = 0;
+		*tmp++ = 0;
+		*tmp++ = 0;
+		*tmp++ = *buf;
+		break;
+	default:
+		break;
+	}
+}
+
+static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev)
+{
+	crypto4xx_destroy_pdr(core_dev->dev);
+	crypto4xx_destroy_gdr(core_dev->dev);
+	crypto4xx_destroy_sdr(core_dev->dev);
+	dev_set_drvdata(core_dev->device, NULL);
+	iounmap(core_dev->dev->ce_base);
+	kfree(core_dev->dev);
+	kfree(core_dev);
+}
+
+void crypto4xx_return_pd(struct crypto4xx_device *dev,
+			 u32 pd_entry, struct ce_pd *pd,
+			 struct pd_uinfo *pd_uinfo)
+{
+	/* irq should be already disabled */
+	dev->pdr_head = pd_entry;
+	pd->pd_ctl.w = 0;
+	pd->pd_ctl_len.w = 0;
+	pd_uinfo->state = PD_ENTRY_FREE;
+}
+
+/*
+ * derive number of elements in scatterlist
+ * Shamlessly copy from talitos.c
+ */
+static int get_sg_count(struct scatterlist *sg_list, int nbytes)
+{
+	struct scatterlist *sg = sg_list;
+	int sg_nents = 0;
+
+	while (nbytes) {
+		sg_nents++;
+		if (sg->length > nbytes)
+			break;
+		nbytes -= sg->length;
+		sg = sg_next(sg);
+	}
+
+	return sg_nents;
+}
+
+static u32 get_next_gd(u32 current)
+{
+	if (current != PPC4XX_LAST_GD)
+		return current + 1;
+	else
+		return 0;
+}
+
+static u32 get_next_sd(u32 current)
+{
+	if (current != PPC4XX_LAST_SD)
+		return current + 1;
+	else
+		return 0;
+}
+
+u32 crypto4xx_build_pd(struct crypto_async_request *req,
+		       struct crypto4xx_ctx *ctx,
+		       struct scatterlist *src,
+		       struct scatterlist *dst,
+		       unsigned int datalen,
+		       void *iv, u32 iv_len)
+{
+	struct crypto4xx_device *dev = ctx->dev;
+	dma_addr_t addr, pd_dma, sd_dma, gd_dma;
+	struct dynamic_sa_ctl *sa;
+	struct scatterlist *sg;
+	struct ce_gd *gd;
+	struct ce_pd *pd;
+	u32 num_gd, num_sd;
+	u32 fst_gd = 0xffffffff;
+	u32 fst_sd = 0xffffffff;
+	u32 pd_entry;
+	unsigned long flags;
+	struct pd_uinfo *pd_uinfo = NULL;
+	unsigned int nbytes = datalen, idx;
+	unsigned int ivlen = 0;
+	u32 gd_idx = 0;
+
+	/* figure how many gd is needed */
+	num_gd = get_sg_count(src, datalen);
+	if (num_gd == 1)
+		num_gd = 0;
+
+	/* figure how many sd is needed */
+	if (sg_is_last(dst) || ctx->is_hash) {
+		num_sd = 0;
+	} else {
+		if (datalen > PPC4XX_SD_BUFFER_SIZE) {
+			num_sd = datalen / PPC4XX_SD_BUFFER_SIZE;
+			if (datalen % PPC4XX_SD_BUFFER_SIZE)
+				num_sd++;
+		} else {
+			num_sd = 1;
+		}
+	}
+
+	/*
+	 * The follow section of code needs to be protected
+	 * The gather ring and scatter ring needs to be consecutive
+	 * In case of run out of any kind of descriptor, the descriptor
+	 * already got must be return the original place.
+	 */
+	spin_lock_irqsave(&dev->core_dev->lock, flags);
+	if (num_gd) {
+		fst_gd = crypto4xx_get_n_gd(dev, num_gd);
+		if (fst_gd == ERING_WAS_FULL) {
+			spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+			return -EAGAIN;
+		}
+	}
+	if (num_sd) {
+		fst_sd = crypto4xx_get_n_sd(dev, num_sd);
+		if (fst_sd == ERING_WAS_FULL) {
+			if (num_gd)
+				dev->gdr_head = fst_gd;
+			spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+			return -EAGAIN;
+		}
+	}
+	pd_entry = crypto4xx_get_pd_from_pdr_nolock(dev);
+	if (pd_entry == ERING_WAS_FULL) {
+		if (num_gd)
+			dev->gdr_head = fst_gd;
+		if (num_sd)
+			dev->sdr_head = fst_sd;
+		spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+		return -EAGAIN;
+	}
+	spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+	pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+				       sizeof(struct pd_uinfo) * pd_entry);
+	pd = crypto4xx_get_pdp(dev, &pd_dma, pd_entry);
+	pd_uinfo->async_req = req;
+	pd_uinfo->num_gd = num_gd;
+	pd_uinfo->num_sd = num_sd;
+
+	if (iv_len || ctx->is_hash) {
+		ivlen = iv_len;
+		pd->sa = pd_uinfo->sa_pa;
+		sa = (struct dynamic_sa_ctl *) pd_uinfo->sa_va;
+		if (ctx->direction == DIR_INBOUND)
+			memcpy(sa, ctx->sa_in, ctx->sa_len * 4);
+		else
+			memcpy(sa, ctx->sa_out, ctx->sa_len * 4);
+
+		memcpy((void *) sa + ctx->offset_to_sr_ptr,
+			&pd_uinfo->sr_pa, 4);
+
+		if (iv_len)
+			crypto4xx_memcpy_le(pd_uinfo->sr_va, iv, iv_len);
+	} else {
+		if (ctx->direction == DIR_INBOUND) {
+			pd->sa = ctx->sa_in_dma_addr;
+			sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+		} else {
+			pd->sa = ctx->sa_out_dma_addr;
+			sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+		}
+	}
+	pd->sa_len = ctx->sa_len;
+	if (num_gd) {
+		/* get first gd we are going to use */
+		gd_idx = fst_gd;
+		pd_uinfo->first_gd = fst_gd;
+		pd_uinfo->num_gd = num_gd;
+		gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+		pd->src = gd_dma;
+		/* enable gather */
+		sa->sa_command_0.bf.gather = 1;
+		idx = 0;
+		src = &src[0];
+		/* walk the sg, and setup gather array */
+		while (nbytes) {
+			sg = &src[idx];
+			addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+				    sg->offset, sg->length, DMA_TO_DEVICE);
+			gd->ptr = addr;
+			gd->ctl_len.len = sg->length;
+			gd->ctl_len.done = 0;
+			gd->ctl_len.ready = 1;
+			if (sg->length >= nbytes)
+				break;
+			nbytes -= sg->length;
+			gd_idx = get_next_gd(gd_idx);
+			gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+			idx++;
+		}
+	} else {
+		pd->src = (u32)dma_map_page(dev->core_dev->device, sg_page(src),
+				src->offset, src->length, DMA_TO_DEVICE);
+		/*
+		 * Disable gather in sa command
+		 */
+		sa->sa_command_0.bf.gather = 0;
+		/*
+		 * Indicate gather array is not used
+		 */
+		pd_uinfo->first_gd = 0xffffffff;
+		pd_uinfo->num_gd = 0;
+	}
+	if (ctx->is_hash || sg_is_last(dst)) {
+		/*
+		 * we know application give us dst a whole piece of memory
+		 * no need to use scatter ring.
+		 * In case of is_hash, the icv is always at end of src data.
+		 */
+		pd_uinfo->using_sd = 0;
+		pd_uinfo->first_sd = 0xffffffff;
+		pd_uinfo->num_sd = 0;
+		pd_uinfo->dest_va = dst;
+		sa->sa_command_0.bf.scatter = 0;
+		if (ctx->is_hash)
+			pd->dest = virt_to_phys((void *)dst);
+		else
+			pd->dest = (u32)dma_map_page(dev->core_dev->device,
+					sg_page(dst), dst->offset,
+					dst->length, DMA_TO_DEVICE);
+	} else {
+		struct ce_sd *sd = NULL;
+		u32 sd_idx = fst_sd;
+		nbytes = datalen;
+		sa->sa_command_0.bf.scatter = 1;
+		pd_uinfo->using_sd = 1;
+		pd_uinfo->dest_va = dst;
+		pd_uinfo->first_sd = fst_sd;
+		pd_uinfo->num_sd = num_sd;
+		sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+		pd->dest = sd_dma;
+		/* setup scatter descriptor */
+		sd->ctl.done = 0;
+		sd->ctl.rdy = 1;
+		/* sd->ptr should be setup by sd_init routine*/
+		idx = 0;
+		if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+			nbytes -= PPC4XX_SD_BUFFER_SIZE;
+		else
+			nbytes = 0;
+		while (nbytes) {
+			sd_idx = get_next_sd(sd_idx);
+			sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+			/* setup scatter descriptor */
+			sd->ctl.done = 0;
+			sd->ctl.rdy = 1;
+			if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+				nbytes -= PPC4XX_SD_BUFFER_SIZE;
+			else
+				/*
+				 * SD entry can hold PPC4XX_SD_BUFFER_SIZE,
+				 * which is more than nbytes, so done.
+				 */
+				nbytes = 0;
+		}
+	}
+
+	sa->sa_command_1.bf.hash_crypto_offset = 0;
+	pd->pd_ctl.w = ctx->pd_ctl;
+	pd->pd_ctl_len.w = 0x00400000 | (ctx->bypass << 24) | datalen;
+	pd_uinfo->state = PD_ENTRY_INUSE;
+	wmb();
+	/* write any value to push engine to read a pd */
+	writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD);
+	return -EINPROGRESS;
+}
+
+/**
+ * Algorithm Registration Functions
+ */
+static int crypto4xx_alg_init(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct crypto4xx_alg *amcc_alg = crypto_alg_to_crypto4xx_alg(alg);
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->dev = amcc_alg->dev;
+	ctx->sa_in = NULL;
+	ctx->sa_out = NULL;
+	ctx->sa_in_dma_addr = 0;
+	ctx->sa_out_dma_addr = 0;
+	ctx->sa_len = 0;
+
+	if (alg->cra_type == &crypto_ablkcipher_type)
+		tfm->crt_ablkcipher.reqsize = sizeof(struct crypto4xx_ctx);
+	else if (alg->cra_type == &crypto_ahash_type)
+		tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+
+	return 0;
+}
+
+static void crypto4xx_alg_exit(struct crypto_tfm *tfm)
+{
+	struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	crypto4xx_free_sa(ctx);
+	crypto4xx_free_state_record(ctx);
+}
+
+int crypto4xx_register_alg(struct crypto4xx_device *sec_dev,
+			   struct crypto_alg *crypto_alg, int array_size)
+{
+	struct crypto4xx_alg *alg;
+	int i;
+	int rc = 0;
+
+	for (i = 0; i < array_size; i++) {
+		alg = kzalloc(sizeof(struct crypto4xx_alg), GFP_KERNEL);
+		if (!alg)
+			return -ENOMEM;
+
+		alg->alg = crypto_alg[i];
+		INIT_LIST_HEAD(&alg->alg.cra_list);
+		if (alg->alg.cra_init == NULL)
+			alg->alg.cra_init = crypto4xx_alg_init;
+		if (alg->alg.cra_exit == NULL)
+			alg->alg.cra_exit = crypto4xx_alg_exit;
+		alg->dev = sec_dev;
+		rc = crypto_register_alg(&alg->alg);
+		if (rc) {
+			list_del(&alg->entry);
+			kfree(alg);
+		} else {
+			list_add_tail(&alg->entry, &sec_dev->alg_list);
+		}
+	}
+
+	return 0;
+}
+
+static void crypto4xx_unregister_alg(struct crypto4xx_device *sec_dev)
+{
+	struct crypto4xx_alg *alg, *tmp;
+
+	list_for_each_entry_safe(alg, tmp, &sec_dev->alg_list, entry) {
+		list_del(&alg->entry);
+		crypto_unregister_alg(&alg->alg);
+		kfree(alg);
+	}
+}
+
+static void crypto4xx_bh_tasklet_cb(unsigned long data)
+{
+	struct device *dev = (struct device *)data;
+	struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+	struct pd_uinfo *pd_uinfo;
+	struct ce_pd *pd;
+	u32 tail;
+
+	while (core_dev->dev->pdr_head != core_dev->dev->pdr_tail) {
+		tail = core_dev->dev->pdr_tail;
+		pd_uinfo = core_dev->dev->pdr_uinfo +
+			sizeof(struct pd_uinfo)*tail;
+		pd =  core_dev->dev->pdr + sizeof(struct ce_pd) * tail;
+		if ((pd_uinfo->state == PD_ENTRY_INUSE) &&
+				   pd->pd_ctl.bf.pe_done &&
+				   !pd->pd_ctl.bf.host_ready) {
+			pd->pd_ctl.bf.pe_done = 0;
+			crypto4xx_pd_done(core_dev->dev, tail);
+			crypto4xx_put_pd_to_pdr(core_dev->dev, tail);
+			pd_uinfo->state = PD_ENTRY_FREE;
+		} else {
+			/* if tail not done, break */
+			break;
+		}
+	}
+}
+
+/**
+ * Top Half of isr.
+ */
+static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data)
+{
+	struct device *dev = (struct device *)data;
+	struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+	if (core_dev->dev->ce_base == 0)
+		return 0;
+
+	writel(PPC4XX_INTERRUPT_CLR,
+	       core_dev->dev->ce_base + CRYPTO4XX_INT_CLR);
+	tasklet_schedule(&core_dev->tasklet);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * Supported Crypto Algorithms
+ */
+struct crypto_alg crypto4xx_alg[] = {
+	/* Crypto AES modes */
+	{
+		.cra_name 	= "cbc(aes)",
+		.cra_driver_name = "cbc-aes-ppc4xx",
+		.cra_priority 	= CRYPTO4XX_CRYPTO_PRIORITY,
+		.cra_flags 	= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+		.cra_blocksize 	= AES_BLOCK_SIZE,
+		.cra_ctxsize 	= sizeof(struct crypto4xx_ctx),
+		.cra_alignmask 	= 0,
+		.cra_type 	= &crypto_ablkcipher_type,
+		.cra_module 	= THIS_MODULE,
+		.cra_u 		= {
+			.ablkcipher = {
+				.min_keysize 	= AES_MIN_KEY_SIZE,
+				.max_keysize 	= AES_MAX_KEY_SIZE,
+				.ivsize		= AES_IV_SIZE,
+				.setkey 	= crypto4xx_setkey_aes_cbc,
+				.encrypt 	= crypto4xx_encrypt,
+				.decrypt 	= crypto4xx_decrypt,
+			}
+		}
+	},
+	/* Hash SHA1 */
+	{
+		.cra_name	= "sha1",
+		.cra_driver_name = "sha1-ppc4xx",
+		.cra_priority	= CRYPTO4XX_CRYPTO_PRIORITY,
+		.cra_flags	= CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+		.cra_blocksize	= SHA1_BLOCK_SIZE,
+		.cra_ctxsize	= sizeof(struct crypto4xx_ctx),
+		.cra_alignmask	= 0,
+		.cra_type	= &crypto_ahash_type,
+		.cra_init	= crypto4xx_sha1_alg_init,
+		.cra_module	= THIS_MODULE,
+		.cra_u		= {
+			.ahash = {
+				.digestsize 	= SHA1_DIGEST_SIZE,
+				.init		= crypto4xx_hash_init,
+				.update		= crypto4xx_hash_update,
+				.final  	= crypto4xx_hash_final,
+				.digest 	= crypto4xx_hash_digest,
+			}
+		}
+	},
+};
+
+/**
+ * Module Initialization Routine
+ */
+static int __init crypto4xx_probe(struct of_device *ofdev,
+				  const struct of_device_id *match)
+{
+	int rc;
+	struct resource res;
+	struct device *dev = &ofdev->dev;
+	struct crypto4xx_core_device *core_dev;
+
+	rc = of_address_to_resource(ofdev->node, 0, &res);
+	if (rc)
+		return -ENODEV;
+
+	if (of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto")) {
+		mtdcri(SDR0, PPC460EX_SDR0_SRST,
+		       mfdcri(SDR0, PPC460EX_SDR0_SRST) | PPC460EX_CE_RESET);
+		mtdcri(SDR0, PPC460EX_SDR0_SRST,
+		       mfdcri(SDR0, PPC460EX_SDR0_SRST) & ~PPC460EX_CE_RESET);
+	} else if (of_find_compatible_node(NULL, NULL,
+			"amcc,ppc405ex-crypto")) {
+		mtdcri(SDR0, PPC405EX_SDR0_SRST,
+		       mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET);
+		mtdcri(SDR0, PPC405EX_SDR0_SRST,
+		       mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET);
+	} else if (of_find_compatible_node(NULL, NULL,
+			"amcc,ppc460sx-crypto")) {
+		mtdcri(SDR0, PPC460SX_SDR0_SRST,
+		       mfdcri(SDR0, PPC460SX_SDR0_SRST) | PPC460SX_CE_RESET);
+		mtdcri(SDR0, PPC460SX_SDR0_SRST,
+		       mfdcri(SDR0, PPC460SX_SDR0_SRST) & ~PPC460SX_CE_RESET);
+	} else {
+		printk(KERN_ERR "Crypto Function Not supported!\n");
+		return -EINVAL;
+	}
+
+	core_dev = kzalloc(sizeof(struct crypto4xx_core_device), GFP_KERNEL);
+	if (!core_dev)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, core_dev);
+	core_dev->ofdev = ofdev;
+	core_dev->dev = kzalloc(sizeof(struct crypto4xx_device), GFP_KERNEL);
+	if (!core_dev->dev)
+		goto err_alloc_dev;
+
+	core_dev->dev->core_dev = core_dev;
+	core_dev->device = dev;
+	spin_lock_init(&core_dev->lock);
+	INIT_LIST_HEAD(&core_dev->dev->alg_list);
+	rc = crypto4xx_build_pdr(core_dev->dev);
+	if (rc)
+		goto err_build_pdr;
+
+	rc = crypto4xx_build_gdr(core_dev->dev);
+	if (rc)
+		goto err_build_gdr;
+
+	rc = crypto4xx_build_sdr(core_dev->dev);
+	if (rc)
+		goto err_build_sdr;
+
+	/* Init tasklet for bottom half processing */
+	tasklet_init(&core_dev->tasklet, crypto4xx_bh_tasklet_cb,
+		     (unsigned long) dev);
+
+	/* Register for Crypto isr, Crypto Engine IRQ */
+	core_dev->irq = irq_of_parse_and_map(ofdev->node, 0);
+	rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
+			 core_dev->dev->name, dev);
+	if (rc)
+		goto err_request_irq;
+
+	core_dev->dev->ce_base = of_iomap(ofdev->node, 0);
+	if (!core_dev->dev->ce_base) {
+		dev_err(dev, "failed to of_iomap\n");
+		goto err_iomap;
+	}
+
+	/* need to setup pdr, rdr, gdr and sdr before this */
+	crypto4xx_hw_init(core_dev->dev);
+
+	/* Register security algorithms with Linux CryptoAPI */
+	rc = crypto4xx_register_alg(core_dev->dev, crypto4xx_alg,
+			       ARRAY_SIZE(crypto4xx_alg));
+	if (rc)
+		goto err_start_dev;
+
+	return 0;
+
+err_start_dev:
+	iounmap(core_dev->dev->ce_base);
+err_iomap:
+	free_irq(core_dev->irq, dev);
+	irq_dispose_mapping(core_dev->irq);
+	tasklet_kill(&core_dev->tasklet);
+err_request_irq:
+	crypto4xx_destroy_sdr(core_dev->dev);
+err_build_sdr:
+	crypto4xx_destroy_gdr(core_dev->dev);
+err_build_gdr:
+	crypto4xx_destroy_pdr(core_dev->dev);
+err_build_pdr:
+	kfree(core_dev->dev);
+err_alloc_dev:
+	kfree(core_dev);
+
+	return rc;
+}
+
+static int __exit crypto4xx_remove(struct of_device *ofdev)
+{
+	struct device *dev = &ofdev->dev;
+	struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+	free_irq(core_dev->irq, dev);
+	irq_dispose_mapping(core_dev->irq);
+
+	tasklet_kill(&core_dev->tasklet);
+	/* Un-register with Linux CryptoAPI */
+	crypto4xx_unregister_alg(core_dev->dev);
+	/* Free all allocated memory */
+	crypto4xx_stop_all(core_dev);
+
+	return 0;
+}
+
+static struct of_device_id crypto4xx_match[] = {
+	{ .compatible      = "amcc,ppc4xx-crypto",},
+	{ },
+};
+
+static struct of_platform_driver crypto4xx_driver = {
+	.name		= "crypto4xx",
+	.match_table	= crypto4xx_match,
+	.probe		= crypto4xx_probe,
+	.remove		= crypto4xx_remove,
+};
+
+static int __init crypto4xx_init(void)
+{
+	return of_register_platform_driver(&crypto4xx_driver);
+}
+
+static void __exit crypto4xx_exit(void)
+{
+	of_unregister_platform_driver(&crypto4xx_driver);
+}
+
+module_init(crypto4xx_init);
+module_exit(crypto4xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
+MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_core.h linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_core.h
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_core.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,177 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This is the header file for AMCC Crypto offload Linux device driver for
+ * use with Linux CryptoAPI.
+
+ */
+
+#ifndef __CRYPTO4XX_CORE_H__
+#define __CRYPTO4XX_CORE_H__
+
+#define PPC460SX_SDR0_SRST                      0x201
+#define PPC405EX_SDR0_SRST                      0x200
+#define PPC460EX_SDR0_SRST                      0x201
+#define PPC460EX_CE_RESET                       0x08000000
+#define PPC460SX_CE_RESET                       0x20000000
+#define PPC405EX_CE_RESET                       0x00000008
+
+#define CRYPTO4XX_CRYPTO_PRIORITY		300
+#define PPC4XX_LAST_PD				63
+#define PPC4XX_NUM_PD				64
+#define PPC4XX_LAST_GD				1023
+#define PPC4XX_NUM_GD				1024
+#define PPC4XX_LAST_SD				63
+#define PPC4XX_NUM_SD				64
+#define PPC4XX_SD_BUFFER_SIZE			2048
+
+#define PD_ENTRY_INUSE				1
+#define PD_ENTRY_FREE				0
+#define ERING_WAS_FULL				0xffffffff
+
+struct crypto4xx_device;
+
+struct pd_uinfo {
+	struct crypto4xx_device *dev;
+	u32   state;
+	u32 using_sd;
+	u32 first_gd;		/* first gather discriptor
+				used by this packet */
+	u32 num_gd;             /* number of gather discriptor
+				used by this packet */
+	u32 first_sd;		/* first scatter discriptor
+				used by this packet */
+	u32 num_sd;		/* number of scatter discriptors
+				used by this packet */
+	void *sa_va;		/* shadow sa, when using cp from ctx->sa */
+	u32 sa_pa;
+	void *sr_va;		/* state record for shadow sa */
+	u32 sr_pa;
+	struct scatterlist *dest_va;
+	struct crypto_async_request *async_req; 	/* base crypto request
+							for this packet */
+};
+
+struct crypto4xx_device {
+	struct crypto4xx_core_device *core_dev;
+	char *name;
+	u64  ce_phy_address;
+	void __iomem *ce_base;
+
+	void *pdr;			/* base address of packet
+					descriptor ring */
+	dma_addr_t pdr_pa;		/* physical address used to
+					program ce pdr_base_register */
+	void *gdr;                      /* gather descriptor ring */
+	dma_addr_t gdr_pa;		/* physical address used to
+					program ce gdr_base_register */
+	void *sdr;			/* scatter descriptor ring */
+	dma_addr_t sdr_pa;		/* physical address used to
+					program ce sdr_base_register */
+	void *scatter_buffer_va;
+	dma_addr_t scatter_buffer_pa;
+	u32 scatter_buffer_size;
+
+	void *shadow_sa_pool;		/* pool of memory for sa in pd_uinfo */
+	dma_addr_t shadow_sa_pool_pa;
+	void *shadow_sr_pool;		/* pool of memory for sr in pd_uinfo */
+	dma_addr_t shadow_sr_pool_pa;
+	u32 pdr_tail;
+	u32 pdr_head;
+	u32 gdr_tail;
+	u32 gdr_head;
+	u32 sdr_tail;
+	u32 sdr_head;
+	void *pdr_uinfo;
+	struct list_head alg_list;	/* List of algorithm supported
+					by this device */
+};
+
+struct crypto4xx_core_device {
+	struct device *device;
+	struct of_device *ofdev;
+	struct crypto4xx_device *dev;
+	u32 int_status;
+	u32 irq;
+	struct tasklet_struct tasklet;
+	spinlock_t lock;
+};
+
+struct crypto4xx_ctx {
+	struct crypto4xx_device *dev;
+	void *sa_in;
+	dma_addr_t sa_in_dma_addr;
+	void *sa_out;
+	dma_addr_t sa_out_dma_addr;
+	void *state_record;
+	dma_addr_t state_record_dma_addr;
+	u32 sa_len;
+	u32 offset_to_sr_ptr;           /* offset to state ptr, in dynamic sa */
+	u32 direction;
+	u32 next_hdr;
+	u32 save_iv;
+	u32 pd_ctl_len;
+	u32 pd_ctl;
+	u32 bypass;
+	u32 is_hash;
+	u32 hash_final;
+};
+
+struct crypto4xx_req_ctx {
+	struct crypto4xx_device *dev;	/* Device in which
+					operation to send to */
+	void *sa;
+	u32 sa_dma_addr;
+	u16 sa_len;
+};
+
+struct crypto4xx_alg {
+	struct list_head  entry;
+	struct crypto_alg alg;
+	struct crypto4xx_device *dev;
+};
+
+#define crypto_alg_to_crypto4xx_alg(x) \
+		container_of(x, struct crypto4xx_alg, alg)
+
+extern int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
+extern void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_sa_rctx(struct crypto4xx_ctx *ctx,
+				   struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_sa_rctx(struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx);
+extern void crypto4xx_memcpy_le(unsigned int *dst,
+				const unsigned char *buf, int len);
+extern u32 crypto4xx_build_pd(struct crypto_async_request *req,
+			      struct crypto4xx_ctx *ctx,
+			      struct scatterlist *src,
+			      struct scatterlist *dst,
+			      unsigned int datalen,
+			      void *iv, u32 iv_len);
+extern int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+				    const u8 *key, unsigned int keylen);
+extern int crypto4xx_encrypt(struct ablkcipher_request *req);
+extern int crypto4xx_decrypt(struct ablkcipher_request *req);
+extern int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
+extern int crypto4xx_hash_digest(struct ahash_request *req);
+extern int crypto4xx_hash_final(struct ahash_request *req);
+extern int crypto4xx_hash_update(struct ahash_request *req);
+extern int crypto4xx_hash_init(struct ahash_request *req);
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_reg_def.h linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_reg_def.h
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_reg_def.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_reg_def.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,284 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This filr defines the register set for Security Subsystem
+ */
+
+#ifndef __CRYPTO4XX_REG_DEF_H__
+#define __CRYPTO4XX_REG_DEF_H__
+
+/* CRYPTO4XX Register offset */
+#define CRYPTO4XX_DESCRIPTOR			0x00000000
+#define CRYPTO4XX_CTRL_STAT			0x00000000
+#define CRYPTO4XX_SOURCE			0x00000004
+#define CRYPTO4XX_DEST				0x00000008
+#define CRYPTO4XX_SA				0x0000000C
+#define CRYPTO4XX_SA_LENGTH			0x00000010
+#define CRYPTO4XX_LENGTH			0x00000014
+
+#define CRYPTO4XX_PE_DMA_CFG			0x00000040
+#define CRYPTO4XX_PE_DMA_STAT			0x00000044
+#define CRYPTO4XX_PDR_BASE			0x00000048
+#define CRYPTO4XX_RDR_BASE			0x0000004c
+#define CRYPTO4XX_RING_SIZE			0x00000050
+#define CRYPTO4XX_RING_CTRL			0x00000054
+#define CRYPTO4XX_INT_RING_STAT			0x00000058
+#define CRYPTO4XX_EXT_RING_STAT			0x0000005c
+#define CRYPTO4XX_IO_THRESHOLD			0x00000060
+#define CRYPTO4XX_GATH_RING_BASE		0x00000064
+#define CRYPTO4XX_SCAT_RING_BASE		0x00000068
+#define CRYPTO4XX_PART_RING_SIZE		0x0000006c
+#define CRYPTO4XX_PART_RING_CFG		        0x00000070
+
+#define CRYPTO4XX_PDR_BASE_UADDR		0x00000080
+#define CRYPTO4XX_RDR_BASE_UADDR		0x00000084
+#define CRYPTO4XX_PKT_SRC_UADDR			0x00000088
+#define CRYPTO4XX_PKT_DEST_UADDR		0x0000008c
+#define CRYPTO4XX_SA_UADDR			0x00000090
+#define CRYPTO4XX_GATH_RING_BASE_UADDR		0x000000A0
+#define CRYPTO4XX_SCAT_RING_BASE_UADDR		0x000000A4
+
+#define CRYPTO4XX_SEQ_RD			0x00000408
+#define CRYPTO4XX_SEQ_MASK_RD			0x0000040C
+
+#define CRYPTO4XX_SA_CMD_0			0x00010600
+#define CRYPTO4XX_SA_CMD_1			0x00010604
+
+#define CRYPTO4XX_STATE_PTR			0x000106dc
+#define CRYPTO4XX_STATE_IV			0x00010700
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_0		0x00010710
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_1		0x00010714
+
+#define CRYPTO4XX_STATE_IDIGEST_0		0x00010718
+#define CRYPTO4XX_STATE_IDIGEST_1		0x0001071c
+
+#define CRYPTO4XX_DATA_IN			0x00018000
+#define CRYPTO4XX_DATA_OUT			0x0001c000
+
+#define CRYPTO4XX_INT_UNMASK_STAT		0x000500a0
+#define CRYPTO4XX_INT_MASK_STAT			0x000500a4
+#define CRYPTO4XX_INT_CLR			0x000500a4
+#define CRYPTO4XX_INT_EN			0x000500a8
+
+#define CRYPTO4XX_INT_PKA			0x00000002
+#define CRYPTO4XX_INT_PDR_DONE			0x00008000
+#define CRYPTO4XX_INT_MA_WR_ERR			0x00020000
+#define CRYPTO4XX_INT_MA_RD_ERR			0x00010000
+#define CRYPTO4XX_INT_PE_ERR			0x00000200
+#define CRYPTO4XX_INT_USER_DMA_ERR		0x00000040
+#define CRYPTO4XX_INT_SLAVE_ERR			0x00000010
+#define CRYPTO4XX_INT_MASTER_ERR		0x00000008
+#define CRYPTO4XX_INT_ERROR			0x00030258
+
+#define CRYPTO4XX_INT_CFG			0x000500ac
+#define CRYPTO4XX_INT_DESCR_RD			0x000500b0
+#define CRYPTO4XX_INT_DESCR_CNT			0x000500b4
+#define CRYPTO4XX_INT_TIMEOUT_CNT		0x000500b8
+
+#define CRYPTO4XX_DEVICE_CTRL			0x00060080
+#define CRYPTO4XX_DEVICE_ID			0x00060084
+#define CRYPTO4XX_DEVICE_INFO			0x00060088
+#define CRYPTO4XX_DMA_USER_SRC			0x00060094
+#define CRYPTO4XX_DMA_USER_DEST			0x00060098
+#define CRYPTO4XX_DMA_USER_CMD			0x0006009C
+
+#define CRYPTO4XX_DMA_CFG	        	0x000600d4
+#define CRYPTO4XX_BYTE_ORDER_CFG 		0x000600d8
+#define CRYPTO4XX_ENDIAN_CFG			0x000600d8
+
+#define CRYPTO4XX_PRNG_STAT			0x00070000
+#define CRYPTO4XX_PRNG_CTRL			0x00070004
+#define CRYPTO4XX_PRNG_SEED_L			0x00070008
+#define CRYPTO4XX_PRNG_SEED_H			0x0007000c
+
+#define CRYPTO4XX_PRNG_RES_0			0x00070020
+#define CRYPTO4XX_PRNG_RES_1			0x00070024
+#define CRYPTO4XX_PRNG_RES_2			0x00070028
+#define CRYPTO4XX_PRNG_RES_3			0x0007002C
+
+#define CRYPTO4XX_PRNG_LFSR_L			0x00070030
+#define CRYPTO4XX_PRNG_LFSR_H			0x00070034
+
+/**
+ * Initilize CRYPTO ENGINE registers, and memory bases.
+ */
+#define PPC4XX_PDR_POLL				0x3ff
+#define PPC4XX_OUTPUT_THRESHOLD			2
+#define PPC4XX_INPUT_THRESHOLD			2
+#define PPC4XX_PD_SIZE				6
+#define PPC4XX_CTX_DONE_INT			0x2000
+#define PPC4XX_PD_DONE_INT			0x8000
+#define PPC4XX_BYTE_ORDER			0x22222
+#define PPC4XX_INTERRUPT_CLR			0x3ffff
+#define PPC4XX_PRNG_CTRL_AUTO_EN		0x3
+#define PPC4XX_DC_3DES_EN			1
+#define PPC4XX_INT_DESCR_CNT			4
+#define PPC4XX_INT_TIMEOUT_CNT			0
+#define PPC4XX_INT_CFG				1
+/**
+ * all follow define are ad hoc
+ */
+#define PPC4XX_RING_RETRY			100
+#define PPC4XX_RING_POLL			100
+#define PPC4XX_SDR_SIZE				PPC4XX_NUM_SD
+#define PPC4XX_GDR_SIZE				PPC4XX_NUM_GD
+
+/**
+  * Generic Security Association (SA) with all possible fields. These will
+ * never likely used except for reference purpose. These structure format
+ * can be not changed as the hardware expects them to be layout as defined.
+ * Field can be removed or reduced but ordering can not be changed.
+ */
+#define CRYPTO4XX_DMA_CFG_OFFSET		0x40
+union ce_pe_dma_cfg {
+	struct {
+		u32 rsv:7;
+		u32 dir_host:1;
+		u32 rsv1:2;
+		u32 bo_td_en:1;
+		u32 dis_pdr_upd:1;
+		u32 bo_sgpd_en:1;
+		u32 bo_data_en:1;
+		u32 bo_sa_en:1;
+		u32 bo_pd_en:1;
+		u32 rsv2:4;
+		u32 dynamic_sa_en:1;
+		u32 pdr_mode:2;
+		u32 pe_mode:1;
+		u32 rsv3:5;
+		u32 reset_sg:1;
+		u32 reset_pdr:1;
+		u32 reset_pe:1;
+	} bf;
+    u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_PDR_BASE_OFFSET		0x48
+#define CRYPTO4XX_RDR_BASE_OFFSET		0x4c
+#define CRYPTO4XX_RING_SIZE_OFFSET		0x50
+union ce_ring_size {
+	struct {
+		u32 ring_offset:16;
+		u32 rsv:6;
+		u32 ring_size:10;
+	} bf;
+    u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_RING_CONTROL_OFFSET		0x54
+union ce_ring_contol {
+	struct {
+		u32 continuous:1;
+		u32 rsv:5;
+		u32 ring_retry_divisor:10;
+		u32 rsv1:4;
+		u32 ring_poll_divisor:10;
+	} bf;
+    u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_IO_THRESHOLD_OFFSET		0x60
+union ce_io_threshold {
+	struct {
+		u32 rsv:6;
+		u32 output_threshold:10;
+		u32 rsv1:6;
+		u32 input_threshold:10;
+	} bf;
+    u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_GATHER_RING_BASE_OFFSET	0x64
+#define CRYPTO4XX_SCATTER_RING_BASE_OFFSET	0x68
+
+union ce_part_ring_size  {
+	struct {
+		u32 sdr_size:16;
+		u32 gdr_size:16;
+	} bf;
+    u32 w;
+} __attribute__((packed));
+
+#define MAX_BURST_SIZE_32			0
+#define MAX_BURST_SIZE_64			1
+#define MAX_BURST_SIZE_128			2
+#define MAX_BURST_SIZE_256			3
+
+/* gather descriptor control length */
+struct gd_ctl_len {
+	u32 len:16;
+	u32 rsv:14;
+	u32 done:1;
+	u32 ready:1;
+} __attribute__((packed));
+
+struct ce_gd {
+	u32 ptr;
+	struct gd_ctl_len ctl_len;
+} __attribute__((packed));
+
+struct sd_ctl {
+	u32 ctl:30;
+	u32 done:1;
+	u32 rdy:1;
+} __attribute__((packed));
+
+struct ce_sd {
+    u32 ptr;
+	struct sd_ctl ctl;
+} __attribute__((packed));
+
+#define PD_PAD_CTL_32	0x10
+#define PD_PAD_CTL_64	0x20
+#define PD_PAD_CTL_128	0x40
+#define PD_PAD_CTL_256	0x80
+union ce_pd_ctl {
+	struct {
+		u32 pd_pad_ctl:8;
+		u32 status:8;
+		u32 next_hdr:8;
+		u32 rsv:2;
+		u32 cached_sa:1;
+		u32 hash_final:1;
+		u32 init_arc4:1;
+		u32 rsv1:1;
+		u32 pe_done:1;
+		u32 host_ready:1;
+	} bf;
+	u32 w;
+} __attribute__((packed));
+
+union ce_pd_ctl_len {
+	struct {
+		u32 bypass:8;
+		u32 pe_done:1;
+		u32 host_ready:1;
+		u32 rsv:2;
+		u32 pkt_len:20;
+	} bf;
+	u32 w;
+} __attribute__((packed));
+
+struct ce_pd {
+	union ce_pd_ctl   pd_ctl;
+	u32 src;
+	u32 dest;
+	u32 sa;                 /* get from ctx->sa_dma_addr */
+	u32 sa_len;             /* only if dynamic sa is used */
+	union ce_pd_ctl_len pd_ctl_len;
+
+} __attribute__((packed));
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_sa.c linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_sa.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_sa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_sa.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,108 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * @file crypto4xx_sa.c
+ *
+ * This file implements the security context
+ * assoicate format.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mod_devicetable.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <crypto/des.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+u32 get_dynamic_sa_offset_iv_field(struct crypto4xx_ctx *ctx)
+{
+	u32 offset;
+	union dynamic_sa_contents cts;
+
+	if (ctx->direction == DIR_INBOUND)
+		cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_in))->sa_contents;
+	else
+		cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_out))->sa_contents;
+	offset = cts.bf.key_size
+		+ cts.bf.inner_size
+		+ cts.bf.outer_size
+		+ cts.bf.spi
+		+ cts.bf.seq_num0
+		+ cts.bf.seq_num1
+		+ cts.bf.seq_num_mask0
+		+ cts.bf.seq_num_mask1
+		+ cts.bf.seq_num_mask2
+		+ cts.bf.seq_num_mask3;
+
+	return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx)
+{
+	u32 offset;
+	union dynamic_sa_contents cts;
+
+	if (ctx->direction == DIR_INBOUND)
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+	else
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+	offset = cts.bf.key_size
+		+ cts.bf.inner_size
+		+ cts.bf.outer_size
+		+ cts.bf.spi
+		+ cts.bf.seq_num0
+		+ cts.bf.seq_num1
+		+ cts.bf.seq_num_mask0
+		+ cts.bf.seq_num_mask1
+		+ cts.bf.seq_num_mask2
+		+ cts.bf.seq_num_mask3
+		+ cts.bf.iv0
+		+ cts.bf.iv1
+		+ cts.bf.iv2
+		+ cts.bf.iv3;
+
+	return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx)
+{
+	union dynamic_sa_contents cts;
+
+	if (ctx->direction == DIR_INBOUND)
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+	else
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+	return (cts.bf.iv0 + cts.bf.iv1 + cts.bf.iv2 + cts.bf.iv3) * 4;
+}
+
+u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx)
+{
+	union dynamic_sa_contents cts;
+
+	if (ctx->direction == DIR_INBOUND)
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+	else
+		cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+
+	return sizeof(struct dynamic_sa_ctl);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_sa.h linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_sa.h
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/crypto4xx_sa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/crypto4xx_sa.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,243 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.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.
+ *
+ * This file defines the security context
+ * assoicate format.
+ */
+
+#ifndef __CRYPTO4XX_SA_H__
+#define __CRYPTO4XX_SA_H__
+
+#define AES_IV_SIZE				16
+
+/**
+ * Contents of Dynamic Security Association (SA) with all possible fields
+ */
+union dynamic_sa_contents {
+	struct {
+		u32 arc4_state_ptr:1;
+		u32 arc4_ij_ptr:1;
+		u32 state_ptr:1;
+		u32 iv3:1;
+		u32 iv2:1;
+		u32 iv1:1;
+		u32 iv0:1;
+		u32 seq_num_mask3:1;
+		u32 seq_num_mask2:1;
+		u32 seq_num_mask1:1;
+		u32 seq_num_mask0:1;
+		u32 seq_num1:1;
+		u32 seq_num0:1;
+		u32 spi:1;
+		u32 outer_size:5;
+		u32 inner_size:5;
+		u32 key_size:4;
+		u32 cmd_size:4;
+	} bf;
+	u32 w;
+} __attribute__((packed));
+
+#define DIR_OUTBOUND				0
+#define DIR_INBOUND				1
+#define SA_OP_GROUP_BASIC			0
+#define SA_OPCODE_ENCRYPT			0
+#define SA_OPCODE_DECRYPT			0
+#define SA_OPCODE_HASH				3
+#define SA_CIPHER_ALG_DES			0
+#define SA_CIPHER_ALG_3DES			1
+#define SA_CIPHER_ALG_ARC4			2
+#define SA_CIPHER_ALG_AES			3
+#define SA_CIPHER_ALG_KASUMI			4
+#define SA_CIPHER_ALG_NULL			15
+
+#define SA_HASH_ALG_MD5				0
+#define SA_HASH_ALG_SHA1			1
+#define SA_HASH_ALG_NULL			15
+#define SA_HASH_ALG_SHA1_DIGEST_SIZE		20
+
+#define SA_LOAD_HASH_FROM_SA			0
+#define SA_LOAD_HASH_FROM_STATE			2
+#define SA_NOT_LOAD_HASH			3
+#define SA_LOAD_IV_FROM_SA			0
+#define SA_LOAD_IV_FROM_INPUT			1
+#define SA_LOAD_IV_FROM_STATE			2
+#define SA_LOAD_IV_GEN_IV			3
+
+#define SA_PAD_TYPE_CONSTANT			2
+#define SA_PAD_TYPE_ZERO			3
+#define SA_PAD_TYPE_TLS				5
+#define SA_PAD_TYPE_DTLS			5
+#define SA_NOT_SAVE_HASH			0
+#define SA_SAVE_HASH				1
+#define SA_NOT_SAVE_IV				0
+#define SA_SAVE_IV				1
+#define SA_HEADER_PROC				1
+#define SA_NO_HEADER_PROC			0
+
+union sa_command_0 {
+	struct {
+		u32 scatter:1;
+		u32 gather:1;
+		u32 save_hash_state:1;
+		u32 save_iv:1;
+		u32 load_hash_state:2;
+		u32 load_iv:2;
+		u32 digest_len:4;
+		u32 hdr_proc:1;
+		u32 extend_pad:1;
+		u32 stream_cipher_pad:1;
+		u32 rsv:1;
+		u32 hash_alg:4;
+		u32 cipher_alg:4;
+		u32 pad_type:2;
+		u32 op_group:2;
+		u32 dir:1;
+		u32 opcode:3;
+	} bf;
+	u32 w;
+} __attribute__((packed));
+
+#define CRYPTO_MODE_ECB				0
+#define CRYPTO_MODE_CBC				1
+
+#define CRYPTO_FEEDBACK_MODE_NO_FB		0
+#define CRYPTO_FEEDBACK_MODE_64BIT_OFB		0
+#define CRYPTO_FEEDBACK_MODE_8BIT_CFB		1
+#define CRYPTO_FEEDBACK_MODE_1BIT_CFB		2
+#define CRYPTO_FEEDBACK_MODE_128BIT_CFB		3
+
+#define SA_AES_KEY_LEN_128			2
+#define SA_AES_KEY_LEN_192			3
+#define SA_AES_KEY_LEN_256			4
+
+#define SA_REV2					1
+/**
+ * The follow defines bits sa_command_1
+ * In Basic hash mode  this bit define simple hash or hmac.
+ * In IPsec mode, this bit define muting control.
+ */
+#define SA_HASH_MODE_HASH			0
+#define SA_HASH_MODE_HMAC			1
+#define SA_MC_ENABLE				0
+#define SA_MC_DISABLE				1
+#define SA_NOT_COPY_HDR				0
+#define SA_COPY_HDR				1
+#define SA_NOT_COPY_PAD				0
+#define SA_COPY_PAD				1
+#define SA_NOT_COPY_PAYLOAD			0
+#define SA_COPY_PAYLOAD				1
+#define SA_EXTENDED_SN_OFF			0
+#define SA_EXTENDED_SN_ON			1
+#define SA_SEQ_MASK_OFF				0
+#define SA_SEQ_MASK_ON				1
+
+union sa_command_1 {
+	struct {
+		u32 crypto_mode31:1;
+		u32 save_arc4_state:1;
+		u32 arc4_stateful:1;
+		u32 key_len:5;
+		u32 hash_crypto_offset:8;
+		u32 sa_rev:2;
+		u32 byte_offset:1;
+		u32 hmac_muting:1;
+		u32 feedback_mode:2;
+		u32 crypto_mode9_8:2;
+		u32 extended_seq_num:1;
+		u32 seq_num_mask:1;
+		u32 mutable_bit_proc:1;
+		u32 ip_version:1;
+		u32 copy_pad:1;
+		u32 copy_payload:1;
+		u32 copy_hdr:1;
+		u32 rsv1:1;
+	} bf;
+	u32 w;
+} __attribute__((packed));
+
+struct dynamic_sa_ctl {
+	u32 sa_contents;
+	union sa_command_0 sa_command_0;
+	union sa_command_1 sa_command_1;
+} __attribute__((packed));
+
+/**
+ * State Record for Security Association (SA)
+ */
+struct  sa_state_record {
+	u32 save_iv[4];
+	u32 save_hash_byte_cnt[2];
+	u32 save_digest[16];
+} __attribute__((packed));
+
+/**
+ * Security Association (SA) for AES128
+ *
+ */
+struct dynamic_sa_aes128 {
+	struct dynamic_sa_ctl	ctrl;
+	u32 key[4];
+	u32 iv[4]; /* for CBC, OFC, and CFB mode */
+	u32 state_ptr;
+	u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES128_LEN		(sizeof(struct dynamic_sa_aes128)/4)
+#define SA_AES128_CONTENTS	0x3e000042
+
+/*
+ * Security Association (SA) for AES192
+ */
+struct dynamic_sa_aes192 {
+	struct dynamic_sa_ctl ctrl;
+	u32 key[6];
+	u32 iv[4]; /* for CBC, OFC, and CFB mode */
+	u32 state_ptr;
+	u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES192_LEN		(sizeof(struct dynamic_sa_aes192)/4)
+#define SA_AES192_CONTENTS	0x3e000062
+
+/**
+ * Security Association (SA) for AES256
+ */
+struct dynamic_sa_aes256 {
+	struct dynamic_sa_ctl ctrl;
+	u32 key[8];
+	u32 iv[4]; /* for CBC, OFC, and CFB mode */
+	u32 state_ptr;
+	u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES256_LEN		(sizeof(struct dynamic_sa_aes256)/4)
+#define SA_AES256_CONTENTS	0x3e000082
+#define SA_AES_CONTENTS		0x3e000002
+
+/**
+ * Security Association (SA) for HASH160: HMAC-SHA1
+ */
+struct dynamic_sa_hash160 {
+	struct dynamic_sa_ctl ctrl;
+	u32 inner_digest[5];
+	u32 outer_digest[5];
+	u32 state_ptr;
+	u32 reserved;
+} __attribute__((packed));
+#define SA_HASH160_LEN		(sizeof(struct dynamic_sa_hash160)/4)
+#define SA_HASH160_CONTENTS     0x2000a502
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/amcc/Makefile linux-libre-2.6.30-gnu1/drivers/crypto/amcc/Makefile
--- linux-libre-2.6.29-gnu1/drivers/crypto/amcc/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/crypto/amcc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
+crypto4xx-objs :=  crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/hifn_795x.c linux-libre-2.6.30-gnu1/drivers/crypto/hifn_795x.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/hifn_795x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/crypto/hifn_795x.c	2009-06-09 23:05:27.000000000 -0400
@@ -1882,7 +1882,7 @@ static void hifn_clear_rings(struct hifn
 
 static void hifn_work(struct work_struct *work)
 {
-	struct delayed_work *dw = container_of(work, struct delayed_work, work);
+	struct delayed_work *dw = to_delayed_work(work);
 	struct hifn_device *dev = container_of(dw, struct hifn_device, work);
 	unsigned long flags;
 	int reset = 0;
@@ -2575,7 +2575,7 @@ static int hifn_probe(struct pci_dev *pd
 		return err;
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err)
 		goto err_out_disable_pci_device;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/ixp4xx_crypto.c linux-libre-2.6.30-gnu1/drivers/crypto/ixp4xx_crypto.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/ixp4xx_crypto.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/crypto/ixp4xx_crypto.c	2009-06-09 23:05:27.000000000 -0400
@@ -101,6 +101,7 @@ struct buffer_desc {
 	u32 phys_addr;
 	u32 __reserved[4];
 	struct buffer_desc *next;
+	enum dma_data_direction dir;
 };
 
 struct crypt_ctl {
@@ -132,14 +133,10 @@ struct crypt_ctl {
 struct ablk_ctx {
 	struct buffer_desc *src;
 	struct buffer_desc *dst;
-	unsigned src_nents;
-	unsigned dst_nents;
 };
 
 struct aead_ctx {
 	struct buffer_desc *buffer;
-	unsigned short assoc_nents;
-	unsigned short src_nents;
 	struct scatterlist ivlist;
 	/* used when the hmac is not on one sg entry */
 	u8 *hmac_virt;
@@ -212,7 +209,7 @@ static struct platform_device pseudo_dev
 	.id   = 0,
 	.num_resources = 0,
 	.dev  = {
-		.coherent_dma_mask = DMA_32BIT_MASK,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 		.release = dev_release,
 	}
 };
@@ -312,7 +309,7 @@ static struct crypt_ctl *get_crypt_desc_
 	}
 }
 
-static void free_buf_chain(struct buffer_desc *buf, u32 phys)
+static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys)
 {
 	while (buf) {
 		struct buffer_desc *buf1;
@@ -320,6 +317,7 @@ static void free_buf_chain(struct buffer
 
 		buf1 = buf->next;
 		phys1 = buf->phys_next;
+		dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
 		dma_pool_free(buffer_pool, buf, phys);
 		buf = buf1;
 		phys = phys1;
@@ -348,7 +346,6 @@ static void one_packet(dma_addr_t phys)
 	struct crypt_ctl *crypt;
 	struct ixp_ctx *ctx;
 	int failed;
-	enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
 
 	failed = phys & 0x1 ? -EBADMSG : 0;
 	phys &= ~0x3;
@@ -358,13 +355,8 @@ static void one_packet(dma_addr_t phys)
 	case CTL_FLAG_PERFORM_AEAD: {
 		struct aead_request *req = crypt->data.aead_req;
 		struct aead_ctx *req_ctx = aead_request_ctx(req);
-		dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents,
-				DMA_TO_DEVICE);
-		dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-		dma_unmap_sg(dev, req->src, req_ctx->src_nents,
-				DMA_BIDIRECTIONAL);
 
-		free_buf_chain(req_ctx->buffer, crypt->src_buf);
+		free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
 		if (req_ctx->hmac_virt) {
 			finish_scattered_hmac(crypt);
 		}
@@ -374,16 +366,11 @@ static void one_packet(dma_addr_t phys)
 	case CTL_FLAG_PERFORM_ABLK: {
 		struct ablkcipher_request *req = crypt->data.ablk_req;
 		struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
-		int nents;
+
 		if (req_ctx->dst) {
-			nents = req_ctx->dst_nents;
-			dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
-			free_buf_chain(req_ctx->dst, crypt->dst_buf);
-			src_direction = DMA_TO_DEVICE;
+			free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
 		}
-		nents = req_ctx->src_nents;
-		dma_unmap_sg(dev, req->src, nents, src_direction);
-		free_buf_chain(req_ctx->src, crypt->src_buf);
+		free_buf_chain(dev, req_ctx->src, crypt->src_buf);
 		req->base.complete(&req->base, failed);
 		break;
 	}
@@ -428,6 +415,7 @@ static void crypto_done_action(unsigned
 static int init_ixp_crypto(void)
 {
 	int ret = -ENODEV;
+	u32 msg[2] = { 0, 0 };
 
 	if (! ( ~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
 				IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
@@ -439,9 +427,35 @@ static int init_ixp_crypto(void)
 		return ret;
 
 	if (!npe_running(npe_c)) {
-		npe_load_firmware(npe_c, npe_name(npe_c), dev);
+		ret = npe_load_firmware(npe_c, npe_name(npe_c), dev);
+		if (ret) {
+			return ret;
+		}
+		if (npe_recv_message(npe_c, msg, "STATUS_MSG"))
+			goto npe_error;
+	} else {
+		if (npe_send_message(npe_c, msg, "STATUS_MSG"))
+			goto npe_error;
+
+		if (npe_recv_message(npe_c, msg, "STATUS_MSG"))
+			goto npe_error;
 	}
 
+	switch ((msg[1]>>16) & 0xff) {
+	case 3:
+		printk(KERN_WARNING "Firmware of %s lacks AES support\n",
+				npe_name(npe_c));
+		support_aes = 0;
+		break;
+	case 4:
+	case 5:
+		support_aes = 1;
+		break;
+	default:
+		printk(KERN_ERR "Firmware of %s lacks crypto support\n",
+			npe_name(npe_c));
+		return -ENODEV;
+	}
 	/* buffer_pool will also be used to sometimes store the hmac,
 	 * so assure it is large enough
 	 */
@@ -472,6 +486,10 @@ static int init_ixp_crypto(void)
 
 	qmgr_enable_irq(RECV_QID);
 	return 0;
+
+npe_error:
+	printk(KERN_ERR "%s not responding\n", npe_name(npe_c));
+	ret = -EIO;
 err:
 	if (ctx_pool)
 		dma_pool_destroy(ctx_pool);
@@ -750,56 +768,35 @@ static int setup_cipher(struct crypto_tf
 	return 0;
 }
 
-static int count_sg(struct scatterlist *sg, int nbytes)
-{
-	int i;
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
-		nbytes -= sg->length;
-	return i;
-}
-
-static struct buffer_desc *chainup_buffers(struct scatterlist *sg,
-			unsigned nbytes, struct buffer_desc *buf, gfp_t flags)
+static struct buffer_desc *chainup_buffers(struct device *dev,
+		struct scatterlist *sg,	unsigned nbytes,
+		struct buffer_desc *buf, gfp_t flags,
+		enum dma_data_direction dir)
 {
-	int nents = 0;
-
-	while (nbytes > 0) {
+	for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) {
+		unsigned len = min(nbytes, sg->length);
 		struct buffer_desc *next_buf;
 		u32 next_buf_phys;
-		unsigned len = min(nbytes, sg_dma_len(sg));
+		void *ptr;
 
-		nents++;
 		nbytes -= len;
-		if (!buf->phys_addr) {
-			buf->phys_addr = sg_dma_address(sg);
-			buf->buf_len = len;
-			buf->next = NULL;
-			buf->phys_next = 0;
-			goto next;
-		}
-		/* Two consecutive chunks on one page may be handled by the old
-		 * buffer descriptor, increased by the length of the new one
-		 */
-		if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) {
-			buf->buf_len += len;
-			goto next;
-		}
+		ptr = page_address(sg_page(sg)) + sg->offset;
 		next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
-		if (!next_buf)
-			return NULL;
+		if (!next_buf) {
+			buf = NULL;
+			break;
+		}
+		sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
 		buf->next = next_buf;
 		buf->phys_next = next_buf_phys;
-
 		buf = next_buf;
-		buf->next = NULL;
-		buf->phys_next = 0;
+
 		buf->phys_addr = sg_dma_address(sg);
 		buf->buf_len = len;
-next:
-		if (nbytes > 0) {
-			sg = sg_next(sg);
-		}
+		buf->dir = dir;
 	}
+	buf->next = NULL;
+	buf->phys_next = 0;
 	return buf;
 }
 
@@ -860,12 +857,12 @@ static int ablk_perform(struct ablkciphe
 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
 	struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 	unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
-	int ret = -ENOMEM;
 	struct ix_sa_dir *dir;
 	struct crypt_ctl *crypt;
-	unsigned int nbytes = req->nbytes, nents;
+	unsigned int nbytes = req->nbytes;
 	enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
 	struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
+	struct buffer_desc src_hook;
 	gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
 				GFP_KERNEL : GFP_ATOMIC;
 
@@ -878,7 +875,7 @@ static int ablk_perform(struct ablkciphe
 
 	crypt = get_crypt_desc();
 	if (!crypt)
-		return ret;
+		return -ENOMEM;
 
 	crypt->data.ablk_req = req;
 	crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -891,53 +888,41 @@ static int ablk_perform(struct ablkciphe
 	BUG_ON(ivsize && !req->info);
 	memcpy(crypt->iv, req->info, ivsize);
 	if (req->src != req->dst) {
+		struct buffer_desc dst_hook;
 		crypt->mode |= NPE_OP_NOT_IN_PLACE;
-		nents = count_sg(req->dst, nbytes);
 		/* This was never tested by Intel
 		 * for more than one dst buffer, I think. */
-		BUG_ON(nents != 1);
-		req_ctx->dst_nents = nents;
-		dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
-		req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf);
-		if (!req_ctx->dst)
-			goto unmap_sg_dest;
-		req_ctx->dst->phys_addr = 0;
-		if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags))
+		BUG_ON(req->dst->length < nbytes);
+		req_ctx->dst = NULL;
+		if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+					flags, DMA_FROM_DEVICE))
 			goto free_buf_dest;
 		src_direction = DMA_TO_DEVICE;
+		req_ctx->dst = dst_hook.next;
+		crypt->dst_buf = dst_hook.phys_next;
 	} else {
 		req_ctx->dst = NULL;
-		req_ctx->dst_nents = 0;
 	}
-	nents = count_sg(req->src, nbytes);
-	req_ctx->src_nents = nents;
-	dma_map_sg(dev, req->src, nents, src_direction);
-
-	req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
-	if (!req_ctx->src)
-		goto unmap_sg_src;
-	req_ctx->src->phys_addr = 0;
-	if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags))
+	req_ctx->src = NULL;
+	if (!chainup_buffers(dev, req->src, nbytes, &src_hook,
+				flags, src_direction))
 		goto free_buf_src;
 
+	req_ctx->src = src_hook.next;
+	crypt->src_buf = src_hook.phys_next;
 	crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
 	qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
 	BUG_ON(qmgr_stat_overflow(SEND_QID));
 	return -EINPROGRESS;
 
 free_buf_src:
-	free_buf_chain(req_ctx->src, crypt->src_buf);
-unmap_sg_src:
-	dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction);
+	free_buf_chain(dev, req_ctx->src, crypt->src_buf);
 free_buf_dest:
 	if (req->src != req->dst) {
-		free_buf_chain(req_ctx->dst, crypt->dst_buf);
-unmap_sg_dest:
-		dma_unmap_sg(dev, req->src, req_ctx->dst_nents,
-			DMA_FROM_DEVICE);
+		free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
 	}
 	crypt->ctl_flags = CTL_FLAG_UNUSED;
-	return ret;
+	return -ENOMEM;
 }
 
 static int ablk_encrypt(struct ablkcipher_request *req)
@@ -985,7 +970,7 @@ static int hmac_inconsistent(struct scat
 			break;
 
 		offset += sg->length;
-		sg = sg_next(sg);
+		sg = scatterwalk_sg_next(sg);
 	}
 	return (start + nbytes > offset + sg->length);
 }
@@ -997,11 +982,10 @@ static int aead_perform(struct aead_requ
 	struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
 	unsigned ivsize = crypto_aead_ivsize(tfm);
 	unsigned authsize = crypto_aead_authsize(tfm);
-	int ret = -ENOMEM;
 	struct ix_sa_dir *dir;
 	struct crypt_ctl *crypt;
-	unsigned int cryptlen, nents;
-	struct buffer_desc *buf;
+	unsigned int cryptlen;
+	struct buffer_desc *buf, src_hook;
 	struct aead_ctx *req_ctx = aead_request_ctx(req);
 	gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
 				GFP_KERNEL : GFP_ATOMIC;
@@ -1022,7 +1006,7 @@ static int aead_perform(struct aead_requ
 	}
 	crypt = get_crypt_desc();
 	if (!crypt)
-		return ret;
+		return -ENOMEM;
 
 	crypt->data.aead_req = req;
 	crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -1041,31 +1025,27 @@ static int aead_perform(struct aead_requ
 		BUG(); /* -ENOTSUP because of my lazyness */
 	}
 
-	req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
-	if (!req_ctx->buffer)
-		goto out;
-	req_ctx->buffer->phys_addr = 0;
 	/* ASSOC data */
-	nents = count_sg(req->assoc, req->assoclen);
-	req_ctx->assoc_nents = nents;
-	dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE);
-	buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags);
+	buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook,
+		flags, DMA_TO_DEVICE);
+	req_ctx->buffer = src_hook.next;
+	crypt->src_buf = src_hook.phys_next;
 	if (!buf)
-		goto unmap_sg_assoc;
+		goto out;
 	/* IV */
 	sg_init_table(&req_ctx->ivlist, 1);
 	sg_set_buf(&req_ctx->ivlist, iv, ivsize);
-	dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-	buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags);
+	buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags,
+			DMA_BIDIRECTIONAL);
 	if (!buf)
-		goto unmap_sg_iv;
+		goto free_chain;
 	if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) {
 		/* The 12 hmac bytes are scattered,
 		 * we need to copy them into a safe buffer */
 		req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
 				&crypt->icv_rev_aes);
 		if (unlikely(!req_ctx->hmac_virt))
-			goto unmap_sg_iv;
+			goto free_chain;
 		if (!encrypt) {
 			scatterwalk_map_and_copy(req_ctx->hmac_virt,
 				req->src, cryptlen, authsize, 0);
@@ -1075,33 +1055,28 @@ static int aead_perform(struct aead_requ
 		req_ctx->hmac_virt = NULL;
 	}
 	/* Crypt */
-	nents = count_sg(req->src, cryptlen + authsize);
-	req_ctx->src_nents = nents;
-	dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL);
-	buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags);
+	buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags,
+			DMA_BIDIRECTIONAL);
 	if (!buf)
-		goto unmap_sg_src;
+		goto free_hmac_virt;
 	if (!req_ctx->hmac_virt) {
 		crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize;
 	}
+
 	crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD;
 	qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
 	BUG_ON(qmgr_stat_overflow(SEND_QID));
 	return -EINPROGRESS;
-unmap_sg_src:
-	dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL);
+free_hmac_virt:
 	if (req_ctx->hmac_virt) {
 		dma_pool_free(buffer_pool, req_ctx->hmac_virt,
 				crypt->icv_rev_aes);
 	}
-unmap_sg_iv:
-	dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-unmap_sg_assoc:
-	dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE);
-	free_buf_chain(req_ctx->buffer, crypt->src_buf);
+free_chain:
+	free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
 out:
 	crypt->ctl_flags = CTL_FLAG_UNUSED;
-	return ret;
+	return -ENOMEM;
 }
 
 static int aead_setup(struct crypto_aead *tfm, unsigned int authsize)
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/Kconfig linux-libre-2.6.30-gnu1/drivers/crypto/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/crypto/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/crypto/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -86,7 +86,7 @@ config ZCRYPT_MONOLITHIC
 config CRYPTO_SHA1_S390
 	tristate "SHA1 digest algorithm"
 	depends on S390
-	select CRYPTO_ALGAPI
+	select CRYPTO_HASH
 	help
 	  This is the s390 hardware accelerated implementation of the
 	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
@@ -94,7 +94,7 @@ config CRYPTO_SHA1_S390
 config CRYPTO_SHA256_S390
 	tristate "SHA256 digest algorithm"
 	depends on S390
-	select CRYPTO_ALGAPI
+	select CRYPTO_HASH
 	help
 	  This is the s390 hardware accelerated implementation of the
 	  SHA256 secure hash standard (DFIPS 180-2).
@@ -105,7 +105,7 @@ config CRYPTO_SHA256_S390
 config CRYPTO_SHA512_S390
 	tristate "SHA384 and SHA512 digest algorithm"
 	depends on S390
-	select CRYPTO_ALGAPI
+	select CRYPTO_HASH
 	help
 	  This is the s390 hardware accelerated implementation of the
 	  SHA512 secure hash standard.
@@ -200,4 +200,13 @@ config CRYPTO_DEV_IXP4XX
 	help
 	  Driver for the IXP4xx NPE crypto engine.
 
+config CRYPTO_DEV_PPC4XX
+	tristate "Driver AMCC PPC4xx crypto accelerator"
+	depends on PPC && 4xx
+	select CRYPTO_HASH
+	select CRYPTO_ALGAPI
+	select CRYPTO_BLKCIPHER
+	help
+	  This option allows you to have support for AMCC crypto acceleration.
+
 endif # CRYPTO_HW
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/Makefile linux-libre-2.6.30-gnu1/drivers/crypto/Makefile
--- linux-libre-2.6.29-gnu1/drivers/crypto/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/crypto/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,3 +4,4 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-
 obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
diff -druNp linux-libre-2.6.29-gnu1/drivers/crypto/padlock-aes.c linux-libre-2.6.30-gnu1/drivers/crypto/padlock-aes.c
--- linux-libre-2.6.29-gnu1/drivers/crypto/padlock-aes.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/crypto/padlock-aes.c	2009-06-09 23:05:27.000000000 -0400
@@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algo
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michal Ludvig");
 
-MODULE_ALIAS("aes-all");
+MODULE_ALIAS("aes");
diff -druNp linux-libre-2.6.29-gnu1/drivers/dio/dio.c linux-libre-2.6.30-gnu1/drivers/dio/dio.c
--- linux-libre-2.6.29-gnu1/drivers/dio/dio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dio/dio.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,7 @@ static int __init dio_init(void)
 
 	/* Initialize the DIO bus */ 
 	INIT_LIST_HEAD(&dio_bus.devices);
-	strcpy(dio_bus.dev.bus_id, "dio");
+	dev_set_name(&dio_bus.dev, "dio");
 	error = device_register(&dio_bus.dev);
 	if (error) {
 		pr_err("DIO: Error registering dio_bus\n");
@@ -237,7 +237,7 @@ static int __init dio_init(void)
 		dev->scode = scode;
 		dev->resource.start = pa;
 		dev->resource.end = pa + DIO_SIZE(scode, va);
-		sprintf(dev->dev.bus_id,"%02x", scode);
+		dev_set_name(&dev->dev, "%02x", scode);
 
                 /* read the ID byte(s) and encode if necessary. */
 		prid = DIO_ID(va);
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/dmaengine.c linux-libre-2.6.30-gnu1/drivers/dma/dmaengine.c
--- linux-libre-2.6.29-gnu1/drivers/dma/dmaengine.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/dmaengine.c	2009-06-09 23:05:27.000000000 -0400
@@ -507,6 +507,7 @@ struct dma_chan *__dma_request_channel(d
 			 * published in the general-purpose allocator
 			 */
 			dma_cap_set(DMA_PRIVATE, device->cap_mask);
+			device->privatecnt++;
 			err = dma_chan_get(chan);
 
 			if (err == -ENODEV) {
@@ -518,6 +519,8 @@ struct dma_chan *__dma_request_channel(d
 				       dma_chan_name(chan), err);
 			else
 				break;
+			if (--device->privatecnt == 0)
+				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
 			chan->private = NULL;
 			chan = NULL;
 		}
@@ -537,6 +540,9 @@ void dma_release_channel(struct dma_chan
 	WARN_ONCE(chan->client_count != 1,
 		  "chan reference count %d != 1\n", chan->client_count);
 	dma_chan_put(chan);
+	/* drop PRIVATE cap enabled by __dma_request_channel() */
+	if (--chan->device->privatecnt == 0)
+		dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
 	chan->private = NULL;
 	mutex_unlock(&dma_list_mutex);
 }
@@ -602,6 +608,24 @@ void dmaengine_put(void)
 }
 EXPORT_SYMBOL(dmaengine_put);
 
+static int get_dma_id(struct dma_device *device)
+{
+	int rc;
+
+ idr_retry:
+	if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+		return -ENOMEM;
+	mutex_lock(&dma_list_mutex);
+	rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
+	mutex_unlock(&dma_list_mutex);
+	if (rc == -EAGAIN)
+		goto idr_retry;
+	else if (rc != 0)
+		return rc;
+
+	return 0;
+}
+
 /**
  * dma_async_device_register - registers DMA devices found
  * @device: &dma_device
@@ -640,27 +664,25 @@ int dma_async_device_register(struct dma
 	idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL);
 	if (!idr_ref)
 		return -ENOMEM;
-	atomic_set(idr_ref, 0);
- idr_retry:
-	if (!idr_pre_get(&dma_idr, GFP_KERNEL))
-		return -ENOMEM;
-	mutex_lock(&dma_list_mutex);
-	rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
-	mutex_unlock(&dma_list_mutex);
-	if (rc == -EAGAIN)
-		goto idr_retry;
-	else if (rc != 0)
+	rc = get_dma_id(device);
+	if (rc != 0) {
+		kfree(idr_ref);
 		return rc;
+	}
+
+	atomic_set(idr_ref, 0);
 
 	/* represent channels in sysfs. Probably want devs too */
 	list_for_each_entry(chan, &device->channels, device_node) {
+		rc = -ENOMEM;
 		chan->local = alloc_percpu(typeof(*chan->local));
 		if (chan->local == NULL)
-			continue;
+			goto err_out;
 		chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
 		if (chan->dev == NULL) {
 			free_percpu(chan->local);
-			continue;
+			chan->local = NULL;
+			goto err_out;
 		}
 
 		chan->chan_id = chancnt++;
@@ -677,6 +699,8 @@ int dma_async_device_register(struct dma
 		if (rc) {
 			free_percpu(chan->local);
 			chan->local = NULL;
+			kfree(chan->dev);
+			atomic_dec(idr_ref);
 			goto err_out;
 		}
 		chan->client_count = 0;
@@ -701,12 +725,23 @@ int dma_async_device_register(struct dma
 			}
 		}
 	list_add_tail_rcu(&device->global_node, &dma_device_list);
+	if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
+		device->privatecnt++;	/* Always private */
 	dma_channel_rebalance();
 	mutex_unlock(&dma_list_mutex);
 
 	return 0;
 
 err_out:
+	/* if we never registered a channel just release the idr */
+	if (atomic_read(idr_ref) == 0) {
+		mutex_lock(&dma_list_mutex);
+		idr_remove(&dma_idr, device->dev_id);
+		mutex_unlock(&dma_list_mutex);
+		kfree(idr_ref);
+		return rc;
+	}
+
 	list_for_each_entry(chan, &device->channels, device_node) {
 		if (chan->local == NULL)
 			continue;
@@ -769,11 +804,14 @@ dma_async_memcpy_buf_to_buf(struct dma_c
 	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);
 	dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE);
-	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
-					 DMA_CTRL_ACK);
+	flags = DMA_CTRL_ACK |
+		DMA_COMPL_SRC_UNMAP_SINGLE |
+		DMA_COMPL_DEST_UNMAP_SINGLE;
+	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
 
 	if (!tx) {
 		dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
@@ -815,11 +853,12 @@ dma_async_memcpy_buf_to_pg(struct dma_ch
 	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);
 	dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE);
-	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
-					 DMA_CTRL_ACK);
+	flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE;
+	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
 
 	if (!tx) {
 		dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
@@ -863,12 +902,13 @@ dma_async_memcpy_pg_to_pg(struct dma_cha
 	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);
 	dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len,
 				DMA_FROM_DEVICE);
-	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
-					 DMA_CTRL_ACK);
+	flags = DMA_CTRL_ACK;
+	tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
 
 	if (!tx) {
 		dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE);
@@ -893,6 +933,7 @@ void dma_async_tx_descriptor_init(struct
 {
 	tx->chan = chan;
 	spin_lock_init(&tx->lock);
+	INIT_LIST_HEAD(&tx->tx_list);
 }
 EXPORT_SYMBOL(dma_async_tx_descriptor_init);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/dmatest.c linux-libre-2.6.30-gnu1/drivers/dma/dmatest.c
--- linux-libre-2.6.29-gnu1/drivers/dma/dmatest.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/dmatest.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,11 @@ module_param(max_channels, uint, S_IRUGO
 MODULE_PARM_DESC(max_channels,
 		"Maximum number of channels to use (default: all)");
 
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+		"Number of xor source buffers (default: 3)");
+
 /*
  * Initialization patterns. All bytes in the source buffer has bit 7
  * set, all bytes in the destination buffer has bit 7 cleared.
@@ -59,8 +64,9 @@ struct dmatest_thread {
 	struct list_head	node;
 	struct task_struct	*task;
 	struct dma_chan		*chan;
-	u8			*srcbuf;
-	u8			*dstbuf;
+	u8			**srcs;
+	u8			**dsts;
+	enum dma_transaction_type type;
 };
 
 struct dmatest_chan {
@@ -98,30 +104,37 @@ static unsigned long dmatest_random(void
 	return buf;
 }
 
-static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
 {
 	unsigned int i;
+	u8 *buf;
 
-	for (i = 0; i < start; i++)
-		buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
-	for ( ; i < start + len; i++)
-		buf[i] = PATTERN_SRC | PATTERN_COPY
-			| (~i & PATTERN_COUNT_MASK);;
-	for ( ; i < test_buf_size; i++)
-		buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_SRC | PATTERN_COPY
+				| (~i & PATTERN_COUNT_MASK);;
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		buf++;
+	}
 }
 
-static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
 {
 	unsigned int i;
+	u8 *buf;
 
-	for (i = 0; i < start; i++)
-		buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
-	for ( ; i < start + len; i++)
-		buf[i] = PATTERN_DST | PATTERN_OVERWRITE
-			| (~i & PATTERN_COUNT_MASK);
-	for ( ; i < test_buf_size; i++)
-		buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	}
 }
 
 static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
@@ -150,23 +163,30 @@ static void dmatest_mismatch(u8 actual,
 				thread_name, index, expected, actual);
 }
 
-static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
 		unsigned int end, unsigned int counter, u8 pattern,
 		bool is_srcbuf)
 {
 	unsigned int i;
 	unsigned int error_count = 0;
 	u8 actual;
+	u8 expected;
+	u8 *buf;
+	unsigned int counter_orig = counter;
 
-	for (i = start; i < end; i++) {
-		actual = buf[i];
-		if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
-			if (error_count < 32)
-				dmatest_mismatch(actual, pattern, i, counter,
-						is_srcbuf);
-			error_count++;
+	for (; (buf = *bufs); bufs++) {
+		counter = counter_orig;
+		for (i = start; i < end; i++) {
+			actual = buf[i];
+			expected = pattern | (~counter & PATTERN_COUNT_MASK);
+			if (actual != expected) {
+				if (error_count < 32)
+					dmatest_mismatch(actual, pattern, i,
+							 counter, is_srcbuf);
+				error_count++;
+			}
+			counter++;
 		}
-		counter++;
 	}
 
 	if (error_count > 32)
@@ -176,12 +196,17 @@ static unsigned int dmatest_verify(u8 *b
 	return error_count;
 }
 
+static void dmatest_callback(void *completion)
+{
+	complete(completion);
+}
+
 /*
  * This function repeatedly tests DMA transfers of various lengths and
- * offsets until it is told to exit by kthread_stop(). There may be
- * multiple threads running this function in parallel for a single
- * channel, and there may be multiple channels being tested in
- * parallel.
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
  *
  * Before each test, the source and destination buffer is initialized
  * with a known pattern. This pattern is different depending on
@@ -201,25 +226,57 @@ static int dmatest_func(void *data)
 	unsigned int		total_tests = 0;
 	dma_cookie_t		cookie;
 	enum dma_status		status;
+	enum dma_ctrl_flags 	flags;
 	int			ret;
+	int			src_cnt;
+	int			dst_cnt;
+	int			i;
 
 	thread_name = current->comm;
 
 	ret = -ENOMEM;
-	thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
-	if (!thread->srcbuf)
-		goto err_srcbuf;
-	thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
-	if (!thread->dstbuf)
-		goto err_dstbuf;
 
 	smp_rmb();
 	chan = thread->chan;
+	if (thread->type == DMA_MEMCPY)
+		src_cnt = dst_cnt = 1;
+	else if (thread->type == DMA_XOR) {
+		src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+		dst_cnt = 1;
+	} else
+		goto err_srcs;
+
+	thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->srcs)
+		goto err_srcs;
+	for (i = 0; i < src_cnt; i++) {
+		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->srcs[i])
+			goto err_srcbuf;
+	}
+	thread->srcs[i] = NULL;
+
+	thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->dsts)
+		goto err_dsts;
+	for (i = 0; i < dst_cnt; i++) {
+		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->dsts[i])
+			goto err_dstbuf;
+	}
+	thread->dsts[i] = NULL;
+
+	set_user_nice(current, 10);
+
+	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
 
 	while (!kthread_should_stop()) {
 		struct dma_device *dev = chan->device;
-		struct dma_async_tx_descriptor *tx;
-		dma_addr_t dma_src, dma_dest;
+		struct dma_async_tx_descriptor *tx = NULL;
+		dma_addr_t dma_srcs[src_cnt];
+		dma_addr_t dma_dsts[dst_cnt];
+		struct completion cmp;
+		unsigned long tmo = msecs_to_jiffies(3000);
 
 		total_tests++;
 
@@ -227,22 +284,41 @@ static int dmatest_func(void *data)
 		src_off = dmatest_random() % (test_buf_size - len + 1);
 		dst_off = dmatest_random() % (test_buf_size - len + 1);
 
-		dmatest_init_srcbuf(thread->srcbuf, src_off, len);
-		dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+		dmatest_init_srcs(thread->srcs, src_off, len);
+		dmatest_init_dsts(thread->dsts, dst_off, len);
 
-		dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
-				len, DMA_TO_DEVICE);
+		for (i = 0; i < src_cnt; i++) {
+			u8 *buf = thread->srcs[i] + src_off;
+
+			dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+						     DMA_TO_DEVICE);
+		}
 		/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
-		dma_dest = dma_map_single(dev->dev, thread->dstbuf,
-				test_buf_size, DMA_BIDIRECTIONAL);
+		for (i = 0; i < dst_cnt; i++) {
+			dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+						     test_buf_size,
+						     DMA_BIDIRECTIONAL);
+		}
+
+		if (thread->type == DMA_MEMCPY)
+			tx = dev->device_prep_dma_memcpy(chan,
+							 dma_dsts[0] + dst_off,
+							 dma_srcs[0], len,
+							 flags);
+		else if (thread->type == DMA_XOR)
+			tx = dev->device_prep_dma_xor(chan,
+						      dma_dsts[0] + dst_off,
+						      dma_srcs, xor_sources,
+						      len, flags);
 
-		tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
-				dma_src, len,
-				DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
 		if (!tx) {
-			dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
-			dma_unmap_single(dev->dev, dma_dest,
-					test_buf_size, DMA_BIDIRECTIONAL);
+			for (i = 0; i < src_cnt; i++)
+				dma_unmap_single(dev->dev, dma_srcs[i], len,
+						 DMA_TO_DEVICE);
+			for (i = 0; i < dst_cnt; i++)
+				dma_unmap_single(dev->dev, dma_dsts[i],
+						 test_buf_size,
+						 DMA_BIDIRECTIONAL);
 			pr_warning("%s: #%u: prep error with src_off=0x%x "
 					"dst_off=0x%x len=0x%x\n",
 					thread_name, total_tests - 1,
@@ -251,7 +327,10 @@ static int dmatest_func(void *data)
 			failed_tests++;
 			continue;
 		}
-		tx->callback = NULL;
+
+		init_completion(&cmp);
+		tx->callback = dmatest_callback;
+		tx->callback_param = &cmp;
 		cookie = tx->tx_submit(tx);
 
 		if (dma_submit_error(cookie)) {
@@ -263,44 +342,50 @@ static int dmatest_func(void *data)
 			failed_tests++;
 			continue;
 		}
-		dma_async_memcpy_issue_pending(chan);
+		dma_async_issue_pending(chan);
 
-		do {
-			msleep(1);
-			status = dma_async_memcpy_complete(
-					chan, cookie, NULL, NULL);
-		} while (status == DMA_IN_PROGRESS);
+		tmo = wait_for_completion_timeout(&cmp, tmo);
+		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
 
-		if (status == DMA_ERROR) {
-			pr_warning("%s: #%u: error during copy\n",
-					thread_name, total_tests - 1);
+		if (tmo == 0) {
+			pr_warning("%s: #%u: test timed out\n",
+				   thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warning("%s: #%u: got completion callback,"
+				   " but status is \'%s\'\n",
+				   thread_name, total_tests - 1,
+				   status == DMA_ERROR ? "error" : "in progress");
 			failed_tests++;
 			continue;
 		}
+
 		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
-		dma_unmap_single(dev->dev, dma_dest,
-				test_buf_size, DMA_BIDIRECTIONAL);
+		for (i = 0; i < dst_cnt; i++)
+			dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+					 DMA_BIDIRECTIONAL);
 
 		error_count = 0;
 
 		pr_debug("%s: verifying source buffer...\n", thread_name);
-		error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+		error_count += dmatest_verify(thread->srcs, 0, src_off,
 				0, PATTERN_SRC, true);
-		error_count += dmatest_verify(thread->srcbuf, src_off,
+		error_count += dmatest_verify(thread->srcs, src_off,
 				src_off + len, src_off,
 				PATTERN_SRC | PATTERN_COPY, true);
-		error_count += dmatest_verify(thread->srcbuf, src_off + len,
+		error_count += dmatest_verify(thread->srcs, src_off + len,
 				test_buf_size, src_off + len,
 				PATTERN_SRC, true);
 
 		pr_debug("%s: verifying dest buffer...\n",
 				thread->task->comm);
-		error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+		error_count += dmatest_verify(thread->dsts, 0, dst_off,
 				0, PATTERN_DST, false);
-		error_count += dmatest_verify(thread->dstbuf, dst_off,
+		error_count += dmatest_verify(thread->dsts, dst_off,
 				dst_off + len, src_off,
 				PATTERN_SRC | PATTERN_COPY, false);
-		error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+		error_count += dmatest_verify(thread->dsts, dst_off + len,
 				test_buf_size, dst_off + len,
 				PATTERN_DST, false);
 
@@ -319,10 +404,16 @@ static int dmatest_func(void *data)
 	}
 
 	ret = 0;
-	kfree(thread->dstbuf);
+	for (i = 0; thread->dsts[i]; i++)
+		kfree(thread->dsts[i]);
 err_dstbuf:
-	kfree(thread->srcbuf);
+	kfree(thread->dsts);
+err_dsts:
+	for (i = 0; thread->srcs[i]; i++)
+		kfree(thread->srcs[i]);
 err_srcbuf:
+	kfree(thread->srcs);
+err_srcs:
 	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
 			thread_name, total_tests, failed_tests, ret);
 	return ret;
@@ -344,35 +435,36 @@ static void dmatest_cleanup_channel(stru
 	kfree(dtc);
 }
 
-static int dmatest_add_channel(struct dma_chan *chan)
+static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
 {
-	struct dmatest_chan	*dtc;
-	struct dmatest_thread	*thread;
-	unsigned int		i;
-
-	dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
-	if (!dtc) {
-		pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
-		return -ENOMEM;
-	}
+	struct dmatest_thread *thread;
+	struct dma_chan *chan = dtc->chan;
+	char *op;
+	unsigned int i;
 
-	dtc->chan = chan;
-	INIT_LIST_HEAD(&dtc->threads);
+	if (type == DMA_MEMCPY)
+		op = "copy";
+	else if (type == DMA_XOR)
+		op = "xor";
+	else
+		return -EINVAL;
 
 	for (i = 0; i < threads_per_chan; i++) {
 		thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
 		if (!thread) {
-			pr_warning("dmatest: No memory for %s-test%u\n",
-				   dma_chan_name(chan), i);
+			pr_warning("dmatest: No memory for %s-%s%u\n",
+				   dma_chan_name(chan), op, i);
+
 			break;
 		}
 		thread->chan = dtc->chan;
+		thread->type = type;
 		smp_wmb();
-		thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
-				dma_chan_name(chan), i);
+		thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",
+				dma_chan_name(chan), op, i);
 		if (IS_ERR(thread->task)) {
-			pr_warning("dmatest: Failed to run thread %s-test%u\n",
-					dma_chan_name(chan), i);
+			pr_warning("dmatest: Failed to run thread %s-%s%u\n",
+					dma_chan_name(chan), op, i);
 			kfree(thread);
 			break;
 		}
@@ -382,7 +474,36 @@ static int dmatest_add_channel(struct dm
 		list_add_tail(&thread->node, &dtc->threads);
 	}
 
-	pr_info("dmatest: Started %u threads using %s\n", i, dma_chan_name(chan));
+	return i;
+}
+
+static int dmatest_add_channel(struct dma_chan *chan)
+{
+	struct dmatest_chan	*dtc;
+	struct dma_device	*dma_dev = chan->device;
+	unsigned int		thread_count = 0;
+	unsigned int		cnt;
+
+	dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+	if (!dtc) {
+		pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
+		return -ENOMEM;
+	}
+
+	dtc->chan = chan;
+	INIT_LIST_HEAD(&dtc->threads);
+
+	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+		cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
+		thread_count += cnt > 0 ?: 0;
+	}
+	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+		cnt = dmatest_add_threads(dtc, DMA_XOR);
+		thread_count += cnt > 0 ?: 0;
+	}
+
+	pr_info("dmatest: Started %u threads using %s\n",
+		thread_count, dma_chan_name(chan));
 
 	list_add_tail(&dtc->node, &dmatest_channels);
 	nr_channels++;
@@ -410,9 +531,7 @@ static int __init dmatest_init(void)
 		chan = dma_request_channel(mask, filter, NULL);
 		if (chan) {
 			err = dmatest_add_channel(chan);
-			if (err == 0)
-				continue;
-			else {
+			if (err) {
 				dma_release_channel(chan);
 				break; /* add_channel failed, punt */
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/dw_dmac.c linux-libre-2.6.30-gnu1/drivers/dma/dw_dmac.c
--- linux-libre-2.6.29-gnu1/drivers/dma/dw_dmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/dw_dmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -363,6 +363,82 @@ static void dwc_handle_error(struct dw_d
 	dwc_descriptor_complete(dwc, bad_desc);
 }
 
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, DAR);
+}
+EXPORT_SYMBOL(dw_dma_get_dst_addr);
+
+/* called with dwc->lock held and all DMAC interrupts disabled */
+static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+		u32 status_block, u32 status_err, u32 status_xfer)
+{
+	if (status_block & dwc->mask) {
+		void (*callback)(void *param);
+		void *callback_param;
+
+		dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+				channel_readl(dwc, LLP));
+		dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+
+		callback = dwc->cdesc->period_callback;
+		callback_param = dwc->cdesc->period_callback_param;
+		if (callback) {
+			spin_unlock(&dwc->lock);
+			callback(callback_param);
+			spin_lock(&dwc->lock);
+		}
+	}
+
+	/*
+	 * Error and transfer complete are highly unlikely, and will most
+	 * likely be due to a configuration error by the user.
+	 */
+	if (unlikely(status_err & dwc->mask) ||
+			unlikely(status_xfer & dwc->mask)) {
+		int i;
+
+		dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+				"interrupt, stopping DMA transfer\n",
+				status_xfer ? "xfer" : "error");
+		dev_err(chan2dev(&dwc->chan),
+			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+			channel_readl(dwc, SAR),
+			channel_readl(dwc, DAR),
+			channel_readl(dwc, LLP),
+			channel_readl(dwc, CTL_HI),
+			channel_readl(dwc, CTL_LO));
+
+		channel_clear_bit(dw, CH_EN, dwc->mask);
+		while (dma_readl(dw, CH_EN) & dwc->mask)
+			cpu_relax();
+
+		/* make sure DMA does not restart by loading a new list */
+		channel_writel(dwc, LLP, 0);
+		channel_writel(dwc, CTL_LO, 0);
+		channel_writel(dwc, CTL_HI, 0);
+
+		dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+		dma_writel(dw, CLEAR.ERROR, dwc->mask);
+		dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+		for (i = 0; i < dwc->cdesc->periods; i++)
+			dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
 static void dw_dma_tasklet(unsigned long data)
 {
 	struct dw_dma *dw = (struct dw_dma *)data;
@@ -382,7 +458,10 @@ static void dw_dma_tasklet(unsigned long
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
 		spin_lock(&dwc->lock);
-		if (status_err & (1 << i))
+		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+			dwc_handle_cyclic(dw, dwc, status_block, status_err,
+					status_xfer);
+		else if (status_err & (1 << i))
 			dwc_handle_error(dw, dwc);
 		else if ((status_block | status_xfer) & (1 << i))
 			dwc_scan_descriptors(dw, dwc);
@@ -826,7 +905,6 @@ static int dwc_alloc_chan_resources(stru
 		dma_async_tx_descriptor_init(&desc->txd, chan);
 		desc->txd.tx_submit = dwc_tx_submit;
 		desc->txd.flags = DMA_CTRL_ACK;
-		INIT_LIST_HEAD(&desc->txd.tx_list);
 		desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
 				sizeof(desc->lli), DMA_TO_DEVICE);
 		dwc_desc_put(dwc, desc);
@@ -884,6 +962,257 @@ static void dwc_free_chan_resources(stru
 	dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
 }
 
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+int dw_dma_cyclic_start(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+
+	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+		dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+		return -ENODEV;
+	}
+
+	spin_lock(&dwc->lock);
+
+	/* assert channel is idle */
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_err(chan2dev(&dwc->chan),
+			"BUG: Attempted to start non-idle channel\n");
+		dev_err(chan2dev(&dwc->chan),
+			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+			channel_readl(dwc, SAR),
+			channel_readl(dwc, DAR),
+			channel_readl(dwc, LLP),
+			channel_readl(dwc, CTL_HI),
+			channel_readl(dwc, CTL_LO));
+		spin_unlock(&dwc->lock);
+		return -EBUSY;
+	}
+
+	dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+	/* setup DMAC channel registers */
+	channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+	channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+	channel_writel(dwc, CTL_HI, 0);
+
+	channel_set_bit(dw, CH_EN, dwc->mask);
+
+	spin_unlock(&dwc->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+
+	spin_lock(&dwc->lock);
+
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+
+	spin_unlock(&dwc->lock);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+		dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+		enum dma_data_direction direction)
+{
+	struct dw_dma_chan		*dwc = to_dw_dma_chan(chan);
+	struct dw_cyclic_desc		*cdesc;
+	struct dw_cyclic_desc		*retval = NULL;
+	struct dw_desc			*desc;
+	struct dw_desc			*last = NULL;
+	struct dw_dma_slave		*dws = chan->private;
+	unsigned long			was_cyclic;
+	unsigned int			reg_width;
+	unsigned int			periods;
+	unsigned int			i;
+
+	spin_lock_bh(&dwc->lock);
+	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+		spin_unlock_bh(&dwc->lock);
+		dev_dbg(chan2dev(&dwc->chan),
+				"queue and/or active list are not empty\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	spin_unlock_bh(&dwc->lock);
+	if (was_cyclic) {
+		dev_dbg(chan2dev(&dwc->chan),
+				"channel already prepared for cyclic DMA\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	retval = ERR_PTR(-EINVAL);
+	reg_width = dws->reg_width;
+	periods = buf_len / period_len;
+
+	/* Check for too big/unaligned periods and unaligned DMA buffer. */
+	if (period_len > (DWC_MAX_COUNT << reg_width))
+		goto out_err;
+	if (unlikely(period_len & ((1 << reg_width) - 1)))
+		goto out_err;
+	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+		goto out_err;
+	if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+		goto out_err;
+
+	retval = ERR_PTR(-ENOMEM);
+
+	if (periods > NR_DESCS_PER_CHANNEL)
+		goto out_err;
+
+	cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+	if (!cdesc)
+		goto out_err;
+
+	cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+	if (!cdesc->desc)
+		goto out_err_alloc;
+
+	for (i = 0; i < periods; i++) {
+		desc = dwc_desc_get(dwc);
+		if (!desc)
+			goto out_err_desc_get;
+
+		switch (direction) {
+		case DMA_TO_DEVICE:
+			desc->lli.dar = dws->tx_reg;
+			desc->lli.sar = buf_addr + (period_len * i);
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_FIX
+					| DWC_CTLL_SRC_INC
+					| DWC_CTLL_FC_M2P
+					| DWC_CTLL_INT_EN);
+			break;
+		case DMA_FROM_DEVICE:
+			desc->lli.dar = buf_addr + (period_len * i);
+			desc->lli.sar = dws->rx_reg;
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_DST_INC
+					| DWC_CTLL_SRC_FIX
+					| DWC_CTLL_FC_P2M
+					| DWC_CTLL_INT_EN);
+			break;
+		default:
+			break;
+		}
+
+		desc->lli.ctlhi = (period_len >> reg_width);
+		cdesc->desc[i] = desc;
+
+		if (last) {
+			last->lli.llp = desc->txd.phys;
+			dma_sync_single_for_device(chan2parent(chan),
+					last->txd.phys, sizeof(last->lli),
+					DMA_TO_DEVICE);
+		}
+
+		last = desc;
+	}
+
+	/* lets make a cyclic list */
+	last->lli.llp = cdesc->desc[0]->txd.phys;
+	dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
+			sizeof(last->lli), DMA_TO_DEVICE);
+
+	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
+			"period %zu periods %d\n", buf_addr, buf_len,
+			period_len, periods);
+
+	cdesc->periods = periods;
+	dwc->cdesc = cdesc;
+
+	return cdesc;
+
+out_err_desc_get:
+	while (i--)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+	kfree(cdesc);
+out_err:
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	struct dw_cyclic_desc	*cdesc = dwc->cdesc;
+	int			i;
+
+	dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+
+	if (!cdesc)
+		return;
+
+	spin_lock_bh(&dwc->lock);
+
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+
+	dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+	spin_unlock_bh(&dwc->lock);
+
+	for (i = 0; i < cdesc->periods; i++)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+
+	kfree(cdesc->desc);
+	kfree(cdesc);
+
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
 /*----------------------------------------------------------------------*/
 
 static void dw_dma_off(struct dw_dma *dw)
@@ -1011,7 +1340,7 @@ static int __init dw_probe(struct platfo
 	dma_writel(dw, CFG, DW_CFG_DMA_EN);
 
 	printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
-			pdev->dev.bus_id, dw->dma.chancnt);
+			dev_name(&pdev->dev), dw->dma.chancnt);
 
 	dma_async_device_register(&dw->dma);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/dw_dmac_regs.h linux-libre-2.6.30-gnu1/drivers/dma/dw_dmac_regs.h
--- linux-libre-2.6.29-gnu1/drivers/dma/dw_dmac_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/dw_dmac_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -126,6 +126,10 @@ struct dw_dma_regs {
 
 #define DW_REGLEN		0x400
 
+enum dw_dmac_flags {
+	DW_DMA_IS_CYCLIC = 0,
+};
+
 struct dw_dma_chan {
 	struct dma_chan		chan;
 	void __iomem		*ch_regs;
@@ -134,10 +138,12 @@ struct dw_dma_chan {
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
+	unsigned long		flags;
 	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
+	struct dw_cyclic_desc	*cdesc;
 
 	unsigned int		descs_allocated;
 };
@@ -158,7 +164,6 @@ static inline struct dw_dma_chan *to_dw_
 	return container_of(chan, struct dw_dma_chan, chan);
 }
 
-
 struct dw_dma {
 	struct dma_device	dma;
 	void __iomem		*regs;
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/fsldma.c linux-libre-2.6.30-gnu1/drivers/dma/fsldma.c
--- linux-libre-2.6.29-gnu1/drivers/dma/fsldma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/fsldma.c	2009-06-09 23:05:27.000000000 -0400
@@ -179,9 +179,14 @@ static void dma_halt(struct fsl_dma_chan
 static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
 			struct fsl_desc_sw *desc)
 {
+	u64 snoop_bits;
+
+	snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+		? FSL_DMA_SNEN : 0;
+
 	desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
-		DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64)	| FSL_DMA_EOL,
-		64);
+		DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL
+			| snoop_bits, 64);
 }
 
 static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
@@ -313,8 +318,8 @@ static void fsl_chan_toggle_ext_start(st
 
 static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
-	struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
 	struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+	struct fsl_desc_sw *desc;
 	unsigned long flags;
 	dma_cookie_t cookie;
 
@@ -322,14 +327,17 @@ static dma_cookie_t fsl_dma_tx_submit(st
 	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
 
 	cookie = fsl_chan->common.cookie;
-	cookie++;
-	if (cookie < 0)
-		cookie = 1;
-	desc->async_tx.cookie = cookie;
-	fsl_chan->common.cookie = desc->async_tx.cookie;
+	list_for_each_entry(desc, &tx->tx_list, node) {
+		cookie++;
+		if (cookie < 0)
+			cookie = 1;
 
-	append_ld_queue(fsl_chan, desc);
-	list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+		desc->async_tx.cookie = cookie;
+	}
+
+	fsl_chan->common.cookie = cookie;
+	append_ld_queue(fsl_chan, tx_to_fsl_desc(tx));
+	list_splice_init(&tx->tx_list, fsl_chan->ld_queue.prev);
 
 	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
 
@@ -354,7 +362,6 @@ static struct fsl_desc_sw *fsl_dma_alloc
 		dma_async_tx_descriptor_init(&desc_sw->async_tx,
 						&fsl_chan->common);
 		desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
-		INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
 		desc_sw->async_tx.phys = pdesc;
 	}
 
@@ -455,8 +462,8 @@ static struct dma_async_tx_descriptor *f
 {
 	struct fsl_dma_chan *fsl_chan;
 	struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+	struct list_head *list;
 	size_t copy;
-	LIST_HEAD(link_chain);
 
 	if (!chan)
 		return NULL;
@@ -473,7 +480,7 @@ static struct dma_async_tx_descriptor *f
 		if (!new) {
 			dev_err(fsl_chan->dev,
 					"No free memory for link descriptor\n");
-			return NULL;
+			goto fail;
 		}
 #ifdef FSL_DMA_LD_DEBUG
 		dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
@@ -508,7 +515,19 @@ static struct dma_async_tx_descriptor *f
 	/* Set End-of-link to the last link descriptor of new list*/
 	set_ld_eol(fsl_chan, new);
 
-	return first ? &first->async_tx : NULL;
+	return &first->async_tx;
+
+fail:
+	if (!first)
+		return NULL;
+
+	list = &first->async_tx.tx_list;
+	list_for_each_entry_safe_reverse(new, prev, list, node) {
+		list_del(&new->node);
+		dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys);
+	}
+
+	return NULL;
 }
 
 /**
@@ -599,15 +618,16 @@ static void fsl_chan_xfer_ld_queue(struc
 	dma_addr_t next_dest_addr;
 	unsigned long flags;
 
+	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
 	if (!dma_is_idle(fsl_chan))
-		return;
+		goto out_unlock;
 
 	dma_halt(fsl_chan);
 
 	/* If there are some link descriptors
 	 * not transfered in queue. We need to start it.
 	 */
-	spin_lock_irqsave(&fsl_chan->desc_lock, flags);
 
 	/* Find the first un-transfer desciptor */
 	for (ld_node = fsl_chan->ld_queue.next;
@@ -618,19 +638,20 @@ static void fsl_chan_xfer_ld_queue(struc
 				fsl_chan->common.cookie) == DMA_SUCCESS);
 		ld_node = ld_node->next);
 
-	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
-
 	if (ld_node != &fsl_chan->ld_queue) {
 		/* Get the ld start address from ld_queue */
 		next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
-		dev_dbg(fsl_chan->dev, "xfer LDs staring from %p\n",
-				(void *)next_dest_addr);
+		dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%llx\n",
+				(unsigned long long)next_dest_addr);
 		set_cdar(fsl_chan, next_dest_addr);
 		dma_start(fsl_chan);
 	} else {
 		set_cdar(fsl_chan, 0);
 		set_ndar(fsl_chan, 0);
 	}
+
+out_unlock:
+	spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
 }
 
 /**
@@ -735,8 +756,9 @@ static irqreturn_t fsl_dma_chan_do_inter
 	 */
 	if (stat & FSL_DMA_SR_EOSI) {
 		dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
-		dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n",
-			(void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan));
+		dev_dbg(fsl_chan->dev, "event: clndar 0x%llx, nlndar 0x%llx\n",
+			(unsigned long long)get_cdar(fsl_chan),
+			(unsigned long long)get_ndar(fsl_chan));
 		stat &= ~FSL_DMA_SR_EOSI;
 		update_cookie = 1;
 	}
@@ -831,7 +853,7 @@ static int __devinit fsl_dma_chan_probe(
 			new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
 
 	new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
-	if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
+	if (new_fsl_chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) {
 		dev_err(fdev->dev, "There is no %d channel!\n",
 				new_fsl_chan->id);
 		err = -EINVAL;
@@ -926,8 +948,8 @@ static int __devinit of_fsl_dma_probe(st
 	}
 
 	dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
-			"controller at %p...\n",
-			match->compatible, (void *)fdev->reg.start);
+			"controller at 0x%llx...\n",
+			match->compatible, (unsigned long long)fdev->reg.start);
 	fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
 						- fdev->reg.start + 1);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/ioat.c linux-libre-2.6.30-gnu1/drivers/dma/ioat.c
--- linux-libre-2.6.29-gnu1/drivers/dma/ioat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/ioat.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,15 +98,15 @@ static int __devinit ioat_probe(struct p
 	if (err)
 		goto err_request_regions;
 
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err)
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err)
 		goto err_set_dma_mask;
 
-	err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err)
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err)
 		goto err_set_dma_mask;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/ioat_dma.c linux-libre-2.6.30-gnu1/drivers/dma/ioat_dma.c
--- linux-libre-2.6.29-gnu1/drivers/dma/ioat_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/ioat_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -173,7 +173,7 @@ static int ioat_dma_enumerate_channels(s
 	xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
 #ifdef  CONFIG_I7300_IDLE_IOAT_CHANNEL
-	if (i7300_idle_platform_probe(NULL, NULL) == 0) {
+	if (i7300_idle_platform_probe(NULL, NULL, 1) == 0) {
 		device->common.chancnt--;
 	}
 #endif
@@ -693,7 +693,6 @@ static struct ioat_desc_sw *ioat_dma_all
 		desc_sw->async_tx.tx_submit = ioat2_tx_submit;
 		break;
 	}
-	INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
 
 	desc_sw->hw = desc;
 	desc_sw->async_tx.phys = phys;
@@ -1064,22 +1063,31 @@ static void ioat_dma_cleanup_tasklet(uns
 static void
 ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
 {
-	/*
-	 * yes we are unmapping both _page and _single
-	 * alloc'd regions with unmap_page. Is this
-	 * *really* that bad?
-	 */
-	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
-		pci_unmap_page(ioat_chan->device->pdev,
-				pci_unmap_addr(desc, dst),
-				pci_unmap_len(desc, len),
-				PCI_DMA_FROMDEVICE);
+	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+		if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+			pci_unmap_single(ioat_chan->device->pdev,
+					 pci_unmap_addr(desc, dst),
+					 pci_unmap_len(desc, len),
+					 PCI_DMA_FROMDEVICE);
+		else
+			pci_unmap_page(ioat_chan->device->pdev,
+				       pci_unmap_addr(desc, dst),
+				       pci_unmap_len(desc, len),
+				       PCI_DMA_FROMDEVICE);
+	}
 
-	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
-		pci_unmap_page(ioat_chan->device->pdev,
-				pci_unmap_addr(desc, src),
-				pci_unmap_len(desc, len),
-				PCI_DMA_TODEVICE);
+	if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+		if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+			pci_unmap_single(ioat_chan->device->pdev,
+					 pci_unmap_addr(desc, src),
+					 pci_unmap_len(desc, len),
+					 PCI_DMA_TODEVICE);
+		else
+			pci_unmap_page(ioat_chan->device->pdev,
+				       pci_unmap_addr(desc, src),
+				       pci_unmap_len(desc, len),
+				       PCI_DMA_TODEVICE);
+	}
 }
 
 /**
@@ -1364,6 +1372,7 @@ static int ioat_dma_self_test(struct ioa
 	int err = 0;
 	struct completion cmp;
 	unsigned long tmo;
+	unsigned long flags;
 
 	src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
 	if (!src)
@@ -1393,8 +1402,9 @@ static int ioat_dma_self_test(struct ioa
 				 DMA_TO_DEVICE);
 	dma_dest = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
 				  DMA_FROM_DEVICE);
+	flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE;
 	tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src,
-						   IOAT_TEST_SIZE, 0);
+						   IOAT_TEST_SIZE, flags);
 	if (!tx) {
 		dev_err(&device->pdev->dev,
 			"Self-test prep failed, disabling\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/iop-adma.c linux-libre-2.6.30-gnu1/drivers/dma/iop-adma.c
--- linux-libre-2.6.29-gnu1/drivers/dma/iop-adma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/iop-adma.c	2009-06-09 23:05:27.000000000 -0400
@@ -498,7 +498,6 @@ static int iop_adma_alloc_chan_resources
 		slot->async_tx.tx_submit = iop_adma_tx_submit;
 		INIT_LIST_HEAD(&slot->chain_node);
 		INIT_LIST_HEAD(&slot->slot_node);
-		INIT_LIST_HEAD(&slot->async_tx.tx_list);
 		hw_desc = (char *) iop_chan->device->dma_desc_pool;
 		slot->async_tx.phys =
 			(dma_addr_t) &hw_desc[idx * IOP_ADMA_SLOT_SIZE];
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/ipu/ipu_idmac.c linux-libre-2.6.30-gnu1/drivers/dma/ipu/ipu_idmac.c
--- linux-libre-2.6.29-gnu1/drivers/dma/ipu/ipu_idmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/ipu/ipu_idmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,6 +28,9 @@
 #define FS_VF_IN_VALID	0x00000002
 #define FS_ENC_IN_VALID	0x00000001
 
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+			       bool wait_for_stop);
+
 /*
  * There can be only one, we could allocate it dynamically, but then we'd have
  * to add an extra parameter to some functions, and use something as ugly as
@@ -107,7 +110,7 @@ static uint32_t bytes_per_pixel(enum pix
 	}
 }
 
-/* Enable / disable direct write to memory by the Camera Sensor Interface */
+/* Enable direct write to memory by the Camera Sensor Interface */
 static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
 {
 	uint32_t ic_conf, mask;
@@ -126,6 +129,7 @@ static void ipu_ic_enable_task(struct ip
 	idmac_write_icreg(ipu, ic_conf, IC_CONF);
 }
 
+/* Called under spin_lock_irqsave(&ipu_data.lock) */
 static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
 {
 	uint32_t ic_conf, mask;
@@ -422,7 +426,7 @@ static void ipu_ch_param_set_size(union
 		break;
 	default:
 		dev_err(ipu_data.dev,
-			"mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+			"mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
 		break;
 	}
 
@@ -433,20 +437,20 @@ static void ipu_ch_param_set_burst_size(
 					uint16_t burst_pixels)
 {
 	params->pp.npb = burst_pixels - 1;
-};
+}
 
 static void ipu_ch_param_set_buffer(union chan_param_mem *params,
 				    dma_addr_t buf0, dma_addr_t buf1)
 {
 	params->pp.eba0 = buf0;
 	params->pp.eba1 = buf1;
-};
+}
 
 static void ipu_ch_param_set_rotation(union chan_param_mem *params,
 				      enum ipu_rotate_mode rotate)
 {
 	params->pp.bam = rotate;
-};
+}
 
 static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
 				uint32_t num_words)
@@ -571,7 +575,7 @@ static uint32_t dma_param_addr(uint32_t
 {
 	/* Channel Parameter Memory */
 	return 0x10000 | (dma_ch << 4);
-};
+}
 
 static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
 				     bool prio)
@@ -611,7 +615,8 @@ static uint32_t ipu_channel_conf_mask(en
 
 /**
  * ipu_enable_channel() - enable an IPU channel.
- * @channel:	channel ID.
+ * @idmac:	IPU DMAC context.
+ * @ichan:	IDMAC channel.
  * @return:	0 on success or negative error code on failure.
  */
 static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
@@ -649,7 +654,7 @@ static int ipu_enable_channel(struct idm
 
 /**
  * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
- * @channel:	channel ID.
+ * @ichan:	IDMAC channel.
  * @pixel_fmt:	pixel format of buffer. Pixel format is a FOURCC ASCII code.
  * @width:	width of buffer in pixels.
  * @height:	height of buffer in pixels.
@@ -687,7 +692,7 @@ static int ipu_init_channel_buffer(struc
 	}
 
 	/* IC channel's stride must be a multiple of 8 pixels */
-	if ((channel <= 13) && (stride % 8)) {
+	if ((channel <= IDMAC_IC_13) && (stride % 8)) {
 		dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
 		return -EINVAL;
 	}
@@ -752,7 +757,7 @@ static void ipu_select_buffer(enum ipu_c
 
 /**
  * ipu_update_channel_buffer() - update physical address of a channel buffer.
- * @channel:	channel ID.
+ * @ichan:	IDMAC channel.
  * @buffer_n:	buffer number to update.
  *		0 or 1 are the only valid values.
  * @phyaddr:	buffer physical address.
@@ -760,9 +765,10 @@ static void ipu_select_buffer(enum ipu_c
  *              function will fail if the buffer is set to ready.
  */
 /* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(enum ipu_channel channel,
+static int 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;
 	unsigned long flags;
 
@@ -771,8 +777,8 @@ static int ipu_update_channel_buffer(enu
 	if (buffer_n == 0) {
 		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
 		if (reg & (1UL << channel)) {
-			spin_unlock_irqrestore(&ipu_data.lock, flags);
-			return -EACCES;
+			ipu_ic_disable_task(&ipu_data, channel);
+			ichan->status = IPU_CHANNEL_READY;
 		}
 
 		/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
@@ -782,8 +788,8 @@ static int ipu_update_channel_buffer(enu
 	} else {
 		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
 		if (reg & (1UL << channel)) {
-			spin_unlock_irqrestore(&ipu_data.lock, flags);
-			return -EACCES;
+			ipu_ic_disable_task(&ipu_data, channel);
+			ichan->status = IPU_CHANNEL_READY;
 		}
 
 		/* Check if double-buffering is already enabled */
@@ -805,6 +811,39 @@ static int ipu_update_channel_buffer(enu
 }
 
 /* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_buffer(struct idmac_channel *ichan,
+	struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
+{
+	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;
+
+	/*
+	 * On first invocation this shouldn't be necessary, the call to
+	 * ipu_init_channel_buffer() above will set addresses for us, so we
+	 * 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_select_buffer(chan_id, buf_idx);
+	dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
+		sg, chan_id, buf_idx);
+
+	return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
 static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
 				      struct idmac_tx_desc *desc)
 {
@@ -815,20 +854,10 @@ static int ipu_submit_channel_buffers(st
 		if (!ichan->sg[i]) {
 			ichan->sg[i] = sg;
 
-			/*
-			 * On first invocation this shouldn't be necessary, the
-			 * call to ipu_init_channel_buffer() above will set
-			 * addresses for us, so we could make it conditional
-			 * on status >= IPU_CHANNEL_ENABLED, but doing it again
-			 * shouldn't hurt either.
-			 */
-			ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
-							sg_dma_address(sg));
+			ret = ipu_submit_buffer(ichan, desc, sg, i);
 			if (ret < 0)
 				return ret;
 
-			ipu_select_buffer(ichan->dma_chan.chan_id, i);
-
 			sg = sg_next(sg);
 		}
 	}
@@ -842,19 +871,22 @@ static dma_cookie_t idmac_tx_submit(stru
 	struct idmac_channel *ichan = to_idmac_chan(tx->chan);
 	struct idmac *idmac = to_idmac(tx->chan->device);
 	struct ipu *ipu = to_ipu(idmac);
+	struct device *dev = &ichan->dma_chan.dev->device;
 	dma_cookie_t cookie;
 	unsigned long flags;
+	int ret;
 
 	/* Sanity check */
 	if (!list_empty(&desc->list)) {
 		/* The descriptor doesn't belong to client */
-		dev_err(&ichan->dma_chan.dev->device,
-			"Descriptor %p not prepared!\n", tx);
+		dev_err(dev, "Descriptor %p not prepared!\n", tx);
 		return -EBUSY;
 	}
 
 	mutex_lock(&ichan->chan_mutex);
 
+	async_tx_clear_ack(tx);
+
 	if (ichan->status < IPU_CHANNEL_READY) {
 		struct idmac_video_param *video = &ichan->params.video;
 		/*
@@ -878,16 +910,7 @@ static dma_cookie_t idmac_tx_submit(stru
 			goto out;
 	}
 
-	/* ipu->lock can be taken under ichan->lock, but not v.v. */
-	spin_lock_irqsave(&ichan->lock, flags);
-
-	/* submit_buffers() atomically verifies and fills empty sg slots */
-	cookie = ipu_submit_channel_buffers(ichan, desc);
-
-	spin_unlock_irqrestore(&ichan->lock, flags);
-
-	if (cookie < 0)
-		goto out;
+	dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
 
 	cookie = ichan->dma_chan.cookie;
 
@@ -897,24 +920,40 @@ static dma_cookie_t idmac_tx_submit(stru
 	/* from dmaengine.h: "last cookie value returned to client" */
 	ichan->dma_chan.cookie = cookie;
 	tx->cookie = cookie;
+
+	/* ipu->lock can be taken under ichan->lock, but not v.v. */
 	spin_lock_irqsave(&ichan->lock, flags);
+
 	list_add_tail(&desc->list, &ichan->queue);
+	/* submit_buffers() atomically verifies and fills empty sg slots */
+	ret = ipu_submit_channel_buffers(ichan, desc);
+
 	spin_unlock_irqrestore(&ichan->lock, flags);
 
+	if (ret < 0) {
+		cookie = ret;
+		goto dequeue;
+	}
+
 	if (ichan->status < IPU_CHANNEL_ENABLED) {
-		int ret = ipu_enable_channel(idmac, ichan);
+		ret = ipu_enable_channel(idmac, ichan);
 		if (ret < 0) {
 			cookie = ret;
-			spin_lock_irqsave(&ichan->lock, flags);
-			list_del_init(&desc->list);
-			spin_unlock_irqrestore(&ichan->lock, flags);
-			tx->cookie = cookie;
-			ichan->dma_chan.cookie = cookie;
+			goto dequeue;
 		}
 	}
 
 	dump_idmac_reg(ipu);
 
+dequeue:
+	if (cookie < 0) {
+		spin_lock_irqsave(&ichan->lock, flags);
+		list_del_init(&desc->list);
+		spin_unlock_irqrestore(&ichan->lock, flags);
+		tx->cookie = cookie;
+		ichan->dma_chan.cookie = cookie;
+	}
+
 out:
 	mutex_unlock(&ichan->chan_mutex);
 
@@ -944,8 +983,6 @@ static int idmac_desc_alloc(struct idmac
 		memset(txd, 0, sizeof(*txd));
 		dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
 		txd->tx_submit		= idmac_tx_submit;
-		txd->chan		= &ichan->dma_chan;
-		INIT_LIST_HEAD(&txd->tx_list);
 
 		list_add(&desc->list, &ichan->free_list);
 
@@ -1161,6 +1198,24 @@ static int ipu_disable_channel(struct id
 	return 0;
 }
 
+static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
+	struct idmac_tx_desc **desc, struct scatterlist *sg)
+{
+	struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
+
+	if (sgnew)
+		/* next sg-element in this list */
+		return sgnew;
+
+	if ((*desc)->list.next == &ichan->queue)
+		/* No more descriptors on the queue */
+		return NULL;
+
+	/* Fetch next descriptor */
+	*desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
+	return (*desc)->sg;
+}
+
 /*
  * We have several possibilities here:
  * current BUF		next BUF
@@ -1176,25 +1231,49 @@ static int ipu_disable_channel(struct id
 static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 {
 	struct idmac_channel *ichan = dev_id;
+	struct device *dev = &ichan->dma_chan.dev->device;
 	unsigned int chan_id = ichan->dma_chan.chan_id;
 	struct scatterlist **sg, *sgnext, *sgnew = NULL;
 	/* Next transfer descriptor */
-	struct idmac_tx_desc *desc = NULL, *descnew;
+	struct idmac_tx_desc *desc, *descnew;
 	dma_async_tx_callback callback;
 	void *callback_param;
 	bool done = false;
-	u32	ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
-		ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
-		curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+	u32 ready0, ready1, curbuf, err;
+	unsigned long flags;
 
 	/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
 
-	pr_debug("IDMAC irq %d\n", irq);
+	dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
+
+	spin_lock_irqsave(&ipu_data.lock, flags);
+
+	ready0	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+	ready1	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+	curbuf	= idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+	err	= idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+
+	if (err & (1 << chan_id)) {
+		idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+		spin_unlock_irqrestore(&ipu_data.lock, flags);
+		/*
+		 * Doing this
+		 * ichan->sg[0] = ichan->sg[1] = NULL;
+		 * you can force channel re-enable on the next tx_submit(), but
+		 * this is dirty - think about descriptors with multiple
+		 * sg elements.
+		 */
+		dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
+			 chan_id, ready0, ready1, curbuf);
+		return IRQ_HANDLED;
+	}
+	spin_unlock_irqrestore(&ipu_data.lock, flags);
+
 	/* Other interrupts do not interfere with this channel */
 	spin_lock(&ichan->lock);
-
 	if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
-		     ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
+		     ((curbuf >> chan_id) & 1) == ichan->active_buffer &&
+		     !list_is_last(ichan->queue.next, &ichan->queue))) {
 		int i = 100;
 
 		/* This doesn't help. See comment in ipu_disable_channel() */
@@ -1207,19 +1286,23 @@ static irqreturn_t idmac_interrupt(int i
 
 		if (!i) {
 			spin_unlock(&ichan->lock);
-			dev_dbg(ichan->dma_chan.device->dev,
+			dev_dbg(dev,
 				"IRQ on active buffer on channel %x, active "
 				"%d, ready %x, %x, current %x!\n", chan_id,
 				ichan->active_buffer, ready0, ready1, curbuf);
 			return IRQ_NONE;
-		}
+		} else
+			dev_dbg(dev,
+				"Buffer deactivated on channel %x, active "
+				"%d, ready %x, %x, current %x, rest %d!\n", chan_id,
+				ichan->active_buffer, ready0, ready1, curbuf, i);
 	}
 
 	if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
 		     (!ichan->active_buffer && (ready0 >> chan_id) & 1)
 		     )) {
 		spin_unlock(&ichan->lock);
-		dev_dbg(ichan->dma_chan.device->dev,
+		dev_dbg(dev,
 			"IRQ with active buffer still ready on channel %x, "
 			"active %d, ready %x, %x!\n", chan_id,
 			ichan->active_buffer, ready0, ready1);
@@ -1227,8 +1310,9 @@ static irqreturn_t idmac_interrupt(int i
 	}
 
 	if (unlikely(list_empty(&ichan->queue))) {
+		ichan->sg[ichan->active_buffer] = NULL;
 		spin_unlock(&ichan->lock);
-		dev_err(ichan->dma_chan.device->dev,
+		dev_err(dev,
 			"IRQ without queued buffers on channel %x, active %d, "
 			"ready %x, %x!\n", chan_id,
 			ichan->active_buffer, ready0, ready1);
@@ -1243,40 +1327,44 @@ static irqreturn_t idmac_interrupt(int i
 	sg = &ichan->sg[ichan->active_buffer];
 	sgnext = ichan->sg[!ichan->active_buffer];
 
+	if (!*sg) {
+		spin_unlock(&ichan->lock);
+		return IRQ_HANDLED;
+	}
+
+	desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+	descnew = desc;
+
+	dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
+		irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
+
+	/* Find the descriptor of sgnext */
+	sgnew = idmac_sg_next(ichan, &descnew, *sg);
+	if (sgnext != sgnew)
+		dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
+
 	/*
 	 * if sgnext == NULL sg must be the last element in a scatterlist and
 	 * queue must be empty
 	 */
 	if (unlikely(!sgnext)) {
-		if (unlikely(sg_next(*sg))) {
-			dev_err(ichan->dma_chan.device->dev,
-				"Broken buffer-update locking on channel %x!\n",
-				chan_id);
-			/* We'll let the user catch up */
+		if (!WARN_ON(sg_next(*sg)))
+			dev_dbg(dev, "Underrun on channel %x\n", chan_id);
+		ichan->sg[!ichan->active_buffer] = sgnew;
+
+		if (unlikely(sgnew)) {
+			ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
 		} else {
-			/* Underrun */
+			spin_lock_irqsave(&ipu_data.lock, flags);
 			ipu_ic_disable_task(&ipu_data, chan_id);
-			dev_dbg(ichan->dma_chan.device->dev,
-				"Underrun on channel %x\n", chan_id);
+			spin_unlock_irqrestore(&ipu_data.lock, flags);
 			ichan->status = IPU_CHANNEL_READY;
 			/* Continue to check for complete descriptor */
 		}
 	}
 
-	desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
-
-	/* First calculate and submit the next sg element */
-	if (likely(sgnext))
-		sgnew = sg_next(sgnext);
-
-	if (unlikely(!sgnew)) {
-		/* Start a new scatterlist, if any queued */
-		if (likely(desc->list.next != &ichan->queue)) {
-			descnew = list_entry(desc->list.next,
-					     struct idmac_tx_desc, list);
-			sgnew = &descnew->sg[0];
-		}
-	}
+	/* Calculate and submit the next sg element */
+	sgnew = idmac_sg_next(ichan, &descnew, sgnew);
 
 	if (unlikely(!sg_next(*sg)) || !sgnext) {
 		/*
@@ -1289,17 +1377,13 @@ static irqreturn_t idmac_interrupt(int i
 
 	*sg = sgnew;
 
-	if (likely(sgnew)) {
-		int ret;
-
-		ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
-						sg_dma_address(*sg));
-		if (ret < 0)
-			dev_err(ichan->dma_chan.device->dev,
-				"Failed to update buffer on channel %x buffer %d!\n",
-				chan_id, ichan->active_buffer);
-		else
-			ipu_select_buffer(chan_id, ichan->active_buffer);
+	if (likely(sgnew) &&
+	    ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
+		callback = desc->txd.callback;
+		callback_param = desc->txd.callback_param;
+		spin_unlock(&ichan->lock);
+		callback(callback_param);
+		spin_lock(&ichan->lock);
 	}
 
 	/* Flip the active buffer - even if update above failed */
@@ -1327,13 +1411,20 @@ static void ipu_gc_tasklet(unsigned long
 		struct idmac_channel *ichan = ipu->channel + i;
 		struct idmac_tx_desc *desc;
 		unsigned long flags;
-		int j;
+		struct scatterlist *sg;
+		int j, k;
 
 		for (j = 0; j < ichan->n_tx_desc; j++) {
 			desc = ichan->desc + j;
 			spin_lock_irqsave(&ichan->lock, flags);
 			if (async_tx_test_ack(&desc->txd)) {
 				list_move(&desc->list, &ichan->free_list);
+				for_each_sg(desc->sg, sg, desc->sg_len, k) {
+					if (ichan->sg[0] == sg)
+						ichan->sg[0] = NULL;
+					else if (ichan->sg[1] == sg)
+						ichan->sg[1] = NULL;
+				}
 				async_tx_clear_ack(&desc->txd);
 			}
 			spin_unlock_irqrestore(&ichan->lock, flags);
@@ -1341,13 +1432,7 @@ static void ipu_gc_tasklet(unsigned long
 	}
 }
 
-/*
- * At the time .device_alloc_chan_resources() method is called, we cannot know,
- * whether the client will accept the channel. Thus we must only check, if we
- * can satisfy client's request but the only real criterion to verify, whether
- * the client has accepted our offer is the client_count. That's why we have to
- * perform the rest of our allocation tasks on the first call to this function.
- */
+/* Allocate and initialise a transfer descriptor. */
 static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
 		struct scatterlist *sgl, unsigned int sg_len,
 		enum dma_data_direction direction, unsigned long tx_flags)
@@ -1358,8 +1443,8 @@ static struct dma_async_tx_descriptor *i
 	unsigned long flags;
 
 	/* We only can handle these three channels so far */
-	if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
-	    ichan->dma_chan.chan_id != IDMAC_IC_7)
+	if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
+	    chan->chan_id != IDMAC_IC_7)
 		return NULL;
 
 	if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
@@ -1400,7 +1485,7 @@ static void idmac_issue_pending(struct d
 
 	/* This is not always needed, but doesn't hurt either */
 	spin_lock_irqsave(&ipu->lock, flags);
-	ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+	ipu_select_buffer(chan->chan_id, ichan->active_buffer);
 	spin_unlock_irqrestore(&ipu->lock, flags);
 
 	/*
@@ -1432,8 +1517,7 @@ static void __idmac_terminate_all(struct
 			struct idmac_tx_desc *desc = ichan->desc + i;
 			if (list_empty(&desc->list))
 				/* Descriptor was prepared, but not submitted */
-				list_add(&desc->list,
-					 &ichan->free_list);
+				list_add(&desc->list, &ichan->free_list);
 
 			async_tx_clear_ack(&desc->txd);
 		}
@@ -1458,6 +1542,28 @@ static void idmac_terminate_all(struct d
 	mutex_unlock(&ichan->chan_mutex);
 }
 
+#ifdef DEBUG
+static irqreturn_t ic_sof_irq(int irq, void *dev_id)
+{
+	struct idmac_channel *ichan = dev_id;
+	printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
+	       irq, ichan->dma_chan.chan_id);
+	disable_irq_nosync(irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ic_eof_irq(int irq, void *dev_id)
+{
+	struct idmac_channel *ichan = dev_id;
+	printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
+	       irq, ichan->dma_chan.chan_id);
+	disable_irq_nosync(irq);
+	return IRQ_HANDLED;
+}
+
+static int ic_sof = -EINVAL, ic_eof = -EINVAL;
+#endif
+
 static int idmac_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct idmac_channel *ichan = to_idmac_chan(chan);
@@ -1471,31 +1577,49 @@ static int idmac_alloc_chan_resources(st
 	chan->cookie		= 1;
 	ichan->completed	= -ENXIO;
 
-	ret = ipu_irq_map(ichan->dma_chan.chan_id);
+	ret = ipu_irq_map(chan->chan_id);
 	if (ret < 0)
 		goto eimap;
 
 	ichan->eof_irq = ret;
+
+	/*
+	 * Important to first disable the channel, because maybe someone
+	 * used it before us, e.g., the bootloader
+	 */
+	ipu_disable_channel(idmac, ichan, true);
+
+	ret = ipu_init_channel(idmac, ichan);
+	if (ret < 0)
+		goto eichan;
+
 	ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
 			  ichan->eof_name, ichan);
 	if (ret < 0)
 		goto erirq;
 
-	ret = ipu_init_channel(idmac, ichan);
-	if (ret < 0)
-		goto eichan;
+#ifdef DEBUG
+	if (chan->chan_id == IDMAC_IC_7) {
+		ic_sof = ipu_irq_map(69);
+		if (ic_sof > 0)
+			request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+		ic_eof = ipu_irq_map(70);
+		if (ic_eof > 0)
+			request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+	}
+#endif
 
 	ichan->status = IPU_CHANNEL_INITIALIZED;
 
-	dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
-		ichan->dma_chan.chan_id, ichan->eof_irq);
+	dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+		chan->chan_id, ichan->eof_irq);
 
 	return ret;
 
-eichan:
-	free_irq(ichan->eof_irq, ichan);
 erirq:
-	ipu_irq_unmap(ichan->dma_chan.chan_id);
+	ipu_uninit_channel(idmac, ichan);
+eichan:
+	ipu_irq_unmap(chan->chan_id);
 eimap:
 	return ret;
 }
@@ -1510,8 +1634,22 @@ static void idmac_free_chan_resources(st
 	__idmac_terminate_all(chan);
 
 	if (ichan->status > IPU_CHANNEL_FREE) {
+#ifdef DEBUG
+		if (chan->chan_id == IDMAC_IC_7) {
+			if (ic_sof > 0) {
+				free_irq(ic_sof, ichan);
+				ipu_irq_unmap(69);
+				ic_sof = -EINVAL;
+			}
+			if (ic_eof > 0) {
+				free_irq(ic_eof, ichan);
+				ipu_irq_unmap(70);
+				ic_eof = -EINVAL;
+			}
+		}
+#endif
 		free_irq(ichan->eof_irq, ichan);
-		ipu_irq_unmap(ichan->dma_chan.chan_id);
+		ipu_irq_unmap(chan->chan_id);
 	}
 
 	ichan->status = IPU_CHANNEL_FREE;
@@ -1573,7 +1711,7 @@ static int __init ipu_idmac_init(struct
 		dma_chan->device	= &idmac->dma;
 		dma_chan->cookie	= 1;
 		dma_chan->chan_id	= i;
-		list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+		list_add_tail(&dma_chan->device_node, &dma->channels);
 	}
 
 	idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
@@ -1581,7 +1719,7 @@ static int __init ipu_idmac_init(struct
 	return dma_async_device_register(&idmac->dma);
 }
 
-static void ipu_idmac_exit(struct ipu *ipu)
+static void __exit ipu_idmac_exit(struct ipu *ipu)
 {
 	int i;
 	struct idmac *idmac = &ipu->idmac;
@@ -1600,7 +1738,7 @@ static void ipu_idmac_exit(struct ipu *i
  * IPU common probe / remove
  */
 
-static int ipu_probe(struct platform_device *pdev)
+static int __init ipu_probe(struct platform_device *pdev)
 {
 	struct ipu_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *mem_ipu, *mem_ic;
@@ -1649,7 +1787,7 @@ static int ipu_probe(struct platform_dev
 	}
 
 	/* Get IPU clock */
-	ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk");
+	ipu_data.ipu_clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(ipu_data.ipu_clk)) {
 		ret = PTR_ERR(ipu_data.ipu_clk);
 		goto err_clk_get;
@@ -1700,7 +1838,7 @@ err_noirq:
 	return ret;
 }
 
-static int ipu_remove(struct platform_device *pdev)
+static int __exit ipu_remove(struct platform_device *pdev)
 {
 	struct ipu *ipu = platform_get_drvdata(pdev);
 
@@ -1725,7 +1863,7 @@ static struct platform_driver ipu_platfo
 		.name	= "ipu-core",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= ipu_remove,
+	.remove		= __exit_p(ipu_remove),
 };
 
 static int __init ipu_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/ipu/ipu_irq.c linux-libre-2.6.30-gnu1/drivers/dma/ipu/ipu_irq.c
--- linux-libre-2.6.29-gnu1/drivers/dma/ipu/ipu_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/ipu/ipu_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -352,7 +352,7 @@ static struct irq_chip ipu_irq_chip = {
 };
 
 /* Install the IRQ handler */
-int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
 {
 	struct ipu_platform_data *pdata = dev->dev.platform_data;
 	unsigned int irq, irq_base, i;
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/Kconfig linux-libre-2.6.30-gnu1/drivers/dma/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/dma/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -98,6 +98,17 @@ config NET_DMA
 	  Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
 	  say N.
 
+config ASYNC_TX_DMA
+	bool "Async_tx: Offload support for the async_tx api"
+	depends on DMA_ENGINE
+	help
+	  This allows the async_tx api to take advantage of offload engines for
+	  memcpy, memset, xor, and raid6 p+q operations.  If your platform has
+	  a dma engine that can perform raid operations and you have enabled
+	  MD_RAID456 say Y.
+
+	  If unsure, say N.
+
 config DMATEST
 	tristate "DMA Test client"
 	depends on DMA_ENGINE
diff -druNp linux-libre-2.6.29-gnu1/drivers/dma/mv_xor.c linux-libre-2.6.30-gnu1/drivers/dma/mv_xor.c
--- linux-libre-2.6.29-gnu1/drivers/dma/mv_xor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/dma/mv_xor.c	2009-06-09 23:05:27.000000000 -0400
@@ -632,7 +632,6 @@ static int mv_xor_alloc_chan_resources(s
 		slot->async_tx.tx_submit = mv_xor_tx_submit;
 		INIT_LIST_HEAD(&slot->chain_node);
 		INIT_LIST_HEAD(&slot->slot_node);
-		INIT_LIST_HEAD(&slot->async_tx.tx_list);
 		hw_desc = (char *) mv_chan->device->dma_desc_pool;
 		slot->async_tx.phys =
 			(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/amd8111_edac.c linux-libre-2.6.30-gnu1/drivers/edac/amd8111_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/amd8111_edac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/amd8111_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,595 @@
+/*
+ * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors:	Cao Qingtao <qingtao.cao@windriver.com>
+ * 		Benjamin Walsh <benjamin.walsh@windriver.com>
+ * 		Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+#include <asm/io.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8111_edac.h"
+
+#define AMD8111_EDAC_REVISION	" Ver: 1.0.0 " __DATE__
+#define AMD8111_EDAC_MOD_STR	"amd8111_edac"
+
+#define PCI_DEVICE_ID_AMD_8111_PCI	0x7460
+static int edac_dev_idx;
+
+enum amd8111_edac_devs {
+	LPC_BRIDGE = 0,
+};
+
+enum amd8111_edac_pcis {
+	PCI_BRIDGE = 0,
+};
+
+/* Wrapper functions for accessing PCI configuration space */
+static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+	int ret;
+
+	ret = pci_read_config_dword(dev, reg, val32);
+	if (ret != 0)
+		printk(KERN_ERR AMD8111_EDAC_MOD_STR
+			" PCI Access Read Error at 0x%x\n", reg);
+
+	return ret;
+}
+
+static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
+{
+	int ret;
+
+	ret = pci_read_config_byte(dev, reg, val8);
+	if (ret != 0)
+		printk(KERN_ERR AMD8111_EDAC_MOD_STR
+			" PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+	int ret;
+
+	ret = pci_write_config_dword(dev, reg, val32);
+	if (ret != 0)
+		printk(KERN_ERR AMD8111_EDAC_MOD_STR
+			" PCI Access Write Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
+{
+	int ret;
+
+	ret = pci_write_config_byte(dev, reg, val8);
+	if (ret != 0)
+		printk(KERN_ERR AMD8111_EDAC_MOD_STR
+			" PCI Access Write Error at 0x%x\n", reg);
+}
+
+/*
+ * device-specific methods for amd8111 PCI Bridge Controller
+ *
+ * Error Reporting and Handling for amd8111 chipset could be found
+ * in its datasheet 3.1.2 section, P37
+ */
+static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
+{
+	u32 val32;
+	struct pci_dev *dev = pci_info->dev;
+
+	/* First clear error detection flags on the host interface */
+
+	/* Clear SSE/SMA/STA flags in the global status register*/
+	edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+	if (val32 & PCI_STSCMD_CLEAR_MASK)
+		edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+	/* Clear CRC and Link Fail flags in HT Link Control reg */
+	edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+	if (val32 & HT_LINK_CLEAR_MASK)
+		edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+	/* Second clear all fault on the secondary interface */
+
+	/* Clear error flags in the memory-base limit reg. */
+	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+	if (val32 & MEM_LIMIT_CLEAR_MASK)
+		edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+	/* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
+	edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+	if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
+		edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+	/* Last enable error detections */
+	if (edac_op_state == EDAC_OPSTATE_POLL) {
+		/* Enable System Error reporting in global status register */
+		edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+		val32 |= PCI_STSCMD_SERREN;
+		edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+		/* Enable CRC Sync flood packets to HyperTransport Link */
+		edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+		val32 |= HT_LINK_CRCFEN;
+		edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+		/* Enable SSE reporting etc in Interrupt control reg */
+		edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+		val32 |= PCI_INTBRG_CTRL_POLL_MASK;
+		edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+	}
+}
+
+static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
+{
+	u32 val32;
+	struct pci_dev *dev = pci_info->dev;
+
+	if (edac_op_state == EDAC_OPSTATE_POLL) {
+		/* Disable System Error reporting */
+		edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+		val32 &= ~PCI_STSCMD_SERREN;
+		edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+		/* Disable CRC flood packets */
+		edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+		val32 &= ~HT_LINK_CRCFEN;
+		edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+		/* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
+		edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+		val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
+		edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+	}
+}
+
+static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
+{
+	struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
+	struct pci_dev *dev = pci_info->dev;
+	u32 val32;
+
+	/* Check out PCI Bridge Status and Command Register */
+	edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+	if (val32 & PCI_STSCMD_CLEAR_MASK) {
+		printk(KERN_INFO "Error(s) in PCI bridge status and command"
+			"register on device %s\n", pci_info->ctl_name);
+		printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
+			(val32 & PCI_STSCMD_SSE) != 0,
+			(val32 & PCI_STSCMD_RMA) != 0,
+			(val32 & PCI_STSCMD_RTA) != 0);
+
+		val32 |= PCI_STSCMD_CLEAR_MASK;
+		edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check out HyperTransport Link Control Register */
+	edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+	if (val32 & HT_LINK_LKFAIL) {
+		printk(KERN_INFO "Error(s) in hypertransport link control"
+			"register on device %s\n", pci_info->ctl_name);
+		printk(KERN_INFO "LKFAIL: %d\n",
+			(val32 & HT_LINK_LKFAIL) != 0);
+
+		val32 |= HT_LINK_LKFAIL;
+		edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check out PCI Interrupt and Bridge Control Register */
+	edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+	if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
+		printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
+			"register on device %s\n", pci_info->ctl_name);
+		printk(KERN_INFO "DTSTAT: %d\n",
+			(val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
+
+		val32 |= PCI_INTBRG_CTRL_DTSTAT;
+		edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check out PCI Bridge Memory Base-Limit Register */
+	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+	if (val32 & MEM_LIMIT_CLEAR_MASK) {
+		printk(KERN_INFO
+			"Error(s) in mem limit register on %s device\n",
+			pci_info->ctl_name);
+		printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+			"RTA: %d, STA: %d, MDPE: %d\n",
+			(val32 & MEM_LIMIT_DPE)  != 0,
+			(val32 & MEM_LIMIT_RSE)  != 0,
+			(val32 & MEM_LIMIT_RMA)  != 0,
+			(val32 & MEM_LIMIT_RTA)  != 0,
+			(val32 & MEM_LIMIT_STA)  != 0,
+			(val32 & MEM_LIMIT_MDPE) != 0);
+
+		val32 |= MEM_LIMIT_CLEAR_MASK;
+		edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+}
+
+static struct resource *legacy_io_res;
+static int at_compat_reg_broken;
+#define LEGACY_NR_PORTS	1
+
+/* device-specific methods for amd8111 LPC Bridge device */
+static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
+{
+	u8 val8;
+	struct pci_dev *dev = dev_info->dev;
+
+	/* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
+	legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
+					AMD8111_EDAC_MOD_STR);
+	if (!legacy_io_res)
+		printk(KERN_INFO "%s: failed to request legacy I/O region "
+			"start %d, len %d\n", __func__,
+			REG_AT_COMPAT, LEGACY_NR_PORTS);
+	else {
+		val8 = __do_inb(REG_AT_COMPAT);
+		if (val8 == 0xff) { /* buggy port */
+			printk(KERN_INFO "%s: port %d is buggy, not supported"
+				" by hardware?\n", __func__, REG_AT_COMPAT);
+			at_compat_reg_broken = 1;
+			release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+			legacy_io_res = NULL;
+		} else {
+			u8 out8 = 0;
+			if (val8 & AT_COMPAT_SERR)
+				out8 = AT_COMPAT_CLRSERR;
+			if (val8 & AT_COMPAT_IOCHK)
+				out8 |= AT_COMPAT_CLRIOCHK;
+			if (out8 > 0)
+				__do_outb(out8, REG_AT_COMPAT);
+		}
+	}
+
+	/* Second clear error flags on LPC bridge */
+	edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+	if (val8 & IO_CTRL_1_CLEAR_MASK)
+		edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+}
+
+static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
+{
+	if (legacy_io_res)
+		release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+}
+
+static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
+{
+	struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
+	struct pci_dev *dev = dev_info->dev;
+	u8 val8;
+
+	edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+	if (val8 & IO_CTRL_1_CLEAR_MASK) {
+		printk(KERN_INFO
+			"Error(s) in IO control register on %s device\n",
+			dev_info->ctl_name);
+		printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
+			(val8 & IO_CTRL_1_LPC_ERR) != 0,
+			(val8 & IO_CTRL_1_PW2LPC) != 0);
+
+		val8 |= IO_CTRL_1_CLEAR_MASK;
+		edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+	}
+
+	if (at_compat_reg_broken == 0) {
+		u8 out8 = 0;
+		val8 = __do_inb(REG_AT_COMPAT);
+		if (val8 & AT_COMPAT_SERR)
+			out8 = AT_COMPAT_CLRSERR;
+		if (val8 & AT_COMPAT_IOCHK)
+			out8 |= AT_COMPAT_CLRIOCHK;
+		if (out8 > 0) {
+			__do_outb(out8, REG_AT_COMPAT);
+			edac_device_handle_ue(edac_dev, 0, 0,
+						edac_dev->ctl_name);
+		}
+	}
+}
+
+/* General devices represented by edac_device_ctl_info */
+static struct amd8111_dev_info amd8111_devices[] = {
+	[LPC_BRIDGE] = {
+		.err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
+		.ctl_name = "lpc",
+		.init = amd8111_lpc_bridge_init,
+		.exit = amd8111_lpc_bridge_exit,
+		.check = amd8111_lpc_bridge_check,
+	},
+	{0},
+};
+
+/* PCI controllers represented by edac_pci_ctl_info */
+static struct amd8111_pci_info amd8111_pcis[] = {
+	[PCI_BRIDGE] = {
+		.err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
+		.ctl_name = "AMD8111_PCI_Controller",
+		.init = amd8111_pci_bridge_init,
+		.exit = amd8111_pci_bridge_exit,
+		.check = amd8111_pci_bridge_check,
+	},
+	{0},
+};
+
+static int amd8111_dev_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
+{
+	struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
+
+	dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+					dev_info->err_dev, NULL);
+
+	if (!dev_info->dev) {
+		printk(KERN_ERR "EDAC device not found:"
+			"vendor %x, device %x, name %s\n",
+			PCI_VENDOR_ID_AMD, dev_info->err_dev,
+			dev_info->ctl_name);
+		return -ENODEV;
+	}
+
+	if (pci_enable_device(dev_info->dev)) {
+		pci_dev_put(dev_info->dev);
+		printk(KERN_ERR "failed to enable:"
+			"vendor %x, device %x, name %s\n",
+			PCI_VENDOR_ID_AMD, dev_info->err_dev,
+			dev_info->ctl_name);
+		return -ENODEV;
+	}
+
+	/*
+	 * we do not allocate extra private structure for
+	 * edac_device_ctl_info, but make use of existing
+	 * one instead.
+	*/
+	dev_info->edac_idx = edac_dev_idx++;
+	dev_info->edac_dev =
+		edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
+					   NULL, 0, 0,
+					   NULL, 0, dev_info->edac_idx);
+	if (!dev_info->edac_dev)
+		return -ENOMEM;
+
+	dev_info->edac_dev->pvt_info = dev_info;
+	dev_info->edac_dev->dev = &dev_info->dev->dev;
+	dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+	dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+	dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		dev_info->edac_dev->edac_check = dev_info->check;
+
+	if (dev_info->init)
+		dev_info->init(dev_info);
+
+	if (edac_device_add_device(dev_info->edac_dev) > 0) {
+		printk(KERN_ERR "failed to add edac_dev for %s\n",
+			dev_info->ctl_name);
+		edac_device_free_ctl_info(dev_info->edac_dev);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "added one edac_dev on AMD8111 "
+		"vendor %x, device %x, name %s\n",
+		PCI_VENDOR_ID_AMD, dev_info->err_dev,
+		dev_info->ctl_name);
+
+	return 0;
+}
+
+static void amd8111_dev_remove(struct pci_dev *dev)
+{
+	struct amd8111_dev_info *dev_info;
+
+	for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
+		if (dev_info->dev->device == dev->device)
+			break;
+
+	if (!dev_info->err_dev)	/* should never happen */
+		return;
+
+	if (dev_info->edac_dev) {
+		edac_device_del_device(dev_info->edac_dev->dev);
+		edac_device_free_ctl_info(dev_info->edac_dev);
+	}
+
+	if (dev_info->exit)
+		dev_info->exit(dev_info);
+
+	pci_dev_put(dev_info->dev);
+}
+
+static int amd8111_pci_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
+{
+	struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
+
+	pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+					pci_info->err_dev, NULL);
+
+	if (!pci_info->dev) {
+		printk(KERN_ERR "EDAC device not found:"
+			"vendor %x, device %x, name %s\n",
+			PCI_VENDOR_ID_AMD, pci_info->err_dev,
+			pci_info->ctl_name);
+		return -ENODEV;
+	}
+
+	if (pci_enable_device(pci_info->dev)) {
+		pci_dev_put(pci_info->dev);
+		printk(KERN_ERR "failed to enable:"
+			"vendor %x, device %x, name %s\n",
+			PCI_VENDOR_ID_AMD, pci_info->err_dev,
+			pci_info->ctl_name);
+		return -ENODEV;
+	}
+
+	/*
+	 * we do not allocate extra private structure for
+	 * edac_pci_ctl_info, but make use of existing
+	 * one instead.
+	*/
+	pci_info->edac_idx = edac_pci_alloc_index();
+	pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
+	if (!pci_info->edac_dev)
+		return -ENOMEM;
+
+	pci_info->edac_dev->pvt_info = pci_info;
+	pci_info->edac_dev->dev = &pci_info->dev->dev;
+	pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+	pci_info->edac_dev->ctl_name = pci_info->ctl_name;
+	pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev);
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		pci_info->edac_dev->edac_check = pci_info->check;
+
+	if (pci_info->init)
+		pci_info->init(pci_info);
+
+	if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
+		printk(KERN_ERR "failed to add edac_pci for %s\n",
+			pci_info->ctl_name);
+		edac_pci_free_ctl_info(pci_info->edac_dev);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "added one edac_pci on AMD8111 "
+		"vendor %x, device %x, name %s\n",
+		PCI_VENDOR_ID_AMD, pci_info->err_dev,
+		pci_info->ctl_name);
+
+	return 0;
+}
+
+static void amd8111_pci_remove(struct pci_dev *dev)
+{
+	struct amd8111_pci_info *pci_info;
+
+	for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
+		if (pci_info->dev->device == dev->device)
+			break;
+
+	if (!pci_info->err_dev)	/* should never happen */
+		return;
+
+	if (pci_info->edac_dev) {
+		edac_pci_del_device(pci_info->edac_dev->dev);
+		edac_pci_free_ctl_info(pci_info->edac_dev);
+	}
+
+	if (pci_info->exit)
+		pci_info->exit(pci_info);
+
+	pci_dev_put(pci_info->dev);
+}
+
+/* PCI Device ID talbe for general EDAC device */
+static const struct pci_device_id amd8111_edac_dev_tbl[] = {
+	{
+	PCI_VEND_DEV(AMD, 8111_LPC),
+	.subvendor = PCI_ANY_ID,
+	.subdevice = PCI_ANY_ID,
+	.class = 0,
+	.class_mask = 0,
+	.driver_data = LPC_BRIDGE,
+	},
+	{
+	0,
+	}			/* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
+
+static struct pci_driver amd8111_edac_dev_driver = {
+	.name = "AMD8111_EDAC_DEV",
+	.probe = amd8111_dev_probe,
+	.remove = amd8111_dev_remove,
+	.id_table = amd8111_edac_dev_tbl,
+};
+
+/* PCI Device ID table for EDAC PCI controller */
+static const struct pci_device_id amd8111_edac_pci_tbl[] = {
+	{
+	PCI_VEND_DEV(AMD, 8111_PCI),
+	.subvendor = PCI_ANY_ID,
+	.subdevice = PCI_ANY_ID,
+	.class = 0,
+	.class_mask = 0,
+	.driver_data = PCI_BRIDGE,
+	},
+	{
+	0,
+	}			/* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
+
+static struct pci_driver amd8111_edac_pci_driver = {
+	.name = "AMD8111_EDAC_PCI",
+	.probe = amd8111_pci_probe,
+	.remove = amd8111_pci_remove,
+	.id_table = amd8111_edac_pci_tbl,
+};
+
+static int __init amd8111_edac_init(void)
+{
+	int val;
+
+	printk(KERN_INFO "AMD8111 EDAC driver "	AMD8111_EDAC_REVISION "\n");
+	printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+	/* Only POLL mode supported so far */
+	edac_op_state = EDAC_OPSTATE_POLL;
+
+	val = pci_register_driver(&amd8111_edac_dev_driver);
+	val |= pci_register_driver(&amd8111_edac_pci_driver);
+
+	return val;
+}
+
+static void __exit amd8111_edac_exit(void)
+{
+	pci_unregister_driver(&amd8111_edac_pci_driver);
+	pci_unregister_driver(&amd8111_edac_dev_driver);
+}
+
+
+module_init(amd8111_edac_init);
+module_exit(amd8111_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/amd8111_edac.h linux-libre-2.6.30-gnu1/drivers/edac/amd8111_edac.h
--- linux-libre-2.6.29-gnu1/drivers/edac/amd8111_edac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/amd8111_edac.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,130 @@
+/*
+ * amd8111_edac.h, EDAC defs for AMD8111 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors:	Cao Qingtao <qingtao.cao@windriver.com>
+ * 		Benjamin Walsh <benjamin.walsh@windriver.com>
+ * 		Hu Yongqi <yongqi.hu@windriver.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 _AMD8111_EDAC_H_
+#define _AMD8111_EDAC_H_
+
+/************************************************************
+ *	PCI Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_PCI_STSCMD	0x04
+enum pci_stscmd_bits {
+	PCI_STSCMD_SSE		= BIT(30),
+	PCI_STSCMD_RMA		= BIT(29),
+	PCI_STSCMD_RTA		= BIT(28),
+	PCI_STSCMD_SERREN	= BIT(8),
+	PCI_STSCMD_CLEAR_MASK	= (PCI_STSCMD_SSE |
+				   PCI_STSCMD_RMA |
+				   PCI_STSCMD_RTA)
+};
+
+/************************************************************
+ *	PCI Bridge Memory Base-Limit Register, DevA:0x1c
+ ************************************************************/
+#define REG_MEM_LIM     0x1c
+enum mem_limit_bits {
+	MEM_LIMIT_DPE   = BIT(31),
+	MEM_LIMIT_RSE   = BIT(30),
+	MEM_LIMIT_RMA   = BIT(29),
+	MEM_LIMIT_RTA   = BIT(28),
+	MEM_LIMIT_STA   = BIT(27),
+	MEM_LIMIT_MDPE  = BIT(24),
+	MEM_LIMIT_CLEAR_MASK  = (MEM_LIMIT_DPE |
+				 MEM_LIMIT_RSE |
+				 MEM_LIMIT_RMA |
+				 MEM_LIMIT_RTA |
+				 MEM_LIMIT_STA |
+				 MEM_LIMIT_MDPE)
+};
+
+/************************************************************
+ *	HyperTransport Link Control Register, DevA:0xc4
+ ************************************************************/
+#define REG_HT_LINK	0xc4
+enum ht_link_bits {
+	HT_LINK_LKFAIL	= BIT(4),
+	HT_LINK_CRCFEN	= BIT(1),
+	HT_LINK_CLEAR_MASK = (HT_LINK_LKFAIL)
+};
+
+/************************************************************
+ *	PCI Bridge Interrupt and Bridge Control, DevA:0x3c
+ ************************************************************/
+#define REG_PCI_INTBRG_CTRL	0x3c
+enum pci_intbrg_ctrl_bits {
+	PCI_INTBRG_CTRL_DTSERREN	= BIT(27),
+	PCI_INTBRG_CTRL_DTSTAT		= BIT(26),
+	PCI_INTBRG_CTRL_MARSP		= BIT(21),
+	PCI_INTBRG_CTRL_SERREN		= BIT(17),
+	PCI_INTBRG_CTRL_PEREN		= BIT(16),
+	PCI_INTBRG_CTRL_CLEAR_MASK	= (PCI_INTBRG_CTRL_DTSTAT),
+	PCI_INTBRG_CTRL_POLL_MASK	= (PCI_INTBRG_CTRL_DTSERREN |
+					   PCI_INTBRG_CTRL_MARSP |
+					   PCI_INTBRG_CTRL_SERREN)
+};
+
+/************************************************************
+ *		I/O Control 1 Register, DevB:0x40
+ ************************************************************/
+#define REG_IO_CTRL_1 0x40
+enum io_ctrl_1_bits {
+	IO_CTRL_1_NMIONERR	= BIT(7),
+	IO_CTRL_1_LPC_ERR	= BIT(6),
+	IO_CTRL_1_PW2LPC	= BIT(1),
+	IO_CTRL_1_CLEAR_MASK	= (IO_CTRL_1_LPC_ERR | IO_CTRL_1_PW2LPC)
+};
+
+/************************************************************
+ *		Legacy I/O Space Registers
+ ************************************************************/
+#define REG_AT_COMPAT 0x61
+enum at_compat_bits {
+	AT_COMPAT_SERR		= BIT(7),
+	AT_COMPAT_IOCHK		= BIT(6),
+	AT_COMPAT_CLRIOCHK	= BIT(3),
+	AT_COMPAT_CLRSERR	= BIT(2),
+};
+
+struct amd8111_dev_info {
+	u16 err_dev;	/* PCI Device ID */
+	struct pci_dev *dev;
+	int edac_idx;	/* device index */
+	char *ctl_name;
+	struct edac_device_ctl_info *edac_dev;
+	void (*init)(struct amd8111_dev_info *dev_info);
+	void (*exit)(struct amd8111_dev_info *dev_info);
+	void (*check)(struct edac_device_ctl_info *edac_dev);
+};
+
+struct amd8111_pci_info {
+	u16 err_dev;	/* PCI Device ID */
+	struct pci_dev *dev;
+	int edac_idx;	/* pci index */
+	const char *ctl_name;
+	struct edac_pci_ctl_info *edac_dev;
+	void (*init)(struct amd8111_pci_info *dev_info);
+	void (*exit)(struct amd8111_pci_info *dev_info);
+	void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8111_EDAC_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/amd8131_edac.c linux-libre-2.6.30-gnu1/drivers/edac/amd8131_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/amd8131_edac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/amd8131_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,379 @@
+/*
+ * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors:	Cao Qingtao <qingtao.cao@windriver.com>
+ * 		Benjamin Walsh <benjamin.walsh@windriver.com>
+ * 		Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8131_edac.h"
+
+#define AMD8131_EDAC_REVISION	" Ver: 1.0.0 " __DATE__
+#define AMD8131_EDAC_MOD_STR	"amd8131_edac"
+
+/* Wrapper functions for accessing PCI configuration space */
+static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+	int ret;
+
+	ret = pci_read_config_dword(dev, reg, val32);
+	if (ret != 0)
+		printk(KERN_ERR AMD8131_EDAC_MOD_STR
+			" PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+	int ret;
+
+	ret = pci_write_config_dword(dev, reg, val32);
+	if (ret != 0)
+		printk(KERN_ERR AMD8131_EDAC_MOD_STR
+			" PCI Access Write Error at 0x%x\n", reg);
+}
+
+static char * const bridge_str[] = {
+	[NORTH_A] = "NORTH A",
+	[NORTH_B] = "NORTH B",
+	[SOUTH_A] = "SOUTH A",
+	[SOUTH_B] = "SOUTH B",
+	[NO_BRIDGE] = "NO BRIDGE",
+};
+
+/* Support up to two AMD8131 chipsets on a platform */
+static struct amd8131_dev_info amd8131_devices[] = {
+	{
+	.inst = NORTH_A,
+	.devfn = DEVFN_PCIX_BRIDGE_NORTH_A,
+	.ctl_name = "AMD8131_PCIX_NORTH_A",
+	},
+	{
+	.inst = NORTH_B,
+	.devfn = DEVFN_PCIX_BRIDGE_NORTH_B,
+	.ctl_name = "AMD8131_PCIX_NORTH_B",
+	},
+	{
+	.inst = SOUTH_A,
+	.devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,
+	.ctl_name = "AMD8131_PCIX_SOUTH_A",
+	},
+	{
+	.inst = SOUTH_B,
+	.devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,
+	.ctl_name = "AMD8131_PCIX_SOUTH_B",
+	},
+	{.inst = NO_BRIDGE,},
+};
+
+static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)
+{
+	u32 val32;
+	struct pci_dev *dev = dev_info->dev;
+
+	/* First clear error detection flags */
+	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+	if (val32 & MEM_LIMIT_MASK)
+		edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+	/* Clear Discard Timer Timedout flag */
+	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+	if (val32 & INT_CTLR_DTS)
+		edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+	/* Clear CRC Error flag on link side A */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+	if (val32 & LNK_CTRL_CRCERR_A)
+		edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+	/* Clear CRC Error flag on link side B */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+	if (val32 & LNK_CTRL_CRCERR_B)
+		edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+	/*
+	 * Then enable all error detections.
+	 *
+	 * Setup Discard Timer Sync Flood Enable,
+	 * System Error Enable and Parity Error Enable.
+	 */
+	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+	val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;
+	edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+	/* Enable overall SERR Error detection */
+	edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+	val32 |= STS_CMD_SERREN;
+	edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+	/* Setup CRC Flood Enable for link side A */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+	val32 |= LNK_CTRL_CRCFEN;
+	edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+	/* Setup CRC Flood Enable for link side B */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+	val32 |= LNK_CTRL_CRCFEN;
+	edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)
+{
+	u32 val32;
+	struct pci_dev *dev = dev_info->dev;
+
+	/* Disable SERR, PERR and DTSE Error detection */
+	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+	val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);
+	edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+	/* Disable overall System Error detection */
+	edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+	val32 &= ~STS_CMD_SERREN;
+	edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+	/* Disable CRC Sync Flood on link side A */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+	val32 &= ~LNK_CTRL_CRCFEN;
+	edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+	/* Disable CRC Sync Flood on link side B */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+	val32 &= ~LNK_CTRL_CRCFEN;
+	edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)
+{
+	struct amd8131_dev_info *dev_info = edac_dev->pvt_info;
+	struct pci_dev *dev = dev_info->dev;
+	u32 val32;
+
+	/* Check PCI-X Bridge Memory Base-Limit Register for errors */
+	edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+	if (val32 & MEM_LIMIT_MASK) {
+		printk(KERN_INFO "Error(s) in mem limit register "
+			"on %s bridge\n", dev_info->ctl_name);
+		printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+			"RTA: %d, STA: %d, MDPE: %d\n",
+			val32 & MEM_LIMIT_DPE,
+			val32 & MEM_LIMIT_RSE,
+			val32 & MEM_LIMIT_RMA,
+			val32 & MEM_LIMIT_RTA,
+			val32 & MEM_LIMIT_STA,
+			val32 & MEM_LIMIT_MDPE);
+
+		val32 |= MEM_LIMIT_MASK;
+		edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check if Discard Timer timed out */
+	edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+	if (val32 & INT_CTLR_DTS) {
+		printk(KERN_INFO "Error(s) in interrupt and control register "
+			"on %s bridge\n", dev_info->ctl_name);
+		printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);
+
+		val32 |= INT_CTLR_DTS;
+		edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check if CRC error happens on link side A */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+	if (val32 & LNK_CTRL_CRCERR_A) {
+		printk(KERN_INFO "Error(s) in link conf and control register "
+			"on %s bridge\n", dev_info->ctl_name);
+		printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);
+
+		val32 |= LNK_CTRL_CRCERR_A;
+		edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+
+	/* Check if CRC error happens on link side B */
+	edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+	if (val32 & LNK_CTRL_CRCERR_B) {
+		printk(KERN_INFO "Error(s) in link conf and control register "
+			"on %s bridge\n", dev_info->ctl_name);
+		printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);
+
+		val32 |= LNK_CTRL_CRCERR_B;
+		edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+		edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+	}
+}
+
+static struct amd8131_info amd8131_chipset = {
+	.err_dev = PCI_DEVICE_ID_AMD_8131_APIC,
+	.devices = amd8131_devices,
+	.init = amd8131_pcix_init,
+	.exit = amd8131_pcix_exit,
+	.check = amd8131_pcix_check,
+};
+
+/*
+ * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,
+ * so amd8131_probe() would be called by kernel 4 times, with different
+ * address of pci_dev for each of them each time.
+ */
+static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct amd8131_dev_info *dev_info;
+
+	for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+		dev_info++)
+		if (dev_info->devfn == dev->devfn)
+			break;
+
+	if (dev_info->inst == NO_BRIDGE) /* should never happen */
+		return -ENODEV;
+
+	/*
+	 * We can't call pci_get_device() as we are used to do because
+	 * there are 4 of them but pci_dev_get() instead.
+	 */
+	dev_info->dev = pci_dev_get(dev);
+
+	if (pci_enable_device(dev_info->dev)) {
+		pci_dev_put(dev_info->dev);
+		printk(KERN_ERR "failed to enable:"
+			"vendor %x, device %x, devfn %x, name %s\n",
+			PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+			dev_info->devfn, dev_info->ctl_name);
+		return -ENODEV;
+	}
+
+	/*
+	 * we do not allocate extra private structure for
+	 * edac_pci_ctl_info, but make use of existing
+	 * one instead.
+	 */
+	dev_info->edac_idx = edac_pci_alloc_index();
+	dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);
+	if (!dev_info->edac_dev)
+		return -ENOMEM;
+
+	dev_info->edac_dev->pvt_info = dev_info;
+	dev_info->edac_dev->dev = &dev_info->dev->dev;
+	dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;
+	dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+	dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		dev_info->edac_dev->edac_check = amd8131_chipset.check;
+
+	if (amd8131_chipset.init)
+		amd8131_chipset.init(dev_info);
+
+	if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {
+		printk(KERN_ERR "failed edac_pci_add_device() for %s\n",
+			dev_info->ctl_name);
+		edac_pci_free_ctl_info(dev_info->edac_dev);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "added one device on AMD8131 "
+		"vendor %x, device %x, devfn %x, name %s\n",
+		PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+		dev_info->devfn, dev_info->ctl_name);
+
+	return 0;
+}
+
+static void amd8131_remove(struct pci_dev *dev)
+{
+	struct amd8131_dev_info *dev_info;
+
+	for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+		dev_info++)
+		if (dev_info->devfn == dev->devfn)
+			break;
+
+	if (dev_info->inst == NO_BRIDGE) /* should never happen */
+		return;
+
+	if (dev_info->edac_dev) {
+		edac_pci_del_device(dev_info->edac_dev->dev);
+		edac_pci_free_ctl_info(dev_info->edac_dev);
+	}
+
+	if (amd8131_chipset.exit)
+		amd8131_chipset.exit(dev_info);
+
+	pci_dev_put(dev_info->dev);
+}
+
+static const struct pci_device_id amd8131_edac_pci_tbl[] = {
+	{
+	PCI_VEND_DEV(AMD, 8131_BRIDGE),
+	.subvendor = PCI_ANY_ID,
+	.subdevice = PCI_ANY_ID,
+	.class = 0,
+	.class_mask = 0,
+	.driver_data = 0,
+	},
+	{
+	0,
+	}			/* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);
+
+static struct pci_driver amd8131_edac_driver = {
+	.name = AMD8131_EDAC_MOD_STR,
+	.probe = amd8131_probe,
+	.remove = amd8131_remove,
+	.id_table = amd8131_edac_pci_tbl,
+};
+
+static int __init amd8131_edac_init(void)
+{
+	printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");
+	printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+	/* Only POLL mode supported so far */
+	edac_op_state = EDAC_OPSTATE_POLL;
+
+	return pci_register_driver(&amd8131_edac_driver);
+}
+
+static void __exit amd8131_edac_exit(void)
+{
+	pci_unregister_driver(&amd8131_edac_driver);
+}
+
+module_init(amd8131_edac_init);
+module_exit(amd8131_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/amd8131_edac.h linux-libre-2.6.30-gnu1/drivers/edac/amd8131_edac.h
--- linux-libre-2.6.29-gnu1/drivers/edac/amd8131_edac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/amd8131_edac.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,119 @@
+/*
+ * amd8131_edac.h, EDAC defs for AMD8131 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors:	Cao Qingtao <qingtao.cao@windriver.com>
+ * 		Benjamin Walsh <benjamin.walsh@windriver.com>
+ * 		Hu Yongqi <yongqi.hu@windriver.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 _AMD8131_EDAC_H_
+#define _AMD8131_EDAC_H_
+
+#define DEVFN_PCIX_BRIDGE_NORTH_A	8
+#define DEVFN_PCIX_BRIDGE_NORTH_B	16
+#define DEVFN_PCIX_BRIDGE_SOUTH_A	24
+#define DEVFN_PCIX_BRIDGE_SOUTH_B	32
+
+/************************************************************
+ *	PCI-X Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_STS_CMD	0x04
+enum sts_cmd_bits {
+	STS_CMD_SSE	= BIT(30),
+	STS_CMD_SERREN	= BIT(8)
+};
+
+/************************************************************
+ *	PCI-X Bridge Interrupt and Bridge Control Register,
+ ************************************************************/
+#define REG_INT_CTLR	0x3c
+enum int_ctlr_bits {
+	INT_CTLR_DTSE	= BIT(27),
+	INT_CTLR_DTS	= BIT(26),
+	INT_CTLR_SERR	= BIT(17),
+	INT_CTLR_PERR	= BIT(16)
+};
+
+/************************************************************
+ *	PCI-X Bridge Memory Base-Limit Register, DevA:0x1C
+ ************************************************************/
+#define REG_MEM_LIM	0x1c
+enum mem_limit_bits {
+	MEM_LIMIT_DPE 	= BIT(31),
+	MEM_LIMIT_RSE 	= BIT(30),
+	MEM_LIMIT_RMA 	= BIT(29),
+	MEM_LIMIT_RTA 	= BIT(28),
+	MEM_LIMIT_STA	= BIT(27),
+	MEM_LIMIT_MDPE	= BIT(24),
+	MEM_LIMIT_MASK	= MEM_LIMIT_DPE|MEM_LIMIT_RSE|MEM_LIMIT_RMA|
+				MEM_LIMIT_RTA|MEM_LIMIT_STA|MEM_LIMIT_MDPE
+};
+
+/************************************************************
+ *	Link Configuration And Control Register, side A
+ ************************************************************/
+#define REG_LNK_CTRL_A	0xc4
+
+/************************************************************
+ *	Link Configuration And Control Register, side B
+ ************************************************************/
+#define REG_LNK_CTRL_B  0xc8
+
+enum lnk_ctrl_bits {
+	LNK_CTRL_CRCERR_A	= BIT(9),
+	LNK_CTRL_CRCERR_B	= BIT(8),
+	LNK_CTRL_CRCFEN		= BIT(1)
+};
+
+enum pcix_bridge_inst {
+	NORTH_A = 0,
+	NORTH_B = 1,
+	SOUTH_A = 2,
+	SOUTH_B = 3,
+	NO_BRIDGE = 4
+};
+
+struct amd8131_dev_info {
+	int devfn;
+	enum pcix_bridge_inst inst;
+	struct pci_dev *dev;
+	int edac_idx;	/* pci device index */
+	char *ctl_name;
+	struct edac_pci_ctl_info *edac_dev;
+};
+
+/*
+ * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC
+ * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are
+ * four PCIX Bridges on ATCA-6101 altogether.
+ *
+ * These PCIX Bridges share the same PCI Device ID and are all of
+ * Function Zero, they could be discrimated by their pci_dev->devfn.
+ * They share the same set of init/check/exit methods, and their
+ * private structures are collected in the devices[] array.
+ */
+struct amd8131_info {
+	u16 err_dev;	/* PCI Device ID for AMD8131 APIC*/
+	struct amd8131_dev_info *devices;
+	void (*init)(struct amd8131_dev_info *dev_info);
+	void (*exit)(struct amd8131_dev_info *dev_info);
+	void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8131_EDAC_H_ */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/cell_edac.c linux-libre-2.6.30-gnu1/drivers/edac/cell_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/cell_edac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/cell_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(str
 	mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
 	mci->mod_name = "cell_edac";
 	mci->ctl_name = "MIC";
-	mci->dev_name = pdev->dev.bus_id;
+	mci->dev_name = dev_name(&pdev->dev);
 	mci->edac_check = cell_edac_check;
 	cell_edac_init_csrows(mci);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/edac_core.h linux-libre-2.6.30-gnu1/drivers/edac/edac_core.h
--- linux-libre-2.6.29-gnu1/drivers/edac/edac_core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/edac_core.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,6 +49,10 @@
 #define edac_printk(level, prefix, fmt, arg...) \
 	printk(level "EDAC " prefix ": " fmt, ##arg)
 
+#define edac_printk_verbose(level, prefix, fmt, arg...) \
+	printk(level "EDAC " prefix ": " "in %s, line at %d: " fmt,	\
+	       __FILE__, __LINE__, ##arg)
+
 #define edac_mc_printk(mci, level, fmt, arg...) \
 	printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
 
@@ -71,11 +75,20 @@
 #ifdef CONFIG_EDAC_DEBUG
 extern int edac_debug_level;
 
+#ifndef CONFIG_EDAC_DEBUG_VERBOSE
 #define edac_debug_printk(level, fmt, arg...)                            \
 	do {                                                             \
 		if (level <= edac_debug_level)                           \
 			edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \
-	} while(0)
+	} while (0)
+#else  /* CONFIG_EDAC_DEBUG_VERBOSE */
+#define edac_debug_printk(level, fmt, arg...)                            \
+	do {                                                             \
+		if (level <= edac_debug_level)                           \
+			edac_printk_verbose(KERN_DEBUG, EDAC_DEBUG, fmt, \
+					    ##arg);			\
+	} while (0)
+#endif
 
 #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
 #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ )
@@ -754,11 +767,19 @@ static inline void pci_write_bits16(stru
 	pci_write_config_word(pdev, offset, value);
 }
 
-/* write all or some bits in a dword-register*/
+/*
+ * pci_write_bits32
+ *
+ * edac local routine to do pci_write_config_dword, but adds
+ * a mask parameter. If mask is all ones, ignore the mask.
+ * Otherwise utilize the mask to isolate specified bits
+ *
+ * write all or some bits in a dword-register
+ */
 static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
 				    u32 value, u32 mask)
 {
-	if (mask != 0xffff) {
+	if (mask != 0xffffffff) {
 		u32 buf;
 
 		pci_read_config_dword(pdev, offset, &buf);
@@ -831,6 +852,7 @@ extern void edac_pci_free_ctl_info(struc
 extern void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
 				unsigned long value);
 
+extern int edac_pci_alloc_index(void);
 extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx);
 extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/edac_device.c linux-libre-2.6.30-gnu1/drivers/edac/edac_device.c
--- linux-libre-2.6.29-gnu1/drivers/edac/edac_device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/edac_device.c	2009-06-09 23:05:27.000000000 -0400
@@ -389,7 +389,7 @@ static void del_edac_device_from_global_
  */
 static void edac_device_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work);
 
 	mutex_lock(&device_ctls_mutex);
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/edac_mc.c linux-libre-2.6.30-gnu1/drivers/edac/edac_mc.c
--- linux-libre-2.6.29-gnu1/drivers/edac/edac_mc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/edac_mc.c	2009-06-09 23:05:27.000000000 -0400
@@ -260,7 +260,7 @@ static int edac_mc_assert_error_check_an
  */
 static void edac_mc_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work);
 
 	mutex_lock(&mem_ctls_mutex);
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/edac_pci.c linux-libre-2.6.30-gnu1/drivers/edac/edac_pci.c
--- linux-libre-2.6.29-gnu1/drivers/edac/edac_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/edac_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,7 @@
 
 static DEFINE_MUTEX(edac_pci_ctls_mutex);
 static LIST_HEAD(edac_pci_list);
+static atomic_t pci_indexes = ATOMIC_INIT(0);
 
 /*
  * edac_pci_alloc_ctl_info
@@ -232,7 +233,7 @@ EXPORT_SYMBOL_GPL(edac_pci_find);
  */
 static void edac_pci_workq_function(struct work_struct *work_req)
 {
-	struct delayed_work *d_work = (struct delayed_work *)work_req;
+	struct delayed_work *d_work = to_delayed_work(work_req);
 	struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work);
 	int msec;
 	unsigned long delay;
@@ -318,6 +319,19 @@ void edac_pci_reset_delay_period(struct
 EXPORT_SYMBOL_GPL(edac_pci_reset_delay_period);
 
 /*
+ * edac_pci_alloc_index: Allocate a unique PCI index number
+ *
+ * Return:
+ *      allocated index number
+ *
+ */
+int edac_pci_alloc_index(void)
+{
+	return atomic_inc_return(&pci_indexes) - 1;
+}
+EXPORT_SYMBOL_GPL(edac_pci_alloc_index);
+
+/*
  * edac_pci_add_device: Insert the 'edac_dev' structure into the
  * edac_pci global list and create sysfs entries associated with
  * edac_pci structure.
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/Kconfig linux-libre-2.6.30-gnu1/drivers/edac/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/edac/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,12 @@
 #
 #	EDAC Kconfig
-#	Copyright (c) 2003 Linux Networx
+#	Copyright (c) 2008 Doug Thompson www.softwarebitmaker.com
 #	Licensed and distributed under the GPL
 #
 
 menuconfig EDAC
-	bool "EDAC - error detection and reporting (EXPERIMENTAL)"
+	bool "EDAC - error detection and reporting"
 	depends on HAS_IOMEM
-	depends on EXPERIMENTAL
 	depends on X86 || PPC
 	help
 	  EDAC is designed to report errors in the core system.
@@ -40,6 +39,14 @@ config EDAC_DEBUG
 	  there're four debug levels (x=0,1,2,3 from low to high).
 	  Usually you should select 'N'.
 
+config EDAC_DEBUG_VERBOSE
+	bool "More verbose debugging"
+	depends on EDAC_DEBUG
+	help
+	  This option makes debugging information more verbose.
+	  Source file name and line number where debugging message
+	  printed will be added to debugging message.
+
 config EDAC_MM_EDAC
 	tristate "Main Memory EDAC (Error Detection And Correction) reporting"
 	default y
@@ -174,4 +181,31 @@ config EDAC_CELL
 	  Cell Broadband Engine internal memory controller
 	  on platform without a hypervisor
 
+config EDAC_PPC4XX
+	tristate "PPC4xx IBM DDR2 Memory Controller"
+	depends on EDAC_MM_EDAC && 4xx
+	help
+	  This enables support for EDAC on the ECC memory used
+	  with the IBM DDR2 memory controller found in various
+	  PowerPC 4xx embedded processors such as the 405EX[r],
+	  440SP, 440SPe, 460EX, 460GT and 460SX.
+
+config EDAC_AMD8131
+	tristate "AMD8131 HyperTransport PCI-X Tunnel"
+	depends on EDAC_MM_EDAC && PCI && PPC_MAPLE
+	help
+	  Support for error detection and correction on the
+	  AMD8131 HyperTransport PCI-X Tunnel chip.
+	  Note, add more Kconfig dependency if it's adopted
+	  on some machine other than Maple.
+
+config EDAC_AMD8111
+	tristate "AMD8111 HyperTransport I/O Hub"
+	depends on EDAC_MM_EDAC && PCI && PPC_MAPLE
+	help
+	  Support for error detection and correction on the
+	  AMD8111 HyperTransport I/O Hub chip.
+	  Note, add more Kconfig dependency if it's adopted
+	  on some machine other than Maple.
+
 endif # EDAC
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/Makefile linux-libre-2.6.30-gnu1/drivers/edac/Makefile
--- linux-libre-2.6.29-gnu1/drivers/edac/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -34,4 +34,6 @@ obj-$(CONFIG_EDAC_PASEMI)		+= pasemi_eda
 obj-$(CONFIG_EDAC_MPC85XX)		+= mpc85xx_edac.o
 obj-$(CONFIG_EDAC_MV64X60)		+= mv64x60_edac.o
 obj-$(CONFIG_EDAC_CELL)			+= cell_edac.o
-
+obj-$(CONFIG_EDAC_PPC4XX)		+= ppc4xx_edac.o
+obj-$(CONFIG_EDAC_AMD8111)		+= amd8111_edac.o
+obj-$(CONFIG_EDAC_AMD8131)		+= amd8131_edac.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/mpc85xx_edac.c linux-libre-2.6.30-gnu1/drivers/edac/mpc85xx_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/mpc85xx_edac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/mpc85xx_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_pro
 	pci->dev = &op->dev;
 	pci->mod_name = EDAC_MOD_STR;
 	pci->ctl_name = pdata->name;
-	pci->dev_name = op->dev.bus_id;
+	pci->dev_name = dev_name(&op->dev);
 
 	if (edac_op_state == EDAC_OPSTATE_POLL)
 		pci->edac_check = mpc85xx_pci_check;
@@ -674,7 +674,7 @@ static void mpc85xx_mc_check(struct mem_
 	int row_index;
 
 	err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
-	if (err_detect)
+	if (!err_detect)
 		return;
 
 	mpc85xx_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/mv64x60_edac.c linux-libre-2.6.30-gnu1/drivers/edac/mv64x60_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/mv64x60_edac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/edac/mv64x60_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_pro
 	pdata->irq = NO_IRQ;
 	platform_set_drvdata(pdev, pci);
 	pci->dev = &pdev->dev;
-	pci->dev_name = pdev->dev.bus_id;
+	pci->dev_name = dev_name(&pdev->dev);
 	pci->mod_name = EDAC_MOD_STR;
 	pci->ctl_name = pdata->name;
 
@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_pr
 	pdata->irq = NO_IRQ;
 	edac_dev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, edac_dev);
-	edac_dev->dev_name = pdev->dev.bus_id;
+	edac_dev->dev_name = dev_name(&pdev->dev);
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_pro
 	pdata->irq = NO_IRQ;
 	edac_dev->dev = &pdev->dev;
 	platform_set_drvdata(pdev, edac_dev);
-	edac_dev->dev_name = pdev->dev.bus_id;
+	edac_dev->dev_name = dev_name(&pdev->dev);
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_prob
 	platform_set_drvdata(pdev, mci);
 	pdata->name = "mv64x60_mc_err";
 	pdata->irq = NO_IRQ;
-	mci->dev_name = pdev->dev.bus_id;
+	mci->dev_name = dev_name(&pdev->dev);
 	pdata->edac_idx = edac_mc_idx++;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/ppc4xx_edac.c linux-libre-2.6.30-gnu1/drivers/edac/ppc4xx_edac.c
--- linux-libre-2.6.29-gnu1/drivers/edac/ppc4xx_edac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/ppc4xx_edac.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1448 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ *   Grant Erickson <gerickson@nuovations.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/edac.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/types.h>
+
+#include <asm/dcr.h>
+
+#include "edac_core.h"
+#include "ppc4xx_edac.h"
+
+/*
+ * This file implements a driver for monitoring and handling events
+ * associated with the IMB DDR2 ECC controller found in the AMCC/IBM
+ * 405EX[r], 440SP, 440SPe, 460EX, 460GT and 460SX.
+ *
+ * As realized in the 405EX[r], this controller features:
+ *
+ *   - Support for registered- and non-registered DDR1 and DDR2 memory.
+ *   - 32-bit or 16-bit memory interface with optional ECC.
+ *
+ *     o ECC support includes:
+ *
+ *       - 4-bit SEC/DED
+ *       - Aligned-nibble error detect
+ *       - Bypass mode
+ *
+ *   - Two (2) memory banks/ranks.
+ *   - Up to 1 GiB per bank/rank in 32-bit mode and up to 512 MiB per
+ *     bank/rank in 16-bit mode.
+ *
+ * As realized in the 440SP and 440SPe, this controller changes/adds:
+ *
+ *   - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ *     o ECC support includes:
+ *
+ *       - 8-bit SEC/DED
+ *       - Aligned-nibble error detect
+ *       - Bypass mode
+ *
+ *   - Up to 4 GiB per bank/rank in 64-bit mode and up to 2 GiB
+ *     per bank/rank in 32-bit mode.
+ *
+ * As realized in the 460EX and 460GT, this controller changes/adds:
+ *
+ *   - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ *     o ECC support includes:
+ *
+ *       - 8-bit SEC/DED
+ *       - Aligned-nibble error detect
+ *       - Bypass mode
+ *
+ *   - Four (4) memory banks/ranks.
+ *   - Up to 16 GiB per bank/rank in 64-bit mode and up to 8 GiB
+ *     per bank/rank in 32-bit mode.
+ *
+ * At present, this driver has ONLY been tested against the controller
+ * realization in the 405EX[r] on the AMCC Kilauea and Haleakala
+ * boards (256 MiB w/o ECC memory soldered onto the board) and a
+ * proprietary board based on those designs (128 MiB ECC memory, also
+ * soldered onto the board).
+ *
+ * Dynamic feature detection and handling needs to be added for the
+ * other realizations of this controller listed above.
+ *
+ * Eventually, this driver will likely be adapted to the above variant
+ * realizations of this controller as well as broken apart to handle
+ * the other known ECC-capable controllers prevalent in other 4xx
+ * processors:
+ *
+ *   - IBM SDRAM (405GP, 405CR and 405EP) "ibm,sdram-4xx"
+ *   - IBM DDR1 (440GP, 440GX, 440EP and 440GR) "ibm,sdram-4xx-ddr"
+ *   - Denali DDR1/DDR2 (440EPX and 440GRX) "denali,sdram-4xx-ddr2"
+ *
+ * For this controller, unfortunately, correctable errors report
+ * nothing more than the beat/cycle and byte/lane the correction
+ * occurred on and the check bit group that covered the error.
+ *
+ * In contrast, uncorrectable errors also report the failing address,
+ * the bus master and the transaction direction (i.e. read or write)
+ *
+ * Regardless of whether the error is a CE or a UE, we report the
+ * following pieces of information in the driver-unique message to the
+ * EDAC subsystem:
+ *
+ *   - Device tree path
+ *   - Bank(s)
+ *   - Check bit error group
+ *   - Beat(s)/lane(s)
+ */
+
+/* Preprocessor Definitions */
+
+#define EDAC_OPSTATE_INT_STR		"interrupt"
+#define EDAC_OPSTATE_POLL_STR		"polled"
+#define EDAC_OPSTATE_UNKNOWN_STR	"unknown"
+
+#define PPC4XX_EDAC_MODULE_NAME		"ppc4xx_edac"
+#define PPC4XX_EDAC_MODULE_REVISION	"v1.0.0 " __DATE__
+
+#define PPC4XX_EDAC_MESSAGE_SIZE	256
+
+/*
+ * Kernel logging without an EDAC instance
+ */
+#define ppc4xx_edac_printk(level, fmt, arg...) \
+	edac_printk(level, "PPC4xx MC", fmt, ##arg)
+
+/*
+ * Kernel logging with an EDAC instance
+ */
+#define ppc4xx_edac_mc_printk(level, mci, fmt, arg...) \
+	edac_mc_chipset_printk(mci, level, "PPC4xx", fmt, ##arg)
+
+/*
+ * Macros to convert bank configuration size enumerations into MiB and
+ * page values.
+ */
+#define SDRAM_MBCF_SZ_MiB_MIN		4
+#define SDRAM_MBCF_SZ_TO_MiB(n)		(SDRAM_MBCF_SZ_MiB_MIN \
+					 << (SDRAM_MBCF_SZ_DECODE(n)))
+#define SDRAM_MBCF_SZ_TO_PAGES(n)	(SDRAM_MBCF_SZ_MiB_MIN \
+					 << (20 - PAGE_SHIFT + \
+					     SDRAM_MBCF_SZ_DECODE(n)))
+
+/*
+ * The ibm,sdram-4xx-ddr2 Device Control Registers (DCRs) are
+ * indirectly acccessed and have a base and length defined by the
+ * device tree. The base can be anything; however, we expect the
+ * length to be precisely two registers, the first for the address
+ * window and the second for the data window.
+ */
+#define SDRAM_DCR_RESOURCE_LEN		2
+#define SDRAM_DCR_ADDR_OFFSET		0
+#define SDRAM_DCR_DATA_OFFSET		1
+
+/*
+ * Device tree interrupt indices
+ */
+#define INTMAP_ECCDED_INDEX		0	/* Double-bit Error Detect */
+#define INTMAP_ECCSEC_INDEX		1	/* Single-bit Error Correct */
+
+/* Type Definitions */
+
+/*
+ * PPC4xx SDRAM memory controller private instance data
+ */
+struct ppc4xx_edac_pdata {
+	dcr_host_t dcr_host;	/* Indirect DCR address/data window mapping */
+	struct {
+		int sec;	/* Single-bit correctable error IRQ assigned */
+		int ded;	/* Double-bit detectable error IRQ assigned */
+	} irqs;
+};
+
+/*
+ * Various status data gathered and manipulated when checking and
+ * reporting ECC status.
+ */
+struct ppc4xx_ecc_status {
+	u32 ecces;
+	u32 besr;
+	u32 bearh;
+	u32 bearl;
+	u32 wmirq;
+};
+
+/* Function Prototypes */
+
+static int ppc4xx_edac_probe(struct of_device *device,
+			     const struct of_device_id *device_id);
+static int ppc4xx_edac_remove(struct of_device *device);
+
+/* Global Variables */
+
+/*
+ * Device tree node type and compatible tuples this driver can match
+ * on.
+ */
+static struct of_device_id ppc4xx_edac_match[] = {
+	{
+		.compatible	= "ibm,sdram-4xx-ddr2"
+	},
+	{ }
+};
+
+static struct of_platform_driver ppc4xx_edac_driver = {
+	.match_table		= ppc4xx_edac_match,
+	.probe			= ppc4xx_edac_probe,
+	.remove			= ppc4xx_edac_remove,
+	.driver			= {
+		.owner	= THIS_MODULE,
+		.name	= PPC4XX_EDAC_MODULE_NAME
+	}
+};
+
+/*
+ * TODO: The row and channel parameters likely need to be dynamically
+ * set based on the aforementioned variant controller realizations.
+ */
+static const unsigned ppc4xx_edac_nr_csrows = 2;
+static const unsigned ppc4xx_edac_nr_chans = 1;
+
+/*
+ * Strings associated with PLB master IDs capable of being posted in
+ * SDRAM_BESR or SDRAM_WMIRQ on uncorrectable ECC errors.
+ */
+static const char * const ppc4xx_plb_masters[9] = {
+	[SDRAM_PLB_M0ID_ICU]	= "ICU",
+	[SDRAM_PLB_M0ID_PCIE0]	= "PCI-E 0",
+	[SDRAM_PLB_M0ID_PCIE1]	= "PCI-E 1",
+	[SDRAM_PLB_M0ID_DMA]	= "DMA",
+	[SDRAM_PLB_M0ID_DCU]	= "DCU",
+	[SDRAM_PLB_M0ID_OPB]	= "OPB",
+	[SDRAM_PLB_M0ID_MAL]	= "MAL",
+	[SDRAM_PLB_M0ID_SEC]	= "SEC",
+	[SDRAM_PLB_M0ID_AHB]	= "AHB"
+};
+
+/**
+ * mfsdram - read and return controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to read.
+ *
+ * This routine reads and returns the data associated with the
+ * controller's specified indirect DCR register.
+ *
+ * Returns the read data.
+ */
+static inline u32
+mfsdram(const dcr_host_t *dcr_host, unsigned int idcr_n)
+{
+	return __mfdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+			dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+			idcr_n);
+}
+
+/**
+ * mtsdram - write controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to write.
+ * @value: The data to write.
+ *
+ * This routine writes the provided data to the controller's specified
+ * indirect DCR register.
+ */
+static inline void
+mtsdram(const dcr_host_t *dcr_host, unsigned int idcr_n, u32 value)
+{
+	return __mtdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+			dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+			idcr_n,
+			value);
+}
+
+/**
+ * ppc4xx_edac_check_bank_error - check a bank for an ECC bank error
+ * @status: A pointer to the ECC status structure to check for an
+ *          ECC bank error.
+ * @bank: The bank to check for an ECC error.
+ *
+ * This routine determines whether the specified bank has an ECC
+ * error.
+ *
+ * Returns true if the specified bank has an ECC error; otherwise,
+ * false.
+ */
+static bool
+ppc4xx_edac_check_bank_error(const struct ppc4xx_ecc_status *status,
+			     unsigned int bank)
+{
+	switch (bank) {
+	case 0:
+		return status->ecces & SDRAM_ECCES_BK0ER;
+	case 1:
+		return status->ecces & SDRAM_ECCES_BK1ER;
+	default:
+		return false;
+	}
+}
+
+/**
+ * ppc4xx_edac_generate_bank_message - generate interpretted bank status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the bank message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BKNER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_bank_message(const struct mem_ctl_info *mci,
+				  const struct ppc4xx_ecc_status *status,
+				  char *buffer,
+				  size_t size)
+{
+	int n, total = 0;
+	unsigned int row, rows;
+
+	n = snprintf(buffer, size, "%s: Banks: ", mci->dev_name);
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+	for (rows = 0, row = 0; row < mci->nr_csrows; row++) {
+		if (ppc4xx_edac_check_bank_error(status, row)) {
+			n = snprintf(buffer, size, "%s%u",
+					(rows++ ? ", " : ""), row);
+
+			if (n < 0 || n >= size)
+				goto fail;
+
+			buffer += n;
+			size -= n;
+			total += n;
+		}
+	}
+
+	n = snprintf(buffer, size, "%s; ", rows ? "" : "None");
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+ fail:
+	return total;
+}
+
+/**
+ * ppc4xx_edac_generate_checkbit_message - generate interpretted checkbit message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the checkbit message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[CKBER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_checkbit_message(const struct mem_ctl_info *mci,
+				      const struct ppc4xx_ecc_status *status,
+				      char *buffer,
+				      size_t size)
+{
+	const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+	const char *ckber = NULL;
+
+	switch (status->ecces & SDRAM_ECCES_CKBER_MASK) {
+	case SDRAM_ECCES_CKBER_NONE:
+		ckber = "None";
+		break;
+	case SDRAM_ECCES_CKBER_32_ECC_0_3:
+		ckber = "ECC0:3";
+		break;
+	case SDRAM_ECCES_CKBER_32_ECC_4_8:
+		switch (mfsdram(&pdata->dcr_host, SDRAM_MCOPT1) &
+			SDRAM_MCOPT1_WDTH_MASK) {
+		case SDRAM_MCOPT1_WDTH_16:
+			ckber = "ECC0:3";
+			break;
+		case SDRAM_MCOPT1_WDTH_32:
+			ckber = "ECC4:8";
+			break;
+		default:
+			ckber = "Unknown";
+			break;
+		}
+		break;
+	case SDRAM_ECCES_CKBER_32_ECC_0_8:
+		ckber = "ECC0:8";
+		break;
+	default:
+		ckber = "Unknown";
+		break;
+	}
+
+	return snprintf(buffer, size, "Checkbit Error: %s", ckber);
+}
+
+/**
+ * ppc4xx_edac_generate_lane_message - generate interpretted byte lane message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the byte lane message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BNCE]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_lane_message(const struct mem_ctl_info *mci,
+				  const struct ppc4xx_ecc_status *status,
+				  char *buffer,
+				  size_t size)
+{
+	int n, total = 0;
+	unsigned int lane, lanes;
+	const unsigned int first_lane = 0;
+	const unsigned int lane_count = 16;
+
+	n = snprintf(buffer, size, "; Byte Lane Errors: ");
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+	for (lanes = 0, lane = first_lane; lane < lane_count; lane++) {
+		if ((status->ecces & SDRAM_ECCES_BNCE_ENCODE(lane)) != 0) {
+			n = snprintf(buffer, size,
+				     "%s%u",
+				     (lanes++ ? ", " : ""), lane);
+
+			if (n < 0 || n >= size)
+				goto fail;
+
+			buffer += n;
+			size -= n;
+			total += n;
+		}
+	}
+
+	n = snprintf(buffer, size, "%s; ", lanes ? "" : "None");
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+ fail:
+	return total;
+}
+
+/**
+ * ppc4xx_edac_generate_ecc_message - generate interpretted ECC status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the ECCES message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS register of
+ * the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_ecc_message(const struct mem_ctl_info *mci,
+				 const struct ppc4xx_ecc_status *status,
+				 char *buffer,
+				 size_t size)
+{
+	int n, total = 0;
+
+	n = ppc4xx_edac_generate_bank_message(mci, status, buffer, size);
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+	n = ppc4xx_edac_generate_checkbit_message(mci, status, buffer, size);
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+	n = ppc4xx_edac_generate_lane_message(mci, status, buffer, size);
+
+	if (n < 0 || n >= size)
+		goto fail;
+
+	buffer += n;
+	size -= n;
+	total += n;
+
+ fail:
+	return total;
+}
+
+/**
+ * ppc4xx_edac_generate_plb_message - generate interpretted PLB status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the PLB message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the PLB-related BESR
+ * and/or WMIRQ registers of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_plb_message(const struct mem_ctl_info *mci,
+				 const struct ppc4xx_ecc_status *status,
+				 char *buffer,
+				 size_t size)
+{
+	unsigned int master;
+	bool read;
+
+	if ((status->besr & SDRAM_BESR_MASK) == 0)
+		return 0;
+
+	if ((status->besr & SDRAM_BESR_M0ET_MASK) == SDRAM_BESR_M0ET_NONE)
+		return 0;
+
+	read = ((status->besr & SDRAM_BESR_M0RW_MASK) == SDRAM_BESR_M0RW_READ);
+
+	master = SDRAM_BESR_M0ID_DECODE(status->besr);
+
+	return snprintf(buffer, size,
+			"%s error w/ PLB master %u \"%s\"; ",
+			(read ? "Read" : "Write"),
+			master,
+			(((master >= SDRAM_PLB_M0ID_FIRST) &&
+			  (master <= SDRAM_PLB_M0ID_LAST)) ?
+			 ppc4xx_plb_masters[master] : "UNKNOWN"));
+}
+
+/**
+ * ppc4xx_edac_generate_message - generate interpretted status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ *       with the driver-unique message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ *          message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ *          message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the driver-unique
+ * EDAC report message from the specified ECC status.
+ */
+static void
+ppc4xx_edac_generate_message(const struct mem_ctl_info *mci,
+			     const struct ppc4xx_ecc_status *status,
+			     char *buffer,
+			     size_t size)
+{
+	int n;
+
+	if (buffer == NULL || size == 0)
+		return;
+
+	n = ppc4xx_edac_generate_ecc_message(mci, status, buffer, size);
+
+	if (n < 0 || n >= size)
+		return;
+
+	buffer += n;
+	size -= n;
+
+	ppc4xx_edac_generate_plb_message(mci, status, buffer, size);
+}
+
+#ifdef DEBUG
+/**
+ * ppc4xx_ecc_dump_status - dump controller ECC status registers
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the status being dumped.
+ * @status: A pointer to the ECC status structure to generate the
+ *          dump from.
+ *
+ * This routine dumps to the kernel log buffer the raw and
+ * interpretted specified ECC status.
+ */
+static void
+ppc4xx_ecc_dump_status(const struct mem_ctl_info *mci,
+		       const struct ppc4xx_ecc_status *status)
+{
+	char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+	ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+	ppc4xx_edac_mc_printk(KERN_INFO, mci,
+			      "\n"
+			      "\tECCES: 0x%08x\n"
+			      "\tWMIRQ: 0x%08x\n"
+			      "\tBESR:  0x%08x\n"
+			      "\tBEAR:  0x%08x%08x\n"
+			      "\t%s\n",
+			      status->ecces,
+			      status->wmirq,
+			      status->besr,
+			      status->bearh,
+			      status->bearl,
+			      message);
+}
+#endif /* DEBUG */
+
+/**
+ * ppc4xx_ecc_get_status - get controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the status being retrieved.
+ * @status: A pointer to the ECC status structure to populate the
+ *          ECC status with.
+ *
+ * This routine reads and masks, as appropriate, all the relevant
+ * status registers that deal with ibm,sdram-4xx-ddr2 ECC errors.
+ * While we read all of them, for correctable errors, we only expect
+ * to deal with ECCES. For uncorrectable errors, we expect to deal
+ * with all of them.
+ */
+static void
+ppc4xx_ecc_get_status(const struct mem_ctl_info *mci,
+		      struct ppc4xx_ecc_status *status)
+{
+	const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+	const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+	status->ecces = mfsdram(dcr_host, SDRAM_ECCES) & SDRAM_ECCES_MASK;
+	status->wmirq = mfsdram(dcr_host, SDRAM_WMIRQ) & SDRAM_WMIRQ_MASK;
+	status->besr  = mfsdram(dcr_host, SDRAM_BESR)  & SDRAM_BESR_MASK;
+	status->bearl = mfsdram(dcr_host, SDRAM_BEARL);
+	status->bearh = mfsdram(dcr_host, SDRAM_BEARH);
+}
+
+/**
+ * ppc4xx_ecc_clear_status - clear controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the status being cleared.
+ * @status: A pointer to the ECC status structure containing the
+ *          values to write to clear the ECC status.
+ *
+ * This routine clears--by writing the masked (as appropriate) status
+ * values back to--the status registers that deal with
+ * ibm,sdram-4xx-ddr2 ECC errors.
+ */
+static void
+ppc4xx_ecc_clear_status(const struct mem_ctl_info *mci,
+			const struct ppc4xx_ecc_status *status)
+{
+	const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+	const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+	mtsdram(dcr_host, SDRAM_ECCES,	status->ecces & SDRAM_ECCES_MASK);
+	mtsdram(dcr_host, SDRAM_WMIRQ,	status->wmirq & SDRAM_WMIRQ_MASK);
+	mtsdram(dcr_host, SDRAM_BESR,	status->besr & SDRAM_BESR_MASK);
+	mtsdram(dcr_host, SDRAM_BEARL,	0);
+	mtsdram(dcr_host, SDRAM_BEARH,	0);
+}
+
+/**
+ * ppc4xx_edac_handle_ce - handle controller correctable ECC error (CE)
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the correctable error being handled and reported.
+ * @status: A pointer to the ECC status structure associated with
+ *          the correctable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * correctable error. Per the aforementioned discussion, there's not
+ * enough status available to use the full EDAC correctable error
+ * interface, so we just pass driver-unique message to the "no info"
+ * interface.
+ */
+static void
+ppc4xx_edac_handle_ce(struct mem_ctl_info *mci,
+		      const struct ppc4xx_ecc_status *status)
+{
+	int row;
+	char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+	ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+	for (row = 0; row < mci->nr_csrows; row++)
+		if (ppc4xx_edac_check_bank_error(status, row))
+			edac_mc_handle_ce_no_info(mci, message);
+}
+
+/**
+ * ppc4xx_edac_handle_ue - handle controller uncorrectable ECC error (UE)
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the uncorrectable error being handled and
+ *       reported.
+ * @status: A pointer to the ECC status structure associated with
+ *          the uncorrectable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * uncorrectable error.
+ */
+static void
+ppc4xx_edac_handle_ue(struct mem_ctl_info *mci,
+		      const struct ppc4xx_ecc_status *status)
+{
+	const u64 bear = ((u64)status->bearh << 32 | status->bearl);
+	const unsigned long page = bear >> PAGE_SHIFT;
+	const unsigned long offset = bear & ~PAGE_MASK;
+	int row;
+	char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+	ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+	for (row = 0; row < mci->nr_csrows; row++)
+		if (ppc4xx_edac_check_bank_error(status, row))
+			edac_mc_handle_ue(mci, page, offset, row, message);
+}
+
+/**
+ * ppc4xx_edac_check - check controller for ECC errors
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the ibm,sdram-4xx-ddr2 controller being
+ *       checked.
+ *
+ * This routine is used to check and post ECC errors and is called by
+ * both the EDAC polling thread and this driver's CE and UE interrupt
+ * handler.
+ */
+static void
+ppc4xx_edac_check(struct mem_ctl_info *mci)
+{
+#ifdef DEBUG
+	static unsigned int count;
+#endif
+	struct ppc4xx_ecc_status status;
+
+	ppc4xx_ecc_get_status(mci, &status);
+
+#ifdef DEBUG
+	if (count++ % 30 == 0)
+		ppc4xx_ecc_dump_status(mci, &status);
+#endif
+
+	if (status.ecces & SDRAM_ECCES_UE)
+		ppc4xx_edac_handle_ue(mci, &status);
+
+	if (status.ecces & SDRAM_ECCES_CE)
+		ppc4xx_edac_handle_ce(mci, &status);
+
+	ppc4xx_ecc_clear_status(mci, &status);
+}
+
+/**
+ * ppc4xx_edac_isr - SEC (CE) and DED (UE) interrupt service routine
+ * @irq:    The virtual interrupt number being serviced.
+ * @dev_id: A pointer to the EDAC memory controller instance
+ *          associated with the interrupt being handled.
+ *
+ * This routine implements the interrupt handler for both correctable
+ * (CE) and uncorrectable (UE) ECC errors for the ibm,sdram-4xx-ddr2
+ * controller. It simply calls through to the same routine used during
+ * polling to check, report and clear the ECC status.
+ *
+ * Unconditionally returns IRQ_HANDLED.
+ */
+static irqreturn_t
+ppc4xx_edac_isr(int irq, void *dev_id)
+{
+	struct mem_ctl_info *mci = dev_id;
+
+	ppc4xx_edac_check(mci);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ppc4xx_edac_get_dtype - return the controller memory width
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ *          currently set for the controller, from which the width
+ *          is derived.
+ *
+ * This routine returns the EDAC device type width appropriate for the
+ * current controller configuration.
+ *
+ * TODO: This needs to be conditioned dynamically through feature
+ * flags or some such when other controller variants are supported as
+ * the 405EX[r] is 16-/32-bit and the others are 32-/64-bit with the
+ * 16- and 64-bit field definition/value/enumeration (b1) overloaded
+ * among them.
+ *
+ * Returns a device type width enumeration.
+ */
+static enum dev_type __devinit
+ppc4xx_edac_get_dtype(u32 mcopt1)
+{
+	switch (mcopt1 & SDRAM_MCOPT1_WDTH_MASK) {
+	case SDRAM_MCOPT1_WDTH_16:
+		return DEV_X2;
+	case SDRAM_MCOPT1_WDTH_32:
+		return DEV_X4;
+	default:
+		return DEV_UNKNOWN;
+	}
+}
+
+/**
+ * ppc4xx_edac_get_mtype - return controller memory type
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ *          currently set for the controller, from which the memory type
+ *          is derived.
+ *
+ * This routine returns the EDAC memory type appropriate for the
+ * current controller configuration.
+ *
+ * Returns a memory type enumeration.
+ */
+static enum mem_type __devinit
+ppc4xx_edac_get_mtype(u32 mcopt1)
+{
+	bool rden = ((mcopt1 & SDRAM_MCOPT1_RDEN_MASK) == SDRAM_MCOPT1_RDEN);
+
+	switch (mcopt1 & SDRAM_MCOPT1_DDR_TYPE_MASK) {
+	case SDRAM_MCOPT1_DDR2_TYPE:
+		return rden ? MEM_RDDR2 : MEM_DDR2;
+	case SDRAM_MCOPT1_DDR1_TYPE:
+		return rden ? MEM_RDDR : MEM_DDR;
+	default:
+		return MEM_UNKNOWN;
+	}
+}
+
+/**
+ * ppc4xx_edac_init_csrows - intialize driver instance rows
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the ibm,sdram-4xx-ddr2 controller for which
+ *       the csrows (i.e. banks/ranks) are being initialized.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ *          currently set for the controller, from which bank width
+ *          and memory typ information is derived.
+ *
+ * This routine intializes the virtual "chip select rows" associated
+ * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2
+ * controller bank/rank is mapped to a row.
+ *
+ * Returns 0 if OK; otherwise, -EINVAL if the memory bank size
+ * configuration cannot be determined.
+ */
+static int __devinit
+ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1)
+{
+	const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+	int status = 0;
+	enum mem_type mtype;
+	enum dev_type dtype;
+	enum edac_type edac_mode;
+	int row;
+	u32 mbxcf, size;
+	static u32 ppc4xx_last_page;
+
+	/* Establish the memory type and width */
+
+	mtype = ppc4xx_edac_get_mtype(mcopt1);
+	dtype = ppc4xx_edac_get_dtype(mcopt1);
+
+	/* Establish EDAC mode */
+
+	if (mci->edac_cap & EDAC_FLAG_SECDED)
+		edac_mode = EDAC_SECDED;
+	else if (mci->edac_cap & EDAC_FLAG_EC)
+		edac_mode = EDAC_EC;
+	else
+		edac_mode = EDAC_NONE;
+
+	/*
+	 * Initialize each chip select row structure which correspond
+	 * 1:1 with a controller bank/rank.
+	 */
+
+	for (row = 0; row < mci->nr_csrows; row++) {
+		struct csrow_info *csi = &mci->csrows[row];
+
+		/*
+		 * Get the configuration settings for this
+		 * row/bank/rank and skip disabled banks.
+		 */
+
+		mbxcf = mfsdram(&pdata->dcr_host, SDRAM_MBXCF(row));
+
+		if ((mbxcf & SDRAM_MBCF_BE_MASK) != SDRAM_MBCF_BE_ENABLE)
+			continue;
+
+		/* Map the bank configuration size setting to pages. */
+
+		size = mbxcf & SDRAM_MBCF_SZ_MASK;
+
+		switch (size) {
+		case SDRAM_MBCF_SZ_4MB:
+		case SDRAM_MBCF_SZ_8MB:
+		case SDRAM_MBCF_SZ_16MB:
+		case SDRAM_MBCF_SZ_32MB:
+		case SDRAM_MBCF_SZ_64MB:
+		case SDRAM_MBCF_SZ_128MB:
+		case SDRAM_MBCF_SZ_256MB:
+		case SDRAM_MBCF_SZ_512MB:
+		case SDRAM_MBCF_SZ_1GB:
+		case SDRAM_MBCF_SZ_2GB:
+		case SDRAM_MBCF_SZ_4GB:
+		case SDRAM_MBCF_SZ_8GB:
+			csi->nr_pages = SDRAM_MBCF_SZ_TO_PAGES(size);
+			break;
+		default:
+			ppc4xx_edac_mc_printk(KERN_ERR, mci,
+					      "Unrecognized memory bank %d "
+					      "size 0x%08x\n",
+					      row, SDRAM_MBCF_SZ_DECODE(size));
+			status = -EINVAL;
+			goto done;
+		}
+
+		csi->first_page = ppc4xx_last_page;
+		csi->last_page	= csi->first_page + csi->nr_pages - 1;
+		csi->page_mask	= 0;
+
+		/*
+		 * It's unclear exactly what grain should be set to
+		 * here. The SDRAM_ECCES register allows resolution of
+		 * an error down to a nibble which would potentially
+		 * argue for a grain of '1' byte, even though we only
+		 * know the associated address for uncorrectable
+		 * errors. This value is not used at present for
+		 * anything other than error reporting so getting it
+		 * wrong should be of little consequence. Other
+		 * possible values would be the PLB width (16), the
+		 * page size (PAGE_SIZE) or the memory width (2 or 4).
+		 */
+
+		csi->grain	= 1;
+
+		csi->mtype	= mtype;
+		csi->dtype	= dtype;
+
+		csi->edac_mode	= edac_mode;
+
+		ppc4xx_last_page += csi->nr_pages;
+	}
+
+ done:
+	return status;
+}
+
+/**
+ * ppc4xx_edac_mc_init - intialize driver instance
+ * @mci: A pointer to the EDAC memory controller instance being
+ *       initialized.
+ * @op: A pointer to the OpenFirmware device tree node associated
+ *      with the controller this EDAC instance is bound to.
+ * @match: A pointer to the OpenFirmware device tree match
+ *         information associated with the controller this EDAC instance
+ *         is bound to.
+ * @dcr_host: A pointer to the DCR data containing the DCR mapping
+ *            for this controller instance.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ *          currently set for the controller, from which ECC capabilities
+ *          and scrub mode are derived.
+ *
+ * This routine performs initialization of the EDAC memory controller
+ * instance and related driver-private data associated with the
+ * ibm,sdram-4xx-ddr2 memory controller the instance is bound to.
+ *
+ * Returns 0 if OK; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_mc_init(struct mem_ctl_info *mci,
+		    struct of_device *op,
+		    const struct of_device_id *match,
+		    const dcr_host_t *dcr_host,
+		    u32 mcopt1)
+{
+	int status = 0;
+	const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+	struct ppc4xx_edac_pdata *pdata = NULL;
+	const struct device_node *np = op->node;
+
+	if (match == NULL)
+		return -EINVAL;
+
+	/* Initial driver pointers and private data */
+
+	mci->dev		= &op->dev;
+
+	dev_set_drvdata(mci->dev, mci);
+
+	pdata			= mci->pvt_info;
+
+	pdata->dcr_host		= *dcr_host;
+	pdata->irqs.sec		= NO_IRQ;
+	pdata->irqs.ded		= NO_IRQ;
+
+	/* Initialize controller capabilities and configuration */
+
+	mci->mtype_cap		= (MEM_FLAG_DDR | MEM_FLAG_RDDR |
+				   MEM_FLAG_DDR2 | MEM_FLAG_RDDR2);
+
+	mci->edac_ctl_cap	= (EDAC_FLAG_NONE |
+				   EDAC_FLAG_EC |
+				   EDAC_FLAG_SECDED);
+
+	mci->scrub_cap		= SCRUB_NONE;
+	mci->scrub_mode		= SCRUB_NONE;
+
+	/*
+	 * Update the actual capabilites based on the MCOPT1[MCHK]
+	 * settings. Scrubbing is only useful if reporting is enabled.
+	 */
+
+	switch (memcheck) {
+	case SDRAM_MCOPT1_MCHK_CHK:
+		mci->edac_cap	= EDAC_FLAG_EC;
+		break;
+	case SDRAM_MCOPT1_MCHK_CHK_REP:
+		mci->edac_cap	= (EDAC_FLAG_EC | EDAC_FLAG_SECDED);
+		mci->scrub_mode	= SCRUB_SW_SRC;
+		break;
+	default:
+		mci->edac_cap	= EDAC_FLAG_NONE;
+		break;
+	}
+
+	/* Initialize strings */
+
+	mci->mod_name		= PPC4XX_EDAC_MODULE_NAME;
+	mci->mod_ver		= PPC4XX_EDAC_MODULE_REVISION;
+	mci->ctl_name		= match->compatible,
+	mci->dev_name		= np->full_name;
+
+	/* Initialize callbacks */
+
+	mci->edac_check		= ppc4xx_edac_check;
+	mci->ctl_page_to_phys	= NULL;
+
+	/* Initialize chip select rows */
+
+	status = ppc4xx_edac_init_csrows(mci, mcopt1);
+
+	if (status)
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Failed to initialize rows!\n");
+
+	return status;
+}
+
+/**
+ * ppc4xx_edac_register_irq - setup and register controller interrupts
+ * @op: A pointer to the OpenFirmware device tree node associated
+ *      with the controller this EDAC instance is bound to.
+ * @mci: A pointer to the EDAC memory controller instance
+ *       associated with the ibm,sdram-4xx-ddr2 controller for which
+ *       interrupts are being registered.
+ *
+ * This routine parses the correctable (CE) and uncorrectable error (UE)
+ * interrupts from the device tree node and maps and assigns them to
+ * the associated EDAC memory controller instance.
+ *
+ * Returns 0 if OK; otherwise, -ENODEV if the interrupts could not be
+ * mapped and assigned.
+ */
+static int __devinit
+ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci)
+{
+	int status = 0;
+	int ded_irq, sec_irq;
+	struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+	struct device_node *np = op->node;
+
+	ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX);
+	sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX);
+
+	if (ded_irq == NO_IRQ || sec_irq == NO_IRQ) {
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Unable to map interrupts.\n");
+		status = -ENODEV;
+		goto fail;
+	}
+
+	status = request_irq(ded_irq,
+			     ppc4xx_edac_isr,
+			     IRQF_DISABLED,
+			     "[EDAC] MC ECCDED",
+			     mci);
+
+	if (status < 0) {
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Unable to request irq %d for ECC DED",
+				      ded_irq);
+		status = -ENODEV;
+		goto fail1;
+	}
+
+	status = request_irq(sec_irq,
+			     ppc4xx_edac_isr,
+			     IRQF_DISABLED,
+			     "[EDAC] MC ECCSEC",
+			     mci);
+
+	if (status < 0) {
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Unable to request irq %d for ECC SEC",
+				      sec_irq);
+		status = -ENODEV;
+		goto fail2;
+	}
+
+	ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCDED irq is %d\n", ded_irq);
+	ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCSEC irq is %d\n", sec_irq);
+
+	pdata->irqs.ded = ded_irq;
+	pdata->irqs.sec = sec_irq;
+
+	return 0;
+
+ fail2:
+	free_irq(sec_irq, mci);
+
+ fail1:
+	free_irq(ded_irq, mci);
+
+ fail:
+	return status;
+}
+
+/**
+ * ppc4xx_edac_map_dcrs - locate and map controller registers
+ * @np: A pointer to the device tree node containing the DCR
+ *      resources to map.
+ * @dcr_host: A pointer to the DCR data to populate with the
+ *            DCR mapping.
+ *
+ * This routine attempts to locate in the device tree and map the DCR
+ * register resources associated with the controller's indirect DCR
+ * address and data windows.
+ *
+ * Returns 0 if the DCRs were successfully mapped; otherwise, < 0 on
+ * error.
+ */
+static int __devinit
+ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host)
+{
+	unsigned int dcr_base, dcr_len;
+
+	if (np == NULL || dcr_host == NULL)
+		return -EINVAL;
+
+	/* Get the DCR resource extent and sanity check the values. */
+
+	dcr_base = dcr_resource_start(np, 0);
+	dcr_len = dcr_resource_len(np, 0);
+
+	if (dcr_base == 0 || dcr_len == 0) {
+		ppc4xx_edac_printk(KERN_ERR,
+				   "Failed to obtain DCR property.\n");
+		return -ENODEV;
+	}
+
+	if (dcr_len != SDRAM_DCR_RESOURCE_LEN) {
+		ppc4xx_edac_printk(KERN_ERR,
+				   "Unexpected DCR length %d, expected %d.\n",
+				   dcr_len, SDRAM_DCR_RESOURCE_LEN);
+		return -ENODEV;
+	}
+
+	/*  Attempt to map the DCR extent. */
+
+	*dcr_host = dcr_map(np, dcr_base, dcr_len);
+
+	if (!DCR_MAP_OK(*dcr_host)) {
+		ppc4xx_edac_printk(KERN_INFO, "Failed to map DCRs.\n");
+		    return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * ppc4xx_edac_probe - check controller and bind driver
+ * @op: A pointer to the OpenFirmware device tree node associated
+ *      with the controller being probed for driver binding.
+ * @match: A pointer to the OpenFirmware device tree match
+ *         information associated with the controller being probed
+ *         for driver binding.
+ *
+ * This routine probes a specific ibm,sdram-4xx-ddr2 controller
+ * instance for binding with the driver.
+ *
+ * Returns 0 if the controller instance was successfully bound to the
+ * driver; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match)
+{
+	int status = 0;
+	u32 mcopt1, memcheck;
+	dcr_host_t dcr_host;
+	const struct device_node *np = op->node;
+	struct mem_ctl_info *mci = NULL;
+	static int ppc4xx_edac_instance;
+
+	/*
+	 * At this point, we only support the controller realized on
+	 * the AMCC PPC 405EX[r]. Reject anything else.
+	 */
+
+	if (!of_device_is_compatible(np, "ibm,sdram-405ex") &&
+	    !of_device_is_compatible(np, "ibm,sdram-405exr")) {
+		ppc4xx_edac_printk(KERN_NOTICE,
+				   "Only the PPC405EX[r] is supported.\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Next, get the DCR property and attempt to map it so that we
+	 * can probe the controller.
+	 */
+
+	status = ppc4xx_edac_map_dcrs(np, &dcr_host);
+
+	if (status)
+		return status;
+
+	/*
+	 * First determine whether ECC is enabled at all. If not,
+	 * there is no useful checking or monitoring that can be done
+	 * for this controller.
+	 */
+
+	mcopt1 = mfsdram(&dcr_host, SDRAM_MCOPT1);
+	memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+
+	if (memcheck == SDRAM_MCOPT1_MCHK_NON) {
+		ppc4xx_edac_printk(KERN_INFO, "%s: No ECC memory detected or "
+				   "ECC is disabled.\n", np->full_name);
+		status = -ENODEV;
+		goto done;
+	}
+
+	/*
+	 * At this point, we know ECC is enabled, allocate an EDAC
+	 * controller instance and perform the appropriate
+	 * initialization.
+	 */
+
+	mci = edac_mc_alloc(sizeof(struct ppc4xx_edac_pdata),
+			    ppc4xx_edac_nr_csrows,
+			    ppc4xx_edac_nr_chans,
+			    ppc4xx_edac_instance);
+
+	if (mci == NULL) {
+		ppc4xx_edac_printk(KERN_ERR, "%s: "
+				   "Failed to allocate EDAC MC instance!\n",
+				   np->full_name);
+		status = -ENOMEM;
+		goto done;
+	}
+
+	status = ppc4xx_edac_mc_init(mci, op, match, &dcr_host, mcopt1);
+
+	if (status) {
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Failed to initialize instance!\n");
+		goto fail;
+	}
+
+	/*
+	 * We have a valid, initialized EDAC instance bound to the
+	 * controller. Attempt to register it with the EDAC subsystem
+	 * and, if necessary, register interrupts.
+	 */
+
+	if (edac_mc_add_mc(mci)) {
+		ppc4xx_edac_mc_printk(KERN_ERR, mci,
+				      "Failed to add instance!\n");
+		status = -ENODEV;
+		goto fail;
+	}
+
+	if (edac_op_state == EDAC_OPSTATE_INT) {
+		status = ppc4xx_edac_register_irq(op, mci);
+
+		if (status)
+			goto fail1;
+	}
+
+	ppc4xx_edac_instance++;
+
+	return 0;
+
+ fail1:
+	edac_mc_del_mc(mci->dev);
+
+ fail:
+	edac_mc_free(mci);
+
+ done:
+	return status;
+}
+
+/**
+ * ppc4xx_edac_remove - unbind driver from controller
+ * @op: A pointer to the OpenFirmware device tree node associated
+ *      with the controller this EDAC instance is to be unbound/removed
+ *      from.
+ *
+ * This routine unbinds the EDAC memory controller instance associated
+ * with the specified ibm,sdram-4xx-ddr2 controller described by the
+ * OpenFirmware device tree node passed as a parameter.
+ *
+ * Unconditionally returns 0.
+ */
+static int
+ppc4xx_edac_remove(struct of_device *op)
+{
+	struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
+	struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+
+	if (edac_op_state == EDAC_OPSTATE_INT) {
+		free_irq(pdata->irqs.sec, mci);
+		free_irq(pdata->irqs.ded, mci);
+	}
+
+	dcr_unmap(pdata->dcr_host, SDRAM_DCR_RESOURCE_LEN);
+
+	edac_mc_del_mc(mci->dev);
+	edac_mc_free(mci);
+
+	return 0;
+}
+
+/**
+ * ppc4xx_edac_opstate_init - initialize EDAC reporting method
+ *
+ * This routine ensures that the EDAC memory controller reporting
+ * method is mapped to a sane value as the EDAC core defines the value
+ * to EDAC_OPSTATE_INVAL by default. We don't call the global
+ * opstate_init as that defaults to polling and we want interrupt as
+ * the default.
+ */
+static inline void __init
+ppc4xx_edac_opstate_init(void)
+{
+	switch (edac_op_state) {
+	case EDAC_OPSTATE_POLL:
+	case EDAC_OPSTATE_INT:
+		break;
+	default:
+		edac_op_state = EDAC_OPSTATE_INT;
+		break;
+	}
+
+	ppc4xx_edac_printk(KERN_INFO, "Reporting type: %s\n",
+			   ((edac_op_state == EDAC_OPSTATE_POLL) ?
+			    EDAC_OPSTATE_POLL_STR :
+			    ((edac_op_state == EDAC_OPSTATE_INT) ?
+			     EDAC_OPSTATE_INT_STR :
+			     EDAC_OPSTATE_UNKNOWN_STR)));
+}
+
+/**
+ * ppc4xx_edac_init - driver/module insertion entry point
+ *
+ * This routine is the driver/module insertion entry point. It
+ * initializes the EDAC memory controller reporting state and
+ * registers the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static int __init
+ppc4xx_edac_init(void)
+{
+	ppc4xx_edac_printk(KERN_INFO, PPC4XX_EDAC_MODULE_REVISION "\n");
+
+	ppc4xx_edac_opstate_init();
+
+	return of_register_platform_driver(&ppc4xx_edac_driver);
+}
+
+/**
+ * ppc4xx_edac_exit - driver/module removal entry point
+ *
+ * This routine is the driver/module removal entry point. It
+ * unregisters the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static void __exit
+ppc4xx_edac_exit(void)
+{
+	of_unregister_platform_driver(&ppc4xx_edac_driver);
+}
+
+module_init(ppc4xx_edac_init);
+module_exit(ppc4xx_edac_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Grant Erickson <gerickson@nuovations.com>");
+MODULE_DESCRIPTION("EDAC MC Driver for the PPC4xx IBM DDR2 Memory Controller");
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting State: "
+		 "0=" EDAC_OPSTATE_POLL_STR ", 2=" EDAC_OPSTATE_INT_STR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/edac/ppc4xx_edac.h linux-libre-2.6.30-gnu1/drivers/edac/ppc4xx_edac.h
--- linux-libre-2.6.29-gnu1/drivers/edac/ppc4xx_edac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/edac/ppc4xx_edac.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ *   Grant Erickson <gerickson@nuovations.com>
+ *
+ * This file defines processor mnemonics for accessing and managing
+ * the IBM DDR1/DDR2 ECC controller found in the 405EX[r], 440SP,
+ * 440SPe, 460EX, 460GT and 460SX.
+ *
+ * This program is free software; 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 __PPC4XX_EDAC_H
+#define __PPC4XX_EDAC_H
+
+#include <linux/types.h>
+
+/*
+ * Macro for generating register field mnemonics
+ */
+#define PPC_REG_BITS			32
+#define PPC_REG_VAL(bit, val)		((val) << ((PPC_REG_BITS - 1) - (bit)))
+#define PPC_REG_DECODE(bit, val)	((val) >> ((PPC_REG_BITS - 1) - (bit)))
+
+/*
+ * IBM 4xx DDR1/DDR2 SDRAM memory controller registers (at least those
+ * relevant to ECC)
+ */
+#define SDRAM_BESR			0x00	/* Error status (read/clear) */
+#define SDRAM_BESRT			0x01	/* Error statuss (test/set)  */
+#define SDRAM_BEARL			0x02	/* Error address low	     */
+#define SDRAM_BEARH			0x03	/* Error address high	     */
+#define SDRAM_WMIRQ			0x06	/* Write master (read/clear) */
+#define SDRAM_WMIRQT			0x07	/* Write master (test/set)   */
+#define SDRAM_MCOPT1			0x20	/* Controller options 1	     */
+#define SDRAM_MBXCF_BASE		0x40	/* Bank n configuration base */
+#define	SDRAM_MBXCF(n)			(SDRAM_MBXCF_BASE + (4 * (n)))
+#define SDRAM_MB0CF			SDRAM_MBXCF(0)
+#define SDRAM_MB1CF			SDRAM_MBXCF(1)
+#define SDRAM_MB2CF			SDRAM_MBXCF(2)
+#define SDRAM_MB3CF			SDRAM_MBXCF(3)
+#define SDRAM_ECCCR			0x98	/* ECC error status	     */
+#define SDRAM_ECCES			SDRAM_ECCCR
+
+/*
+ * PLB Master IDs
+ */
+#define	SDRAM_PLB_M0ID_FIRST		0
+#define	SDRAM_PLB_M0ID_ICU		SDRAM_PLB_M0ID_FIRST
+#define	SDRAM_PLB_M0ID_PCIE0		1
+#define	SDRAM_PLB_M0ID_PCIE1		2
+#define	SDRAM_PLB_M0ID_DMA		3
+#define	SDRAM_PLB_M0ID_DCU		4
+#define	SDRAM_PLB_M0ID_OPB		5
+#define	SDRAM_PLB_M0ID_MAL		6
+#define	SDRAM_PLB_M0ID_SEC		7
+#define	SDRAM_PLB_M0ID_AHB		8
+#define SDRAM_PLB_M0ID_LAST		SDRAM_PLB_M0ID_AHB
+#define SDRAM_PLB_M0ID_COUNT		(SDRAM_PLB_M0ID_LAST - \
+					 SDRAM_PLB_M0ID_FIRST + 1)
+
+/*
+ * Memory Controller Bus Error Status Register
+ */
+#define SDRAM_BESR_MASK			PPC_REG_VAL(7, 0xFF)
+#define SDRAM_BESR_M0ID_MASK		PPC_REG_VAL(3, 0xF)
+#define	SDRAM_BESR_M0ID_DECODE(n)	PPC_REG_DECODE(3, n)
+#define SDRAM_BESR_M0ID_ICU		PPC_REG_VAL(3, SDRAM_PLB_M0ID_ICU)
+#define SDRAM_BESR_M0ID_PCIE0		PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE0)
+#define SDRAM_BESR_M0ID_PCIE1		PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE1)
+#define SDRAM_BESR_M0ID_DMA		PPC_REG_VAL(3, SDRAM_PLB_M0ID_DMA)
+#define SDRAM_BESR_M0ID_DCU		PPC_REG_VAL(3, SDRAM_PLB_M0ID_DCU)
+#define SDRAM_BESR_M0ID_OPB		PPC_REG_VAL(3, SDRAM_PLB_M0ID_OPB)
+#define SDRAM_BESR_M0ID_MAL		PPC_REG_VAL(3, SDRAM_PLB_M0ID_MAL)
+#define SDRAM_BESR_M0ID_SEC		PPC_REG_VAL(3, SDRAM_PLB_M0ID_SEC)
+#define SDRAM_BESR_M0ID_AHB		PPC_REG_VAL(3, SDRAM_PLB_M0ID_AHB)
+#define SDRAM_BESR_M0ET_MASK		PPC_REG_VAL(6, 0x7)
+#define SDRAM_BESR_M0ET_NONE		PPC_REG_VAL(6, 0)
+#define SDRAM_BESR_M0ET_ECC		PPC_REG_VAL(6, 1)
+#define SDRAM_BESR_M0RW_MASK		PPC_REG_VAL(7, 1)
+#define SDRAM_BESR_M0RW_WRITE		PPC_REG_VAL(7, 0)
+#define SDRAM_BESR_M0RW_READ		PPC_REG_VAL(7, 1)
+
+/*
+ * Memory Controller PLB Write Master Interrupt Register
+ */
+#define SDRAM_WMIRQ_MASK		PPC_REG_VAL(8, 0x1FF)
+#define	SDRAM_WMIRQ_ENCODE(id)		PPC_REG_VAL((id % \
+						     SDRAM_PLB_M0ID_COUNT), 1)
+#define SDRAM_WMIRQ_ICU			PPC_REG_VAL(SDRAM_PLB_M0ID_ICU, 1)
+#define SDRAM_WMIRQ_PCIE0		PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE0, 1)
+#define SDRAM_WMIRQ_PCIE1		PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE1, 1)
+#define SDRAM_WMIRQ_DMA			PPC_REG_VAL(SDRAM_PLB_M0ID_DMA, 1)
+#define SDRAM_WMIRQ_DCU			PPC_REG_VAL(SDRAM_PLB_M0ID_DCU, 1)
+#define SDRAM_WMIRQ_OPB			PPC_REG_VAL(SDRAM_PLB_M0ID_OPB, 1)
+#define SDRAM_WMIRQ_MAL			PPC_REG_VAL(SDRAM_PLB_M0ID_MAL, 1)
+#define SDRAM_WMIRQ_SEC			PPC_REG_VAL(SDRAM_PLB_M0ID_SEC, 1)
+#define SDRAM_WMIRQ_AHB			PPC_REG_VAL(SDRAM_PLB_M0ID_AHB, 1)
+
+/*
+ * Memory Controller Options 1 Register
+ */
+#define SDRAM_MCOPT1_MCHK_MASK	    PPC_REG_VAL(3, 0x3)	 /* ECC mask	     */
+#define SDRAM_MCOPT1_MCHK_NON	    PPC_REG_VAL(3, 0x0)	 /* No ECC gen	     */
+#define SDRAM_MCOPT1_MCHK_GEN	    PPC_REG_VAL(3, 0x2)	 /* ECC gen	     */
+#define SDRAM_MCOPT1_MCHK_CHK	    PPC_REG_VAL(3, 0x1)	 /* ECC gen and chk  */
+#define SDRAM_MCOPT1_MCHK_CHK_REP   PPC_REG_VAL(3, 0x3)	 /* ECC gen/chk/rpt  */
+#define SDRAM_MCOPT1_MCHK_DECODE(n) ((((u32)(n)) >> 28) & 0x3)
+#define SDRAM_MCOPT1_RDEN_MASK	    PPC_REG_VAL(4, 0x1)	 /* Rgstrd DIMM mask */
+#define SDRAM_MCOPT1_RDEN	    PPC_REG_VAL(4, 0x1)	 /* Rgstrd DIMM enbl */
+#define SDRAM_MCOPT1_WDTH_MASK	    PPC_REG_VAL(7, 0x1)	 /* Width mask	     */
+#define SDRAM_MCOPT1_WDTH_32	    PPC_REG_VAL(7, 0x0)	 /* 32 bits	     */
+#define SDRAM_MCOPT1_WDTH_16	    PPC_REG_VAL(7, 0x1)	 /* 16 bits	     */
+#define SDRAM_MCOPT1_DDR_TYPE_MASK  PPC_REG_VAL(11, 0x1) /* DDR type mask    */
+#define SDRAM_MCOPT1_DDR1_TYPE	    PPC_REG_VAL(11, 0x0) /* DDR1 type	     */
+#define SDRAM_MCOPT1_DDR2_TYPE	    PPC_REG_VAL(11, 0x1) /* DDR2 type	     */
+
+/*
+ * Memory Bank 0 - n Configuration Register
+ */
+#define SDRAM_MBCF_BA_MASK		PPC_REG_VAL(12, 0x1FFF)
+#define SDRAM_MBCF_SZ_MASK		PPC_REG_VAL(19, 0xF)
+#define SDRAM_MBCF_SZ_DECODE(mbxcf)	PPC_REG_DECODE(19, mbxcf)
+#define SDRAM_MBCF_SZ_4MB		PPC_REG_VAL(19, 0x0)
+#define SDRAM_MBCF_SZ_8MB		PPC_REG_VAL(19, 0x1)
+#define SDRAM_MBCF_SZ_16MB		PPC_REG_VAL(19, 0x2)
+#define SDRAM_MBCF_SZ_32MB		PPC_REG_VAL(19, 0x3)
+#define SDRAM_MBCF_SZ_64MB		PPC_REG_VAL(19, 0x4)
+#define SDRAM_MBCF_SZ_128MB		PPC_REG_VAL(19, 0x5)
+#define SDRAM_MBCF_SZ_256MB		PPC_REG_VAL(19, 0x6)
+#define SDRAM_MBCF_SZ_512MB		PPC_REG_VAL(19, 0x7)
+#define SDRAM_MBCF_SZ_1GB		PPC_REG_VAL(19, 0x8)
+#define SDRAM_MBCF_SZ_2GB		PPC_REG_VAL(19, 0x9)
+#define SDRAM_MBCF_SZ_4GB		PPC_REG_VAL(19, 0xA)
+#define SDRAM_MBCF_SZ_8GB		PPC_REG_VAL(19, 0xB)
+#define SDRAM_MBCF_AM_MASK		PPC_REG_VAL(23, 0xF)
+#define SDRAM_MBCF_AM_MODE0		PPC_REG_VAL(23, 0x0)
+#define SDRAM_MBCF_AM_MODE1		PPC_REG_VAL(23, 0x1)
+#define SDRAM_MBCF_AM_MODE2		PPC_REG_VAL(23, 0x2)
+#define SDRAM_MBCF_AM_MODE3		PPC_REG_VAL(23, 0x3)
+#define SDRAM_MBCF_AM_MODE4		PPC_REG_VAL(23, 0x4)
+#define SDRAM_MBCF_AM_MODE5		PPC_REG_VAL(23, 0x5)
+#define SDRAM_MBCF_AM_MODE6		PPC_REG_VAL(23, 0x6)
+#define SDRAM_MBCF_AM_MODE7		PPC_REG_VAL(23, 0x7)
+#define SDRAM_MBCF_AM_MODE8		PPC_REG_VAL(23, 0x8)
+#define SDRAM_MBCF_AM_MODE9		PPC_REG_VAL(23, 0x9)
+#define SDRAM_MBCF_BE_MASK		PPC_REG_VAL(31, 0x1)
+#define SDRAM_MBCF_BE_DISABLE		PPC_REG_VAL(31, 0x0)
+#define SDRAM_MBCF_BE_ENABLE		PPC_REG_VAL(31, 0x1)
+
+/*
+ * ECC Error Status
+ */
+#define SDRAM_ECCES_MASK		PPC_REG_VAL(21, 0x3FFFFF)
+#define SDRAM_ECCES_BNCE_MASK		PPC_REG_VAL(15, 0xFFFF)
+#define SDRAM_ECCES_BNCE_ENCODE(lane)	PPC_REG_VAL(((lane) & 0xF), 1)
+#define SDRAM_ECCES_CKBER_MASK		PPC_REG_VAL(17, 0x3)
+#define SDRAM_ECCES_CKBER_NONE		PPC_REG_VAL(17, 0)
+#define SDRAM_ECCES_CKBER_16_ECC_0_3	PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_3	PPC_REG_VAL(17, 1)
+#define SDRAM_ECCES_CKBER_32_ECC_4_8	PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_8	PPC_REG_VAL(17, 3)
+#define SDRAM_ECCES_CE			PPC_REG_VAL(18, 1)
+#define SDRAM_ECCES_UE			PPC_REG_VAL(19, 1)
+#define SDRAM_ECCES_BKNER_MASK		PPC_REG_VAL(21, 0x3)
+#define SDRAM_ECCES_BK0ER		PPC_REG_VAL(20, 1)
+#define SDRAM_ECCES_BK1ER		PPC_REG_VAL(21, 1)
+
+#endif /* __PPC4XX_EDAC_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/eisa/eisa-bus.c linux-libre-2.6.30-gnu1/drivers/eisa/eisa-bus.c
--- linux-libre-2.6.29-gnu1/drivers/eisa/eisa-bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/eisa/eisa-bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,7 +200,7 @@ static int __init eisa_init_device (stru
 	edev->dev.bus = &eisa_bus_type;
 	edev->dev.dma_mask = &edev->dma_mask;
 	edev->dev.coherent_dma_mask = edev->dma_mask;
-	sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
+	dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot);
 
 	for (i = 0; i < EISA_MAX_RESOURCES; i++) {
 #ifdef CONFIG_EISA_NAMES
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eis
 	struct eisa_device *edev;
 
         printk (KERN_INFO "EISA: Probing bus %d at %s\n",
-		root->bus_nr, root->dev->bus_id);
+		root->bus_nr, dev_name(root->dev));
 
 	/* First try to get hold of slot 0. If there is no device
 	 * here, simply fail, unless root->force_probe is set. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/eisa/Kconfig linux-libre-2.6.30-gnu1/drivers/eisa/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/eisa/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/eisa/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 #
 config EISA_VLB_PRIMING
 	bool "Vesa Local Bus priming"
-	depends on X86_PC && EISA
+	depends on X86 && EISA
 	default n
 	---help---
 	  Activate this option if your system contains a Vesa Local
@@ -24,11 +24,11 @@ config EISA_PCI_EISA
 	  When in doubt, say Y.
 
 # Using EISA_VIRTUAL_ROOT on something other than an Alpha or
-# an X86_PC may lead to crashes...
+# an X86 may lead to crashes...
 
 config EISA_VIRTUAL_ROOT
 	bool "EISA virtual root device"
-	depends on EISA && (ALPHA || X86_PC)
+	depends on EISA && (ALPHA || X86)
 	default y
 	---help---
 	  Activate this option if your system only have EISA bus
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-card.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-card.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-card.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-card.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,8 +63,7 @@ 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 u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
 {
 	struct fw_descriptor *desc;
 	static u32 config_rom[256];
@@ -128,8 +127,7 @@ generate_config_rom(struct fw_card *card
 	return config_rom;
 }
 
-static void
-update_config_roms(void)
+static void update_config_roms(void)
 {
 	struct fw_card *card;
 	u32 *config_rom;
@@ -141,8 +139,7 @@ update_config_roms(void)
 	}
 }
 
-int
-fw_core_add_descriptor(struct fw_descriptor *desc)
+int fw_core_add_descriptor(struct fw_descriptor *desc)
 {
 	size_t i;
 
@@ -171,8 +168,7 @@ fw_core_add_descriptor(struct fw_descrip
 	return 0;
 }
 
-void
-fw_core_remove_descriptor(struct fw_descriptor *desc)
+void fw_core_remove_descriptor(struct fw_descriptor *desc)
 {
 	mutex_lock(&card_mutex);
 
@@ -185,12 +181,30 @@ fw_core_remove_descriptor(struct fw_desc
 	mutex_unlock(&card_mutex);
 }
 
+static int set_broadcast_channel(struct device *dev, void *data)
+{
+	fw_device_set_broadcast_channel(fw_device(dev), (long)data);
+	return 0;
+}
+
+static void allocate_broadcast_channel(struct fw_card *card, int generation)
+{
+	int channel, bandwidth = 0;
+
+	fw_iso_resource_manage(card, generation, 1ULL << 31,
+			       &channel, &bandwidth, true);
+	if (channel == 31) {
+		card->broadcast_channel_allocated = true;
+		device_for_each_child(card->device, (void *)(long)generation,
+				      set_broadcast_channel);
+	}
+}
+
 static const char gap_count_table[] = {
 	63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
 };
 
-void
-fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
+void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
 {
 	int scheduled;
 
@@ -200,37 +214,38 @@ fw_schedule_bm_work(struct fw_card *card
 		fw_card_put(card);
 }
 
-static void
-fw_card_bm_work(struct work_struct *work)
+static void fw_card_bm_work(struct work_struct *work)
 {
 	struct fw_card *card = container_of(work, struct fw_card, work.work);
 	struct fw_device *root_device;
-	struct fw_node *root_node, *local_node;
+	struct fw_node *root_node;
 	unsigned long flags;
-	int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
+	int root_id, new_root_id, irm_id, local_id;
+	int gap_count, generation, grace, rcode;
 	bool do_reset = false;
 	bool root_device_is_running;
 	bool root_device_is_cmc;
 	__be32 lock_data[2];
 
 	spin_lock_irqsave(&card->lock, flags);
-	local_node = card->local_node;
-	root_node  = card->root_node;
 
-	if (local_node == NULL) {
+	if (card->local_node == NULL) {
 		spin_unlock_irqrestore(&card->lock, flags);
 		goto out_put_card;
 	}
-	fw_node_get(local_node);
-	fw_node_get(root_node);
 
 	generation = card->generation;
+	root_node = card->root_node;
+	fw_node_get(root_node);
 	root_device = root_node->data;
 	root_device_is_running = root_device &&
 			atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
 	root_device_is_cmc = root_device && root_device->cmc;
-	root_id = root_node->node_id;
-	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
+	root_id  = root_node->node_id;
+	irm_id   = card->irm_node->node_id;
+	local_id = card->local_node->node_id;
+
+	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8));
 
 	if (is_next_generation(generation, card->bm_generation) ||
 	    (card->bm_generation != generation && grace)) {
@@ -246,16 +261,15 @@ fw_card_bm_work(struct work_struct *work
 		 * next generation.
 		 */
 
-		irm_id = card->irm_node->node_id;
 		if (!card->irm_node->link_on) {
-			new_root_id = local_node->node_id;
+			new_root_id = local_id;
 			fw_notify("IRM has link off, making local node (%02x) root.\n",
 				  new_root_id);
 			goto pick_me;
 		}
 
 		lock_data[0] = cpu_to_be32(0x3f);
-		lock_data[1] = cpu_to_be32(local_node->node_id);
+		lock_data[1] = cpu_to_be32(local_id);
 
 		spin_unlock_irqrestore(&card->lock, flags);
 
@@ -269,9 +283,14 @@ fw_card_bm_work(struct work_struct *work
 			goto out;
 
 		if (rcode == RCODE_COMPLETE &&
-		    lock_data[0] != cpu_to_be32(0x3f))
-			/* Somebody else is BM, let them do the work. */
+		    lock_data[0] != cpu_to_be32(0x3f)) {
+
+			/* Somebody else is BM.  Only act as IRM. */
+			if (local_id == irm_id)
+				allocate_broadcast_channel(card, generation);
+
 			goto out;
+		}
 
 		spin_lock_irqsave(&card->lock, flags);
 
@@ -282,19 +301,18 @@ fw_card_bm_work(struct work_struct *work
 			 * do a bus reset and pick the local node as
 			 * root, and thus, IRM.
 			 */
-			new_root_id = local_node->node_id;
+			new_root_id = local_id;
 			fw_notify("BM lock failed, making local node (%02x) root.\n",
 				  new_root_id);
 			goto pick_me;
 		}
 	} else if (card->bm_generation != generation) {
 		/*
-		 * OK, we weren't BM in the last generation, and it's
-		 * less than 100ms since last bus reset. Reschedule
-		 * this task 100ms from now.
+		 * We weren't BM in the last generation, and the last
+		 * bus reset is less than 125ms ago.  Reschedule this job.
 		 */
 		spin_unlock_irqrestore(&card->lock, flags);
-		fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10));
+		fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8));
 		goto out;
 	}
 
@@ -310,7 +328,7 @@ fw_card_bm_work(struct work_struct *work
 		 * Either link_on is false, or we failed to read the
 		 * config rom.  In either case, pick another root.
 		 */
-		new_root_id = local_node->node_id;
+		new_root_id = local_id;
 	} else if (!root_device_is_running) {
 		/*
 		 * If we haven't probed this device yet, bail out now
@@ -332,7 +350,7 @@ fw_card_bm_work(struct work_struct *work
 		 * successfully read the config rom, but it's not
 		 * cycle master capable.
 		 */
-		new_root_id = local_node->node_id;
+		new_root_id = local_id;
 	}
 
  pick_me:
@@ -363,25 +381,28 @@ fw_card_bm_work(struct work_struct *work
 			  card->index, new_root_id, gap_count);
 		fw_send_phy_config(card, new_root_id, generation, gap_count);
 		fw_core_initiate_bus_reset(card, 1);
+		/* Will allocate broadcast channel after the reset. */
+	} else {
+		if (local_id == irm_id)
+			allocate_broadcast_channel(card, generation);
 	}
+
  out:
 	fw_node_put(root_node);
-	fw_node_put(local_node);
  out_put_card:
 	fw_card_put(card);
 }
 
-static void
-flush_timer_callback(unsigned long data)
+static void flush_timer_callback(unsigned long data)
 {
 	struct fw_card *card = (struct fw_card *)data;
 
 	fw_flush_transactions(card);
 }
 
-void
-fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
-		   struct device *device)
+void fw_card_initialize(struct fw_card *card,
+			const struct fw_card_driver *driver,
+			struct device *device)
 {
 	static atomic_t index = ATOMIC_INIT(-1);
 
@@ -406,13 +427,12 @@ fw_card_initialize(struct fw_card *card,
 }
 EXPORT_SYMBOL(fw_card_initialize);
 
-int
-fw_card_add(struct fw_card *card,
-	    u32 max_receive, u32 link_speed, u64 guid)
+int fw_card_add(struct fw_card *card,
+		u32 max_receive, u32 link_speed, u64 guid)
 {
 	u32 *config_rom;
 	size_t length;
-	int err;
+	int ret;
 
 	card->max_receive = max_receive;
 	card->link_speed = link_speed;
@@ -423,13 +443,14 @@ fw_card_add(struct fw_card *card,
 	list_add_tail(&card->link, &card_list);
 	mutex_unlock(&card_mutex);
 
-	err = card->driver->enable(card, config_rom, length);
-	if (err < 0) {
+	ret = card->driver->enable(card, config_rom, length);
+	if (ret < 0) {
 		mutex_lock(&card_mutex);
 		list_del(&card->link);
 		mutex_unlock(&card_mutex);
 	}
-	return err;
+
+	return ret;
 }
 EXPORT_SYMBOL(fw_card_add);
 
@@ -442,23 +463,20 @@ EXPORT_SYMBOL(fw_card_add);
  * dummy driver just fails all IO.
  */
 
-static int
-dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
 {
 	BUG();
 	return -1;
 }
 
-static int
-dummy_update_phy_reg(struct fw_card *card, int address,
-		     int clear_bits, int set_bits)
+static int dummy_update_phy_reg(struct fw_card *card, int address,
+				int clear_bits, int set_bits)
 {
 	return -ENODEV;
 }
 
-static int
-dummy_set_config_rom(struct fw_card *card,
-		     u32 *config_rom, size_t length)
+static int dummy_set_config_rom(struct fw_card *card,
+				u32 *config_rom, size_t length)
 {
 	/*
 	 * We take the card out of card_list before setting the dummy
@@ -468,27 +486,23 @@ dummy_set_config_rom(struct fw_card *car
 	return -1;
 }
 
-static void
-dummy_send_request(struct fw_card *card, struct fw_packet *packet)
+static void dummy_send_request(struct fw_card *card, struct fw_packet *packet)
 {
 	packet->callback(packet, card, -ENODEV);
 }
 
-static void
-dummy_send_response(struct fw_card *card, struct fw_packet *packet)
+static void dummy_send_response(struct fw_card *card, struct fw_packet *packet)
 {
 	packet->callback(packet, card, -ENODEV);
 }
 
-static int
-dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+static int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
 {
 	return -ENOENT;
 }
 
-static int
-dummy_enable_phys_dma(struct fw_card *card,
-		      int node_id, int generation)
+static int dummy_enable_phys_dma(struct fw_card *card,
+				 int node_id, int generation)
 {
 	return -ENODEV;
 }
@@ -503,16 +517,14 @@ static struct fw_card_driver dummy_drive
 	.enable_phys_dma = dummy_enable_phys_dma,
 };
 
-void
-fw_card_release(struct kref *kref)
+void fw_card_release(struct kref *kref)
 {
 	struct fw_card *card = container_of(kref, struct fw_card, kref);
 
 	complete(&card->done);
 }
 
-void
-fw_core_remove_card(struct fw_card *card)
+void fw_core_remove_card(struct fw_card *card)
 {
 	card->driver->update_phy_reg(card, 4,
 				     PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
@@ -536,8 +548,7 @@ fw_core_remove_card(struct fw_card *card
 }
 EXPORT_SYMBOL(fw_core_remove_card);
 
-int
-fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
 {
 	int reg = short_reset ? 5 : 1;
 	int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-cdev.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-cdev.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-cdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-cdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,87 +18,162 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
+#include <linux/compat.h>
+#include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include <linux/firewire-cdev.h>
+#include <linux/idr.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/preempt.h>
+#include <linux/spinlock.h>
 #include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/idr.h>
-#include <linux/compat.h>
-#include <linux/firewire-cdev.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include "fw-transaction.h"
-#include "fw-topology.h"
+
 #include "fw-device.h"
+#include "fw-topology.h"
+#include "fw-transaction.h"
+
+struct client {
+	u32 version;
+	struct fw_device *device;
+
+	spinlock_t lock;
+	bool in_shutdown;
+	struct idr resource_idr;
+	struct list_head event_list;
+	wait_queue_head_t wait;
+	u64 bus_reset_closure;
+
+	struct fw_iso_context *iso_context;
+	u64 iso_closure;
+	struct fw_iso_buffer buffer;
+	unsigned long vm_start;
 
-struct client;
-struct client_resource {
 	struct list_head link;
-	void (*release)(struct client *client, struct client_resource *r);
-	u32 handle;
+	struct kref kref;
 };
 
+static inline void client_get(struct client *client)
+{
+	kref_get(&client->kref);
+}
+
+static void client_release(struct kref *kref)
+{
+	struct client *client = container_of(kref, struct client, kref);
+
+	fw_device_put(client->device);
+	kfree(client);
+}
+
+static void client_put(struct client *client)
+{
+	kref_put(&client->kref, client_release);
+}
+
+struct client_resource;
+typedef void (*client_resource_release_fn_t)(struct client *,
+					     struct client_resource *);
+struct client_resource {
+	client_resource_release_fn_t release;
+	int handle;
+};
+
+struct address_handler_resource {
+	struct client_resource resource;
+	struct fw_address_handler handler;
+	__u64 closure;
+	struct client *client;
+};
+
+struct outbound_transaction_resource {
+	struct client_resource resource;
+	struct fw_transaction transaction;
+};
+
+struct inbound_transaction_resource {
+	struct client_resource resource;
+	struct fw_request *request;
+	void *data;
+	size_t length;
+};
+
+struct descriptor_resource {
+	struct client_resource resource;
+	struct fw_descriptor descriptor;
+	u32 data[0];
+};
+
+struct iso_resource {
+	struct client_resource resource;
+	struct client *client;
+	/* Schedule work and access todo only with client->lock held. */
+	struct delayed_work work;
+	enum {ISO_RES_ALLOC, ISO_RES_REALLOC, ISO_RES_DEALLOC,
+	      ISO_RES_ALLOC_ONCE, ISO_RES_DEALLOC_ONCE,} todo;
+	int generation;
+	u64 channels;
+	s32 bandwidth;
+	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 *);
+
 /*
  * dequeue_event() just kfree()'s the event, so the event has to be
- * the first field in the struct.
+ * the first field in a struct XYZ_event.
  */
-
 struct event {
 	struct { void *data; size_t size; } v[2];
 	struct list_head link;
 };
 
-struct bus_reset {
+struct bus_reset_event {
 	struct event event;
 	struct fw_cdev_event_bus_reset reset;
 };
 
-struct response {
+struct outbound_transaction_event {
 	struct event event;
-	struct fw_transaction transaction;
 	struct client *client;
-	struct client_resource resource;
+	struct outbound_transaction_resource r;
 	struct fw_cdev_event_response response;
 };
 
-struct iso_interrupt {
+struct inbound_transaction_event {
 	struct event event;
-	struct fw_cdev_event_iso_interrupt interrupt;
+	struct fw_cdev_event_request request;
 };
 
-struct client {
-	u32 version;
-	struct fw_device *device;
-	spinlock_t lock;
-	u32 resource_handle;
-	struct list_head resource_list;
-	struct list_head event_list;
-	wait_queue_head_t wait;
-	u64 bus_reset_closure;
-
-	struct fw_iso_context *iso_context;
-	u64 iso_closure;
-	struct fw_iso_buffer buffer;
-	unsigned long vm_start;
+struct iso_interrupt_event {
+	struct event event;
+	struct fw_cdev_event_iso_interrupt interrupt;
+};
 
-	struct list_head link;
+struct iso_resource_event {
+	struct event event;
+	struct fw_cdev_event_iso_resource resource;
 };
 
-static inline void __user *
-u64_to_uptr(__u64 value)
+static inline void __user *u64_to_uptr(__u64 value)
 {
 	return (void __user *)(unsigned long)value;
 }
 
-static inline __u64
-uptr_to_u64(void __user *ptr)
+static inline __u64 uptr_to_u64(void __user *ptr)
 {
 	return (__u64)(unsigned long)ptr;
 }
@@ -107,7 +182,6 @@ static int fw_device_op_open(struct inod
 {
 	struct fw_device *device;
 	struct client *client;
-	unsigned long flags;
 
 	device = fw_device_get_by_devt(inode->i_rdev);
 	if (device == NULL)
@@ -125,16 +199,17 @@ static int fw_device_op_open(struct inod
 	}
 
 	client->device = device;
-	INIT_LIST_HEAD(&client->event_list);
-	INIT_LIST_HEAD(&client->resource_list);
 	spin_lock_init(&client->lock);
+	idr_init(&client->resource_idr);
+	INIT_LIST_HEAD(&client->event_list);
 	init_waitqueue_head(&client->wait);
+	kref_init(&client->kref);
 
 	file->private_data = client;
 
-	spin_lock_irqsave(&device->card->lock, flags);
+	mutex_lock(&device->client_list_mutex);
 	list_add_tail(&client->link, &device->client_list);
-	spin_unlock_irqrestore(&device->card->lock, flags);
+	mutex_unlock(&device->client_list_mutex);
 
 	return 0;
 }
@@ -150,68 +225,69 @@ static void queue_event(struct client *c
 	event->v[1].size = size1;
 
 	spin_lock_irqsave(&client->lock, flags);
-	list_add_tail(&event->link, &client->event_list);
+	if (client->in_shutdown)
+		kfree(event);
+	else
+		list_add_tail(&event->link, &client->event_list);
 	spin_unlock_irqrestore(&client->lock, flags);
 
 	wake_up_interruptible(&client->wait);
 }
 
-static int
-dequeue_event(struct client *client, char __user *buffer, size_t count)
+static int dequeue_event(struct client *client,
+			 char __user *buffer, size_t count)
 {
-	unsigned long flags;
 	struct event *event;
 	size_t size, total;
-	int i, retval;
+	int i, ret;
 
-	retval = wait_event_interruptible(client->wait,
-					  !list_empty(&client->event_list) ||
-					  fw_device_is_shutdown(client->device));
-	if (retval < 0)
-		return retval;
+	ret = wait_event_interruptible(client->wait,
+			!list_empty(&client->event_list) ||
+			fw_device_is_shutdown(client->device));
+	if (ret < 0)
+		return ret;
 
 	if (list_empty(&client->event_list) &&
 		       fw_device_is_shutdown(client->device))
 		return -ENODEV;
 
-	spin_lock_irqsave(&client->lock, flags);
-	event = container_of(client->event_list.next, struct event, link);
+	spin_lock_irq(&client->lock);
+	event = list_first_entry(&client->event_list, struct event, link);
 	list_del(&event->link);
-	spin_unlock_irqrestore(&client->lock, flags);
+	spin_unlock_irq(&client->lock);
 
 	total = 0;
 	for (i = 0; i < ARRAY_SIZE(event->v) && total < count; i++) {
 		size = min(event->v[i].size, count - total);
 		if (copy_to_user(buffer + total, event->v[i].data, size)) {
-			retval = -EFAULT;
+			ret = -EFAULT;
 			goto out;
 		}
 		total += size;
 	}
-	retval = total;
+	ret = total;
 
  out:
 	kfree(event);
 
-	return retval;
+	return ret;
 }
 
-static ssize_t
-fw_device_op_read(struct file *file,
-		  char __user *buffer, size_t count, loff_t *offset)
+static ssize_t fw_device_op_read(struct file *file, char __user *buffer,
+				 size_t count, loff_t *offset)
 {
 	struct client *client = file->private_data;
 
 	return dequeue_event(client, buffer, count);
 }
 
-/* caller must hold card->lock so that node pointers can be dereferenced here */
-static void
-fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
-		     struct client *client)
+static void fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
+				 struct client *client)
 {
 	struct fw_card *card = client->device->card;
 
+	spin_lock_irq(&card->lock);
+
 	event->closure	     = client->bus_reset_closure;
 	event->type          = FW_CDEV_EVENT_BUS_RESET;
 	event->generation    = client->device->generation;
@@ -220,39 +296,49 @@ fill_bus_reset_event(struct fw_cdev_even
 	event->bm_node_id    = 0; /* FIXME: We don't track the BM. */
 	event->irm_node_id   = card->irm_node->node_id;
 	event->root_node_id  = card->root_node->node_id;
+
+	spin_unlock_irq(&card->lock);
 }
 
-static void
-for_each_client(struct fw_device *device,
-		void (*callback)(struct client *client))
+static void for_each_client(struct fw_device *device,
+			    void (*callback)(struct client *client))
 {
-	struct fw_card *card = device->card;
 	struct client *c;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->lock, flags);
 
+	mutex_lock(&device->client_list_mutex);
 	list_for_each_entry(c, &device->client_list, link)
 		callback(c);
+	mutex_unlock(&device->client_list_mutex);
+}
 
-	spin_unlock_irqrestore(&card->lock, flags);
+static int schedule_reallocations(int id, void *p, void *data)
+{
+	struct client_resource *r = p;
+
+	if (r->release == release_iso_resource)
+		schedule_iso_resource(container_of(r,
+					struct iso_resource, resource));
+	return 0;
 }
 
-static void
-queue_bus_reset_event(struct client *client)
+static void queue_bus_reset_event(struct client *client)
 {
-	struct bus_reset *bus_reset;
+	struct bus_reset_event *e;
 
-	bus_reset = kzalloc(sizeof(*bus_reset), GFP_ATOMIC);
-	if (bus_reset == NULL) {
+	e = kzalloc(sizeof(*e), GFP_KERNEL);
+	if (e == NULL) {
 		fw_notify("Out of memory when allocating bus reset event\n");
 		return;
 	}
 
-	fill_bus_reset_event(&bus_reset->reset, client);
+	fill_bus_reset_event(&e->reset, client);
 
-	queue_event(client, &bus_reset->event,
-		    &bus_reset->reset, sizeof(bus_reset->reset), NULL, 0);
+	queue_event(client, &e->event,
+		    &e->reset, sizeof(e->reset), NULL, 0);
+
+	spin_lock_irq(&client->lock);
+	idr_for_each(&client->resource_idr, schedule_reallocations, client);
+	spin_unlock_irq(&client->lock);
 }
 
 void fw_device_cdev_update(struct fw_device *device)
@@ -274,11 +360,11 @@ static int ioctl_get_info(struct client
 {
 	struct fw_cdev_get_info *get_info = buffer;
 	struct fw_cdev_event_bus_reset bus_reset;
-	struct fw_card *card = client->device->card;
 	unsigned long ret = 0;
 
 	client->version = get_info->version;
 	get_info->version = FW_CDEV_VERSION;
+	get_info->card = client->device->card->index;
 
 	down_read(&fw_device_rwsem);
 
@@ -300,49 +386,61 @@ static int ioctl_get_info(struct client
 	client->bus_reset_closure = get_info->bus_reset_closure;
 	if (get_info->bus_reset != 0) {
 		void __user *uptr = u64_to_uptr(get_info->bus_reset);
-		unsigned long flags;
 
-		spin_lock_irqsave(&card->lock, flags);
 		fill_bus_reset_event(&bus_reset, client);
-		spin_unlock_irqrestore(&card->lock, flags);
-
 		if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
 			return -EFAULT;
 	}
 
-	get_info->card = card->index;
-
 	return 0;
 }
 
-static void
-add_client_resource(struct client *client, struct client_resource *resource)
+static int add_client_resource(struct client *client,
+			       struct client_resource *resource, gfp_t gfp_mask)
 {
 	unsigned long flags;
+	int ret;
+
+ retry:
+	if (idr_pre_get(&client->resource_idr, gfp_mask) == 0)
+		return -ENOMEM;
 
 	spin_lock_irqsave(&client->lock, flags);
-	list_add_tail(&resource->link, &client->resource_list);
-	resource->handle = client->resource_handle++;
+	if (client->in_shutdown)
+		ret = -ECANCELED;
+	else
+		ret = idr_get_new(&client->resource_idr, resource,
+				  &resource->handle);
+	if (ret >= 0) {
+		client_get(client);
+		if (resource->release == release_iso_resource)
+			schedule_iso_resource(container_of(resource,
+						struct iso_resource, resource));
+	}
 	spin_unlock_irqrestore(&client->lock, flags);
+
+	if (ret == -EAGAIN)
+		goto retry;
+
+	return ret < 0 ? ret : 0;
 }
 
-static int
-release_client_resource(struct client *client, u32 handle,
-			struct client_resource **resource)
+static int release_client_resource(struct client *client, u32 handle,
+				   client_resource_release_fn_t release,
+				   struct client_resource **resource)
 {
 	struct client_resource *r;
-	unsigned long flags;
 
-	spin_lock_irqsave(&client->lock, flags);
-	list_for_each_entry(r, &client->resource_list, link) {
-		if (r->handle == handle) {
-			list_del(&r->link);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&client->lock, flags);
+	spin_lock_irq(&client->lock);
+	if (client->in_shutdown)
+		r = NULL;
+	else
+		r = idr_find(&client->resource_idr, handle);
+	if (r && r->release == release)
+		idr_remove(&client->resource_idr, handle);
+	spin_unlock_irq(&client->lock);
 
-	if (&r->link == &client->resource_list)
+	if (!(r && r->release == release))
 		return -EINVAL;
 
 	if (resource)
@@ -350,203 +448,239 @@ release_client_resource(struct client *c
 	else
 		r->release(client, r);
 
+	client_put(client);
+
 	return 0;
 }
 
-static void
-release_transaction(struct client *client, struct client_resource *resource)
+static void release_transaction(struct client *client,
+				struct client_resource *resource)
 {
-	struct response *response =
-		container_of(resource, struct response, resource);
+	struct outbound_transaction_resource *r = container_of(resource,
+			struct outbound_transaction_resource, resource);
 
-	fw_cancel_transaction(client->device->card, &response->transaction);
+	fw_cancel_transaction(client->device->card, &r->transaction);
 }
 
-static void
-complete_transaction(struct fw_card *card, int rcode,
-		     void *payload, size_t length, void *data)
+static void complete_transaction(struct fw_card *card, int rcode,
+				 void *payload, size_t length, void *data)
 {
-	struct response *response = data;
-	struct client *client = response->client;
+	struct outbound_transaction_event *e = data;
+	struct fw_cdev_event_response *rsp = &e->response;
+	struct client *client = e->client;
 	unsigned long flags;
-	struct fw_cdev_event_response *r = &response->response;
 
-	if (length < r->length)
-		r->length = length;
+	if (length < rsp->length)
+		rsp->length = length;
 	if (rcode == RCODE_COMPLETE)
-		memcpy(r->data, payload, r->length);
+		memcpy(rsp->data, payload, rsp->length);
 
 	spin_lock_irqsave(&client->lock, flags);
-	list_del(&response->resource.link);
+	/*
+	 * 1. If called while in shutdown, the idr tree must be left untouched.
+	 *    The idr handle will be removed and the client reference will be
+	 *    dropped later.
+	 * 2. If the call chain was release_client_resource ->
+	 *    release_transaction -> complete_transaction (instead of a normal
+	 *    conclusion of the transaction), i.e. if this resource was already
+	 *    unregistered from the idr, the client reference will be dropped
+	 *    by release_client_resource and we must not drop it here.
+	 */
+	if (!client->in_shutdown &&
+	    idr_find(&client->resource_idr, e->r.resource.handle)) {
+		idr_remove(&client->resource_idr, e->r.resource.handle);
+		/* Drop the idr's reference */
+		client_put(client);
+	}
 	spin_unlock_irqrestore(&client->lock, flags);
 
-	r->type   = FW_CDEV_EVENT_RESPONSE;
-	r->rcode  = rcode;
+	rsp->type = FW_CDEV_EVENT_RESPONSE;
+	rsp->rcode = rcode;
 
 	/*
-	 * In the case that sizeof(*r) doesn't align with the position of the
+	 * In the case that sizeof(*rsp) doesn't align with the position of the
 	 * data, and the read is short, preserve an extra copy of the data
 	 * to stay compatible with a pre-2.6.27 bug.  Since the bug is harmless
 	 * for short reads and some apps depended on it, this is both safe
 	 * and prudent for compatibility.
 	 */
-	if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
-		queue_event(client, &response->event, r, sizeof(*r),
-			    r->data, r->length);
+	if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data))
+		queue_event(client, &e->event, rsp, sizeof(*rsp),
+			    rsp->data, rsp->length);
 	else
-		queue_event(client, &response->event, r, sizeof(*r) + r->length,
+		queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length,
 			    NULL, 0);
+
+	/* Drop the transaction callback's reference */
+	client_put(client);
 }
 
-static int ioctl_send_request(struct client *client, void *buffer)
+static int init_request(struct client *client,
+			struct fw_cdev_send_request *request,
+			int destination_id, int speed)
 {
-	struct fw_device *device = client->device;
-	struct fw_cdev_send_request *request = buffer;
-	struct response *response;
+	struct outbound_transaction_event *e;
+	int ret;
 
-	/* What is the biggest size we'll accept, really? */
-	if (request->length > 4096)
-		return -EINVAL;
+	if (request->tcode != TCODE_STREAM_DATA &&
+	    (request->length > 4096 || request->length > 512 << speed))
+		return -EIO;
 
-	response = kmalloc(sizeof(*response) + request->length, GFP_KERNEL);
-	if (response == NULL)
+	e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
+	if (e == NULL)
 		return -ENOMEM;
 
-	response->client = client;
-	response->response.length = request->length;
-	response->response.closure = request->closure;
+	e->client = client;
+	e->response.length = request->length;
+	e->response.closure = request->closure;
 
 	if (request->data &&
-	    copy_from_user(response->response.data,
+	    copy_from_user(e->response.data,
 			   u64_to_uptr(request->data), request->length)) {
-		kfree(response);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto failed;
 	}
 
-	response->resource.release = release_transaction;
-	add_client_resource(client, &response->resource);
+	e->r.resource.release = release_transaction;
+	ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
+	if (ret < 0)
+		goto failed;
 
-	fw_send_request(device->card, &response->transaction,
-			request->tcode & 0x1f,
-			device->node->node_id,
-			request->generation,
-			device->max_speed,
-			request->offset,
-			response->response.data, request->length,
-			complete_transaction, response);
+	/* Get a reference for the transaction callback */
+	client_get(client);
 
-	if (request->data)
-		return sizeof(request) + request->length;
-	else
-		return sizeof(request);
+	fw_send_request(client->device->card, &e->r.transaction,
+			request->tcode, destination_id, request->generation,
+			speed, request->offset, e->response.data,
+			request->length, complete_transaction, e);
+	return 0;
+
+ failed:
+	kfree(e);
+
+	return ret;
 }
 
-struct address_handler {
-	struct fw_address_handler handler;
-	__u64 closure;
-	struct client *client;
-	struct client_resource resource;
-};
+static int ioctl_send_request(struct client *client, void *buffer)
+{
+	struct fw_cdev_send_request *request = buffer;
 
-struct request {
-	struct fw_request *request;
-	void *data;
-	size_t length;
-	struct client_resource resource;
-};
+	switch (request->tcode) {
+	case TCODE_WRITE_QUADLET_REQUEST:
+	case TCODE_WRITE_BLOCK_REQUEST:
+	case TCODE_READ_QUADLET_REQUEST:
+	case TCODE_READ_BLOCK_REQUEST:
+	case TCODE_LOCK_MASK_SWAP:
+	case TCODE_LOCK_COMPARE_SWAP:
+	case TCODE_LOCK_FETCH_ADD:
+	case TCODE_LOCK_LITTLE_ADD:
+	case TCODE_LOCK_BOUNDED_ADD:
+	case TCODE_LOCK_WRAP_ADD:
+	case TCODE_LOCK_VENDOR_DEPENDENT:
+		break;
+	default:
+		return -EINVAL;
+	}
 
-struct request_event {
-	struct event event;
-	struct fw_cdev_event_request request;
-};
+	return init_request(client, request, client->device->node_id,
+			    client->device->max_speed);
+}
 
-static void
-release_request(struct client *client, struct client_resource *resource)
+static void release_request(struct client *client,
+			    struct client_resource *resource)
 {
-	struct request *request =
-		container_of(resource, struct request, resource);
+	struct inbound_transaction_resource *r = container_of(resource,
+			struct inbound_transaction_resource, resource);
 
-	fw_send_response(client->device->card, request->request,
+	fw_send_response(client->device->card, r->request,
 			 RCODE_CONFLICT_ERROR);
-	kfree(request);
+	kfree(r);
 }
 
-static void
-handle_request(struct fw_card *card, struct fw_request *r,
-	       int tcode, int destination, int source,
-	       int generation, int speed,
-	       unsigned long long offset,
-	       void *payload, size_t length, void *callback_data)
+static void handle_request(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 address_handler *handler = callback_data;
-	struct request *request;
-	struct request_event *e;
-	struct client *client = handler->client;
+	struct address_handler_resource *handler = callback_data;
+	struct inbound_transaction_resource *r;
+	struct inbound_transaction_event *e;
+	int ret;
 
-	request = kmalloc(sizeof(*request), GFP_ATOMIC);
+	r = kmalloc(sizeof(*r), GFP_ATOMIC);
 	e = kmalloc(sizeof(*e), GFP_ATOMIC);
-	if (request == NULL || e == NULL) {
-		kfree(request);
-		kfree(e);
-		fw_send_response(card, r, RCODE_CONFLICT_ERROR);
-		return;
-	}
+	if (r == NULL || e == NULL)
+		goto failed;
 
-	request->request = r;
-	request->data    = payload;
-	request->length  = length;
+	r->request = request;
+	r->data    = payload;
+	r->length  = length;
 
-	request->resource.release = release_request;
-	add_client_resource(client, &request->resource);
+	r->resource.release = release_request;
+	ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
+	if (ret < 0)
+		goto failed;
 
 	e->request.type    = FW_CDEV_EVENT_REQUEST;
 	e->request.tcode   = tcode;
 	e->request.offset  = offset;
 	e->request.length  = length;
-	e->request.handle  = request->resource.handle;
+	e->request.handle  = r->resource.handle;
 	e->request.closure = handler->closure;
 
-	queue_event(client, &e->event,
+	queue_event(handler->client, &e->event,
 		    &e->request, sizeof(e->request), payload, length);
+	return;
+
+ failed:
+	kfree(r);
+	kfree(e);
+	fw_send_response(card, request, RCODE_CONFLICT_ERROR);
 }
 
-static void
-release_address_handler(struct client *client,
-			struct client_resource *resource)
+static void release_address_handler(struct client *client,
+				    struct client_resource *resource)
 {
-	struct address_handler *handler =
-		container_of(resource, struct address_handler, resource);
+	struct address_handler_resource *r =
+	    container_of(resource, struct address_handler_resource, resource);
 
-	fw_core_remove_address_handler(&handler->handler);
-	kfree(handler);
+	fw_core_remove_address_handler(&r->handler);
+	kfree(r);
 }
 
 static int ioctl_allocate(struct client *client, void *buffer)
 {
 	struct fw_cdev_allocate *request = buffer;
-	struct address_handler *handler;
+	struct address_handler_resource *r;
 	struct fw_address_region region;
+	int ret;
 
-	handler = kmalloc(sizeof(*handler), GFP_KERNEL);
-	if (handler == NULL)
+	r = kmalloc(sizeof(*r), GFP_KERNEL);
+	if (r == NULL)
 		return -ENOMEM;
 
 	region.start = request->offset;
 	region.end = request->offset + request->length;
-	handler->handler.length = request->length;
-	handler->handler.address_callback = handle_request;
-	handler->handler.callback_data = handler;
-	handler->closure = request->closure;
-	handler->client = client;
+	r->handler.length = request->length;
+	r->handler.address_callback = handle_request;
+	r->handler.callback_data = r;
+	r->closure = request->closure;
+	r->client = client;
 
-	if (fw_core_add_address_handler(&handler->handler, &region) < 0) {
-		kfree(handler);
-		return -EBUSY;
+	ret = fw_core_add_address_handler(&r->handler, &region);
+	if (ret < 0) {
+		kfree(r);
+		return ret;
 	}
 
-	handler->resource.release = release_address_handler;
-	add_client_resource(client, &handler->resource);
-	request->handle = handler->resource.handle;
+	r->resource.release = release_address_handler;
+	ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+	if (ret < 0) {
+		release_address_handler(client, &r->resource);
+		return ret;
+	}
+	request->handle = r->resource.handle;
 
 	return 0;
 }
@@ -555,18 +689,22 @@ static int ioctl_deallocate(struct clien
 {
 	struct fw_cdev_deallocate *request = buffer;
 
-	return release_client_resource(client, request->handle, NULL);
+	return release_client_resource(client, request->handle,
+				       release_address_handler, NULL);
 }
 
 static int ioctl_send_response(struct client *client, void *buffer)
 {
 	struct fw_cdev_send_response *request = buffer;
 	struct client_resource *resource;
-	struct request *r;
+	struct inbound_transaction_resource *r;
 
-	if (release_client_resource(client, request->handle, &resource) < 0)
+	if (release_client_resource(client, request->handle,
+				    release_request, &resource) < 0)
 		return -EINVAL;
-	r = container_of(resource, struct request, resource);
+
+	r = container_of(resource, struct inbound_transaction_resource,
+			 resource);
 	if (request->length < r->length)
 		r->length = request->length;
 	if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
@@ -588,85 +726,92 @@ static int ioctl_initiate_bus_reset(stru
 	return fw_core_initiate_bus_reset(client->device->card, short_reset);
 }
 
-struct descriptor {
-	struct fw_descriptor d;
-	struct client_resource resource;
-	u32 data[0];
-};
-
 static void release_descriptor(struct client *client,
 			       struct client_resource *resource)
 {
-	struct descriptor *descriptor =
-		container_of(resource, struct descriptor, resource);
+	struct descriptor_resource *r =
+		container_of(resource, struct descriptor_resource, resource);
 
-	fw_core_remove_descriptor(&descriptor->d);
-	kfree(descriptor);
+	fw_core_remove_descriptor(&r->descriptor);
+	kfree(r);
 }
 
 static int ioctl_add_descriptor(struct client *client, void *buffer)
 {
 	struct fw_cdev_add_descriptor *request = buffer;
-	struct descriptor *descriptor;
-	int retval;
+	struct fw_card *card = client->device->card;
+	struct descriptor_resource *r;
+	int ret;
+
+	/* Access policy: Allow this ioctl only on local nodes' device files. */
+	spin_lock_irq(&card->lock);
+	ret = client->device->node_id != card->local_node->node_id;
+	spin_unlock_irq(&card->lock);
+	if (ret)
+		return -ENOSYS;
 
 	if (request->length > 256)
 		return -EINVAL;
 
-	descriptor =
-		kmalloc(sizeof(*descriptor) + request->length * 4, GFP_KERNEL);
-	if (descriptor == NULL)
+	r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL);
+	if (r == NULL)
 		return -ENOMEM;
 
-	if (copy_from_user(descriptor->data,
+	if (copy_from_user(r->data,
 			   u64_to_uptr(request->data), request->length * 4)) {
-		kfree(descriptor);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto failed;
 	}
 
-	descriptor->d.length = request->length;
-	descriptor->d.immediate = request->immediate;
-	descriptor->d.key = request->key;
-	descriptor->d.data = descriptor->data;
+	r->descriptor.length    = request->length;
+	r->descriptor.immediate = request->immediate;
+	r->descriptor.key       = request->key;
+	r->descriptor.data      = r->data;
 
-	retval = fw_core_add_descriptor(&descriptor->d);
-	if (retval < 0) {
-		kfree(descriptor);
-		return retval;
-	}
+	ret = fw_core_add_descriptor(&r->descriptor);
+	if (ret < 0)
+		goto failed;
 
-	descriptor->resource.release = release_descriptor;
-	add_client_resource(client, &descriptor->resource);
-	request->handle = descriptor->resource.handle;
+	r->resource.release = release_descriptor;
+	ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+	if (ret < 0) {
+		fw_core_remove_descriptor(&r->descriptor);
+		goto failed;
+	}
+	request->handle = r->resource.handle;
 
 	return 0;
+ failed:
+	kfree(r);
+
+	return ret;
 }
 
 static int ioctl_remove_descriptor(struct client *client, void *buffer)
 {
 	struct fw_cdev_remove_descriptor *request = buffer;
 
-	return release_client_resource(client, request->handle, NULL);
+	return release_client_resource(client, request->handle,
+				       release_descriptor, NULL);
 }
 
-static void
-iso_callback(struct fw_iso_context *context, u32 cycle,
-	     size_t header_length, void *header, void *data)
+static void iso_callback(struct fw_iso_context *context, u32 cycle,
+			 size_t header_length, void *header, void *data)
 {
 	struct client *client = data;
-	struct iso_interrupt *irq;
+	struct iso_interrupt_event *e;
 
-	irq = kzalloc(sizeof(*irq) + header_length, GFP_ATOMIC);
-	if (irq == NULL)
+	e = kzalloc(sizeof(*e) + header_length, GFP_ATOMIC);
+	if (e == NULL)
 		return;
 
-	irq->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT;
-	irq->interrupt.closure   = client->iso_closure;
-	irq->interrupt.cycle     = cycle;
-	irq->interrupt.header_length = header_length;
-	memcpy(irq->interrupt.header, header, header_length);
-	queue_event(client, &irq->event, &irq->interrupt,
-		    sizeof(irq->interrupt) + header_length, NULL, 0);
+	e->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT;
+	e->interrupt.closure   = client->iso_closure;
+	e->interrupt.cycle     = cycle;
+	e->interrupt.header_length = header_length;
+	memcpy(e->interrupt.header, header, header_length);
+	queue_event(client, &e->event, &e->interrupt,
+		    sizeof(e->interrupt) + header_length, NULL, 0);
 }
 
 static int ioctl_create_iso_context(struct client *client, void *buffer)
@@ -871,6 +1016,261 @@ static int ioctl_get_cycle_timer(struct
 	return 0;
 }
 
+static void iso_resource_work(struct work_struct *work)
+{
+	struct iso_resource_event *e;
+	struct iso_resource *r =
+			container_of(work, struct iso_resource, work.work);
+	struct client *client = r->client;
+	int generation, channel, bandwidth, todo;
+	bool skip, free, success;
+
+	spin_lock_irq(&client->lock);
+	generation = client->device->generation;
+	todo = r->todo;
+	/* 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);
+		skip = true;
+	} else {
+		/* We could be called twice within the same generation. */
+		skip = todo == ISO_RES_REALLOC &&
+		       r->generation == generation;
+	}
+	free = todo == ISO_RES_DEALLOC ||
+	       todo == ISO_RES_ALLOC_ONCE ||
+	       todo == ISO_RES_DEALLOC_ONCE;
+	r->generation = generation;
+	spin_unlock_irq(&client->lock);
+
+	if (skip)
+		goto out;
+
+	bandwidth = r->bandwidth;
+
+	fw_iso_resource_manage(client->device->card, generation,
+			r->channels, &channel, &bandwidth,
+			todo == ISO_RES_ALLOC ||
+			todo == ISO_RES_REALLOC ||
+			todo == ISO_RES_ALLOC_ONCE);
+	/*
+	 * Is this generation outdated already?  As long as this resource sticks
+	 * in the idr, it will be scheduled again for a newer generation or at
+	 * shutdown.
+	 */
+	if (channel == -EAGAIN &&
+	    (todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC))
+		goto out;
+
+	success = channel >= 0 || bandwidth > 0;
+
+	spin_lock_irq(&client->lock);
+	/*
+	 * Transit from allocation to reallocation, except if the client
+	 * requested deallocation in the meantime.
+	 */
+	if (r->todo == ISO_RES_ALLOC)
+		r->todo = ISO_RES_REALLOC;
+	/*
+	 * Allocation or reallocation failure?  Pull this resource out of the
+	 * idr and prepare for deletion, unless the client is shutting down.
+	 */
+	if (r->todo == ISO_RES_REALLOC && !success &&
+	    !client->in_shutdown &&
+	    idr_find(&client->resource_idr, r->resource.handle)) {
+		idr_remove(&client->resource_idr, r->resource.handle);
+		client_put(client);
+		free = true;
+	}
+	spin_unlock_irq(&client->lock);
+
+	if (todo == ISO_RES_ALLOC && channel >= 0)
+		r->channels = 1ULL << channel;
+
+	if (todo == ISO_RES_REALLOC && success)
+		goto out;
+
+	if (todo == ISO_RES_ALLOC || todo == ISO_RES_ALLOC_ONCE) {
+		e = r->e_alloc;
+		r->e_alloc = NULL;
+	} else {
+		e = r->e_dealloc;
+		r->e_dealloc = NULL;
+	}
+	e->resource.handle	= r->resource.handle;
+	e->resource.channel	= channel;
+	e->resource.bandwidth	= bandwidth;
+
+	queue_event(client, &e->event,
+		    &e->resource, sizeof(e->resource), NULL, 0);
+
+	if (free) {
+		cancel_delayed_work(&r->work);
+		kfree(r->e_alloc);
+		kfree(r->e_dealloc);
+		kfree(r);
+	}
+ out:
+	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)
+{
+	struct iso_resource *r =
+		container_of(resource, struct iso_resource, resource);
+
+	spin_lock_irq(&client->lock);
+	r->todo = ISO_RES_DEALLOC;
+	schedule_iso_resource(r);
+	spin_unlock_irq(&client->lock);
+}
+
+static int init_iso_resource(struct client *client,
+		struct fw_cdev_allocate_iso_resource *request, int todo)
+{
+	struct iso_resource_event *e1, *e2;
+	struct iso_resource *r;
+	int ret;
+
+	if ((request->channels == 0 && request->bandwidth == 0) ||
+	    request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
+	    request->bandwidth < 0)
+		return -EINVAL;
+
+	r  = kmalloc(sizeof(*r), GFP_KERNEL);
+	e1 = kmalloc(sizeof(*e1), GFP_KERNEL);
+	e2 = kmalloc(sizeof(*e2), GFP_KERNEL);
+	if (r == NULL || e1 == NULL || e2 == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	INIT_DELAYED_WORK(&r->work, iso_resource_work);
+	r->client	= client;
+	r->todo		= todo;
+	r->generation	= -1;
+	r->channels	= request->channels;
+	r->bandwidth	= request->bandwidth;
+	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;
+
+	if (todo == ISO_RES_ALLOC) {
+		r->resource.release = release_iso_resource;
+		ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+		if (ret < 0)
+			goto fail;
+	} else {
+		r->resource.release = NULL;
+		r->resource.handle = -1;
+		schedule_iso_resource(r);
+	}
+	request->handle = r->resource.handle;
+
+	return 0;
+ fail:
+	kfree(r);
+	kfree(e1);
+	kfree(e2);
+
+	return ret;
+}
+
+static int ioctl_allocate_iso_resource(struct client *client, void *buffer)
+{
+	struct fw_cdev_allocate_iso_resource *request = buffer;
+
+	return init_iso_resource(client, request, ISO_RES_ALLOC);
+}
+
+static int ioctl_deallocate_iso_resource(struct client *client, void *buffer)
+{
+	struct fw_cdev_deallocate *request = buffer;
+
+	return release_client_resource(client, request->handle,
+				       release_iso_resource, NULL);
+}
+
+static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer)
+{
+	struct fw_cdev_allocate_iso_resource *request = buffer;
+
+	return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
+}
+
+static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer)
+{
+	struct fw_cdev_allocate_iso_resource *request = buffer;
+
+	return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
+}
+
+/*
+ * Returns a speed code:  Maximum speed to or from this device,
+ * limited by the device's link speed, the local node's link speed,
+ * and all PHY port speeds between the two links.
+ */
+static int ioctl_get_speed(struct client *client, void *buffer)
+{
+	return client->device->max_speed;
+}
+
+static int ioctl_send_broadcast_request(struct client *client, void *buffer)
+{
+	struct fw_cdev_send_request *request = buffer;
+
+	switch (request->tcode) {
+	case TCODE_WRITE_QUADLET_REQUEST:
+	case TCODE_WRITE_BLOCK_REQUEST:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Security policy: Only allow accesses to Units Space. */
+	if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
+		return -EACCES;
+
+	return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
+}
+
+static int ioctl_send_stream_packet(struct client *client, void *buffer)
+{
+	struct fw_cdev_send_stream_packet *p = buffer;
+	struct fw_cdev_send_request request;
+	int dest;
+
+	if (p->speed > client->device->card->link_speed ||
+	    p->length > 1024 << p->speed)
+		return -EIO;
+
+	if (p->tag > 3 || p->channel > 63 || p->sy > 15)
+		return -EINVAL;
+
+	dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy);
+	request.tcode		= TCODE_STREAM_DATA;
+	request.length		= p->length;
+	request.closure		= p->closure;
+	request.data		= p->data;
+	request.generation	= p->generation;
+
+	return init_request(client, &request, dest, p->speed);
+}
+
 static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
 	ioctl_get_info,
 	ioctl_send_request,
@@ -885,13 +1285,20 @@ static int (* const ioctl_handlers[])(st
 	ioctl_start_iso,
 	ioctl_stop_iso,
 	ioctl_get_cycle_timer,
+	ioctl_allocate_iso_resource,
+	ioctl_deallocate_iso_resource,
+	ioctl_allocate_iso_resource_once,
+	ioctl_deallocate_iso_resource_once,
+	ioctl_get_speed,
+	ioctl_send_broadcast_request,
+	ioctl_send_stream_packet,
 };
 
-static int
-dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
+static int dispatch_ioctl(struct client *client,
+			  unsigned int cmd, void __user *arg)
 {
 	char buffer[256];
-	int retval;
+	int ret;
 
 	if (_IOC_TYPE(cmd) != '#' ||
 	    _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
@@ -903,9 +1310,9 @@ dispatch_ioctl(struct client *client, un
 			return -EFAULT;
 	}
 
-	retval = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
-	if (retval < 0)
-		return retval;
+	ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
+	if (ret < 0)
+		return ret;
 
 	if (_IOC_DIR(cmd) & _IOC_READ) {
 		if (_IOC_SIZE(cmd) > sizeof(buffer) ||
@@ -913,12 +1320,11 @@ dispatch_ioctl(struct client *client, un
 			return -EFAULT;
 	}
 
-	return retval;
+	return ret;
 }
 
-static long
-fw_device_op_ioctl(struct file *file,
-		   unsigned int cmd, unsigned long arg)
+static long fw_device_op_ioctl(struct file *file,
+			       unsigned int cmd, unsigned long arg)
 {
 	struct client *client = file->private_data;
 
@@ -929,9 +1335,8 @@ fw_device_op_ioctl(struct file *file,
 }
 
 #ifdef CONFIG_COMPAT
-static long
-fw_device_op_compat_ioctl(struct file *file,
-			  unsigned int cmd, unsigned long arg)
+static long fw_device_op_compat_ioctl(struct file *file,
+				      unsigned int cmd, unsigned long arg)
 {
 	struct client *client = file->private_data;
 
@@ -947,7 +1352,7 @@ static int fw_device_op_mmap(struct file
 	struct client *client = file->private_data;
 	enum dma_data_direction direction;
 	unsigned long size;
-	int page_count, retval;
+	int page_count, ret;
 
 	if (fw_device_is_shutdown(client->device))
 		return -ENODEV;
@@ -973,48 +1378,57 @@ static int fw_device_op_mmap(struct file
 	else
 		direction = DMA_FROM_DEVICE;
 
-	retval = fw_iso_buffer_init(&client->buffer, client->device->card,
-				    page_count, direction);
-	if (retval < 0)
-		return retval;
+	ret = fw_iso_buffer_init(&client->buffer, client->device->card,
+				 page_count, direction);
+	if (ret < 0)
+		return ret;
 
-	retval = fw_iso_buffer_map(&client->buffer, vma);
-	if (retval < 0)
+	ret = fw_iso_buffer_map(&client->buffer, vma);
+	if (ret < 0)
 		fw_iso_buffer_destroy(&client->buffer, client->device->card);
 
-	return retval;
+	return ret;
+}
+
+static int shutdown_resource(int id, void *p, void *data)
+{
+	struct client_resource *r = p;
+	struct client *client = data;
+
+	r->release(client, r);
+	client_put(client);
+
+	return 0;
 }
 
 static int fw_device_op_release(struct inode *inode, struct file *file)
 {
 	struct client *client = file->private_data;
 	struct event *e, *next_e;
-	struct client_resource *r, *next_r;
-	unsigned long flags;
 
-	if (client->buffer.pages)
-		fw_iso_buffer_destroy(&client->buffer, client->device->card);
+	mutex_lock(&client->device->client_list_mutex);
+	list_del(&client->link);
+	mutex_unlock(&client->device->client_list_mutex);
 
 	if (client->iso_context)
 		fw_iso_context_destroy(client->iso_context);
 
-	list_for_each_entry_safe(r, next_r, &client->resource_list, link)
-		r->release(client, r);
+	if (client->buffer.pages)
+		fw_iso_buffer_destroy(&client->buffer, client->device->card);
 
-	/*
-	 * FIXME: We should wait for the async tasklets to stop
-	 * running before freeing the memory.
-	 */
+	/* Freeze client->resource_idr and client->event_list */
+	spin_lock_irq(&client->lock);
+	client->in_shutdown = true;
+	spin_unlock_irq(&client->lock);
+
+	idr_for_each(&client->resource_idr, shutdown_resource, client);
+	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);
 
-	spin_lock_irqsave(&client->device->card->lock, flags);
-	list_del(&client->link);
-	spin_unlock_irqrestore(&client->device->card->lock, flags);
-
-	fw_device_put(client->device);
-	kfree(client);
+	client_put(client);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-device.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-device.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-device.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,22 +18,26 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/kthread.h>
-#include <linux/device.h>
+#include <linux/ctype.h>
 #include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
 #include <linux/idr.h>
 #include <linux/jiffies.h>
-#include <linux/string.h>
+#include <linux/kobject.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/rwsem.h>
 #include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+
 #include <asm/system.h>
-#include <linux/ctype.h>
-#include "fw-transaction.h"
-#include "fw-topology.h"
+
 #include "fw-device.h"
+#include "fw-topology.h"
+#include "fw-transaction.h"
 
 void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p)
 {
@@ -132,8 +136,7 @@ static int get_modalias(struct fw_unit *
 			vendor, model, specifier_id, version);
 }
 
-static int
-fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct fw_unit *unit = fw_unit(dev);
 	char modalias[64];
@@ -152,27 +155,6 @@ struct bus_type fw_bus_type = {
 };
 EXPORT_SYMBOL(fw_bus_type);
 
-static void fw_device_release(struct device *dev)
-{
-	struct fw_device *device = fw_device(dev);
-	struct fw_card *card = device->card;
-	unsigned long flags;
-
-	/*
-	 * Take the card lock so we don't set this to NULL while a
-	 * FW_NODE_UPDATED callback is being handled or while the
-	 * bus manager work looks at this node.
-	 */
-	spin_lock_irqsave(&card->lock, flags);
-	device->node->data = NULL;
-	spin_unlock_irqrestore(&card->lock, flags);
-
-	fw_node_put(device->node);
-	kfree(device->config_rom);
-	kfree(device);
-	fw_card_put(card);
-}
-
 int fw_device_enable_phys_dma(struct fw_device *device)
 {
 	int generation = device->generation;
@@ -191,8 +173,8 @@ struct config_rom_attribute {
 	u32 key;
 };
 
-static ssize_t
-show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
+static ssize_t show_immediate(struct device *dev,
+			      struct device_attribute *dattr, char *buf)
 {
 	struct config_rom_attribute *attr =
 		container_of(dattr, struct config_rom_attribute, attr);
@@ -223,8 +205,8 @@ show_immediate(struct device *dev, struc
 #define IMMEDIATE_ATTR(name, key)				\
 	{ __ATTR(name, S_IRUGO, show_immediate, NULL), key }
 
-static ssize_t
-show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
+static ssize_t show_text_leaf(struct device *dev,
+			      struct device_attribute *dattr, char *buf)
 {
 	struct config_rom_attribute *attr =
 		container_of(dattr, struct config_rom_attribute, attr);
@@ -293,10 +275,9 @@ static struct config_rom_attribute confi
 	TEXT_LEAF_ATTR(hardware_version_name, CSR_HARDWARE_VERSION),
 };
 
-static void
-init_fw_attribute_group(struct device *dev,
-			struct device_attribute *attrs,
-			struct fw_attribute_group *group)
+static void init_fw_attribute_group(struct device *dev,
+				    struct device_attribute *attrs,
+				    struct fw_attribute_group *group)
 {
 	struct device_attribute *attr;
 	int i, j;
@@ -319,9 +300,8 @@ init_fw_attribute_group(struct device *d
 	dev->groups = group->groups;
 }
 
-static ssize_t
-modalias_show(struct device *dev,
-	      struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
 {
 	struct fw_unit *unit = fw_unit(dev);
 	int length;
@@ -332,9 +312,8 @@ modalias_show(struct device *dev,
 	return length + 1;
 }
 
-static ssize_t
-rom_index_show(struct device *dev,
-	       struct device_attribute *attr, char *buf)
+static ssize_t rom_index_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
 {
 	struct fw_device *device = fw_device(dev->parent);
 	struct fw_unit *unit = fw_unit(dev);
@@ -349,8 +328,8 @@ static struct device_attribute fw_unit_a
 	__ATTR_NULL,
 };
 
-static ssize_t
-config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t config_rom_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct fw_device *device = fw_device(dev);
 	size_t length;
@@ -363,8 +342,8 @@ config_rom_show(struct device *dev, stru
 	return length;
 }
 
-static ssize_t
-guid_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t guid_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
 {
 	struct fw_device *device = fw_device(dev);
 	int ret;
@@ -383,8 +362,8 @@ static struct device_attribute fw_device
 	__ATTR_NULL,
 };
 
-static int
-read_rom(struct fw_device *device, int generation, int index, u32 *data)
+static int read_rom(struct fw_device *device,
+		    int generation, int index, u32 *data)
 {
 	int rcode;
 
@@ -539,7 +518,7 @@ static int read_bus_info_block(struct fw
 
 	kfree(old_rom);
 	ret = 0;
-	device->cmc = rom[2] & 1 << 30;
+	device->cmc = rom[2] >> 30 & 1;
  out:
 	kfree(rom);
 
@@ -679,11 +658,53 @@ static void fw_device_shutdown(struct wo
 	fw_device_put(device);
 }
 
+static void fw_device_release(struct device *dev)
+{
+	struct fw_device *device = fw_device(dev);
+	struct fw_card *card = device->card;
+	unsigned long flags;
+
+	/*
+	 * Take the card lock so we don't set this to NULL while a
+	 * FW_NODE_UPDATED callback is being handled or while the
+	 * bus manager work looks at this node.
+	 */
+	spin_lock_irqsave(&card->lock, flags);
+	device->node->data = NULL;
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	fw_node_put(device->node);
+	kfree(device->config_rom);
+	kfree(device);
+	fw_card_put(card);
+}
+
 static struct device_type fw_device_type = {
-	.release	= fw_device_release,
+	.release = fw_device_release,
 };
 
-static void fw_device_update(struct work_struct *work);
+static int update_unit(struct device *dev, void *data)
+{
+	struct fw_unit *unit = fw_unit(dev);
+	struct fw_driver *driver = (struct fw_driver *)dev->driver;
+
+	if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
+		down(&dev->sem);
+		driver->update(unit);
+		up(&dev->sem);
+	}
+
+	return 0;
+}
+
+static void fw_device_update(struct work_struct *work)
+{
+	struct fw_device *device =
+		container_of(work, struct fw_device, work.work);
+
+	fw_device_cdev_update(device);
+	device_for_each_child(&device->device, NULL, update_unit);
+}
 
 /*
  * If a device was pending for deletion because its node went away but its
@@ -735,12 +756,50 @@ static int lookup_existing_device(struct
 	return match;
 }
 
+enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
+
+void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
+{
+	struct fw_card *card = device->card;
+	__be32 data;
+	int rcode;
+
+	if (!card->broadcast_channel_allocated)
+		return;
+
+	if (device->bc_implemented == BC_UNKNOWN) {
+		rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
+				device->node_id, generation, device->max_speed,
+				CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
+				&data, 4);
+		switch (rcode) {
+		case RCODE_COMPLETE:
+			if (data & cpu_to_be32(1 << 31)) {
+				device->bc_implemented = BC_IMPLEMENTED;
+				break;
+			}
+			/* else fall through to case address error */
+		case RCODE_ADDRESS_ERROR:
+			device->bc_implemented = BC_UNIMPLEMENTED;
+		}
+	}
+
+	if (device->bc_implemented == BC_IMPLEMENTED) {
+		data = cpu_to_be32(BROADCAST_CHANNEL_INITIAL |
+				   BROADCAST_CHANNEL_VALID);
+		fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
+				device->node_id, generation, device->max_speed,
+				CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
+				&data, 4);
+	}
+}
+
 static void fw_device_init(struct work_struct *work)
 {
 	struct fw_device *device =
 		container_of(work, struct fw_device, work.work);
 	struct device *revived_dev;
-	int minor, err;
+	int minor, ret;
 
 	/*
 	 * All failure paths here set node->data to NULL, so that we
@@ -776,12 +835,12 @@ static void fw_device_init(struct work_s
 
 	fw_device_get(device);
 	down_write(&fw_device_rwsem);
-	err = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
+	ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
 	      idr_get_new(&fw_device_idr, device, &minor) :
 	      -ENOMEM;
 	up_write(&fw_device_rwsem);
 
-	if (err < 0)
+	if (ret < 0)
 		goto error;
 
 	device->device.bus = &fw_bus_type;
@@ -828,6 +887,8 @@ static void fw_device_init(struct work_s
 				  device->config_rom[3], device->config_rom[4],
 				  1 << device->max_speed);
 		device->config_rom_retries = 0;
+
+		fw_device_set_broadcast_channel(device, device->generation);
 	}
 
 	/*
@@ -851,29 +912,6 @@ static void fw_device_init(struct work_s
 	put_device(&device->device);	/* our reference */
 }
 
-static int update_unit(struct device *dev, void *data)
-{
-	struct fw_unit *unit = fw_unit(dev);
-	struct fw_driver *driver = (struct fw_driver *)dev->driver;
-
-	if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
-		down(&dev->sem);
-		driver->update(unit);
-		up(&dev->sem);
-	}
-
-	return 0;
-}
-
-static void fw_device_update(struct work_struct *work)
-{
-	struct fw_device *device =
-		container_of(work, struct fw_device, work.work);
-
-	fw_device_cdev_update(device);
-	device_for_each_child(&device->device, NULL, update_unit);
-}
-
 enum {
 	REREAD_BIB_ERROR,
 	REREAD_BIB_GONE,
@@ -894,7 +932,7 @@ static int reread_bus_info_block(struct
 		if (i == 0 && q == 0)
 			return REREAD_BIB_GONE;
 
-		if (i > device->config_rom_length || q != device->config_rom[i])
+		if (q != device->config_rom[i])
 			return REREAD_BIB_CHANGED;
 	}
 
@@ -1004,6 +1042,7 @@ void fw_node_event(struct fw_card *card,
 		device->node = fw_node_get(node);
 		device->node_id = node->node_id;
 		device->generation = card->generation;
+		mutex_init(&device->client_list_mutex);
 		INIT_LIST_HEAD(&device->client_list);
 
 		/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-device.h linux-libre-2.6.30-gnu1/drivers/firewire/fw-device.h
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-device.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-device.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,10 +19,17 @@
 #ifndef __fw_device_h
 #define __fw_device_h
 
+#include <linux/device.h>
 #include <linux/fs.h>
-#include <linux/cdev.h>
 #include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/rwsem.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
 #include <asm/atomic.h>
 
 enum fw_device_state {
@@ -38,6 +45,9 @@ struct fw_attribute_group {
 	struct attribute *attrs[11];
 };
 
+struct fw_node;
+struct fw_card;
+
 /*
  * Note, fw_device.generation always has to be read before fw_device.node_id.
  * Use SMP memory barriers to ensure this.  Otherwise requests will be sent
@@ -61,13 +71,18 @@ struct fw_device {
 	int node_id;
 	int generation;
 	unsigned max_speed;
-	bool cmc;
 	struct fw_card *card;
 	struct device device;
+
+	struct mutex client_list_mutex;
 	struct list_head client_list;
+
 	u32 *config_rom;
 	size_t config_rom_length;
 	int config_rom_retries;
+	unsigned cmc:1;
+	unsigned bc_implemented:2;
+
 	struct delayed_work work;
 	struct fw_attribute_group attribute_group;
 };
@@ -96,6 +111,7 @@ static inline void fw_device_put(struct
 
 struct fw_device *fw_device_get_by_devt(dev_t devt);
 int fw_device_enable_phys_dma(struct fw_device *device);
+void fw_device_set_broadcast_channel(struct fw_device *device, int generation);
 
 void fw_device_cdev_update(struct fw_device *device);
 void fw_device_cdev_remove(struct fw_device *device);
@@ -176,8 +192,7 @@ struct fw_driver {
 	const struct fw_device_id *id_table;
 };
 
-static inline struct fw_driver *
-fw_driver(struct device_driver *drv)
+static inline struct fw_driver *fw_driver(struct device_driver *drv)
 {
 	return container_of(drv, struct fw_driver, driver);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-iso.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-iso.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-iso.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-iso.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,7 @@
 /*
- * Isochronous IO functionality
+ * Isochronous I/O functionality:
+ *   - Isochronous DMA context management
+ *   - Isochronous bus resource management (channels, bandwidth), client side
  *
  * Copyright (C) 2006 Kristian Hoegsberg <krh@bitplanet.net>
  *
@@ -18,21 +20,25 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/dma-mapping.h>
-#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include <linux/firewire-constants.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
 
-#include "fw-transaction.h"
 #include "fw-topology.h"
-#include "fw-device.h"
+#include "fw-transaction.h"
 
-int
-fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
-		   int page_count, enum dma_data_direction direction)
+/*
+ * Isochronous DMA context management
+ */
+
+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
+		       int page_count, enum dma_data_direction direction)
 {
-	int i, j, retval = -ENOMEM;
+	int i, j;
 	dma_addr_t address;
 
 	buffer->page_count = page_count;
@@ -69,19 +75,21 @@ fw_iso_buffer_init(struct fw_iso_buffer
 	kfree(buffer->pages);
  out:
 	buffer->pages = NULL;
-	return retval;
+
+	return -ENOMEM;
 }
 
 int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma)
 {
 	unsigned long uaddr;
-	int i, retval;
+	int i, err;
 
 	uaddr = vma->vm_start;
 	for (i = 0; i < buffer->page_count; i++) {
-		retval = vm_insert_page(vma, uaddr, buffer->pages[i]);
-		if (retval)
-			return retval;
+		err = vm_insert_page(vma, uaddr, buffer->pages[i]);
+		if (err)
+			return err;
+
 		uaddr += PAGE_SIZE;
 	}
 
@@ -105,14 +113,14 @@ void fw_iso_buffer_destroy(struct fw_iso
 	buffer->pages = NULL;
 }
 
-struct fw_iso_context *
-fw_iso_context_create(struct fw_card *card, int type,
-		      int channel, int speed, size_t header_size,
-		      fw_iso_callback_t callback, void *callback_data)
+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
+		int type, int channel, int speed, size_t header_size,
+		fw_iso_callback_t callback, void *callback_data)
 {
 	struct fw_iso_context *ctx;
 
-	ctx = card->driver->allocate_iso_context(card, type, header_size);
+	ctx = card->driver->allocate_iso_context(card,
+						 type, channel, header_size);
 	if (IS_ERR(ctx))
 		return ctx;
 
@@ -134,25 +142,186 @@ void fw_iso_context_destroy(struct fw_is
 	card->driver->free_iso_context(ctx);
 }
 
-int
-fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags)
+int fw_iso_context_start(struct fw_iso_context *ctx,
+			 int cycle, int sync, int tags)
 {
 	return ctx->card->driver->start_iso(ctx, cycle, sync, tags);
 }
 
-int
-fw_iso_context_queue(struct fw_iso_context *ctx,
-		     struct fw_iso_packet *packet,
-		     struct fw_iso_buffer *buffer,
-		     unsigned long payload)
+int fw_iso_context_queue(struct fw_iso_context *ctx,
+			 struct fw_iso_packet *packet,
+			 struct fw_iso_buffer *buffer,
+			 unsigned long payload)
 {
 	struct fw_card *card = ctx->card;
 
 	return card->driver->queue_iso(ctx, packet, buffer, payload);
 }
 
-int
-fw_iso_context_stop(struct fw_iso_context *ctx)
+int fw_iso_context_stop(struct fw_iso_context *ctx)
 {
 	return ctx->card->driver->stop_iso(ctx);
 }
+
+/*
+ * Isochronous bus resource management (channels, bandwidth), client side
+ */
+
+static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
+			    int bandwidth, bool allocate)
+{
+	__be32 data[2];
+	int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
+
+	/*
+	 * On a 1394a IRM with low contention, try < 1 is enough.
+	 * On a 1394-1995 IRM, we need at least try < 2.
+	 * Let's just do try < 5.
+	 */
+	for (try = 0; try < 5; try++) {
+		new = allocate ? old - bandwidth : old + bandwidth;
+		if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
+			break;
+
+		data[0] = cpu_to_be32(old);
+		data[1] = cpu_to_be32(new);
+		switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+				irm_id, generation, SCODE_100,
+				CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
+				data, sizeof(data))) {
+		case RCODE_GENERATION:
+			/* A generation change frees all bandwidth. */
+			return allocate ? -EAGAIN : bandwidth;
+
+		case RCODE_COMPLETE:
+			if (be32_to_cpup(data) == old)
+				return bandwidth;
+
+			old = be32_to_cpup(data);
+			/* Fall through. */
+		}
+	}
+
+	return -EIO;
+}
+
+static int manage_channel(struct fw_card *card, int irm_id, int generation,
+			  u32 channels_mask, u64 offset, bool allocate)
+{
+	__be32 data[2], c, all, old;
+	int i, retry = 5;
+
+	old = all = allocate ? cpu_to_be32(~0) : 0;
+
+	for (i = 0; i < 32; i++) {
+		if (!(channels_mask & 1 << i))
+			continue;
+
+		c = cpu_to_be32(1 << (31 - i));
+		if ((old & c) != (all & c))
+			continue;
+
+		data[0] = old;
+		data[1] = old ^ c;
+		switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+					   irm_id, generation, SCODE_100,
+					   offset, data, sizeof(data))) {
+		case RCODE_GENERATION:
+			/* A generation change frees all channels. */
+			return allocate ? -EAGAIN : i;
+
+		case RCODE_COMPLETE:
+			if (data[0] == old)
+				return i;
+
+			old = data[0];
+
+			/* Is the IRM 1394a-2000 compliant? */
+			if ((data[0] & c) == (data[1] & c))
+				continue;
+
+			/* 1394-1995 IRM, fall through to retry. */
+		default:
+			if (retry--)
+				i--;
+		}
+	}
+
+	return -EIO;
+}
+
+static void deallocate_channel(struct fw_card *card, int irm_id,
+			       int generation, int channel)
+{
+	u32 mask;
+	u64 offset;
+
+	mask = channel < 32 ? 1 << channel : 1 << (channel - 32);
+	offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
+				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
+
+	manage_channel(card, irm_id, generation, mask, offset, false);
+}
+
+/**
+ * fw_iso_resource_manage - Allocate or deallocate a channel and/or bandwidth
+ *
+ * In parameters: card, generation, channels_mask, bandwidth, allocate
+ * Out parameters: channel, bandwidth
+ * This function blocks (sleeps) during communication with the IRM.
+ *
+ * Allocates or deallocates at most one channel out of channels_mask.
+ * channels_mask is a bitfield with MSB for channel 63 and LSB for channel 0.
+ * (Note, the IRM's CHANNELS_AVAILABLE is a big-endian bitfield with MSB for
+ * channel 0 and LSB for channel 63.)
+ * Allocates or deallocates as many bandwidth allocation units as specified.
+ *
+ * Returns channel < 0 if no channel was allocated or deallocated.
+ * Returns bandwidth = 0 if no bandwidth was allocated or deallocated.
+ *
+ * If generation is stale, deallocations succeed but allocations fail with
+ * channel = -EAGAIN.
+ *
+ * If channel allocation fails, no bandwidth will be allocated either.
+ * If bandwidth allocation fails, no channel will be allocated either.
+ * But deallocations of channel and bandwidth are tried independently
+ * of each other's success.
+ */
+void fw_iso_resource_manage(struct fw_card *card, int generation,
+			    u64 channels_mask, int *channel, int *bandwidth,
+			    bool allocate)
+{
+	u32 channels_hi = channels_mask;	/* channels 31...0 */
+	u32 channels_lo = channels_mask >> 32;	/* channels 63...32 */
+	int irm_id, ret, c = -EINVAL;
+
+	spin_lock_irq(&card->lock);
+	irm_id = card->irm_node->node_id;
+	spin_unlock_irq(&card->lock);
+
+	if (channels_hi)
+		c = manage_channel(card, irm_id, generation, channels_hi,
+		    CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate);
+	if (channels_lo && c < 0) {
+		c = manage_channel(card, irm_id, generation, channels_lo,
+		    CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate);
+		if (c >= 0)
+			c += 32;
+	}
+	*channel = c;
+
+	if (allocate && channels_mask != 0 && c < 0)
+		*bandwidth = 0;
+
+	if (*bandwidth == 0)
+		return;
+
+	ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
+	if (ret < 0)
+		*bandwidth = 0;
+
+	if (allocate && ret < 0 && c >= 0) {
+		deallocate_channel(card, irm_id, generation, c);
+		*channel = ret;
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-ohci.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-ohci.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-ohci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-ohci.c	2009-06-09 23:05:27.000000000 -0400
@@ -205,6 +205,7 @@ struct fw_ohci {
 
 	u32 it_context_mask;
 	struct iso_context *it_context_list;
+	u64 ir_context_channels;
 	u32 ir_context_mask;
 	struct iso_context *ir_context_list;
 };
@@ -441,9 +442,8 @@ static inline void flush_writes(const st
 	reg_read(ohci, OHCI1394_Version);
 }
 
-static int
-ohci_update_phy_reg(struct fw_card *card, int addr,
-		    int clear_bits, int set_bits)
+static int ohci_update_phy_reg(struct fw_card *card, int addr,
+			       int clear_bits, int set_bits)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
 	u32 val, old;
@@ -658,8 +658,8 @@ static void ar_context_tasklet(unsigned
 	}
 }
 
-static int
-ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
+static int ar_context_init(struct ar_context *ctx,
+			   struct fw_ohci *ohci, u32 regs)
 {
 	struct ar_buffer ab;
 
@@ -690,8 +690,7 @@ static void ar_context_run(struct ar_con
 	flush_writes(ctx->ohci);
 }
 
-static struct descriptor *
-find_branch_descriptor(struct descriptor *d, int z)
+static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
 {
 	int b, key;
 
@@ -751,8 +750,7 @@ static void context_tasklet(unsigned lon
  * Allocate a new buffer and add it to the list of free buffers for this
  * context.  Must be called with ohci->lock held.
  */
-static int
-context_add_buffer(struct context *ctx)
+static int context_add_buffer(struct context *ctx)
 {
 	struct descriptor_buffer *desc;
 	dma_addr_t uninitialized_var(bus_addr);
@@ -781,9 +779,8 @@ context_add_buffer(struct context *ctx)
 	return 0;
 }
 
-static int
-context_init(struct context *ctx, struct fw_ohci *ohci,
-	     u32 regs, descriptor_callback_t callback)
+static int context_init(struct context *ctx, struct fw_ohci *ohci,
+			u32 regs, descriptor_callback_t callback)
 {
 	ctx->ohci = ohci;
 	ctx->regs = regs;
@@ -814,8 +811,7 @@ context_init(struct context *ctx, struct
 	return 0;
 }
 
-static void
-context_release(struct context *ctx)
+static void context_release(struct context *ctx)
 {
 	struct fw_card *card = &ctx->ohci->card;
 	struct descriptor_buffer *desc, *tmp;
@@ -827,8 +823,8 @@ context_release(struct context *ctx)
 }
 
 /* Must be called with ohci->lock held */
-static struct descriptor *
-context_get_descriptors(struct context *ctx, int z, dma_addr_t *d_bus)
+static struct descriptor *context_get_descriptors(struct context *ctx,
+						  int z, dma_addr_t *d_bus)
 {
 	struct descriptor *d = NULL;
 	struct descriptor_buffer *desc = ctx->buffer_tail;
@@ -912,8 +908,8 @@ struct driver_data {
  * Must always be called with the ochi->lock held to ensure proper
  * generation handling and locking around packet queue manipulation.
  */
-static int
-at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
+static int at_context_queue_packet(struct context *ctx,
+				   struct fw_packet *packet)
 {
 	struct fw_ohci *ohci = ctx->ohci;
 	dma_addr_t d_bus, uninitialized_var(payload_bus);
@@ -940,7 +936,9 @@ at_context_queue_packet(struct context *
 	 */
 
 	header = (__le32 *) &d[1];
-	if (packet->header_length > 8) {
+	switch (packet->header_length) {
+	case 16:
+	case 12:
 		header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
 					(packet->speed << 16));
 		header[1] = cpu_to_le32((packet->header[1] & 0xffff) |
@@ -954,12 +952,27 @@ at_context_queue_packet(struct context *
 			header[3] = (__force __le32) packet->header[3];
 
 		d[0].req_count = cpu_to_le16(packet->header_length);
-	} else {
+		break;
+
+	case 8:
 		header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) |
 					(packet->speed << 16));
 		header[1] = cpu_to_le32(packet->header[0]);
 		header[2] = cpu_to_le32(packet->header[1]);
 		d[0].req_count = cpu_to_le16(12);
+		break;
+
+	case 4:
+		header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
+					(packet->speed << 16));
+		header[1] = cpu_to_le32(packet->header[0] & 0xffff0000);
+		d[0].req_count = cpu_to_le16(8);
+		break;
+
+	default:
+		/* BUG(); */
+		packet->ack = RCODE_SEND_ERROR;
+		return -1;
 	}
 
 	driver_data = (struct driver_data *) &d[3];
@@ -1095,8 +1108,8 @@ static int handle_at_packet(struct conte
 #define HEADER_GET_DATA_LENGTH(q)	(((q) >> 16) & 0xffff)
 #define HEADER_GET_EXTENDED_TCODE(q)	(((q) >> 0) & 0xffff)
 
-static void
-handle_local_rom(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
+static void handle_local_rom(struct fw_ohci *ohci,
+			     struct fw_packet *packet, u32 csr)
 {
 	struct fw_packet response;
 	int tcode, length, i;
@@ -1122,8 +1135,8 @@ handle_local_rom(struct fw_ohci *ohci, s
 	fw_core_handle_response(&ohci->card, &response);
 }
 
-static void
-handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
+static void handle_local_lock(struct fw_ohci *ohci,
+			      struct fw_packet *packet, u32 csr)
 {
 	struct fw_packet response;
 	int tcode, length, ext_tcode, sel;
@@ -1164,8 +1177,7 @@ handle_local_lock(struct fw_ohci *ohci,
 	fw_core_handle_response(&ohci->card, &response);
 }
 
-static void
-handle_local_request(struct context *ctx, struct fw_packet *packet)
+static void handle_local_request(struct context *ctx, struct fw_packet *packet)
 {
 	u64 offset;
 	u32 csr;
@@ -1205,11 +1217,10 @@ handle_local_request(struct context *ctx
 	}
 }
 
-static void
-at_context_transmit(struct context *ctx, struct fw_packet *packet)
+static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
 {
 	unsigned long flags;
-	int retval;
+	int ret;
 
 	spin_lock_irqsave(&ctx->ohci->lock, flags);
 
@@ -1220,10 +1231,10 @@ at_context_transmit(struct context *ctx,
 		return;
 	}
 
-	retval = at_context_queue_packet(ctx, packet);
+	ret = at_context_queue_packet(ctx, packet);
 	spin_unlock_irqrestore(&ctx->ohci->lock, flags);
 
-	if (retval < 0)
+	if (ret < 0)
 		packet->callback(packet, &ctx->ohci->card, packet->ack);
 
 }
@@ -1590,12 +1601,12 @@ static int ohci_enable(struct fw_card *c
 	return 0;
 }
 
-static int
-ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
+static int ohci_set_config_rom(struct fw_card *card,
+			       u32 *config_rom, size_t length)
 {
 	struct fw_ohci *ohci;
 	unsigned long flags;
-	int retval = -EBUSY;
+	int ret = -EBUSY;
 	__be32 *next_config_rom;
 	dma_addr_t uninitialized_var(next_config_rom_bus);
 
@@ -1649,7 +1660,7 @@ ohci_set_config_rom(struct fw_card *card
 
 		reg_write(ohci, OHCI1394_ConfigROMmap,
 			  ohci->next_config_rom_bus);
-		retval = 0;
+		ret = 0;
 	}
 
 	spin_unlock_irqrestore(&ohci->lock, flags);
@@ -1661,13 +1672,13 @@ ohci_set_config_rom(struct fw_card *card
 	 * controller could need to access it before the bus reset
 	 * takes effect.
 	 */
-	if (retval == 0)
+	if (ret == 0)
 		fw_core_initiate_bus_reset(&ohci->card, 1);
 	else
 		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
 				  next_config_rom, next_config_rom_bus);
 
-	return retval;
+	return ret;
 }
 
 static void ohci_send_request(struct fw_card *card, struct fw_packet *packet)
@@ -1689,7 +1700,7 @@ static int ohci_cancel_packet(struct fw_
 	struct fw_ohci *ohci = fw_ohci(card);
 	struct context *ctx = &ohci->at_request_ctx;
 	struct driver_data *driver_data = packet->driver_data;
-	int retval = -ENOENT;
+	int ret = -ENOENT;
 
 	tasklet_disable(&ctx->tasklet);
 
@@ -1704,23 +1715,22 @@ static int ohci_cancel_packet(struct fw_
 	driver_data->packet = NULL;
 	packet->ack = RCODE_CANCELLED;
 	packet->callback(packet, &ohci->card, packet->ack);
-	retval = 0;
-
+	ret = 0;
  out:
 	tasklet_enable(&ctx->tasklet);
 
-	return retval;
+	return ret;
 }
 
-static int
-ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+static int ohci_enable_phys_dma(struct fw_card *card,
+				int node_id, int generation)
 {
 #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
 	return 0;
 #else
 	struct fw_ohci *ohci = fw_ohci(card);
 	unsigned long flags;
-	int n, retval = 0;
+	int n, ret = 0;
 
 	/*
 	 * FIXME:  Make sure this bitmask is cleared when we clear the busReset
@@ -1730,7 +1740,7 @@ ohci_enable_phys_dma(struct fw_card *car
 	spin_lock_irqsave(&ohci->lock, flags);
 
 	if (ohci->generation != generation) {
-		retval = -ESTALE;
+		ret = -ESTALE;
 		goto out;
 	}
 
@@ -1748,12 +1758,12 @@ ohci_enable_phys_dma(struct fw_card *car
 	flush_writes(ohci);
  out:
 	spin_unlock_irqrestore(&ohci->lock, flags);
-	return retval;
+
+	return ret;
 #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
 }
 
-static u64
-ohci_get_bus_time(struct fw_card *card)
+static u64 ohci_get_bus_time(struct fw_card *card)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
 	u32 cycle_time;
@@ -1765,6 +1775,28 @@ ohci_get_bus_time(struct fw_card *card)
 	return bus_time;
 }
 
+static void copy_iso_headers(struct iso_context *ctx, void *p)
+{
+	int i = ctx->header_length;
+
+	if (i + ctx->base.header_size > PAGE_SIZE)
+		return;
+
+	/*
+	 * The iso header is byteswapped to little endian by
+	 * the controller, but the remaining header quadlets
+	 * are big endian.  We want to present all the headers
+	 * as big endian, so we have to swap the first quadlet.
+	 */
+	if (ctx->base.header_size > 0)
+		*(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
+	if (ctx->base.header_size > 4)
+		*(u32 *) (ctx->header + i + 4) = __swab32(*(u32 *) p);
+	if (ctx->base.header_size > 8)
+		memcpy(ctx->header + i + 8, p + 8, ctx->base.header_size - 8);
+	ctx->header_length += ctx->base.header_size;
+}
+
 static int handle_ir_dualbuffer_packet(struct context *context,
 				       struct descriptor *d,
 				       struct descriptor *last)
@@ -1775,7 +1807,6 @@ static int handle_ir_dualbuffer_packet(s
 	__le32 *ir_header;
 	size_t header_length;
 	void *p, *end;
-	int i;
 
 	if (db->first_res_count != 0 && db->second_res_count != 0) {
 		if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
@@ -1788,25 +1819,14 @@ static int handle_ir_dualbuffer_packet(s
 	header_length = le16_to_cpu(db->first_req_count) -
 		le16_to_cpu(db->first_res_count);
 
-	i = ctx->header_length;
 	p = db + 1;
 	end = p + header_length;
-	while (p < end && i + ctx->base.header_size <= PAGE_SIZE) {
-		/*
-		 * The iso header is byteswapped to little endian by
-		 * the controller, but the remaining header quadlets
-		 * are big endian.  We want to present all the headers
-		 * as big endian, so we have to swap the first
-		 * quadlet.
-		 */
-		*(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
-		memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
-		i += ctx->base.header_size;
+	while (p < end) {
+		copy_iso_headers(ctx, p);
 		ctx->excess_bytes +=
 			(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
-		p += ctx->base.header_size + 4;
+		p += max(ctx->base.header_size, (size_t)8);
 	}
-	ctx->header_length = i;
 
 	ctx->excess_bytes -= le16_to_cpu(db->second_req_count) -
 		le16_to_cpu(db->second_res_count);
@@ -1832,7 +1852,6 @@ static int handle_ir_packet_per_buffer(s
 	struct descriptor *pd;
 	__le32 *ir_header;
 	void *p;
-	int i;
 
 	for (pd = d; pd <= last; pd++) {
 		if (pd->transfer_status)
@@ -1842,21 +1861,8 @@ static int handle_ir_packet_per_buffer(s
 		/* Descriptor(s) not done yet, stop iteration */
 		return 0;
 
-	i   = ctx->header_length;
-	p   = last + 1;
-
-	if (ctx->base.header_size > 0 &&
-			i + ctx->base.header_size <= PAGE_SIZE) {
-		/*
-		 * The iso header is byteswapped to little endian by
-		 * the controller, but the remaining header quadlets
-		 * are big endian.  We want to present all the headers
-		 * as big endian, so we have to swap the first quadlet.
-		 */
-		*(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
-		memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
-		ctx->header_length += ctx->base.header_size;
-	}
+	p = last + 1;
+	copy_iso_headers(ctx, p);
 
 	if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
 		ir_header = (__le32 *) p;
@@ -1888,21 +1894,24 @@ static int handle_it_packet(struct conte
 	return 1;
 }
 
-static struct fw_iso_context *
-ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
+static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
+				int type, int channel, size_t header_size)
 {
 	struct fw_ohci *ohci = fw_ohci(card);
 	struct iso_context *ctx, *list;
 	descriptor_callback_t callback;
+	u64 *channels, dont_care = ~0ULL;
 	u32 *mask, regs;
 	unsigned long flags;
-	int index, retval = -ENOMEM;
+	int index, ret = -ENOMEM;
 
 	if (type == FW_ISO_CONTEXT_TRANSMIT) {
+		channels = &dont_care;
 		mask = &ohci->it_context_mask;
 		list = ohci->it_context_list;
 		callback = handle_it_packet;
 	} else {
+		channels = &ohci->ir_context_channels;
 		mask = &ohci->ir_context_mask;
 		list = ohci->ir_context_list;
 		if (ohci->use_dualbuffer)
@@ -1912,9 +1921,11 @@ ohci_allocate_iso_context(struct fw_card
 	}
 
 	spin_lock_irqsave(&ohci->lock, flags);
-	index = ffs(*mask) - 1;
-	if (index >= 0)
+	index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1;
+	if (index >= 0) {
+		*channels &= ~(1ULL << channel);
 		*mask &= ~(1 << index);
+	}
 	spin_unlock_irqrestore(&ohci->lock, flags);
 
 	if (index < 0)
@@ -1932,8 +1943,8 @@ ohci_allocate_iso_context(struct fw_card
 	if (ctx->header == NULL)
 		goto out;
 
-	retval = context_init(&ctx->context, ohci, regs, callback);
-	if (retval < 0)
+	ret = context_init(&ctx->context, ohci, regs, callback);
+	if (ret < 0)
 		goto out_with_header;
 
 	return &ctx->base;
@@ -1945,7 +1956,7 @@ ohci_allocate_iso_context(struct fw_card
 	*mask |= 1 << index;
 	spin_unlock_irqrestore(&ohci->lock, flags);
 
-	return ERR_PTR(retval);
+	return ERR_PTR(ret);
 }
 
 static int ohci_start_iso(struct fw_iso_context *base,
@@ -2024,16 +2035,16 @@ static void ohci_free_iso_context(struct
 	} else {
 		index = ctx - ohci->ir_context_list;
 		ohci->ir_context_mask |= 1 << index;
+		ohci->ir_context_channels |= 1ULL << base->channel;
 	}
 
 	spin_unlock_irqrestore(&ohci->lock, flags);
 }
 
-static int
-ohci_queue_iso_transmit(struct fw_iso_context *base,
-			struct fw_iso_packet *packet,
-			struct fw_iso_buffer *buffer,
-			unsigned long payload)
+static int ohci_queue_iso_transmit(struct fw_iso_context *base,
+				   struct fw_iso_packet *packet,
+				   struct fw_iso_buffer *buffer,
+				   unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
 	struct descriptor *d, *last, *pd;
@@ -2128,11 +2139,10 @@ ohci_queue_iso_transmit(struct fw_iso_co
 	return 0;
 }
 
-static int
-ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
-				  struct fw_iso_packet *packet,
-				  struct fw_iso_buffer *buffer,
-				  unsigned long payload)
+static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
+					     struct fw_iso_packet *packet,
+					     struct fw_iso_buffer *buffer,
+					     unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
 	struct db_descriptor *db = NULL;
@@ -2151,11 +2161,11 @@ ohci_queue_iso_receive_dualbuffer(struct
 	z = 2;
 
 	/*
-	 * The OHCI controller puts the status word in the header
-	 * buffer too, so we need 4 extra bytes per packet.
+	 * The OHCI controller puts the isochronous header and trailer in the
+	 * buffer, so we need at least 8 bytes.
 	 */
 	packet_count = p->header_length / ctx->base.header_size;
-	header_size = packet_count * (ctx->base.header_size + 4);
+	header_size = packet_count * max(ctx->base.header_size, (size_t)8);
 
 	/* Get header size in number of descriptors. */
 	header_z = DIV_ROUND_UP(header_size, sizeof(*d));
@@ -2173,7 +2183,8 @@ ohci_queue_iso_receive_dualbuffer(struct
 		db = (struct db_descriptor *) d;
 		db->control = cpu_to_le16(DESCRIPTOR_STATUS |
 					  DESCRIPTOR_BRANCH_ALWAYS);
-		db->first_size = cpu_to_le16(ctx->base.header_size + 4);
+		db->first_size =
+		    cpu_to_le16(max(ctx->base.header_size, (size_t)8));
 		if (p->skip && rest == p->payload_length) {
 			db->control |= cpu_to_le16(DESCRIPTOR_WAIT);
 			db->first_req_count = db->first_size;
@@ -2208,11 +2219,10 @@ ohci_queue_iso_receive_dualbuffer(struct
 	return 0;
 }
 
-static int
-ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
-					 struct fw_iso_packet *packet,
-					 struct fw_iso_buffer *buffer,
-					 unsigned long payload)
+static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
+					struct fw_iso_packet *packet,
+					struct fw_iso_buffer *buffer,
+					unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
 	struct descriptor *d = NULL, *pd = NULL;
@@ -2223,11 +2233,11 @@ ohci_queue_iso_receive_packet_per_buffer
 	int page, offset, packet_count, header_size, payload_per_buffer;
 
 	/*
-	 * The OHCI controller puts the status word in the
-	 * buffer too, so we need 4 extra bytes per packet.
+	 * The OHCI controller puts the isochronous header and trailer in the
+	 * buffer, so we need at least 8 bytes.
 	 */
 	packet_count = p->header_length / ctx->base.header_size;
-	header_size  = ctx->base.header_size + 4;
+	header_size  = max(ctx->base.header_size, (size_t)8);
 
 	/* Get header size in number of descriptors. */
 	header_z = DIV_ROUND_UP(header_size, sizeof(*d));
@@ -2286,29 +2296,27 @@ ohci_queue_iso_receive_packet_per_buffer
 	return 0;
 }
 
-static int
-ohci_queue_iso(struct fw_iso_context *base,
-	       struct fw_iso_packet *packet,
-	       struct fw_iso_buffer *buffer,
-	       unsigned long payload)
+static int ohci_queue_iso(struct fw_iso_context *base,
+			  struct fw_iso_packet *packet,
+			  struct fw_iso_buffer *buffer,
+			  unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
 	unsigned long flags;
-	int retval;
+	int ret;
 
 	spin_lock_irqsave(&ctx->context.ohci->lock, flags);
 	if (base->type == FW_ISO_CONTEXT_TRANSMIT)
-		retval = ohci_queue_iso_transmit(base, packet, buffer, payload);
+		ret = ohci_queue_iso_transmit(base, packet, buffer, payload);
 	else if (ctx->context.ohci->use_dualbuffer)
-		retval = ohci_queue_iso_receive_dualbuffer(base, packet,
-							 buffer, payload);
+		ret = ohci_queue_iso_receive_dualbuffer(base, packet,
+							buffer, payload);
 	else
-		retval = ohci_queue_iso_receive_packet_per_buffer(base, packet,
-								buffer,
-								payload);
+		ret = ohci_queue_iso_receive_packet_per_buffer(base, packet,
+							buffer, payload);
 	spin_unlock_irqrestore(&ctx->context.ohci->lock, flags);
 
-	return retval;
+	return ret;
 }
 
 static const struct fw_card_driver ohci_driver = {
@@ -2357,8 +2365,8 @@ static void ohci_pmac_off(struct pci_dev
 #define ohci_pmac_off(dev)
 #endif /* CONFIG_PPC_PMAC */
 
-static int __devinit
-pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+static int __devinit pci_probe(struct pci_dev *dev,
+			       const struct pci_device_id *ent)
 {
 	struct fw_ohci *ohci;
 	u32 bus_options, max_receive, link_speed, version;
@@ -2440,6 +2448,7 @@ pci_probe(struct pci_dev *dev, const str
 	ohci->it_context_list = kzalloc(size, GFP_KERNEL);
 
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
+	ohci->ir_context_channels = ~0ULL;
 	ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
 	size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask);
@@ -2467,11 +2476,12 @@ pci_probe(struct pci_dev *dev, const str
 		reg_read(ohci, OHCI1394_GUIDLo);
 
 	err = fw_card_add(&ohci->card, max_receive, link_speed, guid);
-	if (err < 0)
+	if (err)
 		goto fail_self_id;
 
 	fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
 		  dev_name(&dev->dev), version >> 16, version & 0xff);
+
 	return 0;
 
  fail_self_id:
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-sbp2.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-sbp2.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-sbp2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-sbp2.c	2009-06-09 23:05:27.000000000 -0400
@@ -392,20 +392,18 @@ static const struct {
 	}
 };
 
-static void
-free_orb(struct kref *kref)
+static void free_orb(struct kref *kref)
 {
 	struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref);
 
 	kfree(orb);
 }
 
-static void
-sbp2_status_write(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)
+static void sbp2_status_write(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 sbp2_logical_unit *lu = callback_data;
 	struct sbp2_orb *orb;
@@ -451,9 +449,8 @@ sbp2_status_write(struct fw_card *card,
 	fw_send_response(card, request, RCODE_COMPLETE);
 }
 
-static void
-complete_transaction(struct fw_card *card, int rcode,
-		     void *payload, size_t length, void *data)
+static void complete_transaction(struct fw_card *card, int rcode,
+				 void *payload, size_t length, void *data)
 {
 	struct sbp2_orb *orb = data;
 	unsigned long flags;
@@ -482,9 +479,8 @@ complete_transaction(struct fw_card *car
 	kref_put(&orb->kref, free_orb);
 }
 
-static void
-sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
-	      int node_id, int generation, u64 offset)
+static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
+			  int node_id, int generation, u64 offset)
 {
 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	unsigned long flags;
@@ -531,8 +527,8 @@ static int sbp2_cancel_orbs(struct sbp2_
 	return retval;
 }
 
-static void
-complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
+static void complete_management_orb(struct sbp2_orb *base_orb,
+				    struct sbp2_status *status)
 {
 	struct sbp2_management_orb *orb =
 		container_of(base_orb, struct sbp2_management_orb, base);
@@ -542,10 +538,9 @@ complete_management_orb(struct sbp2_orb
 	complete(&orb->done);
 }
 
-static int
-sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
-			 int generation, int function, int lun_or_login_id,
-			 void *response)
+static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+				    int generation, int function,
+				    int lun_or_login_id, void *response)
 {
 	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct sbp2_management_orb *orb;
@@ -652,9 +647,8 @@ static void sbp2_agent_reset(struct sbp2
 			   &d, sizeof(d));
 }
 
-static void
-complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
-				   void *payload, size_t length, void *data)
+static void complete_agent_reset_write_no_wait(struct fw_card *card,
+		int rcode, void *payload, size_t length, void *data)
 {
 	kfree(data);
 }
@@ -1299,8 +1293,7 @@ static void sbp2_unmap_scatterlist(struc
 				 sizeof(orb->page_table), DMA_TO_DEVICE);
 }
 
-static unsigned int
-sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
+static unsigned int sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
 {
 	int sam_status;
 
@@ -1337,8 +1330,8 @@ sbp2_status_to_sense_data(u8 *sbp2_statu
 	}
 }
 
-static void
-complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
+static void complete_command_orb(struct sbp2_orb *base_orb,
+				 struct sbp2_status *status)
 {
 	struct sbp2_command_orb *orb =
 		container_of(base_orb, struct sbp2_command_orb, base);
@@ -1384,9 +1377,8 @@ complete_command_orb(struct sbp2_orb *ba
 	orb->done(orb->cmd);
 }
 
-static int
-sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
-		     struct sbp2_logical_unit *lu)
+static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
+		struct fw_device *device, struct sbp2_logical_unit *lu)
 {
 	struct scatterlist *sg = scsi_sglist(orb->cmd);
 	int i, n;
@@ -1584,9 +1576,8 @@ static int sbp2_scsi_abort(struct scsi_c
  * This is the concatenation of target port identifier and logical unit
  * identifier as per SAM-2...SAM-4 annex A.
  */
-static ssize_t
-sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
-			    char *buf)
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	struct sbp2_logical_unit *lu;
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-topology.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-topology.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-topology.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-topology.c	2009-06-09 23:05:27.000000000 -0400
@@ -314,9 +314,8 @@ typedef void (*fw_node_callback_t)(struc
 				   struct fw_node * node,
 				   struct fw_node * parent);
 
-static void
-for_each_fw_node(struct fw_card *card, struct fw_node *root,
-		 fw_node_callback_t callback)
+static void for_each_fw_node(struct fw_card *card, struct fw_node *root,
+			     fw_node_callback_t callback)
 {
 	struct list_head list;
 	struct fw_node *node, *next, *child, *parent;
@@ -349,9 +348,8 @@ for_each_fw_node(struct fw_card *card, s
 		fw_node_put(node);
 }
 
-static void
-report_lost_node(struct fw_card *card,
-		 struct fw_node *node, struct fw_node *parent)
+static void report_lost_node(struct fw_card *card,
+			     struct fw_node *node, struct fw_node *parent)
 {
 	fw_node_event(card, node, FW_NODE_DESTROYED);
 	fw_node_put(node);
@@ -360,9 +358,8 @@ report_lost_node(struct fw_card *card,
 	card->bm_retries = 0;
 }
 
-static void
-report_found_node(struct fw_card *card,
-		  struct fw_node *node, struct fw_node *parent)
+static void report_found_node(struct fw_card *card,
+			      struct fw_node *node, struct fw_node *parent)
 {
 	int b_path = (node->phy_speed == SCODE_BETA);
 
@@ -415,8 +412,7 @@ static void move_tree(struct fw_node *no
  * found, lost or updated.  Update the nodes in the card topology tree
  * as we go.
  */
-static void
-update_tree(struct fw_card *card, struct fw_node *root)
+static void update_tree(struct fw_card *card, struct fw_node *root)
 {
 	struct list_head list0, list1;
 	struct fw_node *node0, *node1, *next1;
@@ -497,8 +493,8 @@ update_tree(struct fw_card *card, struct
 	}
 }
 
-static void
-update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
+static void update_topology_map(struct fw_card *card,
+				u32 *self_ids, int self_id_count)
 {
 	int node_count;
 
@@ -510,10 +506,8 @@ update_topology_map(struct fw_card *card
 	fw_compute_block_crc(card->topology_map);
 }
 
-void
-fw_core_handle_bus_reset(struct fw_card *card,
-			 int node_id, int generation,
-			 int self_id_count, u32 * self_ids)
+void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
+			      int self_id_count, u32 *self_ids)
 {
 	struct fw_node *local_node;
 	unsigned long flags;
@@ -532,6 +526,7 @@ fw_core_handle_bus_reset(struct fw_card
 
 	spin_lock_irqsave(&card->lock, flags);
 
+	card->broadcast_channel_allocated = false;
 	card->node_id = node_id;
 	/*
 	 * Update node_id before generation to prevent anybody from using
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-topology.h linux-libre-2.6.30-gnu1/drivers/firewire/fw-topology.h
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-topology.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-topology.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,11 @@
 #ifndef __fw_topology_h
 #define __fw_topology_h
 
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include <asm/atomic.h>
+
 enum {
 	FW_NODE_CREATED,
 	FW_NODE_UPDATED,
@@ -51,26 +56,22 @@ struct fw_node {
 	struct fw_node *ports[0];
 };
 
-static inline struct fw_node *
-fw_node_get(struct fw_node *node)
+static inline struct fw_node *fw_node_get(struct fw_node *node)
 {
 	atomic_inc(&node->ref_count);
 
 	return node;
 }
 
-static inline void
-fw_node_put(struct fw_node *node)
+static inline void fw_node_put(struct fw_node *node)
 {
 	if (atomic_dec_and_test(&node->ref_count))
 		kfree(node);
 }
 
-void
-fw_destroy_nodes(struct fw_card *card);
-
-int
-fw_compute_block_crc(u32 *block);
+struct fw_card;
+void fw_destroy_nodes(struct fw_card *card);
 
+int fw_compute_block_crc(u32 *block);
 
 #endif /* __fw_topology_h */
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-transaction.c linux-libre-2.6.30-gnu1/drivers/firewire/fw-transaction.c
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-transaction.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-transaction.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,10 +64,8 @@
 #define PHY_CONFIG_ROOT_ID(node_id)	((((node_id) & 0x3f) << 24) | (1 << 23))
 #define PHY_IDENTIFIER(id)		((id) << 30)
 
-static int
-close_transaction(struct fw_transaction *transaction,
-		  struct fw_card *card, int rcode,
-		  u32 *payload, size_t length)
+static int close_transaction(struct fw_transaction *transaction,
+			     struct fw_card *card, int rcode)
 {
 	struct fw_transaction *t;
 	unsigned long flags;
@@ -83,7 +81,7 @@ close_transaction(struct fw_transaction
 	spin_unlock_irqrestore(&card->lock, flags);
 
 	if (&t->link != &card->transaction_list) {
-		t->callback(card, rcode, payload, length, t->callback_data);
+		t->callback(card, rcode, NULL, 0, t->callback_data);
 		return 0;
 	}
 
@@ -94,9 +92,8 @@ close_transaction(struct fw_transaction
  * Only valid for transactions that are potentially pending (ie have
  * been sent).
  */
-int
-fw_cancel_transaction(struct fw_card *card,
-		      struct fw_transaction *transaction)
+int fw_cancel_transaction(struct fw_card *card,
+			  struct fw_transaction *transaction)
 {
 	/*
 	 * Cancel the packet transmission if it's still queued.  That
@@ -112,20 +109,19 @@ fw_cancel_transaction(struct fw_card *ca
 	 * if the transaction is still pending and remove it in that case.
 	 */
 
-	return close_transaction(transaction, card, RCODE_CANCELLED, NULL, 0);
+	return close_transaction(transaction, card, RCODE_CANCELLED);
 }
 EXPORT_SYMBOL(fw_cancel_transaction);
 
-static void
-transmit_complete_callback(struct fw_packet *packet,
-			   struct fw_card *card, int status)
+static void transmit_complete_callback(struct fw_packet *packet,
+				       struct fw_card *card, int status)
 {
 	struct fw_transaction *t =
 	    container_of(packet, struct fw_transaction, packet);
 
 	switch (status) {
 	case ACK_COMPLETE:
-		close_transaction(t, card, RCODE_COMPLETE, NULL, 0);
+		close_transaction(t, card, RCODE_COMPLETE);
 		break;
 	case ACK_PENDING:
 		t->timestamp = packet->timestamp;
@@ -133,31 +129,42 @@ transmit_complete_callback(struct fw_pac
 	case ACK_BUSY_X:
 	case ACK_BUSY_A:
 	case ACK_BUSY_B:
-		close_transaction(t, card, RCODE_BUSY, NULL, 0);
+		close_transaction(t, card, RCODE_BUSY);
 		break;
 	case ACK_DATA_ERROR:
-		close_transaction(t, card, RCODE_DATA_ERROR, NULL, 0);
+		close_transaction(t, card, RCODE_DATA_ERROR);
 		break;
 	case ACK_TYPE_ERROR:
-		close_transaction(t, card, RCODE_TYPE_ERROR, NULL, 0);
+		close_transaction(t, card, RCODE_TYPE_ERROR);
 		break;
 	default:
 		/*
 		 * In this case the ack is really a juju specific
 		 * rcode, so just forward that to the callback.
 		 */
-		close_transaction(t, card, status, NULL, 0);
+		close_transaction(t, card, status);
 		break;
 	}
 }
 
-static void
-fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
+static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
 		int destination_id, int source_id, int generation, int speed,
 		unsigned long long offset, void *payload, size_t length)
 {
 	int ext_tcode;
 
+	if (tcode == TCODE_STREAM_DATA) {
+		packet->header[0] =
+			HEADER_DATA_LENGTH(length) |
+			destination_id |
+			HEADER_TCODE(TCODE_STREAM_DATA);
+		packet->header_length = 4;
+		packet->payload = payload;
+		packet->payload_length = length;
+
+		goto common;
+	}
+
 	if (tcode > 0x10) {
 		ext_tcode = tcode & ~0x10;
 		tcode = TCODE_LOCK_REQUEST;
@@ -204,7 +211,7 @@ fw_fill_request(struct fw_packet *packet
 		packet->payload_length = 0;
 		break;
 	}
-
+ common:
 	packet->speed = speed;
 	packet->generation = generation;
 	packet->ack = 0;
@@ -246,13 +253,14 @@ fw_fill_request(struct fw_packet *packet
  * @param callback function to be called when the transaction is completed
  * @param callback_data pointer to arbitrary data, which will be
  *   passed to the callback
+ *
+ * In case of asynchronous stream packets i.e. TCODE_STREAM_DATA, the caller
+ * needs to synthesize @destination_id with fw_stream_packet_destination_id().
  */
-void
-fw_send_request(struct fw_card *card, struct fw_transaction *t,
-		int tcode, int destination_id, int generation, int speed,
-		unsigned long long offset,
-		void *payload, size_t length,
-		fw_transaction_callback_t callback, void *callback_data)
+void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
+		     int destination_id, int generation, int speed,
+		     unsigned long long offset, void *payload, size_t length,
+		     fw_transaction_callback_t callback, void *callback_data)
 {
 	unsigned long flags;
 	int tlabel;
@@ -322,16 +330,16 @@ static void transaction_callback(struct
  * Returns the RCODE.
  */
 int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
-		int generation, int speed, unsigned long long offset,
-		void *data, size_t length)
+		       int generation, int speed, unsigned long long offset,
+		       void *payload, size_t length)
 {
 	struct transaction_callback_data d;
 	struct fw_transaction t;
 
 	init_completion(&d.done);
-	d.payload = data;
+	d.payload = payload;
 	fw_send_request(card, &t, tcode, destination_id, generation, speed,
-			offset, data, length, transaction_callback, &d);
+			offset, payload, length, transaction_callback, &d);
 	wait_for_completion(&d.done);
 
 	return d.rcode;
@@ -399,9 +407,8 @@ void fw_flush_transactions(struct fw_car
 	}
 }
 
-static struct fw_address_handler *
-lookup_overlapping_address_handler(struct list_head *list,
-				   unsigned long long offset, size_t length)
+static struct fw_address_handler *lookup_overlapping_address_handler(
+	struct list_head *list, unsigned long long offset, size_t length)
 {
 	struct fw_address_handler *handler;
 
@@ -414,9 +421,8 @@ lookup_overlapping_address_handler(struc
 	return NULL;
 }
 
-static struct fw_address_handler *
-lookup_enclosing_address_handler(struct list_head *list,
-				 unsigned long long offset, size_t 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;
 
@@ -449,36 +455,44 @@ const struct fw_address_region fw_unit_s
 #endif  /*  0  */
 
 /**
- * Allocate a range of addresses in the node space of the OHCI
- * controller.  When a request is received that falls within the
- * specified address range, the specified callback is invoked.  The
- * parameters passed to the callback give the details of the
- * particular request.
+ * fw_core_add_address_handler - register for incoming requests
+ * @handler: callback
+ * @region: region in the IEEE 1212 node space address range
+ *
+ * region->start, ->end, and handler->length have to be quadlet-aligned.
+ *
+ * When a request is received that falls within the specified address range,
+ * the specified callback is invoked.  The parameters passed to the callback
+ * 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.
- * The offset is quadlet-aligned.
  */
-int
-fw_core_add_address_handler(struct fw_address_handler *handler,
-			    const struct fw_address_region *region)
+int fw_core_add_address_handler(struct fw_address_handler *handler,
+				const struct fw_address_region *region)
 {
 	struct fw_address_handler *other;
 	unsigned long flags;
 	int ret = -EBUSY;
 
+	if (region->start & 0xffff000000000003ULL ||
+	    region->end   & 0xffff000000000003ULL ||
+	    region->start >= region->end ||
+	    handler->length & 3 ||
+	    handler->length == 0)
+		return -EINVAL;
+
 	spin_lock_irqsave(&address_handler_lock, flags);
 
-	handler->offset = roundup(region->start, 4);
+	handler->offset = region->start;
 	while (handler->offset + handler->length <= region->end) {
 		other =
 		    lookup_overlapping_address_handler(&address_handler_list,
 						       handler->offset,
 						       handler->length);
 		if (other != NULL) {
-			handler->offset =
-			    roundup(other->offset + other->length, 4);
+			handler->offset += other->length;
 		} else {
 			list_add_tail(&handler->link, &address_handler_list);
 			ret = 0;
@@ -493,12 +507,7 @@ fw_core_add_address_handler(struct fw_ad
 EXPORT_SYMBOL(fw_core_add_address_handler);
 
 /**
- * Deallocate a range of addresses allocated with fw_allocate.  This
- * will call the associated callback one last time with a the special
- * tcode TCODE_DEALLOCATE, to let the client destroy the registered
- * callback data.  For convenience, the callback parameters offset and
- * length are set to the start and the length respectively for the
- * deallocated region, payload is set to NULL.
+ * fw_core_remove_address_handler - unregister an address handler
  */
 void fw_core_remove_address_handler(struct fw_address_handler *handler)
 {
@@ -518,9 +527,8 @@ struct fw_request {
 	u32 data[0];
 };
 
-static void
-free_response_callback(struct fw_packet *packet,
-		       struct fw_card *card, int status)
+static void free_response_callback(struct fw_packet *packet,
+				   struct fw_card *card, int status)
 {
 	struct fw_request *request;
 
@@ -528,9 +536,8 @@ free_response_callback(struct fw_packet
 	kfree(request);
 }
 
-void
-fw_fill_response(struct fw_packet *response, u32 *request_header,
-		 int rcode, void *payload, size_t length)
+void fw_fill_response(struct fw_packet *response, u32 *request_header,
+		      int rcode, void *payload, size_t length)
 {
 	int tcode, tlabel, extended_tcode, source, destination;
 
@@ -588,8 +595,7 @@ fw_fill_response(struct fw_packet *respo
 }
 EXPORT_SYMBOL(fw_fill_response);
 
-static struct fw_request *
-allocate_request(struct fw_packet *p)
+static struct fw_request *allocate_request(struct fw_packet *p)
 {
 	struct fw_request *request;
 	u32 *data, length;
@@ -649,8 +655,8 @@ allocate_request(struct fw_packet *p)
 	return request;
 }
 
-void
-fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
+void fw_send_response(struct fw_card *card,
+		      struct fw_request *request, int rcode)
 {
 	/* unified transaction or broadcast transaction: don't respond */
 	if (request->ack != ACK_PENDING ||
@@ -670,8 +676,7 @@ fw_send_response(struct fw_card *card, s
 }
 EXPORT_SYMBOL(fw_send_response);
 
-void
-fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
+void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
 {
 	struct fw_address_handler *handler;
 	struct fw_request *request;
@@ -719,8 +724,7 @@ fw_core_handle_request(struct fw_card *c
 }
 EXPORT_SYMBOL(fw_core_handle_request);
 
-void
-fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
+void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
 {
 	struct fw_transaction *t;
 	unsigned long flags;
@@ -793,12 +797,10 @@ static const struct fw_address_region to
 	{ .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP,
 	  .end   = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, };
 
-static void
-handle_topology_map(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)
+static void handle_topology_map(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)
 {
 	int i, start, end;
 	__be32 *map;
@@ -832,12 +834,10 @@ static const struct fw_address_region re
 	{ .start = CSR_REGISTER_BASE,
 	  .end   = CSR_REGISTER_BASE | CSR_CONFIG_ROM, };
 
-static void
-handle_registers(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)
+static void handle_registers(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)
 {
 	int reg = offset & ~CSR_REGISTER_BASE;
 	unsigned long long bus_time;
@@ -939,11 +939,11 @@ static struct fw_descriptor model_id_des
 
 static int __init fw_core_init(void)
 {
-	int retval;
+	int ret;
 
-	retval = bus_register(&fw_bus_type);
-	if (retval < 0)
-		return retval;
+	ret = bus_register(&fw_bus_type);
+	if (ret < 0)
+		return ret;
 
 	fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops);
 	if (fw_cdev_major < 0) {
@@ -951,19 +951,10 @@ static int __init fw_core_init(void)
 		return fw_cdev_major;
 	}
 
-	retval = fw_core_add_address_handler(&topology_map,
-					     &topology_map_region);
-	BUG_ON(retval < 0);
-
-	retval = fw_core_add_address_handler(&registers,
-					     &registers_region);
-	BUG_ON(retval < 0);
-
-	/* Add the vendor textual descriptor. */
-	retval = fw_core_add_descriptor(&vendor_id_descriptor);
-	BUG_ON(retval < 0);
-	retval = fw_core_add_descriptor(&model_id_descriptor);
-	BUG_ON(retval < 0);
+	fw_core_add_address_handler(&topology_map, &topology_map_region);
+	fw_core_add_address_handler(&registers, &registers_region);
+	fw_core_add_descriptor(&vendor_id_descriptor);
+	fw_core_add_descriptor(&model_id_descriptor);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/firewire/fw-transaction.h linux-libre-2.6.30-gnu1/drivers/firewire/fw-transaction.h
--- linux-libre-2.6.29-gnu1/drivers/firewire/fw-transaction.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firewire/fw-transaction.h	2009-06-09 23:05:27.000000000 -0400
@@ -82,14 +82,14 @@
 #define CSR_SPEED_MAP			0x2000
 #define CSR_SPEED_MAP_END		0x3000
 
+#define BANDWIDTH_AVAILABLE_INITIAL	4915
 #define BROADCAST_CHANNEL_INITIAL	(1 << 31 | 31)
 #define BROADCAST_CHANNEL_VALID		(1 << 30)
 
 #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
 #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
 
-static inline void
-fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
+static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
 {
 	u32    *dst = _dst;
 	__be32 *src = _src;
@@ -99,8 +99,7 @@ fw_memcpy_from_be32(void *_dst, void *_s
 		dst[i] = be32_to_cpu(src[i]);
 }
 
-static inline void
-fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
+static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
 {
 	fw_memcpy_from_be32(_dst, _src, size);
 }
@@ -125,8 +124,7 @@ typedef void (*fw_packet_callback_t)(str
 				     struct fw_card *card, int status);
 
 typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
-					  void *data,
-					  size_t length,
+					  void *data, size_t length,
 					  void *callback_data);
 
 /*
@@ -141,12 +139,6 @@ typedef void (*fw_address_callback_t)(st
 				      void *data, size_t length,
 				      void *callback_data);
 
-typedef void (*fw_bus_reset_callback_t)(struct fw_card *handle,
-					int node_id, int generation,
-					u32 *self_ids,
-					int self_id_count,
-					void *callback_data);
-
 struct fw_packet {
 	int speed;
 	int generation;
@@ -187,12 +179,6 @@ struct fw_transaction {
 	void *callback_data;
 };
 
-static inline struct fw_packet *
-fw_packet(struct list_head *l)
-{
-	return list_entry(l, struct fw_packet, link);
-}
-
 struct fw_address_handler {
 	u64 offset;
 	size_t length;
@@ -201,7 +187,6 @@ struct fw_address_handler {
 	struct list_head link;
 };
 
-
 struct fw_address_region {
 	u64 start;
 	u64 end;
@@ -255,6 +240,7 @@ struct fw_card {
 	int bm_retries;
 	int bm_generation;
 
+	bool broadcast_channel_allocated;
 	u32 broadcast_channel;
 	u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
 };
@@ -315,10 +301,8 @@ struct fw_iso_packet {
 struct fw_iso_context;
 
 typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
-				  u32 cycle,
-				  size_t header_length,
-				  void *header,
-				  void *data);
+				  u32 cycle, size_t header_length,
+				  void *header, void *data);
 
 /*
  * An iso buffer is just a set of pages mapped for DMA in the
@@ -344,36 +328,25 @@ struct fw_iso_context {
 	void *callback_data;
 };
 
-int
-fw_iso_buffer_init(struct fw_iso_buffer *buffer,
-		   struct fw_card *card,
-		   int page_count,
-		   enum dma_data_direction direction);
-int
-fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
-void
-fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
-
-struct fw_iso_context *
-fw_iso_context_create(struct fw_card *card, int type,
-		      int channel, int speed, size_t header_size,
-		      fw_iso_callback_t callback, void *callback_data);
-
-void
-fw_iso_context_destroy(struct fw_iso_context *ctx);
-
-int
-fw_iso_context_queue(struct fw_iso_context *ctx,
-		     struct fw_iso_packet *packet,
-		     struct fw_iso_buffer *buffer,
-		     unsigned long payload);
+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
+		       int page_count, enum dma_data_direction direction);
+int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
+void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
 
-int
-fw_iso_context_start(struct fw_iso_context *ctx,
-		     int cycle, int sync, int tags);
+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
+		int type, int channel, int speed, size_t header_size,
+		fw_iso_callback_t callback, void *callback_data);
+int fw_iso_context_queue(struct fw_iso_context *ctx,
+			 struct fw_iso_packet *packet,
+			 struct fw_iso_buffer *buffer,
+			 unsigned long payload);
+int fw_iso_context_start(struct fw_iso_context *ctx,
+			 int cycle, int sync, int tags);
+int fw_iso_context_stop(struct fw_iso_context *ctx);
+void fw_iso_context_destroy(struct fw_iso_context *ctx);
 
-int
-fw_iso_context_stop(struct fw_iso_context *ctx);
+void fw_iso_resource_manage(struct fw_card *card, int generation,
+		u64 channels_mask, int *channel, int *bandwidth, bool allocate);
 
 struct fw_card_driver {
 	/*
@@ -415,7 +388,7 @@ struct fw_card_driver {
 
 	struct fw_iso_context *
 	(*allocate_iso_context)(struct fw_card *card,
-				int type, size_t header_size);
+				int type, int channel, size_t header_size);
 	void (*free_iso_context)(struct fw_iso_context *ctx);
 
 	int (*start_iso)(struct fw_iso_context *ctx,
@@ -429,54 +402,45 @@ struct fw_card_driver {
 	int (*stop_iso)(struct fw_iso_context *ctx);
 };
 
-int
-fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
 
-void
-fw_send_request(struct fw_card *card, struct fw_transaction *t,
+void fw_send_request(struct fw_card *card, struct fw_transaction *t,
 		int tcode, int destination_id, int generation, int speed,
-		unsigned long long offset, void *data, size_t length,
+		unsigned long long offset, void *payload, size_t length,
 		fw_transaction_callback_t callback, void *callback_data);
-
-int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
-		       int generation, int speed, unsigned long long offset,
-		       void *data, size_t length);
-
 int fw_cancel_transaction(struct fw_card *card,
 			  struct fw_transaction *transaction);
-
 void fw_flush_transactions(struct fw_card *card);
-
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+		       int generation, int speed, unsigned long long offset,
+		       void *payload, size_t length);
 void fw_send_phy_config(struct fw_card *card,
 			int node_id, int generation, int gap_count);
 
+static inline int fw_stream_packet_destination_id(int tag, int channel, int sy)
+{
+	return tag << 14 | channel << 8 | sy;
+}
+
 /*
  * Called by the topology code to inform the device code of node
  * activity; found, lost, or updated nodes.
  */
-void
-fw_node_event(struct fw_card *card, struct fw_node *node, int event);
+void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
 
 /* API used by card level drivers */
 
-void
-fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
-		   struct device *device);
-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);
-
-void
-fw_core_handle_bus_reset(struct fw_card *card,
-			 int node_id, int generation,
-			 int self_id_count, u32 *self_ids);
-void
-fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
+void fw_card_initialize(struct fw_card *card,
+		const struct fw_card_driver *driver, struct device *device);
+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);
+void fw_core_handle_bus_reset(struct fw_card *card, int node_id,
+		int generation, int self_id_count, u32 *self_ids);
+void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
+void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
 
-void
-fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
+extern int fw_irm_set_broadcast_channel_register(struct device *dev,
+						 void *data);
 
 #endif /* __fw_transaction_h */
diff -druNp linux-libre-2.6.29-gnu1/drivers/firmware/dcdbas.c linux-libre-2.6.30-gnu1/drivers/firmware/dcdbas.c
--- linux-libre-2.6.29-gnu1/drivers/firmware/dcdbas.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firmware/dcdbas.c	2009-06-09 23:05:27.000000000 -0400
@@ -244,7 +244,7 @@ static ssize_t host_control_on_shutdown_
  */
 int dcdbas_smi_request(struct smi_cmd *smi_cmd)
 {
-	cpumask_t old_mask;
+	cpumask_var_t old_mask;
 	int ret = 0;
 
 	if (smi_cmd->magic != SMI_CMD_MAGIC) {
@@ -254,8 +254,11 @@ int dcdbas_smi_request(struct smi_cmd *s
 	}
 
 	/* SMI requires CPU 0 */
-	old_mask = current->cpus_allowed;
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(0));
+	if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
+		return -ENOMEM;
+
+	cpumask_copy(old_mask, &current->cpus_allowed);
+	set_cpus_allowed_ptr(current, cpumask_of(0));
 	if (smp_processor_id() != 0) {
 		dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
 			__func__);
@@ -275,7 +278,8 @@ int dcdbas_smi_request(struct smi_cmd *s
 	);
 
 out:
-	set_cpus_allowed_ptr(current, &old_mask);
+	set_cpus_allowed_ptr(current, old_mask);
+	free_cpumask_var(old_mask);
 	return ret;
 }
 
@@ -541,7 +545,7 @@ static int __devinit dcdbas_probe(struct
 	 * BIOS SMI calls require buffer addresses be in 32-bit address space.
 	 * This is done by setting the DMA mask below.
 	 */
-	dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+	dcdbas_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
 
 	error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
diff -druNp linux-libre-2.6.29-gnu1/drivers/firmware/dmi_scan.c linux-libre-2.6.30-gnu1/drivers/firmware/dmi_scan.c
--- linux-libre-2.6.29-gnu1/drivers/firmware/dmi_scan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firmware/dmi_scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,7 +68,8 @@ static char * __init dmi_string(const st
  *	pointing to completely the wrong place for example
  */
 static void dmi_table(u8 *buf, int len, int num,
-		      void (*decode)(const struct dmi_header *))
+		      void (*decode)(const struct dmi_header *, void *),
+		      void *private_data)
 {
 	u8 *data = buf;
 	int i = 0;
@@ -89,7 +90,7 @@ static void dmi_table(u8 *buf, int len,
 		while ((data - buf < len - 1) && (data[0] || data[1]))
 			data++;
 		if (data - buf < len - 1)
-			decode(dm);
+			decode(dm, private_data);
 		data += 2;
 		i++;
 	}
@@ -99,7 +100,8 @@ static u32 dmi_base;
 static u16 dmi_len;
 static u16 dmi_num;
 
-static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
+static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
+		void *))
 {
 	u8 *buf;
 
@@ -107,7 +109,7 @@ static int __init dmi_walk_early(void (*
 	if (buf == NULL)
 		return -1;
 
-	dmi_table(buf, dmi_len, dmi_num, decode);
+	dmi_table(buf, dmi_len, dmi_num, decode, NULL);
 
 	dmi_iounmap(buf, dmi_len);
 	return 0;
@@ -295,7 +297,7 @@ static void __init dmi_save_extended_dev
  *	and machine entries. For 2.5 we should pull the smbus controller info
  *	out of here.
  */
-static void __init dmi_decode(const struct dmi_header *dm)
+static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
 {
 	switch(dm->type) {
 	case 0:		/* BIOS Information */
@@ -598,10 +600,12 @@ int dmi_get_year(int field)
 /**
  *	dmi_walk - Walk the DMI table and get called back for every record
  *	@decode: Callback function
+ *	@private_data: Private data to be passed to the callback function
  *
  *	Returns -1 when the DMI table can't be reached, 0 on success.
  */
-int dmi_walk(void (*decode)(const struct dmi_header *))
+int dmi_walk(void (*decode)(const struct dmi_header *, void *),
+	     void *private_data)
 {
 	u8 *buf;
 
@@ -612,7 +616,7 @@ int dmi_walk(void (*decode)(const struct
 	if (buf == NULL)
 		return -1;
 
-	dmi_table(buf, dmi_len, dmi_num, decode);
+	dmi_table(buf, dmi_len, dmi_num, decode, private_data);
 
 	iounmap(buf);
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/firmware/iscsi_ibft.c linux-libre-2.6.30-gnu1/drivers/firmware/iscsi_ibft.c
--- linux-libre-2.6.29-gnu1/drivers/firmware/iscsi_ibft.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/firmware/iscsi_ibft.c	2009-06-09 23:05:27.000000000 -0400
@@ -754,11 +754,11 @@ static int __init ibft_check_nic_for(str
 		rc = 1;
 		break;
 	case ibft_eth_ip_addr:
-		if (!memcmp(nic->dhcp, nulls, sizeof(nic->dhcp)))
+		if (memcmp(nic->ip_addr, nulls, sizeof(nic->ip_addr)))
 			rc = 1;
 		break;
 	case ibft_eth_subnet_mask:
-		if (!memcmp(nic->dhcp, nulls, sizeof(nic->dhcp)))
+		if (nic->subnet_mask_prefix)
 			rc = 1;
 		break;
 	case ibft_eth_origin:
@@ -938,8 +938,8 @@ static int __init ibft_init(void)
 		return -ENOMEM;
 
 	if (ibft_addr) {
-		printk(KERN_INFO "iBFT detected at 0x%lx.\n",
-		       virt_to_phys((void *)ibft_addr));
+		printk(KERN_INFO "iBFT detected at 0x%llx.\n",
+		       (u64)virt_to_phys((void *)ibft_addr));
 
 		rc = ibft_check_device();
 		if (rc)
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpio/bt8xxgpio.c linux-libre-2.6.30-gnu1/drivers/gpio/bt8xxgpio.c
--- linux-libre-2.6.29-gnu1/drivers/gpio/bt8xxgpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpio/bt8xxgpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct
 {
 	struct gpio_chip *c = &bg->gpio;
 
-	c->label = bg->pdev->dev.bus_id;
+	c->label = dev_name(&bg->pdev->dev);
 	c->owner = THIS_MODULE;
 	c->direction_input = bt8xxgpio_gpio_direction_input;
 	c->get = bt8xxgpio_gpio_get;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpio/gpiolib.c linux-libre-2.6.30-gnu1/drivers/gpio/gpiolib.c
--- linux-libre-2.6.29-gnu1/drivers/gpio/gpiolib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpio/gpiolib.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,20 +69,24 @@ static inline void desc_set_label(struct
  * those calls have no teeth) we can't avoid autorequesting.  This nag
  * message should motivate switching to explicit requests... so should
  * the weaker cleanup after faults, compared to gpio_request().
+ *
+ * NOTE: the autorequest mechanism is going away; at this point it's
+ * only "legal" in the sense that (old) code using it won't break yet,
+ * but instead only triggers a WARN() stack dump.
  */
 static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
 {
-	if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
-		struct gpio_chip *chip = desc->chip;
-		int gpio = chip->base + offset;
+	const struct gpio_chip *chip = desc->chip;
+	const int gpio = chip->base + offset;
 
+	if (WARN(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0,
+			"autorequest GPIO-%d\n", gpio)) {
 		if (!try_module_get(chip->owner)) {
 			pr_err("GPIO-%d: module can't be gotten \n", gpio);
 			clear_bit(FLAG_REQUESTED, &desc->flags);
 			/* lose */
 			return -EIO;
 		}
-		pr_warning("GPIO-%d autorequested\n", gpio);
 		desc_set_label(desc, "[auto]");
 		/* caller must chip->request() w/o spinlock */
 		if (chip->request)
@@ -438,6 +442,7 @@ int gpio_export(unsigned gpio, bool dire
 	unsigned long		flags;
 	struct gpio_desc	*desc;
 	int			status = -EINVAL;
+	char			*ioname = NULL;
 
 	/* can't export until sysfs is available ... */
 	if (!gpio_class.p) {
@@ -461,11 +466,14 @@ int gpio_export(unsigned gpio, bool dire
 	}
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
+	if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
+		ioname = desc->chip->names[gpio - desc->chip->base];
+
 	if (status == 0) {
 		struct device	*dev;
 
 		dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-					desc, "gpio%d", gpio);
+				    desc, ioname ? ioname : "gpio%d", gpio);
 		if (dev) {
 			if (direction_may_change)
 				status = sysfs_create_group(&dev->kobj,
@@ -513,6 +521,7 @@ void gpio_unexport(unsigned gpio)
 	mutex_lock(&sysfs_lock);
 
 	desc = &gpio_desc[gpio];
+
 	if (test_bit(FLAG_EXPORT, &desc->flags)) {
 		struct device	*dev = NULL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpio/Kconfig linux-libre-2.6.30-gnu1/drivers/gpio/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/gpio/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpio/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -42,9 +42,9 @@ config DEBUG_GPIO
 	depends on DEBUG_KERNEL
 	help
 	  Say Y here to add some extra checks and diagnostics to GPIO calls.
-	  The checks help ensure that GPIOs have been properly initialized
-	  before they are used and that sleeping calls aren not made from
-	  nonsleeping contexts.  They can make bitbanged serial protocols
+	  These checks help ensure that GPIOs have been properly initialized
+	  before they are used, and that sleeping calls are not made from
+	  non-sleeping contexts.  They can make bitbanged serial protocols
 	  slower.  The diagnostics help catch the type of setup errors
 	  that are most common when setting up new platforms or boards.
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/ati_pcigart.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/ati_pcigart.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/ati_pcigart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/ati_pcigart.c	2009-06-09 23:05:27.000000000 -0400
@@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_d
 			if (!entry->busaddr[i])
 				break;
 			pci_unmap_page(dev->pdev, entry->busaddr[i],
-					 PAGE_SIZE, PCI_DMA_TODEVICE);
+					 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 		}
 
 		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
@@ -95,13 +95,14 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
 
 int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
 {
+	struct drm_local_map *map = &gart_info->mapping;
 	struct drm_sg_mem *entry = dev->sg;
 	void *address = NULL;
 	unsigned long pages;
-	u32 *pci_gart, page_base;
+	u32 *pci_gart = NULL, page_base, gart_idx;
 	dma_addr_t bus_address = 0;
 	int i, j, ret = 0;
-	int max_pages;
+	int max_ati_pages, max_real_pages;
 
 	if (!entry) {
 		DRM_ERROR("no scatter/gather memory!\n");
@@ -117,6 +118,7 @@ int drm_ati_pcigart_init(struct drm_devi
 			goto done;
 		}
 
+		pci_gart = gart_info->table_handle->vaddr;
 		address = gart_info->table_handle->vaddr;
 		bus_address = gart_info->table_handle->busaddr;
 	} else {
@@ -127,18 +129,23 @@ int drm_ati_pcigart_init(struct drm_devi
 			  (unsigned long)address);
 	}
 
-	pci_gart = (u32 *) address;
 
-	max_pages = (gart_info->table_size / sizeof(u32));
-	pages = (entry->pages <= max_pages)
-	    ? entry->pages : max_pages;
+	max_ati_pages = (gart_info->table_size / sizeof(u32));
+	max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+	pages = (entry->pages <= max_real_pages)
+	    ? entry->pages : max_real_pages;
 
-	memset(pci_gart, 0, max_pages * sizeof(u32));
+	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+		memset(pci_gart, 0, max_ati_pages * sizeof(u32));
+	} else {
+		memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32));
+	}
 
+	gart_idx = 0;
 	for (i = 0; i < pages; i++) {
 		/* we need to support large memory configurations */
 		entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
-						 0, PAGE_SIZE, PCI_DMA_TODEVICE);
+						 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 		if (entry->busaddr[i] == 0) {
 			DRM_ERROR("unable to map PCIGART pages!\n");
 			drm_ati_pcigart_cleanup(dev, gart_info);
@@ -149,19 +156,26 @@ int drm_ati_pcigart_init(struct drm_devi
 		page_base = (u32) entry->busaddr[i];
 
 		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+			u32 val;
+
 			switch(gart_info->gart_reg_if) {
 			case DRM_ATI_GART_IGP:
-				*pci_gart = cpu_to_le32((page_base) | 0xc);
+				val = page_base | 0xc;
 				break;
 			case DRM_ATI_GART_PCIE:
-				*pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
+				val = (page_base >> 8) | 0xc;
 				break;
 			default:
 			case DRM_ATI_GART_PCI:
-				*pci_gart = cpu_to_le32(page_base);
+				val = page_base;
 				break;
 			}
-			pci_gart++;
+			if (gart_info->gart_table_location ==
+			    DRM_ATI_GART_MAIN)
+				pci_gart[gart_idx] = cpu_to_le32(val);
+			else
+				DRM_WRITE32(map, gart_idx * sizeof(u32), val);
+			gart_idx++;
 			page_base += ATI_PCIGART_PAGE_SIZE;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_bufs.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_bufs.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_bufs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_bufs.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,15 +34,17 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/log2.h>
+#include <asm/shmparam.h>
 #include "drmP.h"
 
-unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource)
 {
 	return pci_resource_start(dev->pdev, resource);
 }
 EXPORT_SYMBOL(drm_get_resource_start);
 
-unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource)
 {
 	return pci_resource_len(dev->pdev, resource);
 }
@@ -50,24 +52,44 @@ unsigned long drm_get_resource_len(struc
 EXPORT_SYMBOL(drm_get_resource_len);
 
 static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
-					     drm_local_map_t *map)
+						  struct drm_local_map *map)
 {
 	struct drm_map_list *entry;
 	list_for_each_entry(entry, &dev->maplist, head) {
-		if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) &&
-		    ((entry->map->offset == map->offset) ||
-		     ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) {
+		/*
+		 * Because the kernel-userspace ABI is fixed at a 32-bit offset
+		 * while PCI resources may live above that, we ignore the map
+		 * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
+		 * It is assumed that each driver will have only one resource of
+		 * each type.
+		 */
+		if (!entry->map ||
+		    map->type != entry->map->type ||
+		    entry->master != dev->primary->master)
+			continue;
+		switch (map->type) {
+		case _DRM_SHM:
+			if (map->flags != _DRM_CONTAINS_LOCK)
+				break;
+		case _DRM_REGISTERS:
+		case _DRM_FRAME_BUFFER:
 			return entry;
+		default: /* Make gcc happy */
+			;
 		}
+		if (entry->map->offset == map->offset)
+			return entry;
 	}
 
 	return NULL;
 }
 
 static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
-			  unsigned long user_token, int hashed_handle)
+			  unsigned long user_token, int hashed_handle, int shm)
 {
-	int use_hashed_handle;
+	int use_hashed_handle, shift;
+	unsigned long add;
+
 #if (BITS_PER_LONG == 64)
 	use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
 #elif (BITS_PER_LONG == 32)
@@ -83,30 +105,47 @@ static int drm_map_handle(struct drm_dev
 		if (ret != -EINVAL)
 			return ret;
 	}
+
+	shift = 0;
+	add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT;
+	if (shm && (SHMLBA > PAGE_SIZE)) {
+		int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1;
+
+		/* For shared memory, we have to preserve the SHMLBA
+		 * bits of the eventual vma->vm_pgoff value during
+		 * mmap().  Otherwise we run into cache aliasing problems
+		 * on some platforms.  On these platforms, the pgoff of
+		 * a mmap() request is used to pick a suitable virtual
+		 * address for the mmap() region such that it will not
+		 * cause cache aliasing problems.
+		 *
+		 * Therefore, make sure the SHMLBA relevant bits of the
+		 * hash value we use are equal to those in the original
+		 * kernel virtual address.
+		 */
+		shift = bits;
+		add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL));
+	}
+
 	return drm_ht_just_insert_please(&dev->map_hash, hash,
 					 user_token, 32 - PAGE_SHIFT - 3,
-					 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
+					 shift, add);
 }
 
 /**
- * Ioctl to specify a range of memory that is available for mapping by a non-root process.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a drm_map structure.
- * \return zero on success or a negative value on error.
+ * Core function to create a range of memory available for mapping by a
+ * non-root process.
  *
  * Adjusts the memory offset to its absolute value according to the mapping
  * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
  * applicable and if supported by the kernel.
  */
-static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
+static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
 			   unsigned int size, enum drm_map_type type,
 			   enum drm_map_flags flags,
 			   struct drm_map_list ** maplist)
 {
-	struct drm_map *map;
+	struct drm_local_map *map;
 	struct drm_map_list *list;
 	drm_dma_handle_t *dmah;
 	unsigned long user_token;
@@ -129,9 +168,17 @@ static int drm_addmap_core(struct drm_de
 		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 		return -EINVAL;
 	}
-	DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-		  map->offset, map->size, map->type);
-	if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
+	DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
+		  (unsigned long long)map->offset, map->size, map->type);
+
+	/* page-align _DRM_SHM maps. They are allocated here so there is no security
+	 * hole created by that and it works around various broken drivers that use
+	 * a non-aligned quantity to map the SAREA. --BenH
+	 */
+	if (map->type == _DRM_SHM)
+		map->size = PAGE_ALIGN(map->size);
+
+	if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
 		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 		return -EINVAL;
 	}
@@ -259,7 +306,8 @@ static int drm_addmap_core(struct drm_de
 			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
 			return -EPERM;
 		}
-		DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
+		DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
+			  (unsigned long long)map->offset, map->size);
 
 		break;
 	case _DRM_GEM:
@@ -309,7 +357,8 @@ static int drm_addmap_core(struct drm_de
 	/* We do it here so that dev->struct_mutex protects the increment */
 	user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
 		map->offset;
-	ret = drm_map_handle(dev, &list->hash, user_token, 0);
+	ret = drm_map_handle(dev, &list->hash, user_token, 0,
+			     (map->type == _DRM_SHM));
 	if (ret) {
 		if (map->type == _DRM_REGISTERS)
 			iounmap(map->handle);
@@ -327,9 +376,9 @@ static int drm_addmap_core(struct drm_de
 	return 0;
 	}
 
-int drm_addmap(struct drm_device * dev, unsigned int offset,
+int drm_addmap(struct drm_device * dev, resource_size_t offset,
 	       unsigned int size, enum drm_map_type type,
-	       enum drm_map_flags flags, drm_local_map_t ** map_ptr)
+	       enum drm_map_flags flags, struct drm_local_map ** map_ptr)
 {
 	struct drm_map_list *list;
 	int rc;
@@ -342,6 +391,17 @@ int drm_addmap(struct drm_device * dev,
 
 EXPORT_SYMBOL(drm_addmap);
 
+/**
+ * Ioctl to specify a range of memory that is available for mapping by a
+ * non-root process.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a drm_map structure.
+ * \return zero on success or a negative value on error.
+ *
+ */
 int drm_addmap_ioctl(struct drm_device *dev, void *data,
 		     struct drm_file *file_priv)
 {
@@ -367,19 +427,13 @@ int drm_addmap_ioctl(struct drm_device *
  * Remove a map private from list and deallocate resources if the mapping
  * isn't in use.
  *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a struct drm_map structure.
- * \return zero on success or a negative value on error.
- *
  * Searches the map on drm_device::maplist, removes it from the list, see if
  * its being used, and free any associate resource (such as MTRR's) if it's not
  * being on use.
  *
  * \sa drm_addmap
  */
-int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
 {
 	struct drm_map_list *r_list = NULL, *list_t;
 	drm_dma_handle_t dmah;
@@ -442,7 +496,7 @@ int drm_rmmap_locked(struct drm_device *
 }
 EXPORT_SYMBOL(drm_rmmap_locked);
 
-int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap(struct drm_device *dev, struct drm_local_map *map)
 {
 	int ret;
 
@@ -462,12 +516,18 @@ EXPORT_SYMBOL(drm_rmmap);
  * One use case might be after addmap is allowed for normal users for SHM and
  * gets used by drivers that the server doesn't need to care about.  This seems
  * unlikely.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a struct drm_map structure.
+ * \return zero on success or a negative value on error.
  */
 int drm_rmmap_ioctl(struct drm_device *dev, void *data,
 		    struct drm_file *file_priv)
 {
 	struct drm_map *request = data;
-	drm_local_map_t *map = NULL;
+	struct drm_local_map *map = NULL;
 	struct drm_map_list *r_list;
 	int ret;
 
@@ -1534,7 +1594,7 @@ int drm_mapbufs(struct drm_device *dev,
 			&& (dma->flags & _DRM_DMA_USE_SG))
 		    || (drm_core_check_feature(dev, DRIVER_FB_DMA)
 			&& (dma->flags & _DRM_DMA_USE_FB))) {
-			struct drm_map *map = dev->agp_buffer_map;
+			struct drm_local_map *map = dev->agp_buffer_map;
 			unsigned long token = dev->agp_buffer_token;
 
 			if (!map) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_context.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_context.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_context.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_context.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,7 +143,7 @@ int drm_getsareactx(struct drm_device *d
 		    struct drm_file *file_priv)
 {
 	struct drm_ctx_priv_map *request = data;
-	struct drm_map *map;
+	struct drm_local_map *map;
 	struct drm_map_list *_entry;
 
 	mutex_lock(&dev->struct_mutex);
@@ -186,7 +186,7 @@ int drm_setsareactx(struct drm_device *d
 		    struct drm_file *file_priv)
 {
 	struct drm_ctx_priv_map *request = data;
-	struct drm_map *map = NULL;
+	struct drm_local_map *map = NULL;
 	struct drm_map_list *r_list = NULL;
 
 	mutex_lock(&dev->struct_mutex);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_crtc.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_crtc.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_crtc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_crtc.c	2009-06-09 23:05:27.000000000 -0400
@@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioct
 		}
 	}
 
-	if (connector->funcs->set_property)
+	/* Do DPMS ourselves */
+	if (property == connector->dev->mode_config.dpms_property) {
+		if (connector->funcs->dpms)
+			(*connector->funcs->dpms)(connector, (int) out_resp->value);
+		ret = 0;
+	} else if (connector->funcs->set_property)
 		ret = connector->funcs->set_property(connector, property, out_resp->value);
 
 	/* store the property value if succesful */
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_crtc_helper.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_crtc_helper.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_crtc_helper.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
 };
 
+static void drm_mode_validate_flag(struct drm_connector *connector,
+				   int flags)
+{
+	struct drm_display_mode *mode, *t;
+
+	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
+		return;
+
+	list_for_each_entry_safe(mode, t, &connector->modes, head) {
+		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+				!(flags & DRM_MODE_FLAG_INTERLACE))
+			mode->status = MODE_NO_INTERLACE;
+		if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+				!(flags & DRM_MODE_FLAG_DBLSCAN))
+			mode->status = MODE_NO_DBLESCAN;
+	}
+
+	return;
+}
+
 /**
  * drm_helper_probe_connector_modes - get complete set of display modes
  * @dev: DRM device
@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_mo
 	struct drm_connector_helper_funcs *connector_funcs =
 		connector->helper_private;
 	int count = 0;
+	int mode_flags = 0;
 
 	DRM_DEBUG("%s\n", drm_get_connector_name(connector));
 	/* set all modes to the unverified state */
@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_mo
 	if (maxX && maxY)
 		drm_mode_validate_size(dev, &connector->modes, maxX,
 				       maxY, 0);
+
+	if (connector->interlace_allowed)
+		mode_flags |= DRM_MODE_FLAG_INTERLACE;
+	if (connector->doublescan_allowed)
+		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+	drm_mode_validate_flag(connector, mode_flags);
+
 	list_for_each_entry_safe(mode, t, &connector->modes, head) {
 		if (mode->status == MODE_OK)
 			mode->status = connector_funcs->mode_valid(connector,
@@ -171,6 +199,29 @@ static void drm_helper_add_std_modes(str
 }
 
 /**
+ * drm_helper_encoder_in_use - check if a given encoder is in use
+ * @encoder: encoder to check
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Walk @encoders's DRM device's mode_config and see if it's in use.
+ *
+ * RETURNS:
+ * True if @encoder is part of the mode_config, false otherwise.
+ */
+bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
+{
+	struct drm_connector *connector;
+	struct drm_device *dev = encoder->dev;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		if (connector->encoder == encoder)
+			return true;
+	return false;
+}
+EXPORT_SYMBOL(drm_helper_encoder_in_use);
+
+/**
  * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
  * @crtc: CRTC to check
  *
@@ -188,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_c
 	struct drm_device *dev = crtc->dev;
 	/* FIXME: Locking around list access? */
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		if (encoder->crtc == crtc)
+		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
 			return true;
 	return false;
 }
@@ -212,7 +263,7 @@ void drm_helper_disable_unused_functions
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		encoder_funcs = encoder->helper_private;
-		if (!encoder->crtc)
+		if (!drm_helper_encoder_in_use(encoder))
 			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
 	}
 
@@ -533,7 +584,6 @@ bool drm_crtc_helper_set_mode(struct drm
 	int saved_x, saved_y;
 	struct drm_encoder *encoder;
 	bool ret = true;
-	bool depth_changed, bpp_changed;
 
 	adjusted_mode = drm_mode_duplicate(dev, mode);
 
@@ -542,15 +592,6 @@ bool drm_crtc_helper_set_mode(struct drm
 	if (!crtc->enabled)
 		return true;
 
-	if (old_fb && crtc->fb) {
-		depth_changed = (old_fb->depth != crtc->fb->depth);
-		bpp_changed = (old_fb->bits_per_pixel !=
-			       crtc->fb->bits_per_pixel);
-	} else {
-		depth_changed = true;
-		bpp_changed = true;
-	}
-
 	saved_mode = crtc->mode;
 	saved_x = crtc->x;
 	saved_y = crtc->y;
@@ -562,15 +603,6 @@ bool drm_crtc_helper_set_mode(struct drm
 	crtc->x = x;
 	crtc->y = y;
 
-	if (drm_mode_equal(&saved_mode, &crtc->mode)) {
-		if (saved_x != crtc->x || saved_y != crtc->y ||
-		    depth_changed || bpp_changed) {
-			ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
-							 old_fb);
-			goto done;
-		}
-	}
-
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -885,7 +917,6 @@ bool drm_helper_plugged_event(struct drm
 /**
  * drm_initial_config - setup a sane initial connector configuration
  * @dev: DRM device
- * @can_grow: this configuration is growable
  *
  * LOCKING:
  * Called at init time, must take mode config lock.
@@ -897,7 +928,7 @@ bool drm_helper_plugged_event(struct drm
  * RETURNS:
  * Zero if everything went ok, nonzero otherwise.
  */
-bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
+bool drm_helper_initial_config(struct drm_device *dev)
 {
 	struct drm_connector *connector;
 	int count = 0;
@@ -927,6 +958,88 @@ bool drm_helper_initial_config(struct dr
 }
 EXPORT_SYMBOL(drm_helper_initial_config);
 
+static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
+{
+	int dpms = DRM_MODE_DPMS_OFF;
+	struct drm_connector *connector;
+	struct drm_device *dev = encoder->dev;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		if (connector->encoder == encoder)
+			if (connector->dpms < dpms)
+				dpms = connector->dpms;
+	return dpms;
+}
+
+static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
+{
+	int dpms = DRM_MODE_DPMS_OFF;
+	struct drm_connector *connector;
+	struct drm_device *dev = crtc->dev;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		if (connector->encoder && connector->encoder->crtc == crtc)
+			if (connector->dpms < dpms)
+				dpms = connector->dpms;
+	return dpms;
+}
+
+/**
+ * drm_helper_connector_dpms
+ * @connector affected connector
+ * @mode DPMS mode
+ *
+ * Calls the low-level connector DPMS function, then
+ * calls appropriate encoder and crtc DPMS functions as well
+ */
+void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
+{
+	struct drm_encoder *encoder = connector->encoder;
+	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
+	int old_dpms;
+
+	if (mode == connector->dpms)
+		return;
+
+	old_dpms = connector->dpms;
+	connector->dpms = mode;
+
+	/* from off to on, do crtc then encoder */
+	if (mode < old_dpms) {
+		if (crtc) {
+			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+			if (crtc_funcs->dpms)
+				(*crtc_funcs->dpms) (crtc,
+						     drm_helper_choose_crtc_dpms(crtc));
+		}
+		if (encoder) {
+			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+			if (encoder_funcs->dpms)
+				(*encoder_funcs->dpms) (encoder,
+							drm_helper_choose_encoder_dpms(encoder));
+		}
+	}
+
+	/* from on to off, do encoder then crtc */
+	if (mode > old_dpms) {
+		if (encoder) {
+			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+			if (encoder_funcs->dpms)
+				(*encoder_funcs->dpms) (encoder,
+							drm_helper_choose_encoder_dpms(encoder));
+		}
+		if (crtc) {
+			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+			if (crtc_funcs->dpms)
+				(*crtc_funcs->dpms) (crtc,
+						     drm_helper_choose_crtc_dpms(crtc));
+		}
+	}
+
+	return;
+}
+EXPORT_SYMBOL(drm_helper_connector_dpms);
+
 /**
  * drm_hotplug_stage_two
  * @dev DRM device
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_debugfs.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,235 @@
+/**
+ * \file drm_debugfs.c
+ * debugfs support for DRM
+ *
+ * \author Ben Gamari <bgamari@gmail.com>
+ */
+
+/*
+ * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
+ *
+ * Copyright 2008 Ben Gamari <bgamari@gmail.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
+ * 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/debugfs.h>
+#include <linux/seq_file.h>
+#include "drmP.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+/***************************************************
+ * Initialization, etc.
+ **************************************************/
+
+static struct drm_info_list drm_debugfs_list[] = {
+	{"name", drm_name_info, 0},
+	{"vm", drm_vm_info, 0},
+	{"clients", drm_clients_info, 0},
+	{"queues", drm_queues_info, 0},
+	{"bufs", drm_bufs_info, 0},
+	{"gem_names", drm_gem_name_info, DRIVER_GEM},
+	{"gem_objects", drm_gem_object_info, DRIVER_GEM},
+#if DRM_DEBUG_CODE
+	{"vma", drm_vma_info, 0},
+#endif
+};
+#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list)
+
+
+static int drm_debugfs_open(struct inode *inode, struct file *file)
+{
+	struct drm_info_node *node = inode->i_private;
+
+	return single_open(file, node->info_ent->show, node);
+}
+
+
+static const struct file_operations drm_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_debugfs_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+
+/**
+ * Initialize a given set of debugfs files for a device
+ *
+ * \param files The array of files to create
+ * \param count The number of files given
+ * \param root DRI debugfs dir entry.
+ * \param minor device minor number
+ * \return Zero on success, non-zero on failure
+ *
+ * Create a given set of debugfs files represented by an array of
+ * gdm_debugfs_lists in the given root directory.
+ */
+int drm_debugfs_create_files(struct drm_info_list *files, int count,
+			     struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+	struct drm_info_node *tmp;
+	char name[64];
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		u32 features = files[i].driver_features;
+
+		if (features != 0 &&
+		    (dev->driver->driver_features & features) != features)
+			continue;
+
+		tmp = drm_alloc(sizeof(struct drm_info_node),
+				_DRM_DRIVER);
+		ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
+					  root, tmp, &drm_debugfs_fops);
+		if (!ent) {
+			DRM_ERROR("Cannot create /debugfs/dri/%s/%s\n",
+				  name, files[i].name);
+			drm_free(tmp, sizeof(struct drm_info_node),
+				 _DRM_DRIVER);
+			ret = -1;
+			goto fail;
+		}
+
+		tmp->minor = minor;
+		tmp->dent = ent;
+		tmp->info_ent = &files[i];
+		list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+	}
+	return 0;
+
+fail:
+	drm_debugfs_remove_files(files, count, minor);
+	return ret;
+}
+EXPORT_SYMBOL(drm_debugfs_create_files);
+
+/**
+ * Initialize the DRI debugfs filesystem for a device
+ *
+ * \param dev DRM device
+ * \param minor device minor number
+ * \param root DRI debugfs dir entry.
+ *
+ * Create the DRI debugfs root entry "/debugfs/dri", the device debugfs root entry
+ * "/debugfs/dri/%minor%/", and each entry in debugfs_list as
+ * "/debugfs/dri/%minor%/%name%".
+ */
+int drm_debugfs_init(struct drm_minor *minor, int minor_id,
+		     struct dentry *root)
+{
+	struct drm_device *dev = minor->dev;
+	char name[64];
+	int ret;
+
+	INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+	sprintf(name, "%d", minor_id);
+	minor->debugfs_root = debugfs_create_dir(name, root);
+	if (!minor->debugfs_root) {
+		DRM_ERROR("Cannot create /debugfs/dri/%s\n", name);
+		return -1;
+	}
+
+	ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
+				       minor->debugfs_root, minor);
+	if (ret) {
+		debugfs_remove(minor->debugfs_root);
+		minor->debugfs_root = NULL;
+		DRM_ERROR("Failed to create core drm debugfs files\n");
+		return ret;
+	}
+
+	if (dev->driver->debugfs_init) {
+		ret = dev->driver->debugfs_init(minor);
+		if (ret) {
+			DRM_ERROR("DRM: Driver failed to initialize "
+				  "/debugfs/dri.\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+
+/**
+ * Remove a list of debugfs files
+ *
+ * \param files The list of files
+ * \param count The number of files
+ * \param minor The minor of which we should remove the files
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_remove_files(struct drm_info_list *files, int count,
+			     struct drm_minor *minor)
+{
+	struct list_head *pos, *q;
+	struct drm_info_node *tmp;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+			tmp = list_entry(pos, struct drm_info_node, list);
+			if (tmp->info_ent == &files[i]) {
+				debugfs_remove(tmp->dent);
+				list_del(pos);
+				drm_free(tmp, sizeof(struct drm_info_node),
+					 _DRM_DRIVER);
+			}
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_debugfs_remove_files);
+
+/**
+ * Cleanup the debugfs filesystem resources.
+ *
+ * \param minor device minor number.
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_cleanup(struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+
+	if (!minor->debugfs_root)
+		return 0;
+
+	if (dev->driver->debugfs_cleanup)
+		dev->driver->debugfs_cleanup(minor);
+
+	drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, minor);
+
+	debugfs_remove(minor->debugfs_root);
+	minor->debugfs_root = NULL;
+
+	return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_drv.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_drv.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_drv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_drv.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,9 +46,11 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/debugfs.h>
 #include "drmP.h"
 #include "drm_core.h"
 
+
 static int drm_version(struct drm_device *dev, void *data,
 		       struct drm_file *file_priv);
 
@@ -178,7 +180,7 @@ int drm_lastclose(struct drm_device * de
 
 	/* Clear AGP information */
 	if (drm_core_has_AGP(dev) && dev->agp &&
-	    !drm_core_check_feature(dev, DRIVER_MODESET)) {
+			!drm_core_check_feature(dev, DRIVER_MODESET)) {
 		struct drm_agp_mem *entry, *tempe;
 
 		/* Remove AGP resources, but leave dev->agp
@@ -252,15 +254,19 @@ int drm_lastclose(struct drm_device * de
 int drm_init(struct drm_driver *driver)
 {
 	struct pci_dev *pdev = NULL;
-	struct pci_device_id *pid;
+	const struct pci_device_id *pid;
 	int i;
 
 	DRM_DEBUG("\n");
 
 	INIT_LIST_HEAD(&driver->device_list);
 
+	if (driver->driver_features & DRIVER_MODESET)
+		return pci_register_driver(&driver->pci_driver);
+
+	/* If not using KMS, fall back to stealth mode manual scanning. */
 	for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
-		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+		pid = &driver->pci_driver.id_table[i];
 
 		/* Loop around setting up a DRM device for each PCI device
 		 * matching our ID and device class.  If we had the internal
@@ -285,68 +291,17 @@ int drm_init(struct drm_driver *driver)
 
 EXPORT_SYMBOL(drm_init);
 
-/**
- * Called via cleanup_module() at module unload time.
- *
- * Cleans up all DRM device, calling drm_lastclose().
- *
- * \sa drm_init
- */
-static void drm_cleanup(struct drm_device * dev)
-{
-	struct drm_map_list *r_list, *list_temp;
-	DRM_DEBUG("\n");
-
-	if (!dev) {
-		DRM_ERROR("cleanup called no dev\n");
-		return;
-	}
-
-	drm_vblank_cleanup(dev);
-
-	drm_lastclose(dev);
-
-	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
-	    dev->agp && dev->agp->agp_mtrr >= 0) {
-		int retval;
-		retval = mtrr_del(dev->agp->agp_mtrr,
-				  dev->agp->agp_info.aper_base,
-				  dev->agp->agp_info.aper_size * 1024 * 1024);
-		DRM_DEBUG("mtrr_del=%d\n", retval);
-	}
-
-	if (dev->driver->unload)
-		dev->driver->unload(dev);
-
-	if (drm_core_has_AGP(dev) && dev->agp) {
-		drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-		dev->agp = NULL;
-	}
-
-	drm_ht_remove(&dev->map_hash);
-	drm_ctxbitmap_cleanup(dev);
-
-	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
-		drm_rmmap(dev, r_list->map);
-
-	if (drm_core_check_feature(dev, DRIVER_MODESET))
-		drm_put_minor(&dev->control);
-
-	if (dev->driver->driver_features & DRIVER_GEM)
-		drm_gem_destroy(dev);
-
-	drm_put_minor(&dev->primary);
-	if (drm_put_dev(dev))
-		DRM_ERROR("Cannot unload module\n");
-}
-
 void drm_exit(struct drm_driver *driver)
 {
 	struct drm_device *dev, *tmp;
 	DRM_DEBUG("\n");
 
-	list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
-		drm_cleanup(dev);
+	if (driver->driver_features & DRIVER_MODESET) {
+		pci_unregister_driver(&driver->pci_driver);
+	} else {
+		list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
+			drm_put_dev(dev);
+	}
 
 	DRM_INFO("Module unloaded\n");
 }
@@ -382,6 +337,13 @@ static int __init drm_core_init(void)
 		goto err_p3;
 	}
 
+	drm_debugfs_root = debugfs_create_dir("dri", NULL);
+	if (!drm_debugfs_root) {
+		DRM_ERROR("Cannot create /debugfs/dri\n");
+		ret = -1;
+		goto err_p3;
+	}
+
 	drm_mem_init();
 
 	DRM_INFO("Initialized %s %d.%d.%d %s\n",
@@ -400,6 +362,7 @@ err_p1:
 static void __exit drm_core_exit(void)
 {
 	remove_proc_entry("dri", NULL);
+	debugfs_remove(drm_debugfs_root);
 	drm_sysfs_destroy();
 
 	unregister_chrdev(DRM_MAJOR, "drm");
@@ -458,6 +421,7 @@ int drm_ioctl(struct inode *inode, struc
 	drm_ioctl_t *func;
 	unsigned int nr = DRM_IOCTL_NR(cmd);
 	int retcode = -EINVAL;
+	char stack_kdata[128];
 	char *kdata = NULL;
 
 	atomic_inc(&dev->ioctl_count);
@@ -492,14 +456,19 @@ int drm_ioctl(struct inode *inode, struc
 		retcode = -EINVAL;
 	} else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
 		   ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
-		   ((ioctl->flags & DRM_MASTER) && !file_priv->is_master)) {
+		   ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) ||
+		   (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL))) {
 		retcode = -EACCES;
 	} else {
 		if (cmd & (IOC_IN | IOC_OUT)) {
-			kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
-			if (!kdata) {
-				retcode = -ENOMEM;
-				goto err_i1;
+			if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) {
+				kdata = stack_kdata;
+			} else {
+				kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+				if (!kdata) {
+					retcode = -ENOMEM;
+					goto err_i1;
+				}
 			}
 		}
 
@@ -512,7 +481,7 @@ int drm_ioctl(struct inode *inode, struc
 		}
 		retcode = func(dev, kdata, file_priv);
 
-		if ((retcode == 0) && (cmd & IOC_OUT)) {
+		if (cmd & IOC_OUT) {
 			if (copy_to_user((void __user *)arg, kdata,
 					 _IOC_SIZE(cmd)) != 0)
 				retcode = -EFAULT;
@@ -520,7 +489,7 @@ int drm_ioctl(struct inode *inode, struc
 	}
 
       err_i1:
-	if (kdata)
+	if (kdata != stack_kdata)
 		kfree(kdata);
 	atomic_dec(&dev->ioctl_count);
 	if (retcode)
@@ -530,7 +499,7 @@ int drm_ioctl(struct inode *inode, struc
 
 EXPORT_SYMBOL(drm_ioctl);
 
-drm_local_map_t *drm_getsarea(struct drm_device *dev)
+struct drm_local_map *drm_getsarea(struct drm_device *dev)
 {
 	struct drm_map_list *entry;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_edid.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_edid.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_edid.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_edid.c	2009-06-09 23:05:27.000000000 -0400
@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *e
 		DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
 		goto bad;
 	}
-	if (edid->revision > 3) {
-		DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
-		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];
@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edi
 	edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
 	edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
 			  ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
-	edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@';
+	edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
 
 	return !strncmp(edid_vendor, vendor, 3);
 }
@@ -291,6 +289,11 @@ static struct drm_display_mode *drm_mode
 	struct drm_display_mode *mode;
 	struct detailed_pixel_timing *pt = &timing->data.pixel_data;
 
+	/* ignore tiny modes */
+	if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 ||
+	    ((pt->vactive_hi << 8) | pt->hactive_lo) < 64)
+		return NULL;
+
 	if (pt->stereo) {
 		printk(KERN_WARNING "stereo mode not supported\n");
 		return NULL;
@@ -550,11 +553,20 @@ static int add_detailed_info(struct drm_
 }
 
 #define DDC_ADDR 0x50
-
-unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
+/**
+ * Get EDID information via I2C.
+ *
+ * \param adapter : i2c device adaptor
+ * \param buf     : EDID data buffer to be filled
+ * \param len     : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Try to fetch EDID information by calling i2c driver function.
+ */
+int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
+			  unsigned char *buf, int len)
 {
 	unsigned char start = 0x0;
-	unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	struct i2c_msg msgs[] = {
 		{
 			.addr	= DDC_ADDR,
@@ -564,31 +576,36 @@ unsigned char *drm_do_probe_ddc_edid(str
 		}, {
 			.addr	= DDC_ADDR,
 			.flags	= I2C_M_RD,
-			.len	= EDID_LENGTH,
+			.len	= len,
 			.buf	= buf,
 		}
 	};
 
-	if (!buf) {
-		dev_warn(&adapter->dev, "unable to allocate memory for EDID "
-			 "block.\n");
-		return NULL;
-	}
-
 	if (i2c_transfer(adapter, msgs, 2) == 2)
-		return buf;
+		return 0;
 
 	dev_info(&adapter->dev, "unable to read EDID block.\n");
-	kfree(buf);
-	return NULL;
+	return -1;
 }
 EXPORT_SYMBOL(drm_do_probe_ddc_edid);
 
-static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
+/**
+ * Get EDID information.
+ *
+ * \param adapter : i2c device adaptor.
+ * \param buf     : EDID data buffer to be filled
+ * \param len     : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Initialize DDC, then fetch EDID information
+ * by calling drm_do_probe_ddc_edid function.
+ */
+static int drm_ddc_read(struct i2c_adapter *adapter,
+			unsigned char *buf, int len)
 {
 	struct i2c_algo_bit_data *algo_data = adapter->algo_data;
-	unsigned char *edid = NULL;
 	int i, j;
+	int ret = -1;
 
 	algo_data->setscl(algo_data->data, 1);
 
@@ -616,7 +633,7 @@ static unsigned char *drm_ddc_read(struc
 		msleep(15);
 
 		/* Do the real work */
-		edid = drm_do_probe_ddc_edid(adapter);
+		ret = drm_do_probe_ddc_edid(adapter, buf, len);
 		algo_data->setsda(algo_data->data, 0);
 		algo_data->setscl(algo_data->data, 0);
 		msleep(15);
@@ -632,7 +649,7 @@ static unsigned char *drm_ddc_read(struc
 		msleep(15);
 		algo_data->setscl(algo_data->data, 0);
 		algo_data->setsda(algo_data->data, 0);
-		if (edid)
+		if (ret == 0)
 			break;
 	}
 	/* Release the DDC lines when done or the Apple Cinema HD display
@@ -641,9 +658,31 @@ static unsigned char *drm_ddc_read(struc
 	algo_data->setsda(algo_data->data, 1);
 	algo_data->setscl(algo_data->data, 1);
 
-	return edid;
+	return ret;
 }
 
+static int drm_ddc_read_edid(struct drm_connector *connector,
+			     struct i2c_adapter *adapter,
+			     char *buf, int len)
+{
+	int ret;
+
+	ret = drm_ddc_read(adapter, buf, len);
+	if (ret != 0) {
+		dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
+			 drm_get_connector_name(connector));
+		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;
+	}
+end:
+	return ret;
+}
+
+#define MAX_EDID_EXT_NUM 4
 /**
  * drm_get_edid - get EDID data, if available
  * @connector: connector we're probing
@@ -656,27 +695,118 @@ static unsigned char *drm_ddc_read(struc
 struct edid *drm_get_edid(struct drm_connector *connector,
 			  struct i2c_adapter *adapter)
 {
+	int ret;
 	struct edid *edid;
 
-	edid = (struct edid *)drm_ddc_read(adapter);
-	if (!edid) {
-		dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
-			 drm_get_connector_name(connector));
-		return NULL;
+	edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
+		       GFP_KERNEL);
+	if (edid == NULL) {
+		dev_warn(&connector->dev->pdev->dev,
+			 "Failed to allocate EDID\n");
+		goto end;
 	}
-	if (!edid_is_valid(edid)) {
-		dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
-			 drm_get_connector_name(connector));
-		kfree(edid);
-		return NULL;
+
+	/* Read first EDID block */
+	ret = drm_ddc_read_edid(connector, adapter,
+				(unsigned char *)edid, EDID_LENGTH);
+	if (ret != 0)
+		goto clean_up;
+
+	/* There are EDID extensions to be read */
+	if (edid->extensions != 0) {
+		int edid_ext_num = edid->extensions;
+
+		if (edid_ext_num > MAX_EDID_EXT_NUM) {
+			dev_warn(&connector->dev->pdev->dev,
+				 "The number of extension(%d) is "
+				 "over max (%d), actually read number (%d)\n",
+				 edid_ext_num, MAX_EDID_EXT_NUM,
+				 MAX_EDID_EXT_NUM);
+			/* Reset EDID extension number to be read */
+			edid_ext_num = MAX_EDID_EXT_NUM;
+		}
+		/* Read EDID including extensions too */
+		ret = drm_ddc_read_edid(connector, adapter, (char *)edid,
+					EDID_LENGTH * (edid_ext_num + 1));
+		if (ret != 0)
+			goto clean_up;
+
 	}
 
 	connector->display_info.raw_edid = (char *)edid;
+	goto end;
 
+clean_up:
+	kfree(edid);
+	edid = NULL;
+end:
 	return edid;
+
 }
 EXPORT_SYMBOL(drm_get_edid);
 
+#define HDMI_IDENTIFIER 0x000C03
+#define VENDOR_BLOCK    0x03
+/**
+ * drm_detect_hdmi_monitor - detect whether monitor is hdmi.
+ * @edid: monitor EDID information
+ *
+ * Parse the CEA extension according to CEA-861-B.
+ * Return true if HDMI, false if not or unknown.
+ */
+bool drm_detect_hdmi_monitor(struct edid *edid)
+{
+	char *edid_ext = NULL;
+	int i, hdmi_id, edid_ext_num;
+	int start_offset, end_offset;
+	bool is_hdmi = false;
+
+	/* No EDID or EDID extensions */
+	if (edid == NULL || edid->extensions == 0)
+		goto end;
+
+	/* Chose real EDID extension number */
+	edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
+		       MAX_EDID_EXT_NUM : edid->extensions;
+
+	/* Find CEA extension */
+	for (i = 0; i < edid_ext_num; i++) {
+		edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
+		/* This block is CEA extension */
+		if (edid_ext[0] == 0x02)
+			break;
+	}
+
+	if (i == edid_ext_num)
+		goto end;
+
+	/* Data block offset in CEA extension block */
+	start_offset = 4;
+	end_offset = edid_ext[2];
+
+	/*
+	 * Because HDMI identifier is in Vendor Specific Block,
+	 * search it from all data blocks of CEA extension.
+	 */
+	for (i = start_offset; i < end_offset;
+		/* Increased by data block len */
+		i += ((edid_ext[i] & 0x1f) + 1)) {
+		/* Find vendor specific block */
+		if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
+			hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
+				  edid_ext[i + 3] << 16;
+			/* Find HDMI identifier */
+			if (hdmi_id == HDMI_IDENTIFIER)
+				is_hdmi = true;
+			break;
+		}
+	}
+
+end:
+	return is_hdmi;
+}
+EXPORT_SYMBOL(drm_detect_hdmi_monitor);
+
 /**
  * drm_add_edid_modes - add modes from EDID data, if available
  * @connector: connector we're probing
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_fops.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_fops.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_fops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_fops.c	2009-06-09 23:05:27.000000000 -0400
@@ -274,6 +274,7 @@ static int drm_open_helper(struct inode
 		/* create a new master */
 		priv->minor->master = drm_master_create(priv->minor);
 		if (!priv->minor->master) {
+			mutex_unlock(&dev->struct_mutex);
 			ret = -ENOMEM;
 			goto out_free;
 		}
@@ -337,14 +338,10 @@ int drm_fasync(int fd, struct file *filp
 {
 	struct drm_file *priv = filp->private_data;
 	struct drm_device *dev = priv->minor->dev;
-	int retcode;
 
 	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
 		  (long)old_encode_dev(priv->minor->device));
-	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-	if (retcode < 0)
-		return retcode;
-	return 0;
+	return fasync_helper(fd, filp, on, &dev->buf_async);
 }
 EXPORT_SYMBOL(drm_fasync);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_gem.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_gem.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_gem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_gem.c	2009-06-09 23:05:27.000000000 -0400
@@ -502,10 +502,9 @@ int drm_gem_mmap(struct file *filp, stru
 	struct drm_file *priv = filp->private_data;
 	struct drm_device *dev = priv->minor->dev;
 	struct drm_gem_mm *mm = dev->mm_private;
-	struct drm_map *map = NULL;
+	struct drm_local_map *map = NULL;
 	struct drm_gem_object *obj;
 	struct drm_hash_item *hash;
-	unsigned long prot;
 	int ret = 0;
 
 	mutex_lock(&dev->struct_mutex);
@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, stru
 	vma->vm_ops = obj->dev->driver->gem_vm_ops;
 	vma->vm_private_data = map->handle;
 	/* FIXME: use pgprot_writecombine when available */
-	prot = pgprot_val(vma->vm_page_prot);
-#ifdef CONFIG_X86
-	prot |= _PAGE_CACHE_WC;
-#endif
-	vma->vm_page_prot = __pgprot(prot);
+	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
 	/* Take a ref for this mapping of the object, so that the fault
 	 * handler can dereference the mmap offset's pointer to the object.
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_info.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_info.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_info.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_info.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,328 @@
+/**
+ * \file drm_info.c
+ * DRM info file implementations
+ *
+ * \author Ben Gamari <bgamari@gmail.com>
+ */
+
+/*
+ * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright 2008 Ben Gamari <bgamari@gmail.com>
+ * 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/seq_file.h>
+#include "drmP.h"
+
+/**
+ * Called when "/proc/dri/.../name" is read.
+ *
+ * Prints the device name together with the bus id if available.
+ */
+int drm_name_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_master *master = minor->master;
+
+	if (!master)
+		return 0;
+
+	if (master->unique) {
+		seq_printf(m, "%s %s %s\n",
+			   dev->driver->pci_driver.name,
+			   pci_name(dev->pdev), master->unique);
+	} else {
+		seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
+			   pci_name(dev->pdev));
+	}
+
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../vm" is read.
+ *
+ * Prints information about all mappings in drm_device::maplist.
+ */
+int drm_vm_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;
+	struct drm_local_map *map;
+	struct drm_map_list *r_list;
+
+	/* Hardcoded from _DRM_FRAME_BUFFER,
+	   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+	   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+	const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
+	const char *type;
+	int i;
+
+	mutex_lock(&dev->struct_mutex);
+	seq_printf(m, "slot	 offset	      size type flags	 address mtrr\n\n");
+	i = 0;
+	list_for_each_entry(r_list, &dev->maplist, head) {
+		map = r_list->map;
+		if (!map)
+			continue;
+		if (map->type < 0 || map->type > 5)
+			type = "??";
+		else
+			type = types[map->type];
+
+		seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s  0x%02x 0x%08lx ",
+			   i,
+			   (unsigned long long)map->offset,
+			   map->size, type, map->flags,
+			   (unsigned long) r_list->user_token);
+		if (map->mtrr < 0)
+			seq_printf(m, "none\n");
+		else
+			seq_printf(m, "%4d\n", map->mtrr);
+		i++;
+	}
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../queues" is read.
+ */
+int drm_queues_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;
+	int i;
+	struct drm_queue *q;
+
+	mutex_lock(&dev->struct_mutex);
+	seq_printf(m, "  ctx/flags   use   fin"
+		   "   blk/rw/rwf  wait    flushed	   queued"
+		   "      locks\n\n");
+	for (i = 0; i < dev->queue_count; i++) {
+		q = dev->queuelist[i];
+		atomic_inc(&q->use_count);
+		seq_printf(m,   "%5d/0x%03x %5d %5d"
+			   " %5d/%c%c/%c%c%c %5Zd\n",
+			   i,
+			   q->flags,
+			   atomic_read(&q->use_count),
+			   atomic_read(&q->finalization),
+			   atomic_read(&q->block_count),
+			   atomic_read(&q->block_read) ? 'r' : '-',
+			   atomic_read(&q->block_write) ? 'w' : '-',
+			   waitqueue_active(&q->read_queue) ? 'r' : '-',
+			   waitqueue_active(&q->write_queue) ? 'w' : '-',
+			   waitqueue_active(&q->flush_queue) ? 'f' : '-',
+			   DRM_BUFCOUNT(&q->waitlist));
+		atomic_dec(&q->use_count);
+	}
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../bufs" is read.
+ */
+int drm_bufs_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;
+	struct drm_device_dma *dma;
+	int i, seg_pages;
+
+	mutex_lock(&dev->struct_mutex);
+	dma = dev->dma;
+	if (!dma) {
+		mutex_unlock(&dev->struct_mutex);
+		return 0;
+	}
+
+	seq_printf(m, " o     size count  free	 segs pages    kB\n\n");
+	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+		if (dma->bufs[i].buf_count) {
+			seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order);
+			seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n",
+				   i,
+				   dma->bufs[i].buf_size,
+				   dma->bufs[i].buf_count,
+				   atomic_read(&dma->bufs[i].freelist.count),
+				   dma->bufs[i].seg_count,
+				   seg_pages,
+				   seg_pages * PAGE_SIZE / 1024);
+		}
+	}
+	seq_printf(m, "\n");
+	for (i = 0; i < dma->buf_count; i++) {
+		if (i && !(i % 32))
+			seq_printf(m, "\n");
+		seq_printf(m, " %d", dma->buflist[i]->list);
+	}
+	seq_printf(m, "\n");
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../vblank" is read.
+ */
+int drm_vblank_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;
+	int crtc;
+
+	mutex_lock(&dev->struct_mutex);
+	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
+		seq_printf(m, "CRTC %d enable:     %d\n",
+			   crtc, atomic_read(&dev->vblank_refcount[crtc]));
+		seq_printf(m, "CRTC %d counter:    %d\n",
+			   crtc, drm_vblank_count(dev, crtc));
+		seq_printf(m, "CRTC %d last wait:  %d\n",
+			   crtc, dev->last_vblank_wait[crtc]);
+		seq_printf(m, "CRTC %d in modeset: %d\n",
+			   crtc, dev->vblank_inmodeset[crtc]);
+	}
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../clients" is read.
+ *
+ */
+int drm_clients_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;
+	struct drm_file *priv;
+
+	mutex_lock(&dev->struct_mutex);
+	seq_printf(m, "a dev	pid    uid	magic	  ioctls\n\n");
+	list_for_each_entry(priv, &dev->filelist, lhead) {
+		seq_printf(m, "%c %3d %5d %5d %10u %10lu\n",
+			   priv->authenticated ? 'y' : 'n',
+			   priv->minor->index,
+			   priv->pid,
+			   priv->uid, priv->magic, priv->ioctl_count);
+	}
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+
+int drm_gem_one_name_info(int id, void *ptr, void *data)
+{
+	struct drm_gem_object *obj = ptr;
+	struct seq_file *m = data;
+
+	seq_printf(m, "name %d size %zd\n", obj->name, obj->size);
+
+	seq_printf(m, "%6d %8zd %7d %8d\n",
+		   obj->name, obj->size,
+		   atomic_read(&obj->handlecount.refcount),
+		   atomic_read(&obj->refcount.refcount));
+	return 0;
+}
+
+int drm_gem_name_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;
+
+	seq_printf(m, "  name     size handles refcount\n");
+	idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m);
+	return 0;
+}
+
+int drm_gem_object_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;
+
+	seq_printf(m, "%d objects\n", atomic_read(&dev->object_count));
+	seq_printf(m, "%d object bytes\n", atomic_read(&dev->object_memory));
+	seq_printf(m, "%d pinned\n", atomic_read(&dev->pin_count));
+	seq_printf(m, "%d pin bytes\n", atomic_read(&dev->pin_memory));
+	seq_printf(m, "%d gtt bytes\n", atomic_read(&dev->gtt_memory));
+	seq_printf(m, "%d gtt total\n", dev->gtt_total);
+	return 0;
+}
+
+#if DRM_DEBUG_CODE
+
+int drm_vma_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;
+	struct drm_vma_entry *pt;
+	struct vm_area_struct *vma;
+#if defined(__i386__)
+	unsigned int pgprot;
+#endif
+
+	mutex_lock(&dev->struct_mutex);
+	seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n",
+		   atomic_read(&dev->vma_count),
+		   high_memory, (u64)virt_to_phys(high_memory));
+
+	list_for_each_entry(pt, &dev->vmalist, head) {
+		vma = pt->vma;
+		if (!vma)
+			continue;
+		seq_printf(m,
+			   "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
+			   pt->pid, vma->vm_start, vma->vm_end,
+			   vma->vm_flags & VM_READ ? 'r' : '-',
+			   vma->vm_flags & VM_WRITE ? 'w' : '-',
+			   vma->vm_flags & VM_EXEC ? 'x' : '-',
+			   vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+			   vma->vm_flags & VM_LOCKED ? 'l' : '-',
+			   vma->vm_flags & VM_IO ? 'i' : '-',
+			   vma->vm_pgoff);
+
+#if defined(__i386__)
+		pgprot = pgprot_val(vma->vm_page_prot);
+		seq_printf(m, " %c%c%c%c%c%c%c%c%c",
+			   pgprot & _PAGE_PRESENT ? 'p' : '-',
+			   pgprot & _PAGE_RW ? 'w' : 'r',
+			   pgprot & _PAGE_USER ? 'u' : 's',
+			   pgprot & _PAGE_PWT ? 't' : 'b',
+			   pgprot & _PAGE_PCD ? 'u' : 'c',
+			   pgprot & _PAGE_ACCESSED ? 'a' : '-',
+			   pgprot & _PAGE_DIRTY ? 'd' : '-',
+			   pgprot & _PAGE_PSE ? 'm' : 'k',
+			   pgprot & _PAGE_GLOBAL ? 'g' : 'l');
+#endif
+		seq_printf(m, "\n");
+	}
+	mutex_unlock(&dev->struct_mutex);
+	return 0;
+}
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_ioc32.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_ioc32.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_ioc32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_ioc32.c	2009-06-09 23:05:27.000000000 -0400
@@ -954,6 +954,7 @@ static int compat_drm_sg_free(struct fil
 			 DRM_IOCTL_SG_FREE, (unsigned long)request);
 }
 
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 typedef struct drm_update_draw32 {
 	drm_drawable_t handle;
 	unsigned int type;
@@ -984,6 +985,7 @@ static int compat_drm_update_draw(struct
 			DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
 	return err;
 }
+#endif
 
 struct drm_wait_vblank_request32 {
 	enum drm_vblank_seq_type type;
@@ -1066,7 +1068,9 @@ drm_ioctl_compat_t *drm_compat_ioctls[]
 #endif
 	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
 	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
 	[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
+#endif
 	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_irq.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_irq.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -196,6 +196,7 @@ int drm_irq_install(struct drm_device *d
 {
 	int ret = 0;
 	unsigned long sh_flags = 0;
+	char *irqname;
 
 	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
 		return -EINVAL;
@@ -227,8 +228,13 @@ int drm_irq_install(struct drm_device *d
 	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
 		sh_flags = IRQF_SHARED;
 
+	if (dev->devname)
+		irqname = dev->devname;
+	else
+		irqname = dev->driver->name;
+
 	ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
-			  sh_flags, dev->devname, dev);
+			  sh_flags, irqname, dev);
 
 	if (ret < 0) {
 		mutex_lock(&dev->struct_mutex);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_memory.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_memory.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_memory.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_memory.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,7 +159,7 @@ static inline void *agp_remap(unsigned l
 
 #endif				/* debug_memory */
 
-void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
 {
 	if (drm_core_has_AGP(dev) &&
 	    dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -169,7 +169,7 @@ void drm_core_ioremap(struct drm_map *ma
 }
 EXPORT_SYMBOL(drm_core_ioremap);
 
-void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
 {
 	if (drm_core_has_AGP(dev) &&
 	    dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -179,7 +179,7 @@ void drm_core_ioremap_wc(struct drm_map
 }
 EXPORT_SYMBOL(drm_core_ioremap_wc);
 
-void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
 {
 	if (!map->handle || !map->size)
 		return;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_proc.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_proc.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,697 +37,195 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/seq_file.h>
 #include "drmP.h"
 
-static int drm_name_info(char *buf, char **start, off_t offset,
-			 int request, int *eof, void *data);
-static int drm_vm_info(char *buf, char **start, off_t offset,
-		       int request, int *eof, void *data);
-static int drm_clients_info(char *buf, char **start, off_t offset,
-			    int request, int *eof, void *data);
-static int drm_queues_info(char *buf, char **start, off_t offset,
-			   int request, int *eof, void *data);
-static int drm_bufs_info(char *buf, char **start, off_t offset,
-			 int request, int *eof, void *data);
-static int drm_vblank_info(char *buf, char **start, off_t offset,
-			   int request, int *eof, void *data);
-static int drm_gem_name_info(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data);
-static int drm_gem_object_info(char *buf, char **start, off_t offset,
-			       int request, int *eof, void *data);
-#if DRM_DEBUG_CODE
-static int drm_vma_info(char *buf, char **start, off_t offset,
-			int request, int *eof, void *data);
-#endif
+/***************************************************
+ * Initialization, etc.
+ **************************************************/
 
 /**
  * Proc file list.
  */
-static struct drm_proc_list {
-	const char *name;	/**< file name */
-	int (*f) (char *, char **, off_t, int, int *, void *);		/**< proc callback*/
-	u32 driver_features; /**< Required driver features for this entry */
-} drm_proc_list[] = {
+static struct drm_info_list drm_proc_list[] = {
 	{"name", drm_name_info, 0},
-	{"mem", drm_mem_info, 0},
 	{"vm", drm_vm_info, 0},
 	{"clients", drm_clients_info, 0},
 	{"queues", drm_queues_info, 0},
 	{"bufs", drm_bufs_info, 0},
-	{"vblank", drm_vblank_info, 0},
 	{"gem_names", drm_gem_name_info, DRIVER_GEM},
 	{"gem_objects", drm_gem_object_info, DRIVER_GEM},
 #if DRM_DEBUG_CODE
-	{"vma", drm_vma_info},
+	{"vma", drm_vma_info, 0},
 #endif
 };
-
 #define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list)
 
+static int drm_proc_open(struct inode *inode, struct file *file)
+{
+	struct drm_info_node* node = PDE(inode)->data;
+
+	return single_open(file, node->info_ent->show, node);
+}
+
+static const struct file_operations drm_proc_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_proc_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+
 /**
- * Initialize the DRI proc filesystem for a device.
+ * Initialize a given set of proc files for a device
  *
- * \param dev DRM device.
- * \param minor device minor number.
+ * \param files The array of files to create
+ * \param count The number of files given
  * \param root DRI proc dir entry.
- * \param dev_root resulting DRI device proc dir entry.
- * \return root entry pointer on success, or NULL on failure.
+ * \param minor device minor number
+ * \return Zero on success, non-zero on failure
  *
- * Create the DRI proc root entry "/proc/dri", the device proc root entry
- * "/proc/dri/%minor%/", and each entry in proc_list as
- * "/proc/dri/%minor%/%name%".
+ * Create a given set of proc files represented by an array of
+ * gdm_proc_lists in the given root directory.
  */
-int drm_proc_init(struct drm_minor *minor, int minor_id,
-		  struct proc_dir_entry *root)
+int drm_proc_create_files(struct drm_info_list *files, int count,
+			  struct proc_dir_entry *root, struct drm_minor *minor)
 {
 	struct drm_device *dev = minor->dev;
 	struct proc_dir_entry *ent;
-	int i, j, ret;
+	struct drm_info_node *tmp;
 	char name[64];
+	int i, ret;
 
-	sprintf(name, "%d", minor_id);
-	minor->dev_root = proc_mkdir(name, root);
-	if (!minor->dev_root) {
-		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
-		return -1;
-	}
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-		u32 features = drm_proc_list[i].driver_features;
+	for (i = 0; i < count; i++) {
+		u32 features = files[i].driver_features;
 
 		if (features != 0 &&
 		    (dev->driver->driver_features & features) != features)
 			continue;
 
-		ent = create_proc_entry(drm_proc_list[i].name,
-					S_IFREG | S_IRUGO, minor->dev_root);
+		tmp = drm_alloc(sizeof(struct drm_info_node), _DRM_DRIVER);
+		ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root);
 		if (!ent) {
 			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
-				  name, drm_proc_list[i].name);
+				  name, files[i].name);
+			drm_free(tmp, sizeof(struct drm_info_node),
+				 _DRM_DRIVER);
 			ret = -1;
 			goto fail;
 		}
-		ent->read_proc = drm_proc_list[i].f;
-		ent->data = minor;
-	}
 
-	if (dev->driver->proc_init) {
-		ret = dev->driver->proc_init(minor);
-		if (ret) {
-			DRM_ERROR("DRM: Driver failed to initialize "
-				  "/proc/dri.\n");
-			goto fail;
-		}
+		ent->proc_fops = &drm_proc_fops;
+		ent->data = tmp;
+		tmp->minor = minor;
+		tmp->info_ent = &files[i];
+		list_add(&(tmp->list), &(minor->proc_nodes.list));
 	}
-
 	return 0;
- fail:
 
-	for (j = 0; j < i; j++)
-		remove_proc_entry(drm_proc_list[i].name,
-				  minor->dev_root);
-	remove_proc_entry(name, root);
-	minor->dev_root = NULL;
+fail:
+	for (i = 0; i < count; i++)
+		remove_proc_entry(drm_proc_list[i].name, minor->proc_root);
 	return ret;
 }
 
 /**
- * Cleanup the proc filesystem resources.
+ * Initialize the DRI proc filesystem for a device
  *
- * \param minor device minor number.
+ * \param dev DRM device
+ * \param minor device minor number
  * \param root DRI proc dir entry.
- * \param dev_root DRI device proc dir entry.
- * \return always zero.
+ * \param dev_root resulting DRI device proc dir entry.
+ * \return root entry pointer on success, or NULL on failure.
  *
- * Remove all proc entries created by proc_init().
+ * Create the DRI proc root entry "/proc/dri", the device proc root entry
+ * "/proc/dri/%minor%/", and each entry in proc_list as
+ * "/proc/dri/%minor%/%name%".
  */
-int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
+int drm_proc_init(struct drm_minor *minor, int minor_id,
+		  struct proc_dir_entry *root)
 {
 	struct drm_device *dev = minor->dev;
-	int i;
 	char name[64];
+	int ret;
 
-	if (!root || !minor->dev_root)
-		return 0;
-
-	if (dev->driver->proc_cleanup)
-		dev->driver->proc_cleanup(minor);
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++)
-		remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
-	sprintf(name, "%d", minor->index);
-	remove_proc_entry(name, root);
-
-	return 0;
-}
-
-/**
- * Called when "/proc/dri/.../name" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * Prints the device name together with the bus id if available.
- */
-static int drm_name_info(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_master *master = minor->master;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	if (!master)
-		return 0;
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	if (master->unique) {
-		DRM_PROC_PRINT("%s %s %s\n",
-			       dev->driver->pci_driver.name,
-			       pci_name(dev->pdev), master->unique);
-	} else {
-		DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
-			       pci_name(dev->pdev));
+	INIT_LIST_HEAD(&minor->proc_nodes.list);
+	sprintf(name, "%d", minor_id);
+	minor->proc_root = proc_mkdir(name, root);
+	if (!minor->proc_root) {
+		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
+		return -1;
 	}
 
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Called when "/proc/dri/.../vm" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * Prints information about all mappings in drm_device::maplist.
- */
-static int drm__vm_info(char *buf, char **start, off_t offset, int request,
-			int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-	struct drm_map *map;
-	struct drm_map_list *r_list;
-
-	/* Hardcoded from _DRM_FRAME_BUFFER,
-	   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
-	   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
-	const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
-	const char *type;
-	int i;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
+	ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES,
+				    minor->proc_root, minor);
+	if (ret) {
+		remove_proc_entry(name, root);
+		minor->proc_root = NULL;
+		DRM_ERROR("Failed to create core drm proc files\n");
+		return ret;
 	}
 
-	*start = &buf[offset];
-	*eof = 0;
-
-	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
-		       "address mtrr\n\n");
-	i = 0;
-	list_for_each_entry(r_list, &dev->maplist, head) {
-		map = r_list->map;
-		if (!map)
-			continue;
-		if (map->type < 0 || map->type > 5)
-			type = "??";
-		else
-			type = types[map->type];
-		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
-			       i,
-			       map->offset,
-			       map->size, type, map->flags,
-			       (unsigned long) r_list->user_token);
-		if (map->mtrr < 0) {
-			DRM_PROC_PRINT("none\n");
-		} else {
-			DRM_PROC_PRINT("%4d\n", map->mtrr);
+	if (dev->driver->proc_init) {
+		ret = dev->driver->proc_init(minor);
+		if (ret) {
+			DRM_ERROR("DRM: Driver failed to initialize "
+				  "/proc/dri.\n");
+			return ret;
 		}
-		i++;
-	}
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _vm_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_vm_info(char *buf, char **start, off_t offset, int request,
-		       int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__vm_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../queues" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__queues_info(char *buf, char **start, off_t offset,
-			    int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-	int i;
-	struct drm_queue *q;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
 	}
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	DRM_PROC_PRINT("  ctx/flags   use   fin"
-		       "   blk/rw/rwf  wait    flushed	   queued"
-		       "      locks\n\n");
-	for (i = 0; i < dev->queue_count; i++) {
-		q = dev->queuelist[i];
-		atomic_inc(&q->use_count);
-		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
-				   "%5d/0x%03x %5d %5d"
-				   " %5d/%c%c/%c%c%c %5Zd\n",
-				   i,
-				   q->flags,
-				   atomic_read(&q->use_count),
-				   atomic_read(&q->finalization),
-				   atomic_read(&q->block_count),
-				   atomic_read(&q->block_read) ? 'r' : '-',
-				   atomic_read(&q->block_write) ? 'w' : '-',
-				   waitqueue_active(&q->read_queue) ? 'r' : '-',
-				   waitqueue_active(&q->
-						    write_queue) ? 'w' : '-',
-				   waitqueue_active(&q->
-						    flush_queue) ? 'f' : '-',
-				   DRM_BUFCOUNT(&q->waitlist));
-		atomic_dec(&q->use_count);
-	}
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _queues_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_queues_info(char *buf, char **start, off_t offset, int request,
-			   int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__queues_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
+	return 0;
 }
 
-/**
- * Called when "/proc/dri/.../bufs" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
+int drm_proc_remove_files(struct drm_info_list *files, int count,
+			  struct drm_minor *minor)
 {
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-	struct drm_device_dma *dma = dev->dma;
+	struct list_head *pos, *q;
+	struct drm_info_node *tmp;
 	int i;
 
-	if (!dma || offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
-	for (i = 0; i <= DRM_MAX_ORDER; i++) {
-		if (dma->bufs[i].buf_count)
-			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
-				       i,
-				       dma->bufs[i].buf_size,
-				       dma->bufs[i].buf_count,
-				       atomic_read(&dma->bufs[i]
-						   .freelist.count),
-				       dma->bufs[i].seg_count,
-				       dma->bufs[i].seg_count
-				       * (1 << dma->bufs[i].page_order),
-				       (dma->bufs[i].seg_count
-					* (1 << dma->bufs[i].page_order))
-				       * PAGE_SIZE / 1024);
-	}
-	DRM_PROC_PRINT("\n");
-	for (i = 0; i < dma->buf_count; i++) {
-		if (i && !(i % 32))
-			DRM_PROC_PRINT("\n");
-		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+	for (i = 0; i < count; i++) {
+		list_for_each_safe(pos, q, &minor->proc_nodes.list) {
+			tmp = list_entry(pos, struct drm_info_node, list);
+			if (tmp->info_ent == &files[i]) {
+				remove_proc_entry(files[i].name,
+						  minor->proc_root);
+				list_del(pos);
+				drm_free(tmp, sizeof(struct drm_info_node),
+					 _DRM_DRIVER);
+			}
+		}
 	}
-	DRM_PROC_PRINT("\n");
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__bufs_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
+	return 0;
 }
 
 /**
- * Called when "/proc/dri/.../vblank" is read.
+ * Cleanup the proc filesystem resources.
  *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__vblank_info(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-	int crtc;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
-		DRM_PROC_PRINT("CRTC %d enable:     %d\n",
-			       crtc, atomic_read(&dev->vblank_refcount[crtc]));
-		DRM_PROC_PRINT("CRTC %d counter:    %d\n",
-			       crtc, drm_vblank_count(dev, crtc));
-		DRM_PROC_PRINT("CRTC %d last wait:  %d\n",
-			       crtc, dev->last_vblank_wait[crtc]);
-		DRM_PROC_PRINT("CRTC %d in modeset: %d\n",
-			       crtc, dev->vblank_inmodeset[crtc]);
-	}
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_vblank_info(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__vblank_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../clients" is read.
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root DRI device proc dir entry.
+ * \return always zero.
  *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
+ * Remove all proc entries created by proc_init().
  */
-static int drm__clients_info(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
+int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
 {
-	struct drm_minor *minor = (struct drm_minor *) data;
 	struct drm_device *dev = minor->dev;
-	int len = 0;
-	struct drm_file *priv;
+	char name[64];
 
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
+	if (!root || !minor->proc_root)
 		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
-	list_for_each_entry(priv, &dev->filelist, lhead) {
-		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
-			       priv->authenticated ? 'y' : 'n',
-			       priv->minor->index,
-			       priv->pid,
-			       priv->uid, priv->magic, priv->ioctl_count);
-	}
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
 
-/**
- * Simply calls _clients_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_clients_info(char *buf, char **start, off_t offset,
-			    int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__clients_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
-}
-
-struct drm_gem_name_info_data {
-       int                     len;
-       char                    *buf;
-       int                     eof;
-};
+	if (dev->driver->proc_cleanup)
+		dev->driver->proc_cleanup(minor);
 
-static int drm_gem_one_name_info(int id, void *ptr, void *data)
-{
-	struct drm_gem_object *obj = ptr;
-	struct drm_gem_name_info_data   *nid = data;
+	drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor);
 
-	DRM_INFO("name %d size %zd\n", obj->name, obj->size);
-	if (nid->eof)
-		return 0;
+	sprintf(name, "%d", minor->index);
+	remove_proc_entry(name, root);
 
-	nid->len += sprintf(&nid->buf[nid->len],
-			    "%6d %8zd %7d %8d\n",
-			    obj->name, obj->size,
-			    atomic_read(&obj->handlecount.refcount),
-			    atomic_read(&obj->refcount.refcount));
-	if (nid->len > DRM_PROC_LIMIT) {
-		nid->eof = 1;
-		return 0;
-	}
 	return 0;
 }
 
-static int drm_gem_name_info(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	struct drm_gem_name_info_data nid;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	nid.len = sprintf(buf, "  name     size handles refcount\n");
-	nid.buf = buf;
-	nid.eof = 0;
-	idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
-
-	*start = &buf[offset];
-	*eof = 0;
-	if (nid.len > request + offset)
-		return request;
-	*eof = 1;
-	return nid.len - offset;
-}
-
-static int drm_gem_object_info(char *buf, char **start, off_t offset,
-			       int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
-	DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
-	DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
-	DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
-	DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
-	DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-#if DRM_DEBUG_CODE
-
-static int drm__vma_info(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int len = 0;
-	struct drm_vma_entry *pt;
-	struct vm_area_struct *vma;
-#if defined(__i386__)
-	unsigned int pgprot;
-#endif
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-
-	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
-		       atomic_read(&dev->vma_count),
-		       high_memory, virt_to_phys(high_memory));
-	list_for_each_entry(pt, &dev->vmalist, head) {
-		if (!(vma = pt->vma))
-			continue;
-		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
-			       pt->pid,
-			       vma->vm_start,
-			       vma->vm_end,
-			       vma->vm_flags & VM_READ ? 'r' : '-',
-			       vma->vm_flags & VM_WRITE ? 'w' : '-',
-			       vma->vm_flags & VM_EXEC ? 'x' : '-',
-			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
-			       vma->vm_flags & VM_LOCKED ? 'l' : '-',
-			       vma->vm_flags & VM_IO ? 'i' : '-',
-			       vma->vm_pgoff);
-
-#if defined(__i386__)
-		pgprot = pgprot_val(vma->vm_page_prot);
-		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
-			       pgprot & _PAGE_PRESENT ? 'p' : '-',
-			       pgprot & _PAGE_RW ? 'w' : 'r',
-			       pgprot & _PAGE_USER ? 'u' : 's',
-			       pgprot & _PAGE_PWT ? 't' : 'b',
-			       pgprot & _PAGE_PCD ? 'u' : 'c',
-			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
-			       pgprot & _PAGE_DIRTY ? 'd' : '-',
-			       pgprot & _PAGE_PSE ? 'm' : 'k',
-			       pgprot & _PAGE_GLOBAL ? 'g' : 'l');
-#endif
-		DRM_PROC_PRINT("\n");
-	}
-
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int drm_vma_info(char *buf, char **start, off_t offset, int request,
-			int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	int ret;
-
-	mutex_lock(&dev->struct_mutex);
-	ret = drm__vma_info(buf, start, offset, request, eof, data);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_stub.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_stub.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_stub.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_stub.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,7 @@ struct idr drm_minors_idr;
 
 struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
+struct dentry *drm_debugfs_root;
 
 static int drm_minor_get_id(struct drm_device *dev, int type)
 {
@@ -158,6 +159,9 @@ void drm_master_put(struct drm_master **
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
+	if (file_priv->is_master)
+		return 0;
+
 	if (file_priv->minor->master && file_priv->minor->master != file_priv->master)
 		return -EINVAL;
 
@@ -168,6 +172,7 @@ int drm_setmaster_ioctl(struct drm_devic
 	    file_priv->minor->master != file_priv->master) {
 		mutex_lock(&dev->struct_mutex);
 		file_priv->minor->master = drm_master_get(file_priv->master);
+		file_priv->is_master = 1;
 		mutex_unlock(&dev->struct_mutex);
 	}
 
@@ -177,10 +182,15 @@ int drm_setmaster_ioctl(struct drm_devic
 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv)
 {
-	if (!file_priv->master)
+	if (!file_priv->is_master)
+		return -EINVAL;
+
+	if (!file_priv->minor->master)
 		return -EINVAL;
+
 	mutex_lock(&dev->struct_mutex);
 	drm_master_put(&file_priv->minor->master);
+	file_priv->is_master = 0;
 	mutex_unlock(&dev->struct_mutex);
 	return 0;
 }
@@ -313,7 +323,15 @@ static int drm_get_minor(struct drm_devi
 			goto err_mem;
 		}
 	} else
-		new_minor->dev_root = NULL;
+		new_minor->proc_root = NULL;
+
+#if defined(CONFIG_DEBUG_FS)
+	ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root);
+	if (ret) {
+		DRM_ERROR("DRM: Failed to initialize /debugfs/dri.\n");
+		goto err_g2;
+	}
+#endif
 
 	ret = drm_sysfs_device_add(new_minor);
 	if (ret) {
@@ -372,6 +390,7 @@ int drm_get_dev(struct pci_dev *pdev, co
 	}
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		pci_set_drvdata(pdev, dev);
 		ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
 		if (ret)
 			goto err_g2;
@@ -383,55 +402,36 @@ int drm_get_dev(struct pci_dev *pdev, co
 	if (dev->driver->load) {
 		ret = dev->driver->load(dev, ent->driver_data);
 		if (ret)
-			goto err_g3;
+			goto err_g4;
 	}
 
         /* setup the grouping for the legacy output */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
 		if (ret)
-			goto err_g3;
+			goto err_g4;
 	}
 
 	list_add_tail(&dev->driver_item, &driver->device_list);
 
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+	DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
 		 driver->name, driver->major, driver->minor, driver->patchlevel,
-		 driver->date, dev->primary->index);
+		 driver->date, pci_name(pdev), dev->primary->index);
 
 	return 0;
 
-err_g3:
+err_g4:
 	drm_put_minor(&dev->primary);
+err_g3:
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		drm_put_minor(&dev->control);
 err_g2:
 	pci_disable_device(pdev);
 err_g1:
 	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
 	return ret;
 }
-
-/**
- * Put a device minor number.
- *
- * \param dev device data structure
- * \return always zero
- *
- * Cleans up the proc resources. If it is the last minor then release the foreign
- * "drm" data, otherwise unregisters the "drm" data, frees the dev list and
- * unregisters the character device.
- */
-int drm_put_dev(struct drm_device * dev)
-{
-	DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
-
-	if (dev->devname) {
-		drm_free(dev->devname, strlen(dev->devname) + 1,
-			 DRM_MEM_DRIVER);
-		dev->devname = NULL;
-	}
-	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
-	return 0;
-}
+EXPORT_SYMBOL(drm_get_dev);
 
 /**
  * Put a secondary minor number.
@@ -451,6 +451,10 @@ int drm_put_minor(struct drm_minor **min
 
 	if (minor->type == DRM_MINOR_LEGACY)
 		drm_proc_cleanup(minor, drm_proc_root);
+#if defined(CONFIG_DEBUG_FS)
+	drm_debugfs_cleanup(minor);
+#endif
+
 	drm_sysfs_device_remove(minor);
 
 	idr_remove(&drm_minors_idr, minor->index);
@@ -459,3 +463,67 @@ int drm_put_minor(struct drm_minor **min
 	*minor_p = NULL;
 	return 0;
 }
+
+/**
+ * Called via drm_exit() at module unload time or when pci device is
+ * unplugged.
+ *
+ * Cleans up all DRM device, calling drm_lastclose().
+ *
+ * \sa drm_init
+ */
+void drm_put_dev(struct drm_device *dev)
+{
+	struct drm_driver *driver = dev->driver;
+	struct drm_map_list *r_list, *list_temp;
+
+	DRM_DEBUG("\n");
+
+	if (!dev) {
+		DRM_ERROR("cleanup called no dev\n");
+		return;
+	}
+
+	drm_vblank_cleanup(dev);
+
+	drm_lastclose(dev);
+
+	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+	    dev->agp && dev->agp->agp_mtrr >= 0) {
+		int retval;
+		retval = mtrr_del(dev->agp->agp_mtrr,
+				  dev->agp->agp_info.aper_base,
+				  dev->agp->agp_info.aper_size * 1024 * 1024);
+		DRM_DEBUG("mtrr_del=%d\n", retval);
+	}
+
+	if (dev->driver->unload)
+		dev->driver->unload(dev);
+
+	if (drm_core_has_AGP(dev) && dev->agp) {
+		drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+		dev->agp = NULL;
+	}
+
+	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+		drm_rmmap(dev, r_list->map);
+	drm_ht_remove(&dev->map_hash);
+
+	drm_ctxbitmap_cleanup(dev);
+
+	if (drm_core_check_feature(dev, DRIVER_MODESET))
+		drm_put_minor(&dev->control);
+
+	if (driver->driver_features & DRIVER_GEM)
+		drm_gem_destroy(dev);
+
+	drm_put_minor(&dev->primary);
+
+	if (dev->devname) {
+		drm_free(dev->devname, strlen(dev->devname) + 1,
+			 DRM_MEM_DRIVER);
+		dev->devname = NULL;
+	}
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+}
+EXPORT_SYMBOL(drm_put_dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_sysfs.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,9 @@ static int drm_sysfs_suspend(struct devi
 	struct drm_minor *drm_minor = to_drm_minor(dev);
 	struct drm_device *drm_dev = drm_minor->dev;
 
-	if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend)
+	if (drm_minor->type == DRM_MINOR_LEGACY &&
+	    !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+	    drm_dev->driver->suspend)
 		return drm_dev->driver->suspend(drm_dev, state);
 
 	return 0;
@@ -53,7 +55,9 @@ static int drm_sysfs_resume(struct devic
 	struct drm_minor *drm_minor = to_drm_minor(dev);
 	struct drm_device *drm_dev = drm_minor->dev;
 
-	if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume)
+	if (drm_minor->type == DRM_MINOR_LEGACY &&
+	    !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+	    drm_dev->driver->resume)
 		return drm_dev->driver->resume(drm_dev);
 
 	return 0;
@@ -118,20 +122,6 @@ void drm_sysfs_destroy(void)
 	class_destroy(drm_class);
 }
 
-static ssize_t show_dri(struct device *device, struct device_attribute *attr,
-			char *buf)
-{
-	struct drm_minor *drm_minor = to_drm_minor(device);
-	struct drm_device *drm_dev = drm_minor->dev;
-	if (drm_dev->driver->dri_library_name)
-		return drm_dev->driver->dri_library_name(drm_dev, buf);
-	return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
-}
-
-static struct device_attribute device_attrs[] = {
-	__ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
-};
-
 /**
  * drm_sysfs_device_release - do nothing
  * @dev: Linux device
@@ -142,6 +132,7 @@ static struct device_attribute device_at
  */
 static void drm_sysfs_device_release(struct device *dev)
 {
+	memset(dev, 0, sizeof(struct device));
 	return;
 }
 
@@ -156,7 +147,7 @@ static ssize_t status_show(struct device
 	enum drm_connector_status status;
 
 	status = connector->funcs->detect(connector);
-	return snprintf(buf, PAGE_SIZE, "%s",
+	return snprintf(buf, PAGE_SIZE, "%s\n",
 			drm_get_connector_status_name(status));
 }
 
@@ -175,7 +166,7 @@ static ssize_t dpms_show(struct device *
 	if (ret)
 		return 0;
 
-	return snprintf(buf, PAGE_SIZE, "%s",
+	return snprintf(buf, PAGE_SIZE, "%s\n",
 			drm_get_dpms_name((int)dpms_status));
 }
 
@@ -185,7 +176,7 @@ static ssize_t enabled_show(struct devic
 {
 	struct drm_connector *connector = to_drm_connector(device);
 
-	return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" :
+	return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" :
 			"disabled");
 }
 
@@ -326,6 +317,7 @@ static struct device_attribute connector
 
 static struct bin_attribute edid_attr = {
 	.attr.name = "edid",
+	.attr.mode = 0444,
 	.size = 128,
 	.read = edid_show,
 };
@@ -359,8 +351,8 @@ int drm_sysfs_connector_add(struct drm_c
 	DRM_DEBUG("adding \"%s\" to sysfs\n",
 		  drm_get_connector_name(connector));
 
-	snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
-		 dev->primary->index, drm_get_connector_name(connector));
+	dev_set_name(&connector->kdev, "card%d-%s",
+		     dev->primary->index, drm_get_connector_name(connector));
 	ret = device_register(&connector->kdev);
 
 	if (ret) {
@@ -461,6 +453,7 @@ void drm_sysfs_hotplug_event(struct drm_
 
 	kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
 }
+EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
 /**
  * drm_sysfs_device_add - adds a class device to sysfs for a character driver
@@ -474,7 +467,6 @@ void drm_sysfs_hotplug_event(struct drm_
 int drm_sysfs_device_add(struct drm_minor *minor)
 {
 	int err;
-	int i, j;
 	char *minor_str;
 
 	minor->kdev.parent = &minor->dev->pdev->dev;
@@ -496,21 +488,9 @@ int drm_sysfs_device_add(struct drm_mino
 		goto err_out;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
-		err = device_create_file(&minor->kdev, &device_attrs[i]);
-		if (err)
-			goto err_out_files;
-	}
-
 	return 0;
 
-err_out_files:
-	if (i > 0)
-		for (j = 0; j < i; j++)
-			device_remove_file(&minor->kdev, &device_attrs[j]);
-	device_unregister(&minor->kdev);
 err_out:
-
 	return err;
 }
 
@@ -523,9 +503,5 @@ err_out:
  */
 void drm_sysfs_device_remove(struct drm_minor *minor)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-		device_remove_file(&minor->kdev, &device_attrs[i]);
 	device_unregister(&minor->kdev);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_vm.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_vm.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/drm_vm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/drm_vm.c	2009-06-09 23:05:27.000000000 -0400
@@ -91,7 +91,7 @@ static int drm_do_vm_fault(struct vm_are
 {
 	struct drm_file *priv = vma->vm_file->private_data;
 	struct drm_device *dev = priv->minor->dev;
-	struct drm_map *map = NULL;
+	struct drm_local_map *map = NULL;
 	struct drm_map_list *r_list;
 	struct drm_hash_item *hash;
 
@@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_are
 		 * Using vm_pgoff as a selector forces us to use this unusual
 		 * addressing scheme.
 		 */
-		unsigned long offset = (unsigned long)vmf->virtual_address -
-								vma->vm_start;
-		unsigned long baddr = map->offset + offset;
+		resource_size_t offset = (unsigned long)vmf->virtual_address -
+			vma->vm_start;
+		resource_size_t baddr = map->offset + offset;
 		struct drm_agp_mem *agpmem;
 		struct page *page;
 
@@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_are
 		vmf->page = page;
 
 		DRM_DEBUG
-		    ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
-		     baddr, __va(agpmem->memory->memory[offset]), offset,
+		    ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n",
+		     (unsigned long long)baddr,
+		     __va(agpmem->memory->memory[offset]),
+		     (unsigned long long)offset,
 		     page_count(page));
 		return 0;
 	}
@@ -176,7 +178,7 @@ static int drm_do_vm_fault(struct vm_are
  */
 static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
-	struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+	struct drm_local_map *map = vma->vm_private_data;
 	unsigned long offset;
 	unsigned long i;
 	struct page *page;
@@ -209,7 +211,7 @@ static void drm_vm_shm_close(struct vm_a
 	struct drm_file *priv = vma->vm_file->private_data;
 	struct drm_device *dev = priv->minor->dev;
 	struct drm_vma_entry *pt, *temp;
-	struct drm_map *map;
+	struct drm_local_map *map;
 	struct drm_map_list *r_list;
 	int found_maps = 0;
 
@@ -322,7 +324,7 @@ static int drm_do_vm_dma_fault(struct vm
  */
 static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
-	struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+	struct drm_local_map *map = vma->vm_private_data;
 	struct drm_file *priv = vma->vm_file->private_data;
 	struct drm_device *dev = priv->minor->dev;
 	struct drm_sg_mem *entry = dev->sg;
@@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *fil
 	return 0;
 }
 
-unsigned long drm_core_get_map_ofs(struct drm_map * map)
+resource_size_t drm_core_get_map_ofs(struct drm_local_map * map)
 {
 	return map->offset;
 }
 
 EXPORT_SYMBOL(drm_core_get_map_ofs);
 
-unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
 {
 #ifdef __alpha__
 	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
@@ -547,8 +549,8 @@ int drm_mmap_locked(struct file *filp, s
 {
 	struct drm_file *priv = filp->private_data;
 	struct drm_device *dev = priv->minor->dev;
-	struct drm_map *map = NULL;
-	unsigned long offset = 0;
+	struct drm_local_map *map = NULL;
+	resource_size_t offset = 0;
 	struct drm_hash_item *hash;
 
 	DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
@@ -623,9 +625,9 @@ int drm_mmap_locked(struct file *filp, s
 				       vma->vm_page_prot))
 			return -EAGAIN;
 		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
-			  " offset = 0x%lx\n",
+			  " offset = 0x%llx\n",
 			  map->type,
-			  vma->vm_start, vma->vm_end, map->offset + offset);
+			  vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));
 		vma->vm_ops = &drm_vm_ops;
 		break;
 	case _DRM_CONSISTENT:
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i810/i810_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i810/i810_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i810/i810_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i810/i810_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer {
 } drm_i810_ring_buffer_t;
 
 typedef struct drm_i810_private {
-	struct drm_map *sarea_map;
-	struct drm_map *mmio_map;
+	struct drm_local_map *sarea_map;
+	struct drm_local_map *mmio_map;
 
 	drm_i810_sarea_t *sarea_priv;
 	drm_i810_ring_buffer_t ring;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i830/i830_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i830/i830_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i830/i830_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i830/i830_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -84,8 +84,8 @@ typedef struct _drm_i830_ring_buffer {
 } drm_i830_ring_buffer_t;
 
 typedef struct drm_i830_private {
-	struct drm_map *sarea_map;
-	struct drm_map *mmio_map;
+	struct drm_local_map *sarea_map;
+	struct drm_local_map *mmio_map;
 
 	drm_i830_sarea_t *sarea_priv;
 	drm_i830_ring_buffer_t ring;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_dma.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,6 @@
 int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
 	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
 	u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
 	u32 last_acthd = I915_READ(acthd_reg);
@@ -58,8 +57,12 @@ int i915_wait_ring(struct drm_device * d
 		if (ring->space >= n)
 			return 0;
 
-		if (master_priv->sarea_priv)
-			master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+		if (dev->primary->master) {
+			struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+			if (master_priv->sarea_priv)
+				master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+		}
+
 
 		if (ring->head != last_head)
 			i = 0;
@@ -356,7 +359,7 @@ static int validate_cmd(int cmd)
 	return ret;
 }
 
-static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
+static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int i;
@@ -370,8 +373,7 @@ static int i915_emit_cmds(struct drm_dev
 	for (i = 0; i < dwords;) {
 		int cmd, sz;
 
-		if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
-			return -EINVAL;
+		cmd = buffer[i];
 
 		if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
 			return -EINVAL;
@@ -379,11 +381,7 @@ static int i915_emit_cmds(struct drm_dev
 		OUT_RING(cmd);
 
 		while (++i, --sz) {
-			if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
-							 sizeof(cmd))) {
-				return -EINVAL;
-			}
-			OUT_RING(cmd);
+			OUT_RING(buffer[i]);
 		}
 	}
 
@@ -397,17 +395,13 @@ static int i915_emit_cmds(struct drm_dev
 
 int
 i915_emit_box(struct drm_device *dev,
-	      struct drm_clip_rect __user *boxes,
+	      struct drm_clip_rect *boxes,
 	      int i, int DR1, int DR4)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_clip_rect box;
+	struct drm_clip_rect box = boxes[i];
 	RING_LOCALS;
 
-	if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
-		return -EFAULT;
-	}
-
 	if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
 		DRM_ERROR("Bad box %d,%d..%d,%d\n",
 			  box.x1, box.y1, box.x2, box.y2);
@@ -460,7 +454,9 @@ static void i915_emit_breadcrumb(struct
 }
 
 static int i915_dispatch_cmdbuffer(struct drm_device * dev,
-				   drm_i915_cmdbuffer_t * cmd)
+				   drm_i915_cmdbuffer_t *cmd,
+				   struct drm_clip_rect *cliprects,
+				   void *cmdbuf)
 {
 	int nbox = cmd->num_cliprects;
 	int i = 0, count, ret;
@@ -476,13 +472,13 @@ static int i915_dispatch_cmdbuffer(struc
 
 	for (i = 0; i < count; i++) {
 		if (i < nbox) {
-			ret = i915_emit_box(dev, cmd->cliprects, i,
+			ret = i915_emit_box(dev, cliprects, i,
 					    cmd->DR1, cmd->DR4);
 			if (ret)
 				return ret;
 		}
 
-		ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
+		ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4);
 		if (ret)
 			return ret;
 	}
@@ -492,10 +488,10 @@ static int i915_dispatch_cmdbuffer(struc
 }
 
 static int i915_dispatch_batchbuffer(struct drm_device * dev,
-				     drm_i915_batchbuffer_t * batch)
+				     drm_i915_batchbuffer_t * batch,
+				     struct drm_clip_rect *cliprects)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_clip_rect __user *boxes = batch->cliprects;
 	int nbox = batch->num_cliprects;
 	int i = 0, count;
 	RING_LOCALS;
@@ -511,7 +507,7 @@ static int i915_dispatch_batchbuffer(str
 
 	for (i = 0; i < count; i++) {
 		if (i < nbox) {
-			int ret = i915_emit_box(dev, boxes, i,
+			int ret = i915_emit_box(dev, cliprects, i,
 						batch->DR1, batch->DR4);
 			if (ret)
 				return ret;
@@ -626,6 +622,7 @@ static int i915_batchbuffer(struct drm_d
 	    master_priv->sarea_priv;
 	drm_i915_batchbuffer_t *batch = data;
 	int ret;
+	struct drm_clip_rect *cliprects = NULL;
 
 	if (!dev_priv->allow_batchbuffer) {
 		DRM_ERROR("Batchbuffer ioctl disabled\n");
@@ -637,17 +634,35 @@ static int i915_batchbuffer(struct drm_d
 
 	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
-						       batch->num_cliprects *
-						       sizeof(struct drm_clip_rect)))
-		return -EFAULT;
+	if (batch->num_cliprects < 0)
+		return -EINVAL;
+
+	if (batch->num_cliprects) {
+		cliprects = drm_calloc(batch->num_cliprects,
+				       sizeof(struct drm_clip_rect),
+				       DRM_MEM_DRIVER);
+		if (cliprects == NULL)
+			return -ENOMEM;
+
+		ret = copy_from_user(cliprects, batch->cliprects,
+				     batch->num_cliprects *
+				     sizeof(struct drm_clip_rect));
+		if (ret != 0)
+			goto fail_free;
+	}
 
 	mutex_lock(&dev->struct_mutex);
-	ret = i915_dispatch_batchbuffer(dev, batch);
+	ret = i915_dispatch_batchbuffer(dev, batch, cliprects);
 	mutex_unlock(&dev->struct_mutex);
 
 	if (sarea_priv)
 		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+
+fail_free:
+	drm_free(cliprects,
+		 batch->num_cliprects * sizeof(struct drm_clip_rect),
+		 DRM_MEM_DRIVER);
+
 	return ret;
 }
 
@@ -659,6 +674,8 @@ static int i915_cmdbuffer(struct drm_dev
 	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
 	    master_priv->sarea_priv;
 	drm_i915_cmdbuffer_t *cmdbuf = data;
+	struct drm_clip_rect *cliprects = NULL;
+	void *batch_data;
 	int ret;
 
 	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@ -666,25 +683,50 @@ static int i915_cmdbuffer(struct drm_dev
 
 	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (cmdbuf->num_cliprects &&
-	    DRM_VERIFYAREA_READ(cmdbuf->cliprects,
-				cmdbuf->num_cliprects *
-				sizeof(struct drm_clip_rect))) {
-		DRM_ERROR("Fault accessing cliprects\n");
-		return -EFAULT;
+	if (cmdbuf->num_cliprects < 0)
+		return -EINVAL;
+
+	batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER);
+	if (batch_data == NULL)
+		return -ENOMEM;
+
+	ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
+	if (ret != 0)
+		goto fail_batch_free;
+
+	if (cmdbuf->num_cliprects) {
+		cliprects = drm_calloc(cmdbuf->num_cliprects,
+				       sizeof(struct drm_clip_rect),
+				       DRM_MEM_DRIVER);
+		if (cliprects == NULL)
+			goto fail_batch_free;
+
+		ret = copy_from_user(cliprects, cmdbuf->cliprects,
+				     cmdbuf->num_cliprects *
+				     sizeof(struct drm_clip_rect));
+		if (ret != 0)
+			goto fail_clip_free;
 	}
 
 	mutex_lock(&dev->struct_mutex);
-	ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
+	ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data);
 	mutex_unlock(&dev->struct_mutex);
 	if (ret) {
 		DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
-		return ret;
+		goto fail_clip_free;
 	}
 
 	if (sarea_priv)
 		sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
-	return 0;
+
+fail_clip_free:
+	drm_free(cliprects,
+		 cmdbuf->num_cliprects * sizeof(struct drm_clip_rect),
+		 DRM_MEM_DRIVER);
+fail_batch_free:
+	drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
+
+	return ret;
 }
 
 static int i915_flip_bufs(struct drm_device *dev, void *data,
@@ -880,7 +922,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))
+	if (IS_G4X(dev) || IS_IGD(dev))
 		overhead = 4096;
 	else
 		overhead = (*aperture_size / 1024) + 4096;
@@ -945,12 +987,6 @@ static int i915_load_modeset_init(struct
 	int fb_bar = IS_I9XX(dev) ? 2 : 0;
 	int ret = 0;
 
-	dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
-	if (!dev->devname) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
 	dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
 		0xff000000;
 
@@ -964,17 +1000,25 @@ static int i915_load_modeset_init(struct
 
 	ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
 	if (ret)
-		goto kfree_devname;
+		goto out;
 
 	/* Basic memrange allocator for stolen space (aka vram) */
 	drm_mm_init(&dev_priv->vram, 0, prealloc_size);
 
-	/* Let GEM Manage from end of prealloc space to end of aperture */
-	i915_gem_do_init(dev, prealloc_size, agp_size);
+	/* Let GEM Manage from end of prealloc space to end of aperture.
+	 *
+	 * However, leave one page at the end still bound to the scratch page.
+	 * There are a number of places where the hardware apparently
+	 * prefetches past the end of the object, and we've seen multiple
+	 * hangs with the GPU head pointer stuck in a batchbuffer bound
+	 * at the last page of the aperture.  One page should be enough to
+	 * keep any prefetching inside of the aperture.
+	 */
+	i915_gem_do_init(dev, prealloc_size, agp_size - 4096);
 
 	ret = i915_gem_init_ringbuffer(dev);
 	if (ret)
-		goto kfree_devname;
+		goto out;
 
 	/* Allow hardware batchbuffers unless told otherwise.
 	 */
@@ -988,13 +1032,6 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		goto destroy_ringbuffer;
 
-	/* FIXME: re-add hotplug support */
-#if 0
-	ret = drm_hotplug_init(dev);
-	if (ret)
-		goto destroy_ringbuffer;
-#endif
-
 	/* Always safe in the mode setting case. */
 	/* FIXME: do pre/post-mode set stuff in core KMS code */
 	dev->vblank_disable_allowed = 1;
@@ -1007,14 +1044,12 @@ static int i915_load_modeset_init(struct
 
 	intel_modeset_init(dev);
 
-	drm_helper_initial_config(dev, false);
+	drm_helper_initial_config(dev);
 
 	return 0;
 
 destroy_ringbuffer:
 	i915_gem_cleanup_ringbuffer(dev);
-kfree_devname:
-	kfree(dev->devname);
 out:
 	return ret;
 }
@@ -1057,7 +1092,7 @@ void i915_master_destroy(struct drm_devi
 int i915_driver_load(struct drm_device *dev, unsigned long flags)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long base, size;
+	resource_size_t base, size;
 	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
 
 	/* i915 has 4 more counters */
@@ -1144,8 +1179,6 @@ int i915_driver_load(struct drm_device *
 	if (!IS_I945G(dev) && !IS_I945GM(dev))
 		pci_enable_msi(dev->pdev);
 
-	intel_opregion_init(dev);
-
 	spin_lock_init(&dev_priv->user_irq_lock);
 	dev_priv->user_irq_refcount = 0;
 
@@ -1164,6 +1197,9 @@ int i915_driver_load(struct drm_device *
 		}
 	}
 
+	/* Must be done after probing outputs */
+	intel_opregion_init(dev, 0);
+
 	return 0;
 
 out_iomapfree:
@@ -1196,7 +1232,7 @@ int i915_driver_unload(struct drm_device
 	if (dev_priv->regs != NULL)
 		iounmap(dev_priv->regs);
 
-	intel_opregion_free(dev);
+	intel_opregion_free(dev, 0);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		intel_modeset_cleanup(dev);
@@ -1314,6 +1350,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
 	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
 	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),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_drv.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_drv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,8 @@ module_param_named(modeset, i915_modeset
 unsigned int i915_fbpercrtc = 0;
 module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
 
+static struct drm_driver driver;
+
 static struct pci_device_id pciidlist[] = {
 	i915_PCI_IDS
 };
@@ -75,7 +77,7 @@ static int i915_suspend(struct drm_devic
 		drm_irq_uninstall(dev);
 	}
 
-	intel_opregion_free(dev);
+	intel_opregion_free(dev, 1);
 
 	if (state.event == PM_EVENT_SUSPEND) {
 		/* Shut down the device */
@@ -99,7 +101,7 @@ static int i915_resume(struct drm_device
 
 	i915_restore_state(dev);
 
-	intel_opregion_init(dev);
+	intel_opregion_init(dev, 1);
 
 	/* KMS EnterVT equivalent */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -117,6 +119,36 @@ static int i915_resume(struct drm_device
 	return ret;
 }
 
+static int __devinit
+i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return drm_get_dev(pdev, ent, &driver);
+}
+
+static void
+i915_pci_remove(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	drm_put_dev(dev);
+}
+
+static int
+i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	return i915_suspend(dev, state);
+}
+
+static int
+i915_pci_resume(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+
+	return i915_resume(dev);
+}
+
 static struct vm_operations_struct i915_gem_vm_ops = {
 	.fault = i915_gem_fault,
 	.open = drm_gem_vm_open,
@@ -150,8 +182,10 @@ static struct drm_driver driver = {
 	.get_reg_ofs = drm_core_get_reg_ofs,
 	.master_create = i915_master_create,
 	.master_destroy = i915_master_destroy,
-	.proc_init = i915_gem_proc_init,
-	.proc_cleanup = i915_gem_proc_cleanup,
+#if defined(CONFIG_DEBUG_FS)
+	.debugfs_init = i915_gem_debugfs_init,
+	.debugfs_cleanup = i915_gem_debugfs_cleanup,
+#endif
 	.gem_init_object = i915_gem_init_object,
 	.gem_free_object = i915_gem_free_object,
 	.gem_vm_ops = &i915_gem_vm_ops,
@@ -172,6 +206,12 @@ static struct drm_driver driver = {
 	.pci_driver = {
 		 .name = DRIVER_NAME,
 		 .id_table = pciidlist,
+		 .probe = i915_pci_probe,
+		 .remove = i915_pci_remove,
+#ifdef CONFIG_PM
+		 .resume = i915_pci_resume,
+		 .suspend = i915_pci_suspend,
+#endif
 	},
 
 	.name = DRIVER_NAME,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -159,6 +159,9 @@ typedef struct drm_i915_private {
 	u32 irq_mask_reg;
 	u32 pipestat[2];
 
+	u32 hotplug_supported_mask;
+	struct work_struct hotplug_work;
+
 	int tex_lru_log_granularity;
 	int allow_batchbuffer;
 	struct mem_block *agp_heap;
@@ -177,7 +180,8 @@ typedef struct drm_i915_private {
 	int backlight_duty_cycle;  /* restore backlight to this value */
 	bool panel_wants_dither;
 	struct drm_display_mode *panel_fixed_mode;
-	struct drm_display_mode *vbt_mode; /* if any */
+	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
 
 	/* Feature bits from the VBIOS */
 	unsigned int int_tv_support:1;
@@ -280,6 +284,7 @@ typedef struct drm_i915_private {
 	u8 saveAR[21];
 	u8 saveDACMASK;
 	u8 saveCR[37];
+	uint64_t saveFENCE[16];
 
 	struct {
 		struct drm_mm gtt_space;
@@ -297,6 +302,7 @@ typedef struct drm_i915_private {
 		 *
 		 * A reference is held on the buffer while on this list.
 		 */
+		spinlock_t active_list_lock;
 		struct list_head active_list;
 
 		/**
@@ -404,7 +410,8 @@ struct drm_i915_gem_object {
 	/** AGP memory structure for our GTT binding. */
 	DRM_AGP_MEM *agp_mem;
 
-	struct page **page_list;
+	struct page **pages;
+	int pages_refcount;
 
 	/**
 	 * Current offset of the object in GTT space.
@@ -441,6 +448,9 @@ struct drm_i915_gem_object {
 	uint32_t tiling_mode;
 	uint32_t stride;
 
+	/** Record of address bit 17 of each page at last unbind. */
+	long *bit_17;
+
 	/** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
 	uint32_t agp_type;
 
@@ -519,7 +529,7 @@ extern int i915_driver_device_is_agp(str
 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
 			      unsigned long arg);
 extern int i915_emit_box(struct drm_device *dev,
-			 struct drm_clip_rect __user *boxes,
+			 struct drm_clip_rect *boxes,
 			 int i, int DR1, int DR4);
 
 /* i915_irq.c */
@@ -604,8 +614,6 @@ int i915_gem_get_tiling(struct drm_devic
 int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
-int i915_gem_proc_init(struct drm_minor *minor);
-void i915_gem_proc_cleanup(struct drm_minor *minor);
 int i915_gem_init_object(struct drm_gem_object *obj);
 void i915_gem_free_object(struct drm_gem_object *obj);
 int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
@@ -632,9 +640,13 @@ int i915_gem_attach_phys_object(struct d
 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);
+void i915_gem_object_put_pages(struct drm_gem_object *obj);
 
 /* i915_gem_tiling.c */
 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);
 
 /* i915_gem_debug.c */
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
@@ -649,6 +661,10 @@ void i915_gem_dump_object(struct drm_gem
 			  const char *where, uint32_t mark);
 void i915_dump_lru(struct drm_device *dev, const char *where);
 
+/* i915_debugfs.c */
+int i915_gem_debugfs_init(struct drm_minor *minor);
+void i915_gem_debugfs_cleanup(struct drm_minor *minor);
+
 /* i915_suspend.c */
 extern int i915_save_state(struct drm_device *dev);
 extern int i915_restore_state(struct drm_device *dev);
@@ -659,13 +675,13 @@ extern int i915_restore_state(struct drm
 
 #ifdef CONFIG_ACPI
 /* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
-extern void intel_opregion_free(struct drm_device *dev);
+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 opregion_enable_asle(struct drm_device *dev);
 #else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
-static inline void intel_opregion_free(struct drm_device *dev) { return; }
+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 opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
@@ -691,13 +707,8 @@ extern void intel_modeset_cleanup(struct
 #define I915_WRITE16(reg, val)	writel(val, dev_priv->regs + (reg))
 #define I915_READ8(reg)		readb(dev_priv->regs + (reg))
 #define I915_WRITE8(reg, val)	writeb(val, dev_priv->regs + (reg))
-#ifdef writeq
 #define I915_WRITE64(reg, val)	writeq(val, dev_priv->regs + (reg))
-#else
-#define I915_WRITE64(reg, val)	(writel(val, dev_priv->regs + (reg)), \
-				 writel(upper_32_bits(val), dev_priv->regs + \
-					(reg) + 4))
-#endif
+#define I915_READ64(reg)	readq(dev_priv->regs + (reg))
 #define POSTING_READ(reg)	(void)I915_READ(reg)
 
 #define I915_VERBOSE 0
@@ -773,26 +784,35 @@ extern int i915_wait_ring(struct drm_dev
 		       (dev)->pci_device == 0x2A42 || \
 		       (dev)->pci_device == 0x2E02 || \
 		       (dev)->pci_device == 0x2E12 || \
-		       (dev)->pci_device == 0x2E22)
+		       (dev)->pci_device == 0x2E22 || \
+		       (dev)->pci_device == 0x2E32)
 
-#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
+#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 || \
 		     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)
+			(dev)->pci_device == 0x29D2 ||  \
+			(IS_IGD(dev)))
 
 #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
 		      IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
 
 #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
-			IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
+			IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
+			IS_IGD(dev))
 
 #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
 /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
@@ -801,6 +821,7 @@ extern int i915_wait_ring(struct drm_dev
 #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
 						      IS_I915GM(dev)))
 #define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev))
+#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,8 +43,6 @@ static int i915_gem_object_set_cpu_read_
 						     uint64_t offset,
 						     uint64_t size);
 static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj);
-static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
-static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
 static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
 static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
 					   unsigned alignment);
@@ -136,6 +134,306 @@ i915_gem_create_ioctl(struct drm_device
 	return 0;
 }
 
+static inline int
+fast_shmem_read(struct page **pages,
+		loff_t page_base, int page_offset,
+		char __user *data,
+		int length)
+{
+	char __iomem *vaddr;
+	int unwritten;
+
+	vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
+	if (vaddr == NULL)
+		return -ENOMEM;
+	unwritten = __copy_to_user_inatomic(data, vaddr + page_offset, length);
+	kunmap_atomic(vaddr, KM_USER0);
+
+	if (unwritten)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
+{
+	drm_i915_private_t *dev_priv = obj->dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
+		obj_priv->tiling_mode != I915_TILING_NONE;
+}
+
+static inline int
+slow_shmem_copy(struct page *dst_page,
+		int dst_offset,
+		struct page *src_page,
+		int src_offset,
+		int length)
+{
+	char *dst_vaddr, *src_vaddr;
+
+	dst_vaddr = kmap_atomic(dst_page, KM_USER0);
+	if (dst_vaddr == NULL)
+		return -ENOMEM;
+
+	src_vaddr = kmap_atomic(src_page, KM_USER1);
+	if (src_vaddr == NULL) {
+		kunmap_atomic(dst_vaddr, KM_USER0);
+		return -ENOMEM;
+	}
+
+	memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
+
+	kunmap_atomic(src_vaddr, KM_USER1);
+	kunmap_atomic(dst_vaddr, KM_USER0);
+
+	return 0;
+}
+
+static inline int
+slow_shmem_bit17_copy(struct page *gpu_page,
+		      int gpu_offset,
+		      struct page *cpu_page,
+		      int cpu_offset,
+		      int length,
+		      int is_read)
+{
+	char *gpu_vaddr, *cpu_vaddr;
+
+	/* Use the unswizzled path if this page isn't affected. */
+	if ((page_to_phys(gpu_page) & (1 << 17)) == 0) {
+		if (is_read)
+			return slow_shmem_copy(cpu_page, cpu_offset,
+					       gpu_page, gpu_offset, length);
+		else
+			return slow_shmem_copy(gpu_page, gpu_offset,
+					       cpu_page, cpu_offset, length);
+	}
+
+	gpu_vaddr = kmap_atomic(gpu_page, KM_USER0);
+	if (gpu_vaddr == NULL)
+		return -ENOMEM;
+
+	cpu_vaddr = kmap_atomic(cpu_page, KM_USER1);
+	if (cpu_vaddr == NULL) {
+		kunmap_atomic(gpu_vaddr, KM_USER0);
+		return -ENOMEM;
+	}
+
+	/* Copy the data, XORing A6 with A17 (1). The user already knows he's
+	 * XORing with the other bits (A9 for Y, A9 and A10 for X)
+	 */
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		if (is_read) {
+			memcpy(cpu_vaddr + cpu_offset,
+			       gpu_vaddr + swizzled_gpu_offset,
+			       this_length);
+		} else {
+			memcpy(gpu_vaddr + swizzled_gpu_offset,
+			       cpu_vaddr + cpu_offset,
+			       this_length);
+		}
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	kunmap_atomic(cpu_vaddr, KM_USER1);
+	kunmap_atomic(gpu_vaddr, KM_USER0);
+
+	return 0;
+}
+
+/**
+ * This is the fast shmem pread path, which attempts to copy_from_user directly
+ * from the backing pages of the object to the user's address space.  On a
+ * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow().
+ */
+static int
+i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
+			  struct drm_i915_gem_pread *args,
+			  struct drm_file *file_priv)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	ssize_t remain;
+	loff_t offset, page_base;
+	char __user *user_data;
+	int page_offset, page_length;
+	int ret;
+
+	user_data = (char __user *) (uintptr_t) args->data_ptr;
+	remain = args->size;
+
+	mutex_lock(&dev->struct_mutex);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret != 0)
+		goto fail_unlock;
+
+	ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
+							args->size);
+	if (ret != 0)
+		goto fail_put_pages;
+
+	obj_priv = obj->driver_private;
+	offset = args->offset;
+
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * page_base = page offset within aperture
+		 * page_offset = offset within page
+		 * page_length = bytes to copy for this page
+		 */
+		page_base = (offset & ~(PAGE_SIZE-1));
+		page_offset = offset & (PAGE_SIZE-1);
+		page_length = remain;
+		if ((page_offset + remain) > PAGE_SIZE)
+			page_length = PAGE_SIZE - page_offset;
+
+		ret = fast_shmem_read(obj_priv->pages,
+				      page_base, page_offset,
+				      user_data, page_length);
+		if (ret)
+			goto fail_put_pages;
+
+		remain -= page_length;
+		user_data += page_length;
+		offset += page_length;
+	}
+
+fail_put_pages:
+	i915_gem_object_put_pages(obj);
+fail_unlock:
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+/**
+ * This is the fallback shmem pread path, which allocates temporary storage
+ * in kernel space to copy_to_user into outside of the struct_mutex, so we
+ * can copy out of the object's backing pages while holding the struct mutex
+ * and not take page faults.
+ */
+static int
+i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
+			  struct drm_i915_gem_pread *args,
+			  struct drm_file *file_priv)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct mm_struct *mm = current->mm;
+	struct page **user_pages;
+	ssize_t remain;
+	loff_t offset, pinned_pages, i;
+	loff_t first_data_page, last_data_page, num_pages;
+	int shmem_page_index, shmem_page_offset;
+	int data_page_index,  data_page_offset;
+	int page_length;
+	int ret;
+	uint64_t data_ptr = args->data_ptr;
+	int do_bit17_swizzling;
+
+	remain = args->size;
+
+	/* Pin the user pages containing the data.  We can't fault while
+	 * holding the struct mutex, yet we want to hold it while
+	 * dereferencing the user data.
+	 */
+	first_data_page = data_ptr / PAGE_SIZE;
+	last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+	num_pages = last_data_page - first_data_page + 1;
+
+	user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
+	if (user_pages == NULL)
+		return -ENOMEM;
+
+	down_read(&mm->mmap_sem);
+	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+				      num_pages, 1, 0, user_pages, NULL);
+	up_read(&mm->mmap_sem);
+	if (pinned_pages < num_pages) {
+		ret = -EFAULT;
+		goto fail_put_user_pages;
+	}
+
+	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
+	mutex_lock(&dev->struct_mutex);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret != 0)
+		goto fail_unlock;
+
+	ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
+							args->size);
+	if (ret != 0)
+		goto fail_put_pages;
+
+	obj_priv = obj->driver_private;
+	offset = args->offset;
+
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * shmem_page_index = page number within shmem file
+		 * shmem_page_offset = offset within page in shmem file
+		 * data_page_index = page number in get_user_pages return
+		 * data_page_offset = offset with data_page_index page.
+		 * page_length = bytes to copy for this page
+		 */
+		shmem_page_index = offset / PAGE_SIZE;
+		shmem_page_offset = offset & ~PAGE_MASK;
+		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+		data_page_offset = data_ptr & ~PAGE_MASK;
+
+		page_length = remain;
+		if ((shmem_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - shmem_page_offset;
+		if ((data_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - data_page_offset;
+
+		if (do_bit17_swizzling) {
+			ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
+						    shmem_page_offset,
+						    user_pages[data_page_index],
+						    data_page_offset,
+						    page_length,
+						    1);
+		} else {
+			ret = slow_shmem_copy(user_pages[data_page_index],
+					      data_page_offset,
+					      obj_priv->pages[shmem_page_index],
+					      shmem_page_offset,
+					      page_length);
+		}
+		if (ret)
+			goto fail_put_pages;
+
+		remain -= page_length;
+		data_ptr += page_length;
+		offset += page_length;
+	}
+
+fail_put_pages:
+	i915_gem_object_put_pages(obj);
+fail_unlock:
+	mutex_unlock(&dev->struct_mutex);
+fail_put_user_pages:
+	for (i = 0; i < pinned_pages; i++) {
+		SetPageDirty(user_pages[i]);
+		page_cache_release(user_pages[i]);
+	}
+	drm_free_large(user_pages);
+
+	return ret;
+}
+
 /**
  * Reads data from the object referenced by handle.
  *
@@ -148,8 +446,6 @@ i915_gem_pread_ioctl(struct drm_device *
 	struct drm_i915_gem_pread *args = data;
 	struct drm_gem_object *obj;
 	struct drm_i915_gem_object *obj_priv;
-	ssize_t read;
-	loff_t offset;
 	int ret;
 
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
@@ -167,33 +463,18 @@ i915_gem_pread_ioctl(struct drm_device *
 		return -EINVAL;
 	}
 
-	mutex_lock(&dev->struct_mutex);
-
-	ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
-							args->size);
-	if (ret != 0) {
-		drm_gem_object_unreference(obj);
-		mutex_unlock(&dev->struct_mutex);
-		return ret;
-	}
-
-	offset = args->offset;
-
-	read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
-			args->size, &offset);
-	if (read != args->size) {
-		drm_gem_object_unreference(obj);
-		mutex_unlock(&dev->struct_mutex);
-		if (read < 0)
-			return read;
-		else
-			return -EINVAL;
+	if (i915_gem_object_needs_bit17_swizzle(obj)) {
+		ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv);
+	} else {
+		ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv);
+		if (ret != 0)
+			ret = i915_gem_shmem_pread_slow(dev, obj, args,
+							file_priv);
 	}
 
 	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
 
-	return 0;
+	return ret;
 }
 
 /* This is the fast write path which cannot handle
@@ -223,29 +504,54 @@ fast_user_write(struct io_mapping *mappi
  */
 
 static inline int
-slow_user_write(struct io_mapping *mapping,
-		loff_t page_base, int page_offset,
-		char __user *user_data,
-		int length)
+slow_kernel_write(struct io_mapping *mapping,
+		  loff_t gtt_base, int gtt_offset,
+		  struct page *user_page, int user_offset,
+		  int length)
+{
+	char *src_vaddr, *dst_vaddr;
+	unsigned long unwritten;
+
+	dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base);
+	src_vaddr = kmap_atomic(user_page, KM_USER1);
+	unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset,
+						      src_vaddr + user_offset,
+						      length);
+	kunmap_atomic(src_vaddr, KM_USER1);
+	io_mapping_unmap_atomic(dst_vaddr);
+	if (unwritten)
+		return -EFAULT;
+	return 0;
+}
+
+static inline int
+fast_shmem_write(struct page **pages,
+		 loff_t page_base, int page_offset,
+		 char __user *data,
+		 int length)
 {
 	char __iomem *vaddr;
 	unsigned long unwritten;
 
-	vaddr = io_mapping_map_wc(mapping, page_base);
+	vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
 	if (vaddr == NULL)
-		return -EFAULT;
-	unwritten = __copy_from_user(vaddr + page_offset,
-				     user_data, length);
-	io_mapping_unmap(vaddr);
+		return -ENOMEM;
+	unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length);
+	kunmap_atomic(vaddr, KM_USER0);
+
 	if (unwritten)
 		return -EFAULT;
 	return 0;
 }
 
+/**
+ * This is the fast pwrite path, where we copy the data directly from the
+ * user into the GTT, uncached.
+ */
 static int
-i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
-		    struct drm_i915_gem_pwrite *args,
-		    struct drm_file *file_priv)
+i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
+			 struct drm_i915_gem_pwrite *args,
+			 struct drm_file *file_priv)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -273,7 +579,6 @@ i915_gem_gtt_pwrite(struct drm_device *d
 
 	obj_priv = obj->driver_private;
 	offset = obj_priv->gtt_offset + args->offset;
-	obj_priv->dirty = 1;
 
 	while (remain > 0) {
 		/* Operation in this page
@@ -292,16 +597,11 @@ i915_gem_gtt_pwrite(struct drm_device *d
 				       page_offset, user_data, page_length);
 
 		/* If we get a fault while copying data, then (presumably) our
-		 * source page isn't available. In this case, use the
-		 * non-atomic function
+		 * source page isn't available.  Return the error and we'll
+		 * retry in the slow path.
 		 */
-		if (ret) {
-			ret = slow_user_write (dev_priv->mm.gtt_mapping,
-					       page_base, page_offset,
-					       user_data, page_length);
-			if (ret)
-				goto fail;
-		}
+		if (ret)
+			goto fail;
 
 		remain -= page_length;
 		user_data += page_length;
@@ -315,39 +615,296 @@ fail:
 	return ret;
 }
 
+/**
+ * This is the fallback GTT pwrite path, which uses get_user_pages to pin
+ * the memory and maps it using kmap_atomic for copying.
+ *
+ * This code resulted in x11perf -rgb10text consuming about 10% more CPU
+ * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit).
+ */
 static int
-i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
-		      struct drm_i915_gem_pwrite *args,
-		      struct drm_file *file_priv)
+i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
+			 struct drm_i915_gem_pwrite *args,
+			 struct drm_file *file_priv)
 {
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	ssize_t remain;
+	loff_t gtt_page_base, offset;
+	loff_t first_data_page, last_data_page, num_pages;
+	loff_t pinned_pages, i;
+	struct page **user_pages;
+	struct mm_struct *mm = current->mm;
+	int gtt_page_offset, data_page_offset, data_page_index, page_length;
 	int ret;
-	loff_t offset;
-	ssize_t written;
+	uint64_t data_ptr = args->data_ptr;
+
+	remain = args->size;
+
+	/* Pin the user pages containing the data.  We can't fault while
+	 * holding the struct mutex, and all of the pwrite implementations
+	 * want to hold it while dereferencing the user data.
+	 */
+	first_data_page = data_ptr / PAGE_SIZE;
+	last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+	num_pages = last_data_page - first_data_page + 1;
+
+	user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
+	if (user_pages == NULL)
+		return -ENOMEM;
+
+	down_read(&mm->mmap_sem);
+	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+				      num_pages, 0, 0, user_pages, NULL);
+	up_read(&mm->mmap_sem);
+	if (pinned_pages < num_pages) {
+		ret = -EFAULT;
+		goto out_unpin_pages;
+	}
 
 	mutex_lock(&dev->struct_mutex);
+	ret = i915_gem_object_pin(obj, 0);
+	if (ret)
+		goto out_unlock;
+
+	ret = i915_gem_object_set_to_gtt_domain(obj, 1);
+	if (ret)
+		goto out_unpin_object;
+
+	obj_priv = obj->driver_private;
+	offset = obj_priv->gtt_offset + args->offset;
+
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * gtt_page_base = page offset within aperture
+		 * gtt_page_offset = offset within page in aperture
+		 * data_page_index = page number in get_user_pages return
+		 * data_page_offset = offset with data_page_index page.
+		 * page_length = bytes to copy for this page
+		 */
+		gtt_page_base = offset & PAGE_MASK;
+		gtt_page_offset = offset & ~PAGE_MASK;
+		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+		data_page_offset = data_ptr & ~PAGE_MASK;
+
+		page_length = remain;
+		if ((gtt_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - gtt_page_offset;
+		if ((data_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - data_page_offset;
+
+		ret = slow_kernel_write(dev_priv->mm.gtt_mapping,
+					gtt_page_base, gtt_page_offset,
+					user_pages[data_page_index],
+					data_page_offset,
+					page_length);
+
+		/* If we get a fault while copying data, then (presumably) our
+		 * source page isn't available.  Return the error and we'll
+		 * retry in the slow path.
+		 */
+		if (ret)
+			goto out_unpin_object;
+
+		remain -= page_length;
+		offset += page_length;
+		data_ptr += page_length;
+	}
+
+out_unpin_object:
+	i915_gem_object_unpin(obj);
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+out_unpin_pages:
+	for (i = 0; i < pinned_pages; i++)
+		page_cache_release(user_pages[i]);
+	drm_free_large(user_pages);
+
+	return ret;
+}
+
+/**
+ * This is the fast shmem pwrite path, which attempts to directly
+ * copy_from_user into the kmapped pages backing the object.
+ */
+static int
+i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
+			   struct drm_i915_gem_pwrite *args,
+			   struct drm_file *file_priv)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	ssize_t remain;
+	loff_t offset, page_base;
+	char __user *user_data;
+	int page_offset, page_length;
+	int ret;
+
+	user_data = (char __user *) (uintptr_t) args->data_ptr;
+	remain = args->size;
+
+	mutex_lock(&dev->struct_mutex);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret != 0)
+		goto fail_unlock;
 
 	ret = i915_gem_object_set_to_cpu_domain(obj, 1);
-	if (ret) {
-		mutex_unlock(&dev->struct_mutex);
-		return ret;
+	if (ret != 0)
+		goto fail_put_pages;
+
+	obj_priv = obj->driver_private;
+	offset = args->offset;
+	obj_priv->dirty = 1;
+
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * page_base = page offset within aperture
+		 * page_offset = offset within page
+		 * page_length = bytes to copy for this page
+		 */
+		page_base = (offset & ~(PAGE_SIZE-1));
+		page_offset = offset & (PAGE_SIZE-1);
+		page_length = remain;
+		if ((page_offset + remain) > PAGE_SIZE)
+			page_length = PAGE_SIZE - page_offset;
+
+		ret = fast_shmem_write(obj_priv->pages,
+				       page_base, page_offset,
+				       user_data, page_length);
+		if (ret)
+			goto fail_put_pages;
+
+		remain -= page_length;
+		user_data += page_length;
+		offset += page_length;
+	}
+
+fail_put_pages:
+	i915_gem_object_put_pages(obj);
+fail_unlock:
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+}
+
+/**
+ * This is the fallback shmem pwrite path, which uses get_user_pages to pin
+ * the memory and maps it using kmap_atomic for copying.
+ *
+ * This avoids taking mmap_sem for faulting on the user's address while the
+ * struct_mutex is held.
+ */
+static int
+i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
+			   struct drm_i915_gem_pwrite *args,
+			   struct drm_file *file_priv)
+{
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	struct mm_struct *mm = current->mm;
+	struct page **user_pages;
+	ssize_t remain;
+	loff_t offset, pinned_pages, i;
+	loff_t first_data_page, last_data_page, num_pages;
+	int shmem_page_index, shmem_page_offset;
+	int data_page_index,  data_page_offset;
+	int page_length;
+	int ret;
+	uint64_t data_ptr = args->data_ptr;
+	int do_bit17_swizzling;
+
+	remain = args->size;
+
+	/* Pin the user pages containing the data.  We can't fault while
+	 * holding the struct mutex, and all of the pwrite implementations
+	 * want to hold it while dereferencing the user data.
+	 */
+	first_data_page = data_ptr / PAGE_SIZE;
+	last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+	num_pages = last_data_page - first_data_page + 1;
+
+	user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
+	if (user_pages == NULL)
+		return -ENOMEM;
+
+	down_read(&mm->mmap_sem);
+	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+				      num_pages, 0, 0, user_pages, NULL);
+	up_read(&mm->mmap_sem);
+	if (pinned_pages < num_pages) {
+		ret = -EFAULT;
+		goto fail_put_user_pages;
 	}
 
+	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+
+	mutex_lock(&dev->struct_mutex);
+
+	ret = i915_gem_object_get_pages(obj);
+	if (ret != 0)
+		goto fail_unlock;
+
+	ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+	if (ret != 0)
+		goto fail_put_pages;
+
+	obj_priv = obj->driver_private;
 	offset = args->offset;
+	obj_priv->dirty = 1;
 
-	written = vfs_write(obj->filp,
-			    (char __user *)(uintptr_t) args->data_ptr,
-			    args->size, &offset);
-	if (written != args->size) {
-		mutex_unlock(&dev->struct_mutex);
-		if (written < 0)
-			return written;
-		else
-			return -EINVAL;
+	while (remain > 0) {
+		/* Operation in this page
+		 *
+		 * shmem_page_index = page number within shmem file
+		 * shmem_page_offset = offset within page in shmem file
+		 * data_page_index = page number in get_user_pages return
+		 * data_page_offset = offset with data_page_index page.
+		 * page_length = bytes to copy for this page
+		 */
+		shmem_page_index = offset / PAGE_SIZE;
+		shmem_page_offset = offset & ~PAGE_MASK;
+		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+		data_page_offset = data_ptr & ~PAGE_MASK;
+
+		page_length = remain;
+		if ((shmem_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - shmem_page_offset;
+		if ((data_page_offset + page_length) > PAGE_SIZE)
+			page_length = PAGE_SIZE - data_page_offset;
+
+		if (do_bit17_swizzling) {
+			ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index],
+						    shmem_page_offset,
+						    user_pages[data_page_index],
+						    data_page_offset,
+						    page_length,
+						    0);
+		} else {
+			ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
+					      shmem_page_offset,
+					      user_pages[data_page_index],
+					      data_page_offset,
+					      page_length);
+		}
+		if (ret)
+			goto fail_put_pages;
+
+		remain -= page_length;
+		data_ptr += page_length;
+		offset += page_length;
 	}
 
+fail_put_pages:
+	i915_gem_object_put_pages(obj);
+fail_unlock:
 	mutex_unlock(&dev->struct_mutex);
+fail_put_user_pages:
+	for (i = 0; i < pinned_pages; i++)
+		page_cache_release(user_pages[i]);
+	drm_free_large(user_pages);
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -388,10 +945,21 @@ i915_gem_pwrite_ioctl(struct drm_device
 	if (obj_priv->phys_obj)
 		ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
 	else if (obj_priv->tiling_mode == I915_TILING_NONE &&
-		 dev->gtt_total != 0)
-		ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
-	else
-		ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
+		 dev->gtt_total != 0) {
+		ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv);
+		if (ret == -EFAULT) {
+			ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
+						       file_priv);
+		}
+	} else if (i915_gem_object_needs_bit17_swizzle(obj)) {
+		ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file_priv);
+	} else {
+		ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv);
+		if (ret == -EFAULT) {
+			ret = i915_gem_shmem_pwrite_slow(dev, obj, args,
+							 file_priv);
+		}
+	}
 
 #if WATCH_PWRITE
 	if (ret)
@@ -577,7 +1145,14 @@ int i915_gem_fault(struct vm_area_struct
 			mutex_unlock(&dev->struct_mutex);
 			return VM_FAULT_SIGBUS;
 		}
-		list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
+
+		ret = i915_gem_object_set_to_gtt_domain(obj, write);
+		if (ret) {
+			mutex_unlock(&dev->struct_mutex);
+			return VM_FAULT_SIGBUS;
+		}
+
+		list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
 	}
 
 	/* Need a new fence register? */
@@ -603,6 +1178,7 @@ int i915_gem_fault(struct vm_area_struct
 	case -EAGAIN:
 		return VM_FAULT_OOM;
 	case -EFAULT:
+	case -EINVAL:
 		return VM_FAULT_SIGBUS;
 	default:
 		return VM_FAULT_NOPAGE;
@@ -627,7 +1203,7 @@ i915_gem_create_mmap_offset(struct drm_g
 	struct drm_gem_mm *mm = dev->mm_private;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	struct drm_map_list *list;
-	struct drm_map *map;
+	struct drm_local_map *map;
 	int ret = 0;
 
 	/* Set the object up for mmap'ing */
@@ -806,7 +1382,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_devic
 			mutex_unlock(&dev->struct_mutex);
 			return ret;
 		}
-		list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
+		list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
 	}
 
 	drm_gem_object_unreference(obj);
@@ -815,30 +1391,32 @@ i915_gem_mmap_gtt_ioctl(struct drm_devic
 	return 0;
 }
 
-static void
-i915_gem_object_free_page_list(struct drm_gem_object *obj)
+void
+i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int page_count = obj->size / PAGE_SIZE;
 	int i;
 
-	if (obj_priv->page_list == NULL)
+	BUG_ON(obj_priv->pages_refcount == 0);
+
+	if (--obj_priv->pages_refcount != 0)
 		return;
 
+	if (obj_priv->tiling_mode != I915_TILING_NONE)
+		i915_gem_object_save_bit_17_swizzle(obj);
 
 	for (i = 0; i < page_count; i++)
-		if (obj_priv->page_list[i] != NULL) {
+		if (obj_priv->pages[i] != NULL) {
 			if (obj_priv->dirty)
-				set_page_dirty(obj_priv->page_list[i]);
-			mark_page_accessed(obj_priv->page_list[i]);
-			page_cache_release(obj_priv->page_list[i]);
+				set_page_dirty(obj_priv->pages[i]);
+			mark_page_accessed(obj_priv->pages[i]);
+			page_cache_release(obj_priv->pages[i]);
 		}
 	obj_priv->dirty = 0;
 
-	drm_free(obj_priv->page_list,
-		 page_count * sizeof(struct page *),
-		 DRM_MEM_DRIVER);
-	obj_priv->page_list = NULL;
+	drm_free_large(obj_priv->pages);
+	obj_priv->pages = NULL;
 }
 
 static void
@@ -854,8 +1432,10 @@ i915_gem_object_move_to_active(struct dr
 		obj_priv->active = 1;
 	}
 	/* Move from whatever list we were on to the tail of execution. */
+	spin_lock(&dev_priv->mm.active_list_lock);
 	list_move_tail(&obj_priv->list,
 		       &dev_priv->mm.active_list);
+	spin_unlock(&dev_priv->mm.active_list_lock);
 	obj_priv->last_rendering_seqno = seqno;
 }
 
@@ -997,6 +1577,7 @@ i915_gem_retire_request(struct drm_devic
 	/* Move any buffers on the active list that are no longer referenced
 	 * by the ringbuffer to the flushing/inactive lists as appropriate.
 	 */
+	spin_lock(&dev_priv->mm.active_list_lock);
 	while (!list_empty(&dev_priv->mm.active_list)) {
 		struct drm_gem_object *obj;
 		struct drm_i915_gem_object *obj_priv;
@@ -1011,7 +1592,7 @@ i915_gem_retire_request(struct drm_devic
 		 * this seqno.
 		 */
 		if (obj_priv->last_rendering_seqno != request->seqno)
-			return;
+			goto out;
 
 #if WATCH_LRU
 		DRM_INFO("%s: retire %d moves to inactive list %p\n",
@@ -1020,9 +1601,22 @@ i915_gem_retire_request(struct drm_devic
 
 		if (obj->write_domain != 0)
 			i915_gem_object_move_to_flushing(obj);
-		else
+		else {
+			/* Take a reference on the object so it won't be
+			 * freed while the spinlock is held.  The list
+			 * protection for this spinlock is safe when breaking
+			 * the lock like this since the next thing we do
+			 * is just get the head of the list again.
+			 */
+			drm_gem_object_reference(obj);
 			i915_gem_object_move_to_inactive(obj);
+			spin_unlock(&dev_priv->mm.active_list_lock);
+			drm_gem_object_unreference(obj);
+			spin_lock(&dev_priv->mm.active_list_lock);
+		}
 	}
+out:
+	spin_unlock(&dev_priv->mm.active_list_lock);
 }
 
 /**
@@ -1102,11 +1696,20 @@ static int
 i915_wait_request(struct drm_device *dev, uint32_t seqno)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
+	u32 ier;
 	int ret = 0;
 
 	BUG_ON(seqno == 0);
 
 	if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
+		ier = I915_READ(IER);
+		if (!ier) {
+			DRM_ERROR("something (likely vbetool) disabled "
+				  "interrupts, re-enabling\n");
+			i915_driver_irq_preinstall(dev);
+			i915_driver_irq_postinstall(dev);
+		}
+
 		dev_priv->mm.waiting_gem_seqno = seqno;
 		i915_user_irq_get(dev);
 		ret = wait_event_interruptible(dev_priv->irq_queue,
@@ -1290,7 +1893,7 @@ i915_gem_object_unbind(struct drm_gem_ob
 	if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
 		i915_gem_clear_fence_reg(obj);
 
-	i915_gem_object_free_page_list(obj);
+	i915_gem_object_put_pages(obj);
 
 	if (obj_priv->gtt_space) {
 		atomic_dec(&dev->gtt_count);
@@ -1408,8 +2011,8 @@ i915_gem_evict_everything(struct drm_dev
 	return ret;
 }
 
-static int
-i915_gem_object_get_page_list(struct drm_gem_object *obj)
+int
+i915_gem_object_get_pages(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int page_count, i;
@@ -1418,18 +2021,18 @@ i915_gem_object_get_page_list(struct drm
 	struct page *page;
 	int ret;
 
-	if (obj_priv->page_list)
+	if (obj_priv->pages_refcount++ != 0)
 		return 0;
 
 	/* Get the list of pages out of our struct file.  They'll be pinned
 	 * at this point until we release them.
 	 */
 	page_count = obj->size / PAGE_SIZE;
-	BUG_ON(obj_priv->page_list != NULL);
-	obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
-					 DRM_MEM_DRIVER);
-	if (obj_priv->page_list == NULL) {
+	BUG_ON(obj_priv->pages != NULL);
+	obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *));
+	if (obj_priv->pages == NULL) {
 		DRM_ERROR("Faled to allocate page list\n");
+		obj_priv->pages_refcount--;
 		return -ENOMEM;
 	}
 
@@ -1440,11 +2043,15 @@ i915_gem_object_get_page_list(struct drm
 		if (IS_ERR(page)) {
 			ret = PTR_ERR(page);
 			DRM_ERROR("read_mapping_page failed: %d\n", ret);
-			i915_gem_object_free_page_list(obj);
+			i915_gem_object_put_pages(obj);
 			return ret;
 		}
-		obj_priv->page_list[i] = page;
+		obj_priv->pages[i] = page;
 	}
+
+	if (obj_priv->tiling_mode != I915_TILING_NONE)
+		i915_gem_object_do_bit_17_swizzle(obj);
+
 	return 0;
 }
 
@@ -1519,20 +2126,25 @@ static void i830_write_fence_reg(struct
 	int regnum = obj_priv->fence_reg;
 	uint32_t val;
 	uint32_t pitch_val;
+	uint32_t fence_size_bits;
 
-	if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
+	if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
 	    (obj_priv->gtt_offset & (obj->size - 1))) {
-		WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
+		WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
 		     __func__, obj_priv->gtt_offset);
 		return;
 	}
 
-	pitch_val = (obj_priv->stride / 128) - 1;
+	pitch_val = obj_priv->stride / 128;
+	pitch_val = ffs(pitch_val) - 1;
+	WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
 
 	val = obj_priv->gtt_offset;
 	if (obj_priv->tiling_mode == I915_TILING_Y)
 		val |= 1 << I830_FENCE_TILING_Y_SHIFT;
-	val |= I830_FENCE_SIZE_BITS(obj->size);
+	fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
+	WARN_ON(fence_size_bits & ~0x00000f00);
+	val |= fence_size_bits;
 	val |= pitch_val << I830_FENCE_PITCH_SHIFT;
 	val |= I830_FENCE_REG_VALID;
 
@@ -1648,9 +2260,6 @@ try_again:
 			goto try_again;
 		}
 
-		BUG_ON(old_obj_priv->active ||
-		       (reg->obj->write_domain & I915_GEM_GPU_DOMAINS));
-
 		/*
 		 * Zap this virtual mapping so we can set up a fence again
 		 * for this object next time we need it.
@@ -1723,7 +2332,7 @@ i915_gem_object_bind_to_gtt(struct drm_g
 		return -EBUSY;
 	if (alignment == 0)
 		alignment = i915_gem_get_gtt_alignment(obj);
-	if (alignment & (PAGE_SIZE - 1)) {
+	if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
 		DRM_ERROR("Invalid object alignment requested %u\n", alignment);
 		return -EINVAL;
 	}
@@ -1740,15 +2349,20 @@ i915_gem_object_bind_to_gtt(struct drm_g
 		}
 	}
 	if (obj_priv->gtt_space == NULL) {
+		bool lists_empty;
+
 		/* If the gtt is empty and we're still having trouble
 		 * fitting our object in, we're out of memory.
 		 */
 #if WATCH_LRU
 		DRM_INFO("%s: GTT full, evicting something\n", __func__);
 #endif
-		if (list_empty(&dev_priv->mm.inactive_list) &&
-		    list_empty(&dev_priv->mm.flushing_list) &&
-		    list_empty(&dev_priv->mm.active_list)) {
+		spin_lock(&dev_priv->mm.active_list_lock);
+		lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
+			       list_empty(&dev_priv->mm.flushing_list) &&
+			       list_empty(&dev_priv->mm.active_list));
+		spin_unlock(&dev_priv->mm.active_list_lock);
+		if (lists_empty) {
 			DRM_ERROR("GTT full, but LRU list empty\n");
 			return -ENOMEM;
 		}
@@ -1766,7 +2380,7 @@ i915_gem_object_bind_to_gtt(struct drm_g
 	DRM_INFO("Binding object of size %d at 0x%08x\n",
 		 obj->size, obj_priv->gtt_offset);
 #endif
-	ret = i915_gem_object_get_page_list(obj);
+	ret = i915_gem_object_get_pages(obj);
 	if (ret) {
 		drm_mm_put_block(obj_priv->gtt_space);
 		obj_priv->gtt_space = NULL;
@@ -1778,12 +2392,12 @@ i915_gem_object_bind_to_gtt(struct drm_g
 	 * into the GTT.
 	 */
 	obj_priv->agp_mem = drm_agp_bind_pages(dev,
-					       obj_priv->page_list,
+					       obj_priv->pages,
 					       page_count,
 					       obj_priv->gtt_offset,
 					       obj_priv->agp_type);
 	if (obj_priv->agp_mem == NULL) {
-		i915_gem_object_free_page_list(obj);
+		i915_gem_object_put_pages(obj);
 		drm_mm_put_block(obj_priv->gtt_space);
 		obj_priv->gtt_space = NULL;
 		return -ENOMEM;
@@ -1810,10 +2424,20 @@ i915_gem_clflush_object(struct drm_gem_o
 	 * to GPU, and we can ignore the cache flush because it'll happen
 	 * again at bind time.
 	 */
-	if (obj_priv->page_list == NULL)
+	if (obj_priv->pages == NULL)
 		return;
 
-	drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
+	/* XXX: The 865 in particular appears to be weird in how it handles
+	 * cache flushing.  We haven't figured it out, but the
+	 * clflush+agp_chipset_flush doesn't appear to successfully get the
+	 * data visible to the PGU, while wbinvd + agp_chipset_flush does.
+	 */
+	if (IS_I865G(obj->dev)) {
+		wbinvd();
+		return;
+	}
+
+	drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE);
 }
 
 /** Flushes any GPU write domain for the object if it's dirty. */
@@ -1913,7 +2537,6 @@ i915_gem_object_set_to_gtt_domain(struct
 static int
 i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
 {
-	struct drm_device *dev = obj->dev;
 	int ret;
 
 	i915_gem_object_flush_gpu_write_domain(obj);
@@ -1932,7 +2555,6 @@ i915_gem_object_set_to_cpu_domain(struct
 	/* Flush the CPU cache if it's still invalid. */
 	if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) {
 		i915_gem_clflush_object(obj);
-		drm_agp_chipset_flush(dev);
 
 		obj->read_domains |= I915_GEM_DOMAIN_CPU;
 	}
@@ -2144,7 +2766,6 @@ i915_gem_object_set_to_gpu_domain(struct
 static void
 i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
 {
-	struct drm_device *dev = obj->dev;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 
 	if (!obj_priv->page_cpu_valid)
@@ -2158,9 +2779,8 @@ i915_gem_object_set_to_full_cpu_read_dom
 		for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) {
 			if (obj_priv->page_cpu_valid[i])
 				continue;
-			drm_clflush_pages(obj_priv->page_list + i, 1);
+			drm_clflush_pages(obj_priv->pages + i, 1);
 		}
-		drm_agp_chipset_flush(dev);
 	}
 
 	/* Free the page_cpu_valid mappings which are now stale, whether
@@ -2224,7 +2844,7 @@ i915_gem_object_set_cpu_read_domain_rang
 		if (obj_priv->page_cpu_valid[i])
 			continue;
 
-		drm_clflush_pages(obj_priv->page_list + i, 1);
+		drm_clflush_pages(obj_priv->pages + i, 1);
 
 		obj_priv->page_cpu_valid[i] = 1;
 	}
@@ -2245,12 +2865,11 @@ 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_object *entry,
+				 struct drm_i915_gem_relocation_entry *relocs)
 {
 	struct drm_device *dev = obj->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_relocation_entry __user *relocs;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int i, ret;
 	void __iomem *reloc_page;
@@ -2262,25 +2881,18 @@ i915_gem_object_pin_and_relocate(struct
 
 	entry->offset = obj_priv->gtt_offset;
 
-	relocs = (struct drm_i915_gem_relocation_entry __user *)
-		 (uintptr_t) entry->relocs_ptr;
 	/* Apply the relocations, using the GTT aperture to avoid cache
 	 * flushing requirements.
 	 */
 	for (i = 0; i < entry->relocation_count; i++) {
+		struct drm_i915_gem_relocation_entry *reloc= &relocs[i];
 		struct drm_gem_object *target_obj;
 		struct drm_i915_gem_object *target_obj_priv;
 		uint32_t reloc_val, reloc_offset;
 		uint32_t __iomem *reloc_entry;
 
-		ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
-		if (ret != 0) {
-			i915_gem_object_unpin(obj);
-			return ret;
-		}
-
 		target_obj = drm_gem_object_lookup(obj->dev, file_priv,
-						   reloc.target_handle);
+						   reloc->target_handle);
 		if (target_obj == NULL) {
 			i915_gem_object_unpin(obj);
 			return -EBADF;
@@ -2292,53 +2904,53 @@ i915_gem_object_pin_and_relocate(struct
 		 */
 		if (target_obj_priv->gtt_space == NULL) {
 			DRM_ERROR("No GTT space found for object %d\n",
-				  reloc.target_handle);
+				  reloc->target_handle);
 			drm_gem_object_unreference(target_obj);
 			i915_gem_object_unpin(obj);
 			return -EINVAL;
 		}
 
-		if (reloc.offset > obj->size - 4) {
+		if (reloc->offset > obj->size - 4) {
 			DRM_ERROR("Relocation beyond object bounds: "
 				  "obj %p target %d offset %d size %d.\n",
-				  obj, reloc.target_handle,
-				  (int) reloc.offset, (int) obj->size);
+				  obj, reloc->target_handle,
+				  (int) reloc->offset, (int) obj->size);
 			drm_gem_object_unreference(target_obj);
 			i915_gem_object_unpin(obj);
 			return -EINVAL;
 		}
-		if (reloc.offset & 3) {
+		if (reloc->offset & 3) {
 			DRM_ERROR("Relocation not 4-byte aligned: "
 				  "obj %p target %d offset %d.\n",
-				  obj, reloc.target_handle,
-				  (int) reloc.offset);
+				  obj, reloc->target_handle,
+				  (int) reloc->offset);
 			drm_gem_object_unreference(target_obj);
 			i915_gem_object_unpin(obj);
 			return -EINVAL;
 		}
 
-		if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
-		    reloc.read_domains & I915_GEM_DOMAIN_CPU) {
+		if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+		    reloc->read_domains & I915_GEM_DOMAIN_CPU) {
 			DRM_ERROR("reloc with read/write CPU domains: "
 				  "obj %p target %d offset %d "
 				  "read %08x write %08x",
-				  obj, reloc.target_handle,
-				  (int) reloc.offset,
-				  reloc.read_domains,
-				  reloc.write_domain);
+				  obj, reloc->target_handle,
+				  (int) reloc->offset,
+				  reloc->read_domains,
+				  reloc->write_domain);
 			drm_gem_object_unreference(target_obj);
 			i915_gem_object_unpin(obj);
 			return -EINVAL;
 		}
 
-		if (reloc.write_domain && target_obj->pending_write_domain &&
-		    reloc.write_domain != target_obj->pending_write_domain) {
+		if (reloc->write_domain && target_obj->pending_write_domain &&
+		    reloc->write_domain != target_obj->pending_write_domain) {
 			DRM_ERROR("Write domain conflict: "
 				  "obj %p target %d offset %d "
 				  "new %08x old %08x\n",
-				  obj, reloc.target_handle,
-				  (int) reloc.offset,
-				  reloc.write_domain,
+				  obj, reloc->target_handle,
+				  (int) reloc->offset,
+				  reloc->write_domain,
 				  target_obj->pending_write_domain);
 			drm_gem_object_unreference(target_obj);
 			i915_gem_object_unpin(obj);
@@ -2351,22 +2963,22 @@ i915_gem_object_pin_and_relocate(struct
 			 "presumed %08x delta %08x\n",
 			 __func__,
 			 obj,
-			 (int) reloc.offset,
-			 (int) reloc.target_handle,
-			 (int) reloc.read_domains,
-			 (int) reloc.write_domain,
+			 (int) reloc->offset,
+			 (int) reloc->target_handle,
+			 (int) reloc->read_domains,
+			 (int) reloc->write_domain,
 			 (int) target_obj_priv->gtt_offset,
-			 (int) reloc.presumed_offset,
-			 reloc.delta);
+			 (int) reloc->presumed_offset,
+			 reloc->delta);
 #endif
 
-		target_obj->pending_read_domains |= reloc.read_domains;
-		target_obj->pending_write_domain |= reloc.write_domain;
+		target_obj->pending_read_domains |= reloc->read_domains;
+		target_obj->pending_write_domain |= reloc->write_domain;
 
 		/* If the relocation already has the right value in it, no
 		 * more work needs to be done.
 		 */
-		if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
+		if (target_obj_priv->gtt_offset == reloc->presumed_offset) {
 			drm_gem_object_unreference(target_obj);
 			continue;
 		}
@@ -2381,32 +2993,26 @@ i915_gem_object_pin_and_relocate(struct
 		/* Map the page containing the relocation we're going to
 		 * perform.
 		 */
-		reloc_offset = obj_priv->gtt_offset + reloc.offset;
+		reloc_offset = obj_priv->gtt_offset + reloc->offset;
 		reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
 						      (reloc_offset &
 						       ~(PAGE_SIZE - 1)));
 		reloc_entry = (uint32_t __iomem *)(reloc_page +
 						   (reloc_offset & (PAGE_SIZE - 1)));
-		reloc_val = target_obj_priv->gtt_offset + reloc.delta;
+		reloc_val = target_obj_priv->gtt_offset + reloc->delta;
 
 #if WATCH_BUF
 		DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
-			  obj, (unsigned int) reloc.offset,
+			  obj, (unsigned int) reloc->offset,
 			  readl(reloc_entry), reloc_val);
 #endif
 		writel(reloc_val, reloc_entry);
 		io_mapping_unmap_atomic(reloc_page);
 
-		/* Write the updated presumed offset for this entry back out
-		 * to the user.
+		/* The updated presumed offset for this entry will be
+		 * copied back out to the user.
 		 */
-		reloc.presumed_offset = target_obj_priv->gtt_offset;
-		ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
-		if (ret != 0) {
-			drm_gem_object_unreference(target_obj);
-			i915_gem_object_unpin(obj);
-			return ret;
-		}
+		reloc->presumed_offset = target_obj_priv->gtt_offset;
 
 		drm_gem_object_unreference(target_obj);
 	}
@@ -2423,11 +3029,10 @@ 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_clip_rect *cliprects,
 			      uint64_t exec_offset)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
-					     (uintptr_t) exec->cliprects_ptr;
 	int nbox = exec->num_cliprects;
 	int i = 0, count;
 	uint32_t	exec_start, exec_len;
@@ -2448,7 +3053,7 @@ i915_dispatch_gem_execbuffer(struct drm_
 
 	for (i = 0; i < count; i++) {
 		if (i < nbox) {
-			int ret = i915_emit_box(dev, boxes, i,
+			int ret = i915_emit_box(dev, cliprects, i,
 						exec->DR1, exec->DR4);
 			if (ret)
 				return ret;
@@ -2504,6 +3109,79 @@ i915_gem_ring_throttle(struct drm_device
 	return ret;
 }
 
+static int
+i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
+			      uint32_t buffer_count,
+			      struct drm_i915_gem_relocation_entry **relocs)
+{
+	uint32_t reloc_count = 0, reloc_index = 0, i;
+	int ret;
+
+	*relocs = NULL;
+	for (i = 0; i < buffer_count; i++) {
+		if (reloc_count + exec_list[i].relocation_count < reloc_count)
+			return -EINVAL;
+		reloc_count += exec_list[i].relocation_count;
+	}
+
+	*relocs = drm_calloc_large(reloc_count, sizeof(**relocs));
+	if (*relocs == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < buffer_count; i++) {
+		struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+		user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+		ret = copy_from_user(&(*relocs)[reloc_index],
+				     user_relocs,
+				     exec_list[i].relocation_count *
+				     sizeof(**relocs));
+		if (ret != 0) {
+			drm_free_large(*relocs);
+			*relocs = NULL;
+			return -EFAULT;
+		}
+
+		reloc_index += exec_list[i].relocation_count;
+	}
+
+	return 0;
+}
+
+static int
+i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list,
+			    uint32_t buffer_count,
+			    struct drm_i915_gem_relocation_entry *relocs)
+{
+	uint32_t reloc_count = 0, i;
+	int ret = 0;
+
+	for (i = 0; i < buffer_count; i++) {
+		struct drm_i915_gem_relocation_entry __user *user_relocs;
+		int unwritten;
+
+		user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+		unwritten = copy_to_user(user_relocs,
+					 &relocs[reloc_count],
+					 exec_list[i].relocation_count *
+					 sizeof(*relocs));
+
+		if (unwritten) {
+			ret = -EFAULT;
+			goto err;
+		}
+
+		reloc_count += exec_list[i].relocation_count;
+	}
+
+err:
+	drm_free_large(relocs);
+
+	return ret;
+}
+
 int
 i915_gem_execbuffer(struct drm_device *dev, void *data,
 		    struct drm_file *file_priv)
@@ -2515,9 +3193,11 @@ i915_gem_execbuffer(struct drm_device *d
 	struct drm_gem_object **object_list = NULL;
 	struct drm_gem_object *batch_obj;
 	struct drm_i915_gem_object *obj_priv;
-	int ret, i, pinned = 0;
+	struct drm_clip_rect *cliprects = NULL;
+	struct drm_i915_gem_relocation_entry *relocs;
+	int ret, ret2, i, pinned = 0;
 	uint64_t exec_offset;
-	uint32_t seqno, flush_domains;
+	uint32_t seqno, flush_domains, reloc_index;
 	int pin_tries;
 
 #if WATCH_EXEC
@@ -2530,10 +3210,8 @@ i915_gem_execbuffer(struct drm_device *d
 		return -EINVAL;
 	}
 	/* Copy in the exec list from userland */
-	exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
-			       DRM_MEM_DRIVER);
-	object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
-				 DRM_MEM_DRIVER);
+	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",
@@ -2551,6 +3229,28 @@ i915_gem_execbuffer(struct drm_device *d
 		goto pre_mutex_err;
 	}
 
+	if (args->num_cliprects != 0) {
+		cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects),
+				       DRM_MEM_DRIVER);
+		if (cliprects == NULL)
+			goto pre_mutex_err;
+
+		ret = copy_from_user(cliprects,
+				     (struct drm_clip_rect __user *)
+				     (uintptr_t) args->cliprects_ptr,
+				     sizeof(*cliprects) * args->num_cliprects);
+		if (ret != 0) {
+			DRM_ERROR("copy %d cliprects failed: %d\n",
+				  args->num_cliprects, ret);
+			goto pre_mutex_err;
+		}
+	}
+
+	ret = i915_gem_get_relocs_from_user(exec_list, args->buffer_count,
+					    &relocs);
+	if (ret != 0)
+		goto pre_mutex_err;
+
 	mutex_lock(&dev->struct_mutex);
 
 	i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2593,15 +3293,19 @@ i915_gem_execbuffer(struct drm_device *d
 	/* Pin and relocate */
 	for (pin_tries = 0; ; pin_tries++) {
 		ret = 0;
+		reloc_index = 0;
+
 		for (i = 0; i < args->buffer_count; i++) {
 			object_list[i]->pending_read_domains = 0;
 			object_list[i]->pending_write_domain = 0;
 			ret = i915_gem_object_pin_and_relocate(object_list[i],
 							       file_priv,
-							       &exec_list[i]);
+							       &exec_list[i],
+							       &relocs[reloc_index]);
 			if (ret)
 				break;
 			pinned = i + 1;
+			reloc_index += exec_list[i].relocation_count;
 		}
 		/* success */
 		if (ret == 0)
@@ -2680,14 +3384,14 @@ i915_gem_execbuffer(struct drm_device *d
 	exec_offset = exec_list[args->buffer_count - 1].offset;
 
 #if WATCH_EXEC
-	i915_gem_dump_object(object_list[args->buffer_count - 1],
+	i915_gem_dump_object(batch_obj,
 			      args->batch_len,
 			      __func__,
 			      ~0);
 #endif
 
 	/* Exec the batchbuffer */
-	ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
+	ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
 	if (ret) {
 		DRM_ERROR("dispatch failed %d\n", ret);
 		goto err;
@@ -2745,16 +3449,32 @@ err:
 				   (uintptr_t) args->buffers_ptr,
 				   exec_list,
 				   sizeof(*exec_list) * args->buffer_count);
-		if (ret)
+		if (ret) {
+			ret = -EFAULT;
 			DRM_ERROR("failed to copy %d exec entries "
 				  "back to user (%d)\n",
 				  args->buffer_count, ret);
+		}
+	}
+
+	/* 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;
 	}
 
 pre_mutex_err:
-	drm_free(object_list, sizeof(*object_list) * args->buffer_count,
-		 DRM_MEM_DRIVER);
-	drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
+	drm_free_large(object_list);
+	drm_free_large(exec_list);
+	drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects,
 		 DRM_MEM_DRIVER);
 
 	return ret;
@@ -3014,6 +3734,7 @@ void i915_gem_free_object(struct drm_gem
 	i915_gem_free_mmap_offset(obj);
 
 	drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
+	kfree(obj_priv->bit_17);
 	drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
 }
 
@@ -3110,6 +3831,7 @@ i915_gem_idle(struct drm_device *dev)
 
 	i915_gem_retire_requests(dev);
 
+	spin_lock(&dev_priv->mm.active_list_lock);
 	if (!dev_priv->mm.wedged) {
 		/* Active and flushing should now be empty as we've
 		 * waited for a sequence higher than any pending execbuffer
@@ -3136,6 +3858,7 @@ i915_gem_idle(struct drm_device *dev)
 		obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
 		i915_gem_object_move_to_inactive(obj_priv->obj);
 	}
+	spin_unlock(&dev_priv->mm.active_list_lock);
 
 	while (!list_empty(&dev_priv->mm.flushing_list)) {
 		struct drm_i915_gem_object *obj_priv;
@@ -3192,7 +3915,7 @@ i915_gem_init_hws(struct drm_device *dev
 
 	dev_priv->status_gfx_addr = obj_priv->gtt_offset;
 
-	dev_priv->hw_status_page = kmap(obj_priv->page_list[0]);
+	dev_priv->hw_status_page = kmap(obj_priv->pages[0]);
 	if (dev_priv->hw_status_page == NULL) {
 		DRM_ERROR("Failed to map status page.\n");
 		memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
@@ -3222,7 +3945,7 @@ i915_gem_cleanup_hws(struct drm_device *
 	obj = dev_priv->hws_obj;
 	obj_priv = obj->driver_private;
 
-	kunmap(obj_priv->page_list[0]);
+	kunmap(obj_priv->pages[0]);
 	i915_gem_object_unpin(obj);
 	drm_gem_object_unreference(obj);
 	dev_priv->hws_obj = NULL;
@@ -3381,10 +4104,15 @@ i915_gem_entervt_ioctl(struct drm_device
 	dev_priv->mm.suspended = 0;
 
 	ret = i915_gem_init_ringbuffer(dev);
-	if (ret != 0)
+	if (ret != 0) {
+		mutex_unlock(&dev->struct_mutex);
 		return ret;
+	}
 
+	spin_lock(&dev_priv->mm.active_list_lock);
 	BUG_ON(!list_empty(&dev_priv->mm.active_list));
+	spin_unlock(&dev_priv->mm.active_list_lock);
+
 	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
 	BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
 	BUG_ON(!list_empty(&dev_priv->mm.request_list));
@@ -3428,6 +4156,7 @@ i915_gem_load(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
+	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.inactive_list);
@@ -3525,20 +4254,20 @@ void i915_gem_detach_phys_object(struct
 	if (!obj_priv->phys_obj)
 		return;
 
-	ret = i915_gem_object_get_page_list(obj);
+	ret = i915_gem_object_get_pages(obj);
 	if (ret)
 		goto out;
 
 	page_count = obj->size / PAGE_SIZE;
 
 	for (i = 0; i < page_count; i++) {
-		char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+		char *dst = kmap_atomic(obj_priv->pages[i], KM_USER0);
 		char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
 
 		memcpy(dst, src, PAGE_SIZE);
 		kunmap_atomic(dst, KM_USER0);
 	}
-	drm_clflush_pages(obj_priv->page_list, page_count);
+	drm_clflush_pages(obj_priv->pages, page_count);
 	drm_agp_chipset_flush(dev);
 out:
 	obj_priv->phys_obj->cur_obj = NULL;
@@ -3581,7 +4310,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_page_list(obj);
+	ret = i915_gem_object_get_pages(obj);
 	if (ret) {
 		DRM_ERROR("failed to get page list\n");
 		goto out;
@@ -3590,7 +4319,7 @@ i915_gem_attach_phys_object(struct drm_d
 	page_count = obj->size / PAGE_SIZE;
 
 	for (i = 0; i < page_count; i++) {
-		char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+		char *src = kmap_atomic(obj_priv->pages[i], KM_USER0);
 		char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
 
 		memcpy(dst, src, PAGE_SIZE);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, co
 	struct drm_i915_gem_object	*obj_priv;
 
 	DRM_INFO("active list %s {\n", where);
+	spin_lock(&dev_priv->mm.active_list_lock);
 	list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
 			    list)
 	{
 		DRM_INFO("    %p: %08x\n", obj_priv,
 			 obj_priv->last_rendering_seqno);
 	}
+	spin_unlock(&dev_priv->mm.active_list_lock);
 	DRM_INFO("}\n");
 	DRM_INFO("flushing list %s {\n", where);
 	list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_debugfs.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,356 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/seq_file.h>
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+#define DRM_I915_RING_DEBUG 1
+
+
+#if defined(CONFIG_DEBUG_FS)
+
+#define ACTIVE_LIST	1
+#define FLUSHING_LIST	2
+#define INACTIVE_LIST	3
+
+static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
+{
+	if (obj_priv->user_pin_count > 0)
+		return "P";
+	else if (obj_priv->pin_count > 0)
+		return "p";
+	else
+		return " ";
+}
+
+static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
+{
+    switch (obj_priv->tiling_mode) {
+    default:
+    case I915_TILING_NONE: return " ";
+    case I915_TILING_X: return "X";
+    case I915_TILING_Y: return "Y";
+    }
+}
+
+static int i915_gem_object_list_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	uintptr_t list = (uintptr_t) node->info_ent->data;
+	struct list_head *head;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv;
+	spinlock_t *lock = NULL;
+
+	switch (list) {
+	case ACTIVE_LIST:
+		seq_printf(m, "Active:\n");
+		lock = &dev_priv->mm.active_list_lock;
+		spin_lock(lock);
+		head = &dev_priv->mm.active_list;
+		break;
+	case INACTIVE_LIST:
+		seq_printf(m, "Inctive:\n");
+		head = &dev_priv->mm.inactive_list;
+		break;
+	case FLUSHING_LIST:
+		seq_printf(m, "Flushing:\n");
+		head = &dev_priv->mm.flushing_list;
+		break;
+	default:
+		DRM_INFO("Ooops, unexpected list\n");
+		return 0;
+	}
+
+	list_for_each_entry(obj_priv, head, list)
+	{
+		struct drm_gem_object *obj = obj_priv->obj;
+
+		seq_printf(m, "    %p: %s %08x %08x %d",
+			   obj,
+			   get_pin_flag(obj_priv),
+			   obj->read_domains, obj->write_domain,
+			   obj_priv->last_rendering_seqno);
+
+		if (obj->name)
+			seq_printf(m, " (name: %d)", obj->name);
+		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+			seq_printf(m, " (fence: %d\n", obj_priv->fence_reg);
+		seq_printf(m, "\n");
+	}
+
+	if (lock)
+	    spin_unlock(lock);
+	return 0;
+}
+
+static int i915_gem_request_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_request *gem_request;
+
+	seq_printf(m, "Request:\n");
+	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
+		seq_printf(m, "    %d @ %d\n",
+			   gem_request->seqno,
+			   (int) (jiffies - gem_request->emitted_jiffies));
+	}
+	return 0;
+}
+
+static int i915_gem_seqno_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (dev_priv->hw_status_page != NULL) {
+		seq_printf(m, "Current sequence: %d\n",
+			   i915_get_gem_seqno(dev));
+	} else {
+		seq_printf(m, "Current sequence: hws uninitialized\n");
+	}
+	seq_printf(m, "Waiter sequence:  %d\n",
+			dev_priv->mm.waiting_gem_seqno);
+	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
+	return 0;
+}
+
+
+static int i915_interrupt_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	seq_printf(m, "Interrupt enable:    %08x\n",
+		   I915_READ(IER));
+	seq_printf(m, "Interrupt identity:  %08x\n",
+		   I915_READ(IIR));
+	seq_printf(m, "Interrupt mask:      %08x\n",
+		   I915_READ(IMR));
+	seq_printf(m, "Pipe A stat:         %08x\n",
+		   I915_READ(PIPEASTAT));
+	seq_printf(m, "Pipe B stat:         %08x\n",
+		   I915_READ(PIPEBSTAT));
+	seq_printf(m, "Interrupts received: %d\n",
+		   atomic_read(&dev_priv->irq_received));
+	if (dev_priv->hw_status_page != NULL) {
+		seq_printf(m, "Current sequence:    %d\n",
+			   i915_get_gem_seqno(dev));
+	} else {
+		seq_printf(m, "Current sequence:    hws uninitialized\n");
+	}
+	seq_printf(m, "Waiter sequence:     %d\n",
+		   dev_priv->mm.waiting_gem_seqno);
+	seq_printf(m, "IRQ sequence:        %d\n",
+		   dev_priv->mm.irq_gem_seqno);
+	return 0;
+}
+
+static int i915_gem_fence_regs_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int i;
+
+	seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
+	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
+
+		if (obj == NULL) {
+			seq_printf(m, "Fenced object[%2d] = unused\n", i);
+		} else {
+			struct drm_i915_gem_object *obj_priv;
+
+			obj_priv = obj->driver_private;
+			seq_printf(m, "Fenced object[%2d] = %p: %s "
+				   "%08x %08zx %08x %s %08x %08x %d",
+				   i, obj, get_pin_flag(obj_priv),
+				   obj_priv->gtt_offset,
+				   obj->size, obj_priv->stride,
+				   get_tiling_flag(obj_priv),
+				   obj->read_domains, obj->write_domain,
+				   obj_priv->last_rendering_seqno);
+			if (obj->name)
+				seq_printf(m, " (name: %d)", obj->name);
+			seq_printf(m, "\n");
+		}
+	}
+
+	return 0;
+}
+
+static int i915_hws_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int i;
+	volatile u32 *hws;
+
+	hws = (volatile u32 *)dev_priv->hw_status_page;
+	if (hws == NULL)
+		return 0;
+
+	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
+		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			   i * 4,
+			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
+	}
+	return 0;
+}
+
+static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
+{
+	int page, i;
+	uint32_t *mem;
+
+	for (page = 0; page < page_count; page++) {
+		mem = kmap(pages[page]);
+		for (i = 0; i < PAGE_SIZE; i += 4)
+			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
+		kunmap(pages[page]);
+	}
+}
+
+static int i915_batchbuffer_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
+	int ret;
+
+	spin_lock(&dev_priv->mm.active_list_lock);
+
+	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);
+		    if (ret) {
+			    DRM_ERROR("Failed to get pages: %d\n", ret);
+			    spin_unlock(&dev_priv->mm.active_list_lock);
+			    return ret;
+		    }
+
+		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
+		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
+
+		    i915_gem_object_put_pages(obj);
+		}
+	}
+
+	spin_unlock(&dev_priv->mm.active_list_lock);
+
+	return 0;
+}
+
+static int i915_ringbuffer_data(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	u8 *virt;
+	uint32_t *ptr, off;
+
+	if (!dev_priv->ring.ring_obj) {
+		seq_printf(m, "No ringbuffer setup\n");
+		return 0;
+	}
+
+	virt = dev_priv->ring.virtual_start;
+
+	for (off = 0; off < dev_priv->ring.Size; off += 4) {
+		ptr = (uint32_t *)(virt + off);
+		seq_printf(m, "%08x :  %08x\n", off, *ptr);
+	}
+
+	return 0;
+}
+
+static int i915_ringbuffer_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;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	unsigned int head, tail, mask;
+
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
+	mask = dev_priv->ring.tail_mask;
+
+	seq_printf(m, "RingHead :  %08x\n", head);
+	seq_printf(m, "RingTail :  %08x\n", tail);
+	seq_printf(m, "RingMask :  %08x\n", mask);
+	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
+	seq_printf(m, "Acthd :  %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
+
+	return 0;
+}
+
+
+static struct drm_info_list i915_gem_debugfs_list[] = {
+	{"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},
+	{"i915_gem_request", i915_gem_request_info, 0},
+	{"i915_gem_seqno", i915_gem_seqno_info, 0},
+	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
+	{"i915_gem_interrupt", i915_interrupt_info, 0},
+	{"i915_gem_hws", i915_hws_info, 0},
+	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
+	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
+	{"i915_batchbuffers", i915_batchbuffer_info, 0},
+};
+#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
+
+int i915_gem_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(i915_gem_debugfs_list,
+					I915_GEM_DEBUGFS_ENTRIES,
+					minor->debugfs_root, minor);
+}
+
+void i915_gem_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(i915_gem_debugfs_list,
+				 I915_GEM_DEBUGFS_ENTRIES, minor);
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_proc.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_proc.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_proc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,334 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *    Keith Packard <keithp@keithp.com>
- *
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-static int i915_gem_active_info(char *buf, char **start, off_t offset,
-				int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("Active:\n");
-	list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
-			    list)
-	{
-		struct drm_gem_object *obj = obj_priv->obj;
-		if (obj->name) {
-			DRM_PROC_PRINT("    %p(%d): %08x %08x %d\n",
-				       obj, obj->name,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		} else {
-			DRM_PROC_PRINT("       %p: %08x %08x %d\n",
-				       obj,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		}
-	}
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("Flushing:\n");
-	list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
-			    list)
-	{
-		struct drm_gem_object *obj = obj_priv->obj;
-		if (obj->name) {
-			DRM_PROC_PRINT("    %p(%d): %08x %08x %d\n",
-				       obj, obj->name,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		} else {
-			DRM_PROC_PRINT("       %p: %08x %08x %d\n", obj,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		}
-	}
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("Inactive:\n");
-	list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
-			    list)
-	{
-		struct drm_gem_object *obj = obj_priv->obj;
-		if (obj->name) {
-			DRM_PROC_PRINT("    %p(%d): %08x %08x %d\n",
-				       obj, obj->name,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		} else {
-			DRM_PROC_PRINT("       %p: %08x %08x %d\n", obj,
-				       obj->read_domains, obj->write_domain,
-				       obj_priv->last_rendering_seqno);
-		}
-	}
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int i915_gem_request_info(char *buf, char **start, off_t offset,
-				 int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_request *gem_request;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("Request:\n");
-	list_for_each_entry(gem_request, &dev_priv->mm.request_list,
-			    list)
-	{
-		DRM_PROC_PRINT("    %d @ %d\n",
-			       gem_request->seqno,
-			       (int) (jiffies - gem_request->emitted_jiffies));
-	}
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
-			       int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	if (dev_priv->hw_status_page != NULL) {
-		DRM_PROC_PRINT("Current sequence: %d\n",
-			       i915_get_gem_seqno(dev));
-	} else {
-		DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
-	}
-	DRM_PROC_PRINT("Waiter sequence:  %d\n",
-		       dev_priv->mm.waiting_gem_seqno);
-	DRM_PROC_PRINT("IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-
-static int i915_interrupt_info(char *buf, char **start, off_t offset,
-			       int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int len = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	DRM_PROC_PRINT("Interrupt enable:    %08x\n",
-		       I915_READ(IER));
-	DRM_PROC_PRINT("Interrupt identity:  %08x\n",
-		       I915_READ(IIR));
-	DRM_PROC_PRINT("Interrupt mask:      %08x\n",
-		       I915_READ(IMR));
-	DRM_PROC_PRINT("Pipe A stat:         %08x\n",
-		       I915_READ(PIPEASTAT));
-	DRM_PROC_PRINT("Pipe B stat:         %08x\n",
-		       I915_READ(PIPEBSTAT));
-	DRM_PROC_PRINT("Interrupts received: %d\n",
-		       atomic_read(&dev_priv->irq_received));
-	if (dev_priv->hw_status_page != NULL) {
-		DRM_PROC_PRINT("Current sequence:    %d\n",
-			       i915_get_gem_seqno(dev));
-	} else {
-		DRM_PROC_PRINT("Current sequence:    hws uninitialized\n");
-	}
-	DRM_PROC_PRINT("Waiter sequence:     %d\n",
-		       dev_priv->mm.waiting_gem_seqno);
-	DRM_PROC_PRINT("IRQ sequence:        %d\n",
-		       dev_priv->mm.irq_gem_seqno);
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int i915_hws_info(char *buf, char **start, off_t offset,
-			 int request, int *eof, void *data)
-{
-	struct drm_minor *minor = (struct drm_minor *) data;
-	struct drm_device *dev = minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int len = 0, i;
-	volatile u32 *hws;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	hws = (volatile u32 *)dev_priv->hw_status_page;
-	if (hws == NULL) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof = 0;
-	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
-		DRM_PROC_PRINT("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
-			       i * 4,
-			       hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
-	}
-	if (len > request + offset)
-		return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static struct drm_proc_list {
-	/** file name */
-	const char *name;
-	/** proc callback*/
-	int (*f) (char *, char **, off_t, int, int *, void *);
-} i915_gem_proc_list[] = {
-	{"i915_gem_active", i915_gem_active_info},
-	{"i915_gem_flushing", i915_gem_flushing_info},
-	{"i915_gem_inactive", i915_gem_inactive_info},
-	{"i915_gem_request", i915_gem_request_info},
-	{"i915_gem_seqno", i915_gem_seqno_info},
-	{"i915_gem_interrupt", i915_interrupt_info},
-	{"i915_gem_hws", i915_hws_info},
-};
-
-#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
-
-int i915_gem_proc_init(struct drm_minor *minor)
-{
-	struct proc_dir_entry *ent;
-	int i, j;
-
-	for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
-		ent = create_proc_entry(i915_gem_proc_list[i].name,
-					S_IFREG | S_IRUGO, minor->dev_root);
-		if (!ent) {
-			DRM_ERROR("Cannot create /proc/dri/.../%s\n",
-				  i915_gem_proc_list[i].name);
-			for (j = 0; j < i; j++)
-				remove_proc_entry(i915_gem_proc_list[i].name,
-						  minor->dev_root);
-			return -1;
-		}
-		ent->read_proc = i915_gem_proc_list[i].f;
-		ent->data = minor;
-	}
-	return 0;
-}
-
-void i915_gem_proc_cleanup(struct drm_minor *minor)
-{
-	int i;
-
-	if (!minor->dev_root)
-		return;
-
-	for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
-		remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem_tiling.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,8 @@
  *
  */
 
+#include "linux/string.h"
+#include "linux/bitops.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -96,16 +98,16 @@ i915_gem_detect_bit_6_swizzle(struct drm
 		 */
 		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
 		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-	} else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) ||
-		   IS_GM45(dev)) {
+	} else if (IS_MOBILE(dev)) {
 		uint32_t dcc;
 
-		/* On 915-945 and GM965, channel interleave by the CPU is
-		 * determined by DCC.  The CPU will alternate based on bit 6
-		 * in interleaved mode, and the GPU will then also alternate
-		 * on bit 6, 9, and 10 for X, but the CPU may also optionally
-		 * alternate based on bit 17 (XOR not disabled and XOR
-		 * bit == 17).
+		/* On mobile 9xx chipsets, channel interleave by the CPU is
+		 * determined by DCC.  For single-channel, neither the CPU
+		 * nor the GPU do swizzling.  For dual channel interleaved,
+		 * the GPU's interleave is bit 9 and 10 for X tiled, and bit
+		 * 9 for Y tiled.  The CPU's interleave is independent, and
+		 * can be based on either bit 11 (haven't seen this yet) or
+		 * bit 17 (common).
 		 */
 		dcc = I915_READ(DCC);
 		switch (dcc & DCC_ADDRESSING_MODE_MASK) {
@@ -115,21 +117,20 @@ i915_gem_detect_bit_6_swizzle(struct drm
 			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
 			break;
 		case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
-			if (IS_I915G(dev) || IS_I915GM(dev) ||
-			    dcc & DCC_CHANNEL_XOR_DISABLE) {
+			if (dcc & DCC_CHANNEL_XOR_DISABLE) {
+				/* This is the base swizzling by the GPU for
+				 * tiled buffers.
+				 */
 				swizzle_x = I915_BIT_6_SWIZZLE_9_10;
 				swizzle_y = I915_BIT_6_SWIZZLE_9;
-			} else if ((IS_I965GM(dev) || IS_GM45(dev)) &&
-				   (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
-				/* GM965/GM45 does either bit 11 or bit 17
-				 * swizzling.
-				 */
+			} else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
+				/* Bit 11 swizzling by the CPU in addition. */
 				swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
 				swizzle_y = I915_BIT_6_SWIZZLE_9_11;
 			} else {
-				/* Bit 17 or perhaps other swizzling */
-				swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-				swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+				/* Bit 17 swizzling by the CPU in addition. */
+				swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
+				swizzle_y = I915_BIT_6_SWIZZLE_9_17;
 			}
 			break;
 		}
@@ -212,11 +213,35 @@ i915_tiling_ok(struct drm_device *dev, i
 	if (tiling_mode == I915_TILING_NONE)
 		return true;
 
-	if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+	if (!IS_I9XX(dev) ||
+	    (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
 		tile_width = 128;
 	else
 		tile_width = 512;
 
+	/* check maximum stride & object size */
+	if (IS_I965G(dev)) {
+		/* i965 stores the end address of the gtt mapping in the fence
+		 * reg, so dont bother to check the size */
+		if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
+			return false;
+	} else if (IS_I9XX(dev)) {
+		uint32_t pitch_val = ffs(stride / tile_width) - 1;
+
+		/* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
+		 * instead of 4 (2KB) on 945s.
+		 */
+		if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
+		    size > (I830_FENCE_MAX_SIZE_VAL << 20))
+			return false;
+	} else {
+		uint32_t pitch_val = ffs(stride / tile_width) - 1;
+
+		if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
+		    size > (I830_FENCE_MAX_SIZE_VAL << 19))
+			return false;
+	}
+
 	/* 965+ just needs multiples of tile width */
 	if (IS_I965G(dev)) {
 		if (stride & (tile_width - 1))
@@ -266,13 +291,25 @@ i915_gem_set_tiling(struct drm_device *d
 	mutex_lock(&dev->struct_mutex);
 
 	if (args->tiling_mode == I915_TILING_NONE) {
-		obj_priv->tiling_mode = I915_TILING_NONE;
 		args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
 	} else {
 		if (args->tiling_mode == I915_TILING_X)
 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
 		else
 			args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+
+		/* Hide bit 17 swizzling from the user.  This prevents old Mesa
+		 * from aborting the application on sw fallbacks to bit 17,
+		 * and we use the pread/pwrite bit17 paths to swizzle for it.
+		 * If there was a user that was relying on the swizzle
+		 * information for drm_intel_bo_map()ed reads/writes this would
+		 * break it, but we don't have any of those.
+		 */
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+			args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
 		/* If we can't handle the swizzling, make it untiled. */
 		if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
 			args->tiling_mode = I915_TILING_NONE;
@@ -339,8 +376,100 @@ i915_gem_get_tiling(struct drm_device *d
 		DRM_ERROR("unknown tiling mode\n");
 	}
 
+	/* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
+	if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
+		args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
+
 	drm_gem_object_unreference(obj);
 	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
 }
+
+/**
+ * Swap every 64 bytes of this page around, to account for it having a new
+ * bit 17 of its physical address and therefore being interpreted differently
+ * by the GPU.
+ */
+static int
+i915_gem_swizzle_page(struct page *page)
+{
+	char *vaddr;
+	int i;
+	char temp[64];
+
+	vaddr = kmap(page);
+	if (vaddr == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < PAGE_SIZE; i += 128) {
+		memcpy(temp, &vaddr[i], 64);
+		memcpy(&vaddr[i], &vaddr[i + 64], 64);
+		memcpy(&vaddr[i + 64], temp, 64);
+	}
+
+	kunmap(page);
+
+	return 0;
+}
+
+void
+i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	int page_count = obj->size >> PAGE_SHIFT;
+	int i;
+
+	if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
+		return;
+
+	if (obj_priv->bit_17 == NULL)
+		return;
+
+	for (i = 0; i < page_count; i++) {
+		char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17;
+		if ((new_bit_17 & 0x1) !=
+		    (test_bit(i, obj_priv->bit_17) != 0)) {
+			int ret = i915_gem_swizzle_page(obj_priv->pages[i]);
+			if (ret != 0) {
+				DRM_ERROR("Failed to swizzle page\n");
+				return;
+			}
+			set_page_dirty(obj_priv->pages[i]);
+		}
+	}
+}
+
+void
+i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	int page_count = obj->size >> PAGE_SHIFT;
+	int i;
+
+	if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17)
+		return;
+
+	if (obj_priv->bit_17 == NULL) {
+		obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) *
+					   sizeof(long), GFP_KERNEL);
+		if (obj_priv->bit_17 == NULL) {
+			DRM_ERROR("Failed to allocate memory for bit 17 "
+				  "record\n");
+			return;
+		}
+	}
+
+	for (i = 0; i < page_count; i++) {
+		if (page_to_phys(obj_priv->pages[i]) & (1 << 17))
+			__set_bit(i, obj_priv->bit_17);
+		else
+			__clear_bit(i, obj_priv->bit_17);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_irq.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,10 +48,6 @@
 /** Interrupts that we mask and unmask at runtime. */
 #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
 
-/** These are all of the interrupts used by the driver */
-#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
-				    I915_INTERRUPT_ENABLE_VAR)
-
 #define I915_PIPE_VBLANK_STATUS	(PIPE_START_VBLANK_INTERRUPT_STATUS |\
 				 PIPE_VBLANK_INTERRUPT_STATUS)
 
@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_d
 	return I915_READ(reg);
 }
 
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void i915_hotplug_work_func(struct work_struct *work)
+{
+	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+						    hotplug_work);
+	struct drm_device *dev = dev_priv->dev;
+
+	/* Just fire off a uevent and let userspace tell us what to do */
+	drm_sysfs_hotplug_event(dev);
+}
+
 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 		ret = IRQ_HANDLED;
 
+		/* Consume port.  Then clear IIR or we'll miss events */
+		if ((I915_HAS_HOTPLUG(dev)) &&
+		    (iir & I915_DISPLAY_PORT_INTERRUPT)) {
+			u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
+
+			DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+				  hotplug_status);
+			if (hotplug_status & dev_priv->hotplug_supported_mask)
+				schedule_work(&dev_priv->hotplug_work);
+
+			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+			I915_READ(PORT_HOTPLUG_STAT);
+		}
+
 		I915_WRITE(IIR, iir);
 		new_iir = I915_READ(IIR); /* Flush posted writes */
 
@@ -383,7 +406,7 @@ int i915_irq_emit(struct drm_device *dev
 	drm_i915_irq_emit_t *emit = data;
 	int result;
 
-	if (!dev_priv) {
+	if (!dev_priv || !dev_priv->ring.virtual_start) {
 		DRM_ERROR("called with no initialization\n");
 		return -EINVAL;
 	}
@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct d
 
 	atomic_set(&dev_priv->irq_received, 0);
 
+	if (I915_HAS_HOTPLUG(dev)) {
+		I915_WRITE(PORT_HOTPLUG_EN, 0);
+		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+	}
+
 	I915_WRITE(HWSTAM, 0xeffe);
 	I915_WRITE(PIPEASTAT, 0);
 	I915_WRITE(PIPEBSTAT, 0);
 	I915_WRITE(IMR, 0xffffffff);
 	I915_WRITE(IER, 0x0);
 	(void) I915_READ(IER);
+	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
 }
 
 int i915_driver_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct d
 	dev_priv->pipestat[0] = 0;
 	dev_priv->pipestat[1] = 0;
 
+	if (I915_HAS_HOTPLUG(dev)) {
+		u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+
+		/* Leave other bits alone */
+		hotplug_en |= HOTPLUG_EN_MASK;
+		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 */
+		i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
+	}
+
 	/* Disable pipe interrupt enables, clear pending pipe status */
 	I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
 	I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
 	/* Clear pending interrupt status */
 	I915_WRITE(IIR, I915_READ(IIR));
 
-	I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+	I915_WRITE(IER, enable_mask);
 	I915_WRITE(IMR, dev_priv->irq_mask_reg);
 	(void) I915_READ(IER);
 
@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct dr
 
 	dev_priv->vblank_pipe = 0;
 
+	if (I915_HAS_HOTPLUG(dev)) {
+		I915_WRITE(PORT_HOTPLUG_EN, 0);
+		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+	}
+
 	I915_WRITE(HWSTAM, 0xffffffff);
 	I915_WRITE(PIPEASTAT, 0);
 	I915_WRITE(PIPEBSTAT, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_opregion.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_opregion.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_opregion.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@
  */
 
 #include <linux/acpi.h>
+#include <acpi/video.h>
 
 #include "drmP.h"
 #include "i915_drm.h"
@@ -136,6 +137,12 @@ struct opregion_asle {
 
 #define ASLE_CBLV_VALID         (1<<31)
 
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
 static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@ static struct notifier_block intel_opreg
 	.notifier_call = intel_opregion_video_event,
 };
 
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_opregion *opregion = &dev_priv->opregion;
+	struct drm_connector *connector;
+	int i = 0;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		int output_type = ACPI_OTHER_OUTPUT;
+		if (i >= 8) {
+			dev_printk (KERN_ERR, &dev->pdev->dev,
+				    "More than 8 outputs detected\n");
+			return;
+		}
+		switch (connector->connector_type) {
+		case DRM_MODE_CONNECTOR_VGA:
+		case DRM_MODE_CONNECTOR_DVIA:
+			output_type = ACPI_VGA_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_Composite:
+		case DRM_MODE_CONNECTOR_SVIDEO:
+		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_9PinDIN:
+			output_type = ACPI_TV_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_DVII:
+		case DRM_MODE_CONNECTOR_DVID:
+		case DRM_MODE_CONNECTOR_DisplayPort:
+		case DRM_MODE_CONNECTOR_HDMIA:
+		case DRM_MODE_CONNECTOR_HDMIB:
+			output_type = ACPI_DIGITAL_OUTPUT;
+			break;
+		case DRM_MODE_CONNECTOR_LVDS:
+			output_type = ACPI_LVDS_OUTPUT;
+			break;
+		}
+		opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+		i++;
+	}
+
+	/* If fewer than 8 outputs, the list must be null terminated */
+	if (i < 8)
+		opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,8 @@ int intel_opregion_init(struct drm_devic
 	if (mboxes & MBOX_ACPI) {
 		DRM_DEBUG("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");
 		err = -ENOTSUPP;
@@ -326,8 +386,13 @@ int intel_opregion_init(struct drm_devic
 	if (mboxes & MBOX_ASLE) {
 		DRM_DEBUG("ASLE supported\n");
 		opregion->asle = base + OPREGION_ASLE_OFFSET;
+		opregion_enable_asle(dev);
 	}
 
+	if (!resume)
+		acpi_video_register();
+
+
 	/* Notify BIOS we are ready to handle ACPI video ext notifs.
 	 * Right now, all the events are handled by the ACPI video module.
 	 * We don't actually need to do anything with them. */
@@ -345,7 +410,7 @@ err_out:
 	return err;
 }
 
-void intel_opregion_free(struct drm_device *dev)
+void intel_opregion_free(struct drm_device *dev, int suspend)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
@@ -353,6 +418,9 @@ void intel_opregion_free(struct drm_devi
 	if (!opregion->enabled)
 		return;
 
+	if (!suspend)
+		acpi_video_exit();
+
 	opregion->acpi->drdy = 0;
 
 	system_opregion = NULL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_reg.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_reg.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -190,6 +190,9 @@
 #define   I830_FENCE_SIZE_BITS(size)	((ffs((size) >> 19) - 1) << 8)
 #define   I830_FENCE_PITCH_SHIFT	4
 #define   I830_FENCE_REG_VALID		(1<<0)
+#define   I915_FENCE_MAX_PITCH_VAL	0x10
+#define   I830_FENCE_MAX_PITCH_VAL	6
+#define   I830_FENCE_MAX_SIZE_VAL	(1<<8)
 
 #define   I915_FENCE_START_MASK		0x0ff00000
 #define   I915_FENCE_SIZE_BITS(size)	((ffs((size) >> 20) - 1) << 8)
@@ -198,6 +201,7 @@
 #define   I965_FENCE_PITCH_SHIFT	2
 #define   I965_FENCE_TILING_Y_SHIFT	1
 #define   I965_FENCE_REG_VALID		(1<<0)
+#define   I965_FENCE_MAX_PITCH_VAL	0x0400
 
 /*
  * Instruction and interrupt control regs
@@ -359,6 +363,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 I915_FIFO_UNDERRUN_STATUS		(1UL<<31)
 #define I915_CRC_ERROR_ENABLE			(1UL<<29)
@@ -435,6 +440,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
 /* i830, required in DVO non-gang */
 #define   PLL_P2_DIVIDE_BY_4		(1 << 23)
 #define   PLL_P1_DIVIDE_BY_TWO		(1 << 21) /* i830 */
@@ -501,10 +507,12 @@
 #define FPB0	0x06048
 #define FPB1	0x0604c
 #define   FP_N_DIV_MASK		0x003f0000
+#define   FP_N_IGD_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_DIV_SHIFT		 0
 #define DPLL_TEST	0x606c
 #define   DPLLB_TEST_SDVO_DIV_1		(0 << 22)
@@ -519,6 +527,7 @@
 #define   DPLLA_INPUT_BUFFER_ENABLE	(1 << 0)
 #define D_STATE		0x6104
 #define CG_2D_DIS	0x6200
+#define DPCUNIT_CLOCK_GATE_DISABLE	(1 << 24)
 #define CG_3D_DIS	0x6204
 
 /*
@@ -629,6 +638,30 @@
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
+/* must use period 64 on GM45 according to docs */
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_64	(1 << 8)
+#define CRT_HOTPLUG_DAC_ON_TIME_2M		(0 << 7)
+#define CRT_HOTPLUG_DAC_ON_TIME_4M		(1 << 7)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_40		(0 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_50		(1 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_60		(2 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_70		(3 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK	(3 << 5)
+#define CRT_HOTPLUG_DETECT_DELAY_1G		(0 << 4)
+#define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
+#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)
@@ -856,7 +889,7 @@
  */
 # define TV_ENC_C0_FIX			(1 << 10)
 /** Bits that must be preserved by software */
-# define TV_CTL_SAVE			((3 << 8) | (3 << 6))
+# define TV_CTL_SAVE			((1 << 11) | (3 << 9) | (7 << 6) | 0xf)
 # define TV_FUSE_STATE_MASK		(3 << 4)
 /** Read-only state that reports all features enabled */
 # define TV_FUSE_STATE_ENABLED		(0 << 4)
@@ -1378,9 +1411,25 @@
 
 /* Cursor A & B regs */
 #define CURACNTR		0x70080
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define   CURSOR_ENABLE		0x80000000
+#define   CURSOR_GAMMA_ENABLE	0x40000000
+#define   CURSOR_STRIDE_MASK	0x30000000
+#define   CURSOR_FORMAT_SHIFT	24
+#define   CURSOR_FORMAT_MASK	(0x07 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_2C	(0x00 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_3C	(0x01 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_4C	(0x02 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_ARGB	(0x04 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_XRGB	(0x05 << CURSOR_FORMAT_SHIFT)
+/* New style CUR*CNTR flags */
+#define   CURSOR_MODE		0x27
 #define   CURSOR_MODE_DISABLE   0x00
 #define   CURSOR_MODE_64_32B_AX 0x07
 #define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_PIPE_SELECT	(1 << 28)
+#define   MCURSOR_PIPE_A	0x00
+#define   MCURSOR_PIPE_B	(1 << 28)
 #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
 #define CURABASE		0x70084
 #define CURAPOS			0x70088
@@ -1388,6 +1437,7 @@
 #define   CURSOR_POS_SIGN       0x8000
 #define   CURSOR_X_SHIFT        0
 #define   CURSOR_Y_SHIFT        16
+#define CURSIZE			0x700a0
 #define CURBCNTR		0x700c0
 #define CURBBASE		0x700c4
 #define CURBPOS			0x700c8
@@ -1415,6 +1465,7 @@
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+#define   DISPPLANE_TILED			(1<<10)
 #define DSPAADDR		0x70184
 #define DSPASTRIDE		0x70188
 #define DSPAPOS			0x7018C /* reserved */
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_suspend.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2009-06-09 23:05:27.000000000 -0400
@@ -349,6 +349,18 @@ int i915_save_state(struct drm_device *d
 	for (i = 0; i < 3; i++)
 		dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
 
+	/* Fences */
+	if (IS_I965G(dev)) {
+		for (i = 0; i < 16; i++)
+			dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
+	} else {
+		for (i = 0; i < 8; i++)
+			dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
+
+		if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+			for (i = 0; i < 8; i++)
+				dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
+	}
 	i915_save_vga(dev);
 
 	return 0;
@@ -371,6 +383,18 @@ int i915_restore_state(struct drm_device
 	/* Display arbitration */
 	I915_WRITE(DSPARB, dev_priv->saveDSPARB);
 
+	/* Fences */
+	if (IS_I965G(dev)) {
+		for (i = 0; i < 16; i++)
+			I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
+	} else {
+		for (i = 0; i < 8; i++)
+			I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+		if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+			for (i = 0; i < 8; i++)
+				I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
+	}
+
 	/* Pipe & plane A info */
 	/* Prime the clock */
 	if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_bios.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_bios.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,9 +57,43 @@ find_section(struct bdb_header *bdb, int
 	return NULL;
 }
 
-/* Try to find panel data */
 static void
-parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
+fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+			struct lvds_dvo_timing *dvo_timing)
+{
+	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
+		dvo_timing->hactive_lo;
+	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
+		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
+	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
+		dvo_timing->hsync_pulse_width;
+	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
+		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+
+	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
+		dvo_timing->vactive_lo;
+	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
+		dvo_timing->vsync_off;
+	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
+		dvo_timing->vsync_pulse_width;
+	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
+		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
+	panel_fixed_mode->clock = dvo_timing->clock * 10;
+	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+
+	/* Some VBTs have bogus h/vtotal values */
+	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
+	drm_mode_set_name(panel_fixed_mode);
+}
+
+/* Try to find integrated panel data */
+static void
+parse_lfp_panel_data(struct drm_i915_private *dev_priv,
+			    struct bdb_header *bdb)
 {
 	struct bdb_lvds_options *lvds_options;
 	struct bdb_lvds_lfp_data *lvds_lfp_data;
@@ -91,38 +125,45 @@ parse_panel_data(struct drm_i915_private
 	panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
 				      DRM_MEM_DRIVER);
 
-	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
-		dvo_timing->hactive_lo;
-	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
-		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
-	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
-		dvo_timing->hsync_pulse_width;
-	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
-		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+	fill_detail_timing_data(panel_fixed_mode, dvo_timing);
 
-	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
-		dvo_timing->vactive_lo;
-	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
-		dvo_timing->vsync_off;
-	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
-		dvo_timing->vsync_pulse_width;
-	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
-		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
-	panel_fixed_mode->clock = dvo_timing->clock * 10;
-	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
-	/* Some VBTs have bogus h/vtotal values */
-	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
-		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
-	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
-		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+	drm_mode_debug_printmodeline(panel_fixed_mode);
 
-	drm_mode_set_name(panel_fixed_mode);
+	return;
+}
 
-	dev_priv->vbt_mode = panel_fixed_mode;
+/* Try to find sdvo panel data */
+static void
+parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
+		      struct bdb_header *bdb)
+{
+	struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+	struct lvds_dvo_timing *dvo_timing;
+	struct drm_display_mode *panel_fixed_mode;
 
-	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
-	drm_mode_debug_printmodeline(panel_fixed_mode);
+	dev_priv->sdvo_lvds_vbt_mode = NULL;
+
+	sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+	if (!sdvo_lvds_options)
+		return;
+
+	dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+	if (!dvo_timing)
+		return;
+
+	panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
+				      DRM_MEM_DRIVER);
+
+	if (!panel_fixed_mode)
+		return;
+
+	fill_detail_timing_data(panel_fixed_mode,
+			dvo_timing + sdvo_lvds_options->panel_type);
+
+	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
 
 	return;
 }
@@ -199,7 +240,8 @@ intel_init_bios(struct drm_device *dev)
 
 	/* Grab useful general definitions */
 	parse_general_features(dev_priv, bdb);
-	parse_panel_data(dev_priv, bdb);
+	parse_lfp_panel_data(dev_priv, bdb);
+	parse_sdvo_panel_data(dev_priv, bdb);
 
 	pci_unmap_rom(pdev, bios);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_bios.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_bios.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.h	2009-06-09 23:05:27.000000000 -0400
@@ -162,13 +162,13 @@ struct bdb_lvds_options {
 	u8 panel_type;
 	u8 rsvd1;
 	/* LVDS capabilities, stored in a dword */
-	u8 rsvd2:1;
-	u8 lvds_edid:1;
-	u8 pixel_dither:1;
-	u8 pfit_ratio_auto:1;
-	u8 pfit_gfx_mode_enhanced:1;
-	u8 pfit_text_mode_enhanced:1;
 	u8 pfit_mode:2;
+	u8 pfit_text_mode_enhanced:1;
+	u8 pfit_gfx_mode_enhanced:1;
+	u8 pfit_ratio_auto:1;
+	u8 pixel_dither:1;
+	u8 lvds_edid:1;
+	u8 rsvd2:1;
 	u8 rsvd4;
 } __attribute__((packed));
 
@@ -279,6 +279,23 @@ struct vch_bdb_22 {
 	struct vch_panel_data panels[16];
 } __attribute__((packed));
 
+struct bdb_sdvo_lvds_options {
+	u8 panel_backlight;
+	u8 h40_set_panel_type;
+	u8 panel_type;
+	u8 ssc_clk_freq;
+	u16 als_low_trip;
+	u16 als_high_trip;
+	u8 sclalarcoeff_tab_row_num;
+	u8 sclalarcoeff_tab_row_size;
+	u8 coefficient[8];
+	u8 panel_misc_bits_1;
+	u8 panel_misc_bits_2;
+	u8 panel_misc_bits_3;
+	u8 panel_misc_bits_4;
+} __attribute__((packed));
+
+
 bool intel_init_bios(struct drm_device *dev);
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_crt.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_crt.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_crt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_crt.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_en
 
 	temp = I915_READ(ADPA);
 	temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
-	temp &= ~ADPA_DAC_ENABLE;
+	temp |= ADPA_DAC_ENABLE;
 
 	switch(mode) {
 	case DRM_MODE_DPMS_ON:
@@ -64,11 +64,21 @@ static void intel_crt_dpms(struct drm_en
 static int intel_crt_mode_valid(struct drm_connector *connector,
 				struct drm_display_mode *mode)
 {
+	struct drm_device *dev = connector->dev;
+
+	int max_clock = 0;
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
 
-	if (mode->clock > 400000 || mode->clock < 25000)
-		return MODE_CLOCK_RANGE;
+	if (mode->clock < 25000)
+		return MODE_CLOCK_LOW;
+
+	if (!IS_I9XX(dev))
+		max_clock = 350000;
+	else
+		max_clock = 400000;
+	if (mode->clock > max_clock)
+		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
 }
@@ -113,10 +123,13 @@ static void intel_crt_mode_set(struct dr
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
 		adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 
-	if (intel_crtc->pipe == 0)
+	if (intel_crtc->pipe == 0) {
 		adpa |= ADPA_PIPE_A_SELECT;
-	else
+		I915_WRITE(BCLRPAT_A, 0);
+	} else {
 		adpa |= ADPA_PIPE_B_SELECT;
+		I915_WRITE(BCLRPAT_B, 0);
+	}
 
 	I915_WRITE(ADPA, adpa);
 }
@@ -133,20 +146,39 @@ static bool intel_crt_detect_hotplug(str
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 temp;
+	u32 hotplug_en;
+	int i, tries = 0;
+	/*
+	 * On 4 series desktop, CRT detect sequence need to be done twice
+	 * to get a reliable result.
+	 */
 
-	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+	if (IS_G4X(dev) && !IS_GM45(dev))
+		tries = 2;
+	else
+		tries = 1;
+	hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+	hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
+	hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
 
-	temp = I915_READ(PORT_HOTPLUG_EN);
+	if (IS_G4X(dev))
+		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
 
-	I915_WRITE(PORT_HOTPLUG_EN,
-		   temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
+	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
 
-	do {
-		if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT))
-			break;
-		msleep(1);
-	} while (time_after(timeout, jiffies));
+	for (i = 0; i < tries ; i++) {
+		unsigned long timeout;
+		/* turn on the FORCE_DETECT */
+		I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+		timeout = jiffies + msecs_to_jiffies(1000);
+		/* wait for FORCE_DETECT to go off */
+		do {
+			if (!(I915_READ(PORT_HOTPLUG_EN) &
+					CRT_HOTPLUG_FORCE_DETECT))
+				break;
+			msleep(1);
+		} while (time_after(timeout, jiffies));
+	}
 
 	if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
 	    CRT_HOTPLUG_MONITOR_COLOR)
@@ -166,9 +198,142 @@ static bool intel_crt_detect_ddc(struct
 	return intel_ddc_probe(intel_output);
 }
 
+static enum drm_connector_status
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+{
+	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pipe = intel_crtc->pipe;
+	uint32_t save_bclrpat;
+	uint32_t save_vtotal;
+	uint32_t vtotal, vactive;
+	uint32_t vsample;
+	uint32_t vblank, vblank_start, vblank_end;
+	uint32_t dsl;
+	uint32_t bclrpat_reg;
+	uint32_t vtotal_reg;
+	uint32_t vblank_reg;
+	uint32_t vsync_reg;
+	uint32_t pipeconf_reg;
+	uint32_t pipe_dsl_reg;
+	uint8_t	st00;
+	enum drm_connector_status status;
+
+	if (pipe == 0) {
+		bclrpat_reg = BCLRPAT_A;
+		vtotal_reg = VTOTAL_A;
+		vblank_reg = VBLANK_A;
+		vsync_reg = VSYNC_A;
+		pipeconf_reg = PIPEACONF;
+		pipe_dsl_reg = PIPEADSL;
+	} else {
+		bclrpat_reg = BCLRPAT_B;
+		vtotal_reg = VTOTAL_B;
+		vblank_reg = VBLANK_B;
+		vsync_reg = VSYNC_B;
+		pipeconf_reg = PIPEBCONF;
+		pipe_dsl_reg = PIPEBDSL;
+	}
+
+	save_bclrpat = I915_READ(bclrpat_reg);
+	save_vtotal = I915_READ(vtotal_reg);
+	vblank = I915_READ(vblank_reg);
+
+	vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
+	vactive = (save_vtotal & 0x7ff) + 1;
+
+	vblank_start = (vblank & 0xfff) + 1;
+	vblank_end = ((vblank >> 16) & 0xfff) + 1;
+
+	/* Set the border color to purple. */
+	I915_WRITE(bclrpat_reg, 0x500050);
+
+	if (IS_I9XX(dev)) {
+		uint32_t pipeconf = I915_READ(pipeconf_reg);
+		I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+		/* Wait for next Vblank to substitue
+		 * border color for Color info */
+		intel_wait_for_vblank(dev);
+		st00 = I915_READ8(VGA_MSR_WRITE);
+		status = ((st00 & (1 << 4)) != 0) ?
+			connector_status_connected :
+			connector_status_disconnected;
+
+		I915_WRITE(pipeconf_reg, pipeconf);
+	} else {
+		bool restore_vblank = false;
+		int count, detect;
+
+		/*
+		* If there isn't any border, add some.
+		* Yes, this will flicker
+		*/
+		if (vblank_start <= vactive && vblank_end >= vtotal) {
+			uint32_t vsync = I915_READ(vsync_reg);
+			uint32_t vsync_start = (vsync & 0xffff) + 1;
+
+			vblank_start = vsync_start;
+			I915_WRITE(vblank_reg,
+				   (vblank_start - 1) |
+				   ((vblank_end - 1) << 16));
+			restore_vblank = true;
+		}
+		/* sample in the vertical border, selecting the larger one */
+		if (vblank_start - vactive >= vtotal - vblank_end)
+			vsample = (vblank_start + vactive) >> 1;
+		else
+			vsample = (vtotal + vblank_end) >> 1;
+
+		/*
+		 * Wait for the border to be displayed
+		 */
+		while (I915_READ(pipe_dsl_reg) >= vactive)
+			;
+		while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample)
+			;
+		/*
+		 * Watch ST00 for an entire scanline
+		 */
+		detect = 0;
+		count = 0;
+		do {
+			count++;
+			/* Read the ST00 VGA status register */
+			st00 = I915_READ8(VGA_MSR_WRITE);
+			if (st00 & (1 << 4))
+				detect++;
+		} while ((I915_READ(pipe_dsl_reg) == dsl));
+
+		/* restore vblank if necessary */
+		if (restore_vblank)
+			I915_WRITE(vblank_reg, vblank);
+		/*
+		 * If more than 3/4 of the scanline detected a monitor,
+		 * then it is assumed to be present. This works even on i830,
+		 * where there isn't any way to force the border color across
+		 * the screen
+		 */
+		status = detect * 4 > count * 3 ?
+			 connector_status_connected :
+			 connector_status_disconnected;
+	}
+
+	/* Restore previous settings */
+	I915_WRITE(bclrpat_reg, save_bclrpat);
+
+	return status;
+}
+
 static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_crtc *crtc;
+	int dpms_mode;
+	enum drm_connector_status status;
 
 	if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
 		if (intel_crt_detect_hotplug(connector))
@@ -180,8 +345,20 @@ static enum drm_connector_status intel_c
 	if (intel_crt_detect_ddc(connector))
 		return connector_status_connected;
 
-	/* TODO use load detect */
-	return connector_status_unknown;
+	/* for pre-945g platforms use load detect */
+	if (encoder->crtc && encoder->crtc->enabled) {
+		status = intel_crt_load_detect(encoder->crtc, intel_output);
+	} else {
+		crtc = intel_get_load_detect_pipe(intel_output,
+						  NULL, &dpms_mode);
+		if (crtc) {
+			status = intel_crt_load_detect(crtc, intel_output);
+			intel_release_load_detect_pipe(intel_output, dpms_mode);
+		} else
+			status = connector_status_unknown;
+	}
+
+	return status;
 }
 
 static void intel_crt_destroy(struct drm_connector *connector)
@@ -204,11 +381,6 @@ static int intel_crt_set_property(struct
 				  struct drm_property *property,
 				  uint64_t value)
 {
-	struct drm_device *dev = connector->dev;
-
-	if (property == dev->mode_config.dpms_property && connector->encoder)
-		intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));
-
 	return 0;
 }
 
@@ -225,6 +397,7 @@ static const struct drm_encoder_helper_f
 };
 
 static const struct drm_connector_funcs intel_crt_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.detect = intel_crt_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = intel_crt_destroy,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_display.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_display.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_display.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,11 +56,13 @@ typedef struct {
 } intel_p2_t;
 
 #define INTEL_P2_NUM		      2
-
-typedef struct {
+typedef struct intel_limit intel_limit_t;
+struct intel_limit {
     intel_range_t   dot, vco, n, m, m1, m2, p, p1;
     intel_p2_t	    p2;
-} intel_limit_t;
+    bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
+		      int, int, intel_clock_t *);
+};
 
 #define I8XX_DOT_MIN		  25000
 #define I8XX_DOT_MAX		 350000
@@ -90,18 +92,32 @@ typedef struct {
 #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 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
 #define I9XX_M_MIN		     70
 #define I9XX_M_MAX		    120
+#define IGD_M_MIN		      2
+#define IGD_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
 #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 I9XX_P1_MIN		      1
 #define I9XX_P1_MAX		      8
 #define I9XX_P2_SDVO_DAC_SLOW		     10
@@ -115,6 +131,97 @@ typedef struct {
 #define INTEL_LIMIT_I8XX_LVDS	    1
 #define INTEL_LIMIT_I9XX_SDVO_DAC   2
 #define INTEL_LIMIT_I9XX_LVDS	    3
+#define INTEL_LIMIT_G4X_SDVO	    4
+#define INTEL_LIMIT_G4X_HDMI_DAC   5
+#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS   6
+#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS   7
+#define INTEL_LIMIT_IGD_SDVO_DAC    8
+#define INTEL_LIMIT_IGD_LVDS	    9
+
+/*The parameter is for SDVO on G4x platform*/
+#define G4X_DOT_SDVO_MIN           25000
+#define G4X_DOT_SDVO_MAX           270000
+#define G4X_VCO_MIN                1750000
+#define G4X_VCO_MAX                3500000
+#define G4X_N_SDVO_MIN             1
+#define G4X_N_SDVO_MAX             4
+#define G4X_M_SDVO_MIN             104
+#define G4X_M_SDVO_MAX             138
+#define G4X_M1_SDVO_MIN            17
+#define G4X_M1_SDVO_MAX            23
+#define G4X_M2_SDVO_MIN            5
+#define G4X_M2_SDVO_MAX            11
+#define G4X_P_SDVO_MIN             10
+#define G4X_P_SDVO_MAX             30
+#define G4X_P1_SDVO_MIN            1
+#define G4X_P1_SDVO_MAX            3
+#define G4X_P2_SDVO_SLOW           10
+#define G4X_P2_SDVO_FAST           10
+#define G4X_P2_SDVO_LIMIT          270000
+
+/*The parameter is for HDMI_DAC on G4x platform*/
+#define G4X_DOT_HDMI_DAC_MIN           22000
+#define G4X_DOT_HDMI_DAC_MAX           400000
+#define G4X_N_HDMI_DAC_MIN             1
+#define G4X_N_HDMI_DAC_MAX             4
+#define G4X_M_HDMI_DAC_MIN             104
+#define G4X_M_HDMI_DAC_MAX             138
+#define G4X_M1_HDMI_DAC_MIN            16
+#define G4X_M1_HDMI_DAC_MAX            23
+#define G4X_M2_HDMI_DAC_MIN            5
+#define G4X_M2_HDMI_DAC_MAX            11
+#define G4X_P_HDMI_DAC_MIN             5
+#define G4X_P_HDMI_DAC_MAX             80
+#define G4X_P1_HDMI_DAC_MIN            1
+#define G4X_P1_HDMI_DAC_MAX            8
+#define G4X_P2_HDMI_DAC_SLOW           10
+#define G4X_P2_HDMI_DAC_FAST           5
+#define G4X_P2_HDMI_DAC_LIMIT          165000
+
+/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN           20000
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX           115000
+#define G4X_N_SINGLE_CHANNEL_LVDS_MIN             1
+#define G4X_N_SINGLE_CHANNEL_LVDS_MAX             3
+#define G4X_M_SINGLE_CHANNEL_LVDS_MIN             104
+#define G4X_M_SINGLE_CHANNEL_LVDS_MAX             138
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN            17
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX            23
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN            5
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX            11
+#define G4X_P_SINGLE_CHANNEL_LVDS_MIN             28
+#define G4X_P_SINGLE_CHANNEL_LVDS_MAX             112
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN            2
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX            8
+#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW           14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST           14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT          0
+
+/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN           80000
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX           224000
+#define G4X_N_DUAL_CHANNEL_LVDS_MIN             1
+#define G4X_N_DUAL_CHANNEL_LVDS_MAX             3
+#define G4X_M_DUAL_CHANNEL_LVDS_MIN             104
+#define G4X_M_DUAL_CHANNEL_LVDS_MAX             138
+#define G4X_M1_DUAL_CHANNEL_LVDS_MIN            17
+#define G4X_M1_DUAL_CHANNEL_LVDS_MAX            23
+#define G4X_M2_DUAL_CHANNEL_LVDS_MIN            5
+#define G4X_M2_DUAL_CHANNEL_LVDS_MAX            11
+#define G4X_P_DUAL_CHANNEL_LVDS_MIN             14
+#define G4X_P_DUAL_CHANNEL_LVDS_MAX             42
+#define G4X_P1_DUAL_CHANNEL_LVDS_MIN            2
+#define G4X_P1_DUAL_CHANNEL_LVDS_MAX            6
+#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW           7
+#define G4X_P2_DUAL_CHANNEL_LVDS_FAST           7
+#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT          0
+
+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_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			int target, int refclk, intel_clock_t *best_clock);
 
 static const intel_limit_t intel_limits[] = {
     { /* INTEL_LIMIT_I8XX_DVO_DAC */
@@ -128,6 +235,7 @@ static const intel_limit_t intel_limits[
         .p1  = { .min = I8XX_P1_MIN,		.max = I8XX_P1_MAX },
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
+	.find_pll = intel_find_best_PLL,
     },
     { /* INTEL_LIMIT_I8XX_LVDS */
         .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
@@ -140,6 +248,7 @@ static const intel_limit_t intel_limits[
         .p1  = { .min = I8XX_P1_LVDS_MIN,	.max = I8XX_P1_LVDS_MAX },
 	.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,
     },
     { /* INTEL_LIMIT_I9XX_SDVO_DAC */
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
@@ -152,6 +261,7 @@ static const intel_limit_t intel_limits[
         .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,
     },
     { /* INTEL_LIMIT_I9XX_LVDS */
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
@@ -167,19 +277,159 @@ 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,
+    },
+    /* below parameter and function is for G4X Chipset Family*/
+    { /* INTEL_LIMIT_G4X_SDVO */
+	.dot = { .min = G4X_DOT_SDVO_MIN,	.max = G4X_DOT_SDVO_MAX },
+	.vco = { .min = G4X_VCO_MIN,	        .max = G4X_VCO_MAX},
+	.n   = { .min = G4X_N_SDVO_MIN,	        .max = G4X_N_SDVO_MAX },
+	.m   = { .min = G4X_M_SDVO_MIN,         .max = G4X_M_SDVO_MAX },
+	.m1  = { .min = G4X_M1_SDVO_MIN,	.max = G4X_M1_SDVO_MAX },
+	.m2  = { .min = G4X_M2_SDVO_MIN,	.max = G4X_M2_SDVO_MAX },
+	.p   = { .min = G4X_P_SDVO_MIN,         .max = G4X_P_SDVO_MAX },
+	.p1  = { .min = G4X_P1_SDVO_MIN,	.max = G4X_P1_SDVO_MAX},
+	.p2  = { .dot_limit = G4X_P2_SDVO_LIMIT,
+		 .p2_slow = G4X_P2_SDVO_SLOW,
+		 .p2_fast = G4X_P2_SDVO_FAST
+	},
+	.find_pll = intel_g4x_find_best_PLL,
+    },
+    { /* INTEL_LIMIT_G4X_HDMI_DAC */
+	.dot = { .min = G4X_DOT_HDMI_DAC_MIN,	.max = G4X_DOT_HDMI_DAC_MAX },
+	.vco = { .min = G4X_VCO_MIN,	        .max = G4X_VCO_MAX},
+	.n   = { .min = G4X_N_HDMI_DAC_MIN,	.max = G4X_N_HDMI_DAC_MAX },
+	.m   = { .min = G4X_M_HDMI_DAC_MIN,	.max = G4X_M_HDMI_DAC_MAX },
+	.m1  = { .min = G4X_M1_HDMI_DAC_MIN,	.max = G4X_M1_HDMI_DAC_MAX },
+	.m2  = { .min = G4X_M2_HDMI_DAC_MIN,	.max = G4X_M2_HDMI_DAC_MAX },
+	.p   = { .min = G4X_P_HDMI_DAC_MIN,	.max = G4X_P_HDMI_DAC_MAX },
+	.p1  = { .min = G4X_P1_HDMI_DAC_MIN,	.max = G4X_P1_HDMI_DAC_MAX},
+	.p2  = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
+		 .p2_slow = G4X_P2_HDMI_DAC_SLOW,
+		 .p2_fast = G4X_P2_HDMI_DAC_FAST
+	},
+	.find_pll = intel_g4x_find_best_PLL,
+    },
+    { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */
+	.dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX },
+	.vco = { .min = G4X_VCO_MIN,
+		 .max = G4X_VCO_MAX },
+	.n   = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX },
+	.m   = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX },
+	.m1  = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX },
+	.m2  = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX },
+	.p   = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX },
+	.p1  = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN,
+		 .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX },
+	.p2  = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT,
+		 .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW,
+		 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
+	},
+	.find_pll = intel_g4x_find_best_PLL,
+    },
+    { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */
+	.dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX },
+	.vco = { .min = G4X_VCO_MIN,
+		 .max = G4X_VCO_MAX },
+	.n   = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_N_DUAL_CHANNEL_LVDS_MAX },
+	.m   = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_M_DUAL_CHANNEL_LVDS_MAX },
+	.m1  = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX },
+	.m2  = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX },
+	.p   = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_P_DUAL_CHANNEL_LVDS_MAX },
+	.p1  = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN,
+		 .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX },
+	.p2  = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT,
+		 .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW,
+		 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
+	},
+	.find_pll = intel_g4x_find_best_PLL,
+    },
+    { /* INTEL_LIMIT_IGD_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 },
+        .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,
+    },
+    { /* INTEL_LIMIT_IGD_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 },
+        .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
+	/* IGD 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,
     },
+
 };
 
+static const intel_limit_t *intel_g4x_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)) {
+		if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+		    LVDS_CLKB_POWER_UP)
+			/* LVDS with dual channel */
+			limit = &intel_limits
+					[INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS];
+		else
+			/* LVDS with dual channel */
+			limit = &intel_limits
+					[INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS];
+	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
+		   intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
+		limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
+	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
+		limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
+	} else /* The option is for other outputs */
+		limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+
+	return limit;
+}
+
 static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	const intel_limit_t *limit;
 
-	if (IS_I9XX(dev)) {
+	if (IS_G4X(dev)) {
+		limit = intel_g4x_limit(crtc);
+	} else if (IS_I9XX(dev) && !IS_IGD(dev)) {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
 		else
 			limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+	} else if (IS_IGD(dev)) {
+		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
+			limit = &intel_limits[INTEL_LIMIT_IGD_LVDS];
+		else
+			limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC];
 	} else {
 		if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
@@ -189,8 +439,21 @@ static const intel_limit_t *intel_limit(
 	return limit;
 }
 
-static void intel_clock(int refclk, intel_clock_t *clock)
+/* m1 is reserved as 0 in IGD, n is a ring counter */
+static void igd_clock(int refclk, intel_clock_t *clock)
 {
+	clock->m = clock->m2 + 2;
+	clock->p = clock->p1 * clock->p2;
+	clock->vco = refclk * clock->m / clock->n;
+	clock->dot = clock->vco / clock->p;
+}
+
+static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
+{
+	if (IS_IGD(dev)) {
+		igd_clock(refclk, clock);
+		return;
+	}
 	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
 	clock->p = clock->p1 * clock->p2;
 	clock->vco = refclk * clock->m / (clock->n + 2);
@@ -226,6 +489,7 @@ bool intel_pipe_has_type (struct drm_crt
 static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
 {
 	const intel_limit_t *limit = intel_limit (crtc);
+	struct drm_device *dev = crtc->dev;
 
 	if (clock->p1  < limit->p1.min  || limit->p1.max  < clock->p1)
 		INTELPllInvalid ("p1 out of range\n");
@@ -235,7 +499,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)
+	if (clock->m1 <= clock->m2 && !IS_IGD(dev))
 		INTELPllInvalid ("m1 <= m2\n");
 	if (clock->m   < limit->m.min   || limit->m.max   < clock->m)
 		INTELPllInvalid ("m out of range\n");
@@ -252,18 +516,14 @@ static bool intel_PLL_is_valid(struct dr
 	return true;
 }
 
-/**
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE.  The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
-static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
-				int refclk, intel_clock_t *best_clock)
+static bool
+intel_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;
-	const intel_limit_t *limit = intel_limit(crtc);
 	int err = target;
 
 	if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
@@ -289,15 +549,17 @@ static bool intel_find_best_PLL(struct d
 	memset (best_clock, 0, sizeof (*best_clock));
 
 	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
-		for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
-			     clock.m2 <= limit->m2.max; clock.m2++) {
+		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.p1 = limit->p1.min;
 				     clock.p1 <= limit->p1.max; clock.p1++) {
 					int this_err;
 
-					intel_clock(refclk, &clock);
+					intel_clock(dev, refclk, &clock);
 
 					if (!intel_PLL_is_valid(crtc, &clock))
 						continue;
@@ -315,11 +577,68 @@ static bool intel_find_best_PLL(struct d
 	return (err != target);
 }
 
+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)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	intel_clock_t clock;
+	int max_n;
+	bool found;
+	/* approximately equals target * 0.00488 */
+	int err_most = (target >> 8) + (target >> 10);
+	found = false;
+
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+		if ((I915_READ(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));
+	max_n = limit->n.max;
+	/* based on hardware requriment prefer smaller n to precision */
+	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+		/* based on hardware requirment prefere larger m1,m2, p1 */
+		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--) {
+				for (clock.p1 = limit->p1.max;
+				     clock.p1 >= limit->p1.min; clock.p1--) {
+					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_most) {
+						*best_clock = clock;
+						err_most = this_err;
+						max_n = clock.n;
+						found = true;
+					}
+				}
+			}
+		}
+	}
+
+	return found;
+}
+
 void
 intel_wait_for_vblank(struct drm_device *dev)
 {
 	/* Wait for 20ms, i.e. one cycle at 50hz. */
-	udelay(20000);
+	mdelay(20);
 }
 
 static int
@@ -338,6 +657,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 	int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
 	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+	int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
 	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 	u32 dspcntr, alignment;
 	int ret;
@@ -414,6 +734,13 @@ intel_pipe_set_base(struct drm_crtc *crt
 		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
+	if (IS_I965G(dev)) {
+		if (obj_priv->tiling_mode != I915_TILING_NONE)
+			dspcntr |= DISPPLANE_TILED;
+		else
+			dspcntr &= ~DISPPLANE_TILED;
+	}
+
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	Start = obj_priv->gtt_offset;
@@ -426,6 +753,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 		I915_READ(dspbase);
 		I915_WRITE(dspsurf, Start);
 		I915_READ(dspsurf);
+		I915_WRITE(dsptileoff, (y << 16) | x);
 	} else {
 		I915_WRITE(dspbase, Start + Offset);
 		I915_READ(dspbase);
@@ -634,7 +962,7 @@ static int intel_get_core_clock_speed(st
 		return 400000;
 	else if (IS_I915G(dev))
 		return 333000;
-	else if (IS_I945GM(dev) || IS_845G(dev))
+	else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
 		return 200000;
 	else if (IS_I915GM(dev)) {
 		u16 gcfgc = 0;
@@ -733,6 +1061,7 @@ static int intel_crtc_mode_set(struct dr
 	bool is_crt = false, is_lvds = false, is_tv = false;
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
+	const intel_limit_t *limit;
 	int ret;
 
 	drm_vblank_pre_modeset(dev, pipe);
@@ -776,13 +1105,42 @@ static int intel_crtc_mode_set(struct dr
 		refclk = 48000;
 	}
 
-	ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
+	/*
+	 * Returns a set of divisors for the desired target clock with the given
+	 * refclk, or FALSE.  The returned values represent the clock equation:
+	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+	 */
+	limit = intel_limit(crtc);
+	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
 		return -EINVAL;
 	}
 
-	fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+	/* SDVO TV has fixed PLL values depend on its clock range,
+	   this mirrors vbios setting. */
+	if (is_sdvo && is_tv) {
+		if (adjusted_mode->clock >= 100000
+				&& adjusted_mode->clock < 140500) {
+			clock.p1 = 2;
+			clock.p2 = 10;
+			clock.n = 3;
+			clock.m1 = 16;
+			clock.m2 = 8;
+		} else if (adjusted_mode->clock >= 140500
+				&& adjusted_mode->clock <= 200000) {
+			clock.p1 = 1;
+			clock.p2 = 10;
+			clock.n = 6;
+			clock.m1 = 12;
+			clock.m2 = 8;
+		}
+	}
+
+	if (IS_IGD(dev))
+		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
+	else
+		fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
 
 	dpll = DPLL_VGA_MODE_DIS;
 	if (IS_I9XX(dev)) {
@@ -799,7 +1157,10 @@ static int intel_crtc_mode_set(struct dr
 		}
 
 		/* compute bitmask from p1 value */
-		dpll |= (1 << (clock.p1 - 1)) << 16;
+		if (IS_IGD(dev))
+			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+		else
+			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 		switch (clock.p2) {
 		case 5:
 			dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
@@ -996,7 +1357,7 @@ static int intel_crtc_cursor_set(struct
 	int pipe = intel_crtc->pipe;
 	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
 	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-	uint32_t temp;
+	uint32_t temp = I915_READ(control);
 	size_t addr;
 	int ret;
 
@@ -1005,7 +1366,12 @@ static int intel_crtc_cursor_set(struct
 	/* if we want to turn off the cursor ignore width and height */
 	if (!handle) {
 		DRM_DEBUG("cursor off\n");
-		temp = CURSOR_MODE_DISABLE;
+		if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+			temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
+			temp |= CURSOR_MODE_DISABLE;
+		} else {
+			temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
+		}
 		addr = 0;
 		bo = NULL;
 		mutex_lock(&dev->struct_mutex);
@@ -1048,10 +1414,19 @@ static int intel_crtc_cursor_set(struct
 		addr = obj_priv->phys_obj->handle->busaddr;
 	}
 
-	temp = 0;
-	/* set the pipe for the cursor */
-	temp |= (pipe << 28);
-	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+	if (!IS_I9XX(dev))
+		I915_WRITE(CURSIZE, (height << 12) | width);
+
+	/* Hooray for CUR*CNTR differences */
+	if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+		temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+		temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+		temp |= (pipe << 28); /* Connect to correct pipe */
+	} else {
+		temp &= ~(CURSOR_FORMAT_MASK);
+		temp |= CURSOR_ENABLE;
+		temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+	}
 
  finish:
 	I915_WRITE(control, temp);
@@ -1279,10 +1654,20 @@ 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;
-	clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
-	clock.n = (fp & FP_N_DIV_MASK) >> FP_N_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;
+	} 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)) {
-		clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+		if (IS_IGD(dev))
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
+				DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+		else
+			clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
 			       DPLL_FPA01_P1_POST_DIV_SHIFT);
 
 		switch (dpll & DPLL_MODE_MASK) {
@@ -1301,7 +1686,7 @@ static int intel_crtc_clock_get(struct d
 		}
 
 		/* XXX: Handle the 100Mhz refclk */
-		intel_clock(96000, &clock);
+		intel_clock(dev, 96000, &clock);
 	} else {
 		bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
 
@@ -1313,9 +1698,9 @@ static int intel_crtc_clock_get(struct d
 			if ((dpll & PLL_REF_INPUT_MASK) ==
 			    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
 				/* XXX: might not be 66MHz */
-				intel_clock(66000, &clock);
+				intel_clock(dev, 66000, &clock);
 			} else
-				intel_clock(48000, &clock);
+				intel_clock(dev, 48000, &clock);
 		} else {
 			if (dpll & PLL_P1_DIVIDE_BY_TWO)
 				clock.p1 = 2;
@@ -1328,7 +1713,7 @@ static int intel_crtc_clock_get(struct d
 			else
 				clock.p2 = 2;
 
-			intel_clock(48000, &clock);
+			intel_clock(dev, 48000, &clock);
 		}
 	}
 
@@ -1433,6 +1818,37 @@ static void intel_crtc_init(struct drm_d
 	}
 }
 
+int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
+	struct drm_crtc *crtc = NULL;
+	int pipe = -1;
+
+	if (!dev_priv) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
+			pipe = intel_crtc->pipe;
+			break;
+		}
+	}
+
+	if (pipe == -1) {
+		DRM_ERROR("no such CRTC id\n");
+		return -EINVAL;
+	}
+
+	pipe_from_crtc_id->pipe = pipe;
+
+       return 0;
+}
+
 struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
 {
 	struct drm_crtc *crtc = NULL;
@@ -1474,13 +1890,21 @@ static void intel_setup_outputs(struct d
 
 	if (IS_I9XX(dev)) {
 		int found;
+		u32 reg;
 
 		if (I915_READ(SDVOB) & SDVO_DETECTED) {
 			found = intel_sdvo_init(dev, SDVOB);
 			if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
 				intel_hdmi_init(dev, SDVOB);
 		}
-		if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) {
+
+		/* Before G4X SDVOC doesn't have its own detect register */
+		if (IS_G4X(dev))
+			reg = SDVOC;
+		else
+			reg = SDVOB;
+
+		if (I915_READ(reg) & SDVO_DETECTED) {
 			found = intel_sdvo_init(dev, SDVOC);
 			if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
 				intel_hdmi_init(dev, SDVOC);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -109,7 +109,7 @@ struct intel_i2c_chan *intel_i2c_create(
 void intel_i2c_destroy(struct intel_i2c_chan *chan);
 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);
 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);
@@ -125,6 +125,8 @@ extern struct drm_encoder *intel_best_en
 
 extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 						    struct drm_crtc *crtc);
+int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
+				struct drm_file *file_priv);
 extern void intel_wait_for_vblank(struct drm_device *dev);
 extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
 extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_dvo.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_dvo.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_dvo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_dvo.c	2009-06-09 23:05:27.000000000 -0400
@@ -316,6 +316,7 @@ static const struct drm_encoder_helper_f
 };
 
 static const struct drm_connector_funcs intel_dvo_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.save = intel_dvo_save,
 	.restore = intel_dvo_restore,
 	.detect = intel_dvo_detect,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_fb.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_fb.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_fb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_fb.c	2009-06-09 23:05:27.000000000 -0400
@@ -864,8 +864,8 @@ static void intelfb_sysrq(int dummy1, st
 
 static struct sysrq_key_op sysrq_intelfb_restore_op = {
         .handler = intelfb_sysrq,
-        .help_msg = "force fb",
-        .action_msg = "force restore of fb console",
+        .help_msg = "force-fb(V)",
+        .action_msg = "Restore framebuffer console",
 };
 
 int intelfb_probe(struct drm_device *dev)
@@ -898,7 +898,7 @@ int intelfb_probe(struct drm_device *dev
 		ret = intelfb_single_fb_probe(dev);
 	}
 
-	register_sysrq_key('g', &sysrq_intelfb_restore_op);
+	register_sysrq_key('v', &sysrq_intelfb_restore_op);
 
 	return ret;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_hdmi.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_hdmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@
 struct intel_hdmi_priv {
 	u32 sdvox_reg;
 	u32 save_SDVOX;
-	int has_hdmi_sink;
+	bool has_hdmi_sink;
 };
 
 static void intel_hdmi_mode_set(struct drm_encoder *encoder,
@@ -128,6 +128,22 @@ static bool intel_hdmi_mode_fixup(struct
 	return true;
 }
 
+static void
+intel_hdmi_sink_detect(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct edid *edid = NULL;
+
+	edid = drm_get_edid(&intel_output->base,
+			    &intel_output->ddc_bus->adapter);
+	if (edid != NULL) {
+		hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+		kfree(edid);
+		intel_output->base.display_info.raw_edid = NULL;
+	}
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
@@ -139,11 +155,18 @@ intel_hdmi_detect(struct drm_connector *
 
 	temp = I915_READ(PORT_HOTPLUG_EN);
 
-	I915_WRITE(PORT_HOTPLUG_EN,
-		   temp |
-		   HDMIB_HOTPLUG_INT_EN |
-		   HDMIC_HOTPLUG_INT_EN |
-		   HDMID_HOTPLUG_INT_EN);
+	switch (hdmi_priv->sdvox_reg) {
+	case SDVOB:
+		temp |= HDMIB_HOTPLUG_INT_EN;
+		break;
+	case SDVOC:
+		temp |= HDMIC_HOTPLUG_INT_EN;
+		break;
+	default:
+		return connector_status_unknown;
+	}
+
+	I915_WRITE(PORT_HOTPLUG_EN, temp);
 
 	POSTING_READ(PORT_HOTPLUG_EN);
 
@@ -158,9 +181,10 @@ intel_hdmi_detect(struct drm_connector *
 		return connector_status_unknown;
 	}
 
-	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0)
+	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) {
+		intel_hdmi_sink_detect(connector);
 		return connector_status_connected;
-	else
+	} else
 		return connector_status_disconnected;
 }
 
@@ -195,6 +219,7 @@ static const struct drm_encoder_helper_f
 };
 
 static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.save = intel_hdmi_save,
 	.restore = intel_hdmi_restore,
 	.detect = intel_hdmi_detect,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_i2c.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_i2c.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,21 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
+{
+	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))
+		return;
+	if (enable)
+		I915_WRITE(CG_2D_DIS,
+			I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
+	else
+		I915_WRITE(CG_2D_DIS,
+			I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE));
+}
+
 /*
  * Intel GPIO access functions
  */
@@ -153,8 +168,10 @@ struct intel_i2c_chan *intel_i2c_create(
 		goto out_free;
 
 	/* JJJ:  raise SCL and SDA? */
+	intel_i2c_quirk_set(dev, true);
 	set_data(chan, 1);
 	set_clock(chan, 1);
+	intel_i2c_quirk_set(dev, false);
 	udelay(20);
 
 	return chan;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_lvds.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2009-06-09 23:05:27.000000000 -0400
@@ -265,7 +265,7 @@ static void intel_lvds_mode_set(struct d
 		pfit_control = 0;
 
 	if (!IS_I965G(dev)) {
-		if (dev_priv->panel_wants_dither)
+		if (dev_priv->panel_wants_dither || dev_priv->lvds_dither)
 			pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 	}
 	else
@@ -343,11 +343,6 @@ static int intel_lvds_set_property(struc
 				   struct drm_property *property,
 				   uint64_t value)
 {
-	struct drm_device *dev = connector->dev;
-
-	if (property == dev->mode_config.dpms_property && connector->encoder)
-		intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
-
 	return 0;
 }
 
@@ -366,6 +361,7 @@ static const struct drm_connector_helper
 };
 
 static const struct drm_connector_funcs intel_lvds_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.save = intel_lvds_save,
 	.restore = intel_lvds_restore,
 	.detect = intel_lvds_detect,
@@ -384,7 +380,51 @@ static const struct drm_encoder_funcs in
 	.destroy = intel_lvds_enc_destroy,
 };
 
+static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
+{
+	DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident);
+	return 1;
+}
+
+/* These systems claim to have LVDS, but really don't */
+static const struct dmi_system_id intel_no_lvds[] = {
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Apple Mac Mini (Core series)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Apple Mac Mini (Core 2 series)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "MSI IM-945GSE-A",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Dell Studio Hybrid",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
+		},
+	},
+
+	/* FIXME: add a check for the Aopen Mini PC */
 
+	{ }	/* terminating entry */
+};
 
 /**
  * intel_lvds_init - setup LVDS connectors on this device
@@ -404,15 +444,9 @@ void intel_lvds_init(struct drm_device *
 	u32 lvds;
 	int pipe;
 
-	/* Blacklist machines that we know falsely report LVDS. */
-	/* FIXME: add a check for the Aopen Mini PC */
-
-	/* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */
-	if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") ||
-	   dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) {
-		DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n");
+	/* Skip init on machines we know falsely report LVDS */
+	if (dmi_check_system(intel_no_lvds))
 		return;
-	}
 
 	intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
 	if (!intel_output) {
@@ -473,10 +507,10 @@ void intel_lvds_init(struct drm_device *
 	}
 
 	/* Failed to get EDID, what about VBT? */
-	if (dev_priv->vbt_mode) {
+	if (dev_priv->lfp_lvds_vbt_mode) {
 		mutex_lock(&dev->mode_config.mutex);
 		dev_priv->panel_fixed_mode =
-			drm_mode_duplicate(dev, dev_priv->vbt_mode);
+			drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
 		mutex_unlock(&dev->mode_config.mutex);
 		if (dev_priv->panel_fixed_mode) {
 			dev_priv->panel_fixed_mode->type |=
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_modes.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_modes.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_modes.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_modes.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/fb.h>
 #include "drmP.h"
 #include "intel_drv.h"
+#include "i915_drv.h"
 
 /**
  * intel_ddc_probe
@@ -52,7 +53,10 @@ bool intel_ddc_probe(struct intel_output
 		}
 	};
 
+	intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
 	ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2);
+	intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
+
 	if (ret == 2)
 		return true;
 
@@ -70,12 +74,15 @@ int intel_ddc_get_modes(struct intel_out
 	struct edid *edid;
 	int ret = 0;
 
+	intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
 	edid = drm_get_edid(&intel_output->base,
 			    &intel_output->ddc_bus->adapter);
+	intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
 	if (edid) {
 		drm_mode_connector_update_edid_property(&intel_output->base,
 							edid);
 		ret = drm_add_edid_modes(&intel_output->base, edid);
+		intel_output->base.display_info.raw_edid = NULL;
 		kfree(edid);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_sdvo.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_sdvo.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,6 +69,10 @@ struct intel_sdvo_priv {
 	 * This is set if we treat the device as HDMI, instead of DVI.
 	 */
 	bool is_hdmi;
+	/**
+	 * This is set if we detect output of sdvo device as LVDS.
+	 */
+	bool is_lvds;
 
 	/**
 	 * Returned SDTV resolutions allowed for the current format, if the
@@ -273,20 +277,20 @@ static void intel_sdvo_debug_write(struc
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 	int i;
 
-	DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
+	printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
 	for (i = 0; i < args_len; i++)
-		printk("%02X ", ((u8 *)args)[i]);
+		printk(KERN_DEBUG "%02X ", ((u8 *)args)[i]);
 	for (; i < 8; i++)
-		printk("   ");
+		printk(KERN_DEBUG "   ");
 	for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
 		if (cmd == sdvo_cmd_names[i].cmd) {
-			printk("(%s)", sdvo_cmd_names[i].name);
+			printk(KERN_DEBUG "(%s)", sdvo_cmd_names[i].name);
 			break;
 		}
 	}
 	if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
-		printk("(%02X)",cmd);
-	printk("\n");
+		printk(KERN_DEBUG "(%02X)", cmd);
+	printk(KERN_DEBUG "\n");
 }
 #else
 #define intel_sdvo_debug_write(o, c, a, l)
@@ -323,17 +327,18 @@ static void intel_sdvo_debug_response(st
 				      u8 status)
 {
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	int i;
 
-	DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
+	printk(KERN_DEBUG "%s: R: ", SDVO_NAME(sdvo_priv));
 	for (i = 0; i < response_len; i++)
-		printk("%02X ", ((u8 *)response)[i]);
+		printk(KERN_DEBUG "%02X ", ((u8 *)response)[i]);
 	for (; i < 8; i++)
-		printk("   ");
+		printk(KERN_DEBUG "   ");
 	if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
-		printk("(%s)", cmd_status_names[status]);
+		printk(KERN_DEBUG "(%s)", cmd_status_names[status]);
 	else
-		printk("(??? %d)", status);
-	printk("\n");
+		printk(KERN_DEBUG "(??? %d)", status);
+	printk(KERN_DEBUG "\n");
 }
 #else
 #define intel_sdvo_debug_response(o, r, l, s)
@@ -588,9 +593,12 @@ intel_sdvo_create_preferred_input_timing
 	struct intel_sdvo_preferred_input_timing_args args;
 	uint8_t status;
 
+	memset(&args, 0, sizeof(args));
 	args.clock = clock;
 	args.width = width;
 	args.height = height;
+	args.interlace = 0;
+	args.scaled = 0;
 	intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
 			     &args, sizeof(args));
 	status = intel_sdvo_read_response(output, NULL, 0);
@@ -683,7 +691,7 @@ static void intel_sdvo_get_dtd_from_mode
 	dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
 		((v_blank_len >> 8) & 0xf);
 
-	dtd->part2.h_sync_off = h_sync_offset;
+	dtd->part2.h_sync_off = h_sync_offset & 0xff;
 	dtd->part2.h_sync_width = h_sync_len & 0xff;
 	dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
 		(v_sync_len & 0xf);
@@ -705,27 +713,10 @@ static void intel_sdvo_get_dtd_from_mode
 static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
 					 struct intel_sdvo_dtd *dtd)
 {
-	uint16_t width, height;
-	uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
-	uint16_t h_sync_offset, v_sync_offset;
-
-	width = mode->crtc_hdisplay;
-	height = mode->crtc_vdisplay;
-
-	/* do some mode translations */
-	h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
-	h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-
-	v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
-	v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-
-	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
-	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
-
 	mode->hdisplay = dtd->part1.h_active;
 	mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
 	mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
-	mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2;
+	mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
 	mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
 	mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
 	mode->htotal = mode->hdisplay + dtd->part1.h_blank;
@@ -735,7 +726,7 @@ static void intel_sdvo_get_mode_from_dtd
 	mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
 	mode->vsync_start = mode->vdisplay;
 	mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
-	mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2;
+	mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
 	mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
 	mode->vsync_end = mode->vsync_start +
 		(dtd->part2.v_sync_off_width & 0xf);
@@ -745,7 +736,7 @@ static void intel_sdvo_get_mode_from_dtd
 
 	mode->clock = dtd->part1.clock * 10;
 
-	mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+	mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
 	if (dtd->part2.dtd_flags & 0x2)
 		mode->flags |= DRM_MODE_FLAG_PHSYNC;
 	if (dtd->part2.dtd_flags & 0x4)
@@ -924,6 +915,27 @@ static void intel_sdvo_set_avi_infoframe
 				SDVO_HBUF_TX_VSYNC);
 }
 
+static void intel_sdvo_set_tv_format(struct intel_output *output)
+{
+	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+	struct intel_sdvo_tv_format *format, unset;
+	u8 status;
+
+	format = &sdvo_priv->tv_format;
+	memset(&unset, 0, sizeof(unset));
+	if (memcmp(format, &unset, sizeof(*format))) {
+		DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
+				SDVO_NAME(sdvo_priv));
+		format->ntsc_m = 1;
+		intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
+				sizeof(*format));
+		status = intel_sdvo_read_response(output, NULL, 0);
+		if (status != SDVO_CMD_STATUS_SUCCESS)
+			DRM_DEBUG("%s: Failed to set TV format\n",
+					SDVO_NAME(sdvo_priv));
+	}
+}
+
 static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 				  struct drm_display_mode *mode,
 				  struct drm_display_mode *adjusted_mode)
@@ -968,6 +980,12 @@ static bool intel_sdvo_mode_fixup(struct
 							     &input_dtd);
 			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
 
+			drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+			mode->clock = adjusted_mode->clock;
+
+			adjusted_mode->clock *=
+				intel_sdvo_get_pixel_multiplier(mode);
 		} else {
 			return false;
 		}
@@ -1012,7 +1030,12 @@ static void intel_sdvo_mode_set(struct d
 		sdvox |= SDVO_AUDIO_ENABLE;
 	}
 
-	intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
+	/* We have tried to get input timing in mode_fixup, and filled into
+	   adjusted_mode */
+	if (sdvo_priv->is_tv)
+		intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+	else
+		intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
 
 	/* If it's a TV, we already set the output timing in mode_fixup.
 	 * Otherwise, the output timing is equal to the input timing.
@@ -1027,6 +1050,9 @@ static void intel_sdvo_mode_set(struct d
 	/* Set the input timing to the screen. Assume always input 0. */
 	intel_sdvo_set_target_input(output, true, false);
 
+	if (sdvo_priv->is_tv)
+		intel_sdvo_set_tv_format(output);
+
 	/* We would like to use intel_sdvo_create_preferred_input_timing() to
 	 * provide the device with a timing it can support, if it supports that
 	 * feature.  However, presumably we would need to adjust the CRTC to
@@ -1335,6 +1361,23 @@ void intel_sdvo_set_hotplug(struct drm_c
 	intel_sdvo_read_response(intel_output, &response, 2);
 }
 
+static void
+intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct edid *edid = NULL;
+
+	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+	edid = drm_get_edid(&intel_output->base,
+			    &intel_output->ddc_bus->adapter);
+	if (edid != NULL) {
+		sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
+		kfree(edid);
+		intel_output->base.display_info.raw_edid = NULL;
+	}
+}
+
 static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
 {
 	u8 response[2];
@@ -1349,19 +1392,18 @@ static enum drm_connector_status intel_s
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return connector_status_unknown;
 
-	if ((response[0] != 0) || (response[1] != 0))
+	if ((response[0] != 0) || (response[1] != 0)) {
+		intel_sdvo_hdmi_sink_detect(connector);
 		return connector_status_connected;
-	else
+	} else
 		return connector_status_disconnected;
 }
 
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 
 	/* set the bus switch and get the modes */
-	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
 	intel_ddc_get_modes(intel_output);
 
 #if 0
@@ -1395,7 +1437,7 @@ static void
 intel_sdvo_check_tv_format(struct intel_output *output)
 {
 	struct intel_sdvo_priv *dev_priv = output->dev_priv;
-	struct intel_sdvo_tv_format format, unset;
+	struct intel_sdvo_tv_format format;
 	uint8_t status;
 
 	intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
@@ -1403,15 +1445,7 @@ intel_sdvo_check_tv_format(struct intel_
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return;
 
-	memset(&unset, 0, sizeof(unset));
-	if (memcmp(&format, &unset, sizeof(format))) {
-		DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
-			  SDVO_NAME(dev_priv));
-
-		format.ntsc_m = true;
-		intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
-		status = intel_sdvo_read_response(output, NULL, 0);
-	}
+	memcpy(&dev_priv->tv_format, &format, sizeof(format));
 }
 
 /*
@@ -1420,68 +1454,70 @@ intel_sdvo_check_tv_format(struct intel_
  * XXX: all 60Hz refresh?
  */
 struct drm_display_mode sdvo_tv_modes[] = {
-	{ DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416,
-		   200, 0, 232, 201, 233, 4196112, 0,
+	{ DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
+		   416, 0, 200, 201, 232, 233, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416,
-		   240, 0, 272, 241, 273, 4196112, 0,
+	{ DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
+		   416, 0, 240, 241, 272, 273, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496,
-		   300, 0, 332, 301, 333, 4196112, 0,
+	{ DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
+		   496, 0, 300, 301, 332, 333, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736,
-		   350, 0, 382, 351, 383, 4196112, 0,
+	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
+		   736, 0, 350, 351, 382, 383, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
-		   400, 0, 432, 401, 433, 4196112, 0,
+	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
+		   736, 0, 400, 401, 432, 433, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
-		   400, 0, 432, 401, 433, 4196112, 0,
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
+		   736, 0, 480, 481, 512, 513, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800,
-		   480, 0, 512, 481, 513, 4196112, 0,
+	{ DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
+		   800, 0, 480, 481, 512, 513, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800,
-		   576, 0, 608, 577, 609, 4196112, 0,
+	{ DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
+		   800, 0, 576, 577, 608, 609, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816,
-		   350, 0, 382, 351, 383, 4196112, 0,
+	{ DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
+		   816, 0, 350, 351, 382, 383, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816,
-		   400, 0, 432, 401, 433, 4196112, 0,
+	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
+		   816, 0, 400, 401, 432, 433, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816,
-		   480, 0, 512, 481, 513, 4196112, 0,
+	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
+		   816, 0, 480, 481, 512, 513, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816,
-		   540, 0, 572, 541, 573, 4196112, 0,
+	{ DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
+		   816, 0, 540, 541, 572, 573, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816,
-		   576, 0, 608, 577, 609, 4196112, 0,
+	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
+		   816, 0, 576, 577, 608, 609, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864,
-		   576, 0, 608, 577, 609, 4196112, 0,
+	{ DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
+		   864, 0, 576, 577, 608, 609, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896,
-		   600, 0, 632, 601, 633, 4196112, 0,
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
+		   896, 0, 600, 601, 632, 633, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928,
-		   624, 0, 656, 625, 657, 4196112, 0,
+	{ DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
+		   928, 0, 624, 625, 656, 657, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016,
-		   766, 0, 798, 767, 799, 4196112, 0,
+	{ DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
+		   1016, 0, 766, 767, 798, 799, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120,
-		   768, 0, 800, 769, 801, 4196112, 0,
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
+		   1120, 0, 768, 769, 800, 801, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376,
-		   1024, 0, 1056, 1025, 1057, 4196112, 0,
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
+		   1376, 0, 1024, 1025, 1056, 1057, 0,
 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
 };
 
 static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 {
 	struct intel_output *output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+	struct intel_sdvo_sdtv_resolution_request tv_res;
 	uint32_t reply = 0;
 	uint8_t status;
 	int i = 0;
@@ -1491,15 +1527,53 @@ static void intel_sdvo_get_tv_modes(stru
 	/* Read the list of supported input resolutions for the selected TV
 	 * format.
 	 */
+	memset(&tv_res, 0, sizeof(tv_res));
+	memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
 	intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
-			     NULL, 0);
+			     &tv_res, sizeof(tv_res));
 	status = intel_sdvo_read_response(output, &reply, 3);
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
-		if (reply & (1 << i))
-			drm_mode_probed_add(connector, &sdvo_tv_modes[i]);
+		if (reply & (1 << i)) {
+			struct drm_display_mode *nmode;
+			nmode = drm_mode_duplicate(connector->dev,
+					&sdvo_tv_modes[i]);
+			if (nmode)
+				drm_mode_probed_add(connector, nmode);
+		}
+}
+
+static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+
+	/*
+	 * Attempt to get the mode list from DDC.
+	 * Assume that the preferred modes are
+	 * arranged in priority order.
+	 */
+	/* set the bus switch and get the modes */
+	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+	intel_ddc_get_modes(intel_output);
+	if (list_empty(&connector->probed_modes) == false)
+		return;
+
+	/* Fetch modes from VBT */
+	if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
+		struct drm_display_mode *newmode;
+		newmode = drm_mode_duplicate(connector->dev,
+					     dev_priv->sdvo_lvds_vbt_mode);
+		if (newmode != NULL) {
+			/* Guarantee the mode is preferred */
+			newmode->type = (DRM_MODE_TYPE_PREFERRED |
+					 DRM_MODE_TYPE_DRIVER);
+			drm_mode_probed_add(connector, newmode);
+		}
+	}
 }
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
@@ -1509,6 +1583,8 @@ static int intel_sdvo_get_modes(struct d
 
 	if (sdvo_priv->is_tv)
 		intel_sdvo_get_tv_modes(connector);
+	else if (sdvo_priv->is_lvds == true)
+		intel_sdvo_get_lvds_modes(connector);
 	else
 		intel_sdvo_get_ddc_modes(connector);
 
@@ -1523,6 +1599,9 @@ static void intel_sdvo_destroy(struct dr
 
 	if (intel_output->i2c_bus)
 		intel_i2c_destroy(intel_output->i2c_bus);
+	if (intel_output->ddc_bus)
+		intel_i2c_destroy(intel_output->ddc_bus);
+
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
 	kfree(intel_output);
@@ -1537,6 +1616,7 @@ static const struct drm_encoder_helper_f
 };
 
 static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.save = intel_sdvo_save,
 	.restore = intel_sdvo_restore,
 	.detect = intel_sdvo_detect,
@@ -1619,12 +1699,56 @@ intel_sdvo_get_digital_encoding_mode(str
 	return true;
 }
 
+static struct intel_output *
+intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+{
+	struct drm_device *dev = chan->drm_dev;
+	struct drm_connector *connector;
+	struct intel_output *intel_output = NULL;
+
+	list_for_each_entry(connector,
+			&dev->mode_config.connector_list, head) {
+		if (to_intel_output(connector)->ddc_bus == chan) {
+			intel_output = to_intel_output(connector);
+			break;
+		}
+	}
+	return intel_output;
+}
+
+static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
+				  struct i2c_msg msgs[], int num)
+{
+	struct intel_output *intel_output;
+	struct intel_sdvo_priv *sdvo_priv;
+	struct i2c_algo_bit_data *algo_data;
+	struct i2c_algorithm *algo;
+
+	algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
+	intel_output =
+		intel_sdvo_chan_to_intel_output(
+				(struct intel_i2c_chan *)(algo_data->data));
+	if (intel_output == NULL)
+		return -EINVAL;
+
+	sdvo_priv = intel_output->dev_priv;
+	algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo;
+
+	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+	return algo->master_xfer(i2c_adap, msgs, num);
+}
+
+static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
+	.master_xfer	= intel_sdvo_master_xfer,
+};
+
 bool intel_sdvo_init(struct drm_device *dev, int output_device)
 {
 	struct drm_connector *connector;
 	struct intel_output *intel_output;
 	struct intel_sdvo_priv *sdvo_priv;
 	struct intel_i2c_chan *i2cbus = NULL;
+	struct intel_i2c_chan *ddcbus = NULL;
 	int connector_type;
 	u8 ch[0x40];
 	int i;
@@ -1635,17 +1759,9 @@ bool intel_sdvo_init(struct drm_device *
 		return false;
 	}
 
-	connector = &intel_output->base;
-
-	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
-			   DRM_MODE_CONNECTOR_Unknown);
-	drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
 	sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
 	intel_output->type = INTEL_OUTPUT_SDVO;
 
-	connector->interlace_allowed = 0;
-	connector->doublescan_allowed = 0;
-
 	/* setup the DDC bus. */
 	if (output_device == SDVOB)
 		i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
@@ -1653,7 +1769,7 @@ bool intel_sdvo_init(struct drm_device *
 		i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
 	if (!i2cbus)
-		goto err_connector;
+		goto err_inteloutput;
 
 	sdvo_priv->i2c_bus = i2cbus;
 
@@ -1669,7 +1785,6 @@ bool intel_sdvo_init(struct drm_device *
 	intel_output->i2c_bus = i2cbus;
 	intel_output->dev_priv = sdvo_priv;
 
-
 	/* Read the regs to test if we can talk to the device */
 	for (i = 0; i < 0x40; i++) {
 		if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
@@ -1679,6 +1794,22 @@ bool intel_sdvo_init(struct drm_device *
 		}
 	}
 
+	/* setup the DDC bus. */
+	if (output_device == SDVOB)
+		ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+	else
+		ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+
+	if (ddcbus == NULL)
+		goto err_i2c;
+
+	intel_sdvo_i2c_bit_algo.functionality =
+		intel_output->i2c_bus->adapter.algo->functionality;
+	ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo;
+	intel_output->ddc_bus = ddcbus;
+
+	/* In defaut case sdvo lvds is false */
+	sdvo_priv->is_lvds = false;
 	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
 
 	if (sdvo_priv->caps.output_flags &
@@ -1688,7 +1819,6 @@ bool intel_sdvo_init(struct drm_device *
 		else
 			sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
 
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_TMDS;
 		connector_type = DRM_MODE_CONNECTOR_DVID;
 
@@ -1706,7 +1836,6 @@ bool intel_sdvo_init(struct drm_device *
 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
 	{
 		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_TVDAC;
 		connector_type = DRM_MODE_CONNECTOR_SVIDEO;
 		sdvo_priv->is_tv = true;
@@ -1715,30 +1844,28 @@ bool intel_sdvo_init(struct drm_device *
 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
 	{
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_DAC;
 		connector_type = DRM_MODE_CONNECTOR_VGA;
 	}
 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
 	{
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_DAC;
 		connector_type = DRM_MODE_CONNECTOR_VGA;
 	}
 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
 	{
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector_type = DRM_MODE_CONNECTOR_LVDS;
+		sdvo_priv->is_lvds = true;
 	}
 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
 	{
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
-		connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 		encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector_type = DRM_MODE_CONNECTOR_LVDS;
+		sdvo_priv->is_lvds = true;
 	}
 	else
 	{
@@ -1754,9 +1881,16 @@ bool intel_sdvo_init(struct drm_device *
 		goto err_i2c;
 	}
 
+	connector = &intel_output->base;
+	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
+			   connector_type);
+	drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+
 	drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
 	drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
-	connector->connector_type = connector_type;
 
 	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
 	drm_sysfs_connector_add(connector);
@@ -1788,14 +1922,13 @@ bool intel_sdvo_init(struct drm_device *
 		  sdvo_priv->caps.output_flags &
 			(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
 
-	intel_output->ddc_bus = i2cbus;
-
 	return true;
 
 err_i2c:
+	if (ddcbus != NULL)
+		intel_i2c_destroy(intel_output->ddc_bus);
 	intel_i2c_destroy(intel_output->i2c_bus);
-err_connector:
-	drm_connector_cleanup(connector);
+err_inteloutput:
 	kfree(intel_output);
 
 	return false;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_sdvo_regs.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_sdvo_regs.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_sdvo_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_sdvo_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing
     u16 clock;
     u16 width;
     u16 height;
+    u8	interlace:1;
+    u8	scaled:1;
+    u8	pad:6;
 } __attribute__((packed));
 
 /* I2C registers for SDVO */
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_tv.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_tv.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/intel_tv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_tv.c	2009-06-09 23:05:27.000000000 -0400
@@ -217,8 +217,8 @@ static const u32 filter_table[] = {
  */
 static const struct color_conversion ntsc_m_csc_composite = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
-	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
-	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
 };
 
 static const struct video_levels ntsc_m_levels_composite = {
@@ -226,9 +226,9 @@ static const struct video_levels ntsc_m_
 };
 
 static const struct color_conversion ntsc_m_csc_svideo = {
-	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
-	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
-	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
 };
 
 static const struct video_levels ntsc_m_levels_svideo = {
@@ -237,8 +237,8 @@ static const struct video_levels ntsc_m_
 
 static const struct color_conversion ntsc_j_csc_composite = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
-	.ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0f00,
-	.rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0f00,
+	.ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
+	.rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
 };
 
 static const struct video_levels ntsc_j_levels_composite = {
@@ -247,8 +247,8 @@ static const struct video_levels ntsc_j_
 
 static const struct color_conversion ntsc_j_csc_svideo = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
-	.ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0f00,
-	.rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0f00,
+	.ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
+	.rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
 };
 
 static const struct video_levels ntsc_j_levels_svideo = {
@@ -257,8 +257,8 @@ static const struct video_levels ntsc_j_
 
 static const struct color_conversion pal_csc_composite = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
-	.ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0f00,
-	.rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0f00,
+	.ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
+	.rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
 };
 
 static const struct video_levels pal_levels_composite = {
@@ -267,8 +267,8 @@ static const struct video_levels pal_lev
 
 static const struct color_conversion pal_csc_svideo = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
-	.ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0f00,
-	.rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0f00,
+	.ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
+	.rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
 };
 
 static const struct video_levels pal_levels_svideo = {
@@ -277,8 +277,8 @@ static const struct video_levels pal_lev
 
 static const struct color_conversion pal_m_csc_composite = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
-	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
-	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
 };
 
 static const struct video_levels pal_m_levels_composite = {
@@ -286,9 +286,9 @@ static const struct video_levels pal_m_l
 };
 
 static const struct color_conversion pal_m_csc_svideo = {
-	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
-	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
-	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
 };
 
 static const struct video_levels pal_m_levels_svideo = {
@@ -297,8 +297,8 @@ static const struct video_levels pal_m_l
 
 static const struct color_conversion pal_n_csc_composite = {
 	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
-	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
-	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+	.ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+	.rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
 };
 
 static const struct video_levels pal_n_levels_composite = {
@@ -306,9 +306,9 @@ static const struct video_levels pal_n_l
 };
 
 static const struct color_conversion pal_n_csc_svideo = {
-	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
-	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
-	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+	.ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+	.rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
 };
 
 static const struct video_levels pal_n_levels_svideo = {
@@ -319,9 +319,9 @@ static const struct video_levels pal_n_l
  * Component connections
  */
 static const struct color_conversion sdtv_csc_yprpb = {
-	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0146,
-	.ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0f00,
-	.rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0f00,
+	.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
+	.ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
+	.rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
 };
 
 static const struct color_conversion sdtv_csc_rgb = {
@@ -331,9 +331,9 @@ static const struct color_conversion sdt
 };
 
 static const struct color_conversion hdtv_csc_yprpb = {
-	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0146,
-	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0f00,
-	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0f00,
+	.ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
+	.ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
+	.rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
 };
 
 static const struct color_conversion hdtv_csc_rgb = {
@@ -414,7 +414,7 @@ struct tv_mode {
 static const struct tv_mode tv_modes[] = {
 	{
 		.name		= "NTSC-M",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 29970,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
@@ -442,8 +442,8 @@ static const struct tv_mode tv_modes[] =
 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
 
 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
-		.dda1_inc	=    136,
-		.dda2_inc	=   7624,	    .dda2_size		=  20013,
+		.dda1_inc	=    135,
+		.dda2_inc	=  20800,	    .dda2_size		=  27456,
 		.dda3_inc	=      0,	    .dda3_size		=      0,
 		.sc_reset	= TV_SC_RESET_EVERY_4,
 		.pal_burst	= false,
@@ -457,7 +457,7 @@ static const struct tv_mode tv_modes[] =
 	},
 	{
 		.name		= "NTSC-443",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 29970,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
@@ -485,10 +485,10 @@ static const struct tv_mode tv_modes[] =
 
 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
 		.dda1_inc       =    168,
-		.dda2_inc       =  18557,       .dda2_size      =  20625,
-		.dda3_inc       =      0,       .dda3_size      =      0,
-		.sc_reset   = TV_SC_RESET_EVERY_8,
-		.pal_burst  = true,
+		.dda2_inc       =   4093,       .dda2_size      =  27456,
+		.dda3_inc       =    310,       .dda3_size      =    525,
+		.sc_reset   = TV_SC_RESET_NEVER,
+		.pal_burst  = false,
 
 		.composite_levels = &ntsc_m_levels_composite,
 		.composite_color = &ntsc_m_csc_composite,
@@ -499,7 +499,7 @@ static const struct tv_mode tv_modes[] =
 	},
 	{
 		.name		= "NTSC-J",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 29970,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
@@ -527,8 +527,8 @@ static const struct tv_mode tv_modes[] =
 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
 
 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
-		.dda1_inc	=    136,
-		.dda2_inc	=   7624,	    .dda2_size		=  20013,
+		.dda1_inc	=    135,
+		.dda2_inc	=  20800,	    .dda2_size		=  27456,
 		.dda3_inc	=      0,	    .dda3_size		=      0,
 		.sc_reset	= TV_SC_RESET_EVERY_4,
 		.pal_burst	= false,
@@ -542,7 +542,7 @@ static const struct tv_mode tv_modes[] =
 	},
 	{
 		.name		= "PAL-M",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 29970,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
@@ -570,11 +570,11 @@ static const struct tv_mode tv_modes[] =
 		.vburst_start_f4 = 10,		    .vburst_end_f4	= 240,
 
 		/* desired 3.5800000 actual 3.5800000 clock 107.52 */
-		.dda1_inc	=    136,
-		.dda2_inc	=    7624,	    .dda2_size		=  20013,
+		.dda1_inc	=    135,
+		.dda2_inc	=  16704,	    .dda2_size		=  27456,
 		.dda3_inc	=      0,	    .dda3_size		=      0,
-		.sc_reset	= TV_SC_RESET_EVERY_4,
-		.pal_burst  = false,
+		.sc_reset	= TV_SC_RESET_EVERY_8,
+		.pal_burst  = true,
 
 		.composite_levels = &pal_m_levels_composite,
 		.composite_color = &pal_m_csc_composite,
@@ -586,7 +586,7 @@ static const struct tv_mode tv_modes[] =
 	{
 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
 		.name	    = "PAL-N",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 25000,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
@@ -615,9 +615,9 @@ static const struct tv_mode tv_modes[] =
 
 
 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
-		.dda1_inc       =    168,
-		.dda2_inc       =  18557,       .dda2_size      =  20625,
-		.dda3_inc       =      0,       .dda3_size      =      0,
+		.dda1_inc       =    135,
+		.dda2_inc       =  23578,       .dda2_size      =  27648,
+		.dda3_inc       =    134,       .dda3_size      =    625,
 		.sc_reset   = TV_SC_RESET_EVERY_8,
 		.pal_burst  = true,
 
@@ -631,12 +631,12 @@ static const struct tv_mode tv_modes[] =
 	{
 		/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
 		.name	    = "PAL",
-		.clock		= 107520,
+		.clock		= 108000,
 		.refresh	= 25000,
 		.oversample	= TV_OVERSAMPLE_8X,
 		.component_only = 0,
 
-		.hsync_end	= 64,		    .hblank_end		= 128,
+		.hsync_end	= 64,		    .hblank_end		= 142,
 		.hblank_start	= 844,	    .htotal		= 863,
 
 		.progressive	= false,    .trilevel_sync = false,
@@ -659,8 +659,8 @@ static const struct tv_mode tv_modes[] =
 
 		/* desired 4.4336180 actual 4.4336180 clock 107.52 */
 		.dda1_inc       =    168,
-		.dda2_inc       =  18557,       .dda2_size      =  20625,
-		.dda3_inc       =      0,       .dda3_size      =      0,
+		.dda2_inc       =   4122,       .dda2_size      =  27648,
+		.dda3_inc       =     67,       .dda3_size      =    625,
 		.sc_reset   = TV_SC_RESET_EVERY_8,
 		.pal_burst  = true,
 
@@ -689,7 +689,7 @@ static const struct tv_mode tv_modes[] =
 		.veq_ena        = false,
 
 		.vi_end_f1      = 44,               .vi_end_f2          = 44,
-		.nbr_end        = 496,
+		.nbr_end        = 479,
 
 		.burst_ena      = false,
 
@@ -713,7 +713,7 @@ static const struct tv_mode tv_modes[] =
 		.veq_ena        = false,
 
 		.vi_end_f1      = 44,               .vi_end_f2          = 44,
-		.nbr_end        = 496,
+		.nbr_end        = 479,
 
 		.burst_ena      = false,
 
@@ -876,7 +876,7 @@ static const struct tv_mode tv_modes[] =
 		.component_only = 1,
 
 		.hsync_end      = 88,               .hblank_end         = 235,
-		.hblank_start   = 2155,             .htotal             = 2200,
+		.hblank_start   = 2155,             .htotal             = 2201,
 
 		.progressive    = false, 	    .trilevel_sync = true,
 
@@ -1082,7 +1082,7 @@ intel_tv_mode_valid(struct drm_connector
 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
 
 	/* Ensure TV refresh is close to desired refresh */
-	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1)
+	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10)
 		return MODE_OK;
 	return MODE_CLOCK_RANGE;
 }
@@ -1135,7 +1135,8 @@ intel_tv_mode_set(struct drm_encoder *en
 	if (!tv_mode)
 		return;	/* can't happen (mode_prepare prevents this) */
 
-	tv_ctl = 0;
+	tv_ctl = I915_READ(TV_CTL);
+	tv_ctl &= TV_CTL_SAVE;
 
 	switch (tv_priv->type) {
 	default:
@@ -1215,7 +1216,6 @@ intel_tv_mode_set(struct drm_encoder *en
 	/* dda1 implies valid video levels */
 	if (tv_mode->dda1_inc) {
 		scctl1 |= TV_SC_DDA1_EN;
-		scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
 	}
 
 	if (tv_mode->dda2_inc)
@@ -1225,6 +1225,7 @@ intel_tv_mode_set(struct drm_encoder *en
 		scctl1 |= TV_SC_DDA3_EN;
 
 	scctl1 |= tv_mode->sc_reset;
+	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 |
@@ -1266,7 +1267,11 @@ intel_tv_mode_set(struct drm_encoder *en
 			   color_conversion->av);
 	}
 
-	I915_WRITE(TV_CLR_KNOBS, 0x00606000);
+	if (IS_I965G(dev))
+		I915_WRITE(TV_CLR_KNOBS, 0x00404000);
+	else
+		I915_WRITE(TV_CLR_KNOBS, 0x00606000);
+
 	if (video_levels)
 		I915_WRITE(TV_CLR_LEVEL,
 			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
@@ -1401,6 +1406,7 @@ intel_tv_detect_type (struct drm_crtc *c
 		tv_dac = I915_READ(TV_DAC);
 		I915_WRITE(TV_DAC, save_tv_dac);
 		I915_WRITE(TV_CTL, save_tv_ctl);
+		intel_wait_for_vblank(dev);
 	}
 	/*
 	 *  A B C
@@ -1451,7 +1457,7 @@ intel_tv_detect(struct drm_connector *co
 	mode = reported_modes[0];
 	drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
-	if (encoder->crtc) {
+	if (encoder->crtc && encoder->crtc->enabled) {
 		type = intel_tv_detect_type(encoder->crtc, intel_output);
 	} else {
 		crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
@@ -1462,6 +1468,8 @@ intel_tv_detect(struct drm_connector *co
 			type = -1;
 	}
 
+	tv_priv->type = type;
+
 	if (type < 0)
 		return connector_status_disconnected;
 
@@ -1495,7 +1503,8 @@ intel_tv_get_modes(struct drm_connector
 	struct drm_display_mode *mode_ptr;
 	struct intel_output *intel_output = to_intel_output(connector);
 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
-	int j;
+	int j, count = 0;
+	u64 tmp;
 
 	for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]);
 	     j++) {
@@ -1510,8 +1519,9 @@ intel_tv_get_modes(struct drm_connector
 					&& !tv_mode->component_only))
 			continue;
 
-		mode_ptr = drm_calloc(1, sizeof(struct drm_display_mode),
-				      DRM_MEM_DRIVER);
+		mode_ptr = drm_mode_create(connector->dev);
+		if (!mode_ptr)
+			continue;
 		strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
 
 		mode_ptr->hdisplay = hactive_s;
@@ -1528,15 +1538,17 @@ intel_tv_get_modes(struct drm_connector
 			mode_ptr->vsync_end = mode_ptr->vsync_start  + 1;
 		mode_ptr->vtotal = vactive_s + 33;
 
-		mode_ptr->clock = (int) (tv_mode->refresh *
-					 mode_ptr->vtotal *
-					 mode_ptr->htotal / 1000) / 1000;
+		tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
+		tmp *= mode_ptr->htotal;
+		tmp = div_u64(tmp, 1000000);
+		mode_ptr->clock = (int) tmp;
 
 		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
 		drm_mode_probed_add(connector, mode_ptr);
+		count++;
 	}
 
-	return 0;
+	return count;
 }
 
 static void
@@ -1558,33 +1570,49 @@ intel_tv_set_property(struct drm_connect
 	struct drm_device *dev = connector->dev;
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_crtc *crtc = encoder->crtc;
 	int ret = 0;
+	bool changed = false;
 
 	ret = drm_connector_property_set_value(connector, property, val);
 	if (ret < 0)
 		goto out;
 
-	if (property == dev->mode_config.tv_left_margin_property)
+	if (property == dev->mode_config.tv_left_margin_property &&
+		tv_priv->margin[TV_MARGIN_LEFT] != val) {
 		tv_priv->margin[TV_MARGIN_LEFT] = val;
-	else if (property == dev->mode_config.tv_right_margin_property)
+		changed = true;
+	} else if (property == dev->mode_config.tv_right_margin_property &&
+		tv_priv->margin[TV_MARGIN_RIGHT] != val) {
 		tv_priv->margin[TV_MARGIN_RIGHT] = val;
-	else if (property == dev->mode_config.tv_top_margin_property)
+		changed = true;
+	} else if (property == dev->mode_config.tv_top_margin_property &&
+		tv_priv->margin[TV_MARGIN_TOP] != val) {
 		tv_priv->margin[TV_MARGIN_TOP] = val;
-	else if (property == dev->mode_config.tv_bottom_margin_property)
+		changed = true;
+	} else if (property == dev->mode_config.tv_bottom_margin_property &&
+		tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
 		tv_priv->margin[TV_MARGIN_BOTTOM] = val;
-	else if (property == dev->mode_config.tv_mode_property) {
+		changed = true;
+	} else if (property == dev->mode_config.tv_mode_property) {
 		if (val >= NUM_TV_MODES) {
 			ret = -EINVAL;
 			goto out;
 		}
+		if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
+			goto out;
+
 		tv_priv->tv_format = tv_modes[val].name;
-		intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+		changed = true;
 	} else {
 		ret = -EINVAL;
 		goto out;
 	}
 
-	intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+	if (changed && crtc)
+		drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
+				crtc->y, crtc->fb);
 out:
 	return ret;
 }
@@ -1598,6 +1626,7 @@ static const struct drm_encoder_helper_f
 };
 
 static const struct drm_connector_funcs intel_tv_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
 	.save = intel_tv_save,
 	.restore = intel_tv_restore,
 	.detect = intel_tv_detect,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/Makefile linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/Makefile
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/i915/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq
           i915_suspend.o \
 	  i915_gem.o \
 	  i915_gem_debug.o \
-	  i915_gem_proc.o \
+	  i915_gem_debugfs.o \
 	  i915_gem_tiling.o \
 	  intel_display.o \
 	  intel_crt.o \
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/Kconfig linux-libre-2.6.30-gnu1/drivers/gpu/drm/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/Kconfig	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/Kconfig	2013-05-03 16:44:18.000000000 -0400
@@ -69,11 +69,18 @@ config DRM_I830
 	  will load the correct one.
 
 config DRM_I915
+	tristate "i915 driver"
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
 	select FB
-	tristate "i915 driver"
+	select FRAMEBUFFER_CONSOLE if !EMBEDDED
+	# i915 depends on ACPI_VIDEO when ACPI is enabled
+	# but for select to work, need to select ACPI_VIDEO's dependencies, ick
+	select VIDEO_OUTPUT_CONTROL if ACPI
+	select BACKLIGHT_CLASS_DEVICE if ACPI
+	select INPUT if ACPI
+	select ACPI_VIDEO if ACPI
 	help
 	  Choose this option if you have a system that has Intel 830M, 845G,
 	  852GM, 855GM 865G or 915G integrated graphics.  If M is selected, the
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/Makefile linux-libre-2.6.30-gnu1/drivers/gpu/drm/Makefile
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,8 @@ drm-y       :=	drm_auth.o drm_bufs.o drm
 		drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
 		drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
 		drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
-		drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o
+		drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \
+		drm_info.o drm_debugfs.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/mga/mga_dma.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/mga/mga_dma.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/mga/mga_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/mga/mga_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,8 +148,8 @@ void mga_do_dma_flush(drm_mga_private_t
 		primary->space = head - tail;
 	}
 
-	DRM_DEBUG("   head = 0x%06lx\n", head - dev_priv->primary->offset);
-	DRM_DEBUG("   tail = 0x%06lx\n", tail - dev_priv->primary->offset);
+	DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
+	DRM_DEBUG("   tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset));
 	DRM_DEBUG("  space = 0x%06x\n", primary->space);
 
 	mga_flush_write_combine();
@@ -187,7 +187,7 @@ void mga_do_dma_wrap_start(drm_mga_priva
 		primary->space = head - dev_priv->primary->offset;
 	}
 
-	DRM_DEBUG("   head = 0x%06lx\n", head - dev_priv->primary->offset);
+	DRM_DEBUG("   head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
 	DRM_DEBUG("   tail = 0x%06x\n", primary->tail);
 	DRM_DEBUG("   wrap = %d\n", primary->last_wrap);
 	DRM_DEBUG("  space = 0x%06x\n", primary->space);
@@ -239,7 +239,7 @@ static void mga_freelist_print(struct dr
 	for (entry = dev_priv->head->next; entry; entry = entry->next) {
 		DRM_INFO("   %p   idx=%2d  age=0x%x 0x%06lx\n",
 			 entry, entry->buf->idx, entry->age.head,
-			 entry->age.head - dev_priv->primary->offset);
+			 (unsigned long)(entry->age.head - dev_priv->primary->offset));
 	}
 	DRM_INFO("\n");
 }
@@ -340,10 +340,10 @@ static struct drm_buf *mga_freelist_get(
 
 	DRM_DEBUG("   tail=0x%06lx %d\n",
 		  tail->age.head ?
-		  tail->age.head - dev_priv->primary->offset : 0,
+		  (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0,
 		  tail->age.wrap);
 	DRM_DEBUG("   head=0x%06lx %d\n",
-		  head - dev_priv->primary->offset, wrap);
+		  (unsigned long)(head - dev_priv->primary->offset), wrap);
 
 	if (TEST_AGE(&tail->age, head, wrap)) {
 		prev = dev_priv->tail->prev;
@@ -366,8 +366,9 @@ int mga_freelist_put(struct drm_device *
 	drm_mga_freelist_t *head, *entry, *prev;
 
 	DRM_DEBUG("age=0x%06lx wrap=%d\n",
-		  buf_priv->list_entry->age.head -
-		  dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
+		  (unsigned long)(buf_priv->list_entry->age.head -
+				  dev_priv->primary->offset),
+		  buf_priv->list_entry->age.wrap);
 
 	entry = buf_priv->list_entry;
 	head = dev_priv->head;
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/mga/mga_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/mga/mga_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/mga/mga_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/mga/mga_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -113,8 +113,8 @@ typedef struct drm_mga_private {
 	 * \sa drm_mga_private_t::mmio
 	 */
 	/*@{ */
-	u32 mmio_base;		   /**< Bus address of base of MMIO. */
-	u32 mmio_size;		   /**< Size of the MMIO region. */
+	resource_size_t mmio_base;	   /**< Bus address of base of MMIO. */
+	resource_size_t mmio_size;	   /**< Size of the MMIO region. */
 	/*@} */
 
 	u32 clear_cmd;
@@ -317,8 +317,8 @@ do {									\
 		DRM_INFO( "\n" );					\
 		DRM_INFO( "   tail=0x%06x head=0x%06lx\n",		\
 			  dev_priv->prim.tail,				\
-			  MGA_READ( MGA_PRIMADDRESS ) -			\
-			  dev_priv->primary->offset );			\
+			  (unsigned long)(MGA_READ(MGA_PRIMADDRESS) -	\
+					  dev_priv->primary->offset));	\
 	}								\
 	if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) {		\
 		if ( dev_priv->prim.space <				\
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/r128/r128_cce.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/r128/r128_cce.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/r128/r128_cce.c	2013-05-03 18:00:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/r128/r128_cce.c	2013-05-03 16:44:09.000000000 -0400
@@ -462,9 +462,9 @@ static int r128_do_init_cce(struct drm_d
 
 #if __OS_HAS_AGP
 	if (!dev_priv->is_pci) {
-		drm_core_ioremap(dev_priv->cce_ring, dev);
-		drm_core_ioremap(dev_priv->ring_rptr, dev);
-		drm_core_ioremap(dev->agp_buffer_map, dev);
+		drm_core_ioremap_wc(dev_priv->cce_ring, dev);
+		drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+		drm_core_ioremap_wc(dev->agp_buffer_map, dev);
 		if (!dev_priv->cce_ring->handle ||
 		    !dev_priv->ring_rptr->handle ||
 		    !dev->agp_buffer_map->handle) {
@@ -476,11 +476,12 @@ static int r128_do_init_cce(struct drm_d
 	} else
 #endif
 	{
-		dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
+		dev_priv->cce_ring->handle =
+			(void *)(unsigned long)dev_priv->cce_ring->offset;
 		dev_priv->ring_rptr->handle =
-		    (void *)dev_priv->ring_rptr->offset;
+			(void *)(unsigned long)dev_priv->ring_rptr->offset;
 		dev->agp_buffer_map->handle =
-		    (void *)dev->agp_buffer_map->offset;
+			(void *)(unsigned long)dev->agp_buffer_map->offset;
 	}
 
 #if __OS_HAS_AGP
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/Makefile linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/Makefile
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 ccflags-y := -Iinclude/drm
-radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
+radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r300_cmdbuf.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,8 @@
 #include "radeon_drv.h"
 #include "r300_reg.h"
 
+#include <asm/unaligned.h>
+
 #define R300_SIMULTANEOUS_CLIPRECTS		4
 
 /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
@@ -205,6 +207,10 @@ void r300_init_reg_flags(struct drm_devi
 	ADD_RANGE(0x42C0, 2);
 	ADD_RANGE(R300_RS_CNTL_0, 2);
 
+	ADD_RANGE(R300_SU_REG_DEST, 1);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530)
+		ADD_RANGE(RV530_FG_ZBREG_DEST, 1);
+
 	ADD_RANGE(R300_SC_HYPERZ, 2);
 	ADD_RANGE(0x43E8, 1);
 
@@ -230,6 +236,7 @@ void r300_init_reg_flags(struct drm_devi
 	ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
 	ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
 	ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
+	ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */
 
 	ADD_RANGE(R300_TX_FILTER_0, 16);
 	ADD_RANGE(R300_TX_FILTER1_0, 16);
@@ -917,6 +924,7 @@ static int r300_scratch(drm_radeon_priva
 {
 	u32 *ref_age_base;
 	u32 i, buf_idx, h_pending;
+	u64 ptr_addr;
 	RING_LOCALS;
 
 	if (cmdbuf->bufsz <
@@ -930,7 +938,8 @@ static int r300_scratch(drm_radeon_priva
 
 	dev_priv->scratch_ages[header.scratch.reg]++;
 
-	ref_age_base =  (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
+	ptr_addr = get_unaligned((u64 *)cmdbuf->buf);
+	ref_age_base = (u32 *)(unsigned long)ptr_addr;
 
 	cmdbuf->buf += sizeof(u64);
 	cmdbuf->bufsz -= sizeof(u64);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r300_reg.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r300_reg.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r300_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -1770,4 +1770,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define R500_RB3D_COLOR_CLEAR_VALUE_AR  0x46c0
 #define R500_RB3D_CONSTANT_COLOR_AR     0x4ef8
 
+#define R300_SU_REG_DEST                0x42c8
+#define RV530_FG_ZBREG_DEST             0x4be8
+#define R300_ZB_ZPASS_DATA              0x4f58
+#define R300_ZB_ZPASS_ADDR              0x4f5c
+
 #endif /* _R300_REG_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r600_cp.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r600_cp.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r600_cp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r600_cp.c	2013-05-03 16:44:16.000000000 -0400
@@ -0,0 +1,2076 @@
+/*
+ * Copyright 2008-2009 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     Dave Airlie <airlied@redhat.com>
+ *     Alex Deucher <alexander.deucher@amd.com>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+#include "r600_microcode.h"
+
+# define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
+# define ATI_PCIGART_PAGE_MASK		(~(ATI_PCIGART_PAGE_SIZE-1))
+
+#define R600_PTE_VALID     (1 << 0)
+#define R600_PTE_SYSTEM    (1 << 1)
+#define R600_PTE_SNOOPED   (1 << 2)
+#define R600_PTE_READABLE  (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+/* MAX values used for gfx init */
+#define R6XX_MAX_SH_GPRS           256
+#define R6XX_MAX_TEMP_GPRS         16
+#define R6XX_MAX_SH_THREADS        256
+#define R6XX_MAX_SH_STACK_ENTRIES  4096
+#define R6XX_MAX_BACKENDS          8
+#define R6XX_MAX_BACKENDS_MASK     0xff
+#define R6XX_MAX_SIMDS             8
+#define R6XX_MAX_SIMDS_MASK        0xff
+#define R6XX_MAX_PIPES             8
+#define R6XX_MAX_PIPES_MASK        0xff
+
+#define R7XX_MAX_SH_GPRS           256
+#define R7XX_MAX_TEMP_GPRS         16
+#define R7XX_MAX_SH_THREADS        256
+#define R7XX_MAX_SH_STACK_ENTRIES  4096
+#define R7XX_MAX_BACKENDS          8
+#define R7XX_MAX_BACKENDS_MASK     0xff
+#define R7XX_MAX_SIMDS             16
+#define R7XX_MAX_SIMDS_MASK        0xffff
+#define R7XX_MAX_PIPES             8
+#define R7XX_MAX_PIPES_MASK        0xff
+
+static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries)
+{
+	int i;
+
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+	for (i = 0; i < dev_priv->usec_timeout; i++) {
+		int slots;
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+			slots = (RADEON_READ(R600_GRBM_STATUS)
+				 & R700_CMDFIFO_AVAIL_MASK);
+		else
+			slots = (RADEON_READ(R600_GRBM_STATUS)
+				 & R600_CMDFIFO_AVAIL_MASK);
+		if (slots >= entries)
+			return 0;
+		DRM_UDELAY(1);
+	}
+	DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+		 RADEON_READ(R600_GRBM_STATUS),
+		 RADEON_READ(R600_GRBM_STATUS2));
+
+	return -EBUSY;
+}
+
+static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv)
+{
+	int i, ret;
+
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+		ret = r600_do_wait_for_fifo(dev_priv, 8);
+	else
+		ret = r600_do_wait_for_fifo(dev_priv, 16);
+	if (ret)
+		return ret;
+	for (i = 0; i < dev_priv->usec_timeout; i++) {
+		if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE))
+			return 0;
+		DRM_UDELAY(1);
+	}
+	DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+		 RADEON_READ(R600_GRBM_STATUS),
+		 RADEON_READ(R600_GRBM_STATUS2));
+
+	return -EBUSY;
+}
+
+void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
+{
+	struct drm_sg_mem *entry = dev->sg;
+	int max_pages;
+	int pages;
+	int i;
+
+	if (!entry)
+		return;
+
+	if (gart_info->bus_addr) {
+		max_pages = (gart_info->table_size / sizeof(u64));
+		pages = (entry->pages <= max_pages)
+		  ? entry->pages : max_pages;
+
+		for (i = 0; i < pages; i++) {
+			if (!entry->busaddr[i])
+				break;
+			pci_unmap_page(dev->pdev, entry->busaddr[i],
+				       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		}
+		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+			gart_info->bus_addr = 0;
+	}
+}
+
+/* R600 has page table setup */
+int r600_page_table_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+	struct drm_local_map *map = &gart_info->mapping;
+	struct drm_sg_mem *entry = dev->sg;
+	int ret = 0;
+	int i, j;
+	int pages;
+	u64 page_base;
+	dma_addr_t entry_addr;
+	int max_ati_pages, max_real_pages, gart_idx;
+
+	/* okay page table is available - lets rock */
+	max_ati_pages = (gart_info->table_size / sizeof(u64));
+	max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+
+	pages = (entry->pages <= max_real_pages) ?
+		entry->pages : max_real_pages;
+
+	memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64));
+
+	gart_idx = 0;
+	for (i = 0; i < pages; i++) {
+		entry->busaddr[i] = pci_map_page(dev->pdev,
+						 entry->pagelist[i], 0,
+						 PAGE_SIZE,
+						 PCI_DMA_BIDIRECTIONAL);
+		if (entry->busaddr[i] == 0) {
+			DRM_ERROR("unable to map PCIGART pages!\n");
+			r600_page_table_cleanup(dev, gart_info);
+			goto done;
+		}
+		entry_addr = entry->busaddr[i];
+		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+			page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK;
+			page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+			page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+
+			DRM_WRITE64(map, gart_idx * sizeof(u64), page_base);
+
+			gart_idx++;
+
+			if ((i % 128) == 0)
+				DRM_DEBUG("page entry %d: 0x%016llx\n",
+				    i, (unsigned long long)page_base);
+			entry_addr += ATI_PCIGART_PAGE_SIZE;
+		}
+	}
+	ret = 1;
+done:
+	return ret;
+}
+
+static void r600_vm_flush_gart_range(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u32 resp, countdown = 1000;
+	RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2);
+
+	do {
+		resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE);
+		countdown--;
+		DRM_UDELAY(1);
+	} while (((resp & 0xf0) == 0) && countdown);
+}
+
+static void r600_vm_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	/* initialise the VM to use the page table we constructed up there */
+	u32 vm_c0, i;
+	u32 mc_rd_a;
+	u32 vm_l2_cntl, vm_l2_cntl3;
+	/* okay set up the PCIE aperture type thingo */
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+	/* setup MC RD a */
+	mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS |
+		R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) |
+		R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY;
+
+	RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING);
+	RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/);
+
+	RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE);
+	RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a);
+
+	vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+	vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7);
+	RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+	RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+	vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) |
+		       R600_VM_L2_CNTL3_BANK_SELECT_1(1) |
+		       R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2));
+	RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+	vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+	RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+	vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+	/* disable all other contexts */
+	for (i = 1; i < 8; i++)
+		RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+	r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+#define r600_cp_load_microcode(dev_priv) \
+  do { \
+    DRM_ERROR("Missing Free microcode!\n"); \
+    r600_do_cleanup_cp(dev); \
+    return -EINVAL; \
+  } while (0)
+/*(DEBLOBBED)*/
+
+static void r700_vm_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	/* initialise the VM to use the page table we constructed up there */
+	u32 vm_c0, i;
+	u32 mc_vm_md_l1;
+	u32 vm_l2_cntl, vm_l2_cntl3;
+	/* okay set up the PCIE aperture type thingo */
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+	mc_vm_md_l1 = R700_ENABLE_L1_TLB |
+	    R700_ENABLE_L1_FRAGMENT_PROCESSING |
+	    R700_SYSTEM_ACCESS_MODE_IN_SYS |
+	    R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+	    R700_EFFECTIVE_L1_TLB_SIZE(5) |
+	    R700_EFFECTIVE_L1_QUEUE_SIZE(5);
+
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1);
+
+	vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+	vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7);
+	RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+	RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+	vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2);
+	RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+	vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+	RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+	vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+	/* disable all other contexts */
+	for (i = 1; i < 8; i++)
+		RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+	r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+#define r700_cp_load_microcode(dev_priv) \
+  do { \
+    DRM_ERROR("Missing Free microcode!\n"); \
+    r600_do_cleanup_cp(dev); \
+    return -EINVAL; \
+  } while (0)
+/*(DEBLOBBED)*/
+
+static void r600_test_writeback(drm_radeon_private_t *dev_priv)
+{
+	u32 tmp;
+
+	/* Start with assuming that writeback doesn't work */
+	dev_priv->writeback_works = 0;
+
+	/* Writeback doesn't seem to work everywhere, test it here and possibly
+	 * enable it if it appears to work
+	 */
+	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+
+	RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef);
+
+	for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+		u32 val;
+
+		val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1));
+		if (val == 0xdeadbeef)
+			break;
+		DRM_UDELAY(1);
+	}
+
+	if (tmp < dev_priv->usec_timeout) {
+		dev_priv->writeback_works = 1;
+		DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
+	} else {
+		dev_priv->writeback_works = 0;
+		DRM_INFO("writeback test failed\n");
+	}
+	if (radeon_no_wb == 1) {
+		dev_priv->writeback_works = 0;
+		DRM_INFO("writeback forced off\n");
+	}
+
+	if (!dev_priv->writeback_works) {
+		/* Disable writeback to avoid unnecessary bus master transfer */
+		RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) |
+			     RADEON_RB_NO_UPDATE);
+		RADEON_WRITE(R600_SCRATCH_UMSK, 0);
+	}
+}
+
+int r600_do_engine_reset(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u32 cp_ptr, cp_me_cntl, cp_rb_cntl;
+
+	DRM_INFO("Resetting GPU\n");
+
+	cp_ptr = RADEON_READ(R600_CP_RB_WPTR);
+	cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL);
+	RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT);
+
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+	DRM_UDELAY(50);
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+
+	RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+	cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL);
+	RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA);
+
+	RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr);
+	RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr);
+	RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl);
+	RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl);
+
+	/* Reset the CP ring */
+	r600_do_cp_reset(dev_priv);
+
+	/* The CP is no longer running after an engine reset */
+	dev_priv->cp_running = 0;
+
+	/* Reset any pending vertex, indirect buffers */
+	radeon_freelist_reset(dev);
+
+	return 0;
+
+}
+
+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+					     u32 num_backends,
+					     u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+	u32 enabled_backends_mask;
+	u32 enabled_backends_count;
+	u32 cur_pipe;
+	u32 swizzle_pipe[R6XX_MAX_PIPES];
+	u32 cur_backend;
+	u32 i;
+
+	if (num_tile_pipes > R6XX_MAX_PIPES)
+		num_tile_pipes = R6XX_MAX_PIPES;
+	if (num_tile_pipes < 1)
+		num_tile_pipes = 1;
+	if (num_backends > R6XX_MAX_BACKENDS)
+		num_backends = R6XX_MAX_BACKENDS;
+	if (num_backends < 1)
+		num_backends = 1;
+
+	enabled_backends_mask = 0;
+	enabled_backends_count = 0;
+	for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
+		if (((backend_disable_mask >> i) & 1) == 0) {
+			enabled_backends_mask |= (1 << i);
+			++enabled_backends_count;
+		}
+		if (enabled_backends_count == num_backends)
+			break;
+	}
+
+	if (enabled_backends_count == 0) {
+		enabled_backends_mask = 1;
+		enabled_backends_count = 1;
+	}
+
+	if (enabled_backends_count != num_backends)
+		num_backends = enabled_backends_count;
+
+	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
+	switch (num_tile_pipes) {
+	case 1:
+		swizzle_pipe[0] = 0;
+		break;
+	case 2:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		break;
+	case 3:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		break;
+	case 4:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		break;
+	case 5:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		swizzle_pipe[4] = 4;
+		break;
+	case 6:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 5;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		break;
+	case 7:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		break;
+	case 8:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		swizzle_pipe[7] = 7;
+		break;
+	}
+
+	cur_backend = 0;
+	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+		while (((1 << cur_backend) & enabled_backends_mask) == 0)
+			cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+
+		backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+		cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+	}
+
+	return backend_map;
+}
+
+static int r600_count_pipe_bits(uint32_t val)
+{
+	int i, ret = 0;
+	for (i = 0; i < 32; i++) {
+		ret += val & 1;
+		val >>= 1;
+	}
+	return ret;
+}
+
+static void r600_gfx_init(struct drm_device *dev,
+			  drm_radeon_private_t *dev_priv)
+{
+	int i, j, num_qd_pipes;
+	u32 sx_debug_1;
+	u32 tc_cntl;
+	u32 arb_pop;
+	u32 num_gs_verts_per_thread;
+	u32 vgt_gs_per_es;
+	u32 gs_prim_buffer_depth = 0;
+	u32 sq_ms_fifo_sizes;
+	u32 sq_config;
+	u32 sq_gpr_resource_mgmt_1 = 0;
+	u32 sq_gpr_resource_mgmt_2 = 0;
+	u32 sq_thread_resource_mgmt = 0;
+	u32 sq_stack_resource_mgmt_1 = 0;
+	u32 sq_stack_resource_mgmt_2 = 0;
+	u32 hdp_host_path_cntl;
+	u32 backend_map;
+	u32 gb_tiling_config = 0;
+	u32 cc_rb_backend_disable = 0;
+	u32 cc_gc_shader_pipe_config = 0;
+	u32 ramcfg;
+
+	/* setup chip specs */
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_R600:
+		dev_priv->r600_max_pipes = 4;
+		dev_priv->r600_max_tile_pipes = 8;
+		dev_priv->r600_max_simds = 4;
+		dev_priv->r600_max_backends = 4;
+		dev_priv->r600_max_gprs = 256;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		dev_priv->r600_max_pipes = 2;
+		dev_priv->r600_max_tile_pipes = 2;
+		dev_priv->r600_max_simds = 3;
+		dev_priv->r600_max_backends = 1;
+		dev_priv->r600_max_gprs = 128;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 128;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 4;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		dev_priv->r600_max_pipes = 1;
+		dev_priv->r600_max_tile_pipes = 1;
+		dev_priv->r600_max_simds = 2;
+		dev_priv->r600_max_backends = 1;
+		dev_priv->r600_max_gprs = 128;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 128;
+		dev_priv->r600_max_hw_contexts = 4;
+		dev_priv->r600_max_gs_threads = 4;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 1;
+		break;
+	case CHIP_RV670:
+		dev_priv->r600_max_pipes = 4;
+		dev_priv->r600_max_tile_pipes = 4;
+		dev_priv->r600_max_simds = 4;
+		dev_priv->r600_max_backends = 4;
+		dev_priv->r600_max_gprs = 192;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	default:
+		break;
+	}
+
+	/* Initialize HDP */
+	j = 0;
+	for (i = 0; i < 32; i++) {
+		RADEON_WRITE((0x2c14 + j), 0x00000000);
+		RADEON_WRITE((0x2c18 + j), 0x00000000);
+		RADEON_WRITE((0x2c1c + j), 0x00000000);
+		RADEON_WRITE((0x2c20 + j), 0x00000000);
+		RADEON_WRITE((0x2c24 + j), 0x00000000);
+		j += 0x18;
+	}
+
+	RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+	/* setup tiling, simd, pipe config */
+	ramcfg = RADEON_READ(R600_RAMCFG);
+
+	switch (dev_priv->r600_max_tile_pipes) {
+	case 1:
+		gb_tiling_config |= R600_PIPE_TILING(0);
+		break;
+	case 2:
+		gb_tiling_config |= R600_PIPE_TILING(1);
+		break;
+	case 4:
+		gb_tiling_config |= R600_PIPE_TILING(2);
+		break;
+	case 8:
+		gb_tiling_config |= R600_PIPE_TILING(3);
+		break;
+	default:
+		break;
+	}
+
+	gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK);
+
+	gb_tiling_config |= R600_GROUP_SIZE(0);
+
+	if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) {
+		gb_tiling_config |= R600_ROW_TILING(3);
+		gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+	} else {
+		gb_tiling_config |=
+			R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+		gb_tiling_config |=
+			R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+	}
+
+	gb_tiling_config |= R600_BANK_SWAPS(1);
+
+	backend_map = r600_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 =
+		R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK);
+	cc_gc_shader_pipe_config |=
+		R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK);
+
+	cc_rb_backend_disable =
+		R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK);
+
+	RADEON_WRITE(R600_GB_TILING_CONFIG,      gb_tiling_config);
+	RADEON_WRITE(R600_DCP_TILING_CONFIG,    (gb_tiling_config & 0xffff));
+	RADEON_WRITE(R600_HDP_TILING_CONFIG,    (gb_tiling_config & 0xffff));
+
+	RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
+	RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
+	RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+	num_qd_pipes =
+		R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+	RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+	RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+	/* set HW defaults for 3D engine */
+	RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+						R600_ROQ_IB2_START(0x2b)));
+
+	RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) |
+					      R600_ROQ_END(0x40)));
+
+	RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+					R600_SYNC_GRADIENT |
+					R600_SYNC_WALKER |
+					R600_SYNC_ALIGNER));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)
+		RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021);
+
+	sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1);
+	sx_debug_1 |= R600_SMX_EVENT_RELEASE;
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600))
+		sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS;
+	RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1);
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+		RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE);
+	else
+		RADEON_WRITE(R600_DB_DEBUG, 0);
+
+	RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) |
+					  R600_DEPTH_FLUSH(16) |
+					  R600_DEPTH_PENDING_FREE(4) |
+					  R600_DEPTH_CACHELINE_FREE(16)));
+	RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+	RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0);
+
+	RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+	RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0));
+
+	sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES);
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+		sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) |
+				    R600_FETCH_FIFO_HIWATER(0xa) |
+				    R600_DONE_FIFO_HIWATER(0xe0) |
+				    R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+		sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff);
+		sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4);
+	}
+	RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+	/* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+	 * should be adjusted as needed by the 2D/3D drivers.  This just sets default values
+	 */
+	sq_config = RADEON_READ(R600_SQ_CONFIG);
+	sq_config &= ~(R600_PS_PRIO(3) |
+		       R600_VS_PRIO(3) |
+		       R600_GS_PRIO(3) |
+		       R600_ES_PRIO(3));
+	sq_config |= (R600_DX9_CONSTS |
+		      R600_VC_ENABLE |
+		      R600_PS_PRIO(0) |
+		      R600_VS_PRIO(1) |
+		      R600_GS_PRIO(2) |
+		      R600_ES_PRIO(3));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) {
+		sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) |
+					  R600_NUM_VS_GPRS(124) |
+					  R600_NUM_CLAUSE_TEMP_GPRS(4));
+		sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) |
+					  R600_NUM_ES_GPRS(0));
+		sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) |
+					   R600_NUM_VS_THREADS(48) |
+					   R600_NUM_GS_THREADS(4) |
+					   R600_NUM_ES_THREADS(4));
+		sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) |
+					    R600_NUM_VS_STACK_ENTRIES(128));
+		sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) |
+					    R600_NUM_ES_STACK_ENTRIES(0));
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+		/* no vertex cache */
+		sq_config &= ~R600_VC_ENABLE;
+
+		sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+					  R600_NUM_VS_GPRS(44) |
+					  R600_NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+					  R600_NUM_ES_GPRS(17));
+		sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+					   R600_NUM_VS_THREADS(78) |
+					   R600_NUM_GS_THREADS(4) |
+					   R600_NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+					    R600_NUM_VS_STACK_ENTRIES(40));
+		sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+					    R600_NUM_ES_STACK_ENTRIES(16));
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+		sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+					  R600_NUM_VS_GPRS(44) |
+					  R600_NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) |
+					  R600_NUM_ES_GPRS(18));
+		sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+					   R600_NUM_VS_THREADS(78) |
+					   R600_NUM_GS_THREADS(4) |
+					   R600_NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+					    R600_NUM_VS_STACK_ENTRIES(40));
+		sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+					    R600_NUM_ES_STACK_ENTRIES(16));
+	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) {
+		sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+					  R600_NUM_VS_GPRS(44) |
+					  R600_NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+					  R600_NUM_ES_GPRS(17));
+		sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+					   R600_NUM_VS_THREADS(78) |
+					   R600_NUM_GS_THREADS(4) |
+					   R600_NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) |
+					    R600_NUM_VS_STACK_ENTRIES(64));
+		sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) |
+					    R600_NUM_ES_STACK_ENTRIES(64));
+	}
+
+	RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+	RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1,  sq_gpr_resource_mgmt_1);
+	RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2,  sq_gpr_resource_mgmt_2);
+	RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+	RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
+	RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+		RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY));
+	else
+		RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC));
+
+	RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) |
+						    R600_S0_Y(0x4) |
+						    R600_S1_X(0x4) |
+						    R600_S1_Y(0xc)));
+	RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) |
+						    R600_S0_Y(0xe) |
+						    R600_S1_X(0x2) |
+						    R600_S1_Y(0x2) |
+						    R600_S2_X(0xa) |
+						    R600_S2_Y(0x6) |
+						    R600_S3_X(0x6) |
+						    R600_S3_Y(0xa)));
+	RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) |
+							R600_S0_Y(0xb) |
+							R600_S1_X(0x4) |
+							R600_S1_Y(0xc) |
+							R600_S2_X(0x1) |
+							R600_S2_Y(0x6) |
+							R600_S3_X(0xa) |
+							R600_S3_Y(0xe)));
+	RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) |
+							R600_S4_Y(0x1) |
+							R600_S5_X(0x0) |
+							R600_S5_Y(0x0) |
+							R600_S6_X(0xb) |
+							R600_S6_Y(0x4) |
+							R600_S7_X(0x7) |
+							R600_S7_Y(0x8)));
+
+
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_R600:
+	case CHIP_RV630:
+	case CHIP_RV635:
+		gs_prim_buffer_depth = 0;
+		break;
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		gs_prim_buffer_depth = 32;
+		break;
+	case CHIP_RV670:
+		gs_prim_buffer_depth = 128;
+		break;
+	default:
+		break;
+	}
+
+	num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+	vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+	/* Max value for this is 256 */
+	if (vgt_gs_per_es > 256)
+		vgt_gs_per_es = 256;
+
+	RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+	RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+	RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+	RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+
+	/* more default values. 2D/3D driver should adjust as needed */
+	RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+	RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+	RADEON_WRITE(R600_SX_MISC, 0);
+	RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+	RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+	RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+	RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+	RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+	RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+	/* clear render buffer base addresses */
+	RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		tc_cntl = R600_TC_L2_SIZE(8);
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		tc_cntl = R600_TC_L2_SIZE(4);
+		break;
+	case CHIP_R600:
+		tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT;
+		break;
+	default:
+		tc_cntl = R600_TC_L2_SIZE(0);
+		break;
+	}
+
+	RADEON_WRITE(R600_TC_CNTL, tc_cntl);
+
+	hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+	RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+	arb_pop = RADEON_READ(R600_ARB_POP);
+	arb_pop |= R600_ENABLE_TC128;
+	RADEON_WRITE(R600_ARB_POP, arb_pop);
+
+	RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+	RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+					  R600_NUM_CLIP_SEQ(3)));
+	RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095));
+
+}
+
+static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+					     u32 num_backends,
+					     u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+	u32 enabled_backends_mask;
+	u32 enabled_backends_count;
+	u32 cur_pipe;
+	u32 swizzle_pipe[R7XX_MAX_PIPES];
+	u32 cur_backend;
+	u32 i;
+
+	if (num_tile_pipes > R7XX_MAX_PIPES)
+		num_tile_pipes = R7XX_MAX_PIPES;
+	if (num_tile_pipes < 1)
+		num_tile_pipes = 1;
+	if (num_backends > R7XX_MAX_BACKENDS)
+		num_backends = R7XX_MAX_BACKENDS;
+	if (num_backends < 1)
+		num_backends = 1;
+
+	enabled_backends_mask = 0;
+	enabled_backends_count = 0;
+	for (i = 0; i < R7XX_MAX_BACKENDS; ++i) {
+		if (((backend_disable_mask >> i) & 1) == 0) {
+			enabled_backends_mask |= (1 << i);
+			++enabled_backends_count;
+		}
+		if (enabled_backends_count == num_backends)
+			break;
+	}
+
+	if (enabled_backends_count == 0) {
+		enabled_backends_mask = 1;
+		enabled_backends_count = 1;
+	}
+
+	if (enabled_backends_count != num_backends)
+		num_backends = enabled_backends_count;
+
+	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
+	switch (num_tile_pipes) {
+	case 1:
+		swizzle_pipe[0] = 0;
+		break;
+	case 2:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		break;
+	case 3:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 1;
+		break;
+	case 4:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 3;
+		swizzle_pipe[3] = 1;
+		break;
+	case 5:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 1;
+		swizzle_pipe[4] = 3;
+		break;
+	case 6:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 5;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		break;
+	case 7:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		swizzle_pipe[6] = 5;
+		break;
+	case 8:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		swizzle_pipe[6] = 7;
+		swizzle_pipe[7] = 5;
+		break;
+	}
+
+	cur_backend = 0;
+	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+		while (((1 << cur_backend) & enabled_backends_mask) == 0)
+			cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+
+		backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+		cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+	}
+
+	return backend_map;
+}
+
+static void r700_gfx_init(struct drm_device *dev,
+			  drm_radeon_private_t *dev_priv)
+{
+	int i, j, num_qd_pipes;
+	u32 sx_debug_1;
+	u32 smx_dc_ctl0;
+	u32 num_gs_verts_per_thread;
+	u32 vgt_gs_per_es;
+	u32 gs_prim_buffer_depth = 0;
+	u32 sq_ms_fifo_sizes;
+	u32 sq_config;
+	u32 sq_thread_resource_mgmt;
+	u32 hdp_host_path_cntl;
+	u32 sq_dyn_gpr_size_simd_ab_0;
+	u32 backend_map;
+	u32 gb_tiling_config = 0;
+	u32 cc_rb_backend_disable = 0;
+	u32 cc_gc_shader_pipe_config = 0;
+	u32 mc_arb_ramcfg;
+	u32 db_debug4;
+
+	/* setup chip specs */
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV770:
+		dev_priv->r600_max_pipes = 4;
+		dev_priv->r600_max_tile_pipes = 8;
+		dev_priv->r600_max_simds = 10;
+		dev_priv->r600_max_backends = 4;
+		dev_priv->r600_max_gprs = 256;
+		dev_priv->r600_max_threads = 248;
+		dev_priv->r600_max_stack_entries = 512;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16 * 2;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 112;
+		dev_priv->r600_sq_num_cf_insts = 2;
+
+		dev_priv->r700_sx_num_of_sets = 7;
+		dev_priv->r700_sc_prim_fifo_size = 0xF9;
+		dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+		dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+		break;
+	case CHIP_RV730:
+		dev_priv->r600_max_pipes = 2;
+		dev_priv->r600_max_tile_pipes = 4;
+		dev_priv->r600_max_simds = 8;
+		dev_priv->r600_max_backends = 2;
+		dev_priv->r600_max_gprs = 128;
+		dev_priv->r600_max_threads = 248;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16 * 2;
+		dev_priv->r600_sx_max_export_size = 256;
+		dev_priv->r600_sx_max_export_pos_size = 32;
+		dev_priv->r600_sx_max_export_smx_size = 224;
+		dev_priv->r600_sq_num_cf_insts = 2;
+
+		dev_priv->r700_sx_num_of_sets = 7;
+		dev_priv->r700_sc_prim_fifo_size = 0xf9;
+		dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+		dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+		break;
+	case CHIP_RV710:
+		dev_priv->r600_max_pipes = 2;
+		dev_priv->r600_max_tile_pipes = 2;
+		dev_priv->r600_max_simds = 2;
+		dev_priv->r600_max_backends = 1;
+		dev_priv->r600_max_gprs = 256;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 4;
+		dev_priv->r600_max_gs_threads = 8 * 2;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 112;
+		dev_priv->r600_sq_num_cf_insts = 1;
+
+		dev_priv->r700_sx_num_of_sets = 7;
+		dev_priv->r700_sc_prim_fifo_size = 0x40;
+		dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+		dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+		break;
+	default:
+		break;
+	}
+
+	/* Initialize HDP */
+	j = 0;
+	for (i = 0; i < 32; i++) {
+		RADEON_WRITE((0x2c14 + j), 0x00000000);
+		RADEON_WRITE((0x2c18 + j), 0x00000000);
+		RADEON_WRITE((0x2c1c + j), 0x00000000);
+		RADEON_WRITE((0x2c20 + j), 0x00000000);
+		RADEON_WRITE((0x2c24 + j), 0x00000000);
+		j += 0x18;
+	}
+
+	RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+	/* setup tiling, simd, pipe config */
+	mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG);
+
+	switch (dev_priv->r600_max_tile_pipes) {
+	case 1:
+		gb_tiling_config |= R600_PIPE_TILING(0);
+		break;
+	case 2:
+		gb_tiling_config |= R600_PIPE_TILING(1);
+		break;
+	case 4:
+		gb_tiling_config |= R600_PIPE_TILING(2);
+		break;
+	case 8:
+		gb_tiling_config |= R600_PIPE_TILING(3);
+		break;
+	default:
+		break;
+	}
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+		gb_tiling_config |= R600_BANK_TILING(1);
+	else
+		gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK);
+
+	gb_tiling_config |= R600_GROUP_SIZE(0);
+
+	if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) {
+		gb_tiling_config |= R600_ROW_TILING(3);
+		gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+	} else {
+		gb_tiling_config |=
+			R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+		gb_tiling_config |=
+			R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+	}
+
+	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);
+	gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+
+	cc_gc_shader_pipe_config =
+		R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK);
+	cc_gc_shader_pipe_config |=
+		R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK);
+
+	cc_rb_backend_disable =
+		R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK);
+
+	RADEON_WRITE(R600_GB_TILING_CONFIG,      gb_tiling_config);
+	RADEON_WRITE(R600_DCP_TILING_CONFIG,    (gb_tiling_config & 0xffff));
+	RADEON_WRITE(R600_HDP_TILING_CONFIG,    (gb_tiling_config & 0xffff));
+
+	RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
+	RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
+	RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+	RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+	RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
+	RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
+	RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
+	RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
+
+	num_qd_pipes =
+		R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+	RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+	RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+	/* set HW defaults for 3D engine */
+	RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+						R600_ROQ_IB2_START(0x2b)));
+
+	RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30));
+
+	RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+					R600_SYNC_GRADIENT |
+					R600_SYNC_WALKER |
+					R600_SYNC_ALIGNER));
+
+	sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1);
+	sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS;
+	RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1);
+
+	smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0);
+	smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff);
+	smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1);
+	RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0);
+
+	RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) |
+					  R700_GS_FLUSH_CTL(4) |
+					  R700_ACK_FLUSH_CTL(3) |
+					  R700_SYNC_FLUSH_CTL));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+		RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f));
+	else {
+		db_debug4 = RADEON_READ(RV700_DB_DEBUG4);
+		db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER;
+		RADEON_WRITE(RV700_DB_DEBUG4, db_debug4);
+	}
+
+	RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) |
+						   R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) |
+						   R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1)));
+
+	RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) |
+						 R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) |
+						 R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize)));
+
+	RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+	RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1);
+
+	RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+
+	RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4));
+
+	RADEON_WRITE(R600_CP_PERFMON_CNTL, 0);
+
+	sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) |
+			    R600_DONE_FIFO_HIWATER(0xe0) |
+			    R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV770:
+		sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1);
+		break;
+	case CHIP_RV730:
+	case CHIP_RV710:
+	default:
+		sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4);
+		break;
+	}
+	RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+	/* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+	 * should be adjusted as needed by the 2D/3D drivers.  This just sets default values
+	 */
+	sq_config = RADEON_READ(R600_SQ_CONFIG);
+	sq_config &= ~(R600_PS_PRIO(3) |
+		       R600_VS_PRIO(3) |
+		       R600_GS_PRIO(3) |
+		       R600_ES_PRIO(3));
+	sq_config |= (R600_DX9_CONSTS |
+		      R600_VC_ENABLE |
+		      R600_EXPORT_SRC_C |
+		      R600_PS_PRIO(0) |
+		      R600_VS_PRIO(1) |
+		      R600_GS_PRIO(2) |
+		      R600_ES_PRIO(3));
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+		/* no vertex cache */
+		sq_config &= ~R600_VC_ENABLE;
+
+	RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+
+	RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1,  (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+						    R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+						    R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2)));
+
+	RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2,  (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) |
+						    R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64)));
+
+	sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) |
+				   R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) |
+				   R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8));
+	if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads)
+		sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads);
+	else
+		sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8);
+	RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+
+	RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+						     R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+	RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+						     R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+	sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) |
+				     R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) |
+				     R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) |
+				     R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64));
+
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
+	RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
+
+	RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) |
+						     R700_FORCE_EOV_MAX_REZ_CNT(255)));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+		RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) |
+							   R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+	else
+		RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) |
+							   R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_RV770:
+	case CHIP_RV730:
+		gs_prim_buffer_depth = 384;
+		break;
+	case CHIP_RV710:
+		gs_prim_buffer_depth = 128;
+		break;
+	default:
+		break;
+	}
+
+	num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+	vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+	/* Max value for this is 256 */
+	if (vgt_gs_per_es > 256)
+		vgt_gs_per_es = 256;
+
+	RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+	RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+	RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+
+	/* more default values. 2D/3D driver should adjust as needed */
+	RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+	RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+	RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+	RADEON_WRITE(R600_SX_MISC, 0);
+	RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+	RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa);
+	RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+	RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff);
+	RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+	RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+	RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+	RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+	/* clear render buffer base addresses */
+	RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+	RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+	RADEON_WRITE(R700_TCP_CNTL, 0);
+
+	hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+	RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+	RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+	RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+					  R600_NUM_CLIP_SEQ(3)));
+
+}
+
+static void r600_cp_init_ring_buffer(struct drm_device *dev,
+				       drm_radeon_private_t *dev_priv,
+				       struct drm_file *file_priv)
+{
+	struct drm_radeon_master_private *master_priv;
+	u32 ring_start;
+	u64 rptr_addr;
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+		r700_gfx_init(dev, dev_priv);
+	else
+		r600_gfx_init(dev, dev_priv);
+
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+	DRM_UDELAY(15000);
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+	/* Set ring buffer size */
+#ifdef __BIG_ENDIAN
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     RADEON_BUF_SWAP_32BIT |
+		     RADEON_RB_NO_UPDATE |
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#else
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     RADEON_RB_NO_UPDATE |
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#endif
+
+	RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4);
+
+	/* Set the write pointer delay */
+	RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+
+#ifdef __BIG_ENDIAN
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     RADEON_BUF_SWAP_32BIT |
+		     RADEON_RB_NO_UPDATE |
+		     RADEON_RB_RPTR_WR_ENA |
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#else
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     RADEON_RB_NO_UPDATE |
+		     RADEON_RB_RPTR_WR_ENA |
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#endif
+
+	/* Initialize the ring buffer's read and write pointers */
+	RADEON_WRITE(R600_CP_RB_RPTR_WR, 0);
+	RADEON_WRITE(R600_CP_RB_WPTR, 0);
+	SET_RING_HEAD(dev_priv, 0);
+	dev_priv->ring.tail = 0;
+
+#if __OS_HAS_AGP
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		rptr_addr = dev_priv->ring_rptr->offset
+			- dev->agp->base +
+			dev_priv->gart_vm_start;
+	} else
+#endif
+	{
+		rptr_addr = dev_priv->ring_rptr->offset
+			- ((unsigned long) dev->sg->virtual)
+			+ dev_priv->gart_vm_start;
+	}
+	RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
+		     rptr_addr & 0xffffffff);
+	RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI,
+		     upper_32_bits(rptr_addr));
+
+#ifdef __BIG_ENDIAN
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     RADEON_BUF_SWAP_32BIT |
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#else
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     (dev_priv->ring.rptr_update_l2qw << 8) |
+		     dev_priv->ring.size_l2qw);
+#endif
+
+#if __OS_HAS_AGP
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		/* XXX */
+		radeon_write_agp_base(dev_priv, dev->agp->base);
+
+		/* XXX */
+		radeon_write_agp_location(dev_priv,
+			     (((dev_priv->gart_vm_start - 1 +
+				dev_priv->gart_size) & 0xffff0000) |
+			      (dev_priv->gart_vm_start >> 16)));
+
+		ring_start = (dev_priv->cp_ring->offset
+			      - dev->agp->base
+			      + dev_priv->gart_vm_start);
+	} else
+#endif
+		ring_start = (dev_priv->cp_ring->offset
+			      - (unsigned long)dev->sg->virtual
+			      + dev_priv->gart_vm_start);
+
+	RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8);
+
+	RADEON_WRITE(R600_CP_ME_CNTL, 0xff);
+
+	RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28));
+
+	/* Initialize the scratch register pointer.  This will cause
+	 * the scratch register values to be written out to memory
+	 * whenever they are updated.
+	 *
+	 * We simply put this behind the ring read pointer, this works
+	 * with PCI GART as well as (whatever kind of) AGP GART
+	 */
+	{
+		u64 scratch_addr;
+
+		scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR);
+		scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32;
+		scratch_addr += R600_SCRATCH_REG_OFFSET;
+		scratch_addr >>= 8;
+		scratch_addr &= 0xffffffff;
+
+		RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr);
+	}
+
+	RADEON_WRITE(R600_SCRATCH_UMSK, 0x7);
+
+	/* Turn on bus mastering */
+	radeon_enable_bm(dev_priv);
+
+	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0);
+	RADEON_WRITE(R600_LAST_FRAME_REG, 0);
+
+	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+	RADEON_WRITE(R600_LAST_DISPATCH_REG, 0);
+
+	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0);
+	RADEON_WRITE(R600_LAST_CLEAR_REG, 0);
+
+	/* reset sarea copies of these */
+	master_priv = file_priv->master->driver_priv;
+	if (master_priv->sarea_priv) {
+		master_priv->sarea_priv->last_frame = 0;
+		master_priv->sarea_priv->last_dispatch = 0;
+		master_priv->sarea_priv->last_clear = 0;
+	}
+
+	r600_do_wait_for_idle(dev_priv);
+
+}
+
+int r600_do_cleanup_cp(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	DRM_DEBUG("\n");
+
+	/* Make sure interrupts are disabled here because the uninstall ioctl
+	 * may not have been called from userspace and after dev_private
+	 * is freed, it's too late.
+	 */
+	if (dev->irq_enabled)
+		drm_irq_uninstall(dev);
+
+#if __OS_HAS_AGP
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		if (dev_priv->cp_ring != NULL) {
+			drm_core_ioremapfree(dev_priv->cp_ring, dev);
+			dev_priv->cp_ring = NULL;
+		}
+		if (dev_priv->ring_rptr != NULL) {
+			drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+			dev_priv->ring_rptr = NULL;
+		}
+		if (dev->agp_buffer_map != NULL) {
+			drm_core_ioremapfree(dev->agp_buffer_map, dev);
+			dev->agp_buffer_map = NULL;
+		}
+	} else
+#endif
+	{
+
+		if (dev_priv->gart_info.bus_addr)
+			r600_page_table_cleanup(dev, &dev_priv->gart_info);
+
+		if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
+			drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
+			dev_priv->gart_info.addr = NULL;
+		}
+	}
+	/* only clear to the start of flags */
+	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
+
+	return 0;
+}
+
+int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+		    struct drm_file *file_priv)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+
+	DRM_DEBUG("\n");
+
+	/* if we require new memory map but we don't have it fail */
+	if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
+		DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+
+	if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
+		DRM_DEBUG("Forcing AGP card to PCI mode\n");
+		dev_priv->flags &= ~RADEON_IS_AGP;
+		/* The writeback test succeeds, but when writeback is enabled,
+		 * the ring buffer read ptr update fails after first 128 bytes.
+		 */
+		radeon_no_wb = 1;
+	} else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
+		 && !init->is_pci) {
+		DRM_DEBUG("Restoring AGP flag\n");
+		dev_priv->flags |= RADEON_IS_AGP;
+	}
+
+	dev_priv->usec_timeout = init->usec_timeout;
+	if (dev_priv->usec_timeout < 1 ||
+	    dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
+		DRM_DEBUG("TIMEOUT problem!\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+
+	/* Enable vblank on CRTC1 for older X servers
+	 */
+	dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
+
+	dev_priv->cp_mode = init->cp_mode;
+
+	/* We don't support anything other than bus-mastering ring mode,
+	 * but the ring can be in either AGP or PCI space for the ring
+	 * read pointer.
+	 */
+	if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
+	    (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
+		DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+
+	switch (init->fb_bpp) {
+	case 16:
+		dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
+		break;
+	case 32:
+	default:
+		dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
+		break;
+	}
+	dev_priv->front_offset = init->front_offset;
+	dev_priv->front_pitch = init->front_pitch;
+	dev_priv->back_offset = init->back_offset;
+	dev_priv->back_pitch = init->back_pitch;
+
+	dev_priv->ring_offset = init->ring_offset;
+	dev_priv->ring_rptr_offset = init->ring_rptr_offset;
+	dev_priv->buffers_offset = init->buffers_offset;
+	dev_priv->gart_textures_offset = init->gart_textures_offset;
+
+	master_priv->sarea = drm_getsarea(dev);
+	if (!master_priv->sarea) {
+		DRM_ERROR("could not find sarea!\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+
+	dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
+	if (!dev_priv->cp_ring) {
+		DRM_ERROR("could not find cp ring region!\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
+	if (!dev_priv->ring_rptr) {
+		DRM_ERROR("could not find ring read pointer!\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+	dev->agp_buffer_token = init->buffers_offset;
+	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+	if (!dev->agp_buffer_map) {
+		DRM_ERROR("could not find dma buffer region!\n");
+		r600_do_cleanup_cp(dev);
+		return -EINVAL;
+	}
+
+	if (init->gart_textures_offset) {
+		dev_priv->gart_textures =
+		    drm_core_findmap(dev, init->gart_textures_offset);
+		if (!dev_priv->gart_textures) {
+			DRM_ERROR("could not find GART texture region!\n");
+			r600_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+	}
+
+#if __OS_HAS_AGP
+	/* XXX */
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		drm_core_ioremap_wc(dev_priv->cp_ring, dev);
+		drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+		drm_core_ioremap_wc(dev->agp_buffer_map, dev);
+		if (!dev_priv->cp_ring->handle ||
+		    !dev_priv->ring_rptr->handle ||
+		    !dev->agp_buffer_map->handle) {
+			DRM_ERROR("could not find ioremap agp regions!\n");
+			r600_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+	} else
+#endif
+	{
+		dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+		dev_priv->ring_rptr->handle =
+		    (void *)dev_priv->ring_rptr->offset;
+		dev->agp_buffer_map->handle =
+		    (void *)dev->agp_buffer_map->offset;
+
+		DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
+			  dev_priv->cp_ring->handle);
+		DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
+			  dev_priv->ring_rptr->handle);
+		DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
+			  dev->agp_buffer_map->handle);
+	}
+
+	dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24;
+	dev_priv->fb_size =
+		(((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000)
+		- dev_priv->fb_location;
+
+	dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
+					((dev_priv->front_offset
+					  + dev_priv->fb_location) >> 10));
+
+	dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
+				       ((dev_priv->back_offset
+					 + dev_priv->fb_location) >> 10));
+
+	dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
+					((dev_priv->depth_offset
+					  + dev_priv->fb_location) >> 10));
+
+	dev_priv->gart_size = init->gart_size;
+
+	/* New let's set the memory map ... */
+	if (dev_priv->new_memmap) {
+		u32 base = 0;
+
+		DRM_INFO("Setting GART location based on new memory map\n");
+
+		/* If using AGP, try to locate the AGP aperture at the same
+		 * location in the card and on the bus, though we have to
+		 * align it down.
+		 */
+#if __OS_HAS_AGP
+		/* XXX */
+		if (dev_priv->flags & RADEON_IS_AGP) {
+			base = dev->agp->base;
+			/* Check if valid */
+			if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
+			    base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
+				DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
+					 dev->agp->base);
+				base = 0;
+			}
+		}
+#endif
+		/* If not or if AGP is at 0 (Macs), try to put it elsewhere */
+		if (base == 0) {
+			base = dev_priv->fb_location + dev_priv->fb_size;
+			if (base < dev_priv->fb_location ||
+			    ((base + dev_priv->gart_size) & 0xfffffffful) < base)
+				base = dev_priv->fb_location
+					- dev_priv->gart_size;
+		}
+		dev_priv->gart_vm_start = base & 0xffc00000u;
+		if (dev_priv->gart_vm_start != base)
+			DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
+				 base, dev_priv->gart_vm_start);
+	}
+
+#if __OS_HAS_AGP
+	/* XXX */
+	if (dev_priv->flags & RADEON_IS_AGP)
+		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+						 - dev->agp->base
+						 + dev_priv->gart_vm_start);
+	else
+#endif
+		dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+						 - (unsigned long)dev->sg->virtual
+						 + dev_priv->gart_vm_start);
+
+	DRM_DEBUG("fb 0x%08x size %d\n",
+		  (unsigned int) dev_priv->fb_location,
+		  (unsigned int) dev_priv->fb_size);
+	DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
+	DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n",
+		  (unsigned int) dev_priv->gart_vm_start);
+	DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n",
+		  dev_priv->gart_buffers_offset);
+
+	dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
+	dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+			      + init->ring_size / sizeof(u32));
+	dev_priv->ring.size = init->ring_size;
+	dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+
+	dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
+	dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8);
+
+	dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
+	dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16);
+
+	dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+
+	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
+#if __OS_HAS_AGP
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		/* XXX turn off pcie gart */
+	} else
+#endif
+	{
+		dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
+		/* if we have an offset set from userspace */
+		if (!dev_priv->pcigart_offset_set) {
+			DRM_ERROR("Need gart offset from userspace\n");
+			r600_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+
+		DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset);
+
+		dev_priv->gart_info.bus_addr =
+			dev_priv->pcigart_offset + dev_priv->fb_location;
+		dev_priv->gart_info.mapping.offset =
+			dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
+		dev_priv->gart_info.mapping.size =
+			dev_priv->gart_info.table_size;
+
+		drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
+		if (!dev_priv->gart_info.mapping.handle) {
+			DRM_ERROR("ioremap failed.\n");
+			r600_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+
+		dev_priv->gart_info.addr =
+			dev_priv->gart_info.mapping.handle;
+
+		DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
+			  dev_priv->gart_info.addr,
+			  dev_priv->pcigart_offset);
+
+		if (!r600_page_table_init(dev)) {
+			DRM_ERROR("Failed to init GART table\n");
+			r600_do_cleanup_cp(dev);
+			return -EINVAL;
+		}
+
+		if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+			r700_vm_init(dev);
+		else
+			r600_vm_init(dev);
+	}
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+		r700_cp_load_microcode(dev_priv);
+	else
+		r600_cp_load_microcode(dev_priv);
+
+	r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+
+	dev_priv->last_buf = 0;
+
+	r600_do_engine_reset(dev);
+	r600_test_writeback(dev_priv);
+
+	return 0;
+}
+
+int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	DRM_DEBUG("\n");
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) {
+		r700_vm_init(dev);
+		r700_cp_load_microcode(dev_priv);
+	} else {
+		r600_vm_init(dev);
+		r600_cp_load_microcode(dev_priv);
+	}
+	r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+	r600_do_engine_reset(dev);
+
+	return 0;
+}
+
+/* Wait for the CP to go idle.
+ */
+int r600_do_cp_idle(drm_radeon_private_t *dev_priv)
+{
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(5);
+	OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+	OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+	/* wait for 3D idle clean */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+	OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
+
+	ADVANCE_RING();
+	COMMIT_RING();
+
+	return r600_do_wait_for_idle(dev_priv);
+}
+
+/* Start the Command Processor.
+ */
+void r600_do_cp_start(drm_radeon_private_t *dev_priv)
+{
+	u32 cp_me;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(7);
+	OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5));
+	OUT_RING(0x00000001);
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770))
+		OUT_RING(0x00000003);
+	else
+		OUT_RING(0x00000000);
+	OUT_RING((dev_priv->r600_max_hw_contexts - 1));
+	OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1));
+	OUT_RING(0x00000000);
+	OUT_RING(0x00000000);
+	ADVANCE_RING();
+	COMMIT_RING();
+
+	/* set the mux and reset the halt bit */
+	cp_me = 0xff;
+	RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+	dev_priv->cp_running = 1;
+
+}
+
+void r600_do_cp_reset(drm_radeon_private_t *dev_priv)
+{
+	u32 cur_read_ptr;
+	DRM_DEBUG("\n");
+
+	cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR);
+	RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr);
+	SET_RING_HEAD(dev_priv, cur_read_ptr);
+	dev_priv->ring.tail = cur_read_ptr;
+}
+
+void r600_do_cp_stop(drm_radeon_private_t *dev_priv)
+{
+	uint32_t cp_me;
+
+	DRM_DEBUG("\n");
+
+	cp_me = 0xff | R600_CP_ME_HALT;
+
+	RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+	dev_priv->cp_running = 0;
+}
+
+int r600_cp_dispatch_indirect(struct drm_device *dev,
+			      struct drm_buf *buf, int start, int end)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+
+	if (start != end) {
+		unsigned long offset = (dev_priv->gart_buffers_offset
+					+ buf->offset + start);
+		int dwords = (end - start + 3) / sizeof(u32);
+
+		DRM_DEBUG("dwords:%d\n", dwords);
+		DRM_DEBUG("offset 0x%lx\n", offset);
+
+
+		/* Indirect buffer data must be a multiple of 16 dwords.
+		 * pad the data with a Type-2 CP packet.
+		 */
+		while (dwords & 0xf) {
+			u32 *data = (u32 *)
+			    ((char *)dev->agp_buffer_map->handle
+			     + buf->offset + start);
+			data[dwords++] = RADEON_CP_PACKET2;
+		}
+
+		/* Fire off the indirect buffer */
+		BEGIN_RING(4);
+		OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2));
+		OUT_RING((offset & 0xfffffffc));
+		OUT_RING((upper_32_bits(offset) & 0xff));
+		OUT_RING(dwords);
+		ADVANCE_RING();
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r600_microcode.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r600_microcode.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/r600_microcode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/r600_microcode.h	2013-05-03 16:44:18.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008-2009 Advanced Micro Devices, 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 (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
+ * 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 R600_MICROCODE_H
+#define R600_MICROCODE_H
+
+static const int ME_JUMP_TABLE_START = 1764;
+static const int ME_JUMP_TABLE_END   = 1792;
+
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+/*(DEBLOBBED)*/
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_cp.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_cp.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 18:00:28.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_cp.c	2013-05-03 16:44:12.000000000 -0400
@@ -43,6 +43,78 @@
 static int radeon_do_cleanup_cp(struct drm_device * dev);
 static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
 
+u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off)
+{
+	u32 val;
+
+	if (dev_priv->flags & RADEON_IS_AGP) {
+		val = DRM_READ32(dev_priv->ring_rptr, off);
+	} else {
+		val = *(((volatile u32 *)
+			 dev_priv->ring_rptr->handle) +
+			(off / sizeof(u32)));
+		val = le32_to_cpu(val);
+	}
+	return val;
+}
+
+u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv)
+{
+	if (dev_priv->writeback_works)
+		return radeon_read_ring_rptr(dev_priv, 0);
+	else {
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			return RADEON_READ(R600_CP_RB_RPTR);
+		else
+			return RADEON_READ(RADEON_CP_RB_RPTR);
+	}
+}
+
+void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val)
+{
+	if (dev_priv->flags & RADEON_IS_AGP)
+		DRM_WRITE32(dev_priv->ring_rptr, off, val);
+	else
+		*(((volatile u32 *) dev_priv->ring_rptr->handle) +
+		  (off / sizeof(u32))) = cpu_to_le32(val);
+}
+
+void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val)
+{
+	radeon_write_ring_rptr(dev_priv, 0, val);
+}
+
+u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index)
+{
+	if (dev_priv->writeback_works) {
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			return radeon_read_ring_rptr(dev_priv,
+						     R600_SCRATCHOFF(index));
+		else
+			return radeon_read_ring_rptr(dev_priv,
+						     RADEON_SCRATCHOFF(index));
+	} else {
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			return RADEON_READ(R600_SCRATCH_REG0 + 4*index);
+		else
+			return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index);
+	}
+}
+
+u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr)
+{
+	u32 ret;
+
+	if (addr < 0x10000)
+		ret = DRM_READ32(dev_priv->mmio, addr);
+	else {
+		DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr);
+		ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA);
+	}
+
+	return ret;
+}
+
 static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
 {
 	u32 ret;
@@ -70,11 +142,22 @@ static u32 RS690_READ_MCIND(drm_radeon_p
 	return ret;
 }
 
+static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+	u32 ret;
+	RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) |
+				      RS600_MC_IND_CITF_ARB0));
+	ret = RADEON_READ(RS600_MC_DATA);
+	return ret;
+}
+
 static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
 {
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
 		return RS690_READ_MCIND(dev_priv, addr);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+		return RS600_READ_MCIND(dev_priv, addr);
 	else
 		return RS480_READ_MCIND(dev_priv, addr);
 }
@@ -82,11 +165,17 @@ static u32 IGP_READ_MCIND(drm_radeon_pri
 u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
 {
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+		return RADEON_READ(R700_MC_VM_FB_LOCATION);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return RADEON_READ(R600_MC_VM_FB_LOCATION);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
 		return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
 	else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 		 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
 		return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+		return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION);
 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
 		return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
 	else
@@ -95,42 +184,66 @@ u32 radeon_read_fb_location(drm_radeon_p
 
 static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
 {
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+		RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
 		R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
 	else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 		 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
 		RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+		RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc);
 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
 		R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
 	else
 		RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
 }
 
-static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
 {
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+	/*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+		RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+		RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+		RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+		RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
 		R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
 	else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 		 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
 		RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+		RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc);
 	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
 		R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
 	else
 		RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
 }
 
-static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
+void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
 {
 	u32 agp_base_hi = upper_32_bits(agp_base);
 	u32 agp_base_lo = agp_base & 0xffffffff;
+	u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff;
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
+	/* R6xx/R7xx must be aligned to a 4MB boundry */
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+		RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base);
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
 		R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
 		R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 		 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
 		RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
 		RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
+	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+		RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo);
+		RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi);
 	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
 		R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
 		R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
@@ -145,6 +258,25 @@ static void radeon_write_agp_base(drm_ra
 	}
 }
 
+void radeon_enable_bm(struct drm_radeon_private *dev_priv)
+{
+	u32 tmp;
+	/* Turn on bus mastering */
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+		/* rs600/rs690/rs740 */
+		tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
+		RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
+		/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+		tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+		RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+	} /* PCIE cards appears to not need this */
+}
+
 static int RADEON_READ_PLL(struct drm_device * dev, int addr)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -302,7 +434,7 @@ static void radeon_init_pipes(drm_radeon
 
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
 		RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
-		RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+		RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
 	}
 	RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
 	radeon_do_wait_for_idle(dev_priv);
@@ -491,7 +623,6 @@ static void radeon_cp_init_ring_buffer(s
 {
 	struct drm_radeon_master_private *master_priv;
 	u32 ring_start, cur_read_ptr;
-	u32 tmp;
 
 	/* Initialize the memory controller. With new memory map, the fb location
 	 * is not changed, it should have been properly initialized already. Part
@@ -540,17 +671,10 @@ static void radeon_cp_init_ring_buffer(s
 	} else
 #endif
 	{
-		struct drm_sg_mem *entry = dev->sg;
-		unsigned long tmp_ofs, page_ofs;
-
-		tmp_ofs = dev_priv->ring_rptr->offset -
-				(unsigned long)dev->sg->virtual;
-		page_ofs = tmp_ofs >> PAGE_SHIFT;
-
-		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
-		DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
-			  (unsigned long)entry->busaddr[page_ofs],
-			  entry->handle + tmp_ofs);
+		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
+			     dev_priv->ring_rptr->offset
+			     - ((unsigned long) dev->sg->virtual)
+			     + dev_priv->gart_vm_start);
 	}
 
 	/* Set ring buffer size */
@@ -578,34 +702,17 @@ static void radeon_cp_init_ring_buffer(s
 	RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
 		     + RADEON_SCRATCH_REG_OFFSET);
 
-	dev_priv->scratch = ((__volatile__ u32 *)
-			     dev_priv->ring_rptr->handle +
-			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
-
 	RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
 
-	/* Turn on bus mastering */
-	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
-	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
-		/* rs600/rs690/rs740 */
-		tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
-		RADEON_WRITE(RADEON_BUS_CNTL, tmp);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
-		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
-		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
-		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
-		/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
-		tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
-		RADEON_WRITE(RADEON_BUS_CNTL, tmp);
-	} /* PCIE cards appears to not need this */
+	radeon_enable_bm(dev_priv);
 
-	dev_priv->scratch[0] = 0;
+	radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0);
 	RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
 
-	dev_priv->scratch[1] = 0;
+	radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
 	RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0);
 
-	dev_priv->scratch[2] = 0;
+	radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0);
 	RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
 
 	/* reset sarea copies of these */
@@ -637,12 +744,15 @@ static void radeon_test_writeback(drm_ra
 	/* Writeback doesn't seem to work everywhere, test it here and possibly
 	 * enable it if it appears to work
 	 */
-	DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
+	radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
+
 	RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
 
 	for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
-		if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
-		    0xdeadbeef)
+		u32 val;
+
+		val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
+		if (val == 0xdeadbeef)
 			break;
 		DRM_UDELAY(1);
 	}
@@ -738,6 +848,82 @@ static void radeon_set_igpgart(drm_radeo
 	}
 }
 
+/* Enable or disable IGP GART on the chip */
+static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on)
+{
+	u32 temp;
+	int i;
+
+	if (on) {
+		DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
+			 dev_priv->gart_vm_start,
+			 (long)dev_priv->gart_info.bus_addr,
+			 dev_priv->gart_size);
+
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
+						    RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
+
+		for (i = 0; i < 19; i++)
+			IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i,
+					(RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
+					 RS600_SYSTEM_ACCESS_MODE_IN_SYS |
+					 RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH |
+					 RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
+					 RS600_ENABLE_FRAGMENT_PROCESSING |
+					 RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
+
+		IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE |
+							     RS600_PAGE_TABLE_TYPE_FLAT));
+
+		/* disable all other contexts */
+		for (i = 1; i < 8; i++)
+			IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
+
+		/* setup the page table aperture */
+		IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
+				dev_priv->gart_info.bus_addr);
+		IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR,
+				dev_priv->gart_vm_start);
+		IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR,
+				(dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+		IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
+
+		/* setup the system aperture */
+		IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR,
+				dev_priv->gart_vm_start);
+		IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR,
+				(dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+
+		/* enable page tables */
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT));
+
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+		IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES));
+
+		/* invalidate the cache */
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+		temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+		temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+		temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+	} else {
+		IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0);
+		temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+		temp &= ~RS600_ENABLE_PAGE_TABLES;
+		IGP_WRITE_MCIND(RS600_MC_CNTL1, temp);
+	}
+}
+
 static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
 {
 	u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -779,6 +965,11 @@ static void radeon_set_pcigart(drm_radeo
 		return;
 	}
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+		rs600_set_igpgart(dev_priv, on);
+		return;
+	}
+
 	if (dev_priv->flags & RADEON_IS_PCIE) {
 		radeon_set_pciegart(dev_priv, on);
 		return;
@@ -810,6 +1001,46 @@ static void radeon_set_pcigart(drm_radeo
 	}
 }
 
+static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv)
+{
+	struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+	struct radeon_virt_surface *vp;
+	int i;
+
+	for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) {
+		if (!dev_priv->virt_surfaces[i].file_priv ||
+		    dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV)
+			break;
+	}
+	if (i >= 2 * RADEON_MAX_SURFACES)
+		return -ENOMEM;
+	vp = &dev_priv->virt_surfaces[i];
+
+	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+		struct radeon_surface *sp = &dev_priv->surfaces[i];
+		if (sp->refcount)
+			continue;
+
+		vp->surface_index = i;
+		vp->lower = gart_info->bus_addr;
+		vp->upper = vp->lower + gart_info->table_size;
+		vp->flags = 0;
+		vp->file_priv = PCIGART_FILE_PRIV;
+
+		sp->refcount = 1;
+		sp->lower = vp->lower;
+		sp->upper = vp->upper;
+		sp->flags = 0;
+
+		RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags);
+		RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower);
+		RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper);
+		return 0;
+	}
+
+	return -ENOMEM;
+}
+
 static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 			     struct drm_file *file_priv)
 {
@@ -991,11 +1222,12 @@ static int radeon_do_init_cp(struct drm_
 	} else
 #endif
 	{
-		dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+		dev_priv->cp_ring->handle =
+			(void *)(unsigned long)dev_priv->cp_ring->offset;
 		dev_priv->ring_rptr->handle =
-		    (void *)dev_priv->ring_rptr->offset;
+			(void *)(unsigned long)dev_priv->ring_rptr->offset;
 		dev->agp_buffer_map->handle =
-		    (void *)dev->agp_buffer_map->offset;
+			(void *)(unsigned long)dev->agp_buffer_map->offset;
 
 		DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
 			  dev_priv->cp_ring->handle);
@@ -1102,11 +1334,14 @@ static int radeon_do_init_cp(struct drm_
 	} else
 #endif
 	{
+		u32 sctrl;
+		int ret;
+
 		dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
 		/* if we have an offset set from userspace */
 		if (dev_priv->pcigart_offset_set) {
 			dev_priv->gart_info.bus_addr =
-			    dev_priv->pcigart_offset + dev_priv->fb_location;
+				(resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location;
 			dev_priv->gart_info.mapping.offset =
 			    dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
 			dev_priv->gart_info.mapping.size =
@@ -1143,12 +1378,31 @@ static int radeon_do_init_cp(struct drm_
 			}
 		}
 
-		if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+		sctrl = RADEON_READ(RADEON_SURFACE_CNTL);
+		RADEON_WRITE(RADEON_SURFACE_CNTL, 0);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+			ret = r600_page_table_init(dev);
+		else
+			ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info);
+		RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl);
+
+		if (!ret) {
 			DRM_ERROR("failed to init PCI GART!\n");
 			radeon_do_cleanup_cp(dev);
 			return -ENOMEM;
 		}
 
+		ret = radeon_setup_pcigart_surface(dev_priv);
+		if (ret) {
+			DRM_ERROR("failed to setup GART surface!\n");
+			if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+				r600_page_table_cleanup(dev, &dev_priv->gart_info);
+			else
+				drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info);
+			radeon_do_cleanup_cp(dev);
+			return ret;
+		}
+
 		/* Turn on PCI GART */
 		radeon_set_pcigart(dev_priv, 1);
 	}
@@ -1197,14 +1451,18 @@ static int radeon_do_cleanup_cp(struct d
 		if (dev_priv->gart_info.bus_addr) {
 			/* Turn off PCI GART */
 			radeon_set_pcigart(dev_priv, 0);
-			if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
-				DRM_ERROR("failed to cleanup PCI GART!\n");
+			if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+				r600_page_table_cleanup(dev, &dev_priv->gart_info);
+			else {
+				if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
+					DRM_ERROR("failed to cleanup PCI GART!\n");
+			}
 		}
 
 		if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
 		{
 			drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
-			dev_priv->gart_info.addr = 0;
+			dev_priv->gart_info.addr = NULL;
 		}
 	}
 	/* only clear to the start of flags */
@@ -1255,6 +1513,7 @@ static int radeon_do_resume_cp(struct dr
 
 int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
+	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_init_t *init = data;
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1267,8 +1526,13 @@ int radeon_cp_init(struct drm_device *de
 	case RADEON_INIT_R200_CP:
 	case RADEON_INIT_R300_CP:
 		return radeon_do_init_cp(dev, init, file_priv);
+	case RADEON_INIT_R600_CP:
+		return r600_do_init_cp(dev, init, file_priv);
 	case RADEON_CLEANUP_CP:
-		return radeon_do_cleanup_cp(dev);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			return r600_do_cleanup_cp(dev);
+		else
+			return radeon_do_cleanup_cp(dev);
 	}
 
 	return -EINVAL;
@@ -1291,7 +1555,10 @@ int radeon_cp_start(struct drm_device *d
 		return 0;
 	}
 
-	radeon_do_cp_start(dev_priv);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_do_cp_start(dev_priv);
+	else
+		radeon_do_cp_start(dev_priv);
 
 	return 0;
 }
@@ -1322,7 +1589,10 @@ int radeon_cp_stop(struct drm_device *de
 	 * code so that the DRM ioctl wrapper can try again.
 	 */
 	if (stop->idle) {
-		ret = radeon_do_cp_idle(dev_priv);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			ret = r600_do_cp_idle(dev_priv);
+		else
+			ret = radeon_do_cp_idle(dev_priv);
 		if (ret)
 			return ret;
 	}
@@ -1331,10 +1601,16 @@ int radeon_cp_stop(struct drm_device *de
 	 * we will get some dropped triangles as they won't be fully
 	 * rendered before the CP is shut down.
 	 */
-	radeon_do_cp_stop(dev_priv);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_do_cp_stop(dev_priv);
+	else
+		radeon_do_cp_stop(dev_priv);
 
 	/* Reset the engine */
-	radeon_do_engine_reset(dev);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_do_engine_reset(dev);
+	else
+		radeon_do_engine_reset(dev);
 
 	return 0;
 }
@@ -1347,29 +1623,47 @@ void radeon_do_release(struct drm_device
 	if (dev_priv) {
 		if (dev_priv->cp_running) {
 			/* Stop the cp */
-			while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
-				DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+			if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+				while ((ret = r600_do_cp_idle(dev_priv)) != 0) {
+					DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
 #ifdef __linux__
-				schedule();
+					schedule();
 #else
-				tsleep(&ret, PZERO, "rdnrel", 1);
+					tsleep(&ret, PZERO, "rdnrel", 1);
+#endif
+				}
+			} else {
+				while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
+					DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+#ifdef __linux__
+					schedule();
+#else
+					tsleep(&ret, PZERO, "rdnrel", 1);
 #endif
+				}
+			}
+			if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+				r600_do_cp_stop(dev_priv);
+				r600_do_engine_reset(dev);
+			} else {
+				radeon_do_cp_stop(dev_priv);
+				radeon_do_engine_reset(dev);
 			}
-			radeon_do_cp_stop(dev_priv);
-			radeon_do_engine_reset(dev);
 		}
 
-		/* Disable *all* interrupts */
-		if (dev_priv->mmio)	/* remove this after permanent addmaps */
-			RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) {
+			/* Disable *all* interrupts */
+			if (dev_priv->mmio)	/* remove this after permanent addmaps */
+				RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
 
-		if (dev_priv->mmio) {	/* remove all surfaces */
-			for (i = 0; i < RADEON_MAX_SURFACES; i++) {
-				RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
-				RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
-					     16 * i, 0);
-				RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
-					     16 * i, 0);
+			if (dev_priv->mmio) {	/* remove all surfaces */
+				for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+					RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
+					RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
+						     16 * i, 0);
+					RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
+						     16 * i, 0);
+				}
 			}
 		}
 
@@ -1378,7 +1672,10 @@ void radeon_do_release(struct drm_device
 		radeon_mem_takedown(&(dev_priv->fb_heap));
 
 		/* deallocate kernel resources */
-		radeon_do_cleanup_cp(dev);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			r600_do_cleanup_cp(dev);
+		else
+			radeon_do_cleanup_cp(dev);
 	}
 }
 
@@ -1396,7 +1693,10 @@ int radeon_cp_reset(struct drm_device *d
 		return -EINVAL;
 	}
 
-	radeon_do_cp_reset(dev_priv);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_do_cp_reset(dev_priv);
+	else
+		radeon_do_cp_reset(dev_priv);
 
 	/* The CP is no longer running after an engine reset */
 	dev_priv->cp_running = 0;
@@ -1411,23 +1711,36 @@ int radeon_cp_idle(struct drm_device *de
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	return radeon_do_cp_idle(dev_priv);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return r600_do_cp_idle(dev_priv);
+	else
+		return radeon_do_cp_idle(dev_priv);
 }
 
 /* Added by Charl P. Botha to call radeon_do_resume_cp().
  */
 int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-	return radeon_do_resume_cp(dev, file_priv);
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	DRM_DEBUG("\n");
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return r600_do_resume_cp(dev, file_priv);
+	else
+		return radeon_do_resume_cp(dev, file_priv);
 }
 
 int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
+	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG("\n");
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	return radeon_do_engine_reset(dev);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return r600_do_engine_reset(dev);
+	else
+		return radeon_do_engine_reset(dev);
 }
 
 /* ================================================================
@@ -1477,7 +1790,7 @@ struct drm_buf *radeon_freelist_get(stru
 	start = dev_priv->last_buf;
 
 	for (t = 0; t < dev_priv->usec_timeout; t++) {
-		u32 done_age = GET_SCRATCH(1);
+		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];
@@ -1511,8 +1824,9 @@ struct drm_buf *radeon_freelist_get(stru
 	struct drm_buf *buf;
 	int i, t;
 	int start;
-	u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+	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;
 
@@ -1783,3 +2097,41 @@ int radeon_driver_unload(struct drm_devi
 	dev->dev_private = NULL;
 	return 0;
 }
+
+void radeon_commit_ring(drm_radeon_private_t *dev_priv)
+{
+	int i;
+	u32 *ring;
+	int tail_aligned;
+
+	/* check if the ring is padded out to 16-dword alignment */
+
+	tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1);
+	if (tail_aligned) {
+		int num_p2 = RADEON_RING_ALIGN - tail_aligned;
+
+		ring = dev_priv->ring.start;
+		/* pad with some CP_PACKET2 */
+		for (i = 0; i < num_p2; i++)
+			ring[dev_priv->ring.tail + i] = CP_PACKET2();
+
+		dev_priv->ring.tail += i;
+
+		dev_priv->ring.space -= num_p2 * sizeof(u32);
+	}
+
+	dev_priv->ring.tail &= dev_priv->ring.tail_mask;
+
+	DRM_MEMORYBARRIER();
+	GET_RING_HEAD( dev_priv );
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+		RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
+		/* read from PCI bus to ensure correct posting */
+		RADEON_READ(R600_CP_RB_RPTR);
+	} else {
+		RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
+		/* read from PCI bus to ensure correct posting */
+		RADEON_READ(RADEON_CP_RB_RPTR);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_drv.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_drv.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_drv.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,23 +41,15 @@ int radeon_no_wb;
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
 
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
-	drm_radeon_private_t *dev_priv = dev->dev_private;
-	int family = dev_priv->flags & RADEON_FAMILY_MASK;
-
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-		        (family < CHIP_R200) ? "radeon" :
-		        ((family < CHIP_R300) ? "r200" :
-		        "r300"));
-}
-
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return 0;
+
 	/* Disable *all* interrupts */
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
 	return 0;
@@ -67,8 +59,11 @@ static int radeon_resume(struct drm_devi
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return 0;
+
 	/* Restore interrupt registers */
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
 	RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
 	return 0;
@@ -95,7 +90,6 @@ static struct drm_driver driver = {
 	.get_vblank_counter = radeon_get_vblank_counter,
 	.enable_vblank = radeon_enable_vblank,
 	.disable_vblank = radeon_disable_vblank,
-	.dri_library_name = dri_library_name,
 	.master_create = radeon_master_create,
 	.master_destroy = radeon_master_destroy,
 	.irq_preinstall = radeon_driver_irq_preinstall,
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_drv.h linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_drv.h
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_drv.h	2009-06-09 23:05:27.000000000 -0400
@@ -99,9 +99,10 @@
  * 1.27- Add support for IGP GART
  * 1.28- Add support for VBL on CRTC2
  * 1.29- R500 3D cmd buffer support
+ * 1.30- Add support for occlusion queries
  */
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		29
+#define DRIVER_MINOR		30
 #define DRIVER_PATCHLEVEL	0
 
 /*
@@ -126,6 +127,7 @@ enum radeon_family {
 	CHIP_RV410,
 	CHIP_RS400,
 	CHIP_RS480,
+	CHIP_RS600,
 	CHIP_RS690,
 	CHIP_RS740,
 	CHIP_RV515,
@@ -134,6 +136,16 @@ enum radeon_family {
 	CHIP_RV560,
 	CHIP_RV570,
 	CHIP_R580,
+	CHIP_R600,
+	CHIP_RV610,
+	CHIP_RV630,
+	CHIP_RV620,
+	CHIP_RV635,
+	CHIP_RV670,
+	CHIP_RS780,
+	CHIP_RV770,
+	CHIP_RV730,
+	CHIP_RV710,
 	CHIP_LAST,
 };
 
@@ -160,10 +172,6 @@ enum radeon_chip_flags {
 	RADEON_IS_IGPGART = 0x01000000UL,
 };
 
-#define GET_RING_HEAD(dev_priv)	(dev_priv->writeback_works ? \
-        DRM_READ32(  (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
-#define SET_RING_HEAD(dev_priv,val)	DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
-
 typedef struct drm_radeon_freelist {
 	unsigned int age;
 	struct drm_buf *buf;
@@ -221,10 +229,11 @@ struct radeon_virt_surface {
 	u32 upper;
 	u32 flags;
 	struct drm_file *file_priv;
+#define PCIGART_FILE_PRIV	((void *) -1L)
 };
 
-#define RADEON_FLUSH_EMITED	(1 < 0)
-#define RADEON_PURGE_EMITED	(1 < 1)
+#define RADEON_FLUSH_EMITED	(1 << 0)
+#define RADEON_PURGE_EMITED	(1 << 1)
 
 struct drm_radeon_master_private {
 	drm_local_map_t *sarea;
@@ -248,7 +257,6 @@ typedef struct drm_radeon_private {
 	drm_radeon_freelist_t *head;
 	drm_radeon_freelist_t *tail;
 	int last_buf;
-	volatile u32 *scratch;
 	int writeback_works;
 
 	int usec_timeout;
@@ -316,11 +324,31 @@ typedef struct drm_radeon_private {
 
 	/* starting from here on, data is preserved accross an open */
 	uint32_t flags;		/* see radeon_chip_flags */
-	unsigned long fb_aper_offset;
+	resource_size_t fb_aper_offset;
 
 	int num_gb_pipes;
 	int track_flush;
 	drm_local_map_t *mmio;
+
+	/* r6xx/r7xx pipe/shader config */
+	int r600_max_pipes;
+	int r600_max_tile_pipes;
+	int r600_max_simds;
+	int r600_max_backends;
+	int r600_max_gprs;
+	int r600_max_threads;
+	int r600_max_stack_entries;
+	int r600_max_hw_contexts;
+	int r600_max_gs_threads;
+	int r600_sx_max_export_size;
+	int r600_sx_max_export_pos_size;
+	int r600_sx_max_export_smx_size;
+	int r600_sq_num_cf_insts;
+	int r700_sx_num_of_sets;
+	int r700_sc_prim_fifo_size;
+	int r700_sc_hiz_tile_fifo_size;
+	int r700_sc_earlyz_tile_fifo_fize;
+
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -338,6 +366,12 @@ extern int radeon_no_wb;
 extern struct drm_ioctl_desc radeon_ioctls[];
 extern int radeon_max_ioctl;
 
+extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv);
+extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val);
+
+#define GET_RING_HEAD(dev_priv)	radeon_get_ring_head(dev_priv)
+#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val)
+
 /* Check whether the given hardware address is inside the framebuffer or the
  * GART area.
  */
@@ -364,6 +398,9 @@ extern int radeon_engine_reset(struct dr
 extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
+extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc);
+extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base);
+extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr);
 
 extern void radeon_freelist_reset(struct drm_device * dev);
 extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
@@ -383,6 +420,10 @@ extern void radeon_mem_takedown(struct m
 extern void radeon_mem_release(struct drm_file *file_priv,
 			       struct mem_block *heap);
 
+extern void radeon_enable_bm(struct drm_radeon_private *dev_priv);
+extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off);
+extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val);
+
 				/* radeon_irq.c */
 extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
 extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -423,6 +464,21 @@ extern int r300_do_cp_cmdbuf(struct drm_
 			     struct drm_file *file_priv,
 			     drm_radeon_kcmd_buffer_t *cmdbuf);
 
+/* r600_cp.c */
+extern int r600_do_engine_reset(struct drm_device *dev);
+extern int r600_do_cleanup_cp(struct drm_device *dev);
+extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+			   struct drm_file *file_priv);
+extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv);
+extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_start(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv);
+extern int r600_cp_dispatch_indirect(struct drm_device *dev,
+				     struct drm_buf *buf, int start, int end);
+extern int r600_page_table_init(struct drm_device *dev);
+extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
@@ -434,6 +490,8 @@ extern int r300_do_cp_cmdbuf(struct drm_
 /* Register definitions, register access macros and drmAddMap constants
  * for Radeon kernel driver.
  */
+#define RADEON_MM_INDEX		        0x0000
+#define RADEON_MM_DATA		        0x0004
 
 #define RADEON_AGP_COMMAND		0x0f60
 #define RADEON_AGP_COMMAND_PCI_CONFIG   0x0060	/* offset in PCI config */
@@ -556,6 +614,56 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #define RS690_MC_AGP_BASE               0x102
 #define RS690_MC_AGP_BASE_2             0x103
 
+#define RS600_MC_INDEX                          0x70
+#       define RS600_MC_ADDR_MASK               0xffff
+#       define RS600_MC_IND_SEQ_RBS_0           (1 << 16)
+#       define RS600_MC_IND_SEQ_RBS_1           (1 << 17)
+#       define RS600_MC_IND_SEQ_RBS_2           (1 << 18)
+#       define RS600_MC_IND_SEQ_RBS_3           (1 << 19)
+#       define RS600_MC_IND_AIC_RBS             (1 << 20)
+#       define RS600_MC_IND_CITF_ARB0           (1 << 21)
+#       define RS600_MC_IND_CITF_ARB1           (1 << 22)
+#       define RS600_MC_IND_WR_EN               (1 << 23)
+#define RS600_MC_DATA                           0x74
+
+#define RS600_MC_STATUS                         0x0
+#       define RS600_MC_IDLE                    (1 << 1)
+#define RS600_MC_FB_LOCATION                    0x4
+#define RS600_MC_AGP_LOCATION                   0x5
+#define RS600_AGP_BASE                          0x6
+#define RS600_AGP_BASE_2                        0x7
+#define RS600_MC_CNTL1                          0x9
+#       define RS600_ENABLE_PAGE_TABLES         (1 << 26)
+#define RS600_MC_PT0_CNTL                       0x100
+#       define RS600_ENABLE_PT                  (1 << 0)
+#       define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15)
+#       define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21)
+#       define RS600_INVALIDATE_ALL_L1_TLBS     (1 << 28)
+#       define RS600_INVALIDATE_L2_CACHE        (1 << 29)
+#define RS600_MC_PT0_CONTEXT0_CNTL              0x102
+#       define RS600_ENABLE_PAGE_TABLE          (1 << 0)
+#       define RS600_PAGE_TABLE_TYPE_FLAT       (0 << 1)
+#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR   0x112
+#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR  0x114
+#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c
+#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR    0x12c
+#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR   0x13c
+#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR     0x14c
+#define RS600_MC_PT0_CLIENT0_CNTL               0x16c
+#       define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE       (1 << 0)
+#       define RS600_TRANSLATION_MODE_OVERRIDE              (1 << 1)
+#       define RS600_SYSTEM_ACCESS_MODE_MASK                (3 << 8)
+#       define RS600_SYSTEM_ACCESS_MODE_PA_ONLY             (0 << 8)
+#       define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP         (1 << 8)
+#       define RS600_SYSTEM_ACCESS_MODE_IN_SYS              (2 << 8)
+#       define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS          (3 << 8)
+#       define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH        (0 << 10)
+#       define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE       (1 << 10)
+#       define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11)
+#       define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14)
+#       define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
+#       define RS600_INVALIDATE_L1_TLB          (1 << 20)
+
 #define R520_MC_IND_INDEX 0x70
 #define R520_MC_IND_WR_EN (1 << 24)
 #define R520_MC_IND_DATA  0x74
@@ -580,7 +688,6 @@ extern int r300_do_cp_cmdbuf(struct drm_
 /* pipe config regs */
 #define R400_GB_PIPE_SELECT             0x402c
 #define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
-#define R500_SU_REG_DEST                0x42c8
 #define R300_GB_TILE_CONFIG             0x4018
 #       define R300_ENABLE_TILING       (1 << 0)
 #       define R300_PIPE_COUNT_RV350    (0 << 1)
@@ -639,9 +746,22 @@ extern int r300_do_cp_cmdbuf(struct drm_
 
 #define RADEON_SCRATCHOFF( x )		(RADEON_SCRATCH_REG_OFFSET + 4*(x))
 
-#define GET_SCRATCH( x )	(dev_priv->writeback_works			\
-				? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
-				: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
+
+#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x)
+
+#define R600_SCRATCH_REG0		0x8500
+#define R600_SCRATCH_REG1		0x8504
+#define R600_SCRATCH_REG2		0x8508
+#define R600_SCRATCH_REG3		0x850c
+#define R600_SCRATCH_REG4		0x8510
+#define R600_SCRATCH_REG5		0x8514
+#define R600_SCRATCH_REG6		0x8518
+#define R600_SCRATCH_REG7		0x851c
+#define R600_SCRATCH_UMSK		0x8540
+#define R600_SCRATCH_ADDR		0x8544
+
+#define R600_SCRATCHOFF(x)		(R600_SCRATCH_REG_OFFSET + 4*(x))
 
 #define RADEON_GEN_INT_CNTL		0x0040
 #	define RADEON_CRTC_VBLANK_MASK		(1 << 0)
@@ -922,6 +1042,7 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #define RADEON_CP_RB_CNTL		0x0704
 #	define RADEON_BUF_SWAP_32BIT		(2 << 16)
 #	define RADEON_RB_NO_UPDATE		(1 << 27)
+#	define RADEON_RB_RPTR_WR_ENA		(1 << 31)
 #define RADEON_CP_RB_RPTR_ADDR		0x070c
 #define RADEON_CP_RB_RPTR		0x0710
 #define RADEON_CP_RB_WPTR		0x0714
@@ -983,6 +1104,14 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #	define RADEON_CNTL_BITBLT_MULTI		0x00009B00
 #	define RADEON_CNTL_SET_SCISSORS		0xC0001E00
 
+#	define R600_IT_INDIRECT_BUFFER		0x00003200
+#	define R600_IT_ME_INITIALIZE		0x00004400
+#	       define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
+#	define R600_IT_EVENT_WRITE		0x00004600
+#	define R600_IT_SET_CONFIG_REG		0x00006800
+#	define R600_SET_CONFIG_REG_OFFSET       0x00008000
+#	define R600_SET_CONFIG_REG_END          0x0000ac00
+
 #define RADEON_CP_PACKET_MASK		0xC0000000
 #define RADEON_CP_PACKET_COUNT_MASK	0x3fff0000
 #define RADEON_CP_PACKET0_REG_MASK	0x000007ff
@@ -1181,6 +1310,422 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #define R500_D1_VBLANK_INTERRUPT (1 << 4)
 #define R500_D2_VBLANK_INTERRUPT (1 << 5)
 
+/* R6xx/R7xx registers */
+#define R600_MC_VM_FB_LOCATION                                 0x2180
+#define R600_MC_VM_AGP_TOP                                     0x2184
+#define R600_MC_VM_AGP_BOT                                     0x2188
+#define R600_MC_VM_AGP_BASE                                    0x218c
+#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR                    0x2190
+#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR                   0x2194
+#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR                0x2198
+
+#define R700_MC_VM_FB_LOCATION                                 0x2024
+#define R700_MC_VM_AGP_TOP                                     0x2028
+#define R700_MC_VM_AGP_BOT                                     0x202c
+#define R700_MC_VM_AGP_BASE                                    0x2030
+#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR                    0x2034
+#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR                   0x2038
+#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR                0x203c
+
+#define R600_MCD_RD_A_CNTL                                     0x219c
+#define R600_MCD_RD_B_CNTL                                     0x21a0
+
+#define R600_MCD_WR_A_CNTL                                     0x21a4
+#define R600_MCD_WR_B_CNTL                                     0x21a8
+
+#define R600_MCD_RD_SYS_CNTL                                   0x2200
+#define R600_MCD_WR_SYS_CNTL                                   0x2214
+
+#define R600_MCD_RD_GFX_CNTL                                   0x21fc
+#define R600_MCD_RD_HDP_CNTL                                   0x2204
+#define R600_MCD_RD_PDMA_CNTL                                  0x2208
+#define R600_MCD_RD_SEM_CNTL                                   0x220c
+#define R600_MCD_WR_GFX_CNTL                                   0x2210
+#define R600_MCD_WR_HDP_CNTL                                   0x2218
+#define R600_MCD_WR_PDMA_CNTL                                  0x221c
+#define R600_MCD_WR_SEM_CNTL                                   0x2220
+
+#       define R600_MCD_L1_TLB                                 (1 << 0)
+#       define R600_MCD_L1_FRAG_PROC                           (1 << 1)
+#       define R600_MCD_L1_STRICT_ORDERING                     (1 << 2)
+
+#       define R600_MCD_SYSTEM_ACCESS_MODE_MASK                (3 << 6)
+#       define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY             (0 << 6)
+#       define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP         (1 << 6)
+#       define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS              (2 << 6)
+#       define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS          (3 << 6)
+
+#       define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU    (0 << 8)
+#       define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8)
+
+#       define R600_MCD_SEMAPHORE_MODE                         (1 << 10)
+#       define R600_MCD_WAIT_L2_QUERY                          (1 << 11)
+#       define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x)               ((x) << 12)
+#       define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x)             ((x) << 15)
+
+#define R700_MC_VM_MD_L1_TLB0_CNTL                             0x2654
+#define R700_MC_VM_MD_L1_TLB1_CNTL                             0x2658
+#define R700_MC_VM_MD_L1_TLB2_CNTL                             0x265c
+
+#define R700_MC_VM_MB_L1_TLB0_CNTL                             0x2234
+#define R700_MC_VM_MB_L1_TLB1_CNTL                             0x2238
+#define R700_MC_VM_MB_L1_TLB2_CNTL                             0x223c
+#define R700_MC_VM_MB_L1_TLB3_CNTL                             0x2240
+
+#       define R700_ENABLE_L1_TLB                              (1 << 0)
+#       define R700_ENABLE_L1_FRAGMENT_PROCESSING              (1 << 1)
+#       define R700_SYSTEM_ACCESS_MODE_IN_SYS                  (2 << 3)
+#       define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU  (0 << 5)
+#       define R700_EFFECTIVE_L1_TLB_SIZE(x)                   ((x) << 15)
+#       define R700_EFFECTIVE_L1_QUEUE_SIZE(x)                 ((x) << 18)
+
+#define R700_MC_ARB_RAMCFG                                     0x2760
+#       define R700_NOOFBANK_SHIFT                             0
+#       define R700_NOOFBANK_MASK                              0x3
+#       define R700_NOOFRANK_SHIFT                             2
+#       define R700_NOOFRANK_MASK                              0x1
+#       define R700_NOOFROWS_SHIFT                             3
+#       define R700_NOOFROWS_MASK                              0x7
+#       define R700_NOOFCOLS_SHIFT                             6
+#       define R700_NOOFCOLS_MASK                              0x3
+#       define R700_CHANSIZE_SHIFT                             8
+#       define R700_CHANSIZE_MASK                              0x1
+#       define R700_BURSTLENGTH_SHIFT                          9
+#       define R700_BURSTLENGTH_MASK                           0x1
+#define R600_RAMCFG                                            0x2408
+#       define R600_NOOFBANK_SHIFT                             0
+#       define R600_NOOFBANK_MASK                              0x1
+#       define R600_NOOFRANK_SHIFT                             1
+#       define R600_NOOFRANK_MASK                              0x1
+#       define R600_NOOFROWS_SHIFT                             2
+#       define R600_NOOFROWS_MASK                              0x7
+#       define R600_NOOFCOLS_SHIFT                             5
+#       define R600_NOOFCOLS_MASK                              0x3
+#       define R600_CHANSIZE_SHIFT                             7
+#       define R600_CHANSIZE_MASK                              0x1
+#       define R600_BURSTLENGTH_SHIFT                          8
+#       define R600_BURSTLENGTH_MASK                           0x1
+
+#define R600_VM_L2_CNTL                                        0x1400
+#       define R600_VM_L2_CACHE_EN                             (1 << 0)
+#       define R600_VM_L2_FRAG_PROC                            (1 << 1)
+#       define R600_VM_ENABLE_PTE_CACHE_LRU_W                  (1 << 9)
+#       define R600_VM_L2_CNTL_QUEUE_SIZE(x)                   ((x) << 13)
+#       define R700_VM_L2_CNTL_QUEUE_SIZE(x)                   ((x) << 14)
+
+#define R600_VM_L2_CNTL2                                       0x1404
+#       define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS         (1 << 0)
+#       define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE            (1 << 1)
+#define R600_VM_L2_CNTL3                                       0x1408
+#       define R600_VM_L2_CNTL3_BANK_SELECT_0(x)               ((x) << 0)
+#       define R600_VM_L2_CNTL3_BANK_SELECT_1(x)               ((x) << 5)
+#       define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x)           ((x) << 10)
+#       define R700_VM_L2_CNTL3_BANK_SELECT(x)                 ((x) << 0)
+#       define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x)           ((x) << 6)
+
+#define R600_VM_L2_STATUS                                      0x140c
+
+#define R600_VM_CONTEXT0_CNTL                                  0x1410
+#       define R600_VM_ENABLE_CONTEXT                          (1 << 0)
+#       define R600_VM_PAGE_TABLE_DEPTH_FLAT                   (0 << 1)
+
+#define R600_VM_CONTEXT0_CNTL2                                 0x1430
+#define R600_VM_CONTEXT0_REQUEST_RESPONSE                      0x1470
+#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR                 0x1490
+#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR                0x14b0
+#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR                  0x1574
+#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR                 0x1594
+#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR                   0x15b4
+
+#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR                  0x153c
+#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR                 0x155c
+#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR                   0x157c
+
+#define R600_HDP_HOST_PATH_CNTL                                0x2c00
+
+#define R600_GRBM_CNTL                                         0x8000
+#       define R600_GRBM_READ_TIMEOUT(x)                       ((x) << 0)
+
+#define R600_GRBM_STATUS                                       0x8010
+#       define R600_CMDFIFO_AVAIL_MASK                         0x1f
+#       define R700_CMDFIFO_AVAIL_MASK                         0xf
+#       define R600_GUI_ACTIVE                                 (1 << 31)
+#define R600_GRBM_STATUS2                                      0x8014
+#define R600_GRBM_SOFT_RESET                                   0x8020
+#       define R600_SOFT_RESET_CP                              (1 << 0)
+#define R600_WAIT_UNTIL		                               0x8040
+
+#define R600_CP_SEM_WAIT_TIMER                                 0x85bc
+#define R600_CP_ME_CNTL                                        0x86d8
+#       define R600_CP_ME_HALT                                 (1 << 28)
+#define R600_CP_QUEUE_THRESHOLDS                               0x8760
+#       define R600_ROQ_IB1_START(x)                           ((x) << 0)
+#       define R600_ROQ_IB2_START(x)                           ((x) << 8)
+#define R600_CP_MEQ_THRESHOLDS                                 0x8764
+#       define R700_STQ_SPLIT(x)                               ((x) << 0)
+#       define R600_MEQ_END(x)                                 ((x) << 16)
+#       define R600_ROQ_END(x)                                 ((x) << 24)
+#define R600_CP_PERFMON_CNTL                                   0x87fc
+#define R600_CP_RB_BASE                                        0xc100
+#define R600_CP_RB_CNTL                                        0xc104
+#       define R600_RB_BUFSZ(x)                                ((x) << 0)
+#       define R600_RB_BLKSZ(x)                                ((x) << 8)
+#       define R600_RB_NO_UPDATE                               (1 << 27)
+#       define R600_RB_RPTR_WR_ENA                             (1 << 31)
+#define R600_CP_RB_RPTR_WR                                     0xc108
+#define R600_CP_RB_RPTR_ADDR                                   0xc10c
+#define R600_CP_RB_RPTR_ADDR_HI                                0xc110
+#define R600_CP_RB_WPTR                                        0xc114
+#define R600_CP_RB_WPTR_ADDR                                   0xc118
+#define R600_CP_RB_WPTR_ADDR_HI                                0xc11c
+#define R600_CP_RB_RPTR                                        0x8700
+#define R600_CP_RB_WPTR_DELAY                                  0x8704
+#define R600_CP_PFP_UCODE_ADDR                                 0xc150
+#define R600_CP_PFP_UCODE_DATA                                 0xc154
+#define R600_CP_ME_RAM_RADDR                                   0xc158
+#define R600_CP_ME_RAM_WADDR                                   0xc15c
+#define R600_CP_ME_RAM_DATA                                    0xc160
+#define R600_CP_DEBUG                                          0xc1fc
+
+#define R600_PA_CL_ENHANCE                                     0x8a14
+#       define R600_CLIP_VTX_REORDER_ENA                       (1 << 0)
+#       define R600_NUM_CLIP_SEQ(x)                            ((x) << 1)
+#define R600_PA_SC_LINE_STIPPLE_STATE                          0x8b10
+#define R600_PA_SC_MULTI_CHIP_CNTL                             0x8b20
+#define R700_PA_SC_FORCE_EOV_MAX_CNTS                          0x8b24
+#       define R700_FORCE_EOV_MAX_CLK_CNT(x)                   ((x) << 0)
+#       define R700_FORCE_EOV_MAX_REZ_CNT(x)                   ((x) << 16)
+#define R600_PA_SC_AA_SAMPLE_LOCS_2S                           0x8b40
+#define R600_PA_SC_AA_SAMPLE_LOCS_4S                           0x8b44
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0                       0x8b48
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1                       0x8b4c
+#       define R600_S0_X(x)                                    ((x) << 0)
+#       define R600_S0_Y(x)                                    ((x) << 4)
+#       define R600_S1_X(x)                                    ((x) << 8)
+#       define R600_S1_Y(x)                                    ((x) << 12)
+#       define R600_S2_X(x)                                    ((x) << 16)
+#       define R600_S2_Y(x)                                    ((x) << 20)
+#       define R600_S3_X(x)                                    ((x) << 24)
+#       define R600_S3_Y(x)                                    ((x) << 28)
+#       define R600_S4_X(x)                                    ((x) << 0)
+#       define R600_S4_Y(x)                                    ((x) << 4)
+#       define R600_S5_X(x)                                    ((x) << 8)
+#       define R600_S5_Y(x)                                    ((x) << 12)
+#       define R600_S6_X(x)                                    ((x) << 16)
+#       define R600_S6_Y(x)                                    ((x) << 20)
+#       define R600_S7_X(x)                                    ((x) << 24)
+#       define R600_S7_Y(x)                                    ((x) << 28)
+#define R600_PA_SC_FIFO_SIZE                                   0x8bd0
+#       define R600_SC_PRIM_FIFO_SIZE(x)                       ((x) << 0)
+#       define R600_SC_HIZ_TILE_FIFO_SIZE(x)                   ((x) << 8)
+#       define R600_SC_EARLYZ_TILE_FIFO_SIZE(x)                ((x) << 16)
+#define R700_PA_SC_FIFO_SIZE_R7XX                              0x8bcc
+#       define R700_SC_PRIM_FIFO_SIZE(x)                       ((x) << 0)
+#       define R700_SC_HIZ_TILE_FIFO_SIZE(x)                   ((x) << 12)
+#       define R700_SC_EARLYZ_TILE_FIFO_SIZE(x)                ((x) << 20)
+#define R600_PA_SC_ENHANCE                                     0x8bf0
+#       define R600_FORCE_EOV_MAX_CLK_CNT(x)                   ((x) << 0)
+#       define R600_FORCE_EOV_MAX_TILE_CNT(x)                  ((x) << 12)
+#define R600_PA_SC_CLIPRECT_RULE                               0x2820c
+#define R700_PA_SC_EDGERULE                                    0x28230
+#define R600_PA_SC_LINE_STIPPLE                                0x28a0c
+#define R600_PA_SC_MODE_CNTL                                   0x28a4c
+#define R600_PA_SC_AA_CONFIG                                   0x28c04
+
+#define R600_SX_EXPORT_BUFFER_SIZES                            0x900c
+#       define R600_COLOR_BUFFER_SIZE(x)                       ((x) << 0)
+#       define R600_POSITION_BUFFER_SIZE(x)                    ((x) << 8)
+#       define R600_SMX_BUFFER_SIZE(x)                         ((x) << 16)
+#define R600_SX_DEBUG_1                                        0x9054
+#       define R600_SMX_EVENT_RELEASE                          (1 << 0)
+#       define R600_ENABLE_NEW_SMX_ADDRESS                     (1 << 16)
+#define R700_SX_DEBUG_1                                        0x9058
+#       define R700_ENABLE_NEW_SMX_ADDRESS                     (1 << 16)
+#define R600_SX_MISC                                           0x28350
+
+#define R600_DB_DEBUG                                          0x9830
+#       define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE              (1 << 31)
+#define R600_DB_WATERMARKS                                     0x9838
+#       define R600_DEPTH_FREE(x)                              ((x) << 0)
+#       define R600_DEPTH_FLUSH(x)                             ((x) << 5)
+#       define R600_DEPTH_PENDING_FREE(x)                      ((x) << 15)
+#       define R600_DEPTH_CACHELINE_FREE(x)                    ((x) << 20)
+#define R700_DB_DEBUG3                                         0x98b0
+#       define R700_DB_CLK_OFF_DELAY(x)                        ((x) << 11)
+#define RV700_DB_DEBUG4                                        0x9b8c
+#       define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER          (1 << 6)
+
+#define R600_VGT_CACHE_INVALIDATION                            0x88c4
+#       define R600_CACHE_INVALIDATION(x)                      ((x) << 0)
+#       define R600_VC_ONLY                                    0
+#       define R600_TC_ONLY                                    1
+#       define R600_VC_AND_TC                                  2
+#       define R700_AUTO_INVLD_EN(x)                           ((x) << 6)
+#       define R700_NO_AUTO                                    0
+#       define R700_ES_AUTO                                    1
+#       define R700_GS_AUTO                                    2
+#       define R700_ES_AND_GS_AUTO                             3
+#define R600_VGT_GS_PER_ES                                     0x88c8
+#define R600_VGT_ES_PER_GS                                     0x88cc
+#define R600_VGT_GS_PER_VS                                     0x88e8
+#define R600_VGT_GS_VERTEX_REUSE                               0x88d4
+#define R600_VGT_NUM_INSTANCES                                 0x8974
+#define R600_VGT_STRMOUT_EN                                    0x28ab0
+#define R600_VGT_EVENT_INITIATOR                               0x28a90
+#       define R600_CACHE_FLUSH_AND_INV_EVENT                  (0x16 << 0)
+#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL                       0x28c58
+#       define R600_VTX_REUSE_DEPTH_MASK                       0xff
+#define R600_VGT_OUT_DEALLOC_CNTL                              0x28c5c
+#       define R600_DEALLOC_DIST_MASK                          0x7f
+
+#define R600_CB_COLOR0_BASE                                    0x28040
+#define R600_CB_COLOR1_BASE                                    0x28044
+#define R600_CB_COLOR2_BASE                                    0x28048
+#define R600_CB_COLOR3_BASE                                    0x2804c
+#define R600_CB_COLOR4_BASE                                    0x28050
+#define R600_CB_COLOR5_BASE                                    0x28054
+#define R600_CB_COLOR6_BASE                                    0x28058
+#define R600_CB_COLOR7_BASE                                    0x2805c
+#define R600_CB_COLOR7_FRAG                                    0x280fc
+
+#define R600_TC_CNTL                                           0x9608
+#       define R600_TC_L2_SIZE(x)                              ((x) << 5)
+#       define R600_L2_DISABLE_LATE_HIT                        (1 << 9)
+
+#define R600_ARB_POP                                           0x2418
+#       define R600_ENABLE_TC128                               (1 << 30)
+#define R600_ARB_GDEC_RD_CNTL                                  0x246c
+
+#define R600_TA_CNTL_AUX                                       0x9508
+#       define R600_DISABLE_CUBE_WRAP                          (1 << 0)
+#       define R600_DISABLE_CUBE_ANISO                         (1 << 1)
+#       define R700_GETLOD_SELECT(x)                           ((x) << 2)
+#       define R600_SYNC_GRADIENT                              (1 << 24)
+#       define R600_SYNC_WALKER                                (1 << 25)
+#       define R600_SYNC_ALIGNER                               (1 << 26)
+#       define R600_BILINEAR_PRECISION_6_BIT                   (0 << 31)
+#       define R600_BILINEAR_PRECISION_8_BIT                   (1 << 31)
+
+#define R700_TCP_CNTL                                          0x9610
+
+#define R600_SMX_DC_CTL0                                       0xa020
+#       define R700_USE_HASH_FUNCTION                          (1 << 0)
+#       define R700_CACHE_DEPTH(x)                             ((x) << 1)
+#       define R700_FLUSH_ALL_ON_EVENT                         (1 << 10)
+#       define R700_STALL_ON_EVENT                             (1 << 11)
+#define R700_SMX_EVENT_CTL                                     0xa02c
+#       define R700_ES_FLUSH_CTL(x)                            ((x) << 0)
+#       define R700_GS_FLUSH_CTL(x)                            ((x) << 3)
+#       define R700_ACK_FLUSH_CTL(x)                           ((x) << 6)
+#       define R700_SYNC_FLUSH_CTL                             (1 << 8)
+
+#define R600_SQ_CONFIG                                         0x8c00
+#       define R600_VC_ENABLE                                  (1 << 0)
+#       define R600_EXPORT_SRC_C                               (1 << 1)
+#       define R600_DX9_CONSTS                                 (1 << 2)
+#       define R600_ALU_INST_PREFER_VECTOR                     (1 << 3)
+#       define R600_DX10_CLAMP                                 (1 << 4)
+#       define R600_CLAUSE_SEQ_PRIO(x)                         ((x) << 8)
+#       define R600_PS_PRIO(x)                                 ((x) << 24)
+#       define R600_VS_PRIO(x)                                 ((x) << 26)
+#       define R600_GS_PRIO(x)                                 ((x) << 28)
+#       define R600_ES_PRIO(x)                                 ((x) << 30)
+#define R600_SQ_GPR_RESOURCE_MGMT_1                            0x8c04
+#       define R600_NUM_PS_GPRS(x)                             ((x) << 0)
+#       define R600_NUM_VS_GPRS(x)                             ((x) << 16)
+#       define R700_DYN_GPR_ENABLE                             (1 << 27)
+#       define R600_NUM_CLAUSE_TEMP_GPRS(x)                    ((x) << 28)
+#define R600_SQ_GPR_RESOURCE_MGMT_2                            0x8c08
+#       define R600_NUM_GS_GPRS(x)                             ((x) << 0)
+#       define R600_NUM_ES_GPRS(x)                             ((x) << 16)
+#define R600_SQ_THREAD_RESOURCE_MGMT                           0x8c0c
+#       define R600_NUM_PS_THREADS(x)                          ((x) << 0)
+#       define R600_NUM_VS_THREADS(x)                          ((x) << 8)
+#       define R600_NUM_GS_THREADS(x)                          ((x) << 16)
+#       define R600_NUM_ES_THREADS(x)                          ((x) << 24)
+#define R600_SQ_STACK_RESOURCE_MGMT_1                          0x8c10
+#       define R600_NUM_PS_STACK_ENTRIES(x)                    ((x) << 0)
+#       define R600_NUM_VS_STACK_ENTRIES(x)                    ((x) << 16)
+#define R600_SQ_STACK_RESOURCE_MGMT_2                          0x8c14
+#       define R600_NUM_GS_STACK_ENTRIES(x)                    ((x) << 0)
+#       define R600_NUM_ES_STACK_ENTRIES(x)                    ((x) << 16)
+#define R600_SQ_MS_FIFO_SIZES                                  0x8cf0
+#       define R600_CACHE_FIFO_SIZE(x)                         ((x) << 0)
+#       define R600_FETCH_FIFO_HIWATER(x)                      ((x) << 8)
+#       define R600_DONE_FIFO_HIWATER(x)                       ((x) << 16)
+#       define R600_ALU_UPDATE_FIFO_HIWATER(x)                 ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0                         0x8db0
+#       define R700_SIMDA_RING0(x)                             ((x) << 0)
+#       define R700_SIMDA_RING1(x)                             ((x) << 8)
+#       define R700_SIMDB_RING0(x)                             ((x) << 16)
+#       define R700_SIMDB_RING1(x)                             ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1                         0x8db4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2                         0x8db8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3                         0x8dbc
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4                         0x8dc0
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5                         0x8dc4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6                         0x8dc8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7                         0x8dcc
+
+#define R600_SPI_PS_IN_CONTROL_0                               0x286cc
+#       define R600_NUM_INTERP(x)                              ((x) << 0)
+#       define R600_POSITION_ENA                               (1 << 8)
+#       define R600_POSITION_CENTROID                          (1 << 9)
+#       define R600_POSITION_ADDR(x)                           ((x) << 10)
+#       define R600_PARAM_GEN(x)                               ((x) << 15)
+#       define R600_PARAM_GEN_ADDR(x)                          ((x) << 19)
+#       define R600_BARYC_SAMPLE_CNTL(x)                       ((x) << 26)
+#       define R600_PERSP_GRADIENT_ENA                         (1 << 28)
+#       define R600_LINEAR_GRADIENT_ENA                        (1 << 29)
+#       define R600_POSITION_SAMPLE                            (1 << 30)
+#       define R600_BARYC_AT_SAMPLE_ENA                        (1 << 31)
+#define R600_SPI_PS_IN_CONTROL_1                               0x286d0
+#       define R600_GEN_INDEX_PIX                              (1 << 0)
+#       define R600_GEN_INDEX_PIX_ADDR(x)                      ((x) << 1)
+#       define R600_FRONT_FACE_ENA                             (1 << 8)
+#       define R600_FRONT_FACE_CHAN(x)                         ((x) << 9)
+#       define R600_FRONT_FACE_ALL_BITS                        (1 << 11)
+#       define R600_FRONT_FACE_ADDR(x)                         ((x) << 12)
+#       define R600_FOG_ADDR(x)                                ((x) << 17)
+#       define R600_FIXED_PT_POSITION_ENA                      (1 << 24)
+#       define R600_FIXED_PT_POSITION_ADDR(x)                  ((x) << 25)
+#       define R700_POSITION_ULC                               (1 << 30)
+#define R600_SPI_INPUT_Z                                       0x286d8
+
+#define R600_SPI_CONFIG_CNTL                                   0x9100
+#       define R600_GPR_WRITE_PRIORITY(x)                      ((x) << 0)
+#       define R600_DISABLE_INTERP_1                           (1 << 5)
+#define R600_SPI_CONFIG_CNTL_1                                 0x913c
+#       define R600_VTX_DONE_DELAY(x)                          ((x) << 0)
+#       define R600_INTERP_ONE_PRIM_PER_ROW                    (1 << 4)
+
+#define R600_GB_TILING_CONFIG                                  0x98f0
+#       define R600_PIPE_TILING(x)                             ((x) << 1)
+#       define R600_BANK_TILING(x)                             ((x) << 4)
+#       define R600_GROUP_SIZE(x)                              ((x) << 6)
+#       define R600_ROW_TILING(x)                              ((x) << 8)
+#       define R600_BANK_SWAPS(x)                              ((x) << 11)
+#       define R600_SAMPLE_SPLIT(x)                            ((x) << 14)
+#       define R600_BACKEND_MAP(x)                             ((x) << 16)
+#define R600_DCP_TILING_CONFIG                                 0x6ca0
+#define R600_HDP_TILING_CONFIG                                 0x2f3c
+
+#define R600_CC_RB_BACKEND_DISABLE                             0x98f4
+#define R700_CC_SYS_RB_BACKEND_DISABLE                         0x3f88
+#       define R600_BACKEND_DISABLE(x)                         ((x) << 16)
+
+#define R600_CC_GC_SHADER_PIPE_CONFIG                          0x8950
+#define R600_GC_USER_SHADER_PIPE_CONFIG                        0x8954
+#       define R600_INACTIVE_QD_PIPES(x)                       ((x) << 8)
+#       define R600_INACTIVE_QD_PIPES_MASK                     (0xff << 8)
+#       define R600_INACTIVE_SIMDS(x)                          ((x) << 16)
+#       define R600_INACTIVE_SIMDS_MASK                        (0xff << 16)
+
+#define R700_CGTS_SYS_TCC_DISABLE                              0x3f90
+#define R700_CGTS_USER_SYS_TCC_DISABLE                         0x3f94
+#define R700_CGTS_TCC_DISABLE                                  0x9148
+#define R700_CGTS_USER_TCC_DISABLE                             0x914c
+
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */
 
@@ -1190,6 +1735,11 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #define RADEON_LAST_SWI_REG		RADEON_SCRATCH_REG3
 #define RADEON_LAST_DISPATCH		1
 
+#define R600_LAST_FRAME_REG		R600_SCRATCH_REG0
+#define R600_LAST_DISPATCH_REG	        R600_SCRATCH_REG1
+#define R600_LAST_CLEAR_REG		R600_SCRATCH_REG2
+#define R600_LAST_SWI_REG		R600_SCRATCH_REG3
+
 #define RADEON_MAX_VB_AGE		0x7fffffff
 #define RADEON_MAX_VB_VERTS		(0xffff)
 
@@ -1198,7 +1748,15 @@ extern int r300_do_cp_cmdbuf(struct drm_
 #define RADEON_PCIGART_TABLE_SIZE      (32*1024)
 
 #define RADEON_READ(reg)	DRM_READ32(  dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val)	DRM_WRITE32( dev_priv->mmio, (reg), (val) )
+#define RADEON_WRITE(reg, val)                                          \
+do {									\
+	if (reg < 0x10000) {				                \
+		DRM_WRITE32(dev_priv->mmio, (reg), (val));		\
+	} else {                                                        \
+		DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg));	\
+		DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val));	\
+	}                                                               \
+} while (0)
 #define RADEON_READ8(reg)	DRM_READ8(  dev_priv->mmio, (reg) )
 #define RADEON_WRITE8(reg,val)	DRM_WRITE8( dev_priv->mmio, (reg), (val) )
 
@@ -1238,11 +1796,19 @@ do {								\
 	RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);	\
 } while (0)
 
+#define RS600_WRITE_MCIND(addr, val)				\
+do {							        \
+	RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \
+	RADEON_WRITE(RS600_MC_DATA, val);                       \
+} while (0)
+
 #define IGP_WRITE_MCIND(addr, val)				\
 do {									\
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||   \
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))      \
 		RS690_WRITE_MCIND(addr, val);				\
+	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)  \
+		RS600_WRITE_MCIND(addr, val);				\
 	else								\
 		RS480_WRITE_MCIND(addr, val);				\
 } while (0)
@@ -1346,7 +1912,11 @@ do {								\
 	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;	\
 	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;	\
 	if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) {		\
-		int __ret = radeon_do_cp_idle( dev_priv );		\
+		int __ret;						\
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \
+			__ret = r600_do_cp_idle(dev_priv);		\
+		else							\
+			__ret = radeon_do_cp_idle(dev_priv);		\
 		if ( __ret ) return __ret;				\
 		sarea_priv->last_dispatch = 0;				\
 		radeon_freelist_reset( dev );				\
@@ -1368,21 +1938,43 @@ do {								\
 	OUT_RING( age );						\
 } while (0)
 
+#define R600_DISPATCH_AGE(age) do {					\
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));		\
+	OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2);  \
+	OUT_RING(age);							\
+} while (0)
+
+#define R600_FRAME_AGE(age) do {					\
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));		\
+	OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2);  \
+	OUT_RING(age);							\
+} while (0)
+
+#define R600_CLEAR_AGE(age) do {					\
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));		\
+	OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2);  \
+	OUT_RING(age);							\
+} while (0)
+
 /* ================================================================
  * Ring control
  */
 
 #define RADEON_VERBOSE	0
 
-#define RING_LOCALS	int write, _nr; unsigned int mask; u32 *ring;
+#define RING_LOCALS	int write, _nr, _align_nr; unsigned int mask; u32 *ring;
+
+#define RADEON_RING_ALIGN 16
 
 #define BEGIN_RING( n ) do {						\
 	if ( RADEON_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_RING( %d )\n", (n));			\
 	}								\
-	if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {		\
+	_align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1));	\
+	_align_nr += n;							\
+	if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) {	\
                 COMMIT_RING();						\
-		radeon_wait_ring( dev_priv, (n) * sizeof(u32) );	\
+		radeon_wait_ring( dev_priv, _align_nr * sizeof(u32));	\
 	}								\
 	_nr = n; dev_priv->ring.space -= (n) * sizeof(u32);		\
 	ring = dev_priv->ring.start;					\
@@ -1399,19 +1991,16 @@ do {								\
 		DRM_ERROR(						\
 			"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n",	\
 			((dev_priv->ring.tail + _nr) & mask),		\
-			write, __LINE__);						\
+			write, __LINE__);				\
 	} else								\
 		dev_priv->ring.tail = write;				\
 } while (0)
 
+extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);
+
 #define COMMIT_RING() do {						\
-	/* Flush writes to ring */					\
-	DRM_MEMORYBARRIER();						\
-	GET_RING_HEAD( dev_priv );					\
-	RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );		\
-	/* read from PCI bus to ensure correct posting */		\
-	RADEON_READ( RADEON_CP_RB_RPTR );				\
-} while (0)
+		radeon_commit_ring(dev_priv);				\
+	} while(0)
 
 #define OUT_RING( x ) do {						\
 	if ( RADEON_VERBOSE ) {						\
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_irq.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_irq.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,7 @@ int radeon_enable_vblank(struct drm_devi
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
 		switch (crtc) {
 		case 0:
 			r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
@@ -100,7 +100,7 @@ void radeon_disable_vblank(struct drm_de
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
 		switch (crtc) {
 		case 0:
 			r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
@@ -135,7 +135,7 @@ static inline u32 radeon_acknowledge_irq
 	u32 irq_mask = RADEON_SW_INT_TEST;
 
 	*r500_disp_int = 0;
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
 		/* vbl interrupts in a different place */
 
 		if (irqs & R500_DISPLAY_INT_STATUS) {
@@ -202,7 +202,7 @@ irqreturn_t radeon_driver_irq_handler(DR
 		DRM_WAKEUP(&dev_priv->swi_queue);
 
 	/* VBLANK interrupt */
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
 		if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
 			drm_handle_vblank(dev, 0);
 		if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
@@ -265,7 +265,7 @@ u32 radeon_get_vblank_counter(struct drm
 		return -EINVAL;
 	}
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
 		if (crtc == 0)
 			return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
 		else
@@ -327,7 +327,7 @@ void radeon_driver_irq_preinstall(struct
 	u32 dummy;
 
 	/* Disable *all* interrupts */
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
 
@@ -357,7 +357,7 @@ void radeon_driver_irq_uninstall(struct
 	if (!dev_priv)
 		return;
 
-	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	/* Disable *all* interrupts */
 	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_state.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_state.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/radeon/radeon_state.c	2009-06-09 23:05:27.000000000 -0400
@@ -1556,9 +1556,15 @@ static void radeon_cp_discard_buffer(str
 	buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
 
 	/* Emit the vertex buffer age */
-	BEGIN_RING(2);
-	RADEON_DISPATCH_AGE(buf_priv->age);
-	ADVANCE_RING();
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+		BEGIN_RING(3);
+		R600_DISPATCH_AGE(buf_priv->age);
+		ADVANCE_RING();
+	} else {
+		BEGIN_RING(2);
+		RADEON_DISPATCH_AGE(buf_priv->age);
+		ADVANCE_RING();
+	}
 
 	buf->pending = 1;
 	buf->used = 0;
@@ -1980,7 +1986,7 @@ static int alloc_surface(drm_radeon_surf
 
 	/* find a virtual surface */
 	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
-		if (dev_priv->virt_surfaces[i].file_priv == 0)
+		if (dev_priv->virt_surfaces[i].file_priv == NULL)
 			break;
 	if (i == 2 * RADEON_MAX_SURFACES) {
 		return -1;
@@ -2473,24 +2479,25 @@ static int radeon_cp_indirect(struct drm
 
 	buf->used = indirect->end;
 
-	/* Wait for the 3D stream to idle before the indirect buffer
-	 * containing 2D acceleration commands is processed.
-	 */
-	BEGIN_RING(2);
-
-	RADEON_WAIT_UNTIL_3D_IDLE();
-
-	ADVANCE_RING();
-
 	/* Dispatch the indirect buffer full of commands from the
 	 * X server.  This is insecure and is thus only available to
 	 * privileged clients.
 	 */
-	radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
-	if (indirect->discard) {
-		radeon_cp_discard_buffer(dev, file_priv->master, buf);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
+	else {
+		/* Wait for the 3D stream to idle before the indirect buffer
+		 * containing 2D acceleration commands is processed.
+		 */
+		BEGIN_RING(2);
+		RADEON_WAIT_UNTIL_3D_IDLE();
+		ADVANCE_RING();
+		radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
 	}
 
+	if (indirect->discard)
+		radeon_cp_discard_buffer(dev, file_priv->master, buf);
+
 	COMMIT_RING();
 	return 0;
 }
@@ -3010,14 +3017,14 @@ static int radeon_cp_getparam(struct drm
 		break;
 	case RADEON_PARAM_LAST_FRAME:
 		dev_priv->stats.last_frame_reads++;
-		value = GET_SCRATCH(0);
+		value = GET_SCRATCH(dev_priv, 0);
 		break;
 	case RADEON_PARAM_LAST_DISPATCH:
-		value = GET_SCRATCH(1);
+		value = GET_SCRATCH(dev_priv, 1);
 		break;
 	case RADEON_PARAM_LAST_CLEAR:
 		dev_priv->stats.last_clear_reads++;
-		value = GET_SCRATCH(2);
+		value = GET_SCRATCH(dev_priv, 2);
 		break;
 	case RADEON_PARAM_IRQ_NR:
 		value = drm_dev_to_irq(dev);
@@ -3052,7 +3059,10 @@ static int radeon_cp_getparam(struct drm
 	case RADEON_PARAM_SCRATCH_OFFSET:
 		if (!dev_priv->writeback_works)
 			return -EINVAL;
-		value = RADEON_SCRATCH_REG_OFFSET;
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			value = R600_SCRATCH_REG_OFFSET;
+		else
+			value = RADEON_SCRATCH_REG_OFFSET;
 		break;
 	case RADEON_PARAM_CARD_TYPE:
 		if (dev_priv->flags & RADEON_IS_PCIE)
@@ -3155,6 +3165,7 @@ void radeon_driver_preclose(struct drm_d
 
 void radeon_driver_lastclose(struct drm_device *dev)
 {
+	radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
 	radeon_do_release(dev);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/savage/savage_bci.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/savage/savage_bci.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/savage/savage_bci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/savage/savage_bci.c	2009-06-09 23:05:27.000000000 -0400
@@ -599,8 +599,8 @@ int savage_driver_firstopen(struct drm_d
 			    drm_mtrr_add(dev_priv->mtrr[2].base,
 					 dev_priv->mtrr[2].size, DRM_MTRR_WC);
 		} else {
-			DRM_ERROR("strange pci_resource_len %08lx\n",
-				  drm_get_resource_len(dev, 0));
+			DRM_ERROR("strange pci_resource_len %08llx\n",
+				  (unsigned long long)drm_get_resource_len(dev, 0));
 		}
 	} else if (dev_priv->chipset != S3_SUPERSAVAGE &&
 		   dev_priv->chipset != S3_SAVAGE2000) {
@@ -620,8 +620,8 @@ int savage_driver_firstopen(struct drm_d
 			    drm_mtrr_add(dev_priv->mtrr[0].base,
 					 dev_priv->mtrr[0].size, DRM_MTRR_WC);
 		} else {
-			DRM_ERROR("strange pci_resource_len %08lx\n",
-				  drm_get_resource_len(dev, 1));
+			DRM_ERROR("strange pci_resource_len %08llx\n",
+				  (unsigned long long)drm_get_resource_len(dev, 1));
 		}
 	} else {
 		mmio_base = drm_get_resource_start(dev, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/via/via_dma.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/via/via_dma.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/via/via_dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/via/via_dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -481,11 +481,13 @@ static int via_wait_idle(drm_via_private
 {
 	int count = 10000000;
 
-	while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--);
+	while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && --count)
+		;
 
-	while (count-- && (VIA_READ(VIA_REG_STATUS) &
+	while (count && (VIA_READ(VIA_REG_STATUS) &
 			   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
-			    VIA_3D_ENG_BUSY))) ;
+			    VIA_3D_ENG_BUSY)))
+		--count;
 	return count;
 }
 
@@ -705,7 +707,7 @@ static int via_cmdbuf_size(struct drm_de
 	switch (d_siz->func) {
 	case VIA_CMDBUF_SPACE:
 		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
-		       && count--) {
+		       && --count) {
 			if (!d_siz->wait) {
 				break;
 			}
@@ -717,7 +719,7 @@ static int via_cmdbuf_size(struct drm_de
 		break;
 	case VIA_CMDBUF_LAG:
 		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
-		       && count--) {
+		       && --count) {
 			if (!d_siz->wait) {
 				break;
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/gpu/drm/via/via_drv.c linux-libre-2.6.30-gnu1/drivers/gpu/drm/via/via_drv.c
--- linux-libre-2.6.29-gnu1/drivers/gpu/drm/via/via_drv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/gpu/drm/via/via_drv.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,11 +28,6 @@
 
 #include "drm_pciids.h"
 
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "unichrome");
-}
-
 static struct pci_device_id pciidlist[] = {
 	viadrv_PCI_IDS
 };
@@ -52,7 +47,6 @@ static struct drm_driver driver = {
 	.irq_uninstall = via_driver_irq_uninstall,
 	.irq_handler = via_driver_irq_handler,
 	.dma_quiescent = via_driver_dma_quiescent,
-	.dri_library_name = dri_library_name,
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.reclaim_buffers_locked = NULL,
 	.reclaim_buffers_idlelocked = via_reclaim_buffers_locked,
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-a4tech.c linux-libre-2.6.30-gnu1/drivers/hid/hid-a4tech.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-a4tech.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-a4tech.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,5 +158,3 @@ static void a4_exit(void)
 module_init(a4_init);
 module_exit(a4_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(a4tech);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-apple.c linux-libre-2.6.30-gnu1/drivers/hid/hid-apple.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-apple.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-apple.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,7 +53,7 @@ struct apple_key_translation {
 	u8 flags;
 };
 
-static struct apple_key_translation apple_fn_keys[] = {
+static const struct apple_key_translation apple_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
 	{ KEY_ENTER,	KEY_INSERT },
 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -75,7 +75,7 @@ static struct apple_key_translation appl
 	{ }
 };
 
-static struct apple_key_translation powerbook_fn_keys[] = {
+static const struct apple_key_translation powerbook_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
 	{ KEY_F1,	KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
 	{ KEY_F2,	KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
@@ -94,7 +94,7 @@ static struct apple_key_translation powe
 	{ }
 };
 
-static struct apple_key_translation powerbook_numlock_keys[] = {
+static const struct apple_key_translation powerbook_numlock_keys[] = {
 	{ KEY_J,	KEY_KP1 },
 	{ KEY_K,	KEY_KP2 },
 	{ KEY_L,	KEY_KP3 },
@@ -117,16 +117,16 @@ static struct apple_key_translation powe
 	{ }
 };
 
-static struct apple_key_translation apple_iso_keyboard[] = {
+static const struct apple_key_translation apple_iso_keyboard[] = {
 	{ KEY_GRAVE,	KEY_102ND },
 	{ KEY_102ND,	KEY_GRAVE },
 	{ }
 };
 
-static struct apple_key_translation *apple_find_translation(
-		struct apple_key_translation *table, u16 from)
+static const struct apple_key_translation *apple_find_translation(
+		const struct apple_key_translation *table, u16 from)
 {
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	/* Look for the translation */
 	for (trans = table; trans->from; trans++)
@@ -140,7 +140,7 @@ static int hidinput_apple_event(struct h
 		struct hid_usage *usage, __s32 value)
 {
 	struct apple_sc *asc = hid_get_drvdata(hid);
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	if (usage->code == KEY_FN) {
 		asc->fn_on = !!value;
@@ -151,7 +151,7 @@ static int hidinput_apple_event(struct h
 	if (fnmode) {
 		int do_translate;
 
-		trans = apple_find_translation((hid->product < 0x220 ||
+		trans = apple_find_translation((hid->product < 0x21d ||
 					hid->product >= 0x300) ?
 					powerbook_fn_keys : apple_fn_keys,
 					usage->code);
@@ -253,7 +253,7 @@ static void apple_report_fixup(struct hi
 
 static void apple_setup_input(struct input_dev *input)
 {
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	set_bit(KEY_NUMLOCK, input->keybit);
 
@@ -387,6 +387,12 @@ static const struct hid_device_id apple_
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
 			APPLE_RDESC_JIS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+		.driver_data = APPLE_HAS_FN },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+		.driver_data = APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
 		.driver_data = APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
@@ -468,5 +474,3 @@ static void apple_exit(void)
 module_init(apple_init);
 module_exit(apple_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(apple);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-belkin.c linux-libre-2.6.30-gnu1/drivers/hid/hid-belkin.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-belkin.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-belkin.c	2009-06-09 23:05:27.000000000 -0400
@@ -101,5 +101,3 @@ static void belkin_exit(void)
 module_init(belkin_init);
 module_exit(belkin_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(belkin);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-cherry.c linux-libre-2.6.30-gnu1/drivers/hid/hid-cherry.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-cherry.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-cherry.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,5 +83,3 @@ static void ch_exit(void)
 module_init(ch_init);
 module_exit(ch_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cherry);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-chicony.c linux-libre-2.6.30-gnu1/drivers/hid/hid-chicony.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-chicony.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-chicony.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,5 +76,3 @@ static void ch_exit(void)
 module_init(ch_init);
 module_exit(ch_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(chicony);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-core.c linux-libre-2.6.30-gnu1/drivers/hid/hid-core.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -1236,6 +1236,9 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
@@ -1262,6 +1265,7 @@ static const struct hid_device_id hid_bl
 	{ 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_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1269,6 +1273,8 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1287,6 +1293,7 @@ static const struct hid_device_id hid_bl
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
 	{ 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_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
@@ -1813,14 +1820,24 @@ void hid_unregister_driver(struct hid_dr
 }
 EXPORT_SYMBOL_GPL(hid_unregister_driver);
 
-#ifdef CONFIG_HID_COMPAT
-static void hid_compat_load(struct work_struct *ws)
+int hid_check_keys_pressed(struct hid_device *hid)
 {
-	request_module("hid-dummy");
+	struct hid_input *hidinput;
+	int i;
+
+	if (!(hid->claimed & HID_CLAIMED_INPUT))
+		return 0;
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+		for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+			if (hidinput->input->key[i])
+				return 1;
+	}
+
+	return 0;
 }
-static DECLARE_WORK(hid_compat_work, hid_compat_load);
-static struct workqueue_struct *hid_compat_wq;
-#endif
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
 
 static int __init hid_init(void)
 {
@@ -1836,15 +1853,6 @@ static int __init hid_init(void)
 	if (ret)
 		goto err_bus;
 
-#ifdef CONFIG_HID_COMPAT
-	hid_compat_wq = create_singlethread_workqueue("hid_compat");
-	if (!hid_compat_wq) {
-		hidraw_exit();
-		goto err;
-	}
-	queue_work(hid_compat_wq, &hid_compat_work);
-#endif
-
 	return 0;
 err_bus:
 	bus_unregister(&hid_bus_type);
@@ -1854,9 +1862,6 @@ err:
 
 static void __exit hid_exit(void)
 {
-#ifdef CONFIG_HID_COMPAT
-	destroy_workqueue(hid_compat_wq);
-#endif
 	hidraw_exit();
 	bus_unregister(&hid_bus_type);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-cypress.c linux-libre-2.6.30-gnu1/drivers/hid/hid-cypress.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-cypress.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-cypress.c	2009-06-09 23:05:27.000000000 -0400
@@ -154,5 +154,3 @@ static void cp_exit(void)
 module_init(cp_init);
 module_exit(cp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cypress);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-drff.c linux-libre-2.6.30-gnu1/drivers/hid/hid-drff.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-drff.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-drff.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * Force feedback support for DragonRise Inc. game controllers
+ *
+ * From what I have gathered, these devices are mass produced in China and are
+ * distributed under several vendors. They often share the same design as
+ * the original PlayStation DualShock controller.
+ *
+ * 0079:0006 "DragonRise Inc.   Generic   USB  Joystick  "
+ *  - tested with a Tesun USB-703 game controller.
+ *
+ * Copyright (c) 2009 Richard Walmsley <richwalm@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/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct drff_device {
+	struct hid_report *report;
+};
+
+static int drff_play(struct input_dev *dev, void *data,
+				 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct drff_device *drff = data;
+	int strong, weak;
+
+	strong = effect->u.rumble.strong_magnitude;
+	weak = effect->u.rumble.weak_magnitude;
+
+	dbg_hid("called with 0x%04x 0x%04x", strong, weak);
+
+	if (strong || weak) {
+		strong = strong * 0xff / 0xffff;
+		weak = weak * 0xff / 0xffff;
+
+		/* While reverse engineering this device, I found that when
+		   this value is set, it causes the strong rumble to function
+		   at a near maximum speed, so we'll bypass it. */
+		if (weak == 0x0a)
+			weak = 0x0b;
+
+		drff->report->field[0]->value[0] = 0x51;
+		drff->report->field[0]->value[1] = 0x00;
+		drff->report->field[0]->value[2] = weak;
+		drff->report->field[0]->value[4] = strong;
+		usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+		drff->report->field[0]->value[0] = 0xfa;
+		drff->report->field[0]->value[1] = 0xfe;
+	} else {
+		drff->report->field[0]->value[0] = 0xf3;
+		drff->report->field[0]->value[1] = 0x00;
+	}
+
+	drff->report->field[0]->value[2] = 0x00;
+	drff->report->field[0]->value[4] = 0x00;
+	dbg_hid("running with 0x%02x 0x%02x", strong, weak);
+	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+static int drff_init(struct hid_device *hid)
+{
+	struct drff_device *drff;
+	struct hid_report *report;
+	struct hid_input *hidinput = list_first_entry(&hid->inputs,
+						struct hid_input, list);
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	int error;
+
+	if (list_empty(report_list)) {
+		dev_err(&hid->dev, "no output reports found\n");
+		return -ENODEV;
+	}
+
+	report = list_first_entry(report_list, struct hid_report, list);
+	if (report->maxfield < 1) {
+		dev_err(&hid->dev, "no fields in the report\n");
+		return -ENODEV;
+	}
+
+	if (report->field[0]->report_count < 7) {
+		dev_err(&hid->dev, "not enough values in the field\n");
+		return -ENODEV;
+	}
+
+	drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
+	if (!drff)
+		return -ENOMEM;
+
+	set_bit(FF_RUMBLE, dev->ffbit);
+
+	error = input_ff_create_memless(dev, drff, drff_play);
+	if (error) {
+		kfree(drff);
+		return error;
+	}
+
+	drff->report = report;
+	drff->report->field[0]->value[0] = 0xf3;
+	drff->report->field[0]->value[1] = 0x00;
+	drff->report->field[0]->value[2] = 0x00;
+	drff->report->field[0]->value[3] = 0x00;
+	drff->report->field[0]->value[4] = 0x00;
+	drff->report->field[0]->value[5] = 0x00;
+	drff->report->field[0]->value[6] = 0x00;
+	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+	dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
+	       "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+
+	return 0;
+}
+
+static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	drff_init(hdev);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id dr_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006),  },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, dr_devices);
+
+static struct hid_driver dr_driver = {
+	.name = "dragonrise",
+	.id_table = dr_devices,
+	.probe = dr_probe,
+};
+
+static int __init dr_init(void)
+{
+	return hid_register_driver(&dr_driver);
+}
+
+static void __exit dr_exit(void)
+{
+	hid_unregister_driver(&dr_driver);
+}
+
+module_init(dr_init);
+module_exit(dr_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-dummy.c linux-libre-2.6.30-gnu1/drivers/hid/hid-dummy.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-dummy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-dummy.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-#include <linux/autoconf.h>
-#include <linux/module.h>
-#include <linux/hid.h>
-
-static int __init hid_dummy_init(void)
-{
-#ifdef CONFIG_HID_A4TECH_MODULE
-	HID_COMPAT_CALL_DRIVER(a4tech);
-#endif
-#ifdef CONFIG_HID_APPLE_MODULE
-	HID_COMPAT_CALL_DRIVER(apple);
-#endif
-#ifdef CONFIG_HID_BELKIN_MODULE
-	HID_COMPAT_CALL_DRIVER(belkin);
-#endif
-#ifdef CONFIG_HID_BRIGHT_MODULE
-	HID_COMPAT_CALL_DRIVER(bright);
-#endif
-#ifdef CONFIG_HID_CHERRY_MODULE
-	HID_COMPAT_CALL_DRIVER(cherry);
-#endif
-#ifdef CONFIG_HID_CHICONY_MODULE
-	HID_COMPAT_CALL_DRIVER(chicony);
-#endif
-#ifdef CONFIG_HID_CYPRESS_MODULE
-	HID_COMPAT_CALL_DRIVER(cypress);
-#endif
-#ifdef CONFIG_HID_DELL_MODULE
-	HID_COMPAT_CALL_DRIVER(dell);
-#endif
-#ifdef CONFIG_HID_EZKEY_MODULE
-	HID_COMPAT_CALL_DRIVER(ezkey);
-#endif
-#ifdef CONFIG_HID_GYRATION_MODULE
-	HID_COMPAT_CALL_DRIVER(gyration);
-#endif
-#ifdef CONFIG_HID_LOGITECH_MODULE
-	HID_COMPAT_CALL_DRIVER(logitech);
-#endif
-#ifdef CONFIG_HID_MICROSOFT_MODULE
-	HID_COMPAT_CALL_DRIVER(microsoft);
-#endif
-#ifdef CONFIG_HID_MONTEREY_MODULE
-	HID_COMPAT_CALL_DRIVER(monterey);
-#endif
-#ifdef CONFIG_HID_NTRIG_MODULE
-	HID_COMPAT_CALL_DRIVER(ntrig);
-#endif
-#ifdef CONFIG_HID_PANTHERLORD_MODULE
-	HID_COMPAT_CALL_DRIVER(pantherlord);
-#endif
-#ifdef CONFIG_HID_PETALYNX_MODULE
-	HID_COMPAT_CALL_DRIVER(petalynx);
-#endif
-#ifdef CONFIG_HID_SAMSUNG_MODULE
-	HID_COMPAT_CALL_DRIVER(samsung);
-#endif
-#ifdef CONFIG_HID_SONY_MODULE
-	HID_COMPAT_CALL_DRIVER(sony);
-#endif
-#ifdef CONFIG_HID_SUNPLUS_MODULE
-	HID_COMPAT_CALL_DRIVER(sunplus);
-#endif
-#ifdef CONFIG_GREENASIA_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(greenasia);
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(thrustmaster);
-#endif
-#ifdef CONFIG_ZEROPLUS_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(zeroplus);
-#endif
-
-	return -EIO;
-}
-module_init(hid_dummy_init);
-
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-ezkey.c linux-libre-2.6.30-gnu1/drivers/hid/hid-ezkey.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-ezkey.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-ezkey.c	2009-06-09 23:05:27.000000000 -0400
@@ -91,5 +91,3 @@ static void ez_exit(void)
 module_init(ez_init);
 module_exit(ez_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ezkey);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-gaff.c linux-libre-2.6.30-gnu1/drivers/hid/hid-gaff.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-gaff.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-gaff.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,5 +181,3 @@ static void __exit ga_exit(void)
 module_init(ga_init);
 module_exit(ga_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(greenasia);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-gyration.c linux-libre-2.6.30-gnu1/drivers/hid/hid-gyration.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-gyration.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-gyration.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,5 +94,3 @@ static void gyration_exit(void)
 module_init(gyration_init);
 module_exit(gyration_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(gyration);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-ids.h linux-libre-2.6.30-gnu1/drivers/hid/hid-ids.h
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-ids.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-ids.h	2009-06-09 23:05:27.000000000 -0400
@@ -67,6 +67,9 @@
 #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI	0x021a
 #define USB_DEVICE_ID_APPLE_GEYSER4_ISO	0x021b
 #define USB_DEVICE_ID_APPLE_GEYSER4_JIS	0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI	0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO	0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS	0x021f
 #define USB_DEVICE_ID_APPLE_ALU_ANSI	0x0220
 #define USB_DEVICE_ID_APPLE_ALU_ISO	0x0221
 #define USB_DEVICE_ID_APPLE_ALU_JIS	0x0222
@@ -110,6 +113,11 @@
 #define USB_VENDOR_ID_BERKSHIRE		0x0c98
 #define USB_DEVICE_ID_BERKSHIRE_PCWD	0x1140
 
+#define USB_VENDOR_ID_CH		0x068e
+#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_VENDOR_ID_CHERRY		0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
 
@@ -148,6 +156,8 @@
 #define USB_VENDOR_ID_DMI		0x0c0b
 #define USB_DEVICE_ID_DMI_ENC		0x5fab
 
+#define USB_VENDOR_ID_DRAGONRISE	0x0079
+
 #define USB_VENDOR_ID_ELO		0x04E7
 #define USB_DEVICE_ID_ELO_TS2700	0x0020
 
@@ -272,6 +282,9 @@
 #define USB_DEVICE_ID_LD_POWERCONTROL	0x2030
 #define USB_DEVICE_ID_LD_MACHINETEST	0x2040
 
+#define USB_VENDOR_ID_KENSINGTON	0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE	0x2041
+
 #define USB_VENDOR_ID_LOGITECH		0x046d
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
@@ -284,6 +297,7 @@
 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO	0xc286
 #define USB_DEVICE_ID_LOGITECH_WHEEL	0xc294
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL	0xc295
+#define USB_DEVICE_ID_LOGITECH_G25_WHEEL	0xc299
 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD	0xc30a
 #define USB_DEVICE_ID_S510_RECEIVER	0xc50c
 #define USB_DEVICE_ID_S510_RECEIVER_2	0xc517
@@ -418,6 +432,8 @@
 #define USB_VENDOR_ID_ZEROPLUS		0x0c12
 
 #define USB_VENDOR_ID_KYE		0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V	0x0087
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-kensington.c linux-libre-2.6.30-gnu1/drivers/hid/hid-kensington.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-kensington.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-kensington.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ *  HID driver for Kensigton Slimblade Trackball
+ *
+ *  Copyright (c) 2009 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define ks_map_key(c)	hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+	case 0x01: ks_map_key(BTN_MIDDLE);	break;
+	case 0x02: ks_map_key(BTN_SIDE);	break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static const struct hid_device_id ks_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, ks_devices);
+
+static struct hid_driver ks_driver = {
+	.name = "kensington",
+	.id_table = ks_devices,
+	.input_mapping = ks_input_mapping,
+};
+
+static int ks_init(void)
+{
+	return hid_register_driver(&ks_driver);
+}
+
+static void ks_exit(void)
+{
+	hid_unregister_driver(&ks_driver);
+}
+
+module_init(ks_init);
+module_exit(ks_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-kye.c linux-libre-2.6.30-gnu1/drivers/hid/hid-kye.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-kye.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-kye.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ *  HID driver for Kye/Genius devices not fully compliant with HID standard
+ *
+ *  Copyright (c) 2009 Jiri Kosina
+ *  Copyright (c) 2009 Tomas Hanak
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/* the fixups that need to be done:
+ *   - change led usage page to button for extra buttons
+ *   - report size 8 count 1 must be size 1 count 8 for button bitfield
+ *   - change the button usage range to 4-7 for the extra buttons
+ */
+static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+		unsigned int rsize)
+{
+	if (rsize >= 74 &&
+		rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
+		rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
+		rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+		rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
+		rdesc[73] == 0x95 && rdesc[74] == 0x01) {
+		dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
+				"descriptor\n");
+		rdesc[62] = 0x09;
+		rdesc[64] = 0x04;
+		rdesc[66] = 0x07;
+		rdesc[72] = 0x01;
+		rdesc[74] = 0x08;
+	}
+}
+
+static const struct hid_device_id kye_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, kye_devices);
+
+static struct hid_driver kye_driver = {
+	.name = "kye",
+	.id_table = kye_devices,
+	.report_fixup = kye_report_fixup,
+};
+
+static int kye_init(void)
+{
+	return hid_register_driver(&kye_driver);
+}
+
+static void kye_exit(void)
+{
+	hid_unregister_driver(&kye_driver);
+}
+
+module_init(kye_init);
+module_exit(kye_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-lg.c linux-libre-2.6.30-gnu1/drivers/hid/hid-lg.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-lg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-lg.c	2009-06-09 23:05:27.000000000 -0400
@@ -297,6 +297,8 @@ static const struct hid_device_id lg_dev
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
 		.driver_data = LG_FF },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
+		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
 		.driver_data = LG_FF2 },
 	{ }
@@ -326,5 +328,3 @@ static void lg_exit(void)
 module_init(lg_init);
 module_exit(lg_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(logitech);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-microsoft.c linux-libre-2.6.30-gnu1/drivers/hid/hid-microsoft.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-microsoft.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-microsoft.c	2009-06-09 23:05:27.000000000 -0400
@@ -210,5 +210,3 @@ static void ms_exit(void)
 module_init(ms_init);
 module_exit(ms_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(microsoft);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-monterey.c linux-libre-2.6.30-gnu1/drivers/hid/hid-monterey.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-monterey.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-monterey.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,5 +78,3 @@ static void mr_exit(void)
 module_init(mr_init);
 module_exit(mr_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(monterey);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-ntrig.c linux-libre-2.6.30-gnu1/drivers/hid/hid-ntrig.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-ntrig.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-ntrig.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,5 +78,3 @@ static void ntrig_exit(void)
 module_init(ntrig_init);
 module_exit(ntrig_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ntrig);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-petalynx.c linux-libre-2.6.30-gnu1/drivers/hid/hid-petalynx.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-petalynx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-petalynx.c	2009-06-09 23:05:27.000000000 -0400
@@ -118,5 +118,3 @@ static void pl_exit(void)
 module_init(pl_init);
 module_exit(pl_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(petalynx);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-pl.c linux-libre-2.6.30-gnu1/drivers/hid/hid-pl.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-pl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-pl.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,9 +9,12 @@
  *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
  *
  *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
- *   - tested with K??ng Gaming gamepad
+ *   - tested with König Gaming gamepad
  *
- *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
+ *  0e8f:0003 "GASIA USB Gamepad"
+ *   - another version of the König gamepad
+ *
+ *  Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
  */
 
 /*
@@ -46,6 +49,8 @@
 
 struct plff_device {
 	struct hid_report *report;
+	s32 *strong;
+	s32 *weak;
 };
 
 static int hid_plff_play(struct input_dev *dev, void *data,
@@ -62,8 +67,8 @@ static int hid_plff_play(struct input_de
 	left = left * 0x7f / 0xffff;
 	right = right * 0x7f / 0xffff;
 
-	plff->report->field[0]->value[2] = left;
-	plff->report->field[0]->value[3] = right;
+	*plff->strong = left;
+	*plff->weak = right;
 	debug("running with 0x%02x 0x%02x", left, right);
 	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
 
@@ -80,6 +85,8 @@ static int plff_init(struct hid_device *
 	struct list_head *report_ptr = report_list;
 	struct input_dev *dev;
 	int error;
+	s32 *strong;
+	s32 *weak;
 
 	/* The device contains one output report per physical device, all
 	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
@@ -87,7 +94,12 @@ static int plff_init(struct hid_device *
 
 	   The input reports also contain a field which contains
 	   8 ff00.0001 usages and 8 boolean values. Their meaning is
-	   currently unknown. */
+	   currently unknown.
+	   
+	   A version of the 0e8f:0003 exists that has all the values in
+	   separate fields and misses the extra input field, thus resembling
+	   Zeroplus (hid-zpff) devices.
+	*/
 
 	if (list_empty(report_list)) {
 		dev_err(&hid->dev, "no output reports found\n");
@@ -110,8 +122,21 @@ static int plff_init(struct hid_device *
 			return -ENODEV;
 		}
 
-		if (report->field[0]->report_count < 4) {
-			dev_err(&hid->dev, "not enough values in the field\n");
+		if (report->field[0]->report_count >= 4) {
+			report->field[0]->value[0] = 0x00;
+			report->field[0]->value[1] = 0x00;
+			strong = &report->field[0]->value[2];
+			weak = &report->field[0]->value[3];
+			debug("detected single-field device");
+		} else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+				report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
+			report->field[0]->value[0] = 0x00;
+			report->field[1]->value[0] = 0x00;
+			strong = &report->field[2]->value[0];
+			weak = &report->field[3]->value[0];
+			debug("detected 4-field device");
+		} else {
+			dev_err(&hid->dev, "not enough fields or values\n");
 			return -ENODEV;
 		}
 
@@ -130,10 +155,11 @@ static int plff_init(struct hid_device *
 		}
 
 		plff->report = report;
-		plff->report->field[0]->value[0] = 0x00;
-		plff->report->field[0]->value[1] = 0x00;
-		plff->report->field[0]->value[2] = 0x00;
-		plff->report->field[0]->value[3] = 0x00;
+		plff->strong = strong;
+		plff->weak = weak;
+
+		*strong = 0x00;
+		*weak = 0x00;
 		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
 	}
 
@@ -180,7 +206,7 @@ static const struct hid_device_id pl_dev
 		.driver_data = 1 }, /* Twin USB Joystick */
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
 		.driver_data = 1 }, /* Twin USB Joystick */
-	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, pl_devices);
@@ -204,5 +230,3 @@ static void pl_exit(void)
 module_init(pl_init);
 module_exit(pl_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(pantherlord);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hidraw.c linux-libre-2.6.30-gnu1/drivers/hid/hidraw.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hidraw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hidraw.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *ino
 
 	dev = hidraw_table[minor];
 	if (!dev->open++) {
+		if (dev->hid->ll_driver->power) {
+			err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+			if (err < 0)
+				goto out_unlock;
+		}
 		err = dev->hid->ll_driver->open(dev->hid);
-		if (err < 0)
+		if (err < 0) {
+			if (dev->hid->ll_driver->power)
+				dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
 			dev->open--;
+		}
 	}
 
 out_unlock:
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode *
 	list_del(&list->node);
 	dev = hidraw_table[minor];
 	if (!--dev->open) {
-		if (list->hidraw->exist)
+		if (list->hidraw->exist) {
+			if (dev->hid->ll_driver->power)
+				dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
 			dev->hid->ll_driver->close(dev->hid);
-		else
+		} else {
 			kfree(list->hidraw);
+		}
 	}
 
 	kfree(list);
@@ -274,8 +285,10 @@ static long hidraw_ioctl(struct file *fi
 
 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
 					int len;
-					if (!hid->name)
-						return 0;
+					if (!hid->name) {
+						ret = 0;
+						break;
+					}
 					len = strlen(hid->name) + 1;
 					if (len > _IOC_SIZE(cmd))
 						len = _IOC_SIZE(cmd);
@@ -286,8 +299,10 @@ static long hidraw_ioctl(struct file *fi
 
 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
 					int len;
-					if (!hid->phys)
-						return 0;
+					if (!hid->phys) {
+						ret = 0;
+						break;
+					}
 					len = strlen(hid->phys) + 1;
 					if (len > _IOC_SIZE(cmd))
 						len = _IOC_SIZE(cmd);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-samsung.c linux-libre-2.6.30-gnu1/drivers/hid/hid-samsung.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-samsung.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-samsung.c	2009-06-09 23:05:27.000000000 -0400
@@ -96,5 +96,3 @@ static void samsung_exit(void)
 module_init(samsung_init);
 module_exit(samsung_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(samsung);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-sony.c linux-libre-2.6.30-gnu1/drivers/hid/hid-sony.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-sony.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-sony.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,5 +148,3 @@ static void sony_exit(void)
 module_init(sony_init);
 module_exit(sony_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sony);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-sunplus.c linux-libre-2.6.30-gnu1/drivers/hid/hid-sunplus.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-sunplus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-sunplus.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,5 +78,3 @@ static void sp_exit(void)
 module_init(sp_init);
 module_exit(sp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sunplus);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-tmff.c linux-libre-2.6.30-gnu1/drivers/hid/hid-tmff.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-tmff.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-tmff.c	2009-06-09 23:05:27.000000000 -0400
@@ -265,5 +265,3 @@ static void tm_exit(void)
 module_init(tm_init);
 module_exit(tm_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-topseed.c linux-libre-2.6.30-gnu1/drivers/hid/hid-topseed.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-topseed.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-topseed.c	2009-06-09 23:05:27.000000000 -0400
@@ -73,5 +73,3 @@ static void ts_exit(void)
 module_init(ts_init);
 module_exit(ts_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(topseed);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/hid-zpff.c linux-libre-2.6.30-gnu1/drivers/hid/hid-zpff.c
--- linux-libre-2.6.29-gnu1/drivers/hid/hid-zpff.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/hid-zpff.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,5 +158,3 @@ static void zp_exit(void)
 module_init(zp_init);
 module_exit(zp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(zeroplus);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/Kconfig linux-libre-2.6.30-gnu1/drivers/hid/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/hid/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -29,11 +29,11 @@ config HID
 
 	  For docs and specs, see http://www.usb.org/developers/hidpage/
 
-	  If unsure, say Y
+	  If unsure, say Y.
 
 config HID_DEBUG
 	bool "HID debugging support"
-	default y if !EMBEDDED
+	default y
 	depends on HID
 	---help---
 	This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@ config HID_DEBUG
 	This feature is useful for those who are either debugging the HID parser
 	or any HID hardware device.
 
-	If unsure, say N
+	If unsure, say Y.
 
 config HIDRAW
 	bool "/dev/hidraw raw HID device support"
@@ -70,18 +70,6 @@ source "drivers/hid/usbhid/Kconfig"
 menu "Special HID drivers"
 	depends on HID
 
-config HID_COMPAT
-	bool "Load all HID drivers on hid core load"
-	default y
-	---help---
-	Compatible option for older userspace. If you have system without udev
-	support of module loading through aliases and also old
-	module-init-tools which can't handle hid bus, choose Y here. Otherwise
-	say N. If you say N and your userspace is old enough, the only
-	functionality you lose is modules autoloading.
-
-	If unsure, say Y.
-
 config HID_A4TECH
 	tristate "A4 tech" if EMBEDDED
 	depends on USB_HID
@@ -128,6 +116,14 @@ config HID_CYPRESS
 	---help---
 	Support for cypress mouse and barcode readers.
 
+config DRAGONRISE_FF
+	tristate "DragonRise Inc. force feedback support"
+	depends on USB_HID
+	select INPUT_FF_MEMLESS
+	---help---
+	Say Y here if you want to enable force feedback support for DragonRise Inc.
+	game controllers.
+
 config HID_EZKEY
 	tristate "Ezkey" if EMBEDDED
 	depends on USB_HID
@@ -135,6 +131,13 @@ config HID_EZKEY
 	---help---
 	Support for Ezkey BTC 8193 keyboard.
 
+config HID_KYE
+	tristate "Kye" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Kye/Genius Ergo Mouse.
+
 config HID_GYRATION
 	tristate "Gyration" if EMBEDDED
 	depends on USB_HID
@@ -142,6 +145,13 @@ config HID_GYRATION
 	---help---
 	Support for Gyration remote control.
 
+config HID_KENSINGTON
+	tristate "Kensington" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Kensington Slimblade Trackball.
+
 config HID_LOGITECH
 	tristate "Logitech" if EMBEDDED
 	depends on USB_HID
@@ -243,7 +253,7 @@ config GREENASIA_FF
 	select INPUT_FF_MEMLESS
 	---help---
 	Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
-	(like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
+	(like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
 	and want to enable force feedback support for it.
 
 config HID_TOPSEED
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/Makefile linux-libre-2.6.30-gnu1/drivers/hid/Makefile
--- linux-libre-2.6.29-gnu1/drivers/hid/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -8,10 +8,6 @@ obj-$(CONFIG_HID)		+= hid.o
 hid-$(CONFIG_HID_DEBUG)		+= hid-debug.o
 hid-$(CONFIG_HIDRAW)		+= hidraw.o
 
-ifdef CONFIG_HID_COMPAT
-obj-m				+= hid-dummy.o
-endif
-
 hid-logitech-objs		:= hid-lg.o
 ifdef CONFIG_LOGITECH_FF
 	hid-logitech-objs	+= hid-lgff.o
@@ -26,8 +22,11 @@ obj-$(CONFIG_HID_BELKIN)	+= hid-belkin.o
 obj-$(CONFIG_HID_CHERRY)	+= hid-cherry.o
 obj-$(CONFIG_HID_CHICONY)	+= hid-chicony.o
 obj-$(CONFIG_HID_CYPRESS)	+= hid-cypress.o
+obj-$(CONFIG_DRAGONRISE_FF)	+= hid-drff.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
 obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
+obj-$(CONFIG_HID_KENSINGTON)	+= hid-kensington.o
+obj-$(CONFIG_HID_KYE)		+= hid-kye.o
 obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
 obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
 obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hid-core.c linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hid-core.c
--- linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hid-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hid-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
  *  Copyright (c) 2006-2008 Jiri Kosina
+ *  Copyright (c) 2007-2008 Oliver Neukum
  */
 
 /*
@@ -27,6 +28,7 @@
 #include <asm/byteorder.h>
 #include <linux/input.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <linux/usb.h>
 
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interv
 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
 MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
 
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
 /* Quirks specified at module load time */
 static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
 module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB
 /*
  * Input submission and I/O error handler.
  */
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
 
 static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
 
 /* Start up the input URB */
 static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_devic
 	int rc = 0;
 	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&usbhid->inlock, flags);
-	if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+	spin_lock_irqsave(&usbhid->lock, flags);
+	if (hid->open > 0 &&
 			!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+			!test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
 			!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
 		rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
 		if (rc != 0)
 			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 	}
-	spin_unlock_irqrestore(&usbhid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 	return rc;
 }
 
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_devi
 	unsigned long flags;
 	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&usbhid->inlock, flags);
+	spin_lock_irqsave(&usbhid->lock, flags);
 
 	/* Stop when disconnected */
 	if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_devi
 	mod_timer(&usbhid->io_retry,
 			jiffies + msecs_to_jiffies(usbhid->retry_delay));
 done:
-	spin_unlock_irqrestore(&usbhid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+	struct usb_interface *intf = usbhid->intf;
+
+	usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+	int kicked;
+
+	if (!hid)
+		return 0;
+
+	if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+		dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+		if (hid_submit_out(hid)) {
+			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+			wake_up(&usbhid->wait);
+		}
+	}
+	return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+	int kicked;
+
+	WARN_ON(hid == NULL);
+	if (!hid)
+		return 0;
+
+	if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+		dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+		if (hid_submit_ctrl(hid)) {
+			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+			wake_up(&usbhid->wait);
+		}
+	}
+	return kicked;
 }
 
 /*
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb)
 
 	switch (urb->status) {
 	case 0:			/* success */
+		usbhid_mark_busy(usbhid);
 		usbhid->retry_delay = 0;
 		hid_input_report(urb->context, HID_INPUT_REPORT,
 				 urb->transfer_buffer,
 				 urb->actual_length, 1);
+		/*
+		 * autosuspend refused while keys are pressed
+		 * because most keyboards don't wake up when
+		 * a key is released
+		 */
+		if (hid_check_keys_pressed(hid))
+			set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+		else
+			clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 		break;
 	case -EPIPE:		/* stall */
+		usbhid_mark_busy(usbhid);
 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 		set_bit(HID_CLEAR_HALT, &usbhid->iofl);
 		schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb)
 	case -EPROTO:		/* protocol error or unplug */
 	case -ETIME:		/* protocol error or unplug */
 	case -ETIMEDOUT:	/* Should never happen, but... */
+		usbhid_mark_busy(usbhid);
 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 		hid_io_error(hid);
 		return;
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_dev
 	report = usbhid->out[usbhid->outtail].report;
 	raw_report = usbhid->out[usbhid->outtail].raw_report;
 
-	usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-	usbhid->urbout->dev = hid_to_usb_dev(hid);
-	memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
-	kfree(raw_report);
+	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+		usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+		usbhid->urbout->dev = hid_to_usb_dev(hid);
+		memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+		kfree(raw_report);
 
-	dbg_hid("submitting out urb\n");
+		dbg_hid("submitting out urb\n");
 
-	if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
-		err_hid("usb_submit_urb(out) failed");
-		return -1;
+		if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+			err_hid("usb_submit_urb(out) failed");
+			return -1;
+		}
+	} else {
+		/*
+		 * queue work to wake up the device.
+		 * as the work queue is freezeable, this is safe
+		 * with respect to STD and STR
+		 */
+		queue_work(resumption_waker, &usbhid->restart_work);
 	}
 
 	return 0;
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_de
 	raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
 	dir = usbhid->ctrl[usbhid->ctrltail].dir;
 
-	len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-	if (dir == USB_DIR_OUT) {
-		usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
-		usbhid->urbctrl->transfer_buffer_length = len;
-		memcpy(usbhid->ctrlbuf, raw_report, len);
-		kfree(raw_report);
-	} else {
-		int maxpacket, padlen;
+	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+		len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+		if (dir == USB_DIR_OUT) {
+			usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+			usbhid->urbctrl->transfer_buffer_length = len;
+			memcpy(usbhid->ctrlbuf, raw_report, len);
+			kfree(raw_report);
+		} else {
+			int maxpacket, padlen;
 
-		usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
-		maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
-		if (maxpacket > 0) {
-			padlen = DIV_ROUND_UP(len, maxpacket);
-			padlen *= maxpacket;
-			if (padlen > usbhid->bufsize)
-				padlen = usbhid->bufsize;
-		} else
-			padlen = 0;
-		usbhid->urbctrl->transfer_buffer_length = padlen;
-	}
-	usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+			usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+			maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+			if (maxpacket > 0) {
+				padlen = DIV_ROUND_UP(len, maxpacket);
+				padlen *= maxpacket;
+				if (padlen > usbhid->bufsize)
+					padlen = usbhid->bufsize;
+			} else
+				padlen = 0;
+			usbhid->urbctrl->transfer_buffer_length = padlen;
+		}
+		usbhid->urbctrl->dev = hid_to_usb_dev(hid);
 
-	usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
-	usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
-	usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
-	usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
-	usbhid->cr->wLength = cpu_to_le16(len);
+		usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+		usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+		usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+		usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+		usbhid->cr->wLength = cpu_to_le16(len);
 
-	dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
-		usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
-		usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+		dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+			usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+			usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
 
-	if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
-		err_hid("usb_submit_urb(ctrl) failed");
-		return -1;
+		if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+			err_hid("usb_submit_urb(ctrl) failed");
+			return -1;
+		}
+	} else {
+		/*
+		 * queue work to wake up the device.
+		 * as the work queue is freezeable, this is safe
+		 * with respect to STD and STR
+		 */
+		queue_work(resumption_waker, &usbhid->restart_work);
 	}
 
 	return 0;
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb)
 				"received\n", urb->status);
 	}
 
-	spin_lock_irqsave(&usbhid->outlock, flags);
+	spin_lock_irqsave(&usbhid->lock, flags);
 
 	if (unplug)
 		usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb)
 			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
 			wake_up(&usbhid->wait);
 		}
-		spin_unlock_irqrestore(&usbhid->outlock, flags);
+		spin_unlock_irqrestore(&usbhid->lock, flags);
 		return;
 	}
 
 	clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-	spin_unlock_irqrestore(&usbhid->outlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 	wake_up(&usbhid->wait);
 }
 
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb)
 {
 	struct hid_device *hid = urb->context;
 	struct usbhid_device *usbhid = hid->driver_data;
-	unsigned long flags;
-	int unplug = 0;
+	int unplug = 0, status = urb->status;
 
-	spin_lock_irqsave(&usbhid->ctrllock, flags);
+	spin_lock(&usbhid->lock);
 
-	switch (urb->status) {
+	switch (status) {
 	case 0:			/* success */
 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
 			hid_input_report(urb->context,
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb)
 		break;
 	default:		/* error */
 		dev_warn(&urb->dev->dev, "ctrl urb status %d "
-				"received\n", urb->status);
+				"received\n", status);
 	}
 
 	if (unplug)
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb)
 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
 			wake_up(&usbhid->wait);
 		}
-		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+		spin_unlock(&usbhid->lock);
 		return;
 	}
 
 	clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
-	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+	spin_unlock(&usbhid->lock);
 	wake_up(&usbhid->wait);
 }
 
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
 {
 	int head;
-	unsigned long flags;
 	struct usbhid_device *usbhid = hid->driver_data;
 	int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
 
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_dev
 		return;
 
 	if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
-		spin_lock_irqsave(&usbhid->outlock, flags);
-
 		if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
-			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			dev_warn(&hid->dev, "output queue full\n");
 			return;
 		}
 
 		usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->out[usbhid->outhead].raw_report) {
-			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			dev_warn(&hid->dev, "output queueing failed\n");
 			return;
 		}
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_dev
 		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
 			if (hid_submit_out(hid))
 				clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
-		spin_unlock_irqrestore(&usbhid->outlock, flags);
 		return;
 	}
 
-	spin_lock_irqsave(&usbhid->ctrllock, flags);
-
 	if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
-		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 		dev_warn(&hid->dev, "control queue full\n");
 		return;
 	}
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_dev
 	if (dir == USB_DIR_OUT) {
 		usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
-			spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 			dev_warn(&hid->dev, "control queueing failed\n");
 			return;
 		}
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_dev
 	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
 		if (hid_submit_ctrl(hid))
 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
 
-	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&usbhid->lock, flags);
+	__usbhid_submit_report(hid, report, dir);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usbhid_submit_report);
 
 static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct hid_device *hid = input_get_drvdata(dev);
+	struct usbhid_device *usbhid = hid->driver_data;
 	struct hid_field *field;
+	unsigned long flags;
 	int offset;
 
 	if (type == EV_FF)
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(stru
 	}
 
 	hid_set_field(field, offset, value);
+	if (value) {
+		spin_lock_irqsave(&usbhid->lock, flags);
+		usbhid->ledcount++;
+		spin_unlock_irqrestore(&usbhid->lock, flags);
+	} else {
+		spin_lock_irqsave(&usbhid->lock, flags);
+		usbhid->ledcount--;
+		spin_unlock_irqrestore(&usbhid->lock, flags);
+	}
 	usbhid_submit_report(hid, field->report, USB_DIR_OUT);
 
 	return 0;
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid)
 	struct usbhid_device *usbhid = hid->driver_data;
 	int res;
 
+	mutex_lock(&hid_open_mut);
 	if (!hid->open++) {
 		res = usb_autopm_get_interface(usbhid->intf);
+		/* the device must be awake to reliable request remote wakeup */
 		if (res < 0) {
 			hid->open--;
+			mutex_unlock(&hid_open_mut);
 			return -EIO;
 		}
+		usbhid->intf->needs_remote_wakeup = 1;
+		if (hid_start_in(hid))
+			hid_io_error(hid);
+ 
+		usb_autopm_put_interface(usbhid->intf);
 	}
-	if (hid_start_in(hid))
-		hid_io_error(hid);
+	mutex_unlock(&hid_open_mut);
 	return 0;
 }
 
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid
 {
 	struct usbhid_device *usbhid = hid->driver_data;
 
+	mutex_lock(&hid_open_mut);
+
+	/* protecting hid->open to make sure we don't restart
+	 * data acquistion due to a resumption we no longer
+	 * care about
+	 */
+	spin_lock_irq(&usbhid->lock);
 	if (!--hid->open) {
+		spin_unlock_irq(&usbhid->lock);
+		hid_cancel_delayed_stuff(usbhid);
 		usb_kill_urb(usbhid->urbin);
-		usb_autopm_put_interface(usbhid->intf);
+		usbhid->intf->needs_remote_wakeup = 0;
+	} else {
+		spin_unlock_irq(&usbhid->lock);
 	}
+	mutex_unlock(&hid_open_mut);
 }
 
 /*
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(stru
 	return ret;
 }
 
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+	if (usbhid->urbout)
+		usbhid_restart_out_queue(usbhid);
+	usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+	struct usbhid_device *usbhid =
+		container_of(work, struct usbhid_device, restart_work);
+	int r;
+
+	r = usb_autopm_get_interface(usbhid->intf);
+	if (r < 0)
+		return;
+	usb_autopm_put_interface(usbhid->intf);
+}
+
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
 	struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@ static int usbhid_parse(struct hid_devic
 	quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
 			le16_to_cpu(dev->descriptor.idProduct));
 
+	if (quirks & HID_QUIRK_IGNORE)
+		return -ENODEV;
+
 	/* Many keyboards and mice don't like to be polled for reports,
 	 * so we will always set the HID_QUIRK_NOGET flag for them. */
 	if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -765,7 +898,7 @@ static int usbhid_parse(struct hid_devic
 		goto err;
 	}
 
-	hid->quirks = quirks;
+	hid->quirks |= quirks;
 
 	return 0;
 err:
@@ -850,11 +983,11 @@ static int usbhid_start(struct hid_devic
 
 	init_waitqueue_head(&usbhid->wait);
 	INIT_WORK(&usbhid->reset_work, hid_reset);
+	INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
 	setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 
-	spin_lock_init(&usbhid->inlock);
-	spin_lock_init(&usbhid->outlock);
-	spin_lock_init(&usbhid->ctrllock);
+	spin_lock_init(&usbhid->lock);
+	spin_lock_init(&usbhid->lock);
 
 	usbhid->intf = intf;
 	usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@ static void usbhid_stop(struct hid_devic
 		return;
 
 	clear_bit(HID_STARTED, &usbhid->iofl);
-	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
+	spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
 	set_bit(HID_DISCONNECTED, &usbhid->iofl);
-	spin_unlock_irq(&usbhid->inlock);
+	spin_unlock_irq(&usbhid->lock);
 	usb_kill_urb(usbhid->urbin);
 	usb_kill_urb(usbhid->urbout);
 	usb_kill_urb(usbhid->urbctrl);
 
-	del_timer_sync(&usbhid->io_retry);
-	cancel_work_sync(&usbhid->reset_work);
+	hid_cancel_delayed_stuff(usbhid);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@ static void usbhid_stop(struct hid_devic
 	hid_free_buffers(hid_to_usb_dev(hid), hid);
 }
 
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+	int r = 0;
+
+	switch (lvl) {
+	case PM_HINT_FULLON:
+		r = usbhid_get_power(hid);
+		break;
+	case PM_HINT_NORMAL:
+		usbhid_put_power(hid);
+		break;
+	}
+	return r;
+}
+
 static struct hid_ll_driver usb_hid_driver = {
 	.parse = usbhid_parse,
 	.start = usbhid_start,
 	.stop = usbhid_stop,
 	.open = usbhid_open,
 	.close = usbhid_close,
+	.power = usbhid_power,
 	.hidinput_input_event = usb_hidinput_input_event,
 };
 
@@ -1049,19 +1197,126 @@ static void hid_disconnect(struct usb_in
 	kfree(usbhid);
 }
 
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
+{
+	del_timer_sync(&usbhid->io_retry);
+	cancel_work_sync(&usbhid->restart_work);
+	cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+	del_timer(&usbhid->io_retry);
+	usb_kill_urb(usbhid->urbin);
+	usb_kill_urb(usbhid->urbctrl);
+	usb_kill_urb(usbhid->urbout);
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	spin_lock_irq(&usbhid->lock);
+	set_bit(HID_RESET_PENDING, &usbhid->iofl);
+	spin_unlock_irq(&usbhid->lock);
+	cancel_work_sync(&usbhid->restart_work);
+	hid_cease_io(usbhid);
+
+	return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+	struct usb_device *dev = interface_to_usbdev (intf);
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
+	int status;
+ 
+	spin_lock_irq(&usbhid->lock);
+	clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+	spin_unlock_irq(&usbhid->lock);
+	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+	/* FIXME: Any more reinitialization needed? */
+	status = hid_start_in(hid);
+	if (status < 0)
+		hid_io_error(hid);
+	usbhid_restart_queues(usbhid);
+
+	return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+ 
+	return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+ 
+	usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
 static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 {
-	struct hid_device *hid = usb_get_intfdata (intf);
+	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 (!test_bit(HID_STARTED, &usbhid->iofl))
-		return 0;
+	if (udev->auto_pm) {
+		spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
+		if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+		    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+		    && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+		    && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+		    && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+		    && (!usbhid->ledcount || ignoreled))
+		{
+			set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+			spin_unlock_irq(&usbhid->lock);
+		} else {
+			usbhid_mark_busy(usbhid);
+			spin_unlock_irq(&usbhid->lock);
+			return -EBUSY;
+		}
 
-	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
-	set_bit(HID_SUSPENDED, &usbhid->iofl);
-	spin_unlock_irq(&usbhid->inlock);
-	del_timer_sync(&usbhid->io_retry);
-	usb_kill_urb(usbhid->urbin);
+	} else {
+		spin_lock_irq(&usbhid->lock);
+		set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+		spin_unlock_irq(&usbhid->lock);
+		if (usbhid_wait_io(hid) < 0)
+			return -EIO;
+	}
+
+	if (!ignoreled && udev->auto_pm) {
+		spin_lock_irq(&usbhid->lock);
+		if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+			spin_unlock_irq(&usbhid->lock);
+			usbhid_mark_busy(usbhid);
+			return -EBUSY;
+		}
+		spin_unlock_irq(&usbhid->lock);
+	}
+
+	hid_cancel_delayed_stuff(usbhid);
+	hid_cease_io(usbhid);
+
+	if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+		/* lost race against keypresses */
+		status = hid_start_in(hid);
+		if (status < 0)
+			hid_io_error(hid);
+		usbhid_mark_busy(usbhid);
+		return -EBUSY;
+	}
 	dev_dbg(&intf->dev, "suspend\n");
 	return 0;
 }
@@ -1075,32 +1330,33 @@ static int hid_resume(struct usb_interfa
 	if (!test_bit(HID_STARTED, &usbhid->iofl))
 		return 0;
 
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
+	clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+	usbhid_mark_busy(usbhid);
+
+	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
+	    test_bit(HID_RESET_PENDING, &usbhid->iofl))
+		schedule_work(&usbhid->reset_work);
 	usbhid->retry_delay = 0;
 	status = hid_start_in(hid);
-	dev_dbg(&intf->dev, "resume status %d\n", status);
-	return status;
-}
+	if (status < 0)
+		hid_io_error(hid);
+	usbhid_restart_queues(usbhid);
 
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
-	/* FIXME: What if the interface is already suspended? */
-	hid_suspend(intf, PMSG_ON);
+	dev_dbg(&intf->dev, "resume status %d\n", status);
 	return 0;
 }
 
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
 {
-	struct usb_device *dev = interface_to_usbdev (intf);
-
-	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-	/* FIXME: Any more reinitialization needed? */
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	return hid_resume(intf);
+	clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+	return hid_post_reset(intf);
 }
 
+#endif /* CONFIG_PM */
+
 static struct usb_device_id hid_usb_ids [] = {
 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
 		.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@ static struct usb_driver hid_driver = {
 	.name =		"usbhid",
 	.probe =	hid_probe,
 	.disconnect =	hid_disconnect,
+#ifdef CONFIG_PM
 	.suspend =	hid_suspend,
 	.resume =	hid_resume,
-	.reset_resume =	hid_post_reset,
+	.reset_resume =	hid_reset_resume,
+#endif
 	.pre_reset =	hid_pre_reset,
 	.post_reset =	hid_post_reset,
 	.id_table =	hid_usb_ids,
@@ -1134,7 +1392,11 @@ static struct hid_driver hid_usb_driver
 
 static int __init hid_init(void)
 {
-	int retval;
+	int retval = -ENOMEM;
+
+	resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+	if (!resumption_waker)
+		goto no_queue;
 	retval = hid_register_driver(&hid_usb_driver);
 	if (retval)
 		goto hid_register_fail;
@@ -1158,6 +1420,8 @@ hiddev_init_fail:
 usbhid_quirks_init_fail:
 	hid_unregister_driver(&hid_usb_driver);
 hid_register_fail:
+	destroy_workqueue(resumption_waker);
+no_queue:
 	return retval;
 }
 
@@ -1167,6 +1431,7 @@ static void __exit hid_exit(void)
 	hiddev_exit();
 	usbhid_quirks_exit();
 	hid_unregister_driver(&hid_usb_driver);
+	destroy_workqueue(resumption_waker);
 }
 
 module_init(hid_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hiddev.c linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hiddev.c
--- linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hiddev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hiddev.c	2009-06-09 23:05:27.000000000 -0400
@@ -227,12 +227,9 @@ void hiddev_report_event(struct hid_devi
  */
 static int hiddev_fasync(int fd, struct file *file, int on)
 {
-	int retval;
 	struct hiddev_list *list = file->private_data;
 
-	retval = fasync_helper(fd, file, on, &list->fasync);
-
-	return retval < 0 ? retval : 0;
+	return fasync_helper(fd, file, on, &list->fasync);
 }
 
 
@@ -249,10 +246,12 @@ static int hiddev_release(struct inode *
 	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
 
 	if (!--list->hiddev->open) {
-		if (list->hiddev->exist)
+		if (list->hiddev->exist) {
 			usbhid_close(list->hiddev->hid);
-		else
+			usbhid_put_power(list->hiddev->hid);
+		} else {
 			kfree(list->hiddev);
+		}
 	}
 
 	kfree(list);
@@ -303,6 +302,17 @@ static int hiddev_open(struct inode *ino
 	list_add_tail(&list->node, &hiddev_table[i]->list);
 	spin_unlock_irq(&list->hiddev->list_lock);
 
+	if (!list->hiddev->open++)
+		if (list->hiddev->exist) {
+			struct hid_device *hid = hiddev_table[i]->hid;
+			res = usbhid_get_power(hid);
+			if (res < 0) {
+				res = -EIO;
+				goto bail;
+			}
+			usbhid_open(hid);
+		}
+
 	return 0;
 bail:
 	file->private_data = NULL;
@@ -878,16 +888,21 @@ int hiddev_connect(struct hid_device *hi
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
+	/* when lock_kernel() usage is fixed in usb_open(),
+	 * we could also fix it here */
+	lock_kernel();
 	retval = usb_register_dev(usbhid->intf, &hiddev_class);
 	if (retval) {
 		err_hid("Not able to get a minor for this device.");
 		hid->hiddev = NULL;
+		unlock_kernel();
 		kfree(hiddev);
 		return -1;
 	} else {
 		hid->minor = usbhid->intf->minor;
 		hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
 	}
+	unlock_kernel();
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hid-quirks.c linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hid-quirks.c
--- linux-libre-2.6.29-gnu1/drivers/hid/usbhid/hid-quirks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hid-quirks.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,9 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+	{ 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_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 },
diff -druNp linux-libre-2.6.29-gnu1/drivers/hid/usbhid/usbhid.h linux-libre-2.6.30-gnu1/drivers/hid/usbhid/usbhid.h
--- linux-libre-2.6.29-gnu1/drivers/hid/usbhid/usbhid.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hid/usbhid/usbhid.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hi
 void usbhid_close(struct hid_device *hid);
 int usbhid_open(struct hid_device *hid);
 void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
 
 /* iofl flags */
 #define HID_CTRL_RUNNING	1
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_dev
 #define HID_CLEAR_HALT		6
 #define HID_DISCONNECTED	7
 #define HID_STARTED		8
+#define HID_REPORTED_IDLE	9
+#define HID_KEYS_PRESSED	10
+#define HID_LED_ON		11
 
 /*
  * USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@ struct usbhid_device {
 	struct urb *urbin;                                              /* Input URB */
 	char *inbuf;                                                    /* Input buffer */
 	dma_addr_t inbuf_dma;                                           /* Input buffer dma */
-	spinlock_t inlock;                                              /* Input fifo spinlock */
 
 	struct urb *urbctrl;                                            /* Control URB */
 	struct usb_ctrlrequest *cr;                                     /* Control request struct */
@@ -75,21 +80,22 @@ struct usbhid_device {
 	unsigned char ctrlhead, ctrltail;                               /* Control fifo head & tail */
 	char *ctrlbuf;                                                  /* Control buffer */
 	dma_addr_t ctrlbuf_dma;                                         /* Control buffer dma */
-	spinlock_t ctrllock;                                            /* Control fifo spinlock */
 
 	struct urb *urbout;                                             /* Output URB */
 	struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE];              /* Output pipe fifo */
 	unsigned char outhead, outtail;                                 /* Output pipe fifo head & tail */
 	char *outbuf;                                                   /* Output buffer */
 	dma_addr_t outbuf_dma;                                          /* Output buffer dma */
-	spinlock_t outlock;                                             /* Output fifo spinlock */
 
+	spinlock_t lock;						/* fifo spinlock */
 	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
 	struct timer_list io_retry;                                     /* Retry timer */
 	unsigned long stop_retry;                                       /* Time to give up, in jiffies */
 	unsigned int retry_delay;                                       /* Delay length in ms */
 	struct work_struct reset_work;                                  /* Task context for resets */
+	struct work_struct restart_work;				/* waking up for output to be done in a task */
 	wait_queue_head_t wait;						/* For sleeping */
+	int ledcount;							/* counting the number of active leds */
 };
 
 #define	hid_to_usb_dev(hid_dev) \
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/asus_atk0110.c linux-libre-2.6.30-gnu1/drivers/hwmon/asus_atk0110.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/asus_atk0110.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/asus_atk0110.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1011 @@
+/*
+ * Copyright (C) 2007-2009 Luca Tettamanti <kronos.it@gmail.com>
+ *
+ * This file is released under the GPLv2
+ * See COPYING in the top level directory of the kernel tree.
+ */
+
+#include <linux/kernel.h>
+#include <linux/hwmon.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acpixf.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+
+#define ATK_HID "ATK0110"
+
+/* Minimum time between readings, enforced in order to avoid
+ * hogging the CPU.
+ */
+#define CACHE_TIME		HZ
+
+#define BOARD_ID		"MBIF"
+#define METHOD_ENUMERATE	"GGRP"
+#define METHOD_READ		"GITM"
+#define METHOD_WRITE		"SITM"
+#define METHOD_OLD_READ_TMP	"RTMP"
+#define METHOD_OLD_READ_VLT	"RVLT"
+#define METHOD_OLD_READ_FAN	"RFAN"
+#define METHOD_OLD_ENUM_TMP	"TSIF"
+#define METHOD_OLD_ENUM_VLT	"VSIF"
+#define METHOD_OLD_ENUM_FAN	"FSIF"
+
+#define ATK_MUX_HWMON		0x00000006ULL
+
+#define ATK_CLASS_MASK		0xff000000ULL
+#define ATK_CLASS_FREQ_CTL	0x03000000ULL
+#define ATK_CLASS_FAN_CTL	0x04000000ULL
+#define ATK_CLASS_HWMON		0x06000000ULL
+
+#define ATK_TYPE_MASK		0x00ff0000ULL
+#define HWMON_TYPE_VOLT		0x00020000ULL
+#define HWMON_TYPE_TEMP		0x00030000ULL
+#define HWMON_TYPE_FAN		0x00040000ULL
+
+#define HWMON_SENSOR_ID_MASK	0x0000ffffULL
+
+enum atk_pack_member {
+	HWMON_PACK_FLAGS,
+	HWMON_PACK_NAME,
+	HWMON_PACK_LIMIT1,
+	HWMON_PACK_LIMIT2,
+	HWMON_PACK_ENABLE
+};
+
+/* New package format */
+#define _HWMON_NEW_PACK_SIZE	7
+#define _HWMON_NEW_PACK_FLAGS	0
+#define _HWMON_NEW_PACK_NAME	1
+#define _HWMON_NEW_PACK_UNK1	2
+#define _HWMON_NEW_PACK_UNK2	3
+#define _HWMON_NEW_PACK_LIMIT1	4
+#define _HWMON_NEW_PACK_LIMIT2	5
+#define _HWMON_NEW_PACK_ENABLE	6
+
+/* Old package format */
+#define _HWMON_OLD_PACK_SIZE	5
+#define _HWMON_OLD_PACK_FLAGS	0
+#define _HWMON_OLD_PACK_NAME	1
+#define _HWMON_OLD_PACK_LIMIT1	2
+#define _HWMON_OLD_PACK_LIMIT2	3
+#define _HWMON_OLD_PACK_ENABLE	4
+
+
+struct atk_data {
+	struct device *hwmon_dev;
+	acpi_handle atk_handle;
+	struct acpi_device *acpi_dev;
+
+	bool old_interface;
+
+	/* old interface */
+	acpi_handle rtmp_handle;
+	acpi_handle rvlt_handle;
+	acpi_handle rfan_handle;
+	/* new inteface */
+	acpi_handle enumerate_handle;
+	acpi_handle read_handle;
+
+	int voltage_count;
+	int temperature_count;
+	int fan_count;
+	struct list_head sensor_list;
+};
+
+
+typedef ssize_t (*sysfs_show_func)(struct device *dev,
+			struct device_attribute *attr, char *buf);
+
+static const struct acpi_device_id atk_ids[] = {
+	{ATK_HID, 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, atk_ids);
+
+#define ATTR_NAME_SIZE 16 /* Worst case is "tempN_input" */
+
+struct atk_sensor_data {
+	struct list_head list;
+	struct atk_data *data;
+	struct device_attribute label_attr;
+	struct device_attribute input_attr;
+	struct device_attribute limit1_attr;
+	struct device_attribute limit2_attr;
+	char label_attr_name[ATTR_NAME_SIZE];
+	char input_attr_name[ATTR_NAME_SIZE];
+	char limit1_attr_name[ATTR_NAME_SIZE];
+	char limit2_attr_name[ATTR_NAME_SIZE];
+	u64 id;
+	u64 type;
+	u64 limit1;
+	u64 limit2;
+	u64 cached_value;
+	unsigned long last_updated; /* in jiffies */
+	bool is_valid;
+	char const *acpi_name;
+};
+
+struct atk_acpi_buffer_u64 {
+	union acpi_object buf;
+	u64 value;
+};
+
+static int atk_add(struct acpi_device *device);
+static int atk_remove(struct acpi_device *device, int type);
+static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
+static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
+static void atk_free_sensors(struct atk_data *data);
+
+static struct acpi_driver atk_driver = {
+	.name	= ATK_HID,
+	.class	= "hwmon",
+	.ids	= atk_ids,
+	.ops	= {
+		.add	= atk_add,
+		.remove	= atk_remove,
+	},
+};
+
+#define input_to_atk_sensor(attr) \
+	container_of(attr, struct atk_sensor_data, input_attr)
+
+#define label_to_atk_sensor(attr) \
+	container_of(attr, struct atk_sensor_data, label_attr)
+
+#define limit1_to_atk_sensor(attr) \
+	container_of(attr, struct atk_sensor_data, limit1_attr)
+
+#define limit2_to_atk_sensor(attr) \
+	container_of(attr, struct atk_sensor_data, limit2_attr)
+
+static ssize_t atk_input_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct atk_sensor_data *s = input_to_atk_sensor(attr);
+	u64 value;
+	int err;
+
+	err = atk_read_value(s, &value);
+	if (err)
+		return err;
+
+	if (s->type == HWMON_TYPE_TEMP)
+		/* ACPI returns decidegree */
+		value *= 100;
+
+	return sprintf(buf, "%llu\n", value);
+}
+
+static ssize_t atk_label_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct atk_sensor_data *s = label_to_atk_sensor(attr);
+
+	return sprintf(buf, "%s\n", s->acpi_name);
+}
+
+static ssize_t atk_limit1_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct atk_sensor_data *s = limit1_to_atk_sensor(attr);
+	u64 value = s->limit1;
+
+	if (s->type == HWMON_TYPE_TEMP)
+		value *= 100;
+
+	return sprintf(buf, "%lld\n", value);
+}
+
+static ssize_t atk_limit2_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct atk_sensor_data *s = limit2_to_atk_sensor(attr);
+	u64 value = s->limit2;
+
+	if (s->type == HWMON_TYPE_TEMP)
+		value *= 100;
+
+	return sprintf(buf, "%lld\n", value);
+}
+
+static ssize_t atk_name_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "atk0110\n");
+}
+static struct device_attribute atk_name_attr =
+		__ATTR(name, 0444, atk_name_show, NULL);
+
+static void atk_init_attribute(struct device_attribute *attr, char *name,
+		sysfs_show_func show)
+{
+	attr->attr.name = name;
+	attr->attr.mode = 0444;
+	attr->show = show;
+	attr->store = NULL;
+}
+
+
+static union acpi_object *atk_get_pack_member(struct atk_data *data,
+						union acpi_object *pack,
+						enum atk_pack_member m)
+{
+	bool old_if = data->old_interface;
+	int offset;
+
+	switch (m) {
+	case HWMON_PACK_FLAGS:
+		offset = old_if ? _HWMON_OLD_PACK_FLAGS : _HWMON_NEW_PACK_FLAGS;
+		break;
+	case HWMON_PACK_NAME:
+		offset = old_if ? _HWMON_OLD_PACK_NAME : _HWMON_NEW_PACK_NAME;
+		break;
+	case HWMON_PACK_LIMIT1:
+		offset = old_if ? _HWMON_OLD_PACK_LIMIT1 :
+				  _HWMON_NEW_PACK_LIMIT1;
+		break;
+	case HWMON_PACK_LIMIT2:
+		offset = old_if ? _HWMON_OLD_PACK_LIMIT2 :
+				  _HWMON_NEW_PACK_LIMIT2;
+		break;
+	case HWMON_PACK_ENABLE:
+		offset = old_if ? _HWMON_OLD_PACK_ENABLE :
+				  _HWMON_NEW_PACK_ENABLE;
+		break;
+	default:
+		return NULL;
+	}
+
+	return &pack->package.elements[offset];
+}
+
+
+/* New package format is:
+ * - flag (int)
+ *	class - used for de-muxing the request to the correct GITn
+ *	type (volt, temp, fan)
+ *	sensor id |
+ *	sensor id - used for de-muxing the request _inside_ the GITn
+ * - name (str)
+ * - unknown (int)
+ * - unknown (int)
+ * - limit1 (int)
+ * - limit2 (int)
+ * - enable (int)
+ *
+ * The old package has the same format but it's missing the two unknown fields.
+ */
+static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	union acpi_object *tmp;
+	bool old_if = data->old_interface;
+	int const expected_size = old_if ? _HWMON_OLD_PACK_SIZE :
+					   _HWMON_NEW_PACK_SIZE;
+
+	if (obj->type != ACPI_TYPE_PACKAGE) {
+		dev_warn(dev, "Invalid type: %d\n", obj->type);
+		return -EINVAL;
+	}
+
+	if (obj->package.count != expected_size) {
+		dev_warn(dev, "Invalid package size: %d, expected: %d\n",
+				obj->package.count, expected_size);
+		return -EINVAL;
+	}
+
+	tmp = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (flag): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	tmp = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+	if (tmp->type != ACPI_TYPE_STRING) {
+		dev_warn(dev, "Invalid type (name): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	/* Don't check... we don't know what they're useful for anyway */
+#if 0
+	tmp = &obj->package.elements[HWMON_PACK_UNK1];
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (unk1): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	tmp = &obj->package.elements[HWMON_PACK_UNK2];
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (unk2): %d\n", tmp->type);
+		return -EINVAL;
+	}
+#endif
+
+	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (limit1): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (limit2): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	tmp = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+	if (tmp->type != ACPI_TYPE_INTEGER) {
+		dev_warn(dev, "Invalid type (enable): %d\n", tmp->type);
+		return -EINVAL;
+	}
+
+	atk_print_sensor(data, obj);
+
+	return 0;
+}
+
+#ifdef DEBUG
+static char const *atk_sensor_type(union acpi_object *flags)
+{
+	u64 type = flags->integer.value & ATK_TYPE_MASK;
+	char const *what;
+
+	switch (type) {
+	case HWMON_TYPE_VOLT:
+		what = "voltage";
+		break;
+	case HWMON_TYPE_TEMP:
+		what = "temperature";
+		break;
+	case HWMON_TYPE_FAN:
+		what = "fan";
+		break;
+	default:
+		what = "unknown";
+		break;
+	}
+
+	return what;
+}
+#endif
+
+static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
+{
+#ifdef DEBUG
+	struct device *dev = &data->acpi_dev->dev;
+	union acpi_object *flags;
+	union acpi_object *name;
+	union acpi_object *limit1;
+	union acpi_object *limit2;
+	union acpi_object *enable;
+	char const *what;
+
+	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+
+	what = atk_sensor_type(flags);
+
+	dev_dbg(dev, "%s: %#llx %s [%llu-%llu] %s\n", what,
+			flags->integer.value,
+			name->string.pointer,
+			limit1->integer.value, limit2->integer.value,
+			enable->integer.value ? "enabled" : "disabled");
+#endif
+}
+
+static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value)
+{
+	struct atk_data *data = sensor->data;
+	struct device *dev = &data->acpi_dev->dev;
+	struct acpi_object_list params;
+	union acpi_object id;
+	acpi_status status;
+	acpi_handle method;
+
+	switch (sensor->type) {
+	case HWMON_TYPE_VOLT:
+		method = data->rvlt_handle;
+		break;
+	case HWMON_TYPE_TEMP:
+		method = data->rtmp_handle;
+		break;
+	case HWMON_TYPE_FAN:
+		method = data->rfan_handle;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	id.type = ACPI_TYPE_INTEGER;
+	id.integer.value = sensor->id;
+
+	params.count = 1;
+	params.pointer = &id;
+
+	status = acpi_evaluate_integer(method, NULL, &params, value);
+	if (status != AE_OK) {
+		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
+				acpi_format_exception(status));
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
+{
+	struct atk_data *data = sensor->data;
+	struct device *dev = &data->acpi_dev->dev;
+	struct acpi_object_list params;
+	struct acpi_buffer ret;
+	union acpi_object id;
+	struct atk_acpi_buffer_u64 tmp;
+	acpi_status status;
+
+	id.type = ACPI_TYPE_INTEGER;
+	id.integer.value = sensor->id;
+
+	params.count = 1;
+	params.pointer = &id;
+
+	tmp.buf.type = ACPI_TYPE_BUFFER;
+	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
+	tmp.buf.buffer.length = sizeof(u64);
+	ret.length = sizeof(tmp);
+	ret.pointer = &tmp;
+
+	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
+			&ret, ACPI_TYPE_BUFFER);
+	if (status != AE_OK) {
+		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
+				acpi_format_exception(status));
+		return -EIO;
+	}
+
+	/* Return buffer format:
+	 * [0-3] "value" is valid flag
+	 * [4-7] value
+	 */
+	if (!(tmp.value & 0xffffffff)) {
+		/* The reading is not valid, possible causes:
+		 * - sensor failure
+		 * - enumeration was FUBAR (and we didn't notice)
+		 */
+		dev_info(dev, "Failure: %#llx\n", tmp.value);
+		return -EIO;
+	}
+
+	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
+
+	return 0;
+}
+
+static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
+{
+	int err;
+
+	if (!sensor->is_valid ||
+	    time_after(jiffies, sensor->last_updated + CACHE_TIME)) {
+		if (sensor->data->old_interface)
+			err = atk_read_value_old(sensor, value);
+		else
+			err = atk_read_value_new(sensor, value);
+
+		sensor->is_valid = true;
+		sensor->last_updated = jiffies;
+		sensor->cached_value = *value;
+	} else {
+		*value = sensor->cached_value;
+		err = 0;
+	}
+
+	return err;
+}
+
+static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	union acpi_object *flags;
+	union acpi_object *name;
+	union acpi_object *limit1;
+	union acpi_object *limit2;
+	union acpi_object *enable;
+	struct atk_sensor_data *sensor;
+	char const *base_name;
+	char const *limit1_name;
+	char const *limit2_name;
+	u64 type;
+	int err;
+	int *num;
+	int start;
+
+	if (obj->type != ACPI_TYPE_PACKAGE) {
+		/* wft is this? */
+		dev_warn(dev, "Unknown type for ACPI object: (%d)\n",
+				obj->type);
+		return -EINVAL;
+	}
+
+	err = validate_hwmon_pack(data, obj);
+	if (err)
+		return err;
+
+	/* Ok, we have a valid hwmon package */
+	type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value
+	       & ATK_TYPE_MASK;
+
+	switch (type) {
+	case HWMON_TYPE_VOLT:
+		base_name = "in";
+		limit1_name = "min";
+		limit2_name = "max";
+		num = &data->voltage_count;
+		start = 0;
+		break;
+	case HWMON_TYPE_TEMP:
+		base_name = "temp";
+		limit1_name = "max";
+		limit2_name = "crit";
+		num = &data->temperature_count;
+		start = 1;
+		break;
+	case HWMON_TYPE_FAN:
+		base_name = "fan";
+		limit1_name = "min";
+		limit2_name = "max";
+		num = &data->fan_count;
+		start = 1;
+		break;
+	default:
+		dev_warn(dev, "Unknown sensor type: %#llx\n", type);
+		return -EINVAL;
+	}
+
+	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
+	if (!enable->integer.value)
+		/* sensor is disabled */
+		return 0;
+
+	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
+	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
+	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
+	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
+
+	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+	if (!sensor)
+		return -ENOMEM;
+
+	sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
+	if (!sensor->acpi_name) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&sensor->list);
+	sensor->type = type;
+	sensor->data = data;
+	sensor->id = flags->integer.value;
+	sensor->limit1 = limit1->integer.value;
+	sensor->limit2 = limit2->integer.value;
+
+	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
+			"%s%d_input", base_name, start + *num);
+	atk_init_attribute(&sensor->input_attr,
+			sensor->input_attr_name,
+			atk_input_show);
+
+	snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
+			"%s%d_label", base_name, start + *num);
+	atk_init_attribute(&sensor->label_attr,
+			sensor->label_attr_name,
+			atk_label_show);
+
+	snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
+			"%s%d_%s", base_name, start + *num, limit1_name);
+	atk_init_attribute(&sensor->limit1_attr,
+			sensor->limit1_attr_name,
+			atk_limit1_show);
+
+	snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
+			"%s%d_%s", base_name, start + *num, limit2_name);
+	atk_init_attribute(&sensor->limit2_attr,
+			sensor->limit2_attr_name,
+			atk_limit2_show);
+
+	list_add(&sensor->list, &data->sensor_list);
+	(*num)++;
+
+	return 1;
+out:
+	kfree(sensor->acpi_name);
+	kfree(sensor);
+	return err;
+}
+
+static int atk_enumerate_old_hwmon(struct atk_data *data)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	struct acpi_buffer buf;
+	union acpi_object *pack;
+	acpi_status status;
+	int i, ret;
+	int count = 0;
+
+	/* Voltages */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	status = acpi_evaluate_object_typed(data->atk_handle,
+			METHOD_OLD_ENUM_VLT, NULL, &buf, ACPI_TYPE_PACKAGE);
+	if (status != AE_OK) {
+		dev_warn(dev, METHOD_OLD_ENUM_VLT ": ACPI exception: %s\n",
+				acpi_format_exception(status));
+
+		return -ENODEV;
+	}
+
+	pack = buf.pointer;
+	for (i = 1; i < pack->package.count; i++) {
+		union acpi_object *obj = &pack->package.elements[i];
+
+		ret = atk_add_sensor(data, obj);
+		if (ret > 0)
+			count++;
+	}
+	ACPI_FREE(buf.pointer);
+
+	/* Temperatures */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	status = acpi_evaluate_object_typed(data->atk_handle,
+			METHOD_OLD_ENUM_TMP, NULL, &buf, ACPI_TYPE_PACKAGE);
+	if (status != AE_OK) {
+		dev_warn(dev, METHOD_OLD_ENUM_TMP ": ACPI exception: %s\n",
+				acpi_format_exception(status));
+
+		ret = -ENODEV;
+		goto cleanup;
+	}
+
+	pack = buf.pointer;
+	for (i = 1; i < pack->package.count; i++) {
+		union acpi_object *obj = &pack->package.elements[i];
+
+		ret = atk_add_sensor(data, obj);
+		if (ret > 0)
+			count++;
+	}
+	ACPI_FREE(buf.pointer);
+
+	/* Fans */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	status = acpi_evaluate_object_typed(data->atk_handle,
+			METHOD_OLD_ENUM_FAN, NULL, &buf, ACPI_TYPE_PACKAGE);
+	if (status != AE_OK) {
+		dev_warn(dev, METHOD_OLD_ENUM_FAN ": ACPI exception: %s\n",
+				acpi_format_exception(status));
+
+		ret = -ENODEV;
+		goto cleanup;
+	}
+
+	pack = buf.pointer;
+	for (i = 1; i < pack->package.count; i++) {
+		union acpi_object *obj = &pack->package.elements[i];
+
+		ret = atk_add_sensor(data, obj);
+		if (ret > 0)
+			count++;
+	}
+	ACPI_FREE(buf.pointer);
+
+	return count;
+cleanup:
+	atk_free_sensors(data);
+	return ret;
+}
+
+static int atk_enumerate_new_hwmon(struct atk_data *data)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	struct acpi_buffer buf;
+	acpi_status ret;
+	struct acpi_object_list params;
+	union acpi_object id;
+	union acpi_object *pack;
+	int err;
+	int i;
+
+	dev_dbg(dev, "Enumerating hwmon sensors\n");
+
+	id.type = ACPI_TYPE_INTEGER;
+	id.integer.value = ATK_MUX_HWMON;
+	params.count = 1;
+	params.pointer = &id;
+
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params,
+			&buf, ACPI_TYPE_PACKAGE);
+	if (ret != AE_OK) {
+		dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
+				acpi_format_exception(ret));
+		return -ENODEV;
+	}
+
+	/* Result must be a package */
+	pack = buf.pointer;
+
+	if (pack->package.count < 1) {
+		dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__,
+				pack->package.count);
+		err = -EINVAL;
+		goto out;
+	}
+
+	for (i = 0; i < pack->package.count; i++) {
+		union acpi_object *obj = &pack->package.elements[i];
+
+		atk_add_sensor(data, obj);
+	}
+
+	err = data->voltage_count + data->temperature_count + data->fan_count;
+
+out:
+	ACPI_FREE(buf.pointer);
+	return err;
+}
+
+static int atk_create_files(struct atk_data *data)
+{
+	struct atk_sensor_data *s;
+	int err;
+
+	list_for_each_entry(s, &data->sensor_list, list) {
+		err = device_create_file(data->hwmon_dev, &s->input_attr);
+		if (err)
+			return err;
+		err = device_create_file(data->hwmon_dev, &s->label_attr);
+		if (err)
+			return err;
+		err = device_create_file(data->hwmon_dev, &s->limit1_attr);
+		if (err)
+			return err;
+		err = device_create_file(data->hwmon_dev, &s->limit2_attr);
+		if (err)
+			return err;
+	}
+
+	err = device_create_file(data->hwmon_dev, &atk_name_attr);
+
+	return err;
+}
+
+static void atk_remove_files(struct atk_data *data)
+{
+	struct atk_sensor_data *s;
+
+	list_for_each_entry(s, &data->sensor_list, list) {
+		device_remove_file(data->hwmon_dev, &s->input_attr);
+		device_remove_file(data->hwmon_dev, &s->label_attr);
+		device_remove_file(data->hwmon_dev, &s->limit1_attr);
+		device_remove_file(data->hwmon_dev, &s->limit2_attr);
+	}
+	device_remove_file(data->hwmon_dev, &atk_name_attr);
+}
+
+static void atk_free_sensors(struct atk_data *data)
+{
+	struct list_head *head = &data->sensor_list;
+	struct atk_sensor_data *s, *tmp;
+
+	list_for_each_entry_safe(s, tmp, head, list) {
+		kfree(s->acpi_name);
+		kfree(s);
+	}
+}
+
+static int atk_register_hwmon(struct atk_data *data)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	int err;
+
+	dev_dbg(dev, "registering hwmon device\n");
+	data->hwmon_dev = hwmon_device_register(dev);
+	if (IS_ERR(data->hwmon_dev))
+		return PTR_ERR(data->hwmon_dev);
+
+	dev_dbg(dev, "populating sysfs directory\n");
+	err = atk_create_files(data);
+	if (err)
+		goto remove;
+
+	return 0;
+remove:
+	/* Cleanup the registered files */
+	atk_remove_files(data);
+	hwmon_device_unregister(data->hwmon_dev);
+	return err;
+}
+
+static int atk_check_old_if(struct atk_data *data)
+{
+	struct device *dev = &data->acpi_dev->dev;
+	acpi_handle ret;
+	acpi_status status;
+
+	/* RTMP: read temperature */
+	status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret);
+	if (status != AE_OK) {
+		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) {
+		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) {
+		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) {
+		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) {
+		dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
+				acpi_format_exception(status));
+		return -ENODEV;
+	}
+	data->read_handle = ret;
+
+	return 0;
+}
+
+static int atk_add(struct acpi_device *device)
+{
+	acpi_status ret;
+	int err;
+	struct acpi_buffer buf;
+	union acpi_object *obj;
+	struct atk_data *data;
+
+	dev_dbg(&device->dev, "adding...\n");
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->acpi_dev = device;
+	data->atk_handle = device->handle;
+	INIT_LIST_HEAD(&data->sensor_list);
+
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
+			&buf, ACPI_TYPE_PACKAGE);
+	if (ret != AE_OK) {
+		dev_dbg(&device->dev, "atk: method MBIF not found\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	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);
+	}
+	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) {
+		dev_dbg(&device->dev, "Using old hwmon interface\n");
+		data->old_interface = true;
+	} 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) {
+		dev_info(&device->dev,
+			 "No usable sensor detected, bailing out\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	err = atk_register_hwmon(data);
+	if (err)
+		goto cleanup;
+
+	device->driver_data = data;
+	return 0;
+cleanup:
+	atk_free_sensors(data);
+out:
+	kfree(data);
+	return err;
+}
+
+static int atk_remove(struct acpi_device *device, int type)
+{
+	struct atk_data *data = device->driver_data;
+	dev_dbg(&device->dev, "removing...\n");
+
+	device->driver_data = NULL;
+
+	atk_remove_files(data);
+	atk_free_sensors(data);
+	hwmon_device_unregister(data->hwmon_dev);
+
+	kfree(data);
+
+	return 0;
+}
+
+static int __init atk0110_init(void)
+{
+	int ret;
+
+	ret = acpi_bus_register_driver(&atk_driver);
+	if (ret)
+		pr_info("atk: acpi_bus_register_driver failed: %d\n", ret);
+
+	return ret;
+}
+
+static void __exit atk0110_exit(void)
+{
+	acpi_bus_unregister_driver(&atk_driver);
+}
+
+module_init(atk0110_init);
+module_exit(atk0110_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/ds1621.c linux-libre-2.6.30-gnu1/drivers/hwmon/ds1621.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/ds1621.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/ds1621.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,71 +81,84 @@ struct ds1621_data {
 	u8 conf;			/* Register encoding, combined */
 };
 
-static int ds1621_probe(struct i2c_client *client,
-			const struct i2c_device_id *id);
-static int ds1621_detect(struct i2c_client *client, int kind,
-			 struct i2c_board_info *info);
-static void ds1621_init_client(struct i2c_client *client);
-static int ds1621_remove(struct i2c_client *client);
-static struct ds1621_data *ds1621_update_client(struct device *dev);
-
-static const struct i2c_device_id ds1621_id[] = {
-	{ "ds1621", ds1621 },
-	{ "ds1625", ds1621 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, ds1621_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ds1621_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "ds1621",
-	},
-	.probe		= ds1621_probe,
-	.remove		= ds1621_remove,
-	.id_table	= ds1621_id,
-	.detect		= ds1621_detect,
-	.address_data	= &addr_data,
-};
-
-/* All registers are word-sized, except for the configuration register.
+/* Temperature registers are word-sized.
    DS1621 uses a high-byte first convention, which is exactly opposite to
    the SMBus standard. */
-static int ds1621_read_value(struct i2c_client *client, u8 reg)
+static int ds1621_read_temp(struct i2c_client *client, u8 reg)
 {
-	if (reg == DS1621_REG_CONF)
-		return i2c_smbus_read_byte_data(client, reg);
-	else
-		return swab16(i2c_smbus_read_word_data(client, reg));
+	int ret;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+	return swab16(ret);
 }
 
-static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
+static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
 {
-	if (reg == DS1621_REG_CONF)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	else
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
+	return i2c_smbus_write_word_data(client, reg, swab16(value));
 }
 
 static void ds1621_init_client(struct i2c_client *client)
 {
-	int reg = ds1621_read_value(client, DS1621_REG_CONF);
+	u8 conf, new_conf;
+
+	new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
 	/* switch to continuous conversion mode */
-	reg &= ~ DS1621_REG_CONFIG_1SHOT;
+	new_conf &= ~DS1621_REG_CONFIG_1SHOT;
 
 	/* setup output polarity */
 	if (polarity == 0)
-		reg &= ~DS1621_REG_CONFIG_POLARITY;
+		new_conf &= ~DS1621_REG_CONFIG_POLARITY;
 	else if (polarity == 1)
-		reg |= DS1621_REG_CONFIG_POLARITY;
+		new_conf |= DS1621_REG_CONFIG_POLARITY;
 	
-	ds1621_write_value(client, DS1621_REG_CONF, reg);
+	if (conf != new_conf)
+		i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
 	
 	/* start conversion */
 	i2c_smbus_write_byte(client, DS1621_COM_START);
 }
 
+static struct ds1621_data *ds1621_update_client(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
+	u8 new_conf;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		int i;
+
+		dev_dbg(&client->dev, "Starting ds1621 update\n");
+
+		data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+
+		for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+			data->temp[i] = ds1621_read_temp(client,
+							 DS1621_REG_TEMP[i]);
+
+		/* reset alarms if necessary */
+		new_conf = data->conf;
+		if (data->temp[0] > data->temp[1])	/* input > min */
+			new_conf &= ~DS1621_ALARM_TEMP_LOW;
+		if (data->temp[0] < data->temp[2])	/* input < max */
+			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
+		if (data->conf != new_conf)
+			i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
+						  new_conf);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
 static ssize_t show_temp(struct device *dev, struct device_attribute *da,
 			 char *buf)
 {
@@ -160,13 +173,13 @@ static ssize_t set_temp(struct device *d
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct i2c_client *client = to_i2c_client(dev);
-	struct ds1621_data *data = ds1621_update_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
 	u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
 
 	mutex_lock(&data->update_lock);
 	data->temp[attr->index] = val;
-	ds1621_write_value(client, DS1621_REG_TEMP[attr->index],
-			   data->temp[attr->index]);
+	ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
+			  data->temp[attr->index]);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -228,13 +241,14 @@ static int ds1621_detect(struct i2c_clie
 		/* 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 = ds1621_read_value(client, DS1621_REG_CONF);
-		if (conf & DS1621_REG_CONFIG_NVB)
+		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 = ds1621_read_value(client, DS1621_REG_TEMP[i]);
-			if (temp & 0x007f)
+			temp = i2c_smbus_read_word_data(client,
+							DS1621_REG_TEMP[i]);
+			if (temp < 0 || (temp & 0x7f00))
 				return -ENODEV;
 		}
 	}
@@ -294,45 +308,25 @@ static int ds1621_remove(struct i2c_clie
 	return 0;
 }
 
+static const struct i2c_device_id ds1621_id[] = {
+	{ "ds1621", ds1621 },
+	{ "ds1625", ds1621 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ds1621_id);
 
-static struct ds1621_data *ds1621_update_client(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ds1621_data *data = i2c_get_clientdata(client);
-	u8 new_conf;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		int i;
-
-		dev_dbg(&client->dev, "Starting ds1621 update\n");
-
-		data->conf = ds1621_read_value(client, DS1621_REG_CONF);
-
-		for (i = 0; i < ARRAY_SIZE(data->temp); i++)
-			data->temp[i] = ds1621_read_value(client,
-							  DS1621_REG_TEMP[i]);
-
-		/* reset alarms if necessary */
-		new_conf = data->conf;
-		if (data->temp[0] > data->temp[1])	/* input > min */
-			new_conf &= ~DS1621_ALARM_TEMP_LOW;
-		if (data->temp[0] < data->temp[2])	/* input < max */
-			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
-		if (data->conf != new_conf)
-			ds1621_write_value(client, DS1621_REG_CONF,
-					   new_conf);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
-
-	return data;
-}
+/* This is the driver that will be inserted */
+static struct i2c_driver ds1621_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "ds1621",
+	},
+	.probe		= ds1621_probe,
+	.remove		= ds1621_remove,
+	.id_table	= ds1621_id,
+	.detect		= ds1621_detect,
+	.address_data	= &addr_data,
+};
 
 static int __init ds1621_init(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/f75375s.c linux-libre-2.6.30-gnu1/drivers/hwmon/f75375s.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/f75375s.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/f75375s.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * f75375s.c - driver for the Fintek F75375/SP and F75373
  *             hardware monitoring features
- * Copyright (C) 2006-2007  Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2006-2007  Riku Voipio
  *
  * Datasheets available at:
  *
@@ -721,7 +721,7 @@ static void __exit sensors_f75375_exit(v
 	i2c_del_driver(&f75375_driver);
 }
 
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/fschmd.c linux-libre-2.6.30-gnu1/drivers/hwmon/fschmd.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/fschmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/fschmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /* fschmd.c
  *
- * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@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
@@ -19,7 +19,7 @@
 
 /*
  *  Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
- *  Scylla, Heracles and Heimdall chips
+ *  Scylla, Heracles, Heimdall, Hades and Syleus chips
  *
  *  Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6
  *  (candidate) fschmd drivers:
@@ -56,7 +56,7 @@ 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_5(fscpos, fscher, fscscy, fschrc, fschmd);
+I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl);
 
 /*
  * The FSCHMD registers and other defines
@@ -75,9 +75,12 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscs
 #define FSCHMD_CONTROL_ALERT_LED	0x01
 
 /* watchdog */
-#define FSCHMD_REG_WDOG_PRESET		0x28
-#define FSCHMD_REG_WDOG_STATE		0x23
-#define FSCHMD_REG_WDOG_CONTROL		0x21
+static const u8 FSCHMD_REG_WDOG_CONTROL[7] =
+	{ 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
+static const u8 FSCHMD_REG_WDOG_STATE[7] =
+	{ 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
+static const u8 FSCHMD_REG_WDOG_PRESET[7] =
+	{ 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
 
 #define FSCHMD_WDOG_CONTROL_TRIGGER	0x10
 #define FSCHMD_WDOG_CONTROL_STARTED	0x10 /* the same as trigger */
@@ -87,70 +90,95 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscs
 #define FSCHMD_WDOG_STATE_CARDRESET	0x02
 
 /* voltages, weird order is to keep the same order as the old drivers */
-static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
+static const u8 FSCHMD_REG_VOLT[7][6] = {
+	{ 0x45, 0x42, 0x48 },				/* pos */
+	{ 0x45, 0x42, 0x48 },				/* her */
+	{ 0x45, 0x42, 0x48 },				/* scy */
+	{ 0x45, 0x42, 0x48 },				/* hrc */
+	{ 0x45, 0x42, 0x48 },				/* hmd */
+	{ 0x21, 0x20, 0x22 },				/* hds */
+	{ 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 },		/* syl */
+};
+
+static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
 
 /* minimum pwm at which the fan is driven (pwm can by increased depending on
    the temp. Notice that for the scy some fans share there minimum speed.
    Also notice that with the scy the sensor order is different than with the
    other chips, this order was in the 2.4 driver and kept for consistency. */
-static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
+static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
 	{ 0x55, 0x65 },					/* pos */
 	{ 0x55, 0x65, 0xb5 },				/* her */
 	{ 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 },		/* scy */
 	{ 0x55, 0x65, 0xa5, 0xb5 },			/* hrc */
 	{ 0x55, 0x65, 0xa5, 0xb5, 0xc5 },		/* hmd */
+	{ 0x55, 0x65, 0xa5, 0xb5, 0xc5 },		/* hds */
+	{ 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 },	/* syl */
 };
 
 /* actual fan speed */
-static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
+static const u8 FSCHMD_REG_FAN_ACT[7][7] = {
 	{ 0x0e, 0x6b, 0xab },				/* pos */
 	{ 0x0e, 0x6b, 0xbb },				/* her */
 	{ 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb },		/* scy */
 	{ 0x0e, 0x6b, 0xab, 0xbb },			/* hrc */
 	{ 0x5b, 0x6b, 0xab, 0xbb, 0xcb },		/* hmd */
+	{ 0x5b, 0x6b, 0xab, 0xbb, 0xcb },		/* hds */
+	{ 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 },	/* syl */
 };
 
 /* fan status registers */
-static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
+static const u8 FSCHMD_REG_FAN_STATE[7][7] = {
 	{ 0x0d, 0x62, 0xa2 },				/* pos */
 	{ 0x0d, 0x62, 0xb2 },				/* her */
 	{ 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 },		/* scy */
 	{ 0x0d, 0x62, 0xa2, 0xb2 },			/* hrc */
 	{ 0x52, 0x62, 0xa2, 0xb2, 0xc2 },		/* hmd */
+	{ 0x52, 0x62, 0xa2, 0xb2, 0xc2 },		/* hds */
+	{ 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 },	/* syl */
 };
 
 /* fan ripple / divider registers */
-static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
+static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = {
 	{ 0x0f, 0x6f, 0xaf },				/* pos */
 	{ 0x0f, 0x6f, 0xbf },				/* her */
 	{ 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf },		/* scy */
 	{ 0x0f, 0x6f, 0xaf, 0xbf },			/* hrc */
 	{ 0x5f, 0x6f, 0xaf, 0xbf, 0xcf },		/* hmd */
+	{ 0x5f, 0x6f, 0xaf, 0xbf, 0xcf },		/* hds */
+	{ 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 },	/* syl */
 };
 
-static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
+static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 };
 
 /* Fan status register bitmasks */
 #define FSCHMD_FAN_ALARM	0x04 /* called fault by FSC! */
-#define FSCHMD_FAN_NOT_PRESENT	0x08 /* not documented */
+#define FSCHMD_FAN_NOT_PRESENT	0x08
+#define FSCHMD_FAN_DISABLED	0x80
 
 
 /* actual temperature registers */
-static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_ACT[7][11] = {
 	{ 0x64, 0x32, 0x35 },				/* pos */
 	{ 0x64, 0x32, 0x35 },				/* her */
 	{ 0x64, 0xD0, 0x32, 0x35 },			/* scy */
 	{ 0x64, 0x32, 0x35 },				/* hrc */
 	{ 0x70, 0x80, 0x90, 0xd0, 0xe0 },		/* hmd */
+	{ 0x70, 0x80, 0x90, 0xd0, 0xe0 },		/* hds */
+	{ 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8,		/* syl */
+	  0xb8, 0xc8, 0xd8, 0xe8, 0xf8 },
 };
 
 /* temperature state registers */
-static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
+static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
 	{ 0x71, 0x81, 0x91 },				/* pos */
 	{ 0x71, 0x81, 0x91 },				/* her */
 	{ 0x71, 0xd1, 0x81, 0x91 },			/* scy */
 	{ 0x71, 0x81, 0x91 },				/* hrc */
 	{ 0x71, 0x81, 0x91, 0xd1, 0xe1 },		/* hmd */
+	{ 0x71, 0x81, 0x91, 0xd1, 0xe1 },		/* hds */
+	{ 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9,		/* syl */
+	  0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
 };
 
 /* temperature high limit registers, FSC does not document these. Proven to be
@@ -158,24 +186,31 @@ static const u8 FSCHMD_REG_TEMP_STATE[5]
    in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
    at these addresses, but doesn't want to confirm they are the same as with
    the fscher?? */
-static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
 	{ 0, 0, 0 },					/* pos */
 	{ 0x76, 0x86, 0x96 },				/* her */
 	{ 0x76, 0xd6, 0x86, 0x96 },			/* scy */
 	{ 0x76, 0x86, 0x96 },				/* hrc */
 	{ 0x76, 0x86, 0x96, 0xd6, 0xe6 },		/* hmd */
+	{ 0x76, 0x86, 0x96, 0xd6, 0xe6 },		/* hds */
+	{ 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa,		/* syl */
+	  0xba, 0xca, 0xda, 0xea, 0xfa },
 };
 
 /* These were found through experimenting with an fscher, currently they are
    not used, but we keep them around for future reference.
+   On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
+   AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
+   the fan speed.
 static const u8 FSCHER_REG_TEMP_AUTOP1[] =	{ 0x73, 0x83, 0x93 };
 static const u8 FSCHER_REG_TEMP_AUTOP2[] =	{ 0x75, 0x85, 0x95 }; */
 
-static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
+static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
 
 /* temp status register bitmasks */
 #define FSCHMD_TEMP_WORKING	0x01
 #define FSCHMD_TEMP_ALERT	0x02
+#define FSCHMD_TEMP_DISABLED	0x80
 /* there only really is an alarm if the sensor is working and alert == 1 */
 #define FSCHMD_TEMP_ALARM_MASK \
 	(FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
@@ -201,6 +236,8 @@ static const struct i2c_device_id fschmd
 	{ "fscscy", fscscy },
 	{ "fschrc", fschrc },
 	{ "fschmd", fschmd },
+	{ "fschds", fschds },
+	{ "fscsyl", fscsyl },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, fschmd_id);
@@ -242,14 +279,14 @@ struct fschmd_data {
 	u8 watchdog_control;    /* watchdog control register */
 	u8 watchdog_state;      /* watchdog status register */
 	u8 watchdog_preset;     /* watchdog counter preset on trigger val */
-	u8 volt[3];		/* 12, 5, battery voltage */
-	u8 temp_act[5];		/* temperature */
-	u8 temp_status[5];	/* status of sensor */
-	u8 temp_max[5];		/* high temp limit, notice: undocumented! */
-	u8 fan_act[6];		/* fans revolutions per second */
-	u8 fan_status[6];	/* fan status */
-	u8 fan_min[6];		/* fan min value for rps */
-	u8 fan_ripple[6];	/* divider for rps */
+	u8 volt[6];		/* voltage */
+	u8 temp_act[11];	/* temperature */
+	u8 temp_status[11];	/* status of sensor */
+	u8 temp_max[11];	/* high temp limit, notice: undocumented! */
+	u8 fan_act[7];		/* fans revolutions per second */
+	u8 fan_status[7];	/* fan status */
+	u8 fan_min[7];		/* fan min value for rps */
+	u8 fan_ripple[7];	/* divider for rps */
 };
 
 /* Global variables to hold information read from special DMI tables, which are
@@ -257,8 +294,8 @@ struct fschmd_data {
    protect these with a lock as they are only modified from our attach function
    which always gets called with the i2c-core lock held and never accessed
    before the attach function is done with them. */
-static int dmi_mult[3] = { 490, 200, 100 };
-static int dmi_offset[3] = { 0, 0, 0 };
+static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
+static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
 static int dmi_vref = -1;
 
 /* Somewhat ugly :( global data pointer list with all fschmd devices, so that
@@ -450,10 +487,11 @@ static ssize_t show_pwm_auto_point1_pwm(
 	struct device_attribute *devattr, char *buf)
 {
 	int index = to_sensor_dev_attr(devattr)->index;
-	int val = fschmd_update_device(dev)->fan_min[index];
+	struct fschmd_data *data = fschmd_update_device(dev);
+	int val = data->fan_min[index];
 
-	/* 0 = allow turning off, 1-255 = 50-100% */
-	if (val)
+	/* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+	if (val || data->kind == fscsyl - 1)
 		val = val / 2 + 128;
 
 	return sprintf(buf, "%d\n", val);
@@ -466,8 +504,8 @@ static ssize_t store_pwm_auto_point1_pwm
 	struct fschmd_data *data = dev_get_drvdata(dev);
 	unsigned long v = simple_strtoul(buf, NULL, 10);
 
-	/* register: 0 = allow turning off, 1-255 = 50-100% */
-	if (v) {
+	/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+	if (v || data->kind == fscsyl - 1) {
 		v = SENSORS_LIMIT(v, 128, 255);
 		v = (v - 128) * 2 + 1;
 	}
@@ -522,11 +560,15 @@ static ssize_t store_alert_led(struct de
 	return count;
 }
 
+static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led);
+
 static struct sensor_device_attribute fschmd_attr[] = {
 	SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
 	SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
 	SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
-	SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
+	SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3),
+	SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4),
+	SENSOR_ATTR(in5_input, 0444, show_in_value, NULL, 5),
 };
 
 static struct sensor_device_attribute fschmd_temp_attr[] = {
@@ -550,6 +592,30 @@ static struct sensor_device_attribute fs
 	SENSOR_ATTR(temp5_max,   0644, show_temp_max, store_temp_max, 4),
 	SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
 	SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
+	SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5),
+	SENSOR_ATTR(temp6_max,   0644, show_temp_max, store_temp_max, 5),
+	SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5),
+	SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5),
+	SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6),
+	SENSOR_ATTR(temp7_max,   0644, show_temp_max, store_temp_max, 6),
+	SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6),
+	SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6),
+	SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7),
+	SENSOR_ATTR(temp8_max,   0644, show_temp_max, store_temp_max, 7),
+	SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7),
+	SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7),
+	SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8),
+	SENSOR_ATTR(temp9_max,   0644, show_temp_max, store_temp_max, 8),
+	SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8),
+	SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8),
+	SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9),
+	SENSOR_ATTR(temp10_max,   0644, show_temp_max, store_temp_max, 9),
+	SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9),
+	SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9),
+	SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10),
+	SENSOR_ATTR(temp11_max,   0644, show_temp_max, store_temp_max, 10),
+	SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10),
+	SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10),
 };
 
 static struct sensor_device_attribute fschmd_fan_attr[] = {
@@ -589,6 +655,12 @@ static struct sensor_device_attribute fs
 	SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
 	SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
 		store_pwm_auto_point1_pwm, 5),
+	SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6),
+	SENSOR_ATTR(fan7_div,   0644, show_fan_div, store_fan_div, 6),
+	SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6),
+	SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6),
+	SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
+		store_pwm_auto_point1_pwm, 6),
 };
 
 
@@ -624,10 +696,11 @@ static int watchdog_set_timeout(struct f
 	data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
 
 	/* Write new timeout value */
-	i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET,
-		data->watchdog_preset);
+	i2c_smbus_write_byte_data(data->client,
+		FSCHMD_REG_WDOG_PRESET[data->kind], data->watchdog_preset);
 	/* Write new control register, do not trigger! */
-	i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+	i2c_smbus_write_byte_data(data->client,
+		FSCHMD_REG_WDOG_CONTROL[data->kind],
 		data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
 
 	ret = data->watchdog_preset * resolution;
@@ -662,8 +735,9 @@ static int watchdog_trigger(struct fschm
 	}
 
 	data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
-	i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
-					data->watchdog_control);
+	i2c_smbus_write_byte_data(data->client,
+				  FSCHMD_REG_WDOG_CONTROL[data->kind],
+				  data->watchdog_control);
 leave:
 	mutex_unlock(&data->watchdog_lock);
 	return ret;
@@ -682,7 +756,8 @@ static int watchdog_stop(struct fschmd_d
 	data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
 	/* Don't store the stop flag in our watchdog control register copy, as
 	   its a write only bit (read always returns 0) */
-	i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+	i2c_smbus_write_byte_data(data->client,
+		FSCHMD_REG_WDOG_CONTROL[data->kind],
 		data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
 leave:
 	mutex_unlock(&data->watchdog_lock);
@@ -856,7 +931,7 @@ static struct file_operations watchdog_f
 
 /* DMI decode routine to read voltage scaling factors from special DMI tables,
    which are available on FSC machines with an fscher or later chip. */
-static void fschmd_dmi_decode(const struct dmi_header *header)
+static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
 {
 	int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
 
@@ -912,6 +987,15 @@ static void fschmd_dmi_decode(const stru
 			dmi_mult[i] = mult[i] * 10;
 			dmi_offset[i] = offset[i] * 10;
 		}
+		/* According to the docs there should be separate dmi entries
+		   for the mult's and offsets of in3-5 of the syl, but on
+		   my test machine these are not present */
+		dmi_mult[3] = dmi_mult[2];
+		dmi_mult[4] = dmi_mult[1];
+		dmi_mult[5] = dmi_mult[2];
+		dmi_offset[3] = dmi_offset[2];
+		dmi_offset[4] = dmi_offset[1];
+		dmi_offset[5] = dmi_offset[2];
 		dmi_vref = vref;
 	}
 }
@@ -920,8 +1004,6 @@ static int fschmd_detect(struct i2c_clie
 			 struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
-						"fschrc", "fschmd" };
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
@@ -948,11 +1030,15 @@ static int fschmd_detect(struct i2c_clie
 			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, client_names[kind - 1], I2C_NAME_SIZE);
+	strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
 
 	return 0;
 }
@@ -961,8 +1047,8 @@ static int fschmd_probe(struct i2c_clien
 			const struct i2c_device_id *id)
 {
 	struct fschmd_data *data;
-	const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
-					"Heracles", "Heimdall" };
+	const char * const names[7] = { "Poseidon", "Hermes", "Scylla",
+				"Heracles", "Heimdall", "Hades", "Syleus" };
 	const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
 	int i, err;
 	enum chips kind = id->driver_data;
@@ -991,7 +1077,7 @@ static int fschmd_probe(struct i2c_clien
 
 	/* Read the special DMI table for fscher and newer chips */
 	if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
-		dmi_walk(fschmd_dmi_decode);
+		dmi_walk(fschmd_dmi_decode, NULL);
 		if (dmi_vref == -1) {
 			dev_warn(&client->dev,
 				"Couldn't get voltage scaling factors from "
@@ -1000,21 +1086,25 @@ static int fschmd_probe(struct i2c_clien
 		}
 	}
 
+	/* i2c kind goes from 1-6, we want from 0-5 to address arrays */
+	data->kind = kind - 1;
+
 	/* Read in some never changing registers */
 	data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
 	data->global_control = i2c_smbus_read_byte_data(client,
 					FSCHMD_REG_CONTROL);
 	data->watchdog_control = i2c_smbus_read_byte_data(client,
-					FSCHMD_REG_WDOG_CONTROL);
+					FSCHMD_REG_WDOG_CONTROL[data->kind]);
 	data->watchdog_state = i2c_smbus_read_byte_data(client,
-					FSCHMD_REG_WDOG_STATE);
+					FSCHMD_REG_WDOG_STATE[data->kind]);
 	data->watchdog_preset = i2c_smbus_read_byte_data(client,
-					FSCHMD_REG_WDOG_PRESET);
+					FSCHMD_REG_WDOG_PRESET[data->kind]);
 
-	/* i2c kind goes from 1-5, we want from 0-4 to address arrays */
-	data->kind = kind - 1;
+	err = device_create_file(&client->dev, &dev_attr_alert_led);
+	if (err)
+		goto exit_detach;
 
-	for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
+	for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) {
 		err = device_create_file(&client->dev,
 					&fschmd_attr[i].dev_attr);
 		if (err)
@@ -1027,6 +1117,16 @@ static int fschmd_probe(struct i2c_clien
 				show_temp_max)
 			continue;
 
+		if (kind == fscsyl) {
+			if (i % 4 == 0)
+				data->temp_status[i / 4] =
+					i2c_smbus_read_byte_data(client,
+						FSCHMD_REG_TEMP_STATE
+						[data->kind][i / 4]);
+			if (data->temp_status[i / 4] & FSCHMD_TEMP_DISABLED)
+				continue;
+		}
+
 		err = device_create_file(&client->dev,
 					&fschmd_temp_attr[i].dev_attr);
 		if (err)
@@ -1040,6 +1140,16 @@ static int fschmd_probe(struct i2c_clien
 					"pwm3_auto_point1_pwm"))
 			continue;
 
+		if (kind == fscsyl) {
+			if (i % 5 == 0)
+				data->fan_status[i / 5] =
+					i2c_smbus_read_byte_data(client,
+						FSCHMD_REG_FAN_STATE
+						[data->kind][i / 5]);
+			if (data->fan_status[i / 5] & FSCHMD_FAN_DISABLED)
+				continue;
+		}
+
 		err = device_create_file(&client->dev,
 					&fschmd_fan_attr[i].dev_attr);
 		if (err)
@@ -1126,7 +1236,8 @@ static int fschmd_remove(struct i2c_clie
 	if (data->hwmon_dev)
 		hwmon_device_unregister(data->hwmon_dev);
 
-	for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
+	device_remove_file(&client->dev, &dev_attr_alert_led);
+	for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->kind]); i++)
 		device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
 	for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
 		device_remove_file(&client->dev,
@@ -1171,7 +1282,7 @@ static struct fschmd_data *fschmd_update
 					data->temp_act[i] < data->temp_max[i])
 				i2c_smbus_write_byte_data(client,
 					FSCHMD_REG_TEMP_STATE[data->kind][i],
-					FSCHMD_TEMP_ALERT);
+					data->temp_status[i]);
 		}
 
 		for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
@@ -1193,12 +1304,12 @@ static struct fschmd_data *fschmd_update
 					data->fan_act[i])
 				i2c_smbus_write_byte_data(client,
 					FSCHMD_REG_FAN_STATE[data->kind][i],
-					FSCHMD_FAN_ALARM);
+					data->fan_status[i]);
 		}
 
-		for (i = 0; i < 3; i++)
+		for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++)
 			data->volt[i] = i2c_smbus_read_byte_data(client,
-						FSCHMD_REG_VOLT[i]);
+					       FSCHMD_REG_VOLT[data->kind][i]);
 
 		data->last_updated = jiffies;
 		data->valid = 1;
@@ -1220,8 +1331,8 @@ static void __exit fschmd_exit(void)
 }
 
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
-			"Heimdall driver");
+MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades "
+			"and Syleus driver");
 MODULE_LICENSE("GPL");
 
 module_init(fschmd_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/g760a.c linux-libre-2.6.30-gnu1/drivers/hwmon/g760a.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/g760a.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/g760a.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,272 @@
+/*
+    g760a - Driver for the Global Mixed-mode Technology Inc. G760A
+            fan speed PWM controller chip
+
+    Copyright (C) 2007  Herbert Valerio Riedel <hvr@gnu.org>
+
+    Complete datasheet is available at GMT's website:
+      http://www.gmt.com.tw/datasheet/g760a.pdf
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+*/
+
+#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>
+#include <linux/sysfs.h>
+
+static const struct i2c_device_id g760a_id[] = {
+	{ "g760a", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, g760a_id);
+
+enum g760a_regs {
+	G760A_REG_SET_CNT = 0x00,
+	G760A_REG_ACT_CNT = 0x01,
+	G760A_REG_FAN_STA = 0x02
+};
+
+#define G760A_REG_FAN_STA_RPM_OFF 0x1 /* +/-20% off */
+#define G760A_REG_FAN_STA_RPM_LOW 0x2 /* below 1920rpm */
+
+/* register data is read (and cached) at most once per second */
+#define G760A_UPDATE_INTERVAL (HZ)
+
+struct g760a_data {
+	struct i2c_client *client;
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+
+	/* board specific parameters */
+	u32 clk; /* default 32kHz */
+	u16 fan_div; /* default P=2 */
+
+	/* g760a register cache */
+	unsigned int valid:1;
+	unsigned long last_updated; /* In jiffies */
+
+	u8 set_cnt; /* PWM (period) count number; 0xff stops fan */
+	u8 act_cnt; /*   formula: cnt = (CLK * 30)/(rpm * P) */
+	u8 fan_sta; /* bit 0: set when actual fan speed more than 20%
+		     *   outside requested fan speed
+		     * bit 1: set when fan speed below 1920 rpm */
+};
+
+#define G760A_DEFAULT_CLK 32768
+#define G760A_DEFAULT_FAN_DIV 2
+
+#define PWM_FROM_CNT(cnt)	(0xff-(cnt))
+#define PWM_TO_CNT(pwm)		(0xff-(pwm))
+
+unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
+{
+	return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
+}
+
+/* new-style driver model */
+static int g760a_probe(struct i2c_client *client,
+			const struct i2c_device_id *id);
+static int g760a_remove(struct i2c_client *client);
+
+static struct i2c_driver g760a_driver = {
+	.driver = {
+		.name	= "g760a",
+	},
+	.probe	  = g760a_probe,
+	.remove	  = g760a_remove,
+	.id_table = g760a_id,
+};
+
+/* read/write wrappers */
+static int g760a_read_value(struct i2c_client *client, enum g760a_regs reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
+			     u16 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/****************************************************************************
+ * sysfs attributes
+ */
+
+static struct g760a_data *g760a_update_client(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g760a_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + G760A_UPDATE_INTERVAL)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting g760a update\n");
+
+		data->set_cnt = g760a_read_value(client, G760A_REG_SET_CNT);
+		data->act_cnt = g760a_read_value(client, G760A_REG_ACT_CNT);
+		data->fan_sta = g760a_read_value(client, G760A_REG_FAN_STA);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *da,
+			char *buf)
+{
+	struct g760a_data *data = g760a_update_client(dev);
+	unsigned int rpm = 0;
+
+	mutex_lock(&data->update_lock);
+	if (!(data->fan_sta & G760A_REG_FAN_STA_RPM_LOW))
+		rpm = rpm_from_cnt(data->act_cnt, data->clk, data->fan_div);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t show_fan_alarm(struct device *dev, struct device_attribute *da,
+			      char *buf)
+{
+	struct g760a_data *data = g760a_update_client(dev);
+
+	int fan_alarm = (data->fan_sta & G760A_REG_FAN_STA_RPM_OFF) ? 1 : 0;
+
+	return sprintf(buf, "%d\n", fan_alarm);
+}
+
+static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
+		       char *buf)
+{
+	struct g760a_data *data = g760a_update_client(dev);
+
+	return sprintf(buf, "%d\n", PWM_FROM_CNT(data->set_cnt));
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
+		       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g760a_data *data = g760a_update_client(dev);
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val))
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	data->set_cnt = PWM_TO_CNT(SENSORS_LIMIT(val, 0, 255));
+	g760a_write_value(client, G760A_REG_SET_CNT, data->set_cnt);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
+static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
+static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
+
+static struct attribute *g760a_attributes[] = {
+	&dev_attr_pwm1.attr,
+	&dev_attr_fan1_input.attr,
+	&dev_attr_fan1_alarm.attr,
+	NULL
+};
+
+static const struct attribute_group g760a_group = {
+	.attrs = g760a_attributes,
+};
+
+/****************************************************************************
+ * new-style driver model code
+ */
+
+static int g760a_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct g760a_data *data;
+	int err;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	data = kzalloc(sizeof(struct g760a_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+
+	data->client = client;
+	mutex_init(&data->update_lock);
+
+	/* setup default configuration for now */
+	data->fan_div = G760A_DEFAULT_FAN_DIV;
+	data->clk = G760A_DEFAULT_CLK;
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &g760a_group);
+	if (err)
+		goto error_sysfs_create_group;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto error_hwmon_device_register;
+	}
+
+	return 0;
+
+error_hwmon_device_register:
+	sysfs_remove_group(&client->dev.kobj, &g760a_group);
+error_sysfs_create_group:
+	kfree(data);
+	i2c_set_clientdata(client, NULL);
+
+	return err;
+}
+
+static int g760a_remove(struct i2c_client *client)
+{
+	struct g760a_data *data = i2c_get_clientdata(client);
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &g760a_group);
+	kfree(data);
+	i2c_set_clientdata(client, NULL);
+
+	return 0;
+}
+
+/* module management */
+
+static int __init g760a_init(void)
+{
+	return i2c_add_driver(&g760a_driver);
+}
+
+static void __exit g760a_exit(void)
+{
+	i2c_del_driver(&g760a_driver);
+}
+
+MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
+MODULE_DESCRIPTION("GMT G760A driver");
+MODULE_LICENSE("GPL");
+
+module_init(g760a_init);
+module_exit(g760a_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/hdaps.c linux-libre-2.6.30-gnu1/drivers/hwmon/hdaps.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/hdaps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/hdaps.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,6 +65,10 @@
 #define HDAPS_INPUT_FUZZ	4	/* input event threshold */
 #define HDAPS_INPUT_FLAT	4
 
+#define HDAPS_X_AXIS		(1 << 0)
+#define HDAPS_Y_AXIS		(1 << 1)
+#define HDAPS_BOTH_AXES		(HDAPS_X_AXIS | HDAPS_Y_AXIS)
+
 static struct platform_device *pdev;
 static struct input_polled_dev *hdaps_idev;
 static unsigned int hdaps_invert;
@@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned in
 	km_activity = inb(HDAPS_PORT_KMACT);
 	__device_complete();
 
-	/* if hdaps_invert is set, negate the two values */
-	if (hdaps_invert) {
+	/* hdaps_invert is a bitvector to negate the axes */
+	if (hdaps_invert & HDAPS_X_AXIS)
 		*x = -*x;
+	if (hdaps_invert & HDAPS_Y_AXIS)
 		*y = -*y;
-	}
 
 	return 0;
 }
@@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct
 {
 	int invert;
 
-	if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
+	if (sscanf(buf, "%d", &invert) != 1 ||
+	    invert < 0 || invert > HDAPS_BOTH_AXES)
 		return -EINVAL;
 
 	hdaps_invert = invert;
@@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const
 /* hdaps_dmi_match_invert - found an inverted match. */
 static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
 {
-	hdaps_invert = 1;
-	printk(KERN_INFO "hdaps: inverting axis readings.\n");
+	hdaps_invert = (unsigned long)id->driver_data;
+	printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
+	       hdaps_invert);
 	return hdaps_dmi_match(id);
 }
 
-#define HDAPS_DMI_MATCH_NORMAL(vendor, model) {		\
-	.ident = vendor " " model,			\
-	.callback = hdaps_dmi_match,			\
-	.matches = {					\
-		DMI_MATCH(DMI_BOARD_VENDOR, vendor),	\
-		DMI_MATCH(DMI_PRODUCT_VERSION, model)	\
-	}						\
-}
-
-#define HDAPS_DMI_MATCH_INVERT(vendor, model) {		\
+#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) {	\
 	.ident = vendor " " model,			\
 	.callback = hdaps_dmi_match_invert,		\
+	.driver_data = (void *)axes,			\
 	.matches = {					\
 		DMI_MATCH(DMI_BOARD_VENDOR, vendor),	\
 		DMI_MATCH(DMI_PRODUCT_VERSION, model)	\
 	}						\
 }
 
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model)		\
+	HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
+
 /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
    "ThinkPad T42p", so the order of the entries matters.
    If your ThinkPad is not recognized, please update to latest
    BIOS. This is especially the case for some R52 ThinkPads. */
 static struct dmi_system_id __initdata hdaps_whitelist[] = {
-	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"),
-	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
-	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
-	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"),
+	HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
 	HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"),
-	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
+	HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
 	{ .ident = NULL }
 };
 
@@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
 module_init(hdaps_init);
 module_exit(hdaps_exit);
 
-module_param_named(invert, hdaps_invert, bool, 0);
-MODULE_PARM_DESC(invert, "invert data along each axis");
+module_param_named(invert, hdaps_invert, int, 0);
+MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
+		 "2 invert y-axis, 3 invert both axes.");
 
 MODULE_AUTHOR("Robert Love");
 MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/hp_accel.c linux-libre-2.6.30-gnu1/drivers/hwmon/hp_accel.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/hp_accel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/hp_accel.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/wait.h>
 #include <linux/poll.h>
 #include <linux/freezer.h>
-#include <linux/version.h>
 #include <linux/uaccess.h>
 #include <linux/leds.h>
 #include <acpi/acpi_drivers.h>
@@ -85,25 +84,31 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_devi
 
 /**
  * lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_init(acpi_handle handle)
+int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
 {
-	return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
+	struct acpi_device *dev = lis3->bus_priv;
+	if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
+				 NULL, NULL) != AE_OK)
+		return -EINVAL;
+
+	return 0;
 }
 
 /**
  * lis3lv02d_acpi_read - ACPI ALRD method: read a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  * @reg:    the register to read
  * @ret:    result of the operation
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
+int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
 {
+	struct acpi_device *dev = lis3->bus_priv;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 	unsigned long long lret;
@@ -111,21 +116,22 @@ acpi_status lis3lv02d_acpi_read(acpi_han
 
 	arg0.integer.value = reg;
 
-	status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
+	status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret);
 	*ret = lret;
-	return status;
+	return (status != AE_OK) ? -EINVAL : 0;
 }
 
 /**
  * lis3lv02d_acpi_write - ACPI ALWR method: write to a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  * @reg:    the register to write to
  * @val:    the value to write
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
+int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
 {
+	struct acpi_device *dev = lis3->bus_priv;
 	unsigned long long ret; /* Not used when writting */
 	union acpi_object in_obj[2];
 	struct acpi_object_list args = { 2, in_obj };
@@ -135,12 +141,15 @@ acpi_status lis3lv02d_acpi_write(acpi_ha
 	in_obj[1].type          = ACPI_TYPE_INTEGER;
 	in_obj[1].integer.value = val;
 
-	return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
+	if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
 {
-	adev.ac = *((struct axis_conversion *)dmi->driver_data);
+	lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data);
 	printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
 
 	return 1;
@@ -187,6 +196,7 @@ static struct dmi_system_id lis3lv02d_dm
 	AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
 	AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
 	AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+	AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
 	AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
 	AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
 	AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
@@ -201,6 +211,8 @@ static struct dmi_system_id lis3lv02d_dm
 			PRODUCT_NAME, "HP Pavilion dv5",
 			BOARD_NAME, "3600",
 			y_inverted),
+	AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
+	AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
 	{ NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
@@ -214,7 +226,7 @@ static struct dmi_system_id lis3lv02d_dm
 
 static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value)
 {
-	acpi_handle handle = adev.device->handle;
+	struct acpi_device *dev = lis3_dev.bus_priv;
 	unsigned long long ret; /* Not used when writing */
 	union acpi_object in_obj[1];
 	struct acpi_object_list args = { 1, in_obj };
@@ -222,7 +234,7 @@ static void hpled_set(struct delayed_led
 	in_obj[0].type          = ACPI_TYPE_INTEGER;
 	in_obj[0].integer.value = !!value;
 
-	acpi_evaluate_integer(handle, "ALED", &args, &ret);
+	acpi_evaluate_integer(dev->handle, "ALED", &args, &ret);
 }
 
 static struct delayed_led_classdev hpled_led = {
@@ -254,28 +266,11 @@ static void lis3lv02d_enum_resources(str
 	acpi_status status;
 
 	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-					lis3lv02d_get_resource, &adev.irq);
+					lis3lv02d_get_resource, &lis3_dev.irq);
 	if (ACPI_FAILURE(status))
 		printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
 }
 
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
-	u8 lo, hi;
-
-	adev.read(handle, reg - 1, &lo);
-	adev.read(handle, reg, &hi);
-	/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
-	return (s16)((hi << 8) | lo);
-}
-
-static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
-{
-	s8 lo;
-	adev.read(handle, reg, &lo);
-	return lo;
-}
-
 static int lis3lv02d_add(struct acpi_device *device)
 {
 	int ret;
@@ -283,51 +278,35 @@ static int lis3lv02d_add(struct acpi_dev
 	if (!device)
 		return -EINVAL;
 
-	adev.device = device;
-	adev.init = lis3lv02d_acpi_init;
-	adev.read = lis3lv02d_acpi_read;
-	adev.write = lis3lv02d_acpi_write;
+	lis3_dev.bus_priv = device;
+	lis3_dev.init = lis3lv02d_acpi_init;
+	lis3_dev.read = lis3lv02d_acpi_read;
+	lis3_dev.write = lis3lv02d_acpi_write;
 	strcpy(acpi_device_name(device), DRIVER_NAME);
 	strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
-	device->driver_data = &adev;
+	device->driver_data = &lis3_dev;
 
-	lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
-	switch (adev.whoami) {
-	case LIS_DOUBLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
-		adev.read_data = lis3lv02d_read_16;
-		adev.mdps_max_val = 2048;
-		break;
-	case LIS_SINGLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
-		adev.read_data = lis3lv02d_read_8;
-		adev.mdps_max_val = 128;
-		break;
-	default:
-		printk(KERN_ERR DRIVER_NAME
-			": unknown sensor type 0x%X\n", adev.whoami);
-		return -EINVAL;
-	}
+	/* obtain IRQ number of our device from ACPI */
+	lis3lv02d_enum_resources(device);
 
 	/* If possible use a "standard" axes order */
 	if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
 		printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
 				 "using default axes configuration\n");
-		adev.ac = lis3lv02d_axis_normal;
+		lis3_dev.ac = lis3lv02d_axis_normal;
 	}
 
-	INIT_WORK(&hpled_led.work, delayed_set_status_worker);
-	ret = led_classdev_register(NULL, &hpled_led.led_classdev);
+	/* call the core layer do its init */
+	ret = lis3lv02d_init_device(&lis3_dev);
 	if (ret)
 		return ret;
 
-	/* obtain IRQ number of our device from ACPI */
-	lis3lv02d_enum_resources(adev.device);
-
-	ret = lis3lv02d_init_device(&adev);
+	INIT_WORK(&hpled_led.work, delayed_set_status_worker);
+	ret = led_classdev_register(NULL, &hpled_led.led_classdev);
 	if (ret) {
+		lis3lv02d_joystick_disable();
+		lis3lv02d_poweroff(&lis3_dev);
 		flush_work(&hpled_led.work);
-		led_classdev_unregister(&hpled_led.led_classdev);
 		return ret;
 	}
 
@@ -340,7 +319,7 @@ static int lis3lv02d_remove(struct acpi_
 		return -EINVAL;
 
 	lis3lv02d_joystick_disable();
-	lis3lv02d_poweroff(device->handle);
+	lis3lv02d_poweroff(&lis3_dev);
 
 	flush_work(&hpled_led.work);
 	led_classdev_unregister(&hpled_led.led_classdev);
@@ -353,19 +332,19 @@ static int lis3lv02d_remove(struct acpi_
 static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
 {
 	/* make sure the device is off when we suspend */
-	lis3lv02d_poweroff(device->handle);
+	lis3lv02d_poweroff(&lis3_dev);
 	return 0;
 }
 
 static int lis3lv02d_resume(struct acpi_device *device)
 {
 	/* put back the device in the right state (ACPI might turn it on) */
-	mutex_lock(&adev.lock);
-	if (adev.usage > 0)
-		lis3lv02d_poweron(device->handle);
+	mutex_lock(&lis3_dev.lock);
+	if (lis3_dev.usage > 0)
+		lis3lv02d_poweron(&lis3_dev);
 	else
-		lis3lv02d_poweroff(device->handle);
-	mutex_unlock(&adev.lock);
+		lis3lv02d_poweroff(&lis3_dev);
+	mutex_unlock(&lis3_dev.lock);
 	return 0;
 }
 #else
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/Kconfig linux-libre-2.6.30-gnu1/drivers/hwmon/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/hwmon/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -248,6 +248,18 @@ config SENSORS_ASB100
 	  This driver can also be built as a module.  If so, the module
 	  will be called asb100.
 
+config SENSORS_ATK0110
+	tristate "ASUS ATK0110 ACPI hwmon"
+	depends on X86 && ACPI && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the ACPI hardware
+	  monitoring interface found in many ASUS motherboards. This
+	  driver will provide readings of fans, voltages and temperatures
+	  through the system firmware.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called asus_atk0110.
+
 config SENSORS_ATXP1
 	tristate "Attansic ATXP1 VID controller"
 	depends on I2C && EXPERIMENTAL
@@ -343,12 +355,13 @@ config SENSORS_FSCPOS
 	  will be called fscpos.
 
 config SENSORS_FSCHMD
-	tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
+	tristate "Fujitsu Siemens Computers sensor chips"
 	depends on X86 && I2C
 	help
-	  If you say yes here you get support for various Fujitsu Siemens
-	  Computers sensor chips, including support for the integrated
-	  watchdog.
+	  If you say yes here you get support for the following Fujitsu
+	  Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes,
+	  Heimdall, Heracles, Hades and Syleus including support for the
+	  integrated watchdog.
 
 	  This is a merged driver for FSC sensor chips replacing the fscpos,
 	  fscscy and fscher drivers and adding support for several other FSC
@@ -357,6 +370,16 @@ config SENSORS_FSCHMD
 	  This driver can also be built as a module.  If so, the module
 	  will be called fschmd.
 
+config SENSORS_G760A
+	tristate "GMT G760A"
+	depends on I2C
+	help
+	  If you say yes here you get support for Global Mixed-mode
+	  Technology Inc G760A fan speed PWM controller chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called g760a.
+
 config SENSORS_GL518SM
 	tristate "Genesys Logic GL518SM"
 	depends on I2C
@@ -570,6 +593,17 @@ config SENSORS_LM93
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm93.
 
+config SENSORS_LTC4215
+	tristate "Linear Technology LTC4215"
+	depends on I2C && EXPERIMENTAL
+	default n
+	help
+	  If you say yes here you get support for Linear Technology LTC4215
+	  Hot Swap Controller I2C interface.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc4215.
+
 config SENSORS_LTC4245
 	tristate "Linear Technology LTC4245"
 	depends on I2C && EXPERIMENTAL
@@ -581,6 +615,15 @@ config SENSORS_LTC4245
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc4245.
 
+config SENSORS_LM95241
+	tristate "National Semiconductor LM95241 sensor chip"
+	depends on I2C
+	help
+	  If you say yes here you get support for LM95241 sensor chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm95241.
+
 config SENSORS_MAX1111
 	tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
 	depends on SPI_MASTER
@@ -635,6 +678,30 @@ config SENSORS_PC87427
 	  This driver can also be built as a module.  If so, the module
 	  will be called pc87427.
 
+config SENSORS_PCF8591
+	tristate "Philips PCF8591 ADC/DAC"
+	depends on I2C
+	default n
+	help
+	  If you say yes here you get support for Philips PCF8591 4-channel
+	  ADC, 1-channel DAC chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called pcf8591.
+
+	  These devices are hard to detect and rarely found on mainstream
+	  hardware.  If unsure, say N.
+
+config SENSORS_SHT15
+	tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
+	depends on GENERIC_GPIO
+	help
+	  If you say yes here you get support for the Sensiron SHT10, SHT11,
+	  SHT15, SHT71, SHT75 humidity and temperature sensors.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called sht15.
+
 config SENSORS_SIS5595
 	tristate "Silicon Integrated Systems Corp. SiS5595"
 	depends on PCI
@@ -827,7 +894,7 @@ config SENSORS_W83627HF
 	  will be called w83627hf.
 
 config SENSORS_W83627EHF
-	tristate "Winbond W83627EHF/DHG"
+	tristate "Winbond W83627EHF/EHG/DHG, W83667HG"
 	select HWMON_VID
 	help
 	  If you say yes here you get support for the hardware
@@ -838,6 +905,8 @@ config SENSORS_W83627EHF
 	  chip suited for specific Intel processors that use PECI such as
 	  the Core 2 Duo.
 
+	  This driver also supports the W83667HG chip.
+
 	  This driver can also be built as a module.  If so, the module
 	  will be called w83627ehf.
 
@@ -895,6 +964,22 @@ config SENSORS_LIS3LV02D
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of lis3lv02d.
 
+config SENSORS_LIS3_SPI
+	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
+	depends on !ACPI && SPI_MASTER && INPUT
+	default n
+	help
+	  This driver provides support for the LIS3LV02Dx accelerometer connected
+	  via SPI. 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.
+
+	  This driver can also be built as modules.  If so, the core module
+	  will be called lis3lv02d and a specific module for the SPI transport
+	  is called lis3lv02d_spi.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/lis3lv02d.c linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/lis3lv02d.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
-#include <acpi/acpi_drivers.h>
 #include <asm/atomic.h>
 #include "lis3lv02d.h"
 
@@ -53,13 +52,30 @@
  * joystick.
  */
 
-struct acpi_lis3lv02d adev = {
-	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+struct lis3lv02d lis3_dev = {
+	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
 };
 
-EXPORT_SYMBOL_GPL(adev);
+EXPORT_SYMBOL_GPL(lis3_dev);
 
-static int lis3lv02d_add_fs(struct acpi_device *device);
+static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
+{
+	s8 lo;
+	if (lis3->read(lis3, reg, &lo) < 0)
+		return 0;
+
+	return lo;
+}
+
+static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+{
+	u8 lo, hi;
+
+	lis3->read(lis3, reg - 1, &lo);
+	lis3->read(lis3, reg, &hi);
+	/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+	return (s16)((hi << 8) | lo);
+}
 
 /**
  * lis3lv02d_get_axis - For the given axis, give the value converted
@@ -78,36 +94,36 @@ static inline int lis3lv02d_get_axis(s8
 
 /**
  * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer
- * @handle: the handle to the device
- * @x:      where to store the X axis value
- * @y:      where to store the Y axis value
- * @z:      where to store the Z axis value
+ * @lis3: pointer to the device struct
+ * @x:    where to store the X axis value
+ * @y:    where to store the Y axis value
+ * @z:    where to store the Z axis value
  *
  * Note that 40Hz input device can eat up about 10% CPU at 800MHZ
  */
-static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
+static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 {
 	int position[3];
 
-	position[0] = adev.read_data(handle, OUTX);
-	position[1] = adev.read_data(handle, OUTY);
-	position[2] = adev.read_data(handle, OUTZ);
+	position[0] = lis3_dev.read_data(lis3, OUTX);
+	position[1] = lis3_dev.read_data(lis3, OUTY);
+	position[2] = lis3_dev.read_data(lis3, OUTZ);
 
-	*x = lis3lv02d_get_axis(adev.ac.x, position);
-	*y = lis3lv02d_get_axis(adev.ac.y, position);
-	*z = lis3lv02d_get_axis(adev.ac.z, position);
+	*x = lis3lv02d_get_axis(lis3_dev.ac.x, position);
+	*y = lis3lv02d_get_axis(lis3_dev.ac.y, position);
+	*z = lis3lv02d_get_axis(lis3_dev.ac.z, position);
 }
 
-void lis3lv02d_poweroff(acpi_handle handle)
+void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
-	adev.is_on = 0;
+	lis3_dev.is_on = 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
-void lis3lv02d_poweron(acpi_handle handle)
+void lis3lv02d_poweron(struct lis3lv02d *lis3)
 {
-	adev.is_on = 1;
-	adev.init(handle);
+	lis3_dev.is_on = 1;
+	lis3_dev.init(lis3);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -116,13 +132,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
  * device will always be on until a call to lis3lv02d_decrease_use(). Not to be
  * used from interrupt context.
  */
-static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_increase_use(struct lis3lv02d *dev)
 {
 	mutex_lock(&dev->lock);
 	dev->usage++;
 	if (dev->usage == 1) {
 		if (!dev->is_on)
-			lis3lv02d_poweron(dev->device->handle);
+			lis3lv02d_poweron(dev);
 	}
 	mutex_unlock(&dev->lock);
 }
@@ -131,12 +147,12 @@ static void lis3lv02d_increase_use(struc
  * To be called whenever a usage of the device is stopped.
  * It will make sure to turn off the device when there is not usage.
  */
-static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_decrease_use(struct lis3lv02d *dev)
 {
 	mutex_lock(&dev->lock);
 	dev->usage--;
 	if (dev->usage == 0)
-		lis3lv02d_poweroff(dev->device->handle);
+		lis3lv02d_poweroff(dev);
 	mutex_unlock(&dev->lock);
 }
 
@@ -147,10 +163,10 @@ static irqreturn_t lis302dl_interrupt(in
 	 * the lid is closed. This leads to interrupts as soon as a little move
 	 * is done.
 	 */
-	atomic_inc(&adev.count);
+	atomic_inc(&lis3_dev.count);
 
-	wake_up_interruptible(&adev.misc_wait);
-	kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+	wake_up_interruptible(&lis3_dev.misc_wait);
+	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
 	return IRQ_HANDLED;
 }
 
@@ -158,10 +174,10 @@ static int lis3lv02d_misc_open(struct in
 {
 	int ret;
 
-	if (test_and_set_bit(0, &adev.misc_opened))
+	if (test_and_set_bit(0, &lis3_dev.misc_opened))
 		return -EBUSY; /* already open */
 
-	atomic_set(&adev.count, 0);
+	atomic_set(&lis3_dev.count, 0);
 
 	/*
 	 * The sensor can generate interrupts for free-fall and direction
@@ -174,25 +190,25 @@ static int lis3lv02d_misc_open(struct in
 	 * io-apic is not configurable (and generates a warning) but I keep it
 	 * in case of support for other hardware.
 	 */
-	ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
-			  DRIVER_NAME, &adev);
+	ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+			  DRIVER_NAME, &lis3_dev);
 
 	if (ret) {
-		clear_bit(0, &adev.misc_opened);
-		printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+		clear_bit(0, &lis3_dev.misc_opened);
+		printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq);
 		return -EBUSY;
 	}
-	lis3lv02d_increase_use(&adev);
-	printk("lis3: registered interrupt %d\n", adev.irq);
+	lis3lv02d_increase_use(&lis3_dev);
+	printk("lis3: registered interrupt %d\n", lis3_dev.irq);
 	return 0;
 }
 
 static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
-	fasync_helper(-1, file, 0, &adev.async_queue);
-	lis3lv02d_decrease_use(&adev);
-	free_irq(adev.irq, &adev);
-	clear_bit(0, &adev.misc_opened); /* release the device */
+	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
+	lis3lv02d_decrease_use(&lis3_dev);
+	free_irq(lis3_dev.irq, &lis3_dev);
+	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
 	return 0;
 }
 
@@ -207,10 +223,10 @@ static ssize_t lis3lv02d_misc_read(struc
 	if (count < 1)
 		return -EINVAL;
 
-	add_wait_queue(&adev.misc_wait, &wait);
+	add_wait_queue(&lis3_dev.misc_wait, &wait);
 	while (true) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		data = atomic_xchg(&adev.count, 0);
+		data = atomic_xchg(&lis3_dev.count, 0);
 		if (data)
 			break;
 
@@ -240,22 +256,22 @@ static ssize_t lis3lv02d_misc_read(struc
 
 out:
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&adev.misc_wait, &wait);
+	remove_wait_queue(&lis3_dev.misc_wait, &wait);
 
 	return retval;
 }
 
 static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
 {
-	poll_wait(file, &adev.misc_wait, wait);
-	if (atomic_read(&adev.count))
+	poll_wait(file, &lis3_dev.misc_wait, wait);
+	if (atomic_read(&lis3_dev.count))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
 
 static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
 {
-	return fasync_helper(fd, file, on, &adev.async_queue);
+	return fasync_helper(fd, file, on, &lis3_dev.async_queue);
 }
 
 static const struct file_operations lis3lv02d_misc_fops = {
@@ -283,12 +299,12 @@ static int lis3lv02d_joystick_kthread(vo
 	int x, y, z;
 
 	while (!kthread_should_stop()) {
-		lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
-		input_report_abs(adev.idev, ABS_X, x - adev.xcalib);
-		input_report_abs(adev.idev, ABS_Y, y - adev.ycalib);
-		input_report_abs(adev.idev, ABS_Z, z - adev.zcalib);
+		lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+		input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib);
+		input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib);
+		input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib);
 
-		input_sync(adev.idev);
+		input_sync(lis3_dev.idev);
 
 		try_to_freeze();
 		msleep_interruptible(MDPS_POLL_INTERVAL);
@@ -299,11 +315,11 @@ static int lis3lv02d_joystick_kthread(vo
 
 static int lis3lv02d_joystick_open(struct input_dev *input)
 {
-	lis3lv02d_increase_use(&adev);
-	adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
-	if (IS_ERR(adev.kthread)) {
-		lis3lv02d_decrease_use(&adev);
-		return PTR_ERR(adev.kthread);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
+	if (IS_ERR(lis3_dev.kthread)) {
+		lis3lv02d_decrease_use(&lis3_dev);
+		return PTR_ERR(lis3_dev.kthread);
 	}
 
 	return 0;
@@ -311,45 +327,46 @@ static int lis3lv02d_joystick_open(struc
 
 static void lis3lv02d_joystick_close(struct input_dev *input)
 {
-	kthread_stop(adev.kthread);
-	lis3lv02d_decrease_use(&adev);
+	kthread_stop(lis3_dev.kthread);
+	lis3lv02d_decrease_use(&lis3_dev);
 }
 
 static inline void lis3lv02d_calibrate_joystick(void)
 {
-	lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
+	lis3lv02d_get_xyz(&lis3_dev,
+		&lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib);
 }
 
 int lis3lv02d_joystick_enable(void)
 {
 	int err;
 
-	if (adev.idev)
+	if (lis3_dev.idev)
 		return -EINVAL;
 
-	adev.idev = input_allocate_device();
-	if (!adev.idev)
+	lis3_dev.idev = input_allocate_device();
+	if (!lis3_dev.idev)
 		return -ENOMEM;
 
 	lis3lv02d_calibrate_joystick();
 
-	adev.idev->name       = "ST LIS3LV02DL Accelerometer";
-	adev.idev->phys       = DRIVER_NAME "/input0";
-	adev.idev->id.bustype = BUS_HOST;
-	adev.idev->id.vendor  = 0;
-	adev.idev->dev.parent = &adev.pdev->dev;
-	adev.idev->open       = lis3lv02d_joystick_open;
-	adev.idev->close      = lis3lv02d_joystick_close;
+	lis3_dev.idev->name       = "ST LIS3LV02DL Accelerometer";
+	lis3_dev.idev->phys       = DRIVER_NAME "/input0";
+	lis3_dev.idev->id.bustype = BUS_HOST;
+	lis3_dev.idev->id.vendor  = 0;
+	lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev;
+	lis3_dev.idev->open       = lis3lv02d_joystick_open;
+	lis3_dev.idev->close      = lis3lv02d_joystick_close;
 
-	set_bit(EV_ABS, adev.idev->evbit);
-	input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
-	input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
-	input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+	set_bit(EV_ABS, lis3_dev.idev->evbit);
+	input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+	input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+	input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
 
-	err = input_register_device(adev.idev);
+	err = input_register_device(lis3_dev.idev);
 	if (err) {
-		input_free_device(adev.idev);
-		adev.idev = NULL;
+		input_free_device(lis3_dev.idev);
+		lis3_dev.idev = NULL;
 	}
 
 	return err;
@@ -358,71 +375,40 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_ena
 
 void lis3lv02d_joystick_disable(void)
 {
-	if (!adev.idev)
+	if (!lis3_dev.idev)
 		return;
 
 	misc_deregister(&lis3lv02d_misc_device);
-	input_unregister_device(adev.idev);
-	adev.idev = NULL;
+	input_unregister_device(lis3_dev.idev);
+	lis3_dev.idev = NULL;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
-/*
- * Initialise the accelerometer and the various subsystems.
- * Should be rather independant of the bus system.
- */
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
-{
-	mutex_init(&dev->lock);
-	lis3lv02d_add_fs(dev->device);
-	lis3lv02d_increase_use(dev);
-
-	if (lis3lv02d_joystick_enable())
-		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
-
-	printk("lis3_init_device: irq %d\n", dev->irq);
-
-	/* if we did not get an IRQ from ACPI - we have nothing more to do */
-	if (!dev->irq) {
-		printk(KERN_ERR DRIVER_NAME
-			": No IRQ in ACPI. Disabling /dev/freefall\n");
-		goto out;
-	}
-
-	printk("lis3: registering device\n");
-	if (misc_register(&lis3lv02d_misc_device))
-		printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
-out:
-	lis3lv02d_decrease_use(dev);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
-
 /* Sysfs stuff */
 static ssize_t lis3lv02d_position_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	int x, y, z;
 
-	lis3lv02d_increase_use(&adev);
-	lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+	lis3lv02d_decrease_use(&lis3_dev);
 	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)
 {
-	return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib);
+	return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib);
 }
 
 static ssize_t lis3lv02d_calibrate_store(struct device *dev,
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 {
-	lis3lv02d_increase_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
 	lis3lv02d_calibrate_joystick();
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_decrease_use(&lis3_dev);
 	return count;
 }
 
@@ -434,9 +420,9 @@ static ssize_t lis3lv02d_rate_show(struc
 	u8 ctrl;
 	int val;
 
-	lis3lv02d_increase_use(&adev);
-	adev.read(adev.device->handle, CTRL_REG1, &ctrl);
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+	lis3lv02d_decrease_use(&lis3_dev);
 	val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
 	return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
 }
@@ -458,23 +444,73 @@ static struct attribute_group lis3lv02d_
 };
 
 
-static int lis3lv02d_add_fs(struct acpi_device *device)
+static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
 {
-	adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-	if (IS_ERR(adev.pdev))
-		return PTR_ERR(adev.pdev);
+	lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+	if (IS_ERR(lis3_dev.pdev))
+		return PTR_ERR(lis3_dev.pdev);
 
-	return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+	return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
 }
 
 int lis3lv02d_remove_fs(void)
 {
-	sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
-	platform_device_unregister(adev.pdev);
+	sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+	platform_device_unregister(lis3_dev.pdev);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
 
+/*
+ * Initialise the accelerometer and the various subsystems.
+ * Should be rather independant 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;
+		dev->mdps_max_val = 2048;
+		break;
+	case LIS_SINGLE_ID:
+		printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+		dev->read_data = lis3lv02d_read_8;
+		dev->mdps_max_val = 128;
+		break;
+	default:
+		printk(KERN_ERR DRIVER_NAME
+			": unknown sensor type 0x%X\n", lis3_dev.whoami);
+		return -EINVAL;
+	}
+
+	mutex_init(&dev->lock);
+	lis3lv02d_add_fs(dev);
+	lis3lv02d_increase_use(dev);
+
+	if (lis3lv02d_joystick_enable())
+		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+
+	printk("lis3_init_device: irq %d\n", dev->irq);
+
+	/* bail if we did not get an IRQ from the bus layer */
+	if (!dev->irq) {
+		printk(KERN_ERR DRIVER_NAME
+			": No IRQ. Disabling /dev/freefall\n");
+		goto out;
+	}
+
+	printk("lis3: registering device\n");
+	if (misc_register(&lis3lv02d_misc_device))
+		printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
+	lis3lv02d_decrease_use(dev);
+	return 0;
+}
+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.29-gnu1/drivers/hwmon/lis3lv02d.h linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d.h
--- linux-libre-2.6.29-gnu1/drivers/hwmon/lis3lv02d.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d.h	2009-06-09 23:05:27.000000000 -0400
@@ -159,14 +159,14 @@ struct axis_conversion {
 	s8	z;
 };
 
-struct acpi_lis3lv02d {
-	struct acpi_device	*device;   /* The ACPI device */
-	acpi_status (*init) (acpi_handle handle);
-	acpi_status (*write) (acpi_handle handle, int reg, u8 val);
-	acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+struct lis3lv02d {
+	void			*bus_priv; /* used by the bus layer only */
+	int (*init) (struct lis3lv02d *lis3);
+	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 */
-	s16 (*read_data) (acpi_handle handle, int reg);
+	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
 	int			mdps_max_val;
 
 	struct input_dev	*idev;     /* input device */
@@ -187,11 +187,11 @@ struct acpi_lis3lv02d {
 	unsigned long		misc_opened; /* bit0: whether the device is open */
 };
 
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
+int lis3lv02d_init_device(struct lis3lv02d *lis3);
 int lis3lv02d_joystick_enable(void);
 void lis3lv02d_joystick_disable(void);
-void lis3lv02d_poweroff(acpi_handle handle);
-void lis3lv02d_poweron(acpi_handle handle);
+void lis3lv02d_poweroff(struct lis3lv02d *lis3);
+void lis3lv02d_poweron(struct lis3lv02d *lis3);
 int lis3lv02d_remove_fs(void);
 
-extern struct acpi_lis3lv02d adev;
+extern struct lis3lv02d lis3_dev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/lis3lv02d_spi.c linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d_spi.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/lis3lv02d_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/lis3lv02d_spi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,114 @@
+/*
+ * lis3lv02d_spi - SPI glue layer for lis3lv02d
+ *
+ * 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 version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#include "lis3lv02d.h"
+
+#define DRV_NAME 	"lis3lv02d_spi"
+#define LIS3_SPI_READ	0x80
+
+static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
+{
+	struct spi_device *spi = lis3->bus_priv;
+	int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
+	if (ret < 0)
+		return -EINVAL;
+
+	*v = (u8) ret;
+	return 0;
+}
+
+static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
+{
+	u8 tmp[2] = { reg, val };
+	struct spi_device *spi = lis3->bus_priv;
+	return spi_write(spi, tmp, sizeof(tmp));
+}
+
+static int lis3_spi_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);
+}
+
+static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 };
+
+static int __devinit lis302dl_spi_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;
+
+	lis3_dev.bus_priv = spi;
+	lis3_dev.init = lis3_spi_init;
+	lis3_dev.read = lis3_spi_read;
+	lis3_dev.write = lis3_spi_write;
+	lis3_dev.irq = spi->irq;
+	lis3_dev.ac = lis3lv02d_axis_normal;
+	spi_set_drvdata(spi, &lis3_dev);
+
+	ret = lis3lv02d_init_device(&lis3_dev);
+	return ret;
+}
+
+static int __devexit lis302dl_spi_remove(struct spi_device *spi)
+{
+	struct lis3lv02d *lis3 = spi_get_drvdata(spi);
+	lis3lv02d_joystick_disable();
+	lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static struct spi_driver lis302dl_spi_driver = {
+	.driver	 = {
+		.name   = DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+	.probe	= lis302dl_spi_probe,
+	.remove	= __devexit_p(lis302dl_spi_remove),
+};
+
+static int __init lis302dl_init(void)
+{
+	return spi_register_driver(&lis302dl_spi_driver);
+}
+
+static void __exit lis302dl_exit(void)
+{
+	spi_unregister_driver(&lis302dl_spi_driver);
+}
+
+module_init(lis302dl_init);
+module_exit(lis302dl_exit);
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
+MODULE_LICENSE("GPL");
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/lm78.c linux-libre-2.6.30-gnu1/drivers/hwmon/lm78.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/lm78.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/lm78.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,7 @@ static struct platform_driver lm78_isa_d
 		.name	= "lm78",
 	},
 	.probe		= lm78_isa_probe,
-	.remove		= lm78_isa_remove,
+	.remove		= __devexit_p(lm78_isa_remove),
 };
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/lm95241.c linux-libre-2.6.30-gnu1/drivers/hwmon/lm95241.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/lm95241.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/lm95241.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,509 @@
+/*
+ * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
+ *             monitoring
+ * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
+ *
+ * Based on the max1619 driver. The LM95241 is a sensor chip made by National
+ *   Semiconductors.
+ * It reports up to three temperatures (its own plus up to
+ * two external ones). Complete datasheet can be
+ * obtained from National's website at:
+ *   http://www.national.com/ds.cgi/LM/LM95241.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#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>
+#include <linux/sysfs.h>
+
+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
+#define LM95241_REG_R_STATUS		0x02
+#define LM95241_REG_RW_CONFIG		0x03
+#define LM95241_REG_RW_REM_FILTER	0x06
+#define LM95241_REG_RW_TRUTHERM		0x07
+#define LM95241_REG_W_ONE_SHOT  	0x0F
+#define LM95241_REG_R_LOCAL_TEMPH	0x10
+#define LM95241_REG_R_REMOTE1_TEMPH	0x11
+#define LM95241_REG_R_REMOTE2_TEMPH	0x12
+#define LM95241_REG_R_LOCAL_TEMPL	0x20
+#define LM95241_REG_R_REMOTE1_TEMPL	0x21
+#define LM95241_REG_R_REMOTE2_TEMPL	0x22
+#define LM95241_REG_RW_REMOTE_MODEL	0x30
+
+/* LM95241 specific bitfields */
+#define CFG_STOP 0x40
+#define CFG_CR0076 0x00
+#define CFG_CR0182 0x10
+#define CFG_CR1000 0x20
+#define CFG_CR2700 0x30
+#define R1MS_SHIFT 0
+#define R2MS_SHIFT 2
+#define R1MS_MASK (0x01 << (R1MS_SHIFT))
+#define R2MS_MASK (0x01 << (R2MS_SHIFT))
+#define R1DF_SHIFT 1
+#define R2DF_SHIFT 2
+#define R1DF_MASK (0x01 << (R1DF_SHIFT))
+#define R2DF_MASK (0x01 << (R2DF_SHIFT))
+#define R1FE_MASK 0x01
+#define R2FE_MASK 0x05
+#define TT1_SHIFT 0
+#define TT2_SHIFT 4
+#define TT_OFF 0
+#define TT_ON 1
+#define TT_MASK 7
+#define MANUFACTURER_ID 0x01
+#define DEFAULT_REVISION 0xA4
+
+/* Conversions and various macros */
+#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
+    (val_h)) * 1000 + (val_l) * 1000 / 256)
+
+/* Functions declaration */
+static void lm95241_init_client(struct i2c_client *client);
+static struct lm95241_data *lm95241_update_device(struct device *dev);
+
+/* Client data (each client gets its own) */
+struct lm95241_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	unsigned long last_updated, rate; /* in jiffies */
+	char valid; /* zero until following fields are valid */
+	/* registers values */
+	u8 local_h, local_l; /* local */
+	u8 remote1_h, remote1_l; /* remote1 */
+	u8 remote2_h, remote2_l; /* remote2 */
+	u8 config, model, trutherm;
+};
+
+/* Sysfs stuff */
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct lm95241_data *data = lm95241_update_device(dev); \
+	snprintf(buf, PAGE_SIZE - 1, "%d\n", \
+		TEMP_FROM_REG(data->value##_h, data->value##_l)); \
+	return strlen(buf); \
+}
+show_temp(local);
+show_temp(remote1);
+show_temp(remote2);
+
+static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct lm95241_data *data = lm95241_update_device(dev);
+
+	snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
+	return strlen(buf);
+}
+
+static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	strict_strtol(buf, 10, &data->rate);
+	data->rate = data->rate * HZ / 1000;
+
+	return count;
+}
+
+#define show_type(flag) \
+static ssize_t show_type##flag(struct device *dev, \
+				   struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
+	return strlen(buf); \
+}
+show_type(1);
+show_type(2);
+
+#define show_min(flag) \
+static ssize_t show_min##flag(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->config & R##flag##DF_MASK ?	\
+		"-127000\n" : "0\n"); \
+	return strlen(buf); \
+}
+show_min(1);
+show_min(2);
+
+#define show_max(flag) \
+static ssize_t show_max##flag(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->config & R##flag##DF_MASK ? \
+		"127000\n" : "255000\n"); \
+	return strlen(buf); \
+}
+show_max(1);
+show_max(2);
+
+#define set_type(flag) \
+static ssize_t set_type##flag(struct device *dev, \
+				  struct device_attribute *attr, \
+				  const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	if ((val == 1) || (val == 2)) { \
+\
+		mutex_lock(&data->update_lock); \
+\
+		data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
+		if (val == 1) { \
+			data->model |= R##flag##MS_MASK; \
+			data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
+		} \
+		else { \
+			data->model &= ~R##flag##MS_MASK; \
+			data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
+		} \
+\
+		data->valid = 0; \
+\
+		i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
+					  data->model); \
+		i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
+					  data->trutherm); \
+\
+		mutex_unlock(&data->update_lock); \
+\
+	} \
+	return count; \
+}
+set_type(1);
+set_type(2);
+
+#define set_min(flag) \
+static ssize_t set_min##flag(struct device *dev, \
+	struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	mutex_lock(&data->update_lock); \
+\
+	if (val < 0) \
+		data->config |= R##flag##DF_MASK; \
+	else \
+		data->config &= ~R##flag##DF_MASK; \
+\
+	data->valid = 0; \
+\
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+		data->config); \
+\
+	mutex_unlock(&data->update_lock); \
+\
+	return count; \
+}
+set_min(1);
+set_min(2);
+
+#define set_max(flag) \
+static ssize_t set_max##flag(struct device *dev, \
+	struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	mutex_lock(&data->update_lock); \
+\
+	if (val <= 127000) \
+		data->config |= R##flag##DF_MASK; \
+	else \
+		data->config &= ~R##flag##DF_MASK; \
+\
+	data->valid = 0; \
+\
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+		data->config); \
+\
+	mutex_unlock(&data->update_lock); \
+\
+	return count; \
+}
+set_max(1);
+set_max(2);
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
+static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
+static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
+static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
+static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
+static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
+static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
+
+static struct attribute *lm95241_attributes[] = {
+	&dev_attr_temp1_input.attr,
+	&dev_attr_temp2_input.attr,
+	&dev_attr_temp3_input.attr,
+	&dev_attr_temp2_type.attr,
+	&dev_attr_temp3_type.attr,
+	&dev_attr_temp2_min.attr,
+	&dev_attr_temp3_min.attr,
+	&dev_attr_temp2_max.attr,
+	&dev_attr_temp3_max.attr,
+	&dev_attr_rate.attr,
+	NULL
+};
+
+static const struct attribute_group lm95241_group = {
+	.attrs = lm95241_attributes,
+};
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm95241_detect(struct i2c_client *new_client, int kind,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = new_client->adapter;
+	int address = new_client->addr;
+	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;
+			}
+		}
+	}
+
+	/* Fill the i2c board info */
+	if (kind == lm95241)
+		name = "lm95241";
+	strlcpy(info->type, name, I2C_NAME_SIZE);
+	return 0;
+}
+
+static int lm95241_probe(struct i2c_client *new_client,
+			 const struct i2c_device_id *id)
+{
+	struct lm95241_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(new_client, data);
+	mutex_init(&data->update_lock);
+
+	/* Initialize the LM95241 chip */
+	lm95241_init_client(new_client);
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&new_client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_files;
+	}
+
+	return 0;
+
+exit_remove_files:
+	sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void lm95241_init_client(struct i2c_client *client)
+{
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	data->rate = HZ;    /* 1 sec default */
+	data->valid = 0;
+	data->config = CFG_CR0076;
+	data->model = 0;
+	data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
+
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
+				  data->config);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
+				  R1FE_MASK | R2FE_MASK);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+				  data->trutherm);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+				  data->model);
+}
+
+static int lm95241_remove(struct i2c_client *client)
+{
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &lm95241_group);
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+	return 0;
+}
+
+static struct lm95241_data *lm95241_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + data->rate) ||
+	    !data->valid) {
+		dev_dbg(&client->dev, "Updating lm95241 data.\n");
+		data->local_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_LOCAL_TEMPH);
+		data->local_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_LOCAL_TEMPL);
+		data->remote1_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE1_TEMPH);
+		data->remote1_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE1_TEMPL);
+		data->remote2_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE2_TEMPH);
+		data->remote2_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE2_TEMPL);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/* Driver data (common to all clients) */
+static const struct i2c_device_id lm95241_id[] = {
+	{ "lm95241", lm95241 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lm95241_id);
+
+static struct i2c_driver lm95241_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name   = "lm95241",
+	},
+	.probe		= lm95241_probe,
+	.remove		= lm95241_remove,
+	.id_table	= lm95241_id,
+	.detect		= lm95241_detect,
+	.address_data	= &addr_data,
+};
+
+static int __init sensors_lm95241_init(void)
+{
+	return i2c_add_driver(&lm95241_driver);
+}
+
+static void __exit sensors_lm95241_exit(void)
+{
+	i2c_del_driver(&lm95241_driver);
+}
+
+MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
+MODULE_DESCRIPTION("LM95241 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm95241_init);
+module_exit(sensors_lm95241_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/ltc4215.c linux-libre-2.6.30-gnu1/drivers/hwmon/ltc4215.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/ltc4215.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/ltc4215.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,364 @@
+/*
+ * Driver for Linear Technology LTC4215 I2C Hot Swap Controller
+ *
+ * Copyright (C) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; 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.
+ *
+ * Datasheet:
+ * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(ltc4215);
+
+/* Here are names of the chip's registers (a.k.a. commands) */
+enum ltc4215_cmd {
+	LTC4215_CONTROL			= 0x00, /* rw */
+	LTC4215_ALERT			= 0x01, /* rw */
+	LTC4215_STATUS			= 0x02, /* ro */
+	LTC4215_FAULT			= 0x03, /* rw */
+	LTC4215_SENSE			= 0x04, /* rw */
+	LTC4215_SOURCE			= 0x05, /* rw */
+	LTC4215_ADIN			= 0x06, /* rw */
+};
+
+struct ltc4215_data {
+	struct device *hwmon_dev;
+
+	struct mutex update_lock;
+	bool valid;
+	unsigned long last_updated; /* in jiffies */
+
+	/* Registers */
+	u8 regs[7];
+};
+
+static struct ltc4215_data *ltc4215_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ltc4215_data *data = i2c_get_clientdata(client);
+	s32 val;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	/* The chip's A/D updates 10 times per second */
+	if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting ltc4215 update\n");
+
+		/* Read all registers */
+		for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
+			val = i2c_smbus_read_byte_data(client, i);
+			if (unlikely(val < 0))
+				data->regs[i] = 0;
+			else
+				data->regs[i] = val;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/* Return the voltage from the given register in millivolts */
+static int ltc4215_get_voltage(struct device *dev, u8 reg)
+{
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+	const u8 regval = data->regs[reg];
+	u32 voltage = 0;
+
+	switch (reg) {
+	case LTC4215_SENSE:
+		/* 151 uV per increment */
+		voltage = regval * 151 / 1000;
+		break;
+	case LTC4215_SOURCE:
+		/* 60.5 mV per increment */
+		voltage = regval * 605 / 10;
+		break;
+	case LTC4215_ADIN:
+		/* The ADIN input is divided by 12.5, and has 4.82 mV
+		 * per increment, so we have the additional multiply */
+		voltage = regval * 482 * 125 / 1000;
+		break;
+	default:
+		/* If we get here, the developer messed up */
+		WARN_ON_ONCE(1);
+		break;
+	}
+
+	return voltage;
+}
+
+/* Return the current from the sense resistor in mA */
+static unsigned int ltc4215_get_current(struct device *dev)
+{
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+
+	/* The strange looking conversions that follow are fixed-point
+	 * math, since we cannot do floating point in the kernel.
+	 *
+	 * Step 1: convert sense register to microVolts
+	 * Step 2: convert voltage to milliAmperes
+	 *
+	 * If you play around with the V=IR equation, you come up with
+	 * the following: X uV / Y mOhm == Z mA
+	 *
+	 * With the resistors that are fractions of a milliOhm, we multiply
+	 * the voltage and resistance by 10, to shift the decimal point.
+	 * Now we can use the normal division operator again.
+	 */
+
+	/* Calculate voltage in microVolts (151 uV per increment) */
+	const unsigned int voltage = data->regs[LTC4215_SENSE] * 151;
+
+	/* Calculate current in milliAmperes (4 milliOhm sense resistor) */
+	const unsigned int curr = voltage / 4;
+
+	return curr;
+}
+
+static ssize_t ltc4215_show_voltage(struct device *dev,
+				    struct device_attribute *da,
+				    char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	const int voltage = ltc4215_get_voltage(dev, attr->index);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", voltage);
+}
+
+static ssize_t ltc4215_show_current(struct device *dev,
+				    struct device_attribute *da,
+				    char *buf)
+{
+	const unsigned int curr = ltc4215_get_current(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", curr);
+}
+
+static ssize_t ltc4215_show_power(struct device *dev,
+				  struct device_attribute *da,
+				  char *buf)
+{
+	const unsigned int curr = ltc4215_get_current(dev);
+	const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN);
+
+	/* current in mA * voltage in mV == power in uW */
+	const unsigned int power = abs(output_voltage * curr);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", power);
+}
+
+static ssize_t ltc4215_show_alarm(struct device *dev,
+					  struct device_attribute *da,
+					  char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+	const u8 reg = data->regs[attr->index];
+	const u32 mask = attr->nr;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
+}
+
+/* These macros are used below in constructing device attribute objects
+ * for use with sysfs_create_group() to make a sysfs device file
+ * for each register.
+ */
+
+#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_voltage, NULL, ltc4215_cmd_idx)
+
+#define LTC4215_CURRENT(name) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_current, NULL, 0);
+
+#define LTC4215_POWER(name) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_power, NULL, 0);
+
+#define LTC4215_ALARM(name, mask, reg) \
+	static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
+	ltc4215_show_alarm, NULL, (mask), reg)
+
+/* Construct a sensor_device_attribute structure for each register */
+
+/* Current */
+LTC4215_CURRENT(curr1_input);
+LTC4215_ALARM(curr1_max_alarm,	(1 << 2),	LTC4215_STATUS);
+
+/* Power (virtual) */
+LTC4215_POWER(power1_input);
+LTC4215_ALARM(power1_alarm,	(1 << 3),	LTC4215_STATUS);
+
+/* Input Voltage */
+LTC4215_VOLTAGE(in1_input,			LTC4215_ADIN);
+LTC4215_ALARM(in1_max_alarm,	(1 << 0),	LTC4215_STATUS);
+LTC4215_ALARM(in1_min_alarm,	(1 << 1),	LTC4215_STATUS);
+
+/* Output Voltage */
+LTC4215_VOLTAGE(in2_input,			LTC4215_SOURCE);
+
+/* Finally, construct an array of pointers to members of the above objects,
+ * as required for sysfs_create_group()
+ */
+static struct attribute *ltc4215_attributes[] = {
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_power1_input.dev_attr.attr,
+	&sensor_dev_attr_power1_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+
+	NULL,
+};
+
+static const struct attribute_group ltc4215_group = {
+	.attrs = ltc4215_attributes,
+};
+
+static int ltc4215_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct ltc4215_data *data;
+	int ret;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto out_kzalloc;
+	}
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	/* Initialize the LTC4215 chip */
+	/* TODO */
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
+	if (ret)
+		goto out_sysfs_create_group;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto out_hwmon_device_register;
+	}
+
+	return 0;
+
+out_hwmon_device_register:
+	sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+out_sysfs_create_group:
+	kfree(data);
+out_kzalloc:
+	return ret;
+}
+
+static int ltc4215_remove(struct i2c_client *client)
+{
+	struct ltc4215_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+
+	kfree(data);
+
+	return 0;
+}
+
+static int ltc4215_detect(struct i2c_client *client,
+			  int kind,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	if (kind < 0) {		/* probed detection - check the chip type */
+		s32 v;		/* 8 bits from the chip, or -ERRNO */
+
+		/*
+		 * Register 0x01 bit b7 is reserved, expect 0
+		 * Register 0x03 bit b6 and b7 are reserved, expect 0
+		 */
+		v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
+		if (v < 0 || (v & (1 << 7)) != 0)
+			return -ENODEV;
+
+		v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
+		if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
+				return -ENODEV;
+	}
+
+	strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
+	dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
+			kind < 0 ? "probed" : "forced",
+			client->addr);
+
+	return 0;
+}
+
+static const struct i2c_device_id ltc4215_id[] = {
+	{ "ltc4215", ltc4215 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ltc4215_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ltc4215_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "ltc4215",
+	},
+	.probe		= ltc4215_probe,
+	.remove		= ltc4215_remove,
+	.id_table	= ltc4215_id,
+	.detect		= ltc4215_detect,
+	.address_data	= &addr_data,
+};
+
+static int __init ltc4215_init(void)
+{
+	return i2c_add_driver(&ltc4215_driver);
+}
+
+static void __exit ltc4215_exit(void)
+{
+	i2c_del_driver(&ltc4215_driver);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("LTC4215 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ltc4215_init);
+module_exit(ltc4215_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/Makefile linux-libre-2.6.30-gnu1/drivers/hwmon/Makefile
--- linux-libre-2.6.29-gnu1/drivers/hwmon/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@ obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475
 
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
+obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SENSORS_F75375S)	+= f75375s
 obj-$(CONFIG_SENSORS_FSCHER)	+= fscher.o
 obj-$(CONFIG_SENSORS_FSCHMD)	+= fschmd.o
 obj-$(CONFIG_SENSORS_FSCPOS)	+= fscpos.o
+obj-$(CONFIG_SENSORS_G760A)	+= g760a.o
 obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
 obj-$(CONFIG_SENSORS_GL520SM)	+= gl520sm.o
 obj-$(CONFIG_SENSORS_ULTRA45)	+= ultra45_env.o
@@ -52,6 +54,7 @@ obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_K8TEMP)	+= k8temp.o
 obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
+obj-$(CONFIG_SENSORS_LIS3_SPI)	+= lis3lv02d.o lis3lv02d_spi.o
 obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
 obj-$(CONFIG_SENSORS_LM70)	+= lm70.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
@@ -64,12 +67,16 @@ obj-$(CONFIG_SENSORS_LM87)	+= lm87.o
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
 obj-$(CONFIG_SENSORS_LM93)	+= lm93.o
+obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
+obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4245)	+= ltc4245.o
 obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
+obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_SHT15)	+= sht15.o
 obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/pcf8591.c linux-libre-2.6.30-gnu1/drivers/hwmon/pcf8591.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/pcf8591.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/pcf8591.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,325 @@
+/*
+    Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
+    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+    the help of Jean Delvare <khali@linux-fr.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+/* Addresses to scan */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(pcf8591);
+
+static int input_mode;
+module_param(input_mode, int, 0);
+MODULE_PARM_DESC(input_mode,
+	"Analog input mode:\n"
+	" 0 = four single ended inputs\n"
+	" 1 = three differential inputs\n"
+	" 2 = single ended and differential mixed\n"
+	" 3 = two differential inputs\n");
+
+/* The PCF8591 control byte
+      7    6    5    4    3    2    1    0
+   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   | */
+
+/* Analog Output Enable Flag (analog output active if 1) */
+#define PCF8591_CONTROL_AOEF		0x40
+
+/* Analog Input Programming
+   0x00 = four single ended inputs
+   0x10 = three differential inputs
+   0x20 = single ended and differential mixed
+   0x30 = two differential inputs */
+#define PCF8591_CONTROL_AIP_MASK	0x30
+
+/* Autoincrement Flag (switch on if 1) */
+#define PCF8591_CONTROL_AINC		0x04
+
+/* Channel selection
+   0x00 = channel 0
+   0x01 = channel 1
+   0x02 = channel 2
+   0x03 = channel 3 */
+#define PCF8591_CONTROL_AICH_MASK	0x03
+
+/* Initial values */
+#define PCF8591_INIT_CONTROL	((input_mode << 4) | PCF8591_CONTROL_AOEF)
+#define PCF8591_INIT_AOUT	0	/* DAC out = 0 */
+
+/* Conversions */
+#define REG_TO_SIGNED(reg)	(((reg) & 0x80)?((reg) - 256):(reg))
+
+struct pcf8591_data {
+	struct mutex update_lock;
+
+	u8 control;
+	u8 aout;
+};
+
+static void pcf8591_init_client(struct i2c_client *client);
+static int pcf8591_read_channel(struct device *dev, int channel);
+
+/* following are the sysfs callback functions */
+#define show_in_channel(channel)					\
+static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
+}									\
+static DEVICE_ATTR(in##channel##_input, S_IRUGO,			\
+		   show_in##channel##_input, NULL);
+
+show_in_channel(0);
+show_in_channel(1);
+show_in_channel(2);
+show_in_channel(3);
+
+static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
+	return sprintf(buf, "%d\n", data->aout * 10);
+}
+
+static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int value;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pcf8591_data *data = i2c_get_clientdata(client);
+	if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
+		data->aout = value;
+		i2c_smbus_write_byte_data(client, data->control, data->aout);
+		return count;
+	}
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
+		   show_out0_ouput, set_out0_output);
+
+static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
+	return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
+}
+
+static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pcf8591_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	mutex_lock(&data->update_lock);
+	if (val)
+		data->control |= PCF8591_CONTROL_AOEF;
+	else
+		data->control &= ~PCF8591_CONTROL_AOEF;
+	i2c_smbus_write_byte(client, data->control);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
+		   show_out0_enable, set_out0_enable);
+
+static struct attribute *pcf8591_attributes[] = {
+	&dev_attr_out0_enable.attr,
+	&dev_attr_out0_output.attr,
+	&dev_attr_in0_input.attr,
+	&dev_attr_in1_input.attr,
+	NULL
+};
+
+static const struct attribute_group pcf8591_attr_group = {
+	.attrs = pcf8591_attributes,
+};
+
+static struct attribute *pcf8591_attributes_opt[] = {
+	&dev_attr_in2_input.attr,
+	&dev_attr_in3_input.attr,
+	NULL
+};
+
+static const struct attribute_group pcf8591_attr_group_opt = {
+	.attrs = pcf8591_attributes_opt,
+};
+
+/*
+ * Real code
+ */
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int pcf8591_detect(struct i2c_client *client, int kind,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
+				     | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+		return -ENODEV;
+
+	/* Now, we would do the remaining detection. But the PCF8591 is plainly
+	   impossible to detect! Stupid chip. */
+
+	strlcpy(info->type, "pcf8591", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static int pcf8591_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct pcf8591_data *data;
+	int err;
+
+	if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	/* Initialize the PCF8591 chip */
+	pcf8591_init_client(client);
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);
+	if (err)
+		goto exit_kfree;
+
+	/* Register input2 if not in "two differential inputs" mode */
+	if (input_mode != 3) {
+		if ((err = device_create_file(&client->dev,
+					      &dev_attr_in2_input)))
+			goto exit_sysfs_remove;
+	}
+
+	/* Register input3 only in "four single ended inputs" mode */
+	if (input_mode == 0) {
+		if ((err = device_create_file(&client->dev,
+					      &dev_attr_in3_input)))
+			goto exit_sysfs_remove;
+	}
+
+	return 0;
+
+exit_sysfs_remove:
+	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
+	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
+exit_kfree:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int pcf8591_remove(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
+	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+/* Called when we have found a new PCF8591. */
+static void pcf8591_init_client(struct i2c_client *client)
+{
+	struct pcf8591_data *data = i2c_get_clientdata(client);
+	data->control = PCF8591_INIT_CONTROL;
+	data->aout = PCF8591_INIT_AOUT;
+
+	i2c_smbus_write_byte_data(client, data->control, data->aout);
+
+	/* The first byte transmitted contains the conversion code of the
+	   previous read cycle. FLUSH IT! */
+	i2c_smbus_read_byte(client);
+}
+
+static int pcf8591_read_channel(struct device *dev, int channel)
+{
+	u8 value;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pcf8591_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+
+	if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) {
+		data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
+			      | channel;
+		i2c_smbus_write_byte(client, data->control);
+
+		/* The first byte transmitted contains the conversion code of
+		   the previous read cycle. FLUSH IT! */
+		i2c_smbus_read_byte(client);
+	}
+	value = i2c_smbus_read_byte(client);
+
+	mutex_unlock(&data->update_lock);
+
+	if ((channel == 2 && input_mode == 2) ||
+	    (channel != 3 && (input_mode == 1 || input_mode == 3)))
+		return (10 * REG_TO_SIGNED(value));
+	else
+		return (10 * value);
+}
+
+static const struct i2c_device_id pcf8591_id[] = {
+	{ "pcf8591", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, pcf8591_id);
+
+static struct i2c_driver pcf8591_driver = {
+	.driver = {
+		.name	= "pcf8591",
+	},
+	.probe		= pcf8591_probe,
+	.remove		= pcf8591_remove,
+	.id_table	= pcf8591_id,
+
+	.class		= I2C_CLASS_HWMON,	/* Nearest choice */
+	.detect		= pcf8591_detect,
+	.address_data	= &addr_data,
+};
+
+static int __init pcf8591_init(void)
+{
+	if (input_mode < 0 || input_mode > 3) {
+		printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n",
+		       input_mode);
+		input_mode = 0;
+	}
+	return i2c_add_driver(&pcf8591_driver);
+}
+
+static void __exit pcf8591_exit(void)
+{
+	i2c_del_driver(&pcf8591_driver);
+}
+
+MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
+MODULE_DESCRIPTION("PCF8591 driver");
+MODULE_LICENSE("GPL");
+
+module_init(pcf8591_init);
+module_exit(pcf8591_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/sht15.c linux-libre-2.6.30-gnu1/drivers/hwmon/sht15.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/sht15.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/sht15.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,692 @@
+/*
+ * sht15.c - support for the SHT15 Temperature and Humidity Sensor
+ *
+ * Copyright (c) 2009 Jonathan Cameron
+ *
+ * Copyright (c) 2007 Wouter Horre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Currently ignoring checksum on readings.
+ * Default resolution only (14bit temp, 12bit humidity)
+ * Ignoring battery status.
+ * Heater not enabled.
+ * Timings are all conservative.
+ *
+ * Data sheet available (1/2009) at
+ * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf
+ *
+ * Regulator supply name = vcc
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include <linux/sht15.h>
+#include <linux/regulator/consumer.h>
+#include <asm/atomic.h>
+
+#define SHT15_MEASURE_TEMP	3
+#define SHT15_MEASURE_RH	5
+
+#define SHT15_READING_NOTHING	0
+#define SHT15_READING_TEMP	1
+#define SHT15_READING_HUMID	2
+
+/* Min timings in nsecs */
+#define SHT15_TSCKL		100	/* clock low */
+#define SHT15_TSCKH		100	/* clock high */
+#define SHT15_TSU		150	/* data setup time */
+
+/**
+ * struct sht15_temppair - elements of voltage dependant temp calc
+ * @vdd:	supply voltage in microvolts
+ * @d1:		see data sheet
+ */
+struct sht15_temppair {
+	int vdd; /* microvolts */
+	int d1;
+};
+
+/* Table 9 from data sheet - relates temperature calculation
+ * to supply voltage.
+ */
+static const struct sht15_temppair temppoints[] = {
+	{ 2500000, -39400 },
+	{ 3000000, -39600 },
+	{ 3500000, -39700 },
+	{ 4000000, -39800 },
+	{ 5000000, -40100 },
+};
+
+/**
+ * struct sht15_data - device instance specific data
+ * @pdata:	platform data (gpio's etc)
+ * @read_work:	bh of interrupt handler
+ * @wait_queue:	wait queue for getting values from device
+ * @val_temp:	last temperature value read from device
+ * @val_humid: 	last humidity value read from device
+ * @flag:	status flag used to identify what the last request was
+ * @valid:	are the current stored values valid (start condition)
+ * @last_updat:	time of last update
+ * @read_lock:	mutex to ensure only one read in progress
+ *		at a time.
+ * @dev:	associate device structure
+ * @hwmon_dev:	device associated with hwmon subsystem
+ * @reg:	associated regulator (if specified)
+ * @nb:		notifier block to handle notifications of voltage changes
+ * @supply_uV:	local copy of supply voltage used to allow
+ *		use of regulator consumer if available
+ * @supply_uV_valid:   indicates that an updated value has not yet
+ *		been obtained from the regulator and so any calculations
+ *		based upon it will be invalid.
+ * @update_supply_work:	work struct that is used to update the supply_uV
+ * @interrupt_handled:	flag used to indicate a hander has been scheduled
+ */
+struct sht15_data {
+	struct sht15_platform_data	*pdata;
+	struct work_struct		read_work;
+	wait_queue_head_t		wait_queue;
+	uint16_t			val_temp;
+	uint16_t			val_humid;
+	u8				flag;
+	u8				valid;
+	unsigned long			last_updat;
+	struct mutex			read_lock;
+	struct device			*dev;
+	struct device			*hwmon_dev;
+	struct regulator		*reg;
+	struct notifier_block		nb;
+	int				supply_uV;
+	int				supply_uV_valid;
+	struct work_struct		update_supply_work;
+	atomic_t			interrupt_handled;
+};
+
+/**
+ * sht15_connection_reset() - reset the comms interface
+ * @data:	sht15 specific data
+ *
+ * This implements section 3.4 of the data sheet
+ */
+static void sht15_connection_reset(struct sht15_data *data)
+{
+	int i;
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	for (i = 0; i < 9; ++i) {
+		gpio_set_value(data->pdata->gpio_sck, 1);
+		ndelay(SHT15_TSCKH);
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		ndelay(SHT15_TSCKL);
+	}
+}
+/**
+ * sht15_send_bit() - send an individual bit to the device
+ * @data:	device state data
+ * @val:	value of bit to be sent
+ **/
+static inline void sht15_send_bit(struct sht15_data *data, int val)
+{
+
+	gpio_set_value(data->pdata->gpio_data, val);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL); /* clock low time */
+}
+
+/**
+ * sht15_transmission_start() - specific sequence for new transmission
+ *
+ * @data:	device state data
+ * Timings for this are not documented on the data sheet, so very
+ * conservative ones used in implementation. This implements
+ * figure 12 on the data sheet.
+ **/
+static void sht15_transmission_start(struct sht15_data *data)
+{
+	/* ensure data is high and output */
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_data, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+}
+/**
+ * sht15_send_byte() - send a single byte to the device
+ * @data:	device state
+ * @byte:	value to be sent
+ **/
+static void sht15_send_byte(struct sht15_data *data, u8 byte)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		sht15_send_bit(data, !!(byte & 0x80));
+		byte <<= 1;
+	}
+}
+/**
+ * sht15_wait_for_response() - checks for ack from device
+ * @data:	device state
+ **/
+static int sht15_wait_for_response(struct sht15_data *data)
+{
+	gpio_direction_input(data->pdata->gpio_data);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	if (gpio_get_value(data->pdata->gpio_data)) {
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		dev_err(data->dev, "Command not acknowledged\n");
+		sht15_connection_reset(data);
+		return -EIO;
+	}
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+	return 0;
+}
+
+/**
+ * sht15_send_cmd() - Sends a command to the device.
+ * @data:	device state
+ * @cmd:	command byte to be sent
+ *
+ * On entry, sck is output low, data is output pull high
+ * and the interrupt disabled.
+ **/
+static int sht15_send_cmd(struct sht15_data *data, u8 cmd)
+{
+	int ret = 0;
+	sht15_transmission_start(data);
+	sht15_send_byte(data, cmd);
+	ret = sht15_wait_for_response(data);
+	return ret;
+}
+/**
+ * sht15_update_single_val() - get a new value from device
+ * @data:		device instance specific data
+ * @command:		command sent to request value
+ * @timeout_msecs:	timeout after which comms are assumed
+ *			to have failed are reset.
+ **/
+static inline int sht15_update_single_val(struct sht15_data *data,
+					  int command,
+					  int timeout_msecs)
+{
+	int ret;
+	ret = sht15_send_cmd(data, command);
+	if (ret)
+		return ret;
+
+	gpio_direction_input(data->pdata->gpio_data);
+	atomic_set(&data->interrupt_handled, 0);
+
+	enable_irq(gpio_to_irq(data->pdata->gpio_data));
+	if (gpio_get_value(data->pdata->gpio_data) == 0) {
+		disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+		/* Only relevant if the interrupt hasn't occured. */
+		if (!atomic_read(&data->interrupt_handled))
+			schedule_work(&data->read_work);
+	}
+	ret = wait_event_timeout(data->wait_queue,
+				 (data->flag == SHT15_READING_NOTHING),
+				 msecs_to_jiffies(timeout_msecs));
+	if (ret == 0) {/* timeout occurred */
+		disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));;
+		sht15_connection_reset(data);
+		return -ETIME;
+	}
+	return 0;
+}
+
+/**
+ * sht15_update_vals() - get updated readings from device if too old
+ * @data:	device state
+ **/
+static int sht15_update_vals(struct sht15_data *data)
+{
+	int ret = 0;
+	int timeout = HZ;
+
+	mutex_lock(&data->read_lock);
+	if (time_after(jiffies, data->last_updat + timeout)
+	    || !data->valid) {
+		data->flag = SHT15_READING_HUMID;
+		ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160);
+		if (ret)
+			goto error_ret;
+		data->flag = SHT15_READING_TEMP;
+		ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400);
+		if (ret)
+			goto error_ret;
+		data->valid = 1;
+		data->last_updat = jiffies;
+	}
+error_ret:
+	mutex_unlock(&data->read_lock);
+
+	return ret;
+}
+
+/**
+ * sht15_calc_temp() - convert the raw reading to a temperature
+ * @data:	device state
+ *
+ * As per section 4.3 of the data sheet.
+ **/
+static inline int sht15_calc_temp(struct sht15_data *data)
+{
+	int d1 = 0;
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++)
+		/* Find pointer to interpolate */
+		if (data->supply_uV > temppoints[i - 1].vdd) {
+			d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+				* (temppoints[i].d1 - temppoints[i - 1].d1)
+				/ (temppoints[i].vdd - temppoints[i - 1].vdd)
+				+ temppoints[i - 1].d1;
+			break;
+		}
+
+	return data->val_temp*10 + d1;
+}
+
+/**
+ * sht15_calc_humid() - using last temperature convert raw to humid
+ * @data:	device state
+ *
+ * This is the temperature compensated version as per section 4.2 of
+ * the data sheet.
+ **/
+static inline int sht15_calc_humid(struct sht15_data *data)
+{
+	int RHlinear; /* milli percent */
+	int temp = sht15_calc_temp(data);
+
+	const int c1 = -4;
+	const int c2 = 40500; /* x 10 ^ -6 */
+	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)
+		/ 1000000 + RHlinear;
+}
+
+static ssize_t sht15_show_temp(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+
+	/* Technically no need to read humidity as well */
+	ret = sht15_update_vals(data);
+
+	return ret ? ret : sprintf(buf, "%d\n",
+				   sht15_calc_temp(data));
+}
+
+static ssize_t sht15_show_humidity(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+
+	ret = sht15_update_vals(data);
+
+	return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data));
+
+};
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr,
+			 char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	return sprintf(buf, "%s\n", pdev->name);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input,
+			  S_IRUGO, sht15_show_temp,
+			  NULL, 0);
+static SENSOR_DEVICE_ATTR(humidity1_input,
+			  S_IRUGO, sht15_show_humidity,
+			  NULL, 0);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static struct attribute *sht15_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_humidity1_input.dev_attr.attr,
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group sht15_attr_group = {
+	.attrs = sht15_attrs,
+};
+
+static irqreturn_t sht15_interrupt_fired(int irq, void *d)
+{
+	struct sht15_data *data = d;
+	/* First disable the interrupt */
+	disable_irq_nosync(irq);
+	atomic_inc(&data->interrupt_handled);
+	/* Then schedule a reading work struct */
+	if (data->flag != SHT15_READING_NOTHING)
+		schedule_work(&data->read_work);
+	return IRQ_HANDLED;
+}
+
+/* Each byte of data is acknowledged by pulling the data line
+ * low for one clock pulse.
+ */
+static void sht15_ack(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_data, 1);
+
+	gpio_direction_input(data->pdata->gpio_data);
+}
+/**
+ * sht15_end_transmission() - notify device of end of transmission
+ * @data:	device state
+ *
+ * This is basically a NAK. (single clock pulse, data high)
+ **/
+static void sht15_end_transmission(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+}
+
+static void sht15_bh_read_data(struct work_struct *work_s)
+{
+	int i;
+	uint16_t val = 0;
+	struct sht15_data *data
+		= container_of(work_s, struct sht15_data,
+			       read_work);
+	/* Firstly, verify the line is low */
+	if (gpio_get_value(data->pdata->gpio_data)) {
+		/* If not, then start the interrupt again - care
+		   here as could have gone low in meantime so verify
+		   it hasn't!
+		*/
+		atomic_set(&data->interrupt_handled, 0);
+		enable_irq(gpio_to_irq(data->pdata->gpio_data));
+		/* If still not occured or another handler has been scheduled */
+		if (gpio_get_value(data->pdata->gpio_data)
+		    || atomic_read(&data->interrupt_handled))
+			return;
+	}
+	/* Read the data back from the device */
+	for (i = 0; i < 16; ++i) {
+		val <<= 1;
+		gpio_set_value(data->pdata->gpio_sck, 1);
+		ndelay(SHT15_TSCKH);
+		val |= !!gpio_get_value(data->pdata->gpio_data);
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		ndelay(SHT15_TSCKL);
+		if (i == 7)
+			sht15_ack(data);
+	}
+	/* Tell the device we are done */
+	sht15_end_transmission(data);
+
+	switch (data->flag) {
+	case SHT15_READING_TEMP:
+		data->val_temp = val;
+		break;
+	case SHT15_READING_HUMID:
+		data->val_humid = val;
+		break;
+	}
+
+	data->flag = SHT15_READING_NOTHING;
+	wake_up(&data->wait_queue);
+}
+
+static void sht15_update_voltage(struct work_struct *work_s)
+{
+	struct sht15_data *data
+		= container_of(work_s, struct sht15_data,
+			       update_supply_work);
+	data->supply_uV = regulator_get_voltage(data->reg);
+}
+
+/**
+ * sht15_invalidate_voltage() - mark supply voltage invalid when notified by reg
+ * @nb:		associated notification structure
+ * @event:	voltage regulator state change event code
+ * @ignored:	function parameter - ignored here
+ *
+ * Note that as the notification code holds the regulator lock, we have
+ * to schedule an update of the supply voltage rather than getting it directly.
+ **/
+static int sht15_invalidate_voltage(struct notifier_block *nb,
+				unsigned long event,
+				void *ignored)
+{
+	struct sht15_data *data = container_of(nb, struct sht15_data, nb);
+
+	if (event == REGULATOR_EVENT_VOLTAGE_CHANGE)
+		data->supply_uV_valid = false;
+	schedule_work(&data->update_supply_work);
+
+	return NOTIFY_OK;
+}
+
+static int __devinit sht15_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+
+	if (!data) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "kzalloc failed");
+		goto error_ret;
+	}
+
+	INIT_WORK(&data->read_work, sht15_bh_read_data);
+	INIT_WORK(&data->update_supply_work, sht15_update_voltage);
+	platform_set_drvdata(pdev, data);
+	mutex_init(&data->read_lock);
+	data->dev = &pdev->dev;
+	init_waitqueue_head(&data->wait_queue);
+
+	if (pdev->dev.platform_data == NULL) {
+		dev_err(&pdev->dev, "no platform data supplied");
+		goto err_free_data;
+	}
+	data->pdata = pdev->dev.platform_data;
+	data->supply_uV = data->pdata->supply_mv*1000;
+
+/* If a regulator is available, query what the supply voltage actually is!*/
+	data->reg = regulator_get(data->dev, "vcc");
+	if (!IS_ERR(data->reg)) {
+		data->supply_uV = regulator_get_voltage(data->reg);
+		regulator_enable(data->reg);
+		/* setup a notifier block to update this if another device
+		 *  causes the voltage to change */
+		data->nb.notifier_call = &sht15_invalidate_voltage;
+		ret = regulator_register_notifier(data->reg, &data->nb);
+	}
+/* Try requesting the GPIOs */
+	ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
+	if (ret) {
+		dev_err(&pdev->dev, "gpio request failed");
+		goto err_free_data;
+	}
+	gpio_direction_output(data->pdata->gpio_sck, 0);
+	ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
+	if (ret) {
+		dev_err(&pdev->dev, "gpio request failed");
+		goto err_release_gpio_sck;
+	}
+	ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
+	if (ret) {
+		dev_err(&pdev->dev, "sysfs create failed");
+		goto err_free_data;
+	}
+
+	ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
+			  sht15_interrupt_fired,
+			  IRQF_TRIGGER_FALLING,
+			  "sht15 data",
+			  data);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to get irq for data line");
+		goto err_release_gpio_data;
+	}
+	disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+	sht15_connection_reset(data);
+	sht15_send_cmd(data, 0x1E);
+
+	data->hwmon_dev = hwmon_device_register(data->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto err_release_gpio_data;
+	}
+	return 0;
+
+err_release_gpio_data:
+	gpio_free(data->pdata->gpio_data);
+err_release_gpio_sck:
+	gpio_free(data->pdata->gpio_sck);
+err_free_data:
+	kfree(data);
+error_ret:
+
+	return ret;
+}
+
+static int __devexit sht15_remove(struct platform_device *pdev)
+{
+	struct sht15_data *data = platform_get_drvdata(pdev);
+
+	/* Make sure any reads from the device are done and
+	 * prevent new ones beginnning */
+	mutex_lock(&data->read_lock);
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
+	if (!IS_ERR(data->reg)) {
+		regulator_unregister_notifier(data->reg, &data->nb);
+		regulator_disable(data->reg);
+		regulator_put(data->reg);
+	}
+
+	free_irq(gpio_to_irq(data->pdata->gpio_data), data);
+	gpio_free(data->pdata->gpio_data);
+	gpio_free(data->pdata->gpio_sck);
+	mutex_unlock(&data->read_lock);
+	kfree(data);
+	return 0;
+}
+
+
+static struct platform_driver sht_drivers[] = {
+	{
+		.driver = {
+			.name = "sht10",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht11",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht15",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht71",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	}, {
+		.driver = {
+			.name = "sht75",
+			.owner = THIS_MODULE,
+		},
+		.probe = sht15_probe,
+		.remove = sht15_remove,
+	},
+};
+
+
+static int __init sht15_init(void)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) {
+		ret = platform_driver_register(&sht_drivers[i]);
+		if (ret)
+			goto error_unreg;
+	}
+
+	return 0;
+
+error_unreg:
+	while (--i >= 0)
+		platform_driver_unregister(&sht_drivers[i]);
+
+	return ret;
+}
+module_init(sht15_init);
+
+static void __exit sht15_exit(void)
+{
+	int i;
+	for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--)
+		platform_driver_unregister(&sht_drivers[i]);
+}
+module_exit(sht15_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/w83627ehf.c linux-libre-2.6.30-gnu1/drivers/hwmon/w83627ehf.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/w83627ehf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/w83627ehf.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@
     w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
                                                0x8860 0xa1
     w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
+    w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
 */
 
 #include <linux/module.h>
@@ -52,12 +53,13 @@
 #include <asm/io.h>
 #include "lm75.h"
 
-enum kinds { w83627ehf, w83627dhg };
+enum kinds { w83627ehf, w83627dhg, w83667hg };
 
 /* used to set data->name = w83627ehf_device_names[data->sio_kind] */
 static const char * w83627ehf_device_names[] = {
 	"w83627ehf",
 	"w83627dhg",
+	"w83667hg",
 };
 
 static unsigned short force_id;
@@ -71,6 +73,7 @@ MODULE_PARM_DESC(force_id, "Override the
  */
 
 #define W83627EHF_LD_HWM	0x0b
+#define W83667HG_LD_VID 	0x0d
 
 #define SIO_REG_LDSEL		0x07	/* Logical device select */
 #define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
@@ -83,6 +86,7 @@ MODULE_PARM_DESC(force_id, "Override the
 #define SIO_W83627EHF_ID	0x8850
 #define SIO_W83627EHG_ID	0x8860
 #define SIO_W83627DHG_ID	0xa020
+#define SIO_W83667HG_ID 	0xa510
 #define SIO_ID_MASK		0xFFF0
 
 static inline void
@@ -289,6 +293,7 @@ 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) */
+	u8 pwm_num;		/* number of pwm */
 	u8 pwm[4];
 	u8 target_temp[4];
 	u8 tolerance[4];
@@ -298,6 +303,9 @@ struct w83627ehf_data {
 
 	u8 vid;
 	u8 vrm;
+
+	u8 temp3_disable;
+	u8 in6_skip;
 };
 
 struct w83627ehf_sio_data {
@@ -866,25 +874,37 @@ show_temp_type(struct device *dev, struc
 	return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
 }
 
-static struct sensor_device_attribute sda_temp[] = {
+static struct sensor_device_attribute sda_temp_input[] = {
 	SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
 	SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
 	SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max[] = {
 	SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
 		    store_temp1_max, 0),
 	SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
 		    store_temp_max, 0),
 	SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
 		    store_temp_max, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max_hyst[] = {
 	SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
 		    store_temp1_max_hyst, 0),
 	SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
 		    store_temp_max_hyst, 0),
 	SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
 		    store_temp_max_hyst, 1),
+};
+
+static struct sensor_device_attribute sda_temp_alarm[] = {
 	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
 	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
 	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
+};
+
+static struct sensor_device_attribute sda_temp_type[] = {
 	SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
 	SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
 	SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
@@ -1181,6 +1201,8 @@ static void w83627ehf_device_remove_file
 	for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
 		device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
 	for (i = 0; i < data->in_num; i++) {
+		if ((i == 6) && data->in6_skip)
+			continue;
 		device_remove_file(dev, &sda_in_input[i].dev_attr);
 		device_remove_file(dev, &sda_in_alarm[i].dev_attr);
 		device_remove_file(dev, &sda_in_min[i].dev_attr);
@@ -1192,15 +1214,22 @@ static void w83627ehf_device_remove_file
 		device_remove_file(dev, &sda_fan_div[i].dev_attr);
 		device_remove_file(dev, &sda_fan_min[i].dev_attr);
 	}
-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < data->pwm_num; i++) {
 		device_remove_file(dev, &sda_pwm[i].dev_attr);
 		device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
 		device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
 		device_remove_file(dev, &sda_target_temp[i].dev_attr);
 		device_remove_file(dev, &sda_tolerance[i].dev_attr);
 	}
-	for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
-		device_remove_file(dev, &sda_temp[i].dev_attr);
+	for (i = 0; i < 3; i++) {
+		if ((i == 2) && data->temp3_disable)
+			continue;
+		device_remove_file(dev, &sda_temp_input[i].dev_attr);
+		device_remove_file(dev, &sda_temp_max[i].dev_attr);
+		device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
+		device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
+		device_remove_file(dev, &sda_temp_type[i].dev_attr);
+	}
 
 	device_remove_file(dev, &dev_attr_name);
 	device_remove_file(dev, &dev_attr_cpu0_vid);
@@ -1222,6 +1251,8 @@ static inline void __devinit w83627ehf_i
 	for (i = 0; i < 2; i++) {
 		tmp = w83627ehf_read_value(data,
 					   W83627EHF_REG_TEMP_CONFIG[i]);
+		if ((i == 1) && data->temp3_disable)
+			continue;
 		if (tmp & 0x01)
 			w83627ehf_write_value(data,
 					      W83627EHF_REG_TEMP_CONFIG[i],
@@ -1272,8 +1303,17 @@ static int __devinit w83627ehf_probe(str
 	data->name = w83627ehf_device_names[sio_data->kind];
 	platform_set_drvdata(pdev, data);
 
-	/* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */
-	data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10;
+	/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
+	data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
+	/* 667HG has 3 pwms */
+	data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
+
+	/* Check temp3 configuration bit for 667HG */
+	if (sio_data->kind == w83667hg) {
+		data->temp3_disable = w83627ehf_read_value(data,
+					W83627EHF_REG_TEMP_CONFIG[1]) & 0x01;
+		data->in6_skip = !data->temp3_disable;
+	}
 
 	/* Initialize the chip */
 	w83627ehf_init_device(data);
@@ -1281,44 +1321,64 @@ static int __devinit w83627ehf_probe(str
 	data->vrm = vid_which_vrm();
 	superio_enter(sio_data->sioreg);
 	/* Read VID value */
-	superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
-	if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
-		/* Set VID input sensibility if needed. In theory the BIOS
-		   should have set it, but in practice it's not always the
-		   case. We only do it for the W83627EHF/EHG because the
-		   W83627DHG is more complex in this respect. */
-		if (sio_data->kind == w83627ehf) {
-			en_vrm10 = superio_inb(sio_data->sioreg,
-					       SIO_REG_EN_VRM10);
-			if ((en_vrm10 & 0x08) && data->vrm == 90) {
-				dev_warn(dev, "Setting VID input voltage to "
-					 "TTL\n");
-				superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
-					     en_vrm10 & ~0x08);
-			} else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
-				dev_warn(dev, "Setting VID input voltage to "
-					 "VRM10\n");
-				superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
-					     en_vrm10 | 0x08);
-			}
-		}
-
-		data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
-		if (sio_data->kind == w83627ehf) /* 6 VID pins only */
-			data->vid &= 0x3f;
-
+	if (sio_data->kind == w83667hg) {
+		/* W83667HG has different pins for VID input and output, so
+		we can get the VID input values directly at logical device D
+		0xe3. */
+		superio_select(sio_data->sioreg, W83667HG_LD_VID);
+		data->vid = superio_inb(sio_data->sioreg, 0xe3);
 		err = device_create_file(dev, &dev_attr_cpu0_vid);
 		if (err)
 			goto exit_release;
 	} else {
-		dev_info(dev, "VID pins in output mode, CPU VID not "
-			 "available\n");
+		superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+		if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
+			/* Set VID input sensibility if needed. In theory the
+			   BIOS should have set it, but in practice it's not
+			   always the case. We only do it for the W83627EHF/EHG
+			   because the W83627DHG is more complex in this
+			   respect. */
+			if (sio_data->kind == w83627ehf) {
+				en_vrm10 = superio_inb(sio_data->sioreg,
+						       SIO_REG_EN_VRM10);
+				if ((en_vrm10 & 0x08) && data->vrm == 90) {
+					dev_warn(dev, "Setting VID input "
+						 "voltage to TTL\n");
+					superio_outb(sio_data->sioreg,
+						     SIO_REG_EN_VRM10,
+						     en_vrm10 & ~0x08);
+				} else if (!(en_vrm10 & 0x08)
+					   && data->vrm == 100) {
+					dev_warn(dev, "Setting VID input "
+						 "voltage to VRM10\n");
+					superio_outb(sio_data->sioreg,
+						     SIO_REG_EN_VRM10,
+						     en_vrm10 | 0x08);
+				}
+			}
+
+			data->vid = superio_inb(sio_data->sioreg,
+						SIO_REG_VID_DATA);
+			if (sio_data->kind == w83627ehf) /* 6 VID pins only */
+				data->vid &= 0x3f;
+
+			err = device_create_file(dev, &dev_attr_cpu0_vid);
+			if (err)
+				goto exit_release;
+		} else {
+			dev_info(dev, "VID pins in output mode, CPU VID not "
+				 "available\n");
+		}
 	}
 
 	/* fan4 and fan5 share some pins with the GPIO and serial flash */
-
-	fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
-	fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
+	if (sio_data->kind == w83667hg) {
+		fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
+		fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
+	} else {
+		fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
+		fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
+	}
 	superio_exit(sio_data->sioreg);
 
 	/* It looks like fan4 and fan5 pins can be alternatively used
@@ -1329,9 +1389,9 @@ static int __devinit w83627ehf_probe(str
 
 	data->has_fan = 0x07; /* fan1, fan2 and fan3 */
 	i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
-	if ((i & (1 << 2)) && (!fan4pin))
+	if ((i & (1 << 2)) && fan4pin)
 		data->has_fan |= (1 << 3);
-	if (!(i & (1 << 1)) && (!fan5pin))
+	if (!(i & (1 << 1)) && fan5pin)
 		data->has_fan |= (1 << 4);
 
 	/* Read fan clock dividers immediately */
@@ -1344,14 +1404,16 @@ static int __devinit w83627ehf_probe(str
 			goto exit_remove;
 
 	/* if fan4 is enabled create the sf3 files for it */
-	if (data->has_fan & (1 << 3))
+	if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
 		for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
 			if ((err = device_create_file(dev,
 				&sda_sf3_arrays_fan4[i].dev_attr)))
 				goto exit_remove;
 		}
 
-	for (i = 0; i < data->in_num; i++)
+	for (i = 0; i < data->in_num; i++) {
+		if ((i == 6) && data->in6_skip)
+			continue;
 		if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
 			|| (err = device_create_file(dev,
 				&sda_in_alarm[i].dev_attr))
@@ -1360,6 +1422,7 @@ static int __devinit w83627ehf_probe(str
 			|| (err = device_create_file(dev,
 				&sda_in_max[i].dev_attr)))
 			goto exit_remove;
+	}
 
 	for (i = 0; i < 5; i++) {
 		if (data->has_fan & (1 << i)) {
@@ -1372,7 +1435,7 @@ static int __devinit w83627ehf_probe(str
 				|| (err = device_create_file(dev,
 					&sda_fan_min[i].dev_attr)))
 				goto exit_remove;
-			if (i < 4 && /* w83627ehf only has 4 pwm */
+			if (i < data->pwm_num &&
 				((err = device_create_file(dev,
 					&sda_pwm[i].dev_attr))
 				|| (err = device_create_file(dev,
@@ -1387,9 +1450,21 @@ static int __devinit w83627ehf_probe(str
 		}
 	}
 
-	for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
-		if ((err = device_create_file(dev, &sda_temp[i].dev_attr)))
+	for (i = 0; i < 3; i++) {
+		if ((i == 2) && data->temp3_disable)
+			continue;
+		if ((err = device_create_file(dev,
+				&sda_temp_input[i].dev_attr))
+			|| (err = device_create_file(dev,
+				&sda_temp_max[i].dev_attr))
+			|| (err = device_create_file(dev,
+				&sda_temp_max_hyst[i].dev_attr))
+			|| (err = device_create_file(dev,
+				&sda_temp_alarm[i].dev_attr))
+			|| (err = device_create_file(dev,
+				&sda_temp_type[i].dev_attr)))
 			goto exit_remove;
+	}
 
 	err = device_create_file(dev, &dev_attr_name);
 	if (err)
@@ -1442,6 +1517,7 @@ static int __init w83627ehf_find(int sio
 	static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
 	static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
 	static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
+	static const char __initdata sio_name_W83667HG[] = "W83667HG";
 
 	u16 val;
 	const char *sio_name;
@@ -1466,6 +1542,10 @@ static int __init w83627ehf_find(int sio
 		sio_data->kind = w83627dhg;
 		sio_name = sio_name_W83627DHG;
 		break;
+	case SIO_W83667HG_ID:
+		sio_data->kind = w83667hg;
+		sio_name = sio_name_W83667HG;
+		break;
 	default:
 		if (val != 0xffff)
 			pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/hwmon/w83781d.c linux-libre-2.6.30-gnu1/drivers/hwmon/w83781d.c
--- linux-libre-2.6.29-gnu1/drivers/hwmon/w83781d.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/hwmon/w83781d.c	2009-06-09 23:05:27.000000000 -0400
@@ -1462,7 +1462,8 @@ static struct w83781d_data *w83781d_upda
 				data->pwm[i] =
 				    w83781d_read_value(data,
 						       W83781D_REG_PWM[i]);
-				if ((data->type != w83782d || !client->driver)
+				/* Only W83782D on SMBus has PWM3 and PWM4 */
+				if ((data->type != w83782d || !client)
 				    && i == 1)
 					break;
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-bit.c linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-bit.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-bit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-bit.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,7 @@ static int sclhi(struct i2c_algo_bit_dat
 		 * chips may hold it low ("clock stretching") while they
 		 * are processing data internally.
 		 */
-		if (time_after_eq(jiffies, start + adap->timeout))
+		if (time_after(jiffies, start + adap->timeout))
 			return -ETIMEDOUT;
 		cond_resched();
 	}
@@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2
 
 	/* register new adapter to i2c module... */
 	adap->algo = &i2c_bit_algo;
-
-	adap->timeout = 100;	/* default values, should	*/
-	adap->retries = 3;	/* be replaced by defines	*/
+	adap->retries = 3;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-pca.c linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-pca.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-pca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-pca.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,14 +22,18 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pca.h>
 
-#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
-#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
-#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
+#define DEB1(fmt, args...) do { if (i2c_debug >= 1)			\
+				 printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB2(fmt, args...) do { if (i2c_debug >= 2)			\
+				 printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB3(fmt, args...) do { if (i2c_debug >= 3)			\
+				 printk(KERN_DEBUG fmt, ## args); } while (0)
 
 static int i2c_debug;
 
@@ -43,19 +47,27 @@ static int i2c_debug;
 #define pca_wait(adap) adap->wait_for_completion(adap->data)
 #define pca_reset(adap) adap->reset_chip(adap->data)
 
+static void pca9665_reset(void *pd)
+{
+	struct i2c_algo_pca_data *adap = pd;
+	pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+	pca_outw(adap, I2C_PCA_IND, 0xA5);
+	pca_outw(adap, I2C_PCA_IND, 0x5A);
+}
+
 /*
  * Generate a start condition on the i2c bus.
  *
  * returns after the start condition has occurred
  */
-static void pca_start(struct i2c_algo_pca_data *adap)
+static int pca_start(struct i2c_algo_pca_data *adap)
 {
 	int sta = pca_get_con(adap);
 	DEB2("=== START\n");
 	sta |= I2C_PCA_CON_STA;
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
 	pca_set_con(adap, sta);
-	pca_wait(adap);
+	return pca_wait(adap);
 }
 
 /*
@@ -63,14 +75,14 @@ static void pca_start(struct i2c_algo_pc
  *
  * return after the repeated start condition has occurred
  */
-static void pca_repeated_start(struct i2c_algo_pca_data *adap)
+static int pca_repeated_start(struct i2c_algo_pca_data *adap)
 {
 	int sta = pca_get_con(adap);
 	DEB2("=== REPEATED START\n");
 	sta |= I2C_PCA_CON_STA;
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
 	pca_set_con(adap, sta);
-	pca_wait(adap);
+	return pca_wait(adap);
 }
 
 /*
@@ -96,7 +108,7 @@ static void pca_stop(struct i2c_algo_pca
  *
  * returns after the address has been sent
  */
-static void pca_address(struct i2c_algo_pca_data *adap,
+static int pca_address(struct i2c_algo_pca_data *adap,
 			struct i2c_msg *msg)
 {
 	int sta = pca_get_con(adap);
@@ -113,7 +125,7 @@ static void pca_address(struct i2c_algo_
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
 	pca_set_con(adap, sta);
 
-	pca_wait(adap);
+	return pca_wait(adap);
 }
 
 /*
@@ -121,7 +133,7 @@ static void pca_address(struct i2c_algo_
  *
  * Returns after the byte has been transmitted
  */
-static void pca_tx_byte(struct i2c_algo_pca_data *adap,
+static int pca_tx_byte(struct i2c_algo_pca_data *adap,
 			__u8 b)
 {
 	int sta = pca_get_con(adap);
@@ -131,7 +143,7 @@ static void pca_tx_byte(struct i2c_algo_
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
 	pca_set_con(adap, sta);
 
-	pca_wait(adap);
+	return pca_wait(adap);
 }
 
 /*
@@ -151,7 +163,7 @@ static void pca_rx_byte(struct i2c_algo_
  *
  * Returns after next byte has arrived.
  */
-static void pca_rx_ack(struct i2c_algo_pca_data *adap,
+static int pca_rx_ack(struct i2c_algo_pca_data *adap,
 		       int ack)
 {
 	int sta = pca_get_con(adap);
@@ -162,7 +174,7 @@ static void pca_rx_ack(struct i2c_algo_p
 		sta |= I2C_PCA_CON_AA;
 
 	pca_set_con(adap, sta);
-	pca_wait(adap);
+	return pca_wait(adap);
 }
 
 static int pca_xfer(struct i2c_adapter *i2c_adap,
@@ -175,14 +187,17 @@ static int pca_xfer(struct i2c_adapter *
 	int numbytes = 0;
 	int state;
 	int ret;
-	int timeout = i2c_adap->timeout;
+	int completed = 1;
+	unsigned long timeout = jiffies + i2c_adap->timeout;
 
-	while ((state = pca_status(adap)) != 0xf8 && timeout--) {
-		msleep(10);
-	}
-	if (state != 0xf8) {
-		dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state);
-		return -EAGAIN;
+	while ((state = pca_status(adap)) != 0xf8) {
+		if (time_before(jiffies, timeout)) {
+			msleep(10);
+		} else {
+			dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
+				"%#04x\n", state);
+			return -EAGAIN;
+		}
 	}
 
 	DEB1("{{{ XFER %d messages\n", num);
@@ -218,18 +233,19 @@ static int pca_xfer(struct i2c_adapter *
 
 		switch (state) {
 		case 0xf8: /* On reset or stop the bus is idle */
-			pca_start(adap);
+			completed = pca_start(adap);
 			break;
 
 		case 0x08: /* A START condition has been transmitted */
 		case 0x10: /* A repeated start condition has been transmitted */
-			pca_address(adap, msg);
+			completed = pca_address(adap, msg);
 			break;
 
 		case 0x18: /* SLA+W has been transmitted; ACK has been received */
 		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
 			if (numbytes < msg->len) {
-				pca_tx_byte(adap, msg->buf[numbytes]);
+				completed = pca_tx_byte(adap,
+							msg->buf[numbytes]);
 				numbytes++;
 				break;
 			}
@@ -237,7 +253,7 @@ static int pca_xfer(struct i2c_adapter *
 			if (curmsg == num)
 				pca_stop(adap);
 			else
-				pca_repeated_start(adap);
+				completed = pca_repeated_start(adap);
 			break;
 
 		case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
@@ -246,21 +262,22 @@ static int pca_xfer(struct i2c_adapter *
 			goto out;
 
 		case 0x40: /* SLA+R has been transmitted; ACK has been received */
-			pca_rx_ack(adap, msg->len > 1);
+			completed = pca_rx_ack(adap, msg->len > 1);
 			break;
 
 		case 0x50: /* Data bytes has been received; ACK has been returned */
 			if (numbytes < msg->len) {
 				pca_rx_byte(adap, &msg->buf[numbytes], 1);
 				numbytes++;
-				pca_rx_ack(adap, numbytes < msg->len - 1);
+				completed = pca_rx_ack(adap,
+						       numbytes < msg->len - 1);
 				break;
 			}
 			curmsg++; numbytes = 0;
 			if (curmsg == num)
 				pca_stop(adap);
 			else
-				pca_repeated_start(adap);
+				completed = pca_repeated_start(adap);
 			break;
 
 		case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
@@ -270,10 +287,21 @@ static int pca_xfer(struct i2c_adapter *
 
 		case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */
 			DEB2("NOT ACK received after data byte\n");
+			pca_stop(adap);
 			goto out;
 
 		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
 			DEB2("Arbitration lost\n");
+			/*
+			 * The PCA9564 data sheet (2006-09-01) says "A
+			 * START condition will be transmitted when the
+			 * bus becomes free (STOP or SCL and SDA high)"
+			 * when the STA bit is set (p. 11).
+			 *
+			 * In case this won't work, try pca_reset()
+			 * instead.
+			 */
+			pca_start(adap);
 			goto out;
 
 		case 0x58: /* Data byte has been received; NOT ACK has been returned */
@@ -283,7 +311,7 @@ static int pca_xfer(struct i2c_adapter *
 				if (curmsg == num)
 					pca_stop(adap);
 				else
-					pca_repeated_start(adap);
+					completed = pca_repeated_start(adap);
 			} else {
 				DEB2("NOT ACK sent after data byte received. "
 				     "Not final byte. numbytes %d. len %d\n",
@@ -309,11 +337,13 @@ static int pca_xfer(struct i2c_adapter *
 			break;
 		}
 
+		if (!completed)
+			goto out;
 	}
 
 	ret = curmsg;
  out:
-	DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
+	DEB1("}}} transfered %d/%d messages. "
 	     "status is %#04x. control is %#04x\n",
 	     curmsg, num, pca_status(adap),
 	     pca_get_con(adap));
@@ -330,26 +360,171 @@ static const struct i2c_algorithm pca_al
 	.functionality	= pca_func,
 };
 
-static int pca_init(struct i2c_adapter *adap)
+static unsigned int pca_probe_chip(struct i2c_adapter *adap)
 {
-	static int freqs[] = {330,288,217,146,88,59,44,36};
-	int clock;
 	struct i2c_algo_pca_data *pca_data = adap->algo_data;
-
-	if (pca_data->i2c_clock > 7) {
-		printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
-			adap->name);
-		pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+	/* The trick here is to check if there is an indirect register
+	 * available. If there is one, we will read the value we first
+	 * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
+	 * we wrote on I2C_PCA_ADR
+	 */
+	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+	pca_outw(pca_data, I2C_PCA_IND, 0xAA);
+	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
+	pca_outw(pca_data, I2C_PCA_IND, 0x00);
+	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+	if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
+		printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
+		return I2C_PCA_CHIP_9665;
+	} else {
+		printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
+		return I2C_PCA_CHIP_9564;
 	}
+}
+
+static int pca_init(struct i2c_adapter *adap)
+{
+	struct i2c_algo_pca_data *pca_data = adap->algo_data;
 
 	adap->algo = &pca_algo;
 
-	pca_reset(pca_data);
+	if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
+		static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
+		int clock;
 
-	clock = pca_clock(pca_data);
-	DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
+		if (pca_data->i2c_clock > 7) {
+			switch (pca_data->i2c_clock) {
+			case 330000:
+				pca_data->i2c_clock = I2C_PCA_CON_330kHz;
+				break;
+			case 288000:
+				pca_data->i2c_clock = I2C_PCA_CON_288kHz;
+				break;
+			case 217000:
+				pca_data->i2c_clock = I2C_PCA_CON_217kHz;
+				break;
+			case 146000:
+				pca_data->i2c_clock = I2C_PCA_CON_146kHz;
+				break;
+			case 88000:
+				pca_data->i2c_clock = I2C_PCA_CON_88kHz;
+				break;
+			case 59000:
+				pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+				break;
+			case 44000:
+				pca_data->i2c_clock = I2C_PCA_CON_44kHz;
+				break;
+			case 36000:
+				pca_data->i2c_clock = I2C_PCA_CON_36kHz;
+				break;
+			default:
+				printk(KERN_WARNING
+					"%s: Invalid I2C clock speed selected."
+					" Using default 59kHz.\n", adap->name);
+			pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+			}
+		} else {
+			printk(KERN_WARNING "%s: "
+				"Choosing the clock frequency based on "
+				"index is deprecated."
+				" Use the nominal frequency.\n", adap->name);
+		}
 
-	pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+		pca_reset(pca_data);
+
+		clock = pca_clock(pca_data);
+		printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
+		     adap->name, freqs[clock]);
+
+		pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+	} else {
+		int clock;
+		int mode;
+		int tlow, thi;
+		/* Values can be found on PCA9665 datasheet section 7.3.2.6 */
+		int min_tlow, min_thi;
+		/* These values are the maximum raise and fall values allowed
+		 * by the I2C operation mode (Standard, Fast or Fast+)
+		 * They are used (added) below to calculate the clock dividers
+		 * of PCA9665. Note that they are slightly different of the
+		 * real maximum, to allow the change on mode exactly on the
+		 * maximum clock rate for each mode
+		 */
+		int raise_fall_time;
+
+		struct i2c_algo_pca_data *pca_data = adap->algo_data;
+
+		/* Ignore the reset function from the module,
+		 * we can use the parallel bus reset
+		 */
+		pca_data->reset_chip = pca9665_reset;
+
+		if (pca_data->i2c_clock > 1265800) {
+			printk(KERN_WARNING "%s: I2C clock speed too high."
+				" Using 1265.8kHz.\n", adap->name);
+			pca_data->i2c_clock = 1265800;
+		}
+
+		if (pca_data->i2c_clock < 60300) {
+			printk(KERN_WARNING "%s: I2C clock speed too low."
+				" Using 60.3kHz.\n", adap->name);
+			pca_data->i2c_clock = 60300;
+		}
+
+		/* To avoid integer overflow, use clock/100 for calculations */
+		clock = pca_clock(pca_data) / 100;
+
+		if (pca_data->i2c_clock > 10000) {
+			mode = I2C_PCA_MODE_TURBO;
+			min_tlow = 14;
+			min_thi  = 5;
+			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+		} else if (pca_data->i2c_clock > 4000) {
+			mode = I2C_PCA_MODE_FASTP;
+			min_tlow = 17;
+			min_thi  = 9;
+			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+		} else if (pca_data->i2c_clock > 1000) {
+			mode = I2C_PCA_MODE_FAST;
+			min_tlow = 44;
+			min_thi  = 20;
+			raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
+		} else {
+			mode = I2C_PCA_MODE_STD;
+			min_tlow = 157;
+			min_thi  = 134;
+			raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
+		}
+
+		/* The minimum clock that respects the thi/tlow = 134/157 is
+		 * 64800 Hz. Below that, we have to fix the tlow to 255 and
+		 * calculate the thi factor.
+		 */
+		if (clock < 648) {
+			tlow = 255;
+			thi = 1000000 - clock * raise_fall_time;
+			thi /= (I2C_PCA_OSC_PER * clock) - tlow;
+		} else {
+			tlow = (1000000 - clock * raise_fall_time) * min_tlow;
+			tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
+			thi = tlow * min_thi / min_tlow;
+		}
+
+		pca_reset(pca_data);
+
+		printk(KERN_INFO
+		     "%s: Clock frequency is %dHz\n", adap->name, clock * 100);
+
+		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
+		pca_outw(pca_data, I2C_PCA_IND, mode);
+		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
+		pca_outw(pca_data, I2C_PCA_IND, tlow);
+		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
+		pca_outw(pca_data, I2C_PCA_IND, thi);
+
+		pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
+	}
 	udelay(500); /* 500 us for oscilator to stabilise */
 
 	return 0;
@@ -384,7 +559,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
 
 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
 	"Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
+MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
 MODULE_LICENSE("GPL");
 
 module_param(i2c_debug, int, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-pcf.c linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-pcf.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-pcf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-pcf.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,31 +1,30 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters		     */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-1997 Simon G. Vogl
-                   1998-2000 Hans Berglund
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU 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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from KyÃ¶sti MÃ¤lkki <kmalkki@cc.hut.fi> and
-   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
-   <mbailey@littlefeet-inc.com> */
-
-/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
-   messages, proper stop/repstart signaling during receive,
-   added detect code */
+/*
+ * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
+ *
+ *   Copyright (C) 1995-1997 Simon G. Vogl
+ *		   1998-2000 Hans Berglund
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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.
+ *
+ * With some changes from KyÃ¶sti MÃ¤lkki <kmalkki@cc.hut.fi> and
+ * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
+ * <mbailey@littlefeet-inc.com>
+ *
+ * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+ * messages, proper stop/repstart signaling during receive, added detect code
+ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -38,17 +37,18 @@
 #include "i2c-algo-pcf.h"
 
 
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- 	/* debug the protocol by showing transferred bits */
+#define DEB2(x) if (i2c_debug >= 2) x
+#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
+#define DEBPROTO(x) if (i2c_debug >= 9) x;
+	/* debug the protocol by showing transferred bits */
 #define DEF_TIMEOUT 16
 
-/* module parameters:
+/*
+ * module parameters:
  */
 static int i2c_debug;
 
-/* --- setting states on the bus with the right timing: ---------------	*/
+/* setting states on the bus with the right timing: */
 
 #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
 #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
@@ -57,22 +57,21 @@ static int i2c_debug;
 #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
 #define i2c_inb(adap) adap->getpcf(adap->data, 0)
 
-/* --- other auxiliary functions --------------------------------------	*/
+/* other auxiliary functions */
 
-static void i2c_start(struct i2c_algo_pcf_data *adap) 
+static void i2c_start(struct i2c_algo_pcf_data *adap)
 {
-	DEBPROTO(printk("S "));
+	DEBPROTO(printk(KERN_DEBUG "S "));
 	set_pcf(adap, 1, I2C_PCF_START);
 }
 
-static void i2c_repstart(struct i2c_algo_pcf_data *adap) 
+static void i2c_repstart(struct i2c_algo_pcf_data *adap)
 {
 	DEBPROTO(printk(" Sr "));
 	set_pcf(adap, 1, I2C_PCF_REPSTART);
 }
 
-
-static void i2c_stop(struct i2c_algo_pcf_data *adap) 
+static void i2c_stop(struct i2c_algo_pcf_data *adap)
 {
 	DEBPROTO(printk("P\n"));
 	set_pcf(adap, 1, I2C_PCF_STOP);
@@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_p
 {
 	DEB2(printk(KERN_INFO
 		"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
-		 *status));
-
-	/* Cleanup from LAB -- reset and enable ESO.
+		*status));
+	/*
+	 * Cleanup from LAB -- reset and enable ESO.
 	 * This resets the PCF8584; since we've lost the bus, no
 	 * further attempts should be made by callers to clean up
 	 * (no i2c_stop() etc.)
 	 */
 	set_pcf(adap, 1, I2C_PCF_PIN);
 	set_pcf(adap, 1, I2C_PCF_ESO);
-
-	/* We pause for a time period sufficient for any running
+	/*
+	 * We pause for a time period sufficient for any running
 	 * I2C transaction to complete -- the arbitration logic won't
 	 * work properly until the next START is seen.
 	 * It is assumed the bus driver or client has set a proper value.
@@ -108,48 +107,50 @@ static void handle_lab(struct i2c_algo_p
 		get_pcf(adap, 1)));
 }
 
-static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
+static int wait_for_bb(struct i2c_algo_pcf_data *adap)
+{
 
 	int timeout = DEF_TIMEOUT;
 	int status;
 
 	status = get_pcf(adap, 1);
-#ifndef STUB_I2C
-	while (timeout-- && !(status & I2C_PCF_BB)) {
+
+	while (!(status & I2C_PCF_BB) && --timeout) {
 		udelay(100); /* wait for 100 us */
 		status = get_pcf(adap, 1);
 	}
-#endif
-	if (timeout <= 0) {
+
+	if (timeout == 0) {
 		printk(KERN_ERR "Timeout waiting for Bus Busy\n");
+		return -ETIMEDOUT;
 	}
-	
-	return (timeout<=0);
-}
 
+	return 0;
+}
 
-static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
+static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
+{
 
 	int timeout = DEF_TIMEOUT;
 
 	*status = get_pcf(adap, 1);
-#ifndef STUB_I2C
-	while (timeout-- && (*status & I2C_PCF_PIN)) {
+
+	while ((*status & I2C_PCF_PIN) && --timeout) {
 		adap->waitforpin(adap->data);
 		*status = get_pcf(adap, 1);
 	}
 	if (*status & I2C_PCF_LAB) {
 		handle_lab(adap, status);
-		return(-EINTR);
+		return -EINTR;
 	}
-#endif
-	if (timeout <= 0)
-		return(-1);
-	else
-		return(0);
+
+	if (timeout == 0)
+		return -ETIMEDOUT;
+
+	return 0;
 }
 
-/* 
+/*
  * This should perform the 'PCF8584 initialization sequence' as described
  * in the Philips IC12 data book (1995, Aug 29).
  * There should be a 30 clock cycle wait after reset, I assume this
@@ -164,18 +165,21 @@ static int pcf_init_8584 (struct i2c_alg
 {
 	unsigned char temp;
 
-	DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
+	DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
+				get_pcf(adap, 1)));
 
 	/* S1=0x80: S0 selected, serial interface off */
 	set_pcf(adap, 1, I2C_PCF_PIN);
-	/* check to see S1 now used as R/W ctrl -
-	   PCF8584 does that when ESO is zero */
+	/*
+	 * check to see S1 now used as R/W ctrl -
+	 * PCF8584 does that when ESO is zero
+	 */
 	if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
 		return -ENXIO; /* definetly not PCF8584 */
 	}
 
-	/* load own address in S0, effective address is (own << 1)	*/
+	/* load own address in S0, effective address is (own << 1) */
 	i2c_outb(adap, get_own(adap));
 	/* check it's really written */
 	if ((temp = i2c_inb(adap)) != get_own(adap)) {
@@ -183,7 +187,7 @@ static int pcf_init_8584 (struct i2c_alg
 		return -ENXIO;
 	}
 
-	/* S1=0xA0, next byte in S2					*/
+	/* S1=0xA0, next byte in S2 */
 	set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
 	/* check to see S2 now selected */
 	if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
@@ -191,7 +195,7 @@ static int pcf_init_8584 (struct i2c_alg
 		return -ENXIO;
 	}
 
-	/* load clock register S2					*/
+	/* load clock register S2 */
 	i2c_outb(adap, get_clock(adap));
 	/* check it's really written, the only 5 lowest bits does matter */
 	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
@@ -199,7 +203,7 @@ static int pcf_init_8584 (struct i2c_alg
 		return -ENXIO;
 	}
 
-	/* Enable serial interface, idle, S0 selected			*/
+	/* Enable serial interface, idle, S0 selected */
 	set_pcf(adap, 1, I2C_PCF_IDLE);
 
 	/* check to see PCF is really idled and we can access status register */
@@ -207,57 +211,47 @@ static int pcf_init_8584 (struct i2c_alg
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
 		return -ENXIO;
 	}
-	
+
 	printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
 
 	return 0;
 }
 
-
-/* ----- Utility functions
- */
-
 static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
-                         int count, int last)
+			 int count, int last)
 {
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
 	int wrcount, status, timeout;
-    
+
 	for (wrcount=0; wrcount<count; ++wrcount) {
 		DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
-				buf[wrcount]&0xff));
+				buf[wrcount] & 0xff));
 		i2c_outb(adap, buf[wrcount]);
 		timeout = wait_for_pin(adap, &status);
 		if (timeout) {
-			if (timeout == -EINTR) {
-				/* arbitration lost */
-				return -EINTR;
-			}
+			if (timeout == -EINTR)
+				return -EINTR; /* arbitration lost */
+
 			i2c_stop(adap);
 			dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
 			return -EREMOTEIO; /* got a better one ?? */
 		}
-#ifndef STUB_I2C
 		if (status & I2C_PCF_LRB) {
 			i2c_stop(adap);
 			dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
 			return -EREMOTEIO; /* got a better one ?? */
 		}
-#endif
 	}
-	if (last) {
+	if (last)
 		i2c_stop(adap);
-	}
-	else {
+	else
 		i2c_repstart(adap);
-	}
 
-	return (wrcount);
+	return wrcount;
 }
 
-
 static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
-                         int count, int last)
+			 int count, int last)
 {
 	int i, status;
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
@@ -267,42 +261,36 @@ static int pcf_readbytes(struct i2c_adap
 	for (i = 0; i <= count; i++) {
 
 		if ((wfp = wait_for_pin(adap, &status))) {
-			if (wfp == -EINTR) {
-				/* arbitration lost */
-				return -EINTR;
-			}
+			if (wfp == -EINTR)
+				return -EINTR; /* arbitration lost */
+
 			i2c_stop(adap);
 			dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
-			return (-1);
+			return -1;
 		}
 
-#ifndef STUB_I2C
 		if ((status & I2C_PCF_LRB) && (i != count)) {
 			i2c_stop(adap);
 			dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
-			return (-1);
+			return -1;
 		}
-#endif
-		
+
 		if (i == count - 1) {
 			set_pcf(adap, 1, I2C_PCF_ESO);
-		} else 
-		if (i == count) {
-			if (last) {
+		} else if (i == count) {
+			if (last)
 				i2c_stop(adap);
-			} else {
+			else
 				i2c_repstart(adap);
-			}
-		};
+		}
 
-		if (i) {
+		if (i)
 			buf[i - 1] = i2c_inb(adap);
-		} else {
+		else
 			i2c_inb(adap); /* dummy read */
-		}
 	}
 
-	return (i - 1);
+	return i - 1;
 }
 
 
@@ -323,14 +311,14 @@ static int pcf_doAddress(struct i2c_algo
 }
 
 static int pcf_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg *msgs, 
+		    struct i2c_msg *msgs,
 		    int num)
 {
 	struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
 	struct i2c_msg *pmsg;
 	int i;
 	int ret=0, timeout, status;
-    
+
 	if (adap->xfer_begin)
 		adap->xfer_begin(adap->data);
 
@@ -338,25 +326,24 @@ static int pcf_xfer(struct i2c_adapter *
 	timeout = wait_for_bb(adap);
 	if (timeout) {
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
-		            "Timeout waiting for BB in pcf_xfer\n");)
+			    "Timeout waiting for BB in pcf_xfer\n");)
 		i = -EIO;
 		goto out;
 	}
-	
+
 	for (i = 0;ret >= 0 && i < num; i++) {
 		pmsg = &msgs[i];
 
 		DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
 		     pmsg->flags & I2C_M_RD ? "read" : "write",
-                     pmsg->len, pmsg->addr, i + 1, num);)
-    
+		     pmsg->len, pmsg->addr, i + 1, num);)
+
 		ret = pcf_doAddress(adap, pmsg);
 
 		/* Send START */
-		if (i == 0) {
-			i2c_start(adap); 
-		}
-    
+		if (i == 0)
+			i2c_start(adap);
+
 		/* Wait for PIN (pending interrupt NOT) */
 		timeout = wait_for_pin(adap, &status);
 		if (timeout) {
@@ -371,8 +358,7 @@ static int pcf_xfer(struct i2c_adapter *
 			i = -EREMOTEIO;
 			goto out;
 		}
-    
-#ifndef STUB_I2C
+
 		/* Check LRB (last rcvd bit - slave ack) */
 		if (status & I2C_PCF_LRB) {
 			i2c_stop(adap);
@@ -380,27 +366,24 @@ static int pcf_xfer(struct i2c_adapter *
 			i = -EREMOTEIO;
 			goto out;
 		}
-#endif
-    
+
 		DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
 			    i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-    
-		/* Read */
+
 		if (pmsg->flags & I2C_M_RD) {
-			/* read bytes into buffer*/
 			ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
-                                            (i + 1 == num));
-        
+					    (i + 1 == num));
+
 			if (ret != pmsg->len) {
 				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
 					    "only read %d bytes.\n",ret));
 			} else {
 				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
 			}
-		} else { /* Write */
+		} else {
 			ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
-                                            (i + 1 == num));
-        
+					    (i + 1 == num));
+
 			if (ret != pmsg->len) {
 				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
 					    "only wrote %d bytes.\n",ret));
@@ -413,24 +396,23 @@ static int pcf_xfer(struct i2c_adapter *
 out:
 	if (adap->xfer_end)
 		adap->xfer_end(adap->data);
-	return (i);
+	return i;
 }
 
 static u32 pcf_func(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
 	       I2C_FUNC_PROTOCOL_MANGLING;
 }
 
-/* -----exported algorithm data: -------------------------------------	*/
-
+/* exported algorithm data: */
 static const struct i2c_algorithm pcf_algo = {
 	.master_xfer	= pcf_xfer,
 	.functionality	= pcf_func,
 };
 
-/* 
- * registering functions to load algorithms at runtime 
+/*
+ * registering functions to load algorithms at runtime
  */
 int i2c_pcf_add_bus(struct i2c_adapter *adap)
 {
@@ -441,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *
 
 	/* register new adapter to i2c module... */
 	adap->algo = &pcf_algo;
-	adap->timeout = 100;
 
 	if ((rval = pcf_init_8584(pcf_adap)))
 		return rval;
@@ -458,4 +439,4 @@ MODULE_LICENSE("GPL");
 
 module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(i2c_debug,
-        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
+	"debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-sgi.c linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-sgi.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/i2c-algo-sgi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/i2c-algo-sgi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,179 +0,0 @@
-/*
- * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
- * MACE (SGI O2) chips.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
-
-
-#define SGI_I2C_FORCE_IDLE	(0 << 0)
-#define SGI_I2C_NOT_IDLE	(1 << 0)
-#define SGI_I2C_WRITE		(0 << 1)
-#define SGI_I2C_READ		(1 << 1)
-#define SGI_I2C_RELEASE_BUS	(0 << 2)
-#define SGI_I2C_HOLD_BUS	(1 << 2)
-#define SGI_I2C_XFER_DONE	(0 << 4)
-#define SGI_I2C_XFER_BUSY	(1 << 4)
-#define SGI_I2C_ACK		(0 << 5)
-#define SGI_I2C_NACK		(1 << 5)
-#define SGI_I2C_BUS_OK		(0 << 7)
-#define SGI_I2C_BUS_ERR		(1 << 7)
-
-#define get_control()		adap->getctrl(adap->data)
-#define set_control(val)	adap->setctrl(adap->data, val)
-#define read_data()		adap->rdata(adap->data)
-#define write_data(val)		adap->wdata(adap->data, val)
-
-
-static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
-{
-	int i;
-
-	for (i = 0; i < adap->xfer_timeout; i++) {
-		if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
-			return 0;
-		udelay(1);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_algo_sgi_data *adap)
-{
-	int i;
-
-	if (wait_xfer_done(adap))
-		return -ETIMEDOUT;
-	for (i = 0; i < adap->ack_timeout; i++) {
-		if ((get_control() & SGI_I2C_NACK) == 0)
-			return 0;
-		udelay(1);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int force_idle(struct i2c_algo_sgi_data *adap)
-{
-	int i;
-
-	set_control(SGI_I2C_FORCE_IDLE);
-	for (i = 0; i < adap->xfer_timeout; i++) {
-		if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
-			goto out;
-		udelay(1);
-	}
-	return -ETIMEDOUT;
-out:
-	if (get_control() & SGI_I2C_BUS_ERR)
-		return -EIO;
-	return 0;
-}
-
-static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
-		      int rd)
-{
-	if (rd)
-		set_control(SGI_I2C_NOT_IDLE);
-	/* Check if bus is idle, eventually force it to do so */
-	if (get_control() & SGI_I2C_NOT_IDLE)
-		if (force_idle(adap))
-	                return -EIO;
-	/* Write out the i2c chip address and specify operation */
-	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
-	if (rd)
-		addr |= 1;
-	write_data(addr);
-	if (wait_ack(adap))
-		return -EIO;
-	return 0;
-}
-
-static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
-		    unsigned int len)
-{
-	int i;
-
-	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
-	for (i = 0; i < len; i++) {
-		if (wait_xfer_done(adap))
-			return -EIO;
-		buf[i] = read_data();
-	}
-	set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
-
-	return 0;
-
-}
-
-static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
-		     unsigned int len)
-{
-	int i;
-
-	/* We are already in write state */
-	for (i = 0; i < len; i++) {
-		write_data(buf[i]);
-		if (wait_ack(adap))
-			return -EIO;
-	}
-	return 0;
-}
-
-static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
-		    int num)
-{
-	struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
-	struct i2c_msg *p;
-	int i, err = 0;
-
-	for (i = 0; !err && i < num; i++) {
-		p = &msgs[i];
-		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
-		if (err || !p->len)
-			continue;
-		if (p->flags & I2C_M_RD)
-			err = i2c_read(adap, p->buf, p->len);
-		else
-			err = i2c_write(adap, p->buf, p->len);
-	}
-
-	return (err < 0) ? err : i;
-}
-
-static u32 sgi_func(struct i2c_adapter *adap)
-{
-	return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sgi_algo = {
-	.master_xfer	= sgi_xfer,
-	.functionality	= sgi_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_sgi_add_bus(struct i2c_adapter *adap)
-{
-	adap->algo = &sgi_algo;
-
-	return i2c_add_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_sgi_add_bus);
-
-MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
-MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/Kconfig linux-libre-2.6.30-gnu1/drivers/i2c/algos/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -14,8 +14,4 @@ config I2C_ALGOPCF
 config I2C_ALGOPCA
 	tristate "I2C PCA 9564 interfaces"
 
-config I2C_ALGO_SGI
-	tristate
-	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-
 endmenu
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/algos/Makefile linux-libre-2.6.30-gnu1/drivers/i2c/algos/Makefile
--- linux-libre-2.6.29-gnu1/drivers/i2c/algos/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/algos/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
 
 ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
 EXTRA_CFLAGS += -DDEBUG
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-acorn.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-acorn.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-acorn.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-acorn.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,9 +15,9 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/hardware/ioc.h>
 #include <asm/system.h>
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ali1535.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ali1535.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ali1535.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ali1535.c	2009-06-09 23:05:27.000000000 -0400
@@ -284,7 +284,7 @@ static int ali1535_transaction(struct i2
 		 && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		result = -ETIMEDOUT;
 		dev_err(&adap->dev, "SMBus Timeout!\n");
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ali15x3.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ali15x3.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ali15x3.c	2009-06-09 23:05:27.000000000 -0400
@@ -306,7 +306,7 @@ static int ali15x3_transaction(struct i2
 		 && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		result = -ETIMEDOUT;
 		dev_err(&adap->dev, "SMBus Timeout!\n");
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-amd756.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-amd756.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-amd756.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-amd756.c	2009-06-09 23:05:27.000000000 -0400
@@ -126,7 +126,7 @@ static int amd756_transaction(struct i2c
 		} while ((temp & (GS_HST_STS | GS_SMB_STS)) &&
 		         (timeout++ < MAX_TIMEOUT));
 		/* If the SMBus is still busy, we give up */
-		if (timeout >= MAX_TIMEOUT) {
+		if (timeout > MAX_TIMEOUT) {
 			dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp);
 			goto abort;
 		}
@@ -143,7 +143,7 @@ static int amd756_transaction(struct i2c
 	} while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_dbg(&adap->dev, "Completion timeout!\n");
 		goto abort;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-cpm.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-cpm.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-cpm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-cpm.c	2009-06-09 23:05:27.000000000 -0400
@@ -531,16 +531,16 @@ static int __devinit cpm_i2c_setup(struc
 	rbdf = cpm->rbase;
 
 	for (i = 0; i < CPM_MAXBD; i++) {
-		cpm->rxbuf[i] = dma_alloc_coherent(
-			NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+		cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev,
+						   CPM_MAX_READ + 1,
+						   &cpm->rxdma[i], GFP_KERNEL);
 		if (!cpm->rxbuf[i]) {
 			ret = -ENOMEM;
 			goto out_muram;
 		}
 		out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
 
-		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
-			NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
 		if (!cpm->txbuf[i]) {
 			ret = -ENOMEM;
 			goto out_muram;
@@ -585,10 +585,10 @@ static int __devinit cpm_i2c_setup(struc
 out_muram:
 	for (i = 0; i < CPM_MAXBD; i++) {
 		if (cpm->rxbuf[i])
-			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
 				cpm->rxbuf[i], cpm->rxdma[i]);
 		if (cpm->txbuf[i])
-			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
 				cpm->txbuf[i], cpm->txdma[i]);
 	}
 	cpm_muram_free(cpm->dp_addr);
@@ -619,9 +619,9 @@ static void cpm_i2c_shutdown(struct cpm_
 
 	/* Free all memory */
 	for (i = 0; i < CPM_MAXBD; i++) {
-		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+		dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
 			cpm->rxbuf[i], cpm->rxdma[i]);
-		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+		dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
 			cpm->txbuf[i], cpm->txdma[i]);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-davinci.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-davinci.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-davinci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-davinci.c	2009-06-09 23:05:27.000000000 -0400
@@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy
 {
 	unsigned long timeout;
 
-	timeout = jiffies + DAVINCI_I2C_TIMEOUT;
+	timeout = jiffies + dev->adapter.timeout;
 	while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
 	       & DAVINCI_I2C_STR_BB) {
 		if (time_after(jiffies, timeout)) {
@@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter
 	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
 
 	r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
-						      DAVINCI_I2C_TIMEOUT);
+						      dev->adapter.timeout);
 	if (r == 0) {
 		dev_err(dev->dev, "controller timed out\n");
 		i2c_davinci_init(dev);
@@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct plat
 	strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
 	adap->algo = &i2c_davinci_algo;
 	adap->dev.parent = &pdev->dev;
-
-	/* FIXME */
-	adap->timeout = 1;
+	adap->timeout = DAVINCI_I2C_TIMEOUT;
 
 	adap->nr = pdev->id;
 	r = i2c_add_numbered_adapter(adap);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-i801.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-i801.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-i801.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-i801.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,6 +65,7 @@
 #include <linux/i2c.h>
 #include <linux/acpi.h>
 #include <linux/io.h>
+#include <linux/dmi.h>
 
 /* I801 SMBus address offsets */
 #define SMBHSTSTS	(0 + i801_smba)
@@ -236,7 +237,7 @@ static int i801_transaction(int xact)
 		status = inb_p(SMBHSTSTS);
 	} while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
 
-	result = i801_check_post(status, timeout >= MAX_TIMEOUT);
+	result = i801_check_post(status, timeout > MAX_TIMEOUT);
 	if (result < 0)
 		return result;
 
@@ -256,9 +257,9 @@ static void i801_wait_hwpec(void)
 	} while ((!(status & SMBHSTSTS_INTR))
 		 && (timeout++ < MAX_TIMEOUT));
 
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT)
 		dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
-	}
+
 	outb_p(status, SMBHSTSTS);
 }
 
@@ -343,7 +344,7 @@ static int i801_block_transaction_byte_b
 		while ((!(status & SMBHSTSTS_BYTE_DONE))
 		       && (timeout++ < MAX_TIMEOUT));
 
-		result = i801_check_post(status, timeout >= MAX_TIMEOUT);
+		result = i801_check_post(status, timeout > MAX_TIMEOUT);
 		if (result < 0)
 			return result;
 
@@ -616,10 +617,81 @@ static void __init input_apanel_init(voi
 static void __init input_apanel_init(void) {}
 #endif
 
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+struct dmi_onboard_device_info {
+	const char *name;
+	u8 type;
+	unsigned short i2c_addr;
+	const char *i2c_type;
+};
+
+static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
+	{ "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
+	{ "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
+	{ "Hades",  DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
+};
+
+static void __devinit dmi_check_onboard_device(u8 type, const char *name,
+					       struct i2c_adapter *adap)
+{
+	int i;
+	struct i2c_board_info info;
+
+	for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
+		/* & ~0x80, ignore enabled/disabled bit */
+		if ((type & ~0x80) != dmi_devices[i].type)
+			continue;
+		if (strcmp(name, dmi_devices[i].name))
+			continue;
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		info.addr = dmi_devices[i].i2c_addr;
+		strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
+		i2c_new_device(adap, &info);
+		break;
+	}
+}
+
+/* We use our own function to check for onboard devices instead of
+   dmi_find_device() as some buggy BIOS's have the devices we are interested
+   in marked as disabled */
+static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
+						void *adap)
+{
+	int i, count;
+
+	if (dm->type != 10)
+		return;
+
+	count = (dm->length - sizeof(struct dmi_header)) / 2;
+	for (i = 0; i < count; i++) {
+		const u8 *d = (char *)(dm + 1) + (i * 2);
+		const char *name = ((char *) dm) + dm->length;
+		u8 type = d[0];
+		u8 s = d[1];
+
+		if (!s)
+			continue;
+		s--;
+		while (s > 0 && name[0]) {
+			name += strlen(name) + 1;
+			s--;
+		}
+		if (name[0] == 0) /* Bogus string reference */
+			continue;
+
+		dmi_check_onboard_device(type, name, adap);
+	}
+}
+#endif
+
 static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	unsigned char temp;
 	int err;
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+	const char *vendor;
+#endif
 
 	I801_dev = dev;
 	i801_features = 0;
@@ -712,6 +784,11 @@ static int __devinit i801_probe(struct p
 		i2c_new_device(&i801_adapter, &info);
 	}
 #endif
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+	vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+	if (vendor && !strcmp(vendor, "FUJITSU SIEMENS"))
+		dmi_walk(dmi_check_onboard_devices, &i801_adapter);
+#endif
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ibm_iic.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ibm_iic.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-ibm_iic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-ibm_iic.c	2009-06-09 23:05:27.000000000 -0400
@@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_ii
 	if (dev->irq >= 0){
 		/* Interrupt mode */
 		ret = wait_event_interruptible_timeout(dev->wq,
-			!(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+			!(in_8(&iic->sts) & STS_PT), dev->adap.timeout);
 
 		if (unlikely(ret < 0))
 			DBG("%d: wait interrupted\n", dev->idx);
@@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_ii
 	}
 	else {
 		/* Polling mode */
-		unsigned long x = jiffies + dev->adap.timeout * HZ;
+		unsigned long x = jiffies + dev->adap.timeout;
 
 		while (in_8(&iic->sts) & STS_PT){
 			if (unlikely(time_after(jiffies, x))){
@@ -748,7 +748,7 @@ static int __devinit iic_probe(struct of
 	i2c_set_adapdata(adap, dev);
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->algo = &iic_algo;
-	adap->timeout = 1;
+	adap->timeout = HZ;
 
 	ret = i2c_add_adapter(adap);
 	if (ret  < 0) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-imx.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-imx.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-imx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-imx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,624 @@
+/*
+ *	Copyright (C) 2002 Motorola GSG-China
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU 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.
+ *
+ * Author:
+ *	Darius Augulis, Teltonika Inc.
+ *
+ * Desc.:
+ *	Implementation of I2C Adapter/Algorithm Driver
+ *	for I2C Bus integrated in Freescale i.MX/MXC processors
+ *
+ *	Derived from Motorola GSG China I2C example driver
+ *
+ *	Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de
+ *	Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de
+ *	Copyright (C) 2007 RightHand Technologies, Inc.
+ *	Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
+ *
+ */
+
+/** Includes *******************************************************************
+*******************************************************************************/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+
+/** Defines ********************************************************************
+*******************************************************************************/
+
+/* This will be the driver name the kernel reports */
+#define DRIVER_NAME "imx-i2c"
+
+/* Default value */
+#define IMX_I2C_BIT_RATE	100000	/* 100kHz */
+
+/* IMX I2C registers */
+#define IMX_I2C_IADR	0x00	/* i2c slave address */
+#define IMX_I2C_IFDR	0x04	/* i2c frequency divider */
+#define IMX_I2C_I2CR	0x08	/* i2c control */
+#define IMX_I2C_I2SR	0x0C	/* i2c status */
+#define IMX_I2C_I2DR	0x10	/* i2c transfer data */
+
+/* Bits of IMX I2C registers */
+#define I2SR_RXAK	0x01
+#define I2SR_IIF	0x02
+#define I2SR_SRW	0x04
+#define I2SR_IAL	0x10
+#define I2SR_IBB	0x20
+#define I2SR_IAAS	0x40
+#define I2SR_ICF	0x80
+#define I2CR_RSTA	0x04
+#define I2CR_TXAK	0x08
+#define I2CR_MTX	0x10
+#define I2CR_MSTA	0x20
+#define I2CR_IIEN	0x40
+#define I2CR_IEN	0x80
+
+/** Variables ******************************************************************
+*******************************************************************************/
+
+/*
+ * sorted list of clock divider, register value pairs
+ * taken from table 26-5, p.26-9, Freescale i.MX
+ * Integrated Portable System Processor Reference Manual
+ * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007
+ *
+ * Duplicated divider values removed from list
+ */
+
+static u16 __initdata i2c_clk_div[50][2] = {
+	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
+	{ 30,	0x00 },	{ 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
+	{ 42,	0x03 }, { 44,	0x27 },	{ 48,	0x28 }, { 52,	0x05 },
+	{ 56,	0x29 }, { 60,	0x06 }, { 64,	0x2A },	{ 72,	0x2B },
+	{ 80,	0x2C }, { 88,	0x09 }, { 96,	0x2D }, { 104,	0x0A },
+	{ 112,	0x2E }, { 128,	0x2F }, { 144,	0x0C }, { 160,	0x30 },
+	{ 192,	0x31 },	{ 224,	0x32 }, { 240,	0x0F }, { 256,	0x33 },
+	{ 288,	0x10 }, { 320,	0x34 },	{ 384,	0x35 }, { 448,	0x36 },
+	{ 480,	0x13 }, { 512,	0x37 }, { 576,	0x14 },	{ 640,	0x38 },
+	{ 768,	0x39 }, { 896,	0x3A }, { 960,	0x17 }, { 1024,	0x3B },
+	{ 1152,	0x18 }, { 1280,	0x3C }, { 1536,	0x3D }, { 1792,	0x3E },
+	{ 1920,	0x1B },	{ 2048,	0x3F }, { 2304,	0x1C }, { 2560,	0x1D },
+	{ 3072,	0x1E }, { 3840,	0x1F }
+};
+
+struct imx_i2c_struct {
+	struct i2c_adapter	adapter;
+	struct resource		*res;
+	struct clk		*clk;
+	void __iomem		*base;
+	int			irq;
+	wait_queue_head_t	queue;
+	unsigned long		i2csr;
+	unsigned int 		disable_delay;
+};
+
+/** Functions for IMX I2C adapter driver ***************************************
+*******************************************************************************/
+
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx)
+{
+	unsigned long orig_jiffies = jiffies;
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+	/* wait for bus not busy */
+	while (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_IBB) {
+		if (signal_pending(current)) {
+			dev_dbg(&i2c_imx->adapter.dev,
+				"<%s> I2C Interrupted\n", __func__);
+			return -EINTR;
+		}
+		if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+			dev_dbg(&i2c_imx->adapter.dev,
+				"<%s> I2C bus is busy\n", __func__);
+			return -EIO;
+		}
+		schedule();
+	}
+
+	return 0;
+}
+
+static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
+{
+	int result;
+
+	result = wait_event_interruptible_timeout(i2c_imx->queue,
+		i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+
+	if (unlikely(result < 0)) {
+		dev_dbg(&i2c_imx->adapter.dev, "<%s> result < 0\n", __func__);
+		return result;
+	} else if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
+		dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
+	i2c_imx->i2csr = 0;
+	return 0;
+}
+
+static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
+{
+	if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
+		dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
+		return -EIO;  /* No ACK */
+	}
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> ACK received\n", __func__);
+	return 0;
+}
+
+static void i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+{
+	unsigned int temp = 0;
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+	/* Enable I2C controller */
+	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+	/* Start I2C transaction */
+	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+	temp |= I2CR_MSTA;
+	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+}
+
+static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
+{
+	unsigned int temp = 0;
+
+	/* Stop I2C transaction */
+	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+	temp &= ~I2CR_MSTA;
+	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	/* setup chip registers to defaults */
+	writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+	/*
+	 * This delay caused by an i.MXL hardware bug.
+	 * If no (or too short) delay, no "STOP" bit will be generated.
+	 */
+	udelay(i2c_imx->disable_delay);
+	/* Disable I2C controller */
+	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+}
+
+static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
+							unsigned int rate)
+{
+	unsigned int i2c_clk_rate;
+	unsigned int div;
+	int i;
+
+	/* Divider value calculation */
+	i2c_clk_rate = clk_get_rate(i2c_imx->clk);
+	div = (i2c_clk_rate + rate - 1) / rate;
+	if (div < i2c_clk_div[0][0])
+		i = 0;
+	else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
+		i = ARRAY_SIZE(i2c_clk_div) - 1;
+	else
+		for (i = 0; i2c_clk_div[i][0] < div; i++);
+
+	/* Write divider value to register */
+	writeb(i2c_clk_div[i][1], i2c_imx->base + IMX_I2C_IFDR);
+
+	/*
+	 * There dummy delay is calculated.
+	 * It should be about one I2C clock period long.
+	 * This delay is used in I2C bus disable function
+	 * to fix chip hardware bug.
+	 */
+	i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
+		+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
+
+	/* dev_dbg() can't be used, because adapter is not yet registered */
+#ifdef CONFIG_I2C_DEBUG_BUS
+	printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n",
+		__func__, i2c_clk_rate, div);
+	printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
+		__func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
+#endif
+}
+
+static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
+{
+	struct imx_i2c_struct *i2c_imx = dev_id;
+	unsigned int temp;
+
+	temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+	if (temp & I2SR_IIF) {
+		/* save status register */
+		i2c_imx->i2csr = temp;
+		temp &= ~I2SR_IIF;
+		writeb(temp, i2c_imx->base + IMX_I2C_I2SR);
+		wake_up_interruptible(&i2c_imx->queue);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+{
+	int i, result;
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n",
+		__func__, msgs->addr << 1);
+
+	/* write slave address */
+	writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR);
+	result = i2c_imx_trx_complete(i2c_imx);
+	if (result)
+		return result;
+	result = i2c_imx_acked(i2c_imx);
+	if (result)
+		return result;
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__);
+
+	/* write data */
+	for (i = 0; i < msgs->len; i++) {
+		dev_dbg(&i2c_imx->adapter.dev,
+			"<%s> write byte: B%d=0x%X\n",
+			__func__, i, msgs->buf[i]);
+		writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR);
+		result = i2c_imx_trx_complete(i2c_imx);
+		if (result)
+			return result;
+		result = i2c_imx_acked(i2c_imx);
+		if (result)
+			return result;
+	}
+	return 0;
+}
+
+static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+{
+	int i, result;
+	unsigned int temp;
+
+	dev_dbg(&i2c_imx->adapter.dev,
+		"<%s> write slave address: addr=0x%x\n",
+		__func__, (msgs->addr << 1) | 0x01);
+
+	/* write slave address */
+	writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
+	result = i2c_imx_trx_complete(i2c_imx);
+	if (result)
+		return result;
+	result = i2c_imx_acked(i2c_imx);
+	if (result)
+		return result;
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);
+
+	/* setup bus to read data */
+	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+	temp &= ~I2CR_MTX;
+	if (msgs->len - 1)
+		temp &= ~I2CR_TXAK;
+	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
+
+	/* read data */
+	for (i = 0; i < msgs->len; i++) {
+		result = i2c_imx_trx_complete(i2c_imx);
+		if (result)
+			return result;
+		if (i == (msgs->len - 1)) {
+			dev_dbg(&i2c_imx->adapter.dev,
+				"<%s> clear MSTA\n", __func__);
+			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+			temp &= ~I2CR_MSTA;
+			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+		} else if (i == (msgs->len - 2)) {
+			dev_dbg(&i2c_imx->adapter.dev,
+				"<%s> set TXAK\n", __func__);
+			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+			temp |= I2CR_TXAK;
+			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+		}
+		msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
+		dev_dbg(&i2c_imx->adapter.dev,
+			"<%s> read byte: B%d=0x%X\n",
+			__func__, i, msgs->buf[i]);
+	}
+	return 0;
+}
+
+static int i2c_imx_xfer(struct i2c_adapter *adapter,
+						struct i2c_msg *msgs, int num)
+{
+	unsigned int i, temp;
+	int result;
+	struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
+
+	/* Check if i2c bus is not busy */
+	result = i2c_imx_bus_busy(i2c_imx);
+	if (result)
+		goto fail0;
+
+	/* Start I2C transfer */
+	i2c_imx_start(i2c_imx);
+
+	/* read/write data */
+	for (i = 0; i < num; i++) {
+		if (i) {
+			dev_dbg(&i2c_imx->adapter.dev,
+				"<%s> repeated start\n", __func__);
+			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+			temp |= I2CR_RSTA;
+			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+		}
+		dev_dbg(&i2c_imx->adapter.dev,
+			"<%s> transfer message: %d\n", __func__, i);
+		/* write/read data */
+#ifdef CONFIG_I2C_DEBUG_BUS
+		temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+		dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
+			"MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
+			(temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
+			(temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
+			(temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0));
+		temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+		dev_dbg(&i2c_imx->adapter.dev,
+			"<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
+			"IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
+			(temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0),
+			(temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0),
+			(temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
+			(temp & I2SR_RXAK ? 1 : 0));
+#endif
+		if (msgs[i].flags & I2C_M_RD)
+			result = i2c_imx_read(i2c_imx, &msgs[i]);
+		else
+			result = i2c_imx_write(i2c_imx, &msgs[i]);
+	}
+
+fail0:
+	/* Stop I2C transfer */
+	i2c_imx_stop(i2c_imx);
+
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
+		(result < 0) ? "error" : "success msg",
+			(result < 0) ? result : num);
+	return (result < 0) ? result : num;
+}
+
+static u32 i2c_imx_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm i2c_imx_algo = {
+	.master_xfer	= i2c_imx_xfer,
+	.functionality	= i2c_imx_func,
+};
+
+static int __init i2c_imx_probe(struct platform_device *pdev)
+{
+	struct imx_i2c_struct *i2c_imx;
+	struct resource *res;
+	struct imxi2c_platform_data *pdata;
+	void __iomem *base;
+	resource_size_t res_size;
+	int irq;
+	int ret;
+
+	dev_dbg(&pdev->dev, "<%s>\n", __func__);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "can't get device resources\n");
+		return -ENOENT;
+	}
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "can't get irq number\n");
+		return -ENOENT;
+	}
+
+	pdata = pdev->dev.platform_data;
+
+	if (pdata && pdata->init) {
+		ret = pdata->init(&pdev->dev);
+		if (ret)
+			return ret;
+	}
+
+	res_size = resource_size(res);
+	base = ioremap(res->start, res_size);
+	if (!base) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		ret = -EIO;
+		goto fail0;
+	}
+
+	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;
+	}
+
+	/* Setup i2c_imx driver structure */
+	strcpy(i2c_imx->adapter.name, pdev->name);
+	i2c_imx->adapter.owner		= THIS_MODULE;
+	i2c_imx->adapter.algo		= &i2c_imx_algo;
+	i2c_imx->adapter.dev.parent	= &pdev->dev;
+	i2c_imx->adapter.nr 		= pdev->id;
+	i2c_imx->irq			= irq;
+	i2c_imx->base			= base;
+	i2c_imx->res			= res;
+
+	/* Get I2C clock */
+	i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
+	if (IS_ERR(i2c_imx->clk)) {
+		ret = PTR_ERR(i2c_imx->clk);
+		dev_err(&pdev->dev, "can't get I2C clock\n");
+		goto fail3;
+	}
+	clk_enable(i2c_imx->clk);
+
+	/* Request IRQ */
+	ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);
+	if (ret) {
+		dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq);
+		goto fail4;
+	}
+
+	/* Init queue */
+	init_waitqueue_head(&i2c_imx->queue);
+
+	/* Set up adapter data */
+	i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
+
+	/* Set up clock divider */
+	if (pdata && pdata->bitrate)
+		i2c_imx_set_clk(i2c_imx, pdata->bitrate);
+	else
+		i2c_imx_set_clk(i2c_imx, IMX_I2C_BIT_RATE);
+
+	/* Set up chip registers to defaults */
+	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+
+	/* Add I2C adapter */
+	ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "registration failed\n");
+		goto fail5;
+	}
+
+	/* Set up platform driver data */
+	platform_set_drvdata(pdev, i2c_imx);
+
+	dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq);
+	dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
+		i2c_imx->res->start, i2c_imx->res->end);
+	dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n",
+		res_size, i2c_imx->res->start);
+	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
+		i2c_imx->adapter.name);
+	dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
+
+	return 0;   /* Return OK */
+
+fail5:
+	free_irq(i2c_imx->irq, i2c_imx);
+fail4:
+	clk_disable(i2c_imx->clk);
+	clk_put(i2c_imx->clk);
+fail3:
+	release_mem_region(i2c_imx->res->start, resource_size(res));
+fail2:
+	kfree(i2c_imx);
+fail1:
+	iounmap(base);
+fail0:
+	if (pdata && pdata->exit)
+		pdata->exit(&pdev->dev);
+	return ret; /* Return error number */
+}
+
+static int __exit i2c_imx_remove(struct platform_device *pdev)
+{
+	struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev);
+	struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
+
+	/* remove adapter */
+	dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
+	i2c_del_adapter(&i2c_imx->adapter);
+	platform_set_drvdata(pdev, NULL);
+
+	/* free interrupt */
+	free_irq(i2c_imx->irq, i2c_imx);
+
+	/* setup chip registers to defaults */
+	writeb(0, i2c_imx->base + IMX_I2C_IADR);
+	writeb(0, i2c_imx->base + IMX_I2C_IFDR);
+	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+
+	/* Shut down hardware */
+	if (pdata && pdata->exit)
+		pdata->exit(&pdev->dev);
+
+	/* Disable I2C clock */
+	clk_disable(i2c_imx->clk);
+	clk_put(i2c_imx->clk);
+
+	release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res));
+	iounmap(i2c_imx->base);
+	kfree(i2c_imx);
+	return 0;
+}
+
+static struct platform_driver i2c_imx_driver = {
+	.probe		= i2c_imx_probe,
+	.remove		= __exit_p(i2c_imx_remove),
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init i2c_adap_imx_init(void)
+{
+	return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe);
+}
+
+static void __exit i2c_adap_imx_exit(void)
+{
+	platform_driver_unregister(&i2c_imx_driver);
+}
+
+module_init(i2c_adap_imx_init);
+module_exit(i2c_adap_imx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Darius Augulis");
+MODULE_DESCRIPTION("I2C adapter driver for IMX I2C bus");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-iop3xx.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-iop3xx.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-iop3xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-iop3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -488,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device
 	/*
 	 * Default values...should these come in from board code?
 	 */
-	new_adapter->timeout = 100;	
+	new_adapter->timeout = HZ;
 	new_adapter->algo = &iop3xx_i2c_algo;
 
 	init_waitqueue_head(&adapter_data->waitq);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-isch.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-isch.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-isch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-isch.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,7 @@ static int sch_transaction(void)
 	} while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-mpc.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-mpc.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-mpc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-mpc.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,18 +20,21 @@
 #include <linux/of_platform.h>
 #include <linux/of_i2c.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/fsl_devices.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 
+#include <asm/mpc52xx.h>
+#include <sysdev/fsl_soc.h>
+
 #define DRV_NAME "mpc-i2c"
 
-#define MPC_I2C_FDR 	0x04
-#define MPC_I2C_CR	0x08
-#define MPC_I2C_SR	0x0c
-#define MPC_I2C_DR	0x10
+#define MPC_I2C_FDR   0x04
+#define MPC_I2C_CR    0x08
+#define MPC_I2C_SR    0x0c
+#define MPC_I2C_DR    0x10
 #define MPC_I2C_DFSRR 0x14
 
 #define CCR_MEN  0x80
@@ -50,15 +53,27 @@
 #define CSR_RXAK 0x01
 
 struct mpc_i2c {
+	struct device *dev;
 	void __iomem *base;
 	u32 interrupt;
 	wait_queue_head_t queue;
 	struct i2c_adapter adap;
 	int irq;
-	u32 flags;
 };
 
-static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
+struct mpc_i2c_divider {
+	u16 divider;
+	u16 fdr;	/* including dfsrr */
+};
+
+struct mpc_i2c_match_data {
+	void (*setclock)(struct device_node *node,
+			 struct mpc_i2c *i2c,
+			 u32 clock, u32 prescaler);
+	u32 prescaler;
+};
+
+static inline void writeccr(struct mpc_i2c *i2c, u32 x)
 {
 	writeb(x, i2c->base + MPC_I2C_CR);
 }
@@ -70,7 +85,7 @@ static irqreturn_t mpc_i2c_isr(int irq,
 		/* Read again to allow register to stabilise */
 		i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
 		writeb(0, i2c->base + MPC_I2C_SR);
-		wake_up_interruptible(&i2c->queue);
+		wake_up(&i2c->queue);
 	}
 	return IRQ_HANDLED;
 }
@@ -100,12 +115,11 @@ static int i2c_wait(struct mpc_i2c *i2c,
 	u32 x;
 	int result = 0;
 
-	if (i2c->irq == NO_IRQ)
-	{
+	if (i2c->irq == NO_IRQ) {
 		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
 			schedule();
 			if (time_after(jiffies, orig_jiffies + timeout)) {
-				pr_debug("I2C: timeout\n");
+				dev_dbg(i2c->dev, "timeout\n");
 				writeccr(i2c, 0);
 				result = -EIO;
 				break;
@@ -115,14 +129,11 @@ static int i2c_wait(struct mpc_i2c *i2c,
 		writeb(0, i2c->base + MPC_I2C_SR);
 	} else {
 		/* Interrupt mode */
-		result = wait_event_interruptible_timeout(i2c->queue,
-			(i2c->interrupt & CSR_MIF), timeout * HZ);
+		result = wait_event_timeout(i2c->queue,
+			(i2c->interrupt & CSR_MIF), timeout);
 
-		if (unlikely(result < 0)) {
-			pr_debug("I2C: wait interrupted\n");
-			writeccr(i2c, 0);
-		} else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
-			pr_debug("I2C: wait timeout\n");
+		if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+			dev_dbg(i2c->dev, "wait timeout\n");
 			writeccr(i2c, 0);
 			result = -ETIMEDOUT;
 		}
@@ -135,17 +146,17 @@ static int i2c_wait(struct mpc_i2c *i2c,
 		return result;
 
 	if (!(x & CSR_MCF)) {
-		pr_debug("I2C: unfinished\n");
+		dev_dbg(i2c->dev, "unfinished\n");
 		return -EIO;
 	}
 
 	if (x & CSR_MAL) {
-		pr_debug("I2C: MAL\n");
+		dev_dbg(i2c->dev, "MAL\n");
 		return -EIO;
 	}
 
 	if (writing && (x & CSR_RXAK)) {
-		pr_debug("I2C: No RXAK\n");
+		dev_dbg(i2c->dev, "No RXAK\n");
 		/* generate stop */
 		writeccr(i2c, CCR_MEN);
 		return -EIO;
@@ -153,18 +164,187 @@ static int i2c_wait(struct mpc_i2c *i2c,
 	return 0;
 }
 
-static void mpc_i2c_setclock(struct mpc_i2c *i2c)
+#ifdef CONFIG_PPC_MPC52xx
+static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
+	{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
+	{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
+	{36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
+	{52, 0x63}, {56, 0x29}, {60, 0x41}, {64, 0x2a},
+	{68, 0x07}, {72, 0x2b}, {80, 0x2c}, {88, 0x09},
+	{96, 0x2d}, {104, 0x0a}, {112, 0x2e}, {120, 0x81},
+	{128, 0x2f}, {136, 0x47}, {144, 0x0c}, {160, 0x30},
+	{176, 0x49}, {192, 0x31}, {208, 0x4a}, {224, 0x32},
+	{240, 0x0f}, {256, 0x33}, {272, 0x87}, {288, 0x10},
+	{320, 0x34}, {352, 0x89}, {384, 0x35}, {416, 0x8a},
+	{448, 0x36}, {480, 0x13}, {512, 0x37}, {576, 0x14},
+	{640, 0x38}, {768, 0x39}, {896, 0x3a}, {960, 0x17},
+	{1024, 0x3b}, {1152, 0x18}, {1280, 0x3c}, {1536, 0x3d},
+	{1792, 0x3e}, {1920, 0x1b}, {2048, 0x3f}, {2304, 0x1c},
+	{2560, 0x1d}, {3072, 0x1e}, {3584, 0x7e}, {3840, 0x1f},
+	{4096, 0x7f}, {4608, 0x5c}, {5120, 0x5d}, {6144, 0x5e},
+	{7168, 0xbe}, {7680, 0x5f}, {8192, 0xbf}, {9216, 0x9c},
+	{10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
+};
+
+int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
 {
-	/* Set clock and filters */
-	if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
-		writeb(0x31, i2c->base + MPC_I2C_FDR);
-		writeb(0x10, i2c->base + MPC_I2C_DFSRR);
-	} else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
-		writeb(0x3f, i2c->base + MPC_I2C_FDR);
-	else
-		writel(0x1031, i2c->base + MPC_I2C_FDR);
+	const struct mpc_i2c_divider *div = NULL;
+	unsigned int pvr = mfspr(SPRN_PVR);
+	u32 divider;
+	int i;
+
+	if (!clock)
+		return -EINVAL;
+
+	/* Determine divider value */
+	divider = mpc52xx_find_ipb_freq(node) / clock;
+
+	/*
+	 * We want to choose an FDR/DFSR that generates an I2C bus speed that
+	 * is equal to or lower than the requested speed.
+	 */
+	for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_52xx); i++) {
+		div = &mpc_i2c_dividers_52xx[i];
+		/* Old MPC5200 rev A CPUs do not support the high bits */
+		if (div->fdr & 0xc0 && pvr == 0x80822011)
+			continue;
+		if (div->divider >= divider)
+			break;
+	}
+
+	return div ? (int)div->fdr : -EINVAL;
 }
 
+static void mpc_i2c_setclock_52xx(struct device_node *node,
+				  struct mpc_i2c *i2c,
+				  u32 clock, u32 prescaler)
+{
+	int ret, fdr;
+
+	ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
+	fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
+
+	writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
+
+	if (ret >= 0)
+		dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
+}
+#else /* !CONFIG_PPC_MPC52xx */
+static void mpc_i2c_setclock_52xx(struct device_node *node,
+				  struct mpc_i2c *i2c,
+				  u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_PPC_MPC52xx*/
+
+#ifdef CONFIG_FSL_SOC
+static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
+	{160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
+	{288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
+	{416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
+	{544, 0x0b03}, {576, 0x0104}, {608, 0x1603}, {640, 0x0105},
+	{672, 0x2003}, {704, 0x0b05}, {736, 0x2b03}, {768, 0x0106},
+	{800, 0x3603}, {832, 0x0b06}, {896, 0x012a}, {960, 0x0107},
+	{1024, 0x012b}, {1088, 0x1607}, {1152, 0x0108}, {1216, 0x2b07},
+	{1280, 0x0109}, {1408, 0x1609}, {1536, 0x010a}, {1664, 0x160a},
+	{1792, 0x012e}, {1920, 0x010b}, {2048, 0x012f}, {2176, 0x2b0b},
+	{2304, 0x010c}, {2560, 0x010d}, {2816, 0x2b0d}, {3072, 0x010e},
+	{3328, 0x2b0e}, {3584, 0x0132}, {3840, 0x010f}, {4096, 0x0133},
+	{4608, 0x0110}, {5120, 0x0111}, {6144, 0x0112}, {7168, 0x0136},
+	{7680, 0x0113}, {8192, 0x0137}, {9216, 0x0114}, {10240, 0x0115},
+	{12288, 0x0116}, {14336, 0x013a}, {15360, 0x0117}, {16384, 0x013b},
+	{18432, 0x0118}, {20480, 0x0119}, {24576, 0x011a}, {28672, 0x013e},
+	{30720, 0x011b}, {32768, 0x013f}, {36864, 0x011c}, {40960, 0x011d},
+	{49152, 0x011e}, {61440, 0x011f}
+};
+
+u32 mpc_i2c_get_sec_cfg_8xxx(void)
+{
+	struct device_node *node = NULL;
+	u32 __iomem *reg;
+	u32 val = 0;
+
+	node = of_find_node_by_name(NULL, "global-utilities");
+	if (node) {
+		const u32 *prop = of_get_property(node, "reg", NULL);
+		if (prop) {
+			/*
+			 * Map and check POR Device Status Register 2
+			 * (PORDEVSR2) at 0xE0014
+			 */
+			reg = ioremap(get_immrbase() + *prop + 0x14, 0x4);
+			if (!reg)
+				printk(KERN_ERR
+				       "Error: couldn't map PORDEVSR2\n");
+			else
+				val = in_be32(reg) & 0x00000080; /* sec-cfg */
+			iounmap(reg);
+		}
+	}
+	if (node)
+		of_node_put(node);
+
+	return val;
+}
+
+int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
+{
+	const struct mpc_i2c_divider *div = NULL;
+	u32 divider;
+	int i;
+
+	if (!clock)
+		return -EINVAL;
+
+	/* Determine proper divider value */
+	if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
+		prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
+	if (!prescaler)
+		prescaler = 1;
+
+	divider = fsl_get_sys_freq() / clock / prescaler;
+
+	pr_debug("I2C: src_clock=%d clock=%d divider=%d\n",
+		 fsl_get_sys_freq(), clock, divider);
+
+	/*
+	 * We want to choose an FDR/DFSR that generates an I2C bus speed that
+	 * is equal to or lower than the requested speed.
+	 */
+	for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_8xxx); i++) {
+		div = &mpc_i2c_dividers_8xxx[i];
+		if (div->divider >= divider)
+			break;
+	}
+
+	return div ? (int)div->fdr : -EINVAL;
+}
+
+static void mpc_i2c_setclock_8xxx(struct device_node *node,
+				  struct mpc_i2c *i2c,
+				  u32 clock, u32 prescaler)
+{
+	int ret, fdr;
+
+	ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+	fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
+
+	writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
+	writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR);
+
+	if (ret >= 0)
+		dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
+			 clock, fdr >> 8, fdr & 0xff);
+}
+
+#else /* !CONFIG_FSL_SOC */
+static void mpc_i2c_setclock_8xxx(struct device_node *node,
+				  struct mpc_i2c *i2c,
+				  u32 clock, u32 prescaler)
+{
+}
+#endif /* CONFIG_FSL_SOC */
+
 static void mpc_i2c_start(struct mpc_i2c *i2c)
 {
 	/* Clear arbitration */
@@ -179,7 +359,7 @@ static void mpc_i2c_stop(struct mpc_i2c
 }
 
 static int mpc_write(struct mpc_i2c *i2c, int target,
-		     const u8 * data, int length, int restart)
+		     const u8 *data, int length, int restart)
 {
 	int i, result;
 	unsigned timeout = i2c->adap.timeout;
@@ -210,7 +390,7 @@ static int mpc_write(struct mpc_i2c *i2c
 }
 
 static int mpc_read(struct mpc_i2c *i2c, int target,
-		    u8 * data, int length, int restart)
+		    u8 *data, int length, int restart)
 {
 	unsigned timeout = i2c->adap.timeout;
 	int i, result;
@@ -267,12 +447,12 @@ static int mpc_xfer(struct i2c_adapter *
 	/* Allow bus up to 1s to become not busy */
 	while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
 		if (signal_pending(current)) {
-			pr_debug("I2C: Interrupted\n");
+			dev_dbg(i2c->dev, "Interrupted\n");
 			writeccr(i2c, 0);
 			return -EINTR;
 		}
 		if (time_after(jiffies, orig_jiffies + HZ)) {
-			pr_debug("I2C: timeout\n");
+			dev_dbg(i2c->dev, "timeout\n");
 			if (readb(i2c->base + MPC_I2C_SR) ==
 			    (CSR_MCF | CSR_MBB | CSR_RXAK))
 				mpc_i2c_fixup(i2c);
@@ -283,9 +463,10 @@ static int mpc_xfer(struct i2c_adapter *
 
 	for (i = 0; ret >= 0 && i < num; i++) {
 		pmsg = &msgs[i];
-		pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messages\n",
-			 pmsg->flags & I2C_M_RD ? "read" : "write",
-			 pmsg->len, pmsg->addr, i + 1, num);
+		dev_dbg(i2c->dev,
+			"Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+			pmsg->flags & I2C_M_RD ? "read" : "write",
+			pmsg->len, pmsg->addr, i + 1, num);
 		if (pmsg->flags & I2C_M_RD)
 			ret =
 			    mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
@@ -311,30 +492,29 @@ static struct i2c_adapter mpc_ops = {
 	.owner = THIS_MODULE,
 	.name = "MPC adapter",
 	.algo = &mpc_algo,
-	.timeout = 1,
+	.timeout = HZ,
 };
 
-static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
+static int __devinit fsl_i2c_probe(struct of_device *op,
+				   const struct of_device_id *match)
 {
-	int result = 0;
 	struct mpc_i2c *i2c;
+	const u32 *prop;
+	u32 clock = 0;
+	int result = 0;
+	int plen;
 
 	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
 	if (!i2c)
 		return -ENOMEM;
 
-	if (of_get_property(op->node, "dfsrr", NULL))
-		i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
-
-	if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") ||
-			of_device_is_compatible(op->node, "mpc5200-i2c"))
-		i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
+	i2c->dev = &op->dev; /* for debug and error output */
 
 	init_waitqueue_head(&i2c->queue);
 
 	i2c->base = of_iomap(op->node, 0);
 	if (!i2c->base) {
-		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
+		dev_err(i2c->dev, "failed to map controller\n");
 		result = -ENOMEM;
 		goto fail_map;
 	}
@@ -344,12 +524,27 @@ static int __devinit fsl_i2c_probe(struc
 		result = request_irq(i2c->irq, mpc_i2c_isr,
 				     IRQF_SHARED, "i2c-mpc", i2c);
 		if (result < 0) {
-			printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
+			dev_err(i2c->dev, "failed to attach interrupt\n");
 			goto fail_request;
 		}
 	}
-	
-	mpc_i2c_setclock(i2c);
+
+	if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
+		prop = of_get_property(op->node, "clock-frequency", &plen);
+		if (prop && plen == sizeof(u32))
+			clock = *prop;
+
+		if (match->data) {
+			struct mpc_i2c_match_data *data =
+				(struct mpc_i2c_match_data *)match->data;
+			data->setclock(op->node, i2c, clock, data->prescaler);
+		} else {
+			/* Backwards compatibility */
+			if (of_get_property(op->node, "dfsrr", NULL))
+				mpc_i2c_setclock_8xxx(op->node, i2c,
+						      clock, 0);
+		}
+	}
 
 	dev_set_drvdata(&op->dev, i2c);
 
@@ -359,7 +554,7 @@ static int __devinit fsl_i2c_probe(struc
 
 	result = i2c_add_adapter(&i2c->adap);
 	if (result < 0) {
-		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
+		dev_err(i2c->dev, "failed to add adapter\n");
 		goto fail_add;
 	}
 	of_register_i2c_devices(&i2c->adap, op->node);
@@ -371,7 +566,7 @@ static int __devinit fsl_i2c_probe(struc
 	free_irq(i2c->irq, i2c);
  fail_request:
 	irq_dispose_mapping(i2c->irq);
- 	iounmap(i2c->base);
+	iounmap(i2c->base);
  fail_map:
 	kfree(i2c);
 	return result;
@@ -394,9 +589,43 @@ static int __devexit fsl_i2c_remove(stru
 };
 
 static const struct of_device_id mpc_i2c_of_match[] = {
-	{.compatible = "fsl-i2c",},
+	{.compatible = "mpc5200-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_52xx,
+		},
+	},
+	{.compatible = "fsl,mpc5200b-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_52xx,
+		},
+	},
+	{.compatible = "fsl,mpc5200-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_52xx,
+		},
+	},
+	{.compatible = "fsl,mpc8313-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_8xxx,
+		},
+	},
+	{.compatible = "fsl,mpc8543-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_8xxx,
+			.prescaler = 2,
+		},
+	},
+	{.compatible = "fsl,mpc8544-i2c",
+	 .data = &(struct mpc_i2c_match_data) {
+			.setclock = mpc_i2c_setclock_8xxx,
+			.prescaler = 3,
+		},
+	/* Backward compatibility */
+	},
+	{.compatible = "fsl-i2c", },
 	{},
 };
+
 MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
 
 
@@ -417,7 +646,7 @@ static int __init fsl_i2c_init(void)
 
 	rv = of_register_platform_driver(&mpc_i2c_driver);
 	if (rv)
-		printk(KERN_ERR DRV_NAME 
+		printk(KERN_ERR DRV_NAME
 		       " of_register_platform_driver failed (%i)\n", rv);
 	return rv;
 }
@@ -431,6 +660,6 @@ module_init(fsl_i2c_init);
 module_exit(fsl_i2c_exit);
 
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
-MODULE_DESCRIPTION
-    ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
+MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
+		   "MPC824x/85xx/52xx processors");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-mv64xxx.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-mv64xxx.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-mv64xxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct m
 	char		abort = 0;
 
 	time_left = wait_event_interruptible_timeout(drv_data->waitq,
-		!drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout));
+		!drv_data->block, drv_data->adapter.timeout);
 
 	spin_lock_irqsave(&drv_data->lock, flags);
 	if (!time_left) { /* Timed out */
@@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct m
 		spin_unlock_irqrestore(&drv_data->lock, flags);
 
 		time_left = wait_event_timeout(drv_data->waitq,
-			!drv_data->block,
-			msecs_to_jiffies(drv_data->adapter.timeout));
+			!drv_data->block, drv_data->adapter.timeout);
 
 		if ((time_left <= 0) && drv_data->block) {
 			drv_data->state = MV64XXX_I2C_STATE_IDLE;
@@ -530,7 +529,7 @@ mv64xxx_i2c_probe(struct platform_device
 	drv_data->adapter.algo = &mv64xxx_i2c_algo;
 	drv_data->adapter.owner = THIS_MODULE;
 	drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-	drv_data->adapter.timeout = pdata->timeout;
+	drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
 	drv_data->adapter.nr = pd->id;
 	platform_set_drvdata(pd, drv_data);
 	i2c_set_adapdata(&drv_data->adapter, drv_data);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-nforce2.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-nforce2.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-nforce2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-nforce2.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,10 +31,14 @@
     nForce3 250Gb MCP		00E4
     nForce4 MCP			0052
     nForce4 MCP-04		0034
-    nForce4 MCP51		0264
-    nForce4 MCP55		0368
+    nForce MCP51		0264
+    nForce MCP55		0368
     nForce MCP61		03EB
     nForce MCP65		0446
+    nForce MCP67		0542
+    nForce MCP73		07D8
+    nForce MCP78S		0752
+    nForce MCP79		0AA2
 
     This driver supports the 2 SMBuses that are included in the MCP of the
     nForce2/3/4/5xx chipsets.
@@ -169,7 +173,7 @@ static int nforce2_check_status(struct i
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while ((!temp) && (timeout++ < MAX_TIMEOUT));
 
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_dbg(&adap->dev, "SMBus Timeout!\n");
 		if (smbus->can_abort)
 			nforce2_abort(adap);
@@ -315,6 +319,10 @@ static struct pci_device_id nforce2_ids[
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
 	{ 0 }
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-omap.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-omap.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-omap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-omap.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,22 +193,24 @@ static inline u16 omap_i2c_read_reg(stru
 
 static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
 {
-	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-		dev->iclk = clk_get(dev->dev, "i2c_ick");
-		if (IS_ERR(dev->iclk)) {
-			dev->iclk = NULL;
-			return -ENODEV;
-		}
+	int ret;
+
+	dev->iclk = clk_get(dev->dev, "ick");
+	if (IS_ERR(dev->iclk)) {
+		ret = PTR_ERR(dev->iclk);
+		dev->iclk = NULL;
+		return ret;
 	}
 
-	dev->fclk = clk_get(dev->dev, "i2c_fck");
+	dev->fclk = clk_get(dev->dev, "fck");
 	if (IS_ERR(dev->fclk)) {
+		ret = PTR_ERR(dev->fclk);
 		if (dev->iclk != NULL) {
 			clk_put(dev->iclk);
 			dev->iclk = NULL;
 		}
 		dev->fclk = NULL;
-		return -ENODEV;
+		return ret;
 	}
 
 	return 0;
@@ -218,18 +220,15 @@ static void omap_i2c_put_clocks(struct o
 {
 	clk_put(dev->fclk);
 	dev->fclk = NULL;
-	if (dev->iclk != NULL) {
-		clk_put(dev->iclk);
-		dev->iclk = NULL;
-	}
+	clk_put(dev->iclk);
+	dev->iclk = NULL;
 }
 
 static void omap_i2c_unidle(struct omap_i2c_dev *dev)
 {
 	WARN_ON(!dev->idle);
 
-	if (dev->iclk != NULL)
-		clk_enable(dev->iclk);
+	clk_enable(dev->iclk);
 	clk_enable(dev->fclk);
 	dev->idle = 0;
 	if (dev->iestate)
@@ -254,8 +253,7 @@ static void omap_i2c_idle(struct omap_i2
 	}
 	dev->idle = 1;
 	clk_disable(dev->fclk);
-	if (dev->iclk != NULL)
-		clk_disable(dev->iclk);
+	clk_disable(dev->iclk);
 }
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -312,15 +310,14 @@ static int omap_i2c_init(struct omap_i2c
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 
 	if (cpu_class_is_omap1()) {
-		struct clk *armxor_ck;
+		/*
+		 * The I2C functional clock is the armxor_ck, so there's
+		 * no need to get "armxor_ck" separately.  Now, if OMAP2420
+		 * always returns 12MHz for the functional clock, we can
+		 * do this bit unconditionally.
+		 */
+		fclk_rate = clk_get_rate(dev->fclk);
 
-		armxor_ck = clk_get(NULL, "armxor_ck");
-		if (IS_ERR(armxor_ck))
-			dev_warn(dev->dev, "Could not get armxor_ck\n");
-		else {
-			fclk_rate = clk_get_rate(armxor_ck);
-			clk_put(armxor_ck);
-		}
 		/* TRM for 5912 says the I2C clock must be prescaled to be
 		 * between 7 - 12 MHz. The XOR input clock is typically
 		 * 12, 13 or 19.2 MHz. So we should have code that produces:
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pca-isa.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pca-isa.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pca-isa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pca-isa.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
@@ -41,15 +42,17 @@ static int irq = -1;
 
 /* Data sheet recommends 59kHz for 100kHz operation due to variation
  * in the actual clock rate */
-static int clock  = I2C_PCA_CON_59kHz;
+static int clock  = 59000;
 
+static struct i2c_adapter pca_isa_ops;
 static wait_queue_head_t pca_wait;
 
 static void pca_isa_writebyte(void *pd, int reg, int val)
 {
 #ifdef DEBUG_IO
 	static char *names[] = { "T/O", "DAT", "ADR", "CON" };
-	printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val);
+	printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg],
+	       base+reg, val);
 #endif
 	outb(val, base+reg);
 }
@@ -60,7 +63,7 @@ static int pca_isa_readbyte(void *pd, in
 #ifdef DEBUG_IO
 	{
 		static char *names[] = { "STA", "DAT", "ADR", "CON" };
-		printk("*** read  %s => %#04x\n", names[reg], res);
+		printk(KERN_DEBUG "*** read  %s => %#04x\n", names[reg], res);
 	}
 #endif
 	return res;
@@ -68,16 +71,22 @@ static int pca_isa_readbyte(void *pd, in
 
 static int pca_isa_waitforcompletion(void *pd)
 {
-	int ret = 0;
+	long ret = ~0;
+	unsigned long timeout;
 
 	if (irq > -1) {
-		ret = wait_event_interruptible(pca_wait,
-					       pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
+		ret = wait_event_interruptible_timeout(pca_wait,
+				pca_isa_readbyte(pd, I2C_PCA_CON)
+				& I2C_PCA_CON_SI, pca_isa_ops.timeout);
 	} else {
-		while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+		/* Do polling */
+		timeout = jiffies + pca_isa_ops.timeout;
+		while (((pca_isa_readbyte(pd, I2C_PCA_CON)
+				& I2C_PCA_CON_SI) == 0)
+				&& (ret = time_before(jiffies, timeout)))
 			udelay(100);
 	}
-	return ret;
+	return ret > 0;
 }
 
 static void pca_isa_resetchip(void *pd)
@@ -102,8 +111,8 @@ static struct i2c_algo_pca_data pca_isa_
 static struct i2c_adapter pca_isa_ops = {
 	.owner          = THIS_MODULE,
 	.algo_data	= &pca_isa_data,
-	.name		= "PCA9564 ISA Adapter",
-	.timeout	= 100,
+	.name		= "PCA9564/PCA9665 ISA Adapter",
+	.timeout	= HZ,
 };
 
 static int __devinit pca_isa_match(struct device *dev, unsigned int id)
@@ -195,7 +204,7 @@ static void __exit pca_isa_exit(void)
 }
 
 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
-MODULE_DESCRIPTION("ISA base PCA9564 driver");
+MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver");
 MODULE_LICENSE("GPL");
 
 module_param(base, ulong, 0);
@@ -204,7 +213,13 @@ MODULE_PARM_DESC(base, "I/O base address
 module_param(irq, int, 0);
 MODULE_PARM_DESC(irq, "IRQ");
 module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
+MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
+		"For PCA9564: 330000,288000,217000,146000,"
+		"88000,59000,44000,36000\n"
+		"\t\tFor PCA9665:\tStandard: 60300 - 100099\n"
+		"\t\t\t\tFast: 100100 - 400099\n"
+		"\t\t\t\tFast+: 400100 - 10000099\n"
+		"\t\t\t\tTurbo: Up to 1265800");
 
 module_init(pca_isa_init);
 module_exit(pca_isa_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pca-platform.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pca-platform.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pca-platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pca-platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
@@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void
 static int i2c_pca_pf_waitforcompletion(void *pd)
 {
 	struct i2c_pca_pf_data *i2c = pd;
-	int ret = 0;
+	long ret = ~0;
+	unsigned long timeout;
 
 	if (i2c->irq) {
-		ret = wait_event_interruptible(i2c->wait,
+		ret = wait_event_interruptible_timeout(i2c->wait,
 			i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
-			& I2C_PCA_CON_SI);
+			& I2C_PCA_CON_SI, i2c->adap.timeout);
 	} else {
-		/*
-		 * Do polling...
-		 * XXX: Could get stuck in extreme cases!
-		 *      Maybe add timeout, but using irqs is preferred anyhow.
-		 */
-		while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+		/* Do polling */
+		timeout = jiffies + i2c->adap.timeout;
+		while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
 				& I2C_PCA_CON_SI) == 0)
+				&& (ret = time_before(jiffies, timeout)))
 			udelay(100);
 	}
 
-	return ret;
+	return ret > 0;
 }
 
 static void i2c_pca_pf_dummyreset(void *pd)
@@ -172,14 +172,25 @@ static int __devinit i2c_pca_pf_probe(st
 
 	i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
 	i2c->adap.owner = THIS_MODULE;
-	snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
-		(unsigned long) res->start);
+	snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+		 "PCA9564/PCA9665 at 0x%08lx",
+		 (unsigned long) res->start);
 	i2c->adap.algo_data = &i2c->algo_data;
 	i2c->adap.dev.parent = &pdev->dev;
-	i2c->adap.timeout = platform_data->timeout;
 
-	i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+	if (platform_data) {
+		i2c->adap.timeout = platform_data->timeout;
+		i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+		i2c->gpio = platform_data->gpio;
+	} else {
+		i2c->adap.timeout = HZ;
+		i2c->algo_data.i2c_clock = 59000;
+		i2c->gpio = -1;
+	}
+
 	i2c->algo_data.data = i2c;
+	i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
+	i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
 
 	switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
 	case IORESOURCE_MEM_32BIT:
@@ -197,11 +208,6 @@ static int __devinit i2c_pca_pf_probe(st
 		break;
 	}
 
-	i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
-
-	i2c->gpio = platform_data->gpio;
-	i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
-
 	/* Use gpio_is_valid() when in mainline */
 	if (i2c->gpio > -1) {
 		ret = gpio_request(i2c->gpio, i2c->adap.name);
@@ -246,7 +252,7 @@ e_remap:
 e_alloc:
 	release_mem_region(res->start, res_len(res));
 e_print:
-	printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+	printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
 	return ret;
 }
 
@@ -290,7 +296,7 @@ static void __exit i2c_pca_pf_exit(void)
 }
 
 MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
 MODULE_LICENSE("GPL");
 
 module_init(i2c_pca_pf_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-piix4.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-piix4.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-piix4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-piix4.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@
 /*
    Supports:
 	Intel PIIX4, 440MX
-	Serverworks OSB4, CSB5, CSB6, HT-1000
+	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
 	ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
 	SMSC Victory66
 
@@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct
 	return 0;
 }
 
+static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
+				const struct pci_device_id *id)
+{
+	unsigned short smba_idx = 0xcd6;
+	u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
+
+	/* SB800 SMBus does not support forcing address */
+	if (force || force_addr) {
+		dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
+			"forcing address!\n");
+		return -EINVAL;
+	}
+
+	/* Determine the address of the SMBus areas */
+	if (!request_region(smba_idx, 2, "smba_idx")) {
+		dev_err(&PIIX4_dev->dev, "SMBus base address index region "
+			"0x%x already in use!\n", smba_idx);
+		return -EBUSY;
+	}
+	outb_p(smb_en, smba_idx);
+	smba_en_lo = inb_p(smba_idx + 1);
+	outb_p(smb_en + 1, smba_idx);
+	smba_en_hi = inb_p(smba_idx + 1);
+	release_region(smba_idx, 2);
+
+	if ((smba_en_lo & 1) == 0) {
+		dev_err(&PIIX4_dev->dev,
+			"Host SMBus controller not enabled!\n");
+		return -ENODEV;
+	}
+
+	piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
+		return -EBUSY;
+
+	if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+		dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
+			piix4_smba);
+		return -EBUSY;
+	}
+
+	/* Request the SMBus I2C bus config region */
+	if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
+		dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
+			"0x%x already in use!\n", piix4_smba + i2ccfg_offset);
+		release_region(piix4_smba, SMBIOSIZE);
+		piix4_smba = 0;
+		return -EBUSY;
+	}
+	i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
+	release_region(piix4_smba + i2ccfg_offset, 1);
+
+	if (i2ccfg & 1)
+		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
+	else
+		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
+
+	dev_info(&PIIX4_dev->dev,
+		 "SMBus Host Controller at 0x%x, revision %d\n",
+		 piix4_smba, i2ccfg >> 4);
+
+	return 0;
+}
+
 static int piix4_transaction(void)
 {
 	int temp;
@@ -423,6 +487,8 @@ static struct pci_device_id piix4_ids[]
 		     PCI_DEVICE_ID_SERVERWORKS_CSB6) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
 		     PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
+		     PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
 	{ 0, }
 };
 
@@ -433,7 +499,14 @@ static int __devinit piix4_probe(struct
 {
 	int retval;
 
-	retval = piix4_setup(dev, id);
+	if ((dev->vendor == PCI_VENDOR_ID_ATI) &&
+	    (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) &&
+	    (dev->revision >= 0x40))
+		/* base address location etc changed in SB800 */
+		retval = piix4_setup_sb800(dev, id);
+	else
+		retval = piix4_setup(dev, id);
+
 	if (retval)
 		return retval;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-powermac.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-powermac.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-powermac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-powermac.c	2009-06-09 23:05:27.000000000 -0400
@@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove
 	i2c_set_adapdata(adapter, NULL);
 	/* We aren't that prepared to deal with this... */
 	if (rc)
-		printk("i2c-powermac.c: Failed to remove bus %s !\n",
+		printk(KERN_WARNING
+		       "i2c-powermac.c: Failed to remove bus %s !\n",
 		       adapter->name);
 	platform_set_drvdata(dev, NULL);
 	kfree(adapter);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pxa.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pxa.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-pxa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-pxa.c	2009-06-09 23:05:27.000000000 -0400
@@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int t
 static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
 {
 	unsigned int i;
-	printk("i2c: error: %s\n", why);
-	printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+	printk(KERN_ERR "i2c: error: %s\n", why);
+	printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
 		i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
-	printk("i2c: ICR: %08x ISR: %08x\n"
-	       "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
+	printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n",
+	       readl(_ICR(i2c)), readl(_ISR(i2c)));
+	printk(KERN_DEBUG "i2c: log: ");
 	for (i = 0; i < i2c->irqlogidx; i++)
 		printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
 	printk("\n");
@@ -264,10 +265,10 @@ static int i2c_pxa_wait_bus_not_busy(str
 		show_state(i2c);
 	}
 
-	if (timeout <= 0)
+	if (timeout < 0)
 		show_state(i2c);
 
-	return timeout <= 0 ? I2C_RETRY : 0;
+	return timeout < 0 ? I2C_RETRY : 0;
 }
 
 static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
@@ -611,7 +612,7 @@ static int i2c_pxa_pio_set_master(struct
 		show_state(i2c);
 	}
 
-	if (timeout <= 0) {
+	if (timeout < 0) {
 		show_state(i2c);
 		dev_err(&i2c->adap.dev,
 			"i2c_pxa: timeout waiting for bus free\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s3c2410.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s3c2410.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s3c2410.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /* linux/drivers/i2c/busses/i2c-s3c2410.c
  *
- * Copyright (C) 2004,2005 Simtec Electronics
+ * Copyright (C) 2004,2005,2009 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 I2C Controller
@@ -590,18 +590,6 @@ static int s3c24xx_i2c_calcdivisor(unsig
 	return clkin / (calc_divs * calc_div1);
 }
 
-/* freq_acceptable
- *
- * test wether a frequency is within the acceptable range of error
-*/
-
-static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
-{
-	int diff = freq - wanted;
-
-	return diff >= -2 && diff <= 2;
-}
-
 /* s3c24xx_i2c_clockrate
  *
  * work out a divisor for the user requested frequency setting,
@@ -614,44 +602,28 @@ static int s3c24xx_i2c_clockrate(struct
 	struct s3c2410_platform_i2c *pdata = i2c->dev->platform_data;
 	unsigned long clkin = clk_get_rate(i2c->clk);
 	unsigned int divs, div1;
+	unsigned long target_frequency;
 	u32 iiccon;
 	int freq;
-	int start, end;
 
 	i2c->clkrate = clkin;
 	clkin /= 1000;		/* clkin now in KHz */
 
-	dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
-		 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
-
-	if (pdata->bus_freq != 0) {
-		freq = s3c24xx_i2c_calcdivisor(clkin, pdata->bus_freq/1000,
-					       &div1, &divs);
-		if (freq_acceptable(freq, pdata->bus_freq/1000))
-			goto found;
-	}
-
-	/* ok, we may have to search for something suitable... */
+	dev_dbg(i2c->dev, "pdata desired frequency %lu\n", pdata->frequency);
 
-	start = (pdata->max_freq == 0) ? pdata->bus_freq : pdata->max_freq;
-	end = pdata->min_freq;
+	target_frequency = pdata->frequency ? pdata->frequency : 100000;
 
-	start /= 1000;
-	end /= 1000;
+	target_frequency /= 1000; /* Target frequency now in KHz */
 
-	/* search loop... */
+	freq = s3c24xx_i2c_calcdivisor(clkin, target_frequency, &div1, &divs);
 
-	for (; start > end; start--) {
-		freq = s3c24xx_i2c_calcdivisor(clkin, start, &div1, &divs);
-		if (freq_acceptable(freq, start))
-			goto found;
+	if (freq > target_frequency) {
+		dev_err(i2c->dev,
+			"Unable to achieve desired frequency %luKHz."	\
+			" Lowest achievable %dKHz\n", target_frequency, freq);
+		return -EINVAL;
 	}
 
-	/* cannot find frequency spec */
-
-	return -EINVAL;
-
- found:
 	*got = freq;
 
 	iiccon = readl(i2c->regs + S3C2410_IICCON);
@@ -663,6 +635,23 @@ static int s3c24xx_i2c_clockrate(struct
 
 	writel(iiccon, i2c->regs + S3C2410_IICCON);
 
+	if (s3c24xx_i2c_is2440(i2c)) {
+		unsigned long sda_delay;
+
+		if (pdata->sda_delay) {
+			sda_delay = (freq / 1000) * pdata->sda_delay;
+			sda_delay /= 1000000;
+			sda_delay = DIV_ROUND_UP(sda_delay, 5);
+			if (sda_delay > 3)
+				sda_delay = 3;
+			sda_delay |= S3C2410_IICLC_FILTER_ON;
+		} else
+			sda_delay = 0;
+
+		dev_dbg(i2c->dev, "IICLC=%08lx\n", sda_delay);
+		writel(sda_delay, i2c->regs + S3C2440_IICLC);
+	}
+
 	return 0;
 }
 
@@ -769,11 +758,8 @@ static int s3c24xx_i2c_init(struct s3c24
 
 	/* check for s3c2440 i2c controller  */
 
-	if (s3c24xx_i2c_is2440(i2c)) {
-		dev_dbg(i2c->dev, "S3C2440_IICLC=%08x\n", pdata->sda_delay);
-
-		writel(pdata->sda_delay, i2c->regs + S3C2440_IICLC);
-	}
+	if (s3c24xx_i2c_is2440(i2c))
+		writel(0x0, i2c->regs + S3C2440_IICLC);
 
 	return 0;
 }
@@ -1018,14 +1004,13 @@ static int __init i2c_adap_s3c_init(void
 
 	return ret;
 }
+subsys_initcall(i2c_adap_s3c_init);
 
 static void __exit i2c_adap_s3c_exit(void)
 {
 	platform_driver_unregister(&s3c2410_i2c_driver);
 	platform_driver_unregister(&s3c2440_i2c_driver);
 }
-
-module_init(i2c_adap_s3c_init);
 module_exit(i2c_adap_s3c_exit);
 
 MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s6000.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s6000.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s6000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s6000.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,407 @@
+/*
+ * drivers/i2c/busses/i2c-s6000.c
+ *
+ * Description: Driver for S6000 Family I2C Interface
+ * Copyright (c) 2008 emlix GmbH
+ * Author:	Oskar Schirmer <os@emlix.com>
+ *
+ * Partially based on i2c-bfin-twi.c driver by <sonic.zhang@analog.com>
+ * Copyright (c) 2005-2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/s6000.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include "i2c-s6000.h"
+
+#define DRV_NAME "i2c-s6000"
+
+#define POLL_TIMEOUT	(2 * HZ)
+
+struct s6i2c_if {
+	u8 __iomem		*reg; /* memory mapped registers */
+	int			irq;
+	spinlock_t		lock;
+	struct i2c_msg		*msgs; /* messages currently handled */
+	int			msgs_num; /* nb of msgs to do */
+	int			msgs_push; /* nb of msgs read/written */
+	int			msgs_done; /* nb of msgs finally handled */
+	unsigned		push; /* nb of bytes read/written in msg */
+	unsigned		done; /* nb of bytes finally handled */
+	int			timeout_count; /* timeout retries left */
+	struct timer_list	timeout_timer;
+	struct i2c_adapter	adap;
+	struct completion	complete;
+	struct clk		*clk;
+	struct resource		*res;
+};
+
+static inline u16 i2c_rd16(struct s6i2c_if *iface, unsigned n)
+{
+	return readw(iface->reg + (n));
+}
+
+static inline void i2c_wr16(struct s6i2c_if *iface, unsigned n, u16 v)
+{
+	writew(v, iface->reg + (n));
+}
+
+static inline u32 i2c_rd32(struct s6i2c_if *iface, unsigned n)
+{
+	return readl(iface->reg + (n));
+}
+
+static inline void i2c_wr32(struct s6i2c_if *iface, unsigned n, u32 v)
+{
+	writel(v, iface->reg + (n));
+}
+
+static struct s6i2c_if s6i2c_if;
+
+static void s6i2c_handle_interrupt(struct s6i2c_if *iface)
+{
+	if (i2c_rd16(iface, S6_I2C_INTRSTAT) & (1 << S6_I2C_INTR_TXABRT)) {
+		i2c_rd16(iface, S6_I2C_CLRTXABRT);
+		i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+		complete(&iface->complete);
+		return;
+	}
+	if (iface->msgs_done >= iface->msgs_num) {
+		dev_err(&iface->adap.dev, "s6i2c: spurious I2C irq: %04x\n",
+			i2c_rd16(iface, S6_I2C_INTRSTAT));
+		i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+		return;
+	}
+	while ((iface->msgs_push < iface->msgs_num)
+	    && (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_TFNF))) {
+		struct i2c_msg *m = &iface->msgs[iface->msgs_push];
+		if (!(m->flags & I2C_M_RD))
+			i2c_wr16(iface, S6_I2C_DATACMD, m->buf[iface->push]);
+		else
+			i2c_wr16(iface, S6_I2C_DATACMD,
+				 1 << S6_I2C_DATACMD_READ);
+		if (++iface->push >= m->len) {
+			iface->push = 0;
+			iface->msgs_push += 1;
+		}
+	}
+	do {
+		struct i2c_msg *m = &iface->msgs[iface->msgs_done];
+		if (!(m->flags & I2C_M_RD)) {
+			if (iface->msgs_done < iface->msgs_push)
+				iface->msgs_done += 1;
+			else
+				break;
+		} else if (i2c_rd16(iface, S6_I2C_STATUS)
+				& (1 << S6_I2C_STATUS_RFNE)) {
+			m->buf[iface->done] = i2c_rd16(iface, S6_I2C_DATACMD);
+			if (++iface->done >= m->len) {
+				iface->done = 0;
+				iface->msgs_done += 1;
+			}
+		} else{
+			break;
+		}
+	} while (iface->msgs_done < iface->msgs_num);
+	if (iface->msgs_done >= iface->msgs_num) {
+		i2c_wr16(iface, S6_I2C_INTRMASK, 1 << S6_I2C_INTR_TXABRT);
+		complete(&iface->complete);
+	} else if (iface->msgs_push >= iface->msgs_num) {
+		i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
+						 (1 << S6_I2C_INTR_RXFULL));
+	} else {
+		i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXABRT) |
+						 (1 << S6_I2C_INTR_TXEMPTY) |
+						 (1 << S6_I2C_INTR_RXFULL));
+	}
+}
+
+static irqreturn_t s6i2c_interrupt_entry(int irq, void *dev_id)
+{
+	struct s6i2c_if *iface = dev_id;
+	if (!(i2c_rd16(iface, S6_I2C_STATUS) & ((1 << S6_I2C_INTR_RXUNDER)
+					      | (1 << S6_I2C_INTR_RXOVER)
+					      | (1 << S6_I2C_INTR_RXFULL)
+					      | (1 << S6_I2C_INTR_TXOVER)
+					      | (1 << S6_I2C_INTR_TXEMPTY)
+					      | (1 << S6_I2C_INTR_RDREQ)
+					      | (1 << S6_I2C_INTR_TXABRT)
+					      | (1 << S6_I2C_INTR_RXDONE)
+					      | (1 << S6_I2C_INTR_ACTIVITY)
+					      | (1 << S6_I2C_INTR_STOPDET)
+					      | (1 << S6_I2C_INTR_STARTDET)
+					      | (1 << S6_I2C_INTR_GENCALL))))
+		return IRQ_NONE;
+
+	spin_lock(&iface->lock);
+	del_timer(&iface->timeout_timer);
+	s6i2c_handle_interrupt(iface);
+	spin_unlock(&iface->lock);
+	return IRQ_HANDLED;
+}
+
+static void s6i2c_timeout(unsigned long data)
+{
+	struct s6i2c_if *iface = (struct s6i2c_if *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iface->lock, flags);
+	s6i2c_handle_interrupt(iface);
+	if (--iface->timeout_count > 0) {
+		iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+		add_timer(&iface->timeout_timer);
+	} else {
+		complete(&iface->complete);
+		i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+	}
+	spin_unlock_irqrestore(&iface->lock, flags);
+}
+
+static int s6i2c_master_xfer(struct i2c_adapter *adap,
+				struct i2c_msg *msgs, int num)
+{
+	struct s6i2c_if *iface = adap->algo_data;
+	int i;
+	if (num == 0)
+		return 0;
+	if (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
+		yield();
+	i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+	i2c_rd16(iface, S6_I2C_CLRINTR);
+	for (i = 0; i < num; i++) {
+		if (msgs[i].flags & I2C_M_TEN) {
+			dev_err(&adap->dev,
+				"s6i2c: 10 bits addr not supported\n");
+			return -EINVAL;
+		}
+		if (msgs[i].len == 0) {
+			dev_err(&adap->dev,
+				"s6i2c: zero length message not supported\n");
+			return -EINVAL;
+		}
+		if (msgs[i].addr != msgs[0].addr) {
+			dev_err(&adap->dev,
+				"s6i2c: multiple xfer cannot change target\n");
+			return -EINVAL;
+		}
+	}
+
+	iface->msgs = msgs;
+	iface->msgs_num = num;
+	iface->msgs_push = 0;
+	iface->msgs_done = 0;
+	iface->push = 0;
+	iface->done = 0;
+	iface->timeout_count = 10;
+	i2c_wr16(iface, S6_I2C_TAR, msgs[0].addr);
+	i2c_wr16(iface, S6_I2C_ENABLE, 1);
+	i2c_wr16(iface, S6_I2C_INTRMASK, (1 << S6_I2C_INTR_TXEMPTY) |
+					 (1 << S6_I2C_INTR_TXABRT));
+
+	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+	add_timer(&iface->timeout_timer);
+	wait_for_completion(&iface->complete);
+	del_timer_sync(&iface->timeout_timer);
+	while (i2c_rd32(iface, S6_I2C_TXFLR) > 0)
+		schedule();
+	while (i2c_rd16(iface, S6_I2C_STATUS) & (1 << S6_I2C_STATUS_ACTIVITY))
+		schedule();
+
+	i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+	i2c_wr16(iface, S6_I2C_ENABLE, 0);
+	return iface->msgs_done;
+}
+
+static u32 s6i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm s6i2c_algorithm = {
+	.master_xfer   = s6i2c_master_xfer,
+	.functionality = s6i2c_functionality,
+};
+
+static u16 __devinit nanoseconds_on_clk(struct s6i2c_if *iface, u32 ns)
+{
+	u32 dividend = ((clk_get_rate(iface->clk) / 1000) * ns) / 1000000;
+	if (dividend > 0xffff)
+		return 0xffff;
+	return dividend;
+}
+
+static int __devinit s6i2c_probe(struct platform_device *dev)
+{
+	struct s6i2c_if *iface = &s6i2c_if;
+	struct i2c_adapter *p_adap;
+	const char *clock;
+	int bus_num, rc;
+	spin_lock_init(&iface->lock);
+	init_completion(&iface->complete);
+	iface->irq = platform_get_irq(dev, 0);
+	if (iface->irq < 0) {
+		rc = iface->irq;
+		goto err_out;
+	}
+	iface->res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!iface->res) {
+		rc = -ENXIO;
+		goto err_out;
+	}
+	iface->res = request_mem_region(iface->res->start,
+					resource_size(iface->res),
+					dev->dev.bus_id);
+	if (!iface->res) {
+		rc = -EBUSY;
+		goto err_out;
+	}
+	iface->reg = ioremap_nocache(iface->res->start,
+				     resource_size(iface->res));
+	if (!iface->reg) {
+		rc = -ENOMEM;
+		goto err_reg;
+	}
+
+	clock = 0;
+	bus_num = -1;
+	if (dev->dev.platform_data) {
+		struct s6_i2c_platform_data *pdata = dev->dev.platform_data;
+		bus_num = pdata->bus_num;
+		clock = pdata->clock;
+	}
+	iface->clk = clk_get(&dev->dev, clock);
+	if (IS_ERR(iface->clk)) {
+		rc = PTR_ERR(iface->clk);
+		goto err_map;
+	}
+	rc = clk_enable(iface->clk);
+	if (rc < 0)
+		goto err_clk_put;
+	init_timer(&iface->timeout_timer);
+	iface->timeout_timer.function = s6i2c_timeout;
+	iface->timeout_timer.data = (unsigned long)iface;
+
+	p_adap = &iface->adap;
+	strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+	p_adap->algo = &s6i2c_algorithm;
+	p_adap->algo_data = iface;
+	p_adap->nr = bus_num;
+	p_adap->class = 0;
+	p_adap->dev.parent = &dev->dev;
+	i2c_wr16(iface, S6_I2C_INTRMASK, 0);
+	rc = request_irq(iface->irq, s6i2c_interrupt_entry,
+			 IRQF_SHARED, dev->name, iface);
+	if (rc) {
+		dev_err(&p_adap->dev, "s6i2c: cant get IRQ %d\n", iface->irq);
+		goto err_clk_dis;
+	}
+
+	i2c_wr16(iface, S6_I2C_ENABLE, 0);
+	udelay(1);
+	i2c_wr32(iface, S6_I2C_SRESET, 1 << S6_I2C_SRESET_IC_SRST);
+	i2c_wr16(iface, S6_I2C_CLRTXABRT, 1);
+	i2c_wr16(iface, S6_I2C_CON,
+			(1 << S6_I2C_CON_MASTER) |
+			(S6_I2C_CON_SPEED_NORMAL << S6_I2C_CON_SPEED) |
+			(0 << S6_I2C_CON_10BITSLAVE) |
+			(0 << S6_I2C_CON_10BITMASTER) |
+			(1 << S6_I2C_CON_RESTARTENA) |
+			(1 << S6_I2C_CON_SLAVEDISABLE));
+	i2c_wr16(iface, S6_I2C_SSHCNT, nanoseconds_on_clk(iface, 4000));
+	i2c_wr16(iface, S6_I2C_SSLCNT, nanoseconds_on_clk(iface, 4700));
+	i2c_wr16(iface, S6_I2C_FSHCNT, nanoseconds_on_clk(iface, 600));
+	i2c_wr16(iface, S6_I2C_FSLCNT, nanoseconds_on_clk(iface, 1300));
+	i2c_wr16(iface, S6_I2C_RXTL, 0);
+	i2c_wr16(iface, S6_I2C_TXTL, 0);
+
+	platform_set_drvdata(dev, iface);
+	if (bus_num < 0)
+		rc = i2c_add_adapter(p_adap);
+	else
+		rc = i2c_add_numbered_adapter(p_adap);
+	if (rc)
+		goto err_irq_free;
+	return 0;
+
+err_irq_free:
+	free_irq(iface->irq, iface);
+err_clk_dis:
+	clk_disable(iface->clk);
+err_clk_put:
+	clk_put(iface->clk);
+err_map:
+	iounmap(iface->reg);
+err_reg:
+	release_mem_region(iface->res->start,
+			   resource_size(iface->res));
+err_out:
+	return rc;
+}
+
+static int __devexit s6i2c_remove(struct platform_device *pdev)
+{
+	struct s6i2c_if *iface = platform_get_drvdata(pdev);
+	i2c_wr16(iface, S6_I2C_ENABLE, 0);
+	platform_set_drvdata(pdev, NULL);
+	i2c_del_adapter(&iface->adap);
+	free_irq(iface->irq, iface);
+	clk_disable(iface->clk);
+	clk_put(iface->clk);
+	iounmap(iface->reg);
+	release_mem_region(iface->res->start,
+			   resource_size(iface->res));
+	return 0;
+}
+
+static struct platform_driver s6i2c_driver = {
+	.probe		= s6i2c_probe,
+	.remove		= __devexit_p(s6i2c_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init s6i2c_init(void)
+{
+	pr_info("I2C: S6000 I2C driver\n");
+	return platform_driver_register(&s6i2c_driver);
+}
+
+static void __exit s6i2c_exit(void)
+{
+	platform_driver_unregister(&s6i2c_driver);
+}
+
+MODULE_DESCRIPTION("I2C-Bus adapter routines for S6000 I2C");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+
+subsys_initcall(s6i2c_init);
+module_exit(s6i2c_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s6000.h linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s6000.h
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-s6000.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-s6000.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,79 @@
+/*
+ * drivers/i2c/busses/i2c-s6000.h
+ *
+ * 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) 2008 Emlix GmbH <info@emlix.com>
+ * Author:	Oskar Schirmer <os@emlix.com>
+ */
+
+#ifndef __DRIVERS_I2C_BUSSES_I2C_S6000_H
+#define __DRIVERS_I2C_BUSSES_I2C_S6000_H
+
+#define S6_I2C_CON		0x000
+#define S6_I2C_CON_MASTER		0
+#define S6_I2C_CON_SPEED		1
+#define S6_I2C_CON_SPEED_NORMAL			1
+#define S6_I2C_CON_SPEED_FAST			2
+#define S6_I2C_CON_SPEED_MASK			3
+#define S6_I2C_CON_10BITSLAVE		3
+#define S6_I2C_CON_10BITMASTER		4
+#define S6_I2C_CON_RESTARTENA		5
+#define S6_I2C_CON_SLAVEDISABLE		6
+#define S6_I2C_TAR		0x004
+#define S6_I2C_TAR_GCORSTART		10
+#define S6_I2C_TAR_SPECIAL		11
+#define S6_I2C_SAR		0x008
+#define S6_I2C_HSMADDR		0x00C
+#define S6_I2C_DATACMD		0x010
+#define S6_I2C_DATACMD_READ		8
+#define S6_I2C_SSHCNT		0x014
+#define S6_I2C_SSLCNT		0x018
+#define S6_I2C_FSHCNT		0x01C
+#define S6_I2C_FSLCNT		0x020
+#define S6_I2C_INTRSTAT		0x02C
+#define S6_I2C_INTRMASK		0x030
+#define S6_I2C_RAWINTR		0x034
+#define S6_I2C_INTR_RXUNDER		0
+#define S6_I2C_INTR_RXOVER		1
+#define S6_I2C_INTR_RXFULL		2
+#define S6_I2C_INTR_TXOVER		3
+#define S6_I2C_INTR_TXEMPTY		4
+#define S6_I2C_INTR_RDREQ		5
+#define S6_I2C_INTR_TXABRT		6
+#define S6_I2C_INTR_RXDONE		7
+#define S6_I2C_INTR_ACTIVITY		8
+#define S6_I2C_INTR_STOPDET		9
+#define S6_I2C_INTR_STARTDET		10
+#define S6_I2C_INTR_GENCALL		11
+#define S6_I2C_RXTL		0x038
+#define S6_I2C_TXTL		0x03C
+#define S6_I2C_CLRINTR		0x040
+#define S6_I2C_CLRRXUNDER	0x044
+#define S6_I2C_CLRRXOVER	0x048
+#define S6_I2C_CLRTXOVER	0x04C
+#define S6_I2C_CLRRDREQ		0x050
+#define S6_I2C_CLRTXABRT	0x054
+#define S6_I2C_CLRRXDONE	0x058
+#define S6_I2C_CLRACTIVITY	0x05C
+#define S6_I2C_CLRSTOPDET	0x060
+#define S6_I2C_CLRSTARTDET	0x064
+#define S6_I2C_CLRGENCALL	0x068
+#define S6_I2C_ENABLE		0x06C
+#define S6_I2C_STATUS		0x070
+#define S6_I2C_STATUS_ACTIVITY		0
+#define S6_I2C_STATUS_TFNF		1
+#define S6_I2C_STATUS_TFE		2
+#define S6_I2C_STATUS_RFNE		3
+#define S6_I2C_STATUS_RFF		4
+#define S6_I2C_TXFLR		0x074
+#define S6_I2C_RXFLR		0x078
+#define S6_I2C_SRESET		0x07C
+#define S6_I2C_SRESET_IC_SRST		0
+#define S6_I2C_SRESET_IC_MASTER_SRST	1
+#define S6_I2C_SRESET_IC_SLAVE_SRST	2
+#define S6_I2C_TXABRTSOURCE	0x080
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis5595.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis5595.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis5595.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis5595.c	2009-06-09 23:05:27.000000000 -0400
@@ -256,7 +256,7 @@ static int sis5595_transaction(struct i2
 	} while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_dbg(&adap->dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis630.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis630.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis630.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis630.c	2009-06-09 23:05:27.000000000 -0400
@@ -173,7 +173,7 @@ static int sis630_transaction_wait(struc
 	} while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_dbg(&adap->dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis96x.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis96x.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-sis96x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-sis96x.c	2009-06-09 23:05:27.000000000 -0400
@@ -132,7 +132,7 @@ static int sis96x_transaction(int size)
 	} while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout >= MAX_TIMEOUT) {
+	if (timeout > MAX_TIMEOUT) {
 		dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp);
 		result = -ETIMEDOUT;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-versatile.c linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-versatile.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/i2c-versatile.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/i2c-versatile.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,7 +102,13 @@ static int i2c_versatile_probe(struct pl
 	i2c->algo = i2c_versatile_algo;
 	i2c->algo.data = i2c;
 
-	ret = i2c_bit_add_bus(&i2c->adap);
+	if (dev->id >= 0) {
+		/* static bus numbering */
+		i2c->adap.nr = dev->id;
+		ret = i2c_bit_add_numbered_bus(&i2c->adap);
+	} else
+		/* dynamic bus numbering */
+		ret = i2c_bit_add_bus(&i2c->adap);
 	if (ret >= 0) {
 		platform_set_drvdata(dev, i2c);
 		return 0;
@@ -146,7 +152,7 @@ static void __exit i2c_versatile_exit(vo
 	platform_driver_unregister(&i2c_versatile_driver);
 }
 
-module_init(i2c_versatile_init);
+subsys_initcall(i2c_versatile_init);
 module_exit(i2c_versatile_exit);
 
 MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/Kconfig linux-libre-2.6.30-gnu1/drivers/i2c/busses/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -132,6 +132,7 @@ config I2C_PIIX4
 	    Serverworks CSB5
 	    Serverworks CSB6
 	    Serverworks HT-1000
+	    Serverworks HT-1100
 	    SMSC Victory66
 
 	  This driver can also be built as a module.  If so, the module
@@ -355,6 +356,16 @@ config I2C_IBM_IIC
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-ibm_iic.
 
+config I2C_IMX
+	tristate "IMX I2C interface"
+	depends on ARCH_MXC
+	help
+	  Say Y here if you want to use the IIC bus controller on
+	  the Freescale i.MX/MXC processors.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-imx.
+
 config I2C_IOP3XX
 	tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
 	depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
@@ -456,11 +467,21 @@ config I2C_PXA_SLAVE
 
 config I2C_S3C2410
 	tristate "S3C2410 I2C Driver"
-	depends on ARCH_S3C2410
+	depends on ARCH_S3C2410 || ARCH_S3C64XX
 	help
 	  Say Y here to include support for I2C controller in the
 	  Samsung S3C2410 based System-on-Chip devices.
 
+config I2C_S6000
+	tristate "S6000 I2C support"
+	depends on XTENSA_VARIANT_S6000
+	help
+	  This driver supports the on chip I2C device on the
+	  S6000 xtensa processor family.
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called i2c-s6000.
+
 config I2C_SH7760
 	tristate "Renesas SH7760 I2C Controller"
 	depends on CPU_SUBTYPE_SH7760
@@ -583,12 +604,14 @@ comment "Graphics adapter I2C/DDC channe
 	depends on PCI
 
 config I2C_VOODOO3
-	tristate "Voodoo 3"
+	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.
+	  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.
@@ -617,12 +640,12 @@ config I2C_ELEKTOR
 	  will be called i2c-elektor.
 
 config I2C_PCA_ISA
-	tristate "PCA9564 on an ISA bus"
+	tristate "PCA9564/PCA9665 on an ISA bus"
 	depends on ISA
 	select I2C_ALGOPCA
 	default n
 	help
-	  This driver supports ISA boards using the Philips PCA9564
+	  This driver supports ISA boards using the Philips PCA9564/PCA9665
 	  parallel bus to I2C bus controller.
 
 	  This driver can also be built as a module.  If so, the module
@@ -634,11 +657,11 @@ config I2C_PCA_ISA
 	  time).  If unsure, say N.
 
 config I2C_PCA_PLATFORM
-	tristate "PCA9564 as platform device"
+	tristate "PCA9564/PCA9665 as platform device"
 	select I2C_ALGOPCA
 	default n
 	help
-	  This driver supports a memory mapped Philips PCA9564
+	  This driver supports a memory mapped Philips PCA9564/PCA9665
 	  parallel bus to I2C bus controller.
 
 	  This driver can also be built as a module.  If so, the module
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/busses/Makefile linux-libre-2.6.30-gnu1/drivers/i2c/busses/Makefile
--- linux-libre-2.6.29-gnu1/drivers/i2c/busses/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/busses/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci
 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
 obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o
 obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
+obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_IXP2000)	+= i2c-ixp2000.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
@@ -43,6 +44,7 @@ obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
+obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o
 obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o
 obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mobile.o
 obj-$(CONFIG_I2C_SIMTEC)	+= i2c-simtec.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/chips/Kconfig linux-libre-2.6.30-gnu1/drivers/i2c/chips/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/i2c/chips/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/chips/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -64,19 +64,6 @@ config SENSORS_PCA9539
 	  This driver is deprecated and will be dropped soon. Use
 	  drivers/gpio/pca953x.c instead.
 
-config SENSORS_PCF8591
-	tristate "Philips PCF8591"
-	depends on EXPERIMENTAL
-	default n
-	help
-	  If you say yes here you get support for Philips PCF8591 chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called pcf8591.
-
-	  These devices are hard to detect and rarely found on mainstream
-	  hardware.  If unsure, say N.
-
 config SENSORS_MAX6875
 	tristate "Maxim MAX6875 Power supply supervisor"
 	depends on EXPERIMENTAL
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/chips/Makefile linux-libre-2.6.30-gnu1/drivers/i2c/chips/Makefile
--- linux-libre-2.6.29-gnu1/drivers/i2c/chips/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/chips/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@ obj-$(CONFIG_SENSORS_MAX6875)	+= max6875
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_PCF8575)		+= pcf8575.o
-obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/chips/pcf8591.c linux-libre-2.6.30-gnu1/drivers/i2c/chips/pcf8591.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/chips/pcf8591.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/chips/pcf8591.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,325 +0,0 @@
-/*
-    Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with 
-    the help of Jean Delvare <khali@linux-fr.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(pcf8591);
-
-static int input_mode;
-module_param(input_mode, int, 0);
-MODULE_PARM_DESC(input_mode,
-	"Analog input mode:\n"
-	" 0 = four single ended inputs\n"
-	" 1 = three differential inputs\n"
-	" 2 = single ended and differential mixed\n"
-	" 3 = two differential inputs\n");
-
-/* The PCF8591 control byte
-      7    6    5    4    3    2    1    0  
-   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   | */
-
-/* Analog Output Enable Flag (analog output active if 1) */
-#define PCF8591_CONTROL_AOEF		0x40
-					
-/* Analog Input Programming 
-   0x00 = four single ended inputs
-   0x10 = three differential inputs
-   0x20 = single ended and differential mixed
-   0x30 = two differential inputs */
-#define PCF8591_CONTROL_AIP_MASK	0x30
-
-/* Autoincrement Flag (switch on if 1) */
-#define PCF8591_CONTROL_AINC		0x04
-
-/* Channel selection
-   0x00 = channel 0 
-   0x01 = channel 1
-   0x02 = channel 2
-   0x03 = channel 3 */
-#define PCF8591_CONTROL_AICH_MASK	0x03
-
-/* Initial values */
-#define PCF8591_INIT_CONTROL	((input_mode << 4) | PCF8591_CONTROL_AOEF)
-#define PCF8591_INIT_AOUT	0	/* DAC out = 0 */
-
-/* Conversions */
-#define REG_TO_SIGNED(reg)	(((reg) & 0x80)?((reg) - 256):(reg))
-
-struct pcf8591_data {
-	struct mutex update_lock;
-
-	u8 control;
-	u8 aout;
-};
-
-static void pcf8591_init_client(struct i2c_client *client);
-static int pcf8591_read_channel(struct device *dev, int channel);
-
-/* following are the sysfs callback functions */
-#define show_in_channel(channel)					\
-static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf)	\
-{									\
-	return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
-}									\
-static DEVICE_ATTR(in##channel##_input, S_IRUGO,			\
-		   show_in##channel##_input, NULL);
-
-show_in_channel(0);
-show_in_channel(1);
-show_in_channel(2);
-show_in_channel(3);
-
-static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
-	return sprintf(buf, "%d\n", data->aout * 10);
-}
-
-static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	unsigned int value;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pcf8591_data *data = i2c_get_clientdata(client);
-	if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
-		data->aout = value;
-		i2c_smbus_write_byte_data(client, data->control, data->aout);
-		return count;
-	}
-	return -EINVAL;
-}
-
-static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, 
-		   show_out0_ouput, set_out0_output);
-
-static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
-	return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
-}
-
-static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pcf8591_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	mutex_lock(&data->update_lock);
-	if (val)
-		data->control |= PCF8591_CONTROL_AOEF;
-	else
-		data->control &= ~PCF8591_CONTROL_AOEF;
-	i2c_smbus_write_byte(client, data->control);
-	mutex_unlock(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, 
-		   show_out0_enable, set_out0_enable);
-
-static struct attribute *pcf8591_attributes[] = {
-	&dev_attr_out0_enable.attr,
-	&dev_attr_out0_output.attr,
-	&dev_attr_in0_input.attr,
-	&dev_attr_in1_input.attr,
-	NULL
-};
-
-static const struct attribute_group pcf8591_attr_group = {
-	.attrs = pcf8591_attributes,
-};
-
-static struct attribute *pcf8591_attributes_opt[] = {
-	&dev_attr_in2_input.attr,
-	&dev_attr_in3_input.attr,
-	NULL
-};
-
-static const struct attribute_group pcf8591_attr_group_opt = {
-	.attrs = pcf8591_attributes_opt,
-};
-
-/*
- * Real code
- */
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int pcf8591_detect(struct i2c_client *client, int kind,
-			  struct i2c_board_info *info)
-{
-	struct i2c_adapter *adapter = client->adapter;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
-				     | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-		return -ENODEV;
-
-	/* Now, we would do the remaining detection. But the PCF8591 is plainly
-	   impossible to detect! Stupid chip. */
-
-	strlcpy(info->type, "pcf8591", I2C_NAME_SIZE);
-
-	return 0;
-}
-
-static int pcf8591_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct pcf8591_data *data;
-	int err;
-
-	if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->update_lock);
-
-	/* Initialize the PCF8591 chip */
-	pcf8591_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);
-	if (err)
-		goto exit_kfree;
-
-	/* Register input2 if not in "two differential inputs" mode */
-	if (input_mode != 3) {
-		if ((err = device_create_file(&client->dev,
-					      &dev_attr_in2_input)))
-			goto exit_sysfs_remove;
-	}
-
-	/* Register input3 only in "four single ended inputs" mode */
-	if (input_mode == 0) {
-		if ((err = device_create_file(&client->dev,
-					      &dev_attr_in3_input)))
-			goto exit_sysfs_remove;
-	}
-
-	return 0;
-
-exit_sysfs_remove:
-	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
-	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
-exit_kfree:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int pcf8591_remove(struct i2c_client *client)
-{
-	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
-	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* Called when we have found a new PCF8591. */
-static void pcf8591_init_client(struct i2c_client *client)
-{
-	struct pcf8591_data *data = i2c_get_clientdata(client);
-	data->control = PCF8591_INIT_CONTROL;
-	data->aout = PCF8591_INIT_AOUT;
-
-	i2c_smbus_write_byte_data(client, data->control, data->aout);
-	
-	/* The first byte transmitted contains the conversion code of the 
-	   previous read cycle. FLUSH IT! */
-	i2c_smbus_read_byte(client);
-}
-
-static int pcf8591_read_channel(struct device *dev, int channel)
-{
-	u8 value;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pcf8591_data *data = i2c_get_clientdata(client);
-
-	mutex_lock(&data->update_lock);
-
-	if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) {
-		data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
-			      | channel;
-		i2c_smbus_write_byte(client, data->control);
-	
-		/* The first byte transmitted contains the conversion code of 
-		   the previous read cycle. FLUSH IT! */
-		i2c_smbus_read_byte(client);
-	}
-	value = i2c_smbus_read_byte(client);
-
-	mutex_unlock(&data->update_lock);
-
-	if ((channel == 2 && input_mode == 2) ||
-	    (channel != 3 && (input_mode == 1 || input_mode == 3)))
-		return (10 * REG_TO_SIGNED(value));
-	else
-		return (10 * value);
-}
-
-static const struct i2c_device_id pcf8591_id[] = {
-	{ "pcf8591", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, pcf8591_id);
-
-static struct i2c_driver pcf8591_driver = {
-	.driver = {
-		.name	= "pcf8591",
-	},
-	.probe		= pcf8591_probe,
-	.remove		= pcf8591_remove,
-	.id_table	= pcf8591_id,
-
-	.class		= I2C_CLASS_HWMON,	/* Nearest choice */
-	.detect		= pcf8591_detect,
-	.address_data	= &addr_data,
-};
-
-static int __init pcf8591_init(void)
-{
-	if (input_mode < 0 || input_mode > 3) {
-		printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n",
-		       input_mode);
-		input_mode = 0;
-	}
-	return i2c_add_driver(&pcf8591_driver);
-}
-
-static void __exit pcf8591_exit(void)
-{
-	i2c_del_driver(&pcf8591_driver);
-}
-
-MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
-MODULE_DESCRIPTION("PCF8591 driver");
-MODULE_LICENSE("GPL");
-
-module_init(pcf8591_init);
-module_exit(pcf8591_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/i2c/i2c-core.c linux-libre-2.6.30-gnu1/drivers/i2c/i2c-core.c
--- linux-libre-2.6.29-gnu1/drivers/i2c/i2c-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/i2c/i2c-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,7 +152,7 @@ static void i2c_device_shutdown(struct d
 		driver->shutdown(to_i2c_client(dev));
 }
 
-static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
+static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct i2c_driver *driver;
 
@@ -164,7 +164,7 @@ static int i2c_device_suspend(struct dev
 	return driver->suspend(to_i2c_client(dev), mesg);
 }
 
-static int i2c_device_resume(struct device * dev)
+static int i2c_device_resume(struct device *dev)
 {
 	struct i2c_driver *driver;
 
@@ -187,13 +187,15 @@ static void i2c_client_dev_release(struc
 	kfree(to_i2c_client(dev));
 }
 
-static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	return sprintf(buf, "%s\n", client->name);
 }
 
-static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
@@ -365,8 +367,7 @@ static struct i2c_driver dummy_driver =
  * This returns the new i2c client, which should be saved for later use with
  * i2c_unregister_device(); or NULL to indicate an error.
  */
-struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
+struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
 {
 	struct i2c_board_info info = {
 		I2C_BOARD_INFO("dummy", address),
@@ -413,8 +414,8 @@ static void i2c_scan_static_board_info(s
 		if (devinfo->busnum == adapter->nr
 				&& !i2c_new_device(adapter,
 						&devinfo->board_info))
-			printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
-				i2c_adapter_id(adapter),
+			dev_err(&adapter->dev,
+				"Can't create device at 0x%02x\n",
 				devinfo->board_info.addr);
 	}
 	mutex_unlock(&__i2c_board_lock);
@@ -459,6 +460,11 @@ static int i2c_register_adapter(struct i
 		pr_debug("I2C adapter driver [%s] forgot to specify "
 			 "physical device\n", adap->name);
 	}
+
+	/* Set default timeout to 1 second if not already set */
+	if (adap->timeout == 0)
+		adap->timeout = HZ;
+
 	dev_set_name(&adap->dev, "i2c-%d", adap->nr);
 	adap->dev.release = &i2c_adapter_dev_release;
 	adap->dev.class = &i2c_adapter_class;
@@ -581,7 +587,8 @@ static int i2c_do_del_adapter(struct dev
 	struct i2c_client *client, *_n;
 	int res;
 
-	/* Remove the devices we created ourselves */
+	/* 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) {
 		if (client->adapter == adapter) {
 			dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
@@ -709,8 +716,7 @@ int i2c_register_driver(struct module *o
 
 	/* new style driver methods can't mix with legacy ones */
 	if (is_newstyle_driver(driver)) {
-		if (driver->attach_adapter || driver->detach_adapter
-				|| driver->detach_client) {
+		if (driver->detach_adapter || driver->detach_client) {
 			printk(KERN_WARNING
 					"i2c-core: driver [%s] is confused\n",
 					driver->driver.name);
@@ -749,6 +755,8 @@ static int __detach_adapter(struct devic
 	struct i2c_driver *driver = data;
 	struct i2c_client *client, *_n;
 
+	/* 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);
@@ -841,7 +849,7 @@ int i2c_attach_client(struct i2c_client
 
 	if (client->driver && !is_newstyle_driver(client->driver)) {
 		client->dev.release = i2c_client_release;
-		client->dev.uevent_suppress = 1;
+		dev_set_uevent_suppress(&client->dev, 1);
 	} else
 		client->dev.release = i2c_client_dev_release;
 
@@ -1012,7 +1020,7 @@ module_exit(i2c_exit);
  * Note that there is no requirement that each message be sent to
  * the same slave address, although that is the most common model.
  */
-int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
 	int ret;
 
@@ -1519,8 +1527,7 @@ EXPORT_SYMBOL(i2c_put_adapter);
 /* The SMBus parts */
 
 #define POLY    (0x1070U << 3)
-static u8
-crc8(u16 data)
+static u8 crc8(u16 data)
 {
 	int i;
 
@@ -1984,9 +1991,9 @@ static s32 i2c_smbus_xfer_emulated(struc
  * This executes an SMBus protocol operation, and returns a negative
  * errno code else zero on success.
  */
-s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
+s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
 		   char read_write, u8 command, int protocol,
-                   union i2c_smbus_data * data)
+		   union i2c_smbus_data *data)
 {
 	s32 res;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/aec62xx.c linux-libre-2.6.30-gnu1/drivers/ide/aec62xx.c
--- linux-libre-2.6.29-gnu1/drivers/ide/aec62xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/aec62xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t
 	drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
 }
 
-static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
+static int init_chipset_aec62xx(struct pci_dev *dev)
 {
 	/* These are necessary to get AEC6280 Macintosh cards to work */
 	if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
@@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx
 		pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
 	}
 
-	return dev->irq;
+	return 0;
 }
 
 static u8 atp86x_cable_detect(ide_hwif_t *hwif)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/alim15x3.c linux-libre-2.6.30-gnu1/drivers/ide/alim15x3.c
--- linux-libre-2.6.29-gnu1/drivers/ide/alim15x3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/alim15x3.c	2009-06-09 23:05:27.000000000 -0400
@@ -189,19 +189,20 @@ static void ali_set_dma_mode(ide_drive_t
 }
 
 /**
- *	ali15x3_dma_setup	-	begin a DMA phase
+ *	ali_dma_check	-	DMA check
  *	@drive:	target device
+ *	@cmd: command
  *
  *	Returns 1 if the DMA cannot be performed, zero on success.
  */
 
-static int ali15x3_dma_setup(ide_drive_t *drive)
+static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	if (m5229_revision < 0xC2 && drive->media != ide_disk) {
-		if (rq_data_dir(drive->hwif->rq))
+		if (cmd->tf_flags & IDE_TFLAG_WRITE)
 			return 1;	/* try PIO instead of DMA */
 	}
-	return ide_dma_setup(drive);
+	return 0;
 }
 
 /**
@@ -212,7 +213,7 @@ static int ali15x3_dma_setup(ide_drive_t
  *	appropriate also sets up the 1533 southbridge.
  */
 
-static unsigned int init_chipset_ali15x3(struct pci_dev *dev)
+static int init_chipset_ali15x3(struct pci_dev *dev)
 {
 	unsigned long flags;
 	u8 tmpbyte;
@@ -502,13 +503,13 @@ static const struct ide_port_ops ali_por
 
 static const struct ide_dma_ops ali_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
-	.dma_setup		= ali15x3_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
+	.dma_setup		= ide_dma_setup,
 	.dma_start		= ide_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_check		= ali_dma_check,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/amd74xx.c linux-libre-2.6.30-gnu1/drivers/ide/amd74xx.c
--- linux-libre-2.6.29-gnu1/drivers/ide/amd74xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/amd74xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct
  * The initialization callback.  Initialize drive independent registers.
  */
 
-static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
+static int init_chipset_amd74xx(struct pci_dev *dev)
 {
 	u8 t = 0, offset = amd_offset(dev);
 
@@ -172,7 +172,7 @@ static unsigned int init_chipset_amd74xx
 		t |= 0xf0;
 	pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t);
 
-	return dev->irq;
+	return 0;
 }
 
 static u8 amd_cable_detect(ide_hwif_t *hwif)
@@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *h
 		return ATA_CBL_PATA40;
 }
 
-static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
-{
-	struct pci_dev *dev = to_pci_dev(hwif->dev);
-
-	if (hwif->irq == 0) /* 0 is bogus but will do for now */
-		hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
-}
-
 static const struct ide_port_ops amd_port_ops = {
 	.set_pio_mode		= amd_set_pio_mode,
 	.set_dma_mode		= amd_set_drive,
@@ -207,7 +199,6 @@ static const struct ide_port_ops amd_por
 	{								\
 		.name		= DRV_NAME,				\
 		.init_chipset	= init_chipset_amd74xx,			\
-		.init_hwif	= init_hwif_amd74xx,			\
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},	\
 		.port_ops	= &amd_port_ops,			\
 		.host_flags	= IDE_HFLAGS_AMD,			\
@@ -221,7 +212,6 @@ static const struct ide_port_ops amd_por
 	{								\
 		.name		= DRV_NAME,				\
 		.init_chipset	= init_chipset_amd74xx,			\
-		.init_hwif	= init_hwif_amd74xx,			\
 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},	\
 		.port_ops	= &amd_port_ops,			\
 		.host_flags	= IDE_HFLAGS_AMD,			\
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/at91_ide.c linux-libre-2.6.30-gnu1/drivers/ide/at91_ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/at91_ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/at91_ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/clk.h>
@@ -143,7 +142,7 @@ static void apply_timings(const u8 chips
 	set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
 }
 
-static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -156,11 +155,11 @@ static void at91_ide_input_data(ide_driv
 	len++;
 
 	enter_16bit(chipselect, mode);
-	__ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2);
+	readsw((void __iomem *)io_ports->data_addr, buf, len / 2);
 	leave_16bit(chipselect, mode);
 }
 
-static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 				 void *buf, unsigned int len)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -171,108 +170,10 @@ static void at91_ide_output_data(ide_dri
 	pdbg("cs %u buf %p len %d\n", chipselect,  buf, len);
 
 	enter_16bit(chipselect, mode);
-	__ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2);
+	writesw((void __iomem *)io_ports->data_addr, buf, len / 2);
 	leave_16bit(chipselect, mode);
 }
 
-static u8 ide_mm_inb(unsigned long port)
-{
-	return readb((void __iomem *) port);
-}
-
-static void ide_mm_outb(u8 value, unsigned long port)
-{
-	writeb(value, (void __iomem *) port);
-}
-
-static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
-		u16 data = (tf->hob_data << 8) | tf->data;
-
-		at91_ide_output_data(drive, NULL, &data, 2);
-	}
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		ide_mm_outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-		ide_mm_outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-		ide_mm_outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-		ide_mm_outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-		ide_mm_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
-}
-
-static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data;
-
-		at91_ide_input_data(drive, NULL, &data, 2);
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = ide_mm_inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = ide_mm_inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = ide_mm_inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = ide_mm_inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = ide_mm_inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = ide_mm_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = ide_mm_inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = ide_mm_inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = ide_mm_inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = ide_mm_inb(io_ports->lbah_addr);
-	}
-}
-
 static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 	struct ide_timing *timing;
@@ -295,10 +196,11 @@ static const struct ide_tp_ops at91_ide_
 	.exec_command	= ide_exec_command,
 	.read_status	= ide_read_status,
 	.read_altstatus	= ide_read_altstatus,
-	.set_irq	= ide_set_irq,
+	.write_devctl	= ide_write_devctl,
 
-	.tf_load	= at91_ide_tf_load,
-	.tf_read	= at91_ide_tf_read,
+	.dev_select	= ide_dev_select,
+	.tf_load	= ide_tf_load,
+	.tf_read	= ide_tf_read,
 
 	.input_data	= at91_ide_input_data,
 	.output_data	= at91_ide_output_data,
@@ -313,7 +215,7 @@ static const struct ide_port_info at91_i
 	.tp_ops		= &at91_ide_tp_ops,
 	.host_flags 	= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
 			  IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
-	.pio_mask 	= ATA_PIO5,
+	.pio_mask 	= ATA_PIO6,
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/atiixp.c linux-libre-2.6.30-gnu1/drivers/ide/atiixp.c
--- linux-libre-2.6.29-gnu1/drivers/ide/atiixp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/atiixp.c	2009-06-09 23:05:27.000000000 -0400
@@ -142,7 +142,6 @@ static const struct ide_port_info atiixp
 		.name		= DRV_NAME,
 		.enablebits	= {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
 		.port_ops	= &atiixp_port_ops,
-		.host_flags	= IDE_HFLAG_LEGACY_IRQS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
@@ -151,7 +150,7 @@ static const struct ide_port_info atiixp
 		.name		= DRV_NAME,
 		.enablebits	= {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
 		.port_ops	= &atiixp_port_ops,
-		.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
+		.host_flags	= IDE_HFLAG_SINGLE,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/au1xxx-ide.c linux-libre-2.6.30-gnu1/drivers/ide/au1xxx-ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/au1xxx-ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/au1xxx-ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ static _auide_hwif auide_hwif;
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
 
-void auide_insw(unsigned long port, void *addr, u32 count)
+static inline void auide_insw(unsigned long port, void *addr, u32 count)
 {
 	_auide_hwif *ahwif = &auide_hwif;
 	chan_tab_t *ctp;
@@ -68,7 +68,7 @@ void auide_insw(unsigned long port, void
 	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
 }
 
-void auide_outsw(unsigned long port, void *addr, u32 count)
+static inline void auide_outsw(unsigned long port, void *addr, u32 count)
 {
 	_auide_hwif *ahwif = &auide_hwif;
 	chan_tab_t *ctp;
@@ -86,13 +86,13 @@ void auide_outsw(unsigned long port, voi
 	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
 }
 
-static void au1xxx_input_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			      void *buf, unsigned int len)
 {
 	auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
 }
 
-static void au1xxx_output_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			       void *buf, unsigned int len)
 {
 	auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -209,23 +209,17 @@ static void auide_set_dma_mode(ide_drive
  */
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int auide_build_dmatable(ide_drive_t *drive)
+static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	int i, iswrite, count = 0;
 	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
 	_auide_hwif *ahwif = &auide_hwif;
 	struct scatterlist *sg;
+	int i = cmd->sg_nents, count = 0;
+	int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
 
-	iswrite = (rq_data_dir(rq) == WRITE);
 	/* Save for interrupt context */
 	ahwif->drive = drive;
 
-	hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
-	if (!i)
-		return 0;
-
 	/* fill the descriptors */
 	sg = hwif->sg_table;
 	while (i && sg_dma_len(sg)) {
@@ -242,7 +236,7 @@ static int auide_build_dmatable(ide_driv
 			if (++count >= PRD_ENTRIES) {
 				printk(KERN_WARNING "%s: DMA table too small\n",
 				       drive->name);
-				goto use_pio_instead;
+				return 0;
 			}
 
 			/* Lets enable intr for the last descriptor only */
@@ -278,21 +272,11 @@ static int auide_build_dmatable(ide_driv
 	if (count)
 		return 1;
 
- use_pio_instead:
-	ide_destroy_dmatable(drive);
-
 	return 0; /* revert to PIO for this request */
 }
 
 static int auide_dma_end(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
-
-	if (hwif->sg_nents) {
-		ide_destroy_dmatable(drive);
-		hwif->sg_nents = 0;
-	}
-
 	return 0;
 }
 
@@ -301,23 +285,11 @@ static void auide_dma_start(ide_drive_t
 }
 
 
-static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr,
-			    (2*WAIT_CMD), NULL);
-}
-
-static int auide_dma_setup(ide_drive_t *drive)
+static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	struct request *rq = drive->hwif->rq;
-
-	if (!auide_build_dmatable(drive)) {
-		ide_map_sg(drive, rq);
+	if (auide_build_dmatable(drive, cmd) == 0)
 		return 1;
-	}
 
-	drive->waiting_for_dma = 1;
 	return 0;
 }
 
@@ -342,16 +314,11 @@ static void auide_dma_host_set(ide_drive
 
 static void auide_ddma_tx_callback(int irq, void *param)
 {
-	_auide_hwif *ahwif = (_auide_hwif*)param;
-	ahwif->drive->waiting_for_dma = 0;
 }
 
 static void auide_ddma_rx_callback(int irq, void *param)
 {
-	_auide_hwif *ahwif = (_auide_hwif*)param;
-	ahwif->drive->waiting_for_dma = 0;
 }
-
 #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
 
 static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
@@ -369,12 +336,10 @@ static void auide_init_dbdma_dev(dbdev_t
 static const struct ide_dma_ops au1xxx_dma_ops = {
 	.dma_host_set		= auide_dma_host_set,
 	.dma_setup		= auide_dma_setup,
-	.dma_exec_cmd		= auide_dma_exec_cmd,
 	.dma_start		= auide_dma_start,
 	.dma_end		= auide_dma_end,
 	.dma_test_irq		= auide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
 };
 
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -502,9 +467,9 @@ static const struct ide_tp_ops au1xxx_tp
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -536,9 +501,8 @@ static const struct ide_port_info au1xxx
 #endif
 };
 
-static int au_ide_probe(struct device *dev)
+static int au_ide_probe(struct platform_device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	_auide_hwif *ahwif = &auide_hwif;
 	struct resource *res;
 	struct ide_host *host;
@@ -552,23 +516,23 @@ static int au_ide_probe(struct device *d
 #endif
 
 	memset(&auide_hwif, 0, sizeof(_auide_hwif));
-	ahwif->irq = platform_get_irq(pdev, 0);
+	ahwif->irq = platform_get_irq(dev, 0);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 
 	if (res == NULL) {
-		pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+		pr_debug("%s %d: no base address\n", DRV_NAME, dev->id);
 		ret = -ENODEV;
 		goto out;
 	}
 	if (ahwif->irq < 0) {
-		pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+		pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id);
 		ret = -ENODEV;
 		goto out;
 	}
 
 	if (!request_mem_region(res->start, res->end - res->start + 1,
-				pdev->name)) {
+				dev->name)) {
 		pr_debug("%s: request_mem_region failed\n", DRV_NAME);
 		ret =  -EBUSY;
 		goto out;
@@ -583,7 +547,7 @@ static int au_ide_probe(struct device *d
 	memset(&hw, 0, sizeof(hw));
 	auide_setup_ports(&hw, ahwif);
 	hw.irq = ahwif->irq;
-	hw.dev = dev;
+	hw.dev = &dev->dev;
 	hw.chipset = ide_au1xxx;
 
 	ret = ide_host_add(&au1xxx_port_info, hws, &host);
@@ -592,7 +556,7 @@ static int au_ide_probe(struct device *d
 
 	auide_hwif.hwif = host->ports[0];
 
-	dev_set_drvdata(dev, host);
+	platform_set_drvdata(dev, host);
 
 	printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
 
@@ -600,38 +564,39 @@ static int au_ide_probe(struct device *d
 	return ret;
 }
 
-static int au_ide_remove(struct device *dev)
+static int au_ide_remove(struct platform_device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *res;
-	struct ide_host *host = dev_get_drvdata(dev);
+	struct ide_host *host = platform_get_drvdata(dev);
 	_auide_hwif *ahwif = &auide_hwif;
 
 	ide_host_remove(host);
 
 	iounmap((void *)ahwif->regbase);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, res->end - res->start + 1);
 
 	return 0;
 }
 
-static struct device_driver au1200_ide_driver = {
-	.name		= "au1200-ide",
-	.bus		= &platform_bus_type,
+static struct platform_driver au1200_ide_driver = {
+	.driver = {
+		.name		= "au1200-ide",
+		.owner		= THIS_MODULE,
+	},
 	.probe 		= au_ide_probe,
 	.remove		= au_ide_remove,
 };
 
 static int __init au_ide_init(void)
 {
-	return driver_register(&au1200_ide_driver);
+	return platform_driver_register(&au1200_ide_driver);
 }
 
 static void __exit au_ide_exit(void)
 {
-	driver_unregister(&au1200_ide_driver);
+	platform_driver_unregister(&au1200_ide_driver);
 }
 
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/buddha.c linux-libre-2.6.30-gnu1/drivers/ide/buddha.c
--- linux-libre-2.6.29-gnu1/drivers/ide/buddha.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/buddha.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,6 +143,11 @@ static void __init buddha_setup_ports(hw
 	hw->chipset = ide_generic;
 }
 
+static const struct ide_port_info buddha_port_info = {
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
+};
+
     /*
      *  Probe for a Buddha or Catweasel IDE interface
      */
@@ -172,10 +177,6 @@ static int __init buddha_init(void)
 		
 		board = z->resource.start;
 
-/*
- * FIXME: we now have selectable mmio v/s iomio transports.
- */
-
 		if(type != BOARD_XSURF) {
 			if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
 				continue;
@@ -224,7 +225,7 @@ fail_base2:
 			hws[i] = &hw[i];
 		}
 
-		ide_host_add(NULL, hws, NULL);
+		ide_host_add(&buddha_port_info, hws, NULL);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/cmd64x.c linux-libre-2.6.30-gnu1/drivers/ide/cmd64x.c
--- linux-libre-2.6.29-gnu1/drivers/ide/cmd64x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/cmd64x.c	2009-06-09 23:05:27.000000000 -0400
@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t
 	ide_hwif_t *hwif = drive->hwif;
 	u8 dma_stat = 0, dma_cmd = 0;
 
-	drive->waiting_for_dma = 0;
 	/* get DMA status */
 	dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
 	/* read DMA command state */
@@ -327,13 +326,11 @@ static int cmd646_1_dma_end(ide_drive_t
 	outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
 	/* clear the INTR & ERROR bits */
 	outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
-	/* and free any DMA resources */
-	ide_destroy_dmatable(drive);
 	/* verify good DMA status */
 	return (dma_stat & 7) != 4;
 }
 
-static unsigned int init_chipset_cmd64x(struct pci_dev *dev)
+static int init_chipset_cmd64x(struct pci_dev *dev)
 {
 	u8 mrdmode = 0;
 
@@ -379,36 +376,33 @@ static const struct ide_port_ops cmd64x_
 static const struct ide_dma_ops cmd64x_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= cmd64x_dma_end,
 	.dma_test_irq		= cmd64x_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_dma_ops cmd646_rev1_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= cmd646_1_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_dma_ops cmd648_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= cmd648_dma_end,
 	.dma_test_irq		= cmd648_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/cs5520.c linux-libre-2.6.30-gnu1/drivers/ide/cs5520.c
--- linux-libre-2.6.29-gnu1/drivers/ide/cs5520.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/cs5520.c	2009-06-09 23:05:27.000000000 -0400
@@ -122,7 +122,7 @@ static int __devinit cs5520_init_one(str
 		return -ENODEV;
 	}
 	pci_set_master(dev);
-	if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING "%s: No suitable DMA available.\n",
 			d->name);
 		return -ENODEV;
@@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(str
 	 *	do all the device setup for us
 	 */
 
-	ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
+	ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
+	hw[0].irq = 14;
 
 	return ide_host_add(d, hws, NULL);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/cs5530.c linux-libre-2.6.30-gnu1/drivers/ide/cs5530.c
--- linux-libre-2.6.29-gnu1/drivers/ide/cs5530.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/cs5530.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t
 		if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
 		    (mateid[ATA_ID_UDMA_MODES] & 7))
 			goto out;
-		if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
-		    (mateid[ATA_ID_MWDMA_MODES] & 7))
+		if (mateid[ATA_ID_MWDMA_MODES] & 7)
 			mask = 0;
 	}
 out:
@@ -135,7 +134,7 @@ static void cs5530_set_dma_mode(ide_driv
  *	Initialize the cs5530 bridge for reliable IDE DMA operation.
  */
 
-static unsigned int init_chipset_cs5530(struct pci_dev *dev)
+static int init_chipset_cs5530(struct pci_dev *dev)
 {
 	struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/cs5536.c linux-libre-2.6.30-gnu1/drivers/ide/cs5536.c
--- linux-libre-2.6.29-gnu1/drivers/ide/cs5536.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/cs5536.c	2009-06-09 23:05:27.000000000 -0400
@@ -231,12 +231,12 @@ static const struct ide_port_ops cs5536_
 static const struct ide_dma_ops cs5536_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= cs5536_dma_start,
 	.dma_end		= cs5536_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
+	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_port_info cs5536_info = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/delkin_cb.c linux-libre-2.6.30-gnu1/drivers/ide/delkin_cb.c
--- linux-libre-2.6.29-gnu1/drivers/ide/delkin_cb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/delkin_cb.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_
 	.quirkproc		= ide_undecoded_slave,
 };
 
-static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+static int delkin_cb_init_chipset(struct pci_dev *dev)
 {
 	unsigned long base = pci_resource_start(dev, 0);
 	int i;
@@ -66,6 +66,7 @@ static const struct ide_port_info delkin
 	.port_ops		= &delkin_cb_port_ops,
 	.host_flags		= IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
 				  IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
 	.init_chipset		= delkin_cb_init_chipset,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/dtc2278.c linux-libre-2.6.30-gnu1/drivers/ide/dtc2278.c
--- linux-libre-2.6.29-gnu1/drivers/ide/dtc2278.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/dtc2278.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,7 +100,8 @@ static const struct ide_port_info dtc227
 				  IDE_HFLAG_IO_32BIT |
 				  /* disallow ->io_32bit changes */
 				  IDE_HFLAG_NO_IO_32BIT |
-				  IDE_HFLAG_NO_DMA,
+				  IDE_HFLAG_NO_DMA |
+				  IDE_HFLAG_DTC2278,
 	.pio_mask		= ATA_PIO4,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/falconide.c linux-libre-2.6.30-gnu1/drivers/ide/falconide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/falconide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/falconide.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
 #include <asm/atari_stdma.h>
+#include <asm/ide.h>
 
 #define DRV_NAME "falconide"
 
@@ -40,29 +41,52 @@
      *  which is shared between several drivers.
      */
 
-int falconide_intr_lock;
-EXPORT_SYMBOL(falconide_intr_lock);
+static int falconide_intr_lock;
 
-static void falconide_input_data(ide_drive_t *drive, struct request *rq,
+static void falconide_release_lock(void)
+{
+	if (falconide_intr_lock == 0) {
+		printk(KERN_ERR "%s: bug\n", __func__);
+		return;
+	}
+	falconide_intr_lock = 0;
+	stdma_release();
+}
+
+static void falconide_get_lock(irq_handler_t handler, void *data)
+{
+	if (falconide_intr_lock == 0) {
+		if (in_interrupt() > 0)
+			panic("Falcon IDE hasn't ST-DMA lock in interrupt");
+		stdma_lock(handler, data);
+		falconide_intr_lock = 1;
+	}
+}
+
+static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 				 void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-		return insw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_insw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
-	insw_swapw(data_addr, buf, (len + 1) / 2);
+	raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
 
-static void falconide_output_data(ide_drive_t *drive, struct request *rq,
+static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 				  void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-		return outsw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
-	outsw_swapw(data_addr, buf, (len + 1) / 2);
+	raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
 
 /* Atari has a byte-swapped IDE interface */
@@ -70,9 +94,9 @@ static const struct ide_tp_ops falconide
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -81,8 +105,12 @@ static const struct ide_tp_ops falconide
 };
 
 static const struct ide_port_info falconide_port_info = {
+	.get_lock		= falconide_get_lock,
+	.release_lock		= falconide_release_lock,
 	.tp_ops			= &falconide_tp_ops,
-	.host_flags		= IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE,
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+				  IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
 };
 
 static void __init falconide_setup_ports(hw_regs_t *hw)
@@ -132,9 +160,9 @@ static int __init falconide_init(void)
 		goto err;
 	}
 
-	ide_get_lock(NULL, NULL);
+	falconide_get_lock(NULL, NULL);
 	rc = ide_host_register(host, &falconide_port_info, hws);
-	ide_release_lock();
+	falconide_release_lock();
 
 	if (rc)
 		goto err_free;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/gayle.c linux-libre-2.6.30-gnu1/drivers/ide/gayle.c
--- linux-libre-2.6.29-gnu1/drivers/ide/gayle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/gayle.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,11 +53,6 @@
 
 #define GAYLE_NEXT_PORT	0x1000
 
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS		1
-#define GAYLE_NUM_PROBE_HWIFS	GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG	1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
 #define GAYLE_NUM_HWIFS		2
 #define GAYLE_NUM_PROBE_HWIFS	(ide_doubler ? GAYLE_NUM_HWIFS : \
 					       GAYLE_NUM_HWIFS-1)
@@ -66,8 +61,6 @@
 static int ide_doubler;
 module_param_named(doubler, ide_doubler, bool, 0);
 MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
 
     /*
      *  Check and acknowledge the interrupt status
@@ -118,7 +111,9 @@ static void __init gayle_setup_ports(hw_
 }
 
 static const struct ide_port_info gayle_port_info = {
-	.host_flags		= IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+				  IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
 };
 
     /*
@@ -149,10 +144,7 @@ static int __init gayle_init(void)
 found:
 	printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
 			 a4000 ? 4000 : 1200,
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
-			 ide_doubler ? ", IDE doubler" :
-#endif
-			 "");
+			 ide_doubler ? ", IDE doubler" : "");
 
 	if (a4000) {
 	    phys_base = GAYLE_BASE_4000;
@@ -163,9 +155,6 @@ found:
 	    irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
 	    ack_intr = gayle_ack_intr_a1200;
 	}
-/*
- * FIXME: we now have selectable modes between mmio v/s iomio
- */
 
 	res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
 	res_n = GAYLE_IDEREG_SIZE;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/hpt366.c linux-libre-2.6.30-gnu1/drivers/ide/hpt366.c
--- linux-libre-2.6.29-gnu1/drivers/ide/hpt366.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/hpt366.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2003		Red Hat Inc
  * Portions Copyright (C) 2007		Bartlomiej Zolnierkiewicz
- * Portions Copyright (C) 2005-2008	MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009	MontaVista Software, Inc.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
  * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -114,6 +114,8 @@
  *   the register setting lists into the table indexed by the clock selected
  * - set the correct hwif->ultra_mask for each individual chip
  * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
+ * - stop resetting HPT370's state machine before each DMA transfer as that has
+ *   caused more harm than good
  *	Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
  */
 
@@ -133,7 +135,7 @@
 #define DRV_NAME "hpt366"
 
 /* various tuning parameters */
-#define HPT_RESET_STATE_ENGINE
+#undef	HPT_RESET_STATE_ENGINE
 #undef	HPT_DELAY_INTERRUPT
 
 static const char *quirk_drives[] = {
@@ -808,7 +810,7 @@ static void hpt370_irq_timeout(ide_drive
 	/* get DMA command mode */
 	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
 	/* stop DMA */
-	outb(dma_cmd & ~0x1, hwif->dma_base + ATA_DMA_CMD);
+	outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
 	hpt370_clear_engine(drive);
 }
 
@@ -825,22 +827,16 @@ static int hpt370_dma_end(ide_drive_t *d
 	ide_hwif_t *hwif	= drive->hwif;
 	u8  dma_stat		= inb(hwif->dma_base + ATA_DMA_STATUS);
 
-	if (dma_stat & 0x01) {
+	if (dma_stat & ATA_DMA_ACTIVE) {
 		/* wait a little */
 		udelay(20);
 		dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
-		if (dma_stat & 0x01)
+		if (dma_stat & ATA_DMA_ACTIVE)
 			hpt370_irq_timeout(drive);
 	}
 	return ide_dma_end(drive);
 }
 
-static void hpt370_dma_timeout(ide_drive_t *drive)
-{
-	hpt370_irq_timeout(drive);
-	ide_dma_timeout(drive);
-}
-
 /* returns 1 if DMA IRQ issued, 0 otherwise */
 static int hpt374_dma_test_irq(ide_drive_t *drive)
 {
@@ -857,7 +853,7 @@ static int hpt374_dma_test_irq(ide_drive
 
 	dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
 	/* return 1 if INTR asserted */
-	if (dma_stat & 4)
+	if (dma_stat & ATA_DMA_INTR)
 		return 1;
 
 	return 0;
@@ -995,7 +991,7 @@ static void hpt3xx_disable_fast_irq(stru
 		pci_write_config_byte(dev, mcr_addr + 1, new_mcr);
 }
 
-static unsigned int init_chipset_hpt366(struct pci_dev *dev)
+static int init_chipset_hpt366(struct pci_dev *dev)
 {
 	unsigned long io_base	= pci_resource_start(dev, 4);
 	struct hpt_info *info	= hpt3xx_get_info(&dev->dev);
@@ -1237,7 +1233,7 @@ static unsigned int init_chipset_hpt366(
 	hpt3xx_disable_fast_irq(dev, 0x50);
 	hpt3xx_disable_fast_irq(dev, 0x54);
 
-	return dev->irq;
+	return 0;
 }
 
 static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
@@ -1418,36 +1414,34 @@ static const struct ide_port_ops hpt3xx_
 static const struct ide_dma_ops hpt37x_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= hpt374_dma_end,
 	.dma_test_irq		= hpt374_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_dma_ops hpt370_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= hpt370_dma_start,
 	.dma_end		= hpt370_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= hpt370_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
+	.dma_clear		= hpt370_irq_timeout,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_dma_ops hpt36x_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= hpt366_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ht6560b.c linux-libre-2.6.30-gnu1/drivers/ide/ht6560b.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ht6560b.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ht6560b.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@
 /*
  * This routine is invoked from ide.c to prepare for access to a given drive.
  */
-static void ht6560b_selectproc (ide_drive_t *drive)
+static void ht6560b_dev_select(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	unsigned long flags;
@@ -143,6 +143,8 @@ static void ht6560b_selectproc (ide_driv
 #endif
 	}
 	local_irq_restore(flags);
+
+	outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
 }
 
 /*
@@ -305,15 +307,29 @@ static int probe_ht6560b;
 module_param_named(probe, probe_ht6560b, bool, 0);
 MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 
+static const struct ide_tp_ops ht6560b_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= ht6560b_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
+};
+
 static const struct ide_port_ops ht6560b_port_ops = {
 	.init_dev		= ht6560b_init_dev,
 	.set_pio_mode		= ht6560b_set_pio_mode,
-	.selectproc		= ht6560b_selectproc,
 };
 
 static const struct ide_port_info ht6560b_port_info __initdata = {
 	.name			= DRV_NAME,
 	.chipset		= ide_ht6560b,
+	.tp_ops 		= &ht6560b_tp_ops,
 	.port_ops		= &ht6560b_port_ops,
 	.host_flags		= IDE_HFLAG_SERIALIZE | /* is this needed? */
 				  IDE_HFLAG_NO_DMA |
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/icside.c linux-libre-2.6.30-gnu1/drivers/ide/icside.c
--- linux-libre-2.6.29-gnu1/drivers/ide/icside.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/icside.c	2009-06-09 23:05:27.000000000 -0400
@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *d
 	ide_hwif_t *hwif = drive->hwif;
 	struct expansion_card *ec = ECARD_DEV(hwif->dev);
 
-	drive->waiting_for_dma = 0;
-
 	disable_dma(ec->dma);
 
-	/* Teardown mappings after DMA has completed. */
-	ide_destroy_dmatable(drive);
-
 	return get_dma_residue(ec->dma) != 0;
 }
 
@@ -307,15 +302,14 @@ static void icside_dma_start(ide_drive_t
 	enable_dma(ec->dma);
 }
 
-static int icside_dma_setup(ide_drive_t *drive)
+static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct expansion_card *ec = ECARD_DEV(hwif->dev);
 	struct icside_state *state = ecard_get_drvdata(ec);
-	struct request *rq = hwif->rq;
 	unsigned int dma_mode;
 
-	if (rq_data_dir(rq))
+	if (cmd->tf_flags & IDE_TFLAG_WRITE)
 		dma_mode = DMA_MODE_WRITE;
 	else
 		dma_mode = DMA_MODE_READ;
@@ -325,8 +319,6 @@ static int icside_dma_setup(ide_drive_t
 	 */
 	BUG_ON(dma_channel_active(ec->dma));
 
-	hwif->sg_nents = ide_build_sglist(drive, rq);
-
 	/*
 	 * Ensure that we have the right interrupt routed.
 	 */
@@ -346,20 +338,12 @@ static int icside_dma_setup(ide_drive_t
 	 * Tell the DMA engine about the SG table and
 	 * data direction.
 	 */
-	set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents);
+	set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
 	set_dma_mode(ec->dma, dma_mode);
 
-	drive->waiting_for_dma = 1;
-
 	return 0;
 }
 
-static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
-{
-	/* issue cmd to drive */
-	ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
-}
-
 static int icside_dma_test_irq(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -383,11 +367,9 @@ static int icside_dma_init(ide_hwif_t *h
 static const struct ide_dma_ops icside_v6_dma_ops = {
 	.dma_host_set		= icside_dma_host_set,
 	.dma_setup		= icside_dma_setup,
-	.dma_exec_cmd		= icside_dma_exec_cmd,
 	.dma_start		= icside_dma_start,
 	.dma_end		= icside_dma_end,
 	.dma_test_irq		= icside_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
 };
 #else
@@ -419,6 +401,10 @@ static void icside_setup_ports(hw_regs_t
 	hw->chipset = ide_acorn;
 }
 
+static const struct ide_port_info icside_v5_port_info = {
+	.host_flags		= IDE_HFLAG_NO_DMA,
+};
+
 static int __devinit
 icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 {
@@ -445,7 +431,7 @@ icside_register_v5(struct icside_state *
 
 	icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
 
-	host = ide_host_alloc(NULL, hws);
+	host = ide_host_alloc(&icside_v5_port_info, hws);
 	if (host == NULL)
 		return -ENODEV;
 
@@ -453,7 +439,7 @@ icside_register_v5(struct icside_state *
 
 	ecard_set_drvdata(ec, state);
 
-	ret = ide_host_register(host, NULL, hws);
+	ret = ide_host_register(host, &icside_v5_port_info, hws);
 	if (ret)
 		goto err_free;
 
@@ -480,7 +466,7 @@ icside_register_v6(struct icside_state *
 	struct ide_host *host;
 	unsigned int sel = 0;
 	int ret;
-	hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL };
+	hw_regs_t hw[2], *hws[] = { &hw[0], &hw[1], NULL, NULL };
 	struct ide_port_info d = icside_v6_port_info;
 
 	ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-4drives.c linux-libre-2.6.30-gnu1/drivers/ide/ide-4drives.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-4drives.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-4drives.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,8 @@ static const struct ide_port_ops ide_4dr
 
 static const struct ide_port_info ide_4drives_port_info = {
 	.port_ops		= &ide_4drives_port_ops,
-	.host_flags		= IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+	.host_flags		= IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
+				  IDE_HFLAG_4DRIVES,
 };
 
 static int __init ide_4drives_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-acpi.c linux-libre-2.6.30-gnu1/drivers/ide/ide-acpi.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,9 +20,6 @@
 #include <acpi/acpi_bus.h>
 
 #define REGS_PER_GTF		7
-struct taskfile_array {
-	u8	tfa[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
-};
 
 struct GTM_buffer {
 	u32	PIO_speed0;
@@ -89,12 +86,8 @@ static const struct dmi_system_id ide_ac
 	{ }	/* terminate list */
 };
 
-static int ide_acpi_blacklist(void)
+int ide_acpi_init(void)
 {
-	static int done;
-	if (done)
-		return 0;
-	done = 1;
 	dmi_check_system(ide_acpi_dmi_table);
 	return 0;
 }
@@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_han
 }
 
 /**
- * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
- * @drive: device to locate
- *
- * Retrieves the object handle of a given drive. According to the ACPI
- * spec the drive is a child of the hwif.
- *
- * Returns handle on success, 0 on error.
- */
-static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
-{
-	ide_hwif_t	*hwif = drive->hwif;
-	int		 port;
-	acpi_handle	 drive_handle;
-
-	if (!hwif->acpidata)
-		return NULL;
-
-	if (!hwif->acpidata->obj_handle)
-		return NULL;
-
-	port = hwif->channel ? drive->dn - 2: drive->dn;
-
-	DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
-		 drive->name, hwif->channel, port);
-
-
-	/* TBD: could also check ACPI object VALID bits */
-	drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
-	DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
-
-	return drive_handle;
-}
-
-/**
  * do_drive_get_GTF - get the drive bootup default taskfile settings
  * @drive: the drive for which the taskfile settings should be retrieved
  * @gtf_length: number of bytes of _GTF data returned at @gtf_address
@@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t
 	acpi_status			status;
 	struct acpi_buffer		output;
 	union acpi_object 		*out_obj;
-	ide_hwif_t			*hwif = drive->hwif;
-	struct device			*dev = hwif->gendev.parent;
 	int				err = -ENODEV;
-	int				port;
 
 	*gtf_length = 0;
 	*gtf_address = 0UL;
 	*obj_loc = 0UL;
 
-	if (ide_noacpi)
-		return 0;
-
-	if (!dev) {
-		DEBPRINT("no PCI device for %s\n", hwif->name);
-		goto out;
-	}
-
-	if (!hwif->acpidata) {
-		DEBPRINT("no ACPI data for %s\n", hwif->name);
-		goto out;
-	}
-
-	port = hwif->channel ? drive->dn - 2: drive->dn;
-
-	DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
-		 hwif->name, dev_name(dev), port, hwif->channel);
-
-	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
-		DEBPRINT("%s drive %d:%d not present\n",
-			 hwif->name, hwif->channel, port);
-		goto out;
-	}
-
-	/* Get this drive's _ADR info. if not already known. */
 	if (!drive->acpidata->obj_handle) {
-		drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
-		if (!drive->acpidata->obj_handle) {
-			DEBPRINT("No ACPI object found for %s\n",
-				 drive->name);
-			goto out;
-		}
+		DEBPRINT("No ACPI object found for %s\n", drive->name);
+		goto out;
 	}
 
 	/* Setting up output buffer */
@@ -355,43 +282,6 @@ out:
 }
 
 /**
- * taskfile_load_raw - send taskfile registers to drive
- * @drive: drive to which output is sent
- * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
- *
- * Outputs IDE taskfile to the drive.
- */
-static int taskfile_load_raw(ide_drive_t *drive,
-			      const struct taskfile_array *gtf)
-{
-	ide_task_t args;
-	int err = 0;
-
-	DEBPRINT("(0x1f1-1f7): hex: "
-	       "%02x %02x %02x %02x %02x %02x %02x\n",
-	       gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
-	       gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
-	memset(&args, 0, sizeof(ide_task_t));
-
-	/* convert gtf to IDE Taskfile */
-	memcpy(&args.tf_array[7], &gtf->tfa, 7);
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-
-	if (!ide_acpigtf) {
-		DEBPRINT("_GTF execution disabled\n");
-		return err;
-	}
-
-	err = ide_no_data_taskfile(drive, &args);
-	if (err)
-		printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
-		       __func__, err);
-
-	return err;
-}
-
-/**
  * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
  * @drive: the drive to which the taskfile command should be sent
  * @gtf_length: total number of bytes of _GTF taskfiles
@@ -404,43 +294,42 @@ static int do_drive_set_taskfiles(ide_dr
 				  unsigned int gtf_length,
 				  unsigned long gtf_address)
 {
-	int			rc = -ENODEV, err;
+	int			rc = 0, err;
 	int			gtf_count = gtf_length / REGS_PER_GTF;
 	int			ix;
-	struct taskfile_array	*gtf;
-
-	if (ide_noacpi)
-		return 0;
-
-	DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
-
-	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-		goto out;
-
-	if (!gtf_count)		/* shouldn't be here */
-		goto out;
 
 	DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
 		 gtf_length, gtf_length, gtf_count, gtf_address);
 
-	if (gtf_length % REGS_PER_GTF) {
-		printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
-		       __func__, gtf_length);
-		goto out;
-	}
-
-	rc = 0;
+	/* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */
 	for (ix = 0; ix < gtf_count; ix++) {
-		gtf = (struct taskfile_array *)
-			(gtf_address + ix * REGS_PER_GTF);
+		u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF);
+		struct ide_cmd cmd;
 
-		/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
-		err = taskfile_load_raw(drive, gtf);
-		if (err)
+		DEBPRINT("(0x1f1-1f7): "
+			 "hex: %02x %02x %02x %02x %02x %02x %02x\n",
+			 gtf[0], gtf[1], gtf[2],
+			 gtf[3], gtf[4], gtf[5], gtf[6]);
+
+		if (!ide_acpigtf) {
+			DEBPRINT("_GTF execution disabled\n");
+			continue;
+		}
+
+		/* convert GTF to taskfile */
+		memset(&cmd, 0, sizeof(cmd));
+		memcpy(&cmd.tf.feature, gtf, REGS_PER_GTF);
+		cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+		cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+
+		err = ide_no_data_taskfile(drive, &cmd);
+		if (err) {
+			printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
+					__func__, err);
 			rc = err;
+		}
 	}
 
-out:
 	return rc;
 }
 
@@ -647,26 +536,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif
 		DEBPRINT("no ACPI data for %s\n", hwif->name);
 		return;
 	}
+
 	/* channel first and then drives for power on and verse versa for power off */
 	if (on)
 		acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (!drive->acpidata->obj_handle)
-			drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
-
-		if (drive->acpidata->obj_handle &&
-		    (drive->dev_flags & IDE_DFLAG_PRESENT)) {
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		if (drive->acpidata->obj_handle)
 			acpi_bus_set_power(drive->acpidata->obj_handle,
-				on? ACPI_STATE_D0: ACPI_STATE_D3);
-		}
+					   on ? ACPI_STATE_D0 : ACPI_STATE_D3);
 	}
+
 	if (!on)
 		acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
 }
 
 /**
- * ide_acpi_init - initialize the ACPI link for an IDE interface
+ * ide_acpi_init_port - initialize the ACPI link for an IDE interface
  * @hwif: target IDE interface (channel)
  *
  * The ACPI spec is not quite clear when the drive identify buffer
@@ -676,10 +562,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif
  * So we get the information during startup; but this means that
  * any changes during run-time will be lost after resume.
  */
-void ide_acpi_init(ide_hwif_t *hwif)
+void ide_acpi_init_port(ide_hwif_t *hwif)
 {
-	ide_acpi_blacklist();
-
 	hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
 	if (!hwif->acpidata)
 		return;
@@ -708,15 +592,24 @@ void ide_acpi_port_init_devices(ide_hwif
 	hwif->devices[0]->acpidata = &hwif->acpidata->master;
 	hwif->devices[1]->acpidata = &hwif->acpidata->slave;
 
-	/*
-	 * Send IDENTIFY for each drive
-	 */
-	ide_port_for_each_dev(i, drive, hwif) {
-		memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+	/* get _ADR info for each device */
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		acpi_handle dev_handle;
 
-		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-			continue;
+		DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
+			 drive->name, hwif->channel, drive->dn & 1);
+
+		/* TBD: could also check ACPI object VALID bits */
+		dev_handle = acpi_get_child(hwif->acpidata->obj_handle,
+					    drive->dn & 1);
 
+		DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle);
+
+		drive->acpidata->obj_handle = dev_handle;
+	}
+
+	/* send IDENTIFY for each device */
+	ide_port_for_each_present_dev(i, drive, hwif) {
 		err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
 		if (err)
 			DEBPRINT("identify device %s failed (%d)\n",
@@ -736,9 +629,7 @@ void ide_acpi_port_init_devices(ide_hwif
 	ide_acpi_get_timing(hwif);
 	ide_acpi_push_timing(hwif);
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (drive->dev_flags & IDE_DFLAG_PRESENT)
-			/* Execute ACPI startup code */
-			ide_acpi_exec_tfs(drive);
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		ide_acpi_exec_tfs(drive);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide_arm.c linux-libre-2.6.30-gnu1/drivers/ide/ide_arm.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide_arm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide_arm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * ARM default IDE host driver
- *
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- * Based on code by: Russell King, Ian Molton and Alexander Schulz.
- *
- * May be copied or modified under the terms of the GNU General Public License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/irq.h>
-
-#define DRV_NAME "ide_arm"
-
-#define IDE_ARM_IO	0x1f0
-#define IDE_ARM_IRQ	IRQ_HARDDISK
-
-static int __init ide_arm_init(void)
-{
-	unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
-	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
-	if (!request_region(base, 8, DRV_NAME)) {
-		printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
-				DRV_NAME, base, base + 7);
-		return -EBUSY;
-	}
-
-	if (!request_region(ctl, 1, DRV_NAME)) {
-		printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
-				DRV_NAME, ctl);
-		release_region(base, 8);
-		return -EBUSY;
-	}
-
-	memset(&hw, 0, sizeof(hw));
-	ide_std_init_ports(&hw, base, ctl);
-	hw.irq = IDE_ARM_IRQ;
-	hw.chipset = ide_generic;
-
-	return ide_host_add(NULL, hws, NULL);
-}
-
-module_init(ide_arm_init);
-
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-atapi.c linux-libre-2.6.30-gnu1/drivers/ide/ide-atapi.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-atapi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-atapi.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,8 @@
 #include <linux/cdrom.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/scatterlist.h>
+
 #include <scsi/scsi.h>
 
 #ifdef DEBUG
@@ -69,56 +71,6 @@ int ide_check_atapi_device(ide_drive_t *
 }
 EXPORT_SYMBOL_GPL(ide_check_atapi_device);
 
-/* PIO data transfer routine using the scatter gather table. */
-int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
-		    unsigned int bcount, int write)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
-	xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
-	struct scatterlist *sg = pc->sg;
-	char *buf;
-	int count, done = 0;
-
-	while (bcount) {
-		count = min(sg->length - pc->b_count, bcount);
-
-		if (PageHighMem(sg_page(sg))) {
-			unsigned long flags;
-
-			local_irq_save(flags);
-			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
-			xf(drive, NULL, buf + pc->b_count, count);
-			kunmap_atomic(buf - sg->offset, KM_IRQ0);
-			local_irq_restore(flags);
-		} else {
-			buf = sg_virt(sg);
-			xf(drive, NULL, buf + pc->b_count, count);
-		}
-
-		bcount -= count;
-		pc->b_count += count;
-		done += count;
-
-		if (pc->b_count == sg->length) {
-			if (!--pc->sg_cnt)
-				break;
-			pc->sg = sg = sg_next(sg);
-			pc->b_count = 0;
-		}
-	}
-
-	if (bcount) {
-		printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
-			bcount, write ? "padding with zeros"
-				      : "discarding data");
-		ide_pad_transfer(drive, write, bcount);
-	}
-
-	return done;
-}
-EXPORT_SYMBOL_GPL(ide_io_buffers);
-
 void ide_init_pc(struct ide_atapi_pc *pc)
 {
 	memset(pc, 0, sizeof(*pc));
@@ -149,7 +101,10 @@ static void ide_queue_pc_head(ide_drive_
 	memcpy(rq->cmd, pc->c, 12);
 	if (drive->media == ide_tape)
 		rq->cmd[13] = REQ_IDETAPE_PC1;
-	ide_do_drive_cmd(drive, rq);
+
+	drive->hwif->rq = NULL;
+
+	elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
 }
 
 /*
@@ -297,6 +252,18 @@ int ide_cd_get_xferlen(struct request *r
 }
 EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
 
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+	struct ide_taskfile tf;
+
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT |
+				     IDE_VALID_LBAM | IDE_VALID_LBAH);
+
+	*bcount = (tf.lbah << 8) | tf.lbam;
+	*ireason = tf.nsect & 3;
+}
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
 /*
  * This is the usual interrupt handler which will be called during a packet
  * command.  We will transfer some of the data (as requested by the drive)
@@ -306,29 +273,31 @@ static ide_startstop_t ide_pc_intr(ide_d
 {
 	struct ide_atapi_pc *pc = drive->pc;
 	ide_hwif_t *hwif = drive->hwif;
+	struct ide_cmd *cmd = &hwif->cmd;
 	struct request *rq = hwif->rq;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
 	xfer_func_t *xferfunc;
-	unsigned int timeout, temp;
+	unsigned int timeout, done;
 	u16 bcount;
 	u8 stat, ireason, dsc = 0;
+	u8 write = !!(pc->flags & PC_FLAG_WRITING);
 
 	debug_log("Enter %s - interrupt handler\n", __func__);
 
 	timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
 					       : WAIT_TAPE_CMD;
 
-	if (pc->flags & PC_FLAG_TIMEDOUT) {
-		drive->pc_callback(drive, 0);
-		return ide_stopped;
-	}
-
 	/* Clear the interrupt */
 	stat = tp_ops->read_status(hwif);
 
 	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
-		if (hwif->dma_ops->dma_end(drive) ||
-		    (drive->media == ide_tape && (stat & ATA_ERR))) {
+		int rc;
+
+		drive->waiting_for_dma = 0;
+		rc = hwif->dma_ops->dma_end(drive);
+		ide_dma_unmap_sg(drive, cmd);
+
+		if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
 			if (drive->media == ide_floppy)
 				printk(KERN_ERR "%s: DMA %s error\n",
 					drive->name, rq_data_dir(pc->rq)
@@ -344,6 +313,9 @@ static ide_startstop_t ide_pc_intr(ide_d
 
 	/* No more interrupts */
 	if ((stat & ATA_DRQ) == 0) {
+		int uptodate, error;
+		unsigned int done;
+
 		debug_log("Packet command completed, %d bytes transferred\n",
 			  pc->xferred);
 
@@ -382,8 +354,31 @@ static ide_startstop_t ide_pc_intr(ide_d
 			dsc = 1;
 
 		/* Command finished - Call the callback function */
-		drive->pc_callback(drive, dsc);
+		uptodate = drive->pc_callback(drive, dsc);
+
+		if (uptodate == 0)
+			drive->failed_pc = NULL;
+
+		if (blk_special_request(rq)) {
+			rq->errors = 0;
+			done = blk_rq_bytes(rq);
+			error = 0;
+		} else {
+
+			if (blk_fs_request(rq) == 0 && uptodate <= 0) {
+				if (rq->errors == 0)
+					rq->errors = -EIO;
+			}
 
+			if (drive->media == ide_tape)
+				done = ide_rq_bytes(rq); /* FIXME */
+			else
+				done = blk_rq_bytes(rq);
+
+			error = uptodate ? 0 : -EIO;
+		}
+
+		ide_complete_rq(drive, error, done);
 		return ide_stopped;
 	}
 
@@ -403,8 +398,7 @@ static ide_startstop_t ide_pc_intr(ide_d
 		return ide_do_reset(drive);
 	}
 
-	if (((ireason & ATAPI_IO) == ATAPI_IO) ==
-		!!(pc->flags & PC_FLAG_WRITING)) {
+	if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
 		/* Hopefully, we will never get here */
 		printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
 				"to %s!\n", drive->name,
@@ -413,59 +407,54 @@ static ide_startstop_t ide_pc_intr(ide_d
 		return ide_do_reset(drive);
 	}
 
-	if (!(pc->flags & PC_FLAG_WRITING)) {
-		/* Reading - Check that we have enough space */
-		temp = pc->xferred + bcount;
-		if (temp > pc->req_xfer) {
-			if (temp > pc->buf_size) {
-				printk(KERN_ERR "%s: The device wants to send "
-						"us more data than expected - "
-						"discarding data\n",
-						drive->name);
+	xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
 
-				ide_pad_transfer(drive, 0, bcount);
-				goto next_irq;
-			}
-			debug_log("The device wants to send us more data than "
-				  "expected - allowing transfer\n");
-		}
-		xferfunc = tp_ops->input_data;
-	} else
-		xferfunc = tp_ops->output_data;
+	if (drive->media == ide_floppy && pc->buf == NULL) {
+		done = min_t(unsigned int, bcount, cmd->nleft);
+		ide_pio_bytes(drive, cmd, write, done);
+	} else if (drive->media == ide_tape && pc->bh) {
+		done = drive->pc_io_buffers(drive, pc, bcount, write);
+	} else {
+		done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
+		xferfunc(drive, NULL, pc->cur_pos, done);
+	}
 
-	if ((drive->media == ide_floppy && !pc->buf) ||
-	    (drive->media == ide_tape && pc->bh)) {
-		int done = drive->pc_io_buffers(drive, pc, bcount,
-				  !!(pc->flags & PC_FLAG_WRITING));
+	/* Update the current position */
+	pc->xferred += done;
+	pc->cur_pos += done;
 
-		/* FIXME: don't do partial completions */
-		if (drive->media == ide_floppy)
-			ide_end_request(drive, 1, done >> 9);
-	} else
-		xferfunc(drive, NULL, pc->cur_pos, bcount);
+	bcount -= done;
 
-	/* Update the current position */
-	pc->xferred += bcount;
-	pc->cur_pos += bcount;
+	if (bcount)
+		ide_pad_transfer(drive, write, bcount);
+
+	debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
+		  rq->cmd[0], done, bcount);
 
-	debug_log("[cmd %x] transferred %d bytes on that intr.\n",
-		  rq->cmd[0], bcount);
-next_irq:
 	/* And set the interrupt handler again */
-	ide_set_handler(drive, ide_pc_intr, timeout, NULL);
+	ide_set_handler(drive, ide_pc_intr, timeout);
 	return ide_started;
 }
 
-static u8 ide_read_ireason(ide_drive_t *drive)
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf,
+				u16 bcount, u8 dma)
 {
-	ide_task_t task;
+	cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+	cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM |
+			    IDE_VALID_FEATURE | valid_tf;
+	cmd->tf.command = ATA_CMD_PACKET;
+	cmd->tf.feature = dma;		/* Use PIO/DMA */
+	cmd->tf.lbam    = bcount & 0xff;
+	cmd->tf.lbah    = (bcount >> 8) & 0xff;
+}
 
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_IN_NSECT;
+static u8 ide_read_ireason(ide_drive_t *drive)
+{
+	struct ide_taskfile tf;
 
-	drive->hwif->tp_ops->tf_read(drive, &task);
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT);
 
-	return task.tf.nsect & 3;
+	return tf.nsect & 3;
 }
 
 static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -560,11 +549,17 @@ static ide_startstop_t ide_transfer_pc(i
 		}
 	}
 
+	hwif->expiry = expiry;
+
 	/* Set the interrupt routine */
 	ide_set_handler(drive,
 			(dev_is_idecd(drive) ? drive->irq_handler
 					     : ide_pc_intr),
-			timeout, expiry);
+			timeout);
+
+	/* Send the actual packet */
+	if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+		hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
 
 	/* Begin DMA, if necessary */
 	if (dev_is_idecd(drive)) {
@@ -577,30 +572,28 @@ static ide_startstop_t ide_transfer_pc(i
 		}
 	}
 
-	/* Send the actual packet */
-	if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
-		hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
 	return ide_started;
 }
 
-ide_startstop_t ide_issue_pc(ide_drive_t *drive)
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	struct ide_atapi_pc *pc;
 	ide_hwif_t *hwif = drive->hwif;
 	ide_expiry_t *expiry = NULL;
+	struct request *rq = hwif->rq;
 	unsigned int timeout;
-	u32 tf_flags;
 	u16 bcount;
+	u8 valid_tf;
+	u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
 
 	if (dev_is_idecd(drive)) {
-		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
-		bcount = ide_cd_get_xferlen(hwif->rq);
+		valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL;
+		bcount = ide_cd_get_xferlen(rq);
 		expiry = ide_cd_expiry;
 		timeout = ATAPI_WAIT_PC;
 
 		if (drive->dma)
-			drive->dma = !hwif->dma_ops->dma_setup(drive);
+			drive->dma = !ide_dma_prepare(drive, cmd);
 	} else {
 		pc = drive->pc;
 
@@ -608,7 +601,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t
 		pc->xferred = 0;
 		pc->cur_pos = pc->buf;
 
-		tf_flags = IDE_TFLAG_OUT_DEVICE;
+		valid_tf = IDE_VALID_DEVICE;
 		bcount = ((drive->media == ide_tape) ?
 				pc->req_xfer :
 				min(pc->req_xfer, 63 * 1024));
@@ -618,9 +611,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t
 			ide_dma_off(drive);
 		}
 
-		if ((pc->flags & PC_FLAG_DMA_OK) &&
-		     (drive->dev_flags & IDE_DFLAG_USING_DMA))
-			drive->dma = !hwif->dma_ops->dma_setup(drive);
+		if (pc->flags & PC_FLAG_DMA_OK)
+			drive->dma = !ide_dma_prepare(drive, cmd);
 
 		if (!drive->dma)
 			pc->flags &= ~PC_FLAG_DMA_OK;
@@ -629,18 +621,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t
 						       : WAIT_TAPE_CMD;
 	}
 
-	ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
+	ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma);
 
-	/* Issue the packet command */
-	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+	(void)do_rw_taskfile(drive, cmd);
+
+	if (drq_int) {
 		if (drive->dma)
 			drive->waiting_for_dma = 0;
-		ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
-				    timeout, expiry);
-		return ide_started;
-	} else {
-		ide_execute_pkt_cmd(drive);
-		return ide_transfer_pc(drive);
+		hwif->expiry = expiry;
 	}
+
+	ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+	return drq_int ? ide_started : ide_transfer_pc(drive);
 }
 EXPORT_SYMBOL_GPL(ide_issue_pc);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide.c linux-libre-2.6.30-gnu1/drivers/ide/ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,160 +62,6 @@
 
 struct class *ide_port_class;
 
-/*
- *	Locks for IDE setting functionality
- */
-
-DEFINE_MUTEX(ide_setting_mtx);
-
-ide_devset_get(io_32bit, io_32bit);
-
-static int set_io_32bit(ide_drive_t *drive, int arg)
-{
-	if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
-		return -EPERM;
-
-	if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
-		return -EINVAL;
-
-	drive->io_32bit = arg;
-
-	return 0;
-}
-
-ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
-
-static int set_ksettings(ide_drive_t *drive, int arg)
-{
-	if (arg < 0 || arg > 1)
-		return -EINVAL;
-
-	if (arg)
-		drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
-	else
-		drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
-
-	return 0;
-}
-
-ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
-
-static int set_using_dma(ide_drive_t *drive, int arg)
-{
-#ifdef CONFIG_BLK_DEV_IDEDMA
-	int err = -EPERM;
-
-	if (arg < 0 || arg > 1)
-		return -EINVAL;
-
-	if (ata_id_has_dma(drive->id) == 0)
-		goto out;
-
-	if (drive->hwif->dma_ops == NULL)
-		goto out;
-
-	err = 0;
-
-	if (arg) {
-		if (ide_set_dma(drive))
-			err = -EIO;
-	} else
-		ide_dma_off(drive);
-
-out:
-	return err;
-#else
-	if (arg < 0 || arg > 1)
-		return -EINVAL;
-
-	return -EPERM;
-#endif
-}
-
-/*
- * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
- */
-static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
-{
-	switch (req_pio) {
-	case 202:
-	case 201:
-	case 200:
-	case 102:
-	case 101:
-	case 100:
-		return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
-	case 9:
-	case 8:
-		return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
-	case 7:
-	case 6:
-		return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
-	default:
-		return 0;
-	}
-}
-
-static int set_pio_mode(ide_drive_t *drive, int arg)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-
-	if (arg < 0 || arg > 255)
-		return -EINVAL;
-
-	if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
-	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
-		return -ENOSYS;
-
-	if (set_pio_mode_abuse(drive->hwif, arg)) {
-		if (arg == 8 || arg == 9) {
-			unsigned long flags;
-
-			/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
-			spin_lock_irqsave(&hwif->lock, flags);
-			port_ops->set_pio_mode(drive, arg);
-			spin_unlock_irqrestore(&hwif->lock, flags);
-		} else
-			port_ops->set_pio_mode(drive, arg);
-	} else {
-		int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
-
-		ide_set_pio(drive, arg);
-
-		if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
-			if (keep_dma)
-				ide_dma_on(drive);
-		}
-	}
-
-	return 0;
-}
-
-ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
-
-static int set_unmaskirq(ide_drive_t *drive, int arg)
-{
-	if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
-		return -EPERM;
-
-	if (arg < 0 || arg > 1)
-		return -EINVAL;
-
-	if (arg)
-		drive->dev_flags |= IDE_DFLAG_UNMASK;
-	else
-		drive->dev_flags &= ~IDE_DFLAG_UNMASK;
-
-	return 0;
-}
-
-ide_ext_devset_rw_sync(io_32bit, io_32bit);
-ide_ext_devset_rw_sync(keepsettings, ksettings);
-ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
-ide_ext_devset_rw_sync(using_dma, using_dma);
-__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
-
 /**
  * ide_device_get	-	get an additional reference to a ide_drive_t
  * @drive:	device to get a reference to
@@ -527,6 +373,8 @@ static int __init ide_init(void)
 		goto out_port_class;
 	}
 
+	ide_acpi_init();
+
 	proc_ide_create();
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-cd.c linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-cd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright (C) 1994-1996   Scott Snyder <snyder@fnald0.fnal.gov>
  * Copyright (C) 1996-1998   Erik Andersen <andersee@debian.org>
  * Copyright (C) 1998-2000   Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005, 2007  Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2005, 2007-2009  Bartlomiej Zolnierkiewicz
  *
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
@@ -12,12 +12,9 @@
  * See Documentation/cdrom/ide-cd for usage information.
  *
  * Suggestions are welcome. Patches that work are more welcome though. ;-)
- * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
- * anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
+ *
+ * Documentation:
+ *	Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
  *
  * For historical changelog please see:
  *	Documentation/ide/ChangeLog.ide-cd.1994-2004
@@ -100,8 +97,7 @@ static int cdrom_log_sense(ide_drive_t *
 {
 	int log = 0;
 
-	ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__,
-		      sense->sense_key);
+	ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
 
 	if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
 		return 0;
@@ -151,13 +147,12 @@ static void cdrom_analyze_sense_data(ide
 	unsigned long bio_sectors;
 	struct cdrom_info *info = drive->driver_data;
 
-	ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, "
-			"sense_key: 0x%x\n", __func__, sense->error_code,
-			sense->sense_key);
+	ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
+				     sense->error_code, sense->sense_key);
 
 	if (failed_command)
-		ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n",
-				__func__, failed_command->cmd[0]);
+		ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
+					     failed_command->cmd[0]);
 
 	if (!cdrom_log_sense(drive, failed_command, sense))
 		return;
@@ -215,9 +210,9 @@ static void cdrom_queue_request_sense(id
 				      struct request *failed_command)
 {
 	struct cdrom_info *info		= drive->driver_data;
-	struct request *rq		= &info->request_sense_request;
+	struct request *rq		= &drive->request_sense_rq;
 
-	ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_SENSE, "enter");
 
 	if (sense == NULL)
 		sense = &info->sense_data;
@@ -239,106 +234,92 @@ static void cdrom_queue_request_sense(id
 	rq->buffer = (void *) failed_command;
 
 	if (failed_command)
-		ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n",
-			      failed_command->cmd[0]);
+		ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
+					     failed_command->cmd[0]);
 
-	ide_do_drive_cmd(drive, rq);
+	drive->hwif->rq = NULL;
+
+	elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
 }
 
-static void cdrom_end_request(ide_drive_t *drive, int uptodate)
+static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
 {
-	struct request *rq = drive->hwif->rq;
-	int nsectors = rq->hard_cur_sectors;
+	/*
+	 * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+	 * failed request
+	 */
+	struct request *failed = (struct request *)rq->buffer;
+	struct cdrom_info *info = drive->driver_data;
+	void *sense = &info->sense_data;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
-		      "nsectors: %d\n", __func__, rq->cmd[0], uptodate,
-		      nsectors);
+	if (failed) {
+		if (failed->sense) {
+			sense = failed->sense;
+			failed->sense_len = rq->sense_len;
+		}
+		cdrom_analyze_sense_data(drive, failed, sense);
 
-	if (blk_sense_request(rq) && uptodate) {
-		/*
-		 * For REQ_TYPE_SENSE, "rq->buffer" points to the original
-		 * failed request
-		 */
-		struct request *failed = (struct request *) rq->buffer;
-		struct cdrom_info *info = drive->driver_data;
-		void *sense = &info->sense_data;
+		if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
+			BUG();
+	} else
+		cdrom_analyze_sense_data(drive, NULL, sense);
+}
 
-		if (failed) {
-			if (failed->sense) {
-				sense = failed->sense;
-				failed->sense_len = rq->sense_len;
-			}
-			cdrom_analyze_sense_data(drive, failed, sense);
-			/*
-			 * now end the failed request
-			 */
-			if (blk_fs_request(failed)) {
-				if (ide_end_dequeued_request(drive, failed, 0,
-						failed->hard_nr_sectors))
-					BUG();
-			} else {
-				if (blk_end_request(failed, -EIO,
-						    failed->data_len))
-					BUG();
-			}
-		} else
-			cdrom_analyze_sense_data(drive, NULL, sense);
-	}
 
-	if (!rq->current_nr_sectors && blk_fs_request(rq))
-		uptodate = 1;
-	/* make sure it's fully ended */
-	if (blk_pc_request(rq))
-		nsectors = (rq->data_len + 511) >> 9;
-	if (!nsectors)
-		nsectors = 1;
+/*
+ * Allow the drive 5 seconds to recover; some devices will return NOT_READY
+ * while flushing data from cache.
+ *
+ * returns: 0 failed (write timeout expired)
+ *	    1 success
+ */
+static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
+{
 
-	ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n",
-		      __func__, uptodate, nsectors);
+	struct cdrom_info *info = drive->driver_data;
 
-	ide_end_request(drive, uptodate, nsectors);
-}
+	if (!rq->errors)
+		info->write_timeout = jiffies +	ATAPI_WAIT_WRITE_BUSY;
 
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
-{
-	if (st & 0x80)
-		return;
-	ide_dump_status(drive, msg, st);
+	rq->errors = 1;
+
+	if (time_after(jiffies, info->write_timeout))
+		return 0;
+	else {
+		struct request_queue *q = drive->queue;
+		unsigned long flags;
+
+		/*
+		 * take a breather relying on the unplug timer to kick us again
+		 */
+
+		spin_lock_irqsave(q->queue_lock, flags);
+		blk_plug_device(q);
+		spin_unlock_irqrestore(q->queue_lock, flags);
+
+		return 1;
+	}
 }
 
-/*
+/**
  * Returns:
  * 0: if the request should be continued.
- * 1: if the request was ended.
+ * 1: if the request will be going through error recovery.
+ * 2: if the request should be ended.
  */
-static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
+static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq = hwif->rq;
-	int stat, err, sense_key;
-
-	/* check for errors */
-	stat = hwif->tp_ops->read_status(hwif);
-
-	if (stat_ret)
-		*stat_ret = stat;
-
-	if (OK_STAT(stat, good_stat, BAD_R_STAT))
-		return 0;
+	int err, sense_key, do_end_request = 0;
 
 	/* get the IDE error register */
 	err = ide_read_error(drive);
 	sense_key = err >> 4;
 
-	if (rq == NULL) {
-		printk(KERN_ERR PFX "%s: missing rq in %s\n",
-				drive->name, __func__);
-		return 1;
-	}
-
-	ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
-		      "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
-		      __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
+	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, "
+				  "stat 0x%x",
+				  rq->cmd[0], rq->cmd_type, err, stat);
 
 	if (blk_sense_request(rq)) {
 		/*
@@ -347,157 +328,107 @@ static int cdrom_decode_status(ide_drive
 		 * Just give up.
 		 */
 		rq->cmd_flags |= REQ_FAILED;
-		cdrom_end_request(drive, 0);
-		ide_error(drive, "request sense failure", stat);
-		return 1;
+		return 2;
+	}
 
-	} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
-		/* All other functions, except for READ. */
+	/* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
+	if (blk_pc_request(rq) && !rq->errors)
+		rq->errors = SAM_STAT_CHECK_CONDITION;
 
-		/*
-		 * if we have an error, pass back CHECK_CONDITION as the
-		 * scsi status byte
-		 */
-		if (blk_pc_request(rq) && !rq->errors)
-			rq->errors = SAM_STAT_CHECK_CONDITION;
+	if (blk_noretry_request(rq))
+		do_end_request = 1;
 
-		/* check for tray open */
-		if (sense_key == NOT_READY) {
-			cdrom_saw_media_change(drive);
-		} else if (sense_key == UNIT_ATTENTION) {
-			/* check for media change */
+	switch (sense_key) {
+	case NOT_READY:
+		if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
+			if (ide_cd_breathe(drive, rq))
+				return 1;
+		} else {
 			cdrom_saw_media_change(drive);
-			return 0;
-		} else if (sense_key == ILLEGAL_REQUEST &&
-			   rq->cmd[0] == GPCMD_START_STOP_UNIT) {
-			/*
-			 * Don't print error message for this condition--
-			 * SFF8090i indicates that 5/24/00 is the correct
-			 * response to a request to close the tray if the
-			 * drive doesn't have that capability.
-			 * cdrom_log_sense() knows this!
-			 */
-		} else if (!(rq->cmd_flags & REQ_QUIET)) {
-			/* otherwise, print an error */
-			ide_dump_status(drive, "packet command error", stat);
+
+			if (blk_fs_request(rq) && !blk_rq_quiet(rq))
+				printk(KERN_ERR PFX "%s: tray open\n",
+					drive->name);
 		}
+		do_end_request = 1;
+		break;
+	case UNIT_ATTENTION:
+		cdrom_saw_media_change(drive);
 
-		rq->cmd_flags |= REQ_FAILED;
+		if (blk_fs_request(rq) == 0)
+			return 0;
 
 		/*
-		 * instead of playing games with moving completions around,
-		 * remove failed request completely and end it when the
-		 * request sense has completed
+		 * Arrange to retry the request but be sure to give up if we've
+		 * retried too many times.
 		 */
-		goto end_request;
-
-	} else if (blk_fs_request(rq)) {
-		int do_end_request = 0;
-
-		/* handle errors from READ and WRITE requests */
-
-		if (blk_noretry_request(rq))
-			do_end_request = 1;
-
-		if (sense_key == NOT_READY) {
-			/* tray open */
-			if (rq_data_dir(rq) == READ) {
-				cdrom_saw_media_change(drive);
-
-				/* fail the request */
-				printk(KERN_ERR PFX "%s: tray open\n",
-						drive->name);
-				do_end_request = 1;
-			} else {
-				struct cdrom_info *info = drive->driver_data;
-
-				/*
-				 * Allow the drive 5 seconds to recover, some
-				 * devices will return this error while flushing
-				 * data from cache.
-				 */
-				if (!rq->errors)
-					info->write_timeout = jiffies +
-							ATAPI_WAIT_WRITE_BUSY;
-				rq->errors = 1;
-				if (time_after(jiffies, info->write_timeout))
-					do_end_request = 1;
-				else {
-					struct request_queue *q = drive->queue;
-					unsigned long flags;
-
-					/*
-					 * take a breather relying on the unplug
-					 * timer to kick us again
-					 */
-					spin_lock_irqsave(q->queue_lock, flags);
-					blk_plug_device(q);
-					spin_unlock_irqrestore(q->queue_lock, flags);
-
-					return 1;
-				}
-			}
-		} else if (sense_key == UNIT_ATTENTION) {
-			/* media change */
-			cdrom_saw_media_change(drive);
-
-			/*
-			 * Arrange to retry the request but be sure to give up
-			 * if we've retried too many times.
-			 */
-			if (++rq->errors > ERROR_MAX)
-				do_end_request = 1;
-		} else if (sense_key == ILLEGAL_REQUEST ||
-			   sense_key == DATA_PROTECT) {
-			/*
-			 * No point in retrying after an illegal request or data
-			 * protect error.
-			 */
-			ide_dump_status_no_sense(drive, "command error", stat);
-			do_end_request = 1;
-		} else if (sense_key == MEDIUM_ERROR) {
-			/*
-			 * No point in re-trying a zillion times on a bad
-			 * sector. If we got here the error is not correctable.
-			 */
-			ide_dump_status_no_sense(drive,
-						 "media error (bad sector)",
-						 stat);
-			do_end_request = 1;
-		} else if (sense_key == BLANK_CHECK) {
-			/* disk appears blank ?? */
-			ide_dump_status_no_sense(drive, "media error (blank)",
-						 stat);
+		if (++rq->errors > ERROR_MAX)
 			do_end_request = 1;
-		} else if ((err & ~ATA_ABORTED) != 0) {
+		break;
+	case ILLEGAL_REQUEST:
+		/*
+		 * Don't print error message for this condition -- SFF8090i
+		 * indicates that 5/24/00 is the correct response to a request
+		 * to close the tray if the drive doesn't have that capability.
+		 *
+		 * cdrom_log_sense() knows this!
+		 */
+		if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
+			break;
+		/* fall-through */
+	case DATA_PROTECT:
+		/*
+		 * No point in retrying after an illegal request or data
+		 * protect error.
+		 */
+		if (!blk_rq_quiet(rq))
+			ide_dump_status(drive, "command error", stat);
+		do_end_request = 1;
+		break;
+	case MEDIUM_ERROR:
+		/*
+		 * No point in re-trying a zillion times on a bad sector.
+		 * If we got here the error is not correctable.
+		 */
+		if (!blk_rq_quiet(rq))
+			ide_dump_status(drive, "media error "
+					"(bad sector)", stat);
+		do_end_request = 1;
+		break;
+	case BLANK_CHECK:
+		/* disk appears blank? */
+		if (!blk_rq_quiet(rq))
+			ide_dump_status(drive, "media error (blank)",
+					stat);
+		do_end_request = 1;
+		break;
+	default:
+		if (blk_fs_request(rq) == 0)
+			break;
+		if (err & ~ATA_ABORTED) {
 			/* go to the default handler for other errors */
 			ide_error(drive, "cdrom_decode_status", stat);
 			return 1;
-		} else if ((++rq->errors > ERROR_MAX)) {
+		} else if (++rq->errors > ERROR_MAX)
 			/* we've racked up too many retries, abort */
 			do_end_request = 1;
-		}
-
-		/*
-		 * End a request through request sense analysis when we have
-		 * sense data. We need this in order to perform end of media
-		 * processing.
-		 */
-		if (do_end_request)
-			goto end_request;
+	}
 
-		/*
-		 * If we got a CHECK_CONDITION status, queue
-		 * a request sense command.
-		 */
-		if (stat & ATA_ERR)
-			cdrom_queue_request_sense(drive, NULL, NULL);
-	} else {
-		blk_dump_rq_flags(rq, PFX "bad rq");
-		cdrom_end_request(drive, 0);
+	if (blk_fs_request(rq) == 0) {
+		rq->cmd_flags |= REQ_FAILED;
+		do_end_request = 1;
 	}
 
-	/* retry, or handle the next request */
+	/*
+	 * End a request through request sense analysis when we have sense data.
+	 * We need this in order to perform end of media processing.
+	 */
+	if (do_end_request)
+		goto end_request;
+
+	/* if we got a CHECK_CONDITION status, queue a request sense command */
+	if (stat & ATA_ERR)
+		cdrom_queue_request_sense(drive, NULL, NULL);
 	return 1;
 
 end_request:
@@ -512,10 +443,9 @@ end_request:
 		hwif->rq = NULL;
 
 		cdrom_queue_request_sense(drive, rq->sense, rq);
+		return 1;
 	} else
-		cdrom_end_request(drive, 0);
-
-	return 1;
+		return 2;
 }
 
 /*
@@ -528,8 +458,7 @@ static int ide_cd_check_ireason(ide_driv
 {
 	ide_hwif_t *hwif = drive->hwif;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n",
-		      __func__, ireason, rw);
+	ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
 
 	/*
 	 * ireason == 0: the drive wants to receive data from us
@@ -560,115 +489,28 @@ static int ide_cd_check_ireason(ide_driv
 	if (rq->cmd_type == REQ_TYPE_ATA_PC)
 		rq->cmd_flags |= REQ_FAILED;
 
-	cdrom_end_request(drive, 0);
 	return -1;
 }
 
-/*
- * Assume that the drive will always provide data in multiples of at least
- * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
- */
-static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
-{
-	ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len);
-
-	if ((len % SECTOR_SIZE) == 0)
-		return 0;
-
-	printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name,
-			__func__, len);
-
-	if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
-		printk(KERN_ERR PFX "This drive is not supported by this "
-				"version of the driver\n");
-	else {
-		printk(KERN_ERR PFX "Trying to limit transfer sizes\n");
-		drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
-	}
-
-	return 1;
-}
-
-static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
-						 struct request *rq)
-{
-	ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__,
-		      rq->cmd_flags);
-
-	if (rq_data_dir(rq) == READ) {
-		unsigned short sectors_per_frame =
-			queue_hardsect_size(drive->queue) >> SECTOR_BITS;
-		int nskip = rq->sector & (sectors_per_frame - 1);
-
-		/*
-		 * If the requested sector doesn't start on a frame boundary,
-		 * we must adjust the start of the transfer so that it does,
-		 * and remember to skip the first few sectors.
-		 *
-		 * If the rq->current_nr_sectors field is larger than the size
-		 * of the buffer, it will mean that we're to skip a number of
-		 * sectors equal to the amount by which rq->current_nr_sectors
-		 * is larger than the buffer size.
-		 */
-		if (nskip > 0) {
-			/* sanity check... */
-			if (rq->current_nr_sectors !=
-			    bio_cur_sectors(rq->bio)) {
-				printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
-						drive->name, __func__,
-						rq->current_nr_sectors);
-				cdrom_end_request(drive, 0);
-				return ide_stopped;
-			}
-			rq->current_nr_sectors += nskip;
-		}
-	}
-
-	/* set up the command */
-	rq->timeout = ATAPI_WAIT_PC;
-
-	return ide_started;
-}
-
-/*
- * Fix up a possibly partially-processed request so that we can start it over
- * entirely, or even put it back on the request queue.
- */
-static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
+static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
+	struct request *rq = cmd->rq;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-	if (rq->buffer != bio_data(rq->bio)) {
-		sector_t n =
-			(rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
-
-		rq->buffer = bio_data(rq->bio);
-		rq->nr_sectors += n;
-		rq->sector -= n;
-	}
-	rq->current_nr_sectors = bio_cur_sectors(rq->bio);
-	rq->hard_cur_sectors = rq->current_nr_sectors;
-	rq->hard_nr_sectors = rq->nr_sectors;
-	rq->hard_sector = rq->sector;
-	rq->q->prep_rq_fn(rq->q, rq);
-}
-
-static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
-{
-	ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
-		      __func__, rq->cmd[0]);
+	ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
 
 	/*
 	 * Some of the trailing request sense fields are optional,
 	 * and some drives don't send them.  Sigh.
 	 */
 	if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
-	    rq->data_len > 0 && rq->data_len <= 5)
-		while (rq->data_len > 0) {
-			*(u8 *)rq->data++ = 0;
-			--rq->data_len;
+	    cmd->nleft > 0 && cmd->nleft <= 5) {
+		unsigned int ofs = cmd->nbytes - cmd->nleft;
+
+		while (cmd->nleft > 0) {
+			*((u8 *)rq->data + ofs++) = 0;
+			cmd->nleft--;
 		}
+	}
 }
 
 int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -684,9 +526,9 @@ int ide_cd_queue_pc(ide_drive_t *drive,
 	if (!sense)
 		sense = &local_sense;
 
-	ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
-		      "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
-		      timeout, cmd_flags);
+	ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
+				  "cmd_flags: 0x%x",
+				  cmd[0], write, timeout, cmd_flags);
 
 	/* start of retry loop */
 	do {
@@ -748,36 +590,39 @@ int ide_cd_queue_pc(ide_drive_t *drive,
 	return (flags & REQ_FAILED) ? -EIO : 0;
 }
 
-/*
- * Called from blk_end_request_callback() after the data of the request is
- * completed and before the request itself is completed. By returning value '1',
- * blk_end_request_callback() returns immediately without completing it.
- */
-static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	return 1;
+	unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
+
+	if (cmd->tf_flags & IDE_TFLAG_WRITE)
+		nr_bytes -= cmd->last_xfer_len;
+
+	if (nr_bytes > 0)
+		ide_complete_rq(drive, 0, nr_bytes);
 }
 
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
+	struct ide_cmd *cmd = &hwif->cmd;
 	struct request *rq = hwif->rq;
-	xfer_func_t *xferfunc;
 	ide_expiry_t *expiry = NULL;
-	int dma_error = 0, dma, stat, thislen, uptodate = 0;
-	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
+	int dma_error = 0, dma, thislen, uptodate = 0;
+	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
+	int sense = blk_sense_request(rq);
 	unsigned int timeout;
 	u16 len;
-	u8 ireason;
+	u8 ireason, stat;
 
-	ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n",
-		      __func__, rq->cmd[0], write);
+	ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write);
 
 	/* check for errors */
 	dma = drive->dma;
 	if (dma) {
 		drive->dma = 0;
+		drive->waiting_for_dma = 0;
 		dma_error = hwif->dma_ops->dma_end(drive);
+		ide_dma_unmap_sg(drive, cmd);
 		if (dma_error) {
 			printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
 					write ? "write" : "read");
@@ -785,31 +630,34 @@ static ide_startstop_t cdrom_newpc_intr(
 		}
 	}
 
-	if (cdrom_decode_status(drive, 0, &stat))
-		return ide_stopped;
+	/* check status */
+	stat = hwif->tp_ops->read_status(hwif);
+
+	if (!OK_STAT(stat, 0, BAD_R_STAT)) {
+		rc = cdrom_decode_status(drive, stat);
+		if (rc) {
+			if (rc == 2)
+				goto out_end;
+			return ide_stopped;
+		}
+	}
 
 	/* using dma, transfer is complete now */
 	if (dma) {
 		if (dma_error)
 			return ide_error(drive, "dma error", stat);
-		if (blk_fs_request(rq)) {
-			ide_end_request(drive, 1, rq->nr_sectors);
-			return ide_stopped;
-		} else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
-			ide_end_request(drive, 1, 1);
-			return ide_stopped;
-		}
-		goto end_request;
+		uptodate = 1;
+		goto out_end;
 	}
 
 	ide_read_bcount_and_ireason(drive, &len, &ireason);
 
-	thislen = blk_fs_request(rq) ? len : rq->data_len;
+	thislen = blk_fs_request(rq) ? len : cmd->nleft;
 	if (thislen > len)
 		thislen = len;
 
-	ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n",
-		      __func__, stat, thislen);
+	ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
+				  stat, thislen);
 
 	/* If DRQ is clear, the command has completed. */
 	if ((stat & ATA_DRQ) == 0) {
@@ -819,135 +667,62 @@ static ide_startstop_t cdrom_newpc_intr(
 			 * Otherwise, complete the command normally.
 			 */
 			uptodate = 1;
-			if (rq->current_nr_sectors > 0) {
+			if (cmd->nleft > 0) {
 				printk(KERN_ERR PFX "%s: %s: data underrun "
-						"(%d blocks)\n",
-						drive->name, __func__,
-						rq->current_nr_sectors);
+					"(%u bytes)\n", drive->name, __func__,
+					cmd->nleft);
 				if (!write)
 					rq->cmd_flags |= REQ_FAILED;
 				uptodate = 0;
 			}
-			cdrom_end_request(drive, uptodate);
-			return ide_stopped;
 		} else if (!blk_pc_request(rq)) {
-			ide_cd_request_sense_fixup(drive, rq);
+			ide_cd_request_sense_fixup(drive, cmd);
 			/* complain if we still have data left to transfer */
-			uptodate = rq->data_len ? 0 : 1;
+			uptodate = cmd->nleft ? 0 : 1;
+			if (uptodate == 0)
+				rq->cmd_flags |= REQ_FAILED;
 		}
-		goto end_request;
+		goto out_end;
 	}
 
 	/* check which way to transfer data */
-	if (ide_cd_check_ireason(drive, rq, len, ireason, write))
-		return ide_stopped;
-
-	if (blk_fs_request(rq)) {
-		if (write == 0) {
-			int nskip;
-
-			if (ide_cd_check_transfer_size(drive, len)) {
-				cdrom_end_request(drive, 0);
-				return ide_stopped;
-			}
-
-			/*
-			 * First, figure out if we need to bit-bucket
-			 * any of the leading sectors.
-			 */
-			nskip = min_t(int, rq->current_nr_sectors
-					   - bio_cur_sectors(rq->bio),
-					   thislen >> 9);
-			if (nskip > 0) {
-				ide_pad_transfer(drive, write, nskip << 9);
-				rq->current_nr_sectors -= nskip;
-				thislen -= (nskip << 9);
-			}
-		}
-	}
+	rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+	if (rc)
+		goto out_end;
 
-	if (ireason == 0) {
-		write = 1;
-		xferfunc = hwif->tp_ops->output_data;
-	} else {
-		write = 0;
-		xferfunc = hwif->tp_ops->input_data;
-	}
+	cmd->last_xfer_len = 0;
 
-	ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, "
-		      "ireason: 0x%x\n", __func__, rq->cmd_type, ireason);
+	ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
+				  "ireason: 0x%x",
+				  rq->cmd_type, ireason);
 
 	/* transfer data */
 	while (thislen > 0) {
-		u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
-		int blen = rq->data_len;
-
-		/* bio backed? */
-		if (rq->bio) {
-			if (blk_fs_request(rq)) {
-				ptr = rq->buffer;
-				blen = rq->current_nr_sectors << 9;
-			} else {
-				ptr = bio_data(rq->bio);
-				blen = bio_iovec(rq->bio)->bv_len;
-			}
-		}
+		int blen = min_t(int, thislen, cmd->nleft);
 
-		if (!ptr) {
-			if (blk_fs_request(rq) && !write)
-				/*
-				 * If the buffers are full, pipe the rest into
-				 * oblivion.
-				 */
-				ide_pad_transfer(drive, 0, thislen);
-			else {
-				printk(KERN_ERR PFX "%s: confused, missing data\n",
-						drive->name);
-				blk_dump_rq_flags(rq, rq_data_dir(rq)
-						  ? "cdrom_newpc_intr, write"
-						  : "cdrom_newpc_intr, read");
-			}
+		if (cmd->nleft == 0)
 			break;
-		}
-
-		if (blen > thislen)
-			blen = thislen;
 
-		xferfunc(drive, NULL, ptr, blen);
+		ide_pio_bytes(drive, cmd, write, blen);
+		cmd->last_xfer_len += blen;
 
 		thislen -= blen;
 		len -= blen;
 
-		if (blk_fs_request(rq)) {
-			rq->buffer += blen;
-			rq->nr_sectors -= (blen >> 9);
-			rq->current_nr_sectors -= (blen >> 9);
-			rq->sector += (blen >> 9);
-
-			if (rq->current_nr_sectors == 0 && rq->nr_sectors)
-				cdrom_end_request(drive, 1);
-		} else {
-			rq->data_len -= blen;
-
-			/*
-			 * The request can't be completed until DRQ is cleared.
-			 * So complete the data, but don't complete the request
-			 * using the dummy function for the callback feature
-			 * of blk_end_request_callback().
-			 */
-			if (rq->bio)
-				blk_end_request_callback(rq, 0, blen,
-						 cdrom_newpc_intr_dummy_cb);
-			else
-				rq->data += blen;
-		}
-		if (!write && blk_sense_request(rq))
+		if (sense && write == 0)
 			rq->sense_len += blen;
 	}
 
 	/* pad, if necessary */
-	if (!blk_fs_request(rq) && len > 0)
-		ide_pad_transfer(drive, write, len);
+	if (len > 0) {
+		if (blk_fs_request(rq) == 0 || write == 0)
+			ide_pad_transfer(drive, write, len);
+		else {
+			printk(KERN_ERR PFX "%s: confused, missing data\n",
+				drive->name);
+			blk_dump_rq_flags(rq, "cdrom_newpc_intr");
+		}
+	}
 
 	if (blk_pc_request(rq)) {
 		timeout = rq->timeout;
@@ -957,24 +732,54 @@ static ide_startstop_t cdrom_newpc_intr(
 			expiry = ide_cd_expiry;
 	}
 
-	ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
+	hwif->expiry = expiry;
+	ide_set_handler(drive, cdrom_newpc_intr, timeout);
 	return ide_started;
 
-end_request:
-	if (blk_pc_request(rq)) {
+out_end:
+	if (blk_pc_request(rq) && rc == 0) {
 		unsigned int dlen = rq->data_len;
 
-		if (dma)
-			rq->data_len = 0;
+		rq->data_len = 0;
 
 		if (blk_end_request(rq, 0, dlen))
 			BUG();
 
 		hwif->rq = NULL;
 	} else {
-		if (!uptodate)
-			rq->cmd_flags |= REQ_FAILED;
-		cdrom_end_request(drive, uptodate);
+		if (sense && uptodate)
+			ide_cd_complete_failed_rq(drive, rq);
+
+		if (blk_fs_request(rq)) {
+			if (cmd->nleft == 0)
+				uptodate = 1;
+		} else {
+			if (uptodate <= 0 && rq->errors == 0)
+				rq->errors = -EIO;
+		}
+
+		if (uptodate == 0)
+			ide_cd_error_cmd(drive, cmd);
+
+		/* make sure it's fully ended */
+		if (blk_pc_request(rq))
+			nsectors = (rq->data_len + 511) >> 9;
+		else
+			nsectors = rq->hard_nr_sectors;
+
+		if (nsectors == 0)
+			nsectors = 1;
+
+		if (blk_fs_request(rq) == 0) {
+			rq->data_len -= (cmd->nbytes - cmd->nleft);
+			if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
+				rq->data_len += cmd->last_xfer_len;
+		}
+
+		ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+		if (sense && rc == 2)
+			ide_error(drive, "request sense failure", stat);
 	}
 	return ide_stopped;
 }
@@ -982,51 +787,48 @@ end_request:
 static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 {
 	struct cdrom_info *cd = drive->driver_data;
+	struct request_queue *q = drive->queue;
 	int write = rq_data_dir(rq) == WRITE;
 	unsigned short sectors_per_frame =
-		queue_hardsect_size(drive->queue) >> SECTOR_BITS;
+		queue_hardsect_size(q) >> SECTOR_BITS;
 
-	ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
-		      "secs_per_frame: %u\n",
-		      __func__, rq->cmd[0], write, sectors_per_frame);
+	ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
+				  "secs_per_frame: %u",
+				  rq->cmd[0], rq->cmd_flags, sectors_per_frame);
 
 	if (write) {
 		/* disk has become write protected */
-		if (get_disk_ro(cd->disk)) {
-			cdrom_end_request(drive, 0);
+		if (get_disk_ro(cd->disk))
 			return ide_stopped;
-		}
 	} else {
 		/*
 		 * We may be retrying this request after an error.  Fix up any
 		 * weirdness which might be present in the request packet.
 		 */
-		ide_cd_restore_request(drive, rq);
+		q->prep_rq_fn(q, rq);
 	}
 
-	/* use DMA, if possible / writes *must* be hardware frame aligned */
+	/* fs requests *must* be hardware frame aligned */
 	if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
-	    (rq->sector & (sectors_per_frame - 1))) {
-		if (write) {
-			cdrom_end_request(drive, 0);
-			return ide_stopped;
-		}
-		drive->dma = 0;
-	} else
-		drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+	    (rq->sector & (sectors_per_frame - 1)))
+		return ide_stopped;
+
+	/* use DMA, if possible */
+	drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
 
 	if (write)
 		cd->devinfo.media_written = 1;
 
+	rq->timeout = ATAPI_WAIT_PC;
+
 	return ide_started;
 }
 
 static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
 
-	ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
-		      "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
-		      rq->cmd_type);
+	ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
+				  rq->cmd[0], rq->cmd_type);
 
 	if (blk_pc_request(rq))
 		rq->cmd_flags |= REQ_QUIET;
@@ -1065,17 +867,18 @@ static void cdrom_do_block_pc(ide_drive_
 static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
 					sector_t block)
 {
-	ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
-		      "rq->cmd_type: 0x%x, block: %llu\n",
-		      __func__, rq->cmd[0], rq->cmd_type,
-		      (unsigned long long)block);
+	struct ide_cmd cmd;
+	int uptodate = 0, nsectors;
+
+	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
+				  rq->cmd[0], (unsigned long long)block);
+
+	if (drive->debug_mask & IDE_DBG_RQ)
+		blk_dump_rq_flags(rq, "ide_cd_do_request");
 
 	if (blk_fs_request(rq)) {
 		if (cdrom_start_rw(drive, rq) == ide_stopped)
-			return ide_stopped;
-
-		if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
-			return ide_stopped;
+			goto out_end;
 	} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
 		   rq->cmd_type == REQ_TYPE_ATA_PC) {
 		if (!rq->timeout)
@@ -1084,15 +887,38 @@ static ide_startstop_t ide_cd_do_request
 		cdrom_do_block_pc(drive, rq);
 	} else if (blk_special_request(rq)) {
 		/* right now this can only be a reset... */
-		cdrom_end_request(drive, 1);
-		return ide_stopped;
+		uptodate = 1;
+		goto out_end;
 	} else {
 		blk_dump_rq_flags(rq, DRV_NAME " bad flags");
-		cdrom_end_request(drive, 0);
-		return ide_stopped;
+		if (rq->errors == 0)
+			rq->errors = -EIO;
+		goto out_end;
 	}
 
-	return ide_issue_pc(drive);
+	memset(&cmd, 0, sizeof(cmd));
+
+	if (rq_data_dir(rq))
+		cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+	cmd.rq = rq;
+
+	if (blk_fs_request(rq) || rq->data_len) {
+		ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
+							 : rq->data_len);
+		ide_map_sg(drive, &cmd);
+	}
+
+	return ide_issue_pc(drive, &cmd);
+out_end:
+	nsectors = rq->hard_nr_sectors;
+
+	if (nsectors == 0)
+		nsectors = 1;
+
+	ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+	return ide_stopped;
 }
 
 /*
@@ -1117,7 +943,7 @@ int cdrom_check_status(ide_drive_t *driv
 	struct cdrom_device_info *cdi = &info->devinfo;
 	unsigned char cmd[BLK_MAX_CDB];
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	memset(cmd, 0, BLK_MAX_CDB);
 	cmd[0] = GPCMD_TEST_UNIT_READY;
@@ -1145,7 +971,7 @@ static int cdrom_read_capacity(ide_drive
 	unsigned len = sizeof(capbuf);
 	u32 blocklen;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	memset(cmd, 0, BLK_MAX_CDB);
 	cmd[0] = GPCMD_READ_CDVD_CAPACITY;
@@ -1177,8 +1003,8 @@ static int cdrom_read_capacity(ide_drive
 	*capacity = 1 + be32_to_cpu(capbuf.lba);
 	*sectors_per_frame = blocklen >> SECTOR_BITS;
 
-	ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
-		      __func__, *capacity, *sectors_per_frame);
+	ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
+				     *capacity, *sectors_per_frame);
 
 	return 0;
 }
@@ -1189,7 +1015,7 @@ static int cdrom_read_tocentry(ide_drive
 {
 	unsigned char cmd[BLK_MAX_CDB];
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	memset(cmd, 0, BLK_MAX_CDB);
 
@@ -1219,7 +1045,7 @@ int ide_cd_read_toc(ide_drive_t *drive,
 	long last_written;
 	unsigned long sectors_per_frame = SECTORS_PER_FRAME;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	if (toc == NULL) {
 		/* try to allocate space */
@@ -1381,7 +1207,7 @@ int ide_cdrom_get_capabilities(ide_drive
 	struct packet_command cgc;
 	int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
 		size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
@@ -1401,7 +1227,7 @@ void ide_cdrom_update_speed(ide_drive_t
 	struct cdrom_info *cd = drive->driver_data;
 	u16 curspeed, maxspeed;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
 		curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
@@ -1411,8 +1237,8 @@ void ide_cdrom_update_speed(ide_drive_t
 		maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
 	}
 
-	ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
-		      __func__, curspeed, maxspeed);
+	ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
+				     curspeed, maxspeed);
 
 	cd->current_speed = (curspeed + (176/2)) / 176;
 	cd->max_speed = (maxspeed + (176/2)) / 176;
@@ -1446,7 +1272,7 @@ static int ide_cdrom_register(ide_drive_
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *devinfo = &info->devinfo;
 
-	ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots);
+	ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
 
 	devinfo->ops = &ide_cdrom_dops;
 	devinfo->speed = info->current_speed;
@@ -1469,9 +1295,8 @@ static int ide_cdrom_probe_capabilities(
 	mechtype_t mechtype;
 	int nslots = 1;
 
-	ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, "
-		      "drive->atapi_flags: 0x%lx\n", __func__, drive->media,
-		      drive->atapi_flags);
+	ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
+				     drive->media, drive->atapi_flags);
 
 	cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
 		     CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
@@ -1685,9 +1510,6 @@ static const struct ide_proc_devset *ide
 #endif
 
 static const struct cd_list_entry ide_cd_quirks_list[] = {
-	/* Limit transfer size per interrupt. */
-	{ "SAMSUNG CD-ROM SCR-2430", NULL,   IDE_AFLAG_LIMIT_NFRAMES	     },
-	{ "SAMSUNG CD-ROM SCR-2432", NULL,   IDE_AFLAG_LIMIT_NFRAMES	     },
 	/* SCR-3231 doesn't support the SET_CD_SPEED command. */
 	{ "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_AFLAG_NO_SPEED_SELECT	     },
 	/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
@@ -1748,18 +1570,18 @@ static int ide_cdrom_setup(ide_drive_t *
 {
 	struct cdrom_info *cd = drive->driver_data;
 	struct cdrom_device_info *cdi = &cd->devinfo;
+	struct request_queue *q = drive->queue;
 	u16 *id = drive->id;
 	char *fw_rev = (char *)&id[ATA_ID_FW_REV];
 	int nslots;
 
-	ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_PROBE, "enter");
 
-	blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
-	blk_queue_dma_alignment(drive->queue, 31);
-	blk_queue_update_dma_pad(drive->queue, 15);
-	drive->queue->unplug_delay = (1 * HZ) / 1000;
-	if (!drive->queue->unplug_delay)
-		drive->queue->unplug_delay = 1;
+	blk_queue_prep_rq(q, ide_cdrom_prep_fn);
+	blk_queue_dma_alignment(q, 31);
+	blk_queue_update_dma_pad(q, 15);
+
+	q->unplug_delay = max((1 * HZ) / 1000, 1);
 
 	drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
 	drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
@@ -1777,8 +1599,7 @@ static int ide_cdrom_setup(ide_drive_t *
 
 	nslots = ide_cdrom_probe_capabilities(drive);
 
-	/* set correct block size */
-	blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+	blk_queue_hardsect_size(q, CD_FRAMESIZE);
 
 	if (ide_cdrom_register(drive, nslots)) {
 		printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1795,7 +1616,7 @@ static void ide_cd_remove(ide_drive_t *d
 {
 	struct cdrom_info *info = drive->driver_data;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	ide_proc_unregister_driver(drive, info->driver);
 	device_del(&info->dev);
@@ -1813,7 +1634,7 @@ static void ide_cd_release(struct device
 	ide_drive_t *drive = info->drive;
 	struct gendisk *g = info->disk;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	kfree(info->toc);
 	if (devinfo->handle == drive)
@@ -1837,7 +1658,6 @@ static struct ide_driver ide_cdrom_drive
 	.remove			= ide_cd_remove,
 	.version		= IDECD_VERSION,
 	.do_request		= ide_cd_do_request,
-	.end_request		= ide_end_request,
 #ifdef CONFIG_IDE_PROC_FS
 	.proc_entries		= ide_cd_proc_entries,
 	.proc_devsets		= ide_cd_proc_devsets,
@@ -1958,9 +1778,6 @@ static struct block_device_operations id
 };
 
 /* module options */
-static char *ignore;
-module_param(ignore, charp, 0400);
-
 static unsigned long debug_mask;
 module_param(debug_mask, ulong, 0644);
 
@@ -1972,9 +1789,8 @@ static int ide_cd_probe(ide_drive_t *dri
 	struct gendisk *g;
 	struct request_sense sense;
 
-	ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, "
-		      "drive->media: 0x%x\n", __func__, drive->driver_req,
-		      drive->media);
+	ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
+				     drive->driver_req, drive->media);
 
 	if (!strstr("ide-cdrom", drive->driver_req))
 		goto failed;
@@ -1982,15 +1798,6 @@ static int ide_cd_probe(ide_drive_t *dri
 	if (drive->media != ide_cdrom && drive->media != ide_optical)
 		goto failed;
 
-	/* skip drives that we were told to ignore */
-	if (ignore != NULL) {
-		if (strstr(ignore, drive->name)) {
-			printk(KERN_INFO PFX "ignoring drive %s\n",
-					 drive->name);
-			goto failed;
-		}
-	}
-
 	drive->debug_mask = debug_mask;
 	drive->irq_handler = cdrom_newpc_intr;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-cd.h linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.h
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-cd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,7 @@
 #define IDECD_DEBUG_LOG		0
 
 #if IDECD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
 #else
 #define ide_debug_log(lvl, fmt, args...) do {} while (0)
 #endif
@@ -91,8 +91,6 @@ struct cdrom_info {
 	   on this device. */
 	struct request_sense sense_data;
 
-	struct request request_sense_request;
-
 	u8 max_speed;		/* Max speed of the drive. */
 	u8 current_speed;	/* Current speed of the drive. */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-cs.c linux-libre-2.6.30-gnu1/drivers/ide/ide-cs.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -154,6 +154,7 @@ static const struct ide_port_ops idecs_p
 static const struct ide_port_info idecs_port_info = {
 	.port_ops		= &idecs_port_ops,
 	.host_flags		= IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
 };
 
 static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-devsets.c linux-libre-2.6.30-gnu1/drivers/ide/ide-devsets.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-devsets.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-devsets.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,188 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+DEFINE_MUTEX(ide_setting_mtx);
+
+ide_devset_get(io_32bit, io_32bit);
+
+static int set_io_32bit(ide_drive_t *drive, int arg)
+{
+	if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
+		return -EPERM;
+
+	if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
+		return -EINVAL;
+
+	drive->io_32bit = arg;
+
+	return 0;
+}
+
+ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
+
+static int set_ksettings(ide_drive_t *drive, int arg)
+{
+	if (arg < 0 || arg > 1)
+		return -EINVAL;
+
+	if (arg)
+		drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
+	else
+		drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
+
+	return 0;
+}
+
+ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
+
+static int set_using_dma(ide_drive_t *drive, int arg)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	int err = -EPERM;
+
+	if (arg < 0 || arg > 1)
+		return -EINVAL;
+
+	if (ata_id_has_dma(drive->id) == 0)
+		goto out;
+
+	if (drive->hwif->dma_ops == NULL)
+		goto out;
+
+	err = 0;
+
+	if (arg) {
+		if (ide_set_dma(drive))
+			err = -EIO;
+	} else
+		ide_dma_off(drive);
+
+out:
+	return err;
+#else
+	if (arg < 0 || arg > 1)
+		return -EINVAL;
+
+	return -EPERM;
+#endif
+}
+
+/*
+ * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
+ */
+static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
+{
+	switch (req_pio) {
+	case 202:
+	case 201:
+	case 200:
+	case 102:
+	case 101:
+	case 100:
+		return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
+	case 9:
+	case 8:
+		return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
+	case 7:
+	case 6:
+		return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
+	default:
+		return 0;
+	}
+}
+
+static int set_pio_mode(ide_drive_t *drive, int arg)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+
+	if (arg < 0 || arg > 255)
+		return -EINVAL;
+
+	if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+		return -ENOSYS;
+
+	if (set_pio_mode_abuse(drive->hwif, arg)) {
+		if (arg == 8 || arg == 9) {
+			unsigned long flags;
+
+			/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
+			spin_lock_irqsave(&hwif->lock, flags);
+			port_ops->set_pio_mode(drive, arg);
+			spin_unlock_irqrestore(&hwif->lock, flags);
+		} else
+			port_ops->set_pio_mode(drive, arg);
+	} else {
+		int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+
+		ide_set_pio(drive, arg);
+
+		if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
+			if (keep_dma)
+				ide_dma_on(drive);
+		}
+	}
+
+	return 0;
+}
+
+ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
+
+static int set_unmaskirq(ide_drive_t *drive, int arg)
+{
+	if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
+		return -EPERM;
+
+	if (arg < 0 || arg > 1)
+		return -EINVAL;
+
+	if (arg)
+		drive->dev_flags |= IDE_DFLAG_UNMASK;
+	else
+		drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+
+	return 0;
+}
+
+ide_ext_devset_rw_sync(io_32bit, io_32bit);
+ide_ext_devset_rw_sync(keepsettings, ksettings);
+ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
+ide_ext_devset_rw_sync(using_dma, using_dma);
+__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
+
+int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
+		       int arg)
+{
+	struct request_queue *q = drive->queue;
+	struct request *rq;
+	int ret = 0;
+
+	if (!(setting->flags & DS_SYNC))
+		return setting->set(drive, arg);
+
+	rq = blk_get_request(q, READ, __GFP_WAIT);
+	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_len = 5;
+	rq->cmd[0] = REQ_DEVSET_EXEC;
+	*(int *)&rq->cmd[1] = arg;
+	rq->special = setting->set;
+
+	if (blk_execute_rq(q, NULL, rq, 0))
+		ret = rq->errors;
+	blk_put_request(rq);
+
+	return ret;
+}
+
+ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
+{
+	int err, (*setfunc)(ide_drive_t *, int) = rq->special;
+
+	err = setfunc(drive, *(int *)&rq->cmd[1]);
+	if (err)
+		rq->errors = err;
+	ide_complete_rq(drive, err, ide_rq_bytes(rq));
+	return ide_stopped;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-disk.c linux-libre-2.6.30-gnu1/drivers/ide/ide-disk.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-disk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-disk.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/mutex.h>
 #include <linux/leds.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -53,33 +52,26 @@ static const u8 ide_rw_cmds[] = {
 	ATA_CMD_WRITE_EXT,
 };
 
-static const u8 ide_data_phases[] = {
-	TASKFILE_MULTI_IN,
-	TASKFILE_MULTI_OUT,
-	TASKFILE_IN,
-	TASKFILE_OUT,
-	TASKFILE_IN_DMA,
-	TASKFILE_OUT_DMA,
-};
-
-static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
+static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
 {
 	u8 index, lba48, write;
 
-	lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
-	write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
+	lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
+	write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
 
-	if (dma)
+	if (dma) {
+		cmd->protocol = ATA_PROT_DMA;
 		index = 8;
-	else
-		index = drive->mult_count ? 0 : 4;
-
-	task->tf.command = ide_rw_cmds[index + lba48 + write];
-
-	if (dma)
-		index = 8; /* fixup index */
+	} else {
+		cmd->protocol = ATA_PROT_PIO;
+		if (drive->mult_count) {
+			cmd->tf_flags |= IDE_TFLAG_MULTI_PIO;
+			index = 0;
+		} else
+			index = 4;
+	}
 
-	task->data_phase = ide_data_phases[index / 2 + write];
+	cmd->tf.command = ide_rw_cmds[index + lba48 + write];
 }
 
 /*
@@ -93,8 +85,8 @@ static ide_startstop_t __ide_do_rw_disk(
 	u16 nsectors		= (u16)rq->nr_sectors;
 	u8 lba48		= !!(drive->dev_flags & IDE_DFLAG_LBA48);
 	u8 dma			= !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
-	ide_task_t		task;
-	struct ide_taskfile	*tf = &task.tf;
+	struct ide_cmd		cmd;
+	struct ide_taskfile	*tf = &cmd.tf;
 	ide_startstop_t		rc;
 
 	if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
@@ -104,41 +96,39 @@ static ide_startstop_t __ide_do_rw_disk(
 			lba48 = 0;
 	}
 
-	if (!dma) {
-		ide_init_sg_cmd(drive, rq);
-		ide_map_sg(drive, rq);
-	}
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
 	if (drive->dev_flags & IDE_DFLAG_LBA) {
 		if (lba48) {
 			pr_debug("%s: LBA=0x%012llx\n", drive->name,
 					(unsigned long long)block);
 
-			tf->hob_nsect = (nsectors >> 8) & 0xff;
-			tf->hob_lbal  = (u8)(block >> 24);
-			if (sizeof(block) != 4) {
-				tf->hob_lbam = (u8)((u64)block >> 32);
-				tf->hob_lbah = (u8)((u64)block >> 40);
-			}
-
 			tf->nsect  = nsectors & 0xff;
 			tf->lbal   = (u8) block;
 			tf->lbam   = (u8)(block >>  8);
 			tf->lbah   = (u8)(block >> 16);
+			tf->device = ATA_LBA;
 
-			task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+			tf = &cmd.hob;
+			tf->nsect = (nsectors >> 8) & 0xff;
+			tf->lbal  = (u8)(block >> 24);
+			if (sizeof(block) != 4) {
+				tf->lbam = (u8)((u64)block >> 32);
+				tf->lbah = (u8)((u64)block >> 40);
+			}
+
+			cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+			cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+			cmd.tf_flags |= IDE_TFLAG_LBA48;
 		} else {
 			tf->nsect  = nsectors & 0xff;
 			tf->lbal   = block;
 			tf->lbam   = block >>= 8;
 			tf->lbah   = block >>= 8;
-			tf->device = (block >> 8) & 0xf;
+			tf->device = ((block >> 8) & 0xf) | ATA_LBA;
 		}
-
-		tf->device |= ATA_LBA;
 	} else {
 		unsigned int sect, head, cyl, track;
 
@@ -156,23 +146,27 @@ static ide_startstop_t __ide_do_rw_disk(
 		tf->device = head;
 	}
 
+	cmd.tf_flags |= IDE_TFLAG_FS;
+
 	if (rq_data_dir(rq))
-		task.tf_flags |= IDE_TFLAG_WRITE;
+		cmd.tf_flags |= IDE_TFLAG_WRITE;
 
-	ide_tf_set_cmd(drive, &task, dma);
-	if (!dma)
-		hwif->data_phase = task.data_phase;
-	task.rq = rq;
+	ide_tf_set_cmd(drive, &cmd, dma);
+	cmd.rq = rq;
 
-	rc = do_rw_taskfile(drive, &task);
+	if (dma == 0) {
+		ide_init_sg_cmd(&cmd, nsectors << 9);
+		ide_map_sg(drive, &cmd);
+	}
+
+	rc = do_rw_taskfile(drive, &cmd);
 
 	if (rc == ide_stopped && dma) {
 		/* fallback to PIO */
-		task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
-		ide_tf_set_cmd(drive, &task, 0);
-		hwif->data_phase = task.data_phase;
-		ide_init_sg_cmd(drive, rq);
-		rc = do_rw_taskfile(drive, &task);
+		cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
+		ide_tf_set_cmd(drive, &cmd, 0);
+		ide_init_sg_cmd(&cmd, nsectors << 9);
+		rc = do_rw_taskfile(drive, &cmd);
 	}
 
 	return rc;
@@ -193,7 +187,9 @@ static ide_startstop_t ide_do_rw_disk(id
 
 	if (!blk_fs_request(rq)) {
 		blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
-		ide_end_request(drive, 0, 0);
+		if (rq->errors == 0)
+			rq->errors = -EIO;
+		ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
 		return ide_stopped;
 	}
 
@@ -216,26 +212,30 @@ static ide_startstop_t ide_do_rw_disk(id
  */
 static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
 {
-	ide_task_t args;
-	struct ide_taskfile *tf = &args.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 	u64 addr = 0;
 
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 	if (lba48)
 		tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
 	else
 		tf->command = ATA_CMD_READ_NATIVE_MAX;
 	tf->device  = ATA_LBA;
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	if (lba48)
-		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
-	/* submit command request */
-	ide_no_data_taskfile(drive, &args);
+
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	if (lba48) {
+		cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+		cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	}
+
+	ide_no_data_taskfile(drive, &cmd);
 
 	/* if OK, compute maximum address value */
-	if ((tf->status & 0x01) == 0)
-		addr = ide_get_lba_addr(tf, lba48) + 1;
+	if (!(tf->status & ATA_ERR))
+		addr = ide_get_lba_addr(&cmd, lba48) + 1;
 
 	return addr;
 }
@@ -246,34 +246,40 @@ static u64 idedisk_read_native_max_addre
  */
 static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
 {
-	ide_task_t args;
-	struct ide_taskfile *tf = &args.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 	u64 addr_set = 0;
 
 	addr_req--;
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(ide_task_t));
+
+	memset(&cmd, 0, sizeof(cmd));
 	tf->lbal     = (addr_req >>  0) & 0xff;
 	tf->lbam     = (addr_req >>= 8) & 0xff;
 	tf->lbah     = (addr_req >>= 8) & 0xff;
 	if (lba48) {
-		tf->hob_lbal = (addr_req >>= 8) & 0xff;
-		tf->hob_lbam = (addr_req >>= 8) & 0xff;
-		tf->hob_lbah = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbal = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbam = (addr_req >>= 8) & 0xff;
+		cmd.hob.lbah = (addr_req >>= 8) & 0xff;
 		tf->command  = ATA_CMD_SET_MAX_EXT;
 	} else {
 		tf->device   = (addr_req >>= 8) & 0x0f;
 		tf->command  = ATA_CMD_SET_MAX;
 	}
 	tf->device |= ATA_LBA;
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	if (lba48)
-		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
-	/* submit command request */
-	ide_no_data_taskfile(drive, &args);
+
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	if (lba48) {
+		cmd.valid.out.hob = IDE_VALID_OUT_HOB;
+		cmd.valid.in.hob  = IDE_VALID_IN_HOB;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	}
+
+	ide_no_data_taskfile(drive, &cmd);
+
 	/* if OK, compute maximum address value */
-	if ((tf->status & 0x01) == 0)
-		addr_set = ide_get_lba_addr(tf, lba48) + 1;
+	if (!(tf->status & ATA_ERR))
+		addr_set = ide_get_lba_addr(&cmd, lba48) + 1;
 
 	return addr_set;
 }
@@ -389,24 +395,24 @@ static int ide_disk_get_capacity(ide_dri
 static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
 {
 	ide_drive_t *drive = q->queuedata;
-	ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
+	struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
 
 	/* FIXME: map struct ide_taskfile on rq->cmd[] */
-	BUG_ON(task == NULL);
+	BUG_ON(cmd == NULL);
 
-	memset(task, 0, sizeof(*task));
+	memset(cmd, 0, sizeof(*cmd));
 	if (ata_id_flush_ext_enabled(drive->id) &&
 	    (drive->capacity64 >= (1UL << 28)))
-		task->tf.command = ATA_CMD_FLUSH_EXT;
+		cmd->tf.command = ATA_CMD_FLUSH_EXT;
 	else
-		task->tf.command = ATA_CMD_FLUSH;
-	task->tf_flags	 = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
-			   IDE_TFLAG_DYN;
-	task->data_phase = TASKFILE_NO_DATA;
+		cmd->tf.command = ATA_CMD_FLUSH;
+	cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd->tf_flags = IDE_TFLAG_DYN;
+	cmd->protocol = ATA_PROT_NODATA;
 
 	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 	rq->cmd_flags |= REQ_SOFTBARRIER;
-	rq->special = task;
+	rq->special = cmd;
 }
 
 ide_devset_get(multcount, mult_count);
@@ -456,15 +462,16 @@ static int set_nowerr(ide_drive_t *drive
 
 static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
 {
-	ide_task_t task;
+	struct ide_cmd cmd;
 
-	memset(&task, 0, sizeof(task));
-	task.tf.feature = feature;
-	task.tf.nsect   = nsect;
-	task.tf.command = ATA_CMD_SET_FEATURES;
-	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.tf.feature = feature;
+	cmd.tf.nsect   = nsect;
+	cmd.tf.command = ATA_CMD_SET_FEATURES;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
-	return ide_no_data_taskfile(drive, &task);
+	return ide_no_data_taskfile(drive, &cmd);
 }
 
 static void update_ordered(ide_drive_t *drive)
@@ -531,15 +538,17 @@ static int set_wcache(ide_drive_t *drive
 
 static int do_idedisk_flushcache(ide_drive_t *drive)
 {
-	ide_task_t args;
+	struct ide_cmd cmd;
 
-	memset(&args, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 	if (ata_id_flush_ext_enabled(drive->id))
-		args.tf.command = ATA_CMD_FLUSH_EXT;
+		cmd.tf.command = ATA_CMD_FLUSH_EXT;
 	else
-		args.tf.command = ATA_CMD_FLUSH;
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	return ide_no_data_taskfile(drive, &args);
+		cmd.tf.command = ATA_CMD_FLUSH;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+
+	return ide_no_data_taskfile(drive, &cmd);
 }
 
 ide_devset_get(acoustic, acoustic);
@@ -711,17 +720,18 @@ static int ide_disk_init_media(ide_drive
 static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
 				 int on)
 {
-	ide_task_t task;
+	struct ide_cmd cmd;
 	int ret;
 
 	if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
 		return 0;
 
-	memset(&task, 0, sizeof(task));
-	task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
-	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
-	ret = ide_no_data_taskfile(drive, &task);
+	ret = ide_no_data_taskfile(drive, &cmd);
 
 	if (ret)
 		drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
@@ -737,6 +747,5 @@ const struct ide_disk_ops ide_ata_disk_o
 	.init_media	= ide_disk_init_media,
 	.set_doorlock	= ide_disk_set_doorlock,
 	.do_request	= ide_do_rw_disk,
-	.end_request	= ide_end_request,
 	.ioctl		= ide_disk_ioctl,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-disk_proc.c linux-libre-2.6.30-gnu1/drivers/ide/ide-disk_proc.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-disk_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-disk_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,38 +1,40 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 #include "ide-disk.h"
 
 static int smart_enable(ide_drive_t *drive)
 {
-	ide_task_t args;
-	struct ide_taskfile *tf = &args.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 
-	memset(&args, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 	tf->feature = ATA_SMART_ENABLE;
 	tf->lbam    = ATA_SMART_LBAM_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->command = ATA_CMD_SMART;
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	return ide_no_data_taskfile(drive, &args);
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+
+	return ide_no_data_taskfile(drive, &cmd);
 }
 
 static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 {
-	ide_task_t args;
-	struct ide_taskfile *tf = &args.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 
-	memset(&args, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 	tf->feature = sub_cmd;
 	tf->nsect   = 0x01;
 	tf->lbam    = ATA_SMART_LBAM_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->command = ATA_CMD_SMART;
-	args.tf_flags	= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	args.data_phase	= TASKFILE_IN;
-	(void) smart_enable(drive);
-	return ide_raw_taskfile(drive, &args, buf, 1);
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	cmd.protocol = ATA_PROT_PIO;
+
+	return ide_raw_taskfile(drive, &cmd, buf, 1);
 }
 
 static int proc_idedisk_read_cache
@@ -67,6 +69,8 @@ static int proc_idedisk_read_smart(char
 	ide_drive_t	*drive = (ide_drive_t *)data;
 	int		len = 0, i = 0;
 
+	(void)smart_enable(drive);
+
 	if (get_smart_data(drive, page, sub_cmd) == 0) {
 		unsigned short *val = (unsigned short *) page;
 		char *out = (char *)val + SECTOR_SIZE;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-dma.c linux-libre-2.6.30-gnu1/drivers/ide/ide-dma.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -89,16 +89,21 @@ static const struct drive_list_entry dri
 ide_startstop_t ide_dma_intr(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
+	struct ide_cmd *cmd = &hwif->cmd;
 	u8 stat = 0, dma_stat = 0;
 
+	drive->waiting_for_dma = 0;
 	dma_stat = hwif->dma_ops->dma_end(drive);
+	ide_dma_unmap_sg(drive, cmd);
 	stat = hwif->tp_ops->read_status(hwif);
 
 	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
 		if (!dma_stat) {
-			struct request *rq = hwif->rq;
-
-			task_end_request(drive, rq, stat);
+			if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+				ide_finish_cmd(drive, cmd, stat);
+			else
+				ide_complete_rq(drive, 0,
+						cmd->rq->nr_sectors << 9);
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -106,7 +111,6 @@ ide_startstop_t ide_dma_intr(ide_drive_t
 	}
 	return ide_error(drive, "dma_intr", stat);
 }
-EXPORT_SYMBOL_GPL(ide_dma_intr);
 
 int ide_dma_good_drive(ide_drive_t *drive)
 {
@@ -114,9 +118,9 @@ int ide_dma_good_drive(ide_drive_t *driv
 }
 
 /**
- *	ide_build_sglist	-	map IDE scatter gather for DMA I/O
- *	@drive: the drive to build the DMA table for
- *	@rq: the request holding the sg list
+ *	ide_dma_map_sg	-	map IDE scatter gather for DMA I/O
+ *	@drive: the drive to map the DMA table for
+ *	@cmd: command
  *
  *	Perform the DMA mapping magic necessary to access the source or
  *	target buffers of a request via DMA.  The lower layers of the
@@ -124,31 +128,28 @@ int ide_dma_good_drive(ide_drive_t *driv
  *	operate in a portable fashion.
  */
 
-int ide_build_sglist(ide_drive_t *drive, struct request *rq)
+static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
 	int i;
 
-	ide_map_sg(drive, rq);
-
-	if (rq_data_dir(rq) == READ)
-		hwif->sg_dma_direction = DMA_FROM_DEVICE;
+	if (cmd->tf_flags & IDE_TFLAG_WRITE)
+		cmd->sg_dma_direction = DMA_TO_DEVICE;
 	else
-		hwif->sg_dma_direction = DMA_TO_DEVICE;
+		cmd->sg_dma_direction = DMA_FROM_DEVICE;
 
-	i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
+	i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
 	if (i) {
-		hwif->orig_sg_nents = hwif->sg_nents;
-		hwif->sg_nents = i;
+		cmd->orig_sg_nents = cmd->sg_nents;
+		cmd->sg_nents = i;
 	}
 
 	return i;
 }
-EXPORT_SYMBOL_GPL(ide_build_sglist);
 
 /**
- *	ide_destroy_dmatable	-	clean up DMA mapping
+ *	ide_dma_unmap_sg	-	clean up DMA mapping
  *	@drive: The drive to unmap
  *
  *	Teardown mappings after DMA has completed. This must be called
@@ -158,14 +159,14 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
  *	time.
  */
 
-void ide_destroy_dmatable(ide_drive_t *drive)
+void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
-	dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents,
-		     hwif->sg_dma_direction);
+	dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
+		     cmd->sg_dma_direction);
 }
-EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
 
 /**
  *	ide_dma_off_quietly	-	Generic DMA kill
@@ -244,12 +245,11 @@ static unsigned int ide_get_mode_mask(id
 	case XFER_UDMA_0:
 		if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
 			break;
-
+		mask = id[ATA_ID_UDMA_MODES];
 		if (port_ops && port_ops->udma_filter)
-			mask = port_ops->udma_filter(drive);
+			mask &= port_ops->udma_filter(drive);
 		else
-			mask = hwif->ultra_mask;
-		mask &= id[ATA_ID_UDMA_MODES];
+			mask &= hwif->ultra_mask;
 
 		/*
 		 * avoid false cable warning from eighty_ninty_three()
@@ -260,18 +260,23 @@ static unsigned int ide_get_mode_mask(id
 		}
 		break;
 	case XFER_MW_DMA_0:
-		if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
-			break;
+		mask = id[ATA_ID_MWDMA_MODES];
+
+		/* Also look for the CF specific MWDMA modes... */
+		if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) {
+			u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1;
+
+			mask |= ((2 << mode) - 1) << 3;
+		}
+
 		if (port_ops && port_ops->mdma_filter)
-			mask = port_ops->mdma_filter(drive);
+			mask &= port_ops->mdma_filter(drive);
 		else
-			mask = hwif->mwdma_mask;
-		mask &= id[ATA_ID_MWDMA_MODES];
+			mask &= hwif->mwdma_mask;
 		break;
 	case XFER_SW_DMA_0:
-		if (id[ATA_ID_FIELD_VALID] & 2) {
-			mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
-		} else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
+		mask = id[ATA_ID_SWDMA_MODES];
+		if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
 			u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
 
 			/*
@@ -279,8 +284,9 @@ static unsigned int ide_get_mode_mask(id
 			 * (the maximum allowed mode is XFER_SW_DMA_2)
 			 */
 			if (mode <= 2)
-				mask = ((2 << mode) - 1) & hwif->swdma_mask;
+				mask = (2 << mode) - 1;
 		}
+		mask &= hwif->swdma_mask;
 		break;
 	default:
 		BUG();
@@ -397,11 +403,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
 		if ((id[ATA_ID_UDMA_MODES] >> 8) &&
 		    (id[ATA_ID_MWDMA_MODES] >> 8))
 			goto err_out;
-	} else if (id[ATA_ID_FIELD_VALID] & 2) {
-		if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
-		    (id[ATA_ID_SWDMA_MODES] >> 8))
-			goto err_out;
-	}
+	} else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
+		   (id[ATA_ID_SWDMA_MODES] >> 8))
+		goto err_out;
+
 	return 0;
 err_out:
 	printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
@@ -455,20 +460,75 @@ void ide_dma_lost_irq(ide_drive_t *drive
 }
 EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
 
-void ide_dma_timeout(ide_drive_t *drive)
+/*
+ * un-busy the port etc, and clear any pending DMA status. we want to
+ * retry the current request in pio mode instead of risking tossing it
+ * all away
+ */
+ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
 {
 	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_dma_ops *dma_ops = hwif->dma_ops;
+	struct ide_cmd *cmd = &hwif->cmd;
+	struct request *rq;
+	ide_startstop_t ret = ide_stopped;
 
-	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+	/*
+	 * end current dma transaction
+	 */
 
-	if (hwif->dma_ops->dma_test_irq(drive))
-		return;
+	if (error < 0) {
+		printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
+		drive->waiting_for_dma = 0;
+		(void)dma_ops->dma_end(drive);
+		ide_dma_unmap_sg(drive, cmd);
+		ret = ide_error(drive, "dma timeout error",
+				hwif->tp_ops->read_status(hwif));
+	} else {
+		printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
+		if (dma_ops->dma_clear)
+			dma_ops->dma_clear(drive);
+		printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+		if (dma_ops->dma_test_irq(drive) == 0) {
+			ide_dump_status(drive, "DMA timeout",
+					hwif->tp_ops->read_status(hwif));
+			drive->waiting_for_dma = 0;
+			(void)dma_ops->dma_end(drive);
+			ide_dma_unmap_sg(drive, cmd);
+		}
+	}
 
-	ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
+	/*
+	 * disable dma for now, but remember that we did so because of
+	 * a timeout -- we'll reenable after we finish this next request
+	 * (or rather the first chunk of it) in pio.
+	 */
+	drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
+	drive->retry_pio++;
+	ide_dma_off_quietly(drive);
 
-	hwif->dma_ops->dma_end(drive);
+	/*
+	 * un-busy drive etc and make sure request is sane
+	 */
+
+	rq = hwif->rq;
+	if (!rq)
+		goto out;
+
+	hwif->rq = NULL;
+
+	rq->errors = 0;
+
+	if (!rq->bio)
+		goto out;
+
+	rq->sector = rq->bio->bi_sector;
+	rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+	rq->hard_cur_sectors = rq->current_nr_sectors;
+	rq->buffer = bio_data(rq->bio);
+out:
+	return ret;
 }
-EXPORT_SYMBOL_GPL(ide_dma_timeout);
 
 void ide_release_dma_engine(ide_hwif_t *hwif)
 {
@@ -505,3 +565,25 @@ int ide_allocate_dma_engine(ide_hwif_t *
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+	const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
+
+	if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+	    (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
+		goto out;
+	ide_map_sg(drive, cmd);
+	if (ide_dma_map_sg(drive, cmd) == 0)
+		goto out_map;
+	if (dma_ops->dma_setup(drive, cmd))
+		goto out_dma_unmap;
+	drive->waiting_for_dma = 1;
+	return 0;
+out_dma_unmap:
+	ide_dma_unmap_sg(drive, cmd);
+out_map:
+	ide_map_sg(drive, cmd);
+out:
+	return 1;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-dma-sff.c linux-libre-2.6.30-gnu1/drivers/ide/ide-dma-sff.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-dma-sff.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-dma-sff.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *dr
 	 * Enable DMA on any drive that has mode2 DMA
 	 * (multi or single) enabled
 	 */
-	if (id[ATA_ID_FIELD_VALID] & 2)	/* regular DMA */
-		if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
-		    (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
-			return 1;
+	if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+	    (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+		return 1;
 
 	/* Consult the list of known "good" drives */
 	if (ide_dma_good_drive(drive))
@@ -111,7 +110,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
  *	May also be invoked from trm290.c
  */
 
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	__le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,11 +119,7 @@ int ide_build_dmatable(ide_drive_t *driv
 	struct scatterlist *sg;
 	u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
 
-	hwif->sg_nents = ide_build_sglist(drive, rq);
-	if (hwif->sg_nents == 0)
-		return 0;
-
-	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+	for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
 		u32 cur_addr, cur_len, xcount, bcount;
 
 		cur_addr = sg_dma_address(sg);
@@ -170,8 +165,6 @@ use_pio_instead:
 	printk(KERN_ERR "%s: %s\n", drive->name,
 		count ? "DMA table too small" : "empty DMA table?");
 
-	ide_destroy_dmatable(drive);
-
 	return 0; /* revert to PIO for this request */
 }
 EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -179,6 +172,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
 /**
  *	ide_dma_setup	-	begin a DMA phase
  *	@drive: target device
+ *	@cmd: command
  *
  *	Build an IDE DMA PRD (IDE speak for scatter gather table)
  *	and then set up the DMA transfer registers for a device
@@ -189,17 +183,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
  *	is returned.
  */
 
-int ide_dma_setup(ide_drive_t *drive)
+int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
-	unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
 	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+	u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
 	u8 dma_stat;
 
 	/* fall back to pio! */
-	if (!ide_build_dmatable(drive, rq)) {
-		ide_map_sg(drive, rq);
+	if (ide_build_dmatable(drive, cmd) == 0) {
+		ide_map_sg(drive, cmd);
 		return 1;
 	}
 
@@ -212,9 +205,9 @@ int ide_dma_setup(ide_drive_t *drive)
 
 	/* specify r/w */
 	if (mmio)
-		writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+		writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
 	else
-		outb(reading, hwif->dma_base + ATA_DMA_CMD);
+		outb(rw, hwif->dma_base + ATA_DMA_CMD);
 
 	/* read DMA status for INTR & ERROR flags */
 	dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -222,13 +215,12 @@ int ide_dma_setup(ide_drive_t *drive)
 	/* clear INTR & ERROR flags */
 	ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
 
-	drive->waiting_for_dma = 1;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ide_dma_setup);
 
 /**
- *	dma_timer_expiry	-	handle a DMA timeout
+ *	ide_dma_sff_timer_expiry	-	handle a DMA timeout
  *	@drive: Drive that timed out
  *
  *	An IDE DMA transfer timed out. In the event of an error we ask
@@ -241,7 +233,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
  *	This can occur if an interrupt is lost or due to hang or bugs.
  */
 
-static int dma_timer_expiry(ide_drive_t *drive)
+int ide_dma_sff_timer_expiry(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -265,14 +257,7 @@ static int dma_timer_expiry(ide_drive_t
 
 	return 0;	/* Status is unknown -- reset the bus */
 }
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
-			    dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry);
 
 void ide_dma_start(ide_drive_t *drive)
 {
@@ -292,8 +277,6 @@ void ide_dma_start(ide_drive_t *drive)
 		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
 		outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
 	}
-
-	wmb();
 }
 EXPORT_SYMBOL_GPL(ide_dma_start);
 
@@ -301,9 +284,7 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
 int ide_dma_end(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	u8 dma_stat = 0, dma_cmd = 0, mask;
-
-	drive->waiting_for_dma = 0;
+	u8 dma_stat = 0, dma_cmd = 0;
 
 	/* stop DMA */
 	if (hwif->host_flags & IDE_HFLAG_MMIO) {
@@ -321,13 +302,10 @@ int ide_dma_end(ide_drive_t *drive)
 	/* clear INTR & ERROR bits */
 	ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
 
-	/* purge DMA mappings */
-	ide_destroy_dmatable(drive);
-	wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
 
 	/* verify good DMA status */
-	mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
-	if ((dma_stat & mask) != ATA_DMA_INTR)
+	if ((dma_stat & CHECK_DMA_MASK) != ATA_DMA_INTR)
 		return 0x10 | dma_stat;
 	return 0;
 }
@@ -346,12 +324,11 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
 const struct ide_dma_ops sff_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 EXPORT_SYMBOL_GPL(sff_dma_ops);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-eh.c linux-libre-2.6.30-gnu1/drivers/ide/ide-eh.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-eh.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-eh.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,440 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
+				     u8 stat, u8 err)
+{
+	ide_hwif_t *hwif = drive->hwif;
+
+	if ((stat & ATA_BUSY) ||
+	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+		/* other bits are useless when BUSY */
+		rq->errors |= ERROR_RESET;
+	} else if (stat & ATA_ERR) {
+		/* err has different meaning on cdrom and tape */
+		if (err == ATA_ABORTED) {
+			if ((drive->dev_flags & IDE_DFLAG_LBA) &&
+			    /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
+			    hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
+				return ide_stopped;
+		} else if ((err & BAD_CRC) == BAD_CRC) {
+			/* UDMA crc error, just retry the operation */
+			drive->crc_count++;
+		} else if (err & (ATA_BBK | ATA_UNC)) {
+			/* retries won't help these */
+			rq->errors = ERROR_MAX;
+		} else if (err & ATA_TRK0NF) {
+			/* help it find track zero */
+			rq->errors |= ERROR_RECAL;
+		}
+	}
+
+	if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
+	    (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+		int nsect = drive->mult_count ? drive->mult_count : 1;
+
+		ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+	}
+
+	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+		ide_kill_rq(drive, rq);
+		return ide_stopped;
+	}
+
+	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+		rq->errors |= ERROR_RESET;
+
+	if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+		++rq->errors;
+		return ide_do_reset(drive);
+	}
+
+	if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+		drive->special.b.recalibrate = 1;
+
+	++rq->errors;
+
+	return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
+				       u8 stat, u8 err)
+{
+	ide_hwif_t *hwif = drive->hwif;
+
+	if ((stat & ATA_BUSY) ||
+	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+		/* other bits are useless when BUSY */
+		rq->errors |= ERROR_RESET;
+	} else {
+		/* add decoding error stuff */
+	}
+
+	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+		/* force an abort */
+		hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+
+	if (rq->errors >= ERROR_MAX) {
+		ide_kill_rq(drive, rq);
+	} else {
+		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+			++rq->errors;
+			return ide_do_reset(drive);
+		}
+		++rq->errors;
+	}
+
+	return ide_stopped;
+}
+
+static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
+				   u8 stat, u8 err)
+{
+	if (drive->media == ide_disk)
+		return ide_ata_error(drive, rq, stat, err);
+	return ide_atapi_error(drive, rq, stat, err);
+}
+
+/**
+ *	ide_error	-	handle an error on the IDE
+ *	@drive: drive the error occurred on
+ *	@msg: message to report
+ *	@stat: status bits
+ *
+ *	ide_error() takes action based on the error returned by the drive.
+ *	For normal I/O that may well include retries. We deal with
+ *	both new-style (taskfile) and old style command handling here.
+ *	In the case of taskfile command handling there is work left to
+ *	do
+ */
+
+ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
+{
+	struct request *rq;
+	u8 err;
+
+	err = ide_dump_status(drive, msg, stat);
+
+	rq = drive->hwif->rq;
+	if (rq == NULL)
+		return ide_stopped;
+
+	/* retry only "normal" I/O: */
+	if (!blk_fs_request(rq)) {
+		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+			struct ide_cmd *cmd = rq->special;
+
+			if (cmd)
+				ide_complete_cmd(drive, cmd, stat, err);
+		} else if (blk_pm_request(rq)) {
+			rq->errors = 1;
+			ide_complete_pm_rq(drive, rq);
+			return ide_stopped;
+		}
+		rq->errors = err;
+		ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
+		return ide_stopped;
+	}
+
+	return __ide_error(drive, rq, stat, err);
+}
+EXPORT_SYMBOL_GPL(ide_error);
+
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+	struct request *rq = drive->hwif->rq;
+
+	if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) {
+		if (err <= 0 && rq->errors == 0)
+			rq->errors = -EIO;
+		ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq));
+	}
+}
+
+/* needed below */
+static ide_startstop_t do_reset1(ide_drive_t *, int);
+
+/*
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation.  If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
+ */
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+	u8 stat;
+
+	tp_ops->dev_select(drive);
+	udelay(10);
+	stat = tp_ops->read_status(hwif);
+
+	if (OK_STAT(stat, 0, ATA_BUSY))
+		printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
+	else {
+		if (time_before(jiffies, hwif->poll_timeout)) {
+			ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+			/* continue polling */
+			return ide_started;
+		}
+		/* end of polling */
+		hwif->polling = 0;
+		printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+			drive->name, stat);
+		/* do it the old fashioned way */
+		return do_reset1(drive, 1);
+	}
+	/* done polling */
+	hwif->polling = 0;
+	ide_complete_drive_reset(drive, 0);
+	return ide_stopped;
+}
+
+static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
+{
+	static const char *err_master_vals[] =
+		{ NULL, "passed", "formatter device error",
+		  "sector buffer error", "ECC circuitry error",
+		  "controlling MPU error" };
+
+	u8 err_master = err & 0x7f;
+
+	printk(KERN_ERR "%s: reset: master: ", hwif->name);
+	if (err_master && err_master < 6)
+		printk(KERN_CONT "%s", err_master_vals[err_master]);
+	else
+		printk(KERN_CONT "error (0x%02x?)", err);
+	if (err & 0x80)
+		printk(KERN_CONT "; slave: failed");
+	printk(KERN_CONT "\n");
+}
+
+/*
+ * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
+ * during an ide reset operation. If the drives have not yet responded,
+ * and we have not yet hit our maximum waiting time, then the timer is restarted
+ * for another 50ms.
+ */
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+	u8 tmp;
+	int err = 0;
+
+	if (port_ops && port_ops->reset_poll) {
+		err = port_ops->reset_poll(drive);
+		if (err) {
+			printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
+				hwif->name, drive->name);
+			goto out;
+		}
+	}
+
+	tmp = hwif->tp_ops->read_status(hwif);
+
+	if (!OK_STAT(tmp, 0, ATA_BUSY)) {
+		if (time_before(jiffies, hwif->poll_timeout)) {
+			ide_set_handler(drive, &reset_pollfunc, HZ/20);
+			/* continue polling */
+			return ide_started;
+		}
+		printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+			hwif->name, tmp);
+		drive->failures++;
+		err = -EIO;
+	} else  {
+		tmp = ide_read_error(drive);
+
+		if (tmp == 1) {
+			printk(KERN_INFO "%s: reset: success\n", hwif->name);
+			drive->failures = 0;
+		} else {
+			ide_reset_report_error(hwif, tmp);
+			drive->failures++;
+			err = -EIO;
+		}
+	}
+out:
+	hwif->polling = 0;	/* done polling */
+	ide_complete_drive_reset(drive, err);
+	return ide_stopped;
+}
+
+static void ide_disk_pre_reset(ide_drive_t *drive)
+{
+	int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
+
+	drive->special.all = 0;
+	drive->special.b.set_geometry = legacy;
+	drive->special.b.recalibrate  = legacy;
+
+	drive->mult_count = 0;
+	drive->dev_flags &= ~IDE_DFLAG_PARKED;
+
+	if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
+	    (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
+		drive->mult_req = 0;
+
+	if (drive->mult_req != drive->mult_count)
+		drive->special.b.set_multmode = 1;
+}
+
+static void pre_reset(ide_drive_t *drive)
+{
+	const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+	if (drive->media == ide_disk)
+		ide_disk_pre_reset(drive);
+	else
+		drive->dev_flags |= IDE_DFLAG_POST_RESET;
+
+	if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
+		if (drive->crc_count)
+			ide_check_dma_crc(drive);
+		else
+			ide_dma_off(drive);
+	}
+
+	if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
+		if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
+			drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+			drive->io_32bit = 0;
+		}
+		return;
+	}
+
+	if (port_ops && port_ops->pre_reset)
+		port_ops->pre_reset(drive);
+
+	if (drive->current_speed != 0xff)
+		drive->desired_speed = drive->current_speed;
+	drive->current_speed = 0xff;
+}
+
+/*
+ * do_reset1() attempts to recover a confused drive by resetting it.
+ * Unfortunately, resetting a disk drive actually resets all devices on
+ * the same interface, so it can really be thought of as resetting the
+ * interface rather than resetting the drive.
+ *
+ * ATAPI devices have their own reset mechanism which allows them to be
+ * individually reset without clobbering other devices on the same interface.
+ *
+ * Unfortunately, the IDE interface does not generate an interrupt to let
+ * us know when the reset operation has finished, so we must poll for this.
+ * Equally poor, though, is the fact that this may a very long time to complete,
+ * (up to 30 seconds worstcase).  So, instead of busy-waiting here for it,
+ * we set a timer to poll at 50ms intervals.
+ */
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct ide_io_ports *io_ports = &hwif->io_ports;
+	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+	const struct ide_port_ops *port_ops;
+	ide_drive_t *tdrive;
+	unsigned long flags, timeout;
+	int i;
+	DEFINE_WAIT(wait);
+
+	spin_lock_irqsave(&hwif->lock, flags);
+
+	/* We must not reset with running handlers */
+	BUG_ON(hwif->handler != NULL);
+
+	/* For an ATAPI device, first try an ATAPI SRST. */
+	if (drive->media != ide_disk && !do_not_try_atapi) {
+		pre_reset(drive);
+		tp_ops->dev_select(drive);
+		udelay(20);
+		tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+		ndelay(400);
+		hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+		hwif->polling = 1;
+		__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+		spin_unlock_irqrestore(&hwif->lock, flags);
+		return ide_started;
+	}
+
+	/* We must not disturb devices in the IDE_DFLAG_PARKED state. */
+	do {
+		unsigned long now;
+
+		prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
+		timeout = jiffies;
+		ide_port_for_each_present_dev(i, tdrive, hwif) {
+			if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
+			    time_after(tdrive->sleep, timeout))
+				timeout = tdrive->sleep;
+		}
+
+		now = jiffies;
+		if (time_before_eq(timeout, now))
+			break;
+
+		spin_unlock_irqrestore(&hwif->lock, flags);
+		timeout = schedule_timeout_uninterruptible(timeout - now);
+		spin_lock_irqsave(&hwif->lock, flags);
+	} while (timeout);
+	finish_wait(&ide_park_wq, &wait);
+
+	/*
+	 * First, reset any device state data we were maintaining
+	 * for any of the drives on this interface.
+	 */
+	ide_port_for_each_dev(i, tdrive, hwif)
+		pre_reset(tdrive);
+
+	if (io_ports->ctl_addr == 0) {
+		spin_unlock_irqrestore(&hwif->lock, flags);
+		ide_complete_drive_reset(drive, -ENXIO);
+		return ide_stopped;
+	}
+
+	/*
+	 * Note that we also set nIEN while resetting the device,
+	 * to mask unwanted interrupts from the interface during the reset.
+	 * However, due to the design of PC hardware, this will cause an
+	 * immediate interrupt due to the edge transition it produces.
+	 * This single interrupt gives us a "fast poll" for drives that
+	 * recover from reset very quickly, saving us the first 50ms wait time.
+	 */
+	/* set SRST and nIEN */
+	tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS);
+	/* more than enough time */
+	udelay(10);
+	/* clear SRST, leave nIEN (unless device is on the quirk list) */
+	tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) |
+			     ATA_DEVCTL_OBS);
+	/* more than enough time */
+	udelay(10);
+	hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+	hwif->polling = 1;
+	__ide_set_handler(drive, &reset_pollfunc, HZ/20);
+
+	/*
+	 * Some weird controller like resetting themselves to a strange
+	 * state when the disks are reset this way. At least, the Winbond
+	 * 553 documentation says that
+	 */
+	port_ops = hwif->port_ops;
+	if (port_ops && port_ops->resetproc)
+		port_ops->resetproc(drive);
+
+	spin_unlock_irqrestore(&hwif->lock, flags);
+	return ide_started;
+}
+
+/*
+ * ide_do_reset() is the entry point to the drive/interface reset code.
+ */
+
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
+{
+	return do_reset1(drive, 0);
+}
+EXPORT_SYMBOL(ide_do_reset);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-floppy.c linux-libre-2.6.30-gnu1/drivers/ide/ide-floppy.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-floppy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-floppy.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,73 +61,20 @@
  */
 #define IDEFLOPPY_PC_DELAY	(HZ/20)	/* default delay for ZIP 100 (50ms) */
 
-/* Error code returned in rq->errors to the higher part of the driver. */
-#define	IDEFLOPPY_ERROR_GENERAL		101
-
-/*
- * Used to finish servicing a request. For read/write requests, we will call
- * ide_end_request to pass to the next buffer.
- */
-static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
-{
-	struct ide_disk_obj *floppy = drive->driver_data;
-	struct request *rq = drive->hwif->rq;
-	int error;
-
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-	switch (uptodate) {
-	case 0:
-		error = IDEFLOPPY_ERROR_GENERAL;
-		break;
-
-	case 1:
-		error = 0;
-		break;
-
-	default:
-		error = uptodate;
-	}
-
-	if (error)
-		floppy->failed_pc = NULL;
-	/* Why does this happen? */
-	if (!rq)
-		return 0;
-	if (!blk_special_request(rq)) {
-		/* our real local end request function */
-		ide_end_request(drive, uptodate, nsecs);
-		return 0;
-	}
-	rq->errors = error;
-	/* fixme: need to move this local also */
-	ide_end_drive_cmd(drive, 0, 0);
-	return 0;
-}
-
-static void idefloppy_update_buffers(ide_drive_t *drive,
-				struct ide_atapi_pc *pc)
-{
-	struct request *rq = pc->rq;
-	struct bio *bio = rq->bio;
-
-	while ((bio = rq->bio) != NULL)
-		ide_floppy_end_request(drive, 1, 0);
-}
-
-static void ide_floppy_callback(ide_drive_t *drive, int dsc)
+static int ide_floppy_callback(ide_drive_t *drive, int dsc)
 {
 	struct ide_disk_obj *floppy = drive->driver_data;
 	struct ide_atapi_pc *pc = drive->pc;
+	struct request *rq = pc->rq;
 	int uptodate = pc->error ? 0 : 1;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
-	if (floppy->failed_pc == pc)
-		floppy->failed_pc = NULL;
+	if (drive->failed_pc == pc)
+		drive->failed_pc = NULL;
 
 	if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
-	    (pc->rq && blk_pc_request(pc->rq)))
+	    (rq && blk_pc_request(rq)))
 		uptodate = 1; /* FIXME */
 	else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
 		u8 *buf = pc->buf;
@@ -139,19 +86,22 @@ static void ide_floppy_callback(ide_driv
 			floppy->progress_indication = buf[15] & 0x80 ?
 				(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
 
-			if (floppy->failed_pc)
-				ide_debug_log(IDE_DBG_PC, "pc = %x, ",
-					      floppy->failed_pc->c[0]);
+			if (drive->failed_pc)
+				ide_debug_log(IDE_DBG_PC, "pc = %x",
+					      drive->failed_pc->c[0]);
 
 			ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
-				      "ascq = %x\n", floppy->sense_key,
+				      "ascq = %x", floppy->sense_key,
 				      floppy->asc, floppy->ascq);
 		} else
 			printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
 			       "Aborting request!\n");
 	}
 
-	ide_floppy_end_request(drive, uptodate, 0);
+	if (blk_special_request(rq))
+		rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
+
+	return uptodate;
 }
 
 static void ide_floppy_report_error(struct ide_disk_obj *floppy,
@@ -170,14 +120,15 @@ static void ide_floppy_report_error(stru
 
 }
 
-static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
-		struct ide_atapi_pc *pc)
+static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
+					   struct ide_cmd *cmd,
+					   struct ide_atapi_pc *pc)
 {
 	struct ide_disk_obj *floppy = drive->driver_data;
 
-	if (floppy->failed_pc == NULL &&
+	if (drive->failed_pc == NULL &&
 	    pc->c[0] != GPCMD_REQUEST_SENSE)
-		floppy->failed_pc = pc;
+		drive->failed_pc = pc;
 
 	/* Set the current packet command */
 	drive->pc = pc;
@@ -186,18 +137,18 @@ static ide_startstop_t idefloppy_issue_p
 		if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
 			ide_floppy_report_error(floppy, pc);
 		/* Giving up */
-		pc->error = IDEFLOPPY_ERROR_GENERAL;
+		pc->error = IDE_DRV_ERROR_GENERAL;
 
-		floppy->failed_pc = NULL;
+		drive->failed_pc = NULL;
 		drive->pc_callback(drive, 0);
 		return ide_stopped;
 	}
 
-	ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries);
+	ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
 
 	pc->retries++;
 
-	return ide_issue_pc(drive);
+	return ide_issue_pc(drive, cmd);
 }
 
 void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -242,8 +193,7 @@ static void idefloppy_create_rw_cmd(ide_
 	int blocks = rq->nr_sectors / floppy->bs_factor;
 	int cmd = rq_data_dir(rq);
 
-	ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__,
-		      block, blocks);
+	ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
 
 	ide_init_pc(pc);
 	pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
@@ -253,7 +203,6 @@ static void idefloppy_create_rw_cmd(ide_
 	memcpy(rq->cmd, pc->c, 12);
 
 	pc->rq = rq;
-	pc->b_count = 0;
 	if (rq->cmd_flags & REQ_RW)
 		pc->flags |= PC_FLAG_WRITING;
 	pc->buf = NULL;
@@ -267,7 +216,6 @@ static void idefloppy_blockpc_cmd(struct
 	ide_init_pc(pc);
 	memcpy(pc->c, rq->cmd, sizeof(pc->c));
 	pc->rq = rq;
-	pc->b_count = 0;
 	if (rq->data_len && rq_data_dir(rq) == WRITE)
 		pc->flags |= PC_FLAG_WRITING;
 	pc->buf = rq->data;
@@ -284,35 +232,36 @@ static ide_startstop_t ide_floppy_do_req
 					     struct request *rq, sector_t block)
 {
 	struct ide_disk_obj *floppy = drive->driver_data;
-	ide_hwif_t *hwif = drive->hwif;
+	struct ide_cmd cmd;
 	struct ide_atapi_pc *pc;
 
-	ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
-		      "errors: %d\n",
-		      __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
-		      rq->cmd[0], rq->cmd_type, rq->errors);
+	ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]);
 
-	ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
-		      "current_nr_sectors: %d\n",
-		      __func__, (long)rq->sector, rq->nr_sectors,
-		      rq->current_nr_sectors);
+	if (drive->debug_mask & IDE_DBG_RQ)
+		blk_dump_rq_flags(rq, (rq->rq_disk
+					? rq->rq_disk->disk_name
+					: "dev?"));
 
 	if (rq->errors >= ERROR_MAX) {
-		if (floppy->failed_pc)
-			ide_floppy_report_error(floppy, floppy->failed_pc);
-		else
+		if (drive->failed_pc) {
+			ide_floppy_report_error(floppy, drive->failed_pc);
+			drive->failed_pc = NULL;
+		} else
 			printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
 
-		ide_floppy_end_request(drive, 0, 0);
-		return ide_stopped;
+		if (blk_special_request(rq)) {
+			rq->errors = 0;
+			ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+			return ide_stopped;
+		} else
+			goto out_end;
 	}
 	if (blk_fs_request(rq)) {
 		if (((long)rq->sector % floppy->bs_factor) ||
 		    (rq->nr_sectors % floppy->bs_factor)) {
 			printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
 				drive->name);
-			ide_floppy_end_request(drive, 0, 0);
-			return ide_stopped;
+			goto out_end;
 		}
 		pc = &floppy->queued_pc;
 		idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
@@ -323,21 +272,30 @@ static ide_startstop_t ide_floppy_do_req
 		idefloppy_blockpc_cmd(floppy, pc, rq);
 	} else {
 		blk_dump_rq_flags(rq, PFX "unsupported command in queue");
-		ide_floppy_end_request(drive, 0, 0);
-		return ide_stopped;
+		goto out_end;
 	}
 
+	memset(&cmd, 0, sizeof(cmd));
+
+	if (rq_data_dir(rq))
+		cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+	cmd.rq = rq;
+
 	if (blk_fs_request(rq) || pc->req_xfer) {
-		ide_init_sg_cmd(drive, rq);
-		ide_map_sg(drive, rq);
+		ide_init_sg_cmd(&cmd, pc->req_xfer);
+		ide_map_sg(drive, &cmd);
 	}
 
-	pc->sg = hwif->sg_table;
-	pc->sg_cnt = hwif->sg_nents;
-
 	pc->rq = rq;
 
-	return idefloppy_issue_pc(drive, pc);
+	return ide_floppy_issue_pc(drive, &cmd, pc);
+out_end:
+	drive->failed_pc = NULL;
+	if (blk_fs_request(rq) == 0 && rq->errors == 0)
+		rq->errors = -EIO;
+	ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+	return ide_stopped;
 }
 
 /*
@@ -413,9 +371,11 @@ static int ide_floppy_get_capacity(ide_d
 	struct gendisk *disk = floppy->disk;
 	struct ide_atapi_pc pc;
 	u8 *cap_desc;
-	u8 header_len, desc_cnt;
+	u8 pc_buf[256], header_len, desc_cnt;
 	int i, rc = 1, blocks, length;
 
+	ide_debug_log(IDE_DBG_FUNC, "enter");
+
 	drive->bios_cyl = 0;
 	drive->bios_head = drive->bios_sect = 0;
 	floppy->blocks = 0;
@@ -423,6 +383,9 @@ static int ide_floppy_get_capacity(ide_d
 	drive->capacity64 = 0;
 
 	ide_floppy_create_read_capacity_cmd(&pc);
+	pc.buf = &pc_buf[0];
+	pc.buf_size = sizeof(pc_buf);
+
 	if (ide_queue_pc_tail(drive, disk, &pc)) {
 		printk(KERN_ERR PFX "Can't get floppy parameters\n");
 		return 1;
@@ -438,8 +401,9 @@ static int ide_floppy_get_capacity(ide_d
 		length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
 
 		ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
-			      "%d sector size\n",
-			      i, blocks * length / 1024, blocks, length);
+					     "%d sector size",
+					     i, blocks * length / 1024,
+					     blocks, length);
 
 		if (i)
 			continue;
@@ -495,8 +459,8 @@ static int ide_floppy_get_capacity(ide_d
 				"in drive\n", drive->name);
 			break;
 		}
-		ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n",
-			      pc.buf[desc_start + 4] & 0x03);
+		ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
+					     pc.buf[desc_start + 4] & 0x03);
 	}
 
 	/* Clik! disk does not support get_flexible_disk_page */
@@ -512,8 +476,6 @@ static void ide_floppy_setup(ide_drive_t
 	u16 *id = drive->id;
 
 	drive->pc_callback	 = ide_floppy_callback;
-	drive->pc_update_buffers = idefloppy_update_buffers;
-	drive->pc_io_buffers	 = ide_io_buffers;
 
 	/*
 	 * We used to check revisions here. At this point however I'm giving up.
@@ -575,6 +537,5 @@ const struct ide_disk_ops ide_atapi_disk
 	.init_media	= ide_floppy_init_media,
 	.set_doorlock	= ide_set_media_lock,
 	.do_request	= ide_floppy_do_request,
-	.end_request	= ide_floppy_end_request,
 	.ioctl		= ide_floppy_ioctl,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-floppy_ioctl.c linux-libre-2.6.30-gnu1/drivers/ide/ide-floppy_ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-floppy_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-floppy_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacit
 					    int __user *arg)
 {
 	struct ide_disk_obj *floppy = drive->driver_data;
-	u8 header_len, desc_cnt;
 	int i, blocks, length, u_array_size, u_index;
 	int __user *argp;
+	u8 pc_buf[256], header_len, desc_cnt;
 
 	if (get_user(u_array_size, arg))
 		return -EFAULT;
@@ -47,6 +47,9 @@ static int ide_floppy_get_format_capacit
 		return -EINVAL;
 
 	ide_floppy_create_read_capacity_cmd(pc);
+	pc->buf = &pc_buf[0];
+	pc->buf_size = sizeof(pc_buf);
+
 	if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
 		printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
 		return -EIO;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-gd.c linux-libre-2.6.30-gnu1/drivers/ide/ide-gd.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-gd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-gd.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/mutex.h>
 #include <linux/ide.h>
 #include <linux/hdreg.h>
+#include <linux/dmi.h>
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define IDE_DISK_MINORS		(1 << PARTN_BITS)
@@ -99,6 +100,19 @@ static void ide_gd_resume(ide_drive_t *d
 		(void)drive->disk_ops->get_capacity(drive);
 }
 
+static const struct dmi_system_id ide_coldreboot_table[] = {
+	{
+		/* Acer TravelMate 66x cuts power during reboot */
+		.ident   = "Acer TravelMate 660",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
+		},
+	},
+
+	{ }	/* terminate list */
+};
+
 static void ide_gd_shutdown(ide_drive_t *drive)
 {
 #ifdef	CONFIG_ALPHA
@@ -115,7 +129,8 @@ static void ide_gd_shutdown(ide_drive_t
 	   the disk to expire its write cache. */
 	if (system_state != SYSTEM_POWER_OFF) {
 #else
-	if (system_state == SYSTEM_RESTART) {
+	if (system_state == SYSTEM_RESTART &&
+		!dmi_check_system(ide_coldreboot_table)) {
 #endif
 		drive->disk_ops->flush(drive);
 		return;
@@ -145,11 +160,6 @@ static ide_startstop_t ide_gd_do_request
 	return drive->disk_ops->do_request(drive, rq, sector);
 }
 
-static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
-{
-	return drive->disk_ops->end_request(drive, uptodate, nrsecs);
-}
-
 static struct ide_driver ide_gd_driver = {
 	.gen_driver = {
 		.owner		= THIS_MODULE,
@@ -162,7 +172,6 @@ static struct ide_driver ide_gd_driver =
 	.shutdown		= ide_gd_shutdown,
 	.version		= IDE_GD_VERSION,
 	.do_request		= ide_gd_do_request,
-	.end_request		= ide_gd_end_request,
 #ifdef CONFIG_IDE_PROC_FS
 	.proc_entries		= ide_disk_proc_entries,
 	.proc_devsets		= ide_disk_proc_devsets,
@@ -182,7 +191,7 @@ static int ide_gd_open(struct block_devi
 
 	drive = idkp->drive;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	idkp->openers++;
 
@@ -232,7 +241,7 @@ static int ide_gd_release(struct gendisk
 	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
 	ide_drive_t *drive = idkp->drive;
 
-	ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	if (idkp->openers == 1)
 		drive->disk_ops->flush(drive);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-gd.h linux-libre-2.6.30-gnu1/drivers/ide/ide-gd.h
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-gd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-gd.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
 #define IDE_GD_DEBUG_LOG	0
 
 #if IDE_GD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
 #else
 #define ide_debug_log(lvl, fmt, args...) do {} while (0)
 #endif
@@ -20,8 +20,6 @@ struct ide_disk_obj {
 	struct device		dev;
 	unsigned int		openers;	/* protected by BKL for now */
 
-	/* Last failed packet command */
-	struct ide_atapi_pc *failed_pc;
 	/* used for blk_{fs,pc}_request() requests */
 	struct ide_atapi_pc queued_pc;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-generic.c linux-libre-2.6.30-gnu1/drivers/ide/ide-generic.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,27 +1,22 @@
 /*
  * generic/default IDE host driver
  *
- * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
  * This code was split off from ide.c.  See it for original copyrights.
  *
  * May be copied or modified under the terms of the GNU General Public License.
  */
 
-/*
- * For special cases new interfaces may be added using sysfs, i.e.
- *
- *	echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
- *
- * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
- */
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/ide.h>
 #include <linux/pci_ids.h>
 
-/* FIXME: convert m32r to use ide_platform host driver */
+/* FIXME: convert arm and m32r to use ide_platform host driver */
+#ifdef CONFIG_ARM
+#include <asm/irq.h>
+#endif
 #ifdef CONFIG_M32R
 #include <asm/m32r.h>
 #endif
@@ -32,62 +27,15 @@ static int probe_mask;
 module_param(probe_mask, int, 0);
 MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
 
-static ssize_t store_add(struct class *cls, const char *buf, size_t n)
-{
-	unsigned int base, ctl;
-	int irq, rc;
-	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
-	if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
-		return -EINVAL;
-
-	memset(&hw, 0, sizeof(hw));
-	ide_std_init_ports(&hw, base, ctl);
-	hw.irq = irq;
-	hw.chipset = ide_generic;
-
-	rc = ide_host_add(NULL, hws, NULL);
-	if (rc)
-		return rc;
-
-	return n;
-};
-
-static struct class_attribute ide_generic_class_attrs[] = {
-	__ATTR(add, S_IWUSR, NULL, store_add),
-	__ATTR_NULL
+static const struct ide_port_info ide_generic_port_info = {
+	.host_flags		= IDE_HFLAG_NO_DMA,
 };
 
-static void ide_generic_class_release(struct class *cls)
-{
-	kfree(cls);
-}
-
-static int __init ide_generic_sysfs_init(void)
-{
-	struct class *cls;
-	int rc;
-
-	cls = kzalloc(sizeof(*cls), GFP_KERNEL);
-	if (!cls)
-		return -ENOMEM;
-
-	cls->name = DRV_NAME;
-	cls->owner = THIS_MODULE;
-	cls->class_release = ide_generic_class_release;
-	cls->class_attrs = ide_generic_class_attrs;
-
-	rc = class_register(cls);
-	if (rc) {
-		kfree(cls);
-		return rc;
-	}
-
-	return 0;
-}
-
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
-	|| defined(CONFIG_PLAT_OPSPUT)
+#ifdef CONFIG_ARM
+static const u16 legacy_bases[] = { 0x1f0 };
+static const int legacy_irqs[]  = { IRQ_HARDDISK };
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
+      defined(CONFIG_PLAT_OPSPUT)
 static const u16 legacy_bases[] = { 0x1f0 };
 static const int legacy_irqs[]  = { PLD_IRQ_CFIREQ };
 #elif defined(CONFIG_PLAT_MAPPI3)
@@ -103,11 +51,11 @@ static const int legacy_irqs[]  = { 14,
 
 static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
 {
+#ifdef CONFIG_PCI
 	struct pci_dev *p = NULL;
 	u16 val;
 
 	for_each_pci_dev(p) {
-
 		if (pci_resource_start(p, 0) == 0x1f0)
 			*primary = 1;
 		if (pci_resource_start(p, 2) == 0x170)
@@ -122,7 +70,6 @@ static void ide_generic_check_pci_legacy
 		/* Intel MPIIX - PIO ATA on non PCI side of bridge */
 		if (p->vendor == PCI_VENDOR_ID_INTEL &&
 		    p->device == PCI_DEVICE_ID_INTEL_82371MX) {
-
 			pci_read_config_word(p, 0x6C, &val);
 			if (val & 0x8000) {
 				/* ATA port enabled */
@@ -133,6 +80,7 @@ static void ide_generic_check_pci_legacy
 			}
 		}
 	}
+#endif
 }
 
 static int __init ide_generic_init(void)
@@ -164,6 +112,7 @@ static int __init ide_generic_init(void)
 				printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
 						"not free.\n",
 						DRV_NAME, io_addr, io_addr + 7);
+				rc = -EBUSY;
 				continue;
 			}
 
@@ -172,6 +121,7 @@ static int __init ide_generic_init(void)
 						"not free.\n",
 						DRV_NAME, io_addr + 0x206);
 				release_region(io_addr, 8);
+				rc = -EBUSY;
 				continue;
 			}
 
@@ -184,7 +134,7 @@ static int __init ide_generic_init(void)
 #endif
 			hw.chipset = ide_generic;
 
-			rc = ide_host_add(NULL, hws, NULL);
+			rc = ide_host_add(&ide_generic_port_info, hws, NULL);
 			if (rc) {
 				release_region(io_addr + 0x206, 1);
 				release_region(io_addr, 8);
@@ -192,10 +142,6 @@ static int __init ide_generic_init(void)
 		}
 	}
 
-	if (ide_generic_sysfs_init())
-		printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
-					 "class\n");
-
 	return rc;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-h8300.c linux-libre-2.6.30-gnu1/drivers/ide/ide-h8300.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-h8300.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-h8300.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,113 +22,6 @@
 	(r);				\
 })
 
-static void mm_outw(u16 d, unsigned long a)
-{
-	__asm__("mov.b %w0,r2h\n\t"
-		"mov.b %x0,r2l\n\t"
-		"mov.w r2,@%1"
-		:
-		:"r"(d),"r"(a)
-		:"er2");
-}
-
-static u16 mm_inw(unsigned long a)
-{
-	register u16 r __asm__("er0");
-	__asm__("mov.w @%1,r2\n\t"
-		"mov.b r2l,%x0\n\t"
-		"mov.b r2h,%w0"
-		:"=r"(r)
-		:"r"(a)
-		:"er2");
-	return r;
-}
-
-static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA)
-		mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-		outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-		outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-		outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-		outb(tf->lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		outb((tf->device & HIHI) | drive->select,
-		     io_ports->device_addr);
-}
-
-static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data = mm_inw(io_ports->data_addr);
-
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature = inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = inb(io_ports->lbah_addr);
-	}
-}
-
 static void mm_outsw(unsigned long addr, void *buf, u32 len)
 {
 	unsigned short *bp = (unsigned short *)buf;
@@ -143,13 +36,13 @@ static void mm_insw(unsigned long addr,
 		*bp = bswap(*(volatile u16 *)addr);
 }
 
-static void h8300_input_data(ide_drive_t *drive, struct request *rq,
+static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			     void *buf, unsigned int len)
 {
 	mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
 }
 
-static void h8300_output_data(ide_drive_t *drive, struct request *rq,
+static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			      void *buf, unsigned int len)
 {
 	mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -159,11 +52,11 @@ static const struct ide_tp_ops h8300_tp_
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
-	.tf_load		= h8300_tf_load,
-	.tf_read		= h8300_tf_read,
+	.dev_select		= ide_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= h8300_input_data,
 	.output_data		= h8300_output_data,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-io.c linux-libre-2.6.30-gnu1/drivers/ide/ide-io.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-io.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,7 +40,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 #include <linux/completion.h>
 #include <linux/reboot.h>
 #include <linux/cdrom.h>
@@ -55,25 +54,9 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-static int __ide_end_request(ide_drive_t *drive, struct request *rq,
-			     int uptodate, unsigned int nr_bytes, int dequeue)
+int ide_end_rq(ide_drive_t *drive, struct request *rq, int error,
+	       unsigned int nr_bytes)
 {
-	int ret = 1;
-	int error = 0;
-
-	if (uptodate <= 0)
-		error = uptodate ? uptodate : -EIO;
-
-	/*
-	 * if failfast is set on a request, override number of sectors and
-	 * complete the whole request right now
-	 */
-	if (blk_noretry_request(rq) && error)
-		nr_bytes = rq->hard_nr_sectors << 9;
-
-	if (!blk_fs_request(rq) && error && !rq->errors)
-		rq->errors = -EIO;
-
 	/*
 	 * decide whether to reenable DMA -- 3 is a random magic for now,
 	 * if we DMA timeout more than 3 times, just stay in PIO
@@ -84,255 +67,100 @@ static int __ide_end_request(ide_drive_t
 		ide_dma_on(drive);
 	}
 
-	if (!blk_end_request(rq, error, nr_bytes))
-		ret = 0;
-
-	if (ret == 0 && dequeue)
-		drive->hwif->rq = NULL;
-
-	return ret;
-}
-
-/**
- *	ide_end_request		-	complete an IDE I/O
- *	@drive: IDE device for the I/O
- *	@uptodate:
- *	@nr_sectors: number of sectors completed
- *
- *	This is our end_request wrapper function. We complete the I/O
- *	update random number input and dequeue the request, which if
- *	it was tagged may be out of order.
- */
-
-int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
-{
-	unsigned int nr_bytes = nr_sectors << 9;
-	struct request *rq = drive->hwif->rq;
-
-	if (!nr_bytes) {
-		if (blk_pc_request(rq))
-			nr_bytes = rq->data_len;
-		else
-			nr_bytes = rq->hard_cur_sectors << 9;
-	}
-
-	return __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
-}
-EXPORT_SYMBOL(ide_end_request);
-
-/**
- *	ide_end_dequeued_request	-	complete an IDE I/O
- *	@drive: IDE device for the I/O
- *	@uptodate:
- *	@nr_sectors: number of sectors completed
- *
- *	Complete an I/O that is no longer on the request queue. This
- *	typically occurs when we pull the request and issue a REQUEST_SENSE.
- *	We must still finish the old request but we must not tamper with the
- *	queue in the meantime.
- *
- *	NOTE: This path does not handle barrier, but barrier is not supported
- *	on ide-cd anyway.
- */
-
-int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
-			     int uptodate, int nr_sectors)
-{
-	BUG_ON(!blk_rq_started(rq));
-
-	return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
+	return blk_end_request(rq, error, nr_bytes);
 }
-EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
+EXPORT_SYMBOL_GPL(ide_end_rq);
 
-/**
- *	ide_end_drive_cmd	-	end an explicit drive command
- *	@drive: command 
- *	@stat: status bits
- *	@err: error bits
- *
- *	Clean up after success/failure of an explicit drive command.
- *	These get thrown onto the queue so they are synchronized with
- *	real I/O operations on the drive.
- *
- *	In LBA48 mode we have to read the register set twice to get
- *	all the extra information out.
- */
- 
-void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
+void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
+	const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
+	struct ide_taskfile *tf = &cmd->tf;
+	struct request *rq = cmd->rq;
+	u8 tf_cmd = tf->command;
 
-	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		ide_task_t *task = (ide_task_t *)rq->special;
+	tf->error = err;
+	tf->status = stat;
 
-		if (task) {
-			struct ide_taskfile *tf = &task->tf;
+	if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
+		u8 data[2];
 
-			tf->error = err;
-			tf->status = stat;
+		tp_ops->input_data(drive, cmd, data, 2);
 
-			drive->hwif->tp_ops->tf_read(drive, task);
+		cmd->tf.data  = data[0];
+		cmd->hob.data = data[1];
+	}
 
-			if (task->tf_flags & IDE_TFLAG_DYN)
-				kfree(task);
-		}
-	} else if (blk_pm_request(rq)) {
-		struct request_pm_state *pm = rq->data;
+	ide_tf_readback(drive, cmd);
 
-		ide_complete_power_step(drive, rq);
-		if (pm->pm_step == IDE_PM_COMPLETED)
-			ide_complete_pm_request(drive, rq);
-		return;
+	if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
+	    tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
+		if (tf->lbal != 0xc4) {
+			printk(KERN_ERR "%s: head unload failed!\n",
+			       drive->name);
+			ide_tf_dump(drive->name, cmd);
+		} else
+			drive->dev_flags |= IDE_DFLAG_PARKED;
 	}
 
-	hwif->rq = NULL;
-
-	rq->errors = err;
+	if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+		struct ide_cmd *orig_cmd = rq->special;
 
-	if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0),
-				     blk_rq_bytes(rq))))
-		BUG();
+		if (cmd->tf_flags & IDE_TFLAG_DYN)
+			kfree(orig_cmd);
+		else
+			memcpy(orig_cmd, cmd, sizeof(*cmd));
+	}
 }
-EXPORT_SYMBOL(ide_end_drive_cmd);
 
-static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+/* obsolete, blk_rq_bytes() should be used instead */
+unsigned int ide_rq_bytes(struct request *rq)
 {
-	if (rq->rq_disk) {
-		struct ide_driver *drv;
-
-		drv = *(struct ide_driver **)rq->rq_disk->private_data;
-		drv->end_request(drive, 0, 0);
-	} else
-		ide_end_request(drive, 0, 0);
+	if (blk_pc_request(rq))
+		return rq->data_len;
+	else
+		return rq->hard_cur_sectors << 9;
 }
+EXPORT_SYMBOL_GPL(ide_rq_bytes);
 
-static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
 {
 	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = hwif->rq;
+	int rc;
 
-	if ((stat & ATA_BUSY) ||
-	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
-		/* other bits are useless when BUSY */
-		rq->errors |= ERROR_RESET;
-	} else if (stat & ATA_ERR) {
-		/* err has different meaning on cdrom and tape */
-		if (err == ATA_ABORTED) {
-			if ((drive->dev_flags & IDE_DFLAG_LBA) &&
-			    /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
-			    hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
-				return ide_stopped;
-		} else if ((err & BAD_CRC) == BAD_CRC) {
-			/* UDMA crc error, just retry the operation */
-			drive->crc_count++;
-		} else if (err & (ATA_BBK | ATA_UNC)) {
-			/* retries won't help these */
-			rq->errors = ERROR_MAX;
-		} else if (err & ATA_TRK0NF) {
-			/* help it find track zero */
-			rq->errors |= ERROR_RECAL;
-		}
-	}
-
-	if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
-	    (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
-		int nsect = drive->mult_count ? drive->mult_count : 1;
-
-		ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
-	}
-
-	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
-		ide_kill_rq(drive, rq);
-		return ide_stopped;
-	}
-
-	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
-		rq->errors |= ERROR_RESET;
-
-	if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-		++rq->errors;
-		return ide_do_reset(drive);
-	}
-
-	if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
-		drive->special.b.recalibrate = 1;
+	/*
+	 * if failfast is set on a request, override number of sectors
+	 * and complete the whole request right now
+	 */
+	if (blk_noretry_request(rq) && error <= 0)
+		nr_bytes = rq->hard_nr_sectors << 9;
 
-	++rq->errors;
+	rc = ide_end_rq(drive, rq, error, nr_bytes);
+	if (rc == 0)
+		hwif->rq = NULL;
 
-	return ide_stopped;
+	return rc;
 }
+EXPORT_SYMBOL(ide_complete_rq);
 
-static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+void ide_kill_rq(ide_drive_t *drive, struct request *rq)
 {
-	ide_hwif_t *hwif = drive->hwif;
-
-	if ((stat & ATA_BUSY) ||
-	    ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
-		/* other bits are useless when BUSY */
-		rq->errors |= ERROR_RESET;
-	} else {
-		/* add decoding error stuff */
-	}
+	u8 drv_req = blk_special_request(rq) && rq->rq_disk;
+	u8 media = drive->media;
 
-	if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
-		/* force an abort */
-		hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+	drive->failed_pc = NULL;
 
-	if (rq->errors >= ERROR_MAX) {
-		ide_kill_rq(drive, rq);
+	if ((media == ide_floppy || media == ide_tape) && drv_req) {
+		rq->errors = 0;
+		ide_complete_rq(drive, 0, blk_rq_bytes(rq));
 	} else {
-		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-			++rq->errors;
-			return ide_do_reset(drive);
-		}
-		++rq->errors;
-	}
-
-	return ide_stopped;
-}
-
-static ide_startstop_t
-__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
-	if (drive->media == ide_disk)
-		return ide_ata_error(drive, rq, stat, err);
-	return ide_atapi_error(drive, rq, stat, err);
-}
-
-/**
- *	ide_error	-	handle an error on the IDE
- *	@drive: drive the error occurred on
- *	@msg: message to report
- *	@stat: status bits
- *
- *	ide_error() takes action based on the error returned by the drive.
- *	For normal I/O that may well include retries. We deal with
- *	both new-style (taskfile) and old style command handling here.
- *	In the case of taskfile command handling there is work left to
- *	do
- */
- 
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
-	struct request *rq;
-	u8 err;
-
-	err = ide_dump_status(drive, msg, stat);
-
-	rq = drive->hwif->rq;
-	if (rq == NULL)
-		return ide_stopped;
-
-	/* retry only "normal" I/O: */
-	if (!blk_fs_request(rq)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, stat, err);
-		return ide_stopped;
+		if (media == ide_tape)
+			rq->errors = IDE_DRV_ERROR_GENERAL;
+		else if (blk_fs_request(rq) == 0 && rq->errors == 0)
+			rq->errors = -EIO;
+		ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
 	}
-
-	return __ide_error(drive, rq, stat, err);
 }
-EXPORT_SYMBOL_GPL(ide_error);
 
 static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
 {
@@ -359,20 +187,20 @@ static void ide_tf_set_setmult_cmd(ide_d
 static ide_startstop_t ide_disk_special(ide_drive_t *drive)
 {
 	special_t *s = &drive->special;
-	ide_task_t args;
+	struct ide_cmd cmd;
 
-	memset(&args, 0, sizeof(ide_task_t));
-	args.data_phase = TASKFILE_NO_DATA;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.protocol = ATA_PROT_NODATA;
 
 	if (s->b.set_geometry) {
 		s->b.set_geometry = 0;
-		ide_tf_set_specify_cmd(drive, &args.tf);
+		ide_tf_set_specify_cmd(drive, &cmd.tf);
 	} else if (s->b.recalibrate) {
 		s->b.recalibrate = 0;
-		ide_tf_set_restore_cmd(drive, &args.tf);
+		ide_tf_set_restore_cmd(drive, &cmd.tf);
 	} else if (s->b.set_multmode) {
 		s->b.set_multmode = 0;
-		ide_tf_set_setmult_cmd(drive, &args.tf);
+		ide_tf_set_setmult_cmd(drive, &cmd.tf);
 	} else if (s->all) {
 		int special = s->all;
 		s->all = 0;
@@ -380,10 +208,11 @@ static ide_startstop_t ide_disk_special(
 		return ide_stopped;
 	}
 
-	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
-			IDE_TFLAG_CUSTOM_HANDLER;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER;
 
-	do_rw_taskfile(drive, &args);
+	do_rw_taskfile(drive, &cmd);
 
 	return ide_started;
 }
@@ -413,33 +242,29 @@ static ide_startstop_t do_special (ide_d
 	return ide_stopped;
 }
 
-void ide_map_sg(ide_drive_t *drive, struct request *rq)
+void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
+	struct request *rq = cmd->rq;
 
 	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
-		hwif->sg_nents = 1;
+		cmd->sg_nents = 1;
 	} else if (!rq->bio) {
 		sg_init_one(sg, rq->data, rq->data_len);
-		hwif->sg_nents = 1;
-	} else {
-		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
-	}
+		cmd->sg_nents = 1;
+	} else
+		cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
 }
-
 EXPORT_SYMBOL_GPL(ide_map_sg);
 
-void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
 {
-	ide_hwif_t *hwif = drive->hwif;
-
-	hwif->nsect = hwif->nleft = rq->nr_sectors;
-	hwif->cursg_ofs = 0;
-	hwif->cursg = NULL;
+	cmd->nbytes = cmd->nleft = nr_bytes;
+	cmd->cursg_ofs = 0;
+	cmd->cursg = NULL;
 }
-
 EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
 
 /**
@@ -457,24 +282,15 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
 static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
 		struct request *rq)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	ide_task_t *task = rq->special;
-
-	if (task) {
-		hwif->data_phase = task->data_phase;
+	struct ide_cmd *cmd = rq->special;
 
-		switch (hwif->data_phase) {
-		case TASKFILE_MULTI_OUT:
-		case TASKFILE_OUT:
-		case TASKFILE_MULTI_IN:
-		case TASKFILE_IN:
-			ide_init_sg_cmd(drive, rq);
-			ide_map_sg(drive, rq);
-		default:
-			break;
+	if (cmd) {
+		if (cmd->protocol == ATA_PROT_PIO) {
+			ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+			ide_map_sg(drive, cmd);
 		}
 
-		return do_rw_taskfile(drive, task);
+		return do_rw_taskfile(drive, cmd);
 	}
 
  	/*
@@ -484,83 +300,26 @@ static ide_startstop_t execute_drive_cmd
 #ifdef DEBUG
  	printk("%s: DRIVE_CMD (null)\n", drive->name);
 #endif
-	ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
-			  ide_read_error(drive));
+	rq->errors = 0;
+	ide_complete_rq(drive, 0, blk_rq_bytes(rq));
 
  	return ide_stopped;
 }
 
-int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
-		       int arg)
-{
-	struct request_queue *q = drive->queue;
-	struct request *rq;
-	int ret = 0;
-
-	if (!(setting->flags & DS_SYNC))
-		return setting->set(drive, arg);
-
-	rq = blk_get_request(q, READ, __GFP_WAIT);
-	rq->cmd_type = REQ_TYPE_SPECIAL;
-	rq->cmd_len = 5;
-	rq->cmd[0] = REQ_DEVSET_EXEC;
-	*(int *)&rq->cmd[1] = arg;
-	rq->special = setting->set;
-
-	if (blk_execute_rq(q, NULL, rq, 0))
-		ret = rq->errors;
-	blk_put_request(rq);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(ide_devset_execute);
-
 static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
 {
 	u8 cmd = rq->cmd[0];
 
-	if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) {
-		ide_task_t task;
-		struct ide_taskfile *tf = &task.tf;
-
-		memset(&task, 0, sizeof(task));
-		if (cmd == REQ_PARK_HEADS) {
-			drive->sleep = *(unsigned long *)rq->special;
-			drive->dev_flags |= IDE_DFLAG_SLEEPING;
-			tf->command = ATA_CMD_IDLEIMMEDIATE;
-			tf->feature = 0x44;
-			tf->lbal = 0x4c;
-			tf->lbam = 0x4e;
-			tf->lbah = 0x55;
-			task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
-		} else		/* cmd == REQ_UNPARK_HEADS */
-			tf->command = ATA_CMD_CHK_POWER;
-
-		task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-		task.rq = rq;
-		drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
-		return do_rw_taskfile(drive, &task);
-	}
-
 	switch (cmd) {
+	case REQ_PARK_HEADS:
+	case REQ_UNPARK_HEADS:
+		return ide_do_park_unpark(drive, rq);
 	case REQ_DEVSET_EXEC:
-	{
-		int err, (*setfunc)(ide_drive_t *, int) = rq->special;
-
-		err = setfunc(drive, *(int *)&rq->cmd[1]);
-		if (err)
-			rq->errors = err;
-		else
-			err = 1;
-		ide_end_request(drive, err, 0);
-		return ide_stopped;
-	}
+		return ide_do_devset(drive, rq);
 	case REQ_DRIVE_RESET:
 		return ide_do_reset(drive);
 	default:
-		blk_dump_rq_flags(rq, "ide_special_rq - bad request");
-		ide_end_request(drive, 0, 0);
-		return ide_stopped;
+		BUG();
 	}
 }
 
@@ -593,7 +352,7 @@ static ide_startstop_t start_request (id
 	if (blk_pm_request(rq))
 		ide_check_pm_state(drive, rq);
 
-	SELECT_DRIVE(drive);
+	drive->hwif->tp_ops->dev_select(drive);
 	if (ide_wait_stat(&startstop, drive, drive->ready_stat,
 			  ATA_BUSY | ATA_DRQ, WAIT_READY)) {
 		printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
@@ -620,7 +379,7 @@ static ide_startstop_t start_request (id
 			startstop = ide_start_power_step(drive, rq);
 			if (startstop == ide_stopped &&
 			    pm->pm_step == IDE_PM_COMPLETED)
-				ide_complete_pm_request(drive, rq);
+				ide_complete_pm_rq(drive, rq);
 			return startstop;
 		} else if (!rq->rq_disk && blk_special_request(rq))
 			/*
@@ -683,8 +442,8 @@ static inline int ide_lock_host(struct i
 	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
 		rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
 		if (rc == 0) {
-			/* for atari only */
-			ide_get_lock(ide_intr, hwif);
+			if (host->get_lock)
+				host->get_lock(ide_intr, hwif);
 		}
 	}
 	return rc;
@@ -693,8 +452,8 @@ static inline int ide_lock_host(struct i
 static inline void ide_unlock_host(struct ide_host *host)
 {
 	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
-		/* for atari only */
-		ide_release_lock();
+		if (host->release_lock)
+			host->release_lock();
 		clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
 	}
 }
@@ -736,11 +495,10 @@ repeat:
 		prev_port = hwif->host->cur_port;
 		hwif->rq = NULL;
 
-		if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
-			if (time_before(drive->sleep, jiffies)) {
-				ide_unlock_port(hwif);
-				goto plug_device;
-			}
+		if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
+		    time_after(drive->sleep, jiffies)) {
+			ide_unlock_port(hwif);
+			goto plug_device;
 		}
 
 		if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
@@ -750,7 +508,9 @@ repeat:
 			 * quirk_list may not like intr setups/cleanups
 			 */
 			if (prev_port && prev_port->cur_dev->quirk_list == 0)
-				prev_port->tp_ops->set_irq(prev_port, 0);
+				prev_port->tp_ops->write_devctl(prev_port,
+								ATA_NIEN |
+								ATA_DEVCTL_OBS);
 
 			hwif->host->cur_port = hwif;
 		}
@@ -820,63 +580,6 @@ plug_device_2:
 		blk_plug_device(q);
 }
 
-/*
- * un-busy the port etc, and clear any pending DMA status. we want to
- * retry the current request in pio mode instead of risking tossing it
- * all away
- */
-static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq;
-	ide_startstop_t ret = ide_stopped;
-
-	/*
-	 * end current dma transaction
-	 */
-
-	if (error < 0) {
-		printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
-		(void)hwif->dma_ops->dma_end(drive);
-		ret = ide_error(drive, "dma timeout error",
-				hwif->tp_ops->read_status(hwif));
-	} else {
-		printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
-		hwif->dma_ops->dma_timeout(drive);
-	}
-
-	/*
-	 * disable dma for now, but remember that we did so because of
-	 * a timeout -- we'll reenable after we finish this next request
-	 * (or rather the first chunk of it) in pio.
-	 */
-	drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
-	drive->retry_pio++;
-	ide_dma_off_quietly(drive);
-
-	/*
-	 * un-busy drive etc and make sure request is sane
-	 */
-
-	rq = hwif->rq;
-	if (!rq)
-		goto out;
-
-	hwif->rq = NULL;
-
-	rq->errors = 0;
-
-	if (!rq->bio)
-		goto out;
-
-	rq->sector = rq->bio->bi_sector;
-	rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
-	rq->hard_cur_sectors = rq->current_nr_sectors;
-	rq->buffer = bio_data(rq->bio);
-out:
-	return ret;
-}
-
 static void ide_plug_device(ide_drive_t *drive)
 {
 	struct request_queue *q = drive->queue;
@@ -888,6 +591,29 @@ static void ide_plug_device(ide_drive_t
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
+static int drive_is_ready(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 stat = 0;
+
+	if (drive->waiting_for_dma)
+		return hwif->dma_ops->dma_test_irq(drive);
+
+	if (hwif->io_ports.ctl_addr &&
+	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
+		stat = hwif->tp_ops->read_altstatus(hwif);
+	else
+		/* Note: this may clear a pending IRQ!! */
+		stat = hwif->tp_ops->read_status(hwif);
+
+	if (stat & ATA_BUSY)
+		/* drive busy: definitely not interrupting */
+		return 0;
+
+	/* drive ready: *might* be interrupting */
+	return 1;
+}
+
 /**
  *	ide_timer_expiry	-	handle lack of an IDE interrupt
  *	@data: timer callback magic (hwif)
@@ -940,6 +666,7 @@ void ide_timer_expiry (unsigned long dat
 			}
 		}
 		hwif->handler = NULL;
+		hwif->expiry = NULL;
 		/*
 		 * We need to simulate a real interrupt when invoking
 		 * the handler() function, which means we need to
@@ -955,7 +682,8 @@ void ide_timer_expiry (unsigned long dat
 		} else if (drive_is_ready(drive)) {
 			if (drive->waiting_for_dma)
 				hwif->dma_ops->dma_lost_irq(drive);
-			(void)ide_ack_intr(hwif);
+			if (hwif->ack_intr)
+				hwif->ack_intr(hwif);
 			printk(KERN_WARNING "%s: lost interrupt\n",
 				drive->name);
 			startstop = handler(drive);
@@ -968,7 +696,7 @@ void ide_timer_expiry (unsigned long dat
 		}
 		spin_lock_irq(&hwif->lock);
 		enable_irq(hwif->irq);
-		if (startstop == ide_stopped) {
+		if (startstop == ide_stopped && hwif->polling == 0) {
 			ide_unlock_port(hwif);
 			plug_device = 1;
 		}
@@ -1056,6 +784,7 @@ static void unexpected_intr(int irq, ide
 irqreturn_t ide_intr (int irq, void *dev_id)
 {
 	ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
+	struct ide_host *host = hwif->host;
 	ide_drive_t *uninitialized_var(drive);
 	ide_handler_t *handler;
 	unsigned long flags;
@@ -1063,14 +792,14 @@ irqreturn_t ide_intr (int irq, void *dev
 	irqreturn_t irq_ret = IRQ_NONE;
 	int plug_device = 0;
 
-	if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
-		if (hwif != hwif->host->cur_port)
+	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+		if (hwif != host->cur_port)
 			goto out_early;
 	}
 
 	spin_lock_irqsave(&hwif->lock, flags);
 
-	if (!ide_ack_intr(hwif))
+	if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
 		goto out;
 
 	handler = hwif->handler;
@@ -1087,27 +816,19 @@ irqreturn_t ide_intr (int irq, void *dev
 		 *
 		 * For PCI, we cannot tell the difference,
 		 * so in that case we just ignore it and hope it goes away.
-		 *
-		 * FIXME: unexpected_intr should be hwif-> then we can
-		 * remove all the ifdef PCI crap
 		 */
-#ifdef CONFIG_BLK_DEV_IDEPCI
-		if (hwif->chipset != ide_pci)
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		{
+		if ((host->irq_flags & IRQF_SHARED) == 0) {
 			/*
 			 * Probably not a shared PCI interrupt,
 			 * so we can safely try to do something about it:
 			 */
 			unexpected_intr(irq, hwif);
-#ifdef CONFIG_BLK_DEV_IDEPCI
 		} else {
 			/*
 			 * Whack the status register, just in case
 			 * we have a leftover pending IRQ.
 			 */
 			(void)hwif->tp_ops->read_status(hwif);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
 		}
 		goto out;
 	}
@@ -1125,6 +846,7 @@ irqreturn_t ide_intr (int irq, void *dev
 		goto out;
 
 	hwif->handler = NULL;
+	hwif->expiry = NULL;
 	hwif->req_gen++;
 	del_timer(&hwif->timer);
 	spin_unlock(&hwif->lock);
@@ -1146,7 +868,7 @@ irqreturn_t ide_intr (int irq, void *dev
 	 * same irq as is currently being serviced here, and Linux
 	 * won't allow another of the same (on any CPU) until we return.
 	 */
-	if (startstop == ide_stopped) {
+	if (startstop == ide_stopped && hwif->polling == 0) {
 		BUG_ON(hwif->handler);
 		ide_unlock_port(hwif);
 		plug_device = 1;
@@ -1164,54 +886,6 @@ out_early:
 }
 EXPORT_SYMBOL_GPL(ide_intr);
 
-/**
- *	ide_do_drive_cmd	-	issue IDE special command
- *	@drive: device to issue command
- *	@rq: request to issue
- *
- *	This function issues a special IDE device request
- *	onto the request queue.
- *
- *	the rq is queued at the head of the request queue, displacing
- *	the currently-being-processed request and this function
- *	returns immediately without waiting for the new rq to be
- *	completed.  This is VERY DANGEROUS, and is intended for
- *	careful use by the ATAPI tape/cdrom driver code.
- */
-
-void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
-{
-	struct request_queue *q = drive->queue;
-	unsigned long flags;
-
-	drive->hwif->rq = NULL;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
-	spin_unlock_irqrestore(q->queue_lock, flags);
-}
-EXPORT_SYMBOL(ide_do_drive_cmd);
-
-void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	ide_task_t task;
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
-			IDE_TFLAG_OUT_FEATURE | tf_flags;
-	task.tf.feature = dma;		/* Use PIO/DMA */
-	task.tf.lbam    = bcount & 0xff;
-	task.tf.lbah    = (bcount >> 8) & 0xff;
-
-	ide_tf_dump(drive->name, &task.tf);
-	hwif->tp_ops->set_irq(hwif, 1);
-	SELECT_MASK(drive, 0);
-	hwif->tp_ops->tf_load(drive, &task);
-}
-
-EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
-
 void ide_pad_transfer(ide_drive_t *drive, int write, int len)
 {
 	ide_hwif_t *hwif = drive->hwif;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-ioctls.c linux-libre-2.6.30-gnu1/drivers/ide/ide-ioctls.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-ioctls.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-ioctls.c	2009-06-09 23:05:27.000000000 -0400
@@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_
 	return 0;
 }
 
-static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
 {
 	u8 *buf = NULL;
 	int bufsize = 0, err = 0;
 	u8 args[4], xfer_rate = 0;
-	ide_task_t tfargs;
-	struct ide_taskfile *tf = &tfargs.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 	u16 *id = drive->id;
 
 	if (NULL == (void *) arg) {
@@ -134,24 +134,25 @@ static int ide_cmd_ioctl(ide_drive_t *dr
 	if (copy_from_user(args, (void __user *)arg, 4))
 		return -EFAULT;
 
-	memset(&tfargs, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 	tf->feature = args[2];
 	if (args[0] == ATA_CMD_SMART) {
 		tf->nsect = args[3];
 		tf->lbal  = args[1];
 		tf->lbam  = 0x4f;
 		tf->lbah  = 0xc2;
-		tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+		cmd.valid.out.tf = IDE_VALID_OUT_TF;
+		cmd.valid.in.tf  = IDE_VALID_NSECT;
 	} else {
 		tf->nsect = args[1];
-		tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
-				  IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
+		cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+		cmd.valid.in.tf  = IDE_VALID_NSECT;
 	}
 	tf->command = args[0];
-	tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
+	cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
 
 	if (args[3]) {
-		tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
+		cmd.tf_flags |= IDE_TFLAG_IO_16BIT;
 		bufsize = SECTOR_SIZE * args[3];
 		buf = kzalloc(bufsize, GFP_KERNEL);
 		if (buf == NULL)
@@ -172,7 +173,7 @@ static int ide_cmd_ioctl(ide_drive_t *dr
 		}
 	}
 
-	err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
+	err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
 
 	args[0] = tf->status;
 	args[1] = tf->error;
@@ -194,25 +195,26 @@ abort:
 	return err;
 }
 
-static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
 {
 	void __user *p = (void __user *)arg;
 	int err = 0;
 	u8 args[7];
-	ide_task_t task;
+	struct ide_cmd cmd;
 
 	if (copy_from_user(args, p, 7))
 		return -EFAULT;
 
-	memset(&task, 0, sizeof(task));
-	memcpy(&task.tf_array[7], &args[1], 6);
-	task.tf.command = args[0];
-	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	memset(&cmd, 0, sizeof(cmd));
+	memcpy(&cmd.tf.feature, &args[1], 6);
+	cmd.tf.command = args[0];
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
 
-	err = ide_no_data_taskfile(drive, &task);
+	err = ide_no_data_taskfile(drive, &cmd);
 
-	args[0] = task.tf.command;
-	memcpy(&args[1], &task.tf_array[7], 6);
+	args[0] = cmd.tf.command;
+	memcpy(&args[1], &cmd.tf.feature, 6);
 
 	if (copy_to_user(p, args, 7))
 		err = -EFAULT;
@@ -262,17 +264,17 @@ int generic_ide_ioctl(ide_drive_t *drive
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 			return -EACCES;
 		if (drive->media == ide_disk)
-			return ide_taskfile_ioctl(drive, cmd, arg);
+			return ide_taskfile_ioctl(drive, arg);
 		return -ENOMSG;
 #endif
 	case HDIO_DRIVE_CMD:
 		if (!capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return ide_cmd_ioctl(drive, cmd, arg);
+		return ide_cmd_ioctl(drive, arg);
 	case HDIO_DRIVE_TASK:
 		if (!capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return ide_task_ioctl(drive, cmd, arg);
+		return ide_task_ioctl(drive, arg);
 	case HDIO_DRIVE_RESET:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-iops.c linux-libre-2.6.30-gnu1/drivers/ide/ide-iops.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-iops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-iops.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,49 +27,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-/*
- *	Conventional PIO operations for ATA devices
- */
-
-static u8 ide_inb (unsigned long port)
-{
-	return (u8) inb(port);
-}
-
-static void ide_outb (u8 val, unsigned long port)
-{
-	outb(val, port);
-}
-
-/*
- *	MMIO operations, typically used for SATA controllers
- */
-
-static u8 ide_mm_inb (unsigned long port)
-{
-	return (u8) readb((void __iomem *) port);
-}
-
-static void ide_mm_outb (u8 value, unsigned long port)
-{
-	writeb(value, (void __iomem *) port);
-}
-
-void SELECT_DRIVE (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-	ide_task_t task;
-
-	if (port_ops && port_ops->selectproc)
-		port_ops->selectproc(drive);
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_OUT_DEVICE;
-
-	drive->hwif->tp_ops->tf_load(drive, &task);
-}
-
 void SELECT_MASK(ide_drive_t *drive, int mask)
 {
 	const struct ide_port_ops *port_ops = drive->hwif->port_ops;
@@ -78,319 +35,16 @@ void SELECT_MASK(ide_drive_t *drive, int
 		port_ops->maskproc(drive, mask);
 }
 
-void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
-	else
-		outb(cmd, hwif->io_ports.command_addr);
-}
-EXPORT_SYMBOL_GPL(ide_exec_command);
-
-u8 ide_read_status(ide_hwif_t *hwif)
-{
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		return readb((void __iomem *)hwif->io_ports.status_addr);
-	else
-		return inb(hwif->io_ports.status_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_status);
-
-u8 ide_read_altstatus(ide_hwif_t *hwif)
-{
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		return readb((void __iomem *)hwif->io_ports.ctl_addr);
-	else
-		return inb(hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_altstatus);
-
-void ide_set_irq(ide_hwif_t *hwif, int on)
-{
-	u8 ctl = ATA_DEVCTL_OBS;
-
-	if (on == 4) { /* hack for SRST */
-		ctl |= 4;
-		on &= ~4;
-	}
-
-	ctl |= on ? 0 : 2;
-
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
-	else
-		outb(ctl, hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_set_irq);
-
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	void (*tf_outb)(u8 addr, unsigned long port);
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-	u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (mmio)
-		tf_outb = ide_mm_outb;
-	else
-		tf_outb = ide_outb;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
-		u16 data = (tf->hob_data << 8) | tf->data;
-
-		if (mmio)
-			writew(data, (void __iomem *)io_ports->data_addr);
-		else
-			outw(data, io_ports->data_addr);
-	}
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tf_outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tf_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tf_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tf_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		tf_outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-		tf_outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-		tf_outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-		tf_outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-		tf_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tf_outb((tf->device & HIHI) | drive->select,
-			 io_ports->device_addr);
-}
-EXPORT_SYMBOL_GPL(ide_tf_load);
-
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	void (*tf_outb)(u8 addr, unsigned long port);
-	u8 (*tf_inb)(unsigned long port);
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
-	if (mmio) {
-		tf_outb = ide_mm_outb;
-		tf_inb  = ide_mm_inb;
-	} else {
-		tf_outb = ide_outb;
-		tf_inb  = ide_inb;
-	}
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data;
-
-		if (mmio)
-			data = readw((void __iomem *)io_ports->data_addr);
-		else
-			data = inw(io_ports->data_addr);
-
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = tf_inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = tf_inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = tf_inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = tf_inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = tf_inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = tf_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature = tf_inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = tf_inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = tf_inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = tf_inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = tf_inb(io_ports->lbah_addr);
-	}
-}
-EXPORT_SYMBOL_GPL(ide_tf_read);
-
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data.  We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static void ata_vlb_sync(unsigned long port)
-{
-	(void)inb(port);
-	(void)inb(port);
-	(void)inb(port);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd len is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
-		    unsigned int len)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	unsigned long data_addr = io_ports->data_addr;
-	u8 io_32bit = drive->io_32bit;
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
-	len++;
-
-	if (io_32bit) {
-		unsigned long uninitialized_var(flags);
-
-		if ((io_32bit & 2) && !mmio) {
-			local_irq_save(flags);
-			ata_vlb_sync(io_ports->nsect_addr);
-		}
-
-		if (mmio)
-			__ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
-		else
-			insl(data_addr, buf, len / 4);
-
-		if ((io_32bit & 2) && !mmio)
-			local_irq_restore(flags);
-
-		if ((len & 3) >= 2) {
-			if (mmio)
-				__ide_mm_insw((void __iomem *)data_addr,
-						(u8 *)buf + (len & ~3), 1);
-			else
-				insw(data_addr, (u8 *)buf + (len & ~3), 1);
-		}
-	} else {
-		if (mmio)
-			__ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
-		else
-			insw(data_addr, buf, len / 2);
-	}
-}
-EXPORT_SYMBOL_GPL(ide_input_data);
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
-		     unsigned int len)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	unsigned long data_addr = io_ports->data_addr;
-	u8 io_32bit = drive->io_32bit;
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
-	len++;
-
-	if (io_32bit) {
-		unsigned long uninitialized_var(flags);
-
-		if ((io_32bit & 2) && !mmio) {
-			local_irq_save(flags);
-			ata_vlb_sync(io_ports->nsect_addr);
-		}
-
-		if (mmio)
-			__ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
-		else
-			outsl(data_addr, buf, len / 4);
-
-		if ((io_32bit & 2) && !mmio)
-			local_irq_restore(flags);
-
-		if ((len & 3) >= 2) {
-			if (mmio)
-				__ide_mm_outsw((void __iomem *)data_addr,
-						 (u8 *)buf + (len & ~3), 1);
-			else
-				outsw(data_addr, (u8 *)buf + (len & ~3), 1);
-		}
-	} else {
-		if (mmio)
-			__ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
-		else
-			outsw(data_addr, buf, len / 2);
-	}
-}
-EXPORT_SYMBOL_GPL(ide_output_data);
-
 u8 ide_read_error(ide_drive_t *drive)
 {
-	ide_task_t task;
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_IN_FEATURE;
+	struct ide_taskfile tf;
 
-	drive->hwif->tp_ops->tf_read(drive, &task);
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR);
 
-	return task.tf.error;
+	return tf.error;
 }
 EXPORT_SYMBOL_GPL(ide_read_error);
 
-void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
-{
-	ide_task_t task;
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
-			IDE_TFLAG_IN_NSECT;
-
-	drive->hwif->tp_ops->tf_read(drive, &task);
-
-	*bcount = (task.tf.lbah << 8) | task.tf.lbam;
-	*ireason = task.tf.nsect & 3;
-}
-EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
-
-const struct ide_tp_ops default_tp_ops = {
-	.exec_command		= ide_exec_command,
-	.read_status		= ide_read_status,
-	.read_altstatus		= ide_read_altstatus,
-
-	.set_irq		= ide_set_irq,
-
-	.tf_load		= ide_tf_load,
-	.tf_read		= ide_tf_read,
-
-	.input_data		= ide_input_data,
-	.output_data		= ide_output_data,
-};
-
 void ide_fix_driveid(u16 *id)
 {
 #ifndef __LITTLE_ENDIAN
@@ -412,7 +66,7 @@ void ide_fix_driveid(u16 *id)
  * returned by the ATA_CMD_ID_ATA[PI] commands.
  */
 
-void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
+void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
 {
 	u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
 
@@ -435,44 +89,9 @@ void ide_fixstring (u8 *s, const int byt
 	while (p != end)
 		*p++ = '\0';
 }
-
 EXPORT_SYMBOL(ide_fixstring);
 
 /*
- * Needed for PCI irq sharing
- */
-int drive_is_ready (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= drive->hwif;
-	u8 stat			= 0;
-
-	if (drive->waiting_for_dma)
-		return hwif->dma_ops->dma_test_irq(drive);
-
-	/*
-	 * We do a passive status test under shared PCI interrupts on
-	 * cards that truly share the ATA side interrupt, but may also share
-	 * an interrupt with another pci card/device.  We make no assumptions
-	 * about possible isa-pnp and pci-pnp issues yet.
-	 */
-	if (hwif->io_ports.ctl_addr &&
-	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
-		stat = hwif->tp_ops->read_altstatus(hwif);
-	else
-		/* Note: this may clear a pending IRQ!! */
-		stat = hwif->tp_ops->read_status(hwif);
-
-	if (stat & ATA_BUSY)
-		/* drive busy:  definitely not interrupting */
-		return 0;
-
-	/* drive ready: *might* be interrupting */
-	return 1;
-}
-
-EXPORT_SYMBOL(drive_is_ready);
-
-/*
  * This routine busy-waits for the drive status to be not "busy".
  * It then checks the status for all of the "good" bits and none
  * of the "bad" bits, and if all is okay it returns 0.  All other
@@ -483,7 +102,8 @@ EXPORT_SYMBOL(drive_is_ready);
  * setting a timer to wake up at half second intervals thereafter,
  * until timeout is achieved, before timing out.
  */
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
+static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+			   unsigned long timeout, u8 *rstat)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -541,7 +161,8 @@ static int __ide_wait_stat(ide_drive_t *
  * The caller should return the updated value of "startstop" in this case,
  * "startstop" is unchanged when the function returns 0.
  */
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
+		  u8 bad, unsigned long timeout)
 {
 	int err;
 	u8 stat;
@@ -561,7 +182,6 @@ int ide_wait_stat(ide_startstop_t *start
 
 	return err;
 }
-
 EXPORT_SYMBOL(ide_wait_stat);
 
 /**
@@ -582,13 +202,10 @@ int ide_in_drive_list(u16 *id, const str
 			return 1;
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(ide_in_drive_list);
 
 /*
  * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
- * We list them here and depend on the device side cable detection for them.
- *
  * Some optical devices with the buggy firmwares have the same problem.
  */
 static const struct drive_list_entry ivb_list[] = {
@@ -607,7 +224,7 @@ static const struct drive_list_entry ivb
  *  All hosts that use the 80c ribbon must use!
  *  The name is derived from upper byte of word 93 and the 80c ribbon.
  */
-u8 eighty_ninty_three (ide_drive_t *drive)
+u8 eighty_ninty_three(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u16 *id = drive->id;
@@ -632,10 +249,25 @@ u8 eighty_ninty_three (ide_drive_t *driv
 	 * - force bit13 (80c cable present) check also for !ivb devices
 	 *   (unless the slave device is pre-ATA3)
 	 */
-	if ((id[ATA_ID_HW_CONFIG] & 0x4000) ||
-	    (ivb && (id[ATA_ID_HW_CONFIG] & 0x2000)))
+	if (id[ATA_ID_HW_CONFIG] & 0x4000)
 		return 1;
 
+	if (ivb) {
+		const char *model = (char *)&id[ATA_ID_PROD];
+
+		if (strstr(model, "TSSTcorp CDDVDW SH-S202")) {
+			/*
+			 * These ATAPI devices always report 80c cable
+			 * so we have to depend on the host in this case.
+			 */
+			if (hwif->cbl == ATA_CBL_PATA80)
+				return 1;
+		} else {
+			/* Depend on the device side cable detection. */
+			if (id[ATA_ID_HW_CONFIG] & 0x2000)
+				return 1;
+		}
+	}
 no_80w:
 	if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED)
 		return 0;
@@ -652,51 +284,24 @@ no_80w:
 
 int ide_driveid_update(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
 	u16 *id;
-	unsigned long flags;
-	u8 stat;
-
-	/*
-	 * Re-read drive->id for possible DMA mode
-	 * change (copied from ide-probe.c)
-	 */
-
-	SELECT_MASK(drive, 1);
-	tp_ops->set_irq(hwif, 0);
-	msleep(50);
-	tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);
+	int rc;
 
-	if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
-		SELECT_MASK(drive, 0);
+	id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
+	if (id == NULL)
 		return 0;
-	}
 
-	msleep(50);	/* wait for IRQ and ATA_DRQ */
-	stat = tp_ops->read_status(hwif);
-
-	if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) {
-		SELECT_MASK(drive, 0);
-		printk("%s: CHECK for good STATUS\n", drive->name);
-		return 0;
-	}
-	local_irq_save(flags);
+	SELECT_MASK(drive, 1);
+	rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
 	SELECT_MASK(drive, 0);
-	id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
-	if (!id) {
-		local_irq_restore(flags);
-		return 0;
-	}
-	tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
-	(void)tp_ops->read_status(hwif);	/* clear drive IRQ */
-	local_irq_enable();
-	local_irq_restore(flags);
-	ide_fix_driveid(id);
+
+	if (rc)
+		goto out_err;
 
 	drive->id[ATA_ID_UDMA_MODES]  = id[ATA_ID_UDMA_MODES];
 	drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
 	drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
+	drive->id[ATA_ID_CFA_MODES]   = id[ATA_ID_CFA_MODES];
 	/* anything more ? */
 
 	kfree(id);
@@ -705,16 +310,22 @@ int ide_driveid_update(ide_drive_t *driv
 		ide_dma_off(drive);
 
 	return 1;
+out_err:
+	SELECT_MASK(drive, 0);
+	if (rc == 2)
+		printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
+	kfree(id);
+	return 0;
 }
 
 int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+	struct ide_taskfile tf;
 	u16 *id = drive->id, i;
 	int error = 0;
 	u8 stat;
-	ide_task_t task;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_ops)	/* check if host supports DMA */
@@ -731,35 +342,31 @@ int ide_config_drive_speed(ide_drive_t *
 	 * but for some reason these don't work at
 	 * this point (lost interrupt).
 	 */
-        /*
-         * Select the drive, and issue the SETFEATURES command
-         */
-	disable_irq_nosync(hwif->irq);
-	
+
 	/*
 	 *	FIXME: we race against the running IRQ here if
 	 *	this is called from non IRQ context. If we use
 	 *	disable_irq() we hang on the error path. Work
 	 *	is needed.
 	 */
-	 
+	disable_irq_nosync(hwif->irq);
+
 	udelay(1);
-	SELECT_DRIVE(drive);
+	tp_ops->dev_select(drive);
 	SELECT_MASK(drive, 1);
 	udelay(1);
-	tp_ops->set_irq(hwif, 0);
+	tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
 
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
-	task.tf.feature = SETFEATURES_XFER;
-	task.tf.nsect   = speed;
+	memset(&tf, 0, sizeof(tf));
+	tf.feature = SETFEATURES_XFER;
+	tf.nsect   = speed;
 
-	tp_ops->tf_load(drive, &task);
+	tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT);
 
 	tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
 
 	if (drive->quirk_list == 2)
-		tp_ops->set_irq(hwif, 1);
+		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 
 	error = __ide_wait_stat(drive, drive->ready_stat,
 				ATA_BUSY | ATA_DRQ | ATA_ERR,
@@ -774,9 +381,14 @@ int ide_config_drive_speed(ide_drive_t *
 		return error;
 	}
 
-	id[ATA_ID_UDMA_MODES]  &= ~0xFF00;
-	id[ATA_ID_MWDMA_MODES] &= ~0x0F00;
-	id[ATA_ID_SWDMA_MODES] &= ~0x0F00;
+	if (speed >= XFER_SW_DMA_0) {
+		id[ATA_ID_UDMA_MODES]  &= ~0xFF00;
+		id[ATA_ID_MWDMA_MODES] &= ~0x0700;
+		id[ATA_ID_SWDMA_MODES] &= ~0x0700;
+		if (ata_id_is_cfa(id))
+			id[ATA_ID_CFA_MODES] &= ~0x0E00;
+	} else	if (ata_id_is_cfa(id))
+		id[ATA_ID_CFA_MODES] &= ~0x01C0;
 
  skip:
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -789,12 +401,18 @@ int ide_config_drive_speed(ide_drive_t *
 	if (speed >= XFER_UDMA_0) {
 		i = 1 << (speed - XFER_UDMA_0);
 		id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
+	} else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
+		i = speed - XFER_MW_DMA_2;
+		id[ATA_ID_CFA_MODES] |= i << 9;
 	} else if (speed >= XFER_MW_DMA_0) {
 		i = 1 << (speed - XFER_MW_DMA_0);
 		id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
 	} else if (speed >= XFER_SW_DMA_0) {
 		i = 1 << (speed - XFER_SW_DMA_0);
 		id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
+	} else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
+		i = speed - XFER_PIO_4;
+		id[ATA_ID_CFA_MODES] |= i << 6;
 	}
 
 	if (!drive->init_speed)
@@ -812,55 +430,55 @@ int ide_config_drive_speed(ide_drive_t *
  *
  * See also ide_execute_command
  */
-static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
-		      unsigned int timeout, ide_expiry_t *expiry)
+void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+		       unsigned int timeout)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
 	BUG_ON(hwif->handler);
 	hwif->handler		= handler;
-	hwif->expiry		= expiry;
 	hwif->timer.expires	= jiffies + timeout;
 	hwif->req_gen_timer	= hwif->req_gen;
 	add_timer(&hwif->timer);
 }
 
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
-		      unsigned int timeout, ide_expiry_t *expiry)
+void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+		     unsigned int timeout)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hwif->lock, flags);
-	__ide_set_handler(drive, handler, timeout, expiry);
+	__ide_set_handler(drive, handler, timeout);
 	spin_unlock_irqrestore(&hwif->lock, flags);
 }
-
 EXPORT_SYMBOL(ide_set_handler);
- 
+
 /**
  *	ide_execute_command	-	execute an IDE command
  *	@drive: IDE drive to issue the command against
- *	@command: command byte to write
+ *	@cmd: command
  *	@handler: handler for next phase
  *	@timeout: timeout for command
- *	@expiry:  handler to run on timeout
  *
  *	Helper function to issue an IDE command. This handles the
- *	atomicity requirements, command timing and ensures that the 
+ *	atomicity requirements, command timing and ensures that the
  *	handler and IRQ setup do not race. All IDE command kick off
  *	should go via this function or do equivalent locking.
  */
 
-void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
-			 unsigned timeout, ide_expiry_t *expiry)
+void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
+			 ide_handler_t *handler, unsigned timeout)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hwif->lock, flags);
-	__ide_set_handler(drive, handler, timeout, expiry);
-	hwif->tp_ops->exec_command(hwif, cmd);
+	if ((cmd->protocol != ATAPI_PROT_DMA &&
+	     cmd->protocol != ATAPI_PROT_PIO) ||
+	    (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
+		__ide_set_handler(drive, handler, timeout);
+	hwif->tp_ops->exec_command(hwif, cmd->tf.command);
 	/*
 	 * Drive takes 400nS to respond, we must avoid the IRQ being
 	 * serviced before that.
@@ -870,314 +488,6 @@ void ide_execute_command(ide_drive_t *dr
 	ndelay(400);
 	spin_unlock_irqrestore(&hwif->lock, flags);
 }
-EXPORT_SYMBOL(ide_execute_command);
-
-void ide_execute_pkt_cmd(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	unsigned long flags;
-
-	spin_lock_irqsave(&hwif->lock, flags);
-	hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET);
-	ndelay(400);
-	spin_unlock_irqrestore(&hwif->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
-
-static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
-{
-	struct request *rq = drive->hwif->rq;
-
-	if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
-		ide_end_request(drive, err ? err : 1, 0);
-}
-
-/* needed below */
-static ide_startstop_t do_reset1 (ide_drive_t *, int);
-
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 stat;
-
-	SELECT_DRIVE(drive);
-	udelay (10);
-	stat = hwif->tp_ops->read_status(hwif);
-
-	if (OK_STAT(stat, 0, ATA_BUSY))
-		printk("%s: ATAPI reset complete\n", drive->name);
-	else {
-		if (time_before(jiffies, hwif->poll_timeout)) {
-			ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
-			/* continue polling */
-			return ide_started;
-		}
-		/* end of polling */
-		hwif->polling = 0;
-		printk("%s: ATAPI reset timed-out, status=0x%02x\n",
-				drive->name, stat);
-		/* do it the old fashioned way */
-		return do_reset1(drive, 1);
-	}
-	/* done polling */
-	hwif->polling = 0;
-	ide_complete_drive_reset(drive, 0);
-	return ide_stopped;
-}
-
-static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
-{
-	static const char *err_master_vals[] =
-		{ NULL, "passed", "formatter device error",
-		  "sector buffer error", "ECC circuitry error",
-		  "controlling MPU error" };
-
-	u8 err_master = err & 0x7f;
-
-	printk(KERN_ERR "%s: reset: master: ", hwif->name);
-	if (err_master && err_master < 6)
-		printk(KERN_CONT "%s", err_master_vals[err_master]);
-	else
-		printk(KERN_CONT "error (0x%02x?)", err);
-	if (err & 0x80)
-		printk(KERN_CONT "; slave: failed");
-	printk(KERN_CONT "\n");
-}
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-	u8 tmp;
-	int err = 0;
-
-	if (port_ops && port_ops->reset_poll) {
-		err = port_ops->reset_poll(drive);
-		if (err) {
-			printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
-				hwif->name, drive->name);
-			goto out;
-		}
-	}
-
-	tmp = hwif->tp_ops->read_status(hwif);
-
-	if (!OK_STAT(tmp, 0, ATA_BUSY)) {
-		if (time_before(jiffies, hwif->poll_timeout)) {
-			ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-			/* continue polling */
-			return ide_started;
-		}
-		printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
-		drive->failures++;
-		err = -EIO;
-	} else  {
-		tmp = ide_read_error(drive);
-
-		if (tmp == 1) {
-			printk(KERN_INFO "%s: reset: success\n", hwif->name);
-			drive->failures = 0;
-		} else {
-			ide_reset_report_error(hwif, tmp);
-			drive->failures++;
-			err = -EIO;
-		}
-	}
-out:
-	hwif->polling = 0;	/* done polling */
-	ide_complete_drive_reset(drive, err);
-	return ide_stopped;
-}
-
-static void ide_disk_pre_reset(ide_drive_t *drive)
-{
-	int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
-
-	drive->special.all = 0;
-	drive->special.b.set_geometry = legacy;
-	drive->special.b.recalibrate  = legacy;
-
-	drive->mult_count = 0;
-	drive->dev_flags &= ~IDE_DFLAG_PARKED;
-
-	if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
-	    (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
-		drive->mult_req = 0;
-
-	if (drive->mult_req != drive->mult_count)
-		drive->special.b.set_multmode = 1;
-}
-
-static void pre_reset(ide_drive_t *drive)
-{
-	const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-
-	if (drive->media == ide_disk)
-		ide_disk_pre_reset(drive);
-	else
-		drive->dev_flags |= IDE_DFLAG_POST_RESET;
-
-	if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
-		if (drive->crc_count)
-			ide_check_dma_crc(drive);
-		else
-			ide_dma_off(drive);
-	}
-
-	if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
-		if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
-			drive->dev_flags &= ~IDE_DFLAG_UNMASK;
-			drive->io_32bit = 0;
-		}
-		return;
-	}
-
-	if (port_ops && port_ops->pre_reset)
-		port_ops->pre_reset(drive);
-
-	if (drive->current_speed != 0xff)
-		drive->desired_speed = drive->current_speed;
-	drive->current_speed = 0xff;
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase).  So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
-	const struct ide_port_ops *port_ops;
-	ide_drive_t *tdrive;
-	unsigned long flags, timeout;
-	int i;
-	DEFINE_WAIT(wait);
-
-	spin_lock_irqsave(&hwif->lock, flags);
-
-	/* We must not reset with running handlers */
-	BUG_ON(hwif->handler != NULL);
-
-	/* For an ATAPI device, first try an ATAPI SRST. */
-	if (drive->media != ide_disk && !do_not_try_atapi) {
-		pre_reset(drive);
-		SELECT_DRIVE(drive);
-		udelay (20);
-		tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
-		ndelay(400);
-		hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
-		hwif->polling = 1;
-		__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
-		spin_unlock_irqrestore(&hwif->lock, flags);
-		return ide_started;
-	}
-
-	/* We must not disturb devices in the IDE_DFLAG_PARKED state. */
-	do {
-		unsigned long now;
-
-		prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
-		timeout = jiffies;
-		ide_port_for_each_dev(i, tdrive, hwif) {
-			if (tdrive->dev_flags & IDE_DFLAG_PRESENT &&
-			    tdrive->dev_flags & IDE_DFLAG_PARKED &&
-			    time_after(tdrive->sleep, timeout))
-				timeout = tdrive->sleep;
-		}
-
-		now = jiffies;
-		if (time_before_eq(timeout, now))
-			break;
-
-		spin_unlock_irqrestore(&hwif->lock, flags);
-		timeout = schedule_timeout_uninterruptible(timeout - now);
-		spin_lock_irqsave(&hwif->lock, flags);
-	} while (timeout);
-	finish_wait(&ide_park_wq, &wait);
-
-	/*
-	 * First, reset any device state data we were maintaining
-	 * for any of the drives on this interface.
-	 */
-	ide_port_for_each_dev(i, tdrive, hwif)
-		pre_reset(tdrive);
-
-	if (io_ports->ctl_addr == 0) {
-		spin_unlock_irqrestore(&hwif->lock, flags);
-		ide_complete_drive_reset(drive, -ENXIO);
-		return ide_stopped;
-	}
-
-	/*
-	 * Note that we also set nIEN while resetting the device,
-	 * to mask unwanted interrupts from the interface during the reset.
-	 * However, due to the design of PC hardware, this will cause an
-	 * immediate interrupt due to the edge transition it produces.
-	 * This single interrupt gives us a "fast poll" for drives that
-	 * recover from reset very quickly, saving us the first 50ms wait time.
-	 *
-	 * TODO: add ->softreset method and stop abusing ->set_irq
-	 */
-	/* set SRST and nIEN */
-	tp_ops->set_irq(hwif, 4);
-	/* more than enough time */
-	udelay(10);
-	/* clear SRST, leave nIEN (unless device is on the quirk list) */
-	tp_ops->set_irq(hwif, drive->quirk_list == 2);
-	/* more than enough time */
-	udelay(10);
-	hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
-	hwif->polling = 1;
-	__ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-
-	/*
-	 * Some weird controller like resetting themselves to a strange
-	 * state when the disks are reset this way. At least, the Winbond
-	 * 553 documentation says that
-	 */
-	port_ops = hwif->port_ops;
-	if (port_ops && port_ops->resetproc)
-		port_ops->resetproc(drive);
-
-	spin_unlock_irqrestore(&hwif->lock, flags);
-	return ide_started;
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
-{
-	return do_reset1(drive, 0);
-}
-
-EXPORT_SYMBOL(ide_do_reset);
 
 /*
  * ide_wait_not_busy() waits for the currently selected device on the hwif
@@ -1187,7 +497,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif,
 {
 	u8 stat = 0;
 
-	while(timeout--) {
+	while (timeout--) {
 		/*
 		 * Turn this into a schedule() sleep once I'm sure
 		 * about locking issues (2.5 work ?).
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-io-std.c linux-libre-2.6.30-gnu1/drivers/ide/ide-io-std.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-io-std.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-io-std.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,260 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
+    defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#include <asm/ide.h>
+#else
+#include <asm-generic/ide_iops.h>
+#endif
+
+/*
+ *	Conventional PIO operations for ATA devices
+ */
+
+static u8 ide_inb(unsigned long port)
+{
+	return (u8) inb(port);
+}
+
+static void ide_outb(u8 val, unsigned long port)
+{
+	outb(val, port);
+}
+
+/*
+ *	MMIO operations, typically used for SATA controllers
+ */
+
+static u8 ide_mm_inb(unsigned long port)
+{
+	return (u8) readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+	writeb(value, (void __iomem *) port);
+}
+
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+	else
+		outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		return readb((void __iomem *)hwif->io_ports.status_addr);
+	else
+		return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		return readb((void __iomem *)hwif->io_ports.ctl_addr);
+	else
+		return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
+{
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+	else
+		outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_write_devctl);
+
+void ide_dev_select(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 select = drive->select | ATA_DEVICE_OBS;
+
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		writeb(select, (void __iomem *)hwif->io_ports.device_addr);
+	else
+		outb(select, hwif->io_ports.device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_dev_select);
+
+void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct ide_io_ports *io_ports = &hwif->io_ports;
+	void (*tf_outb)(u8 addr, unsigned long port);
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+	if (mmio)
+		tf_outb = ide_mm_outb;
+	else
+		tf_outb = ide_outb;
+
+	if (valid & IDE_VALID_FEATURE)
+		tf_outb(tf->feature, io_ports->feature_addr);
+	if (valid & IDE_VALID_NSECT)
+		tf_outb(tf->nsect, io_ports->nsect_addr);
+	if (valid & IDE_VALID_LBAL)
+		tf_outb(tf->lbal, io_ports->lbal_addr);
+	if (valid & IDE_VALID_LBAM)
+		tf_outb(tf->lbam, io_ports->lbam_addr);
+	if (valid & IDE_VALID_LBAH)
+		tf_outb(tf->lbah, io_ports->lbah_addr);
+	if (valid & IDE_VALID_DEVICE)
+		tf_outb(tf->device, io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_load);
+
+void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct ide_io_ports *io_ports = &hwif->io_ports;
+	u8 (*tf_inb)(unsigned long port);
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+	if (mmio)
+		tf_inb  = ide_mm_inb;
+	else
+		tf_inb  = ide_inb;
+
+	if (valid & IDE_VALID_ERROR)
+		tf->error  = tf_inb(io_ports->feature_addr);
+	if (valid & IDE_VALID_NSECT)
+		tf->nsect  = tf_inb(io_ports->nsect_addr);
+	if (valid & IDE_VALID_LBAL)
+		tf->lbal   = tf_inb(io_ports->lbal_addr);
+	if (valid & IDE_VALID_LBAM)
+		tf->lbam   = tf_inb(io_ports->lbam_addr);
+	if (valid & IDE_VALID_LBAH)
+		tf->lbah   = tf_inb(io_ports->lbah_addr);
+	if (valid & IDE_VALID_DEVICE)
+		tf->device = tf_inb(io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_read);
+
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data.  We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static void ata_vlb_sync(unsigned long port)
+{
+	(void)inb(port);
+	(void)inb(port);
+	(void)inb(port);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd len is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+		    unsigned int len)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct ide_io_ports *io_ports = &hwif->io_ports;
+	unsigned long data_addr = io_ports->data_addr;
+	unsigned int words = (len + 1) >> 1;
+	u8 io_32bit = drive->io_32bit;
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+	if (io_32bit) {
+		unsigned long uninitialized_var(flags);
+
+		if ((io_32bit & 2) && !mmio) {
+			local_irq_save(flags);
+			ata_vlb_sync(io_ports->nsect_addr);
+		}
+
+		words >>= 1;
+		if (mmio)
+			__ide_mm_insl((void __iomem *)data_addr, buf, words);
+		else
+			insl(data_addr, buf, words);
+
+		if ((io_32bit & 2) && !mmio)
+			local_irq_restore(flags);
+
+		if (((len + 1) & 3) < 2)
+			return;
+
+		buf += len & ~3;
+		words = 1;
+	}
+
+	if (mmio)
+		__ide_mm_insw((void __iomem *)data_addr, buf, words);
+	else
+		insw(data_addr, buf, words);
+}
+EXPORT_SYMBOL_GPL(ide_input_data);
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+		     unsigned int len)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct ide_io_ports *io_ports = &hwif->io_ports;
+	unsigned long data_addr = io_ports->data_addr;
+	unsigned int words = (len + 1) >> 1;
+	u8 io_32bit = drive->io_32bit;
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+	if (io_32bit) {
+		unsigned long uninitialized_var(flags);
+
+		if ((io_32bit & 2) && !mmio) {
+			local_irq_save(flags);
+			ata_vlb_sync(io_ports->nsect_addr);
+		}
+
+		words >>= 1;
+		if (mmio)
+			__ide_mm_outsl((void __iomem *)data_addr, buf, words);
+		else
+			outsl(data_addr, buf, words);
+
+		if ((io_32bit & 2) && !mmio)
+			local_irq_restore(flags);
+
+		if (((len + 1) & 3) < 2)
+			return;
+
+		buf += len & ~3;
+		words = 1;
+	}
+
+	if (mmio)
+		__ide_mm_outsw((void __iomem *)data_addr, buf, words);
+	else
+		outsw(data_addr, buf, words);
+}
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+const struct ide_tp_ops default_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= ide_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-lib.c linux-libre-2.6.30-gnu1/drivers/ide/ide-lib.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-lib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-lib.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,163 +5,6 @@
 #include <linux/ide.h>
 #include <linux/bitops.h>
 
-static const char *udma_str[] =
-	 { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
-	   "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
-static const char *mwdma_str[] =
-	{ "MWDMA0", "MWDMA1", "MWDMA2" };
-static const char *swdma_str[] =
-	{ "SWDMA0", "SWDMA1", "SWDMA2" };
-static const char *pio_str[] =
-	{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
-
-/**
- *	ide_xfer_verbose	-	return IDE mode names
- *	@mode: transfer mode
- *
- *	Returns a constant string giving the name of the mode
- *	requested.
- */
-
-const char *ide_xfer_verbose(u8 mode)
-{
-	const char *s;
-	u8 i = mode & 0xf;
-
-	if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
-		s = udma_str[i];
-	else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
-		s = mwdma_str[i];
-	else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
-		s = swdma_str[i];
-	else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
-		s = pio_str[i & 0x7];
-	else if (mode == XFER_PIO_SLOW)
-		s = "PIO SLOW";
-	else
-		s = "XFER ERROR";
-
-	return s;
-}
-EXPORT_SYMBOL(ide_xfer_verbose);
-
-/**
- *	ide_rate_filter		-	filter transfer mode
- *	@drive: IDE device
- *	@speed: desired speed
- *
- *	Given the available transfer modes this function returns
- *	the best available speed at or below the speed requested.
- *
- *	TODO: check device PIO capabilities
- */
-
-static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 mode = ide_find_dma_mode(drive, speed);
-
-	if (mode == 0) {
-		if (hwif->pio_mask)
-			mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
-		else
-			mode = XFER_PIO_4;
-	}
-
-/*	printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
-
-	return min(speed, mode);
-}
-
-/**
- *	ide_get_best_pio_mode	-	get PIO mode from drive
- *	@drive: drive to consider
- *	@mode_wanted: preferred mode
- *	@max_mode: highest allowed mode
- *
- *	This routine returns the recommended PIO settings for a given drive,
- *	based on the drive->id information and the ide_pio_blacklist[].
- *
- *	Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
- *	This is used by most chipset support modules when "auto-tuning".
- */
-
-u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
-{
-	u16 *id = drive->id;
-	int pio_mode = -1, overridden = 0;
-
-	if (mode_wanted != 255)
-		return min_t(u8, mode_wanted, max_mode);
-
-	if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
-		pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
-
-	if (pio_mode != -1) {
-		printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
-	} else {
-		pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
-		if (pio_mode > 2) {	/* 2 is maximum allowed tPIO value */
-			pio_mode = 2;
-			overridden = 1;
-		}
-
-		if (id[ATA_ID_FIELD_VALID] & 2) {	      /* ATA2? */
-			if (ata_id_has_iordy(id)) {
-				if (id[ATA_ID_PIO_MODES] & 7) {
-					overridden = 0;
-					if (id[ATA_ID_PIO_MODES] & 4)
-						pio_mode = 5;
-					else if (id[ATA_ID_PIO_MODES] & 2)
-						pio_mode = 4;
-					else
-						pio_mode = 3;
-				}
-			}
-		}
-
-		if (overridden)
-			printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
-					 drive->name);
-	}
-
-	if (pio_mode > max_mode)
-		pio_mode = max_mode;
-
-	return pio_mode;
-}
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
-
-/* req_pio == "255" for auto-tune */
-void ide_set_pio(ide_drive_t *drive, u8 req_pio)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-	u8 host_pio, pio;
-
-	if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
-	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
-		return;
-
-	BUG_ON(hwif->pio_mask == 0x00);
-
-	host_pio = fls(hwif->pio_mask) - 1;
-
-	pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
-
-	/*
-	 * TODO:
-	 * - report device max PIO mode
-	 * - check req_pio != 255 against device max PIO mode
-	 */
-	printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
-			  drive->name, host_pio, req_pio,
-			  req_pio == 255 ? "(auto-tune)" : "", pio);
-
-	(void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
-}
-EXPORT_SYMBOL_GPL(ide_set_pio);
-
 /**
  *	ide_toggle_bounce	-	handle bounce buffering
  *	@drive: drive to update
@@ -188,117 +31,17 @@ void ide_toggle_bounce(ide_drive_t *driv
 		blk_queue_bounce_limit(drive->queue, addr);
 }
 
-int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-
-	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
-		return 0;
-
-	if (port_ops == NULL || port_ops->set_pio_mode == NULL)
-		return -1;
-
-	/*
-	 * TODO: temporary hack for some legacy host drivers that didn't
-	 * set transfer mode on the device in ->set_pio_mode method...
-	 */
-	if (port_ops->set_dma_mode == NULL) {
-		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
-		return 0;
-	}
-
-	if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
-		if (ide_config_drive_speed(drive, mode))
-			return -1;
-		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
-		return 0;
-	} else {
-		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
-		return ide_config_drive_speed(drive, mode);
-	}
-}
-
-int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-
-	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
-		return 0;
-
-	if (port_ops == NULL || port_ops->set_dma_mode == NULL)
-		return -1;
-
-	if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
-		if (ide_config_drive_speed(drive, mode))
-			return -1;
-		port_ops->set_dma_mode(drive, mode);
-		return 0;
-	} else {
-		port_ops->set_dma_mode(drive, mode);
-		return ide_config_drive_speed(drive, mode);
-	}
-}
-EXPORT_SYMBOL_GPL(ide_set_dma_mode);
-
-/**
- *	ide_set_xfer_rate	-	set transfer rate
- *	@drive: drive to set
- *	@rate: speed to attempt to set
- *
- *	General helper for setting the speed of an IDE device. This
- *	function knows about user enforced limits from the configuration
- *	which ->set_pio_mode/->set_dma_mode does not.
- */
-
-int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_port_ops *port_ops = hwif->port_ops;
-
-	if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
-	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
-		return -1;
-
-	rate = ide_rate_filter(drive, rate);
-
-	BUG_ON(rate < XFER_PIO_0);
-
-	if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
-		return ide_set_pio_mode(drive, rate);
-
-	return ide_set_dma_mode(drive, rate);
-}
-
-static void ide_dump_opcode(ide_drive_t *drive)
-{
-	struct request *rq = drive->hwif->rq;
-	ide_task_t *task = NULL;
-
-	if (!rq)
-		return;
-
-	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
-		task = rq->special;
-
-	printk(KERN_ERR "ide: failed opcode was: ");
-	if (task == NULL)
-		printk(KERN_CONT "unknown\n");
-	else
-		printk(KERN_CONT "0x%02x\n", task->tf.command);
-}
-
-u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
+u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48)
 {
+	struct ide_taskfile *tf = &cmd->tf;
 	u32 high, low;
 
-	if (lba48)
-		high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) |
-			tf->hob_lbal;
-	else
-		high = tf->device & 0xf;
 	low  = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+	if (lba48) {
+		tf = &cmd->hob;
+		high = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
+	} else
+		high = tf->device & 0xf;
 
 	return ((u64)high << 24) | low;
 }
@@ -306,22 +49,23 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr);
 
 static void ide_dump_sector(ide_drive_t *drive)
 {
-	ide_task_t task;
-	struct ide_taskfile *tf = &task.tf;
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
 	u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
 
-	memset(&task, 0, sizeof(task));
-	if (lba48)
-		task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
-				IDE_TFLAG_LBA48;
-	else
-		task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+	memset(&cmd, 0, sizeof(cmd));
+	if (lba48) {
+		cmd.valid.in.tf  = IDE_VALID_LBA;
+		cmd.valid.in.hob = IDE_VALID_LBA;
+		cmd.tf_flags = IDE_TFLAG_LBA48;
+	} else
+		cmd.valid.in.tf  = IDE_VALID_LBA | IDE_VALID_DEVICE;
 
-	drive->hwif->tp_ops->tf_read(drive, &task);
+	ide_tf_readback(drive, &cmd);
 
 	if (lba48 || (tf->device & ATA_LBA))
 		printk(KERN_CONT ", LBAsect=%llu",
-			(unsigned long long)ide_get_lba_addr(tf, lba48));
+			(unsigned long long)ide_get_lba_addr(&cmd, lba48));
 	else
 		printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam,
 			tf->device & 0xf, tf->lbal);
@@ -329,7 +73,7 @@ static void ide_dump_sector(ide_drive_t
 
 static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
 {
-	printk(KERN_ERR "{ ");
+	printk(KERN_CONT "{ ");
 	if (err & ATA_ABORTED)
 		printk(KERN_CONT "DriveStatusError ");
 	if (err & ATA_ICRC)
@@ -359,7 +103,7 @@ static void ide_dump_ata_error(ide_drive
 
 static void ide_dump_atapi_error(ide_drive_t *drive, u8 err)
 {
-	printk(KERN_ERR "{ ");
+	printk(KERN_CONT "{ ");
 	if (err & ATAPI_ILI)
 		printk(KERN_CONT "IllegalLengthIndication ");
 	if (err & ATAPI_EOM)
@@ -417,7 +161,10 @@ u8 ide_dump_status(ide_drive_t *drive, c
 		else
 			ide_dump_atapi_error(drive, err);
 	}
-	ide_dump_opcode(drive);
+
+	printk(KERN_ERR "%s: possibly failed opcode: 0x%02x\n",
+		drive->name, drive->hwif->cmd.tf.command);
+
 	return err;
 }
 EXPORT_SYMBOL(ide_dump_status);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-park.c linux-libre-2.6.30-gnu1/drivers/ide/ide-park.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-park.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-park.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,6 +60,33 @@ out:
 	return;
 }
 
+ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
+{
+	struct ide_cmd cmd;
+	struct ide_taskfile *tf = &cmd.tf;
+
+	memset(&cmd, 0, sizeof(cmd));
+	if (rq->cmd[0] == REQ_PARK_HEADS) {
+		drive->sleep = *(unsigned long *)rq->special;
+		drive->dev_flags |= IDE_DFLAG_SLEEPING;
+		tf->command = ATA_CMD_IDLEIMMEDIATE;
+		tf->feature = 0x44;
+		tf->lbal = 0x4c;
+		tf->lbam = 0x4e;
+		tf->lbah = 0x55;
+		cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+		cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	} else		/* cmd == REQ_UNPARK_HEADS */
+		tf->command = ATA_CMD_CHK_POWER;
+
+	cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+	cmd.protocol = ATA_PROT_NODATA;
+
+	cmd.rq = rq;
+
+	return do_rw_taskfile(drive, &cmd);
+}
+
 ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
 		      char *buf)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-pci-generic.c linux-libre-2.6.30-gnu1/drivers/ide/ide-pci-generic.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-pci-generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-pci-generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,15 @@ static int ide_generic_all;		/* Set to c
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
-#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
+static void netcell_quirkproc(ide_drive_t *drive)
+{
+	/* mark words 85-87 as valid */
+	drive->id[ATA_ID_CSF_DEFAULT] |= 0x4000;
+}
+
+static const struct ide_port_ops netcell_port_ops = {
+	.quirkproc		= netcell_quirkproc,
+};
 
 #define DECLARE_GENERIC_PCI_DEV(extra_flags) \
 	{ \
@@ -61,7 +69,7 @@ static const struct ide_port_info generi
 	/*  2: SAMURAI / HT6565 / HINT_IDE */
 	DECLARE_GENERIC_PCI_DEV(0),
 	/*  3: UM8673F / UM8886A / UM8886BF */
-	DECLARE_GENERIC_PCI_DEV(IDE_HFLAGS_UMC),
+	DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_DMA),
 	/*  4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */
 	DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA),
 
@@ -76,6 +84,7 @@ static const struct ide_port_info generi
 
 	{	/* 6: Revolution */
 		.name		= DRV_NAME,
+		.port_ops	= &netcell_port_ops,
 		.host_flags	= IDE_HFLAG_CLEAR_SIMPLEX |
 				  IDE_HFLAG_TRUST_BIOS_FOR_DMA |
 				  IDE_HFLAG_OFF_BOARD,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-pm.c linux-libre-2.6.30-gnu1/drivers/ide/ide-pm.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-pm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-pm.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,5 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 {
@@ -8,7 +7,7 @@ int generic_ide_suspend(struct device *d
 	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq;
 	struct request_pm_state rqpm;
-	ide_task_t args;
+	struct ide_cmd cmd;
 	int ret;
 
 	/* call ACPI _GTM only once */
@@ -16,10 +15,10 @@ int generic_ide_suspend(struct device *d
 		ide_acpi_get_timing(hwif);
 
 	memset(&rqpm, 0, sizeof(rqpm));
-	memset(&args, 0, sizeof(args));
+	memset(&cmd, 0, sizeof(cmd));
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
 	rq->cmd_type = REQ_TYPE_PM_SUSPEND;
-	rq->special = &args;
+	rq->special = &cmd;
 	rq->data = &rqpm;
 	rqpm.pm_step = IDE_PM_START_SUSPEND;
 	if (mesg.event == PM_EVENT_PRETHAW)
@@ -42,7 +41,7 @@ int generic_ide_resume(struct device *de
 	ide_hwif_t *hwif = drive->hwif;
 	struct request *rq;
 	struct request_pm_state rqpm;
-	ide_task_t args;
+	struct ide_cmd cmd;
 	int err;
 
 	/* call ACPI _PS0 / _STM only once */
@@ -54,11 +53,11 @@ int generic_ide_resume(struct device *de
 	ide_acpi_exec_tfs(drive);
 
 	memset(&rqpm, 0, sizeof(rqpm));
-	memset(&args, 0, sizeof(args));
+	memset(&cmd, 0, sizeof(cmd));
 	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
 	rq->cmd_type = REQ_TYPE_PM_RESUME;
 	rq->cmd_flags |= REQ_PREEMPT;
-	rq->special = &args;
+	rq->special = &cmd;
 	rq->data = &rqpm;
 	rqpm.pm_step = IDE_PM_START_RESUME;
 	rqpm.pm_state = PM_EVENT_ON;
@@ -109,9 +108,9 @@ void ide_complete_power_step(ide_drive_t
 ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
 {
 	struct request_pm_state *pm = rq->data;
-	ide_task_t *args = rq->special;
+	struct ide_cmd *cmd = rq->special;
 
-	memset(args, 0, sizeof(*args));
+	memset(cmd, 0, sizeof(*cmd));
 
 	switch (pm->pm_step) {
 	case IDE_PM_FLUSH_CACHE:	/* Suspend step 1 (flush cache) */
@@ -124,12 +123,12 @@ ide_startstop_t ide_start_power_step(ide
 			return ide_stopped;
 		}
 		if (ata_id_flush_ext_enabled(drive->id))
-			args->tf.command = ATA_CMD_FLUSH_EXT;
+			cmd->tf.command = ATA_CMD_FLUSH_EXT;
 		else
-			args->tf.command = ATA_CMD_FLUSH;
+			cmd->tf.command = ATA_CMD_FLUSH;
 		goto out_do_tf;
 	case IDE_PM_STANDBY:		/* Suspend step 2 (standby) */
-		args->tf.command = ATA_CMD_STANDBYNOW1;
+		cmd->tf.command = ATA_CMD_STANDBYNOW1;
 		goto out_do_tf;
 	case IDE_PM_RESTORE_PIO:	/* Resume step 1 (restore PIO) */
 		ide_set_max_pio(drive);
@@ -142,7 +141,7 @@ ide_startstop_t ide_start_power_step(ide
 			ide_complete_power_step(drive, rq);
 		return ide_stopped;
 	case IDE_PM_IDLE:		/* Resume step 2 (idle) */
-		args->tf.command = ATA_CMD_IDLEIMMEDIATE;
+		cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
 		goto out_do_tf;
 	case IDE_PM_RESTORE_DMA:	/* Resume step 3 (restore DMA) */
 		/*
@@ -160,27 +159,35 @@ ide_startstop_t ide_start_power_step(ide
 	}
 
 	pm->pm_step = IDE_PM_COMPLETED;
+
 	return ide_stopped;
 
 out_do_tf:
-	args->tf_flags	 = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	args->data_phase = TASKFILE_NO_DATA;
-	return do_rw_taskfile(drive, args);
+	cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd->valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	cmd->protocol = ATA_PROT_NODATA;
+
+	return do_rw_taskfile(drive, cmd);
 }
 
 /**
- *	ide_complete_pm_request - end the current Power Management request
+ *	ide_complete_pm_rq - end the current Power Management request
  *	@drive: target drive
  *	@rq: request
  *
  *	This function cleans up the current PM request and stops the queue
  *	if necessary.
  */
-void ide_complete_pm_request(ide_drive_t *drive, struct request *rq)
+void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
 {
 	struct request_queue *q = drive->queue;
+	struct request_pm_state *pm = rq->data;
 	unsigned long flags;
 
+	ide_complete_power_step(drive, rq);
+	if (pm->pm_step != IDE_PM_COMPLETED)
+		return;
+
 #ifdef DEBUG_PM
 	printk("%s: completing PM request, %s\n", drive->name,
 	       blk_pm_suspend_request(rq) ? "suspend" : "resume");
@@ -217,6 +224,7 @@ void ide_check_pm_state(ide_drive_t *dri
 		 * point.
 		 */
 		ide_hwif_t *hwif = drive->hwif;
+		const struct ide_tp_ops *tp_ops = hwif->tp_ops;
 		struct request_queue *q = drive->queue;
 		unsigned long flags;
 		int rc;
@@ -226,8 +234,8 @@ void ide_check_pm_state(ide_drive_t *dri
 		rc = ide_wait_not_busy(hwif, 35000);
 		if (rc)
 			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
-		SELECT_DRIVE(drive);
-		hwif->tp_ops->set_irq(hwif, 1);
+		tp_ops->dev_select(drive);
+		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 		rc = ide_wait_not_busy(hwif, 100000);
 		if (rc)
 			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-pnp.c linux-libre-2.6.30-gnu1/drivers/ide/ide-pnp.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-pnp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-pnp.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,10 @@ static struct pnp_device_id idepnp_devic
 	{.id = ""}
 };
 
+static const struct ide_port_info ide_pnp_port_info = {
+	.host_flags		= IDE_HFLAG_NO_DMA,
+};
+
 static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
 	struct ide_host *host;
@@ -60,7 +64,7 @@ static int idepnp_probe(struct pnp_dev *
 	hw.irq = pnp_irq(dev, 0);
 	hw.chipset = ide_generic;
 
-	rc = ide_host_add(NULL, hws, &host);
+	rc = ide_host_add(&ide_pnp_port_info, hws, &host);
 	if (rc)
 		goto out;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-probe.c linux-libre-2.6.30-gnu1/drivers/ide/ide-probe.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-probe.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,16 +181,16 @@ static void ide_classify_atapi_dev(ide_d
  *	do_identify	-	identify a drive
  *	@drive: drive to identify 
  *	@cmd: command used
+ *	@id: buffer for IDENTIFY data
  *
  *	Called when we have issued a drive identify command to
  *	read and parse the results. This function is run with
  *	interrupts disabled. 
  */
 
-static void do_identify(ide_drive_t *drive, u8 cmd)
+static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	u16 *id = drive->id;
 	char *m = (char *)&id[ATA_ID_PROD];
 	unsigned long flags;
 	int bswap = 1;
@@ -228,43 +228,25 @@ static void do_identify(ide_drive_t *dri
 	m[ATA_ID_PROD_LEN - 1] = '\0';
 
 	if (strstr(m, "E X A B Y T E N E S T"))
-		goto err_misc;
-
-	drive->dev_flags |= IDE_DFLAG_PRESENT;
-	drive->dev_flags &= ~IDE_DFLAG_DEAD;
-
-	/*
-	 * Check for an ATAPI device
-	 */
-	if (cmd == ATA_CMD_ID_ATAPI)
-		ide_classify_atapi_dev(drive);
+		drive->dev_flags &= ~IDE_DFLAG_PRESENT;
 	else
-	/*
-	 * Not an ATAPI device: looks like a "regular" hard disk
-	 */
-		ide_classify_ata_dev(drive);
-	return;
-err_misc:
-	kfree(id);
-	drive->dev_flags &= ~IDE_DFLAG_PRESENT;
+		drive->dev_flags |= IDE_DFLAG_PRESENT;
 }
 
 /**
- *	actual_try_to_identify	-	send ata/atapi identify
+ *	ide_dev_read_id	-	send ATA/ATAPI IDENTIFY command
  *	@drive: drive to identify
  *	@cmd: command to use
+ *	@id: buffer for IDENTIFY data
  *
- *	try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- *	and waits for a response.  It also monitors irqs while this is
- *	happening, in hope of automatically determining which one is
- *	being used by the interface.
+ *	Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
  *
  *	Returns:	0  device was identified
  *			1  device timed-out (no response to identify request)
  *			2  device aborted the command (refused to identify itself)
  */
 
-static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -273,6 +255,13 @@ static int actual_try_to_identify (ide_d
 	unsigned long timeout;
 	u8 s = 0, a = 0;
 
+	/*
+	 * Disable device IRQ.  Otherwise we'll get spurious interrupts
+	 * during the identify phase that the IRQ handler isn't expecting.
+	 */
+	if (io_ports->ctl_addr)
+		tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
+
 	/* take a deep breath */
 	msleep(50);
 
@@ -294,13 +283,11 @@ static int actual_try_to_identify (ide_d
 	 * identify command to be sure of reply
 	 */
 	if (cmd == ATA_CMD_ID_ATAPI) {
-		ide_task_t task;
+		struct ide_taskfile tf;
 
-		memset(&task, 0, sizeof(task));
+		memset(&tf, 0, sizeof(tf));
 		/* disable DMA & overlap */
-		task.tf_flags = IDE_TFLAG_OUT_FEATURE;
-
-		tp_ops->tf_load(drive, &task);
+		tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE);
 	}
 
 	/* ask drive for ID */
@@ -308,7 +295,7 @@ static int actual_try_to_identify (ide_d
 
 	timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
 
-	if (ide_busy_sleep(hwif, timeout, use_altstatus))
+	if (ide_busy_sleep(drive, timeout, use_altstatus))
 		return 1;
 
 	/* wait for IRQ and ATA_DRQ */
@@ -317,7 +304,7 @@ static int actual_try_to_identify (ide_d
 
 	if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
 		/* drive returned ID */
-		do_identify(drive, cmd);
+		do_identify(drive, cmd, id);
 		/* drive responded with ID */
 		rc = 0;
 		/* clear drive IRQ */
@@ -329,65 +316,9 @@ static int actual_try_to_identify (ide_d
 	return rc;
 }
 
-/**
- *	try_to_identify	-	try to identify a drive
- *	@drive: drive to probe
- *	@cmd: command to use
- *
- *	Issue the identify command and then do IRQ probing to
- *	complete the identification when needed by finding the
- *	IRQ the drive is attached to
- */
- 
-static int try_to_identify (ide_drive_t *drive, u8 cmd)
+int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
-	int retval;
-	int autoprobe = 0;
-	unsigned long cookie = 0;
-
-	/*
-	 * Disable device irq unless we need to
-	 * probe for it. Otherwise we'll get spurious
-	 * interrupts during the identify-phase that
-	 * the irq handler isn't expecting.
-	 */
-	if (hwif->io_ports.ctl_addr) {
-		if (!hwif->irq) {
-			autoprobe = 1;
-			cookie = probe_irq_on();
-		}
-		tp_ops->set_irq(hwif, autoprobe);
-	}
-
-	retval = actual_try_to_identify(drive, cmd);
-
-	if (autoprobe) {
-		int irq;
-
-		tp_ops->set_irq(hwif, 0);
-		/* clear drive IRQ */
-		(void)tp_ops->read_status(hwif);
-		udelay(5);
-		irq = probe_irq_off(cookie);
-		if (!hwif->irq) {
-			if (irq > 0) {
-				hwif->irq = irq;
-			} else {
-				/* Mmmm.. multiple IRQs..
-				 * don't know which was ours
-				 */
-				printk(KERN_ERR "%s: IRQ probe failed (0x%lx)\n",
-					drive->name, cookie);
-			}
-		}
-	}
-	return retval;
-}
-
-int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
-{
 	u8 stat;
 
 	timeout += jiffies;
@@ -400,19 +331,18 @@ int ide_busy_sleep(ide_hwif_t *hwif, uns
 			return 0;
 	} while (time_before(jiffies, timeout));
 
+	printk(KERN_ERR "%s: timeout in %s\n", drive->name, __func__);
+
 	return 1;	/* drive timed-out */
 }
 
 static u8 ide_read_device(ide_drive_t *drive)
 {
-	ide_task_t task;
-
-	memset(&task, 0, sizeof(task));
-	task.tf_flags = IDE_TFLAG_IN_DEVICE;
+	struct ide_taskfile tf;
 
-	drive->hwif->tp_ops->tf_read(drive, &task);
+	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE);
 
-	return task.tf.device;
+	return tf.device;
 }
 
 /**
@@ -440,6 +370,7 @@ static int do_probe (ide_drive_t *drive,
 {
 	ide_hwif_t *hwif = drive->hwif;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+	u16 *id = drive->id;
 	int rc;
 	u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
 
@@ -457,13 +388,13 @@ static int do_probe (ide_drive_t *drive,
 	 * (e.g. crw9624 as drive0 with disk as slave)
 	 */
 	msleep(50);
-	SELECT_DRIVE(drive);
+	tp_ops->dev_select(drive);
 	msleep(50);
 
 	if (ide_read_device(drive) != drive->select && present == 0) {
 		if (drive->dn & 1) {
 			/* exit with drive0 selected */
-			SELECT_DRIVE(hwif->devices[0]);
+			tp_ops->dev_select(hwif->devices[0]);
 			/* allow ATA_BUSY to assert & clear */
 			msleep(50);
 		}
@@ -475,11 +406,10 @@ static int do_probe (ide_drive_t *drive,
 
 	if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
 	    present || cmd == ATA_CMD_ID_ATAPI) {
-		/* send cmd and wait */
-		if ((rc = try_to_identify(drive, cmd))) {
+		rc = ide_dev_read_id(drive, cmd, id);
+		if (rc)
 			/* failed: try again */
-			rc = try_to_identify(drive,cmd);
-		}
+			rc = ide_dev_read_id(drive, cmd, id);
 
 		stat = tp_ops->read_status(hwif);
 
@@ -490,11 +420,11 @@ static int do_probe (ide_drive_t *drive,
 			printk(KERN_ERR "%s: no response (status = 0x%02x), "
 					"resetting drive\n", drive->name, stat);
 			msleep(50);
-			SELECT_DRIVE(drive);
+			tp_ops->dev_select(drive);
 			msleep(50);
 			tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
-			(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
-			rc = try_to_identify(drive, cmd);
+			(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
+			rc = ide_dev_read_id(drive, cmd, id);
 		}
 
 		/* ensure drive IRQ is clear */
@@ -509,7 +439,7 @@ static int do_probe (ide_drive_t *drive,
 	}
 	if (drive->dn & 1) {
 		/* exit with drive0 selected */
-		SELECT_DRIVE(hwif->devices[0]);
+		tp_ops->dev_select(hwif->devices[0]);
 		msleep(50);
 		/* ensure drive irq is clear */
 		(void)tp_ops->read_status(hwif);
@@ -517,37 +447,6 @@ static int do_probe (ide_drive_t *drive,
 	return rc;
 }
 
-/*
- *
- */
-static void enable_nest (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
-	u8 stat;
-
-	printk(KERN_INFO "%s: enabling %s -- ",
-		hwif->name, (char *)&drive->id[ATA_ID_PROD]);
-
-	SELECT_DRIVE(drive);
-	msleep(50);
-	tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST);
-
-	if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) {
-		printk(KERN_CONT "failed (timeout)\n");
-		return;
-	}
-
-	msleep(50);
-
-	stat = tp_ops->read_status(hwif);
-
-	if (!OK_STAT(stat, 0, BAD_STAT))
-		printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
-	else
-		printk(KERN_CONT "success\n");
-}
-
 /**
  *	probe_for_drives	-	upper level drive probe
  *	@drive: drive to probe for
@@ -563,6 +462,8 @@ static void enable_nest (ide_drive_t *dr
 static u8 probe_for_drive(ide_drive_t *drive)
 {
 	char *m;
+	int rc;
+	u8 cmd;
 
 	/*
 	 *	In order to keep things simple we have an id
@@ -586,20 +487,17 @@ static u8 probe_for_drive(ide_drive_t *d
 
 	/* skip probing? */
 	if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
-retry:
 		/* if !(success||timed-out) */
-		if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
+		cmd = ATA_CMD_ID_ATA;
+		rc = do_probe(drive, cmd);
+		if (rc >= 2) {
 			/* look for ATAPI device */
-			(void)do_probe(drive, ATA_CMD_ID_ATAPI);
+			cmd = ATA_CMD_ID_ATAPI;
+			rc = do_probe(drive, cmd);
+		}
 
 		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-			/* drive not found */
-			return 0;
-
-		if (strstr(m, "E X A B Y T E N E S T")) {
-			enable_nest(drive);
-			goto retry;
-		}
+			goto out_free;
 
 		/* identification failed? */
 		if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -614,12 +512,16 @@ retry:
 				printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
 				drive->dev_flags &= ~IDE_DFLAG_PRESENT;
 			}
+		} else {
+			if (cmd == ATA_CMD_ID_ATAPI)
+				ide_classify_atapi_dev(drive);
+			else
+				ide_classify_ata_dev(drive);
 		}
-		/* drive was found */
 	}
 
 	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-		return 0;
+		goto out_free;
 
 	/* The drive wasn't being helpful. Add generic info only */
 	if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -632,7 +534,10 @@ retry:
 		ide_disk_init_mult_count(drive);
 	}
 
-	return !!(drive->dev_flags & IDE_DFLAG_PRESENT);
+	return 1;
+out_free:
+	kfree(drive->id);
+	return 0;
 }
 
 static void hwif_release_dev(struct device *dev)
@@ -698,6 +603,7 @@ out:
 
 static int ide_port_wait_ready(ide_hwif_t *hwif)
 {
+	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
 	ide_drive_t *drive;
 	int i, rc;
 
@@ -720,8 +626,8 @@ static int ide_port_wait_ready(ide_hwif_
 		/* Ignore disks that we will not probe for later. */
 		if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
 		    (drive->dev_flags & IDE_DFLAG_PRESENT)) {
-			SELECT_DRIVE(drive);
-			hwif->tp_ops->set_irq(hwif, 1);
+			tp_ops->dev_select(drive);
+			tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 			mdelay(2);
 			rc = ide_wait_not_busy(hwif, 35000);
 			if (rc)
@@ -733,7 +639,7 @@ static int ide_port_wait_ready(ide_hwif_
 out:
 	/* Exit function with master reselected (let's be sane) */
 	if (i)
-		SELECT_DRIVE(hwif->devices[0]);
+		tp_ops->dev_select(hwif->devices[0]);
 
 	return rc;
 }
@@ -779,7 +685,6 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
 static int ide_probe_port(ide_hwif_t *hwif)
 {
 	ide_drive_t *drive;
-	unsigned long flags;
 	unsigned int irqd;
 	int i, rc = -ENODEV;
 
@@ -797,9 +702,6 @@ static int ide_probe_port(ide_hwif_t *hw
 	if (irqd)
 		disable_irq(hwif->irq);
 
-	local_save_flags(flags);
-	local_irq_enable_in_hardirq();
-
 	if (ide_port_wait_ready(hwif) == -EBUSY)
 		printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
@@ -813,8 +715,6 @@ static int ide_probe_port(ide_hwif_t *hw
 			rc = 0;
 	}
 
-	local_irq_restore(flags);
-
 	/*
 	 * Use cached IRQ number. It might be (and is...) changed by probe
 	 * code above
@@ -831,29 +731,18 @@ static void ide_port_tune_devices(ide_hw
 	ide_drive_t *drive;
 	int i;
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (drive->dev_flags & IDE_DFLAG_PRESENT) {
-			if (port_ops && port_ops->quirkproc)
-				port_ops->quirkproc(drive);
-		}
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		if (port_ops && port_ops->quirkproc)
+			port_ops->quirkproc(drive);
 	}
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (drive->dev_flags & IDE_DFLAG_PRESENT) {
-			ide_set_max_pio(drive);
-
-			drive->dev_flags |= IDE_DFLAG_NICE1;
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		ide_set_max_pio(drive);
 
-			if (hwif->dma_ops)
-				ide_set_dma(drive);
-		}
-	}
+		drive->dev_flags |= IDE_DFLAG_NICE1;
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
-			drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
-		else
-			drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
+		if (hwif->dma_ops)
+			ide_set_dma(drive);
 	}
 }
 
@@ -924,10 +813,7 @@ static int ide_port_setup_devices(ide_hw
 	int i, j = 0;
 
 	mutex_lock(&ide_cfg_mtx);
-	ide_port_for_each_dev(i, drive, hwif) {
-		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-			continue;
-
+	ide_port_for_each_present_dev(i, drive, hwif) {
 		if (ide_init_queue(drive)) {
 			printk(KERN_ERR "ide: failed to init %s\n",
 					drive->name);
@@ -950,41 +836,19 @@ static int ide_port_setup_devices(ide_hw
 static int init_irq (ide_hwif_t *hwif)
 {
 	struct ide_io_ports *io_ports = &hwif->io_ports;
-	irq_handler_t irq_handler;
-	int sa = 0;
-
-	mutex_lock(&ide_cfg_mtx);
-	spin_lock_init(&hwif->lock);
-
-	init_timer(&hwif->timer);
-	hwif->timer.function = &ide_timer_expiry;
-	hwif->timer.data = (unsigned long)hwif;
+	struct ide_host *host = hwif->host;
+	irq_handler_t irq_handler = host->irq_handler;
+	int sa = host->irq_flags;
 
-	irq_handler = hwif->host->irq_handler;
 	if (irq_handler == NULL)
 		irq_handler = ide_intr;
 
-#if defined(__mc68000__)
-	sa = IRQF_SHARED;
-#endif /* __mc68000__ */
-
-	if (hwif->chipset == ide_pci)
-		sa = IRQF_SHARED;
-
 	if (io_ports->ctl_addr)
-		hwif->tp_ops->set_irq(hwif, 1);
+		hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 
 	if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
 		goto out_up;
 
-	if (!hwif->rqsize) {
-		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
-		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
-			hwif->rqsize = 256;
-		else
-			hwif->rqsize = 65536;
-	}
-
 #if !defined(__mc68000__)
 	printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
 		io_ports->data_addr, io_ports->status_addr,
@@ -997,10 +861,8 @@ static int init_irq (ide_hwif_t *hwif)
 		printk(KERN_CONT " (serialized)");
 	printk(KERN_CONT "\n");
 
-	mutex_unlock(&ide_cfg_mtx);
 	return 0;
 out_up:
-	mutex_unlock(&ide_cfg_mtx);
 	return 1;
 }
 
@@ -1079,34 +941,25 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
 static void drive_release_dev (struct device *dev)
 {
 	ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
-	ide_hwif_t *hwif = drive->hwif;
 
 	ide_proc_unregister_device(drive);
 
-	spin_lock_irq(&hwif->lock);
+	blk_cleanup_queue(drive->queue);
+	drive->queue = NULL;
+
 	kfree(drive->id);
 	drive->id = NULL;
+
 	drive->dev_flags &= ~IDE_DFLAG_PRESENT;
-	/* Messed up locking ... */
-	spin_unlock_irq(&hwif->lock);
-	blk_cleanup_queue(drive->queue);
-	spin_lock_irq(&hwif->lock);
-	drive->queue = NULL;
-	spin_unlock_irq(&hwif->lock);
 
 	complete(&drive->gendev_rel_comp);
 }
 
 static int hwif_init(ide_hwif_t *hwif)
 {
-	int old_irq;
-
 	if (!hwif->irq) {
-		hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
-		if (!hwif->irq) {
-			printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
-			return 0;
-		}
+		printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
+		return 0;
 	}
 
 	if (register_blkdev(hwif->major, hwif->name))
@@ -1124,29 +977,12 @@ static int hwif_init(ide_hwif_t *hwif)
 
 	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
-	if (init_irq(hwif) == 0)
-		goto done;
-
-	old_irq = hwif->irq;
-	/*
-	 *	It failed to initialise. Find the default IRQ for 
-	 *	this port and try that.
-	 */
-	hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
-	if (!hwif->irq) {
-		printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
-			hwif->name, old_irq);
-		goto out;
-	}
 	if (init_irq(hwif)) {
-		printk(KERN_ERR "%s: probed IRQ %d and default IRQ %d failed\n",
-			hwif->name, old_irq, hwif->irq);
+		printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
+			hwif->name, hwif->irq);
 		goto out;
 	}
-	printk(KERN_WARNING "%s: probed IRQ %d failed, using default\n",
-		hwif->name, hwif->irq);
 
-done:
 	blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
 			    THIS_MODULE, ata_probe, ata_lock, hwif);
 	return 1;
@@ -1161,13 +997,10 @@ static void hwif_register_devices(ide_hw
 	ide_drive_t *drive;
 	unsigned int i;
 
-	ide_port_for_each_dev(i, drive, hwif) {
+	ide_port_for_each_present_dev(i, drive, hwif) {
 		struct device *dev = &drive->gendev;
 		int ret;
 
-		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-			continue;
-
 		dev_set_name(dev, "%u.%u", hwif->index, i);
 		dev->parent = &hwif->gendev;
 		dev->bus = &ide_bus_type;
@@ -1192,6 +1025,8 @@ static void ide_port_init_devices(ide_hw
 
 		if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
 			drive->io_32bit = 1;
+		if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
+			drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
 		if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
 			drive->dev_flags |= IDE_DFLAG_UNMASK;
 		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
@@ -1213,10 +1048,6 @@ static void ide_init_port(ide_hwif_t *hw
 	if (d->init_iops)
 		d->init_iops(hwif);
 
-	if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
-	    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
-		hwif->irq = port ? 15 : 14;
-
 	/* ->host_flags may be set by ->init_iops (or even earlier...) */
 	hwif->host_flags |= d->host_flags;
 	hwif->pio_mask = d->pio_mask;
@@ -1225,7 +1056,7 @@ static void ide_init_port(ide_hwif_t *hw
 		hwif->tp_ops = d->tp_ops;
 
 	/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
-	if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
+	if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
 		hwif->port_ops = d->port_ops;
 
 	hwif->swdma_mask = d->swdma_mask;
@@ -1259,6 +1090,13 @@ static void ide_init_port(ide_hwif_t *hw
 
 	if (d->max_sectors)
 		hwif->rqsize = d->max_sectors;
+	else {
+		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
+			hwif->rqsize = 256;
+		else
+			hwif->rqsize = 65536;
+	}
 
 	/* call chipset specific routine for each enabled port */
 	if (d->init_hwif)
@@ -1317,6 +1155,12 @@ static void ide_init_port_data(ide_hwif_
 	hwif->name[2]	= 'e';
 	hwif->name[3]	= '0' + index;
 
+	spin_lock_init(&hwif->lock);
+
+	init_timer(&hwif->timer);
+	hwif->timer.function = &ide_timer_expiry;
+	hwif->timer.data = (unsigned long)hwif;
+
 	init_completion(&hwif->gendev_rel_comp);
 
 	hwif->tp_ops = &default_tp_ops;
@@ -1465,7 +1309,10 @@ struct ide_host *ide_host_alloc(const st
 
 	if (d) {
 		host->init_chipset = d->init_chipset;
+		host->get_lock     = d->get_lock;
+		host->release_lock = d->release_lock;
 		host->host_flags = d->host_flags;
+		host->irq_flags = d->irq_flags;
 	}
 
 	return host;
@@ -1511,20 +1358,15 @@ int ide_host_register(struct ide_host *h
 		ide_init_port_hw(hwif, hws[i]);
 		ide_port_apply_params(hwif);
 
-		if (d == NULL) {
-			mate = NULL;
-		} else {
-			if ((i & 1) && mate) {
-				hwif->mate = mate;
-				mate->mate = hwif;
-			}
-
-			mate = (i & 1) ? NULL : hwif;
-
-			ide_init_port(hwif, i & 1, d);
-			ide_port_cable_detect(hwif);
+		if ((i & 1) && mate) {
+			hwif->mate = mate;
+			mate->mate = hwif;
 		}
 
+		mate = (i & 1) ? NULL : hwif;
+
+		ide_init_port(hwif, i & 1, d);
+		ide_port_cable_detect(hwif);
 		ide_port_init_devices(hwif);
 	}
 
@@ -1535,8 +1377,8 @@ int ide_host_register(struct ide_host *h
 		if (ide_probe_port(hwif) == 0)
 			hwif->present = 1;
 
-		if (hwif->chipset != ide_4drives || !hwif->mate ||
-		    !hwif->mate->present) {
+		if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
+		    hwif->mate == NULL || hwif->mate->present == 0) {
 			if (ide_register_port(hwif)) {
 				ide_disable_port(hwif);
 				continue;
@@ -1567,7 +1409,7 @@ int ide_host_register(struct ide_host *h
 
 		j++;
 
-		ide_acpi_init(hwif);
+		ide_acpi_init_port(hwif);
 
 		if (hwif->present)
 			ide_acpi_port_init_devices(hwif);
@@ -1624,11 +1466,9 @@ static void __ide_port_unregister_device
 	ide_drive_t *drive;
 	int i;
 
-	ide_port_for_each_dev(i, drive, hwif) {
-		if (drive->dev_flags & IDE_DFLAG_PRESENT) {
-			device_unregister(&drive->gendev);
-			wait_for_completion(&drive->gendev_rel_comp);
-		}
+	ide_port_for_each_present_dev(i, drive, hwif) {
+		device_unregister(&drive->gendev);
+		wait_for_completion(&drive->gendev_rel_comp);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-proc.c linux-libre-2.6.30-gnu1/drivers/ide/ide-proc.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed)
 
 static int set_xfer_rate (ide_drive_t *drive, int arg)
 {
-	ide_task_t task;
+	struct ide_cmd cmd;
 	int err;
 
 	if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
 		return -EINVAL;
 
-	memset(&task, 0, sizeof(task));
-	task.tf.command = ATA_CMD_SET_FEATURES;
-	task.tf.feature = SETFEATURES_XFER;
-	task.tf.nsect   = (u8)arg;
-	task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
-			IDE_TFLAG_IN_NSECT;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.tf.command = ATA_CMD_SET_FEATURES;
+	cmd.tf.feature = SETFEATURES_XFER;
+	cmd.tf.nsect   = (u8)arg;
+	cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
+	cmd.valid.in.tf  = IDE_VALID_NSECT;
 
-	err = ide_no_data_taskfile(drive, &task);
+	err = ide_no_data_taskfile(drive, &cmd);
 
 	if (!err) {
 		ide_set_xfer_rate(drive, (u8) arg);
@@ -600,7 +600,7 @@ void ide_proc_port_register_devices(ide_
 	int i;
 
 	ide_port_for_each_dev(i, drive, hwif) {
-		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
+		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
 			continue;
 
 		drive->proc = proc_mkdir(drive->name, parent);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-tape.c linux-libre-2.6.30-gnu1/drivers/ide/ide-tape.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-tape.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-tape.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,11 +152,6 @@ struct idetape_bh {
 #define IDETAPE_LU_RETENSION_MASK	2
 #define IDETAPE_LU_EOT_MASK		4
 
-/* Error codes returned in rq->errors to the higher part of the driver. */
-#define IDETAPE_ERROR_GENERAL		101
-#define IDETAPE_ERROR_FILEMARK		102
-#define IDETAPE_ERROR_EOD		103
-
 /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
 #define IDETAPE_BLOCK_DESCRIPTOR	0
 #define IDETAPE_CAPABILITIES_PAGE	0x2a
@@ -171,14 +166,6 @@ typedef struct ide_tape_obj {
 	struct gendisk		*disk;
 	struct device		dev;
 
-	/*
-	 *	failed_pc points to the last failed packet command, or contains
-	 *	NULL if we do not need to retry any packet command. This is
-	 *	required since an additional packet command is needed before the
-	 *	retry, to get detailed information on what went wrong.
-	 */
-	/* Last failed packet command */
-	struct ide_atapi_pc *failed_pc;
 	/* used by REQ_IDETAPE_{READ,WRITE} requests */
 	struct ide_atapi_pc queued_pc;
 
@@ -245,9 +232,6 @@ typedef struct ide_tape_obj {
 	/* Wasted space in each stage */
 	int excess_bh_size;
 
-	/* protects the ide-tape queue */
-	spinlock_t lock;
-
 	/* Measures average tape speed */
 	unsigned long avg_time;
 	int avg_size;
@@ -313,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chr
 	return tape;
 }
 
-static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 				  unsigned int bcount)
 {
 	struct idetape_bh *bh = pc->bh;
 	int count;
 
 	while (bcount) {
-		if (bh == NULL) {
-			printk(KERN_ERR "ide-tape: bh == NULL in "
-				"idetape_input_buffers\n");
-			ide_pad_transfer(drive, 0, bcount);
-			return;
-		}
+		if (bh == NULL)
+			break;
 		count = min(
 			(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
 			bcount);
@@ -339,21 +319,21 @@ static void idetape_input_buffers(ide_dr
 				atomic_set(&bh->b_count, 0);
 		}
 	}
+
 	pc->bh = bh;
+
+	return bcount;
 }
 
-static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 				   unsigned int bcount)
 {
 	struct idetape_bh *bh = pc->bh;
 	int count;
 
 	while (bcount) {
-		if (bh == NULL) {
-			printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
-					__func__);
-			return;
-		}
+		if (bh == NULL)
+			break;
 		count = min((unsigned int)pc->b_count, (unsigned int)bcount);
 		drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
 		bcount -= count;
@@ -368,6 +348,8 @@ static void idetape_output_buffers(ide_d
 			}
 		}
 	}
+
+	return bcount;
 }
 
 static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -400,7 +382,7 @@ static void idetape_update_buffers(ide_d
 static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
 {
 	idetape_tape_t *tape = drive->driver_data;
-	struct ide_atapi_pc *pc = tape->failed_pc;
+	struct ide_atapi_pc *pc = drive->failed_pc;
 
 	tape->sense_key = sense[2] & 0xF;
 	tape->asc       = sense[12];
@@ -433,19 +415,19 @@ static void idetape_analyze_error(ide_dr
 		}
 	}
 	if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
-		pc->error = IDETAPE_ERROR_FILEMARK;
+		pc->error = IDE_DRV_ERROR_FILEMARK;
 		pc->flags |= PC_FLAG_ABORT;
 	}
 	if (pc->c[0] == WRITE_6) {
 		if ((sense[2] & 0x40) || (tape->sense_key == 0xd
 		     && tape->asc == 0x0 && tape->ascq == 0x2)) {
-			pc->error = IDETAPE_ERROR_EOD;
+			pc->error = IDE_DRV_ERROR_EOD;
 			pc->flags |= PC_FLAG_ABORT;
 		}
 	}
 	if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
 		if (tape->sense_key == 8) {
-			pc->error = IDETAPE_ERROR_EOD;
+			pc->error = IDE_DRV_ERROR_EOD;
 			pc->flags |= PC_FLAG_ABORT;
 		}
 		if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +459,23 @@ static void ide_tape_kfree_buffer(idetap
 	}
 }
 
-static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
-{
-	struct request *rq = drive->hwif->rq;
-	idetape_tape_t *tape = drive->driver_data;
-	unsigned long flags;
-	int error;
-
-	debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
-	switch (uptodate) {
-	case 0:	error = IDETAPE_ERROR_GENERAL; break;
-	case 1: error = 0; break;
-	default: error = uptodate;
-	}
-	rq->errors = error;
-	if (error)
-		tape->failed_pc = NULL;
-
-	if (!blk_special_request(rq)) {
-		ide_end_request(drive, uptodate, nr_sects);
-		return 0;
-	}
-
-	spin_lock_irqsave(&tape->lock, flags);
-
-	ide_end_drive_cmd(drive, 0, 0);
-
-	spin_unlock_irqrestore(&tape->lock, flags);
-	return 0;
-}
-
 static void ide_tape_handle_dsc(ide_drive_t *);
 
-static void ide_tape_callback(ide_drive_t *drive, int dsc)
+static int ide_tape_callback(ide_drive_t *drive, int dsc)
 {
 	idetape_tape_t *tape = drive->driver_data;
 	struct ide_atapi_pc *pc = drive->pc;
+	struct request *rq = drive->hwif->rq;
 	int uptodate = pc->error ? 0 : 1;
+	int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
 
 	debug_log(DBG_PROCS, "Enter %s\n", __func__);
 
 	if (dsc)
 		ide_tape_handle_dsc(drive);
 
-	if (tape->failed_pc == pc)
-		tape->failed_pc = NULL;
+	if (drive->failed_pc == pc)
+		drive->failed_pc = NULL;
 
 	if (pc->c[0] == REQUEST_SENSE) {
 		if (uptodate)
@@ -531,7 +484,6 @@ static void ide_tape_callback(ide_drive_
 			printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
 					"itself - Aborting request!\n");
 	} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
-		struct request *rq = drive->hwif->rq;
 		int blocks = pc->xferred / tape->blk_size;
 
 		tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +498,10 @@ static void ide_tape_callback(ide_drive_
 		tape->first_frame += blocks;
 		rq->current_nr_sectors -= blocks;
 
-		if (pc->error)
-			uptodate = pc->error;
+		if (pc->error) {
+			uptodate = 0;
+			err = pc->error;
+		}
 	} else if (pc->c[0] == READ_POSITION && uptodate) {
 		u8 *readpos = pc->buf;
 
@@ -561,6 +515,7 @@ static void ide_tape_callback(ide_drive_
 					 "to the tape\n");
 			clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
 			uptodate = 0;
+			err = IDE_DRV_ERROR_GENERAL;
 		} else {
 			debug_log(DBG_SENSE, "Block Location - %u\n",
 					be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +526,9 @@ static void ide_tape_callback(ide_drive_
 		}
 	}
 
-	idetape_end_request(drive, uptodate, 0);
+	rq->errors = err;
+
+	return uptodate;
 }
 
 /*
@@ -604,12 +561,14 @@ static void ide_tape_handle_dsc(ide_driv
 static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 				unsigned int bcount, int write)
 {
+	unsigned int bleft;
+
 	if (write)
-		idetape_output_buffers(drive, pc, bcount);
+		bleft = idetape_output_buffers(drive, pc, bcount);
 	else
-		idetape_input_buffers(drive, pc, bcount);
+		bleft = idetape_input_buffers(drive, pc, bcount);
 
-	return bcount;
+	return bcount - bleft;
 }
 
 /*
@@ -621,7 +580,7 @@ static int ide_tape_io_buffers(ide_drive
  *
  * The handling will be done in three stages:
  *
- * 1. idetape_issue_pc will send the packet command to the drive, and will set
+ * 1. ide_tape_issue_pc will send the packet command to the drive, and will set
  * the interrupt handler to ide_pc_intr.
  *
  * 2. On each interrupt, ide_pc_intr will be called. This step will be
@@ -649,19 +608,14 @@ static int ide_tape_io_buffers(ide_drive
  * request.
  */
 
-static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
-		struct ide_atapi_pc *pc)
+static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
+					 struct ide_cmd *cmd,
+					 struct ide_atapi_pc *pc)
 {
 	idetape_tape_t *tape = drive->driver_data;
 
-	if (drive->pc->c[0] == REQUEST_SENSE &&
-	    pc->c[0] == REQUEST_SENSE) {
-		printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
-			"Two request sense in serial were issued\n");
-	}
-
-	if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
-		tape->failed_pc = pc;
+	if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
+		drive->failed_pc = pc;
 
 	/* Set the current packet command */
 	drive->pc = pc;
@@ -685,9 +639,9 @@ static ide_startstop_t idetape_issue_pc(
 						tape->ascq);
 			}
 			/* Giving up */
-			pc->error = IDETAPE_ERROR_GENERAL;
+			pc->error = IDE_DRV_ERROR_GENERAL;
 		}
-		tape->failed_pc = NULL;
+		drive->failed_pc = NULL;
 		drive->pc_callback(drive, 0);
 		return ide_stopped;
 	}
@@ -695,7 +649,7 @@ static ide_startstop_t idetape_issue_pc(
 
 	pc->retries++;
 
-	return ide_issue_pc(drive);
+	return ide_issue_pc(drive, cmd);
 }
 
 /* A mode sense command is used to "sense" tape parameters. */
@@ -746,8 +700,8 @@ static ide_startstop_t idetape_media_acc
 		}
 		pc->error = 0;
 	} else {
-		pc->error = IDETAPE_ERROR_GENERAL;
-		tape->failed_pc = NULL;
+		pc->error = IDE_DRV_ERROR_GENERAL;
+		drive->failed_pc = NULL;
 	}
 	drive->pc_callback(drive, 0);
 	return ide_stopped;
@@ -790,6 +744,7 @@ static ide_startstop_t idetape_do_reques
 	idetape_tape_t *tape = drive->driver_data;
 	struct ide_atapi_pc *pc = NULL;
 	struct request *postponed_rq = tape->postponed_rq;
+	struct ide_cmd cmd;
 	u8 stat;
 
 	debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
@@ -801,13 +756,15 @@ static ide_startstop_t idetape_do_reques
 		/* We do not support buffer cache originated requests. */
 		printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
 			"request queue (%d)\n", drive->name, rq->cmd_type);
-		ide_end_request(drive, 0, 0);
+		if (blk_fs_request(rq) == 0 && rq->errors == 0)
+			rq->errors = -EIO;
+		ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
 		return ide_stopped;
 	}
 
 	/* Retry a failed packet command */
-	if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
-		pc = tape->failed_pc;
+	if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
+		pc = drive->failed_pc;
 		goto out;
 	}
 
@@ -815,7 +772,9 @@ static ide_startstop_t idetape_do_reques
 		if (rq != postponed_rq) {
 			printk(KERN_ERR "ide-tape: ide-tape.c bug - "
 					"Two DSC requests were queued\n");
-			idetape_end_request(drive, 0, 0);
+			drive->failed_pc = NULL;
+			rq->errors = 0;
+			ide_complete_rq(drive, 0, blk_rq_bytes(rq));
 			return ide_stopped;
 		}
 
@@ -881,7 +840,14 @@ static ide_startstop_t idetape_do_reques
 	BUG();
 
 out:
-	return idetape_issue_pc(drive, pc);
+	memset(&cmd, 0, sizeof(cmd));
+
+	if (rq_data_dir(rq))
+		cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+	cmd.rq = rq;
+
+	return ide_tape_issue_pc(drive, &cmd, pc);
 }
 
 /*
@@ -1226,7 +1192,7 @@ static int idetape_queue_rw_tail(ide_dri
 
 	if (tape->merge_bh)
 		idetape_init_merge_buffer(tape);
-	if (errors == IDETAPE_ERROR_GENERAL)
+	if (errors == IDE_DRV_ERROR_GENERAL)
 		return -EIO;
 	return ret;
 }
@@ -2042,9 +2008,13 @@ static void idetape_get_inquiry_results(
 {
 	idetape_tape_t *tape = drive->driver_data;
 	struct ide_atapi_pc pc;
+	u8 pc_buf[256];
 	char fw_rev[4], vendor_id[8], product_id[16];
 
 	idetape_create_inquiry_cmd(&pc);
+	pc.buf = &pc_buf[0];
+	pc.buf_size = sizeof(pc_buf);
+
 	if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
 		printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
 				tape->name);
@@ -2192,8 +2162,6 @@ static void idetape_setup(ide_drive_t *d
 	drive->pc_update_buffers = idetape_update_buffers;
 	drive->pc_io_buffers	 = ide_tape_io_buffers;
 
-	spin_lock_init(&tape->lock);
-
 	drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
 
 	if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2325,7 +2293,6 @@ static struct ide_driver idetape_driver
 	.remove			= ide_tape_remove,
 	.version		= IDETAPE_VERSION,
 	.do_request		= idetape_do_request,
-	.end_request		= idetape_end_request,
 #ifdef CONFIG_IDE_PROC_FS
 	.proc_entries		= ide_tape_proc_entries,
 	.proc_devsets		= ide_tape_proc_devsets,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-taskfile.c linux-libre-2.6.30-gnu1/drivers/ide/ide-taskfile.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-taskfile.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-taskfile.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,104 +23,134 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-void ide_tf_dump(const char *s, struct ide_taskfile *tf)
+void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+
+	/* Be sure we're looking at the low order bytes */
+	tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+
+	tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf);
+
+	if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+		tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS);
+
+		tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob);
+	}
+}
+
+void ide_tf_dump(const char *s, struct ide_cmd *cmd)
 {
 #ifdef DEBUG
 	printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
 		"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
-		s, tf->feature, tf->nsect, tf->lbal,
-		tf->lbam, tf->lbah, tf->device, tf->command);
-	printk("%s: hob: nsect 0x%02x lbal 0x%02x "
-		"lbam 0x%02x lbah 0x%02x\n",
-		s, tf->hob_nsect, tf->hob_lbal,
-		tf->hob_lbam, tf->hob_lbah);
+	       s, cmd->tf.feature, cmd->tf.nsect,
+	       cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah,
+	       cmd->tf.device, cmd->tf.command);
+	printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n",
+	       s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah);
 #endif
 }
 
 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
 {
-	ide_task_t args;
+	struct ide_cmd cmd;
 
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tf.nsect = 0x01;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.tf.nsect = 0x01;
 	if (drive->media == ide_disk)
-		args.tf.command = ATA_CMD_ID_ATA;
+		cmd.tf.command = ATA_CMD_ID_ATA;
 	else
-		args.tf.command = ATA_CMD_ID_ATAPI;
-	args.tf_flags	= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-	args.data_phase	= TASKFILE_IN;
-	return ide_raw_taskfile(drive, &args, buf, 1);
+		cmd.tf.command = ATA_CMD_ID_ATAPI;
+	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
+	cmd.protocol = ATA_PROT_PIO;
+
+	return ide_raw_taskfile(drive, &cmd, buf, 1);
 }
 
 static ide_startstop_t task_no_data_intr(ide_drive_t *);
-static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
-static ide_startstop_t task_in_intr(ide_drive_t *);
+static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
+static ide_startstop_t task_pio_intr(ide_drive_t *);
 
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	struct ide_taskfile *tf = &task->tf;
+	struct ide_cmd *cmd = &hwif->cmd;
+	struct ide_taskfile *tf = &cmd->tf;
 	ide_handler_t *handler = NULL;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
 	const struct ide_dma_ops *dma_ops = hwif->dma_ops;
 
-	if (task->data_phase == TASKFILE_MULTI_IN ||
-	    task->data_phase == TASKFILE_MULTI_OUT) {
-		if (!drive->mult_count) {
-			printk(KERN_ERR "%s: multimode not set!\n",
-					drive->name);
-			return ide_stopped;
-		}
+	if (orig_cmd->protocol == ATA_PROT_PIO &&
+	    (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
+	    drive->mult_count == 0) {
+		printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+		return ide_stopped;
 	}
 
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
+	if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+		orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
 
-	memcpy(&hwif->task, task, sizeof(*task));
+	memcpy(cmd, orig_cmd, sizeof(*cmd));
 
-	if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
-		ide_tf_dump(drive->name, tf);
-		tp_ops->set_irq(hwif, 1);
+	if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
+		ide_tf_dump(drive->name, cmd);
+		tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
 		SELECT_MASK(drive, 0);
-		tp_ops->tf_load(drive, task);
+
+		if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
+			u8 data[2] = { cmd->tf.data, cmd->hob.data };
+
+			tp_ops->output_data(drive, cmd, data, 2);
+		}
+
+		if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
+			u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
+				  0xE0 : 0xEF;
+
+			if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
+				cmd->tf.device &= HIHI;
+			cmd->tf.device |= drive->select;
+		}
+
+		tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
+		tp_ops->tf_load(drive, &cmd->tf,  cmd->valid.out.tf);
 	}
 
-	switch (task->data_phase) {
-	case TASKFILE_MULTI_OUT:
-	case TASKFILE_OUT:
-		tp_ops->exec_command(hwif, tf->command);
-		ndelay(400);	/* FIXME */
-		return pre_task_out_intr(drive, task->rq);
-	case TASKFILE_MULTI_IN:
-	case TASKFILE_IN:
-		handler = task_in_intr;
+	switch (cmd->protocol) {
+	case ATA_PROT_PIO:
+		if (cmd->tf_flags & IDE_TFLAG_WRITE) {
+			tp_ops->exec_command(hwif, tf->command);
+			ndelay(400);	/* FIXME */
+			return pre_task_out_intr(drive, cmd);
+		}
+		handler = task_pio_intr;
 		/* fall-through */
-	case TASKFILE_NO_DATA:
+	case ATA_PROT_NODATA:
 		if (handler == NULL)
 			handler = task_no_data_intr;
-		ide_execute_command(drive, tf->command, handler,
-				    WAIT_WORSTCASE, NULL);
+		ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
 		return ide_started;
-	default:
-		if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
-		    dma_ops->dma_setup(drive))
+	case ATA_PROT_DMA:
+		if (ide_dma_prepare(drive, cmd))
 			return ide_stopped;
-		dma_ops->dma_exec_cmd(drive, tf->command);
+		hwif->expiry = dma_ops->dma_timer_expiry;
+		ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
 		dma_ops->dma_start(drive);
+	default:
 		return ide_started;
 	}
 }
 EXPORT_SYMBOL_GPL(do_rw_taskfile);
 
-/*
- * Handler for commands without a data phase
- */
 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	ide_task_t *task = &hwif->task;
-	struct ide_taskfile *tf = &task->tf;
-	int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
+	struct ide_cmd *cmd = &hwif->cmd;
+	struct ide_taskfile *tf = &cmd->tf;
+	int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
 	int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
 	u8 stat;
 
@@ -142,28 +172,26 @@ static ide_startstop_t task_no_data_intr
 		} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
 			if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
 				ide_set_handler(drive, &task_no_data_intr,
-						WAIT_WORSTCASE, NULL);
+						WAIT_WORSTCASE);
 				return ide_started;
 			}
 		}
 		return ide_error(drive, "task_no_data_intr", stat);
-		/* calls ide_end_drive_cmd */
 	}
 
-	if (!custom)
-		ide_end_drive_cmd(drive, stat, ide_read_error(drive));
-	else if (tf->command == ATA_CMD_IDLEIMMEDIATE) {
-		hwif->tp_ops->tf_read(drive, task);
-		if (tf->lbal != 0xc4) {
-			printk(KERN_ERR "%s: head unload failed!\n",
-			       drive->name);
-			ide_tf_dump(drive->name, tf);
-		} else
-			drive->dev_flags |= IDE_DFLAG_PARKED;
-		ide_end_drive_cmd(drive, stat, ide_read_error(drive));
-	} else if (tf->command == ATA_CMD_SET_MULTI)
+	if (custom && tf->command == ATA_CMD_SET_MULTI)
 		drive->mult_count = drive->mult_req;
 
+	if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
+	    tf->command == ATA_CMD_CHK_POWER) {
+		struct request *rq = hwif->rq;
+
+		if (blk_pm_request(rq))
+			ide_complete_pm_rq(drive, rq);
+		else
+			ide_finish_cmd(drive, cmd, stat);
+	}
+
 	return ide_stopped;
 }
 
@@ -192,239 +220,188 @@ static u8 wait_drive_not_busy(ide_drive_
 	return stat;
 }
 
-static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
-			   unsigned int write)
+void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
+		   unsigned int write, unsigned int len)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
-	struct scatterlist *cursg = hwif->cursg;
+	struct scatterlist *cursg = cmd->cursg;
 	struct page *page;
-#ifdef CONFIG_HIGHMEM
 	unsigned long flags;
-#endif
 	unsigned int offset;
 	u8 *buf;
 
-	cursg = hwif->cursg;
-	if (!cursg) {
-		cursg = sg;
-		hwif->cursg = sg;
-	}
+	cursg = cmd->cursg;
+	if (cursg == NULL)
+		cursg = cmd->cursg = sg;
 
-	page = sg_page(cursg);
-	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
+	while (len) {
+		unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
 
-	/* get the current page and offset */
-	page = nth_page(page, (offset >> PAGE_SHIFT));
-	offset %= PAGE_SIZE;
+		if (nr_bytes > PAGE_SIZE)
+			nr_bytes = PAGE_SIZE;
 
-#ifdef CONFIG_HIGHMEM
-	local_irq_save(flags);
-#endif
-	buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+		page = sg_page(cursg);
+		offset = cursg->offset + cmd->cursg_ofs;
 
-	hwif->nleft--;
-	hwif->cursg_ofs++;
+		/* get the current page and offset */
+		page = nth_page(page, (offset >> PAGE_SHIFT));
+		offset %= PAGE_SIZE;
 
-	if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
-		hwif->cursg = sg_next(hwif->cursg);
-		hwif->cursg_ofs = 0;
-	}
+		if (PageHighMem(page))
+			local_irq_save(flags);
 
-	/* do the actual data transfer */
-	if (write)
-		hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
-	else
-		hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
+		buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
 
-	kunmap_atomic(buf, KM_BIO_SRC_IRQ);
-#ifdef CONFIG_HIGHMEM
-	local_irq_restore(flags);
-#endif
-}
+		cmd->nleft -= nr_bytes;
+		cmd->cursg_ofs += nr_bytes;
 
-static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
-			  unsigned int write)
-{
-	unsigned int nsect;
+		if (cmd->cursg_ofs == cursg->length) {
+			cursg = cmd->cursg = sg_next(cmd->cursg);
+			cmd->cursg_ofs = 0;
+		}
 
-	nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
-	while (nsect--)
-		ide_pio_sector(drive, rq, write);
+		/* do the actual data transfer */
+		if (write)
+			hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
+		else
+			hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+
+		kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+
+		if (PageHighMem(page))
+			local_irq_restore(flags);
+
+		len -= nr_bytes;
+	}
 }
+EXPORT_SYMBOL_GPL(ide_pio_bytes);
 
-static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
-				     unsigned int write)
+static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
+			      unsigned int write)
 {
-	u8 saved_io_32bit = drive->io_32bit;
+	unsigned int nr_bytes;
 
-	if (rq->bio)	/* fs request */
-		rq->errors = 0;
+	u8 saved_io_32bit = drive->io_32bit;
 
-	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		ide_task_t *task = rq->special;
+	if (cmd->tf_flags & IDE_TFLAG_FS)
+		cmd->rq->errors = 0;
 
-		if (task->tf_flags & IDE_TFLAG_IO_16BIT)
-			drive->io_32bit = 0;
-	}
+	if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
+		drive->io_32bit = 0;
 
 	touch_softlockup_watchdog();
 
-	switch (drive->hwif->data_phase) {
-	case TASKFILE_MULTI_IN:
-	case TASKFILE_MULTI_OUT:
-		ide_pio_multi(drive, rq, write);
-		break;
-	default:
-		ide_pio_sector(drive, rq, write);
-		break;
-	}
+	if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+		nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
+	else
+		nr_bytes = SECTOR_SIZE;
+
+	ide_pio_bytes(drive, cmd, write, nr_bytes);
 
 	drive->io_32bit = saved_io_32bit;
 }
 
-static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
-				  const char *s, u8 stat)
+static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	if (rq->bio) {
-		ide_hwif_t *hwif = drive->hwif;
-		int sectors = hwif->nsect - hwif->nleft;
-
-		switch (hwif->data_phase) {
-		case TASKFILE_IN:
-			if (hwif->nleft)
-				break;
-			/* fall through */
-		case TASKFILE_OUT:
-			sectors--;
-			break;
-		case TASKFILE_MULTI_IN:
-			if (hwif->nleft)
-				break;
-			/* fall through */
-		case TASKFILE_MULTI_OUT:
-			sectors -= drive->mult_count;
-		default:
-			break;
-		}
-
-		if (sectors > 0) {
-			struct ide_driver *drv;
+	if (cmd->tf_flags & IDE_TFLAG_FS) {
+		int nr_bytes = cmd->nbytes - cmd->nleft;
 
-			drv = *(struct ide_driver **)rq->rq_disk->private_data;
-			drv->end_request(drive, 1, sectors);
+		if (cmd->protocol == ATA_PROT_PIO &&
+		    ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
+			if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+				nr_bytes -= drive->mult_count << 9;
+			else
+				nr_bytes -= SECTOR_SIZE;
 		}
-	}
-	return ide_error(drive, s, stat);
-}
 
-void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
-{
-	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		u8 err = ide_read_error(drive);
-
-		ide_end_drive_cmd(drive, stat, err);
-		return;
+		if (nr_bytes > 0)
+			ide_complete_rq(drive, 0, nr_bytes);
 	}
-
-	if (rq->rq_disk) {
-		struct ide_driver *drv;
-
-		drv = *(struct ide_driver **)rq->rq_disk->private_data;;
-		drv->end_request(drive, 1, rq->nr_sectors);
-	} else
-		ide_end_request(drive, 1, rq->nr_sectors);
 }
 
-/*
- * We got an interrupt on a task_in case, but no errors and no DRQ.
- *
- * It might be a spurious irq (shared irq), but it might be a
- * command that had no output.
- */
-static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
+void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
 {
-	/* Command all done? */
-	if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
-		task_end_request(drive, rq, stat);
-		return ide_stopped;
-	}
+	struct request *rq = drive->hwif->rq;
+	u8 err = ide_read_error(drive);
 
-	/* Assume it was a spurious irq */
-	ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-	return ide_started;
+	ide_complete_cmd(drive, cmd, stat, err);
+	rq->errors = err;
+	ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
 }
 
 /*
- * Handler for command with PIO data-in phase (Read/Read Multiple).
+ * Handler for command with PIO data phase.
  */
-static ide_startstop_t task_in_intr(ide_drive_t *drive)
+static ide_startstop_t task_pio_intr(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
+	struct ide_cmd *cmd = &drive->hwif->cmd;
 	u8 stat = hwif->tp_ops->read_status(hwif);
+	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
 
-	/* Error? */
-	if (stat & ATA_ERR)
-		return task_error(drive, rq, __func__, stat);
+	if (write == 0) {
+		/* Error? */
+		if (stat & ATA_ERR)
+			goto out_err;
 
-	/* Didn't want any data? Odd. */
-	if ((stat & ATA_DRQ) == 0)
-		return task_in_unexpected(drive, rq, stat);
+		/* Didn't want any data? Odd. */
+		if ((stat & ATA_DRQ) == 0) {
+			/* Command all done? */
+			if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
+				goto out_end;
 
-	ide_pio_datablock(drive, rq, 0);
+			/* Assume it was a spurious irq */
+			goto out_wait;
+		}
+	} else {
+		if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
+			goto out_err;
 
-	/* Are we done? Check status and finish transfer. */
-	if (!hwif->nleft) {
-		stat = wait_drive_not_busy(drive);
-		if (!OK_STAT(stat, 0, BAD_STAT))
-			return task_error(drive, rq, __func__, stat);
-		task_end_request(drive, rq, stat);
-		return ide_stopped;
+		/* Deal with unexpected ATA data phase. */
+		if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
+			goto out_err;
 	}
 
-	/* Still data left to transfer. */
-	ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-
-	return ide_started;
-}
-
-/*
- * Handler for command with PIO data-out phase (Write/Write Multiple).
- */
-static ide_startstop_t task_out_intr (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
-	u8 stat = hwif->tp_ops->read_status(hwif);
+	if (write && cmd->nleft == 0)
+		goto out_end;
 
-	if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
-		return task_error(drive, rq, __func__, stat);
+	/* Still data left to transfer. */
+	ide_pio_datablock(drive, cmd, write);
 
-	/* Deal with unexpected ATA data phase. */
-	if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
-		return task_error(drive, rq, __func__, stat);
+	/* Are we done? Check status and finish transfer. */
+	if (write == 0 && cmd->nleft == 0) {
+		stat = wait_drive_not_busy(drive);
+		if (!OK_STAT(stat, 0, BAD_STAT))
+			goto out_err;
 
-	if (!hwif->nleft) {
-		task_end_request(drive, rq, stat);
-		return ide_stopped;
+		goto out_end;
 	}
-
+out_wait:
 	/* Still data left to transfer. */
-	ide_pio_datablock(drive, rq, 1);
-	ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-
+	ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
 	return ide_started;
+out_end:
+	if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+		ide_finish_cmd(drive, cmd, stat);
+	else
+		ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+	return ide_stopped;
+out_err:
+	ide_error_cmd(drive, cmd);
+	return ide_error(drive, __func__, stat);
 }
 
-static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
+					 struct ide_cmd *cmd)
 {
 	ide_startstop_t startstop;
 
 	if (ide_wait_stat(&startstop, drive, ATA_DRQ,
 			  drive->bad_wstat, WAIT_DRQ)) {
 		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
-			drive->name, drive->hwif->data_phase ? "MULT" : "",
+			drive->name,
+			(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
 			(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
 		return startstop;
 	}
@@ -432,13 +409,15 @@ static ide_startstop_t pre_task_out_intr
 	if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
 		local_irq_disable();
 
-	ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-	ide_pio_datablock(drive, rq, 1);
+	ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
+
+	ide_pio_datablock(drive, cmd, 1);
 
 	return ide_started;
 }
 
-int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
+int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
+		     u16 nsect)
 {
 	struct request *rq;
 	int error;
@@ -456,11 +435,11 @@ int ide_raw_taskfile(ide_drive_t *drive,
 	rq->hard_nr_sectors = rq->nr_sectors = nsect;
 	rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
 
-	if (task->tf_flags & IDE_TFLAG_WRITE)
+	if (cmd->tf_flags & IDE_TFLAG_WRITE)
 		rq->cmd_flags |= REQ_RW;
 
-	rq->special = task;
-	task->rq = rq;
+	rq->special = cmd;
+	cmd->rq = rq;
 
 	error = blk_execute_rq(drive->queue, NULL, rq, 0);
 	blk_put_request(rq);
@@ -470,19 +449,19 @@ int ide_raw_taskfile(ide_drive_t *drive,
 
 EXPORT_SYMBOL(ide_raw_taskfile);
 
-int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
+int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	task->data_phase = TASKFILE_NO_DATA;
+	cmd->protocol = ATA_PROT_NODATA;
 
-	return ide_raw_taskfile(drive, task, NULL, 0);
+	return ide_raw_taskfile(drive, cmd, NULL, 0);
 }
 EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
 
 #ifdef CONFIG_IDE_TASK_IOCTL
-int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 {
 	ide_task_request_t	*req_task;
-	ide_task_t		args;
+	struct ide_cmd		cmd;
 	u8 *outbuf		= NULL;
 	u8 *inbuf		= NULL;
 	u8 *data_buf		= NULL;
@@ -536,53 +515,64 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 		}
 	}
 
-	memset(&args, 0, sizeof(ide_task_t));
+	memset(&cmd, 0, sizeof(cmd));
 
-	memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
-	memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+	memcpy(&cmd.tf,  req_task->io_ports,  HDIO_DRIVE_TASK_HDR_SIZE);
 
-	args.data_phase = req_task->data_phase;
+	cmd.valid.out.tf = IDE_VALID_DEVICE;
+	cmd.valid.in.tf  = IDE_VALID_DEVICE | IDE_VALID_IN_TF;
+	cmd.tf_flags = IDE_TFLAG_IO_16BIT;
 
-	args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
-			IDE_TFLAG_IN_TF;
-	if (drive->dev_flags & IDE_DFLAG_LBA48)
-		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+	if (drive->dev_flags & IDE_DFLAG_LBA48) {
+		cmd.tf_flags |= IDE_TFLAG_LBA48;
+		cmd.valid.in.hob = IDE_VALID_IN_HOB;
+	}
 
 	if (req_task->out_flags.all) {
-		args.tf_flags |= IDE_TFLAG_FLAGGED;
+		cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
 
 		if (req_task->out_flags.b.data)
-			args.tf_flags |= IDE_TFLAG_OUT_DATA;
+			cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
 
 		if (req_task->out_flags.b.nsector_hob)
-			args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+			cmd.valid.out.hob |= IDE_VALID_NSECT;
 		if (req_task->out_flags.b.sector_hob)
-			args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+			cmd.valid.out.hob |= IDE_VALID_LBAL;
 		if (req_task->out_flags.b.lcyl_hob)
-			args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+			cmd.valid.out.hob |= IDE_VALID_LBAM;
 		if (req_task->out_flags.b.hcyl_hob)
-			args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+			cmd.valid.out.hob |= IDE_VALID_LBAH;
 
 		if (req_task->out_flags.b.error_feature)
-			args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+			cmd.valid.out.tf  |= IDE_VALID_FEATURE;
 		if (req_task->out_flags.b.nsector)
-			args.tf_flags |= IDE_TFLAG_OUT_NSECT;
+			cmd.valid.out.tf  |= IDE_VALID_NSECT;
 		if (req_task->out_flags.b.sector)
-			args.tf_flags |= IDE_TFLAG_OUT_LBAL;
+			cmd.valid.out.tf  |= IDE_VALID_LBAL;
 		if (req_task->out_flags.b.lcyl)
-			args.tf_flags |= IDE_TFLAG_OUT_LBAM;
+			cmd.valid.out.tf  |= IDE_VALID_LBAM;
 		if (req_task->out_flags.b.hcyl)
-			args.tf_flags |= IDE_TFLAG_OUT_LBAH;
+			cmd.valid.out.tf  |= IDE_VALID_LBAH;
 	} else {
-		args.tf_flags |= IDE_TFLAG_OUT_TF;
-		if (args.tf_flags & IDE_TFLAG_LBA48)
-			args.tf_flags |= IDE_TFLAG_OUT_HOB;
+		cmd.valid.out.tf |= IDE_VALID_OUT_TF;
+		if (cmd.tf_flags & IDE_TFLAG_LBA48)
+			cmd.valid.out.hob |= IDE_VALID_OUT_HOB;
 	}
 
 	if (req_task->in_flags.b.data)
-		args.tf_flags |= IDE_TFLAG_IN_DATA;
+		cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
 
-	switch(req_task->data_phase) {
+	if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
+		/* fixup data phase if needed */
+		if (req_task->data_phase == TASKFILE_IN_DMAQ ||
+		    req_task->data_phase == TASKFILE_IN_DMA)
+			cmd.tf_flags |= IDE_TFLAG_WRITE;
+	}
+
+	cmd.protocol = ATA_PROT_DMA;
+
+	switch (req_task->data_phase) {
 		case TASKFILE_MULTI_OUT:
 			if (!drive->mult_count) {
 				/* (hs): give up if multcount is not set */
@@ -592,11 +582,14 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 				err = -EPERM;
 				goto abort;
 			}
+			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 			/* fall through */
 		case TASKFILE_OUT:
+			cmd.protocol = ATA_PROT_PIO;
 			/* fall through */
 		case TASKFILE_OUT_DMAQ:
 		case TASKFILE_OUT_DMA:
+			cmd.tf_flags |= IDE_TFLAG_WRITE;
 			nsect = taskout / SECTOR_SIZE;
 			data_buf = outbuf;
 			break;
@@ -609,8 +602,10 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 				err = -EPERM;
 				goto abort;
 			}
+			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 			/* fall through */
 		case TASKFILE_IN:
+			cmd.protocol = ATA_PROT_PIO;
 			/* fall through */
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMA:
@@ -618,6 +613,7 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 			data_buf = inbuf;
 			break;
 		case TASKFILE_NO_DATA:
+			cmd.protocol = ATA_PROT_NODATA;
 			break;
 		default:
 			err = -EFAULT;
@@ -627,7 +623,7 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
 		nsect = 0;
 	else if (!nsect) {
-		nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
+		nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
 
 		if (!nsect) {
 			printk(KERN_ERR "%s: in/out command without data\n",
@@ -637,15 +633,12 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 		}
 	}
 
-	if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
-		args.tf_flags |= IDE_TFLAG_WRITE;
-
-	err = ide_raw_taskfile(drive, &args, data_buf, nsect);
+	err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
 
-	memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
-	memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
+	memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2);
+	memcpy(req_task->io_ports,  &cmd.tf,  HDIO_DRIVE_TASK_HDR_SIZE);
 
-	if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
+	if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
 	    req_task->in_flags.all == 0) {
 		req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
 		if (drive->dev_flags & IDE_DFLAG_LBA48)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-timings.c linux-libre-2.6.30-gnu1/drivers/ide/ide-timings.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-timings.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-timings.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] =
 	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
 	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
 
+	{ XFER_MW_DMA_4,  25,   0,   0,   0,  55,  20,  80,   0 },
+	{ XFER_MW_DMA_3,  25,   0,   0,   0,  65,  25, 100,   0 },
 	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
 	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
 	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] =
 	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
 	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
 
-	{ XFER_PIO_5,     20,  50,  30, 100,  50,  30, 100,   0 },
+	{ XFER_PIO_6,     10,  55,  20,  80,  55,  20,  80,   0 },
+	{ XFER_PIO_5,     15,  65,  25, 100,  65,  25, 100,   0 },
 	{ XFER_PIO_4,     25,  70,  25, 120,  70,  25, 120,   0 },
 	{ XFER_PIO_3,     30,  80,  70, 180,  80,  70, 180,   0 },
 
@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *driv
 		/* conservative "downgrade" for all pre-ATA2 drives */
 		if (pio < 3 && cycle < t->cycle)
 			cycle = 0; /* use standard timing */
+
+		/* Use the standard timing for the CF specific modes too */
+		if (pio > 4 && ata_id_is_cfa(id))
+			cycle = 0;
 	}
 
 	return cycle ? cycle : t->cycle;
@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *driv
 
 		if (speed <= XFER_PIO_2)
 			p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
-		else if (speed <= XFER_PIO_5)
+		else if ((speed <= XFER_PIO_4) ||
+			 (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
 			p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
 		else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
 			p.cycle = id[ATA_ID_EIDE_DMA_MIN];
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ide-xfer-mode.c linux-libre-2.6.30-gnu1/drivers/ide/ide-xfer-mode.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ide-xfer-mode.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/ide/ide-xfer-mode.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,249 @@
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+static const char *udma_str[] =
+	 { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
+	   "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
+static const char *mwdma_str[] =
+	{ "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
+static const char *swdma_str[] =
+	{ "SWDMA0", "SWDMA1", "SWDMA2" };
+static const char *pio_str[] =
+	{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
+
+/**
+ *	ide_xfer_verbose	-	return IDE mode names
+ *	@mode: transfer mode
+ *
+ *	Returns a constant string giving the name of the mode
+ *	requested.
+ */
+
+const char *ide_xfer_verbose(u8 mode)
+{
+	const char *s;
+	u8 i = mode & 0xf;
+
+	if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
+		s = udma_str[i];
+	else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
+		s = mwdma_str[i];
+	else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
+		s = swdma_str[i];
+	else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
+		s = pio_str[i & 0x7];
+	else if (mode == XFER_PIO_SLOW)
+		s = "PIO SLOW";
+	else
+		s = "XFER ERROR";
+
+	return s;
+}
+EXPORT_SYMBOL(ide_xfer_verbose);
+
+/**
+ *	ide_get_best_pio_mode	-	get PIO mode from drive
+ *	@drive: drive to consider
+ *	@mode_wanted: preferred mode
+ *	@max_mode: highest allowed mode
+ *
+ *	This routine returns the recommended PIO settings for a given drive,
+ *	based on the drive->id information and the ide_pio_blacklist[].
+ *
+ *	Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
+ *	This is used by most chipset support modules when "auto-tuning".
+ */
+
+u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
+{
+	u16 *id = drive->id;
+	int pio_mode = -1, overridden = 0;
+
+	if (mode_wanted != 255)
+		return min_t(u8, mode_wanted, max_mode);
+
+	if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
+		pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
+
+	if (pio_mode != -1) {
+		printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
+	} else {
+		pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
+		if (pio_mode > 2) {	/* 2 is maximum allowed tPIO value */
+			pio_mode = 2;
+			overridden = 1;
+		}
+
+		if (id[ATA_ID_FIELD_VALID] & 2) {	      /* ATA2? */
+			if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
+				pio_mode = 4 + min_t(int, 2,
+						     id[ATA_ID_CFA_MODES] & 7);
+			else if (ata_id_has_iordy(id)) {
+				if (id[ATA_ID_PIO_MODES] & 7) {
+					overridden = 0;
+					if (id[ATA_ID_PIO_MODES] & 4)
+						pio_mode = 5;
+					else if (id[ATA_ID_PIO_MODES] & 2)
+						pio_mode = 4;
+					else
+						pio_mode = 3;
+				}
+			}
+		}
+
+		if (overridden)
+			printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
+					 drive->name);
+	}
+
+	if (pio_mode > max_mode)
+		pio_mode = max_mode;
+
+	return pio_mode;
+}
+EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+
+	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+		return 0;
+
+	if (port_ops == NULL || port_ops->set_pio_mode == NULL)
+		return -1;
+
+	/*
+	 * TODO: temporary hack for some legacy host drivers that didn't
+	 * set transfer mode on the device in ->set_pio_mode method...
+	 */
+	if (port_ops->set_dma_mode == NULL) {
+		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+		return 0;
+	}
+
+	if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+		if (ide_config_drive_speed(drive, mode))
+			return -1;
+		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+		return 0;
+	} else {
+		port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+		return ide_config_drive_speed(drive, mode);
+	}
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+
+	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+		return 0;
+
+	if (port_ops == NULL || port_ops->set_dma_mode == NULL)
+		return -1;
+
+	if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+		if (ide_config_drive_speed(drive, mode))
+			return -1;
+		port_ops->set_dma_mode(drive, mode);
+		return 0;
+	} else {
+		port_ops->set_dma_mode(drive, mode);
+		return ide_config_drive_speed(drive, mode);
+	}
+}
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
+/* req_pio == "255" for auto-tune */
+void ide_set_pio(ide_drive_t *drive, u8 req_pio)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+	u8 host_pio, pio;
+
+	if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+		return;
+
+	BUG_ON(hwif->pio_mask == 0x00);
+
+	host_pio = fls(hwif->pio_mask) - 1;
+
+	pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
+
+	/*
+	 * TODO:
+	 * - report device max PIO mode
+	 * - check req_pio != 255 against device max PIO mode
+	 */
+	printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
+			  drive->name, host_pio, req_pio,
+			  req_pio == 255 ? "(auto-tune)" : "", pio);
+
+	(void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
+}
+EXPORT_SYMBOL_GPL(ide_set_pio);
+
+/**
+ *	ide_rate_filter		-	filter transfer mode
+ *	@drive: IDE device
+ *	@speed: desired speed
+ *
+ *	Given the available transfer modes this function returns
+ *	the best available speed at or below the speed requested.
+ *
+ *	TODO: check device PIO capabilities
+ */
+
+static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 mode = ide_find_dma_mode(drive, speed);
+
+	if (mode == 0) {
+		if (hwif->pio_mask)
+			mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
+		else
+			mode = XFER_PIO_4;
+	}
+
+/*	printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
+
+	return min(speed, mode);
+}
+
+/**
+ *	ide_set_xfer_rate	-	set transfer rate
+ *	@drive: drive to set
+ *	@rate: speed to attempt to set
+ *
+ *	General helper for setting the speed of an IDE device. This
+ *	function knows about user enforced limits from the configuration
+ *	which ->set_pio_mode/->set_dma_mode does not.
+ */
+
+int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	const struct ide_port_ops *port_ops = hwif->port_ops;
+
+	if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+		return -1;
+
+	rate = ide_rate_filter(drive, rate);
+
+	BUG_ON(rate < XFER_PIO_0);
+
+	if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
+		return ide_set_pio_mode(drive, rate);
+
+	return ide_set_dma_mode(drive, rate);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/it821x.c linux-libre-2.6.30-gnu1/drivers/ide/it821x.c
--- linux-libre-2.6.29-gnu1/drivers/ide/it821x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/it821x.c	2009-06-09 23:05:27.000000000 -0400
@@ -508,12 +508,11 @@ static void it821x_quirkproc(ide_drive_t
 static struct ide_dma_ops it821x_pass_through_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= it821x_dma_start,
 	.dma_end		= it821x_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
@@ -603,7 +602,7 @@ static void it8212_disable_raid(struct p
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
 }
 
-static unsigned int init_chipset_it821x(struct pci_dev *dev)
+static int init_chipset_it821x(struct pci_dev *dev)
 {
 	u8 conf;
 	static char *mode[2] = { "pass through", "smart" };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/Kconfig linux-libre-2.6.30-gnu1/drivers/ide/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/ide/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -56,8 +56,12 @@ if IDE
 
 comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
 
+config IDE_XFER_MODE
+	bool
+
 config IDE_TIMINGS
 	bool
+	select IDE_XFER_MODE
 
 config IDE_ATAPI
 	bool
@@ -218,7 +222,8 @@ comment "IDE chipset support/bugfixes"
 
 config IDE_GENERIC
 	tristate "generic/default IDE chipset support"
-	depends on ALPHA || X86 || IA64 || M32R || MIPS
+	depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
+	default ARM && (ARCH_RPC || ARCH_SHARK)
 	help
 	  This is the generic IDE driver.  This driver attaches to the
 	  fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -676,7 +681,7 @@ endif
 # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
 config BLK_DEV_IDE_PMAC
 	tristate "PowerMac on-board IDE support"
-	depends on PPC_PMAC && IDE=y
+	depends on PPC_PMAC
 	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	help
@@ -698,6 +703,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
 config BLK_DEV_IDE_AU1XXX
        bool "IDE for AMD Alchemy Au1200"
        depends on SOC_AU1200
+       select IDE_XFER_MODE
 choice
        prompt "IDE Mode for AMD Alchemy Au1200"
        default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
@@ -726,11 +732,6 @@ config BLK_DEV_IDE_AT91
 	depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
 	select IDE_TIMINGS
 
-config IDE_ARM
-	tristate "ARM IDE support"
-	depends on ARM && (ARCH_RPC || ARCH_SHARK)
-	default y
-
 config BLK_DEV_IDE_ICSIDE
 	tristate "ICS IDE interface support"
 	depends on ARM && ARCH_ACORN
@@ -769,27 +770,20 @@ config BLK_DEV_GAYLE
 	  This includes on-board IDE interfaces on some Amiga models (A600,
 	  A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
 	  bus (M-Tech E-Matrix 530 expansion card).
-	  Say Y if you have an Amiga with a Gayle IDE interface and want to use
-	  IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
-	  it.
-	  Note that you also have to enable Zorro bus support if you want to
-	  use Gayle IDE interfaces on the Zorro expansion bus.
 
-config BLK_DEV_IDEDOUBLER
-	bool "Amiga IDE Doubler support (EXPERIMENTAL)"
-	depends on BLK_DEV_GAYLE && EXPERIMENTAL
-	---help---
-	  This feature provides support for the so-called `IDE doublers' (made
+	  It also provides support for the so-called `IDE doublers' (made
 	  by various manufacturers, e.g. Eyetech) that can be connected to
 	  the on-board IDE interface of some Amiga models. Using such an IDE
 	  doubler, you can connect up to four instead of two IDE devices to
-	  the Amiga's on-board IDE interface.
+	  the Amiga's on-board IDE interface. The feature is enabled at kernel
+	  runtime using the "gayle.doubler" kernel boot parameter.
 
-	  Note that the normal Amiga Gayle IDE driver may not work correctly
-	  if you have an IDE doubler and don't enable this feature!
+	  Say Y if you have an Amiga with a Gayle IDE interface and want to use
+	  IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+	  it.
 
-	  Say Y if you have an IDE doubler.  The feature is enabled at kernel
-	  runtime using the "gayle.doubler" kernel boot parameter.
+	  Note that you also have to enable Zorro bus support if you want to
+	  use Gayle IDE interfaces on the Zorro expansion bus.
 
 config BLK_DEV_BUDDHA
 	tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
@@ -871,6 +865,7 @@ config BLK_DEV_ALI14XX
 
 config BLK_DEV_DTC2278
 	tristate "DTC-2278 support"
+	select IDE_XFER_MODE
 	select IDE_LEGACY
 	help
 	  This driver is enabled at runtime using the "dtc2278.probe" kernel
@@ -902,6 +897,7 @@ config BLK_DEV_QD65XX
 
 config BLK_DEV_UMC8672
 	tristate "UMC-8672 support"
+	select IDE_XFER_MODE
 	select IDE_LEGACY
 	help
 	  This driver is enabled at runtime using the "umc8672.probe" kernel
@@ -915,5 +911,6 @@ endif
 config BLK_DEV_IDEDMA
 	def_bool BLK_DEV_IDEDMA_SFF || \
 		 BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+	select IDE_XFER_MODE
 
 endif # IDE
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/macide.c linux-libre-2.6.30-gnu1/drivers/ide/macide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/macide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/macide.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,6 +80,11 @@ static void __init macide_setup_ports(hw
 	hw->chipset = ide_generic;
 }
 
+static const struct ide_port_info macide_port_info = {
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
+};
+
 static const char *mac_ide_name[] =
 	{ "Quadra", "Powerbook", "Powerbook Baboon" };
 
@@ -122,7 +127,7 @@ static int __init macide_init(void)
 
 	macide_setup_ports(&hw, base, irq, ack_intr);
 
-	return ide_host_add(NULL, hws, NULL);
+	return ide_host_add(&macide_port_info, hws, NULL);
 }
 
 module_init(macide_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/Makefile linux-libre-2.6.30-gnu1/drivers/ide/Makefile
--- linux-libre-2.6.29-gnu1/drivers/ide/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,9 +5,11 @@
 EXTRA_CFLAGS				+= -Idrivers/ide
 
 ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
-	      ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
+	      ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
+	      ide-io-std.o ide-eh.o
 
 # core IDE code
+ide-core-$(CONFIG_IDE_XFER_MODE)	+= ide-pio-blacklist.o ide-xfer-mode.o
 ide-core-$(CONFIG_IDE_TIMINGS)		+= ide-timings.o
 ide-core-$(CONFIG_IDE_ATAPI)		+= ide-atapi.o
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
@@ -19,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY)		+= ide-le
 
 obj-$(CONFIG_IDE)			+= ide-core.o
 
-obj-$(CONFIG_IDE_ARM)			+= ide_arm.o
-
 obj-$(CONFIG_BLK_DEV_ALI14XX)		+= ali14xx.o
 obj-$(CONFIG_BLK_DEV_UMC8672)		+= umc8672.o
 obj-$(CONFIG_BLK_DEV_DTC2278)		+= dtc2278.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/ns87415.c linux-libre-2.6.30-gnu1/drivers/ide/ns87415.c
--- linux-libre-2.6.29-gnu1/drivers/ide/ns87415.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/ns87415.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,57 +61,34 @@ static u8 superio_dma_sff_read_status(id
 	return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
 }
 
-static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void superio_tf_read(ide_drive_t *drive, struct ide_taskfile *tf,
+			    u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data = inw(io_ports->data_addr);
-
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
 
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+	if (valid & IDE_VALID_ERROR)
+		tf->error  = inb(io_ports->feature_addr);
+	if (valid & IDE_VALID_NSECT)
 		tf->nsect  = inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf->lbal   = inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf->lbam   = inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf->lbah   = inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+	if (valid & IDE_VALID_DEVICE)
 		tf->device = superio_ide_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature = inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = inb(io_ports->lbah_addr);
-	}
 }
 
+static void ns87415_dev_select(ide_drive_t *drive);
+
 static const struct ide_tp_ops superio_tp_ops = {
 	.exec_command		= ide_exec_command,
 	.read_status		= superio_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ns87415_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= superio_tf_read,
 
@@ -190,10 +167,18 @@ static void ns87415_prepare_drive (ide_d
 	local_irq_restore(flags);
 }
 
-static void ns87415_selectproc (ide_drive_t *drive)
+static void ns87415_dev_select(ide_drive_t *drive)
 {
 	ns87415_prepare_drive(drive,
 			      !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
+
+	outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
+}
+
+static void ns87415_dma_start(ide_drive_t *drive)
+{
+	ns87415_prepare_drive(drive, 1);
+	ide_dma_start(drive);
 }
 
 static int ns87415_dma_end(ide_drive_t *drive)
@@ -201,7 +186,6 @@ static int ns87415_dma_end(ide_drive_t *
 	ide_hwif_t *hwif = drive->hwif;
 	u8 dma_stat = 0, dma_cmd = 0;
 
-	drive->waiting_for_dma = 0;
 	dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
 	/* get DMA command mode */
 	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
@@ -210,21 +194,11 @@ static int ns87415_dma_end(ide_drive_t *
 	/* from ERRATA: clear the INTR & ERROR bits */
 	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
 	outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
-	/* and free any DMA resources */
-	ide_destroy_dmatable(drive);
-	/* verify good DMA status */
-	return (dma_stat & 7) != 4;
-}
 
-static int ns87415_dma_setup(ide_drive_t *drive)
-{
-	/* select DMA xfer */
-	ns87415_prepare_drive(drive, 1);
-	if (!ide_dma_setup(drive))
-		return 0;
-	/* DMA failed: select PIO xfer */
 	ns87415_prepare_drive(drive, 0);
-	return 1;
+
+	/* verify good DMA status */
+	return (dma_stat & 7) != 4;
 }
 
 static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
@@ -242,7 +216,7 @@ static void __devinit init_hwif_ns87415
 	 * Also, leave IRQ masked during drive probing, to prevent infinite
 	 * interrupts from a potentially floating INTA..
 	 *
-	 * IRQs get unmasked in selectproc when drive is first used.
+	 * IRQs get unmasked in dev_select() when drive is first used.
 	 */
 	(void) pci_read_config_dword(dev, 0x40, &ctrl);
 	(void) pci_read_config_byte(dev, 0x09, &progif);
@@ -270,7 +244,7 @@ static void __devinit init_hwif_ns87415
 #ifdef __sparc_v9__
 		/*
 		 * XXX: Reset the device, if we don't it will not respond to
-		 *      SELECT_DRIVE() properly during first ide_probe_port().
+		 *      dev_select() properly during first ide_probe_port().
 		 */
 		timeout = 10000;
 		outb(12, hwif->io_ports.ctl_addr);
@@ -286,9 +260,7 @@ static void __devinit init_hwif_ns87415
 	}
 
 	if (!using_inta)
-		hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
-	else if (!hwif->irq && hwif->mate && hwif->mate->irq)
-		hwif->irq = hwif->mate->irq;	/* share IRQ with mate */
+		hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
 
 	if (!hwif->dma_base)
 		return;
@@ -296,26 +268,35 @@ static void __devinit init_hwif_ns87415
 	outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
 }
 
-static const struct ide_port_ops ns87415_port_ops = {
-	.selectproc		= ns87415_selectproc,
+static const struct ide_tp_ops ns87415_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= ns87415_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
 };
 
 static const struct ide_dma_ops ns87415_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
-	.dma_setup		= ns87415_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
-	.dma_start		= ide_dma_start,
+	.dma_setup		= ide_dma_setup,
+	.dma_start		= ns87415_dma_start,
 	.dma_end		= ns87415_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= superio_dma_sff_read_status,
 };
 
 static const struct ide_port_info ns87415_chipset __devinitdata = {
 	.name		= DRV_NAME,
 	.init_hwif	= init_hwif_ns87415,
-	.port_ops	= &ns87415_port_ops,
+	.tp_ops 	= &ns87415_tp_ops,
 	.dma_ops	= &ns87415_dma_ops,
 	.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
 			  IDE_HFLAG_NO_ATAPI_DMA,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/palm_bk3710.c linux-libre-2.6.30-gnu1/drivers/ide/palm_bk3710.c
--- linux-libre-2.6.29-gnu1/drivers/ide/palm_bk3710.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/palm_bk3710.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,27 +39,12 @@
 /* Primary Control Offset */
 #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
 
-/*
- * PalmChip 3710 IDE Controller UDMA timing structure Definition
- */
-struct palm_bk3710_udmatiming {
-	unsigned int rptime;	/* Ready to pause time  */
-	unsigned int cycletime;	/* Cycle Time           */
-};
-
 #define BK3710_BMICP		0x00
 #define BK3710_BMISP		0x02
 #define BK3710_BMIDTP		0x04
-#define BK3710_BMICS		0x08
-#define BK3710_BMISS		0x0A
-#define BK3710_BMIDTS		0x0C
 #define BK3710_IDETIMP		0x40
-#define BK3710_IDETIMS		0x42
-#define BK3710_SIDETIM		0x44
-#define BK3710_SLEWCTL		0x45
 #define BK3710_IDESTATUS	0x47
 #define BK3710_UDMACTL		0x48
-#define BK3710_UDMATIM		0x4A
 #define BK3710_MISCCTL		0x50
 #define BK3710_REGSTB		0x54
 #define BK3710_REGRCVR		0x58
@@ -71,17 +56,22 @@ struct palm_bk3710_udmatiming {
 #define BK3710_UDMATRP		0x70
 #define BK3710_UDMAENV		0x74
 #define BK3710_IORDYTMP		0x78
-#define BK3710_IORDYTMS		0x7C
 
 static unsigned ideclk_period; /* in nanoseconds */
 
+struct palm_bk3710_udmatiming {
+	unsigned int rptime;	/* tRP -- Ready to pause time (nsec) */
+	unsigned int cycletime;	/* tCYCTYP2/2 -- avg Cycle Time (nsec) */
+				/* tENV is always a minimum of 20 nsec */
+};
+
 static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
-	{160, 240},		/* UDMA Mode 0 */
-	{125, 160},		/* UDMA Mode 1 */
-	{100, 120},		/* UDMA Mode 2 */
-	{100, 90},		/* UDMA Mode 3 */
-	{100, 60},		/* UDMA Mode 4 */
-	{85,  40},		/* UDMA Mode 5 */
+	{ 160, 240 / 2 },	/* UDMA Mode 0 */
+	{ 125, 160 / 2 },	/* UDMA Mode 1 */
+	{ 100, 120 / 2 },	/* UDMA Mode 2 */
+	{ 100,  90 / 2 },	/* UDMA Mode 3 */
+	{ 100,  60 / 2 },	/* UDMA Mode 4 */
+	{  85,  40 / 2 },	/* UDMA Mode 5 */
 };
 
 static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
@@ -98,11 +88,6 @@ static void palm_bk3710_setudmamode(void
 	trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
 			   ideclk_period) - 1;
 
-	/* udmatim Register */
-	val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
-	val16 |= (mode << (dev ? 4 : 0));
-	writew(val16, base + BK3710_UDMATIM);
-
 	/* udmastb Ultra DMA Access Strobe Width */
 	val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
 	val32 |= (t0 << (dev ? 8 : 0));
@@ -163,10 +148,11 @@ static void palm_bk3710_setpiomode(void
 	u32 val32;
 	struct ide_timing *t;
 
+	t = ide_timing_find_mode(XFER_PIO_0 + mode);
+
 	/* PIO Data Setup */
 	t0 = DIV_ROUND_UP(cycletime, ideclk_period);
-	t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
-			  ideclk_period);
+	t2 = DIV_ROUND_UP(t->active, ideclk_period);
 
 	t2i = t0 - t2 - 1;
 	t2 -= 1;
@@ -187,7 +173,6 @@ static void palm_bk3710_setpiomode(void
 	}
 
 	/* TASKFILE Setup */
-	t = ide_timing_find_mode(XFER_PIO_0 + mode);
 	t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
 	t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
 
@@ -236,42 +221,23 @@ static void palm_bk3710_set_pio_mode(ide
 static void __devinit palm_bk3710_chipinit(void __iomem *base)
 {
 	/*
-	 * enable the reset_en of ATA controller so that when ata signals
-	 * are brought out, by writing into device config. at that
-	 * time por_n signal should not be 'Z' and have a stable value.
+	 * REVISIT:  the ATA reset signal needs to be managed through a
+	 * GPIO, which means it should come from platform_data.  Until
+	 * we get and use such information, we have to trust that things
+	 * have been reset before we get here.
 	 */
-	writel(0x0300, base + BK3710_MISCCTL);
-
-	/* wait for some time and deassert the reset of ATA Device. */
-	mdelay(100);
-
-	/* Deassert the Reset */
-	writel(0x0200, base + BK3710_MISCCTL);
 
 	/*
 	 * Program the IDETIMP Register Value based on the following assumptions
 	 *
 	 * (ATA_IDETIMP_IDEEN		, ENABLE ) |
-	 * (ATA_IDETIMP_SLVTIMEN	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSMPL		, 70NS)    |
-	 * (ATA_IDETIMP_RDYRCVRY	, 50NS)    |
-	 * (ATA_IDETIMP_DMAFTIM1	, PIOCOMP) |
 	 * (ATA_IDETIMP_PREPOST1	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSEN1		, DISABLE) |
-	 * (ATA_IDETIMP_PIOFTIM1	, DISABLE) |
-	 * (ATA_IDETIMP_DMAFTIM0	, PIOCOMP) |
 	 * (ATA_IDETIMP_PREPOST0	, DISABLE) |
-	 * (ATA_IDETIMP_RDYSEN0		, DISABLE) |
-	 * (ATA_IDETIMP_PIOFTIM0	, DISABLE)
-	 */
-	writew(0xB388, base + BK3710_IDETIMP);
-
-	/*
-	 * Configure  SIDETIM  Register
-	 * (ATA_SIDETIM_RDYSMPS1	,120NS ) |
-	 * (ATA_SIDETIM_RDYRCYS1	,120NS )
+	 *
+	 * DM6446 silicon rev 2.1 and earlier have no observed net benefit
+	 * from enabling prefetch/postwrite.
 	 */
-	writeb(0, base + BK3710_SIDETIM);
+	writew(BIT(15), base + BK3710_IDETIMP);
 
 	/*
 	 * UDMACTL Ultra-ATA DMA Control
@@ -283,11 +249,11 @@ static void __devinit palm_bk3710_chipin
 
 	/*
 	 * MISCCTL Miscellaneous Conrol Register
-	 * (ATA_MISCCTL_RSTMODEP	, 1) |
-	 * (ATA_MISCCTL_RESETP		, 0) |
+	 * (ATA_MISCCTL_HWNHLD1P	, 1 cycle)
+	 * (ATA_MISCCTL_HWNHLD0P	, 1 cycle)
 	 * (ATA_MISCCTL_TIMORIDE	, 1)
 	 */
-	writel(0x201, base + BK3710_MISCCTL);
+	writel(0x001, base + BK3710_MISCCTL);
 
 	/*
 	 * IORDYTMP IORDY Timer for Primary Register
@@ -347,7 +313,7 @@ static int __init palm_bk3710_probe(stru
 	struct clk *clk;
 	struct resource *mem, *irq;
 	void __iomem *base;
-	unsigned long rate;
+	unsigned long rate, mem_size;
 	int i, rc;
 	hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
@@ -357,10 +323,9 @@ static int __init palm_bk3710_probe(stru
 
 	clk_enable(clk);
 	rate = clk_get_rate(clk);
-	ideclk_period = 1000000000UL / rate;
 
-	/* Register the IDE interface with Linux ATA Interface */
-	memset(&hw, 0, sizeof(hw));
+	/* NOTE:  round *down* to meet minimum timings; we count in clocks */
+	ideclk_period = 1000000000UL / rate;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (mem == NULL) {
@@ -374,17 +339,23 @@ static int __init palm_bk3710_probe(stru
 		return -ENODEV;
 	}
 
-	if (request_mem_region(mem->start, mem->end - mem->start + 1,
-			       "palm_bk3710") == NULL) {
+	mem_size = mem->end - mem->start + 1;
+	if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
 		printk(KERN_ERR "failed to request memory region\n");
 		return -EBUSY;
 	}
 
-	base = IO_ADDRESS(mem->start);
+	base = ioremap(mem->start, mem_size);
+	if (!base) {
+		printk(KERN_ERR "failed to map IO memory\n");
+		release_mem_region(mem->start, mem_size);
+		return -ENOMEM;
+	}
 
 	/* Configure the Palm Chip controller */
 	palm_bk3710_chipinit(base);
 
+	memset(&hw, 0, sizeof(hw));
 	for (i = 0; i < IDE_NR_PORTS - 2; i++)
 		hw.io_ports_array[i] = (unsigned long)
 				(base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
@@ -397,6 +368,7 @@ static int __init palm_bk3710_probe(stru
 	palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
 							     ATA_UDMA5;
 
+	/* Register the IDE interface with Linux */
 	rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
 	if (rc)
 		goto out;
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/pdc202xx_new.c linux-libre-2.6.30-gnu1/drivers/ide/pdc202xx_new.c
--- linux-libre-2.6.29-gnu1/drivers/ide/pdc202xx_new.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/pdc202xx_new.c	2009-06-09 23:05:27.000000000 -0400
@@ -325,7 +325,7 @@ static void apple_kiwi_init(struct pci_d
 }
 #endif /* CONFIG_PPC_PMAC */
 
-static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
+static int init_chipset_pdcnew(struct pci_dev *dev)
 {
 	const char *name = DRV_NAME;
 	unsigned long dma_base = pci_resource_start(dev, 4);
@@ -444,7 +444,7 @@ static unsigned int init_chipset_pdcnew(
 #endif
 
  out:
-	return dev->irq;
+	return 0;
 }
 
 static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/pdc202xx_old.c linux-libre-2.6.30-gnu1/drivers/ide/pdc202xx_old.c
--- linux-libre-2.6.29-gnu1/drivers/ide/pdc202xx_old.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/pdc202xx_old.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
- *  Copyright (C) 2006-2007		MontaVista Software, Inc.
+ *  Copyright (C) 2006-2007, 2009	MontaVista Software, Inc.
  *  Copyright (C) 2007			Bartlomiej Zolnierkiewicz
  *
  *  Portions Copyright (C) 1999 Promise Technology, Inc.
@@ -227,28 +227,19 @@ somebody_else:
 	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
 }
 
-static void pdc202xx_reset_host (ide_hwif_t *hwif)
+static void pdc202xx_reset(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif	= drive->hwif;
 	unsigned long high_16	= hwif->extra_base - 16;
 	u8 udma_speed_flag	= inb(high_16 | 0x001f);
 
+	printk(KERN_WARNING "PDC202xx: software reset...\n");
+
 	outb(udma_speed_flag | 0x10, high_16 | 0x001f);
 	mdelay(100);
 	outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
 	mdelay(2000);	/* 2 seconds ?! */
 
-	printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
-		hwif->channel ? "Secondary" : "Primary");
-}
-
-static void pdc202xx_reset (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= drive->hwif;
-	ide_hwif_t *mate	= hwif->mate;
-
-	pdc202xx_reset_host(hwif);
-	pdc202xx_reset_host(mate);
-
 	ide_set_max_pio(drive);
 }
 
@@ -258,13 +249,7 @@ static void pdc202xx_dma_lost_irq(ide_dr
 	ide_dma_lost_irq(drive);
 }
 
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
-	pdc202xx_reset(drive);
-	ide_dma_timeout(drive);
-}
-
-static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
+static int init_chipset_pdc202xx(struct pci_dev *dev)
 {
 	unsigned long dmabase = pci_resource_start(dev, 4);
 	u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
@@ -290,7 +275,7 @@ static unsigned int init_chipset_pdc202x
 		printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
 	}
 out:
-	return dev->irq;
+	return 0;
 }
 
 static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
@@ -331,24 +316,23 @@ static const struct ide_port_ops pdc2026
 static const struct ide_dma_ops pdc20246_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= pdc202xx_dma_test_irq,
-	.dma_lost_irq		= pdc202xx_dma_lost_irq,
-	.dma_timeout		= pdc202xx_dma_timeout,
+	.dma_lost_irq		= ide_dma_lost_irq,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
 static const struct ide_dma_ops pdc2026x_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= pdc202xx_dma_start,
 	.dma_end		= pdc202xx_dma_end,
 	.dma_test_irq		= pdc202xx_dma_test_irq,
 	.dma_lost_irq		= pdc202xx_dma_lost_irq,
-	.dma_timeout		= pdc202xx_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
+	.dma_clear		= pdc202xx_reset,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/piix.c linux-libre-2.6.30-gnu1/drivers/ide/piix.c
--- linux-libre-2.6.29-gnu1/drivers/ide/piix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/piix.c	2009-06-09 23:05:27.000000000 -0400
@@ -204,7 +204,7 @@ static void piix_set_dma_mode(ide_drive_
  *	out to be nice and simple.
  */
 
-static unsigned int init_chipset_ich(struct pci_dev *dev)
+static int init_chipset_ich(struct pci_dev *dev)
 {
 	u32 extra = 0;
 
@@ -263,6 +263,7 @@ static const struct ich_laptop ich_lapto
 	{ 0x24CA, 0x1025, 0x003d },	/* ICH4 on ACER TM290 */
 	{ 0x266F, 0x1025, 0x0066 },	/* ICH6 on ACER Aspire 1694WLMi */
 	{ 0x2653, 0x1043, 0x82D8 },	/* ICH6M on Asus Eee 701 */
+	{ 0x27df, 0x104d, 0x900e },	/* ICH7 on Sony TZ-90 */
 	/* end marker */
 	{ 0, }
 };
@@ -318,19 +319,12 @@ static const struct ide_port_ops ich_por
 	.cable_detect		= piix_cable_detect,
 };
 
-#ifndef CONFIG_IA64
- #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
-#else
- #define IDE_HFLAGS_PIIX 0
-#endif
-
 #define DECLARE_PIIX_DEV(udma) \
 	{						\
 		.name		= DRV_NAME,		\
 		.init_hwif	= init_hwif_piix,	\
 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
 		.port_ops	= &piix_port_ops,	\
-		.host_flags	= IDE_HFLAGS_PIIX,	\
 		.pio_mask	= ATA_PIO4,		\
 		.swdma_mask	= ATA_SWDMA2_ONLY,	\
 		.mwdma_mask	= ATA_MWDMA12_ONLY,	\
@@ -344,7 +338,6 @@ static const struct ide_port_ops ich_por
 		.init_hwif	= init_hwif_piix, \
 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
 		.port_ops	= &ich_port_ops, \
-		.host_flags	= IDE_HFLAGS_PIIX, \
 		.pio_mask	= ATA_PIO4, \
 		.swdma_mask	= ATA_SWDMA2_ONLY, \
 		.mwdma_mask	= ATA_MWDMA12_ONLY, \
@@ -360,8 +353,7 @@ static const struct ide_port_info piix_p
 		 */
 		.name		= DRV_NAME,
 		.enablebits	= {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
-		.host_flags	= IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
-				  IDE_HFLAGS_PIIX,
+		.host_flags	= IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA,
 		.pio_mask	= ATA_PIO4,
 		/* This is a painful system best to let it self tune for now */
 	},
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/pmac.c linux-libre-2.6.30-gnu1/drivers/ide/pmac.c
--- linux-libre-2.6.29-gnu1/drivers/ide/pmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/pmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -404,9 +404,6 @@ kauai_lookup_timing(struct kauai_timing*
 #define IDE_WAKEUP_DELAY	(1*HZ)
 
 static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
-static void pmac_ide_selectproc(ide_drive_t *drive);
-static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
 
 #define PMAC_IDE_REG(x) \
 	((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
@@ -416,8 +413,7 @@ static void pmac_ide_kauai_selectproc(id
  * timing register when selecting that unit. This version is for
  * ASICs with a single timing register
  */
-static void
-pmac_ide_selectproc(ide_drive_t *drive)
+static void pmac_ide_apply_timings(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
@@ -435,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
  * timing register when selecting that unit. This version is for
  * ASICs with a dual timing register (Kauai)
  */
-static void
-pmac_ide_kauai_selectproc(ide_drive_t *drive)
+static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
@@ -465,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *
 	if (pmif->kind == controller_sh_ata6 ||
 	    pmif->kind == controller_un_ata6 ||
 	    pmif->kind == controller_k2_ata6)
-		pmac_ide_kauai_selectproc(drive);
+		pmac_ide_kauai_apply_timings(drive);
 	else
-		pmac_ide_selectproc(drive);
+		pmac_ide_apply_timings(drive);
+}
+
+static void pmac_dev_select(ide_drive_t *drive)
+{
+	pmac_ide_apply_timings(drive);
+
+	writeb(drive->select | ATA_DEVICE_OBS,
+	       (void __iomem *)drive->hwif->io_ports.device_addr);
+}
+
+static void pmac_kauai_dev_select(ide_drive_t *drive)
+{
+	pmac_ide_kauai_apply_timings(drive);
+
+	writeb(drive->select | ATA_DEVICE_OBS,
+	       (void __iomem *)drive->hwif->io_ports.device_addr);
 }
 
 static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
@@ -477,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t
 				     + IDE_TIMING_CONFIG));
 }
 
-static void pmac_set_irq(ide_hwif_t *hwif, int on)
+static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
 {
-	u8 ctl = ATA_DEVCTL_OBS;
-
-	if (on == 4) { /* hack for SRST */
-		ctl |= 4;
-		on &= ~4;
-	}
-
-	ctl |= on ? 0 : 2;
-
 	writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
 	(void)readl((void __iomem *)(hwif->io_ports.data_addr
 				     + IDE_TIMING_CONFIG));
@@ -917,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 	struct device_node *np = pmif->node;
 	const char *cable = of_get_property(np, "cable-type", NULL);
+	struct device_node *root = of_find_node_by_path("/");
+	const char *model = of_get_property(root, "model", NULL);
 
 	/* Get cable type from device-tree. */
-	if (cable && !strncmp(cable, "80-", 3))
-		return ATA_CBL_PATA80;
+	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.
@@ -955,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_o
 	.exec_command		= pmac_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= pmac_write_devctl,
 
-	.set_irq		= pmac_set_irq,
-
+	.dev_select		= pmac_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -965,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_o
 	.output_data		= ide_output_data,
 };
 
-static const struct ide_port_ops pmac_ide_ata6_port_ops = {
-	.init_dev		= pmac_ide_init_dev,
-	.set_pio_mode		= pmac_ide_set_pio_mode,
-	.set_dma_mode		= pmac_ide_set_dma_mode,
-	.selectproc		= pmac_ide_kauai_selectproc,
-	.cable_detect		= pmac_ide_cable_detect,
+static const struct ide_tp_ops pmac_ata6_tp_ops = {
+	.exec_command		= pmac_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= pmac_write_devctl,
+
+	.dev_select		= pmac_kauai_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
 };
 
 static const struct ide_port_ops pmac_ide_ata4_port_ops = {
 	.init_dev		= pmac_ide_init_dev,
 	.set_pio_mode		= pmac_ide_set_pio_mode,
 	.set_dma_mode		= pmac_ide_set_dma_mode,
-	.selectproc		= pmac_ide_selectproc,
 	.cable_detect		= pmac_ide_cable_detect,
 };
 
@@ -985,7 +1000,6 @@ static const struct ide_port_ops pmac_id
 	.init_dev		= pmac_ide_init_dev,
 	.set_pio_mode		= pmac_ide_set_pio_mode,
 	.set_dma_mode		= pmac_ide_set_dma_mode,
-	.selectproc		= pmac_ide_selectproc,
 };
 
 static const struct ide_dma_ops pmac_dma_ops;
@@ -1022,15 +1036,18 @@ static int __devinit pmac_ide_setup_devi
 	pmif->broken_dma = pmif->broken_dma_warn = 0;
 	if (of_device_is_compatible(np, "shasta-ata")) {
 		pmif->kind = controller_sh_ata6;
-		d.port_ops = &pmac_ide_ata6_port_ops;
+		d.tp_ops = &pmac_ata6_tp_ops;
+		d.port_ops = &pmac_ide_ata4_port_ops;
 		d.udma_mask = ATA_UDMA6;
 	} else if (of_device_is_compatible(np, "kauai-ata")) {
 		pmif->kind = controller_un_ata6;
-		d.port_ops = &pmac_ide_ata6_port_ops;
+		d.tp_ops = &pmac_ata6_tp_ops;
+		d.port_ops = &pmac_ide_ata4_port_ops;
 		d.udma_mask = ATA_UDMA5;
 	} else if (of_device_is_compatible(np, "K2-UATA")) {
 		pmif->kind = controller_k2_ata6;
-		d.port_ops = &pmac_ide_ata6_port_ops;
+		d.tp_ops = &pmac_ata6_tp_ops;
+		d.port_ops = &pmac_ide_ata4_port_ops;
 		d.udma_mask = ATA_UDMA5;
 	} else if (of_device_is_compatible(np, "keylargo-ata")) {
 		if (strcmp(np->name, "ata-4") == 0) {
@@ -1422,17 +1439,16 @@ out:
  * pmac_ide_build_dmatable builds the DBDMA command list
  * for a transfer and sets the DBDMA channel to point to it.
  */
-static int
-pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 	struct dbdma_cmd *table;
-	int i, count = 0;
 	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
 	struct scatterlist *sg;
-	int wr = (rq_data_dir(rq) == WRITE);
+	int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
+	int i = cmd->sg_nents, count = 0;
 
 	/* DMA table is already aligned */
 	table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1442,11 +1458,6 @@ pmac_ide_build_dmatable(ide_drive_t *dri
 	while (readl(&dma->status) & RUN)
 		udelay(1);
 
-	hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
-	if (!i)
-		return 0;
-
 	/* Build DBDMA commands list */
 	sg = hwif->sg_table;
 	while (i && sg_dma_len(sg)) {
@@ -1462,7 +1473,7 @@ pmac_ide_build_dmatable(ide_drive_t *dri
 				       "switching to PIO on Ohare chipset\n", drive->name);
 				pmif->broken_dma_warn = 1;
 			}
-			goto use_pio_instead;
+			return 0;
 		}
 		while (cur_len) {
 			unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
@@ -1470,7 +1481,7 @@ pmac_ide_build_dmatable(ide_drive_t *dri
 			if (count++ >= MAX_DCMDS) {
 				printk(KERN_WARNING "%s: DMA table too small\n",
 				       drive->name);
-				goto use_pio_instead;
+				return 0;
 			}
 			st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
 			st_le16(&table->req_count, tc);
@@ -1499,9 +1510,6 @@ pmac_ide_build_dmatable(ide_drive_t *dri
 
 	printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
 
-use_pio_instead:
-	ide_destroy_dmatable(drive);
-
 	return 0; /* revert to PIO for this request */
 }
 
@@ -1509,39 +1517,27 @@ use_pio_instead:
  * Prepare a DMA transfer. We build the DMA table, adjust the timings for
  * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
  */
-static int
-pmac_ide_dma_setup(ide_drive_t *drive)
+static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	pmac_ide_hwif_t *pmif =
 		(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
-	struct request *rq = hwif->rq;
 	u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
+	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
 
-	if (!pmac_ide_build_dmatable(drive, rq)) {
-		ide_map_sg(drive, rq);
+	if (pmac_ide_build_dmatable(drive, cmd) == 0)
 		return 1;
-	}
 
 	/* Apple adds 60ns to wrDataSetup on reads */
 	if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
-		writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
+		writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
 			PMAC_IDE_REG(IDE_TIMING_CONFIG));
 		(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
 	}
 
-	drive->waiting_for_dma = 1;
-
 	return 0;
 }
 
-static void
-pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-}
-
 /*
  * Kick the DMA controller into life after the DMA command has been issued
  * to the drive.
@@ -1573,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
 	volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
 	u32 dstat;
 
-	drive->waiting_for_dma = 0;
 	dstat = readl(&dma->status);
 	writel(((RUN|WAKE|DEAD) << 16), &dma->control);
 
-	ide_destroy_dmatable(drive);
-
 	/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
 	 * in theory, but with ATAPI decices doing buffer underruns, that would
 	 * cause us to disable DMA, which isn't what we want
@@ -1662,11 +1655,9 @@ pmac_ide_dma_lost_irq (ide_drive_t *driv
 static const struct ide_dma_ops pmac_dma_ops = {
 	.dma_host_set		= pmac_ide_dma_host_set,
 	.dma_setup		= pmac_ide_dma_setup,
-	.dma_exec_cmd		= pmac_ide_dma_exec_cmd,
 	.dma_start		= pmac_ide_dma_start,
 	.dma_end		= pmac_ide_dma_end,
 	.dma_test_irq		= pmac_ide_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= pmac_ide_dma_lost_irq,
 };
 
@@ -1691,7 +1682,7 @@ static int __devinit pmac_ide_init_dma(i
 	 * The +2 is +1 for the stop command and +1 to allow for
 	 * aligning the start address to a multiple of 16 bytes.
 	 */
-	pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
+	pmif->dma_table_cpu = pci_alloc_consistent(
 		dev,
 		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
 		&hwif->dmatable_dma);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/q40ide.c linux-libre-2.6.30-gnu1/drivers/ide/q40ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/q40ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/q40ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,8 @@
 #include <linux/blkdev.h>
 #include <linux/ide.h>
 
+#include <asm/ide.h>
+
     /*
      *  Bases of the IDE interfaces
      */
@@ -72,26 +74,30 @@ static void q40_ide_setup_ports(hw_regs_
 	hw->chipset = ide_generic;
 }
 
-static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			      void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-		return insw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_insw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
-	insw_swapw(data_addr, buf, (len + 1) / 2);
+	raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
 
-static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			       void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
 
-	if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
-		return outsw(data_addr, buf, (len + 1) / 2);
+	if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) {
+		__ide_mm_outsw(data_addr, buf, (len + 1) / 2);
+		return;
+	}
 
-	outsw_swapw(data_addr, buf, (len + 1) / 2);
+	raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
 }
 
 /* Q40 has a byte-swapped IDE interface */
@@ -99,9 +105,9 @@ static const struct ide_tp_ops q40ide_tp
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -111,7 +117,8 @@ static const struct ide_tp_ops q40ide_tp
 
 static const struct ide_port_info q40ide_port_info = {
 	.tp_ops			= &q40ide_tp_ops,
-	.host_flags		= IDE_HFLAG_NO_DMA,
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+	.irq_flags		= IRQF_SHARED,
 };
 
 /* 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/qd65xx.c linux-libre-2.6.30-gnu1/drivers/ide/qd65xx.c
--- linux-libre-2.6.29-gnu1/drivers/ide/qd65xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/qd65xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /*
  * This routine is invoked to prepare for access to a given drive.
  */
 
-static void qd65xx_select(ide_drive_t *drive)
+static void qd65xx_dev_select(ide_drive_t *drive)
 {
 	u8 index = ((	(QD_TIMREG(drive)) & 0x80 ) >> 7) |
 			(QD_TIMREG(drive) & 0x02);
 
 	if (timings[index] != QD_TIMING(drive))
 		outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+
+	outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
 }
 
 /*
@@ -309,20 +311,33 @@ static void __init qd6580_init_dev(ide_d
 	drive->drive_data = (drive->dn & 1) ? t2 : t1;
 }
 
+static const struct ide_tp_ops qd65xx_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= qd65xx_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
+};
+
 static const struct ide_port_ops qd6500_port_ops = {
 	.init_dev		= qd6500_init_dev,
 	.set_pio_mode		= qd6500_set_pio_mode,
-	.selectproc		= qd65xx_select,
 };
 
 static const struct ide_port_ops qd6580_port_ops = {
 	.init_dev		= qd6580_init_dev,
 	.set_pio_mode		= qd6580_set_pio_mode,
-	.selectproc		= qd65xx_select,
 };
 
 static const struct ide_port_info qd65xx_port_info __initdata = {
 	.name			= DRV_NAME,
+	.tp_ops 		= &qd65xx_tp_ops,
 	.chipset		= ide_qd65xx,
 	.host_flags		= IDE_HFLAG_IO_32BIT |
 				  IDE_HFLAG_NO_DMA,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/sc1200.c linux-libre-2.6.30-gnu1/drivers/ide/sc1200.c
--- linux-libre-2.6.29-gnu1/drivers/ide/sc1200.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/sc1200.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t
 		if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
 		    (mateid[ATA_ID_UDMA_MODES] & 7))
 			goto out;
-		if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
-		    (mateid[ATA_ID_MWDMA_MODES] & 7))
+		if (mateid[ATA_ID_MWDMA_MODES] & 7)
 			mask = 0;
 	}
 out:
@@ -183,9 +182,6 @@ static int sc1200_dma_end(ide_drive_t *d
 	outb(dma_stat|0x1b, dma_base+2);	/* clear the INTR & ERROR bits */
 	outb(inb(dma_base)&~1, dma_base);	/* !! DO THIS HERE !! stop DMA */
 
-	drive->waiting_for_dma = 0;
-	ide_destroy_dmatable(drive);		/* purge DMA mappings */
-
 	return (dma_stat & 7) != 4;		/* verify good DMA status */
 }
 
@@ -286,12 +282,11 @@ static const struct ide_port_ops sc1200_
 static const struct ide_dma_ops sc1200_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= sc1200_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/scc_pata.c linux-libre-2.6.30-gnu1/drivers/ide/scc_pata.c
--- linux-libre-2.6.29-gnu1/drivers/ide/scc_pata.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/scc_pata.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,17 +148,8 @@ static u8 scc_dma_sff_read_status(ide_hw
 	return (u8)in_be32((void *)(hwif->dma_base + 4));
 }
 
-static void scc_set_irq(ide_hwif_t *hwif, int on)
+static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
 {
-	u8 ctl = ATA_DEVCTL_OBS;
-
-	if (on == 4) { /* hack for SRST */
-		ctl |= 4;
-		on &= ~4;
-	}
-
-	ctl |= on ? 0 : 2;
-
 	out_be32((void *)hwif->io_ports.ctl_addr, ctl);
 	eieio();
 	in_be32((void *)(hwif->dma_base + 0x01c));
@@ -303,8 +294,9 @@ static void scc_dma_host_set(ide_drive_t
 }
 
 /**
- *	scc_ide_dma_setup	-	begin a DMA phase
+ *	scc_dma_setup	-	begin a DMA phase
  *	@drive: target device
+ *	@cmd: command
  *
  *	Build an IDE DMA PRD (IDE speak for scatter gather table)
  *	and then set up the DMA transfer registers.
@@ -313,36 +305,28 @@ static void scc_dma_host_set(ide_drive_t
  *	is returned.
  */
 
-static int scc_dma_setup(ide_drive_t *drive)
+static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
-	unsigned int reading;
+	u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
 	u8 dma_stat;
 
-	if (rq_data_dir(rq))
-		reading = 0;
-	else
-		reading = 1 << 3;
-
 	/* fall back to pio! */
-	if (!ide_build_dmatable(drive, rq)) {
-		ide_map_sg(drive, rq);
+	if (ide_build_dmatable(drive, cmd) == 0)
 		return 1;
-	}
 
 	/* PRD table */
 	out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
 
 	/* specify r/w */
-	out_be32((void __iomem *)hwif->dma_base, reading);
+	out_be32((void __iomem *)hwif->dma_base, rw);
 
 	/* read DMA status for INTR & ERROR flags */
 	dma_stat = scc_dma_sff_read_status(hwif);
 
 	/* clear INTR & ERROR flags */
 	out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
-	drive->waiting_for_dma = 1;
+
 	return 0;
 }
 
@@ -353,7 +337,6 @@ static void scc_dma_start(ide_drive_t *d
 
 	/* start DMA */
 	scc_ide_outb(dma_cmd | 1, hwif->dma_base);
-	wmb();
 }
 
 static int __scc_dma_end(ide_drive_t *drive)
@@ -361,7 +344,6 @@ static int __scc_dma_end(ide_drive_t *dr
 	ide_hwif_t *hwif = drive->hwif;
 	u8 dma_stat, dma_cmd;
 
-	drive->waiting_for_dma = 0;
 	/* get DMA command mode */
 	dma_cmd = scc_ide_inb(hwif->dma_base);
 	/* stop DMA */
@@ -370,10 +352,7 @@ static int __scc_dma_end(ide_drive_t *dr
 	dma_stat = scc_dma_sff_read_status(hwif);
 	/* clear the INTR & ERROR bits */
 	scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
-	/* purge DMA mappings */
-	ide_destroy_dmatable(drive);
 	/* verify good DMA status */
-	wmb();
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
 }
 
@@ -666,91 +645,43 @@ static int __devinit init_setup_scc(stru
 	return rc;
 }
 
-static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA)
-		out_be32((void *)io_ports->data_addr,
-			 (tf->hob_data << 8) | tf->data);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
 
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+	if (valid & IDE_VALID_FEATURE)
 		scc_ide_outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+	if (valid & IDE_VALID_NSECT)
 		scc_ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		scc_ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		scc_ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		scc_ide_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		scc_ide_outb((tf->device & HIHI) | drive->select,
-			     io_ports->device_addr);
+	if (valid & IDE_VALID_DEVICE)
+		scc_ide_outb(tf->device, io_ports->device_addr);
 }
 
-static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
 {
 	struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
 
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data = (u16)in_be32((void *)io_ports->data_addr);
-
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = scc_ide_inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+	if (valid & IDE_VALID_ERROR)
+		tf->error  = scc_ide_inb(io_ports->feature_addr);
+	if (valid & IDE_VALID_NSECT)
 		tf->nsect  = scc_ide_inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+	if (valid & IDE_VALID_LBAL)
 		tf->lbal   = scc_ide_inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+	if (valid & IDE_VALID_LBAM)
 		tf->lbam   = scc_ide_inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+	if (valid & IDE_VALID_LBAH)
 		tf->lbah   = scc_ide_inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+	if (valid & IDE_VALID_DEVICE)
 		tf->device = scc_ide_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = scc_ide_inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = scc_ide_inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = scc_ide_inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = scc_ide_inb(io_ports->lbah_addr);
-	}
 }
 
-static void scc_input_data(ide_drive_t *drive, struct request *rq,
+static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
 			   void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -766,7 +697,7 @@ static void scc_input_data(ide_drive_t *
 		scc_ide_insw(data_addr, buf, len / 2);
 }
 
-static void scc_output_data(ide_drive_t *drive,  struct request *rq,
+static void scc_output_data(ide_drive_t *drive,  struct ide_cmd *cmd,
 			    void *buf, unsigned int len)
 {
 	unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -853,9 +784,9 @@ static const struct ide_tp_ops scc_tp_op
 	.exec_command		= scc_exec_command,
 	.read_status		= scc_read_status,
 	.read_altstatus		= scc_read_altstatus,
+	.write_devctl		= scc_write_devctl,
 
-	.set_irq		= scc_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= scc_tf_load,
 	.tf_read		= scc_tf_read,
 
@@ -873,30 +804,25 @@ static const struct ide_port_ops scc_por
 static const struct ide_dma_ops scc_dma_ops = {
 	.dma_host_set		= scc_dma_host_set,
 	.dma_setup		= scc_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= scc_dma_start,
 	.dma_end		= scc_dma_end,
 	.dma_test_irq		= scc_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= scc_dma_sff_read_status,
 };
 
-#define DECLARE_SCC_DEV(name_str)			\
-  {							\
-      .name		= name_str,			\
-      .init_iops	= init_iops_scc,		\
-      .init_dma		= scc_init_dma,			\
-      .init_hwif	= init_hwif_scc,		\
-      .tp_ops		= &scc_tp_ops,		\
-      .port_ops		= &scc_port_ops,		\
-      .dma_ops		= &scc_dma_ops,			\
-      .host_flags	= IDE_HFLAG_SINGLE,		\
-      .pio_mask		= ATA_PIO4,			\
-  }
-
-static const struct ide_port_info scc_chipsets[] __devinitdata = {
-	/* 0 */ DECLARE_SCC_DEV("sccIDE"),
+static const struct ide_port_info scc_chipset __devinitdata = {
+	.name		= "sccIDE",
+	.init_iops	= init_iops_scc,
+	.init_dma	= scc_init_dma,
+	.init_hwif	= init_hwif_scc,
+	.tp_ops		= &scc_tp_ops,
+	.port_ops	= &scc_port_ops,
+	.dma_ops	= &scc_dma_ops,
+	.host_flags	= IDE_HFLAG_SINGLE,
+	.irq_flags	= IRQF_SHARED,
+	.pio_mask	= ATA_PIO4,
 };
 
 /**
@@ -910,7 +836,7 @@ static const struct ide_port_info scc_ch
 
 static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
+	return init_setup_scc(dev, &scc_chipset);
 }
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/serverworks.c linux-libre-2.6.30-gnu1/drivers/ide/serverworks.c
--- linux-libre-2.6.29-gnu1/drivers/ide/serverworks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/serverworks.c	2009-06-09 23:05:27.000000000 -0400
@@ -175,7 +175,7 @@ static void svwks_set_dma_mode(ide_drive
 	pci_write_config_byte(dev, 0x54, ultra_enable);
 }
 
-static unsigned int init_chipset_svwks(struct pci_dev *dev)
+static int init_chipset_svwks(struct pci_dev *dev)
 {
 	unsigned int reg;
 	u8 btr;
@@ -270,7 +270,7 @@ static unsigned int init_chipset_svwks(s
 		pci_write_config_byte(dev, 0x5A, btr);
 	}
 
-	return dev->irq;
+	return 0;
 }
 
 static u8 ata66_svwks_svwks(ide_hwif_t *hwif)
@@ -353,14 +353,11 @@ static const struct ide_port_ops svwks_p
 	.cable_detect		= svwks_cable_detect,
 };
 
-#define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS
-
 static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
 	{	/* 0: OSB4 */
 		.name		= DRV_NAME,
 		.init_chipset	= init_chipset_svwks,
 		.port_ops	= &osb4_port_ops,
-		.host_flags	= IDE_HFLAGS_SVWKS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= 0x00, /* UDMA is problematic on OSB4 */
@@ -369,7 +366,6 @@ static const struct ide_port_info server
 		.name		= DRV_NAME,
 		.init_chipset	= init_chipset_svwks,
 		.port_ops	= &svwks_port_ops,
-		.host_flags	= IDE_HFLAGS_SVWKS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
@@ -378,7 +374,6 @@ static const struct ide_port_info server
 		.name		= DRV_NAME,
 		.init_chipset	= init_chipset_svwks,
 		.port_ops	= &svwks_port_ops,
-		.host_flags	= IDE_HFLAGS_SVWKS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
@@ -387,7 +382,7 @@ static const struct ide_port_info server
 		.name		= DRV_NAME,
 		.init_chipset	= init_chipset_svwks,
 		.port_ops	= &svwks_port_ops,
-		.host_flags	= IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+		.host_flags	= IDE_HFLAG_SINGLE,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
@@ -396,7 +391,7 @@ static const struct ide_port_info server
 		.name		= DRV_NAME,
 		.init_chipset	= init_chipset_svwks,
 		.port_ops	= &svwks_port_ops,
-		.host_flags	= IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+		.host_flags	= IDE_HFLAG_SINGLE,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/setup-pci.c linux-libre-2.6.30-gnu1/drivers/ide/setup-pci.c
--- linux-libre-2.6.29-gnu1/drivers/ide/setup-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/setup-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -208,7 +208,7 @@ static int ide_pci_enable(struct pci_dev
 	 * a DMA mask field to the struct ide_port_info if we need it
 	 * (or let lower level driver set the DMA mask)
 	 */
-	ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+	ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
 	if (ret < 0) {
 		printk(KERN_ERR "%s %s: can't set DMA mask\n",
 			d->name, pci_name(dev));
@@ -305,7 +305,6 @@ static int ide_pci_check_iomem(struct pc
  *	@dev: PCI device holding interface
  *	@d: IDE port info
  *	@port: port number
- *	@irq: PCI IRQ
  *	@hw: hw_regs_t instance corresponding to this port
  *
  *	Perform the initial set up for the hardware interface structure. This
@@ -316,7 +315,7 @@ static int ide_pci_check_iomem(struct pc
  */
 
 static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
-			    unsigned int port, int irq, hw_regs_t *hw)
+			    unsigned int port, hw_regs_t *hw)
 {
 	unsigned long ctl = 0, base = 0;
 
@@ -344,7 +343,6 @@ static int ide_hw_configure(struct pci_d
 	}
 
 	memset(hw, 0, sizeof(*hw));
-	hw->irq = irq;
 	hw->dev = &dev->dev;
 	hw->chipset = d->chipset ? d->chipset : ide_pci;
 	ide_std_init_ports(hw, base, ctl | 2);
@@ -448,7 +446,6 @@ out:
  *	ide_pci_setup_ports	-	configure ports/devices on PCI IDE
  *	@dev: PCI device
  *	@d: IDE port info
- *	@pciirq: IRQ line
  *	@hw: hw_regs_t instances corresponding to this PCI IDE device
  *	@hws: hw_regs_t pointers table to update
  *
@@ -462,7 +459,7 @@ out:
  */
 
 void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
-			 int pciirq, hw_regs_t *hw, hw_regs_t **hws)
+			 hw_regs_t *hw, hw_regs_t **hws)
 {
 	int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
 	u8 tmp;
@@ -481,7 +478,7 @@ void ide_pci_setup_ports(struct pci_dev
 			continue;	/* port not enabled */
 		}
 
-		if (ide_hw_configure(dev, d, port, pciirq, hw + port))
+		if (ide_hw_configure(dev, d, port, hw + port))
 			continue;
 
 		*(hws + port) = hw + port;
@@ -524,7 +521,7 @@ static int do_ide_setup_pci_device(struc
 		if (noisy)
 			printk(KERN_INFO "%s %s: not 100%% native mode: will "
 				"probe irqs later\n", d->name, pci_name(dev));
-		pciirq = ret;
+		pciirq = 0;
 	} else if (!pciirq && noisy) {
 		printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n",
 			d->name, pci_name(dev), pciirq);
@@ -549,7 +546,7 @@ int ide_pci_init_one(struct pci_dev *dev
 	if (ret < 0)
 		goto out;
 
-	ide_pci_setup_ports(dev, d, 0, &hw[0], &hws[0]);
+	ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
 
 	host = ide_host_alloc(d, hws);
 	if (host == NULL) {
@@ -561,6 +558,8 @@ int ide_pci_init_one(struct pci_dev *dev
 
 	host->host_priv = priv;
 
+	host->irq_flags = IRQF_SHARED;
+
 	pci_set_drvdata(dev, host);
 
 	ret = do_ide_setup_pci_device(dev, d, 1);
@@ -568,7 +567,11 @@ int ide_pci_init_one(struct pci_dev *dev
 		goto out;
 
 	/* fixup IRQ */
-	hw[1].irq = hw[0].irq = ret;
+	if (ide_pci_is_in_compatibility_mode(dev)) {
+		hw[0].irq = pci_get_legacy_ide_irq(dev, 0);
+		hw[1].irq = pci_get_legacy_ide_irq(dev, 1);
+	} else
+		hw[1].irq = hw[0].irq = ret;
 
 	ret = ide_host_register(host, d, hws);
 	if (ret)
@@ -591,7 +594,7 @@ int ide_pci_init_two(struct pci_dev *dev
 		if (ret < 0)
 			goto out;
 
-		ide_pci_setup_ports(pdev[i], d, 0, &hw[i*2], &hws[i*2]);
+		ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
 	}
 
 	host = ide_host_alloc(d, hws);
@@ -605,6 +608,8 @@ int ide_pci_init_two(struct pci_dev *dev
 
 	host->host_priv = priv;
 
+	host->irq_flags = IRQF_SHARED;
+
 	pci_set_drvdata(pdev[0], host);
 	pci_set_drvdata(pdev[1], host);
 
@@ -619,7 +624,11 @@ int ide_pci_init_two(struct pci_dev *dev
 			goto out;
 
 		/* fixup IRQ */
-		hw[i*2 + 1].irq = hw[i*2].irq = ret;
+		if (ide_pci_is_in_compatibility_mode(pdev[i])) {
+			hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0);
+			hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1);
+		} else
+			hw[i*2 + 1].irq = hw[i*2].irq = ret;
 	}
 
 	ret = ide_host_register(host, d, hws);
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/sgiioc4.c linux-libre-2.6.30-gnu1/drivers/ide/sgiioc4.c
--- linux-libre-2.6.29-gnu1/drivers/ide/sgiioc4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/sgiioc4.c	2009-06-09 23:05:27.000000000 -0400
@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *
 		}
 	}
 
-	drive->waiting_for_dma = 0;
-	ide_destroy_dmatable(drive);
-
 	return dma_stat;
 }
 
@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_dri
 		sgiioc4_clearirq(drive);
 }
 
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
 {
+	struct ide_cmd *cmd = &drive->hwif->cmd;
+
 	sgiioc4_dma_end(drive);
+	ide_dma_unmap_sg(drive, cmd);
 	sgiioc4_clearirq(drive);
 }
 
@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direct
 	writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
 
 	writel(dma_direction, (void __iomem *)ioc4_dma_addr);
-	drive->waiting_for_dma = 1;
 }
 
 /* IOC4 Scatter Gather list Format 					 */
@@ -424,20 +422,13 @@ sgiioc4_configure_for_dma(int dma_direct
 /* | Upper 32 bits - Zero	    |EOL| 15 unused     | 16 Bit Length| */
 /* --------------------------------------------------------------------- */
 /* Creates the scatter gather list, DMA Table */
-static unsigned int
-sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	unsigned int *table = hwif->dmatable_cpu;
-	unsigned int count = 0, i = 1;
-	struct scatterlist *sg;
-
-	hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
-	if (!i)
-		return 0;	/* sglist of length Zero */
+	unsigned int count = 0, i = cmd->sg_nents;
+	struct scatterlist *sg = hwif->sg_table;
 
-	sg = hwif->sg_table;
 	while (i && sg_dma_len(sg)) {
 		dma_addr_t cur_addr;
 		int cur_len;
@@ -449,7 +440,7 @@ sgiioc4_build_dma_table(ide_drive_t * dr
 				printk(KERN_WARNING
 				       "%s: DMA table too small\n",
 				       drive->name);
-				goto use_pio_instead;
+				return 0;
 			} else {
 				u32 bcount =
 				    0x10000 - (cur_addr & 0xffff);
@@ -484,30 +475,19 @@ sgiioc4_build_dma_table(ide_drive_t * dr
 		return count;
 	}
 
-use_pio_instead:
-	ide_destroy_dmatable(drive);
-
 	return 0;		/* revert to PIO for this request */
 }
 
-static int sgiioc4_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	struct request *rq = drive->hwif->rq;
-	unsigned int count = 0;
 	int ddir;
+	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
 
-	if (rq_data_dir(rq))
-		ddir = PCI_DMA_TODEVICE;
-	else
-		ddir = PCI_DMA_FROMDEVICE;
-
-	if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
+	if (sgiioc4_build_dmatable(drive, cmd) == 0)
 		/* try PIO instead of DMA */
-		ide_map_sg(drive, rq);
 		return 1;
-	}
 
-	if (rq_data_dir(rq))
+	if (write)
 		/* Writes TO the IOC4 FROM Main Memory */
 		ddir = IOC4_DMA_READ;
 	else
@@ -523,9 +503,9 @@ static const struct ide_tp_ops sgiioc4_t
 	.exec_command		= ide_exec_command,
 	.read_status		= sgiioc4_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -546,7 +526,6 @@ static const struct ide_dma_ops sgiioc4_
 	.dma_end		= sgiioc4_dma_end,
 	.dma_test_irq		= sgiioc4_dma_test_irq,
 	.dma_lost_irq		= sgiioc4_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
 };
 
 static const struct ide_port_info sgiioc4_port_info __devinitconst = {
@@ -557,6 +536,7 @@ static const struct ide_port_info sgiioc
 	.port_ops		= &sgiioc4_port_ops,
 	.dma_ops		= &sgiioc4_dma_ops,
 	.host_flags		= IDE_HFLAG_MMIO,
+	.irq_flags		= IRQF_SHARED,
 	.mwdma_mask		= ATA_MWDMA2_ONLY,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/siimage.c linux-libre-2.6.30-gnu1/drivers/ide/siimage.c
--- linux-libre-2.6.29-gnu1/drivers/ide/siimage.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/siimage.c	2009-06-09 23:05:27.000000000 -0400
@@ -464,7 +464,7 @@ static void sil_sata_pre_reset(ide_drive
  *	to 133 MHz clocking if the system isn't already set up to do it.
  */
 
-static unsigned int init_chipset_siimage(struct pci_dev *dev)
+static int init_chipset_siimage(struct pci_dev *dev)
 {
 	struct ide_host *host = pci_get_drvdata(dev);
 	void __iomem *ioaddr = host->host_priv;
@@ -711,11 +711,10 @@ static const struct ide_port_ops sil_sat
 static const struct ide_dma_ops sil_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= siimage_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_lost_irq		= ide_dma_lost_irq,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/sis5513.c linux-libre-2.6.30-gnu1/drivers/ide/sis5513.c
--- linux-libre-2.6.29-gnu1/drivers/ide/sis5513.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/sis5513.c	2009-06-09 23:05:27.000000000 -0400
@@ -447,7 +447,7 @@ static int __devinit sis_find_family(str
 	return chipset_family;
 }
 
-static unsigned int init_chipset_sis5513(struct pci_dev *dev)
+static int init_chipset_sis5513(struct pci_dev *dev)
 {
 	/* Make general config ops here
 	   1/ tell IDE channels to operate in Compatibility mode only
@@ -563,7 +563,7 @@ static const struct ide_port_info sis551
 	.name		= DRV_NAME,
 	.init_chipset	= init_chipset_sis5513,
 	.enablebits	= { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
-	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
+	.host_flags	= IDE_HFLAG_NO_AUTODMA,
 	.pio_mask	= ATA_PIO4,
 	.mwdma_mask	= ATA_MWDMA2,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/sl82c105.c linux-libre-2.6.30-gnu1/drivers/ide/sl82c105.c
--- linux-libre-2.6.29-gnu1/drivers/ide/sl82c105.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/sl82c105.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,8 @@ static unsigned int get_pio_timings(ide_
 	if (cmd_off == 0)
 		cmd_off = 1;
 
-	if (pio > 2 || ata_id_has_iordy(drive->id))
+	if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
+	    !(pio > 4 && ata_id_is_cfa(drive->id)))
 		iordy = 0x40;
 
 	return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
@@ -189,14 +190,13 @@ static void sl82c105_dma_start(ide_drive
 	ide_dma_start(drive);
 }
 
-static void sl82c105_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_clear(ide_drive_t *drive)
 {
 	struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
 
-	DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
+	DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
 
 	sl82c105_reset_host(dev);
-	ide_dma_timeout(drive);
 }
 
 static int sl82c105_dma_end(ide_drive_t *drive)
@@ -271,7 +271,7 @@ static u8 sl82c105_bridge_revision(struc
  * channel 0 here at least, but channel 1 has to be enabled by
  * firmware or arch code. We still set both to 16 bits mode.
  */
-static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
+static int init_chipset_sl82c105(struct pci_dev *dev)
 {
 	u32 val;
 
@@ -281,7 +281,7 @@ static unsigned int init_chipset_sl82c10
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
 
-	return dev->irq;
+	return 0;
 }
 
 static const struct ide_port_ops sl82c105_port_ops = {
@@ -293,12 +293,12 @@ static const struct ide_port_ops sl82c10
 static const struct ide_dma_ops sl82c105_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= sl82c105_dma_start,
 	.dma_end		= sl82c105_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= sl82c105_dma_lost_irq,
-	.dma_timeout		= sl82c105_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
+	.dma_clear		= sl82c105_dma_clear,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/slc90e66.c linux-libre-2.6.30-gnu1/drivers/ide/slc90e66.c
--- linux-libre-2.6.29-gnu1/drivers/ide/slc90e66.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/slc90e66.c	2009-06-09 23:05:27.000000000 -0400
@@ -136,7 +136,6 @@ static const struct ide_port_info slc90e
 	.name		= DRV_NAME,
 	.enablebits	= { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
 	.port_ops	= &slc90e66_port_ops,
-	.host_flags	= IDE_HFLAG_LEGACY_IRQS,
 	.pio_mask	= ATA_PIO4,
 	.swdma_mask	= ATA_SWDMA2_ONLY,
 	.mwdma_mask	= ATA_MWDMA12_ONLY,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/tc86c001.c linux-libre-2.6.30-gnu1/drivers/ide/tc86c001.c
--- linux-libre-2.6.29-gnu1/drivers/ide/tc86c001.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/tc86c001.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,12 +182,11 @@ static const struct ide_port_ops tc86c00
 static const struct ide_dma_ops tc86c001_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= tc86c001_dma_start,
 	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/trm290.c linux-libre-2.6.30-gnu1/drivers/ide/trm290.c
--- linux-libre-2.6.29-gnu1/drivers/ide/trm290.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/trm290.c	2009-06-09 23:05:27.000000000 -0400
@@ -171,58 +171,51 @@ static void trm290_prepare_drive (ide_dr
 	local_irq_restore(flags);
 }
 
-static void trm290_selectproc (ide_drive_t *drive)
+static void trm290_dev_select(ide_drive_t *drive)
 {
 	trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
-}
 
-static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
+	outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
 }
 
-static int trm290_dma_setup(ide_drive_t *drive)
+static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->rq;
-	unsigned int count, rw;
-
-	if (rq_data_dir(rq)) {
+	if (cmd->tf_flags & IDE_TFLAG_WRITE) {
 #ifdef TRM290_NO_DMA_WRITES
 		/* always use PIO for writes */
-		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
 		return 1;
 #endif
-		rw = 1;
-	} else
-		rw = 2;
+	}
+	return 0;
+}
 
-	if (!(count = ide_build_dmatable(drive, rq))) {
+static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
+
+	count = ide_build_dmatable(drive, cmd);
+	if (count == 0)
 		/* try PIO instead of DMA */
-		trm290_prepare_drive(drive, 0); /* select PIO xfer */
 		return 1;
-	}
-	/* select DMA xfer */
-	trm290_prepare_drive(drive, 1);
+
 	outl(hwif->dmatable_dma | rw, hwif->dma_base);
-	drive->waiting_for_dma = 1;
 	/* start DMA */
 	outw(count * 2 - 1, hwif->dma_base + 2);
+
 	return 0;
 }
 
 static void trm290_dma_start(ide_drive_t *drive)
 {
+	trm290_prepare_drive(drive, 1);
 }
 
 static int trm290_dma_end(ide_drive_t *drive)
 {
-	u16 status;
+	u16 status = inw(drive->hwif->dma_base + 2);
 
-	drive->waiting_for_dma = 0;
-	/* purge DMA mappings */
-	ide_destroy_dmatable(drive);
-	status = inw(drive->hwif->dma_base + 2);
+	trm290_prepare_drive(drive, 0);
 
 	return status != 0x00ff;
 }
@@ -277,9 +270,6 @@ static void __devinit init_hwif_trm290(i
 	if (reg & 0x10)
 		/* legacy mode */
 		hwif->irq = hwif->channel ? 15 : 14;
-	else if (!hwif->irq && hwif->mate && hwif->mate->irq)
-		/* sharing IRQ with mate */
-		hwif->irq = hwif->mate->irq;
 
 #if 1
 	{
@@ -310,25 +300,34 @@ static void __devinit init_hwif_trm290(i
 #endif
 }
 
-static const struct ide_port_ops trm290_port_ops = {
-	.selectproc		= trm290_selectproc,
+static const struct ide_tp_ops trm290_tp_ops = {
+	.exec_command		= ide_exec_command,
+	.read_status		= ide_read_status,
+	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
+
+	.dev_select		= trm290_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
+
+	.input_data		= ide_input_data,
+	.output_data		= ide_output_data,
 };
 
 static struct ide_dma_ops trm290_dma_ops = {
 	.dma_host_set		= trm290_dma_host_set,
 	.dma_setup 		= trm290_dma_setup,
-	.dma_exec_cmd		= trm290_dma_exec_cmd,
 	.dma_start 		= trm290_dma_start,
 	.dma_end		= trm290_dma_end,
 	.dma_test_irq		= trm290_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_check		= trm290_dma_check,
 };
 
 static const struct ide_port_info trm290_chipset __devinitdata = {
 	.name		= DRV_NAME,
 	.init_hwif	= init_hwif_trm290,
-	.port_ops	= &trm290_port_ops,
+	.tp_ops 	= &trm290_tp_ops,
 	.dma_ops	= &trm290_dma_ops,
 	.host_flags	= IDE_HFLAG_TRM290 |
 			  IDE_HFLAG_NO_ATAPI_DMA |
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/tx4938ide.c linux-libre-2.6.30-gnu1/drivers/ide/tx4938ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/tx4938ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/tx4938ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+
+#include <asm/ide.h>
 #include <asm/txx9/tx4938.h>
 
 static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
@@ -70,109 +72,7 @@ static void tx4938ide_set_pio_mode(ide_d
 #ifdef __BIG_ENDIAN
 
 /* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4938ide_inb(unsigned long port)
-{
-	return __raw_readb((void __iomem *)port);
-}
-
-static void tx4938ide_outb(u8 value, unsigned long port)
-{
-	__raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
-		u16 data = (tf->hob_data << 8) | tf->data;
-
-		/* no endian swap */
-		__raw_writew(data, (void __iomem *)io_ports->data_addr);
-	}
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		tx4938ide_outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-		tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-		tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-		tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-		tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tx4938ide_outb((tf->device & HIHI) | drive->select,
-			       io_ports->device_addr);
-}
-
-static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data;
-
-		/* no endian swap */
-		data = __raw_readw((void __iomem *)io_ports->data_addr);
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = tx4938ide_inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = tx4938ide_inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = tx4938ide_inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = tx4938ide_inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = tx4938ide_inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = tx4938ide_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature =
-				tx4938ide_inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = tx4938ide_inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = tx4938ide_inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = tx4938ide_inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = tx4938ide_inb(io_ports->lbah_addr);
-	}
-}
-
-static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -184,7 +84,7 @@ static void tx4938ide_input_data_swap(id
 	__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
 }
 
-static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -202,11 +102,11 @@ static const struct ide_tp_ops tx4938ide
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
-	.tf_load		= tx4938ide_tf_load,
-	.tf_read		= tx4938ide_tf_read,
+	.dev_select		= ide_dev_select,
+	.tf_load		= ide_tf_load,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= tx4938ide_input_data_swap,
 	.output_data		= tx4938ide_output_data_swap,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/tx4939ide.c linux-libre-2.6.30-gnu1/drivers/ide/tx4939ide.c
--- linux-libre-2.6.29-gnu1/drivers/ide/tx4939ide.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/tx4939ide.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,8 @@
 #include <linux/io.h>
 #include <linux/scatterlist.h>
 
+#include <asm/ide.h>
+
 #define MODNAME	"tx4939ide"
 
 /* ATA Shadow Registers (8-bit except for Data which is 16-bit) */
@@ -230,7 +232,7 @@ static u8 tx4939ide_clear_dma_status(voi
 
 #ifdef __BIG_ENDIAN
 /* custom ide_build_dmatable to handle swapped layout */
-static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u32 *table = (u32 *)hwif->dmatable_cpu;
@@ -238,11 +240,7 @@ static int tx4939ide_build_dmatable(ide_
 	int i;
 	struct scatterlist *sg;
 
-	hwif->sg_nents = ide_build_sglist(drive, rq);
-	if (hwif->sg_nents == 0)
-		return 0;
-
-	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+	for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
 		u32 cur_addr, cur_len, bcount;
 
 		cur_addr = sg_dma_address(sg);
@@ -281,48 +279,36 @@ use_pio_instead:
 	printk(KERN_ERR "%s: %s\n", drive->name,
 		count ? "DMA table too small" : "empty DMA table?");
 
-	ide_destroy_dmatable(drive);
-
 	return 0; /* revert to PIO for this request */
 }
 #else
 #define tx4939ide_build_dmatable	ide_build_dmatable
 #endif
 
-static int tx4939ide_dma_setup(ide_drive_t *drive)
+static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	void __iomem *base = TX4939IDE_BASE(hwif);
-	struct request *rq = hwif->rq;
-	u8 reading;
-	int nent;
-
-	if (rq_data_dir(rq))
-		reading = 0;
-	else
-		reading = ATA_DMA_WR;
+	u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
 
 	/* fall back to PIO! */
-	nent = tx4939ide_build_dmatable(drive, rq);
-	if (!nent) {
-		ide_map_sg(drive, rq);
+	if (tx4939ide_build_dmatable(drive, cmd) == 0)
 		return 1;
-	}
 
 	/* PRD table */
 	tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
 
 	/* specify r/w */
-	tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd);
+	tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd);
 
 	/* clear INTR & ERROR flags */
 	tx4939ide_clear_dma_status(base);
 
-	drive->waiting_for_dma = 1;
-
 	tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
 			 TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
-	tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
+	tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
 	return 0;
 }
 
@@ -333,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t
 	void __iomem *base = TX4939IDE_BASE(hwif);
 	u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
 
-	drive->waiting_for_dma = 0;
-
 	/* get DMA command mode */
 	dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
 	/* stop DMA */
@@ -343,17 +327,15 @@ static int tx4939ide_dma_end(ide_drive_t
 	/* read and clear the INTR & ERROR bits */
 	dma_stat = tx4939ide_clear_dma_status(base);
 
-	/* purge DMA mappings */
-	ide_destroy_dmatable(drive);
-	/* verify good DMA status */
-	wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
 
-	if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
+	/* verify good DMA status */
+	if ((dma_stat & CHECK_DMA_MASK) == 0 &&
 	    (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
 	    (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
 		/* INT_IDE lost... bug? */
 		return 0;
-	return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) !=
+	return ((dma_stat & CHECK_DMA_MASK) !=
 		ATA_DMA_INTR) ? 0x10 | dma_stat : 0;
 }
 
@@ -437,7 +419,7 @@ static int tx4939ide_init_dma(ide_hwif_t
 	return ide_allocate_dma_engine(hwif);
 }
 
-static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	void __iomem *base = TX4939IDE_BASE(hwif);
@@ -447,119 +429,24 @@ static void tx4939ide_tf_load_fixup(ide_
 	 * Fix ATA100 CORE System Control Register. (The write to the
 	 * Device/Head register may write wrong data to the System
 	 * Control Register)
-	 * While Sys_Ctl is written here, selectproc is not needed.
+	 * While Sys_Ctl is written here, dev_select() is not needed.
 	 */
 	tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
 }
 
-#ifdef __BIG_ENDIAN
-
-/* custom iops (independent from SWAP_IO_SPACE) */
-static u8 tx4939ide_inb(unsigned long port)
-{
-	return __raw_readb((void __iomem *)port);
-}
-
-static void tx4939ide_outb(u8 value, unsigned long port)
-{
-	__raw_writeb(value, (void __iomem *)port);
-}
-
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf,
+			      u8 valid)
 {
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-	u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
-
-	if (task->tf_flags & IDE_TFLAG_FLAGGED)
-		HIHI = 0xFF;
-
-	if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
-		u16 data = (tf->hob_data << 8) | tf->data;
-
-		/* no endian swap */
-		__raw_writew(data, (void __iomem *)io_ports->data_addr);
-	}
-
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
-		tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
-		tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
-		tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
-		tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
-		tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
-
-	if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
-		tx4939ide_outb(tf->feature, io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
-		tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
-		tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
-		tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
-		tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
+	ide_tf_load(drive, tf, valid);
 
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) {
-		tx4939ide_outb((tf->device & HIHI) | drive->select,
-			       io_ports->device_addr);
-		tx4939ide_tf_load_fixup(drive, task);
-	}
+	if (valid & IDE_VALID_DEVICE)
+		tx4939ide_tf_load_fixup(drive);
 }
 
-static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct ide_io_ports *io_ports = &hwif->io_ports;
-	struct ide_taskfile *tf = &task->tf;
-
-	if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-		u16 data;
-
-		/* no endian swap */
-		data = __raw_readw((void __iomem *)io_ports->data_addr);
-		tf->data = data & 0xff;
-		tf->hob_data = (data >> 8) & 0xff;
-	}
-
-	/* be sure we're looking at the low order bits */
-	tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
-	if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
-		tf->feature = tx4939ide_inb(io_ports->feature_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-		tf->nsect  = tx4939ide_inb(io_ports->nsect_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-		tf->lbal   = tx4939ide_inb(io_ports->lbal_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-		tf->lbam   = tx4939ide_inb(io_ports->lbam_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-		tf->lbah   = tx4939ide_inb(io_ports->lbah_addr);
-	if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-		tf->device = tx4939ide_inb(io_ports->device_addr);
-
-	if (task->tf_flags & IDE_TFLAG_LBA48) {
-		tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-			tf->hob_feature =
-				tx4939ide_inb(io_ports->feature_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-			tf->hob_nsect   = tx4939ide_inb(io_ports->nsect_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-			tf->hob_lbal    = tx4939ide_inb(io_ports->lbal_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-			tf->hob_lbam    = tx4939ide_inb(io_ports->lbam_addr);
-		if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-			tf->hob_lbah    = tx4939ide_inb(io_ports->lbah_addr);
-	}
-}
+#ifdef __BIG_ENDIAN
 
-static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+/* custom iops (independent from SWAP_IO_SPACE) */
+static void tx4939ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -571,7 +458,7 @@ static void tx4939ide_input_data_swap(id
 	__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
 }
 
-static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4939ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
 				void *buf, unsigned int len)
 {
 	unsigned long port = drive->hwif->io_ports.data_addr;
@@ -589,11 +476,11 @@ static const struct ide_tp_ops tx4939ide
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= tx4939ide_tf_load,
-	.tf_read		= tx4939ide_tf_read,
+	.tf_read		= ide_tf_read,
 
 	.input_data		= tx4939ide_input_data_swap,
 	.output_data		= tx4939ide_output_data_swap,
@@ -601,20 +488,13 @@ static const struct ide_tp_ops tx4939ide
 
 #else	/* __LITTLE_ENDIAN */
 
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
-	ide_tf_load(drive, task);
-	if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
-		tx4939ide_tf_load_fixup(drive, task);
-}
-
 static const struct ide_tp_ops tx4939ide_tp_ops = {
 	.exec_command		= ide_exec_command,
 	.read_status		= ide_read_status,
 	.read_altstatus		= ide_read_altstatus,
+	.write_devctl		= ide_write_devctl,
 
-	.set_irq		= ide_set_irq,
-
+	.dev_select		= ide_dev_select,
 	.tf_load		= tx4939ide_tf_load,
 	.tf_read		= ide_tf_read,
 
@@ -634,12 +514,11 @@ static const struct ide_port_ops tx4939i
 static const struct ide_dma_ops tx4939ide_dma_ops = {
 	.dma_host_set		= tx4939ide_dma_host_set,
 	.dma_setup		= tx4939ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
 	.dma_end		= tx4939ide_dma_end,
 	.dma_test_irq		= tx4939ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= ide_dma_timeout,
+	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
 	.dma_sff_read_status	= tx4939ide_dma_sff_read_status,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ide/via82cxxx.c linux-libre-2.6.30-gnu1/drivers/ide/via82cxxx.c
--- linux-libre-2.6.29-gnu1/drivers/ide/via82cxxx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ide/via82cxxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,6 +67,7 @@ static struct via_isa_bridge {
 	u8 udma_mask;
 	u8 flags;
 } via_isa_bridges[] = {
+	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "cx700",	PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
 	{ "vt8237s",	PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -267,7 +268,7 @@ static void via_cable_detect(struct via8
  *	and initialize its drive independent registers.
  */
 
-static unsigned int init_chipset_via82cxxx(struct pci_dev *dev)
+static int init_chipset_via82cxxx(struct pci_dev *dev)
 {
 	struct ide_host *host = pci_get_drvdata(dev);
 	struct via82cxxx_dev *vdev = host->host_priv;
@@ -443,16 +444,6 @@ static int __devinit via_init_one(struct
 	if ((via_config->flags & VIA_NO_UNMASK) == 0)
 		d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
 
-#ifdef CONFIG_PPC_CHRP
-	if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
-		d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
-#ifdef CONFIG_AMIGAONE
-	if (machine_is(amigaone))
-		d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
 	d.udma_mask = via_config->udma_mask;
 
 	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
@@ -484,6 +475,7 @@ static const struct pci_device_id via_pc
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1),  0 },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1),  0 },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
+	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), 0 },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410),      1 },
 	{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
 	{ 0, },
diff -druNp linux-libre-2.6.29-gnu1/drivers/idle/i7300_idle.c linux-libre-2.6.30-gnu1/drivers/idle/i7300_idle.c
--- linux-libre-2.6.29-gnu1/drivers/idle/i7300_idle.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/idle/i7300_idle.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,10 @@ static int debug;
 module_param_named(debug, debug, uint, 0644);
 MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
 
+static int forceload;
+module_param_named(forceload, forceload, uint, 0644);
+MODULE_PARM_DESC(debug, "Enable driver testing on unvalidated i5000");
+
 #define dprintk(fmt, arg...) \
 	do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0)
 
@@ -178,7 +182,7 @@ static int __init i7300_idle_ioat_selfte
 
 static struct device dummy_dma_dev = {
 	.init_name = "fallback device",
-	.coherent_dma_mask = DMA_64BIT_MASK,
+	.coherent_dma_mask = DMA_BIT_MASK(64),
 	.dma_mask = &dummy_dma_dev.coherent_dma_mask,
 };
 
@@ -552,7 +556,7 @@ static int __init i7300_idle_init(void)
 	cpus_clear(idle_cpumask);
 	total_us = 0;
 
-	if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev))
+	if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload))
 		return -ENODEV;
 
 	if (i7300_idle_thrt_save())
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/csr.c linux-libre-2.6.30-gnu1/drivers/ieee1394/csr.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/csr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/csr.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,22 +68,22 @@ static struct hpsb_highlevel csr_highlev
 	.host_reset =	host_reset,
 };
 
-const static struct hpsb_address_ops map_ops = {
+static const struct hpsb_address_ops map_ops = {
 	.read = read_maps,
 };
 
-const static struct hpsb_address_ops fcp_ops = {
+static const struct hpsb_address_ops fcp_ops = {
 	.write = write_fcp,
 };
 
-const static struct hpsb_address_ops reg_ops = {
+static const struct hpsb_address_ops reg_ops = {
 	.read = read_regs,
 	.write = write_regs,
 	.lock = lock_regs,
 	.lock64 = lock64_regs,
 };
 
-const static struct hpsb_address_ops config_rom_ops = {
+static const struct hpsb_address_ops config_rom_ops = {
 	.read = read_config_rom,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/dv1394.c linux-libre-2.6.30-gnu1/drivers/ieee1394/dv1394.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/dv1394.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/dv1394.c	2009-06-09 23:05:27.000000000 -0400
@@ -1325,11 +1325,7 @@ static int dv1394_fasync(int fd, struct
 
 	struct video_card *video = file_to_video_card(file);
 
-	int retval = fasync_helper(fd, file, on, &video->fasync);
-
-	if (retval < 0)
-		return retval;
-        return 0;
+	return fasync_helper(fd, file, on, &video->fasync);
 }
 
 static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -2175,7 +2171,7 @@ static const struct file_operations dv13
  * Export information about protocols/devices supported by this driver.
  */
 #ifdef MODULE
-static struct ieee1394_device_id dv1394_id_table[] = {
+static const struct ieee1394_device_id dv1394_id_table[] = {
 	{
 		.match_flags	= IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/eth1394.c linux-libre-2.6.30-gnu1/drivers/ieee1394/eth1394.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/eth1394.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/eth1394.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,7 +181,7 @@ static void ether1394_remove_host(struct
 static void ether1394_host_reset(struct hpsb_host *host);
 
 /* Function for incoming 1394 packets */
-const static struct hpsb_address_ops addr_ops = {
+static const struct hpsb_address_ops addr_ops = {
 	.write =	ether1394_write,
 };
 
@@ -438,7 +438,7 @@ static int eth1394_update(struct unit_di
 	return eth1394_new_node(hi, ud);
 }
 
-static struct ieee1394_device_id eth1394_id_table[] = {
+static const struct ieee1394_device_id eth1394_id_table[] = {
 	{
 		.match_flags = (IEEE1394_MATCH_SPECIFIER_ID |
 				IEEE1394_MATCH_VERSION),
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/highlevel.c linux-libre-2.6.30-gnu1/drivers/ieee1394/highlevel.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/highlevel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/highlevel.c	2009-06-09 23:05:27.000000000 -0400
@@ -478,7 +478,7 @@ int hpsb_unregister_addrspace(struct hps
 	return retval;
 }
 
-const static struct hpsb_address_ops dummy_ops;
+static const struct hpsb_address_ops dummy_ops;
 
 /* dummy address spaces as lower and upper bounds of the host's a.s. list */
 static void init_hpsb_highlevel(struct hpsb_host *host)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/nodemgr.c linux-libre-2.6.30-gnu1/drivers/ieee1394/nodemgr.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/nodemgr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/nodemgr.c	2009-06-09 23:05:27.000000000 -0400
@@ -484,7 +484,7 @@ static struct device_attribute *const fw
 static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
 {
 	struct hpsb_protocol_driver *driver;
-	struct ieee1394_device_id *id;
+	const struct ieee1394_device_id *id;
 	int length = 0;
 	char *scratch = buf;
 
@@ -658,7 +658,7 @@ static int nodemgr_bus_match(struct devi
 {
 	struct hpsb_protocol_driver *driver;
 	struct unit_directory *ud;
-	struct ieee1394_device_id *id;
+	const struct ieee1394_device_id *id;
 
 	/* We only match unit directories */
 	if (dev->platform_data != &nodemgr_ud_platform_data)
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/nodemgr.h linux-libre-2.6.30-gnu1/drivers/ieee1394/nodemgr.h
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/nodemgr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/nodemgr.h	2009-06-09 23:05:27.000000000 -0400
@@ -125,7 +125,7 @@ struct hpsb_protocol_driver {
 	 * probe function below can implement further protocol
 	 * dependent or vendor dependent checking.
 	 */
-	struct ieee1394_device_id *id_table;
+	const struct ieee1394_device_id *id_table;
 
 	/*
 	 * The update function is called when the node has just
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/pcilynx.c linux-libre-2.6.30-gnu1/drivers/ieee1394/pcilynx.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/pcilynx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/pcilynx.c	2009-06-09 23:05:27.000000000 -0400
@@ -1171,7 +1171,7 @@ static int __devinit add_card(struct pci
 
         error = -ENXIO;
 
-        if (pci_set_dma_mask(dev, DMA_32BIT_MASK))
+        if (pci_set_dma_mask(dev, DMA_BIT_MASK(32)))
                 FAIL("DMA address limits not supported for PCILynx hardware");
         if (pci_enable_device(dev))
                 FAIL("failed to enable PCILynx hardware");
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/raw1394.c linux-libre-2.6.30-gnu1/drivers/ieee1394/raw1394.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/raw1394.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/raw1394.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,7 @@ static int arm_lock(struct hpsb_host *ho
 static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
 		      u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
 		      u16 flags);
-const static struct hpsb_address_ops arm_ops = {
+static const struct hpsb_address_ops arm_ops = {
 	.read = arm_read,
 	.write = arm_write,
 	.lock = arm_lock,
@@ -369,6 +369,7 @@ static const char __user *raw1394_compat
 {
 	struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
 	struct raw1394_request __user *r;
+
 	r = compat_alloc_user_space(sizeof(struct raw1394_request));
 
 #define C(x) __copy_in_user(&r->x, &cr->x, sizeof(r->x))
@@ -378,7 +379,8 @@ static const char __user *raw1394_compat
 	    C(tag) ||
 	    C(sendb) ||
 	    C(recvb))
-		return ERR_PTR(-EFAULT);
+		return (__force const char __user *)ERR_PTR(-EFAULT);
+
 	return (const char __user *)r;
 }
 #undef C
@@ -389,6 +391,7 @@ static int
 raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
 {
 	struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
+
 	if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) ||
 	    P(type) ||
 	    P(error) ||
@@ -400,6 +403,7 @@ raw1394_compat_read(const char __user *b
 	    P(sendb) ||
 	    P(recvb))
 		return -EFAULT;
+
 	return sizeof(struct compat_raw1394_req);
 }
 #undef P
@@ -2249,8 +2253,8 @@ static ssize_t raw1394_write(struct file
    	    sizeof(struct compat_raw1394_req) !=
 			sizeof(struct raw1394_request)) {
 		buffer = raw1394_compat_write(buffer);
-		if (IS_ERR(buffer))
-			return PTR_ERR(buffer);
+		if (IS_ERR((__force void *)buffer))
+			return PTR_ERR((__force void *)buffer);
 	} else
 #endif
 	if (count != sizeof(struct raw1394_request)) {
@@ -2978,7 +2982,7 @@ static int raw1394_release(struct inode
  * Export information about protocols/devices supported by this driver.
  */
 #ifdef MODULE
-static struct ieee1394_device_id raw1394_id_table[] = {
+static const struct ieee1394_device_id raw1394_id_table[] = {
 	{
 	 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
 	 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/sbp2.c linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/sbp2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.c	2009-06-09 23:05:27.000000000 -0400
@@ -265,7 +265,7 @@ static struct hpsb_highlevel sbp2_highle
 	.host_reset	= sbp2_host_reset,
 };
 
-const static struct hpsb_address_ops sbp2_ops = {
+static const struct hpsb_address_ops sbp2_ops = {
 	.write		= sbp2_handle_status_write
 };
 
@@ -275,7 +275,7 @@ static int sbp2_handle_physdma_write(str
 static int sbp2_handle_physdma_read(struct hpsb_host *, int, quadlet_t *, u64,
 				    size_t, u16);
 
-const static struct hpsb_address_ops sbp2_physdma_ops = {
+static const struct hpsb_address_ops sbp2_physdma_ops = {
 	.read		= sbp2_handle_physdma_read,
 	.write		= sbp2_handle_physdma_write,
 };
@@ -285,7 +285,7 @@ const static struct hpsb_address_ops sbp
 /*
  * Interface to driver core and IEEE 1394 core
  */
-static struct ieee1394_device_id sbp2_id_table[] = {
+static const struct ieee1394_device_id sbp2_id_table[] = {
 	{
 	 .match_flags	= IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
 	 .specifier_id	= SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
@@ -1413,8 +1413,7 @@ static void sbp2_parse_unit_directory(st
 			  "(firmware_revision 0x%06x, vendor_id 0x%06x,"
 			  " model_id 0x%06x)",
 			  NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
-			  workarounds, firmware_revision,
-			  ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id,
+			  workarounds, firmware_revision, ud->vendor_id,
 			  model);
 
 	/* We would need one SCSI host template for each target to adjust
diff -druNp linux-libre-2.6.29-gnu1/drivers/ieee1394/video1394.c linux-libre-2.6.30-gnu1/drivers/ieee1394/video1394.c
--- linux-libre-2.6.29-gnu1/drivers/ieee1394/video1394.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ieee1394/video1394.c	2009-06-09 23:05:27.000000000 -0400
@@ -1294,7 +1294,7 @@ static const struct file_operations vide
  * Export information about protocols/devices supported by this driver.
  */
 #ifdef MODULE
-static struct ieee1394_device_id video1394_id_table[] = {
+static const struct ieee1394_device_id video1394_id_table[] = {
 	{
 		.match_flags	= IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
 		.specifier_id	= CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/cma.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/cma.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/cma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/cma.c	2009-06-09 23:05:27.000000000 -0400
@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct r
 	id_priv->cma_dev = NULL;
 }
 
-static int cma_set_qkey(struct ib_device *device, u8 port_num,
-			enum rdma_port_space ps,
-			struct rdma_dev_addr *dev_addr, u32 *qkey)
+static int cma_set_qkey(struct rdma_id_private *id_priv)
 {
 	struct ib_sa_mcmember_rec rec;
 	int ret = 0;
 
-	switch (ps) {
+	if (id_priv->qkey)
+		return 0;
+
+	switch (id_priv->id.ps) {
 	case RDMA_PS_UDP:
-		*qkey = RDMA_UDP_QKEY;
+		id_priv->qkey = RDMA_UDP_QKEY;
 		break;
 	case RDMA_PS_IPOIB:
-		ib_addr_get_mgid(dev_addr, &rec.mgid);
-		ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
-		*qkey = be32_to_cpu(rec.qkey);
+		ib_addr_get_mgid(&id_priv->id.route.addr.dev_addr, &rec.mgid);
+		ret = ib_sa_get_mcmember_rec(id_priv->id.device,
+					     id_priv->id.port_num, &rec.mgid,
+					     &rec);
+		if (!ret)
+			id_priv->qkey = be32_to_cpu(rec.qkey);
 		break;
 	default:
 		break;
@@ -341,12 +345,7 @@ static int cma_acquire_dev(struct rdma_i
 		ret = ib_find_cached_gid(cma_dev->device, &gid,
 					 &id_priv->id.port_num, NULL);
 		if (!ret) {
-			ret = cma_set_qkey(cma_dev->device,
-					   id_priv->id.port_num,
-					   id_priv->id.ps, dev_addr,
-					   &id_priv->qkey);
-			if (!ret)
-				cma_attach_to_dev(id_priv, cma_dev);
+			cma_attach_to_dev(id_priv, cma_dev);
 			break;
 		}
 	}
@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rd
 	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
 	if (cma_is_ud_ps(id_priv->id.ps)) {
+		ret = cma_set_qkey(id_priv);
+		if (ret)
+			return ret;
+
 		qp_attr->qkey = id_priv->qkey;
 		*qp_attr_mask |= IB_QP_QKEY;
 	} else {
@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct i
 			event.status = ib_event->param.sidr_rep_rcvd.status;
 			break;
 		}
+		ret = cma_set_qkey(id_priv);
+		if (ret) {
+			event.event = RDMA_CM_EVENT_ADDR_ERROR;
+			event.status = -EINVAL;
+			break;
+		}
 		if (id_priv->qkey != rep->qkey) {
 			event.event = RDMA_CM_EVENT_UNREACHABLE;
 			event.status = -EINVAL;
@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma
 			     const void *private_data, int private_data_len)
 {
 	struct ib_cm_sidr_rep_param rep;
+	int ret;
 
 	memset(&rep, 0, sizeof rep);
 	rep.status = status;
 	if (status == IB_SIDR_SUCCESS) {
+		ret = cma_set_qkey(id_priv);
+		if (ret)
+			return ret;
 		rep.qp_num = id_priv->qp_num;
 		rep.qkey = id_priv->qkey;
 	}
@@ -2713,6 +2726,10 @@ static int cma_join_ib_multicast(struct
 		    IB_SA_MCMEMBER_REC_FLOW_LABEL |
 		    IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
 
+	if (id_priv->id.ps == RDMA_PS_IPOIB)
+		comp_mask |= IB_SA_MCMEMBER_REC_RATE |
+			     IB_SA_MCMEMBER_REC_RATE_SELECTOR;
+
 	mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
 						id_priv->id.port_num, &rec,
 						comp_mask, GFP_KERNEL,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/cm.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/cm.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/cm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/cm.c	2009-06-09 23:05:27.000000000 -0400
@@ -927,8 +927,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 	unsigned long flags;
 	int ret = 0;
 
-	service_mask = service_mask ? service_mask :
-		       __constant_cpu_to_be64(~0ULL);
+	service_mask = service_mask ? service_mask : ~cpu_to_be64(0);
 	service_id &= service_mask;
 	if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
 	    (service_id != IB_CM_ASSIGN_SERVICE_ID))
@@ -954,7 +953,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 	spin_lock_irqsave(&cm.lock, flags);
 	if (service_id == IB_CM_ASSIGN_SERVICE_ID) {
 		cm_id->service_id = cpu_to_be64(cm.listen_service_id++);
-		cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+		cm_id->service_mask = ~cpu_to_be64(0);
 	} else {
 		cm_id->service_id = service_id;
 		cm_id->service_mask = service_mask;
@@ -1134,7 +1133,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
 			goto error1;
 	}
 	cm_id->service_id = param->service_id;
-	cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+	cm_id->service_mask = ~cpu_to_be64(0);
 	cm_id_priv->timeout_ms = cm_convert_to_ms(
 				    param->primary_path->packet_life_time) * 2 +
 				 cm_convert_to_ms(
@@ -1545,7 +1544,7 @@ static int cm_req_handler(struct cm_work
 	cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
 	cm_id_priv->id.context = listen_cm_id_priv->id.context;
 	cm_id_priv->id.service_id = req_msg->service_id;
-	cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+	cm_id_priv->id.service_mask = ~cpu_to_be64(0);
 
 	cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
 	cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
@@ -2898,7 +2897,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id
 		goto out;
 
 	cm_id->service_id = param->service_id;
-	cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+	cm_id->service_mask = ~cpu_to_be64(0);
 	cm_id_priv->timeout_ms = param->timeout_ms;
 	cm_id_priv->max_cm_retries = param->max_cm_retries;
 	ret = cm_alloc_msg(cm_id_priv, &msg);
@@ -2992,7 +2991,7 @@ static int cm_sidr_req_handler(struct cm
 	cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
 	cm_id_priv->id.context = cur_cm_id_priv->id.context;
 	cm_id_priv->id.service_id = sidr_req_msg->service_id;
-	cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+	cm_id_priv->id.service_mask = ~cpu_to_be64(0);
 
 	cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
 	cm_process_work(cm_id_priv, work);
@@ -3789,7 +3788,7 @@ static int __init ib_cm_init(void)
 	rwlock_init(&cm.device_lock);
 	spin_lock_init(&cm.lock);
 	cm.listen_service_table = RB_ROOT;
-	cm.listen_service_id = __constant_be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+	cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
 	cm.remote_id_table = RB_ROOT;
 	cm.remote_qp_table = RB_ROOT;
 	cm.remote_sidr_table = RB_ROOT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/cm_msgs.h linux-libre-2.6.30-gnu1/drivers/infiniband/core/cm_msgs.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/cm_msgs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/cm_msgs.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,17 +44,17 @@
 
 #define IB_CM_CLASS_VERSION	2 /* IB specification 1.2 */
 
-#define CM_REQ_ATTR_ID	    __constant_htons(0x0010)
-#define CM_MRA_ATTR_ID	    __constant_htons(0x0011)
-#define CM_REJ_ATTR_ID	    __constant_htons(0x0012)
-#define CM_REP_ATTR_ID	    __constant_htons(0x0013)
-#define CM_RTU_ATTR_ID	    __constant_htons(0x0014)
-#define CM_DREQ_ATTR_ID	    __constant_htons(0x0015)
-#define CM_DREP_ATTR_ID	    __constant_htons(0x0016)
-#define CM_SIDR_REQ_ATTR_ID __constant_htons(0x0017)
-#define CM_SIDR_REP_ATTR_ID __constant_htons(0x0018)
-#define CM_LAP_ATTR_ID      __constant_htons(0x0019)
-#define CM_APR_ATTR_ID      __constant_htons(0x001A)
+#define CM_REQ_ATTR_ID		cpu_to_be16(0x0010)
+#define CM_MRA_ATTR_ID		cpu_to_be16(0x0011)
+#define CM_REJ_ATTR_ID		cpu_to_be16(0x0012)
+#define CM_REP_ATTR_ID		cpu_to_be16(0x0013)
+#define CM_RTU_ATTR_ID		cpu_to_be16(0x0014)
+#define CM_DREQ_ATTR_ID		cpu_to_be16(0x0015)
+#define CM_DREP_ATTR_ID		cpu_to_be16(0x0016)
+#define CM_SIDR_REQ_ATTR_ID	cpu_to_be16(0x0017)
+#define CM_SIDR_REP_ATTR_ID	cpu_to_be16(0x0018)
+#define CM_LAP_ATTR_ID		cpu_to_be16(0x0019)
+#define CM_APR_ATTR_ID		cpu_to_be16(0x001A)
 
 enum cm_msg_sequence {
 	CM_MSG_SEQUENCE_REQ,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/device.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/device.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/device.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ void ib_dealloc_device(struct ib_device
 
 	BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
 
-	ib_device_unregister_sysfs(device);
+	kobject_put(&device->dev.kobj);
 }
 EXPORT_SYMBOL(ib_dealloc_device);
 
@@ -348,6 +348,8 @@ void ib_unregister_device(struct ib_devi
 
 	mutex_unlock(&device_mutex);
 
+	ib_device_unregister_sysfs(device);
+
 	spin_lock_irqsave(&device->client_data_lock, flags);
 	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
 		kfree(context);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/mad.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/mad.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/mad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/mad.c	2009-06-09 23:05:27.000000000 -0400
@@ -301,6 +301,16 @@ struct ib_mad_agent *ib_register_mad_age
 	mad_agent_priv->agent.context = context;
 	mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
 	mad_agent_priv->agent.port_num = port_num;
+	spin_lock_init(&mad_agent_priv->lock);
+	INIT_LIST_HEAD(&mad_agent_priv->send_list);
+	INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+	INIT_LIST_HEAD(&mad_agent_priv->done_list);
+	INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
+	INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
+	INIT_LIST_HEAD(&mad_agent_priv->local_list);
+	INIT_WORK(&mad_agent_priv->local_work, local_completions);
+	atomic_set(&mad_agent_priv->refcount, 1);
+	init_completion(&mad_agent_priv->comp);
 
 	spin_lock_irqsave(&port_priv->reg_lock, flags);
 	mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
@@ -350,17 +360,6 @@ struct ib_mad_agent *ib_register_mad_age
 	list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 
-	spin_lock_init(&mad_agent_priv->lock);
-	INIT_LIST_HEAD(&mad_agent_priv->send_list);
-	INIT_LIST_HEAD(&mad_agent_priv->wait_list);
-	INIT_LIST_HEAD(&mad_agent_priv->done_list);
-	INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
-	INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
-	INIT_LIST_HEAD(&mad_agent_priv->local_list);
-	INIT_WORK(&mad_agent_priv->local_work, local_completions);
-	atomic_set(&mad_agent_priv->refcount, 1);
-	init_completion(&mad_agent_priv->comp);
-
 	return &mad_agent_priv->agent;
 
 error4:
@@ -743,9 +742,7 @@ static int handle_outgoing_dr_smp(struct
 		break;
 	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
 		kmem_cache_free(ib_mad_cache, mad_priv);
-		kfree(local);
-		ret = 1;
-		goto out;
+		break;
 	case IB_MAD_RESULT_SUCCESS:
 		/* Treat like an incoming receive MAD */
 		port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
@@ -756,10 +753,12 @@ static int handle_outgoing_dr_smp(struct
 						        &mad_priv->mad.mad);
 		}
 		if (!port_priv || !recv_mad_agent) {
+			/*
+			 * No receiving agent so drop packet and
+			 * generate send completion.
+			 */
 			kmem_cache_free(ib_mad_cache, mad_priv);
-			kfree(local);
-			ret = 0;
-			goto out;
+			break;
 		}
 		local->mad_priv = mad_priv;
 		local->recv_mad_agent = recv_mad_agent;
@@ -2356,7 +2355,7 @@ static void local_completions(struct wor
 	struct ib_mad_local_private *local;
 	struct ib_mad_agent_private *recv_mad_agent;
 	unsigned long flags;
-	int recv = 0;
+	int free_mad;
 	struct ib_wc wc;
 	struct ib_mad_send_wc mad_send_wc;
 
@@ -2370,14 +2369,15 @@ static void local_completions(struct wor
 				   completion_list);
 		list_del(&local->completion_list);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		free_mad = 0;
 		if (local->mad_priv) {
 			recv_mad_agent = local->recv_mad_agent;
 			if (!recv_mad_agent) {
 				printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
+				free_mad = 1;
 				goto local_send_completion;
 			}
 
-			recv = 1;
 			/*
 			 * Defined behavior is to complete response
 			 * before request
@@ -2422,7 +2422,7 @@ local_send_completion:
 
 		spin_lock_irqsave(&mad_agent_priv->lock, flags);
 		atomic_dec(&mad_agent_priv->refcount);
-		if (!recv)
+		if (free_mad)
 			kmem_cache_free(ib_mad_cache, local->mad_priv);
 		kfree(local);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/mad_rmpp.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/mad_rmpp.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/mad_rmpp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/mad_rmpp.c	2009-06-09 23:05:27.000000000 -0400
@@ -735,7 +735,7 @@ process_rmpp_data(struct ib_mad_agent_pr
 		goto bad;
 	}
 
-	if (rmpp_hdr->seg_num == __constant_htonl(1)) {
+	if (rmpp_hdr->seg_num == cpu_to_be32(1)) {
 		if (!(ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST)) {
 			rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG;
 			goto bad;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/sa_query.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/sa_query.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/sa_query.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/sa_query.c	2009-06-09 23:05:27.000000000 -0400
@@ -395,6 +395,8 @@ static void update_sm_ah(struct work_str
 	}
 
 	spin_lock_irq(&port->ah_lock);
+	if (port->sm_ah)
+		kref_put(&port->sm_ah->ref, free_sm_ah);
 	port->sm_ah = new_ah;
 	spin_unlock_irq(&port->ah_lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/core/sysfs.c linux-libre-2.6.30-gnu1/drivers/infiniband/core/sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/core/sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/core/sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -66,11 +66,6 @@ struct port_table_attribute {
 	int			index;
 };
 
-static inline int ibdev_is_alive(const struct ib_device *dev)
-{
-	return dev->reg_state == IB_DEV_REGISTERED;
-}
-
 static ssize_t port_attr_show(struct kobject *kobj,
 			      struct attribute *attr, char *buf)
 {
@@ -80,8 +75,6 @@ static ssize_t port_attr_show(struct kob
 
 	if (!port_attr->show)
 		return -EIO;
-	if (!ibdev_is_alive(p->ibdev))
-		return -ENODEV;
 
 	return port_attr->show(p, port_attr, buf);
 }
@@ -562,9 +555,6 @@ static ssize_t show_node_type(struct dev
 {
 	struct ib_device *dev = container_of(device, struct ib_device, dev);
 
-	if (!ibdev_is_alive(dev))
-		return -ENODEV;
-
 	switch (dev->node_type) {
 	case RDMA_NODE_IB_CA:	  return sprintf(buf, "%d: CA\n", dev->node_type);
 	case RDMA_NODE_RNIC:	  return sprintf(buf, "%d: RNIC\n", dev->node_type);
@@ -581,9 +571,6 @@ static ssize_t show_sys_image_guid(struc
 	struct ib_device_attr attr;
 	ssize_t ret;
 
-	if (!ibdev_is_alive(dev))
-		return -ENODEV;
-
 	ret = ib_query_device(dev, &attr);
 	if (ret)
 		return ret;
@@ -600,9 +587,6 @@ static ssize_t show_node_guid(struct dev
 {
 	struct ib_device *dev = container_of(device, struct ib_device, dev);
 
-	if (!ibdev_is_alive(dev))
-		return -ENODEV;
-
 	return sprintf(buf, "%04x:%04x:%04x:%04x\n",
 		       be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
 		       be16_to_cpu(((__be16 *) &dev->node_guid)[1]),
@@ -848,6 +832,9 @@ void ib_device_unregister_sysfs(struct i
 	struct kobject *p, *t;
 	struct ib_port *port;
 
+	/* Hold kobject until ib_dealloc_device() */
+	kobject_get(&device->dev.kobj);
+
 	list_for_each_entry_safe(p, t, &device->port_list, entry) {
 		list_del(&p->entry);
 		port = container_of(p, struct ib_port, kobj);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,6 @@ static irqreturn_t c2_interrupt(int irq,
 static void c2_tx_timeout(struct net_device *netdev);
 static int c2_change_mtu(struct net_device *netdev, int new_mtu);
 static void c2_reset(struct c2_port *c2_port);
-static struct net_device_stats *c2_get_stats(struct net_device *netdev);
 
 static struct pci_device_id c2_pci_table[] = {
 	{ PCI_DEVICE(0x18b8, 0xb001) },
@@ -349,7 +348,7 @@ static void c2_tx_clean(struct c2_port *
 					     elem->hw_desc + C2_TXP_ADDR);
 				__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE),
 					     elem->hw_desc + C2_TXP_FLAGS);
-				c2_port->netstats.tx_dropped++;
+				c2_port->netdev->stats.tx_dropped++;
 				break;
 			} else {
 				__raw_writew(0,
@@ -457,7 +456,7 @@ static void c2_rx_error(struct c2_port *
 		     elem->hw_desc + C2_RXP_FLAGS);
 
 	pr_debug("packet dropped\n");
-	c2_port->netstats.rx_dropped++;
+	c2_port->netdev->stats.rx_dropped++;
 }
 
 static void c2_rx_interrupt(struct net_device *netdev)
@@ -532,8 +531,8 @@ static void c2_rx_interrupt(struct net_d
 		netif_rx(skb);
 
 		netdev->last_rx = jiffies;
-		c2_port->netstats.rx_packets++;
-		c2_port->netstats.rx_bytes += buflen;
+		netdev->stats.rx_packets++;
+		netdev->stats.rx_bytes += buflen;
 	}
 
 	/* Save where we left off */
@@ -797,8 +796,8 @@ static int c2_xmit_frame(struct sk_buff
 	__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
 		     elem->hw_desc + C2_TXP_FLAGS);
 
-	c2_port->netstats.tx_packets++;
-	c2_port->netstats.tx_bytes += maplen;
+	netdev->stats.tx_packets++;
+	netdev->stats.tx_bytes += maplen;
 
 	/* Loop thru additional data fragments and queue them */
 	if (skb_shinfo(skb)->nr_frags) {
@@ -823,8 +822,8 @@ static int c2_xmit_frame(struct sk_buff
 			__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
 				     elem->hw_desc + C2_TXP_FLAGS);
 
-			c2_port->netstats.tx_packets++;
-			c2_port->netstats.tx_bytes += maplen;
+			netdev->stats.tx_packets++;
+			netdev->stats.tx_bytes += maplen;
 		}
 	}
 
@@ -845,13 +844,6 @@ static int c2_xmit_frame(struct sk_buff
 	return NETDEV_TX_OK;
 }
 
-static struct net_device_stats *c2_get_stats(struct net_device *netdev)
-{
-	struct c2_port *c2_port = netdev_priv(netdev);
-
-	return &c2_port->netstats;
-}
-
 static void c2_tx_timeout(struct net_device *netdev)
 {
 	struct c2_port *c2_port = netdev_priv(netdev);
@@ -880,6 +872,16 @@ static int c2_change_mtu(struct net_devi
 	return ret;
 }
 
+static const struct net_device_ops c2_netdev = {
+	.ndo_open 		= c2_up,
+	.ndo_stop 		= c2_down,
+	.ndo_start_xmit		= c2_xmit_frame,
+	.ndo_tx_timeout		= c2_tx_timeout,
+	.ndo_change_mtu		= c2_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* Initialize network device */
 static struct net_device *c2_devinit(struct c2_dev *c2dev,
 				     void __iomem * mmio_addr)
@@ -894,12 +896,7 @@ static struct net_device *c2_devinit(str
 
 	SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
 
-	netdev->open = c2_up;
-	netdev->stop = c2_down;
-	netdev->hard_start_xmit = c2_xmit_frame;
-	netdev->get_stats = c2_get_stats;
-	netdev->tx_timeout = c2_tx_timeout;
-	netdev->change_mtu = c2_change_mtu;
+	netdev->netdev_ops = &c2_netdev;
 	netdev->watchdog_timeo = C2_TX_TIMEOUT;
 	netdev->irq = c2dev->pcidev->irq;
 
@@ -992,13 +989,13 @@ static int __devinit c2_probe(struct pci
 	}
 
 	if ((sizeof(dma_addr_t) > 4)) {
-		ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
+		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
 		if (ret < 0) {
 			printk(KERN_ERR PFX "64b DMA configuration failed\n");
 			goto bail2;
 		}
 	} else {
-		ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
+		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
 		if (ret < 0) {
 			printk(KERN_ERR PFX "32b DMA configuration failed\n");
 			goto bail2;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2.h	2009-06-09 23:05:27.000000000 -0400
@@ -369,8 +369,6 @@ struct c2_port {
 	unsigned long mem_size;
 
 	u32 rx_buf_size;
-
-	struct net_device_stats netstats;
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/amso1100/c2_provider.c	2009-06-09 23:05:27.000000000 -0400
@@ -708,26 +708,27 @@ static int c2_pseudo_xmit_frame(struct s
 
 static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
 {
-	int ret = 0;
-
 	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
 
 	netdev->mtu = new_mtu;
 
 	/* TODO: Tell rnic about new rmda interface mtu */
-	return ret;
+	return 0;
 }
 
+static const struct net_device_ops c2_pseudo_netdev_ops = {
+	.ndo_open 		= c2_pseudo_up,
+	.ndo_stop 		= c2_pseudo_down,
+	.ndo_start_xmit 	= c2_pseudo_xmit_frame,
+	.ndo_change_mtu 	= c2_pseudo_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static void setup(struct net_device *netdev)
 {
-	netdev->open = c2_pseudo_up;
-	netdev->stop = c2_pseudo_down;
-	netdev->hard_start_xmit = c2_pseudo_xmit_frame;
-	netdev->get_stats = NULL;
-	netdev->tx_timeout = NULL;
-	netdev->set_mac_address = NULL;
-	netdev->change_mtu = c2_pseudo_change_mtu;
+	netdev->netdev_ops = &c2_pseudo_netdev_ops;
+
 	netdev->watchdog_timeo = 0;
 	netdev->type = ARPHRD_ETHER;
 	netdev->mtu = 1500;
@@ -735,7 +736,6 @@ static void setup(struct net_device *net
 	netdev->addr_len = ETH_ALEN;
 	netdev->tx_queue_len = 0;
 	netdev->flags |= IFF_NOARP;
-	return;
 }
 
 static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct
 	sge_cmd = qpid << 8 | 3;
 	wqe->sge_cmd = cpu_to_be64(sge_cmd);
 	skb->priority = CPL_PRIORITY_CONTROL;
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 }
 
 int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
@@ -410,6 +410,7 @@ int cxio_flush_sq(struct t3_wq *wq, stru
 	ptr = wq->sq_rptr + count;
 	sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
 	while (ptr != wq->sq_wptr) {
+		sqp->signaled = 0;
 		insert_sq_cqe(wq, cq, sqp);
 		ptr++;
 		sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
@@ -450,7 +451,7 @@ static int cqe_completes_wr(struct t3_cq
 	if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe))
 		return 0;
 
-	if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) &&
+	if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) &&
 	    Q_EMPTY(wq->rq_rptr, wq->rq_wptr))
 		return 0;
 
@@ -571,7 +572,7 @@ static int cxio_hal_init_ctrl_qp(struct
 	     (unsigned long long) rdev_p->ctrl_qp.dma_addr,
 	     rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
 	skb->priority = CPL_PRIORITY_CONTROL;
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 err:
 	kfree_skb(skb);
 	return err;
@@ -701,6 +702,9 @@ static int __cxio_tpt_op(struct cxio_rde
 	u32 stag_idx;
 	u32 wptr;
 
+	if (cxio_fatal_error(rdev_p))
+		return -EIO;
+
 	stag_state = stag_state > 0;
 	stag_idx = (*stag) >> 8;
 
@@ -855,7 +859,7 @@ int cxio_rdma_init(struct cxio_rdev *rde
 	wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
 	wqe->irs = cpu_to_be32(attr->irs);
 	skb->priority = 0;	/* 0=>ToeQ; 1=>CtrlQ */
-	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+	return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
 }
 
 void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb)
@@ -938,6 +942,23 @@ int cxio_rdev_open(struct cxio_rdev *rde
 	if (!rdev_p->t3cdev_p)
 		rdev_p->t3cdev_p = dev2t3cdev(netdev_p);
 	rdev_p->t3cdev_p->ulp = (void *) rdev_p;
+
+	err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, GET_EMBEDDED_INFO,
+					 &(rdev_p->fw_info));
+	if (err) {
+		printk(KERN_ERR "%s t3cdev_p(%p)->ctl returned error %d.\n",
+		     __func__, rdev_p->t3cdev_p, err);
+		goto err1;
+	}
+	if (G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers) != CXIO_FW_MAJ) {
+		printk(KERN_ERR MOD "fatal firmware version mismatch: "
+		       "need version %u but adapter has version %u\n",
+		       CXIO_FW_MAJ,
+		       G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers));
+		err = -EINVAL;
+		goto err1;
+	}
+
 	err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS,
 					 &(rdev_p->rnic_info));
 	if (err) {
@@ -1021,9 +1042,9 @@ void cxio_rdev_close(struct cxio_rdev *r
 		cxio_hal_pblpool_destroy(rdev_p);
 		cxio_hal_rqtpool_destroy(rdev_p);
 		list_del(&rdev_p->entry);
-		rdev_p->t3cdev_p->ulp = NULL;
 		cxio_hal_destroy_ctrl_qp(rdev_p);
 		cxio_hal_destroy_resource(rdev_p->rscp);
+		rdev_p->t3cdev_p->ulp = NULL;
 	}
 }
 
@@ -1204,11 +1225,12 @@ int cxio_poll_cq(struct t3_wq *wq, struc
 		}
 
 		/* incoming SEND with no receive posted failures */
-		if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) &&
+		if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) &&
 		    Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
 			ret = -1;
 			goto skip_cqe;
 		}
+		BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe));
 		goto proc_cqe;
 	}
 
@@ -1223,6 +1245,13 @@ int cxio_poll_cq(struct t3_wq *wq, struc
 		 * then we complete this with TPT_ERR_MSN and mark the wq in
 		 * error.
 		 */
+
+		if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
+			wq->error = 1;
+			ret = -1;
+			goto skip_cqe;
+		}
+
 		if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) {
 			wq->error = 1;
 			hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN));
@@ -1277,6 +1306,7 @@ proc_cqe:
 			cxio_hal_pblpool_free(wq->rdev,
 				wq->rq[Q_PTR2IDX(wq->rq_rptr,
 				wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE);
+		BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr));
 		wq->rq_rptr++;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2009-06-09 23:05:27.000000000 -0400
@@ -61,6 +61,8 @@
 
 #define T3_MAX_DEV_NAME_LEN 32
 
+#define CXIO_FW_MAJ 7
+
 struct cxio_hal_ctrl_qp {
 	u32 wptr;
 	u32 rptr;
@@ -108,8 +110,16 @@ struct cxio_rdev {
 	struct gen_pool *pbl_pool;
 	struct gen_pool *rqt_pool;
 	struct list_head entry;
+	struct ch_embedded_info fw_info;
+	u32	flags;
+#define	CXIO_ERROR_FATAL	1
 };
 
+static inline int cxio_fatal_error(struct cxio_rdev *rdev_p)
+{
+	return rdev_p->flags & CXIO_ERROR_FATAL;
+}
+
 static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
 {
 	return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
@@ -183,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq,
 void cxio_flush_hw_cq(struct t3_cq *cq);
 int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
 		     u8 *cqe_flushed, u64 *cookie, u32 *credit);
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb);
 
 #define MOD "iw_cxgb3: "
 #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args)
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/cxio_wr.h	2009-06-09 23:05:27.000000000 -0400
@@ -604,6 +604,12 @@ struct t3_cqe {
 #define CQE_STATUS(x)     (G_CQE_STATUS(be32_to_cpu((x).header)))
 #define CQE_OPCODE(x)     (G_CQE_OPCODE(be32_to_cpu((x).header)))
 
+#define CQE_SEND_OPCODE(x)( \
+	(G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \
+	(G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \
+	(G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \
+	(G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV))
+
 #define CQE_LEN(x)        (be32_to_cpu((x).len))
 
 /* used for RQ completion processing */
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,13 +51,15 @@ cxgb3_cpl_handler_func t3c_handlers[NUM_
 
 static void open_rnic_dev(struct t3cdev *);
 static void close_rnic_dev(struct t3cdev *);
+static void iwch_err_handler(struct t3cdev *, u32, u32);
 
 struct cxgb3_client t3c_client = {
 	.name = "iw_cxgb3",
 	.add = open_rnic_dev,
 	.remove = close_rnic_dev,
 	.handlers = t3c_handlers,
-	.redirect = iwch_ep_redirect
+	.redirect = iwch_ep_redirect,
+	.err_handler = iwch_err_handler
 };
 
 static LIST_HEAD(dev_list);
@@ -160,6 +162,24 @@ static void close_rnic_dev(struct t3cdev
 	mutex_unlock(&dev_mutex);
 }
 
+static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
+{
+	struct cxio_rdev *rdev = tdev->ulp;
+	struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev);
+	struct ib_event event;
+
+	if (status == OFFLOAD_STATUS_DOWN) {
+		rdev->flags = CXIO_ERROR_FATAL;
+
+		event.device = &rnicp->ibdev;
+		event.event  = IB_EVENT_DEVICE_FATAL;
+		event.element.port_num = 0;
+		ib_dispatch_event(&event);
+	}
+
+	return;
+}
+
 static int __init iwch_init_module(void)
 {
 	int err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.c	2009-06-09 23:05:27.000000000 -0400
@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep
 	put_ep(&ep->com);
 }
 
+int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e)
+{
+	int	error = 0;
+	struct cxio_rdev *rdev;
+
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		kfree_skb(skb);
+		return -EIO;
+	}
+	error = l2t_send(tdev, skb, l2e);
+	if (error)
+		kfree_skb(skb);
+	return error;
+}
+
+int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
+{
+	int	error = 0;
+	struct cxio_rdev *rdev;
+
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		kfree_skb(skb);
+		return -EIO;
+	}
+	error = cxgb3_ofld_send(tdev, skb);
+	if (error)
+		kfree_skb(skb);
+	return error;
+}
+
 static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
 {
 	struct cpl_tid_release *req;
@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *t
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
 	skb->priority = CPL_PRIORITY_SETUP;
-	cxgb3_ofld_send(tdev, skb);
+	iwch_cxgb3_ofld_send(tdev, skb);
 	return;
 }
 
@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
 	req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
 
 	skb->priority = CPL_PRIORITY_DATA;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 int iwch_resume_tid(struct iwch_ep *ep)
@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
 	req->val = 0;
 
 	skb->priority = CPL_PRIORITY_DATA;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static void set_emss(struct iwch_ep *ep, u16 opt)
@@ -252,18 +282,22 @@ static void *alloc_ep(int size, gfp_t gf
 
 void __free_ep(struct kref *kref)
 {
-	struct iwch_ep_common *epc;
-	epc = container_of(kref, struct iwch_ep_common, kref);
-	PDBG("%s ep %p state %s\n", __func__, epc, states[state_read(epc)]);
-	kfree(epc);
+	struct iwch_ep *ep;
+	ep = container_of(container_of(kref, struct iwch_ep_common, kref),
+			  struct iwch_ep, com);
+	PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
+	if (ep->com.flags & RELEASE_RESOURCES) {
+		cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
+		dst_release(ep->dst);
+		l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+	}
+	kfree(ep);
 }
 
 static void release_ep_resources(struct iwch_ep *ep)
 {
 	PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid);
-	cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
-	dst_release(ep->dst);
-	l2t_release(L2DATA(ep->com.tdev), ep->l2t);
+	ep->com.flags |= RELEASE_RESOURCES;
 	put_ep(&ep->com);
 }
 
@@ -382,7 +416,7 @@ static void abort_arp_failure(struct t3c
 
 	PDBG("%s t3cdev %p\n", __func__, dev);
 	req->cmd = CPL_ABORT_NO_RST;
-	cxgb3_ofld_send(dev, skb);
+	iwch_cxgb3_ofld_send(dev, skb);
 }
 
 static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
@@ -402,8 +436,7 @@ static int send_halfclose(struct iwch_ep
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
 	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
@@ -424,8 +457,7 @@ static int send_abort(struct iwch_ep *ep
 	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
 	req->cmd = CPL_ABORT_SEND_RST;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_connect(struct iwch_ep *ep)
@@ -469,8 +501,7 @@ static int send_connect(struct iwch_ep *
 	req->opt0l = htonl(opt0l);
 	req->params = 0;
 	req->opt2 = htonl(opt2);
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
@@ -527,7 +558,7 @@ static void send_mpa_req(struct iwch_ep
 	req->sndseq = htonl(ep->snd_seq);
 	BUG_ON(ep->mpa_skb);
 	ep->mpa_skb = skb;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
+	iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 	start_ep_timer(ep);
 	state_set(&ep->com, MPA_REQ_SENT);
 	return;
@@ -578,8 +609,7 @@ static int send_mpa_reject(struct iwch_e
 	req->sndseq = htonl(ep->snd_seq);
 	BUG_ON(ep->mpa_skb);
 	ep->mpa_skb = skb;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
@@ -630,8 +660,7 @@ static int send_mpa_reply(struct iwch_ep
 	req->sndseq = htonl(ep->snd_seq);
 	ep->mpa_skb = skb;
 	state_set(&ep->com, MPA_REP_SENT);
-	l2t_send(ep->com.tdev, skb, ep->l2t);
-	return 0;
+	return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 }
 
 static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -795,7 +824,7 @@ static int update_rx_credits(struct iwch
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
 	req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
 	skb->priority = CPL_PRIORITY_ACK;
-	cxgb3_ofld_send(ep->com.tdev, skb);
+	iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 	return credits;
 }
 
@@ -1127,8 +1156,8 @@ static int abort_rpl(struct t3cdev *tdev
 	 * We get 2 abort replies from the HW.  The first one must
 	 * be ignored except for scribbling that we need one more.
 	 */
-	if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) {
-		ep->flags |= ABORT_REQ_IN_PROGRESS;
+	if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) {
+		ep->com.flags |= ABORT_REQ_IN_PROGRESS;
 		return CPL_RET_BUF_DONE;
 	}
 
@@ -1203,8 +1232,7 @@ static int listen_start(struct iwch_list
 	req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
 
 	skb->priority = 1;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -1237,8 +1265,7 @@ static int listen_stop(struct iwch_liste
 	req->cpu_idx = 0;
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
 	skb->priority = 1;
-	cxgb3_ofld_send(ep->com.tdev, skb);
-	return 0;
+	return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
 }
 
 static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb,
@@ -1286,7 +1313,7 @@ static void accept_cr(struct iwch_ep *ep
 	rpl->opt2 = htonl(opt2);
 	rpl->rsvd = rpl->opt2;	/* workaround for HW bug */
 	skb->priority = CPL_PRIORITY_SETUP;
-	l2t_send(ep->com.tdev, skb, ep->l2t);
+	iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
 
 	return;
 }
@@ -1315,7 +1342,7 @@ static void reject_cr(struct t3cdev *tde
 		rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
 		rpl->opt2 = 0;
 		rpl->rsvd = rpl->opt2;
-		cxgb3_ofld_send(tdev, skb);
+		iwch_cxgb3_ofld_send(tdev, skb);
 	}
 }
 
@@ -1534,8 +1561,8 @@ static int peer_abort(struct t3cdev *tde
 	 * We get 2 peer aborts from the HW.  The first one must
 	 * be ignored except for scribbling that we need one more.
 	 */
-	if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) {
-		ep->flags |= PEER_ABORT_IN_PROGRESS;
+	if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) {
+		ep->com.flags |= PEER_ABORT_IN_PROGRESS;
 		return CPL_RET_BUF_DONE;
 	}
 
@@ -1613,7 +1640,7 @@ static int peer_abort(struct t3cdev *tde
 	rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
 	OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
 	rpl->cmd = CPL_ABORT_NO_RST;
-	cxgb3_ofld_send(ep->com.tdev, rpl_skb);
+	iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb);
 out:
 	if (release)
 		release_ep_resources(ep);
@@ -1678,6 +1705,9 @@ static int terminate(struct t3cdev *tdev
 {
 	struct iwch_ep *ep = ctx;
 
+	if (state_read(&ep->com) != FPDU_MODE)
+		return CPL_RET_BUF_DONE;
+
 	PDBG("%s ep %p\n", __func__, ep);
 	skb_pull(skb, sizeof(struct cpl_rdma_terminate));
 	PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
@@ -1800,6 +1830,10 @@ int iwch_accept_cr(struct iw_cm_id *cm_i
 	ep->com.rpl_err = 0;
 	ep->ird = conn_param->ird;
 	ep->ord = conn_param->ord;
+
+	if (peer2peer && ep->ird == 0)
+		ep->ird = 1;
+
 	PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);
 
 	get_ep(&ep->com);
@@ -1885,6 +1919,10 @@ int iwch_connect(struct iw_cm_id *cm_id,
 		       conn_param->private_data, ep->plen);
 	ep->ird = conn_param->ird;
 	ep->ord = conn_param->ord;
+
+	if (peer2peer && ep->ord == 0)
+		ep->ord = 1;
+
 	ep->com.tdev = h->rdev.t3cdev_p;
 
 	cm_id->add_ref(cm_id);
@@ -2014,8 +2052,11 @@ int iwch_destroy_listen(struct iw_cm_id
 	ep->com.rpl_done = 0;
 	ep->com.rpl_err = 0;
 	err = listen_stop(ep);
+	if (err)
+		goto done;
 	wait_event(ep->com.waitq, ep->com.rpl_done);
 	cxgb3_free_stid(ep->com.tdev, ep->stid);
+done:
 	err = ep->com.rpl_err;
 	cm_id->rem_ref(cm_id);
 	put_ep(&ep->com);
@@ -2027,12 +2068,22 @@ int iwch_ep_disconnect(struct iwch_ep *e
 	int ret=0;
 	unsigned long flags;
 	int close = 0;
+	int fatal = 0;
+	struct t3cdev *tdev;
+	struct cxio_rdev *rdev;
 
 	spin_lock_irqsave(&ep->com.lock, flags);
 
 	PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
 	     states[ep->com.state], abrupt);
 
+	tdev = (struct t3cdev *)ep->com.tdev;
+	rdev = (struct cxio_rdev *)tdev->ulp;
+	if (cxio_fatal_error(rdev)) {
+		fatal = 1;
+		close_complete_upcall(ep);
+		ep->com.state = DEAD;
+	}
 	switch (ep->com.state) {
 	case MPA_REQ_WAIT:
 	case MPA_REQ_SENT:
@@ -2072,7 +2123,11 @@ int iwch_ep_disconnect(struct iwch_ep *e
 			ret = send_abort(ep, NULL, gfp);
 		else
 			ret = send_halfclose(ep, gfp);
+		if (ret)
+			fatal = 1;
 	}
+	if (fatal)
+		release_ep_resources(ep);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_cm.h	2009-06-09 23:05:27.000000000 -0400
@@ -147,6 +147,7 @@ enum iwch_ep_state {
 enum iwch_ep_flags {
 	PEER_ABORT_IN_PROGRESS	= (1 << 0),
 	ABORT_REQ_IN_PROGRESS	= (1 << 1),
+	RELEASE_RESOURCES	= (1 << 2),
 };
 
 struct iwch_ep_common {
@@ -161,6 +162,7 @@ struct iwch_ep_common {
 	wait_queue_head_t waitq;
 	int rpl_done;
 	int rpl_err;
+	u32 flags;
 };
 
 struct iwch_listen_ep {
@@ -188,7 +190,6 @@ struct iwch_ep {
 	u16 plen;
 	u32 ird;
 	u32 ord;
-	u32 flags;
 };
 
 static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_ev.c	2009-06-09 23:05:27.000000000 -0400
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *
 	case TPT_ERR_BOUND:
 	case TPT_ERR_INVALIDATE_SHARED_MR:
 	case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
-		printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x "
-		       "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,
-		       CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
-		       CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
-		       CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
 		(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
 		post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
 		break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch.h	2009-06-09 23:05:27.000000000 -0400
@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_d
 	return container_of(ibdev, struct iwch_dev, ibdev);
 }
 
+static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev)
+{
+	return container_of(rdev, struct iwch_dev, rdev);
+}
+
 static inline int t3b_device(const struct iwch_dev *rhp)
 {
 	return rhp->rdev.t3cdev_p->type == T3B;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/cxgb3/iwch_qp.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,8 +99,8 @@ static int build_rdma_write(union t3_wr
 	if (wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
 		plen = 4;
 		wqe->write.sgl[0].stag = wr->ex.imm_data;
-		wqe->write.sgl[0].len = __constant_cpu_to_be32(0);
-		wqe->write.num_sgle = __constant_cpu_to_be32(0);
+		wqe->write.sgl[0].len = cpu_to_be32(0);
+		wqe->write.num_sgle = cpu_to_be32(0);
 		*flit_cnt = 6;
 	} else {
 		plen = 0;
@@ -195,15 +195,12 @@ static int build_inv_stag(union t3_wr *w
 	return 0;
 }
 
-/*
- * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now.
- */
 static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list,
 			    u32 num_sgle, u32 * pbl_addr, u8 * page_size)
 {
 	int i;
 	struct iwch_mr *mhp;
-	u32 offset;
+	u64 offset;
 	for (i = 0; i < num_sgle; i++) {
 
 		mhp = get_mhp(rhp, (sg_list[i].lkey) >> 8);
@@ -235,8 +232,8 @@ static int iwch_sgl2pbl_map(struct iwch_
 			return -EINVAL;
 		}
 		offset = sg_list[i].addr - mhp->attr.va_fbo;
-		offset += ((u32) mhp->attr.va_fbo) %
-		          (1UL << (12 + mhp->attr.page_size));
+		offset += mhp->attr.va_fbo &
+			  ((1UL << (12 + mhp->attr.page_size)) - 1);
 		pbl_addr[i] = ((mhp->attr.pbl_addr -
 			        rhp->rdev.rnic_info.pbl_base) >> 3) +
 			      (offset >> (12 + mhp->attr.page_size));
@@ -266,8 +263,8 @@ static int build_rdma_recv(struct iwch_q
 		wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length);
 
 		/* to in the WQE == the offset into the page */
-		wqe->recv.sgl[i].to = cpu_to_be64(((u32) wr->sg_list[i].addr) %
-				(1UL << (12 + page_size[i])));
+		wqe->recv.sgl[i].to = cpu_to_be64(((u32)wr->sg_list[i].addr) &
+				((1UL << (12 + page_size[i])) - 1));
 
 		/* pbl_addr is the adapters address in the PBL */
 		wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_addr[i]);
@@ -754,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qh
 	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
 						V_FW_RIWR_LEN(flit_cnt));
 	skb->priority = CPL_PRIORITY_DATA;
-	return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+	return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
 }
 
 /*
@@ -786,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *
 			 V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
 	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
 	skb->priority = CPL_PRIORITY_DATA;
-	return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+	return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
 }
 
 /*
@@ -1072,7 +1069,6 @@ int iwch_modify_qp(struct iwch_dev *rhp,
 			goto out;
 		}
 		qhp->attr.state = IWCH_QP_STATE_IDLE;
-		memset(&qhp->attr, 0, sizeof(qhp->attr));
 		break;
 	case IWCH_QP_STATE_TERMINATE:
 		if (!internal) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ehca/ehca_sqp.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,11 +46,11 @@
 #include "ehca_iverbs.h"
 #include "hcp_if.h"
 
-#define IB_MAD_STATUS_REDIRECT		__constant_htons(0x0002)
-#define IB_MAD_STATUS_UNSUP_VERSION	__constant_htons(0x0004)
-#define IB_MAD_STATUS_UNSUP_METHOD	__constant_htons(0x0008)
+#define IB_MAD_STATUS_REDIRECT		cpu_to_be16(0x0002)
+#define IB_MAD_STATUS_UNSUP_VERSION	cpu_to_be16(0x0004)
+#define IB_MAD_STATUS_UNSUP_METHOD	cpu_to_be16(0x0008)
 
-#define IB_PMA_CLASS_PORT_INFO		__constant_htons(0x0001)
+#define IB_PMA_CLASS_PORT_INFO		cpu_to_be16(0x0001)
 
 /**
  * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -470,14 +470,14 @@ static int __devinit ipath_init_one(stru
 		goto bail_disable;
 	}
 
-	ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (ret) {
 		/*
 		 * if the 64 bit setup fails, try 32 bit.  Some systems
 		 * do not setup 64 bit maps on systems with 2GB or less
 		 * memory installed.
 		 */
-		ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (ret) {
 			dev_info(&pdev->dev,
 				"Unable to set DMA mask for unit %u: %d\n",
@@ -486,7 +486,7 @@ static int __devinit ipath_init_one(stru
 		}
 		else {
 			ipath_dbg("No 64bit DMA mask, used 32 bit mask\n");
-			ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (ret)
 				dev_info(&pdev->dev,
 					"Unable to set DMA consistent mask "
@@ -496,7 +496,7 @@ static int __devinit ipath_init_one(stru
 		}
 	}
 	else {
-		ret = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (ret)
 			dev_info(&pdev->dev,
 				"Unable to set DMA consistent mask "
@@ -2715,7 +2715,7 @@ static void ipath_hol_signal_up(struct i
  * to prevent HoL blocking, then start the HoL timer that
  * periodically continues, then stop procs, so they can detect
  * link down if they want, and do something about it.
- * Timer may already be running, so use __mod_timer, not add_timer.
+ * Timer may already be running, so use mod_timer, not add_timer.
  */
 void ipath_hol_down(struct ipath_devdata *dd)
 {
@@ -2724,7 +2724,7 @@ void ipath_hol_down(struct ipath_devdata
 	dd->ipath_hol_next = IPATH_HOL_DOWNCONT;
 	dd->ipath_hol_timer.expires = jiffies +
 		msecs_to_jiffies(ipath_hol_timeout_ms);
-	__mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
+	mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
 }
 
 /*
@@ -2763,7 +2763,7 @@ void ipath_hol_event(unsigned long opaqu
 	else {
 		dd->ipath_hol_timer.expires = jiffies +
 			msecs_to_jiffies(ipath_hol_timeout_ms);
-		__mod_timer(&dd->ipath_hol_timer,
+		mod_timer(&dd->ipath_hol_timer,
 			dd->ipath_hol_timer.expires);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_eeprom.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_eeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -772,8 +772,8 @@ void ipath_get_eeprom_info(struct ipath_
 			 "0x%x, not 0x%x\n", csum, ifp->if_csum);
 		goto done;
 	}
-	if (*(__be64 *) ifp->if_guid == 0ULL ||
-	    *(__be64 *) ifp->if_guid == __constant_cpu_to_be64(-1LL)) {
+	if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) ||
+	    *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) {
 		ipath_dev_err(dd, "Invalid GUID %llx from flash; "
 			      "ignoring\n",
 			      *(unsigned long long *) ifp->if_guid);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_fs.c	2009-06-09 23:05:27.000000000 -0400
@@ -347,7 +347,7 @@ static int ipathfs_fill_super(struct sup
 		spin_unlock_irqrestore(&ipath_devs_lock, flags);
 		ret = create_device_files(sb, dd);
 		if (ret) {
-			deactivate_super(sb);
+			deactivate_locked_super(sb);
 			goto bail;
 		}
 		spin_lock_irqsave(&ipath_devs_lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_init_chip.c	2009-06-09 23:05:27.000000000 -0400
@@ -455,7 +455,7 @@ static void init_shadow_tids(struct ipat
 	if (!addrs) {
 		ipath_dev_err(dd, "failed to allocate shadow dma handle "
 			      "array, no expected sends!\n");
-		vfree(dd->ipath_pageshadow);
+		vfree(pages);
 		dd->ipath_pageshadow = NULL;
 		return;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_mad.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_mad.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_mad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_mad.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,10 +37,10 @@
 #include "ipath_verbs.h"
 #include "ipath_common.h"
 
-#define IB_SMP_UNSUP_VERSION	__constant_htons(0x0004)
-#define IB_SMP_UNSUP_METHOD	__constant_htons(0x0008)
-#define IB_SMP_UNSUP_METH_ATTR	__constant_htons(0x000C)
-#define IB_SMP_INVALID_FIELD	__constant_htons(0x001C)
+#define IB_SMP_UNSUP_VERSION	cpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD	cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR	cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELD	cpu_to_be16(0x001C)
 
 static int reply(struct ib_smp *smp)
 {
@@ -789,12 +789,12 @@ static int recv_subn_set_pkeytable(struc
 	return recv_subn_get_pkeytable(smp, ibdev);
 }
 
-#define IB_PMA_CLASS_PORT_INFO		__constant_htons(0x0001)
-#define IB_PMA_PORT_SAMPLES_CONTROL	__constant_htons(0x0010)
-#define IB_PMA_PORT_SAMPLES_RESULT	__constant_htons(0x0011)
-#define IB_PMA_PORT_COUNTERS		__constant_htons(0x0012)
-#define IB_PMA_PORT_COUNTERS_EXT	__constant_htons(0x001D)
-#define IB_PMA_PORT_SAMPLES_RESULT_EXT	__constant_htons(0x001E)
+#define IB_PMA_CLASS_PORT_INFO		cpu_to_be16(0x0001)
+#define IB_PMA_PORT_SAMPLES_CONTROL	cpu_to_be16(0x0010)
+#define IB_PMA_PORT_SAMPLES_RESULT	cpu_to_be16(0x0011)
+#define IB_PMA_PORT_COUNTERS		cpu_to_be16(0x0012)
+#define IB_PMA_PORT_COUNTERS_EXT	cpu_to_be16(0x001D)
+#define IB_PMA_PORT_SAMPLES_RESULT_EXT	cpu_to_be16(0x001E)
 
 struct ib_perf {
 	u8 base_version;
@@ -884,19 +884,19 @@ struct ib_pma_portcounters {
 	__be32 port_rcv_packets;
 } __attribute__ ((packed));
 
-#define IB_PMA_SEL_SYMBOL_ERROR			__constant_htons(0x0001)
-#define IB_PMA_SEL_LINK_ERROR_RECOVERY		__constant_htons(0x0002)
-#define IB_PMA_SEL_LINK_DOWNED			__constant_htons(0x0004)
-#define IB_PMA_SEL_PORT_RCV_ERRORS		__constant_htons(0x0008)
-#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS	__constant_htons(0x0010)
-#define IB_PMA_SEL_PORT_XMIT_DISCARDS		__constant_htons(0x0040)
-#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS	__constant_htons(0x0200)
-#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS	__constant_htons(0x0400)
-#define IB_PMA_SEL_PORT_VL15_DROPPED		__constant_htons(0x0800)
-#define IB_PMA_SEL_PORT_XMIT_DATA		__constant_htons(0x1000)
-#define IB_PMA_SEL_PORT_RCV_DATA		__constant_htons(0x2000)
-#define IB_PMA_SEL_PORT_XMIT_PACKETS		__constant_htons(0x4000)
-#define IB_PMA_SEL_PORT_RCV_PACKETS		__constant_htons(0x8000)
+#define IB_PMA_SEL_SYMBOL_ERROR			cpu_to_be16(0x0001)
+#define IB_PMA_SEL_LINK_ERROR_RECOVERY		cpu_to_be16(0x0002)
+#define IB_PMA_SEL_LINK_DOWNED			cpu_to_be16(0x0004)
+#define IB_PMA_SEL_PORT_RCV_ERRORS		cpu_to_be16(0x0008)
+#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS	cpu_to_be16(0x0010)
+#define IB_PMA_SEL_PORT_XMIT_DISCARDS		cpu_to_be16(0x0040)
+#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS	cpu_to_be16(0x0200)
+#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS	cpu_to_be16(0x0400)
+#define IB_PMA_SEL_PORT_VL15_DROPPED		cpu_to_be16(0x0800)
+#define IB_PMA_SEL_PORT_XMIT_DATA		cpu_to_be16(0x1000)
+#define IB_PMA_SEL_PORT_RCV_DATA		cpu_to_be16(0x2000)
+#define IB_PMA_SEL_PORT_XMIT_PACKETS		cpu_to_be16(0x4000)
+#define IB_PMA_SEL_PORT_RCV_PACKETS		cpu_to_be16(0x8000)
 
 struct ib_pma_portcounters_ext {
 	u8 reserved;
@@ -913,14 +913,14 @@ struct ib_pma_portcounters_ext {
 	__be64 port_multicast_rcv_packets;
 } __attribute__ ((packed));
 
-#define IB_PMA_SELX_PORT_XMIT_DATA		__constant_htons(0x0001)
-#define IB_PMA_SELX_PORT_RCV_DATA		__constant_htons(0x0002)
-#define IB_PMA_SELX_PORT_XMIT_PACKETS		__constant_htons(0x0004)
-#define IB_PMA_SELX_PORT_RCV_PACKETS		__constant_htons(0x0008)
-#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS	__constant_htons(0x0010)
-#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS	__constant_htons(0x0020)
-#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS	__constant_htons(0x0040)
-#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS	__constant_htons(0x0080)
+#define IB_PMA_SELX_PORT_XMIT_DATA		cpu_to_be16(0x0001)
+#define IB_PMA_SELX_PORT_RCV_DATA		cpu_to_be16(0x0002)
+#define IB_PMA_SELX_PORT_XMIT_PACKETS		cpu_to_be16(0x0004)
+#define IB_PMA_SELX_PORT_RCV_PACKETS		cpu_to_be16(0x0008)
+#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS	cpu_to_be16(0x0010)
+#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS	cpu_to_be16(0x0020)
+#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS	cpu_to_be16(0x0040)
+#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS	cpu_to_be16(0x0080)
 
 static int recv_pma_get_classportinfo(struct ib_perf *pmp)
 {
@@ -933,7 +933,7 @@ static int recv_pma_get_classportinfo(st
 		pmp->status |= IB_SMP_INVALID_FIELD;
 
 	/* Indicate AllPortSelect is valid (only one port anyway) */
-	p->cap_mask = __constant_cpu_to_be16(1 << 8);
+	p->cap_mask = cpu_to_be16(1 << 8);
 	p->base_version = 1;
 	p->class_version = 1;
 	/*
@@ -951,12 +951,11 @@ static int recv_pma_get_classportinfo(st
  * We support 5 counters which only count the mandatory quantities.
  */
 #define COUNTER_MASK(q, n) (q << ((9 - n) * 3))
-#define COUNTER_MASK0_9 \
-	__constant_cpu_to_be32(COUNTER_MASK(1, 0) | \
-			       COUNTER_MASK(1, 1) | \
-			       COUNTER_MASK(1, 2) | \
-			       COUNTER_MASK(1, 3) | \
-			       COUNTER_MASK(1, 4))
+#define COUNTER_MASK0_9 cpu_to_be32(COUNTER_MASK(1, 0) | \
+				    COUNTER_MASK(1, 1) | \
+				    COUNTER_MASK(1, 2) | \
+				    COUNTER_MASK(1, 3) | \
+				    COUNTER_MASK(1, 4))
 
 static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
 					   struct ib_device *ibdev, u8 port)
@@ -1137,7 +1136,7 @@ static int recv_pma_get_portsamplesresul
 		status = dev->pma_sample_status;
 	p->sample_status = cpu_to_be16(status);
 	/* 64 bits */
-	p->extended_width = __constant_cpu_to_be32(0x80000000);
+	p->extended_width = cpu_to_be32(0x80000000);
 	for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
 		p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
 		    cpu_to_be64(
@@ -1185,7 +1184,7 @@ static int recv_pma_get_portcounters(str
 		pmp->status |= IB_SMP_INVALID_FIELD;
 
 	if (cntrs.symbol_error_counter > 0xFFFFUL)
-		p->symbol_error_counter = __constant_cpu_to_be16(0xFFFF);
+		p->symbol_error_counter = cpu_to_be16(0xFFFF);
 	else
 		p->symbol_error_counter =
 			cpu_to_be16((u16)cntrs.symbol_error_counter);
@@ -1199,17 +1198,17 @@ static int recv_pma_get_portcounters(str
 	else
 		p->link_downed_counter = (u8)cntrs.link_downed_counter;
 	if (cntrs.port_rcv_errors > 0xFFFFUL)
-		p->port_rcv_errors = __constant_cpu_to_be16(0xFFFF);
+		p->port_rcv_errors = cpu_to_be16(0xFFFF);
 	else
 		p->port_rcv_errors =
 			cpu_to_be16((u16) cntrs.port_rcv_errors);
 	if (cntrs.port_rcv_remphys_errors > 0xFFFFUL)
-		p->port_rcv_remphys_errors = __constant_cpu_to_be16(0xFFFF);
+		p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF);
 	else
 		p->port_rcv_remphys_errors =
 			cpu_to_be16((u16)cntrs.port_rcv_remphys_errors);
 	if (cntrs.port_xmit_discards > 0xFFFFUL)
-		p->port_xmit_discards = __constant_cpu_to_be16(0xFFFF);
+		p->port_xmit_discards = cpu_to_be16(0xFFFF);
 	else
 		p->port_xmit_discards =
 			cpu_to_be16((u16)cntrs.port_xmit_discards);
@@ -1220,24 +1219,24 @@ static int recv_pma_get_portcounters(str
 	p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) |
 		cntrs.excessive_buffer_overrun_errors;
 	if (cntrs.vl15_dropped > 0xFFFFUL)
-		p->vl15_dropped = __constant_cpu_to_be16(0xFFFF);
+		p->vl15_dropped = cpu_to_be16(0xFFFF);
 	else
 		p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped);
 	if (cntrs.port_xmit_data > 0xFFFFFFFFUL)
-		p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF);
+		p->port_xmit_data = cpu_to_be32(0xFFFFFFFF);
 	else
 		p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data);
 	if (cntrs.port_rcv_data > 0xFFFFFFFFUL)
-		p->port_rcv_data = __constant_cpu_to_be32(0xFFFFFFFF);
+		p->port_rcv_data = cpu_to_be32(0xFFFFFFFF);
 	else
 		p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data);
 	if (cntrs.port_xmit_packets > 0xFFFFFFFFUL)
-		p->port_xmit_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+		p->port_xmit_packets = cpu_to_be32(0xFFFFFFFF);
 	else
 		p->port_xmit_packets =
 			cpu_to_be32((u32)cntrs.port_xmit_packets);
 	if (cntrs.port_rcv_packets > 0xFFFFFFFFUL)
-		p->port_rcv_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+		p->port_rcv_packets = cpu_to_be32(0xFFFFFFFF);
 	else
 		p->port_rcv_packets =
 			cpu_to_be32((u32) cntrs.port_rcv_packets);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_rc.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_rc.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_rc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_rc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1744,7 +1744,7 @@ void ipath_rc_rcv(struct ipath_ibdev *de
 		/* Signal completion event if the solicited bit is set. */
 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 			       (ohdr->bth[0] &
-				__constant_cpu_to_be32(1 << 23)) != 0);
+				cpu_to_be32(1 << 23)) != 0);
 		break;
 
 	case OP(RDMA_WRITE_FIRST):
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_sdma.c	2009-06-09 23:05:27.000000000 -0400
@@ -781,10 +781,10 @@ retry:
 		descqp = &dd->ipath_sdma_descq[dd->ipath_sdma_descq_cnt].qw[0];
 	descqp -= 2;
 	/* SDmaLastDesc */
-	descqp[0] |= __constant_cpu_to_le64(1ULL << 11);
+	descqp[0] |= cpu_to_le64(1ULL << 11);
 	if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_INTREQ) {
 		/* SDmaIntReq */
-		descqp[0] |= __constant_cpu_to_le64(1ULL << 15);
+		descqp[0] |= cpu_to_le64(1ULL << 15);
 	}
 
 	/* Commit writes to memory and advance the tail on the chip */
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_uc.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_uc.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_uc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_uc.c	2009-06-09 23:05:27.000000000 -0400
@@ -419,7 +419,7 @@ void ipath_uc_rcv(struct ipath_ibdev *de
 		/* Signal completion event if the solicited bit is set. */
 		ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 			       (ohdr->bth[0] &
-				__constant_cpu_to_be32(1 << 23)) != 0);
+				cpu_to_be32(1 << 23)) != 0);
 		break;
 
 	case OP(RDMA_WRITE_FIRST):
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_ud.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_ud.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_ud.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_ud.c	2009-06-09 23:05:27.000000000 -0400
@@ -370,7 +370,7 @@ int ipath_make_ud_req(struct ipath_qp *q
 	 */
 	ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
 		ah_attr->dlid != IPATH_PERMISSIVE_LID ?
-		__constant_cpu_to_be32(IPATH_MULTICAST_QPN) :
+		cpu_to_be32(IPATH_MULTICAST_QPN) :
 		cpu_to_be32(wqe->wr.wr.ud.remote_qpn);
 	ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK);
 	/*
@@ -573,7 +573,7 @@ void ipath_ud_rcv(struct ipath_ibdev *de
 	/* Signal completion event if the solicited bit is set. */
 	ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
 		       (ohdr->bth[0] &
-			__constant_cpu_to_be32(1 << 23)) != 0);
+			cpu_to_be32(1 << 23)) != 0);
 
 bail:;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_user_pages.c	2009-06-09 23:05:27.000000000 -0400
@@ -209,20 +209,20 @@ void ipath_release_user_pages_on_close(s
 
 	mm = get_task_mm(current);
 	if (!mm)
-		goto bail;
+		return;
 
 	work = kmalloc(sizeof(*work), GFP_KERNEL);
 	if (!work)
 		goto bail_mm;
 
-	goto bail;
-
 	INIT_WORK(&work->work, user_pages_account);
 	work->mm = mm;
 	work->num_pages = num_pages;
 
+	schedule_work(&work->work);
+	return;
+
 bail_mm:
 	mmput(mm);
-bail:
 	return;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_user_sdma.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_user_sdma.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_user_sdma.c	2009-06-09 23:05:27.000000000 -0400
@@ -667,13 +667,13 @@ static inline __le64 ipath_sdma_make_des
 
 static inline __le64 ipath_sdma_make_first_desc0(__le64 descq)
 {
-	return descq | __constant_cpu_to_le64(1ULL << 12);
+	return descq | cpu_to_le64(1ULL << 12);
 }
 
 static inline __le64 ipath_sdma_make_last_desc0(__le64 descq)
 {
 					      /* last */  /* dma head */
-	return descq | __constant_cpu_to_le64(1ULL << 11 | 1ULL << 13);
+	return descq | cpu_to_le64(1ULL << 11 | 1ULL << 13);
 }
 
 static inline __le64 ipath_sdma_make_desc1(u64 addr)
@@ -763,7 +763,7 @@ static int ipath_user_sdma_push_pkts(str
 		if (ofs >= IPATH_SMALLBUF_DWORDS) {
 			for (i = 0; i < pkt->naddr; i++) {
 				dd->ipath_sdma_descq[dtail].qw[0] |=
-					__constant_cpu_to_le64(1ULL << 14);
+					cpu_to_le64(1ULL << 14);
 				if (++dtail == dd->ipath_sdma_descq_cnt)
 					dtail = 0;
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.c	2009-06-09 23:05:27.000000000 -0400
@@ -1585,7 +1585,7 @@ static int ipath_query_port(struct ib_de
 	u64 ibcstat;
 
 	memset(props, 0, sizeof(*props));
-	props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE);
+	props->lid = lid ? lid : be16_to_cpu(IB_LID_PERMISSIVE);
 	props->lmc = dd->ipath_lmc;
 	props->sm_lid = dev->sm_lid;
 	props->sm_sl = dev->sm_sl;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/ipath/ipath_verbs.h	2009-06-09 23:05:27.000000000 -0400
@@ -86,11 +86,11 @@
 #define IB_PMA_SAMPLE_STATUS_RUNNING	0x02
 
 /* Mandatory IB performance counter select values. */
-#define IB_PMA_PORT_XMIT_DATA	__constant_htons(0x0001)
-#define IB_PMA_PORT_RCV_DATA	__constant_htons(0x0002)
-#define IB_PMA_PORT_XMIT_PKTS	__constant_htons(0x0003)
-#define IB_PMA_PORT_RCV_PKTS	__constant_htons(0x0004)
-#define IB_PMA_PORT_XMIT_WAIT	__constant_htons(0x0005)
+#define IB_PMA_PORT_XMIT_DATA	cpu_to_be16(0x0001)
+#define IB_PMA_PORT_RCV_DATA	cpu_to_be16(0x0002)
+#define IB_PMA_PORT_XMIT_PKTS	cpu_to_be16(0x0003)
+#define IB_PMA_PORT_RCV_PKTS	cpu_to_be16(0x0004)
+#define IB_PMA_PORT_XMIT_WAIT	cpu_to_be16(0x0005)
 
 struct ib_reth {
 	__be64 vaddr;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mad.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mad.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mad.c	2009-06-09 23:05:27.000000000 -0400
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_
  * Snoop SM MADs for port info and P_Key table sets, so we can
  * synthesize LID change and P_Key change events.
  */
-static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
+static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
+				u16 prev_lid)
 {
 	struct ib_event event;
 
@@ -157,6 +158,7 @@ static void smp_snoop(struct ib_device *
 		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
 			struct ib_port_info *pinfo =
 				(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+			u16 lid = be16_to_cpu(pinfo->lid);
 
 			update_sm_ah(to_mdev(ibdev), port_num,
 				     be16_to_cpu(pinfo->sm_lid),
@@ -165,12 +167,15 @@ static void smp_snoop(struct ib_device *
 			event.device	       = ibdev;
 			event.element.port_num = port_num;
 
-			if (pinfo->clientrereg_resv_subnetto & 0x80)
+			if (pinfo->clientrereg_resv_subnetto & 0x80) {
 				event.event    = IB_EVENT_CLIENT_REREGISTER;
-			else
-				event.event    = IB_EVENT_LID_CHANGE;
+				ib_dispatch_event(&event);
+			}
 
-			ib_dispatch_event(&event);
+			if (prev_lid != lid) {
+				event.event    = IB_EVENT_LID_CHANGE;
+				ib_dispatch_event(&event);
+			}
 		}
 
 		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -228,8 +233,9 @@ int mlx4_ib_process_mad(struct ib_device
 			struct ib_wc *in_wc, struct ib_grh *in_grh,
 			struct ib_mad *in_mad, struct ib_mad *out_mad)
 {
-	u16 slid;
+	u16 slid, prev_lid = 0;
 	int err;
+	struct ib_port_attr pattr;
 
 	slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
 
@@ -263,6 +269,13 @@ int mlx4_ib_process_mad(struct ib_device
 	} else
 		return IB_MAD_RESULT_SUCCESS;
 
+	if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	     in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+	    in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+	    in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+	    !ib_query_port(ibdev, port_num, &pattr))
+		prev_lid = pattr.lid;
+
 	err = mlx4_MAD_IFC(to_mdev(ibdev),
 			   mad_flags & IB_MAD_IGNORE_MKEY,
 			   mad_flags & IB_MAD_IGNORE_BKEY,
@@ -271,7 +284,7 @@ int mlx4_ib_process_mad(struct ib_device
 		return IB_MAD_RESULT_FAILURE;
 
 	if (!out_mad->mad_hdr.status) {
-		smp_snoop(ibdev, port_num, in_mad);
+		smp_snoop(ibdev, port_num, in_mad, prev_lid);
 		node_desc_override(ibdev, out_mad);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/main.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/main.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -394,8 +394,7 @@ static int mlx4_ib_mmap(struct ib_uconte
 				       PAGE_SIZE, vma->vm_page_prot))
 			return -EAGAIN;
 	} else if (vma->vm_pgoff == 1 && dev->dev->caps.bf_reg_size != 0) {
-		/* FIXME want pgprot_writecombine() for BlueFlame pages */
-		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
 		if (io_remap_pfn_range(vma, vma->vm_start,
 				       to_mucontext(context)->uar.pfn +
@@ -699,11 +698,12 @@ static void mlx4_ib_remove(struct mlx4_d
 	struct mlx4_ib_dev *ibdev = ibdev_ptr;
 	int p;
 
+	mlx4_ib_mad_cleanup(ibdev);
+	ib_unregister_device(&ibdev->ib_dev);
+
 	for (p = 1; p <= ibdev->num_ports; ++p)
 		mlx4_CLOSE_PORT(dev, p);
 
-	mlx4_ib_mad_cleanup(ibdev);
-	ib_unregister_device(&ibdev->ib_dev);
 	iounmap(ibdev->uar_map);
 	mlx4_uar_free(dev, &ibdev->priv_uar);
 	mlx4_pd_free(dev, ibdev->priv_pdn);
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mlx4_ib.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mlx4_ib.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mlx4_ib.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mlx4_ib.h	2009-06-09 23:05:27.000000000 -0400
@@ -86,6 +86,7 @@ struct mlx4_ib_mr {
 
 struct mlx4_ib_fast_reg_page_list {
 	struct ib_fast_reg_page_list	ibfrpl;
+	__be64			       *mapped_page_list;
 	dma_addr_t			map;
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mr.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mr.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/mr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/mr.c	2009-06-09 23:05:27.000000000 -0400
@@ -231,7 +231,11 @@ struct ib_fast_reg_page_list *mlx4_ib_al
 	if (!mfrpl)
 		return ERR_PTR(-ENOMEM);
 
-	mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
+	mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL);
+	if (!mfrpl->ibfrpl.page_list)
+		goto err_free;
+
+	mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
 						     size, &mfrpl->map,
 						     GFP_KERNEL);
 	if (!mfrpl->ibfrpl.page_list)
@@ -242,6 +246,7 @@ struct ib_fast_reg_page_list *mlx4_ib_al
 	return &mfrpl->ibfrpl;
 
 err_free:
+	kfree(mfrpl->ibfrpl.page_list);
 	kfree(mfrpl);
 	return ERR_PTR(-ENOMEM);
 }
@@ -252,8 +257,9 @@ void mlx4_ib_free_fast_reg_page_list(str
 	struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
 	int size = page_list->max_page_list_len * sizeof (u64);
 
-	dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list,
+	dma_free_coherent(&dev->dev->pdev->dev, size, mfrpl->mapped_page_list,
 			  mfrpl->map);
+	kfree(mfrpl->ibfrpl.page_list);
 	kfree(mfrpl);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/qp.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/qp.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mlx4/qp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/qp.c	2009-06-09 23:05:27.000000000 -0400
@@ -71,17 +71,17 @@ enum {
 };
 
 static const __be32 mlx4_ib_opcode[] = {
-	[IB_WR_SEND]			= __constant_cpu_to_be32(MLX4_OPCODE_SEND),
-	[IB_WR_LSO]			= __constant_cpu_to_be32(MLX4_OPCODE_LSO),
-	[IB_WR_SEND_WITH_IMM]		= __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
-	[IB_WR_RDMA_WRITE]		= __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
-	[IB_WR_RDMA_WRITE_WITH_IMM]	= __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
-	[IB_WR_RDMA_READ]		= __constant_cpu_to_be32(MLX4_OPCODE_RDMA_READ),
-	[IB_WR_ATOMIC_CMP_AND_SWP]	= __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
-	[IB_WR_ATOMIC_FETCH_AND_ADD]	= __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
-	[IB_WR_SEND_WITH_INV]		= __constant_cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
-	[IB_WR_LOCAL_INV]		= __constant_cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
-	[IB_WR_FAST_REG_MR]		= __constant_cpu_to_be32(MLX4_OPCODE_FMR),
+	[IB_WR_SEND]			= cpu_to_be32(MLX4_OPCODE_SEND),
+	[IB_WR_LSO]			= cpu_to_be32(MLX4_OPCODE_LSO),
+	[IB_WR_SEND_WITH_IMM]		= cpu_to_be32(MLX4_OPCODE_SEND_IMM),
+	[IB_WR_RDMA_WRITE]		= cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
+	[IB_WR_RDMA_WRITE_WITH_IMM]	= cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
+	[IB_WR_RDMA_READ]		= cpu_to_be32(MLX4_OPCODE_RDMA_READ),
+	[IB_WR_ATOMIC_CMP_AND_SWP]	= cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
+	[IB_WR_ATOMIC_FETCH_AND_ADD]	= cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
+	[IB_WR_SEND_WITH_INV]		= cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
+	[IB_WR_LOCAL_INV]		= cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
+	[IB_WR_FAST_REG_MR]		= cpu_to_be32(MLX4_OPCODE_FMR),
 };
 
 static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
@@ -1365,7 +1365,7 @@ static void set_fmr_seg(struct mlx4_wqe_
 	int i;
 
 	for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i)
-		wr->wr.fast_reg.page_list->page_list[i] =
+		mfrpl->mapped_page_list[i] =
 			cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] |
 				    MLX4_MTT_FLAG_PRESENT);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_cmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -157,13 +157,15 @@ enum {
 enum {
 	CMD_TIME_CLASS_A = (HZ + 999) / 1000 + 1,
 	CMD_TIME_CLASS_B = (HZ +  99) /  100 + 1,
-	CMD_TIME_CLASS_C = (HZ +   9) /   10 + 1
+	CMD_TIME_CLASS_C = (HZ +   9) /   10 + 1,
+	CMD_TIME_CLASS_D = 60 * HZ
 };
 #else
 enum {
 	CMD_TIME_CLASS_A = 60 * HZ,
 	CMD_TIME_CLASS_B = 60 * HZ,
-	CMD_TIME_CLASS_C = 60 * HZ
+	CMD_TIME_CLASS_C = 60 * HZ,
+	CMD_TIME_CLASS_D = 60 * HZ
 };
 #endif
 
@@ -598,7 +600,7 @@ int mthca_SYS_EN(struct mthca_dev *dev,
 	u64 out;
 	int ret;
 
-	ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, HZ, status);
+	ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D, status);
 
 	if (*status == MTHCA_CMD_STAT_DDR_MEM_ERR)
 		mthca_warn(dev, "SYS_EN DDR error: syn=%x, sock=%d, "
@@ -611,7 +613,7 @@ int mthca_SYS_EN(struct mthca_dev *dev,
 
 int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status)
 {
-	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, HZ, status);
+	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, CMD_TIME_CLASS_C, status);
 }
 
 static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
@@ -1390,7 +1392,7 @@ int mthca_INIT_HCA(struct mthca_dev *dev
 		MTHCA_PUT(inbox, param->uarc_base,   INIT_HCA_UAR_CTX_BASE_OFFSET);
 	}
 
-	err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, HZ, status);
+	err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, CMD_TIME_CLASS_D, status);
 
 	mthca_free_mailbox(dev, mailbox);
 	return err;
@@ -1450,12 +1452,12 @@ int mthca_INIT_IB(struct mthca_dev *dev,
 
 int mthca_CLOSE_IB(struct mthca_dev *dev, int port, u8 *status)
 {
-	return mthca_cmd(dev, 0, port, 0, CMD_CLOSE_IB, HZ, status);
+	return mthca_cmd(dev, 0, port, 0, CMD_CLOSE_IB, CMD_TIME_CLASS_A, status);
 }
 
 int mthca_CLOSE_HCA(struct mthca_dev *dev, int panic, u8 *status)
 {
-	return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, HZ, status);
+	return mthca_cmd(dev, 0, 0, panic, CMD_CLOSE_HCA, CMD_TIME_CLASS_C, status);
 }
 
 int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_mad.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_mad.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_mad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_mad.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,8 @@ static void update_sm_ah(struct mthca_de
  */
 static void smp_snoop(struct ib_device *ibdev,
 		      u8 port_num,
-		      struct ib_mad *mad)
+		      struct ib_mad *mad,
+		      u16 prev_lid)
 {
 	struct ib_event event;
 
@@ -114,6 +115,7 @@ static void smp_snoop(struct ib_device *
 		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
 			struct ib_port_info *pinfo =
 				(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+			u16 lid = be16_to_cpu(pinfo->lid);
 
 			mthca_update_rate(to_mdev(ibdev), port_num);
 			update_sm_ah(to_mdev(ibdev), port_num,
@@ -123,12 +125,15 @@ static void smp_snoop(struct ib_device *
 			event.device           = ibdev;
 			event.element.port_num = port_num;
 
-			if (pinfo->clientrereg_resv_subnetto & 0x80)
+			if (pinfo->clientrereg_resv_subnetto & 0x80) {
 				event.event    = IB_EVENT_CLIENT_REREGISTER;
-			else
-				event.event    = IB_EVENT_LID_CHANGE;
+				ib_dispatch_event(&event);
+			}
 
-			ib_dispatch_event(&event);
+			if (prev_lid != lid) {
+				event.event    = IB_EVENT_LID_CHANGE;
+				ib_dispatch_event(&event);
+			}
 		}
 
 		if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -196,6 +201,8 @@ int mthca_process_mad(struct ib_device *
 	int err;
 	u8 status;
 	u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+	u16 prev_lid = 0;
+	struct ib_port_attr pattr;
 
 	/* Forward locally generated traps to the SM */
 	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
@@ -233,6 +240,12 @@ int mthca_process_mad(struct ib_device *
 			return IB_MAD_RESULT_SUCCESS;
 	} else
 		return IB_MAD_RESULT_SUCCESS;
+	if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	     in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+	    in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+	    in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+	    !ib_query_port(ibdev, port_num, &pattr))
+		prev_lid = pattr.lid;
 
 	err = mthca_MAD_IFC(to_mdev(ibdev),
 			    mad_flags & IB_MAD_IGNORE_MKEY,
@@ -252,7 +265,7 @@ int mthca_process_mad(struct ib_device *
 	}
 
 	if (!out_mad->mad_hdr.status) {
-		smp_snoop(ibdev, port_num, in_mad);
+		smp_snoop(ibdev, port_num, in_mad, prev_lid);
 		node_desc_override(ibdev, out_mad);
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_main.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_main.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/mthca/mthca_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mthca/mthca_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1016,20 +1016,20 @@ static int __mthca_init_one(struct pci_d
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err) {
 		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
 			goto err_free_res;
 		}
 	}
-	err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err) {
 		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit "
 			 "consistent PCI DMA mask.\n");
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "Can't set consistent PCI DMA mask, "
 				"aborting.\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  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
@@ -478,23 +478,23 @@ static int __devinit nes_probe(struct pc
 	}
 
 	if ((sizeof(dma_addr_t) > 4)) {
-		ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
+		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
 		if (ret < 0) {
 			printk(KERN_ERR PFX "64b DMA mask configuration failed\n");
 			goto bail2;
 		}
-		ret = pci_set_consistent_dma_mask(pcidev, DMA_64BIT_MASK);
+		ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
 		if (ret) {
 			printk(KERN_ERR PFX "64b DMA consistent mask configuration failed\n");
 			goto bail2;
 		}
 	} else {
-		ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
+		ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
 		if (ret < 0) {
 			printk(KERN_ERR PFX "32b DMA mask configuration failed\n");
 			goto bail2;
 		}
-		ret = pci_set_consistent_dma_mask(pcidev, DMA_32BIT_MASK);
+		ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
 		if (ret) {
 			printk(KERN_ERR PFX "32b DMA consistent mask configuration failed\n");
 			goto bail2;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_cm.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_cm.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_cm.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -56,6 +56,7 @@
 #include <net/neighbour.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
+#include <net/tcp.h>
 
 #include "nes.h"
 
@@ -103,6 +104,7 @@ static int nes_disconnect(struct nes_qp
 static void nes_disconnect_worker(struct work_struct *work);
 
 static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
+static int send_mpa_reject(struct nes_cm_node *);
 static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
 static int send_reset(struct nes_cm_node *, struct sk_buff *);
 static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
@@ -113,8 +115,7 @@ static void process_packet(struct nes_cm
 static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
 static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
 static void cleanup_retrans_entry(struct nes_cm_node *);
-static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *,
-	enum nes_cm_event_type);
+static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *);
 static void free_retrans_entry(struct nes_cm_node *cm_node);
 static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
 	struct sk_buff *skb, int optionsize, int passive);
@@ -124,6 +125,8 @@ static void cm_event_connected(struct ne
 static void cm_event_connect_error(struct nes_cm_event *);
 static void cm_event_reset(struct nes_cm_event *);
 static void cm_event_mpa_req(struct nes_cm_event *);
+static void cm_event_mpa_reject(struct nes_cm_event *);
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node);
 
 static void print_core(struct nes_cm_core *core);
 
@@ -196,7 +199,6 @@ static struct nes_cm_event *create_event
  */
 static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
 {
-	int ret;
 	if (!skb) {
 		nes_debug(NES_DBG_CM, "skb set to NULL\n");
 		return -1;
@@ -206,11 +208,27 @@ static int send_mpa_request(struct nes_c
 	form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
 			cm_node->mpa_frame_size, SET_ACK);
 
-	ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
-	if (ret < 0)
-		return ret;
+	return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
+}
 
-	return 0;
+
+
+static int send_mpa_reject(struct nes_cm_node *cm_node)
+{
+	struct sk_buff  *skb = NULL;
+
+	skb = dev_alloc_skb(MAX_CM_BUFFER);
+	if (!skb) {
+		nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
+		return -ENOMEM;
+	}
+
+	/* send an MPA reject frame */
+	form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
+			cm_node->mpa_frame_size, SET_ACK | SET_FIN);
+
+	cm_node->state = NES_CM_STATE_FIN_WAIT1;
+	return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
 }
 
 
@@ -218,14 +236,17 @@ static int send_mpa_request(struct nes_c
  * recv_mpa - process a received TCP pkt, we are expecting an
  * IETF MPA frame
  */
-static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
+static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
+		u32 len)
 {
 	struct ietf_mpa_frame *mpa_frame;
 
+	*type = NES_MPA_REQUEST_ACCEPT;
+
 	/* assume req frame is in tcp data payload */
 	if (len < sizeof(struct ietf_mpa_frame)) {
 		nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
-		return -1;
+		return -EINVAL;
 	}
 
 	mpa_frame = (struct ietf_mpa_frame *)buffer;
@@ -234,14 +255,25 @@ static int parse_mpa(struct nes_cm_node
 	if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
 		nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
 				" complete (%x + %x != %x)\n",
-				cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len);
-		return -1;
+				cm_node->mpa_frame_size,
+				(u32)sizeof(struct ietf_mpa_frame), len);
+		return -EINVAL;
+	}
+	/* make sure it does not exceed the max size */
+	if (len > MAX_CM_BUFFER) {
+		nes_debug(NES_DBG_CM, "The received ietf buffer was too large"
+				" (%x + %x != %x)\n",
+				cm_node->mpa_frame_size,
+				(u32)sizeof(struct ietf_mpa_frame), len);
+		return -EINVAL;
 	}
 
 	/* copy entire MPA frame to our cm_node's frame */
 	memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
 			cm_node->mpa_frame_size);
 
+	if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
+		*type = NES_MPA_REQUEST_REJECT;
 	return 0;
 }
 
@@ -380,7 +412,7 @@ int schedule_nes_timer(struct nes_cm_nod
 
 	new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
 	if (!new_send)
-		return -1;
+		return -ENOMEM;
 
 	/* new_send->timetosend = currenttime */
 	new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -394,9 +426,12 @@ int schedule_nes_timer(struct nes_cm_nod
 
 	if (type == NES_TIMER_TYPE_CLOSE) {
 		new_send->timetosend += (HZ/10);
-		spin_lock_irqsave(&cm_node->recv_list_lock, flags);
-		list_add_tail(&new_send->list, &cm_node->recv_list);
-		spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
+		if (cm_node->recv_entry) {
+			kfree(new_send);
+			WARN_ON(1);
+			return -EINVAL;
+		}
+		cm_node->recv_entry = new_send;
 	}
 
 	if (type == NES_TIMER_TYPE_SEND) {
@@ -412,8 +447,8 @@ int schedule_nes_timer(struct nes_cm_nod
 		if (ret != NETDEV_TX_OK) {
 			nes_debug(NES_DBG_CM, "Error sending packet %p "
 				"(jiffies = %lu)\n", new_send, jiffies);
-			atomic_dec(&new_send->skb->users);
 			new_send->timetosend = jiffies;
+			ret = NETDEV_TX_OK;
 		} else {
 			cm_packets_sent++;
 			if (!send_retrans) {
@@ -435,24 +470,79 @@ int schedule_nes_timer(struct nes_cm_nod
 	return ret;
 }
 
+static void nes_retrans_expired(struct nes_cm_node *cm_node)
+{
+	switch (cm_node->state) {
+	case NES_CM_STATE_SYN_RCVD:
+	case NES_CM_STATE_CLOSING:
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
+		break;
+	case NES_CM_STATE_LAST_ACK:
+	case NES_CM_STATE_FIN_WAIT1:
+	case NES_CM_STATE_MPAREJ_RCVD:
+		send_reset(cm_node, NULL);
+		break;
+	default:
+		create_event(cm_node, NES_CM_EVENT_ABORTED);
+	}
+}
+
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
+{
+	struct nes_timer_entry *recv_entry = cm_node->recv_entry;
+	struct iw_cm_id *cm_id = cm_node->cm_id;
+	struct nes_qp *nesqp;
+	unsigned long qplockflags;
+
+	if (!recv_entry)
+		return;
+	nesqp = (struct nes_qp *)recv_entry->skb;
+	if (nesqp) {
+		spin_lock_irqsave(&nesqp->lock, qplockflags);
+		if (nesqp->cm_id) {
+			nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+				"refcount = %d: HIT A "
+				"NES_TIMER_TYPE_CLOSE with something "
+				"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+				atomic_read(&nesqp->refcount));
+			nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
+			nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
+			nesqp->ibqp_state = IB_QPS_ERR;
+			spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+			nes_cm_disconn(nesqp);
+		} else {
+			spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+			nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+				"refcount = %d: HIT A "
+				"NES_TIMER_TYPE_CLOSE with nothing "
+				"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+				atomic_read(&nesqp->refcount));
+		}
+	} else if (rem_node) {
+		/* TIME_WAIT state */
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
+	}
+	if (cm_node->cm_id)
+		cm_id->rem_ref(cm_id);
+	kfree(recv_entry);
+	cm_node->recv_entry = NULL;
+}
 
 /**
  * nes_cm_timer_tick
  */
 static void nes_cm_timer_tick(unsigned long pass)
 {
-	unsigned long flags, qplockflags;
+	unsigned long flags;
 	unsigned long nexttimeout = jiffies + NES_LONG_TIME;
-	struct iw_cm_id *cm_id;
 	struct nes_cm_node *cm_node;
 	struct nes_timer_entry *send_entry, *recv_entry;
-	struct list_head *list_core, *list_core_temp;
-	struct list_head *list_node, *list_node_temp;
+	struct list_head *list_core_temp;
+	struct list_head *list_node;
 	struct nes_cm_core *cm_core = g_cm_core;
-	struct nes_qp *nesqp;
 	u32 settimer = 0;
+	unsigned long timetosend;
 	int ret = NETDEV_TX_OK;
-	enum nes_cm_node_state last_state;
 
 	struct list_head timer_list;
 	INIT_LIST_HEAD(&timer_list);
@@ -461,7 +551,7 @@ static void nes_cm_timer_tick(unsigned l
 	list_for_each_safe(list_node, list_core_temp,
 				&cm_core->connected_nodes) {
 		cm_node = container_of(list_node, struct nes_cm_node, list);
-		if (!list_empty(&cm_node->recv_list) || (cm_node->send_entry)) {
+		if ((cm_node->recv_entry) || (cm_node->send_entry)) {
 			add_ref_cm_node(cm_node);
 			list_add(&cm_node->timer_entry, &timer_list);
 		}
@@ -471,54 +561,18 @@ static void nes_cm_timer_tick(unsigned l
 	list_for_each_safe(list_node, list_core_temp, &timer_list) {
 		cm_node = container_of(list_node, struct nes_cm_node,
 					timer_entry);
-		spin_lock_irqsave(&cm_node->recv_list_lock, flags);
-		list_for_each_safe(list_core, list_node_temp,
-			&cm_node->recv_list) {
-			recv_entry = container_of(list_core,
-				struct nes_timer_entry, list);
-			if (!recv_entry)
-				break;
+		recv_entry = cm_node->recv_entry;
+
+		if (recv_entry) {
 			if (time_after(recv_entry->timetosend, jiffies)) {
 				if (nexttimeout > recv_entry->timetosend ||
-					!settimer) {
+						!settimer) {
 					nexttimeout = recv_entry->timetosend;
 					settimer = 1;
 				}
-				continue;
-			}
-			list_del(&recv_entry->list);
-			cm_id = cm_node->cm_id;
-			spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
-			nesqp = (struct nes_qp *)recv_entry->skb;
-			spin_lock_irqsave(&nesqp->lock, qplockflags);
-			if (nesqp->cm_id) {
-				nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
-					"refcount = %d: HIT A "
-					"NES_TIMER_TYPE_CLOSE with something "
-					"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
-					atomic_read(&nesqp->refcount));
-				nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
-				nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
-				nesqp->ibqp_state = IB_QPS_ERR;
-				spin_unlock_irqrestore(&nesqp->lock,
-					qplockflags);
-				nes_cm_disconn(nesqp);
-			} else {
-				spin_unlock_irqrestore(&nesqp->lock,
-					qplockflags);
-				nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
-					"refcount = %d: HIT A "
-					"NES_TIMER_TYPE_CLOSE with nothing "
-					"to do!!!\n", nesqp->hwqp.qp_id, cm_id,
-					atomic_read(&nesqp->refcount));
-			}
-			if (cm_id)
-				cm_id->rem_ref(cm_id);
-
-			kfree(recv_entry);
-			spin_lock_irqsave(&cm_node->recv_list_lock, flags);
+			} else
+				handle_recv_entry(cm_node, 1);
 		}
-		spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
 
 		spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
 		do {
@@ -533,12 +587,11 @@ static void nes_cm_timer_tick(unsigned l
 						nexttimeout =
 							send_entry->timetosend;
 						settimer = 1;
-						break;
 					}
 				} else {
 					free_retrans_entry(cm_node);
-					break;
 				}
+				break;
 			}
 
 			if ((cm_node->state == NES_CM_STATE_TSA) ||
@@ -550,16 +603,12 @@ static void nes_cm_timer_tick(unsigned l
 			if (!send_entry->retranscount ||
 				!send_entry->retrycount) {
 				cm_packets_dropped++;
-				last_state = cm_node->state;
-				cm_node->state = NES_CM_STATE_CLOSED;
 				free_retrans_entry(cm_node);
+
 				spin_unlock_irqrestore(
 					&cm_node->retrans_list_lock, flags);
-				if (last_state == NES_CM_STATE_SYN_RCVD)
-					rem_ref_cm_node(cm_core, cm_node);
-				else
-					create_event(cm_node,
-						NES_CM_EVENT_ABORTED);
+				nes_retrans_expired(cm_node);
+				cm_node->state = NES_CM_STATE_CLOSED;
 				spin_lock_irqsave(&cm_node->retrans_list_lock,
 					flags);
 				break;
@@ -584,7 +633,6 @@ static void nes_cm_timer_tick(unsigned l
 				nes_debug(NES_DBG_CM, "rexmit failed for "
 					"node=%p\n", cm_node);
 				cm_packets_bounced++;
-				atomic_dec(&send_entry->skb->users);
 				send_entry->retrycount--;
 				nexttimeout = jiffies + NES_SHORT_TIME;
 				settimer = 1;
@@ -598,8 +646,11 @@ static void nes_cm_timer_tick(unsigned l
 				send_entry->retrycount);
 			if (send_entry->send_retrans) {
 				send_entry->retranscount--;
+				timetosend = (NES_RETRY_TIMEOUT <<
+					(NES_DEFAULT_RETRANS - send_entry->retranscount));
+
 				send_entry->timetosend = jiffies +
-					NES_RETRY_TIMEOUT;
+					min(timetosend, NES_MAX_TIMEOUT);
 				if (nexttimeout > send_entry->timetosend ||
 					!settimer) {
 					nexttimeout = send_entry->timetosend;
@@ -620,11 +671,6 @@ static void nes_cm_timer_tick(unsigned l
 
 		spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
 		rem_ref_cm_node(cm_node->cm_core, cm_node);
-		if (ret != NETDEV_TX_OK) {
-			nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
-				cm_node);
-			break;
-		}
 	}
 
 	if (settimer) {
@@ -714,7 +760,7 @@ static int send_reset(struct nes_cm_node
 		skb = dev_alloc_skb(MAX_CM_BUFFER);
 	if (!skb) {
 		nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
-		return -1;
+		return -ENOMEM;
 	}
 
 	form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
@@ -778,14 +824,10 @@ static struct nes_cm_node *find_node(str
 	unsigned long flags;
 	struct list_head *hte;
 	struct nes_cm_node *cm_node;
-	__be32 tmp_addr = cpu_to_be32(loc_addr);
 
 	/* get a handle on the hte */
 	hte = &cm_core->connected_nodes;
 
-	nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
-		  &tmp_addr, loc_port, cm_core, hte);
-
 	/* walk list and find cm_node associated with this session ID */
 	spin_lock_irqsave(&cm_core->ht_lock, flags);
 	list_for_each_entry(cm_node, hte, list) {
@@ -817,7 +859,6 @@ static struct nes_cm_listener *find_list
 {
 	unsigned long flags;
 	struct nes_cm_listener *listen_node;
-	__be32 tmp_addr = cpu_to_be32(dst_addr);
 
 	/* walk list and find cm_node associated with this session ID */
 	spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -834,9 +875,6 @@ static struct nes_cm_listener *find_list
 	}
 	spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 
-	nes_debug(NES_DBG_CM, "Unable to find listener for %pI4:%x\n",
-		  &tmp_addr, dst_port);
-
 	/* no listener */
 	return NULL;
 }
@@ -875,7 +913,8 @@ static int add_hte_node(struct nes_cm_co
 static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
 	struct nes_cm_listener *listener, int free_hanging_nodes)
 {
-	int ret = 1;
+	int ret = -EINVAL;
+	int err = 0;
 	unsigned long flags;
 	struct list_head *list_pos = NULL;
 	struct list_head *list_temp = NULL;
@@ -904,10 +943,60 @@ static int mini_cm_dec_refcnt_listen(str
 
 	list_for_each_safe(list_pos, list_temp, &reset_list) {
 		cm_node = container_of(list_pos, struct nes_cm_node,
-					reset_entry);
-		cleanup_retrans_entry(cm_node);
-		send_reset(cm_node, NULL);
-		rem_ref_cm_node(cm_node->cm_core, cm_node);
+				reset_entry);
+		{
+			struct nes_cm_node *loopback = cm_node->loopbackpartner;
+			if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
+				rem_ref_cm_node(cm_node->cm_core, cm_node);
+			} else {
+				if (!loopback) {
+					cleanup_retrans_entry(cm_node);
+					err = send_reset(cm_node, NULL);
+					if (err) {
+						cm_node->state =
+							 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);
+					}
+				} else {
+					struct nes_cm_event event;
+
+					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_connect_error(&event);
+					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);
+
+				}
+			}
+		}
 	}
 
 	spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -968,6 +1057,7 @@ static inline int mini_cm_accelerated(st
 	if (cm_node->accept_pend) {
 		BUG_ON(!cm_node->listener);
 		atomic_dec(&cm_node->listener->pend_accepts_cnt);
+		cm_node->accept_pend = 0;
 		BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
 	}
 
@@ -994,7 +1084,7 @@ static int nes_addr_resolve_neigh(struct
 	memset(&fl, 0, sizeof fl);
 	fl.nl_u.ip4_u.daddr = htonl(dst_ip);
 	if (ip_route_output_key(&init_net, &rt, &fl)) {
-		printk("%s: ip_route_output_key failed for 0x%08X\n",
+		printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
 				__func__, dst_ip);
 		return rc;
 	}
@@ -1057,8 +1147,6 @@ static struct nes_cm_node *make_cm_node(
 			cm_node->cm_id);
 
 	spin_lock_init(&cm_node->retrans_list_lock);
-	INIT_LIST_HEAD(&cm_node->recv_list);
-	spin_lock_init(&cm_node->recv_list_lock);
 
 	cm_node->loopbackpartner = NULL;
 	atomic_set(&cm_node->ref_count, 1);
@@ -1126,10 +1214,7 @@ static int add_ref_cm_node(struct nes_cm
 static int rem_ref_cm_node(struct nes_cm_core *cm_core,
 	struct nes_cm_node *cm_node)
 {
-	unsigned long flags, qplockflags;
-	struct nes_timer_entry *recv_entry;
-	struct iw_cm_id *cm_id;
-	struct list_head *list_core, *list_node_temp;
+	unsigned long flags;
 	struct nes_qp *nesqp;
 
 	if (!cm_node)
@@ -1150,38 +1235,9 @@ static int rem_ref_cm_node(struct nes_cm
 		atomic_dec(&cm_node->listener->pend_accepts_cnt);
 		BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
 	}
-	BUG_ON(cm_node->send_entry);
-	spin_lock_irqsave(&cm_node->recv_list_lock, flags);
-	list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) {
-		recv_entry = container_of(list_core, struct nes_timer_entry,
-				list);
-		list_del(&recv_entry->list);
-		cm_id = cm_node->cm_id;
-		spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
-		nesqp = (struct nes_qp *)recv_entry->skb;
-		spin_lock_irqsave(&nesqp->lock, qplockflags);
-		if (nesqp->cm_id) {
-			nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
-				"NES_TIMER_TYPE_CLOSE with something to do!\n",
-				nesqp->hwqp.qp_id, cm_id);
-			nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
-			nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
-			nesqp->ibqp_state = IB_QPS_ERR;
-			spin_unlock_irqrestore(&nesqp->lock, qplockflags);
-			nes_cm_disconn(nesqp);
-		} else {
-			spin_unlock_irqrestore(&nesqp->lock, qplockflags);
-			nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
-				"NES_TIMER_TYPE_CLOSE with nothing to do!\n",
-				nesqp->hwqp.qp_id, cm_id);
-		}
-		cm_id->rem_ref(cm_id);
-
-		kfree(recv_entry);
-		spin_lock_irqsave(&cm_node->recv_list_lock, flags);
-	}
-	spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
-
+	WARN_ON(cm_node->send_entry);
+	if (cm_node->recv_entry)
+		handle_recv_entry(cm_node, 0);
 	if (cm_node->listener) {
 		mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
 	} else {
@@ -1202,7 +1258,6 @@ static int rem_ref_cm_node(struct nes_cm
 		cm_node->nesqp = NULL;
 	}
 
-	cm_node->freed = 1;
 	kfree(cm_node);
 	return 0;
 }
@@ -1266,36 +1321,48 @@ static void drop_packet(struct sk_buff *
 	dev_kfree_skb_any(skb);
 }
 
-static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
-	struct tcphdr *tcph)
+static void handle_fin_pkt(struct nes_cm_node *cm_node)
 {
 	nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
 		"refcnt=%d\n", cm_node, cm_node->state,
 		atomic_read(&cm_node->ref_count));
-	cm_node->tcp_cntxt.rcv_nxt++;
-	cleanup_retrans_entry(cm_node);
 	switch (cm_node->state) {
 	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, skb);
+		send_fin(cm_node, NULL);
 		break;
 	case NES_CM_STATE_FIN_WAIT1:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSING;
-		send_ack(cm_node, skb);
+		send_ack(cm_node, NULL);
+		/* Wait for ACK as this is simultanous close..
+		* After we receive ACK, do not send anything..
+		* Just rm the node.. Done.. */
 		break;
 	case NES_CM_STATE_FIN_WAIT2:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_TIME_WAIT;
-		send_ack(cm_node, skb);
+		send_ack(cm_node, NULL);
+		schedule_nes_timer(cm_node, NULL,  NES_TIMER_TYPE_CLOSE, 1, 0);
+		break;
+	case NES_CM_STATE_TIME_WAIT:
+		cm_node->tcp_cntxt.rcv_nxt++;
+		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
 		break;
 	case NES_CM_STATE_TSA:
 	default:
 		nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
 			cm_node, cm_node->state);
-		drop_packet(skb);
 		break;
 	}
 }
@@ -1324,7 +1391,6 @@ static void handle_rst_pkt(struct nes_cm
 		passive_state = atomic_add_return(1, &cm_node->passive_state);
 		if (passive_state ==  NES_SEND_RESET_EVENT)
 			create_event(cm_node, NES_CM_EVENT_RESET);
-		cleanup_retrans_entry(cm_node);
 		cm_node->state = NES_CM_STATE_CLOSED;
 		dev_kfree_skb_any(skb);
 		break;
@@ -1338,26 +1404,37 @@ static void handle_rst_pkt(struct nes_cm
 		active_open_err(cm_node, skb, reset);
 		break;
 	case NES_CM_STATE_CLOSED:
-		cleanup_retrans_entry(cm_node);
 		drop_packet(skb);
 		break;
+	case NES_CM_STATE_LAST_ACK:
+		cm_node->cm_id->rem_ref(cm_node->cm_id);
+	case NES_CM_STATE_TIME_WAIT:
+		cm_node->state = NES_CM_STATE_CLOSED;
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
+		drop_packet(skb);
+		break;
+	case NES_CM_STATE_FIN_WAIT1:
+		nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
 	default:
 		drop_packet(skb);
 		break;
 	}
 }
 
-static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
-	enum nes_cm_event_type type)
+
+static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
 {
 
-	int	ret;
+	int	ret = 0;
 	int datasize = skb->len;
 	u8 *dataloc = skb->data;
-	ret = parse_mpa(cm_node, dataloc, datasize);
-	if (ret < 0) {
+
+	enum nes_cm_event_type type = NES_CM_EVENT_UNKNOWN;
+	u32     res_type;
+	ret = parse_mpa(cm_node, dataloc, &res_type, datasize);
+	if (ret) {
 		nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
-		if (type == NES_CM_EVENT_CONNECTED) {
+		if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
 			nes_debug(NES_DBG_CM, "%s[%u] create abort for "
 				"cm_node=%p listener=%p state=%d\n", __func__,
 				__LINE__, cm_node, cm_node->listener,
@@ -1366,18 +1443,39 @@ static void handle_rcv_mpa(struct nes_cm
 		} else {
 			passive_open_err(cm_node, skb, 1);
 		}
-	} else {
+		return;
+	}
+
+	switch (cm_node->state) {
+	case NES_CM_STATE_ESTABLISHED:
+		if (res_type == NES_MPA_REQUEST_REJECT) {
+			/*BIG problem as we are receiving the MPA.. So should
+			* not be REJECT.. This is Passive Open.. We can
+			* only receive it Reject for Active Open...*/
+			WARN_ON(1);
+		}
+		cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
+		type = NES_CM_EVENT_MPA_REQ;
+		atomic_set(&cm_node->passive_state,
+				NES_PASSIVE_STATE_INDICATED);
+		break;
+	case NES_CM_STATE_MPAREQ_SENT:
 		cleanup_retrans_entry(cm_node);
-		dev_kfree_skb_any(skb);
-		if (type == NES_CM_EVENT_CONNECTED)
+		if (res_type == NES_MPA_REQUEST_REJECT) {
+			type = NES_CM_EVENT_MPA_REJECT;
+			cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
+		} else {
+			type = NES_CM_EVENT_CONNECTED;
 			cm_node->state = NES_CM_STATE_TSA;
-		else
-			atomic_set(&cm_node->passive_state,
-					NES_PASSIVE_STATE_INDICATED);
-		create_event(cm_node, type);
+		}
 
+		break;
+	default:
+		WARN_ON(1);
+		break;
 	}
-	return ;
+	dev_kfree_skb_any(skb);
+	create_event(cm_node, type);
 }
 
 static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
@@ -1426,7 +1524,7 @@ static int check_seq(struct nes_cm_node
 	rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
 	if (ack_seq != loc_seq_num)
 		err = 1;
-	else if ((seq + rcv_wnd) < rcv_nxt)
+	else if (!between(seq, rcv_nxt, (rcv_nxt+rcv_wnd)))
 		err = 1;
 	if (err) {
 		nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
@@ -1465,8 +1563,6 @@ static void handle_syn_pkt(struct nes_cm
 		break;
 	case NES_CM_STATE_LISTENING:
 		/* Passive OPEN */
-		cm_node->accept_pend = 1;
-		atomic_inc(&cm_node->listener->pend_accepts_cnt);
 		if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
 				cm_node->listener->backlog) {
 			nes_debug(NES_DBG_CM, "drop syn due to backlog "
@@ -1484,6 +1580,9 @@ static void handle_syn_pkt(struct nes_cm
 		}
 		cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
 		BUG_ON(cm_node->send_entry);
+		cm_node->accept_pend = 1;
+		atomic_inc(&cm_node->listener->pend_accepts_cnt);
+
 		cm_node->state = NES_CM_STATE_SYN_RCVD;
 		send_syn(cm_node, 1, skb);
 		break;
@@ -1518,6 +1617,7 @@ static void handle_synack_pkt(struct nes
 	inc_sequence = ntohl(tcph->seq);
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_SENT:
+		cleanup_retrans_entry(cm_node);
 		/* active open */
 		if (check_syn(cm_node, tcph, skb))
 			return;
@@ -1558,62 +1658,46 @@ static void handle_synack_pkt(struct nes
 	}
 }
 
-static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
+static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
 	struct tcphdr *tcph)
 {
 	int datasize = 0;
 	u32 inc_sequence;
 	u32 rem_seq_ack;
 	u32 rem_seq;
-	int ret;
+	int ret = 0;
 	int optionsize;
-	u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
-
 	optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
-	cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
 
 	if (check_seq(cm_node, tcph, skb))
-		return;
+		return -EINVAL;
 
 	skb_pull(skb, tcph->doff << 2);
 	inc_sequence = ntohl(tcph->seq);
 	rem_seq = ntohl(tcph->seq);
 	rem_seq_ack =  ntohl(tcph->ack_seq);
 	datasize = skb->len;
-
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_RCVD:
 		/* Passive OPEN */
+		cleanup_retrans_entry(cm_node);
 		ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1);
 		if (ret)
 			break;
 		cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
-		cm_node->tcp_cntxt.loc_seq_num = temp_seq;
-		if (cm_node->tcp_cntxt.rem_ack_num !=
-		    cm_node->tcp_cntxt.loc_seq_num) {
-			nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
-			cleanup_retrans_entry(cm_node);
-			send_reset(cm_node, skb);
-			return;
-		}
 		cm_node->state = NES_CM_STATE_ESTABLISHED;
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
-			cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
-			handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ);
-		 } else { /* rcvd ACK only */
+			handle_rcv_mpa(cm_node, skb);
+		} else  /* rcvd ACK only */
 			dev_kfree_skb_any(skb);
-			cleanup_retrans_entry(cm_node);
-		 }
 		break;
 	case NES_CM_STATE_ESTABLISHED:
 		/* Passive OPEN */
-		/* We expect mpa frame to be received only */
+		cleanup_retrans_entry(cm_node);
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
-			cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
-			handle_rcv_mpa(cm_node, skb,
-				NES_CM_EVENT_MPA_REQ);
+			handle_rcv_mpa(cm_node, skb);
 		} else
 			drop_packet(skb);
 		break;
@@ -1621,29 +1705,39 @@ static void handle_ack_pkt(struct nes_cm
 		cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
-			handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED);
-		} else { /* Could be just an ack pkt.. */
-			cleanup_retrans_entry(cm_node);
+			handle_rcv_mpa(cm_node, skb);
+		} else  /* Could be just an ack pkt.. */
 			dev_kfree_skb_any(skb);
-		}
 		break;
 	case NES_CM_STATE_LISTENING:
 	case NES_CM_STATE_CLOSED:
 		cleanup_retrans_entry(cm_node);
 		send_reset(cm_node, skb);
 		break;
+	case NES_CM_STATE_LAST_ACK:
+	case NES_CM_STATE_CLOSING:
+		cleanup_retrans_entry(cm_node);
+		cm_node->state = NES_CM_STATE_CLOSED;
+		cm_node->cm_id->rem_ref(cm_node->cm_id);
+		rem_ref_cm_node(cm_node->cm_core, cm_node);
+		drop_packet(skb);
+		break;
 	case NES_CM_STATE_FIN_WAIT1:
+		cleanup_retrans_entry(cm_node);
+		drop_packet(skb);
+		cm_node->state = NES_CM_STATE_FIN_WAIT2;
+		break;
 	case NES_CM_STATE_SYN_SENT:
 	case NES_CM_STATE_FIN_WAIT2:
 	case NES_CM_STATE_TSA:
 	case NES_CM_STATE_MPAREQ_RCVD:
-	case NES_CM_STATE_LAST_ACK:
-	case NES_CM_STATE_CLOSING:
 	case NES_CM_STATE_UNKNOWN:
 	default:
+		cleanup_retrans_entry(cm_node);
 		drop_packet(skb);
 		break;
 	}
+	return ret;
 }
 
 
@@ -1748,6 +1842,8 @@ static void process_packet(struct nes_cm
 {
 	enum nes_tcpip_pkt_type	pkt_type = NES_PKT_TYPE_UNKNOWN;
 	struct tcphdr *tcph = tcp_hdr(skb);
+	u32     fin_set = 0;
+	int ret = 0;
 	skb_pull(skb, ip_hdr(skb)->ihl << 2);
 
 	nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
@@ -1760,10 +1856,10 @@ static void process_packet(struct nes_cm
 		pkt_type = NES_PKT_TYPE_SYN;
 		if (tcph->ack)
 			pkt_type = NES_PKT_TYPE_SYNACK;
-	} else if (tcph->fin)
-		pkt_type = NES_PKT_TYPE_FIN;
-	else if (tcph->ack)
+	} else if (tcph->ack)
 		pkt_type = NES_PKT_TYPE_ACK;
+	if (tcph->fin)
+		fin_set = 1;
 
 	switch (pkt_type) {
 	case NES_PKT_TYPE_SYN:
@@ -1773,15 +1869,16 @@ static void process_packet(struct nes_cm
 		handle_synack_pkt(cm_node, skb, tcph);
 		break;
 	case NES_PKT_TYPE_ACK:
-		handle_ack_pkt(cm_node, skb, tcph);
+		ret = handle_ack_pkt(cm_node, skb, tcph);
+		if (fin_set && !ret)
+			handle_fin_pkt(cm_node);
 		break;
 	case NES_PKT_TYPE_RST:
 		handle_rst_pkt(cm_node, skb, tcph);
 		break;
-	case NES_PKT_TYPE_FIN:
-		handle_fin_pkt(cm_node, skb, tcph);
-		break;
 	default:
+		if ((fin_set) && (!check_seq(cm_node, tcph, skb)))
+			handle_fin_pkt(cm_node);
 		drop_packet(skb);
 		break;
 	}
@@ -1891,13 +1988,17 @@ static struct nes_cm_node *mini_cm_conne
 		if (loopbackremotelistener == NULL) {
 			create_event(cm_node, NES_CM_EVENT_ABORTED);
 		} else {
-			atomic_inc(&cm_loopbacks);
 			loopback_cm_info = *cm_info;
 			loopback_cm_info.loc_port = cm_info->rem_port;
 			loopback_cm_info.rem_port = cm_info->loc_port;
 			loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
 			loopbackremotenode = make_cm_node(cm_core, nesvnic,
 				&loopback_cm_info, loopbackremotelistener);
+			if (!loopbackremotenode) {
+				rem_ref_cm_node(cm_node->cm_core, cm_node);
+				return NULL;
+			}
+			atomic_inc(&cm_loopbacks);
 			loopbackremotenode->loopbackpartner = cm_node;
 			loopbackremotenode->tcp_cntxt.rcv_wscale =
 				NES_CM_DEFAULT_RCV_WND_SCALE;
@@ -1925,7 +2026,7 @@ static struct nes_cm_node *mini_cm_conne
 				loopbackremotenode->tcp_cntxt.rcv_wscale;
 			loopbackremotenode->tcp_cntxt.snd_wscale =
 				cm_node->tcp_cntxt.rcv_wscale;
-
+			loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
 			create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
 		}
 		return cm_node;
@@ -1980,7 +2081,11 @@ static int mini_cm_reject(struct nes_cm_
 	struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
 {
 	int ret = 0;
+	int err = 0;
 	int passive_state;
+	struct nes_cm_event event;
+	struct iw_cm_id *cm_id = cm_node->cm_id;
+	struct nes_cm_node *loopback = cm_node->loopbackpartner;
 
 	nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
 		__func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
@@ -1989,12 +2094,38 @@ static int mini_cm_reject(struct nes_cm_
 		return ret;
 	cleanup_retrans_entry(cm_node);
 
-	passive_state = atomic_add_return(1, &cm_node->passive_state);
-	cm_node->state = NES_CM_STATE_CLOSED;
-	if (passive_state == NES_SEND_RESET_EVENT)
+	if (!loopback) {
+		passive_state = atomic_add_return(1, &cm_node->passive_state);
+		if (passive_state == NES_SEND_RESET_EVENT) {
+			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);
+		}
+	} 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);
-	else
-		ret = send_reset(cm_node, NULL);
+		loopback->state = NES_CM_STATE_CLOSING;
+
+		cm_id = loopback->cm_id;
+		rem_ref_cm_node(cm_core, loopback);
+		cm_id->rem_ref(cm_id);
+	}
+
 	return ret;
 }
 
@@ -2031,6 +2162,7 @@ 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:
 	case NES_CM_STATE_UNKNOWN:
 	case NES_CM_STATE_INITED:
@@ -2227,15 +2359,15 @@ static int mini_cm_set(struct nes_cm_cor
 	int ret = 0;
 
 	switch (type) {
-		case NES_CM_SET_PKT_SIZE:
-			cm_core->mtu = value;
-			break;
-		case NES_CM_SET_FREE_PKT_Q_SIZE:
-			cm_core->free_tx_pkt_max = value;
-			break;
-		default:
-			/* unknown set option */
-			ret = -EINVAL;
+	case NES_CM_SET_PKT_SIZE:
+		cm_core->mtu = value;
+		break;
+	case NES_CM_SET_FREE_PKT_Q_SIZE:
+		cm_core->free_tx_pkt_max = value;
+		break;
+	default:
+		/* unknown set option */
+		ret = -EINVAL;
 	}
 
 	return ret;
@@ -2551,6 +2683,7 @@ int nes_accept(struct iw_cm_id *cm_id, s
 	struct ib_mr *ibmr = NULL;
 	struct ib_phys_buf ibphysbuf;
 	struct nes_pd *nespd;
+	u64 tagged_offset;
 
 
 
@@ -2572,7 +2705,6 @@ int nes_accept(struct iw_cm_id *cm_id, s
 	/* associate the node with the QP */
 	nesqp->cm_node = (void *)cm_node;
 	cm_node->nesqp = nesqp;
-	nes_add_ref(&nesqp->ibqp);
 
 	nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
 		nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
@@ -2616,14 +2748,18 @@ int nes_accept(struct iw_cm_id *cm_id, s
 		ibphysbuf.addr = nesqp->ietf_frame_pbase;
 		ibphysbuf.size = conn_param->private_data_len +
 					sizeof(struct ietf_mpa_frame);
+		tagged_offset = (u64)(unsigned long)nesqp->ietf_frame;
 		ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd,
 						&ibphysbuf, 1,
 						IB_ACCESS_LOCAL_WRITE,
-						(u64 *)&nesqp->ietf_frame);
+						&tagged_offset);
 		if (!ibmr) {
 			nes_debug(NES_DBG_CM, "Unable to register memory region"
 					"for lSMM for cm_node = %p \n",
 					cm_node);
+			pci_free_consistent(nesdev->pcidev,
+				nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
+				nesqp->ietf_frame, nesqp->ietf_frame_pbase);
 			return -ENOMEM;
 		}
 
@@ -2643,7 +2779,7 @@ int nes_accept(struct iw_cm_id *cm_id, s
 			sizeof(struct ietf_mpa_frame));
 		set_wqe_64bit_value(wqe->wqe_words,
 					NES_IWARP_SQ_WQE_FRAG0_LOW_IDX,
-					(u64)nesqp->ietf_frame);
+					(u64)(unsigned long)nesqp->ietf_frame);
 		wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
 			cpu_to_le32(conn_param->private_data_len +
 			sizeof(struct ietf_mpa_frame));
@@ -2654,9 +2790,7 @@ int nes_accept(struct iw_cm_id *cm_id, s
 			NES_QPCONTEXT_ORDIRD_WRPDU);
 	} else {
 		nesqp->nesqp_context->ird_ord_sizes |=
-			cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
-			NES_QPCONTEXT_ORDIRD_WRPDU |
-			NES_QPCONTEXT_ORDIRD_ALSMM));
+			cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
 	}
 	nesqp->skip_lsmm = 1;
 
@@ -2742,6 +2876,7 @@ int nes_accept(struct iw_cm_id *cm_id, s
 
 	/* notify OF layer that accept event was successful */
 	cm_id->add_ref(cm_id);
+	nes_add_ref(&nesqp->ibqp);
 
 	cm_event.event = IW_CM_EVENT_ESTABLISHED;
 	cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
@@ -2778,23 +2913,35 @@ int nes_accept(struct iw_cm_id *cm_id, s
 int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
 {
 	struct nes_cm_node *cm_node;
+	struct nes_cm_node *loopback;
+
 	struct nes_cm_core *cm_core;
 
 	atomic_inc(&cm_rejects);
 	cm_node = (struct nes_cm_node *) cm_id->provider_data;
+	loopback = cm_node->loopbackpartner;
 	cm_core = cm_node->cm_core;
+	cm_node->cm_id = cm_id;
 	cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
 
+	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.priv_data, pdata, pdata_len);
+	if (loopback) {
+		memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
+		loopback->mpa_frame.priv_data_len = pdata_len;
+		loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
+				pdata_len;
+	} else {
+		memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
+		cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
+	}
 
-	cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
 	cm_node->mpa_frame.rev = mpa_version;
 	cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
 
-	cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
-
-	return 0;
+	return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
 }
 
 
@@ -2810,6 +2957,7 @@ int nes_connect(struct iw_cm_id *cm_id,
 	struct nes_device *nesdev;
 	struct nes_cm_node *cm_node;
 	struct nes_cm_info cm_info;
+	int apbvt_set = 0;
 
 	ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
 	if (!ibqp)
@@ -2847,9 +2995,11 @@ int nes_connect(struct iw_cm_id *cm_id,
 		conn_param->private_data_len);
 
 	if (cm_id->local_addr.sin_addr.s_addr !=
-		cm_id->remote_addr.sin_addr.s_addr)
+		cm_id->remote_addr.sin_addr.s_addr) {
 		nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
 			PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
+		apbvt_set = 1;
+	}
 
 	/* set up the connection params for the node */
 	cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr);
@@ -2866,8 +3016,7 @@ int nes_connect(struct iw_cm_id *cm_id,
 		conn_param->private_data_len, (void *)conn_param->private_data,
 		&cm_info);
 	if (!cm_node) {
-		if (cm_id->local_addr.sin_addr.s_addr !=
-				cm_id->remote_addr.sin_addr.s_addr)
+		if (apbvt_set)
 			nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
 				PCI_FUNC(nesdev->pcidev->devfn),
 				NES_MANAGE_APBVT_DEL);
@@ -2876,7 +3025,7 @@ int nes_connect(struct iw_cm_id *cm_id,
 		return -ENOMEM;
 	}
 
-	cm_node->apbvt_set = 1;
+	cm_node->apbvt_set = apbvt_set;
 	nesqp->cm_node = cm_node;
 	cm_node->nesqp = nesqp;
 	nes_add_ref(&nesqp->ibqp);
@@ -3303,13 +3452,56 @@ static void cm_event_mpa_req(struct nes_
 	cm_event.remote_addr.sin_family = AF_INET;
 	cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
 	cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
+	cm_event.private_data = cm_node->mpa_frame_buf;
+	cm_event.private_data_len  = (u8) cm_node->mpa_frame_size;
+
+	ret = cm_id->event_handler(cm_id, &cm_event);
+	if (ret)
+		printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
+				__func__, __LINE__, ret);
+	return;
+}
 
-		cm_event.private_data                = cm_node->mpa_frame_buf;
-		cm_event.private_data_len            = (u8) cm_node->mpa_frame_size;
+
+static void cm_event_mpa_reject(struct nes_cm_event *event)
+{
+	struct iw_cm_id   *cm_id;
+	struct iw_cm_event cm_event;
+	struct nes_cm_node *cm_node;
+	int ret;
+
+	cm_node = event->cm_node;
+	if (!cm_node)
+		return;
+	cm_id = cm_node->cm_id;
+
+	atomic_inc(&cm_connect_reqs);
+	nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
+			cm_node, cm_id, jiffies);
+
+	cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
+	cm_event.status = -ECONNREFUSED;
+	cm_event.provider_data = cm_id->provider_data;
+
+	cm_event.local_addr.sin_family = AF_INET;
+	cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
+	cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
+
+	cm_event.remote_addr.sin_family = AF_INET;
+	cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
+	cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
+
+	cm_event.private_data = cm_node->mpa_frame_buf;
+	cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+
+	nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
+			"remove_addr=%08x\n",
+			cm_event.local_addr.sin_addr.s_addr,
+			cm_event.remote_addr.sin_addr.s_addr);
 
 	ret = cm_id->event_handler(cm_id, &cm_event);
 	if (ret)
-		printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
+		printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
 				__func__, __LINE__, ret);
 
 	return;
@@ -3374,6 +3566,14 @@ static void nes_cm_event_handler(struct
 		cm_event_connected(event);
 		nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
 		break;
+	case NES_CM_EVENT_MPA_REJECT:
+		if ((!event->cm_node->cm_id) ||
+				(event->cm_node->state == NES_CM_STATE_TSA))
+			break;
+		cm_event_mpa_reject(event);
+		nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
+		break;
+
 	case NES_CM_EVENT_ABORTED:
 		if ((!event->cm_node->cm_id) ||
 			(event->cm_node->state == NES_CM_STATE_TSA))
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_cm.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_cm.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_cm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_cm.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -39,6 +39,9 @@
 #define NES_MANAGE_APBVT_DEL 0
 #define NES_MANAGE_APBVT_ADD 1
 
+#define NES_MPA_REQUEST_ACCEPT  1
+#define NES_MPA_REQUEST_REJECT  2
+
 /* IETF MPA -- defines, enums, structs */
 #define IEFT_MPA_KEY_REQ  "MPA ID Req Frame"
 #define IEFT_MPA_KEY_REP  "MPA ID Rep Frame"
@@ -146,6 +149,7 @@ struct nes_timer_entry {
 #endif
 #define NES_SHORT_TIME      (10)
 #define NES_LONG_TIME       (2000*HZ/1000)
+#define NES_MAX_TIMEOUT     ((unsigned long) (12*HZ))
 
 #define NES_CM_HASHTABLE_SIZE         1024
 #define NES_CM_TCP_TIMER_INTERVAL     3000
@@ -186,6 +190,7 @@ enum nes_cm_node_state {
 	NES_CM_STATE_ACCEPTING,
 	NES_CM_STATE_MPAREQ_SENT,
 	NES_CM_STATE_MPAREQ_RCVD,
+	NES_CM_STATE_MPAREJ_RCVD,
 	NES_CM_STATE_TSA,
 	NES_CM_STATE_FIN_WAIT1,
 	NES_CM_STATE_FIN_WAIT2,
@@ -278,13 +283,12 @@ struct nes_cm_node {
 	struct nes_timer_entry	*send_entry;
 
 	spinlock_t                retrans_list_lock;
-	struct list_head          recv_list;
-	spinlock_t                recv_list_lock;
+	struct nes_timer_entry  *recv_entry;
 
 	int                       send_write0;
 	union {
 		struct ietf_mpa_frame mpa_frame;
-		u8                    mpa_frame_buf[NES_CM_DEFAULT_MTU];
+		u8                    mpa_frame_buf[MAX_CM_BUFFER];
 	};
 	u16                       mpa_frame_size;
 	struct iw_cm_id           *cm_id;
@@ -295,7 +299,6 @@ struct nes_cm_node {
 	struct nes_vnic           *nesvnic;
 	int                       apbvt_set;
 	int                       accept_pend;
-	int			freed;
 	struct list_head	timer_entry;
 	struct list_head	reset_entry;
 	struct nes_qp		*nesqp;
@@ -326,6 +329,7 @@ enum  nes_cm_event_type {
 	NES_CM_EVENT_MPA_REQ,
 	NES_CM_EVENT_MPA_CONNECT,
 	NES_CM_EVENT_MPA_ACCEPT,
+	NES_CM_EVENT_MPA_REJECT,
 	NES_CM_EVENT_MPA_ESTABLISHED,
 	NES_CM_EVENT_CONNECTED,
 	NES_CM_EVENT_CLOSED,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_context.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_context.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_context.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_context.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  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
@@ -56,10 +56,8 @@
 
 #define QUEUE_DISCONNECTS
 
-#define DRV_BUILD   "1"
-
 #define DRV_NAME    "iw_nes"
-#define DRV_VERSION "1.0 KO Build " DRV_BUILD
+#define DRV_VERSION "1.5.0.0"
 #define PFX         DRV_NAME ": "
 
 /*
@@ -289,8 +287,8 @@ static inline __le32 get_crc_value(struc
 static inline void
 set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
 {
-	wqe_words[index]     = cpu_to_le32((u32) ((unsigned long)value));
-	wqe_words[index + 1] = cpu_to_le32((u32)(upper_32_bits((unsigned long)value)));
+	wqe_words[index]     = cpu_to_le32((u32) value);
+	wqe_words[index + 1] = cpu_to_le32(upper_32_bits(value));
 }
 
 static inline void
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_hw.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_hw.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -46,6 +46,10 @@ static unsigned int nes_lro_max_aggr = N
 module_param(nes_lro_max_aggr, uint, 0444);
 MODULE_PARM_DESC(nes_lro_max_aggr, "NIC LRO max packet aggregation");
 
+static int wide_ppm_offset;
+module_param(wide_ppm_offset, int, 0644);
+MODULE_PARM_DESC(wide_ppm_offset, "Increase CX4 interface clock ppm offset, 0=100ppm (default), 1=300ppm");
+
 static u32 crit_err_count;
 u32 int_mod_timer_init;
 u32 int_mod_cq_depth_256;
@@ -254,6 +258,7 @@ struct nes_adapter *nes_init_adapter(str
 	u32 adapter_size;
 	u32 arp_table_size;
 	u16 vendor_id;
+	u16 device_id;
 	u8  OneG_Mode;
 	u8  func_index;
 
@@ -356,6 +361,13 @@ struct nes_adapter *nes_init_adapter(str
 		return NULL;
 	}
 
+	nesadapter->vendor_id = (((u32) nesadapter->mac_addr_high) << 8) |
+				(nesadapter->mac_addr_low >> 24);
+
+	pci_bus_read_config_word(nesdev->pcidev->bus, nesdev->pcidev->devfn,
+				 PCI_DEVICE_ID, &device_id);
+	nesadapter->vendor_part_id = device_id;
+
 	if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
 							OneG_Mode)) {
 		kfree(nesadapter);
@@ -539,7 +551,7 @@ struct nes_adapter *nes_init_adapter(str
 		}
 		if (int_cnt > 1) {
 			spin_lock_irqsave(&nesadapter->phy_lock, flags);
-			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088);
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8);
 			mh_detected++;
 			reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
 			reset_value |= 0x0000003d;
@@ -564,7 +576,7 @@ struct nes_adapter *nes_init_adapter(str
 					if (++ext_cnt > int_cnt) {
 						spin_lock_irqsave(&nesadapter->phy_lock, flags);
 						nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1,
-								0x0000F0C8);
+								0x0000F088);
 						mh_detected++;
 						reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET);
 						reset_value |= 0x0000003d;
@@ -728,38 +740,50 @@ static int nes_init_serdes(struct nes_de
 {
 	int i;
 	u32 u32temp;
-	u32 serdes_common_control;
+	u32 sds;
 
 	if (hw_rev != NE020_REV) {
 		/* init serdes 0 */
+		if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4))
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA);
+		else
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
 
-		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
 		if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
-			serdes_common_control = nes_read_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL0);
-			serdes_common_control |= 0x000000100;
-			nes_write_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL0,
-					serdes_common_control);
-		} else if (!OneG_Mode) {
-			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
+			sds |= 0x00000100;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds);
 		}
-		if (((port_count > 1) &&
-			(nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
-			((port_count > 2) &&
-			(nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
-			/* init serdes 1 */
+		if (!OneG_Mode)
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
+
+		if (port_count < 2)
+			return 0;
+
+		/* init serdes 1 */
+		if (!(OneG_Mode && (nesadapter->phy_type[1] != NES_PHY_TYPE_PUMA_1G)))
 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
-			if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
-				serdes_common_control = nes_read_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL1);
-				serdes_common_control |= 0x000000100;
-				nes_write_indexed(nesdev,
-					NES_IDX_ETH_SERDES_COMMON_CONTROL1,
-					serdes_common_control);
-			} else if (!OneG_Mode) {
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
-			}
+
+		switch (nesadapter->phy_type[1]) {
+		case NES_PHY_TYPE_ARGUS:
+		case NES_PHY_TYPE_SFP_D:
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000);
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000);
+			break;
+		case NES_PHY_TYPE_CX4:
+			if (wide_ppm_offset)
+				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA);
+			break;
+		case NES_PHY_TYPE_PUMA_1G:
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+			sds |= 0x000000100;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
+		}
+		if (!OneG_Mode) {
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
+			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1);
+			sds &= 0xFFFFFFBF;
+			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, sds);
 		}
 	} else {
 		/* init serdes 0 */
@@ -888,6 +912,12 @@ static void nes_init_csr_ne020(struct ne
 		u32temp &= 0x7fffffff;
 		u32temp |= 0x7fff0010;
 		nes_write_indexed(nesdev, 0x000021f8, u32temp);
+		if (port_count > 1) {
+			u32temp = nes_read_indexed(nesdev, 0x000023f8);
+			u32temp &= 0x7fffffff;
+			u32temp |= 0x7fff0010;
+			nes_write_indexed(nesdev, 0x000023f8, u32temp);
+		}
 	}
 }
 
@@ -1251,203 +1281,163 @@ int nes_init_phy(struct nes_device *nesd
 {
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
 	u32 counter = 0;
-	u32 sds_common_control0;
+	u32 sds;
 	u32 mac_index = nesdev->mac_index;
 	u32 tx_config = 0;
 	u16 phy_data;
 	u32 temp_phy_data = 0;
 	u32 temp_phy_data2 = 0;
-	u32 i = 0;
+	u8  phy_type = nesadapter->phy_type[mac_index];
+	u8  phy_index = nesadapter->phy_index[mac_index];
 
 	if ((nesadapter->OneG_Mode) &&
-	    (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
+	    (phy_type != NES_PHY_TYPE_PUMA_1G)) {
 		nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index);
-		if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) {
-			printk(PFX "%s: Programming mdc config for 1G\n", __func__);
+		if (phy_type == NES_PHY_TYPE_1G) {
 			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
 			tx_config &= 0xFFFFFFE3;
 			tx_config |= 0x04;
 			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
 		}
 
-		nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n",
-				nesadapter->phy_index[mac_index], phy_data);
-		nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000);
+		nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000);
 
 		/* Reset the PHY */
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000);
 		udelay(100);
 		counter = 0;
 		do {
-			nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-			nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
-			if (counter++ > 100) break;
+			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+			if (counter++ > 100)
+				break;
 		} while (phy_data & 0x8000);
 
 		/* Setting no phy loopback */
 		phy_data &= 0xbfff;
 		phy_data |= 0x1140;
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index],  phy_data);
-		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data);
-
-		nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data);
-
-		nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index,  phy_data);
+		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data);
 
 		/* Setting the interrupt mask */
-		nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
-		nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee);
-
-		nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data);
+		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee);
+		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data);
 
 		/* turning on flow control */
-		nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
-		nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
-				(phy_data & ~(0x03E0)) | 0xc00);
-		/* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index],
-				phy_data | 0xc00); */
-		nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data);
+		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00);
+		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data);
 
-		nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
 		/* Clear Half duplex */
-		nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index],
-				phy_data & ~(0x0100));
-		nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data);
-		nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data);
+		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100));
+		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data);
 
-		nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data);
-		nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300);
-	} else {
-		if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) ||
-		    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
-			/* setup 10G MDIO operation */
-			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
-			tx_config &= 0xFFFFFFE3;
-			tx_config |= 0x15;
-			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
-		}
-		if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) {
-			nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
+		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
+		nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300);
 
-			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-			mdelay(10);
-			nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-			temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		return 0;
+	}
 
-			/*
-			 * if firmware is already running (like from a
-			 * driver un-load/load, don't do anything.
-			 */
-			if (temp_phy_data == temp_phy_data2) {
-				/* configure QT2505 AMCC PHY */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0001);
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528);
+	if ((phy_type == NES_PHY_TYPE_IRIS) ||
+	    (phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		/* setup 10G MDIO operation */
+		tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG);
+		tx_config &= 0xFFFFFFE3;
+		tx_config |= 0x15;
+		nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config);
+	}
+	if ((phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		/* 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);
+		udelay(1500);
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+		temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
 
-				/*
-				 * remove micro from reset; chip boots from ROM,
-				 * uploads EEPROM f/w image, uC executes f/w
-				 */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002);
+		if (temp_phy_data != temp_phy_data2)
+			return 0;
 
-				/*
-				 * wait for heart beat to start to
-				 * know loading is done
-				 */
-				counter = 0;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-					temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n");
-						break;
-					}
-					mdelay(100);
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee);
-					temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-				} while ((temp_phy_data2 == temp_phy_data));
+		/* no heartbeat, configure the PHY */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052);
+		if (phy_type == NES_PHY_TYPE_ARGUS) {
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001);
+		} else {
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038);
+			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013);
+		}
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00);
 
-				/*
-				 * wait for tracking to start to know
-				 * f/w is good to go
-				 */
-				counter = 0;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd);
-					temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n");
-						break;
-					}
-					mdelay(1000);
-					/*
-					 * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n",
-					 *			temp_phy_data);
-					 */
-				} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
+		/* setup LEDs */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009);
 
-				/* set LOS Control invert RXLOSB_I_PADINV */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000);
-				/* set LOS Control to mask of RXLOSB_I */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042);
-				/* set LED1 to input mode (LED1 and LED2 share same LED) */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007);
-				/* set LED2 to RX link_status and activity */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A);
-				/* set LED3 to RX link_status */
-				nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528);
 
-				/*
-				 * reset the res-calibration on t2
-				 * serdes; ensures it is stable after
-				 * the amcc phy is stable
-				 */
+		/* Bring PHY out of reset */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002);
 
-				sds_common_control0  = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0);
-				sds_common_control0 |= 0x1;
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+		/* Check for heartbeat */
+		counter = 0;
+		mdelay(690);
+		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+		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");
+				break;
+			}
+			mdelay(1);
+			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee);
+			temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+		} while ((temp_phy_data2 == temp_phy_data));
 
-				/* release the res-calibration reset */
-				sds_common_control0 &= 0xfffffffe;
-				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0);
+		/* wait for tracking */
+		counter = 0;
+		do {
+			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;
+			}
+			mdelay(10);
+		} while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70));
 
-				i = 0;
-				while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
-						&& (i++ < 5000)) {
-					/* mdelay(1); */
-				}
+		/* setup signal integrity */
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002);
+		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063);
 
-				/*
-				 * wait for link train done before moving on,
-				 * or will get an interupt storm
-				 */
-				counter = 0;
-				do {
-					temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 +
-								(0x200 * (nesdev->mac_index & 1)));
-					if (counter++ > 1000) {
-						nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n");
-						break;
-					}
-					mdelay(1);
-				} while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000));
-			}
-		}
+		/* reset serdes */
+		sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				       mac_index * 0x200);
+		sds |= 0x1;
+		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				  mac_index * 0x200, sds);
+		sds &= 0xfffffffe;
+		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 +
+				  mac_index * 0x200, sds);
+
+		counter = 0;
+		while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040)
+				&& (counter++ < 5000))
+			;
 	}
 	return 0;
 }
@@ -1636,7 +1626,6 @@ int nes_init_nic_qp(struct nes_device *n
 	nesvnic->post_cqp_request = nes_post_cqp_request;
 	nesvnic->mcrq_mcast_filter = NULL;
 
-	spin_lock_init(&nesvnic->nic.sq_lock);
 	spin_lock_init(&nesvnic->nic.rq_lock);
 
 	/* setup the RQ */
@@ -2261,6 +2250,8 @@ static void nes_process_aeq(struct nes_d
 
 		if (++head >= aeq_size)
 			head = 0;
+
+		nes_write32(nesdev->regs + NES_AEQ_ALLOC, 1 << 16);
 	}
 	while (1);
 	aeq->aeq_head = head;
@@ -2350,6 +2341,7 @@ static void nes_process_mac_intr(struct
 	u16 temp_phy_data;
 	u32 pcs_val  = 0x0f0f0000;
 	u32 pcs_mask = 0x0f1f0000;
+	u32 cdr_ctrl;
 
 	spin_lock_irqsave(&nesadapter->phy_lock, flags);
 	if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) {
@@ -2464,6 +2456,7 @@ static void nes_process_mac_intr(struct
 				break;
 
 			case NES_PHY_TYPE_ARGUS:
+			case NES_PHY_TYPE_SFP_D:
 				/* clear the alarms */
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008);
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001);
@@ -2474,19 +2467,18 @@ static void nes_process_mac_intr(struct
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004);
 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005);
 				/* check link status */
-				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
 				temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-				u32temp = 100;
-				do {
-					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1);
 
-					phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
-					if ((phy_data == temp_phy_data) || (!(--u32temp)))
-						break;
-					temp_phy_data = phy_data;
-				} while (1);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+				nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
+				phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
+
+				phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
+
 				nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
-					__func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP");
+					__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
 				break;
 
 			case NES_PHY_TYPE_PUMA_1G:
@@ -2502,6 +2494,17 @@ static void nes_process_mac_intr(struct
 		}
 
 		if (phy_data & 0x0004) {
+			if (wide_ppm_offset &&
+			    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+			    (nesadapter->hw_rev != NE020_REV)) {
+				cdr_ctrl = nes_read_indexed(nesdev,
+							    NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+							    mac_index * 0x200);
+				nes_write_indexed(nesdev,
+						  NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+						  mac_index * 0x200,
+						  cdr_ctrl | 0x000F0000);
+			}
 			nesadapter->mac_link_down[mac_index] = 0;
 			list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
 				nes_debug(NES_DBG_PHY, "The Link is UP!!.  linkup was %d\n",
@@ -2516,6 +2519,17 @@ static void nes_process_mac_intr(struct
 				}
 			}
 		} else {
+			if (wide_ppm_offset &&
+			    (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_CX4) &&
+			    (nesadapter->hw_rev != NE020_REV)) {
+				cdr_ctrl = nes_read_indexed(nesdev,
+							    NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+							    mac_index * 0x200);
+				nes_write_indexed(nesdev,
+						  NES_IDX_ETH_SERDES_CDR_CONTROL0 +
+						  mac_index * 0x200,
+						  cdr_ctrl & 0xFFF0FFFF);
+			}
 			nesadapter->mac_link_down[mac_index] = 1;
 			list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
 				nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n",
@@ -2541,7 +2555,7 @@ static void nes_nic_napi_ce_handler(stru
 {
 	struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
 
-	netif_rx_schedule(&nesvnic->napi);
+	napi_schedule(&nesvnic->napi);
 }
 
 
@@ -2622,9 +2636,9 @@ void nes_nic_ce_handler(struct nes_devic
 						} else
 							break;
 					}
-					if (skb)
-						dev_kfree_skb_any(skb);
 				}
+				if (skb)
+					dev_kfree_skb_any(skb);
 				nesnic->sq_tail++;
 				nesnic->sq_tail &= nesnic->sq_size-1;
 				if (sq_cqes > 128) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_hw.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_hw.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+* Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
@@ -35,12 +35,14 @@
 
 #include <linux/inet_lro.h>
 
+#define NES_PHY_TYPE_CX4       1
 #define NES_PHY_TYPE_1G        2
 #define NES_PHY_TYPE_IRIS      3
 #define NES_PHY_TYPE_ARGUS     4
 #define NES_PHY_TYPE_PUMA_1G   5
 #define NES_PHY_TYPE_PUMA_10G  6
 #define NES_PHY_TYPE_GLADIUS   7
+#define NES_PHY_TYPE_SFP_D     8
 
 #define NES_MULTICAST_PF_MAX 8
 
@@ -61,6 +63,7 @@ enum pci_regs {
 	NES_CQ_ACK = 0x0034,
 	NES_WQE_ALLOC = 0x0040,
 	NES_CQE_ALLOC = 0x0044,
+	NES_AEQ_ALLOC = 0x0048
 };
 
 enum indexed_regs {
@@ -875,7 +878,6 @@ struct nes_hw_nic {
 	u8 replenishing_rq;
 	u8 reserved;
 
-	spinlock_t sq_lock;
 	spinlock_t rq_lock;
 };
 
@@ -1147,7 +1149,6 @@ struct nes_ib_device;
 struct nes_vnic {
 	struct nes_ib_device *nesibdev;
 	u64 sq_full;
-	u64 sq_locked;
 	u64 tso_requests;
 	u64 segmented_tso_requests;
 	u64 linearized_skbs;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_nic.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_nic.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_nic.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -111,7 +111,7 @@ static int nes_netdev_poll(struct napi_s
 	nes_nic_ce_handler(nesdev, nescq);
 
 	if (nescq->cqes_pending == 0) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		/* clear out completed cqes and arm */
 		nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
 				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
@@ -400,8 +400,7 @@ static int nes_nic_send(struct sk_buff *
 	if (skb_headlen(skb) == skb->len) {
 		if (skb_headlen(skb) <= NES_FIRST_FRAG_SIZE) {
 			nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_2_1_IDX] = 0;
-			nesnic->tx_skb[nesnic->sq_head] = NULL;
-			dev_kfree_skb(skb);
+			nesnic->tx_skb[nesnic->sq_head] = skb;
 		}
 	} else {
 		/* Deal with Fragments */
@@ -453,7 +452,6 @@ static int nes_netdev_start_xmit(struct
 	u32 wqe_count=1;
 	u32 send_rc;
 	struct iphdr *iph;
-	unsigned long flags;
 	__le16 *wqe_fragment_length;
 	u32 nr_frags;
 	u32 original_first_length;
@@ -480,13 +478,6 @@ static int nes_netdev_start_xmit(struct
 	if (netif_queue_stopped(netdev))
 		return NETDEV_TX_BUSY;
 
-	local_irq_save(flags);
-	if (!spin_trylock(&nesnic->sq_lock)) {
-		local_irq_restore(flags);
-		nesvnic->sq_locked++;
-		return NETDEV_TX_LOCKED;
-	}
-
 	/* Check if SQ is full */
 	if ((((nesnic->sq_tail+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) == 1) {
 		if (!netif_queue_stopped(netdev)) {
@@ -498,7 +489,6 @@ static int nes_netdev_start_xmit(struct
 			}
 		}
 		nesvnic->sq_full++;
-		spin_unlock_irqrestore(&nesnic->sq_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -531,7 +521,6 @@ sq_no_longer_full:
 					}
 				}
 				nesvnic->sq_full++;
-				spin_unlock_irqrestore(&nesnic->sq_lock, flags);
 				nes_debug(NES_DBG_NIC_TX, "%s: HNIC SQ full- TSO request has too many frags!\n",
 						netdev->name);
 				return NETDEV_TX_BUSY;
@@ -656,17 +645,13 @@ tso_sq_no_longer_full:
 			skb_set_transport_header(skb, hoffset);
 			skb_set_network_header(skb, nhoffset);
 			send_rc = nes_nic_send(skb, netdev);
-			if (send_rc != NETDEV_TX_OK) {
-				spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+			if (send_rc != NETDEV_TX_OK)
 				return NETDEV_TX_OK;
-			}
 		}
 	} else {
 		send_rc = nes_nic_send(skb, netdev);
-		if (send_rc != NETDEV_TX_OK) {
-			spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+		if (send_rc != NETDEV_TX_OK)
 			return NETDEV_TX_OK;
-		}
 	}
 
 	barrier();
@@ -676,7 +661,6 @@ tso_sq_no_longer_full:
 				(wqe_count << 24) | (1 << 23) | nesvnic->nic.qp_id);
 
 	netdev->trans_start = jiffies;
-	spin_unlock_irqrestore(&nesnic->sq_lock, flags);
 
 	return NETDEV_TX_OK;
 }
@@ -1012,7 +996,6 @@ static const char nes_ethtool_stringset[
 	"Pause Frames Received",
 	"Internal Routing Errors",
 	"SQ SW Dropped SKBs",
-	"SQ Locked",
 	"SQ Full",
 	"Segmented TSO Requests",
 	"Rx Symbol Errors",
@@ -1129,16 +1112,17 @@ static void nes_netdev_get_ethtool_stats
 	struct nes_device *nesdev = nesvnic->nesdev;
 	u32 nic_count;
 	u32 u32temp;
+	u32 index = 0;
 
 	target_ethtool_stats->n_stats = NES_ETHTOOL_STAT_COUNT;
-	target_stat_values[0] = nesvnic->nesdev->link_status_interrupts;
-	target_stat_values[1] = nesvnic->linearized_skbs;
-	target_stat_values[2] = nesvnic->tso_requests;
+	target_stat_values[index] = nesvnic->nesdev->link_status_interrupts;
+	target_stat_values[++index] = nesvnic->linearized_skbs;
+	target_stat_values[++index] = nesvnic->tso_requests;
 
 	u32temp = nes_read_indexed(nesdev,
 			NES_IDX_MAC_TX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
 	nesvnic->nesdev->mac_pause_frames_sent += u32temp;
-	target_stat_values[3] = nesvnic->nesdev->mac_pause_frames_sent;
+	target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_sent;
 
 	u32temp = nes_read_indexed(nesdev,
 			NES_IDX_MAC_RX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
@@ -1209,60 +1193,59 @@ static void nes_netdev_get_ethtool_stats
 		nesvnic->endnode_ipv4_tcp_retransmits += u32temp;
 	}
 
-	target_stat_values[4] = nesvnic->nesdev->mac_pause_frames_received;
-	target_stat_values[5] = nesdev->nesadapter->nic_rx_eth_route_err;
-	target_stat_values[6] = nesvnic->tx_sw_dropped;
-	target_stat_values[7] = nesvnic->sq_locked;
-	target_stat_values[8] = nesvnic->sq_full;
-	target_stat_values[9] = nesvnic->segmented_tso_requests;
-	target_stat_values[10] = nesvnic->nesdev->mac_rx_symbol_err_frames;
-	target_stat_values[11] = nesvnic->nesdev->mac_rx_jabber_frames;
-	target_stat_values[12] = nesvnic->nesdev->mac_rx_oversized_frames;
-	target_stat_values[13] = nesvnic->nesdev->mac_rx_short_frames;
-	target_stat_values[14] = nesvnic->endnode_nstat_rx_discard;
-	target_stat_values[15] = nesvnic->endnode_nstat_rx_octets;
-	target_stat_values[16] = nesvnic->endnode_nstat_rx_frames;
-	target_stat_values[17] = nesvnic->endnode_nstat_tx_octets;
-	target_stat_values[18] = nesvnic->endnode_nstat_tx_frames;
-	target_stat_values[19] = mh_detected;
-	target_stat_values[20] = mh_pauses_sent;
-	target_stat_values[21] = nesvnic->endnode_ipv4_tcp_retransmits;
-	target_stat_values[22] = atomic_read(&cm_connects);
-	target_stat_values[23] = atomic_read(&cm_accepts);
-	target_stat_values[24] = atomic_read(&cm_disconnects);
-	target_stat_values[25] = atomic_read(&cm_connecteds);
-	target_stat_values[26] = atomic_read(&cm_connect_reqs);
-	target_stat_values[27] = atomic_read(&cm_rejects);
-	target_stat_values[28] = atomic_read(&mod_qp_timouts);
-	target_stat_values[29] = atomic_read(&qps_created);
-	target_stat_values[30] = atomic_read(&sw_qps_destroyed);
-	target_stat_values[31] = atomic_read(&qps_destroyed);
-	target_stat_values[32] = atomic_read(&cm_closes);
-	target_stat_values[33] = cm_packets_sent;
-	target_stat_values[34] = cm_packets_bounced;
-	target_stat_values[35] = cm_packets_created;
-	target_stat_values[36] = cm_packets_received;
-	target_stat_values[37] = cm_packets_dropped;
-	target_stat_values[38] = cm_packets_retrans;
-	target_stat_values[39] = cm_listens_created;
-	target_stat_values[40] = cm_listens_destroyed;
-	target_stat_values[41] = cm_backlog_drops;
-	target_stat_values[42] = atomic_read(&cm_loopbacks);
-	target_stat_values[43] = atomic_read(&cm_nodes_created);
-	target_stat_values[44] = atomic_read(&cm_nodes_destroyed);
-	target_stat_values[45] = atomic_read(&cm_accel_dropped_pkts);
-	target_stat_values[46] = atomic_read(&cm_resets_recvd);
-	target_stat_values[47] = int_mod_timer_init;
-	target_stat_values[48] = int_mod_cq_depth_1;
-	target_stat_values[49] = int_mod_cq_depth_4;
-	target_stat_values[50] = int_mod_cq_depth_16;
-	target_stat_values[51] = int_mod_cq_depth_24;
-	target_stat_values[52] = int_mod_cq_depth_32;
-	target_stat_values[53] = int_mod_cq_depth_128;
-	target_stat_values[54] = int_mod_cq_depth_256;
-	target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated;
-	target_stat_values[56] = nesvnic->lro_mgr.stats.flushed;
-	target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc;
+	target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_received;
+	target_stat_values[++index] = nesdev->nesadapter->nic_rx_eth_route_err;
+	target_stat_values[++index] = nesvnic->tx_sw_dropped;
+	target_stat_values[++index] = nesvnic->sq_full;
+	target_stat_values[++index] = nesvnic->segmented_tso_requests;
+	target_stat_values[++index] = nesvnic->nesdev->mac_rx_symbol_err_frames;
+	target_stat_values[++index] = nesvnic->nesdev->mac_rx_jabber_frames;
+	target_stat_values[++index] = nesvnic->nesdev->mac_rx_oversized_frames;
+	target_stat_values[++index] = nesvnic->nesdev->mac_rx_short_frames;
+	target_stat_values[++index] = nesvnic->endnode_nstat_rx_discard;
+	target_stat_values[++index] = nesvnic->endnode_nstat_rx_octets;
+	target_stat_values[++index] = nesvnic->endnode_nstat_rx_frames;
+	target_stat_values[++index] = nesvnic->endnode_nstat_tx_octets;
+	target_stat_values[++index] = nesvnic->endnode_nstat_tx_frames;
+	target_stat_values[++index] = mh_detected;
+	target_stat_values[++index] = mh_pauses_sent;
+	target_stat_values[++index] = nesvnic->endnode_ipv4_tcp_retransmits;
+	target_stat_values[++index] = atomic_read(&cm_connects);
+	target_stat_values[++index] = atomic_read(&cm_accepts);
+	target_stat_values[++index] = atomic_read(&cm_disconnects);
+	target_stat_values[++index] = atomic_read(&cm_connecteds);
+	target_stat_values[++index] = atomic_read(&cm_connect_reqs);
+	target_stat_values[++index] = atomic_read(&cm_rejects);
+	target_stat_values[++index] = atomic_read(&mod_qp_timouts);
+	target_stat_values[++index] = atomic_read(&qps_created);
+	target_stat_values[++index] = atomic_read(&sw_qps_destroyed);
+	target_stat_values[++index] = atomic_read(&qps_destroyed);
+	target_stat_values[++index] = atomic_read(&cm_closes);
+	target_stat_values[++index] = cm_packets_sent;
+	target_stat_values[++index] = cm_packets_bounced;
+	target_stat_values[++index] = cm_packets_created;
+	target_stat_values[++index] = cm_packets_received;
+	target_stat_values[++index] = cm_packets_dropped;
+	target_stat_values[++index] = cm_packets_retrans;
+	target_stat_values[++index] = cm_listens_created;
+	target_stat_values[++index] = cm_listens_destroyed;
+	target_stat_values[++index] = cm_backlog_drops;
+	target_stat_values[++index] = atomic_read(&cm_loopbacks);
+	target_stat_values[++index] = atomic_read(&cm_nodes_created);
+	target_stat_values[++index] = atomic_read(&cm_nodes_destroyed);
+	target_stat_values[++index] = atomic_read(&cm_accel_dropped_pkts);
+	target_stat_values[++index] = atomic_read(&cm_resets_recvd);
+	target_stat_values[++index] = int_mod_timer_init;
+	target_stat_values[++index] = int_mod_cq_depth_1;
+	target_stat_values[++index] = int_mod_cq_depth_4;
+	target_stat_values[++index] = int_mod_cq_depth_16;
+	target_stat_values[++index] = int_mod_cq_depth_24;
+	target_stat_values[++index] = int_mod_cq_depth_32;
+	target_stat_values[++index] = int_mod_cq_depth_128;
+	target_stat_values[++index] = int_mod_cq_depth_256;
+	target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated;
+	target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed;
+	target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc;
 
 }
 
@@ -1443,49 +1426,55 @@ static int nes_netdev_get_settings(struc
 	struct nes_vnic *nesvnic = netdev_priv(netdev);
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
+	u32 mac_index = nesdev->mac_index;
+	u8 phy_type = nesadapter->phy_type[mac_index];
+	u8 phy_index = nesadapter->phy_index[mac_index];
 	u16 phy_data;
 
 	et_cmd->duplex = DUPLEX_FULL;
 	et_cmd->port   = PORT_MII;
+	et_cmd->maxtxpkt = 511;
+	et_cmd->maxrxpkt = 511;
 
 	if (nesadapter->OneG_Mode) {
 		et_cmd->speed = SPEED_1000;
-		if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) {
+		if (phy_type == NES_PHY_TYPE_PUMA_1G) {
 			et_cmd->supported   = SUPPORTED_1000baseT_Full;
 			et_cmd->advertising = ADVERTISED_1000baseT_Full;
 			et_cmd->autoneg     = AUTONEG_DISABLE;
 			et_cmd->transceiver = XCVR_INTERNAL;
-			et_cmd->phy_address = nesdev->mac_index;
+			et_cmd->phy_address = mac_index;
 		} else {
-			et_cmd->supported   = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
-			et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg;
-			nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data);
+			et_cmd->supported   = SUPPORTED_1000baseT_Full
+					    | SUPPORTED_Autoneg;
+			et_cmd->advertising = ADVERTISED_1000baseT_Full
+					    | ADVERTISED_Autoneg;
+			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data);
 			if (phy_data & 0x1000)
 				et_cmd->autoneg = AUTONEG_ENABLE;
 			else
 				et_cmd->autoneg = AUTONEG_DISABLE;
 			et_cmd->transceiver = XCVR_EXTERNAL;
-			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
+			et_cmd->phy_address = phy_index;
 		}
+		return 0;
+	}
+	if ((phy_type == NES_PHY_TYPE_IRIS) ||
+	    (phy_type == NES_PHY_TYPE_ARGUS) ||
+	    (phy_type == NES_PHY_TYPE_SFP_D)) {
+		et_cmd->transceiver = XCVR_EXTERNAL;
+		et_cmd->port        = PORT_FIBRE;
+		et_cmd->supported   = SUPPORTED_FIBRE;
+		et_cmd->advertising = ADVERTISED_FIBRE;
+		et_cmd->phy_address = phy_index;
 	} else {
-		if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) ||
-		    (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) {
-			et_cmd->transceiver = XCVR_EXTERNAL;
-			et_cmd->port        = PORT_FIBRE;
-			et_cmd->supported   = SUPPORTED_FIBRE;
-			et_cmd->advertising = ADVERTISED_FIBRE;
-			et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
-		} else {
-			et_cmd->transceiver = XCVR_INTERNAL;
-			et_cmd->supported   = SUPPORTED_10000baseT_Full;
-			et_cmd->advertising = ADVERTISED_10000baseT_Full;
-			et_cmd->phy_address = nesdev->mac_index;
-		}
-		et_cmd->speed = SPEED_10000;
-		et_cmd->autoneg = AUTONEG_DISABLE;
+		et_cmd->transceiver = XCVR_INTERNAL;
+		et_cmd->supported   = SUPPORTED_10000baseT_Full;
+		et_cmd->advertising = ADVERTISED_10000baseT_Full;
+		et_cmd->phy_address = mac_index;
 	}
-	et_cmd->maxtxpkt = 511;
-	et_cmd->maxrxpkt = 511;
+	et_cmd->speed = SPEED_10000;
+	et_cmd->autoneg = AUTONEG_DISABLE;
 	return 0;
 }
 
@@ -1568,6 +1557,19 @@ static void nes_netdev_vlan_rx_register(
 	spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
 }
 
+static const struct net_device_ops nes_netdev_ops = {
+	.ndo_open 		= nes_netdev_open,
+	.ndo_stop		= nes_netdev_stop,
+	.ndo_start_xmit 	= nes_netdev_start_xmit,
+	.ndo_get_stats		= nes_netdev_get_stats,
+	.ndo_tx_timeout 	= nes_netdev_tx_timeout,
+	.ndo_set_mac_address	= nes_netdev_set_mac_address,
+	.ndo_set_multicast_list = nes_netdev_set_multicast_list,
+	.ndo_change_mtu		= nes_netdev_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_vlan_rx_register 	= nes_netdev_vlan_rx_register,
+};
 
 /**
  * nes_netdev_init - initialize network device
@@ -1576,7 +1578,7 @@ struct net_device *nes_netdev_init(struc
 		void __iomem *mmio_addr)
 {
 	u64 u64temp;
-	struct nes_vnic *nesvnic = NULL;
+	struct nes_vnic *nesvnic;
 	struct net_device *netdev;
 	struct nic_qp_map *curr_qp_map;
 	u32 u32temp;
@@ -1588,22 +1590,12 @@ struct net_device *nes_netdev_init(struc
 		printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
 		return NULL;
 	}
+	nesvnic = netdev_priv(netdev);
 
 	nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
 
 	SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
 
-	nesvnic = netdev_priv(netdev);
-	memset(nesvnic, 0, sizeof(*nesvnic));
-
-	netdev->open = nes_netdev_open;
-	netdev->stop = nes_netdev_stop;
-	netdev->hard_start_xmit = nes_netdev_start_xmit;
-	netdev->get_stats = nes_netdev_get_stats;
-	netdev->tx_timeout = nes_netdev_tx_timeout;
-	netdev->set_mac_address = nes_netdev_set_mac_address;
-	netdev->set_multicast_list = nes_netdev_set_multicast_list;
-	netdev->change_mtu = nes_netdev_change_mtu;
 	netdev->watchdog_timeo = NES_TX_TIMEOUT;
 	netdev->irq = nesdev->pcidev->irq;
 	netdev->mtu = ETH_DATA_LEN;
@@ -1611,12 +1603,11 @@ struct net_device *nes_netdev_init(struc
 	netdev->addr_len = ETH_ALEN;
 	netdev->type = ARPHRD_ETHER;
 	netdev->features = NETIF_F_HIGHDMA;
+	netdev->netdev_ops = &nes_netdev_ops;
 	netdev->ethtool_ops = &nes_ethtool_ops;
 	netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
 	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
-	netdev->features |= NETIF_F_LLTX;
 
 	/* Fill in the port structure */
 	nesvnic->netdev = netdev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_user.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_user.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_user.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_user.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect.  All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  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.
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_utils.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_utils.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_utils.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_verbs.c linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_verbs.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_verbs.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -551,6 +551,7 @@ static int nes_dealloc_fmr(struct ib_fmr
 	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) {
@@ -572,7 +573,9 @@ static int nes_dealloc_fmr(struct ib_fmr
 	nesmr->ibmw.rkey = ibfmr->rkey;
 	nesmr->ibmw.uobject = NULL;
 
-	if (nesfmr->nesmr.pbls_used != 0) {
+	rc = nes_dealloc_mw(&nesmr->ibmw);
+
+	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;
@@ -584,7 +587,7 @@ static int nes_dealloc_fmr(struct ib_fmr
 		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
 	}
 
-	return nes_dealloc_mw(&nesmr->ibmw);
+	return rc;
 }
 
 
@@ -1624,6 +1627,7 @@ static struct ib_cq *nes_create_cq(struc
 				nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff;
 			else
 				nescq->hw_cq.cq_number = nesvnic->mcrq_qp_id + nes_ucontext->mcrqf-1;
+			nescq->mcrqf = nes_ucontext->mcrqf;
 			nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		}
 		nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n",
@@ -1679,6 +1683,12 @@ static struct ib_cq *nes_create_cq(struc
 		if (!context)
 			pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 					nescq->hw_cq.cq_pbase);
+		else {
+			pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+					    nespbl->pbl_vbase, nespbl->pbl_pbase);
+			kfree(nespbl);
+		}
+
 		nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		kfree(nescq);
 		return ERR_PTR(-ENOMEM);
@@ -1702,6 +1712,11 @@ static struct ib_cq *nes_create_cq(struc
 				if (!context)
 					pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 							nescq->hw_cq.cq_pbase);
+				else {
+					pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+							    nespbl->pbl_vbase, nespbl->pbl_pbase);
+					kfree(nespbl);
+				}
 				nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 				kfree(nescq);
 				return ERR_PTR(-ENOMEM);
@@ -1719,6 +1734,11 @@ static struct ib_cq *nes_create_cq(struc
 				if (!context)
 					pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 							nescq->hw_cq.cq_pbase);
+				else {
+					pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+							    nespbl->pbl_vbase, nespbl->pbl_pbase);
+					kfree(nespbl);
+				}
 				nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 				kfree(nescq);
 				return ERR_PTR(-ENOMEM);
@@ -1771,6 +1791,11 @@ static struct ib_cq *nes_create_cq(struc
 		if (!context)
 			pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
 					nescq->hw_cq.cq_pbase);
+		else {
+			pci_free_consistent(nesdev->pcidev, nespbl->pbl_size,
+					    nespbl->pbl_vbase, nespbl->pbl_pbase);
+			kfree(nespbl);
+		}
 		nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 		kfree(nescq);
 		return ERR_PTR(-EIO);
@@ -1852,7 +1877,9 @@ static int nes_destroy_cq(struct ib_cq *
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode);
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX,
 		(nescq->hw_cq.cq_number | ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 16)));
-	nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number);
+	if (!nescq->mcrqf)
+		nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number);
+
 	atomic_set(&cqp_request->refcount, 2);
 	nes_post_cqp_request(nesdev, cqp_request);
 
@@ -1886,21 +1913,74 @@ static int nes_destroy_cq(struct ib_cq *
 	return ret;
 }
 
+/**
+ * root_256
+ */
+static u32 root_256(struct nes_device *nesdev,
+		    struct nes_root_vpbl *root_vpbl,
+		    struct nes_root_vpbl *new_root,
+		    u16 pbl_count_4k)
+{
+	u64 leaf_pbl;
+	int i, j, k;
+
+	if (pbl_count_4k == 1) {
+		new_root->pbl_vbase = pci_alloc_consistent(nesdev->pcidev,
+						512, &new_root->pbl_pbase);
+
+		if (new_root->pbl_vbase == NULL)
+			return 0;
+
+		leaf_pbl = (u64)root_vpbl->pbl_pbase;
+		for (i = 0; i < 16; i++) {
+			new_root->pbl_vbase[i].pa_low =
+				cpu_to_le32((u32)leaf_pbl);
+			new_root->pbl_vbase[i].pa_high =
+				cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+			leaf_pbl += 256;
+		}
+	} else {
+		for (i = 3; i >= 0; i--) {
+			j = i * 16;
+			root_vpbl->pbl_vbase[j] = root_vpbl->pbl_vbase[i];
+			leaf_pbl = le32_to_cpu(root_vpbl->pbl_vbase[j].pa_low) +
+			    (((u64)le32_to_cpu(root_vpbl->pbl_vbase[j].pa_high))
+				<< 32);
+			for (k = 1; k < 16; k++) {
+				leaf_pbl += 256;
+				root_vpbl->pbl_vbase[j + k].pa_low =
+						cpu_to_le32((u32)leaf_pbl);
+				root_vpbl->pbl_vbase[j + k].pa_high =
+				    cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+			}
+		}
+	}
+
+	return 1;
+}
+
 
 /**
  * nes_reg_mr
  */
 static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
 		u32 stag, u64 region_length, struct nes_root_vpbl *root_vpbl,
-		dma_addr_t single_buffer, u16 pbl_count, u16 residual_page_count,
-		int acc, u64 *iova_start)
+		dma_addr_t single_buffer, u16 pbl_count_4k,
+		u16 residual_page_count_4k, int acc, u64 *iova_start,
+		u16 *actual_pbl_cnt, u8 *used_4k_pbls)
 {
 	struct nes_hw_cqp_wqe *cqp_wqe;
 	struct nes_cqp_request *cqp_request;
 	unsigned long flags;
 	int ret;
 	struct nes_adapter *nesadapter = nesdev->nesadapter;
-	/* int count; */
+	uint pg_cnt = 0;
+	u16 pbl_count_256 = 0;
+	u16 pbl_count = 0;
+	u8  use_256_pbls = 0;
+	u8  use_4k_pbls = 0;
+	u16 use_two_level = (pbl_count_4k > 1) ? 1 : 0;
+	struct nes_root_vpbl new_root = {0, 0, 0};
 	u32 opcode = 0;
 	u16 major_code;
 
@@ -1913,41 +1993,70 @@ static int nes_reg_mr(struct nes_device
 	cqp_request->waiting = 1;
 	cqp_wqe = &cqp_request->cqp_wqe;
 
-	spin_lock_irqsave(&nesadapter->pbl_lock, flags);
-	/* track PBL resources */
-	if (pbl_count != 0) {
-		if (pbl_count > 1) {
-			/* Two level PBL */
-			if ((pbl_count+1) > nesadapter->free_4kpbl) {
-				nes_debug(NES_DBG_MR, "Out of 4KB Pbls for two level request.\n");
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				nes_free_cqp_request(nesdev, cqp_request);
-				return -ENOMEM;
-			} else {
-				nesadapter->free_4kpbl -= pbl_count+1;
-			}
-		} else if (residual_page_count > 32) {
-			if (pbl_count > nesadapter->free_4kpbl) {
-				nes_debug(NES_DBG_MR, "Out of 4KB Pbls.\n");
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				nes_free_cqp_request(nesdev, cqp_request);
-				return -ENOMEM;
-			} else {
-				nesadapter->free_4kpbl -= pbl_count;
+	if (pbl_count_4k) {
+		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+
+		pg_cnt = ((pbl_count_4k - 1) * 512) + residual_page_count_4k;
+		pbl_count_256 = (pg_cnt + 31) / 32;
+		if (pg_cnt <= 32) {
+			if (pbl_count_256 <= nesadapter->free_256pbl)
+				use_256_pbls = 1;
+			else if (pbl_count_4k <= nesadapter->free_4kpbl)
+				use_4k_pbls = 1;
+		} else if (pg_cnt <= 2048) {
+			if (((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) &&
+			    (nesadapter->free_4kpbl > (nesadapter->max_4kpbl >> 1))) {
+				use_4k_pbls = 1;
+			} else if ((pbl_count_256 + 1) <= nesadapter->free_256pbl) {
+				use_256_pbls = 1;
+				use_two_level = 1;
+			} else if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+				use_4k_pbls = 1;
 			}
 		} else {
-			if (pbl_count > nesadapter->free_256pbl) {
-				nes_debug(NES_DBG_MR, "Out of 256B Pbls.\n");
-				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
-				nes_free_cqp_request(nesdev, cqp_request);
-				return -ENOMEM;
-			} else {
-				nesadapter->free_256pbl -= pbl_count;
-			}
+			if ((pbl_count_4k + 1) <= nesadapter->free_4kpbl)
+				use_4k_pbls = 1;
+		}
+
+		if (use_256_pbls) {
+			pbl_count = pbl_count_256;
+			nesadapter->free_256pbl -= pbl_count + use_two_level;
+		} else if (use_4k_pbls) {
+			pbl_count =  pbl_count_4k;
+			nesadapter->free_4kpbl -= pbl_count + use_two_level;
+		} else {
+			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;
 		}
+
+		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
 	}
 
-	spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+	if (use_256_pbls && use_two_level) {
+		if (root_256(nesdev, root_vpbl, &new_root, pbl_count_4k) == 1) {
+			if (new_root.pbl_pbase != 0)
+				root_vpbl = &new_root;
+		} else {
+			spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+			nesadapter->free_256pbl += pbl_count_256 + use_two_level;
+			use_256_pbls = 0;
+
+			if (pbl_count_4k == 1)
+				use_two_level = 0;
+			pbl_count = pbl_count_4k;
+
+			if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+				nesadapter->free_4kpbl -= pbl_count + use_two_level;
+				use_4k_pbls = 1;
+			}
+			spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+
+			if (use_4k_pbls == 0)
+				return -ENOMEM;
+		}
+	}
 
 	opcode = NES_CQP_REGISTER_STAG | NES_CQP_STAG_RIGHTS_LOCAL_READ |
 					NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR;
@@ -1976,10 +2085,9 @@ static int nes_reg_mr(struct nes_device
 	} else {
 		set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, root_vpbl->pbl_pbase);
 		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, pbl_count);
-		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX,
-				(((pbl_count - 1) * 4096) + (residual_page_count*8)));
+		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (pg_cnt * 8));
 
-		if ((pbl_count > 1) || (residual_page_count > 32))
+		if (use_4k_pbls)
 			cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE);
 	}
 	barrier();
@@ -1996,13 +2104,25 @@ static int nes_reg_mr(struct nes_device
 	major_code = cqp_request->major_code;
 	nes_put_cqp_request(nesdev, cqp_request);
 
+	if ((!ret || major_code) && pbl_count != 0) {
+		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+		if (use_256_pbls)
+			nesadapter->free_256pbl += pbl_count + use_two_level;
+		else if (use_4k_pbls)
+			nesadapter->free_4kpbl += pbl_count + use_two_level;
+		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+	}
+	if (new_root.pbl_pbase)
+		pci_free_consistent(nesdev->pcidev, 512, new_root.pbl_vbase,
+				    new_root.pbl_pbase);
+
 	if (!ret)
 		return -ETIME;
 	else if (major_code)
 		return -EIO;
-	else
-		return 0;
 
+	*actual_pbl_cnt = pbl_count + use_two_level;
+	*used_4k_pbls = use_4k_pbls;
 	return 0;
 }
 
@@ -2025,6 +2145,7 @@ static struct ib_mr *nes_reg_phys_mr(str
 	struct nes_root_vpbl root_vpbl;
 	u32 stag;
 	u32 i;
+	unsigned long mask;
 	u32 stag_index = 0;
 	u32 next_stag_index = 0;
 	u32 driver_key = 0;
@@ -2053,6 +2174,9 @@ static struct ib_mr *nes_reg_phys_mr(str
 		return ERR_PTR(-E2BIG);
 	}
 
+	if ((buffer_list[0].addr ^ *iova_start) & ~PAGE_MASK)
+		return ERR_PTR(-EINVAL);
+
 	err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, nesadapter->max_mr,
 			&stag_index, &next_stag_index);
 	if (err) {
@@ -2118,19 +2242,16 @@ static struct ib_mr *nes_reg_phys_mr(str
 			root_pbl_index++;
 			cur_pbl_index = 0;
 		}
-		if (buffer_list[i].addr & ~PAGE_MASK) {
-			/* TODO: Unwind allocated buffers */
-			nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-			nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n",
-					(unsigned int) buffer_list[i].addr);
-			ibmr = ERR_PTR(-EINVAL);
-			kfree(nesmr);
-			goto reg_phys_err;
-		}
 
-		if (!buffer_list[i].size) {
+		mask = !buffer_list[i].size;
+		if (i != 0)
+			mask |= buffer_list[i].addr;
+		if (i != num_phys_buf - 1)
+			mask |= buffer_list[i].addr + buffer_list[i].size;
+
+		if (mask & ~PAGE_MASK) {
 			nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-			nes_debug(NES_DBG_MR, "Invalid Buffer Size\n");
+			nes_debug(NES_DBG_MR, "Invalid buffer addr or size\n");
 			ibmr = ERR_PTR(-EINVAL);
 			kfree(nesmr);
 			goto reg_phys_err;
@@ -2141,7 +2262,7 @@ static struct ib_mr *nes_reg_phys_mr(str
 			if ((buffer_list[i-1].addr+PAGE_SIZE) != buffer_list[i].addr)
 				single_page = 0;
 		}
-		vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr);
+		vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr & PAGE_MASK);
 		vpbl.pbl_vbase[cur_pbl_index++].pa_high =
 				cpu_to_le32((u32)((((u64)buffer_list[i].addr) >> 32)));
 	}
@@ -2154,8 +2275,6 @@ static struct ib_mr *nes_reg_phys_mr(str
 			" length = 0x%016lX, index = 0x%08X\n",
 			stag, (unsigned long)*iova_start, (unsigned long)region_length, stag_index);
 
-	region_length -= (*iova_start)&PAGE_MASK;
-
 	/* Make the leaf PBL the root if only one PBL */
 	if (root_pbl_index == 1) {
 		root_vpbl.pbl_pbase = vpbl.pbl_pbase;
@@ -2167,18 +2286,14 @@ static struct ib_mr *nes_reg_phys_mr(str
 		pbl_count = root_pbl_index;
 	}
 	ret = nes_reg_mr(nesdev, nespd, stag, region_length, &root_vpbl,
-			buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start);
+			buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start,
+			&nesmr->pbls_used, &nesmr->pbl_4k);
 
 	if (ret == 0) {
 		nesmr->ibmr.rkey = stag;
 		nesmr->ibmr.lkey = stag;
 		nesmr->mode = IWNES_MEMREG_TYPE_MEM;
 		ibmr = &nesmr->ibmr;
-		nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
-		nesmr->pbls_used = pbl_count;
-		if (pbl_count > 1) {
-			nesmr->pbls_used++;
-		}
 	} else {
 		kfree(nesmr);
 		ibmr = ERR_PTR(-ENOMEM);
@@ -2456,8 +2571,9 @@ static struct ib_mr *nes_reg_user_mr(str
 					stag, (unsigned int)iova_start,
 					(unsigned int)region_length, stag_index,
 					(unsigned long long)region->length, pbl_count);
-			ret = nes_reg_mr( nesdev, nespd, stag, region->length, &root_vpbl,
-					first_dma_addr, pbl_count, (u16)cur_pbl_index, acc, &iova_start);
+			ret = nes_reg_mr(nesdev, nespd, stag, region->length, &root_vpbl,
+					 first_dma_addr, pbl_count, (u16)cur_pbl_index, acc,
+					 &iova_start, &nesmr->pbls_used, &nesmr->pbl_4k);
 
 			nes_debug(NES_DBG_MR, "ret=%d\n", ret);
 
@@ -2466,11 +2582,6 @@ static struct ib_mr *nes_reg_user_mr(str
 				nesmr->ibmr.lkey = stag;
 				nesmr->mode = IWNES_MEMREG_TYPE_MEM;
 				ibmr = &nesmr->ibmr;
-				nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
-				nesmr->pbls_used = pbl_count;
-				if (pbl_count > 1) {
-					nesmr->pbls_used++;
-				}
 			} else {
 				ib_umem_release(region);
 				kfree(nesmr);
@@ -2609,24 +2720,6 @@ static int nes_dereg_mr(struct ib_mr *ib
 	cqp_request->waiting = 1;
 	cqp_wqe = &cqp_request->cqp_wqe;
 
-	spin_lock_irqsave(&nesadapter->pbl_lock, flags);
-	if (nesmr->pbls_used != 0) {
-		if (nesmr->pbl_4k) {
-			nesadapter->free_4kpbl += nesmr->pbls_used;
-			if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) {
-				printk(KERN_ERR PFX "free 4KB PBLs(%u) has exceeded the max(%u)\n",
-						nesadapter->free_4kpbl, nesadapter->max_4kpbl);
-			}
-		} else {
-			nesadapter->free_256pbl += nesmr->pbls_used;
-			if (nesadapter->free_256pbl > nesadapter->max_256pbl) {
-				printk(KERN_ERR PFX "free 256B PBLs(%u) has exceeded the max(%u)\n",
-						nesadapter->free_256pbl, nesadapter->max_256pbl);
-			}
-		}
-	}
-
-	spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
 	nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
 	set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
 			NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO |
@@ -2644,11 +2737,6 @@ static int nes_dereg_mr(struct ib_mr *ib
 			" CQP Major:Minor codes = 0x%04X:0x%04X\n",
 			ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code);
 
-	nes_free_resource(nesadapter, nesadapter->allocated_mrs,
-			(ib_mr->rkey & 0x0fffff00) >> 8);
-
-	kfree(nesmr);
-
 	major_code = cqp_request->major_code;
 	minor_code = cqp_request->minor_code;
 
@@ -2664,8 +2752,33 @@ static int nes_dereg_mr(struct ib_mr *ib
 				" to destroy STag, ib_mr=%p, rkey = 0x%08X\n",
 				major_code, minor_code, ib_mr, ib_mr->rkey);
 		return -EIO;
-	} else
-		return 0;
+	}
+
+	if (nesmr->pbls_used != 0) {
+		spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+		if (nesmr->pbl_4k) {
+			nesadapter->free_4kpbl += nesmr->pbls_used;
+			if (nesadapter->free_4kpbl > nesadapter->max_4kpbl)
+				printk(KERN_ERR PFX "free 4KB PBLs(%u) has "
+					"exceeded the max(%u)\n",
+					nesadapter->free_4kpbl,
+					nesadapter->max_4kpbl);
+		} else {
+			nesadapter->free_256pbl += nesmr->pbls_used;
+			if (nesadapter->free_256pbl > nesadapter->max_256pbl)
+				printk(KERN_ERR PFX "free 256B PBLs(%u) has "
+					"exceeded the max(%u)\n",
+					nesadapter->free_256pbl,
+					nesadapter->max_256pbl);
+		}
+		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+	}
+	nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+			(ib_mr->rkey & 0x0fffff00) >> 8);
+
+	kfree(nesmr);
+
+	return 0;
 }
 
 
@@ -2695,10 +2808,9 @@ static ssize_t show_fw_ver(struct device
 	struct nes_vnic *nesvnic = nesibdev->nesvnic;
 
 	nes_debug(NES_DBG_INIT, "\n");
-	return sprintf(buf, "%x.%x.%x\n",
-			(int)(nesvnic->nesdev->nesadapter->fw_ver >> 32),
-			(int)(nesvnic->nesdev->nesadapter->fw_ver >> 16) & 0xffff,
-			(int)(nesvnic->nesdev->nesadapter->fw_ver & 0xffff));
+	return sprintf(buf, "%u.%u\n",
+		(nesvnic->nesdev->nesadapter->firmware_version >> 16),
+		(nesvnic->nesdev->nesadapter->firmware_version & 0x000000ff));
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_verbs.h linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_verbs.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/hw/nes/nes_verbs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/hw/nes/nes_verbs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc.  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
@@ -112,6 +112,7 @@ struct nes_cq {
 	spinlock_t       lock;
 	u8               virtual_cq;
 	u8               pad[3];
+	u32		 mcrqf;
 };
 
 struct nes_wq {
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-06-09 23:05:27.000000000 -0400
@@ -446,11 +446,11 @@ poll_more:
 		if (dev->features & NETIF_F_LRO)
 			lro_flush_all(&priv->lro.lro_mgr);
 
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		if (unlikely(ib_req_notify_cq(priv->recv_cq,
 					      IB_CQ_NEXT_COMP |
 					      IB_CQ_REPORT_MISSED_EVENTS)) &&
-		    netif_rx_reschedule(napi))
+		    napi_reschedule(napi))
 			goto poll_more;
 	}
 
@@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *c
 	struct net_device *dev = dev_ptr;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-	netif_rx_schedule(&priv->napi);
+	napi_schedule(&priv->napi);
 }
 
 static void drain_tx_cq(struct net_device *dev)
@@ -685,7 +685,8 @@ int ipoib_ib_dev_open(struct net_device
 	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
 			   round_jiffies_relative(HZ));
 
-	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_enable(&priv->napi);
 
 	return 0;
 }
@@ -804,7 +805,8 @@ int ipoib_ib_dev_stop(struct net_device
 	struct ipoib_tx_buf *tx_req;
 	int i;
 
-	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_disable(&priv->napi);
 
 	ipoib_cm_dev_stop(dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -106,8 +106,7 @@ int ipoib_open(struct net_device *dev)
 
 	ipoib_dbg(priv, "bringing up interface\n");
 
-	if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
-		napi_enable(&priv->napi);
+	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	if (ipoib_pkey_dev_delay_open(dev))
 		return 0;
@@ -143,7 +142,6 @@ err_stop:
 	ipoib_ib_dev_stop(dev, 1);
 
 err_disable:
-	napi_disable(&priv->napi);
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	return -EINVAL;
@@ -156,7 +154,6 @@ static int ipoib_stop(struct net_device
 	ipoib_dbg(priv, "stopping interface\n");
 
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
-	napi_disable(&priv->napi);
 
 	netif_stop_queue(dev);
 
@@ -660,8 +657,12 @@ static void unicast_arp_send(struct sk_b
 
 	path = __path_find(dev, phdr->hwaddr + 4);
 	if (!path || !path->valid) {
-		if (!path)
+		int new_path = 0;
+
+		if (!path) {
 			path = path_rec_create(dev, phdr->hwaddr + 4);
+			new_path = 1;
+		}
 		if (path) {
 			/* put pseudoheader back on for next time */
 			skb_push(skb, sizeof *phdr);
@@ -669,7 +670,8 @@ static void unicast_arp_send(struct sk_b
 
 			if (!path->query && path_rec_start(dev, path)) {
 				spin_unlock_irqrestore(&priv->lock, flags);
-				path_free(dev, path);
+				if (new_path)
+					path_free(dev, path);
 				return;
 			} else
 				__path_add(dev, path);
@@ -1016,18 +1018,22 @@ static void ipoib_lro_setup(struct ipoib
 	priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
 }
 
+static const struct net_device_ops ipoib_netdev_ops = {
+	.ndo_open		 = ipoib_open,
+	.ndo_stop		 = ipoib_stop,
+	.ndo_change_mtu		 = ipoib_change_mtu,
+	.ndo_start_xmit	 	 = ipoib_start_xmit,
+	.ndo_tx_timeout		 = ipoib_timeout,
+	.ndo_set_multicast_list	 = ipoib_set_mcast_list,
+	.ndo_neigh_setup	 = ipoib_neigh_setup_dev,
+};
+
 static void ipoib_setup(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-	dev->open		 = ipoib_open;
-	dev->stop		 = ipoib_stop;
-	dev->change_mtu		 = ipoib_change_mtu;
-	dev->hard_start_xmit	 = ipoib_start_xmit;
-	dev->tx_timeout		 = ipoib_timeout;
+	dev->netdev_ops		 = &ipoib_netdev_ops;
 	dev->header_ops		 = &ipoib_header_ops;
-	dev->set_multicast_list	 = ipoib_set_mcast_list;
-	dev->neigh_setup	 = ipoib_neigh_setup_dev;
 
 	ipoib_set_ethtool_ops(dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/ipoib/ipoib_vlan.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pd
 	 */
 	if (ppriv->pkey == pkey) {
 		result = -ENOTUNIQ;
+		priv = NULL;
 		goto err;
 	}
 
 	list_for_each_entry(priv, &ppriv->child_intfs, list) {
 		if (priv->pkey == pkey) {
 			result = -ENOTUNIQ;
+			priv = NULL;
 			goto err;
 		}
 	}
@@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pd
 
 	result = ipoib_set_dev_features(priv, ppriv->ca);
 	if (result)
-		goto device_init_failed;
+		goto err;
 
 	priv->pkey = pkey;
 
@@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pd
 		ipoib_warn(ppriv, "failed to initialize subinterface: "
 			   "device %s, port %d",
 			   ppriv->ca->name, ppriv->port);
-		goto device_init_failed;
+		goto err;
 	}
 
 	result = register_netdevice(priv->dev);
@@ -146,19 +148,19 @@ sysfs_failed:
 register_failed:
 	ipoib_dev_cleanup(priv->dev);
 
-device_init_failed:
-	free_netdev(priv->dev);
-
 err:
 	mutex_unlock(&ppriv->vlan_mutex);
 	rtnl_unlock();
+	if (priv)
+		free_netdev(priv->dev);
+
 	return result;
 }
 
 int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 {
 	struct ipoib_dev_priv *ppriv, *priv, *tpriv;
-	int ret = -ENOENT;
+	struct net_device *dev = NULL;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device
 			unregister_netdevice(priv->dev);
 			ipoib_dev_cleanup(priv->dev);
 			list_del(&priv->list);
-			free_netdev(priv->dev);
-
-			ret = 0;
+			dev = priv->dev;
 			break;
 		}
 	}
 	mutex_unlock(&ppriv->vlan_mutex);
 	rtnl_unlock();
 
-	return ret;
+	if (dev) {
+		free_netdev(dev);
+		return 0;
+	}
+
+	return -ENODEV;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,7 +168,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
 {
 	int error = 0;
 
-	debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
+	iser_dbg("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
 
 	error = iser_send_control(conn, task);
 
@@ -195,7 +195,7 @@ iscsi_iser_task_xmit_unsol_data(struct i
 	/* Send data-out PDUs while there's still unsolicited data to send */
 	while (iscsi_task_has_unsol_data(task)) {
 		iscsi_prep_data_out_pdu(task, r2t, &hdr);
-		debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
+		iser_dbg("Sending data-out: itt 0x%x, data count %d\n",
 			   hdr.itt, r2t->data_count);
 
 		/* the buffer description has been passed with the command */
@@ -206,7 +206,7 @@ iscsi_iser_task_xmit_unsol_data(struct i
 			goto iscsi_iser_task_xmit_unsol_data_exit;
 		}
 		r2t->sent += r2t->data_count;
-		debug_scsi("Need to send %d more as data-out PDUs\n",
+		iser_dbg("Need to send %d more as data-out PDUs\n",
 			   r2t->data_length - r2t->sent);
 	}
 
@@ -227,12 +227,12 @@ iscsi_iser_task_xmit(struct iscsi_task *
 	if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
 		BUG_ON(scsi_bufflen(task->sc) == 0);
 
-		debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
+		iser_dbg("cmd [itt %x total %d imm %d unsol_data %d\n",
 			   task->itt, scsi_bufflen(task->sc),
 			   task->imm_count, task->unsol_r2t.data_length);
 	}
 
-	debug_scsi("task deq [cid %d itt 0x%x]\n",
+	iser_dbg("task deq [cid %d itt 0x%x]\n",
 		   conn->id, task->itt);
 
 	/* Send the cmd PDU */
@@ -397,14 +397,14 @@ static void iscsi_iser_session_destroy(s
 static struct iscsi_cls_session *
 iscsi_iser_session_create(struct iscsi_endpoint *ep,
 			  uint16_t cmds_max, uint16_t qdepth,
-			  uint32_t initial_cmdsn, uint32_t *hostno)
+			  uint32_t initial_cmdsn)
 {
 	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
 	struct Scsi_Host *shost;
 	struct iser_conn *ib_conn;
 
-	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
+	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 1);
 	if (!shost)
 		return NULL;
 	shost->transportt = iscsi_iser_scsi_transport;
@@ -423,7 +423,6 @@ iscsi_iser_session_create(struct iscsi_e
 	if (iscsi_host_add(shost,
 			   ep ? ib_conn->device->ib_device->dma_device : NULL))
 		goto free_host;
-	*hostno = shost->host_no;
 
 	/*
 	 * we do not support setting can_queue cmd_per_lun from userspace yet
@@ -596,10 +595,11 @@ static struct scsi_host_template iscsi_i
 	.change_queue_depth	= iscsi_change_queue_depth,
 	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
 	.max_sectors		= 1024,
-	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
+	.cmd_per_lun            = ISER_DEF_CMD_PER_LUN,
 	.eh_abort_handler       = iscsi_eh_abort,
 	.eh_device_reset_handler= iscsi_eh_device_reset,
 	.eh_target_reset_handler= iscsi_eh_target_reset,
+	.target_alloc		= iscsi_target_alloc,
 	.use_clustering         = DISABLE_CLUSTERING,
 	.proc_name              = "iscsi_iser",
 	.this_id                = -1,
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iscsi_iser.h	2009-06-09 23:05:27.000000000 -0400
@@ -93,7 +93,7 @@
 
 					/* support upto 512KB in one RDMA */
 #define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> SHIFT_4K)
-#define ISCSI_ISER_MAX_LUN		256
+#define ISER_DEF_CMD_PER_LUN		128
 
 /* QP settings */
 /* Maximal bounds on received asynchronous PDUs */
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iser_initiator.c	2009-06-09 23:05:27.000000000 -0400
@@ -661,7 +661,7 @@ void iser_snd_completion(struct iser_des
 
 	if (resume_tx) {
 		iser_dbg("%ld resuming tx\n",jiffies);
-		scsi_queue_work(conn->session->host, &conn->xmitwork);
+		iscsi_conn_queue_work(conn);
 	}
 
 	if (tx_desc->type == ISCSI_TX_CONTROL) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c
--- linux-libre-2.6.29-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/infiniband/ulp/iser/iser_verbs.c	2009-06-09 23:05:27.000000000 -0400
@@ -401,13 +401,6 @@ static void iser_route_handler(struct rd
 	if (ret)
 		goto failure;
 
-	iser_dbg("path.mtu is %d setting it to %d\n",
-		 cma_id->route.path_rec->mtu, IB_MTU_1024);
-
-	/* we must set the MTU to 1024 as this is what the target is assuming */
-	if (cma_id->route.path_rec->mtu > IB_MTU_1024)
-		cma_id->route.path_rec->mtu = IB_MTU_1024;
-
 	memset(&conn_param, 0, sizeof conn_param);
 	conn_param.responder_resources = 4;
 	conn_param.initiator_depth     = 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/evdev.c linux-libre-2.6.30-gnu1/drivers/input/evdev.c
--- linux-libre-2.6.29-gnu1/drivers/input/evdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/evdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,11 +94,8 @@ static void evdev_event(struct input_han
 static int evdev_fasync(int fd, struct file *file, int on)
 {
 	struct evdev_client *client = file->private_data;
-	int retval;
-
-	retval = fasync_helper(fd, file, on, &client->fasync);
 
-	return retval < 0 ? retval : 0;
+	return fasync_helper(fd, file, on, &client->fasync);
 }
 
 static int evdev_flush(struct file *file, fl_owner_t id)
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/ff-memless.c linux-libre-2.6.30-gnu1/drivers/input/ff-memless.c
--- linux-libre-2.6.29-gnu1/drivers/input/ff-memless.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/ff-memless.c	2009-06-09 23:05:27.000000000 -0400
@@ -226,7 +226,7 @@ static int get_compatible_type(struct ff
  */
 static void ml_combine_effects(struct ff_effect *effect,
 			       struct ml_effect_state *state,
-			       int gain)
+			       unsigned int gain)
 {
 	struct ff_effect *new = state->effect;
 	unsigned int strong, weak, i;
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/gameport/gameport.c linux-libre-2.6.30-gnu1/drivers/input/gameport/gameport.c
--- linux-libre-2.6.29-gnu1/drivers/input/gameport/gameport.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/gameport/gameport.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list);
 
 static struct bus_type gameport_bus;
 
-static void gameport_add_driver(struct gameport_driver *drv);
 static void gameport_add_port(struct gameport *gameport);
-static void gameport_destroy_port(struct gameport *gameport);
+static void gameport_attach_driver(struct gameport_driver *drv);
 static void gameport_reconnect_port(struct gameport *gameport);
 static void gameport_disconnect_port(struct gameport *gameport);
 
@@ -230,7 +229,6 @@ static void gameport_find_driver(struct
 
 enum gameport_event_type {
 	GAMEPORT_REGISTER_PORT,
-	GAMEPORT_REGISTER_DRIVER,
 	GAMEPORT_ATTACH_DRIVER,
 };
 
@@ -374,8 +372,8 @@ static void gameport_handle_event(void)
 				gameport_add_port(event->object);
 				break;
 
-			case GAMEPORT_REGISTER_DRIVER:
-				gameport_add_driver(event->object);
+			case GAMEPORT_ATTACH_DRIVER:
+				gameport_attach_driver(event->object);
 				break;
 
 			default:
@@ -706,14 +704,14 @@ static int gameport_driver_remove(struct
 	return 0;
 }
 
-static void gameport_add_driver(struct gameport_driver *drv)
+static void gameport_attach_driver(struct gameport_driver *drv)
 {
 	int error;
 
-	error = driver_register(&drv->driver);
+	error = driver_attach(&drv->driver);
 	if (error)
 		printk(KERN_ERR
-			"gameport: driver_register() failed for %s, error: %d\n",
+			"gameport: driver_attach() failed for %s, error: %d\n",
 			drv->driver.name, error);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/input.c linux-libre-2.6.30-gnu1/drivers/input/input.c
--- linux-libre-2.6.29-gnu1/drivers/input/input.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/input.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,24 @@ MODULE_LICENSE("GPL");
 
 #define INPUT_DEVICES	256
 
+/*
+ * EV_ABS events which should not be cached are listed here.
+ */
+static unsigned int input_abs_bypass_init_data[] __initdata = {
+	ABS_MT_TOUCH_MAJOR,
+	ABS_MT_TOUCH_MINOR,
+	ABS_MT_WIDTH_MAJOR,
+	ABS_MT_WIDTH_MINOR,
+	ABS_MT_ORIENTATION,
+	ABS_MT_POSITION_X,
+	ABS_MT_POSITION_Y,
+	ABS_MT_TOOL_TYPE,
+	ABS_MT_BLOB_ID,
+	ABS_MT_TRACKING_ID,
+	0
+};
+static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
+
 static LIST_HEAD(input_dev_list);
 static LIST_HEAD(input_handler_list);
 
@@ -132,6 +150,11 @@ static void input_start_autorepeat(struc
 	}
 }
 
+static void input_stop_autorepeat(struct input_dev *dev)
+{
+	del_timer(&dev->timer);
+}
+
 #define INPUT_IGNORE_EVENT	0
 #define INPUT_PASS_TO_HANDLERS	1
 #define INPUT_PASS_TO_DEVICE	2
@@ -156,6 +179,10 @@ static void input_handle_event(struct in
 				disposition = INPUT_PASS_TO_HANDLERS;
 			}
 			break;
+		case SYN_MT_REPORT:
+			dev->sync = 0;
+			disposition = INPUT_PASS_TO_HANDLERS;
+			break;
 		}
 		break;
 
@@ -167,6 +194,8 @@ static void input_handle_event(struct in
 				__change_bit(code, dev->key);
 				if (value)
 					input_start_autorepeat(dev, code);
+				else
+					input_stop_autorepeat(dev);
 			}
 
 			disposition = INPUT_PASS_TO_HANDLERS;
@@ -185,6 +214,11 @@ static void input_handle_event(struct in
 	case EV_ABS:
 		if (is_event_supported(code, dev->absbit, ABS_MAX)) {
 
+			if (test_bit(code, input_abs_bypass)) {
+				disposition = INPUT_PASS_TO_HANDLERS;
+				break;
+			}
+
 			value = input_defuzz_abs_event(value,
 					dev->abs[code], dev->absfuzz[code]);
 
@@ -737,11 +771,11 @@ static inline void input_wakeup_procfs_r
 
 static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
 {
-	int state = input_devices_state;
-
 	poll_wait(file, &input_devices_poll_wait, wait);
-	if (state != input_devices_state)
+	if (file->f_version != input_devices_state) {
+		file->f_version = input_devices_state;
 		return POLLIN | POLLRDNORM;
+	}
 
 	return 0;
 }
@@ -903,8 +937,6 @@ static int __init input_proc_init(void)
 	if (!proc_bus_input_dir)
 		return -ENOMEM;
 
-	proc_bus_input_dir->owner = THIS_MODULE;
-
 	entry = proc_create("devices", 0, proc_bus_input_dir,
 			    &input_devices_fileops);
 	if (!entry)
@@ -1544,7 +1576,6 @@ int input_register_handle(struct input_h
 		return error;
 	list_add_tail_rcu(&handle->d_node, &dev->h_list);
 	mutex_unlock(&dev->mutex);
-	synchronize_rcu();
 
 	/*
 	 * Since we are supposed to be called from ->connect()
@@ -1630,10 +1661,20 @@ static const struct file_operations inpu
 	.open = input_open_file,
 };
 
+static void __init input_init_abs_bypass(void)
+{
+	const unsigned int *p;
+
+	for (p = input_abs_bypass_init_data; *p; p++)
+		input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);
+}
+
 static int __init input_init(void)
 {
 	int err;
 
+	input_init_abs_bypass();
+
 	err = class_register(&input_class);
 	if (err) {
 		printk(KERN_ERR "input: unable to register input_dev class\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/joydev.c linux-libre-2.6.30-gnu1/drivers/input/joydev.c
--- linux-libre-2.6.29-gnu1/drivers/input/joydev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/joydev.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,12 +159,9 @@ static void joydev_event(struct input_ha
 
 static int joydev_fasync(int fd, struct file *file, int on)
 {
-	int retval;
 	struct joydev_client *client = file->private_data;
 
-	retval = fasync_helper(fd, file, on, &client->fasync);
-
-	return retval < 0 ? retval : 0;
+	return fasync_helper(fd, file, on, &client->fasync);
 }
 
 static void joydev_free(struct device *dev)
@@ -846,7 +843,13 @@ static const struct input_device_id joyd
 				INPUT_DEVICE_ID_MATCH_KEYBIT,
 		.evbit = { BIT_MASK(EV_KEY) },
 		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
-	},	/* Avoid itouchpads, touchscreens and tablets */
+	},	/* Avoid itouchpads and touchscreens */
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+				INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
+	},	/* Avoid tablets, digitisers and similar devices */
 	{ }	/* Terminating entry */
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/joystick/maplecontrol.c linux-libre-2.6.30-gnu1/drivers/input/joystick/maplecontrol.c
--- linux-libre-2.6.29-gnu1/drivers/input/joystick/maplecontrol.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/joystick/maplecontrol.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  *	Based on drivers/usb/iforce.c
  *
  *	Copyright Yaegashi Takeshi, 2001
- *	Adrian McMenamin, 2008
+ *	Adrian McMenamin, 2008 - 2009
  */
 
 #include <linux/kernel.h>
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct maple
 	struct maple_device *mapledev = mq->dev;
 	struct dc_pad *pad = maple_get_drvdata(mapledev);
 	struct input_dev *dev = pad->dev;
-	unsigned char *res = mq->recvbuf;
+	unsigned char *res = mq->recvbuf->buf;
 
 	buttons = ~le16_to_cpup((__le16 *)(res + 8));
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/Kconfig linux-libre-2.6.30-gnu1/drivers/input/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/input/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -143,7 +143,7 @@ config INPUT_APMPOWER
 	---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 behviour is desired without userspace
+	  systems where such behaviour is desired without userspace
 	  interaction. If unsure, say N.
 
 	  To compile this driver as a module, choose M here: the
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/atkbd.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/atkbd.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/atkbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/atkbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -229,7 +229,8 @@ struct atkbd {
 /*
  * System-specific ketymap fixup routine
  */
-static void (*atkbd_platform_fixup)(struct atkbd *);
+static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
+static void *atkbd_platform_fixup_data;
 
 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
 				ssize_t (*handler)(struct atkbd *, char *));
@@ -834,87 +835,71 @@ static void atkbd_disconnect(struct seri
 }
 
 /*
- * Most special keys (Fn+F?) on Dell laptops do not generate release
- * events so we have to do it ourselves.
+ * generate release events for the keycodes given in data
  */
-static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
+						const void *data)
 {
-	static const unsigned int forced_release_keys[] = {
-		0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
-	};
-	int i;
+	const unsigned int *keys = data;
+	unsigned int i;
 
 	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
+		for (i = 0; keys[i] != -1U; i++)
+			__set_bit(keys[i], atkbd->force_release_mask);
 }
 
 /*
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+static unsigned int atkbd_dell_laptop_forced_release_keys[] = {
+	0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U
+};
+
+/*
  * Perform fixup for HP system that doesn't generate release
  * for its video switch
  */
-static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
-{
-	static const unsigned int forced_release_keys[] = {
-		0x94,
-	};
-	int i;
-
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-					atkbd->force_release_mask);
-}
+static unsigned int atkbd_hp_forced_release_keys[] = {
+	0x94, -1U
+};
 
 /*
  * Inventec system with broken key release on volume keys
  */
-static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0xae, 0xb0,
-	};
-	int i;
-
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
-}
+static unsigned int atkbd_inventec_forced_release_keys[] = {
+	0xae, 0xb0, -1U
+};
 
 /*
  * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release
  * for its volume buttons
  */
-static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0xae, 0xb0,
-	};
-	int i;
+static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
+	0xae, 0xb0, -1U
+};
 
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-					atkbd->force_release_mask);
-}
+/*
+ * Samsung NC10,NC20 with Fn+F? key release not working
+ */
+static unsigned int atkbd_samsung_forced_release_keys[] = {
+	0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U
+};
 
 /*
- * Samsung NC10 with Fn+F? key release not working
+ * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop
+ * do not generate release events so we have to do it ourselves.
  */
-static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd)
-{
-	const unsigned int forced_release_keys[] = {
-		0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9,
-	};
-	int i;
+static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
+	0xb0, 0xae, -1U
+};
 
-	if (atkbd->set == 2)
-		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
-			__set_bit(forced_release_keys[i],
-				  atkbd->force_release_mask);
-}
+/*
+ * Amilo Xi 3650 key release for light touch bar not working
+ */
+static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = {
+	0x67, 0xed, 0x90, 0xa2, 0x99, 0xa4, 0xae, 0xb0, -1U
+};
 
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
@@ -967,7 +952,7 @@ static void atkbd_set_keycode_table(stru
  * Perform additional fixups
  */
 	if (atkbd_platform_fixup)
-		atkbd_platform_fixup(atkbd);
+		atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);
 }
 
 /*
@@ -1492,9 +1477,11 @@ static ssize_t atkbd_show_err_count(stru
 	return sprintf(buf, "%lu\n", atkbd->err_count);
 }
 
-static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
+static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
 {
-	atkbd_platform_fixup = id->driver_data;
+	atkbd_platform_fixup = atkbd_apply_forced_release_keylist;
+	atkbd_platform_fixup_data = id->driver_data;
+
 	return 0;
 }
 
@@ -1505,8 +1492,8 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_dell_laptop_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
 		.ident = "Dell Laptop",
@@ -1514,8 +1501,8 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_dell_laptop_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_dell_laptop_forced_release_keys,
 	},
 	{
 		.ident = "HP 2133",
@@ -1523,8 +1510,8 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_hp_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_hp_forced_release_keys,
 	},
 	{
 		.ident = "HP Pavilion ZV6100",
@@ -1532,8 +1519,8 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_hp_zv6100_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_hp_zv6100_forced_release_keys,
 	},
 	{
 		.ident = "Inventec Symphony",
@@ -1541,8 +1528,8 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_inventec_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_inventec_forced_release_keys,
 	},
 	{
 		.ident = "Samsung NC10",
@@ -1550,8 +1537,44 @@ static struct dmi_system_id atkbd_dmi_qu
 			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
 		},
-		.callback = atkbd_setup_fixup,
-		.driver_data = atkbd_samsung_keymap_fixup,
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Samsung NC20",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "NC20"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Samsung SQ45S70S",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_samsung_forced_release_keys,
+	},
+	{
+		.ident = "Fujitsu Amilo PA 1510",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_amilo_pa1510_forced_release_keys,
+	},
+	{
+		.ident = "Fujitsu Amilo Xi 3650",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"),
+		},
+		.callback = atkbd_setup_forced_release,
+		.driver_data = atkbd_amilo_xi3650_forced_release_keys,
 	},
 	{ }
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/bf54x-keys.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/bf54x-keys.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/bf54x-keys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/bf54x-keys.c	2009-06-09 23:05:27.000000000 -0400
@@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(str
 
 	if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
 	    !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
-		printk(KERN_ERR DRV_NAME
-			": Invalid Debounce/Columdrive Time from pdata\n");
+		printk(KERN_WARNING DRV_NAME
+			": Invalid Debounce/Columndrive Time in platform data\n");
 		bfin_write_KPAD_MSEL(0xFF0);	/* Default MSEL	*/
 	} else {
 		bfin_write_KPAD_MSEL(
@@ -252,7 +252,7 @@ static int __devinit bfin_kpad_probe(str
 	}
 
 	error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
-				 IRQF_SAMPLE_RANDOM, DRV_NAME, pdev);
+				0, DRV_NAME, pdev);
 	if (error) {
 		printk(KERN_ERR DRV_NAME
 			": unable to claim irq %d; error %d\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/corgikbd.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/corgikbd.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/corgikbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/corgikbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,8 +21,6 @@
 #include <linux/slab.h>
 
 #include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 #include <asm/hardware/scoop.h>
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/hilkbd.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/hilkbd.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/hilkbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/hilkbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, un
 }
 
 
-/* initialise HIL */
-static int __init
-hil_keyb_init(void)
+/* initialize HIL */
+static int __devinit hil_keyb_init(void)
 {
 	unsigned char c;
 	unsigned int i, kbid;
 	wait_queue_head_t hil_wait;
 	int err;
 
-	if (hil_dev.dev) {
+	if (hil_dev.dev)
 		return -ENODEV; /* already initialized */
-	}
 
+	init_waitqueue_head(&hil_wait);
 	spin_lock_init(&hil_dev.lock);
+
 	hil_dev.dev = input_allocate_device();
 	if (!hil_dev.dev)
 		return -ENOMEM;
 
-#if defined(CONFIG_HP300)
-	if (!MACH_IS_HP300) {
-		err = -ENODEV;
-		goto err1;
-	}
-	if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
-		printk(KERN_ERR "HIL: hardware register was not found\n");
-		err = -ENODEV;
-		goto err1;
-	}
-	if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
-		printk(KERN_ERR "HIL: IOPORT region already used\n");
-		err = -EIO;
-		goto err1;
-	}
-#endif
-
 	err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
 	if (err) {
 		printk(KERN_ERR "HIL: Can't get IRQ\n");
-		goto err2;
+		goto err1;
 	}
 
 	/* Turn on interrupts */
@@ -246,11 +229,9 @@ hil_keyb_init(void)
 	hil_dev.valid = 0;	/* clear any pending data */
 	hil_do(HIL_READKBDSADR, NULL, 0);
 
-	init_waitqueue_head(&hil_wait);
-	wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
-	if (!hil_dev.valid) {
+	wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);
+	if (!hil_dev.valid)
 		printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
-	}
 
 	c = hil_dev.c;
 	hil_dev.valid = 0;
@@ -268,7 +249,7 @@ hil_keyb_init(void)
 
 	for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
 		if (hphilkeyb_keycode[i] != KEY_RESERVED)
-			set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+			__set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
 
 	hil_dev.dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	hil_dev.dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
@@ -287,34 +268,45 @@ hil_keyb_init(void)
 	err = input_register_device(hil_dev.dev);
 	if (err) {
 		printk(KERN_ERR "HIL: Can't register device\n");
-		goto err3;
+		goto err2;
 	}
+
 	printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
 	       hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
 
 	return 0;
 
-err3:
+err2:
 	hil_do(HIL_INTOFF, NULL, 0);
-	disable_irq(HIL_IRQ);
 	free_irq(HIL_IRQ, hil_dev.dev_id);
-err2:
-#if defined(CONFIG_HP300)
-	release_region(HILBASE + HIL_DATA, 2);
 err1:
-#endif
 	input_free_device(hil_dev.dev);
 	hil_dev.dev = NULL;
 	return err;
 }
 
+static void __devexit hil_keyb_exit(void)
+{
+	if (HIL_IRQ)
+		free_irq(HIL_IRQ, hil_dev.dev_id);
+
+	/* Turn off interrupts */
+	hil_do(HIL_INTOFF, NULL, 0);
+
+	input_unregister_device(hil_dev.dev);
+	hil_dev.dev = NULL;
+}
 
 #if defined(CONFIG_PARISC)
-static int __init
-hil_init_chip(struct parisc_device *dev)
+static int __devinit hil_probe_chip(struct parisc_device *dev)
 {
+	/* Only allow one HIL keyboard */
+	if (hil_dev.dev)
+		return -ENODEV;
+
 	if (!dev->irq) {
-		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
+		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",
+			(void *)dev->hpa.start);
 		return -ENODEV;
 	}
 
@@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev)
 	return hil_keyb_init();
 }
 
+static int __devexit hil_remove_chip(struct parisc_device *dev)
+{
+	hil_keyb_exit();
+
+	return 0;
+}
+
 static struct parisc_device_id hil_tbl[] = {
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
 	{ 0, }
 };
 
+#if 0
+/* Disabled to avoid conflicts with the HP SDC HIL drivers */
 MODULE_DEVICE_TABLE(parisc, hil_tbl);
+#endif
 
 static struct parisc_driver hil_driver = {
-	.name =		"hil",
-	.id_table =	hil_tbl,
-	.probe =	hil_init_chip,
+	.name		= "hil",
+	.id_table	= hil_tbl,
+	.probe		= hil_probe_chip,
+	.remove		= __devexit_p(hil_remove_chip),
 };
-#endif /* CONFIG_PARISC */
-
 
 static int __init hil_init(void)
 {
-#if defined(CONFIG_PARISC)
 	return register_parisc_driver(&hil_driver);
-#else
-	return hil_keyb_init();
-#endif
 }
 
-
 static void __exit hil_exit(void)
 {
-	if (HIL_IRQ) {
-		disable_irq(HIL_IRQ);
-		free_irq(HIL_IRQ, hil_dev.dev_id);
+	unregister_parisc_driver(&hil_driver);
+}
+
+#else /* !CONFIG_PARISC */
+
+static int __init hil_init(void)
+{
+	int error;
+
+	/* Only allow one HIL keyboard */
+	if (hil_dev.dev)
+		return -EBUSY;
+
+	if (!MACH_IS_HP300)
+		return -ENODEV;
+
+	if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
+		printk(KERN_ERR "HIL: hardware register was not found\n");
+		return -ENODEV;
 	}
 
-	/* Turn off interrupts */
-	hil_do(HIL_INTOFF, NULL, 0);
+	if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
+		printk(KERN_ERR "HIL: IOPORT region already used\n");
+		return -EIO;
+	}
 
-	input_unregister_device(hil_dev.dev);
+	error = hil_keyb_init();
+	if (error) {
+		release_region(HILBASE + HIL_DATA, 2);
+		return error;
+	}
 
-	hil_dev.dev = NULL;
+	return 0;
+}
 
-#if defined(CONFIG_PARISC)
-	unregister_parisc_driver(&hil_driver);
-#else
-	release_region(HILBASE+HIL_DATA, 2);
-#endif
+static void __exit hil_exit(void)
+{
+	hil_keyb_exit();
+	release_region(HILBASE + HIL_DATA, 2);
 }
 
+#endif /* CONFIG_PARISC */
+
 module_init(hil_init);
 module_exit(hil_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/Kconfig linux-libre-2.6.30-gnu1/drivers/input/keyboard/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
 if INPUT_KEYBOARD
 
 config KEYBOARD_ATKBD
-	tristate "AT keyboard" if EMBEDDED || !X86_PC
+	tristate "AT keyboard" if EMBEDDED || !X86
 	default y
 	select SERIO
 	select SERIO_LIBPS2
-	select SERIO_I8042 if X86_PC
+	select SERIO_I8042 if X86
 	select SERIO_GSCPS2 if GSC
 	help
 	  Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/maple_keyb.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/maple_keyb.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/maple_keyb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/maple_keyb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * SEGA Dreamcast keyboard driver
  * Based on drivers/usb/usbkbd.c
- * Copyright YAEGASHI Takeshi, 2001
- * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008
+ * Copyright (c) YAEGASHI Takeshi, 2001
+ * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex);
 
 #define NR_SCANCODES 256
 
-MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk");
 MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
 MODULE_LICENSE("GPL");
 
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *k
 				input_event(dev, EV_MSC, MSC_SCAN, code);
 				input_report_key(dev, keycode, 0);
 			} else
-				printk(KERN_DEBUG "maple_keyb: "
+				dev_dbg(&dev->dev,
 					"Unknown key (scancode %#x) released.",
 					code);
 		}
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *k
 				input_event(dev, EV_MSC, MSC_SCAN, code);
 				input_report_key(dev, keycode, 1);
 			} else
-				printk(KERN_DEBUG "maple_keyb: "
+				dev_dbg(&dev->dev,
 					"Unknown key (scancode %#x) pressed.",
 					code);
 		}
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct maple
 {
 	struct maple_device *mapledev = mq->dev;
 	struct dc_kbd *kbd = maple_get_drvdata(mapledev);
-	unsigned long *buf = mq->recvbuf;
+	unsigned long *buf = (unsigned long *)(mq->recvbuf->buf);
 
 	/*
 	 * We should always get the lock because the only
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct maple
 
 static int probe_maple_kbd(struct device *dev)
 {
-	struct maple_device *mdev = to_maple_dev(dev);
-	struct maple_driver *mdrv = to_maple_driver(dev->driver);
+	struct maple_device *mdev;
+	struct maple_driver *mdrv;
 	int i, error;
 	struct dc_kbd *kbd;
 	struct input_dev *idev;
 
-	if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
-		return -EINVAL;
+	mdev = to_maple_dev(dev);
+	mdrv = to_maple_driver(dev->driver);
 
 	kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
-	idev = input_allocate_device();
-	if (!kbd || !idev) {
+	if (!kbd) {
 		error = -ENOMEM;
 		goto fail;
 	}
 
+	idev = input_allocate_device();
+	if (!idev) {
+		error = -ENOMEM;
+		goto fail_idev_alloc;
+	}
+
 	kbd->dev = idev;
 	memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
 
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device
 
 	error = input_register_device(idev);
 	if (error)
-		goto fail;
+		goto fail_register;
 
 	/* Maple polling is locked to VBLANK - which may be just 50/s */
 	maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device
 
 	return error;
 
-fail:
+fail_register:
+	maple_set_drvdata(mdev, NULL);
 	input_free_device(idev);
+fail_idev_alloc:
 	kfree(kbd);
-	maple_set_drvdata(mdev, NULL);
+fail:
 	return error;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/omap-keypad.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/omap-keypad.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/omap-keypad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/omap-keypad.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,8 +100,20 @@ static irqreturn_t omap_kp_interrupt(int
 	/* disable keyboard interrupt and schedule for handling */
 	if (cpu_is_omap24xx()) {
 		int i;
-		for (i = 0; i < omap_kp->rows; i++)
-			disable_irq(gpio_to_irq(row_gpios[i]));
+
+		for (i = 0; i < omap_kp->rows; i++) {
+			int gpio_irq = gpio_to_irq(row_gpios[i]);
+			/*
+			 * The interrupt which we're currently handling should
+			 * be disabled _nosync() to avoid deadlocks waiting
+			 * for this handler to complete.  All others should
+			 * be disabled the regular way for SMP safety.
+			 */
+			if (gpio_irq == irq)
+				disable_irq_nosync(gpio_irq);
+			else
+				disable_irq(gpio_irq);
+		}
 	} else
 		/* disable keyboard interrupt and schedule for handling */
 		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/sh_keysc.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/sh_keysc.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/sh_keysc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/sh_keysc.c	2009-06-09 23:05:27.000000000 -0400
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(stru
 		  pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
 	iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
 	iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
+
+	device_init_wakeup(&pdev->dev, 1);
 	return 0;
  err5:
 	free_irq(irq, pdev);
@@ -253,17 +255,48 @@ static int __devexit sh_keysc_remove(str
 	return 0;
 }
 
+static int sh_keysc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
+	unsigned short value;
 
-#define sh_keysc_suspend NULL
-#define sh_keysc_resume NULL
+	value = ioread16(priv->iomem_base + KYCR1_OFFS);
+
+	if (device_may_wakeup(dev)) {
+		value |= 0x80;
+		enable_irq_wake(irq);
+	}
+	else
+		value &= ~0x80;
+
+	iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+	return 0;
+}
+
+static int sh_keysc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int irq = platform_get_irq(pdev, 0);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(irq);
+
+	return 0;
+}
+
+static struct dev_pm_ops sh_keysc_dev_pm_ops = {
+	.suspend = sh_keysc_suspend,
+	.resume = sh_keysc_resume,
+};
 
 struct platform_driver sh_keysc_device_driver = {
 	.probe		= sh_keysc_probe,
 	.remove		= __devexit_p(sh_keysc_remove),
-	.suspend	= sh_keysc_suspend,
-	.resume		= sh_keysc_resume,
 	.driver		= {
 		.name	= "sh_keysc",
+		.pm	= &sh_keysc_dev_pm_ops,
 	}
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/keyboard/spitzkbd.c linux-libre-2.6.30-gnu1/drivers/input/keyboard/spitzkbd.c
--- linux-libre-2.6.29-gnu1/drivers/input/keyboard/spitzkbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/keyboard/spitzkbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,8 +21,6 @@
 #include <linux/slab.h>
 
 #include <mach/spitz.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 
 #define KB_ROWS			7
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/misc/ati_remote2.c linux-libre-2.6.30-gnu1/drivers/input/misc/ati_remote2.c
--- linux-libre-2.6.29-gnu1/drivers/input/misc/ati_remote2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/misc/ati_remote2.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,12 +31,73 @@ MODULE_LICENSE("GPL");
  * newly configured "channel".
  */
 
-static unsigned int channel_mask = 0xFFFF;
-module_param(channel_mask, uint, 0644);
+enum {
+	ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF,
+	ATI_REMOTE2_MAX_MODE_MASK = 0x1F,
+};
+
+static int ati_remote2_set_mask(const char *val,
+				struct kernel_param *kp, unsigned int max)
+{
+	unsigned long mask;
+	int ret;
+
+	if (!val)
+		return -EINVAL;
+
+	ret = strict_strtoul(val, 0, &mask);
+	if (ret)
+		return ret;
+
+	if (mask & ~max)
+		return -EINVAL;
+
+	*(unsigned int *)kp->arg = mask;
+
+	return 0;
+}
+
+static int ati_remote2_set_channel_mask(const char *val,
+					struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
+}
+
+static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
+}
+
+static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
+}
+
+static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
+{
+	pr_debug("%s()\n", __func__);
+
+	return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg);
+}
+
+static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
+#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_channel_mask ati_remote2_set_channel_mask
+#define param_get_channel_mask ati_remote2_get_channel_mask
+module_param(channel_mask, channel_mask, 0644);
 MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
 
-static unsigned int mode_mask = 0x1F;
-module_param(mode_mask, uint, 0644);
+static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
+#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
+#define param_set_mode_mask ati_remote2_set_mode_mask
+#define param_get_mode_mask ati_remote2_get_mode_mask
+module_param(mode_mask, mode_mask, 0644);
 MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
 
 static struct usb_device_id ati_remote2_id_table[] = {
@@ -133,12 +194,18 @@ struct ati_remote2 {
 	u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
 
 	unsigned int flags;
+
+	unsigned int channel_mask;
+	unsigned int mode_mask;
 };
 
 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
 static void ati_remote2_disconnect(struct usb_interface *interface);
 static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
 static int ati_remote2_resume(struct usb_interface *interface);
+static int ati_remote2_reset_resume(struct usb_interface *interface);
+static int ati_remote2_pre_reset(struct usb_interface *interface);
+static int ati_remote2_post_reset(struct usb_interface *interface);
 
 static struct usb_driver ati_remote2_driver = {
 	.name       = "ati_remote2",
@@ -147,6 +214,9 @@ static struct usb_driver ati_remote2_dri
 	.id_table   = ati_remote2_id_table,
 	.suspend    = ati_remote2_suspend,
 	.resume     = ati_remote2_resume,
+	.reset_resume = ati_remote2_reset_resume,
+	.pre_reset  = ati_remote2_pre_reset,
+	.post_reset = ati_remote2_post_reset,
 	.supports_autosuspend = 1,
 };
 
@@ -238,7 +308,7 @@ static void ati_remote2_input_mouse(stru
 
 	channel = data[0] >> 4;
 
-	if (!((1 << channel) & channel_mask))
+	if (!((1 << channel) & ar2->channel_mask))
 		return;
 
 	mode = data[0] & 0x0F;
@@ -250,7 +320,7 @@ static void ati_remote2_input_mouse(stru
 		return;
 	}
 
-	if (!((1 << mode) & mode_mask))
+	if (!((1 << mode) & ar2->mode_mask))
 		return;
 
 	input_event(idev, EV_REL, REL_X, (s8) data[1]);
@@ -277,7 +347,7 @@ static void ati_remote2_input_key(struct
 
 	channel = data[0] >> 4;
 
-	if (!((1 << channel) & channel_mask))
+	if (!((1 << channel) & ar2->channel_mask))
 		return;
 
 	mode = data[0] & 0x0F;
@@ -305,7 +375,7 @@ static void ati_remote2_input_key(struct
 			ar2->mode = mode;
 	}
 
-	if (!((1 << mode) & mode_mask))
+	if (!((1 << mode) & ar2->mode_mask))
 		return;
 
 	index = ati_remote2_lookup(hw_code);
@@ -410,7 +480,7 @@ static int ati_remote2_getkeycode(struct
 	int index, mode;
 
 	mode = scancode >> 8;
-	if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
 		return -EINVAL;
 
 	index = ati_remote2_lookup(scancode & 0xFF);
@@ -427,7 +497,7 @@ static int ati_remote2_setkeycode(struct
 	int index, mode, old_keycode;
 
 	mode = scancode >> 8;
-	if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+	if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
 		return -EINVAL;
 
 	index = ati_remote2_lookup(scancode & 0xFF);
@@ -550,7 +620,7 @@ static void ati_remote2_urb_cleanup(stru
 	}
 }
 
-static int ati_remote2_setup(struct ati_remote2 *ar2)
+static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask)
 {
 	int r, i, channel;
 
@@ -565,8 +635,8 @@ static int ati_remote2_setup(struct ati_
 
 	channel = 0;
 	for (i = 0; i < 16; i++) {
-		if ((1 << i) & channel_mask) {
-			if (!(~(1 << i) & 0xFFFF & channel_mask))
+		if ((1 << i) & ch_mask) {
+			if (!(~(1 << i) & ch_mask))
 				channel = i + 1;
 			break;
 		}
@@ -585,6 +655,99 @@ static int ati_remote2_setup(struct ati_
 	return 0;
 }
 
+static ssize_t ati_remote2_show_channel_mask(struct device *dev,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+	return sprintf(buf, "0x%04x\n", ar2->channel_mask);
+}
+
+static ssize_t ati_remote2_store_channel_mask(struct device *dev,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+	unsigned long mask;
+	int r;
+
+	if (strict_strtoul(buf, 0, &mask))
+		return -EINVAL;
+
+	if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK)
+		return -EINVAL;
+
+	r = usb_autopm_get_interface(ar2->intf[0]);
+	if (r) {
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): usb_autopm_get_interface() = %d\n", __func__, r);
+		return r;
+	}
+
+	mutex_lock(&ati_remote2_mutex);
+
+	if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))
+		ar2->channel_mask = mask;
+
+	mutex_unlock(&ati_remote2_mutex);
+
+	usb_autopm_put_interface(ar2->intf[0]);
+
+	return count;
+}
+
+static ssize_t ati_remote2_show_mode_mask(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+
+	return sprintf(buf, "0x%02x\n", ar2->mode_mask);
+}
+
+static ssize_t ati_remote2_store_mode_mask(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+	struct ati_remote2 *ar2 = usb_get_intfdata(intf);
+	unsigned long mask;
+
+	if (strict_strtoul(buf, 0, &mask))
+		return -EINVAL;
+
+	if (mask & ~ATI_REMOTE2_MAX_MODE_MASK)
+		return -EINVAL;
+
+	ar2->mode_mask = mask;
+
+	return count;
+}
+
+static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask,
+		   ati_remote2_store_channel_mask);
+
+static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask,
+		   ati_remote2_store_mode_mask);
+
+static struct attribute *ati_remote2_attrs[] = {
+	&dev_attr_channel_mask.attr,
+	&dev_attr_mode_mask.attr,
+	NULL,
+};
+
+static struct attribute_group ati_remote2_attr_group = {
+	.attrs = ati_remote2_attrs,
+};
+
 static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(interface);
@@ -615,7 +778,10 @@ static int ati_remote2_probe(struct usb_
 	if (r)
 		goto fail2;
 
-	r = ati_remote2_setup(ar2);
+	ar2->channel_mask = channel_mask;
+	ar2->mode_mask = mode_mask;
+
+	r = ati_remote2_setup(ar2, ar2->channel_mask);
 	if (r)
 		goto fail2;
 
@@ -624,19 +790,24 @@ static int ati_remote2_probe(struct usb_
 
 	strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
 
-	r = ati_remote2_input_init(ar2);
+	r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
 	if (r)
 		goto fail2;
 
+	r = ati_remote2_input_init(ar2);
+	if (r)
+		goto fail3;
+
 	usb_set_intfdata(interface, ar2);
 
 	interface->needs_remote_wakeup = 1;
 
 	return 0;
 
+ fail3:
+	sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
  fail2:
 	ati_remote2_urb_cleanup(ar2);
-
 	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
  fail1:
 	kfree(ar2);
@@ -657,6 +828,8 @@ static void ati_remote2_disconnect(struc
 
 	input_unregister_device(ar2->idev);
 
+	sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group);
+
 	ati_remote2_urb_cleanup(ar2);
 
 	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
@@ -712,6 +885,78 @@ static int ati_remote2_resume(struct usb
 
 	mutex_unlock(&ati_remote2_mutex);
 
+	return r;
+}
+
+static int ati_remote2_reset_resume(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	int r = 0;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	mutex_lock(&ati_remote2_mutex);
+
+	r = ati_remote2_setup(ar2, ar2->channel_mask);
+	if (r)
+		goto out;
+
+	if (ar2->flags & ATI_REMOTE2_OPENED)
+		r = ati_remote2_submit_urbs(ar2);
+
+	if (!r)
+		ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
+
+ out:
+	mutex_unlock(&ati_remote2_mutex);
+
+	return r;
+}
+
+static int ati_remote2_pre_reset(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	mutex_lock(&ati_remote2_mutex);
+
+	if (ar2->flags == ATI_REMOTE2_OPENED)
+		ati_remote2_kill_urbs(ar2);
+
+	return 0;
+}
+
+static int ati_remote2_post_reset(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	int r = 0;
+
+	if (alt->desc.bInterfaceNumber)
+		return 0;
+
+	ar2 = usb_get_intfdata(interface);
+
+	dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+	if (ar2->flags == ATI_REMOTE2_OPENED)
+		r = ati_remote2_submit_urbs(ar2);
+
+	mutex_unlock(&ati_remote2_mutex);
+
 	return r;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/misc/Kconfig linux-libre-2.6.30-gnu1/drivers/input/misc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/input/misc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/misc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -214,7 +214,7 @@ config INPUT_SGI_BTNS
 
 config HP_SDC_RTC
 	tristate "HP SDC Real Time Clock"
-	depends on GSC || HP300
+	depends on (GSC || HP300) && SERIO
 	select HP_SDC
 	help
 	  Say Y here if you want to support the built-in real time clock
@@ -227,4 +227,27 @@ config INPUT_PCF50633_PMU
 	 Say Y to include support for delivering  PMU events via  input
 	 layer on NXP PCF50633.
 
+config INPUT_GPIO_ROTARY_ENCODER
+	tristate "Rotary encoders connected to GPIO pins"
+	depends on GPIOLIB && GENERIC_GPIO
+	help
+	  Say Y here to add support for rotary encoders connected to GPIO lines.
+	  Check file:Documentation/incput/rotary_encoder.txt for more
+	  information.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rotary_encoder.
+
+config INPUT_RB532_BUTTON
+	tristate "Mikrotik Routerboard 532 button interface"
+	depends on MIKROTIK_RB532
+	depends on GPIOLIB && GENERIC_GPIO
+	select INPUT_POLLDEV
+	help
+	  Say Y here if you want support for the S1 button built into
+	  Mikrotik's Routerboard 532.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rb532_button.
+
 endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/misc/Makefile linux-libre-2.6.30-gnu1/drivers/input/misc/Makefile
--- linux-libre-2.6.29-gnu1/drivers/input/misc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/misc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,21 +4,23 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
-obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
-obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
-obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
-obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
-obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
+obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
 obj-$(CONFIG_INPUT_ATI_REMOTE)		+= ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
-obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
-obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
-obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
+obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
 obj-$(CONFIG_INPUT_CM109)		+= cm109.o
+obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
-obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
-obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
+obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)	+= pcf50633-input.o
+obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
+obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
+obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
+obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
+obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
+obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
+obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
+obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/misc/rb532_button.c linux-libre-2.6.30-gnu1/drivers/input/misc/rb532_button.c
--- linux-libre-2.6.29-gnu1/drivers/input/misc/rb532_button.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/misc/rb532_button.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,120 @@
+/*
+ * Support for the S1 button on Routerboard 532
+ *
+ * Copyright (C) 2009  Phil Sutter <n0-1@freewrt.org>
+ */
+
+#include <linux/input-polldev.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+#define DRV_NAME "rb532-button"
+
+#define RB532_BTN_RATE 100 /* msec */
+#define RB532_BTN_KSYM BTN_0
+
+/* The S1 button state is provided by GPIO pin 1. But as this
+ * pin is also used for uart input as alternate function, the
+ * operational modes must be switched first:
+ * 1) disable uart using set_latch_u5()
+ * 2) turn off alternate function implicitly through
+ *    gpio_direction_input()
+ * 3) read the GPIO's current value
+ * 4) undo step 2 by enabling alternate function (in this
+ *    mode the GPIO direction is fixed, so no change needed)
+ * 5) turn on uart again
+ * The GPIO value occurs to be inverted, so pin high means
+ * button is not pressed.
+ */
+static bool rb532_button_pressed(void)
+{
+	int val;
+
+	set_latch_u5(0, LO_FOFF);
+	gpio_direction_input(GPIO_BTN_S1);
+
+	val = gpio_get_value(GPIO_BTN_S1);
+
+	rb532_gpio_set_func(GPIO_BTN_S1);
+	set_latch_u5(LO_FOFF, 0);
+
+	return !val;
+}
+
+static void rb532_button_poll(struct input_polled_dev *poll_dev)
+{
+	input_report_key(poll_dev->input, RB532_BTN_KSYM,
+			 rb532_button_pressed());
+	input_sync(poll_dev->input);
+}
+
+static int __devinit rb532_button_probe(struct platform_device *pdev)
+{
+	struct input_polled_dev *poll_dev;
+	int error;
+
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev)
+		return -ENOMEM;
+
+	poll_dev->poll = rb532_button_poll;
+	poll_dev->poll_interval = RB532_BTN_RATE;
+
+	poll_dev->input->name = "rb532 button";
+	poll_dev->input->phys = "rb532/button0";
+	poll_dev->input->id.bustype = BUS_HOST;
+	poll_dev->input->dev.parent = &pdev->dev;
+
+	dev_set_drvdata(&pdev->dev, poll_dev);
+
+	input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);
+
+	error = input_register_polled_device(poll_dev);
+	if (error) {
+		input_free_polled_device(poll_dev);
+		return error;
+	}
+
+	return 0;
+}
+
+static int __devexit rb532_button_remove(struct platform_device *pdev)
+{
+	struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev);
+
+	input_unregister_polled_device(poll_dev);
+	input_free_polled_device(poll_dev);
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver rb532_button_driver = {
+	.probe = rb532_button_probe,
+	.remove = __devexit_p(rb532_button_remove),
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init rb532_button_init(void)
+{
+	return platform_driver_register(&rb532_button_driver);
+}
+
+static void __exit rb532_button_exit(void)
+{
+	platform_driver_unregister(&rb532_button_driver);
+}
+
+module_init(rb532_button_init);
+module_exit(rb532_button_exit);
+
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Support for S1 button on Routerboard 532");
+MODULE_ALIAS("platform:" DRV_NAME);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/misc/rotary_encoder.c linux-libre-2.6.30-gnu1/drivers/input/misc/rotary_encoder.c
--- linux-libre-2.6.29-gnu1/drivers/input/misc/rotary_encoder.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/misc/rotary_encoder.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,221 @@
+/*
+ * rotary_encoder.c
+ *
+ * (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * state machine code inspired by code from Tim Ruetz
+ *
+ * A generic driver for rotary encoders connected to GPIO lines.
+ * See file:Documentation/input/rotary_encoder.txt for more information
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/rotary_encoder.h>
+
+#define DRV_NAME "rotary-encoder"
+
+struct rotary_encoder {
+	unsigned int irq_a;
+	unsigned int irq_b;
+	unsigned int pos;
+	unsigned int armed;
+	unsigned int dir;
+	struct input_dev *input;
+	struct rotary_encoder_platform_data *pdata;
+};
+
+static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
+{
+	struct rotary_encoder *encoder = dev_id;
+	struct rotary_encoder_platform_data *pdata = encoder->pdata;
+	int a = !!gpio_get_value(pdata->gpio_a);
+	int b = !!gpio_get_value(pdata->gpio_b);
+	int state;
+
+	a ^= pdata->inverted_a;
+	b ^= pdata->inverted_b;
+	state = (a << 1) | b;
+
+	switch (state) {
+
+	case 0x0:
+		if (!encoder->armed)
+			break;
+
+		if (encoder->dir) {
+			/* turning counter-clockwise */
+			encoder->pos += pdata->steps;
+			encoder->pos--;
+			encoder->pos %= pdata->steps;
+		} else {
+			/* turning clockwise */
+			encoder->pos++;
+			encoder->pos %= pdata->steps;
+		}
+
+		input_report_abs(encoder->input, pdata->axis, encoder->pos);
+		input_sync(encoder->input);
+
+		encoder->armed = 0;
+		break;
+
+	case 0x1:
+	case 0x2:
+		if (encoder->armed)
+			encoder->dir = state - 1;
+		break;
+
+	case 0x3:
+		encoder->armed = 1;
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit rotary_encoder_probe(struct platform_device *pdev)
+{
+	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+	struct rotary_encoder *encoder;
+	struct input_dev *input;
+	int err;
+
+	if (!pdata || !pdata->steps) {
+		dev_err(&pdev->dev, "invalid platform data\n");
+		return -ENOENT;
+	}
+
+	encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
+	input = input_allocate_device();
+	if (!encoder || !input) {
+		dev_err(&pdev->dev, "failed to allocate memory for device\n");
+		err = -ENOMEM;
+		goto exit_free_mem;
+	}
+
+	encoder->input = input;
+	encoder->pdata = pdata;
+	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
+	encoder->irq_b = gpio_to_irq(pdata->gpio_b);
+
+	/* create and register the input driver */
+	input->name = pdev->name;
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &pdev->dev;
+	input->evbit[0] = BIT_MASK(EV_ABS);
+	input_set_abs_params(encoder->input,
+			     pdata->axis, 0, pdata->steps, 0, 1);
+
+	err = input_register_device(input);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		goto exit_free_mem;
+	}
+
+	/* request the GPIOs */
+	err = gpio_request(pdata->gpio_a, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request GPIO %d\n",
+			pdata->gpio_a);
+		goto exit_unregister_input;
+	}
+
+	err = gpio_request(pdata->gpio_b, DRV_NAME);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request GPIO %d\n",
+			pdata->gpio_b);
+		goto exit_free_gpio_a;
+	}
+
+	/* request the IRQs */
+	err = request_irq(encoder->irq_a, &rotary_encoder_irq,
+			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+			  DRV_NAME, encoder);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request IRQ %d\n",
+			encoder->irq_a);
+		goto exit_free_gpio_b;
+	}
+
+	err = request_irq(encoder->irq_b, &rotary_encoder_irq,
+			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+			  DRV_NAME, encoder);
+	if (err) {
+		dev_err(&pdev->dev, "unable to request IRQ %d\n",
+			encoder->irq_b);
+		goto exit_free_irq_a;
+	}
+
+	platform_set_drvdata(pdev, encoder);
+
+	return 0;
+
+exit_free_irq_a:
+	free_irq(encoder->irq_a, encoder);
+exit_free_gpio_b:
+	gpio_free(pdata->gpio_b);
+exit_free_gpio_a:
+	gpio_free(pdata->gpio_a);
+exit_unregister_input:
+	input_unregister_device(input);
+	input = NULL; /* so we don't try to free it */
+exit_free_mem:
+	input_free_device(input);
+	kfree(encoder);
+	return err;
+}
+
+static int __devexit rotary_encoder_remove(struct platform_device *pdev)
+{
+	struct rotary_encoder *encoder = platform_get_drvdata(pdev);
+	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
+
+	free_irq(encoder->irq_a, encoder);
+	free_irq(encoder->irq_b, encoder);
+	gpio_free(pdata->gpio_a);
+	gpio_free(pdata->gpio_b);
+	input_unregister_device(encoder->input);
+	platform_set_drvdata(pdev, NULL);
+	kfree(encoder);
+
+	return 0;
+}
+
+static struct platform_driver rotary_encoder_driver = {
+	.probe		= rotary_encoder_probe,
+	.remove		= __devexit_p(rotary_encoder_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init rotary_encoder_init(void)
+{
+	return platform_driver_register(&rotary_encoder_driver);
+}
+
+static void __exit rotary_encoder_exit(void)
+{
+	platform_driver_unregister(&rotary_encoder_driver);
+}
+
+module_init(rotary_encoder_init);
+module_exit(rotary_encoder_exit);
+
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DESCRIPTION("GPIO rotary encoder driver");
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_LICENSE("GPL v2");
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/alps.c linux-libre-2.6.30-gnu1/drivers/input/mouse/alps.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/alps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/alps.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,7 @@
 #define ALPS_FW_BK_2	0x40
 
 static const struct alps_model_info alps_model_data[] = {
+	{ { 0x32, 0x02, 0x14 },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
 	{ { 0x33, 0x02, 0x0a },	0x88, 0xf8, ALPS_OLDPROTO },		/* UMAX-530T */
 	{ { 0x53, 0x02, 0x0a },	0xf8, 0xf8, 0 },
 	{ { 0x53, 0x02, 0x14 },	0xf8, 0xf8, 0 },
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/appletouch.c linux-libre-2.6.30-gnu1/drivers/input/mouse/appletouch.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/appletouch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/appletouch.c	2009-06-09 23:05:27.000000000 -0400
@@ -255,15 +255,22 @@ MODULE_PARM_DESC(debug, "Activate debugg
  */
 static int atp_geyser_init(struct usb_device *udev)
 {
-	char data[8];
+	char *data;
 	int size;
 	int i;
+	int ret;
+
+	data = kmalloc(8, GFP_KERNEL);
+	if (!data) {
+		err("Out of memory");
+		return -ENOMEM;
+	}
 
 	size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			ATP_GEYSER_MODE_READ_REQUEST_ID,
 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 			ATP_GEYSER_MODE_REQUEST_VALUE,
-			ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
+			ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000);
 
 	if (size != 8) {
 		dprintk("atp_geyser_init: read error\n");
@@ -271,7 +278,8 @@ static int atp_geyser_init(struct usb_de
 			dprintk("appletouch[%d]: %d\n", i, data[i]);
 
 		err("Failed to read mode from device.");
-		return -EIO;
+		ret = -EIO;
+		goto out_free;
 	}
 
 	/* Apply the mode switch */
@@ -281,7 +289,7 @@ static int atp_geyser_init(struct usb_de
 			ATP_GEYSER_MODE_WRITE_REQUEST_ID,
 			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 			ATP_GEYSER_MODE_REQUEST_VALUE,
-			ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
+			ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000);
 
 	if (size != 8) {
 		dprintk("atp_geyser_init: write error\n");
@@ -289,9 +297,13 @@ static int atp_geyser_init(struct usb_de
 			dprintk("appletouch[%d]: %d\n", i, data[i]);
 
 		err("Failed to request geyser raw mode");
-		return -EIO;
+		ret = -EIO;
+		goto out_free;
 	}
-	return 0;
+	ret = 0;
+out_free:
+	kfree(data);
+	return ret;
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/bcm5974.c linux-libre-2.6.30-gnu1/drivers/input/mouse/bcm5974.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/bcm5974.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/bcm5974.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,10 @@
 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI	0x0230
 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO	0x0231
 #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS	0x0232
+/* Macbook5,1 (unibody), aka wellspring3 */
+#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 BCM5974_DEVICE(prod) {					\
 	.match_flags = (USB_DEVICE_ID_MATCH_DEVICE |		\
@@ -72,6 +76,10 @@ static const struct usb_device_id bcm597
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
+	/* Macbook5,1 */
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
 	/* Terminating entry */
 	{}
 };
@@ -96,14 +104,23 @@ struct bt_data {
 	u8 rel_y;		/* relative y coordinate */
 };
 
-/* trackpad header structure */
-struct tp_header {
-	u8 unknown1[16];	/* constants, timers, etc */
-	u8 fingers;		/* number of fingers on trackpad */
-	u8 unknown2[9];		/* constants, timers, etc */
+/* trackpad header types */
+enum tp_type {
+	TYPE1,			/* plain trackpad */
+	TYPE2			/* button integrated in trackpad */
 };
 
-/* trackpad finger structure */
+/* trackpad finger data offsets, le16-aligned */
+#define FINGER_TYPE1		(13 * sizeof(__le16))
+#define FINGER_TYPE2		(15 * sizeof(__le16))
+
+/* trackpad button data offsets */
+#define BUTTON_TYPE2		15
+
+/* list of device capability bits */
+#define HAS_INTEGRATED_BUTTON	1
+
+/* trackpad finger structure, le16-aligned */
 struct tp_finger {
 	__le16 origin;		/* zero when switching track finger */
 	__le16 abs_x;		/* absolute x coodinate */
@@ -117,13 +134,11 @@ struct tp_finger {
 	__le16 force_minor;	/* trackpad force, minor axis? */
 	__le16 unused[3];	/* zeros */
 	__le16 multi;		/* one finger: varies, more fingers: constant */
-};
+} __attribute__((packed,aligned(2)));
 
-/* trackpad data structure, empirically at least ten fingers */
-struct tp_data {
-	struct tp_header header;
-	struct tp_finger finger[16];
-};
+/* trackpad finger data size, empirically at least ten fingers */
+#define SIZEOF_FINGER		sizeof(struct tp_finger)
+#define SIZEOF_ALL_FINGERS	(16 * SIZEOF_FINGER)
 
 /* device-specific parameters */
 struct bcm5974_param {
@@ -136,9 +151,12 @@ struct bcm5974_param {
 /* device-specific configuration */
 struct bcm5974_config {
 	int ansi, iso, jis;	/* the product id of this device */
+	int caps;		/* device capability bitmask */
 	int bt_ep;		/* the endpoint of the button interface */
 	int bt_datalen;		/* data length of the button interface */
 	int tp_ep;		/* the endpoint of the trackpad interface */
+	enum tp_type tp_type;	/* type of trackpad interface */
+	int tp_offset;		/* offset to trackpad finger data */
 	int tp_datalen;		/* data length of the trackpad interface */
 	struct bcm5974_param p;	/* finger pressure limits */
 	struct bcm5974_param w;	/* finger width limits */
@@ -158,7 +176,7 @@ struct bcm5974 {
 	struct urb *bt_urb;		/* button usb request block */
 	struct bt_data *bt_data;	/* button transferred data */
 	struct urb *tp_urb;		/* trackpad usb request block */
-	struct tp_data *tp_data;	/* trackpad transferred data */
+	u8 *tp_data;			/* trackpad transferred data */
 	int fingers;			/* number of fingers on trackpad */
 };
 
@@ -183,8 +201,9 @@ static const struct bcm5974_config bcm59
 		USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
 		USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
 		USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
+		0,
 		0x84, sizeof(struct bt_data),
-		0x81, sizeof(struct tp_data),
+		0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
 		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
 		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
 		{ DIM_X, DIM_X / SN_COORD, -4824, 5342 },
@@ -194,13 +213,26 @@ static const struct bcm5974_config bcm59
 		USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
 		USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
 		USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
+		0,
 		0x84, sizeof(struct bt_data),
-		0x81, sizeof(struct tp_data),
+		0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
 		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
 		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
 		{ DIM_X, DIM_X / SN_COORD, -4824, 4824 },
 		{ DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
 	},
+	{
+		USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
+		USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
+		USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
+		HAS_INTEGRATED_BUTTON,
+		0x84, sizeof(struct bt_data),
+		0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+		{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
+		{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
+	},
 	{}
 };
 
@@ -257,6 +289,7 @@ static void setup_events_to_report(struc
 	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
 	__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
 	__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+	__set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
 	__set_bit(BTN_LEFT, input_dev->keybit);
 }
 
@@ -266,6 +299,11 @@ static int report_bt_state(struct bcm597
 	if (size != sizeof(struct bt_data))
 		return -EIO;
 
+	dprintk(7,
+		"bcm5974: button data: %x %x %x %x\n",
+		dev->bt_data->unknown1, dev->bt_data->button,
+		dev->bt_data->rel_x, dev->bt_data->rel_y);
+
 	input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
 	input_sync(dev->input);
 
@@ -276,29 +314,37 @@ static int report_bt_state(struct bcm597
 static int report_tp_state(struct bcm5974 *dev, int size)
 {
 	const struct bcm5974_config *c = &dev->cfg;
-	const struct tp_finger *f = dev->tp_data->finger;
+	const struct tp_finger *f;
 	struct input_dev *input = dev->input;
-	const int fingers = (size - 26) / 28;
-	int raw_p, raw_w, raw_x, raw_y;
-	int ptest = 0, origin = 0, nmin = 0, nmax = 0;
+	int raw_p, raw_w, raw_x, raw_y, raw_n;
+	int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
 	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
 
-	if (size < 26 || (size - 26) % 28 != 0)
+	if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
 		return -EIO;
 
+	/* finger data, le16-aligned */
+	f = (const struct tp_finger *)(dev->tp_data + c->tp_offset);
+	raw_n = (size - c->tp_offset) / SIZEOF_FINGER;
+
 	/* always track the first finger; when detached, start over */
-	if (fingers) {
+	if (raw_n) {
 		raw_p = raw2int(f->force_major);
 		raw_w = raw2int(f->size_major);
 		raw_x = raw2int(f->abs_x);
 		raw_y = raw2int(f->abs_y);
 
 		dprintk(9,
-			"bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
-			raw_p, raw_w, raw_x, raw_y);
+			"bcm5974: "
+			"raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
+			raw_p, raw_w, raw_x, raw_y, raw_n);
 
 		ptest = int2bound(&c->p, raw_p);
 		origin = raw2int(f->origin);
+
+		/* set the integrated button if applicable */
+		if (c->tp_type == TYPE2)
+			ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
 	}
 
 	/* while tracking finger still valid, count all fingers */
@@ -307,12 +353,13 @@ static int report_tp_state(struct bcm597
 		abs_w = int2bound(&c->w, raw_w);
 		abs_x = int2bound(&c->x, raw_x - c->x.devmin);
 		abs_y = int2bound(&c->y, c->y.devmax - raw_y);
-		for (; f != dev->tp_data->finger + fingers; f++) {
+		while (raw_n--) {
 			ptest = int2bound(&c->p, raw2int(f->force_major));
 			if (ptest > PRESSURE_LOW)
 				nmax++;
 			if (ptest > PRESSURE_HIGH)
 				nmin++;
+			f++;
 		}
 	}
 
@@ -324,7 +371,8 @@ static int report_tp_state(struct bcm597
 	input_report_key(input, BTN_TOUCH, dev->fingers > 0);
 	input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
 	input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
-	input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
+	input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3);
+	input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3);
 
 	input_report_abs(input, ABS_PRESSURE, abs_p);
 	input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
@@ -335,11 +383,15 @@ static int report_tp_state(struct bcm597
 
 		dprintk(8,
 			"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
-			"nmin: %d nmax: %d n: %d\n",
-			abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
+			"nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w,
+			abs_x, abs_y, nmin, nmax, dev->fingers, ibt);
 
 	}
 
+	/* type 2 reports button events via ibt only */
+	if (c->tp_type == TYPE2)
+		input_report_key(input, BTN_LEFT, ibt);
+
 	input_sync(input);
 
 	return 0;
@@ -649,6 +701,8 @@ static int bcm5974_probe(struct usb_inte
 	input_dev->name = "bcm5974";
 	input_dev->phys = dev->phys;
 	usb_to_input_id(dev->udev, &input_dev->id);
+	/* report driver capabilities via the version field */
+	input_dev->id.version = cfg->caps;
 	input_dev->dev.parent = &iface->dev;
 
 	input_set_drvdata(input_dev, dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/elantech.c linux-libre-2.6.30-gnu1/drivers/input/mouse/elantech.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/elantech.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/elantech.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * Elantech Touchpad driver (v5)
+ * Elantech Touchpad driver (v6)
  *
- * Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net>
+ * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -178,6 +178,7 @@ static void elantech_report_absolute_v1(
 	struct elantech_data *etd = psmouse->private;
 	unsigned char *packet = psmouse->packet;
 	int fingers;
+	static int old_fingers;
 
 	if (etd->fw_version_maj == 0x01) {
 		/* byte 0:  D   U  p1  p2   1  p3   R   L
@@ -190,6 +191,14 @@ static void elantech_report_absolute_v1(
 		fingers = (packet[0] & 0xc0) >> 6;
 	}
 
+	if (etd->jumpy_cursor) {
+		/* Discard packets that are likely to have bogus coordinates */
+		if (fingers > old_fingers) {
+			elantech_debug("elantech.c: discarding packet\n");
+			goto discard_packet_v1;
+		}
+	}
+
 	input_report_key(dev, BTN_TOUCH, fingers != 0);
 
 	/* byte 2: x7  x6  x5  x4  x3  x2  x1  x0
@@ -216,6 +225,9 @@ static void elantech_report_absolute_v1(
 	}
 
 	input_sync(dev);
+
+ discard_packet_v1:
+	old_fingers = fingers;
 }
 
 /*
@@ -363,9 +375,14 @@ static int elantech_set_absolute_mode(st
 			rc = -1;
 			break;
 		}
+	}
+
+	if (rc == 0) {
 		/*
-		 * Read back reg 0x10. The touchpad is probably initalising
-		 * and not ready until we read back the value we just wrote.
+		 * Read back reg 0x10. For hardware version 1 we must make
+		 * sure the absolute mode bit is set. For hardware version 2
+		 * the touchpad is probably initalising and not ready until
+		 * we read back the value we just wrote.
 		 */
 		do {
 			rc = elantech_read_reg(psmouse, 0x10, &val);
@@ -373,12 +390,18 @@ static int elantech_set_absolute_mode(st
 				break;
 			tries--;
 			elantech_debug("elantech.c: retrying read (%d).\n",
-				tries);
+					tries);
 			msleep(ETP_READ_BACK_DELAY);
 		} while (tries > 0);
-		if (rc)
+
+		if (rc) {
 			pr_err("elantech.c: failed to read back register 0x10.\n");
-		break;
+		} else if (etd->hw_version == 1 &&
+			   !(val & ETP_R10_ABSOLUTE_MODE)) {
+			pr_err("elantech.c: touchpad refuses "
+				"to switch to absolute mode.\n");
+			rc = -1;
+		}
 	}
 
 	if (rc)
@@ -662,6 +685,17 @@ int elantech_init(struct psmouse *psmous
 		param[0], param[1], param[2]);
 	etd->capabilities = param[0];
 
+	/*
+	 * This firmware seems to suffer from misreporting coordinates when
+	 * a touch action starts causing the mouse cursor or scrolled page
+	 * to jump. Enable a workaround.
+	 */
+	if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
+		pr_info("elantech.c: firmware version 2.34 detected, "
+			"enabling jumpy cursor workaround\n");
+		etd->jumpy_cursor = 1;
+	}
+
 	if (elantech_set_absolute_mode(psmouse)) {
 		pr_err("elantech.c: failed to put touchpad into absolute mode.\n");
 		goto init_fail;
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/elantech.h linux-libre-2.6.30-gnu1/drivers/input/mouse/elantech.h
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/elantech.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/elantech.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * Elantech Touchpad driver (v5)
+ * Elantech Touchpad driver (v6)
  *
- * Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net>
+ * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -104,6 +104,7 @@ struct elantech_data {
 	unsigned char fw_version_min;
 	unsigned char hw_version;
 	unsigned char paritycheck;
+	unsigned char jumpy_cursor;
 	unsigned char parity[256];
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/gpio_mouse.c linux-libre-2.6.30-gnu1/drivers/input/mouse/gpio_mouse.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/gpio_mouse.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/gpio_mouse.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,7 @@
 
 /*
  * Timer function which is run every scan_ms ms when the device is opened.
- * The dev input varaible is set to the the input_dev pointer.
+ * The dev input variable is set to the the input_dev pointer.
  */
 static void gpio_mouse_scan(struct input_polled_dev *dev)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/hgpk.c linux-libre-2.6.30-gnu1/drivers/input/mouse/hgpk.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/hgpk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/hgpk.c	2009-06-09 23:05:27.000000000 -0400
@@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmou
 
 static void hgpk_recalib_work(struct work_struct *work)
 {
-	struct delayed_work *w = container_of(work, struct delayed_work, work);
+	struct delayed_work *w = to_delayed_work(work);
 	struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
 	struct psmouse *psmouse = priv->psmouse;
 
@@ -472,7 +472,7 @@ static enum hgpk_model_t hgpk_get_model(
 		return -EIO;
 	}
 
-	hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
+	hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]);
 
 	/* HGPK signature: 0x67, 0x00, 0x<model> */
 	if (param[0] != 0x67 || param[1] != 0x00)
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/Kconfig linux-libre-2.6.30-gnu1/drivers/input/mouse/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@ config MOUSE_PS2
 	default y
 	select SERIO
 	select SERIO_LIBPS2
-	select SERIO_I8042 if X86_PC
+	select SERIO_I8042 if X86
 	select SERIO_GSCPS2 if GSC
 	help
 	  Say Y here if you have a PS/2 mouse connected to your system. This
@@ -292,4 +292,15 @@ config MOUSE_PXA930_TRKBALL
 	help
 	  Say Y here to support PXA930 Trackball mouse.
 
+config MOUSE_MAPLE
+	tristate "Maple mouse (for the Dreamcast)"
+	depends on MAPLE
+	help
+	  This driver supports the Maple mouse on the SEGA Dreamcast.
+
+	  Most Dreamcast users, who have a mouse, will say Y here.
+
+	  To compile this driver as a module choose M here: the module will be
+	  called maplemouse.
+
 endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/lifebook.c linux-libre-2.6.30-gnu1/drivers/input/mouse/lifebook.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/lifebook.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/lifebook.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,6 +61,12 @@ static const struct dmi_system_id lifebo
 		},
 	},
 	{
+		.ident = "Lifebook B-2130",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"),
+		},
+	},
+	{
 		.ident = "Lifebook B213x/B2150",
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"),
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/Makefile linux-libre-2.6.30-gnu1/drivers/input/mouse/Makefile
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,18 +6,19 @@
 
 obj-$(CONFIG_MOUSE_AMIGA)		+= amimouse.o
 obj-$(CONFIG_MOUSE_APPLETOUCH)		+= appletouch.o
-obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
 obj-$(CONFIG_MOUSE_ATARI)		+= atarimouse.o
-obj-$(CONFIG_MOUSE_RISCPC)		+= rpcmouse.o
+obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
+obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
+obj-$(CONFIG_MOUSE_HIL)			+= hil_ptr.o
 obj-$(CONFIG_MOUSE_INPORT)		+= inport.o
 obj-$(CONFIG_MOUSE_LOGIBM)		+= logibm.o
+obj-$(CONFIG_MOUSE_MAPLE)		+= maplemouse.o
 obj-$(CONFIG_MOUSE_PC110PAD)		+= pc110pad.o
 obj-$(CONFIG_MOUSE_PS2)			+= psmouse.o
 obj-$(CONFIG_MOUSE_PXA930_TRKBALL)	+= pxa930_trkball.o
+obj-$(CONFIG_MOUSE_RISCPC)		+= rpcmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)		+= sermouse.o
-obj-$(CONFIG_MOUSE_HIL)			+= hil_ptr.o
 obj-$(CONFIG_MOUSE_VSXXXAA)		+= vsxxxaa.o
-obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
 
 psmouse-objs := psmouse-base.o synaptics.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/maplemouse.c linux-libre-2.6.30-gnu1/drivers/input/mouse/maplemouse.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/maplemouse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/maplemouse.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,150 @@
+/*
+ *	SEGA Dreamcast mouse driver
+ *	Based on drivers/usb/usbmouse.c
+ *
+ *	Copyright (c) Yaegashi Takeshi, 2001
+ *	Copyright (c) Adrian McMenamin, 2008 - 2009
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/maple.h>
+
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
+MODULE_DESCRIPTION("SEGA Dreamcast mouse driver");
+MODULE_LICENSE("GPL");
+
+struct dc_mouse {
+	struct input_dev *dev;
+	struct maple_device *mdev;
+};
+
+static void dc_mouse_callback(struct mapleq *mq)
+{
+	int buttons, relx, rely, relz;
+	struct maple_device *mapledev = mq->dev;
+	struct dc_mouse *mse = maple_get_drvdata(mapledev);
+	struct input_dev *dev = mse->dev;
+	unsigned char *res = mq->recvbuf->buf;
+
+	buttons = ~res[8];
+	relx = *(unsigned short *)(res + 12) - 512;
+	rely = *(unsigned short *)(res + 14) - 512;
+	relz = *(unsigned short *)(res + 16) - 512;
+
+	input_report_key(dev, BTN_LEFT,   buttons & 4);
+	input_report_key(dev, BTN_MIDDLE, buttons & 9);
+	input_report_key(dev, BTN_RIGHT,  buttons & 2);
+	input_report_rel(dev, REL_X,      relx);
+	input_report_rel(dev, REL_Y,      rely);
+	input_report_rel(dev, REL_WHEEL,  relz);
+	input_sync(dev);
+}
+
+static int dc_mouse_open(struct input_dev *dev)
+{
+	struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
+
+	maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50,
+		MAPLE_FUNC_MOUSE);
+
+	return 0;
+}
+
+static void dc_mouse_close(struct input_dev *dev)
+{
+	struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev));
+
+	maple_getcond_callback(mse->mdev, dc_mouse_callback, 0,
+		MAPLE_FUNC_MOUSE);
+}
+
+/* allow the mouse to be used */
+static int __devinit probe_maple_mouse(struct device *dev)
+{
+	struct maple_device *mdev = to_maple_dev(dev);
+	struct maple_driver *mdrv = to_maple_driver(dev->driver);
+	int error;
+	struct input_dev *input_dev;
+	struct dc_mouse *mse;
+
+	mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL);
+	if (!mse) {
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		error = -ENOMEM;
+		goto fail_nomem;
+	}
+
+	mse->dev = input_dev;
+	mse->mdev = mdev;
+
+	input_set_drvdata(input_dev, mse);
+	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_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
+		BIT_MASK(REL_WHEEL);
+	input_dev->open = dc_mouse_open;
+	input_dev->close = dc_mouse_close;
+	input_dev->name = mdev->product_name;
+	input_dev->id.bustype = BUS_HOST;
+	error =	input_register_device(input_dev);
+	if (error)
+		goto fail_register;
+
+	mdev->driver = mdrv;
+	maple_set_drvdata(mdev, mse);
+
+	return error;
+
+fail_register:
+	input_free_device(input_dev);
+fail_nomem:
+	kfree(mse);
+fail:
+	return error;
+}
+
+static int __devexit remove_maple_mouse(struct device *dev)
+{
+	struct maple_device *mdev = to_maple_dev(dev);
+	struct dc_mouse *mse = maple_get_drvdata(mdev);
+
+	mdev->callback = NULL;
+	input_unregister_device(mse->dev);
+	maple_set_drvdata(mdev, NULL);
+	kfree(mse);
+
+	return 0;
+}
+
+static struct maple_driver dc_mouse_driver = {
+	.function =	MAPLE_FUNC_MOUSE,
+	.drv = {
+		.name = "Dreamcast_mouse",
+		.probe = probe_maple_mouse,
+		.remove = __devexit_p(remove_maple_mouse),
+	},
+};
+
+static int __init dc_mouse_init(void)
+{
+	return maple_driver_register(&dc_mouse_driver);
+}
+
+static void __exit dc_mouse_exit(void)
+{
+	maple_driver_unregister(&dc_mouse_driver);
+}
+
+module_init(dc_mouse_init);
+module_exit(dc_mouse_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/pc110pad.c linux-libre-2.6.30-gnu1/drivers/input/mouse/pc110pad.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/pc110pad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/pc110pad.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,14 +108,10 @@ static int pc110pad_open(struct input_de
  */
 static int __init pc110pad_init(void)
 {
-	struct pci_dev *dev;
 	int err;
 
-	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (dev) {
-		pci_dev_put(dev);
+	if (!no_pci_devices())
 		return -ENODEV;
-	}
 
 	if (!request_region(pc110pad_io, 4, "pc110pad")) {
 		printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mouse/rpcmouse.c linux-libre-2.6.30-gnu1/drivers/input/mouse/rpcmouse.c
--- linux-libre-2.6.29-gnu1/drivers/input/mouse/rpcmouse.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mouse/rpcmouse.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,10 +22,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/hardware/iomd.h>
 
 MODULE_AUTHOR("Vojtech Pavlik, Russell King");
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/mousedev.c linux-libre-2.6.30-gnu1/drivers/input/mousedev.c
--- linux-libre-2.6.29-gnu1/drivers/input/mousedev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/mousedev.c	2009-06-09 23:05:27.000000000 -0400
@@ -403,12 +403,9 @@ static void mousedev_event(struct input_
 
 static int mousedev_fasync(int fd, struct file *file, int on)
 {
-	int retval;
 	struct mousedev_client *client = file->private_data;
 
-	retval = fasync_helper(fd, file, on, &client->fasync);
-
-	return retval < 0 ? retval : 0;
+	return fasync_helper(fd, file, on, &client->fasync);
 }
 
 static void mousedev_free(struct device *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/ambakmi.c linux-libre-2.6.30-gnu1/drivers/input/serio/ambakmi.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/ambakmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/ambakmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio
 	clk_disable(kmi->clk);
 }
 
-static int amba_kmi_probe(struct amba_device *dev, void *id)
+static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct amba_kmi_port *kmi;
 	struct serio *io;
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/hp_sdc.c linux-libre-2.6.30-gnu1/drivers/input/serio/hp_sdc.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/hp_sdc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/hp_sdc.c	2009-06-09 23:05:27.000000000 -0400
@@ -819,6 +819,7 @@ static const struct parisc_device_id hp_
 MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
 
 static int __init hp_sdc_init_hppa(struct parisc_device *d);
+static struct delayed_work moduleloader_work;
 
 static struct parisc_driver hp_sdc_driver = {
 	.name =		"hp_sdc",
@@ -930,8 +931,15 @@ static int __init hp_sdc_init(void)
 
 #if defined(__hppa__)
 
+static void request_module_delayed(struct work_struct *work)
+{
+	request_module("hp_sdc_mlc");
+}
+
 static int __init hp_sdc_init_hppa(struct parisc_device *d)
 {
+	int ret;
+
 	if (!d)
 		return 1;
 	if (hp_sdc.dev != NULL)
@@ -944,13 +952,26 @@ static int __init hp_sdc_init_hppa(struc
 	hp_sdc.data_io		= d->hpa.start + 0x800;
 	hp_sdc.status_io	= d->hpa.start + 0x801;
 
-	return hp_sdc_init();
+	INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed);
+
+	ret = hp_sdc_init();
+	/* after sucessfull initialization give SDC some time to settle
+	 * and then load the hp_sdc_mlc upper layer driver */
+	if (!ret)
+		schedule_delayed_work(&moduleloader_work,
+			msecs_to_jiffies(2000));
+
+	return ret;
 }
 
 #endif /* __hppa__ */
 
 static void hp_sdc_exit(void)
 {
+	/* do nothing if we don't have a SDC */
+	if (!hp_sdc.dev)
+		return;
+
 	write_lock_irq(&hp_sdc.lock);
 
 	/* Turn off all maskable "sub-function" irq's. */
@@ -969,6 +990,7 @@ static void hp_sdc_exit(void)
 	tasklet_kill(&hp_sdc.task);
 
 #if defined(__hppa__)
+	cancel_delayed_work_sync(&moduleloader_work);
 	if (unregister_parisc_driver(&hp_sdc_driver))
 		printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/i8042.c linux-libre-2.6.30-gnu1/drivers/input/serio/i8042.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/i8042.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/i8042.c	2009-06-09 23:05:27.000000000 -0400
@@ -712,22 +712,43 @@ static int i8042_controller_check(void)
 static int i8042_controller_selftest(void)
 {
 	unsigned char param;
+	int i = 0;
 
 	if (!i8042_reset)
 		return 0;
 
-	if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
-		printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-		return -ENODEV;
-	}
+	/*
+	 * We try this 5 times; on some really fragile systems this does not
+	 * take the first time...
+	 */
+	do {
+
+		if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+			printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+			return -ENODEV;
+		}
+
+		if (param == I8042_RET_CTL_TEST)
+			return 0;
 
-	if (param != I8042_RET_CTL_TEST) {
 		printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
-			 param, I8042_RET_CTL_TEST);
-		return -EIO;
-	}
+			param, I8042_RET_CTL_TEST);
+		msleep(50);
+	} while (i++ < 5);
 
+#ifdef CONFIG_X86
+	/*
+	 * On x86, we don't fail entire i8042 initialization if controller
+	 * reset fails in hopes that keyboard port will still be functional
+	 * and user will still get a working keyboard. This is especially
+	 * important on netbooks. On other arches we trust hardware more.
+	 */
+	printk(KERN_INFO
+		"i8042: giving up on controller selftest, continuing anyway...\n");
 	return 0;
+#else
+	return -EIO;
+#endif
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/i8042-x86ia64io.h linux-libre-2.6.30-gnu1/drivers/input/serio/i8042-x86ia64io.h
--- linux-libre-2.6.29-gnu1/drivers/input/serio/i8042-x86ia64io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/i8042-x86ia64io.h	2009-06-09 23:05:27.000000000 -0400
@@ -151,6 +151,14 @@ static struct dmi_system_id __initdata i
 			DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
 		},
 	},
+	{
+		.ident = "HP DV9700",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
+		},
+	},
 	{ }
 };
 
@@ -369,6 +377,24 @@ static struct dmi_system_id __initdata i
 	{ }
 };
 
+static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+	{
+		.ident = "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",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "X110"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+		},
+	},
+	{ }
+};
+
 #ifdef CONFIG_PNP
 static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 	{
@@ -378,6 +404,13 @@ static struct dmi_system_id __initdata i
 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
 		},
 	},
+	{
+		.ident = "MSI Wind U-100",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+		},
+	},
 	{ }
 };
 #endif
@@ -690,6 +723,9 @@ static int __init i8042_platform_init(vo
 #endif
 
 #ifdef CONFIG_X86
+	if (dmi_check_system(i8042_dmi_reset_table))
+		i8042_reset = 1;
+
 	if (dmi_check_system(i8042_dmi_noloop_table))
 		i8042_noloop = 1;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/libps2.c linux-libre-2.6.30-gnu1/drivers/input/serio/libps2.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/libps2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/libps2.c	2009-06-09 23:05:27.000000000 -0400
@@ -210,7 +210,7 @@ int ps2_command(struct ps2dev *ps2dev, u
 	timeout = wait_event_timeout(ps2dev->wait,
 				     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
 
-	if (ps2dev->cmdcnt && timeout > 0) {
+	if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
 
 		timeout = ps2_adjust_timeout(ps2dev, command, timeout);
 		wait_event_timeout(ps2dev->wait,
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/rpckbd.c linux-libre-2.6.30-gnu1/drivers/input/serio/rpckbd.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/rpckbd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/rpckbd.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,10 +33,10 @@
 #include <linux/serio.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/hardware/iomd.h>
 #include <asm/system.h>
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/sa1111ps2.c linux-libre-2.6.30-gnu1/drivers/input/serio/sa1111ps2.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/sa1111ps2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/sa1111ps2.c	2009-06-09 23:05:27.000000000 -0400
@@ -77,7 +77,7 @@ static irqreturn_t ps2_txint(int irq, vo
 	spin_lock(&ps2if->lock);
 	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
 	if (ps2if->head == ps2if->tail) {
-		disable_irq(irq);
+		disable_irq_nosync(irq);
 		/* done */
 	} else if (status & PS2STAT_TXE) {
 		sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA);
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/serio/serio_raw.c linux-libre-2.6.30-gnu1/drivers/input/serio/serio_raw.c
--- linux-libre-2.6.29-gnu1/drivers/input/serio/serio_raw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/serio/serio_raw.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,10 +58,8 @@ static unsigned int serio_raw_no;
 static int serio_raw_fasync(int fd, struct file *file, int on)
 {
 	struct serio_raw_list *list = file->private_data;
-	int retval;
 
-	retval = fasync_helper(fd, file, on, &list->fasync);
-	return retval < 0 ? retval : 0;
+	return fasync_helper(fd, file, on, &list->fasync);
 }
 
 static struct serio_raw *serio_raw_locate(int minor)
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/tablet/wacom.h linux-libre-2.6.30-gnu1/drivers/input/tablet/wacom.h
--- linux-libre-2.6.29-gnu1/drivers/input/tablet/wacom.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/tablet/wacom.h	2009-06-09 23:05:27.000000000 -0400
@@ -11,7 +11,7 @@
  *  Copyright (c) 2000 Daniel Egger		<egger@suse.de>
  *  Copyright (c) 2001 Frederic Lepied		<flepied@mandrakesoft.com>
  *  Copyright (c) 2004 Panagiotis Issaris	<panagiotis.issaris@mech.kuleuven.ac.be>
- *  Copyright (c) 2002-2008 Ping Cheng		<pingc@wacom.com>
+ *  Copyright (c) 2002-2009 Ping Cheng		<pingc@wacom.com>
  *
  *  ChangeLog:
  *      v0.1 (vp)  - Initial release
@@ -67,6 +67,7 @@
  *      v1.47 (pc) - Added support for Bamboo
  *      v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
  *      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
  */
 
 /*
@@ -87,7 +88,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.49"
+#define DRIVER_VERSION "v1.50"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
 #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
 #define DRIVER_LICENSE "GPL"
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/tablet/wacom_sys.c linux-libre-2.6.30-gnu1/drivers/input/tablet/wacom_sys.c
--- linux-libre-2.6.29-gnu1/drivers/input/tablet/wacom_sys.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/tablet/wacom_sys.c	2009-06-09 23:05:27.000000000 -0400
@@ -289,6 +289,7 @@ static int wacom_parse_hid(struct usb_in
 			5000); /* 5 secs */
 	} while (result < 0 && limit++ < 5);
 
+	/* No need to parse the Descriptor. It isn't an error though */
 	if (result < 0)
 		goto out;
 
@@ -368,9 +369,8 @@ static int wacom_parse_hid(struct usb_in
 		}
 	}
 
-	result = 0;
-
  out:
+	result = 0;
 	kfree(report);
 	return result;
 }
@@ -425,6 +425,15 @@ 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)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ad7877.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ad7877.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ad7877.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ad7877.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:	AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver
+ * Based on:	ads7846.c
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *	Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *	Copyright (C) 2002 MontaVista Software
+ *	Copyright (C) 2004 Texas Instruments
+ *	Copyright (C) 2005 Dirk Behme
+ */
+
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ad7877.h>
+#include <asm/irq.h>
+
+#define	TS_PEN_UP_TIMEOUT	msecs_to_jiffies(50)
+
+#define MAX_SPI_FREQ_HZ			20000000
+#define	MAX_12BIT			((1<<12)-1)
+
+#define AD7877_REG_ZEROS			0
+#define AD7877_REG_CTRL1			1
+#define AD7877_REG_CTRL2			2
+#define AD7877_REG_ALERT			3
+#define AD7877_REG_AUX1HIGH			4
+#define AD7877_REG_AUX1LOW			5
+#define AD7877_REG_BAT1HIGH			6
+#define AD7877_REG_BAT1LOW			7
+#define AD7877_REG_BAT2HIGH			8
+#define AD7877_REG_BAT2LOW			9
+#define AD7877_REG_TEMP1HIGH			10
+#define AD7877_REG_TEMP1LOW			11
+#define AD7877_REG_SEQ0				12
+#define AD7877_REG_SEQ1				13
+#define AD7877_REG_DAC				14
+#define AD7877_REG_NONE1			15
+#define AD7877_REG_EXTWRITE			15
+#define AD7877_REG_XPLUS			16
+#define AD7877_REG_YPLUS			17
+#define AD7877_REG_Z2				18
+#define AD7877_REG_aux1				19
+#define AD7877_REG_aux2				20
+#define AD7877_REG_aux3				21
+#define AD7877_REG_bat1				22
+#define AD7877_REG_bat2				23
+#define AD7877_REG_temp1			24
+#define AD7877_REG_temp2			25
+#define AD7877_REG_Z1				26
+#define AD7877_REG_GPIOCTRL1			27
+#define AD7877_REG_GPIOCTRL2			28
+#define AD7877_REG_GPIODATA			29
+#define AD7877_REG_NONE2			30
+#define AD7877_REG_NONE3			31
+
+#define AD7877_SEQ_YPLUS_BIT			(1<<11)
+#define AD7877_SEQ_XPLUS_BIT			(1<<10)
+#define AD7877_SEQ_Z2_BIT			(1<<9)
+#define AD7877_SEQ_AUX1_BIT			(1<<8)
+#define AD7877_SEQ_AUX2_BIT			(1<<7)
+#define AD7877_SEQ_AUX3_BIT			(1<<6)
+#define AD7877_SEQ_BAT1_BIT			(1<<5)
+#define AD7877_SEQ_BAT2_BIT			(1<<4)
+#define AD7877_SEQ_TEMP1_BIT			(1<<3)
+#define AD7877_SEQ_TEMP2_BIT			(1<<2)
+#define AD7877_SEQ_Z1_BIT			(1<<1)
+
+enum {
+	AD7877_SEQ_YPOS  = 0,
+	AD7877_SEQ_XPOS  = 1,
+	AD7877_SEQ_Z2    = 2,
+	AD7877_SEQ_AUX1  = 3,
+	AD7877_SEQ_AUX2  = 4,
+	AD7877_SEQ_AUX3  = 5,
+	AD7877_SEQ_BAT1  = 6,
+	AD7877_SEQ_BAT2  = 7,
+	AD7877_SEQ_TEMP1 = 8,
+	AD7877_SEQ_TEMP2 = 9,
+	AD7877_SEQ_Z1    = 10,
+	AD7877_NR_SENSE  = 11,
+};
+
+/* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */
+#define AD7877_DAC_CONF			0x1
+
+/* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */
+#define AD7877_EXTW_GPIO_3_CONF		0x1C4
+#define AD7877_EXTW_GPIO_DATA		0x200
+
+/* Control REG 2 */
+#define AD7877_TMR(x)			((x & 0x3) << 0)
+#define AD7877_REF(x)			((x & 0x1) << 2)
+#define AD7877_POL(x)			((x & 0x1) << 3)
+#define AD7877_FCD(x)			((x & 0x3) << 4)
+#define AD7877_PM(x)			((x & 0x3) << 6)
+#define AD7877_ACQ(x)			((x & 0x3) << 8)
+#define AD7877_AVG(x)			((x & 0x3) << 10)
+
+/* Control REG 1 */
+#define	AD7877_SER			(1 << 11)	/* non-differential */
+#define	AD7877_DFR			(0 << 11)	/* differential */
+
+#define AD7877_MODE_NOC  (0)	/* Do not convert */
+#define AD7877_MODE_SCC  (1)	/* Single channel conversion */
+#define AD7877_MODE_SEQ0 (2)	/* Sequence 0 in Slave Mode */
+#define AD7877_MODE_SEQ1 (3)	/* Sequence 1 in Master Mode */
+
+#define AD7877_CHANADD(x)		((x&0xF)<<7)
+#define AD7877_READADD(x)		((x)<<2)
+#define AD7877_WRITEADD(x)		((x)<<12)
+
+#define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \
+		AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \
+		AD7877_READADD(AD7877_REG_ ## x))
+
+#define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \
+		AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT)
+
+/*
+ * Non-touchscreen sensors only use single-ended conversions.
+ */
+
+struct ser_req {
+	u16			reset;
+	u16			ref_on;
+	u16			command;
+	u16			sample;
+	struct spi_message	msg;
+	struct spi_transfer	xfer[6];
+};
+
+struct ad7877 {
+	struct input_dev	*input;
+	char			phys[32];
+
+	struct spi_device	*spi;
+	u16			model;
+	u16			vref_delay_usecs;
+	u16			x_plate_ohms;
+	u16			pressure_max;
+
+	u16			cmd_crtl1;
+	u16			cmd_crtl2;
+	u16			cmd_dummy;
+	u16			dac;
+
+	u8			stopacq_polarity;
+	u8			first_conversion_delay;
+	u8			acquisition_time;
+	u8			averaging;
+	u8			pen_down_acc_interval;
+
+	u16			conversion_data[AD7877_NR_SENSE];
+
+	struct spi_transfer	xfer[AD7877_NR_SENSE + 2];
+	struct spi_message	msg;
+
+	struct mutex		mutex;
+	unsigned		disabled:1;	/* P: mutex */
+	unsigned		gpio3:1;	/* P: mutex */
+	unsigned		gpio4:1;	/* P: mutex */
+
+	spinlock_t		lock;
+	struct timer_list	timer;		/* P: lock */
+	unsigned		pending:1;	/* P: lock */
+};
+
+static int gpio3;
+module_param(gpio3, int, 0);
+MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3");
+
+/*
+ * ad7877_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done using spi_async() in the interrupt handler.
+ */
+
+static int ad7877_read(struct spi_device *spi, u16 reg)
+{
+	struct ser_req *req;
+	int status, ret;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) |
+			AD7877_READADD(reg));
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].rx_buf = &req->sample;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	ret = status ? : req->sample;
+
+	kfree(req);
+
+	return ret;
+}
+
+static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
+{
+	struct ser_req *req;
+	int status;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) (AD7877_WRITEADD(reg) | (val & MAX_12BIT));
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+
+	kfree(req);
+
+	return status;
+}
+
+static int ad7877_read_adc(struct spi_device *spi, unsigned command)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+	struct ser_req *req;
+	int status;
+	int sample;
+	int i;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	/* activate reference, so it has time to settle; */
+	req->ref_on = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+			 AD7877_POL(ts->stopacq_polarity) |
+			 AD7877_AVG(0) | AD7877_PM(2) | AD7877_TMR(0) |
+			 AD7877_ACQ(ts->acquisition_time) | AD7877_FCD(0);
+
+	req->reset = AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_MODE_NOC;
+
+	req->command = (u16) command;
+
+	req->xfer[0].tx_buf = &req->reset;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].tx_buf = &req->ref_on;
+	req->xfer[1].len = 2;
+	req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+
+	req->xfer[2].tx_buf = &req->command;
+	req->xfer[2].len = 2;
+	req->xfer[2].delay_usecs = ts->vref_delay_usecs;
+
+	req->xfer[3].rx_buf = &req->sample;
+	req->xfer[3].len = 2;
+
+	req->xfer[4].tx_buf = &ts->cmd_crtl2;	/*REF OFF*/
+	req->xfer[4].len = 2;
+
+	req->xfer[5].tx_buf = &ts->cmd_crtl1;	/*DEFAULT*/
+	req->xfer[5].len = 2;
+
+	/* group all the transfers together, so we can't interfere with
+	 * reading touchscreen state; disable penirq while sampling
+	 */
+	for (i = 0; i < 6; i++)
+		spi_message_add_tail(&req->xfer[i], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	sample = req->sample;
+
+	kfree(req);
+
+	return status ? : sample;
+}
+
+static void ad7877_rx(struct ad7877 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+	unsigned Rt;
+	u16 x, y, z1, z2;
+
+	x = ts->conversion_data[AD7877_SEQ_XPOS] & MAX_12BIT;
+	y = ts->conversion_data[AD7877_SEQ_YPOS] & MAX_12BIT;
+	z1 = ts->conversion_data[AD7877_SEQ_Z1] & MAX_12BIT;
+	z2 = ts->conversion_data[AD7877_SEQ_Z2] & MAX_12BIT;
+
+	/*
+	 * The samples processed here are already preprocessed by the AD7877.
+	 * The preprocessing function consists of an averaging filter.
+	 * The combination of 'first conversion delay' and averaging provides a robust solution,
+	 * discarding the spurious noise in the signal and keeping only the data of interest.
+	 * The size of the averaging filter is programmable. (dev.platform_data, see linux/spi/ad7877.h)
+	 * Other user-programmable conversion controls include variable acquisition time,
+	 * and first conversion delay. Up to 16 averages can be taken per conversion.
+	 */
+
+	if (likely(x && z1)) {
+		/* compute touch pressure resistance using equation #1 */
+		Rt = (z2 - z1) * x * ts->x_plate_ohms;
+		Rt /= z1;
+		Rt = (Rt + 2047) >> 12;
+
+		input_report_abs(input_dev, ABS_X, x);
+		input_report_abs(input_dev, ABS_Y, y);
+		input_report_abs(input_dev, ABS_PRESSURE, Rt);
+		input_sync(input_dev);
+	}
+}
+
+static inline void ad7877_ts_event_release(struct ad7877 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+
+	input_report_abs(input_dev, ABS_PRESSURE, 0);
+	input_sync(input_dev);
+}
+
+static void ad7877_timer(unsigned long handle)
+{
+	struct ad7877 *ts = (void *)handle;
+
+	ad7877_ts_event_release(ts);
+}
+
+static irqreturn_t ad7877_irq(int irq, void *handle)
+{
+	struct ad7877 *ts = handle;
+	unsigned long flags;
+	int status;
+
+	/*
+	 * The repeated conversion sequencer controlled by TMR kicked off
+	 * too fast. We ignore the last and process the sample sequence
+	 * currently in the queue. It can't be older than 9.4ms, and we
+	 * need to avoid that ts->msg doesn't get issued twice while in work.
+	 */
+
+	spin_lock_irqsave(&ts->lock, flags);
+	if (!ts->pending) {
+		ts->pending = 1;
+
+		status = spi_async(ts->spi, &ts->msg);
+		if (status)
+			dev_err(&ts->spi->dev, "spi_sync --> %d\n", status);
+	}
+	spin_unlock_irqrestore(&ts->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void ad7877_callback(void *_ts)
+{
+	struct ad7877 *ts = _ts;
+
+	spin_lock_irq(&ts->lock);
+
+	ad7877_rx(ts);
+	ts->pending = 0;
+	mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+
+	spin_unlock_irq(&ts->lock);
+}
+
+static void ad7877_disable(struct ad7877 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (!ts->disabled) {
+		ts->disabled = 1;
+		disable_irq(ts->spi->irq);
+
+		/* Wait for spi_async callback */
+		while (ts->pending)
+			msleep(1);
+
+		if (del_timer_sync(&ts->timer))
+			ad7877_ts_event_release(ts);
+	}
+
+	/* we know the chip's in lowpower mode since we always
+	 * leave it that way after every request
+	 */
+
+	mutex_unlock(&ts->mutex);
+}
+
+static void ad7877_enable(struct ad7877 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (ts->disabled) {
+		ts->disabled = 0;
+		enable_irq(ts->spi->irq);
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+#define SHOW(name) static ssize_t \
+name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct ad7877	*ts = dev_get_drvdata(dev); \
+	ssize_t v = ad7877_read_adc(ts->spi, \
+			AD7877_READ_CHAN(name)); \
+	if (v < 0) \
+		return v; \
+	return sprintf(buf, "%u\n", (unsigned) v); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
+
+SHOW(aux1)
+SHOW(aux2)
+SHOW(aux3)
+SHOW(bat1)
+SHOW(bat2)
+SHOW(temp1)
+SHOW(temp2)
+
+static ssize_t ad7877_disable_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7877_disable_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val)
+		ad7877_disable(ts);
+	else
+		ad7877_enable(ts);
+
+	return count;
+}
+
+static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store);
+
+static ssize_t ad7877_dac_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->dac);
+}
+
+static ssize_t ad7877_dac_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->dac = val & 0xFF;
+	ad7877_write(ts->spi, AD7877_REG_DAC, (ts->dac << 4) | AD7877_DAC_CONF);
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store);
+
+static ssize_t ad7877_gpio3_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio3);
+}
+
+static ssize_t ad7877_gpio3_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->gpio3 = !!val;
+	ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+		 (ts->gpio4 << 4) | (ts->gpio3 << 5));
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store);
+
+static ssize_t ad7877_gpio4_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7877	*ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio4);
+}
+
+static ssize_t ad7877_gpio4_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7877 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&ts->mutex);
+	ts->gpio4 = !!val;
+	ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
+		     (ts->gpio4 << 4) | (ts->gpio3 << 5));
+	mutex_unlock(&ts->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpio4, 0664, ad7877_gpio4_show, ad7877_gpio4_store);
+
+static struct attribute *ad7877_attributes[] = {
+	&dev_attr_temp1.attr,
+	&dev_attr_temp2.attr,
+	&dev_attr_aux1.attr,
+	&dev_attr_aux2.attr,
+	&dev_attr_bat1.attr,
+	&dev_attr_bat2.attr,
+	&dev_attr_disable.attr,
+	&dev_attr_dac.attr,
+	&dev_attr_gpio4.attr,
+	NULL
+};
+
+static const struct attribute_group ad7877_attr_group = {
+	.attrs = ad7877_attributes,
+};
+
+static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts)
+{
+	struct spi_message *m;
+	int i;
+
+	ts->cmd_crtl2 = AD7877_WRITEADD(AD7877_REG_CTRL2) |
+			AD7877_POL(ts->stopacq_polarity) |
+			AD7877_AVG(ts->averaging) | AD7877_PM(1) |
+			AD7877_TMR(ts->pen_down_acc_interval) |
+			AD7877_ACQ(ts->acquisition_time) |
+			AD7877_FCD(ts->first_conversion_delay);
+
+	ad7877_write(spi, AD7877_REG_CTRL2, ts->cmd_crtl2);
+
+	ts->cmd_crtl1 = AD7877_WRITEADD(AD7877_REG_CTRL1) |
+			AD7877_READADD(AD7877_REG_XPLUS-1) |
+			AD7877_MODE_SEQ1 | AD7877_DFR;
+
+	ad7877_write(spi, AD7877_REG_CTRL1, ts->cmd_crtl1);
+
+	ts->cmd_dummy = 0;
+
+	m = &ts->msg;
+
+	spi_message_init(m);
+
+	m->complete = ad7877_callback;
+	m->context = ts;
+
+	ts->xfer[0].tx_buf = &ts->cmd_crtl1;
+	ts->xfer[0].len = 2;
+
+	spi_message_add_tail(&ts->xfer[0], m);
+
+	ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */
+	ts->xfer[1].len = 2;
+
+	spi_message_add_tail(&ts->xfer[1], m);
+
+	for (i = 0; i < 11; i++) {
+		ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i];
+		ts->xfer[i + 2].len = 2;
+		spi_message_add_tail(&ts->xfer[i + 2], m);
+	}
+}
+
+static int __devinit ad7877_probe(struct spi_device *spi)
+{
+	struct ad7877			*ts;
+	struct input_dev		*input_dev;
+	struct ad7877_platform_data	*pdata = spi->dev.platform_data;
+	int				err;
+	u16				verify;
+
+	if (!spi->irq) {
+		dev_dbg(&spi->dev, "no IRQ?\n");
+		return -ENODEV;
+	}
+
+	if (!pdata) {
+		dev_dbg(&spi->dev, "no platform data?\n");
+		return -ENODEV;
+	}
+
+	/* don't exceed max specified SPI CLK frequency */
+	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+		dev_dbg(&spi->dev, "SPI CLK %d Hz?\n",spi->max_speed_hz);
+		return -EINVAL;
+	}
+
+	ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ts || !input_dev) {
+		err = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	dev_set_drvdata(&spi->dev, ts);
+	ts->spi = spi;
+	ts->input = input_dev;
+
+	setup_timer(&ts->timer, ad7877_timer, (unsigned long) ts);
+	mutex_init(&ts->mutex);
+	spin_lock_init(&ts->lock);
+
+	ts->model = pdata->model ? : 7877;
+	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
+	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+	ts->pressure_max = pdata->pressure_max ? : ~0;
+
+	ts->stopacq_polarity = pdata->stopacq_polarity;
+	ts->first_conversion_delay = pdata->first_conversion_delay;
+	ts->acquisition_time = pdata->acquisition_time;
+	ts->averaging = pdata->averaging;
+	ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
+
+	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
+
+	input_dev->name = "AD7877 Touchscreen";
+	input_dev->phys = ts->phys;
+	input_dev->dev.parent = &spi->dev;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(ABS_X, input_dev->absbit);
+	__set_bit(ABS_Y, input_dev->absbit);
+	__set_bit(ABS_PRESSURE, input_dev->absbit);
+
+	input_set_abs_params(input_dev, ABS_X,
+			pdata->x_min ? : 0,
+			pdata->x_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			pdata->y_min ? : 0,
+			pdata->y_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE,
+			pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+	ad7877_write(spi, AD7877_REG_SEQ1, AD7877_MM_SEQUENCE);
+
+	verify = ad7877_read(spi, AD7877_REG_SEQ1);
+
+	if (verify != AD7877_MM_SEQUENCE){
+		dev_err(&spi->dev, "%s: Failed to probe %s\n",
+			dev_name(&spi->dev), input_dev->name);
+		err = -ENODEV;
+		goto err_free_mem;
+	}
+
+	if (gpio3)
+		ad7877_write(spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_3_CONF);
+
+	ad7877_setup_ts_def_msg(spi, ts);
+
+	/* Request AD7877 /DAV GPIO interrupt */
+
+	err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING,
+			spi->dev.driver->name, ts);
+	if (err) {
+		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
+		goto err_free_mem;
+	}
+
+	err = sysfs_create_group(&spi->dev.kobj, &ad7877_attr_group);
+	if (err)
+		goto err_free_irq;
+
+	err = device_create_file(&spi->dev,
+				 gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+	if (err)
+		goto err_remove_attr_group;
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_remove_attr;
+
+	return 0;
+
+err_remove_attr:
+	device_remove_file(&spi->dev,
+			   gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+err_remove_attr_group:
+	sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+err_free_irq:
+	free_irq(spi->irq, ts);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(ts);
+	dev_set_drvdata(&spi->dev, NULL);
+	return err;
+}
+
+static int __devexit ad7877_remove(struct spi_device *spi)
+{
+	struct ad7877		*ts = dev_get_drvdata(&spi->dev);
+
+	sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group);
+	device_remove_file(&spi->dev,
+			   gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3);
+
+	ad7877_disable(ts);
+	free_irq(ts->spi->irq, ts);
+
+	input_unregister_device(ts->input);
+	kfree(ts);
+
+	dev_dbg(&spi->dev, "unregistered touchscreen\n");
+	dev_set_drvdata(&spi->dev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7877_suspend(struct spi_device *spi, pm_message_t message)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7877_disable(ts);
+
+	return 0;
+}
+
+static int ad7877_resume(struct spi_device *spi)
+{
+	struct ad7877 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7877_enable(ts);
+
+	return 0;
+}
+#else
+#define ad7877_suspend NULL
+#define ad7877_resume  NULL
+#endif
+
+static struct spi_driver ad7877_driver = {
+	.driver = {
+		.name	= "ad7877",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7877_probe,
+	.remove		= __devexit_p(ad7877_remove),
+	.suspend	= ad7877_suspend,
+	.resume		= ad7877_resume,
+};
+
+static int __init ad7877_init(void)
+{
+	return spi_register_driver(&ad7877_driver);
+}
+module_init(ad7877_init);
+
+static void __exit ad7877_exit(void)
+{
+	spi_unregister_driver(&ad7877_driver);
+}
+module_exit(ad7877_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7877 touchscreen Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ad7879.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ad7879.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ad7879.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ad7879.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,781 @@
+/*
+ * Copyright (C) 2008 Michael Hennerich, Analog Devices Inc.
+ *
+ * Description:	AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface)
+ *
+ * Bugs:        Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * History:
+ * Copyright (c) 2005 David Brownell
+ * Copyright (c) 2006 Nokia Corporation
+ * Various changes: Imre Deak <imre.deak@nokia.com>
+ *
+ * Using code from:
+ *  - corgi_ts.c
+ *	Copyright (C) 2004-2005 Richard Purdie
+ *  - omap_ts.[hc], ads7846.h, ts_osk.c
+ *	Copyright (C) 2002 MontaVista Software
+ *	Copyright (C) 2004 Texas Instruments
+ *	Copyright (C) 2005 Dirk Behme
+ *  - ad7877.c
+ *	Copyright (C) 2006-2008 Analog Devices Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+
+#include <linux/spi/ad7879.h>
+
+#define AD7879_REG_ZEROS		0
+#define AD7879_REG_CTRL1		1
+#define AD7879_REG_CTRL2		2
+#define AD7879_REG_CTRL3		3
+#define AD7879_REG_AUX1HIGH		4
+#define AD7879_REG_AUX1LOW		5
+#define AD7879_REG_TEMP1HIGH		6
+#define AD7879_REG_TEMP1LOW		7
+#define AD7879_REG_XPLUS		8
+#define AD7879_REG_YPLUS		9
+#define AD7879_REG_Z1			10
+#define AD7879_REG_Z2			11
+#define AD7879_REG_AUXVBAT		12
+#define AD7879_REG_TEMP			13
+#define AD7879_REG_REVID		14
+
+/* Control REG 1 */
+#define AD7879_TMR(x)			((x & 0xFF) << 0)
+#define AD7879_ACQ(x)			((x & 0x3) << 8)
+#define AD7879_MODE_NOC			(0 << 10)	/* Do not convert */
+#define AD7879_MODE_SCC			(1 << 10)	/* Single channel conversion */
+#define AD7879_MODE_SEQ0		(2 << 10)	/* Sequence 0 in Slave Mode */
+#define AD7879_MODE_SEQ1		(3 << 10)	/* Sequence 1 in Master Mode */
+#define AD7879_MODE_INT			(1 << 15)	/* PENIRQ disabled INT enabled */
+
+/* Control REG 2 */
+#define AD7879_FCD(x)			((x & 0x3) << 0)
+#define AD7879_RESET			(1 << 4)
+#define AD7879_MFS(x)			((x & 0x3) << 5)
+#define AD7879_AVG(x)			((x & 0x3) << 7)
+#define	AD7879_SER			(1 << 9)	/* non-differential */
+#define	AD7879_DFR			(0 << 9)	/* differential */
+#define AD7879_GPIOPOL			(1 << 10)
+#define AD7879_GPIODIR			(1 << 11)
+#define AD7879_GPIO_DATA		(1 << 12)
+#define AD7879_GPIO_EN			(1 << 13)
+#define AD7879_PM(x)			((x & 0x3) << 14)
+#define AD7879_PM_SHUTDOWN		(0)
+#define AD7879_PM_DYN			(1)
+#define AD7879_PM_FULLON		(2)
+
+/* Control REG 3 */
+#define AD7879_TEMPMASK_BIT		(1<<15)
+#define AD7879_AUXVBATMASK_BIT		(1<<14)
+#define AD7879_INTMODE_BIT		(1<<13)
+#define AD7879_GPIOALERTMASK_BIT	(1<<12)
+#define AD7879_AUXLOW_BIT		(1<<11)
+#define AD7879_AUXHIGH_BIT		(1<<10)
+#define AD7879_TEMPLOW_BIT		(1<<9)
+#define AD7879_TEMPHIGH_BIT		(1<<8)
+#define AD7879_YPLUS_BIT		(1<<7)
+#define AD7879_XPLUS_BIT		(1<<6)
+#define AD7879_Z1_BIT			(1<<5)
+#define AD7879_Z2_BIT			(1<<4)
+#define AD7879_AUX_BIT			(1<<3)
+#define AD7879_VBAT_BIT			(1<<2)
+#define AD7879_TEMP_BIT			(1<<1)
+
+enum {
+	AD7879_SEQ_XPOS  = 0,
+	AD7879_SEQ_YPOS  = 1,
+	AD7879_SEQ_Z1    = 2,
+	AD7879_SEQ_Z2    = 3,
+	AD7879_NR_SENSE  = 4,
+};
+
+#define	MAX_12BIT			((1<<12)-1)
+#define	TS_PEN_UP_TIMEOUT		msecs_to_jiffies(50)
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define AD7879_DEVID		0x7A
+typedef struct spi_device	bus_device;
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+#define AD7879_DEVID		0x79
+typedef struct i2c_client	bus_device;
+#endif
+
+struct ad7879 {
+	bus_device		*bus;
+	struct input_dev	*input;
+	struct work_struct	work;
+	struct timer_list	timer;
+
+	struct mutex		mutex;
+	unsigned		disabled:1;	/* P: mutex */
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+	struct spi_message	msg;
+	struct spi_transfer	xfer[AD7879_NR_SENSE + 1];
+	u16			cmd;
+#endif
+	u16			conversion_data[AD7879_NR_SENSE];
+	char			phys[32];
+	u8			first_conversion_delay;
+	u8			acquisition_time;
+	u8			averaging;
+	u8			pen_down_acc_interval;
+	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);
+static int ad7879_write(bus_device *, u8, u16);
+static void ad7879_collect(struct ad7879 *);
+
+static void ad7879_report(struct ad7879 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+	unsigned Rt;
+	u16 x, y, z1, z2;
+
+	x = ts->conversion_data[AD7879_SEQ_XPOS] & MAX_12BIT;
+	y = ts->conversion_data[AD7879_SEQ_YPOS] & MAX_12BIT;
+	z1 = ts->conversion_data[AD7879_SEQ_Z1] & MAX_12BIT;
+	z2 = ts->conversion_data[AD7879_SEQ_Z2] & MAX_12BIT;
+
+	/*
+	 * The samples processed here are already preprocessed by the AD7879.
+	 * The preprocessing function consists of a median and an averaging filter.
+	 * The combination of these two techniques provides a robust solution,
+	 * discarding the spurious noise in the signal and keeping only the data of interest.
+	 * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h)
+	 * Other user-programmable conversion controls include variable acquisition time,
+	 * and first conversion delay. Up to 16 averages can be taken per conversion.
+	 */
+
+	if (likely(x && z1)) {
+		/* compute touch pressure resistance using equation #1 */
+		Rt = (z2 - z1) * x * ts->x_plate_ohms;
+		Rt /= z1;
+		Rt = (Rt + 2047) >> 12;
+
+		input_report_abs(input_dev, ABS_X, x);
+		input_report_abs(input_dev, ABS_Y, y);
+		input_report_abs(input_dev, ABS_PRESSURE, Rt);
+		input_sync(input_dev);
+	}
+}
+
+static void ad7879_work(struct work_struct *work)
+{
+	struct ad7879 *ts = container_of(work, struct ad7879, work);
+
+	/* use keventd context to read the result registers */
+	ad7879_collect(ts);
+	ad7879_report(ts);
+	mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
+}
+
+static void ad7879_ts_event_release(struct ad7879 *ts)
+{
+	struct input_dev *input_dev = ts->input;
+
+	input_report_abs(input_dev, ABS_PRESSURE, 0);
+	input_sync(input_dev);
+}
+
+static void ad7879_timer(unsigned long handle)
+{
+	struct ad7879 *ts = (void *)handle;
+
+	ad7879_ts_event_release(ts);
+}
+
+static irqreturn_t ad7879_irq(int irq, void *handle)
+{
+	struct ad7879 *ts = handle;
+
+	/* The repeated conversion sequencer controlled by TMR kicked off too fast.
+	 * We ignore the last and process the sample sequence currently in the queue.
+	 * It can't be older than 9.4ms
+	 */
+
+	if (!work_pending(&ts->work))
+		schedule_work(&ts->work);
+
+	return IRQ_HANDLED;
+}
+
+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);
+}
+
+static void ad7879_disable(struct ad7879 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (!ts->disabled) {
+
+		ts->disabled = 1;
+		disable_irq(ts->bus->irq);
+
+		cancel_work_sync(&ts->work);
+
+		if (del_timer_sync(&ts->timer))
+			ad7879_ts_event_release(ts);
+
+		ad7879_write(ts->bus, AD7879_REG_CTRL2,
+			     AD7879_PM(AD7879_PM_SHUTDOWN));
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+static void ad7879_enable(struct ad7879 *ts)
+{
+	mutex_lock(&ts->mutex);
+
+	if (ts->disabled) {
+		ad7879_setup(ts);
+		ts->disabled = 0;
+		enable_irq(ts->bus->irq);
+	}
+
+	mutex_unlock(&ts->mutex);
+}
+
+static ssize_t ad7879_disable_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->disabled);
+}
+
+static ssize_t ad7879_disable_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val)
+		ad7879_disable(ts);
+	else
+		ad7879_enable(ts);
+
+	return count;
+}
+
+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)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ts->gpio);
+}
+
+static ssize_t ad7879_gpio_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct ad7879 *ts = dev_get_drvdata(dev);
+	unsigned long val;
+	int error;
+
+	error = strict_strtoul(buf, 10, &val);
+	if (error)
+		return error;
+
+	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);
+	mutex_unlock(&ts->mutex);
+
+	return error ? : count;
+}
+
+static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store);
+
+static struct attribute *ad7879_attributes[] = {
+	&dev_attr_disable.attr,
+	&dev_attr_gpio.attr,
+	NULL
+};
+
+static const struct attribute_group ad7879_attr_group = {
+	.attrs = ad7879_attributes,
+};
+
+static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
+{
+	struct input_dev *input_dev;
+	struct ad7879_platform_data *pdata = bus->dev.platform_data;
+	int err;
+	u16 revid;
+
+	if (!bus->irq) {
+		dev_err(&bus->dev, "no IRQ?\n");
+		return -ENODEV;
+	}
+
+	if (!pdata) {
+		dev_err(&bus->dev, "no platform data?\n");
+		return -ENODEV;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	ts->input = input_dev;
+
+	setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts);
+	INIT_WORK(&ts->work, ad7879_work);
+	mutex_init(&ts->mutex);
+
+	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
+	ts->pressure_max = pdata->pressure_max ? : ~0;
+
+	ts->first_conversion_delay = pdata->first_conversion_delay;
+	ts->acquisition_time = pdata->acquisition_time;
+	ts->averaging = pdata->averaging;
+	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";
+	input_dev->phys = ts->phys;
+	input_dev->dev.parent = &bus->dev;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(ABS_X, input_dev->absbit);
+	__set_bit(ABS_Y, input_dev->absbit);
+	__set_bit(ABS_PRESSURE, input_dev->absbit);
+
+	input_set_abs_params(input_dev, ABS_X,
+			pdata->x_min ? : 0,
+			pdata->x_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			pdata->y_min ? : 0,
+			pdata->y_max ? : MAX_12BIT,
+			0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE,
+			pdata->pressure_min, pdata->pressure_max, 0, 0);
+
+	err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET);
+
+	if (err < 0) {
+		dev_err(&bus->dev, "Failed to write %s\n", input_dev->name);
+		goto err_free_mem;
+	}
+
+	revid = ad7879_read(bus, AD7879_REG_REVID);
+
+	if ((revid & 0xFF) != AD7879_DEVID) {
+		dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name);
+		err = -ENODEV;
+		goto err_free_mem;
+	}
+
+	ad7879_setup(ts);
+
+	err = request_irq(bus->irq, ad7879_irq,
+			  IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts);
+
+	if (err) {
+		dev_err(&bus->dev, "irq %d busy?\n", bus->irq);
+		goto err_free_mem;
+	}
+
+	err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group);
+	if (err)
+		goto err_free_irq;
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto err_remove_attr;
+
+	dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n",
+		 revid >> 8, bus->irq);
+
+	return 0;
+
+err_remove_attr:
+	sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group);
+err_free_irq:
+	free_irq(bus->irq, ts);
+err_free_mem:
+	input_free_device(input_dev);
+
+	return err;
+}
+
+static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
+{
+	ad7879_disable(ts);
+	sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
+	free_irq(ts->bus->irq, ts);
+	input_unregister_device(ts->input);
+	dev_dbg(&bus->dev, "unregistered touchscreen\n");
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ad7879_suspend(bus_device *bus, pm_message_t message)
+{
+	struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+	ad7879_disable(ts);
+
+	return 0;
+}
+
+static int ad7879_resume(bus_device *bus)
+{
+	struct ad7879 *ts = dev_get_drvdata(&bus->dev);
+
+	ad7879_enable(ts);
+
+	return 0;
+}
+#else
+#define ad7879_suspend NULL
+#define ad7879_resume  NULL
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+#define MAX_SPI_FREQ_HZ		5000000
+#define AD7879_CMD_MAGIC	0xE000
+#define AD7879_CMD_READ		(1 << 10)
+#define AD7879_WRITECMD(reg)	(AD7879_CMD_MAGIC | (reg & 0xF))
+#define AD7879_READCMD(reg)	(AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF))
+
+struct ser_req {
+	u16			command;
+	u16			data;
+	struct spi_message	msg;
+	struct spi_transfer	xfer[2];
+};
+
+/*
+ * ad7879_read/write are only used for initial setup and for sysfs controls.
+ * The main traffic is done in ad7879_collect().
+ */
+
+static int ad7879_read(struct spi_device *spi, u8 reg)
+{
+	struct ser_req *req;
+	int status, ret;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) AD7879_READCMD(reg);
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->xfer[1].rx_buf = &req->data;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+	ret = status ? : req->data;
+
+	kfree(req);
+
+	return ret;
+}
+
+static int ad7879_write(struct spi_device *spi, u8 reg, u16 val)
+{
+	struct ser_req *req;
+	int status;
+
+	req = kzalloc(sizeof *req, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+
+	spi_message_init(&req->msg);
+
+	req->command = (u16) AD7879_WRITECMD(reg);
+	req->xfer[0].tx_buf = &req->command;
+	req->xfer[0].len = 2;
+
+	req->data = val;
+	req->xfer[1].tx_buf = &req->data;
+	req->xfer[1].len = 2;
+
+	spi_message_add_tail(&req->xfer[0], &req->msg);
+	spi_message_add_tail(&req->xfer[1], &req->msg);
+
+	status = spi_sync(spi, &req->msg);
+
+	kfree(req);
+
+	return status;
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+	int status = spi_sync(ts->bus, &ts->msg);
+
+	if (status)
+		dev_err(&ts->bus->dev, "spi_sync --> %d\n", status);
+}
+
+static void ad7879_setup_ts_def_msg(struct ad7879 *ts)
+{
+	struct spi_message *m;
+	int i;
+
+	ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS);
+
+	m = &ts->msg;
+	spi_message_init(m);
+	ts->xfer[0].tx_buf = &ts->cmd;
+	ts->xfer[0].len = 2;
+
+	spi_message_add_tail(&ts->xfer[0], m);
+
+	for (i = 0; i < AD7879_NR_SENSE; i++) {
+		ts->xfer[i + 1].rx_buf = &ts->conversion_data[i];
+		ts->xfer[i + 1].len = 2;
+		spi_message_add_tail(&ts->xfer[i + 1], m);
+	}
+}
+
+static int __devinit ad7879_probe(struct spi_device *spi)
+{
+	struct ad7879 *ts;
+	int error;
+
+	/* don't exceed max specified SPI CLK frequency */
+	if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
+		dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
+		return -EINVAL;
+	}
+
+	ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	dev_set_drvdata(&spi->dev, ts);
+	ts->bus = spi;
+
+	ad7879_setup_ts_def_msg(ts);
+
+	error = ad7879_construct(spi, ts);
+	if (error) {
+		dev_set_drvdata(&spi->dev, NULL);
+		kfree(ts);
+	}
+
+	return 0;
+}
+
+static int __devexit ad7879_remove(struct spi_device *spi)
+{
+	struct ad7879 *ts = dev_get_drvdata(&spi->dev);
+
+	ad7879_destroy(spi, ts);
+	dev_set_drvdata(&spi->dev, NULL);
+	kfree(ts);
+
+	return 0;
+}
+
+static struct spi_driver ad7879_driver = {
+	.driver = {
+		.name	= "ad7879",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7879_probe,
+	.remove		= __devexit_p(ad7879_remove),
+	.suspend	= ad7879_suspend,
+	.resume		= ad7879_resume,
+};
+
+static int __init ad7879_init(void)
+{
+	return spi_register_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+	spi_unregister_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+
+#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+
+/* All registers are word-sized.
+ * AD7879 uses a high-byte first convention.
+ */
+static int ad7879_read(struct i2c_client *client, u8 reg)
+{
+	return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static int ad7879_write(struct i2c_client *client, u8 reg, u16 val)
+{
+	return i2c_smbus_write_word_data(client, reg, swab16(val));
+}
+
+static void ad7879_collect(struct ad7879 *ts)
+{
+	int i;
+
+	for (i = 0; i < AD7879_NR_SENSE; i++)
+		ts->conversion_data[i] = ad7879_read(ts->bus,
+						     AD7879_REG_XPLUS + i);
+}
+
+static int __devinit ad7879_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct ad7879 *ts;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_WORD_DATA)) {
+		dev_err(&client->dev, "SMBUS Word Data not Supported\n");
+		return -EIO;
+	}
+
+	ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, ts);
+	ts->bus = client;
+
+	error = ad7879_construct(client, ts);
+	if (error) {
+		i2c_set_clientdata(client, NULL);
+		kfree(ts);
+	}
+
+	return 0;
+}
+
+static int __devexit ad7879_remove(struct i2c_client *client)
+{
+	struct ad7879 *ts = dev_get_drvdata(&client->dev);
+
+	ad7879_destroy(client, ts);
+	i2c_set_clientdata(client, NULL);
+	kfree(ts);
+
+	return 0;
+}
+
+static const struct i2c_device_id ad7879_id[] = {
+	{ "ad7879", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ad7879_id);
+
+static struct i2c_driver ad7879_driver = {
+	.driver = {
+		.name	= "ad7879",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7879_probe,
+	.remove		= __devexit_p(ad7879_remove),
+	.suspend	= ad7879_suspend,
+	.resume		= ad7879_resume,
+	.id_table	= ad7879_id,
+};
+
+static int __init ad7879_init(void)
+{
+	return i2c_add_driver(&ad7879_driver);
+}
+module_init(ad7879_init);
+
+static void __exit ad7879_exit(void)
+{
+	i2c_del_driver(&ad7879_driver);
+}
+module_exit(ad7879_exit);
+#endif
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ads7846.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ads7846.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ads7846.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ads7846.c	2009-06-09 23:05:27.000000000 -0400
@@ -127,6 +127,8 @@ struct ads7846 {
 	void			(*filter_cleanup)(void *data);
 	int			(*get_pendown_state)(void);
 	int			gpio_pendown;
+
+	void			(*wait_for_sync)(void);
 };
 
 /* leave chip selected when we're done, for quicker re-select? */
@@ -295,7 +297,7 @@ name ## _show(struct device *dev, struct
 static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
 
 
-/* Sysfs conventions report temperatures in millidegrees Celcius.
+/* Sysfs conventions report temperatures in millidegrees Celsius.
  * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
  * accuracy scheme without calibration data.  For now we won't try either;
  * userspace sees raw sensor values, and must scale/calibrate appropriately.
@@ -511,6 +513,10 @@ static int get_pendown_state(struct ads7
 	return !gpio_get_value(ts->gpio_pendown);
 }
 
+static void null_wait_for_sync(void)
+{
+}
+
 /*
  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
  * to retrieve touchscreen status.
@@ -686,6 +692,7 @@ static void ads7846_rx_val(void *ads)
 	default:
 		BUG();
 	}
+	ts->wait_for_sync();
 	status = spi_async(ts->spi, m);
 	if (status)
 		dev_err(&ts->spi->dev, "spi_async --> %d\n",
@@ -723,6 +730,7 @@ static enum hrtimer_restart ads7846_time
 	} else {
 		/* pen is still down, continue with the measurement */
 		ts->msg_idx = 0;
+		ts->wait_for_sync();
 		status = spi_async(ts->spi, &ts->msg[0]);
 		if (status)
 			dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
@@ -746,7 +754,7 @@ static irqreturn_t ads7846_irq(int irq,
 			 * that here.  (The "generic irq" framework may help...)
 			 */
 			ts->irq_disabled = 1;
-			disable_irq(ts->spi->irq);
+			disable_irq_nosync(ts->spi->irq);
 			ts->pending = 1;
 			hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
 					HRTIMER_MODE_REL);
@@ -947,6 +955,8 @@ static int __devinit ads7846_probe(struc
 		ts->penirq_recheck_delay_usecs =
 				pdata->penirq_recheck_delay_usecs;
 
+	ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
+
 	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
 
 	input_dev->name = "ADS784x Touchscreen";
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/corgi_ts.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/corgi_ts.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/corgi_ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/corgi_ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,7 +21,6 @@
 
 #include <mach/sharpsl.h>
 #include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-gpio.h>
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/da9034-ts.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/da9034-ts.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/da9034-ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/da9034-ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2006-2008 Marvell International Ltd.
  *	Fengwei Yin <fengwei.yin@marvell.com>
+ *	Bin Yang  <bin.yang@marvell.com>
  *	Eric Miao <eric.miao@marvell.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -175,6 +176,16 @@ static void da9034_event_handler(struct
 			goto err_reset;
 
 		touch->state = STATE_STOP;
+
+		/* FIXME: PEN_{UP/DOWN} events are expected to be
+		 * available by stopping TSI, but this is found not
+		 * always true, delay and simulate such an event
+		 * here is more reliable
+		 */
+		mdelay(1);
+		da9034_event_handler(touch,
+				     is_pen_down(touch) ? EVENT_PEN_DOWN :
+							  EVENT_PEN_UP);
 		break;
 
 	case STATE_STOP:
@@ -189,8 +200,6 @@ static void da9034_event_handler(struct
 			report_pen_up(touch);
 			touch->state = STATE_IDLE;
 		}
-
-		input_sync(touch->input_dev);
 		break;
 
 	case STATE_WAIT:
@@ -200,8 +209,10 @@ static void da9034_event_handler(struct
 		if (is_pen_down(touch)) {
 			start_tsi(touch);
 			touch->state = STATE_BUSY;
-		} else
+		} else {
+			report_pen_up(touch);
 			touch->state = STATE_IDLE;
+		}
 		break;
 	}
 	return;
@@ -226,16 +237,12 @@ static int da9034_touch_notifier(struct
 	struct da9034_touch *touch =
 		container_of(nb, struct da9034_touch, notifier);
 
-	if (event & DA9034_EVENT_PEN_DOWN) {
-		if (is_pen_down(touch))
-			da9034_event_handler(touch, EVENT_PEN_DOWN);
-		else
-			da9034_event_handler(touch, EVENT_PEN_UP);
-	}
-
 	if (event & DA9034_EVENT_TSI_READY)
 		da9034_event_handler(touch, EVENT_TSI_READY);
 
+	if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
+		da9034_event_handler(touch, EVENT_PEN_DOWN);
+
 	return 0;
 }
 
@@ -385,6 +392,6 @@ static void __exit da9034_touch_exit(voi
 module_exit(da9034_touch_exit);
 
 MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:da9034-touch");
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/Kconfig linux-libre-2.6.30-gnu1/drivers/input/touchscreen/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,51 @@ config TOUCHSCREEN_ADS7846
 	  To compile this driver as a module, choose M here: the
 	  module will be called ads7846.
 
+config TOUCHSCREEN_AD7877
+	tristate "AD7877 based touchscreens"
+	depends on SPI_MASTER
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7877 controller, and your board-specific initialization
+	  code includes that in its table of SPI devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7877.
+
+config TOUCHSCREEN_AD7879_I2C
+	tristate "AD7879 based touchscreens: AD7879-1 I2C Interface"
+	depends on I2C
+	select TOUCHSCREEN_AD7879
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7879-1 controller, and your board-specific initialization
+	  code includes that in its table of I2C devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879_SPI
+	tristate "AD7879 based touchscreens: AD7879 SPI Interface"
+	depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n
+	select TOUCHSCREEN_AD7879
+	help
+	  Say Y here if you have a touchscreen interface using the
+	  AD7879 controller, and your board-specific initialization
+	  code includes that in its table of SPI devices.
+
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7879.
+
+config TOUCHSCREEN_AD7879
+	tristate
+	default n
+
 config TOUCHSCREEN_BITSY
 	tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
 	depends on SA1100_BITSY
@@ -308,6 +353,19 @@ config TOUCHSCREEN_WM97XX_MAINSTONE
 	  To compile this driver as a module, choose M here: the
 	  module will be called mainstone-wm97xx.
 
+config TOUCHSCREEN_WM97XX_ZYLONITE
+	tristate "Zylonite accelerated touch"
+	depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE
+	select TOUCHSCREEN_WM9713
+	help
+	  Say Y here for support for streaming mode with the touchscreen
+	  on Zylonite systems.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called zylonite-wm97xx.
+
 config TOUCHSCREEN_USB_COMPOSITE
 	tristate "USB Touchscreen Driver"
 	depends on USB_ARCH_HAS_HCD
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/mainstone-wm97xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -111,13 +111,12 @@ static void wm97xx_acc_pen_up(struct wm9
 #else
 static void wm97xx_acc_pen_up(struct wm97xx *wm)
 {
-	int count = 16;
+	unsigned int count;
+
 	schedule_timeout_uninterruptible(1);
 
-	while (count < 16) {
+	for (count = 0; count < 16; count++)
 		MODR;
-		count--;
-	}
 }
 #endif
 
@@ -162,6 +161,7 @@ static int wm97xx_acc_pen_down(struct wm
 		input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
 		input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
 		input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
 		input_sync(wm->input_dev);
 		reads++;
 	} while (reads < cinfo[sp_idx].reads);
@@ -245,7 +245,7 @@ static void wm97xx_irq_enable(struct wm9
 	if (enable)
 		enable_irq(wm->pen_irq);
 	else
-		disable_irq(wm->pen_irq);
+		disable_irq_nosync(wm->pen_irq);
 }
 
 static struct wm97xx_mach_ops mainstone_mach_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/Makefile linux-libre-2.6.30-gnu1/drivers/input/touchscreen/Makefile
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,8 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
+obj-$(CONFIG_TOUCHSCREEN_AD7877)	+= ad7877.o
+obj-$(CONFIG_TOUCHSCREEN_AD7879)	+= ad7879.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)	+= ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
@@ -34,3 +36,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705)	+
 wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712)	+= wm9712.o
 wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713)	+= wm9713.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
+obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/migor_ts.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/migor_ts.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/migor_ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/migor_ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_cli
 		goto err2;
 	}
 
+	device_init_wakeup(&client->dev, 1);
 	return 0;
 
  err2:
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_cl
 	return 0;
 }
 
+static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(priv->irq);
+
+	return 0;
+}
+
+static int migor_ts_resume(struct i2c_client *client)
+{
+	struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(priv->irq);
+
+	return 0;
+}
+
 static const struct i2c_device_id migor_ts_id[] = {
 	{ "migor_ts", 0 },
 	{ }
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver
 	},
 	.probe = migor_ts_probe,
 	.remove = migor_ts_remove,
+	.suspend = migor_ts_suspend,
+	.resume = migor_ts_resume,
 	.id_table = migor_ts_id,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/tsc2007.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/tsc2007.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/tsc2007.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/tsc2007.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,8 +200,9 @@ static int tsc2007_read_values(struct ts
 static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
 {
 	struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
+	unsigned long flags;
 
-	spin_lock_irq(&ts->lock);
+	spin_lock_irqsave(&ts->lock, flags);
 
 	if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
 		struct input_dev *input = ts->input;
@@ -222,7 +223,7 @@ static enum hrtimer_restart tsc2007_time
 		tsc2007_send_event(ts);
 	}
 
-	spin_unlock_irq(&ts->lock);
+	spin_unlock_irqrestore(&ts->lock, flags);
 
 	return HRTIMER_NORESTART;
 }
@@ -235,7 +236,7 @@ static irqreturn_t tsc2007_irq(int irq,
 	spin_lock_irqsave(&ts->lock, flags);
 
 	if (likely(ts->get_pendown_state())) {
-		disable_irq(ts->irq);
+		disable_irq_nosync(ts->irq);
 		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
 					HRTIMER_MODE_REL);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ucb1400_ts.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ucb1400_ts.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/ucb1400_ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -151,12 +151,14 @@ static void ucb1400_ts_evt_add(struct in
 	input_report_abs(idev, ABS_X, x);
 	input_report_abs(idev, ABS_Y, y);
 	input_report_abs(idev, ABS_PRESSURE, pressure);
+	input_report_key(idev, BTN_TOUCH, 1);
 	input_sync(idev);
 }
 
 static void ucb1400_ts_event_release(struct input_dev *idev)
 {
 	input_report_abs(idev, ABS_PRESSURE, 0);
+	input_report_key(idev, BTN_TOUCH, 0);
 	input_sync(idev);
 }
 
@@ -254,7 +256,7 @@ static irqreturn_t ucb1400_hard_irq(int
 	struct ucb1400_ts *ucb = devid;
 
 	if (irqnr == ucb->irq) {
-		disable_irq(ucb->irq);
+		disable_irq_nosync(ucb->irq);
 		ucb->irq_pending = 1;
 		wake_up(&ucb->ts_wait);
 		return IRQ_HANDLED;
@@ -377,7 +379,8 @@ static int ucb1400_ts_probe(struct platf
 	ucb->ts_idev->id.product	= ucb->id;
 	ucb->ts_idev->open		= ucb1400_ts_open;
 	ucb->ts_idev->close		= ucb1400_ts_close;
-	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS);
+	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	ucb1400_adc_enable(ucb->ac97);
 	x_res = ucb1400_ts_read_xres(ucb);
@@ -416,7 +419,7 @@ static int ucb1400_ts_remove(struct plat
 #ifdef CONFIG_PM
 static int ucb1400_ts_resume(struct platform_device *dev)
 {
-	struct ucb1400_ts *ucb = platform_get_drvdata(dev);
+	struct ucb1400_ts *ucb = dev->dev.platform_data;
 
 	if (ucb->ts_task) {
 		/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/wm97xx-core.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/wm97xx-core.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/wm97xx-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/wm97xx-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -370,8 +370,7 @@ static int wm97xx_init_pen_irq(struct wm
 	 * provided. */
 	BUG_ON(!wm->mach_ops->irq_enable);
 
-	if (request_irq(wm->pen_irq, wm97xx_pen_interrupt,
-			IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+	if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED,
 			"wm97xx-pen", wm)) {
 		dev_err(wm->dev,
 			"Failed to register pen down interrupt, polling");
@@ -409,6 +408,7 @@ static int wm97xx_read_samples(struct wm
 			wm->pen_is_down = 0;
 			dev_dbg(wm->dev, "pen up\n");
 			input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
+			input_report_key(wm->input_dev, BTN_TOUCH, 0);
 			input_sync(wm->input_dev);
 		} else if (!(rc & RC_AGAIN)) {
 			/* We need high frequency updates only while
@@ -433,6 +433,7 @@ static int wm97xx_read_samples(struct wm
 		input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
 		input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
 		input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, 1);
 		input_sync(wm->input_dev);
 		wm->pen_is_down = 1;
 		wm->ts_reader_interval = wm->ts_reader_min_interval;
@@ -628,18 +629,21 @@ static int wm97xx_probe(struct device *d
 	wm->input_dev->phys = "wm97xx";
 	wm->input_dev->open = wm97xx_ts_input_open;
 	wm->input_dev->close = wm97xx_ts_input_close;
-	set_bit(EV_ABS, wm->input_dev->evbit);
-	set_bit(ABS_X, wm->input_dev->absbit);
-	set_bit(ABS_Y, wm->input_dev->absbit);
-	set_bit(ABS_PRESSURE, wm->input_dev->absbit);
+
+	__set_bit(EV_ABS, wm->input_dev->evbit);
+	__set_bit(EV_KEY, wm->input_dev->evbit);
+	__set_bit(BTN_TOUCH, wm->input_dev->keybit);
+
 	input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
 			     abs_x[2], 0);
 	input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
 			     abs_y[2], 0);
 	input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
 			     abs_p[2], 0);
+
 	input_set_drvdata(wm->input_dev, wm);
 	wm->input_dev->dev.parent = dev;
+
 	ret = input_register_device(wm->input_dev);
 	if (ret < 0)
 		goto dev_alloc_err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c linux-libre-2.6.30-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c
--- linux-libre-2.6.29-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/input/touchscreen/zylonite-wm97xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,240 @@
+/*
+ * zylonite-wm97xx.c  --  Zylonite Continuous Touch screen driver
+ *
+ * Copyright 2004, 2007, 2008 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ * Parts Copyright : Ian Molton <spyro@f2s.com>
+ *                   Andrew Zabolotny <zap@homelink.ru>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Notes:
+ *     This is a wm97xx extended touch driver supporting interrupt driven
+ *     and continuous operation on Marvell Zylonite development systems
+ *     (which have a WM9713 on board).
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/wm97xx.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/regs-ac97.h>
+
+struct continuous {
+	u16 id;    /* codec id */
+	u8 code;   /* continuous code */
+	u8 reads;  /* number of coord reads per read cycle */
+	u32 speed; /* number of coords per second */
+};
+
+#define WM_READS(sp) ((sp / HZ) + 1)
+
+static const struct continuous cinfo[] = {
+	{ WM9713_ID2, 0, WM_READS(94),  94  },
+	{ WM9713_ID2, 1, WM_READS(120), 120 },
+	{ WM9713_ID2, 2, WM_READS(154), 154 },
+	{ WM9713_ID2, 3, WM_READS(188), 188 },
+};
+
+/* continuous speed index */
+static int sp_idx;
+
+/*
+ * Pen sampling frequency (Hz) in continuous mode.
+ */
+static int cont_rate = 200;
+module_param(cont_rate, int, 0);
+MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
+
+/*
+ * Pressure readback.
+ *
+ * Set to 1 to read back pen down pressure
+ */
+static int pressure;
+module_param(pressure, int, 0);
+MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
+
+/*
+ * AC97 touch data slot.
+ *
+ * Touch screen readback data ac97 slot
+ */
+static int ac97_touch_slot = 5;
+module_param(ac97_touch_slot, int, 0);
+MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
+
+
+/* flush AC97 slot 5 FIFO machines */
+static void wm97xx_acc_pen_up(struct wm97xx *wm)
+{
+	int i;
+
+	msleep(1);
+
+	for (i = 0; i < 16; i++)
+		MODR;
+}
+
+static int wm97xx_acc_pen_down(struct wm97xx *wm)
+{
+	u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
+	int reads = 0;
+	static u16 last, tries;
+
+	/* 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.
+	 */
+	msleep(1);
+
+	if (tries > 5) {
+		tries = 0;
+		return RC_PENUP;
+	}
+
+	x = MODR;
+	if (x == last) {
+		tries++;
+		return RC_AGAIN;
+	}
+	last = x;
+	do {
+		if (reads)
+			x = MODR;
+		y = MODR;
+		if (pressure)
+			p = MODR;
+
+		/* are samples valid */
+		if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X ||
+		    (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y ||
+		    (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES)
+			goto up;
+
+		/* coordinate is good */
+		tries = 0;
+		input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
+		input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
+		input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
+		input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
+		input_sync(wm->input_dev);
+		reads++;
+	} while (reads < cinfo[sp_idx].reads);
+up:
+	return RC_PENDOWN | RC_AGAIN;
+}
+
+static int wm97xx_acc_startup(struct wm97xx *wm)
+{
+	int idx;
+
+	/* check we have a codec */
+	if (wm->ac97 == NULL)
+		return -ENODEV;
+
+	/* Go you big red fire engine */
+	for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
+		if (wm->id != cinfo[idx].id)
+			continue;
+		sp_idx = idx;
+		if (cont_rate <= cinfo[idx].speed)
+			break;
+	}
+	wm->acc_rate = cinfo[sp_idx].code;
+	wm->acc_slot = ac97_touch_slot;
+	dev_info(wm->dev,
+		 "zylonite accelerated touchscreen driver, %d samples/sec\n",
+		 cinfo[sp_idx].speed);
+
+	return 0;
+}
+
+static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
+{
+	if (enable)
+		enable_irq(wm->pen_irq);
+	else
+		disable_irq_nosync(wm->pen_irq);
+}
+
+static struct wm97xx_mach_ops zylonite_mach_ops = {
+	.acc_enabled	= 1,
+	.acc_pen_up	= wm97xx_acc_pen_up,
+	.acc_pen_down	= wm97xx_acc_pen_down,
+	.acc_startup	= wm97xx_acc_startup,
+	.irq_enable	= wm97xx_irq_enable,
+	.irq_gpio	= WM97XX_GPIO_2,
+};
+
+static int zylonite_wm97xx_probe(struct platform_device *pdev)
+{
+	struct wm97xx *wm = platform_get_drvdata(pdev);
+	int gpio_touch_irq;
+
+	if (cpu_is_pxa320())
+		gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO15);
+	else
+		gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+
+	wm->pen_irq = IRQ_GPIO(gpio_touch_irq);
+	set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);
+
+	wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
+			   WM97XX_GPIO_POL_HIGH,
+			   WM97XX_GPIO_STICKY,
+			   WM97XX_GPIO_WAKE);
+	wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
+			   WM97XX_GPIO_POL_HIGH,
+			   WM97XX_GPIO_NOTSTICKY,
+			   WM97XX_GPIO_NOWAKE);
+
+	return wm97xx_register_mach_ops(wm, &zylonite_mach_ops);
+}
+
+static int zylonite_wm97xx_remove(struct platform_device *pdev)
+{
+	struct wm97xx *wm = platform_get_drvdata(pdev);
+
+	wm97xx_unregister_mach_ops(wm);
+
+	return 0;
+}
+
+static struct platform_driver zylonite_wm97xx_driver = {
+	.probe	= zylonite_wm97xx_probe,
+	.remove	= zylonite_wm97xx_remove,
+	.driver	= {
+		.name	= "wm97xx-touch",
+	},
+};
+
+static int __init zylonite_wm97xx_init(void)
+{
+	return platform_driver_register(&zylonite_wm97xx_driver);
+}
+
+static void __exit zylonite_wm97xx_exit(void)
+{
+	platform_driver_unregister(&zylonite_wm97xx_driver);
+}
+
+module_init(zylonite_wm97xx_init);
+module_exit(zylonite_wm97xx_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("wm97xx continuous touch driver for Zylonite");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/act2000/act2000_isa.c linux-libre-2.6.30-gnu1/drivers/isdn/act2000/act2000_isa.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/act2000/act2000_isa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/act2000/act2000_isa.c	2009-06-09 23:05:27.000000000 -0400
@@ -257,9 +257,9 @@ act2000_isa_receive(act2000_card *card)
 					printk(KERN_WARNING
 					       "act2000_isa_receive: Invalid CAPI msg\n");
 					{
-						int i; __u8 *p; __u8 *c; __u8 tmp[30];
-						for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, c = tmp; i < 8; i++)
-							c += sprintf(c, "%02x ", *(p++));
+						int i; __u8 *p; __u8 *t; __u8 tmp[30];
+						for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++)
+							t += sprintf(t, "%02x ", *(p++));
 						printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
 					}
 				}
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/capi/capi.c linux-libre-2.6.30-gnu1/drivers/isdn/capi/capi.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/capi/capi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/capi/capi.c	2009-06-09 23:05:27.000000000 -0400
@@ -277,7 +277,7 @@ static void capiminor_free(struct capimi
 	list_del(&mp->list);
 	write_unlock_irqrestore(&capiminor_list_lock, flags);
 
-	if (mp->ttyskb) kfree_skb(mp->ttyskb);
+	kfree_skb(mp->ttyskb);
 	mp->ttyskb = NULL;
 	skb_queue_purge(&mp->inqueue);
 	skb_queue_purge(&mp->outqueue);
@@ -1331,12 +1331,6 @@ static void capinc_tty_send_xchar(struct
 #endif
 }
 
-static int capinc_tty_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
-{
-	return 0;
-}
-
 static struct tty_driver *capinc_tty_driver;
 
 static const struct tty_operations capinc_ops = {
@@ -1358,7 +1352,6 @@ static const struct tty_operations capin
 	.flush_buffer = capinc_tty_flush_buffer,
 	.set_ldisc = capinc_tty_set_ldisc,
 	.send_xchar = capinc_tty_send_xchar,
-	.read_proc = capinc_tty_read_proc,
 };
 
 static int capinc_tty_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/capi/capifs.c linux-libre-2.6.30-gnu1/drivers/isdn/capi/capifs.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/capi/capifs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/capi/capifs.c	2009-06-09 23:05:27.000000000 -0400
@@ -75,15 +75,17 @@ static int capifs_remount(struct super_b
 		}
 	}
 
-	kfree(s->s_options);
-	s->s_options = new_opt;
+	mutex_lock(&s->s_root->d_inode->i_mutex);
 
+	replace_mount_options(s, new_opt);
 	config.setuid  = setuid;
 	config.setgid  = setgid;
 	config.uid     = uid;
 	config.gid     = gid;
 	config.mode    = mode;
 
+	mutex_unlock(&s->s_root->d_inode->i_mutex);
+
 	return 0;
 }
 
@@ -154,13 +156,16 @@ void capifs_new_ncci(unsigned int number
 	if (!inode)
 		return;
 	inode->i_ino = number+2;
+
+	dentry = get_node(number);
+
+	/* config contents is protected by root's i_mutex */
 	inode->i_uid = config.setuid ? config.uid : current_fsuid();
 	inode->i_gid = config.setgid ? config.gid : current_fsgid();
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	init_special_inode(inode, S_IFCHR|config.mode, device);
 	//inode->i_op = &capifs_file_inode_operations;
 
-	dentry = get_node(number);
 	if (!IS_ERR(dentry) && !dentry->d_inode)
 		d_instantiate(dentry, inode);
 	mutex_unlock(&capifs_root->d_inode->i_mutex);
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/capi/kcapi.c linux-libre-2.6.30-gnu1/drivers/isdn/capi/kcapi.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/capi/kcapi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/capi/kcapi.c	2009-06-09 23:05:27.000000000 -0400
@@ -270,6 +270,15 @@ static void recv_handler(struct work_str
 	mutex_unlock(&ap->recv_mtx);
 }
 
+/**
+ * capi_ctr_handle_message() - handle incoming CAPI message
+ * @card:	controller descriptor structure.
+ * @appl:	application ID.
+ * @skb:	message.
+ *
+ * Called by hardware driver to pass a CAPI message to the application.
+ */
+
 void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb)
 {
 	struct capi20_appl *ap;
@@ -348,6 +357,13 @@ error:
 
 EXPORT_SYMBOL(capi_ctr_handle_message);
 
+/**
+ * capi_ctr_ready() - signal CAPI controller ready
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to signal that the controller is up and running.
+ */
+
 void capi_ctr_ready(struct capi_ctr * card)
 {
 	card->cardstate = CARD_RUNNING;
@@ -360,6 +376,14 @@ void capi_ctr_ready(struct capi_ctr * ca
 
 EXPORT_SYMBOL(capi_ctr_ready);
 
+/**
+ * capi_ctr_reseted() - signal CAPI controller reset
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to signal that the controller is down and
+ * unavailable for use.
+ */
+
 void capi_ctr_reseted(struct capi_ctr * card)
 {
 	u16 appl;
@@ -391,6 +415,13 @@ void capi_ctr_reseted(struct capi_ctr *
 
 EXPORT_SYMBOL(capi_ctr_reseted);
 
+/**
+ * capi_ctr_suspend_output() - suspend controller
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to stop data flow.
+ */
+
 void capi_ctr_suspend_output(struct capi_ctr *card)
 {
 	if (!card->blocked) {
@@ -401,6 +432,13 @@ void capi_ctr_suspend_output(struct capi
 
 EXPORT_SYMBOL(capi_ctr_suspend_output);
 
+/**
+ * capi_ctr_resume_output() - resume controller
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to resume data flow.
+ */
+
 void capi_ctr_resume_output(struct capi_ctr *card)
 {
 	if (card->blocked) {
@@ -413,6 +451,14 @@ EXPORT_SYMBOL(capi_ctr_resume_output);
 
 /* ------------------------------------------------------------- */
 
+/**
+ * attach_capi_ctr() - register CAPI controller
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to register a controller with the CAPI subsystem.
+ * Return value: 0 on success, error code < 0 on error
+ */
+
 int
 attach_capi_ctr(struct capi_ctr *card)
 {
@@ -459,6 +505,15 @@ attach_capi_ctr(struct capi_ctr *card)
 
 EXPORT_SYMBOL(attach_capi_ctr);
 
+/**
+ * detach_capi_ctr() - unregister CAPI controller
+ * @card:	controller descriptor structure.
+ *
+ * Called by hardware driver to remove the registration of a controller
+ * with the CAPI subsystem.
+ * Return value: 0 on success, error code < 0 on error
+ */
+
 int detach_capi_ctr(struct capi_ctr *card)
 {
         if (card->cardstate != CARD_DETECTED)
@@ -479,6 +534,13 @@ int detach_capi_ctr(struct capi_ctr *car
 
 EXPORT_SYMBOL(detach_capi_ctr);
 
+/**
+ * register_capi_driver() - register CAPI driver
+ * @driver:	driver descriptor structure.
+ *
+ * Called by hardware driver to register itself with the CAPI subsystem.
+ */
+
 void register_capi_driver(struct capi_driver *driver)
 {
 	unsigned long flags;
@@ -490,6 +552,13 @@ void register_capi_driver(struct capi_dr
 
 EXPORT_SYMBOL(register_capi_driver);
 
+/**
+ * unregister_capi_driver() - unregister CAPI driver
+ * @driver:	driver descriptor structure.
+ *
+ * Called by hardware driver to unregister itself from the CAPI subsystem.
+ */
+
 void unregister_capi_driver(struct capi_driver *driver)
 {
 	unsigned long flags;
@@ -505,6 +574,13 @@ EXPORT_SYMBOL(unregister_capi_driver);
 /* -------- CAPI2.0 Interface ---------------------------------- */
 /* ------------------------------------------------------------- */
 
+/**
+ * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
+ *
+ * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
+ *	is ready for use, CAPI_REGNOTINSTALLED otherwise)
+ */
+
 u16 capi20_isinstalled(void)
 {
 	int i;
@@ -517,6 +593,18 @@ u16 capi20_isinstalled(void)
 
 EXPORT_SYMBOL(capi20_isinstalled);
 
+/**
+ * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
+ * @ap:		CAPI application descriptor structure.
+ *
+ * Register an application's presence with CAPI.
+ * A unique application ID is assigned and stored in @ap->applid.
+ * After this function returns successfully, the message receive
+ * callback function @ap->recv_message() may be called at any time
+ * until capi20_release() has been called for the same @ap.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_register(struct capi20_appl *ap)
 {
 	int i;
@@ -571,6 +659,16 @@ u16 capi20_register(struct capi20_appl *
 
 EXPORT_SYMBOL(capi20_register);
 
+/**
+ * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
+ * @ap:		CAPI application descriptor structure.
+ *
+ * Terminate an application's registration with CAPI.
+ * After this function returns successfully, the message receive
+ * callback function @ap->recv_message() will no longer be called.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_release(struct capi20_appl *ap)
 {
 	int i;
@@ -603,6 +701,15 @@ u16 capi20_release(struct capi20_appl *a
 
 EXPORT_SYMBOL(capi20_release);
 
+/**
+ * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
+ * @ap:		CAPI application descriptor structure.
+ * @skb:	CAPI message.
+ *
+ * Transfer a single message to CAPI.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 {
 	struct capi_ctr *card;
@@ -668,6 +775,16 @@ u16 capi20_put_message(struct capi20_app
 
 EXPORT_SYMBOL(capi20_put_message);
 
+/**
+ * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
+ * @contr:	controller number.
+ * @buf:	result buffer (64 bytes).
+ *
+ * Retrieve information about the manufacturer of the specified ISDN controller
+ * or (for @contr == 0) the driver itself.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_get_manufacturer(u32 contr, u8 *buf)
 {
 	struct capi_ctr *card;
@@ -685,6 +802,16 @@ u16 capi20_get_manufacturer(u32 contr, u
 
 EXPORT_SYMBOL(capi20_get_manufacturer);
 
+/**
+ * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
+ * @contr:	controller number.
+ * @verp:	result structure.
+ *
+ * Retrieve version information for the specified ISDN controller
+ * or (for @contr == 0) the driver itself.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_get_version(u32 contr, struct capi_version *verp)
 {
 	struct capi_ctr *card;
@@ -703,6 +830,16 @@ u16 capi20_get_version(u32 contr, struct
 
 EXPORT_SYMBOL(capi20_get_version);
 
+/**
+ * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
+ * @contr:	controller number.
+ * @serial:	result buffer (8 bytes).
+ *
+ * Retrieve the serial number of the specified ISDN controller
+ * or (for @contr == 0) the driver itself.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_get_serial(u32 contr, u8 *serial)
 {
 	struct capi_ctr *card;
@@ -721,6 +858,16 @@ u16 capi20_get_serial(u32 contr, u8 *ser
 
 EXPORT_SYMBOL(capi20_get_serial);
 
+/**
+ * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
+ * @contr:	controller number.
+ * @profp:	result structure.
+ *
+ * Retrieve capability information for the specified ISDN controller
+ * or (for @contr == 0) the number of installed controllers.
+ * Return value: CAPI result code
+ */
+
 u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
 {
 	struct capi_ctr *card;
@@ -903,6 +1050,15 @@ static int old_capi_manufacturer(unsigne
 }
 #endif
 
+/**
+ * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
+ * @cmd:	command.
+ * @data:	parameter.
+ *
+ * Perform manufacturer specific command.
+ * Return value: CAPI result code
+ */
+
 int capi20_manufacturer(unsigned int cmd, void __user *data)
 {
         struct capi_ctr *card;
@@ -981,6 +1137,21 @@ int capi20_manufacturer(unsigned int cmd
 EXPORT_SYMBOL(capi20_manufacturer);
 
 /* temporary hack */
+
+/**
+ * capi20_set_callback() - set CAPI application notification callback function
+ * @ap:		CAPI application descriptor structure.
+ * @callback:	callback function (NULL to remove).
+ *
+ * If not NULL, the callback function will be called to notify the
+ * application of the addition or removal of a controller.
+ * The first argument (cmd) will tell whether the controller was added
+ * (KCI_CONTRUP) or removed (KCI_CONTRDOWN).
+ * The second argument (contr) will be the controller number.
+ * For cmd==KCI_CONTRUP the third argument (data) will be a pointer to the
+ * new controller's capability profile structure.
+ */
+
 void capi20_set_callback(struct capi20_appl *ap,
 			 void (*callback) (unsigned int cmd, __u32 contr, void *data))
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/capi/kcapi_proc.c linux-libre-2.6.30-gnu1/drivers/isdn/capi/kcapi_proc.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/capi/kcapi_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/capi/kcapi_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -239,6 +239,7 @@ static const struct file_operations proc
 // ---------------------------------------------------------------------------
 
 static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
+	__acquires(&capi_drivers_list_lock)
 {
 	read_lock(&capi_drivers_list_lock);
 	return seq_list_start(&capi_drivers, *pos);
@@ -250,6 +251,7 @@ static void *capi_driver_next(struct seq
 }
 
 static void capi_driver_stop(struct seq_file *seq, void *v)
+	__releases(&capi_drivers_list_lock)
 {
 	read_unlock(&capi_drivers_list_lock);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/bas-gigaset.c linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/bas-gigaset.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/bas-gigaset.c	2009-06-09 23:05:27.000000000 -0400
@@ -821,7 +821,7 @@ static void read_iso_callback(struct urb
 		/* pass URB to tasklet */
 		ubc->isoindone = urb;
 		ubc->isoinstatus = status;
-		tasklet_schedule(&ubc->rcvd_tasklet);
+		tasklet_hi_schedule(&ubc->rcvd_tasklet);
 	} else {
 		/* tasklet still busy, drop data and resubmit URB */
 		ubc->loststatus = status;
@@ -888,7 +888,7 @@ static void write_iso_callback(struct ur
 	ubc->isooutovfl = ubc->isooutdone;
 	ubc->isooutdone = ucx;
 	spin_unlock_irqrestore(&ubc->isooutlock, flags);
-	tasklet_schedule(&ubc->sent_tasklet);
+	tasklet_hi_schedule(&ubc->sent_tasklet);
 }
 
 /* starturbs
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/interface.c linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/interface.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/interface.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/interface.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,9 @@ static void if_close(struct tty_struct *
 
 	mutex_lock(&cs->mutex);
 
-	if (!cs->open_count)
+	if (!cs->connected)
+		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 {
 		if (!--cs->open_count) {
@@ -228,7 +230,10 @@ static int if_ioctl(struct tty_struct *t
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS; // FIXME -EINTR?
 
-	if (!cs->open_count)
+	if (!cs->connected) {
+		gig_dbg(DEBUG_IF, "not connected");
+		retval = -ENODEV;
+	} else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else {
 		retval = 0;
@@ -248,13 +253,6 @@ static int if_ioctl(struct tty_struct *t
 				retval = put_user(int_arg, (int __user *) arg);
 			break;
 		case GIGASET_BRKCHARS:
-			//FIXME test if MS_LOCKED
-			if (!cs->connected) {
-				gig_dbg(DEBUG_ANY,
-				    "can't communicate with unplugged device");
-				retval = -ENODEV;
-				break;
-			}
 			retval = copy_from_user(&buf,
 					(const unsigned char __user *) arg, 6)
 				? -EFAULT : 0;
@@ -331,7 +329,7 @@ static int if_tiocmset(struct tty_struct
 		return -ERESTARTSYS; // FIXME -EINTR?
 
 	if (!cs->connected) {
-		gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
+		gig_dbg(DEBUG_IF, "not connected");
 		retval = -ENODEV;
 	} else {
 		mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR);
@@ -360,14 +358,14 @@ static int if_write(struct tty_struct *t
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS; // FIXME -EINTR?
 
-	if (!cs->open_count)
+	if (!cs->connected) {
+		gig_dbg(DEBUG_IF, "not connected");
+		retval = -ENODEV;
+	} else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else if (cs->mstate != MS_LOCKED) {
 		dev_warn(cs->dev, "can't write to unlocked device\n");
 		retval = -EBUSY;
-	} else if (!cs->connected) {
-		gig_dbg(DEBUG_ANY, "can't write to unplugged device");
-		retval = -EBUSY; //FIXME
 	} else {
 		retval = cs->ops->write_cmd(cs, buf, count,
 					    &cs->if_wake_tasklet);
@@ -394,14 +392,14 @@ static int if_write_room(struct tty_stru
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS; // FIXME -EINTR?
 
-	if (!cs->open_count)
+	if (!cs->connected) {
+		gig_dbg(DEBUG_IF, "not connected");
+		retval = -ENODEV;
+	} else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else if (cs->mstate != MS_LOCKED) {
 		dev_warn(cs->dev, "can't write to unlocked device\n");
 		retval = -EBUSY;
-	} else if (!cs->connected) {
-		gig_dbg(DEBUG_ANY, "can't write to unplugged device");
-		retval = -EBUSY; //FIXME
 	} else
 		retval = cs->ops->write_room(cs);
 
@@ -426,14 +424,14 @@ static int if_chars_in_buffer(struct tty
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS; // FIXME -EINTR?
 
-	if (!cs->open_count)
+	if (!cs->connected) {
+		gig_dbg(DEBUG_IF, "not connected");
+		retval = -ENODEV;
+	} else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 	else if (cs->mstate != MS_LOCKED) {
 		dev_warn(cs->dev, "can't write to unlocked device\n");
 		retval = -EBUSY;
-	} else if (!cs->connected) {
-		gig_dbg(DEBUG_ANY, "can't write to unplugged device");
-		retval = -EBUSY; //FIXME
 	} else
 		retval = cs->ops->chars_in_buffer(cs);
 
@@ -456,7 +454,9 @@ static void if_throttle(struct tty_struc
 
 	mutex_lock(&cs->mutex);
 
-	if (!cs->open_count)
+	if (!cs->connected)
+		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
@@ -479,7 +479,9 @@ static void if_unthrottle(struct tty_str
 
 	mutex_lock(&cs->mutex);
 
-	if (!cs->open_count)
+	if (!cs->connected)
+		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
@@ -506,13 +508,13 @@ static void if_set_termios(struct tty_st
 
 	mutex_lock(&cs->mutex);
 
-	if (!cs->open_count) {
-		dev_warn(cs->dev, "%s: device not opened\n", __func__);
+	if (!cs->connected) {
+		gig_dbg(DEBUG_IF, "not connected");
 		goto out;
 	}
 
-	if (!cs->connected) {
-		gig_dbg(DEBUG_ANY, "can't communicate with unplugged device");
+	if (!cs->open_count) {
+		dev_warn(cs->dev, "%s: device not opened\n", __func__);
 		goto out;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/isocdata.c linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/isocdata.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/isocdata.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/isocdata.c	2009-06-09 23:05:27.000000000 -0400
@@ -175,7 +175,7 @@ int gigaset_isowbuf_getbytes(struct isow
 		return -EINVAL;
 	}
 	src = iwb->read;
-	if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
+	if (unlikely(limit >= BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
 		     (read < src && limit >= src))) {
 		pr_err("isoc write buffer frame reservation violated\n");
 		return -EFAULT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/Kconfig linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 menuconfig ISDN_DRV_GIGASET
-	tristate "Siemens Gigaset support (isdn)"
+	tristate "Siemens Gigaset support"
 	select CRC_CCITT
 	select BITREVERSE
 	help
@@ -11,11 +11,11 @@ menuconfig ISDN_DRV_GIGASET
 	  one of the connection specific parts that follow.
 	  This will build a module called "gigaset".
 
-if ISDN_DRV_GIGASET!=n
+if ISDN_DRV_GIGASET
 
 config GIGASET_BASE
 	tristate "Gigaset base station support"
-	depends on ISDN_DRV_GIGASET && USB
+	depends on USB
 	help
 	  Say M here if you want to use the USB interface of the Gigaset
 	  base for connection to your system.
@@ -23,7 +23,7 @@ config GIGASET_BASE
 
 config GIGASET_M105
 	tristate "Gigaset M105 support"
-	depends on ISDN_DRV_GIGASET && USB
+	depends on USB
 	help
 	  Say M here if you want to connect to the Gigaset base via DECT
 	  using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
@@ -31,7 +31,6 @@ config GIGASET_M105
 
 config GIGASET_M101
 	tristate "Gigaset M101 support"
-	depends on ISDN_DRV_GIGASET
 	help
 	  Say M here if you want to connect to the Gigaset base via DECT
 	  using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
@@ -48,7 +47,6 @@ config GIGASET_UNDOCREQ
 	help
 	  This enables support for USB requests we only know from
 	  reverse engineering (currently M105 only). If you need
-	  features like configuration mode of M105, say yes. If you
-	  care about your device, say no.
+	  features like configuration mode of M105, say yes.
 
-endif # ISDN_DRV_GIGASET != n
+endif # ISDN_DRV_GIGASET
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/ser-gigaset.c linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/ser-gigaset.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/ser-gigaset.c	2009-06-09 23:05:27.000000000 -0400
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct card
 
 static void gigaset_device_release(struct device *dev)
 {
-	struct platform_device *pdev =
-		container_of(dev, struct platform_device, dev);
+	struct platform_device *pdev = to_platform_device(dev);
 
 	/* adapted from platform_device_release() in drivers/base/platform.c */
 	//FIXME is this actually necessary?
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/usb-gigaset.c linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/usb-gigaset.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/usb-gigaset.c	2009-06-09 23:05:27.000000000 -0400
@@ -278,17 +278,17 @@ static int gigaset_set_line_ctrl(struct
 static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
 				  unsigned new_state)
 {
-	return -EINVAL;
+	return -ENOTTY;
 }
 
 static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
 {
-	return -EINVAL;
+	return -ENOTTY;
 }
 
 static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
 {
-	return -EINVAL;
+	return -ENOTTY;
 }
 #endif
 
@@ -577,7 +577,7 @@ static int gigaset_brkchars(struct cards
 	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
 			       0, 0, &buf, 6, 2000);
 #else
-	return -EINVAL;
+	return -ENOTTY;
 #endif
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/debug.c linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/debug.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -1198,7 +1198,7 @@ int SuperTraceASSIGN (void* AdapterHandl
         pC->xbuffer[5] = (byte)(rx_dma_magic >>  8);
         pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
         pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
-        pC->xbuffer[8] = (byte)DIVA_MAX_MANAGEMENT_TRANSFER_SIZE;
+	pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
         pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
         pC->xbuffer[10] = 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/divasi.c linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/divasi.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/divasi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/divasi.c	2009-06-09 23:05:27.000000000 -0400
@@ -118,7 +118,6 @@ static int DIVA_INIT_FUNCTION create_um_
 		return (0);
 
 	um_idi_proc_entry->read_proc = um_idi_proc_read;
-	um_idi_proc_entry->owner = THIS_MODULE;
 
 	return (1);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/message.c linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/message.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/eicon/message.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/eicon/message.c	2009-06-09 23:05:27.000000000 -0400
@@ -1194,7 +1194,8 @@ static char hex_digit_table[0x10] =
 /* translation function for each message                            */
 /*------------------------------------------------------------------*/
 
-byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ch;
   word i;
@@ -1411,7 +1412,8 @@ byte connect_req(dword Id, word Number,
   return 2;
 }
 
-byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word i, Info;
   word Reject;
@@ -1567,13 +1569,15 @@ byte connect_res(dword Id, word Number,
   return 1;
 }
 
-byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			  PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   dbug(1,dprintf("connect_a_res"));
   return false;
 }
 
-byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			   PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   word Info;
   word i;
@@ -1628,7 +1632,8 @@ byte disconnect_req(dword Id, word Numbe
   return false;
 }
 
-byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			   PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   dbug(1,dprintf("disconnect_res"));
   if(plci)
@@ -1655,7 +1660,8 @@ byte disconnect_res(dword Id, word Numbe
   return 0;
 }
 
-byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+		       PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word Info;
   byte i;
@@ -1704,7 +1710,8 @@ byte listen_req(dword Id, word Number, D
   return false;
 }
 
-byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+		     PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   word i;
   API_PARSE * ai;
@@ -1813,13 +1820,15 @@ byte info_req(dword Id, word Number, DIV
   return false;
 }
 
-byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+		     PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   dbug(1,dprintf("info_res"));
   return false;
 }
 
-byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+		      PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   word Info;
   byte ret;
@@ -1849,7 +1858,8 @@ byte alert_req(dword Id, word Number, DI
   return ret;
 }
 
-byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   word Info = 0;
   word i    = 0;
@@ -2599,13 +2609,15 @@ byte facility_req(dword Id, word Number,
   return false;
 }
 
-byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   dbug(1,dprintf("facility_res"));
   return false;
 }
 
-byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			   PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word Info = 0;
   byte req;
@@ -2839,7 +2851,8 @@ byte connect_b3_req(dword Id, word Numbe
   return false;
 }
 
-byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			   PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ncci;
   API_PARSE * ncpi;
@@ -2954,7 +2967,8 @@ byte connect_b3_res(dword Id, word Numbe
   return false;
 }
 
-byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			     PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ncci;
 
@@ -2974,7 +2988,8 @@ byte connect_b3_a_res(dword Id, word Num
   return false;
 }
 
-byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			      PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word Info;
   word ncci;
@@ -3030,7 +3045,8 @@ byte disconnect_b3_req(dword Id, word Nu
   return false;
 }
 
-byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			      PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ncci;
   word i;
@@ -3086,7 +3102,8 @@ byte disconnect_b3_res(dword Id, word Nu
   return false;
 }
 
-byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   NCCI   *ncci_ptr;
   DATA_B3_DESC   *data;
@@ -3163,7 +3180,8 @@ byte data_b3_req(dword Id, word Number,
   return false;
 }
 
-byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word n;
   word ncci;
@@ -3196,7 +3214,8 @@ byte data_b3_res(dword Id, word Number,
   return false;
 }
 
-byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word Info;
   word ncci;
@@ -3237,7 +3256,8 @@ byte reset_b3_req(dword Id, word Number,
   return false;
 }
 
-byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ncci;
 
@@ -3261,7 +3281,8 @@ byte reset_b3_res(dword Id, word Number,
   return false;
 }
 
-byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * parms)
+static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+				 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
   word ncci;
   API_PARSE * ncpi;
@@ -3295,7 +3316,8 @@ byte connect_b3_t90_a_res(dword Id, word
 }
 
 
-byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER   * a, PLCI   * plci, APPL   * appl, API_PARSE * msg)
+static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
   word Info=0;
   word i;
@@ -8689,7 +8711,7 @@ static word add_modem_b23 (PLCI  * plci,
 /* send a request for the signaling entity                          */
 /*------------------------------------------------------------------*/
 
-void sig_req(PLCI   * plci, byte req, byte Id)
+static void sig_req(PLCI *plci, byte req, byte Id)
 {
   if(!plci) return;
   if(plci->adapter->adapter_disabled) return;
@@ -8789,7 +8811,7 @@ static void send_req(PLCI *plci)
   dbug(1,dprintf("send_ok"));
 }
 
-void send_data(PLCI   * plci)
+static void send_data(PLCI *plci)
 {
   DIVA_CAPI_ADAPTER   * a;
   DATA_B3_DESC   * data;
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcpci.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,8 +56,8 @@ static const char *hfcpci_revision = "2.
 static int HFC_cnt;
 static uint debug;
 static uint poll, tics;
-struct timer_list hfc_tl;
-u32	hfc_jiffies;
+static struct timer_list hfc_tl;
+static unsigned long hfc_jiffies;
 
 MODULE_AUTHOR("Karsten Keil");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,7 @@
 #include <linux/mISDNhw.h>
 #include "hfcsusb.h"
 
-const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
+static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
 
 static unsigned int debug;
 static int poll = DEFAULT_TRANSP_BURST_SZ;
@@ -974,7 +974,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo,
 	spin_unlock(&hw->lock);
 }
 
-void
+static void
 fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
 	      void *buf, int num_packets, int packet_size, int interval,
 	      usb_complete_t complete, void *context)
@@ -1720,7 +1720,7 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw
 
 
 /* Hardware Initialization */
-int
+static int
 setup_hfcsusb(struct hfcsusb *hw)
 {
 	int err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h
--- linux-libre-2.6.29-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hardware/mISDN/hfcsusb.h	2009-06-09 23:05:27.000000000 -0400
@@ -198,7 +198,7 @@ validconf[][19] = {
 };
 
 /* string description of chosen config */
-char *conf_str[] = {
+static char *conf_str[] = {
 	"4 Interrupt IN + 3 Isochron OUT",
 	"3 Interrupt IN + 3 Isochron OUT",
 	"4 Isochron IN + 3 Isochron OUT",
@@ -316,7 +316,7 @@ struct hfcsusb_vdata {
 #define HFC_MAX_TE_LAYER1_STATE 8
 #define HFC_MAX_NT_LAYER1_STATE 4
 
-const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
+static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
 	"TE F0 - Reset",
 	"TE F1 - Reset",
 	"TE F2 - Sensing",
@@ -328,7 +328,7 @@ const char *HFC_TE_LAYER1_STATES[HFC_MAX
 	"TE F8 - Lost framing",
 };
 
-const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
+static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
 	"NT G0 - Reset",
 	"NT G1 - Deactive",
 	"NT G2 - Pending activation",
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/callc.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/callc.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/callc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/callc.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,6 @@
 const char *lli_revision = "$Revision: 2.59.2.4 $";
 
 extern struct IsdnCard cards[];
-extern int nrcards;
 
 static int init_b_st(struct Channel *chanp, int incoming);
 static void release_b_st(struct Channel *chanp);
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/config.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/config.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/config.c	2009-06-09 23:05:27.000000000 -0400
@@ -361,12 +361,6 @@ module_param_array(io1, int, NULL, 0);
 
 int nrcards;
 
-extern const char *l1_revision;
-extern const char *l2_revision;
-extern const char *l3_revision;
-extern const char *lli_revision;
-extern const char *tei_revision;
-
 char *HiSax_getrev(const char *revision)
 {
 	char *rev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/hfcscard.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hfcscard.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/hfcscard.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hfcscard.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,8 +16,6 @@
 #include "hfc_2bds0.h"
 #include "isdnl1.h"
 
-extern const char *CardType[];
-
 static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
 
 static irqreturn_t
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/hisax.h linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hisax.h
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/hisax.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hisax.h	2009-06-09 23:05:27.000000000 -0400
@@ -121,6 +121,15 @@
 
 #ifdef __KERNEL__
 
+extern const char *CardType[];
+extern int nrcards;
+
+extern const char *l1_revision;
+extern const char *l2_revision;
+extern const char *l3_revision;
+extern const char *lli_revision;
+extern const char *tei_revision;
+
 /* include l3dss1 & ni1 specific process structures, but no other defines */
 #ifdef CONFIG_HISAX_EURO
   #define l3dss1_process
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/isdnl1.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/isdnl1.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/isdnl1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/isdnl1.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,12 +18,12 @@
  *
  */
 
-const char *l1_revision = "$Revision: 2.46.2.5 $";
-
 #include <linux/init.h>
 #include "hisax.h"
 #include "isdnl1.h"
 
+const char *l1_revision = "$Revision: 2.46.2.5 $";
+
 #define TIMER3_VALUE 7000
 
 static struct Fsm l1fsm_b;
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/sedlbauer.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/sedlbauer.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/sedlbauer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/sedlbauer.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,8 +48,6 @@
 #include <linux/pci.h>
 #include <linux/isapnp.h>
 
-extern const char *CardType[];
-
 static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
 
 static const char *Sedlbauer_Types[] =
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/st5481_usb.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/st5481_usb.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/st5481_usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/st5481_usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -149,14 +149,7 @@ static void usb_ctrl_complete(struct urb
 	if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
 	        /* Special case handling for pipe reset */
 		le16_to_cpus(&ctrl_msg->dr.wIndex);
-
-		/* toggle is reset on clear */
-		usb_settoggle(adapter->usb_dev, 
-			      ctrl_msg->dr.wIndex & ~USB_DIR_IN, 
-			      (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0,
-			      0);
-
-
+		usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex);
 	}
 	
 	if (ctrl_msg->complete)
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/teles0.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/teles0.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/teles0.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/teles0.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,8 +21,6 @@
 #include "isac.h"
 #include "hscx.h"
 
-extern const char *CardType[];
-
 static const char *teles0_revision = "$Revision: 2.15.2.4 $";
 
 #define TELES_IOMEM_SIZE	0x400
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/hisax/teles3.c linux-libre-2.6.30-gnu1/drivers/isdn/hisax/teles3.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/hisax/teles3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/hisax/teles3.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@
 #include "hscx.h"
 #include "isdnl1.h"
 
-extern const char *CardType[];
 static const char *teles3_revision = "$Revision: 2.19.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/clock.c linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/clock.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/clock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/clock.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,11 +41,11 @@
 
 static u_int *debug;
 static LIST_HEAD(iclock_list);
-DEFINE_RWLOCK(iclock_lock);
-u16	iclock_count;		/* counter of last clock */
-struct	timeval iclock_tv;	/* time stamp of last clock */
-int	iclock_tv_valid;	/* already received one timestamp */
-struct	mISDNclock *iclock_current;
+static DEFINE_RWLOCK(iclock_lock);
+static u16 iclock_count;		/* counter of last clock */
+static struct timeval iclock_tv;	/* time stamp of last clock */
+static int iclock_tv_valid;		/* already received one timestamp */
+static struct mISDNclock *iclock_current;
 
 void
 mISDN_init_clock(u_int *dp)
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/Kconfig linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -14,13 +14,15 @@ config MISDN_DSP
 	depends on MISDN
 	help
 	  Enable support for digital audio processing capability.
+
 	  This module may be used for special applications that require
-	  cross connecting of bchannels, conferencing, dtmf decoding
+	  cross connecting of bchannels, conferencing, dtmf decoding,
 	  echo cancelation, tone generation, and Blowfish encryption and
-	  decryption.
-	  It may use hardware features if available.
+	  decryption. It may use hardware features if available.
+
 	  E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
-	  and get more informations about this module and it's usage.
+	  and get more information about this module and its usage.
+
 	  If unsure, say 'N'.
 
 config MISDN_L1OIP
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/l1oip_codec.c linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/l1oip_codec.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/l1oip_codec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/l1oip_codec.c	2009-06-09 23:05:27.000000000 -0400
@@ -331,7 +331,7 @@ l1oip_4bit_alloc(int ulaw)
 	/* alloc conversion tables */
 	table_com = vmalloc(65536);
 	table_dec = vmalloc(512);
-	if (!table_com | !table_dec) {
+	if (!table_com || !table_dec) {
 		l1oip_4bit_free();
 		return -ENOMEM;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/timerdev.c linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/timerdev.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/mISDN/timerdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/mISDN/timerdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,8 +152,7 @@ dev_expire_timer(unsigned long data)
 	u_long			flags;
 
 	spin_lock_irqsave(&timer->dev->lock, flags);
-	list_del(&timer->list);
-	list_add_tail(&timer->list, &timer->dev->expired);
+	list_move_tail(&timer->list, &timer->dev->expired);
 	spin_unlock_irqrestore(&timer->dev->lock, flags);
 	wake_up_interruptible(&timer->dev->wait);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/isdn/pcbit/layer2.c linux-libre-2.6.30-gnu1/drivers/isdn/pcbit/layer2.c
--- linux-libre-2.6.29-gnu1/drivers/isdn/pcbit/layer2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/isdn/pcbit/layer2.c	2009-06-09 23:05:27.000000000 -0400
@@ -347,8 +347,7 @@ pcbit_receive(struct pcbit_dev *dev)
 		if (dev->read_frame) {
 			printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
 			/* discard previous queued frame */
-			if (dev->read_frame->skb)
-				kfree_skb(dev->read_frame->skb);
+			kfree_skb(dev->read_frame->skb);
 			kfree(dev->read_frame);
 			dev->read_frame = NULL;
 		}
@@ -601,8 +600,7 @@ pcbit_l2_err_recover(unsigned long data)
 	dev->w_busy = dev->r_busy = 1;
 
 	if (dev->read_frame) {
-		if (dev->read_frame->skb)
-			kfree_skb(dev->read_frame->skb);
+		kfree_skb(dev->read_frame->skb);
 		kfree(dev->read_frame);
 		dev->read_frame = NULL;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/Kconfig linux-libre-2.6.30-gnu1/drivers/leds/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/leds/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,13 @@ config LEDS_LOCOMO
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
 
+config LEDS_MIKROTIK_RB532
+	tristate "LED Support for Mikrotik Routerboard 532"
+	depends on LEDS_CLASS && MIKROTIK_RB532
+	help
+	  This option enables support for the so called "User LED" of
+	  Mikrotik's Routerboard 532.
+
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS && ARCH_S3C2410
@@ -100,7 +107,7 @@ config LEDS_HP6XX
 	tristate "LED Support for the HP Jornada 6xx"
 	depends on LEDS_CLASS && SH_HP6XX
 	help
-	  This option enables led support for the handheld
+	  This option enables LED support for the handheld
 	  HP Jornada 620/660/680/690.
 
 config LEDS_PCA9532
@@ -108,7 +115,7 @@ config LEDS_PCA9532
 	depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
 	help
 	  This option enables support for NXP pca9532
-	  led controller. It is generally only usefull
+	  LED controller. It is generally only useful
 	  as a platform driver
 
 config LEDS_GPIO
@@ -117,11 +124,40 @@ config LEDS_GPIO
 	help
 	  This option enables support for the LEDs connected to GPIO
 	  outputs. To be useful the particular board must have LEDs
-	  and they must be connected to the GPIO lines.
+	  and they must be connected to the GPIO lines.  The LEDs must be
+	  defined as platform devices and/or OpenFirmware platform devices.
+	  The code to use these bindings can be selected below.
+
+config LEDS_GPIO_PLATFORM
+	bool "Platform device bindings for GPIO LEDs"
+	depends on LEDS_GPIO
+	default y
+	help
+	  Let the leds-gpio driver drive LEDs which have been defined as
+	  platform devices.  If you don't know what this means, say yes.
+
+config LEDS_GPIO_OF
+	bool "OpenFirmware platform device bindings for GPIO LEDs"
+	depends on LEDS_GPIO && OF_DEVICE
+	default y
+	help
+	  Let the leds-gpio driver drive LEDs which have been defined as
+	  of_platform devices.  For instance, LEDs which are listed in a "dts"
+	  file.
+
+config LEDS_LP5521
+	tristate "LED Support for the LP5521 LEDs"
+	depends on LEDS_CLASS && I2C
+	help
+	  If you say 'Y' here you get support for the National Semiconductor
+	  LP5521 LED driver used in n8x0 boards.
+
+	  This driver can be built as a module by choosing 'M'. The module
+	  will be called leds-lp5521.
 
 config LEDS_CLEVO_MAIL
-	tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
-	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
+	tristate "Mail LED on Clevo notebook"
+	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
 	help
 	  This driver makes the mail LED accessible from userspace
 	  programs through the leds subsystem. This LED have three
@@ -144,7 +180,7 @@ config LEDS_CLEVO_MAIL
 	  	Positivo Mobile (Clevo M5x0V)
 
 	  If your model is not listed here you can try the "nodetect"
-	  module paramter.
+	  module parameter.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called leds-clevo-mail.
@@ -171,6 +207,26 @@ config LEDS_DA903X
 	  This option enables support for on-chip LED drivers found
 	  on Dialog Semiconductor DA9030/DA9034 PMICs.
 
+config LEDS_DAC124S085
+	tristate "LED Support for DAC124S085 SPI DAC"
+	depends on LEDS_CLASS && SPI
+	help
+	  This option enables support for DAC124S085 SPI DAC from NatSemi,
+	  which can be used to control up to four LEDs.
+
+config LEDS_PWM
+	tristate "PWM driven LED Support"
+	depends on LEDS_CLASS && HAVE_PWM
+	help
+	  This option enables support for pwm driven LEDs
+
+config LEDS_BD2802
+	tristate "LED driver for BD2802 RGB LED"
+	depends on LEDS_CLASS && I2C
+	help
+	  This option enables support for BD2802GU RGB LED driver chips
+	  accessed via the I2C bus.
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
@@ -216,6 +272,19 @@ config LEDS_TRIGGER_BACKLIGHT
 
 	  If unsure, say N.
 
+config LEDS_TRIGGER_GPIO
+	tristate "LED GPIO Trigger"
+	depends on LEDS_TRIGGERS
+	depends on GPIOLIB
+	help
+	  This allows LEDs to be controlled by gpio events. It's good
+	  when using gpios as switches and triggering the needed LEDs
+	  from there. One use case is n810's keypad LEDs that could
+	  be triggered by this trigger when user slides up to show
+	  keypad.
+
+	  If unsure, say N.
+
 config LEDS_TRIGGER_DEFAULT_ON
 	tristate "LED Default ON Trigger"
 	depends on LEDS_TRIGGERS
@@ -223,4 +292,7 @@ config LEDS_TRIGGER_DEFAULT_ON
 	  This allows LEDs to be initialised in the ON state.
 	  If unsure, say Y.
 
+comment "iptables trigger is under Netfilter config (LED target)"
+	depends on LEDS_TRIGGERS
+
 endif # NEW_LEDS
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/led-class.c linux-libre-2.6.30-gnu1/drivers/leds/led-class.c
--- linux-libre-2.6.29-gnu1/drivers/leds/led-class.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/led-class.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(stru
 	return ret;
 }
 
+static ssize_t led_max_brightness_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", led_cdev->max_brightness);
+}
+
 static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
 #ifdef CONFIG_LEDS_TRIGGERS
 static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
 #endif
@@ -138,6 +147,13 @@ int led_classdev_register(struct device
 	list_add_tail(&led_cdev->node, &leds_list);
 	up_write(&leds_list_lock);
 
+	if (!led_cdev->max_brightness)
+		led_cdev->max_brightness = LED_FULL;
+
+	rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
+	if (rc)
+		goto err_out_attr_max;
+
 	led_update_brightness(led_cdev);
 
 #ifdef CONFIG_LEDS_TRIGGERS
@@ -155,9 +171,11 @@ int led_classdev_register(struct device
 
 #ifdef CONFIG_LEDS_TRIGGERS
 err_out_led_list:
+	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
+#endif
+err_out_attr_max:
 	device_remove_file(led_cdev->dev, &dev_attr_brightness);
 	list_del(&led_cdev->node);
-#endif
 err_out:
 	device_unregister(led_cdev->dev);
 	return rc;
@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register)
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
+	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
 	device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
 	device_remove_file(led_cdev->dev, &dev_attr_trigger);
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-bd2802.c linux-libre-2.6.30-gnu1/drivers/leds/leds-bd2802.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-bd2802.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-bd2802.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,765 @@
+/*
+ * leds-bd2802.c - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@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.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/leds-bd2802.h>
+
+
+#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
+
+#define BD2802_LED_OFFSET		0xa
+#define BD2802_COLOR_OFFSET		0x3
+
+#define BD2802_REG_CLKSETUP 		0x00
+#define BD2802_REG_CONTROL 		0x01
+#define BD2802_REG_HOURSETUP		0x02
+#define BD2802_REG_CURRENT1SETUP	0x03
+#define BD2802_REG_CURRENT2SETUP	0x04
+#define BD2802_REG_WAVEPATTERN		0x05
+
+#define BD2802_CURRENT_032		0x10 /* 3.2mA */
+#define BD2802_CURRENT_000		0x00 /* 0.0mA */
+
+#define BD2802_PATTERN_FULL		0x07
+#define BD2802_PATTERN_HALF		0x03
+
+enum led_ids {
+	LED1,
+	LED2,
+	LED_NUM,
+};
+
+enum led_colors {
+	RED,
+	GREEN,
+	BLUE,
+};
+
+enum led_bits {
+	BD2802_OFF,
+	BD2802_BLINK,
+	BD2802_ON,
+};
+
+/*
+ * State '0' : 'off'
+ * State '1' : 'blink'
+ * State '2' : 'on'.
+ */
+struct led_state {
+	unsigned r:2;
+	unsigned g:2;
+	unsigned b:2;
+};
+
+struct bd2802_led {
+	struct bd2802_led_platform_data	*pdata;
+	struct i2c_client		*client;
+	struct rw_semaphore		rwsem;
+	struct work_struct		work;
+
+	struct led_state		led[2];
+
+	/*
+	 * Making led_classdev as array is not recommended, because array
+	 * members prevent using 'container_of' macro. So repetitive works
+	 * are needed.
+	 */
+	struct led_classdev		cdev_led1r;
+	struct led_classdev		cdev_led1g;
+	struct led_classdev		cdev_led1b;
+	struct led_classdev		cdev_led2r;
+	struct led_classdev		cdev_led2g;
+	struct led_classdev		cdev_led2b;
+
+	/*
+	 * Advanced Configuration Function(ADF) mode:
+	 * In ADF mode, user can set registers of BD2802GU directly,
+	 * therefore BD2802GU doesn't enter reset state.
+	 */
+	int 				adf_on;
+
+	enum led_ids			led_id;
+	enum led_colors			color;
+	enum led_bits			state;
+};
+
+
+/*--------------------------------------------------------------*/
+/*	BD2802GU helper functions					*/
+/*--------------------------------------------------------------*/
+
+static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	switch (color) {
+	case RED:
+		return !led->led[id].r;
+	case GREEN:
+		return !led->led[id].g;
+	case BLUE:
+		return !led->led[id].b;
+	default:
+		dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
+		return -EINVAL;
+	}
+}
+
+static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
+{
+	if (led->led[id].r || led->led[id].g || led->led[id].b)
+		return 0;
+
+	return 1;
+}
+
+static inline int bd2802_is_all_off(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < LED_NUM; i++)
+		if (!bd2802_is_led_off(led, i))
+			return 0;
+
+	return 1;
+}
+
+static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
+{
+	return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
+}
+
+static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
+								u8 reg_offset)
+{
+	return reg_offset + bd2802_get_base_offset(id, color);
+}
+
+
+/*--------------------------------------------------------------*/
+/*	BD2802GU core functions					*/
+/*--------------------------------------------------------------*/
+
+static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret = i2c_smbus_write_byte_data(client, reg, val);
+	if (ret >= 0)
+		return 0;
+
+	dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
+						__func__, reg, val, ret);
+
+	return ret;
+}
+
+static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
+				enum led_colors color, enum led_bits led_bit)
+{
+	int i;
+	u8 value;
+
+	for (i = 0; i < LED_NUM; i++) {
+		if (i == id) {
+			switch (color) {
+			case RED:
+				led->led[i].r = led_bit;
+				break;
+			case GREEN:
+				led->led[i].g = led_bit;
+				break;
+			case BLUE:
+				led->led[i].b = led_bit;
+				break;
+			default:
+				dev_err(&led->client->dev,
+					"%s: Invalid color\n", __func__);
+				return;
+			}
+		}
+	}
+
+	if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
+		return;
+
+	if (!bd2802_is_led_off(led, id))
+		return;
+
+	if (bd2802_is_all_off(led) && !led->adf_on) {
+		gpio_set_value(led->pdata->reset_gpio, 0);
+		return;
+	}
+
+	/*
+	 * In this case, other led is turned on, and current led is turned
+	 * off. So set RGB LED Control register to stop the current RGB LED
+	 */
+	value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
+	bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_configure(struct bd2802_led *led)
+{
+	struct bd2802_led_platform_data *pdata = led->pdata;
+	u8 reg;
+
+	reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
+	bd2802_write_byte(led->client, reg, pdata->rgb_time);
+
+	reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
+	bd2802_write_byte(led->client, reg, pdata->rgb_time);
+}
+
+static void bd2802_reset_cancel(struct bd2802_led *led)
+{
+	gpio_set_value(led->pdata->reset_gpio, 1);
+	udelay(100);
+	bd2802_configure(led);
+}
+
+static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
+{
+	enum led_ids other_led = (id == LED1) ? LED2 : LED1;
+	u8 value, other_led_on;
+
+	other_led_on = !bd2802_is_led_off(led, other_led);
+	if (id == LED1)
+		value = LED_CTL(other_led_on, 1);
+	else
+		value = LED_CTL(1 , other_led_on);
+
+	bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_all_off(led) && !led->adf_on)
+		bd2802_reset_cancel(led);
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+	bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
+
+	bd2802_enable(led, id);
+	bd2802_update_state(led, id, color, BD2802_ON);
+}
+
+static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_all_off(led) && !led->adf_on)
+		bd2802_reset_cancel(led);
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+	bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF);
+
+	bd2802_enable(led, id);
+	bd2802_update_state(led, id, color, BD2802_BLINK);
+}
+
+static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
+				enum led_colors color, enum led_bits led_bit)
+{
+	if (led_bit == BD2802_OFF) {
+		dev_err(&led->client->dev,
+					"Only 'blink' and 'on' are allowed\n");
+		return;
+	}
+
+	if (led_bit == BD2802_BLINK)
+		bd2802_set_blink(led, id, color);
+	else
+		bd2802_set_on(led, id, color);
+}
+
+static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_rgb_off(led, id, color))
+		return;
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+
+	bd2802_update_state(led, id, color, BD2802_OFF);
+}
+
+static void bd2802_restore_state(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < LED_NUM; i++) {
+		if (led->led[i].r)
+			bd2802_turn_on(led, i, RED, led->led[i].r);
+		if (led->led[i].g)
+			bd2802_turn_on(led, i, GREEN, led->led[i].g);
+		if (led->led[i].b)
+			bd2802_turn_on(led, i, BLUE, led->led[i].b);
+	}
+}
+
+#define BD2802_SET_REGISTER(reg_addr, reg_name)				\
+static ssize_t bd2802_store_reg##reg_addr(struct device *dev,		\
+	struct device_attribute *attr, const char *buf, size_t count)	\
+{									\
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
+	unsigned long val;						\
+	int ret;							\
+	if (!count)							\
+		return -EINVAL;						\
+	ret = strict_strtoul(buf, 16, &val);				\
+	if (ret)							\
+		return ret;						\
+	down_write(&led->rwsem);					\
+	bd2802_write_byte(led->client, reg_addr, (u8) val);		\
+	up_write(&led->rwsem);						\
+	return count;							\
+}									\
+static struct device_attribute bd2802_reg##reg_addr##_attr = {		\
+	.attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE},	\
+	.store = bd2802_store_reg##reg_addr,				\
+};
+
+BD2802_SET_REGISTER(0x00, "0x00");
+BD2802_SET_REGISTER(0x01, "0x01");
+BD2802_SET_REGISTER(0x02, "0x02");
+BD2802_SET_REGISTER(0x03, "0x03");
+BD2802_SET_REGISTER(0x04, "0x04");
+BD2802_SET_REGISTER(0x05, "0x05");
+BD2802_SET_REGISTER(0x06, "0x06");
+BD2802_SET_REGISTER(0x07, "0x07");
+BD2802_SET_REGISTER(0x08, "0x08");
+BD2802_SET_REGISTER(0x09, "0x09");
+BD2802_SET_REGISTER(0x0a, "0x0a");
+BD2802_SET_REGISTER(0x0b, "0x0b");
+BD2802_SET_REGISTER(0x0c, "0x0c");
+BD2802_SET_REGISTER(0x0d, "0x0d");
+BD2802_SET_REGISTER(0x0e, "0x0e");
+BD2802_SET_REGISTER(0x0f, "0x0f");
+BD2802_SET_REGISTER(0x10, "0x10");
+BD2802_SET_REGISTER(0x11, "0x11");
+BD2802_SET_REGISTER(0x12, "0x12");
+BD2802_SET_REGISTER(0x13, "0x13");
+BD2802_SET_REGISTER(0x14, "0x14");
+BD2802_SET_REGISTER(0x15, "0x15");
+
+static struct device_attribute *bd2802_addr_attributes[] = {
+	&bd2802_reg0x00_attr,
+	&bd2802_reg0x01_attr,
+	&bd2802_reg0x02_attr,
+	&bd2802_reg0x03_attr,
+	&bd2802_reg0x04_attr,
+	&bd2802_reg0x05_attr,
+	&bd2802_reg0x06_attr,
+	&bd2802_reg0x07_attr,
+	&bd2802_reg0x08_attr,
+	&bd2802_reg0x09_attr,
+	&bd2802_reg0x0a_attr,
+	&bd2802_reg0x0b_attr,
+	&bd2802_reg0x0c_attr,
+	&bd2802_reg0x0d_attr,
+	&bd2802_reg0x0e_attr,
+	&bd2802_reg0x0f_attr,
+	&bd2802_reg0x10_attr,
+	&bd2802_reg0x11_attr,
+	&bd2802_reg0x12_attr,
+	&bd2802_reg0x13_attr,
+	&bd2802_reg0x14_attr,
+	&bd2802_reg0x15_attr,
+};
+
+static void bd2802_enable_adv_conf(struct bd2802_led *led)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
+		ret = device_create_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+		if (ret) {
+			dev_err(&led->client->dev, "failed to sysfs file %s\n",
+					bd2802_addr_attributes[i]->attr.name);
+			goto failed_remove_files;
+		}
+	}
+
+	if (bd2802_is_all_off(led))
+		bd2802_reset_cancel(led);
+
+	led->adf_on = 1;
+
+	return;
+
+failed_remove_files:
+	for (i--; i >= 0; i--)
+		device_remove_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+}
+
+static void bd2802_disable_adv_conf(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
+		device_remove_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+
+	if (bd2802_is_all_off(led))
+		gpio_set_value(led->pdata->reset_gpio, 0);
+
+	led->adf_on = 0;
+}
+
+static ssize_t bd2802_show_adv_conf(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+	ssize_t ret;
+
+	down_read(&led->rwsem);
+	if (led->adf_on)
+		ret = sprintf(buf, "on\n");
+	else
+		ret = sprintf(buf, "off\n");
+	up_read(&led->rwsem);
+
+	return ret;
+}
+
+static ssize_t bd2802_store_adv_conf(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+
+	if (!count)
+		return -EINVAL;
+
+	down_write(&led->rwsem);
+	if (!led->adf_on && !strncmp(buf, "on", 2))
+		bd2802_enable_adv_conf(led);
+	else if (led->adf_on && !strncmp(buf, "off", 3))
+		bd2802_disable_adv_conf(led);
+	up_write(&led->rwsem);
+
+	return count;
+}
+
+static struct device_attribute bd2802_adv_conf_attr = {
+	.attr = {
+		.name = "advanced_configuration",
+		.mode = 0644,
+		.owner = THIS_MODULE
+	},
+	.show = bd2802_show_adv_conf,
+	.store = bd2802_store_adv_conf,
+};
+
+static void bd2802_led_work(struct work_struct *work)
+{
+	struct bd2802_led *led = container_of(work, struct bd2802_led, work);
+
+	if (led->state)
+		bd2802_turn_on(led, led->led_id, led->color, led->state);
+	else
+		bd2802_turn_off(led, led->led_id, led->color);
+}
+
+#define BD2802_CONTROL_RGBS(name, id, clr)				\
+static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
+					enum led_brightness value)	\
+{									\
+	struct bd2802_led *led =					\
+		container_of(led_cdev, struct bd2802_led, cdev_##name);	\
+	led->led_id = id;						\
+	led->color = clr;						\
+	if (value == LED_OFF)						\
+		led->state = BD2802_OFF;				\
+	else								\
+		led->state = BD2802_ON;					\
+	schedule_work(&led->work);					\
+}									\
+static int bd2802_set_##name##_blink(struct led_classdev *led_cdev,	\
+		unsigned long *delay_on, unsigned long *delay_off)	\
+{									\
+	struct bd2802_led *led =					\
+		container_of(led_cdev, struct bd2802_led, cdev_##name);	\
+	if (*delay_on == 0 || *delay_off == 0)				\
+		return -EINVAL;						\
+	led->led_id = id;						\
+	led->color = clr;						\
+	led->state = BD2802_BLINK;					\
+	schedule_work(&led->work);					\
+	return 0;							\
+}
+
+BD2802_CONTROL_RGBS(led1r, LED1, RED);
+BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
+BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
+BD2802_CONTROL_RGBS(led2r, LED2, RED);
+BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
+BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
+
+static int bd2802_register_led_classdev(struct bd2802_led *led)
+{
+	int ret;
+
+	INIT_WORK(&led->work, bd2802_led_work);
+
+	led->cdev_led1r.name = "led1_R";
+	led->cdev_led1r.brightness = LED_OFF;
+	led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
+	led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
+	led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1r.name);
+		goto failed_unregister_led1_R;
+	}
+
+	led->cdev_led1g.name = "led1_G";
+	led->cdev_led1g.brightness = LED_OFF;
+	led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
+	led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
+	led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1g.name);
+		goto failed_unregister_led1_G;
+	}
+
+	led->cdev_led1b.name = "led1_B";
+	led->cdev_led1b.brightness = LED_OFF;
+	led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
+	led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
+	led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1b.name);
+		goto failed_unregister_led1_B;
+	}
+
+	led->cdev_led2r.name = "led2_R";
+	led->cdev_led2r.brightness = LED_OFF;
+	led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
+	led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
+	led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2r.name);
+		goto failed_unregister_led2_R;
+	}
+
+	led->cdev_led2g.name = "led2_G";
+	led->cdev_led2g.brightness = LED_OFF;
+	led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
+	led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
+	led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2g.name);
+		goto failed_unregister_led2_G;
+	}
+
+	led->cdev_led2b.name = "led2_B";
+	led->cdev_led2b.brightness = LED_OFF;
+	led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
+	led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
+	led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2b.name);
+		goto failed_unregister_led2_B;
+	}
+
+	return 0;
+
+failed_unregister_led2_B:
+	led_classdev_unregister(&led->cdev_led2g);
+failed_unregister_led2_G:
+	led_classdev_unregister(&led->cdev_led2r);
+failed_unregister_led2_R:
+	led_classdev_unregister(&led->cdev_led1b);
+failed_unregister_led1_B:
+	led_classdev_unregister(&led->cdev_led1g);
+failed_unregister_led1_G:
+	led_classdev_unregister(&led->cdev_led1r);
+failed_unregister_led1_R:
+
+	return ret;
+}
+
+static void bd2802_unregister_led_classdev(struct bd2802_led *led)
+{
+	cancel_work_sync(&led->work);
+	led_classdev_unregister(&led->cdev_led1r);
+}
+
+static int __devinit bd2802_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct bd2802_led *led;
+	struct bd2802_led_platform_data *pdata;
+	int ret;
+
+	led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
+	if (!led) {
+		dev_err(&client->dev, "failed to allocate driver data\n");
+		return -ENOMEM;
+	}
+
+	led->client = client;
+	pdata = led->pdata = client->dev.platform_data;
+	i2c_set_clientdata(client, led);
+
+	/* Configure RESET GPIO (L: RESET, H: RESET cancel) */
+	gpio_request(pdata->reset_gpio, "RGB_RESETB");
+	gpio_direction_output(pdata->reset_gpio, 1);
+
+	/* Tacss = min 0.1ms */
+	udelay(100);
+
+	/* Detect BD2802GU */
+	ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to detect device\n");
+		goto failed_free;
+	} else
+		dev_info(&client->dev, "return 0x%02x\n", ret);
+
+	/* To save the power, reset BD2802 after detecting */
+	gpio_set_value(led->pdata->reset_gpio, 0);
+
+	init_rwsem(&led->rwsem);
+
+	ret = device_create_file(&client->dev, &bd2802_adv_conf_attr);
+	if (ret) {
+		dev_err(&client->dev, "failed to create sysfs file %s\n",
+					bd2802_adv_conf_attr.attr.name);
+		goto failed_free;
+	}
+
+	ret = bd2802_register_led_classdev(led);
+	if (ret < 0)
+		goto failed_unregister_dev_file;
+
+	return 0;
+
+failed_unregister_dev_file:
+	device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+failed_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(led);
+
+	return ret;
+}
+
+static int __exit bd2802_remove(struct i2c_client *client)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	bd2802_unregister_led_classdev(led);
+	gpio_set_value(led->pdata->reset_gpio, 0);
+	if (led->adf_on)
+		bd2802_disable_adv_conf(led);
+	device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+	i2c_set_clientdata(client, NULL);
+	kfree(led);
+
+	return 0;
+}
+
+static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	gpio_set_value(led->pdata->reset_gpio, 0);
+
+	return 0;
+}
+
+static int bd2802_resume(struct i2c_client *client)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	if (!bd2802_is_all_off(led) || led->adf_on) {
+		gpio_set_value(led->pdata->reset_gpio, 1);
+		udelay(100);
+		bd2802_restore_state(led);
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id bd2802_id[] = {
+	{ "BD2802", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bd2802_id);
+
+static struct i2c_driver bd2802_i2c_driver = {
+	.driver	= {
+		.name	= "BD2802",
+	},
+	.probe		= bd2802_probe,
+	.remove		= __exit_p(bd2802_remove),
+	.suspend	= bd2802_suspend,
+	.resume		= bd2802_resume,
+	.id_table	= bd2802_id,
+};
+
+static int __init bd2802_init(void)
+{
+	return i2c_add_driver(&bd2802_i2c_driver);
+}
+module_init(bd2802_init);
+
+static void __exit bd2802_exit(void)
+{
+	i2c_del_driver(&bd2802_i2c_driver);
+}
+module_exit(bd2802_exit);
+
+MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
+MODULE_DESCRIPTION("BD2802 LED driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-dac124s085.c linux-libre-2.6.30-gnu1/drivers/leds/leds-dac124s085.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-dac124s085.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-dac124s085.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the DAC124S085 SPI DAC
+ */
+
+#include <linux/gfp.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+struct dac124s085_led {
+	struct led_classdev	ldev;
+	struct spi_device	*spi;
+	int			id;
+	int			brightness;
+	char			name[sizeof("dac124s085-3")];
+
+	struct mutex		mutex;
+	struct work_struct	work;
+	spinlock_t		lock;
+};
+
+struct dac124s085 {
+	struct dac124s085_led leds[4];
+};
+
+#define REG_WRITE		(0 << 12)
+#define REG_WRITE_UPDATE	(1 << 12)
+#define ALL_WRITE_UPDATE	(2 << 12)
+#define POWER_DOWN_OUTPUT	(3 << 12)
+
+static void dac124s085_led_work(struct work_struct *work)
+{
+	struct dac124s085_led *led = container_of(work, struct dac124s085_led,
+						  work);
+	u16 word;
+
+	mutex_lock(&led->mutex);
+	word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
+			   (led->brightness & 0xfff));
+	spi_write(led->spi, (const u8 *)&word, sizeof(word));
+	mutex_unlock(&led->mutex);
+}
+
+static void dac124s085_set_brightness(struct led_classdev *ldev,
+				      enum led_brightness brightness)
+{
+	struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
+						  ldev);
+
+	spin_lock(&led->lock);
+	led->brightness = brightness;
+	schedule_work(&led->work);
+	spin_unlock(&led->lock);
+}
+
+static int dac124s085_probe(struct spi_device *spi)
+{
+	struct dac124s085	*dac;
+	struct dac124s085_led	*led;
+	int i, ret;
+
+	dac = kzalloc(sizeof(*dac), GFP_KERNEL);
+	if (!dac)
+		return -ENOMEM;
+
+	spi->bits_per_word = 16;
+
+	for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+		led		= dac->leds + i;
+		led->id		= i;
+		led->brightness	= LED_OFF;
+		led->spi	= spi;
+		snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
+		spin_lock_init(&led->lock);
+		INIT_WORK(&led->work, dac124s085_led_work);
+		mutex_init(&led->mutex);
+		led->ldev.name = led->name;
+		led->ldev.brightness = LED_OFF;
+		led->ldev.max_brightness = 0xfff;
+		led->ldev.brightness_set = dac124s085_set_brightness;
+		ret = led_classdev_register(&spi->dev, &led->ldev);
+		if (ret < 0)
+			goto eledcr;
+	}
+
+	spi_set_drvdata(spi, dac);
+
+	return 0;
+
+eledcr:
+	while (i--)
+		led_classdev_unregister(&dac->leds[i].ldev);
+
+	spi_set_drvdata(spi, NULL);
+	kfree(dac);
+	return ret;
+}
+
+static int dac124s085_remove(struct spi_device *spi)
+{
+	struct dac124s085	*dac = spi_get_drvdata(spi);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+		led_classdev_unregister(&dac->leds[i].ldev);
+		cancel_work_sync(&dac->leds[i].work);
+	}
+
+	spi_set_drvdata(spi, NULL);
+	kfree(dac);
+
+	return 0;
+}
+
+static struct spi_driver dac124s085_driver = {
+	.probe		= dac124s085_probe,
+	.remove		= dac124s085_remove,
+	.driver = {
+		.name	= "dac124s085",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init dac124s085_leds_init(void)
+{
+	return spi_register_driver(&dac124s085_driver);
+}
+
+static void __exit dac124s085_leds_exit(void)
+{
+	spi_unregister_driver(&dac124s085_driver);
+}
+
+module_init(dac124s085_leds_init);
+module_exit(dac124s085_leds_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_DESCRIPTION("DAC124S085 LED driver");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-gpio.c linux-libre-2.6.30-gnu1/drivers/leds/leds-gpio.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * 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
@@ -71,11 +72,67 @@ static int gpio_blink_set(struct led_cla
 	return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
 }
 
+static int __devinit create_gpio_led(const struct gpio_led *template,
+	struct gpio_led_data *led_dat, struct device *parent,
+	int (*blink_set)(unsigned, unsigned long *, unsigned long *))
+{
+	int ret;
+
+	/* skip leds that aren't available */
+	if (!gpio_is_valid(template->gpio)) {
+		printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", 
+				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->can_sleep = gpio_cansleep(template->gpio);
+	led_dat->active_low = template->active_low;
+	if (blink_set) {
+		led_dat->platform_gpio_blink_set = blink_set;
+		led_dat->cdev.blink_set = gpio_blink_set;
+	}
+	led_dat->cdev.brightness_set = gpio_led_set;
+	led_dat->cdev.brightness = LED_OFF;
+	if (!template->retain_state_suspended)
+		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = gpio_direction_output(led_dat->gpio, led_dat->active_low);
+	if (ret < 0)
+		goto err;
+
+	INIT_WORK(&led_dat->work, gpio_led_work);
+
+	ret = led_classdev_register(parent, &led_dat->cdev);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+err:
+	gpio_free(led_dat->gpio);
+	return ret;
+}
+
+static void delete_gpio_led(struct gpio_led_data *led)
+{
+	if (!gpio_is_valid(led->gpio))
+		return;
+	led_classdev_unregister(&led->cdev);
+	cancel_work_sync(&led->work);
+	gpio_free(led->gpio);
+}
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
 static int gpio_led_probe(struct platform_device *pdev)
 {
 	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
-	struct gpio_led *cur_led;
-	struct gpio_led_data *leds_data, *led_dat;
+	struct gpio_led_data *leds_data;
 	int i, ret = 0;
 
 	if (!pdata)
@@ -87,35 +144,10 @@ static int gpio_led_probe(struct platfor
 		return -ENOMEM;
 
 	for (i = 0; i < pdata->num_leds; i++) {
-		cur_led = &pdata->leds[i];
-		led_dat = &leds_data[i];
-
-		ret = gpio_request(cur_led->gpio, cur_led->name);
+		ret = create_gpio_led(&pdata->leds[i], &leds_data[i],
+				      &pdev->dev, pdata->gpio_blink_set);
 		if (ret < 0)
 			goto err;
-
-		led_dat->cdev.name = cur_led->name;
-		led_dat->cdev.default_trigger = cur_led->default_trigger;
-		led_dat->gpio = cur_led->gpio;
-		led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
-		led_dat->active_low = cur_led->active_low;
-		if (pdata->gpio_blink_set) {
-			led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
-			led_dat->cdev.blink_set = gpio_blink_set;
-		}
-		led_dat->cdev.brightness_set = gpio_led_set;
-		led_dat->cdev.brightness = LED_OFF;
-		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
-		gpio_direction_output(led_dat->gpio, led_dat->active_low);
-
-		INIT_WORK(&led_dat->work, gpio_led_work);
-
-		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
-		if (ret < 0) {
-			gpio_free(led_dat->gpio);
-			goto err;
-		}
 	}
 
 	platform_set_drvdata(pdev, leds_data);
@@ -123,13 +155,8 @@ static int gpio_led_probe(struct platfor
 	return 0;
 
 err:
-	if (i > 0) {
-		for (i = i - 1; i >= 0; i--) {
-			led_classdev_unregister(&leds_data[i].cdev);
-			cancel_work_sync(&leds_data[i].work);
-			gpio_free(leds_data[i].gpio);
-		}
-	}
+	for (i = i - 1; i >= 0; i--)
+		delete_gpio_led(&leds_data[i]);
 
 	kfree(leds_data);
 
@@ -144,11 +171,8 @@ static int __devexit gpio_led_remove(str
 
 	leds_data = platform_get_drvdata(pdev);
 
-	for (i = 0; i < pdata->num_leds; i++) {
-		led_classdev_unregister(&leds_data[i].cdev);
-		cancel_work_sync(&leds_data[i].work);
-		gpio_free(leds_data[i].gpio);
-	}
+	for (i = 0; i < pdata->num_leds; i++)
+		delete_gpio_led(&leds_data[i]);
 
 	kfree(leds_data);
 
@@ -164,20 +188,133 @@ static struct platform_driver gpio_led_d
 	},
 };
 
+MODULE_ALIAS("platform:leds-gpio");
+#endif /* CONFIG_LEDS_GPIO_PLATFORM */
+
+/* Code to create from OpenFirmware platform devices */
+#ifdef CONFIG_LEDS_GPIO_OF
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+struct gpio_led_of_platform_data {
+	int num_leds;
+	struct gpio_led_data led_data[];
+};
+
+static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
+					const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node, *child;
+	struct gpio_led led;
+	struct gpio_led_of_platform_data *pdata;
+	int count = 0, ret;
+
+	/* count LEDs defined by this device, so we know how much to allocate */
+	for_each_child_of_node(np, child)
+		count++;
+	if (!count)
+		return 0; /* or ENODEV? */
+
+	pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count,
+			GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	memset(&led, 0, sizeof(led));
+	for_each_child_of_node(np, child) {
+		enum of_gpio_flags flags;
+
+		led.gpio = of_get_gpio_flags(child, 0, &flags);
+		led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+		led.name = of_get_property(child, "label", NULL) ? : child->name;
+		led.default_trigger =
+			of_get_property(child, "linux,default-trigger", NULL);
+
+		ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++],
+				      &ofdev->dev, NULL);
+		if (ret < 0) {
+			of_node_put(child);
+			goto err;
+		}
+	}
+
+	dev_set_drvdata(&ofdev->dev, pdata);
+
+	return 0;
+
+err:
+	for (count = pdata->num_leds - 2; count >= 0; count--)
+		delete_gpio_led(&pdata->led_data[count]);
+
+	kfree(pdata);
+
+	return ret;
+}
+
+static int __devexit of_gpio_leds_remove(struct of_device *ofdev)
+{
+	struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev);
+	int i;
+
+	for (i = 0; i < pdata->num_leds; i++)
+		delete_gpio_led(&pdata->led_data[i]);
+
+	kfree(pdata);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id of_gpio_leds_match[] = {
+	{ .compatible = "gpio-leds", },
+	{},
+};
+
+static struct of_platform_driver of_gpio_leds_driver = {
+	.driver = {
+		.name = "of_gpio_leds",
+		.owner = THIS_MODULE,
+	},
+	.match_table = of_gpio_leds_match,
+	.probe = of_gpio_leds_probe,
+	.remove = __devexit_p(of_gpio_leds_remove),
+};
+#endif
+
 static int __init gpio_led_init(void)
 {
-	return platform_driver_register(&gpio_led_driver);
+	int ret;
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM	
+	ret = platform_driver_register(&gpio_led_driver);
+	if (ret)
+		return ret;
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+	ret = of_register_platform_driver(&of_gpio_leds_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_PLATFORM	
+	if (ret)
+		platform_driver_unregister(&gpio_led_driver);
+#endif
+
+	return ret;
 }
 
 static void __exit gpio_led_exit(void)
 {
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
 	platform_driver_unregister(&gpio_led_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+	of_unregister_platform_driver(&of_gpio_leds_driver);
+#endif
 }
 
 module_init(gpio_led_init);
 module_exit(gpio_led_exit);
 
-MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
 MODULE_DESCRIPTION("GPIO LED driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-gpio");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds.h linux-libre-2.6.30-gnu1/drivers/leds/leds.h
--- linux-libre-2.6.29-gnu1/drivers/leds/leds.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,8 +20,8 @@
 static inline void led_set_brightness(struct led_classdev *led_cdev,
 					enum led_brightness value)
 {
-	if (value > LED_FULL)
-		value = LED_FULL;
+	if (value > led_cdev->max_brightness)
+		value = led_cdev->max_brightness;
 	led_cdev->brightness = value;
 	if (!(led_cdev->flags & LED_SUSPENDED))
 		led_cdev->brightness_set(led_cdev, value);
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-h1940.c linux-libre-2.6.30-gnu1/drivers/leds/leds-h1940.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-h1940.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-h1940.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,7 +104,7 @@ static struct led_classdev h1940_blueled
 	.default_trigger	= "h1940-bluetooth",
 };
 
-static int __init h1940leds_probe(struct platform_device *pdev)
+static int __devinit h1940leds_probe(struct platform_device *pdev)
 {
 	int ret;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-pca9532.c linux-libre-2.6.30-gnu1/drivers/leds/leds-pca9532.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-pca9532.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-pca9532.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * pca9532.c - 16-bit Led dimmer
  *
- * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2008 Riku Voipio
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -169,7 +169,7 @@ static int pca9532_event(struct input_de
 {
 	struct pca9532_data *data = input_get_drvdata(dev);
 
-	if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
+	if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
 		return -1;
 
 	/* XXX: allow different kind of beeps with psc/pwm modifications */
@@ -367,7 +367,7 @@ static void __exit pca9532_exit(void)
 	i2c_del_driver(&pca9532_driver);
 }
 
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("PCA 9532 LED dimmer");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-pwm.c linux-libre-2.6.30-gnu1/drivers/leds/leds-pwm.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-pwm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-pwm.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,153 @@
+/*
+ * linux/drivers/leds-pwm.c
+ *
+ * simple PWM based LED control
+ *
+ * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
+ *
+ * based on leds-gpio.c by Raphael Assenat <raph@8d.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+
+struct led_pwm_data {
+	struct led_classdev	cdev;
+	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,
+	enum led_brightness brightness)
+{
+	struct led_pwm_data *led_dat =
+		container_of(led_cdev, struct led_pwm_data, cdev);
+	unsigned int max = led_dat->max_brightness;
+	unsigned int period =  led_dat->period;
+
+	if (brightness == 0) {
+		pwm_config(led_dat->pwm, 0, period);
+		pwm_disable(led_dat->pwm);
+	} else {
+		pwm_config(led_dat->pwm, brightness * period / max, period);
+		pwm_enable(led_dat->pwm);
+	}
+}
+
+static int led_pwm_probe(struct platform_device *pdev)
+{
+	struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+	struct led_pwm *cur_led;
+	struct led_pwm_data *leds_data, *led_dat;
+	int i, ret = 0;
+
+	if (!pdata)
+		return -EBUSY;
+
+	leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
+				GFP_KERNEL);
+	if (!leds_data)
+		return -ENOMEM;
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		cur_led = &pdata->leds[i];
+		led_dat = &leds_data[i];
+
+		led_dat->pwm = pwm_request(cur_led->pwm_id,
+				cur_led->name);
+		if (IS_ERR(led_dat->pwm)) {
+			dev_err(&pdev->dev, "unable to request PWM %d\n",
+					cur_led->pwm_id);
+			goto err;
+		}
+
+		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.flags |= LED_CORE_SUSPENDRESUME;
+
+		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+		if (ret < 0) {
+			pwm_free(led_dat->pwm);
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, leds_data);
+
+	return 0;
+
+err:
+	if (i > 0) {
+		for (i = i - 1; i >= 0; i--) {
+			led_classdev_unregister(&leds_data[i].cdev);
+			pwm_free(leds_data[i].pwm);
+		}
+	}
+
+	kfree(leds_data);
+
+	return ret;
+}
+
+static int __devexit led_pwm_remove(struct platform_device *pdev)
+{
+	int i;
+	struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+	struct led_pwm_data *leds_data;
+
+	leds_data = platform_get_drvdata(pdev);
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		led_classdev_unregister(&leds_data[i].cdev);
+		pwm_free(leds_data[i].pwm);
+	}
+
+	kfree(leds_data);
+
+	return 0;
+}
+
+static struct platform_driver led_pwm_driver = {
+	.probe		= led_pwm_probe,
+	.remove		= __devexit_p(led_pwm_remove),
+	.driver		= {
+		.name	= "leds_pwm",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init led_pwm_init(void)
+{
+	return platform_driver_register(&led_pwm_driver);
+}
+
+static void __exit led_pwm_exit(void)
+{
+	platform_driver_unregister(&led_pwm_driver);
+}
+
+module_init(led_pwm_init);
+module_exit(led_pwm_exit);
+
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_DESCRIPTION("PWM LED driver for PXA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pwm");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-rb532.c linux-libre-2.6.30-gnu1/drivers/leds/leds-rb532.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-rb532.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-rb532.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,77 @@
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+                          enum led_brightness brightness)
+{
+	if (brightness)
+		set_latch_u5(LO_ULED, 0);
+
+	else
+		set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+	return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+	.name = "uled",
+	.brightness_set = rb532_led_set,
+	.brightness_get = rb532_led_get,
+	.default_trigger = "nand-disk",
+};
+
+static int __devinit rb532_led_probe(struct platform_device *pdev)
+{
+	return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int __devexit rb532_led_remove(struct platform_device *pdev)
+{
+	led_classdev_unregister(&rb532_uled);
+	return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+	.probe = rb532_led_probe,
+	.remove = __devexit_p(rb532_led_remove),
+	.driver = {
+		.name = "rb532-led",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init rb532_led_init(void)
+{
+	return platform_driver_register(&rb532_led_driver);
+}
+
+static void __exit rb532_led_exit(void)
+{
+	platform_driver_unregister(&rb532_led_driver);
+}
+
+module_init(rb532_led_init);
+module_exit(rb532_led_exit);
+
+MODULE_ALIAS("platform:rb532-led");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/leds-s3c24xx.c linux-libre-2.6.30-gnu1/drivers/leds/leds-s3c24xx.c
--- linux-libre-2.6.29-gnu1/drivers/leds/leds-s3c24xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/leds-s3c24xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,14 +102,11 @@ static int s3c24xx_led_probe(struct plat
 	ret = led_classdev_register(&dev->dev, &led->cdev);
 	if (ret < 0) {
 		dev_err(&dev->dev, "led_classdev_register failed\n");
-		goto exit_err1;
+		kfree(led);
+		return ret;
 	}
 
 	return 0;
-
- exit_err1:
-	kfree(led);
-	return ret;
 }
 
 static struct platform_driver s3c24xx_led_driver = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-default-on.c linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-default-on.c
--- linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-default-on.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-default-on.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,7 @@
 
 static void defon_trig_activate(struct led_classdev *led_cdev)
 {
-	led_set_brightness(led_cdev, LED_FULL);
+	led_set_brightness(led_cdev, led_cdev->max_brightness);
 }
 
 static struct led_trigger defon_led_trigger = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/led-triggers.c linux-libre-2.6.30-gnu1/drivers/leds/led-triggers.c
--- linux-libre-2.6.29-gnu1/drivers/leds/led-triggers.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/led-triggers.c	2009-06-09 23:05:27.000000000 -0400
@@ -156,12 +156,20 @@ EXPORT_SYMBOL_GPL(led_trigger_set_defaul
 int led_trigger_register(struct led_trigger *trigger)
 {
 	struct led_classdev *led_cdev;
+	struct led_trigger *trig;
 
 	rwlock_init(&trigger->leddev_list_lock);
 	INIT_LIST_HEAD(&trigger->led_cdevs);
 
-	/* Add to the list of led triggers */
 	down_write(&triggers_list_lock);
+	/* Make sure the trigger's name isn't already in use */
+	list_for_each_entry(trig, &trigger_list, next_trig) {
+		if (!strcmp(trig->name, trigger->name)) {
+			up_write(&triggers_list_lock);
+			return -EEXIST;
+		}
+	}
+	/* Add to the list of led triggers */
 	list_add_tail(&trigger->next_trig, &trigger_list);
 	up_write(&triggers_list_lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-gpio.c linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-gpio.c
--- linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,239 @@
+/*
+ * ledtrig-gio.c - LED Trigger Based on GPIO events
+ *
+ * Copyright 2009 Felipe Balbi <me@felipebalbi.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/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct gpio_trig_data {
+	struct led_classdev *led;
+	struct work_struct work;
+
+	unsigned desired_brightness;	/* desired brightness when led is on */
+	unsigned inverted;		/* true when gpio is inverted */
+	unsigned gpio;			/* gpio that triggers the leds */
+};
+
+static irqreturn_t gpio_trig_irq(int irq, void *_led)
+{
+	struct led_classdev *led = _led;
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	/* just schedule_work since gpio_get_value can sleep */
+	schedule_work(&gpio_data->work);
+
+	return IRQ_HANDLED;
+};
+
+static void gpio_trig_work(struct work_struct *work)
+{
+	struct gpio_trig_data *gpio_data = container_of(work,
+			struct gpio_trig_data, work);
+	int tmp;
+
+       if (!gpio_data->gpio)
+	       return;
+
+       tmp = gpio_get_value(gpio_data->gpio);
+       if (gpio_data->inverted)
+	       tmp = !tmp;
+
+       if (tmp) {
+               if (gpio_data->desired_brightness)
+                       led_set_brightness(gpio_data->led,
+                                       gpio_data->desired_brightness);
+               else
+                       led_set_brightness(gpio_data->led, LED_FULL);
+       } else {
+               led_set_brightness(gpio_data->led, LED_OFF);
+       }
+}
+
+static ssize_t gpio_trig_brightness_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%u\n", gpio_data->desired_brightness);
+}
+
+static ssize_t gpio_trig_brightness_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned desired_brightness;
+	int ret;
+
+	ret = sscanf(buf, "%u", &desired_brightness);
+	if (ret < 1 || desired_brightness > 255) {
+		dev_err(dev, "invalid value\n");
+		return -EINVAL;
+	}
+
+	gpio_data->desired_brightness = desired_brightness;
+
+	return n;
+}
+static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
+		gpio_trig_brightness_store);
+
+static ssize_t gpio_trig_inverted_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no");
+}
+
+static ssize_t gpio_trig_inverted_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned inverted;
+	int ret;
+
+	ret = sscanf(buf, "%u", &inverted);
+	if (ret < 1) {
+		dev_err(dev, "invalid value\n");
+		return -EINVAL;
+	}
+
+	gpio_data->inverted = !!inverted;
+
+	return n;
+}
+static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
+		gpio_trig_inverted_store);
+
+static ssize_t gpio_trig_gpio_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%u\n", gpio_data->gpio);
+}
+
+static ssize_t gpio_trig_gpio_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned gpio;
+	int ret;
+
+	ret = sscanf(buf, "%u", &gpio);
+	if (ret < 1) {
+		dev_err(dev, "couldn't read gpio number\n");
+		flush_work(&gpio_data->work);
+		return -EINVAL;
+	}
+
+	if (!gpio) {
+		free_irq(gpio_to_irq(gpio_data->gpio), led);
+		return n;
+	}
+
+	if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
+		free_irq(gpio_to_irq(gpio_data->gpio), led);
+
+	gpio_data->gpio = gpio;
+	ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
+			IRQF_SHARED | IRQF_TRIGGER_RISING
+			| IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
+	if (ret)
+		dev_err(dev, "request_irq failed with error %d\n", ret);
+
+	return ret ? ret : n;
+}
+static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);
+
+static void gpio_trig_activate(struct led_classdev *led)
+{
+	struct gpio_trig_data *gpio_data;
+	int ret;
+
+	gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+	if (!gpio_data)
+		return;
+
+	ret = device_create_file(led->dev, &dev_attr_gpio);
+	if (ret)
+		goto err_gpio;
+
+	ret = device_create_file(led->dev, &dev_attr_inverted);
+	if (ret)
+		goto err_inverted;
+
+	ret = device_create_file(led->dev, &dev_attr_desired_brightness);
+	if (ret)
+		goto err_brightness;
+
+	gpio_data->led = led;
+	led->trigger_data = gpio_data;
+	INIT_WORK(&gpio_data->work, gpio_trig_work);
+
+	return;
+
+err_brightness:
+	device_remove_file(led->dev, &dev_attr_inverted);
+
+err_inverted:
+	device_remove_file(led->dev, &dev_attr_gpio);
+
+err_gpio:
+	kfree(gpio_data);
+}
+
+static void gpio_trig_deactivate(struct led_classdev *led)
+{
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	if (gpio_data) {
+		device_remove_file(led->dev, &dev_attr_gpio);
+		device_remove_file(led->dev, &dev_attr_inverted);
+		device_remove_file(led->dev, &dev_attr_desired_brightness);
+		flush_work(&gpio_data->work);
+		free_irq(gpio_to_irq(gpio_data->gpio),led);
+		kfree(gpio_data);
+	}
+}
+
+static struct led_trigger gpio_led_trigger = {
+	.name		= "gpio",
+	.activate	= gpio_trig_activate,
+	.deactivate	= gpio_trig_deactivate,
+};
+
+static int __init gpio_trig_init(void)
+{
+	return led_trigger_register(&gpio_led_trigger);
+}
+module_init(gpio_trig_init);
+
+static void __exit gpio_trig_exit(void)
+{
+	led_trigger_unregister(&gpio_led_trigger);
+}
+module_exit(gpio_trig_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_DESCRIPTION("GPIO LED trigger");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-heartbeat.c linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-heartbeat.c
--- linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-heartbeat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-heartbeat.c	2009-06-09 23:05:27.000000000 -0400
@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsig
 			msecs_to_jiffies(heartbeat_data->period);
 		delay = msecs_to_jiffies(70);
 		heartbeat_data->phase++;
-		brightness = LED_FULL;
+		brightness = led_cdev->max_brightness;
 		break;
 	case 1:
 		delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsig
 	case 2:
 		delay = msecs_to_jiffies(70);
 		heartbeat_data->phase++;
-		brightness = LED_FULL;
+		brightness = led_cdev->max_brightness;
 		break;
 	default:
 		delay = heartbeat_data->period - heartbeat_data->period / 4 -
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-ide-disk.c linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-ide-disk.c
--- linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-ide-disk.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-ide-disk.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsign
 {
 	if (ide_lastactivity != ide_activity) {
 		ide_lastactivity = ide_activity;
-		led_trigger_event(ledtrig_ide, LED_FULL);
+		/* INT_MAX will set each LED to its maximum brightness */
+		led_trigger_event(ledtrig_ide, INT_MAX);
 		mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
 	} else {
 		led_trigger_event(ledtrig_ide, LED_OFF);
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-timer.c linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-timer.c
--- linux-libre-2.6.29-gnu1/drivers/leds/ledtrig-timer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/ledtrig-timer.c	2009-06-09 23:05:27.000000000 -0400
@@ -166,7 +166,7 @@ static void timer_trig_activate(struct l
 
 	timer_data->brightness_on = led_get_brightness(led_cdev);
 	if (timer_data->brightness_on == LED_OFF)
-		timer_data->brightness_on = LED_FULL;
+		timer_data->brightness_on = led_cdev->max_brightness;
 	led_cdev->trigger_data = timer_data;
 
 	init_timer(&timer_data->timer);
diff -druNp linux-libre-2.6.29-gnu1/drivers/leds/Makefile linux-libre-2.6.30-gnu1/drivers/leds/Makefile
--- linux-libre-2.6.29-gnu1/drivers/leds/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/leds/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,9 @@ obj-$(CONFIG_LEDS_TRIGGERS)		+= led-trig
 
 # LED Platform Drivers
 obj-$(CONFIG_LEDS_ATMEL_PWM)		+= leds-atmel-pwm.o
+obj-$(CONFIG_LEDS_BD2802)		+= leds-bd2802.o
 obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
+obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_AMS_DELTA)		+= leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
@@ -24,10 +26,15 @@ obj-$(CONFIG_LEDS_FSG)			+= leds-fsg.o
 obj-$(CONFIG_LEDS_PCA955X)		+= leds-pca955x.o
 obj-$(CONFIG_LEDS_DA903X)		+= leds-da903x.o
 obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
+obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
+
+# LED SPI Drivers
+obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
 obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)	+= ledtrig-ide-disk.o
 obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+= ledtrig-heartbeat.o
 obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o
+obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o
 obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/core.c linux-libre-2.6.30-gnu1/drivers/lguest/core.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,8 +152,8 @@ static void unmap_switcher(void)
  * code.  We have to check that the range is below the pfn_limit the Launcher
  * gave us.  We have to make sure that addr + len doesn't give us a false
  * positive by overflowing, too. */
-int lguest_address_ok(const struct lguest *lg,
-		      unsigned long addr, unsigned long len)
+bool lguest_address_ok(const struct lguest *lg,
+		       unsigned long addr, unsigned long len)
 {
 	return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/interrupts_and_traps.c linux-libre-2.6.30-gnu1/drivers/lguest/interrupts_and_traps.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/interrupts_and_traps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/interrupts_and_traps.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@ static int idt_type(u32 lo, u32 hi)
 }
 
 /* An IDT entry can't be used unless the "present" bit is set. */
-static int idt_present(u32 lo, u32 hi)
+static bool idt_present(u32 lo, u32 hi)
 {
 	return (hi & 0x8000);
 }
@@ -60,7 +60,8 @@ static void push_guest_stack(struct lg_c
  * We set up the stack just like the CPU does for a real interrupt, so it's
  * identical for the Guest (and the standard "iret" instruction will undo
  * it). */
-static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi,
+				bool has_err)
 {
 	unsigned long gstack, origstack;
 	u32 eflags, ss, irq_enable;
@@ -184,7 +185,7 @@ void maybe_do_interrupt(struct lg_cpu *c
 		/* set_guest_interrupt() takes the interrupt descriptor and a
 		 * flag to say whether this interrupt pushes an error code onto
 		 * the stack as well: virtual interrupts never do. */
-		set_guest_interrupt(cpu, idt->a, idt->b, 0);
+		set_guest_interrupt(cpu, idt->a, idt->b, false);
 	}
 
 	/* Every time we deliver an interrupt, we update the timestamp in the
@@ -244,26 +245,26 @@ void free_interrupts(void)
 /*H:220 Now we've got the routines to deliver interrupts, delivering traps like
  * page fault is easy.  The only trick is that Intel decided that some traps
  * should have error codes: */
-static int has_err(unsigned int trap)
+static bool has_err(unsigned int trap)
 {
 	return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
 }
 
 /* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lg_cpu *cpu, unsigned int num)
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
 {
 	/* Trap numbers are always 8 bit, but we set an impossible trap number
 	 * for traps inside the Switcher, so check that here. */
 	if (num >= ARRAY_SIZE(cpu->arch.idt))
-		return 0;
+		return false;
 
 	/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 	 * bogus one in): if we fail here, the Guest will be killed. */
 	if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b))
-		return 0;
+		return false;
 	set_guest_interrupt(cpu, cpu->arch.idt[num].a,
 			    cpu->arch.idt[num].b, has_err(num));
-	return 1;
+	return true;
 }
 
 /*H:250 Here's the hard part: returning to the Host every time a trap happens
@@ -279,18 +280,19 @@ int deliver_trap(struct lg_cpu *cpu, uns
  *
  * This routine indicates if a particular trap number could be delivered
  * directly. */
-static int direct_trap(unsigned int num)
+static bool direct_trap(unsigned int num)
 {
 	/* Hardware interrupts don't go to the Guest at all (except system
 	 * call). */
 	if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
-		return 0;
+		return false;
 
 	/* The Host needs to see page faults (for shadow paging and to save the
 	 * fault address), general protection faults (in/out emulation) and
-	 * device not available (TS handling), and of course, the hypercall
-	 * trap. */
-	return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
+	 * device not available (TS handling), invalid opcode fault (kvm hcall),
+	 * and of course, the hypercall trap. */
+	return num != 14 && num != 13 && num != 7 &&
+			num != 6 && num != LGUEST_TRAP_ENTRY;
 }
 /*:*/
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/Kconfig linux-libre-2.6.30-gnu1/drivers/lguest/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/lguest/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config LGUEST
 	tristate "Linux hypervisor example code"
-	depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !X86_VOYAGER
+	depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX
 	select HVC_DRIVER
 	---help---
 	  This is a very simple module which allows you to run
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/lg.h linux-libre-2.6.30-gnu1/drivers/lguest/lg.h
--- linux-libre-2.6.29-gnu1/drivers/lguest/lg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/lg.h	2009-06-09 23:05:27.000000000 -0400
@@ -109,8 +109,8 @@ struct lguest
 extern struct mutex lguest_lock;
 
 /* core.c: */
-int lguest_address_ok(const struct lguest *lg,
-		      unsigned long addr, unsigned long len);
+bool lguest_address_ok(const struct lguest *lg,
+		       unsigned long addr, unsigned long len);
 void __lgread(struct lg_cpu *, void *, unsigned long, unsigned);
 void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned);
 
@@ -140,7 +140,7 @@ int run_guest(struct lg_cpu *cpu, unsign
 
 /* interrupts_and_traps.c: */
 void maybe_do_interrupt(struct lg_cpu *cpu);
-int deliver_trap(struct lg_cpu *cpu, unsigned int num);
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num);
 void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
 			  u32 low, u32 hi);
 void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages);
@@ -158,7 +158,8 @@ void free_interrupts(void);
 /* segments.c: */
 void setup_default_gdt_entries(struct lguest_ro_state *state);
 void setup_guest_gdt(struct lg_cpu *cpu);
-void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num);
+void load_guest_gdt_entry(struct lg_cpu *cpu, unsigned int i,
+			  u32 low, u32 hi);
 void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array);
 void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt);
 void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt);
@@ -173,7 +174,7 @@ void guest_pagetable_flush_user(struct l
 void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir,
 		   unsigned long vaddr, pte_t val);
 void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages);
-int demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
+bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
 void pin_page(struct lg_cpu *cpu, unsigned long vaddr);
 unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr);
 void page_table_guest_data_init(struct lg_cpu *cpu);
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/lguest_device.c linux-libre-2.6.30-gnu1/drivers/lguest/lguest_device.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/lguest_device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/lguest_device.c	2009-06-09 23:05:27.000000000 -0400
@@ -161,7 +161,7 @@ static void set_status(struct virtio_dev
 
 	/* We set the status. */
 	to_lgdev(vdev)->desc->status = status;
-	hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
+	kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
 }
 
 static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -209,7 +209,7 @@ static void lg_notify(struct virtqueue *
 	 * virtqueue structure. */
 	struct lguest_vq_info *lvq = vq->priv;
 
-	hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
+	kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
 }
 
 /* An extern declaration inside a C file is bad form.  Don't do it. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/page_tables.c linux-libre-2.6.30-gnu1/drivers/lguest/page_tables.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/page_tables.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/page_tables.c	2009-06-09 23:05:27.000000000 -0400
@@ -199,7 +199,7 @@ static void check_gpgd(struct lg_cpu *cp
  *
  * If we fixed up the fault (ie. we mapped the address), this routine returns
  * true.  Otherwise, it was a real fault and we need to tell the Guest. */
-int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
+bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
 {
 	pgd_t gpgd;
 	pgd_t *spgd;
@@ -211,7 +211,7 @@ int demand_page(struct lg_cpu *cpu, unsi
 	gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
 	/* Toplevel not present?  We can't map it in. */
 	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
-		return 0;
+		return false;
 
 	/* Now look at the matching shadow entry. */
 	spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
@@ -222,7 +222,7 @@ int demand_page(struct lg_cpu *cpu, unsi
 		 * simple for this corner case. */
 		if (!ptepage) {
 			kill_guest(cpu, "out of memory allocating pte page");
-			return 0;
+			return false;
 		}
 		/* We check that the Guest pgd is OK. */
 		check_gpgd(cpu, gpgd);
@@ -238,16 +238,16 @@ int demand_page(struct lg_cpu *cpu, unsi
 
 	/* If this page isn't in the Guest page tables, we can't page it in. */
 	if (!(pte_flags(gpte) & _PAGE_PRESENT))
-		return 0;
+		return false;
 
 	/* Check they're not trying to write to a page the Guest wants
 	 * read-only (bit 2 of errcode == write). */
 	if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
-		return 0;
+		return false;
 
 	/* User access to a kernel-only page? (bit 3 == user access) */
 	if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
-		return 0;
+		return false;
 
 	/* Check that the Guest PTE flags are OK, and the page number is below
 	 * the pfn_limit (ie. not mapping the Launcher binary). */
@@ -283,7 +283,7 @@ int demand_page(struct lg_cpu *cpu, unsi
 	 * manipulated, the result returned and the code complete.  A small
 	 * delay and a trace of alliteration are the only indications the Guest
 	 * has that a page fault occurred at all. */
-	return 1;
+	return true;
 }
 
 /*H:360
@@ -296,7 +296,7 @@ int demand_page(struct lg_cpu *cpu, unsi
  *
  * This is a quick version which answers the question: is this virtual address
  * mapped by the shadow page tables, and is it writable? */
-static int page_writable(struct lg_cpu *cpu, unsigned long vaddr)
+static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr)
 {
 	pgd_t *spgd;
 	unsigned long flags;
@@ -304,7 +304,7 @@ static int page_writable(struct lg_cpu *
 	/* Look at the current top level entry: is it present? */
 	spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
 	if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
-		return 0;
+		return false;
 
 	/* Check the flags on the pte entry itself: it must be present and
 	 * writable. */
@@ -373,8 +373,10 @@ unsigned long guest_pa(struct lg_cpu *cp
 	/* First step: get the top-level Guest page table entry. */
 	gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
 	/* Toplevel not present?  We can't map it in. */
-	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+	if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) {
 		kill_guest(cpu, "Bad address %#lx", vaddr);
+		return -1UL;
+	}
 
 	gpte = lgread(cpu, gpte_addr(gpgd, vaddr), pte_t);
 	if (!(pte_flags(gpte) & _PAGE_PRESENT))
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/segments.c linux-libre-2.6.30-gnu1/drivers/lguest/segments.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/segments.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/segments.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,7 @@
  * "Task State Segment" which controls all kinds of delicate things.  The
  * LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
  * the Guest can't be trusted to deal with double faults. */
-static int ignored_gdt(unsigned int num)
+static bool ignored_gdt(unsigned int num)
 {
 	return (num == GDT_ENTRY_TSS
 		|| num == GDT_ENTRY_LGUEST_CS
@@ -144,18 +144,19 @@ void copy_gdt(const struct lg_cpu *cpu,
 			gdt[i] = cpu->arch.gdt[i];
 }
 
-/*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT).
- * We copy it from the Guest and tweak the entries. */
-void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num)
+/*H:620 This is where the Guest asks us to load a new GDT entry
+ * (LHCALL_LOAD_GDT_ENTRY).  We tweak the entry and copy it in. */
+void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi)
 {
 	/* 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))
 		kill_guest(cpu, "too many gdt entries %i", num);
 
-	/* We read the whole thing in, then fix it up. */
-	__lgread(cpu, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0]));
-	fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt));
+	/* Set it up, then fix it. */
+	cpu->arch.gdt[num].a = lo;
+	cpu->arch.gdt[num].b = hi;
+	fixup_gdt_table(cpu, num, num+1);
 	/* Mark that the GDT changed so the core knows it has to copy it again,
 	 * even if the Guest is run on the same CPU. */
 	cpu->changed |= CHANGED_GDT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/lguest/x86/core.c linux-libre-2.6.30-gnu1/drivers/lguest/x86/core.c
--- linux-libre-2.6.29-gnu1/drivers/lguest/x86/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/lguest/x86/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -290,6 +290,62 @@ static int emulate_insn(struct lg_cpu *c
 	return 1;
 }
 
+/* Our hypercalls mechanism used to be based on direct software interrupts.
+ * After Anthony's "Refactor hypercall infrastructure" kvm patch, we decided to
+ * change over to using kvm hypercalls.
+ *
+ * KVM_HYPERCALL is actually a "vmcall" instruction, which generates an invalid
+ * opcode fault (fault 6) on non-VT cpus, so the easiest solution seemed to be
+ * an *emulation approach*: if the fault was really produced by an hypercall
+ * (is_hypercall() does exactly this check), we can just call the corresponding
+ * hypercall host implementation function.
+ *
+ * But these invalid opcode faults are notably slower than software interrupts.
+ * So we implemented the *patching (or rewriting) approach*: every time we hit
+ * the KVM_HYPERCALL opcode in Guest code, we patch it to the old "int 0x1f"
+ * opcode, so next time the Guest calls this hypercall it will use the
+ * faster trap mechanism.
+ *
+ * Matias even benchmarked it to convince you: this shows the average cycle
+ * cost of a hypercall.  For each alternative solution mentioned above we've
+ * made 5 runs of the benchmark:
+ *
+ * 1) direct software interrupt: 2915, 2789, 2764, 2721, 2898
+ * 2) emulation technique: 3410, 3681, 3466, 3392, 3780
+ * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884
+ *
+ * One two-line function is worth a 20% hypercall speed boost!
+ */
+static void rewrite_hypercall(struct lg_cpu *cpu)
+{
+	/* This are the opcodes we use to patch the Guest.  The opcode for "int
+	 * $0x1f" is "0xcd 0x1f" but vmcall instruction is 3 bytes long, so we
+	 * complete the sequence with a NOP (0x90). */
+	u8 insn[3] = {0xcd, 0x1f, 0x90};
+
+	__lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
+	/* The above write might have caused a copy of that page to be made
+	 * (if it was read-only).  We need to make sure the Guest has
+	 * up-to-date pagetables.  As this doesn't happen often, we can just
+	 * drop them all. */
+	guest_pagetable_clear_all(cpu);
+}
+
+static bool is_hypercall(struct lg_cpu *cpu)
+{
+	u8 insn[3];
+
+	/* This must be the Guest kernel trying to do something.
+	 * The bottom two bits of the CS segment register are the privilege
+	 * level. */
+	if ((cpu->regs->cs & 3) != GUEST_PL)
+		return false;
+
+	/* Is it a vmcall? */
+	__lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn));
+	return insn[0] == 0x0f && insn[1] == 0x01 && insn[2] == 0xc1;
+}
+
 /*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
 void lguest_arch_handle_trap(struct lg_cpu *cpu)
 {
@@ -302,6 +358,16 @@ void lguest_arch_handle_trap(struct lg_c
 			if (emulate_insn(cpu))
 				return;
 		}
+		/* If KVM is active, the vmcall instruction triggers a
+		 * General Protection Fault.  Normally it triggers an
+		 * invalid opcode fault (6): */
+	case 6:
+		/* We need to check if ring == GUEST_PL and
+		 * faulting instruction == vmcall. */
+		if (is_hypercall(cpu)) {
+			rewrite_hypercall(cpu);
+			return;
+		}
 		break;
 	case 14: /* We've intercepted a Page Fault. */
 		/* The Guest accessed a virtual address that wasn't mapped.
@@ -337,7 +403,7 @@ void lguest_arch_handle_trap(struct lg_c
 		break;
 	case 32 ... 255:
 		/* These values mean a real interrupt occurred, in which case
-		 * the Host handler has already been run.  We just do a
+		 * the Host handler has already been run. We just do a
 		 * friendly check if another process should now be run, then
 		 * return to run the Guest again */
 		cond_resched();
@@ -503,8 +569,8 @@ void __exit lguest_arch_host_fini(void)
 int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
 {
 	switch (args->arg0) {
-	case LHCALL_LOAD_GDT:
-		load_guest_gdt(cpu, args->arg1, args->arg2);
+	case LHCALL_LOAD_GDT_ENTRY:
+		load_guest_gdt_entry(cpu, args->arg1, args->arg2, args->arg3);
 		break;
 	case LHCALL_LOAD_IDT_ENTRY:
 		load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3);
diff -druNp linux-libre-2.6.29-gnu1/drivers/macintosh/Kconfig linux-libre-2.6.30-gnu1/drivers/macintosh/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/macintosh/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/macintosh/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -123,7 +123,7 @@ config PMAC_APM_EMU
 
 config PMAC_MEDIABAY
 	bool "Support PowerBook hotswap media bay"
-	depends on PPC_PMAC && PPC32
+	depends on PPC_PMAC && PPC32 && BLOCK
 	help
 	  This option adds support for older PowerBook's hotswap media bay
 	  that can contains batteries, floppy drives, or IDE devices. PCI
diff -druNp linux-libre-2.6.29-gnu1/drivers/macintosh/mediabay.c linux-libre-2.6.30-gnu1/drivers/macintosh/mediabay.c
--- linux-libre-2.6.29-gnu1/drivers/macintosh/mediabay.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/macintosh/mediabay.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/timer.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
-#include <linux/ide.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <asm/prom.h>
@@ -447,6 +446,7 @@ int check_media_bay_by_base(unsigned lon
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(check_media_bay_by_base);
 
 int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base,
 			    int irq, ide_hwif_t *hwif)
@@ -486,6 +486,7 @@ int media_bay_set_ide_infos(struct devic
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
 #endif /* CONFIG_BLK_DEV_IDE_PMAC */
 
 static void media_bay_step(int i)
diff -druNp linux-libre-2.6.29-gnu1/drivers/macintosh/therm_adt746x.c linux-libre-2.6.30-gnu1/drivers/macintosh/therm_adt746x.c
--- linux-libre-2.6.29-gnu1/drivers/macintosh/therm_adt746x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/macintosh/therm_adt746x.c	2009-06-09 23:05:27.000000000 -0400
@@ -498,8 +498,8 @@ static ssize_t store_##name(struct devic
 #define BUILD_STORE_FUNC_INT(name, data)			\
 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
 {								\
-	u32 val;						\
-	val = simple_strtoul(buf, NULL, 10);			\
+	int val;						\
+	val = simple_strtol(buf, NULL, 10);			\
 	if (val < 0 || val > 255)				\
 		return -EINVAL;					\
 	printk(KERN_INFO "Setting specified fan speed to %d\n", val);	\
diff -druNp linux-libre-2.6.29-gnu1/drivers/Makefile linux-libre-2.6.30-gnu1/drivers/Makefile
--- linux-libre-2.6.29-gnu1/drivers/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -36,13 +36,14 @@ obj-$(CONFIG_FB_INTEL)          += video
 
 obj-y				+= serial/
 obj-$(CONFIG_PARPORT)		+= parport/
-obj-y				+= base/ block/ misc/ mfd/ net/ media/
+obj-y				+= base/ block/ misc/ mfd/
 obj-$(CONFIG_NUBUS)		+= nubus/
-obj-$(CONFIG_ATM)		+= atm/
 obj-y				+= macintosh/
 obj-$(CONFIG_IDE)		+= ide/
 obj-$(CONFIG_SCSI)		+= scsi/
 obj-$(CONFIG_ATA)		+= ata/
+obj-y				+= net/
+obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_FUSION)		+= message/
 obj-$(CONFIG_FIREWIRE)		+= firewire/
 obj-y				+= ieee1394/
@@ -70,7 +71,7 @@ obj-$(CONFIG_GAMEPORT)		+= input/gamepor
 obj-$(CONFIG_INPUT)		+= input/
 obj-$(CONFIG_I2O)		+= message/
 obj-$(CONFIG_RTC_LIB)		+= rtc/
-obj-y				+= i2c/
+obj-y				+= i2c/ media/
 obj-$(CONFIG_W1)		+= w1/
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
diff -druNp linux-libre-2.6.29-gnu1/drivers/mca/mca-bus.c linux-libre-2.6.30-gnu1/drivers/mca/mca-bus.c
--- linux-libre-2.6.29-gnu1/drivers/mca/mca-bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mca/mca-bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus,
 
 	mca_dev->dev.parent = &mca_bus->dev;
 	mca_dev->dev.bus = &mca_bus_type;
-	sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+	dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
 	mca_dev->dma_mask = mca_bus->default_dma_mask;
 	mca_dev->dev.dma_mask = &mca_dev->dma_mask;
 	mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bu
 	if (!mca_bus)
 		return NULL;
 
-	sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+	dev_set_name(&mca_bus->dev, "mca%d", bus);
 	sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
 	if (device_register(&mca_bus->dev)) {
 		kfree(mca_bus);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/bitmap.c linux-libre-2.6.30-gnu1/drivers/md/bitmap.c
--- linux-libre-2.6.29-gnu1/drivers/md/bitmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/bitmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
  * wait if count gets too high, wake when it drops to half.
  */
 
+#include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -26,8 +27,8 @@
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/buffer_head.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include "md.h"
+#include "bitmap.h"
 
 /* debug macros */
 
@@ -111,9 +112,10 @@ static int bitmap_checkpage(struct bitma
 	unsigned char *mappage;
 
 	if (page >= bitmap->pages) {
-		printk(KERN_ALERT
-			"%s: invalid bitmap page request: %lu (> %lu)\n",
-			bmname(bitmap), page, bitmap->pages-1);
+		/* This can happen if bitmap_start_sync goes beyond
+		 * End-of-device while looking for a whole page.
+		 * It is harmless.
+		 */
 		return -EINVAL;
 	}
 
@@ -265,7 +267,6 @@ static mdk_rdev_t *next_active_rdev(mdk_
 	list_for_each_continue_rcu(pos, &mddev->disks) {
 		rdev = list_entry(pos, mdk_rdev_t, same_set);
 		if (rdev->raid_disk >= 0 &&
-		    test_bit(In_sync, &rdev->flags) &&
 		    !test_bit(Faulty, &rdev->flags)) {
 			/* this is a usable devices */
 			atomic_inc(&rdev->nr_pending);
@@ -297,7 +298,7 @@ static int write_sb_page(struct bitmap *
 				    + size/512 > 0)
 					/* bitmap runs in to metadata */
 					goto bad_alignment;
-				if (rdev->data_offset + mddev->size*2
+				if (rdev->data_offset + mddev->dev_sectors
 				    > rdev->sb_start + bitmap->offset)
 					/* data runs in to bitmap */
 					goto bad_alignment;
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap
 	else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
 		 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
 		reason = "unrecognized superblock version";
-	else if (chunksize < PAGE_SIZE)
+	else if (chunksize < 512)
 		reason = "bitmap chunksize too small";
 	else if ((1 << ffz(~chunksize)) != chunksize)
 		reason = "bitmap chunksize not a power of 2";
@@ -985,6 +986,9 @@ static int bitmap_init_from_disk(struct
 			oldindex = index;
 			oldpage = page;
 
+			bitmap->filemap[bitmap->file_pages++] = page;
+			bitmap->last_page_size = count;
+
 			if (outofdate) {
 				/*
 				 * if bitmap is out of date, dirty the
@@ -997,15 +1001,9 @@ static int bitmap_init_from_disk(struct
 				write_page(bitmap, page, 1);
 
 				ret = -EIO;
-				if (bitmap->flags & BITMAP_WRITE_ERROR) {
-					/* release, page not in filemap yet */
-					put_page(page);
+				if (bitmap->flags & BITMAP_WRITE_ERROR)
 					goto err;
-				}
 			}
-
-			bitmap->filemap[bitmap->file_pages++] = page;
-			bitmap->last_page_size = count;
 		}
 		paddr = kmap_atomic(page, KM_USER0);
 		if (bitmap->flags & BITMAP_HOSTENDIAN)
@@ -1015,9 +1013,11 @@ static int bitmap_init_from_disk(struct
 		kunmap_atomic(paddr, KM_USER0);
 		if (b) {
 			/* if the disk bit is set, set the memory bit */
-			bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
-					       ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
-				);
+			int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap))
+				      >= start);
+			bitmap_set_memory_bits(bitmap,
+					       (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap),
+					       needed);
 			bit_cnt++;
 			set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
 		}
@@ -1097,14 +1097,12 @@ void bitmap_daemon_work(struct bitmap *b
 	}
 	bitmap->allclean = 1;
 
+	spin_lock_irqsave(&bitmap->lock, flags);
 	for (j = 0; j < bitmap->chunks; j++) {
 		bitmap_counter_t *bmc;
-		spin_lock_irqsave(&bitmap->lock, flags);
-		if (!bitmap->filemap) {
+		if (!bitmap->filemap)
 			/* error or shutdown */
-			spin_unlock_irqrestore(&bitmap->lock, flags);
 			break;
-		}
 
 		page = filemap_get_page(bitmap, j);
 
@@ -1121,6 +1119,8 @@ void bitmap_daemon_work(struct bitmap *b
 					write_page(bitmap, page, 0);
 					bitmap->allclean = 0;
 				}
+				spin_lock_irqsave(&bitmap->lock, flags);
+				j |= (PAGE_BITS - 1);
 				continue;
 			}
 
@@ -1153,8 +1153,9 @@ void bitmap_daemon_work(struct bitmap *b
 			spin_lock_irqsave(&bitmap->lock, flags);
 			clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
 		}
-		bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
-					&blocks, 0);
+		bmc = bitmap_get_counter(bitmap,
+					 (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
+					 &blocks, 0);
 		if (bmc) {
 /*
   if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
@@ -1168,7 +1169,8 @@ void bitmap_daemon_work(struct bitmap *b
 			} else if (*bmc == 1) {
 				/* we can clear the bit */
 				*bmc = 0;
-				bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
+				bitmap_count_page(bitmap,
+						  (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap),
 						  -1);
 
 				/* clear the bit */
@@ -1179,9 +1181,10 @@ void bitmap_daemon_work(struct bitmap *b
 					ext2_clear_bit(file_page_offset(j), paddr);
 				kunmap_atomic(paddr, KM_USER0);
 			}
-		}
-		spin_unlock_irqrestore(&bitmap->lock, flags);
+		} else
+			j |= PAGE_COUNTER_MASK;
 	}
+	spin_unlock_irqrestore(&bitmap->lock, flags);
 
 	/* now sync the final page */
 	if (lastpage != NULL) {
@@ -1306,6 +1309,9 @@ void bitmap_endwrite(struct bitmap *bitm
 		PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
 		  atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
 	}
+	if (bitmap->mddev->degraded)
+		/* Never clear bits or update events_cleared when degraded */
+		success = 0;
 
 	while (sectors) {
 		int blocks;
@@ -1345,8 +1351,8 @@ void bitmap_endwrite(struct bitmap *bitm
 	}
 }
 
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
-			int degraded)
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+			       int degraded)
 {
 	bitmap_counter_t *bmc;
 	int rv;
@@ -1374,6 +1380,29 @@ int bitmap_start_sync(struct bitmap *bit
 	return rv;
 }
 
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+		      int degraded)
+{
+	/* bitmap_start_sync must always report on multiples of whole
+	 * pages, otherwise resync (which is very PAGE_SIZE based) will
+	 * get confused.
+	 * So call __bitmap_start_sync repeatedly (if needed) until
+	 * At least PAGE_SIZE>>9 blocks are covered.
+	 * Return the 'or' of the result.
+	 */
+	int rv = 0;
+	int blocks1;
+
+	*blocks = 0;
+	while (*blocks < (PAGE_SIZE>>9)) {
+		rv |= __bitmap_start_sync(bitmap, offset,
+					  &blocks1, degraded);
+		offset += blocks1;
+		*blocks += blocks1;
+	}
+	return rv;
+}
+
 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
 {
 	bitmap_counter_t *bmc;
@@ -1443,6 +1472,8 @@ void bitmap_cond_end_sync(struct bitmap
 	wait_event(bitmap->mddev->recovery_wait,
 		   atomic_read(&bitmap->mddev->recovery_active) == 0);
 
+	bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
+	set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
 	sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
 	s = 0;
 	while (s < sector && s < bitmap->mddev->resync_max_sectors) {
@@ -1450,6 +1481,7 @@ void bitmap_cond_end_sync(struct bitmap
 		s += blocks;
 	}
 	bitmap->last_end_sync = jiffies;
+	sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
 }
 
 static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
@@ -1484,7 +1516,7 @@ void bitmap_dirty_bits(struct bitmap *bi
 	unsigned long chunk;
 
 	for (chunk = s; chunk <= e; chunk++) {
-		sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap);
+		sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap);
 		bitmap_set_memory_bits(bitmap, sec, 1);
 		bitmap_file_set_bit(bitmap, sec);
 	}
@@ -1560,7 +1592,7 @@ void bitmap_destroy(mddev_t *mddev)
 int bitmap_create(mddev_t *mddev)
 {
 	struct bitmap *bitmap;
-	unsigned long blocks = mddev->resync_max_sectors;
+	sector_t blocks = mddev->resync_max_sectors;
 	unsigned long chunks;
 	unsigned long pages;
 	struct file *file = mddev->bitmap_file;
@@ -1602,8 +1634,8 @@ int bitmap_create(mddev_t *mddev)
 	bitmap->chunkshift = ffz(~bitmap->chunksize);
 
 	/* now that chunksize and chunkshift are set, we can use these macros */
- 	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
-			CHUNK_BLOCK_RATIO(bitmap);
+ 	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >>
+			CHUNK_BLOCK_SHIFT(bitmap);
  	pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
 
 	BUG_ON(!pages);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/bitmap.h linux-libre-2.6.30-gnu1/drivers/md/bitmap.h
--- linux-libre-2.6.29-gnu1/drivers/md/bitmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/bitmap.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,288 @@
+/*
+ * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
+ *
+ * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.
+ */
+#ifndef BITMAP_H
+#define BITMAP_H 1
+
+#define BITMAP_MAJOR_LO 3
+/* version 4 insists the bitmap is in little-endian order
+ * with version 3, it is host-endian which is non-portable
+ */
+#define BITMAP_MAJOR_HI 4
+#define	BITMAP_MAJOR_HOSTENDIAN 3
+
+#define BITMAP_MINOR 39
+
+/*
+ * in-memory bitmap:
+ *
+ * Use 16 bit block counters to track pending writes to each "chunk".
+ * The 2 high order bits are special-purpose, the first is a flag indicating
+ * whether a resync is needed.  The second is a flag indicating whether a
+ * resync is active.
+ * This means that the counter is actually 14 bits:
+ *
+ * +--------+--------+------------------------------------------------+
+ * | resync | resync |               counter                          |
+ * | needed | active |                                                |
+ * |  (0-1) |  (0-1) |              (0-16383)                         |
+ * +--------+--------+------------------------------------------------+
+ *
+ * The "resync needed" bit is set when:
+ *    a '1' bit is read from storage at startup.
+ *    a write request fails on some drives
+ *    a resync is aborted on a chunk with 'resync active' set
+ * It is cleared (and resync-active set) when a resync starts across all drives
+ * of the chunk.
+ *
+ *
+ * The "resync active" bit is set when:
+ *    a resync is started on all drives, and resync_needed is set.
+ *       resync_needed will be cleared (as long as resync_active wasn't already set).
+ * It is cleared when a resync completes.
+ *
+ * The counter counts pending write requests, plus the on-disk bit.
+ * When the counter is '1' and the resync bits are clear, the on-disk
+ * bit can be cleared aswell, thus setting the counter to 0.
+ * When we set a bit, or in the counter (to start a write), if the fields is
+ * 0, we first set the disk bit and set the counter to 1.
+ *
+ * If the counter is 0, the on-disk bit is clear and the stipe is clean
+ * Anything that dirties the stipe pushes the counter to 2 (at least)
+ * and sets the on-disk bit (lazily).
+ * If a periodic sweep find the counter at 2, it is decremented to 1.
+ * If the sweep find the counter at 1, the on-disk bit is cleared and the
+ * counter goes to zero.
+ *
+ * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block
+ * counters as a fallback when "page" memory cannot be allocated:
+ *
+ * Normal case (page memory allocated):
+ *
+ *     page pointer (32-bit)
+ *
+ *     [ ] ------+
+ *               |
+ *               +-------> [   ][   ]..[   ] (4096 byte page == 2048 counters)
+ *                          c1   c2    c2048
+ *
+ * Hijacked case (page memory allocation failed):
+ *
+ *     hijacked page pointer (32-bit)
+ *
+ *     [		  ][		  ] (no page memory allocated)
+ *      counter #1 (16-bit) counter #2 (16-bit)
+ *
+ */
+
+#ifdef __KERNEL__
+
+#define PAGE_BITS (PAGE_SIZE << 3)
+#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3)
+
+typedef __u16 bitmap_counter_t;
+#define COUNTER_BITS 16
+#define COUNTER_BIT_SHIFT 4
+#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8)
+#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3)
+
+#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1)))
+#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2)))
+#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1)
+#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK)
+#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK)
+#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX)
+
+/* how many counters per page? */
+#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS)
+/* same, except a shift value for more efficient bitops */
+#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT)
+/* same, except a mask value for more efficient bitops */
+#define PAGE_COUNTER_MASK  (PAGE_COUNTER_RATIO - 1)
+
+#define BITMAP_BLOCK_SIZE 512
+#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_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1)
+
+/* when hijacked, the counters and bits represent even larger "chunks" */
+/* there will be 1024 chunks represented by each counter in the page pointers */
+#define PAGEPTR_BLOCK_RATIO(bitmap) \
+			(CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1)
+#define PAGEPTR_BLOCK_SHIFT(bitmap) \
+			(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
+
+/*
+ * bitmap structures:
+ */
+
+#define BITMAP_MAGIC 0x6d746962
+
+/* use these for bitmap->flags and bitmap->sb->state bit-fields */
+enum bitmap_state {
+	BITMAP_STALE  = 0x002,  /* the bitmap file is out of date or had -EIO */
+	BITMAP_WRITE_ERROR = 0x004, /* A write error has occurred */
+	BITMAP_HOSTENDIAN = 0x8000,
+};
+
+/* the superblock at the front of the bitmap file -- little endian */
+typedef struct bitmap_super_s {
+	__le32 magic;        /*  0  BITMAP_MAGIC */
+	__le32 version;      /*  4  the bitmap major for now, could change... */
+	__u8  uuid[16];      /*  8  128 bit uuid - must match md device uuid */
+	__le64 events;       /* 24  event counter for the bitmap (1)*/
+	__le64 events_cleared;/*32  event counter when last bit cleared (2) */
+	__le64 sync_size;    /* 40  the size of the md device's sync range(3) */
+	__le32 state;        /* 48  bitmap state information */
+	__le32 chunksize;    /* 52  the bitmap chunk size in bytes */
+	__le32 daemon_sleep; /* 56  seconds between disk flushes */
+	__le32 write_behind; /* 60  number of outstanding write-behind writes */
+
+	__u8  pad[256 - 64]; /* set to zero */
+} bitmap_super_t;
+
+/* notes:
+ * (1) This event counter is updated before the eventcounter in the md superblock
+ *    When a bitmap is loaded, it is only accepted if this event counter is equal
+ *    to, or one greater than, the event counter in the superblock.
+ * (2) This event counter is updated when the other one is *if*and*only*if* the
+ *    array is not degraded.  As bits are not cleared when the array is degraded,
+ *    this represents the last time that any bits were cleared.
+ *    If a device is being added that has an event count with this value or
+ *    higher, it is accepted as conforming to the bitmap.
+ * (3)This is the number of sectors represented by the bitmap, and is the range that
+ *    resync happens across.  For raid1 and raid5/6 it is the size of individual
+ *    devices.  For raid10 it is the size of the array.
+ */
+
+#ifdef __KERNEL__
+
+/* the in-memory bitmap is represented by bitmap_pages */
+struct bitmap_page {
+	/*
+	 * map points to the actual memory page
+	 */
+	char *map;
+	/*
+	 * in emergencies (when map cannot be alloced), hijack the map
+	 * pointer and use it as two counters itself
+	 */
+	unsigned int hijacked:1;
+	/*
+	 * count of dirty bits on the page
+	 */
+	unsigned int  count:31;
+};
+
+/* keep track of bitmap file pages that have pending writes on them */
+struct page_list {
+	struct list_head list;
+	struct page *page;
+};
+
+/* the main bitmap structure - one per mddev */
+struct bitmap {
+	struct bitmap_page *bp;
+	unsigned long pages; /* total number of pages in the bitmap */
+	unsigned long missing_pages; /* number of pages not yet allocated */
+
+	mddev_t *mddev; /* the md device that the bitmap is for */
+
+	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 */
+
+	/* We hold a count on the chunk currently being synced, and drop
+	 * it when the last block is started.  If the resync is aborted
+	 * midway, we need to be able to drop that count, so we remember
+	 * the counted chunk..
+	 */
+	unsigned long syncchunk;
+
+	__u64	events_cleared;
+	int need_sync;
+
+	/* 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 */
+	unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
+	unsigned long file_pages; /* number of pages in the file */
+	int last_page_size; /* bytes in the last page */
+
+	unsigned long flags;
+
+	int allclean;
+
+	unsigned long max_write_behind; /* write-behind mode */
+	atomic_t behind_writes;
+
+	/*
+	 * the bitmap daemon - periodically wakes up and sweeps the 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 */
+
+	atomic_t pending_writes; /* pending writes to the bitmap file */
+	wait_queue_head_t write_wait;
+	wait_queue_head_t overflow_wait;
+
+};
+
+/* the bitmap API */
+
+/* these are used only by md/bitmap */
+int  bitmap_create(mddev_t *mddev);
+void bitmap_flush(mddev_t *mddev);
+void bitmap_destroy(mddev_t *mddev);
+
+void bitmap_print_sb(struct bitmap *bitmap);
+void bitmap_update_sb(struct bitmap *bitmap);
+
+int  bitmap_setallbits(struct bitmap *bitmap);
+void bitmap_write_all(struct bitmap *bitmap);
+
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
+
+/* these are exported */
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
+			unsigned long sectors, int behind);
+void bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
+			unsigned long sectors, int success, int behind);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
+void bitmap_close_sync(struct bitmap *bitmap);
+void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
+
+void bitmap_unplug(struct bitmap *bitmap);
+void bitmap_daemon_work(struct bitmap *bitmap);
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-bio-list.h linux-libre-2.6.30-gnu1/drivers/md/dm-bio-list.h
--- linux-libre-2.6.29-gnu1/drivers/md/dm-bio-list.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-bio-list.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2004 Red Hat UK Ltd.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_BIO_LIST_H
-#define DM_BIO_LIST_H
-
-#include <linux/bio.h>
-
-#ifdef CONFIG_BLOCK
-
-struct bio_list {
-	struct bio *head;
-	struct bio *tail;
-};
-
-static inline int bio_list_empty(const struct bio_list *bl)
-{
-	return bl->head == NULL;
-}
-
-static inline void bio_list_init(struct bio_list *bl)
-{
-	bl->head = bl->tail = NULL;
-}
-
-#define bio_list_for_each(bio, bl) \
-	for (bio = (bl)->head; bio; bio = bio->bi_next)
-
-static inline unsigned bio_list_size(const struct bio_list *bl)
-{
-	unsigned sz = 0;
-	struct bio *bio;
-
-	bio_list_for_each(bio, bl)
-		sz++;
-
-	return sz;
-}
-
-static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
-{
-	bio->bi_next = NULL;
-
-	if (bl->tail)
-		bl->tail->bi_next = bio;
-	else
-		bl->head = bio;
-
-	bl->tail = bio;
-}
-
-static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
-{
-	if (!bl2->head)
-		return;
-
-	if (bl->tail)
-		bl->tail->bi_next = bl2->head;
-	else
-		bl->head = bl2->head;
-
-	bl->tail = bl2->tail;
-}
-
-static inline void bio_list_merge_head(struct bio_list *bl,
-				       struct bio_list *bl2)
-{
-	if (!bl2->head)
-		return;
-
-	if (bl->head)
-		bl2->tail->bi_next = bl->head;
-	else
-		bl->tail = bl2->tail;
-
-	bl->head = bl2->head;
-}
-
-static inline struct bio *bio_list_pop(struct bio_list *bl)
-{
-	struct bio *bio = bl->head;
-
-	if (bio) {
-		bl->head = bl->head->bi_next;
-		if (!bl->head)
-			bl->tail = NULL;
-
-		bio->bi_next = NULL;
-	}
-
-	return bio;
-}
-
-static inline struct bio *bio_list_get(struct bio_list *bl)
-{
-	struct bio *bio = bl->head;
-
-	bl->head = bl->tail = NULL;
-
-	return bio;
-}
-
-#endif /* CONFIG_BLOCK */
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-bio-record.h linux-libre-2.6.30-gnu1/drivers/md/dm-bio-record.h
--- linux-libre-2.6.29-gnu1/drivers/md/dm-bio-record.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-bio-record.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,30 +16,56 @@
  * functions in this file help the target record and restore the
  * original bio state.
  */
+
+struct dm_bio_vec_details {
+#if PAGE_SIZE < 65536
+	__u16 bv_len;
+	__u16 bv_offset;
+#else
+	unsigned bv_len;
+	unsigned bv_offset;
+#endif
+};
+
 struct dm_bio_details {
 	sector_t bi_sector;
 	struct block_device *bi_bdev;
 	unsigned int bi_size;
 	unsigned short bi_idx;
 	unsigned long bi_flags;
+	struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
 };
 
 static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
 {
+	unsigned i;
+
 	bd->bi_sector = bio->bi_sector;
 	bd->bi_bdev = bio->bi_bdev;
 	bd->bi_size = bio->bi_size;
 	bd->bi_idx = bio->bi_idx;
 	bd->bi_flags = bio->bi_flags;
+
+	for (i = 0; i < bio->bi_vcnt; i++) {
+		bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
+		bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
+	}
 }
 
 static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
 {
+	unsigned i;
+
 	bio->bi_sector = bd->bi_sector;
 	bio->bi_bdev = bd->bi_bdev;
 	bio->bi_size = bd->bi_size;
 	bio->bi_idx = bd->bi_idx;
 	bio->bi_flags = bd->bi_flags;
+
+	for (i = 0; i < bio->bi_vcnt; i++) {
+		bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
+		bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
+	}
 }
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm.c linux-libre-2.6.30-gnu1/drivers/md/dm.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,6 @@
  */
 
 #include "dm.h"
-#include "dm-bio-list.h"
 #include "dm-uevent.h"
 
 #include <linux/init.h>
@@ -89,29 +88,20 @@ union map_info *dm_get_mapinfo(struct bi
 /*
  * Bits for the md->flags field.
  */
-#define DMF_BLOCK_IO 0
+#define DMF_BLOCK_IO_FOR_SUSPEND 0
 #define DMF_SUSPENDED 1
 #define DMF_FROZEN 2
 #define DMF_FREEING 3
 #define DMF_DELETING 4
 #define DMF_NOFLUSH_SUSPENDING 5
+#define DMF_QUEUE_IO_TO_THREAD 6
 
 /*
  * Work processed by per-device workqueue.
  */
-struct dm_wq_req {
-	enum {
-		DM_WQ_FLUSH_DEFERRED,
-	} type;
-	struct work_struct work;
-	struct mapped_device *md;
-	void *context;
-};
-
 struct mapped_device {
 	struct rw_semaphore io_lock;
 	struct mutex suspend_lock;
-	spinlock_t pushback_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
 	atomic_t open_count;
@@ -129,8 +119,14 @@ struct mapped_device {
 	 */
 	atomic_t pending;
 	wait_queue_head_t wait;
+	struct work_struct work;
 	struct bio_list deferred;
-	struct bio_list pushback;
+	spinlock_t deferred_lock;
+
+	/*
+	 * An error from the barrier request currently being processed.
+	 */
+	int barrier_error;
 
 	/*
 	 * Processing queue (flush/barriers)
@@ -433,6 +429,10 @@ static void end_io_acct(struct dm_io *io
 	part_stat_add(cpu, &dm_disk(md)->part0, ticks[rw], duration);
 	part_stat_unlock();
 
+	/*
+	 * After this is decremented the bio must not be touched if it is
+	 * a barrier.
+	 */
 	dm_disk(md)->part0.in_flight = pending =
 		atomic_dec_return(&md->pending);
 
@@ -444,19 +444,18 @@ static void end_io_acct(struct dm_io *io
 /*
  * Add the bio to the list of deferred io.
  */
-static int queue_io(struct mapped_device *md, struct bio *bio)
+static void queue_io(struct mapped_device *md, struct bio *bio)
 {
 	down_write(&md->io_lock);
 
-	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
-		up_write(&md->io_lock);
-		return 1;
-	}
-
+	spin_lock_irq(&md->deferred_lock);
 	bio_list_add(&md->deferred, bio);
+	spin_unlock_irq(&md->deferred_lock);
+
+	if (!test_and_set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags))
+		queue_work(md->wq, &md->work);
 
 	up_write(&md->io_lock);
-	return 0;		/* deferred successfully */
 }
 
 /*
@@ -537,30 +536,38 @@ static void dec_pending(struct dm_io *io
 		if (io->error == DM_ENDIO_REQUEUE) {
 			/*
 			 * Target requested pushing back the I/O.
-			 * This must be handled before the sleeper on
-			 * suspend queue merges the pushback list.
 			 */
-			spin_lock_irqsave(&md->pushback_lock, flags);
+			spin_lock_irqsave(&md->deferred_lock, flags);
 			if (__noflush_suspending(md))
-				bio_list_add(&md->pushback, io->bio);
+				bio_list_add_head(&md->deferred, io->bio);
 			else
 				/* noflush suspend was interrupted. */
 				io->error = -EIO;
-			spin_unlock_irqrestore(&md->pushback_lock, flags);
+			spin_unlock_irqrestore(&md->deferred_lock, flags);
 		}
 
-		end_io_acct(io);
-
 		io_error = io->error;
 		bio = io->bio;
 
-		free_io(md, io);
+		if (bio_barrier(bio)) {
+			/*
+			 * There can be just one barrier request so we use
+			 * a per-device variable for error reporting.
+			 * Note that you can't touch the bio after end_io_acct
+			 */
+			md->barrier_error = io_error;
+			end_io_acct(io);
+		} else {
+			end_io_acct(io);
 
-		if (io_error != DM_ENDIO_REQUEUE) {
-			trace_block_bio_complete(md->queue, bio);
+			if (io_error != DM_ENDIO_REQUEUE) {
+				trace_block_bio_complete(md->queue, bio);
 
-			bio_endio(bio, io_error);
+				bio_endio(bio, io_error);
+			}
 		}
+
+		free_io(md, io);
 	}
 }
 
@@ -702,13 +709,19 @@ static struct bio *split_bvec(struct bio
 
 	clone->bi_sector = sector;
 	clone->bi_bdev = bio->bi_bdev;
-	clone->bi_rw = bio->bi_rw;
+	clone->bi_rw = bio->bi_rw & ~(1 << BIO_RW_BARRIER);
 	clone->bi_vcnt = 1;
 	clone->bi_size = to_bytes(len);
 	clone->bi_io_vec->bv_offset = offset;
 	clone->bi_io_vec->bv_len = clone->bi_size;
 	clone->bi_flags |= 1 << BIO_CLONED;
 
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, GFP_NOIO);
+		bio_integrity_trim(clone,
+				   bio_sector_offset(bio, idx, offset), len);
+	}
+
 	return clone;
 }
 
@@ -723,6 +736,7 @@ static struct bio *clone_bio(struct bio
 
 	clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
 	__bio_clone(clone, bio);
+	clone->bi_rw &= ~(1 << BIO_RW_BARRIER);
 	clone->bi_destructor = dm_bio_destructor;
 	clone->bi_sector = sector;
 	clone->bi_idx = idx;
@@ -730,6 +744,14 @@ static struct bio *clone_bio(struct bio
 	clone->bi_size = to_bytes(len);
 	clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
+	if (bio_integrity(bio)) {
+		bio_integrity_clone(clone, bio, GFP_NOIO);
+
+		if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
+			bio_integrity_trim(clone,
+					   bio_sector_offset(bio, idx, 0), len);
+	}
+
 	return clone;
 }
 
@@ -834,21 +856,22 @@ static int __clone_and_map(struct clone_
 }
 
 /*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
  */
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
 {
 	struct clone_info ci;
 	int error = 0;
 
 	ci.map = dm_get_table(md);
-	if (unlikely(!ci.map))
-		return -EIO;
-	if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
-		dm_table_put(ci.map);
-		bio_endio(bio, -EOPNOTSUPP);
-		return 0;
+	if (unlikely(!ci.map)) {
+		if (!bio_barrier(bio))
+			bio_io_error(bio);
+		else
+			md->barrier_error = -EIO;
+		return;
 	}
+
 	ci.md = md;
 	ci.bio = bio;
 	ci.io = alloc_io(md);
@@ -867,8 +890,6 @@ static int __split_bio(struct mapped_dev
 	/* drop the extra reference count */
 	dec_pending(ci.io, error);
 	dm_table_put(ci.map);
-
-	return 0;
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -927,7 +948,6 @@ out:
  */
 static int dm_request(struct request_queue *q, struct bio *bio)
 {
-	int r = -EIO;
 	int rw = bio_data_dir(bio);
 	struct mapped_device *md = q->queuedata;
 	int cpu;
@@ -940,32 +960,26 @@ static int dm_request(struct request_que
 	part_stat_unlock();
 
 	/*
-	 * If we're suspended we have to queue
-	 * this io for later.
+	 * If we're suspended or the thread is processing barriers
+	 * we have to queue this io for later.
 	 */
-	while (test_bit(DMF_BLOCK_IO, &md->flags)) {
+	if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) ||
+	    unlikely(bio_barrier(bio))) {
 		up_read(&md->io_lock);
 
-		if (bio_rw(bio) != READA)
-			r = queue_io(md, bio);
+		if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) &&
+		    bio_rw(bio) == READA) {
+			bio_io_error(bio);
+			return 0;
+		}
 
-		if (r <= 0)
-			goto out_req;
+		queue_io(md, bio);
 
-		/*
-		 * We're in a while loop, because someone could suspend
-		 * before we get to the following read lock.
-		 */
-		down_read(&md->io_lock);
+		return 0;
 	}
 
-	r = __split_bio(md, bio);
+	__split_and_process_bio(md, bio);
 	up_read(&md->io_lock);
-
-out_req:
-	if (r < 0)
-		bio_io_error(bio);
-
 	return 0;
 }
 
@@ -986,7 +1000,7 @@ static int dm_any_congested(void *conges
 	struct mapped_device *md = congested_data;
 	struct dm_table *map;
 
-	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
+	if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
 		map = dm_get_table(md);
 		if (map) {
 			r = dm_table_any_congested(map, bdi_bits);
@@ -1074,6 +1088,8 @@ out:
 
 static struct block_device_operations dm_blk_dops;
 
+static void dm_wq_work(struct work_struct *work);
+
 /*
  * Allocate and initialise a blank device with a given minor.
  */
@@ -1101,7 +1117,7 @@ static struct mapped_device *alloc_dev(i
 
 	init_rwsem(&md->io_lock);
 	mutex_init(&md->suspend_lock);
-	spin_lock_init(&md->pushback_lock);
+	spin_lock_init(&md->deferred_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
@@ -1118,6 +1134,7 @@ static struct mapped_device *alloc_dev(i
 	md->queue->backing_dev_info.congested_fn = dm_any_congested;
 	md->queue->backing_dev_info.congested_data = md;
 	blk_queue_make_request(md->queue, dm_request);
+	blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL);
 	blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
 	md->queue->unplug_fn = dm_unplug_all;
 	blk_queue_merge_bvec(md->queue, dm_merge_bvec);
@@ -1140,6 +1157,7 @@ static struct mapped_device *alloc_dev(i
 
 	atomic_set(&md->pending, 0);
 	init_waitqueue_head(&md->wait);
+	INIT_WORK(&md->work, dm_wq_work);
 	init_waitqueue_head(&md->eventq);
 
 	md->disk->major = _major;
@@ -1197,6 +1215,7 @@ static void free_dev(struct mapped_devic
 	mempool_destroy(md->tio_pool);
 	mempool_destroy(md->io_pool);
 	bioset_free(md->bs);
+	blk_integrity_unregister(md->disk);
 	del_gendisk(md->disk);
 	free_minor(minor);
 
@@ -1379,18 +1398,24 @@ void dm_put(struct mapped_device *md)
 }
 EXPORT_SYMBOL_GPL(dm_put);
 
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
 {
 	int r = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	dm_unplug_all(md->queue);
+
+	add_wait_queue(&md->wait, &wait);
 
 	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
+		set_current_state(interruptible);
 
 		smp_mb();
 		if (!atomic_read(&md->pending))
 			break;
 
-		if (signal_pending(current)) {
+		if (interruptible == TASK_INTERRUPTIBLE &&
+		    signal_pending(current)) {
 			r = -EINTR;
 			break;
 		}
@@ -1399,68 +1424,80 @@ static int dm_wait_for_completion(struct
 	}
 	set_current_state(TASK_RUNNING);
 
+	remove_wait_queue(&md->wait, &wait);
+
 	return r;
 }
 
-/*
- * Process the deferred bios
- */
-static void __flush_deferred_io(struct mapped_device *md)
+static int dm_flush(struct mapped_device *md)
 {
-	struct bio *c;
+	dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
+	return 0;
+}
 
-	while ((c = bio_list_pop(&md->deferred))) {
-		if (__split_bio(md, c))
-			bio_io_error(c);
+static void process_barrier(struct mapped_device *md, struct bio *bio)
+{
+	int error = dm_flush(md);
+
+	if (unlikely(error)) {
+		bio_endio(bio, error);
+		return;
+	}
+	if (bio_empty_barrier(bio)) {
+		bio_endio(bio, 0);
+		return;
 	}
 
-	clear_bit(DMF_BLOCK_IO, &md->flags);
-}
+	__split_and_process_bio(md, bio);
 
-static void __merge_pushback_list(struct mapped_device *md)
-{
-	unsigned long flags;
+	error = dm_flush(md);
 
-	spin_lock_irqsave(&md->pushback_lock, flags);
-	clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
-	bio_list_merge_head(&md->deferred, &md->pushback);
-	bio_list_init(&md->pushback);
-	spin_unlock_irqrestore(&md->pushback_lock, flags);
+	if (!error && md->barrier_error)
+		error = md->barrier_error;
+
+	if (md->barrier_error != DM_ENDIO_REQUEUE)
+		bio_endio(bio, error);
 }
 
+/*
+ * Process the deferred bios
+ */
 static void dm_wq_work(struct work_struct *work)
 {
-	struct dm_wq_req *req = container_of(work, struct dm_wq_req, work);
-	struct mapped_device *md = req->md;
+	struct mapped_device *md = container_of(work, struct mapped_device,
+						work);
+	struct bio *c;
 
 	down_write(&md->io_lock);
-	switch (req->type) {
-	case DM_WQ_FLUSH_DEFERRED:
-		__flush_deferred_io(md);
-		break;
-	default:
-		DMERR("dm_wq_work: unrecognised work type %d", req->type);
-		BUG();
+
+	while (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
+		spin_lock_irq(&md->deferred_lock);
+		c = bio_list_pop(&md->deferred);
+		spin_unlock_irq(&md->deferred_lock);
+
+		if (!c) {
+			clear_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
+			break;
+		}
+
+		up_write(&md->io_lock);
+
+		if (bio_barrier(c))
+			process_barrier(md, c);
+		else
+			__split_and_process_bio(md, c);
+
+		down_write(&md->io_lock);
 	}
-	up_write(&md->io_lock);
-}
 
-static void dm_wq_queue(struct mapped_device *md, int type, void *context,
-			struct dm_wq_req *req)
-{
-	req->type = type;
-	req->md = md;
-	req->context = context;
-	INIT_WORK(&req->work, dm_wq_work);
-	queue_work(md->wq, &req->work);
+	up_write(&md->io_lock);
 }
 
-static void dm_queue_flush(struct mapped_device *md, int type, void *context)
+static void dm_queue_flush(struct mapped_device *md)
 {
-	struct dm_wq_req req;
-
-	dm_wq_queue(md, type, context, &req);
-	flush_workqueue(md->wq);
+	clear_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+	smp_mb__after_clear_bit();
+	queue_work(md->wq, &md->work);
 }
 
 /*
@@ -1534,7 +1571,6 @@ static void unlock_fs(struct mapped_devi
 int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 {
 	struct dm_table *map = NULL;
-	DECLARE_WAITQUEUE(wait, current);
 	int r = 0;
 	int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
 	int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
@@ -1579,38 +1615,54 @@ int dm_suspend(struct mapped_device *md,
 	}
 
 	/*
-	 * First we set the BLOCK_IO flag so no more ios will be mapped.
+	 * Here we must make sure that no processes are submitting requests
+	 * to target drivers i.e. no one may be executing
+	 * __split_and_process_bio. This is called from dm_request and
+	 * dm_wq_work.
+	 *
+	 * To get all processes out of __split_and_process_bio in dm_request,
+	 * we take the write lock. To prevent any process from reentering
+	 * __split_and_process_bio from dm_request, we set
+	 * DMF_QUEUE_IO_TO_THREAD.
+	 *
+	 * To quiesce the thread (dm_wq_work), we set DMF_BLOCK_IO_FOR_SUSPEND
+	 * and call flush_workqueue(md->wq). flush_workqueue will wait until
+	 * dm_wq_work exits and DMF_BLOCK_IO_FOR_SUSPEND will prevent any
+	 * further calls to __split_and_process_bio from dm_wq_work.
 	 */
 	down_write(&md->io_lock);
-	set_bit(DMF_BLOCK_IO, &md->flags);
-
-	add_wait_queue(&md->wait, &wait);
+	set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
+	set_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags);
 	up_write(&md->io_lock);
 
-	/* unplug */
-	if (map)
-		dm_table_unplug_all(map);
+	flush_workqueue(md->wq);
 
 	/*
-	 * Wait for the already-mapped ios to complete.
+	 * At this point no more requests are entering target request routines.
+	 * We call dm_wait_for_completion to wait for all existing requests
+	 * to finish.
 	 */
-	r = dm_wait_for_completion(md);
+	r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
 
 	down_write(&md->io_lock);
-	remove_wait_queue(&md->wait, &wait);
-
 	if (noflush)
-		__merge_pushback_list(md);
+		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
 	up_write(&md->io_lock);
 
 	/* were we interrupted ? */
 	if (r < 0) {
-		dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+		dm_queue_flush(md);
 
 		unlock_fs(md);
 		goto out; /* pushback list is already flushed, so skip flush */
 	}
 
+	/*
+	 * If dm_wait_for_completion returned 0, the device is completely
+	 * quiescent now. There is no request-processing activity. All new
+	 * requests are being added to md->deferred list.
+	 */
+
 	dm_table_postsuspend_targets(map);
 
 	set_bit(DMF_SUSPENDED, &md->flags);
@@ -1645,7 +1697,7 @@ int dm_resume(struct mapped_device *md)
 	if (r)
 		goto out;
 
-	dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+	dm_queue_flush(md);
 
 	unlock_fs(md);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-crypt.c linux-libre-2.6.30-gnu1/drivers/md/dm-crypt.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-crypt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-crypt.c	2009-06-09 23:05:27.000000000 -0400
@@ -1156,8 +1156,7 @@ bad_ivmode:
 	crypto_free_ablkcipher(tfm);
 bad_cipher:
 	/* Must zero key material before freeing */
-	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
-	kfree(cc);
+	kzfree(cc);
 	return -EINVAL;
 }
 
@@ -1183,8 +1182,7 @@ static void crypt_dtr(struct dm_target *
 	dm_put_device(ti, cc->dev);
 
 	/* Must zero key material before freeing */
-	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
-	kfree(cc);
+	kzfree(cc);
 }
 
 static int crypt_map(struct dm_target *ti, struct bio *bio,
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-delay.c linux-libre-2.6.30-gnu1/drivers/md/dm-delay.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-delay.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-delay.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,8 +15,6 @@
 
 #include <linux/device-mapper.h>
 
-#include "dm-bio-list.h"
-
 #define DM_MSG_PREFIX "delay"
 
 struct delay_c {
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-exception-store.c linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-exception-store.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@
 
 #include "dm-exception-store.h"
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
@@ -14,6 +15,257 @@
 
 #define DM_MSG_PREFIX "snapshot exception stores"
 
+static LIST_HEAD(_exception_store_types);
+static DEFINE_SPINLOCK(_lock);
+
+static struct dm_exception_store_type *__find_exception_store_type(const char *name)
+{
+	struct dm_exception_store_type *type;
+
+	list_for_each_entry(type, &_exception_store_types, list)
+		if (!strcmp(name, type->name))
+			return type;
+
+	return NULL;
+}
+
+static struct dm_exception_store_type *_get_exception_store_type(const char *name)
+{
+	struct dm_exception_store_type *type;
+
+	spin_lock(&_lock);
+
+	type = __find_exception_store_type(name);
+
+	if (type && !try_module_get(type->module))
+		type = NULL;
+
+	spin_unlock(&_lock);
+
+	return type;
+}
+
+/*
+ * get_type
+ * @type_name
+ *
+ * Attempt to retrieve the dm_exception_store_type by name.  If not already
+ * available, attempt to load the appropriate module.
+ *
+ * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
+ * Modules may contain multiple types.
+ * This function will first try the module "dm-exstore-<type_name>",
+ * then truncate 'type_name' on the last '-' and try again.
+ *
+ * For example, if type_name was "clustered-shared", it would search
+ * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
+ *
+ * 'dm-exception-store-<type_name>' is too long of a name in my
+ * opinion, which is why I've chosen to have the files
+ * containing exception store implementations be 'dm-exstore-<type_name>'.
+ * If you want your module to be autoloaded, you will follow this
+ * naming convention.
+ *
+ * Returns: dm_exception_store_type* on success, NULL on failure
+ */
+static struct dm_exception_store_type *get_type(const char *type_name)
+{
+	char *p, *type_name_dup;
+	struct dm_exception_store_type *type;
+
+	type = _get_exception_store_type(type_name);
+	if (type)
+		return type;
+
+	type_name_dup = kstrdup(type_name, GFP_KERNEL);
+	if (!type_name_dup) {
+		DMERR("No memory left to attempt load for \"%s\"", type_name);
+		return NULL;
+	}
+
+	while (request_module("dm-exstore-%s", type_name_dup) ||
+	       !(type = _get_exception_store_type(type_name))) {
+		p = strrchr(type_name_dup, '-');
+		if (!p)
+			break;
+		p[0] = '\0';
+	}
+
+	if (!type)
+		DMWARN("Module for exstore type \"%s\" not found.", type_name);
+
+	kfree(type_name_dup);
+
+	return type;
+}
+
+static void put_type(struct dm_exception_store_type *type)
+{
+	spin_lock(&_lock);
+	module_put(type->module);
+	spin_unlock(&_lock);
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type)
+{
+	int r = 0;
+
+	spin_lock(&_lock);
+	if (!__find_exception_store_type(type->name))
+		list_add(&type->list, &_exception_store_types);
+	else
+		r = -EEXIST;
+	spin_unlock(&_lock);
+
+	return r;
+}
+EXPORT_SYMBOL(dm_exception_store_type_register);
+
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
+{
+	spin_lock(&_lock);
+
+	if (!__find_exception_store_type(type->name)) {
+		spin_unlock(&_lock);
+		return -EINVAL;
+	}
+
+	list_del(&type->list);
+
+	spin_unlock(&_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(dm_exception_store_type_unregister);
+
+/*
+ * Round a number up to the nearest 'size' boundary.  size must
+ * be a power of 2.
+ */
+static ulong round_up(ulong n, ulong size)
+{
+	size--;
+	return (n + size) & ~size;
+}
+
+static int set_chunk_size(struct dm_exception_store *store,
+			  const char *chunk_size_arg, char **error)
+{
+	unsigned long chunk_size_ulong;
+	char *value;
+
+	chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
+	if (*chunk_size_arg == '\0' || *value != '\0') {
+		*error = "Invalid chunk size";
+		return -EINVAL;
+	}
+
+	if (!chunk_size_ulong) {
+		store->chunk_size = store->chunk_mask = store->chunk_shift = 0;
+		return 0;
+	}
+
+	/*
+	 * Chunk size must be multiple of page size.  Silently
+	 * round up if it's not.
+	 */
+	chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
+	/* Check chunk_size is a power of 2 */
+	if (!is_power_of_2(chunk_size_ulong)) {
+		*error = "Chunk size is not a power of 2";
+		return -EINVAL;
+	}
+
+	/* Validate the chunk size against the device block size */
+	if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+		*error = "Chunk size is not a multiple of device blocksize";
+		return -EINVAL;
+	}
+
+	store->chunk_size = chunk_size_ulong;
+	store->chunk_mask = chunk_size_ulong - 1;
+	store->chunk_shift = ffs(chunk_size_ulong) - 1;
+
+	return 0;
+}
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      unsigned *args_used,
+			      struct dm_exception_store **store)
+{
+	int r = 0;
+	struct dm_exception_store_type *type;
+	struct dm_exception_store *tmp_store;
+	char persistent;
+
+	if (argc < 3) {
+		ti->error = "Insufficient exception store arguments";
+		return -EINVAL;
+	}
+
+	tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+	if (!tmp_store) {
+		ti->error = "Exception store allocation failed";
+		return -ENOMEM;
+	}
+
+	persistent = toupper(*argv[1]);
+	if (persistent != 'P' && persistent != 'N') {
+		ti->error = "Persistent flag is not P or N";
+		return -EINVAL;
+	}
+
+	type = get_type(argv[1]);
+	if (!type) {
+		ti->error = "Exception store type not recognised";
+		r = -EINVAL;
+		goto bad_type;
+	}
+
+	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;
+	}
+
+	r = set_chunk_size(tmp_store, argv[2], &ti->error);
+	if (r)
+		goto bad_cow;
+
+	r = type->ctr(tmp_store, 0, NULL);
+	if (r) {
+		ti->error = "Exception store type constructor failed";
+		goto bad_ctr;
+	}
+
+	*args_used = 3;
+	*store = tmp_store;
+	return 0;
+
+bad_ctr:
+	dm_put_device(ti, tmp_store->cow);
+bad_cow:
+	put_type(type);
+bad_type:
+	kfree(tmp_store);
+	return r;
+}
+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);
+}
+EXPORT_SYMBOL(dm_exception_store_destroy);
+
 int dm_exception_store_init(void)
 {
 	int r;
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-exception-store.h linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.h
--- linux-libre-2.6.29-gnu1/drivers/md/dm-exception-store.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,11 +37,18 @@ struct dm_snap_exception {
  * Abstraction to handle the meta/layout of exception stores (the
  * COW device).
  */
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+	const char *name;
+	struct module *module;
+
+	int (*ctr) (struct dm_exception_store *store,
+		    unsigned argc, char **argv);
+
 	/*
 	 * Destroys this object when you've finished with it.
 	 */
-	void (*destroy) (struct dm_exception_store *store);
+	void (*dtr) (struct dm_exception_store *store);
 
 	/*
 	 * The target shouldn't read the COW device until this is
@@ -72,8 +79,9 @@ struct dm_exception_store {
 	 */
 	void (*drop_snapshot) (struct dm_exception_store *store);
 
-	int (*status) (struct dm_exception_store *store, status_type_t status,
-		       char *result, unsigned int maxlen);
+	unsigned (*status) (struct dm_exception_store *store,
+			    status_type_t status, char *result,
+			    unsigned maxlen);
 
 	/*
 	 * Return how full the snapshot is.
@@ -82,7 +90,21 @@ struct dm_exception_store {
 			       sector_t *numerator,
 			       sector_t *denominator);
 
-	struct dm_snapshot *snap;
+	/* For internal device-mapper use only. */
+	struct list_head list;
+};
+
+struct dm_exception_store {
+	struct dm_exception_store_type *type;
+	struct dm_target *ti;
+
+	struct dm_dev *cow;
+
+	/* Size of data blocks saved - must be a power of 2 */
+	chunk_t chunk_size;
+	chunk_t chunk_mask;
+	chunk_t chunk_shift;
+
 	void *context;
 };
 
@@ -129,6 +151,28 @@ static inline void dm_consecutive_chunk_
 
 #  endif
 
+/*
+ * Return the number of sectors in the device.
+ */
+static inline sector_t get_dev_size(struct block_device *bdev)
+{
+	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+}
+
+static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+				      sector_t sector)
+{
+	return (sector & ~store->chunk_mask) >> store->chunk_shift;
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type);
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      unsigned *args_used,
+			      struct dm_exception_store **store);
+void dm_exception_store_destroy(struct dm_exception_store *store);
+
 int dm_exception_store_init(void);
 void dm_exception_store_exit(void);
 
@@ -141,8 +185,4 @@ void dm_persistent_snapshot_exit(void);
 int dm_transient_snapshot_init(void);
 void dm_transient_snapshot_exit(void);
 
-int dm_create_persistent(struct dm_exception_store *store);
-
-int dm_create_transient(struct dm_exception_store *store);
-
 #endif /* _LINUX_DM_EXCEPTION_STORE */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm.h linux-libre-2.6.30-gnu1/drivers/md/dm.h
--- linux-libre-2.6.29-gnu1/drivers/md/dm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm.h	2009-06-09 23:05:27.000000000 -0400
@@ -52,7 +52,6 @@ int dm_table_any_congested(struct dm_tab
  * To check the return value from dm_table_find_target().
  */
 #define dm_target_is_valid(t) ((t)->table)
-int dm_table_barrier_ok(struct dm_table *t);
 
 /*-----------------------------------------------------------------
  * A registry of target types.
@@ -60,7 +59,7 @@ int dm_table_barrier_ok(struct dm_table
 int dm_target_init(void);
 void dm_target_exit(void);
 struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
 					void *param), void *param);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-io.c linux-libre-2.6.30-gnu1/drivers/md/dm-io.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-io.c	2009-06-09 23:05:27.000000000 -0400
@@ -370,16 +370,13 @@ static int sync_io(struct dm_io_client *
 	while (1) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 
-		if (!atomic_read(&io.count) || signal_pending(current))
+		if (!atomic_read(&io.count))
 			break;
 
 		io_schedule();
 	}
 	set_current_state(TASK_RUNNING);
 
-	if (atomic_read(&io.count))
-		return -EINTR;
-
 	if (error_bits)
 		*error_bits = io.error_bits;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-ioctl.c linux-libre-2.6.30-gnu1/drivers/md/dm-ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -1047,6 +1047,19 @@ static int populate_table(struct dm_tabl
 	return dm_table_complete(table);
 }
 
+static int table_prealloc_integrity(struct dm_table *t,
+				    struct mapped_device *md)
+{
+	struct list_head *devices = dm_table_get_devices(t);
+	struct dm_dev_internal *dd;
+
+	list_for_each_entry(dd, devices, list)
+		if (bdev_get_integrity(dd->dm_dev.bdev))
+			return blk_integrity_register(dm_disk(md), NULL);
+
+	return 0;
+}
+
 static int table_load(struct dm_ioctl *param, size_t param_size)
 {
 	int r;
@@ -1067,6 +1080,14 @@ static int table_load(struct dm_ioctl *p
 		dm_table_destroy(t);
 		goto out;
 	}
+
+	r = table_prealloc_integrity(t, md);
+	if (r) {
+		DMERR("%s: could not register integrity profile.",
+		      dm_device_name(md));
+		dm_table_destroy(t);
+		goto out;
+	}
 
 	down_write(&_hash_lock);
 	hc = dm_get_mdptr(md);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-kcopyd.c linux-libre-2.6.30-gnu1/drivers/md/dm-kcopyd.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-kcopyd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-kcopyd.c	2009-06-09 23:05:27.000000000 -0400
@@ -297,7 +297,8 @@ static int run_complete_job(struct kcopy
 	dm_kcopyd_notify_fn fn = job->fn;
 	struct dm_kcopyd_client *kc = job->kc;
 
-	kcopyd_put_pages(kc, job->pages);
+	if (job->pages)
+		kcopyd_put_pages(kc, job->pages);
 	mempool_free(job, kc->job_pool);
 	fn(read_err, write_err, context);
 
@@ -461,6 +462,7 @@ static void segment_complete(int read_er
 	sector_t progress = 0;
 	sector_t count = 0;
 	struct kcopyd_job *job = (struct kcopyd_job *) context;
+	struct dm_kcopyd_client *kc = job->kc;
 
 	mutex_lock(&job->lock);
 
@@ -490,7 +492,7 @@ static void segment_complete(int read_er
 
 	if (count) {
 		int i;
-		struct kcopyd_job *sub_job = mempool_alloc(job->kc->job_pool,
+		struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool,
 							   GFP_NOIO);
 
 		*sub_job = *job;
@@ -509,13 +511,16 @@ static void segment_complete(int read_er
 	} else if (atomic_dec_and_test(&job->sub_jobs)) {
 
 		/*
-		 * To avoid a race we must keep the job around
-		 * until after the notify function has completed.
-		 * Otherwise the client may try and stop the job
-		 * after we've completed.
+		 * Queue the completion callback to the kcopyd thread.
+		 *
+		 * Some callers assume that all the completions are called
+		 * from a single thread and don't race with each other.
+		 *
+		 * We must not call the callback directly here because this
+		 * code may not be executing in the thread.
 		 */
-		job->fn(read_err, write_err, job->context);
-		mempool_free(job, job->kc->job_pool);
+		push(&kc->complete_jobs, job);
+		wake(kc);
 	}
 }
 
@@ -528,6 +533,8 @@ static void split_job(struct kcopyd_job
 {
 	int i;
 
+	atomic_inc(&job->kc->nr_jobs);
+
 	atomic_set(&job->sub_jobs, SPLIT_COUNT);
 	for (i = 0; i < SPLIT_COUNT; i++)
 		segment_complete(0, 0u, job);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-linear.c linux-libre-2.6.30-gnu1/drivers/md/dm-linear.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-linear.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-linear.c	2009-06-09 23:05:27.000000000 -0400
@@ -142,7 +142,6 @@ static struct target_type linear_target
 	.status = linear_status,
 	.ioctl  = linear_ioctl,
 	.merge  = linear_merge,
-	.features = DM_TARGET_SUPPORTS_BARRIERS,
 };
 
 int __init dm_linear_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-log.c linux-libre-2.6.30-gnu1/drivers/md/dm-log.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-log.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-log.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,40 +16,29 @@
 
 #define DM_MSG_PREFIX "dirty region log"
 
-struct dm_dirty_log_internal {
-	struct dm_dirty_log_type *type;
-
-	struct list_head list;
-	long use;
-};
-
 static LIST_HEAD(_log_types);
 static DEFINE_SPINLOCK(_lock);
 
-static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
 {
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	list_for_each_entry(log_type, &_log_types, list)
-		if (!strcmp(name, log_type->type->name))
+		if (!strcmp(name, log_type->name))
 			return log_type;
 
 	return NULL;
 }
 
-static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
 {
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	spin_lock(&_lock);
 
 	log_type = __find_dirty_log_type(name);
-	if (log_type) {
-		if (!log_type->use && !try_module_get(log_type->type->module))
-			log_type = NULL;
-		else
-			log_type->use++;
-	}
+	if (log_type && !try_module_get(log_type->module))
+		log_type = NULL;
 
 	spin_unlock(&_lock);
 
@@ -76,14 +65,14 @@ static struct dm_dirty_log_internal *_ge
 static struct dm_dirty_log_type *get_type(const char *type_name)
 {
 	char *p, *type_name_dup;
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	if (!type_name)
 		return NULL;
 
 	log_type = _get_dirty_log_type(type_name);
 	if (log_type)
-		return log_type->type;
+		return log_type;
 
 	type_name_dup = kstrdup(type_name, GFP_KERNEL);
 	if (!type_name_dup) {
@@ -105,56 +94,33 @@ static struct dm_dirty_log_type *get_typ
 
 	kfree(type_name_dup);
 
-	return log_type ? log_type->type : NULL;
+	return log_type;
 }
 
 static void put_type(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type;
-
 	if (!type)
 		return;
 
 	spin_lock(&_lock);
-	log_type = __find_dirty_log_type(type->name);
-	if (!log_type)
+	if (!__find_dirty_log_type(type->name))
 		goto out;
 
-	if (!--log_type->use)
-		module_put(type->module);
-
-	BUG_ON(log_type->use < 0);
+	module_put(type->module);
 
 out:
 	spin_unlock(&_lock);
 }
 
-static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
-{
-	struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
-							 GFP_KERNEL);
-
-	if (log_type)
-		log_type->type = type;
-
-	return log_type;
-}
-
 int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
 	int r = 0;
 
-	if (!log_type)
-		return -ENOMEM;
-
 	spin_lock(&_lock);
 	if (!__find_dirty_log_type(type->name))
-		list_add(&log_type->list, &_log_types);
-	else {
-		kfree(log_type);
+		list_add(&type->list, &_log_types);
+	else
 		r = -EEXIST;
-	}
 	spin_unlock(&_lock);
 
 	return r;
@@ -163,25 +129,16 @@ EXPORT_SYMBOL(dm_dirty_log_type_register
 
 int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type;
-
 	spin_lock(&_lock);
 
-	log_type = __find_dirty_log_type(type->name);
-	if (!log_type) {
+	if (!__find_dirty_log_type(type->name)) {
 		spin_unlock(&_lock);
 		return -EINVAL;
 	}
 
-	if (log_type->use) {
-		spin_unlock(&_lock);
-		return -ETXTBSY;
-	}
-
-	list_del(&log_type->list);
+	list_del(&type->list);
 
 	spin_unlock(&_lock);
-	kfree(log_type);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-mpath.c linux-libre-2.6.30-gnu1/drivers/md/dm-mpath.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-mpath.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-mpath.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,6 @@
 #include <linux/device-mapper.h>
 
 #include "dm-path-selector.h"
-#include "dm-bio-list.h"
 #include "dm-bio-record.h"
 #include "dm-uevent.h"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-path-selector.c linux-libre-2.6.30-gnu1/drivers/md/dm-path-selector.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-path-selector.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-path-selector.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,9 +17,7 @@
 
 struct ps_internal {
 	struct path_selector_type pst;
-
 	struct list_head list;
-	long use;
 };
 
 #define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
@@ -45,12 +43,8 @@ static struct ps_internal *get_path_sele
 
 	down_read(&_ps_lock);
 	psi = __find_path_selector_type(name);
-	if (psi) {
-		if ((psi->use == 0) && !try_module_get(psi->pst.module))
-			psi = NULL;
-		else
-			psi->use++;
-	}
+	if (psi && !try_module_get(psi->pst.module))
+		psi = NULL;
 	up_read(&_ps_lock);
 
 	return psi;
@@ -84,11 +78,7 @@ void dm_put_path_selector(struct path_se
 	if (!psi)
 		goto out;
 
-	if (--psi->use == 0)
-		module_put(psi->pst.module);
-
-	BUG_ON(psi->use < 0);
-
+	module_put(psi->pst.module);
 out:
 	up_read(&_ps_lock);
 }
@@ -136,11 +126,6 @@ int dm_unregister_path_selector(struct p
 		return -EINVAL;
 	}
 
-	if (psi->use) {
-		up_write(&_ps_lock);
-		return -ETXTBSY;
-	}
-
 	list_del(&psi->list);
 
 	up_write(&_ps_lock);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-raid1.c linux-libre-2.6.30-gnu1/drivers/md/dm-raid1.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-raid1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-raid1.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,6 @@
  * This file is released under the GPL.
  */
 
-#include "dm-bio-list.h"
 #include "dm-bio-record.h"
 
 #include <linux/init.h>
@@ -145,6 +144,8 @@ struct dm_raid1_read_record {
 	struct dm_bio_details details;
 };
 
+static struct kmem_cache *_dm_raid1_read_record_cache;
+
 /*
  * Every mirror should look like this one.
  */
@@ -586,6 +587,9 @@ static void do_writes(struct mirror_set
 	int state;
 	struct bio *bio;
 	struct bio_list sync, nosync, recover, *this_list = NULL;
+	struct bio_list requeue;
+	struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+	region_t region;
 
 	if (!writes->head)
 		return;
@@ -596,10 +600,18 @@ static void do_writes(struct mirror_set
 	bio_list_init(&sync);
 	bio_list_init(&nosync);
 	bio_list_init(&recover);
+	bio_list_init(&requeue);
 
 	while ((bio = bio_list_pop(writes))) {
-		state = dm_rh_get_state(ms->rh,
-					dm_rh_bio_to_region(ms->rh, bio), 1);
+		region = dm_rh_bio_to_region(ms->rh, bio);
+
+		if (log->type->is_remote_recovering &&
+		    log->type->is_remote_recovering(log, region)) {
+			bio_list_add(&requeue, bio);
+			continue;
+		}
+
+		state = dm_rh_get_state(ms->rh, region, 1);
 		switch (state) {
 		case DM_RH_CLEAN:
 		case DM_RH_DIRTY:
@@ -619,6 +631,16 @@ static void do_writes(struct mirror_set
 	}
 
 	/*
+	 * Add bios that are delayed due to remote recovery
+	 * back on to the write queue
+	 */
+	if (unlikely(requeue.head)) {
+		spin_lock_irq(&ms->lock);
+		bio_list_merge(&ms->writes, &requeue);
+		spin_unlock_irq(&ms->lock);
+	}
+
+	/*
 	 * Increment the pending counts for any regions that will
 	 * be written to (writes to recover regions are going to
 	 * be delayed).
@@ -764,9 +786,9 @@ static struct mirror_set *alloc_context(
 	atomic_set(&ms->suspend, 0);
 	atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
 
-	len = sizeof(struct dm_raid1_read_record);
-	ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
-							   len);
+	ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
+						_dm_raid1_read_record_cache);
+
 	if (!ms->read_record_pool) {
 		ti->error = "Error creating mirror read_record_pool";
 		kfree(ms);
@@ -1279,16 +1301,31 @@ static int __init dm_mirror_init(void)
 {
 	int r;
 
+	_dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
+	if (!_dm_raid1_read_record_cache) {
+		DMERR("Can't allocate dm_raid1_read_record cache");
+		r = -ENOMEM;
+		goto bad_cache;
+	}
+
 	r = dm_register_target(&mirror_target);
-	if (r < 0)
+	if (r < 0) {
 		DMERR("Failed to register mirror target");
+		goto bad_target;
+	}
 
+	return 0;
+
+bad_target:
+	kmem_cache_destroy(_dm_raid1_read_record_cache);
+bad_cache:
 	return r;
 }
 
 static void __exit dm_mirror_exit(void)
 {
 	dm_unregister_target(&mirror_target);
+	kmem_cache_destroy(_dm_raid1_read_record_cache);
 }
 
 /* Module hooks */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-region-hash.c linux-libre-2.6.30-gnu1/drivers/md/dm-region-hash.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-region-hash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-region-hash.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/vmalloc.h>
 
 #include "dm.h"
-#include "dm-bio-list.h"
 
 #define	DM_MSG_PREFIX	"region hash"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-snap.c linux-libre-2.6.30-gnu1/drivers/md/dm-snap.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-snap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-snap.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,7 +7,6 @@
  */
 
 #include <linux/blkdev.h>
-#include <linux/ctype.h>
 #include <linux/device-mapper.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
@@ -20,10 +19,9 @@
 #include <linux/vmalloc.h>
 #include <linux/log2.h>
 #include <linux/dm-kcopyd.h>
+#include <linux/workqueue.h>
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
-#include "dm-bio-list.h"
 
 #define DM_MSG_PREFIX "snapshots"
 
@@ -47,9 +45,76 @@
  */
 #define MIN_IOS 256
 
+#define DM_TRACKED_CHUNK_HASH_SIZE	16
+#define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
+					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
+struct exception_table {
+	uint32_t hash_mask;
+	unsigned hash_shift;
+	struct list_head *table;
+};
+
+struct dm_snapshot {
+	struct rw_semaphore lock;
+
+	struct dm_dev *origin;
+
+	/* List of snapshots per Origin */
+	struct list_head list;
+
+	/* You can't use a snapshot if this is 0 (e.g. if full) */
+	int valid;
+
+	/* Origin writes don't trigger exceptions until this is set */
+	int active;
+
+	mempool_t *pending_pool;
+
+	atomic_t pending_exceptions_count;
+
+	struct exception_table pending;
+	struct exception_table complete;
+
+	/*
+	 * pe_lock protects all pending_exception operations and access
+	 * as well as the snapshot_bios list.
+	 */
+	spinlock_t pe_lock;
+
+	/* The on disk metadata handler */
+	struct dm_exception_store *store;
+
+	struct dm_kcopyd_client *kcopyd_client;
+
+	/* Queue of snapshot writes for ksnapd to flush */
+	struct bio_list queued_bios;
+	struct work_struct queued_bios_work;
+
+	/* Chunks with outstanding reads */
+	mempool_t *tracked_chunk_pool;
+	spinlock_t tracked_chunk_lock;
+	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+};
+
 static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
+static sector_t chunk_to_sector(struct dm_exception_store *store,
+				chunk_t chunk)
+{
+	return chunk << store->chunk_shift;
+}
+
+static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
+{
+	/*
+	 * There is only ever one instance of a particular block
+	 * device so we can compare pointers safely.
+	 */
+	return lhs == rhs;
+}
+
 struct dm_snap_pending_exception {
 	struct dm_snap_exception e;
 
@@ -476,11 +541,11 @@ 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->cow->bdev);
+	cow_dev_size = get_dev_size(s->store->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->chunk_shift;
+	hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
 	hash_size = min(hash_size, max_buckets);
 
 	hash_size = rounddown_pow_of_two(hash_size);
@@ -505,58 +570,6 @@ static int init_hash_tables(struct dm_sn
 }
 
 /*
- * Round a number up to the nearest 'size' boundary.  size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
-	size--;
-	return (n + size) & ~size;
-}
-
-static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
-			  char **error)
-{
-	unsigned long chunk_size;
-	char *value;
-
-	chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
-	if (*chunk_size_arg == '\0' || *value != '\0') {
-		*error = "Invalid chunk size";
-		return -EINVAL;
-	}
-
-	if (!chunk_size) {
-		s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
-		return 0;
-	}
-
-	/*
-	 * Chunk size must be multiple of page size.  Silently
-	 * round up if it's not.
-	 */
-	chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
-	/* Check chunk_size is a power of 2 */
-	if (!is_power_of_2(chunk_size)) {
-		*error = "Chunk size is not a power of 2";
-		return -EINVAL;
-	}
-
-	/* Validate the chunk size against the device block size */
-	if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
-		*error = "Chunk size is not a multiple of device blocksize";
-		return -EINVAL;
-	}
-
-	s->chunk_size = chunk_size;
-	s->chunk_mask = chunk_size - 1;
-	s->chunk_shift = ffs(chunk_size) - 1;
-
-	return 0;
-}
-
-/*
  * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
  */
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -564,91 +577,68 @@ static int snapshot_ctr(struct dm_target
 	struct dm_snapshot *s;
 	int i;
 	int r = -EINVAL;
-	char persistent;
 	char *origin_path;
-	char *cow_path;
+	struct dm_exception_store *store;
+	unsigned args_used;
 
 	if (argc != 4) {
 		ti->error = "requires exactly 4 arguments";
 		r = -EINVAL;
-		goto bad1;
+		goto bad_args;
 	}
 
 	origin_path = argv[0];
-	cow_path = argv[1];
-	persistent = toupper(*argv[2]);
+	argv++;
+	argc--;
 
-	if (persistent != 'P' && persistent != 'N') {
-		ti->error = "Persistent flag is not P or N";
+	r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+	if (r) {
+		ti->error = "Couldn't create exception store";
 		r = -EINVAL;
-		goto bad1;
+		goto bad_args;
 	}
 
+	argv += args_used;
+	argc -= args_used;
+
 	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (s == NULL) {
+	if (!s) {
 		ti->error = "Cannot allocate snapshot context private "
 		    "structure";
 		r = -ENOMEM;
-		goto bad1;
+		goto bad_snap;
 	}
 
 	r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
 	if (r) {
 		ti->error = "Cannot get origin device";
-		goto bad2;
-	}
-
-	r = dm_get_device(ti, cow_path, 0, 0,
-			  FMODE_READ | FMODE_WRITE, &s->cow);
-	if (r) {
-		dm_put_device(ti, s->origin);
-		ti->error = "Cannot get COW device";
-		goto bad2;
+		goto bad_origin;
 	}
 
-	r = set_chunk_size(s, argv[3], &ti->error);
-	if (r)
-		goto bad3;
-
-	s->type = persistent;
-
+	s->store = store;
 	s->valid = 1;
 	s->active = 0;
 	atomic_set(&s->pending_exceptions_count, 0);
 	init_rwsem(&s->lock);
 	spin_lock_init(&s->pe_lock);
-	s->ti = ti;
 
 	/* Allocate hash table for COW data */
 	if (init_hash_tables(s)) {
 		ti->error = "Unable to allocate hash table space";
 		r = -ENOMEM;
-		goto bad3;
-	}
-
-	s->store.snap = s;
-
-	if (persistent == 'P')
-		r = dm_create_persistent(&s->store);
-	else
-		r = dm_create_transient(&s->store);
-
-	if (r) {
-		ti->error = "Couldn't create exception store";
-		r = -EINVAL;
-		goto bad4;
+		goto bad_hash_tables;
 	}
 
 	r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
 	if (r) {
 		ti->error = "Could not create kcopyd client";
-		goto bad5;
+		goto bad_kcopyd;
 	}
 
 	s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
 	if (!s->pending_pool) {
 		ti->error = "Could not allocate mempool for pending exceptions";
-		goto bad6;
+		goto bad_pending_pool;
 	}
 
 	s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
@@ -665,7 +655,8 @@ static int snapshot_ctr(struct dm_target
 	spin_lock_init(&s->tracked_chunk_lock);
 
 	/* Metadata must only be loaded into one table at once */
-	r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+	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;
@@ -686,34 +677,33 @@ static int snapshot_ctr(struct dm_target
 	}
 
 	ti->private = s;
-	ti->split_io = s->chunk_size;
+	ti->split_io = s->store->chunk_size;
 
 	return 0;
 
- bad_load_and_register:
+bad_load_and_register:
 	mempool_destroy(s->tracked_chunk_pool);
 
- bad_tracked_chunk_pool:
+bad_tracked_chunk_pool:
 	mempool_destroy(s->pending_pool);
 
- bad6:
+bad_pending_pool:
 	dm_kcopyd_client_destroy(s->kcopyd_client);
 
- bad5:
-	s->store.destroy(&s->store);
-
- bad4:
+bad_kcopyd:
 	exit_exception_table(&s->pending, pending_cache);
 	exit_exception_table(&s->complete, exception_cache);
 
- bad3:
-	dm_put_device(ti, s->cow);
+bad_hash_tables:
 	dm_put_device(ti, s->origin);
 
- bad2:
+bad_origin:
 	kfree(s);
 
- bad1:
+bad_snap:
+	dm_exception_store_destroy(store);
+
+bad_args:
 	return r;
 }
 
@@ -724,8 +714,6 @@ static void __free_exceptions(struct dm_
 
 	exit_exception_table(&s->pending, pending_cache);
 	exit_exception_table(&s->complete, exception_cache);
-
-	s->store.destroy(&s->store);
 }
 
 static void snapshot_dtr(struct dm_target *ti)
@@ -761,7 +749,8 @@ static void snapshot_dtr(struct dm_targe
 	mempool_destroy(s->pending_pool);
 
 	dm_put_device(ti, s->origin);
-	dm_put_device(ti, s->cow);
+
+	dm_exception_store_destroy(s->store);
 
 	kfree(s);
 }
@@ -820,12 +809,12 @@ static void __invalidate_snapshot(struct
 	else if (err == -ENOMEM)
 		DMERR("Invalidating snapshot: Unable to allocate exception.");
 
-	if (s->store.drop_snapshot)
-		s->store.drop_snapshot(&s->store);
+	if (s->store->type->drop_snapshot)
+		s->store->type->drop_snapshot(s->store);
 
 	s->valid = 0;
 
-	dm_table_event(s->ti->table);
+	dm_table_event(s->store->ti->table);
 }
 
 static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -943,8 +932,8 @@ static void copy_callback(int read_err,
 
 	else
 		/* Update the metadata if we are persistent */
-		s->store.commit_exception(&s->store, &pe->e, commit_callback,
-					  pe);
+		s->store->type->commit_exception(s->store, &pe->e,
+						 commit_callback, pe);
 }
 
 /*
@@ -960,11 +949,11 @@ static void start_copy(struct dm_snap_pe
 	dev_size = get_dev_size(bdev);
 
 	src.bdev = bdev;
-	src.sector = chunk_to_sector(s, pe->e.old_chunk);
-	src.count = min(s->chunk_size, dev_size - src.sector);
+	src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
+	src.count = min(s->store->chunk_size, dev_size - src.sector);
 
-	dest.bdev = s->cow->bdev;
-	dest.sector = chunk_to_sector(s, pe->e.new_chunk);
+	dest.bdev = s->store->cow->bdev;
+	dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
 	dest.count = src.count;
 
 	/* Hand over to kcopyd */
@@ -972,6 +961,17 @@ static void start_copy(struct dm_snap_pe
 		    &src, 1, &dest, 0, copy_callback, 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);
+
+	if (!e)
+		return NULL;
+
+	return container_of(e, struct dm_snap_pending_exception, e);
+}
+
 /*
  * Looks to see if this snapshot already has a pending exception
  * for this chunk, otherwise it allocates a new one and inserts
@@ -981,40 +981,15 @@ static void start_copy(struct dm_snap_pe
  * this.
  */
 static struct dm_snap_pending_exception *
-__find_pending_exception(struct dm_snapshot *s, struct bio *bio)
+__find_pending_exception(struct dm_snapshot *s,
+			 struct dm_snap_pending_exception *pe, chunk_t chunk)
 {
-	struct dm_snap_exception *e;
-	struct dm_snap_pending_exception *pe;
-	chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
-
-	/*
-	 * Is there a pending exception for this already ?
-	 */
-	e = lookup_exception(&s->pending, chunk);
-	if (e) {
-		/* cast the exception to a pending exception */
-		pe = container_of(e, struct dm_snap_pending_exception, e);
-		goto out;
-	}
-
-	/*
-	 * Create a new pending exception, we don't want
-	 * to hold the lock while we do this.
-	 */
-	up_write(&s->lock);
-	pe = alloc_pending_exception(s);
-	down_write(&s->lock);
-
-	if (!s->valid) {
-		free_pending_exception(pe);
-		return NULL;
-	}
+	struct dm_snap_pending_exception *pe2;
 
-	e = lookup_exception(&s->pending, chunk);
-	if (e) {
+	pe2 = __lookup_pending_exception(s, chunk);
+	if (pe2) {
 		free_pending_exception(pe);
-		pe = container_of(e, struct dm_snap_pending_exception, e);
-		goto out;
+		return pe2;
 	}
 
 	pe->e.old_chunk = chunk;
@@ -1024,7 +999,7 @@ __find_pending_exception(struct dm_snaps
 	atomic_set(&pe->ref_count, 0);
 	pe->started = 0;
 
-	if (s->store.prepare_exception(&s->store, &pe->e)) {
+	if (s->store->type->prepare_exception(s->store, &pe->e)) {
 		free_pending_exception(pe);
 		return NULL;
 	}
@@ -1032,17 +1007,18 @@ __find_pending_exception(struct dm_snaps
 	get_pending_exception(pe);
 	insert_exception(&s->pending, &pe->e);
 
- out:
 	return pe;
 }
 
 static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
 			    struct bio *bio, chunk_t chunk)
 {
-	bio->bi_bdev = s->cow->bdev;
-	bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
-			 (chunk - e->old_chunk)) +
-			 (bio->bi_sector & s->chunk_mask);
+	bio->bi_bdev = s->store->cow->bdev;
+	bio->bi_sector = chunk_to_sector(s->store,
+					 dm_chunk_number(e->new_chunk) +
+					 (chunk - e->old_chunk)) +
+					 (bio->bi_sector &
+					  s->store->chunk_mask);
 }
 
 static int snapshot_map(struct dm_target *ti, struct bio *bio,
@@ -1054,7 +1030,7 @@ static int snapshot_map(struct dm_target
 	chunk_t chunk;
 	struct dm_snap_pending_exception *pe = NULL;
 
-	chunk = sector_to_chunk(s, bio->bi_sector);
+	chunk = sector_to_chunk(s->store, bio->bi_sector);
 
 	/* Full snapshots are not usable */
 	/* To get here the table must be live so s->active is always set. */
@@ -1083,11 +1059,31 @@ static int snapshot_map(struct dm_target
 	 * writeable.
 	 */
 	if (bio_rw(bio) == WRITE) {
-		pe = __find_pending_exception(s, bio);
+		pe = __lookup_pending_exception(s, chunk);
 		if (!pe) {
-			__invalidate_snapshot(s, -ENOMEM);
-			r = -EIO;
-			goto out_unlock;
+			up_write(&s->lock);
+			pe = alloc_pending_exception(s);
+			down_write(&s->lock);
+
+			if (!s->valid) {
+				free_pending_exception(pe);
+				r = -EIO;
+				goto out_unlock;
+			}
+
+			e = lookup_exception(&s->complete, chunk);
+			if (e) {
+				free_pending_exception(pe);
+				remap_exception(s, e, bio, chunk);
+				goto out_unlock;
+			}
+
+			pe = __find_pending_exception(s, pe, chunk);
+			if (!pe) {
+				__invalidate_snapshot(s, -ENOMEM);
+				r = -EIO;
+				goto out_unlock;
+			}
 		}
 
 		remap_exception(s, &pe->e, bio, chunk);
@@ -1137,24 +1133,25 @@ static void snapshot_resume(struct dm_ta
 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;
 
 	switch (type) {
 	case STATUSTYPE_INFO:
 		if (!snap->valid)
-			snprintf(result, maxlen, "Invalid");
+			DMEMIT("Invalid");
 		else {
-			if (snap->store.fraction_full) {
+			if (snap->store->type->fraction_full) {
 				sector_t numerator, denominator;
-				snap->store.fraction_full(&snap->store,
-							  &numerator,
-							  &denominator);
-				snprintf(result, maxlen, "%llu/%llu",
-					(unsigned long long)numerator,
-					(unsigned long long)denominator);
+				snap->store->type->fraction_full(snap->store,
+								 &numerator,
+								 &denominator);
+				DMEMIT("%llu/%llu",
+				       (unsigned long long)numerator,
+				       (unsigned long long)denominator);
 			}
 			else
-				snprintf(result, maxlen, "Unknown");
+				DMEMIT("Unknown");
 		}
 		break;
 
@@ -1164,10 +1161,9 @@ static int snapshot_status(struct dm_tar
 		 * to make private copies if the output is to
 		 * make sense.
 		 */
-		snprintf(result, maxlen, "%s %s %c %llu",
-			 snap->origin->name, snap->cow->name,
-			 snap->type,
-			 (unsigned long long)snap->chunk_size);
+		DMEMIT("%s", snap->origin->name);
+		snap->store->type->status(snap->store, type, result + sz,
+					  maxlen - sz);
 		break;
 	}
 
@@ -1196,14 +1192,14 @@ 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->ti->table))
+		if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
 			goto next_snapshot;
 
 		/*
 		 * Remember, different snapshots can have
 		 * different chunk sizes.
 		 */
-		chunk = sector_to_chunk(snap, bio->bi_sector);
+		chunk = sector_to_chunk(snap->store, bio->bi_sector);
 
 		/*
 		 * Check exception table to see if block
@@ -1217,10 +1213,28 @@ static int __origin_write(struct list_he
 		if (e)
 			goto next_snapshot;
 
-		pe = __find_pending_exception(snap, bio);
+		pe = __lookup_pending_exception(snap, chunk);
 		if (!pe) {
-			__invalidate_snapshot(snap, -ENOMEM);
-			goto next_snapshot;
+			up_write(&snap->lock);
+			pe = alloc_pending_exception(snap);
+			down_write(&snap->lock);
+
+			if (!snap->valid) {
+				free_pending_exception(pe);
+				goto next_snapshot;
+			}
+
+			e = lookup_exception(&snap->complete, chunk);
+			if (e) {
+				free_pending_exception(pe);
+				goto next_snapshot;
+			}
+
+			pe = __find_pending_exception(snap, pe, chunk);
+			if (!pe) {
+				__invalidate_snapshot(snap, -ENOMEM);
+				goto next_snapshot;
+			}
 		}
 
 		if (!primary_pe) {
@@ -1360,7 +1374,8 @@ static void origin_resume(struct dm_targ
 	o = __lookup_origin(dev->bdev);
 	if (o)
 		list_for_each_entry (snap, &o->snapshots, list)
-			chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+			chunk_size = min_not_zero(chunk_size,
+						  snap->store->chunk_size);
 	up_read(&_origins_lock);
 
 	ti->split_io = chunk_size;
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-snap.h linux-libre-2.6.30-gnu1/drivers/md/dm-snap.h
--- linux-libre-2.6.29-gnu1/drivers/md/dm-snap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-snap.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_SNAPSHOT_H
-#define DM_SNAPSHOT_H
-
-#include <linux/device-mapper.h>
-#include "dm-exception-store.h"
-#include "dm-bio-list.h"
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
-
-struct exception_table {
-	uint32_t hash_mask;
-	unsigned hash_shift;
-	struct list_head *table;
-};
-
-#define DM_TRACKED_CHUNK_HASH_SIZE	16
-#define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
-					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
-
-struct dm_snapshot {
-	struct rw_semaphore lock;
-	struct dm_target *ti;
-
-	struct dm_dev *origin;
-	struct dm_dev *cow;
-
-	/* List of snapshots per Origin */
-	struct list_head list;
-
-	/* Size of data blocks saved - must be a power of 2 */
-	chunk_t chunk_size;
-	chunk_t chunk_mask;
-	chunk_t chunk_shift;
-
-	/* You can't use a snapshot if this is 0 (e.g. if full) */
-	int valid;
-
-	/* Origin writes don't trigger exceptions until this is set */
-	int active;
-
-	/* Used for display of table */
-	char type;
-
-	mempool_t *pending_pool;
-
-	atomic_t pending_exceptions_count;
-
-	struct exception_table pending;
-	struct exception_table complete;
-
-	/*
-	 * pe_lock protects all pending_exception operations and access
-	 * as well as the snapshot_bios list.
-	 */
-	spinlock_t pe_lock;
-
-	/* The on disk metadata handler */
-	struct dm_exception_store store;
-
-	struct dm_kcopyd_client *kcopyd_client;
-
-	/* Queue of snapshot writes for ksnapd to flush */
-	struct bio_list queued_bios;
-	struct work_struct queued_bios_work;
-
-	/* Chunks with outstanding reads */
-	mempool_t *tracked_chunk_pool;
-	spinlock_t tracked_chunk_lock;
-	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
-};
-
-/*
- * Return the number of sectors in the device.
- */
-static inline sector_t get_dev_size(struct block_device *bdev)
-{
-	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
-}
-
-static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
-{
-	return (sector & ~s->chunk_mask) >> s->chunk_shift;
-}
-
-static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
-{
-	return chunk << s->chunk_shift;
-}
-
-static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs)
-{
-	/*
-	 * There is only ever one instance of a particular block
-	 * device so we can compare pointers safely.
-	 */
-	return lhs == rhs;
-}
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-snap-persistent.c linux-libre-2.6.30-gnu1/drivers/md/dm-snap-persistent.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-snap-persistent.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-snap-persistent.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,6 @@
  */
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
 
 #include <linux/mm.h>
 #include <linux/pagemap.h>
@@ -89,7 +88,7 @@ struct commit_callback {
  * The top level structure for a persistent exception store.
  */
 struct pstore {
-	struct dm_snapshot *snap;	/* up pointer to my snapshot */
+	struct dm_exception_store *store;
 	int version;
 	int valid;
 	uint32_t exceptions_per_area;
@@ -141,7 +140,7 @@ static int alloc_area(struct pstore *ps)
 	int r = -ENOMEM;
 	size_t len;
 
-	len = ps->snap->chunk_size << SECTOR_SHIFT;
+	len = ps->store->chunk_size << SECTOR_SHIFT;
 
 	/*
 	 * Allocate the chunk_size block of memory that will hold
@@ -163,9 +162,12 @@ static int alloc_area(struct pstore *ps)
 
 static void free_area(struct pstore *ps)
 {
-	vfree(ps->area);
+	if (ps->area)
+		vfree(ps->area);
 	ps->area = NULL;
-	vfree(ps->zero_area);
+
+	if (ps->zero_area)
+		vfree(ps->zero_area);
 	ps->zero_area = NULL;
 }
 
@@ -189,9 +191,9 @@ static void do_metadata(struct work_stru
 static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
 {
 	struct dm_io_region where = {
-		.bdev = ps->snap->cow->bdev,
-		.sector = ps->snap->chunk_size * chunk,
-		.count = ps->snap->chunk_size,
+		.bdev = ps->store->cow->bdev,
+		.sector = ps->store->chunk_size * chunk,
+		.count = ps->store->chunk_size,
 	};
 	struct dm_io_request io_req = {
 		.bi_rw = rw,
@@ -247,15 +249,15 @@ static int area_io(struct pstore *ps, in
 
 static void zero_memory_area(struct pstore *ps)
 {
-	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+	memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 }
 
 static int zero_disk_area(struct pstore *ps, chunk_t area)
 {
 	struct dm_io_region where = {
-		.bdev = ps->snap->cow->bdev,
-		.sector = ps->snap->chunk_size * area_location(ps, area),
-		.count = ps->snap->chunk_size,
+		.bdev = ps->store->cow->bdev,
+		.sector = ps->store->chunk_size * area_location(ps, area),
+		.count = ps->store->chunk_size,
 	};
 	struct dm_io_request io_req = {
 		.bi_rw = WRITE,
@@ -278,15 +280,15 @@ static int read_header(struct pstore *ps
 	/*
 	 * Use default chunk size (or hardsect_size, if larger) if none supplied
 	 */
-	if (!ps->snap->chunk_size) {
-		ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
-		    bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
-		ps->snap->chunk_mask = ps->snap->chunk_size - 1;
-		ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+	if (!ps->store->chunk_size) {
+		ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+		    bdev_hardsect_size(ps->store->cow->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;
 	}
 
-	ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
+	ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
 							     chunk_size));
 	if (IS_ERR(ps->io_client))
 		return PTR_ERR(ps->io_client);
@@ -317,22 +319,22 @@ static int read_header(struct pstore *ps
 	ps->version = le32_to_cpu(dh->version);
 	chunk_size = le32_to_cpu(dh->chunk_size);
 
-	if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+	if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
 		return 0;
 
 	DMWARN("chunk size %llu in device metadata overrides "
 	       "table chunk size of %llu.",
 	       (unsigned long long)chunk_size,
-	       (unsigned long long)ps->snap->chunk_size);
+	       (unsigned long long)ps->store->chunk_size);
 
 	/* We had a bogus chunk_size. Fix stuff up. */
 	free_area(ps);
 
-	ps->snap->chunk_size = chunk_size;
-	ps->snap->chunk_mask = chunk_size - 1;
-	ps->snap->chunk_shift = ffs(chunk_size) - 1;
+	ps->store->chunk_size = chunk_size;
+	ps->store->chunk_mask = chunk_size - 1;
+	ps->store->chunk_shift = ffs(chunk_size) - 1;
 
-	r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
+	r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
 				ps->io_client);
 	if (r)
 		return r;
@@ -349,13 +351,13 @@ static int write_header(struct pstore *p
 {
 	struct disk_header *dh;
 
-	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+	memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 
 	dh = (struct disk_header *) ps->area;
 	dh->magic = cpu_to_le32(SNAP_MAGIC);
 	dh->valid = cpu_to_le32(ps->valid);
 	dh->version = cpu_to_le32(ps->version);
-	dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+	dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
 
 	return chunk_io(ps, 0, WRITE, 1);
 }
@@ -474,18 +476,25 @@ static struct pstore *get_info(struct dm
 static void persistent_fraction_full(struct dm_exception_store *store,
 				     sector_t *numerator, sector_t *denominator)
 {
-	*numerator = get_info(store)->next_free * store->snap->chunk_size;
-	*denominator = get_dev_size(store->snap->cow->bdev);
+	*numerator = get_info(store)->next_free * store->chunk_size;
+	*denominator = get_dev_size(store->cow->bdev);
 }
 
-static void persistent_destroy(struct dm_exception_store *store)
+static void persistent_dtr(struct dm_exception_store *store)
 {
 	struct pstore *ps = get_info(store);
 
 	destroy_workqueue(ps->metadata_wq);
-	dm_io_client_destroy(ps->io_client);
-	vfree(ps->callbacks);
+
+	/* Created in read_header */
+	if (ps->io_client)
+		dm_io_client_destroy(ps->io_client);
 	free_area(ps);
+
+	/* Allocated in persistent_read_metadata */
+	if (ps->callbacks)
+		vfree(ps->callbacks);
+
 	kfree(ps);
 }
 
@@ -507,7 +516,7 @@ static int persistent_read_metadata(stru
 	/*
 	 * Now we know correct chunk_size, complete the initialisation.
 	 */
-	ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
+	ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) /
 				  sizeof(struct disk_exception);
 	ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
 			sizeof(*ps->callbacks));
@@ -564,10 +573,10 @@ static int persistent_prepare_exception(
 	struct pstore *ps = get_info(store);
 	uint32_t stride;
 	chunk_t next_free;
-	sector_t size = get_dev_size(store->snap->cow->bdev);
+	sector_t size = get_dev_size(store->cow->bdev);
 
 	/* Is there enough room ? */
-	if (size < ((ps->next_free + 1) * store->snap->chunk_size))
+	if (size < ((ps->next_free + 1) * store->chunk_size))
 		return -ENOSPC;
 
 	e->new_chunk = ps->next_free;
@@ -656,16 +665,17 @@ static void persistent_drop_snapshot(str
 		DMWARN("write header failed");
 }
 
-int dm_create_persistent(struct dm_exception_store *store)
+static int persistent_ctr(struct dm_exception_store *store,
+			  unsigned argc, char **argv)
 {
 	struct pstore *ps;
 
 	/* allocate the pstore */
-	ps = kmalloc(sizeof(*ps), GFP_KERNEL);
+	ps = kzalloc(sizeof(*ps), GFP_KERNEL);
 	if (!ps)
 		return -ENOMEM;
 
-	ps->snap = store->snap;
+	ps->store = store;
 	ps->valid = 1;
 	ps->version = SNAPSHOT_DISK_VERSION;
 	ps->area = NULL;
@@ -683,22 +693,77 @@ int dm_create_persistent(struct dm_excep
 		return -ENOMEM;
 	}
 
-	store->destroy = persistent_destroy;
-	store->read_metadata = persistent_read_metadata;
-	store->prepare_exception = persistent_prepare_exception;
-	store->commit_exception = persistent_commit_exception;
-	store->drop_snapshot = persistent_drop_snapshot;
-	store->fraction_full = persistent_fraction_full;
 	store->context = ps;
 
 	return 0;
 }
 
+static unsigned persistent_status(struct dm_exception_store *store,
+				  status_type_t status, char *result,
+				  unsigned maxlen)
+{
+	unsigned sz = 0;
+
+	switch (status) {
+	case STATUSTYPE_INFO:
+		break;
+	case STATUSTYPE_TABLE:
+		DMEMIT(" %s P %llu", store->cow->name,
+		       (unsigned long long)store->chunk_size);
+	}
+
+	return sz;
+}
+
+static struct dm_exception_store_type _persistent_type = {
+	.name = "persistent",
+	.module = THIS_MODULE,
+	.ctr = persistent_ctr,
+	.dtr = persistent_dtr,
+	.read_metadata = persistent_read_metadata,
+	.prepare_exception = persistent_prepare_exception,
+	.commit_exception = persistent_commit_exception,
+	.drop_snapshot = persistent_drop_snapshot,
+	.fraction_full = persistent_fraction_full,
+	.status = persistent_status,
+};
+
+static struct dm_exception_store_type _persistent_compat_type = {
+	.name = "P",
+	.module = THIS_MODULE,
+	.ctr = persistent_ctr,
+	.dtr = persistent_dtr,
+	.read_metadata = persistent_read_metadata,
+	.prepare_exception = persistent_prepare_exception,
+	.commit_exception = persistent_commit_exception,
+	.drop_snapshot = persistent_drop_snapshot,
+	.fraction_full = persistent_fraction_full,
+	.status = persistent_status,
+};
+
 int dm_persistent_snapshot_init(void)
 {
-	return 0;
+	int r;
+
+	r = dm_exception_store_type_register(&_persistent_type);
+	if (r) {
+		DMERR("Unable to register persistent exception store type");
+		return r;
+	}
+
+	r = dm_exception_store_type_register(&_persistent_compat_type);
+	if (r) {
+		DMERR("Unable to register old-style persistent exception "
+		      "store type");
+		dm_exception_store_type_unregister(&_persistent_type);
+		return r;
+	}
+
+	return r;
 }
 
 void dm_persistent_snapshot_exit(void)
 {
+	dm_exception_store_type_unregister(&_persistent_type);
+	dm_exception_store_type_unregister(&_persistent_compat_type);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-snap-transient.c linux-libre-2.6.30-gnu1/drivers/md/dm-snap-transient.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-snap-transient.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-snap-transient.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,6 @@
  */
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
 
 #include <linux/mm.h>
 #include <linux/pagemap.h>
@@ -23,7 +22,7 @@ struct transient_c {
 	sector_t next_free;
 };
 
-static void transient_destroy(struct dm_exception_store *store)
+static void transient_dtr(struct dm_exception_store *store)
 {
 	kfree(store->context);
 }
@@ -39,14 +38,14 @@ static int transient_read_metadata(struc
 static int transient_prepare_exception(struct dm_exception_store *store,
 				       struct dm_snap_exception *e)
 {
-	struct transient_c *tc = (struct transient_c *) store->context;
-	sector_t size = get_dev_size(store->snap->cow->bdev);
+	struct transient_c *tc = store->context;
+	sector_t size = get_dev_size(store->cow->bdev);
 
-	if (size < (tc->next_free + store->snap->chunk_size))
+	if (size < (tc->next_free + store->chunk_size))
 		return -1;
 
-	e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
-	tc->next_free += store->snap->chunk_size;
+	e->new_chunk = sector_to_chunk(store, tc->next_free);
+	tc->next_free += store->chunk_size;
 
 	return 0;
 }
@@ -64,20 +63,14 @@ static void transient_fraction_full(stru
 				    sector_t *numerator, sector_t *denominator)
 {
 	*numerator = ((struct transient_c *) store->context)->next_free;
-	*denominator = get_dev_size(store->snap->cow->bdev);
+	*denominator = get_dev_size(store->cow->bdev);
 }
 
-int dm_create_transient(struct dm_exception_store *store)
+static int transient_ctr(struct dm_exception_store *store,
+			 unsigned argc, char **argv)
 {
 	struct transient_c *tc;
 
-	store->destroy = transient_destroy;
-	store->read_metadata = transient_read_metadata;
-	store->prepare_exception = transient_prepare_exception;
-	store->commit_exception = transient_commit_exception;
-	store->drop_snapshot = NULL;
-	store->fraction_full = transient_fraction_full;
-
 	tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
 	if (!tc)
 		return -ENOMEM;
@@ -88,11 +81,70 @@ int dm_create_transient(struct dm_except
 	return 0;
 }
 
+static unsigned transient_status(struct dm_exception_store *store,
+				 status_type_t status, char *result,
+				 unsigned maxlen)
+{
+	unsigned sz = 0;
+
+	switch (status) {
+	case STATUSTYPE_INFO:
+		break;
+	case STATUSTYPE_TABLE:
+		DMEMIT(" %s N %llu", store->cow->name,
+		       (unsigned long long)store->chunk_size);
+	}
+
+	return sz;
+}
+
+static struct dm_exception_store_type _transient_type = {
+	.name = "transient",
+	.module = THIS_MODULE,
+	.ctr = transient_ctr,
+	.dtr = transient_dtr,
+	.read_metadata = transient_read_metadata,
+	.prepare_exception = transient_prepare_exception,
+	.commit_exception = transient_commit_exception,
+	.fraction_full = transient_fraction_full,
+	.status = transient_status,
+};
+
+static struct dm_exception_store_type _transient_compat_type = {
+	.name = "N",
+	.module = THIS_MODULE,
+	.ctr = transient_ctr,
+	.dtr = transient_dtr,
+	.read_metadata = transient_read_metadata,
+	.prepare_exception = transient_prepare_exception,
+	.commit_exception = transient_commit_exception,
+	.fraction_full = transient_fraction_full,
+	.status = transient_status,
+};
+
 int dm_transient_snapshot_init(void)
 {
-	return 0;
+	int r;
+
+	r = dm_exception_store_type_register(&_transient_type);
+	if (r) {
+		DMWARN("Unable to register transient exception store type");
+		return r;
+	}
+
+	r = dm_exception_store_type_register(&_transient_compat_type);
+	if (r) {
+		DMWARN("Unable to register old-style transient "
+		       "exception store type");
+		dm_exception_store_type_unregister(&_transient_type);
+		return r;
+	}
+
+	return r;
 }
 
 void dm_transient_snapshot_exit(void)
 {
+	dm_exception_store_type_unregister(&_transient_type);
+	dm_exception_store_type_unregister(&_transient_compat_type);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-table.c linux-libre-2.6.30-gnu1/drivers/md/dm-table.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-table.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-table.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,8 +52,6 @@ struct dm_table {
 	sector_t *highs;
 	struct dm_target *targets;
 
-	unsigned barriers_supported:1;
-
 	/*
 	 * Indicates the rw permissions for the new logical
 	 * device.  This should be a combination of FMODE_READ
@@ -243,7 +241,6 @@ int dm_table_create(struct dm_table **re
 
 	INIT_LIST_HEAD(&t->devices);
 	atomic_set(&t->holders, 0);
-	t->barriers_supported = 1;
 
 	if (!num_targets)
 		num_targets = KEYS_PER_NODE;
@@ -399,28 +396,30 @@ static int check_device_area(struct dm_d
 }
 
 /*
- * This upgrades the mode on an already open dm_dev.  Being
+ * This upgrades the mode on an already open dm_dev, being
  * careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
  */
 static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
 			struct mapped_device *md)
 {
 	int r;
-	struct dm_dev_internal dd_copy;
-	dev_t dev = dd->dm_dev.bdev->bd_dev;
+	struct dm_dev_internal dd_new, dd_old;
 
-	dd_copy = *dd;
+	dd_new = dd_old = *dd;
+
+	dd_new.dm_dev.mode |= new_mode;
+	dd_new.dm_dev.bdev = NULL;
+
+	r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+	if (r)
+		return r;
 
 	dd->dm_dev.mode |= new_mode;
-	dd->dm_dev.bdev = NULL;
-	r = open_dev(dd, dev, md);
-	if (!r)
-		close_dev(&dd_copy, md);
-	else
-		*dd = dd_copy;
+	close_dev(&dd_old, md);
 
-	return r;
+	return 0;
 }
 
 /*
@@ -749,10 +748,6 @@ int dm_table_add_target(struct dm_table
 	/* FIXME: the plan is to combine high here and then have
 	 * the merge fn apply the target level restrictions. */
 	combine_restrictions_low(&t->limits, &tgt->limits);
-
-	if (!(tgt->type->features & DM_TARGET_SUPPORTS_BARRIERS))
-		t->barriers_supported = 0;
-
 	return 0;
 
  bad:
@@ -797,12 +792,6 @@ int dm_table_complete(struct dm_table *t
 
 	check_for_valid_limits(&t->limits);
 
-	/*
-	 * We only support barriers if there is exactly one underlying device.
-	 */
-	if (!list_is_singular(&t->devices))
-		t->barriers_supported = 0;
-
 	/* how many indexes will the btree have ? */
 	leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE);
 	t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE);
@@ -877,6 +866,45 @@ struct dm_target *dm_table_find_target(s
 	return &t->targets[(KEYS_PER_NODE * n) + k];
 }
 
+/*
+ * Set the integrity profile for this device if all devices used have
+ * matching profiles.
+ */
+static void dm_table_set_integrity(struct dm_table *t)
+{
+	struct list_head *devices = dm_table_get_devices(t);
+	struct dm_dev_internal *prev = NULL, *dd = NULL;
+
+	if (!blk_get_integrity(dm_disk(t->md)))
+		return;
+
+	list_for_each_entry(dd, devices, list) {
+		if (prev &&
+		    blk_integrity_compare(prev->dm_dev.bdev->bd_disk,
+					  dd->dm_dev.bdev->bd_disk) < 0) {
+			DMWARN("%s: integrity not set: %s and %s mismatch",
+			       dm_device_name(t->md),
+			       prev->dm_dev.bdev->bd_disk->disk_name,
+			       dd->dm_dev.bdev->bd_disk->disk_name);
+			goto no_integrity;
+		}
+		prev = dd;
+	}
+
+	if (!prev || !bdev_get_integrity(prev->dm_dev.bdev))
+		goto no_integrity;
+
+	blk_integrity_register(dm_disk(t->md),
+			       bdev_get_integrity(prev->dm_dev.bdev));
+
+	return;
+
+no_integrity:
+	blk_integrity_register(dm_disk(t->md), NULL);
+
+	return;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q)
 {
 	/*
@@ -897,6 +925,7 @@ void dm_table_set_restrictions(struct dm
 	else
 		queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
 
+	dm_table_set_integrity(t);
 }
 
 unsigned int dm_table_get_num_targets(struct dm_table *t)
@@ -1017,12 +1046,6 @@ struct mapped_device *dm_table_get_md(st
 	return t->md;
 }
 
-int dm_table_barrier_ok(struct dm_table *t)
-{
-	return t->barriers_supported;
-}
-EXPORT_SYMBOL(dm_table_barrier_ok);
-
 EXPORT_SYMBOL(dm_vcalloc);
 EXPORT_SYMBOL(dm_get_device);
 EXPORT_SYMBOL(dm_put_device);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/dm-target.c linux-libre-2.6.30-gnu1/drivers/md/dm-target.c
--- linux-libre-2.6.29-gnu1/drivers/md/dm-target.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/dm-target.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,45 +14,34 @@
 
 #define DM_MSG_PREFIX "target"
 
-struct tt_internal {
-	struct target_type tt;
-
-	struct list_head list;
-	long use;
-};
-
 static LIST_HEAD(_targets);
 static DECLARE_RWSEM(_lock);
 
 #define DM_MOD_NAME_SIZE 32
 
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
-	list_for_each_entry (ti, &_targets, list)
-		if (!strcmp(name, ti->tt.name))
-			return ti;
+	list_for_each_entry(tt, &_targets, list)
+		if (!strcmp(name, tt->name))
+			return tt;
 
 	return NULL;
 }
 
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
 	down_read(&_lock);
 
-	ti = __find_target_type(name);
-	if (ti) {
-		if ((ti->use == 0) && !try_module_get(ti->tt.module))
-			ti = NULL;
-		else
-			ti->use++;
-	}
+	tt = __find_target_type(name);
+	if (tt && !try_module_get(tt->module))
+		tt = NULL;
 
 	up_read(&_lock);
-	return ti;
+	return tt;
 }
 
 static void load_module(const char *name)
@@ -62,92 +51,59 @@ static void load_module(const char *name
 
 struct target_type *dm_get_target_type(const char *name)
 {
-	struct tt_internal *ti = get_target_type(name);
+	struct target_type *tt = get_target_type(name);
 
-	if (!ti) {
+	if (!tt) {
 		load_module(name);
-		ti = get_target_type(name);
+		tt = get_target_type(name);
 	}
 
-	return ti ? &ti->tt : NULL;
+	return tt;
 }
 
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
 {
-	struct tt_internal *ti = (struct tt_internal *) t;
-
 	down_read(&_lock);
-	if (--ti->use == 0)
-		module_put(ti->tt.module);
-
-	BUG_ON(ti->use < 0);
+	module_put(tt->module);
 	up_read(&_lock);
-
-	return;
 }
 
-static struct tt_internal *alloc_target(struct target_type *t)
-{
-	struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
-	if (ti)
-		ti->tt = *t;
-
-	return ti;
-}
-
-
 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
 					void *param), void *param)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
 	down_read(&_lock);
-	list_for_each_entry (ti, &_targets, list)
-		iter_func(&ti->tt, param);
+	list_for_each_entry(tt, &_targets, list)
+		iter_func(tt, param);
 	up_read(&_lock);
 
 	return 0;
 }
 
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
 {
 	int rv = 0;
-	struct tt_internal *ti = alloc_target(t);
-
-	if (!ti)
-		return -ENOMEM;
 
 	down_write(&_lock);
-	if (__find_target_type(t->name))
+	if (__find_target_type(tt->name))
 		rv = -EEXIST;
 	else
-		list_add(&ti->list, &_targets);
+		list_add(&tt->list, &_targets);
 
 	up_write(&_lock);
-	if (rv)
-		kfree(ti);
 	return rv;
 }
 
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
 {
-	struct tt_internal *ti;
-
 	down_write(&_lock);
-	if (!(ti = __find_target_type(t->name))) {
-		DMCRIT("Unregistering unrecognised target: %s", t->name);
-		BUG();
-	}
-
-	if (ti->use) {
-		DMCRIT("Attempt to unregister target still in use: %s",
-		       t->name);
+	if (!__find_target_type(tt->name)) {
+		DMCRIT("Unregistering unrecognised target: %s", tt->name);
 		BUG();
 	}
 
-	list_del(&ti->list);
-	kfree(ti);
+	list_del(&tt->list);
 
 	up_write(&_lock);
 }
@@ -156,17 +112,17 @@ void dm_unregister_target(struct target_
  * io-err: always fails an io, useful for bringing
  * up LVs that have holes in them.
  */
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
 {
 	return 0;
 }
 
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
 {
 	/* empty */
 }
 
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
 		      union map_info *map_context)
 {
 	return -EIO;
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/faulty.c linux-libre-2.6.30-gnu1/drivers/md/faulty.c
--- linux-libre-2.6.29-gnu1/drivers/md/faulty.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/faulty.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,7 +62,10 @@
 #define	ModeShift	5
 
 #define MaxFault	50
-#include <linux/raid/md.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include <linux/seq_file.h>
 
 
 static void faulty_fail(struct bio *bio, int error)
@@ -280,6 +283,17 @@ static int reconfig(mddev_t *mddev, int
 	return 0;
 }
 
+static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	WARN_ONCE(raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	if (sectors == 0)
+		return mddev->dev_sectors;
+
+	return sectors;
+}
+
 static int run(mddev_t *mddev)
 {
 	mdk_rdev_t *rdev;
@@ -298,7 +312,7 @@ static int run(mddev_t *mddev)
 	list_for_each_entry(rdev, &mddev->disks, same_set)
 		conf->rdev = rdev;
 
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
 	mddev->private = conf;
 
 	reconfig(mddev, mddev->layout, -1);
@@ -325,6 +339,7 @@ static struct mdk_personality faulty_per
 	.stop		= stop,
 	.status		= status,
 	.reconfig	= reconfig,
+	.size		= faulty_size,
 };
 
 static int __init raid_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/Kconfig linux-libre-2.6.30-gnu1/drivers/md/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/md/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -121,6 +121,7 @@ config MD_RAID10
 config MD_RAID456
 	tristate "RAID-4/RAID-5/RAID-6 mode"
 	depends on BLK_DEV_MD
+	select MD_RAID6_PQ
 	select ASYNC_MEMCPY
 	select ASYNC_XOR
 	---help---
@@ -151,34 +152,8 @@ config MD_RAID456
 
 	  If unsure, say Y.
 
-config MD_RAID5_RESHAPE
-	bool "Support adding drives to a raid-5 array"
-	depends on MD_RAID456
-	default y
-	---help---
-	  A RAID-5 set can be expanded by adding extra drives. This
-	  requires "restriping" the array which means (almost) every
-	  block must be written to a different place.
-
-          This option allows such restriping to be done while the array
-	  is online.
-
-	  You will need mdadm version 2.4.1 or later to use this
-	  feature safely.  During the early stage of reshape there is
-	  a critical section where live data is being over-written.  A
-	  crash during this time needs extra care for recovery.  The
-	  newer mdadm takes a copy of the data in the critical section
-	  and will restore it, if necessary, after a crash.
-
-	  The mdadm usage is e.g.
-	       mdadm --grow /dev/md1 --raid-disks=6
-	  to grow '/dev/md1' to having 6 disks.
-
-	  Note: The array can only be expanded, not contracted.
-	  There should be enough spares already present to make the new
-	  array workable.
-
-	  If unsure, say Y.
+config MD_RAID6_PQ
+	tristate
 
 config MD_MULTIPATH
 	tristate "Multipath I/O support"
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/linear.c linux-libre-2.6.30-gnu1/drivers/md/linear.c
--- linux-libre-2.6.29-gnu1/drivers/md/linear.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/linear.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,11 @@
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/raid/linear.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "linear.h"
 
 /*
  * find which device holds a particular offset 
@@ -97,6 +101,16 @@ static int linear_congested(void *data,
 	return ret;
 }
 
+static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	linear_conf_t *conf = mddev_to_conf(mddev);
+
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	return conf->array_sectors;
+}
+
 static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
 {
 	linear_conf_t *conf;
@@ -135,8 +149,8 @@ static linear_conf_t *linear_conf(mddev_
 		    mddev->queue->max_sectors > (PAGE_SIZE>>9))
 			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
-		disk->num_sectors = rdev->size * 2;
-		conf->array_sectors += rdev->size * 2;
+		disk->num_sectors = rdev->sectors;
+		conf->array_sectors += rdev->sectors;
 
 		cnt++;
 	}
@@ -249,7 +263,7 @@ static int linear_run (mddev_t *mddev)
 	if (!conf)
 		return 1;
 	mddev->private = conf;
-	mddev->array_sectors = conf->array_sectors;
+	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 
 	blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
 	mddev->queue->unplug_fn = linear_unplug;
@@ -283,7 +297,7 @@ static int linear_add(mddev_t *mddev, md
 	newconf->prev = mddev_to_conf(mddev);
 	mddev->private = newconf;
 	mddev->raid_disks++;
-	mddev->array_sectors = newconf->array_sectors;
+	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	return 0;
 }
@@ -381,6 +395,7 @@ static struct mdk_personality linear_per
 	.stop		= linear_stop,
 	.status		= linear_status,
 	.hot_add_disk	= linear_add,
+	.size		= linear_size,
 };
 
 static int __init linear_init (void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/linear.h linux-libre-2.6.30-gnu1/drivers/md/linear.h
--- linux-libre-2.6.29-gnu1/drivers/md/linear.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/linear.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct dev_info {
+	mdk_rdev_t	*rdev;
+	sector_t	num_sectors;
+	sector_t	start_sector;
+};
+
+typedef struct dev_info dev_info_t;
+
+struct linear_private_data
+{
+	struct linear_private_data *prev;	/* earlier version */
+	dev_info_t		**hash_table;
+	sector_t		spacing;
+	sector_t		array_sectors;
+	int			sector_shift;	/* shift before dividing
+						 * by spacing
+						 */
+	dev_info_t		disks[0];
+};
+
+
+typedef struct linear_private_data linear_conf_t;
+
+#define mddev_to_conf(mddev) ((linear_conf_t *) mddev->private)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/Makefile linux-libre-2.6.30-gnu1/drivers/md/Makefile
--- linux-libre-2.6.29-gnu1/drivers/md/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,20 +2,21 @@
 # Makefile for the kernel software RAID and LVM drivers.
 #
 
-dm-mod-objs	:= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
+dm-mod-y	+= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
 		   dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
-dm-multipath-objs := dm-path-selector.o dm-mpath.o
-dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-snap-transient.o \
+dm-multipath-y	+= dm-path-selector.o dm-mpath.o
+dm-snapshot-y	+= dm-snap.o dm-exception-store.o dm-snap-transient.o \
 		    dm-snap-persistent.o
-dm-mirror-objs	:= dm-raid1.o
-md-mod-objs     := md.o bitmap.o
-raid456-objs	:= raid5.o raid6algos.o raid6recov.o raid6tables.o \
+dm-mirror-y	+= dm-raid1.o
+md-mod-y	+= md.o bitmap.o
+raid456-y	+= raid5.o
+raid6_pq-y	+= raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
 		   raid6int8.o raid6int16.o raid6int32.o \
 		   raid6altivec1.o raid6altivec2.o raid6altivec4.o \
 		   raid6altivec8.o \
 		   raid6mmx.o raid6sse1.o raid6sse2.o
-hostprogs-y	:= mktables
+hostprogs-y	+= mktables
 
 # Note: link order is important.  All raid personalities
 # and must come before md.o, as they each initialise 
@@ -26,6 +27,7 @@ obj-$(CONFIG_MD_LINEAR)		+= linear.o
 obj-$(CONFIG_MD_RAID0)		+= raid0.o
 obj-$(CONFIG_MD_RAID1)		+= raid1.o
 obj-$(CONFIG_MD_RAID10)		+= raid10.o
+obj-$(CONFIG_MD_RAID6_PQ)	+= raid6_pq.o
 obj-$(CONFIG_MD_RAID456)	+= raid456.o
 obj-$(CONFIG_MD_MULTIPATH)	+= multipath.o
 obj-$(CONFIG_MD_FAULTY)		+= faulty.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/md.c linux-libre-2.6.30-gnu1/drivers/md/md.c
--- linux-libre-2.6.29-gnu1/drivers/md/md.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/md.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,9 +33,9 @@
 */
 
 #include <linux/kthread.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
 #include <linux/sysctl.h>
+#include <linux/seq_file.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/poll.h>
 #include <linux/ctype.h>
@@ -45,11 +45,10 @@
 #include <linux/reboot.h>
 #include <linux/file.h>
 #include <linux/delay.h>
-
-#define MAJOR_NR MD_MAJOR
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include "bitmap.h"
 
 #define DEBUG 0
 #define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -202,12 +201,68 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
 		)
 
 
-static int md_fail_request(struct request_queue *q, struct bio *bio)
+/* Rather than calling directly into the personality make_request function,
+ * IO requests come here first so that we can check if the device is
+ * being suspended pending a reconfiguration.
+ * We hold a refcount over the call to ->make_request.  By the time that
+ * call has finished, the bio has been linked into some internal structure
+ * and so is visible to ->quiesce(), so we don't need the refcount any more.
+ */
+static int md_make_request(struct request_queue *q, struct bio *bio)
 {
-	bio_io_error(bio);
-	return 0;
+	mddev_t *mddev = q->queuedata;
+	int rv;
+	if (mddev == NULL || mddev->pers == NULL) {
+		bio_io_error(bio);
+		return 0;
+	}
+	rcu_read_lock();
+	if (mddev->suspended) {
+		DEFINE_WAIT(__wait);
+		for (;;) {
+			prepare_to_wait(&mddev->sb_wait, &__wait,
+					TASK_UNINTERRUPTIBLE);
+			if (!mddev->suspended)
+				break;
+			rcu_read_unlock();
+			schedule();
+			rcu_read_lock();
+		}
+		finish_wait(&mddev->sb_wait, &__wait);
+	}
+	atomic_inc(&mddev->active_io);
+	rcu_read_unlock();
+	rv = mddev->pers->make_request(q, bio);
+	if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
+		wake_up(&mddev->sb_wait);
+
+	return rv;
 }
 
+static void mddev_suspend(mddev_t *mddev)
+{
+	BUG_ON(mddev->suspended);
+	mddev->suspended = 1;
+	synchronize_rcu();
+	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
+	mddev->pers->quiesce(mddev, 1);
+	md_unregister_thread(mddev->thread);
+	mddev->thread = NULL;
+	/* we now know that no code is executing in the personality module,
+	 * except possibly the tail end of a ->bi_end_io function, but that
+	 * is certain to complete before the module has a chance to get
+	 * unloaded
+	 */
+}
+
+static void mddev_resume(mddev_t *mddev)
+{
+	mddev->suspended = 0;
+	wake_up(&mddev->sb_wait);
+	mddev->pers->quiesce(mddev, 0);
+}
+
+
 static inline mddev_t *mddev_get(mddev_t *mddev)
 {
 	atomic_inc(&mddev->active);
@@ -310,6 +365,7 @@ static mddev_t * mddev_find(dev_t unit)
 	init_timer(&new->safemode_timer);
 	atomic_set(&new->active, 1);
 	atomic_set(&new->openers, 0);
+	atomic_set(&new->active_io, 0);
 	spin_lock_init(&new->write_lock);
 	init_waitqueue_head(&new->sb_wait);
 	init_waitqueue_head(&new->recovery_wait);
@@ -326,6 +382,11 @@ static inline int mddev_lock(mddev_t * m
 	return mutex_lock_interruptible(&mddev->reconfig_mutex);
 }
 
+static inline int mddev_is_locked(mddev_t *mddev)
+{
+	return mutex_is_locked(&mddev->reconfig_mutex);
+}
+
 static inline int mddev_trylock(mddev_t * mddev)
 {
 	return mutex_trylock(&mddev->reconfig_mutex);
@@ -409,7 +470,7 @@ static void free_disk_sb(mdk_rdev_t * rd
 		rdev->sb_loaded = 0;
 		rdev->sb_page = NULL;
 		rdev->sb_start = 0;
-		rdev->size = 0;
+		rdev->sectors = 0;
 	}
 }
 
@@ -775,9 +836,9 @@ static int super_90_load(mdk_rdev_t *rde
 		else 
 			ret = 0;
 	}
-	rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
+	rdev->sectors = calc_num_sectors(rdev, sb->chunk_size);
 
-	if (rdev->size < sb->size && sb->level > 1)
+	if (rdev->sectors < sb->size * 2 && sb->level > 1)
 		/* "this cannot possibly happen" ... */
 		ret = -EINVAL;
 
@@ -812,7 +873,7 @@ static int super_90_validate(mddev_t *md
 		mddev->clevel[0] = 0;
 		mddev->layout = sb->layout;
 		mddev->raid_disks = sb->raid_disks;
-		mddev->size = sb->size;
+		mddev->dev_sectors = sb->size * 2;
 		mddev->events = ev1;
 		mddev->bitmap_offset = 0;
 		mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -926,7 +987,7 @@ static void super_90_sync(mddev_t *mddev
 
 	sb->ctime = mddev->ctime;
 	sb->level = mddev->level;
-	sb->size  = mddev->size;
+	sb->size = mddev->dev_sectors / 2;
 	sb->raid_disks = mddev->raid_disks;
 	sb->md_minor = mddev->md_minor;
 	sb->not_persistent = 0;
@@ -1024,7 +1085,7 @@ static void super_90_sync(mddev_t *mddev
 static unsigned long long
 super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
 {
-	if (num_sectors && num_sectors < rdev->mddev->size * 2)
+	if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
 		return 0; /* component must fit device */
 	if (rdev->mddev->bitmap_offset)
 		return 0; /* can't move bitmap */
@@ -1180,16 +1241,17 @@ static int super_1_load(mdk_rdev_t *rdev
 			ret = 0;
 	}
 	if (minor_version)
-		rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
+		rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+			le64_to_cpu(sb->data_offset);
 	else
-		rdev->size = rdev->sb_start / 2;
-	if (rdev->size < le64_to_cpu(sb->data_size)/2)
+		rdev->sectors = rdev->sb_start;
+	if (rdev->sectors < le64_to_cpu(sb->data_size))
 		return -EINVAL;
-	rdev->size = le64_to_cpu(sb->data_size)/2;
+	rdev->sectors = le64_to_cpu(sb->data_size);
 	if (le32_to_cpu(sb->chunksize))
-		rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+		rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
 
-	if (le64_to_cpu(sb->size) > rdev->size*2)
+	if (le64_to_cpu(sb->size) > rdev->sectors)
 		return -EINVAL;
 	return ret;
 }
@@ -1216,7 +1278,7 @@ static int super_1_validate(mddev_t *mdd
 		mddev->clevel[0] = 0;
 		mddev->layout = le32_to_cpu(sb->layout);
 		mddev->raid_disks = le32_to_cpu(sb->raid_disks);
-		mddev->size = le64_to_cpu(sb->size)/2;
+		mddev->dev_sectors = le64_to_cpu(sb->size);
 		mddev->events = ev1;
 		mddev->bitmap_offset = 0;
 		mddev->default_bitmap_offset = 1024 >> 9;
@@ -1312,7 +1374,10 @@ static void super_1_sync(mddev_t *mddev,
 	sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
 	sb->raid_disks = cpu_to_le32(mddev->raid_disks);
-	sb->size = cpu_to_le64(mddev->size<<1);
+	sb->size = cpu_to_le64(mddev->dev_sectors);
+	sb->chunksize = cpu_to_le32(mddev->chunk_size >> 9);
+	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);
@@ -1320,10 +1385,15 @@ static void super_1_sync(mddev_t *mddev,
 	}
 
 	if (rdev->raid_disk >= 0 &&
-	    !test_bit(In_sync, &rdev->flags) &&
-	    rdev->recovery_offset > 0) {
-		sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
-		sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
+	    !test_bit(In_sync, &rdev->flags)) {
+		if (mddev->curr_resync_completed > rdev->recovery_offset)
+			rdev->recovery_offset = mddev->curr_resync_completed;
+		if (rdev->recovery_offset > 0) {
+			sb->feature_map |=
+				cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+			sb->recovery_offset =
+				cpu_to_le64(rdev->recovery_offset);
+		}
 	}
 
 	if (mddev->reshape_position != MaxSector) {
@@ -1365,7 +1435,7 @@ super_1_rdev_size_change(mdk_rdev_t *rde
 {
 	struct mdp_superblock_1 *sb;
 	sector_t max_sectors;
-	if (num_sectors && num_sectors < rdev->mddev->size * 2)
+	if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
 		return 0; /* component must fit device */
 	if (rdev->sb_start < rdev->data_offset) {
 		/* minor versions 1 and 2; superblock before data */
@@ -1381,7 +1451,7 @@ super_1_rdev_size_change(mdk_rdev_t *rde
 		sector_t sb_start;
 		sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
 		sb_start &= ~(sector_t)(4*2 - 1);
-		max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+		max_sectors = rdev->sectors + sb_start - rdev->sb_start;
 		if (!num_sectors || num_sectors > max_sectors)
 			num_sectors = max_sectors;
 		rdev->sb_start = sb_start;
@@ -1433,6 +1503,38 @@ static int match_mddev_units(mddev_t *md
 
 static LIST_HEAD(pending_raid_disks);
 
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+	struct mdk_personality *pers = mddev->pers;
+	struct gendisk *disk = mddev->gendisk;
+	struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+	struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+	/* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+	if (pers && pers->level >= 4 && pers->level <= 6)
+		return;
+
+	/* If rdev is integrity capable, register profile for mddev */
+	if (!bi_mddev && bi_rdev) {
+		if (blk_integrity_register(disk, bi_rdev))
+			printk(KERN_ERR "%s: %s Could not register integrity!\n",
+			       __func__, disk->disk_name);
+		else
+			printk(KERN_NOTICE "Enabling data integrity on %s\n",
+			       disk->disk_name);
+		return;
+	}
+
+	/* Check that mddev and rdev have matching profiles */
+	if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+		printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+		       disk->disk_name, rdev->bdev->bd_disk->disk_name);
+		printk(KERN_NOTICE "Disabling data integrity on %s\n",
+		       disk->disk_name);
+		blk_integrity_unregister(disk);
+	}
+}
+
 static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
 	char b[BDEVNAME_SIZE];
@@ -1449,8 +1551,9 @@ static int bind_rdev_to_array(mdk_rdev_t
 	if (find_rdev(mddev, rdev->bdev->bd_dev))
 		return -EEXIST;
 
-	/* make sure rdev->size exceeds mddev->size */
-	if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+	/* make sure rdev->sectors exceeds mddev->dev_sectors */
+	if (rdev->sectors && (mddev->dev_sectors == 0 ||
+			rdev->sectors < mddev->dev_sectors)) {
 		if (mddev->pers) {
 			/* Cannot change size, so fail
 			 * If mddev->level <= 0, then we don't care
@@ -1459,7 +1562,7 @@ static int bind_rdev_to_array(mdk_rdev_t
 			if (mddev->level > 0)
 				return -ENOSPC;
 		} else
-			mddev->size = rdev->size;
+			mddev->dev_sectors = rdev->sectors;
 	}
 
 	/* Verify rdev->desc_nr is unique.
@@ -1503,6 +1606,8 @@ static int bind_rdev_to_array(mdk_rdev_t
 
 	/* May as well allow recovery to be retried once */
 	mddev->recovery_disabled = 0;
+
+	md_integrity_check(rdev, mddev);
 	return 0;
 
  fail:
@@ -1713,8 +1818,8 @@ static void print_sb_1(struct mdp_superb
 static void print_rdev(mdk_rdev_t *rdev, int major_version)
 {
 	char b[BDEVNAME_SIZE];
-	printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
-		bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
+	printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n",
+		bdevname(rdev->bdev, b), (unsigned long long)rdev->sectors,
 	        test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
 	        rdev->desc_nr);
 	if (rdev->sb_loaded) {
@@ -1915,6 +2020,8 @@ repeat:
 	clear_bit(MD_CHANGE_PENDING, &mddev->flags);
 	spin_unlock_irq(&mddev->write_lock);
 	wake_up(&mddev->sb_wait);
+	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 
 }
 
@@ -1984,6 +2091,7 @@ state_store(mdk_rdev_t *rdev, const char
 	 *  -writemostly - clears write_mostly
 	 *  blocked - sets the Blocked flag
 	 *  -blocked - clears the Blocked flag
+	 *  insync - sets Insync providing device isn't active
 	 */
 	int err = -EINVAL;
 	if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
@@ -2016,6 +2124,9 @@ state_store(mdk_rdev_t *rdev, const char
 		md_wakeup_thread(rdev->mddev->thread);
 
 		err = 0;
+	} else if (cmd_match(buf, "insync") && rdev->raid_disk == -1) {
+		set_bit(In_sync, &rdev->flags);
+		err = 0;
 	}
 	if (!err && rdev->sysfs_state)
 		sysfs_notify_dirent(rdev->sysfs_state);
@@ -2088,7 +2199,7 @@ slot_store(mdk_rdev_t *rdev, const char
 	} else if (rdev->mddev->pers) {
 		mdk_rdev_t *rdev2;
 		/* Activating a spare .. or possibly reactivating
-		 * if we every get bitmaps working here.
+		 * if we ever get bitmaps working here.
 		 */
 
 		if (rdev->raid_disk != -1)
@@ -2153,7 +2264,7 @@ offset_store(mdk_rdev_t *rdev, const cha
 		return -EINVAL;
 	if (rdev->mddev->pers && rdev->raid_disk >= 0)
 		return -EBUSY;
-	if (rdev->size && rdev->mddev->external)
+	if (rdev->sectors && rdev->mddev->external)
 		/* Must set offset before size, so overlap checks
 		 * can be sane */
 		return -EBUSY;
@@ -2167,7 +2278,7 @@ __ATTR(offset, S_IRUGO|S_IWUSR, offset_s
 static ssize_t
 rdev_size_show(mdk_rdev_t *rdev, char *page)
 {
-	return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+	return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2);
 }
 
 static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
@@ -2180,34 +2291,52 @@ static int overlaps(sector_t s1, sector_
 	return 1;
 }
 
+static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
+{
+	unsigned long long blocks;
+	sector_t new;
+
+	if (strict_strtoull(buf, 10, &blocks) < 0)
+		return -EINVAL;
+
+	if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
+		return -EINVAL; /* sector conversion overflow */
+
+	new = blocks * 2;
+	if (new != blocks * 2)
+		return -EINVAL; /* unsigned long long to sector_t overflow */
+
+	*sectors = new;
+	return 0;
+}
+
 static ssize_t
 rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 {
-	unsigned long long size;
-	unsigned long long oldsize = rdev->size;
 	mddev_t *my_mddev = rdev->mddev;
+	sector_t oldsectors = rdev->sectors;
+	sector_t sectors;
 
-	if (strict_strtoull(buf, 10, &size) < 0)
+	if (strict_blocks_to_sectors(buf, &sectors) < 0)
 		return -EINVAL;
 	if (my_mddev->pers && rdev->raid_disk >= 0) {
 		if (my_mddev->persistent) {
-			size = super_types[my_mddev->major_version].
-				rdev_size_change(rdev, size * 2);
-			if (!size)
+			sectors = super_types[my_mddev->major_version].
+				rdev_size_change(rdev, sectors);
+			if (!sectors)
 				return -EBUSY;
-		} else if (!size) {
-			size = (rdev->bdev->bd_inode->i_size >> 10);
-			size -= rdev->data_offset/2;
-		}
+		} else if (!sectors)
+			sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+				rdev->data_offset;
 	}
-	if (size < my_mddev->size)
+	if (sectors < my_mddev->dev_sectors)
 		return -EINVAL; /* component must fit device */
 
-	rdev->size = size;
-	if (size > oldsize && my_mddev->external) {
+	rdev->sectors = sectors;
+	if (sectors > oldsectors && my_mddev->external) {
 		/* need to check that all other rdevs with the same ->bdev
 		 * do not overlap.  We need to unlock the mddev to avoid
-		 * a deadlock.  We have already changed rdev->size, and if
+		 * a deadlock.  We have already changed rdev->sectors, and if
 		 * we have to change it back, we will have the lock again.
 		 */
 		mddev_t *mddev;
@@ -2223,9 +2352,9 @@ rdev_size_store(mdk_rdev_t *rdev, const
 				if (test_bit(AllReserved, &rdev2->flags) ||
 				    (rdev->bdev == rdev2->bdev &&
 				     rdev != rdev2 &&
-				     overlaps(rdev->data_offset, rdev->size * 2,
+				     overlaps(rdev->data_offset, rdev->sectors,
 					      rdev2->data_offset,
-					      rdev2->size * 2))) {
+					      rdev2->sectors))) {
 					overlap = 1;
 					break;
 				}
@@ -2239,11 +2368,11 @@ rdev_size_store(mdk_rdev_t *rdev, const
 		if (overlap) {
 			/* Someone else could have slipped in a size
 			 * change here, but doing so is just silly.
-			 * We put oldsize back because we *know* it is
+			 * We put oldsectors back because we *know* it is
 			 * safe, and trust userspace not to race with
 			 * itself
 			 */
-			rdev->size = oldsize;
+			rdev->sectors = oldsectors;
 			return -EBUSY;
 		}
 	}
@@ -2547,18 +2676,101 @@ level_show(mddev_t *mddev, char *page)
 static ssize_t
 level_store(mddev_t *mddev, const char *buf, size_t len)
 {
+	char level[16];
 	ssize_t rv = len;
-	if (mddev->pers)
+	struct mdk_personality *pers;
+	void *priv;
+
+	if (mddev->pers == NULL) {
+		if (len == 0)
+			return 0;
+		if (len >= sizeof(mddev->clevel))
+			return -ENOSPC;
+		strncpy(mddev->clevel, buf, len);
+		if (mddev->clevel[len-1] == '\n')
+			len--;
+		mddev->clevel[len] = 0;
+		mddev->level = LEVEL_NONE;
+		return rv;
+	}
+
+	/* request to change the personality.  Need to ensure:
+	 *  - array is not engaged in resync/recovery/reshape
+	 *  - old personality can be suspended
+	 *  - new personality will access other array.
+	 */
+
+	if (mddev->sync_thread || mddev->reshape_position != MaxSector)
 		return -EBUSY;
-	if (len == 0)
-		return 0;
-	if (len >= sizeof(mddev->clevel))
-		return -ENOSPC;
-	strncpy(mddev->clevel, buf, len);
-	if (mddev->clevel[len-1] == '\n')
+
+	if (!mddev->pers->quiesce) {
+		printk(KERN_WARNING "md: %s: %s does not support online personality change\n",
+		       mdname(mddev), mddev->pers->name);
+		return -EINVAL;
+	}
+
+	/* Now find the new personality */
+	if (len == 0 || len >= sizeof(level))
+		return -EINVAL;
+	strncpy(level, buf, len);
+	if (level[len-1] == '\n')
 		len--;
-	mddev->clevel[len] = 0;
-	mddev->level = LEVEL_NONE;
+	level[len] = 0;
+
+	request_module("md-%s", level);
+	spin_lock(&pers_lock);
+	pers = find_pers(LEVEL_NONE, level);
+	if (!pers || !try_module_get(pers->owner)) {
+		spin_unlock(&pers_lock);
+		printk(KERN_WARNING "md: personality %s not loaded\n", level);
+		return -EINVAL;
+	}
+	spin_unlock(&pers_lock);
+
+	if (pers == mddev->pers) {
+		/* Nothing to do! */
+		module_put(pers->owner);
+		return rv;
+	}
+	if (!pers->takeover) {
+		module_put(pers->owner);
+		printk(KERN_WARNING "md: %s: %s does not support personality takeover\n",
+		       mdname(mddev), level);
+		return -EINVAL;
+	}
+
+	/* ->takeover must set new_* and/or delta_disks
+	 * if it succeeds, and may set them when it fails.
+	 */
+	priv = pers->takeover(mddev);
+	if (IS_ERR(priv)) {
+		mddev->new_level = mddev->level;
+		mddev->new_layout = mddev->layout;
+		mddev->new_chunk = mddev->chunk_size;
+		mddev->raid_disks -= mddev->delta_disks;
+		mddev->delta_disks = 0;
+		module_put(pers->owner);
+		printk(KERN_WARNING "md: %s: %s would not accept array\n",
+		       mdname(mddev), level);
+		return PTR_ERR(priv);
+	}
+
+	/* Looks like we have a winner */
+	mddev_suspend(mddev);
+	mddev->pers->stop(mddev);
+	module_put(mddev->pers->owner);
+	mddev->pers = pers;
+	mddev->private = priv;
+	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+	mddev->level = mddev->new_level;
+	mddev->layout = mddev->new_layout;
+	mddev->chunk_size = mddev->new_chunk;
+	mddev->delta_disks = 0;
+	pers->run(mddev);
+	mddev_resume(mddev);
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+	md_wakeup_thread(mddev->thread);
 	return rv;
 }
 
@@ -2586,12 +2798,18 @@ layout_store(mddev_t *mddev, const char
 	if (!*buf || (*e && *e != '\n'))
 		return -EINVAL;
 
-	if (mddev->pers)
-		return -EBUSY;
-	if (mddev->reshape_position != MaxSector)
+	if (mddev->pers) {
+		int err;
+		if (mddev->pers->reconfig == NULL)
+			return -EBUSY;
+		err = mddev->pers->reconfig(mddev, n, -1);
+		if (err)
+			return err;
+	} else {
 		mddev->new_layout = n;
-	else
-		mddev->layout = n;
+		if (mddev->reshape_position == MaxSector)
+			mddev->layout = n;
+	}
 	return len;
 }
 static struct md_sysfs_entry md_layout =
@@ -2648,19 +2866,24 @@ chunk_size_show(mddev_t *mddev, char *pa
 static ssize_t
 chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
 {
-	/* can only set chunk_size if array is not yet active */
 	char *e;
 	unsigned long n = simple_strtoul(buf, &e, 10);
 
 	if (!*buf || (*e && *e != '\n'))
 		return -EINVAL;
 
-	if (mddev->pers)
-		return -EBUSY;
-	else if (mddev->reshape_position != MaxSector)
+	if (mddev->pers) {
+		int err;
+		if (mddev->pers->reconfig == NULL)
+			return -EBUSY;
+		err = mddev->pers->reconfig(mddev, -1, n);
+		if (err)
+			return err;
+	} else {
 		mddev->new_chunk = n;
-	else
-		mddev->chunk_size = n;
+		if (mddev->reshape_position == MaxSector)
+			mddev->chunk_size = n;
+	}
 	return len;
 }
 static struct md_sysfs_entry md_chunk_size =
@@ -2669,6 +2892,8 @@ __ATTR(chunk_size, S_IRUGO|S_IWUSR, chun
 static ssize_t
 resync_start_show(mddev_t *mddev, char *page)
 {
+	if (mddev->recovery_cp == MaxSector)
+		return sprintf(page, "none\n");
 	return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp);
 }
 
@@ -2766,7 +2991,7 @@ array_state_show(mddev_t *mddev, char *p
 	else {
 		if (list_empty(&mddev->disks) &&
 		    mddev->raid_disks == 0 &&
-		    mddev->size == 0)
+		    mddev->dev_sectors == 0)
 			st = clear;
 		else
 			st = inactive;
@@ -2844,11 +3069,8 @@ array_state_store(mddev_t *mddev, const
 			} else
 				err = -EBUSY;
 			spin_unlock_irq(&mddev->write_lock);
-		} else {
-			mddev->ro = 0;
-			mddev->recovery_cp = MaxSector;
-			err = do_md_run(mddev);
-		}
+		} else
+			err = -EINVAL;
 		break;
 	case active:
 		if (mddev->pers) {
@@ -2973,7 +3195,8 @@ __ATTR(bitmap_set_bits, S_IWUSR, null_sh
 static ssize_t
 size_show(mddev_t *mddev, char *page)
 {
-	return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+	return sprintf(page, "%llu\n",
+		(unsigned long long)mddev->dev_sectors / 2);
 }
 
 static int update_size(mddev_t *mddev, sector_t num_sectors);
@@ -2985,20 +3208,18 @@ size_store(mddev_t *mddev, const char *b
 	 * not increase it (except from 0).
 	 * If array is active, we can try an on-line resize
 	 */
-	char *e;
-	int err = 0;
-	unsigned long long size = simple_strtoull(buf, &e, 10);
-	if (!*buf || *buf == '\n' ||
-	    (*e && *e != '\n'))
-		return -EINVAL;
+	sector_t sectors;
+	int err = strict_blocks_to_sectors(buf, &sectors);
 
+	if (err < 0)
+		return err;
 	if (mddev->pers) {
-		err = update_size(mddev, size * 2);
+		err = update_size(mddev, sectors);
 		md_update_sb(mddev, 1);
 	} else {
-		if (mddev->size == 0 ||
-		    mddev->size > size)
-			mddev->size = size;
+		if (mddev->dev_sectors == 0 ||
+		    mddev->dev_sectors > sectors)
+			mddev->dev_sectors = sectors;
 		else
 			err = -ENOSPC;
 	}
@@ -3085,7 +3306,9 @@ static ssize_t
 action_show(mddev_t *mddev, char *page)
 {
 	char *type = "idle";
-	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+	if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+		type = "frozen";
+	else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
 	    (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
 		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
 			type = "reshape";
@@ -3108,7 +3331,12 @@ action_store(mddev_t *mddev, const char
 	if (!mddev->pers || !mddev->pers->sync_request)
 		return -EINVAL;
 
-	if (cmd_match(page, "idle")) {
+	if (cmd_match(page, "frozen"))
+		set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	else
+		clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+
+	if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
 		if (mddev->sync_thread) {
 			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 			md_unregister_thread(mddev->sync_thread);
@@ -3251,6 +3479,8 @@ static ssize_t
 sync_speed_show(mddev_t *mddev, char *page)
 {
 	unsigned long resync, dt, db;
+	if (mddev->curr_resync == 0)
+		return sprintf(page, "none\n");
 	resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
 	dt = (jiffies - mddev->resync_mark) / HZ;
 	if (!dt) dt++;
@@ -3263,15 +3493,18 @@ static struct md_sysfs_entry md_sync_spe
 static ssize_t
 sync_completed_show(mddev_t *mddev, char *page)
 {
-	unsigned long max_blocks, resync;
+	unsigned long max_sectors, resync;
+
+	if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+		return sprintf(page, "none\n");
 
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
-		max_blocks = mddev->resync_max_sectors;
+		max_sectors = mddev->resync_max_sectors;
 	else
-		max_blocks = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 
-	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
-	return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+	resync = mddev->curr_resync_completed;
+	return sprintf(page, "%lu / %lu\n", resync, max_sectors);
 }
 
 static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
@@ -3431,6 +3664,57 @@ static struct md_sysfs_entry md_reshape_
 __ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
        reshape_position_store);
 
+static ssize_t
+array_size_show(mddev_t *mddev, char *page)
+{
+	if (mddev->external_size)
+		return sprintf(page, "%llu\n",
+			       (unsigned long long)mddev->array_sectors/2);
+	else
+		return sprintf(page, "default\n");
+}
+
+static ssize_t
+array_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	sector_t sectors;
+
+	if (strncmp(buf, "default", 7) == 0) {
+		if (mddev->pers)
+			sectors = mddev->pers->size(mddev, 0, 0);
+		else
+			sectors = mddev->array_sectors;
+
+		mddev->external_size = 0;
+	} else {
+		if (strict_blocks_to_sectors(buf, &sectors) < 0)
+			return -EINVAL;
+		if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
+			return -E2BIG;
+
+		mddev->external_size = 1;
+	}
+
+	mddev->array_sectors = sectors;
+	set_capacity(mddev->gendisk, mddev->array_sectors);
+	if (mddev->pers) {
+		struct block_device *bdev = bdget_disk(mddev->gendisk, 0);
+
+		if (bdev) {
+			mutex_lock(&bdev->bd_inode->i_mutex);
+			i_size_write(bdev->bd_inode,
+				     (loff_t)mddev->array_sectors << 9);
+			mutex_unlock(&bdev->bd_inode->i_mutex);
+			bdput(bdev);
+		}
+	}
+
+	return len;
+}
+
+static struct md_sysfs_entry md_array_size =
+__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
+       array_size_store);
 
 static struct attribute *md_default_attrs[] = {
 	&md_level.attr,
@@ -3444,6 +3728,7 @@ static struct attribute *md_default_attr
 	&md_safe_delay.attr,
 	&md_array_state.attr,
 	&md_reshape_position.attr,
+	&md_array_size.attr,
 	NULL,
 };
 
@@ -3602,10 +3887,12 @@ static int md_alloc(dev_t dev, char *nam
 		mddev_put(mddev);
 		return -ENOMEM;
 	}
+	mddev->queue->queuedata = mddev;
+
 	/* Can be unlocked because the queue is new: no concurrency */
 	queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
 
-	blk_queue_make_request(mddev->queue, md_fail_request);
+	blk_queue_make_request(mddev->queue, md_make_request);
 
 	disk = alloc_disk(1 << shift);
 	if (!disk) {
@@ -3731,13 +4018,13 @@ static int do_md_run(mddev_t * mddev)
 		list_for_each_entry(rdev, &mddev->disks, same_set) {
 			if (test_bit(Faulty, &rdev->flags))
 				continue;
-			if (rdev->size < chunk_size / 1024) {
+			if (rdev->sectors < chunk_size / 512) {
 				printk(KERN_WARNING
 					"md: Dev %s smaller than chunk_size:"
-					" %lluk < %dk\n",
+					" %llu < %d\n",
 					bdevname(rdev->bdev,b),
-					(unsigned long long)rdev->size,
-					chunk_size / 1024);
+					(unsigned long long)rdev->sectors,
+					chunk_size / 512);
 				return -EINVAL;
 			}
 		}
@@ -3761,11 +4048,11 @@ static int do_md_run(mddev_t * mddev)
 
 		/* perform some consistency tests on the device.
 		 * We don't want the data to overlap the metadata,
-		 * Internal Bitmap issues has handled elsewhere.
+		 * Internal Bitmap issues have been handled elsewhere.
 		 */
 		if (rdev->data_offset < rdev->sb_start) {
-			if (mddev->size &&
-			    rdev->data_offset + mddev->size*2
+			if (mddev->dev_sectors &&
+			    rdev->data_offset + mddev->dev_sectors
 			    > rdev->sb_start) {
 				printk("md: %s: data overlaps metadata\n",
 				       mdname(mddev));
@@ -3801,9 +4088,16 @@ static int do_md_run(mddev_t * mddev)
 	}
 	mddev->pers = pers;
 	spin_unlock(&pers_lock);
-	mddev->level = pers->level;
+	if (mddev->level != pers->level) {
+		mddev->level = pers->level;
+		mddev->new_level = pers->level;
+	}
 	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
 
+	if (pers->level >= 4 && pers->level <= 6)
+		/* Cannot support integrity (yet) */
+		blk_integrity_unregister(mddev->gendisk);
+
 	if (mddev->reshape_position != MaxSector &&
 	    pers->start_reshape == NULL) {
 		/* This personality cannot handle reshaping... */
@@ -3843,7 +4137,9 @@ static int do_md_run(mddev_t * mddev)
 	}
 
 	mddev->recovery = 0;
-	mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+	/* may be over-ridden by personality */
+	mddev->resync_max_sectors = mddev->dev_sectors;
+
 	mddev->barriers_work = 1;
 	mddev->ok_start_degraded = start_dirty_degraded;
 
@@ -3853,7 +4149,17 @@ static int do_md_run(mddev_t * mddev)
 	err = mddev->pers->run(mddev);
 	if (err)
 		printk(KERN_ERR "md: pers->run() failed ...\n");
-	else if (mddev->pers->sync_request) {
+	else if (mddev->pers->size(mddev, 0, 0) < mddev->array_sectors) {
+		WARN_ONCE(!mddev->external_size, "%s: default size too small,"
+			  " but 'external_size' not in effect?\n", __func__);
+		printk(KERN_ERR
+		       "md: invalid array_size %llu > default size %llu\n",
+		       (unsigned long long)mddev->array_sectors / 2,
+		       (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
+		err = -EINVAL;
+		mddev->pers->stop(mddev);
+	}
+	if (err == 0 && mddev->pers->sync_request) {
 		err = bitmap_create(mddev);
 		if (err) {
 			printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3899,16 +4205,6 @@ static int do_md_run(mddev_t * mddev)
 
 	set_capacity(disk, mddev->array_sectors);
 
-	/* If we call blk_queue_make_request here, it will
-	 * re-initialise max_sectors etc which may have been
-	 * refined inside -> run.  So just set the bits we need to set.
-	 * Most initialisation happended when we called
-	 * blk_queue_make_request(..., md_fail_request)
-	 * earlier.
-	 */
-	mddev->queue->queuedata = mddev;
-	mddev->queue->make_request_fn = mddev->pers->make_request;
-
 	/* 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
@@ -4008,6 +4304,7 @@ static int do_md_stop(mddev_t * mddev, i
 {
 	int err = 0;
 	struct gendisk *disk = mddev->gendisk;
+	mdk_rdev_t *rdev;
 
 	if (atomic_read(&mddev->openers) > is_open) {
 		printk("md: %s still in use.\n",mdname(mddev));
@@ -4038,7 +4335,7 @@ static int do_md_stop(mddev_t * mddev, i
 			md_super_wait(mddev);
 			if (mddev->ro)
 				set_disk_ro(disk, 0);
-			blk_queue_make_request(mddev->queue, md_fail_request);
+
 			mddev->pers->stop(mddev);
 			mddev->queue->merge_bvec_fn = NULL;
 			mddev->queue->unplug_fn = NULL;
@@ -4050,6 +4347,13 @@ static int do_md_stop(mddev_t * mddev, i
 			/* tell userspace to handle 'inactive' */
 			sysfs_notify_dirent(mddev->sysfs_state);
 
+			list_for_each_entry(rdev, &mddev->disks, same_set)
+				if (rdev->raid_disk >= 0) {
+					char nm[20];
+					sprintf(nm, "rd%d", rdev->raid_disk);
+					sysfs_remove_link(&mddev->kobj, nm);
+				}
+
 			set_capacity(disk, 0);
 			mddev->changed = 1;
 
@@ -4070,7 +4374,6 @@ static int do_md_stop(mddev_t * mddev, i
 	 * Free resources if final stop
 	 */
 	if (mode == 0) {
-		mdk_rdev_t *rdev;
 
 		printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
 
@@ -4082,20 +4385,14 @@ static int do_md_stop(mddev_t * mddev, i
 		}
 		mddev->bitmap_offset = 0;
 
-		list_for_each_entry(rdev, &mddev->disks, same_set)
-			if (rdev->raid_disk >= 0) {
-				char nm[20];
-				sprintf(nm, "rd%d", rdev->raid_disk);
-				sysfs_remove_link(&mddev->kobj, nm);
-			}
-
 		/* make sure all md_delayed_delete calls have finished */
 		flush_scheduled_work();
 
 		export_array(mddev);
 
 		mddev->array_sectors = 0;
-		mddev->size = 0;
+		mddev->external_size = 0;
+		mddev->dev_sectors = 0;
 		mddev->raid_disks = 0;
 		mddev->recovery_cp = 0;
 		mddev->resync_min = 0;
@@ -4135,6 +4432,7 @@ static int do_md_stop(mddev_t * mddev, i
 		printk(KERN_INFO "md: %s switched to read-only mode.\n",
 			mdname(mddev));
 	err = 0;
+	blk_integrity_unregister(disk);
 	md_new_event(mddev);
 	sysfs_notify_dirent(mddev->sysfs_state);
 out:
@@ -4300,8 +4598,8 @@ static int get_array_info(mddev_t * mdde
 	info.patch_version = MD_PATCHLEVEL_VERSION;
 	info.ctime         = mddev->ctime;
 	info.level         = mddev->level;
-	info.size          = mddev->size;
-	if (info.size != mddev->size) /* overflow */
+	info.size          = mddev->dev_sectors / 2;
+	if (info.size != mddev->dev_sectors / 2) /* overflow */
 		info.size = -1;
 	info.nr_disks      = nr;
 	info.raid_disks    = mddev->raid_disks;
@@ -4480,6 +4778,8 @@ static int add_new_disk(mddev_t * mddev,
 		clear_bit(In_sync, &rdev->flags); /* just to be sure */
 		if (info->state & (1<<MD_DISK_WRITEMOSTLY))
 			set_bit(WriteMostly, &rdev->flags);
+		else
+			clear_bit(WriteMostly, &rdev->flags);
 
 		rdev->raid_disk = -1;
 		err = bind_rdev_to_array(rdev, mddev);
@@ -4543,7 +4843,7 @@ static int add_new_disk(mddev_t * mddev,
 			rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
 		} else 
 			rdev->sb_start = calc_dev_sboffset(rdev->bdev);
-		rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+		rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
 
 		err = bind_rdev_to_array(rdev, mddev);
 		if (err) {
@@ -4613,7 +4913,7 @@ static int hot_add_disk(mddev_t * mddev,
 	else
 		rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
 
-	rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+	rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
 
 	if (test_bit(Faulty, &rdev->flags)) {
 		printk(KERN_WARNING 
@@ -4749,7 +5049,7 @@ static int set_array_info(mddev_t * mdde
 
 	mddev->level         = info->level;
 	mddev->clevel[0]     = 0;
-	mddev->size          = info->size;
+	mddev->dev_sectors   = 2 * (sector_t)info->size;
 	mddev->raid_disks    = info->raid_disks;
 	/* don't set md_minor, it is determined by which /dev/md* was
 	 * openned
@@ -4788,6 +5088,17 @@ static int set_array_info(mddev_t * mdde
 	return 0;
 }
 
+void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors)
+{
+	WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__);
+
+	if (mddev->external_size)
+		return;
+
+	mddev->array_sectors = array_sectors;
+}
+EXPORT_SYMBOL(md_set_array_sectors);
+
 static int update_size(mddev_t *mddev, sector_t num_sectors)
 {
 	mdk_rdev_t *rdev;
@@ -4814,8 +5125,7 @@ static int update_size(mddev_t *mddev, s
 		 */
 		return -EBUSY;
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
-		sector_t avail;
-		avail = rdev->size * 2;
+		sector_t avail = rdev->sectors;
 
 		if (fit && (num_sectors == 0 || num_sectors > avail))
 			num_sectors = avail;
@@ -4887,12 +5197,18 @@ static int update_array_info(mddev_t *md
 		)
 		return -EINVAL;
 	/* Check there is only one change */
-	if (info->size >= 0 && mddev->size != info->size) cnt++;
-	if (mddev->raid_disks != info->raid_disks) cnt++;
-	if (mddev->layout != info->layout) cnt++;
-	if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
-	if (cnt == 0) return 0;
-	if (cnt > 1) return -EINVAL;
+	if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
+		cnt++;
+	if (mddev->raid_disks != info->raid_disks)
+		cnt++;
+	if (mddev->layout != info->layout)
+		cnt++;
+	if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT))
+		cnt++;
+	if (cnt == 0)
+		return 0;
+	if (cnt > 1)
+		return -EINVAL;
 
 	if (mddev->layout != info->layout) {
 		/* Change layout
@@ -4904,7 +5220,7 @@ static int update_array_info(mddev_t *md
 		else
 			return mddev->pers->reconfig(mddev, info->layout, -1);
 	}
-	if (info->size >= 0 && mddev->size != info->size)
+	if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
 		rv = update_size(mddev, (sector_t)info->size * 2);
 
 	if (mddev->raid_disks    != info->raid_disks)
@@ -5251,7 +5567,7 @@ static struct block_device_operations md
 	.owner		= THIS_MODULE,
 	.open		= md_open,
 	.release	= md_release,
-	.locked_ioctl	= md_ioctl,
+	.ioctl		= md_ioctl,
 	.getgeo		= md_getgeo,
 	.media_changed	= md_media_changed,
 	.revalidate_disk= md_revalidate,
@@ -5331,6 +5647,8 @@ mdk_thread_t *md_register_thread(void (*
 
 void md_unregister_thread(mdk_thread_t *thread)
 {
+	if (!thread)
+		return;
 	dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
 
 	kthread_stop(thread->tsk);
@@ -5394,37 +5712,38 @@ static void status_unused(struct seq_fil
 
 static void status_resync(struct seq_file *seq, mddev_t * mddev)
 {
-	sector_t max_blocks, resync, res;
-	unsigned long dt, db, rt;
+	sector_t max_sectors, resync, res;
+	unsigned long dt, db;
+	sector_t rt;
 	int scale;
 	unsigned int per_milli;
 
-	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2;
+	resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
 
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
-		max_blocks = mddev->resync_max_sectors >> 1;
+		max_sectors = mddev->resync_max_sectors;
 	else
-		max_blocks = mddev->size;
+		max_sectors = mddev->dev_sectors;
 
 	/*
 	 * Should not happen.
 	 */
-	if (!max_blocks) {
+	if (!max_sectors) {
 		MD_BUG();
 		return;
 	}
 	/* Pick 'scale' such that (resync>>scale)*1000 will fit
-	 * in a sector_t, and (max_blocks>>scale) will fit in a
+	 * in a sector_t, and (max_sectors>>scale) will fit in a
 	 * u32, as those are the requirements for sector_div.
 	 * Thus 'scale' must be at least 10
 	 */
 	scale = 10;
 	if (sizeof(sector_t) > sizeof(unsigned long)) {
-		while ( max_blocks/2 > (1ULL<<(scale+32)))
+		while ( max_sectors/2 > (1ULL<<(scale+32)))
 			scale++;
 	}
 	res = (resync>>scale)*1000;
-	sector_div(res, (u32)((max_blocks>>scale)+1));
+	sector_div(res, (u32)((max_sectors>>scale)+1));
 
 	per_milli = res;
 	{
@@ -5445,25 +5764,35 @@ static void status_resync(struct seq_fil
 		     (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ?
 		      "resync" : "recovery"))),
 		   per_milli/10, per_milli % 10,
-		   (unsigned long long) resync,
-		   (unsigned long long) max_blocks);
+		   (unsigned long long) resync/2,
+		   (unsigned long long) max_sectors/2);
 
 	/*
-	 * 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
+	 *
+	 * rt is a sector_t, so could be 32bit or 64bit.
+	 * So we divide before multiply in case it is 32bit and close
+	 * to the limit.
+	 * We scale the divisor (db) by 32 to avoid loosing precision
+	 * near the end of resync when the number of remaining sectors
+	 * is close to 'db'.
+	 * We then divide rt by 32 after multiplying by db to compensate.
+	 * The '+1' avoids division by zero if db is very small.
 	 */
 	dt = ((jiffies - mddev->resync_mark) / HZ);
 	if (!dt) dt++;
 	db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
 		- mddev->resync_mark_cnt;
-	rt = (dt * ((unsigned long)(max_blocks-resync) / (db/2/100+1)))/100;
 
-	seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
+	rt = max_sectors - resync;    /* number of remaining sectors */
+	sector_div(rt, db/32+1);
+	rt *= dt;
+	rt >>= 5;
+
+	seq_printf(seq, " finish=%lu.%lumin", (unsigned long)rt / 60,
+		   ((unsigned long)rt % 60)/6);
 
 	seq_printf(seq, " speed=%ldK/sec", db/2/dt);
 }
@@ -5537,7 +5866,7 @@ struct mdstat_info {
 static int md_seq_show(struct seq_file *seq, void *v)
 {
 	mddev_t *mddev = v;
-	sector_t size;
+	sector_t sectors;
 	mdk_rdev_t *rdev;
 	struct mdstat_info *mi = seq->private;
 	struct bitmap *bitmap;
@@ -5573,7 +5902,7 @@ static int md_seq_show(struct seq_file *
 			seq_printf(seq, " %s", mddev->pers->name);
 		}
 
-		size = 0;
+		sectors = 0;
 		list_for_each_entry(rdev, &mddev->disks, same_set) {
 			char b[BDEVNAME_SIZE];
 			seq_printf(seq, " %s[%d]",
@@ -5585,7 +5914,7 @@ static int md_seq_show(struct seq_file *
 				continue;
 			} else if (rdev->raid_disk < 0)
 				seq_printf(seq, "(S)"); /* spare */
-			size += rdev->size;
+			sectors += rdev->sectors;
 		}
 
 		if (!list_empty(&mddev->disks)) {
@@ -5595,7 +5924,7 @@ static int md_seq_show(struct seq_file *
 					   mddev->array_sectors / 2);
 			else
 				seq_printf(seq, "\n      %llu blocks",
-					   (unsigned long long)size);
+					   (unsigned long long)sectors / 2);
 		}
 		if (mddev->persistent) {
 			if (mddev->major_version != 0 ||
@@ -5654,7 +5983,7 @@ static int md_seq_show(struct seq_file *
 	return 0;
 }
 
-static struct seq_operations md_seq_ops = {
+static const struct seq_operations md_seq_ops = {
 	.start  = md_seq_start,
 	.next   = md_seq_next,
 	.stop   = md_seq_stop,
@@ -5722,19 +6051,19 @@ int unregister_md_personality(struct mdk
 	return 0;
 }
 
-static int is_mddev_idle(mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev, int init)
 {
 	mdk_rdev_t * rdev;
 	int idle;
-	long curr_events;
+	int curr_events;
 
 	idle = 1;
 	rcu_read_lock();
 	rdev_for_each_rcu(rdev, mddev) {
 		struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
-		curr_events = part_stat_read(&disk->part0, sectors[0]) +
-				part_stat_read(&disk->part0, sectors[1]) -
-				atomic_read(&disk->sync_io);
+		curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
+			      (int)part_stat_read(&disk->part0, sectors[1]) -
+			      atomic_read(&disk->sync_io);
 		/* sync IO will cause sync_io to increase before the disk_stats
 		 * as sync_io is counted when a request starts, and
 		 * disk_stats is counted when it completes.
@@ -5757,7 +6086,7 @@ static int is_mddev_idle(mddev_t *mddev)
 		 * always make curr_events less than last_events.
 		 *
 		 */
-		if (curr_events - rdev->last_events > 4096) {
+		if (init || curr_events - rdev->last_events > 64) {
 			rdev->last_events = curr_events;
 			idle = 0;
 		}
@@ -5980,10 +6309,10 @@ void md_do_sync(mddev_t *mddev)
 			j = mddev->recovery_cp;
 
 	} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
-		max_sectors = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 	else {
 		/* recovery follows the physical size of devices */
-		max_sectors = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 		j = MaxSector;
 		list_for_each_entry(rdev, &mddev->disks, same_set)
 			if (rdev->raid_disk >= 0 &&
@@ -6000,7 +6329,7 @@ void md_do_sync(mddev_t *mddev)
 	       "(but not more than %d KB/sec) for %s.\n",
 	       speed_max(mddev), desc);
 
-	is_mddev_idle(mddev); /* this also initializes IO event counters */
+	is_mddev_idle(mddev, 1); /* this initializes IO event counters */
 
 	io_sectors = 0;
 	for (m = 0; m < SYNC_MARKS; m++) {
@@ -6032,14 +6361,32 @@ void md_do_sync(mddev_t *mddev)
 		sector_t sectors;
 
 		skipped = 0;
-		if (j >= mddev->resync_max) {
+
+		if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+		    ((mddev->curr_resync > mddev->curr_resync_completed &&
+		      (mddev->curr_resync - mddev->curr_resync_completed)
+		      > (max_sectors >> 4)) ||
+		     (j - mddev->curr_resync_completed)*2
+		     >= mddev->resync_max - mddev->curr_resync_completed
+			    )) {
+			/* time to update curr_resync_completed */
+			blk_unplug(mddev->queue);
+			wait_event(mddev->recovery_wait,
+				   atomic_read(&mddev->recovery_active) == 0);
+			mddev->curr_resync_completed =
+				mddev->curr_resync;
+			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
 			sysfs_notify(&mddev->kobj, NULL, "sync_completed");
+		}
+
+		if (j >= mddev->resync_max)
 			wait_event(mddev->recovery_wait,
 				   mddev->resync_max > j
 				   || kthread_should_stop());
-		}
+
 		if (kthread_should_stop())
 			goto interrupted;
+
 		sectors = mddev->pers->sync_request(mddev, j, &skipped,
 						  currspeed < speed_min(mddev));
 		if (sectors == 0) {
@@ -6102,7 +6449,7 @@ void md_do_sync(mddev_t *mddev)
 
 		if (currspeed > speed_min(mddev)) {
 			if ((currspeed > speed_max(mddev)) ||
-					!is_mddev_idle(mddev)) {
+					!is_mddev_idle(mddev, 0)) {
 				msleep(500);
 				goto repeat;
 			}
@@ -6147,6 +6494,7 @@ void md_do_sync(mddev_t *mddev)
 
  skip:
 	mddev->curr_resync = 0;
+	mddev->curr_resync_completed = 0;
 	mddev->resync_min = 0;
 	mddev->resync_max = MaxSector;
 	sysfs_notify(&mddev->kobj, NULL, "sync_completed");
@@ -6173,6 +6521,8 @@ static int remove_and_add_spares(mddev_t
 	mdk_rdev_t *rdev;
 	int spares = 0;
 
+	mddev->curr_resync_completed = 0;
+
 	list_for_each_entry(rdev, &mddev->disks, same_set)
 		if (rdev->raid_disk >= 0 &&
 		    !test_bit(Blocked, &rdev->flags) &&
@@ -6327,6 +6677,9 @@ void md_check_recovery(mddev_t *mddev)
 					sysfs_notify(&mddev->kobj, NULL,
 						     "degraded");
 			}
+			if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+			    mddev->pers->finish_reshape)
+				mddev->pers->finish_reshape(mddev);
 			md_update_sb(mddev, 1);
 
 			/* if array is no-longer degraded, then any saved_raid_disk
@@ -6470,13 +6823,13 @@ static void md_geninit(void)
 
 static int __init md_init(void)
 {
-	if (register_blkdev(MAJOR_NR, "md"))
+	if (register_blkdev(MD_MAJOR, "md"))
 		return -1;
 	if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
-		unregister_blkdev(MAJOR_NR, "md");
+		unregister_blkdev(MD_MAJOR, "md");
 		return -1;
 	}
-	blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+	blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
 			    md_probe, NULL, NULL);
 	blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
 			    md_probe, NULL, NULL);
@@ -6562,10 +6915,10 @@ static __exit void md_exit(void)
 	mddev_t *mddev;
 	struct list_head *tmp;
 
-	blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+	blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);
 	blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
 
-	unregister_blkdev(MAJOR_NR,"md");
+	unregister_blkdev(MD_MAJOR,"md");
 	unregister_blkdev(mdp_major, "mdp");
 	unregister_reboot_notifier(&md_notifier);
 	unregister_sysctl_table(raid_table_header);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/md.h linux-libre-2.6.30-gnu1/drivers/md/md.h
--- linux-libre-2.6.29-gnu1/drivers/md/md.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/md.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,441 @@
+/*
+   md_k.h : kernel internal structure of the Linux MD driver
+          Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
+	  
+   This program is free software; you can redistribute 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.
+   
+   You should have received a copy of the GNU General Public License
+   (for example /usr/src/linux/COPYING); if not, write to the Free
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
+
+#ifndef _MD_MD_H
+#define _MD_MD_H
+
+#include <linux/blkdev.h>
+#include <linux/kobject.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#define MaxSector (~(sector_t)0)
+
+typedef struct mddev_s mddev_t;
+typedef struct mdk_rdev_s mdk_rdev_t;
+
+/*
+ * options passed in raidrun:
+ */
+
+/* Currently this must fit in an 'int' */
+#define MAX_CHUNK_SIZE (1<<30)
+
+/*
+ * MD's 'extended' device
+ */
+struct mdk_rdev_s
+{
+	struct list_head same_set;	/* RAID devices within the same set */
+
+	sector_t sectors;		/* Device size (in 512bytes sectors) */
+	mddev_t *mddev;			/* RAID array if running */
+	int last_events;		/* IO event timestamp */
+
+	struct block_device *bdev;	/* block device handle */
+
+	struct page	*sb_page;
+	int		sb_loaded;
+	__u64		sb_events;
+	sector_t	data_offset;	/* start of data in array */
+	sector_t 	sb_start;	/* offset of the super block (in 512byte sectors) */
+	int		sb_size;	/* bytes in the superblock */
+	int		preferred_minor;	/* autorun support */
+
+	struct kobject	kobj;
+
+	/* A device can be in one of three states based on two flags:
+	 * Not working:   faulty==1 in_sync==0
+	 * Fully working: faulty==0 in_sync==1
+	 * Working, but not
+	 * in sync with array
+	 *                faulty==0 in_sync==0
+	 *
+	 * It can never have faulty==1, in_sync==1
+	 * This reduces the burden of testing multiple flags in many cases
+	 */
+
+	unsigned long	flags;
+#define	Faulty		1		/* device is known to have a fault */
+#define	In_sync		2		/* device is in_sync with rest of array */
+#define	WriteMostly	4		/* Avoid reading if at all possible */
+#define	BarriersNotsupp	5		/* BIO_RW_BARRIER is not supported */
+#define	AllReserved	6		/* If whole device is reserved for
+					 * one array */
+#define	AutoDetected	7		/* added by auto-detect */
+#define Blocked		8		/* An error occured on an externally
+					 * managed array, don't allow writes
+					 * until it is cleared */
+#define StateChanged	9		/* Faulty or Blocked has changed during
+					 * interrupt, so it needs to be
+					 * notified by the thread */
+	wait_queue_head_t blocked_wait;
+
+	int desc_nr;			/* descriptor index in the superblock */
+	int raid_disk;			/* role of device in array */
+	int saved_raid_disk;		/* role that device used to have in the
+					 * array and could again if we did a partial
+					 * resync from the bitmap
+					 */
+	sector_t	recovery_offset;/* If this device has been partially
+					 * recovered, this is where we were
+					 * up to.
+					 */
+
+	atomic_t	nr_pending;	/* number of pending requests.
+					 * only maintained for arrays that
+					 * support hot removal
+					 */
+	atomic_t	read_errors;	/* number of consecutive read errors that
+					 * we have tried to ignore.
+					 */
+	atomic_t	corrected_errors; /* number of corrected read errors,
+					   * for reporting to userspace and storing
+					   * in superblock.
+					   */
+	struct work_struct del_work;	/* used for delayed sysfs removal */
+
+	struct sysfs_dirent *sysfs_state; /* handle for 'state'
+					   * sysfs entry */
+};
+
+struct mddev_s
+{
+	void				*private;
+	struct mdk_personality		*pers;
+	dev_t				unit;
+	int				md_minor;
+	struct list_head 		disks;
+	unsigned long			flags;
+#define MD_CHANGE_DEVS	0	/* Some device status has changed */
+#define MD_CHANGE_CLEAN 1	/* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2	/* superblock update in progress */
+
+	int				suspended;
+	atomic_t			active_io;
+	int				ro;
+
+	struct gendisk			*gendisk;
+
+	struct kobject			kobj;
+	int				hold_active;
+#define	UNTIL_IOCTL	1
+#define	UNTIL_STOP	2
+
+	/* Superblock information */
+	int				major_version,
+					minor_version,
+					patch_version;
+	int				persistent;
+	int 				external;	/* metadata is
+							 * managed externally */
+	char				metadata_type[17]; /* externally set*/
+	int				chunk_size;
+	time_t				ctime, utime;
+	int				level, layout;
+	char				clevel[16];
+	int				raid_disks;
+	int				max_disks;
+	sector_t			dev_sectors; 	/* used size of
+							 * component devices */
+	sector_t			array_sectors; /* exported array size */
+	int				external_size; /* size managed
+							* externally */
+	__u64				events;
+
+	char				uuid[16];
+
+	/* If the array is being reshaped, we need to record the
+	 * new shape and an indication of where we are up to.
+	 * This is written to the superblock.
+	 * If reshape_position is MaxSector, then no reshape is happening (yet).
+	 */
+	sector_t			reshape_position;
+	int				delta_disks, new_level, new_layout, new_chunk;
+
+	struct mdk_thread_s		*thread;	/* management thread */
+	struct mdk_thread_s		*sync_thread;	/* doing resync or reconstruct */
+	sector_t			curr_resync;	/* last block scheduled */
+	/* As resync requests can complete out of order, we cannot easily track
+	 * how much resync has been completed.  So we occasionally pause until
+	 * everything completes, then set curr_resync_completed to curr_resync.
+	 * As such it may be well behind the real resync mark, but it is a value
+	 * we are certain of.
+	 */
+	sector_t			curr_resync_completed;
+	unsigned long			resync_mark;	/* a recent timestamp */
+	sector_t			resync_mark_cnt;/* blocks written at resync_mark */
+	sector_t			curr_mark_cnt; /* blocks scheduled now */
+
+	sector_t			resync_max_sectors; /* may be set by personality */
+
+	sector_t			resync_mismatches; /* count of sectors where
+							    * parity/replica mismatch found
+							    */
+
+	/* allow user-space to request suspension of IO to regions of the array */
+	sector_t			suspend_lo;
+	sector_t			suspend_hi;
+	/* if zero, use the system-wide default */
+	int				sync_speed_min;
+	int				sync_speed_max;
+
+	/* resync even though the same disks are shared among md-devices */
+	int				parallel_resync;
+
+	int				ok_start_degraded;
+	/* recovery/resync flags 
+	 * NEEDED:   we might need to start a resync/recover
+	 * RUNNING:  a thread is running, or about to be started
+	 * SYNC:     actually doing a resync, not a recovery
+	 * RECOVER:  doing recovery, or need to try it.
+	 * INTR:     resync needs to be aborted for some reason
+	 * DONE:     thread is done and is waiting to be reaped
+	 * REQUEST:  user-space has requested a sync (used with SYNC)
+	 * CHECK:    user-space request for for check-only, no repair
+	 * RESHAPE:  A reshape is happening
+	 *
+	 * If neither SYNC or RESHAPE are set, then it is a recovery.
+	 */
+#define	MD_RECOVERY_RUNNING	0
+#define	MD_RECOVERY_SYNC	1
+#define	MD_RECOVERY_RECOVER	2
+#define	MD_RECOVERY_INTR	3
+#define	MD_RECOVERY_DONE	4
+#define	MD_RECOVERY_NEEDED	5
+#define	MD_RECOVERY_REQUESTED	6
+#define	MD_RECOVERY_CHECK	7
+#define MD_RECOVERY_RESHAPE	8
+#define	MD_RECOVERY_FROZEN	9
+
+	unsigned long			recovery;
+	int				recovery_disabled; /* if we detect that recovery
+							    * will always fail, set this
+							    * so we don't loop trying */
+
+	int				in_sync;	/* know to not need resync */
+	struct mutex			reconfig_mutex;
+	atomic_t			active;		/* general refcount */
+	atomic_t			openers;	/* number of active opens */
+
+	int				changed;	/* true if we might need to reread partition info */
+	int				degraded;	/* whether md should consider
+							 * adding a spare
+							 */
+	int				barriers_work;	/* initialised to true, cleared as soon
+							 * as a barrier request to slave
+							 * fails.  Only supported
+							 */
+	struct bio			*biolist; 	/* bios that need to be retried
+							 * because BIO_RW_BARRIER is not supported
+							 */
+
+	atomic_t			recovery_active; /* blocks scheduled, but not written */
+	wait_queue_head_t		recovery_wait;
+	sector_t			recovery_cp;
+	sector_t			resync_min;	/* user requested sync
+							 * starts here */
+	sector_t			resync_max;	/* resync should pause
+							 * when it gets here */
+
+	struct sysfs_dirent		*sysfs_state;	/* handle for 'array_state'
+							 * file in sysfs.
+							 */
+	struct sysfs_dirent		*sysfs_action;  /* handle for 'sync_action' */
+
+	struct work_struct del_work;	/* used for delayed sysfs removal */
+
+	spinlock_t			write_lock;
+	wait_queue_head_t		sb_wait;	/* for waiting on superblock updates */
+	atomic_t			pending_writes;	/* number of active superblock writes */
+
+	unsigned int			safemode;	/* if set, update "clean" superblock
+							 * when no writes pending.
+							 */ 
+	unsigned int			safemode_delay;
+	struct timer_list		safemode_timer;
+	atomic_t			writes_pending; 
+	struct request_queue		*queue;	/* for plugging ... */
+
+	atomic_t                        write_behind; /* outstanding async IO */
+	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 list_head		all_mddevs;
+};
+
+
+static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+	int faulty = test_bit(Faulty, &rdev->flags);
+	if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
+		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+}
+
+static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
+{
+        atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
+}
+
+struct mdk_personality
+{
+	char *name;
+	int level;
+	struct list_head list;
+	struct module *owner;
+	int (*make_request)(struct request_queue *q, struct bio *bio);
+	int (*run)(mddev_t *mddev);
+	int (*stop)(mddev_t *mddev);
+	void (*status)(struct seq_file *seq, mddev_t *mddev);
+	/* error_handler must set ->faulty and clear ->in_sync
+	 * if appropriate, and should abort recovery if needed 
+	 */
+	void (*error_handler)(mddev_t *mddev, mdk_rdev_t *rdev);
+	int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
+	int (*hot_remove_disk) (mddev_t *mddev, int number);
+	int (*spare_active) (mddev_t *mddev);
+	sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
+	int (*resize) (mddev_t *mddev, sector_t sectors);
+	sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
+	int (*check_reshape) (mddev_t *mddev);
+	int (*start_reshape) (mddev_t *mddev);
+	void (*finish_reshape) (mddev_t *mddev);
+	int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
+	/* quiesce moves between quiescence states
+	 * 0 - fully active
+	 * 1 - no new requests allowed
+	 * others - reserved
+	 */
+	void (*quiesce) (mddev_t *mddev, int state);
+	/* takeover is used to transition an array from one
+	 * personality to another.  The new personality must be able
+	 * to handle the data in the current layout.
+	 * e.g. 2drive raid1 -> 2drive raid5
+	 *      ndrive raid5 -> degraded n+1drive raid6 with special layout
+	 * If the takeover succeeds, a new 'private' structure is returned.
+	 * This needs to be installed and then ->run used to activate the
+	 * array.
+	 */
+	void *(*takeover) (mddev_t *mddev);
+};
+
+
+struct md_sysfs_entry {
+	struct attribute attr;
+	ssize_t (*show)(mddev_t *, char *);
+	ssize_t (*store)(mddev_t *, const char *, size_t);
+};
+
+
+static inline char * mdname (mddev_t * mddev)
+{
+	return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
+}
+
+/*
+ * iterates through some rdev ringlist. It's safe to remove the
+ * current 'rdev'. Dont touch 'tmp' though.
+ */
+#define rdev_for_each_list(rdev, tmp, head)				\
+	list_for_each_entry_safe(rdev, tmp, head, same_set)
+
+/*
+ * iterates through the 'same array disks' ringlist
+ */
+#define rdev_for_each(rdev, tmp, mddev)				\
+	list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set)
+
+#define rdev_for_each_rcu(rdev, mddev)				\
+	list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
+
+typedef struct mdk_thread_s {
+	void			(*run) (mddev_t *mddev);
+	mddev_t			*mddev;
+	wait_queue_head_t	wqueue;
+	unsigned long           flags;
+	struct task_struct	*tsk;
+	unsigned long		timeout;
+} mdk_thread_t;
+
+#define THREAD_WAKEUP  0
+
+#define __wait_event_lock_irq(wq, condition, lock, cmd) 		\
+do {									\
+	wait_queue_t __wait;						\
+	init_waitqueue_entry(&__wait, current);				\
+									\
+	add_wait_queue(&wq, &__wait);					\
+	for (;;) {							\
+		set_current_state(TASK_UNINTERRUPTIBLE);		\
+		if (condition)						\
+			break;						\
+		spin_unlock_irq(&lock);					\
+		cmd;							\
+		schedule();						\
+		spin_lock_irq(&lock);					\
+	}								\
+	current->state = TASK_RUNNING;					\
+	remove_wait_queue(&wq, &__wait);				\
+} while (0)
+
+#define wait_event_lock_irq(wq, condition, lock, cmd) 			\
+do {									\
+	if (condition)	 						\
+		break;							\
+	__wait_event_lock_irq(wq, condition, lock, cmd);		\
+} while (0)
+
+static inline void safe_put_page(struct page *p)
+{
+	if (p) put_page(p);
+}
+
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
+				mddev_t *mddev, const char *name);
+extern void md_unregister_thread(mdk_thread_t *thread);
+extern void md_wakeup_thread(mdk_thread_t *thread);
+extern void md_check_recovery(mddev_t *mddev);
+extern void md_write_start(mddev_t *mddev, struct bio *bi);
+extern void md_write_end(mddev_t *mddev);
+extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
+
+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);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+			struct page *page, int rw);
+extern void md_do_sync(mddev_t *mddev);
+extern void md_new_event(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
+extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
+
+#endif /* _MD_MD_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/mktables.c linux-libre-2.6.30-gnu1/drivers/md/mktables.c
--- linux-libre-2.6.29-gnu1/drivers/md/mktables.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/mktables.c	2009-06-09 23:05:27.000000000 -0400
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
 	uint8_t v;
 	uint8_t exptbl[256], invtbl[256];
 
-	printf("#include \"raid6.h\"\n");
+	printf("#include <linux/raid/pq.h>\n");
 
 	/* Compute multiplication table */
 	printf("\nconst u8  __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@ int main(int argc, char *argv[])
 		printf("\t},\n");
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+	printf("#endif\n");
 
 	/* Compute power-of-2 table (exponent) */
 	v = 1;
@@ -92,6 +95,9 @@ int main(int argc, char *argv[])
 		}
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+	printf("#endif\n");
 
 	/* Compute inverse table x^-1 == x^254 */
 	printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@ int main(int argc, char *argv[])
 		}
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+	printf("#endif\n");
 
 	/* Compute inv(2^x + 1) (exponent-xor-inverse) table */
 	printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@ int main(int argc, char *argv[])
 			       (j == 7) ? '\n' : ' ');
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+	printf("#endif\n");
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/multipath.c linux-libre-2.6.30-gnu1/drivers/md/multipath.c
--- linux-libre-2.6.29-gnu1/drivers/md/multipath.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/multipath.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,7 +19,11 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/raid/multipath.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "multipath.h"
 
 #define MAX_WORK_PER_DISK 128
 
@@ -402,6 +406,14 @@ static void multipathd (mddev_t *mddev)
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 }
 
+static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	return mddev->dev_sectors;
+}
+
 static int multipath_run (mddev_t *mddev)
 {
 	multipath_conf_t *conf;
@@ -498,7 +510,7 @@ static int multipath_run (mddev_t *mddev
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
 
 	mddev->queue->unplug_fn = multipath_unplug;
 	mddev->queue->backing_dev_info.congested_fn = multipath_congested;
@@ -543,6 +555,7 @@ static struct mdk_personality multipath_
 	.error_handler	= multipath_error,
 	.hot_add_disk	= multipath_add_disk,
 	.hot_remove_disk= multipath_remove_disk,
+	.size		= multipath_size,
 };
 
 static int __init multipath_init (void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/multipath.h linux-libre-2.6.30-gnu1/drivers/md/multipath.h
--- linux-libre-2.6.29-gnu1/drivers/md/multipath.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/multipath.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,40 @@
+#ifndef _MULTIPATH_H
+#define _MULTIPATH_H
+
+struct multipath_info {
+	mdk_rdev_t	*rdev;
+};
+
+struct multipath_private_data {
+	mddev_t			*mddev;
+	struct multipath_info	*multipaths;
+	int			raid_disks;
+	int			working_disks;
+	spinlock_t		device_lock;
+	struct list_head	retry_list;
+
+	mempool_t		*pool;
+};
+
+typedef struct multipath_private_data multipath_conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((multipath_conf_t *) mddev->private)
+
+/*
+ * this is our 'private' 'collective' MULTIPATH buffer head.
+ * it contains information about what kind of IO operations were started
+ * for this MULTIPATH operation, and about their status:
+ */
+
+struct multipath_bh {
+	mddev_t			*mddev;
+	struct bio		*master_bio;
+	struct bio		bio;
+	int			path;
+	struct list_head	retry_list;
+};
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid0.c linux-libre-2.6.30-gnu1/drivers/md/raid0.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid0.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid0.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,7 +18,10 @@
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/raid/raid0.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid0.h"
 
 static void raid0_unplug(struct request_queue *q)
 {
@@ -73,16 +76,15 @@ static int create_strip_zones (mddev_t *
 		list_for_each_entry(rdev2, &mddev->disks, same_set) {
 			printk(KERN_INFO "raid0:   comparing %s(%llu)",
 			       bdevname(rdev1->bdev,b),
-			       (unsigned long long)rdev1->size);
+			       (unsigned long long)rdev1->sectors);
 			printk(KERN_INFO " with %s(%llu)\n",
 			       bdevname(rdev2->bdev,b),
-			       (unsigned long long)rdev2->size);
+			       (unsigned long long)rdev2->sectors);
 			if (rdev2 == rdev1) {
 				printk(KERN_INFO "raid0:   END\n");
 				break;
 			}
-			if (rdev2->size == rdev1->size)
-			{
+			if (rdev2->sectors == rdev1->sectors) {
 				/*
 				 * Not unique, don't count it as a new
 				 * group
@@ -145,7 +147,7 @@ static int create_strip_zones (mddev_t *
 		    mddev->queue->max_sectors > (PAGE_SIZE>>9))
 			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
-		if (!smallest || (rdev1->size <smallest->size))
+		if (!smallest || (rdev1->sectors < smallest->sectors))
 			smallest = rdev1;
 		cnt++;
 	}
@@ -155,10 +157,10 @@ static int create_strip_zones (mddev_t *
 		goto abort;
 	}
 	zone->nb_dev = cnt;
-	zone->sectors = smallest->size * cnt * 2;
+	zone->sectors = smallest->sectors * cnt;
 	zone->zone_start = 0;
 
-	current_start = smallest->size * 2;
+	current_start = smallest->sectors;
 	curr_zone_start = zone->sectors;
 
 	/* now do the other zones */
@@ -177,29 +179,29 @@ static int create_strip_zones (mddev_t *
 			rdev = conf->strip_zone[0].dev[j];
 			printk(KERN_INFO "raid0: checking %s ...",
 				bdevname(rdev->bdev, b));
-			if (rdev->size > current_start / 2) {
-				printk(KERN_INFO " contained as device %d\n",
-					c);
-				zone->dev[c] = rdev;
-				c++;
-				if (!smallest || (rdev->size <smallest->size)) {
-					smallest = rdev;
-					printk(KERN_INFO "  (%llu) is smallest!.\n",
-						(unsigned long long)rdev->size);
-				}
-			} else
+			if (rdev->sectors <= current_start) {
 				printk(KERN_INFO " nope.\n");
+				continue;
+			}
+			printk(KERN_INFO " contained as device %d\n", c);
+			zone->dev[c] = rdev;
+			c++;
+			if (!smallest || rdev->sectors < smallest->sectors) {
+				smallest = rdev;
+				printk(KERN_INFO "  (%llu) is smallest!.\n",
+					(unsigned long long)rdev->sectors);
+			}
 		}
 
 		zone->nb_dev = c;
-		zone->sectors = (smallest->size * 2 - current_start) * c;
+		zone->sectors = (smallest->sectors - current_start) * c;
 		printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n",
 			zone->nb_dev, (unsigned long long)zone->sectors);
 
 		zone->zone_start = curr_zone_start;
 		curr_zone_start += zone->sectors;
 
-		current_start = smallest->size * 2;
+		current_start = smallest->sectors;
 		printk(KERN_INFO "raid0: current zone start: %llu\n",
 			(unsigned long long)current_start);
 	}
@@ -261,12 +263,25 @@ static int raid0_mergeable_bvec(struct r
 		return max;
 }
 
+static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	sector_t array_sectors = 0;
+	mdk_rdev_t *rdev;
+
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	list_for_each_entry(rdev, &mddev->disks, same_set)
+		array_sectors += rdev->sectors;
+
+	return array_sectors;
+}
+
 static int raid0_run (mddev_t *mddev)
 {
 	unsigned  cur=0, i=0, nb_zone;
 	s64 sectors;
 	raid0_conf_t *conf;
-	mdk_rdev_t *rdev;
 
 	if (mddev->chunk_size == 0) {
 		printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
@@ -291,16 +306,14 @@ static int raid0_run (mddev_t *mddev)
 		goto out_free_conf;
 
 	/* calculate array device size */
-	mddev->array_sectors = 0;
-	list_for_each_entry(rdev, &mddev->disks, same_set)
-		mddev->array_sectors += rdev->size * 2;
+	md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));
 
 	printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
 		(unsigned long long)mddev->array_sectors);
 	printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n",
 		(unsigned long long)conf->spacing);
 	{
-		sector_t s = mddev->array_sectors;
+		sector_t s = raid0_size(mddev, 0, 0);
 		sector_t space = conf->spacing;
 		int round;
 		conf->sector_shift = 0;
@@ -509,6 +522,7 @@ static struct mdk_personality raid0_pers
 	.run		= raid0_run,
 	.stop		= raid0_stop,
 	.status		= raid0_status,
+	.size		= raid0_size,
 };
 
 static int __init raid0_init (void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid0.h linux-libre-2.6.30-gnu1/drivers/md/raid0.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid0.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/raid0.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,28 @@
+#ifndef _RAID0_H
+#define _RAID0_H
+
+struct strip_zone
+{
+	sector_t zone_start;	/* Zone offset in md_dev (in sectors) */
+	sector_t dev_start;	/* Zone offset in real dev (in sectors) */
+	sector_t sectors;	/* Zone size in sectors */
+	int nb_dev;		/* # of devices attached to the zone */
+	mdk_rdev_t **dev;	/* Devices attached to the zone */
+};
+
+struct raid0_private_data
+{
+	struct strip_zone **hash_table; /* Table of indexes into strip_zone */
+	struct strip_zone *strip_zone;
+	mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
+	int nr_strip_zones;
+
+	sector_t spacing;
+	int sector_shift; /* shift this before divide by spacing */
+};
+
+typedef struct raid0_private_data raid0_conf_t;
+
+#define mddev_to_conf(mddev) ((raid0_conf_t *) mddev->private)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid10.c linux-libre-2.6.30-gnu1/drivers/md/raid10.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid10.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid10.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,10 +18,12 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "dm-bio-list.h"
 #include <linux/delay.h>
-#include <linux/raid/raid10.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid10.h"
+#include "bitmap.h"
 
 /*
  * RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -1695,7 +1697,7 @@ static sector_t sync_request(mddev_t *md
 			return 0;
 
  skipped:
-	max_sector = mddev->size << 1;
+	max_sector = mddev->dev_sectors;
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		max_sector = mddev->resync_max_sectors;
 	if (sector_nr >= max_sector) {
@@ -1807,17 +1809,17 @@ static sector_t sync_request(mddev_t *md
 				r10_bio->sector = sect;
 
 				raid10_find_phys(conf, r10_bio);
-				/* Need to check if this section will still be
+
+				/* Need to check if the array will still be
 				 * degraded
 				 */
-				for (j=0; j<conf->copies;j++) {
-					int d = r10_bio->devs[j].devnum;
-					if (conf->mirrors[d].rdev == NULL ||
-					    test_bit(Faulty, &conf->mirrors[d].rdev->flags)) {
+				for (j=0; j<conf->raid_disks; j++)
+					if (conf->mirrors[j].rdev == NULL ||
+					    test_bit(Faulty, &conf->mirrors[j].rdev->flags)) {
 						still_degraded = 1;
 						break;
 					}
-				}
+
 				must_sync = bitmap_start_sync(mddev->bitmap, sect,
 							      &sync_blocks, still_degraded);
 
@@ -2020,6 +2022,25 @@ static sector_t sync_request(mddev_t *md
 	goto skipped;
 }
 
+static sector_t
+raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	sector_t size;
+	conf_t *conf = mddev_to_conf(mddev);
+
+	if (!raid_disks)
+		raid_disks = mddev->raid_disks;
+	if (!sectors)
+		sectors = mddev->dev_sectors;
+
+	size = sectors >> conf->chunk_shift;
+	sector_div(size, conf->far_copies);
+	size = size * raid_disks;
+	sector_div(size, conf->near_copies);
+
+	return size << conf->chunk_shift;
+}
+
 static int run(mddev_t *mddev)
 {
 	conf_t *conf;
@@ -2076,7 +2097,7 @@ static int run(mddev_t *mddev)
 	conf->far_offset = fo;
 	conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
 	conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
-	size = mddev->size >> (conf->chunk_shift-1);
+	size = mddev->dev_sectors >> conf->chunk_shift;
 	sector_div(size, fc);
 	size = size * conf->raid_disks;
 	sector_div(size, nc);
@@ -2089,7 +2110,7 @@ static int run(mddev_t *mddev)
 	 */
 	stride += conf->raid_disks - 1;
 	sector_div(stride, conf->raid_disks);
-	mddev->size = stride  << (conf->chunk_shift-1);
+	mddev->dev_sectors = stride << conf->chunk_shift;
 
 	if (fo)
 		stride = 1;
@@ -2171,8 +2192,8 @@ static int run(mddev_t *mddev)
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = size << conf->chunk_shift;
-	mddev->resync_max_sectors = size << conf->chunk_shift;
+	md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
+	mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
 
 	mddev->queue->unplug_fn = raid10_unplug;
 	mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2208,6 +2229,9 @@ static int stop(mddev_t *mddev)
 {
 	conf_t *conf = mddev_to_conf(mddev);
 
+	raise_barrier(conf, 0);
+	lower_barrier(conf);
+
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2255,6 +2279,7 @@ static struct mdk_personality raid10_per
 	.spare_active	= raid10_spare_active,
 	.sync_request	= sync_request,
 	.quiesce	= raid10_quiesce,
+	.size		= raid10_size,
 };
 
 static int __init raid_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid10.h linux-libre-2.6.30-gnu1/drivers/md/raid10.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid10.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/raid10.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,121 @@
+#ifndef _RAID10_H
+#define _RAID10_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+	mdk_rdev_t	*rdev;
+	sector_t	head_position;
+};
+
+typedef struct r10bio_s r10bio_t;
+
+struct r10_private_data_s {
+	mddev_t			*mddev;
+	mirror_info_t		*mirrors;
+	int			raid_disks;
+	spinlock_t		device_lock;
+
+	/* geometry */
+	int			near_copies;  /* number of copies layed out raid0 style */
+	int 			far_copies;   /* number of copies layed out
+					       * at large strides across drives
+					       */
+	int			far_offset;   /* far_copies are offset by 1 stripe
+					       * instead of many
+					       */
+	int			copies;	      /* near_copies * far_copies.
+					       * must be <= raid_disks
+					       */
+	sector_t		stride;	      /* distance between far copies.
+					       * This is size / far_copies unless
+					       * far_offset, in which case it is
+					       * 1 stripe.
+					       */
+
+	int chunk_shift; /* shift from chunks to sectors */
+	sector_t chunk_mask;
+
+	struct list_head	retry_list;
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+
+
+	spinlock_t		resync_lock;
+	int nr_pending;
+	int nr_waiting;
+	int nr_queued;
+	int barrier;
+	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	wait_queue_head_t	wait_barrier;
+
+	mempool_t *r10bio_pool;
+	mempool_t *r10buf_pool;
+	struct page		*tmppage;
+};
+
+typedef struct r10_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID10 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID10 operation, and about their status:
+ */
+
+struct r10bio_s {
+	atomic_t		remaining; /* 'have we finished' count,
+					    * used from IRQ handlers
+					    */
+	sector_t		sector;	/* virtual sector number */
+	int			sectors;
+	unsigned long		state;
+	mddev_t			*mddev;
+	/*
+	 * original bio going to /dev/mdx
+	 */
+	struct bio		*master_bio;
+	/*
+	 * if the IO is in READ direction, then this is where we read
+	 */
+	int			read_slot;
+
+	struct list_head	retry_list;
+	/*
+	 * if the IO is in WRITE direction, then multiple bios are used,
+	 * one for each copy.
+	 * When resyncing we also use one for each copy.
+	 * When reconstructing, we use 2 bios, one for read, one for write.
+	 * We choose the number when they are allocated.
+	 */
+	struct {
+		struct bio		*bio;
+		sector_t addr;
+		int devnum;
+	} devs[0];
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r10bio.state */
+#define	R10BIO_Uptodate	0
+#define	R10BIO_IsSync	1
+#define	R10BIO_IsRecover 2
+#define	R10BIO_Degraded 3
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid1.c linux-libre-2.6.30-gnu1/drivers/md/raid1.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid1.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,10 +31,12 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "dm-bio-list.h"
 #include <linux/delay.h>
-#include <linux/raid/raid1.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid1.h"
+#include "bitmap.h"
 
 #define DEBUG 0
 #if DEBUG
@@ -120,6 +122,7 @@ static void * r1buf_pool_alloc(gfp_t gfp
 				goto out_free_pages;
 
 			bio->bi_io_vec[i].bv_page = page;
+			bio->bi_vcnt = i+1;
 		}
 	}
 	/* If not user-requests, copy the page pointers to all bios */
@@ -135,9 +138,9 @@ static void * r1buf_pool_alloc(gfp_t gfp
 	return r1_bio;
 
 out_free_pages:
-	for (i=0; i < RESYNC_PAGES ; i++)
-		for (j=0 ; j < pi->raid_disks; j++)
-			safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
+	for (j=0 ; j < pi->raid_disks; j++)
+		for (i=0; i < r1_bio->bios[j]->bi_vcnt ; i++)
+			put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
 	j = -1;
 out_free_bio:
 	while ( ++j < pi->raid_disks )
@@ -582,7 +585,7 @@ static int raid1_congested(void *data, i
 			/* Note the '|| 1' - when read_balance prefers
 			 * non-congested targets, it can be removed
 			 */
-			if ((bits & (1<<BDI_write_congested)) || 1)
+			if ((bits & (1<<BDI_async_congested)) || 1)
 				ret |= bdi_congested(&q->backing_dev_info, bits);
 			else
 				ret &= bdi_congested(&q->backing_dev_info, bits);
@@ -1723,7 +1726,7 @@ static sector_t sync_request(mddev_t *md
 			return 0;
 	}
 
-	max_sector = mddev->size << 1;
+	max_sector = mddev->dev_sectors;
 	if (sector_nr >= max_sector) {
 		/* If we aborted, we need to abort the
 		 * sync on the 'current' bitmap chunk (there will
@@ -1919,6 +1922,14 @@ static sector_t sync_request(mddev_t *md
 	return nr_sectors;
 }
 
+static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	if (sectors)
+		return sectors;
+
+	return mddev->dev_sectors;
+}
+
 static int run(mddev_t *mddev)
 {
 	conf_t *conf;
@@ -2048,7 +2059,7 @@ static int run(mddev_t *mddev)
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
 
 	mddev->queue->unplug_fn = raid1_unplug;
 	mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2089,6 +2100,9 @@ static int stop(mddev_t *mddev)
 		/* need to kick something here to make sure I/O goes? */
 	}
 
+	raise_barrier(conf);
+	lower_barrier(conf);
+
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2110,15 +2124,17 @@ static int raid1_resize(mddev_t *mddev,
 	 * any io in the removed space completes, but it hardly seems
 	 * worth it.
 	 */
-	mddev->array_sectors = sectors;
+	md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0));
+	if (mddev->array_sectors > raid1_size(mddev, sectors, 0))
+		return -EINVAL;
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	mddev->changed = 1;
-	if (mddev->array_sectors / 2 > mddev->size &&
+	if (sectors > mddev->dev_sectors &&
 	    mddev->recovery_cp == MaxSector) {
-		mddev->recovery_cp = mddev->size << 1;
+		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
-	mddev->size = mddev->array_sectors / 2;
+	mddev->dev_sectors = sectors;
 	mddev->resync_max_sectors = sectors;
 	return 0;
 }
@@ -2264,6 +2280,7 @@ static struct mdk_personality raid1_pers
 	.spare_active	= raid1_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid1_resize,
+	.size		= raid1_size,
 	.check_reshape	= raid1_reshape,
 	.quiesce	= raid1_quiesce,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid1.h linux-libre-2.6.30-gnu1/drivers/md/raid1.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid1.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/raid1.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,132 @@
+#ifndef _RAID1_H
+#define _RAID1_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+	mdk_rdev_t	*rdev;
+	sector_t	head_position;
+};
+
+/*
+ * memory pools need a pointer to the mddev, so they can force an unplug
+ * when memory is tight, and a count of the number of drives that the
+ * pool was allocated for, so they know how much to allocate and free.
+ * mddev->raid_disks cannot be used, as it can change while a pool is active
+ * These two datums are stored in a kmalloced struct.
+ */
+
+struct pool_info {
+	mddev_t *mddev;
+	int	raid_disks;
+};
+
+
+typedef struct r1bio_s r1bio_t;
+
+struct r1_private_data_s {
+	mddev_t			*mddev;
+	mirror_info_t		*mirrors;
+	int			raid_disks;
+	int			last_used;
+	sector_t		next_seq_sect;
+	spinlock_t		device_lock;
+
+	struct list_head	retry_list;
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+	/* queue of writes that have been unplugged */
+	struct bio_list		flushing_bio_list;
+
+	/* for use when syncing mirrors: */
+
+	spinlock_t		resync_lock;
+	int			nr_pending;
+	int			nr_waiting;
+	int			nr_queued;
+	int			barrier;
+	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	wait_queue_head_t	wait_barrier;
+
+	struct pool_info	*poolinfo;
+
+	struct page		*tmppage;
+
+	mempool_t *r1bio_pool;
+	mempool_t *r1buf_pool;
+};
+
+typedef struct r1_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID1 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID1 operation, and about their status:
+ */
+
+struct r1bio_s {
+	atomic_t		remaining; /* 'have we finished' count,
+					    * used from IRQ handlers
+					    */
+	atomic_t		behind_remaining; /* number of write-behind ios remaining
+						 * in this BehindIO request
+						 */
+	sector_t		sector;
+	int			sectors;
+	unsigned long		state;
+	mddev_t			*mddev;
+	/*
+	 * original bio going to /dev/mdx
+	 */
+	struct bio		*master_bio;
+	/*
+	 * if the IO is in READ direction, then this is where we read
+	 */
+	int			read_disk;
+
+	struct list_head	retry_list;
+	struct bitmap_update	*bitmap_update;
+	/*
+	 * if the IO is in WRITE direction, then multiple bios are used.
+	 * We choose the number when they are allocated.
+	 */
+	struct bio		*bios[0];
+	/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r1bio.state */
+#define	R1BIO_Uptodate	0
+#define	R1BIO_IsSync	1
+#define	R1BIO_Degraded	2
+#define	R1BIO_BehindIO	3
+#define	R1BIO_Barrier	4
+#define R1BIO_BarrierRetry 5
+/* For write-behind requests, we call bi_end_io when
+ * the last non-write-behind device completes, providing
+ * any write was successful.  Otherwise we call when
+ * any write-behind write succeeds, otherwise we call
+ * with failure when last write completes (and all failed).
+ * Record that bi_end_io was called with this flag...
+ */
+#define	R1BIO_Returned 6
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid5.c linux-libre-2.6.30-gnu1/drivers/md/raid5.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid5.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid5.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,11 +43,14 @@
  * miss any bits.
  */
 
+#include <linux/blkdev.h>
 #include <linux/kthread.h>
-#include "raid6.h"
-
-#include <linux/raid/bitmap.h>
+#include <linux/raid/pq.h>
 #include <linux/async_tx.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid5.h"
+#include "bitmap.h"
 
 /*
  * Stripe cache
@@ -91,11 +94,6 @@
 
 #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
 
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
 /*
  * We maintain a biased count of active stripes in the bottom 16 bits of
  * bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -130,12 +128,42 @@ static inline void raid5_set_bi_hw_segme
 	bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
 }
 
+/* Find first data disk in a raid6 stripe */
+static inline int raid6_d0(struct stripe_head *sh)
+{
+	if (sh->ddf_layout)
+		/* ddf always start from first device */
+		return 0;
+	/* md starts just after Q block */
+	if (sh->qd_idx == sh->disks - 1)
+		return 0;
+	else
+		return sh->qd_idx + 1;
+}
 static inline int raid6_next_disk(int disk, int raid_disks)
 {
 	disk++;
 	return (disk < raid_disks) ? disk : 0;
 }
 
+/* When walking through the disks in a raid5, starting at raid6_d0,
+ * We need to map each disk to a 'slot', where the data disks are slot
+ * 0 .. raid_disks-3, the parity disk is raid_disks-2 and the Q disk
+ * is raid_disks-1.  This help does that mapping.
+ */
+static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
+			     int *count, int syndrome_disks)
+{
+	int slot;
+
+	if (idx == sh->pd_idx)
+		return syndrome_disks;
+	if (idx == sh->qd_idx)
+		return syndrome_disks + 1;
+	slot = (*count)++;
+	return slot;
+}
+
 static void return_io(struct bio *return_bi)
 {
 	struct bio *bi = return_bi;
@@ -193,6 +221,7 @@ static void __release_stripe(raid5_conf_
 		}
 	}
 }
+
 static void release_stripe(struct stripe_head *sh)
 {
 	raid5_conf_t *conf = sh->raid_conf;
@@ -270,9 +299,11 @@ static int grow_buffers(struct stripe_he
 	return 0;
 }
 
-static void raid5_build_block(struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i, int previous);
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+			    struct stripe_head *sh);
 
-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
 {
 	raid5_conf_t *conf = sh->raid_conf;
 	int i;
@@ -287,11 +318,12 @@ static void init_stripe(struct stripe_he
 
 	remove_hash(sh);
 
+	sh->generation = conf->generation - previous;
+	sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
 	sh->sector = sector;
-	sh->pd_idx = pd_idx;
+	stripe_set_idx(sector, conf, previous, sh);
 	sh->state = 0;
 
-	sh->disks = disks;
 
 	for (i = sh->disks; i--; ) {
 		struct r5dev *dev = &sh->dev[i];
@@ -305,12 +337,13 @@ static void init_stripe(struct stripe_he
 			BUG();
 		}
 		dev->flags = 0;
-		raid5_build_block(sh, i);
+		raid5_build_block(sh, i, previous);
 	}
 	insert_hash(conf, sh);
 }
 
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+					 short generation)
 {
 	struct stripe_head *sh;
 	struct hlist_node *hn;
@@ -318,7 +351,7 @@ static struct stripe_head *__find_stripe
 	CHECK_DEVLOCK();
 	pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
 	hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
-		if (sh->sector == sector && sh->disks == disks)
+		if (sh->sector == sector && sh->generation == generation)
 			return sh;
 	pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
 	return NULL;
@@ -327,8 +360,9 @@ static struct stripe_head *__find_stripe
 static void unplug_slaves(mddev_t *mddev);
 static void raid5_unplug_device(struct request_queue *q);
 
-static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
-					     int pd_idx, int noblock)
+static struct stripe_head *
+get_active_stripe(raid5_conf_t *conf, sector_t sector,
+		  int previous, int noblock, int noquiesce)
 {
 	struct stripe_head *sh;
 
@@ -338,9 +372,9 @@ static struct stripe_head *get_active_st
 
 	do {
 		wait_event_lock_irq(conf->wait_for_stripe,
-				    conf->quiesce == 0,
+				    conf->quiesce == 0 || noquiesce,
 				    conf->device_lock, /* nothing */);
-		sh = __find_stripe(conf, sector, disks);
+		sh = __find_stripe(conf, sector, conf->generation - previous);
 		if (!sh) {
 			if (!conf->inactive_blocked)
 				sh = get_free_stripe(conf);
@@ -358,10 +392,11 @@ static struct stripe_head *get_active_st
 					);
 				conf->inactive_blocked = 0;
 			} else
-				init_stripe(sh, sector, pd_idx, disks);
+				init_stripe(sh, sector, previous);
 		} else {
 			if (atomic_read(&sh->count)) {
-			  BUG_ON(!list_empty(&sh->lru));
+				BUG_ON(!list_empty(&sh->lru)
+				    && !test_bit(STRIPE_EXPANDING, &sh->state));
 			} else {
 				if (!test_bit(STRIPE_HANDLE, &sh->state))
 					atomic_inc(&conf->active_stripes);
@@ -895,8 +930,10 @@ static int grow_stripes(raid5_conf_t *co
 	struct kmem_cache *sc;
 	int devs = conf->raid_disks;
 
-	sprintf(conf->cache_name[0], "raid5-%s", mdname(conf->mddev));
-	sprintf(conf->cache_name[1], "raid5-%s-alt", mdname(conf->mddev));
+	sprintf(conf->cache_name[0],
+		"raid%d-%s", conf->level, mdname(conf->mddev));
+	sprintf(conf->cache_name[1],
+		"raid%d-%s-alt", conf->level, mdname(conf->mddev));
 	conf->active_name = 0;
 	sc = kmem_cache_create(conf->cache_name[conf->active_name],
 			       sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
@@ -911,7 +948,6 @@ static int grow_stripes(raid5_conf_t *co
 	return 0;
 }
 
-#ifdef CONFIG_MD_RAID5_RESHAPE
 static int resize_stripes(raid5_conf_t *conf, int newsize)
 {
 	/* Make all the stripes able to hold 'newsize' devices.
@@ -1036,7 +1072,6 @@ static int resize_stripes(raid5_conf_t *
 	conf->pool_size = newsize;
 	return err;
 }
-#endif
 
 static int drop_one_stripe(raid5_conf_t *conf)
 {
@@ -1066,7 +1101,7 @@ static void shrink_stripes(raid5_conf_t
 
 static void raid5_end_read_request(struct bio * bi, int error)
 {
- 	struct stripe_head *sh = bi->bi_private;
+	struct stripe_head *sh = bi->bi_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks, i;
 	int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1148,7 +1183,7 @@ static void raid5_end_read_request(struc
 
 static void raid5_end_write_request(struct bio *bi, int error)
 {
- 	struct stripe_head *sh = bi->bi_private;
+	struct stripe_head *sh = bi->bi_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks, i;
 	int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1176,9 +1211,9 @@ static void raid5_end_write_request(stru
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
 	
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
 {
 	struct r5dev *dev = &sh->dev[i];
 
@@ -1194,7 +1229,7 @@ static void raid5_build_block(struct str
 	dev->req.bi_private = sh;
 
 	dev->flags = 0;
-	dev->sector = compute_blocknr(sh, i);
+	dev->sector = compute_blocknr(sh, i, previous);
 }
 
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1227,15 +1262,23 @@ static void error(mddev_t *mddev, mdk_rd
  * Input: a 'big' sector number,
  * Output: index of the data and parity disk, and the sector # in them.
  */
-static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
-			unsigned int data_disks, unsigned int * dd_idx,
-			unsigned int * pd_idx, raid5_conf_t *conf)
+static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
+				     int previous, int *dd_idx,
+				     struct stripe_head *sh)
 {
 	long stripe;
 	unsigned long chunk_number;
 	unsigned int chunk_offset;
+	int pd_idx, qd_idx;
+	int ddf_layout = 0;
 	sector_t new_sector;
-	int sectors_per_chunk = conf->chunk_size >> 9;
+	int algorithm = previous ? conf->prev_algo
+				 : conf->algorithm;
+	int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+					 : (conf->chunk_size >> 9);
+	int raid_disks = previous ? conf->previous_raid_disks
+				  : conf->raid_disks;
+	int data_disks = raid_disks - conf->max_degraded;
 
 	/* First compute the information on this sector */
 
@@ -1259,68 +1302,170 @@ static sector_t raid5_compute_sector(sec
 	/*
 	 * Select the parity disk based on the user selected algorithm.
 	 */
+	pd_idx = qd_idx = ~0;
 	switch(conf->level) {
 	case 4:
-		*pd_idx = data_disks;
+		pd_idx = data_disks;
 		break;
 	case 5:
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			*pd_idx = data_disks - stripe % raid_disks;
-			if (*dd_idx >= *pd_idx)
+			pd_idx = data_disks - stripe % raid_disks;
+			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			if (*dd_idx >= *pd_idx)
+			pd_idx = stripe % raid_disks;
+			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			*pd_idx = data_disks - stripe % raid_disks;
-			*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+			pd_idx = data_disks - stripe % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_RIGHT_SYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+			pd_idx = stripe % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+			break;
+		case ALGORITHM_PARITY_0:
+			pd_idx = 0;
+			(*dd_idx)++;
+			break;
+		case ALGORITHM_PARITY_N:
+			pd_idx = data_disks;
 			break;
 		default:
 			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
-				conf->algorithm);
+				algorithm);
+			BUG();
 		}
 		break;
 	case 6:
 
-		/**** FIX THIS ****/
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			*pd_idx = raid_disks - 1 - (stripe % raid_disks);
-			if (*pd_idx == raid_disks-1)
-				(*dd_idx)++; 	/* Q D D D P */
-			else if (*dd_idx >= *pd_idx)
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			if (*pd_idx == raid_disks-1)
-				(*dd_idx)++; 	/* Q D D D P */
-			else if (*dd_idx >= *pd_idx)
+			pd_idx = stripe % raid_disks;
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			*pd_idx = raid_disks - 1 - (stripe % raid_disks);
-			*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = (pd_idx + 1) % raid_disks;
+			*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_RIGHT_SYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+			pd_idx = stripe % raid_disks;
+			qd_idx = (pd_idx + 1) % raid_disks;
+			*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
+			break;
+
+		case ALGORITHM_PARITY_0:
+			pd_idx = 0;
+			qd_idx = 1;
+			(*dd_idx) += 2;
+			break;
+		case ALGORITHM_PARITY_N:
+			pd_idx = data_disks;
+			qd_idx = data_disks + 1;
+			break;
+
+		case ALGORITHM_ROTATING_ZERO_RESTART:
+			/* Exactly the same as RIGHT_ASYMMETRIC, but or
+			 * of blocks for computing Q is different.
+			 */
+			pd_idx = stripe % raid_disks;
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
+				(*dd_idx) += 2; /* D D P Q D */
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_ROTATING_N_RESTART:
+			/* Same a left_asymmetric, by first stripe is
+			 * D D D P Q  rather than
+			 * Q D D D P
+			 */
+			pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
+				(*dd_idx) += 2; /* D D P Q D */
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_ROTATING_N_CONTINUE:
+			/* Same as left_symmetric but Q is before P */
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_LEFT_ASYMMETRIC_6:
+			/* RAID5 left_asymmetric, with Q on last device */
+			pd_idx = data_disks - stripe % (raid_disks-1);
+			if (*dd_idx >= pd_idx)
+				(*dd_idx)++;
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_RIGHT_ASYMMETRIC_6:
+			pd_idx = stripe % (raid_disks-1);
+			if (*dd_idx >= pd_idx)
+				(*dd_idx)++;
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_LEFT_SYMMETRIC_6:
+			pd_idx = data_disks - stripe % (raid_disks-1);
+			*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_RIGHT_SYMMETRIC_6:
+			pd_idx = stripe % (raid_disks-1);
+			*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_PARITY_0_6:
+			pd_idx = 0;
+			(*dd_idx)++;
+			qd_idx = raid_disks - 1;
 			break;
+
+
 		default:
 			printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	}
 
+	if (sh) {
+		sh->pd_idx = pd_idx;
+		sh->qd_idx = qd_idx;
+		sh->ddf_layout = ddf_layout;
+	}
 	/*
 	 * Finally, compute the new sector number
 	 */
@@ -1329,17 +1474,21 @@ static sector_t raid5_compute_sector(sec
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
 {
 	raid5_conf_t *conf = sh->raid_conf;
 	int raid_disks = sh->disks;
 	int data_disks = raid_disks - conf->max_degraded;
 	sector_t new_sector = sh->sector, check;
-	int sectors_per_chunk = conf->chunk_size >> 9;
+	int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+					 : (conf->chunk_size >> 9);
+	int algorithm = previous ? conf->prev_algo
+				 : conf->algorithm;
 	sector_t stripe;
 	int chunk_offset;
-	int chunk_number, dummy1, dummy2, dd_idx = i;
+	int chunk_number, dummy1, dd_idx = i;
 	sector_t r_sector;
+	struct stripe_head sh2;
 
 
 	chunk_offset = sector_div(new_sector, sectors_per_chunk);
@@ -1351,7 +1500,7 @@ static sector_t compute_blocknr(struct s
 	switch(conf->level) {
 	case 4: break;
 	case 5:
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
 		case ALGORITHM_RIGHT_ASYMMETRIC:
 			if (i > sh->pd_idx)
@@ -1363,19 +1512,27 @@ static sector_t compute_blocknr(struct s
 				i += raid_disks;
 			i -= (sh->pd_idx + 1);
 			break;
+		case ALGORITHM_PARITY_0:
+			i -= 1;
+			break;
+		case ALGORITHM_PARITY_N:
+			break;
 		default:
 			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	case 6:
-		if (i == raid6_next_disk(sh->pd_idx, raid_disks))
+		if (i == sh->qd_idx)
 			return 0; /* It is the Q disk */
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-		  	if (sh->pd_idx == raid_disks-1)
-				i--; 	/* Q D D D P */
+		case ALGORITHM_ROTATING_ZERO_RESTART:
+		case ALGORITHM_ROTATING_N_RESTART:
+			if (sh->pd_idx == raid_disks-1)
+				i--;	/* Q D D D P */
 			else if (i > sh->pd_idx)
 				i -= 2; /* D D P Q D */
 			break;
@@ -1390,9 +1547,35 @@ static sector_t compute_blocknr(struct s
 				i -= (sh->pd_idx + 2);
 			}
 			break;
+		case ALGORITHM_PARITY_0:
+			i -= 2;
+			break;
+		case ALGORITHM_PARITY_N:
+			break;
+		case ALGORITHM_ROTATING_N_CONTINUE:
+			if (sh->pd_idx == 0)
+				i--;	/* P D D D Q */
+			else if (i > sh->pd_idx)
+				i -= 2; /* D D Q P D */
+			break;
+		case ALGORITHM_LEFT_ASYMMETRIC_6:
+		case ALGORITHM_RIGHT_ASYMMETRIC_6:
+			if (i > sh->pd_idx)
+				i--;
+			break;
+		case ALGORITHM_LEFT_SYMMETRIC_6:
+		case ALGORITHM_RIGHT_SYMMETRIC_6:
+			if (i < sh->pd_idx)
+				i += data_disks + 1;
+			i -= (sh->pd_idx + 1);
+			break;
+		case ALGORITHM_PARITY_0_6:
+			i -= 1;
+			break;
 		default:
 			printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	}
@@ -1400,8 +1583,10 @@ static sector_t compute_blocknr(struct s
 	chunk_number = stripe * data_disks + i;
 	r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
 
-	check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
-	if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+	check = raid5_compute_sector(conf, r_sector,
+				     previous, &dummy1, &sh2);
+	if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
+		|| sh2.qd_idx != sh->qd_idx) {
 		printk(KERN_ERR "compute_blocknr: map not correct\n");
 		return 0;
 	}
@@ -1468,14 +1653,16 @@ static void copy_data(int frombio, struc
 
 static void compute_parity6(struct stripe_head *sh, int method)
 {
-	raid6_conf_t *conf = sh->raid_conf;
-	int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+	raid5_conf_t *conf = sh->raid_conf;
+	int i, pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+	int syndrome_disks = sh->ddf_layout ? disks : (disks - 2);
 	struct bio *chosen;
 	/**** FIX THIS: This could be very bad if disks is close to 256 ****/
-	void *ptrs[disks];
+	void *ptrs[syndrome_disks+2];
 
-	qd_idx = raid6_next_disk(pd_idx, disks);
-	d0_idx = raid6_next_disk(qd_idx, disks);
+	pd_idx = sh->pd_idx;
+	qd_idx = sh->qd_idx;
+	d0_idx = raid6_d0(sh);
 
 	pr_debug("compute_parity, stripe %llu, method %d\n",
 		(unsigned long long)sh->sector, method);
@@ -1513,24 +1700,29 @@ static void compute_parity6(struct strip
 			set_bit(R5_UPTODATE, &sh->dev[i].flags);
 		}
 
-//	switch(method) {
-//	case RECONSTRUCT_WRITE:
-//	case CHECK_PARITY:
-//	case UPDATE_PARITY:
-		/* Note that unlike RAID-5, the ordering of the disks matters greatly. */
-		/* FIX: Is this ordering of drives even remotely optimal? */
-		count = 0;
-		i = d0_idx;
-		do {
-			ptrs[count++] = page_address(sh->dev[i].page);
-			if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
-				printk("block %d/%d not uptodate on parity calc\n", i,count);
-			i = raid6_next_disk(i, disks);
-		} while ( i != d0_idx );
-//		break;
-//	}
+	/* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
 
-	raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs);
+	for (i = 0; i < disks; i++)
+		ptrs[i] = (void *)raid6_empty_zero_page;
+
+	count = 0;
+	i = d0_idx;
+	do {
+		int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+		ptrs[slot] = page_address(sh->dev[i].page);
+		if (slot < syndrome_disks &&
+		    !test_bit(R5_UPTODATE, &sh->dev[i].flags)) {
+			printk(KERN_ERR "block %d/%d not uptodate "
+			       "on parity calc\n", i, count);
+			BUG();
+		}
+
+		i = raid6_next_disk(i, disks);
+	} while (i != d0_idx);
+	BUG_ON(count != syndrome_disks);
+
+	raid6_call.gen_syndrome(syndrome_disks+2, STRIPE_SIZE, ptrs);
 
 	switch(method) {
 	case RECONSTRUCT_WRITE:
@@ -1552,8 +1744,7 @@ static void compute_block_1(struct strip
 {
 	int i, count, disks = sh->disks;
 	void *ptr[MAX_XOR_BLOCKS], *dest, *p;
-	int pd_idx = sh->pd_idx;
-	int qd_idx = raid6_next_disk(pd_idx, disks);
+	int qd_idx = sh->qd_idx;
 
 	pr_debug("compute_block_1, stripe %llu, idx %d\n",
 		(unsigned long long)sh->sector, dd_idx);
@@ -1589,63 +1780,65 @@ static void compute_block_1(struct strip
 static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
 {
 	int i, count, disks = sh->disks;
-	int pd_idx = sh->pd_idx;
-	int qd_idx = raid6_next_disk(pd_idx, disks);
-	int d0_idx = raid6_next_disk(qd_idx, disks);
-	int faila, failb;
+	int syndrome_disks = sh->ddf_layout ? disks : disks-2;
+	int d0_idx = raid6_d0(sh);
+	int faila = -1, failb = -1;
+	/**** FIX THIS: This could be very bad if disks is close to 256 ****/
+	void *ptrs[syndrome_disks+2];
 
-	/* faila and failb are disk numbers relative to d0_idx */
-	/* pd_idx become disks-2 and qd_idx become disks-1 */
-	faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx;
-	failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx;
+	for (i = 0; i < disks ; i++)
+		ptrs[i] = (void *)raid6_empty_zero_page;
+	count = 0;
+	i = d0_idx;
+	do {
+		int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+		ptrs[slot] = page_address(sh->dev[i].page);
+
+		if (i == dd_idx1)
+			faila = slot;
+		if (i == dd_idx2)
+			failb = slot;
+		i = raid6_next_disk(i, disks);
+	} while (i != d0_idx);
+	BUG_ON(count != syndrome_disks);
 
 	BUG_ON(faila == failb);
 	if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; }
 
 	pr_debug("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n",
-	       (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb);
+		 (unsigned long long)sh->sector, dd_idx1, dd_idx2,
+		 faila, failb);
 
-	if ( failb == disks-1 ) {
+	if (failb == syndrome_disks+1) {
 		/* Q disk is one of the missing disks */
-		if ( faila == disks-2 ) {
+		if (faila == syndrome_disks) {
 			/* Missing P+Q, just recompute */
 			compute_parity6(sh, UPDATE_PARITY);
 			return;
 		} else {
 			/* We're missing D+Q; recompute D from P */
-			compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
+			compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
+					     dd_idx2 : dd_idx1),
+					0);
 			compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
 			return;
 		}
 	}
 
-	/* We're missing D+P or D+D; build pointer table */
-	{
-		/**** FIX THIS: This could be very bad if disks is close to 256 ****/
-		void *ptrs[disks];
-
-		count = 0;
-		i = d0_idx;
-		do {
-			ptrs[count++] = page_address(sh->dev[i].page);
-			i = raid6_next_disk(i, disks);
-			if (i != dd_idx1 && i != dd_idx2 &&
-			    !test_bit(R5_UPTODATE, &sh->dev[i].flags))
-				printk("compute_2 with missing block %d/%d\n", count, i);
-		} while ( i != d0_idx );
-
-		if ( failb == disks-2 ) {
-			/* We're missing D+P. */
-			raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs);
-		} else {
-			/* We're missing D+D. */
-			raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs);
-		}
-
-		/* Both the above update both missing blocks */
-		set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
-		set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
+	/* We're missing D+P or D+D; */
+	if (failb == syndrome_disks) {
+		/* We're missing D+P. */
+		raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, faila, ptrs);
+	} else {
+		/* We're missing D+D. */
+		raid6_2data_recov(syndrome_disks+2, STRIPE_SIZE, faila, failb,
+				  ptrs);
 	}
+
+	/* Both the above update both missing blocks */
+	set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
+	set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
 }
 
 static void
@@ -1800,17 +1993,21 @@ static int page_is_zero(struct page *p)
 		memcmp(a, a+4, STRIPE_SIZE-4)==0);
 }
 
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+			    struct stripe_head *sh)
 {
-	int sectors_per_chunk = conf->chunk_size >> 9;
-	int pd_idx, dd_idx;
+	int sectors_per_chunk =
+		previous ? (conf->prev_chunk >> 9)
+			 : (conf->chunk_size >> 9);
+	int dd_idx;
 	int chunk_offset = sector_div(stripe, sectors_per_chunk);
+	int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
 
-	raid5_compute_sector(stripe * (disks - conf->max_degraded)
+	raid5_compute_sector(conf,
+			     stripe * (disks - conf->max_degraded)
 			     *sectors_per_chunk + chunk_offset,
-			     disks, disks - conf->max_degraded,
-			     &dd_idx, &pd_idx, conf);
-	return pd_idx;
+			     previous,
+			     &dd_idx, sh);
 }
 
 static void
@@ -2181,7 +2378,7 @@ static void handle_stripe_dirtying6(raid
 		struct r6_state *r6s, int disks)
 {
 	int rcw = 0, must_compute = 0, pd_idx = sh->pd_idx, i;
-	int qd_idx = r6s->qd_idx;
+	int qd_idx = sh->qd_idx;
 	for (i = disks; i--; ) {
 		struct r5dev *dev = &sh->dev[i];
 		/* Would I have to read this buffer for reconstruct_write */
@@ -2371,7 +2568,7 @@ static void handle_parity_checks6(raid5_
 	int update_p = 0, update_q = 0;
 	struct r5dev *dev;
 	int pd_idx = sh->pd_idx;
-	int qd_idx = r6s->qd_idx;
+	int qd_idx = sh->qd_idx;
 
 	set_bit(STRIPE_HANDLE, &sh->state);
 
@@ -2467,17 +2664,14 @@ static void handle_stripe_expansion(raid
 	struct dma_async_tx_descriptor *tx = NULL;
 	clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
 	for (i = 0; i < sh->disks; i++)
-		if (i != sh->pd_idx && (!r6s || i != r6s->qd_idx)) {
-			int dd_idx, pd_idx, j;
+		if (i != sh->pd_idx && i != sh->qd_idx) {
+			int dd_idx, j;
 			struct stripe_head *sh2;
 
-			sector_t bn = compute_blocknr(sh, i);
-			sector_t s = raid5_compute_sector(bn, conf->raid_disks,
-						conf->raid_disks -
-						conf->max_degraded, &dd_idx,
-						&pd_idx, conf);
-			sh2 = get_active_stripe(conf, s, conf->raid_disks,
-						pd_idx, 1);
+			sector_t bn = compute_blocknr(sh, i, 1);
+			sector_t s = raid5_compute_sector(conf, bn, 0,
+							  &dd_idx, NULL);
+			sh2 = get_active_stripe(conf, s, 0, 1, 1);
 			if (sh2 == NULL)
 				/* so far only the early blocks of this stripe
 				 * have been requested.  When later blocks
@@ -2500,8 +2694,7 @@ static void handle_stripe_expansion(raid
 			set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
 			for (j = 0; j < conf->raid_disks; j++)
 				if (j != sh2->pd_idx &&
-				    (!r6s || j != raid6_next_disk(sh2->pd_idx,
-								 sh2->disks)) &&
+				    (!r6s || j != sh2->qd_idx) &&
 				    !test_bit(R5_Expanded, &sh2->dev[j].flags))
 					break;
 			if (j == conf->raid_disks) {
@@ -2750,6 +2943,23 @@ static bool handle_stripe5(struct stripe
 
 	/* Finish reconstruct operations initiated by the expansion process */
 	if (sh->reconstruct_state == reconstruct_state_result) {
+		struct stripe_head *sh2
+			= get_active_stripe(conf, sh->sector, 1, 1, 1);
+		if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+			/* sh cannot be written until sh2 has been read.
+			 * so arrange for sh to be delayed a little
+			 */
+			set_bit(STRIPE_DELAYED, &sh->state);
+			set_bit(STRIPE_HANDLE, &sh->state);
+			if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+					      &sh2->state))
+				atomic_inc(&conf->preread_active_stripes);
+			release_stripe(sh2);
+			goto unlock;
+		}
+		if (sh2)
+			release_stripe(sh2);
+
 		sh->reconstruct_state = reconstruct_state_idle;
 		clear_bit(STRIPE_EXPANDING, &sh->state);
 		for (i = conf->raid_disks; i--; ) {
@@ -2763,8 +2973,7 @@ static bool handle_stripe5(struct stripe
 	    !sh->reconstruct_state) {
 		/* Need to write out all blocks after computing parity */
 		sh->disks = conf->raid_disks;
-		sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
-			conf->raid_disks);
+		stripe_set_idx(sh->sector, conf, 0, sh);
 		schedule_reconstruction5(sh, &s, 1, 1);
 	} else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
 		clear_bit(STRIPE_EXPAND_READY, &sh->state);
@@ -2796,20 +3005,19 @@ static bool handle_stripe5(struct stripe
 
 static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
 {
-	raid6_conf_t *conf = sh->raid_conf;
+	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks;
 	struct bio *return_bi = NULL;
-	int i, pd_idx = sh->pd_idx;
+	int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
 	struct stripe_head_state s;
 	struct r6_state r6s;
 	struct r5dev *dev, *pdev, *qdev;
 	mdk_rdev_t *blocked_rdev = NULL;
 
-	r6s.qd_idx = raid6_next_disk(pd_idx, disks);
 	pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
 		"pd_idx=%d, qd_idx=%d\n",
 	       (unsigned long long)sh->sector, sh->state,
-	       atomic_read(&sh->count), pd_idx, r6s.qd_idx);
+	       atomic_read(&sh->count), pd_idx, qd_idx);
 	memset(&s, 0, sizeof(s));
 
 	spin_lock(&sh->lock);
@@ -2920,9 +3128,9 @@ static bool handle_stripe6(struct stripe
 	pdev = &sh->dev[pd_idx];
 	r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx)
 		|| (s.failed >= 2 && r6s.failed_num[1] == pd_idx);
-	qdev = &sh->dev[r6s.qd_idx];
-	r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == r6s.qd_idx)
-		|| (s.failed >= 2 && r6s.failed_num[1] == r6s.qd_idx);
+	qdev = &sh->dev[qd_idx];
+	r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx)
+		|| (s.failed >= 2 && r6s.failed_num[1] == qd_idx);
 
 	if ( s.written &&
 	     ( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
@@ -2980,10 +3188,26 @@ static bool handle_stripe6(struct stripe
 		}
 
 	if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+		struct stripe_head *sh2
+			= get_active_stripe(conf, sh->sector, 1, 1, 1);
+		if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+			/* sh cannot be written until sh2 has been read.
+			 * so arrange for sh to be delayed a little
+			 */
+			set_bit(STRIPE_DELAYED, &sh->state);
+			set_bit(STRIPE_HANDLE, &sh->state);
+			if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+					      &sh2->state))
+				atomic_inc(&conf->preread_active_stripes);
+			release_stripe(sh2);
+			goto unlock;
+		}
+		if (sh2)
+			release_stripe(sh2);
+
 		/* Need to write out all blocks after computing P&Q */
 		sh->disks = conf->raid_disks;
-		sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
-					     conf->raid_disks);
+		stripe_set_idx(sh->sector, conf, 0, sh);
 		compute_parity6(sh, RECONSTRUCT_WRITE);
 		for (i = conf->raid_disks ; i-- ;  ) {
 			set_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -3064,7 +3288,7 @@ static void unplug_slaves(mddev_t *mddev
 	int i;
 
 	rcu_read_lock();
-	for (i=0; i<mddev->raid_disks; i++) {
+	for (i = 0; i < conf->raid_disks; i++) {
 		mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
 		if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
 			struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
@@ -3134,6 +3358,8 @@ static int raid5_mergeable_bvec(struct r
 	if ((bvm->bi_rw & 1) == WRITE)
 		return biovec->bv_len; /* always allow writes to be mergeable */
 
+	if (mddev->new_chunk < mddev->chunk_size)
+		chunk_sectors = mddev->new_chunk >> 9;
 	max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
 	if (max < 0) max = 0;
 	if (max <= biovec->bv_len && bio_sectors == 0)
@@ -3149,6 +3375,8 @@ static int in_chunk_boundary(mddev_t *md
 	unsigned int chunk_sectors = mddev->chunk_size >> 9;
 	unsigned int bio_sectors = bio->bi_size >> 9;
 
+	if (mddev->new_chunk < mddev->chunk_size)
+		chunk_sectors = mddev->new_chunk >> 9;
 	return  chunk_sectors >=
 		((sector & (chunk_sectors - 1)) + bio_sectors);
 }
@@ -3255,9 +3483,7 @@ static int chunk_aligned_read(struct req
 {
 	mddev_t *mddev = q->queuedata;
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	const unsigned int raid_disks = conf->raid_disks;
-	const unsigned int data_disks = raid_disks - conf->max_degraded;
-	unsigned int dd_idx, pd_idx;
+	unsigned int dd_idx;
 	struct bio* align_bi;
 	mdk_rdev_t *rdev;
 
@@ -3266,7 +3492,7 @@ static int chunk_aligned_read(struct req
 		return 0;
 	}
 	/*
- 	 * use bio_clone to make a copy of the bio
+	 * use bio_clone to make a copy of the bio
 	 */
 	align_bi = bio_clone(raid_bio, GFP_NOIO);
 	if (!align_bi)
@@ -3280,12 +3506,9 @@ static int chunk_aligned_read(struct req
 	/*
 	 *	compute position
 	 */
-	align_bi->bi_sector =  raid5_compute_sector(raid_bio->bi_sector,
-					raid_disks,
-					data_disks,
-					&dd_idx,
-					&pd_idx,
-					conf);
+	align_bi->bi_sector =  raid5_compute_sector(conf, raid_bio->bi_sector,
+						    0,
+						    &dd_idx, NULL);
 
 	rcu_read_lock();
 	rdev = rcu_dereference(conf->disks[dd_idx].rdev);
@@ -3377,7 +3600,7 @@ static int make_request(struct request_q
 {
 	mddev_t *mddev = q->queuedata;
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	unsigned int dd_idx, pd_idx;
+	int dd_idx;
 	sector_t new_sector;
 	sector_t logical_sector, last_sector;
 	struct stripe_head *sh;
@@ -3400,7 +3623,7 @@ static int make_request(struct request_q
 	if (rw == READ &&
 	     mddev->reshape_position == MaxSector &&
 	     chunk_aligned_read(q,bi))
-            	return 0;
+		return 0;
 
 	logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
 	last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3410,26 +3633,31 @@ static int make_request(struct request_q
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
 		DEFINE_WAIT(w);
 		int disks, data_disks;
+		int previous;
 
 	retry:
+		previous = 0;
+		disks = conf->raid_disks;
 		prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
-		if (likely(conf->expand_progress == MaxSector))
-			disks = conf->raid_disks;
-		else {
-			/* spinlock is needed as expand_progress may be
+		if (unlikely(conf->reshape_progress != MaxSector)) {
+			/* spinlock is needed as reshape_progress may be
 			 * 64bit on a 32bit platform, and so it might be
 			 * possible to see a half-updated value
-			 * Ofcourse expand_progress could change after
+			 * Ofcourse reshape_progress could change after
 			 * the lock is dropped, so once we get a reference
 			 * to the stripe that we think it is, we will have
 			 * to check again.
 			 */
 			spin_lock_irq(&conf->device_lock);
-			disks = conf->raid_disks;
-			if (logical_sector >= conf->expand_progress)
+			if (mddev->delta_disks < 0
+			    ? logical_sector < conf->reshape_progress
+			    : logical_sector >= conf->reshape_progress) {
 				disks = conf->previous_raid_disks;
-			else {
-				if (logical_sector >= conf->expand_lo) {
+				previous = 1;
+			} else {
+				if (mddev->delta_disks < 0
+				    ? logical_sector < conf->reshape_safe
+				    : logical_sector >= conf->reshape_safe) {
 					spin_unlock_irq(&conf->device_lock);
 					schedule();
 					goto retry;
@@ -3439,15 +3667,17 @@ static int make_request(struct request_q
 		}
 		data_disks = disks - conf->max_degraded;
 
- 		new_sector = raid5_compute_sector(logical_sector, disks, data_disks,
-						  &dd_idx, &pd_idx, conf);
+		new_sector = raid5_compute_sector(conf, logical_sector,
+						  previous,
+						  &dd_idx, NULL);
 		pr_debug("raid5: make_request, sector %llu logical %llu\n",
 			(unsigned long long)new_sector, 
 			(unsigned long long)logical_sector);
 
-		sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+		sh = get_active_stripe(conf, new_sector, previous,
+				       (bi->bi_rw&RWA_MASK), 0);
 		if (sh) {
-			if (unlikely(conf->expand_progress != MaxSector)) {
+			if (unlikely(previous)) {
 				/* expansion might have moved on while waiting for a
 				 * stripe, so we must do the range check again.
 				 * Expansion could still move past after this
@@ -3458,8 +3688,9 @@ static int make_request(struct request_q
 				 */
 				int must_retry = 0;
 				spin_lock_irq(&conf->device_lock);
-				if (logical_sector <  conf->expand_progress &&
-				    disks == conf->previous_raid_disks)
+				if (mddev->delta_disks < 0
+				    ? logical_sector >= conf->reshape_progress
+				    : logical_sector < conf->reshape_progress)
 					/* mismatch, need to try again */
 					must_retry = 1;
 				spin_unlock_irq(&conf->device_lock);
@@ -3514,6 +3745,8 @@ static int make_request(struct request_q
 	return 0;
 }
 
+static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
+
 static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
 {
 	/* reshaping is quite different to recovery/resync so it is
@@ -3527,61 +3760,120 @@ static sector_t reshape_request(mddev_t
 	 */
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
-	int pd_idx;
 	sector_t first_sector, last_sector;
 	int raid_disks = conf->previous_raid_disks;
 	int data_disks = raid_disks - conf->max_degraded;
 	int new_data_disks = conf->raid_disks - conf->max_degraded;
 	int i;
 	int dd_idx;
-	sector_t writepos, safepos, gap;
+	sector_t writepos, readpos, safepos;
+	sector_t stripe_addr;
+	int reshape_sectors;
+	struct list_head stripes;
 
-	if (sector_nr == 0 &&
-	    conf->expand_progress != 0) {
-		/* restarting in the middle, skip the initial sectors */
-		sector_nr = conf->expand_progress;
+	if (sector_nr == 0) {
+		/* If restarting in the middle, skip the initial sectors */
+		if (mddev->delta_disks < 0 &&
+		    conf->reshape_progress < raid5_size(mddev, 0, 0)) {
+			sector_nr = raid5_size(mddev, 0, 0)
+				- conf->reshape_progress;
+		} else if (mddev->delta_disks > 0 &&
+			   conf->reshape_progress > 0)
+			sector_nr = conf->reshape_progress;
 		sector_div(sector_nr, new_data_disks);
-		*skipped = 1;
-		return sector_nr;
+		if (sector_nr) {
+			*skipped = 1;
+			return sector_nr;
+		}
 	}
 
+	/* We need to process a full chunk at a time.
+	 * If old and new chunk sizes differ, we need to process the
+	 * largest of these
+	 */
+	if (mddev->new_chunk > mddev->chunk_size)
+		reshape_sectors = mddev->new_chunk / 512;
+	else
+		reshape_sectors = mddev->chunk_size / 512;
+
 	/* we update the metadata when there is more than 3Meg
 	 * in the block range (that is rather arbitrary, should
 	 * probably be time based) or when the data about to be
 	 * copied would over-write the source of the data at
 	 * the front of the range.
-	 * i.e. one new_stripe forward from expand_progress new_maps
-	 * to after where expand_lo old_maps to
+	 * i.e. one new_stripe along from reshape_progress new_maps
+	 * to after where reshape_safe old_maps to
 	 */
-	writepos = conf->expand_progress +
-		conf->chunk_size/512*(new_data_disks);
+	writepos = conf->reshape_progress;
 	sector_div(writepos, new_data_disks);
-	safepos = conf->expand_lo;
+	readpos = conf->reshape_progress;
+	sector_div(readpos, data_disks);
+	safepos = conf->reshape_safe;
 	sector_div(safepos, data_disks);
-	gap = conf->expand_progress - conf->expand_lo;
+	if (mddev->delta_disks < 0) {
+		writepos -= min_t(sector_t, reshape_sectors, writepos);
+		readpos += reshape_sectors;
+		safepos += reshape_sectors;
+	} else {
+		writepos += reshape_sectors;
+		readpos -= min_t(sector_t, reshape_sectors, readpos);
+		safepos -= min_t(sector_t, reshape_sectors, safepos);
+	}
 
-	if (writepos >= safepos ||
-	    gap > (new_data_disks)*3000*2 /*3Meg*/) {
+	/* 'writepos' is the most advanced device address we might write.
+	 * 'readpos' is the least advanced device address we might read.
+	 * 'safepos' is the least address recorded in the metadata as having
+	 *     been reshaped.
+	 * If 'readpos' is behind 'writepos', then there is no way that we can
+	 * ensure safety in the face of a crash - that must be done by userspace
+	 * making a backup of the data.  So in that case there is no particular
+	 * rush to update metadata.
+	 * Otherwise if 'safepos' is behind 'writepos', then we really need to
+	 * update the metadata to advance 'safepos' to match 'readpos' so that
+	 * we can be safe in the event of a crash.
+	 * So we insist on updating metadata if safepos is behind writepos and
+	 * readpos is beyond writepos.
+	 * In any case, update the metadata every 10 seconds.
+	 * Maybe that number should be configurable, but I'm not sure it is
+	 * worth it.... maybe it could be a multiple of safemode_delay???
+	 */
+	if ((mddev->delta_disks < 0
+	     ? (safepos > writepos && readpos < writepos)
+	     : (safepos < writepos && readpos > writepos)) ||
+	    time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
 		/* Cannot proceed until we've updated the superblock... */
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes)==0);
-		mddev->reshape_position = conf->expand_progress;
+		mddev->reshape_position = conf->reshape_progress;
+		mddev->curr_resync_completed = mddev->curr_resync;
+		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
 		wait_event(mddev->sb_wait, mddev->flags == 0 ||
 			   kthread_should_stop());
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_lo = mddev->reshape_position;
+		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	}
 
-	for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
+	if (mddev->delta_disks < 0) {
+		BUG_ON(conf->reshape_progress == 0);
+		stripe_addr = writepos;
+		BUG_ON((mddev->dev_sectors &
+			~((sector_t)reshape_sectors - 1))
+		       - reshape_sectors - stripe_addr
+		       != sector_nr);
+	} else {
+		BUG_ON(writepos != sector_nr + reshape_sectors);
+		stripe_addr = sector_nr;
+	}
+	INIT_LIST_HEAD(&stripes);
+	for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
 		int j;
 		int skipped = 0;
-		pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
-		sh = get_active_stripe(conf, sector_nr+i,
-				       conf->raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1);
 		set_bit(STRIPE_EXPANDING, &sh->state);
 		atomic_inc(&conf->reshape_stripes);
 		/* If any of this stripe is beyond the end of the old
@@ -3592,10 +3884,10 @@ static sector_t reshape_request(mddev_t
 			if (j == sh->pd_idx)
 				continue;
 			if (conf->level == 6 &&
-			    j == raid6_next_disk(sh->pd_idx, sh->disks))
+			    j == sh->qd_idx)
 				continue;
-			s = compute_blocknr(sh, j);
-			if (s < mddev->array_sectors) {
+			s = compute_blocknr(sh, j, 0);
+			if (s < raid5_size(mddev, 0, 0)) {
 				skipped = 1;
 				continue;
 			}
@@ -3607,10 +3899,13 @@ static sector_t reshape_request(mddev_t
 			set_bit(STRIPE_EXPAND_READY, &sh->state);
 			set_bit(STRIPE_HANDLE, &sh->state);
 		}
-		release_stripe(sh);
+		list_add(&sh->lru, &stripes);
 	}
 	spin_lock_irq(&conf->device_lock);
-	conf->expand_progress = (sector_nr + i) * new_data_disks;
+	if (mddev->delta_disks < 0)
+		conf->reshape_progress -= reshape_sectors * new_data_disks;
+	else
+		conf->reshape_progress += reshape_sectors * new_data_disks;
 	spin_unlock_irq(&conf->device_lock);
 	/* Ok, those stripe are ready. We can start scheduling
 	 * reads on the source stripes.
@@ -3618,46 +3913,53 @@ static sector_t reshape_request(mddev_t
 	 * block on the destination stripes.
 	 */
 	first_sector =
-		raid5_compute_sector(sector_nr*(new_data_disks),
-				     raid_disks, data_disks,
-				     &dd_idx, &pd_idx, conf);
+		raid5_compute_sector(conf, stripe_addr*(new_data_disks),
+				     1, &dd_idx, NULL);
 	last_sector =
-		raid5_compute_sector((sector_nr+conf->chunk_size/512)
-				     *(new_data_disks) -1,
-				     raid_disks, data_disks,
-				     &dd_idx, &pd_idx, conf);
-	if (last_sector >= (mddev->size<<1))
-		last_sector = (mddev->size<<1)-1;
+		raid5_compute_sector(conf, ((stripe_addr+reshape_sectors)
+					    *(new_data_disks) - 1),
+				     1, &dd_idx, NULL);
+	if (last_sector >= mddev->dev_sectors)
+		last_sector = mddev->dev_sectors - 1;
 	while (first_sector <= last_sector) {
-		pd_idx = stripe_to_pdidx(first_sector, conf,
-					 conf->previous_raid_disks);
-		sh = get_active_stripe(conf, first_sector,
-				       conf->previous_raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, first_sector, 1, 0, 1);
 		set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
 		set_bit(STRIPE_HANDLE, &sh->state);
 		release_stripe(sh);
 		first_sector += STRIPE_SECTORS;
 	}
+	/* Now that the sources are clearly marked, we can release
+	 * the destination stripes
+	 */
+	while (!list_empty(&stripes)) {
+		sh = list_entry(stripes.next, struct stripe_head, lru);
+		list_del_init(&sh->lru);
+		release_stripe(sh);
+	}
 	/* If this takes us to the resync_max point where we have to pause,
 	 * then we need to write out the superblock.
 	 */
-	sector_nr += conf->chunk_size>>9;
-	if (sector_nr >= mddev->resync_max) {
+	sector_nr += reshape_sectors;
+	if ((sector_nr - mddev->curr_resync_completed) * 2
+	    >= mddev->resync_max - mddev->curr_resync_completed) {
 		/* Cannot proceed until we've updated the superblock... */
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes) == 0);
-		mddev->reshape_position = conf->expand_progress;
+		mddev->reshape_position = conf->reshape_progress;
+		mddev->curr_resync_completed = mddev->curr_resync;
+		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
 		wait_event(mddev->sb_wait,
 			   !test_bit(MD_CHANGE_DEVS, &mddev->flags)
 			   || kthread_should_stop());
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_lo = mddev->reshape_position;
+		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
+		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
 	}
-	return conf->chunk_size>>9;
+	return reshape_sectors;
 }
 
 /* FIXME go_faster isn't used */
@@ -3665,9 +3967,7 @@ static inline sector_t sync_request(mdde
 {
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
-	int pd_idx;
-	int raid_disks = conf->raid_disks;
-	sector_t max_sector = mddev->size << 1;
+	sector_t max_sector = mddev->dev_sectors;
 	int sync_blocks;
 	int still_degraded = 0;
 	int i;
@@ -3675,6 +3975,7 @@ static inline sector_t sync_request(mdde
 	if (sector_nr >= max_sector) {
 		/* just being told to finish up .. nothing much to do */
 		unplug_slaves(mddev);
+
 		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
 			end_reshape(conf);
 			return 0;
@@ -3705,7 +4006,7 @@ static inline sector_t sync_request(mdde
 	 */
 	if (mddev->degraded >= conf->max_degraded &&
 	    test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-		sector_t rv = (mddev->size << 1) - sector_nr;
+		sector_t rv = mddev->dev_sectors - sector_nr;
 		*skipped = 1;
 		return rv;
 	}
@@ -3721,10 +4022,9 @@ static inline sector_t sync_request(mdde
 
 	bitmap_cond_end_sync(mddev->bitmap, sector_nr);
 
-	pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
-	sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+	sh = get_active_stripe(conf, sector_nr, 0, 1, 0);
 	if (sh == NULL) {
-		sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, sector_nr, 0, 0, 0);
 		/* make sure we don't swamp the stripe cache if someone else
 		 * is trying to get access
 		 */
@@ -3734,7 +4034,7 @@ static inline sector_t sync_request(mdde
 	 * We don't need to check the 'failed' flag as when that gets set,
 	 * recovery aborts.
 	 */
-	for (i=0; i<mddev->raid_disks; i++)
+	for (i = 0; i < conf->raid_disks; i++)
 		if (conf->disks[i].rdev == NULL)
 			still_degraded = 1;
 
@@ -3766,19 +4066,15 @@ static int  retry_aligned_read(raid5_con
 	 * it will be only one 'dd_idx' and only need one call to raid5_compute_sector.
 	 */
 	struct stripe_head *sh;
-	int dd_idx, pd_idx;
+	int dd_idx;
 	sector_t sector, logical_sector, last_sector;
 	int scnt = 0;
 	int remaining;
 	int handled = 0;
 
 	logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
-	sector = raid5_compute_sector(	logical_sector,
-					conf->raid_disks,
-					conf->raid_disks - conf->max_degraded,
-					&dd_idx,
-					&pd_idx,
-					conf);
+	sector = raid5_compute_sector(conf, logical_sector,
+				      0, &dd_idx, NULL);
 	last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9);
 
 	for (; logical_sector < last_sector;
@@ -3790,7 +4086,7 @@ static int  retry_aligned_read(raid5_con
 			/* already done this stripe */
 			continue;
 
-		sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+		sh = get_active_stripe(conf, sector, 0, 1, 0);
 
 		if (!sh) {
 			/* failed to get a stripe - must wait */
@@ -3992,89 +4288,69 @@ static struct attribute_group raid5_attr
 	.attrs = raid5_attrs,
 };
 
-static int run(mddev_t *mddev)
+static sector_t
+raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (!sectors)
+		sectors = mddev->dev_sectors;
+	if (!raid_disks) {
+		/* size is defined by the smallest of previous and new size */
+		if (conf->raid_disks < conf->previous_raid_disks)
+			raid_disks = conf->raid_disks;
+		else
+			raid_disks = conf->previous_raid_disks;
+	}
+
+	sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+	sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
+	return sectors * (raid_disks - conf->max_degraded);
+}
+
+static raid5_conf_t *setup_conf(mddev_t *mddev)
 {
 	raid5_conf_t *conf;
 	int raid_disk, memory;
 	mdk_rdev_t *rdev;
 	struct disk_info *disk;
-	int working_disks = 0;
 
-	if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
+	if (mddev->new_level != 5
+	    && mddev->new_level != 4
+	    && mddev->new_level != 6) {
 		printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
-		       mdname(mddev), mddev->level);
-		return -EIO;
+		       mdname(mddev), mddev->new_level);
+		return ERR_PTR(-EIO);
 	}
-
-	if (mddev->chunk_size < PAGE_SIZE) {
-		printk(KERN_ERR "md/raid5: chunk_size must be at least "
-		       "PAGE_SIZE but %d < %ld\n",
-		       mddev->chunk_size, PAGE_SIZE);
-		return -EINVAL;
+	if ((mddev->new_level == 5
+	     && !algorithm_valid_raid5(mddev->new_layout)) ||
+	    (mddev->new_level == 6
+	     && !algorithm_valid_raid6(mddev->new_layout))) {
+		printk(KERN_ERR "raid5: %s: layout %d not supported\n",
+		       mdname(mddev), mddev->new_layout);
+		return ERR_PTR(-EIO);
 	}
-
-	if (mddev->reshape_position != MaxSector) {
-		/* Check that we can continue the reshape.
-		 * Currently only disks can change, it must
-		 * increase, and we must be past the point where
-		 * a stripe over-writes itself
-		 */
-		sector_t here_new, here_old;
-		int old_disks;
-		int max_degraded = (mddev->level == 5 ? 1 : 2);
-
-		if (mddev->new_level != mddev->level ||
-		    mddev->new_layout != mddev->layout ||
-		    mddev->new_chunk != mddev->chunk_size) {
-			printk(KERN_ERR "raid5: %s: unsupported reshape "
-			       "required - aborting.\n",
-			       mdname(mddev));
-			return -EINVAL;
-		}
-		if (mddev->delta_disks <= 0) {
-			printk(KERN_ERR "raid5: %s: unsupported reshape "
-			       "(reduce disks) required - aborting.\n",
-			       mdname(mddev));
-			return -EINVAL;
-		}
-		old_disks = mddev->raid_disks - mddev->delta_disks;
-		/* reshape_position must be on a new-stripe boundary, and one
-		 * further up in new geometry must map after here in old
-		 * geometry.
-		 */
-		here_new = mddev->reshape_position;
-		if (sector_div(here_new, (mddev->chunk_size>>9)*
-			       (mddev->raid_disks - max_degraded))) {
-			printk(KERN_ERR "raid5: reshape_position not "
-			       "on a stripe boundary\n");
-			return -EINVAL;
-		}
-		/* here_new is the stripe we will write to */
-		here_old = mddev->reshape_position;
-		sector_div(here_old, (mddev->chunk_size>>9)*
-			   (old_disks-max_degraded));
-		/* here_old is the first stripe that we might need to read
-		 * from */
-		if (here_new >= here_old) {
-			/* Reading from the same stripe as writing to - bad */
-			printk(KERN_ERR "raid5: reshape_position too early for "
-			       "auto-recovery - aborting.\n");
-			return -EINVAL;
-		}
-		printk(KERN_INFO "raid5: reshape will continue\n");
-		/* OK, we should be able to continue; */
+	if (mddev->new_level == 6 && mddev->raid_disks < 4) {
+		printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
+		       mdname(mddev), mddev->raid_disks);
+		return ERR_PTR(-EINVAL);
 	}
 
+	if (!mddev->new_chunk || mddev->new_chunk % PAGE_SIZE) {
+		printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
+			mddev->new_chunk, mdname(mddev));
+		return ERR_PTR(-EINVAL);
+	}
 
-	mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
-	if ((conf = mddev->private) == NULL)
+	conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
+	if (conf == NULL)
 		goto abort;
-	if (mddev->reshape_position == MaxSector) {
-		conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
-	} else {
-		conf->raid_disks = mddev->raid_disks;
+
+	conf->raid_disks = mddev->raid_disks;
+	if (mddev->reshape_position == MaxSector)
+		conf->previous_raid_disks = mddev->raid_disks;
+	else
 		conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
-	}
 
 	conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
 			      GFP_KERNEL);
@@ -4086,13 +4362,12 @@ static int run(mddev_t *mddev)
 	if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
 		goto abort;
 
-	if (mddev->level == 6) {
+	if (mddev->new_level == 6) {
 		conf->spare_page = alloc_page(GFP_KERNEL);
 		if (!conf->spare_page)
 			goto abort;
 	}
 	spin_lock_init(&conf->device_lock);
-	mddev->queue->queue_lock = &conf->device_lock;
 	init_waitqueue_head(&conf->wait_for_stripe);
 	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
@@ -4121,47 +4396,134 @@ static int run(mddev_t *mddev)
 			printk(KERN_INFO "raid5: device %s operational as raid"
 				" disk %d\n", bdevname(rdev->bdev,b),
 				raid_disk);
-			working_disks++;
 		} else
 			/* Cannot rely on bitmap to complete recovery */
 			conf->fullsync = 1;
 	}
 
-	/*
-	 * 0 for a fully functional array, 1 or 2 for a degraded array.
-	 */
-	mddev->degraded = conf->raid_disks - working_disks;
-	conf->mddev = mddev;
-	conf->chunk_size = mddev->chunk_size;
-	conf->level = mddev->level;
+	conf->chunk_size = mddev->new_chunk;
+	conf->level = mddev->new_level;
 	if (conf->level == 6)
 		conf->max_degraded = 2;
 	else
 		conf->max_degraded = 1;
-	conf->algorithm = mddev->layout;
+	conf->algorithm = mddev->new_layout;
 	conf->max_nr_stripes = NR_STRIPES;
-	conf->expand_progress = mddev->reshape_position;
-
-	/* device size must be a multiple of chunk size */
-	mddev->size &= ~(mddev->chunk_size/1024 -1);
-	mddev->resync_max_sectors = mddev->size << 1;
+	conf->reshape_progress = mddev->reshape_position;
+	if (conf->reshape_progress != MaxSector) {
+		conf->prev_chunk = mddev->chunk_size;
+		conf->prev_algo = mddev->layout;
+	}
 
-	if (conf->level == 6 && conf->raid_disks < 4) {
-		printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
-		       mdname(mddev), conf->raid_disks);
+	memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+		 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+	if (grow_stripes(conf, conf->max_nr_stripes)) {
+		printk(KERN_ERR
+			"raid5: couldn't allocate %dkB for buffers\n", memory);
 		goto abort;
-	}
-	if (!conf->chunk_size || conf->chunk_size % 4) {
-		printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
-			conf->chunk_size, mdname(mddev));
+	} else
+		printk(KERN_INFO "raid5: allocated %dkB for %s\n",
+			memory, mdname(mddev));
+
+	conf->thread = md_register_thread(raid5d, mddev, "%s_raid5");
+	if (!conf->thread) {
+		printk(KERN_ERR
+		       "raid5: couldn't allocate thread for %s\n",
+		       mdname(mddev));
 		goto abort;
 	}
-	if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
-		printk(KERN_ERR 
-			"raid5: unsupported parity algorithm %d for %s\n",
-			conf->algorithm, mdname(mddev));
-		goto abort;
+
+	return conf;
+
+ abort:
+	if (conf) {
+		shrink_stripes(conf);
+		safe_put_page(conf->spare_page);
+		kfree(conf->disks);
+		kfree(conf->stripe_hashtbl);
+		kfree(conf);
+		return ERR_PTR(-EIO);
+	} else
+		return ERR_PTR(-ENOMEM);
+}
+
+static int run(mddev_t *mddev)
+{
+	raid5_conf_t *conf;
+	int working_disks = 0;
+	mdk_rdev_t *rdev;
+
+	if (mddev->reshape_position != MaxSector) {
+		/* Check that we can continue the reshape.
+		 * Currently only disks can change, it must
+		 * increase, and we must be past the point where
+		 * a stripe over-writes itself
+		 */
+		sector_t here_new, here_old;
+		int old_disks;
+		int max_degraded = (mddev->level == 6 ? 2 : 1);
+
+		if (mddev->new_level != mddev->level) {
+			printk(KERN_ERR "raid5: %s: unsupported reshape "
+			       "required - aborting.\n",
+			       mdname(mddev));
+			return -EINVAL;
+		}
+		old_disks = mddev->raid_disks - mddev->delta_disks;
+		/* reshape_position must be on a new-stripe boundary, and one
+		 * further up in new geometry must map after here in old
+		 * geometry.
+		 */
+		here_new = mddev->reshape_position;
+		if (sector_div(here_new, (mddev->new_chunk>>9)*
+			       (mddev->raid_disks - max_degraded))) {
+			printk(KERN_ERR "raid5: reshape_position not "
+			       "on a stripe boundary\n");
+			return -EINVAL;
+		}
+		/* here_new is the stripe we will write to */
+		here_old = mddev->reshape_position;
+		sector_div(here_old, (mddev->chunk_size>>9)*
+			   (old_disks-max_degraded));
+		/* here_old is the first stripe that we might need to read
+		 * from */
+		if (here_new >= here_old) {
+			/* Reading from the same stripe as writing to - bad */
+			printk(KERN_ERR "raid5: reshape_position too early for "
+			       "auto-recovery - aborting.\n");
+			return -EINVAL;
+		}
+		printk(KERN_INFO "raid5: reshape will continue\n");
+		/* OK, we should be able to continue; */
+	} else {
+		BUG_ON(mddev->level != mddev->new_level);
+		BUG_ON(mddev->layout != mddev->new_layout);
+		BUG_ON(mddev->chunk_size != mddev->new_chunk);
+		BUG_ON(mddev->delta_disks != 0);
 	}
+
+	if (mddev->private == NULL)
+		conf = setup_conf(mddev);
+	else
+		conf = mddev->private;
+
+	if (IS_ERR(conf))
+		return PTR_ERR(conf);
+
+	mddev->thread = conf->thread;
+	conf->thread = NULL;
+	mddev->private = conf;
+
+	/*
+	 * 0 for a fully functional array, 1 or 2 for a degraded array.
+	 */
+	list_for_each_entry(rdev, &mddev->disks, same_set)
+		if (rdev->raid_disk >= 0 &&
+		    test_bit(In_sync, &rdev->flags))
+			working_disks++;
+
+	mddev->degraded = conf->raid_disks - working_disks;
+
 	if (mddev->degraded > conf->max_degraded) {
 		printk(KERN_ERR "raid5: not enough operational devices for %s"
 			" (%d/%d failed)\n",
@@ -4169,6 +4531,10 @@ static int run(mddev_t *mddev)
 		goto abort;
 	}
 
+	/* device size must be a multiple of chunk size */
+	mddev->dev_sectors &= ~(mddev->chunk_size / 512 - 1);
+	mddev->resync_max_sectors = mddev->dev_sectors;
+
 	if (mddev->degraded > 0 &&
 	    mddev->recovery_cp != MaxSector) {
 		if (mddev->ok_start_degraded)
@@ -4184,43 +4550,22 @@ static int run(mddev_t *mddev)
 		}
 	}
 
-	{
-		mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
-		if (!mddev->thread) {
-			printk(KERN_ERR 
-				"raid5: couldn't allocate thread for %s\n",
-				mdname(mddev));
-			goto abort;
-		}
-	}
-	memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
-		 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
-	if (grow_stripes(conf, conf->max_nr_stripes)) {
-		printk(KERN_ERR 
-			"raid5: couldn't allocate %dkB for buffers\n", memory);
-		shrink_stripes(conf);
-		md_unregister_thread(mddev->thread);
-		goto abort;
-	} else
-		printk(KERN_INFO "raid5: allocated %dkB for %s\n",
-			memory, mdname(mddev));
-
 	if (mddev->degraded == 0)
 		printk("raid5: raid level %d set %s active with %d out of %d"
-			" devices, algorithm %d\n", conf->level, mdname(mddev), 
-			mddev->raid_disks-mddev->degraded, mddev->raid_disks,
-			conf->algorithm);
+		       " devices, algorithm %d\n", conf->level, mdname(mddev),
+		       mddev->raid_disks-mddev->degraded, mddev->raid_disks,
+		       mddev->new_layout);
 	else
 		printk(KERN_ALERT "raid5: raid level %d set %s active with %d"
 			" out of %d devices, algorithm %d\n", conf->level,
 			mdname(mddev), mddev->raid_disks - mddev->degraded,
-			mddev->raid_disks, conf->algorithm);
+			mddev->raid_disks, mddev->new_layout);
 
 	print_raid5_conf(conf);
 
-	if (conf->expand_progress != MaxSector) {
+	if (conf->reshape_progress != MaxSector) {
 		printk("...ok start reshape thread\n");
-		conf->expand_lo = conf->expand_progress;
+		conf->reshape_safe = conf->reshape_progress;
 		atomic_set(&conf->reshape_stripes, 0);
 		clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
 		clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -4247,18 +4592,22 @@ static int run(mddev_t *mddev)
 		       "raid5: failed to create sysfs attributes for %s\n",
 		       mdname(mddev));
 
+	mddev->queue->queue_lock = &conf->device_lock;
+
 	mddev->queue->unplug_fn = raid5_unplug_device;
 	mddev->queue->backing_dev_info.congested_data = mddev;
 	mddev->queue->backing_dev_info.congested_fn = raid5_congested;
 
-	mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
-					    conf->max_degraded);
+	md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
 
 	blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
 
 	return 0;
 abort:
+	md_unregister_thread(mddev->thread);
+	mddev->thread = NULL;
 	if (conf) {
+		shrink_stripes(conf);
 		print_raid5_conf(conf);
 		safe_put_page(conf->spare_page);
 		kfree(conf->disks);
@@ -4396,6 +4745,10 @@ static int raid5_remove_disk(mddev_t *md
 	print_raid5_conf(conf);
 	rdev = p->rdev;
 	if (rdev) {
+		if (number >= conf->raid_disks &&
+		    conf->reshape_progress == MaxSector)
+			clear_bit(In_sync, &rdev->flags);
+
 		if (test_bit(In_sync, &rdev->flags) ||
 		    atomic_read(&rdev->nr_pending)) {
 			err = -EBUSY;
@@ -4405,7 +4758,8 @@ static int raid5_remove_disk(mddev_t *md
 		 * isn't possible.
 		 */
 		if (!test_bit(Faulty, &rdev->flags) &&
-		    mddev->degraded <= conf->max_degraded) {
+		    mddev->degraded <= conf->max_degraded &&
+		    number < conf->raid_disks) {
 			err = -EBUSY;
 			goto abort;
 		}
@@ -4472,36 +4826,48 @@ static int raid5_resize(mddev_t *mddev,
 	 * any io in the removed space completes, but it hardly seems
 	 * worth it.
 	 */
-	raid5_conf_t *conf = mddev_to_conf(mddev);
-
 	sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
-	mddev->array_sectors = sectors * (mddev->raid_disks
-					  - conf->max_degraded);
+	md_set_array_sectors(mddev, raid5_size(mddev, sectors,
+					       mddev->raid_disks));
+	if (mddev->array_sectors >
+	    raid5_size(mddev, sectors, mddev->raid_disks))
+		return -EINVAL;
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	mddev->changed = 1;
-	if (sectors/2  > mddev->size && mddev->recovery_cp == MaxSector) {
-		mddev->recovery_cp = mddev->size << 1;
+	if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
-	mddev->size = sectors /2;
+	mddev->dev_sectors = sectors;
 	mddev->resync_max_sectors = sectors;
 	return 0;
 }
 
-#ifdef CONFIG_MD_RAID5_RESHAPE
 static int raid5_check_reshape(mddev_t *mddev)
 {
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	int err;
 
-	if (mddev->delta_disks < 0 ||
-	    mddev->new_level != mddev->level)
-		return -EINVAL; /* Cannot shrink array or change level yet */
-	if (mddev->delta_disks == 0)
-		return 0; /* nothing to do */
+	if (mddev->delta_disks == 0 &&
+	    mddev->new_layout == mddev->layout &&
+	    mddev->new_chunk == mddev->chunk_size)
+		return -EINVAL; /* nothing to do */
 	if (mddev->bitmap)
 		/* Cannot grow a bitmap yet */
 		return -EBUSY;
+	if (mddev->degraded > conf->max_degraded)
+		return -EINVAL;
+	if (mddev->delta_disks < 0) {
+		/* We might be able to shrink, but the devices must
+		 * be made bigger first.
+		 * For raid6, 4 is the minimum size.
+		 * Otherwise 2 is the minimum
+		 */
+		int min = 2;
+		if (mddev->level == 6)
+			min = 4;
+		if (mddev->raid_disks + mddev->delta_disks < min)
+			return -EINVAL;
+	}
 
 	/* Can only proceed if there are plenty of stripe_heads.
 	 * We need a minimum of one full stripe,, and for sensible progress
@@ -4514,18 +4880,12 @@ static int raid5_check_reshape(mddev_t *
 	if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
 	    (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
 		printk(KERN_WARNING "raid5: reshape: not enough stripes.  Needed %lu\n",
-		       (mddev->chunk_size / STRIPE_SIZE)*4);
+		       (max(mddev->chunk_size, mddev->new_chunk)
+			/ STRIPE_SIZE)*4);
 		return -ENOSPC;
 	}
 
-	err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
-	if (err)
-		return err;
-
-	if (mddev->degraded > conf->max_degraded)
-		return -EINVAL;
-	/* looks like we might be able to manage this */
-	return 0;
+	return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
 }
 
 static int raid5_start_reshape(mddev_t *mddev)
@@ -4550,12 +4910,31 @@ static int raid5_start_reshape(mddev_t *
 		 */
 		return -EINVAL;
 
+	/* Refuse to reduce size of the array.  Any reductions in
+	 * array size must be through explicit setting of array_size
+	 * attribute.
+	 */
+	if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks)
+	    < mddev->array_sectors) {
+		printk(KERN_ERR "md: %s: array size must be reduced "
+		       "before number of disks\n", mdname(mddev));
+		return -EINVAL;
+	}
+
 	atomic_set(&conf->reshape_stripes, 0);
 	spin_lock_irq(&conf->device_lock);
 	conf->previous_raid_disks = conf->raid_disks;
 	conf->raid_disks += mddev->delta_disks;
-	conf->expand_progress = 0;
-	conf->expand_lo = 0;
+	conf->prev_chunk = conf->chunk_size;
+	conf->chunk_size = mddev->new_chunk;
+	conf->prev_algo = conf->algorithm;
+	conf->algorithm = mddev->new_layout;
+	if (mddev->delta_disks < 0)
+		conf->reshape_progress = raid5_size(mddev, 0, 0);
+	else
+		conf->reshape_progress = 0;
+	conf->reshape_safe = conf->reshape_progress;
+	conf->generation++;
 	spin_unlock_irq(&conf->device_lock);
 
 	/* Add some new drives, as many as will fit.
@@ -4580,9 +4959,12 @@ static int raid5_start_reshape(mddev_t *
 				break;
 		}
 
-	spin_lock_irqsave(&conf->device_lock, flags);
-	mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
-	spin_unlock_irqrestore(&conf->device_lock, flags);
+	if (mddev->delta_disks > 0) {
+		spin_lock_irqsave(&conf->device_lock, flags);
+		mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+			- added_devices;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+	}
 	mddev->raid_disks = conf->raid_disks;
 	mddev->reshape_position = 0;
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -4597,52 +4979,86 @@ static int raid5_start_reshape(mddev_t *
 		mddev->recovery = 0;
 		spin_lock_irq(&conf->device_lock);
 		mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
-		conf->expand_progress = MaxSector;
+		conf->reshape_progress = MaxSector;
 		spin_unlock_irq(&conf->device_lock);
 		return -EAGAIN;
 	}
+	conf->reshape_checkpoint = jiffies;
 	md_wakeup_thread(mddev->sync_thread);
 	md_new_event(mddev);
 	return 0;
 }
-#endif
 
+/* This is called from the reshape thread and should make any
+ * changes needed in 'conf'
+ */
 static void end_reshape(raid5_conf_t *conf)
 {
-	struct block_device *bdev;
 
 	if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-		conf->mddev->array_sectors = 2 * conf->mddev->size *
-			(conf->raid_disks - conf->max_degraded);
-		set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
-		conf->mddev->changed = 1;
 
-		bdev = bdget_disk(conf->mddev->gendisk, 0);
-		if (bdev) {
-			mutex_lock(&bdev->bd_inode->i_mutex);
-			i_size_write(bdev->bd_inode,
-				     (loff_t)conf->mddev->array_sectors << 9);
-			mutex_unlock(&bdev->bd_inode->i_mutex);
-			bdput(bdev);
-		}
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_progress = MaxSector;
+		conf->previous_raid_disks = conf->raid_disks;
+		conf->reshape_progress = MaxSector;
 		spin_unlock_irq(&conf->device_lock);
-		conf->mddev->reshape_position = MaxSector;
+		wake_up(&conf->wait_for_overlap);
 
 		/* read-ahead size must cover two whole stripes, which is
 		 * 2 * (datadisks) * chunksize where 'n' is the number of raid devices
 		 */
 		{
-			int data_disks = conf->previous_raid_disks - conf->max_degraded;
-			int stripe = data_disks *
-				(conf->mddev->chunk_size / PAGE_SIZE);
+			int data_disks = conf->raid_disks - conf->max_degraded;
+			int stripe = data_disks * (conf->chunk_size
+						   / PAGE_SIZE);
 			if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
 				conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
 		}
 	}
 }
 
+/* This is called from the raid5d thread with mddev_lock held.
+ * It makes config changes to the device.
+ */
+static void raid5_finish_reshape(mddev_t *mddev)
+{
+	struct block_device *bdev;
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+
+		if (mddev->delta_disks > 0) {
+			md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
+			set_capacity(mddev->gendisk, mddev->array_sectors);
+			mddev->changed = 1;
+
+			bdev = bdget_disk(mddev->gendisk, 0);
+			if (bdev) {
+				mutex_lock(&bdev->bd_inode->i_mutex);
+				i_size_write(bdev->bd_inode,
+					     (loff_t)mddev->array_sectors << 9);
+				mutex_unlock(&bdev->bd_inode->i_mutex);
+				bdput(bdev);
+			}
+		} else {
+			int d;
+			mddev->degraded = conf->raid_disks;
+			for (d = 0; d < conf->raid_disks ; d++)
+				if (conf->disks[d].rdev &&
+				    test_bit(In_sync,
+					     &conf->disks[d].rdev->flags))
+					mddev->degraded--;
+			for (d = conf->raid_disks ;
+			     d < conf->raid_disks - mddev->delta_disks;
+			     d++)
+				raid5_remove_disk(mddev, d);
+		}
+		mddev->layout = conf->algorithm;
+		mddev->chunk_size = conf->chunk_size;
+		mddev->reshape_position = MaxSector;
+		mddev->delta_disks = 0;
+	}
+}
+
 static void raid5_quiesce(mddev_t *mddev, int state)
 {
 	raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -4672,6 +5088,212 @@ static void raid5_quiesce(mddev_t *mddev
 	}
 }
 
+
+static void *raid5_takeover_raid1(mddev_t *mddev)
+{
+	int chunksect;
+
+	if (mddev->raid_disks != 2 ||
+	    mddev->degraded > 1)
+		return ERR_PTR(-EINVAL);
+
+	/* Should check if there are write-behind devices? */
+
+	chunksect = 64*2; /* 64K by default */
+
+	/* The array must be an exact multiple of chunksize */
+	while (chunksect && (mddev->array_sectors & (chunksect-1)))
+		chunksect >>= 1;
+
+	if ((chunksect<<9) < STRIPE_SIZE)
+		/* array size does not allow a suitable chunk size */
+		return ERR_PTR(-EINVAL);
+
+	mddev->new_level = 5;
+	mddev->new_layout = ALGORITHM_LEFT_SYMMETRIC;
+	mddev->new_chunk = chunksect << 9;
+
+	return setup_conf(mddev);
+}
+
+static void *raid5_takeover_raid6(mddev_t *mddev)
+{
+	int new_layout;
+
+	switch (mddev->layout) {
+	case ALGORITHM_LEFT_ASYMMETRIC_6:
+		new_layout = ALGORITHM_LEFT_ASYMMETRIC;
+		break;
+	case ALGORITHM_RIGHT_ASYMMETRIC_6:
+		new_layout = ALGORITHM_RIGHT_ASYMMETRIC;
+		break;
+	case ALGORITHM_LEFT_SYMMETRIC_6:
+		new_layout = ALGORITHM_LEFT_SYMMETRIC;
+		break;
+	case ALGORITHM_RIGHT_SYMMETRIC_6:
+		new_layout = ALGORITHM_RIGHT_SYMMETRIC;
+		break;
+	case ALGORITHM_PARITY_0_6:
+		new_layout = ALGORITHM_PARITY_0;
+		break;
+	case ALGORITHM_PARITY_N:
+		new_layout = ALGORITHM_PARITY_N;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	mddev->new_level = 5;
+	mddev->new_layout = new_layout;
+	mddev->delta_disks = -1;
+	mddev->raid_disks -= 1;
+	return setup_conf(mddev);
+}
+
+
+static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+	/* For a 2-drive array, the layout and chunk size can be changed
+	 * immediately as not restriping is needed.
+	 * For larger arrays we record the new value - after validation
+	 * to be used by a reshape pass.
+	 */
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
+		return -EINVAL;
+	if (new_chunk > 0) {
+		if (new_chunk & (new_chunk-1))
+			/* not a power of 2 */
+			return -EINVAL;
+		if (new_chunk < PAGE_SIZE)
+			return -EINVAL;
+		if (mddev->array_sectors & ((new_chunk>>9)-1))
+			/* not factor of array size */
+			return -EINVAL;
+	}
+
+	/* They look valid */
+
+	if (mddev->raid_disks == 2) {
+
+		if (new_layout >= 0) {
+			conf->algorithm = new_layout;
+			mddev->layout = mddev->new_layout = new_layout;
+		}
+		if (new_chunk > 0) {
+			conf->chunk_size = new_chunk;
+			mddev->chunk_size = mddev->new_chunk = new_chunk;
+		}
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
+		md_wakeup_thread(mddev->thread);
+	} else {
+		if (new_layout >= 0)
+			mddev->new_layout = new_layout;
+		if (new_chunk > 0)
+			mddev->new_chunk = new_chunk;
+	}
+	return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+	if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+		return -EINVAL;
+	if (new_chunk > 0) {
+		if (new_chunk & (new_chunk-1))
+			/* not a power of 2 */
+			return -EINVAL;
+		if (new_chunk < PAGE_SIZE)
+			return -EINVAL;
+		if (mddev->array_sectors & ((new_chunk>>9)-1))
+			/* not factor of array size */
+			return -EINVAL;
+	}
+
+	/* They look valid */
+
+	if (new_layout >= 0)
+		mddev->new_layout = new_layout;
+	if (new_chunk > 0)
+		mddev->new_chunk = new_chunk;
+
+	return 0;
+}
+
+static void *raid5_takeover(mddev_t *mddev)
+{
+	/* raid5 can take over:
+	 *  raid0 - if all devices are the same - make it a raid4 layout
+	 *  raid1 - if there are two drives.  We need to know the chunk size
+	 *  raid4 - trivial - just use a raid4 layout.
+	 *  raid6 - Providing it is a *_6 layout
+	 *
+	 * For now, just do raid1
+	 */
+
+	if (mddev->level == 1)
+		return raid5_takeover_raid1(mddev);
+	if (mddev->level == 4) {
+		mddev->new_layout = ALGORITHM_PARITY_N;
+		mddev->new_level = 5;
+		return setup_conf(mddev);
+	}
+	if (mddev->level == 6)
+		return raid5_takeover_raid6(mddev);
+
+	return ERR_PTR(-EINVAL);
+}
+
+
+static struct mdk_personality raid5_personality;
+
+static void *raid6_takeover(mddev_t *mddev)
+{
+	/* Currently can only take over a raid5.  We map the
+	 * personality to an equivalent raid6 personality
+	 * with the Q block at the end.
+	 */
+	int new_layout;
+
+	if (mddev->pers != &raid5_personality)
+		return ERR_PTR(-EINVAL);
+	if (mddev->degraded > 1)
+		return ERR_PTR(-EINVAL);
+	if (mddev->raid_disks > 253)
+		return ERR_PTR(-EINVAL);
+	if (mddev->raid_disks < 3)
+		return ERR_PTR(-EINVAL);
+
+	switch (mddev->layout) {
+	case ALGORITHM_LEFT_ASYMMETRIC:
+		new_layout = ALGORITHM_LEFT_ASYMMETRIC_6;
+		break;
+	case ALGORITHM_RIGHT_ASYMMETRIC:
+		new_layout = ALGORITHM_RIGHT_ASYMMETRIC_6;
+		break;
+	case ALGORITHM_LEFT_SYMMETRIC:
+		new_layout = ALGORITHM_LEFT_SYMMETRIC_6;
+		break;
+	case ALGORITHM_RIGHT_SYMMETRIC:
+		new_layout = ALGORITHM_RIGHT_SYMMETRIC_6;
+		break;
+	case ALGORITHM_PARITY_0:
+		new_layout = ALGORITHM_PARITY_0_6;
+		break;
+	case ALGORITHM_PARITY_N:
+		new_layout = ALGORITHM_PARITY_N;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	mddev->new_level = 6;
+	mddev->new_layout = new_layout;
+	mddev->delta_disks = 1;
+	mddev->raid_disks += 1;
+	return setup_conf(mddev);
+}
+
+
 static struct mdk_personality raid6_personality =
 {
 	.name		= "raid6",
@@ -4687,11 +5309,13 @@ static struct mdk_personality raid6_pers
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
+	.takeover	= raid6_takeover,
+	.reconfig	= raid6_reconfig,
 };
 static struct mdk_personality raid5_personality =
 {
@@ -4708,11 +5332,13 @@ static struct mdk_personality raid5_pers
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
+	.takeover	= raid5_takeover,
+	.reconfig	= raid5_reconfig,
 };
 
 static struct mdk_personality raid4_personality =
@@ -4730,20 +5356,15 @@ static struct mdk_personality raid4_pers
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
 };
 
 static int __init raid5_init(void)
 {
-	int e;
-
-	e = raid6_select_algo();
-	if ( e )
-		return e;
 	register_md_personality(&raid6_personality);
 	register_md_personality(&raid5_personality);
 	register_md_personality(&raid4_personality);
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid5.h linux-libre-2.6.30-gnu1/drivers/md/raid5.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid5.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/md/raid5.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,474 @@
+#ifndef _RAID5_H
+#define _RAID5_H
+
+#include <linux/raid/xor.h>
+
+/*
+ *
+ * Each stripe contains one buffer per disc.  Each buffer can be in
+ * one of a number of states stored in "flags".  Changes between
+ * these states happen *almost* exclusively under a per-stripe
+ * spinlock.  Some very specific changes can happen in bi_end_io, and
+ * these are not protected by the spin lock.
+ *
+ * The flag bits that are used to represent these states are:
+ *   R5_UPTODATE and R5_LOCKED
+ *
+ * State Empty == !UPTODATE, !LOCK
+ *        We have no data, and there is no active request
+ * State Want == !UPTODATE, LOCK
+ *        A read request is being submitted for this block
+ * State Dirty == UPTODATE, LOCK
+ *        Some new data is in this buffer, and it is being written out
+ * State Clean == UPTODATE, !LOCK
+ *        We have valid data which is the same as on disc
+ *
+ * The possible state transitions are:
+ *
+ *  Empty -> Want   - on read or write to get old data for  parity calc
+ *  Empty -> Dirty  - on compute_parity to satisfy write/sync request.(RECONSTRUCT_WRITE)
+ *  Empty -> Clean  - on compute_block when computing a block for failed drive
+ *  Want  -> Empty  - on failed read
+ *  Want  -> Clean  - on successful completion of read request
+ *  Dirty -> Clean  - on successful completion of write request
+ *  Dirty -> Clean  - on failed write
+ *  Clean -> Dirty  - on compute_parity to satisfy write/sync (RECONSTRUCT or RMW)
+ *
+ * The Want->Empty, Want->Clean, Dirty->Clean, transitions
+ * all happen in b_end_io at interrupt time.
+ * Each sets the Uptodate bit before releasing the Lock bit.
+ * This leaves one multi-stage transition:
+ *    Want->Dirty->Clean
+ * This is safe because thinking that a Clean buffer is actually dirty
+ * will at worst delay some action, and the stripe will be scheduled
+ * for attention after the transition is complete.
+ *
+ * There is one possibility that is not covered by these states.  That
+ * is if one drive has failed and there is a spare being rebuilt.  We
+ * can't distinguish between a clean block that has been generated
+ * from parity calculations, and a clean block that has been
+ * successfully written to the spare ( or to parity when resyncing).
+ * To distingush these states we have a stripe bit STRIPE_INSYNC that
+ * is set whenever a write is scheduled to the spare, or to the parity
+ * disc if there is no spare.  A sync request clears this bit, and
+ * when we find it set with no buffers locked, we know the sync is
+ * complete.
+ *
+ * Buffers for the md device that arrive via make_request are attached
+ * to the appropriate stripe in one of two lists linked on b_reqnext.
+ * One list (bh_read) for read requests, one (bh_write) for write.
+ * There should never be more than one buffer on the two lists
+ * together, but we are not guaranteed of that so we allow for more.
+ *
+ * If a buffer is on the read list when the associated cache buffer is
+ * Uptodate, the data is copied into the read buffer and it's b_end_io
+ * routine is called.  This may happen in the end_request routine only
+ * if the buffer has just successfully been read.  end_request should
+ * remove the buffers from the list and then set the Uptodate bit on
+ * the buffer.  Other threads may do this only if they first check
+ * that the Uptodate bit is set.  Once they have checked that they may
+ * take buffers off the read queue.
+ *
+ * When a buffer on the write list is committed for write it is copied
+ * into the cache buffer, which is then marked dirty, and moved onto a
+ * third list, the written list (bh_written).  Once both the parity
+ * block and the cached buffer are successfully written, any buffer on
+ * a written list can be returned with b_end_io.
+ *
+ * The write list and read list both act as fifos.  The read list is
+ * protected by the device_lock.  The write and written lists are
+ * protected by the stripe lock.  The device_lock, which can be
+ * claimed while the stipe lock is held, is only for list
+ * manipulations and will only be held for a very short time.  It can
+ * be claimed from interrupts.
+ *
+ *
+ * Stripes in the stripe cache can be on one of two lists (or on
+ * neither).  The "inactive_list" contains stripes which are not
+ * currently being used for any request.  They can freely be reused
+ * for another stripe.  The "handle_list" contains stripes that need
+ * to be handled in some way.  Both of these are fifo queues.  Each
+ * stripe is also (potentially) linked to a hash bucket in the hash
+ * table so that it can be found by sector number.  Stripes that are
+ * not hashed must be on the inactive_list, and will normally be at
+ * the front.  All stripes start life this way.
+ *
+ * The inactive_list, handle_list and hash bucket lists are all protected by the
+ * device_lock.
+ *  - stripes on the inactive_list never have their stripe_lock held.
+ *  - stripes have a reference counter. If count==0, they are on a list.
+ *  - If a stripe might need handling, STRIPE_HANDLE is set.
+ *  - When refcount reaches zero, then if STRIPE_HANDLE it is put on
+ *    handle_list else inactive_list
+ *
+ * This, combined with the fact that STRIPE_HANDLE is only ever
+ * cleared while a stripe has a non-zero count means that if the
+ * refcount is 0 and STRIPE_HANDLE is set, then it is on the
+ * handle_list and if recount is 0 and STRIPE_HANDLE is not set, then
+ * the stripe is on inactive_list.
+ *
+ * The possible transitions are:
+ *  activate an unhashed/inactive stripe (get_active_stripe())
+ *     lockdev check-hash unlink-stripe cnt++ clean-stripe hash-stripe unlockdev
+ *  activate a hashed, possibly active stripe (get_active_stripe())
+ *     lockdev check-hash if(!cnt++)unlink-stripe unlockdev
+ *  attach a request to an active stripe (add_stripe_bh())
+ *     lockdev attach-buffer unlockdev
+ *  handle a stripe (handle_stripe())
+ *     lockstripe clrSTRIPE_HANDLE ...
+ *		(lockdev check-buffers unlockdev) ..
+ *		change-state ..
+ *		record io/ops needed unlockstripe schedule io/ops
+ *  release an active stripe (release_stripe())
+ *     lockdev if (!--cnt) { if  STRIPE_HANDLE, add to handle_list else add to inactive-list } unlockdev
+ *
+ * The refcount counts each thread that have activated the stripe,
+ * plus raid5d if it is handling it, plus one for each active request
+ * on a cached buffer, and plus one if the stripe is undergoing stripe
+ * operations.
+ *
+ * Stripe operations are performed outside the stripe lock,
+ * the stripe operations are:
+ * -copying data between the stripe cache and user application buffers
+ * -computing blocks to save a disk access, or to recover a missing block
+ * -updating the parity on a write operation (reconstruct write and
+ *  read-modify-write)
+ * -checking parity correctness
+ * -running i/o to disk
+ * These operations are carried out by raid5_run_ops which uses the async_tx
+ * api to (optionally) offload operations to dedicated hardware engines.
+ * When requesting an operation handle_stripe sets the pending bit for the
+ * operation and increments the count.  raid5_run_ops is then run whenever
+ * the count is non-zero.
+ * There are some critical dependencies between the operations that prevent some
+ * from being requested while another is in flight.
+ * 1/ Parity check operations destroy the in cache version of the parity block,
+ *    so we prevent parity dependent operations like writes and compute_blocks
+ *    from starting while a check is in progress.  Some dma engines can perform
+ *    the check without damaging the parity block, in these cases the parity
+ *    block is re-marked up to date (assuming the check was successful) and is
+ *    not re-read from disk.
+ * 2/ When a write operation is requested we immediately lock the affected
+ *    blocks, and mark them as not up to date.  This causes new read requests
+ *    to be held off, as well as parity checks and compute block operations.
+ * 3/ Once a compute block operation has been requested handle_stripe treats
+ *    that block as if it is up to date.  raid5_run_ops guaruntees that any
+ *    operation that is dependent on the compute block result is initiated after
+ *    the compute block completes.
+ */
+
+/*
+ * Operations state - intermediate states that are visible outside of sh->lock
+ * In general _idle indicates nothing is running, _run indicates a data
+ * processing operation is active, and _result means the data processing result
+ * is stable and can be acted upon.  For simple operations like biofill and
+ * compute that only have an _idle and _run state they are indicated with
+ * sh->state flags (STRIPE_BIOFILL_RUN and STRIPE_COMPUTE_RUN)
+ */
+/**
+ * enum check_states - handles syncing / repairing a stripe
+ * @check_state_idle - check operations are quiesced
+ * @check_state_run - check operation is running
+ * @check_state_result - set outside lock when check result is valid
+ * @check_state_compute_run - check failed and we are repairing
+ * @check_state_compute_result - set outside lock when compute result is valid
+ */
+enum check_states {
+	check_state_idle = 0,
+	check_state_run, /* parity check */
+	check_state_check_result,
+	check_state_compute_run, /* parity repair */
+	check_state_compute_result,
+};
+
+/**
+ * enum reconstruct_states - handles writing or expanding a stripe
+ */
+enum reconstruct_states {
+	reconstruct_state_idle = 0,
+	reconstruct_state_prexor_drain_run,	/* prexor-write */
+	reconstruct_state_drain_run,		/* write */
+	reconstruct_state_run,			/* expand */
+	reconstruct_state_prexor_drain_result,
+	reconstruct_state_drain_result,
+	reconstruct_state_result,
+};
+
+struct stripe_head {
+	struct hlist_node	hash;
+	struct list_head	lru;	      /* inactive_list or handle_list */
+	struct raid5_private_data *raid_conf;
+	short			generation;	/* increments with every
+						 * reshape */
+	sector_t		sector;		/* sector of this row */
+	short			pd_idx;		/* parity disk index */
+	short			qd_idx;		/* 'Q' disk index for raid6 */
+	short			ddf_layout;/* use DDF ordering to calculate Q */
+	unsigned long		state;		/* state flags */
+	atomic_t		count;	      /* nr of active thread/requests */
+	spinlock_t		lock;
+	int			bm_seq;	/* sequence number for bitmap flushes */
+	int			disks;		/* disks in stripe */
+	enum check_states	check_state;
+	enum reconstruct_states reconstruct_state;
+	/* stripe_operations
+	 * @target - STRIPE_OP_COMPUTE_BLK target
+	 */
+	struct stripe_operations {
+		int		   target;
+		u32		   zero_sum_result;
+	} ops;
+	struct r5dev {
+		struct bio	req;
+		struct bio_vec	vec;
+		struct page	*page;
+		struct bio	*toread, *read, *towrite, *written;
+		sector_t	sector;			/* sector of this page */
+		unsigned long	flags;
+	} dev[1]; /* allocated with extra space depending of RAID geometry */
+};
+
+/* stripe_head_state - collects and tracks the dynamic state of a stripe_head
+ *     for handle_stripe.  It is only valid under spin_lock(sh->lock);
+ */
+struct stripe_head_state {
+	int syncing, expanding, expanded;
+	int locked, uptodate, to_read, to_write, failed, written;
+	int to_fill, compute, req_compute, non_overwrite;
+	int failed_num;
+	unsigned long ops_request;
+};
+
+/* r6_state - extra state data only relevant to r6 */
+struct r6_state {
+	int p_failed, q_failed, failed_num[2];
+};
+
+/* Flags */
+#define	R5_UPTODATE	0	/* page contains current data */
+#define	R5_LOCKED	1	/* IO has been submitted on "req" */
+#define	R5_OVERWRITE	2	/* towrite covers whole page */
+/* and some that are internal to handle_stripe */
+#define	R5_Insync	3	/* rdev && rdev->in_sync at start */
+#define	R5_Wantread	4	/* want to schedule a read */
+#define	R5_Wantwrite	5
+#define	R5_Overlap	7	/* There is a pending overlapping request on this block */
+#define	R5_ReadError	8	/* seen a read error here recently */
+#define	R5_ReWrite	9	/* have tried to over-write the readerror */
+
+#define	R5_Expanded	10	/* This block now has post-expand data */
+#define	R5_Wantcompute	11 /* compute_block in progress treat as
+				    * uptodate
+				    */
+#define	R5_Wantfill	12 /* dev->toread contains a bio that needs
+				    * filling
+				    */
+#define R5_Wantdrain	13 /* dev->towrite needs to be drained */
+/*
+ * Write method
+ */
+#define RECONSTRUCT_WRITE	1
+#define READ_MODIFY_WRITE	2
+/* not a write method, but a compute_parity mode */
+#define	CHECK_PARITY		3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY		4
+
+/*
+ * Stripe state
+ */
+#define STRIPE_HANDLE		2
+#define	STRIPE_SYNCING		3
+#define	STRIPE_INSYNC		4
+#define	STRIPE_PREREAD_ACTIVE	5
+#define	STRIPE_DELAYED		6
+#define	STRIPE_DEGRADED		7
+#define	STRIPE_BIT_DELAY	8
+#define	STRIPE_EXPANDING	9
+#define	STRIPE_EXPAND_SOURCE	10
+#define	STRIPE_EXPAND_READY	11
+#define	STRIPE_IO_STARTED	12 /* do not count towards 'bypass_count' */
+#define	STRIPE_FULL_WRITE	13 /* all blocks are set to be overwritten */
+#define	STRIPE_BIOFILL_RUN	14
+#define	STRIPE_COMPUTE_RUN	15
+/*
+ * Operation request flags
+ */
+#define STRIPE_OP_BIOFILL	0
+#define STRIPE_OP_COMPUTE_BLK	1
+#define STRIPE_OP_PREXOR	2
+#define STRIPE_OP_BIODRAIN	3
+#define STRIPE_OP_POSTXOR	4
+#define STRIPE_OP_CHECK	5
+
+/*
+ * Plugging:
+ *
+ * To improve write throughput, we need to delay the handling of some
+ * stripes until there has been a chance that several write requests
+ * for the one stripe have all been collected.
+ * In particular, any write request that would require pre-reading
+ * is put on a "delayed" queue until there are no stripes currently
+ * in a pre-read phase.  Further, if the "delayed" queue is empty when
+ * a stripe is put on it then we "plug" the queue and do not process it
+ * until an unplug call is made. (the unplug_io_fn() is called).
+ *
+ * When preread is initiated on a stripe, we set PREREAD_ACTIVE and add
+ * it to the count of prereading stripes.
+ * When write is initiated, or the stripe refcnt == 0 (just in case) we
+ * clear the PREREAD_ACTIVE flag and decrement the count
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
+ * In stripe_handle, if we find pre-reading is necessary, we do it if
+ * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
+ * HANDLE gets cleared if stripe_handle leave nothing locked.
+ */
+
+
+struct disk_info {
+	mdk_rdev_t	*rdev;
+};
+
+struct raid5_private_data {
+	struct hlist_head	*stripe_hashtbl;
+	mddev_t			*mddev;
+	struct disk_info	*spare;
+	int			chunk_size, level, algorithm;
+	int			max_degraded;
+	int			raid_disks;
+	int			max_nr_stripes;
+
+	/* reshape_progress is the leading edge of a 'reshape'
+	 * It has value MaxSector when no reshape is happening
+	 * If delta_disks < 0, it is the last sector we started work on,
+	 * else is it the next sector to work on.
+	 */
+	sector_t		reshape_progress;
+	/* reshape_safe is the trailing edge of a reshape.  We know that
+	 * before (or after) this address, all reshape has completed.
+	 */
+	sector_t		reshape_safe;
+	int			previous_raid_disks;
+	int			prev_chunk, prev_algo;
+	short			generation; /* increments with every reshape */
+	unsigned long		reshape_checkpoint; /* Time we last updated
+						     * metadata */
+
+	struct list_head	handle_list; /* stripes needing handling */
+	struct list_head	hold_list; /* preread ready stripes */
+	struct list_head	delayed_list; /* stripes that have plugged requests */
+	struct list_head	bitmap_list; /* stripes delaying awaiting bitmap update */
+	struct bio		*retry_read_aligned; /* currently retrying aligned bios   */
+	struct bio		*retry_read_aligned_list; /* aligned bios retry list  */
+	atomic_t		preread_active_stripes; /* stripes with scheduled io */
+	atomic_t		active_aligned_reads;
+	atomic_t		pending_full_writes; /* full write backlog */
+	int			bypass_count; /* bypassed prereads */
+	int			bypass_threshold; /* preread nice */
+	struct list_head	*last_hold; /* detect hold_list promotions */
+
+	atomic_t		reshape_stripes; /* stripes with pending writes for reshape */
+	/* unfortunately we need two cache names as we temporarily have
+	 * two caches.
+	 */
+	int			active_name;
+	char			cache_name[2][20];
+	struct kmem_cache		*slab_cache; /* for allocating stripes */
+
+	int			seq_flush, seq_write;
+	int			quiesce;
+
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	struct page 		*spare_page; /* Used when checking P/Q in raid6 */
+
+	/*
+	 * Free stripes pool
+	 */
+	atomic_t		active_stripes;
+	struct list_head	inactive_list;
+	wait_queue_head_t	wait_for_stripe;
+	wait_queue_head_t	wait_for_overlap;
+	int			inactive_blocked;	/* release of inactive stripes blocked,
+							 * waiting for 25% to be free
+							 */
+	int			pool_size; /* number of disks in stripeheads in pool */
+	spinlock_t		device_lock;
+	struct disk_info	*disks;
+
+	/* 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 raid5_private_data raid5_conf_t;
+
+#define mddev_to_conf(mddev) ((raid5_conf_t *) mddev->private)
+
+/*
+ * Our supported algorithms
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC	0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC	1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC	2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC	3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms.  These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0		4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N		5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART	8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART	9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE	10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6	16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6	17
+#define ALGORITHM_LEFT_SYMMETRIC_6	18
+#define ALGORITHM_RIGHT_SYMMETRIC_6	19
+#define ALGORITHM_PARITY_0_6		20
+#define ALGORITHM_PARITY_N_6		ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+	return (layout >= 0) &&
+		(layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+	return (layout >= 0 && layout <= 5)
+		||
+		(layout == 8 || layout == 10)
+		||
+		(layout >= 16 && layout <= 20);
+}
+
+static inline int algorithm_is_DDF(int layout)
+{
+	return layout >= 8 && layout <= 10;
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6algos.c linux-libre-2.6.30-gnu1/drivers/md/raid6algos.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6algos.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6algos.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -16,13 +16,20 @@
  * Algorithm list and algorithm selection for RAID-6
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
+#else
+#if !RAID6_USE_EMPTY_ZERO_PAGE
+/* In .bss so it's zeroed */
+const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
+EXPORT_SYMBOL(raid6_empty_zero_page);
+#endif
 #endif
 
 struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
 
 /* Various routine sets */
 extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@ const struct raid6_calls * const raid6_a
 #else
 /* Need more time to be stable in userspace */
 #define RAID6_TIME_JIFFIES_LG2	9
+#define time_before(x, y) ((x) < (y))
 #endif
 
 /* Try to pick the best algorithm */
@@ -152,3 +160,12 @@ int __init raid6_select_algo(void)
 
 	return best ? 0 : -EINVAL;
 }
+
+static void raid6_exit(void)
+{
+	do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6altivec.uc linux-libre-2.6.30-gnu1/drivers/md/raid6altivec.uc
--- linux-libre-2.6.29-gnu1/drivers/md/raid6altivec.uc	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6altivec.uc	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -22,7 +22,7 @@
  * bracked this with preempt_disable/enable or in a lock)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #ifdef CONFIG_ALTIVEC
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6.h linux-libre-2.6.30-gnu1/drivers/md/raid6.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid6.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,130 +0,0 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
- *
- *   Copyright 2003 H. Peter Anvin - 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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
- *   (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef LINUX_RAID_RAID6_H
-#define LINUX_RAID_RAID6_H
-
-#ifdef __KERNEL__
-
-/* Set to 1 to use kernel-wide empty_zero_page */
-#define RAID6_USE_EMPTY_ZERO_PAGE 0
-
-#include <linux/raid/md.h>
-#include <linux/raid/raid5.h>
-
-typedef raid5_conf_t raid6_conf_t; /* Same configuration */
-
-/* Additional compute_parity mode -- updates the parity w/o LOCKING */
-#define UPDATE_PARITY	4
-
-/* We need a pre-zeroed page... if we don't want to use the kernel-provided
-   one define it here */
-#if RAID6_USE_EMPTY_ZERO_PAGE
-# define raid6_empty_zero_page empty_zero_page
-#else
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-#endif
-
-#else /* ! __KERNEL__ */
-/* Used for testing in user space */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-/* Not standard, but glibc defines it */
-#define BITS_PER_LONG __WORDSIZE
-
-typedef uint8_t  u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-
-#define __init
-#define __exit
-#define __attribute_const__ __attribute__((const))
-#define noinline __attribute__((noinline))
-
-#define preempt_enable()
-#define preempt_disable()
-#define cpu_has_feature(x) 1
-#define enable_kernel_altivec()
-#define disable_kernel_altivec()
-
-#endif /* __KERNEL__ */
-
-/* Routine choices */
-struct raid6_calls {
-	void (*gen_syndrome)(int, size_t, void **);
-	int  (*valid)(void);	/* Returns 1 if this routine set is usable */
-	const char *name;	/* Name of this routine set */
-	int prefer;		/* Has special performance attribute */
-};
-
-/* Selected algorithm */
-extern struct raid6_calls raid6_call;
-
-/* Algorithm list */
-extern const struct raid6_calls * const raid6_algos[];
-int raid6_select_algo(void);
-
-/* Return values from chk_syndrome */
-#define RAID6_OK	0
-#define RAID6_P_BAD	1
-#define RAID6_Q_BAD	2
-#define RAID6_PQ_BAD	3
-
-/* Galois field tables */
-extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
-extern const u8 raid6_gfexp[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfinv[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfexi[256]      __attribute__((aligned(256)));
-
-/* Recovery routines */
-void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
-void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-
-/* Some definitions to allow code to be compiled for testing in userspace */
-#ifndef __KERNEL__
-
-# define jiffies	raid6_jiffies()
-# define printk 	printf
-# define GFP_KERNEL	0
-# define __get_free_pages(x,y)	((unsigned long)mmap(NULL, PAGE_SIZE << (y), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0))
-# define free_pages(x,y)	munmap((void *)(x), (y)*PAGE_SIZE)
-
-static inline void cpu_relax(void)
-{
-	/* Nothing */
-}
-
-#undef  HZ
-#define HZ 1000
-static inline uint32_t raid6_jiffies(void)
-{
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	return tv.tv_sec*1000 + tv.tv_usec/1000;
-}
-
-#endif /* ! __KERNEL__ */
-
-#endif /* LINUX_RAID_RAID6_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6int.uc linux-libre-2.6.30-gnu1/drivers/md/raid6int.uc
--- linux-libre-2.6.29-gnu1/drivers/md/raid6int.uc	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6int.uc	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
  * This file is postprocessed using unroll.pl
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /*
  * This is the C data type to use
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6mmx.c linux-libre-2.6.30-gnu1/drivers/md/raid6mmx.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6mmx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6mmx.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Shared with raid6sse1.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6recov.c linux-libre-2.6.30-gnu1/drivers/md/raid6recov.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6recov.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6recov.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
  * the syndrome.)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /* Recover two failed data blocks. */
 void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@ void raid6_2data_recov(int disks, size_t
 		p++; q++;
 	}
 }
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
 
 /* Recover failure of one data block plus the P block */
 void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@ void raid6_datap_recov(int disks, size_t
 		q++; dq++;
 	}
 }
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
 
-
-#ifndef __KERNEL__		/* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
 
 /* Recover two failed blocks. */
 void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6sse1.c linux-libre-2.6.30-gnu1/drivers/md/raid6sse1.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6sse1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6sse1.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -23,7 +23,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Defined in raid6mmx.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6sse2.c linux-libre-2.6.30-gnu1/drivers/md/raid6sse2.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6sse2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6sse2.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -19,7 +19,7 @@
 
 #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 static const struct raid6_sse_constants {
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6test/Makefile linux-libre-2.6.30-gnu1/drivers/md/raid6test/Makefile
--- linux-libre-2.6.29-gnu1/drivers/md/raid6test/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6test/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
 
 CC	 = gcc
 OPTFLAGS = -O2			# Adjust as desired
-CFLAGS	 = -I.. -g $(OPTFLAGS)
+CFLAGS	 = -I.. -I ../../../include -g $(OPTFLAGS)
 LD	 = ld
 PERL	 = perl
 AR	 = ar
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6test/test.c linux-libre-2.6.30-gnu1/drivers/md/raid6test/test.c
--- linux-libre-2.6.29-gnu1/drivers/md/raid6test/test.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6test/test.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #define NDISKS		16	/* Including P and Q */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/md/raid6x86.h linux-libre-2.6.30-gnu1/drivers/md/raid6x86.h
--- linux-libre-2.6.29-gnu1/drivers/md/raid6x86.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/md/raid6x86.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/ir-keymaps.c linux-libre-2.6.30-gnu1/drivers/media/common/ir-keymaps.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/ir-keymaps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/ir-keymaps.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[
 };
 EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a);
 
+/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = {
+	[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 */
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus);
+
 /* Attila Kondoros <attila.kondoros@chello.hu> */
 IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
 
@@ -2452,6 +2511,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_a
 };
 EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
 
+/* Kaiomy TVnPC U2
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = {
+	[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,
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
+
 IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
 	[0x20] = KEY_LIST,
 	[0x00] = KEY_POWER,
@@ -2604,3 +2712,41 @@ IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600);
+
+/* DVBWorld remotes
+   Igor M. Liplianin <liplianin@me.by>
+ */
+IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
+	[0x0a] = KEY_Q,		/*power*/
+	[0x0c] = KEY_M,		/*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_PAGEUP,	/*ch+*/
+	[0x0f] = KEY_PAGEDOWN,	/*ch-*/
+	[0x1a] = KEY_O,		/*vol+*/
+	[0x0e] = KEY_Z,		/*vol-*/
+	[0x04] = KEY_R,		/*rec*/
+	[0x09] = KEY_D,		/*fav*/
+	[0x08] = KEY_BACKSPACE,	/*rewind*/
+	[0x07] = KEY_A,		/*fast*/
+	[0x0b] = KEY_P,		/*pause*/
+	[0x02] = KEY_ESC,	/*cancel*/
+	[0x03] = KEY_G,		/*tab*/
+	[0x00] = KEY_UP,	/*up*/
+	[0x1f] = KEY_ENTER,	/*ok*/
+	[0x01] = KEY_DOWN,	/*down*/
+	[0x05] = KEY_C,		/*cap*/
+	[0x06] = KEY_S,		/*stop*/
+	[0x40] = KEY_F,		/*full*/
+	[0x1e] = KEY_W,		/*tvmode*/
+	[0x1b] = KEY_B,		/*recall*/
+};
+EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_core.c linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_core.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -452,8 +452,6 @@ static int saa7146_init_one(struct pci_d
 	INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
 	dev->ext = ext;
 
-	pci_set_drvdata(pci, dev);
-
 	mutex_init(&dev->lock);
 	spin_lock_init(&dev->int_slock);
 	spin_lock_init(&dev->slock);
@@ -477,8 +475,12 @@ static int saa7146_init_one(struct pci_d
 
 	if (ext->attach(dev, pci_ext)) {
 		DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
-		goto err_unprobe;
+		goto err_free_i2c;
 	}
+	/* V4L extensions will set the pci drvdata to the v4l2_device in the
+	   attach() above. So for those cards that do not use V4L we have to
+	   set it explicitly. */
+	pci_set_drvdata(pci, &dev->v4l2_dev);
 
 	INIT_LIST_HEAD(&dev->item);
 	list_add_tail(&dev->item,&saa7146_devices);
@@ -488,8 +490,6 @@ static int saa7146_init_one(struct pci_d
 out:
 	return err;
 
-err_unprobe:
-	pci_set_drvdata(pci, NULL);
 err_free_i2c:
 	pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
 			    dev->d_i2c.dma_handle);
@@ -514,7 +514,8 @@ err_free:
 
 static void saa7146_remove_one(struct pci_dev *pdev)
 {
-	struct saa7146_dev* dev = pci_get_drvdata(pdev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
+	struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
 	struct {
 		void *addr;
 		dma_addr_t dma;
@@ -528,6 +529,8 @@ static void saa7146_remove_one(struct pc
 	DEB_EE(("dev:%p\n",dev));
 
 	dev->ext->detach(dev);
+	/* Zero the PCI drvdata after use. */
+	pci_set_drvdata(pdev, NULL);
 
 	/* shut down all video dma transfers */
 	saa7146_write(dev, MC1, 0x00ff0000);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_fops.c linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_fops.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_fops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_fops.c	2009-06-09 23:05:27.000000000 -0400
@@ -308,14 +308,6 @@ static int fops_release(struct file *fil
 	return 0;
 }
 
-static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-/*
-	DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg));
-*/
-	return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
-}
-
 static int fops_mmap(struct file *file, struct vm_area_struct * vma)
 {
 	struct saa7146_fh *fh = file->private_data;
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations
 	.write		= fops_write,
 	.poll		= fops_poll,
 	.mmap		= fops_mmap,
-	.ioctl		= fops_ioctl,
+	.ioctl		= video_ioctl2,
 };
 
 static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@@ -452,19 +444,22 @@ static void vv_callback(struct saa7146_d
 	}
 }
 
-static struct video_device device_template =
-{
-	.fops		= &video_fops,
-	.minor		= -1,
-};
-
 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
 {
-	struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
-	if( NULL == vv ) {
+	struct saa7146_vv *vv;
+	int err;
+
+	err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+	if (err)
+		return err;
+
+	vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
+	if (vv == NULL) {
 		ERR(("out of memory. aborting.\n"));
-		return -1;
+		return -ENOMEM;
 	}
+	ext_vv->ops = saa7146_video_ioctl_ops;
+	ext_vv->core_ops = &saa7146_video_ioctl_ops;
 
 	DEB_EE(("dev:%p\n",dev));
 
@@ -507,6 +502,7 @@ int saa7146_vv_release(struct saa7146_de
 
 	DEB_EE(("dev:%p\n",dev));
 
+	v4l2_device_unregister(&dev->v4l2_dev);
 	pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
 	kfree(vv);
 	dev->vv_data = NULL;
@@ -521,6 +517,8 @@ int saa7146_register_device(struct video
 {
 	struct saa7146_vv *vv = dev->vv_data;
 	struct video_device *vfd;
+	int err;
+	int i;
 
 	DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
 
@@ -529,16 +527,20 @@ int saa7146_register_device(struct video
 	if (vfd == NULL)
 		return -ENOMEM;
 
-	memcpy(vfd, &device_template, sizeof(struct video_device));
-	strlcpy(vfd->name, name, sizeof(vfd->name));
+	vfd->fops = &video_fops;
+	vfd->ioctl_ops = &dev->ext_vv_data->ops;
 	vfd->release = video_device_release;
+	vfd->tvnorms = 0;
+	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+		vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
+	strlcpy(vfd->name, name, sizeof(vfd->name));
 	video_set_drvdata(vfd, dev);
 
-	// fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
-	if (video_register_device(vfd, type, -1) < 0) {
+	err = video_register_device(vfd, type, -1);
+	if (err < 0) {
 		ERR(("cannot register v4l2 device. skipping.\n"));
 		video_device_release(vfd);
-		return -1;
+		return err;
 	}
 
 	if( VFL_TYPE_GRABBER == type ) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_i2c.c linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -293,7 +293,6 @@ static int saa7146_i2c_transfer(struct s
 	int i = 0, count = 0;
 	__le32 *buffer = dev->d_i2c.cpu_addr;
 	int err = 0;
-	int address_err = 0;
 	int short_delay = 0;
 
 	if (mutex_lock_interruptible(&dev->i2c_lock))
@@ -333,17 +332,10 @@ static int saa7146_i2c_transfer(struct s
 				   i2c address probing, however, and address errors indicate that a
 				   device is really *not* there. retrying in that case
 				   increases the time the device needs to probe greatly, so
-				   it should be avoided. because of the fact, that only
-				   analog based cards use irq based i2c transactions (for dvb
-				   cards, this screwes up other interrupt sources), we bail out
-				   completely for analog cards after an address error and trust
-				   the saa7146 address error detection. */
-				if ( -EREMOTEIO == err ) {
-					if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
-						goto out;
-					}
-					address_err++;
-				}
+				   it should be avoided. So we bail out in irq mode after an
+				   address error and trust the saa7146 address error detection. */
+				if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags))
+					goto out;
 				DEB_I2C(("error while sending message(s). starting again.\n"));
 				break;
 			}
@@ -358,10 +350,9 @@ static int saa7146_i2c_transfer(struct s
 
 	} while (err != num && retries--);
 
-	/* if every retry had an address error, exit right away */
-	if (address_err == retries) {
+	/* quit if any error occurred */
+	if (err != num)
 		goto out;
-	}
 
 	/* if any things had to be read, get the results */
 	if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
@@ -390,7 +381,8 @@ out:
 /* utility functions */
 static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
 {
-	struct saa7146_dev* dev = i2c_get_adapdata(adapter);
+	struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+	struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
 
 	/* use helper function to transfer data */
 	return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
@@ -417,9 +409,8 @@ int saa7146_i2c_adapter_prepare(struct s
 	dev->i2c_bitrate = bitrate;
 	saa7146_i2c_reset(dev);
 
-	if( NULL != i2c_adapter ) {
-		BUG_ON(!i2c_adapter->class);
-		i2c_set_adapdata(i2c_adapter,dev);
+	if (i2c_adapter) {
+		i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
 		i2c_adapter->dev.parent    = &dev->pci->dev;
 		i2c_adapter->algo	   = &saa7146_algo;
 		i2c_adapter->algo_data     = NULL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_video.c linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_video.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/saa7146_video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/saa7146_video.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,5 @@
 #include <media/saa7146_vv.h>
+#include <media/v4l2-chip-ident.h>
 
 static int max_memory = 32;
 
@@ -97,172 +98,13 @@ struct saa7146_format* format_by_fourcc(
 	return NULL;
 }
 
-static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
-	struct saa7146_dev *dev = fh->dev;
-	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		f->fmt.pix = fh->video_fmt;
-		return 0;
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		f->fmt.win = fh->ov.win;
-		return 0;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
-	{
-		f->fmt.vbi = fh->vbi_fmt;
-		return 0;
-	}
-	default:
-		DEB_D(("invalid format type '%d'.\n",f->type));
-		return -EINVAL;
-	}
-}
-
-static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
-{
-	struct saa7146_vv *vv = dev->vv_data;
-	enum v4l2_field field;
-	int maxw, maxh;
-
-	DEB_EE(("dev:%p\n",dev));
-
-	if (NULL == vv->ov_fb.base) {
-		DEB_D(("no fb base set.\n"));
-		return -EINVAL;
-	}
-	if (NULL == vv->ov_fmt) {
-		DEB_D(("no fb fmt set.\n"));
-		return -EINVAL;
-	}
-	if (win->w.width < 48 || win->w.height <  32) {
-		DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
-		return -EINVAL;
-	}
-	if (win->clipcount > 16) {
-		DEB_D(("clipcount too big.\n"));
-		return -EINVAL;
-	}
-
-	field = win->field;
-	maxw  = vv->standard->h_max_out;
-	maxh  = vv->standard->v_max_out;
-
-	if (V4L2_FIELD_ANY == field) {
-		field = (win->w.height > maxh/2)
-			? V4L2_FIELD_INTERLACED
-			: V4L2_FIELD_TOP;
-		}
-	switch (field) {
-	case V4L2_FIELD_TOP:
-	case V4L2_FIELD_BOTTOM:
-	case V4L2_FIELD_ALTERNATE:
-		maxh = maxh / 2;
-		break;
-	case V4L2_FIELD_INTERLACED:
-		break;
-	default: {
-		DEB_D(("no known field mode '%d'.\n",field));
-		return -EINVAL;
-	}
-	}
-
-	win->field = field;
-	if (win->w.width > maxw)
-		win->w.width = maxw;
-	if (win->w.height > maxh)
-		win->w.height = maxh;
-
-	return 0;
-}
-
-static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct saa7146_vv *vv = dev->vv_data;
-	int err;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-	{
-		struct saa7146_format *fmt;
-		enum v4l2_field field;
-		int maxw, maxh;
-		int calc_bpl;
-
-		DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
-
-		fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
-		if (NULL == fmt) {
-			return -EINVAL;
-		}
-
-		field = f->fmt.pix.field;
-		maxw  = vv->standard->h_max_out;
-		maxh  = vv->standard->v_max_out;
-
-		if (V4L2_FIELD_ANY == field) {
-			field = (f->fmt.pix.height > maxh/2)
-				? V4L2_FIELD_INTERLACED
-				: V4L2_FIELD_BOTTOM;
-		}
-		switch (field) {
-		case V4L2_FIELD_ALTERNATE: {
-			vv->last_field = V4L2_FIELD_TOP;
-			maxh = maxh / 2;
-			break;
-		}
-		case V4L2_FIELD_TOP:
-		case V4L2_FIELD_BOTTOM:
-			vv->last_field = V4L2_FIELD_INTERLACED;
-			maxh = maxh / 2;
-			break;
-		case V4L2_FIELD_INTERLACED:
-			vv->last_field = V4L2_FIELD_INTERLACED;
-			break;
-		default: {
-			DEB_D(("no known field mode '%d'.\n",field));
-			return -EINVAL;
-		}
-		}
-
-		f->fmt.pix.field = field;
-		if (f->fmt.pix.width > maxw)
-			f->fmt.pix.width = maxw;
-		if (f->fmt.pix.height > maxh)
-			f->fmt.pix.height = maxh;
-
-		calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
-
-		if (f->fmt.pix.bytesperline < calc_bpl)
-			f->fmt.pix.bytesperline = calc_bpl;
-
-		if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
-			f->fmt.pix.bytesperline = calc_bpl;
-
-		f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
-		DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
-
-		return 0;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
-		err = try_win(dev,&f->fmt.win);
-		if (0 != err) {
-			return err;
-		}
-		return 0;
-	default:
-		DEB_EE(("unknown format type '%d'\n",f->type));
-		return -EINVAL;
-	}
-}
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
 
 int saa7146_start_preview(struct saa7146_fh *fh)
 {
 	struct saa7146_dev *dev = fh->dev;
 	struct saa7146_vv *vv = dev->vv_data;
+	struct v4l2_format fmt;
 	int ret = 0, err = 0;
 
 	DEB_EE(("dev:%p, fh:%p\n",dev,fh));
@@ -294,12 +136,13 @@ int saa7146_start_preview(struct saa7146
 		return -EBUSY;
 	}
 
-	err = try_win(dev,&fh->ov.win);
+	fmt.fmt.win = fh->ov.win;
+	err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
 	if (0 != err) {
 		saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
 		return -EBUSY;
 	}
-
+	fh->ov.win = fmt.fmt.win;
 	vv->ov_data = &fh->ov;
 
 	DEB_D(("%dx%d+%d+%d %s field=%s\n",
@@ -355,58 +198,6 @@ int saa7146_stop_preview(struct saa7146_
 }
 EXPORT_SYMBOL_GPL(saa7146_stop_preview);
 
-static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct saa7146_vv *vv = dev->vv_data;
-
-	int err;
-
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
-		if (IS_CAPTURE_ACTIVE(fh) != 0) {
-			DEB_EE(("streaming capture is active\n"));
-			return -EBUSY;
-		}
-		err = try_fmt(fh,f);
-		if (0 != err)
-			return err;
-		fh->video_fmt = f->fmt.pix;
-		DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
-		return 0;
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
-		err = try_win(dev,&f->fmt.win);
-		if (0 != err)
-			return err;
-		mutex_lock(&dev->lock);
-		fh->ov.win    = f->fmt.win;
-		fh->ov.nclips = f->fmt.win.clipcount;
-		if (fh->ov.nclips > 16)
-			fh->ov.nclips = 16;
-		if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
-			mutex_unlock(&dev->lock);
-			return -EFAULT;
-		}
-
-		/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
-		fh->ov.fh = fh;
-
-		mutex_unlock(&dev->lock);
-
-		/* check if our current overlay is active */
-		if (IS_OVERLAY_ACTIVE(fh) != 0) {
-			saa7146_stop_preview(fh);
-			saa7146_start_preview(fh);
-		}
-		return 0;
-	default:
-		DEB_D(("unknown format type '%d'\n",f->type));
-		return -EINVAL;
-	}
-}
-
 /********************************************************************************/
 /* device controls */
 
@@ -419,6 +210,7 @@ static struct v4l2_queryctrl controls[]
 		.step		= 1,
 		.default_value	= 128,
 		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.flags 		= V4L2_CTRL_FLAG_SLIDER,
 	},{
 		.id		= V4L2_CID_CONTRAST,
 		.name		= "Contrast",
@@ -427,6 +219,7 @@ static struct v4l2_queryctrl controls[]
 		.step		= 1,
 		.default_value	= 64,
 		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.flags 		= V4L2_CTRL_FLAG_SLIDER,
 	},{
 		.id		= V4L2_CID_SATURATION,
 		.name		= "Saturation",
@@ -435,15 +228,16 @@ static struct v4l2_queryctrl controls[]
 		.step		= 1,
 		.default_value	= 64,
 		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.flags 		= V4L2_CTRL_FLAG_SLIDER,
 	},{
 		.id		= V4L2_CID_VFLIP,
-		.name		= "Vertical flip",
+		.name		= "Vertical Flip",
 		.minimum	= 0,
 		.maximum	= 1,
 		.type		= V4L2_CTRL_TYPE_BOOLEAN,
 	},{
 		.id		= V4L2_CID_HFLIP,
-		.name		= "Horizontal flip",
+		.name		= "Horizontal Flip",
 		.minimum	= 0,
 		.maximum	= 1,
 		.type		= V4L2_CTRL_TYPE_BOOLEAN,
@@ -463,132 +257,6 @@ static struct v4l2_queryctrl* ctrl_by_id
 	return NULL;
 }
 
-static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct saa7146_vv *vv = dev->vv_data;
-
-	const struct v4l2_queryctrl* ctrl;
-	u32 value = 0;
-
-	ctrl = ctrl_by_id(c->id);
-	if (NULL == ctrl)
-		return -EINVAL;
-	switch (c->id) {
-	case V4L2_CID_BRIGHTNESS:
-		value = saa7146_read(dev, BCS_CTRL);
-		c->value = 0xff & (value >> 24);
-		DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
-		break;
-	case V4L2_CID_CONTRAST:
-		value = saa7146_read(dev, BCS_CTRL);
-		c->value = 0x7f & (value >> 16);
-		DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
-		break;
-	case V4L2_CID_SATURATION:
-		value = saa7146_read(dev, BCS_CTRL);
-		c->value = 0x7f & (value >> 0);
-		DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
-		break;
-	case V4L2_CID_VFLIP:
-		c->value = vv->vflip;
-		DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
-		break;
-	case V4L2_CID_HFLIP:
-		c->value = vv->hflip;
-		DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct saa7146_vv *vv = dev->vv_data;
-
-	const struct v4l2_queryctrl* ctrl;
-
-	ctrl = ctrl_by_id(c->id);
-	if (NULL == ctrl) {
-		DEB_D(("unknown control %d\n",c->id));
-		return -EINVAL;
-	}
-
-	mutex_lock(&dev->lock);
-
-	switch (ctrl->type) {
-	case V4L2_CTRL_TYPE_BOOLEAN:
-	case V4L2_CTRL_TYPE_MENU:
-	case V4L2_CTRL_TYPE_INTEGER:
-		if (c->value < ctrl->minimum)
-			c->value = ctrl->minimum;
-		if (c->value > ctrl->maximum)
-			c->value = ctrl->maximum;
-		break;
-	default:
-		/* nothing */;
-	};
-
-	switch (c->id) {
-	case V4L2_CID_BRIGHTNESS: {
-		u32 value = saa7146_read(dev, BCS_CTRL);
-		value &= 0x00ffffff;
-		value |= (c->value << 24);
-		saa7146_write(dev, BCS_CTRL, value);
-		saa7146_write(dev, MC2, MASK_22 | MASK_06 );
-		break;
-	}
-	case V4L2_CID_CONTRAST: {
-		u32 value = saa7146_read(dev, BCS_CTRL);
-		value &= 0xff00ffff;
-		value |= (c->value << 16);
-		saa7146_write(dev, BCS_CTRL, value);
-		saa7146_write(dev, MC2, MASK_22 | MASK_06 );
-		break;
-	}
-	case V4L2_CID_SATURATION: {
-		u32 value = saa7146_read(dev, BCS_CTRL);
-		value &= 0xffffff00;
-		value |= (c->value << 0);
-		saa7146_write(dev, BCS_CTRL, value);
-		saa7146_write(dev, MC2, MASK_22 | MASK_06 );
-		break;
-	}
-	case V4L2_CID_HFLIP:
-		/* fixme: we can support changing VFLIP and HFLIP here... */
-		if (IS_CAPTURE_ACTIVE(fh) != 0) {
-			DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
-			mutex_unlock(&dev->lock);
-			return -EINVAL;
-		}
-		vv->hflip = c->value;
-		break;
-	case V4L2_CID_VFLIP:
-		if (IS_CAPTURE_ACTIVE(fh) != 0) {
-			DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
-			mutex_unlock(&dev->lock);
-			return -EINVAL;
-		}
-		vv->vflip = c->value;
-		break;
-	default: {
-		mutex_unlock(&dev->lock);
-		return -EINVAL;
-	}
-	}
-	mutex_unlock(&dev->lock);
-
-	if (IS_OVERLAY_ACTIVE(fh) != 0) {
-		saa7146_stop_preview(fh);
-		saa7146_start_preview(fh);
-	}
-	return 0;
-}
-
 /********************************************************************************/
 /* common pagetable functions */
 
@@ -829,231 +497,446 @@ static int video_end(struct saa7146_fh *
 	return 0;
 }
 
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others).  userspace
- * copying is done already, arg is a kernel pointer.
- */
+static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+	strcpy((char *)cap->driver, "saa7146 v4l2");
+	strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
+	sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
+	cap->version = SAA7146_VERSION_CODE;
+	cap->capabilities =
+		V4L2_CAP_VIDEO_CAPTURE |
+		V4L2_CAP_VIDEO_OVERLAY |
+		V4L2_CAP_READWRITE |
+		V4L2_CAP_STREAMING;
+	cap->capabilities |= dev->ext_vv_data->capabilities;
+	return 0;
+}
+
+static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
 {
-	struct saa7146_fh *fh  = file->private_data;
-	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct saa7146_vv *vv = dev->vv_data;
 
-	long err = 0;
-	int result = 0, ee = 0;
+	*fb = vv->ov_fb;
+	fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+	return 0;
+}
 
-	struct saa7146_use_ops *ops;
-	struct videobuf_queue *q;
+static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	struct saa7146_format *fmt;
 
-	/* check if extension handles the command */
-	for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
-		if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
-			break;
-	}
+	DEB_EE(("VIDIOC_S_FBUF\n"));
 
-	if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
-		DEB_D(("extension handles ioctl exclusive.\n"));
-		result = dev->ext_vv_data->ioctl(fh, cmd, arg);
-		return result;
-	}
-	if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
-		DEB_D(("extension handles ioctl before.\n"));
-		result = dev->ext_vv_data->ioctl(fh, cmd, arg);
-		if( -EAGAIN != result ) {
-			return result;
+	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	/* check args */
+	fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+	if (NULL == fmt)
+		return -EINVAL;
+
+	/* planar formats are not allowed for overlay video, clipping and video dma would clash */
+	if (fmt->flags & FORMAT_IS_PLANAR)
+		DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
+					(char *)&fmt->pixelformat));
+
+	/* check if overlay is running */
+	if (IS_OVERLAY_ACTIVE(fh) != 0) {
+		if (vv->video_fh != fh) {
+			DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
+			return -EBUSY;
 		}
 	}
 
-	/* fixme: add handle "after" case (is it still needed?) */
+	mutex_lock(&dev->lock);
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		ops = &saa7146_video_uops;
-		q = &fh->video_q;
+	/* ok, accept it */
+	vv->ov_fb = *fb;
+	vv->ov_fmt = fmt;
+	if (0 == vv->ov_fb.fmt.bytesperline)
+		vv->ov_fb.fmt.bytesperline =
+			vv->ov_fb.fmt.width * fmt->depth / 8;
+
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	if (f->index >= NUM_FORMATS)
+		return -EINVAL;
+	strlcpy((char *)f->description, formats[f->index].name,
+			sizeof(f->description));
+	f->pixelformat = formats[f->index].pixelformat;
+	return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
+{
+	const struct v4l2_queryctrl *ctrl;
+
+	if ((c->id <  V4L2_CID_BASE ||
+	     c->id >= V4L2_CID_LASTP1) &&
+	    (c->id <  V4L2_CID_PRIVATE_BASE ||
+	     c->id >= V4L2_CID_PRIVATE_LASTP1))
+		return -EINVAL;
+
+	ctrl = ctrl_by_id(c->id);
+	if (ctrl == NULL)
+		return -EINVAL;
+
+	DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
+	*c = *ctrl;
+	return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	const struct v4l2_queryctrl *ctrl;
+	u32 value = 0;
+
+	ctrl = ctrl_by_id(c->id);
+	if (NULL == ctrl)
+		return -EINVAL;
+	switch (c->id) {
+	case V4L2_CID_BRIGHTNESS:
+		value = saa7146_read(dev, BCS_CTRL);
+		c->value = 0xff & (value >> 24);
+		DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
 		break;
-		}
-	case V4L2_BUF_TYPE_VBI_CAPTURE: {
-		ops = &saa7146_vbi_uops;
-		q = &fh->vbi_q;
+	case V4L2_CID_CONTRAST:
+		value = saa7146_read(dev, BCS_CTRL);
+		c->value = 0x7f & (value >> 16);
+		DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
+		break;
+	case V4L2_CID_SATURATION:
+		value = saa7146_read(dev, BCS_CTRL);
+		c->value = 0x7f & (value >> 0);
+		DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
+		break;
+	case V4L2_CID_VFLIP:
+		c->value = vv->vflip;
+		DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
+		break;
+	case V4L2_CID_HFLIP:
+		c->value = vv->hflip;
+		DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
 		break;
-		}
 	default:
-		BUG();
-		return 0;
+		return -EINVAL;
 	}
+	return 0;
+}
 
-	switch (cmd) {
-	case VIDIOC_QUERYCAP:
-	{
-		struct v4l2_capability *cap = arg;
-		memset(cap,0,sizeof(*cap));
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	const struct v4l2_queryctrl *ctrl;
 
-		DEB_EE(("VIDIOC_QUERYCAP\n"));
+	ctrl = ctrl_by_id(c->id);
+	if (NULL == ctrl) {
+		DEB_D(("unknown control %d\n", c->id));
+		return -EINVAL;
+	}
 
-		strcpy((char *)cap->driver, "saa7146 v4l2");
-		strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
-		sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci));
-		cap->version = SAA7146_VERSION_CODE;
-		cap->capabilities =
-			V4L2_CAP_VIDEO_CAPTURE |
-			V4L2_CAP_VIDEO_OVERLAY |
-			V4L2_CAP_READWRITE |
-			V4L2_CAP_STREAMING;
-		cap->capabilities |= dev->ext_vv_data->capabilities;
-		return 0;
+	mutex_lock(&dev->lock);
+
+	switch (ctrl->type) {
+	case V4L2_CTRL_TYPE_BOOLEAN:
+	case V4L2_CTRL_TYPE_MENU:
+	case V4L2_CTRL_TYPE_INTEGER:
+		if (c->value < ctrl->minimum)
+			c->value = ctrl->minimum;
+		if (c->value > ctrl->maximum)
+			c->value = ctrl->maximum;
+		break;
+	default:
+		/* nothing */;
 	}
-	case VIDIOC_G_FBUF:
-	{
-		struct v4l2_framebuffer *fb = arg;
 
-		DEB_EE(("VIDIOC_G_FBUF\n"));
+	switch (c->id) {
+	case V4L2_CID_BRIGHTNESS: {
+		u32 value = saa7146_read(dev, BCS_CTRL);
+		value &= 0x00ffffff;
+		value |= (c->value << 24);
+		saa7146_write(dev, BCS_CTRL, value);
+		saa7146_write(dev, MC2, MASK_22 | MASK_06);
+		break;
+	}
+	case V4L2_CID_CONTRAST: {
+		u32 value = saa7146_read(dev, BCS_CTRL);
+		value &= 0xff00ffff;
+		value |= (c->value << 16);
+		saa7146_write(dev, BCS_CTRL, value);
+		saa7146_write(dev, MC2, MASK_22 | MASK_06);
+		break;
+	}
+	case V4L2_CID_SATURATION: {
+		u32 value = saa7146_read(dev, BCS_CTRL);
+		value &= 0xffffff00;
+		value |= (c->value << 0);
+		saa7146_write(dev, BCS_CTRL, value);
+		saa7146_write(dev, MC2, MASK_22 | MASK_06);
+		break;
+	}
+	case V4L2_CID_HFLIP:
+		/* fixme: we can support changing VFLIP and HFLIP here... */
+		if (IS_CAPTURE_ACTIVE(fh) != 0) {
+			DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
+			mutex_unlock(&dev->lock);
+			return -EBUSY;
+		}
+		vv->hflip = c->value;
+		break;
+	case V4L2_CID_VFLIP:
+		if (IS_CAPTURE_ACTIVE(fh) != 0) {
+			DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
+			mutex_unlock(&dev->lock);
+			return -EBUSY;
+		}
+		vv->vflip = c->value;
+		break;
+	default:
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+	mutex_unlock(&dev->lock);
 
-		*fb = vv->ov_fb;
-		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
-		return 0;
+	if (IS_OVERLAY_ACTIVE(fh) != 0) {
+		saa7146_stop_preview(fh);
+		saa7146_start_preview(fh);
 	}
-	case VIDIOC_S_FBUF:
-	{
-		struct v4l2_framebuffer *fb = arg;
-		struct saa7146_format *fmt;
+	return 0;
+}
 
-		DEB_EE(("VIDIOC_S_FBUF\n"));
+static int vidioc_g_parm(struct file *file, void *fh,
+		struct v4l2_streamparm *parm)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
 
-		if(!capable(CAP_SYS_ADMIN) &&
-		   !capable(CAP_SYS_RAWIO))
-			return -EPERM;
+	parm->parm.capture.readbuffers = 1;
+	v4l2_video_std_frame_period(vv->standard->id,
+				    &parm->parm.capture.timeperframe);
+	return 0;
+}
 
-		/* check args */
-		fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
-		if (NULL == fmt) {
-			return -EINVAL;
-		}
+static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
+	return 0;
+}
 
-		/* planar formats are not allowed for overlay video, clipping and video dma would clash */
-		if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
-			DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
-		}
+static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+	f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
+	return 0;
+}
 
-		/* check if overlay is running */
-		if (IS_OVERLAY_ACTIVE(fh) != 0) {
-			if (vv->video_fh != fh) {
-				DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
-				return -EBUSY;
-			}
-		}
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
+	return 0;
+}
 
-		mutex_lock(&dev->lock);
+static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	struct saa7146_format *fmt;
+	enum v4l2_field field;
+	int maxw, maxh;
+	int calc_bpl;
 
-		/* ok, accept it */
-		vv->ov_fb = *fb;
-		vv->ov_fmt = fmt;
-		if (0 == vv->ov_fb.fmt.bytesperline)
-			vv->ov_fb.fmt.bytesperline =
-				vv->ov_fb.fmt.width*fmt->depth/8;
+	DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
 
-		mutex_unlock(&dev->lock);
+	fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+	if (NULL == fmt)
+		return -EINVAL;
 
-		return 0;
+	field = f->fmt.pix.field;
+	maxw  = vv->standard->h_max_out;
+	maxh  = vv->standard->v_max_out;
+
+	if (V4L2_FIELD_ANY == field) {
+		field = (f->fmt.pix.height > maxh / 2)
+			? V4L2_FIELD_INTERLACED
+			: V4L2_FIELD_BOTTOM;
+	}
+	switch (field) {
+	case V4L2_FIELD_ALTERNATE:
+		vv->last_field = V4L2_FIELD_TOP;
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_TOP:
+	case V4L2_FIELD_BOTTOM:
+		vv->last_field = V4L2_FIELD_INTERLACED;
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		vv->last_field = V4L2_FIELD_INTERLACED;
+		break;
+	default:
+		DEB_D(("no known field mode '%d'.\n", field));
+		return -EINVAL;
 	}
-	case VIDIOC_ENUM_FMT:
-	{
-		struct v4l2_fmtdesc *f = arg;
 
-		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			if (f->index >= NUM_FORMATS)
-				return -EINVAL;
-			strlcpy((char *)f->description, formats[f->index].name,
-					sizeof(f->description));
-			f->pixelformat = formats[f->index].pixelformat;
-			f->flags = 0;
-			memset(f->reserved, 0, sizeof(f->reserved));
-			break;
-		default:
-			return -EINVAL;
-		}
+	f->fmt.pix.field = field;
+	if (f->fmt.pix.width > maxw)
+		f->fmt.pix.width = maxw;
+	if (f->fmt.pix.height > maxh)
+		f->fmt.pix.height = maxh;
 
-		DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
-		return 0;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		const struct v4l2_queryctrl *ctrl;
-		struct v4l2_queryctrl *c = arg;
+	calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
 
-		if ((c->id <  V4L2_CID_BASE ||
-		     c->id >= V4L2_CID_LASTP1) &&
-		    (c->id <  V4L2_CID_PRIVATE_BASE ||
-		     c->id >= V4L2_CID_PRIVATE_LASTP1))
-			return -EINVAL;
+	if (f->fmt.pix.bytesperline < calc_bpl)
+		f->fmt.pix.bytesperline = calc_bpl;
 
-		ctrl = ctrl_by_id(c->id);
-		if( NULL == ctrl ) {
-			return -EINVAL;
-/*
-			c->flags = V4L2_CTRL_FLAG_DISABLED;
-			return 0;
-*/
-		}
+	if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
+		f->fmt.pix.bytesperline = calc_bpl;
 
-		DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
-		*c = *ctrl;
-		return 0;
+	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+	DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
+			f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
+
+	return 0;
+}
+
+
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	struct v4l2_window *win = &f->fmt.win;
+	enum v4l2_field field;
+	int maxw, maxh;
+
+	DEB_EE(("dev:%p\n", dev));
+
+	if (NULL == vv->ov_fb.base) {
+		DEB_D(("no fb base set.\n"));
+		return -EINVAL;
 	}
-	case VIDIOC_G_CTRL: {
-		DEB_EE(("VIDIOC_G_CTRL\n"));
-		return get_control(fh,arg);
+	if (NULL == vv->ov_fmt) {
+		DEB_D(("no fb fmt set.\n"));
+		return -EINVAL;
 	}
-	case VIDIOC_S_CTRL:
-	{
-		DEB_EE(("VIDIOC_S_CTRL\n"));
-		err = set_control(fh,arg);
-		return err;
+	if (win->w.width < 48 || win->w.height < 32) {
+		DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
+		return -EINVAL;
 	}
-	case VIDIOC_G_PARM:
-	{
-		struct v4l2_streamparm *parm = arg;
-		if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
-			return -EINVAL;
-		}
-		memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
-		parm->parm.capture.readbuffers = 1;
-		// fixme: only for PAL!
-		parm->parm.capture.timeperframe.numerator = 1;
-		parm->parm.capture.timeperframe.denominator = 25;
-		return 0;
+	if (win->clipcount > 16) {
+		DEB_D(("clipcount too big.\n"));
+		return -EINVAL;
 	}
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format *f = arg;
-		DEB_EE(("VIDIOC_G_FMT\n"));
-		return g_fmt(fh,f);
+
+	field = win->field;
+	maxw  = vv->standard->h_max_out;
+	maxh  = vv->standard->v_max_out;
+
+	if (V4L2_FIELD_ANY == field) {
+		field = (win->w.height > maxh / 2)
+			? V4L2_FIELD_INTERLACED
+			: V4L2_FIELD_TOP;
+		}
+	switch (field) {
+	case V4L2_FIELD_TOP:
+	case V4L2_FIELD_BOTTOM:
+	case V4L2_FIELD_ALTERNATE:
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		break;
+	default:
+		DEB_D(("no known field mode '%d'.\n", field));
+		return -EINVAL;
 	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *f = arg;
-		DEB_EE(("VIDIOC_S_FMT\n"));
-		return s_fmt(fh,f);
+
+	win->field = field;
+	if (win->w.width > maxw)
+		win->w.width = maxw;
+	if (win->w.height > maxh)
+		win->w.height = maxh;
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
+{
+	struct saa7146_fh *fh = __fh;
+	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	int err;
+
+	DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
+	if (IS_CAPTURE_ACTIVE(fh) != 0) {
+		DEB_EE(("streaming capture is active\n"));
+		return -EBUSY;
 	}
-	case VIDIOC_TRY_FMT:
-	{
-		struct v4l2_format *f = arg;
-		DEB_EE(("VIDIOC_TRY_FMT\n"));
-		return try_fmt(fh,f);
+	err = vidioc_try_fmt_vid_cap(file, fh, f);
+	if (0 != err)
+		return err;
+	fh->video_fmt = f->fmt.pix;
+	DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
+{
+	struct saa7146_fh *fh = __fh;
+	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	int err;
+
+	DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
+	err = vidioc_try_fmt_vid_overlay(file, fh, f);
+	if (0 != err)
+		return err;
+	mutex_lock(&dev->lock);
+	fh->ov.win    = f->fmt.win;
+	fh->ov.nclips = f->fmt.win.clipcount;
+	if (fh->ov.nclips > 16)
+		fh->ov.nclips = 16;
+	if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
+				sizeof(struct v4l2_clip) * fh->ov.nclips)) {
+		mutex_unlock(&dev->lock);
+		return -EFAULT;
 	}
-	case VIDIOC_G_STD:
-	{
-		v4l2_std_id *id = arg;
-		DEB_EE(("VIDIOC_G_STD\n"));
-		*id = vv->standard->id;
-		return 0;
+
+	/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
+	fh->ov.fh = fh;
+
+	mutex_unlock(&dev->lock);
+
+	/* check if our current overlay is active */
+	if (IS_OVERLAY_ACTIVE(fh) != 0) {
+		saa7146_stop_preview(fh);
+		saa7146_start_preview(fh);
 	}
+	return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+
+	*norm = vv->standard->id;
+	return 0;
+}
+
 	/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
 	   PAL / NTSC / SECAM. if your hardware does not (or does more)
 	   -- override this function in your extension */
+/*
 	case VIDIOC_ENUMSTD:
 	{
 		struct v4l2_standard *e = arg;
@@ -1066,162 +949,245 @@ long saa7146_video_do_ioctl(struct file
 		}
 		return -EINVAL;
 	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *id = arg;
-		int found = 0;
-		int i;
-
-		DEB_EE(("VIDIOC_S_STD\n"));
+	*/
 
-		if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
-			DEB_D(("cannot change video standard while streaming capture is active\n"));
-			return -EBUSY;
-		}
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	int found = 0;
+	int err, i;
 
-		if ((vv->video_status & STATUS_OVERLAY) != 0) {
-			vv->ov_suspend = vv->video_fh;
-			err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
-			if (0 != err) {
-				DEB_D(("suspending video failed. aborting\n"));
-				return err;
-			}
-		}
+	DEB_EE(("VIDIOC_S_STD\n"));
 
-		mutex_lock(&dev->lock);
+	if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
+		DEB_D(("cannot change video standard while streaming capture is active\n"));
+		return -EBUSY;
+	}
 
-		for(i = 0; i < dev->ext_vv_data->num_stds; i++)
-			if (*id & dev->ext_vv_data->stds[i].id)
-				break;
-		if (i != dev->ext_vv_data->num_stds) {
-			vv->standard = &dev->ext_vv_data->stds[i];
-			if( NULL != dev->ext_vv_data->std_callback )
-				dev->ext_vv_data->std_callback(dev, vv->standard);
-			found = 1;
+	if ((vv->video_status & STATUS_OVERLAY) != 0) {
+		vv->ov_suspend = vv->video_fh;
+		err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
+		if (0 != err) {
+			DEB_D(("suspending video failed. aborting\n"));
+			return err;
 		}
+	}
 
-		mutex_unlock(&dev->lock);
+	mutex_lock(&dev->lock);
 
-		if (vv->ov_suspend != NULL) {
-			saa7146_start_preview(vv->ov_suspend);
-			vv->ov_suspend = NULL;
-		}
+	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+		if (*id & dev->ext_vv_data->stds[i].id)
+			break;
+	if (i != dev->ext_vv_data->num_stds) {
+		vv->standard = &dev->ext_vv_data->stds[i];
+		if (NULL != dev->ext_vv_data->std_callback)
+			dev->ext_vv_data->std_callback(dev, vv->standard);
+		found = 1;
+	}
 
-		if( 0 == found ) {
-			DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
-			return -EINVAL;
-		}
+	mutex_unlock(&dev->lock);
 
-		DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
-		return 0;
+	if (vv->ov_suspend != NULL) {
+		saa7146_start_preview(vv->ov_suspend);
+		vv->ov_suspend = NULL;
 	}
-	case VIDIOC_OVERLAY:
-	{
-		int on = *(int *)arg;
 
-		DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
-		if (on != 0) {
-			err = saa7146_start_preview(fh);
-		} else {
-			err = saa7146_stop_preview(fh);
-		}
-		return err;
-	}
-	case VIDIOC_REQBUFS: {
-		struct v4l2_requestbuffers *req = arg;
-		DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
-		return videobuf_reqbufs(q,req);
-	}
-	case VIDIOC_QUERYBUF: {
-		struct v4l2_buffer *buf = arg;
-		DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
-		return videobuf_querybuf(q,buf);
-	}
-	case VIDIOC_QBUF: {
-		struct v4l2_buffer *buf = arg;
-		int ret = 0;
-		ret = videobuf_qbuf(q,buf);
-		DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
-		return ret;
-	}
-	case VIDIOC_DQBUF: {
-		struct v4l2_buffer *buf = arg;
-		int ret = 0;
-		ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK);
-		DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
-		return ret;
+	if (!found) {
+		DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
+		return -EINVAL;
 	}
-	case VIDIOC_STREAMON: {
-		int *type = arg;
-		DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
 
-		err = video_begin(fh);
-		if( 0 != err) {
-			return err;
-		}
-		err = videobuf_streamon(q);
-		return err;
-	}
-	case VIDIOC_STREAMOFF: {
-		int *type = arg;
+	DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
+	return 0;
+}
 
-		DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
+static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
+{
+	int err;
 
-		/* ugly: we need to copy some checks from video_end(),
-		   because videobuf_streamoff() relies on the capture running.
-		   check and fix this */
-		if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
-			DEB_S(("not capturing.\n"));
-			return 0;
-		}
+	DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
+	if (on)
+		err = saa7146_start_preview(fh);
+	else
+		err = saa7146_stop_preview(fh);
+	return err;
+}
 
-		if (vv->video_fh != fh) {
-			DEB_S(("capturing, but in another open.\n"));
-			return -EBUSY;
-		}
+static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
+{
+	struct saa7146_fh *fh = __fh;
 
-		err = videobuf_streamoff(q);
-		if (0 != err) {
-			DEB_D(("warning: videobuf_streamoff() failed.\n"));
-			video_end(fh, file);
-		} else {
-			err = video_end(fh, file);
-		}
+	if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_reqbufs(&fh->video_q, b);
+	if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return videobuf_reqbufs(&fh->vbi_q, b);
+	return -EINVAL;
+}
+
+static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct saa7146_fh *fh = __fh;
+
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_querybuf(&fh->video_q, buf);
+	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return videobuf_querybuf(&fh->vbi_q, buf);
+	return -EINVAL;
+}
+
+static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct saa7146_fh *fh = __fh;
+
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_qbuf(&fh->video_q, buf);
+	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return videobuf_qbuf(&fh->vbi_q, buf);
+	return -EINVAL;
+}
+
+static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct saa7146_fh *fh = __fh;
+
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
+	if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
+	return -EINVAL;
+}
+
+static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+	struct saa7146_fh *fh = __fh;
+	int err;
+
+	DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
+
+	err = video_begin(fh);
+	if (err)
 		return err;
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_streamon(&fh->video_q);
+	if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return videobuf_streamon(&fh->vbi_q);
+	return -EINVAL;
+}
+
+static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+	struct saa7146_fh *fh = __fh;
+	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_vv *vv = dev->vv_data;
+	int err;
+
+	DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
+
+	/* ugly: we need to copy some checks from video_end(),
+	   because videobuf_streamoff() relies on the capture running.
+	   check and fix this */
+	if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
+		DEB_S(("not capturing.\n"));
+		return 0;
 	}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	case VIDIOCGMBUF:
-	{
-		struct video_mbuf *mbuf = arg;
-		int i;
 
-		/* fixme: number of capture buffers and sizes for v4l apps */
-		int gbuffers = 2;
-		int gbufsize = 768*576*4;
+	if (vv->video_fh != fh) {
+		DEB_S(("capturing, but in another open.\n"));
+		return -EBUSY;
+	}
 
-		DEB_D(("VIDIOCGMBUF \n"));
+	err = -EINVAL;
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		err = videobuf_streamoff(&fh->video_q);
+	else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		err = videobuf_streamoff(&fh->vbi_q);
+	if (0 != err) {
+		DEB_D(("warning: videobuf_streamoff() failed.\n"));
+		video_end(fh, file);
+	} else {
+		err = video_end(fh, file);
+	}
+	return err;
+}
 
-		q = &fh->video_q;
-		err = videobuf_mmap_setup(q,gbuffers,gbufsize,
-					  V4L2_MEMORY_MMAP);
-		if (err < 0)
-			return err;
+static int vidioc_g_chip_ident(struct file *file, void *__fh,
+		struct v4l2_dbg_chip_ident *chip)
+{
+	struct saa7146_fh *fh = __fh;
+	struct saa7146_dev *dev = fh->dev;
 
-		gbuffers = err;
-		memset(mbuf,0,sizeof(*mbuf));
-		mbuf->frames = gbuffers;
-		mbuf->size   = gbuffers * gbufsize;
-		for (i = 0; i < gbuffers; i++)
-			mbuf->offsets[i] = i * gbufsize;
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+	if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
+		chip->ident = V4L2_IDENT_SAA7146;
 		return 0;
 	}
-#endif
-	default:
-		return v4l_compat_translate_ioctl(file, cmd, arg,
-						  saa7146_video_do_ioctl);
-	}
+	return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+			core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
+{
+	struct saa7146_fh *fh = __fh;
+	struct videobuf_queue *q = &fh->video_q;
+	int err, i;
+
+	/* fixme: number of capture buffers and sizes for v4l apps */
+	int gbuffers = 2;
+	int gbufsize = 768 * 576 * 4;
+
+	DEB_D(("VIDIOCGMBUF \n"));
+
+	q = &fh->video_q;
+	err = videobuf_mmap_setup(q, gbuffers, gbufsize,
+			V4L2_MEMORY_MMAP);
+	if (err < 0)
+		return err;
+
+	gbuffers = err;
+	memset(mbuf, 0, sizeof(*mbuf));
+	mbuf->frames = gbuffers;
+	mbuf->size   = gbuffers * gbufsize;
+	for (i = 0; i < gbuffers; i++)
+		mbuf->offsets[i] = i * gbufsize;
 	return 0;
 }
+#endif
+
+const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
+	.vidioc_querycap             = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap     = vidioc_enum_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap        = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap      = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap        = vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_vid_overlay    = vidioc_g_fmt_vid_overlay,
+	.vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
+	.vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
+	.vidioc_g_fmt_vbi_cap        = vidioc_g_fmt_vbi_cap,
+	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
+
+	.vidioc_overlay 	     = vidioc_overlay,
+	.vidioc_g_fbuf  	     = vidioc_g_fbuf,
+	.vidioc_s_fbuf  	     = vidioc_s_fbuf,
+	.vidioc_reqbufs              = vidioc_reqbufs,
+	.vidioc_querybuf             = vidioc_querybuf,
+	.vidioc_qbuf                 = vidioc_qbuf,
+	.vidioc_dqbuf                = vidioc_dqbuf,
+	.vidioc_g_std                = vidioc_g_std,
+	.vidioc_s_std                = vidioc_s_std,
+	.vidioc_queryctrl            = vidioc_queryctrl,
+	.vidioc_g_ctrl               = vidioc_g_ctrl,
+	.vidioc_s_ctrl               = vidioc_s_ctrl,
+	.vidioc_streamon             = vidioc_streamon,
+	.vidioc_streamoff            = vidioc_streamoff,
+	.vidioc_g_parm 		     = vidioc_g_parm,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf                 = vidiocgmbuf,
+#endif
+};
 
 /*********************************************************************************/
 /* buffer handling functions                                                  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/Kconfig linux-libre-2.6.30-gnu1/drivers/media/common/tuners/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -21,16 +21,17 @@ config MEDIA_TUNER
 	tristate
 	default VIDEO_MEDIA && I2C
 	depends on VIDEO_MEDIA && I2C
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
 
-menuconfig MEDIA_TUNER_CUSTOMIZE
+menuconfig MEDIA_TUNER_CUSTOMISE
 	bool "Customize analog and hybrid tuner modules to build"
 	depends on MEDIA_TUNER
 	default n
@@ -43,13 +44,13 @@ menuconfig MEDIA_TUNER_CUSTOMIZE
 
 	  If unsure say N.
 
-if MEDIA_TUNER_CUSTOMIZE
+if MEDIA_TUNER_CUSTOMISE
 
 config MEDIA_TUNER_SIMPLE
 	tristate "Simple tuner support"
 	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA9887
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for various simple tuners.
 
@@ -58,28 +59,28 @@ config MEDIA_TUNER_TDA8290
 	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA827X
 	select MEDIA_TUNER_TDA18271
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for Philips TDA8290+8275(a) tuner.
 
 config MEDIA_TUNER_TDA827X
 	tristate "Philips TDA827X silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A DVB-T silicon tuner module. Say Y when you want to support this tuner.
 
 config MEDIA_TUNER_TDA18271
 	tristate "NXP TDA18271 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A silicon tuner module. Say Y when you want to support this tuner.
 
 config MEDIA_TUNER_TDA9887
 	tristate "TDA 9885/6/7 analog IF demodulator"
 	depends on VIDEO_MEDIA && I2C
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for Philips TDA9885/6/7
 	  analog IF demodulator.
@@ -88,80 +89,87 @@ config MEDIA_TUNER_TEA5761
 	tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
 	depends on VIDEO_MEDIA && I2C
 	depends on EXPERIMENTAL
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for the Philips TEA5761 radio tuner.
 
 config MEDIA_TUNER_TEA5767
 	tristate "TEA 5767 radio tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for the Philips TEA5767 radio tuner.
 
 config MEDIA_TUNER_MT20XX
 	tristate "Microtune 2032 / 2050 tuners"
 	depends on VIDEO_MEDIA && I2C
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for the MT2032 / MT2050 tuner.
 
 config MEDIA_TUNER_MT2060
 	tristate "Microtune MT2060 silicon IF tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon IF tuner MT2060 from Microtune.
 
 config MEDIA_TUNER_MT2266
 	tristate "Microtune MT2266 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner MT2266 from Microtune.
 
 config MEDIA_TUNER_MT2131
 	tristate "Microtune MT2131 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner MT2131 from Microtune.
 
 config MEDIA_TUNER_QT1010
 	tristate "Quantek QT1010 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon tuner QT1010 from Quantek.
 
 config MEDIA_TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
 	depends on VIDEO_MEDIA && I2C
-	default m if MEDIA_TUNER_CUSTOMIZE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to include support for the xc2028/xc3028 tuners.
 
 config MEDIA_TUNER_XC5000
 	tristate "Xceive XC5000 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
-	  This device is only used inside a SiP called togther with a
+	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
 config MEDIA_TUNER_MXL5005S
 	tristate "MaxLinear MSL5005S silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon tuner MXL5005S from MaxLinear.
 
 config MEDIA_TUNER_MXL5007T
 	tristate "MaxLinear MxL5007T silicon tuner"
 	depends on VIDEO_MEDIA && I2C
-	default m if DVB_FE_CUSTOMISE
+	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon tuner MxL5007T from MaxLinear.
 
-endif # MEDIA_TUNER_CUSTOMIZE
+config MEDIA_TUNER_MC44S803
+	tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  Say Y here to support the Freescale MC44S803 based tuners
+
+endif # MEDIA_TUNER_CUSTOMISE
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/Makefile linux-libre-2.6.30-gnu1/drivers/media/common/tuners/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt10
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,371 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.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/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...)	\
+	printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+	u8 buf[3];
+	struct i2c_msg msg = {
+		.addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+	};
+
+	buf[0] = (val & 0xff0000) >> 16;
+	buf[1] = (val & 0xff00) >> 8;
+	buf[2] = (val & 0xff);
+
+	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+		mc_printk(KERN_WARNING, "I2C write failed\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+	u32 wval;
+	u8 buf[3];
+	int ret;
+	struct i2c_msg msg[] = {
+		{ .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+		  .buf = buf, .len = 3 },
+	};
+
+	wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+	       MC44S803_REG_SM(reg, MC44S803_D);
+
+	ret = mc44s803_writereg(priv, wval);
+	if (ret)
+		return ret;
+
+	if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+		mc_printk(KERN_WARNING, "I2C read failed\n");
+		return -EREMOTEIO;
+	}
+
+	*val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+	return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+	struct mc44s803_priv *priv = fe->tuner_priv;
+
+	fe->tuner_priv = NULL;
+	kfree(priv);
+
+	return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+	struct mc44s803_priv *priv = fe->tuner_priv;
+	u32 val;
+	int err;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+	val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_RS);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+/* Power Up and Start Osc */
+
+	val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+	      MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+	      MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+	      MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	msleep(10);
+
+	val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+	      MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+	      MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	msleep(20);
+
+/* Setup Mixer */
+
+	val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+	      MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+/* Setup Cirquit Adjust */
+
+	val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_G1) |
+	      MC44S803_REG_SM(1, MC44S803_G3) |
+	      MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+	      MC44S803_REG_SM(1, MC44S803_G6) |
+	      MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+	      MC44S803_REG_SM(0x3, MC44S803_LP) |
+	      MC44S803_REG_SM(1, MC44S803_CLRF) |
+	      MC44S803_REG_SM(1, MC44S803_CLIF);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_G1) |
+	      MC44S803_REG_SM(1, MC44S803_G3) |
+	      MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+	      MC44S803_REG_SM(1, MC44S803_G6) |
+	      MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+	      MC44S803_REG_SM(0x3, MC44S803_LP);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+/* Setup Digtune */
+
+	val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+	      MC44S803_REG_SM(3, MC44S803_XOD);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+/* Setup AGC */
+
+	val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_AT1) |
+	      MC44S803_REG_SM(1, MC44S803_AT2) |
+	      MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+	      MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+	      MC44S803_REG_SM(1, MC44S803_LNA0);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+	return 0;
+
+exit:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	mc_printk(KERN_WARNING, "I/O Error\n");
+	return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *params)
+{
+	struct mc44s803_priv *priv = fe->tuner_priv;
+	u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+	int err;
+
+	priv->frequency = params->frequency;
+
+	r1 = MC44S803_OSC / 1000000;
+	r2 = MC44S803_OSC /  100000;
+
+	n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000;
+	freq = MC44S803_OSC / r1 * n1;
+	lo1 = ((60 * n1) + (r1 / 2)) / r1;
+	freq = freq - params->frequency;
+
+	n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+	lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+	      MC44S803_REG_SM(r1-1, MC44S803_R1) |
+	      MC44S803_REG_SM(r2-1, MC44S803_R2) |
+	      MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+	      MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+	      MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+	      MC44S803_REG_SM(1, MC44S803_DA) |
+	      MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+	      MC44S803_REG_SM(1, MC44S803_AT);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+	      MC44S803_REG_SM(2, MC44S803_DA) |
+	      MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+	      MC44S803_REG_SM(1, MC44S803_AT);
+
+	err = mc44s803_writereg(priv, val);
+	if (err)
+		goto exit;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+
+exit:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	mc_printk(KERN_WARNING, "I/O Error\n");
+	return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct mc44s803_priv *priv = fe->tuner_priv;
+	*frequency = priv->frequency;
+	return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+	.info = {
+		.name           = "Freescale MC44S803",
+		.frequency_min  =   48000000,
+		.frequency_max  = 1000000000,
+		.frequency_step =     100000,
+	},
+
+	.release       = mc44s803_release,
+	.init          = mc44s803_init,
+	.set_params    = mc44s803_set_params,
+	.get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+   register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+	 struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+	struct mc44s803_priv *priv;
+	u32 reg;
+	u8 id;
+	int ret;
+
+	reg = 0;
+
+	priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return NULL;
+
+	priv->cfg = cfg;
+	priv->i2c = i2c;
+	priv->fe  = fe;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+	ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+	if (ret)
+		goto error;
+
+	id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+	if (id != 0x14) {
+		mc_printk(KERN_ERR, "unsupported ID "
+		       "(%x should be 0x14)\n", id);
+		goto error;
+	}
+
+	mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+	memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+	       sizeof(struct dvb_tuner_ops));
+
+	fe->tuner_priv = priv;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	return fe;
+
+error:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	kfree(priv);
+	return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803.h linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803.h
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,46 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.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.=
+ */
+
+#ifndef MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+	u8 i2c_address;
+	u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+    (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+	 struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+	 struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803_priv.h linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mc44s803_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mc44s803_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,208 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.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.=
+ */
+
+#ifndef MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+   http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+   SPI or I2C Address : 0xc0-0xc6
+
+   Reg.No | Function
+   -------------------------------------------
+       00 | Power Down
+       01 | Reference Oszillator
+       02 | Reference Dividers
+       03 | Mixer and Reference Buffer
+       04 | Reset/Serial Out
+       05 | LO 1
+       06 | LO 2
+       07 | Circuit Adjust
+       08 | Test
+       09 | Digital Tune
+       0A | LNA AGC
+       0B | Data Register Address
+       0C | Regulator Test
+       0D | VCO Test
+       0E | LNA Gain/Input Power
+       0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000	/* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000	/* 36.125 MHz */
+
+#define MC44S803_REG_POWER	0
+#define MC44S803_REG_REFOSC	1
+#define MC44S803_REG_REFDIV	2
+#define MC44S803_REG_MIXER	3
+#define MC44S803_REG_RESET	4
+#define MC44S803_REG_LO1	5
+#define MC44S803_REG_LO2	6
+#define MC44S803_REG_CIRCADJ	7
+#define MC44S803_REG_TEST	8
+#define MC44S803_REG_DIGTUNE	9
+#define MC44S803_REG_LNAAGC	0x0A
+#define MC44S803_REG_DATAREG	0x0B
+#define MC44S803_REG_REGTEST	0x0C
+#define MC44S803_REG_VCOTEST	0x0D
+#define MC44S803_REG_LNAGAIN	0x0E
+#define MC44S803_REG_ID		0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR		0x0F
+#define MC44S803_ADDR_S		0
+/* REG_POWER */
+#define MC44S803_POWER		0xFFFFF0
+#define MC44S803_POWER_S	4
+/* REG_REFOSC */
+#define MC44S803_REFOSC		0x1FF0
+#define MC44S803_REFOSC_S	4
+#define MC44S803_OSCSEL		0x2000
+#define MC44S803_OSCSEL_S	13
+/* REG_REFDIV */
+#define MC44S803_R2		0x1FF0
+#define MC44S803_R2_S		4
+#define MC44S803_REFBUF_EN	0x2000
+#define MC44S803_REFBUF_EN_S	13
+#define MC44S803_R1		0x7C000
+#define MC44S803_R1_S		14
+/* REG_MIXER */
+#define MC44S803_R3		0x70
+#define MC44S803_R3_S		4
+#define MC44S803_MUX3		0x80
+#define MC44S803_MUX3_S		7
+#define MC44S803_MUX4		0x100
+#define MC44S803_MUX4_S		8
+#define MC44S803_OSC_SCR	0x200
+#define MC44S803_OSC_SCR_S	9
+#define MC44S803_TRI_STATE	0x400
+#define MC44S803_TRI_STATE_S	10
+#define MC44S803_BUF_GAIN	0x800
+#define MC44S803_BUF_GAIN_S	11
+#define MC44S803_BUF_IO		0x1000
+#define MC44S803_BUF_IO_S	12
+#define MC44S803_MIXER_RES	0xFE000
+#define MC44S803_MIXER_RES_S	13
+/* REG_RESET */
+#define MC44S803_RS		0x10
+#define MC44S803_RS_S		4
+#define MC44S803_SO		0x20
+#define MC44S803_SO_S		5
+/* REG_LO1 */
+#define MC44S803_LO1		0xFFF0
+#define MC44S803_LO1_S		4
+/* REG_LO2 */
+#define MC44S803_LO2		0x7FFF0
+#define MC44S803_LO2_S		4
+/* REG_CIRCADJ */
+#define MC44S803_G1		0x20
+#define MC44S803_G1_S		5
+#define MC44S803_G3		0x80
+#define MC44S803_G3_S		7
+#define MC44S803_CIRCADJ_RES	0x300
+#define MC44S803_CIRCADJ_RES_S	8
+#define MC44S803_G6		0x400
+#define MC44S803_G6_S		10
+#define MC44S803_G7		0x800
+#define MC44S803_G7_S		11
+#define MC44S803_S1		0x1000
+#define MC44S803_S1_S		12
+#define MC44S803_LP		0x7E000
+#define MC44S803_LP_S		13
+#define MC44S803_CLRF		0x80000
+#define MC44S803_CLRF_S		19
+#define MC44S803_CLIF		0x100000
+#define MC44S803_CLIF_S		20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA		0xF0
+#define MC44S803_DA_S		4
+#define MC44S803_XOD		0x300
+#define MC44S803_XOD_S		8
+#define MC44S803_RST		0x10000
+#define MC44S803_RST_S		16
+#define MC44S803_LO_REF		0x1FFF00
+#define MC44S803_LO_REF_S	8
+#define MC44S803_AT		0x200000
+#define MC44S803_AT_S		21
+#define MC44S803_MT		0x400000
+#define MC44S803_MT_S		22
+/* REG_LNAAGC */
+#define MC44S803_G		0x3F0
+#define MC44S803_G_S		4
+#define MC44S803_AT1		0x400
+#define MC44S803_AT1_S		10
+#define MC44S803_AT2		0x800
+#define MC44S803_AT2_S		11
+#define MC44S803_HL_GR_EN	0x8000
+#define MC44S803_HL_GR_EN_S	15
+#define MC44S803_AGC_AN_DIG	0x10000
+#define MC44S803_AGC_AN_DIG_S	16
+#define MC44S803_ATTEN_EN	0x20000
+#define MC44S803_ATTEN_EN_S	17
+#define MC44S803_AGC_READ_EN	0x40000
+#define MC44S803_AGC_READ_EN_S	18
+#define MC44S803_LNA0		0x80000
+#define MC44S803_LNA0_S		19
+#define MC44S803_AGC_SEL	0x100000
+#define MC44S803_AGC_SEL_S	20
+#define MC44S803_AT0		0x200000
+#define MC44S803_AT0_S		21
+#define MC44S803_B		0xC00000
+#define MC44S803_B_S		22
+/* REG_DATAREG */
+#define MC44S803_D		0xF0
+#define MC44S803_D_S		4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR		0x700
+#define MC44S803_IF_PWR_S	8
+#define MC44S803_RF_PWR		0x3800
+#define MC44S803_RF_PWR_S	11
+#define MC44S803_LNA_GAIN	0xFC000
+#define MC44S803_LNA_GAIN_S	14
+/* REG_ID */
+#define MC44S803_ID		0x3E00
+#define MC44S803_ID_S		9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg)					\
+	(((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg)					\
+	(((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+	struct mc44s803_config *cfg;
+	struct i2c_adapter *i2c;
+	struct dvb_frontend *fe;
+
+	u32 frequency;
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mt2060.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mt2060.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mt2060.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mt2060.c	2009-06-09 23:05:27.000000000 -0400
@@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt20
 	while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
 		msleep(20);
 
-	if (i < 10) {
+	if (i <= 10) {
 		mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
 		dprintk("calibration was successful: %d", (int)priv->fmfreq);
 	} else
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mt20xx.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mt20xx.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mt20xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mt20xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include "tuner-i2c.h"
 #include "mt20xx.h"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mxl5005s.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mxl5005s.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mxl5005s.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mxl5005s.c	2009-06-09 23:05:27.000000000 -0400
@@ -4003,12 +4003,11 @@ static int mxl5005s_set_params(struct dv
 	/* Change tuner for new modulation type if reqd */
 	if (req_mode != state->current_mode) {
 		switch (req_mode) {
-		case VSB_8:
-		case QAM_64:
-		case QAM_256:
-		case QAM_AUTO:
+		case MXL_ATSC:
+		case MXL_QAM:
 			req_bw  = MXL5005S_BANDWIDTH_6MHZ;
 			break;
+		case MXL_DVBT:
 		default:
 			/* Assume DVB-T */
 			switch (params->u.ofdm.bandwidth) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mxl5007t.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mxl5007t.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/mxl5007t.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/mxl5007t.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
  *
- *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *  Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.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,22 +66,17 @@ MODULE_PARM_DESC(debug, "set debug level
 #define MHz 1000000
 
 enum mxl5007t_mode {
-	MxL_MODE_OTA_DVBT_ATSC        =    0,
-	MxL_MODE_OTA_NTSC_PAL_GH      =    1,
-	MxL_MODE_OTA_PAL_IB           =    2,
-	MxL_MODE_OTA_PAL_D_SECAM_KL   =    3,
-	MxL_MODE_OTA_ISDBT            =    4,
-	MxL_MODE_CABLE_DIGITAL        = 0x10,
-	MxL_MODE_CABLE_NTSC_PAL_GH    = 0x11,
-	MxL_MODE_CABLE_PAL_IB         = 0x12,
-	MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
-	MxL_MODE_CABLE_SCTE40         = 0x14,
+	MxL_MODE_ISDBT     =    0,
+	MxL_MODE_DVBT      =    1,
+	MxL_MODE_ATSC      =    2,
+	MxL_MODE_CABLE     = 0x10,
 };
 
 enum mxl5007t_chip_version {
 	MxL_UNKNOWN_ID     = 0x00,
 	MxL_5007_V1_F1     = 0x11,
 	MxL_5007_V1_F2     = 0x12,
+	MxL_5007_V4        = 0x14,
 	MxL_5007_V2_100_F1 = 0x21,
 	MxL_5007_V2_100_F2 = 0x22,
 	MxL_5007_V2_200_F1 = 0x23,
@@ -96,67 +91,61 @@ struct reg_pair_t {
 /* ------------------------------------------------------------------------- */
 
 static struct reg_pair_t init_tab[] = {
-	{ 0x0b, 0x44 }, /* XTAL */
-	{ 0x0c, 0x60 }, /* IF */
-	{ 0x10, 0x00 }, /* MISC */
-	{ 0x12, 0xca }, /* IDAC */
-	{ 0x16, 0x90 }, /* MODE */
-	{ 0x32, 0x38 }, /* MODE Analog/Digital */
-	{ 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
-	{ 0x2c, 0x34 }, /* OVERRIDE */
-	{ 0x4d, 0x40 }, /* OVERRIDE */
-	{ 0x7f, 0x02 }, /* OVERRIDE */
-	{ 0x9a, 0x52 }, /* OVERRIDE */
-	{ 0x48, 0x5a }, /* OVERRIDE */
-	{ 0x76, 0x1a }, /* OVERRIDE */
-	{ 0x6a, 0x48 }, /* OVERRIDE */
-	{ 0x64, 0x28 }, /* OVERRIDE */
-	{ 0x66, 0xe6 }, /* OVERRIDE */
-	{ 0x35, 0x0e }, /* OVERRIDE */
-	{ 0x7e, 0x01 }, /* OVERRIDE */
-	{ 0x83, 0x00 }, /* OVERRIDE */
-	{ 0x04, 0x0b }, /* OVERRIDE */
-	{ 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+	{ 0x02, 0x06 },
+	{ 0x03, 0x48 },
+	{ 0x05, 0x04 },
+	{ 0x06, 0x10 },
+	{ 0x2e, 0x15 }, /* OVERRIDE */
+	{ 0x30, 0x10 }, /* OVERRIDE */
+	{ 0x45, 0x58 }, /* OVERRIDE */
+	{ 0x48, 0x19 }, /* OVERRIDE */
+	{ 0x52, 0x03 }, /* OVERRIDE */
+	{ 0x53, 0x44 }, /* OVERRIDE */
+	{ 0x6a, 0x4b }, /* OVERRIDE */
+	{ 0x76, 0x00 }, /* OVERRIDE */
+	{ 0x78, 0x18 }, /* OVERRIDE */
+	{ 0x7a, 0x17 }, /* OVERRIDE */
+	{ 0x85, 0x06 }, /* OVERRIDE */
+	{ 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
 	{ 0, 0 }
 };
 
 static struct reg_pair_t init_tab_cable[] = {
-	{ 0x0b, 0x44 }, /* XTAL */
-	{ 0x0c, 0x60 }, /* IF */
-	{ 0x10, 0x00 }, /* MISC */
-	{ 0x12, 0xca }, /* IDAC */
-	{ 0x16, 0x90 }, /* MODE */
-	{ 0x32, 0x38 }, /* MODE A/D */
-	{ 0x71, 0x3f }, /* TOP1 */
-	{ 0x72, 0x3f }, /* TOP2 */
-	{ 0x74, 0x3f }, /* TOP3 */
-	{ 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
-	{ 0x2c, 0x34 }, /* OVERRIDE */
-	{ 0x4d, 0x40 }, /* OVERRIDE */
-	{ 0x7f, 0x02 }, /* OVERRIDE */
-	{ 0x9a, 0x52 }, /* OVERRIDE */
-	{ 0x48, 0x5a }, /* OVERRIDE */
-	{ 0x76, 0x1a }, /* OVERRIDE */
-	{ 0x6a, 0x48 }, /* OVERRIDE */
-	{ 0x64, 0x28 }, /* OVERRIDE */
-	{ 0x66, 0xe6 }, /* OVERRIDE */
-	{ 0x35, 0x0e }, /* OVERRIDE */
-	{ 0x7e, 0x01 }, /* OVERRIDE */
-	{ 0x04, 0x0b }, /* OVERRIDE */
-	{ 0x68, 0xb4 }, /* OVERRIDE */
-	{ 0x36, 0x00 }, /* OVERRIDE */
-	{ 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+	{ 0x02, 0x06 },
+	{ 0x03, 0x48 },
+	{ 0x05, 0x04 },
+	{ 0x06, 0x10 },
+	{ 0x09, 0x3f },
+	{ 0x0a, 0x3f },
+	{ 0x0b, 0x3f },
+	{ 0x2e, 0x15 }, /* OVERRIDE */
+	{ 0x30, 0x10 }, /* OVERRIDE */
+	{ 0x45, 0x58 }, /* OVERRIDE */
+	{ 0x48, 0x19 }, /* OVERRIDE */
+	{ 0x52, 0x03 }, /* OVERRIDE */
+	{ 0x53, 0x44 }, /* OVERRIDE */
+	{ 0x6a, 0x4b }, /* OVERRIDE */
+	{ 0x76, 0x00 }, /* OVERRIDE */
+	{ 0x78, 0x18 }, /* OVERRIDE */
+	{ 0x7a, 0x17 }, /* OVERRIDE */
+	{ 0x85, 0x06 }, /* OVERRIDE */
+	{ 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
 	{ 0, 0 }
 };
 
 /* ------------------------------------------------------------------------- */
 
 static struct reg_pair_t reg_pair_rftune[] = {
-	{ 0x11, 0x00 }, /* abort tune */
-	{ 0x13, 0x15 },
-	{ 0x14, 0x40 },
-	{ 0x15, 0x0e },
-	{ 0x11, 0x02 }, /* start tune */
+	{ 0x0f, 0x00 }, /* abort tune */
+	{ 0x0c, 0x15 },
+	{ 0x0d, 0x40 },
+	{ 0x0e, 0x0e },
+	{ 0x1f, 0x87 }, /* OVERRIDE */
+	{ 0x20, 0x1f }, /* OVERRIDE */
+	{ 0x21, 0x87 }, /* OVERRIDE */
+	{ 0x22, 0x1f }, /* OVERRIDE */
+	{ 0x80, 0x01 }, /* freq dependent */
+	{ 0x0f, 0x01 }, /* start tune */
 	{ 0, 0 }
 };
 
@@ -227,63 +216,20 @@ static void mxl5007t_set_mode_bits(struc
 				   s32 if_diff_out_level)
 {
 	switch (mode) {
-	case MxL_MODE_OTA_DVBT_ATSC:
-		set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
-		set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
-		break;
-	case MxL_MODE_OTA_ISDBT:
-		set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
-		set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
-		break;
-	case MxL_MODE_OTA_NTSC_PAL_GH:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		break;
-	case MxL_MODE_OTA_PAL_IB:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		break;
-	case MxL_MODE_OTA_PAL_D_SECAM_KL:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		break;
-	case MxL_MODE_CABLE_DIGITAL:
-		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
-		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
-			     8 - if_diff_out_level);
-		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
-		break;
-	case MxL_MODE_CABLE_NTSC_PAL_GH:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
-		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
-			     8 - if_diff_out_level);
-		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+	case MxL_MODE_ATSC:
+		set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
 		break;
-	case MxL_MODE_CABLE_PAL_IB:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
-		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
-			     8 - if_diff_out_level);
-		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+	case MxL_MODE_DVBT:
+		set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
 		break;
-	case MxL_MODE_CABLE_PAL_D_SECAM_KL:
-		set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
-		set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
-		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
-		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
-			     8 - if_diff_out_level);
-		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+	case MxL_MODE_ISDBT:
+		set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
 		break;
-	case MxL_MODE_CABLE_SCTE40:
-		set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
-		set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
-		set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
-		set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+	case MxL_MODE_CABLE:
+		set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
+		set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
 			     8 - if_diff_out_level);
-		set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+		set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
 		break;
 	default:
 		mxl_fail(-EINVAL);
@@ -302,43 +248,43 @@ static void mxl5007t_set_if_freq_bits(st
 		val = 0x00;
 		break;
 	case MxL_IF_4_5_MHZ:
-		val = 0x20;
+		val = 0x02;
 		break;
 	case MxL_IF_4_57_MHZ:
-		val = 0x30;
+		val = 0x03;
 		break;
 	case MxL_IF_5_MHZ:
-		val = 0x40;
+		val = 0x04;
 		break;
 	case MxL_IF_5_38_MHZ:
-		val = 0x50;
+		val = 0x05;
 		break;
 	case MxL_IF_6_MHZ:
-		val = 0x60;
+		val = 0x06;
 		break;
 	case MxL_IF_6_28_MHZ:
-		val = 0x70;
+		val = 0x07;
 		break;
 	case MxL_IF_9_1915_MHZ:
-		val = 0x80;
+		val = 0x08;
 		break;
 	case MxL_IF_35_25_MHZ:
-		val = 0x90;
+		val = 0x09;
 		break;
 	case MxL_IF_36_15_MHZ:
-		val = 0xa0;
+		val = 0x0a;
 		break;
 	case MxL_IF_44_MHZ:
-		val = 0xb0;
+		val = 0x0b;
 		break;
 	default:
 		mxl_fail(-EINVAL);
 		return;
 	}
-	set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+	set_reg_bits(state->tab_init, 0x02, 0x0f, val);
 
 	/* set inverted IF or normal IF */
-	set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+	set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
 
 	return;
 }
@@ -346,56 +292,68 @@ static void mxl5007t_set_if_freq_bits(st
 static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
 					enum mxl5007t_xtal_freq xtal_freq)
 {
-	u8 val;
-
 	switch (xtal_freq) {
 	case MxL_XTAL_16_MHZ:
-		val = 0x00; /* select xtal freq & Ref Freq */
+		/* select xtal freq & ref freq */
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
 		break;
 	case MxL_XTAL_20_MHZ:
-		val = 0x11;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
 		break;
 	case MxL_XTAL_20_25_MHZ:
-		val = 0x22;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
 		break;
 	case MxL_XTAL_20_48_MHZ:
-		val = 0x33;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
 		break;
 	case MxL_XTAL_24_MHZ:
-		val = 0x44;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
 		break;
 	case MxL_XTAL_25_MHZ:
-		val = 0x55;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
 		break;
 	case MxL_XTAL_25_14_MHZ:
-		val = 0x66;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
 		break;
 	case MxL_XTAL_27_MHZ:
-		val = 0x77;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
 		break;
 	case MxL_XTAL_28_8_MHZ:
-		val = 0x88;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
 		break;
 	case MxL_XTAL_32_MHZ:
-		val = 0x99;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
 		break;
 	case MxL_XTAL_40_MHZ:
-		val = 0xaa;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
 		break;
 	case MxL_XTAL_44_MHZ:
-		val = 0xbb;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
 		break;
 	case MxL_XTAL_48_MHZ:
-		val = 0xcc;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
 		break;
 	case MxL_XTAL_49_3811_MHZ:
-		val = 0xdd;
+		set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
+		set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
 		break;
 	default:
 		mxl_fail(-EINVAL);
 		return;
 	}
-	set_reg_bits(state->tab_init, 0x0b, 0xff, val);
 
 	return;
 }
@@ -412,16 +370,11 @@ static struct reg_pair_t *mxl5007t_calc_
 	mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
 	mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
 
-	set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
-
-	set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
-
-	set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
-
-	/* set IDAC to automatic mode control by AGC */
-	set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
+	set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
+	set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
+	set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
 
-	if (mode >= MxL_MODE_CABLE_DIGITAL) {
+	if (mode >= MxL_MODE_CABLE) {
 		copy_reg_bits(state->tab_init, state->tab_init_cable);
 		return state->tab_init_cable;
 	} else
@@ -447,7 +400,7 @@ static void mxl5007t_set_bw_bits(struct
 			     * and DIG_MODEINDEX_CSF */
 		break;
 	case MxL_BW_7MHz:
-		val = 0x21;
+		val = 0x2a;
 		break;
 	case MxL_BW_8MHz:
 		val = 0x3f;
@@ -456,7 +409,7 @@ static void mxl5007t_set_bw_bits(struct
 		mxl_fail(-EINVAL);
 		return;
 	}
-	set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+	set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
 
 	return;
 }
@@ -493,8 +446,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(s
 	if (temp > 7812)
 		dig_rf_freq++;
 
-	set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
-	set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+	set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
+	set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
+
+	if (rf_freq >= 333000000)
+		set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
 
 	return state->tab_rftune;
 }
@@ -551,9 +507,10 @@ static int mxl5007t_read_reg(struct mxl5
 static int mxl5007t_soft_reset(struct mxl5007t_state *state)
 {
 	u8 d = 0xff;
-	struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
-			       .buf = &d, .len = 1 };
-
+	struct i2c_msg msg = {
+		.addr = state->i2c_props.addr, .flags = 0,
+		.buf = &d, .len = 1
+	};
 	int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
 
 	if (ret != 1) {
@@ -580,9 +537,6 @@ static int mxl5007t_tuner_init(struct mx
 	if (mxl_fail(ret))
 		goto fail;
 	mdelay(1);
-
-	ret = mxl5007t_write_reg(state, 0x2c, 0x35);
-	mxl_fail(ret);
 fail:
 	return ret;
 }
@@ -615,7 +569,7 @@ static int mxl5007t_synth_lock_status(st
 	*rf_locked = 0;
 	*ref_locked = 0;
 
-	ret = mxl5007t_read_reg(state, 0xcf, &d);
+	ret = mxl5007t_read_reg(state, 0xd8, &d);
 	if (mxl_fail(ret))
 		goto fail;
 
@@ -628,37 +582,14 @@ fail:
 	return ret;
 }
 
-static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
-					 s32 *rf_input_level)
-{
-	u8 d1, d2;
-	int ret;
-
-	ret = mxl5007t_read_reg(state, 0xb7, &d1);
-	if (mxl_fail(ret))
-		goto fail;
-
-	ret = mxl5007t_read_reg(state, 0xbf, &d2);
-	if (mxl_fail(ret))
-		goto fail;
-
-	d2 = d2 >> 4;
-	if (d2 > 7)
-		d2 += 0xf0;
-
-	*rf_input_level = (s32)(d1 + d2 - 113);
-fail:
-	return ret;
-}
-
 /* ------------------------------------------------------------------------- */
 
 static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
-	int rf_locked, ref_locked;
-	s32 rf_input_level = 0;
-	int ret;
+	int rf_locked, ref_locked, ret;
+
+	*status = 0;
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
@@ -669,10 +600,8 @@ static int mxl5007t_get_status(struct dv
 	mxl_debug("%s%s", rf_locked ? "rf locked " : "",
 		  ref_locked ? "ref locked" : "");
 
-	ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
-	if (mxl_fail(ret))
-		goto fail;
-	mxl_debug("rf input power: %d", rf_input_level);
+	if ((rf_locked) || (ref_locked))
+		*status |= TUNER_STATUS_LOCKED;
 fail:
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
@@ -695,11 +624,11 @@ static int mxl5007t_set_params(struct dv
 		switch (params->u.vsb.modulation) {
 		case VSB_8:
 		case VSB_16:
-			mode = MxL_MODE_OTA_DVBT_ATSC;
+			mode = MxL_MODE_ATSC;
 			break;
 		case QAM_64:
 		case QAM_256:
-			mode = MxL_MODE_CABLE_DIGITAL;
+			mode = MxL_MODE_CABLE;
 			break;
 		default:
 			mxl_err("modulation not set!");
@@ -721,7 +650,7 @@ static int mxl5007t_set_params(struct dv
 			mxl_err("bandwidth not set!");
 			return -EINVAL;
 		}
-		mode = MxL_MODE_OTA_DVBT_ATSC;
+		mode = MxL_MODE_DVBT;
 	} else {
 		mxl_err("modulation type not supported!");
 		return -EINVAL;
@@ -752,96 +681,20 @@ fail:
 	return ret;
 }
 
-static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
-				      struct analog_parameters *params)
-{
-	struct mxl5007t_state *state = fe->tuner_priv;
-	enum mxl5007t_bw_mhz bw = 0; /* FIXME */
-	enum mxl5007t_mode cbl_mode;
-	enum mxl5007t_mode ota_mode;
-	char *mode_name;
-	int ret;
-	u32 freq = params->frequency * 62500;
-
-#define cable 1
-	if (params->std & V4L2_STD_MN) {
-		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
-		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
-		mode_name = "MN";
-	} else if (params->std & V4L2_STD_B) {
-		cbl_mode = MxL_MODE_CABLE_PAL_IB;
-		ota_mode = MxL_MODE_OTA_PAL_IB;
-		mode_name = "B";
-	} else if (params->std & V4L2_STD_GH) {
-		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
-		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
-		mode_name = "GH";
-	} else if (params->std & V4L2_STD_PAL_I) {
-		cbl_mode = MxL_MODE_CABLE_PAL_IB;
-		ota_mode = MxL_MODE_OTA_PAL_IB;
-		mode_name = "I";
-	} else if (params->std & V4L2_STD_DK) {
-		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
-		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
-		mode_name = "DK";
-	} else if (params->std & V4L2_STD_SECAM_L) {
-		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
-		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
-		mode_name = "L";
-	} else if (params->std & V4L2_STD_SECAM_LC) {
-		cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
-		ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
-		mode_name = "L'";
-	} else {
-		mode_name = "xx";
-		/* FIXME */
-		cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
-		ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
-	}
-	mxl_debug("setting mxl5007 to system %s", mode_name);
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-
-	mutex_lock(&state->lock);
-
-	ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
-	if (mxl_fail(ret))
-		goto fail;
-
-	ret = mxl5007t_tuner_rf_tune(state, freq, bw);
-	if (mxl_fail(ret))
-		goto fail;
-
-	state->frequency = freq;
-	state->bandwidth = 0;
-fail:
-	mutex_unlock(&state->lock);
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
-
-	return ret;
-}
-
 /* ------------------------------------------------------------------------- */
 
 static int mxl5007t_init(struct dvb_frontend *fe)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
 	int ret;
-	u8 d;
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
-	ret = mxl5007t_read_reg(state, 0x05, &d);
-	if (mxl_fail(ret))
-		goto fail;
-
-	ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+	/* wake from standby */
+	ret = mxl5007t_write_reg(state, 0x01, 0x01);
 	mxl_fail(ret);
-fail:
+
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
@@ -852,18 +705,16 @@ static int mxl5007t_sleep(struct dvb_fro
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
 	int ret;
-	u8 d;
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
-	ret = mxl5007t_read_reg(state, 0x05, &d);
-	if (mxl_fail(ret))
-		goto fail;
-
-	ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+	/* enter standby mode */
+	ret = mxl5007t_write_reg(state, 0x01, 0x00);
 	mxl_fail(ret);
-fail:
+	ret = mxl5007t_write_reg(state, 0x0f, 0x00);
+	mxl_fail(ret);
+
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
@@ -911,7 +762,6 @@ static struct dvb_tuner_ops mxl5007t_tun
 	.init              = mxl5007t_init,
 	.sleep             = mxl5007t_sleep,
 	.set_params        = mxl5007t_set_params,
-	.set_analog_params = mxl5007t_set_analog_params,
 	.get_status        = mxl5007t_get_status,
 	.get_frequency     = mxl5007t_get_frequency,
 	.get_bandwidth     = mxl5007t_get_bandwidth,
@@ -924,7 +774,7 @@ static int mxl5007t_get_chip_id(struct m
 	int ret;
 	u8 id;
 
-	ret = mxl5007t_read_reg(state, 0xd3, &id);
+	ret = mxl5007t_read_reg(state, 0xd9, &id);
 	if (mxl_fail(ret))
 		goto fail;
 
@@ -947,8 +797,12 @@ static int mxl5007t_get_chip_id(struct m
 	case MxL_5007_V2_200_F2:
 		name = "MxL5007.v2.200.f2";
 		break;
+	case MxL_5007_V4:
+		name = "MxL5007T.v4";
+		break;
 	default:
 		name = "MxL5007T";
+		printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
 		id = MxL_UNKNOWN_ID;
 	}
 	state->chip_id = id;
@@ -975,7 +829,7 @@ struct dvb_frontend *mxl5007t_attach(str
 	mutex_lock(&mxl5007t_list_mutex);
 	instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
 					      hybrid_tuner_instance_list,
-					      i2c, addr, "mxl5007");
+					      i2c, addr, "mxl5007t");
 	switch (instance) {
 	case 0:
 		goto fail;
@@ -1018,7 +872,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach);
 MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-common.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-common.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-common.c	2009-06-09 23:05:27.000000000 -0400
@@ -490,9 +490,9 @@ int tda18271_set_standby_mode(struct dvb
 		tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
 
 	regs[R_EP3]  &= ~0xe0; /* clear sm, sm_lt, sm_xt */
-	regs[R_EP3]  |= sm    ? (1 << 7) : 0 |
-			sm_lt ? (1 << 6) : 0 |
-			sm_xt ? (1 << 5) : 0;
+	regs[R_EP3]  |= (sm    ? (1 << 7) : 0) |
+			(sm_lt ? (1 << 6) : 0) |
+			(sm_xt ? (1 << 5) : 0);
 
 	return tda18271_write_regs(fe, R_EP3, 1);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-fe.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-fe.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-fe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-fe.c	2009-06-09 23:05:27.000000000 -0400
@@ -818,6 +818,38 @@ fail:
 	return ret;
 }
 
+/* ------------------------------------------------------------------ */
+
+static int tda18271_agc(struct dvb_frontend *fe)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret = 0;
+
+	switch (priv->config) {
+	case 0:
+		/* no LNA */
+		tda_dbg("no agc configuration provided\n");
+		break;
+	case 3:
+		/* switch with GPIO of saa713x */
+		tda_dbg("invoking callback\n");
+		if (fe->callback)
+			ret = fe->callback(priv->i2c_props.adap->algo_data,
+					   DVB_FRONTEND_COMPONENT_TUNER,
+					   TDA18271_CALLBACK_CMD_AGC_ENABLE,
+					   priv->mode);
+		break;
+	case 1:
+	case 2:
+	default:
+		/* n/a - currently not supported */
+		tda_err("unsupported configuration: %d\n", priv->config);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 static int tda18271_tune(struct dvb_frontend *fe,
 			 struct tda18271_std_map_item *map, u32 freq, u32 bw)
 {
@@ -827,6 +859,10 @@ static int tda18271_tune(struct dvb_fron
 	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
 		freq, map->if_freq, bw, map->agc_mode, map->std);
 
+	ret = tda18271_agc(fe);
+	if (tda_fail(ret))
+		tda_warn("failed to configure agc\n");
+
 	ret = tda18271_init(fe);
 	if (tda_fail(ret))
 		goto fail;
@@ -1159,6 +1195,7 @@ struct dvb_frontend *tda18271_attach(str
 		/* new tuner instance */
 		priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
 		priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+		priv->config = (cfg) ? cfg->config : 0;
 		priv->cal_initialized = false;
 		mutex_init(&priv->lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271.h linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271.h
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271.h	2009-06-09 23:05:27.000000000 -0400
@@ -79,6 +79,16 @@ struct tda18271_config {
 
 	/* some i2c providers cant write all 39 registers at once */
 	unsigned int small_i2c:1;
+
+	/* interface to saa713x / tda829x */
+	unsigned int config;
+};
+
+#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
+
+enum tda18271_mode {
+	TDA18271_ANALOG = 0,
+	TDA18271_DIGITAL,
 };
 
 #if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-priv.h linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda18271-priv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda18271-priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -91,11 +91,6 @@ enum tda18271_pll {
 	TDA18271_CAL_PLL,
 };
 
-enum tda18271_mode {
-	TDA18271_ANALOG,
-	TDA18271_DIGITAL,
-};
-
 struct tda18271_map_layout;
 
 enum tda18271_ver {
@@ -114,6 +109,7 @@ struct tda18271_priv {
 	enum tda18271_i2c_gate gate;
 	enum tda18271_ver id;
 
+	unsigned int config; /* interface to saa713x / tda829x */
 	unsigned int tm_rfcal;
 	unsigned int cal_initialized:1;
 	unsigned int small_i2c:1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda827x.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda827x.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda827x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda827x.c	2009-06-09 23:05:27.000000000 -0400
@@ -132,11 +132,31 @@ static const struct tda827x_data tda827x
 	{ .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
 };
 
+static int tuner_transfer(struct dvb_frontend *fe,
+			  struct i2c_msg *msg,
+			  const int size)
+{
+	int rc;
+	struct tda827x_priv *priv = fe->tuner_priv;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	rc = i2c_transfer(priv->i2c_adap, msg, size);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	if (rc >= 0 && rc != size)
+		return -EIO;
+
+	return rc;
+}
+
 static int tda827xo_set_params(struct dvb_frontend *fe,
 			       struct dvb_frontend_parameters *params)
 {
 	struct tda827x_priv *priv = fe->tuner_priv;
 	u8 buf[14];
+	int rc;
 
 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 			       .buf = buf, .len = sizeof(buf) };
@@ -183,27 +203,29 @@ static int tda827xo_set_params(struct dv
 	buf[13] = 0x40;
 
 	msg.len = 14;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
-		printk("%s: could not write to tuner at addr: 0x%02x\n",
-		       __func__, priv->i2c_addr << 1);
-		return -EIO;
-	}
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
+
 	msleep(500);
 	/* correct CP value */
 	buf[0] = 0x30;
 	buf[1] = 0x50 + tda827x_table[i].cp;
 	msg.len = 2;
 
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	priv->frequency = params->frequency;
 	priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
 
 	return 0;
+
+err:
+	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+	       __func__, priv->i2c_addr << 1);
+	return rc;
 }
 
 static int tda827xo_sleep(struct dvb_frontend *fe)
@@ -214,9 +236,7 @@ static int tda827xo_sleep(struct dvb_fro
 			       .buf = buf, .len = sizeof(buf) };
 
 	dprintk("%s:\n", __func__);
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	if (priv->cfg && priv->cfg->sleep)
 		priv->cfg->sleep(fe);
@@ -266,44 +286,44 @@ static int tda827xo_set_analog_params(st
 
 	msg.buf = tuner_reg;
 	msg.len = 8;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msg.buf = reg2;
 	msg.len = 2;
 	reg2[0] = 0x80;
 	reg2[1] = 0;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	reg2[0] = 0x60;
 	reg2[1] = 0xbf;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	reg2[0] = 0x30;
 	reg2[1] = tuner_reg[4] + 0x80;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msleep(1);
 	reg2[0] = 0x30;
 	reg2[1] = tuner_reg[4] + 4;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msleep(1);
 	reg2[0] = 0x30;
 	reg2[1] = tuner_reg[4];
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msleep(550);
 	reg2[0] = 0x30;
 	reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	reg2[0] = 0x60;
 	reg2[1] = 0x3f;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	reg2[0] = 0x80;
 	reg2[1] = 0x08;   /* Vsync en */
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	priv->frequency = params->frequency;
 
@@ -317,7 +337,7 @@ static void tda827xo_agcf(struct dvb_fro
 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 			       .buf = data, .len = 2};
 
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 }
 
 /* ------------------------------------------------------------------ */
@@ -331,7 +351,7 @@ struct tda827xa_data {
 	u8  gc3;
 };
 
-static const struct tda827xa_data tda827xa_dvbt[] = {
+static struct tda827xa_data tda827xa_dvbt[] = {
 	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
 	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
 	{ .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
@@ -361,6 +381,36 @@ static const struct tda827xa_data tda827
 	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
 };
 
+static struct tda827xa_data tda827xa_dvbc[] = {
+	{ .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+	{ .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+	{ .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+	{ .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+	{ .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+	{ .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+	{ .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+	{ .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+	{ .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+	{ .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+	{ .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
+	{ .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
+	{ .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
+	{ .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
+	{ .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+	{ .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+	{ .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
+	{ .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+	{ .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
+	{ .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+	{ .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+	{ .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+	{ .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+	{ .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+	{ .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+	{ .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+	{ .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
 static struct tda827xa_data tda827xa_analog[] = {
 	{ .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
 	{ .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
@@ -398,13 +448,8 @@ static int tda827xa_sleep(struct dvb_fro
 			       .buf = buf, .len = sizeof(buf) };
 
 	dprintk("%s:\n", __func__);
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-
-	i2c_transfer(priv->i2c_adap, &msg, 1);
 
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
+	tuner_transfer(fe, &msg, 1);
 
 	if (priv->cfg && priv->cfg->sleep)
 		priv->cfg->sleep(fe);
@@ -455,7 +500,7 @@ static void tda827xa_lna_gain(struct dvb
 		buf[1] = high ? 0 : 1;
 		if (priv->cfg->config == 2)
 			buf[1] = high ? 1 : 0;
-		i2c_transfer(priv->i2c_adap, &msg, 1);
+		tuner_transfer(fe, &msg, 1);
 		break;
 	case 3: /* switch with GPIO of saa713x */
 		if (fe->callback)
@@ -469,12 +514,13 @@ static int tda827xa_set_params(struct dv
 			       struct dvb_frontend_parameters *params)
 {
 	struct tda827x_priv *priv = fe->tuner_priv;
+	struct tda827xa_data *frequency_map = tda827xa_dvbt;
 	u8 buf[11];
 
 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
 			       .buf = buf, .len = sizeof(buf) };
 
-	int i, tuner_freq, if_freq;
+	int i, tuner_freq, if_freq, rc;
 	u32 N;
 
 	dprintk("%s:\n", __func__);
@@ -495,56 +541,58 @@ static int tda827xa_set_params(struct dv
 	}
 	tuner_freq = params->frequency + if_freq;
 
+	if (fe->ops.info.type == FE_QAM) {
+		dprintk("%s select tda827xa_dvbc\n", __func__);
+		frequency_map = tda827xa_dvbc;
+	}
+
 	i = 0;
-	while (tda827xa_dvbt[i].lomax < tuner_freq) {
-		if(tda827xa_dvbt[i + 1].lomax == 0)
+	while (frequency_map[i].lomax < tuner_freq) {
+		if (frequency_map[i + 1].lomax == 0)
 			break;
 		i++;
 	}
 
-	N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
+	N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
 	buf[0] = 0;            // subaddress
 	buf[1] = N >> 8;
 	buf[2] = N & 0xff;
 	buf[3] = 0;
 	buf[4] = 0x16;
-	buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
-			tda827xa_dvbt[i].sbs;
-	buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
+	buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
+			frequency_map[i].sbs;
+	buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
 	buf[7] = 0x1c;
 	buf[8] = 0x06;
 	buf[9] = 0x24;
 	buf[10] = 0x00;
 	msg.len = 11;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
-		printk("%s: could not write to tuner at addr: 0x%02x\n",
-		       __func__, priv->i2c_addr << 1);
-		return -EIO;
-	}
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
+
 	buf[0] = 0x90;
 	buf[1] = 0xff;
 	buf[2] = 0x60;
 	buf[3] = 0x00;
 	buf[4] = 0x59;  // lpsel, for 6MHz + 2
 	msg.len = 5;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	buf[0] = 0xa0;
 	buf[1] = 0x40;
 	msg.len = 2;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	msleep(11);
 	msg.flags = I2C_M_RD;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 	msg.flags = 0;
 
 	buf[1] >>= 4;
@@ -553,49 +601,55 @@ static int tda827xa_set_params(struct dv
 		tda827xa_lna_gain(fe, 0, NULL);
 		buf[0] = 0x60;
 		buf[1] = 0x0c;
-		if (fe->ops.i2c_gate_ctrl)
-			fe->ops.i2c_gate_ctrl(fe, 1);
-		i2c_transfer(priv->i2c_adap, &msg, 1);
+		rc = tuner_transfer(fe, &msg, 1);
+		if (rc < 0)
+			goto err;
 	}
 
 	buf[0] = 0xc0;
 	buf[1] = 0x99;    // lpsel, for 6MHz + 2
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	buf[0] = 0x60;
 	buf[1] = 0x3c;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	/* correct CP value */
 	buf[0] = 0x30;
-	buf[1] = 0x10 + tda827xa_dvbt[i].scr;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	buf[1] = 0x10 + frequency_map[i].scr;
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	msleep(163);
 	buf[0] = 0xc0;
 	buf[1] = 0x39;  // lpsel, for 6MHz + 2
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	msleep(3);
 	/* freeze AGC1 */
 	buf[0] = 0x50;
-	buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
+	rc = tuner_transfer(fe, &msg, 1);
+	if (rc < 0)
+		goto err;
 
 	priv->frequency = params->frequency;
 	priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
 
+
 	return 0;
+
+err:
+	printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+	       __func__, priv->i2c_addr << 1);
+	return rc;
 }
 
 
@@ -643,7 +697,7 @@ static int tda827xa_set_analog_params(st
 	tuner_reg[9] = 0x20;
 	tuner_reg[10] = 0x00;
 	msg.len = 11;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0x90;
 	tuner_reg[1] = 0xff;
@@ -651,19 +705,19 @@ static int tda827xa_set_analog_params(st
 	tuner_reg[3] = 0;
 	tuner_reg[4] = 0x99 + (priv->lpsel << 1);
 	msg.len = 5;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0xa0;
 	tuner_reg[1] = 0xc0;
 	msg.len = 2;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0x30;
 	tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msg.flags = I2C_M_RD;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 	msg.flags = 0;
 	tuner_reg[1] >>= 4;
 	dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
@@ -673,24 +727,24 @@ static int tda827xa_set_analog_params(st
 	msleep(100);
 	tuner_reg[0] = 0x60;
 	tuner_reg[1] = 0x3c;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	msleep(163);
 	tuner_reg[0] = 0x50;
 	tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0x80;
 	tuner_reg[1] = 0x28;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0xb0;
 	tuner_reg[1] = 0x01;
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	tuner_reg[0] = 0xc0;
 	tuner_reg[1] = 0x19 + (priv->lpsel << 1);
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 
 	priv->frequency = params->frequency;
 
@@ -703,7 +757,7 @@ static void tda827xa_agcf(struct dvb_fro
 	unsigned char data[] = {0x80, 0x2c};
 	struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
 			      .buf = data, .len = 2};
-	i2c_transfer(priv->i2c_adap, &msg, 1);
+	tuner_transfer(fe, &msg, 1);
 }
 
 /* ------------------------------------------------------------------ */
@@ -792,16 +846,19 @@ static struct dvb_tuner_ops tda827xa_tun
 };
 
 static int tda827x_probe_version(struct dvb_frontend *fe)
-{	u8 data;
+{
+	u8 data;
+	int rc;
 	struct tda827x_priv *priv = fe->tuner_priv;
 	struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
 			       .buf = &data, .len = 1 };
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
+
+	rc = tuner_transfer(fe, &msg, 1);
+
+	if (rc < 0) {
 		printk("%s: could not read from tuner at addr: 0x%02x\n",
 		       __func__, msg.addr << 1);
-		return -EIO;
+		return rc;
 	}
 	if ((data & 0x3c) == 0) {
 		dprintk("tda827x tuner found\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda8290.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda8290.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tda8290.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tda8290.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
 
 #include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include "tuner-i2c.h"
 #include "tda8290.h"
 #include "tda827x.h"
@@ -566,8 +566,11 @@ static int tda829x_find_tuner(struct dvb
 	u8 data;
 	struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
 
-	if (NULL == analog_ops->i2c_gate_ctrl)
+	if (!analog_ops->i2c_gate_ctrl) {
+		printk(KERN_ERR "tda8290: no gate control were provided!\n");
+
 		return -EINVAL;
+	}
 
 	analog_ops->i2c_gate_ctrl(fe, 1);
 
@@ -615,11 +618,13 @@ static int tda829x_find_tuner(struct dvb
 
 	if (ret != 1) {
 		tuner_warn("tuner access failed!\n");
+		analog_ops->i2c_gate_ctrl(fe, 0);
 		return -EREMOTEIO;
 	}
 
 	if ((data == 0x83) || (data == 0x84)) {
 		priv->ver |= TDA18271;
+		tda829x_tda18271_config.config = priv->cfg.config;
 		dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
 			   priv->i2c_props.adap, &tda829x_tda18271_config);
 	} else {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tea5761.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tea5761.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tea5761.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tea5761.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@
 
 #include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/tuner.h>
 #include "tuner-i2c.h"
 #include "tea5761.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tea5767.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tea5767.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/tea5767.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/tea5767.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,7 @@
 
 #include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include "tuner-i2c.h"
 #include "tea5767.h"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/common/tuners/xc5000.c linux-libre-2.6.30-gnu1/drivers/media/common/tuners/xc5000.c
--- linux-libre-2.6.29-gnu1/drivers/media/common/tuners/xc5000.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/common/tuners/xc5000.c	2013-05-03 16:44:18.000000000 -0400
@@ -739,7 +739,10 @@ static int xc5000_set_analog_params(stru
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
 
-	priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
+	/* Fix me: it could be air. */
+	priv->rf_mode = params->mode;
+	if (params->mode > XC_RF_MODE_CABLE)
+		priv->rf_mode = XC_RF_MODE_CABLE;
 
 	/* params->frequency is in units of 62.5khz */
 	priv->freq_hz = params->frequency * 62500;
@@ -970,8 +973,6 @@ struct dvb_frontend *xc5000_attach(struc
 	case 1:
 		/* new tuner instance */
 		priv->bandwidth = BANDWIDTH_6_MHZ;
-		priv->if_khz = cfg->if_khz;
-
 		fe->tuner_priv = priv;
 		break;
 	default:
@@ -980,6 +981,13 @@ struct dvb_frontend *xc5000_attach(struc
 		break;
 	}
 
+	if (priv->if_khz == 0) {
+		/* If the IF hasn't been set yet, use the value provided by
+		   the caller (occurs in hybrid devices where the analog
+		   call to xc5000_attach occurs before the digital side) */
+		priv->if_khz = cfg->if_khz;
+	}
+
 	/* 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.29-gnu1/drivers/media/dvb/b2c2/flexcop.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,22 +1,20 @@
 /*
- * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * based on the skystar2-driver
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
  *
  * Acknowledgements:
- *     John Jurrius from BBTI, Inc. for extensive support with
- *         code examples and data books
- *
- *     Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ *   John Jurrius from BBTI, Inc. for extensive support
+ *                    with code examples and data books
+ *   Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
  *
  * Contributions to the skystar2-driver have been done by
- *     Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
- *     Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
- *     Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering)
- *
+ *   Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ *   Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ *   Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ *   Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
+ *               filtering)
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -46,7 +44,10 @@
 
 int b2c2_flexcop_debug;
 module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug,
+		"set debug level (1=info,2=tuner,4=i2c,8=ts,"
+		"16=sram,32=reg (|-able))."
+		DEBSTATUS);
 #undef DEBSTATUS
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -57,37 +58,36 @@ flexcop_ibi_value ibi_zero;
 static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
 {
 	struct flexcop_device *fc = dvbdmxfeed->demux->priv;
-	return flexcop_pid_feed_control(fc,dvbdmxfeed,1);
+	return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
 }
 
 static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
 {
 	struct flexcop_device *fc = dvbdmxfeed->demux->priv;
-	return flexcop_pid_feed_control(fc,dvbdmxfeed,0);
+	return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
 }
 
 static int flexcop_dvb_init(struct flexcop_device *fc)
 {
 	int ret = dvb_register_adapter(&fc->dvb_adapter,
-				       "FlexCop Digital TV device", fc->owner,
-				       fc->dev, adapter_nr);
+			"FlexCop Digital TV device", fc->owner,
+			fc->dev, adapter_nr);
 	if (ret < 0) {
 		err("error registering DVB adapter");
 		return ret;
 	}
 	fc->dvb_adapter.priv = fc;
 
-	fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+	fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
+			| DMX_MEMORY_BASED_FILTERING);
 	fc->demux.priv = fc;
-
 	fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
-
 	fc->demux.start_feed = flexcop_dvb_start_feed;
 	fc->demux.stop_feed = flexcop_dvb_stop_feed;
 	fc->demux.write_to_decoder = NULL;
 
 	if ((ret = dvb_dmx_init(&fc->demux)) < 0) {
-		err("dvb_dmx failed: error %d",ret);
+		err("dvb_dmx failed: error %d", ret);
 		goto err_dmx;
 	}
 
@@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexc
 	fc->dmxdev.demux = &fc->demux.dmx;
 	fc->dmxdev.capabilities = 0;
 	if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) {
-		err("dvb_dmxdev_init failed: error %d",ret);
+		err("dvb_dmxdev_init failed: error %d", ret);
 		goto err_dmx_dev;
 	}
 
 	if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
-		err("adding hw_frontend to dmx failed: error %d",ret);
+		err("adding hw_frontend to dmx failed: error %d", ret);
 		goto err_dmx_add_hw_frontend;
 	}
 
 	fc->mem_frontend.source = DMX_MEMORY_FE;
 	if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) {
-		err("adding mem_frontend to dmx failed: error %d",ret);
+		err("adding mem_frontend to dmx failed: error %d", ret);
 		goto err_dmx_add_mem_frontend;
 	}
 
 	if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
-		err("connect frontend failed: error %d",ret);
+		err("connect frontend failed: error %d", ret);
 		goto err_connect_frontend;
 	}
 
@@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexc
 	return 0;
 
 err_connect_frontend:
-	fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+	fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
 err_dmx_add_mem_frontend:
-	fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+	fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
 err_dmx_add_hw_frontend:
 	dvb_dmxdev_release(&fc->dmxdev);
 err_dmx_dev:
@@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flex
 		dvb_net_release(&fc->dvbnet);
 
 		fc->demux.dmx.close(&fc->demux.dmx);
-		fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
-		fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+		fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+			&fc->mem_frontend);
+		fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+			&fc->hw_frontend);
 		dvb_dmxdev_release(&fc->dmxdev);
 		dvb_dmx_release(&fc->demux);
 		dvb_unregister_adapter(&fc->dvb_adapter);
-
 		deb_info("deinitialized dvb stuff\n");
 	}
 	fc->init_state &= ~FC_STATE_DVB_INIT;
@@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets);
 
 static void flexcop_reset(struct flexcop_device *fc)
 {
-	flexcop_ibi_value v210,v204;
+	flexcop_ibi_value v210, v204;
 
-/* reset the flexcop itself */
+	/* reset the flexcop itself */
 	fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
 
 	v210.raw = 0;
@@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop
 	v210.sw_reset_210.reset_block_600 = 1;
 	v210.sw_reset_210.reset_block_700 = 1;
 	v210.sw_reset_210.Block_reset_enable = 0xb2;
-
 	v210.sw_reset_210.Special_controls = 0xc259;
-
 	fc->write_ibi_reg(fc,sw_reset_210,v210);
 	msleep(1);
 
-/* reset the periphical devices */
+	/* reset the periphical devices */
 
 	v204 = fc->read_ibi_reg(fc,misc_204);
 	v204.misc_204.Per_reset_sig = 0;
@@ -201,25 +200,24 @@ static void flexcop_reset(struct flexcop
 
 void flexcop_reset_block_300(struct flexcop_device *fc)
 {
-	flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
-					  v210 = fc->read_ibi_reg(fc,sw_reset_210);
-
-	deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+	flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
+			  v210 = fc->read_ibi_reg(fc, sw_reset_210);
 
+	deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
 	fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
 
 	v210.sw_reset_210.reset_block_300 = 1;
 	v210.sw_reset_210.Block_reset_enable = 0xb2;
 
 	fc->write_ibi_reg(fc,sw_reset_210,v210);
-	udelay(1000);
 	fc->write_ibi_reg(fc,ctrl_208,v208_save);
 }
 
 struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
 {
 	void *bus;
-	struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL);
+	struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+				GFP_KERNEL);
 	if (!fc) {
 		err("no memory");
 		return NULL;
@@ -254,7 +252,6 @@ int flexcop_device_initialize(struct fle
 	flexcop_determine_revision(fc);
 	flexcop_sram_init(fc);
 	flexcop_hw_filter_init(fc);
-
 	flexcop_smc_ctrl(fc, 0);
 
 	if ((ret = flexcop_dvb_init(fc)))
@@ -279,7 +276,6 @@ int flexcop_device_initialize(struct fle
 		goto error;
 
 	flexcop_device_name(fc,"initialization of","complete");
-
 	return 0;
 
 error:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-common.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-common.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-common.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,11 +28,14 @@
 
 /* Steal from usb.h */
 #undef err
-#define err(format,  arg...) printk(KERN_ERR     FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define err(format, arg...) \
+	printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
 #undef info
-#define info(format, arg...) printk(KERN_INFO    FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define info(format, arg...) \
+	printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
 #undef warn
-#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+	printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
 
 struct flexcop_dma {
 	struct pci_dev *pdev;
@@ -91,16 +94,14 @@ struct flexcop_device {
 	int fullts_streaming_state;
 
 	/* bus specific callbacks */
-	flexcop_ibi_value (*read_ibi_reg)  (struct flexcop_device *, flexcop_ibi_register);
-	int               (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
-
-
-	int (*i2c_request) (struct flexcop_i2c_adapter*,
+	flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+			flexcop_ibi_register);
+	int (*write_ibi_reg) (struct flexcop_device *,
+			flexcop_ibi_register, flexcop_ibi_value);
+	int (*i2c_request) (struct flexcop_i2c_adapter *,
 		flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
-	int (*stream_control) (struct flexcop_device*, int);
-
+	int (*stream_control) (struct flexcop_device *, int);
 	int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-
 	void *bus_specific;
 };
 
@@ -111,22 +112,28 @@ void flexcop_pass_dmx_data(struct flexco
 void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
 
 struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
-void flexcop_device_kfree(struct flexcop_device*);
+void flexcop_device_kfree(struct flexcop_device *);
 
-int  flexcop_device_initialize(struct flexcop_device*);
+int flexcop_device_initialize(struct flexcop_device *);
 void flexcop_device_exit(struct flexcop_device *fc);
-
 void flexcop_reset_block_300(struct flexcop_device *fc);
 
 /* from flexcop-dma.c */
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
+int flexcop_dma_allocate(struct pci_dev *pdev,
+		struct flexcop_dma *dma, u32 size);
 void flexcop_dma_free(struct flexcop_dma *dma);
 
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
-int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+		flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+		flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
+		flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
+		int onoff);
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx, u8 cycles);
 
 /* from flexcop-eeprom.c */
 /* the PCI part uses this call to get the MAC address, the USB part has its own */
@@ -141,13 +148,15 @@ int flexcop_i2c_request(struct flexcop_i
 	u8 chipaddr, u8 addr, u8 *buf, u16 len);
 
 /* from flexcop-sram.c */
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+	flexcop_sram_dest_target_t target);
 void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
-void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill);
+void flexcop_sram_ctrl(struct flexcop_device *fc,
+		int usb_wan, int sramdma, int maximumfill);
 
 /* global prototypes for the flexcop-chip */
 /* from flexcop-fe-tuner.c */
-int flexcop_frontend_init(struct flexcop_device *card);
+int flexcop_frontend_init(struct flexcop_device *fc);
 void flexcop_frontend_exit(struct flexcop_device *fc);
 
 /* from flexcop-i2c.c */
@@ -159,11 +168,14 @@ int flexcop_sram_init(struct flexcop_dev
 
 /* from flexcop-misc.c */
 void flexcop_determine_revision(struct flexcop_device *fc);
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
+void flexcop_device_name(struct flexcop_device *fc,
+		const char *prefix, const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc,
+		flexcop_ibi_register reg, int num);
 
 /* from flexcop-hw-filter.c */
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+		struct dvb_demux_feed *dvbdmxfeed, int onoff);
 void flexcop_hw_filter_init(struct flexcop_device *fc);
 
 void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-dma.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-dma.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,12 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
+int flexcop_dma_allocate(struct pci_dev *pdev,
+		struct flexcop_dma *dma, u32 size)
 {
 	u8 *tcpu;
 	dma_addr_t tdma = 0;
@@ -32,7 +31,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate);
 
 void flexcop_dma_free(struct flexcop_dma *dma)
 {
-	pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0);
+	pci_free_consistent(dma->pdev, dma->size*2,
+			dma->cpu_addr0, dma->dma_addr0);
 	memset(dma,0,sizeof(struct flexcop_dma));
 }
 EXPORT_SYMBOL(flexcop_dma_free);
@@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_de
 	flexcop_ibi_value v0x0,v0x4,v0xc;
 	v0x0.raw = v0x4.raw = v0xc.raw = 0;
 
-	v0x0.dma_0x0.dma_address0        = dma->dma_addr0 >> 2;
-	v0xc.dma_0xc.dma_address1        = dma->dma_addr1 >> 2;
+	v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+	v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
 	v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
 
 	if ((dma_idx & FC_DMA_1) == dma_idx) {
@@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_de
 		fc->write_ibi_reg(fc,dma2_014,v0x4);
 		fc->write_ibi_reg(fc,dma2_01c,v0xc);
 	} else {
-		err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+		err("either DMA1 or DMA2 can be configured within one "
+			"flexcop_dma_config call.");
 		return -EINVAL;
 	}
 
@@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flex
 		r0x0 = dma2_010;
 		r0xc = dma2_01c;
 	} else {
-		err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+		err("either transfer DMA1 or DMA2 can be started within one "
+			"flexcop_dma_xfer_control call.");
 		return -EINVAL;
 	}
 
@@ -154,8 +156,7 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_
 
 /* 1 cycles = 1.97 msec */
 int flexcop_dma_config_timer(struct flexcop_device *fc,
-		flexcop_dma_index_t dma_idx,
-		u8 cycles)
+		flexcop_dma_index_t dma_idx, u8 cycles)
 {
 	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-eeprom.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-eeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,7 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
@@ -14,17 +12,17 @@ static int eeprom_write(struct adapter *
 	return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
 }
 
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+		u32 len, u8 *wbuf, u8 *rbuf, int retries)
 {
-	int i;
+int i;
 
-	for (i = 0; i < retries; i++) {
-		if (eeprom_write(adapter, addr, wbuf, len) == len) {
-			if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
-				return 1;
+for (i = 0; i < retries; i++) {
+	if (eeprom_write(adapter, addr, wbuf, len) == len) {
+		if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+			return 1;
 		}
 	}
-
 	return 0;
 }
 
@@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapte
 		return 0;
 
 	memcpy(wbuf, key, len);
-
 	wbuf[16] = 0;
 	wbuf[17] = 0;
 	wbuf[18] = 0;
 	wbuf[19] = calc_lrc(wbuf, 19);
-
 	return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
 }
 
@@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter
 		return 0;
 
 	memcpy(key, buf, len);
-
 	return 1;
 }
 
@@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct a
 		tmp[3] = mac[5];
 		tmp[4] = mac[6];
 		tmp[5] = mac[7];
-
 	} else {
-
 		tmp[0] = mac[0];
 		tmp[1] = mac[1];
 		tmp[2] = mac[2];
@@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct a
 
 	if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
 		return 1;
-
 	return 0;
 }
 
-static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len)
+static int flexcop_eeprom_read(struct flexcop_device *fc,
+		u16 addr, u8 *buf, u16 len)
 {
 	return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
 }
@@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len)
 	return sum;
 }
 
-static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_request(struct flexcop_device *fc,
+	flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
 {
 	int i,ret = 0;
 	u8 chipaddr =  0x50 | ((addr >> 8) & 3);
@@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct
 	return ret;
 }
 
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
+		u8 *buf, u16 len, int retries)
 {
 	int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
 	if (ret == 0)
@@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struc
 }
 
 /* JJ's comment about extended == 1: it is not presently used anywhere but was
- * added to the low-level functions for possible support of EUI64
- */
+ * added to the low-level functions for possible support of EUI64 */
 int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
 {
 	u8 buf[8];
@@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct
 
 	if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
 		if (extended != 0) {
-			err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
+			err("TODO: extended (EUI64) MAC addresses aren't "
+				"completely supported yet");
 			ret = -EINVAL;
-/*			memcpy(fc->dvb_adapter.proposed_mac,buf,3);
-			mac[3] = 0xfe;
-			mac[4] = 0xff;
-			memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
 		} else
 			memcpy(fc->dvb_adapter.proposed_mac,buf,6);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c	2013-05-03 16:44:18.000000000 -0400
@@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop
 		fc->fe_sleep = ops->sleep;
 		ops->sleep = flexcop_sleep;
 
-		fc->dev_type = FC_SKY;
+		fc->dev_type = FC_SKY_REV26;
 		goto fe_found;
 	}
 
 	/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
 	fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
 	if (fc->fe != NULL) {
-		fc->dev_type = FC_AIR_DVB;
+		fc->dev_type = FC_AIR_DVBT;
 		fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
 		goto fe_found;
 	}
@@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop
 		fc->fe_sleep                = ops->sleep;
 		ops->sleep                  = flexcop_sleep;
 
-		fc->dev_type                = FC_SKY_OLD;
+		fc->dev_type                = FC_SKY_REV23;
 		goto fe_found;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,7 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop.h - private header file for all flexcop-chip-source files.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.h - private header file for all flexcop-chip-source files
+ * see flexcop.c for copyright information
  */
 #ifndef __FLEXCOP_H__
 #define __FLEXCOP_H___
@@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug;
 #define dprintk(level,args...)
 #endif
 
-#define deb_info(args...)  dprintk(0x01,args)
-#define deb_tuner(args...) dprintk(0x02,args)
-#define deb_i2c(args...)   dprintk(0x04,args)
-#define deb_ts(args...)    dprintk(0x08,args)
-#define deb_sram(args...)  dprintk(0x10,args)
-#define deb_rdump(args...)  dprintk(0x20,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_tuner(args...) dprintk(0x02, args)
+#define deb_i2c(args...) dprintk(0x04, args)
+#define deb_ts(args...) dprintk(0x08, args)
+#define deb_sram(args...) dprintk(0x10, args)
+#define deb_rdump(args...) dprintk(0x20, args)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-hw-filter.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-hw-filter.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-hw-filter.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-hw-filter.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,33 +1,30 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and control functions
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
 static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
 {
-	flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
-
-	deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
+	flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
+	deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
 }
 
 void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
 {
-	flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
+	flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
 }
 
 static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
 {
-	flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
+	flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
 }
 
 void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
 {
-	flexcop_ibi_value v418,v41c;
-	v41c = fc->read_ibi_reg(fc,mac_address_41c);
+	flexcop_ibi_value v418, v41c;
+	v41c = fc->read_ibi_reg(fc, mac_address_41c);
 
 	v418.mac_address_418.MAC1 = mac[0];
 	v418.mac_address_418.MAC2 = mac[1];
@@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexc
 	v41c.mac_address_41c.MAC7 = mac[4];
 	v41c.mac_address_41c.MAC8 = mac[5];
 
-	fc->write_ibi_reg(fc,mac_address_418,v418);
-	fc->write_ibi_reg(fc,mac_address_41c,v41c);
+	fc->write_ibi_reg(fc, mac_address_418, v418);
+	fc->write_ibi_reg(fc, mac_address_41c, v41c);
 }
 
 void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
 {
-	flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
+	flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
 }
 
-static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
+static void flexcop_pid_group_filter(struct flexcop_device *fc,
+		u16 pid, u16 mask)
 {
 	/* index_reg_310.extra_index_reg need to 0 or 7 to work */
 	flexcop_ibi_value v30c;
 	v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
 	v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
-	fc->write_ibi_reg(fc,pid_filter_30c,v30c);
+	fc->write_ibi_reg(fc, pid_filter_30c, v30c);
 }
 
 static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
 {
-	flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
+	flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
 }
 
 /* this fancy define reduces the code size of the quite similar PID controlling of
@@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctr
 
 #define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
 	flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
-					  v208 = fc->read_ibi_reg(fc, ctrl_208); \
-\
-	vpid.vregname.field = onoff ? pid : 0x1fff; \
-	vpid.vregname.trans_field = transval; \
-	v208.ctrl_208.enablefield = onoff; \
-\
-	fc->write_ibi_reg(fc,vregname,vpid); \
-	fc->write_ibi_reg(fc,ctrl_208,v208);
+v208 = fc->read_ibi_reg(fc, ctrl_208); \
+vpid.vregname.field = onoff ? pid : 0x1fff; \
+vpid.vregname.trans_field = transval; \
+v208.ctrl_208.enablefield = onoff; \
+fc->write_ibi_reg(fc, vregname, vpid); \
+fc->write_ibi_reg(fc, ctrl_208, v208);
 
-static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
+	pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
+			Stream1_trans, 0);
 }
 
-static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
+	pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
+			Stream2_trans, 0);
 }
 
-static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
+	pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
 }
 
-static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
+	pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
 }
 
-static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
+	pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
 }
 
-static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
+		u16 pid, int onoff)
 {
-	pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
+	pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
 }
 
-static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
+static void flexcop_pid_control(struct flexcop_device *fc,
+		int index, u16 pid, int onoff)
 {
 	if (pid == 0x2000)
 		return;
 
-	deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");
+	deb_ts("setting pid: %5d %04x at index %d '%s'\n",
+			pid, pid, index, onoff ? "on" : "off");
 
 	/* We could use bit magic here to reduce source code size.
 	 * I decided against it, but to use the real register names */
 	switch (index) {
-		case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
-		case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
-		case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
-		case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
-		case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
-		case 5:	flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
-		default:
-			if (fc->has_32_hw_pid_filter && index < 38) {
-				flexcop_ibi_value vpid,vid;
+	case 0:
+		flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
+		break;
+	case 1:
+		flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
+		break;
+	case 2:
+		flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
+		break;
+	case 3:
+		flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
+		break;
+	case 4:
+		flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
+		break;
+	case 5:
+		flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
+		break;
+	default:
+		if (fc->has_32_hw_pid_filter && index < 38) {
+			flexcop_ibi_value vpid, vid;
 
-				/* set the index */
-				vid = fc->read_ibi_reg(fc,index_reg_310);
-				vid.index_reg_310.index_reg = index - 6;
-				fc->write_ibi_reg(fc,index_reg_310, vid);
+			/* set the index */
+			vid = fc->read_ibi_reg(fc, index_reg_310);
+			vid.index_reg_310.index_reg = index - 6;
+			fc->write_ibi_reg(fc, index_reg_310, vid);
 
-				vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
-				vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
-				vpid.pid_n_reg_314.PID_enable_bit = onoff;
-				fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
-			}
-			break;
+			vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
+			vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+			vpid.pid_n_reg_314.PID_enable_bit = onoff;
+			fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
+		}
+		break;
 	}
 }
 
-static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
 {
 	if (fc->fullts_streaming_state != onoff) {
 		deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
 		flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
-		flexcop_pid_group_filter_ctrl(fc,onoff);
+		flexcop_pid_group_filter_ctrl(fc, onoff);
 		fc->fullts_streaming_state = onoff;
 	}
 	return 0;
 }
 
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+		struct dvb_demux_feed *dvbdmxfeed, int onoff)
 {
 	int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
 
@@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flex
 	 *   - or the requested pid is 0x2000 */
 
 	if (!fc->pid_filtering && fc->feedcount == onoff)
-		flexcop_toggle_fullts_streaming(fc,onoff);
+		flexcop_toggle_fullts_streaming(fc, onoff);
 
 	if (fc->pid_filtering) {
-		flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+		flexcop_pid_control \
+			(fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
 
 		if (fc->extra_feedcount > 0)
-			flexcop_toggle_fullts_streaming(fc,1);
+			flexcop_toggle_fullts_streaming(fc, 1);
 		else if (dvbdmxfeed->pid == 0x2000)
-			flexcop_toggle_fullts_streaming(fc,onoff);
+			flexcop_toggle_fullts_streaming(fc, onoff);
 		else
-			flexcop_toggle_fullts_streaming(fc,0);
+			flexcop_toggle_fullts_streaming(fc, 0);
 	}
 
 	/* if it was the first or last feed request change the stream-status */
 	if (fc->feedcount == onoff) {
-		flexcop_rcv_data_ctrl(fc,onoff);
+		flexcop_rcv_data_ctrl(fc, onoff);
 		if (fc->stream_control) /* device specific stream control */
-			fc->stream_control(fc,onoff);
+			fc->stream_control(fc, onoff);
 
 		/* feeding stopped -> reset the flexcop filter*/
 		if (onoff == 0) {
@@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flex
 			flexcop_hw_filter_init(fc);
 		}
 	}
-
 	return 0;
 }
 EXPORT_SYMBOL(flexcop_pid_feed_control);
@@ -199,15 +218,15 @@ void flexcop_hw_filter_init(struct flexc
 	int i;
 	flexcop_ibi_value v;
 	for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
-		flexcop_pid_control(fc,i,0x1fff,0);
+		flexcop_pid_control(fc, i, 0x1fff, 0);
 
 	flexcop_pid_group_filter(fc, 0, 0x1fe0);
-	flexcop_pid_group_filter_ctrl(fc,0);
+	flexcop_pid_group_filter_ctrl(fc, 0);
 
-	v = fc->read_ibi_reg(fc,pid_filter_308);
+	v = fc->read_ibi_reg(fc, pid_filter_308);
 	v.pid_filter_308.EMM_filter_4 = 1;
 	v.pid_filter_308.EMM_filter_6 = 0;
-	fc->write_ibi_reg(fc,pid_filter_308,v);
+	fc->write_ibi_reg(fc, pid_filter_308, v);
 
 	flexcop_null_filter_ctrl(fc, 1);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-i2c.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,17 +1,14 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
  * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
 #define FC_MAX_I2C_RETRIES 100000
 
-/* #define DUMP_I2C_MESSAGES */
-
-static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+		flexcop_ibi_value *r100)
 {
 	int i;
 	flexcop_ibi_value r;
@@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct
 		r = fc->read_ibi_reg(fc, tw_sm_c_100);
 
 		if (!r.tw_sm_c_100.no_base_addr_ack_error) {
-			if (r.tw_sm_c_100.st_done) {  /* && !r.tw_sm_c_100.working_start */
+			if (r.tw_sm_c_100.st_done) {
 				*r100 = r;
 				deb_i2c("i2c success\n");
 				return 0;
@@ -36,17 +33,31 @@ static int flexcop_i2c_operation(struct
 			return -EREMOTEIO;
 		}
 	}
-	deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+	deb_i2c("tried %d times i2c operation, "
+			"never finished or too many ack errors.\n", i);
 	return -EREMOTEIO;
 }
 
 static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
-	flexcop_ibi_value r100, u8 *buf)
+		flexcop_ibi_value r100, u8 *buf)
 {
 	flexcop_ibi_value r104;
-	int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+	int len = r100.tw_sm_c_100.total_bytes,
+		/* remember total_bytes is buflen-1 */
 		ret;
 
+	/* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+	 * correctly:
+	 *
+	 * the ITD1000 is behind an i2c-gate which closes automatically
+	 * after an i2c-transaction the STV0297 needs 2 consecutive reads
+	 * one with no_base_addr = 0 and one with 1
+	 *
+	 * those two work-arounds are conflictin: we check for the card
+	 * type, it is set when probing the ITD1000 */
+	if (i2c->fc->dev_type == FC_SKY_REV27)
+		r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+
 	ret = flexcop_i2c_operation(i2c->fc, &r100);
 	if (ret != 0) {
 		deb_i2c("Retrying operation\n");
@@ -69,11 +80,11 @@ static int flexcop_i2c_read4(struct flex
 		if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
 		if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
 	}
-
 	return 0;
 }
 
-static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+static int flexcop_i2c_write4(struct flexcop_device *fc,
+		flexcop_ibi_value r100, u8 *buf)
 {
 	flexcop_ibi_value r104;
 	int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
@@ -81,7 +92,6 @@ static int flexcop_i2c_write4(struct fle
 
 	/* there is at least one byte, otherwise we wouldn't be here */
 	r100.tw_sm_c_100.data1_reg = buf[0];
-
 	r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
 	r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
 	r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
@@ -94,7 +104,7 @@ static int flexcop_i2c_write4(struct fle
 }
 
 int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
-	flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+		flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
 {
 	int ret;
 
@@ -117,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i
 		printk("rd(");
 	else
 		printk("wr(");
-
 	printk("%02x): %02x ", chipaddr, addr);
 #endif
 
@@ -163,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i
 EXPORT_SYMBOL(flexcop_i2c_request);
 
 /* master xfer callback for demodulator */
-static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msgs[], int num)
 {
 	struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
 	int i, ret = 0;
@@ -182,12 +192,13 @@ static int flexcop_master_xfer(struct i2
 		/* reading */
 		if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
 			ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
-				msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len);
+					msgs[i].buf[0], msgs[i+1].buf,
+					msgs[i+1].len);
 			i++; /* skip the following message */
 		} else /* writing */
 			ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
-				msgs[i].buf[0], &msgs[i].buf[1],
-				msgs[i].len - 1);
+					msgs[i].buf[0], &msgs[i].buf[1],
+					msgs[i].len - 1);
 		if (ret < 0) {
 			err("i2c master_xfer failed");
 			break;
@@ -214,23 +225,21 @@ static struct i2c_algorithm flexcop_algo
 int flexcop_i2c_init(struct flexcop_device *fc)
 {
 	int ret;
-
 	mutex_init(&fc->i2c_mutex);
 
 	fc->fc_i2c_adap[0].fc = fc;
 	fc->fc_i2c_adap[1].fc = fc;
 	fc->fc_i2c_adap[2].fc = fc;
-
 	fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
 	fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
 	fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
 
 	strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
-		sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+			sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
 	strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
-		sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+			sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
 	strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
-		sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+			sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
 
 	i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
 	i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
@@ -268,7 +277,6 @@ adap_2_failed:
 	i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
 adap_1_failed:
 	i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-
 	return ret;
 }
 
@@ -279,6 +287,5 @@ void flexcop_i2c_exit(struct flexcop_dev
 		i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
 		i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
 	}
-
 	fc->init_state &= ~FC_STATE_I2C_INIT;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
  * register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
  */
-
 /* This file is automatically generated, do not edit things here. */
 #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
 #define __FLEXCOP_IBI_VALUE_INCLUDED__
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
  * register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
  */
-
 /* This file is automatically generated, do not edit things here. */
 #ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
 #define __FLEXCOP_IBI_VALUE_INCLUDED__
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-misc.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-misc.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-misc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-misc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,7 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-misc.c - miscellaneous functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
@@ -12,39 +10,43 @@ void flexcop_determine_revision(struct f
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
 
 	switch (v.misc_204.Rev_N_sig_revision_hi) {
-		case 0x2:
-			deb_info("found a FlexCopII.\n");
-			fc->rev = FLEXCOP_II;
-			break;
-		case 0x3:
-			deb_info("found a FlexCopIIb.\n");
-			fc->rev = FLEXCOP_IIB;
-			break;
-		case 0x0:
-			deb_info("found a FlexCopIII.\n");
-			fc->rev = FLEXCOP_III;
-			break;
-		default:
-			err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi);
-			break;
+	case 0x2:
+		deb_info("found a FlexCopII.\n");
+		fc->rev = FLEXCOP_II;
+		break;
+	case 0x3:
+		deb_info("found a FlexCopIIb.\n");
+		fc->rev = FLEXCOP_IIB;
+		break;
+	case 0x0:
+		deb_info("found a FlexCopIII.\n");
+		fc->rev = FLEXCOP_III;
+		break;
+	default:
+		err("unknown FlexCop Revision: %x. Please report this to "
+				"linux-dvb@linuxtv.org.",
+				v.misc_204.Rev_N_sig_revision_hi);
+		break;
 	}
 
 	if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
-		deb_info("this FlexCop has the additional 32 hardware pid filter.\n");
+		deb_info("this FlexCop has "
+				"the additional 32 hardware pid filter.\n");
 	else
-		deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n");
+		deb_info("this FlexCop has "
+				"the 6 basic main hardware pid filter.\n");
 	/* bus parts have to decide if hw pid filtering is used or not. */
 }
 
 static const char *flexcop_revision_names[] = {
-	"Unkown chip",
+	"Unknown chip",
 	"FlexCopII",
 	"FlexCopIIb",
 	"FlexCopIII",
 };
 
 static const char *flexcop_device_names[] = {
-	"Unkown device",
+	"Unknown device",
 	"Air2PC/AirStar 2 DVB-T",
 	"Air2PC/AirStar 2 ATSC 1st generation",
 	"Air2PC/AirStar 2 ATSC 2nd generation",
@@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] =
 	"PCI",
 };
 
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
-		char *suffix)
+void flexcop_device_name(struct flexcop_device *fc,
+		const char *prefix, const char *suffix)
 {
-	info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix,
-			flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
-			flexcop_revision_names[fc->rev],suffix);
+	info("%s '%s' at the '%s' bus controlled by a '%s' %s",
+			prefix,	flexcop_device_names[fc->dev_type],
+			flexcop_bus_names[fc->bus_type],
+			flexcop_revision_names[fc->rev], suffix);
 }
 
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+void flexcop_dump_reg(struct flexcop_device *fc,
+		flexcop_ibi_register reg, int num)
 {
 	flexcop_ibi_value v;
 	int i;
 	for (i = 0; i < num; i++) {
-		v = fc->read_ibi_reg(fc,reg+4*i);
-		deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+		v = fc->read_ibi_reg(fc, reg+4*i);
+		deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
 	}
 	deb_rdump("\n");
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-pci.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-pci.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,7 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-pci.c - covers the PCI part including DMA transfers.
- *
- * see flexcop.c for copyright information.
+ * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-pci.c - covers the PCI part including DMA transfers
+ * see flexcop.c for copyright information
  */
 
 #define FC_LOG_PREFIX "flexcop-pci"
@@ -11,7 +9,8 @@
 
 static int enable_pid_filtering = 1;
 module_param(enable_pid_filtering, int, 0444);
-MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+MODULE_PARM_DESC(enable_pid_filtering,
+	"enable hardware pid filtering: supported values: 0 (fullts), 1");
 
 static int irq_chk_intv = 100;
 module_param(irq_chk_intv, int, 0644);
@@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the
 #define DEBSTATUS " (debugging is not enabled)"
 #endif
 
-#define deb_info(args...)  dprintk(0x01,args)
-#define deb_reg(args...)   dprintk(0x02,args)
-#define deb_ts(args...)    dprintk(0x04,args)
-#define deb_irq(args...)   dprintk(0x08,args)
-#define deb_chk(args...)   dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_reg(args...) dprintk(0x02, args)
+#define deb_ts(args...) dprintk(0x04, args)
+#define deb_irq(args...) dprintk(0x08, args)
+#define deb_chk(args...) dprintk(0x10, args)
 
 static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug,
 	"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
-	 DEBSTATUS);
+	DEBSTATUS);
 
 #define DRIVER_VERSION "0.1"
 #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -51,30 +50,30 @@ struct flexcop_pci {
 
 	void __iomem *io_mem;
 	u32 irq;
-/* buffersize (at least for DMA1, need to be % 188 == 0,
- * this logic is required */
+	/* buffersize (at least for DMA1, need to be % 188 == 0,
+	 * this logic is required */
 #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
 #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
 	struct flexcop_dma dma[2];
 
 	int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
-	u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
+	u32 last_dma1_cur_pos;
+	/* position of the pointer last time the timer/packet irq occured */
 	int count;
 	int count_prev;
 	int stream_problem;
 
 	spinlock_t irq_lock;
-
 	unsigned long last_irq;
 
 	struct delayed_work irq_check_work;
-
 	struct flexcop_device *fc_dev;
 };
 
-static int lastwreg,lastwval,lastrreg,lastrval;
+static int lastwreg, lastwval, lastrreg, lastrval;
 
-static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
+		flexcop_ibi_register r)
 {
 	struct flexcop_pci *fc_pci = fc->bus_specific;
 	flexcop_ibi_value v;
@@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_rea
 
 	if (lastrreg != r || lastrval != v.raw) {
 		lastrreg = r; lastrval = v.raw;
-		deb_reg("new rd: %3x: %08x\n",r,v.raw);
+		deb_reg("new rd: %3x: %08x\n", r, v.raw);
 	}
 
 	return v;
 }
 
-static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
+		flexcop_ibi_register r, flexcop_ibi_value v)
 {
 	struct flexcop_pci *fc_pci = fc->bus_specific;
 
 	if (lastwreg != r || lastwval != v.raw) {
 		lastwreg = r; lastwval = v.raw;
-		deb_reg("new wr: %3x: %08x\n",r,v.raw);
+		deb_reg("new wr: %3x: %08x\n", r, v.raw);
 	}
 
 	writel(v.raw, fc_pci->io_mem + r);
@@ -113,15 +113,16 @@ static void flexcop_pci_irq_check_work(s
 			deb_chk("no IRQ since the last check\n");
 			if (fc_pci->stream_problem++ == 3) {
 				struct dvb_demux_feed *feed;
+				deb_info("flexcop-pci: stream problem, resetting pid filter\n");
 
 				spin_lock_irq(&fc->demux.lock);
 				list_for_each_entry(feed, &fc->demux.feed_list,
-					list_head) {
+						list_head) {
 					flexcop_pid_feed_control(fc, feed, 0);
 				}
 
 				list_for_each_entry(feed, &fc->demux.feed_list,
-					list_head) {
+						list_head) {
 					flexcop_pid_feed_control(fc, feed, 1);
 				}
 				spin_unlock_irq(&fc->demux.lock);
@@ -149,11 +150,10 @@ static irqreturn_t flexcop_pci_isr(int i
 	flexcop_ibi_value v;
 	irqreturn_t ret = IRQ_HANDLED;
 
-	spin_lock_irqsave(&fc_pci->irq_lock,flags);
-
-	v = fc->read_ibi_reg(fc,irq_20c);
+	spin_lock_irqsave(&fc_pci->irq_lock, flags);
+	v = fc->read_ibi_reg(fc, irq_20c);
 
-   /* errors */
+	/* errors */
 	if (v.irq_20c.Data_receiver_error)
 		deb_chk("data receiver error\n");
 	if (v.irq_20c.Continuity_error_flag)
@@ -164,24 +164,29 @@ static irqreturn_t flexcop_pci_isr(int i
 		deb_chk("Transport error\n");
 
 	if ((fc_pci->count % 1000) == 0)
-		deb_chk("%d valid irq took place so far\n",fc_pci->count);
+		deb_chk("%d valid irq took place so far\n", fc_pci->count);
 
 	if (v.irq_20c.DMA1_IRQ_Status == 1) {
 		if (fc_pci->active_dma1_addr == 0)
-			flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
+			flexcop_pass_dmx_packets(fc_pci->fc_dev,
+					fc_pci->dma[0].cpu_addr0,
+					fc_pci->dma[0].size / 188);
 		else
-			flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
+			flexcop_pass_dmx_packets(fc_pci->fc_dev,
+					fc_pci->dma[0].cpu_addr1,
+					fc_pci->dma[0].size / 188);
 
 		deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
 		fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
-	} else if (v.irq_20c.DMA1_Timer_Status == 1) {
 		/* for the timer IRQ we only can use buffer dmx feeding, because we don't have
 		 * complete TS packets when reading from the DMA memory */
+	} else if (v.irq_20c.DMA1_Timer_Status == 1) {
 		dma_addr_t cur_addr =
 			fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
 		u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
 
-		deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+		deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
+			"last_cur_pos: %08x ",
 				jiffies_to_usecs(jiffies - fc_pci->last_irq),
 				v.raw, (unsigned long long)cur_addr, cur_pos,
 				fc_pci->last_dma1_cur_pos);
@@ -191,30 +196,36 @@ static irqreturn_t flexcop_pci_isr(int i
 		 * pass the data from last_cur_pos to the buffer end to the demux
 		 */
 		if (cur_pos < fc_pci->last_dma1_cur_pos) {
-			deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
+			deb_irq(" end was reached: passing %d bytes ",
+				(fc_pci->dma[0].size*2 - 1) -
+				fc_pci->last_dma1_cur_pos);
 			flexcop_pass_dmx_data(fc_pci->fc_dev,
-					fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
-					(fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
+				fc_pci->dma[0].cpu_addr0 +
+					fc_pci->last_dma1_cur_pos,
+				(fc_pci->dma[0].size*2) -
+					fc_pci->last_dma1_cur_pos);
 			fc_pci->last_dma1_cur_pos = 0;
 		}
 
 		if (cur_pos > fc_pci->last_dma1_cur_pos) {
-			deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
+			deb_irq(" passing %d bytes ",
+				cur_pos - fc_pci->last_dma1_cur_pos);
 			flexcop_pass_dmx_data(fc_pci->fc_dev,
-					fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
-					cur_pos - fc_pci->last_dma1_cur_pos);
+				fc_pci->dma[0].cpu_addr0 +
+					fc_pci->last_dma1_cur_pos,
+				cur_pos - fc_pci->last_dma1_cur_pos);
 		}
 		deb_irq("\n");
 
 		fc_pci->last_dma1_cur_pos = cur_pos;
 		fc_pci->count++;
 	} else {
-		deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
+		deb_irq("isr for flexcop called, "
+			"apparently without reason (%08x)\n", v.raw);
 		ret = IRQ_NONE;
 	}
 
-	spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
-
+	spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
 	return ret;
 }
 
@@ -222,52 +233,48 @@ static int flexcop_pci_stream_control(st
 {
 	struct flexcop_pci *fc_pci = fc->bus_specific;
 	if (onoff) {
-		flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
-		flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
-
-		flexcop_dma_config_timer(fc,FC_DMA_1,0);
-
-		flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+		flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
+		flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
+		flexcop_dma_config_timer(fc, FC_DMA_1, 0);
+		flexcop_dma_xfer_control(fc, FC_DMA_1,
+				FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
 		deb_irq("DMA xfer enabled\n");
 
 		fc_pci->last_dma1_cur_pos = 0;
-		flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+		flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
 		deb_irq("IRQ enabled\n");
-
 		fc_pci->count_prev = fc_pci->count;
-
-//		fc_pci->active_dma1_addr = 0;
-//		flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-
 	} else {
-		flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+		flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
 		deb_irq("IRQ disabled\n");
 
-//		flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
-
-		flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+		flexcop_dma_xfer_control(fc, FC_DMA_1,
+			 FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
 		deb_irq("DMA xfer disabled\n");
 	}
-
 	return 0;
 }
 
 static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
 {
 	int ret;
-	if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
+	ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+			FC_DEFAULT_DMA1_BUFSIZE);
+	if (ret != 0)
 		return ret;
 
-	if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
+	ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+			FC_DEFAULT_DMA2_BUFSIZE);
+	if (ret != 0) {
 		flexcop_dma_free(&fc_pci->dma[0]);
 		return ret;
 	}
 
-	flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
-	flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO   | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
-
+	flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
+			FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+	flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
+			FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
 	fc_pci->init_state |= FC_PCI_DMA_INIT;
-
 	return ret;
 }
 
@@ -290,12 +297,8 @@ static int flexcop_pci_init(struct flexc
 
 	if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
 		return ret;
-
 	pci_set_master(fc_pci->pdev);
 
-	/* enable interrupts */
-	// pci_write_config_dword(pdev, 0x6c, 0x8000);
-
 	if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
 		goto err_pci_disable_device;
 
@@ -338,8 +341,8 @@ static void flexcop_pci_exit(struct flex
 	fc_pci->init_state &= ~FC_PCI_INIT;
 }
 
-
-static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int flexcop_pci_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
 	struct flexcop_device *fc;
 	struct flexcop_pci *fc_pci;
@@ -350,7 +353,7 @@ static int flexcop_pci_probe(struct pci_
 		return -ENOMEM;
 	}
 
-/* general flexcop init */
+	/* general flexcop init */
 	fc_pci = fc->bus_specific;
 	fc_pci->fc_dev = fc;
 
@@ -358,7 +361,6 @@ static int flexcop_pci_probe(struct pci_
 	fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
 	fc->i2c_request = flexcop_i2c_request;
 	fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
-
 	fc->stream_control = flexcop_pci_stream_control;
 
 	if (enable_pid_filtering)
@@ -368,29 +370,29 @@ static int flexcop_pci_probe(struct pci_
 
 	fc->pid_filtering = enable_pid_filtering;
 	fc->bus_type = FC_PCI;
-
 	fc->dev = &pdev->dev;
 	fc->owner = THIS_MODULE;
 
-/* bus specific part */
+	/* bus specific part */
 	fc_pci->pdev = pdev;
 	if ((ret = flexcop_pci_init(fc_pci)) != 0)
 		goto err_kfree;
 
-/* init flexcop */
+	/* init flexcop */
 	if ((ret = flexcop_device_initialize(fc)) != 0)
 		goto err_pci_exit;
 
-/* init dma */
+	/* init dma */
 	if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
 		goto err_fc_exit;
 
 	INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
 
-		if (irq_chk_intv > 0)
-			schedule_delayed_work(&fc_pci->irq_check_work,
-		msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-
+	if (irq_chk_intv > 0)
+		schedule_delayed_work(&fc_pci->irq_check_work,
+				msecs_to_jiffies(irq_chk_intv < 100 ?
+					100 :
+					irq_chk_intv));
 	return ret;
 
 err_fc_exit:
@@ -420,7 +422,6 @@ static void flexcop_pci_remove(struct pc
 
 static struct pci_device_id flexcop_pci_tbl[] = {
 	{ PCI_DEVICE(0x13d0, 0x2103) },
-/*	{ PCI_DEVICE(0x13d0, 0x2200) }, ? */
 	{ },
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-reg.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,11 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
  * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
  */
 #ifndef __FLEXCOP_REG_H__
 #define __FLEXCOP_REG_H__
 
-
 typedef enum {
 	FLEXCOP_UNK = 0,
 	FLEXCOP_II,
@@ -18,13 +15,13 @@ typedef enum {
 
 typedef enum {
 	FC_UNK = 0,
-	FC_AIR_DVB,
+	FC_CABLE,
+	FC_AIR_DVBT,
 	FC_AIR_ATSC1,
 	FC_AIR_ATSC2,
-	FC_SKY,
-	FC_SKY_OLD,
-	FC_CABLE,
 	FC_AIR_ATSC3,
+	FC_SKY_REV23,
+	FC_SKY_REV26,
 	FC_SKY_REV27,
 	FC_SKY_REV28,
 } flexcop_device_type_t;
@@ -36,12 +33,12 @@ typedef enum {
 
 /* FlexCop IBI Registers */
 #if defined(__LITTLE_ENDIAN)
-	#include "flexcop_ibi_value_le.h"
+#include "flexcop_ibi_value_le.h"
 #else
 #if defined(__BIG_ENDIAN)
-	#include "flexcop_ibi_value_be.h"
+#include "flexcop_ibi_value_be.h"
 #else
-	#error no endian defined
+#error no endian defined
 #endif
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-sram.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-sram.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-sram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-sram.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,45 +1,43 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-sram.c - functions for controlling the SRAM.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-sram.c - functions for controlling the SRAM
+ * see flexcop.c for copyright information
  */
 #include "flexcop.h"
 
-static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type)
+static void flexcop_sram_set_chip(struct flexcop_device *fc,
+		flexcop_sram_type_t type)
 {
-	flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type);
+	flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
 }
 
 int flexcop_sram_init(struct flexcop_device *fc)
 {
 	switch (fc->rev) {
-		case FLEXCOP_II:
-		case FLEXCOP_IIB:
-			flexcop_sram_set_chip(fc,FC_SRAM_1_32KB);
-			break;
-		case FLEXCOP_III:
-			flexcop_sram_set_chip(fc,FC_SRAM_1_48KB);
-			break;
-		default:
-			return -EINVAL;
+	case FLEXCOP_II:
+	case FLEXCOP_IIB:
+		flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
+		break;
+	case FLEXCOP_III:
+		flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
+		break;
+	default:
+		return -EINVAL;
 	}
 	return 0;
 }
 
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target)
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+		 flexcop_sram_dest_target_t target)
 {
 	flexcop_ibi_value v;
-
-	v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+	v = fc->read_ibi_reg(fc, sram_dest_reg_714);
 
 	if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
 		err("SRAM destination target to available on FlexCopII(b)\n");
 		return -EINVAL;
 	}
-
-	deb_sram("sram dest: %x target: %x\n",dest, target);
+	deb_sram("sram dest: %x target: %x\n", dest, target);
 
 	if (dest & FC_SRAM_DEST_NET)
 		v.sram_dest_reg_714.NET_Dest = target;
@@ -154,14 +152,12 @@ static void sram_write_chunk(struct adap
 		else
 			bank = 0x10000000;
 	}
-
 	flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
 }
 
 static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
 {
 	u32 bank;
-
 	bank = 0;
 
 	if (adapter->dw_sram_type == 0x20000) {
@@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapt
 		else
 			bank = 0x10000000;
 	}
-
 	flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
 }
 
 static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
 {
 	u32 length;
-
 	while (len != 0) {
 		length = len;
-
-		// check if the address range belongs to the same
-		// 32K memory chip. If not, the data is read from
-		// one chip at a time.
+		/* check if the address range belongs to the same
+		 * 32K memory chip. If not, the data is read
+		 * from one chip at a time */
 		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
 			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
 		}
 
 		sram_read_chunk(adapter, addr, buf, length);
-
 		addr = addr + length;
 		buf = buf + length;
 		len = len - length;
@@ -203,19 +195,17 @@ static void sram_read(struct adapter *ad
 static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
 {
 	u32 length;
-
 	while (len != 0) {
 		length = len;
 
-		// check if the address range belongs to the same
-		// 32K memory chip. If not, the data is written to
-		// one chip at a time.
+		/* check if the address range belongs to the same
+		 * 32K memory chip. If not, the data is
+		 * written to one chip at a time */
 		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
 			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
 		}
 
 		sram_write_chunk(adapter, addr, buf, length);
-
 		addr = addr + length;
 		buf = buf + length;
 		len = len - length;
@@ -224,39 +214,29 @@ static void sram_write(struct adapter *a
 
 static void sram_set_size(struct adapter *adapter, u32 mask)
 {
-	write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+	write_reg_dw(adapter, 0x71c,
+			(mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
 }
 
 static void sram_init(struct adapter *adapter)
 {
 	u32 tmp;
-
 	tmp = read_reg_dw(adapter, 0x71c);
-
 	write_reg_dw(adapter, 0x71c, 1);
 
 	if (read_reg_dw(adapter, 0x71c) != 0) {
 		write_reg_dw(adapter, 0x71c, tmp);
-
 		adapter->dw_sram_type = tmp & 0x30000;
-
 		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-
 	} else {
-
 		adapter->dw_sram_type = 0x10000;
-
 		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
 	}
-
-	/* return value is never used? */
-/*	return adapter->dw_sram_type; */
 }
 
 static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
 {
 	u8 tmp1, tmp2;
-
 	dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
 
 	sram_set_size(adapter, mask);
@@ -269,7 +249,6 @@ static int sram_test_location(struct ada
 	sram_write(adapter, addr + 4, &tmp1, 1);
 
 	tmp2 = 0;
-
 	mdelay(20);
 
 	sram_read(adapter, addr, &tmp2, 1);
@@ -287,7 +266,6 @@ static int sram_test_location(struct ada
 	sram_write(adapter, addr + 4, &tmp1, 1);
 
 	tmp2 = 0;
-
 	mdelay(20);
 
 	sram_read(adapter, addr, &tmp2, 1);
@@ -297,26 +275,24 @@ static int sram_test_location(struct ada
 
 	if (tmp2 != 0x5a)
 		return 0;
-
 	return 1;
 }
 
 static u32 sram_length(struct adapter *adapter)
 {
 	if (adapter->dw_sram_type == 0x10000)
-		return 32768;	//  32K
+		return 32768; /* 32K */
 	if (adapter->dw_sram_type == 0x00000)
-		return 65536;	//  64K
+		return 65536; /* 64K */
 	if (adapter->dw_sram_type == 0x20000)
-		return 131072;	// 128K
-
-	return 32768;		// 32K
+		return 131072; /* 128K */
+	return 32768; /* 32K */
 }
 
 /* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
-    - for 128K there are 4x32K chips at bank 0,1,2,3.
-    - for  64K there are 2x32K chips at bank 1,2.
-    - for  32K there is one 32K chip at bank 0.
+   - for 128K there are 4x32K chips at bank 0,1,2,3.
+   - for  64K there are 2x32K chips at bank 1,2.
+   - for  32K there is one 32K chip at bank 0.
 
    FlexCop works only with one bank at a time. The bank is selected
    by bits 28-29 of the 0x700 register.
@@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *a
    bank 0 covers addresses 0x00000-0x07fff
    bank 1 covers addresses 0x08000-0x0ffff
    bank 2 covers addresses 0x10000-0x17fff
-   bank 3 covers addresses 0x18000-0x1ffff
-*/
+   bank 3 covers addresses 0x18000-0x1ffff */
 
 static int flexcop_sram_detect(struct flexcop_device *fc)
 {
-	flexcop_ibi_value r208,r71c_0,vr71c_1;
-
+	flexcop_ibi_value r208, r71c_0, vr71c_1;
 	r208 = fc->read_ibi_reg(fc, ctrl_208);
 	fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
 
 	r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
-
 	write_reg_dw(adapter, 0x71c, 1);
-
 	tmp3 = read_reg_dw(adapter, 0x71c);
-
 	dprintk("%s: tmp3 = %x\n", __func__, tmp3);
-
 	write_reg_dw(adapter, 0x71c, tmp2);
 
 	// check for internal SRAM ???
@@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct fl
 		sram_set_size(adapter, 0x10000);
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
-
 		dprintk("%s: sram size = 32K\n", __func__);
-
 		return 32;
 	}
 
@@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct fl
 		sram_set_size(adapter, 0x20000);
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
-
 		dprintk("%s: sram size = 128K\n", __func__);
-
 		return 128;
 	}
 
@@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct fl
 		sram_set_size(adapter, 0x00000);
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
-
 		dprintk("%s: sram size = 64K\n", __func__);
-
 		return 64;
 	}
 
@@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct fl
 		sram_set_size(adapter, 0x10000);
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
-
 		dprintk("%s: sram size = 32K\n", __func__);
-
 		return 32;
 	}
 
 	sram_set_size(adapter, 0x10000);
 	sram_init(adapter);
 	write_reg_dw(adapter, 0x208, tmp);
-
 	dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-usb.c linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-usb.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,11 +1,8 @@
 /*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-usb.c - covers the USB part.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.c - covers the USB part
+ * see flexcop.c for copyright information
  */
-
 #define FC_LOG_PREFIX "flexcop_usb"
 #include "flexcop-usb.h"
 #include "flexcop-common.h"
@@ -18,42 +15,47 @@
 /* debug */
 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
 #define dprintk(level,args...) \
-	    do { if ((debug & level)) { printk(args); } } while (0)
-#define debug_dump(b,l,method) {\
+	do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
 	int i; \
-	for (i = 0; i < l; i++) method("%02x ", b[i]); \
-	method("\n");\
-}
+	for (i = 0; i < l; i++) \
+		method("%02x ", b[i]); \
+	method("\n"); \
+} while (0)
 
 #define DEBSTATUS ""
 #else
-#define dprintk(level,args...)
-#define debug_dump(b,l,method)
+#define dprintk(level, args...)
+#define debug_dump(b, l, method)
 #define DEBSTATUS " (debugging is not enabled)"
 #endif
 
 static int debug;
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
+		"ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
 #undef DEBSTATUS
 
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_ts(args...)   dprintk(0x02,args)
-#define deb_ctrl(args...) dprintk(0x04,args)
-#define deb_i2c(args...)  dprintk(0x08,args)
-#define deb_v8(args...)   dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_ts(args...) dprintk(0x02, args)
+#define deb_ctrl(args...) dprintk(0x04, args)
+#define deb_i2c(args...) dprintk(0x08, args)
+#define deb_v8(args...) dprintk(0x10, args)
 
 /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
  * in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
  *                  in general: 0000 0HHH 000L LL00
  * IBI ADDRESS FORMAT:                    RHHH BLLL
  *
  * where R is the read(1)/write(0) bit, B is the busy bit
  * and HHH and LLL are the two sets of three bits from the PCI address.
  */
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
+	(((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
+	(((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
 
 /*
  * DKT 020228
@@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(stru
 	struct flexcop_usb *fc_usb = fc->bus_specific;
 	u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
 	u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
-	u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0);
+	u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
+		(read ? 0x80 : 0);
 
 	int len = usb_control_msg(fc_usb->udev,
 			read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
 			request,
-			request_type,  /* 0xc0 read or 0x40 write*/
+			request_type, /* 0xc0 read or 0x40 write */
 			wAddress,
 			0,
 			val,
@@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(stru
 			B2C2_WAIT_FOR_OPERATION_RDW * HZ);
 
 	if (len != sizeof(u32)) {
-		err("error while %s dword from %d (%d).",read ? "reading" : "writing",
-			wAddress,wRegOffsPCI);
+		err("error while %s dword from %d (%d).", read ? "reading" :
+				"writing", wAddress, wRegOffsPCI);
 		return -EIO;
 	}
 	return 0;
 }
-
 /*
  * DKT 010817 - add support for V8 memory read/write and flash update
  */
 static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
 		flexcop_usb_request_t req, u8 page, u16 wAddress,
-		u8 *pbBuffer,u32 buflen)
+		u8 *pbBuffer, u32 buflen)
 {
-//	u8 dwRequestType;
 	u8 request_type = USB_TYPE_VENDOR;
 	u16 wIndex;
-	int nWaitTime,pipe,len;
-
+	int nWaitTime, pipe, len;
 	wIndex = page << 8;
 
 	switch (req) {
-		case B2C2_USB_READ_V8_MEM:
-			nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
-			request_type |= USB_DIR_IN;
-//			dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
-			pipe = B2C2_USB_CTRL_PIPE_IN;
+	case B2C2_USB_READ_V8_MEM:
+		nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+		request_type |= USB_DIR_IN;
+		pipe = B2C2_USB_CTRL_PIPE_IN;
 		break;
-		case B2C2_USB_WRITE_V8_MEM:
-			wIndex |= pbBuffer[0];
-			request_type |= USB_DIR_OUT;
-			nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-//			dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
-			pipe = B2C2_USB_CTRL_PIPE_OUT;
+	case B2C2_USB_WRITE_V8_MEM:
+		wIndex |= pbBuffer[0];
+		request_type |= USB_DIR_OUT;
+		nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+		pipe = B2C2_USB_CTRL_PIPE_OUT;
 		break;
-		case B2C2_USB_FLASH_BLOCK:
-			request_type |= USB_DIR_OUT;
-			nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-//			dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
-			pipe = B2C2_USB_CTRL_PIPE_OUT;
+	case B2C2_USB_FLASH_BLOCK:
+		request_type |= USB_DIR_OUT;
+		nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+		pipe = B2C2_USB_CTRL_PIPE_OUT;
 		break;
-		default:
-			deb_info("unsupported request for v8_mem_req %x.\n",req);
+	default:
+		deb_info("unsupported request for v8_mem_req %x.\n", req);
 		return -EINVAL;
 	}
-	deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req,
-			wAddress,wIndex,buflen);
+	deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+			wAddress, wIndex, buflen);
 
-	len = usb_control_msg(fc_usb->udev,pipe,
+	len = usb_control_msg(fc_usb->udev, pipe,
 			req,
 			request_type,
 			wAddress,
@@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(str
 			buflen,
 			nWaitTime * HZ);
 
-	debug_dump(pbBuffer,len,deb_v8);
-
+	debug_dump(pbBuffer, len, deb_v8);
 	return len == buflen ? 0 : -EIO;
 }
 
 #define bytes_left_to_read_on_page(paddr,buflen) \
-			((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
-			? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+	((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+	 ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
 
-static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req,
-		flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len)
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
+		flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
+		u32 addr, int extended, u8 *buf, u32 len)
 {
 	int i,ret = 0;
 	u16 wMax;
 	u32 pagechunk = 0;
 
 	switch(req) {
-		case B2C2_USB_READ_V8_MEM:  wMax = USB_MEM_READ_MAX; break;
-		case B2C2_USB_WRITE_V8_MEM:	wMax = USB_MEM_WRITE_MAX; break;
-		case B2C2_USB_FLASH_BLOCK:  wMax = USB_FLASH_MAX; break;
-		default:
-			return -EINVAL;
+	case B2C2_USB_READ_V8_MEM:
+		wMax = USB_MEM_READ_MAX;
+		break;
+	case B2C2_USB_WRITE_V8_MEM:
+		wMax = USB_MEM_WRITE_MAX;
+		break;
+	case B2C2_USB_FLASH_BLOCK:
+		wMax = USB_FLASH_MAX;
+		break;
+	default:
+		return -EINVAL;
 		break;
 	}
 	for (i = 0; i < len;) {
-		pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len);
-		deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended));
-		if ((ret = flexcop_usb_v8_memory_req(fc_usb,req,
-				page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */
-				(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended),
-				&buf[i],pagechunk)) < 0)
-			return ret;
+		pagechunk =
+			wMax < bytes_left_to_read_on_page(addr, len) ?
+				wMax :
+				bytes_left_to_read_on_page(addr, len);
+		deb_info("%x\n",
+			(addr & V8_MEMORY_PAGE_MASK) |
+				(V8_MEMORY_EXTENDED*extended));
+
+		ret = flexcop_usb_v8_memory_req(fc_usb, req,
+			page_start + (addr / V8_MEMORY_PAGE_SIZE),
+			(addr & V8_MEMORY_PAGE_MASK) |
+				(V8_MEMORY_EXTENDED*extended),
+			&buf[i], pagechunk);
 
+		if (ret < 0)
+			return ret;
 		addr += pagechunk;
 		len -= pagechunk;
 	}
@@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct
 
 static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
 {
-	return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM,
-			V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6);
+	return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
+		V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
+		fc->dvb_adapter.proposed_mac, 6);
 }
 
 #if 0
@@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struc
 {
 	u16 wValue;
 	u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-//	u8 dwRequestType = (u8) RTYPE_GENERIC,
 	int nWaitTime = 2,
-		pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
-		len;
-
+	    pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
 	wValue = (func << 8) | extra;
 
 	len = usb_control_msg(fc_usb->udev,pipe,
@@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct fl
 	struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
 	u16 wValue, wIndex;
 	int nWaitTime,pipe,len;
-//	u8 dwRequestType;
 	u8 request_type = USB_TYPE_VENDOR;
 
 	switch (func) {
-		case USB_FUNC_I2C_WRITE:
-		case USB_FUNC_I2C_MULTIWRITE:
-		case USB_FUNC_I2C_REPEATWRITE:
+	case USB_FUNC_I2C_WRITE:
+	case USB_FUNC_I2C_MULTIWRITE:
+	case USB_FUNC_I2C_REPEATWRITE:
 		/* DKT 020208 - add this to support special case of DiSEqC */
-		case USB_FUNC_I2C_CHECKWRITE:
-			pipe = B2C2_USB_CTRL_PIPE_OUT;
-			nWaitTime = 2;
-//			dwRequestType = (u8) RTYPE_GENERIC;
-			request_type |= USB_DIR_OUT;
+	case USB_FUNC_I2C_CHECKWRITE:
+		pipe = B2C2_USB_CTRL_PIPE_OUT;
+		nWaitTime = 2;
+		request_type |= USB_DIR_OUT;
 		break;
-		case USB_FUNC_I2C_READ:
-		case USB_FUNC_I2C_REPEATREAD:
-			pipe = B2C2_USB_CTRL_PIPE_IN;
-			nWaitTime = 2;
-//			dwRequestType = (u8) RTYPE_GENERIC;
-			request_type |= USB_DIR_IN;
+	case USB_FUNC_I2C_READ:
+	case USB_FUNC_I2C_REPEATREAD:
+		pipe = B2C2_USB_CTRL_PIPE_IN;
+		nWaitTime = 2;
+		request_type |= USB_DIR_IN;
 		break;
-		default:
-			deb_info("unsupported function for i2c_req %x\n",func);
-			return -EINVAL;
+	default:
+		deb_info("unsupported function for i2c_req %x\n", func);
+		return -EINVAL;
 	}
 	wValue = (func << 8) | (i2c->port << 4);
 	wIndex = (chipaddr << 8 ) | addr;
 
-	deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
-		wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
+	deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
+			func, request_type, req,
+			wValue & 0xff, wValue >> 8,
+			wIndex & 0xff, wIndex >> 8);
 
 	len = usb_control_msg(fc_usb->udev,pipe,
 			req,
@@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct fl
 			buf,
 			buflen,
 			nWaitTime * HZ);
-
 	return len == buflen ? 0 : -EREMOTEIO;
 }
 
-/* actual bus specific access functions, make sure prototype are/will be equal to pci */
-static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg)
+/* actual bus specific access functions,
+   make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
+	flexcop_ibi_register reg)
 {
 	flexcop_ibi_value val;
 	val.raw = 0;
-	flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1);
+	flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
 	return val;
 }
 
-static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val)
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
+		flexcop_ibi_register reg, flexcop_ibi_value val)
 {
-	return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
+	return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
 }
 
 static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
-	flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+		flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
 {
 	if (op == FC_READ)
 		return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
-			USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
+				USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
 	else
 		return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
-			USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
+				USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
 }
 
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
+	u8 *buffer, int buffer_length)
 {
 	u8 *b;
 	int l;
 
-	deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
+	deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
+		fc_usb->tmp_buffer_length, buffer_length);
 
 	if (fc_usb->tmp_buffer_length > 0) {
-		memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
+		memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
+				buffer_length);
 		fc_usb->tmp_buffer_length += buffer_length;
 		b = fc_usb->tmp_buffer;
 		l = fc_usb->tmp_buffer_length;
@@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(st
 	}
 
 	while (l >= 190) {
-		if (*b == 0xff)
+		if (*b == 0xff) {
 			switch (*(b+1) & 0x03) {
-				case 0x01: /* media packet */
-					if ( *(b+2) == 0x47 )
-						flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
-					else
-						deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
-
-					b += 190;
-					l -= 190;
+			case 0x01: /* media packet */
+				if (*(b+2) == 0x47)
+					flexcop_pass_dmx_packets(
+							fc_usb->fc_dev, b+2, 1);
+				else
+					deb_ts(
+					"not ts packet %02x %02x %02x %02x \n",
+						*(b+2), *(b+3),
+						*(b+4), *(b+5));
+				b += 190;
+				l -= 190;
 				break;
-				default:
-					deb_ts("wrong packet type\n");
-					l = 0;
+			default:
+				deb_ts("wrong packet type\n");
+				l = 0;
 				break;
 			}
-		else {
+		} else {
 			deb_ts("wrong header\n");
 			l = 0;
 		}
@@ -337,23 +353,26 @@ static void flexcop_usb_urb_complete(str
 	int i;
 
 	if (urb->actual_length > 0)
-		deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+		deb_ts("urb completed, bufsize: %d actlen; %d\n",
+			urb->transfer_buffer_length, urb->actual_length);
 
 	for (i = 0; i < urb->number_of_packets; i++) {
 		if (urb->iso_frame_desc[i].status < 0) {
-			err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status);
+			err("iso frame descriptor %d has an error: %d\n", i,
+				urb->iso_frame_desc[i].status);
 		} else
 			if (urb->iso_frame_desc[i].actual_length > 0) {
-				deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
+				deb_ts("passed %d bytes to the demux\n",
+					urb->iso_frame_desc[i].actual_length);
 
 				flexcop_usb_process_frame(fc_usb,
-					urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+					urb->transfer_buffer +
+						urb->iso_frame_desc[i].offset,
 					urb->iso_frame_desc[i].actual_length);
-		}
+			}
 		urb->iso_frame_desc[i].status = 0;
 		urb->iso_frame_desc[i].actual_length = 0;
 	}
-
 	usb_submit_urb(urb,GFP_ATOMIC);
 }
 
@@ -374,35 +393,47 @@ static void flexcop_usb_transfer_exit(st
 		}
 
 	if (fc_usb->iso_buffer != NULL)
-		pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+		pci_free_consistent(NULL,
+			fc_usb->buffer_size, fc_usb->iso_buffer,
+			fc_usb->dma_addr);
 }
 
 static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
 {
-	u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
-	int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
+	u16 frame_size = le16_to_cpu(
+		fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
+	int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
+		frame_size, i, j, ret;
 	int buffer_offset = 0;
 
-	deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
-			B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
+	deb_ts("creating %d iso-urbs with %d frames "
+			"each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
+			B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
 
-	fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);
+	fc_usb->iso_buffer = pci_alloc_consistent(NULL,
+			bufsize, &fc_usb->dma_addr);
 	if (fc_usb->iso_buffer == NULL)
 		return -ENOMEM;
+
 	memset(fc_usb->iso_buffer, 0, bufsize);
 	fc_usb->buffer_size = bufsize;
 
 	/* creating iso urbs */
-	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
-		if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
+	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+		fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+			GFP_ATOMIC);
+		if (fc_usb->iso_urb[i] == NULL) {
 			ret = -ENOMEM;
 			goto urb_error;
 		}
+	}
+
 	/* initialising and submitting iso urbs */
 	for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
 		int frame_offset = 0;
 		struct urb *urb = fc_usb->iso_urb[i];
-		deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
+		deb_ts("initializing and submitting urb no. %d "
+			"(buf_offset: %d).\n", i, buffer_offset);
 
 		urb->dev = fc_usb->udev;
 		urb->context = fc_usb;
@@ -416,26 +447,26 @@ static int flexcop_usb_transfer_init(str
 
 		buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
 		for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
-			deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
+			deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
+					i, j, frame_offset);
 			urb->iso_frame_desc[j].offset = frame_offset;
 			urb->iso_frame_desc[j].length = frame_size;
 			frame_offset += frame_size;
 		}
 
 		if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
-			err("submitting urb %d failed with %d.",i,ret);
+			err("submitting urb %d failed with %d.", i, ret);
 			goto urb_error;
 		}
 		deb_ts("submitted urb no. %d.\n",i);
 	}
 
-/* SRAM */
-
-	flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |
-			FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);
-	flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
-	flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
-
+	/* SRAM */
+	flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
+			FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
+			FC_SRAM_DEST_TARGET_WAN_USB);
+	flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
+	flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
 	return 0;
 
 urb_error:
@@ -448,20 +479,20 @@ static int flexcop_usb_init(struct flexc
 	/* use the alternate setting with the larges buffer */
 	usb_set_interface(fc_usb->udev,0,1);
 	switch (fc_usb->udev->speed) {
-		case USB_SPEED_LOW:
-			err("cannot handle USB speed because it is to sLOW.");
-			return -ENODEV;
-			break;
-		case USB_SPEED_FULL:
-			info("running at FULL speed.");
-			break;
-		case USB_SPEED_HIGH:
-			info("running at HIGH speed.");
-			break;
-		case USB_SPEED_UNKNOWN: /* fall through */
-		default:
-			err("cannot handle USB speed because it is unkown.");
-			return -ENODEV;
+	case USB_SPEED_LOW:
+		err("cannot handle USB speed because it is too slow.");
+		return -ENODEV;
+		break;
+	case USB_SPEED_FULL:
+		info("running at FULL speed.");
+		break;
+	case USB_SPEED_HIGH:
+		info("running at HIGH speed.");
+		break;
+	case USB_SPEED_UNKNOWN: /* fall through */
+	default:
+		err("cannot handle USB speed because it is unknown.");
+		return -ENODEV;
 	}
 	usb_set_intfdata(fc_usb->uintf, fc_usb);
 	return 0;
@@ -485,7 +516,7 @@ static int flexcop_usb_probe(struct usb_
 		return -ENOMEM;
 	}
 
-/* general flexcop init */
+	/* general flexcop init */
 	fc_usb = fc->bus_specific;
 	fc_usb->fc_dev = fc;
 
@@ -502,21 +533,21 @@ static int flexcop_usb_probe(struct usb_
 	fc->dev = &udev->dev;
 	fc->owner = THIS_MODULE;
 
-/* bus specific part */
+	/* bus specific part */
 	fc_usb->udev = udev;
 	fc_usb->uintf = intf;
 	if ((ret = flexcop_usb_init(fc_usb)) != 0)
 		goto err_kfree;
 
-/* init flexcop */
+	/* init flexcop */
 	if ((ret = flexcop_device_initialize(fc)) != 0)
 		goto err_usb_exit;
 
-/* xfer init */
+	/* xfer init */
 	if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
 		goto err_fc_exit;
 
-	info("%s successfully initialized and connected.",DRIVER_NAME);
+	info("%s successfully initialized and connected.", DRIVER_NAME);
 	return 0;
 
 err_fc_exit:
@@ -535,12 +566,12 @@ static void flexcop_usb_disconnect(struc
 	flexcop_device_exit(fc_usb->fc_dev);
 	flexcop_usb_exit(fc_usb);
 	flexcop_device_kfree(fc_usb->fc_dev);
-	info("%s successfully deinitialized and disconnected.",DRIVER_NAME);
+	info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
 }
 
 static struct usb_device_id flexcop_usb_table [] = {
-	    { USB_DEVICE(0x0af7, 0x0101) },
-	    { }
+	{ USB_DEVICE(0x0af7, 0x0101) },
+	{ }
 };
 MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
 
@@ -557,10 +588,9 @@ static int __init flexcop_usb_module_ini
 {
 	int result;
 	if ((result = usb_register(&flexcop_usb_driver))) {
-		err("usb_register failed. (%d)",result);
+		err("usb_register failed. (%d)", result);
 		return result;
 	}
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-usb.h linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-usb.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/flexcop-usb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/flexcop-usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,15 +1,20 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
 #ifndef __FLEXCOP_USB_H_INCLUDED__
 #define __FLEXCOP_USB_H_INCLUDED__
 
 #include <linux/usb.h>
 
 /* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO		4
-#define B2C2_USB_NUM_ISO_URB		4
+#define B2C2_USB_FRAMES_PER_ISO 4
+#define B2C2_USB_NUM_ISO_URB 4
 
-#define B2C2_USB_CTRL_PIPE_IN		usb_rcvctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_CTRL_PIPE_OUT		usb_sndctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_DATA_PIPE			usb_rcvisocpipe(fc_usb->udev,0x81)
+#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
 
 struct flexcop_usb {
 	struct usb_device *udev;
@@ -18,8 +23,8 @@ struct flexcop_usb {
 	u8 *iso_buffer;
 	int buffer_size;
 	dma_addr_t dma_addr;
-	struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
 
+	struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
 	struct flexcop_device *fc_dev;
 
 	u8 tmp_buffer[1023+190];
@@ -30,14 +35,6 @@ struct flexcop_usb {
 /* request types TODO What is its use?*/
 typedef enum {
 
-/* something is wrong with this part
-	RTYPE_READ_DW         = (1 << 6),
-	RTYPE_WRITE_DW_1      = (3 << 6),
-	RTYPE_READ_V8_MEMORY  = (6 << 6),
-	RTYPE_WRITE_V8_MEMORY = (7 << 6),
-	RTYPE_WRITE_V8_FLASH  = (8 << 6),
-	RTYPE_GENERIC         = (9 << 6),
-*/
 } flexcop_usb_request_type_t;
 #endif
 
@@ -47,7 +44,6 @@ typedef enum {
 	B2C2_USB_READ_V8_MEM  = 0x05,
 	B2C2_USB_READ_REG     = 0x08,
 	B2C2_USB_WRITE_REG    = 0x0A,
-/*	B2C2_USB_WRITEREGLO   = 0x0A, */
 	B2C2_USB_WRITEREGHI   = 0x0B,
 	B2C2_USB_FLASH_BLOCK  = 0x10,
 	B2C2_USB_I2C_REQUEST  = 0x11,
@@ -62,15 +58,13 @@ typedef enum {
 	USB_FUNC_I2C_REPEATWRITE = 0x04,
 	USB_FUNC_GET_DESCRIPTOR  = 0x05,
 	USB_FUNC_I2C_REPEATREAD  = 0x06,
-/* DKT 020208 - add this to support special case of DiSEqC */
+	/* DKT 020208 - add this to support special case of DiSEqC */
 	USB_FUNC_I2C_CHECKWRITE  = 0x07,
 	USB_FUNC_I2C_CHECKRESULT = 0x08,
 } flexcop_usb_i2c_function_t;
 
-/*
- * function definition for UTILITY request 0x12
- * DKT 020304 - new utility function
- */
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
 typedef enum {
 	UTILITY_SET_FILTER          = 0x01,
 	UTILITY_DATA_ENABLE         = 0x02,
@@ -84,7 +78,7 @@ typedef enum {
 	UTILITY_DATA_RESET          = 0x0A,
 	UTILITY_GET_DATA_STATUS     = 0x10,
 	UTILITY_GET_V8_REG          = 0x11,
-/* DKT 020326 - add function for v1.14 */
+	/* DKT 020326 - add function for v1.14 */
 	UTILITY_SRAM_WRITE          = 0x12,
 	UTILITY_SRAM_READ           = 0x13,
 	UTILITY_SRAM_TESTFILL       = 0x14,
@@ -92,13 +86,13 @@ typedef enum {
 	UTILITY_SRAM_TESTVERIFY     = 0x16,
 } flexcop_usb_utility_function_t;
 
-#define B2C2_WAIT_FOR_OPERATION_RW  1*HZ       /* 1 s */
-#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ       /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ       /* 1 s */
+#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
 
-#define B2C2_WAIT_FOR_OPERATION_V8READ   3*HZ  /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE  3*HZ  /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH  3*HZ  /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
 
 typedef enum {
 	V8_MEMORY_PAGE_DVB_CI = 0x20,
@@ -107,13 +101,11 @@ typedef enum {
 	V8_MEMORY_PAGE_FLASH  = 0x80
 } flexcop_usb_mem_page_t;
 
-#define V8_MEMORY_EXTENDED      (1 << 15)
-
-#define USB_MEM_READ_MAX                32
-#define USB_MEM_WRITE_MAX               1
-#define USB_FLASH_MAX                   8
-
-#define V8_MEMORY_PAGE_SIZE     0x8000      // 32K
-#define V8_MEMORY_PAGE_MASK     0x7FFF
+#define V8_MEMORY_EXTENDED (1 << 15)
+#define USB_MEM_READ_MAX   32
+#define USB_MEM_WRITE_MAX   1
+#define USB_FLASH_MAX       8
+#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
+#define V8_MEMORY_PAGE_MASK 0x7FFF
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP
 	select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
 	select DVB_ISL6421 if !DVB_FE_CUSTOMISE
 	select DVB_CX24123 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
 	help
 	  Support for the digital TV receiver chip made by B2C2 Inc. included in
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/Makefile linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/b2c2/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/b2c2/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe
 	flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
-
 ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
 b2c2-flexcop-objs += flexcop-dma.o
 endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/dst_ca.c linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/dst_ca.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/dst_ca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/dst_ca.c	2009-06-09 23:05:27.000000000 -0400
@@ -552,16 +552,19 @@ free_mem_and_exit:
 	return result;
 }
 
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
 {
-	struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
-	struct dst_state* state = (struct dst_state*) dvbdev->priv;
+	struct dvb_device *dvbdev;
+	struct dst_state *state;
 	struct ca_slot_info *p_ca_slot_info;
 	struct ca_caps *p_ca_caps;
 	struct ca_msg *p_ca_message;
 	void __user *arg = (void __user *)ioctl_arg;
 	int result = 0;
 
+	lock_kernel();
+	dvbdev = (struct dvb_device *)file->private_data;
+	state = (struct dst_state *)dvbdev->priv;
 	p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
 	p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
 	p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
@@ -647,6 +650,7 @@ static int dst_ca_ioctl(struct inode *in
 	kfree (p_ca_slot_info);
 	kfree (p_ca_caps);
 
+	unlock_kernel();
 	return result;
 }
 
@@ -682,9 +686,9 @@ static ssize_t dst_ca_write(struct file
 	return 0;
 }
 
-static struct file_operations dst_ca_fops = {
+static const struct file_operations dst_ca_fops = {
 	.owner = THIS_MODULE,
-	.ioctl = dst_ca_ioctl,
+	.unlocked_ioctl = dst_ca_ioctl,
 	.open = dst_ca_open,
 	.release = dst_ca_release,
 	.read = dst_ca_read,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2013-05-03 16:44:18.000000000 -0400
@@ -814,7 +814,7 @@ static int __devinit dvb_bt8xx_probe(str
 
 	mutex_init(&card->lock);
 	card->bttv_nr = sub->core->nr;
-	strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
+	strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
 	card->i2c_adapter = &sub->core->i2c_adap;
 
 	switch(sub->core->type) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/bt8xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/bt8xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@ config DVB_BT8XX
 	select DVB_OR51211 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are
 	  the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dm1105/dm1105.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dm1105/dm1105.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dm1105/dm1105.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dm1105/dm1105.c	2009-06-09 23:05:27.000000000 -0400
@@ -156,46 +156,12 @@ MODULE_PARM_DESC(ir_debug, "enable debug
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-static u16 ir_codes_dm1105_nec[128] = {
-	[0x0a] = KEY_Q,		/*power*/
-	[0x0c] = KEY_M,		/*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_PAGEUP,	/*ch+*/
-	[0x0f] = KEY_PAGEDOWN,	/*ch-*/
-	[0x1a] = KEY_O,		/*vol+*/
-	[0x0e] = KEY_Z,		/*vol-*/
-	[0x04] = KEY_R,		/*rec*/
-	[0x09] = KEY_D,		/*fav*/
-	[0x08] = KEY_BACKSPACE,	/*rewind*/
-	[0x07] = KEY_A,		/*fast*/
-	[0x0b] = KEY_P,		/*pause*/
-	[0x02] = KEY_ESC,	/*cancel*/
-	[0x03] = KEY_G,		/*tab*/
-	[0x00] = KEY_UP,	/*up*/
-	[0x1f] = KEY_ENTER,	/*ok*/
-	[0x01] = KEY_DOWN,	/*down*/
-	[0x05] = KEY_C,		/*cap*/
-	[0x06] = KEY_S,		/*stop*/
-	[0x40] = KEY_F,		/*full*/
-	[0x1e] = KEY_W,		/*tvmode*/
-	[0x1b] = KEY_B,		/*recall*/
-};
-
 /* infrared remote control */
 struct infrared {
-	u16	key_map[128];
 	struct input_dev	*input_dev;
+	struct ir_input_state	ir;
 	char			input_phys[32];
-	struct tasklet_struct	ir_tasklet;
+	struct work_struct	work;
 	u32			ir_command;
 };
 
@@ -220,10 +186,14 @@ struct dm1105dvb {
 	/* i2c */
 	struct i2c_adapter i2c_adap;
 
+	/* irq */
+	struct work_struct work;
+
 	/* dma */
 	dma_addr_t dma_addr;
 	unsigned char *ts_buf;
 	u32 wrp;
+	u32 nextwrp;
 	u32 buffer_size;
 	unsigned int	PacketErrorCount;
 	unsigned int dmarst;
@@ -233,8 +203,6 @@ struct dm1105dvb {
 
 #define dm_io_mem(reg)	((unsigned long)(&dm1105dvb->io_mem[reg]))
 
-static struct dm1105dvb *dm1105dvb_local;
-
 static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
 			    struct i2c_msg *msgs, int num)
 {
@@ -407,38 +375,61 @@ static int dm1105dvb_stop_feed(struct dv
 	return 0;
 }
 
-/* ir tasklet */
-static void dm1105_emit_key(unsigned long parm)
+/* ir work handler */
+static void dm1105_emit_key(struct work_struct *work)
 {
-	struct infrared *ir = (struct infrared *) parm;
+	struct infrared *ir = container_of(work, struct infrared, work);
 	u32 ircom = ir->ir_command;
 	u8 data;
-	u16 keycode;
+
+	if (ir_debug)
+		printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
 
 	data = (ircom >> 8) & 0x7f;
 
-	input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data);
-	input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
-	keycode = ir->key_map[data];
+	ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+	ir_input_nokey(ir->input_dev, &ir->ir);
+}
 
-	if (!keycode)
-		return;
+/* work handler */
+static void dm1105_dmx_buffer(struct work_struct *work)
+{
+	struct dm1105dvb *dm1105dvb =
+				container_of(work, struct dm1105dvb, work);
+	unsigned int nbpackets;
+	u32 oldwrp = dm1105dvb->wrp;
+	u32 nextwrp = dm1105dvb->nextwrp;
 
-	input_event(ir->input_dev, EV_KEY, keycode, 1);
-	input_sync(ir->input_dev);
-	input_event(ir->input_dev, EV_KEY, keycode, 0);
-	input_sync(ir->input_dev);
+	if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
+			(dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
+			(dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
+		dm1105dvb->PacketErrorCount++;
+		/* bad packet found */
+		if ((dm1105dvb->PacketErrorCount >= 2) &&
+				(dm1105dvb->dmarst == 0)) {
+			outb(1, dm_io_mem(DM1105_RST));
+			dm1105dvb->wrp = 0;
+			dm1105dvb->PacketErrorCount = 0;
+			dm1105dvb->dmarst = 0;
+			return;
+		}
+	}
 
+	if (nextwrp < oldwrp) {
+		memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
+						dm1105dvb->ts_buf, nextwrp);
+		nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
+	} else
+		nbpackets = (nextwrp - oldwrp) / 188;
+
+	dm1105dvb->wrp = nextwrp;
+	dvb_dmx_swfilter_packets(&dm1105dvb->demux,
+					&dm1105dvb->ts_buf[oldwrp], nbpackets);
 }
 
 static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
 {
 	struct dm1105dvb *dm1105dvb = dev_id;
-	unsigned int piece;
-	unsigned int nbpackets;
-	u32 command;
-	u32 nextwrp;
-	u32 oldwrp;
 
 	/* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
 	unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
@@ -447,71 +438,25 @@ static irqreturn_t dm1105dvb_irq(int irq
 	switch (intsts) {
 	case INTSTS_TSIRQ:
 	case (INTSTS_TSIRQ | INTSTS_IR):
-		nextwrp = inl(dm_io_mem(DM1105_WRP)) -
-			inl(dm_io_mem(DM1105_STADR)) ;
-		oldwrp = dm1105dvb->wrp;
-		spin_lock(&dm1105dvb->lock);
-		if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
-				(dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
-				(dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
-			dm1105dvb->PacketErrorCount++;
-			/* bad packet found */
-			if ((dm1105dvb->PacketErrorCount >= 2) &&
-					(dm1105dvb->dmarst == 0)) {
-				outb(1, dm_io_mem(DM1105_RST));
-				dm1105dvb->wrp = 0;
-				dm1105dvb->PacketErrorCount = 0;
-				dm1105dvb->dmarst = 0;
-				spin_unlock(&dm1105dvb->lock);
-				return IRQ_HANDLED;
-			}
-		}
-		if (nextwrp < oldwrp) {
-			piece = dm1105dvb->buffer_size - oldwrp;
-			memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp);
-			nbpackets = (piece + nextwrp)/188;
-		} else	{
-			nbpackets = (nextwrp - oldwrp)/188;
-		}
-		dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets);
-		dm1105dvb->wrp = nextwrp;
-		spin_unlock(&dm1105dvb->lock);
+		dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
+					inl(dm_io_mem(DM1105_STADR));
+		schedule_work(&dm1105dvb->work);
 		break;
 	case INTSTS_IR:
-		command = inl(dm_io_mem(DM1105_IRCODE));
-		if (ir_debug)
-			printk("dm1105: received byte 0x%04x\n", command);
-
-		dm1105dvb->ir.ir_command = command;
-		tasklet_schedule(&dm1105dvb->ir.ir_tasklet);
+		dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
+		schedule_work(&dm1105dvb->ir.work);
 		break;
 	}
-	return IRQ_HANDLED;
 
-
-}
-
-/* register with input layer */
-static void input_register_keys(struct infrared *ir)
-{
-	int i;
-
-	memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
-
-	for (i = 0; i < ARRAY_SIZE(ir->key_map); i++)
-			set_bit(ir->key_map[i], ir->input_dev->keybit);
-
-	ir->input_dev->keycode = ir->key_map;
-	ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
-	ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
+	return IRQ_HANDLED;
 }
 
 int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
 {
 	struct input_dev *input_dev;
-	int err;
-
-	dm1105dvb_local = dm1105;
+	IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
+	int ir_type = IR_TYPE_OTHER;
+	int err = -ENOMEM;
 
 	input_dev = input_allocate_device();
 	if (!input_dev)
@@ -521,12 +466,11 @@ int __devinit dm1105_ir_init(struct dm11
 	snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
 		"pci-%s/ir0", pci_name(dm1105->pdev));
 
-	input_dev->evbit[0] = BIT(EV_KEY);
+	ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
 	input_dev->name = "DVB on-card IR receiver";
-
 	input_dev->phys = dm1105->ir.input_phys;
 	input_dev->id.bustype = BUS_PCI;
-	input_dev->id.version = 2;
+	input_dev->id.version = 1;
 	if (dm1105->pdev->subsystem_vendor) {
 		input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
 		input_dev->id.product = dm1105->pdev->subsystem_device;
@@ -534,25 +478,22 @@ int __devinit dm1105_ir_init(struct dm11
 		input_dev->id.vendor = dm1105->pdev->vendor;
 		input_dev->id.product = dm1105->pdev->device;
 	}
+
 	input_dev->dev.parent = &dm1105->pdev->dev;
-	/* initial keymap */
-	memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map);
-	input_register_keys(&dm1105->ir);
+
+	INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
+
 	err = input_register_device(input_dev);
 	if (err) {
 		input_free_device(input_dev);
 		return err;
 	}
 
-	tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir);
-
 	return 0;
 }
 
-
 void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
 {
-	tasklet_kill(&dm1105->ir.ir_tasklet);
 	input_unregister_device(dm1105->ir.input_dev);
 
 }
@@ -710,7 +651,7 @@ static int __devinit dm1105_probe(struct
 
 	dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
 	if (!dm1105dvb)
-		goto out;
+		return -ENOMEM;
 
 	dm1105dvb->pdev = pdev;
 	dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
@@ -721,7 +662,7 @@ static int __devinit dm1105_probe(struct
 	if (ret < 0)
 		goto err_kfree;
 
-	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (ret < 0)
 		goto err_pci_disable_device;
 
@@ -740,13 +681,9 @@ static int __devinit dm1105_probe(struct
 	spin_lock_init(&dm1105dvb->lock);
 	pci_set_drvdata(pdev, dm1105dvb);
 
-	ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb);
-	if (ret < 0)
-		goto err_pci_iounmap;
-
 	ret = dm1105dvb_hw_init(dm1105dvb);
 	if (ret < 0)
-		goto err_free_irq;
+		goto err_pci_iounmap;
 
 	/* i2c */
 	i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
@@ -813,8 +750,15 @@ static int __devinit dm1105_probe(struct
 
 	dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
 	dm1105_ir_init(dm1105dvb);
-out:
-	return ret;
+
+	INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
+
+	ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
+						DRIVER_NAME, dm1105dvb);
+	if (ret < 0)
+		goto err_free_irq;
+
+	return 0;
 
 err_disconnect_frontend:
 	dmx->disconnect_frontend(dmx);
@@ -843,7 +787,7 @@ err_pci_disable_device:
 err_kfree:
 	pci_set_drvdata(pdev, NULL);
 	kfree(dm1105dvb);
-	goto out;
+	return ret;
 }
 
 static void __devexit dm1105_remove(struct pci_dev *pdev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dm1105/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/dm1105/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dm1105/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dm1105/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,7 @@ config DVB_DM1105
 	select DVB_STB6000 if !DVB_FE_CUSTOMISE
 	select DVB_CX24116 if !DVB_FE_CUSTOMISE
 	select DVB_SI21XX if !DVB_FE_CUSTOMISE
+	select VIDEO_IR
 	help
 	  Support for cards based on the SDMC DM1105 PCI chip like
 	  DvbWorld 2002
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dmxdev.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dmxdev.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dmxdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dmxdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -1024,7 +1024,7 @@ static int dvb_demux_release(struct inod
 	return ret;
 }
 
-static struct file_operations dvb_demux_fops = {
+static const struct file_operations dvb_demux_fops = {
 	.owner = THIS_MODULE,
 	.read = dvb_demux_read,
 	.ioctl = dvb_demux_ioctl,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_ca_en50221.c	2009-06-09 23:05:27.000000000 -0400
@@ -1607,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_po
 EXPORT_SYMBOL(dvb_ca_en50221_init);
 
 
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
 	.owner = THIS_MODULE,
 	.read = dvb_ca_en50221_io_read,
 	.write = dvb_ca_en50221_io_write,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvbdev.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvbdev.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvbdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvbdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapt
 	dvbdev->fops = dvbdevfops;
 	init_waitqueue_head (&dvbdev->wait_queue);
 
-	memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
-	dvbdev->fops->owner = adap->module;
+	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+	dvbdevfops->owner = adap->module;
 
 	list_add_tail (&dvbdev->list_head, &adap->device_list);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvbdev.h linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvbdev.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvbdev.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvbdev.h	2009-06-09 23:05:27.000000000 -0400
@@ -71,7 +71,7 @@ struct dvb_adapter {
 
 struct dvb_device {
 	struct list_head list_head;
-	struct file_operations *fops;
+	const struct file_operations *fops;
 	struct dvb_adapter *adapter;
 	int type;
 	int minor;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_frontend.c	2009-06-09 23:05:27.000000000 -0400
@@ -1875,7 +1875,7 @@ static int dvb_frontend_release(struct i
 	return ret;
 }
 
-static struct file_operations dvb_frontend_fops = {
+static const struct file_operations dvb_frontend_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= dvb_generic_ioctl,
 	.poll		= dvb_frontend_poll,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_net.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_net.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-core/dvb_net.c	2009-06-09 23:05:27.000000000 -0400
@@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *i
 }
 
 
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
 	.owner = THIS_MODULE,
 	.ioctl = dvb_net_ioctl,
 	.open =	dvb_generic_open,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/af9015.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/af9015.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 18:00:39.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/af9015.c	2013-05-03 16:44:30.000000000 -0400
@@ -27,9 +27,7 @@
 #include "qt1010.h"
 #include "tda18271.h"
 #include "mxl5005s.h"
-#if 0
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
 
 static int dvb_usb_af9015_debug;
 module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -37,9 +35,6 @@ MODULE_PARM_DESC(debug, "set debugging l
 static int dvb_usb_af9015_remote;
 module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
 MODULE_PARM_DESC(remote, "select remote");
-static int dvb_usb_af9015_dual_mode;
-module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
-MODULE_PARM_DESC(dual_mode, "enable dual mode");
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static DEFINE_MUTEX(af9015_usb_mutex);
@@ -283,6 +278,21 @@ Due to that the only way to select corre
 			req.data = &msg[i+1].buf[0];
 			ret = af9015_ctrl_msg(d, &req);
 			i += 2;
+		} else if (msg[i].flags & I2C_M_RD) {
+			ret = -EINVAL;
+			if (msg[i].addr ==
+				af9015_af9013_config[0].demod_address)
+				goto error;
+			else
+				req.cmd = READ_I2C;
+			req.i2c_addr = msg[i].addr;
+			req.addr = addr;
+			req.mbox = mbox;
+			req.addr_len = addr_len;
+			req.data_len = msg[i].len;
+			req.data = &msg[i].buf[0];
+			ret = af9015_ctrl_msg(d, &req);
+			i += 1;
 		} else {
 			if (msg[i].addr ==
 				af9015_af9013_config[0].demod_address)
@@ -748,6 +758,16 @@ static int af9015_read_config(struct usb
 				af9015_config.ir_table_size =
 				  ARRAY_SIZE(af9015_ir_table_digittrade);
 				break;
+			case AF9015_REMOTE_AVERMEDIA_KS:
+				af9015_properties[i].rc_key_map =
+				  af9015_rc_keys_avermedia;
+				af9015_properties[i].rc_key_map_size =
+				  ARRAY_SIZE(af9015_rc_keys_avermedia);
+				af9015_config.ir_table =
+				  af9015_ir_table_avermedia_ks;
+				af9015_config.ir_table_size =
+				  ARRAY_SIZE(af9015_ir_table_avermedia_ks);
+				break;
 			}
 		} else {
 			switch (le16_to_cpu(udev->descriptor.idVendor)) {
@@ -762,17 +782,14 @@ static int af9015_read_config(struct usb
 				  ARRAY_SIZE(af9015_ir_table_leadtek);
 				break;
 			case USB_VID_VISIONPLUS:
-				if (udev->descriptor.idProduct ==
-				cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) {
-					af9015_properties[i].rc_key_map =
-					  af9015_rc_keys_twinhan;
-					af9015_properties[i].rc_key_map_size =
-					  ARRAY_SIZE(af9015_rc_keys_twinhan);
-					af9015_config.ir_table =
-					  af9015_ir_table_twinhan;
-					af9015_config.ir_table_size =
-					  ARRAY_SIZE(af9015_ir_table_twinhan);
-				}
+				af9015_properties[i].rc_key_map =
+				  af9015_rc_keys_twinhan;
+				af9015_properties[i].rc_key_map_size =
+				  ARRAY_SIZE(af9015_rc_keys_twinhan);
+				af9015_config.ir_table =
+				  af9015_ir_table_twinhan;
+				af9015_config.ir_table_size =
+				  ARRAY_SIZE(af9015_ir_table_twinhan);
 				break;
 			case USB_VID_KWORLD_2:
 				/* TODO: use correct rc keys */
@@ -813,6 +830,16 @@ static int af9015_read_config(struct usb
 					  af9015_ir_table_msi;
 					af9015_config.ir_table_size =
 					  ARRAY_SIZE(af9015_ir_table_msi);
+				} else if (udev->descriptor.idProduct ==
+					cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
+					af9015_properties[i].rc_key_map =
+					  af9015_rc_keys_trekstor;
+					af9015_properties[i].rc_key_map_size =
+					  ARRAY_SIZE(af9015_rc_keys_trekstor);
+					af9015_config.ir_table =
+					  af9015_ir_table_trekstor;
+					af9015_config.ir_table_size =
+					  ARRAY_SIZE(af9015_ir_table_trekstor);
 				}
 				break;
 			case USB_VID_AVERMEDIA:
@@ -836,9 +863,6 @@ static int af9015_read_config(struct usb
 		goto error;
 	af9015_config.dual_mode = val;
 	deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
-	/* disable dual mode by default because it is buggy */
-	if (!dvb_usb_af9015_dual_mode)
-		af9015_config.dual_mode = 0;
 
 	/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
 	   size can be static because it is enabled only USB2.0 */
@@ -935,7 +959,6 @@ static int af9015_read_config(struct usb
 		switch (val) {
 		case AF9013_TUNER_ENV77H11D5:
 		case AF9013_TUNER_MT2060:
-		case AF9013_TUNER_MC44S803:
 		case AF9013_TUNER_QT1010:
 		case AF9013_TUNER_UNKNOWN:
 		case AF9013_TUNER_MT2060_2:
@@ -948,6 +971,10 @@ static int af9015_read_config(struct usb
 		case AF9013_TUNER_MXL5005R:
 			af9015_af9013_config[i].rf_spec_inv = 0;
 			break;
+		case AF9013_TUNER_MC44S803:
+			af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+			af9015_af9013_config[i].rf_spec_inv = 1;
+			break;
 		default:
 			warn("tuner id:%d not supported, please report!", val);
 			return -ENODEV;
@@ -961,6 +988,21 @@ error:
 	if (ret)
 		err("eeprom read failed:%d", ret);
 
+	/* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
+	   content :-( Override some wrong values here. */
+	if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
+	    le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) {
+		deb_info("%s: AverMedia A850: overriding config\n", __func__);
+		/* disable dual mode */
+		af9015_config.dual_mode = 0;
+		 /* disable 2nd adapter */
+		for (i = 0; i < af9015_properties_count; i++)
+			af9015_properties[i].num_adapters = 1;
+
+		/* set correct IF */
+		af9015_af9013_config[0].tuner_if = 4570;
+	}
+
 	return ret;
 }
 
@@ -1135,6 +1177,11 @@ static struct mxl5005s_config af9015_mxl
 	.AgcMasterByte   = 0x00,
 };
 
+static struct mc44s803_config af9015_mc44s803_config = {
+	.i2c_address = 0xc0,
+	.dig_out = 1,
+};
+
 static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	struct af9015_state *state = adap->dev->priv;
@@ -1179,15 +1226,8 @@ static int af9015_tuner_attach(struct dv
 			DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
 		break;
 	case AF9013_TUNER_MC44S803:
-#if 0
-		ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
-			== NULL ? -ENODEV : 0;
-#else
-		ret = -ENODEV;
-		info("Freescale MC44S803 tuner found but no driver for that" \
-			"tuner. Look at the Linuxtv.org for tuner driver" \
-			"status.");
-#endif
+		ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+			&af9015_mc44s803_config) == NULL ? -ENODEV : 0;
 		break;
 	case AF9013_TUNER_UNKNOWN:
 	default:
@@ -1218,6 +1258,10 @@ static struct usb_device_id af9015_usb_t
 	{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
 /* 15 */{USB_DEVICE(USB_VID_MSI_2,     USB_PID_MSI_DIGI_VOX_MINI_III)},
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_395U)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_395U_2)},
+	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_395U_3)},
+	{USB_DEVICE(USB_VID_AFATECH,   USB_PID_TREKSTOR_DVBT)},
+	{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
 	{0},
 };
 MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1382,7 +1426,7 @@ static struct dvb_usb_device_properties
 
 		.i2c_algo = &af9015_i2c_algo,
 
-		.num_device_descs = 7,
+		.num_device_descs = 9,
 		.devices = {
 			{
 				.name = "Xtensions XD-380",
@@ -1417,7 +1461,20 @@ static struct dvb_usb_device_properties
 			{
 				.name = "KWorld USB DVB-T TV Stick II " \
 					"(VS-DVB-T 395U)",
-				.cold_ids = {&af9015_usb_table[16], NULL},
+				.cold_ids = {&af9015_usb_table[16],
+					     &af9015_usb_table[17],
+					     &af9015_usb_table[18], NULL},
+				.warm_ids = {NULL},
+			},
+			{
+				.name = "TrekStor DVB-T USB Stick",
+				.cold_ids = {&af9015_usb_table[19], NULL},
+				.warm_ids = {NULL},
+			},
+			{
+				.name = "AverMedia AVerTV Volar Black HD " \
+					"(A850)",
+				.cold_ids = {&af9015_usb_table[20], NULL},
 				.warm_ids = {NULL},
 			},
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/af9015.h linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/af9015.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/af9015.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,14 +64,6 @@
 
 #define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
 
-#define AF9015_GPIO_ON (1 << 0)
-#define AF9015_GPIO_EN (1 << 1)
-#define AF9015_GPIO_O  (1 << 2)
-#define AF9015_GPIO_I  (1 << 3)
-
-#define AF9015_GPIO_TUNER_ON  (AF9015_GPIO_ON|AF9015_GPIO_EN)
-#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O)
-
 struct req_t {
 	u8  cmd;       /* [0] */
 	/*  seq */     /* [1] */
@@ -120,10 +112,11 @@ struct af9015_config {
 
 enum af9015_remote {
 	AF9015_REMOTE_NONE                    = 0,
-	AF9015_REMOTE_A_LINK_DTU_M,
+/* 1 */	AF9015_REMOTE_A_LINK_DTU_M,
 	AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
 	AF9015_REMOTE_MYGICTV_U718,
 	AF9015_REMOTE_DIGITTRADE_DVB_T,
+/* 5 */	AF9015_REMOTE_AVERMEDIA_KS,
 };
 
 /* Leadtek WinFast DTV Dongle Gold */
@@ -597,6 +590,36 @@ static u8 af9015_ir_table_avermedia[] =
 	0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
 };
 
+static u8 af9015_ir_table_avermedia_ks[] = {
+	0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
+	0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
+	0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
+	0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
+	0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
+	0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
+	0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
+	0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
+	0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
+	0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
+	0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
+	0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
+	0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
+	0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
+	0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
+	0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
+	0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
+	0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
+	0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
+	0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
+	0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
+	0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
+	0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
+	0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
+	0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
+	0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
+	0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
+};
+
 /* Digittrade DVB-T USB Stick */
 static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
 	{ 0x01, 0x0f, KEY_LAST },	/* RETURN */
@@ -660,4 +683,67 @@ static u8 af9015_ir_table_digittrade[] =
 	0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00,
 };
 
+/* TREKSTOR DVB-T USB Stick */
+static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = {
+	{ 0x07, 0x04, KEY_AGAIN },		/* Home */
+	{ 0x07, 0x05, KEY_MUTE },		/* Mute */
+	{ 0x07, 0x06, KEY_UP },			/* Up */
+	{ 0x07, 0x07, KEY_DOWN },		/* Down */
+	{ 0x07, 0x09, KEY_RIGHT },		/* Right */
+	{ 0x07, 0x0a, KEY_ENTER },		/* OK */
+	{ 0x07, 0x0b, KEY_FASTFORWARD },	/* Fast forward */
+	{ 0x07, 0x0c, KEY_REWIND },		/* Rewind */
+	{ 0x07, 0x0d, KEY_PLAY },		/* Play/Pause */
+	{ 0x07, 0x0e, KEY_VOLUMEUP },		/* Volume + */
+	{ 0x07, 0x0f, KEY_VOLUMEDOWN },		/* Volume - */
+	{ 0x07, 0x10, KEY_RECORD },		/* Record */
+	{ 0x07, 0x11, KEY_STOP },		/* Stop */
+	{ 0x07, 0x12, KEY_ZOOM },		/* TV */
+	{ 0x07, 0x13, KEY_EPG },		/* Info/EPG */
+	{ 0x07, 0x14, KEY_CHANNELDOWN },	/* Channel - */
+	{ 0x07, 0x15, KEY_CHANNELUP },		/* Channel + */
+	{ 0x07, 0x1e, KEY_1 },
+	{ 0x07, 0x1f, KEY_2 },
+	{ 0x07, 0x20, KEY_3 },
+	{ 0x07, 0x21, KEY_4 },
+	{ 0x07, 0x22, KEY_5 },
+	{ 0x07, 0x23, KEY_6 },
+	{ 0x07, 0x24, KEY_7 },
+	{ 0x07, 0x25, KEY_8 },
+	{ 0x07, 0x26, KEY_9 },
+	{ 0x07, 0x08, KEY_LEFT },		/* LEFT */
+	{ 0x07, 0x27, KEY_0 },
+};
+
+static u8 af9015_ir_table_trekstor[] = {
+	0x00, 0xff, 0x86, 0x79, 0x04, 0x07, 0x00,
+	0x00, 0xff, 0x85, 0x7a, 0x05, 0x07, 0x00,
+	0x00, 0xff, 0x87, 0x78, 0x06, 0x07, 0x00,
+	0x00, 0xff, 0x8c, 0x73, 0x07, 0x07, 0x00,
+	0x00, 0xff, 0x89, 0x76, 0x09, 0x07, 0x00,
+	0x00, 0xff, 0x88, 0x77, 0x0a, 0x07, 0x00,
+	0x00, 0xff, 0x8a, 0x75, 0x0b, 0x07, 0x00,
+	0x00, 0xff, 0x9e, 0x61, 0x0c, 0x07, 0x00,
+	0x00, 0xff, 0x8d, 0x72, 0x0d, 0x07, 0x00,
+	0x00, 0xff, 0x8b, 0x74, 0x0e, 0x07, 0x00,
+	0x00, 0xff, 0x9b, 0x64, 0x0f, 0x07, 0x00,
+	0x00, 0xff, 0x9d, 0x62, 0x10, 0x07, 0x00,
+	0x00, 0xff, 0x8e, 0x71, 0x11, 0x07, 0x00,
+	0x00, 0xff, 0x9c, 0x63, 0x12, 0x07, 0x00,
+	0x00, 0xff, 0x8f, 0x70, 0x13, 0x07, 0x00,
+	0x00, 0xff, 0x93, 0x6c, 0x14, 0x07, 0x00,
+	0x00, 0xff, 0x97, 0x68, 0x15, 0x07, 0x00,
+	0x00, 0xff, 0x92, 0x6d, 0x1e, 0x07, 0x00,
+	0x00, 0xff, 0x96, 0x69, 0x1f, 0x07, 0x00,
+	0x00, 0xff, 0x9a, 0x65, 0x20, 0x07, 0x00,
+	0x00, 0xff, 0x91, 0x6e, 0x21, 0x07, 0x00,
+	0x00, 0xff, 0x95, 0x6a, 0x22, 0x07, 0x00,
+	0x00, 0xff, 0x99, 0x66, 0x23, 0x07, 0x00,
+	0x00, 0xff, 0x90, 0x6f, 0x24, 0x07, 0x00,
+	0x00, 0xff, 0x94, 0x6b, 0x25, 0x07, 0x00,
+	0x00, 0xff, 0x98, 0x67, 0x26, 0x07, 0x00,
+	0x00, 0xff, 0x9f, 0x60, 0x08, 0x07, 0x00,
+	0x00, 0xff, 0x84, 0x7b, 0x27, 0x07, 0x00,
+};
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/ce6230.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/ce6230.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/ce6230.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/ce6230.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,334 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * 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 "ce6230.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ce6230_debug;
+module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
+{
+	int ret;
+	unsigned int pipe;
+	u8 request;
+	u8 requesttype;
+	u16 value;
+	u16 index;
+	u8 buf[req->data_len];
+
+	request = req->cmd;
+	value = req->value;
+	index = req->index;
+
+	switch (req->cmd) {
+	case I2C_READ:
+	case DEMOD_READ:
+	case REG_READ:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+		break;
+	case I2C_WRITE:
+	case DEMOD_WRITE:
+	case REG_WRITE:
+		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+		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->data_len);
+		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, value, index,
+				buf, sizeof(buf), CE6230_USB_TIMEOUT);
+
+	ce6230_debug_dump(request, requesttype, value, index, buf,
+		req->data_len, deb_xfer);
+
+	if (ret < 0)
+		deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
+	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->data_len);
+
+error:
+	return ret;
+}
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+	return ce6230_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+			   int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i = 0;
+	struct req_t req;
+	int ret = 0;
+	memset(&req, 0, sizeof(&req));
+
+	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 ==
+				ce6230_zl10353_config.demod_address) {
+				req.cmd = DEMOD_READ;
+				req.value = msg[i].addr >> 1;
+				req.index = msg[i].buf[0];
+				req.data_len = msg[i+1].len;
+				req.data = &msg[i+1].buf[0];
+				ret = ce6230_ctrl_msg(d, &req);
+			} else {
+				err("i2c read not implemented");
+				ret = -EPERM;
+			}
+			i += 2;
+		} else {
+			if (msg[i].addr ==
+				ce6230_zl10353_config.demod_address) {
+				req.cmd = DEMOD_WRITE;
+				req.value = msg[i].addr >> 1;
+				req.index = msg[i].buf[0];
+				req.data_len = msg[i].len-1;
+				req.data = &msg[i].buf[1];
+				ret = ce6230_ctrl_msg(d, &req);
+			} else {
+				req.cmd = I2C_WRITE;
+				req.value = 0x2000 + (msg[i].addr >> 1);
+				req.index = 0x0000;
+				req.data_len = msg[i].len;
+				req.data = &msg[i].buf[0];
+				ret = ce6230_ctrl_msg(d, &req);
+			}
+			i += 1;
+		}
+		if (ret)
+			break;
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algo = {
+	.master_xfer   = ce6230_i2c_xfer,
+	.functionality = ce6230_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+	.demod_address = 0x1e,
+	.adc_clock = 450000,
+	.if2 = 45700,
+	.no_tuner = 1,
+	.parallel_ts = 1,
+	.clock_ctl_1 = 0x34,
+	.pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("%s:\n", __func__);
+	adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+		&adap->dev->i2c_adap);
+	if (adap->fe == NULL)
+		return -ENODEV;
+	return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_config = {
+	.i2c_address     = 0xc6,
+	.if_freq         = IF_FREQ_4570000HZ,
+	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+	.agc_mode        = MXL_SINGLE_AGC,
+	.tracking_filter = MXL_TF_DEFAULT,
+	.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 ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	int ret;
+	deb_info("%s:\n", __func__);
+	ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+			&ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+	return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	int ret;
+	deb_info("%s: onoff:%d\n", __func__, onoff);
+
+	/* InterfaceNumber 1 / AlternateSetting 0     idle
+	   InterfaceNumber 1 / AlternateSetting 1     streaming */
+	ret = usb_set_interface(d->udev, 1, onoff);
+	if (ret)
+		err("usb_set_interface failed with error:%d", ret);
+
+	return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_properties;
+
+static int ce6230_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	int ret = 0;
+	struct dvb_usb_device *d = NULL;
+
+	deb_info("%s: interface:%d\n", __func__,
+		intf->cur_altsetting->desc.bInterfaceNumber);
+
+	if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+		ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
+			&d, adapter_nr);
+		if (ret)
+			err("init failed with error:%d\n", ret);
+	}
+
+	return ret;
+}
+
+static struct usb_device_id ce6230_table[] = {
+	{ USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+	{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) },
+	{ } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ce6230_table);
+
+static struct dvb_usb_device_properties ce6230_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.no_reconnect = 1,
+
+	.size_of_priv = 0,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.frontend_attach  = ce6230_zl10353_frontend_attach,
+			.tuner_attach     = ce6230_mxl5003s_tuner_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 6,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 512,
+					}
+				}
+			},
+		}
+	},
+
+	.power_ctrl = ce6230_power_ctrl,
+
+	.i2c_algo = &ce6230_i2c_algo,
+
+	.num_device_descs = 2,
+	.devices = {
+		{
+			.name = "Intel CE9500 reference design",
+			.cold_ids = {NULL},
+			.warm_ids = {&ce6230_table[0], NULL},
+		},
+		{
+			.name = "AVerMedia A310 USB 2.0 DVB-T tuner",
+			.cold_ids = {NULL},
+			.warm_ids = {&ce6230_table[1], NULL},
+		},
+	}
+};
+
+static struct usb_driver ce6230_driver = {
+	.name       = "dvb_usb_ce6230",
+	.probe      = ce6230_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table   = ce6230_table,
+};
+
+/* module stuff */
+static int __init ce6230_module_init(void)
+{
+	int ret;
+	deb_info("%s:\n", __func__);
+	ret = usb_register(&ce6230_driver);
+	if (ret)
+		err("usb_register failed with error:%d", ret);
+
+	return ret;
+}
+
+static void __exit ce6230_module_exit(void)
+{
+	deb_info("%s:\n", __func__);
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&ce6230_driver);
+}
+
+module_init(ce6230_module_init);
+module_exit(ce6230_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/ce6230.h linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/ce6230.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/ce6230.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/ce6230.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * 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 _DVB_USB_CE6230_H_
+#define _DVB_USB_CE6230_H_
+
+#define DVB_USB_LOG_PREFIX "ce6230"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
+#define deb_rc(args...)   dprintk(dvb_usb_ce6230_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
+#define deb_reg(args...)  dprintk(dvb_usb_ce6230_debug, 0x08, args)
+#define deb_i2c(args...)  dprintk(dvb_usb_ce6230_debug, 0x10, args)
+#define deb_fw(args...)   dprintk(dvb_usb_ce6230_debug, 0x20, args)
+
+#define ce6230_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 CE6230_USB_TIMEOUT 1000
+
+struct req_t {
+	u8  cmd;       /* [1] */
+	u16 value;     /* [2|3] */
+	u16 index;     /* [4|5] */
+	u16 data_len;  /* [6|7] */
+	u8  *data;
+};
+
+enum ce6230_cmd {
+	CONFIG_READ          = 0xd0, /* rd 0 (unclear) */
+	UNKNOWN_WRITE        = 0xc7, /* wr 7 (unclear) */
+	I2C_READ             = 0xd9, /* rd 9 (unclear) */
+	I2C_WRITE            = 0xca, /* wr a */
+	DEMOD_READ           = 0xdb, /* rd b */
+	DEMOD_WRITE          = 0xcc, /* wr c */
+	REG_READ             = 0xde, /* rd e */
+	REG_WRITE            = 0xcf, /* wr f */
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dib0700_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i
 				err("i2c read error (status = %d)\n", result);
 				break;
 			}
+
+			deb_data("<<< ");
+			debug_dump(msg[i].buf, msg[i].len, deb_data);
+
 		} else {
 			/* Write request */
 			buf[0] = REQUEST_NEW_I2C_WRITE;
@@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i
 			/* The Actual i2c payload */
 			memcpy(&buf[4], msg[i].buf, msg[i].len);
 
+			deb_data(">>> ");
+			debug_dump(buf, msg[i].len + 4, deb_data);
+
 			result = usb_control_msg(d->udev,
 						 usb_sndctrlpipe(d->udev, 0),
 						 REQUEST_NEW_I2C_WRITE,
@@ -211,7 +218,8 @@ static int dib0700_i2c_xfer_legacy(struc
 
 			/* special thing in the current firmware: when length is zero the read-failed */
 			if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
-				deb_info("I2C read failed on address %x\n", msg[i].addr);
+				deb_info("I2C read failed on address 0x%02x\n",
+					 msg[i].addr);
 				break;
 			}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 18:00:44.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dib0700_devices.c	2013-05-03 16:44:35.000000000 -0400
@@ -17,6 +17,8 @@
 #include "xc5000.h"
 #include "s5h1411.h"
 #include "dib0070.h"
+#include "lgdt3305.h"
+#include "mxl5007t.h"
 
 static int force_lna_activation;
 module_param(force_lna_activation, int, 0644);
@@ -262,7 +264,12 @@ static int stk7700P2_frontend_attach(str
 		msleep(10);
 		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
 		msleep(10);
-		dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
+		if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+					     stk7700d_dib7000p_mt2266_config)
+		    != 0) {
+			err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+			return -ENODEV;
+		}
 	}
 
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -284,7 +291,12 @@ static int stk7700d_frontend_attach(stru
 		dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
 		msleep(10);
 		dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
-		dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
+		if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+					     stk7700d_dib7000p_mt2266_config)
+		    != 0) {
+			err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
+			return -ENODEV;
+		}
 	}
 
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -421,8 +433,12 @@ static int stk7700ph_frontend_attach(str
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 	msleep(10);
 
-	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-		&stk7700ph_dib7700_xc3028_config);
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+				     &stk7700ph_dib7700_xc3028_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+		    __func__);
+		return -ENODEV;
+	}
 
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
 		&stk7700ph_dib7700_xc3028_config);
@@ -1187,8 +1203,12 @@ static int stk7070p_frontend_attach(stru
 	msleep(10);
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
-	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-		&dib7070p_dib7000p_config);
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+				     &dib7070p_dib7000p_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+		    __func__);
+		return -ENODEV;
+	}
 
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
 		&dib7070p_dib7000p_config);
@@ -1244,7 +1264,12 @@ static int stk7070pd_frontend_attach0(st
 	msleep(10);
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
-	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+				     stk7070pd_dib7000p_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+		    __func__);
+		return -ENODEV;
+	}
 
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
 	return adap->fe == NULL ? -ENODEV : 0;
@@ -1347,6 +1372,72 @@ static int xc5000_tuner_attach(struct dv
 		== NULL ? -ENODEV : 0;
 }
 
+static struct lgdt3305_config hcw_lgdt3305_config = {
+	.i2c_addr           = 0x0e,
+	.mpeg_mode          = LGDT3305_MPEG_PARALLEL,
+	.tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
+	.tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
+	.deny_i2c_rptr      = 0,
+	.spectral_inversion = 1,
+	.qam_if_khz         = 6000,
+	.vsb_if_khz         = 6000,
+	.usref_8vsb         = 0x0500,
+};
+
+static struct mxl5007t_config hcw_mxl5007t_config = {
+	.xtal_freq_hz = MxL_XTAL_25_MHZ,
+	.if_freq_hz = MxL_IF_6_MHZ,
+	.invert_if = 1,
+};
+
+/* TIGER-ATSC map:
+   GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
+   GPIO1  - ANT_SEL  (H: VPA, L: MCX)
+   GPIO4  - SCL2
+   GPIO6  - EN_TUNER
+   GPIO7  - SDA2
+   GPIO10 - DEM_RST
+
+   MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
+ */
+static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_state *st = adap->dev->priv;
+
+	/* Make use of the new i2c functions from FW 1.20 */
+	st->fw_use_new_i2c_api = 1;
+
+	st->disable_streaming_master_mode = 1;
+
+	/* fe power enable */
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(30);
+
+	/* demod reset */
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(30);
+
+	adap->fe = dvb_attach(lgdt3305_attach,
+			      &hcw_lgdt3305_config,
+			      &adap->dev->i2c_adap);
+
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	return dvb_attach(mxl5007t_attach, adap->fe,
+			  &adap->dev->i2c_adap, 0x60,
+			  &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
+}
+
+
 /* DVB-USB and USB stuff follows */
 struct usb_device_id dib0700_usb_id_table[] = {
 /* 0 */	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
@@ -1396,6 +1487,12 @@ struct usb_device_id dib0700_usb_id_tabl
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
 	{ USB_DEVICE(USB_VID_TERRATEC,
 			USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
+	{ USB_DEVICE(USB_VID_SONY,	USB_PID_SONY_PLAYTV) },
+/* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+	{ USB_DEVICE(USB_VID_YUAN,	USB_PID_YUAN_MC770) },
+	{ USB_DEVICE(USB_VID_ELGATO,	USB_PID_ELGATO_EYETV_DTT) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1595,7 +1692,7 @@ struct dvb_usb_device_properties dib0700
 			},
 		},
 
-		.num_device_descs = 9,
+		.num_device_descs = 11,
 		.devices = {
 			{   "DiBcom STK7070P reference design",
 				{ &dib0700_usb_id_table[15], NULL },
@@ -1633,6 +1730,14 @@ struct dvb_usb_device_properties dib0700
 				{ &dib0700_usb_id_table[33], NULL },
 				{ NULL },
 			},
+			{   "Elgato EyeTV DTT",
+				{ &dib0700_usb_id_table[49], NULL },
+				{ NULL },
+			},
+			{   "Yuan PD378S",
+				{ &dib0700_usb_id_table[45], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -1661,7 +1766,7 @@ struct dvb_usb_device_properties dib0700
 			}
 		},
 
-		.num_device_descs = 5,
+		.num_device_descs = 6,
 		.devices = {
 			{   "DiBcom STK7070PD reference design",
 				{ &dib0700_usb_id_table[17], NULL },
@@ -1682,8 +1787,16 @@ struct dvb_usb_device_properties dib0700
 			{  "Terratec Cinergy DT USB XS Diversity",
 				{ &dib0700_usb_id_table[43], NULL },
 				{ NULL },
+			},
+			{  "Sony PlayTV",
+				{ &dib0700_usb_id_table[44], NULL },
+				{ 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,
@@ -1699,7 +1812,7 @@ struct dvb_usb_device_properties dib0700
 			},
 		},
 
-		.num_device_descs = 5,
+		.num_device_descs = 7,
 		.devices = {
 			{   "Terratec Cinergy HT USB XE",
 				{ &dib0700_usb_id_table[27], NULL },
@@ -1725,6 +1838,10 @@ struct dvb_usb_device_properties dib0700
 				{ &dib0700_usb_id_table[39], NULL },
 				{ NULL },
 			},
+			{   "YUAN High-Tech MC770",
+				{ &dib0700_usb_id_table[48], NULL },
+				{ NULL },
+			},
 		},
 		.rc_interval      = DEFAULT_RC_INTERVAL,
 		.rc_key_map       = dib0700_rc_keys,
@@ -1759,6 +1876,31 @@ struct dvb_usb_device_properties dib0700
 		.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 = {
+			{
+				.frontend_attach  = lgdt3305_frontend_attach,
+				.tuner_attach     = mxl5007t_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv = sizeof(struct
+						dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 2,
+		.devices = {
+			{   "Hauppauge ATSC MiniCard (B200)",
+				{ &dib0700_usb_id_table[46], NULL },
+				{ NULL },
+			},
+			{   "Hauppauge ATSC MiniCard (B210)",
+				{ &dib0700_usb_id_table[47], NULL },
+				{ NULL },
+			},
+		},
 	},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dvb-usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
 	int generic_bulk_ctrl_endpoint;
 
 	int num_device_descs;
-	struct dvb_usb_device_description devices[9];
+	struct dvb_usb_device_description devices[11];
 };
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,12 +27,14 @@
 #define USB_VID_DIBCOM				0x10b8
 #define USB_VID_DPOSH				0x1498
 #define USB_VID_DVICO				0x0fe9
+#define USB_VID_ELGATO				0x0fd9
 #define USB_VID_EMPIA				0xeb1a
 #define USB_VID_GENPIX				0x09c0
 #define USB_VID_GRANDTEC			0x5032
 #define USB_VID_HANFTEK				0x15f4
 #define USB_VID_HAUPPAUGE			0x2040
 #define USB_VID_HYPER_PALTEK			0x1025
+#define USB_VID_INTEL				0x8086
 #define USB_VID_KWORLD				0xeb2a
 #define USB_VID_KWORLD_2			0x1b80
 #define USB_VID_KYE				0x0458
@@ -48,6 +50,7 @@
 #define USB_VID_TERRATEC			0x0ccd
 #define USB_VID_TELESTAR			0x10b9
 #define USB_VID_VISIONPLUS			0x13d3
+#define USB_VID_SONY				0x1415
 #define USB_VID_TWINHAN				0x1822
 #define USB_VID_ULTIMA_ELECTRONIC		0x05d8
 #define USB_VID_UNIWILL				0x1584
@@ -62,6 +65,7 @@
 #define USB_PID_AFATECH_AF9005				0x9020
 #define USB_PID_AFATECH_AF9015_9015			0x9015
 #define USB_PID_AFATECH_AF9015_9016			0x9016
+#define USB_PID_TREKSTOR_DVBT				0x901b
 #define USB_VID_ALINK_DTU				0xf170
 #define USB_PID_ANSONIC_DVBT_USB			0x6000
 #define USB_PID_ANYSEE					0x861f
@@ -95,8 +99,11 @@
 #define USB_PID_UNIWILL_STK7700P			0x6003
 #define USB_PID_GRANDTEC_DVBT_USB_COLD			0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM			0x0fa1
+#define USB_PID_INTEL_CE9500				0x9500
 #define USB_PID_KWORLD_399U				0xe399
 #define USB_PID_KWORLD_395U				0xe396
+#define USB_PID_KWORLD_395U_2				0xe39b
+#define USB_PID_KWORLD_395U_3				0xe395
 #define USB_PID_KWORLD_PC160_2T				0xc160
 #define USB_PID_KWORLD_VSTREAM_COLD			0x17de
 #define USB_PID_KWORLD_VSTREAM_WARM			0x17df
@@ -149,6 +156,8 @@
 #define USB_PID_HAUPPAUGE_MYTV_T			0x7080
 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK			0x9580
 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009		0x5200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC			0xb200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210		0xb210
 #define USB_PID_AVERMEDIA_EXPRESS			0xb568
 #define USB_PID_AVERMEDIA_VOLAR				0xa807
 #define USB_PID_AVERMEDIA_VOLAR_2			0xb808
@@ -160,6 +169,8 @@
 #define USB_PID_AVERMEDIA_VOLAR_X			0xa815
 #define USB_PID_AVERMEDIA_VOLAR_X_2			0x8150
 #define USB_PID_AVERMEDIA_A309				0xa309
+#define USB_PID_AVERMEDIA_A310				0xa310
+#define USB_PID_AVERMEDIA_A850				0x850a
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081
@@ -232,9 +243,13 @@
 #define USB_PID_ASUS_U3100				0x173f
 #define USB_PID_YUAN_EC372S				0x1edc
 #define USB_PID_YUAN_STK7700PH				0x1f08
+#define USB_PID_YUAN_PD378S				0x2edc
+#define USB_PID_YUAN_MC770				0x0871
 #define USB_PID_DW2102					0x2102
 #define USB_PID_XTENSIONS_XD_380			0x0381
 #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_ELGATO_EYETV_DTT			0x0021
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@ config DVB_USB_A800
 	depends on DVB_USB
 	select DVB_DIB3000MC
 	select DVB_PLL if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
 
@@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB
 	depends on DVB_USB
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_DIB3000MB
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC
 	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
 	depends on DVB_USB
 	select DVB_DIB3000MC
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Support for USB2.0 DVB-T receivers based on reference designs made by
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -69,15 +69,17 @@ config DVB_USB_DIBUSB_MC
 config DVB_USB_DIB0700
 	tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
 	depends on DVB_USB
-	select DVB_DIB7000P
-	select DVB_DIB7000M
-	select DVB_DIB3000MC
+	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+	select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+	select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
 	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
-	select DVB_TUNER_DIB0070
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+	select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+	select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
 	  USB bridge is also present in devices having the DiB7700 DVB-T-USB
@@ -95,7 +97,8 @@ config DVB_USB_UMT_010
 	depends on DVB_USB
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_DIB3000MC
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
 
@@ -108,10 +111,11 @@ 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 MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MXL5005S 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
@@ -125,8 +129,8 @@ config DVB_USB_M920X
 	depends on DVB_USB
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
 	  Currently, only devices with a product id of
@@ -137,7 +141,7 @@ config DVB_USB_GL861
 	tristate "Genesys Logic GL861 USB2.0 support"
 	depends on DVB_USB
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
 	  receiver with USB ID 0db0:5581.
@@ -146,7 +150,7 @@ config DVB_USB_AU6610
 	tristate "Alcor Micro AU6610 USB2.0 support"
 	depends on DVB_USB
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
 
@@ -199,7 +203,7 @@ config DVB_USB_NOVA_T_USB2
 	depends on DVB_USB
 	select DVB_DIB3000MC
 	select DVB_PLL if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
 
@@ -235,8 +239,8 @@ config DVB_USB_OPERA1
 config DVB_USB_AF9005
 	tristate "Afatech AF9005 DVB-T USB1.1 support"
 	depends on DVB_USB && EXPERIMENTAL
-	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
 	  and the TerraTec Cinergy T USB XE (Rev.1)
@@ -284,18 +288,27 @@ config DVB_USB_DTV5100
 	tristate "AME DTV-5100 USB2.0 DVB-T support"
 	depends on DVB_USB
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
 
 config DVB_USB_AF9015
 	tristate "Afatech AF9015 DVB-T USB2.0 support"
-	depends on DVB_USB && EXPERIMENTAL
+	depends on DVB_USB
 	select DVB_AF9013
 	select DVB_PLL              if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MT2060   if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_CE6230
+	tristate "Intel CE6230 DVB-T USB2.0 support"
+	depends on DVB_USB && EXPERIMENTAL
+	select DVB_ZL10353
+	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	help
+	  Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/Makefile linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/dvb-usb/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/dvb-usb/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -76,6 +76,8 @@ obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-
 dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
 obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
 
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/firewire/firedtv-avc.c linux-libre-2.6.30-gnu1/drivers/media/dvb/firewire/firedtv-avc.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/firewire/firedtv-avc.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,7 +115,7 @@ static const char *debug_fcp_ctype(unsig
 }
 
 static const char *debug_fcp_opcode(unsigned int opcode,
-				    const u8 *data, size_t length)
+				    const u8 *data, int length)
 {
 	switch (opcode) {
 	case AVC_OPCODE_VENDOR:			break;
@@ -135,13 +135,14 @@ static const char *debug_fcp_opcode(unsi
 	case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:	return "RegisterRC";
 	case SFE_VENDOR_OPCODE_LNB_CONTROL:		return "LNBControl";
 	case SFE_VENDOR_OPCODE_TUNE_QPSK:		return "TuneQPSK";
+	case SFE_VENDOR_OPCODE_TUNE_QPSK2:		return "TuneQPSK2";
 	case SFE_VENDOR_OPCODE_HOST2CA:			return "Host2CA";
 	case SFE_VENDOR_OPCODE_CA2HOST:			return "CA2Host";
 	}
 	return "Vendor";
 }
 
-static void debug_fcp(const u8 *data, size_t length)
+static void debug_fcp(const u8 *data, int length)
 {
 	unsigned int subunit_type, subunit_id, op;
 	const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
@@ -266,7 +267,10 @@ static void avc_tuner_tuneqpsk(struct fi
 	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
 	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
 	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
-	c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+	if (fdtv->type == FIREDTV_DVB_S2)
+		c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2;
+	else
+		c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
 
 	c->operand[4] = (params->frequency >> 24) & 0xff;
 	c->operand[5] = (params->frequency >> 16) & 0xff;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,874 +0,0 @@
-/*
-    Auvitek AU8522 QAM/8VSB demodulator driver
-
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include "dvb_frontend.h"
-#include "au8522.h"
-
-struct au8522_state {
-
-	struct i2c_adapter *i2c;
-
-	/* configuration settings */
-	const struct au8522_config *config;
-
-	struct dvb_frontend frontend;
-
-	u32 current_frequency;
-	fe_modulation_t current_modulation;
-
-	u32 fe_status;
-	unsigned int led_state;
-};
-
-static int debug;
-
-#define dprintk(arg...) do {		\
-	if (debug) 			\
-		 printk(arg); 		\
-	} while (0)
-
-/* 16 bit registers, 8 bit values */
-static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
-{
-	int ret;
-	u8 buf [] = { reg >> 8, reg & 0xff, data };
-
-	struct i2c_msg msg = { .addr = state->config->demod_address,
-			       .flags = 0, .buf = buf, .len = 3 };
-
-	ret = i2c_transfer(state->i2c, &msg, 1);
-
-	if (ret != 1)
-		printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
-		       "ret == %i)\n", __func__, reg, data, ret);
-
-	return (ret != 1) ? -1 : 0;
-}
-
-static u8 au8522_readreg(struct au8522_state *state, u16 reg)
-{
-	int ret;
-	u8 b0 [] = { reg >> 8, reg & 0xff };
-	u8 b1 [] = { 0 };
-
-	struct i2c_msg msg [] = {
-		{ .addr = state->config->demod_address, .flags = 0,
-		  .buf = b0, .len = 2 },
-		{ .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: readreg error (ret == %i)\n",
-		       __func__, ret);
-	return b1[0];
-}
-
-static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-
-	dprintk("%s(%d)\n", __func__, enable);
-
-	if (enable)
-		return au8522_writereg(state, 0x106, 1);
-	else
-		return au8522_writereg(state, 0x106, 0);
-}
-
-struct mse2snr_tab {
-	u16 val;
-	u16 data;
-};
-
-/* VSB SNR lookup table */
-static struct mse2snr_tab vsb_mse2snr_tab[] = {
-	{   0, 270 },
-	{   2, 250 },
-	{   3, 240 },
-	{   5, 230 },
-	{   7, 220 },
-	{   9, 210 },
-	{  12, 200 },
-	{  13, 195 },
-	{  15, 190 },
-	{  17, 185 },
-	{  19, 180 },
-	{  21, 175 },
-	{  24, 170 },
-	{  27, 165 },
-	{  31, 160 },
-	{  32, 158 },
-	{  33, 156 },
-	{  36, 152 },
-	{  37, 150 },
-	{  39, 148 },
-	{  40, 146 },
-	{  41, 144 },
-	{  43, 142 },
-	{  44, 140 },
-	{  48, 135 },
-	{  50, 130 },
-	{  43, 142 },
-	{  53, 125 },
-	{  56, 120 },
-	{ 256, 115 },
-};
-
-/* QAM64 SNR lookup table */
-static struct mse2snr_tab qam64_mse2snr_tab[] = {
-	{  15,   0 },
-	{  16, 290 },
-	{  17, 288 },
-	{  18, 286 },
-	{  19, 284 },
-	{  20, 282 },
-	{  21, 281 },
-	{  22, 279 },
-	{  23, 277 },
-	{  24, 275 },
-	{  25, 273 },
-	{  26, 271 },
-	{  27, 269 },
-	{  28, 268 },
-	{  29, 266 },
-	{  30, 264 },
-	{  31, 262 },
-	{  32, 260 },
-	{  33, 259 },
-	{  34, 258 },
-	{  35, 256 },
-	{  36, 255 },
-	{  37, 254 },
-	{  38, 252 },
-	{  39, 251 },
-	{  40, 250 },
-	{  41, 249 },
-	{  42, 248 },
-	{  43, 246 },
-	{  44, 245 },
-	{  45, 244 },
-	{  46, 242 },
-	{  47, 241 },
-	{  48, 240 },
-	{  50, 239 },
-	{  51, 238 },
-	{  53, 237 },
-	{  54, 236 },
-	{  56, 235 },
-	{  57, 234 },
-	{  59, 233 },
-	{  60, 232 },
-	{  62, 231 },
-	{  63, 230 },
-	{  65, 229 },
-	{  67, 228 },
-	{  68, 227 },
-	{  70, 226 },
-	{  71, 225 },
-	{  73, 224 },
-	{  74, 223 },
-	{  76, 222 },
-	{  78, 221 },
-	{  80, 220 },
-	{  82, 219 },
-	{  85, 218 },
-	{  88, 217 },
-	{  90, 216 },
-	{  92, 215 },
-	{  93, 214 },
-	{  94, 212 },
-	{  95, 211 },
-	{  97, 210 },
-	{  99, 209 },
-	{ 101, 208 },
-	{ 102, 207 },
-	{ 104, 206 },
-	{ 107, 205 },
-	{ 111, 204 },
-	{ 114, 203 },
-	{ 118, 202 },
-	{ 122, 201 },
-	{ 125, 200 },
-	{ 128, 199 },
-	{ 130, 198 },
-	{ 132, 197 },
-	{ 256, 190 },
-};
-
-/* QAM256 SNR lookup table */
-static struct mse2snr_tab qam256_mse2snr_tab[] = {
-	{  16,   0 },
-	{  17, 400 },
-	{  18, 398 },
-	{  19, 396 },
-	{  20, 394 },
-	{  21, 392 },
-	{  22, 390 },
-	{  23, 388 },
-	{  24, 386 },
-	{  25, 384 },
-	{  26, 382 },
-	{  27, 380 },
-	{  28, 379 },
-	{  29, 378 },
-	{  30, 377 },
-	{  31, 376 },
-	{  32, 375 },
-	{  33, 374 },
-	{  34, 373 },
-	{  35, 372 },
-	{  36, 371 },
-	{  37, 370 },
-	{  38, 362 },
-	{  39, 354 },
-	{  40, 346 },
-	{  41, 338 },
-	{  42, 330 },
-	{  43, 328 },
-	{  44, 326 },
-	{  45, 324 },
-	{  46, 322 },
-	{  47, 320 },
-	{  48, 319 },
-	{  49, 318 },
-	{  50, 317 },
-	{  51, 316 },
-	{  52, 315 },
-	{  53, 314 },
-	{  54, 313 },
-	{  55, 312 },
-	{  56, 311 },
-	{  57, 310 },
-	{  58, 308 },
-	{  59, 306 },
-	{  60, 304 },
-	{  61, 302 },
-	{  62, 300 },
-	{  63, 298 },
-	{  65, 295 },
-	{  68, 294 },
-	{  70, 293 },
-	{  73, 292 },
-	{  76, 291 },
-	{  78, 290 },
-	{  79, 289 },
-	{  81, 288 },
-	{  82, 287 },
-	{  83, 286 },
-	{  84, 285 },
-	{  85, 284 },
-	{  86, 283 },
-	{  88, 282 },
-	{  89, 281 },
-	{ 256, 280 },
-};
-
-static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
-				 u16 *snr)
-{
-	int i, ret = -EINVAL;
-	dprintk("%s()\n", __func__);
-
-	for (i = 0; i < sz; i++) {
-		if (mse < tab[i].val) {
-			*snr = tab[i].data;
-			ret = 0;
-			break;
-		}
-	}
-	dprintk("%s() snr=%d\n", __func__, *snr);
-	return ret;
-}
-
-static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	u8 r0b5, r0b6, r0b7;
-	char *ifmhz;
-
-	switch (if_freq) {
-	case AU8522_IF_3_25MHZ:
-		ifmhz = "3.25";
-		r0b5 = 0x00;
-		r0b6 = 0x3d;
-		r0b7 = 0xa0;
-		break;
-	case AU8522_IF_4MHZ:
-		ifmhz = "4.00";
-		r0b5 = 0x00;
-		r0b6 = 0x4b;
-		r0b7 = 0xd9;
-		break;
-	case AU8522_IF_6MHZ:
-		ifmhz = "6.00";
-		r0b5 = 0xfb;
-		r0b6 = 0x8e;
-		r0b7 = 0x39;
-		break;
-	default:
-		dprintk("%s() IF Frequency not supported\n", __func__);
-		return -EINVAL;
-	}
-	dprintk("%s() %s MHz\n", __func__, ifmhz);
-	au8522_writereg(state, 0x80b5, r0b5);
-	au8522_writereg(state, 0x80b6, r0b6);
-	au8522_writereg(state, 0x80b7, r0b7);
-
-	return 0;
-}
-
-/* VSB Modulation table */
-static struct {
-	u16 reg;
-	u16 data;
-} VSB_mod_tab[] = {
-	{ 0x8090, 0x84 },
-	{ 0x4092, 0x11 },
-	{ 0x2005, 0x00 },
-	{ 0x8091, 0x80 },
-	{ 0x80a3, 0x0c },
-	{ 0x80a4, 0xe8 },
-	{ 0x8081, 0xc4 },
-	{ 0x80a5, 0x40 },
-	{ 0x80a7, 0x40 },
-	{ 0x80a6, 0x67 },
-	{ 0x8262, 0x20 },
-	{ 0x821c, 0x30 },
-	{ 0x80d8, 0x1a },
-	{ 0x8227, 0xa0 },
-	{ 0x8121, 0xff },
-	{ 0x80a8, 0xf0 },
-	{ 0x80a9, 0x05 },
-	{ 0x80aa, 0x77 },
-	{ 0x80ab, 0xf0 },
-	{ 0x80ac, 0x05 },
-	{ 0x80ad, 0x77 },
-	{ 0x80ae, 0x41 },
-	{ 0x80af, 0x66 },
-	{ 0x821b, 0xcc },
-	{ 0x821d, 0x80 },
-	{ 0x80a4, 0xe8 },
-	{ 0x8231, 0x13 },
-};
-
-/* QAM Modulation table */
-static struct {
-	u16 reg;
-	u16 data;
-} QAM_mod_tab[] = {
-	{ 0x80a3, 0x09 },
-	{ 0x80a4, 0x00 },
-	{ 0x8081, 0xc4 },
-	{ 0x80a5, 0x40 },
-	{ 0x80aa, 0x77 },
-	{ 0x80ad, 0x77 },
-	{ 0x80a6, 0x67 },
-	{ 0x8262, 0x20 },
-	{ 0x821c, 0x30 },
-	{ 0x80b8, 0x3e },
-	{ 0x80b9, 0xf0 },
-	{ 0x80ba, 0x01 },
-	{ 0x80bb, 0x18 },
-	{ 0x80bc, 0x50 },
-	{ 0x80bd, 0x00 },
-	{ 0x80be, 0xea },
-	{ 0x80bf, 0xef },
-	{ 0x80c0, 0xfc },
-	{ 0x80c1, 0xbd },
-	{ 0x80c2, 0x1f },
-	{ 0x80c3, 0xfc },
-	{ 0x80c4, 0xdd },
-	{ 0x80c5, 0xaf },
-	{ 0x80c6, 0x00 },
-	{ 0x80c7, 0x38 },
-	{ 0x80c8, 0x30 },
-	{ 0x80c9, 0x05 },
-	{ 0x80ca, 0x4a },
-	{ 0x80cb, 0xd0 },
-	{ 0x80cc, 0x01 },
-	{ 0x80cd, 0xd9 },
-	{ 0x80ce, 0x6f },
-	{ 0x80cf, 0xf9 },
-	{ 0x80d0, 0x70 },
-	{ 0x80d1, 0xdf },
-	{ 0x80d2, 0xf7 },
-	{ 0x80d3, 0xc2 },
-	{ 0x80d4, 0xdf },
-	{ 0x80d5, 0x02 },
-	{ 0x80d6, 0x9a },
-	{ 0x80d7, 0xd0 },
-	{ 0x8250, 0x0d },
-	{ 0x8251, 0xcd },
-	{ 0x8252, 0xe0 },
-	{ 0x8253, 0x05 },
-	{ 0x8254, 0xa7 },
-	{ 0x8255, 0xff },
-	{ 0x8256, 0xed },
-	{ 0x8257, 0x5b },
-	{ 0x8258, 0xae },
-	{ 0x8259, 0xe6 },
-	{ 0x825a, 0x3d },
-	{ 0x825b, 0x0f },
-	{ 0x825c, 0x0d },
-	{ 0x825d, 0xea },
-	{ 0x825e, 0xf2 },
-	{ 0x825f, 0x51 },
-	{ 0x8260, 0xf5 },
-	{ 0x8261, 0x06 },
-	{ 0x821a, 0x00 },
-	{ 0x8546, 0x40 },
-	{ 0x8210, 0x26 },
-	{ 0x8211, 0xf6 },
-	{ 0x8212, 0x84 },
-	{ 0x8213, 0x02 },
-	{ 0x8502, 0x01 },
-	{ 0x8121, 0x04 },
-	{ 0x8122, 0x04 },
-	{ 0x852e, 0x10 },
-	{ 0x80a4, 0xca },
-	{ 0x80a7, 0x40 },
-	{ 0x8526, 0x01 },
-};
-
-static int au8522_enable_modulation(struct dvb_frontend *fe,
-				    fe_modulation_t m)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	int i;
-
-	dprintk("%s(0x%08x)\n", __func__, m);
-
-	switch (m) {
-	case VSB_8:
-		dprintk("%s() VSB_8\n", __func__);
-		for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
-			au8522_writereg(state,
-				VSB_mod_tab[i].reg,
-				VSB_mod_tab[i].data);
-		au8522_set_if(fe, state->config->vsb_if);
-		break;
-	case QAM_64:
-	case QAM_256:
-		dprintk("%s() QAM 64/256\n", __func__);
-		for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++)
-			au8522_writereg(state,
-				QAM_mod_tab[i].reg,
-				QAM_mod_tab[i].data);
-		au8522_set_if(fe, state->config->qam_if);
-		break;
-	default:
-		dprintk("%s() Invalid modulation\n", __func__);
-		return -EINVAL;
-	}
-
-	state->current_modulation = m;
-
-	return 0;
-}
-
-/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int au8522_set_frontend(struct dvb_frontend *fe,
-			       struct dvb_frontend_parameters *p)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	int ret = -EINVAL;
-
-	dprintk("%s(frequency=%d)\n", __func__, p->frequency);
-
-	if ((state->current_frequency == p->frequency) &&
-	    (state->current_modulation == p->u.vsb.modulation))
-		return 0;
-
-	au8522_enable_modulation(fe, p->u.vsb.modulation);
-
-	/* Allow the demod to settle */
-	msleep(100);
-
-	if (fe->ops.tuner_ops.set_params) {
-		if (fe->ops.i2c_gate_ctrl)
-			fe->ops.i2c_gate_ctrl(fe, 1);
-		ret = fe->ops.tuner_ops.set_params(fe, p);
-		if (fe->ops.i2c_gate_ctrl)
-			fe->ops.i2c_gate_ctrl(fe, 0);
-	}
-
-	if (ret < 0)
-		return ret;
-
-	state->current_frequency = p->frequency;
-
-	return 0;
-}
-
-/* Reset the demod hardware and reset all of the configuration registers
-   to a default state. */
-static int au8522_init(struct dvb_frontend *fe)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	dprintk("%s()\n", __func__);
-
-	au8522_writereg(state, 0xa4, 1 << 5);
-
-	au8522_i2c_gate_ctrl(fe, 1);
-
-	return 0;
-}
-
-static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
-{
-	struct au8522_led_config *led_config = state->config->led_cfg;
-	u8 val;
-
-	/* bail out if we cant control an LED */
-	if (!led_config || !led_config->gpio_output ||
-	    !led_config->gpio_output_enable || !led_config->gpio_output_disable)
-		return 0;
-
-	val = au8522_readreg(state, 0x4000 |
-			     (led_config->gpio_output & ~0xc000));
-	if (onoff) {
-		/* enable GPIO output */
-		val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
-		val |=  (led_config->gpio_output_enable & 0xff);
-	} else {
-		/* disable GPIO output */
-		val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
-		val |=  (led_config->gpio_output_disable & 0xff);
-	}
-	return au8522_writereg(state, 0x8000 |
-			       (led_config->gpio_output & ~0xc000), val);
-}
-
-/* led = 0 | off
- * led = 1 | signal ok
- * led = 2 | signal strong
- * led < 0 | only light led if leds are currently off
- */
-static int au8522_led_ctrl(struct au8522_state *state, int led)
-{
-	struct au8522_led_config *led_config = state->config->led_cfg;
-	int i, ret = 0;
-
-	/* bail out if we cant control an LED */
-	if (!led_config || !led_config->gpio_leds ||
-	    !led_config->num_led_states || !led_config->led_states)
-		return 0;
-
-	if (led < 0) {
-		/* if LED is already lit, then leave it as-is */
-		if (state->led_state)
-			return 0;
-		else
-			led *= -1;
-	}
-
-	/* toggle LED if changing state */
-	if (state->led_state != led) {
-		u8 val;
-
-		dprintk("%s: %d\n", __func__, led);
-
-		au8522_led_gpio_enable(state, 1);
-
-		val = au8522_readreg(state, 0x4000 |
-				     (led_config->gpio_leds & ~0xc000));
-
-		/* start with all leds off */
-		for (i = 0; i < led_config->num_led_states; i++)
-			val &= ~led_config->led_states[i];
-
-		/* set selected LED state */
-		if (led < led_config->num_led_states)
-			val |= led_config->led_states[led];
-		else if (led_config->num_led_states)
-			val |=
-			led_config->led_states[led_config->num_led_states - 1];
-
-		ret = au8522_writereg(state, 0x8000 |
-				      (led_config->gpio_leds & ~0xc000), val);
-		if (ret < 0)
-			return ret;
-
-		state->led_state = led;
-
-		if (led == 0)
-			au8522_led_gpio_enable(state, 0);
-	}
-
-	return 0;
-}
-
-static int au8522_sleep(struct dvb_frontend *fe)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	dprintk("%s()\n", __func__);
-
-	/* turn off led */
-	au8522_led_ctrl(state, 0);
-
-	state->current_frequency = 0;
-
-	return 0;
-}
-
-static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	u8 reg;
-	u32 tuner_status = 0;
-
-	*status = 0;
-
-	if (state->current_modulation == VSB_8) {
-		dprintk("%s() Checking VSB_8\n", __func__);
-		reg = au8522_readreg(state, 0x4088);
-		if ((reg & 0x03) == 0x03)
-			*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
-	} else {
-		dprintk("%s() Checking QAM\n", __func__);
-		reg = au8522_readreg(state, 0x4541);
-		if (reg & 0x80)
-			*status |= FE_HAS_VITERBI;
-		if (reg & 0x20)
-			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
-	}
-
-	switch (state->config->status_mode) {
-	case AU8522_DEMODLOCKING:
-		dprintk("%s() DEMODLOCKING\n", __func__);
-		if (*status & FE_HAS_VITERBI)
-			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-		break;
-	case AU8522_TUNERLOCKING:
-		/* Get the tuner status */
-		dprintk("%s() TUNERLOCKING\n", __func__);
-		if (fe->ops.tuner_ops.get_status) {
-			if (fe->ops.i2c_gate_ctrl)
-				fe->ops.i2c_gate_ctrl(fe, 1);
-
-			fe->ops.tuner_ops.get_status(fe, &tuner_status);
-
-			if (fe->ops.i2c_gate_ctrl)
-				fe->ops.i2c_gate_ctrl(fe, 0);
-		}
-		if (tuner_status)
-			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-		break;
-	}
-	state->fe_status = *status;
-
-	if (*status & FE_HAS_LOCK)
-		/* turn on LED, if it isn't on already */
-		au8522_led_ctrl(state, -1);
-	else
-		/* turn off LED */
-		au8522_led_ctrl(state, 0);
-
-	dprintk("%s() status 0x%08x\n", __func__, *status);
-
-	return 0;
-}
-
-static int au8522_led_status(struct au8522_state *state, const u16 *snr)
-{
-	struct au8522_led_config *led_config = state->config->led_cfg;
-	int led;
-	u16 strong;
-
-	/* bail out if we cant control an LED */
-	if (!led_config)
-		return 0;
-
-	if (0 == (state->fe_status & FE_HAS_LOCK))
-		return au8522_led_ctrl(state, 0);
-	else if (state->current_modulation == QAM_256)
-		strong = led_config->qam256_strong;
-	else if (state->current_modulation == QAM_64)
-		strong = led_config->qam64_strong;
-	else /* (state->current_modulation == VSB_8) */
-		strong = led_config->vsb8_strong;
-
-	if (*snr >= strong)
-		led = 2;
-	else
-		led = 1;
-
-	if ((state->led_state) &&
-	    (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
-		/* snr didn't change enough to bother
-		 * changing the color of the led */
-		return 0;
-
-	return au8522_led_ctrl(state, led);
-}
-
-static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	int ret = -EINVAL;
-
-	dprintk("%s()\n", __func__);
-
-	if (state->current_modulation == QAM_256)
-		ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
-					    ARRAY_SIZE(qam256_mse2snr_tab),
-					    au8522_readreg(state, 0x4522),
-					    snr);
-	else if (state->current_modulation == QAM_64)
-		ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
-					    ARRAY_SIZE(qam64_mse2snr_tab),
-					    au8522_readreg(state, 0x4522),
-					    snr);
-	else /* VSB_8 */
-		ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
-					    ARRAY_SIZE(vsb_mse2snr_tab),
-					    au8522_readreg(state, 0x4311),
-					    snr);
-
-	if (state->config->led_cfg)
-		au8522_led_status(state, snr);
-
-	return ret;
-}
-
-static int au8522_read_signal_strength(struct dvb_frontend *fe,
-				       u16 *signal_strength)
-{
-	return au8522_read_snr(fe, signal_strength);
-}
-
-static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-
-	if (state->current_modulation == VSB_8)
-		*ucblocks = au8522_readreg(state, 0x4087);
-	else
-		*ucblocks = au8522_readreg(state, 0x4543);
-
-	return 0;
-}
-
-static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-	return au8522_read_ucblocks(fe, ber);
-}
-
-static int au8522_get_frontend(struct dvb_frontend *fe,
-				struct dvb_frontend_parameters *p)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-
-	p->frequency = state->current_frequency;
-	p->u.vsb.modulation = state->current_modulation;
-
-	return 0;
-}
-
-static int au8522_get_tune_settings(struct dvb_frontend *fe,
-				    struct dvb_frontend_tune_settings *tune)
-{
-	tune->min_delay_ms = 1000;
-	return 0;
-}
-
-static void au8522_release(struct dvb_frontend *fe)
-{
-	struct au8522_state *state = fe->demodulator_priv;
-	kfree(state);
-}
-
-static struct dvb_frontend_ops au8522_ops;
-
-struct dvb_frontend *au8522_attach(const struct au8522_config *config,
-				   struct i2c_adapter *i2c)
-{
-	struct au8522_state *state = NULL;
-
-	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
-	if (state == NULL)
-		goto error;
-
-	/* setup the state */
-	state->config = config;
-	state->i2c = i2c;
-	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &au8522_ops,
-	       sizeof(struct dvb_frontend_ops));
-	state->frontend.demodulator_priv = state;
-
-	if (au8522_init(&state->frontend) != 0) {
-		printk(KERN_ERR "%s: Failed to initialize correctly\n",
-			__func__);
-		goto error;
-	}
-
-	/* Note: Leaving the I2C gate open here. */
-	au8522_i2c_gate_ctrl(&state->frontend, 1);
-
-	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
-}
-EXPORT_SYMBOL(au8522_attach);
-
-static struct dvb_frontend_ops au8522_ops = {
-
-	.info = {
-		.name			= "Auvitek AU8522 QAM/8VSB Frontend",
-		.type			= FE_ATSC,
-		.frequency_min		= 54000000,
-		.frequency_max		= 858000000,
-		.frequency_stepsize	= 62500,
-		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
-	},
-
-	.init                 = au8522_init,
-	.sleep                = au8522_sleep,
-	.i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
-	.set_frontend         = au8522_set_frontend,
-	.get_frontend         = au8522_get_frontend,
-	.get_tune_settings    = au8522_get_tune_settings,
-	.read_status          = au8522_read_status,
-	.read_ber             = au8522_read_ber,
-	.read_signal_strength = au8522_read_signal_strength,
-	.read_snr             = au8522_read_snr,
-	.read_ucblocks        = au8522_read_ucblocks,
-	.release              = au8522_release,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
-MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
-MODULE_AUTHOR("Steven Toth");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_decoder.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_decoder.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_decoder.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_decoder.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,835 @@
+/*
+ * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * As published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* 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)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-device.h>
+#include "au8522.h"
+#include "au8522_priv.h"
+
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static int au8522_analog_debug;
+
+
+module_param_named(analog_debug, au8522_analog_debug, int, 0644);
+
+MODULE_PARM_DESC(analog_debug,
+		 "Analog debugging messages [0=Off (default) 1=On]");
+
+struct au8522_register_config {
+	u16 reg_name;
+	u8 reg_val[8];
+};
+
+
+/* Video Decoder Filter Coefficients
+   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[] = {
+	{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} },
+	{AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
+	{AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
+	{AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
+	{AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
+	{AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
+	{AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
+	{AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
+	{AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
+	{AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
+	{AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
+	{AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
+	{AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
+	{AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
+	{AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
+	{AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
+	{AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
+	{AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
+	{AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
+	{AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
+	{AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
+	{AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
+	{AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
+
+};
+#define NUM_FILTER_COEF (sizeof(filter_coef)\
+			 / sizeof(struct au8522_register_config))
+
+
+/* Registers 0x060b through 0x0652 are the LP Filter coefficients
+   The values are as follows from left to right
+   0="SIF" 1="ATVRF/ATVRF13"
+   Note: the "ATVRF/ATVRF13" mode has never been tested
+*/
+struct au8522_register_config lpfilter_coef[] = {
+	{0x060b, {0x21, 0x0b} },
+	{0x060c, {0xad, 0xad} },
+	{0x060d, {0x70, 0xf0} },
+	{0x060e, {0xea, 0xe9} },
+	{0x060f, {0xdd, 0xdd} },
+	{0x0610, {0x08, 0x64} },
+	{0x0611, {0x60, 0x60} },
+	{0x0612, {0xf8, 0xb2} },
+	{0x0613, {0x01, 0x02} },
+	{0x0614, {0xe4, 0xb4} },
+	{0x0615, {0x19, 0x02} },
+	{0x0616, {0xae, 0x2e} },
+	{0x0617, {0xee, 0xc5} },
+	{0x0618, {0x56, 0x56} },
+	{0x0619, {0x30, 0x58} },
+	{0x061a, {0xf9, 0xf8} },
+	{0x061b, {0x24, 0x64} },
+	{0x061c, {0x07, 0x07} },
+	{0x061d, {0x30, 0x30} },
+	{0x061e, {0xa9, 0xed} },
+	{0x061f, {0x09, 0x0b} },
+	{0x0620, {0x42, 0xc2} },
+	{0x0621, {0x1d, 0x2a} },
+	{0x0622, {0xd6, 0x56} },
+	{0x0623, {0x95, 0x8b} },
+	{0x0624, {0x2b, 0x2b} },
+	{0x0625, {0x30, 0x24} },
+	{0x0626, {0x3e, 0x3e} },
+	{0x0627, {0x62, 0xe2} },
+	{0x0628, {0xe9, 0xf5} },
+	{0x0629, {0x99, 0x19} },
+	{0x062a, {0xd4, 0x11} },
+	{0x062b, {0x03, 0x04} },
+	{0x062c, {0xb5, 0x85} },
+	{0x062d, {0x1e, 0x20} },
+	{0x062e, {0x2a, 0xea} },
+	{0x062f, {0xd7, 0xd2} },
+	{0x0630, {0x15, 0x15} },
+	{0x0631, {0xa3, 0xa9} },
+	{0x0632, {0x1f, 0x1f} },
+	{0x0633, {0xf9, 0xd1} },
+	{0x0634, {0xc0, 0xc3} },
+	{0x0635, {0x4d, 0x8d} },
+	{0x0636, {0x21, 0x31} },
+	{0x0637, {0x83, 0x83} },
+	{0x0638, {0x08, 0x8c} },
+	{0x0639, {0x19, 0x19} },
+	{0x063a, {0x45, 0xa5} },
+	{0x063b, {0xef, 0xec} },
+	{0x063c, {0x8a, 0x8a} },
+	{0x063d, {0xf4, 0xf6} },
+	{0x063e, {0x8f, 0x8f} },
+	{0x063f, {0x44, 0x0c} },
+	{0x0640, {0xef, 0xf0} },
+	{0x0641, {0x66, 0x66} },
+	{0x0642, {0xcc, 0xd2} },
+	{0x0643, {0x41, 0x41} },
+	{0x0644, {0x63, 0x93} },
+	{0x0645, {0x8e, 0x8e} },
+	{0x0646, {0xa2, 0x42} },
+	{0x0647, {0x7b, 0x7b} },
+	{0x0648, {0x04, 0x04} },
+	{0x0649, {0x00, 0x00} },
+	{0x064a, {0x40, 0x40} },
+	{0x064b, {0x8c, 0x98} },
+	{0x064c, {0x00, 0x00} },
+	{0x064d, {0x63, 0xc3} },
+	{0x064e, {0x04, 0x04} },
+	{0x064f, {0x20, 0x20} },
+	{0x0650, {0x00, 0x00} },
+	{0x0651, {0x40, 0x40} },
+	{0x0652, {0x01, 0x01} },
+};
+#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
+			   / sizeof(struct au8522_register_config))
+
+static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct au8522_state, sd);
+}
+
+static void setup_vbi(struct au8522_state *state, int aud_input)
+{
+	int i;
+
+	/* These are set to zero regardless of what mode we're in */
+	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
+			0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
+			0x00);
+	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
+			0x00);
+
+	/* Setup the VBI registers */
+	for (i = 0x30; i < 0x60; i++)
+		au8522_writereg(state, i, 0x40);
+
+	/* For some reason, every register is 0x40 except register 0x44
+	   (confirmed via the HVR-950q USB capture) */
+	au8522_writereg(state, 0x44, 0x60);
+
+	/* Enable VBI (we always do this regardless of whether the user is
+	   viewing closed caption info) */
+	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
+			AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
+
+}
+
+static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+{
+	int i;
+	int filter_coef_type;
+
+	/* Provide reasonable defaults for picture tuning values */
+	au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
+	au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
+	state->brightness = 0xed - 128;
+	au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
+	state->contrast = 0x79;
+	au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
+	au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+	au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
+	au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+
+	/* Other decoder registers */
+	au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
+
+	if (input_mode == 0x23) {
+		/* S-Video input mapping */
+		au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
+	} else {
+		/* All other modes (CVBS/ATVRF etc.) */
+		au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
+	}
+
+	au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
+			AU8522_TVDEC_PGA_REG012H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
+			AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
+	au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
+			AU8522_TVDED_DBG_MODE_REG060H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+			AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
+	au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+			AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
+	au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
+			AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
+			AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
+			AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
+			AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
+			AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
+			AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
+			AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
+			AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
+			AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+			AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+			AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
+			AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
+			AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
+			AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
+	au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
+	au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
+			AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
+	au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
+	au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
+			AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
+			AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
+			AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
+			AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
+			AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
+	au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
+			AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
+	au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
+			AU8522_TOREGAAGC_REG0E5H_CVBS);
+	au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
+
+	setup_vbi(state, 0);
+
+	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). */
+		/* filter_coef_type = 3; */
+		filter_coef_type = 5;
+	} else {
+		filter_coef_type = 5;
+	}
+
+	/* Load the Video Decoder Filter Coefficients */
+	for (i = 0; i < NUM_FILTER_COEF; i++) {
+		au8522_writereg(state, filter_coef[i].reg_name,
+				filter_coef[i].reg_val[filter_coef_type]);
+	}
+
+	/* It's not clear what these registers are for, but they are always
+	   set to the same value regardless of what mode we're in */
+	au8522_writereg(state, AU8522_REG42EH, 0x87);
+	au8522_writereg(state, AU8522_REG42FH, 0xa2);
+	au8522_writereg(state, AU8522_REG430H, 0xbf);
+	au8522_writereg(state, AU8522_REG431H, 0xcb);
+	au8522_writereg(state, AU8522_REG432H, 0xa1);
+	au8522_writereg(state, AU8522_REG433H, 0x41);
+	au8522_writereg(state, AU8522_REG434H, 0x88);
+	au8522_writereg(state, AU8522_REG435H, 0xc2);
+	au8522_writereg(state, AU8522_REG436H, 0x3c);
+}
+
+static void au8522_setup_cvbs_mode(struct au8522_state *state)
+{
+	/* here we're going to try the pre-programmed route */
+	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+			AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+	setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+{
+	/* here we're going to try the pre-programmed route */
+	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+	/* It's not clear why they turn off the PGA before enabling the clamp
+	   control, but the Windows trace does it so we will too... */
+	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+	/* Enable clamping control */
+	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+
+	/* Turn on the PGA */
+	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+	/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
+	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+			AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+	setup_decoder_defaults(state,
+			       AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_svideo_mode(struct au8522_state *state)
+{
+	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
+
+	/* Set input to Y on Channe1, C on Channel 3 */
+	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+			AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+	/* Disable clamping control (required for S-video) */
+	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+	setup_decoder_defaults(state,
+			       AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void disable_audio_input(struct au8522_state *state)
+{
+	/* This can probably be optimized */
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+	au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+	au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+
+	au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+	au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+	au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
+
+	au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
+	msleep(5);
+	au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
+
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
+	au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+	au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
+
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* 0=disable, 1=SIF */
+static void set_audio_input(struct au8522_state *state, int aud_input)
+{
+	int i;
+
+	/* Note that this function needs to be used in conjunction with setting
+	   the input routing via register 0x81 */
+
+	if (aud_input == AU8522_AUDIO_NONE) {
+		disable_audio_input(state);
+		return;
+	}
+
+	if (aud_input != AU8522_AUDIO_SIF) {
+		/* The caller asked for a mode we don't currently support */
+		printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
+		       aud_input);
+		return;
+	}
+
+	/* Load the Audio Decoder Filter Coefficients */
+	for (i = 0; i < NUM_LPFILTER_COEF; i++) {
+		au8522_writereg(state, lpfilter_coef[i].reg_name,
+				lpfilter_coef[i].reg_val[0]);
+	}
+
+	/* Setup audio */
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+	au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+	au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+	msleep(150);
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
+	msleep(1);
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+	msleep(50);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
+	msleep(80);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+	au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+	au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
+	msleep(70);
+	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
+	au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+	au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct au8522_state *state = to_state(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		state->brightness = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
+				ctrl->value - 128);
+		break;
+	case V4L2_CID_CONTRAST:
+		state->contrast = ctrl->value;
+		au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
+				ctrl->value);
+		break;
+	case V4L2_CID_SATURATION:
+	case V4L2_CID_HUE:
+	case V4L2_CID_AUDIO_VOLUME:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_MUTE:
+		/* Not yet implemented */
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct au8522_state *state = to_state(sd);
+
+	/* Note that we are using values cached in the state structure instead
+	   of reading the registers due to issues with i2c reads not working
+	   properly/consistently yet on the HVR-950q */
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = state->brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = state->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+	case V4L2_CID_HUE:
+	case V4L2_CID_AUDIO_VOLUME:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_MUTE:
+		/* Not yet supported */
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	switch (fmt->type) {
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	switch (fmt->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		/* Not yet implemented */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int au8522_g_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct au8522_state *state = to_state(sd);
+
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	reg->val = au8522_readreg(state, reg->reg & 0xffff);
+	return 0;
+}
+
+static int au8522_s_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct au8522_state *state = to_state(sd);
+
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	au8522_writereg(state, reg->reg, reg->val & 0xff);
+	return 0;
+}
+#endif
+
+static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct au8522_state *state = to_state(sd);
+
+	if (enable) {
+		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+				0x01);
+		msleep(1);
+		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+				AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+	} else {
+		/* This does not completely power down the device
+		   (it only reduces it from around 140ma to 80ma) */
+		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+				1 << 5);
+	}
+	return 0;
+}
+
+static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1,
+					    AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+	case V4L2_CID_SATURATION:
+	case V4L2_CID_HUE:
+		/* Not yet implemented */
+	default:
+		break;
+	}
+
+	qc->type = 0;
+	return -EINVAL;
+}
+
+static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+{
+	struct au8522_state *state = to_state(sd);
+
+	au8522_writereg(state, 0xa4, 1 << 5);
+
+	return 0;
+}
+
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+					u32 input, u32 output, u32 config)
+{
+	struct au8522_state *state = to_state(sd);
+
+	au8522_reset(sd, 0);
+
+	/* Jam open the i2c gate to the tuner.  We do this here to handle the
+	   case where the user went into digital mode (causing the gate to be
+	   closed), and then came back to analog mode */
+	au8522_writereg(state, 0x106, 1);
+
+	if (input == AU8522_COMPOSITE_CH1) {
+		au8522_setup_cvbs_mode(state);
+	} else if (input == AU8522_SVIDEO_CH13) {
+		au8522_setup_svideo_mode(state);
+	} else if (input == AU8522_COMPOSITE_CH4_SIF) {
+		au8522_setup_cvbs_tuner_mode(state);
+	} else {
+		printk(KERN_ERR "au8522 mode not currently supported\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int au8522_s_audio_routing(struct v4l2_subdev *sd,
+					u32 input, u32 output, u32 config)
+{
+	struct au8522_state *state = to_state(sd);
+	set_audio_input(state, input);
+	return 0;
+}
+
+static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	int val = 0;
+	struct au8522_state *state = to_state(sd);
+	u8 lock_status;
+
+	/* Interrogate the decoder to see if we are getting a real signal */
+	lock_status = au8522_readreg(state, 0x00);
+	if (lock_status == 0xa2)
+		vt->signal = 0x01;
+	else
+		vt->signal = 0x00;
+
+	vt->capability |=
+		V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+		V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+	val = V4L2_TUNER_SUB_MONO;
+	vt->rxsubchans = val;
+	vt->audmode = V4L2_TUNER_MODE_STEREO;
+	return 0;
+}
+
+static int au8522_g_chip_ident(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_chip_ident *chip)
+{
+	struct au8522_state *state = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
+}
+
+static int au8522_log_status(struct v4l2_subdev *sd)
+{
+	/* FIXME: Add some status info here */
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops au8522_core_ops = {
+	.log_status = au8522_log_status,
+	.g_chip_ident = au8522_g_chip_ident,
+	.g_ctrl = au8522_g_ctrl,
+	.s_ctrl = au8522_s_ctrl,
+	.queryctrl = au8522_queryctrl,
+	.reset = au8522_reset,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = au8522_g_register,
+	.s_register = au8522_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
+	.g_tuner = au8522_g_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
+	.s_routing = au8522_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops au8522_video_ops = {
+	.s_routing = au8522_s_video_routing,
+	.g_fmt = au8522_g_fmt,
+	.s_fmt = au8522_s_fmt,
+	.s_stream = au8522_s_stream,
+};
+
+static const struct v4l2_subdev_ops au8522_ops = {
+	.core = &au8522_core_ops,
+	.tuner = &au8522_tuner_ops,
+	.audio = &au8522_audio_ops,
+	.video = &au8522_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_probe(struct i2c_client *client,
+			const struct i2c_device_id *did)
+{
+	struct au8522_state *state;
+	struct v4l2_subdev *sd;
+	int instance;
+	struct au8522_config *demod_config;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		return -EIO;
+	}
+
+	/* allocate memory for the internal state */
+	instance = au8522_get_state(&state, client->adapter, client->addr);
+	switch (instance) {
+	case 0:
+		printk(KERN_ERR "au8522_decoder allocation failed\n");
+		return -EIO;
+	case 1:
+		/* new demod instance */
+		printk(KERN_INFO "au8522_decoder creating new instance...\n");
+		break;
+	default:
+		/* existing demod instance */
+		printk(KERN_INFO "au8522_decoder attach existing instance.\n");
+		break;
+	}
+
+	demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+	demod_config->demod_address = 0x8e >> 1;
+
+	state->config = demod_config;
+	state->i2c = client->adapter;
+
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &au8522_ops);
+
+	state->c = client;
+	state->vid_input = AU8522_COMPOSITE_CH1;
+	state->aud_input = AU8522_AUDIO_NONE;
+	state->id = 8522;
+	state->rev = 0;
+
+	/* Jam open the i2c gate to the tuner */
+	au8522_writereg(state, 0x106, 1);
+
+	return 0;
+}
+
+static int au8522_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	v4l2_device_unregister_subdev(sd);
+	au8522_release_state(to_state(sd));
+	return 0;
+}
+
+static const struct i2c_device_id au8522_id[] = {
+	{"au8522", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, au8522_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "au8522",
+	.probe = au8522_probe,
+	.remove = au8522_remove,
+	.id_table = au8522_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_dig.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_dig.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_dig.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_dig.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,902 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "au8522_priv.h"
+
+static int debug;
+
+/* Despite the name "hybrid_tuner", the framework works just as well for
+   hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(au8522_list_mutex);
+
+#define dprintk(arg...)\
+	do { if (debug)\
+		printk(arg);\
+	} while (0)
+
+/* 16 bit registers, 8 bit values */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+{
+	int ret;
+	u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
+
+	struct i2c_msg msg = { .addr = state->config->demod_address,
+			       .flags = 0, .buf = buf, .len = 3 };
+
+	ret = i2c_transfer(state->i2c, &msg, 1);
+
+	if (ret != 1)
+		printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+		       "ret == %i)\n", __func__, reg, data, ret);
+
+	return (ret != 1) ? -1 : 0;
+}
+
+u8 au8522_readreg(struct au8522_state *state, u16 reg)
+{
+	int ret;
+	u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
+	u8 b1[] = { 0 };
+
+	struct i2c_msg msg[] = {
+		{ .addr = state->config->demod_address, .flags = 0,
+		  .buf = b0, .len = 2 },
+		{ .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: readreg error (ret == %i)\n",
+		       __func__, ret);
+	return b1[0];
+}
+
+static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	dprintk("%s(%d)\n", __func__, enable);
+
+	if (enable)
+		return au8522_writereg(state, 0x106, 1);
+	else
+		return au8522_writereg(state, 0x106, 0);
+}
+
+struct mse2snr_tab {
+	u16 val;
+	u16 data;
+};
+
+/* VSB SNR lookup table */
+static struct mse2snr_tab vsb_mse2snr_tab[] = {
+	{   0, 270 },
+	{   2, 250 },
+	{   3, 240 },
+	{   5, 230 },
+	{   7, 220 },
+	{   9, 210 },
+	{  12, 200 },
+	{  13, 195 },
+	{  15, 190 },
+	{  17, 185 },
+	{  19, 180 },
+	{  21, 175 },
+	{  24, 170 },
+	{  27, 165 },
+	{  31, 160 },
+	{  32, 158 },
+	{  33, 156 },
+	{  36, 152 },
+	{  37, 150 },
+	{  39, 148 },
+	{  40, 146 },
+	{  41, 144 },
+	{  43, 142 },
+	{  44, 140 },
+	{  48, 135 },
+	{  50, 130 },
+	{  43, 142 },
+	{  53, 125 },
+	{  56, 120 },
+	{ 256, 115 },
+};
+
+/* QAM64 SNR lookup table */
+static struct mse2snr_tab qam64_mse2snr_tab[] = {
+	{  15,   0 },
+	{  16, 290 },
+	{  17, 288 },
+	{  18, 286 },
+	{  19, 284 },
+	{  20, 282 },
+	{  21, 281 },
+	{  22, 279 },
+	{  23, 277 },
+	{  24, 275 },
+	{  25, 273 },
+	{  26, 271 },
+	{  27, 269 },
+	{  28, 268 },
+	{  29, 266 },
+	{  30, 264 },
+	{  31, 262 },
+	{  32, 260 },
+	{  33, 259 },
+	{  34, 258 },
+	{  35, 256 },
+	{  36, 255 },
+	{  37, 254 },
+	{  38, 252 },
+	{  39, 251 },
+	{  40, 250 },
+	{  41, 249 },
+	{  42, 248 },
+	{  43, 246 },
+	{  44, 245 },
+	{  45, 244 },
+	{  46, 242 },
+	{  47, 241 },
+	{  48, 240 },
+	{  50, 239 },
+	{  51, 238 },
+	{  53, 237 },
+	{  54, 236 },
+	{  56, 235 },
+	{  57, 234 },
+	{  59, 233 },
+	{  60, 232 },
+	{  62, 231 },
+	{  63, 230 },
+	{  65, 229 },
+	{  67, 228 },
+	{  68, 227 },
+	{  70, 226 },
+	{  71, 225 },
+	{  73, 224 },
+	{  74, 223 },
+	{  76, 222 },
+	{  78, 221 },
+	{  80, 220 },
+	{  82, 219 },
+	{  85, 218 },
+	{  88, 217 },
+	{  90, 216 },
+	{  92, 215 },
+	{  93, 214 },
+	{  94, 212 },
+	{  95, 211 },
+	{  97, 210 },
+	{  99, 209 },
+	{ 101, 208 },
+	{ 102, 207 },
+	{ 104, 206 },
+	{ 107, 205 },
+	{ 111, 204 },
+	{ 114, 203 },
+	{ 118, 202 },
+	{ 122, 201 },
+	{ 125, 200 },
+	{ 128, 199 },
+	{ 130, 198 },
+	{ 132, 197 },
+	{ 256, 190 },
+};
+
+/* QAM256 SNR lookup table */
+static struct mse2snr_tab qam256_mse2snr_tab[] = {
+	{  16,   0 },
+	{  17, 400 },
+	{  18, 398 },
+	{  19, 396 },
+	{  20, 394 },
+	{  21, 392 },
+	{  22, 390 },
+	{  23, 388 },
+	{  24, 386 },
+	{  25, 384 },
+	{  26, 382 },
+	{  27, 380 },
+	{  28, 379 },
+	{  29, 378 },
+	{  30, 377 },
+	{  31, 376 },
+	{  32, 375 },
+	{  33, 374 },
+	{  34, 373 },
+	{  35, 372 },
+	{  36, 371 },
+	{  37, 370 },
+	{  38, 362 },
+	{  39, 354 },
+	{  40, 346 },
+	{  41, 338 },
+	{  42, 330 },
+	{  43, 328 },
+	{  44, 326 },
+	{  45, 324 },
+	{  46, 322 },
+	{  47, 320 },
+	{  48, 319 },
+	{  49, 318 },
+	{  50, 317 },
+	{  51, 316 },
+	{  52, 315 },
+	{  53, 314 },
+	{  54, 313 },
+	{  55, 312 },
+	{  56, 311 },
+	{  57, 310 },
+	{  58, 308 },
+	{  59, 306 },
+	{  60, 304 },
+	{  61, 302 },
+	{  62, 300 },
+	{  63, 298 },
+	{  65, 295 },
+	{  68, 294 },
+	{  70, 293 },
+	{  73, 292 },
+	{  76, 291 },
+	{  78, 290 },
+	{  79, 289 },
+	{  81, 288 },
+	{  82, 287 },
+	{  83, 286 },
+	{  84, 285 },
+	{  85, 284 },
+	{  86, 283 },
+	{  88, 282 },
+	{  89, 281 },
+	{ 256, 280 },
+};
+
+static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
+				 u16 *snr)
+{
+	int i, ret = -EINVAL;
+	dprintk("%s()\n", __func__);
+
+	for (i = 0; i < sz; i++) {
+		if (mse < tab[i].val) {
+			*snr = tab[i].data;
+			ret = 0;
+			break;
+		}
+	}
+	dprintk("%s() snr=%d\n", __func__, *snr);
+	return ret;
+}
+
+static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	u8 r0b5, r0b6, r0b7;
+	char *ifmhz;
+
+	switch (if_freq) {
+	case AU8522_IF_3_25MHZ:
+		ifmhz = "3.25";
+		r0b5 = 0x00;
+		r0b6 = 0x3d;
+		r0b7 = 0xa0;
+		break;
+	case AU8522_IF_4MHZ:
+		ifmhz = "4.00";
+		r0b5 = 0x00;
+		r0b6 = 0x4b;
+		r0b7 = 0xd9;
+		break;
+	case AU8522_IF_6MHZ:
+		ifmhz = "6.00";
+		r0b5 = 0xfb;
+		r0b6 = 0x8e;
+		r0b7 = 0x39;
+		break;
+	default:
+		dprintk("%s() IF Frequency not supported\n", __func__);
+		return -EINVAL;
+	}
+	dprintk("%s() %s MHz\n", __func__, ifmhz);
+	au8522_writereg(state, 0x80b5, r0b5);
+	au8522_writereg(state, 0x80b6, r0b6);
+	au8522_writereg(state, 0x80b7, r0b7);
+
+	return 0;
+}
+
+/* VSB Modulation table */
+static struct {
+	u16 reg;
+	u16 data;
+} VSB_mod_tab[] = {
+	{ 0x8090, 0x84 },
+	{ 0x4092, 0x11 },
+	{ 0x2005, 0x00 },
+	{ 0x8091, 0x80 },
+	{ 0x80a3, 0x0c },
+	{ 0x80a4, 0xe8 },
+	{ 0x8081, 0xc4 },
+	{ 0x80a5, 0x40 },
+	{ 0x80a7, 0x40 },
+	{ 0x80a6, 0x67 },
+	{ 0x8262, 0x20 },
+	{ 0x821c, 0x30 },
+	{ 0x80d8, 0x1a },
+	{ 0x8227, 0xa0 },
+	{ 0x8121, 0xff },
+	{ 0x80a8, 0xf0 },
+	{ 0x80a9, 0x05 },
+	{ 0x80aa, 0x77 },
+	{ 0x80ab, 0xf0 },
+	{ 0x80ac, 0x05 },
+	{ 0x80ad, 0x77 },
+	{ 0x80ae, 0x41 },
+	{ 0x80af, 0x66 },
+	{ 0x821b, 0xcc },
+	{ 0x821d, 0x80 },
+	{ 0x80a4, 0xe8 },
+	{ 0x8231, 0x13 },
+};
+
+/* QAM Modulation table */
+static struct {
+	u16 reg;
+	u16 data;
+} QAM_mod_tab[] = {
+	{ 0x80a3, 0x09 },
+	{ 0x80a4, 0x00 },
+	{ 0x8081, 0xc4 },
+	{ 0x80a5, 0x40 },
+	{ 0x80aa, 0x77 },
+	{ 0x80ad, 0x77 },
+	{ 0x80a6, 0x67 },
+	{ 0x8262, 0x20 },
+	{ 0x821c, 0x30 },
+	{ 0x80b8, 0x3e },
+	{ 0x80b9, 0xf0 },
+	{ 0x80ba, 0x01 },
+	{ 0x80bb, 0x18 },
+	{ 0x80bc, 0x50 },
+	{ 0x80bd, 0x00 },
+	{ 0x80be, 0xea },
+	{ 0x80bf, 0xef },
+	{ 0x80c0, 0xfc },
+	{ 0x80c1, 0xbd },
+	{ 0x80c2, 0x1f },
+	{ 0x80c3, 0xfc },
+	{ 0x80c4, 0xdd },
+	{ 0x80c5, 0xaf },
+	{ 0x80c6, 0x00 },
+	{ 0x80c7, 0x38 },
+	{ 0x80c8, 0x30 },
+	{ 0x80c9, 0x05 },
+	{ 0x80ca, 0x4a },
+	{ 0x80cb, 0xd0 },
+	{ 0x80cc, 0x01 },
+	{ 0x80cd, 0xd9 },
+	{ 0x80ce, 0x6f },
+	{ 0x80cf, 0xf9 },
+	{ 0x80d0, 0x70 },
+	{ 0x80d1, 0xdf },
+	{ 0x80d2, 0xf7 },
+	{ 0x80d3, 0xc2 },
+	{ 0x80d4, 0xdf },
+	{ 0x80d5, 0x02 },
+	{ 0x80d6, 0x9a },
+	{ 0x80d7, 0xd0 },
+	{ 0x8250, 0x0d },
+	{ 0x8251, 0xcd },
+	{ 0x8252, 0xe0 },
+	{ 0x8253, 0x05 },
+	{ 0x8254, 0xa7 },
+	{ 0x8255, 0xff },
+	{ 0x8256, 0xed },
+	{ 0x8257, 0x5b },
+	{ 0x8258, 0xae },
+	{ 0x8259, 0xe6 },
+	{ 0x825a, 0x3d },
+	{ 0x825b, 0x0f },
+	{ 0x825c, 0x0d },
+	{ 0x825d, 0xea },
+	{ 0x825e, 0xf2 },
+	{ 0x825f, 0x51 },
+	{ 0x8260, 0xf5 },
+	{ 0x8261, 0x06 },
+	{ 0x821a, 0x00 },
+	{ 0x8546, 0x40 },
+	{ 0x8210, 0x26 },
+	{ 0x8211, 0xf6 },
+	{ 0x8212, 0x84 },
+	{ 0x8213, 0x02 },
+	{ 0x8502, 0x01 },
+	{ 0x8121, 0x04 },
+	{ 0x8122, 0x04 },
+	{ 0x852e, 0x10 },
+	{ 0x80a4, 0xca },
+	{ 0x80a7, 0x40 },
+	{ 0x8526, 0x01 },
+};
+
+static int au8522_enable_modulation(struct dvb_frontend *fe,
+				    fe_modulation_t m)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	int i;
+
+	dprintk("%s(0x%08x)\n", __func__, m);
+
+	switch (m) {
+	case VSB_8:
+		dprintk("%s() VSB_8\n", __func__);
+		for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
+			au8522_writereg(state,
+				VSB_mod_tab[i].reg,
+				VSB_mod_tab[i].data);
+		au8522_set_if(fe, state->config->vsb_if);
+		break;
+	case QAM_64:
+	case QAM_256:
+		dprintk("%s() QAM 64/256\n", __func__);
+		for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++)
+			au8522_writereg(state,
+				QAM_mod_tab[i].reg,
+				QAM_mod_tab[i].data);
+		au8522_set_if(fe, state->config->qam_if);
+		break;
+	default:
+		dprintk("%s() Invalid modulation\n", __func__);
+		return -EINVAL;
+	}
+
+	state->current_modulation = m;
+
+	return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int au8522_set_frontend(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *p)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	int ret = -EINVAL;
+
+	dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+	if ((state->current_frequency == p->frequency) &&
+	    (state->current_modulation == p->u.vsb.modulation))
+		return 0;
+
+	au8522_enable_modulation(fe, p->u.vsb.modulation);
+
+	/* Allow the demod to settle */
+	msleep(100);
+
+	if (fe->ops.tuner_ops.set_params) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		ret = fe->ops.tuner_ops.set_params(fe, p);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	if (ret < 0)
+		return ret;
+
+	state->current_frequency = p->frequency;
+
+	return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+int au8522_init(struct dvb_frontend *fe)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	dprintk("%s()\n", __func__);
+
+	au8522_writereg(state, 0xa4, 1 << 5);
+
+	au8522_i2c_gate_ctrl(fe, 1);
+
+	return 0;
+}
+
+static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
+{
+	struct au8522_led_config *led_config = state->config->led_cfg;
+	u8 val;
+
+	/* bail out if we cant control an LED */
+	if (!led_config || !led_config->gpio_output ||
+	    !led_config->gpio_output_enable || !led_config->gpio_output_disable)
+		return 0;
+
+	val = au8522_readreg(state, 0x4000 |
+			     (led_config->gpio_output & ~0xc000));
+	if (onoff) {
+		/* enable GPIO output */
+		val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
+		val |=  (led_config->gpio_output_enable & 0xff);
+	} else {
+		/* disable GPIO output */
+		val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
+		val |=  (led_config->gpio_output_disable & 0xff);
+	}
+	return au8522_writereg(state, 0x8000 |
+			       (led_config->gpio_output & ~0xc000), val);
+}
+
+/* led = 0 | off
+ * led = 1 | signal ok
+ * led = 2 | signal strong
+ * led < 0 | only light led if leds are currently off
+ */
+static int au8522_led_ctrl(struct au8522_state *state, int led)
+{
+	struct au8522_led_config *led_config = state->config->led_cfg;
+	int i, ret = 0;
+
+	/* bail out if we cant control an LED */
+	if (!led_config || !led_config->gpio_leds ||
+	    !led_config->num_led_states || !led_config->led_states)
+		return 0;
+
+	if (led < 0) {
+		/* if LED is already lit, then leave it as-is */
+		if (state->led_state)
+			return 0;
+		else
+			led *= -1;
+	}
+
+	/* toggle LED if changing state */
+	if (state->led_state != led) {
+		u8 val;
+
+		dprintk("%s: %d\n", __func__, led);
+
+		au8522_led_gpio_enable(state, 1);
+
+		val = au8522_readreg(state, 0x4000 |
+				     (led_config->gpio_leds & ~0xc000));
+
+		/* start with all leds off */
+		for (i = 0; i < led_config->num_led_states; i++)
+			val &= ~led_config->led_states[i];
+
+		/* set selected LED state */
+		if (led < led_config->num_led_states)
+			val |= led_config->led_states[led];
+		else if (led_config->num_led_states)
+			val |=
+			led_config->led_states[led_config->num_led_states - 1];
+
+		ret = au8522_writereg(state, 0x8000 |
+				      (led_config->gpio_leds & ~0xc000), val);
+		if (ret < 0)
+			return ret;
+
+		state->led_state = led;
+
+		if (led == 0)
+			au8522_led_gpio_enable(state, 0);
+	}
+
+	return 0;
+}
+
+int au8522_sleep(struct dvb_frontend *fe)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	dprintk("%s()\n", __func__);
+
+	/* turn off led */
+	au8522_led_ctrl(state, 0);
+
+	/* Power down the chip */
+	au8522_writereg(state, 0xa4, 1 << 5);
+
+	state->current_frequency = 0;
+
+	return 0;
+}
+
+static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	u8 reg;
+	u32 tuner_status = 0;
+
+	*status = 0;
+
+	if (state->current_modulation == VSB_8) {
+		dprintk("%s() Checking VSB_8\n", __func__);
+		reg = au8522_readreg(state, 0x4088);
+		if ((reg & 0x03) == 0x03)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+	} else {
+		dprintk("%s() Checking QAM\n", __func__);
+		reg = au8522_readreg(state, 0x4541);
+		if (reg & 0x80)
+			*status |= FE_HAS_VITERBI;
+		if (reg & 0x20)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
+	}
+
+	switch (state->config->status_mode) {
+	case AU8522_DEMODLOCKING:
+		dprintk("%s() DEMODLOCKING\n", __func__);
+		if (*status & FE_HAS_VITERBI)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	case AU8522_TUNERLOCKING:
+		/* Get the tuner status */
+		dprintk("%s() TUNERLOCKING\n", __func__);
+		if (fe->ops.tuner_ops.get_status) {
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 1);
+
+			fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 0);
+		}
+		if (tuner_status)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	}
+	state->fe_status = *status;
+
+	if (*status & FE_HAS_LOCK)
+		/* turn on LED, if it isn't on already */
+		au8522_led_ctrl(state, -1);
+	else
+		/* turn off LED */
+		au8522_led_ctrl(state, 0);
+
+	dprintk("%s() status 0x%08x\n", __func__, *status);
+
+	return 0;
+}
+
+static int au8522_led_status(struct au8522_state *state, const u16 *snr)
+{
+	struct au8522_led_config *led_config = state->config->led_cfg;
+	int led;
+	u16 strong;
+
+	/* bail out if we cant control an LED */
+	if (!led_config)
+		return 0;
+
+	if (0 == (state->fe_status & FE_HAS_LOCK))
+		return au8522_led_ctrl(state, 0);
+	else if (state->current_modulation == QAM_256)
+		strong = led_config->qam256_strong;
+	else if (state->current_modulation == QAM_64)
+		strong = led_config->qam64_strong;
+	else /* (state->current_modulation == VSB_8) */
+		strong = led_config->vsb8_strong;
+
+	if (*snr >= strong)
+		led = 2;
+	else
+		led = 1;
+
+	if ((state->led_state) &&
+	    (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
+		/* snr didn't change enough to bother
+		 * changing the color of the led */
+		return 0;
+
+	return au8522_led_ctrl(state, led);
+}
+
+static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	int ret = -EINVAL;
+
+	dprintk("%s()\n", __func__);
+
+	if (state->current_modulation == QAM_256)
+		ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
+					    ARRAY_SIZE(qam256_mse2snr_tab),
+					    au8522_readreg(state, 0x4522),
+					    snr);
+	else if (state->current_modulation == QAM_64)
+		ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
+					    ARRAY_SIZE(qam64_mse2snr_tab),
+					    au8522_readreg(state, 0x4522),
+					    snr);
+	else /* VSB_8 */
+		ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
+					    ARRAY_SIZE(vsb_mse2snr_tab),
+					    au8522_readreg(state, 0x4311),
+					    snr);
+
+	if (state->config->led_cfg)
+		au8522_led_status(state, snr);
+
+	return ret;
+}
+
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+				       u16 *signal_strength)
+{
+	return au8522_read_snr(fe, signal_strength);
+}
+
+static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	if (state->current_modulation == VSB_8)
+		*ucblocks = au8522_readreg(state, 0x4087);
+	else
+		*ucblocks = au8522_readreg(state, 0x4543);
+
+	return 0;
+}
+
+static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	return au8522_read_ucblocks(fe, ber);
+}
+
+static int au8522_get_frontend(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *p)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	p->frequency = state->current_frequency;
+	p->u.vsb.modulation = state->current_modulation;
+
+	return 0;
+}
+
+static int au8522_get_tune_settings(struct dvb_frontend *fe,
+				    struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1000;
+	return 0;
+}
+
+static struct dvb_frontend_ops au8522_ops;
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+		     u8 client_address)
+{
+	int ret;
+
+	mutex_lock(&au8522_list_mutex);
+	ret = hybrid_tuner_request_state(struct au8522_state, (*state),
+					 hybrid_tuner_instance_list,
+					 i2c, client_address, "au8522");
+	mutex_unlock(&au8522_list_mutex);
+
+	return ret;
+}
+
+void au8522_release_state(struct au8522_state *state)
+{
+	mutex_lock(&au8522_list_mutex);
+	if (state != NULL)
+		hybrid_tuner_release_state(state);
+	mutex_unlock(&au8522_list_mutex);
+}
+
+
+static void au8522_release(struct dvb_frontend *fe)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	au8522_release_state(state);
+}
+
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+				   struct i2c_adapter *i2c)
+{
+	struct au8522_state *state = NULL;
+	int instance;
+
+	/* allocate memory for the internal state */
+	instance = au8522_get_state(&state, i2c, config->demod_address);
+	switch (instance) {
+	case 0:
+		dprintk("%s state allocation failed\n", __func__);
+		break;
+	case 1:
+		/* new demod instance */
+		dprintk("%s using new instance\n", __func__);
+		break;
+	default:
+		/* existing demod instance */
+		dprintk("%s using existing instance\n", __func__);
+		break;
+	}
+
+	/* setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops, &au8522_ops,
+	       sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	if (au8522_init(&state->frontend) != 0) {
+		printk(KERN_ERR "%s: Failed to initialize correctly\n",
+			__func__);
+		goto error;
+	}
+
+	/* Note: Leaving the I2C gate open here. */
+	au8522_i2c_gate_ctrl(&state->frontend, 1);
+
+	return &state->frontend;
+
+error:
+	au8522_release_state(state);
+	return NULL;
+}
+EXPORT_SYMBOL(au8522_attach);
+
+static struct dvb_frontend_ops au8522_ops = {
+
+	.info = {
+		.name			= "Auvitek AU8522 QAM/8VSB Frontend",
+		.type			= FE_ATSC,
+		.frequency_min		= 54000000,
+		.frequency_max		= 858000000,
+		.frequency_stepsize	= 62500,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+
+	.init                 = au8522_init,
+	.sleep                = au8522_sleep,
+	.i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
+	.set_frontend         = au8522_set_frontend,
+	.get_frontend         = au8522_get_frontend,
+	.get_tune_settings    = au8522_get_tune_settings,
+	.read_status          = au8522_read_status,
+	.read_ber             = au8522_read_ber,
+	.read_signal_strength = au8522_read_signal_strength,
+	.read_snr             = au8522_read_snr,
+	.read_ucblocks        = au8522_read_ucblocks,
+	.release              = au8522_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522.h	2009-06-09 23:05:27.000000000 -0400
@@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const
 }
 #endif /* CONFIG_DVB_AU8522 */
 
+/* Other modes may need to be added later */
+enum au8522_video_input {
+	AU8522_COMPOSITE_CH1 = 1,
+	AU8522_COMPOSITE_CH2,
+	AU8522_COMPOSITE_CH3,
+	AU8522_COMPOSITE_CH4,
+	AU8522_COMPOSITE_CH4_SIF,
+	AU8522_SVIDEO_CH13,
+	AU8522_SVIDEO_CH24,
+};
+
+enum au8522_audio_input {
+	AU8522_AUDIO_NONE,
+	AU8522_AUDIO_SIF,
+};
+
 #endif /* __AU8522_H__ */
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_priv.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/au8522_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/au8522_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,412 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+    Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+    Copyright (C) 2005-2008 Auvitek International, Ltd.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "tuner-i2c.h"
+
+struct au8522_state {
+	struct i2c_client *c;
+	struct i2c_adapter *i2c;
+
+	/* Used for sharing of the state between analog and digital mode */
+	struct tuner_i2c_props i2c_props;
+	struct list_head hybrid_tuner_instance_list;
+
+	/* configuration settings */
+	const struct au8522_config *config;
+
+	struct dvb_frontend frontend;
+
+	u32 current_frequency;
+	fe_modulation_t current_modulation;
+
+	u32 fe_status;
+	unsigned int led_state;
+
+	/* Analog settings */
+	struct v4l2_subdev sd;
+	v4l2_std_id std;
+	int vid_input;
+	int aud_input;
+	u32 id;
+	u32 rev;
+	u8 brightness;
+	u8 contrast;
+};
+
+/* These are routines shared by both the VSB/QAM demodulator and the analog
+   decoder */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
+u8 au8522_readreg(struct au8522_state *state, u16 reg);
+int au8522_init(struct dvb_frontend *fe);
+int au8522_sleep(struct dvb_frontend *fe);
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+		     u8 client_address);
+void au8522_release_state(struct au8522_state *state);
+
+/* REGISTERS */
+#define AU8522_INPUT_CONTROL_REG081H			0x081
+#define AU8522_PGA_CONTROL_REG082H			0x082
+#define AU8522_CLAMPING_CONTROL_REG083H			0x083
+
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H		0x0A3
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H		0x0A4
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H		0x0A5
+#define AU8522_AGC_CONTROL_RANGE_REG0A6H		0x0A6
+#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H		0x0A7
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H  		0x0A8
+#define AU8522_TUNER_AGC_RF_START_REG0A9H		0x0A9
+#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH		0x0AA
+#define AU8522_TUNER_AGC_IF_STOP_REG0ABH		0x0AB
+#define AU8522_TUNER_AGC_IF_START_REG0ACH		0x0AC
+#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH		0x0AD
+#define AU8522_TUNER_AGC_STEP_REG0AEH			0x0AE
+#define AU8522_TUNER_GAIN_STEP_REG0AFH			0x0AF
+
+/* Receiver registers */
+#define AU8522_FRMREGTHRD1_REG0B0H			0x0B0
+#define AU8522_FRMREGAGC1H_REG0B1H 			0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H 			0x0B2
+#define AU8522_TOREGAGC1_REG0B3H 			0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H 			0x0B4
+#define AU8522_FRMREGBBH_REG0B5H			0x0B5
+#define AU8522_FRMREGBBM_REG0B6H 			0x0B6
+#define AU8522_FRMREGBBL_REG0B7H     			0x0B7
+/* 0xB8 TO 0xD7 are the filter coefficients */
+#define AU8522_FRMREGTHRD2_REG0D8H 			0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H 			0x0D9
+#define AU8522_TOREGAGC2_REG0DAH 			0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH 			0x0DB
+#define AU8522_FRMREGPILOTH_REG0DCH			0x0DC
+#define AU8522_FRMREGPILOTM_REG0DDH			0x0DD
+#define AU8522_FRMREGPILOTL_REG0DEH			0x0DE
+#define AU8522_TOREGFREQ_REG0DFH			0x0DF
+
+#define AU8522_RX_PGA_RFOUT_REG0EBH			0x0EB
+#define AU8522_RX_PGA_IFOUT_REG0ECH			0x0EC
+#define AU8522_RX_PGA_PGAOUT_REG0EDH			0x0ED
+
+#define AU8522_CHIP_MODE_REG0FEH			0x0FE
+
+/* I2C bus control registers */
+#define AU8522_I2C_CONTROL_REG0_REG090H    		0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H    		0x091
+#define AU8522_I2C_STATUS_REG092H          		0x092
+#define AU8522_I2C_WR_DATA0_REG093H			0x093
+#define AU8522_I2C_WR_DATA1_REG094H			0x094
+#define AU8522_I2C_WR_DATA2_REG095H			0x095
+#define AU8522_I2C_WR_DATA3_REG096H			0x096
+#define AU8522_I2C_WR_DATA4_REG097H			0x097
+#define AU8522_I2C_WR_DATA5_REG098H			0x098
+#define AU8522_I2C_WR_DATA6_REG099H			0x099
+#define AU8522_I2C_WR_DATA7_REG09AH			0x09A
+#define AU8522_I2C_RD_DATA0_REG09BH			0x09B
+#define AU8522_I2C_RD_DATA1_REG09CH			0x09C
+#define AU8522_I2C_RD_DATA2_REG09DH			0x09D
+#define AU8522_I2C_RD_DATA3_REG09EH			0x09E
+#define AU8522_I2C_RD_DATA4_REG09FH			0x09F
+#define AU8522_I2C_RD_DATA5_REG0A0H			0x0A0
+#define AU8522_I2C_RD_DATA6_REG0A1H			0x0A1
+#define AU8522_I2C_RD_DATA7_REG0A2H			0x0A2
+
+#define AU8522_ENA_USB_REG101H				0x101
+
+#define AU8522_I2S_CTRL_0_REG110H  			0x110
+#define AU8522_I2S_CTRL_1_REG111H 			0x111
+#define AU8522_I2S_CTRL_2_REG112H 			0x112
+
+#define AU8522_FRMREGFFECONTROL_REG121H    		0x121
+#define AU8522_FRMREGDFECONTROL_REG122H    		0x122
+
+#define AU8522_CARRFREQOFFSET0_REG201H 			0x201
+#define AU8522_CARRFREQOFFSET1_REG202H			0x202
+
+#define AU8522_DECIMATION_GAIN_REG21AH			0x21A
+#define AU8522_FRMREGIFSLP_REG21BH 			0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH 			0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH 			0x21D
+#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH		0x21E
+#define AU8522_FRMREGPLLMODE_REG21FH 			0x21F
+#define AU8522_FRMREGCSTHRD_REG220H 			0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H 		0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H 		0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H 		0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H 		0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H 		0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H 		0x226
+#define AU_FRMREGPLLACQPHASESCL_REG227H			0x227
+#define AU8522_FRMREGFREQFBCTRL_REG228H 		0x228
+
+/* Analog TV Decoder */
+#define AU8522_TVDEC_STATUS_REG000H			0x000
+#define AU8522_TVDEC_INT_STATUS_REG001H			0x001
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 	0x002
+#define AU8522_TVDEC_SHARPNESSREG009H			0x009
+#define AU8522_TVDEC_BRIGHTNESS_REG00AH			0x00A
+#define AU8522_TVDEC_CONTRAST_REG00BH			0x00B
+#define AU8522_TVDEC_SATURATION_CB_REG00CH		0x00C
+#define AU8522_TVDEC_SATURATION_CR_REG00DH		0x00D
+#define AU8522_TVDEC_HUE_H_REG00EH			0x00E
+#define AU8522_TVDEC_HUE_L_REG00FH                   	0x00F
+#define AU8522_TVDEC_INT_MASK_REG010H			0x010
+#define AU8522_VIDEO_MODE_REG011H			0x011
+#define AU8522_TVDEC_PGA_REG012H			0x012
+#define AU8522_TVDEC_COMB_MODE_REG015H			0x015
+#define AU8522_REG016H                            	0x016
+#define AU8522_TVDED_DBG_MODE_REG060H			0x060
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H		0x061
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H		0x062
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H		0x063
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H		0x064
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H		0x065
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H		0x066
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H		0x067
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H		0x068
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H   		0x069
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH		0x06A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH   		0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH  		0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 		0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH       	0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH  		0x06F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H		0x070
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H		0x073
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H			0x077
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H		0x078
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H		0x079
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH	0x07A
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH			0x07B
+#define AU8522_TVDEC_PLL_STATUS_REG07EH			0x07E
+#define AU8522_TVDEC_FSC_FREQ_REG07FH			0x07F
+
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H		0x0E4
+#define AU8522_TOREGAAGC_REG0E5H			0x0E5
+
+#define AU8522_TVDEC_CHROMA_AGC_REG401H		0x401
+#define AU8522_TVDEC_CHROMA_SFT_REG402H		0x402
+#define AU8522_FILTER_COEF_R410     		0x410
+#define AU8522_FILTER_COEF_R411     		0x411
+#define AU8522_FILTER_COEF_R412     		0x412
+#define AU8522_FILTER_COEF_R413     		0x413
+#define AU8522_FILTER_COEF_R414     		0x414
+#define AU8522_FILTER_COEF_R415     		0x415
+#define AU8522_FILTER_COEF_R416     		0x416
+#define AU8522_FILTER_COEF_R417     		0x417
+#define AU8522_FILTER_COEF_R418     		0x418
+#define AU8522_FILTER_COEF_R419     		0x419
+#define AU8522_FILTER_COEF_R41A     		0x41A
+#define AU8522_FILTER_COEF_R41B     		0x41B
+#define AU8522_FILTER_COEF_R41C     		0x41C
+#define AU8522_FILTER_COEF_R41D     		0x41D
+#define AU8522_FILTER_COEF_R41E     		0x41E
+#define AU8522_FILTER_COEF_R41F     		0x41F
+#define AU8522_FILTER_COEF_R420     		0x420
+#define AU8522_FILTER_COEF_R421     		0x421
+#define AU8522_FILTER_COEF_R422     		0x422
+#define AU8522_FILTER_COEF_R423     		0x423
+#define AU8522_FILTER_COEF_R424     		0x424
+#define AU8522_FILTER_COEF_R425     		0x425
+#define AU8522_FILTER_COEF_R426     		0x426
+#define AU8522_FILTER_COEF_R427     		0x427
+#define AU8522_FILTER_COEF_R428     		0x428
+#define AU8522_FILTER_COEF_R429     		0x429
+#define AU8522_FILTER_COEF_R42A     		0x42A
+#define AU8522_FILTER_COEF_R42B     		0x42B
+#define AU8522_FILTER_COEF_R42C     		0x42C
+#define AU8522_FILTER_COEF_R42D     		0x42D
+
+/* VBI Control Registers */
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H  	0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H  	0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H      	0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H       	0x007
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H			0x017
+#define AU8522_TVDEC_VBI_CTRL_L_REG018H			0x018
+#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H	0x019
+#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH		0x01A
+#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH		0x01B
+#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH		0x01C
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH	0x01E
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH   	0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H   	0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 	0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H  	0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H	0x023
+
+#define AU8522_REG071H					0x071
+#define AU8522_REG072H					0x072
+#define AU8522_REG074H					0x074
+#define AU8522_REG075H					0x075
+
+/* Digital Demodulator Registers */
+#define AU8522_FRAME_COUNT0_REG084H			0x084
+#define AU8522_RS_STATUS_G0_REG085H			0x085
+#define AU8522_RS_STATUS_B0_REG086H			0x086
+#define AU8522_RS_STATUS_E_REG087H			0x087
+#define AU8522_DEMODULATION_STATUS_REG088H		0x088
+#define AU8522_TOREGTRESTATUS_REG0E6H			0x0E6
+#define AU8522_TSPORT_CONTROL_REG10BH			0x10B
+#define AU8522_TSTHES_REG10CH				0x10C
+#define AU8522_FRMREGDFEKEEP_REG301H			0x301
+#define AU8522_DFE_AVERAGE_REG302H			0x302
+#define AU8522_FRMREGEQLERRWIN_REG303H			0x303
+#define AU8522_FRMREGFFEKEEP_REG304H			0x304
+#define AU8522_FRMREGDFECONTROL1_REG305H		0x305
+#define AU8522_FRMREGEQLERRLOW_REG306H			0x306
+
+#define AU8522_REG42EH				0x42E
+#define AU8522_REG42FH				0x42F
+#define AU8522_REG430H				0x430
+#define AU8522_REG431H				0x431
+#define AU8522_REG432H				0x432
+#define AU8522_REG433H				0x433
+#define AU8522_REG434H				0x434
+#define AU8522_REG435H				0x435
+#define AU8522_REG436H				0x436
+
+/* GPIO Registers */
+#define AU8522_GPIO_CONTROL_REG0E0H			0x0E0
+#define AU8522_GPIO_STATUS_REG0E1H			0x0E1
+#define AU8522_GPIO_DATA_REG0E2H			0x0E2
+
+/* Audio Control Registers */
+#define AU8522_AUDIOAGC_REG0EEH 			0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H 			0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H 			0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H 			0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H 			0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H 			0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H 			0x0F7
+#define AU8522_REG0F9H					0x0F9
+
+#define AU8522_AUDIOAGC2_REG605H 			0x605
+#define AU8522_AUDIOFREQ_REG606H 			0x606
+
+
+/**************************************************************/
+
+#define AU8522_INPUT_CONTROL_REG081H_ATSC               	0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF			0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF13			0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B64             	0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256            	0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS               	0x20
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1			0xA2
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2			0xA0
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3			0x69
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4			0x68
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF        	0x28
+/* CH1 AS Y,CH3 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13        	0x23
+/* CH2 AS Y,CH4 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24        	0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC        	0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64      	0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256    		0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS        	0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF       	0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13		0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO		0x02
+
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR		0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO		0x9C
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS     	0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC		0xE8
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 		0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64  		0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF   		0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13		0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL		0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM		0xDD
+
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC		0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 		0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64  		0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC	0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256	0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64	0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR	0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF		0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13		0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO  		0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS		0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM     		0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS      	0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL		0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM		0x01
+
+/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
+#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS			0x79
+#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS			0x80
+#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS			0x80
+#define AU8522_TVDEC_HUE_H_REG00EH_CVBS				0x00
+#define AU8522_TVDEC_HUE_L_REG00FH_CVBS				0x00
+#define AU8522_TVDEC_PGA_REG012H_CVBS				0x0F
+#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS			0x00
+#define AU8522_REG016H_CVBS					0x00
+#define AU8522_TVDED_DBG_MODE_REG060H_CVBS			0x00
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS			0x0B
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13		0x03
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13		0x00
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS			0x19
+#define AU8522_REG0F9H_AUDIO					0x20
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS			0xA7
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS		0x0A
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS		0x32
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS		0x19
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS		0x23
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS		0x41
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS		0x0A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS		0x32
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS		0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS		0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS		0x6E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS			0x0F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS		0x80
+#define AU8522_REG071H_CVBS					0x18
+#define AU8522_REG072H_CVBS					0x30
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS		0xF0
+#define AU8522_REG074H_CVBS					0x80
+#define AU8522_REG075H_CVBS					0xF0
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS			0xFB
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS			0x04
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS		0x00
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS		0x00
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS			0xEE
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS			0xFE
+#define AU8522_TOREGAAGC_REG0E5H_CVBS				0x00
+#define AU8522_TVDEC_VBI6A_REG035H_CVBS				0x40
+
+/* Enables Closed captioning */
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON			0x21
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24113.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24113.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24113.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24113.c	2009-06-09 23:05:27.000000000 -0400
@@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(stru
 		kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
 	int rc;
 	if (state == NULL) {
-		err("Unable to kmalloc\n");
+		err("Unable to kzalloc\n");
 		goto error;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24116.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24116.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24116.c	2013-05-03 18:01:17.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24116.c	2013-05-03 16:45:09.000000000 -0400
@@ -15,6 +15,9 @@
 	September, 9th 2008
 	    Fixed locking on high symbol rates (>30000).
 	    Implement MPEG initialization parameter.
+	January, 17th 2009
+	    Fill set_voltage with actually control voltage code.
+	    Correct set tone to not affect voltage.
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -146,7 +149,7 @@ enum cmds {
 	CMD_GETAGC      = 0x19,
 	CMD_LNBCONFIG   = 0x20,
 	CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
-	CMD_SET_TONEPRE = 0x22,
+	CMD_LNBDCLEVEL  = 0x22,
 	CMD_SET_TONE    = 0x23,
 	CMD_UPDFWVERS   = 0x35,
 	CMD_TUNERSLEEP  = 0x36,
@@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct
 	return 0;
 }
 
-static int cx24116_set_voltage(struct dvb_frontend *fe,
-	fe_sec_voltage_t voltage)
-{
-	/* The isl6421 module will override this function in the fops. */
-	dprintk("%s() This should never appear if the isl6421 module "
-		"is loaded correctly\n", __func__);
-
-	return -EOPNOTSUPP;
-}
-
 static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
 	struct cx24116_state *state = fe->demodulator_priv;
@@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct d
 	return -ETIMEDOUT; /* -EBUSY ? */
 }
 
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+	fe_sec_voltage_t voltage)
+{
+	struct cx24116_cmd cmd;
+	int ret;
+
+	dprintk("%s: %s\n", __func__,
+		voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+		voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+	/* Wait for LNB ready */
+	ret = cx24116_wait_for_lnb(fe);
+	if (ret != 0)
+		return ret;
+
+	/* Wait for voltage/min repeat delay */
+	msleep(100);
+
+	cmd.args[0x00] = CMD_LNBDCLEVEL;
+	cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+	cmd.len = 0x02;
+
+	/* Min delay time before DiSEqC send */
+	msleep(15);
+
+	return cx24116_cmd_execute(fe, &cmd);
+}
+
 static int cx24116_set_tone(struct dvb_frontend *fe,
 	fe_sec_tone_mode_t tone)
 {
@@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_f
 	/* Min delay time after DiSEqC send */
 	msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
 
-	/* This is always done before the tone is set */
-	cmd.args[0x00] = CMD_SET_TONEPRE;
-	cmd.args[0x01] = 0x00;
-	cmd.len = 0x02;
-	ret = cx24116_cmd_execute(fe, &cmd);
-	if (ret != 0)
-		return ret;
-
 	/* Now we set the tone */
 	cmd.args[0x00] = CMD_SET_TONE;
 	cmd.args[0x01] = 0x00;
@@ -1099,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(cons
 	dprintk("%s\n", __func__);
 
 	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+	state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
 	if (state == NULL)
 		goto error1;
 
-	/* setup the state */
-	memset(state, 0, sizeof(struct cx24116_state));
-
 	state->config = config;
 	state->i2c = i2c;
 
@@ -1154,7 +1164,12 @@ static int cx24116_initfe(struct dvb_fro
 	if (ret != 0)
 		return ret;
 
-	return cx24116_diseqc_init(fe);
+	ret = cx24116_diseqc_init(fe);
+	if (ret != 0)
+		return ret;
+
+	/* HVR-4000 needs this */
+	return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24123.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24123.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/cx24123.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/cx24123.c	2009-06-09 23:05:27.000000000 -0400
@@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_o
 struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
 				    struct i2c_adapter *i2c)
 {
+	/* allocate memory for the internal state */
 	struct cx24123_state *state =
 		kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
 
 	dprintk("\n");
-	/* allocate memory for the internal state */
 	if (state == NULL) {
-		err("Unable to kmalloc\n");
+		err("Unable to kzalloc\n");
 		goto error;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib0070.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib0070.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib0070.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib0070.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,6 +58,4 @@ static inline u16 dib0070_wbd_offset(str
 }
 #endif
 
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib3000mc.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib3000mc.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib3000mc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib3000mc.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,19 +39,43 @@ struct dib3000mc_config {
 #define DEFAULT_DIB3000MC_I2C_ADDRESS 16
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 
-#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
-extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
+#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
+				      defined(MODULE))
+extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
+					     u8 i2c_addr,
+					     struct dib3000mc_config *cfg);
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+				     int no_of_demods, u8 default_addr,
+				     struct dib3000mc_config cfg[]);
+extern
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+						   int gating);
 #else
-static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+static inline
+struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+				      struct dib3000mc_config *cfg)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_DVB_DIB3000MC
 
-extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]);
+static inline
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+			      int no_of_demods, u8 default_addr,
+			      struct dib3000mc_config cfg[])
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
 
-extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
+static inline
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+						   int gating)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
 
 extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
 extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib7000m.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib7000m.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib7000m.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib7000m.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,8 +38,32 @@ struct dib7000m_config {
 
 #define DEFAULT_DIB7000M_I2C_ADDRESS 18
 
-extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg);
-extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
+				     defined(MODULE))
+extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+					    u8 i2c_addr,
+					    struct dib7000m_config *cfg);
+extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
+						   enum dibx000_i2c_interface,
+						   int);
+#else
+static inline
+struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+				     u8 i2c_addr, struct dib7000m_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+static inline
+struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
+					    enum dibx000_i2c_interface intf,
+					    int gating)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
 
 /* TODO
 extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib7000p.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib7000p.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dib7000p.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dib7000p.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,7 +37,8 @@ struct dib7000p_config {
 
 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
 
-#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE))
+#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
+				     defined(MODULE))
 extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
 					    u8 i2c_addr,
 					    struct dib7000p_config *cfg);
@@ -49,10 +50,11 @@ extern int dib7000p_i2c_enumeration(stru
 				    struct dib7000p_config cfg[]);
 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);
 #else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
-						   u8 i2c_addr,
-						   struct dib7000p_config *cfg)
+static inline
+struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+				     struct dib7000p_config *cfg)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
@@ -60,36 +62,39 @@ static inline struct dvb_frontend *dib70
 
 static inline
 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
-					    enum dibx000_i2c_interface i, int x)
+					    enum dibx000_i2c_interface i,
+					    int x)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 
-static inline
-int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
-				    int no_of_demods, u8 default_addr,
-				    struct dib7000p_config cfg[])
+static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
+					   int no_of_demods, u8 default_addr,
+					   struct dib7000p_config cfg[])
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
 
-static inline
-int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+static inline int dib7000p_set_gpio(struct dvb_frontend *fe,
+				    u8 num, u8 dir, u8 val)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
 
-static inline
-int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
-#endif
 
-extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+#endif
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/drx397xD.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/drx397xD.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 18:01:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/drx397xD.c	2013-05-03 16:45:16.000000000 -0400
@@ -74,7 +74,7 @@ static struct {
 } fw[] = {
 #define _FW_ENTRY(a, b, c)	{					\
 			.name	= a,					\
-			.file	= 0,					\
+			.file	= NULL,					\
 			.lock	= __RW_LOCK_UNLOCKED(fw[c].lock),	\
 			.refcnt = 0,					\
 			.data	= { }		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dvb_dummy_fe.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dvb_dummy_fe.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/dvb_dummy_fe.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/dvb_dummy_fe.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,8 +25,27 @@
 #include <linux/dvb/frontend.h>
 #include "dvb_frontend.h"
 
+#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
+defined(MODULE))
 extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
+#else
+static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_DUMMY_FE */
 
 #endif // DVB_DUMMY_FE_H
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/itd1000_priv.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/itd1000_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/itd1000_priv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/itd1000_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ struct itd1000_state {
 	/* ugly workaround for flexcop's incapable i2c-controller
 	 * FIXME, if possible
 	 */
-	u8 shadow[255];
+	u8 shadow[256];
 };
 
 enum itd1000_register {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,17 +1,21 @@
-menu "Customise DVB Frontends"
-	depends on DVB_CORE
-
 config DVB_FE_CUSTOMISE
 	bool "Customise the frontend modules to build"
+	depends on DVB_CORE
 	default N
 	help
-	  This allows the user to deselect frontend drivers unnecessary
-	  for their hardware from the build. Use this option with care
-	  as deselecting frontends which are in fact necessary will result
-	  in DVB devices which cannot be tuned due to lack of driver support.
+	  This allows the user to select/deselect frontend drivers for their
+	  hardware from the build.
+
+	  Use this option with care as deselecting frontends which are in fact
+	  necessary will result in DVB devices which cannot be tuned due to lack
+	  of driver support.
 
 	  If unsure say N.
 
+if DVB_FE_CUSTOMISE
+
+menu "Customise DVB Frontends"
+
 comment "Multistandard (satellite) frontends"
 	depends on DVB_CORE
 
@@ -55,6 +59,13 @@ config DVB_MT312
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_ZL10036
+	tristate "Zarlink ZL10036 silicon tuner"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S tuner module. Say Y when you want to support this frontend.
+
 config DVB_S5H1420
 	tristate "Samsung S5H1420 based"
 	depends on DVB_CORE && I2C
@@ -83,6 +94,20 @@ config DVB_STV0299
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_STV6110
+	tristate "ST STV6110 silicon tuner"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	  help
+	  A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_STV0900
+	tristate "ST STV0900 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
+
 config DVB_TDA8083
 	tristate "Philips TDA8083 based"
 	depends on DVB_CORE && I2C
@@ -288,6 +313,13 @@ config DVB_TDA10048
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
+config DVB_AF9013
+	tristate "Afatech AF9013 demodulator"
+	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
 
@@ -387,6 +419,14 @@ config DVB_LGDT3304
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 
+config DVB_LGDT3305
+	tristate "LG Electronics LGDT3305 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+	  to support this frontend.
+
 config DVB_S5H1409
 	tristate "Samsung S5H1409 based"
 	depends on DVB_CORE && I2C
@@ -397,7 +437,7 @@ config DVB_S5H1409
 
 config DVB_AU8522
 	tristate "Auvitek AU8522 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && VIDEO_V4L2
 	default m if DVB_FE_CUSTOMISE
 	help
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -439,18 +479,18 @@ config DVB_TUNER_DIB0070
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner DiB0070 from DiBcom.
-	  This device is only used inside a SiP called togther with a
+	  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
 
 config DVB_LNBP21
-	tristate "LNBP21 SEC controller"
+	tristate "LNBP21/LNBH24 SEC controllers"
 	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
-	  An SEC control chip.
+	  An SEC control chips.
 
 config DVB_ISL6405
 	tristate "ISL6405 SEC controller"
@@ -473,16 +513,18 @@ config DVB_LGS8GL5
 	help
 	  A DMB-TH tuner module. Say Y when you want to support this frontend.
 
+config DVB_LGS8GXX
+	tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX 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.
+
 comment "Tools to develop new frontends"
 
 config DVB_DUMMY_FE
 	tristate "Dummy frontend driver"
 	default n
-
-config DVB_AF9013
-	tristate "Afatech AF9013 demodulator"
-	depends on DVB_CORE && I2C
-	default m if DVB_FE_CUSTOMISE
-	help
-	  Say Y when you want to support this frontend.
 endmenu
+
+endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3304.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3304.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3304.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3304.c	2009-06-09 23:05:27.000000000 -0400
@@ -363,7 +363,6 @@ struct dvb_frontend* lgdt3304_attach(con
 
 	struct lgdt3304_state *state;
 	state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
-	memset(state, 0x0, sizeof(struct lgdt3304_state));
 	state->addr = config->i2c_address;
 	state->i2c = i2c;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3305.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3305.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1087 @@
+/*
+ *    Support for LGDT3305 - VSB/QAM
+ *
+ *    Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "lgdt3305.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG  2
+
+#define lg_printk(kern, fmt, arg...)					\
+	printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...)	printk(KERN_INFO "lgdt3305: " fmt, ##arg)
+#define lg_warn(fmt, arg...)	lg_printk(KERN_WARNING,       fmt, ##arg)
+#define lg_err(fmt, arg...)	lg_printk(KERN_ERR,           fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO)			\
+				lg_printk(KERN_DEBUG,         fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG)			\
+				lg_printk(KERN_DEBUG,         fmt, ##arg)
+
+#define lg_fail(ret)							\
+({									\
+	int __ret;							\
+	__ret = (ret < 0);						\
+	if (__ret)							\
+		lg_err("error %d on line %d\n",	ret, __LINE__);		\
+	__ret;								\
+})
+
+struct lgdt3305_state {
+	struct i2c_adapter *i2c_adap;
+	const struct lgdt3305_config *cfg;
+
+	struct dvb_frontend frontend;
+
+	fe_modulation_t current_modulation;
+	u32 current_frequency;
+	u32 snr;
+};
+
+/* ------------------------------------------------------------------------ */
+
+#define LGDT3305_GEN_CTRL_1                   0x0000
+#define LGDT3305_GEN_CTRL_2                   0x0001
+#define LGDT3305_GEN_CTRL_3                   0x0002
+#define LGDT3305_GEN_STATUS                   0x0003
+#define LGDT3305_GEN_CONTROL                  0x0007
+#define LGDT3305_GEN_CTRL_4                   0x000a
+#define LGDT3305_DGTL_AGC_REF_1               0x0012
+#define LGDT3305_DGTL_AGC_REF_2               0x0013
+#define LGDT3305_CR_CTR_FREQ_1                0x0106
+#define LGDT3305_CR_CTR_FREQ_2                0x0107
+#define LGDT3305_CR_CTR_FREQ_3                0x0108
+#define LGDT3305_CR_CTR_FREQ_4                0x0109
+#define LGDT3305_CR_MSE_1                     0x011b
+#define LGDT3305_CR_MSE_2                     0x011c
+#define LGDT3305_CR_LOCK_STATUS               0x011d
+#define LGDT3305_CR_CTRL_7                    0x0126
+#define LGDT3305_AGC_POWER_REF_1              0x0300
+#define LGDT3305_AGC_POWER_REF_2              0x0301
+#define LGDT3305_AGC_DELAY_PT_1               0x0302
+#define LGDT3305_AGC_DELAY_PT_2               0x0303
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_1         0x0306
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_2         0x0307
+#define LGDT3305_IFBW_1                       0x0308
+#define LGDT3305_IFBW_2                       0x0309
+#define LGDT3305_AGC_CTRL_1                   0x030c
+#define LGDT3305_AGC_CTRL_4                   0x0314
+#define LGDT3305_EQ_MSE_1                     0x0413
+#define LGDT3305_EQ_MSE_2                     0x0414
+#define LGDT3305_EQ_MSE_3                     0x0415
+#define LGDT3305_PT_MSE_1                     0x0417
+#define LGDT3305_PT_MSE_2                     0x0418
+#define LGDT3305_PT_MSE_3                     0x0419
+#define LGDT3305_FEC_BLOCK_CTRL               0x0504
+#define LGDT3305_FEC_LOCK_STATUS              0x050a
+#define LGDT3305_FEC_PKT_ERR_1                0x050c
+#define LGDT3305_FEC_PKT_ERR_2                0x050d
+#define LGDT3305_TP_CTRL_1                    0x050e
+#define LGDT3305_BERT_PERIOD                  0x0801
+#define LGDT3305_BERT_ERROR_COUNT_1           0x080a
+#define LGDT3305_BERT_ERROR_COUNT_2           0x080b
+#define LGDT3305_BERT_ERROR_COUNT_3           0x080c
+#define LGDT3305_BERT_ERROR_COUNT_4           0x080d
+
+static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
+{
+	int ret;
+	u8 buf[] = { reg >> 8, reg & 0xff, val };
+	struct i2c_msg msg = {
+		.addr = state->cfg->i2c_addr, .flags = 0,
+		.buf = buf, .len = 3,
+	};
+
+	lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+	ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+	if (ret != 1) {
+		lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+		       msg.buf[0], msg.buf[1], msg.buf[2], ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
+{
+	int ret;
+	u8 reg_buf[] = { reg >> 8, reg & 0xff };
+	struct i2c_msg msg[] = {
+		{ .addr = state->cfg->i2c_addr,
+		  .flags = 0, .buf = reg_buf, .len = 2 },
+		{ .addr = state->cfg->i2c_addr,
+		  .flags = I2C_M_RD, .buf = val, .len = 1 },
+	};
+
+	lg_reg("reg: 0x%04x\n", reg);
+
+	ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+	if (ret != 2) {
+		lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+		       state->cfg->i2c_addr, reg, ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EREMOTEIO;
+	}
+	return 0;
+}
+
+#define read_reg(state, reg)						\
+({									\
+	u8 __val;							\
+	int ret = lgdt3305_read_reg(state, reg, &__val);		\
+	if (lg_fail(ret))						\
+		__val = 0;						\
+	__val;								\
+})
+
+static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
+				u16 reg, int bit, int onoff)
+{
+	u8 val;
+	int ret;
+
+	lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+	ret = lgdt3305_read_reg(state, reg, &val);
+	if (lg_fail(ret))
+		goto fail;
+
+	val &= ~(1 << bit);
+	val |= (onoff & 1) << bit;
+
+	ret = lgdt3305_write_reg(state, reg, val);
+fail:
+	return ret;
+}
+
+struct lgdt3305_reg {
+	u16 reg;
+	u8 val;
+};
+
+static int lgdt3305_write_regs(struct lgdt3305_state *state,
+			       struct lgdt3305_reg *regs, int len)
+{
+	int i, ret;
+
+	lg_reg("writing %d registers...\n", len);
+
+	for (i = 0; i < len - 1; i++) {
+		ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
+		if (lg_fail(ret))
+			return ret;
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_soft_reset(struct lgdt3305_state *state)
+{
+	int ret;
+
+	lg_dbg("\n");
+
+	ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
+	if (lg_fail(ret))
+		goto fail;
+
+	msleep(20);
+	ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
+fail:
+	return ret;
+}
+
+static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
+				     enum lgdt3305_mpeg_mode mode)
+{
+	lg_dbg("(%d)\n", mode);
+	return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
+}
+
+static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
+				       enum lgdt3305_tp_clock_edge edge,
+				       enum lgdt3305_tp_valid_polarity valid)
+{
+	u8 val;
+	int ret;
+
+	lg_dbg("edge = %d, valid = %d\n", edge, valid);
+
+	ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
+	if (lg_fail(ret))
+		goto fail;
+
+	val &= ~0x09;
+
+	if (edge)
+		val |= 0x08;
+	if (valid)
+		val |= 0x01;
+
+	ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
+	if (lg_fail(ret))
+		goto fail;
+
+	ret = lgdt3305_soft_reset(state);
+fail:
+	return ret;
+}
+
+static int lgdt3305_set_modulation(struct lgdt3305_state *state,
+				   struct dvb_frontend_parameters *param)
+{
+	u8 opermode;
+	int ret;
+
+	lg_dbg("\n");
+
+	ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
+	if (lg_fail(ret))
+		goto fail;
+
+	opermode &= ~0x03;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		opermode |= 0x03;
+		break;
+	case QAM_64:
+		opermode |= 0x00;
+		break;
+	case QAM_256:
+		opermode |= 0x01;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
+fail:
+	return ret;
+}
+
+static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
+					 struct dvb_frontend_parameters *param)
+{
+	int val;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		val = 0;
+		break;
+	case QAM_64:
+	case QAM_256:
+		val = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	lg_dbg("val = %d\n", val);
+
+	return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
+					 struct dvb_frontend_parameters *param)
+{
+	u16 agc_ref;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		agc_ref = 0x32c4;
+		break;
+	case QAM_64:
+		agc_ref = 0x2a00;
+		break;
+	case QAM_256:
+		agc_ref = 0x2a80;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	lg_dbg("agc ref: 0x%04x\n", agc_ref);
+
+	lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
+	lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
+
+	return 0;
+}
+
+static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
+			       struct dvb_frontend_parameters *param)
+{
+	u16 ifbw, rfbw, agcdelay;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		agcdelay = 0x04c0;
+		rfbw     = 0x8000;
+		ifbw     = 0x8000;
+		break;
+	case QAM_64:
+	case QAM_256:
+		agcdelay = 0x046b;
+		rfbw     = 0x8889;
+		ifbw     = 0x8888;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (state->cfg->rf_agc_loop) {
+		lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
+
+		/* rf agc loop filter bandwidth */
+		lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
+				   agcdelay >> 8);
+		lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
+				   agcdelay & 0xff);
+
+		lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+				   rfbw >> 8);
+		lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+				   rfbw & 0xff);
+	} else {
+		lg_dbg("ifbw: 0x%04x\n", ifbw);
+
+		/* if agc loop filter bandwidth */
+		lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
+		lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
+	}
+
+	return 0;
+}
+
+static int lgdt3305_agc_setup(struct lgdt3305_state *state,
+			      struct dvb_frontend_parameters *param)
+{
+	int lockdten, acqen;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		lockdten = 0;
+		acqen = 0;
+		break;
+	case QAM_64:
+	case QAM_256:
+		lockdten = 1;
+		acqen = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
+
+	/* control agc function */
+	lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+	lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+
+	return lgdt3305_rfagc_loop(state, param);
+}
+
+static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
+				      struct dvb_frontend_parameters *param)
+{
+	u16 usref = 0;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		if (state->cfg->usref_8vsb)
+			usref = state->cfg->usref_8vsb;
+		break;
+	case QAM_64:
+		if (state->cfg->usref_qam64)
+			usref = state->cfg->usref_qam64;
+		break;
+	case QAM_256:
+		if (state->cfg->usref_qam256)
+			usref = state->cfg->usref_qam256;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (usref) {
+		lg_dbg("set manual mode: 0x%04x\n", usref);
+
+		lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
+
+		lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
+				   0xff & (usref >> 8));
+		lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
+				   0xff & (usref >> 0));
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
+				       struct dvb_frontend_parameters *param,
+				       int inversion)
+{
+	int ret;
+
+	lg_dbg("(%d)\n", inversion);
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
+					 inversion ? 0xf9 : 0x79);
+		break;
+	case QAM_64:
+	case QAM_256:
+		ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
+					 inversion ? 0xfd : 0xff);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lgdt3305_set_if(struct lgdt3305_state *state,
+			   struct dvb_frontend_parameters *param)
+{
+	u16 if_freq_khz;
+	u8 nco1, nco2, nco3, nco4;
+	u64 nco;
+
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+		if_freq_khz = state->cfg->vsb_if_khz;
+		break;
+	case QAM_64:
+	case QAM_256:
+		if_freq_khz = state->cfg->qam_if_khz;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nco = if_freq_khz / 10;
+
+#define LGDT3305_64BIT_DIVISION_ENABLED 0
+	/* FIXME: 64bit division disabled to avoid linking error:
+	 * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
+	 */
+	switch (param->u.vsb.modulation) {
+	case VSB_8:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+		nco <<= 24;
+		nco /= 625;
+#else
+		nco *= ((1 << 24) / 625);
+#endif
+		break;
+	case QAM_64:
+	case QAM_256:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+		nco <<= 28;
+		nco /= 625;
+#else
+		nco *= ((1 << 28) / 625);
+#endif
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	nco1 = (nco >> 24) & 0x3f;
+	nco1 |= 0x40;
+	nco2 = (nco >> 16) & 0xff;
+	nco3 = (nco >> 8) & 0xff;
+	nco4 = nco & 0xff;
+
+	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
+	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
+	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
+	lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
+
+	lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
+	       if_freq_khz, nco1, nco2, nco3, nco4);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+
+	if (state->cfg->deny_i2c_rptr)
+		return 0;
+
+	lg_dbg("(%d)\n", enable);
+
+	return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
+				    enable ? 0 : 1);
+}
+
+static int lgdt3305_sleep(struct dvb_frontend *fe)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	u8 gen_ctrl_3, gen_ctrl_4;
+
+	lg_dbg("\n");
+
+	gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
+	gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
+
+	/* hold in software reset while sleeping */
+	gen_ctrl_3 &= ~0x01;
+	/* tristate the IF-AGC pin */
+	gen_ctrl_3 |=  0x02;
+	/* tristate the RF-AGC pin */
+	gen_ctrl_3 |=  0x04;
+
+	/* disable vsb/qam module */
+	gen_ctrl_4 &= ~0x01;
+	/* disable adc module */
+	gen_ctrl_4 &= ~0x02;
+
+	lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
+	lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
+
+	return 0;
+}
+
+static int lgdt3305_init(struct dvb_frontend *fe)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	int ret;
+
+	static struct lgdt3305_reg lgdt3305_init_data[] = {
+		{ .reg = LGDT3305_GEN_CTRL_1,
+		  .val = 0x03, },
+		{ .reg = LGDT3305_GEN_CTRL_2,
+		  .val = 0xb0, },
+		{ .reg = LGDT3305_GEN_CTRL_3,
+		  .val = 0x01, },
+		{ .reg = LGDT3305_GEN_CONTROL,
+		  .val = 0x6f, },
+		{ .reg = LGDT3305_GEN_CTRL_4,
+		  .val = 0x03, },
+		{ .reg = LGDT3305_DGTL_AGC_REF_1,
+		  .val = 0x32, },
+		{ .reg = LGDT3305_DGTL_AGC_REF_2,
+		  .val = 0xc4, },
+		{ .reg = LGDT3305_CR_CTR_FREQ_1,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_CR_CTR_FREQ_2,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_CR_CTR_FREQ_3,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_CR_CTR_FREQ_4,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_CR_CTRL_7,
+		  .val = 0x79, },
+		{ .reg = LGDT3305_AGC_POWER_REF_1,
+		  .val = 0x32, },
+		{ .reg = LGDT3305_AGC_POWER_REF_2,
+		  .val = 0xc4, },
+		{ .reg = LGDT3305_AGC_DELAY_PT_1,
+		  .val = 0x0d, },
+		{ .reg = LGDT3305_AGC_DELAY_PT_2,
+		  .val = 0x30, },
+		{ .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+		  .val = 0x80, },
+		{ .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_IFBW_1,
+		  .val = 0x80, },
+		{ .reg = LGDT3305_IFBW_2,
+		  .val = 0x00, },
+		{ .reg = LGDT3305_AGC_CTRL_1,
+		  .val = 0x30, },
+		{ .reg = LGDT3305_AGC_CTRL_4,
+		  .val = 0x61, },
+		{ .reg = LGDT3305_FEC_BLOCK_CTRL,
+		  .val = 0xff, },
+		{ .reg = LGDT3305_TP_CTRL_1,
+		  .val = 0x1b, },
+	};
+
+	lg_dbg("\n");
+
+	ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+				  ARRAY_SIZE(lgdt3305_init_data));
+	if (lg_fail(ret))
+		goto fail;
+
+	ret = lgdt3305_soft_reset(state);
+fail:
+	return ret;
+}
+
+static int lgdt3305_set_parameters(struct dvb_frontend *fe,
+				   struct dvb_frontend_parameters *param)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	int ret;
+
+	lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
+
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe, param);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+		if (lg_fail(ret))
+			goto fail;
+		state->current_frequency = param->frequency;
+	}
+
+	ret = lgdt3305_set_modulation(state, param);
+	if (lg_fail(ret))
+		goto fail;
+
+	ret = lgdt3305_passband_digital_agc(state, param);
+	if (lg_fail(ret))
+		goto fail;
+	ret = lgdt3305_set_agc_power_ref(state, param);
+	if (lg_fail(ret))
+		goto fail;
+	ret = lgdt3305_agc_setup(state, param);
+	if (lg_fail(ret))
+		goto fail;
+
+	/* low if */
+	ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
+	if (lg_fail(ret))
+		goto fail;
+	ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
+	if (lg_fail(ret))
+		goto fail;
+
+	ret = lgdt3305_set_if(state, param);
+	if (lg_fail(ret))
+		goto fail;
+	ret = lgdt3305_spectral_inversion(state, param,
+					  state->cfg->spectral_inversion
+					  ? 1 : 0);
+	if (lg_fail(ret))
+		goto fail;
+
+	ret = lgdt3305_set_filter_extension(state, param);
+	if (lg_fail(ret))
+		goto fail;
+
+	state->current_modulation = param->u.vsb.modulation;
+
+	ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+	if (lg_fail(ret))
+		goto fail;
+
+	/* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+	ret = lgdt3305_mpeg_mode_polarity(state,
+					  state->cfg->tpclk_edge,
+					  state->cfg->tpvalid_polarity);
+fail:
+	return ret;
+}
+
+static int lgdt3305_get_frontend(struct dvb_frontend *fe,
+				 struct dvb_frontend_parameters *param)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+
+	lg_dbg("\n");
+
+	param->u.vsb.modulation = state->current_modulation;
+	param->frequency = state->current_frequency;
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
+					int *locked)
+{
+	u8 val;
+	int ret;
+	char *cr_lock_state = "";
+
+	*locked = 0;
+
+	ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
+	if (lg_fail(ret))
+		goto fail;
+
+	switch (state->current_modulation) {
+	case QAM_256:
+	case QAM_64:
+		if (val & (1 << 1))
+			*locked = 1;
+
+		switch (val & 0x07) {
+		case 0:
+			cr_lock_state = "QAM UNLOCK";
+			break;
+		case 4:
+			cr_lock_state = "QAM 1stLock";
+			break;
+		case 6:
+			cr_lock_state = "QAM 2ndLock";
+			break;
+		case 7:
+			cr_lock_state = "QAM FinalLock";
+			break;
+		default:
+			cr_lock_state = "CLOCKQAM-INVALID!";
+			break;
+		}
+		break;
+	case VSB_8:
+		if (val & (1 << 7)) {
+			*locked = 1;
+			cr_lock_state = "CLOCKVSB";
+		}
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	lg_dbg("(%d) %s\n", *locked, cr_lock_state);
+fail:
+	return ret;
+}
+
+static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
+					 int *locked)
+{
+	u8 val;
+	int ret, mpeg_lock, fec_lock, viterbi_lock;
+
+	*locked = 0;
+
+	switch (state->current_modulation) {
+	case QAM_256:
+	case QAM_64:
+		ret = lgdt3305_read_reg(state,
+					LGDT3305_FEC_LOCK_STATUS, &val);
+		if (lg_fail(ret))
+			goto fail;
+
+		mpeg_lock    = (val & (1 << 0)) ? 1 : 0;
+		fec_lock     = (val & (1 << 2)) ? 1 : 0;
+		viterbi_lock = (val & (1 << 3)) ? 1 : 0;
+
+		*locked = mpeg_lock && fec_lock && viterbi_lock;
+
+		lg_dbg("(%d) %s%s%s\n", *locked,
+		       mpeg_lock    ? "mpeg lock  "  : "",
+		       fec_lock     ? "fec lock  "   : "",
+		       viterbi_lock ? "viterbi lock" : "");
+		break;
+	case VSB_8:
+	default:
+		ret = -EINVAL;
+	}
+fail:
+	return ret;
+}
+
+static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	u8 val;
+	int ret, signal, inlock, nofecerr, snrgood,
+		cr_lock, fec_lock, sync_lock;
+
+	*status = 0;
+
+	ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
+	if (lg_fail(ret))
+		goto fail;
+
+	signal    = (val & (1 << 4)) ? 1 : 0;
+	inlock    = (val & (1 << 3)) ? 0 : 1;
+	sync_lock = (val & (1 << 2)) ? 1 : 0;
+	nofecerr  = (val & (1 << 1)) ? 1 : 0;
+	snrgood   = (val & (1 << 0)) ? 1 : 0;
+
+	lg_dbg("%s%s%s%s%s\n",
+	       signal    ? "SIGNALEXIST " : "",
+	       inlock    ? "INLOCK "      : "",
+	       sync_lock ? "SYNCLOCK "    : "",
+	       nofecerr  ? "NOFECERR "    : "",
+	       snrgood   ? "SNRGOOD "     : "");
+
+	ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
+	if (lg_fail(ret))
+		goto fail;
+
+	if (signal)
+		*status |= FE_HAS_SIGNAL;
+	if (cr_lock)
+		*status |= FE_HAS_CARRIER;
+	if (nofecerr)
+		*status |= FE_HAS_VITERBI;
+	if (sync_lock)
+		*status |= FE_HAS_SYNC;
+
+	switch (state->current_modulation) {
+	case QAM_256:
+	case QAM_64:
+		ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
+		if (lg_fail(ret))
+			goto fail;
+
+		if (fec_lock)
+			*status |= FE_HAS_LOCK;
+		break;
+	case VSB_8:
+		if (inlock)
+			*status |= FE_HAS_LOCK;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* borrowed from lgdt330x.c */
+static u32 calculate_snr(u32 mse, u32 c)
+{
+	if (mse == 0) /* no signal */
+		return 0;
+
+	mse = intlog10(mse);
+	if (mse > c) {
+		/* Negative SNR, which is possible, but realisticly the
+		demod will lose lock before the signal gets this bad.  The
+		API only allows for unsigned values, so just return 0 */
+		return 0;
+	}
+	return 10*(c - mse);
+}
+
+static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	u32 noise;	/* noise value */
+	u32 c;		/* per-modulation SNR calculation constant */
+
+	switch (state->current_modulation) {
+	case VSB_8:
+#ifdef USE_PTMSE
+		/* Use Phase Tracker Mean-Square Error Register */
+		/* SNR for ranges from -13.11 to +44.08 */
+		noise =	((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
+			(read_reg(state, LGDT3305_PT_MSE_2) << 8) |
+			(read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
+		c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+		/* Use Equalizer Mean-Square Error Register */
+		/* SNR for ranges from -16.12 to +44.08 */
+		noise =	((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
+			(read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
+			(read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
+		c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+		break;
+	case QAM_64:
+	case QAM_256:
+		noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
+			(read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
+
+		c = (state->current_modulation == QAM_64) ?
+			97939837 : 98026066;
+		/* log10(688128)*2^24 and log10(696320)*2^24 */
+		break;
+	default:
+		return -EINVAL;
+	}
+	state->snr = calculate_snr(noise, c);
+	/* report SNR in dB * 10 */
+	*snr = (state->snr / ((1 << 24) / 10));
+	lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
+	       state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+	return 0;
+}
+
+static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
+					 u16 *strength)
+{
+	/* borrowed from lgdt330x.c
+	 *
+	 * Calculate strength from SNR up to 35dB
+	 * Even though the SNR can go higher than 35dB,
+	 * there is some comfort factor in having a range of
+	 * strong signals that can show at 100%
+	 */
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	u16 snr;
+	int ret;
+
+	*strength = 0;
+
+	ret = fe->ops.read_snr(fe, &snr);
+	if (lg_fail(ret))
+		goto fail;
+	/* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+	/* scale the range 0 - 35*2^24 into 0 - 65535 */
+	if (state->snr >= 8960 * 0x10000)
+		*strength = 0xffff;
+	else
+		*strength = state->snr / 8960;
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	*ber = 0;
+	return 0;
+}
+
+static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+
+	*ucblocks =
+		(read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
+		(read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
+
+	return 0;
+}
+
+static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
+				      struct dvb_frontend_tune_settings
+					*fe_tune_settings)
+{
+	fe_tune_settings->min_delay_ms = 500;
+	lg_dbg("\n");
+	return 0;
+}
+
+static void lgdt3305_release(struct dvb_frontend *fe)
+{
+	struct lgdt3305_state *state = fe->demodulator_priv;
+	lg_dbg("\n");
+	kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3305_ops;
+
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+				     struct i2c_adapter *i2c_adap)
+{
+	struct lgdt3305_state *state = NULL;
+	int ret;
+	u8 val;
+
+	lg_dbg("(%d-%04x)\n",
+	       i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+	       config ? config->i2c_addr : 0);
+
+	state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
+	if (state == NULL)
+		goto fail;
+
+	state->cfg = config;
+	state->i2c_adap = i2c_adap;
+
+	memcpy(&state->frontend.ops, &lgdt3305_ops,
+	       sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	/* verify that we're talking to a lg dt3305 */
+	ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
+	if ((lg_fail(ret)) | (val == 0))
+		goto fail;
+	ret = lgdt3305_write_reg(state, 0x0808, 0x80);
+	if (lg_fail(ret))
+		goto fail;
+	ret = lgdt3305_read_reg(state, 0x0808, &val);
+	if ((lg_fail(ret)) | (val != 0x80))
+		goto fail;
+	ret = lgdt3305_write_reg(state, 0x0808, 0x00);
+	if (lg_fail(ret))
+		goto fail;
+
+	state->current_frequency = -1;
+	state->current_modulation = -1;
+
+	return &state->frontend;
+fail:
+	lg_warn("unable to detect LGDT3305 hardware\n");
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(lgdt3305_attach);
+
+static struct dvb_frontend_ops lgdt3305_ops = {
+	.info = {
+		.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
+		.type               = FE_ATSC,
+		.frequency_min      = 54000000,
+		.frequency_max      = 858000000,
+		.frequency_stepsize = 62500,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+	.i2c_gate_ctrl        = lgdt3305_i2c_gate_ctrl,
+	.init                 = lgdt3305_init,
+	.sleep                = lgdt3305_sleep,
+	.set_frontend         = lgdt3305_set_parameters,
+	.get_frontend         = lgdt3305_get_frontend,
+	.get_tune_settings    = lgdt3305_get_tune_settings,
+	.read_status          = lgdt3305_read_status,
+	.read_ber             = lgdt3305_read_ber,
+	.read_signal_strength = lgdt3305_read_signal_strength,
+	.read_snr             = lgdt3305_read_snr,
+	.read_ucblocks        = lgdt3305_read_ucblocks,
+	.release              = lgdt3305_release,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3305.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgdt3305.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,85 @@
+/*
+ *    Support for LGDT3305 - VSB/QAM
+ *
+ *    Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT3305_H_
+#define _LGDT3305_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3305_mpeg_mode {
+	LGDT3305_MPEG_PARALLEL = 0,
+	LGDT3305_MPEG_SERIAL = 1,
+};
+
+enum lgdt3305_tp_clock_edge {
+	LGDT3305_TPCLK_RISING_EDGE = 0,
+	LGDT3305_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3305_tp_valid_polarity {
+	LGDT3305_TP_VALID_LOW = 0,
+	LGDT3305_TP_VALID_HIGH = 1,
+};
+
+struct lgdt3305_config {
+	u8 i2c_addr;
+
+	/* user defined IF frequency in KHz */
+	u16 qam_if_khz;
+	u16 vsb_if_khz;
+
+	/* AGC Power reference - defaults are used if left unset */
+	u16 usref_8vsb;   /* default: 0x32c4 */
+	u16 usref_qam64;  /* default: 0x5400 */
+	u16 usref_qam256; /* default: 0x2a80 */
+
+	/* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+	int deny_i2c_rptr:1;
+
+	/* spectral inversion - 0:disabled 1:enabled */
+	int spectral_inversion:1;
+
+	/* use RF AGC loop - 0:disabled 1:enabled */
+	int rf_agc_loop:1;
+
+	enum lgdt3305_mpeg_mode mpeg_mode;
+	enum lgdt3305_tp_clock_edge tpclk_edge;
+	enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+};
+
+#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
+				     defined(MODULE))
+extern
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+				     struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+				     struct i2c_adapter *i2c_adap)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3305 */
+
+#endif /* _LGDT3305_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,816 @@
+/*
+ *    Support for Legend Silicon DMB-TH demodulator
+ *    LGS8913, LGS8GL5
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU 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 "lgs8gxx.h"
+#include "lgs8gxx_priv.h"
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG "lgs8gxx: " args); \
+	} while (0)
+
+static int debug;
+static int fake_signal_str;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+module_param(fake_signal_str, int, 0644);
+MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
+"Signal strength calculation is slow.(default:off).");
+
+/* LGS8GXX internal helper functions */
+
+static int lgs8gxx_write_reg(struct lgs8gxx_state *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->demod_address;
+	if (reg >= 0xC0)
+		msg.addr += 0x02;
+
+	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) ? -1 : 0;
+}
+
+static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
+{
+	int ret;
+	u8 dev_addr;
+
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{ .flags = 0, .buf = b0, .len = 1 },
+		{ .flags = I2C_M_RD, .buf = b1, .len = 1 },
+	};
+
+	dev_addr = priv->config->demod_address;
+	if (reg >= 0xC0)
+		dev_addr += 0x02;
+	msg[1].addr =  msg[0].addr = dev_addr;
+
+	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 -1;
+	}
+
+	*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 lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
+{
+	lgs8gxx_write_reg(priv, 0x02, 0x00);
+	msleep(1);
+	lgs8gxx_write_reg(priv, 0x02, 0x01);
+	msleep(100);
+
+	return 0;
+}
+
+static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
+{
+	const struct lgs8gxx_config *config = priv->config;
+	u8 if_conf;
+
+	if_conf = 0x10; /* AGC output on; */
+
+	if_conf |=
+		((config->ext_adc) ? 0x80 : 0x00) |
+		((config->if_neg_center) ? 0x04 : 0x00) |
+		((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
+		((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) |
+		((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00);
+
+	if (config->ext_adc &&
+		(config->prod == LGS8GXX_PROD_LGS8G52)) {
+		lgs8gxx_write_reg(priv, 0xBA, 0x40);
+	}
+
+	lgs8gxx_write_reg(priv, 0x07, if_conf);
+
+	return 0;
+}
+
+static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
+{
+	u64 val;
+	u32 v32;
+	u32 if_clk;
+
+	if_clk = priv->config->if_clk_freq;
+
+	val = freq;
+	if (freq != 0) {
+		val *= (u64)1 << 32;
+		if (if_clk != 0)
+			do_div(val, if_clk);
+		v32 = val & 0xFFFFFFFF;
+		dprintk("Set IF Freq to %dkHz\n", freq);
+	} else {
+		v32 = 0;
+		dprintk("Set IF Freq to baseband\n");
+	}
+	dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
+
+	lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
+	lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
+	lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
+	lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
+
+	return 0;
+}
+
+static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
+{
+	u8 t;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+		lgs8gxx_write_reg(priv, 0xC6, 0x01);
+
+	lgs8gxx_read_reg(priv, 0x7E, &t);
+	lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
+
+	/* clear FEC self reset */
+	lgs8gxx_read_reg(priv, 0xC5, &t);
+	lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+		/* FEC auto detect */
+		lgs8gxx_write_reg(priv, 0xC1, 0x03);
+
+		lgs8gxx_read_reg(priv, 0x7C, &t);
+		t = (t & 0x8C) | 0x03;
+		lgs8gxx_write_reg(priv, 0x7C, t);
+	}
+
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+		/* BER test mode */
+		lgs8gxx_read_reg(priv, 0xC3, &t);
+		t = (t & 0xEF) |  0x10;
+		lgs8gxx_write_reg(priv, 0xC3, t);
+	}
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
+		lgs8gxx_write_reg(priv, 0xD9, 0x40);
+
+	return 0;
+}
+
+static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
+{
+	int ret = 0;
+	u8 t;
+
+	/* turn off auto-detect; manual settings */
+	lgs8gxx_write_reg(priv, 0x7E, 0);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+		lgs8gxx_write_reg(priv, 0xC1, 0);
+
+	ret = lgs8gxx_read_reg(priv, 0xC5, &t);
+	t = (t & 0xE0) | 0x06;
+	lgs8gxx_write_reg(priv, 0xC5, t);
+
+	lgs8gxx_soft_reset(priv);
+
+	return 0;
+}
+
+static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
+{
+	int ret = 0;
+	u8 t;
+
+	ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+	if (ret != 0)
+		return ret;
+
+	*locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
+	return 0;
+}
+
+static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
+					  u8 *finished)
+{
+	int ret = 0;
+	u8 t;
+
+	ret = lgs8gxx_read_reg(priv, 0xA4, &t);
+	if (ret != 0)
+		return ret;
+
+	*finished = ((t & 0x3) == 0x1) ? 1 : 0;
+
+	return 0;
+}
+
+static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked)
+{
+	int err;
+	u8 ad_fini = 0;
+
+	if (gi == GI_945)
+		dprintk("try GI 945\n");
+	else if (gi == GI_595)
+		dprintk("try GI 595\n");
+	else if (gi == GI_420)
+		dprintk("try GI 420\n");
+	lgs8gxx_write_reg(priv, 0x04, gi);
+	lgs8gxx_soft_reset(priv);
+	msleep(50);
+	err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
+	if (err != 0)
+		return err;
+	if (ad_fini) {
+		err = lgs8gxx_is_locked(priv, locked);
+		if (err != 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
+			       u8 *detected_param, u8 *gi)
+{
+	int i, j;
+	int err = 0;
+	u8 locked = 0, tmp_gi;
+
+	dprintk("%s\n", __func__);
+
+	lgs8gxx_set_mode_auto(priv);
+	/* Guard Interval */
+	lgs8gxx_write_reg(priv, 0x03, 00);
+
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 2; j++) {
+			tmp_gi = GI_945;
+			err = lgs8gxx_autolock_gi(priv, GI_945, &locked);
+			if (err)
+				goto out;
+			if (locked)
+				goto locked;
+		}
+		for (j = 0; j < 2; j++) {
+			tmp_gi = GI_420;
+			err = lgs8gxx_autolock_gi(priv, GI_420, &locked);
+			if (err)
+				goto out;
+			if (locked)
+				goto locked;
+		}
+		tmp_gi = GI_595;
+		err = lgs8gxx_autolock_gi(priv, GI_595, &locked);
+		if (err)
+			goto out;
+		if (locked)
+			goto locked;
+	}
+
+locked:
+	if ((err == 0) && (locked == 1)) {
+		u8 t;
+
+		lgs8gxx_read_reg(priv, 0xA2, &t);
+		*detected_param = t;
+
+		if (tmp_gi == GI_945)
+			dprintk("GI 945 locked\n");
+		else if (tmp_gi == GI_595)
+			dprintk("GI 595 locked\n");
+		else if (tmp_gi == GI_420)
+			dprintk("GI 420 locked\n");
+		*gi = tmp_gi;
+	}
+	if (!locked)
+		err = -1;
+
+out:
+	return err;
+}
+
+static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
+{
+	s8 err;
+	u8 gi = 0x2;
+	u8 detected_param = 0;
+
+	err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
+
+	if (err != 0) {
+		dprintk("lgs8gxx_auto_detect failed\n");
+	}
+
+	/* Apply detected parameters */
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+		u8 inter_leave_len = detected_param & TIM_MASK ;
+		inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40;
+		detected_param &= CF_MASK | SC_MASK  | LGS_FEC_MASK;
+		detected_param |= inter_leave_len;
+	}
+	lgs8gxx_write_reg(priv, 0x7D, detected_param);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+		lgs8gxx_write_reg(priv, 0xC0, detected_param);
+	/* lgs8gxx_soft_reset(priv); */
+
+	/* Enter manual mode */
+	lgs8gxx_set_mode_manual(priv);
+
+	switch (gi) {
+	case GI_945:
+		priv->curr_gi = 945; break;
+	case GI_595:
+		priv->curr_gi = 595; break;
+	case GI_420:
+		priv->curr_gi = 420; break;
+	default:
+		priv->curr_gi = 945; break;
+	}
+}
+
+static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
+	u8 serial, u8 clk_pol, u8 clk_gated)
+{
+	int ret = 0;
+	u8 t;
+
+	ret = lgs8gxx_read_reg(priv, 0xC2, &t);
+	if (ret != 0)
+		return ret;
+
+	t &= 0xF8;
+	t |= serial ? TS_SERIAL : TS_PARALLEL;
+	t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
+	t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
+
+	ret = lgs8gxx_write_reg(priv, 0xC2, t);
+	if (ret != 0)
+		return ret;
+
+	return 0;
+}
+
+
+/* LGS8913 demod frontend functions */
+
+static int lgs8913_init(struct lgs8gxx_state *priv)
+{
+	u8 t;
+
+	/* LGS8913 specific */
+	lgs8gxx_write_reg(priv, 0xc1, 0x3);
+
+	lgs8gxx_read_reg(priv, 0x7c, &t);
+	lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
+
+	/* LGS8913 specific */
+	lgs8gxx_read_reg(priv, 0xc3, &t);
+	lgs8gxx_write_reg(priv, 0xc3, t&0x10);
+
+
+	return 0;
+}
+
+static int lgs8gxx_init(struct dvb_frontend *fe)
+{
+	struct lgs8gxx_state *priv =
+		(struct lgs8gxx_state *)fe->demodulator_priv;
+	const struct lgs8gxx_config *config = priv->config;
+	u8 data = 0;
+	s8 err;
+	dprintk("%s\n", __func__);
+
+	lgs8gxx_read_reg(priv, 0, &data);
+	dprintk("reg 0 = 0x%02X\n", data);
+
+	/* Setup MPEG output format */
+	err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
+				    config->ts_clk_pol,
+				    config->ts_clk_gated);
+	if (err != 0)
+		return -EIO;
+
+	if (config->prod == LGS8GXX_PROD_LGS8913)
+		lgs8913_init(priv);
+	lgs8gxx_set_if_freq(priv, priv->config->if_freq);
+	if (config->prod != LGS8GXX_PROD_LGS8913)
+		lgs8gxx_set_ad_mode(priv);
+
+	return 0;
+}
+
+static void lgs8gxx_release(struct dvb_frontend *fe)
+{
+	struct lgs8gxx_state *state = fe->demodulator_priv;
+	dprintk("%s\n", __func__);
+
+	kfree(state);
+}
+
+
+static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+	if (len != 2)
+		return -EINVAL;
+
+	return lgs8gxx_write_reg(priv, buf[0], buf[1]);
+}
+
+static int lgs8gxx_set_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+	dprintk("%s\n", __func__);
+
+	/* set frequency */
+	if (fe->ops.tuner_ops.set_params) {
+		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 */
+	lgs8gxx_auto_lock(priv);
+
+	msleep(10);
+
+	return 0;
+}
+
+static int lgs8gxx_get_fe(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *fe_params)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+	u8 t;
+
+	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;
+
+
+	lgs8gxx_read_reg(priv, 0x7D, &t);
+	fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
+	fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
+
+	/* constellation */
+	switch (t & SC_MASK) {
+	case SC_QAM64:
+		fe_params->u.ofdm.constellation = QAM_64;
+		break;
+	case SC_QAM32:
+		fe_params->u.ofdm.constellation = QAM_32;
+		break;
+	case SC_QAM16:
+		fe_params->u.ofdm.constellation = QAM_16;
+		break;
+	case SC_QAM4:
+	case SC_QAM4NR:
+		fe_params->u.ofdm.constellation = QPSK;
+		break;
+	default:
+		fe_params->u.ofdm.constellation = QAM_64;
+	}
+
+	/* 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 lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
+			      struct dvb_frontend_tune_settings *fesettings)
+{
+	/* FIXME: copy from tda1004x.c */
+	fesettings->min_delay_ms = 800;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
+}
+
+static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+	s8 ret;
+	u8 t;
+
+	dprintk("%s\n", __func__);
+
+	ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+	if (ret != 0)
+		return -EIO;
+
+	dprintk("Reg 0x4B: 0x%02X\n", t);
+
+	*fe_status = 0;
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+		if ((t & 0x40) == 0x40)
+			*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+		if ((t & 0x80) == 0x80)
+			*fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
+				FE_HAS_LOCK;
+	} else {
+		if ((t & 0x80) == 0x80)
+			*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+	}
+
+	/* success */
+	dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
+	return 0;
+}
+
+static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
+{
+	u16 v;
+	u8 agc_lvl[2], cat;
+
+	dprintk("%s()\n", __func__);
+	lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
+	lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
+
+	v = agc_lvl[0];
+	v <<= 8;
+	v |= agc_lvl[1];
+
+	dprintk("agc_lvl: 0x%04X\n", v);
+
+	if (v < 0x100)
+		cat = 0;
+	else if (v < 0x190)
+		cat = 5;
+	else if (v < 0x2A8)
+		cat = 4;
+	else if (v < 0x381)
+		cat = 3;
+	else if (v < 0x400)
+		cat = 2;
+	else if (v == 0x400)
+		cat = 1;
+	else
+		cat = 0;
+
+	*signal = cat;
+
+	return 0;
+}
+
+static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
+{
+	u8 t; s8 ret;
+	s16 max_strength = 0;
+	u8 str;
+	u16 i, gi = priv->curr_gi;
+
+	dprintk("%s\n", __func__);
+
+	ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+	if (ret != 0)
+		return -EIO;
+
+	if (fake_signal_str) {
+		if ((t & 0xC0) == 0xC0) {
+			dprintk("Fake signal strength as 50\n");
+			*signal = 0x32;
+		} else
+			*signal = 0;
+		return 0;
+	}
+
+	dprintk("gi = %d\n", gi);
+	for (i = 0; i < gi; i++) {
+
+		if ((i & 0xFF) == 0)
+			lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
+		lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
+
+		lgs8gxx_read_reg(priv, 0x94, &str);
+		if (max_strength < str)
+			max_strength = str;
+	}
+
+	*signal = max_strength;
+	dprintk("%s: signal=0x%02X\n", __func__, *signal);
+
+	lgs8gxx_read_reg(priv, 0x95, &t);
+	dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
+
+	return 0;
+}
+
+static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+		return lgs8913_read_signal_strength(priv, signal);
+	else
+		return lgs8gxx_read_signal_agc(priv, signal);
+}
+
+static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+	u8 t;
+	*snr = 0;
+
+	lgs8gxx_read_reg(priv, 0x95, &t);
+	dprintk("AVG Noise=0x%02X\n", t);
+	*snr = 256 - t;
+	*snr <<= 8;
+	dprintk("snr=0x%x\n", *snr);
+
+	return 0;
+}
+
+static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
+	return 0;
+}
+
+static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+	u8 r0, r1, r2, r3;
+	u32 total_cnt, err_cnt;
+
+	dprintk("%s\n", __func__);
+
+	lgs8gxx_write_reg(priv, 0xc6, 0x01);
+	lgs8gxx_write_reg(priv, 0xc6, 0x41);
+	lgs8gxx_write_reg(priv, 0xc6, 0x01);
+
+	msleep(200);
+
+	lgs8gxx_write_reg(priv, 0xc6, 0x81);
+	lgs8gxx_read_reg(priv, 0xd0, &r0);
+	lgs8gxx_read_reg(priv, 0xd1, &r1);
+	lgs8gxx_read_reg(priv, 0xd2, &r2);
+	lgs8gxx_read_reg(priv, 0xd3, &r3);
+	total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
+	lgs8gxx_read_reg(priv, 0xd4, &r0);
+	lgs8gxx_read_reg(priv, 0xd5, &r1);
+	lgs8gxx_read_reg(priv, 0xd6, &r2);
+	lgs8gxx_read_reg(priv, 0xd7, &r3);
+	err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
+	dprintk("error=%d total=%d\n", err_cnt, total_cnt);
+
+	if (total_cnt == 0)
+		*ber = 0;
+	else
+		*ber = err_cnt * 100 / total_cnt;
+
+	dprintk("%s: ber=0x%x\n", __func__, *ber);
+	return 0;
+}
+
+static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct lgs8gxx_state *priv = fe->demodulator_priv;
+
+	if (priv->config->tuner_address == 0)
+		return 0;
+	if (enable) {
+		u8 v = 0x80 | priv->config->tuner_address;
+		return lgs8gxx_write_reg(priv, 0x01, v);
+	}
+	return lgs8gxx_write_reg(priv, 0x01, 0);
+}
+
+static struct dvb_frontend_ops lgs8gxx_ops = {
+	.info = {
+		.name = "Legend Silicon LGS8913/LGS8GXX 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 = lgs8gxx_release,
+
+	.init = lgs8gxx_init,
+	.write = lgs8gxx_write,
+	.i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
+
+	.set_frontend = lgs8gxx_set_fe,
+	.get_frontend = lgs8gxx_get_fe,
+	.get_tune_settings = lgs8gxx_get_tune_settings,
+
+	.read_status = lgs8gxx_read_status,
+	.read_ber = lgs8gxx_read_ber,
+	.read_signal_strength = lgs8gxx_read_signal_strength,
+	.read_snr = lgs8gxx_read_snr,
+	.read_ucblocks = lgs8gxx_read_ucblocks,
+};
+
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+	struct i2c_adapter *i2c)
+{
+	struct lgs8gxx_state *priv = NULL;
+	u8 data = 0;
+
+	dprintk("%s()\n", __func__);
+
+	if (config == NULL || i2c == NULL)
+		return NULL;
+
+	priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
+	if (priv == NULL)
+		goto error_out;
+
+	priv->config = config;
+	priv->i2c = i2c;
+
+	/* check if the demod is there */
+	if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
+		dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
+			__func__, priv->config->demod_address);
+		goto error_out;
+	}
+
+	lgs8gxx_read_reg(priv, 1, &data);
+
+	memcpy(&priv->frontend.ops, &lgs8gxx_ops,
+	       sizeof(struct dvb_frontend_ops));
+	priv->frontend.demodulator_priv = priv;
+
+	return &priv->frontend;
+
+error_out:
+	dprintk("%s() error_out\n", __func__);
+	kfree(priv);
+	return NULL;
+
+}
+EXPORT_SYMBOL(lgs8gxx_attach);
+
+MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ *    Support for Legend Silicon DMB-TH demodulator
+ *    LGS8913, LGS8GL5
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU 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 __LGS8GXX_H__
+#define __LGS8GXX_H__
+
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#define LGS8GXX_PROD_LGS8913 0
+#define LGS8GXX_PROD_LGS8GL5 1
+#define LGS8GXX_PROD_LGS8G42 3
+#define LGS8GXX_PROD_LGS8G52 4
+#define LGS8GXX_PROD_LGS8G54 5
+
+struct lgs8gxx_config {
+
+	/* product type */
+	u8 prod;
+
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* parallel or serial transport stream */
+	u8 serial_ts;
+
+	/* transport stream polarity*/
+	u8 ts_clk_pol;
+
+	/* transport stream clock gated by ts_valid */
+	u8 ts_clk_gated;
+
+	/* A/D Clock frequency */
+	u32 if_clk_freq; /* in kHz */
+
+	/* IF frequency */
+	u32 if_freq; /* in kHz */
+
+	/*Use External ADC*/
+	u8 ext_adc;
+
+	/*External ADC output two's complement*/
+	u8 adc_signed;
+
+	/*Sample IF data at falling edge of IF_CLK*/
+	u8 if_neg_edge;
+
+	/*IF use Negative center frequency*/
+	u8 if_neg_center;
+
+	/* slave address and configuration of the tuner */
+	u8 tuner_address;
+};
+
+#if defined(CONFIG_DVB_LGS8GXX) || \
+	(defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+					   struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
+				    struct i2c_adapter *i2c) {
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_LGS8GXX */
+
+#endif /* __LGS8GXX_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx_priv.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lgs8gxx_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgs8gxx_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ *    Support for Legend Silicon DMB-TH demodulator
+ *    LGS8913, LGS8GL5
+ *    experimental support LGS8G42, LGS8G52
+ *
+ *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
+ *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU 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 LGS8913_PRIV_H
+#define LGS8913_PRIV_H
+
+struct lgs8gxx_state {
+	struct i2c_adapter *i2c;
+	/* configuration settings */
+	const struct lgs8gxx_config *config;
+	struct dvb_frontend frontend;
+	u16 curr_gi; /* current guard interval */
+};
+
+#define SC_MASK		0x1C	/* Sub-Carrier Modulation Mask */
+#define SC_QAM64	0x10	/* 64QAM modulation */
+#define SC_QAM32	0x0C	/* 32QAM modulation */
+#define SC_QAM16	0x08	/* 16QAM modulation */
+#define SC_QAM4NR	0x04	/* 4QAM modulation */
+#define SC_QAM4		0x00	/* 4QAM modulation */
+
+#define LGS_FEC_MASK	0x03	/* FEC Rate Mask */
+#define LGS_FEC_0_4	0x00	/* FEC Rate 0.4 */
+#define LGS_FEC_0_6	0x01	/* FEC Rate 0.6 */
+#define LGS_FEC_0_8	0x02	/* FEC Rate 0.8 */
+
+#define TIM_MASK	  0x20	/* Time Interleave Length Mask */
+#define TIM_LONG	  0x00	/* Time Interleave Length = 720 */
+#define TIM_MIDDLE     0x20   /* Time Interleave Length = 240 */
+
+#define CF_MASK	0x80	/* Control Frame Mask */
+#define CF_EN	0x80	/* Control Frame On */
+
+#define GI_MASK	0x03	/* Guard Interval Mask */
+#define GI_420	0x00	/* 1/9 Guard Interval */
+#define GI_595	0x01	/* */
+#define GI_945	0x02	/* 1/4 Guard Interval */
+
+
+#define TS_PARALLEL	0x00	/* Parallel TS Output a.k.a. SPI */
+#define TS_SERIAL	0x01	/* Serial TS Output a.k.a. SSI */
+#define TS_CLK_NORMAL		0x00	/* MPEG Clock Normal */
+#define TS_CLK_INVERTED		0x02	/* MPEG Clock Inverted */
+#define TS_CLK_GATED		0x00	/* MPEG clock gated */
+#define TS_CLK_FREERUN		0x04	/* MPEG clock free running*/
+
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbh24.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbh24.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbh24.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbh24.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ * lnbh24.h - driver for lnb supply and control ic lnbh24
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 _LNBH24_H
+#define _LNBH24_H
+
+/* system register bits */
+#define LNBH24_OLF	0x01
+#define LNBH24_OTF	0x02
+#define LNBH24_EN	0x04
+#define LNBH24_VSEL	0x08
+#define LNBH24_LLC	0x10
+#define LNBH24_TEN	0x20
+#define LNBH24_TTX	0x40
+#define LNBH24_PCL	0x80
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+							&& defined(MODULE))
+/* override_set and override_clear control which
+   system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear, u8 i2c_addr);
+#else
+static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear, u8 i2c_addr)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbp21.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbp21.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbp21.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbp21.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,8 @@
 /*
- * lnbp21.h - driver for lnb supply and control ic lnbp21
+ * lnbp21.c - driver for lnb supply and control ic lnbp21
  *
  * Copyright (C) 2006 Oliver Endriss
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -33,18 +34,21 @@
 
 #include "dvb_frontend.h"
 #include "lnbp21.h"
+#include "lnbh24.h"
 
 struct lnbp21 {
 	u8			config;
 	u8			override_or;
 	u8			override_and;
 	struct i2c_adapter	*i2c;
+	u8			i2c_addr;
 };
 
-static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int lnbp21_set_voltage(struct dvb_frontend *fe,
+					fe_sec_voltage_t voltage)
 {
 	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
-	struct i2c_msg msg = {	.addr = 0x08, .flags = 0,
+	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0,
 				.buf = &lnbp21->config,
 				.len = sizeof(lnbp21->config) };
 
@@ -72,7 +76,7 @@ static int lnbp21_set_voltage(struct dvb
 static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
 {
 	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
-	struct i2c_msg msg = {	.addr = 0x08, .flags = 0,
+	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0,
 				.buf = &lnbp21->config,
 				.len = sizeof(lnbp21->config) };
 
@@ -97,15 +101,18 @@ static void lnbp21_release(struct dvb_fr
 	fe->sec_priv = NULL;
 }
 
-struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear, u8 i2c_addr, u8 config)
 {
 	struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
 	if (!lnbp21)
 		return NULL;
 
 	/* default configuration */
-	lnbp21->config = LNBP21_ISEL;
+	lnbp21->config = config;
 	lnbp21->i2c = i2c;
+	lnbp21->i2c_addr = i2c_addr;
 	fe->sec_priv = lnbp21;
 
 	/* bits which should be forced to '1' */
@@ -126,11 +133,29 @@ struct dvb_frontend *lnbp21_attach(struc
 	/* override frontend ops */
 	fe->ops.set_voltage = lnbp21_set_voltage;
 	fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+	printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr);
 
 	return fe;
 }
+
+struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear, u8 i2c_addr)
+{
+	return lnbx2x_attach(fe, i2c, override_set, override_clear,
+							i2c_addr, LNBH24_TTX);
+}
+EXPORT_SYMBOL(lnbh24_attach);
+
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear)
+{
+	return lnbx2x_attach(fe, i2c, override_set, override_clear,
+							0x08, LNBP21_ISEL);
+}
 EXPORT_SYMBOL(lnbp21_attach);
 
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
-MODULE_AUTHOR("Oliver Endriss");
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
+MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbp21.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbp21.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/lnbp21.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lnbp21.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,26 +28,48 @@
 #define _LNBP21_H
 
 /* system register bits */
+/* [RO] 0=OK; 1=over current limit flag */
 #define LNBP21_OLF	0x01
+/* [RO] 0=OK; 1=over temperature flag (150 C) */
 #define LNBP21_OTF	0x02
+/* [RW] 0=disable LNB power, enable loopthrough
+	1=enable LNB power, disable loopthrough */
 #define LNBP21_EN	0x04
+/* [RW] 0=low voltage (13/14V, vert pol)
+	1=high voltage (18/19V,horiz pol) */
 #define LNBP21_VSEL	0x08
+/* [RW] increase LNB voltage by 1V:
+	0=13/18V; 1=14/19V */
 #define LNBP21_LLC	0x10
+/* [RW] 0=tone controlled by DSQIN pin
+	1=tone enable, disable DSQIN */
 #define LNBP21_TEN	0x20
+/* [RW] current limit select:
+	0:Iout=500-650mA Isc=300mA
+	1:Iout=400-550mA Isc=200mA */
 #define LNBP21_ISEL	0x40
+/* [RW] short-circuit protect:
+	0=pulsed (dynamic) curr limiting
+	1=static curr limiting */
 #define LNBP21_PCL	0x80
 
 #include <linux/dvb/frontend.h>
 
-#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE))
-/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+							&& defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear);
 #else
-static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+				struct i2c_adapter *i2c, u8 override_set,
+				u8 override_clear)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_DVB_LNBP21
+#endif
 
-#endif // _LNBP21_H
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/Makefile linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/t
 
 s921-objs := s921_module.o s921_core.o
 stb0899-objs = stb0899_drv.o stb0899_algo.o
+stv0900-objs = stv0900_core.o stv0900_sw.o
+au8522-objs = au8522_dig.o au8522_decoder.o
 
 obj-$(CONFIG_DVB_PLL) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -28,6 +30,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
 obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
+obj-$(CONFIG_DVB_ZL10036) += zl10036.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
 obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
@@ -41,6 +44,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
 obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
 obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
 obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
+obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
 obj-$(CONFIG_DVB_CX24123) += cx24123.o
 obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
 obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@@ -57,6 +61,7 @@ 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_LGS8GXX) += lgs8gxx.o
 obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
 obj-$(CONFIG_DVB_AF9013) += af9013.o
 obj-$(CONFIG_DVB_CX24116) += cx24116.o
@@ -64,4 +69,6 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o
 obj-$(CONFIG_DVB_STV0288) += stv0288.o
 obj-$(CONFIG_DVB_STB6000) += stb6000.o
 obj-$(CONFIG_DVB_S921) += s921.o
+obj-$(CONFIG_DVB_STV6110) += stv6110.o
+obj-$(CONFIG_DVB_STV0900) += stv0900.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/s921_module.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/s921_module.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/s921_module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/s921_module.c	2009-06-09 23:05:27.000000000 -0400
@@ -169,7 +169,6 @@ struct dvb_frontend* s921_attach(const s
 
 	struct s921_state *state;
 	state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
-	memset(state, 0x0, sizeof(struct s921_state));
 
 	state->addr = config->i2c_address;
 	state->i2c = i2c;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stb6100_cfg.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stb6100_cfg.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stb6100_cfg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stb6100_cfg.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct
 			return err;
 		}
 		*frequency = t_state.frequency;
-		printk("%s: Frequency=%d\n", __func__, t_state.frequency);
 	}
 	return 0;
 }
@@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct
 			return err;
 		}
 	}
-	printk("%s: Frequency=%d\n", __func__, t_state.frequency);
 	return 0;
 }
 
@@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct
 		}
 		*bandwidth = t_state.bandwidth;
 	}
-	printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
 	return 0;
 }
 
@@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct
 			return err;
 		}
 	}
-	printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_core.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_core.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1949 @@
+/*
+ * stv0900_core.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+#include "stv0900_init.h"
+
+static int stvdebug = 1;
+module_param_named(debug, stvdebug, int, 0644);
+
+/* internal params node */
+struct stv0900_inode {
+	/* pointer for internal params, one for each pair of demods */
+	struct stv0900_internal		*internal;
+	struct stv0900_inode		*next_inode;
+};
+
+/* first internal params */
+static struct stv0900_inode *stv0900_first_inode;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
+							u8 i2c_addr)
+{
+	struct stv0900_inode *temp_chip = stv0900_first_inode;
+
+	if (temp_chip != NULL) {
+		/*
+		 Search of the last stv0900 chip or
+		 find it by i2c adapter and i2c address */
+		while ((temp_chip != NULL) &&
+			((temp_chip->internal->i2c_adap != i2c_adap) ||
+			(temp_chip->internal->i2c_addr != i2c_addr)))
+
+			temp_chip = temp_chip->next_inode;
+
+	}
+
+	return temp_chip;
+}
+
+/* deallocating chip */
+static void remove_inode(struct stv0900_internal *internal)
+{
+	struct stv0900_inode *prev_node = stv0900_first_inode;
+	struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
+						internal->i2c_addr);
+
+	if (del_node != NULL) {
+		if (del_node == stv0900_first_inode) {
+			stv0900_first_inode = del_node->next_inode;
+		} else {
+			while (prev_node->next_inode != del_node)
+				prev_node = prev_node->next_inode;
+
+			if (del_node->next_inode == NULL)
+				prev_node->next_inode = NULL;
+			else
+				prev_node->next_inode =
+					prev_node->next_inode->next_inode;
+		}
+
+		kfree(del_node);
+	}
+}
+
+/* allocating new chip */
+static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
+{
+	struct stv0900_inode *new_node = stv0900_first_inode;
+
+	if (new_node == NULL) {
+		new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+		stv0900_first_inode = new_node;
+	} else {
+		while (new_node->next_inode != NULL)
+			new_node = new_node->next_inode;
+
+		new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+		if (new_node->next_inode != NULL)
+			new_node = new_node->next_inode;
+		else
+			new_node = NULL;
+	}
+
+	if (new_node != NULL) {
+		new_node->internal = internal;
+		new_node->next_inode = NULL;
+	}
+
+	return new_node;
+}
+
+s32 ge2comp(s32 a, s32 width)
+{
+	if (width == 32)
+		return a;
+	else
+		return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
+}
+
+void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+								u8 reg_data)
+{
+	u8 data[3];
+	int ret;
+	struct i2c_msg i2cmsg = {
+		.addr  = i_params->i2c_addr,
+		.flags = 0,
+		.len   = 3,
+		.buf   = data,
+	};
+
+	data[0] = MSB(reg_addr);
+	data[1] = LSB(reg_addr);
+	data[2] = reg_data;
+
+	ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+	if (ret != 1)
+		dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+}
+
+u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr)
+{
+	u8 data[2];
+	int ret;
+	struct i2c_msg i2cmsg = {
+		.addr  = i_params->i2c_addr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = data,
+	};
+
+	data[0] = MSB(reg_addr);
+	data[1] = LSB(reg_addr);
+
+	ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+	if (ret != 1)
+		dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+	i2cmsg.flags = I2C_M_RD;
+	i2cmsg.len = 1;
+	ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+	if (ret != 1)
+		dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+	return data[0];
+}
+
+void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+	u8 position = 0, i = 0;
+
+	(*mask) = label & 0xff;
+
+	while ((position == 0) && (i < 8)) {
+		position = ((*mask) >> i) & 0x01;
+		i++;
+	}
+
+	(*pos) = (i - 1);
+}
+
+void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+{
+	u8 reg, mask, pos;
+
+	reg = stv0900_read_reg(i_params, (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);
+
+}
+
+u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+{
+	u8 val = 0xff;
+	u8 mask, pos;
+
+	extract_mask_pos(label, &mask, &pos);
+
+	val = stv0900_read_reg(i_params, label >> 16);
+	val = (val & mask) >> pos;
+
+	return val;
+}
+
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+{
+	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, 0x24);
+			stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24);
+			stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
+			msleep(3);
+			stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+
+			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;
+			}
+
+			msleep(3);
+			for (i = 0; i < 182; i++)
+				stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+
+			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]);
+			}
+
+			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;
+
+	return error;
+
+}
+
+u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, 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);
+
+	mclk = (div + 1) * ext_clk / ad_div;
+
+	dprintk(KERN_INFO "%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 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);
+
+	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);
+
+			/*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);
+
+			stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
+			stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+
+			if ((i_params->errs))
+				error = STV0900_I2C_ERROR;
+		}
+	}
+
+	return error;
+}
+
+u32 stv0900_get_err_count(struct stv0900_internal *i_params, 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);
+		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);
+		break;
+	}
+
+	err_val = (hsb << 16) + (msb << 8) + (lsb);
+
+	return err_val;
+}
+
+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;
+	enum fe_stv0900_demod_num demod = state->demod;
+
+	u32 fi2c;
+
+	dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
+	if (enable)
+		stv0900_write_bits(i_params, fi2c, 1);
+
+	return 0;
+}
+
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+					enum fe_stv0900_clock_type path1_ts,
+					enum fe_stv0900_clock_type path2_ts)
+{
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	if (i_params->chip_id >= 0x20) {
+		switch (path1_ts) {
+		case STV0900_PARALLEL_PUNCT_CLOCK:
+		case STV0900_DVBCI_CLOCK:
+			switch (path2_ts) {
+			case STV0900_SERIAL_PUNCT_CLOCK:
+			case STV0900_SERIAL_CONT_CLOCK:
+			default:
+				stv0900_write_reg(i_params, R0900_TSGENERAL,
+							0x00);
+				break;
+			case STV0900_PARALLEL_PUNCT_CLOCK:
+			case STV0900_DVBCI_CLOCK:
+				stv0900_write_reg(i_params, R0900_TSGENERAL,
+							0x06);
+				stv0900_write_bits(i_params,
+						F0900_P1_TSFIFO_MANSPEED, 3);
+				stv0900_write_bits(i_params,
+						F0900_P2_TSFIFO_MANSPEED, 0);
+				stv0900_write_reg(i_params,
+						R0900_P1_TSSPEED, 0x14);
+				stv0900_write_reg(i_params,
+						R0900_P2_TSSPEED, 0x28);
+				break;
+			}
+			break;
+		case STV0900_SERIAL_PUNCT_CLOCK:
+		case STV0900_SERIAL_CONT_CLOCK:
+		default:
+			switch (path2_ts) {
+			case STV0900_SERIAL_PUNCT_CLOCK:
+			case STV0900_SERIAL_CONT_CLOCK:
+			default:
+				stv0900_write_reg(i_params,
+						R0900_TSGENERAL, 0x0C);
+				break;
+			case STV0900_PARALLEL_PUNCT_CLOCK:
+			case STV0900_DVBCI_CLOCK:
+				stv0900_write_reg(i_params,
+						R0900_TSGENERAL, 0x0A);
+				dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+				break;
+			}
+			break;
+		}
+	} else {
+		switch (path1_ts) {
+		case STV0900_PARALLEL_PUNCT_CLOCK:
+		case STV0900_DVBCI_CLOCK:
+			switch (path2_ts) {
+			case STV0900_SERIAL_PUNCT_CLOCK:
+			case STV0900_SERIAL_CONT_CLOCK:
+			default:
+				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+							0x10);
+				break;
+			case STV0900_PARALLEL_PUNCT_CLOCK:
+			case STV0900_DVBCI_CLOCK:
+				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+							0x16);
+				stv0900_write_bits(i_params,
+						F0900_P1_TSFIFO_MANSPEED, 3);
+				stv0900_write_bits(i_params,
+						F0900_P2_TSFIFO_MANSPEED, 0);
+				stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+							0x14);
+				stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+							0x28);
+				break;
+			}
+
+			break;
+		case STV0900_SERIAL_PUNCT_CLOCK:
+		case STV0900_SERIAL_CONT_CLOCK:
+		default:
+			switch (path2_ts) {
+			case STV0900_SERIAL_PUNCT_CLOCK:
+			case STV0900_SERIAL_CONT_CLOCK:
+			default:
+				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+							0x14);
+				break;
+			case STV0900_PARALLEL_PUNCT_CLOCK:
+			case STV0900_DVBCI_CLOCK:
+				stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+							0x12);
+				dprintk(KERN_INFO "%s: 0x12\n", __func__);
+				break;
+			}
+
+			break;
+		}
+	}
+
+	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);
+		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);
+		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);
+		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);
+		break;
+	default:
+		break;
+	}
+
+	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);
+		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);
+		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);
+		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);
+		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);
+}
+
+void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+							u32 bandwidth)
+{
+	struct dvb_frontend_ops *frontend_ops = NULL;
+	struct dvb_tuner_ops *tuner_ops = NULL;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+
+	if (tuner_ops->set_frequency) {
+		if ((tuner_ops->set_frequency(fe, frequency)) < 0)
+			dprintk("%s: Invalid parameter\n", __func__);
+		else
+			dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+	}
+
+	if (tuner_ops->set_bandwidth) {
+		if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+			dprintk("%s: Invalid parameter\n", __func__);
+		else
+			dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+	}
+}
+
+void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+	struct dvb_frontend_ops *frontend_ops = NULL;
+	struct dvb_tuner_ops *tuner_ops = NULL;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+
+	if (tuner_ops->set_bandwidth) {
+		if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+			dprintk("%s: Invalid parameter\n", __func__);
+		else
+			dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+	}
+}
+
+static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+				const struct stv0900_table *lookup,
+				enum fe_stv0900_demod_num demod)
+{
+	s32 agc_gain = 0,
+		imin,
+		imax,
+		i,
+		rf_lvl = 0;
+
+	dprintk(KERN_INFO "%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;
+		}
+
+		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;
+
+				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)
+					* (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;
+
+	}
+
+	dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+
+	return rf_lvl;
+}
+
+static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *internal = state->internal;
+	s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
+								state->demod);
+
+	*strength = (rflevel + 100) * (16383 / 105);
+
+	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;
+	enum fe_stv0900_demod_num demod = state->demod;
+
+	s32 c_n = -100,
+		regval, imin, imax,
+		i,
+		lock_flag_field,
+		noise_field1,
+		noise_field0;
+
+	dprintk(KERN_INFO "%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);
+	} 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);
+	}
+
+	if (stv0900_get_bits(i_params, lock_flag_field)) {
+		if ((lookup != NULL) && lookup->size) {
+			regval = 0;
+			msleep(5);
+			for (i = 0; i < 16; i++) {
+				regval += MAKEWORD(stv0900_get_bits(i_params,
+								noise_field1),
+						stv0900_get_bits(i_params,
+								noise_field0));
+				msleep(1);
+			}
+
+			regval /= 16;
+			imin = 0;
+			imax = lookup->size - 1;
+			if (INRANGE(lookup->table[imin].regval,
+					regval,
+					lookup->table[imax].regval)) {
+				while ((imax - imin) > 1) {
+					i = (imax + imin) >> 1;
+					if (INRANGE(lookup->table[imin].regval,
+						    regval,
+						    lookup->table[i].regval))
+						imax = i;
+					else
+						imin = i;
+				}
+
+				c_n = ((regval - 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 (regval < lookup->table[imin].regval)
+				c_n = 1000;
+		}
+	}
+
+	return c_n;
+}
+
+static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	*snr = stv0900_carr_get_quality(fe,
+			(const struct stv0900_table *)&stv0900_s2_cn);
+	*snr += 30;
+	*snr *= (16383 / 1030);
+
+	return 0;
+}
+
+static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+				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);
+
+	switch (demod_state) {
+	case STV0900_SEARCH:
+	case STV0900_PLH_DETECTED:
+	default:
+		ber = 10000000;
+		break;
+	case STV0900_DVBS_FOUND:
+		ber = 0;
+		for (i = 0; i < 5; i++) {
+			msleep(5);
+			ber += stv0900_get_err_count(i_params, 0, demod);
+		}
+
+		ber /= 5;
+		if (stv0900_get_bits(i_params, prvit_field)) {
+			ber *= 9766;
+			ber = ber >> 13;
+		}
+
+		break;
+	case STV0900_DVBS2_FOUND:
+		ber = 0;
+		for (i = 0; i < 5; i++) {
+			msleep(5);
+			ber += stv0900_get_err_count(i_params, 0, demod);
+		}
+
+		ber /= 5;
+		if (stv0900_get_bits(i_params, pdel_lock_field)) {
+			ber *= 9766;
+			ber = ber >> 13;
+		}
+
+		break;
+	}
+
+	return ber;
+}
+
+static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *internal = state->internal;
+
+	*ber = stv0900_get_ber(internal, state->demod);
+
+	return 0;
+}
+
+int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+			enum fe_stv0900_demod_num demod, s32 time_out)
+{
+	s32 timer = 0,
+		lock = 0,
+		header_field,
+		lock_field;
+
+	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);
+		dprintk("Demod State = %d\n", dmd_state);
+		switch (dmd_state) {
+		case STV0900_SEARCH:
+		case STV0900_PLH_DETECTED:
+		default:
+			lock = 0;
+			break;
+		case STV0900_DVBS2_FOUND:
+		case STV0900_DVBS_FOUND:
+			lock = stv0900_get_bits(i_params, lock_field);
+			break;
+		}
+
+		if (lock == 0)
+			msleep(10);
+
+		timer += 10;
+	}
+
+	if (lock)
+		dprintk("DEMOD LOCK OK\n");
+	else
+		dprintk("DEMOD LOCK FAIL\n");
+
+	return lock;
+}
+
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod)
+{
+	s32 regflist,
+	i;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+
+	for (i = 0; i < 16; i++)
+		stv0900_write_reg(i_params, regflist + i, 0xff);
+}
+
+void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod)
+{
+	u32 matype,
+	mod_code,
+	fmod,
+	reg_index,
+	field_index;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	if (i_params->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;
+		}
+
+
+		switch (matype) {
+		case 0:
+		default:
+			fmod = 14;
+			break;
+		case 1:
+			fmod = 13;
+			break;
+		case 2:
+			fmod = 11;
+			break;
+		case 3:
+			fmod = 7;
+			break;
+		}
+
+		if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
+							&& (matype <= 1)) {
+			if (field_index == 0)
+				stv0900_write_reg(i_params, reg_index,
+							0xf0 | fmod);
+			else
+				stv0900_write_reg(i_params, 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);
+
+			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);
+
+			break;
+		}
+
+	}
+}
+
+void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+					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);
+
+		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);
+
+		break;
+	}
+}
+
+static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_CUSTOM;
+}
+
+static int stb0900_set_property(struct dvb_frontend *fe,
+				struct dtv_property *tvp)
+{
+	dprintk(KERN_INFO "%s(..)\n", __func__);
+
+	return 0;
+}
+
+static int stb0900_get_property(struct dvb_frontend *fe,
+				struct dtv_property *tvp)
+{
+	dprintk(KERN_INFO "%s(..)\n", __func__);
+
+	return 0;
+}
+
+void stv0900_start_search(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod)
+{
+
+	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);
+
+		if (i_params->chip_id < 0x20)
+			stv0900_write_reg(i_params, R0900_P1_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);
+		} 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(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 {
+			if (i_params->dmd1_symbol_rate < 10000000)
+				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+			else
+				stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+		}
+
+		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;
+		}
+
+		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);
+
+		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(i_params, R0900_P2_CFRINIT1, 0);
+		stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+
+		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);
+			}
+		}
+
+		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);
+			}
+
+		} 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);
+		}
+
+		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;
+		}
+
+		break;
+	}
+}
+
+u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
+							s32 pilot, u8 chip_id)
+{
+	u8 aclc_value = 0x29;
+	s32	i;
+	const struct stv0900_car_loop_optim *car_loop_s2;
+
+	dprintk(KERN_INFO "%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 (modcode < STV0900_QPSK_12) {
+		i = 0;
+		while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+			i++;
+
+		if (i >= 3)
+			i = 2;
+	} else {
+		i = 0;
+		while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+			i++;
+
+		if (i >= 14) {
+			i = 0;
+			while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+				i++;
+
+			if (i >= 11)
+				i = 10;
+		}
+	}
+
+	if (modcode <= STV0900_QPSK_25) {
+		if (pilot) {
+			if (srate <= 3000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+			else if (srate <= 7000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+			else if (srate <= 15000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+			else if (srate <= 25000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+			else
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+		} else {
+			if (srate <= 3000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+			else if (srate <= 7000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+			else if (srate <= 15000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+			else if (srate <= 25000000)
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+			else
+				aclc_value = FE_STV0900_S2LowQPCarLoopCut20[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;
+			else if (srate <= 7000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+			else if (srate <= 15000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+			else if (srate <= 25000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+			else
+				aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+		} else {
+			if (srate <= 3000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+			else if (srate <= 7000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+			else if (srate <= 15000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+			else if (srate <= 25000000)
+				aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+			else
+				aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+		}
+
+	} else {
+		if (srate <= 3000000)
+			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+		else if (srate <= 7000000)
+			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+		else if (srate <= 15000000)
+			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+		else if (srate <= 25000000)
+			aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+		else
+			aclc_value = FE_STV0900_S2APSKCarLoopCut20[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)
+{
+	s32 mod_index = 0;
+
+	u8 aclc_value = 0x0b;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	switch (modulation) {
+	case STV0900_QPSK:
+	default:
+		mod_index = 0;
+		break;
+	case STV0900_8PSK:
+		mod_index = 1;
+		break;
+	case STV0900_16APSK:
+		mod_index = 2;
+		break;
+	case STV0900_32APSK:
+		mod_index = 3;
+		break;
+	}
+
+	switch (chip_id) {
+	case 0x20:
+		if (srate <= 3000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+		else if (srate <= 7000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+		else if (srate <= 15000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+		else if (srate <= 25000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+		else
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+
+		break;
+	case 0x12:
+	default:
+		if (srate <= 3000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+		else if (srate <= 7000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+		else if (srate <= 15000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+		else if (srate <= 25000000)
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+		else
+			aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+
+		break;
+	}
+
+	return aclc_value;
+}
+
+static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+					enum fe_stv0900_demod_mode LDPC_Mode,
+					enum fe_stv0900_demod_num demod)
+{
+	enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+	dprintk(KERN_INFO "%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);
+
+			i_params->demod_mode = STV0900_DUAL;
+
+			stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+			stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+		}
+
+		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);
+
+		i_params->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);
+		break;
+	}
+
+	return error;
+}
+
+static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
+					struct stv0900_init_params *p_init)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	enum fe_stv0900_error error = STV0900_NO_ERROR;
+	enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+	int selosci;
+
+	struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
+						state->config->demod_address);
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	if (temp_int != NULL) {
+		state->internal = temp_int->internal;
+		(state->internal->dmds_used)++;
+		dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+		return STV0900_NO_ERROR;
+	} else {
+		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__);
+	}
+
+	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) {
+			if (error == STV0900_NO_ERROR) {
+				state->internal->demod_mode = p_init->demod_mode;
+
+				stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
+
+				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;
+
+				stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+				stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+				stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
+				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;
+				}
+
+				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(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);
+
+				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);
+
+				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;
+		}
+	}
+
+	return error;
+}
+
+static int stv0900_status(struct stv0900_internal *i_params,
+					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;
+
+	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);
+	switch (demod_state) {
+	case STV0900_SEARCH:
+	case STV0900_PLH_DETECTED:
+	default:
+		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);
+		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);
+		break;
+	}
+
+	return locked;
+}
+
+static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
+					struct dvb_frontend_parameters *params)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = state->internal;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	struct stv0900_search_params p_search;
+	struct stv0900_signal_info p_result;
+
+	enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+	dprintk(KERN_INFO "%s: ", __func__);
+
+	p_result.locked = FALSE;
+	p_search.path = state->demod;
+	p_search.frequency = c->frequency;
+	p_search.symbol_rate = c->symbol_rate;
+	p_search.search_range = 10000000;
+	p_search.fec = STV0900_FEC_UNKNOWN;
+	p_search.standard = STV0900_AUTO_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;
+			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;
+			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");
+		return DVBFE_ALGO_SEARCH_SUCCESS;
+	} else {
+		dprintk(KERN_INFO "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)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+
+	dprintk("%s: ", __func__);
+
+	if ((stv0900_status(state->internal, state->demod)) == TRUE) {
+		dprintk("DEMOD LOCK OK\n");
+		*status = FE_HAS_CARRIER
+			| FE_HAS_VITERBI
+			| FE_HAS_SYNC
+			| FE_HAS_LOCK;
+	} else
+		dprintk("DEMOD LOCK FAIL\n");
+
+	return 0;
+}
+
+static int stv0900_track(struct dvb_frontend *fe,
+			struct dvb_frontend_parameters *p)
+{
+	return 0;
+}
+
+static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
+{
+
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = 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);
+	else
+		stv0900_write_bits(i_params, rst_field, 0);
+
+	return 0;
+}
+
+static int stv0900_diseqc_init(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = 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);
+
+	return 0;
+}
+
+static int stv0900_init(struct dvb_frontend *fe)
+{
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	stv0900_stop_ts(fe, 1);
+	stv0900_diseqc_init(fe);
+
+	return 0;
+}
+
+static int stv0900_diseqc_send(struct stv0900_internal *i_params , 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++;
+		}
+
+		break;
+	}
+
+	return 0;
+}
+
+static int stv0900_send_master_cmd(struct dvb_frontend *fe,
+					struct dvb_diseqc_master_cmd *cmd)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+
+	return stv0900_diseqc_send(state->internal,
+				cmd->msg,
+				cmd->msg_len,
+				state->demod);
+}
+
+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;
+	enum fe_stv0900_demod_num demod = state->demod;
+	s32 mode_field;
+	u32 diseqc_fifo;
+
+	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);
+		break;
+	case SEC_MINI_B:
+		stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
+		stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+		break;
+	}
+
+	return 0;
+}
+
+static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
+				struct dvb_diseqc_slave_reply *reply)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = state->internal;
+	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;
+
+		while ((stv0900_get_bits(i_params, F0900_P2_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);
+
+			for (i = 0; i < reply->msg_len; i++)
+				reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = 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);
+
+	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);
+		/*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);
+		/*maintain the DiseqC reset to disable the 22KHz tone*/
+		stv0900_write_bits(i_params, reset_field, 1);
+	}
+
+	return 0;
+}
+
+static void stv0900_release(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	if ((--(state->internal->dmds_used)) <= 0) {
+
+		dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+
+		remove_inode(state->internal);
+		kfree(state->internal);
+	}
+
+	kfree(state);
+}
+
+static struct dvb_frontend_ops stv0900_ops = {
+
+	.info = {
+		.name			= "STV0900 frontend",
+		.type			= FE_QPSK,
+		.frequency_min		= 950000,
+		.frequency_max		= 2150000,
+		.frequency_stepsize	= 125,
+		.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_2G_MODULATION |
+					  FE_CAN_FEC_AUTO
+	},
+	.release			= stv0900_release,
+	.init				= stv0900_init,
+	.get_frontend_algo		= stv0900_frontend_algo,
+	.i2c_gate_ctrl			= stv0900_i2c_gate_ctrl,
+	.diseqc_send_master_cmd		= stv0900_send_master_cmd,
+	.diseqc_send_burst		= stv0900_send_burst,
+	.diseqc_recv_slave_reply	= stv0900_recv_slave_reply,
+	.set_tone			= stv0900_set_tone,
+	.set_property			= stb0900_set_property,
+	.get_property			= stb0900_get_property,
+	.search				= stv0900_search,
+	.track				= stv0900_track,
+	.read_status			= stv0900_read_status,
+	.read_ber			= stv0900_read_ber,
+	.read_signal_strength		= stv0900_read_signal_strength,
+	.read_snr			= stv0900_read_snr,
+};
+
+struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+					struct i2c_adapter *i2c,
+					int demod)
+{
+	struct stv0900_state *state = NULL;
+	struct stv0900_init_params init_params;
+	enum fe_stv0900_error err_stv0900;
+
+	state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	state->demod		= demod;
+	state->config		= config;
+	state->i2c_adap		= i2c;
+
+	memcpy(&state->frontend.ops, &stv0900_ops,
+			sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	switch (demod) {
+	case 0:
+	case 1:
+		init_params.dmd_ref_clk  	= config->xtal;
+		init_params.demod_mode		= STV0900_DUAL;
+		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.tuner1_adc		= config->tun1_adc;
+		init_params.path2_ts_clock	= config->path2_mode;
+		init_params.tun2_maddress	= config->tun2_maddress;
+		init_params.tuner2_adc		= config->tun2_adc;
+		init_params.tun2_iq_inversion	= STV0900_IQ_SWAPPED;
+
+		err_stv0900 = stv0900_init_internal(&state->frontend,
+							&init_params);
+
+		if (err_stv0900)
+			goto error;
+
+		break;
+	default:
+		goto error;
+		break;
+	}
+
+	dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
+	return &state->frontend;
+
+error:
+	dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
+		__func__, demod);
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(stv0900_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0900 frontend");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * stv0900.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 STV0900_H
+#define STV0900_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0900_config {
+	u8 demod_address;
+	u32 xtal;
+	u8 clkmode;/* 0 for CLKI,  2 for XTALI */
+
+	u8 diseqc_mode;
+
+	u8 path1_mode;
+	u8 path2_mode;
+
+	u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
+	u8 tun2_maddress;
+	u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
+	u8 tun2_adc;
+};
+
+#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
+							&& defined(MODULE))
+extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+					struct i2c_adapter *i2c, int demod);
+#else
+static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+					struct i2c_adapter *i2c, int demod)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_init.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_init.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_init.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_init.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,441 @@
+/*
+ * stv0900_init.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 STV0900_INIT_H
+#define STV0900_INIT_H
+
+#include "stv0900_priv.h"
+
+/* DVBS2 C/N Look-Up table */
+static const struct stv0900_table stv0900_s2_cn = {
+	55,
+	{
+		{ -30,	13348 }, /*C/N=-3dB*/
+		{ -20,	12640 }, /*C/N=-2dB*/
+		{ -10,	11883 }, /*C/N=-1dB*/
+		{ 0,	11101 }, /*C/N=-0dB*/
+		{ 5,	10718 }, /*C/N=0.5dB*/
+		{ 10,	10339 }, /*C/N=1.0dB*/
+		{ 15,	9947 }, /*C/N=1.5dB*/
+		{ 20,	9552 }, /*C/N=2.0dB*/
+		{ 25,	9183 }, /*C/N=2.5dB*/
+		{ 30,	8799 }, /*C/N=3.0dB*/
+		{ 35,	8422 }, /*C/N=3.5dB*/
+		{ 40,	8062 }, /*C/N=4.0dB*/
+		{ 45,	7707 }, /*C/N=4.5dB*/
+		{ 50,	7353 }, /*C/N=5.0dB*/
+		{ 55,	7025 }, /*C/N=5.5dB*/
+		{ 60,	6684 }, /*C/N=6.0dB*/
+		{ 65,	6331 }, /*C/N=6.5dB*/
+		{ 70,	6036 }, /*C/N=7.0dB*/
+		{ 75,	5727 }, /*C/N=7.5dB*/
+		{ 80,	5437 }, /*C/N=8.0dB*/
+		{ 85,	5164 }, /*C/N=8.5dB*/
+		{ 90,	4902 }, /*C/N=9.0dB*/
+		{ 95,	4653 }, /*C/N=9.5dB*/
+		{ 100,	4408 }, /*C/N=10.0dB*/
+		{ 105,	4187 }, /*C/N=10.5dB*/
+		{ 110,	3961 }, /*C/N=11.0dB*/
+		{ 115,	3751 }, /*C/N=11.5dB*/
+		{ 120,	3558 }, /*C/N=12.0dB*/
+		{ 125,	3368 }, /*C/N=12.5dB*/
+		{ 130,	3191 }, /*C/N=13.0dB*/
+		{ 135,	3017 }, /*C/N=13.5dB*/
+		{ 140,	2862 }, /*C/N=14.0dB*/
+		{ 145,	2710 }, /*C/N=14.5dB*/
+		{ 150,	2565 }, /*C/N=15.0dB*/
+		{ 160,	2300 }, /*C/N=16.0dB*/
+		{ 170,	2058 }, /*C/N=17.0dB*/
+		{ 180,	1849 }, /*C/N=18.0dB*/
+		{ 190,	1663 }, /*C/N=19.0dB*/
+		{ 200,	1495 }, /*C/N=20.0dB*/
+		{ 210,	1349 }, /*C/N=21.0dB*/
+		{ 220,	1222 }, /*C/N=22.0dB*/
+		{ 230,	1110 }, /*C/N=23.0dB*/
+		{ 240,	1011 }, /*C/N=24.0dB*/
+		{ 250,	925 }, /*C/N=25.0dB*/
+		{ 260,	853 }, /*C/N=26.0dB*/
+		{ 270,	789 }, /*C/N=27.0dB*/
+		{ 280,	734 }, /*C/N=28.0dB*/
+		{ 290,	690 }, /*C/N=29.0dB*/
+		{ 300,	650 }, /*C/N=30.0dB*/
+		{ 310,	619 }, /*C/N=31.0dB*/
+		{ 320,	593 }, /*C/N=32.0dB*/
+		{ 330,	571 }, /*C/N=33.0dB*/
+		{ 400,	498 }, /*C/N=40.0dB*/
+		{ 450,	484 }, /*C/N=45.0dB*/
+		{ 500,	481 }  /*C/N=50.0dB*/
+	}
+};
+
+/* RF level C/N Look-Up table */
+static const struct stv0900_table stv0900_rf = {
+	14,
+	{
+		{ -5, 0xCAA1 }, /*-5dBm*/
+		{ -10, 0xC229 }, /*-10dBm*/
+		{ -15, 0xBB08 }, /*-15dBm*/
+		{ -20, 0xB4BC }, /*-20dBm*/
+		{ -25, 0xAD5A }, /*-25dBm*/
+		{ -30, 0xA298 }, /*-30dBm*/
+		{ -35, 0x98A8 }, /*-35dBm*/
+		{ -40, 0x8389 }, /*-40dBm*/
+		{ -45, 0x59BE }, /*-45dBm*/
+		{ -50, 0x3A14 }, /*-50dBm*/
+		{ -55, 0x2D11 }, /*-55dBm*/
+		{ -60, 0x210D }, /*-60dBm*/
+		{ -65, 0xA14F }, /*-65dBm*/
+		{ -70, 0x7AA }	/*-70dBm*/
+	}
+};
+
+struct stv0900_car_loop_optim {
+	enum fe_stv0900_modcode modcode;
+	u8 car_loop_pilots_on_2;
+	u8 car_loop_pilots_off_2;
+	u8 car_loop_pilots_on_5;
+	u8 car_loop_pilots_off_5;
+	u8 car_loop_pilots_on_10;
+	u8 car_loop_pilots_off_10;
+	u8 car_loop_pilots_on_20;
+	u8 car_loop_pilots_off_20;
+	u8 car_loop_pilots_on_30;
+	u8 car_loop_pilots_off_30;
+
+};
+
+struct stv0900_short_frames_car_loop_optim {
+	enum fe_stv0900_modulation modulation;
+	u8 car_loop_cut12_2;    /* Cut 1.2,   SR<=3msps     */
+	u8 car_loop_cut20_2;    /* Cut 2.0,   SR<3msps      */
+	u8 car_loop_cut12_5;    /* Cut 1.2,   3<SR<=7msps   */
+	u8 car_loop_cut20_5;    /* Cut 2.0,   3<SR<=7msps   */
+	u8 car_loop_cut12_10;   /* Cut 1.2,   7<SR<=15msps  */
+	u8 car_loop_cut20_10;   /* Cut 2.0,   7<SR<=15msps  */
+	u8 car_loop_cut12_20;   /* Cut 1.2,   10<SR<=25msps */
+	u8 car_loop_cut20_20;   /* Cut 2.0,   10<SR<=25msps */
+	u8 car_loop_cut12_30;   /* Cut 1.2,   25<SR<=45msps */
+	u8 car_loop_cut20_30;   /* Cut 2.0,   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 }
+};
+
+
+/* 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 }
+};
+
+
+
+/* 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 }
+};
+
+
+/* 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 }
+};
+
+
+/* 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 u16 STV0900_InitVal[182][2] = {
+	{ R0900_OUTCFG		, 0x00	},
+	{ R0900_MODECFG		, 0xff	},
+	{ R0900_AGCRF1CFG	, 0x11	},
+	{ R0900_AGCRF2CFG	, 0x13	},
+	{ R0900_TSGENERAL1X	, 0x14	},
+	{ R0900_TSTTNR2		, 0x21	},
+	{ R0900_TSTTNR4		, 0x21	},
+	{ R0900_P2_DISTXCTL	, 0x22	},
+	{ R0900_P2_F22TX	, 0xc0	},
+	{ R0900_P2_F22RX	, 0xc0	},
+	{ R0900_P2_DISRXCTL	, 0x00	},
+	{ R0900_P2_TNRSTEPS	, 0x87	},
+	{ R0900_P2_TNRGAIN	, 0x09	},
+	{ R0900_P2_DMDCFGMD	, 0xF9	},
+	{ R0900_P2_DEMOD	, 0x08	},
+	{ R0900_P2_DMDCFG3	, 0xc4	},
+	{ R0900_P2_CARFREQ	, 0xed	},
+	{ R0900_P2_TNRCFG2	, 0x02	},
+	{ R0900_P2_TNRCFG3	, 0x02	},
+	{ R0900_P2_LDT		, 0xd0	},
+	{ R0900_P2_LDT2		, 0xb8	},
+	{ R0900_P2_TMGCFG	, 0xd2	},
+	{ R0900_P2_TMGTHRISE	, 0x20	},
+	{ R0900_P2_TMGTHFALL	, 0x00	},
+	{ R0900_P2_FECSPY	, 0x88	},
+	{ R0900_P2_FSPYDATA	, 0x3a	},
+	{ R0900_P2_FBERCPT4	, 0x00	},
+	{ R0900_P2_FSPYBER	, 0x10	},
+	{ R0900_P2_ERRCTRL1	, 0x35	},
+	{ R0900_P2_ERRCTRL2	, 0xc1	},
+	{ R0900_P2_CFRICFG	, 0xf8	},
+	{ R0900_P2_NOSCFG	, 0x1c	},
+	{ R0900_P2_DMDT0M	, 0x20	},
+	{ R0900_P2_CORRELMANT	, 0x70	},
+	{ R0900_P2_CORRELABS	, 0x88	},
+	{ R0900_P2_AGC2O	, 0x5b	},
+	{ R0900_P2_AGC2REF	, 0x38	},
+	{ R0900_P2_CARCFG	, 0xe4	},
+	{ R0900_P2_ACLC		, 0x1A	},
+	{ R0900_P2_BCLC		, 0x09	},
+	{ R0900_P2_CARHDR	, 0x08	},
+	{ R0900_P2_KREFTMG	, 0xc1	},
+	{ R0900_P2_SFRUPRATIO	, 0xf0	},
+	{ R0900_P2_SFRLOWRATIO	, 0x70	},
+	{ R0900_P2_SFRSTEP	, 0x58	},
+	{ R0900_P2_TMGCFG2	, 0x01	},
+	{ R0900_P2_CAR2CFG	, 0x26	},
+	{ R0900_P2_BCLC2S2Q	, 0x86	},
+	{ R0900_P2_BCLC2S28	, 0x86	},
+	{ R0900_P2_SMAPCOEF7	, 0x77	},
+	{ R0900_P2_SMAPCOEF6	, 0x85	},
+	{ R0900_P2_SMAPCOEF5	, 0x77	},
+	{ R0900_P2_TSCFGL	, 0x20	},
+	{ R0900_P2_DMDCFG2	, 0x3b	},
+	{ R0900_P2_MODCODLST0	, 0xff	},
+	{ R0900_P2_MODCODLST1	, 0xff	},
+	{ R0900_P2_MODCODLST2	, 0xff	},
+	{ R0900_P2_MODCODLST3	, 0xff	},
+	{ R0900_P2_MODCODLST4	, 0xff	},
+	{ R0900_P2_MODCODLST5	, 0xff	},
+	{ R0900_P2_MODCODLST6	, 0xff	},
+	{ R0900_P2_MODCODLST7	, 0xcc	},
+	{ R0900_P2_MODCODLST8	, 0xcc	},
+	{ R0900_P2_MODCODLST9	, 0xcc	},
+	{ R0900_P2_MODCODLSTA	, 0xcc	},
+	{ R0900_P2_MODCODLSTB	, 0xcc	},
+	{ R0900_P2_MODCODLSTC	, 0xcc	},
+	{ R0900_P2_MODCODLSTD	, 0xcc	},
+	{ R0900_P2_MODCODLSTE	, 0xcc	},
+	{ R0900_P2_MODCODLSTF	, 0xcf	},
+	{ R0900_P1_DISTXCTL	, 0x22	},
+	{ R0900_P1_F22TX	, 0xc0	},
+	{ R0900_P1_F22RX	, 0xc0	},
+	{ R0900_P1_DISRXCTL	, 0x00	},
+	{ R0900_P1_TNRSTEPS	, 0x87	},
+	{ R0900_P1_TNRGAIN	, 0x09	},
+	{ R0900_P1_DMDCFGMD	, 0xf9	},
+	{ R0900_P1_DEMOD	, 0x08	},
+	{ R0900_P1_DMDCFG3	, 0xc4	},
+	{ R0900_P1_DMDT0M	, 0x20	},
+	{ R0900_P1_CARFREQ	, 0xed	},
+	{ R0900_P1_TNRCFG2	, 0x82	},
+	{ R0900_P1_TNRCFG3	, 0x02	},
+	{ R0900_P1_LDT		, 0xd0	},
+	{ R0900_P1_LDT2		, 0xb8	},
+	{ R0900_P1_TMGCFG	, 0xd2	},
+	{ R0900_P1_TMGTHRISE	, 0x20	},
+	{ R0900_P1_TMGTHFALL	, 0x00	},
+	{ R0900_P1_SFRUPRATIO	, 0xf0	},
+	{ R0900_P1_SFRLOWRATIO	, 0x70	},
+	{ R0900_P1_TSCFGL	, 0x20	},
+	{ R0900_P1_FECSPY	, 0x88	},
+	{ R0900_P1_FSPYDATA	, 0x3a	},
+	{ R0900_P1_FBERCPT4	, 0x00	},
+	{ R0900_P1_FSPYBER	, 0x10	},
+	{ R0900_P1_ERRCTRL1	, 0x35	},
+	{ R0900_P1_ERRCTRL2	, 0xc1	},
+	{ R0900_P1_CFRICFG	, 0xf8	},
+	{ R0900_P1_NOSCFG	, 0x1c	},
+	{ R0900_P1_CORRELMANT	, 0x70	},
+	{ R0900_P1_CORRELABS	, 0x88	},
+	{ R0900_P1_AGC2O	, 0x5b	},
+	{ R0900_P1_AGC2REF	, 0x38	},
+	{ R0900_P1_CARCFG	, 0xe4	},
+	{ R0900_P1_ACLC		, 0x1A	},
+	{ R0900_P1_BCLC		, 0x09	},
+	{ R0900_P1_CARHDR	, 0x08	},
+	{ R0900_P1_KREFTMG	, 0xc1	},
+	{ R0900_P1_SFRSTEP	, 0x58	},
+	{ R0900_P1_TMGCFG2	, 0x01	},
+	{ R0900_P1_CAR2CFG	, 0x26	},
+	{ R0900_P1_BCLC2S2Q	, 0x86	},
+	{ R0900_P1_BCLC2S28	, 0x86	},
+	{ R0900_P1_SMAPCOEF7	, 0x77	},
+	{ R0900_P1_SMAPCOEF6	, 0x85	},
+	{ R0900_P1_SMAPCOEF5	, 0x77	},
+	{ R0900_P1_DMDCFG2	, 0x3b	},
+	{ R0900_P1_MODCODLST0	, 0xff	},
+	{ R0900_P1_MODCODLST1	, 0xff	},
+	{ R0900_P1_MODCODLST2	, 0xff	},
+	{ R0900_P1_MODCODLST3	, 0xff	},
+	{ R0900_P1_MODCODLST4	, 0xff	},
+	{ R0900_P1_MODCODLST5	, 0xff	},
+	{ R0900_P1_MODCODLST6	, 0xff	},
+	{ R0900_P1_MODCODLST7	, 0xcc	},
+	{ R0900_P1_MODCODLST8	, 0xcc	},
+	{ R0900_P1_MODCODLST9	, 0xcc	},
+	{ R0900_P1_MODCODLSTA	, 0xcc	},
+	{ R0900_P1_MODCODLSTB	, 0xcc	},
+	{ R0900_P1_MODCODLSTC	, 0xcc	},
+	{ R0900_P1_MODCODLSTD	, 0xcc	},
+	{ R0900_P1_MODCODLSTE	, 0xcc	},
+	{ R0900_P1_MODCODLSTF	, 0xcf	},
+	{ R0900_GENCFG		, 0x1d	},
+	{ R0900_NBITER_NF4	, 0x37	},
+	{ R0900_NBITER_NF5	, 0x29	},
+	{ R0900_NBITER_NF6	, 0x37	},
+	{ R0900_NBITER_NF7	, 0x33	},
+	{ R0900_NBITER_NF8	, 0x31	},
+	{ R0900_NBITER_NF9	, 0x2f	},
+	{ R0900_NBITER_NF10	, 0x39	},
+	{ R0900_NBITER_NF11	, 0x3a	},
+	{ R0900_NBITER_NF12	, 0x29	},
+	{ R0900_NBITER_NF13	, 0x37	},
+	{ R0900_NBITER_NF14	, 0x33	},
+	{ R0900_NBITER_NF15	, 0x2f	},
+	{ R0900_NBITER_NF16	, 0x39	},
+	{ R0900_NBITER_NF17	, 0x3a	},
+	{ R0900_NBITERNOERR	, 0x04	},
+	{ R0900_GAINLLR_NF4	, 0x0C	},
+	{ R0900_GAINLLR_NF5	, 0x0F	},
+	{ R0900_GAINLLR_NF6	, 0x11	},
+	{ R0900_GAINLLR_NF7	, 0x14	},
+	{ R0900_GAINLLR_NF8	, 0x17	},
+	{ R0900_GAINLLR_NF9	, 0x19	},
+	{ R0900_GAINLLR_NF10	, 0x20	},
+	{ R0900_GAINLLR_NF11	, 0x21	},
+	{ R0900_GAINLLR_NF12	, 0x0D	},
+	{ R0900_GAINLLR_NF13	, 0x0F	},
+	{ R0900_GAINLLR_NF14	, 0x13	},
+	{ R0900_GAINLLR_NF15	, 0x1A	},
+	{ R0900_GAINLLR_NF16	, 0x1F	},
+	{ R0900_GAINLLR_NF17	, 0x21	},
+	{ R0900_RCCFGH		, 0x20	},
+	{ R0900_P1_FECM		, 0x01	}, /*disable DSS modes*/
+	{ R0900_P2_FECM		, 0x01	}, /*disable DSS modes*/
+	{ R0900_P1_PRVIT	, 0x2F	}, /*disable puncture rate 6/7*/
+	{ R0900_P2_PRVIT	, 0x2F	}, /*disable puncture rate 6/7*/
+	{ R0900_STROUT1CFG	, 0x4c	},
+	{ R0900_STROUT2CFG	, 0x4c	},
+	{ R0900_CLKOUT1CFG	, 0x50	},
+	{ R0900_CLKOUT2CFG	, 0x50	},
+	{ R0900_DPN1CFG		, 0x4a	},
+	{ R0900_DPN2CFG		, 0x4a	},
+	{ R0900_DATA71CFG	, 0x52	},
+	{ R0900_DATA72CFG	, 0x52	},
+	{ R0900_P1_TSCFGM	, 0xc0	},
+	{ R0900_P2_TSCFGM	, 0xc0	},
+	{ R0900_P1_TSCFGH	, 0xe0	}, /* DVB-CI timings */
+	{ R0900_P2_TSCFGH	, 0xe0	}, /* DVB-CI timings */
+	{ R0900_P1_TSSPEED	, 0x40	},
+	{ R0900_P2_TSSPEED	, 0x40	},
+};
+
+static const u16 STV0900_Cut20_AddOnVal[32][2] = {
+	{ R0900_P2_DMDCFG3	, 0xe8	},
+	{ R0900_P2_DMDCFG4	, 0x10	},
+	{ R0900_P2_CARFREQ	, 0x38	},
+	{ R0900_P2_CARHDR	, 0x20	},
+	{ R0900_P2_KREFTMG	, 0x5a	},
+	{ R0900_P2_SMAPCOEF7	, 0x06	},
+	{ R0900_P2_SMAPCOEF6	, 0x00	},
+	{ R0900_P2_SMAPCOEF5	, 0x04	},
+	{ R0900_P2_NOSCFG	, 0x0c	},
+	{ R0900_P1_DMDCFG3	, 0xe8	},
+	{ R0900_P1_DMDCFG4	, 0x10	},
+	{ R0900_P1_CARFREQ	, 0x38	},
+	{ R0900_P1_CARHDR	, 0x20	},
+	{ R0900_P1_KREFTMG	, 0x5a	},
+	{ R0900_P1_SMAPCOEF7	, 0x06	},
+	{ R0900_P1_SMAPCOEF6	, 0x00	},
+	{ R0900_P1_SMAPCOEF5	, 0x04	},
+	{ R0900_P1_NOSCFG	, 0x0c	},
+	{ R0900_GAINLLR_NF4	, 0x21	},
+	{ R0900_GAINLLR_NF5	, 0x21	},
+	{ R0900_GAINLLR_NF6	, 0x20	},
+	{ R0900_GAINLLR_NF7	, 0x1F	},
+	{ R0900_GAINLLR_NF8	, 0x1E	},
+	{ R0900_GAINLLR_NF9	, 0x1E	},
+	{ R0900_GAINLLR_NF10	, 0x1D	},
+	{ R0900_GAINLLR_NF11	, 0x1B	},
+	{ R0900_GAINLLR_NF12	, 0x20	},
+	{ R0900_GAINLLR_NF13	, 0x20	},
+	{ R0900_GAINLLR_NF14	, 0x20	},
+	{ R0900_GAINLLR_NF15	, 0x20	},
+	{ R0900_GAINLLR_NF16	, 0x20	},
+	{ R0900_GAINLLR_NF17	, 0x21	}
+
+};
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_priv.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,430 @@
+/*
+ * stv0900_priv.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 STV0900_PRIV_H
+#define STV0900_PRIV_H
+
+#include <linux/i2c.h>
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
+		|| (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xFF))
+#define MSB(Y) (((Y) >> 8) & 0xFF)
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+#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)
+
+#define dmd_choose(a, b)	(demod = STV0900_DEMOD_2 ? b : a))
+
+static int stvdebug;
+
+#define dprintk(args...) \
+	do { \
+		if (stvdebug) \
+			printk(KERN_DEBUG args); \
+	} while (0)
+
+#define STV0900_MAXLOOKUPSIZE 500
+#define STV0900_BLIND_SEARCH_AGC2_TH 700
+
+/* One point of the lookup table */
+struct stv000_lookpoint {
+	s32 realval;/* real value */
+	s32 regval;/* binary value */
+};
+
+/* Lookup table definition */
+struct stv0900_table{
+	s32 size;/* Size of the lookup table */
+	struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
+};
+
+enum fe_stv0900_error {
+	STV0900_NO_ERROR = 0,
+	STV0900_INVALID_HANDLE,
+	STV0900_BAD_PARAMETER,
+	STV0900_I2C_ERROR,
+	STV0900_SEARCH_FAILED,
+};
+
+enum fe_stv0900_clock_type {
+	STV0900_USE_REGISTERS_DEFAULT,
+	STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
+	STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
+	STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
+	STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
+};
+
+enum fe_stv0900_search_state {
+	STV0900_SEARCH = 0,
+	STV0900_PLH_DETECTED,
+	STV0900_DVBS2_FOUND,
+	STV0900_DVBS_FOUND
+
+};
+
+enum fe_stv0900_ldpc_state {
+	STV0900_PATH1_OFF_PATH2_OFF = 0,
+	STV0900_PATH1_ON_PATH2_OFF = 1,
+	STV0900_PATH1_OFF_PATH2_ON = 2,
+	STV0900_PATH1_ON_PATH2_ON = 3
+};
+
+enum fe_stv0900_signal_type {
+	STV0900_NOAGC1 = 0,
+	STV0900_AGC1OK,
+	STV0900_NOTIMING,
+	STV0900_ANALOGCARRIER,
+	STV0900_TIMINGOK,
+	STV0900_NOAGC2,
+	STV0900_AGC2OK,
+	STV0900_NOCARRIER,
+	STV0900_CARRIEROK,
+	STV0900_NODATA,
+	STV0900_DATAOK,
+	STV0900_OUTOFRANGE,
+	STV0900_RANGEOK
+};
+
+enum fe_stv0900_demod_num {
+	STV0900_DEMOD_1,
+	STV0900_DEMOD_2
+};
+
+enum fe_stv0900_tracking_standard {
+	STV0900_DVBS1_STANDARD,/* Found Standard*/
+	STV0900_DVBS2_STANDARD,
+	STV0900_DSS_STANDARD,
+	STV0900_TURBOCODE_STANDARD,
+	STV0900_UNKNOWN_STANDARD
+};
+
+enum fe_stv0900_search_standard {
+	STV0900_AUTO_SEARCH,
+	STV0900_SEARCH_DVBS1,/* Search Standard*/
+	STV0900_SEARCH_DVBS2,
+	STV0900_SEARCH_DSS,
+	STV0900_SEARCH_TURBOCODE
+};
+
+enum fe_stv0900_search_algo {
+	STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
+	STV0900_COLD_START,/* only the SR is known */
+	STV0900_WARM_START/* offset freq and SR are known */
+};
+
+enum fe_stv0900_modulation {
+	STV0900_QPSK,
+	STV0900_8PSK,
+	STV0900_16APSK,
+	STV0900_32APSK,
+	STV0900_UNKNOWN
+};
+
+enum fe_stv0900_modcode {
+	STV0900_DUMMY_PLF,
+	STV0900_QPSK_14,
+	STV0900_QPSK_13,
+	STV0900_QPSK_25,
+	STV0900_QPSK_12,
+	STV0900_QPSK_35,
+	STV0900_QPSK_23,
+	STV0900_QPSK_34,
+	STV0900_QPSK_45,
+	STV0900_QPSK_56,
+	STV0900_QPSK_89,
+	STV0900_QPSK_910,
+	STV0900_8PSK_35,
+	STV0900_8PSK_23,
+	STV0900_8PSK_34,
+	STV0900_8PSK_56,
+	STV0900_8PSK_89,
+	STV0900_8PSK_910,
+	STV0900_16APSK_23,
+	STV0900_16APSK_34,
+	STV0900_16APSK_45,
+	STV0900_16APSK_56,
+	STV0900_16APSK_89,
+	STV0900_16APSK_910,
+	STV0900_32APSK_34,
+	STV0900_32APSK_45,
+	STV0900_32APSK_56,
+	STV0900_32APSK_89,
+	STV0900_32APSK_910,
+	STV0900_MODCODE_UNKNOWN
+};
+
+enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
+	STV0900_FEC_1_2 = 0,
+	STV0900_FEC_2_3,
+	STV0900_FEC_3_4,
+	STV0900_FEC_4_5,/*for turbo code only*/
+	STV0900_FEC_5_6,
+	STV0900_FEC_6_7,/*for DSS only */
+	STV0900_FEC_7_8,
+	STV0900_FEC_8_9,/*for turbo code only*/
+	STV0900_FEC_UNKNOWN
+};
+
+enum fe_stv0900_frame_length {
+	STV0900_LONG_FRAME,
+	STV0900_SHORT_FRAME
+};
+
+enum fe_stv0900_pilot {
+	STV0900_PILOTS_OFF,
+	STV0900_PILOTS_ON
+};
+
+enum fe_stv0900_rolloff {
+	STV0900_35,
+	STV0900_25,
+	STV0900_20
+};
+
+enum fe_stv0900_search_iq {
+	STV0900_IQ_AUTO,
+	STV0900_IQ_AUTO_NORMAL_FIRST,
+	STV0900_IQ_FORCE_NORMAL,
+	STV0900_IQ_FORCE_SWAPPED
+};
+
+enum stv0900_iq_inversion {
+	STV0900_IQ_NORMAL,
+	STV0900_IQ_SWAPPED
+};
+
+enum fe_stv0900_diseqc_mode {
+	STV0900_22KHZ_Continues = 0,
+	STV0900_DISEQC_2_3_PWM = 2,
+	STV0900_DISEQC_3_3_PWM = 3,
+	STV0900_DISEQC_2_3_ENVELOP = 4,
+	STV0900_DISEQC_3_3_ENVELOP = 5
+};
+
+enum fe_stv0900_demod_mode {
+	STV0900_SINGLE = 0,
+	STV0900_DUAL
+};
+
+struct stv0900_init_params{
+	u32	dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */
+
+	/* Demodulator Type (single demod or dual demod) */
+	enum fe_stv0900_demod_mode	demod_mode;
+	enum fe_stv0900_rolloff		rolloff;
+	enum fe_stv0900_clock_type	path1_ts_clock;
+
+	u8	tun1_maddress;
+	int	tuner1_adc;
+
+	/* IQ from the tuner1 to the demod */
+	enum stv0900_iq_inversion	tun1_iq_inversion;
+	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;
+};
+
+struct stv0900_search_params {
+	enum fe_stv0900_demod_num	path;/* Path Used demod1 or 2 */
+
+	u32	frequency;/* Transponder frequency (in KHz) */
+	u32	symbol_rate;/* Transponder symbol rate  (in bds)*/
+	u32	search_range;/* Range of the search (in Hz) */
+
+	enum fe_stv0900_search_standard	standard;
+	enum fe_stv0900_modulation	modulation;
+	enum fe_stv0900_fec		fec;
+	enum fe_stv0900_modcode		modcode;
+	enum fe_stv0900_search_iq	iq_inversion;
+	enum fe_stv0900_search_algo	search_algo;
+
+};
+
+struct stv0900_signal_info {
+	int	locked;/* Transponder locked */
+	u32	frequency;/* Transponder frequency (in KHz) */
+	u32	symbol_rate;/* Transponder symbol rate  (in Mbds) */
+
+	enum fe_stv0900_tracking_standard	standard;
+	enum fe_stv0900_fec			fec;
+	enum fe_stv0900_modcode			modcode;
+	enum fe_stv0900_modulation		modulation;
+	enum fe_stv0900_pilot			pilot;
+	enum fe_stv0900_frame_length		frame_length;
+	enum stv0900_iq_inversion		spectrum;
+	enum fe_stv0900_rolloff			rolloff;
+
+	s32 Power;/* Power of the RF signal (dBm) */
+	s32 C_N;/* Carrier to noise ratio (dB x10)*/
+	u32 BER;/* Bit error rate (x10^7) */
+
+};
+
+struct stv0900_internal{
+	s32	quartz;
+	s32	mclk;
+	/* manual RollOff for DVBS1/DSS only */
+	enum fe_stv0900_rolloff		rolloff;
+	/* 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;
+
+	/* algorithm for search Blind, Cold or Warm*/
+	enum fe_stv0900_search_algo	dmd1_srch_algo;
+	/* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
+	enum fe_stv0900_search_standard	dmd1_srch_standard;
+	/* 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;
+
+	/* results of the search*/
+	struct stv0900_signal_info	dmd2_rslts;
+	/* current state of the search algorithm */
+	enum fe_stv0900_signal_type	dmd2_state;
+
+	enum fe_stv0900_error		dmd2_err;
+
+	struct i2c_adapter	*i2c_adap;
+	u8			i2c_addr;
+	u8			clkmode;/* 0 for CLKI, 2 for XTALI */
+	u8			chip_id;
+	enum fe_stv0900_error	errs;
+	int dmds_used;
+};
+
+/* state for each demod */
+struct stv0900_state {
+	/* pointer for internal params, one for each pair of demods */
+	struct stv0900_internal		*internal;
+	struct i2c_adapter		*i2c_adap;
+	const struct stv0900_config	*config;
+	struct dvb_frontend		frontend;
+	int demod;
+};
+
+extern s32 ge2comp(s32 a, s32 width);
+
+extern void stv0900_write_reg(struct stv0900_internal *i_params,
+				u16 reg_addr, u8 reg_data);
+
+extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
+				u16 reg_addr);
+
+extern void stv0900_write_bits(struct stv0900_internal *i_params,
+				u32 label, u8 val);
+
+extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
+				u32 label);
+
+extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod, s32 time_out);
+extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
+
+extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+				u32 bandwidth);
+extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
+
+extern void stv0900_start_search(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod);
+
+extern u8 stv0900_get_optim_carr_loop(s32 srate,
+				enum fe_stv0900_modcode modcode,
+				s32 pilot, u8 chip_id);
+
+extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
+				enum fe_stv0900_modulation modulation,
+				u8 chip_id);
+
+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,
+				enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode_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,
+				enum fe_stv0900_demod_num demod);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_reg.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3787 @@
+/*
+ * stv0900_reg.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 STV0900_REG_H
+#define STV0900_REG_H
+
+/*MID*/
+#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
+
+/*DACR2*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*CLKI2CFG*/
+#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
+
+/*GPIO2CFG*/
+#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
+
+/*GPIO4CFG*/
+#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
+
+/*GPIO6CFG*/
+#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
+
+/*GPIO8CFG*/
+#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
+
+/*GPIO10CFG*/
+#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
+
+/*GPIO12CFG*/
+#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
+
+/*CS0CFG*/
+#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
+
+/*STDBYCFG*/
+#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
+
+/*AGCRF1CFG*/
+#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
+
+/*SCLT1CFG*/
+#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
+
+/*AGCRF2CFG*/
+#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
+
+/*SCLT2CFG*/
+#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
+
+/*CLKOUT27CFG*/
+#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
+
+/*DPN1CFG*/
+#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
+
+/*CLKOUT1CFG*/
+#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
+
+/*ERROR2CFG*/
+#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
+
+/*STROUT2CFG*/
+#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
+
+/*DATA72CFG*/
+#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
+
+/*DPN3CFG*/
+#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
+
+/*CLKOUT3CFG*/
+#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
+
+/*FSKTFC2*/
+#define R0900_FSKTFC2  0xf170
+#define F0900_FSKT_KMOD  0xf17000fc
+#define F0900_FSKT_CAR2  0xf1700003
+
+/*FSKTFC1*/
+#define R0900_FSKTFC1  0xf171
+#define F0900_FSKT_CAR1  0xf17100ff
+
+/*FSKTFC0*/
+#define R0900_FSKTFC0  0xf172
+#define F0900_FSKT_CAR0  0xf17200ff
+
+/*FSKTDELTAF1*/
+#define R0900_FSKTDELTAF1  0xf173
+#define F0900_FSKT_DELTAF1  0xf173000f
+
+/*FSKTDELTAF0*/
+#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
+
+/*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
+
+/*FSKRFC1*/
+#define R0900_FSKRFC1  0xf177
+#define F0900_FSKR_CAR1  0xf17700ff
+
+/*FSKRFC0*/
+#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
+
+/*FSKRK2*/
+#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
+
+/*FSKRAGC*/
+#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
+
+/*FSKRPLTH1*/
+#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
+
+/*FSKRDF1*/
+#define R0900_FSKRDF1  0xf180
+#define F0900_FSKR_OUT  0xf1800080
+#define F0900_FSKR_DELTAF1  0xf180001f
+
+/*FSKRDF0*/
+#define R0900_FSKRDF0  0xf181
+#define F0900_FSKR_DELTAF0  0xf18100ff
+
+/*FSKRSTEPP*/
+#define R0900_FSKRSTEPP  0xf182
+#define F0900_FSKR_STEP_PLUS  0xf18200ff
+
+/*FSKRSTEPM*/
+#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
+
+/*FSKRDET0*/
+#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
+
+/*FSKRDTH0*/
+#define R0900_FSKRDTH0  0xf187
+#define F0900_FSKR_CARDET_THRESH0  0xf18700ff
+
+/*FSKRLOSS*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_DISRXDATA*/
+#define R0900_P2_DISRXDATA  0xf196
+#define F0900_P2_DISRX_DATA  0xf19600ff
+
+/*P2_DISTXDATA*/
+#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
+
+/*P2_F22TX*/
+#define R0900_P2_F22TX  0xf199
+#define F0900_P2_F22_REG  0xf19900ff
+
+/*P2_F22RX*/
+#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
+
+/*P2_ACRDIV*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_DISRXDATA*/
+#define R0900_P1_DISRXDATA  0xf1a6
+#define F0900_P1_DISRX_DATA  0xf1a600ff
+
+/*P1_DISTXDATA*/
+#define R0900_P1_DISTXDATA  0xf1a7
+#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
+
+/*P1_F22TX*/
+#define R0900_P1_F22TX  0xf1a9
+#define F0900_P1_F22_REG  0xf1a900ff
+
+/*P1_F22RX*/
+#define R0900_P1_F22RX  0xf1aa
+#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
+
+/*P1_ACRDIV*/
+#define R0900_P1_ACRDIV  0xf1ad
+#define F0900_P1_ACR_DIV  0xf1ad00ff
+
+/*NCOARSE*/
+#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
+
+/*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
+
+/*PLLSTAT*/
+#define R0900_PLLSTAT  0xf1b8
+#define F0900_ACM_SEL  0xf1b80080
+#define F0900_DTV_SEL  0xf1b80040
+#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
+
+/*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
+
+/*TSTTNR0*/
+#define R0900_TSTTNR0  0xf1df
+#define F0900_SEL_FSK  0xf1df0080
+#define F0900_FSK_PON  0xf1df0004
+#define F0900_FSK_OPENLOOP  0xf1df0002
+
+/*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
+
+/*TSTTNR2*/
+#define R0900_TSTTNR2  0xf1e1
+#define F0900_DISEQC1_PON  0xf1e10020
+#define F0900_DISEQC1_TEST  0xf1e1001f
+
+/*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
+
+/*TSTTNR4*/
+#define R0900_TSTTNR4  0xf1e3
+#define F0900_DISEQC2_PON  0xf1e30020
+#define F0900_DISEQC2_TEST  0xf1e3001f
+
+/*P2_IQCONST*/
+#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
+
+/*P2_ISYMB*/
+#define R0900_P2_ISYMB  0xf202
+#define F0900_P2_I_SYMBOL  0xf20201ff
+
+/*P2_QSYMB*/
+#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
+
+/*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
+
+/*P2_AGC1REF*/
+#define R0900_P2_AGC1REF  0xf207
+#define F0900_P2_AGCIQ_REF  0xf20700ff
+
+/*P2_IDCCOMP*/
+#define R0900_P2_IDCCOMP  0xf208
+#define F0900_P2_IAVERAGE_ADJ  0xf20801ff
+
+/*P2_QDCCOMP*/
+#define R0900_P2_QDCCOMP  0xf209
+#define F0900_P2_QAVERAGE_ADJ  0xf20901ff
+
+/*P2_POWERI*/
+#define R0900_P2_POWERI  0xf20a
+#define F0900_P2_POWER_I  0xf20a00ff
+
+/*P2_POWERQ*/
+#define R0900_P2_POWERQ  0xf20b
+#define F0900_P2_POWER_Q  0xf20b00ff
+
+/*P2_AGC1AMM*/
+#define R0900_P2_AGC1AMM  0xf20c
+#define F0900_P2_AMM_VALUE  0xf20c00ff
+
+/*P2_AGC1QUAD*/
+#define R0900_P2_AGC1QUAD  0xf20d
+#define F0900_P2_QUAD_VALUE  0xf20d01ff
+
+/*P2_AGCIQIN1*/
+#define R0900_P2_AGCIQIN1  0xf20e
+#define F0900_P2_AGCIQ_VALUE1  0xf20e00ff
+
+/*P2_AGCIQIN0*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_DMDT0M*/
+#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
+
+/*P2_DMDFLYW*/
+#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
+
+/*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
+
+/*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
+
+/*P2_CORRELMANT*/
+#define R0900_P2_CORRELMANT  0xf220
+#define F0900_P2_CORREL_MANT  0xf22000ff
+
+/*P2_CORRELABS*/
+#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
+
+/*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
+
+/*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_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
+
+/*P2_AGC2REF*/
+#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
+
+/*P2_AGC2I1*/
+#define R0900_P2_AGC2I1  0xf236
+#define F0900_P2_AGC2_INTEGRATOR1  0xf23600ff
+
+/*P2_AGC2I0*/
+#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
+
+/*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
+
+/*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
+
+/*P2_CARFREQ*/
+#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
+
+/*P2_LDT*/
+#define R0900_P2_LDT  0xf23f
+#define F0900_P2_CARLOCK_THRES  0xf23f01ff
+
+/*P2_LDT2*/
+#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
+
+/*P2_CFRUP1*/
+#define R0900_P2_CFRUP1  0xf242
+#define F0900_P2_CFR_UP1  0xf24201ff
+
+/*P2_CFRUP0*/
+#define R0900_P2_CFRUP0  0xf243
+#define F0900_P2_CFR_UP0  0xf24300ff
+
+/*P2_CFRLOW1*/
+#define R0900_P2_CFRLOW1  0xf246
+#define F0900_P2_CFR_LOW1  0xf24601ff
+
+/*P2_CFRLOW0*/
+#define R0900_P2_CFRLOW0  0xf247
+#define F0900_P2_CFR_LOW0  0xf24700ff
+
+/*P2_CFRINIT1*/
+#define R0900_P2_CFRINIT1  0xf248
+#define F0900_P2_CFR_INIT1  0xf24801ff
+
+/*P2_CFRINIT0*/
+#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
+
+/*P2_CFRINC0*/
+#define R0900_P2_CFRINC0  0xf24b
+#define F0900_P2_CFR_INC0  0xf24b00f0
+
+/*P2_CFR2*/
+#define R0900_P2_CFR2  0xf24c
+#define F0900_P2_CAR_FREQ2  0xf24c01ff
+
+/*P2_CFR1*/
+#define R0900_P2_CFR1  0xf24d
+#define F0900_P2_CAR_FREQ1  0xf24d00ff
+
+/*P2_CFR0*/
+#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
+
+/*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
+
+/*P2_RTC*/
+#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
+
+/*P2_TMGTHRISE*/
+#define R0900_P2_TMGTHRISE  0xf253
+#define F0900_P2_TMGLOCK_THRISE  0xf25300ff
+
+/*P2_TMGTHFALL*/
+#define R0900_P2_TMGTHFALL  0xf254
+#define F0900_P2_TMGLOCK_THFALL  0xf25400ff
+
+/*P2_SFRUPRATIO*/
+#define R0900_P2_SFRUPRATIO  0xf255
+#define F0900_P2_SFR_UPRATIO  0xf25500ff
+
+/*P2_SFRLOWRATIO*/
+#define R0900_P2_SFRLOWRATIO  0xf256
+#define F0900_P2_SFR_LOWRATIO  0xf25600ff
+
+/*P2_KREFTMG*/
+#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
+
+/*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
+
+/*P2_SFRINIT1*/
+#define R0900_P2_SFRINIT1  0xf25e
+#define F0900_P2_SFR_INIT1  0xf25e00ff
+
+/*P2_SFRINIT0*/
+#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
+
+/*P2_SFRUP0*/
+#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
+
+/*P2_SFRLOW0*/
+#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
+
+/*P2_SFR2*/
+#define R0900_P2_SFR2  0xf265
+#define F0900_P2_SYMB_FREQ2  0xf26500ff
+
+/*P2_SFR1*/
+#define R0900_P2_SFR1  0xf266
+#define F0900_P2_SYMB_FREQ1  0xf26600ff
+
+/*P2_SFR0*/
+#define R0900_P2_SFR0  0xf267
+#define F0900_P2_SYMB_FREQ0  0xf26700ff
+
+/*P2_TMGREG2*/
+#define R0900_P2_TMGREG2  0xf268
+#define F0900_P2_TMGREG2  0xf26800ff
+
+/*P2_TMGREG1*/
+#define R0900_P2_TMGREG1  0xf269
+#define F0900_P2_TMGREG1  0xf26900ff
+
+/*P2_TMGREG0*/
+#define R0900_P2_TMGREG0  0xf26a
+#define F0900_P2_TMGREG0  0xf26a00ff
+
+/*P2_TMGLOCK1*/
+#define R0900_P2_TMGLOCK1  0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1  0xf26b01ff
+
+/*P2_TMGLOCK0*/
+#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
+
+/*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
+
+/*P2_EQUAI1*/
+#define R0900_P2_EQUAI1  0xf270
+#define F0900_P2_EQUA_ACCI1  0xf27001ff
+
+/*P2_EQUAQ1*/
+#define R0900_P2_EQUAQ1  0xf271
+#define F0900_P2_EQUA_ACCQ1  0xf27101ff
+
+/*P2_EQUAI2*/
+#define R0900_P2_EQUAI2  0xf272
+#define F0900_P2_EQUA_ACCI2  0xf27201ff
+
+/*P2_EQUAQ2*/
+#define R0900_P2_EQUAQ2  0xf273
+#define F0900_P2_EQUA_ACCQ2  0xf27301ff
+
+/*P2_EQUAI3*/
+#define R0900_P2_EQUAI3  0xf274
+#define F0900_P2_EQUA_ACCI3  0xf27401ff
+
+/*P2_EQUAQ3*/
+#define R0900_P2_EQUAQ3  0xf275
+#define F0900_P2_EQUA_ACCQ3  0xf27501ff
+
+/*P2_EQUAI4*/
+#define R0900_P2_EQUAI4  0xf276
+#define F0900_P2_EQUA_ACCI4  0xf27601ff
+
+/*P2_EQUAQ4*/
+#define R0900_P2_EQUAQ4  0xf277
+#define F0900_P2_EQUA_ACCQ4  0xf27701ff
+
+/*P2_EQUAI5*/
+#define R0900_P2_EQUAI5  0xf278
+#define F0900_P2_EQUA_ACCI5  0xf27801ff
+
+/*P2_EQUAQ5*/
+#define R0900_P2_EQUAQ5  0xf279
+#define F0900_P2_EQUA_ACCQ5  0xf27901ff
+
+/*P2_EQUAI6*/
+#define R0900_P2_EQUAI6  0xf27a
+#define F0900_P2_EQUA_ACCI6  0xf27a01ff
+
+/*P2_EQUAQ6*/
+#define R0900_P2_EQUAQ6  0xf27b
+#define F0900_P2_EQUA_ACCQ6  0xf27b01ff
+
+/*P2_EQUAI7*/
+#define R0900_P2_EQUAI7  0xf27c
+#define F0900_P2_EQUA_ACCI7  0xf27c01ff
+
+/*P2_EQUAQ7*/
+#define R0900_P2_EQUAQ7  0xf27d
+#define F0900_P2_EQUA_ACCQ7  0xf27d01ff
+
+/*P2_EQUAI8*/
+#define R0900_P2_EQUAI8  0xf27e
+#define F0900_P2_EQUA_ACCI8  0xf27e01ff
+
+/*P2_EQUAQ8*/
+#define R0900_P2_EQUAQ8  0xf27f
+#define F0900_P2_EQUA_ACCQ8  0xf27f01ff
+
+/*P2_NNOSDATAT1*/
+#define R0900_P2_NNOSDATAT1  0xf280
+#define F0900_P2_NOSDATAT_NORMED1  0xf28000ff
+
+/*P2_NNOSDATAT0*/
+#define R0900_P2_NNOSDATAT0  0xf281
+#define F0900_P2_NOSDATAT_NORMED0  0xf28100ff
+
+/*P2_NNOSDATA1*/
+#define R0900_P2_NNOSDATA1  0xf282
+#define F0900_P2_NOSDATA_NORMED1  0xf28200ff
+
+/*P2_NNOSDATA0*/
+#define R0900_P2_NNOSDATA0  0xf283
+#define F0900_P2_NOSDATA_NORMED0  0xf28300ff
+
+/*P2_NNOSPLHT1*/
+#define R0900_P2_NNOSPLHT1  0xf284
+#define F0900_P2_NOSPLHT_NORMED1  0xf28400ff
+
+/*P2_NNOSPLHT0*/
+#define R0900_P2_NNOSPLHT0  0xf285
+#define F0900_P2_NOSPLHT_NORMED0  0xf28500ff
+
+/*P2_NNOSPLH1*/
+#define R0900_P2_NNOSPLH1  0xf286
+#define F0900_P2_NOSPLH_NORMED1  0xf28600ff
+
+/*P2_NNOSPLH0*/
+#define R0900_P2_NNOSPLH0  0xf287
+#define F0900_P2_NOSPLH_NORMED0  0xf28700ff
+
+/*P2_NOSDATAT1*/
+#define R0900_P2_NOSDATAT1  0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1  0xf28800ff
+
+/*P2_NOSDATAT0*/
+#define R0900_P2_NOSDATAT0  0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0  0xf28900ff
+
+/*P2_NOSDATA1*/
+#define R0900_P2_NOSDATA1  0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1  0xf28a00ff
+
+/*P2_NOSDATA0*/
+#define R0900_P2_NOSDATA0  0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0  0xf28b00ff
+
+/*P2_NOSPLHT1*/
+#define R0900_P2_NOSPLHT1  0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1  0xf28c00ff
+
+/*P2_NOSPLHT0*/
+#define R0900_P2_NOSPLHT0  0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0  0xf28d00ff
+
+/*P2_NOSPLH1*/
+#define R0900_P2_NOSPLH1  0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1  0xf28e00ff
+
+/*P2_NOSPLH0*/
+#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
+
+/*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_CFR22*/
+#define R0900_P2_CFR22  0xf293
+#define F0900_P2_CAR2_FREQ2  0xf29301ff
+
+/*P2_CFR21*/
+#define R0900_P2_CFR21  0xf294
+#define F0900_P2_CAR2_FREQ1  0xf29400ff
+
+/*P2_CFR20*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_PLROOT1*/
+#define R0900_P2_PLROOT1  0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1  0xf2ad00ff
+
+/*P2_PLROOT0*/
+#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
+
+/*P2_MODCODLST1*/
+#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
+
+/*P2_MODCODLST3*/
+#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
+
+/*P2_MODCODLST5*/
+#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
+
+/*P2_MODCODLST7*/
+#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
+
+/*P2_MODCODLST9*/
+#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
+
+/*P2_MODCODLSTB*/
+#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
+
+/*P2_MODCODLSTD*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_DMDRESDATA7*/
+#define R0900_P2_DMDRESDATA7  0xf2c8
+#define F0900_P2_DMDRES_DATA7  0xf2c800ff
+
+/*P2_DMDRESDATA6*/
+#define R0900_P2_DMDRESDATA6  0xf2c9
+#define F0900_P2_DMDRES_DATA6  0xf2c900ff
+
+/*P2_DMDRESDATA5*/
+#define R0900_P2_DMDRESDATA5  0xf2ca
+#define F0900_P2_DMDRES_DATA5  0xf2ca00ff
+
+/*P2_DMDRESDATA4*/
+#define R0900_P2_DMDRESDATA4  0xf2cb
+#define F0900_P2_DMDRES_DATA4  0xf2cb00ff
+
+/*P2_DMDRESDATA3*/
+#define R0900_P2_DMDRESDATA3  0xf2cc
+#define F0900_P2_DMDRES_DATA3  0xf2cc00ff
+
+/*P2_DMDRESDATA2*/
+#define R0900_P2_DMDRESDATA2  0xf2cd
+#define F0900_P2_DMDRES_DATA2  0xf2cd00ff
+
+/*P2_DMDRESDATA1*/
+#define R0900_P2_DMDRESDATA1  0xf2ce
+#define F0900_P2_DMDRES_DATA1  0xf2ce00ff
+
+/*P2_DMDRESDATA0*/
+#define R0900_P2_DMDRESDATA0  0xf2cf
+#define F0900_P2_DMDRES_DATA0  0xf2cf00ff
+
+/*P2_FFEI1*/
+#define R0900_P2_FFEI1  0xf2d0
+#define F0900_P2_FFE_ACCI1  0xf2d001ff
+
+/*P2_FFEQ1*/
+#define R0900_P2_FFEQ1  0xf2d1
+#define F0900_P2_FFE_ACCQ1  0xf2d101ff
+
+/*P2_FFEI2*/
+#define R0900_P2_FFEI2  0xf2d2
+#define F0900_P2_FFE_ACCI2  0xf2d201ff
+
+/*P2_FFEQ2*/
+#define R0900_P2_FFEQ2  0xf2d3
+#define F0900_P2_FFE_ACCQ2  0xf2d301ff
+
+/*P2_FFEI3*/
+#define R0900_P2_FFEI3  0xf2d4
+#define F0900_P2_FFE_ACCI3  0xf2d401ff
+
+/*P2_FFEQ3*/
+#define R0900_P2_FFEQ3  0xf2d5
+#define F0900_P2_FFE_ACCQ3  0xf2d501ff
+
+/*P2_FFEI4*/
+#define R0900_P2_FFEI4  0xf2d6
+#define F0900_P2_FFE_ACCI4  0xf2d601ff
+
+/*P2_FFEQ4*/
+#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
+
+/*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
+
+/*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
+
+/*P2_TNRXTAL*/
+#define R0900_P2_TNRXTAL  0xf2e4
+#define F0900_P2_TUN_MCLKDECIMAL  0xf2e400e0
+#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
+
+/*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
+
+/*P2_TNRRF1*/
+#define R0900_P2_TNRRF1  0xf2e9
+#define F0900_P2_TUN_RFFREQ2  0xf2e900ff
+
+/*P2_TNRRF0*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_TNRLAUNCH*/
+#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
+
+/*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
+
+/*P2_TNRRESTE*/
+#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
+
+/*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
+
+/*P2_SMAPCOEF5*/
+#define R0900_P2_SMAPCOEF5  0xf302
+#define F0900_P2_DIS_8SCALE  0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23  0xf302017f
+
+/*P2_DMDPLHSTAT*/
+#define R0900_P2_DMDPLHSTAT  0xf320
+#define F0900_P2_PLH_STATISTIC  0xf32000ff
+
+/*P2_LOCKTIME3*/
+#define R0900_P2_LOCKTIME3  0xf322
+#define F0900_P2_DEMOD_LOCKTIME3  0xf32200ff
+
+/*P2_LOCKTIME2*/
+#define R0900_P2_LOCKTIME2  0xf323
+#define F0900_P2_DEMOD_LOCKTIME2  0xf32300ff
+
+/*P2_LOCKTIME1*/
+#define R0900_P2_LOCKTIME1  0xf324
+#define F0900_P2_DEMOD_LOCKTIME1  0xf32400ff
+
+/*P2_LOCKTIME0*/
+#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
+
+/*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
+
+/*P2_VTH12*/
+#define R0900_P2_VTH12  0xf334
+#define F0900_P2_VTH12  0xf33400ff
+
+/*P2_VTH23*/
+#define R0900_P2_VTH23  0xf335
+#define F0900_P2_VTH23  0xf33500ff
+
+/*P2_VTH34*/
+#define R0900_P2_VTH34  0xf336
+#define F0900_P2_VTH34  0xf33600ff
+
+/*P2_VTH56*/
+#define R0900_P2_VTH56  0xf337
+#define F0900_P2_VTH56  0xf33700ff
+
+/*P2_VTH67*/
+#define R0900_P2_VTH67  0xf338
+#define F0900_P2_VTH67  0xf33800ff
+
+/*P2_VTH78*/
+#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
+
+/*P2_VERROR*/
+#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
+
+/*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
+
+/*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
+
+/*P2_VTHINUSE*/
+#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
+
+/*P2_KDIV23*/
+#define R0900_P2_KDIV23  0xf341
+#define F0900_P2_KDIV23_MANUAL  0xf3410080
+#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
+
+/*P2_KDIV56*/
+#define R0900_P2_KDIV56  0xf343
+#define F0900_P2_KDIV56_MANUAL  0xf3430080
+#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
+
+/*P2_KDIV78*/
+#define R0900_P2_KDIV78  0xf345
+#define F0900_P2_KDIV78_MANUAL  0xf3450080
+#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
+
+/*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
+
+/*P2_HYSTTHRESH*/
+#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
+
+/*P2_ISIBITENA*/
+#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
+
+/*P2_MATSTR0*/
+#define R0900_P2_MATSTR0  0xf361
+#define F0900_P2_MATYPE_CURRENT0  0xf36100ff
+
+/*P2_UPLSTR1*/
+#define R0900_P2_UPLSTR1  0xf362
+#define F0900_P2_UPL_CURRENT1  0xf36200ff
+
+/*P2_UPLSTR0*/
+#define R0900_P2_UPLSTR0  0xf363
+#define F0900_P2_UPL_CURRENT0  0xf36300ff
+
+/*P2_DFLSTR1*/
+#define R0900_P2_DFLSTR1  0xf364
+#define F0900_P2_DFL_CURRENT1  0xf36400ff
+
+/*P2_DFLSTR0*/
+#define R0900_P2_DFLSTR0  0xf365
+#define F0900_P2_DFL_CURRENT0  0xf36500ff
+
+/*P2_SYNCSTR*/
+#define R0900_P2_SYNCSTR  0xf366
+#define F0900_P2_SYNC_CURRENT  0xf36600ff
+
+/*P2_SYNCDSTR1*/
+#define R0900_P2_SYNCDSTR1  0xf367
+#define F0900_P2_SYNCD_CURRENT1  0xf36700ff
+
+/*P2_SYNCDSTR0*/
+#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
+
+/*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
+
+/*P2_BBFCRCKO1*/
+#define R0900_P2_BBFCRCKO1  0xf36b
+#define F0900_P2_BBHCRC_KOCNT1  0xf36b00ff
+
+/*P2_BBFCRCKO0*/
+#define R0900_P2_BBFCRCKO0  0xf36c
+#define F0900_P2_BBHCRC_KOCNT0  0xf36c00ff
+
+/*P2_UPCRCKO1*/
+#define R0900_P2_UPCRCKO1  0xf36d
+#define F0900_P2_PKTCRC_KOCNT1  0xf36d00ff
+
+/*P2_UPCRCKO0*/
+#define R0900_P2_UPCRCKO0  0xf36e
+#define F0900_P2_PKTCRC_KOCNT0  0xf36e00ff
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_TSSPEED*/
+#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
+
+/*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
+
+/*P2_TSBITRATE1*/
+#define R0900_P2_TSBITRATE1  0xf383
+#define F0900_P2_TSFIFO_BITRATE1  0xf38300ff
+
+/*P2_TSBITRATE0*/
+#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
+
+/*P2_ERRCNT12*/
+#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
+
+/*P2_ERRCNT10*/
+#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
+
+/*P2_ERRCNT22*/
+#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
+
+/*P2_ERRCNT20*/
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P2_FBERCPT4*/
+#define R0900_P2_FBERCPT4  0xf3a8
+#define F0900_P2_FBERMETER_CPT4  0xf3a800ff
+
+/*P2_FBERCPT3*/
+#define R0900_P2_FBERCPT3  0xf3a9
+#define F0900_P2_FBERMETER_CPT3  0xf3a900ff
+
+/*P2_FBERCPT2*/
+#define R0900_P2_FBERCPT2  0xf3aa
+#define F0900_P2_FBERMETER_CPT2  0xf3aa00ff
+
+/*P2_FBERCPT1*/
+#define R0900_P2_FBERCPT1  0xf3ab
+#define F0900_P2_FBERMETER_CPT1  0xf3ab00ff
+
+/*P2_FBERCPT0*/
+#define R0900_P2_FBERCPT0  0xf3ac
+#define F0900_P2_FBERMETER_CPT0  0xf3ac00ff
+
+/*P2_FBERERR2*/
+#define R0900_P2_FBERERR2  0xf3ad
+#define F0900_P2_FBERMETER_ERR2  0xf3ad00ff
+
+/*P2_FBERERR1*/
+#define R0900_P2_FBERERR1  0xf3ae
+#define F0900_P2_FBERMETER_ERR1  0xf3ae00ff
+
+/*P2_FBERERR0*/
+#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
+
+/*P1_IQCONST*/
+#define R0900_P1_IQCONST  0xf400
+#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
+
+/*P1_ISYMB*/
+#define R0900_P1_ISYMB  0xf402
+#define F0900_P1_I_SYMBOL  0xf40201ff
+
+/*P1_QSYMB*/
+#define R0900_P1_QSYMB  0xf403
+#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
+
+/*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
+
+/*P1_AGC1REF*/
+#define R0900_P1_AGC1REF  0xf407
+#define F0900_P1_AGCIQ_REF  0xf40700ff
+
+/*P1_IDCCOMP*/
+#define R0900_P1_IDCCOMP  0xf408
+#define F0900_P1_IAVERAGE_ADJ  0xf40801ff
+
+/*P1_QDCCOMP*/
+#define R0900_P1_QDCCOMP  0xf409
+#define F0900_P1_QAVERAGE_ADJ  0xf40901ff
+
+/*P1_POWERI*/
+#define R0900_P1_POWERI  0xf40a
+#define F0900_P1_POWER_I  0xf40a00ff
+
+/*P1_POWERQ*/
+#define R0900_P1_POWERQ  0xf40b
+#define F0900_P1_POWER_Q  0xf40b00ff
+
+/*P1_AGC1AMM*/
+#define R0900_P1_AGC1AMM  0xf40c
+#define F0900_P1_AMM_VALUE  0xf40c00ff
+
+/*P1_AGC1QUAD*/
+#define R0900_P1_AGC1QUAD  0xf40d
+#define F0900_P1_QUAD_VALUE  0xf40d01ff
+
+/*P1_AGCIQIN1*/
+#define R0900_P1_AGCIQIN1  0xf40e
+#define F0900_P1_AGCIQ_VALUE1  0xf40e00ff
+
+/*P1_AGCIQIN0*/
+#define R0900_P1_AGCIQIN0  0xf40f
+#define F0900_P1_AGCIQ_VALUE0  0xf40f00ff
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_DMDT0M*/
+#define R0900_P1_DMDT0M  0xf417
+#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
+
+/*P1_DMDFLYW*/
+#define R0900_P1_DMDFLYW  0xf41c
+#define F0900_P1_I2C_IRQVAL  0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT  0xf41c000f
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_CORRELMANT*/
+#define R0900_P1_CORRELMANT  0xf420
+#define F0900_P1_CORREL_MANT  0xf42000ff
+
+/*P1_CORRELABS*/
+#define R0900_P1_CORRELABS  0xf421
+#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
+
+/*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
+
+/*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_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
+
+/*P1_AGC2REF*/
+#define R0900_P1_AGC2REF  0xf42d
+#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
+
+/*P1_AGC2I1*/
+#define R0900_P1_AGC2I1  0xf436
+#define F0900_P1_AGC2_INTEGRATOR1  0xf43600ff
+
+/*P1_AGC2I0*/
+#define R0900_P1_AGC2I0  0xf437
+#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
+
+/*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
+
+/*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
+
+/*P1_CARFREQ*/
+#define R0900_P1_CARFREQ  0xf43d
+#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
+
+/*P1_LDT*/
+#define R0900_P1_LDT  0xf43f
+#define F0900_P1_CARLOCK_THRES  0xf43f01ff
+
+/*P1_LDT2*/
+#define R0900_P1_LDT2  0xf440
+#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
+
+/*P1_CFRUP1*/
+#define R0900_P1_CFRUP1  0xf442
+#define F0900_P1_CFR_UP1  0xf44201ff
+
+/*P1_CFRUP0*/
+#define R0900_P1_CFRUP0  0xf443
+#define F0900_P1_CFR_UP0  0xf44300ff
+
+/*P1_CFRLOW1*/
+#define R0900_P1_CFRLOW1  0xf446
+#define F0900_P1_CFR_LOW1  0xf44601ff
+
+/*P1_CFRLOW0*/
+#define R0900_P1_CFRLOW0  0xf447
+#define F0900_P1_CFR_LOW0  0xf44700ff
+
+/*P1_CFRINIT1*/
+#define R0900_P1_CFRINIT1  0xf448
+#define F0900_P1_CFR_INIT1  0xf44801ff
+
+/*P1_CFRINIT0*/
+#define R0900_P1_CFRINIT0  0xf449
+#define F0900_P1_CFR_INIT0  0xf44900ff
+
+/*P1_CFRINC1*/
+#define R0900_P1_CFRINC1  0xf44a
+#define F0900_P1_MANUAL_CFRINC  0xf44a0080
+#define F0900_P1_CFR_INC1  0xf44a017f
+
+/*P1_CFRINC0*/
+#define R0900_P1_CFRINC0  0xf44b
+#define F0900_P1_CFR_INC0  0xf44b00f0
+
+/*P1_CFR2*/
+#define R0900_P1_CFR2  0xf44c
+#define F0900_P1_CAR_FREQ2  0xf44c01ff
+
+/*P1_CFR1*/
+#define R0900_P1_CFR1  0xf44d
+#define F0900_P1_CAR_FREQ1  0xf44d00ff
+
+/*P1_CFR0*/
+#define R0900_P1_CFR0  0xf44e
+#define F0900_P1_CAR_FREQ0  0xf44e00ff
+
+/*P1_LDI*/
+#define R0900_P1_LDI  0xf44f
+#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
+
+/*P1_RTC*/
+#define R0900_P1_RTC  0xf451
+#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
+
+/*P1_TMGTHRISE*/
+#define R0900_P1_TMGTHRISE  0xf453
+#define F0900_P1_TMGLOCK_THRISE  0xf45300ff
+
+/*P1_TMGTHFALL*/
+#define R0900_P1_TMGTHFALL  0xf454
+#define F0900_P1_TMGLOCK_THFALL  0xf45400ff
+
+/*P1_SFRUPRATIO*/
+#define R0900_P1_SFRUPRATIO  0xf455
+#define F0900_P1_SFR_UPRATIO  0xf45500ff
+
+/*P1_SFRLOWRATIO*/
+#define R0900_P1_SFRLOWRATIO  0xf456
+#define F0900_P1_SFR_LOWRATIO  0xf45600ff
+
+/*P1_KREFTMG*/
+#define R0900_P1_KREFTMG  0xf458
+#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
+
+/*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
+
+/*P1_SFRINIT1*/
+#define R0900_P1_SFRINIT1  0xf45e
+#define F0900_P1_SFR_INIT1  0xf45e00ff
+
+/*P1_SFRINIT0*/
+#define R0900_P1_SFRINIT0  0xf45f
+#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
+
+/*P1_SFRUP0*/
+#define R0900_P1_SFRUP0  0xf461
+#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
+
+/*P1_SFRLOW0*/
+#define R0900_P1_SFRLOW0  0xf463
+#define F0900_P1_SYMB_FREQ_LOW0  0xf46300ff
+
+/*P1_SFR3*/
+#define R0900_P1_SFR3  0xf464
+#define F0900_P1_SYMB_FREQ3  0xf46400ff
+
+/*P1_SFR2*/
+#define R0900_P1_SFR2  0xf465
+#define F0900_P1_SYMB_FREQ2  0xf46500ff
+
+/*P1_SFR1*/
+#define R0900_P1_SFR1  0xf466
+#define F0900_P1_SYMB_FREQ1  0xf46600ff
+
+/*P1_SFR0*/
+#define R0900_P1_SFR0  0xf467
+#define F0900_P1_SYMB_FREQ0  0xf46700ff
+
+/*P1_TMGREG2*/
+#define R0900_P1_TMGREG2  0xf468
+#define F0900_P1_TMGREG2  0xf46800ff
+
+/*P1_TMGREG1*/
+#define R0900_P1_TMGREG1  0xf469
+#define F0900_P1_TMGREG1  0xf46900ff
+
+/*P1_TMGREG0*/
+#define R0900_P1_TMGREG0  0xf46a
+#define F0900_P1_TMGREG0  0xf46a00ff
+
+/*P1_TMGLOCK1*/
+#define R0900_P1_TMGLOCK1  0xf46b
+#define F0900_P1_TMGLOCK_LEVEL1  0xf46b01ff
+
+/*P1_TMGLOCK0*/
+#define R0900_P1_TMGLOCK0  0xf46c
+#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
+
+/*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
+
+/*P1_EQUAI1*/
+#define R0900_P1_EQUAI1  0xf470
+#define F0900_P1_EQUA_ACCI1  0xf47001ff
+
+/*P1_EQUAQ1*/
+#define R0900_P1_EQUAQ1  0xf471
+#define F0900_P1_EQUA_ACCQ1  0xf47101ff
+
+/*P1_EQUAI2*/
+#define R0900_P1_EQUAI2  0xf472
+#define F0900_P1_EQUA_ACCI2  0xf47201ff
+
+/*P1_EQUAQ2*/
+#define R0900_P1_EQUAQ2  0xf473
+#define F0900_P1_EQUA_ACCQ2  0xf47301ff
+
+/*P1_EQUAI3*/
+#define R0900_P1_EQUAI3  0xf474
+#define F0900_P1_EQUA_ACCI3  0xf47401ff
+
+/*P1_EQUAQ3*/
+#define R0900_P1_EQUAQ3  0xf475
+#define F0900_P1_EQUA_ACCQ3  0xf47501ff
+
+/*P1_EQUAI4*/
+#define R0900_P1_EQUAI4  0xf476
+#define F0900_P1_EQUA_ACCI4  0xf47601ff
+
+/*P1_EQUAQ4*/
+#define R0900_P1_EQUAQ4  0xf477
+#define F0900_P1_EQUA_ACCQ4  0xf47701ff
+
+/*P1_EQUAI5*/
+#define R0900_P1_EQUAI5  0xf478
+#define F0900_P1_EQUA_ACCI5  0xf47801ff
+
+/*P1_EQUAQ5*/
+#define R0900_P1_EQUAQ5  0xf479
+#define F0900_P1_EQUA_ACCQ5  0xf47901ff
+
+/*P1_EQUAI6*/
+#define R0900_P1_EQUAI6  0xf47a
+#define F0900_P1_EQUA_ACCI6  0xf47a01ff
+
+/*P1_EQUAQ6*/
+#define R0900_P1_EQUAQ6  0xf47b
+#define F0900_P1_EQUA_ACCQ6  0xf47b01ff
+
+/*P1_EQUAI7*/
+#define R0900_P1_EQUAI7  0xf47c
+#define F0900_P1_EQUA_ACCI7  0xf47c01ff
+
+/*P1_EQUAQ7*/
+#define R0900_P1_EQUAQ7  0xf47d
+#define F0900_P1_EQUA_ACCQ7  0xf47d01ff
+
+/*P1_EQUAI8*/
+#define R0900_P1_EQUAI8  0xf47e
+#define F0900_P1_EQUA_ACCI8  0xf47e01ff
+
+/*P1_EQUAQ8*/
+#define R0900_P1_EQUAQ8  0xf47f
+#define F0900_P1_EQUA_ACCQ8  0xf47f01ff
+
+/*P1_NNOSDATAT1*/
+#define R0900_P1_NNOSDATAT1  0xf480
+#define F0900_P1_NOSDATAT_NORMED1  0xf48000ff
+
+/*P1_NNOSDATAT0*/
+#define R0900_P1_NNOSDATAT0  0xf481
+#define F0900_P1_NOSDATAT_NORMED0  0xf48100ff
+
+/*P1_NNOSDATA1*/
+#define R0900_P1_NNOSDATA1  0xf482
+#define F0900_P1_NOSDATA_NORMED1  0xf48200ff
+
+/*P1_NNOSDATA0*/
+#define R0900_P1_NNOSDATA0  0xf483
+#define F0900_P1_NOSDATA_NORMED0  0xf48300ff
+
+/*P1_NNOSPLHT1*/
+#define R0900_P1_NNOSPLHT1  0xf484
+#define F0900_P1_NOSPLHT_NORMED1  0xf48400ff
+
+/*P1_NNOSPLHT0*/
+#define R0900_P1_NNOSPLHT0  0xf485
+#define F0900_P1_NOSPLHT_NORMED0  0xf48500ff
+
+/*P1_NNOSPLH1*/
+#define R0900_P1_NNOSPLH1  0xf486
+#define F0900_P1_NOSPLH_NORMED1  0xf48600ff
+
+/*P1_NNOSPLH0*/
+#define R0900_P1_NNOSPLH0  0xf487
+#define F0900_P1_NOSPLH_NORMED0  0xf48700ff
+
+/*P1_NOSDATAT1*/
+#define R0900_P1_NOSDATAT1  0xf488
+#define F0900_P1_NOSDATAT_UNNORMED1  0xf48800ff
+
+/*P1_NOSDATAT0*/
+#define R0900_P1_NOSDATAT0  0xf489
+#define F0900_P1_NOSDATAT_UNNORMED0  0xf48900ff
+
+/*P1_NOSDATA1*/
+#define R0900_P1_NOSDATA1  0xf48a
+#define F0900_P1_NOSDATA_UNNORMED1  0xf48a00ff
+
+/*P1_NOSDATA0*/
+#define R0900_P1_NOSDATA0  0xf48b
+#define F0900_P1_NOSDATA_UNNORMED0  0xf48b00ff
+
+/*P1_NOSPLHT1*/
+#define R0900_P1_NOSPLHT1  0xf48c
+#define F0900_P1_NOSPLHT_UNNORMED1  0xf48c00ff
+
+/*P1_NOSPLHT0*/
+#define R0900_P1_NOSPLHT0  0xf48d
+#define F0900_P1_NOSPLHT_UNNORMED0  0xf48d00ff
+
+/*P1_NOSPLH1*/
+#define R0900_P1_NOSPLH1  0xf48e
+#define F0900_P1_NOSPLH_UNNORMED1  0xf48e00ff
+
+/*P1_NOSPLH0*/
+#define R0900_P1_NOSPLH0  0xf48f
+#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
+
+/*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_CFR22*/
+#define R0900_P1_CFR22  0xf493
+#define F0900_P1_CAR2_FREQ2  0xf49301ff
+
+/*P1_CFR21*/
+#define R0900_P1_CFR21  0xf494
+#define F0900_P1_CAR2_FREQ1  0xf49400ff
+
+/*P1_CFR20*/
+#define R0900_P1_CFR20  0xf495
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_PLROOT1*/
+#define R0900_P1_PLROOT1  0xf4ad
+#define F0900_P1_PLSCRAMB_ROOT1  0xf4ad00ff
+
+/*P1_PLROOT0*/
+#define R0900_P1_PLROOT0  0xf4ae
+#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
+
+/*P1_MODCODLST1*/
+#define R0900_P1_MODCODLST1  0xf4b1
+#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
+
+/*P1_MODCODLST3*/
+#define R0900_P1_MODCODLST3  0xf4b3
+#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
+
+/*P1_MODCODLST5*/
+#define R0900_P1_MODCODLST5  0xf4b5
+#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
+
+/*P1_MODCODLST7*/
+#define R0900_P1_MODCODLST7  0xf4b7
+#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
+
+/*P1_MODCODLST9*/
+#define R0900_P1_MODCODLST9  0xf4b9
+#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
+
+/*P1_MODCODLSTB*/
+#define R0900_P1_MODCODLSTB  0xf4bb
+#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
+
+/*P1_MODCODLSTD*/
+#define R0900_P1_MODCODLSTD  0xf4bd
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_DMDRESDATA7*/
+#define R0900_P1_DMDRESDATA7  0xf4c8
+#define F0900_P1_DMDRES_DATA7  0xf4c800ff
+
+/*P1_DMDRESDATA6*/
+#define R0900_P1_DMDRESDATA6  0xf4c9
+#define F0900_P1_DMDRES_DATA6  0xf4c900ff
+
+/*P1_DMDRESDATA5*/
+#define R0900_P1_DMDRESDATA5  0xf4ca
+#define F0900_P1_DMDRES_DATA5  0xf4ca00ff
+
+/*P1_DMDRESDATA4*/
+#define R0900_P1_DMDRESDATA4  0xf4cb
+#define F0900_P1_DMDRES_DATA4  0xf4cb00ff
+
+/*P1_DMDRESDATA3*/
+#define R0900_P1_DMDRESDATA3  0xf4cc
+#define F0900_P1_DMDRES_DATA3  0xf4cc00ff
+
+/*P1_DMDRESDATA2*/
+#define R0900_P1_DMDRESDATA2  0xf4cd
+#define F0900_P1_DMDRES_DATA2  0xf4cd00ff
+
+/*P1_DMDRESDATA1*/
+#define R0900_P1_DMDRESDATA1  0xf4ce
+#define F0900_P1_DMDRES_DATA1  0xf4ce00ff
+
+/*P1_DMDRESDATA0*/
+#define R0900_P1_DMDRESDATA0  0xf4cf
+#define F0900_P1_DMDRES_DATA0  0xf4cf00ff
+
+/*P1_FFEI1*/
+#define R0900_P1_FFEI1  0xf4d0
+#define F0900_P1_FFE_ACCI1  0xf4d001ff
+
+/*P1_FFEQ1*/
+#define R0900_P1_FFEQ1  0xf4d1
+#define F0900_P1_FFE_ACCQ1  0xf4d101ff
+
+/*P1_FFEI2*/
+#define R0900_P1_FFEI2  0xf4d2
+#define F0900_P1_FFE_ACCI2  0xf4d201ff
+
+/*P1_FFEQ2*/
+#define R0900_P1_FFEQ2  0xf4d3
+#define F0900_P1_FFE_ACCQ2  0xf4d301ff
+
+/*P1_FFEI3*/
+#define R0900_P1_FFEI3  0xf4d4
+#define F0900_P1_FFE_ACCI3  0xf4d401ff
+
+/*P1_FFEQ3*/
+#define R0900_P1_FFEQ3  0xf4d5
+#define F0900_P1_FFE_ACCQ3  0xf4d501ff
+
+/*P1_FFEI4*/
+#define R0900_P1_FFEI4  0xf4d6
+#define F0900_P1_FFE_ACCI4  0xf4d601ff
+
+/*P1_FFEQ4*/
+#define R0900_P1_FFEQ4  0xf4d7
+#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
+
+/*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
+
+/*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
+
+/*P1_TNRXTAL*/
+#define R0900_P1_TNRXTAL  0xf4e4
+#define F0900_P1_TUN_MCLKDECIMAL  0xf4e400e0
+#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
+
+/*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
+
+/*P1_TNRRF1*/
+#define R0900_P1_TNRRF1  0xf4e9
+#define F0900_P1_TUN_RFFREQ2  0xf4e900ff
+
+/*P1_TNRRF0*/
+#define R0900_P1_TNRRF0  0xf4ea
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_TNRLAUNCH*/
+#define R0900_P1_TNRLAUNCH  0xf4f0
+
+/*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
+
+/*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
+
+/*P1_TNRRESTE*/
+#define R0900_P1_TNRRESTE  0xf4f7
+#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
+
+/*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
+
+/*P1_SMAPCOEF5*/
+#define R0900_P1_SMAPCOEF5  0xf502
+#define F0900_P1_DIS_8SCALE  0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23  0xf502017f
+
+/*P1_DMDPLHSTAT*/
+#define R0900_P1_DMDPLHSTAT  0xf520
+#define F0900_P1_PLH_STATISTIC  0xf52000ff
+
+/*P1_LOCKTIME3*/
+#define R0900_P1_LOCKTIME3  0xf522
+#define F0900_P1_DEMOD_LOCKTIME3  0xf52200ff
+
+/*P1_LOCKTIME2*/
+#define R0900_P1_LOCKTIME2  0xf523
+#define F0900_P1_DEMOD_LOCKTIME2  0xf52300ff
+
+/*P1_LOCKTIME1*/
+#define R0900_P1_LOCKTIME1  0xf524
+#define F0900_P1_DEMOD_LOCKTIME1  0xf52400ff
+
+/*P1_LOCKTIME0*/
+#define R0900_P1_LOCKTIME0  0xf525
+#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
+
+/*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
+
+/*P1_VTH12*/
+#define R0900_P1_VTH12  0xf534
+#define F0900_P1_VTH12  0xf53400ff
+
+/*P1_VTH23*/
+#define R0900_P1_VTH23  0xf535
+#define F0900_P1_VTH23  0xf53500ff
+
+/*P1_VTH34*/
+#define R0900_P1_VTH34  0xf536
+#define F0900_P1_VTH34  0xf53600ff
+
+/*P1_VTH56*/
+#define R0900_P1_VTH56  0xf537
+#define F0900_P1_VTH56  0xf53700ff
+
+/*P1_VTH67*/
+#define R0900_P1_VTH67  0xf538
+#define F0900_P1_VTH67  0xf53800ff
+
+/*P1_VTH78*/
+#define R0900_P1_VTH78  0xf539
+#define F0900_P1_VTH78  0xf53900ff
+
+/*P1_VITCURPUN*/
+#define R0900_P1_VITCURPUN  0xf53a
+#define F0900_P1_VIT_MAPPING  0xf53a00e0
+#define F0900_P1_VIT_CURPUN  0xf53a001f
+
+/*P1_VERROR*/
+#define R0900_P1_VERROR  0xf53b
+#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
+
+/*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
+
+/*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
+
+/*P1_VTHINUSE*/
+#define R0900_P1_VTHINUSE  0xf53f
+#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
+
+/*P1_KDIV23*/
+#define R0900_P1_KDIV23  0xf541
+#define F0900_P1_KDIV23_MANUAL  0xf5410080
+#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
+
+/*P1_KDIV56*/
+#define R0900_P1_KDIV56  0xf543
+#define F0900_P1_KDIV56_MANUAL  0xf5430080
+#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
+
+/*P1_KDIV78*/
+#define R0900_P1_KDIV78  0xf545
+#define F0900_P1_KDIV78_MANUAL  0xf5450080
+#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
+
+/*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
+
+/*P1_HYSTTHRESH*/
+#define R0900_P1_HYSTTHRESH  0xf554
+#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
+
+/*P1_ISIBITENA*/
+#define R0900_P1_ISIBITENA  0xf55f
+#define F0900_P1_ISI_BIT_EN  0xf55f00ff
+
+/*P1_MATSTR1*/
+#define R0900_P1_MATSTR1  0xf560
+#define F0900_P1_MATYPE_CURRENT1  0xf56000ff
+
+/*P1_MATSTR0*/
+#define R0900_P1_MATSTR0  0xf561
+#define F0900_P1_MATYPE_CURRENT0  0xf56100ff
+
+/*P1_UPLSTR1*/
+#define R0900_P1_UPLSTR1  0xf562
+#define F0900_P1_UPL_CURRENT1  0xf56200ff
+
+/*P1_UPLSTR0*/
+#define R0900_P1_UPLSTR0  0xf563
+#define F0900_P1_UPL_CURRENT0  0xf56300ff
+
+/*P1_DFLSTR1*/
+#define R0900_P1_DFLSTR1  0xf564
+#define F0900_P1_DFL_CURRENT1  0xf56400ff
+
+/*P1_DFLSTR0*/
+#define R0900_P1_DFLSTR0  0xf565
+#define F0900_P1_DFL_CURRENT0  0xf56500ff
+
+/*P1_SYNCSTR*/
+#define R0900_P1_SYNCSTR  0xf566
+#define F0900_P1_SYNC_CURRENT  0xf56600ff
+
+/*P1_SYNCDSTR1*/
+#define R0900_P1_SYNCDSTR1  0xf567
+#define F0900_P1_SYNCD_CURRENT1  0xf56700ff
+
+/*P1_SYNCDSTR0*/
+#define R0900_P1_SYNCDSTR0  0xf568
+#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
+
+/*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
+
+/*P1_BBFCRCKO1*/
+#define R0900_P1_BBFCRCKO1  0xf56b
+#define F0900_P1_BBHCRC_KOCNT1  0xf56b00ff
+
+/*P1_BBFCRCKO0*/
+#define R0900_P1_BBFCRCKO0  0xf56c
+#define F0900_P1_BBHCRC_KOCNT0  0xf56c00ff
+
+/*P1_UPCRCKO1*/
+#define R0900_P1_UPCRCKO1  0xf56d
+#define F0900_P1_PKTCRC_KOCNT1  0xf56d00ff
+
+/*P1_UPCRCKO0*/
+#define R0900_P1_UPCRCKO0  0xf56e
+#define F0900_P1_PKTCRC_KOCNT0  0xf56e00ff
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_TSSPEED*/
+#define R0900_P1_TSSPEED  0xf580
+#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
+
+/*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
+
+/*P1_TSBITRATE1*/
+#define R0900_P1_TSBITRATE1  0xf583
+#define F0900_P1_TSFIFO_BITRATE1  0xf58300ff
+
+/*P1_TSBITRATE0*/
+#define R0900_P1_TSBITRATE0  0xf584
+#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
+
+/*P1_ERRCNT12*/
+#define R0900_P1_ERRCNT12  0xf599
+#define F0900_P1_ERRCNT1_OLDVALUE  0xf5990080
+#define F0900_P1_ERR_CNT12  0xf599007f
+
+/*P1_ERRCNT11*/
+#define R0900_P1_ERRCNT11  0xf59a
+#define F0900_P1_ERR_CNT11  0xf59a00ff
+
+/*P1_ERRCNT10*/
+#define R0900_P1_ERRCNT10  0xf59b
+#define F0900_P1_ERR_CNT10  0xf59b00ff
+
+/*P1_ERRCTRL2*/
+#define R0900_P1_ERRCTRL2  0xf59c
+#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
+
+/*P1_ERRCNT21*/
+#define R0900_P1_ERRCNT21  0xf59e
+#define F0900_P1_ERR_CNT21  0xf59e00ff
+
+/*P1_ERRCNT20*/
+#define R0900_P1_ERRCNT20  0xf59f
+#define F0900_P1_ERR_CNT20  0xf59f00ff
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*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
+
+/*P1_FBERCPT4*/
+#define R0900_P1_FBERCPT4  0xf5a8
+#define F0900_P1_FBERMETER_CPT4  0xf5a800ff
+
+/*P1_FBERCPT3*/
+#define R0900_P1_FBERCPT3  0xf5a9
+#define F0900_P1_FBERMETER_CPT3  0xf5a900ff
+
+/*P1_FBERCPT2*/
+#define R0900_P1_FBERCPT2  0xf5aa
+#define F0900_P1_FBERMETER_CPT2  0xf5aa00ff
+
+/*P1_FBERCPT1*/
+#define R0900_P1_FBERCPT1  0xf5ab
+#define F0900_P1_FBERMETER_CPT1  0xf5ab00ff
+
+/*P1_FBERCPT0*/
+#define R0900_P1_FBERCPT0  0xf5ac
+#define F0900_P1_FBERMETER_CPT0  0xf5ac00ff
+
+/*P1_FBERERR2*/
+#define R0900_P1_FBERERR2  0xf5ad
+#define F0900_P1_FBERMETER_ERR2  0xf5ad00ff
+
+/*P1_FBERERR1*/
+#define R0900_P1_FBERERR1  0xf5ae
+#define F0900_P1_FBERMETER_ERR1  0xf5ae00ff
+
+/*P1_FBERERR0*/
+#define R0900_P1_FBERERR0  0xf5af
+#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
+
+/*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
+
+/*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
+
+/*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
+
+/*NBITER_NF4*/
+#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
+
+/*NBITER_NF6*/
+#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
+
+/*NBITER_NF8*/
+#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
+
+/*NBITER_NF10*/
+#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
+
+/*NBITER_NF12*/
+#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
+
+/*NBITER_NF14*/
+#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
+
+/*NBITER_NF16*/
+#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
+
+/*NBITERNOERR*/
+#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
+
+/*GAINLLR_NF5*/
+#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
+
+/*GAINLLR_NF7*/
+#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
+
+/*GAINLLR_NF9*/
+#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
+
+/*GAINLLR_NF11*/
+#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
+
+/*GAINLLR_NF13*/
+#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
+
+/*GAINLLR_NF15*/
+#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
+
+/*GAINLLR_NF17*/
+#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
+
+/*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
+
+/*LDPCERR1*/
+#define R0900_LDPCERR1  0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1  0xfa9600ff
+
+/*LDPCERR0*/
+#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
+
+/*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
+
+/*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
+
+/*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 STV0900_NBREGS		684
+#define STV0900_NBFIELDS		1702
+
+#endif
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_sw.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_sw.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv0900_sw.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2847 @@
+/*
+ * stv0900_sw.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+
+int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+					enum fe_stv0900_demod_num demod)
+{
+	s32 carr_offset,
+	agc2_integr,
+	max_carrier;
+
+	int no_signal;
+
+	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;
+	}
+
+	max_carrier += (max_carrier / 10);
+	max_carrier = 65536 * (max_carrier / 2);
+	max_carrier /= i_params->mclk / 1000;
+	if (max_carrier > 0x4000)
+		max_carrier = 0x4000;
+
+	if ((agc2_integr > 0x2000)
+			|| (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,
+				s32 *frequency_inc, s32 *sw_timeout,
+				s32 *steps,
+				enum fe_stv0900_demod_num demod)
+{
+	s32 timeout, freq_inc, max_steps, srate, max_carrier;
+
+	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;
+	}
+
+	max_carrier = 65536 * (max_carrier / 2);
+	max_carrier /= i_params->mclk / 1000;
+
+	if (max_carrier > 0x4000)
+		max_carrier = 0x4000;
+
+	freq_inc = srate;
+	freq_inc /= i_params->mclk >> 10;
+	freq_inc = freq_inc << 6;
+
+	switch (standard) {
+	case STV0900_SEARCH_DVBS1:
+	case STV0900_SEARCH_DSS:
+		freq_inc *= 3;
+		timeout = 20;
+		break;
+	case STV0900_SEARCH_DVBS2:
+		freq_inc *= 4;
+		timeout = 25;
+		break;
+	case STV0900_AUTO_SEARCH:
+	default:
+		freq_inc *= 3;
+		timeout = 25;
+		break;
+	}
+
+	freq_inc /= 100;
+
+	if ((freq_inc > max_carrier) || (freq_inc < 0))
+		freq_inc = max_carrier / 2;
+
+	timeout *= 27500;
+
+	if (srate > 0)
+		timeout /= srate / 1000;
+
+	if ((timeout > 100) || (timeout < 0))
+		timeout = 100;
+
+	max_steps = (max_carrier / freq_inc) + 1;
+
+	if ((max_steps > 100) || (max_steps < 0)) {
+		max_steps =  100;
+		freq_inc = max_carrier / max_steps;
+	}
+
+	*frequency_inc = freq_inc;
+	*sw_timeout = timeout;
+	*steps = max_steps;
+
+}
+
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+				s32 FreqIncr, s32 Timeout, int zigzag,
+				s32 MaxStep, enum fe_stv0900_demod_num demod)
+{
+	int	no_signal,
+		lock = FALSE;
+	s32	stepCpt,
+		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 = 65536 * (max_carrier / 2);
+	max_carrier /= i_params->mclk / 1000;
+
+	if (max_carrier > 0x4000)
+		max_carrier = 0x4000;
+
+	if (zigzag == TRUE)
+		freqOffset = 0;
+	else
+		freqOffset = -max_carrier + FreqIncr;
+
+	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);
+
+			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 (zigzag == TRUE) {
+			if (freqOffset >= 0)
+				freqOffset = -freqOffset - 2 * FreqIncr;
+			else
+				freqOffset = -freqOffset;
+		} else
+			freqOffset += + 2 * FreqIncr;
+
+		stepCpt++;
+		lock = stv0900_get_demod_lock(i_params, demod, Timeout);
+		no_signal = stv0900_check_signal_presence(i_params, demod);
+
+	} while ((lock == FALSE)
+			&& (no_signal == FALSE)
+			&& ((freqOffset - FreqIncr) <  max_carrier)
+			&& ((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;
+	}
+
+	return lock;
+}
+
+int stv0900_sw_algo(struct stv0900_internal *i_params,
+				enum fe_stv0900_demod_num demod)
+{
+	int lock = FALSE;
+
+	int no_signal,
+	zigzag;
+	s32 dvbs2_fly_wheel;
+
+	s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
+
+	stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+					&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);
+
+			stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+						0x89);
+
+			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(i_params, R0900_P1_DMDCFGMD,
+							0xc9);
+			zigzag = FALSE;
+			break;
+		}
+
+		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));
+
+		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);
+
+			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);
+			} else {
+				stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+						0xef);
+				stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+						0x68);
+			}
+
+			stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
+
+			zigzag = FALSE;
+			break;
+		}
+
+		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_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 ((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 (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);
+
+							stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+						}
+					}
+				}
+			}
+
+		} while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
+
+		break;
+	}
+
+	return lock;
+}
+
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+					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);
+
+	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));
+	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));
+
+	intval1 = (mclk) >> 16;
+	intval2 = (srate) >> 16;
+
+	rem1 = (mclk) % 0x10000;
+	rem2 = (srate) % 0x10000;
+	srate =	(intval1 * intval2) +
+		((intval1 * rem2) >> 16) +
+		((intval2 * rem1) >> 16);
+
+	return srate;
+}
+
+static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+					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,
+							srate, demod);
+
+	dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
+
+	if (srate > 60000000) {
+		symb = srate << 4;
+		symb /= (mclk >> 12);
+	} else if (srate > 6000000) {
+		symb = srate << 6;
+		symb /= (mclk >> 10);
+	} else {
+		symb = srate << 9;
+		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));
+}
+
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+					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) {
+		symb = srate << 4;
+		symb /= (mclk >> 12);
+	} else if (srate > 6000000) {
+		symb = srate << 6;
+		symb /= (mclk >> 10);
+	} else {
+		symb = srate << 9;
+		symb /= (mclk >> 7);
+	}
+
+	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));
+	} else {
+		stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
+		stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+	}
+}
+
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+					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;
+		symb /= (mclk >> 12);
+
+	} else if (srate > 6000000) {
+		symb = srate << 6;
+		symb /= (mclk >> 10);
+
+	} else {
+		symb = srate << 9;
+		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));
+}
+
+static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+					u32 srate,
+					enum fe_stv0900_demod_num demod)
+{
+	s32 tmgreg,
+	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 = ge2comp(timingoffset, 24);
+
+
+	if (timingoffset == 0)
+		timingoffset = 1;
+
+	timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
+	timingoffset /= 320;
+
+	return timingoffset;
+}
+
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+					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);
+
+	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);
+}
+
+static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
+{
+	u32 rolloff;
+
+	switch (ro) {
+	case STV0900_20:
+		rolloff = 20;
+		break;
+	case STV0900_25:
+		rolloff = 25;
+		break;
+	case STV0900_35:
+	default:
+		rolloff = 35;
+		break;
+	}
+
+	return srate  + (srate * rolloff) / 100;
+}
+
+static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+				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);
+		}
+
+		if (timingcpt >= 3)
+			timingLock = TRUE;
+
+		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++;
+
+			msleep(1);
+		}
+
+		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;
+	}
+
+	return	timingLock;
+}
+
+static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
+					s32 demod_timeout)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
+
+	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;
+	}
+
+	if (srate >= 10000000)
+		locktimeout = demod_timeout / 3;
+	else
+		locktimeout = demod_timeout / 2;
+
+	lock = stv0900_get_demod_lock(i_params, demod, 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;
+				}
+
+				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;
+
+			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;
+
+			current_step = 1;
+			direction = 1;
+			timeout = (demod_timeout / 3);
+			if (timeout > 1000)
+				timeout = 1000;
+
+			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);
+
+						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);
+						}
+
+						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;
+
+					while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+						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_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);
+						}
+
+						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;
+			}
+		}
+	}
+
+	return	lock;
+}
+
+static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
+					s32 srate,
+					enum fe_stv0900_search_algo algo)
+{
+	switch (algo) {
+	case STV0900_BLIND_SEARCH:
+		if (srate <= 1500000) {
+			(*demod_timeout) = 1500;
+			(*fec_timeout) = 400;
+		} else if (srate <= 5000000) {
+			(*demod_timeout) = 1000;
+			(*fec_timeout) = 300;
+		} else {
+			(*demod_timeout) = 700;
+			(*fec_timeout) = 100;
+		}
+
+		break;
+	case STV0900_COLD_START:
+	case STV0900_WARM_START:
+	default:
+		if (srate <= 1000000) {
+			(*demod_timeout) = 3000;
+			(*fec_timeout) = 1700;
+		} else if (srate <= 2000000) {
+			(*demod_timeout) = 2500;
+			(*fec_timeout) = 1100;
+		} else if (srate <= 5000000) {
+			(*demod_timeout) = 1000;
+			(*fec_timeout) = 550;
+		} else if (srate <= 10000000) {
+			(*demod_timeout) = 700;
+			(*fec_timeout) = 250;
+		} else if (srate <= 20000000) {
+			(*demod_timeout) = 400;
+			(*fec_timeout) = 130;
+		}
+
+		else {
+			(*demod_timeout) = 300;
+			(*fec_timeout) = 100;
+		}
+
+		break;
+
+	}
+
+	if (algo == STV0900_WARM_START)
+		(*demod_timeout) /= 2;
+}
+
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+					enum fe_stv0900_demod_num demod)
+{
+
+	s32 vth_reg;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+	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);
+}
+
+static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
+				   enum fe_stv0900_search_standard Standard,
+				   enum fe_stv0900_fec PunctureRate,
+				   enum fe_stv0900_demod_num demod)
+{
+
+	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) {
+	case STV0900_AUTO_SEARCH:
+		dprintk("Auto\n");
+		stv0900_write_reg(i_params, fecmReg, 0x10);
+		stv0900_write_reg(i_params, prvitReg, 0x3F);
+		break;
+	case STV0900_SEARCH_DVBS1:
+		dprintk("DVBS1\n");
+		stv0900_write_reg(i_params, fecmReg, 0x00);
+		switch (PunctureRate) {
+		case STV0900_FEC_UNKNOWN:
+		default:
+			stv0900_write_reg(i_params, prvitReg, 0x2F);
+			break;
+		case STV0900_FEC_1_2:
+			stv0900_write_reg(i_params, prvitReg, 0x01);
+			break;
+		case STV0900_FEC_2_3:
+			stv0900_write_reg(i_params, prvitReg, 0x02);
+			break;
+		case STV0900_FEC_3_4:
+			stv0900_write_reg(i_params, prvitReg, 0x04);
+			break;
+		case STV0900_FEC_5_6:
+			stv0900_write_reg(i_params, prvitReg, 0x08);
+			break;
+		case STV0900_FEC_7_8:
+			stv0900_write_reg(i_params, prvitReg, 0x20);
+			break;
+		}
+
+		break;
+	case STV0900_SEARCH_DSS:
+		dprintk("DSS\n");
+		stv0900_write_reg(i_params, fecmReg, 0x80);
+		switch (PunctureRate) {
+		case STV0900_FEC_UNKNOWN:
+		default:
+			stv0900_write_reg(i_params, prvitReg, 0x13);
+			break;
+		case STV0900_FEC_1_2:
+			stv0900_write_reg(i_params, prvitReg, 0x01);
+			break;
+		case STV0900_FEC_2_3:
+			stv0900_write_reg(i_params, prvitReg, 0x02);
+			break;
+		case STV0900_FEC_6_7:
+			stv0900_write_reg(i_params, prvitReg, 0x10);
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+	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_rolloff rolloff;
+	enum fe_stv0900_modcode foundModcod;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+	srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+	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);
+			}
+
+			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);
+				}
+
+				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);
+					}
+				}
+
+			} 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);
+
+				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);
+				}
+
+			}
+
+			if (i_params->chip_id <= 0x11) {
+				if (i_params->demod_mode != STV0900_SINGLE)
+					stv0900_activate_s2_modcode(i_params, demod);
+
+			}
+
+			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);
+			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 (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);
+			}
+		}
+
+		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 ((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++;
+				}
+			}
+
+		}
+
+		if (i_params->chip_id >= 0x20)
+			stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+
+		if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
+			stv0900_set_viterbi_tracq(i_params, demod);
+
+		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);
+				}
+			}
+
+			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;
+		}
+
+		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 (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 (i_params->chip_id < 0x20)
+			stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
+
+		if (i_params->chip_id == 0x10)
+			stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
+
+		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 ((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 ((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);
+			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 (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);
+
+		break;
+	}
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
+{
+	s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
+
+	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);
+
+	dmd_state = stv0900_get_bits(i_params, header_field);
+
+	while ((timer < time_out) && (lock == 0)) {
+		switch (dmd_state) {
+		case STV0900_SEARCH:
+		case STV0900_PLH_DETECTED:
+		default:
+			lock = 0;
+			break;
+		case STV0900_DVBS2_FOUND:
+			lock = stv0900_get_bits(i_params, pktdelin_field);
+			break;
+		case STV0900_DVBS_FOUND:
+			lock = stv0900_get_bits(i_params, lock_vit_field);
+			break;
+		}
+
+		if (lock == 0) {
+			msleep(10);
+			timer += 10;
+		}
+	}
+
+	if (lock)
+		dprintk("DEMOD FEC LOCK OK\n");
+	else
+		dprintk("DEMOD FEC LOCK FAIL\n");
+
+	return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
+				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__);
+
+	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);
+
+	lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
+
+	if (lock)
+		lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
+
+	if (lock) {
+		lock = 0;
+
+		dprintk(KERN_INFO "%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);
+			msleep(1);
+			timer++;
+		}
+	}
+
+	if (lock)
+		dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
+	else
+		dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
+
+	if (lock)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+						enum fe_stv0900_demod_num demod)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = 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);
+
+	if (stv0900_get_bits(i_params, state_field) == 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)
+			fnd_standard = STV0900_DSS_STANDARD;
+		else
+			fnd_standard = STV0900_DVBS1_STANDARD;
+	} else
+		fnd_standard = STV0900_UNKNOWN_STANDARD;
+
+	return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, 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);
+
+	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 = ge2comp(derot, 24);
+	intval1 = mclk >> 12;
+	intval2 = derot >> 12;
+	rem1 = mclk % 0x1000;
+	rem2 = derot % 0x1000;
+	derot = (intval1 * intval2) +
+		((intval1 * rem2) >> 12) +
+		((intval2 * rem1) >> 12);
+
+	return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+	struct dvb_frontend_ops	*frontend_ops = NULL;
+	struct dvb_tuner_ops *tuner_ops = NULL;
+	u32 frequency = 0;
+
+	if (&fe->ops)
+		frontend_ops = &fe->ops;
+
+	if (&frontend_ops->tuner_ops)
+		tuner_ops = &frontend_ops->tuner_ops;
+
+	if (tuner_ops->get_frequency) {
+		if ((tuner_ops->get_frequency(fe, &frequency)) < 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);
+
+	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;
+}
+
+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;
+	enum fe_stv0900_demod_num demod = state->demod;
+	enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
+	s32 offsetFreq,
+	srate_offset,
+	i = 0;
+
+	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;
+			}
+		}
+
+		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;
+		}
+
+		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;
+		}
+		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;
+		}
+
+		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 (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;
+		}
+
+		break;
+	}
+
+	return range;
+}
+
+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;
+	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);
+
+			if (i_params->dmd2_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_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_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 {
+				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;
+	}
+
+	return signal_type;
+}
+
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+					enum fe_stv0900_demod_num demod)
+{
+	u32 minagc2level = 0xffff,
+		agc2level,
+		init_freq, freq_step;
+
+	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;
+
+		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);
+
+			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;
+
+			for (j = 0; j < 10; j++)
+				agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+						| stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+			agc2level /= 10;
+
+			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;
+
+		if (nb_steps < 0)
+			nb_steps = 1;
+
+		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);
+
+			direction *= -1;
+
+			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);
+
+			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;
+
+			if (agc2level < minagc2level)
+				minagc2level = agc2level;
+		}
+		break;
+	}
+
+	return (u16)minagc2level;
+}
+
+static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = state->internal;
+	enum fe_stv0900_demod_num demod = state->demod;
+	int timingLock = FALSE;
+	s32 i, timingcpt = 0,
+		direction = 1,
+		nb_steps,
+		current_step = 0,
+		tuner_freq;
+
+	u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+
+	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);
+
+		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 (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
+			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);
+
+				stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+			}
+		}
+
+		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);
+
+		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);
+		}
+
+		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;
+
+
+		nb_steps = -1 + ((i_params->dmd2_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->dmd2_srch_range / 1000) / 10;
+		}
+
+		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 /= 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;
+
+				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);
+			}
+		}
+
+		if (timingLock == FALSE)
+			coarse_srate = 0;
+		else
+			coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+		break;
+	}
+
+	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;
+	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));
+
+				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));
+			}
+
+			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);
+
+		symb = 13 * (coarse_srate / 10);
+
+		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);
+
+			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);
+
+			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 = 10 * (coarse_srate / 13);
+				symb = (symb / 1000) * 65536;
+				symb /= (i_params->mclk / 1000);
+
+				stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+				stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+				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));
+
+				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));
+
+				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(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);
+		}
+
+		break;
+	}
+
+	return coarse_srate;
+}
+
+static int stv0900_blind_search_algo(struct dvb_frontend *fe)
+{
+	struct stv0900_state *state = fe->demodulator_priv;
+	struct stv0900_internal *i_params = 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;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	if (i_params->chip_id < 0x20) {
+		k_ref_tmg_max = 233;
+		k_ref_tmg_min = 143;
+	} else {
+		k_ref_tmg_max = 120;
+		k_ref_tmg_min = 30;
+	}
+
+	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 (i_params->chip_id < 0x20)
+				stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+			stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
+			stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+
+			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);
+			}
+
+			kref_tmg_reg = R0900_P2_KREFTMG;
+			break;
+		}
+
+		k_ref_tmg = k_ref_tmg_max;
+
+		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);
+
+				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;
+
+				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);
+
+						if (agc2_integr >= 0xff00)
+							agc2_overflow++;
+
+						dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
+
+						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);
+
+						if (agc2_integr >= 0xff00)
+							agc2_overflow++;
+
+						dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
+
+						if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+							fail_cpt++;
+					}
+					break;
+				}
+
+				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));
+	}
+
+	return lock;
+}
+
+static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+					enum fe_stv0900_demod_num demod)
+{
+	s32 vth_reg;
+
+	dprintk(KERN_INFO "%s\n", __func__);
+
+	dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+	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);
+}
+
+static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+					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;
+
+	switch (sstndrd) {
+	case STV0900_SEARCH_DVBS1:
+		dprintk("Search Standard = DVBS1\n");
+		break;
+	case STV0900_SEARCH_DSS:
+		dprintk("Search Standard = DSS\n");
+	case STV0900_SEARCH_DVBS2:
+		break;
+		dprintk("Search Standard = DVBS2\n");
+	case STV0900_AUTO_SEARCH:
+	default:
+		dprintk("Search Standard = AUTO\n");
+		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);
+
+			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);
+
+			} else
+				stv0900_activate_s2_modcode_single(i_params, demod);
+
+			if (i_params->dmd1_symbol_rate >= 2000000)
+				stv0900_set_viterbi_acq(i_params, demod);
+			else
+				stv0900_set_viterbi_tracq(i_params, demod);
+
+			stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, 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(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);
+
+			if (i_params->dmd2_symbol_rate >= 2000000)
+				stv0900_set_viterbi_acq(i_params, demod);
+			else
+				stv0900_set_viterbi_tracq(i_params, demod);
+
+			stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+
+			break;
+		}
+
+		break;
+	}
+}
+
+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;
+	enum fe_stv0900_demod_num demod = state->demod;
+
+	s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+
+	int lock = FALSE, low_sr = FALSE;
+
+	enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
+	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);
+
+		if (i_params->chip_id >= 0x20)
+			stv0900_write_reg(i_params, R0900_P1_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);
+
+		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_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+
+		stream_merger_field = F0900_P2_RST_HWARE;
+
+		stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+
+		if (i_params->chip_id >= 0x20)
+			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+		else
+			stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+
+		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
+
+		if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+			i_params->tuner2_bw = 2 * 36000000;
+
+			stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
+			stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+			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);
+
+			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);
+
+			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);
+
+			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_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+
+			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;
+
+		}
+
+		stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
+
+		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);
+
+		stv0900_set_search_standard(i_params, demod);
+
+		if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
+			stv0900_start_search(i_params, demod);
+		break;
+	}
+
+	if (i_params->chip_id == 0x12) {
+		stv0900_write_bits(i_params, stream_merger_field, 0);
+		msleep(3);
+		stv0900_write_bits(i_params, stream_merger_field, 1);
+		stv0900_write_bits(i_params, stream_merger_field, 0);
+	}
+
+	if (algo == STV0900_BLIND_SEARCH)
+		lock = stv0900_blind_search_algo(fe);
+	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);
+
+	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 (lock == TRUE)
+		signal_type = stv0900_get_signal_params(fe);
+
+	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)) {
+				msleep(20);
+				stv0900_write_bits(i_params, stream_merger_field, 0);
+			} else {
+				stv0900_write_bits(i_params, stream_merger_field, 0);
+				msleep(3);
+				stv0900_write_bits(i_params, stream_merger_field, 1);
+				stv0900_write_bits(i_params, stream_merger_field, 0);
+			}
+		} else if (i_params->chip_id == 0x20) {
+			stv0900_write_bits(i_params, stream_merger_field, 0);
+			msleep(3);
+			stv0900_write_bits(i_params, stream_merger_field, 1);
+			stv0900_write_bits(i_params, stream_merger_field, 0);
+		}
+
+		if (stv0900_wait_for_lock(i_params, 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;
+			}
+		} else {
+			lock = FALSE;
+			signal_type = STV0900_NODATA;
+			no_signal = stv0900_check_signal_presence(i_params, 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;
+			}
+		}
+	}
+
+	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;
+
+			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;
+		}
+	}
+
+	return signal_type;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv6110.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv6110.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv6110.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv6110.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,456 @@
+/*
+ * stv6110.c
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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/dvb/frontend.h>
+
+#include <linux/types.h>
+
+#include "stv6110.h"
+
+static int debug;
+
+struct stv6110_priv {
+	int i2c_address;
+	struct i2c_adapter *i2c;
+
+	u32 mclk;
+	u8 regs[8];
+};
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG args); \
+	} while (0)
+
+static s32 abssub(s32 a, s32 b)
+{
+	if (a > b)
+		return a - b;
+	else
+		return b - a;
+};
+
+static int stv6110_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
+							int start, int len)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	int rc;
+	u8 cmdbuf[len + 1];
+	struct i2c_msg msg = {
+		.addr	= priv->i2c_address,
+		.flags	= 0,
+		.buf	= cmdbuf,
+		.len	= len + 1
+	};
+
+	dprintk("%s\n", __func__);
+
+	if (start + len > 8)
+		return -EINVAL;
+
+	memcpy(&cmdbuf[1], buf, len);
+	cmdbuf[0] = start;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	rc = i2c_transfer(priv->i2c, &msg, 1);
+	if (rc != 1)
+		dprintk("%s: i2c error\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
+							int start, int len)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	int rc;
+	u8 reg[] = { start };
+	struct i2c_msg msg_wr = {
+		.addr	= priv->i2c_address,
+		.flags	= 0,
+		.buf	= reg,
+		.len	= 1,
+	};
+
+	struct i2c_msg msg_rd = {
+		.addr	= priv->i2c_address,
+		.flags	= I2C_M_RD,
+		.buf	= regs,
+		.len	= len,
+	};
+	/* write subaddr */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	rc = i2c_transfer(priv->i2c, &msg_wr, 1);
+	if (rc != 1)
+		dprintk("%s: i2c error\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+	/* read registers */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	rc = i2c_transfer(priv->i2c, &msg_rd, 1);
+	if (rc != 1)
+		dprintk("%s: i2c error\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	memcpy(&priv->regs[start], regs, len);
+
+	return 0;
+}
+
+static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+{
+	u8 buf[] = { 0 };
+	stv6110_read_regs(fe, buf, start, 1);
+
+	return buf[0];
+}
+
+static int stv6110_sleep(struct dvb_frontend *fe)
+{
+	u8 reg[] = { 0 };
+	stv6110_write_regs(fe, reg, 0, 1);
+
+	return 0;
+}
+
+static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
+{
+	u32 rlf;
+
+	switch (rolloff) {
+	case ROLLOFF_20:
+		rlf = 20;
+		break;
+	case ROLLOFF_25:
+		rlf = 25;
+		break;
+	default:
+		rlf = 35;
+		break;
+	}
+
+	return symbol_rate  + ((symbol_rate * rlf) / 100);
+}
+
+static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	u8 r8, ret = 0x04;
+	int i;
+
+	if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
+		r8 = 31;
+	else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
+		r8 = 0;
+	else /*if 5 < BW/2 < 36*/
+		r8 = (bandwidth / 2) / 1000000 - 5;
+
+	/* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
+	/* ctrl3, CF = r8 Set the LPF value */
+	priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
+	priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
+	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+	/* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
+	priv->regs[RSTV6110_STAT1] |= 0x02;
+	stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
+
+	i = 0;
+	/* Wait for CALRCSTRT == 0 */
+	while ((i < 10) && (ret != 0)) {
+		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
+		mdelay(1);	/* wait for LPF auto calibration */
+		i++;
+	}
+
+	/* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
+	priv->regs[RSTV6110_CTRL3] |= (1 << 6);
+	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+	return 0;
+}
+
+static int stv6110_init(struct dvb_frontend *fe)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+	memcpy(priv->regs, buf0, 8);
+	/* K = (Reference / 1000000) - 16 */
+	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+	priv->regs[RSTV6110_CTRL1] |=
+				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
+	msleep(1);
+	stv6110_set_bandwidth(fe, 72000000);
+
+	return 0;
+}
+
+static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	u32 nbsteps, divider, psd2, freq;
+	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+	stv6110_read_regs(fe, regs, 0, 8);
+	/*N*/
+	divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
+	divider += priv->regs[RSTV6110_TUNING1];
+
+	/*R*/
+	nbsteps  = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
+	/*p*/
+	psd2  = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
+
+	freq = divider * (priv->mclk / 1000);
+	freq /= (1 << (nbsteps + psd2));
+	freq /= 4;
+
+	*frequency = freq;
+
+	return 0;
+}
+
+static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	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;
+
+	dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
+						frequency, priv->mclk);
+
+	/* K = (Reference / 1000000) - 16 */
+	priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+	priv->regs[RSTV6110_CTRL1] |=
+				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+	/* BB_GAIN = db/2 */
+	if (fe->ops.set_property && fe->ops.get_property) {
+		srate = c->symbol_rate;
+		dprintk("%s: Get Frontend parameters: srate=%d\n",
+							__func__, srate);
+	} 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);
+
+	if (frequency <= 1023000) {
+		p = 1;
+		presc = 0;
+	} else if (frequency <= 1300000) {
+		p = 1;
+		presc = 1;
+	} else if (frequency <= 2046000) {
+		p = 0;
+		presc = 0;
+	} else {
+		p = 0;
+		presc = 1;
+	}
+	/* DIV4SEL = p*/
+	priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
+	priv->regs[RSTV6110_TUNING2] |= (p << 4);
+
+	/* PRESC32ON = presc */
+	priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
+	priv->regs[RSTV6110_TUNING2] |= (presc << 5);
+
+	p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
+	for (r_div = 0; r_div <= 3; r_div++) {
+		p_calc = (priv->mclk / 100000);
+		p_calc /= (1 << (r_div + 1));
+		if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
+			r_div_opt = r_div;
+
+		p_calc_opt = (priv->mclk / 100000);
+		p_calc_opt /= (1 << (r_div_opt + 1));
+	}
+
+	ref = priv->mclk / ((1 << (r_div_opt + 1))  * (1 << (p + 1)));
+	divider = (((frequency * 1000) + (ref >> 1)) / ref);
+
+	/* RDIV = r_div_opt */
+	priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
+	priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
+
+	/* NDIV_MSB = MSB(divider) */
+	priv->regs[RSTV6110_TUNING2] &= ~0x0f;
+	priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
+
+	/* NDIV_LSB, LSB(divider) */
+	priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
+
+	/* CALVCOSTRT = 1 VCO Auto Calibration */
+	priv->regs[RSTV6110_STAT1] |= 0x04;
+	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
+						RSTV6110_CTRL1, 8);
+
+	i = 0;
+	/* Wait for CALVCOSTRT == 0 */
+	while ((i < 10) && (ret != 0)) {
+		ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
+		msleep(1); /* wait for VCO auto calibration */
+		i++;
+	}
+
+	ret = stv6110_read_reg(fe, RSTV6110_STAT1);
+	stv6110_get_frequency(fe, &result_freq);
+
+	vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
+	dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
+						ret, result_freq, vco_freq);
+
+	return 0;
+}
+
+static int stv6110_set_params(struct dvb_frontend *fe,
+			      struct dvb_frontend_parameters *params)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
+
+	stv6110_set_frequency(fe, c->frequency);
+	stv6110_set_bandwidth(fe, bandwidth);
+
+	return 0;
+}
+
+static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct stv6110_priv *priv = fe->tuner_priv;
+	u8 r8 = 0;
+	u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+	stv6110_read_regs(fe, regs, 0, 8);
+
+	/* CF */
+	r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
+	*bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
+
+	return 0;
+}
+
+static struct dvb_tuner_ops stv6110_tuner_ops = {
+	.info = {
+		.name = "ST STV6110",
+		.frequency_min = 950000,
+		.frequency_max = 2150000,
+		.frequency_step = 1000,
+	},
+	.init = stv6110_init,
+	.release = stv6110_release,
+	.sleep = stv6110_sleep,
+	.set_params = stv6110_set_params,
+	.get_frequency = stv6110_get_frequency,
+	.set_frequency = stv6110_set_frequency,
+	.get_bandwidth = stv6110_get_bandwidth,
+	.set_bandwidth = stv6110_set_bandwidth,
+
+};
+
+struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+					const struct stv6110_config *config,
+					struct i2c_adapter *i2c)
+{
+	struct stv6110_priv *priv = NULL;
+	u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+	struct i2c_msg msg[] = {
+		{
+			.addr = config->i2c_address,
+			.flags = 0,
+			.buf = reg0,
+			.len = 9
+		}
+	};
+	int ret;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	ret = i2c_transfer(i2c, msg, 1);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	if (ret != 1)
+		return NULL;
+
+	priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return NULL;
+
+	priv->i2c_address = config->i2c_address;
+	priv->i2c = i2c;
+	priv->mclk = config->mclk;
+
+	memcpy(&priv->regs, &reg0[1], 8);
+
+	memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
+				sizeof(struct dvb_tuner_ops));
+	fe->tuner_priv = priv;
+	printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
+
+	return fe;
+}
+EXPORT_SYMBOL(stv6110_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV6110 driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv6110.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv6110.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/stv6110.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/stv6110.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * stv6110.h
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 __DVB_STV6110_H__
+#define __DVB_STV6110_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* registers */
+#define RSTV6110_CTRL1		0
+#define RSTV6110_CTRL2		1
+#define RSTV6110_TUNING1	2
+#define RSTV6110_TUNING2	3
+#define RSTV6110_CTRL3		4
+#define RSTV6110_STAT1		5
+#define RSTV6110_STAT2		6
+#define RSTV6110_STAT3		7
+
+struct stv6110_config {
+	u8 i2c_address;
+	u32 mclk;
+	int iq_wiring;
+};
+
+#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
+							&& defined(MODULE))
+extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+					const struct stv6110_config *config,
+					struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+					const struct stv6110_config *config,
+					struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/tda1004x.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/tda1004x.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/tda1004x.c	2013-05-03 18:01:21.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/tda1004x.c	2013-05-03 16:45:13.000000000 -0400
@@ -154,7 +154,7 @@ static int tda1004x_read_byte(struct tda
 	if (ret != 2) {
 		dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
 			ret);
-		return -1;
+		return -EINVAL;
 	}
 
 	dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
@@ -473,16 +473,18 @@ static void tda10046_init_plls(struct dv
 static int tda10046_fwupload(struct dvb_frontend* fe)
 {
 	struct tda1004x_state* state = fe->demodulator_priv;
-	int ret;
+	int ret, confc4;
 	const struct firmware *fw;
 
 	/* reset + wake up chip */
 	if (state->config->xtal_freq == TDA10046_XTAL_4M) {
-		tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+		confc4 = 0;
 	} else {
 		dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
-		tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+		confc4 = 0x80;
 	}
+	tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
 	tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
 	/* set GPIO 1 and 3 */
 	if (state->config->gpio_config != TDA10046_GPTRI) {
@@ -500,13 +502,29 @@ static int tda10046_fwupload(struct dvb_
 	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
 
+	/*
+	   For i2c normal work, we need to slow down the bus speed.
+	   However, the slow down breaks the eeprom firmware load.
+	   So, use normal speed for eeprom booting and then restore the
+	   i2c speed after that. Tested with MSI TV @nyware A/D board,
+	   that comes with firmware version 29 inside their eeprom.
+
+	   It should also be noticed that no other I2C transfer should
+	   be in course while booting from eeprom, otherwise, tda10046
+	   goes into an instable state. So, proper locking are needed
+	   at the i2c bus master.
+	 */
 	printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
-	tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+	tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
 	msleep(300);
-	/* don't re-upload unless necessary */
+	tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+	/* Checks if eeprom firmware went without troubles */
 	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
 
+	/* eeprom firmware didn't work. Load one manually. */
+
 	if (state->config->reject_firmware != NULL) {
 		/* request the firmware, this will block until someone uploads it */
 		printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10036.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10036.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10036.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10036.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,519 @@
+/**
+ * Driver for Zarlink zl10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **
+ * The data sheet for this tuner can be found at:
+ *    http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
+ *
+ * This one is working: (at my Avermedia DVB-S Pro)
+ * - zl10036 (40pin, FTA)
+ *
+ * A driver for zl10038 should be very similar.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "zl10036.h"
+
+static int zl10036_debug;
+#define dprintk(level, args...) \
+	do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
+	} while (0)
+
+#define deb_info(args...)  dprintk(0x01, args)
+#define deb_i2c(args...)  dprintk(0x02, args)
+
+struct zl10036_state {
+	struct i2c_adapter *i2c;
+	const struct zl10036_config *config;
+	u32 frequency;
+	u8 br, bf;
+};
+
+
+/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
+#define _XTAL 10111
+
+/* Some of the possible dividers:
+ *   64, (write 0x05 to reg), freq step size   158kHz
+ *   10, (write 0x0a to reg), freq step size 1.011kHz (used here)
+ *    5, (write 0x09 to reg), freq step size 2.022kHz
+ */
+
+#define _RDIV 10
+#define _RDIV_REG 0x0a
+#define _FR   (_XTAL/_RDIV)
+
+#define STATUS_POR 0x80 /* Power on Reset */
+#define STATUS_FL  0x40 /* Frequency & Phase Lock */
+
+/* read/write for zl10036 and zl10038 */
+
+static int zl10036_read_status_reg(struct zl10036_state *state)
+{
+	u8 status;
+	struct i2c_msg msg[1] = {
+		{ .addr = state->config->tuner_address, .flags = I2C_M_RD,
+		  .buf = &status, .len = sizeof(status) },
+	};
+
+	if (i2c_transfer(state->i2c, msg, 1) != 1) {
+		printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
+			__func__, state->config->tuner_address);
+		return -EIO;
+	}
+
+	deb_i2c("R(status): %02x  [FL=%d]\n", status,
+		(status & STATUS_FL) ? 1 : 0);
+	if (status & STATUS_POR)
+		deb_info("%s: Power-On-Reset bit enabled - "
+			"need to initialize the tuner\n", __func__);
+
+	return status;
+}
+
+static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
+{
+	struct i2c_msg msg[1] = {
+		{ .addr = state->config->tuner_address, .flags = 0,
+		  .buf = buf, .len = count },
+	};
+	u8 reg = 0;
+	int ret;
+
+	if (zl10036_debug & 0x02) {
+		/* every 8bit-value satisifes this!
+		 * so only check for debug log */
+		if ((buf[0] & 0x80) == 0x00)
+			reg = 2;
+		else if ((buf[0] & 0xc0) == 0x80)
+			reg = 4;
+		else if ((buf[0] & 0xf0) == 0xc0)
+			reg = 6;
+		else if ((buf[0] & 0xf0) == 0xd0)
+			reg = 8;
+		else if ((buf[0] & 0xf0) == 0xe0)
+			reg = 10;
+		else if ((buf[0] & 0xf0) == 0xf0)
+			reg = 12;
+
+		deb_i2c("W(%d):", reg);
+		{
+			int i;
+			for (i = 0; i < count; i++)
+				printk(KERN_CONT " %02x", buf[i]);
+			printk(KERN_CONT "\n");
+		}
+	}
+
+	ret = i2c_transfer(state->i2c, msg, 1);
+	if (ret != 1) {
+		printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int zl10036_release(struct dvb_frontend *fe)
+{
+	struct zl10036_state *state = fe->tuner_priv;
+
+	fe->tuner_priv = NULL;
+	kfree(state);
+
+	return 0;
+}
+
+static int zl10036_sleep(struct dvb_frontend *fe)
+{
+	struct zl10036_state *state = fe->tuner_priv;
+	u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
+	int ret;
+
+	deb_info("%s\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+	ret = zl10036_write(state, buf, sizeof(buf));
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	return ret;
+}
+
+/**
+ * register map of the ZL10036/ZL10038
+ *
+ * reg[default] content
+ *  2[0x00]:   0 | N14 | N13 | N12 | N11 | N10 |  N9 |  N8
+ *  3[0x00]:  N7 |  N6 |  N5 |  N4 |  N3 |  N2 |  N1 |  N0
+ *  4[0x80]:   1 |   0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
+ *  5[0x00]:  P0 |  C1 |  C0 |  R4 |  R3 |  R2 |  R1 |  R0
+ *  6[0xc0]:   1 |   1 |   0 |   0 | RSD |   0 |   0 |   0
+ *  7[0x20]:  P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 |   0
+ *  8[0xdb]:   1 |   1 |   0 |   1 |   0 |  CC |   1 |   1
+ *  9[0x30]: VSD |  V2 |  V1 |  V0 |  S3 |  S2 |  S1 |  S0
+ * 10[0xe1]:   1 |   1 |   1 |   0 |   0 | LS2 | LS1 | LS0
+ * 11[0xf5]:  WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
+ * 12[0xf0]:   1 |   1 |   1 |   1 |   0 |   0 |   0 |   0
+ * 13[0x28]:  PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR |  TL
+ */
+
+static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
+{
+	u8 buf[2];
+	u32 div, foffset;
+
+	div = (frequency + _FR/2) / _FR;
+	state->frequency = div * _FR;
+
+	foffset = frequency - state->frequency;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = (div >> 0) & 0xff;
+
+	deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
+		frequency, state->frequency, foffset, div);
+
+	return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
+{
+	/* fbw is measured in kHz */
+	u8 br, bf;
+	int ret;
+	u8 buf_bf[] = {
+		0xc0, 0x00, /*   6/7: rsd=0 bf=0 */
+	};
+	u8 buf_br[] = {
+		0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
+	};
+	u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
+
+	/* ensure correct values */
+	if (fbw > 35000)
+		fbw = 35000;
+	if (fbw <  8000)
+		fbw =  8000;
+
+#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
+
+	/* <= 28,82 MHz */
+	if (fbw <= 28820) {
+		br = _BR_MAXIMUM;
+	} else {
+		/**
+		 *  f(bw)=34,6MHz f(xtal)=10.111MHz
+		 *  br = (10111/34600) * 63 * 1/K = 14;
+		 */
+		br = ((_XTAL * 21 * 1000) / (fbw * 419));
+	}
+
+	/* ensure correct values */
+	if (br < 4)
+		br = 4;
+	if (br > _BR_MAXIMUM)
+		br = _BR_MAXIMUM;
+
+	/*
+	 * k = 1.257
+	 * bf = fbw/_XTAL * br * k - 1 */
+
+	bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
+
+	/* ensure correct values */
+	if (bf > 62)
+		bf = 62;
+
+	buf_bf[1] = (bf << 1) & 0x7e;
+	buf_br[1] = (br << 2) & 0x7c;
+	deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
+
+	if (br != state->br) {
+		ret = zl10036_write(state, buf_br, sizeof(buf_br));
+		if (ret < 0)
+			return ret;
+	}
+
+	if (bf != state->bf) {
+		ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
+		if (ret < 0)
+			return ret;
+
+		/* time = br/(32* fxtal) */
+		/* minimal sleep time to be calculated
+		 * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
+		msleep(1);
+
+		ret = zl10036_write(state, zl10036_rsd_off,
+			sizeof(zl10036_rsd_off));
+		if (ret < 0)
+			return ret;
+	}
+
+	state->br = br;
+	state->bf = bf;
+
+	return 0;
+}
+
+static int zl10036_set_gain_params(struct zl10036_state *state,
+	int c)
+{
+	u8 buf[2];
+	u8 rfg, ba, bg;
+
+	/* default values */
+	rfg = 0; /* enable when using an lna */
+	ba = 1;
+	bg = 1;
+
+	/* reg 4 */
+	buf[0] = 0x80 | ((rfg << 5) & 0x20)
+		| ((ba  << 3) & 0x18) | ((bg  << 1) & 0x06);
+
+	if (!state->config->rf_loop_enable)
+		buf[0] |= 0x01;
+
+	/* P0=0 */
+	buf[1] = _RDIV_REG | ((c << 5) & 0x60);
+
+	deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
+	return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_params(struct dvb_frontend *fe,
+		struct dvb_frontend_parameters *params)
+{
+	struct zl10036_state *state = fe->tuner_priv;
+	int ret = 0;
+	u32 frequency = params->frequency;
+	u32 fbw;
+	int i;
+	u8 c;
+
+	/* ensure correct values
+	 * maybe redundant as core already checks this */
+	if ((frequency < fe->ops.info.frequency_min)
+	||  (frequency > fe->ops.info.frequency_max))
+		return -EINVAL;
+
+	/**
+	 * alpha = 1.35 for dvb-s
+	 * fBW = (alpha*symbolrate)/(2*0.8)
+	 * 1.35 / (2*0.8) = 27 / 32
+	 */
+	fbw = (27 * params->u.qpsk.symbol_rate) / 32;
+
+	/* scale to kHz */
+	fbw /= 1000;
+
+	/* Add safe margin of 3MHz */
+	fbw += 3000;
+
+	/* setting the charge pump - guessed values */
+	if (frequency < 950000)
+		return -EINVAL;
+	else if (frequency < 1250000)
+		c = 0;
+	else if (frequency < 1750000)
+		c = 1;
+	else if (frequency < 2175000)
+		c = 2;
+	else
+		return -EINVAL;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+	ret = zl10036_set_gain_params(state, c);
+	if (ret < 0)
+		goto error;
+
+	ret = zl10036_set_frequency(state, params->frequency);
+	if (ret < 0)
+		goto error;
+
+	ret = zl10036_set_bandwidth(state, fbw);
+	if (ret < 0)
+		goto error;
+
+	/* wait for tuner lock - no idea if this is really needed */
+	for (i = 0; i < 20; i++) {
+		ret = zl10036_read_status_reg(state);
+		if (ret < 0)
+			goto error;
+
+		/* check Frequency & Phase Lock Bit */
+		if (ret & STATUS_FL)
+			break;
+
+		msleep(10);
+	}
+
+error:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	return ret;
+}
+
+static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct zl10036_state *state = fe->tuner_priv;
+
+	*frequency = state->frequency;
+
+	return 0;
+}
+
+static int zl10036_init_regs(struct zl10036_state *state)
+{
+	int ret;
+	int i;
+
+	/* could also be one block from reg 2 to 13 and additional 10/11 */
+	u8 zl10036_init_tab[][2] = {
+		{ 0x04, 0x00 },		/*   2/3: div=0x400 - arbitrary value */
+		{ 0x8b, _RDIV_REG },	/*   4/5: rfg=0 ba=1 bg=1 len=? */
+					/*        p0=0 c=0 r=_RDIV_REG */
+		{ 0xc0, 0x20 },		/*   6/7: rsd=0 bf=0x10 */
+		{ 0xd3, 0x40 },		/*   8/9: from datasheet */
+		{ 0xe3, 0x5b },		/* 10/11: lock window level */
+		{ 0xf0, 0x28 },		/* 12/13: br=0xa clr=0 tl=0*/
+		{ 0xe3, 0xf9 },		/* 10/11: unlock window level */
+	};
+
+	/* invalid values to trigger writing */
+	state->br = 0xff;
+	state->bf = 0xff;
+
+	if (!state->config->rf_loop_enable)
+		zl10036_init_tab[1][2] |= 0x01;
+
+	deb_info("%s\n", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
+		ret = zl10036_write(state, zl10036_init_tab[i], 2);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int zl10036_init(struct dvb_frontend *fe)
+{
+	struct zl10036_state *state = fe->tuner_priv;
+	int ret = 0;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+	ret = zl10036_read_status_reg(state);
+	if (ret < 0)
+		return ret;
+
+	/* Only init if Power-on-Reset bit is set? */
+	ret = zl10036_init_regs(state);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	return ret;
+}
+
+static struct dvb_tuner_ops zl10036_tuner_ops = {
+	.info = {
+		.name = "Zarlink ZL10036",
+		.frequency_min = 950000,
+		.frequency_max = 2175000
+	},
+	.init = zl10036_init,
+	.release = zl10036_release,
+	.sleep = zl10036_sleep,
+	.set_params = zl10036_set_params,
+	.get_frequency = zl10036_get_frequency,
+};
+
+struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+				    const struct zl10036_config *config,
+				    struct i2c_adapter *i2c)
+{
+	struct zl10036_state *state = NULL;
+	int ret;
+
+	if (NULL == config) {
+		printk(KERN_ERR "%s: no config specified", __func__);
+		goto error;
+	}
+
+	state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
+	if (NULL == state)
+		return NULL;
+
+	state->config = config;
+	state->i2c = i2c;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+	ret = zl10036_read_status_reg(state);
+	if (ret < 0) {
+		printk(KERN_ERR "%s: No zl10036 found\n", __func__);
+		goto error;
+	}
+
+	ret = zl10036_init_regs(state);
+	if (ret < 0) {
+		printk(KERN_ERR "%s: tuner initialization failed\n",
+			__func__);
+		goto error;
+	}
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+	fe->tuner_priv = state;
+
+	memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+	printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
+		__func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+	return fe;
+
+error:
+	zl10036_release(fe);
+	return NULL;
+}
+EXPORT_SYMBOL(zl10036_attach);
+
+module_param_named(debug, zl10036_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB ZL10036 driver");
+MODULE_AUTHOR("Tino Reichardt");
+MODULE_AUTHOR("Matthias Schwarzott");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10036.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10036.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10036.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10036.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,53 @@
+/**
+ * Driver for Zarlink ZL10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_ZL10036_H
+#define DVB_ZL10036_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config zl10036_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct zl10036_config {
+	u8 tuner_address;
+	int rf_loop_enable;
+};
+
+#if defined(CONFIG_DVB_ZL10036) || \
+	(defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
+extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+	const struct zl10036_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+	const struct zl10036_config *config, struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif /* DVB_ZL10036_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353.c linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353.c	2009-06-09 23:05:27.000000000 -0400
@@ -572,6 +572,10 @@ static int zl10353_init(struct dvb_front
 		zl10353_dump_regs(fe);
 	if (state->config.parallel_ts)
 		zl10353_reset_attach[2] &= ~0x20;
+	if (state->config.clock_ctl_1)
+		zl10353_reset_attach[3] = state->config.clock_ctl_1;
+	if (state->config.pll_0)
+		zl10353_reset_attach[4] = state->config.pll_0;
 
 	/* Do a "hard" reset if not already done */
 	if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
@@ -614,6 +618,7 @@ struct dvb_frontend *zl10353_attach(cons
 				    struct i2c_adapter *i2c)
 {
 	struct zl10353_state *state = NULL;
+	int id;
 
 	/* allocate memory for the internal state */
 	state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
@@ -625,7 +630,8 @@ struct dvb_frontend *zl10353_attach(cons
 	memcpy(&state->config, config, sizeof(struct zl10353_config));
 
 	/* check if the demod is there */
-	if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+	id = zl10353_read_register(state, CHIP_ID);
+	if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
 		goto error;
 
 	/* create dvb_frontend */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,10 @@ struct zl10353_config
 
 	/* set if i2c_gate_ctrl disable is required */
 	u8 disable_i2c_gate_ctrl:1;
+
+	/* clock control registers (0x51-0x54) */
+	u8 clock_ctl_1;  /* default: 0x46 */
+	u8 pll_0;        /* default: 0x15 */
 };
 
 #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353_priv.h linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/frontends/zl10353_priv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/zl10353_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,9 @@
 #ifndef _ZL10353_PRIV_
 #define _ZL10353_PRIV_
 
-#define ID_ZL10353	0x14
+#define ID_ZL10353	0x14 /* Zarlink ZL10353 */
+#define ID_CE6230	0x18 /* Intel CE6230 */
+#define ID_CE6231	0x19 /* Intel CE6231 */
 
 #define msb(x) (((x) >> 8) & 0xff)
 #define lsb(x) ((x) & 0xff)
@@ -50,6 +52,10 @@ enum zl10353_reg_addr {
 	TPS_RECEIVED_0     = 0x1E,
 	TPS_CURRENT_1      = 0x1F,
 	TPS_CURRENT_0      = 0x20,
+	CLOCK_CTL_0        = 0x51,
+	CLOCK_CTL_1        = 0x52,
+	PLL_0              = 0x53,
+	PLL_1              = 0x54,
 	RESET              = 0x55,
 	AGC_TARGET         = 0x56,
 	MCLK_RATIO         = 0x5C,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/pluto2/pluto2.c linux-libre-2.6.30-gnu1/drivers/media/dvb/pluto2/pluto2.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/pluto2/pluto2.c	2013-05-03 18:01:28.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/pluto2/pluto2.c	2013-05-03 16:45:18.000000000 -0400
@@ -116,6 +116,7 @@ struct pluto {
 
 	/* irq */
 	unsigned int overflow;
+	unsigned int dead;
 
 	/* dma */
 	dma_addr_t dma_addr;
@@ -336,8 +337,10 @@ static irqreturn_t pluto_irq(int irq, vo
 		return IRQ_NONE;
 
 	if (tscr == 0xffffffff) {
-		// FIXME: maybe recover somehow
-		dev_err(&pluto->pdev->dev, "card hung up :(\n");
+		if (pluto->dead == 0)
+			dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+		/* It's dead Jim */
+		pluto->dead = 1;
 		return IRQ_HANDLED;
 	}
 
@@ -613,7 +616,7 @@ static int __devinit pluto2_probe(struct
 	/* enable interrupts */
 	pci_write_config_dword(pdev, 0x6c, 0x8000);
 
-	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (ret < 0)
 		goto err_pci_disable_device;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/Makefile linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,8 @@
-sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
+sms1xxx-objs := smscoreapi.o sms-cards.o
 
 obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/sms-cards.c linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/sms-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 18:01:34.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/sms-cards.c	2013-05-03 16:45:24.000000000 -0400
@@ -19,50 +19,9 @@
 
 #include "sms-cards.h"
 
-struct usb_device_id smsusb_id_table[] = {
-#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
-	{ USB_DEVICE(0x187f, 0x0010),
-		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
-	{ USB_DEVICE(0x187f, 0x0100),
-		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
-	{ USB_DEVICE(0x187f, 0x0200),
-		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
-	{ USB_DEVICE(0x187f, 0x0201),
-		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
-	{ USB_DEVICE(0x187f, 0x0300),
-		.driver_info = SMS1XXX_BOARD_SIANO_VEGA },
-#endif
-	{ USB_DEVICE(0x2040, 0x1700),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
-	{ USB_DEVICE(0x2040, 0x1800),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
-	{ USB_DEVICE(0x2040, 0x1801),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
-	{ USB_DEVICE(0x2040, 0x2000),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-	{ USB_DEVICE(0x2040, 0x2009),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
-	{ USB_DEVICE(0x2040, 0x200a),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-	{ USB_DEVICE(0x2040, 0x2010),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-	{ USB_DEVICE(0x2040, 0x2019),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
-	{ USB_DEVICE(0x2040, 0x5500),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ USB_DEVICE(0x2040, 0x5510),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ USB_DEVICE(0x2040, 0x5520),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ USB_DEVICE(0x2040, 0x5530),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ USB_DEVICE(0x2040, 0x5580),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ USB_DEVICE(0x2040, 0x5590),
-		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
-	{ }		/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
 
 static struct sms_board sms_boards[] = {
 	[SMS_BOARD_UNKNOWN] = {
@@ -115,6 +74,7 @@ static struct sms_board sms_boards[] = {
 		.type	= SMS_NOVA_B0,
 		.fw[DEVICE_MODE_DVBT_BDA] = "/*(DEBLOBBED)*/",
 		.lna_ctrl  = 29,
+		.rf_switch = 17,
 	},
 	[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
 		.name	= "Hauppauge WinTV MiniCard",
@@ -130,6 +90,7 @@ struct sms_board *sms_get_board(int id)
 
 	return &sms_boards[id];
 }
+EXPORT_SYMBOL_GPL(sms_get_board);
 
 static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
 {
@@ -182,6 +143,7 @@ int sms_board_setup(struct smscore_devic
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(sms_board_setup);
 
 int sms_board_power(struct smscore_device_t *coredev, int onoff)
 {
@@ -197,12 +159,13 @@ int sms_board_power(struct smscore_devic
 	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
 	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
 		/* LNA */
-		sms_set_gpio(coredev,
-			     board->lna_ctrl, onoff ? 1 : 0);
+		if (!onoff)
+			sms_set_gpio(coredev, board->lna_ctrl, 0);
 		break;
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(sms_board_power);
 
 int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
 {
@@ -225,3 +188,40 @@ int sms_board_led_feedback(struct smscor
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+	int board_id = smscore_get_board_id(coredev);
+	struct sms_board *board = sms_get_board(board_id);
+
+	sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+	switch (board_id) {
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+		sms_set_gpio(coredev,
+			     board->rf_switch, onoff ? 1 : 0);
+		return sms_set_gpio(coredev,
+				    board->lna_ctrl, onoff ? 1 : 0);
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+	switch (id) {
+	case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+		request_module("smsdvb");
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/sms-cards.h linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/sms-cards.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/sms-cards.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/sms-cards.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,7 +40,7 @@ struct sms_board {
 	char *name, *fw[DEVICE_MODE_MAX];
 
 	/* gpios */
-	int led_power, led_hi, led_lo, lna_ctrl;
+	int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
 };
 
 struct sms_board *sms_get_board(int id);
@@ -52,7 +52,8 @@ int sms_board_setup(struct smscore_devic
 #define SMS_LED_HI  2
 int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
 int sms_board_power(struct smscore_device_t *coredev, int onoff);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
 
-extern struct usb_device_id smsusb_id_table[];
+extern int sms_board_load_modules(int id);
 
 #endif /* __SMS_CARDS_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smscoreapi.c linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smscoreapi.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 18:01:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smscoreapi.c	2013-05-03 16:45:20.000000000 -0400
@@ -3,7 +3,7 @@
  *
  *  This file contains implementation for the interface to sms core component
  *
- *  author: Anatoly Greenblat
+ *  author: Uri Shkolnik
  *
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
@@ -34,8 +34,8 @@
 #include "smscoreapi.h"
 #include "sms-cards.h"
 
-int sms_debug;
-module_param_named(debug, sms_debug, int, 0644);
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
 
 struct smscore_device_notifyee_t {
@@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_dev
 		core->led_state = led;
 	return core->led_state;
 }
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
 
 int smscore_get_board_id(struct smscore_device_t *core)
 {
 	return core->board_id;
 }
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
 
 struct smscore_registry_entry_t {
 	struct list_head entry;
@@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpa
 
 	return default_mode;
 }
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
 
 static enum sms_device_type_st smscore_registry_gettype(char *devpath)
 {
@@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t h
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
 
 /**
  * unregister a client callback that called when device plugged in/unplugged
@@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_
 
 	kmutex_unlock(&g_smscore_deviceslock);
 }
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
 
 static void smscore_notify_clients(struct smscore_device_t *coredev)
 {
@@ -432,6 +437,7 @@ int smscore_register_device(struct smsde
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(smscore_register_device);
 
 /**
  * sets initial device mode and notifies client hotplugs that device is ready
@@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(smscore_start_device);
 
 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
 					void *buffer, size_t size,
@@ -688,6 +695,7 @@ void smscore_unregister_device(struct sm
 
 	sms_info("device %p destroyed", coredev);
 }
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
 
 static int smscore_detect_mode(struct smscore_device_t *coredev)
 {
@@ -732,7 +740,7 @@ static char *smscore_fw_lkup[][SMS_NUM_O
 	/*DVBH*/
 	{"none", "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", "none"},
 	/*TDMB*/
-	{"none", "/*(DEBLOBBED)*/", "none", "none"},
+	{"none", "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", "none"},
 	/*DABIP*/
 	{"none", "none", "none", "none"},
 	/*BDA*/
@@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smsco
 {
 	return coredev->mode;
 }
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
 
 /**
  * find client by response id & type within the clients list.
@@ -1006,6 +1015,7 @@ void smscore_onresponse(struct smscore_d
 		smscore_putbuffer(coredev, cb);
 	}
 }
+EXPORT_SYMBOL_GPL(smscore_onresponse);
 
 /**
  * return pointer to next free buffer descriptor from core pool
@@ -1031,6 +1041,7 @@ struct smscore_buffer_t *smscore_getbuff
 
 	return cb;
 }
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
 
 /**
  * return buffer descriptor to a pool
@@ -1045,6 +1056,7 @@ void smscore_putbuffer(struct smscore_de
 {
 	list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
 }
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
 
 static int smscore_validate_client(struct smscore_device_t *coredev,
 				   struct smscore_client_t *client,
@@ -1124,6 +1136,7 @@ int smscore_register_client(struct smsco
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(smscore_register_client);
 
 /**
  * frees smsclient object and all subclients associated with it
@@ -1154,6 +1167,7 @@ void smscore_unregister_client(struct sm
 
 	spin_unlock_irqrestore(&coredev->clientslock, flags);
 }
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
 
 /**
  * verifies that source id is not taken by another client,
@@ -1193,6 +1207,7 @@ int smsclient_sendrequest(struct smscore
 
 	return coredev->sendrequest_handler(coredev->context, buffer, size);
 }
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
 
 
 int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
@@ -1276,12 +1291,12 @@ static int __init smscore_module_init(vo
 	INIT_LIST_HEAD(&g_smscore_registry);
 	kmutex_init(&g_smscore_registrylock);
 
-	/* USB Register */
-	rc = smsusb_register();
 
-	/* DVB Register */
-	rc = smsdvb_register();
 
+
+
+
+	return rc;
 	sms_debug("rc %d", rc);
 
 	return rc;
@@ -1290,6 +1305,10 @@ static int __init smscore_module_init(vo
 static void __exit smscore_module_exit(void)
 {
 
+
+
+
+
 	kmutex_lock(&g_smscore_deviceslock);
 	while (!list_empty(&g_smscore_notifyees)) {
 		struct smscore_device_notifyee_t *notifyee =
@@ -1312,18 +1331,12 @@ static void __exit smscore_module_exit(v
 	}
 	kmutex_unlock(&g_smscore_registrylock);
 
-	/* DVB UnRegister */
-	smsdvb_unregister();
-
-	/* Unregister USB */
-	smsusb_unregister();
-
 	sms_debug("");
 }
 
 module_init(smscore_module_init);
 module_exit(smscore_module_exit);
 
-MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
-MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smscoreapi.h linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smscoreapi.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smscoreapi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smscoreapi.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,13 +29,13 @@
 #include <linux/scatterlist.h>
 #include <linux/types.h>
 #include <asm/page.h>
+#include <linux/mutex.h>
 
 #include "dmxdev.h"
 #include "dvbdev.h"
 #include "dvb_demux.h"
 #include "dvb_frontend.h"
 
-#include <linux/mutex.h>
 
 #define kmutex_init(_p_) mutex_init(_p_)
 #define kmutex_lock(_p_) mutex_lock(_p_)
@@ -369,27 +369,6 @@ struct smscore_gpio_config {
 	u8 outputdriving;
 };
 
-struct smsdvb_client_t {
-	struct list_head entry;
-
-	struct smscore_device_t	*coredev;
-	struct smscore_client_t	*smsclient;
-
-	struct dvb_adapter	adapter;
-	struct dvb_demux	demux;
-	struct dmxdev		dmxdev;
-	struct dvb_frontend	frontend;
-
-	fe_status_t		fe_status;
-	int			fe_ber, fe_snr, fe_unc, fe_signal_strength;
-
-	struct completion	tune_done, stat_done;
-
-	/* todo: save freq/band instead whole struct */
-	struct dvb_frontend_parameters fe_params;
-
-};
-
 extern void smscore_registry_setmode(char *devpath, int mode);
 extern int smscore_registry_getmode(char *devpath);
 
@@ -418,6 +397,13 @@ extern int smsclient_sendrequest(struct
 extern void smscore_onresponse(struct smscore_device_t *coredev,
 			       struct smscore_buffer_t *cb);
 
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+				      struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+				   int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+				u8 *ufwbuf, int size);
 
 extern
 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
@@ -433,18 +419,9 @@ int smscore_get_board_id(struct smscore_
 
 int smscore_led_state(struct smscore_device_t *core, int led);
 
-/* smsdvb.c */
-int smsdvb_register(void);
-void smsdvb_unregister(void);
-
-/* smsusb.c */
-int smsusb_register(void);
-void smsusb_unregister(void);
 
 /* ------------------------------------------------------------------------ */
 
-extern int sms_debug;
-
 #define DBG_INFO 1
 #define DBG_ADV  2
 
@@ -452,7 +429,7 @@ extern int sms_debug;
 	printk(kern "%s: " fmt "\n", __func__, ##arg)
 
 #define dprintk(kern, lvl, fmt, arg...) do {\
-	if (sms_debug & lvl) \
+	if (sms_dbg & lvl) \
 		sms_printk(kern, fmt, ##arg); } while (0)
 
 #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smsdvb.c linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smsdvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smsdvb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smsdvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  Driver for the Siano SMS1xxx USB dongle
  *
- *  author: Anatoly Greenblat
+ *  Author: Uri Shkolni
  *
  *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  *
@@ -27,9 +27,33 @@
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
+struct smsdvb_client_t {
+	struct list_head entry;
+
+	struct smscore_device_t *coredev;
+	struct smscore_client_t *smsclient;
+
+	struct dvb_adapter      adapter;
+	struct dvb_demux        demux;
+	struct dmxdev           dmxdev;
+	struct dvb_frontend     frontend;
+
+	fe_status_t             fe_status;
+	int                     fe_ber, fe_snr, fe_unc, fe_signal_strength;
+
+	struct completion       tune_done, stat_done;
+
+	/* todo: save freq/band instead whole struct */
+	struct dvb_frontend_parameters fe_params;
+};
+
 static struct list_head g_smsdvb_clients;
 static struct mutex g_smsdvb_clientslock;
 
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
 static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 {
 	struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -262,6 +286,7 @@ static int smsdvb_set_frontend(struct dv
 		struct SmsMsgHdr_ST	Msg;
 		u32		Data[3];
 	} Msg;
+	int ret;
 
 	Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
 	Msg.Msg.msgDstId  = HIF_TASK;
@@ -282,6 +307,24 @@ static int smsdvb_set_frontend(struct dv
 	default: return -EINVAL;
 	}
 
+	/* Disable LNA, if any. An error is returned if no LNA is present */
+	ret = sms_board_lna_control(client->coredev, 0);
+	if (ret == 0) {
+		fe_status_t status;
+
+		/* tune with LNA off at first */
+		ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+						  &client->tune_done);
+
+		smsdvb_read_status(fe, &status);
+
+		if (status & FE_HAS_LOCK)
+			return ret;
+
+		/* previous tune didnt lock - enable LNA and tune again */
+		sms_board_lna_control(client->coredev, 1);
+	}
+
 	return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
 					   &client->tune_done);
 }
@@ -329,7 +372,7 @@ static void smsdvb_release(struct dvb_fr
 
 static struct dvb_frontend_ops smsdvb_fe_ops = {
 	.info = {
-		.name			= "Siano Mobile Digital SMS1xxx",
+		.name			= "Siano Mobile Digital MDTV Receiver",
 		.type			= FE_OFDM,
 		.frequency_min		= 44250000,
 		.frequency_max		= 867250000,
@@ -371,7 +414,7 @@ static int smsdvb_hotplug(struct smscore
 	if (!arrival)
 		return 0;
 
-	if (smscore_get_device_mode(coredev) != 4) {
+	if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
 		sms_err("SMS Device mode is not set for "
 			"DVB operation.");
 		return 0;
@@ -473,7 +516,7 @@ adapter_error:
 	return rc;
 }
 
-int smsdvb_register(void)
+int smsdvb_module_init(void)
 {
 	int rc;
 
@@ -487,7 +530,7 @@ int smsdvb_register(void)
 	return rc;
 }
 
-void smsdvb_unregister(void)
+void smsdvb_module_exit(void)
 {
 	smscore_unregister_hotplug(smsdvb_hotplug);
 
@@ -499,3 +542,10 @@ void smsdvb_unregister(void)
 
 	kmutex_unlock(&g_smsdvb_clientslock);
 }
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smsusb.c linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smsusb.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 18:01:32.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/siano/smsusb.c	2013-05-03 16:45:22.000000000 -0400
@@ -27,6 +27,10 @@
 #include "smscoreapi.h"
 #include "sms-cards.h"
 
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
 #define USB1_BUFFER_SIZE		0x1000
 #define USB2_BUFFER_SIZE		0x4000
 
@@ -424,6 +428,7 @@ static int smsusb_probe(struct usb_inter
 
 	rc = smsusb_init_device(intf, id->driver_info);
 	sms_info("rc %d", rc);
+	sms_board_load_modules(id->driver_info);
 	return rc;
 }
 
@@ -436,7 +441,7 @@ static int smsusb_suspend(struct usb_int
 {
 	struct smsusb_device_t *dev =
 		(struct smsusb_device_t *)usb_get_intfdata(intf);
-	printk(KERN_INFO "%s  Entering status %d.\n", __func__, msg.event);
+	printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
 	smsusb_stop_streaming(dev);
 	return 0;
 }
@@ -448,7 +453,7 @@ static int smsusb_resume(struct usb_inte
 		(struct smsusb_device_t *)usb_get_intfdata(intf);
 	struct usb_device *udev = interface_to_usbdev(intf);
 
-	printk(KERN_INFO "%s  Entering.\n", __func__);
+	printk(KERN_INFO "%s: Entering.\n", __func__);
 	usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
 	usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
 
@@ -463,9 +468,8 @@ static int smsusb_resume(struct usb_inte
 				       intf->cur_altsetting->desc.
 				       bInterfaceNumber, 0);
 		if (rc < 0) {
-			printk(KERN_INFO
-			       "%s usb_set_interface failed, rc %d\n",
-			       __func__, rc);
+			printk(KERN_INFO "%s usb_set_interface failed, "
+			       "rc %d\n", __func__, rc);
 			return rc;
 		}
 	}
@@ -474,8 +478,55 @@ static int smsusb_resume(struct usb_inte
 	return 0;
 }
 
+struct usb_device_id smsusb_id_table[] = {
+#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
+	{ USB_DEVICE(0x187f, 0x0010),
+		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+	{ USB_DEVICE(0x187f, 0x0100),
+		.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+	{ USB_DEVICE(0x187f, 0x0200),
+		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
+	{ USB_DEVICE(0x187f, 0x0201),
+		.driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
+	{ USB_DEVICE(0x187f, 0x0300),
+		.driver_info = SMS1XXX_BOARD_SIANO_VEGA },
+#endif
+	{ USB_DEVICE(0x2040, 0x1700),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
+	{ USB_DEVICE(0x2040, 0x1800),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
+	{ USB_DEVICE(0x2040, 0x1801),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
+	{ USB_DEVICE(0x2040, 0x2000),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+	{ USB_DEVICE(0x2040, 0x2009),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
+	{ USB_DEVICE(0x2040, 0x200a),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+	{ USB_DEVICE(0x2040, 0x2010),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+	{ USB_DEVICE(0x2040, 0x2011),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+	{ USB_DEVICE(0x2040, 0x2019),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+	{ USB_DEVICE(0x2040, 0x5500),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5510),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5520),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5530),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5580),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5590),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+
 static struct usb_driver smsusb_driver = {
-	.name			= "sms1xxx",
+	.name			= "smsusb",
 	.probe			= smsusb_probe,
 	.disconnect		= smsusb_disconnect,
 	.id_table		= smsusb_id_table,
@@ -484,7 +535,7 @@ static struct usb_driver smsusb_driver =
 	.resume			= smsusb_resume,
 };
 
-int smsusb_register(void)
+int smsusb_module_init(void)
 {
 	int rc = usb_register(&smsusb_driver);
 	if (rc)
@@ -495,10 +546,16 @@ int smsusb_register(void)
 	return rc;
 }
 
-void smsusb_unregister(void)
+void smsusb_module_exit(void)
 {
 	sms_debug("");
 	/* Regular USB Cleanup */
 	usb_deregister(&smsusb_driver);
 }
 
+module_init(smsusb_module_init);
+module_exit(smsusb_module_exit);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_av.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_av.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_av.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_av.c	2009-06-09 23:05:27.000000000 -0400
@@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inod
  * driver registration
  ******************************************************************************/
 
-static struct file_operations dvb_video_fops = {
+static const struct file_operations dvb_video_fops = {
 	.owner		= THIS_MODULE,
 	.write		= dvb_video_write,
 	.ioctl		= dvb_generic_ioctl,
@@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video =
 	.kernel_ioctl	= dvb_video_ioctl,
 };
 
-static struct file_operations dvb_audio_fops = {
+static const struct file_operations dvb_audio_fops = {
 	.owner		= THIS_MODULE,
 	.write		= dvb_audio_write,
 	.ioctl		= dvb_generic_ioctl,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 18:01:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110.c	2013-05-03 16:45:16.000000000 -0400
@@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *i
 }
 
 
-static struct file_operations dvb_osd_fops = {
+static const struct file_operations dvb_osd_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= dvb_generic_ioctl,
 	.open		= dvb_generic_open,
@@ -1518,20 +1518,6 @@ static int check_firmware(struct av7110*
 	return 0;
 }
 
-#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
-#include "av7110_firm.h"
-static void put_firmware(struct av7110* av7110)
-{
-	av7110->bin_fw = NULL;
-}
-
-static inline int get_firmware(struct av7110* av7110)
-{
-	av7110->bin_fw = dvb_ttpci_fw;
-	av7110->size_fw = sizeof(dvb_ttpci_fw);
-	return check_firmware(av7110);
-}
-#else
 static void put_firmware(struct av7110* av7110)
 {
 	vfree(av7110->bin_fw);
@@ -1580,8 +1566,6 @@ static int get_firmware(struct av7110* a
 	release_firmware(fw);
 	return ret;
 }
-#endif
-
 
 static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_ca.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_ca.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_ca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_ca.c	2009-06-09 23:05:27.000000000 -0400
@@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *
 	return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
 }
 
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
 	.owner		= THIS_MODULE,
 	.read		= dvb_ca_read,
 	.write		= dvb_ca_write,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_hw.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_hw.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_hw.c	2013-05-03 18:01:23.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,10 +198,10 @@ static int load_dram(struct av7110 *av71
 
 /* we cannot write av7110 DRAM directly, so load a bootloader into
  * the DPRAM which implements a simple boot protocol */
-/*(DEBLOBBED)*/
-
 int av7110_bootarm(struct av7110 *av7110)
 {
+	const struct firmware *fw;
+	const char *fw_name = "av7110/bootcode.bin";
 	struct saa7146_dev *dev = av7110->dev;
 	u32 ret;
 	int i;
@@ -236,16 +236,21 @@ int av7110_bootarm(struct av7110 *av7110
 		iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
 	dprintk(2, "debi test OK\n");
 
-	printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): Missing Free bootcode\n");
-	return -EINVAL;
-
 	/* boot */
 	dprintk(1, "load boot code\n");
 	saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
 	//saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
 	//saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
 
-	/* mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode)); */
+	ret = request_firmware(&fw, fw_name, &dev->pci->dev);
+	if (ret) {
+		printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
+			fw_name);
+		return ret;
+	}
+
+	mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
+	release_firmware(fw);
 	iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 
 	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
@@ -286,7 +291,7 @@ int av7110_bootarm(struct av7110 *av7110
 	av7110->arm_ready = 1;
 	return 0;
 }
-
+MODULE_FIRMWARE("av7110/bootcode.bin");
 
 /****************************************************************************
  * DEBI command polling
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_hw.h linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_hw.h
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -390,7 +390,8 @@ static inline void iwdebi(struct av7110
 }
 
 /* buffer writes */
-static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count)
+static inline void mwdebi(struct av7110 *av7110, u32 config, int addr,
+			  const u8 *val, int count)
 {
 	memcpy(av7110->debi_virt, val, count);
 	av7110_debiwrite(av7110, config, addr, 0, count);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_v4l.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_v4l.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/av7110_v4l.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/av7110_v4l.c	2009-06-09 23:05:27.000000000 -0400
@@ -316,253 +316,261 @@ static int av7110_dvb_c_switch(struct sa
 	return 0;
 }
 
-static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
 {
-	struct saa7146_dev *dev = fh->dev;
-	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
-	dprintk(4, "saa7146_dev: %p\n", dev);
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+	u16 stereo_det;
+	s8 stereo;
 
-	switch (cmd) {
-	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *t = arg;
-		u16 stereo_det;
-		s8 stereo;
+	dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
 
-		dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+	if (!av7110->analog_tuner_flags || t->index != 0)
+		return -EINVAL;
 
-		if (!av7110->analog_tuner_flags || t->index != 0)
-			return -EINVAL;
+	memset(t, 0, sizeof(*t));
+	strcpy((char *)t->name, "Television");
 
-		memset(t, 0, sizeof(*t));
-		strcpy((char *)t->name, "Television");
+	t->type = V4L2_TUNER_ANALOG_TV;
+	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+		V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+	t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+	t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
+	/* FIXME: add the real signal strength here */
+	t->signal = 0xffff;
+	t->afc = 0;
 
-		t->type = V4L2_TUNER_ANALOG_TV;
-		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
-			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-		t->rangelow = 772;	/* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
-		t->rangehigh = 13684;	/* 855.25 MHz / 62.5 kHz = 13684 */
-		/* FIXME: add the real signal strength here */
-		t->signal = 0xffff;
-		t->afc = 0;
+	/* FIXME: standard / stereo detection is still broken */
+	msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
+	dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+	msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
+	dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+	stereo = (s8)(stereo_det >> 8);
+	if (stereo > 0x10) {
+		/* stereo */
+		t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+		t->audmode = V4L2_TUNER_MODE_STEREO;
+	} else if (stereo < -0x10) {
+		/* bilingual */
+		t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+		t->audmode = V4L2_TUNER_MODE_LANG1;
+	} else /* mono */
+		t->rxsubchans = V4L2_TUNER_SUB_MONO;
 
-		// FIXME: standard / stereo detection is still broken
-		msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
-		dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
-		msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
-		dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
-		stereo = (s8)(stereo_det >> 8);
-		if (stereo > 0x10) {
-			/* stereo */
-			t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
-			t->audmode = V4L2_TUNER_MODE_STEREO;
-		}
-		else if (stereo < -0x10) {
-			/* bilingual */
-			t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-			t->audmode = V4L2_TUNER_MODE_LANG1;
-		}
-		else /* mono */
-			t->rxsubchans = V4L2_TUNER_SUB_MONO;
+	return 0;
+}
 
-		return 0;
-	}
-	case VIDIOC_S_TUNER:
-	{
-		struct v4l2_tuner *t = arg;
-		u16 fm_matrix, src;
-		dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+	u16 fm_matrix, src;
+	dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
 
-		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-			return -EINVAL;
+	if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+		return -EINVAL;
 
-		switch (t->audmode) {
-		case V4L2_TUNER_MODE_STEREO:
-			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
-			fm_matrix = 0x3001; // stereo
-			src = 0x0020;
-			break;
-		case V4L2_TUNER_MODE_LANG1_LANG2:
-			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
-			fm_matrix = 0x3000; // bilingual
-			src = 0x0020;
-			break;
-		case V4L2_TUNER_MODE_LANG1:
-			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
-			fm_matrix = 0x3000; // mono
-			src = 0x0000;
-			break;
-		case V4L2_TUNER_MODE_LANG2:
-			dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
-			fm_matrix = 0x3000; // mono
-			src = 0x0010;
-			break;
-		default: /* case V4L2_TUNER_MODE_MONO: */
-			dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
-			fm_matrix = 0x3000; // mono
-			src = 0x0030;
-			break;
-		}
-		msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
-		msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
-		msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
-		msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
-		return 0;
+	switch (t->audmode) {
+	case V4L2_TUNER_MODE_STEREO:
+		dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
+		fm_matrix = 0x3001; /* stereo */
+		src = 0x0020;
+		break;
+	case V4L2_TUNER_MODE_LANG1_LANG2:
+		dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
+		fm_matrix = 0x3000; /* bilingual */
+		src = 0x0020;
+		break;
+	case V4L2_TUNER_MODE_LANG1:
+		dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
+		fm_matrix = 0x3000; /* mono */
+		src = 0x0000;
+		break;
+	case V4L2_TUNER_MODE_LANG2:
+		dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
+		fm_matrix = 0x3000; /* mono */
+		src = 0x0010;
+		break;
+	default: /* case V4L2_TUNER_MODE_MONO: */
+		dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
+		fm_matrix = 0x3000; /* mono */
+		src = 0x0030;
+		break;
 	}
-	case VIDIOC_G_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
+	msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
+	msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
+	msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
+	msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
+	return 0;
+}
 
-		dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
 
-		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-			return -EINVAL;
+	dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
 
-		memset(f, 0, sizeof(*f));
-		f->type = V4L2_TUNER_ANALOG_TV;
-		f->frequency =	av7110->current_freq;
-		return 0;
-	}
-	case VIDIOC_S_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
+	if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+		return -EINVAL;
 
-		dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
+	memset(f, 0, sizeof(*f));
+	f->type = V4L2_TUNER_ANALOG_TV;
+	f->frequency =	av7110->current_freq;
+	return 0;
+}
 
-		if (!av7110->analog_tuner_flags || av7110->current_input != 1)
-			return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
 
-		if (V4L2_TUNER_ANALOG_TV != f->type)
-			return -EINVAL;
+	dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
 
-		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
-		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+	if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+		return -EINVAL;
 
-		/* tune in desired frequency */
-		if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
-			ves1820_set_tv_freq(dev, f->frequency);
-		} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
-			stv0297_set_tv_freq(dev, f->frequency);
-		}
-		av7110->current_freq = f->frequency;
+	if (V4L2_TUNER_ANALOG_TV != f->type)
+		return -EINVAL;
 
-		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
-		msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
-		msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
-		msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
-		return 0;
-	}
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input *i = arg;
+	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+	msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
 
-		dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+	/* tune in desired frequency */
+	if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
+		ves1820_set_tv_freq(dev, f->frequency);
+	else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
+		stv0297_set_tv_freq(dev, f->frequency);
+	av7110->current_freq = f->frequency;
 
-		if (av7110->analog_tuner_flags) {
-			if (i->index < 0 || i->index >= 4)
-				return -EINVAL;
-		} else {
-			if (i->index != 0)
-				return -EINVAL;
-		}
+	msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
+	msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
+	msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
+	msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
+	return 0;
+}
 
-		memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
 
-		return 0;
+	dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+
+	if (av7110->analog_tuner_flags) {
+		if (i->index < 0 || i->index >= 4)
+			return -EINVAL;
+	} else {
+		if (i->index != 0)
+			return -EINVAL;
 	}
-	case VIDIOC_G_INPUT:
-	{
-		int *input = (int *)arg;
-		*input = av7110->current_input;
-		dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+
+	memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+	*input = av7110->current_input;
+	dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+	dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+	if (!av7110->analog_tuner_flags)
 		return 0;
-	}
-	case VIDIOC_S_INPUT:
-	{
-		int input = *(int *)arg;
 
-		dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+	if (input < 0 || input >= 4)
+		return -EINVAL;
 
-		if (!av7110->analog_tuner_flags)
-			return 0;
+	av7110->current_input = input;
+	return av7110_dvb_c_switch(fh);
+}
 
-		if (input < 0 || input >= 4)
-			return -EINVAL;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+	if (a->index != 0)
+		return -EINVAL;
+	memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
+	return 0;
+}
 
-		av7110->current_input = input;
-		return av7110_dvb_c_switch(fh);
-	}
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+	return 0;
+}
 
-		dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
-		if (a->index != 0)
-			return -EINVAL;
-		memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
-		break;
-	}
-	case VIDIOC_S_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
-		dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
-		break;
-	}
-	case VIDIOC_G_SLICED_VBI_CAP:
-	{
-		struct v4l2_sliced_vbi_cap *cap = arg;
-		dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
-		memset(cap, 0, sizeof *cap);
-		if (FW_VERSION(av7110->arm_app) >= 0x2623) {
-			cap->service_set = V4L2_SLICED_WSS_625;
-			cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
-		}
-		break;
-	}
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format *f = arg;
-		dprintk(2, "VIDIOC_G_FMT:\n");
-		if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
-		    FW_VERSION(av7110->arm_app) < 0x2623)
-			return -EAGAIN; /* handled by core driver */
-		memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
-		if (av7110->wssMode) {
-			f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
-			f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
-			f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
-		}
-		break;
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+					struct v4l2_sliced_vbi_cap *cap)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+	dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+	if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+		return -EINVAL;
+	if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+		cap->service_set = V4L2_SLICED_WSS_625;
+		cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
 	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *f = arg;
-		dprintk(2, "VIDIOC_S_FMT\n");
-		if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
-		    FW_VERSION(av7110->arm_app) < 0x2623)
-			return -EAGAIN; /* handled by core driver */
-		if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
-		    f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
-			memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
-			/* WSS controlled by firmware */
-			av7110->wssMode = 0;
-			av7110->wssData = 0;
-			return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
-					     SetWSSConfig, 1, 0);
-		} else {
-			memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
-			f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
-			f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
-			f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
-			/* WSS controlled by userspace */
-			av7110->wssMode = 1;
-			av7110->wssData = 0;
-		}
-		break;
+	return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+	dprintk(2, "VIDIOC_G_FMT:\n");
+	if (FW_VERSION(av7110->arm_app) < 0x2623)
+		return -EINVAL;
+	memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+	if (av7110->wssMode) {
+		f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+		f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+		f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
 	}
-	default:
-		printk("no such ioctl\n");
-		return -ENOIOCTLCMD;
+	return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+					struct v4l2_format *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+	dprintk(2, "VIDIOC_S_FMT\n");
+	if (FW_VERSION(av7110->arm_app) < 0x2623)
+		return -EINVAL;
+	if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+	    f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+		memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+		/* WSS controlled by firmware */
+		av7110->wssMode = 0;
+		av7110->wssData = 0;
+		return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+				     SetWSSConfig, 1, 0);
+	} else {
+		memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+		f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+		f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+		f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+		/* WSS controlled by userspace */
+		av7110->wssMode = 1;
+		av7110->wssData = 0;
 	}
 	return 0;
 }
@@ -609,22 +617,6 @@ static ssize_t av7110_vbi_write(struct f
  * INITIALIZATION
  ****************************************************************************/
 
-static struct saa7146_extension_ioctls ioctls[] = {
-	{ VIDIOC_ENUMINPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_FREQUENCY,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_TUNER,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_TUNER,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_AUDIO,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_AUDIO,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_FMT,		SAA7146_BEFORE },
-	{ VIDIOC_S_FMT,		SAA7146_BEFORE },
-	{ 0, 0 }
-};
-
 static u8 saa7113_init_regs[] = {
 	0x02, 0xd0,
 	0x03, 0x23,
@@ -788,20 +780,34 @@ int av7110_init_analog_module(struct av7
 int av7110_init_v4l(struct av7110 *av7110)
 {
 	struct saa7146_dev* dev = av7110->dev;
+	struct saa7146_ext_vv *vv_data;
 	int ret;
 
 	/* special case DVB-C: these cards have an analog tuner
 	   plus need some special handling, so we have separate
 	   saa7146_ext_vv data for these... */
 	if (av7110->analog_tuner_flags)
-		ret = saa7146_vv_init(dev, &av7110_vv_data_c);
+		vv_data = &av7110_vv_data_c;
 	else
-		ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+		vv_data = &av7110_vv_data_st;
+	ret = saa7146_vv_init(dev, vv_data);
 
 	if (ret) {
 		ERR(("cannot init capture device. skipping.\n"));
 		return -ENODEV;
 	}
+	vv_data->ops.vidioc_enum_input = vidioc_enum_input;
+	vv_data->ops.vidioc_g_input = vidioc_g_input;
+	vv_data->ops.vidioc_s_input = vidioc_s_input;
+	vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
+	vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
+	vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
+	vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
+	vv_data->ops.vidioc_g_audio = vidioc_g_audio;
+	vv_data->ops.vidioc_s_audio = vidioc_s_audio;
+	vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+	vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+	vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
 
 	if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
 		ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +906,6 @@ static struct saa7146_ext_vv av7110_vv_d
 	.num_stds	= ARRAY_SIZE(standard),
 	.std_callback	= &std_callback,
 
-	.ioctls		= &ioctls[0],
-	.ioctl		= av7110_ioctl,
-
 	.vbi_fops.open	= av7110_vbi_reset,
 	.vbi_fops.release = av7110_vbi_reset,
 	.vbi_fops.write	= av7110_vbi_write,
@@ -918,9 +921,6 @@ static struct saa7146_ext_vv av7110_vv_d
 	.num_stds	= ARRAY_SIZE(standard),
 	.std_callback	= &std_callback,
 
-	.ioctls		= &ioctls[0],
-	.ioctl		= av7110_ioctl,
-
 	.vbi_fops.open	= av7110_vbi_reset,
 	.vbi_fops.release = av7110_vbi_reset,
 	.vbi_fops.write	= av7110_vbi_write,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/budget-av.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/budget-av.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/budget-av.c	2013-05-03 18:01:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/budget-av.c	2013-05-03 16:45:16.000000000 -0400
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa71
 	return err;
 }
 
+#define KNC1_INPUTS 2
+static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
+	{0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+	{1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+};
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+	dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
+	if (i->index < 0 || i->index >= KNC1_INPUTS)
+		return -EINVAL;
+	memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+	*i = budget_av->cur_input;
+
+	dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+	dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
+	return saa7113_setinput(budget_av, input);
+}
+
 static struct saa7146_ext_vv vv_data;
 
 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa71
 			ERR(("cannot init vv subsystem.\n"));
 			return err;
 		}
+		vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+		vv_data.ops.vidioc_g_input = vidioc_g_input;
+		vv_data.ops.vidioc_s_input = vidioc_s_input;
 
 		if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
 			/* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa71
 	return 0;
 }
 
-#define KNC1_INPUTS 2
-static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
-	{0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
-	{1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
-};
-
-static struct saa7146_extension_ioctls ioctls[] = {
-	{VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
-	{VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
-	{VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
-	{0, 0}
-};
-
-static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-
-	switch (cmd) {
-	case VIDIOC_ENUMINPUT:{
-		struct v4l2_input *i = arg;
-
-		dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
-		if (i->index < 0 || i->index >= KNC1_INPUTS) {
-			return -EINVAL;
-		}
-		memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
-		return 0;
-	}
-	case VIDIOC_G_INPUT:{
-		int *input = (int *) arg;
-
-		*input = budget_av->cur_input;
-
-		dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
-		return 0;
-	}
-	case VIDIOC_S_INPUT:{
-		int input = *(int *) arg;
-		dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
-		return saa7113_setinput(budget_av, input);
-	}
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
 static struct saa7146_standard standard[] = {
 	{.name = "PAL",.id = V4L2_STD_PAL,
 	 .v_offset = 0x17,.v_field = 288,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
 	.flags = 0,
 	.stds = &standard[0],
 	.num_stds = ARRAY_SIZE(standard),
-	.ioctls = &ioctls[0],
-	.ioctl = av_ioctl,
 };
 
 static struct saa7146_extension budget_extension;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/budget-ci.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/budget-ci.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 18:01:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/budget-ci.c	2013-05-03 16:45:16.000000000 -0400
@@ -1076,6 +1076,10 @@ static struct tda10023_config tda10023_c
 	.deltaf = 0xa511,
 };
 
+static struct tda827x_config tda827x_config = {
+	.config = 0,
+};
+
 /* TT S2-3200 DVB-S (STB0899) Inittab */
 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
 
@@ -1414,7 +1418,7 @@ static void frontend_init(struct budget_
 	case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
 		budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
 		if (budget_ci->budget.dvb_frontend) {
-			if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
+			if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
 				printk(KERN_ERR "%s: No tda827x found!\n", __func__);
 				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
 				budget_ci->budget.dvb_frontend = NULL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/fdump.c linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/fdump.c
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/fdump.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/fdump.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int main(int argc, char **argv)
-{
-    unsigned char buf[8];
-    unsigned int i, count, bytes = 0;
-    FILE *fd_in, *fd_out;
-
-    if (argc != 4) {
-	fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
-	return -1;
-    }
-
-    fd_in = fopen(argv[1], "rb");
-    if (fd_in == NULL) {
-	fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
-	return -1;
-    }
-
-    fd_out = fopen(argv[3], "w+");
-    if (fd_out == NULL) {
-	fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
-	return -1;
-    }
-
-    fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
-
-    while ((count = fread(buf, 1, 8, fd_in)) > 0) {
-	fprintf(fd_out, "\n\t");
-	for (i = 0; i < count; i++, bytes++)
-	    fprintf(fd_out, "0x%02x, ", buf[i]);
-    }
-
-    fprintf(fd_out, "\n};\n\n");
-
-    fclose(fd_in);
-    fclose(fd_out);
-
-    return 0;
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/Kconfig linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/Kconfig	2013-05-03 18:01:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -28,26 +28,12 @@ config DVB_AV7110
 	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
 	  or /lib/firmware (depending on configuration of firmware hotplug).
 
-	  Say Y if you own such a card and want to use it.
-
-config DVB_AV7110_FIRMWARE
-depends on NONFREE
-	bool "Compile AV7110 firmware into the driver"
-	depends on DVB_AV7110 && !STANDALONE
-	default y if DVB_AV7110=y
-	help
-	  The AV7110 firmware is normally loaded by the firmware hotplug manager.
-	  If you want to compile the firmware into the driver you need to say
-	  Y here and provide the correct path of the firmware. You need this
-	  option if you want to compile the whole driver statically into the
-	  kernel.
-
-	  All other people say N.
+	  Alternatively, you can download the file and use the kernel's
+	  EXTRA_FIRMWARE configuration option to build it into your
+	  kernel image by adding the filename to the EXTRA_FIRMWARE
+	  configuration option string.
 
-config DVB_AV7110_FIRMWARE_FILE
-	string "Full pathname of av7110 firmware file"
-	depends on DVB_AV7110_FIRMWARE
-	default "/*(DEBLOBBED)*/"
+	  Say Y if you own such a card and want to use it.
 
 config DVB_AV7110_OSD
 	bool "AV7110 OSD support"
@@ -109,7 +95,7 @@ config DVB_BUDGET_CI
 	select DVB_STB6100 if !DVB_FE_CUSTOMISE
 	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
 	select VIDEO_IR
 	help
 	  Support for simple SAA7146 based DVB cards
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/Makefile linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/dvb/ttpci/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/dvb/ttpci/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -19,12 +19,3 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
-
-hostprogs-y	:= fdump
-
-ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y)
-$(obj)/av7110.o: $(obj)/av7110_firm.h
-
-$(obj)/av7110_firm.h: $(obj)/fdump
-	$(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
-endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/Kconfig linux-libre-2.6.30-gnu1/drivers/media/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig"
 config DAB
 	boolean "DAB adapters"
 	---help---
-	  Allow selecting support for for Digital Audio Broadcasting (DAB)
+	  Allow selecting support for Digital Audio Broadcasting (DAB)
 	  Receiver adapters.
 
 if DAB
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/dsbr100.c linux-libre-2.6.30-gnu1/drivers/media/radio/dsbr100.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/dsbr100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/dsbr100.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,9 @@
 
  History:
 
+ Version 0.45:
+	Converted to v4l2_device.
+
  Version 0.44:
 	Add suspend/resume functions, fix unplug of device,
 	a lot of cleanups and fixes by Alexey Klimov <klimov.linux@gmail.com>
@@ -88,7 +91,7 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 
@@ -97,39 +100,8 @@
  */
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 
-#define DRIVER_VERSION "v0.44"
-#define RADIO_VERSION KERNEL_VERSION(0, 4, 4)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},
-/* HINT: the disabled controls are only here to satify kradio and such apps */
-	{       .id             = V4L2_CID_AUDIO_VOLUME,
-		.flags          = V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id             = V4L2_CID_AUDIO_BALANCE,
-		.flags          = V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id             = V4L2_CID_AUDIO_BASS,
-		.flags          = V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id             = V4L2_CID_AUDIO_TREBLE,
-		.flags          = V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id             = V4L2_CID_AUDIO_LOUDNESS,
-		.flags          = V4L2_CTRL_FLAG_DISABLED,
-	},
-};
+#define DRIVER_VERSION "v0.45"
+#define RADIO_VERSION KERNEL_VERSION(0, 4, 5)
 
 #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
 #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
@@ -167,6 +139,8 @@ module_param(radio_nr, int, 0);
 struct dsbr100_device {
 	struct usb_device *usbdev;
 	struct video_device videodev;
+	struct v4l2_device v4l2_dev;
+
 	u8 *transfer_buffer;
 	struct mutex lock;	/* buffer locking */
 	int curfreq;
@@ -384,15 +358,18 @@ static void usb_dsbr100_disconnect(struc
 	mutex_unlock(&radio->lock);
 
 	video_unregister_device(&radio->videodev);
+	v4l2_device_disconnect(&radio->v4l2_dev);
 }
 
 
 static int vidioc_querycap(struct file *file, void *priv,
 					struct v4l2_capability *v)
 {
+	struct dsbr100_device *radio = video_drvdata(file);
+
 	strlcpy(v->driver, "dsbr100", sizeof(v->driver));
 	strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
-	sprintf(v->bus_info, "USB");
+	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
 	v->capabilities = V4L2_CAP_TUNER;
 	return 0;
@@ -450,7 +427,10 @@ static int vidioc_s_frequency(struct fil
 	if (radio->removed)
 		return -EIO;
 
+	mutex_lock(&radio->lock);
 	radio->curfreq = f->frequency;
+	mutex_unlock(&radio->lock);
+
 	retval = dsbr100_setfreq(radio, radio->curfreq);
 	if (retval < 0)
 		dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
@@ -474,14 +454,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
 	}
+
 	return -EINVAL;
 }
 
@@ -601,7 +578,10 @@ static int usb_dsbr100_close(struct file
 	if (!radio)
 		return -ENODEV;
 
+	mutex_lock(&radio->lock);
 	radio->users = 0;
+	mutex_unlock(&radio->lock);
+
 	if (!radio->removed) {
 		retval = dsbr100_stop(radio);
 		if (retval < 0) {
@@ -648,6 +628,7 @@ static void usb_dsbr100_video_device_rel
 {
 	struct dsbr100_device *radio = videodev_to_radio(videodev);
 
+	v4l2_device_unregister(&radio->v4l2_dev);
 	kfree(radio->transfer_buffer);
 	kfree(radio);
 }
@@ -675,22 +656,15 @@ static const struct v4l2_ioctl_ops usb_d
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-/* V4L2 interface */
-static struct video_device dsbr100_videodev_data = {
-	.name		= "D-Link DSB-R 100",
-	.fops		= &usb_dsbr100_fops,
-	.ioctl_ops 	= &usb_dsbr100_ioctl_ops,
-	.release	= usb_dsbr100_video_device_release,
-};
-
 /* check if the device is present and register with v4l and usb if it is */
 static int usb_dsbr100_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 {
 	struct dsbr100_device *radio;
+	struct v4l2_device *v4l2_dev;
 	int retval;
 
-	radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
+	radio = kzalloc(sizeof(struct dsbr100_device), GFP_KERNEL);
 
 	if (!radio)
 		return -ENOMEM;
@@ -702,17 +676,35 @@ static int usb_dsbr100_probe(struct usb_
 		return -ENOMEM;
 	}
 
+	v4l2_dev = &radio->v4l2_dev;
+
+	retval = v4l2_device_register(&intf->dev, v4l2_dev);
+	if (retval < 0) {
+		v4l2_err(v4l2_dev, "couldn't register v4l2_device\n");
+		kfree(radio->transfer_buffer);
+		kfree(radio);
+		return retval;
+	}
+
+	strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
+	radio->videodev.v4l2_dev = v4l2_dev;
+	radio->videodev.fops = &usb_dsbr100_fops;
+	radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
+	radio->videodev.release = usb_dsbr100_video_device_release;
+
 	mutex_init(&radio->lock);
-	radio->videodev = dsbr100_videodev_data;
 
 	radio->removed = 0;
 	radio->users = 0;
 	radio->usbdev = interface_to_usbdev(intf);
 	radio->curfreq = FREQ_MIN * FREQ_MUL;
+
 	video_set_drvdata(&radio->videodev, radio);
+
 	retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
 	if (retval < 0) {
-		dev_err(&intf->dev, "couldn't register video device\n");
+		v4l2_err(v4l2_dev, "couldn't register video device\n");
+		v4l2_device_unregister(v4l2_dev);
 		kfree(radio->transfer_buffer);
 		kfree(radio);
 		return -EIO;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-aimslab.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-aimslab.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-aimslab.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-aimslab.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,14 +32,15 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
+#include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("M.Kirkwood");
+MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
+MODULE_LICENSE("GPL");
 
 #ifndef CONFIG_RADIO_RTRACK_PORT
 #define CONFIG_RADIO_RTRACK_PORT -1
@@ -47,86 +48,95 @@
 
 static int io = CONFIG_RADIO_RTRACK_PORT;
 static int radio_nr = -1;
-static struct mutex lock;
 
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack
 {
-	unsigned long in_use;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
 	int port;
 	int curvol;
 	unsigned long curfreq;
 	int muted;
+	int io;
+	struct mutex lock;
 };
 
+static struct rtrack rtrack_card;
 
 /* local things */
 
 static void sleep_delay(long n)
 {
 	/* Sleep nicely for 'n' uS */
-	int d=n/msecs_to_jiffies(1000);
-	if(!d)
+	int d = n / msecs_to_jiffies(1000);
+	if (!d)
 		udelay(n);
 	else
 		msleep(jiffies_to_msecs(d));
 }
 
-static void rt_decvol(void)
+static void rt_decvol(struct rtrack *rt)
 {
-	outb(0x58, io);		/* volume down + sigstr + on	*/
+	outb(0x58, rt->io);		/* volume down + sigstr + on	*/
 	sleep_delay(100000);
-	outb(0xd8, io);		/* volume steady + sigstr + on	*/
+	outb(0xd8, rt->io);		/* volume steady + sigstr + on	*/
 }
 
-static void rt_incvol(void)
+static void rt_incvol(struct rtrack *rt)
 {
-	outb(0x98, io);		/* volume up + sigstr + on	*/
+	outb(0x98, rt->io);		/* volume up + sigstr + on	*/
 	sleep_delay(100000);
-	outb(0xd8, io);		/* volume steady + sigstr + on	*/
+	outb(0xd8, rt->io);		/* volume steady + sigstr + on	*/
 }
 
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack *rt)
 {
-	dev->muted = 1;
-	mutex_lock(&lock);
-	outb(0xd0, io);			/* volume steady, off		*/
-	mutex_unlock(&lock);
+	rt->muted = 1;
+	mutex_lock(&rt->lock);
+	outb(0xd0, rt->io);		/* volume steady, off		*/
+	mutex_unlock(&rt->lock);
 }
 
-static int rt_setvol(struct rt_device *dev, int vol)
+static int rt_setvol(struct rtrack *rt, int vol)
 {
 	int i;
 
-	mutex_lock(&lock);
+	mutex_lock(&rt->lock);
 
-	if(vol == dev->curvol) {	/* requested volume = current */
-		if (dev->muted) {	/* user is unmuting the card  */
-			dev->muted = 0;
-			outb (0xd8, io);	/* enable card */
+	if (vol == rt->curvol) {	/* requested volume = current */
+		if (rt->muted) {	/* user is unmuting the card  */
+			rt->muted = 0;
+			outb(0xd8, rt->io);	/* enable card */
 		}
-		mutex_unlock(&lock);
+		mutex_unlock(&rt->lock);
 		return 0;
 	}
 
-	if(vol == 0) {			/* volume = 0 means mute the card */
-		outb(0x48, io);		/* volume down but still "on"	*/
+	if (vol == 0) {			/* volume = 0 means mute the card */
+		outb(0x48, rt->io);	/* volume down but still "on"	*/
 		sleep_delay(2000000);	/* make sure it's totally down	*/
-		outb(0xd0, io);		/* volume steady, off		*/
-		dev->curvol = 0;	/* track the volume state!	*/
-		mutex_unlock(&lock);
+		outb(0xd0, rt->io);	/* volume steady, off		*/
+		rt->curvol = 0;		/* track the volume state!	*/
+		mutex_unlock(&rt->lock);
 		return 0;
 	}
 
-	dev->muted = 0;
-	if(vol > dev->curvol)
-		for(i = dev->curvol; i < vol; i++)
-			rt_incvol();
+	rt->muted = 0;
+	if (vol > rt->curvol)
+		for (i = rt->curvol; i < vol; i++)
+			rt_incvol(rt);
 	else
-		for(i = dev->curvol; i > vol; i--)
-			rt_decvol();
+		for (i = rt->curvol; i > vol; i--)
+			rt_decvol(rt);
 
-	dev->curvol = vol;
-	mutex_unlock(&lock);
+	rt->curvol = vol;
+	mutex_unlock(&rt->lock);
 	return 0;
 }
 
@@ -135,155 +145,137 @@ static int rt_setvol(struct rt_device *d
  * and bit 4 (+16) is to keep the signal strength meter enabled
  */
 
-static void send_0_byte(int port, struct rt_device *dev)
+static void send_0_byte(struct rtrack *rt)
 {
-	if ((dev->curvol == 0) || (dev->muted)) {
-		outb_p(128+64+16+  1, port);   /* wr-enable + data low */
-		outb_p(128+64+16+2+1, port);   /* clock */
+	if (rt->curvol == 0 || rt->muted) {
+		outb_p(128+64+16+  1, rt->io);   /* wr-enable + data low */
+		outb_p(128+64+16+2+1, rt->io);   /* clock */
 	}
 	else {
-		outb_p(128+64+16+8+  1, port);  /* on + wr-enable + data low */
-		outb_p(128+64+16+8+2+1, port);  /* clock */
+		outb_p(128+64+16+8+  1, rt->io);  /* on + wr-enable + data low */
+		outb_p(128+64+16+8+2+1, rt->io);  /* clock */
 	}
 	sleep_delay(1000);
 }
 
-static void send_1_byte(int port, struct rt_device *dev)
+static void send_1_byte(struct rtrack *rt)
 {
-	if ((dev->curvol == 0) || (dev->muted)) {
-		outb_p(128+64+16+4  +1, port);   /* wr-enable+data high */
-		outb_p(128+64+16+4+2+1, port);   /* clock */
+	if (rt->curvol == 0 || rt->muted) {
+		outb_p(128+64+16+4  +1, rt->io);   /* wr-enable+data high */
+		outb_p(128+64+16+4+2+1, rt->io);   /* clock */
 	}
 	else {
-		outb_p(128+64+16+8+4  +1, port); /* on+wr-enable+data high */
-		outb_p(128+64+16+8+4+2+1, port); /* clock */
+		outb_p(128+64+16+8+4  +1, rt->io); /* on+wr-enable+data high */
+		outb_p(128+64+16+8+4+2+1, rt->io); /* clock */
 	}
 
 	sleep_delay(1000);
 }
 
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack *rt, unsigned long freq)
 {
 	int i;
 
-	/* adapted from radio-aztech.c */
+	mutex_lock(&rt->lock);			/* Stop other ops interfering */
+
+	rt->curfreq = freq;
 
 	/* now uses VIDEO_TUNER_LOW for fine tuning */
 
 	freq += 171200;			/* Add 10.7 MHz IF 		*/
 	freq /= 800;			/* Convert to 50 kHz units	*/
 
-	mutex_lock(&lock);			/* Stop other ops interfering */
-
-	send_0_byte (io, dev);		/*  0: LSB of frequency		*/
+	send_0_byte(rt);		/*  0: LSB of frequency		*/
 
 	for (i = 0; i < 13; i++)	/*   : frequency bits (1-13)	*/
 		if (freq & (1 << i))
-			send_1_byte (io, dev);
+			send_1_byte(rt);
 		else
-			send_0_byte (io, dev);
+			send_0_byte(rt);
 
-	send_0_byte (io, dev);		/* 14: test bit - always 0    */
-	send_0_byte (io, dev);		/* 15: test bit - always 0    */
+	send_0_byte(rt);		/* 14: test bit - always 0    */
+	send_0_byte(rt);		/* 15: test bit - always 0    */
 
-	send_0_byte (io, dev);		/* 16: band data 0 - always 0 */
-	send_0_byte (io, dev);		/* 17: band data 1 - always 0 */
-	send_0_byte (io, dev);		/* 18: band data 2 - always 0 */
-	send_0_byte (io, dev);		/* 19: time base - always 0   */
+	send_0_byte(rt);		/* 16: band data 0 - always 0 */
+	send_0_byte(rt);		/* 17: band data 1 - always 0 */
+	send_0_byte(rt);		/* 18: band data 2 - always 0 */
+	send_0_byte(rt);		/* 19: time base - always 0   */
 
-	send_0_byte (io, dev);		/* 20: spacing (0 = 25 kHz)   */
-	send_1_byte (io, dev);		/* 21: spacing (1 = 25 kHz)   */
-	send_0_byte (io, dev);		/* 22: spacing (0 = 25 kHz)   */
-	send_1_byte (io, dev);		/* 23: AM/FM (FM = 1, always) */
+	send_0_byte(rt);		/* 20: spacing (0 = 25 kHz)   */
+	send_1_byte(rt);		/* 21: spacing (1 = 25 kHz)   */
+	send_0_byte(rt);		/* 22: spacing (0 = 25 kHz)   */
+	send_1_byte(rt);		/* 23: AM/FM (FM = 1, always) */
 
-	if ((dev->curvol == 0) || (dev->muted))
-		outb (0xd0, io);	/* volume steady + sigstr */
+	if (rt->curvol == 0 || rt->muted)
+		outb(0xd0, rt->io);	/* volume steady + sigstr */
 	else
-		outb (0xd8, io);	/* volume steady + sigstr + on */
+		outb(0xd8, rt->io);	/* volume steady + sigstr + on */
 
-	mutex_unlock(&lock);
+	mutex_unlock(&rt->lock);
 
 	return 0;
 }
 
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack *rt)
 {
-	if (inb(io) & 2)	/* bit set = no signal present	*/
-		return 0;
-	return 1;		/* signal present		*/
-}
+	int sig = 1;
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 0xff,
-		.step          = 1,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+	mutex_lock(&rt->lock);
+	if (inb(rt->io) & 2)	/* bit set = no signal present	*/
+		sig = 0;
+	mutex_unlock(&rt->lock);
+	return sig;
+}
 
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
 	strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
 	strlcpy(v->card, "RadioTrack", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack *rt = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (87*16000);
-	v->rangehigh = (108*16000);
+	v->rangelow = 87 * 16000;
+	v->rangehigh = 108 * 16000;
 	v->rxsubchans = V4L2_TUNER_SUB_MONO;
 	v->capability = V4L2_TUNER_CAP_LOW;
 	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xffff*rt_getsigstr(rt);
+	v->signal = 0xffff * rt_getsigstr(rt);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack *rt = video_drvdata(file);
 
-	rt->curfreq = f->frequency;
-	rt_setfreq(rt, rt->curfreq);
+	rt_setfreq(rt, f->frequency);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack *rt = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = rt->curfreq;
@@ -293,14 +285,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
 	}
 	return -EINVAL;
 }
@@ -308,14 +297,14 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack *rt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		ctrl->value = rt->muted;
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = rt->curvol * 6554;
+		ctrl->value = rt->curvol;
 		return 0;
 	}
 	return -EINVAL;
@@ -324,33 +313,22 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack *rt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value)
 			rt_mute(rt);
 		else
-			rt_setvol(rt,rt->curvol);
+			rt_setvol(rt, rt->curvol);
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		rt_setvol(rt,ctrl->value);
+		rt_setvol(rt, ctrl->value);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio (struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -359,36 +337,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct rt_device rtrack_unit;
-
-static int rtrack_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0;
-}
-
-static int rtrack_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	clear_bit(0, &rtrack_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations rtrack_fops = {
 	.owner		= THIS_MODULE,
-	.open           = rtrack_exclusive_open,
-	.release        = rtrack_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -407,64 +375,69 @@ static const struct v4l2_ioctl_ops rtrac
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device rtrack_radio = {
-	.name		= "RadioTrack radio",
-	.fops           = &rtrack_fops,
-	.ioctl_ops 	= &rtrack_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init rtrack_init(void)
 {
-	if(io==-1)
-	{
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+	struct rtrack *rt = &rtrack_card;
+	struct v4l2_device *v4l2_dev = &rt->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name));
+	rt->io = io;
+
+	if (rt->io == -1) {
+		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n");
 		return -EINVAL;
 	}
 
-	if (!request_region(io, 2, "rtrack"))
-	{
-		printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
+	if (!request_region(rt->io, 2, "rtrack")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io);
 		return -EBUSY;
 	}
 
-	video_set_drvdata(&rtrack_radio, &rtrack_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(rt->io, 2);
+		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+		return res;
+	}
 
-	if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 2);
+	strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name));
+	rt->vdev.v4l2_dev = v4l2_dev;
+	rt->vdev.fops = &rtrack_fops;
+	rt->vdev.ioctl_ops = &rtrack_ioctl_ops;
+	rt->vdev.release = video_device_release_empty;
+	video_set_drvdata(&rt->vdev, rt);
+
+	if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(&rt->v4l2_dev);
+		release_region(rt->io, 2);
 		return -EINVAL;
 	}
-	printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
+	v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
 
 	/* Set up the I/O locking */
 
-	mutex_init(&lock);
+	mutex_init(&rt->lock);
 
 	/* mute card - prevents noisy bootups */
 
 	/* this ensures that the volume is all the way down  */
-	outb(0x48, io);		/* volume down but still "on"	*/
+	outb(0x48, rt->io);		/* volume down but still "on"	*/
 	sleep_delay(2000000);	/* make sure it's totally down	*/
-	outb(0xc0, io);		/* steady volume, mute card	*/
-	rtrack_unit.curvol = 0;
+	outb(0xc0, rt->io);		/* steady volume, mute card	*/
 
 	return 0;
 }
 
-MODULE_AUTHOR("M.Kirkwood");
-MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-module_param(radio_nr, int, 0);
-
-static void __exit cleanup_rtrack_module(void)
+static void __exit rtrack_exit(void)
 {
-	video_unregister_device(&rtrack_radio);
-	release_region(io,2);
+	struct rtrack *rt = &rtrack_card;
+
+	video_unregister_device(&rt->vdev);
+	v4l2_device_unregister(&rt->v4l2_dev);
+	release_region(rt->io, 2);
 }
 
 module_init(rtrack_init);
-module_exit(cleanup_rtrack_module);
+module_exit(rtrack_exit);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-aztech.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-aztech.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-aztech.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-aztech.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,33 +29,15 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 0xff,
-		.step          = 1,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Aztech radio card.");
+MODULE_LICENSE("GPL");
 
 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
 
@@ -66,55 +48,64 @@ static struct v4l2_queryctrl radio_qctrl
 static int io = CONFIG_RADIO_AZTECH_PORT;
 static int radio_nr = -1;
 static int radio_wait_time = 1000;
-static struct mutex lock;
 
-struct az_device
+module_param(io, int, 0);
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct aztech
 {
-	unsigned long in_use;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	int curvol;
 	unsigned long curfreq;
 	int stereo;
+	struct mutex lock;
 };
 
+static struct aztech aztech_card;
+
 static int volconvert(int level)
 {
-	level>>=14;		/* Map 16bits down to 2 bit */
-	level&=3;
+	level >>= 14;		/* Map 16bits down to 2 bit */
+	level &= 3;
 
 	/* convert to card-friendly values */
-	switch (level)
-	{
-		case 0:
-			return 0;
-		case 1:
-			return 1;
-		case 2:
-			return 4;
-		case 3:
-			return 5;
+	switch (level) {
+	case 0:
+		return 0;
+	case 1:
+		return 1;
+	case 2:
+		return 4;
+	case 3:
+		return 5;
 	}
 	return 0;	/* Quieten gcc */
 }
 
-static void send_0_byte (struct az_device *dev)
+static void send_0_byte(struct aztech *az)
 {
 	udelay(radio_wait_time);
-	outb_p(2+volconvert(dev->curvol), io);
-	outb_p(64+2+volconvert(dev->curvol), io);
+	outb_p(2 + volconvert(az->curvol), az->io);
+	outb_p(64 + 2 + volconvert(az->curvol), az->io);
 }
 
-static void send_1_byte (struct az_device *dev)
+static void send_1_byte(struct aztech *az)
 {
 	udelay (radio_wait_time);
-	outb_p(128+2+volconvert(dev->curvol), io);
-	outb_p(128+64+2+volconvert(dev->curvol), io);
+	outb_p(128 + 2 + volconvert(az->curvol), az->io);
+	outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io);
 }
 
-static int az_setvol(struct az_device *dev, int vol)
+static int az_setvol(struct aztech *az, int vol)
 {
-	mutex_lock(&lock);
-	outb (volconvert(vol), io);
-	mutex_unlock(&lock);
+	mutex_lock(&az->lock);
+	outb(volconvert(vol), az->io);
+	mutex_unlock(&az->lock);
 	return 0;
 }
 
@@ -126,116 +117,110 @@ static int az_setvol(struct az_device *d
  *
  */
 
-static int az_getsigstr(struct az_device *dev)
+static int az_getsigstr(struct aztech *az)
 {
-	if (inb(io) & 2)	/* bit set = no signal present */
-		return 0;
-	return 1;		/* signal present */
+	int sig = 1;
+
+	mutex_lock(&az->lock);
+	if (inb(az->io) & 2)	/* bit set = no signal present */
+		sig = 0;
+	mutex_unlock(&az->lock);
+	return sig;
 }
 
-static int az_getstereo(struct az_device *dev)
+static int az_getstereo(struct aztech *az)
 {
-	if (inb(io) & 1) 	/* bit set = mono */
-		return 0;
-	return 1;		/* stereo */
+	int stereo = 1;
+
+	mutex_lock(&az->lock);
+	if (inb(az->io) & 1) 	/* bit set = mono */
+		stereo = 0;
+	mutex_unlock(&az->lock);
+	return stereo;
 }
 
-static int az_setfreq(struct az_device *dev, unsigned long frequency)
+static int az_setfreq(struct aztech *az, unsigned long frequency)
 {
 	int  i;
 
+	mutex_lock(&az->lock);
+
+	az->curfreq = frequency;
 	frequency += 171200;		/* Add 10.7 MHz IF		*/
 	frequency /= 800;		/* Convert to 50 kHz units	*/
 
-	mutex_lock(&lock);
-
-	send_0_byte (dev);		/*  0: LSB of frequency       */
+	send_0_byte(az);		/*  0: LSB of frequency       */
 
 	for (i = 0; i < 13; i++)	/*   : frequency bits (1-13)  */
 		if (frequency & (1 << i))
-			send_1_byte (dev);
+			send_1_byte(az);
 		else
-			send_0_byte (dev);
+			send_0_byte(az);
 
-	send_0_byte (dev);		/* 14: test bit - always 0    */
-	send_0_byte (dev);		/* 15: test bit - always 0    */
-	send_0_byte (dev);		/* 16: band data 0 - always 0 */
-	if (dev->stereo)		/* 17: stereo (1 to enable)   */
-		send_1_byte (dev);
+	send_0_byte(az);		/* 14: test bit - always 0    */
+	send_0_byte(az);		/* 15: test bit - always 0    */
+	send_0_byte(az);		/* 16: band data 0 - always 0 */
+	if (az->stereo)		/* 17: stereo (1 to enable)   */
+		send_1_byte(az);
 	else
-		send_0_byte (dev);
+		send_0_byte(az);
 
-	send_1_byte (dev);		/* 18: band data 1 - unknown  */
-	send_0_byte (dev);		/* 19: time base - always 0   */
-	send_0_byte (dev);		/* 20: spacing (0 = 25 kHz)   */
-	send_1_byte (dev);		/* 21: spacing (1 = 25 kHz)   */
-	send_0_byte (dev);		/* 22: spacing (0 = 25 kHz)   */
-	send_1_byte (dev);		/* 23: AM/FM (FM = 1, always) */
+	send_1_byte(az);		/* 18: band data 1 - unknown  */
+	send_0_byte(az);		/* 19: time base - always 0   */
+	send_0_byte(az);		/* 20: spacing (0 = 25 kHz)   */
+	send_1_byte(az);		/* 21: spacing (1 = 25 kHz)   */
+	send_0_byte(az);		/* 22: spacing (0 = 25 kHz)   */
+	send_1_byte(az);		/* 23: AM/FM (FM = 1, always) */
 
 	/* latch frequency */
 
-	udelay (radio_wait_time);
-	outb_p(128+64+volconvert(dev->curvol), io);
+	udelay(radio_wait_time);
+	outb_p(128 + 64 + volconvert(az->curvol), az->io);
 
-	mutex_unlock(&lock);
+	mutex_unlock(&az->lock);
 
 	return 0;
 }
 
-static int vidioc_querycap (struct file *file, void  *priv,
+static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
-	strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
-	strlcpy(v->card, "Aztech Radio", sizeof (v->card));
-	sprintf(v->bus_info,"ISA");
+	strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
+	strlcpy(v->card, "Aztech Radio", sizeof(v->card));
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct az_device *az = video_drvdata(file);
+	struct aztech *az = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 
-	v->rangelow=(87*16000);
-	v->rangehigh=(108*16000);
-	v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
-	v->capability=V4L2_TUNER_CAP_LOW;
-	if(az_getstereo(az))
+	v->rangelow = 87 * 16000;
+	v->rangehigh = 108 * 16000;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	if (az_getstereo(az))
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 	else
 		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal=0xFFFF*az_getsigstr(az);
+	v->signal = 0xFFFF * az_getsigstr(az);
 
 	return 0;
 }
 
-
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
-			   struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
@@ -246,113 +231,95 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-
-static int vidioc_s_audio (struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 			   struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
-
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_audio(struct file *file, void *priv,
+			   struct v4l2_audio *a)
+{
+	return a->index ? -EINVAL : 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct az_device *az = video_drvdata(file);
+	struct aztech *az = video_drvdata(file);
 
-	az->curfreq = f->frequency;
-	az_setfreq(az, az->curfreq);
+	az_setfreq(az, f->frequency);
 	return 0;
 }
 
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct az_device *az = video_drvdata(file);
+	struct aztech *az = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = az->curfreq;
-
 	return 0;
 }
 
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
 			    struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return (0);
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_ctrl (struct file *file, void *priv,
+static int vidioc_g_ctrl(struct file *file, void *priv,
 			    struct v4l2_control *ctrl)
 {
-	struct az_device *az = video_drvdata(file);
+	struct aztech *az = video_drvdata(file);
 
 	switch (ctrl->id) {
-		case V4L2_CID_AUDIO_MUTE:
-			if (az->curvol==0)
-				ctrl->value=1;
-			else
-				ctrl->value=0;
-			return (0);
-		case V4L2_CID_AUDIO_VOLUME:
-			ctrl->value=az->curvol * 6554;
-			return (0);
+	case V4L2_CID_AUDIO_MUTE:
+		if (az->curvol == 0)
+			ctrl->value = 1;
+		else
+			ctrl->value = 0;
+		return 0;
+	case V4L2_CID_AUDIO_VOLUME:
+		ctrl->value = az->curvol * 6554;
+		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_s_ctrl (struct file *file, void *priv,
+static int vidioc_s_ctrl(struct file *file, void *priv,
 			    struct v4l2_control *ctrl)
 {
-	struct az_device *az = video_drvdata(file);
+	struct aztech *az = video_drvdata(file);
 
 	switch (ctrl->id) {
-		case V4L2_CID_AUDIO_MUTE:
-			if (ctrl->value) {
-				az_setvol(az,0);
-			} else {
-				az_setvol(az,az->curvol);
-			}
-			return (0);
-		case V4L2_CID_AUDIO_VOLUME:
-			az_setvol(az,ctrl->value);
-			return (0);
+	case V4L2_CID_AUDIO_MUTE:
+		if (ctrl->value)
+			az_setvol(az, 0);
+		else
+			az_setvol(az, az->curvol);
+		return 0;
+	case V4L2_CID_AUDIO_VOLUME:
+		az_setvol(az, ctrl->value);
+		return 0;
 	}
 	return -EINVAL;
 }
 
-static struct az_device aztech_unit;
-
-static int aztech_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0;
-}
-
-static int aztech_exclusive_release(struct file *file)
-{
-	clear_bit(0, &aztech_unit.in_use);
-	return 0;
-}
-
 static const struct v4l2_file_operations aztech_fops = {
 	.owner		= THIS_MODULE,
-	.open           = aztech_exclusive_open,
-	.release        = aztech_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -371,57 +338,60 @@ static const struct v4l2_ioctl_ops aztec
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device aztech_radio = {
-	.name		= "Aztech radio",
-	.fops           = &aztech_fops,
-	.ioctl_ops 	= &aztech_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
-module_param_named(debug,aztech_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
-
 static int __init aztech_init(void)
 {
-	if(io==-1)
-	{
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+	struct aztech *az = &aztech_card;
+	struct v4l2_device *v4l2_dev = &az->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
+	az->io = io;
+
+	if (az->io == -1) {
+		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n");
 		return -EINVAL;
 	}
 
-	if (!request_region(io, 2, "aztech"))
-	{
-		printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
+	if (!request_region(az->io, 2, "aztech")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
 		return -EBUSY;
 	}
 
-	mutex_init(&lock);
-	video_set_drvdata(&aztech_radio, &aztech_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(az->io, 2);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
 
-	if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io,2);
+	mutex_init(&az->lock);
+	strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
+	az->vdev.v4l2_dev = v4l2_dev;
+	az->vdev.fops = &aztech_fops;
+	az->vdev.ioctl_ops = &aztech_ioctl_ops;
+	az->vdev.release = video_device_release_empty;
+	video_set_drvdata(&az->vdev, az);
+
+	if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(az->io, 2);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
+	v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
 	/* mute card - prevents noisy bootups */
-	outb (0, io);
+	outb(0, az->io);
 	return 0;
 }
 
-MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Aztech radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
-
-static void __exit aztech_cleanup(void)
+static void __exit aztech_exit(void)
 {
-	video_unregister_device(&aztech_radio);
-	release_region(io,2);
+	struct aztech *az = &aztech_card;
+
+	video_unregister_device(&az->vdev);
+	v4l2_device_unregister(&az->v4l2_dev);
+	release_region(az->io, 2);
 }
 
 module_init(aztech_init);
-module_exit(aztech_cleanup);
+module_exit(aztech_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-cadet.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-cadet.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-cadet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-cadet.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,333 +35,318 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* V4L2 API defs		*/
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/param.h>
 #include <linux/pnp.h>
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
+MODULE_LICENSE("GPL");
+
+static int io = -1;		/* default to isapnp activation */
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
+module_param(radio_nr, int, 0);
+
+#define CADET_VERSION KERNEL_VERSION(0, 3, 3)
 
 #define RDS_BUFFER 256
 #define RDS_RX_FLAG 1
 #define MBS_RX_FLAG 2
 
-#define CADET_VERSION KERNEL_VERSION(0,3,3)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 0xff,
-		.step          = 1,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
+struct cadet {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
+	int users;
+	int curtuner;
+	int tunestat;
+	int sigstrength;
+	wait_queue_head_t read_queue;
+	struct timer_list readtimer;
+	__u8 rdsin, rdsout, rdsstat;
+	unsigned char rdsbuf[RDS_BUFFER];
+	struct mutex lock;
+	int reading;
 };
 
-static int io=-1;		/* default to isapnp activation */
-static int radio_nr = -1;
-static int users;
-static int curtuner;
-static int tunestat;
-static int sigstrength;
-static wait_queue_head_t read_queue;
-static struct timer_list readtimer;
-static __u8 rdsin, rdsout, rdsstat;
-static unsigned char rdsbuf[RDS_BUFFER];
-static spinlock_t cadet_io_lock;
-
-static int cadet_probe(void);
+static struct cadet cadet_card;
 
 /*
  * Signal Strength Threshold Values
  * The V4L API spec does not define any particular unit for the signal
  * strength value.  These values are in microvolts of RF at the tuner's input.
  */
-static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
+static __u16 sigtable[2][4] = {
+	{  5, 10, 30,  150 },
+	{ 28, 40, 63, 1000 }
+};
 
 
-static int
-cadet_getstereo(void)
+static int cadet_getstereo(struct cadet *dev)
 {
 	int ret = V4L2_TUNER_SUB_MONO;
-	if(curtuner != 0)	/* Only FM has stereo capability! */
+
+	if (dev->curtuner != 0)	/* Only FM has stereo capability! */
 		return V4L2_TUNER_SUB_MONO;
 
-	spin_lock(&cadet_io_lock);
-	outb(7,io);          /* Select tuner control */
-	if( (inb(io+1) & 0x40) == 0)
+	mutex_lock(&dev->lock);
+	outb(7, dev->io);          /* Select tuner control */
+	if ((inb(dev->io + 1) & 0x40) == 0)
 		ret = V4L2_TUNER_SUB_STEREO;
-	spin_unlock(&cadet_io_lock);
+	mutex_unlock(&dev->lock);
 	return ret;
 }
 
-static unsigned
-cadet_gettune(void)
+static unsigned cadet_gettune(struct cadet *dev)
 {
-	int curvol,i;
-	unsigned fifo=0;
+	int curvol, i;
+	unsigned fifo = 0;
 
 	/*
 	 * Prepare for read
 	 */
 
-	spin_lock(&cadet_io_lock);
+	mutex_lock(&dev->lock);
 
-	outb(7,io);       /* Select tuner control */
-	curvol=inb(io+1); /* Save current volume/mute setting */
-	outb(0x00,io+1);  /* Ensure WRITE-ENABLE is LOW */
-	tunestat=0xffff;
+	outb(7, dev->io);       /* Select tuner control */
+	curvol = inb(dev->io + 1); /* Save current volume/mute setting */
+	outb(0x00, dev->io + 1);  /* Ensure WRITE-ENABLE is LOW */
+	dev->tunestat = 0xffff;
 
 	/*
 	 * Read the shift register
 	 */
-	for(i=0;i<25;i++) {
-		fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
-		if(i<24) {
-			outb(0x01,io+1);
-			tunestat&=inb(io+1);
-			outb(0x00,io+1);
+	for (i = 0; i < 25; i++) {
+		fifo = (fifo << 1) | ((inb(dev->io + 1) >> 7) & 0x01);
+		if (i < 24) {
+			outb(0x01, dev->io + 1);
+			dev->tunestat &= inb(dev->io + 1);
+			outb(0x00, dev->io + 1);
 		}
 	}
 
 	/*
 	 * Restore volume/mute setting
 	 */
-	outb(curvol,io+1);
-	spin_unlock(&cadet_io_lock);
+	outb(curvol, dev->io + 1);
+	mutex_unlock(&dev->lock);
 
 	return fifo;
 }
 
-static unsigned
-cadet_getfreq(void)
+static unsigned cadet_getfreq(struct cadet *dev)
 {
 	int i;
-	unsigned freq=0,test,fifo=0;
+	unsigned freq = 0, test, fifo = 0;
 
 	/*
 	 * Read current tuning
 	 */
-	fifo=cadet_gettune();
+	fifo = cadet_gettune(dev);
 
 	/*
 	 * Convert to actual frequency
 	 */
-	if(curtuner==0) {    /* FM */
-		test=12500;
-		for(i=0;i<14;i++) {
-			if((fifo&0x01)!=0) {
-				freq+=test;
-			}
-			test=test<<1;
-			fifo=fifo>>1;
+	if (dev->curtuner == 0) {    /* FM */
+		test = 12500;
+		for (i = 0; i < 14; i++) {
+			if ((fifo & 0x01) != 0)
+				freq += test;
+			test = test << 1;
+			fifo = fifo >> 1;
 		}
-		freq-=10700000;           /* IF frequency is 10.7 MHz */
-		freq=(freq*16)/1000000;   /* Make it 1/16 MHz */
-	}
-	if(curtuner==1) {    /* AM */
-		freq=((fifo&0x7fff)-2010)*16;
+		freq -= 10700000;           /* IF frequency is 10.7 MHz */
+		freq = (freq * 16) / 1000000;   /* Make it 1/16 MHz */
 	}
+	if (dev->curtuner == 1)    /* AM */
+		freq = ((fifo & 0x7fff) - 2010) * 16;
 
 	return freq;
 }
 
-static void
-cadet_settune(unsigned fifo)
+static void cadet_settune(struct cadet *dev, unsigned fifo)
 {
 	int i;
 	unsigned test;
 
-	spin_lock(&cadet_io_lock);
+	mutex_lock(&dev->lock);
 
-	outb(7,io);                /* Select tuner control */
+	outb(7, dev->io);                /* Select tuner control */
 	/*
 	 * Write the shift register
 	 */
-	test=0;
-	test=(fifo>>23)&0x02;      /* Align data for SDO */
-	test|=0x1c;                /* SDM=1, SWE=1, SEN=1, SCK=0 */
-	outb(7,io);                /* Select tuner control */
-	outb(test,io+1);           /* Initialize for write */
-	for(i=0;i<25;i++) {
-		test|=0x01;              /* Toggle SCK High */
-		outb(test,io+1);
-		test&=0xfe;              /* Toggle SCK Low */
-		outb(test,io+1);
-		fifo=fifo<<1;            /* Prepare the next bit */
-		test=0x1c|((fifo>>23)&0x02);
-		outb(test,io+1);
+	test = 0;
+	test = (fifo >> 23) & 0x02;      /* Align data for SDO */
+	test |= 0x1c;                /* SDM=1, SWE=1, SEN=1, SCK=0 */
+	outb(7, dev->io);                /* Select tuner control */
+	outb(test, dev->io + 1);           /* Initialize for write */
+	for (i = 0; i < 25; i++) {
+		test |= 0x01;              /* Toggle SCK High */
+		outb(test, dev->io + 1);
+		test &= 0xfe;              /* Toggle SCK Low */
+		outb(test, dev->io + 1);
+		fifo = fifo << 1;            /* Prepare the next bit */
+		test = 0x1c | ((fifo >> 23) & 0x02);
+		outb(test, dev->io + 1);
 	}
-	spin_unlock(&cadet_io_lock);
+	mutex_unlock(&dev->lock);
 }
 
-static void
-cadet_setfreq(unsigned freq)
+static void cadet_setfreq(struct cadet *dev, unsigned freq)
 {
 	unsigned fifo;
-	int i,j,test;
+	int i, j, test;
 	int curvol;
 
 	/*
 	 * Formulate a fifo command
 	 */
-	fifo=0;
-	if(curtuner==0) {    /* FM */
-		test=102400;
-		freq=(freq*1000)/16;       /* Make it kHz */
-		freq+=10700;               /* IF is 10700 kHz */
-		for(i=0;i<14;i++) {
-			fifo=fifo<<1;
-			if(freq>=test) {
-				fifo|=0x01;
-				freq-=test;
+	fifo = 0;
+	if (dev->curtuner == 0) {    /* FM */
+		test = 102400;
+		freq = (freq * 1000) / 16;       /* Make it kHz */
+		freq += 10700;               /* IF is 10700 kHz */
+		for (i = 0; i < 14; i++) {
+			fifo = fifo << 1;
+			if (freq >= test) {
+				fifo |= 0x01;
+				freq -= test;
 			}
-			test=test>>1;
+			test = test >> 1;
 		}
 	}
-	if(curtuner==1) {    /* AM */
-		fifo=(freq/16)+2010;            /* Make it kHz */
-		fifo|=0x100000;            /* Select AM Band */
+	if (dev->curtuner == 1) {    /* AM */
+		fifo = (freq / 16) + 2010;            /* Make it kHz */
+		fifo |= 0x100000;            /* Select AM Band */
 	}
 
 	/*
 	 * Save current volume/mute setting
 	 */
 
-	spin_lock(&cadet_io_lock);
-	outb(7,io);                /* Select tuner control */
-	curvol=inb(io+1);
-	spin_unlock(&cadet_io_lock);
+	mutex_lock(&dev->lock);
+	outb(7, dev->io);                /* Select tuner control */
+	curvol = inb(dev->io + 1);
+	mutex_unlock(&dev->lock);
 
 	/*
 	 * Tune the card
 	 */
-	for(j=3;j>-1;j--) {
-		cadet_settune(fifo|(j<<16));
+	for (j = 3; j > -1; j--) {
+		cadet_settune(dev, fifo | (j << 16));
 
-		spin_lock(&cadet_io_lock);
-		outb(7,io);         /* Select tuner control */
-		outb(curvol,io+1);
-		spin_unlock(&cadet_io_lock);
+		mutex_lock(&dev->lock);
+		outb(7, dev->io);         /* Select tuner control */
+		outb(curvol, dev->io + 1);
+		mutex_unlock(&dev->lock);
 
 		msleep(100);
 
-		cadet_gettune();
-		if((tunestat & 0x40) == 0) {   /* Tuned */
-			sigstrength=sigtable[curtuner][j];
+		cadet_gettune(dev);
+		if ((dev->tunestat & 0x40) == 0) {   /* Tuned */
+			dev->sigstrength = sigtable[dev->curtuner][j];
 			return;
 		}
 	}
-	sigstrength=0;
+	dev->sigstrength = 0;
 }
 
 
-static int
-cadet_getvol(void)
+static int cadet_getvol(struct cadet *dev)
 {
 	int ret = 0;
 
-	spin_lock(&cadet_io_lock);
+	mutex_lock(&dev->lock);
 
-	outb(7,io);                /* Select tuner control */
-	if((inb(io + 1) & 0x20) != 0)
+	outb(7, dev->io);                /* Select tuner control */
+	if ((inb(dev->io + 1) & 0x20) != 0)
 		ret = 0xffff;
 
-	spin_unlock(&cadet_io_lock);
+	mutex_unlock(&dev->lock);
 	return ret;
 }
 
 
-static void
-cadet_setvol(int vol)
+static void cadet_setvol(struct cadet *dev, int vol)
 {
-	spin_lock(&cadet_io_lock);
-	outb(7,io);                /* Select tuner control */
-	if(vol>0)
-		outb(0x20,io+1);
+	mutex_lock(&dev->lock);
+	outb(7, dev->io);                /* Select tuner control */
+	if (vol > 0)
+		outb(0x20, dev->io + 1);
 	else
-		outb(0x00,io+1);
-	spin_unlock(&cadet_io_lock);
+		outb(0x00, dev->io + 1);
+	mutex_unlock(&dev->lock);
 }
 
-static void
-cadet_handler(unsigned long data)
+static void cadet_handler(unsigned long data)
 {
-	/*
-	 * Service the RDS fifo
-	 */
+	struct cadet *dev = (void *)data;
 
-	if(spin_trylock(&cadet_io_lock))
-	{
-		outb(0x3,io);       /* Select RDS Decoder Control */
-		if((inb(io+1)&0x20)!=0) {
+	/* Service the RDS fifo */
+	if (mutex_trylock(&dev->lock)) {
+		outb(0x3, dev->io);       /* Select RDS Decoder Control */
+		if ((inb(dev->io + 1) & 0x20) != 0)
 			printk(KERN_CRIT "cadet: RDS fifo overflow\n");
-		}
-		outb(0x80,io);      /* Select RDS fifo */
-		while((inb(io)&0x80)!=0) {
-			rdsbuf[rdsin]=inb(io+1);
-			if(rdsin==rdsout)
+		outb(0x80, dev->io);      /* Select RDS fifo */
+		while ((inb(dev->io) & 0x80) != 0) {
+			dev->rdsbuf[dev->rdsin] = inb(dev->io + 1);
+			if (dev->rdsin == dev->rdsout)
 				printk(KERN_WARNING "cadet: RDS buffer overflow\n");
 			else
-				rdsin++;
+				dev->rdsin++;
 		}
-		spin_unlock(&cadet_io_lock);
+		mutex_unlock(&dev->lock);
 	}
 
 	/*
 	 * Service pending read
 	 */
-	if( rdsin!=rdsout)
-		wake_up_interruptible(&read_queue);
+	if (dev->rdsin != dev->rdsout)
+		wake_up_interruptible(&dev->read_queue);
 
 	/*
 	 * Clean up and exit
 	 */
-	init_timer(&readtimer);
-	readtimer.function=cadet_handler;
-	readtimer.data=(unsigned long)0;
-	readtimer.expires=jiffies+msecs_to_jiffies(50);
-	add_timer(&readtimer);
+	init_timer(&dev->readtimer);
+	dev->readtimer.function = cadet_handler;
+	dev->readtimer.data = (unsigned long)0;
+	dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+	add_timer(&dev->readtimer);
 }
 
 
-
-static ssize_t
-cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
+static ssize_t cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
-	int i=0;
+	struct cadet *dev = video_drvdata(file);
 	unsigned char readbuf[RDS_BUFFER];
+	int i = 0;
 
-	if(rdsstat==0) {
-		spin_lock(&cadet_io_lock);
-		rdsstat=1;
-		outb(0x80,io);        /* Select RDS fifo */
-		spin_unlock(&cadet_io_lock);
-		init_timer(&readtimer);
-		readtimer.function=cadet_handler;
-		readtimer.data=(unsigned long)0;
-		readtimer.expires=jiffies+msecs_to_jiffies(50);
-		add_timer(&readtimer);
+	if (dev->rdsstat == 0) {
+		mutex_lock(&dev->lock);
+		dev->rdsstat = 1;
+		outb(0x80, dev->io);        /* Select RDS fifo */
+		mutex_unlock(&dev->lock);
+		init_timer(&dev->readtimer);
+		dev->readtimer.function = cadet_handler;
+		dev->readtimer.data = (unsigned long)dev;
+		dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+		add_timer(&dev->readtimer);
 	}
-	if(rdsin==rdsout) {
+	if (dev->rdsin == dev->rdsout) {
 		if (file->f_flags & O_NONBLOCK)
 			return -EWOULDBLOCK;
-		interruptible_sleep_on(&read_queue);
+		interruptible_sleep_on(&dev->read_queue);
 	}
-	while( i<count && rdsin!=rdsout)
-		readbuf[i++]=rdsbuf[rdsout++];
+	while (i < count && dev->rdsin != dev->rdsout)
+		readbuf[i++] = dev->rdsbuf[dev->rdsout++];
 
-	if (copy_to_user(data,readbuf,i))
+	if (copy_to_user(data, readbuf, i))
 		return -EFAULT;
 	return i;
 }
@@ -370,38 +355,40 @@ cadet_read(struct file *file, char __use
 static int vidioc_querycap(struct file *file, void *priv,
 				struct v4l2_capability *v)
 {
-	v->capabilities =
-		V4L2_CAP_TUNER |
-		V4L2_CAP_READWRITE;
+	strlcpy(v->driver, "ADS Cadet", sizeof(v->driver));
+	strlcpy(v->card, "ADS Cadet", sizeof(v->card));
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = CADET_VERSION;
-	strcpy(v->driver, "ADS Cadet");
-	strcpy(v->card, "ADS Cadet");
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
+	struct cadet *dev = video_drvdata(file);
+
 	v->type = V4L2_TUNER_RADIO;
 	switch (v->index) {
 	case 0:
-		strcpy(v->name, "FM");
+		strlcpy(v->name, "FM", sizeof(v->name));
 		v->capability = V4L2_TUNER_CAP_STEREO;
 		v->rangelow = 1400;     /* 87.5 MHz */
 		v->rangehigh = 1728;    /* 108.0 MHz */
-		v->rxsubchans=cadet_getstereo();
-		switch (v->rxsubchans){
+		v->rxsubchans = cadet_getstereo(dev);
+		switch (v->rxsubchans) {
 		case V4L2_TUNER_SUB_MONO:
 			v->audmode = V4L2_TUNER_MODE_MONO;
 			break;
 		case V4L2_TUNER_SUB_STEREO:
 			v->audmode = V4L2_TUNER_MODE_STEREO;
 			break;
-		default: ;
+		default:
+			break;
 		}
 		break;
 	case 1:
-		strcpy(v->name, "AM");
+		strlcpy(v->name, "AM", sizeof(v->name));
 		v->capability = V4L2_TUNER_CAP_LOW;
 		v->rangelow = 8320;      /* 520 kHz */
 		v->rangehigh = 26400;    /* 1650 kHz */
@@ -411,25 +398,29 @@ static int vidioc_g_tuner(struct file *f
 	default:
 		return -EINVAL;
 	}
-	v->signal = sigstrength; /* We might need to modify scaling of this */
+	v->signal = dev->sigstrength; /* We might need to modify scaling of this */
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	if((v->index != 0)&&(v->index != 1))
+	struct cadet *dev = video_drvdata(file);
+
+	if (v->index != 0 && v->index != 1)
 		return -EINVAL;
-	curtuner = v->index;
+	dev->curtuner = v->index;
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	f->tuner = curtuner;
+	struct cadet *dev = video_drvdata(file);
+
+	f->tuner = dev->curtuner;
 	f->type = V4L2_TUNER_RADIO;
-	f->frequency = cadet_getfreq();
+	f->frequency = cadet_getfreq(dev);
 	return 0;
 }
 
@@ -437,27 +428,26 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
+	struct cadet *dev = video_drvdata(file);
+
 	if (f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
-	if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+	if (dev->curtuner == 0 && (f->frequency < 1400 || f->frequency > 1728))
 		return -EINVAL;
-	if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+	if (dev->curtuner == 1 && (f->frequency < 8320 || f->frequency > 26400))
 		return -EINVAL;
-	cadet_setfreq(f->frequency);
+	cadet_setfreq(dev, f->frequency);
 	return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
 	}
 	return -EINVAL;
 }
@@ -465,12 +455,14 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	switch (ctrl->id){
+	struct cadet *dev = video_drvdata(file);
+
+	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
-		ctrl->value = (cadet_getvol() == 0);
+		ctrl->value = (cadet_getvol(dev) == 0);
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = cadet_getvol();
+		ctrl->value = cadet_getvol(dev);
 		break;
 	default:
 		return -EINVAL;
@@ -481,15 +473,17 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
+	struct cadet *dev = video_drvdata(file);
+
 	switch (ctrl->id){
 	case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
 		if (ctrl->value)
-			cadet_setvol(0);
+			cadet_setvol(dev, 0);
 		else
-			cadet_setvol(0xffff);
+			cadet_setvol(dev, 0xffff);
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
-		cadet_setvol(ctrl->value);
+		cadet_setvol(dev, ctrl->value);
 		break;
 	default:
 		return -EINVAL;
@@ -497,16 +491,6 @@ static int vidioc_s_ctrl(struct file *fi
 	return 0;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -515,43 +499,52 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
+	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)
 {
-	if (a->index != 0)
-		return -EINVAL;
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
-static int
-cadet_open(struct file *file)
+static int cadet_open(struct file *file)
 {
-	users++;
-	if (1 == users) init_waitqueue_head(&read_queue);
+	struct cadet *dev = video_drvdata(file);
+
+	dev->users++;
+	if (1 == dev->users)
+		init_waitqueue_head(&dev->read_queue);
 	return 0;
 }
 
-static int
-cadet_release(struct file *file)
+static int cadet_release(struct file *file)
 {
-	users--;
-	if (0 == users){
-		del_timer_sync(&readtimer);
-		rdsstat=0;
+	struct cadet *dev = video_drvdata(file);
+
+	dev->users--;
+	if (0 == dev->users) {
+		del_timer_sync(&dev->readtimer);
+		dev->rdsstat = 0;
 	}
 	return 0;
 }
 
-static unsigned int
-cadet_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait)
 {
-	poll_wait(file,&read_queue,wait);
-	if(rdsin != rdsout)
+	struct cadet *dev = video_drvdata(file);
+
+	poll_wait(file, &dev->read_queue, wait);
+	if (dev->rdsin != dev->rdsout)
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -581,13 +574,6 @@ static const struct v4l2_ioctl_ops cadet
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-static struct video_device cadet_radio = {
-	.name		= "Cadet radio",
-	.fops           = &cadet_fops,
-	.ioctl_ops 	= &cadet_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 #ifdef CONFIG_PNP
 
 static struct pnp_device_id cadet_pnp_devices[] = {
@@ -598,7 +584,7 @@ static struct pnp_device_id cadet_pnp_de
 
 MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
 
-static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+static int cadet_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
 	if (!dev)
 		return -ENODEV;
@@ -606,13 +592,12 @@ static int cadet_pnp_probe(struct pnp_de
 	if (io > 0)
 		return -EBUSY;
 
-	if (!pnp_port_valid(dev, 0)) {
+	if (!pnp_port_valid(dev, 0))
 		return -ENODEV;
-	}
 
 	io = pnp_port_start(dev, 0);
 
-	printk ("radio-cadet: PnP reports device at %#x\n", io);
+	printk(KERN_INFO "radio-cadet: PnP reports device at %#x\n", io);
 
 	return io;
 }
@@ -628,23 +613,23 @@ static struct pnp_driver cadet_pnp_drive
 static struct pnp_driver cadet_pnp_driver;
 #endif
 
-static int cadet_probe(void)
+static void cadet_probe(struct cadet *dev)
 {
-	static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
+	static int iovals[8] = { 0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e };
 	int i;
 
-	for(i=0;i<8;i++) {
-		io=iovals[i];
-		if (request_region(io, 2, "cadet-probe")) {
-			cadet_setfreq(1410);
-			if(cadet_getfreq()==1410) {
-				release_region(io, 2);
-				return io;
+	for (i = 0; i < 8; i++) {
+		dev->io = iovals[i];
+		if (request_region(dev->io, 2, "cadet-probe")) {
+			cadet_setfreq(dev, 1410);
+			if (cadet_getfreq(dev) == 1410) {
+				release_region(dev->io, 2);
+				return;
 			}
-			release_region(io, 2);
+			release_region(dev->io, 2);
 		}
 	}
-	return -1;
+	dev->io = -1;
 }
 
 /*
@@ -654,59 +639,69 @@ static int cadet_probe(void)
 
 static int __init cadet_init(void)
 {
-	spin_lock_init(&cadet_io_lock);
+	struct cadet *dev = &cadet_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
 
-	/*
-	 *	If a probe was requested then probe ISAPnP first (safest)
-	 */
+	strlcpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name));
+	mutex_init(&dev->lock);
+
+	/* If a probe was requested then probe ISAPnP first (safest) */
 	if (io < 0)
 		pnp_register_driver(&cadet_pnp_driver);
-	/*
-	 *	If that fails then probe unsafely if probe is requested
-	 */
-	if(io < 0)
-		io = cadet_probe ();
+	dev->io = io;
 
-	/*
-	 *	Else we bail out
-	 */
+	/* If that fails then probe unsafely if probe is requested */
+	if (dev->io < 0)
+		cadet_probe(dev);
 
-	if(io < 0) {
+	/* Else we bail out */
+	if (dev->io < 0) {
 #ifdef MODULE
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x330, 0x332, 0x334,\n");
+		v4l2_err(v4l2_dev, "0x336, 0x338, 0x33a, 0x33c or 0x33e\n");
 #endif
 		goto fail;
 	}
-	if (!request_region(io,2,"cadet"))
+	if (!request_region(dev->io, 2, "cadet"))
 		goto fail;
-	if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io,2);
+
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(dev->io, 2);
+		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
 		goto fail;
 	}
-	printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
+
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &cadet_fops;
+	dev->vdev.ioctl_ops = &cadet_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) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(dev->io, 2);
+		goto fail;
+	}
+	v4l2_info(v4l2_dev, "ADS Cadet Radio Card at 0x%x\n", dev->io);
 	return 0;
 fail:
 	pnp_unregister_driver(&cadet_pnp_driver);
-	return -1;
+	return -ENODEV;
 }
 
-
-
-MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
-module_param(radio_nr, int, 0);
-
-static void __exit cadet_cleanup_module(void)
+static void __exit cadet_exit(void)
 {
-	video_unregister_device(&cadet_radio);
-	release_region(io,2);
+	struct cadet *dev = &cadet_card;
+
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+	release_region(dev->io, 2);
 	pnp_unregister_driver(&cadet_pnp_driver);
 }
 
 module_init(cadet_init);
-module_exit(cadet_cleanup_module);
+module_exit(cadet_exit);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-gemtek.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-gemtek.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-gemtek.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-gemtek.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,16 +20,14 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
+#include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
+#include <linux/mutex.h>
+#include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-common.h>
-#include <linux/spinlock.h>
+#include <media/v4l2-device.h>
 
-#include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
-#define RADIO_VERSION KERNEL_VERSION(0,0,3)
-#define RADIO_BANNER "GemTek Radio card driver: v0.0.3"
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 3)
 
 /*
  * Module info.
@@ -57,7 +55,6 @@ static int shutdown	= 1;
 static int keepmuted	= 1;
 static int initmute	= 1;
 static int radio_nr	= -1;
-static unsigned long in_use;
 
 module_param(io, int, 0444);
 MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
@@ -112,12 +109,19 @@ module_param(radio_nr, int, 0444);
 #define SHORT_DELAY 5		/* usec */
 #define LONG_DELAY 75		/* usec */
 
-struct gemtek_device {
+struct gemtek {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct mutex lock;
 	unsigned long lastfreq;
 	int muted;
+	int verified;
+	int io;
 	u32 bu2614data;
 };
 
+static struct gemtek gemtek_card;
+
 #define BU2614_FREQ_BITS 	16 /* D0..D15, Frequency data		*/
 #define BU2614_PORT_BITS	3 /* P0..P2, Output port control data	*/
 #define BU2614_VOID_BITS	4 /* unused 				*/
@@ -153,10 +157,6 @@ struct gemtek_device {
 #define BU2614_FMUN_MASK	MKMASK(FMUN)
 #define BU2614_TEST_MASK	MKMASK(TEST)
 
-static struct gemtek_device gemtek_unit;
-
-static spinlock_t lock;
-
 /*
  * Set data which will be sent to BU2614FS.
  */
@@ -166,33 +166,33 @@ static spinlock_t lock;
 /*
  * Transmit settings to BU2614FS over GemTek IC.
  */
-static void gemtek_bu2614_transmit(struct gemtek_device *dev)
+static void gemtek_bu2614_transmit(struct gemtek *gt)
 {
 	int i, bit, q, mute;
 
-	spin_lock(&lock);
+	mutex_lock(&gt->lock);
 
-	mute = dev->muted ? GEMTEK_MT : 0x00;
+	mute = gt->muted ? GEMTEK_MT : 0x00;
 
-	outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+	outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
 	udelay(SHORT_DELAY);
-	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
 	udelay(LONG_DELAY);
 
-	for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) {
-	    bit = (q & 1) ? GEMTEK_DA : 0;
-	    outb_p(mute | GEMTEK_CE | bit, io);
-	    udelay(SHORT_DELAY);
-	    outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io);
-	    udelay(SHORT_DELAY);
+	for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) {
+		bit = (q & 1) ? GEMTEK_DA : 0;
+		outb_p(mute | GEMTEK_CE | bit, gt->io);
+		udelay(SHORT_DELAY);
+		outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io);
+		udelay(SHORT_DELAY);
 	}
 
-	outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+	outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
 	udelay(SHORT_DELAY);
-	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
 	udelay(LONG_DELAY);
 
-	spin_unlock(&lock);
+	mutex_unlock(&gt->lock);
 }
 
 /*
@@ -206,107 +206,109 @@ static unsigned long gemtek_convfreq(uns
 /*
  * Set FM-frequency.
  */
-static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
 {
-
-	if (keepmuted && hardmute && dev->muted)
+	if (keepmuted && hardmute && gt->muted)
 		return;
 
-	if (freq < GEMTEK_LOWFREQ)
-		freq = GEMTEK_LOWFREQ;
-	else if (freq > GEMTEK_HIGHFREQ)
-		freq = GEMTEK_HIGHFREQ;
+	freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ);
 
-	dev->lastfreq = freq;
-	dev->muted = 0;
+	gt->lastfreq = freq;
+	gt->muted = 0;
 
-	gemtek_bu2614_set(dev, BU2614_PORT, 0);
-	gemtek_bu2614_set(dev, BU2614_FMES, 0);
-	gemtek_bu2614_set(dev, BU2614_SWIN, 0);	/* FM-mode	*/
-	gemtek_bu2614_set(dev, BU2614_SWAL, 0);
-	gemtek_bu2614_set(dev, BU2614_FMUN, 1);	/* GT bit set	*/
-	gemtek_bu2614_set(dev, BU2614_TEST, 0);
+	gemtek_bu2614_set(gt, BU2614_PORT, 0);
+	gemtek_bu2614_set(gt, BU2614_FMES, 0);
+	gemtek_bu2614_set(gt, BU2614_SWIN, 0);	/* FM-mode	*/
+	gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+	gemtek_bu2614_set(gt, BU2614_FMUN, 1);	/* GT bit set	*/
+	gemtek_bu2614_set(gt, BU2614_TEST, 0);
 
-	gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
-	gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq));
+	gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
+	gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq));
 
-	gemtek_bu2614_transmit(dev);
+	gemtek_bu2614_transmit(gt);
 }
 
 /*
  * Set mute flag.
  */
-static void gemtek_mute(struct gemtek_device *dev)
+static void gemtek_mute(struct gemtek *gt)
 {
 	int i;
-	dev->muted = 1;
+
+	gt->muted = 1;
 
 	if (hardmute) {
 		/* Turn off PLL, disable data output */
-		gemtek_bu2614_set(dev, BU2614_PORT, 0);
-		gemtek_bu2614_set(dev, BU2614_FMES, 0);	/* CT bit off	*/
-		gemtek_bu2614_set(dev, BU2614_SWIN, 0);	/* FM-mode	*/
-		gemtek_bu2614_set(dev, BU2614_SWAL, 0);
-		gemtek_bu2614_set(dev, BU2614_FMUN, 0);	/* GT bit off	*/
-		gemtek_bu2614_set(dev, BU2614_TEST, 0);
-		gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_PLL_OFF);
-		gemtek_bu2614_set(dev, BU2614_FREQ, 0);
-		gemtek_bu2614_transmit(dev);
-	} else {
-		spin_lock(&lock);
+		gemtek_bu2614_set(gt, BU2614_PORT, 0);
+		gemtek_bu2614_set(gt, BU2614_FMES, 0);	/* CT bit off	*/
+		gemtek_bu2614_set(gt, BU2614_SWIN, 0);	/* FM-mode	*/
+		gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+		gemtek_bu2614_set(gt, BU2614_FMUN, 0);	/* GT bit off	*/
+		gemtek_bu2614_set(gt, BU2614_TEST, 0);
+		gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
+		gemtek_bu2614_set(gt, BU2614_FREQ, 0);
+		gemtek_bu2614_transmit(gt);
+		return;
+	}
 
-		/* Read bus contents (CE, CK and DA). */
-		i = inb_p(io);
-		/* Write it back with mute flag set. */
-		outb_p((i >> 5) | GEMTEK_MT, io);
-		udelay(SHORT_DELAY);
+	mutex_lock(&gt->lock);
 
-		spin_unlock(&lock);
-	}
+	/* Read bus contents (CE, CK and DA). */
+	i = inb_p(gt->io);
+	/* Write it back with mute flag set. */
+	outb_p((i >> 5) | GEMTEK_MT, gt->io);
+	udelay(SHORT_DELAY);
+
+	mutex_unlock(&gt->lock);
 }
 
 /*
  * Unset mute flag.
  */
-static void gemtek_unmute(struct gemtek_device *dev)
+static void gemtek_unmute(struct gemtek *gt)
 {
 	int i;
-	dev->muted = 0;
 
+	gt->muted = 0;
 	if (hardmute) {
 		/* Turn PLL back on. */
-		gemtek_setfreq(dev, dev->lastfreq);
-	} else {
-		spin_lock(&lock);
+		gemtek_setfreq(gt, gt->lastfreq);
+		return;
+	}
+	mutex_lock(&gt->lock);
 
-		i = inb_p(io);
-		outb_p(i >> 5, io);
-		udelay(SHORT_DELAY);
+	i = inb_p(gt->io);
+	outb_p(i >> 5, gt->io);
+	udelay(SHORT_DELAY);
 
-		spin_unlock(&lock);
-	}
+	mutex_unlock(&gt->lock);
 }
 
 /*
  * Get signal strength (= stereo status).
  */
-static inline int gemtek_getsigstr(void)
+static inline int gemtek_getsigstr(struct gemtek *gt)
 {
-	return inb_p(io) & GEMTEK_NS ? 0 : 1;
+	int sig;
+
+	mutex_lock(&gt->lock);
+	sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1;
+	mutex_unlock(&gt->lock);
+	return sig;
 }
 
 /*
  * Check if requested card acts like GemTek Radio card.
  */
-static int gemtek_verify(int port)
+static int gemtek_verify(struct gemtek *gt, int port)
 {
-	static int verified = -1;
 	int i, q;
 
-	if (verified == port)
+	if (gt->verified == port)
 		return 1;
 
-	spin_lock(&lock);
+	mutex_lock(&gt->lock);
 
 	q = inb_p(port);	/* Read bus contents before probing. */
 	/* Try to turn on CE, CK and DA respectively and check if card responds
@@ -316,15 +318,15 @@ static int gemtek_verify(int port)
 		udelay(SHORT_DELAY);
 
 		if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) {
-			spin_unlock(&lock);
+			mutex_unlock(&gt->lock);
 			return 0;
 		}
 	}
 	outb_p(q >> 5, port);	/* Write bus contents back. */
 	udelay(SHORT_DELAY);
 
-	spin_unlock(&lock);
-	verified = port;
+	mutex_unlock(&gt->lock);
+	gt->verified = port;
 
 	return 1;
 }
@@ -332,42 +334,41 @@ static int gemtek_verify(int port)
 /*
  * Automatic probing for card.
  */
-static int gemtek_probe(void)
+static int gemtek_probe(struct gemtek *gt)
 {
+	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
 	int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
 	int i;
 
 	if (!probe) {
-		printk(KERN_INFO "Automatic device probing disabled.\n");
+		v4l2_info(v4l2_dev, "Automatic device probing disabled.\n");
 		return -1;
 	}
 
-	printk(KERN_INFO "Automatic device probing enabled.\n");
+	v4l2_info(v4l2_dev, "Automatic device probing enabled.\n");
 
 	for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
-		printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]);
+		v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]);
 
 		if (!request_region(ioports[i], 1, "gemtek-probe")) {
-			printk(KERN_WARNING "I/O port 0x%x busy!\n",
+			v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n",
 			       ioports[i]);
 			continue;
 		}
 
-		if (gemtek_verify(ioports[i])) {
-			printk(KERN_INFO "Card found from I/O port "
+		if (gemtek_verify(gt, ioports[i])) {
+			v4l2_info(v4l2_dev, "Card found from I/O port "
 			       "0x%x!\n", ioports[i]);
 
 			release_region(ioports[i], 1);
-
-			io = ioports[i];
-			return io;
+			gt->io = ioports[i];
+			return gt->io;
 		}
 
 		release_region(ioports[i], 1);
 	}
 
-	printk(KERN_ERR "Automatic probing failed!\n");
-
+	v4l2_err(v4l2_dev, "Automatic probing failed!\n");
 	return -1;
 }
 
@@ -375,40 +376,8 @@ static int gemtek_probe(void)
  * Video 4 Linux stuff.
  */
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id = V4L2_CID_AUDIO_MUTE,
-		.name = "Mute",
-		.minimum = 0,
-		.maximum = 1,
-		.default_value = 1,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-	}, {
-		.id = V4L2_CID_AUDIO_VOLUME,
-		.name = "Volume",
-		.minimum = 0,
-		.maximum = 65535,
-		.step = 65535,
-		.default_value = 0xff,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
-
-static int gemtek_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int gemtek_exclusive_release(struct file *file)
-{
-	clear_bit(0, &in_use);
-	return 0;
-}
-
 static const struct v4l2_file_operations gemtek_fops = {
 	.owner		= THIS_MODULE,
-	.open		= gemtek_exclusive_open,
-	.release	= gemtek_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -417,23 +386,25 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
 	strlcpy(v->card, "GemTek", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
 {
+	struct gemtek *gt = video_drvdata(file);
+
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	v->rangelow = GEMTEK_LOWFREQ;
 	v->rangehigh = GEMTEK_HIGHFREQ;
 	v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-	v->signal = 0xffff * gemtek_getsigstr();
+	v->signal = 0xffff * gemtek_getsigstr(gt);
 	if (v->signal) {
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 		v->rxsubchans = V4L2_TUNER_SUB_STEREO;
@@ -441,65 +412,56 @@ static int vidioc_g_tuner(struct file *f
 		v->audmode = V4L2_TUNER_MODE_MONO;
 		v->rxsubchans = V4L2_TUNER_SUB_MONO;
 	}
-
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return (v->index != 0) ? -EINVAL : 0;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
 			      struct v4l2_frequency *f)
 {
-	struct gemtek_device *rt = video_drvdata(file);
-
-	gemtek_setfreq(rt, f->frequency);
+	struct gemtek *gt = video_drvdata(file);
 
+	if (f->tuner != 0)
+		return -EINVAL;
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = gt->lastfreq;
 	return 0;
 }
 
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
 			      struct v4l2_frequency *f)
 {
-	struct gemtek_device *rt = video_drvdata(file);
+	struct gemtek *gt = video_drvdata(file);
 
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = rt->lastfreq;
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+	gemtek_setfreq(gt, f->frequency);
 	return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
 			    struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); ++i) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+	default:
+		return -EINVAL;
 	}
-	return -EINVAL;
 }
 
 static int vidioc_g_ctrl(struct file *file, void *priv,
 			 struct v4l2_control *ctrl)
 {
-	struct gemtek_device *rt = video_drvdata(file);
+	struct gemtek *gt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = rt->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (rt->muted)
-			ctrl->value = 0;
-		else
-			ctrl->value = 65535;
+		ctrl->value = gt->muted;
 		return 0;
 	}
 	return -EINVAL;
@@ -508,35 +470,19 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 			 struct v4l2_control *ctrl)
 {
-	struct gemtek_device *rt = video_drvdata(file);
+	struct gemtek *gt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value)
-			gemtek_mute(rt);
-		else
-			gemtek_unmute(rt);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (ctrl->value)
-			gemtek_unmute(rt);
+			gemtek_mute(gt);
 		else
-			gemtek_mute(rt);
+			gemtek_unmute(gt);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -545,16 +491,20 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
+	return (i != 0) ? -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)
 {
-	if (a->index != 0)
-		return -EINVAL;
-	return 0;
+	return (a->index != 0) ? -EINVAL : 0;
 }
 
 static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
@@ -572,62 +522,73 @@ static const struct v4l2_ioctl_ops gemte
 	.vidioc_s_ctrl		= vidioc_s_ctrl
 };
 
-static struct video_device gemtek_radio = {
-	.name		= "GemTek Radio card",
-	.fops		= &gemtek_fops,
-	.ioctl_ops 	= &gemtek_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 /*
  * Initialization / cleanup related stuff.
  */
 
-/*
- * Initilize card.
- */
 static int __init gemtek_init(void)
 {
-	printk(KERN_INFO RADIO_BANNER "\n");
+	struct gemtek *gt = &gemtek_card;
+	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+	int res;
 
-	spin_lock_init(&lock);
+	strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name));
 
-	gemtek_probe();
-	if (io) {
-		if (!request_region(io, 1, "gemtek")) {
-			printk(KERN_ERR "I/O port 0x%x already in use.\n", io);
+	v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n");
+
+	mutex_init(&gt->lock);
+
+	gt->verified = -1;
+	gt->io = io;
+	gemtek_probe(gt);
+	if (gt->io) {
+		if (!request_region(gt->io, 1, "gemtek")) {
+			v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io);
 			return -EBUSY;
 		}
 
-		if (!gemtek_verify(io))
-			printk(KERN_WARNING "Card at I/O port 0x%x does not "
+		if (!gemtek_verify(gt, gt->io))
+			v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not "
 			       "respond properly, check your "
-			       "configuration.\n", io);
+			       "configuration.\n", gt->io);
 		else
-			printk(KERN_INFO "Using I/O port 0x%x.\n", io);
+			v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io);
 	} else if (probe) {
-		printk(KERN_ERR "Automatic probing failed and no "
+		v4l2_err(v4l2_dev, "Automatic probing failed and no "
 		       "fixed I/O port defined.\n");
 		return -ENODEV;
 	} else {
-		printk(KERN_ERR "Automatic probing disabled but no fixed "
+		v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed "
 		       "I/O port defined.");
 		return -EINVAL;
 	}
 
-	video_set_drvdata(&gemtek_radio, &gemtek_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		release_region(gt->io, 1);
+		return res;
+	}
 
-	if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 1);
+	strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name));
+	gt->vdev.v4l2_dev = v4l2_dev;
+	gt->vdev.fops = &gemtek_fops;
+	gt->vdev.ioctl_ops = &gemtek_ioctl_ops;
+	gt->vdev.release = video_device_release_empty;
+	video_set_drvdata(&gt->vdev, gt);
+
+	if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(gt->io, 1);
 		return -EBUSY;
 	}
 
 	/* Set defaults */
-	gemtek_unit.lastfreq = GEMTEK_LOWFREQ;
-	gemtek_unit.bu2614data = 0;
+	gt->lastfreq = GEMTEK_LOWFREQ;
+	gt->bu2614data = 0;
 
 	if (initmute)
-		gemtek_mute(&gemtek_unit);
+		gemtek_mute(gt);
 
 	return 0;
 }
@@ -637,15 +598,19 @@ static int __init gemtek_init(void)
  */
 static void __exit gemtek_exit(void)
 {
+	struct gemtek *gt = &gemtek_card;
+	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+
 	if (shutdown) {
 		hardmute = 1;	/* Turn off PLL */
-		gemtek_mute(&gemtek_unit);
+		gemtek_mute(gt);
 	} else {
-		printk(KERN_INFO "Module unloaded but card not muted!\n");
+		v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n");
 	}
 
-	video_unregister_device(&gemtek_radio);
-	release_region(io, 1);
+	video_unregister_device(&gt->vdev);
+	v4l2_device_unregister(&gt->v4l2_dev);
+	release_region(gt->io, 1);
 }
 
 module_init(gemtek_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-gemtek-pci.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-gemtek-pci.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-gemtek-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-gemtek-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,34 +45,25 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/errno.h>
-
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#include <linux/io.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 65535,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>");
+MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card");
+MODULE_LICENSE("GPL");
 
-#include <asm/io.h>
-#include <asm/uaccess.h>
+static int nr_radio = -1;
+static int mx = 1;
+
+module_param(mx, bool, 0);
+MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not");
+module_param(nr_radio, int, 0);
+MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
 
 #ifndef PCI_VENDOR_ID_GEMTEK
 #define PCI_VENDOR_ID_GEMTEK 0x5046
@@ -90,8 +81,11 @@ static struct v4l2_queryctrl radio_qctrl
 #define GEMTEK_PCI_RANGE_HIGH (108*16000)
 #endif
 
-struct gemtek_pci_card {
-	struct video_device *videodev;
+struct gemtek_pci {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct mutex lock;
+	struct pci_dev *pdev;
 
 	u32 iobase;
 	u32 length;
@@ -100,116 +94,133 @@ struct gemtek_pci_card {
 	u8  mute;
 };
 
-static int nr_radio = -1;
-static unsigned long in_use;
+static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev);
+}
 
-static inline u8 gemtek_pci_out( u16 value, u32 port )
+static inline u8 gemtek_pci_out(u16 value, u32 port)
 {
-	outw( value, port );
+	outw(value, port);
 
 	return (u8)value;
 }
 
-#define _b0( v ) *((u8 *)&v)
-static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
+#define _b0(v) (*((u8 *)&v))
+
+static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)
 {
-	register u8 byte = *last_byte;
+	u8 byte = *last_byte;
 
-	if ( !value ) {
-		if ( !keep )
+	if (!value) {
+		if (!keep)
 			value = (u16)port;
 		byte &= 0xfd;
 	} else
 		byte |= 2;
 
-	_b0( value ) = byte;
-	outw( value, port );
+	_b0(value) = byte;
+	outw(value, port);
 	byte |= 1;
-	_b0( value ) = byte;
-	outw( value, port );
+	_b0(value) = byte;
+	outw(value, port);
 	byte &= 0xfe;
-	_b0( value ) = byte;
-	outw( value, port );
+	_b0(value) = byte;
+	outw(value, port);
 
 	*last_byte = byte;
 }
 
-static inline void gemtek_pci_nil( u32 port, u8 *last_byte )
+static inline void gemtek_pci_nil(u32 port, u8 *last_byte)
 {
-	__gemtek_pci_cmd( 0x00, port, last_byte, false );
+	__gemtek_pci_cmd(0x00, port, last_byte, false);
 }
 
-static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte )
+static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)
 {
-	__gemtek_pci_cmd( cmd, port, last_byte, true );
+	__gemtek_pci_cmd(cmd, port, last_byte, true);
 }
 
-static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency )
+static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)
 {
-	register int i;
-	register u32 value = frequency / 200 + 856;
-	register u16 mask = 0x8000;
+	int i;
+	u32 value = frequency / 200 + 856;
+	u16 mask = 0x8000;
 	u8 last_byte;
 	u32 port = card->iobase;
 
-	last_byte = gemtek_pci_out( 0x06, port );
+	mutex_lock(&card->lock);
+	card->current_frequency = frequency;
+	last_byte = gemtek_pci_out(0x06, port);
 
 	i = 0;
 	do {
-		gemtek_pci_nil( port, &last_byte );
+		gemtek_pci_nil(port, &last_byte);
 		i++;
-	} while ( i < 9 );
+	} while (i < 9);
 
 	i = 0;
 	do {
-		gemtek_pci_cmd( value & mask, port, &last_byte );
+		gemtek_pci_cmd(value & mask, port, &last_byte);
 		mask >>= 1;
 		i++;
-	} while ( i < 16 );
+	} while (i < 16);
 
-	outw( 0x10, port );
+	outw(0x10, port);
+	mutex_unlock(&card->lock);
 }
 
 
-static inline void gemtek_pci_mute( struct gemtek_pci_card *card )
+static void gemtek_pci_mute(struct gemtek_pci *card)
 {
-	outb( 0x1f, card->iobase );
+	mutex_lock(&card->lock);
+	outb(0x1f, card->iobase);
 	card->mute = true;
+	mutex_unlock(&card->lock);
 }
 
-static inline void gemtek_pci_unmute( struct gemtek_pci_card *card )
+static void gemtek_pci_unmute(struct gemtek_pci *card)
 {
-	if ( card->mute ) {
-		gemtek_pci_setfrequency( card, card->current_frequency );
+	mutex_lock(&card->lock);
+	if (card->mute) {
+		gemtek_pci_setfrequency(card, card->current_frequency);
 		card->mute = false;
 	}
+	mutex_unlock(&card->lock);
 }
 
-static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
+static int gemtek_pci_getsignal(struct gemtek_pci *card)
 {
-	return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
+	int sig;
+
+	mutex_lock(&card->lock);
+	sig = (inb(card->iobase) & 0x08) ? 0 : 1;
+	mutex_unlock(&card->lock);
+	return sig;
 }
 
 static int vidioc_querycap(struct file *file, void *priv,
 					struct v4l2_capability *v)
 {
+	struct gemtek_pci *card = video_drvdata(file);
+
 	strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
 	strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	struct gemtek_pci_card *card = video_drvdata(file);
+	struct gemtek_pci *card = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	v->rangelow = GEMTEK_PCI_RANGE_LOW;
 	v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
@@ -223,21 +234,18 @@ static int vidioc_g_tuner(struct file *f
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct gemtek_pci_card *card = video_drvdata(file);
+	struct gemtek_pci *card = video_drvdata(file);
 
-	if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
-			(f->frequency > GEMTEK_PCI_RANGE_HIGH) )
+	if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
+	    f->frequency > GEMTEK_PCI_RANGE_HIGH)
 		return -EINVAL;
 	gemtek_pci_setfrequency(card, f->frequency);
-	card->current_frequency = f->frequency;
 	card->mute = false;
 	return 0;
 }
@@ -245,7 +253,7 @@ static int vidioc_s_frequency(struct fil
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct gemtek_pci_card *card = video_drvdata(file);
+	struct gemtek_pci *card = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = card->current_frequency;
@@ -255,13 +263,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
 	}
 	return -EINVAL;
 }
@@ -269,7 +275,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct gemtek_pci_card *card = video_drvdata(file);
+	struct gemtek_pci *card = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -288,7 +294,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct gemtek_pci_card *card = video_drvdata(file);
+	struct gemtek_pci *card = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -307,17 +313,6 @@ static int vidioc_s_ctrl(struct file *fi
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -326,17 +321,22 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
+	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)
 {
-	if (a->index != 0)
-		return -EINVAL;
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 enum {
@@ -354,25 +354,10 @@ static struct pci_device_id gemtek_pci_i
 	{ 0 }
 };
 
-MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
-
-static int mx = 1;
-
-static int gemtek_pci_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int gemtek_pci_exclusive_release(struct file *file)
-{
-	clear_bit(0, &in_use);
-	return 0;
-}
+MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
 
 static const struct v4l2_file_operations gemtek_pci_fops = {
 	.owner		= THIS_MODULE,
-	.open           = gemtek_pci_exclusive_open,
-	.release        = gemtek_pci_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -391,108 +376,100 @@ static const struct v4l2_ioctl_ops gemte
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device vdev_template = {
-	.name          	= "Gemtek PCI Radio",
-	.fops          	= &gemtek_pci_fops,
-	.ioctl_ops 	= &gemtek_pci_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
-static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
+static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 {
-	struct gemtek_pci_card *card;
-	struct video_device *devradio;
+	struct gemtek_pci *card;
+	struct v4l2_device *v4l2_dev;
+	int res;
 
-	if ( (card = kzalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) {
-		printk( KERN_ERR "gemtek_pci: out of memory\n" );
+	card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL);
+	if (card == NULL) {
+		dev_err(&pdev->dev, "out of memory\n");
 		return -ENOMEM;
 	}
 
-	if ( pci_enable_device( pci_dev ) )
-		goto err_pci;
+	v4l2_dev = &card->v4l2_dev;
+	mutex_init(&card->lock);
+	card->pdev = pdev;
 
-	card->iobase = pci_resource_start( pci_dev, 0 );
-	card->length = pci_resource_len( pci_dev, 0 );
+	strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name));
 
-	if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) {
-		printk( KERN_ERR "gemtek_pci: i/o port already in use\n" );
-		goto err_pci;
+	res = v4l2_device_register(&pdev->dev, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		kfree(card);
+		return res;
 	}
 
-	pci_set_drvdata( pci_dev, card );
+	if (pci_enable_device(pdev))
+		goto err_pci;
 
-	if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) {
-		printk( KERN_ERR "gemtek_pci: out of memory\n" );
-		goto err_video;
+	card->iobase = pci_resource_start(pdev, 0);
+	card->length = pci_resource_len(pdev, 0);
+
+	if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
+		v4l2_err(v4l2_dev, "i/o port already in use\n");
+		goto err_pci;
 	}
-	*devradio = vdev_template;
 
-	if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
-		kfree( devradio );
+	strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name));
+	card->vdev.v4l2_dev = v4l2_dev;
+	card->vdev.fops = &gemtek_pci_fops;
+	card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops;
+	card->vdev.release = video_device_release_empty;
+	video_set_drvdata(&card->vdev, card);
+
+	if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
 		goto err_video;
-	}
 
-	card->videodev = devradio;
-	video_set_drvdata(devradio, card);
-	gemtek_pci_mute( card );
+	gemtek_pci_mute(card);
 
-	printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
-		pci_dev->revision, card->iobase, card->iobase + card->length - 1 );
+	v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
+		pdev->revision, card->iobase, card->iobase + card->length - 1);
 
 	return 0;
 
 err_video:
-	release_region( card->iobase, card->length );
+	release_region(card->iobase, card->length);
 
 err_pci:
-	kfree( card );
+	v4l2_device_unregister(v4l2_dev);
+	kfree(card);
 	return -ENODEV;
 }
 
-static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
+static void __devexit gemtek_pci_remove(struct pci_dev *pdev)
 {
-	struct gemtek_pci_card *card = pci_get_drvdata( pci_dev );
-
-	video_unregister_device( card->videodev );
-	kfree( card->videodev );
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct gemtek_pci *card = to_gemtek_pci(v4l2_dev);
 
-	release_region( card->iobase, card->length );
+	video_unregister_device(&card->vdev);
+	v4l2_device_unregister(v4l2_dev);
 
-	if ( mx )
-		gemtek_pci_mute( card );
+	release_region(card->iobase, card->length);
 
-	kfree( card );
+	if (mx)
+		gemtek_pci_mute(card);
 
-	pci_set_drvdata( pci_dev, NULL );
+	kfree(card);
 }
 
-static struct pci_driver gemtek_pci_driver =
-{
+static struct pci_driver gemtek_pci_driver = {
 	.name		= "gemtek_pci",
 	.id_table	= gemtek_pci_id,
 	.probe		= gemtek_pci_probe,
 	.remove		= __devexit_p(gemtek_pci_remove),
 };
 
-static int __init gemtek_pci_init_module( void )
+static int __init gemtek_pci_init(void)
 {
-	return pci_register_driver( &gemtek_pci_driver );
+	return pci_register_driver(&gemtek_pci_driver);
 }
 
-static void __exit gemtek_pci_cleanup_module( void )
+static void __exit gemtek_pci_exit(void)
 {
 	pci_unregister_driver(&gemtek_pci_driver);
 }
 
-MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" );
-MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
-MODULE_LICENSE("GPL");
-
-module_param(mx, bool, 0);
-MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
-module_param(nr_radio, int, 0);
-MODULE_PARM_DESC( nr_radio, "video4linux device number to use");
-
-module_init( gemtek_pci_init_module );
-module_exit( gemtek_pci_cleanup_module );
-
+module_init(gemtek_pci_init);
+module_exit(gemtek_pci_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-maestro.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-maestro.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-maestro.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-maestro.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,27 +22,22 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/pci.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,6)
-#define DRIVER_VERSION	"0.06"
+MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	}
-};
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
+#define DRIVER_VERSION	"0.06"
 
 #define GPIO_DATA	0x60   /* port offset from ESS_IO_BASE */
 
@@ -72,62 +67,27 @@ static struct v4l2_queryctrl radio_qctrl
 
 #define BITS2FREQ(x)	((x) * FREQ_STEP - FREQ_IF)
 
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-static unsigned long in_use;
-
-static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+struct maestro {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct pci_dev *pdev;
+	struct mutex lock;
 
-static int maestro_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
+	u16	io;	/* base of Maestro card radio io (GPIO_DATA)*/
+	u16	muted;	/* VIDEO_AUDIO_MUTE */
+	u16	stereo;	/* VIDEO_TUNER_STEREO_ON */
+	u16	tuned;	/* signal strength (0 or 0xffff) */
+};
 
-static int maestro_exclusive_release(struct file *file)
+static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
 {
-	clear_bit(0, &in_use);
-	return 0;
+	return container_of(v4l2_dev, struct maestro, v4l2_dev);
 }
 
-static void maestro_remove(struct pci_dev *pdev);
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
-		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-		.class_mask = 0xffff00 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
-		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-		.class_mask = 0xffff00 },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
-	.name		= "maestro_radio",
-	.id_table	= maestro_r_pci_tbl,
-	.probe		= maestro_probe,
-	.remove		= __devexit_p(maestro_remove),
-};
-
-static const struct v4l2_file_operations maestro_fops = {
-	.owner		= THIS_MODULE,
-	.open           = maestro_exclusive_open,
-	.release        = maestro_exclusive_release,
-	.ioctl		= video_ioctl2,
-};
-
-struct radio_device {
-	u16	io,	/* base of Maestro card radio io (GPIO_DATA)*/
-		muted,	/* VIDEO_AUDIO_MUTE */
-		stereo,	/* VIDEO_TUNER_STEREO_ON */
-		tuned;	/* signal strength (0 or 0xffff) */
-};
-
-static u32 radio_bits_get(struct radio_device *dev)
+static u32 radio_bits_get(struct maestro *dev)
 {
-	register u16 io=dev->io, l, rdata;
-	register u32 data=0;
+	u16 io = dev->io, l, rdata;
+	u32 data = 0;
 	u16 omask;
 
 	omask = inw(io + IO_MASK);
@@ -135,25 +95,23 @@ static u32 radio_bits_get(struct radio_d
 	outw(0, io);
 	udelay(16);
 
-	for (l=24;l--;) {
+	for (l = 24; l--;) {
 		outw(STR_CLK, io);		/* HI state */
 		udelay(2);
-		if(!l)
+		if (!l)
 			dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
 		outw(0, io);			/* LO state */
 		udelay(2);
 		data <<= 1;			/* shift data */
 		rdata = inw(io);
-		if(!l)
-			dev->stereo =  rdata & STR_MOST ?
-			0 : 1;
-		else
-			if(rdata & STR_DATA)
-				data++;
+		if (!l)
+			dev->stereo = (rdata & STR_MOST) ?  0 : 1;
+		else if (rdata & STR_DATA)
+			data++;
 		udelay(2);
 	}
 
-	if(dev->muted)
+	if (dev->muted)
 		outw(STR_WREN, io);
 
 	udelay(4);
@@ -162,18 +120,18 @@ static u32 radio_bits_get(struct radio_d
 	return data & 0x3ffe;
 }
 
-static void radio_bits_set(struct radio_device *dev, u32 data)
+static void radio_bits_set(struct maestro *dev, u32 data)
 {
-	register u16 io=dev->io, l, bits;
+	u16 io = dev->io, l, bits;
 	u16 omask, odir;
 
 	omask = inw(io + IO_MASK);
-	odir  = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+	odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
 	outw(odir | STR_DATA, io + IO_DIR);
 	outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
 	udelay(16);
-	for (l=25;l;l--) {
-		bits = ((data >> 18) & STR_DATA) | STR_WREN ;
+	for (l = 25; l; l--) {
+		bits = ((data >> 18) & STR_DATA) | STR_WREN;
 		data <<= 1;			/* shift data */
 		outw(bits, io);			/* start strobe */
 		udelay(2);
@@ -183,7 +141,7 @@ static void radio_bits_set(struct radio_
 		udelay(4);
 	}
 
-	if(!dev->muted)
+	if (!dev->muted)
 		outw(0, io);
 
 	udelay(4);
@@ -195,78 +153,79 @@ static void radio_bits_set(struct radio_
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
+	struct maestro *dev = video_drvdata(file);
+
 	strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
 	strlcpy(v->card, "Maestro Radio", sizeof(v->card));
-	sprintf(v->bus_info, "PCI");
+	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maestro *dev = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	(void)radio_bits_get(card);
+	mutex_lock(&dev->lock);
+	radio_bits_get(dev);
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	v->rangelow = FREQ_LO;
 	v->rangehigh = FREQ_HI;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	v->capability = V4L2_TUNER_CAP_LOW;
-	if(card->stereo)
+	if (dev->stereo)
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 	else
 		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = card->tuned;
+	v->signal = dev->tuned;
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maestro *dev = video_drvdata(file);
 
 	if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
 		return -EINVAL;
-	radio_bits_set(card, FREQ2BITS(f->frequency));
+	mutex_lock(&dev->lock);
+	radio_bits_set(dev, FREQ2BITS(f->frequency));
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maestro *dev = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
-	f->frequency = BITS2FREQ(radio_bits_get(card));
+	mutex_lock(&dev->lock);
+	f->frequency = BITS2FREQ(radio_bits_get(dev));
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
 	}
 	return -EINVAL;
 }
@@ -274,11 +233,11 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maestro *dev = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = card->muted;
+		ctrl->value = dev->muted;
 		return 0;
 	}
 	return -EINVAL;
@@ -287,34 +246,26 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct radio_device *card = video_drvdata(file);
-	register u16 io = card->io;
-	register u16 omask = inw(io + IO_MASK);
+	struct maestro *dev = video_drvdata(file);
+	u16 io = dev->io;
+	u16 omask;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
+		mutex_lock(&dev->lock);
+		omask = inw(io + IO_MASK);
 		outw(~STR_WREN, io + IO_MASK);
-		outw((card->muted = ctrl->value ) ?
-				STR_WREN : 0, io);
+		dev->muted = ctrl->value;
+		outw(dev->muted ? STR_WREN : 0, io);
 		udelay(4);
 		outw(omask, io + IO_MASK);
 		msleep(125);
+		mutex_unlock(&dev->lock);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -323,20 +274,45 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
+	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)
 {
-	if (a->index != 0)
-		return -EINVAL;
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
-static u16 __devinit radio_power_on(struct radio_device *dev)
+static const struct v4l2_file_operations maestro_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
+	.vidioc_querycap    = vidioc_querycap,
+	.vidioc_g_tuner     = vidioc_g_tuner,
+	.vidioc_s_tuner     = vidioc_s_tuner,
+	.vidioc_g_audio     = vidioc_g_audio,
+	.vidioc_s_audio     = vidioc_s_audio,
+	.vidioc_g_input     = vidioc_g_input,
+	.vidioc_s_input     = vidioc_s_input,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+	.vidioc_queryctrl   = vidioc_queryctrl,
+	.vidioc_g_ctrl      = vidioc_g_ctrl,
+	.vidioc_s_ctrl      = vidioc_s_ctrl,
+};
+
+static u16 __devinit radio_power_on(struct maestro *dev)
 {
 	register u16 io = dev->io;
 	register u32 ofreq;
@@ -360,33 +336,11 @@ static u16 __devinit radio_power_on(stru
 	return (ofreq == radio_bits_get(dev));
 }
 
-static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-};
-
-static struct video_device maestro_radio = {
-	.name           = "Maestro radio",
-	.fops           = &maestro_fops,
-	.ioctl_ops 	= &maestro_ioctl_ops,
-	.release	= video_device_release,
-};
-
 static int __devinit maestro_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
-	struct radio_device *radio_unit;
-	struct video_device *maestro_radio_inst;
+	struct maestro *dev;
+	struct v4l2_device *v4l2_dev;
 	int retval;
 
 	retval = pci_enable_device(pdev);
@@ -397,46 +351,53 @@ static int __devinit maestro_probe(struc
 
 	retval = -ENOMEM;
 
-	radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
-	if (radio_unit == NULL) {
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
 		dev_err(&pdev->dev, "not enough memory\n");
 		goto err;
 	}
 
-	radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
+	v4l2_dev = &dev->v4l2_dev;
+	mutex_init(&dev->lock);
+	dev->pdev = pdev;
 
-	maestro_radio_inst = video_device_alloc();
-	if (maestro_radio_inst == NULL) {
-		dev_err(&pdev->dev, "not enough memory\n");
+	strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
+
+	retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+	if (retval < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
 		goto errfr;
 	}
 
-	memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
-	video_set_drvdata(maestro_radio_inst, radio_unit);
-	pci_set_drvdata(pdev, maestro_radio_inst);
+	dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
 
-	retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &maestro_fops;
+	dev->vdev.ioctl_ops = &maestro_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
+
+	retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
 	if (retval) {
-		printk(KERN_ERR "can't register video device!\n");
+		v4l2_err(v4l2_dev, "can't register video device!\n");
 		goto errfr1;
 	}
 
-	if (!radio_power_on(radio_unit)) {
+	if (!radio_power_on(dev)) {
 		retval = -EIO;
 		goto errunr;
 	}
 
-	dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ "  "
-		 __DATE__ "\n");
-	dev_info(&pdev->dev, "radio chip initialized\n");
+	v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
 
 	return 0;
 errunr:
-	video_unregister_device(maestro_radio_inst);
+	video_unregister_device(&dev->vdev);
 errfr1:
-	video_device_release(maestro_radio_inst);
+	v4l2_device_unregister(v4l2_dev);
 errfr:
-	kfree(radio_unit);
+	kfree(dev);
 err:
 	return retval;
 
@@ -444,11 +405,31 @@ err:
 
 static void __devexit maestro_remove(struct pci_dev *pdev)
 {
-	struct video_device *vdev = pci_get_drvdata(pdev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct maestro *dev = to_maestro(v4l2_dev);
 
-	video_unregister_device(vdev);
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
 }
 
+static struct pci_device_id maestro_r_pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
+		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+		.class_mask = 0xffff00 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
+		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+		.class_mask = 0xffff00 },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
+
+static struct pci_driver maestro_r_driver = {
+	.name		= "maestro_radio",
+	.id_table	= maestro_r_pci_tbl,
+	.probe		= maestro_probe,
+	.remove		= __devexit_p(maestro_remove),
+};
+
 static int __init maestro_radio_init(void)
 {
 	int retval = pci_register_driver(&maestro_r_driver);
@@ -466,7 +447,3 @@ static void __exit maestro_radio_exit(vo
 
 module_init(maestro_radio_init);
 module_exit(maestro_radio_exit);
-
-MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-maxiradio.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-maxiradio.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-maxiradio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-maxiradio.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,38 +37,32 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include <linux/mutex.h>
-
 #include <linux/pci.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
+#include <linux/io.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#define DRIVER_VERSION	"0.77"
+MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
+MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
+MODULE_LICENSE("GPL");
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,7,7)
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
 
-static struct video_device maxiradio_radio;
+static int debug;
 
-#define dprintk(num, fmt, arg...)                                          \
-	do {                                                               \
-		if (maxiradio_radio.debug >= num)                          \
-			printk(KERN_DEBUG "%s: " fmt,                      \
-				maxiradio_radio.name, ## arg); } while (0)
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	}
-};
+#define DRIVER_VERSION	"0.77"
+
+#define RADIO_VERSION KERNEL_VERSION(0, 7, 7)
+
+#define dprintk(dev, num, fmt, arg...) \
+	v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg)
 
 #ifndef PCI_VENDOR_ID_GUILLEMOT
 #define PCI_VENDOR_ID_GUILLEMOT 0x5046
@@ -80,90 +74,70 @@ static struct v4l2_queryctrl radio_qctrl
 
 
 /* TEA5757 pin mappings */
-static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-static unsigned long in_use;
+static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
 
-#define FREQ_LO		 50*16000
-#define FREQ_HI		150*16000
+#define FREQ_LO		(50 * 16000)
+#define FREQ_HI		(150 * 16000)
 
 #define FREQ_IF         171200 /* 10.7*16000   */
 #define FREQ_STEP       200    /* 12.5*16      */
 
 /* (x==fmhz*16*1000) -> bits */
-#define FREQ2BITS(x)	((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1)) \
-			/(FREQ_STEP<<2))<<2)
+#define FREQ2BITS(x) \
+  ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2)
 
 #define BITS2FREQ(x)	((x) * FREQ_STEP - FREQ_IF)
 
 
-static int maxiradio_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int maxiradio_exclusive_release(struct file *file)
+struct maxiradio
 {
-	clear_bit(0, &in_use);
-	return 0;
-}
-
-static const struct v4l2_file_operations maxiradio_fops = {
-	.owner		= THIS_MODULE,
-	.open           = maxiradio_exclusive_open,
-	.release        = maxiradio_exclusive_release,
-	.ioctl          = video_ioctl2,
-};
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct pci_dev *pdev;
 
-static struct radio_device
-{
-	__u16	io,	/* base of radio io */
-		muted,	/* VIDEO_AUDIO_MUTE */
-		stereo,	/* VIDEO_TUNER_STEREO_ON */
-		tuned;	/* signal strength (0 or 0xffff) */
+	u16	io;	/* base of radio io */
+	u16	muted;	/* VIDEO_AUDIO_MUTE */
+	u16	stereo;	/* VIDEO_TUNER_STEREO_ON */
+	u16	tuned;	/* signal strength (0 or 0xffff) */
 
 	unsigned long freq;
 
 	struct mutex lock;
-} radio_unit = {
-	.muted =1,
-	.freq = FREQ_LO,
 };
 
-static void outbit(unsigned long bit, __u16 io)
+static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev)
 {
-	if (bit != 0)
-		{
-			outb(  power|wren|data     ,io); udelay(4);
-			outb(  power|wren|data|clk ,io); udelay(4);
-			outb(  power|wren|data     ,io); udelay(4);
-		}
-	else
-		{
-			outb(  power|wren          ,io); udelay(4);
-			outb(  power|wren|clk      ,io); udelay(4);
-			outb(  power|wren          ,io); udelay(4);
-		}
+	return container_of(v4l2_dev, struct maxiradio, v4l2_dev);
 }
 
-static void turn_power(__u16 io, int p)
+static void outbit(unsigned long bit, u16 io)
+{
+	int val = power | wren | (bit ? data : 0);
+
+	outb(val, io);
+	udelay(4);
+	outb(val | clk, io);
+	udelay(4);
+	outb(val, io);
+	udelay(4);
+}
+
+static void turn_power(struct maxiradio *dev, int p)
 {
 	if (p != 0) {
-		dprintk(1, "Radio powered on\n");
-		outb(power, io);
+		dprintk(dev, 1, "Radio powered on\n");
+		outb(power, dev->io);
 	} else {
-		dprintk(1, "Radio powered off\n");
-		outb(0,io);
+		dprintk(dev, 1, "Radio powered off\n");
+		outb(0, dev->io);
 	}
 }
 
-static void set_freq(__u16 io, __u32 freq)
+static void set_freq(struct maxiradio *dev, u32 freq)
 {
 	unsigned long int si;
 	int bl;
+	int io = dev->io;
 	int val = FREQ2BITS(freq);
 
 	/* TEA5757 shift register bits (see pdf) */
@@ -188,14 +162,14 @@ static void set_freq(__u16 io, __u32 fre
 		si >>= 1;
 	}
 
-	dprintk(1, "Radio freq set to %d.%02d MHz\n",
+	dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n",
 				freq / 16000,
 				freq % 16000 * 100 / 16000);
 
-	turn_power(io, 1);
+	turn_power(dev, 1);
 }
 
-static int get_stereo(__u16 io)
+static int get_stereo(u16 io)
 {
 	outb(power,io);
 	udelay(4);
@@ -203,7 +177,7 @@ static int get_stereo(__u16 io)
 	return !(inb(io) & mo_st);
 }
 
-static int get_tune(__u16 io)
+static int get_tune(u16 io)
 {
 	outb(power+clk,io);
 	udelay(4);
@@ -212,95 +186,84 @@ static int get_tune(__u16 io)
 }
 
 
-static int vidioc_querycap (struct file *file, void  *priv,
+static int vidioc_querycap(struct file *file, void  *priv,
 			    struct v4l2_capability *v)
 {
-	strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver));
-	strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card));
-	sprintf(v->bus_info,"ISA");
-	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	struct maxiradio *dev = video_drvdata(file);
 
+	strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver));
+	strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card));
+	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
+	v->version = RADIO_VERSION;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
 			   struct v4l2_tuner *v)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maxiradio *dev = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	memset(v,0,sizeof(*v));
-	strcpy(v->name, "FM");
+	mutex_lock(&dev->lock);
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-
-	v->rangelow=FREQ_LO;
-	v->rangehigh=FREQ_HI;
-	v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
-	v->capability=V4L2_TUNER_CAP_LOW;
-	if(get_stereo(card->io))
+	v->rangelow = FREQ_LO;
+	v->rangehigh = FREQ_HI;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	if (get_stereo(dev->io))
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 	else
 		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal=0xffff*get_tune(card->io);
+	v->signal = 0xffff * get_tune(dev->io);
+	mutex_unlock(&dev->lock);
 
 	return 0;
 }
 
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
 			   struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
-			   struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "FM");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
+	return v->index ? -EINVAL : 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)
 {
-	if (i != 0)
-		return -EINVAL;
+	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,
+static int vidioc_s_audio(struct file *file, void *priv,
 			   struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
-
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
 			       struct v4l2_frequency *f)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maxiradio *dev = video_drvdata(file);
 
 	if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
-		dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
+		dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
 					f->frequency / 16000,
 					f->frequency % 16000 * 100 / 16000,
 					FREQ_LO / 16000, FREQ_HI / 16000);
@@ -308,75 +271,79 @@ static int vidioc_s_frequency (struct fi
 		return -EINVAL;
 	}
 
-	card->freq = f->frequency;
-	set_freq(card->io, card->freq);
+	mutex_lock(&dev->lock);
+	dev->freq = f->frequency;
+	set_freq(dev, dev->freq);
 	msleep(125);
+	mutex_unlock(&dev->lock);
 
 	return 0;
 }
 
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
 			       struct v4l2_frequency *f)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maxiradio *dev = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
-	f->frequency = card->freq;
+	f->frequency = dev->freq;
 
-	dprintk(4, "radio freq is %d.%02d MHz",
+	dprintk(dev, 4, "radio freq is %d.%02d MHz",
 				f->frequency / 16000,
 				f->frequency % 16000 * 100 / 16000);
 
 	return 0;
 }
 
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
 			     struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return (0);
-		}
+	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)
+static int vidioc_g_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maxiradio *dev = video_drvdata(file);
 
 	switch (ctrl->id) {
-		case V4L2_CID_AUDIO_MUTE:
-			ctrl->value=card->muted;
-			return (0);
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = dev->muted;
+		return 0;
 	}
 
 	return -EINVAL;
 }
 
-static int vidioc_s_ctrl (struct file *file, void *priv,
-			  struct v4l2_control *ctrl)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
 {
-	struct radio_device *card = video_drvdata(file);
+	struct maxiradio *dev = video_drvdata(file);
 
 	switch (ctrl->id) {
-		case V4L2_CID_AUDIO_MUTE:
-			card->muted = ctrl->value;
-			if(card->muted)
-				turn_power(card->io, 0);
-			else
-				set_freq(card->io, card->freq);
-			return 0;
+	case V4L2_CID_AUDIO_MUTE:
+		mutex_lock(&dev->lock);
+		dev->muted = ctrl->value;
+		if (dev->muted)
+			turn_power(dev, 0);
+		else
+			set_freq(dev, dev->freq);
+		mutex_unlock(&dev->lock);
+		return 0;
 	}
 
 	return -EINVAL;
 }
 
+static const struct v4l2_file_operations maxiradio_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl          = video_ioctl2,
+};
+
 static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
@@ -392,60 +359,84 @@ static const struct v4l2_ioctl_ops maxir
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device maxiradio_radio = {
-	.name		= "Maxi Radio FM2000 radio",
-	.fops           = &maxiradio_fops,
-	.ioctl_ops 	= &maxiradio_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	if(!request_region(pci_resource_start(pdev, 0),
+	struct maxiradio *dev;
+	struct v4l2_device *v4l2_dev;
+	int retval = -ENOMEM;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&pdev->dev, "not enough memory\n");
+		return -ENOMEM;
+	}
+
+	v4l2_dev = &dev->v4l2_dev;
+	mutex_init(&dev->lock);
+	dev->pdev = pdev;
+	dev->muted = 1;
+	dev->freq = FREQ_LO;
+
+	strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name));
+
+	retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+	if (retval < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		goto errfr;
+	}
+
+	if (!request_region(pci_resource_start(pdev, 0),
 			   pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
-		printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
+		v4l2_err(v4l2_dev, "can't reserve I/O ports\n");
 		goto err_out;
 	}
 
 	if (pci_enable_device(pdev))
 		goto err_out_free_region;
 
-	radio_unit.io = pci_resource_start(pdev, 0);
-	mutex_init(&radio_unit.lock);
-	video_set_drvdata(&maxiradio_radio, &radio_unit);
+	dev->io = pci_resource_start(pdev, 0);
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &maxiradio_fops;
+	dev->vdev.ioctl_ops = &maxiradio_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
 
-	if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		printk("radio-maxiradio: can't register device!");
+	if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_err(v4l2_dev, "can't register device!");
 		goto err_out_free_region;
 	}
 
-	printk(KERN_INFO "radio-maxiradio: version "
-	       DRIVER_VERSION
-	       " time "
-	       __TIME__ "  "
-	       __DATE__
-	       "\n");
+	v4l2_info(v4l2_dev, "version " DRIVER_VERSION
+			" time " __TIME__ "  " __DATE__ "\n");
 
-	printk(KERN_INFO "radio-maxiradio: found Guillemot MAXI Radio device (io = 0x%x)\n",
-	       radio_unit.io);
+	v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n",
+	       dev->io);
 	return 0;
 
 err_out_free_region:
 	release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 err_out:
+	v4l2_device_unregister(v4l2_dev);
+errfr:
+	kfree(dev);
 	return -ENODEV;
 }
 
 static void __devexit maxiradio_remove_one(struct pci_dev *pdev)
 {
-	video_unregister_device(&maxiradio_radio);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct maxiradio *dev = to_maxiradio(v4l2_dev);
+
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
 	release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 }
 
 static struct pci_device_id maxiradio_pci_tbl[] = {
 	{ PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO,
 		PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0,}
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
@@ -469,10 +460,3 @@ static void __exit maxiradio_radio_exit(
 
 module_init(maxiradio_radio_init);
 module_exit(maxiradio_radio_exit);
-
-MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
-MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
-MODULE_LICENSE("GPL");
-
-module_param_named(debug,maxiradio_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-mr800.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-mr800.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-mr800.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-mr800.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,7 @@
  */
 
 /*
- * Big thanks to authors of dsbr100.c and radio-si470x.c
+ * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
  *
  * When work was looked pretty good, i discover this:
  * http://av-usbradio.sourceforge.net/index.php
@@ -30,18 +30,24 @@
  * Latest release of theirs project was in 2005.
  * Probably, this driver could be improved trough using their
  * achievements (specifications given).
- * So, we have smth to begin with.
+ * 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.
+ * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
  *
- * History:
  * Version 0.01:	First working version.
  * 			It's required to blacklist AverMedia USB Radio
  * 			in usbhid/hid-quirks.c
+ * Version 0.10:	A lot of cleanups and fixes: unpluging the device,
+ * 			few mutex locks were added, codinstyle issues, etc.
+ * 			Added stereo support. Thanks to
+ * 			Douglas Schilling Landgraf <dougsland@gmail.com> and
+ * 			David Ellingsworth <david@identd.dyndns.org>
+ * 			for discussion, help and support.
+ * Version 0.11:	Converted to v4l2_device.
  *
  * Many things to do:
  * 	- Correct power managment of device (suspend & resume)
- * 	- Make x86 independance (little-endian and big-endian stuff)
  * 	- Add code for scanning and smooth tuning
- * 	- Checked and add stereo&mono stuff
  * 	- Add code for sensitivity value
  * 	- Correct mistakes
  * 	- In Japan another FREQ_MIN and FREQ_MAX
@@ -54,7 +60,7 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/usb.h>
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO */
@@ -62,8 +68,8 @@
 /* driver and module definitions */
 #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
 #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
-#define DRIVER_VERSION "0.01"
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 1)
+#define DRIVER_VERSION "0.11"
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -87,43 +93,27 @@ devices, that would be 76 and 91.  */
 #define FREQ_MAX 108.0
 #define FREQ_MUL 16000
 
+/*
+ * Commands that device should understand
+ * List isnt full and will be updated with implementation of new functions
+ */
+#define AMRADIO_SET_FREQ	0xa4
+#define AMRADIO_SET_MUTE	0xab
+#define AMRADIO_SET_MONO	0xae
+
+/* Comfortable defines for amradio_set_mute */
+#define AMRADIO_START		0x00
+#define AMRADIO_STOP		0x01
+
+/* Comfortable defines for amradio_set_stereo */
+#define WANT_STEREO		0x00
+#define WANT_MONO		0x01
+
 /* module parameter */
 static int radio_nr = -1;
 module_param(radio_nr, int, 0);
 MODULE_PARM_DESC(radio_nr, "Radio Nr");
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.step	       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},
-/* HINT: the disabled controls are only here to satify kradio and such apps */
-	{	.id		= V4L2_CID_AUDIO_VOLUME,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_BALANCE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_BASS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_TREBLE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_LOUDNESS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-};
-
 static int usb_amradio_probe(struct usb_interface *intf,
 			     const struct usb_device_id *id);
 static void usb_amradio_disconnect(struct usb_interface *intf);
@@ -138,6 +128,7 @@ struct amradio_device {
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
 	struct video_device *videodev;
+	struct v4l2_device v4l2_dev;
 
 	unsigned char *buffer;
 	struct mutex lock;	/* buffer locking */
@@ -169,43 +160,48 @@ static struct usb_driver usb_amradio_dri
 	.supports_autosuspend	= 0,
 };
 
-/* switch on radio. Send 8 bytes to device. */
-static int amradio_start(struct amradio_device *radio)
+/* switch on/off the radio. Send 8 bytes to device */
+static int amradio_set_mute(struct amradio_device *radio, char argument)
 {
 	int retval;
 	int size;
 
+	/* safety check */
+	if (radio->removed)
+		return -EIO;
+
 	mutex_lock(&radio->lock);
 
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
 	radio->buffer[2] = 0xaa;
 	radio->buffer[3] = 0x00;
-	radio->buffer[4] = 0xab;
-	radio->buffer[5] = 0x00;
+	radio->buffer[4] = AMRADIO_SET_MUTE;
+	radio->buffer[5] = argument;
 	radio->buffer[6] = 0x00;
 	radio->buffer[7] = 0x00;
 
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval) {
+	if (retval < 0 || size != BUFFER_LENGTH) {
 		mutex_unlock(&radio->lock);
 		return retval;
 	}
 
-	radio->muted = 0;
+	radio->muted = argument;
 
 	mutex_unlock(&radio->lock);
 
 	return retval;
 }
 
-/* switch off radio */
-static int amradio_stop(struct amradio_device *radio)
+/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
+static int amradio_setfreq(struct amradio_device *radio, int freq)
 {
 	int retval;
 	int size;
+	unsigned short freq_send = 0x10 + (freq >> 3) / 25;
 
 	/* safety check */
 	if (radio->removed)
@@ -216,33 +212,46 @@ static int amradio_stop(struct amradio_d
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
 	radio->buffer[2] = 0xaa;
-	radio->buffer[3] = 0x00;
-	radio->buffer[4] = 0xab;
-	radio->buffer[5] = 0x01;
+	radio->buffer[3] = 0x03;
+	radio->buffer[4] = AMRADIO_SET_FREQ;
+	radio->buffer[5] = 0x00;
 	radio->buffer[6] = 0x00;
-	radio->buffer[7] = 0x00;
+	radio->buffer[7] = 0x08;
 
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval) {
+	if (retval < 0 || size != BUFFER_LENGTH) {
 		mutex_unlock(&radio->lock);
 		return retval;
 	}
 
-	radio->muted = 1;
+	/* frequency is calculated from freq_send and placed in first 2 bytes */
+	radio->buffer[0] = (freq_send >> 8) & 0xff;
+	radio->buffer[1] = freq_send & 0xff;
+	radio->buffer[2] = 0x01;
+	radio->buffer[3] = 0x00;
+	radio->buffer[4] = 0x00;
+	/* 5 and 6 bytes of buffer already = 0x00 */
+	radio->buffer[7] = 0x00;
+
+	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;
+	}
 
 	mutex_unlock(&radio->lock);
 
 	return retval;
 }
 
-/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
-static int amradio_setfreq(struct amradio_device *radio, int freq)
+static int amradio_set_stereo(struct amradio_device *radio, char argument)
 {
 	int retval;
 	int size;
-	unsigned short freq_send = 0x13 + (freq >> 3) / 25;
 
 	/* safety check */
 	if (radio->removed)
@@ -253,50 +262,33 @@ static int amradio_setfreq(struct amradi
 	radio->buffer[0] = 0x00;
 	radio->buffer[1] = 0x55;
 	radio->buffer[2] = 0xaa;
-	radio->buffer[3] = 0x03;
-	radio->buffer[4] = 0xa4;
-	radio->buffer[5] = 0x00;
-	radio->buffer[6] = 0x00;
-	radio->buffer[7] = 0x08;
-
-	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
-		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
-
-	if (retval) {
-		mutex_unlock(&radio->lock);
-		return retval;
-	}
-
-	/* frequency is calculated from freq_send and placed in first 2 bytes */
-	radio->buffer[0] = (freq_send >> 8) & 0xff;
-	radio->buffer[1] = freq_send & 0xff;
-	radio->buffer[2] = 0x01;
 	radio->buffer[3] = 0x00;
-	radio->buffer[4] = 0x00;
-	/* 5 and 6 bytes of buffer already = 0x00 */
+	radio->buffer[4] = AMRADIO_SET_MONO;
+	radio->buffer[5] = argument;
+	radio->buffer[6] = 0x00;
 	radio->buffer[7] = 0x00;
 
 	retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
 		(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
 
-	if (retval) {
+	if (retval < 0 || size != BUFFER_LENGTH) {
+		radio->stereo = -1;
 		mutex_unlock(&radio->lock);
 		return retval;
 	}
 
-	radio->stereo = 0;
+	radio->stereo = 1;
 
 	mutex_unlock(&radio->lock);
 
 	return retval;
 }
 
-/* USB subsystem interface begins here */
-
-/* handle unplugging of the device, release data structures
-if nothing keeps us from doing it.  If something is still
-keeping us busy, the release callback of v4l will take care
-of releasing it. */
+/* Handle unplugging the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_amradio_device_release.
+ */
 static void usb_amradio_disconnect(struct usb_interface *intf)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
@@ -307,15 +299,18 @@ static void usb_amradio_disconnect(struc
 
 	usb_set_intfdata(intf, NULL);
 	video_unregister_device(radio->videodev);
+	v4l2_device_disconnect(&radio->v4l2_dev);
 }
 
 /* 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);
+
 	strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
 	strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
-	sprintf(v->bus_info, "USB");
+	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
 	v->capabilities = V4L2_CAP_TUNER;
 	return 0;
@@ -326,6 +321,7 @@ static int vidioc_g_tuner(struct file *f
 				struct v4l2_tuner *v)
 {
 	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 	/* safety check */
 	if (radio->removed)
@@ -337,7 +333,16 @@ static int vidioc_g_tuner(struct file *f
 /* TODO: Add function which look is signal stereo or not
  * 	amradio_getstat(radio);
  */
-	radio->stereo = -1;
+
+/* we call amradio_set_stereo to set radio->stereo
+ * Honestly, amradio_getstat should cover this in future and
+ * 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;
 	v->rangelow = FREQ_MIN * FREQ_MUL;
@@ -358,6 +363,7 @@ static int vidioc_s_tuner(struct file *f
 				struct v4l2_tuner *v)
 {
 	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 	/* safety check */
 	if (radio->removed)
@@ -365,6 +371,25 @@ static int vidioc_s_tuner(struct file *f
 
 	if (v->index > 0)
 		return -EINVAL;
+
+	/* mono/stereo selector */
+	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;
 }
 
@@ -373,13 +398,18 @@ static int vidioc_s_frequency(struct fil
 				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;
-	if (amradio_setfreq(radio, radio->curfreq) < 0)
+	mutex_unlock(&radio->lock);
+
+	retval = amradio_setfreq(radio, radio->curfreq);
+	if (retval < 0)
 		amradio_dev_warn(&radio->videodev->dev,
 			"set frequency failed\n");
 	return 0;
@@ -404,14 +434,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
 	}
+
 	return -EINVAL;
 }
 
@@ -438,6 +465,7 @@ static int vidioc_s_ctrl(struct file *fi
 				struct v4l2_control *ctrl)
 {
 	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 	/* safety check */
 	if (radio->removed)
@@ -446,13 +474,15 @@ static int vidioc_s_ctrl(struct file *fi
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value) {
-			if (amradio_stop(radio) < 0) {
+			retval = amradio_set_mute(radio, AMRADIO_STOP);
+			if (retval < 0) {
 				amradio_dev_warn(&radio->videodev->dev,
 					"amradio_stop failed\n");
 				return -1;
 			}
 		} else {
-			if (amradio_start(radio) < 0) {
+			retval = amradio_set_mute(radio, AMRADIO_START);
+			if (retval < 0) {
 				amradio_dev_warn(&radio->videodev->dev,
 					"amradio_start failed\n");
 				return -1;
@@ -503,20 +533,29 @@ static int vidioc_s_input(struct file *f
 static int usb_amradio_open(struct file *file)
 {
 	struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+	int retval;
 
 	lock_kernel();
 
 	radio->users = 1;
 	radio->muted = 1;
 
-	if (amradio_start(radio) < 0) {
+	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;
 	}
-	if (amradio_setfreq(radio, radio->curfreq) < 0)
+
+	retval = amradio_set_stereo(radio, WANT_STEREO);
+	if (retval < 0)
+		amradio_dev_warn(&radio->videodev->dev,
+			"set stereo failed\n");
+
+	retval = amradio_setfreq(radio, radio->curfreq);
+	if (retval < 0)
 		amradio_dev_warn(&radio->videodev->dev,
 			"set frequency failed\n");
 
@@ -533,10 +572,12 @@ static int usb_amradio_close(struct file
 	if (!radio)
 		return -ENODEV;
 
+	mutex_lock(&radio->lock);
 	radio->users = 0;
+	mutex_unlock(&radio->lock);
 
 	if (!radio->removed) {
-		retval = amradio_stop(radio);
+		retval = amradio_set_mute(radio, AMRADIO_STOP);
 		if (retval < 0)
 			amradio_dev_warn(&radio->videodev->dev,
 				"amradio_stop failed\n");
@@ -549,8 +590,10 @@ static int usb_amradio_close(struct file
 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct amradio_device *radio = usb_get_intfdata(intf);
+	int retval;
 
-	if (amradio_stop(radio) < 0)
+	retval = amradio_set_mute(radio, AMRADIO_STOP);
+	if (retval < 0)
 		dev_warn(&intf->dev, "amradio_stop failed\n");
 
 	dev_info(&intf->dev, "going into suspend..\n");
@@ -562,8 +605,10 @@ 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;
 
-	if (amradio_start(radio) < 0)
+	retval = amradio_set_mute(radio, AMRADIO_START);
+	if (retval < 0)
 		dev_warn(&intf->dev, "amradio_start failed\n");
 
 	dev_info(&intf->dev, "coming out of suspend..\n");
@@ -594,67 +639,82 @@ static const struct v4l2_ioctl_ops usb_a
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-static void usb_amradio_device_release(struct video_device *videodev)
+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);
 
+	v4l2_device_unregister(&radio->v4l2_dev);
+
 	/* free rest memory */
 	kfree(radio->buffer);
 	kfree(radio);
 }
 
-/* V4L2 interface */
-static struct video_device amradio_videodev_template = {
-	.name		= "AverMedia MR 800 USB FM Radio",
-	.fops		= &usb_amradio_fops,
-	.ioctl_ops 	= &usb_amradio_ioctl_ops,
-	.release	= usb_amradio_device_release,
-};
-
-/* check if the device is present and register with v4l and
-usb if it is */
+/* check if the device is present and register with v4l and usb if it is */
 static int usb_amradio_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 {
 	struct amradio_device *radio;
+	struct v4l2_device *v4l2_dev;
+	int retval;
 
-	radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
+	radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
 
-	if (!(radio))
+	if (!radio) {
+		dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
 		return -ENOMEM;
+	}
 
 	radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
 
-	if (!(radio->buffer)) {
+	if (!radio->buffer) {
+		dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
 		kfree(radio);
 		return -ENOMEM;
 	}
 
+	v4l2_dev = &radio->v4l2_dev;
+	retval = v4l2_device_register(&intf->dev, 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)) {
+	if (!radio->videodev) {
+		dev_err(&intf->dev, "video_device_alloc failed\n");
 		kfree(radio->buffer);
 		kfree(radio);
 		return -ENOMEM;
 	}
 
-	memcpy(radio->videodev, &amradio_videodev_template,
-		sizeof(amradio_videodev_template));
+	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;
 
 	radio->removed = 0;
 	radio->users = 0;
 	radio->usbdev = interface_to_usbdev(intf);
 	radio->curfreq = 95.16 * FREQ_MUL;
+	radio->stereo = -1;
 
 	mutex_init(&radio->lock);
 
 	video_set_drvdata(radio->videodev, radio);
-	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
-		dev_warn(&intf->dev, "could not register video device\n");
+
+	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;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-rtrack2.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-rtrack2.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-rtrack2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-rtrack2.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,34 +13,16 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-
+#include <linux/mutex.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 65535,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_LICENSE("GPL");
 
 #ifndef CONFIG_RADIO_RTRACK2_PORT
 #define CONFIG_RADIO_RTRACK2_PORT -1
@@ -48,79 +30,88 @@ static struct v4l2_queryctrl radio_qctrl
 
 static int io = CONFIG_RADIO_RTRACK2_PORT;
 static int radio_nr = -1;
-static spinlock_t lock;
 
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack2
 {
-	unsigned long in_use;
-	int port;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	unsigned long curfreq;
 	int muted;
+	struct mutex lock;
 };
 
+static struct rtrack2 rtrack2_card;
+
 
 /* local things */
 
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack2 *dev)
 {
-	if(dev->muted)
+	if (dev->muted)
 		return;
-	spin_lock(&lock);
-	outb(1, io);
-	spin_unlock(&lock);
+	mutex_lock(&dev->lock);
+	outb(1, dev->io);
+	mutex_unlock(&dev->lock);
 	dev->muted = 1;
 }
 
-static void rt_unmute(struct rt_device *dev)
+static void rt_unmute(struct rtrack2 *dev)
 {
 	if(dev->muted == 0)
 		return;
-	spin_lock(&lock);
-	outb(0, io);
-	spin_unlock(&lock);
+	mutex_lock(&dev->lock);
+	outb(0, dev->io);
+	mutex_unlock(&dev->lock);
 	dev->muted = 0;
 }
 
-static void zero(void)
+static void zero(struct rtrack2 *dev)
 {
-	outb_p(1, io);
-	outb_p(3, io);
-	outb_p(1, io);
+	outb_p(1, dev->io);
+	outb_p(3, dev->io);
+	outb_p(1, dev->io);
 }
 
-static void one(void)
+static void one(struct rtrack2 *dev)
 {
-	outb_p(5, io);
-	outb_p(7, io);
-	outb_p(5, io);
+	outb_p(5, dev->io);
+	outb_p(7, dev->io);
+	outb_p(5, dev->io);
 }
 
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack2 *dev, unsigned long freq)
 {
 	int i;
 
+	mutex_lock(&dev->lock);
+	dev->curfreq = freq;
 	freq = freq / 200 + 856;
 
-	spin_lock(&lock);
-
-	outb_p(0xc8, io);
-	outb_p(0xc9, io);
-	outb_p(0xc9, io);
+	outb_p(0xc8, dev->io);
+	outb_p(0xc9, dev->io);
+	outb_p(0xc9, dev->io);
 
 	for (i = 0; i < 10; i++)
-		zero ();
+		zero(dev);
 
 	for (i = 14; i >= 0; i--)
 		if (freq & (1 << i))
-			one ();
+			one(dev);
 		else
-			zero ();
+			zero(dev);
 
-	outb_p(0xc8, io);
+	outb_p(0xc8, dev->io);
 	if (!dev->muted)
-		outb_p(0, io);
+		outb_p(0, dev->io);
 
-	spin_unlock(&lock);
+	mutex_unlock(&dev->lock);
 	return 0;
 }
 
@@ -129,61 +120,61 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
 	strlcpy(v->card, "RadioTrack II", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack2 *dev)
 {
-	if (inb(io) & 2)	/* bit set = no signal present	*/
-		return 0;
-	return 1;		/* signal present		*/
+	int sig = 1;
+
+	mutex_lock(&dev->lock);
+	if (inb(dev->io) & 2)	/* bit set = no signal present	*/
+		sig = 0;
+	mutex_unlock(&dev->lock);
+	return sig;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack2 *rt = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (88*16000);
-	v->rangehigh = (108*16000);
+	v->rangelow = 88 * 16000;
+	v->rangehigh = 108 * 16000;
 	v->rxsubchans = V4L2_TUNER_SUB_MONO;
 	v->capability = V4L2_TUNER_CAP_LOW;
 	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF*rt_getsigstr(rt);
+	v->signal = 0xFFFF * rt_getsigstr(rt);
 	return 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack2 *rt = video_drvdata(file);
 
-	rt->curfreq = f->frequency;
-	rt_setfreq(rt, rt->curfreq);
+	rt_setfreq(rt, f->frequency);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack2 *rt = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = rt->curfreq;
@@ -193,14 +184,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
 	}
 	return -EINVAL;
 }
@@ -208,7 +196,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack2 *rt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -227,7 +215,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct rt_device *rt = video_drvdata(file);
+	struct rtrack2 *rt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -246,17 +234,6 @@ static int vidioc_s_ctrl(struct file *fi
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -265,36 +242,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 				struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct rt_device rtrack2_unit;
-
-static int rtrack2_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0;
-}
-
-static int rtrack2_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+				struct v4l2_audio *a)
 {
-	clear_bit(0, &rtrack2_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations rtrack2_fops = {
 	.owner		= THIS_MODULE,
-	.open           = rtrack2_exclusive_open,
-	.release        = rtrack2_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -313,62 +280,61 @@ static const struct v4l2_ioctl_ops rtrac
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-static struct video_device rtrack2_radio = {
-	.name		= "RadioTrack II radio",
-	.fops           = &rtrack2_fops,
-	.ioctl_ops 	= &rtrack2_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init rtrack2_init(void)
 {
-	if(io==-1)
-	{
-		printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
+	struct rtrack2 *dev = &rtrack2_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
+	dev->io = io;
+	if (dev->io == -1) {
+		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n");
 		return -EINVAL;
 	}
-	if (!request_region(io, 4, "rtrack2"))
-	{
-		printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+	if (!request_region(dev->io, 4, "rtrack2")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
 		return -EBUSY;
 	}
 
-	video_set_drvdata(&rtrack2_radio, &rtrack2_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(dev->io, 4);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
 
-	spin_lock_init(&lock);
-	if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 4);
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &rtrack2_fops;
+	dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
+	dev->vdev.release = video_device_release_empty;
+	video_set_drvdata(&dev->vdev, dev);
+
+	mutex_init(&dev->lock);
+	if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(dev->io, 4);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+	v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
 
 	/* mute card - prevents noisy bootups */
-	outb(1, io);
-	rtrack2_unit.muted = 1;
+	outb(1, dev->io);
+	dev->muted = 1;
 
 	return 0;
 }
 
-MODULE_AUTHOR("Ben Pfaff");
-MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit rtrack2_cleanup_module(void)
+static void __exit rtrack2_exit(void)
 {
-	video_unregister_device(&rtrack2_radio);
-	release_region(io,4);
+	struct rtrack2 *dev = &rtrack2_card;
+
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+	release_region(dev->io, 4);
 }
 
 module_init(rtrack2_init);
-module_exit(rtrack2_cleanup_module);
-
-/*
-  Local variables:
-  compile-command: "mmake"
-  End:
-*/
+module_exit(rtrack2_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-sf16fmi.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-sf16fmi.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-sf16fmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-sf16fmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,113 +22,109 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/isapnp.h>
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/mutex.h>
+#include <linux/videodev2.h>	/* kernel radio structs		*/
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
+MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_LICENSE("GPL");
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	}
-};
+static int io = -1;
+static int radio_nr = -1;
 
-struct fmi_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct fmi
 {
-	unsigned long in_use;
-	int port;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	int curvol; /* 1 or 0 */
 	unsigned long curfreq; /* freq in kHz */
 	__u32 flags;
+	struct mutex lock;
 };
 
-static int io = -1;
-static int radio_nr = -1;
-static struct pnp_dev *dev = NULL;
-static struct mutex lock;
+static struct fmi fmi_card;
+static struct pnp_dev *dev;
 
 /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
 /* It is only useful to give freq in intervall of 800 (=0.05Mhz),
  * other bits will be truncated, e.g 92.7400016 -> 92.7, but
  * 92.7400017 -> 92.75
  */
-#define RSF16_ENCODE(x)	((x)/800+214)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x)	((x) / 800 + 214)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
 
-static void outbits(int bits, unsigned int data, int port)
+static void outbits(int bits, unsigned int data, int io)
 {
-	while(bits--) {
-		if(data & 1) {
-			outb(5, port);
+	while (bits--) {
+		if (data & 1) {
+			outb(5, io);
 			udelay(6);
-			outb(7, port);
+			outb(7, io);
 			udelay(6);
 		} else {
-			outb(1, port);
+			outb(1, io);
 			udelay(6);
-			outb(3, port);
+			outb(3, io);
 			udelay(6);
 		}
-		data>>=1;
+		data >>= 1;
 	}
 }
 
-static inline void fmi_mute(int port)
+static inline void fmi_mute(struct fmi *fmi)
 {
-	mutex_lock(&lock);
-	outb(0x00, port);
-	mutex_unlock(&lock);
+	mutex_lock(&fmi->lock);
+	outb(0x00, fmi->io);
+	mutex_unlock(&fmi->lock);
 }
 
-static inline void fmi_unmute(int port)
+static inline void fmi_unmute(struct fmi *fmi)
 {
-	mutex_lock(&lock);
-	outb(0x08, port);
-	mutex_unlock(&lock);
+	mutex_lock(&fmi->lock);
+	outb(0x08, fmi->io);
+	mutex_unlock(&fmi->lock);
 }
 
-static inline int fmi_setfreq(struct fmi_device *dev)
+static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
 {
-	int myport = dev->port;
-	unsigned long freq = dev->curfreq;
-
-	mutex_lock(&lock);
+	mutex_lock(&fmi->lock);
+	fmi->curfreq = freq;
 
-	outbits(16, RSF16_ENCODE(freq), myport);
-	outbits(8, 0xC0, myport);
+	outbits(16, RSF16_ENCODE(freq), fmi->io);
+	outbits(8, 0xC0, fmi->io);
 	msleep(143);		/* was schedule_timeout(HZ/7) */
-	mutex_unlock(&lock);
-	if (dev->curvol) fmi_unmute(myport);
+	mutex_unlock(&fmi->lock);
+	if (fmi->curvol)
+		fmi_unmute(fmi);
 	return 0;
 }
 
-static inline int fmi_getsigstr(struct fmi_device *dev)
+static inline int fmi_getsigstr(struct fmi *fmi)
 {
 	int val;
 	int res;
-	int myport = dev->port;
 
-
-	mutex_lock(&lock);
-	val = dev->curvol ? 0x08 : 0x00;	/* unmute/mute */
-	outb(val, myport);
-	outb(val | 0x10, myport);
+	mutex_lock(&fmi->lock);
+	val = fmi->curvol ? 0x08 : 0x00;	/* unmute/mute */
+	outb(val, fmi->io);
+	outb(val | 0x10, fmi->io);
 	msleep(143); 		/* was schedule_timeout(HZ/7) */
-	res = (int)inb(myport+1);
-	outb(val, myport);
+	res = (int)inb(fmi->io + 1);
+	outb(val, fmi->io);
 
-	mutex_unlock(&lock);
+	mutex_unlock(&fmi->lock);
 	return (res & 2) ? 0 : 0xFFFF;
 }
 
@@ -137,9 +133,9 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
 	strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
@@ -147,18 +143,18 @@ static int vidioc_g_tuner(struct file *f
 					struct v4l2_tuner *v)
 {
 	int mult;
-	struct fmi_device *fmi = video_drvdata(file);
+	struct fmi *fmi = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
-	v->rangelow = RSF16_MINFREQ/mult;
-	v->rangehigh = RSF16_MAXFREQ/mult;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
-	v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+	v->rangelow = RSF16_MINFREQ / mult;
+	v->rangehigh = RSF16_MAXFREQ / mult;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	v->capability = fmi->flags & V4L2_TUNER_CAP_LOW;
 	v->audmode = V4L2_TUNER_MODE_STEREO;
 	v->signal = fmi_getsigstr(fmi);
 	return 0;
@@ -167,32 +163,29 @@ static int vidioc_g_tuner(struct file *f
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct fmi_device *fmi = video_drvdata(file);
+	struct fmi *fmi = video_drvdata(file);
 
 	if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
 		f->frequency *= 1000;
 	if (f->frequency < RSF16_MINFREQ ||
-			f->frequency > RSF16_MAXFREQ )
+			f->frequency > RSF16_MAXFREQ)
 		return -EINVAL;
-	/*rounding in steps of 800 to match th freq
-	that will be used */
-	fmi->curfreq = (f->frequency/800)*800;
-	fmi_setfreq(fmi);
+	/* rounding in steps of 800 to match the freq
+	   that will be used */
+	fmi_setfreq(fmi, (f->frequency / 800) * 800);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct fmi_device *fmi = video_drvdata(file);
+	struct fmi *fmi = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = fmi->curfreq;
@@ -204,14 +197,9 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
 	}
 	return -EINVAL;
 }
@@ -219,7 +207,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct fmi_device *fmi = video_drvdata(file);
+	struct fmi *fmi = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -232,31 +220,20 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct fmi_device *fmi = video_drvdata(file);
+	struct fmi *fmi = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value)
-			fmi_mute(fmi->port);
+			fmi_mute(fmi);
 		else
-			fmi_unmute(fmi->port);
+			fmi_unmute(fmi);
 		fmi->curvol = ctrl->value;
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -265,36 +242,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct fmi_device fmi_unit;
-
-static int fmi_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0;
-}
-
-static int fmi_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	clear_bit(0, &fmi_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations fmi_fops = {
 	.owner		= THIS_MODULE,
-	.open           = fmi_exclusive_open,
-	.release        = fmi_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -313,13 +280,6 @@ static const struct v4l2_ioctl_ops fmi_i
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device fmi_radio = {
-	.name		= "SF16FMx radio",
-	.fops           = &fmi_fops,
-	.ioctl_ops 	= &fmi_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 /* ladis: this is my card. does any other types exist? */
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
@@ -344,7 +304,7 @@ static int __init isapnp_fmi_probe(void)
 	if (pnp_device_attach(dev) < 0)
 		return -EAGAIN;
 	if (pnp_activate_dev(dev) < 0) {
-		printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n");
+		printk(KERN_ERR "radio-sf16fmi: PnP configure failed (out of resources?)\n");
 		pnp_device_detach(dev);
 		return -ENOMEM;
 	}
@@ -354,59 +314,72 @@ static int __init isapnp_fmi_probe(void)
 	}
 
 	i = pnp_port_start(dev, 0);
-	printk ("radio-sf16fmi: PnP reports card at %#x\n", i);
+	printk(KERN_INFO "radio-sf16fmi: PnP reports card at %#x\n", i);
 
 	return i;
 }
 
 static int __init fmi_init(void)
 {
+	struct fmi *fmi = &fmi_card;
+	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+	int res;
+
 	if (io < 0)
 		io = isapnp_fmi_probe();
-	if (io < 0) {
-		printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
-		return io;
+	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 (!request_region(io, 2, "radio-sf16fmi")) {
-		printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
 		pnp_device_detach(dev);
 		return -EBUSY;
 	}
 
-	fmi_unit.port = io;
-	fmi_unit.curvol = 0;
-	fmi_unit.curfreq = 0;
-	fmi_unit.flags = V4L2_TUNER_CAP_LOW;
-	video_set_drvdata(&fmi_radio, &fmi_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(fmi->io, 2);
+		pnp_device_detach(dev);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
 
-	mutex_init(&lock);
+	fmi->flags = V4L2_TUNER_CAP_LOW;
+	strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
+	fmi->vdev.v4l2_dev = v4l2_dev;
+	fmi->vdev.fops = &fmi_fops;
+	fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
+	fmi->vdev.release = video_device_release_empty;
+	video_set_drvdata(&fmi->vdev, fmi);
 
-	if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 2);
+	mutex_init(&fmi->lock);
+
+	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);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
+	v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
 	/* mute card - prevents noisy bootups */
-	fmi_mute(io);
+	fmi_mute(fmi);
 	return 0;
 }
 
-MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmi_cleanup_module(void)
+static void __exit fmi_exit(void)
 {
-	video_unregister_device(&fmi_radio);
-	release_region(io, 2);
+	struct fmi *fmi = &fmi_card;
+
+	video_unregister_device(&fmi->vdev);
+	v4l2_device_unregister(&fmi->v4l2_dev);
+	release_region(fmi->io, 2);
 	if (dev)
 		pnp_device_detach(dev);
 }
 
 module_init(fmi_init);
-module_exit(fmi_cleanup_module);
+module_exit(fmi_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-sf16fmr2.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-sf16fmr2.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-sf16fmr2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-sf16fmr2.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,40 +18,28 @@
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/mutex.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-static struct mutex lock;
+MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
+MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
+MODULE_LICENSE("GPL");
+
+static int io = 0x384;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
+module_param(radio_nr, int, 0);
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #define RADIO_VERSION KERNEL_VERSION(0,0,2)
 
 #define AUD_VOL_INDEX 1
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},
-	[AUD_VOL_INDEX] = {
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 15,
-		.step          = 1,
-		.default_value = 0,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
-
 #undef DEBUG
 //#define DEBUG 1
 
@@ -62,156 +50,160 @@ static struct v4l2_queryctrl radio_qctrl
 #endif
 
 /* this should be static vars for module size */
-struct fmr2_device
+struct fmr2
 {
-	unsigned long in_use;
-	int port;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct mutex lock;
+	int io;
 	int curvol; /* 0-15 */
 	int mute;
 	int stereo; /* card is producing stereo audio */
 	unsigned long curfreq; /* freq in kHz */
 	int card_type;
-	__u32 flags;
+	u32 flags;
 };
 
-static int io = 0x384;
-static int radio_nr = -1;
+static struct fmr2 fmr2_card;
 
 /* hw precision is 12.5 kHz
  * It is only useful to give freq in intervall of 200 (=0.0125Mhz),
  * other bits will be truncated
  */
-#define RSF16_ENCODE(x)	((x)/200+856)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x)	((x) / 200 + 856)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
 
-static inline void wait(int n,int port)
+static inline void wait(int n, int io)
 {
-	for (;n;--n) inb(port);
+	for (; n; --n)
+		inb(io);
 }
 
-static void outbits(int bits, unsigned int data, int nWait, int port)
+static void outbits(int bits, unsigned int data, int nWait, int io)
 {
 	int bit;
-	for(;--bits>=0;) {
-		bit = (data>>bits) & 1;
-		outb(bit,port);
-		wait(nWait,port);
-		outb(bit|2,port);
-		wait(nWait,port);
-		outb(bit,port);
-		wait(nWait,port);
+
+	for (; --bits >= 0;) {
+		bit = (data >> bits) & 1;
+		outb(bit, io);
+		wait(nWait, io);
+		outb(bit | 2, io);
+		wait(nWait, io);
+		outb(bit, io);
+		wait(nWait, io);
 	}
 }
 
-static inline void fmr2_mute(int port)
+static inline void fmr2_mute(int io)
 {
-	outb(0x00, port);
-	wait(4,port);
+	outb(0x00, io);
+	wait(4, io);
 }
 
-static inline void fmr2_unmute(int port)
+static inline void fmr2_unmute(int io)
 {
-	outb(0x04, port);
-	wait(4,port);
+	outb(0x04, io);
+	wait(4, io);
 }
 
-static inline int fmr2_stereo_mode(int port)
+static inline int fmr2_stereo_mode(int io)
 {
-	int n = inb(port);
-	outb(6,port);
-	inb(port);
-	n = ((n>>3)&1)^1;
+	int n = inb(io);
+
+	outb(6, io);
+	inb(io);
+	n = ((n >> 3) & 1) ^ 1;
 	debug_print((KERN_DEBUG "stereo: %d\n", n));
 	return n;
 }
 
-static int fmr2_product_info(struct fmr2_device *dev)
+static int fmr2_product_info(struct fmr2 *dev)
 {
-	int n = inb(dev->port);
+	int n = inb(dev->io);
+
 	n &= 0xC1;
-	if (n == 0)
-	{
+	if (n == 0) {
 		/* this should support volume set */
 		dev->card_type = 12;
 		return 0;
 	}
 	/* not volume (mine is 11) */
-	dev->card_type = (n==128)?11:0;
+	dev->card_type = (n == 128) ? 11 : 0;
 	return n;
 }
 
-static inline int fmr2_getsigstr(struct fmr2_device *dev)
+static inline int fmr2_getsigstr(struct fmr2 *dev)
 {
-	/* !!! work only if scanning freq */
-	int port = dev->port, res = 0xffff;
-	outb(5,port);
-	wait(4,port);
-	if (!(inb(port)&1)) res = 0;
+	/* !!! works only if scanning freq */
+	int res = 0xffff;
+
+	outb(5, dev->io);
+	wait(4, dev->io);
+	if (!(inb(dev->io) & 1))
+		res = 0;
 	debug_print((KERN_DEBUG "signal: %d\n", res));
 	return res;
 }
 
 /* set frequency and unmute card */
-static int fmr2_setfreq(struct fmr2_device *dev)
+static int fmr2_setfreq(struct fmr2 *dev)
 {
-	int port = dev->port;
 	unsigned long freq = dev->curfreq;
 
-	fmr2_mute(port);
+	fmr2_mute(dev->io);
 
 	/* 0x42 for mono output
 	 * 0x102 forward scanning
 	 * 0x182 scansione avanti
 	 */
-	outbits(9,0x2,3,port);
-	outbits(16,RSF16_ENCODE(freq),2,port);
+	outbits(9, 0x2, 3, dev->io);
+	outbits(16, RSF16_ENCODE(freq), 2, dev->io);
 
-	fmr2_unmute(port);
+	fmr2_unmute(dev->io);
 
 	/* wait 0.11 sec */
 	msleep(110);
 
 	/* NOTE if mute this stop radio
 	   you must set freq on unmute */
-	dev->stereo = fmr2_stereo_mode(port);
+	dev->stereo = fmr2_stereo_mode(dev->io);
 	return 0;
 }
 
 /* !!! not tested, in my card this does't work !!! */
-static int fmr2_setvolume(struct fmr2_device *dev)
+static int fmr2_setvolume(struct fmr2 *dev)
 {
 	int vol[16] = { 0x021, 0x084, 0x090, 0x104,
 			0x110, 0x204, 0x210, 0x402,
 			0x404, 0x408, 0x410, 0x801,
 			0x802, 0x804, 0x808, 0x810 };
-	int i, a, port = dev->port;
+	int i, a;
 	int n = vol[dev->curvol & 0x0f];
 
 	if (dev->card_type != 11)
 		return 1;
 
 	for (i = 12; --i >= 0; ) {
-		a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */
-		outb(a | 4, port);
-		wait(4, port);
-		outb(a | 0x24, port);
-		wait(4, port);
-		outb(a | 4, port);
-		wait(4, port);
+		a = ((n >> i) & 1) << 6; /* if (a==0) a = 0; else a = 0x40; */
+		outb(a | 4, dev->io);
+		wait(4, dev->io);
+		outb(a | 0x24, dev->io);
+		wait(4, dev->io);
+		outb(a | 4, dev->io);
+		wait(4, dev->io);
 	}
 	for (i = 6; --i >= 0; ) {
 		a = ((0x18 >> i) & 1) << 6;
-		outb(a | 4, port);
-		wait(4,port);
-		outb(a | 0x24, port);
-		wait(4,port);
-		outb(a|4, port);
-		wait(4,port);
+		outb(a | 4, dev->io);
+		wait(4, dev->io);
+		outb(a | 0x24, dev->io);
+		wait(4, dev->io);
+		outb(a | 4, dev->io);
+		wait(4, dev->io);
 	}
-	wait(4, port);
-	outb(0x14, port);
-
+	wait(4, dev->io);
+	outb(0x14, dev->io);
 	return 0;
 }
 
@@ -220,9 +212,9 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
 	strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
@@ -230,54 +222,52 @@ static int vidioc_g_tuner(struct file *f
 					struct v4l2_tuner *v)
 {
 	int mult;
-	struct fmr2_device *fmr2 = video_drvdata(file);
+	struct fmr2 *fmr2 = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 
 	mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
-	v->rangelow = RSF16_MINFREQ/mult;
-	v->rangehigh = RSF16_MAXFREQ/mult;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+	v->rangelow = RSF16_MINFREQ / mult;
+	v->rangehigh = RSF16_MAXFREQ / mult;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
 	v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
 				V4L2_TUNER_MODE_MONO;
-	mutex_lock(&lock);
+	mutex_lock(&fmr2->lock);
 	v->signal = fmr2_getsigstr(fmr2);
-	mutex_unlock(&lock);
+	mutex_unlock(&fmr2->lock);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct fmr2_device *fmr2 = video_drvdata(file);
+	struct fmr2 *fmr2 = video_drvdata(file);
 
 	if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
 		f->frequency *= 1000;
 	if (f->frequency < RSF16_MINFREQ ||
-			f->frequency > RSF16_MAXFREQ )
+			f->frequency > RSF16_MAXFREQ)
 		return -EINVAL;
-	/*rounding in steps of 200 to match th freq
-	that will be used */
-	fmr2->curfreq = (f->frequency/200)*200;
+	/* rounding in steps of 200 to match the freq
+	   that will be used */
+	fmr2->curfreq = (f->frequency / 200) * 200;
 
 	/* set card freq (if not muted) */
 	if (fmr2->curvol && !fmr2->mute) {
-		mutex_lock(&lock);
+		mutex_lock(&fmr2->lock);
 		fmr2_setfreq(fmr2);
-		mutex_unlock(&lock);
+		mutex_unlock(&fmr2->lock);
 	}
 	return 0;
 }
@@ -285,7 +275,7 @@ static int vidioc_s_frequency(struct fil
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct fmr2_device *fmr2 = video_drvdata(file);
+	struct fmr2 *fmr2 = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = fmr2->curfreq;
@@ -297,13 +287,16 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
+	struct fmr2 *fmr2 = video_drvdata(file);
 
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &radio_qctrl[i], sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		/* Only card_type == 11 implements volume */
+		if (fmr2->card_type == 11)
+			return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0);
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
 	}
 	return -EINVAL;
 }
@@ -311,7 +304,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct fmr2_device *fmr2 = video_drvdata(file);
+	struct fmr2 *fmr2 = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -327,18 +320,14 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct fmr2_device *fmr2 = video_drvdata(file);
+	struct fmr2 *fmr2 = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		fmr2->mute = ctrl->value;
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
-		if (ctrl->value > radio_qctrl[AUD_VOL_INDEX].maximum)
-			fmr2->curvol = radio_qctrl[AUD_VOL_INDEX].maximum;
-		else
-			fmr2->curvol = ctrl->value;
-
+		fmr2->curvol = ctrl->value;
 		break;
 	default:
 		return -EINVAL;
@@ -351,25 +340,14 @@ static int vidioc_s_ctrl(struct file *fi
 		printk(KERN_DEBUG "mute\n");
 #endif
 
-	mutex_lock(&lock);
+	mutex_lock(&fmr2->lock);
 	if (fmr2->curvol && !fmr2->mute) {
 		fmr2_setvolume(fmr2);
 		/* Set frequency and unmute card */
 		fmr2_setfreq(fmr2);
 	} else
-		fmr2_mute(fmr2->port);
-	mutex_unlock(&lock);
-	return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
+		fmr2_mute(fmr2->io);
+	mutex_unlock(&fmr2->lock);
 	return 0;
 }
 
@@ -381,36 +359,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct fmr2_device fmr2_unit;
-
-static int fmr2_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0;
-}
-
-static int fmr2_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	clear_bit(0, &fmr2_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations fmr2_fops = {
 	.owner          = THIS_MODULE,
-	.open           = fmr2_exclusive_open,
-	.release        = fmr2_exclusive_release,
 	.ioctl          = video_ioctl2,
 };
 
@@ -429,67 +397,64 @@ static const struct v4l2_ioctl_ops fmr2_
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device fmr2_radio = {
-	.name		= "SF16FMR2 radio",
-	.fops		= &fmr2_fops,
-	.ioctl_ops 	= &fmr2_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init fmr2_init(void)
 {
-	fmr2_unit.port = io;
-	fmr2_unit.curvol = 0;
-	fmr2_unit.mute = 0;
-	fmr2_unit.curfreq = 0;
-	fmr2_unit.stereo = 1;
-	fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
-	fmr2_unit.card_type = 0;
-	video_set_drvdata(&fmr2_radio, &fmr2_unit);
+	struct fmr2 *fmr2 = &fmr2_card;
+	struct v4l2_device *v4l2_dev = &fmr2->v4l2_dev;
+	int res;
 
-	mutex_init(&lock);
+	strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name));
+	fmr2->io = io;
+	fmr2->stereo = 1;
+	fmr2->flags = V4L2_TUNER_CAP_LOW;
+	mutex_init(&fmr2->lock);
 
-	if (!request_region(io, 2, "sf16fmr2")) {
-		printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
+	if (!request_region(fmr2->io, 2, "sf16fmr2")) {
+		v4l2_err(v4l2_dev, "request_region failed!\n");
 		return -EBUSY;
 	}
 
-	if (video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 2);
-		return -EINVAL;
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(fmr2->io, 2);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
 	}
 
-	printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
-	/* mute card - prevents noisy bootups */
-	mutex_lock(&lock);
-	fmr2_mute(io);
-	fmr2_product_info(&fmr2_unit);
-	mutex_unlock(&lock);
-	debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
+	strlcpy(fmr2->vdev.name, v4l2_dev->name, sizeof(fmr2->vdev.name));
+	fmr2->vdev.v4l2_dev = v4l2_dev;
+	fmr2->vdev.fops = &fmr2_fops;
+	fmr2->vdev.ioctl_ops = &fmr2_ioctl_ops;
+	fmr2->vdev.release = video_device_release_empty;
+	video_set_drvdata(&fmr2->vdev, fmr2);
 
-	/* Only card_type == 11 implements volume */
-	if (fmr2_unit.card_type != 11)
-		radio_qctrl[AUD_VOL_INDEX].maximum = 1;
+	if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(fmr2->io, 2);
+		return -EINVAL;
+	}
 
+	v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
+	/* mute card - prevents noisy bootups */
+	mutex_lock(&fmr2->lock);
+	fmr2_mute(fmr2->io);
+	fmr2_product_info(fmr2);
+	mutex_unlock(&fmr2->lock);
+	debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
 	return 0;
 }
 
-MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
-MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmr2_cleanup_module(void)
+static void __exit fmr2_exit(void)
 {
-	video_unregister_device(&fmr2_radio);
-	release_region(io,2);
+	struct fmr2 *fmr2 = &fmr2_card;
+
+	video_unregister_device(&fmr2->vdev);
+	v4l2_device_unregister(&fmr2->v4l2_dev);
+	release_region(fmr2->io, 2);
 }
 
 module_init(fmr2_init);
-module_exit(fmr2_cleanup_module);
+module_exit(fmr2_exit);
 
 #ifndef MODULE
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-si470x.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-si470x.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-si470x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-si470x.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,8 +5,9 @@
  *   - Silicon Labs USB FM Radio Reference Design
  *   - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
  *   - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+ *   - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
  *
- *  Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+ *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.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
@@ -29,7 +30,7 @@
  * 2008-01-12	Tobias Lorenz <tobias.lorenz@gmx.net>
  *		Version 1.0.0
  *		- First working version
- * 2008-01-13   Tobias Lorenz <tobias.lorenz@gmx.net>
+ * 2008-01-13	Tobias Lorenz <tobias.lorenz@gmx.net>
  *		Version 1.0.1
  *		- Improved error handling, every function now returns errno
  *		- Improved multi user access (start/mute/stop)
@@ -104,6 +105,7 @@
  * 2009-01-31	Rick Bronson <rick@efn.org>
  *		Tobias Lorenz <tobias.lorenz@gmx.net>
  *		- add LED status output
+ *		- get HW/SW version from scratchpad
  *
  * ToDo:
  * - add firmware download/update support
@@ -114,10 +116,10 @@
 /* driver definitions */
 #define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
 #define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
 #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
 #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.8"
+#define DRIVER_VERSION "1.0.9"
 
 
 /* kernel includes */
@@ -145,7 +147,7 @@ static struct usb_device_id si470x_usb_d
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
 	/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
-	/* DealExtreme USB Radio */
+	/* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
 	/* Terminating entry */
 	{ }
@@ -345,7 +347,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS pol
 
 /* Report 19: stream */
 #define STREAM_REPORT_SIZE	3
-#define	STREAM_REPORT		19
+#define STREAM_REPORT		19
 
 /* Report 20: scratch */
 #define SCRATCH_PAGE_SIZE	63
@@ -353,9 +355,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS pol
 #define SCRATCH_REPORT		20
 
 /* Reports 19-22: flash upgrade of the C8051F321 */
+#define WRITE_REPORT_SIZE	4
 #define WRITE_REPORT		19
+#define FLASH_REPORT_SIZE	64
 #define FLASH_REPORT		20
+#define CRC_REPORT_SIZE		3
 #define CRC_REPORT		21
+#define RESPONSE_REPORT_SIZE	2
 #define RESPONSE_REPORT		22
 
 /* Report 23: currently unused, but can accept 60 byte reports on the HID */
@@ -414,7 +420,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS pol
 
 /* bootloader commands */
 #define GET_SW_VERSION_COMMAND	0x00
-#define	SET_PAGE_COMMAND	0x01
+#define SET_PAGE_COMMAND	0x01
 #define ERASE_PAGE_COMMAND	0x02
 #define WRITE_PAGE_COMMAND	0x03
 #define CRC_ON_PAGE_COMMAND	0x04
@@ -428,12 +434,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS pol
 #define COMMAND_FAILED		0x02
 #define COMMAND_PENDING		0x03
 
-/* buffer sizes */
-#define COMMAND_BUFFER_SIZE	4
-#define RESPONSE_BUFFER_SIZE	2
-#define FLASH_BUFFER_SIZE	64
-#define CRC_BUFFER_SIZE		3
-
 
 
 /**************************************************************************
@@ -465,6 +465,10 @@ struct si470x_device {
 	unsigned int buf_size;
 	unsigned int rd_index;
 	unsigned int wr_index;
+
+	/* scratch page */
+	unsigned char software_version;
+	unsigned char hardware_version;
 };
 
 
@@ -480,7 +484,7 @@ struct si470x_device {
 
 
 /**************************************************************************
- * General Driver Functions
+ * General Driver Functions - REGISTER_REPORTs
  **************************************************************************/
 
 /*
@@ -566,60 +570,6 @@ static int si470x_set_register(struct si
 
 
 /*
- * si470x_get_all_registers - read entire registers
- */
-static int si470x_get_all_registers(struct si470x_device *radio)
-{
-	unsigned char buf[ENTIRE_REPORT_SIZE];
-	int retval;
-	unsigned char regnr;
-
-	buf[0] = ENTIRE_REPORT;
-
-	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
-	if (retval >= 0)
-		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
-			radio->registers[regnr] = get_unaligned_be16(
-				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_get_rds_registers - read rds registers
- */
-static int si470x_get_rds_registers(struct si470x_device *radio)
-{
-	unsigned char buf[RDS_REPORT_SIZE];
-	int retval;
-	int size;
-	unsigned char regnr;
-
-	buf[0] = RDS_REPORT;
-
-	retval = usb_interrupt_msg(radio->usbdev,
-		usb_rcvintpipe(radio->usbdev, 1),
-		(void *) &buf, sizeof(buf), &size, usb_timeout);
-	if (size != sizeof(buf))
-		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
-			"return size differs: %d != %zu\n", size, sizeof(buf));
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
-			"usb_interrupt_msg returned %d\n", retval);
-
-	if (retval >= 0)
-		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
-			radio->registers[STATUSRSSI + regnr] =
-				get_unaligned_be16(
-				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
  * si470x_set_chan - set the channel
  */
 static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
@@ -887,6 +837,70 @@ static int si470x_rds_on(struct si470x_d
 
 
 /**************************************************************************
+ * General Driver Functions - ENTIRE_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+	unsigned char buf[ENTIRE_REPORT_SIZE];
+	int retval;
+	unsigned char regnr;
+
+	buf[0] = ENTIRE_REPORT;
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+	if (retval >= 0)
+		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+			radio->registers[regnr] = get_unaligned_be16(
+				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - RDS_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_rds_registers - read rds registers
+ */
+static int si470x_get_rds_registers(struct si470x_device *radio)
+{
+	unsigned char buf[RDS_REPORT_SIZE];
+	int retval;
+	int size;
+	unsigned char regnr;
+
+	buf[0] = RDS_REPORT;
+
+	retval = usb_interrupt_msg(radio->usbdev,
+		usb_rcvintpipe(radio->usbdev, 1),
+		(void *) &buf, sizeof(buf), &size, usb_timeout);
+	if (size != sizeof(buf))
+		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+			"return size differs: %d != %zu\n", size, sizeof(buf));
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+			"usb_interrupt_msg returned %d\n", retval);
+
+	if (retval >= 0)
+		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+			radio->registers[STATUSRSSI + regnr] =
+				get_unaligned_be16(
+				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
  * General Driver Functions - LED_REPORT
  **************************************************************************/
 
@@ -911,6 +925,35 @@ static int si470x_set_led_state(struct s
 
 
 /**************************************************************************
+ * General Driver Functions - SCRATCH_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_scratch_versions - gets the scratch page and version infos
+ */
+static int si470x_get_scratch_page_versions(struct si470x_device *radio)
+{
+	unsigned char buf[SCRATCH_REPORT_SIZE];
+	int retval;
+
+	buf[0] = SCRATCH_REPORT;
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+	if (retval < 0)
+		printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
+			"si470x_get_report returned %d\n", retval);
+	else {
+		radio->software_version = buf[1];
+		radio->hardware_version = buf[2];
+	}
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
  * RDS Driver Functions
  **************************************************************************/
 
@@ -1124,6 +1167,7 @@ static int si470x_fops_open(struct file
 	}
 
 	if (radio->users == 1) {
+		/* start radio */
 		retval = si470x_start(radio);
 		if (retval < 0)
 			usb_autopm_put_interface(radio->intf);
@@ -1156,7 +1200,7 @@ static int si470x_fops_release(struct fi
 			video_unregister_device(radio->videodev);
 			kfree(radio->buffer);
 			kfree(radio);
-			goto unlock;
+			goto done;
 		}
 
 		/* stop rds reception */
@@ -1165,6 +1209,7 @@ static int si470x_fops_release(struct fi
 		/* cancel read processes */
 		wake_up_interruptible(&radio->read_queue);
 
+		/* stop radio */
 		retval = si470x_stop(radio);
 		usb_autopm_put_interface(radio->intf);
 	}
@@ -1226,9 +1271,11 @@ static struct v4l2_queryctrl si470x_v4l2
 static int si470x_vidioc_querycap(struct file *file, void *priv,
 		struct v4l2_capability *capability)
 {
+	struct si470x_device *radio = video_drvdata(file);
+
 	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
 	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
-	sprintf(capability->bus_info, "USB");
+	usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
 	capability->version = DRIVER_KERNEL_VERSION;
 	capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
 		V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -1636,15 +1683,24 @@ static int si470x_usb_driver_probe(struc
 			sizeof(si470x_viddev_template));
 	video_set_drvdata(radio->videodev, radio);
 
-	/* show some infos about the specific device */
+	/* show some infos about the specific si470x device */
 	if (si470x_get_all_registers(radio) < 0) {
 		retval = -EIO;
-		goto err_all;
+		goto err_video;
 	}
 	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
 			radio->registers[DEVICEID], radio->registers[CHIPID]);
 
-	/* check if firmware is current */
+	/* get software and hardware versions */
+	if (si470x_get_scratch_page_versions(radio) < 0) {
+		retval = -EIO;
+		goto err_video;
+	}
+	printk(KERN_INFO DRIVER_NAME
+			": software version %d, hardware version %d\n",
+			radio->software_version, radio->hardware_version);
+
+	/* check if device and firmware is current */
 	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
 			< RADIO_SW_VERSION_CURRENT) {
 		printk(KERN_WARNING DRIVER_NAME
@@ -1657,7 +1713,7 @@ static int si470x_usb_driver_probe(struc
 			": If you have some trouble using this driver,\n");
 		printk(KERN_WARNING DRIVER_NAME
 			": please report to V4L ML at "
-			"video4linux-list@redhat.com\n");
+			"linux-media@vger.kernel.org\n");
 	}
 
 	/* set initial frequency */
@@ -1671,7 +1727,7 @@ static int si470x_usb_driver_probe(struc
 	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
 	if (!radio->buffer) {
 		retval = -EIO;
-		goto err_all;
+		goto err_video;
 	}
 
 	/* rds buffer configuration */
@@ -1693,8 +1749,9 @@ static int si470x_usb_driver_probe(struc
 
 	return 0;
 err_all:
-	video_device_release(radio->videodev);
 	kfree(radio->buffer);
+err_video:
+	video_device_release(radio->videodev);
 err_radio:
 	kfree(radio);
 err_initial:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-tea5764.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-tea5764.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-tea5764.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-tea5764.c	2009-06-09 23:05:27.000000000 -0400
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *
 
 	strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
 	strlcpy(v->card, dev->name, sizeof(v->card));
-	snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id);
+	snprintf(v->bus_info, sizeof(v->bus_info),
+		 "I2C:%s", dev_name(&dev->dev));
 	v->version = RADIO_VERSION;
 	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-terratec.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-terratec.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-terratec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-terratec.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,16 +27,29 @@
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
-#include <linux/delay.h>	/* udelay			*/
-#include <asm/io.h>		/* outb, outb_p			*/
-#include <asm/uaccess.h>	/* copy to/from user		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
+#include <linux/io.h>		/* outb, outb_p			*/
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("R.OFFERMANNS & others");
+MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
+MODULE_LICENSE("GPL");
+
+#ifndef CONFIG_RADIO_TERRATEC_PORT
+#define CONFIG_RADIO_TERRATEC_PORT 0x590
+#endif
+
+static int io = CONFIG_RADIO_TERRATEC_PORT;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
 
 static struct v4l2_queryctrl radio_qctrl[] = {
 	{
@@ -57,13 +70,6 @@ static struct v4l2_queryctrl radio_qctrl
 	}
 };
 
-#ifndef CONFIG_RADIO_TERRATEC_PORT
-#define CONFIG_RADIO_TERRATEC_PORT 0x590
-#endif
-
-/**************** this ones are for the terratec *******************/
-#define BASEPORT 	0x590
-#define VOLPORT 	0x591
 #define WRT_DIS 	0x00
 #define CLK_OFF		0x00
 #define IIC_DATA	0x01
@@ -71,138 +77,124 @@ static struct v4l2_queryctrl radio_qctrl
 #define DATA		0x04
 #define CLK_ON 		0x08
 #define WRT_EN		0x10
-/*******************************************************************/
-
-static int io = CONFIG_RADIO_TERRATEC_PORT;
-static int radio_nr = -1;
-static spinlock_t lock;
 
-struct tt_device
+struct terratec
 {
-	unsigned long in_use;
-	int port;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	int curvol;
 	unsigned long curfreq;
 	int muted;
+	struct mutex lock;
 };
 
+static struct terratec terratec_card;
 
 /* local things */
 
-static void cardWriteVol(int volume)
+static void tt_write_vol(struct terratec *tt, int volume)
 {
 	int i;
-	volume = volume+(volume * 32); // change both channels
-	spin_lock(&lock);
-	for (i=0;i<8;i++)
-	{
-		if (volume & (0x80>>i))
-			outb(0x80, VOLPORT);
-		else outb(0x00, VOLPORT);
+
+	volume = volume + (volume * 32); /* change both channels */
+	mutex_lock(&tt->lock);
+	for (i = 0; i < 8; i++) {
+		if (volume & (0x80 >> i))
+			outb(0x80, tt->io + 1);
+		else
+			outb(0x00, tt->io + 1);
 	}
-	spin_unlock(&lock);
+	mutex_unlock(&tt->lock);
 }
 
 
 
-static void tt_mute(struct tt_device *dev)
+static void tt_mute(struct terratec *tt)
 {
-	dev->muted = 1;
-	cardWriteVol(0);
+	tt->muted = 1;
+	tt_write_vol(tt, 0);
 }
 
-static int tt_setvol(struct tt_device *dev, int vol)
+static int tt_setvol(struct terratec *tt, int vol)
 {
-
-//	printk(KERN_ERR "setvol called, vol = %d\n", vol);
-
-	if(vol == dev->curvol) {	/* requested volume = current */
-		if (dev->muted) {	/* user is unmuting the card  */
-			dev->muted = 0;
-			cardWriteVol(vol);	/* enable card */
+	if (vol == tt->curvol) {	/* requested volume = current */
+		if (tt->muted) {	/* user is unmuting the card  */
+			tt->muted = 0;
+			tt_write_vol(tt, vol);	/* enable card */
 		}
-
 		return 0;
 	}
 
-	if(vol == 0) {			/* volume = 0 means mute the card */
-		cardWriteVol(0);	/* "turn off card" by setting vol to 0 */
-		dev->curvol = vol;	/* track the volume state!	*/
+	if (vol == 0) {			/* volume = 0 means mute the card */
+		tt_write_vol(tt, 0);	/* "turn off card" by setting vol to 0 */
+		tt->curvol = vol;	/* track the volume state!	*/
 		return 0;
 	}
 
-	dev->muted = 0;
-
-	cardWriteVol(vol);
-
-	dev->curvol = vol;
-
+	tt->muted = 0;
+	tt_write_vol(tt, vol);
+	tt->curvol = vol;
 	return 0;
-
 }
 
 
 /* this is the worst part in this driver */
 /* many more or less strange things are going on here, but hey, it works :) */
 
-static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
+static int tt_setfreq(struct terratec *tt, unsigned long freq1)
 {
 	int freq;
 	int i;
 	int p;
 	int  temp;
 	long rest;
-
 	unsigned char buffer[25];		/* we have to bit shift 25 registers */
-	freq = freq1/160;			/* convert the freq. to a nice to handle value */
-	for(i=24;i>-1;i--)
-		buffer[i]=0;
 
-	rest = freq*10+10700;		/* i once had understood what is going on here */
+	mutex_lock(&tt->lock);
+
+	tt->curfreq = freq1;
+
+	freq = freq1 / 160;			/* convert the freq. to a nice to handle value */
+	memset(buffer, 0, sizeof(buffer));
+
+	rest = freq * 10 + 10700;	/* I once had understood what is going on here */
 					/* maybe some wise guy (friedhelm?) can comment this stuff */
-	i=13;
-	p=10;
-	temp=102400;
-	while (rest!=0)
-	{
-		if (rest%temp  == rest)
+	i = 13;
+	p = 10;
+	temp = 102400;
+	while (rest != 0) {
+		if (rest % temp  == rest)
 			buffer[i] = 0;
-		else
-		{
+		else {
 			buffer[i] = 1;
-			rest = rest-temp;
+			rest = rest - temp;
 		}
 		i--;
 		p--;
-		temp = temp/2;
+		temp = temp / 2;
 	}
 
-	spin_lock(&lock);
-
-	for (i=24;i>-1;i--)			/* bit shift the values to the radiocard */
-	{
-		if (buffer[i]==1)
-		{
-			outb(WRT_EN|DATA, BASEPORT);
-			outb(WRT_EN|DATA|CLK_ON  , BASEPORT);
-			outb(WRT_EN|DATA, BASEPORT);
-		}
-		else
-		{
-			outb(WRT_EN|0x00, BASEPORT);
-			outb(WRT_EN|0x00|CLK_ON  , BASEPORT);
+	for (i = 24; i > -1; i--) {	/* bit shift the values to the radiocard */
+		if (buffer[i] == 1) {
+			outb(WRT_EN | DATA, tt->io);
+			outb(WRT_EN | DATA | CLK_ON, tt->io);
+			outb(WRT_EN | DATA, tt->io);
+		} else {
+			outb(WRT_EN | 0x00, tt->io);
+			outb(WRT_EN | 0x00 | CLK_ON, tt->io);
 		}
 	}
-	outb(0x00, BASEPORT);
+	outb(0x00, tt->io);
 
-	spin_unlock(&lock);
+	mutex_unlock(&tt->lock);
 
 	return 0;
 }
 
-static int tt_getsigstr(struct tt_device *dev)		/* TODO */
+static int tt_getsigstr(struct terratec *tt)
 {
-	if (inb(io) & 2)	/* bit set = no signal present	*/
+	if (inb(tt->io) & 2)	/* bit set = no signal present	*/
 		return 0;
 	return 1;		/* signal present		*/
 }
@@ -212,53 +204,50 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
 	strlcpy(v->card, "ActiveRadio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	struct tt_device *tt = video_drvdata(file);
+	struct terratec *tt = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (87*16000);
-	v->rangehigh = (108*16000);
+	v->rangelow = 87 * 16000;
+	v->rangehigh = 108 * 16000;
 	v->rxsubchans = V4L2_TUNER_SUB_MONO;
 	v->capability = V4L2_TUNER_CAP_LOW;
 	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF*tt_getsigstr(tt);
+	v->signal = 0xFFFF * tt_getsigstr(tt);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct tt_device *tt = video_drvdata(file);
+	struct terratec *tt = video_drvdata(file);
 
-	tt->curfreq = f->frequency;
-	tt_setfreq(tt, tt->curfreq);
+	tt_setfreq(tt, f->frequency);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct tt_device *tt = video_drvdata(file);
+	struct terratec *tt = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = tt->curfreq;
@@ -272,8 +261,7 @@ static int vidioc_queryctrl(struct file
 
 	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
 		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
+			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
 			return 0;
 		}
 	}
@@ -283,7 +271,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct tt_device *tt = video_drvdata(file);
+	struct terratec *tt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -302,7 +290,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct tt_device *tt = video_drvdata(file);
+	struct terratec *tt = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -318,17 +306,6 @@ static int vidioc_s_ctrl(struct file *fi
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -337,36 +314,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct tt_device terratec_unit;
-
-static int terratec_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0;
-}
-
-static int terratec_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	clear_bit(0, &terratec_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations terratec_fops = {
 	.owner		= THIS_MODULE,
-	.open           = terratec_exclusive_open,
-	.release        = terratec_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -385,60 +352,63 @@ static const struct v4l2_ioctl_ops terra
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-static struct video_device terratec_radio = {
-	.name		= "TerraTec ActiveRadio",
-	.fops           = &terratec_fops,
-	.ioctl_ops 	= &terratec_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init terratec_init(void)
 {
-	if(io==-1)
-	{
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+	struct terratec *tt = &terratec_card;
+	struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name));
+	tt->io = io;
+	if (tt->io == -1) {
+		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n");
 		return -EINVAL;
 	}
-	if (!request_region(io, 2, "terratec"))
-	{
-		printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
+	if (!request_region(tt->io, 2, "terratec")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", io);
 		return -EBUSY;
 	}
 
-	video_set_drvdata(&terratec_radio, &terratec_unit);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(tt->io, 2);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
 
-	spin_lock_init(&lock);
+	strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name));
+	tt->vdev.v4l2_dev = v4l2_dev;
+	tt->vdev.fops = &terratec_fops;
+	tt->vdev.ioctl_ops = &terratec_ioctl_ops;
+	tt->vdev.release = video_device_release_empty;
+	video_set_drvdata(&tt->vdev, tt);
 
-	if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io,2);
+	mutex_init(&tt->lock);
+
+	if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(&tt->v4l2_dev);
+		release_region(tt->io, 2);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
+	v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
 
 	/* mute card - prevents noisy bootups */
-
-	/* this ensures that the volume is all the way down  */
-	cardWriteVol(0);
-	terratec_unit.curvol = 0;
-
+	tt_write_vol(tt, 0);
 	return 0;
 }
 
-MODULE_AUTHOR("R.OFFERMANNS & others");
-MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
-MODULE_LICENSE("GPL");
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-module_param(radio_nr, int, 0);
-
-static void __exit terratec_cleanup_module(void)
+static void __exit terratec_exit(void)
 {
-	video_unregister_device(&terratec_radio);
-	release_region(io,2);
-	printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
+	struct terratec *tt = &terratec_card;
+	struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+
+	video_unregister_device(&tt->vdev);
+	v4l2_device_unregister(&tt->v4l2_dev);
+	release_region(tt->io, 2);
+	v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n");
 }
 
 module_init(terratec_init);
-module_exit(terratec_cleanup_module);
+module_exit(terratec_exit);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-trust.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-trust.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-trust.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-trust.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,49 +19,15 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 2048,
-		.default_value = 65535,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	},{
-		.id            = V4L2_CID_AUDIO_BASS,
-		.name          = "Bass",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 4370,
-		.default_value = 32768,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	},{
-		.id            = V4L2_CID_AUDIO_TREBLE,
-		.name          = "Treble",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 4370,
-		.default_value = 32768,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	},
-};
+MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
+MODULE_LICENSE("GPL");
 
 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
 
@@ -71,26 +37,41 @@ static struct v4l2_queryctrl radio_qctrl
 
 static int io = CONFIG_RADIO_TRUST_PORT;
 static int radio_nr = -1;
-static int ioval = 0xf;
-static __u16 curvol;
-static __u16 curbass;
-static __u16 curtreble;
-static unsigned long curfreq;
-static int curstereo;
-static int curmute;
-static unsigned long in_use;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct trust {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
+	int ioval;
+	__u16 curvol;
+	__u16 curbass;
+	__u16 curtreble;
+	int muted;
+	unsigned long curfreq;
+	int curstereo;
+	int curmute;
+	struct mutex lock;
+};
+
+static struct trust trust_card;
 
 /* i2c addresses */
 #define TDA7318_ADDR 0x88
 #define TSA6060T_ADDR 0xc4
 
-#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
-#define TR_SET_SCL outb(ioval |= 2, io)
-#define TR_CLR_SCL outb(ioval &= 0xfd, io)
-#define TR_SET_SDA outb(ioval |= 1, io)
-#define TR_CLR_SDA outb(ioval &= 0xfe, io)
+#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0)
+#define TR_SET_SCL outb(tr->ioval |= 2, tr->io)
+#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io)
+#define TR_SET_SDA outb(tr->ioval |= 1, tr->io)
+#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io)
 
-static void write_i2c(int n, ...)
+static void write_i2c(struct trust *tr, int n, ...)
 {
 	unsigned char val, mask;
 	va_list args;
@@ -136,62 +117,77 @@ static void write_i2c(int n, ...)
 	va_end(args);
 }
 
-static void tr_setvol(__u16 vol)
+static void tr_setvol(struct trust *tr, __u16 vol)
 {
-	curvol = vol / 2048;
-	write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
+	mutex_lock(&tr->lock);
+	tr->curvol = vol / 2048;
+	write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f);
+	mutex_unlock(&tr->lock);
 }
 
 static int basstreble2chip[15] = {
 	0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
 };
 
-static void tr_setbass(__u16 bass)
+static void tr_setbass(struct trust *tr, __u16 bass)
 {
-	curbass = bass / 4370;
-	write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
+	mutex_lock(&tr->lock);
+	tr->curbass = bass / 4370;
+	write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]);
+	mutex_unlock(&tr->lock);
 }
 
-static void tr_settreble(__u16 treble)
+static void tr_settreble(struct trust *tr, __u16 treble)
 {
-	curtreble = treble / 4370;
-	write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
+	mutex_lock(&tr->lock);
+	tr->curtreble = treble / 4370;
+	write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]);
+	mutex_unlock(&tr->lock);
 }
 
-static void tr_setstereo(int stereo)
+static void tr_setstereo(struct trust *tr, int stereo)
 {
-	curstereo = !!stereo;
-	ioval = (ioval & 0xfb) | (!curstereo << 2);
-	outb(ioval, io);
+	mutex_lock(&tr->lock);
+	tr->curstereo = !!stereo;
+	tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2);
+	outb(tr->ioval, tr->io);
+	mutex_unlock(&tr->lock);
 }
 
-static void tr_setmute(int mute)
+static void tr_setmute(struct trust *tr, int mute)
 {
-	curmute = !!mute;
-	ioval = (ioval & 0xf7) | (curmute << 3);
-	outb(ioval, io);
+	mutex_lock(&tr->lock);
+	tr->curmute = !!mute;
+	tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3);
+	outb(tr->ioval, tr->io);
+	mutex_unlock(&tr->lock);
 }
 
-static int tr_getsigstr(void)
+static int tr_getsigstr(struct trust *tr)
 {
 	int i, v;
 
-	for(i = 0, v = 0; i < 100; i++) v |= inb(io);
-	return (v & 1)? 0 : 0xffff;
+	mutex_lock(&tr->lock);
+	for (i = 0, v = 0; i < 100; i++)
+		v |= inb(tr->io);
+	mutex_unlock(&tr->lock);
+	return (v & 1) ? 0 : 0xffff;
 }
 
-static int tr_getstereo(void)
+static int tr_getstereo(struct trust *tr)
 {
 	/* don't know how to determine it, just return the setting */
-	return curstereo;
+	return tr->curstereo;
 }
 
-static void tr_setfreq(unsigned long f)
+static void tr_setfreq(struct trust *tr, unsigned long f)
 {
+	mutex_lock(&tr->lock);
+	tr->curfreq = f;
 	f /= 160;	/* Convert to 10 kHz units	*/
-	f += 1070;	/* Add 10.7 MHz IF			*/
-
-	write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+	f += 1070;	/* Add 10.7 MHz IF		*/
+	write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+	mutex_unlock(&tr->lock);
 }
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -199,68 +195,75 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-trust", sizeof(v->driver));
 	strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
+	struct trust *tr = video_drvdata(file);
+
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (87.5*16000);
-	v->rangehigh = (108*16000);
-	v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+	v->rangelow = 87.5 * 16000;
+	v->rangehigh = 108 * 16000;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	v->capability = V4L2_TUNER_CAP_LOW;
-	if (tr_getstereo())
+	if (tr_getstereo(tr))
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 	else
 		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = tr_getsigstr();
+	v->signal = tr_getsigstr(tr);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
+	struct trust *tr = video_drvdata(file);
 
+	if (v->index)
+		return -EINVAL;
+	tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO);
 	return 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	curfreq = f->frequency;
-	tr_setfreq(curfreq);
+	struct trust *tr = video_drvdata(file);
+
+	tr_setfreq(tr, f->frequency);
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
+	struct trust *tr = video_drvdata(file);
+
 	f->type = V4L2_TUNER_RADIO;
-	f->frequency = curfreq;
+	f->frequency = tr->curfreq;
 	return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535);
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768);
 	}
 	return -EINVAL;
 }
@@ -268,18 +271,20 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
+	struct trust *tr = video_drvdata(file);
+
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = curmute;
+		ctrl->value = tr->curmute;
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = curvol * 2048;
+		ctrl->value = tr->curvol * 2048;
 		return 0;
 	case V4L2_CID_AUDIO_BASS:
-		ctrl->value = curbass * 4370;
+		ctrl->value = tr->curbass * 4370;
 		return 0;
 	case V4L2_CID_AUDIO_TREBLE:
-		ctrl->value = curtreble * 4370;
+		ctrl->value = tr->curtreble * 4370;
 		return 0;
 	}
 	return -EINVAL;
@@ -288,34 +293,25 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
+	struct trust *tr = video_drvdata(file);
+
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		tr_setmute(ctrl->value);
+		tr_setmute(tr, ctrl->value);
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		tr_setvol(ctrl->value);
+		tr_setvol(tr, ctrl->value);
 		return 0;
 	case V4L2_CID_AUDIO_BASS:
-		tr_setbass(ctrl->value);
+		tr_setbass(tr, ctrl->value);
 		return 0;
 	case V4L2_CID_AUDIO_TREBLE:
-		tr_settreble(ctrl->value);
+		tr_settreble(tr, ctrl->value);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -324,34 +320,26 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 				struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static int trust_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int trust_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+				struct v4l2_audio *a)
 {
-	clear_bit(0, &in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations trust_fops = {
 	.owner		= THIS_MODULE,
-	.open           = trust_exclusive_open,
-	.release        = trust_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -370,59 +358,72 @@ static const struct v4l2_ioctl_ops trust
 	.vidioc_s_input     = vidioc_s_input,
 };
 
-static struct video_device trust_radio = {
-	.name		= "Trust FM Radio",
-	.fops           = &trust_fops,
-	.ioctl_ops 	= &trust_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init trust_init(void)
 {
-	if(io == -1) {
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+	struct trust *tr = &trust_card;
+	struct v4l2_device *v4l2_dev = &tr->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name));
+	tr->io = io;
+	tr->ioval = 0xf;
+	mutex_init(&tr->lock);
+
+	if (tr->io == -1) {
+		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n");
 		return -EINVAL;
 	}
-	if(!request_region(io, 2, "Trust FM Radio")) {
-		printk(KERN_ERR "trust: port 0x%x already in use\n", io);
+	if (!request_region(tr->io, 2, "Trust FM Radio")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io);
 		return -EBUSY;
 	}
-	if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 2);
+
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(tr->io, 2);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
+
+	strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name));
+	tr->vdev.v4l2_dev = v4l2_dev;
+	tr->vdev.fops = &trust_fops;
+	tr->vdev.ioctl_ops = &trust_ioctl_ops;
+	tr->vdev.release = video_device_release_empty;
+	video_set_drvdata(&tr->vdev, tr);
+
+	if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(tr->io, 2);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
+	v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
 
-	write_i2c(2, TDA7318_ADDR, 0x80);	/* speaker att. LF = 0 dB */
-	write_i2c(2, TDA7318_ADDR, 0xa0);	/* speaker att. RF = 0 dB */
-	write_i2c(2, TDA7318_ADDR, 0xc0);	/* speaker att. LR = 0 dB */
-	write_i2c(2, TDA7318_ADDR, 0xe0);	/* speaker att. RR = 0 dB */
-	write_i2c(2, TDA7318_ADDR, 0x40);	/* stereo 1 input, gain = 18.75 dB */
+	write_i2c(tr, 2, TDA7318_ADDR, 0x80);	/* speaker att. LF = 0 dB */
+	write_i2c(tr, 2, TDA7318_ADDR, 0xa0);	/* speaker att. RF = 0 dB */
+	write_i2c(tr, 2, TDA7318_ADDR, 0xc0);	/* speaker att. LR = 0 dB */
+	write_i2c(tr, 2, TDA7318_ADDR, 0xe0);	/* speaker att. RR = 0 dB */
+	write_i2c(tr, 2, TDA7318_ADDR, 0x40);	/* stereo 1 input, gain = 18.75 dB */
 
-	tr_setvol(0x8000);
-	tr_setbass(0x8000);
-	tr_settreble(0x8000);
-	tr_setstereo(1);
+	tr_setvol(tr, 0xffff);
+	tr_setbass(tr, 0x8000);
+	tr_settreble(tr, 0x8000);
+	tr_setstereo(tr, 1);
 
 	/* mute card - prevents noisy bootups */
-	tr_setmute(1);
+	tr_setmute(tr, 1);
 
 	return 0;
 }
 
-MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-module_param(radio_nr, int, 0);
-
 static void __exit cleanup_trust_module(void)
 {
-	video_unregister_device(&trust_radio);
-	release_region(io, 2);
+	struct trust *tr = &trust_card;
+
+	video_unregister_device(&tr->vdev);
+	v4l2_device_unregister(&tr->v4l2_dev);
+	release_region(tr->io, 2);
 }
 
 module_init(trust_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-typhoon.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-typhoon.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-typhoon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-typhoon.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,37 +34,15 @@
 #include <linux/module.h>	/* Modules                        */
 #include <linux/init.h>		/* Initdata                       */
 #include <linux/ioport.h>	/* request_region		  */
-#include <linux/proc_fs.h>	/* radio card status report	  */
-#include <linux/seq_file.h>
-#include <asm/io.h>		/* outb, outb_p                   */
-#include <asm/uaccess.h>	/* copy to/from user              */
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/videodev2.h>	/* kernel radio structs           */
-#include <media/v4l2-common.h>
+#include <linux/io.h>		/* outb, outb_p                   */
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,1,1)
-#define BANNER "Typhoon Radio Card driver v0.1.1\n"
-
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 1<<14,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
-
+MODULE_AUTHOR("Dr. Henrik Seidel");
+MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
+MODULE_LICENSE("GPL");
 
 #ifndef CONFIG_RADIO_TYPHOON_PORT
 #define CONFIG_RADIO_TYPHOON_PORT -1
@@ -74,13 +52,26 @@ static struct v4l2_queryctrl radio_qctrl
 #define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
 #endif
 
-#ifndef CONFIG_PROC_FS
-#undef CONFIG_RADIO_TYPHOON_PROC_FS
-#endif
+static int io = CONFIG_RADIO_TYPHOON_PORT;
+static int radio_nr = -1;
 
-struct typhoon_device {
-	unsigned long in_use;
-	int iobase;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
+
+module_param(radio_nr, int, 0);
+
+static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ;
+module_param(mutefreq, ulong, 0);
+MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
+
+#define BANNER "Typhoon Radio Card driver v0.1.1\n"
+
+struct typhoon {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	int curvol;
 	int muted;
 	unsigned long curfreq;
@@ -88,25 +79,19 @@ struct typhoon_device {
 	struct mutex lock;
 };
 
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
-				   unsigned long frequency);
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
-static void typhoon_mute(struct typhoon_device *dev);
-static void typhoon_unmute(struct typhoon_device *dev);
-static int typhoon_setvol(struct typhoon_device *dev, int vol);
+static struct typhoon typhoon_card;
 
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
+static void typhoon_setvol_generic(struct typhoon *dev, int vol)
 {
 	mutex_lock(&dev->lock);
 	vol >>= 14;				/* Map 16 bit to 2 bit */
 	vol &= 3;
-	outb_p(vol / 2, dev->iobase);		/* Set the volume, high bit. */
-	outb_p(vol % 2, dev->iobase + 2);	/* Set the volume, low bit. */
+	outb_p(vol / 2, dev->io);		/* Set the volume, high bit. */
+	outb_p(vol % 2, dev->io + 2);	/* Set the volume, low bit. */
 	mutex_unlock(&dev->lock);
 }
 
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
+static int typhoon_setfreq_generic(struct typhoon *dev,
 				   unsigned long frequency)
 {
 	unsigned long outval;
@@ -130,22 +115,22 @@ static int typhoon_setfreq_generic(struc
 	outval -= (10 * x * x + 10433) / 20866;
 	outval += 4 * x - 11505;
 
-	outb_p((outval >> 8) & 0x01, dev->iobase + 4);
-	outb_p(outval >> 9, dev->iobase + 6);
-	outb_p(outval & 0xff, dev->iobase + 8);
+	outb_p((outval >> 8) & 0x01, dev->io + 4);
+	outb_p(outval >> 9, dev->io + 6);
+	outb_p(outval & 0xff, dev->io + 8);
 	mutex_unlock(&dev->lock);
 
 	return 0;
 }
 
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
+static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency)
 {
 	typhoon_setfreq_generic(dev, frequency);
 	dev->curfreq = frequency;
 	return 0;
 }
 
-static void typhoon_mute(struct typhoon_device *dev)
+static void typhoon_mute(struct typhoon *dev)
 {
 	if (dev->muted == 1)
 		return;
@@ -154,7 +139,7 @@ static void typhoon_mute(struct typhoon_
 	dev->muted = 1;
 }
 
-static void typhoon_unmute(struct typhoon_device *dev)
+static void typhoon_unmute(struct typhoon *dev)
 {
 	if (dev->muted == 0)
 		return;
@@ -163,7 +148,7 @@ static void typhoon_unmute(struct typhoo
 	dev->muted = 0;
 }
 
-static int typhoon_setvol(struct typhoon_device *dev, int vol)
+static int typhoon_setvol(struct typhoon *dev, int vol)
 {
 	if (dev->muted && vol != 0) {	/* user is unmuting the card */
 		dev->curvol = vol;
@@ -188,9 +173,9 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
 	strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
@@ -200,10 +185,10 @@ static int vidioc_g_tuner(struct file *f
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (87.5*16000);
-	v->rangehigh = (108*16000);
+	v->rangelow = 87.5 * 16000;
+	v->rangehigh = 108 * 16000;
 	v->rxsubchans = V4L2_TUNER_SUB_MONO;
 	v->capability = V4L2_TUNER_CAP_LOW;
 	v->audmode = V4L2_TUNER_MODE_MONO;
@@ -214,44 +199,37 @@ static int vidioc_g_tuner(struct file *f
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct typhoon_device *typhoon = video_drvdata(file);
+	struct typhoon *dev = video_drvdata(file);
 
-	typhoon->curfreq = f->frequency;
-	typhoon_setfreq(typhoon, typhoon->curfreq);
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = dev->curfreq;
 	return 0;
 }
 
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct typhoon_device *typhoon = video_drvdata(file);
-
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = typhoon->curfreq;
+	struct typhoon *dev = video_drvdata(file);
 
+	dev->curfreq = f->frequency;
+	typhoon_setfreq(dev, dev->curfreq);
 	return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535);
 	}
 	return -EINVAL;
 }
@@ -259,14 +237,14 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct typhoon_device *typhoon = video_drvdata(file);
+	struct typhoon *dev = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = typhoon->muted;
+		ctrl->value = dev->muted;
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = typhoon->curvol;
+		ctrl->value = dev->curvol;
 		return 0;
 	}
 	return -EINVAL;
@@ -275,33 +253,22 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl (struct file *file, void *priv,
 					struct v4l2_control *ctrl)
 {
-	struct typhoon_device *typhoon = video_drvdata(file);
+	struct typhoon *dev = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value)
-			typhoon_mute(typhoon);
+			typhoon_mute(dev);
 		else
-			typhoon_unmute(typhoon);
+			typhoon_unmute(dev);
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		typhoon_setvol(typhoon, ctrl->value);
+		typhoon_setvol(dev, ctrl->value);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -310,45 +277,50 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct typhoon_device typhoon_unit =
-{
-	.iobase		= CONFIG_RADIO_TYPHOON_PORT,
-	.curfreq	= CONFIG_RADIO_TYPHOON_MUTEFREQ,
-	.mutefreq	= CONFIG_RADIO_TYPHOON_MUTEFREQ,
-};
-
-static int typhoon_exclusive_open(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0;
+	return a->index ? -EINVAL : 0;
 }
 
-static int typhoon_exclusive_release(struct file *file)
+static int vidioc_log_status(struct file *file, void *priv)
 {
-	clear_bit(0, &typhoon_unit.in_use);
+	struct typhoon *dev = video_drvdata(file);
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+
+	v4l2_info(v4l2_dev, BANNER);
+#ifdef MODULE
+	v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n");
+#else
+	v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n");
+#endif
+	v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4);
+	v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol);
+	v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ?  "on" : "off");
+	v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io);
+	v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4);
 	return 0;
 }
 
 static const struct v4l2_file_operations typhoon_fops = {
 	.owner		= THIS_MODULE,
-	.open           = typhoon_exclusive_open,
-	.release        = typhoon_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
+	.vidioc_log_status  = vidioc_log_status,
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
@@ -363,125 +335,72 @@ static const struct v4l2_ioctl_ops typho
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device typhoon_radio = {
-	.name		= "Typhoon Radio",
-	.fops           = &typhoon_fops,
-	.ioctl_ops 	= &typhoon_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-
-static int typhoon_proc_show(struct seq_file *m, void *v)
-{
-	#ifdef MODULE
-	    #define MODULEPROCSTRING "Driver loaded as a module"
-	#else
-	    #define MODULEPROCSTRING "Driver compiled into kernel"
-	#endif
-
-	seq_puts(m, BANNER);
-	seq_puts(m, "Load type: " MODULEPROCSTRING "\n\n");
-	seq_printf(m, "frequency = %lu kHz\n",
-		typhoon_unit.curfreq >> 4);
-	seq_printf(m, "volume = %d\n", typhoon_unit.curvol);
-	seq_printf(m, "mute = %s\n", typhoon_unit.muted ?
-		"on" : "off");
-	seq_printf(m, "iobase = 0x%x\n", typhoon_unit.iobase);
-	seq_printf(m, "mute frequency = %lu kHz\n",
-		typhoon_unit.mutefreq >> 4);
-	return 0;
-}
-
-static int typhoon_proc_open(struct inode *inode, struct file *file)
+static int __init typhoon_init(void)
 {
-	return single_open(file, typhoon_proc_show, NULL);
-}
-
-static const struct file_operations typhoon_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= typhoon_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
-
-MODULE_AUTHOR("Dr. Henrik Seidel");
-MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
-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 Typhoon card (0x316 or 0x336)");
-module_param(radio_nr, int, 0);
+	struct typhoon *dev = &typhoon_card;
+	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+	int res;
 
-#ifdef MODULE
-static unsigned long mutefreq;
-module_param(mutefreq, ulong, 0);
-MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
-#endif
+	strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
+	dev->io = io;
+	dev->curfreq = dev->mutefreq = mutefreq;
 
-static int __init typhoon_init(void)
-{
-#ifdef MODULE
-	if (io == -1) {
-		printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
+	if (dev->io == -1) {
+		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
 		return -EINVAL;
 	}
-	typhoon_unit.iobase = io;
 
-	if (mutefreq < 87000 || mutefreq > 108500) {
-		printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
-		printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
+	if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+		v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
+		v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
 		return -EINVAL;
 	}
-	typhoon_unit.mutefreq = mutefreq;
-#endif /* MODULE */
 
-	printk(KERN_INFO BANNER);
-	mutex_init(&typhoon_unit.lock);
-	io = typhoon_unit.iobase;
-	if (!request_region(io, 8, "typhoon")) {
-		printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
-		       typhoon_unit.iobase);
+	mutex_init(&dev->lock);
+	if (!request_region(dev->io, 8, "typhoon")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n",
+		       dev->io);
 		return -EBUSY;
 	}
 
-	video_set_drvdata(&typhoon_radio, &typhoon_unit);
-	if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 8);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(dev->io, 8);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
+	v4l2_info(v4l2_dev, BANNER);
+
+	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+	dev->vdev.v4l2_dev = v4l2_dev;
+	dev->vdev.fops = &typhoon_fops;
+	dev->vdev.ioctl_ops = &typhoon_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) {
+		v4l2_device_unregister(&dev->v4l2_dev);
+		release_region(dev->io, 8);
 		return -EINVAL;
 	}
-	printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
-	printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
-	       typhoon_unit.mutefreq);
-	typhoon_unit.mutefreq <<= 4;
+	v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
+	v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
+	dev->mutefreq <<= 4;
 
 	/* mute card - prevents noisy bootups */
-	typhoon_mute(&typhoon_unit);
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-	if (!proc_create("driver/radio-typhoon", 0, NULL, &typhoon_proc_fops))
-		printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
-#endif
+	typhoon_mute(dev);
 
 	return 0;
 }
 
-static void __exit typhoon_cleanup_module(void)
+static void __exit typhoon_exit(void)
 {
+	struct typhoon *dev = &typhoon_card;
 
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-	remove_proc_entry("driver/radio-typhoon", NULL);
-#endif
-
-	video_unregister_device(&typhoon_radio);
-	release_region(io, 8);
+	video_unregister_device(&dev->vdev);
+	v4l2_device_unregister(&dev->v4l2_dev);
+	release_region(dev->io, 8);
 }
 
 module_init(typhoon_init);
-module_exit(typhoon_cleanup_module);
+module_exit(typhoon_exit);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/radio/radio-zoltrix.c linux-libre-2.6.30-gnu1/drivers/media/radio/radio-zoltrix.c
--- linux-libre-2.6.29-gnu1/drivers/media/radio/radio-zoltrix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/radio/radio-zoltrix.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,33 +33,16 @@
 #include <linux/init.h>		/* Initdata                       */
 #include <linux/ioport.h>	/* request_region		  */
 #include <linux/delay.h>	/* udelay, msleep                 */
-#include <asm/io.h>		/* outb, outb_p                   */
-#include <asm/uaccess.h>	/* copy to/from user              */
 #include <linux/videodev2.h>	/* kernel radio structs           */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
+#include <linux/mutex.h>
 #include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#include <linux/io.h>		/* outb, outb_p                   */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 65535,
-		.step          = 4096,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+MODULE_AUTHOR("C.van Schaik");
+MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_LICENSE("GPL");
 
 #ifndef CONFIG_RADIO_ZOLTRIX_PORT
 #define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -68,9 +51,16 @@ static struct v4l2_queryctrl radio_qctrl
 static int io = CONFIG_RADIO_ZOLTRIX_PORT;
 static int radio_nr = -1;
 
-struct zol_device {
-	unsigned long in_use;
-	int port;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct zoltrix {
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	int io;
 	int curvol;
 	unsigned long curfreq;
 	int muted;
@@ -78,161 +68,158 @@ struct zol_device {
 	struct mutex lock;
 };
 
-static int zol_setvol(struct zol_device *dev, int vol)
+static struct zoltrix zoltrix_card;
+
+static int zol_setvol(struct zoltrix *zol, int vol)
 {
-	dev->curvol = vol;
-	if (dev->muted)
+	zol->curvol = vol;
+	if (zol->muted)
 		return 0;
 
-	mutex_lock(&dev->lock);
+	mutex_lock(&zol->lock);
 	if (vol == 0) {
-		outb(0, io);
-		outb(0, io);
-		inb(io + 3);    /* Zoltrix needs to be read to confirm */
-		mutex_unlock(&dev->lock);
+		outb(0, zol->io);
+		outb(0, zol->io);
+		inb(zol->io + 3);    /* Zoltrix needs to be read to confirm */
+		mutex_unlock(&zol->lock);
 		return 0;
 	}
 
-	outb(dev->curvol-1, io);
+	outb(zol->curvol-1, zol->io);
 	msleep(10);
-	inb(io + 2);
-	mutex_unlock(&dev->lock);
+	inb(zol->io + 2);
+	mutex_unlock(&zol->lock);
 	return 0;
 }
 
-static void zol_mute(struct zol_device *dev)
+static void zol_mute(struct zoltrix *zol)
 {
-	dev->muted = 1;
-	mutex_lock(&dev->lock);
-	outb(0, io);
-	outb(0, io);
-	inb(io + 3);            /* Zoltrix needs to be read to confirm */
-	mutex_unlock(&dev->lock);
+	zol->muted = 1;
+	mutex_lock(&zol->lock);
+	outb(0, zol->io);
+	outb(0, zol->io);
+	inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
+	mutex_unlock(&zol->lock);
 }
 
-static void zol_unmute(struct zol_device *dev)
+static void zol_unmute(struct zoltrix *zol)
 {
-	dev->muted = 0;
-	zol_setvol(dev, dev->curvol);
+	zol->muted = 0;
+	zol_setvol(zol, zol->curvol);
 }
 
-static int zol_setfreq(struct zol_device *dev, unsigned long freq)
+static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
 {
 	/* tunes the radio to the desired frequency */
+	struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
 	unsigned long long bitmask, f, m;
-	unsigned int stereo = dev->stereo;
+	unsigned int stereo = zol->stereo;
 	int i;
 
 	if (freq == 0) {
-		printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n");
+		v4l2_warn(v4l2_dev, "cannot set a frequency of 0.\n");
 		return -EINVAL;
 	}
 
 	m = (freq / 160 - 8800) * 2;
-	f = (unsigned long long) m + 0x4d1c;
+	f = (unsigned long long)m + 0x4d1c;
 
 	bitmask = 0xc480402c10080000ull;
 	i = 45;
 
-	mutex_lock(&dev->lock);
+	mutex_lock(&zol->lock);
 
-	outb(0, io);
-	outb(0, io);
-	inb(io + 3);            /* Zoltrix needs to be read to confirm */
+	zol->curfreq = freq;
 
-	outb(0x40, io);
-	outb(0xc0, io);
+	outb(0, zol->io);
+	outb(0, zol->io);
+	inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
 
-	bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
+	outb(0x40, zol->io);
+	outb(0xc0, zol->io);
+
+	bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31));
 	while (i--) {
 		if ((bitmask & 0x8000000000000000ull) != 0) {
-			outb(0x80, io);
+			outb(0x80, zol->io);
 			udelay(50);
-			outb(0x00, io);
+			outb(0x00, zol->io);
 			udelay(50);
-			outb(0x80, io);
+			outb(0x80, zol->io);
 			udelay(50);
 		} else {
-			outb(0xc0, io);
+			outb(0xc0, zol->io);
 			udelay(50);
-			outb(0x40, io);
+			outb(0x40, zol->io);
 			udelay(50);
-			outb(0xc0, io);
+			outb(0xc0, zol->io);
 			udelay(50);
 		}
 		bitmask *= 2;
 	}
 	/* termination sequence */
-	outb(0x80, io);
-	outb(0xc0, io);
-	outb(0x40, io);
+	outb(0x80, zol->io);
+	outb(0xc0, zol->io);
+	outb(0x40, zol->io);
 	udelay(1000);
-	inb(io+2);
+	inb(zol->io + 2);
 
 	udelay(1000);
 
-	if (dev->muted)
-	{
-		outb(0, io);
-		outb(0, io);
-		inb(io + 3);
+	if (zol->muted) {
+		outb(0, zol->io);
+		outb(0, zol->io);
+		inb(zol->io + 3);
 		udelay(1000);
 	}
 
-	mutex_unlock(&dev->lock);
+	mutex_unlock(&zol->lock);
 
-	if(!dev->muted)
-	{
-		zol_setvol(dev, dev->curvol);
-	}
+	if (!zol->muted)
+		zol_setvol(zol, zol->curvol);
 	return 0;
 }
 
 /* Get signal strength */
-
-static int zol_getsigstr(struct zol_device *dev)
+static int zol_getsigstr(struct zoltrix *zol)
 {
 	int a, b;
 
-	mutex_lock(&dev->lock);
-	outb(0x00, io);         /* This stuff I found to do nothing */
-	outb(dev->curvol, io);
+	mutex_lock(&zol->lock);
+	outb(0x00, zol->io);         /* This stuff I found to do nothing */
+	outb(zol->curvol, zol->io);
 	msleep(20);
 
-	a = inb(io);
+	a = inb(zol->io);
 	msleep(10);
-	b = inb(io);
+	b = inb(zol->io);
 
-	mutex_unlock(&dev->lock);
+	mutex_unlock(&zol->lock);
 
 	if (a != b)
-		return (0);
+		return 0;
 
-	if ((a == 0xcf) || (a == 0xdf)  /* I found this out by playing */
-		|| (a == 0xef))       /* with a binary scanner on the card io */
-		return (1);
-	return (0);
+	/* I found this out by playing with a binary scanner on the card io */
+	return a == 0xcf || a == 0xdf || a == 0xef;
 }
 
-static int zol_is_stereo (struct zol_device *dev)
+static int zol_is_stereo(struct zoltrix *zol)
 {
 	int x1, x2;
 
-	mutex_lock(&dev->lock);
+	mutex_lock(&zol->lock);
 
-	outb(0x00, io);
-	outb(dev->curvol, io);
+	outb(0x00, zol->io);
+	outb(zol->curvol, zol->io);
 	msleep(20);
 
-	x1 = inb(io);
+	x1 = inb(zol->io);
 	msleep(10);
-	x2 = inb(io);
+	x2 = inb(zol->io);
 
-	mutex_unlock(&dev->lock);
+	mutex_unlock(&zol->lock);
 
-	if ((x1 == x2) && (x1 == 0xcf))
-		return 1;
-	return 0;
+	return x1 == x2 && x1 == 0xcf;
 }
 
 static int vidioc_querycap(struct file *file, void  *priv,
@@ -240,59 +227,54 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
 	strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
-	sprintf(v->bus_info, "ISA");
+	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
 	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	struct zol_device *zol = video_drvdata(file);
+	struct zoltrix *zol = video_drvdata(file);
 
 	if (v->index > 0)
 		return -EINVAL;
 
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = (88*16000);
-	v->rangehigh = (108*16000);
-	v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+	v->rangelow = 88 * 16000;
+	v->rangehigh = 108 * 16000;
+	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	v->capability = V4L2_TUNER_CAP_LOW;
 	if (zol_is_stereo(zol))
 		v->audmode = V4L2_TUNER_MODE_STEREO;
 	else
 		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF*zol_getsigstr(zol);
+	v->signal = 0xFFFF * zol_getsigstr(zol);
 	return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
 					struct v4l2_tuner *v)
 {
-	if (v->index > 0)
-		return -EINVAL;
-	return 0;
+	return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct zol_device *zol = video_drvdata(file);
+	struct zoltrix *zol = video_drvdata(file);
 
-	zol->curfreq = f->frequency;
-	if (zol_setfreq(zol, zol->curfreq) != 0) {
-		printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+	if (zol_setfreq(zol, f->frequency) != 0)
 		return -EINVAL;
-	}
 	return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f)
 {
-	struct zol_device *zol = video_drvdata(file);
+	struct zoltrix *zol = video_drvdata(file);
 
 	f->type = V4L2_TUNER_RADIO;
 	f->frequency = zol->curfreq;
@@ -302,14 +284,11 @@ static int vidioc_g_frequency(struct fil
 static int vidioc_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *qc)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]),
-						sizeof(*qc));
-			return 0;
-		}
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535);
 	}
 	return -EINVAL;
 }
@@ -317,7 +296,7 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct zol_device *zol = video_drvdata(file);
+	struct zoltrix *zol = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -333,7 +312,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct zol_device *zol = video_drvdata(file);
+	struct zoltrix *zol = video_drvdata(file);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -341,43 +320,30 @@ static int vidioc_s_ctrl(struct file *fi
 			zol_mute(zol);
 		else {
 			zol_unmute(zol);
-			zol_setvol(zol,zol->curvol);
+			zol_setvol(zol, zol->curvol);
 		}
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
-		zol_setvol(zol,ctrl->value/4096);
+		zol_setvol(zol, ctrl->value / 4096);
 		return 0;
 	}
 	zol->stereo = 1;
-	if (zol_setfreq(zol, zol->curfreq) != 0) {
-		printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+	if (zol_setfreq(zol, zol->curfreq) != 0)
 		return -EINVAL;
-	}
 #if 0
 /* FIXME: Implement stereo/mono switch on V4L2 */
-			if (v->mode & VIDEO_SOUND_STEREO) {
-				zol->stereo = 1;
-				zol_setfreq(zol, zol->curfreq);
-			}
-			if (v->mode & VIDEO_SOUND_MONO) {
-				zol->stereo = 0;
-				zol_setfreq(zol, zol->curfreq);
-			}
+	if (v->mode & VIDEO_SOUND_STEREO) {
+		zol->stereo = 1;
+		zol_setfreq(zol, zol->curfreq);
+	}
+	if (v->mode & VIDEO_SOUND_MONO) {
+		zol->stereo = 0;
+		zol_setfreq(zol, zol->curfreq);
+	}
 #endif
 	return -EINVAL;
 }
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
 {
 	*i = 0;
@@ -386,37 +352,27 @@ static int vidioc_g_input(struct file *f
 
 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
 {
-	if (i != 0)
-		return -EINVAL;
-	return 0;
+	return i ? -EINVAL : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
 					struct v4l2_audio *a)
 {
-	if (a->index != 0)
-		return -EINVAL;
+	a->index = 0;
+	strlcpy(a->name, "Radio", sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
 	return 0;
 }
 
-static struct zol_device zoltrix_unit;
-
-static int zoltrix_exclusive_open(struct file *file)
-{
-	return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0;
-}
-
-static int zoltrix_exclusive_release(struct file *file)
+static int vidioc_s_audio(struct file *file, void *priv,
+					struct v4l2_audio *a)
 {
-	clear_bit(0, &zoltrix_unit.in_use);
-	return 0;
+	return a->index ? -EINVAL : 0;
 }
 
 static const struct v4l2_file_operations zoltrix_fops =
 {
 	.owner		= THIS_MODULE,
-	.open           = zoltrix_exclusive_open,
-	.release        = zoltrix_exclusive_release,
 	.ioctl		= video_ioctl2,
 };
 
@@ -435,67 +391,75 @@ static const struct v4l2_ioctl_ops zoltr
 	.vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device zoltrix_radio = {
-	.name		= "Zoltrix Radio Plus",
-	.fops           = &zoltrix_fops,
-	.ioctl_ops 	= &zoltrix_ioctl_ops,
-	.release	= video_device_release_empty,
-};
-
 static int __init zoltrix_init(void)
 {
-	if (io == -1) {
-		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+	struct zoltrix *zol = &zoltrix_card;
+	struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
+	int res;
+
+	strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
+	zol->io = io;
+	if (zol->io == -1) {
+		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n");
 		return -EINVAL;
 	}
-	if ((io != 0x20c) && (io != 0x30c)) {
-		printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
+	if (zol->io != 0x20c && zol->io != 0x30c) {
+		v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
 		return -ENXIO;
 	}
 
-	video_set_drvdata(&zoltrix_radio, &zoltrix_unit);
-	if (!request_region(io, 2, "zoltrix")) {
-		printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+	if (!request_region(zol->io, 2, "zoltrix")) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
 		return -EBUSY;
 	}
 
-	if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-		release_region(io, 2);
+	res = v4l2_device_register(NULL, v4l2_dev);
+	if (res < 0) {
+		release_region(zol->io, 2);
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		return res;
+	}
+
+	strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+	zol->vdev.v4l2_dev = v4l2_dev;
+	zol->vdev.fops = &zoltrix_fops;
+	zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+	zol->vdev.release = video_device_release_empty;
+	video_set_drvdata(&zol->vdev, zol);
+
+	if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_device_unregister(v4l2_dev);
+		release_region(zol->io, 2);
 		return -EINVAL;
 	}
-	printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
+	v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
 
-	mutex_init(&zoltrix_unit.lock);
+	mutex_init(&zol->lock);
 
 	/* mute card - prevents noisy bootups */
 
 	/* this ensures that the volume is all the way down  */
 
-	outb(0, io);
-	outb(0, io);
+	outb(0, zol->io);
+	outb(0, zol->io);
 	msleep(20);
-	inb(io + 3);
+	inb(zol->io + 3);
 
-	zoltrix_unit.curvol = 0;
-	zoltrix_unit.stereo = 1;
+	zol->curvol = 0;
+	zol->stereo = 1;
 
 	return 0;
 }
 
-MODULE_AUTHOR("C.van Schaik");
-MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit zoltrix_cleanup_module(void)
+static void __exit zoltrix_exit(void)
 {
-	video_unregister_device(&zoltrix_radio);
-	release_region(io, 2);
+	struct zoltrix *zol = &zoltrix_card;
+
+	video_unregister_device(&zol->vdev);
+	v4l2_device_unregister(&zol->v4l2_dev);
+	release_region(zol->io, 2);
 }
 
 module_init(zoltrix_init);
-module_exit(zoltrix_cleanup_module);
+module_exit(zoltrix_exit);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/adv7170.c linux-libre-2.6.30-gnu1/drivers/media/video/adv7170.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/adv7170.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/adv7170.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,15 +34,16 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin");
 MODULE_LICENSE("GPL");
 
+
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -50,38 +51,43 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 /* ----------------------------------------------------------------------- */
 
 struct adv7170 {
+	struct v4l2_subdev sd;
 	unsigned char reg[128];
 
-	int norm;
+	v4l2_std_id norm;
 	int input;
-	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
 };
 
+static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct adv7170, sd);
+}
+
 static char *inputs[] = { "pass_through", "play_back" };
-static char *norms[] = { "PAL", "NTSC" };
 
 /* ----------------------------------------------------------------------- */
 
-static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
-	struct adv7170 *encoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct adv7170 *encoder = to_adv7170(sd);
 
 	encoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int adv7170_read(struct i2c_client *client, u8 reg)
+static inline int adv7170_read(struct v4l2_subdev *sd, u8 reg)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int adv7170_write_block(struct i2c_client *client,
+static int adv7170_write_block(struct v4l2_subdev *sd,
 		     const u8 *data, unsigned int len)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct adv7170 *encoder = to_adv7170(sd);
 	int ret = -1;
 	u8 reg;
 
@@ -89,7 +95,6 @@ static int adv7170_write_block(struct i2
 	 * the adapter understands raw I2C */
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		/* do raw I2C, not smbus compatible */
-		struct adv7170 *encoder = i2c_get_clientdata(client);
 		u8 block_data[32];
 		int block_len;
 
@@ -110,7 +115,7 @@ static int adv7170_write_block(struct i2
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			ret = adv7170_write(client, reg, *data++);
+			ret = adv7170_write(sd, reg, *data++);
 			if (ret < 0)
 				break;
 			len -= 2;
@@ -128,203 +133,162 @@ static int adv7170_write_block(struct i2
 #define TR1PLAY	    0x00
 
 static const unsigned char init_NTSC[] = {
-	0x00, 0x10,		// MR0
-	0x01, 0x20,		// MR1
-	0x02, 0x0e,		// MR2 RTC control: bits 2 and 1
-	0x03, 0x80,		// MR3
-	0x04, 0x30,		// MR4
-	0x05, 0x00,		// Reserved
-	0x06, 0x00,		// Reserved
-	0x07, TR0MODE,		// TM0
-	0x08, TR1CAPT,		// TM1
-	0x09, 0x16,		// Fsc0
-	0x0a, 0x7c,		// Fsc1
-	0x0b, 0xf0,		// Fsc2
-	0x0c, 0x21,		// Fsc3
-	0x0d, 0x00,		// Subcarrier Phase
-	0x0e, 0x00,		// Closed Capt. Ext 0
-	0x0f, 0x00,		// Closed Capt. Ext 1
-	0x10, 0x00,		// Closed Capt. 0
-	0x11, 0x00,		// Closed Capt. 1
-	0x12, 0x00,		// Pedestal Ctl 0
-	0x13, 0x00,		// Pedestal Ctl 1
-	0x14, 0x00,		// Pedestal Ctl 2
-	0x15, 0x00,		// Pedestal Ctl 3
-	0x16, 0x00,		// CGMS_WSS_0
-	0x17, 0x00,		// CGMS_WSS_1
-	0x18, 0x00,		// CGMS_WSS_2
-	0x19, 0x00,		// Teletext Ctl
+	0x00, 0x10,		/* MR0 */
+	0x01, 0x20,		/* MR1 */
+	0x02, 0x0e,		/* MR2 RTC control: bits 2 and 1 */
+	0x03, 0x80,		/* MR3 */
+	0x04, 0x30,		/* MR4 */
+	0x05, 0x00,		/* Reserved */
+	0x06, 0x00,		/* Reserved */
+	0x07, TR0MODE,		/* TM0 */
+	0x08, TR1CAPT,		/* TM1 */
+	0x09, 0x16,		/* Fsc0 */
+	0x0a, 0x7c,		/* Fsc1 */
+	0x0b, 0xf0,		/* Fsc2 */
+	0x0c, 0x21,		/* Fsc3 */
+	0x0d, 0x00,		/* Subcarrier Phase */
+	0x0e, 0x00,		/* Closed Capt. Ext 0 */
+	0x0f, 0x00,		/* Closed Capt. Ext 1 */
+	0x10, 0x00,		/* Closed Capt. 0 */
+	0x11, 0x00,		/* Closed Capt. 1 */
+	0x12, 0x00,		/* Pedestal Ctl 0 */
+	0x13, 0x00,		/* Pedestal Ctl 1 */
+	0x14, 0x00,		/* Pedestal Ctl 2 */
+	0x15, 0x00,		/* Pedestal Ctl 3 */
+	0x16, 0x00,		/* CGMS_WSS_0 */
+	0x17, 0x00,		/* CGMS_WSS_1 */
+	0x18, 0x00,		/* CGMS_WSS_2 */
+	0x19, 0x00,		/* Teletext Ctl */
 };
 
 static const unsigned char init_PAL[] = {
-	0x00, 0x71,		// MR0
-	0x01, 0x20,		// MR1
-	0x02, 0x0e,		// MR2 RTC control: bits 2 and 1
-	0x03, 0x80,		// MR3
-	0x04, 0x30,		// MR4
-	0x05, 0x00,		// Reserved
-	0x06, 0x00,		// Reserved
-	0x07, TR0MODE,		// TM0
-	0x08, TR1CAPT,		// TM1
-	0x09, 0xcb,		// Fsc0
-	0x0a, 0x8a,		// Fsc1
-	0x0b, 0x09,		// Fsc2
-	0x0c, 0x2a,		// Fsc3
-	0x0d, 0x00,		// Subcarrier Phase
-	0x0e, 0x00,		// Closed Capt. Ext 0
-	0x0f, 0x00,		// Closed Capt. Ext 1
-	0x10, 0x00,		// Closed Capt. 0
-	0x11, 0x00,		// Closed Capt. 1
-	0x12, 0x00,		// Pedestal Ctl 0
-	0x13, 0x00,		// Pedestal Ctl 1
-	0x14, 0x00,		// Pedestal Ctl 2
-	0x15, 0x00,		// Pedestal Ctl 3
-	0x16, 0x00,		// CGMS_WSS_0
-	0x17, 0x00,		// CGMS_WSS_1
-	0x18, 0x00,		// CGMS_WSS_2
-	0x19, 0x00,		// Teletext Ctl
+	0x00, 0x71,		/* MR0 */
+	0x01, 0x20,		/* MR1 */
+	0x02, 0x0e,		/* MR2 RTC control: bits 2 and 1 */
+	0x03, 0x80,		/* MR3 */
+	0x04, 0x30,		/* MR4 */
+	0x05, 0x00,		/* Reserved */
+	0x06, 0x00,		/* Reserved */
+	0x07, TR0MODE,		/* TM0 */
+	0x08, TR1CAPT,		/* TM1 */
+	0x09, 0xcb,		/* Fsc0 */
+	0x0a, 0x8a,		/* Fsc1 */
+	0x0b, 0x09,		/* Fsc2 */
+	0x0c, 0x2a,		/* Fsc3 */
+	0x0d, 0x00,		/* Subcarrier Phase */
+	0x0e, 0x00,		/* Closed Capt. Ext 0 */
+	0x0f, 0x00,		/* Closed Capt. Ext 1 */
+	0x10, 0x00,		/* Closed Capt. 0 */
+	0x11, 0x00,		/* Closed Capt. 1 */
+	0x12, 0x00,		/* Pedestal Ctl 0 */
+	0x13, 0x00,		/* Pedestal Ctl 1 */
+	0x14, 0x00,		/* Pedestal Ctl 2 */
+	0x15, 0x00,		/* Pedestal Ctl 3 */
+	0x16, 0x00,		/* CGMS_WSS_0 */
+	0x17, 0x00,		/* CGMS_WSS_1 */
+	0x18, 0x00,		/* CGMS_WSS_2 */
+	0x19, 0x00,		/* Teletext Ctl */
 };
 
 
-static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
 {
-	struct adv7170 *encoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-#if 0
-		/* This is just for testing!!! */
-		adv7170_write_block(client, init_common,
-				    sizeof(init_common));
-		adv7170_write(client, 0x07, TR0MODE | TR0RST);
-		adv7170_write(client, 0x07, TR0MODE);
-#endif
-		break;
-
-	case ENCODER_GET_CAPABILITIES:
-	{
-		struct video_encoder_capability *cap = arg;
-
-		cap->flags = VIDEO_ENCODER_PAL |
-			     VIDEO_ENCODER_NTSC;
-		cap->inputs = 2;
-		cap->outputs = 1;
-		break;
-	}
-
-	case ENCODER_SET_NORM:
-	{
-		int iarg = *(int *) arg;
-
-		v4l_dbg(1, debug, client, "set norm %d\n", iarg);
-
-		switch (iarg) {
-		case VIDEO_MODE_NTSC:
-			adv7170_write_block(client, init_NTSC,
-					    sizeof(init_NTSC));
-			if (encoder->input == 0)
-				adv7170_write(client, 0x02, 0x0e);	// Enable genlock
-			adv7170_write(client, 0x07, TR0MODE | TR0RST);
-			adv7170_write(client, 0x07, TR0MODE);
-			break;
+	struct adv7170 *encoder = to_adv7170(sd);
 
-		case VIDEO_MODE_PAL:
-			adv7170_write_block(client, init_PAL,
-					    sizeof(init_PAL));
-			if (encoder->input == 0)
-				adv7170_write(client, 0x02, 0x0e);	// Enable genlock
-			adv7170_write(client, 0x07, TR0MODE | TR0RST);
-			adv7170_write(client, 0x07, TR0MODE);
-			break;
+	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
 
-		default:
-			v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
-			return -EINVAL;
-		}
-		v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
-		encoder->norm = iarg;
-		break;
+	if (std & V4L2_STD_NTSC) {
+		adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
+		if (encoder->input == 0)
+			adv7170_write(sd, 0x02, 0x0e);	/* Enable genlock */
+		adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7170_write(sd, 0x07, TR0MODE);
+	} else if (std & V4L2_STD_PAL) {
+		adv7170_write_block(sd, init_PAL, sizeof(init_PAL));
+		if (encoder->input == 0)
+			adv7170_write(sd, 0x02, 0x0e);	/* Enable genlock */
+		adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7170_write(sd, 0x07, TR0MODE);
+	} else {
+		v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+				(unsigned long long)std);
+		return -EINVAL;
 	}
+	v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+	encoder->norm = std;
+	return 0;
+}
 
-	case ENCODER_SET_INPUT:
-	{
-		int iarg = *(int *) arg;
-
-		/* RJ: *iarg = 0: input is from decoder
-		 *iarg = 1: input is from ZR36060
-		 *iarg = 2: color bar */
-
-		v4l_dbg(1, debug, client, "set input from %s\n",
-			iarg == 0 ? "decoder" : "ZR36060");
-
-		switch (iarg) {
-		case 0:
-			adv7170_write(client, 0x01, 0x20);
-			adv7170_write(client, 0x08, TR1CAPT);	/* TR1 */
-			adv7170_write(client, 0x02, 0x0e);	// Enable genlock
-			adv7170_write(client, 0x07, TR0MODE | TR0RST);
-			adv7170_write(client, 0x07, TR0MODE);
-			/* udelay(10); */
-			break;
-
-		case 1:
-			adv7170_write(client, 0x01, 0x00);
-			adv7170_write(client, 0x08, TR1PLAY);	/* TR1 */
-			adv7170_write(client, 0x02, 0x08);
-			adv7170_write(client, 0x07, TR0MODE | TR0RST);
-			adv7170_write(client, 0x07, TR0MODE);
-			/* udelay(10); */
-			break;
+static int adv7170_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
+{
+	struct adv7170 *encoder = to_adv7170(sd);
 
-		default:
-			v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
-			return -EINVAL;
-		}
-		v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
-		encoder->input = iarg;
-		break;
-	}
+	/* RJ: input = 0: input is from decoder
+	   input = 1: input is from ZR36060
+	   input = 2: color bar */
 
-	case ENCODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
+	v4l2_dbg(1, debug, sd, "set input from %s\n",
+			input == 0 ? "decoder" : "ZR36060");
 
-		/* not much choice of outputs */
-		if (*iarg != 0) {
-			return -EINVAL;
-		}
+	switch (input) {
+	case 0:
+		adv7170_write(sd, 0x01, 0x20);
+		adv7170_write(sd, 0x08, TR1CAPT);	/* TR1 */
+		adv7170_write(sd, 0x02, 0x0e);	/* Enable genlock */
+		adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7170_write(sd, 0x07, TR0MODE);
+		/* udelay(10); */
 		break;
-	}
-
-	case ENCODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
 
-		encoder->enable = !!*iarg;
+	case 1:
+		adv7170_write(sd, 0x01, 0x00);
+		adv7170_write(sd, 0x08, TR1PLAY);	/* TR1 */
+		adv7170_write(sd, 0x02, 0x08);
+		adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7170_write(sd, 0x07, TR0MODE);
+		/* udelay(10); */
 		break;
-	}
 
 	default:
+		v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
 		return -EINVAL;
 	}
-
+	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+	encoder->input = input;
 	return 0;
 }
 
+static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static unsigned short normal_i2c[] = {
-	0xd4 >> 1, 0xd6 >> 1,	/* adv7170 IDs */
-	0x54 >> 1, 0x56 >> 1,	/* adv7171 IDs */
-	I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7170_core_ops = {
+	.g_chip_ident = adv7170_g_chip_ident,
 };
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7170_video_ops = {
+	.s_std_output = adv7170_s_std_output,
+	.s_routing = adv7170_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7170_ops = {
+	.core = &adv7170_core_ops,
+	.video = &adv7170_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int adv7170_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct adv7170 *encoder;
+	struct v4l2_subdev *sd;
 	int i;
 
 	/* Check if the adapter supports the needed features */
@@ -337,26 +301,29 @@ static int adv7170_probe(struct i2c_clie
 	encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
-	encoder->norm = VIDEO_MODE_NTSC;
+	sd = &encoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &adv7170_ops);
+	encoder->norm = V4L2_STD_NTSC;
 	encoder->input = 0;
-	encoder->enable = 1;
-	i2c_set_clientdata(client, encoder);
 
-	i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
+	i = adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
 	if (i >= 0) {
-		i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
-		i = adv7170_write(client, 0x07, TR0MODE);
-		i = adv7170_read(client, 0x12);
-		v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+		i = adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+		i = adv7170_write(sd, 0x07, TR0MODE);
+		i = adv7170_read(sd, 0x12);
+		v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
 	}
 	if (i < 0)
-		v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+		v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
 	return 0;
 }
 
 static int adv7170_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_adv7170(sd));
 	return 0;
 }
 
@@ -371,8 +338,6 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "adv7170",
-	.driverid = I2C_DRIVERID_ADV7170,
-	.command = adv7170_command,
 	.probe = adv7170_probe,
 	.remove = adv7170_remove,
 	.id_table = adv7170_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/adv7175.c linux-libre-2.6.30-gnu1/drivers/media/video/adv7175.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/adv7175.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/adv7175.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,15 +30,19 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
 MODULE_LICENSE("GPL");
 
+#define   I2C_ADV7175        0xd4
+#define   I2C_ADV7176        0x54
+
+
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -46,36 +50,38 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 /* ----------------------------------------------------------------------- */
 
 struct adv7175 {
-	int norm;
+	struct v4l2_subdev sd;
+	v4l2_std_id norm;
 	int input;
-	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
 };
 
-#define   I2C_ADV7175        0xd4
-#define   I2C_ADV7176        0x54
+static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct adv7175, sd);
+}
 
 static char *inputs[] = { "pass_through", "play_back", "color_bar" };
-static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
 
 /* ----------------------------------------------------------------------- */
 
-static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int adv7175_read(struct i2c_client *client, u8 reg)
+static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int adv7175_write_block(struct i2c_client *client,
+static int adv7175_write_block(struct v4l2_subdev *sd,
 		     const u8 *data, unsigned int len)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret = -1;
 	u8 reg;
 
@@ -103,7 +109,7 @@ static int adv7175_write_block(struct i2
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			ret = adv7175_write(client, reg, *data++);
+			ret = adv7175_write(sd, reg, *data++);
 			if (ret < 0)
 				break;
 			len -= 2;
@@ -113,18 +119,18 @@ static int adv7175_write_block(struct i2
 	return ret;
 }
 
-static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
+static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
 {
 	/* for some reason pass_through NTSC needs
 	 * a different sub-carrier freq to remain stable. */
 	if (pass_through)
-		adv7175_write(client, 0x02, 0x00);
+		adv7175_write(sd, 0x02, 0x00);
 	else
-		adv7175_write(client, 0x02, 0x55);
+		adv7175_write(sd, 0x02, 0x55);
 
-	adv7175_write(client, 0x03, 0x55);
-	adv7175_write(client, 0x04, 0x55);
-	adv7175_write(client, 0x05, 0x25);
+	adv7175_write(sd, 0x03, 0x55);
+	adv7175_write(sd, 0x04, 0x55);
+	adv7175_write(sd, 0x05, 0x25);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -184,180 +190,145 @@ static const unsigned char init_ntsc[] =
 	0x06, 0x1a,		/* subc. phase */
 };
 
-static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7175_init(struct v4l2_subdev *sd, u32 val)
 {
-	struct adv7175 *encoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-		/* This is just for testing!!! */
-		adv7175_write_block(client, init_common,
-				    sizeof(init_common));
-		adv7175_write(client, 0x07, TR0MODE | TR0RST);
-		adv7175_write(client, 0x07, TR0MODE);
-		break;
-
-	case ENCODER_GET_CAPABILITIES:
-	{
-		struct video_encoder_capability *cap = arg;
-
-		cap->flags = VIDEO_ENCODER_PAL |
-			     VIDEO_ENCODER_NTSC |
-			     VIDEO_ENCODER_SECAM; /* well, hacky */
-		cap->inputs = 2;
-		cap->outputs = 1;
-		break;
-	}
-
-	case ENCODER_SET_NORM:
-	{
-		int iarg = *(int *) arg;
-
-		switch (iarg) {
-		case VIDEO_MODE_NTSC:
-			adv7175_write_block(client, init_ntsc,
-					    sizeof(init_ntsc));
-			if (encoder->input == 0)
-				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			break;
+	/* This is just for testing!!! */
+	adv7175_write_block(sd, init_common, sizeof(init_common));
+	adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+	adv7175_write(sd, 0x07, TR0MODE);
+	return 0;
+}
 
-		case VIDEO_MODE_PAL:
-			adv7175_write_block(client, init_pal,
-					    sizeof(init_pal));
-			if (encoder->input == 0)
-				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			break;
+static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct adv7175 *encoder = to_adv7175(sd);
 
-		case VIDEO_MODE_SECAM:	// WARNING! ADV7176 does not support SECAM.
-			/* This is an attempt to convert
-			 * SECAM->PAL (typically it does not work
-			 * due to genlock: when decoder is in SECAM
-			 * and encoder in in PAL the subcarrier can
-			 * not be syncronized with horizontal
-			 * quency) */
-			adv7175_write_block(client, init_pal,
-					    sizeof(init_pal));
-			if (encoder->input == 0)
-				adv7175_write(client, 0x0d, 0x49);	// Disable genlock
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			break;
-		default:
-			v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
-			return -EINVAL;
-		}
-		v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
-		encoder->norm = iarg;
-		break;
+	if (std & V4L2_STD_NTSC) {
+		adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
+		if (encoder->input == 0)
+			adv7175_write(sd, 0x0d, 0x4f);	/* Enable genlock */
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+	} else if (std & V4L2_STD_PAL) {
+		adv7175_write_block(sd, init_pal, sizeof(init_pal));
+		if (encoder->input == 0)
+			adv7175_write(sd, 0x0d, 0x4f);	/* Enable genlock */
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+	} else if (std & V4L2_STD_SECAM) {
+		/* This is an attempt to convert
+		 * SECAM->PAL (typically it does not work
+		 * due to genlock: when decoder is in SECAM
+		 * and encoder in in PAL the subcarrier can
+		 * not be syncronized with horizontal
+		 * quency) */
+		adv7175_write_block(sd, init_pal, sizeof(init_pal));
+		if (encoder->input == 0)
+			adv7175_write(sd, 0x0d, 0x49);	/* Disable genlock */
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+	} else {
+		v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+				(unsigned long long)std);
+		return -EINVAL;
 	}
+	v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+	encoder->norm = std;
+	return 0;
+}
 
-	case ENCODER_SET_INPUT:
-	{
-		int iarg = *(int *) arg;
-
-		/* RJ: *iarg = 0: input is from SAA7110
-		 *iarg = 1: input is from ZR36060
-		 *iarg = 2: color bar */
-
-		switch (iarg) {
-		case 0:
-			adv7175_write(client, 0x01, 0x00);
-
-			if (encoder->norm == VIDEO_MODE_NTSC)
-				set_subcarrier_freq(client, 1);
-
-			adv7175_write(client, 0x0c, TR1CAPT);	/* TR1 */
-			if (encoder->norm == VIDEO_MODE_SECAM)
-				adv7175_write(client, 0x0d, 0x49);	// Disable genlock
-			else
-				adv7175_write(client, 0x0d, 0x4f);	// Enable genlock
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			//udelay(10);
-			break;
+static int adv7175_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
+{
+	struct adv7175 *encoder = to_adv7175(sd);
 
-		case 1:
-			adv7175_write(client, 0x01, 0x00);
+	/* RJ: input = 0: input is from decoder
+	   input = 1: input is from ZR36060
+	   input = 2: color bar */
 
-			if (encoder->norm == VIDEO_MODE_NTSC)
-				set_subcarrier_freq(client, 0);
+	switch (input) {
+	case 0:
+		adv7175_write(sd, 0x01, 0x00);
 
-			adv7175_write(client, 0x0c, TR1PLAY);	/* TR1 */
-			adv7175_write(client, 0x0d, 0x49);
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			/* udelay(10); */
-			break;
+		if (encoder->norm & V4L2_STD_NTSC)
+			set_subcarrier_freq(sd, 1);
 
-		case 2:
-			adv7175_write(client, 0x01, 0x80);
+		adv7175_write(sd, 0x0c, TR1CAPT);	/* TR1 */
+		if (encoder->norm & V4L2_STD_SECAM)
+			adv7175_write(sd, 0x0d, 0x49);	/* Disable genlock */
+		else
+			adv7175_write(sd, 0x0d, 0x4f);	/* Enable genlock */
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+		/*udelay(10);*/
+		break;
 
-			if (encoder->norm == VIDEO_MODE_NTSC)
-				set_subcarrier_freq(client, 0);
+	case 1:
+		adv7175_write(sd, 0x01, 0x00);
 
-			adv7175_write(client, 0x0d, 0x49);
-			adv7175_write(client, 0x07, TR0MODE | TR0RST);
-			adv7175_write(client, 0x07, TR0MODE);
-			/* udelay(10); */
-			break;
+		if (encoder->norm & V4L2_STD_NTSC)
+			set_subcarrier_freq(sd, 0);
 
-		default:
-			v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
-			return -EINVAL;
-		}
-		v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
-		encoder->input = iarg;
+		adv7175_write(sd, 0x0c, TR1PLAY);	/* TR1 */
+		adv7175_write(sd, 0x0d, 0x49);
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+		/* udelay(10); */
 		break;
-	}
 
-	case ENCODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
-
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
-		break;
-	}
+	case 2:
+		adv7175_write(sd, 0x01, 0x80);
 
-	case ENCODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
+		if (encoder->norm & V4L2_STD_NTSC)
+			set_subcarrier_freq(sd, 0);
 
-		encoder->enable = !!*iarg;
+		adv7175_write(sd, 0x0d, 0x49);
+		adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		adv7175_write(sd, 0x07, TR0MODE);
+		/* udelay(10); */
 		break;
-	}
 
 	default:
+		v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
 		return -EINVAL;
 	}
-
+	v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
+	encoder->input = input;
 	return 0;
 }
 
+static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
-	I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
-	I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
-	I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7175_core_ops = {
+	.g_chip_ident = adv7175_g_chip_ident,
+	.init = adv7175_init,
 };
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7175_video_ops = {
+	.s_std_output = adv7175_s_std_output,
+	.s_routing = adv7175_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7175_ops = {
+	.core = &adv7175_core_ops,
+	.video = &adv7175_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int adv7175_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	int i;
 	struct adv7175 *encoder;
+	struct v4l2_subdev *sd;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -369,26 +340,29 @@ static int adv7175_probe(struct i2c_clie
 	encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
-	encoder->norm = VIDEO_MODE_PAL;
+	sd = &encoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
+	encoder->norm = V4L2_STD_NTSC;
 	encoder->input = 0;
-	encoder->enable = 1;
-	i2c_set_clientdata(client, encoder);
 
-	i = adv7175_write_block(client, init_common, sizeof(init_common));
+	i = adv7175_write_block(sd, init_common, sizeof(init_common));
 	if (i >= 0) {
-		i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
-		i = adv7175_write(client, 0x07, TR0MODE);
-		i = adv7175_read(client, 0x12);
-		v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+		i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+		i = adv7175_write(sd, 0x07, TR0MODE);
+		i = adv7175_read(sd, 0x12);
+		v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
 	}
 	if (i < 0)
-		v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+		v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
 	return 0;
 }
 
 static int adv7175_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_adv7175(sd));
 	return 0;
 }
 
@@ -403,8 +377,6 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "adv7175",
-	.driverid = I2C_DRIVERID_ADV7175,
-	.command = adv7175_command,
 	.probe = adv7175_probe,
 	.remove = adv7175_remove,
 	.id_table = adv7175_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-cards.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-cards.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,25 +21,100 @@
 
 #include "au0828.h"
 #include "au0828-cards.h"
+#include "au8522.h"
+#include "media/tuner.h"
+#include "media/v4l2-common.h"
+
+void hvr950q_cs5340_audio(void *priv, int enable)
+{
+	/* Because the HVR-950q shares an i2s bus between the cs5340 and the
+	   au8522, we need to hold cs5340 in reset when using the au8522 */
+	struct au0828_dev *dev = priv;
+	if (enable == 1)
+		au0828_set(dev, REG_000, 0x10);
+	else
+		au0828_clear(dev, REG_000, 0x10);
+}
 
 struct au0828_board au0828_boards[] = {
 	[AU0828_BOARD_UNKNOWN] = {
 		.name	= "Unknown board",
+		.tuner_type = UNSET,
+		.tuner_addr = ADDR_UNSET,
 	},
 	[AU0828_BOARD_HAUPPAUGE_HVR850] = {
 		.name	= "Hauppauge HVR850",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
+		.input = {
+			{
+				.type = AU0828_VMUX_TELEVISION,
+				.vmux = AU8522_COMPOSITE_CH4_SIF,
+				.amux = AU8522_AUDIO_SIF,
+			},
+			{
+				.type = AU0828_VMUX_COMPOSITE,
+				.vmux = AU8522_COMPOSITE_CH1,
+				.amux = AU8522_AUDIO_NONE,
+				.audio_setup = hvr950q_cs5340_audio,
+			},
+			{
+				.type = AU0828_VMUX_SVIDEO,
+				.vmux = AU8522_SVIDEO_CH13,
+				.amux = AU8522_AUDIO_NONE,
+				.audio_setup = hvr950q_cs5340_audio,
+			},
+		},
 	},
 	[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
 		.name	= "Hauppauge HVR950Q",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		/* The au0828 hardware i2c implementation does not properly
+		   support the xc5000's i2c clock stretching.  So we need to
+		   lower the clock frequency enough where the 15us clock
+		   stretch fits inside of a normal clock cycle, or else the
+		   au0828 fails to set the STOP bit.  A 30 KHz clock puts the
+		   clock pulse width at 18us */
+		.i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
+		.input = {
+			{
+				.type = AU0828_VMUX_TELEVISION,
+				.vmux = AU8522_COMPOSITE_CH4_SIF,
+				.amux = AU8522_AUDIO_SIF,
+			},
+			{
+				.type = AU0828_VMUX_COMPOSITE,
+				.vmux = AU8522_COMPOSITE_CH1,
+				.amux = AU8522_AUDIO_NONE,
+				.audio_setup = hvr950q_cs5340_audio,
+			},
+			{
+				.type = AU0828_VMUX_SVIDEO,
+				.vmux = AU8522_SVIDEO_CH13,
+				.amux = AU8522_AUDIO_NONE,
+				.audio_setup = hvr950q_cs5340_audio,
+			},
+		},
 	},
 	[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
 		.name	= "Hauppauge HVR950Q rev xxF8",
+		.tuner_type = UNSET,
+		.tuner_addr = ADDR_UNSET,
+		.i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
 	},
 	[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
 		.name	= "DViCO FusionHDTV USB",
+		.tuner_type = UNSET,
+		.tuner_addr = ADDR_UNSET,
+		.i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
 	},
 	[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
 		.name = "Hauppauge Woodbury",
+		.tuner_type = UNSET,
+		.tuner_addr = ADDR_UNSET,
+		.i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
 	},
 };
 
@@ -52,7 +127,7 @@ int au0828_tuner_callback(void *priv, in
 
 	dprintk(1, "%s()\n", __func__);
 
-	switch (dev->board) {
+	switch (dev->boardnr) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -81,17 +156,18 @@ static void hauppauge_eeprom(struct au08
 	struct tveeprom tv;
 
 	tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
+	dev->board.tuner_type = tv.tuner_type;
 
 	/* Make sure we support the board model */
 	switch (tv.model) {
 	case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
-	case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
-	case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
-	case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
-	case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
-	case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
-	case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
-	case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+	case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+	case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+	case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+	case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+	case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */
+	case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+	case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */
 	case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
 		break;
 	default:
@@ -107,15 +183,21 @@ static void hauppauge_eeprom(struct au08
 void au0828_card_setup(struct au0828_dev *dev)
 {
 	static u8 eeprom[256];
+	struct tuner_setup tun_setup;
+	struct v4l2_subdev *sd;
+	unsigned int mode_mask = T_ANALOG_TV |
+				 T_DIGITAL_TV;
 
 	dprintk(1, "%s()\n", __func__);
 
+	memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
+
 	if (dev->i2c_rc == 0) {
 		dev->i2c_client.addr = 0xa0 >> 1;
 		tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
 	}
 
-	switch (dev->board) {
+	switch (dev->boardnr) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -124,6 +206,32 @@ void au0828_card_setup(struct au0828_dev
 			hauppauge_eeprom(dev, eeprom+0xa0);
 		break;
 	}
+
+	if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) {
+		/* Load the analog demodulator driver (note this would need to
+		   be abstracted out if we ever need to support a different
+		   demod) */
+		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+				"au8522", "au8522", 0x8e >> 1);
+		if (sd == NULL)
+			printk(KERN_ERR "analog subdev registration failed\n");
+	}
+
+	/* Setup tuners */
+	if (dev->board.tuner_type != TUNER_ABSENT) {
+		/* Load the tuner module, which does the attach */
+		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+				"tuner", "tuner", dev->board.tuner_addr);
+		if (sd == NULL)
+			printk(KERN_ERR "tuner subdev registration fail\n");
+
+		tun_setup.mode_mask      = mode_mask;
+		tun_setup.type           = dev->board.tuner_type;
+		tun_setup.addr           = dev->board.tuner_addr;
+		tun_setup.tuner_callback = au0828_tuner_callback;
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
+				     &tun_setup);
+	}
 }
 
 /*
@@ -135,7 +243,7 @@ void au0828_gpio_setup(struct au0828_dev
 {
 	dprintk(1, "%s()\n", __func__);
 
-	switch (dev->board) {
+	switch (dev->boardnr) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -144,21 +252,23 @@ void au0828_gpio_setup(struct au0828_dev
 		 * 4 - CS5340
 		 * 5 - AU8522 Demodulator
 		 * 6 - eeprom W/P
+		 * 7 - power supply
 		 * 9 - XC5000 Tuner
 		 */
 
 		/* Into reset */
 		au0828_write(dev, REG_003, 0x02);
-		au0828_write(dev, REG_002, 0x88 | 0x20);
+		au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
 		au0828_write(dev, REG_001, 0x0);
 		au0828_write(dev, REG_000, 0x0);
 		msleep(100);
 
-		/* Out of reset */
+		/* Out of reset (leave the cs5340 in reset until needed) */
 		au0828_write(dev, REG_003, 0x02);
 		au0828_write(dev, REG_001, 0x02);
-		au0828_write(dev, REG_002, 0x88 | 0x20);
-		au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40);
+		au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
+		au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
+
 		msleep(250);
 		break;
 	case AU0828_BOARD_DVICO_FUSIONHDTV7:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-core.c linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,13 +51,13 @@ static int recv_control_msg(struct au082
 u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
 {
 	recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
-	dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]);
+	dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
 	return dev->ctrlmsg[0];
 }
 
 u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
 {
-	dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val);
+	dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
 	return send_control_msg(dev, CMD_REQUEST_OUT, val, reg,
 				dev->ctrlmsg, 0);
 }
@@ -146,9 +146,14 @@ static void au0828_usb_disconnect(struct
 	/* Digital TV */
 	au0828_dvb_unregister(dev);
 
+	if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+		au0828_analog_unregister(dev);
+
 	/* I2C */
 	au0828_i2c_unregister(dev);
 
+	v4l2_device_unregister(&dev->v4l2_dev);
+
 	usb_set_intfdata(interface, NULL);
 
 	mutex_lock(&dev->mutex);
@@ -162,7 +167,7 @@ static void au0828_usb_disconnect(struct
 static int au0828_usb_probe(struct usb_interface *interface,
 	const struct usb_device_id *id)
 {
-	int ifnum;
+	int ifnum, retval;
 	struct au0828_dev *dev;
 	struct usb_device *usbdev = interface_to_usbdev(interface);
 
@@ -185,9 +190,16 @@ static int au0828_usb_probe(struct usb_i
 	mutex_init(&dev->mutex);
 	mutex_init(&dev->dvb.lock);
 	dev->usbdev = usbdev;
-	dev->board = id->driver_info;
+	dev->boardnr = id->driver_info;
 
-	usb_set_intfdata(interface, dev);
+	/* Create the v4l2_device */
+	retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+	if (retval) {
+		printk(KERN_ERR "%s() v4l2_device_register failed\n",
+		       __func__);
+		kfree(dev);
+		return -EIO;
+	}
 
 	/* Power Up the bridge */
 	au0828_write(dev, REG_600, 1 << 4);
@@ -201,12 +213,19 @@ static int au0828_usb_probe(struct usb_i
 	/* Setup */
 	au0828_card_setup(dev);
 
+	/* Analog TV */
+	if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+		au0828_analog_register(dev, interface);
+
 	/* Digital TV */
 	au0828_dvb_register(dev);
 
+	/* Store the pointer to the au0828_dev so it can be accessed in
+	   au0828_usb_disconnect */
+	usb_set_intfdata(interface, dev);
+
 	printk(KERN_INFO "Registered device AU0828 [%s]\n",
-		au0828_boards[dev->board].name == NULL ? "Unset" :
-		au0828_boards[dev->board].name);
+		dev->board.name == NULL ? "Unset" : dev->board.name);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-dvb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-dvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -378,7 +378,7 @@ int au0828_dvb_register(struct au0828_de
 	dprintk(1, "%s()\n", __func__);
 
 	/* init frontend */
-	switch (dev->board) {
+	switch (dev->boardnr) {
 	case AU0828_BOARD_HAUPPAUGE_HVR850:
 	case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 		dvb->frontend = dvb_attach(au8522_attach,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828.h linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,11 @@
 #include <linux/i2c-algo-bit.h>
 #include <media/tveeprom.h>
 
+/* Analog */
+#include <linux/videodev2.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+
 /* DVB */
 #include "demux.h"
 #include "dmxdev.h"
@@ -39,8 +44,46 @@
 #define URB_COUNT   16
 #define URB_BUFSIZE (0xe522)
 
+/* Analog constants */
+#define NTSC_STD_W      720
+#define NTSC_STD_H      480
+
+#define AU0828_INTERLACED_DEFAULT       1
+#define V4L2_CID_PRIVATE_SHARPNESS  (V4L2_CID_PRIVATE_BASE + 0)
+
+/* Defination for AU0828 USB transfer */
+#define AU0828_MAX_ISO_BUFS    12  /* maybe resize this value in the future */
+#define AU0828_ISO_PACKETS_PER_URB      10
+
+#define AU0828_MIN_BUF 4
+#define AU0828_DEF_BUF 8
+
+#define AU0828_MAX_INPUT        4
+
+enum au0828_itype {
+	AU0828_VMUX_UNDEFINED = 0,
+	AU0828_VMUX_COMPOSITE,
+	AU0828_VMUX_SVIDEO,
+	AU0828_VMUX_CABLE,
+	AU0828_VMUX_TELEVISION,
+	AU0828_VMUX_DVB,
+	AU0828_VMUX_DEBUG
+};
+
+struct au0828_input {
+	enum au0828_itype type;
+	unsigned int vmux;
+	unsigned int amux;
+	void (*audio_setup) (void *priv, int enable);
+};
+
 struct au0828_board {
 	char *name;
+	unsigned int tuner_type;
+	unsigned char tuner_addr;
+	unsigned char i2c_clk_divider;
+	struct au0828_input input[AU0828_MAX_INPUT];
+
 };
 
 struct au0828_dvb {
@@ -55,31 +98,143 @@ struct au0828_dvb {
 	int feeding;
 };
 
+enum au0828_stream_state {
+	STREAM_OFF,
+	STREAM_INTERRUPT,
+	STREAM_ON
+};
+
+#define AUVI_INPUT(nr) (dev->board.input[nr])
+
+/* device state */
+enum au0828_dev_state {
+	DEV_INITIALIZED = 0x01,
+	DEV_DISCONNECTED = 0x02,
+	DEV_MISCONFIGURED = 0x04
+};
+
+struct au0828_fh {
+	struct au0828_dev *dev;
+	unsigned int  stream_on:1;	/* Locks streams */
+	struct videobuf_queue        vb_vidq;
+	enum v4l2_buf_type           type;
+};
+
+struct au0828_usb_isoc_ctl {
+		/* max packet size of isoc transaction */
+	int				max_pkt_size;
+
+		/* number of allocated urbs */
+	int				num_bufs;
+
+		/* urb for isoc transfers */
+	struct urb			**urb;
+
+		/* transfer buffers for isoc transfer */
+	char				**transfer_buffer;
+
+		/* Last buffer command and region */
+	u8				cmd;
+	int				pos, size, pktsize;
+
+		/* Last field: ODD or EVEN? */
+	int				field;
+
+		/* Stores incomplete commands */
+	u32				tmp_buf;
+	int				tmp_buf_len;
+
+		/* Stores already requested buffers */
+	struct au0828_buffer    	*buf;
+
+		/* Stores the number of received fields */
+	int				nfields;
+
+		/* isoc urb callback */
+	int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb);
+
+};
+
+/* buffer for one video frame */
+struct au0828_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+
+	struct list_head frame;
+	int top_field;
+	int receiving;
+};
+
+struct au0828_dmaqueue {
+	struct list_head       active;
+	struct list_head       queued;
+
+	wait_queue_head_t          wq;
+
+	/* Counters to control buffer fill */
+	int                        pos;
+};
+
 struct au0828_dev {
 	struct mutex mutex;
 	struct usb_device	*usbdev;
-	int			board;
+	int			boardnr;
+	struct au0828_board	board;
 	u8			ctrlmsg[64];
 
 	/* I2C */
 	struct i2c_adapter		i2c_adap;
-	struct i2c_algo_bit_data	i2c_algo;
+	struct i2c_algorithm		i2c_algo;
 	struct i2c_client		i2c_client;
 	u32 				i2c_rc;
 
 	/* Digital */
 	struct au0828_dvb		dvb;
 
+	/* Analog */
+	struct list_head au0828list;
+	struct v4l2_device v4l2_dev;
+	int users;
+	unsigned int stream_on:1;	/* Locks streams */
+	struct video_device *vdev;
+	struct video_device *vbi_dev;
+	int width;
+	int height;
+	u32 field_size;
+	u32 frame_size;
+	u32 bytesperline;
+	int type;
+	u8 ctrl_ainput;
+	__u8 isoc_in_endpointaddr;
+	u8 isoc_init_ok;
+	int greenscreen_detected;
+	unsigned int frame_count;
+	int ctrl_freq;
+	int input_type;
+	unsigned int ctrl_input;
+	enum au0828_dev_state dev_state;
+	enum au0828_stream_state stream_state;
+	wait_queue_head_t open;
+
+	struct mutex lock;
+
+	/* Isoc control struct */
+	struct au0828_dmaqueue vidq;
+	struct au0828_usb_isoc_ctl isoc_ctl;
+	spinlock_t slock;
+
+	/* usb transfer */
+	int alt;		/* alternate */
+	int max_pkt_size;	/* max packet size of isoc transaction */
+	int num_alt;		/* Number of alternative settings */
+	unsigned int *alt_max_pkt_size;	/* array of wMaxPacketSize */
+	struct urb *urb[AU0828_MAX_ISO_BUFS];	/* urb for isoc transfers */
+	char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
+						   transfer */
+
 	/* USB / URB Related */
 	int		urb_streaming;
 	struct urb	*urbs[URB_COUNT];
-
-};
-
-struct au0828_buff {
-	struct au0828_dev	*dev;
-	struct urb		*purb;
-	struct list_head	buff_list;
 };
 
 /* ----------------------------------------------------------- */
@@ -111,8 +266,13 @@ extern void au0828_card_setup(struct au0
 /* au0828-i2c.c */
 extern int au0828_i2c_register(struct au0828_dev *dev);
 extern int au0828_i2c_unregister(struct au0828_dev *dev);
-extern void au0828_call_i2c_clients(struct au0828_dev *dev,
-	unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------- */
+/* au0828-video.c */
+int au0828_analog_register(struct au0828_dev *dev,
+			   struct usb_interface *interface);
+int au0828_analog_stream_disable(struct au0828_dev *d);
+void au0828_analog_unregister(struct au0828_dev *dev);
 
 /* ----------------------------------------------------------- */
 /* au0828-dvb.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,13 +39,15 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus
 static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
 {
 	struct au0828_dev *dev = i2c_adap->algo_data;
-	return au0828_read(dev, REG_201) & 0x08 ? 0 : 1;
+	return au0828_read(dev, AU0828_I2C_STATUS_201) &
+		AU0828_I2C_STATUS_NO_WRITE_ACK ? 0 : 1;
 }
 
 static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap)
 {
 	struct au0828_dev *dev = i2c_adap->algo_data;
-	return au0828_read(dev, REG_201) & 0x02 ? 0 : 1;
+	return au0828_read(dev, AU0828_I2C_STATUS_201) &
+		AU0828_I2C_STATUS_NO_READ_ACK ? 0 : 1;
 }
 
 static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap)
@@ -67,7 +69,8 @@ static int i2c_wait_read_ack(struct i2c_
 static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap)
 {
 	struct au0828_dev *dev = i2c_adap->algo_data;
-	return au0828_read(dev, REG_201) & 0x01 ? 0 : 1;
+	return au0828_read(dev, AU0828_I2C_STATUS_201) &
+		AU0828_I2C_STATUS_READ_DONE ? 0 : 1;
 }
 
 static int i2c_wait_read_done(struct i2c_adapter *i2c_adap)
@@ -89,7 +92,8 @@ static int i2c_wait_read_done(struct i2c
 static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap)
 {
 	struct au0828_dev *dev = i2c_adap->algo_data;
-	return au0828_read(dev, REG_201) & 0x04 ? 1 : 0;
+	return au0828_read(dev, AU0828_I2C_STATUS_201) &
+		AU0828_I2C_STATUS_WRITE_DONE ? 1 : 0;
 }
 
 static int i2c_wait_write_done(struct i2c_adapter *i2c_adap)
@@ -111,7 +115,8 @@ static int i2c_wait_write_done(struct i2
 static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
 {
 	struct au0828_dev *dev = i2c_adap->algo_data;
-	return au0828_read(dev, REG_201) & 0x10 ? 1 : 0;
+	return au0828_read(dev, AU0828_I2C_STATUS_201) &
+		AU0828_I2C_STATUS_BUSY ? 1 : 0;
 }
 
 static int i2c_wait_done(struct i2c_adapter *i2c_adap)
@@ -139,19 +144,42 @@ static int i2c_sendbytes(struct i2c_adap
 
 	dprintk(4, "%s()\n", __func__);
 
-	au0828_write(dev, REG_2FF, 0x01);
-	au0828_write(dev, REG_202, 0x07);
+	au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
+
+	/* Set the I2C clock */
+	au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+		     dev->board.i2c_clk_divider);
 
 	/* Hardware needs 8 bit addresses */
-	au0828_write(dev, REG_203, msg->addr << 1);
+	au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
 
 	dprintk(4, "SEND: %02x\n", msg->addr);
 
+	/* Deal with i2c_scan */
+	if (msg->len == 0) {
+		/* The analog tuner detection code makes use of the SMBUS_QUICK
+		   message (which involves a zero length i2c write).  To avoid
+		   checking the status register when we didn't strobe out any
+		   actual bytes to the bus, just do a read check.  This is
+		   consistent with how I saw i2c device checking done in the
+		   USB trace of the Windows driver */
+		au0828_write(dev, AU0828_I2C_TRIGGER_200,
+			     AU0828_I2C_TRIGGER_READ);
+
+		if (!i2c_wait_done(i2c_adap))
+			return -EIO;
+
+		if (i2c_wait_read_ack(i2c_adap))
+			return -EIO;
+
+		return 0;
+	}
+
 	for (i = 0; i < msg->len;) {
 
 		dprintk(4, " %02x\n", msg->buf[i]);
 
-		au0828_write(dev, REG_205, msg->buf[i]);
+		au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]);
 
 		strobe++;
 		i++;
@@ -160,9 +188,12 @@ static int i2c_sendbytes(struct i2c_adap
 
 			/* Strobe the byte into the bus */
 			if (i < msg->len)
-				au0828_write(dev, REG_200, 0x41);
+				au0828_write(dev, AU0828_I2C_TRIGGER_200,
+					     AU0828_I2C_TRIGGER_WRITE |
+					     AU0828_I2C_TRIGGER_HOLD);
 			else
-				au0828_write(dev, REG_200, 0x01);
+				au0828_write(dev, AU0828_I2C_TRIGGER_200,
+					     AU0828_I2C_TRIGGER_WRITE);
 
 			/* Reset strobe trigger */
 			strobe = 0;
@@ -190,17 +221,22 @@ static int i2c_readbytes(struct i2c_adap
 
 	dprintk(4, "%s()\n", __func__);
 
-	au0828_write(dev, REG_2FF, 0x01);
-	au0828_write(dev, REG_202, 0x07);
+	au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
+
+	/* Set the I2C clock */
+	au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+		     dev->board.i2c_clk_divider);
 
 	/* Hardware needs 8 bit addresses */
-	au0828_write(dev, REG_203, msg->addr << 1);
+	au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
 
 	dprintk(4, " RECV:\n");
 
 	/* Deal with i2c_scan */
 	if (msg->len == 0) {
-		au0828_write(dev, REG_200, 0x20);
+		au0828_write(dev, AU0828_I2C_TRIGGER_200,
+			     AU0828_I2C_TRIGGER_READ);
+
 		if (i2c_wait_read_ack(i2c_adap))
 			return -EIO;
 		return 0;
@@ -211,14 +247,18 @@ static int i2c_readbytes(struct i2c_adap
 		i++;
 
 		if (i < msg->len)
-			au0828_write(dev, REG_200, 0x60);
+			au0828_write(dev, AU0828_I2C_TRIGGER_200,
+				     AU0828_I2C_TRIGGER_READ |
+				     AU0828_I2C_TRIGGER_HOLD);
 		else
-			au0828_write(dev, REG_200, 0x20);
+			au0828_write(dev, AU0828_I2C_TRIGGER_200,
+				     AU0828_I2C_TRIGGER_READ);
 
 		if (!i2c_wait_read_done(i2c_adap))
 			return -EIO;
 
-		msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff;
+		msg->buf[i-1] = au0828_read(dev, AU0828_I2C_READ_FIFO_209) &
+			0xff;
 
 		dprintk(4, " %02x\n", msg->buf[i-1]);
 	}
@@ -265,33 +305,6 @@ err:
 	return retval;
 }
 
-static int attach_inform(struct i2c_client *client)
-{
-	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-		client->driver->driver.name, client->addr, client->name);
-
-	if (!client->driver->command)
-		return 0;
-
-	return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
-	dprintk(1, "i2c detach [client=%s]\n", client->name);
-
-	return 0;
-}
-
-void au0828_call_i2c_clients(struct au0828_dev *dev,
-			      unsigned int cmd, void *arg)
-{
-	if (dev->i2c_rc != 0)
-		return;
-
-	i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
 static u32 au0828_functionality(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -309,9 +322,6 @@ static struct i2c_adapter au0828_i2c_ada
 	.owner             = THIS_MODULE,
 	.id                = I2C_HW_B_AU0828,
 	.algo              = &au0828_i2c_algo_template,
-	.class             = I2C_CLASS_TV_ANALOG,
-	.client_register   = attach_inform,
-	.client_unregister = detach_inform,
 };
 
 static struct i2c_client au0828_i2c_client_template = {
@@ -356,9 +366,9 @@ int au0828_i2c_register(struct au0828_de
 	strlcpy(dev->i2c_adap.name, DRIVER_NAME,
 		sizeof(dev->i2c_adap.name));
 
-	dev->i2c_algo.data = dev;
+	dev->i2c_adap.algo = &dev->i2c_algo;
 	dev->i2c_adap.algo_data = dev;
-	i2c_set_adapdata(&dev->i2c_adap, dev);
+	i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
 	i2c_add_adapter(&dev->i2c_adap);
 
 	dev->i2c_client.adapter = &dev->i2c_adap;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-reg.h linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,12 +27,39 @@
 #define REG_002 0x002
 #define REG_003 0x003
 
-#define REG_200 0x200
-#define REG_201 0x201
-#define REG_202 0x202
-#define REG_203 0x203
-#define REG_205 0x205
-#define REG_209 0x209
-#define REG_2FF 0x2ff
+#define AU0828_SENSORCTRL_100 0x100
+#define AU0828_SENSORCTRL_VBI_103 0x103
+
+/* I2C registers */
+#define AU0828_I2C_TRIGGER_200		0x200
+#define AU0828_I2C_STATUS_201		0x201
+#define AU0828_I2C_CLK_DIVIDER_202	0x202
+#define AU0828_I2C_DEST_ADDR_203	0x203
+#define AU0828_I2C_WRITE_FIFO_205	0x205
+#define AU0828_I2C_READ_FIFO_209	0x209
+#define AU0828_I2C_MULTIBYTE_MODE_2FF	0x2ff
+
+/* Audio registers */
+#define AU0828_AUDIOCTRL_50C 0x50C
 
 #define REG_600 0x600
+
+/*********************************************************************/
+/* Here are constants for values associated with the above registers */
+
+/* I2C Trigger (Reg 0x200) */
+#define AU0828_I2C_TRIGGER_WRITE	0x01
+#define AU0828_I2C_TRIGGER_READ		0x20
+#define AU0828_I2C_TRIGGER_HOLD		0x40
+
+/* I2C Status (Reg 0x201) */
+#define AU0828_I2C_STATUS_READ_DONE	0x01
+#define AU0828_I2C_STATUS_NO_READ_ACK	0x02
+#define AU0828_I2C_STATUS_WRITE_DONE	0x04
+#define AU0828_I2C_STATUS_NO_WRITE_ACK	0x08
+#define AU0828_I2C_STATUS_BUSY		0x10
+
+/* I2C Clock Divider (Reg 0x202) */
+#define AU0828_I2C_CLK_250KHZ 0x07
+#define AU0828_I2C_CLK_100KHZ 0x14
+#define AU0828_I2C_CLK_30KHZ  0x40
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-video.c linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/au0828-video.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/au0828-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1710 @@
+/*
+ * Auvitek AU0828 USB Bridge (Analog video support)
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * As published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* Developer Notes:
+ *
+ * VBI support is not yet working
+ * The hardware scaler supported is unimplemented
+ * AC97 audio support is unimplemented (only i2s audio mode)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/tuner.h>
+#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)
+
+/* ------------------------------------------------------------------
+	Videobuf operations
+   ------------------------------------------------------------------*/
+
+static unsigned int isoc_debug;
+module_param(isoc_debug, int, 0644);
+MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
+
+#define au0828_isocdbg(fmt, arg...) \
+do {\
+	if (isoc_debug) { \
+		printk(KERN_INFO "au0828 %s :"fmt, \
+		       __func__ , ##arg);	   \
+	} \
+  } while (0)
+
+static inline void print_err_status(struct au0828_dev *dev,
+				    int packet, int status)
+{
+	char *errmsg = "Unknown";
+
+	switch (status) {
+	case -ENOENT:
+		errmsg = "unlinked synchronuously";
+		break;
+	case -ECONNRESET:
+		errmsg = "unlinked asynchronuously";
+		break;
+	case -ENOSR:
+		errmsg = "Buffer error (overrun)";
+		break;
+	case -EPIPE:
+		errmsg = "Stalled (device not responding)";
+		break;
+	case -EOVERFLOW:
+		errmsg = "Babble (bad cable?)";
+		break;
+	case -EPROTO:
+		errmsg = "Bit-stuff error (bad cable?)";
+		break;
+	case -EILSEQ:
+		errmsg = "CRC/Timeout (could be anything)";
+		break;
+	case -ETIME:
+		errmsg = "Device does not respond";
+		break;
+	}
+	if (packet < 0) {
+		au0828_isocdbg("URB status %d [%s].\n",	status, errmsg);
+	} else {
+		au0828_isocdbg("URB packet %d, status %d [%s].\n",
+			       packet, status, errmsg);
+	}
+}
+
+static int check_dev(struct au0828_dev *dev)
+{
+	if (dev->dev_state & DEV_DISCONNECTED) {
+		printk(KERN_INFO "v4l2 ioctl: device not present\n");
+		return -ENODEV;
+	}
+
+	if (dev->dev_state & DEV_MISCONFIGURED) {
+		printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
+		       "close and open it again\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void au0828_irq_callback(struct urb *urb)
+{
+	struct au0828_dmaqueue  *dma_q = urb->context;
+	struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+	int rc, i;
+
+	switch (urb->status) {
+	case 0:             /* success */
+	case -ETIMEDOUT:    /* NAK */
+		break;
+	case -ECONNRESET:   /* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		au0828_isocdbg("au0828_irq_callback called: status kill\n");
+		return;
+	default:            /* unknown error */
+		au0828_isocdbg("urb completition error %d.\n", urb->status);
+		break;
+	}
+
+	/* Copy data from URB */
+	spin_lock(&dev->slock);
+	rc = dev->isoc_ctl.isoc_copy(dev, urb);
+	spin_unlock(&dev->slock);
+
+	/* Reset urb buffers */
+	for (i = 0; i < urb->number_of_packets; i++) {
+		urb->iso_frame_desc[i].status = 0;
+		urb->iso_frame_desc[i].actual_length = 0;
+	}
+	urb->status = 0;
+
+	urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (urb->status) {
+		au0828_isocdbg("urb resubmit failed (error=%i)\n",
+			       urb->status);
+	}
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void au0828_uninit_isoc(struct au0828_dev *dev)
+{
+	struct urb *urb;
+	int i;
+
+	au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
+
+	dev->isoc_ctl.nfields = -1;
+	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+		urb = dev->isoc_ctl.urb[i];
+		if (urb) {
+			if (!irqs_disabled())
+				usb_kill_urb(urb);
+			else
+				usb_unlink_urb(urb);
+
+			if (dev->isoc_ctl.transfer_buffer[i]) {
+				usb_buffer_free(dev->usbdev,
+					urb->transfer_buffer_length,
+					dev->isoc_ctl.transfer_buffer[i],
+					urb->transfer_dma);
+			}
+			usb_free_urb(urb);
+			dev->isoc_ctl.urb[i] = NULL;
+		}
+		dev->isoc_ctl.transfer_buffer[i] = NULL;
+	}
+
+	kfree(dev->isoc_ctl.urb);
+	kfree(dev->isoc_ctl.transfer_buffer);
+
+	dev->isoc_ctl.urb = NULL;
+	dev->isoc_ctl.transfer_buffer = NULL;
+	dev->isoc_ctl.num_bufs = 0;
+}
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
+		     int num_bufs, int max_pkt_size,
+		     int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
+{
+	struct au0828_dmaqueue *dma_q = &dev->vidq;
+	int i;
+	int sb_size, pipe;
+	struct urb *urb;
+	int j, k;
+	int rc;
+
+	au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
+
+	/* De-allocates all pending stuff */
+	au0828_uninit_isoc(dev);
+
+	dev->isoc_ctl.isoc_copy = isoc_copy;
+	dev->isoc_ctl.num_bufs = num_bufs;
+
+	dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs,  GFP_KERNEL);
+	if (!dev->isoc_ctl.urb) {
+		au0828_isocdbg("cannot alloc memory for usb buffers\n");
+		return -ENOMEM;
+	}
+
+	dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
+					      GFP_KERNEL);
+	if (!dev->isoc_ctl.transfer_buffer) {
+		au0828_isocdbg("cannot allocate memory for usb transfer\n");
+		kfree(dev->isoc_ctl.urb);
+		return -ENOMEM;
+	}
+
+	dev->isoc_ctl.max_pkt_size = max_pkt_size;
+	dev->isoc_ctl.buf = NULL;
+
+	sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
+
+	/* allocate urbs and transfer buffers */
+	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+		urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+		if (!urb) {
+			au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
+			au0828_uninit_isoc(dev);
+			return -ENOMEM;
+		}
+		dev->isoc_ctl.urb[i] = urb;
+
+		dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
+			sb_size, GFP_KERNEL, &urb->transfer_dma);
+		if (!dev->isoc_ctl.transfer_buffer[i]) {
+			printk("unable to allocate %i bytes for transfer"
+					" buffer %i%s\n",
+					sb_size, i,
+					in_interrupt() ? " while in int" : "");
+			au0828_uninit_isoc(dev);
+			return -ENOMEM;
+		}
+		memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+		pipe = usb_rcvisocpipe(dev->usbdev,
+				       dev->isoc_in_endpointaddr),
+
+		usb_fill_int_urb(urb, dev->usbdev, pipe,
+				 dev->isoc_ctl.transfer_buffer[i], sb_size,
+				 au0828_irq_callback, dma_q, 1);
+
+		urb->number_of_packets = max_packets;
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+
+		k = 0;
+		for (j = 0; j < max_packets; j++) {
+			urb->iso_frame_desc[j].offset = k;
+			urb->iso_frame_desc[j].length =
+						dev->isoc_ctl.max_pkt_size;
+			k += dev->isoc_ctl.max_pkt_size;
+		}
+	}
+
+	init_waitqueue_head(&dma_q->wq);
+
+	/* submit urbs and enables IRQ */
+	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+		rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
+		if (rc) {
+			au0828_isocdbg("submit of urb %i failed (error=%i)\n",
+				       i, rc);
+			au0828_uninit_isoc(dev);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void buffer_filled(struct au0828_dev *dev,
+				  struct au0828_dmaqueue *dma_q,
+				  struct au0828_buffer *buf)
+{
+	/* Advice that buffer was filled */
+	au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+
+	buf->vb.state = VIDEOBUF_DONE;
+	buf->vb.field_count++;
+	do_gettimeofday(&buf->vb.ts);
+
+	dev->isoc_ctl.buf = NULL;
+
+	list_del(&buf->vb.queue);
+	wake_up(&buf->vb.done);
+}
+
+/*
+ * Identify the buffer header type and properly handles
+ */
+static void au0828_copy_video(struct au0828_dev *dev,
+			      struct au0828_dmaqueue  *dma_q,
+			      struct au0828_buffer *buf,
+			      unsigned char *p,
+			      unsigned char *outp, unsigned long len)
+{
+	void *fieldstart, *startwrite, *startread;
+	int  linesdone, currlinedone, offset, lencopy, remain;
+	int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
+
+	if (dma_q->pos + len > buf->vb.size)
+		len = buf->vb.size - dma_q->pos;
+
+	startread = p;
+	remain = len;
+
+	/* Interlaces frame */
+	if (buf->top_field)
+		fieldstart = outp;
+	else
+		fieldstart = outp + bytesperline;
+
+	linesdone = dma_q->pos / bytesperline;
+	currlinedone = dma_q->pos % bytesperline;
+	offset = linesdone * bytesperline * 2 + currlinedone;
+	startwrite = fieldstart + offset;
+	lencopy = bytesperline - currlinedone;
+	lencopy = lencopy > remain ? remain : lencopy;
+
+	if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+		au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
+			       ((char *)startwrite + lencopy) -
+			       ((char *)outp + buf->vb.size));
+		remain = (char *)outp + buf->vb.size - (char *)startwrite;
+		lencopy = remain;
+	}
+	if (lencopy <= 0)
+		return;
+	memcpy(startwrite, startread, lencopy);
+
+	remain -= lencopy;
+
+	while (remain > 0) {
+		startwrite += lencopy + bytesperline;
+		startread += lencopy;
+		if (bytesperline > remain)
+			lencopy = remain;
+		else
+			lencopy = bytesperline;
+
+		if ((char *)startwrite + lencopy > (char *)outp +
+		    buf->vb.size) {
+			au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
+				       ((char *)startwrite + lencopy) -
+				       ((char *)outp + buf->vb.size));
+			lencopy = remain = (char *)outp + buf->vb.size -
+					   (char *)startwrite;
+		}
+		if (lencopy <= 0)
+			break;
+
+		memcpy(startwrite, startread, lencopy);
+
+		remain -= lencopy;
+	}
+
+	if (offset > 1440) {
+		/* We have enough data to check for greenscreen */
+		if (outp[0] < 0x60 && outp[1440] < 0x60)
+			dev->greenscreen_detected = 1;
+	}
+
+	dma_q->pos += len;
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
+				struct au0828_buffer **buf)
+{
+	struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+
+	if (list_empty(&dma_q->active)) {
+		au0828_isocdbg("No active queue to serve\n");
+		dev->isoc_ctl.buf = NULL;
+		*buf = NULL;
+		return;
+	}
+
+	/* Get the next buffer */
+	*buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
+	dev->isoc_ctl.buf = *buf;
+
+	return;
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
+{
+	struct au0828_buffer    *buf;
+	struct au0828_dmaqueue  *dma_q = urb->context;
+	unsigned char *outp = NULL;
+	int i, len = 0, rc = 1;
+	unsigned char *p;
+	unsigned char fbyte;
+
+	if (!dev)
+		return 0;
+
+	if ((dev->dev_state & DEV_DISCONNECTED) ||
+	    (dev->dev_state & DEV_MISCONFIGURED))
+		return 0;
+
+	if (urb->status < 0) {
+		print_err_status(dev, -1, urb->status);
+		if (urb->status == -ENOENT)
+			return 0;
+	}
+
+	buf = dev->isoc_ctl.buf;
+	if (buf != NULL)
+		outp = videobuf_to_vmalloc(&buf->vb);
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		int status = urb->iso_frame_desc[i].status;
+
+		if (status < 0) {
+			print_err_status(dev, i, status);
+			if (urb->iso_frame_desc[i].status != -EPROTO)
+				continue;
+		}
+
+		if (urb->iso_frame_desc[i].actual_length <= 0)
+			continue;
+
+		if (urb->iso_frame_desc[i].actual_length >
+						dev->max_pkt_size) {
+			au0828_isocdbg("packet bigger than packet size");
+			continue;
+		}
+
+		p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+		fbyte = p[0];
+		len = urb->iso_frame_desc[i].actual_length - 4;
+		p += 4;
+
+		if (fbyte & 0x80) {
+			len -= 4;
+			p += 4;
+			au0828_isocdbg("Video frame %s\n",
+				       (fbyte & 0x40) ? "odd" : "even");
+			if (!(fbyte & 0x40)) {
+				if (buf != NULL)
+					buffer_filled(dev, dma_q, buf);
+				get_next_buf(dma_q, &buf);
+				if (buf == NULL)
+					outp = NULL;
+				else
+					outp = videobuf_to_vmalloc(&buf->vb);
+			}
+
+			if (buf != NULL) {
+				if (fbyte & 0x40)
+					buf->top_field = 1;
+				else
+					buf->top_field = 0;
+			}
+
+			dma_q->pos = 0;
+		}
+		if (buf != NULL)
+			au0828_copy_video(dev, dma_q, buf, p, outp, len);
+	}
+	return rc;
+}
+
+static int
+buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+	     unsigned int *size)
+{
+	struct au0828_fh *fh = vq->priv_data;
+	*size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+	if (0 == *count)
+		*count = AU0828_DEF_BUF;
+
+	if (*count < AU0828_MIN_BUF)
+		*count = AU0828_MIN_BUF;
+	return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
+{
+	struct au0828_fh     *fh  = vq->priv_data;
+	struct au0828_dev    *dev = fh->dev;
+	unsigned long flags = 0;
+	if (in_interrupt())
+		BUG();
+
+	/* We used to wait for the buffer to finish here, but this didn't work
+	   because, as we were keeping the state as VIDEOBUF_QUEUED,
+	   videobuf_queue_cancel marked it as finished for us.
+	   (Also, it could wedge forever if the hardware was misconfigured.)
+
+	   This should be safe; by the time we get here, the buffer isn't
+	   queued anymore. If we ever start marking the buffers as
+	   VIDEOBUF_ACTIVE, it won't be, though.
+	*/
+	spin_lock_irqsave(&dev->slock, flags);
+	if (dev->isoc_ctl.buf == buf)
+		dev->isoc_ctl.buf = NULL;
+	spin_unlock_irqrestore(&dev->slock, flags);
+
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+						enum v4l2_field field)
+{
+	struct au0828_fh     *fh  = vq->priv_data;
+	struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+	struct au0828_dev    *dev = fh->dev;
+	int                  rc = 0, urb_init = 0;
+
+	buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	buf->vb.width  = dev->width;
+	buf->vb.height = dev->height;
+	buf->vb.field  = field;
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc < 0) {
+			printk(KERN_INFO "videobuf_iolock failed\n");
+			goto fail;
+		}
+	}
+
+	if (!dev->isoc_ctl.num_bufs)
+		urb_init = 1;
+
+	if (urb_init) {
+		rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
+				      AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
+				      au0828_isoc_copy);
+		if (rc < 0) {
+			printk(KERN_INFO "au0828_init_isoc failed\n");
+			goto fail;
+		}
+	}
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+
+fail:
+	free_buffer(vq, buf);
+	return rc;
+}
+
+static void
+buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct au0828_buffer    *buf     = container_of(vb,
+							struct au0828_buffer,
+							vb);
+	struct au0828_fh        *fh      = vq->priv_data;
+	struct au0828_dev       *dev     = fh->dev;
+	struct au0828_dmaqueue  *vidq    = &dev->vidq;
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &vidq->active);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+				struct videobuf_buffer *vb)
+{
+	struct au0828_buffer   *buf  = container_of(vb,
+						    struct au0828_buffer,
+						    vb);
+
+	free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops au0828_video_qops = {
+	.buf_setup      = buffer_setup,
+	.buf_prepare    = buffer_prepare,
+	.buf_queue      = buffer_queue,
+	.buf_release    = buffer_release,
+};
+
+/* ------------------------------------------------------------------
+   V4L2 interface
+   ------------------------------------------------------------------*/
+
+static int au0828_i2s_init(struct au0828_dev *dev)
+{
+	/* Enable i2s mode */
+	au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
+	return 0;
+}
+
+/*
+ * Auvitek au0828 analog stream enable
+ * Please set interface0 to AS5 before enable the stream
+ */
+int au0828_analog_stream_enable(struct au0828_dev *d)
+{
+	dprintk(1, "au0828_analog_stream_enable called\n");
+	au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
+	au0828_writereg(d, 0x106, 0x00);
+	/* set x position */
+	au0828_writereg(d, 0x110, 0x00);
+	au0828_writereg(d, 0x111, 0x00);
+	au0828_writereg(d, 0x114, 0xa0);
+	au0828_writereg(d, 0x115, 0x05);
+	/* set y position */
+	au0828_writereg(d, 0x112, 0x02);
+	au0828_writereg(d, 0x113, 0x00);
+	au0828_writereg(d, 0x116, 0xf2);
+	au0828_writereg(d, 0x117, 0x00);
+	au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
+
+	return 0;
+}
+
+int au0828_analog_stream_disable(struct au0828_dev *d)
+{
+	dprintk(1, "au0828_analog_stream_disable called\n");
+	au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
+	return 0;
+}
+
+void au0828_analog_stream_reset(struct au0828_dev *dev)
+{
+	dprintk(1, "au0828_analog_stream_reset called\n");
+	au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
+	mdelay(30);
+	au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
+}
+
+/*
+ * Some operations needs to stop current streaming
+ */
+static int au0828_stream_interrupt(struct au0828_dev *dev)
+{
+	int ret = 0;
+
+	dev->stream_state = STREAM_INTERRUPT;
+	if (dev->dev_state == DEV_DISCONNECTED)
+		return -ENODEV;
+	else if (ret) {
+		dev->dev_state = DEV_MISCONFIGURED;
+		dprintk(1, "%s device is misconfigured!\n", __func__);
+		return ret;
+	}
+	return 0;
+}
+
+/*
+ * au0828_release_resources
+ * unregister v4l2 devices
+ */
+void au0828_analog_unregister(struct au0828_dev *dev)
+{
+	dprintk(1, "au0828_release_resources called\n");
+	mutex_lock(&au0828_sysfs_lock);
+
+	if (dev->vdev) {
+		list_del(&dev->au0828list);
+		video_unregister_device(dev->vdev);
+	}
+	if (dev->vbi_dev)
+		video_unregister_device(dev->vbi_dev);
+
+	mutex_unlock(&au0828_sysfs_lock);
+}
+
+
+/* Usage lock check functions */
+static int res_get(struct au0828_fh *fh)
+{
+	struct au0828_dev *dev = fh->dev;
+	int		 rc   = 0;
+
+	/* This instance already has stream_on */
+	if (fh->stream_on)
+		return rc;
+
+	if (dev->stream_on)
+		return -EBUSY;
+
+	dev->stream_on = 1;
+	fh->stream_on  = 1;
+	return rc;
+}
+
+static int res_check(struct au0828_fh *fh)
+{
+	return fh->stream_on;
+}
+
+static void res_free(struct au0828_fh *fh)
+{
+	struct au0828_dev *dev = fh->dev;
+
+	fh->stream_on = 0;
+	dev->stream_on = 0;
+}
+
+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_fh *fh;
+	int type = 0;
+	struct list_head *list;
+
+	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;
+		}
+#endif
+	}
+
+	if (NULL == dev)
+		return -ENODEV;
+
+	fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
+	if (NULL == fh) {
+		dprintk(1, "Failed allocate au0828_fh struct!\n");
+		return -ENOMEM;
+	}
+
+	fh->type = type;
+	fh->dev = dev;
+	filp->private_data = fh;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+		/* set au0828 interface0 to AS5 here again */
+		ret = usb_set_interface(dev->usbdev, 0, 5);
+		if (ret < 0) {
+			printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
+			return -EBUSY;
+		}
+		dev->width = NTSC_STD_W;
+		dev->height = NTSC_STD_H;
+		dev->frame_size = dev->width * dev->height * 2;
+		dev->field_size = dev->width * dev->height;
+		dev->bytesperline = dev->width * 2;
+
+		au0828_analog_stream_enable(dev);
+		au0828_analog_stream_reset(dev);
+
+		/* If we were doing ac97 instead of i2s, it would go here...*/
+		au0828_i2s_init(dev);
+
+		dev->stream_state = STREAM_OFF;
+		dev->dev_state |= DEV_INITIALIZED;
+	}
+
+	dev->users++;
+
+	videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
+				    NULL, &dev->slock, fh->type,
+				    V4L2_FIELD_INTERLACED,
+				    sizeof(struct au0828_buffer), fh);
+
+	return ret;
+}
+
+static int au0828_v4l2_close(struct file *filp)
+{
+	int ret;
+	struct au0828_fh *fh = filp->private_data;
+	struct au0828_dev *dev = fh->dev;
+
+	mutex_lock(&dev->lock);
+	if (res_check(fh))
+		res_free(fh);
+
+	if (dev->users == 1) {
+		videobuf_stop(&fh->vb_vidq);
+		videobuf_mmap_free(&fh->vb_vidq);
+
+		if (dev->dev_state & DEV_DISCONNECTED) {
+			au0828_analog_unregister(dev);
+			mutex_unlock(&dev->lock);
+			kfree(dev);
+			return 0;
+		}
+
+		au0828_analog_stream_disable(dev);
+
+		au0828_uninit_isoc(dev);
+
+		/* When close the device, set the usb intf0 into alt0 to free
+		   USB bandwidth */
+		ret = usb_set_interface(dev->usbdev, 0, 0);
+		if (ret < 0)
+			printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
+	}
+
+	kfree(fh);
+	dev->users--;
+	wake_up_interruptible_nr(&dev->open, 1);
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
+				size_t count, loff_t *pos)
+{
+	struct au0828_fh *fh = filp->private_data;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		mutex_lock(&dev->lock);
+		rc = res_get(fh);
+		mutex_unlock(&dev->lock);
+
+		if (unlikely(rc < 0))
+			return rc;
+
+		return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+					filp->f_flags & O_NONBLOCK);
+	}
+	return 0;
+}
+
+static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
+{
+	struct au0828_fh *fh = filp->private_data;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+	mutex_unlock(&dev->lock);
+
+	if (unlikely(rc < 0))
+		return POLLERR;
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+		return POLLERR;
+
+	return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+}
+
+static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct au0828_fh *fh    = filp->private_data;
+	struct au0828_dev *dev   = fh->dev;
+	int		 rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+	mutex_unlock(&dev->lock);
+
+	if (unlikely(rc < 0))
+		return rc;
+
+	rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+	dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
+		(unsigned long)vma->vm_start,
+		(unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
+		rc);
+
+	return rc;
+}
+
+static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
+			     struct v4l2_format *format)
+{
+	int ret;
+	int width = format->fmt.pix.width;
+	int height = format->fmt.pix.height;
+	unsigned int maxwidth, maxheight;
+
+	maxwidth = 720;
+	maxheight = 480;
+
+#ifdef VBI_IS_WORKING
+	if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+		dprintk(1, "VBI format set: to be supported!\n");
+		return 0;
+	}
+	if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		return 0;
+#endif
+	if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	/* If they are demanding a format other than the one we support,
+	   bail out (tvtime asks for UYVY and then retries with YUYV) */
+	if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
+		return -EINVAL;
+
+	/* format->fmt.pix.width only support 720 and height 480 */
+	if (width != 720)
+		width = 720;
+	if (height != 480)
+		height = 480;
+
+	format->fmt.pix.width = width;
+	format->fmt.pix.height = height;
+	format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+	format->fmt.pix.bytesperline = width * 2;
+	format->fmt.pix.sizeimage = width * height * 2;
+	format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+	format->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+	if (cmd == VIDIOC_TRY_FMT)
+		return 0;
+
+	/* maybe set new image format, driver current only support 720*480 */
+	dev->width = width;
+	dev->height = height;
+	dev->frame_size = width * height * 2;
+	dev->field_size = width * height;
+	dev->bytesperline = width * 2;
+
+	if (dev->stream_state == STREAM_ON) {
+		dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
+		ret = au0828_stream_interrupt(dev);
+		if (ret != 0) {
+			dprintk(1, "error interrupting video stream!\n");
+			return ret;
+		}
+	}
+
+	/* set au0828 interface0 to AS5 here again */
+	ret = usb_set_interface(dev->usbdev, 0, 5);
+	if (ret < 0) {
+		printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
+		return -EBUSY;
+	}
+
+	au0828_analog_stream_enable(dev);
+
+	return 0;
+}
+
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+			    struct v4l2_queryctrl *qc)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
+	if (qc->type)
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int vidioc_querycap(struct file *file, void  *priv,
+			   struct v4l2_capability *cap)
+{
+	struct au0828_fh *fh  = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	strlcpy(cap->driver, "au0828", sizeof(cap->driver));
+	strlcpy(cap->card, dev->board.name, sizeof(cap->card));
+	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+
+	cap->version = AU0828_VERSION_CODE;
+
+	/*set the device capabilities */
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+#ifdef VBI_IS_WORKING
+		V4L2_CAP_VBI_CAPTURE |
+#endif
+		V4L2_CAP_AUDIO |
+		V4L2_CAP_READWRITE |
+		V4L2_CAP_STREAMING |
+		V4L2_CAP_TUNER;
+	return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *f)
+{
+	if (f->index)
+		return -EINVAL;
+
+	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	strcpy(f->description, "Packed YUV2");
+
+	f->flags = 0;
+	f->pixelformat = V4L2_PIX_FMT_UYVY;
+
+	return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct au0828_fh *fh  = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	f->fmt.pix.width = dev->width;
+	f->fmt.pix.height = dev->height;
+	f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+	f->fmt.pix.bytesperline = dev->bytesperline;
+	f->fmt.pix.sizeimage = dev->frame_size;
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
+	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+	return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct au0828_fh *fh  = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct au0828_fh *fh  = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+		printk(KERN_INFO "%s queue busy\n", __func__);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	if (dev->stream_on && !fh->stream_on) {
+		printk(KERN_INFO "%s device in use by another fh\n", __func__);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	return au0828_set_format(dev, VIDIOC_S_FMT, f);
+out:
+	return rc;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	/* FIXME: when we support something other than NTSC, we are going to
+	   have to make the au0828 bridge adjust the size of its capture
+	   buffer, which is currently hardcoded at 720x480 */
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, *norm);
+	return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+				struct v4l2_input *input)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	unsigned int tmp;
+
+	static const char *inames[] = {
+		[AU0828_VMUX_UNDEFINED] = "Undefined",
+		[AU0828_VMUX_COMPOSITE] = "Composite",
+		[AU0828_VMUX_SVIDEO] = "S-Video",
+		[AU0828_VMUX_CABLE] = "Cable TV",
+		[AU0828_VMUX_TELEVISION] = "Television",
+		[AU0828_VMUX_DVB] = "DVB",
+		[AU0828_VMUX_DEBUG] = "tv debug"
+	};
+
+	tmp = input->index;
+
+	if (tmp > AU0828_MAX_INPUT)
+		return -EINVAL;
+	if (AUVI_INPUT(tmp).type == 0)
+		return -EINVAL;
+
+	input->index = tmp;
+	strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
+	if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
+	    (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
+		input->type |= V4L2_INPUT_TYPE_TUNER;
+	else
+		input->type |= V4L2_INPUT_TYPE_CAMERA;
+
+	input->std = dev->vdev->tvnorms;
+
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	*i = dev->ctrl_input;
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int i;
+
+	dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
+		index);
+	if (index >= AU0828_MAX_INPUT)
+		return -EINVAL;
+	if (AUVI_INPUT(index).type == 0)
+		return -EINVAL;
+	dev->ctrl_input = index;
+
+	switch (AUVI_INPUT(index).type) {
+	case AU0828_VMUX_SVIDEO:
+		dev->input_type = AU0828_VMUX_SVIDEO;
+		break;
+	case AU0828_VMUX_COMPOSITE:
+		dev->input_type = AU0828_VMUX_COMPOSITE;
+		break;
+	case AU0828_VMUX_TELEVISION:
+		dev->input_type = AU0828_VMUX_TELEVISION;
+		break;
+	default:
+		dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
+			AUVI_INPUT(index).type);
+		break;
+	}
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			AUVI_INPUT(index).vmux, 0, 0);
+
+	for (i = 0; i < AU0828_MAX_INPUT; i++) {
+		int enable = 0;
+		if (AUVI_INPUT(i).audio_setup == NULL)
+			continue;
+
+		if (i == index)
+			enable = 1;
+		else
+			enable = 0;
+		if (enable) {
+			(AUVI_INPUT(i).audio_setup)(dev, enable);
+		} else {
+			/* Make sure we leave it turned on if some
+			   other input is routed to this callback */
+			if ((AUVI_INPUT(i).audio_setup) !=
+			    ((AUVI_INPUT(index).audio_setup))) {
+				(AUVI_INPUT(i).audio_setup)(dev, enable);
+			}
+		}
+	}
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			AUVI_INPUT(index).amux, 0, 0);
+	return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	unsigned int index = a->index;
+
+	if (a->index > 1)
+		return -EINVAL;
+
+	index = dev->ctrl_ainput;
+	if (index == 0)
+		strcpy(a->name, "Television");
+	else
+		strcpy(a->name, "Line in");
+
+	a->capability = V4L2_AUDCAP_STEREO;
+	a->index = index;
+	return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	if (a->index != dev->ctrl_ainput)
+		return -EINVAL;
+	return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctrl)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
+	return 0;
+
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+				struct v4l2_control *ctrl)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
+	return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	if (t->index != 0)
+		return -EINVAL;
+
+	strcpy(t->name, "Auvitek tuner");
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
+	return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+				struct v4l2_tuner *t)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	if (t->index != 0)
+		return -EINVAL;
+
+	t->type = V4L2_TUNER_ANALOG_TV;
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
+	dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
+		t->afc);
+	return 0;
+
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *freq)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	freq->type = V4L2_TUNER_ANALOG_TV;
+	freq->frequency = dev->ctrl_freq;
+	return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *freq)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	if (freq->tuner != 0)
+		return -EINVAL;
+	if (freq->type != V4L2_TUNER_ANALOG_TV)
+		return -EINVAL;
+
+	dev->ctrl_freq = freq->frequency;
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
+
+	au0828_analog_stream_reset(dev);
+
+	return 0;
+}
+
+static int vidioc_g_chip_ident(struct file *file, void *priv,
+	       struct v4l2_dbg_chip_ident *chip)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+
+	if (v4l2_chip_match_host(&chip->match)) {
+		chip->ident = V4L2_IDENT_AU0828;
+		return 0;
+	}
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
+	if (chip->ident == V4L2_IDENT_NONE)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int vidioc_cropcap(struct file *file, void *priv,
+			  struct v4l2_cropcap *cc)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	cc->bounds.left = 0;
+	cc->bounds.top = 0;
+	cc->bounds.width = dev->width;
+	cc->bounds.height = dev->height;
+
+	cc->defrect = cc->bounds;
+
+	cc->pixelaspect.numerator = 54;
+	cc->pixelaspect.denominator = 59;
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+			   enum v4l2_buf_type type)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		au0828_analog_stream_enable(dev);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+	}
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+
+	if (likely(rc >= 0))
+		rc = videobuf_streamon(&fh->vb_vidq);
+	mutex_unlock(&dev->lock);
+
+	return rc;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+			    enum v4l2_buf_type type)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int i;
+	int ret;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (type != fh->type)
+		return -EINVAL;
+
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+		ret = au0828_stream_interrupt(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	for (i = 0; i < AU0828_MAX_INPUT; i++) {
+		if (AUVI_INPUT(i).audio_setup == NULL)
+			continue;
+		(AUVI_INPUT(i).audio_setup)(dev, 0);
+	}
+
+	mutex_lock(&dev->lock);
+	videobuf_streamoff(&fh->vb_vidq);
+	res_free(fh);
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *priv,
+			     struct v4l2_dbg_register *reg)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	switch (reg->match.type) {
+	case V4L2_CHIP_MATCH_I2C_DRIVER:
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+			     struct v4l2_dbg_register *reg)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+
+	switch (reg->match.type) {
+	case V4L2_CHIP_MATCH_I2C_DRIVER:
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+#endif
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *rb)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+			   struct v4l2_buffer *b)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct au0828_fh *fh = priv;
+	struct au0828_dev *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	/* Workaround for a bug in the au0828 hardware design that sometimes
+	   results in the colorspace being inverted */
+	if (dev->greenscreen_detected == 1) {
+		dprintk(1, "Detected green frame.  Resetting stream...\n");
+		au0828_analog_stream_reset(dev);
+		dev->greenscreen_detected = 0;
+	}
+
+	return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+	struct au0828_fh *fh = priv;
+
+	return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+static struct v4l2_file_operations au0828_v4l_fops = {
+	.owner      = THIS_MODULE,
+	.open       = au0828_v4l2_open,
+	.release    = au0828_v4l2_close,
+	.read       = au0828_v4l2_read,
+	.poll       = au0828_v4l2_poll,
+	.mmap       = au0828_v4l2_mmap,
+	.ioctl      = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap            = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap    = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap       = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap     = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap       = vidioc_s_fmt_vid_cap,
+#ifdef VBI_IS_WORKING
+	.vidioc_g_fmt_vbi_cap       = vidioc_g_fmt_vbi_cap,
+	.vidioc_try_fmt_vbi_cap     = vidioc_s_fmt_vbi_cap,
+	.vidioc_s_fmt_vbi_cap       = vidioc_s_fmt_vbi_cap,
+#endif
+	.vidioc_g_audio             = vidioc_g_audio,
+	.vidioc_s_audio             = vidioc_s_audio,
+	.vidioc_cropcap             = vidioc_cropcap,
+#ifdef VBI_IS_WORKING
+	.vidioc_g_fmt_sliced_vbi_cap   = vidioc_g_fmt_sliced_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+	.vidioc_s_fmt_sliced_vbi_cap   = vidioc_try_set_sliced_vbi_cap,
+#endif
+	.vidioc_reqbufs             = vidioc_reqbufs,
+	.vidioc_querybuf            = vidioc_querybuf,
+	.vidioc_qbuf                = vidioc_qbuf,
+	.vidioc_dqbuf               = vidioc_dqbuf,
+	.vidioc_s_std               = vidioc_s_std,
+	.vidioc_enum_input          = vidioc_enum_input,
+	.vidioc_g_input             = vidioc_g_input,
+	.vidioc_s_input             = vidioc_s_input,
+	.vidioc_queryctrl           = vidioc_queryctrl,
+	.vidioc_g_ctrl              = vidioc_g_ctrl,
+	.vidioc_s_ctrl              = vidioc_s_ctrl,
+	.vidioc_streamon            = vidioc_streamon,
+	.vidioc_streamoff           = vidioc_streamoff,
+	.vidioc_g_tuner             = vidioc_g_tuner,
+	.vidioc_s_tuner             = vidioc_s_tuner,
+	.vidioc_g_frequency         = vidioc_g_frequency,
+	.vidioc_s_frequency         = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register          = vidioc_g_register,
+	.vidioc_s_register          = vidioc_s_register,
+#endif
+	.vidioc_g_chip_ident        = vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf                = vidiocgmbuf,
+#endif
+};
+
+static const struct video_device au0828_video_template = {
+	.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,
+};
+
+/**************************************************************************/
+
+int au0828_analog_register(struct au0828_dev *dev,
+			   struct usb_interface *interface)
+{
+	int retval = -ENOMEM;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+
+	dprintk(1, "au0828_analog_register called!\n");
+
+	/* set au0828 usb interface0 to as5 */
+	retval = usb_set_interface(dev->usbdev,
+			interface->cur_altsetting->desc.bInterfaceNumber, 5);
+	if (retval != 0) {
+		printk(KERN_INFO "Failure setting usb interface0 to as5\n");
+		return retval;
+	}
+
+	/* Figure out which endpoint has the isoc interface */
+	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+		endpoint = &iface_desc->endpoint[i].desc;
+		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+		     == USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+		     == USB_ENDPOINT_XFER_ISOC)) {
+
+			/* we find our isoc in endpoint */
+			u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
+			dev->max_pkt_size = (tmp & 0x07ff) *
+				(((tmp & 0x1800) >> 11) + 1);
+			dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
+		}
+	}
+	if (!(dev->isoc_in_endpointaddr)) {
+		printk(KERN_INFO "Could not locate isoc endpoint\n");
+		kfree(dev);
+		return -ENODEV;
+	}
+
+	init_waitqueue_head(&dev->open);
+	spin_lock_init(&dev->slock);
+	mutex_init(&dev->lock);
+
+	INIT_LIST_HEAD(&dev->vidq.active);
+	INIT_LIST_HEAD(&dev->vidq.queued);
+
+	dev->width = NTSC_STD_W;
+	dev->height = NTSC_STD_H;
+	dev->field_size = dev->width * dev->height;
+	dev->frame_size = dev->field_size << 1;
+	dev->bytesperline = dev->width << 1;
+	dev->ctrl_ainput = 0;
+
+	/* allocate and fill v4l2 video struct */
+	dev->vdev = video_device_alloc();
+	if (NULL == dev->vdev) {
+		dprintk(1, "Can't allocate video_device.\n");
+		return -ENOMEM;
+	}
+
+#ifdef VBI_IS_WORKING
+	dev->vbi_dev = video_device_alloc();
+	if (NULL == dev->vbi_dev) {
+		dprintk(1, "Can't allocate vbi_device.\n");
+		kfree(dev->vdev);
+		return -ENOMEM;
+	}
+#endif
+
+	/* Fill the video capture device struct */
+	*dev->vdev = au0828_video_template;
+	dev->vdev->parent = &dev->usbdev->dev;
+	strcpy(dev->vdev->name, "au0828a video");
+
+#ifdef VBI_IS_WORKING
+	/* Setup the VBI device */
+	*dev->vbi_dev = au0828_video_template;
+	dev->vbi_dev->parent = &dev->usbdev->dev;
+	strcpy(dev->vbi_dev->name, "au0828a vbi");
+#endif
+
+	list_add_tail(&dev->au0828list, &au0828_devlist);
+
+	/* Register the v4l2 device */
+	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 */
+	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;
+	}
+#endif
+
+	dprintk(1, "%s completed!\n", __func__);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/au0828/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,14 @@
 
 config VIDEO_AU0828
 	tristate "Auvitek AU0828 support"
-	depends on I2C && INPUT && DVB_CORE && USB
+	depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
 	select I2C_ALGOBIT
 	select VIDEO_TVEEPROM
-	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
+	select VIDEOBUF_VMALLOC
+	select DVB_AU8522 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This is a video4linux driver for Auvitek's USB device.
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/au0828/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/au0828/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/au0828/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/au0828/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,4 @@
-au0828-objs	:= au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
+au0828-objs	:= au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o
 
 obj-$(CONFIG_VIDEO_AU0828) += au0828.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt819.c linux-libre-2.6.30-gnu1/drivers/media/video/bt819.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt819.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt819.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,16 +29,16 @@
  */
 
 #include <linux/module.h>
-#include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/ioctl.h>
-#include <asm/uaccess.h>
+#include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/bt819.h>
 
 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -48,13 +48,15 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+
 /* ----------------------------------------------------------------------- */
 
 struct bt819 {
+	struct v4l2_subdev sd;
 	unsigned char reg[32];
 
-	int initialized;
-	int norm;
+	v4l2_std_id norm;
+	int ident;
 	int input;
 	int enable;
 	int bright;
@@ -63,6 +65,11 @@ struct bt819 {
 	int sat;
 };
 
+static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct bt819, sd);
+}
+
 struct timing {
 	int hactive;
 	int hdelay;
@@ -80,24 +87,23 @@ static struct timing timing_data[] = {
 
 /* ----------------------------------------------------------------------- */
 
-static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
 {
-	struct bt819 *decoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
 
 	decoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
 {
-	struct bt819 *decoder = i2c_get_clientdata(client);
-
-	return bt819_write(client, reg,
+	return bt819_write(decoder, reg,
 		(decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
 }
 
-static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
 	int ret = -1;
 	u8 reg;
 
@@ -105,7 +111,6 @@ static int bt819_write_block(struct i2c_
 	 * the adapter understands raw I2C */
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		/* do raw I2C, not smbus compatible */
-		struct bt819 *decoder = i2c_get_clientdata(client);
 		u8 block_data[32];
 		int block_len;
 
@@ -126,7 +131,8 @@ static int bt819_write_block(struct i2c_
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = bt819_write(client, reg, *data++)) < 0)
+			ret = bt819_write(decoder, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
@@ -135,15 +141,15 @@ static int bt819_write_block(struct i2c_
 	return ret;
 }
 
-static inline int bt819_read(struct i2c_client *client, u8 reg)
+static inline int bt819_read(struct bt819 *decoder, u8 reg)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
+
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int bt819_init(struct i2c_client *client)
+static int bt819_init(struct v4l2_subdev *sd)
 {
-	struct bt819 *decoder = i2c_get_clientdata(client);
-
 	static unsigned char init[] = {
 		/*0x1f, 0x00,*/     /* Reset */
 		0x01, 0x59,	/* 0x01 input format */
@@ -178,7 +184,8 @@ static int bt819_init(struct i2c_client
 		0x1a, 0x80,	/* 0x1a ADC Interface */
 	};
 
-	struct timing *timing = &timing_data[decoder->norm];
+	struct bt819 *decoder = to_bt819(sd);
+	struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
 
 	init[0x03 * 2 - 1] =
 	    (((timing->vdelay >> 8) & 0x03) << 6) |
@@ -192,266 +199,303 @@ static int bt819_init(struct i2c_client
 	init[0x08 * 2 - 1] = timing->hscale >> 8;
 	init[0x09 * 2 - 1] = timing->hscale & 0xff;
 	/* 0x15 in array is address 0x19 */
-	init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;	/* Chroma burst delay */
+	init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;	/* Chroma burst delay */
 	/* reset */
-	bt819_write(client, 0x1f, 0x00);
+	bt819_write(decoder, 0x1f, 0x00);
 	mdelay(1);
 
 	/* init */
-	return bt819_write_block(client, init, sizeof(init));
+	return bt819_write_block(decoder, init, sizeof(init));
 }
 
 /* ----------------------------------------------------------------------- */
 
-static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
 {
-	int temp;
+	struct bt819 *decoder = to_bt819(sd);
+	int status = bt819_read(decoder, 0x00);
+	int res = V4L2_IN_ST_NO_SIGNAL;
+	v4l2_std_id std;
 
-	struct bt819 *decoder = i2c_get_clientdata(client);
+	if ((status & 0x80))
+		res = 0;
 
-	if (!decoder->initialized) {	/* First call to bt819_init could be */
-		bt819_init(client);	/* without #FRST = 0 */
-		decoder->initialized = 1;
-	}
+	if ((status & 0x10))
+		std = V4L2_STD_PAL;
+	else
+		std = V4L2_STD_NTSC;
+	if (pstd)
+		*pstd = std;
+	if (pstatus)
+		*pstatus = status;
 
-	switch (cmd) {
-	case 0:
-		/* This is just for testing!!! */
-		bt819_init(client);
-		break;
+	v4l2_dbg(1, debug, sd, "get status %x\n", status);
+	return 0;
+}
 
-	case DECODER_GET_CAPABILITIES:
-	{
-		struct video_decoder_capability *cap = arg;
+static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	return bt819_status(sd, NULL, std);
+}
 
-		cap->flags = VIDEO_DECODER_PAL |
-			     VIDEO_DECODER_NTSC |
-			     VIDEO_DECODER_AUTO |
-			     VIDEO_DECODER_CCIR;
-		cap->inputs = 8;
-		cap->outputs = 1;
-		break;
-	}
+static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	return bt819_status(sd, status, NULL);
+}
 
-	case DECODER_GET_STATUS:
-	{
-		int *iarg = arg;
-		int status;
-		int res;
+static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct bt819 *decoder = to_bt819(sd);
+	struct timing *timing = NULL;
 
-		status = bt819_read(client, 0x00);
-		res = 0;
-		if ((status & 0x80))
-			res |= DECODER_STATUS_GOOD;
+	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
 
-		switch (decoder->norm) {
-		case VIDEO_MODE_NTSC:
-			res |= DECODER_STATUS_NTSC;
-			break;
-		case VIDEO_MODE_PAL:
-			res |= DECODER_STATUS_PAL;
-			break;
-		default:
-		case VIDEO_MODE_AUTO:
-			if ((status & 0x10))
-				res |= DECODER_STATUS_PAL;
-			else
-				res |= DECODER_STATUS_NTSC;
-			break;
-		}
-		res |= DECODER_STATUS_COLOR;
-		*iarg = res;
+	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+		v4l2_err(sd, "no notify found!\n");
 
-		v4l_dbg(1, debug, client, "get status %x\n", *iarg);
-		break;
+	if (std & V4L2_STD_NTSC) {
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+		bt819_setbit(decoder, 0x01, 0, 1);
+		bt819_setbit(decoder, 0x01, 1, 0);
+		bt819_setbit(decoder, 0x01, 5, 0);
+		bt819_write(decoder, 0x18, 0x68);
+		bt819_write(decoder, 0x19, 0x5d);
+		/* bt819_setbit(decoder, 0x1a,  5, 1); */
+		timing = &timing_data[1];
+	} else if (std & V4L2_STD_PAL) {
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+		bt819_setbit(decoder, 0x01, 0, 1);
+		bt819_setbit(decoder, 0x01, 1, 1);
+		bt819_setbit(decoder, 0x01, 5, 1);
+		bt819_write(decoder, 0x18, 0x7f);
+		bt819_write(decoder, 0x19, 0x72);
+		/* bt819_setbit(decoder, 0x1a,  5, 0); */
+		timing = &timing_data[0];
+	} else {
+		v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
+				(unsigned long long)std);
+		return -EINVAL;
 	}
+	bt819_write(decoder, 0x03,
+			(((timing->vdelay >> 8) & 0x03) << 6) |
+			(((timing->vactive >> 8) & 0x03) << 4) |
+			(((timing->hdelay >> 8) & 0x03) << 2) |
+			((timing->hactive >> 8) & 0x03));
+	bt819_write(decoder, 0x04, timing->vdelay & 0xff);
+	bt819_write(decoder, 0x05, timing->vactive & 0xff);
+	bt819_write(decoder, 0x06, timing->hdelay & 0xff);
+	bt819_write(decoder, 0x07, timing->hactive & 0xff);
+	bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
+	bt819_write(decoder, 0x09, timing->hscale & 0xff);
+	decoder->norm = std;
+	v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
+	return 0;
+}
 
-	case DECODER_SET_NORM:
-	{
-		int *iarg = arg;
-		struct timing *timing = NULL;
+static int bt819_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
+{
+	struct bt819 *decoder = to_bt819(sd);
 
-		v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
+	v4l2_dbg(1, debug, sd, "set input %x\n", input);
 
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			bt819_setbit(client, 0x01, 0, 1);
-			bt819_setbit(client, 0x01, 1, 0);
-			bt819_setbit(client, 0x01, 5, 0);
-			bt819_write(client, 0x18, 0x68);
-			bt819_write(client, 0x19, 0x5d);
-			/* bt819_setbit(client, 0x1a,  5, 1); */
-			timing = &timing_data[VIDEO_MODE_NTSC];
-			break;
-		case VIDEO_MODE_PAL:
-			bt819_setbit(client, 0x01, 0, 1);
-			bt819_setbit(client, 0x01, 1, 1);
-			bt819_setbit(client, 0x01, 5, 1);
-			bt819_write(client, 0x18, 0x7f);
-			bt819_write(client, 0x19, 0x72);
-			/* bt819_setbit(client, 0x1a,  5, 0); */
-			timing = &timing_data[VIDEO_MODE_PAL];
-			break;
-		case VIDEO_MODE_AUTO:
-			bt819_setbit(client, 0x01, 0, 0);
-			bt819_setbit(client, 0x01, 1, 0);
-			break;
-		default:
-			v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
-			return -EINVAL;
-		}
+	if (input < 0 || input > 7)
+		return -EINVAL;
 
-		if (timing) {
-			bt819_write(client, 0x03,
-				    (((timing->vdelay >> 8) & 0x03) << 6) |
-				    (((timing->vactive >> 8) & 0x03) << 4) |
-				    (((timing->hdelay >> 8) & 0x03) << 2) |
-				     ((timing->hactive >> 8) & 0x03) );
-			bt819_write(client, 0x04, timing->vdelay & 0xff);
-			bt819_write(client, 0x05, timing->vactive & 0xff);
-			bt819_write(client, 0x06, timing->hdelay & 0xff);
-			bt819_write(client, 0x07, timing->hactive & 0xff);
-			bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
-			bt819_write(client, 0x09, timing->hscale & 0xff);
-		}
+	if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+		v4l2_err(sd, "no notify found!\n");
 
-		decoder->norm = *iarg;
-		break;
+	if (decoder->input != input) {
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+		decoder->input = input;
+		/* select mode */
+		if (decoder->input == 0) {
+			bt819_setbit(decoder, 0x0b, 6, 0);
+			bt819_setbit(decoder, 0x1a, 1, 1);
+		} else {
+			bt819_setbit(decoder, 0x0b, 6, 1);
+			bt819_setbit(decoder, 0x1a, 1, 0);
+		}
+		v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
 	}
+	return 0;
+}
 
-	case DECODER_SET_INPUT:
-	{
-		int *iarg = arg;
+static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct bt819 *decoder = to_bt819(sd);
 
-		v4l_dbg(1, debug, client, "set input %x\n", *iarg);
+	v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
 
-		if (*iarg < 0 || *iarg > 7)
-			return -EINVAL;
+	if (decoder->enable != enable) {
+		decoder->enable = enable;
+		bt819_setbit(decoder, 0x16, 7, !enable);
+	}
+	return 0;
+}
 
-		if (decoder->input != *iarg) {
-			decoder->input = *iarg;
-			/* select mode */
-			if (decoder->input == 0) {
-				bt819_setbit(client, 0x0b, 6, 0);
-				bt819_setbit(client, 0x1a, 1, 1);
-			} else {
-				bt819_setbit(client, 0x0b, 6, 1);
-				bt819_setbit(client, 0x1a, 1, 0);
-			}
-		}
+static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
 		break;
-	}
 
-	case DECODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
+	case V4L2_CID_CONTRAST:
+		v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+		break;
 
-		v4l_dbg(1, debug, client, "set output %x\n", *iarg);
+	case V4L2_CID_SATURATION:
+		v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+		break;
 
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
+	case V4L2_CID_HUE:
+		v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
 		break;
-	}
 
-	case DECODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-		int enable = (*iarg != 0);
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
 
-		v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
+static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct bt819 *decoder = to_bt819(sd);
+	int temp;
 
-		if (decoder->enable != enable) {
-			decoder->enable = enable;
-			bt819_setbit(client, 0x16, 7, !enable);
-		}
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (decoder->bright == ctrl->value)
+			break;
+		decoder->bright = ctrl->value;
+		bt819_write(decoder, 0x0a, decoder->bright);
 		break;
-	}
 
-	case DECODER_SET_PICTURE:
-	{
-		struct video_picture *pic = arg;
-
-		v4l_dbg(1, debug, client,
-			"set picture brightness %d contrast %d colour %d\n",
-			pic->brightness, pic->contrast, pic->colour);
+	case V4L2_CID_CONTRAST:
+		if (decoder->contrast == ctrl->value)
+			break;
+		decoder->contrast = ctrl->value;
+		bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
+		bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
+		break;
 
+	case V4L2_CID_SATURATION:
+		if (decoder->sat == ctrl->value)
+			break;
+		decoder->sat = ctrl->value;
+		bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
+		bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
 
-		if (decoder->bright != pic->brightness) {
-			/* We want -128 to 127 we get 0-65535 */
-			decoder->bright = pic->brightness;
-			bt819_write(client, 0x0a,
-				    (decoder->bright >> 8) - 128);
-		}
+		/* Ratio between U gain and V gain must stay the same as
+		   the ratio between the default U and V gain values. */
+		temp = (decoder->sat * 180) / 254;
+		bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
+		bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
+		break;
 
-		if (decoder->contrast != pic->contrast) {
-			/* We want 0 to 511 we get 0-65535 */
-			decoder->contrast = pic->contrast;
-			bt819_write(client, 0x0c,
-				    (decoder->contrast >> 7) & 0xff);
-			bt819_setbit(client, 0x0b, 2,
-				     ((decoder->contrast >> 15) & 0x01));
-		}
+	case V4L2_CID_HUE:
+		if (decoder->hue == ctrl->value)
+			break;
+		decoder->hue = ctrl->value;
+		bt819_write(decoder, 0x0f, decoder->hue);
+		break;
 
-		if (decoder->sat != pic->colour) {
-			/* We want 0 to 511 we get 0-65535 */
-			decoder->sat = pic->colour;
-			bt819_write(client, 0x0d,
-				    (decoder->sat >> 7) & 0xff);
-			bt819_setbit(client, 0x0b, 1,
-				     ((decoder->sat >> 15) & 0x01));
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
 
-			temp = (decoder->sat * 201) / 237;
-			bt819_write(client, 0x0e, (temp >> 7) & 0xff);
-			bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
-		}
+static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct bt819 *decoder = to_bt819(sd);
 
-		if (decoder->hue != pic->hue) {
-			/* We want -128 to 127 we get 0-65535 */
-			decoder->hue = pic->hue;
-			bt819_write(client, 0x0f,
-				    128 - (decoder->hue >> 8));
-		}
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = decoder->bright;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = decoder->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = decoder->sat;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = decoder->hue;
 		break;
-	}
-
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
+static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct bt819 *decoder = to_bt819(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt819_core_ops = {
+	.g_chip_ident = bt819_g_chip_ident,
+	.g_ctrl = bt819_g_ctrl,
+	.s_ctrl = bt819_s_ctrl,
+	.queryctrl = bt819_queryctrl,
+	.s_std = bt819_s_std,
+};
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops bt819_video_ops = {
+	.s_routing = bt819_s_routing,
+	.s_stream = bt819_s_stream,
+	.querystd = bt819_querystd,
+	.g_input_status = bt819_g_input_status,
+};
+
+static const struct v4l2_subdev_ops bt819_ops = {
+	.core = &bt819_core_ops,
+	.video = &bt819_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int bt819_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	int i, ver;
 	struct bt819 *decoder;
+	struct v4l2_subdev *sd;
 	const char *name;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	ver = bt819_read(client, 0x17);
+	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+	if (decoder == NULL)
+		return -ENOMEM;
+	sd = &decoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &bt819_ops);
+
+	ver = bt819_read(decoder, 0x17);
 	switch (ver & 0xf0) {
 	case 0x70:
 		name = "bt819a";
+		decoder->ident = V4L2_IDENT_BT819A;
 		break;
 	case 0x60:
 		name = "bt817a";
+		decoder->ident = V4L2_IDENT_BT817A;
 		break;
 	case 0x20:
 		name = "bt815a";
+		decoder->ident = V4L2_IDENT_BT815A;
 		break;
 	default:
-		v4l_dbg(1, debug, client,
+		v4l2_dbg(1, debug, sd,
 			"unknown chip version 0x%02x\n", ver);
 		return -ENODEV;
 	}
@@ -459,28 +503,26 @@ static int bt819_probe(struct i2c_client
 	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
 			client->addr << 1, client->adapter->name);
 
-	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
-	if (decoder == NULL)
-		return -ENOMEM;
-	decoder->norm = VIDEO_MODE_NTSC;
+	decoder->norm = V4L2_STD_NTSC;
 	decoder->input = 0;
 	decoder->enable = 1;
-	decoder->bright = 32768;
-	decoder->contrast = 32768;
-	decoder->hue = 32768;
-	decoder->sat = 32768;
-	decoder->initialized = 0;
-	i2c_set_clientdata(client, decoder);
+	decoder->bright = 0;
+	decoder->contrast = 0xd8;	/* 100% of original signal */
+	decoder->hue = 0;
+	decoder->sat = 0xfe;		/* 100% of original signal */
 
-	i = bt819_init(client);
+	i = bt819_init(sd);
 	if (i < 0)
-		v4l_dbg(1, debug, client, "init status %d\n", i);
+		v4l2_dbg(1, debug, sd, "init status %d\n", i);
 	return 0;
 }
 
 static int bt819_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_bt819(sd));
 	return 0;
 }
 
@@ -496,8 +538,6 @@ MODULE_DEVICE_TABLE(i2c, bt819_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "bt819",
-	.driverid = I2C_DRIVERID_BT819,
-	.command = bt819_command,
 	.probe = bt819_probe,
 	.remove = bt819_remove,
 	.id_table = bt819_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt856.c linux-libre-2.6.30-gnu1/drivers/media/video/bt856.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt856.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt856.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,10 +34,10 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,43 +47,46 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+
 /* ----------------------------------------------------------------------- */
 
 #define BT856_REG_OFFSET	0xDA
 #define BT856_NR_REG		6
 
 struct bt856 {
+	struct v4l2_subdev sd;
 	unsigned char reg[BT856_NR_REG];
 
-	int norm;
-	int enable;
+	v4l2_std_id norm;
 };
 
+static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct bt856, sd);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value)
 {
-	struct bt856 *encoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
 
 	encoder->reg[reg - BT856_REG_OFFSET] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value)
 {
-	struct bt856 *encoder = i2c_get_clientdata(client);
-
-	return bt856_write(client, reg,
+	return bt856_write(encoder, reg,
 		(encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
 				(value ? (1 << bit) : 0));
 }
 
-static void bt856_dump(struct i2c_client *client)
+static void bt856_dump(struct bt856 *encoder)
 {
 	int i;
-	struct bt856 *encoder = i2c_get_clientdata(client);
 
-	v4l_info(client, "register dump:\n");
+	v4l2_info(&encoder->sd, "register dump:\n");
 	for (i = 0; i < BT856_NR_REG; i += 2)
 		printk(KERN_CONT " %02x", encoder->reg[i]);
 	printk(KERN_CONT "\n");
@@ -91,153 +94,121 @@ static void bt856_dump(struct i2c_client
 
 /* ----------------------------------------------------------------------- */
 
-static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt856_init(struct v4l2_subdev *sd, u32 arg)
 {
-	struct bt856 *encoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-		/* This is just for testing!!! */
-		v4l_dbg(1, debug, client, "init\n");
-		bt856_write(client, 0xdc, 0x18);
-		bt856_write(client, 0xda, 0);
-		bt856_write(client, 0xde, 0);
-
-		bt856_setbit(client, 0xdc, 3, 1);
-		//bt856_setbit(client, 0xdc, 6, 0);
-		bt856_setbit(client, 0xdc, 4, 1);
-
-		switch (encoder->norm) {
-		case VIDEO_MODE_NTSC:
-			bt856_setbit(client, 0xdc, 2, 0);
-			break;
-
-		case VIDEO_MODE_PAL:
-			bt856_setbit(client, 0xdc, 2, 1);
-			break;
-		}
-
-		bt856_setbit(client, 0xdc, 1, 1);
-		bt856_setbit(client, 0xde, 4, 0);
-		bt856_setbit(client, 0xde, 3, 1);
-		if (debug != 0)
-			bt856_dump(client);
-		break;
-
-	case ENCODER_GET_CAPABILITIES:
-	{
-		struct video_encoder_capability *cap = arg;
+	struct bt856 *encoder = to_bt856(sd);
 
-		v4l_dbg(1, debug, client, "get capabilities\n");
+	/* This is just for testing!!! */
+	v4l2_dbg(1, debug, sd, "init\n");
+	bt856_write(encoder, 0xdc, 0x18);
+	bt856_write(encoder, 0xda, 0);
+	bt856_write(encoder, 0xde, 0);
 
-		cap->flags = VIDEO_ENCODER_PAL |
-			     VIDEO_ENCODER_NTSC |
-			     VIDEO_ENCODER_CCIR;
-		cap->inputs = 2;
-		cap->outputs = 1;
-		break;
-	}
+	bt856_setbit(encoder, 0xdc, 3, 1);
+	/*bt856_setbit(encoder, 0xdc, 6, 0);*/
+	bt856_setbit(encoder, 0xdc, 4, 1);
 
-	case ENCODER_SET_NORM:
-	{
-		int *iarg = arg;
+	if (encoder->norm & V4L2_STD_NTSC)
+		bt856_setbit(encoder, 0xdc, 2, 0);
+	else
+		bt856_setbit(encoder, 0xdc, 2, 1);
 
-		v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
+	bt856_setbit(encoder, 0xdc, 1, 1);
+	bt856_setbit(encoder, 0xde, 4, 0);
+	bt856_setbit(encoder, 0xde, 3, 1);
+	if (debug != 0)
+		bt856_dump(encoder);
+	return 0;
+}
 
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			bt856_setbit(client, 0xdc, 2, 0);
-			break;
+static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct bt856 *encoder = to_bt856(sd);
 
-		case VIDEO_MODE_PAL:
-			bt856_setbit(client, 0xdc, 2, 1);
-			bt856_setbit(client, 0xda, 0, 0);
-			//bt856_setbit(client, 0xda, 0, 1);
-			break;
+	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
 
-		default:
-			return -EINVAL;
-		}
-		encoder->norm = *iarg;
-		if (debug != 0)
-			bt856_dump(client);
-		break;
+	if (std & V4L2_STD_NTSC) {
+		bt856_setbit(encoder, 0xdc, 2, 0);
+	} else if (std & V4L2_STD_PAL) {
+		bt856_setbit(encoder, 0xdc, 2, 1);
+		bt856_setbit(encoder, 0xda, 0, 0);
+		/*bt856_setbit(encoder, 0xda, 0, 1);*/
+	} else {
+		return -EINVAL;
 	}
+	encoder->norm = std;
+	if (debug != 0)
+		bt856_dump(encoder);
+	return 0;
+}
 
-	case ENCODER_SET_INPUT:
-	{
-		int *iarg = arg;
-
-		v4l_dbg(1, debug, client, "set input %d\n", *iarg);
+static int bt856_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
+{
+	struct bt856 *encoder = to_bt856(sd);
 
-		/* We only have video bus.
-		 * iarg = 0: input is from bt819
-		 * iarg = 1: input is from ZR36060 */
-		switch (*iarg) {
-		case 0:
-			bt856_setbit(client, 0xde, 4, 0);
-			bt856_setbit(client, 0xde, 3, 1);
-			bt856_setbit(client, 0xdc, 3, 1);
-			bt856_setbit(client, 0xdc, 6, 0);
-			break;
-		case 1:
-			bt856_setbit(client, 0xde, 4, 0);
-			bt856_setbit(client, 0xde, 3, 1);
-			bt856_setbit(client, 0xdc, 3, 1);
-			bt856_setbit(client, 0xdc, 6, 1);
-			break;
-		case 2:	// Color bar
-			bt856_setbit(client, 0xdc, 3, 0);
-			bt856_setbit(client, 0xde, 4, 1);
-			break;
-		default:
-			return -EINVAL;
-		}
+	v4l2_dbg(1, debug, sd, "set input %d\n", input);
 
-		if (debug != 0)
-			bt856_dump(client);
+	/* We only have video bus.
+	 * input= 0: input is from bt819
+	 * input= 1: input is from ZR36060 */
+	switch (input) {
+	case 0:
+		bt856_setbit(encoder, 0xde, 4, 0);
+		bt856_setbit(encoder, 0xde, 3, 1);
+		bt856_setbit(encoder, 0xdc, 3, 1);
+		bt856_setbit(encoder, 0xdc, 6, 0);
 		break;
-	}
-
-	case ENCODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
-
-		v4l_dbg(1, debug, client, "set output %d\n", *iarg);
-
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
+	case 1:
+		bt856_setbit(encoder, 0xde, 4, 0);
+		bt856_setbit(encoder, 0xde, 3, 1);
+		bt856_setbit(encoder, 0xdc, 3, 1);
+		bt856_setbit(encoder, 0xdc, 6, 1);
 		break;
-	}
-
-	case ENCODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-
-		encoder->enable = !!*iarg;
-
-		v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+	case 2:	/* Color bar */
+		bt856_setbit(encoder, 0xdc, 3, 0);
+		bt856_setbit(encoder, 0xde, 4, 1);
 		break;
-	}
-
 	default:
 		return -EINVAL;
 	}
 
+	if (debug != 0)
+		bt856_dump(encoder);
 	return 0;
 }
 
+static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt856_core_ops = {
+	.g_chip_ident = bt856_g_chip_ident,
+	.init = bt856_init,
+};
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops bt856_video_ops = {
+	.s_std_output = bt856_s_std_output,
+	.s_routing = bt856_s_routing,
+};
+
+static const struct v4l2_subdev_ops bt856_ops = {
+	.core = &bt856_core_ops,
+	.video = &bt856_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int bt856_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct bt856 *encoder;
+	struct v4l2_subdev *sd;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -249,41 +220,38 @@ static int bt856_probe(struct i2c_client
 	encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
-	encoder->norm = VIDEO_MODE_NTSC;
-	encoder->enable = 1;
-	i2c_set_clientdata(client, encoder);
-
-	bt856_write(client, 0xdc, 0x18);
-	bt856_write(client, 0xda, 0);
-	bt856_write(client, 0xde, 0);
-
-	bt856_setbit(client, 0xdc, 3, 1);
-	//bt856_setbit(client, 0xdc, 6, 0);
-	bt856_setbit(client, 0xdc, 4, 1);
+	sd = &encoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &bt856_ops);
+	encoder->norm = V4L2_STD_NTSC;
 
-	switch (encoder->norm) {
+	bt856_write(encoder, 0xdc, 0x18);
+	bt856_write(encoder, 0xda, 0);
+	bt856_write(encoder, 0xde, 0);
 
-	case VIDEO_MODE_NTSC:
-		bt856_setbit(client, 0xdc, 2, 0);
-		break;
+	bt856_setbit(encoder, 0xdc, 3, 1);
+	/*bt856_setbit(encoder, 0xdc, 6, 0);*/
+	bt856_setbit(encoder, 0xdc, 4, 1);
 
-	case VIDEO_MODE_PAL:
-		bt856_setbit(client, 0xdc, 2, 1);
-		break;
-	}
+	if (encoder->norm & V4L2_STD_NTSC)
+		bt856_setbit(encoder, 0xdc, 2, 0);
+	else
+		bt856_setbit(encoder, 0xdc, 2, 1);
 
-	bt856_setbit(client, 0xdc, 1, 1);
-	bt856_setbit(client, 0xde, 4, 0);
-	bt856_setbit(client, 0xde, 3, 1);
+	bt856_setbit(encoder, 0xdc, 1, 1);
+	bt856_setbit(encoder, 0xde, 4, 0);
+	bt856_setbit(encoder, 0xde, 3, 1);
 
 	if (debug != 0)
-		bt856_dump(client);
+		bt856_dump(encoder);
 	return 0;
 }
 
 static int bt856_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_bt856(sd));
 	return 0;
 }
 
@@ -295,8 +263,6 @@ MODULE_DEVICE_TABLE(i2c, bt856_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "bt856",
-	.driverid = I2C_DRIVERID_BT856,
-	.command = bt856_command,
 	.probe = bt856_probe,
 	.remove = bt856_remove,
 	.id_table = bt856_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt866.c linux-libre-2.6.30-gnu1/drivers/media/video/bt866.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt866.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt866.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,10 +34,10 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,22 +47,22 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+
 /* ----------------------------------------------------------------------- */
 
 struct bt866 {
+	struct v4l2_subdev sd;
 	u8 reg[256];
-
-	int norm;
-	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
 };
 
-static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
 {
-	struct bt866 *encoder = i2c_get_clientdata(client);
+	return container_of(sd, struct bt866, sd);
+}
+
+static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
 	u8 buffer[2];
 	int err;
 
@@ -89,163 +89,121 @@ static int bt866_write(struct i2c_client
 	return 0;
 }
 
-static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
 {
-	struct bt866 *encoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case ENCODER_GET_CAPABILITIES:
-	{
-		struct video_encoder_capability *cap = arg;
-
-		v4l_dbg(1, debug, client, "get capabilities\n");
-
-		cap->flags
-			= VIDEO_ENCODER_PAL
-			| VIDEO_ENCODER_NTSC
-			| VIDEO_ENCODER_CCIR;
-		cap->inputs = 2;
-		cap->outputs = 1;
-		break;
-	}
-
-	case ENCODER_SET_NORM:
-	{
-		int *iarg = arg;
-
-		v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
-
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			break;
-
-		case VIDEO_MODE_PAL:
-			break;
-
-		default:
-			return -EINVAL;
-		}
-		encoder->norm = *iarg;
-		break;
-	}
-
-	case ENCODER_SET_INPUT:
-	{
-		int *iarg = arg;
-		static const __u8 init[] = {
-			0xc8, 0xcc, /* CRSCALE */
-			0xca, 0x91, /* CBSCALE */
-			0xcc, 0x24, /* YC16 | OSDNUM */
-			0xda, 0x00, /*  */
-			0xdc, 0x24, /* SETMODE | PAL */
-			0xde, 0x02, /* EACTIVE */
-
-			/* overlay colors */
-			0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
-			0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
-			0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
-			0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
-			0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
-			0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
-			0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
-			0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
-
-			0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
-			0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
-			0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
-			0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
-			0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
-			0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
-			0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
-			0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
-		};
-		int i;
-		u8 val;
-
-		for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
-			bt866_write(client, init[i], init[i+1]);
+	v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
 
-		val = encoder->reg[0xdc];
+	/* Only PAL supported by this driver at the moment! */
+	if (!(std & V4L2_STD_NTSC))
+		return -EINVAL;
+	return 0;
+}
 
-		if (*iarg == 0)
-			val |= 0x40; /* CBSWAP */
-		else
-			val &= ~0x40; /* !CBSWAP */
+static int bt866_s_routing(struct v4l2_subdev *sd,
+			   u32 input, u32 output, u32 config)
+{
+	static const __u8 init[] = {
+		0xc8, 0xcc, /* CRSCALE */
+		0xca, 0x91, /* CBSCALE */
+		0xcc, 0x24, /* YC16 | OSDNUM */
+		0xda, 0x00, /*  */
+		0xdc, 0x24, /* SETMODE | PAL */
+		0xde, 0x02, /* EACTIVE */
 
-		bt866_write(client, 0xdc, val);
+		/* overlay colors */
+		0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
+		0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
+		0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
+		0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
+		0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
+		0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
+		0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
+		0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
 
-		val = encoder->reg[0xcc];
-		if (*iarg == 2)
-			val |= 0x01; /* OSDBAR */
-		else
-			val &= ~0x01; /* !OSDBAR */
-		bt866_write(client, 0xcc, val);
+		0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
+		0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
+		0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
+		0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
+		0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
+		0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
+		0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
+		0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
+	};
+	struct bt866 *encoder = to_bt866(sd);
+	u8 val;
+	int i;
 
-		v4l_dbg(1, debug, client, "set input %d\n", *iarg);
+	for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
+		bt866_write(encoder, init[i], init[i+1]);
 
-		switch (*iarg) {
-		case 0:
-			break;
-		case 1:
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
+	val = encoder->reg[0xdc];
 
-	case ENCODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
+	if (input == 0)
+		val |= 0x40; /* CBSWAP */
+	else
+		val &= ~0x40; /* !CBSWAP */
 
-		v4l_dbg(1, debug, client, "set output %d\n", *iarg);
+	bt866_write(encoder, 0xdc, val);
 
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
-		break;
-	}
+	val = encoder->reg[0xcc];
+	if (input == 2)
+		val |= 0x01; /* OSDBAR */
+	else
+		val &= ~0x01; /* !OSDBAR */
+	bt866_write(encoder, 0xcc, val);
 
-	case ENCODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-		encoder->enable = !!*iarg;
+	v4l2_dbg(1, debug, sd, "set input %d\n", input);
 
-		v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+	switch (input) {
+	case 0:
+	case 1:
+	case 2:
 		break;
+	default:
+		return -EINVAL;
 	}
+	return 0;
+}
 
-	case 4711:
-	{
-		int *iarg = arg;
-		__u8 val;
+#if 0
+/* Code to setup square pixels, might be of some use in the future,
+   but is currently unused. */
+	val = encoder->reg[0xdc];
+	if (*iarg)
+		val |= 1; /* SQUARE */
+	else
+		val &= ~1; /* !SQUARE */
+	bt866_write(client, 0xdc, val);
+#endif
 
-		v4l_dbg(1, debug, client, "square %d\n", *iarg);
+static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-		val = encoder->reg[0xdc];
-		if (*iarg)
-			val |= 1; /* SQUARE */
-		else
-			val &= ~1; /* !SQUARE */
-		bt866_write(client, 0xdc, val);
-		break;
-	}
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
+}
 
-	default:
-		return -EINVAL;
-	}
+/* ----------------------------------------------------------------------- */
 
-	return 0;
-}
+static const struct v4l2_subdev_core_ops bt866_core_ops = {
+	.g_chip_ident = bt866_g_chip_ident,
+};
 
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_video_ops bt866_video_ops = {
+	.s_std_output = bt866_s_std_output,
+	.s_routing = bt866_s_routing,
+};
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops bt866_ops = {
+	.core = &bt866_core_ops,
+	.video = &bt866_video_ops,
+};
 
 static int bt866_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct bt866 *encoder;
+	struct v4l2_subdev *sd;
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
@@ -253,20 +211,18 @@ static int bt866_probe(struct i2c_client
 	encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
-
-	i2c_set_clientdata(client, encoder);
+	sd = &encoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &bt866_ops);
 	return 0;
 }
 
 static int bt866_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-static int bt866_legacy_probe(struct i2c_adapter *adapter)
-{
-	return adapter->id == I2C_HW_B_ZR36067;
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_bt866(sd));
+	return 0;
 }
 
 static const struct i2c_device_id bt866_id[] = {
@@ -277,10 +233,7 @@ MODULE_DEVICE_TABLE(i2c, bt866_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "bt866",
-	.driverid = I2C_DRIVERID_BT866,
-	.command = bt866_command,
 	.probe = bt866_probe,
 	.remove = bt866_remove,
-	.legacy_probe = bt866_legacy_probe,
 	.id_table = bt866_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-cards.c	2013-05-03 18:01:44.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-cards.c	2013-05-03 16:45:34.000000000 -0400
@@ -73,6 +73,11 @@ static void sigmaSQ_muxsel(struct bttv *
 
 static void geovision_muxsel(struct bttv *btv, unsigned int input);
 
+static void phytec_muxsel(struct bttv *btv, unsigned int input);
+
+static void gv800s_muxsel(struct bttv *btv, unsigned int input);
+static void gv800s_init(struct bttv *btv);
+
 static int terratec_active_radio_upgrade(struct bttv *btv);
 static int tea5757_read(struct bttv *btv);
 static int tea5757_write(struct bttv *btv, int value);
@@ -91,12 +96,10 @@ static unsigned int pll[BTTV_MAX]    = {
 static unsigned int tuner[BTTV_MAX]  = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int svhs[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
+static unsigned int audiodev[BTTV_MAX];
+static unsigned int saa6588[BTTV_MAX];
 static struct bttv  *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload;
-#endif
+static unsigned int autoload = UNSET;
 static unsigned int gpiomask = UNSET;
 static unsigned int audioall = UNSET;
 static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
@@ -115,6 +118,7 @@ module_param_array(pll,      int, NULL,
 module_param_array(tuner,    int, NULL, 0444);
 module_param_array(svhs,     int, NULL, 0444);
 module_param_array(remote,   int, NULL, 0444);
+module_param_array(audiodev, int, NULL, 0444);
 module_param_array(audiomux, int, NULL, 0444);
 
 MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
@@ -125,7 +129,14 @@ MODULE_PARM_DESC(latency,"pci latency ti
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
 MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
-MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
+MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
+MODULE_PARM_DESC(audiodev, "specify audio device:\n"
+		"\t\t-1 = no audio\n"
+		"\t\t 0 = autodetect (default)\n"
+		"\t\t 1 = msp3400\n"
+		"\t\t 2 = tda7432\n"
+		"\t\t 3 = tvaudio");
+MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
 MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
 		" [some VIA/SIS chipsets are known to have problem with overlay]");
 
@@ -246,6 +257,10 @@ static struct CARD {
 	{ 0xa182ff0d, BTTV_BOARD_IVC120,        "IVC-120G" },
 	{ 0xa182ff0e, BTTV_BOARD_IVC120,        "IVC-120G" },
 	{ 0xa182ff0f, BTTV_BOARD_IVC120,        "IVC-120G" },
+	{ 0xf0500000, BTTV_BOARD_IVCE8784,      "IVCE-8784" },
+	{ 0xf0500001, BTTV_BOARD_IVCE8784,      "IVCE-8784" },
+	{ 0xf0500002, BTTV_BOARD_IVCE8784,      "IVCE-8784" },
+	{ 0xf0500003, BTTV_BOARD_IVCE8784,      "IVCE-8784" },
 
 	{ 0x41424344, BTTV_BOARD_GRANDTEC,      "GrandTec Multi Capture" },
 	{ 0x01020304, BTTV_BOARD_XGUARD,        "Grandtec Grand X-Guard" },
@@ -289,6 +304,8 @@ static struct CARD {
 	/* Duplicate PCI ID, reconfigure for this board during the eeprom read.
 	* { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB,  "Hauppauge ImpactVCB" }, */
 
+	{ 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2,	"Conceptronic CTVFMi v2"},
+
 	/* DVB cards (using pci function .1 for mpeg data xfer) */
 	{ 0x001c11bd, BTTV_BOARD_PINNACLESAT,   "Pinnacle PCTV Sat" },
 	{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
@@ -305,6 +322,20 @@ static struct CARD {
 	{ 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2,	"DViCO FusionHDTV 2" },
 	{ 0x763c008a, BTTV_BOARD_GEOVISION_GV600,	"GeoVision GV-600" },
 	{ 0x18011000, BTTV_BOARD_ENLTV_FM_2,	"Encore ENL TV-FM-2" },
+	{ 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" },
+	{ 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL,	"GeoVision GV-800(S) (slave)" },
+	{ 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL,	"GeoVision GV-800(S) (slave)" },
+	{ 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL,	"GeoVision GV-800(S) (slave)" },
+
+	{ 0x15401830, BTTV_BOARD_PV183,         "Provideo PV183-1" },
+	{ 0x15401831, BTTV_BOARD_PV183,         "Provideo PV183-2" },
+	{ 0x15401832, BTTV_BOARD_PV183,         "Provideo PV183-3" },
+	{ 0x15401833, BTTV_BOARD_PV183,         "Provideo PV183-4" },
+	{ 0x15401834, BTTV_BOARD_PV183,         "Provideo PV183-5" },
+	{ 0x15401835, BTTV_BOARD_PV183,         "Provideo PV183-6" },
+	{ 0x15401836, BTTV_BOARD_PV183,         "Provideo PV183-7" },
+	{ 0x15401837, BTTV_BOARD_PV183,         "Provideo PV183-8" },
+
 	{ 0, -1, NULL }
 };
 
@@ -316,59 +347,50 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_UNKNOWN] = {
 		.name		= " *** UNKNOWN/GENERIC *** ",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
 		.svhs		= 2,
-		.muxsel		= { 2, 3, 1, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MIRO] = {
 		.name		= "MIRO PCTV",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 2, 0, 0, 0 },
 		.gpiomute 	= 10,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_HAUPPAUGE] = {
 		.name		= "Hauppauge (bt848)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_STB] = {
 		.name		= "STB, Gateway P/N 6000699 (bt848)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 4, 0, 2, 3 },
 		.gpiomute 	= 1,
 		.no_msp34xx	= 1,
 		.needs_tvaudio	= 1,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 		.has_radio      = 1,
 	},
@@ -377,202 +399,177 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_INTEL] = {
 		.name		= "Intel Create and Share PCI/ Smart Video Recorder III",
 		.video_inputs	= 4,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
+		/* .audio_inputs= 0, */
 		.svhs		= 2,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0 },
 		.needs_tvaudio	= 0,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_DIAMOND] = {
 		.name		= "Diamond DTV2000",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 3,
-		.muxsel		= { 2, 3, 1, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.gpiomux 	= { 0, 1, 0, 1 },
 		.gpiomute 	= 3,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_AVERMEDIA] = {
 		.name		= "AVerMedia TVPhone",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomask	= 0x0f,
 		.gpiomux 	= { 0x0c, 0x04, 0x08, 0x04 },
 		/*                0x04 for some cards ?? */
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= avermedia_tvphone_audio,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_MATRIX_VISION] = {
 		.name		= "MATRIX-Vision MV-Delta",
 		.video_inputs	= 5,
-		.audio_inputs	= 1,
-		.tuner		= UNSET,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 0, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
 		.gpiomux 	= { 0 },
 		.needs_tvaudio	= 1,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x08 ---------------------------------- */
 	[BTTV_BOARD_FLYVIDEO] = {
 		.name		= "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xc00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0xc00, 0x800, 0x400 },
 		.gpiomute 	= 0xc00,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TURBOTV] = {
 		.name		= "IMS/IXmicro TurboTV",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 3,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 1, 1, 2, 3 },
 		.needs_tvaudio	= 0,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_HAUPPAUGE878] = {
 		.name		= "Hauppauge (bt878)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x0f, /* old: 7 */
-		.muxsel		= { 2, 0, 1, 1 },
+		.muxsel		= MUXSEL(2, 0, 1, 1),
 		.gpiomux 	= { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MIROPRO] = {
 		.name		= "MIRO PCTV pro",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x3014f,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x20001,0x10001, 0, 0 },
 		.gpiomute 	= 10,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x0c ---------------------------------- */
 	[BTTV_BOARD_ADSTECH_TV] = {
 		.name		= "ADS Technologies Channel Surfer TV (bt848)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 13, 14, 11, 7 },
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_AVERMEDIA98] = {
 		.name		= "AVerMedia TVCapture 98",
 		.video_inputs	= 3,
-		.audio_inputs	= 4,
-		.tuner		= 0,
+		/* .audio_inputs= 4, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 13, 14, 11, 7 },
 		.needs_tvaudio	= 1,
 		.msp34xx_alt    = 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= avermedia_tv_stereo_audio,
 		.no_gpioirq     = 1,
 	},
 	[BTTV_BOARD_VHX] = {
 		.name		= "Aimslab Video Highway Xtreme (VHX)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
 		.gpiomute 	= 4,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ZOLTRIX] = {
 		.name		= "Zoltrix TV-Max",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0, 1, 0 },
 		.gpiomute 	= 10,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x10 ---------------------------------- */
 	[BTTV_BOARD_PIXVIEWPLAYTV] = {
 		.name		= "Prolink Pixelview PlayTV (bt878)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x01fe00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
 		.gpiomux        = { 0x001e00, 0, 0x018000, 0x014000 },
 		.gpiomute 	= 0x002000,
@@ -580,194 +577,170 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_WINVIEW_601] = {
 		.name		= "Leadtek WinView 601",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x8300f8,
-		.muxsel		= { 2, 3, 1, 1,0 },
+		.muxsel		= MUXSEL(2, 3, 1, 1, 0),
 		.gpiomux 	= { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
 		.gpiomute 	= 0xcfa007,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.volume_gpio	= winview_volume,
 		.has_radio	= 1,
 	},
 	[BTTV_BOARD_AVEC_INTERCAP] = {
 		.name		= "AVEC Intercapture",
 		.video_inputs	= 3,
-		.audio_inputs	= 2,
-		.tuner		= 0,
+		/* .audio_inputs= 2, */
 		.svhs		= 2,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 1, 0, 0, 0 },
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_LIFE_FLYKIT] = {
 		.name		= "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= UNSET,
-		.svhs		= UNSET,
+		/* .audio_inputs= 1, */
+		.svhs		= NO_SVHS,
 		.gpiomask	= 0x8dff00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0 },
 		.no_msp34xx	= 1,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x14 ---------------------------------- */
 	[BTTV_BOARD_CEI_RAFFLES] = {
 		.name		= "CEI Raffles Card",
 		.video_inputs	= 3,
-		.audio_inputs	= 3,
-		.tuner		= 0,
+		/* .audio_inputs= 3, */
 		.svhs		= 2,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_CONFERENCETV] = {
 		.name		= "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
 		.video_inputs	= 4,
-		.audio_inputs	= 2,  /* tuner, line in */
-		.tuner		= 0,
+		/* .audio_inputs= 2,  tuner, line in */
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_PHOEBE_TVMAS] = {
 		.name		= "Askey CPH050/ Phoebe Tv Master + FM",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xc00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 1, 0x800, 0x400 },
 		.gpiomute 	= 0xc00,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MODTEC_205] = {
 		.name		= "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
-		.svhs		= UNSET,
+		/* .audio_inputs= 1, */
+		.svhs		= NO_SVHS,
+		.has_dig_in	= 1,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 3, -1 },
-		.digital_mode   = DIGITAL_MODE_CAMERA,
+		.muxsel		= MUXSEL(2, 3, 0), /* input 2 is digital */
+		/* .digital_mode= DIGITAL_MODE_CAMERA, */
 		.gpiomux 	= { 0, 0, 0, 0 },
 		.no_msp34xx	= 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_ALPS_TSBB5_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x18 ---------------------------------- */
 	[BTTV_BOARD_MAGICTVIEW061] = {
 		.name		= "Askey CPH05X/06X (bt878) [many vendors]",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xe00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= {0x400, 0x400, 0x400, 0x400 },
 		.gpiomute 	= 0xc00,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_VOBIS_BOOSTAR] = {
 		.name           = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask       = 0x1f0fff,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x20000, 0x30000, 0x10000, 0 },
 		.gpiomute 	= 0x40000,
 		.needs_tvaudio	= 0,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= terratv_audio,
 	},
 	[BTTV_BOARD_HAUPPAUG_WCAM] = {
 		.name		= "Hauppauge WinCam newer (bt878)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 0, 1, 1 },
+		.muxsel		= MUXSEL(2, 0, 1, 1),
 		.gpiomux 	= { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.needs_tvaudio	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MAXI] = {
 		.name		= "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
 		.video_inputs	= 4,
-		.audio_inputs	= 2,
-		.tuner		= 0,
+		/* .audio_inputs= 2, */
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_PHILIPS_SECAM,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x1c ---------------------------------- */
 	[BTTV_BOARD_TERRATV] = {
 		.name           = "Terratec TerraTV+ Version 1.1 (bt878)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x1f0fff,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x20000, 0x30000, 0x10000, 0x00000 },
 		.gpiomute 	= 0x40000,
 		.needs_tvaudio	= 0,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= terratv_audio,
 		/* GPIO wiring:
 		External 20 pin connector (for Active Radio Upgrade board)
@@ -805,87 +778,77 @@ struct tvcard bttv_tvcards[] = {
 		/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
 		.name		= "Imagenation PXC200",
 		.video_inputs	= 5,
-		.audio_inputs	= 1,
-		.tuner		= UNSET,
+		/* .audio_inputs= 1, */
 		.svhs		= 1, /* was: 4 */
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 0, 0},
+		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
 		.gpiomux 	= { 0 },
 		.needs_tvaudio	= 1,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.muxsel_hook    = PXC200_muxsel,
 
 	},
 	[BTTV_BOARD_FLYVIDEO_98] = {
 		.name		= "Lifeview FlyVideo 98 LR50",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x1800,  /* 0x8dfe00 */
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0x0800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_IPROTV] = {
 		.name		= "Formac iProTV, Formac ProTV I (bt848)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
 		.gpiomask	= 1,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 1, 0, 0, 0 },
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x20 ---------------------------------- */
 	[BTTV_BOARD_INTEL_C_S_PCI] = {
 		.name		= "Intel Create and Share PCI/ Smart Video Recorder III",
 		.video_inputs	= 4,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
+		/* .audio_inputs= 0, */
 		.svhs		= 2,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0 },
 		.needs_tvaudio	= 0,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TERRATVALUE] = {
 		.name           = "Terratec TerraTValue Version Bt878",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xffff00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x500, 0, 0x300, 0x900 },
 		.gpiomute 	= 0x900,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_WINFAST2000] = {
 		.name		= "Leadtek WinFast 2000/ WinFast 2000 XP",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
-		.muxsel		= { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */
+		/* TV, CVid, SVid, CVid over SVid connector */
+		.muxsel		= MUXSEL(2, 3, 1, 1, 0),
 		/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
 		.gpiomask	= 0xb33000,
 		.gpiomux 	= { 0x122000,0x1000,0x0000,0x620000 },
@@ -906,217 +869,191 @@ struct tvcard bttv_tvcards[] = {
 		.has_radio	= 1,
 		.tuner_type	= TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= winfast2000_audio,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_CHRONOS_VS2] = {
 		.name		= "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
 		.video_inputs	= 4,
-		.audio_inputs	= 3,
-		.tuner		= 0,
+		/* .audio_inputs= 3, */
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x24 ---------------------------------- */
 	[BTTV_BOARD_TYPHOON_TVIEW] = {
 		.name		= "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
 		.video_inputs	= 4,
-		.audio_inputs	= 3,
-		.tuner		= 0,
+		/* .audio_inputs= 3, */
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio	= 1,
 	},
 	[BTTV_BOARD_PXELVWPLTVPRO] = {
 		.name		= "Prolink PixelView PlayTV pro",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xff,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x21, 0x20, 0x24, 0x2c },
 		.gpiomute 	= 0x29,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MAGICTVIEW063] = {
 		.name		= "Askey CPH06X TView99",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x551e00,
-		.muxsel		= { 2, 3, 1, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.gpiomux 	= { 0x551400, 0x551200, 0, 0 },
 		.gpiomute 	= 0x551c00,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_PINNACLE] = {
 		.name		= "Pinnacle PCTV Studio/Rave",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x03000F,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 2, 0xd0001, 0, 0 },
 		.gpiomute 	= 1,
 		.needs_tvaudio	= 0,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x28 ---------------------------------- */
 	[BTTV_BOARD_STB2] = {
 		.name		= "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 7,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 4, 0, 2, 3 },
 		.gpiomute 	= 1,
 		.no_msp34xx	= 1,
 		.needs_tvaudio	= 1,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 		.has_radio      = 1,
 	},
 	[BTTV_BOARD_AVPHONE98] = {
 		.name		= "AVerMedia TVPhone 98",
 		.video_inputs	= 3,
-		.audio_inputs	= 4,
-		.tuner		= 0,
+		/* .audio_inputs= 4, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 13, 4, 11, 7 },
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio	= 1,
 		.audio_mode_gpio= avermedia_tvphone_audio,
 	},
 	[BTTV_BOARD_PV951] = {
 		.name		= "ProVideo PV951", /* pic16c54 */
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 1},
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0, 0, 0},
 		.needs_tvaudio	= 1,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ONAIR_TV] = {
 		.name		= "Little OnAir TV",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xe00b,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
 		.gpiomute 	= 0xff3ffc,
 		.no_msp34xx	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x2c ---------------------------------- */
 	[BTTV_BOARD_SIGMA_TVII_FM] = {
 		.name		= "Sigma TVII-FM",
 		.video_inputs	= 2,
-		.audio_inputs	= 1,
-		.tuner		= 0,
-		.svhs		= UNSET,
+		/* .audio_inputs= 1, */
+		.svhs		= NO_SVHS,
 		.gpiomask	= 3,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 1, 1, 0, 2 },
 		.gpiomute 	= 3,
 		.no_msp34xx	= 1,
 		.pll		= PLL_NONE,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MATRIX_VISION2] = {
 		.name		= "MATRIX-Vision MV-Delta 2",
 		.video_inputs	= 5,
-		.audio_inputs	= 1,
-		.tuner		= UNSET,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
 		.gpiomask	= 0,
-		.muxsel		= { 2, 3, 1, 0, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
 		.gpiomux 	= { 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ZOLTRIX_GENIE] = {
 		.name		= "Zoltrix Genie TV/FM",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xbcf03f,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
 		.gpiomute 	= 0xbcb03f,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4039FR5_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TERRATVRADIO] = {
 		.name		= "Terratec TV/Radio+",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x70000,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x20000, 0x30000, 0x10000, 0 },
 		.gpiomute 	= 0x40000,
 		.needs_tvaudio	= 1,
@@ -1124,7 +1061,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_35,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio	= 1,
 	},
 
@@ -1132,51 +1068,46 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_DYNALINK] = {
 		.name		= "Askey CPH03x/ Dynalink Magic TView",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= {2,0,0,0 },
 		.gpiomute 	= 1,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_GVBCTV3PCI] = {
 		.name		= "IODATA GV-BCTV3/PCI",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x010f00,
-		.muxsel		= {2, 3, 0, 0 },
+		.muxsel		= MUXSEL(2, 3, 0, 0),
 		.gpiomux 	= {0x10000, 0, 0x10000, 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_ALPS_TSHC6_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= gvbctv3pci_audio,
 	},
 	[BTTV_BOARD_PXELVWPLTVPAK] = {
 		.name		= "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
 		.video_inputs	= 5,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 3,
+		.has_dig_in	= 1,
 		.gpiomask	= 0xAA0000,
-		.muxsel		= { 2,3,1,1,-1 },
-		.digital_mode   = DIGITAL_MODE_CAMERA,
+		.muxsel		= MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+		/* .digital_mode= DIGITAL_MODE_CAMERA, */
 		.gpiomux 	= { 0x20000, 0, 0x80000, 0x80000 },
 		.gpiomute 	= 0xa8000,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote	= 1,
 		/* GPIO wiring: (different from Rev.4C !)
 			GPIO17: U4.A0 (first hef4052bt)
@@ -1191,17 +1122,15 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_EAGLE] = {
 		.name           = "Eagle Wireless Capricorn2 (bt878A)",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 7,
-		.muxsel         = { 2, 0, 1, 1 },
+		.muxsel         = MUXSEL(2, 0, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.pll            = PLL_28,
 		.tuner_type     = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x34 ---------------------------------- */
@@ -1209,11 +1138,10 @@ struct tvcard bttv_tvcards[] = {
 		/* David HÃ¤rdeman <david@2gen.com> */
 		.name           = "Pinnacle PCTV Studio Pro",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 3,
 		.gpiomask       = 0x03000F,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 1, 0xd0001, 0, 0 },
 		.gpiomute 	= 10,
 				/* sound path (5 sources):
@@ -1229,25 +1157,22 @@ struct tvcard bttv_tvcards[] = {
 		.pll            = PLL_28,
 		.tuner_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TVIEW_RDS_FM] = {
 		/* Claas Langbehn <claas@bigfoot.com>,
 		Sven Grothklags <sven@upb.de> */
 		.name		= "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
 		.video_inputs	= 4,
-		.audio_inputs	= 3,
-		.tuner		= 0,
+		/* .audio_inputs= 3, */
 		.svhs		= 2,
 		.gpiomask	= 0x1c,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0, 0, 0x10, 8 },
 		.gpiomute 	= 4,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio	= 1,
 	},
 	[BTTV_BOARD_LIFETEC_9415] = {
@@ -1258,11 +1183,10 @@ struct tvcard bttv_tvcards[] = {
 			options tuner type=5 */
 		.name		= "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x18e0,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x0000,0x0800,0x1000,0x1000 },
 		.gpiomute 	= 0x18e0,
 			/* For cards with tda9820/tda9821:
@@ -1272,25 +1196,22 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_BESTBUY_EASYTV] = {
 		/* Miguel Angel Alvarez <maacruz@navegalia.com>
 		old Easy TV BT848 version (model CPH031) */
 		.name           = "Askey CPH031/ BESTBUY Easy TV",
 		.video_inputs	= 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0xF,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 2, 0, 0, 0 },
 		.gpiomute 	= 10,
 		.needs_tvaudio  = 0,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x38 ---------------------------------- */
@@ -1298,17 +1219,15 @@ struct tvcard bttv_tvcards[] = {
 		/* Gordon Heydon <gjheydon@bigfoot.com ('98) */
 		.name           = "Lifeview FlyVideo 98FM LR50",
 		.video_inputs   = 4,
-		.audio_inputs   = 3,
-		.tuner          = 0,
+		/* .audio_inputs= 3, */
 		.svhs           = 2,
 		.gpiomask       = 0x1800,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0x800, 0x1000, 0x1000 },
 		.gpiomute 	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 		/* This is the ultimate cheapo capture card
 		* just a BT848A on a small PCB!
@@ -1316,51 +1235,45 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_GRANDTEC] = {
 		.name           = "GrandTec 'Grand Video Capture' (Bt848)",
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 1,
 		.gpiomask       = 0,
-		.muxsel         = { 3, 1 },
+		.muxsel         = MUXSEL(3, 1),
 		.gpiomux        = { 0 },
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.pll            = PLL_35,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ASKEY_CPH060] = {
 		/* Daniel Herrington <daniel.herrington@home.com> */
 		.name           = "Askey CPH060/ Phoebe TV Master Only (No FM)",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0xe00,
-		.muxsel         = { 2, 3, 1, 1},
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x400, 0x400, 0x400, 0x400 },
 		.gpiomute 	= 0x800,
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_TEMIC_4036FY5_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ASKEY_CPH03X] = {
 		/* Matti Mottus <mottus@physic.ut.ee> */
 		.name		= "Askey CPH03x TV Capturer",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask       = 0x03000F,
-		.muxsel		= { 2, 3, 1, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 2, 0, 0, 0 },
 		.gpiomute 	= 1,
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x3c ---------------------------------- */
@@ -1368,34 +1281,30 @@ struct tvcard bttv_tvcards[] = {
 		/* Philip Blundell <philb@gnu.org> */
 		.name           = "Modular Technology MM100PCTV",
 		.video_inputs   = 2,
-		.audio_inputs   = 2,
-		.tuner		= 0,
-		.svhs		= UNSET,
+		/* .audio_inputs= 2, */
+		.svhs		= NO_SVHS,
 		.gpiomask       = 11,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 2, 0, 0, 1 },
 		.gpiomute 	= 8,
 		.pll            = PLL_35,
 		.tuner_type     = TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_GMV1] = {
 		/* Adrian Cox <adrian@humboldt.co.uk */
 		.name		= "AG Electronics GMV1",
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
-		.tuner		= UNSET,
+		/* .audio_inputs= 0, */
 		.svhs		= 1,
 		.gpiomask       = 0xF,
-		.muxsel		= { 2, 2 },
+		.muxsel		= MUXSEL(2, 2),
 		.gpiomux        = { },
 		.no_msp34xx     = 1,
 		.needs_tvaudio  = 0,
 		.pll		= PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_BESTBUY_EASYTV2] = {
 		/* Miguel Angel Alvarez <maacruz@navegalia.com>
@@ -1403,34 +1312,30 @@ struct tvcard bttv_tvcards[] = {
 		special thanks to Informatica Mieres for providing the card */
 		.name           = "Askey CPH061/ BESTBUY Easy TV (bt878)",
 		.video_inputs	= 3,
-		.audio_inputs   = 2,
-		.tuner          = 0,
+		/* .audio_inputs= 2, */
 		.svhs           = 2,
 		.gpiomask       = 0xFF,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 1, 0, 4, 4 },
 		.gpiomute 	= 9,
 		.needs_tvaudio  = 0,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_ATI_TVWONDER] = {
 		/* Lukas Gebauer <geby@volny.cz> */
 		.name		= "ATI TV-Wonder",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xf03f,
-		.muxsel		= { 2, 3, 1, 0 },
+		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.gpiomux 	= { 0xbffe, 0, 0xbfff, 0 },
 		.gpiomute 	= 0xbffe,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x40 ---------------------------------- */
@@ -1438,27 +1343,24 @@ struct tvcard bttv_tvcards[] = {
 		/* Lukas Gebauer <geby@volny.cz> */
 		.name		= "ATI TV-Wonder VE",
 		.video_inputs	= 2,
-		.audio_inputs	= 1,
-		.tuner		= 0,
-		.svhs		= UNSET,
+		/* .audio_inputs= 1, */
+		.svhs		= NO_SVHS,
 		.gpiomask	= 1,
-		.muxsel		= { 2, 3, 0, 1 },
+		.muxsel		= MUXSEL(2, 3, 0, 1),
 		.gpiomux 	= { 0, 0, 1, 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_FLYVIDEO2000] = {
 		/* DeeJay <deejay@westel900.net (2000S) */
 		.name           = "Lifeview FlyVideo 2000S LR90",
 		.video_inputs   = 3,
-		.audio_inputs   = 3,
-		.tuner          = 0,
+		/* .audio_inputs= 3, */
 		.svhs           = 2,
 		.gpiomask	= 0x18e0,
-		.muxsel		= { 2, 3, 0, 1 },
+		.muxsel		= MUXSEL(2, 3, 0, 1),
 				/* Radio changed from 1e80 to 0x800 to make
 				FlyVideo2000S in .hu happy (gm)*/
 				/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
@@ -1471,40 +1373,35 @@ struct tvcard bttv_tvcards[] = {
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TERRATVALUER] = {
 		.name		= "Terratec TValueRadio",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0xffff00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x500, 0x500, 0x300, 0x900 },
 		.gpiomute 	= 0x900,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio	= 1,
 	},
 	[BTTV_BOARD_GVBCTV4PCI] = {
 		/* TANAKA Kei <peg00625@nifty.com> */
 		.name           = "IODATA GV-BCTV4/PCI",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x010f00,
-		.muxsel         = {2, 3, 0, 0 },
+		.muxsel         = MUXSEL(2, 3, 0, 0),
 		.gpiomux        = {0x10000, 0, 0x10000, 0 },
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_SHARP_2U5JF5540_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= gvbctv3pci_audio,
 	},
 
@@ -1514,9 +1411,8 @@ struct tvcard bttv_tvcards[] = {
 		/* try "insmod msp3400 simple=0" if you have
 		* sound problems with this card. */
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
-		.svhs           = UNSET,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0x4f8a00,
 		/* 0x100000: 1=MSP enabled (0=disable again)
 		* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1524,10 +1420,9 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomute 	= 0x947fff,
 		/* tvtuner, radio,   external,internal, mute,  stereo
 		* tuner, Composit, SVid, Composit-on-Svid-adapter */
-		.muxsel         = { 2, 3 ,0 ,1 },
+		.muxsel         = MUXSEL(2, 3, 0, 1),
 		.tuner_type     = TUNER_MT2032,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll		= PLL_28,
 		.has_radio	= 1,
 	},
@@ -1536,9 +1431,8 @@ struct tvcard bttv_tvcards[] = {
 		/* try "insmod msp3400 simple=0" if you have
 		* sound problems with this card. */
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
-		.svhs           = UNSET,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0x4f8a00,
 		/* 0x100000: 1=MSP enabled (0=disable again)
 		* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1546,10 +1440,9 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomute 	= 0x947fff,
 		/* tvtuner, radio,   external,internal, mute,  stereo
 		* tuner, Composit, SVid, Composit-on-Svid-adapter */
-		.muxsel         = { 2, 3 ,0 ,1 },
+		.muxsel         = MUXSEL(2, 3, 0, 1),
 		.tuner_type     = TUNER_MT2032,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll		= PLL_28,
 		.has_radio	= 1,
 	},
@@ -1557,31 +1450,27 @@ struct tvcard bttv_tvcards[] = {
 		/* Philip Blundell <pb@nexus.co.uk> */
 		.name           = "Active Imaging AIMMS",
 		.video_inputs   = 1,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
-		.muxsel         = { 2 },
+		.muxsel         = MUXSEL(2),
 		.gpiomask       = 0
 	},
 	[BTTV_BOARD_PV_BT878P_PLUS] = {
 		/* Tomasz Pyra <hellfire@sedez.iq.pl> */
 		.name           = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
 		.video_inputs   = 3,
-		.audio_inputs   = 4,
-		.tuner          = 0,
+		/* .audio_inputs= 4, */
 		.svhs           = 2,
 		.gpiomask       = 15,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
 		.gpiomute 	= 13,
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_LG_PAL_I_FM,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 		/* GPIO wiring:
 			GPIO0: U4.A0 (hef4052bt)
@@ -1594,15 +1483,14 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_FLYVIDEO98EZ] = {
 		.name		= "Lifeview FlyVideo 98EZ (capture only) LR51",
 		.video_inputs	= 4,
-		.audio_inputs   = 0,
-		.tuner		= UNSET,
+		/* .audio_inputs= 0, */
 		.svhs		= 2,
-		.muxsel		= { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */
+		/* AV1, AV2, SVHS, CVid adapter on SVHS */
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 	/* ---- card 0x48 ---------------------------------- */
@@ -1610,11 +1498,10 @@ struct tvcard bttv_tvcards[] = {
 		/* Dariusz Kowalewski <darekk@automex.pl> */
 		.name		= "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
 		.video_inputs	= 4,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x3f,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 0x01, 0x00, 0x03, 0x03 },
 		.gpiomute 	= 0x09,
 		.needs_tvaudio  = 1,
@@ -1623,7 +1510,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
 		.has_radio	= 1,  /* Note: not all cards have radio */
 		.has_remote     = 1,
@@ -1640,49 +1526,42 @@ struct tvcard bttv_tvcards[] = {
 		/* you must jumper JP5 for the card to work */
 		.name           = "Sensoray 311",
 		.video_inputs   = 5,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 4,
 		.gpiomask       = 0,
-		.muxsel         = { 2, 3, 1, 0, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0, 0),
 		.gpiomux        = { 0 },
 		.needs_tvaudio  = 0,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_RV605] = {
 		/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
 		.name           = "RemoteVision MX (RV605)",
 		.video_inputs   = 16,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0x00,
 		.gpiomask2      = 0x07ff,
-		.muxsel         = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
-				0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+		.muxsel         = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.muxsel_hook    = rv605_muxsel,
 	},
 	[BTTV_BOARD_POWERCLR_MTV878] = {
 		.name           = "Powercolor MTV878/ MTV878R/ MTV878F",
 		.video_inputs   = 3,
-		.audio_inputs   = 2,
-		.tuner		= 0,
+		/* .audio_inputs= 2, */
 		.svhs           = 2,
 		.gpiomask       = 0x1C800F,  /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
-		.muxsel         = { 2, 1, 1, },
+		.muxsel         = MUXSEL(2, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
 		.gpiomute 	= 4,
 		.needs_tvaudio  = 0,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll		= PLL_28,
 		.has_radio	= 1,
 	},
@@ -1692,42 +1571,38 @@ struct tvcard bttv_tvcards[] = {
 		/* Masaki Suzuki <masaki@btree.org> */
 		.name           = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x140007,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= windvr_audio,
 	},
 	[BTTV_BOARD_GRANDTEC_MULTI] = {
 		.name           = "GrandTec Multi Capture Card (Bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 0 },
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_KWORLD] = {
 		.name           = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
 		.video_inputs   = 4,
-		.audio_inputs   = 3,
-		.tuner          = 0,
+		/* .audio_inputs= 3, */
 		.svhs           = 2,
 		.gpiomask       = 7,
-		.muxsel         = { 2, 3, 1, 1 },   /* Tuner, SVid, SVHS, SVid to SVHS connector */
+		/* Tuner, SVid, SVHS, SVid to SVHS connector */
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio!
 						* This card lacks external Audio In, so we mute it on Ext. & Int.
 						* The PCB can take a sbx1637/sbx1673, wiring unknown.
@@ -1741,7 +1616,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		/* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
 		radio signal strength indicators work fine. */
 		.has_radio	= 1,
@@ -1759,27 +1633,24 @@ struct tvcard bttv_tvcards[] = {
 		/* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
 		.name           = "DSP Design TCVIDEO",
 		.video_inputs   = 4,
-		.svhs           = UNSET,
-		.muxsel         = { 2, 3, 1, 0 },
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.pll            = PLL_28,
 		.tuner_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 		/* ---- card 0x50 ---------------------------------- */
 	[BTTV_BOARD_HAUPPAUGEPVR] = {
 		.name           = "Hauppauge WinTV PVR",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel         = { 2, 0, 1, 1 },
+		.muxsel         = MUXSEL(2, 0, 1, 1),
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
 		.tuner_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 
 		.gpiomask       = 7,
 		.gpiomux        = {7},
@@ -1787,32 +1658,28 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_GVBCTV5PCI] = {
 		.name           = "IODATA GV-BCTV5/PCI",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x0f0f80,
-		.muxsel         = {2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = {0x030000, 0x010000, 0, 0 },
 		.gpiomute 	= 0x020000,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= gvbctv5pci_audio,
 		.has_radio      = 1,
 	},
 	[BTTV_BOARD_OSPREY1x0] = {
 		.name           = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
 		.video_inputs   = 4,                  /* id-inputs-clock */
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 3,
-		.muxsel         = { 3, 2, 0, 1 },
+		.muxsel         = MUXSEL(3, 2, 0, 1),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1820,14 +1687,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY1x0_848] = {
 		.name           = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
 		.video_inputs   = 3,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 2,
-		.muxsel         = { 2, 3, 1 },
+		.muxsel         = MUXSEL(2, 3, 1),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1837,14 +1702,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY101_848] = {
 		.name           = "Osprey 101 (848)", /* 0x05-40C0-C1 */
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 1,
-		.muxsel         = { 3, 1 },
+		.muxsel         = MUXSEL(3, 1),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1852,14 +1715,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY1x1] = {
 		.name           = "Osprey 101/151",       /* 0x1(4|5)-0004-C4 */
 		.video_inputs   = 1,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 0 },
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(0),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1867,14 +1728,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY1x1_SVID] = {
 		.name           = "Osprey 101/151 w/ svid",  /* 0x(16|17|20)-00C4-C1 */
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 1,
-		.muxsel         = { 0, 1 },
+		.muxsel         = MUXSEL(0, 1),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1882,14 +1741,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY2xx] = {
 		.name           = "Osprey 200/201/250/251",  /* 0x1(8|9|E|F)-0004-C4 */
 		.video_inputs   = 1,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 0 },
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(0),
 		.pll            = PLL_28,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1899,14 +1756,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY2x0_SVID] = {
 		.name           = "Osprey 200/250",   /* 0x1(A|B)-00C4-C1 */
 		.video_inputs   = 2,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
+		/* .audio_inputs= 1, */
 		.svhs           = 1,
-		.muxsel         = { 0, 1 },
+		.muxsel         = MUXSEL(0, 1),
 		.pll            = PLL_28,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1914,14 +1769,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY2x0] = {
 		.name           = "Osprey 210/220/230",   /* 0x1(A|B)-04C0-C1 */
 		.video_inputs   = 2,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
+		/* .audio_inputs= 1, */
 		.svhs           = 1,
-		.muxsel         = { 2, 3 },
+		.muxsel         = MUXSEL(2, 3),
 		.pll            = PLL_28,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1929,14 +1782,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY500] = {
 		.name           = "Osprey 500",   /* 500 */
 		.video_inputs   = 2,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
+		/* .audio_inputs= 1, */
 		.svhs           = 1,
-		.muxsel         = { 2, 3 },
+		.muxsel         = MUXSEL(2, 3),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1944,12 +1795,10 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY540] = {
 		.name           = "Osprey 540",   /* 540 */
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
+		/* .audio_inputs= 1, */
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -1959,14 +1808,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY2000] = {
 		.name           = "Osprey 2000",  /* 2000 */
 		.video_inputs   = 2,
-		.audio_inputs   = 1,
-		.tuner          = UNSET,
+		/* .audio_inputs= 1, */
 		.svhs           = 1,
-		.muxsel         = { 2, 3 },
+		.muxsel         = MUXSEL(2, 3),
 		.pll            = PLL_28,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,      /* must avoid, conflicts with the bt860 */
@@ -1975,14 +1822,12 @@ struct tvcard bttv_tvcards[] = {
 		/* M G Berberich <berberic@forwiss.uni-passau.de> */
 		.name           = "IDS Eagle",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs           = UNSET,
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0,
-		.muxsel         = { 0, 1, 2, 3 },
+		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.muxsel_hook    = eagle_muxsel,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
@@ -1991,16 +1836,14 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_PINNACLESAT] = {
 		.name           = "Pinnacle PCTV Sat",
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
+		/* .audio_inputs= 0, */
 		.svhs           = 1,
-		.tuner          = UNSET,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
-		.muxsel         = { 3, 1 },
+		.muxsel         = MUXSEL(3, 1),
 		.pll            = PLL_28,
 		.no_gpioirq     = 1,
 		.has_dvb        = 1,
@@ -2008,18 +1851,16 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_FORMAC_PROTV] = {
 		.name           = "Formac ProTV II (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 3,
 		.gpiomask       = 2,
 		/* TV, Comp1, Composite over SVID con, SVID */
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 2, 2, 0, 0 },
 		.pll            = PLL_28,
 		.has_radio      = 1,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	/* sound routing:
 		GPIO=0x00,0x01,0x03: mute (?)
 		0x02: both TV and radio (tuner: FM1216/I)
@@ -2033,62 +1874,55 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_MACHTV] = {
 		.name           = "MachTV",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
-		.svhs           = UNSET,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 7,
-		.muxsel         = { 2, 3, 1, 1},
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3},
 		.gpiomute 	= 4,
 		.needs_tvaudio  = 1,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 	},
 	[BTTV_BOARD_EURESYS_PICOLO] = {
 		.name           = "Euresys Picolo",
 		.video_inputs   = 3,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
+		/* .audio_inputs= 0, */
 		.svhs           = 2,
 		.gpiomask       = 0,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
-		.muxsel         = { 2, 0, 1},
+		.muxsel         = MUXSEL(2, 0, 1),
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_PV150] = {
 		/* Luc Van Hoeylandt <luc@e-magic.be> */
 		.name           = "ProVideo PV150", /* 0x4f */
 		.video_inputs   = 2,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0,
-		.muxsel         = { 2, 3 },
+		.muxsel         = MUXSEL(2, 3),
 		.gpiomux        = { 0 },
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_AD_TVK503] = {
 		/* Hiroshi Takekawa <sian@big.or.jp> */
 		/* This card lacks subsystem ID */
 		.name           = "AD-TVK503", /* 0x63 */
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x001e8007,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		/*                  Tuner, Radio, external, internal, off,  on */
 		.gpiomux        = { 0x08,  0x0f,  0x0a,     0x08 },
 		.gpiomute 	= 0x0f,
@@ -2097,7 +1931,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.audio_mode_gpio= adtvk503_audio,
 	},
 
@@ -2105,17 +1938,15 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_HERCULES_SM_TV] = {
 		.name           = "Hercules Smart TV Stereo",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x00,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.needs_tvaudio  = 1,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		/* Notes:
 		- card lacks subsystem ID
 		- stereo variant w/ daughter board with tda9874a @0xb0
@@ -2129,16 +1960,15 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_PACETV] = {
 		.name           = "Pace TV & Radio Card",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel         = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */
+		/* Tuner, CVid, SVid, CVid over SVid connector */
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomask       = 0,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio      = 1,
 		.pll            = PLL_28,
 		/* Bt878, Bt832, FI1246 tuner; no pci subsystem id
@@ -2152,27 +1982,34 @@ struct tvcard bttv_tvcards[] = {
 		/* Chris Willing <chris@vislab.usyd.edu.au> */
 		.name           = "IVC-200",
 		.video_inputs   = 1,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs           = UNSET,
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0xdf,
-		.muxsel         = { 2 },
+		.muxsel         = MUXSEL(2),
+		.pll            = PLL_28,
+	},
+	[BTTV_BOARD_IVCE8784] = {
+		.name           = "IVCE-8784",
+		.video_inputs   = 1,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
+		.tuner_addr     = ADDR_UNSET,
+		.svhs           = NO_SVHS,
+		.gpiomask       = 0xdf,
+		.muxsel         = MUXSEL(2),
 		.pll            = PLL_28,
 	},
 	[BTTV_BOARD_XGUARD] = {
 		.name           = "Grand X-Guard / Trust 814PCI",
 		.video_inputs   = 16,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.gpiomask2      = 0xff,
-		.muxsel         = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+		.muxsel         = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
 		.muxsel_hook    = xguard_muxsel,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
@@ -2184,16 +2021,14 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_NEBULA_DIGITV] = {
 		.name           = "Nebula Electronics DigiTV",
 		.video_inputs   = 1,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 2, 3, 1, 0 },
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_dvb        = 1,
 		.has_remote	= 1,
 		.gpiomask	= 0x1b,
@@ -2203,118 +2038,101 @@ struct tvcard bttv_tvcards[] = {
 		/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
 		.name           = "ProVideo PV143",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 0 },
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
 		/* M.Klahr@phytec.de */
 		.name           = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 3,
 		.gpiomask       = 0x00,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_VD009X1_VD011_COMBI] = {
 		.name           = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 3,
 		.gpiomask       = 0x00,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 
 		/* ---- card 0x6c ---------------------------------- */
 	[BTTV_BOARD_VD009_MINIDIN] = {
 		.name           = "PHYTEC VD-009 MiniDIN (bt878)",
 		.video_inputs   = 10,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 9,
 		.gpiomask       = 0x00,
-		.gpiomask2      = 0x03, /* gpiomask2 defines the bits used to switch audio
-					via the upper nibble of muxsel. here: used for
-					xternal video-mux */
-		.muxsel         = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
+		.gpiomask2      = 0x03, /* used for external vodeo mux */
+		.muxsel         = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
+		.muxsel_hook	= phytec_muxsel,
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_VD009_COMBI] = {
 		.name           = "PHYTEC VD-009 Combi (bt878)",
 		.video_inputs   = 10,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 9,
 		.gpiomask       = 0x00,
-		.gpiomask2      = 0x03, /* gpiomask2 defines the bits used to switch audio
-					via the upper nibble of muxsel. here: used for
-					xternal video-mux */
-		.muxsel         = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
+		.gpiomask2      = 0x03, /* used for external vodeo mux */
+		.muxsel         = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
+		.muxsel_hook	= phytec_muxsel,
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_IVC100] = {
 		.name           = "IVC-100",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs           = UNSET,
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0xdf,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.pll            = PLL_28,
 	},
 	[BTTV_BOARD_IVC120] = {
 		/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
 		.name           = "IVC-120G",
 		.video_inputs   = 16,
-		.audio_inputs   = 0,    /* card has no audio */
-		.tuner          = UNSET,   /* card has no tuner */
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs           = UNSET,   /* card has no svhs */
+		.svhs           = NO_SVHS,   /* card has no svhs */
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.gpiomask       = 0x00,
-		.muxsel         = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+		.muxsel         = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
 		.muxsel_hook    = ivc120_muxsel,
 		.pll            = PLL_28,
 	},
@@ -2323,13 +2141,11 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_PC_HDTV] = {
 		.name           = "pcHDTV HD-2000 TV",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.tuner_type     = TUNER_PHILIPS_FCV1236D,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_dvb        = 1,
 	},
 	[BTTV_BOARD_TWINHAN_DST] = {
@@ -2339,38 +2155,34 @@ struct tvcard bttv_tvcards[] = {
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_video       = 1,
 		.has_dvb        = 1,
 	},
 	[BTTV_BOARD_WINFASTVC100] = {
 		.name           = "Winfast VC100",
 		.video_inputs   = 3,
-		.audio_inputs   = 0,
+		/* .audio_inputs= 0, */
 		.svhs           = 1,
-		.tuner          = UNSET,
-		.muxsel         = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */
+		/* Vid In, SVid In, Vid over SVid in connector */
+		.muxsel		= MUXSEL(3, 1, 1, 3),
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 	},
 	[BTTV_BOARD_TEV560] = {
 		.name           = "Teppro TEV-560/InterVision IV-560",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 3,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 1, 1, 1, 1 },
 		.needs_tvaudio  = 1,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_35,
 	},
 
@@ -2378,14 +2190,12 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_SIMUS_GVC1100] = {
 		.name           = "SIMUS GVC1100",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.tuner_type     = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
-		.muxsel         = { 2, 2, 2, 2 },
+		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.gpiomask       = 0x3F,
 		.muxsel_hook    = gvc1100_muxsel,
 	},
@@ -2393,47 +2203,41 @@ struct tvcard bttv_tvcards[] = {
 		/* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
 		.name           = "NGS NGSTV+",
 		.video_inputs   = 3,
-		.tuner          = 0,
 		.svhs           = 2,
 		.gpiomask       = 0x008007,
-		.muxsel         = { 2, 3, 0, 0 },
+		.muxsel         = MUXSEL(2, 3, 0, 0),
 		.gpiomux        = { 0, 0, 0, 0 },
 		.gpiomute 	= 0x000003,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_LMLBT4] = {
 		/* http://linuxmedialabs.com */
 		.name           = "LMLBT4",
 		.video_inputs   = 4, /* IN1,IN2,IN3,IN4 */
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 2, 3, 1, 0 },
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.needs_tvaudio  = 0,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_TEKRAM_M205] = {
 		/* Helmroos Harri <harri.helmroos@pp.inet.fi> */
 		.name           = "Tekram M205 PRO",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.svhs           = 2,
 		.needs_tvaudio  = 0,
 		.gpiomask       = 0x68,
-		.muxsel         = { 2, 3, 1 },
+		.muxsel         = MUXSEL(2, 3, 1),
 		.gpiomux        = { 0x68, 0x68, 0x61, 0x61 },
 		.pll            = PLL_28,
 	},
@@ -2444,18 +2248,16 @@ struct tvcard bttv_tvcards[] = {
 		/* bt878 TV + FM without subsystem ID */
 		.name           = "Conceptronic CONTVFMi",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x008007,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
 		.gpiomute 	= 3,
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 		.has_radio      = 1,
 	},
@@ -2466,37 +2268,34 @@ struct tvcard bttv_tvcards[] = {
 		/*0x79 in bttv.h*/
 		.name           = "Euresys Picolo Tetra",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0,
 		.gpiomask2      = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
-		.muxsel         = {2,2,2,2},/*878A input is always MUX0, see above.*/
+		/*878A input is always MUX0, see above.*/
+		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.pll            = PLL_28,
 		.needs_tvaudio  = 0,
 		.muxsel_hook    = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_SPIRIT_TV] = {
 		/* Spirit TV Tuner from http://spiritmodems.com.au */
 		/* Stafford Goodsell <surge@goliath.homeunix.org> */
 		.name           = "Spirit TV Tuner",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x0000000f,
-		.muxsel         = { 2, 1, 1 },
+		.muxsel         = MUXSEL(2, 1, 1),
 		.gpiomux        = { 0x02, 0x00, 0x00, 0x00 },
 		.tuner_type     = TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 	},
@@ -2505,11 +2304,9 @@ struct tvcard bttv_tvcards[] = {
 		.name           = "AVerMedia AVerTV DVB-T 771",
 		.video_inputs   = 2,
 		.svhs           = 1,
-		.tuner          = UNSET,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.muxsel         = { 3 , 3 },
+		.muxsel         = MUXSEL(3, 3),
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -2524,54 +2321,47 @@ struct tvcard bttv_tvcards[] = {
 		/* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
 		.name           = "AverMedia AverTV DVB-T 761",
 		.video_inputs   = 2,
-		.tuner          = UNSET,
 		.svhs           = 1,
-		.muxsel         = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */
+		.muxsel         = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_dvb        = 1,
 		.no_gpioirq     = 1,
 		.has_remote     = 1,
 	},
 	[BTTV_BOARD_MATRIX_VISIONSQ] = {
 		/* andre.schwarz@matrix-vision.de */
-		.name             = "MATRIX Vision Sigma-SQ",
-		.video_inputs     = 16,
-		.audio_inputs     = 0,
-		.tuner            = UNSET,
-		.svhs             = UNSET,
-		.gpiomask         = 0x0,
-		.muxsel           = { 2, 2, 2, 2, 2, 2, 2, 2,
-				3, 3, 3, 3, 3, 3, 3, 3 },
-		.muxsel_hook      = sigmaSQ_muxsel,
-		.gpiomux          = { 0 },
-		.no_msp34xx       = 1,
-		.pll              = PLL_28,
-		.tuner_type       = UNSET,
-		.tuner_addr	  = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
+		.name		= "MATRIX Vision Sigma-SQ",
+		.video_inputs	= 16,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.gpiomask	= 0x0,
+		.muxsel		= MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3),
+		.muxsel_hook	= sigmaSQ_muxsel,
+		.gpiomux	= { 0 },
+		.no_msp34xx	= 1,
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
 	},
 	[BTTV_BOARD_MATRIX_VISIONSLC] = {
 		/* andre.schwarz@matrix-vision.de */
-		.name             = "MATRIX Vision Sigma-SLC",
-		.video_inputs     = 4,
-		.audio_inputs     = 0,
-		.tuner            = UNSET,
-		.svhs             = UNSET,
-		.gpiomask         = 0x0,
-		.muxsel           = { 2, 2, 2, 2 },
-		.muxsel_hook      = sigmaSLC_muxsel,
-		.gpiomux          = { 0 },
-		.no_msp34xx       = 1,
-		.pll              = PLL_28,
-		.tuner_type       = UNSET,
-		.tuner_addr	  = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
+		.name		= "MATRIX Vision Sigma-SLC",
+		.video_inputs	= 4,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.gpiomask	= 0x0,
+		.muxsel		= MUXSEL(2, 2, 2, 2),
+		.muxsel_hook	= sigmaSLC_muxsel,
+		.gpiomux	= { 0 },
+		.no_msp34xx	= 1,
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
 	},
 		/* BTTV_BOARD_APAC_VIEWCOMP */
 	[BTTV_BOARD_APAC_VIEWCOMP] = {
@@ -2579,18 +2369,16 @@ struct tvcard bttv_tvcards[] = {
 		/* bt878 TV + FM 0x00000000 subsystem ID */
 		.name           = "APAC Viewcomp 878(AMAX)",
 		.video_inputs   = 2,
-		.audio_inputs   = 1,
-		.tuner          = 0,
-		.svhs           = UNSET,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0xFF,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 2, 0, 0, 0 },
 		.gpiomute 	= 10,
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,   /* miniremote works, see ir-kbd-gpio.c */
 		.has_radio      = 1,   /* not every card has radio */
 	},
@@ -2599,46 +2387,40 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_DVICO_DVBT_LITE] = {
 		/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
 		.name           = "DViCO FusionHDTV DVB-T Lite",
-		.tuner          = UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.no_video       = 1,
 		.has_dvb        = 1,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_VGEAR_MYVCD] = {
 		/* Steven <photon38@pchome.com.tw> */
 		.name           = "V-Gear MyVCD",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x3f,
-		.muxsel         = {2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = {0x31, 0x31, 0x31, 0x31 },
 		.gpiomute 	= 0x31,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio      = 0,
 	},
 	[BTTV_BOARD_SUPER_TV] = {
 		/* Rick C <cryptdragoon@gmail.com> */
 		.name           = "Super TV Tuner",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.gpiomask       = 0x008007,
 		.gpiomux        = { 0, 0x000001,0,0 },
 		.needs_tvaudio  = 1,
@@ -2648,17 +2430,15 @@ struct tvcard bttv_tvcards[] = {
 		/* Chris Fanning <video4linux@haydon.net> */
 		.name           = "Tibet Systems 'Progress DVR' CS16",
 		.video_inputs   = 16,
-		.audio_inputs   = 0,
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
 		.pll		= PLL_28,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432	= 1,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.muxsel_hook    = tibetCS16_muxsel,
 	},
 	[BTTV_BOARD_KODICOM_4400R] = {
@@ -2675,12 +2455,10 @@ struct tvcard bttv_tvcards[] = {
 		*/
 		.name           = "Kodicom 4400R (master)",
 		.video_inputs	= 16,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
-		.tuner_type	= UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs		= UNSET,
+		.svhs		= NO_SVHS,
 		/* GPIO bits 0-9 used for analog switch:
 		*   00 - 03:	camera selector
 		*   04 - 06:	channel (controller) selector
@@ -2691,7 +2469,7 @@ struct tvcard bttv_tvcards[] = {
 		*/
 		.gpiomask	= 0x0003ff,
 		.no_gpioirq     = 1,
-		.muxsel		= { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+		.muxsel		= MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
@@ -2707,15 +2485,13 @@ struct tvcard bttv_tvcards[] = {
 		*/
 		.name		= "Kodicom 4400R (slave)",
 		.video_inputs	= 16,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
-		.tuner_type	= UNSET,
+		/* .audio_inputs= 0, */
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.svhs		= UNSET,
+		.svhs		= NO_SVHS,
 		.gpiomask	= 0x010000,
 		.no_gpioirq     = 1,
-		.muxsel		= { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+		.muxsel		= MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
@@ -2728,27 +2504,23 @@ struct tvcard bttv_tvcards[] = {
 		/* Adlink RTV24 with special unlock codes */
 		.name           = "Adlink RTV24",
 		.video_inputs   = 4,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel         = { 2, 3, 1, 0 },
+		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.tuner_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 	},
 		/* ---- card 0x87---------------------------------- */
 	[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
 		/* Michael Krufky <mkrufky@m1k.net> */
 		.name           = "DViCO FusionHDTV 5 Lite",
-		.tuner          = 0,
 		.tuner_type     = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel		= { 2, 3, 1 },
+		.muxsel		= MUXSEL(2, 3, 1),
 		.gpiomask       = 0x00e00007,
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomute 	= 0x00c00007,
@@ -2762,75 +2534,68 @@ struct tvcard bttv_tvcards[] = {
 		/* Mauro Carvalho Chehab <mchehab@infradead.org> */
 		.name		= "Acorp Y878F",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x01fe00,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x001e00, 0, 0x018000, 0x014000 },
 		.gpiomute 	= 0x002000,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_YMEC_TVF66T5_B_DFF,
 		.tuner_addr	= 0xc1 >>1,
-		.radio_addr     = 0xc1 >>1,
 		.has_radio	= 1,
 	},
 		/* ---- card 0x89 ---------------------------------- */
 	[BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
 		.name           = "Conceptronic CTVFMi v2",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x001c0007,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
 		.gpiomute 	= 3,
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_TENA_9533_DI,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_remote     = 1,
 		.has_radio      = 1,
 	},
 		/* ---- card 0x8a ---------------------------------- */
 	[BTTV_BOARD_PV_BT878P_2E] = {
-		.name          = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
-		.video_inputs  = 5,
-		.audio_inputs  = 1,
-		.tuner         = 0,
-		.svhs          = 3,
-		.gpiomask      = 0x01fe00,
-		.muxsel        = { 2,3,1,1,-1 },
-		.digital_mode  = DIGITAL_MODE_CAMERA,
-		.gpiomux       = { 0x00400, 0x10400, 0x04400, 0x80000 },
-		.gpiomute      = 0x12400,
-		.no_msp34xx    = 1,
-		.pll           = PLL_28,
-		.tuner_type    = TUNER_LG_PAL_FM,
+		.name		= "Prolink Pixelview PV-BT878P+ (Rev.2E)",
+		.video_inputs	= 5,
+		/* .audio_inputs= 1, */
+		.svhs		= 3,
+		.has_dig_in	= 1,
+		.gpiomask	= 0x01fe00,
+		.muxsel		= MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+		/* .digital_mode= DIGITAL_MODE_CAMERA, */
+		.gpiomux	= { 0x00400, 0x10400, 0x04400, 0x80000 },
+		.gpiomute	= 0x12400,
+		.no_msp34xx	= 1,
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_LG_PAL_FM,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-		.has_remote    = 1,
+		.has_remote	= 1,
 	},
 		/* ---- card 0x8b ---------------------------------- */
 	[BTTV_BOARD_PV_M4900] = {
 		/* SÃ©rgio Fortier <sergiofortier@yahoo.com.br> */
 		.name           = "Prolink PixelView PlayTV MPEG2 PV-M4900",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x3f,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x21, 0x20, 0x24, 0x2c },
 		.gpiomute 	= 0x29,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_YMEC_TVF_5533MF,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.has_radio      = 1,
 		.has_remote     = 1,
 	},
@@ -2850,17 +2615,15 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_OSPREY440]  = {
 		.name           = "Osprey 440",
 		.video_inputs   = 4,
-		.audio_inputs   = 2, /* this is meaningless */
-		.tuner          = UNSET,
-		.svhs           = UNSET,
-		.muxsel         = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */
+		/* .audio_inputs= 2, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
 		.gpiomask	= 0x303,
 		.gpiomute	= 0x000, /* int + 32kHz */
 		.gpiomux	= { 0, 0, 0x000, 0x100},
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
@@ -2869,28 +2632,25 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_ASOUND_SKYEYE] = {
 		.name		= "Asound Skyeye PCTV",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 15,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 2, 0, 0, 0 },
 		.gpiomute 	= 1,
 		.needs_tvaudio	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 		/* ---- card 0x8e ---------------------------------- */
 	[BTTV_BOARD_SABRENT_TVFM] = {
 		.name		= "Sabrent TV-FM (bttv version)",
 		.video_inputs	= 3,
-		.audio_inputs	= 1,
-		.tuner		= 0,
+		/* .audio_inputs= 1, */
 		.svhs		= 2,
 		.gpiomask	= 0x108007,
-		.muxsel		= { 2, 3, 1, 1 },
+		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 100000, 100002, 100002, 100000 },
 		.no_msp34xx	= 1,
 		.no_tda9875     = 1,
@@ -2904,17 +2664,15 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
 		.name		= "Hauppauge ImpactVCB (bt878)",
 		.video_inputs	= 4,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
-		.svhs		= UNSET,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
 		.gpiomask	= 0x0f, /* old: 7 */
-		.muxsel		= { 0, 1, 3, 2 }, /* Composite 0-3 */
+		.muxsel		= MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
 		.no_msp34xx	= 1,
 		.no_tda9875     = 1,
 		.no_tda7432     = 1,
-		.tuner_type	= UNSET,
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_MACHTV_MAGICTV] = {
 		/* Julian Calaby <julian.calaby@gmail.com>
@@ -2926,16 +2684,14 @@ struct tvcard bttv_tvcards[] = {
 
 		.name           = "MagicTV", /* rebranded MachTV */
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 7,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
 		.gpiomute 	= 4,
 		.tuner_type     = TUNER_TEMIC_4009FR5_PAL,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 		.has_radio      = 1,
 		.has_remote     = 1,
@@ -2943,36 +2699,30 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_SSAI_SECURITY] = {
 		.name		= "SSAI Security Video Interface",
 		.video_inputs	= 4,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
-		.svhs		= UNSET,
-		.muxsel		= { 0, 1, 2, 3 },
-		.tuner_type	= UNSET,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.muxsel		= MUXSEL(0, 1, 2, 3),
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_SSAI_ULTRASOUND] = {
 		.name		= "SSAI Ultrasound Video Interface",
 		.video_inputs	= 2,
-		.audio_inputs	= 0,
-		.tuner		= UNSET,
+		/* .audio_inputs= 0, */
 		.svhs		= 1,
-		.muxsel		= { 2, 0, 1, 3 },
-		.tuner_type	= UNSET,
+		.muxsel		= MUXSEL(2, 0, 1, 3),
+		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	/* ---- card 0x94---------------------------------- */
 	[BTTV_BOARD_DVICO_FUSIONHDTV_2] = {
 		.name           = "DViCO FusionHDTV 2",
-		.tuner          = 0,
 		.tuner_type     = TUNER_PHILIPS_FCV1236D,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
-		.muxsel		= { 2, 3, 1 },
+		.muxsel		= MUXSEL(2, 3, 1),
 		.gpiomask       = 0x00e00007,
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomute 	= 0x00c00007,
@@ -2984,36 +2734,31 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
 		.name           = "Typhoon TV-Tuner PCI (50684)",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x3014f,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x20001,0x10001, 0, 0 },
 		.gpiomute       = 10,
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL_I,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 	[BTTV_BOARD_GEOVISION_GV600] = {
 		/* emhn@usb.ve */
-		.name             = "Geovision GV-600",
-		.video_inputs     = 16,
-		.audio_inputs     = 0,
-		.tuner            = UNSET,
-		.svhs             = UNSET,
-		.gpiomask         = 0x0,
-		.muxsel           = { 2, 2, 2, 2, 2, 2, 2, 2,
-				      2, 2, 2, 2, 2, 2, 2, 2 },
-		.muxsel_hook      = geovision_muxsel,
-		.gpiomux          = { 0 },
-		.no_msp34xx       = 1,
-		.pll              = PLL_28,
-		.tuner_type       = UNSET,
-		.tuner_addr	  = ADDR_UNSET,
-		.radio_addr       = ADDR_UNSET,
+		.name		= "Geovision GV-600",
+		.video_inputs	= 16,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.gpiomask	= 0x0,
+		.muxsel		= MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+		.muxsel_hook	= geovision_muxsel,
+		.gpiomux	= { 0 },
+		.no_msp34xx	= 1,
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
 	},
 	[BTTV_BOARD_KOZUMI_KTV_01C] = {
 		/* Mauro Lacy <mauro@lacy.com.ar>
@@ -3021,17 +2766,15 @@ struct tvcard bttv_tvcards[] = {
 
 		.name           = "Kozumi KTV-01C",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		.gpiomask       = 0x008007,
-		.muxsel         = { 2, 3, 1, 1 },
+		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 }, /* CONTVFMi */
 		.gpiomute 	= 3, /* CONTVFMi */
 		.needs_tvaudio  = 0,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 		.has_radio      = 1,
 		.has_remote     = 1,
@@ -3041,8 +2784,7 @@ struct tvcard bttv_tvcards[] = {
 		   Mauro Carvalho Chehab <mchehab@infradead.org */
 		.name           = "Encore ENL TV-FM-2",
 		.video_inputs   = 3,
-		.audio_inputs   = 1,
-		.tuner          = 0,
+		/* .audio_inputs= 1, */
 		.svhs           = 2,
 		/* bit 6          -> IR disabled
 		   bit 18/17 = 00 -> mute
@@ -3051,12 +2793,11 @@ struct tvcard bttv_tvcards[] = {
 			       11 -> internal audio input
 		 */
 		.gpiomask       = 0x060040,
-		.muxsel         = { 2, 3, 3 },
+		.muxsel         = MUXSEL(2, 3, 3),
 		.gpiomux        = { 0x60000, 0x60000, 0x20000, 0x20000 },
 		.gpiomute 	= 0,
 		.tuner_type	= TUNER_TCL_MF02GIP_5N,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
 		.has_radio      = 1,
 		.has_remote     = 1,
@@ -3065,50 +2806,111 @@ struct tvcard bttv_tvcards[] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012 (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
-		.svhs           = UNSET, /* card has no s-video */
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
 		.gpiomask       = 0x00,
-		.muxsel         = { 0, 2, 3, 1 },
+		.muxsel         = MUXSEL(0, 2, 3, 1),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 		[BTTV_BOARD_VD012_X1] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X1 (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 3,
 		.gpiomask       = 0x00,
-		.muxsel         = { 2, 3, 1 },
+		.muxsel         = MUXSEL(2, 3, 1),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
 	},
 		[BTTV_BOARD_VD012_X2] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X2 (bt878)",
 		.video_inputs   = 4,
-		.audio_inputs   = 0,
-		.tuner          = UNSET, /* card has no tuner */
+		/* .audio_inputs= 0, */
 		.svhs           = 3,
 		.gpiomask       = 0x00,
-		.muxsel         = { 3, 2, 1 },
+		.muxsel         = MUXSEL(3, 2, 1),
 		.gpiomux        = { 0, 0, 0, 0 }, /* card has no audio */
 		.needs_tvaudio  = 0,
 		.pll            = PLL_28,
-		.tuner_type     = UNSET,
+		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
-	}
+	},
+		[BTTV_BOARD_GEOVISION_GV800S] = {
+		/* Bruno Christo <bchristo@inf.ufsm.br>
+		 *
+		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+		 * 	1 audio input  per BT878A = 4 audio inputs
+		 * 	4 video inputs per BT878A = 16 video inputs
+		 * This is the first BT878A chip of the GV-800(S). It's the
+		 * "master" chip and it controls the video inputs through an
+		 * analog multiplexer (a CD22M3494) via some GPIO pins. The
+		 * slaves should use card type 0x9e (following this one).
+		 * There is a EEPROM on the card which is currently not handled.
+		 * The audio input is not working yet.
+		 */
+		.name           = "Geovision GV-800(S) (master)",
+		.video_inputs   = 4,
+		/* .audio_inputs= 1, */
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+		.svhs           = NO_SVHS,
+		.gpiomask	= 0xf107f,
+		.no_gpioirq     = 1,
+		.muxsel		= MUXSEL(2, 2, 2, 2),
+		.pll		= PLL_28,
+		.no_msp34xx	= 1,
+		.no_tda7432	= 1,
+		.no_tda9875	= 1,
+		.muxsel_hook    = gv800s_muxsel,
+	},
+		[BTTV_BOARD_GEOVISION_GV800S_SL] = {
+		/* Bruno Christo <bchristo@inf.ufsm.br>
+		 *
+		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+		 * 	1 audio input  per BT878A = 4 audio inputs
+		 * 	4 video inputs per BT878A = 16 video inputs
+		 * The 3 other BT878A chips are "slave" chips of the GV-800(S)
+		 * and should use this card type.
+		 * The audio input is not working yet.
+		 */
+		.name           = "Geovision GV-800(S) (slave)",
+		.video_inputs   = 4,
+		/* .audio_inputs= 1, */
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+		.svhs           = NO_SVHS,
+		.gpiomask	= 0x00,
+		.no_gpioirq     = 1,
+		.muxsel		= MUXSEL(2, 2, 2, 2),
+		.pll		= PLL_28,
+		.no_msp34xx	= 1,
+		.no_tda7432	= 1,
+		.no_tda9875	= 1,
+		.muxsel_hook    = gv800s_muxsel,
+	},
+	[BTTV_BOARD_PV183] = {
+		.name           = "ProVideo PV183", /* 0x9f */
+		.video_inputs   = 2,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		.gpiomask       = 0,
+		.muxsel         = MUXSEL(2, 3),
+		.gpiomux        = { 0 },
+		.needs_tvaudio  = 0,
+		.no_msp34xx     = 1,
+		.pll            = PLL_28,
+		.tuner_type     = TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+	},
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3152,7 +2954,7 @@ void __devinit bttv_idcard(struct bttv *
 			       btv->c.nr, btv->cardid & 0xffff,
 			       (btv->cardid >> 16) & 0xffff);
 			printk(KERN_DEBUG "please mail id, board name and "
-			       "the correct card= insmod option to video4linux-list@redhat.com\n");
+			       "the correct card= insmod option to linux-media@vger.kernel.org\n");
 		}
 	}
 
@@ -3403,8 +3205,7 @@ static void init_ids_eagle(struct bttv *
  * has its own multiplexer */
 static void eagle_muxsel(struct bttv *btv, unsigned int input)
 {
-	btaor((2)<<5, ~(3<<5), BT848_IFORM);
-	gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
+	gpio_bits(3, input & 3);
 
 	/* composite */
 	/* set chroma ADC to sleep */
@@ -3629,6 +3430,9 @@ void __devinit bttv_init_card2(struct bt
 	case BTTV_BOARD_KODICOM_4400R:
 		kodicom4400r_init(btv);
 		break;
+	case BTTV_BOARD_GEOVISION_GV800S:
+		gv800s_init(btv);
+		break;
 	}
 
 	/* pll configuration */
@@ -3670,13 +3474,12 @@ void __devinit bttv_init_card2(struct bt
 		addr = bttv_tvcards[btv->c.type].tuner_addr;
 
 	if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
-		if(UNSET == btv->tuner_type)
+		if (UNSET == btv->tuner_type)
 			btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
 	if (UNSET != tuner[btv->c.nr])
 		btv->tuner_type = tuner[btv->c.nr];
 
-	if (btv->tuner_type == TUNER_ABSENT ||
-	    bttv_tvcards[btv->c.type].tuner == UNSET)
+	if (btv->tuner_type == TUNER_ABSENT)
 		printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr);
 	else if(btv->tuner_type == UNSET)
 		printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr);
@@ -3684,14 +3487,38 @@ void __devinit bttv_init_card2(struct bt
 		printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
 		       btv->tuner_type);
 
-	if (btv->tuner_type != UNSET) {
+	if (autoload != UNSET) {
+		printk(KERN_WARNING "bttv%d: the autoload option is obsolete.\n", btv->c.nr);
+		printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or tvaudio to\n", btv->c.nr);
+		printk(KERN_WARNING "bttv%d: override which audio module should be used.\n", btv->c.nr);
+	}
+
+	if (UNSET == btv->tuner_type)
+		btv->tuner_type = TUNER_ABSENT;
+
+	if (btv->tuner_type != TUNER_ABSENT) {
 		struct tuner_setup tun_setup;
 
+		/* Load tuner module before issuing tuner config call! */
+		if (bttv_tvcards[btv->c.type].has_radio)
+			v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+		v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
+
 		tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
 		tun_setup.type = btv->tuner_type;
 		tun_setup.addr = addr;
 
-		bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+		if (bttv_tvcards[btv->c.type].has_radio)
+			tun_setup.mode_mask |= T_RADIO;
+
+		bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
 	}
 
 	if (btv->tda9887_conf) {
@@ -3700,10 +3527,13 @@ void __devinit bttv_init_card2(struct bt
 		tda9887_cfg.tuner = TUNER_TDA9887;
 		tda9887_cfg.priv = &btv->tda9887_conf;
 
-		bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
+		bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
 	}
 
-	btv->svhs = bttv_tvcards[btv->c.type].svhs;
+	btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
+		   bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
+	btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
+		    UNSET : bttv_tvcards[btv->c.type].svhs;
 	if (svhs[btv->c.nr] != UNSET)
 		btv->svhs = svhs[btv->c.nr];
 	if (remote[btv->c.nr] != UNSET)
@@ -3720,34 +3550,119 @@ void __devinit bttv_init_card2(struct bt
 	if (bttv_tvcards[btv->c.type].audio_mode_gpio)
 		btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
 
-	if (!autoload)
-		return;
-
-	if (bttv_tvcards[btv->c.type].tuner == UNSET)
+	if (btv->tuner_type == TUNER_ABSENT)
 		return;  /* no tuner or related drivers to load */
 
+	if (btv->has_saa6588 || saa6588[btv->c.nr]) {
+		/* Probe for RDS receiver chip */
+		static const unsigned short addrs[] = {
+			0x20 >> 1,
+			0x22 >> 1,
+			I2C_CLIENT_END
+		};
+		struct v4l2_subdev *sd;
+
+		sd = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "saa6588", "saa6588", addrs);
+		btv->has_saa6588 = (sd != NULL);
+	}
+
 	/* try to detect audio/fader chips */
-	if (!bttv_tvcards[btv->c.type].no_msp34xx &&
-	    bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0)
-		request_module("msp3400");
 
-	if (bttv_tvcards[btv->c.type].msp34xx_alt &&
-	    bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
-		request_module("msp3400");
+	/* First check if the user specified the audio chip via a module
+	   option. */
 
-	if (!bttv_tvcards[btv->c.type].no_tda9875 &&
-	    bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
-		request_module("tda9875");
+	switch (audiodev[btv->c.nr]) {
+	case -1:
+		return;	/* do not load any audio module */
 
-	if (!bttv_tvcards[btv->c.type].no_tda7432 &&
-	    bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
-		request_module("tda7432");
+	case 0: /* autodetect */
+		break;
 
-	if (bttv_tvcards[btv->c.type].needs_tvaudio)
-		request_module("tvaudio");
+	case 1: {
+		/* The user specified that we should probe for msp3400 */
+		static const unsigned short addrs[] = {
+			I2C_ADDR_MSP3400 >> 1,
+			I2C_ADDR_MSP3400_ALT >> 1,
+			I2C_CLIENT_END
+		};
 
-	if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT)
-		request_module("tuner");
+		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "msp3400", "msp3400", addrs);
+		if (btv->sd_msp34xx)
+			return;
+		goto no_audio;
+	}
+
+	case 2: {
+		/* The user specified that we should probe for tda7432 */
+		static const unsigned short addrs[] = {
+			I2C_ADDR_TDA7432 >> 1,
+			I2C_CLIENT_END
+		};
+
+		if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tda7432", "tda7432", addrs))
+			return;
+		goto no_audio;
+	}
+
+	case 3: {
+		/* The user specified that we should probe for tvaudio */
+		btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
+		if (btv->sd_tvaudio)
+			return;
+		goto no_audio;
+	}
+
+	default:
+		printk(KERN_WARNING "bttv%d: unknown audiodev value!\n",
+			btv->c.nr);
+		return;
+	}
+
+	/* There were no overrides, so now we try to discover this through the
+	   card definition */
+
+	/* probe for msp3400 first: this driver can detect whether or not
+	   it really is a msp3400, so it will return NULL when the device
+	   found is really something else (e.g. a tea6300). */
+	if (!bttv_tvcards[btv->c.type].no_msp34xx) {
+		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "msp3400", "msp3400",
+			I2C_ADDR_MSP3400 >> 1);
+	} else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
+		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "msp3400", "msp3400",
+			I2C_ADDR_MSP3400_ALT >> 1);
+	}
+
+	/* If we found a msp34xx, then we're done. */
+	if (btv->sd_msp34xx)
+		return;
+
+	/* it might also be a tda7432. */
+	if (!bttv_tvcards[btv->c.type].no_tda7432) {
+		static const unsigned short addrs[] = {
+			I2C_ADDR_TDA7432 >> 1,
+			I2C_CLIENT_END
+		};
+
+		if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tda7432", "tda7432", addrs))
+			return;
+	}
+
+	/* Now see if we can find one of the tvaudio devices. */
+	btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+		&btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
+	if (btv->sd_tvaudio)
+		return;
+
+no_audio:
+	printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n",
+			btv->c.nr);
 }
 
 
@@ -3819,6 +3734,7 @@ static int terratec_active_radio_upgrade
 		printk("bttv%d: Terratec Active Radio Upgrade found.\n",
 		       btv->c.nr);
 		btv->has_radio    = 1;
+		btv->has_saa6588  = 1;
 		btv->has_matchbox = 1;
 	} else {
 		btv->has_radio    = 0;
@@ -4064,27 +3980,26 @@ static void __devinit avermedia_eeprom(s
 	       btv->has_remote ? "yes" : "no");
 }
 
-/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
-void bttv_tda9880_setnorm(struct bttv *btv, int norm)
+/*
+ * For Voodoo TV/FM and Voodoo 200.  These cards' tuners use a TDA9880
+ * analog demod, which is not I2C controlled like the newer and more common
+ * TDA9887 series.  Instead is has two tri-state input pins, S0 and S1,
+ * that control the IF for the video and audio.  Apparently, bttv GPIO
+ * 0x10000 is connected to S0.  S0 low selects a 38.9 MHz VIF for B/G/D/K/I
+ * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
+ */
+u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
 {
-	/* fix up our card entry */
-	if(norm==V4L2_STD_NTSC) {
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff;
-		dprintk("bttv_tda9880_setnorm to NTSC\n");
-	}
-	else {
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
-		bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff;
-		dprintk("bttv_tda9880_setnorm to PAL\n");
+
+	if (btv->audio == TVAUDIO_INPUT_TUNER) {
+		if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
+			gpiobits |= 0x10000;
+		else
+			gpiobits &= ~0x10000;
 	}
-	/* set GPIO according */
-	gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
-		  bttv_tvcards[btv->c.type].gpiomux[btv->audio]);
+
+	gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits);
+	return gpiobits;
 }
 
 
@@ -4460,6 +4375,11 @@ void tea5757_set_freq(struct bttv *btv,
  */
 static void rv605_muxsel(struct bttv *btv, unsigned int input)
 {
+	static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
+				      0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
+
+	gpio_bits(0x07f, muxgpio[input]);
+
 	/* reset all conections */
 	gpio_bits(0x200,0x200);
 	mdelay(1);
@@ -4467,7 +4387,6 @@ static void rv605_muxsel(struct bttv *bt
 	mdelay(1);
 
 	/* create a new connection */
-	gpio_bits(0x480,0x080);
 	gpio_bits(0x480,0x480);
 	mdelay(1);
 	gpio_bits(0x480,0x080);
@@ -4726,8 +4645,7 @@ static void ivc120_muxsel(struct bttv *b
 	bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
 		      ((matrix == 2) ? 0x03 : 0x00), 1);  /* 9-12 */
 
-	/* Selects MUX0 for input on the 878 */
-	btaor((0)<<5, ~(3<<5), BT848_IFORM);
+	/* 878's MUX0 is already selected for input via muxsel values */
 }
 
 
@@ -4811,6 +4729,132 @@ static void PXC200_muxsel(struct bttv *b
 	printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
 }
 
+static void phytec_muxsel(struct bttv *btv, unsigned int input)
+{
+	unsigned int mux = input % 4;
+
+	if (input == btv->svhs)
+		mux = 0;
+
+	gpio_bits(0x3, mux);
+}
+
+/*
+ * GeoVision GV-800(S) functions
+ * Bruno Christo <bchristo@inf.ufsm.br>
+*/
+
+/* This is a function to control the analog switch, which determines which
+ * camera is routed to which controller.  The switch comprises an X-address
+ * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
+ * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
+ * A data value (gpio bit 18) of '1' enables the switch, and '0' disables
+ * the switch.  A STROBE bit (gpio bit 17) latches the data value into the
+ * specified address. There is also a chip select (gpio bit 16).
+ * The idea is to set the address and chip select together, bring
+ * STROBE high, write the data, and finally bring STROBE back to low.
+ */
+static void gv800s_write(struct bttv *btv,
+			 unsigned char xaddr,
+			 unsigned char yaddr,
+			 unsigned char data) {
+	/* On the "master" 878A:
+	* GPIO bits 0-9 are used for the analog switch:
+	*   00 - 03:	camera selector
+	*   04 - 06:	878A (controller) selector
+	*   16: 	cselect
+	*   17:		strobe
+	*   18: 	data (1->on, 0->off)
+	*   19:		reset
+	*/
+	const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
+	const u32 CSELECT = 1<<16;
+	const u32 STROBE = 1<<17;
+	const u32 DATA = data<<18;
+
+	gpio_bits(0x1007f, ADDRESS | CSELECT);	/* write ADDRESS and CSELECT */
+	gpio_bits(0x20000, STROBE);		/* STROBE high */
+	gpio_bits(0x40000, DATA);		/* write DATA */
+	gpio_bits(0x20000, ~STROBE);		/* STROBE low */
+}
+
+/*
+ * GeoVision GV-800(S) muxsel
+ *
+ * Each of the 4 cards (controllers) use this function.
+ * The controller using this function selects the input through the GPIO pins
+ * of the "master" card. A pointer to this card is stored in master[btv->c.nr].
+ *
+ * The parameter 'input' is the requested camera number (0-4) on the controller.
+ * The map array has the address of each input. Note that the addresses in the
+ * array are in the sequence the original GeoVision driver uses, that is, set
+ * every controller to input 0, then to input 1, 2, 3, repeat. This means that
+ * the physical "camera 1" connector corresponds to controller 0 input 0,
+ * "camera 2" corresponds to controller 1 input 0, and so on.
+ *
+ * After getting the input address, the function then writes the appropriate
+ * data to the analog switch, and housekeeps the local copy of the switch
+ * information.
+ */
+static void gv800s_muxsel(struct bttv *btv, unsigned int input)
+{
+	struct bttv *mctlr;
+	char *sw_status;
+	int xaddr, yaddr;
+	static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 },
+					  { 0x1, 0x5, 0xb, 0x7 },
+					  { 0x2, 0x8, 0xc, 0xe },
+					  { 0x3, 0x9, 0xd, 0xf } };
+	input = input%4;
+	mctlr = master[btv->c.nr];
+	if (mctlr == NULL) {
+		/* do nothing until the "master" is detected */
+		return;
+	}
+	yaddr = (btv->c.nr - mctlr->c.nr) & 3;
+	sw_status = (char *)(&mctlr->mbox_we);
+	xaddr = map[yaddr][input] & 0xf;
+
+	/* Check if the controller/camera pair has changed, ignore otherwise */
+	if (sw_status[yaddr] != xaddr) {
+		/* disable the old switch, enable the new one and save status */
+		gv800s_write(mctlr, sw_status[yaddr], yaddr, 0);
+		sw_status[yaddr] = xaddr;
+		gv800s_write(mctlr, xaddr, yaddr, 1);
+	}
+}
+
+/* GeoVision GV-800(S) "master" chip init */
+static void gv800s_init(struct bttv *btv)
+{
+	char *sw_status = (char *)(&btv->mbox_we);
+	int ix;
+
+	gpio_inout(0xf107f, 0xf107f);
+	gpio_write(1<<19); /* reset the analog MUX */
+	gpio_write(0);
+
+	/* Preset camera 0 to the 4 controllers */
+	for (ix = 0; ix < 4; ix++) {
+		sw_status[ix] = ix;
+		gv800s_write(btv, ix, ix, 1);
+	}
+
+	/* Inputs on the "master" controller need this brightness fix */
+	bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1);
+
+	if (btv->c.nr > BTTV_MAX-4)
+		return;
+	/*
+	 * Store the "master" controller pointer in the master
+	 * array for later use in the muxsel function.
+	 */
+	master[btv->c.nr]   = btv;
+	master[btv->c.nr+1] = btv;
+	master[btv->c.nr+2] = btv;
+	master[btv->c.nr+3] = btv;
+}
+
 /* ----------------------------------------------------------------------- */
 /* motherboard chipset specific stuff                                      */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-driver.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,7 +58,7 @@
 
 
 unsigned int bttv_num;			/* number of Bt848s in use */
-struct bttv bttvs[BTTV_MAX];
+struct bttv *bttvs[BTTV_MAX];
 
 unsigned int bttv_debug;
 unsigned int bttv_verbose = 1;
@@ -167,7 +167,7 @@ static ssize_t show_card(struct device *
 			 struct device_attribute *attr, char *buf)
 {
 	struct video_device *vfd = container_of(cd, struct video_device, dev);
-	struct bttv *btv = dev_get_drvdata(vfd->parent);
+	struct bttv *btv = video_get_drvdata(vfd);
 	return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 }
 static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -1040,7 +1040,7 @@ static void bt848A_set_timing(struct btt
 	int table_idx = bttv_tvnorms[btv->tvnorm].sram;
 	int fsc       = bttv_tvnorms[btv->tvnorm].Fsc;
 
-	if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
+	if (btv->input == btv->dig) {
 		dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
 			btv->c.nr,table_idx);
 
@@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int
 		btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
 	}
-	mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
+	mux = bttv_muxsel(btv, input);
 	btaor(mux<<5, ~(3<<5), BT848_IFORM);
 	dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
 		btv->c.nr,input,mux);
@@ -1163,7 +1163,6 @@ audio_mux(struct bttv *btv, int input, i
 {
 	int gpio_val, signal;
 	struct v4l2_control ctrl;
-	struct i2c_client *c;
 
 	gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
 		   bttv_tvcards[btv->c.type].gpiomask);
@@ -1180,7 +1179,16 @@ audio_mux(struct bttv *btv, int input, i
 	else
 		gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
 
-	gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+	switch (btv->c.type) {
+	case BTTV_BOARD_VOODOOTV_FM:
+	case BTTV_BOARD_VOODOOTV_200:
+		gpio_val = bttv_tda9880_setnorm(btv, gpio_val);
+		break;
+
+	default:
+		gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+	}
+
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
 	if (in_interrupt())
@@ -1188,10 +1196,9 @@ audio_mux(struct bttv *btv, int input, i
 
 	ctrl.id = V4L2_CID_AUDIO_MUTE;
 	ctrl.value = btv->mute;
-	bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
-	c = btv->i2c_msp34xx_client;
-	if (c) {
-		struct v4l2_routing route;
+	bttv_call_all(btv, core, s_ctrl, &ctrl);
+	if (btv->sd_msp34xx) {
+		u32 in;
 
 		/* Note: the inputs tuner/radio/extern/intern are translated
 		   to msp routings. This assumes common behavior for all msp3400
@@ -1200,11 +1207,11 @@ audio_mux(struct bttv *btv, int input, i
 		   For now this is sufficient. */
 		switch (input) {
 		case TVAUDIO_INPUT_RADIO:
-			route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_EXTERN:
-			route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_INTERN:
@@ -1213,7 +1220,7 @@ audio_mux(struct bttv *btv, int input, i
 			   input is the BTTV_BOARD_AVERMEDIA98. I wonder how
 			   that was tested. My guess is that the whole INTERN
 			   input does not work. */
-			route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+			in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
 				    MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
 			break;
 		case TVAUDIO_INPUT_TUNER:
@@ -1222,22 +1229,18 @@ audio_mux(struct bttv *btv, int input, i
 			   is the only difference between the VOODOOTV_FM
 			   and VOODOOTV_200 */
 			if (btv->c.type == BTTV_BOARD_VOODOOTV_200)
-				route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
+				in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \
 					MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER);
 			else
-				route.input = MSP_INPUT_DEFAULT;
+				in = MSP_INPUT_DEFAULT;
 			break;
 		}
-		route.output = MSP_OUTPUT_DEFAULT;
-		c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+		v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing,
+			       in, MSP_OUTPUT_DEFAULT, 0);
 	}
-	c = btv->i2c_tvaudio_client;
-	if (c) {
-		struct v4l2_routing route;
-
-		route.input = input;
-		route.output = 0;
-		c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	if (btv->sd_tvaudio) {
+		v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing,
+				input, 0, 0);
 	}
 	return 0;
 }
@@ -1277,7 +1280,7 @@ bttv_crop_calc_limits(struct bttv_crop *
 }
 
 static void
-bttv_crop_reset(struct bttv_crop *c, int norm)
+bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
 {
 	c->rect = bttv_tvnorms[norm].cropcap.defrect;
 	bttv_crop_calc_limits(c);
@@ -1290,16 +1293,13 @@ set_tvnorm(struct bttv *btv, unsigned in
 	const struct bttv_tvnorm *tvnorm;
 	v4l2_std_id id;
 
-	if (norm < 0 || norm >= BTTV_TVNORMS)
-		return -EINVAL;
+	BUG_ON(norm >= BTTV_TVNORMS);
+	BUG_ON(btv->tvnorm >= BTTV_TVNORMS);
 
 	tvnorm = &bttv_tvnorms[norm];
 
-	if (btv->tvnorm < 0 ||
-	    btv->tvnorm >= BTTV_TVNORMS ||
-	    0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap,
-			&tvnorm->cropcap,
-			sizeof (tvnorm->cropcap))) {
+	if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+		    sizeof (tvnorm->cropcap))) {
 		bttv_crop_reset(&btv->crop[0], norm);
 		btv->crop[1] = btv->crop[0]; /* current = default */
 
@@ -1322,11 +1322,11 @@ set_tvnorm(struct bttv *btv, unsigned in
 	switch (btv->c.type) {
 	case BTTV_BOARD_VOODOOTV_FM:
 	case BTTV_BOARD_VOODOOTV_200:
-		bttv_tda9880_setnorm(btv,norm);
+		bttv_tda9880_setnorm(btv, gpio_read());
 		break;
 	}
 	id = tvnorm->v4l2_id;
-	bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id);
+	bttv_call_all(btv, core, s_std, id);
 
 	return 0;
 }
@@ -1350,8 +1350,8 @@ set_input(struct bttv *btv, unsigned int
 	} else {
 		video_mux(btv,input);
 	}
-	audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
-		       TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
+	audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ?
+			 TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN);
 	set_tvnorm(btv, norm);
 }
 
@@ -1470,7 +1470,7 @@ static int bttv_g_ctrl(struct file *file
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c);
+		bttv_call_all(btv, core, g_ctrl, c);
 		break;
 
 	case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1544,12 +1544,12 @@ static int bttv_s_ctrl(struct file *file
 		if (btv->volume_gpio)
 			btv->volume_gpio(btv, c->value);
 
-		bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+		bttv_call_all(btv, core, s_ctrl, c);
 		break;
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+		bttv_call_all(btv, core, s_ctrl, c);
 		break;
 
 	case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1888,20 +1888,15 @@ static int bttv_enum_input(struct file *
 {
 	struct bttv_fh *fh = priv;
 	struct bttv *btv = fh->btv;
-	unsigned int n;
-
-	n = i->index;
+	int n;
 
-	if (n >= bttv_tvcards[btv->c.type].video_inputs)
+	if (i->index >= bttv_tvcards[btv->c.type].video_inputs)
 		return -EINVAL;
 
-	memset(i, 0, sizeof(*i));
-
-	i->index    = n;
 	i->type     = V4L2_INPUT_TYPE_CAMERA;
 	i->audioset = 1;
 
-	if (i->index == bttv_tvcards[btv->c.type].tuner) {
+	if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {
 		sprintf(i->name, "Television");
 		i->type  = V4L2_INPUT_TYPE_TUNER;
 		i->tuner = 0;
@@ -1965,14 +1960,14 @@ static int bttv_s_tuner(struct file *fil
 	if (0 != err)
 		return err;
 
-	if (UNSET == bttv_tvcards[btv->c.type].tuner)
+	if (btv->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
 
 	if (0 != t->index)
 		return -EINVAL;
 
 	mutex_lock(&btv->lock);
-	bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+	bttv_call_all(btv, tuner, s_tuner, t);
 
 	if (btv->audio_mode_gpio)
 		btv->audio_mode_gpio(btv, t, 1);
@@ -2017,7 +2012,7 @@ static int bttv_s_frequency(struct file
 		return -EINVAL;
 	mutex_lock(&btv->lock);
 	btv->freq = f->frequency;
-	bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f);
+	bttv_call_all(btv, tuner, s_frequency, f);
 	if (btv->has_matchbox && btv->radio_user)
 		tea5757_set_freq(btv, btv->freq);
 	mutex_unlock(&btv->lock);
@@ -2031,7 +2026,7 @@ static int bttv_log_status(struct file *
 
 	printk(KERN_INFO "bttv%d: ========  START STATUS CARD #%d  ========\n",
 			btv->c.nr, btv->c.nr);
-	bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
+	bttv_call_all(btv, core, log_status);
 	printk(KERN_INFO "bttv%d: ========  END STATUS CARD   #%d  ========\n",
 			btv->c.nr, btv->c.nr);
 	return 0;
@@ -2659,8 +2654,7 @@ static int bttv_querycap(struct file *fi
 	if (no_overlay <= 0)
 		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
 
-	if (bttv_tvcards[btv->c.type].tuner != UNSET &&
-	    bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
+	if (btv->tuner_type != TUNER_ABSENT)
 		cap->capabilities |= V4L2_CAP_TUNER;
 	return 0;
 }
@@ -2927,13 +2921,9 @@ static int bttv_g_parm(struct file *file
 {
 	struct bttv_fh *fh = f;
 	struct bttv *btv = fh->btv;
-	struct v4l2_standard s;
 
-	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
-				 bttv_tvnorms[btv->tvnorm].name);
-	parm->parm.capture.timeperframe = s.frameperiod;
+	v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
+				    &parm->parm.capture.timeperframe);
 	return 0;
 }
 
@@ -2943,15 +2933,14 @@ static int bttv_g_tuner(struct file *fil
 	struct bttv_fh *fh = priv;
 	struct bttv *btv = fh->btv;
 
-	if (UNSET == bttv_tvcards[btv->c.type].tuner)
+	if (btv->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
 	if (0 != t->index)
 		return -EINVAL;
 
 	mutex_lock(&btv->lock);
-	memset(t, 0, sizeof(*t));
 	t->rxsubchans = V4L2_TUNER_SUB_MONO;
-	bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+	bttv_call_all(btv, tuner, g_tuner, t);
 	strcpy(t->name, "Television");
 	t->capability = V4L2_TUNER_CAP_NORM;
 	t->type       = V4L2_TUNER_ANALOG_TV;
@@ -3212,29 +3201,19 @@ err:
 static int bttv_open(struct file *file)
 {
 	int minor = video_devdata(file)->minor;
-	struct bttv *btv = NULL;
+	struct bttv *btv = video_drvdata(file);
 	struct bttv_fh *fh;
 	enum v4l2_buf_type type = 0;
-	unsigned int i;
 
 	dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
 
 	lock_kernel();
-	for (i = 0; i < bttv_num; i++) {
-		if (bttvs[i].video_dev &&
-		    bttvs[i].video_dev->minor == minor) {
-			btv = &bttvs[i];
-			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-			break;
-		}
-		if (bttvs[i].vbi_dev &&
-		    bttvs[i].vbi_dev->minor == minor) {
-			btv = &bttvs[i];
-			type = V4L2_BUF_TYPE_VBI_CAPTURE;
-			break;
-		}
-	}
-	if (NULL == btv) {
+	if (btv->video_dev->minor == minor) {
+		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	} else if (btv->vbi_dev->minor == minor) {
+		type = V4L2_BUF_TYPE_VBI_CAPTURE;
+	} else {
+		WARN_ON(1);
 		unlock_kernel();
 		return -ENODEV;
 	}
@@ -3424,20 +3403,14 @@ static struct video_device bttv_video_te
 static int radio_open(struct file *file)
 {
 	int minor = video_devdata(file)->minor;
-	struct bttv *btv = NULL;
+	struct bttv *btv = video_drvdata(file);
 	struct bttv_fh *fh;
-	unsigned int i;
 
 	dprintk("bttv: open minor=%d\n",minor);
 
 	lock_kernel();
-	for (i = 0; i < bttv_num; i++) {
-		if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
-			btv = &bttvs[i];
-			break;
-		}
-	}
-	if (NULL == btv) {
+	WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
+	if (!btv->radio_dev || btv->radio_dev->minor != minor) {
 		unlock_kernel();
 		return -ENODEV;
 	}
@@ -3458,7 +3431,7 @@ static int radio_open(struct file *file)
 
 	btv->radio_user++;
 
-	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+	bttv_call_all(btv, tuner, s_radio);
 	audio_input(btv,TVAUDIO_INPUT_RADIO);
 
 	mutex_unlock(&btv->lock);
@@ -3478,7 +3451,7 @@ static int radio_release(struct file *fi
 
 	btv->radio_user--;
 
-	bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+	bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
 
 	return 0;
 }
@@ -3503,16 +3476,15 @@ static int radio_g_tuner(struct file *fi
 	struct bttv_fh *fh = priv;
 	struct bttv *btv = fh->btv;
 
-	if (UNSET == bttv_tvcards[btv->c.type].tuner)
+	if (btv->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
 	if (0 != t->index)
 		return -EINVAL;
 	mutex_lock(&btv->lock);
-	memset(t, 0, sizeof(*t));
 	strcpy(t->name, "Radio");
 	t->type = V4L2_TUNER_RADIO;
 
-	bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+	bttv_call_all(btv, tuner, g_tuner, t);
 
 	if (btv->audio_mode_gpio)
 		btv->audio_mode_gpio(btv, t, 0);
@@ -3554,7 +3526,7 @@ static int radio_s_tuner(struct file *fi
 	if (0 != t->index)
 		return -EINVAL;
 
-	bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+	bttv_call_all(btv, tuner, g_tuner, t);
 	return 0;
 }
 
@@ -3615,7 +3587,7 @@ static ssize_t radio_read(struct file *f
 	cmd.instance = file;
 	cmd.result = -ENODEV;
 
-	bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+	bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
 
 	return cmd.result;
 }
@@ -3628,7 +3600,7 @@ static unsigned int radio_poll(struct fi
 	cmd.instance = file;
 	cmd.event_list = wait;
 	cmd.result = -ENODEV;
-	bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+	bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
 
 	return cmd.result;
 }
@@ -3712,14 +3684,14 @@ static void bttv_risc_disasm(struct bttv
 	unsigned int i,j,n;
 
 	printk("%s: risc disasm: %p [dma=0x%08lx]\n",
-	       btv->c.name, risc->cpu, (unsigned long)risc->dma);
+	       btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma);
 	for (i = 0; i < (risc->size >> 2); i += n) {
-		printk("%s:   0x%lx: ", btv->c.name,
+		printk("%s:   0x%lx: ", btv->c.v4l2_dev.name,
 		       (unsigned long)(risc->dma + (i<<2)));
 		n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
 		for (j = 1; j < n; j++)
 			printk("%s:   0x%lx: 0x%08x [ arg #%d ]\n",
-			       btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
+			       btv->c.v4l2_dev.name, (unsigned long)(risc->dma + ((i+j)<<2)),
 			       risc->cpu[i+j], j);
 		if (0 == risc->cpu[i])
 			break;
@@ -4195,9 +4167,10 @@ static struct video_device *vdev_init(st
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->parent  = &btv->c.pci->dev;
+	vfd->v4l2_dev = &btv->c.v4l2_dev;
 	vfd->release = video_device_release;
 	vfd->debug   = bttv_debug;
+	video_set_drvdata(vfd, btv);
 	snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
 		 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
 		 type_name, bttv_tvcards[btv->c.type].name);
@@ -4307,10 +4280,14 @@ static int __devinit bttv_probe(struct p
 	if (bttv_num == BTTV_MAX)
 		return -ENOMEM;
 	printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
-	btv=&bttvs[bttv_num];
-	memset(btv,0,sizeof(*btv));
+	bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL);
+	if (btv == NULL) {
+		printk(KERN_ERR "bttv: out of memory.\n");
+		return -ENOMEM;
+	}
 	btv->c.nr  = bttv_num;
-	sprintf(btv->c.name,"bttv%d",btv->c.nr);
+	snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name),
+			"bttv%d", btv->c.nr);
 
 	/* initialize structs / fill in defaults */
 	mutex_init(&btv->lock);
@@ -4340,14 +4317,14 @@ static int __devinit bttv_probe(struct p
 		       btv->c.nr);
 		return -EIO;
 	}
-	if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
 		       btv->c.nr);
 		return -EIO;
 	}
 	if (!request_mem_region(pci_resource_start(dev,0),
 				pci_resource_len(dev,0),
-				btv->c.name)) {
+				btv->c.v4l2_dev.name)) {
 		printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n",
 		       btv->c.nr,
 		       (unsigned long long)pci_resource_start(dev,0));
@@ -4355,7 +4332,12 @@ static int __devinit bttv_probe(struct p
 	}
 	pci_set_master(dev);
 	pci_set_command(dev);
-	pci_set_drvdata(dev,btv);
+
+	result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev);
+	if (result < 0) {
+		printk(KERN_WARNING "bttv%d: v4l2_device_register() failed\n", btv->c.nr);
+		goto fail0;
+	}
 
 	pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
@@ -4379,7 +4361,7 @@ static int __devinit bttv_probe(struct p
 	/* disable irqs, register irq handler */
 	btwrite(0, BT848_INT_MASK);
 	result = request_irq(btv->c.pci->irq, bttv_irq,
-			     IRQF_SHARED | IRQF_DISABLED,btv->c.name,(void *)btv);
+	    IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv);
 	if (result < 0) {
 		printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
 		       bttv_num,btv->c.pci->irq);
@@ -4463,21 +4445,24 @@ static int __devinit bttv_probe(struct p
 	bttv_num++;
 	return 0;
 
- fail2:
+fail2:
 	free_irq(btv->c.pci->irq,btv);
 
- fail1:
+fail1:
+	v4l2_device_unregister(&btv->c.v4l2_dev);
+
+fail0:
 	if (btv->bt848_mmio)
 		iounmap(btv->bt848_mmio);
 	release_mem_region(pci_resource_start(btv->c.pci,0),
 			   pci_resource_len(btv->c.pci,0));
-	pci_set_drvdata(dev,NULL);
 	return result;
 }
 
 static void __devexit bttv_remove(struct pci_dev *pci_dev)
 {
-	struct bttv *btv = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct bttv *btv = to_bttv(v4l2_dev);
 
 	if (bttv_verbose)
 		printk("bttv%d: unloading\n",btv->c.nr);
@@ -4511,14 +4496,18 @@ static void __devexit bttv_remove(struct
 	release_mem_region(pci_resource_start(btv->c.pci,0),
 			   pci_resource_len(btv->c.pci,0));
 
-	pci_set_drvdata(pci_dev, NULL);
+	v4l2_device_unregister(&btv->c.v4l2_dev);
+	bttvs[btv->c.nr] = NULL;
+	kfree(btv);
+
 	return;
 }
 
 #ifdef CONFIG_PM
 static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
 {
-	struct bttv *btv = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct bttv *btv = to_bttv(v4l2_dev);
 	struct bttv_buffer_set idle;
 	unsigned long flags;
 
@@ -4553,7 +4542,8 @@ static int bttv_suspend(struct pci_dev *
 
 static int bttv_resume(struct pci_dev *pci_dev)
 {
-	struct bttv *btv = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct bttv *btv = to_bttv(v4l2_dev);
 	unsigned long flags;
 	int err;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv.h linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,8 +14,9 @@
 #ifndef _BTTV_H_
 #define _BTTV_H_
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
+#include <media/v4l2-device.h>
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
 #include <media/i2c-addr.h>
@@ -180,6 +181,10 @@
 #define BTTV_BOARD_VD012		   0x99
 #define BTTV_BOARD_VD012_X1		   0x9a
 #define BTTV_BOARD_VD012_X2		   0x9b
+#define BTTV_BOARD_IVCE8784		   0x9c
+#define BTTV_BOARD_GEOVISION_GV800S	   0x9d
+#define BTTV_BOARD_GEOVISION_GV800S_SL	   0x9e
+#define BTTV_BOARD_PV183                   0x9f
 
 
 /* more card-specific defines */
@@ -191,12 +196,9 @@
 #define WINVIEW_PT2254_DATA 0x20
 #define WINVIEW_PT2254_STROBE 0x80
 
-/* digital_mode */
-#define DIGITAL_MODE_VIDEO 1
-#define DIGITAL_MODE_CAMERA 2
-
 struct bttv_core {
 	/* device structs */
+	struct v4l2_device   v4l2_dev;
 	struct pci_dev       *pci;
 	struct i2c_adapter   i2c_adap;
 	struct list_head     subs;     /* struct bttv_sub_device */
@@ -204,59 +206,79 @@ struct bttv_core {
 	/* device config */
 	unsigned int         nr;       /* dev nr (for printk("bttv%d: ...");  */
 	unsigned int         type;     /* card type (pointer into tvcards[])  */
-	char                 name[8];  /* dev name */
 };
 
 struct bttv;
 
-
-struct tvcard
-{
+struct tvcard {
 	char *name;
-	unsigned int video_inputs;
-	unsigned int audio_inputs;
-	unsigned int tuner;
-	unsigned int svhs;
-	unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
+	void (*volume_gpio)(struct bttv *btv, __u16 volume);
+	void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
+	void (*muxsel_hook)(struct bttv *btv, unsigned int input);
+
+	/* MUX bits for each input, two bits per input starting with the LSB */
+	u32 muxsel; /* Use MUXSEL() to set */
+
 	u32 gpiomask;
-	u32 muxsel[16];
 	u32 gpiomux[4];  /* Tuner, Radio, external, internal */
 	u32 gpiomute;    /* GPIO mute setting */
 	u32 gpiomask2;   /* GPIO MUX mask */
 
+	unsigned int tuner_type;
+	u8 tuner_addr;
+	u8 video_inputs;	/* Number of inputs */
+	unsigned int svhs:4;	/* Which input is s-video */
+#define NO_SVHS	15
+	unsigned int pll:2;
+#define PLL_NONE 0
+#define PLL_28   1
+#define PLL_35   2
+
 	/* i2c audio flags */
 	unsigned int no_msp34xx:1;
 	unsigned int no_tda9875:1;
 	unsigned int no_tda7432:1;
 	unsigned int needs_tvaudio:1;
 	unsigned int msp34xx_alt:1;
+	/* Note: currently no card definition needs to mark the presence
+	   of a RDS saa6588 chip. If this is ever needed, then add a new
+	   'has_saa6588' bit here. */
 
-	/* flag: video pci function is unused */
-	unsigned int no_video:1;
+	unsigned int no_video:1; /* video pci function is unused */
 	unsigned int has_dvb:1;
 	unsigned int has_remote:1;
+	unsigned int has_radio:1;
+	unsigned int has_dig_in:1; /* Has digital input (always last input) */
 	unsigned int no_gpioirq:1;
-
-	/* other settings */
-	unsigned int pll;
-#define PLL_NONE 0
-#define PLL_28   1
-#define PLL_35   2
-
-	unsigned int tuner_type;
-	unsigned int tuner_addr;
-	unsigned int radio_addr;
-
-	unsigned int has_radio;
-
-	void (*volume_gpio)(struct bttv *btv, __u16 volume);
-	void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
-	void (*muxsel_hook)(struct bttv *btv, unsigned int input);
 };
 
 extern struct tvcard bttv_tvcards[];
 
+/*
+ * This bit of cpp voodoo is used to create a macro with a variable number of
+ * arguments (1 to 16).  It will pack each argument into a word two bits at a
+ * time.  It can't be a function because it needs to be compile time constant to
+ * initialize structures.  Since each argument must fit in two bits, it's ok
+ * that they are changed to octal.  One should not use hex number, macros, or
+ * anything else with this macro.  Just use plain integers from 0 to 3.
+ */
+#define _MUXSELf(a)      	0##a << 30
+#define _MUXSELe(a, b...)	0##a << 28 | _MUXSELf(b)
+#define _MUXSELd(a, b...)	0##a << 26 | _MUXSELe(b)
+#define _MUXSELc(a, b...)	0##a << 24 | _MUXSELd(b)
+#define _MUXSELb(a, b...)	0##a << 22 | _MUXSELc(b)
+#define _MUXSELa(a, b...)	0##a << 20 | _MUXSELb(b)
+#define _MUXSEL9(a, b...)	0##a << 18 | _MUXSELa(b)
+#define _MUXSEL8(a, b...)	0##a << 16 | _MUXSEL9(b)
+#define _MUXSEL7(a, b...)	0##a << 14 | _MUXSEL8(b)
+#define _MUXSEL6(a, b...)	0##a << 12 | _MUXSEL7(b)
+#define _MUXSEL5(a, b...)	0##a << 10 | _MUXSEL6(b)
+#define _MUXSEL4(a, b...)	0##a << 8  | _MUXSEL5(b)
+#define _MUXSEL3(a, b...)	0##a << 6  | _MUXSEL4(b)
+#define _MUXSEL2(a, b...)	0##a << 4  | _MUXSEL3(b)
+#define _MUXSEL1(a, b...)	0##a << 2  | _MUXSEL2(b)
+#define MUXSEL(a, b...)		(a | _MUXSEL1(b))
+
 /* identification / initialization of the card */
 extern void bttv_idcard(struct bttv *btv);
 extern void bttv_init_card1(struct bttv *btv);
@@ -264,7 +286,7 @@ extern void bttv_init_card2(struct bttv
 
 /* card-specific funtions */
 extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
+extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits);
 
 /* extra tweaks for some chipsets */
 extern void bttv_check_chipset(void);
@@ -336,7 +358,9 @@ void bttv_gpio_bits(struct bttv_core *co
 /* ---------------------------------------------------------- */
 /* i2c                                                        */
 
-extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
+#define bttv_call_all(btv, o, f, args...) \
+	v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
+
 extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
 extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
 			 unsigned char b2, int both);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,8 +36,6 @@
 #include <linux/jiffies.h>
 #include <asm/io.h>
 
-static int attach_inform(struct i2c_client *client);
-
 static int i2c_debug;
 static int i2c_hw;
 static int i2c_scan;
@@ -231,7 +229,8 @@ bttv_i2c_readbytes(struct bttv *btv, con
 
 static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
 {
-	struct bttv *btv = i2c_get_adapdata(i2c_adap);
+	struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+	struct bttv *btv = to_bttv(v4l2_dev);
 	int retval = 0;
 	int i;
 
@@ -265,52 +264,6 @@ static const struct i2c_algorithm bttv_a
 /* ----------------------------------------------------------------------- */
 /* I2C functions - common stuff                                            */
 
-static int attach_inform(struct i2c_client *client)
-{
-	struct bttv *btv = i2c_get_adapdata(client->adapter);
-	int addr=ADDR_UNSET;
-
-
-	if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
-		addr = bttv_tvcards[btv->c.type].tuner_addr;
-
-
-	if (bttv_debug)
-		printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
-			btv->c.nr, client->driver->driver.name, client->addr,
-			client->name);
-	if (!client->driver->command)
-		return 0;
-
-	if (client->driver->id == I2C_DRIVERID_MSP3400)
-		btv->i2c_msp34xx_client = client;
-	if (client->driver->id == I2C_DRIVERID_TVAUDIO)
-		btv->i2c_tvaudio_client = client;
-	if (btv->tuner_type != UNSET) {
-		struct tuner_setup tun_setup;
-
-		if ((addr==ADDR_UNSET) ||
-				(addr==client->addr)) {
-
-			tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
-			tun_setup.type = btv->tuner_type;
-			tun_setup.addr = addr;
-			bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
-		}
-
-	}
-
-	return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
-	if (0 != btv->i2c_rc)
-		return;
-	i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
-}
-
-
 /* read I2C */
 int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
 {
@@ -417,21 +370,15 @@ int __devinit init_bttv_i2c(struct bttv
 		btv->c.i2c_adap.algo_data = &btv->i2c_algo;
 	}
 	btv->c.i2c_adap.owner = THIS_MODULE;
-	btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
-	btv->c.i2c_adap.client_register = attach_inform;
 
 	btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
 	snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
 		 "bt%d #%d [%s]", btv->id, btv->c.nr,
 		 btv->use_i2c_hw ? "hw" : "sw");
 
-	i2c_set_adapdata(&btv->c.i2c_adap, btv);
+	i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
 	btv->i2c_client.adapter = &btv->c.i2c_adap;
 
-	if (bttv_tvcards[btv->c.type].no_video)
-		btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
-	if (bttv_tvcards[btv->c.type].has_dvb)
-		btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
 
 	if (btv->use_i2c_hw) {
 		btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
@@ -441,7 +388,7 @@ int __devinit init_bttv_i2c(struct bttv
 		btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
 	}
 	if (0 == btv->i2c_rc && i2c_scan)
-		do_i2c_scan(btv->c.name,&btv->i2c_client);
+		do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
 	return btv->i2c_rc;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-if.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-if.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-if.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-if.c	2009-06-09 23:05:27.000000000 -0400
@@ -47,7 +47,10 @@ struct pci_dev* bttv_get_pcidev(unsigned
 {
 	if (card >= bttv_num)
 		return NULL;
-	return bttvs[card].c.pci;
+	if (!bttvs[card])
+		return NULL;
+
+	return bttvs[card]->c.pci;
 }
 
 
@@ -59,7 +62,10 @@ int bttv_gpio_enable(unsigned int card,
 		return -EINVAL;
 	}
 
-	btv = &bttvs[card];
+	btv = bttvs[card];
+	if (!btv)
+		return -ENODEV;
+
 	gpio_inout(mask,data);
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"extern enable");
@@ -74,7 +80,9 @@ int bttv_read_gpio(unsigned int card, un
 		return -EINVAL;
 	}
 
-	btv = &bttvs[card];
+	btv = bttvs[card];
+	if (!btv)
+		return -ENODEV;
 
 	if(btv->shutdown) {
 		return -ENODEV;
@@ -94,7 +102,9 @@ int bttv_write_gpio(unsigned int card, u
 		return -EINVAL;
 	}
 
-	btv = &bttvs[card];
+	btv = bttvs[card];
+	if (!btv)
+		return -ENODEV;
 
 /* prior setting BT848_GPIO_REG_INP is (probably) not needed
    because direct input is set on init */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttvp.h linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttvp.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttvp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttvp.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,13 +26,12 @@
 #define _BTTVP_H_
 
 #include <linux/version.h>
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,17)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,18)
 
 #include <linux/types.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
 #include <linux/pci.h>
 #include <linux/input.h>
 #include <linux/mutex.h>
@@ -135,7 +134,7 @@ struct bttv_buffer {
 
 	/* bttv specific */
 	const struct bttv_format   *fmt;
-	int                        tvnorm;
+	unsigned int               tvnorm;
 	int                        btformat;
 	int                        btswap;
 	struct bttv_geometry       geo;
@@ -154,7 +153,7 @@ struct bttv_buffer_set {
 };
 
 struct bttv_overlay {
-	int                    tvnorm;
+	unsigned int           tvnorm;
 	struct v4l2_rect       w;
 	enum v4l2_field        field;
 	struct v4l2_clip       *clips;
@@ -174,7 +173,7 @@ struct bttv_vbi_fmt {
 };
 
 /* bttv-vbi.c */
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm);
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm);
 
 struct bttv_crop {
 	/* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
@@ -329,7 +328,8 @@ struct bttv {
 	unsigned int cardid;   /* pci subsystem id (bt878 based ones) */
 	unsigned int tuner_type;  /* tuner chip type */
 	unsigned int tda9887_conf;
-	unsigned int svhs;
+	unsigned int svhs, dig;
+	unsigned int has_saa6588:1;
 	struct bttv_pll_info pll;
 	int triton1;
 	int gpioirq;
@@ -353,8 +353,8 @@ struct bttv {
 	int                        i2c_state, i2c_rc;
 	int                        i2c_done;
 	wait_queue_head_t          i2c_queue;
-	struct i2c_client 	  *i2c_msp34xx_client;
-	struct i2c_client 	  *i2c_tvaudio_client;
+	struct v4l2_subdev 	  *sd_msp34xx;
+	struct v4l2_subdev 	  *sd_tvaudio;
 
 	/* video4linux (1) */
 	struct video_device *video_dev;
@@ -378,7 +378,8 @@ struct bttv {
 	unsigned int audio;
 	unsigned int mute;
 	unsigned long freq;
-	int tvnorm,hue,contrast,bright,saturation;
+	unsigned int tvnorm;
+	int hue, contrast, bright, saturation;
 	struct v4l2_framebuffer fbuf;
 	unsigned int field_count;
 
@@ -458,10 +459,21 @@ struct bttv {
 	__s32			crop_start;
 };
 
+static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct bttv, c.v4l2_dev);
+}
+
 /* our devices */
 #define BTTV_MAX 32
 extern unsigned int bttv_num;
-extern struct bttv bttvs[BTTV_MAX];
+extern struct bttv *bttvs[BTTV_MAX];
+
+static inline unsigned int bttv_muxsel(const struct bttv *btv,
+				       unsigned int input)
+{
+	return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
+}
 
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-risc.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-risc.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-risc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-risc.c	2009-06-09 23:05:27.000000000 -0400
@@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, stru
 	int totalwidth   = tvnorm->totalwidth;
 	int scaledtwidth = tvnorm->scaledtwidth;
 
-	if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+	if (btv->input == btv->dig) {
 		swidth       = 720;
 		totalwidth   = 858;
 		scaledtwidth = 858;
@@ -391,7 +391,7 @@ bttv_calc_geo		(struct bttv *
 	     && crop->width == tvnorm->cropcap.defrect.width
 	     && crop->height == tvnorm->cropcap.defrect.height
 	     && width <= tvnorm->swidth /* see PAL-Nc et al */)
-	    || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+	    || btv->input == btv->dig) {
 		bttv_calc_geo_old(btv, geo, width, height,
 				  both_fields, tvnorm);
 		return;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/bttv-vbi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/bttv-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file
 	return 0;
 }
 
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm)
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
 {
 	const struct bttv_tvnorm *tvnorm;
 	unsigned int real_samples_per_line;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/bt8xx/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/bt8xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@ config VIDEO_BT848
 	select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
-	select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
 	---help---
 	  Support for BT848 based frame grabber/overlay boards. This includes
 	  the Miro, Hauppauge and STB boards. Please read the material in
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cafe_ccic.c linux-libre-2.6.30-gnu1/drivers/media/video/cafe_ccic.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cafe_ccic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cafe_ccic.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,12 @@
  *
  * Written by Jonathan Corbet, corbet@lwn.net.
  *
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
+ *
  * This file may be distributed under the terms of the GNU General
  * Public License, version 2.
  */
@@ -25,7 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
 #include <linux/device.h>
@@ -33,7 +39,6 @@
 #include <linux/list.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
-#include <linux/debugfs.h>
 #include <linux/jiffies.h>
 #include <linux/vmalloc.h>
 
@@ -136,6 +141,7 @@ struct cafe_sio_buffer {
  */
 struct cafe_camera
 {
+	struct v4l2_device v4l2_dev;
 	enum cafe_state state;
 	unsigned long flags;   		/* Buffer status, mainly (dev_lock) */
 	int users;			/* How many open FDs */
@@ -145,9 +151,10 @@ struct cafe_camera
 	 * Subsystem structures.
 	 */
 	struct pci_dev *pdev;
-	struct video_device v4ldev;
+	struct video_device vdev;
 	struct i2c_adapter i2c_adapter;
-	struct i2c_client *sensor;
+	struct v4l2_subdev *sensor;
+	unsigned short sensor_addr;
 
 	unsigned char __iomem *regs;
 	struct list_head dev_list;	/* link to other devices */
@@ -180,10 +187,6 @@ struct cafe_camera
 	/* Misc */
 	wait_queue_head_t smbus_wait;	/* Waiting on i2c events */
 	wait_queue_head_t iowait;	/* Waiting on frame data */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	struct dentry *dfs_regs;
-	struct dentry *dfs_cam_regs;
-#endif
 };
 
 /*
@@ -195,6 +198,13 @@ struct cafe_camera
 #define CF_DMA_ACTIVE	 3	/* A frame is incoming */
 #define CF_CONFIG_NEEDED 4	/* Must configure hardware */
 
+#define sensor_call(cam, o, f, args...) \
+	v4l2_subdev_call(cam->sensor, o, f, ##args)
+
+static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
+{
+	return container_of(dev, struct cafe_camera, v4l2_dev);
+}
 
 
 /*
@@ -238,59 +248,7 @@ static void cafe_set_config_needed(struc
 
 
 /* ---------------------------------------------------------------------*/
-/*
- * We keep a simple list of known devices to search at open time.
- */
-static LIST_HEAD(cafe_dev_list);
-static DEFINE_MUTEX(cafe_dev_list_lock);
-
-static void cafe_add_dev(struct cafe_camera *cam)
-{
-	mutex_lock(&cafe_dev_list_lock);
-	list_add_tail(&cam->dev_list, &cafe_dev_list);
-	mutex_unlock(&cafe_dev_list_lock);
-}
 
-static void cafe_remove_dev(struct cafe_camera *cam)
-{
-	mutex_lock(&cafe_dev_list_lock);
-	list_del(&cam->dev_list);
-	mutex_unlock(&cafe_dev_list_lock);
-}
-
-static struct cafe_camera *cafe_find_dev(int minor)
-{
-	struct cafe_camera *cam;
-
-	mutex_lock(&cafe_dev_list_lock);
-	list_for_each_entry(cam, &cafe_dev_list, dev_list) {
-		if (cam->v4ldev.minor == minor)
-			goto done;
-	}
-	cam = NULL;
-  done:
-	mutex_unlock(&cafe_dev_list_lock);
-	return cam;
-}
-
-
-static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev)
-{
-	struct cafe_camera *cam;
-
-	mutex_lock(&cafe_dev_list_lock);
-	list_for_each_entry(cam, &cafe_dev_list, dev_list) {
-		if (cam->pdev == pdev)
-			goto done;
-	}
-	cam = NULL;
-  done:
-	mutex_unlock(&cafe_dev_list_lock);
-	return cam;
-}
-
-
-/* ------------------------------------------------------------------------ */
 /*
  * Device register I/O
  */
@@ -481,18 +439,11 @@ static int cafe_smbus_xfer(struct i2c_ad
 		unsigned short flags, char rw, u8 command,
 		int size, union i2c_smbus_data *data)
 {
-	struct cafe_camera *cam = i2c_get_adapdata(adapter);
+	struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+	struct cafe_camera *cam = to_cam(v4l2_dev);
 	int ret = -EINVAL;
 
 	/*
-	 * Refuse to talk to anything but OV cam chips.  We should
-	 * never even see an attempt to do so, but one never knows.
-	 */
-	if (cam->sensor && addr != cam->sensor->addr) {
-		cam_err(cam, "funky smbus addr %d\n", addr);
-		return -EINVAL;
-	}
-	/*
 	 * This interface would appear to only do byte data ops.  OK
 	 * it can do word too, but the cam chip has no use for that.
 	 */
@@ -530,38 +481,9 @@ static struct i2c_algorithm cafe_smbus_a
 };
 
 /* Somebody is on the bus */
-static int cafe_cam_init(struct cafe_camera *cam);
 static void cafe_ctlr_stop_dma(struct cafe_camera *cam);
 static void cafe_ctlr_power_down(struct cafe_camera *cam);
 
-static int cafe_smbus_attach(struct i2c_client *client)
-{
-	struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
-	/*
-	 * Don't talk to chips we don't recognize.
-	 */
-	if (client->driver->id == I2C_DRIVERID_OV7670) {
-		cam->sensor = client;
-		return cafe_cam_init(cam);
-	}
-	return -EINVAL;
-}
-
-static int cafe_smbus_detach(struct i2c_client *client)
-{
-	struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
-	if (cam->sensor == client) {
-		cafe_ctlr_stop_dma(cam);
-		cafe_ctlr_power_down(cam);
-		cam_err(cam, "lost the sensor!\n");
-		cam->sensor = NULL;  /* Bummer, no camera */
-		cam->state = S_NOTREADY;
-	}
-	return 0;
-}
-
 static int cafe_smbus_setup(struct cafe_camera *cam)
 {
 	struct i2c_adapter *adap = &cam->i2c_adapter;
@@ -570,12 +492,10 @@ static int cafe_smbus_setup(struct cafe_
 	cafe_smbus_enable_irq(cam);
 	adap->id = I2C_HW_SMBUS_CAFE;
 	adap->owner = THIS_MODULE;
-	adap->client_register = cafe_smbus_attach;
-	adap->client_unregister = cafe_smbus_detach;
 	adap->algo = &cafe_smbus_algo;
 	strcpy(adap->name, "cafe_ccic");
 	adap->dev.parent = &cam->pdev->dev;
-	i2c_set_adapdata(adap, cam);
+	i2c_set_adapdata(adap, &cam->v4l2_dev);
 	ret = i2c_add_adapter(adap);
 	if (ret)
 		printk(KERN_ERR "Unable to register cafe i2c adapter\n");
@@ -809,9 +729,9 @@ static void cafe_ctlr_power_up(struct ca
 	 * Control 1 is power down, set to 0 to operate.
 	 */
 	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
-//	mdelay(1); /* Marvell says 1ms will do it */
+/*	mdelay(1); */ /* Marvell says 1ms will do it */
 	cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
-//	mdelay(1); /* Enough? */
+/*	mdelay(1); */ /* Enough? */
 	spin_unlock_irqrestore(&cam->dev_lock, flags);
 	msleep(5); /* Just to be sure */
 }
@@ -833,23 +753,9 @@ static void cafe_ctlr_power_down(struct
  * Communications with the sensor.
  */
 
-static int __cafe_cam_cmd(struct cafe_camera *cam, int cmd, void *arg)
-{
-	struct i2c_client *sc = cam->sensor;
-	int ret;
-
-	if (sc == NULL || sc->driver == NULL || sc->driver->command == NULL)
-		return -EINVAL;
-	ret = sc->driver->command(sc, cmd, arg);
-	if (ret == -EPERM) /* Unsupported command */
-		return 0;
-	return ret;
-}
-
 static int __cafe_cam_reset(struct cafe_camera *cam)
 {
-	int zero = 0;
-	return __cafe_cam_cmd(cam, VIDIOC_INT_RESET, &zero);
+	return sensor_call(cam, core, reset, 0);
 }
 
 /*
@@ -868,15 +774,15 @@ static int cafe_cam_init(struct cafe_cam
 	ret = __cafe_cam_reset(cam);
 	if (ret)
 		goto out;
+	chip.ident = V4L2_IDENT_NONE;
 	chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
-	chip.match.addr = cam->sensor->addr;
-	ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip);
+	chip.match.addr = cam->sensor_addr;
+	ret = sensor_call(cam, core, g_chip_ident, &chip);
 	if (ret)
 		goto out;
 	cam->sensor_type = chip.ident;
-//	if (cam->sensor->addr != OV7xx0_SID) {
 	if (cam->sensor_type != V4L2_IDENT_OV7670) {
-		cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr);
+		cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -900,21 +806,21 @@ static int cafe_cam_set_flip(struct cafe
 	memset(&ctrl, 0, sizeof(ctrl));
 	ctrl.id = V4L2_CID_VFLIP;
 	ctrl.value = flip;
-	return __cafe_cam_cmd(cam, VIDIOC_S_CTRL, &ctrl);
+	return sensor_call(cam, core, s_ctrl, &ctrl);
 }
 
 
 static int cafe_cam_configure(struct cafe_camera *cam)
 {
 	struct v4l2_format fmt;
-	int ret, zero = 0;
+	int ret;
 
 	if (cam->state != S_IDLE)
 		return -EINVAL;
 	fmt.fmt.pix = cam->pix_format;
-	ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero);
+	ret = sensor_call(cam, core, init, 0);
 	if (ret == 0)
-		ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt);
+		ret = sensor_call(cam, video, s_fmt, &fmt);
 	/*
 	 * OV7670 does weird things if flip is set *before* format...
 	 */
@@ -1246,8 +1152,6 @@ static int cafe_vidioc_reqbufs(struct fi
 	 * Make sure it's something we can do.  User pointers could be
 	 * implemented without great pain, but that's not been done yet.
 	 */
-	if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 	if (req->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 	/*
@@ -1311,9 +1215,7 @@ static int cafe_vidioc_querybuf(struct f
 	int ret = -EINVAL;
 
 	mutex_lock(&cam->s_mutex);
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		goto out;
-	if (buf->index < 0 || buf->index >= cam->n_sbufs)
+	if (buf->index >= cam->n_sbufs)
 		goto out;
 	*buf = cam->sb_bufs[buf->index].v4lbuf;
 	ret = 0;
@@ -1331,9 +1233,7 @@ static int cafe_vidioc_qbuf(struct file
 	unsigned long flags;
 
 	mutex_lock(&cam->s_mutex);
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		goto out;
-	if (buf->index < 0 || buf->index >= cam->n_sbufs)
+	if (buf->index >= cam->n_sbufs)
 		goto out;
 	sbuf = cam->sb_bufs + buf->index;
 	if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) {
@@ -1364,8 +1264,6 @@ static int cafe_vidioc_dqbuf(struct file
 	unsigned long flags;
 
 	mutex_lock(&cam->s_mutex);
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		goto out_unlock;
 	if (cam->state != S_STREAMING)
 		goto out_unlock;
 	if (list_empty(&cam->sb_full) && filp->f_flags & O_NONBLOCK) {
@@ -1474,11 +1372,8 @@ static int cafe_v4l_mmap(struct file *fi
 
 static int cafe_v4l_open(struct file *filp)
 {
-	struct cafe_camera *cam;
+	struct cafe_camera *cam = video_drvdata(filp);
 
-	cam = cafe_find_dev(video_devdata(filp)->minor);
-	if (cam == NULL)
-		return -ENODEV;
 	filp->private_data = cam;
 
 	mutex_lock(&cam->s_mutex);
@@ -1532,11 +1427,11 @@ static unsigned int cafe_v4l_poll(struct
 static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
 		struct v4l2_queryctrl *qc)
 {
-	struct cafe_camera *cam = filp->private_data;
+	struct cafe_camera *cam = priv;
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc);
+	ret = sensor_call(cam, core, queryctrl, qc);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
@@ -1545,11 +1440,11 @@ static int cafe_vidioc_queryctrl(struct
 static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
 		struct v4l2_control *ctrl)
 {
-	struct cafe_camera *cam = filp->private_data;
+	struct cafe_camera *cam = priv;
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl);
+	ret = sensor_call(cam, core, g_ctrl, ctrl);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
@@ -1558,11 +1453,11 @@ static int cafe_vidioc_g_ctrl(struct fil
 static int cafe_vidioc_s_ctrl(struct file *filp, void *priv,
 		struct v4l2_control *ctrl)
 {
-	struct cafe_camera *cam = filp->private_data;
+	struct cafe_camera *cam = priv;
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl);
+	ret = sensor_call(cam, core, s_ctrl, ctrl);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
@@ -1601,10 +1496,8 @@ static int cafe_vidioc_enum_fmt_vid_cap(
 	struct cafe_camera *cam = priv;
 	int ret;
 
-	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_ENUM_FMT, fmt);
+	ret = sensor_call(cam, video, enum_fmt, fmt);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
@@ -1617,7 +1510,7 @@ static int cafe_vidioc_try_fmt_vid_cap(s
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_TRY_FMT, fmt);
+	ret = sensor_call(cam, video, try_fmt, fmt);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
 }
@@ -1726,7 +1619,7 @@ static int cafe_vidioc_g_parm(struct fil
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_G_PARM, parms);
+	ret = sensor_call(cam, video, g_parm, parms);
 	mutex_unlock(&cam->s_mutex);
 	parms->parm.capture.readbuffers = n_dma_bufs;
 	return ret;
@@ -1739,20 +1632,52 @@ static int cafe_vidioc_s_parm(struct fil
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
-	ret = __cafe_cam_cmd(cam, VIDIOC_S_PARM, parms);
+	ret = sensor_call(cam, video, s_parm, parms);
 	mutex_unlock(&cam->s_mutex);
 	parms->parm.capture.readbuffers = n_dma_bufs;
 	return ret;
 }
 
+static int cafe_vidioc_g_chip_ident(struct file *file, void *priv,
+		struct v4l2_dbg_chip_ident *chip)
+{
+	struct cafe_camera *cam = priv;
 
-static void cafe_v4l_dev_release(struct video_device *vd)
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+	if (v4l2_chip_match_host(&chip->match)) {
+		chip->ident = V4L2_IDENT_CAFE;
+		return 0;
+	}
+	return sensor_call(cam, core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cafe_vidioc_g_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg)
 {
-	struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev);
+	struct cafe_camera *cam = priv;
 
-	kfree(cam);
+	if (v4l2_chip_match_host(&reg->match)) {
+		reg->val = cafe_reg_read(cam, reg->reg);
+		reg->size = 4;
+		return 0;
+	}
+	return sensor_call(cam, core, g_register, reg);
 }
 
+static int cafe_vidioc_s_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg)
+{
+	struct cafe_camera *cam = priv;
+
+	if (v4l2_chip_match_host(&reg->match)) {
+		cafe_reg_write(cam, reg->reg, reg->val);
+		return 0;
+	}
+	return sensor_call(cam, core, s_register, reg);
+}
+#endif
 
 /*
  * This template device holds all of those v4l2 methods; we
@@ -1790,6 +1715,11 @@ static const struct v4l2_ioctl_ops cafe_
 	.vidioc_s_ctrl		= cafe_vidioc_s_ctrl,
 	.vidioc_g_parm		= cafe_vidioc_g_parm,
 	.vidioc_s_parm		= cafe_vidioc_s_parm,
+	.vidioc_g_chip_ident    = cafe_vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register 	= cafe_vidioc_g_register,
+	.vidioc_s_register 	= cafe_vidioc_s_register,
+#endif
 };
 
 static struct video_device cafe_v4l_template = {
@@ -1800,15 +1730,10 @@ static struct video_device cafe_v4l_temp
 
 	.fops = &cafe_v4l_fops,
 	.ioctl_ops = &cafe_v4l_ioctl_ops,
-	.release = cafe_v4l_dev_release,
+	.release = video_device_release_empty,
 };
 
 
-
-
-
-
-
 /* ---------------------------------------------------------------------- */
 /*
  * Interrupt handler stuff
@@ -1962,127 +1887,6 @@ static irqreturn_t cafe_irq(int irq, voi
 
 
 /* -------------------------------------------------------------------------- */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * Debugfs stuff.
- */
-
-static char cafe_debug_buf[1024];
-static struct dentry *cafe_dfs_root;
-
-static void cafe_dfs_setup(void)
-{
-	cafe_dfs_root = debugfs_create_dir("cafe_ccic", NULL);
-	if (IS_ERR(cafe_dfs_root)) {
-		cafe_dfs_root = NULL;  /* Never mind */
-		printk(KERN_NOTICE "cafe_ccic unable to set up debugfs\n");
-	}
-}
-
-static void cafe_dfs_shutdown(void)
-{
-	if (cafe_dfs_root)
-		debugfs_remove(cafe_dfs_root);
-}
-
-static int cafe_dfs_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t cafe_dfs_read_regs(struct file *file,
-		char __user *buf, size_t count, loff_t *ppos)
-{
-	struct cafe_camera *cam = file->private_data;
-	char *s = cafe_debug_buf;
-	int offset;
-
-	for (offset = 0; offset < 0x44; offset += 4)
-		s += sprintf(s, "%02x: %08x\n", offset,
-				cafe_reg_read(cam, offset));
-	for (offset = 0x88; offset <= 0x90; offset += 4)
-		s += sprintf(s, "%02x: %08x\n", offset,
-				cafe_reg_read(cam, offset));
-	for (offset = 0xb4; offset <= 0xbc; offset += 4)
-		s += sprintf(s, "%02x: %08x\n", offset,
-				cafe_reg_read(cam, offset));
-	for (offset = 0x3000; offset <= 0x300c; offset += 4)
-		s += sprintf(s, "%04x: %08x\n", offset,
-				cafe_reg_read(cam, offset));
-	return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
-			s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_reg_ops = {
-	.owner = THIS_MODULE,
-	.read = cafe_dfs_read_regs,
-	.open = cafe_dfs_open
-};
-
-static ssize_t cafe_dfs_read_cam(struct file *file,
-		char __user *buf, size_t count, loff_t *ppos)
-{
-	struct cafe_camera *cam = file->private_data;
-	char *s = cafe_debug_buf;
-	int offset;
-
-	if (! cam->sensor)
-		return -EINVAL;
-	for (offset = 0x0; offset < 0x8a; offset++)
-	{
-		u8 v;
-
-		cafe_smbus_read_data(cam, cam->sensor->addr, offset, &v);
-		s += sprintf(s, "%02x: %02x\n", offset, v);
-	}
-	return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
-			s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_cam_ops = {
-	.owner = THIS_MODULE,
-	.read = cafe_dfs_read_cam,
-	.open = cafe_dfs_open
-};
-
-
-
-static void cafe_dfs_cam_setup(struct cafe_camera *cam)
-{
-	char fname[40];
-
-	if (!cafe_dfs_root)
-		return;
-	sprintf(fname, "regs-%d", cam->v4ldev.num);
-	cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
-			cam, &cafe_dfs_reg_ops);
-	sprintf(fname, "cam-%d", cam->v4ldev.num);
-	cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
-			cam, &cafe_dfs_cam_ops);
-}
-
-
-static void cafe_dfs_cam_shutdown(struct cafe_camera *cam)
-{
-	if (! IS_ERR(cam->dfs_regs))
-		debugfs_remove(cam->dfs_regs);
-	if (! IS_ERR(cam->dfs_cam_regs))
-		debugfs_remove(cam->dfs_cam_regs);
-}
-
-#else
-
-#define cafe_dfs_setup()
-#define cafe_dfs_shutdown()
-#define cafe_dfs_cam_setup(cam)
-#define cafe_dfs_cam_shutdown(cam)
-#endif    /* CONFIG_VIDEO_ADV_DEBUG */
-
-
-
-
-/* ------------------------------------------------------------------------*/
 /*
  * PCI interface stuff.
  */
@@ -2100,6 +1904,10 @@ static int cafe_pci_probe(struct pci_dev
 	cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
 	if (cam == NULL)
 		goto out;
+	ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
+	if (ret)
+		goto out_free;
+
 	mutex_init(&cam->s_mutex);
 	mutex_lock(&cam->s_mutex);
 	spin_lock_init(&cam->dev_lock);
@@ -2118,14 +1926,14 @@ static int cafe_pci_probe(struct pci_dev
 	 */
 	ret = pci_enable_device(pdev);
 	if (ret)
-		goto out_free;
+		goto out_unreg;
 	pci_set_master(pdev);
 
 	ret = -EIO;
 	cam->regs = pci_iomap(pdev, 0, 0);
 	if (! cam->regs) {
 		printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
-		goto out_free;
+		goto out_unreg;
 	}
 	ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
 	if (ret)
@@ -2145,17 +1953,31 @@ static int cafe_pci_probe(struct pci_dev
 	ret = cafe_smbus_setup(cam);
 	if (ret)
 		goto out_freeirq;
+
+	cam->sensor_addr = 0x42;
+	cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
+			"ov7670", "ov7670", cam->sensor_addr);
+	if (cam->sensor == NULL) {
+		ret = -ENODEV;
+		goto out_smbus;
+	}
+	ret = cafe_cam_init(cam);
+	if (ret)
+		goto out_smbus;
+
 	/*
 	 * Get the v4l2 setup done.
 	 */
 	mutex_lock(&cam->s_mutex);
-	cam->v4ldev = cafe_v4l_template;
-	cam->v4ldev.debug = 0;
-//	cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
-	cam->v4ldev.parent = &pdev->dev;
-	ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
+	cam->vdev = cafe_v4l_template;
+	cam->vdev.debug = 0;
+/*	cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/
+	cam->vdev.v4l2_dev = &cam->v4l2_dev;
+	ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret)
 		goto out_smbus;
+	video_set_drvdata(&cam->vdev, cam);
+
 	/*
 	 * If so requested, try to get our DMA buffers now.
 	 */
@@ -2165,21 +1987,21 @@ static int cafe_pci_probe(struct pci_dev
 					" will try again later.");
 	}
 
-	cafe_dfs_cam_setup(cam);
 	mutex_unlock(&cam->s_mutex);
-	cafe_add_dev(cam);
 	return 0;
 
-  out_smbus:
+out_smbus:
 	cafe_smbus_shutdown(cam);
-  out_freeirq:
+out_freeirq:
 	cafe_ctlr_power_down(cam);
 	free_irq(pdev->irq, cam);
-  out_iounmap:
+out_iounmap:
 	pci_iounmap(pdev, cam->regs);
-  out_free:
+out_free:
+	v4l2_device_unregister(&cam->v4l2_dev);
+out_unreg:
 	kfree(cam);
-  out:
+out:
 	return ret;
 }
 
@@ -2190,25 +2012,23 @@ static int cafe_pci_probe(struct pci_dev
 static void cafe_shutdown(struct cafe_camera *cam)
 {
 /* FIXME: Make sure we take care of everything here */
-	cafe_dfs_cam_shutdown(cam);
 	if (cam->n_sbufs > 0)
 		/* What if they are still mapped?  Shouldn't be, but... */
 		cafe_free_sio_buffers(cam);
-	cafe_remove_dev(cam);
 	cafe_ctlr_stop_dma(cam);
 	cafe_ctlr_power_down(cam);
 	cafe_smbus_shutdown(cam);
 	cafe_free_dma_bufs(cam);
 	free_irq(cam->pdev->irq, cam);
 	pci_iounmap(cam->pdev, cam->regs);
-	video_unregister_device(&cam->v4ldev);
-	/* kfree(cam); done in v4l_release () */
+	video_unregister_device(&cam->vdev);
 }
 
 
 static void cafe_pci_remove(struct pci_dev *pdev)
 {
-	struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct cafe_camera *cam = to_cam(v4l2_dev);
 
 	if (cam == NULL) {
 		printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
@@ -2218,6 +2038,8 @@ static void cafe_pci_remove(struct pci_d
 	if (cam->users > 0)
 		cam_warn(cam, "Removing a device with users!\n");
 	cafe_shutdown(cam);
+	v4l2_device_unregister(&cam->v4l2_dev);
+	kfree(cam);
 /* No unlock - it no longer exists */
 }
 
@@ -2228,7 +2050,8 @@ static void cafe_pci_remove(struct pci_d
  */
 static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct cafe_camera *cam = to_cam(v4l2_dev);
 	int ret;
 	enum cafe_state cstate;
 
@@ -2246,7 +2069,8 @@ static int cafe_pci_suspend(struct pci_d
 
 static int cafe_pci_resume(struct pci_dev *pdev)
 {
-	struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct cafe_camera *cam = to_cam(v4l2_dev);
 	int ret = 0;
 
 	ret = pci_restore_state(pdev);
@@ -2307,13 +2131,11 @@ static int __init cafe_init(void)
 
 	printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n",
 			CAFE_VERSION);
-	cafe_dfs_setup();
 	ret = pci_register_driver(&cafe_pci_driver);
 	if (ret) {
 		printk(KERN_ERR "Unable to register cafe_ccic driver\n");
 		goto out;
 	}
-	request_module("ov7670");  /* FIXME want something more general */
 	ret = 0;
 
   out:
@@ -2324,7 +2146,6 @@ static int __init cafe_init(void)
 static void __exit cafe_exit(void)
 {
 	pci_unregister_driver(&cafe_pci_driver);
-	cafe_dfs_shutdown();
 }
 
 module_init(cafe_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cpia2/cpia2_v4l.c linux-libre-2.6.30-gnu1/drivers/media/video/cpia2/cpia2_v4l.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cpia2/cpia2_v4l.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cpia2/cpia2_v4l.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/videodev.h>
 #include <media/v4l2-ioctl.h>
 
 #include "cpia2.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cpia.c linux-libre-2.6.30-gnu1/drivers/media/video/cpia.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cpia.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cpia.c	2009-06-09 23:05:27.000000000 -0400
@@ -1381,9 +1381,7 @@ static void proc_cpia_create(void)
 {
 	cpia_proc_root = proc_mkdir("cpia", NULL);
 
-	if (cpia_proc_root)
-		cpia_proc_root->owner = THIS_MODULE;
-	else
+	if (!cpia_proc_root)
 		LOG("Unable to initialise /proc/cpia\n");
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cs5345.c linux-libre-2.6.30-gnu1/drivers/media/video/cs5345.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cs5345.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cs5345.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,14 +53,15 @@ static inline int cs5345_read(struct v4l
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int cs5345_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs5345_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
-	if ((route->input & 0xf) > 6) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if ((input & 0xf) > 6) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	cs5345_write(sd, 0x09, route->input & 0xf);
-	cs5345_write(sd, 0x05, route->input & 0xf0);
+	cs5345_write(sd, 0x09, input & 0xf);
+	cs5345_write(sd, 0x05, input & 0xf0);
 	return 0;
 }
 
@@ -141,11 +142,6 @@ static int cs5345_log_status(struct v4l2
 	return 0;
 }
 
-static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops cs5345_core_ops = {
@@ -214,8 +210,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cs5345",
-	.driverid = I2C_DRIVERID_CS5345,
-	.command = cs5345_command,
 	.probe = cs5345_probe,
 	.remove = cs5345_remove,
 	.id_table = cs5345_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cs53l32a.c linux-libre-2.6.30-gnu1/drivers/media/video/cs53l32a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cs53l32a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cs53l32a.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
 MODULE_AUTHOR("Martin Vaughan");
@@ -41,9 +41,6 @@ module_param(debug, bool, 0644);
 
 MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
 
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
 
 /* ----------------------------------------------------------------------- */
 
@@ -61,17 +58,18 @@ static int cs53l32a_read(struct v4l2_sub
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int cs53l32a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cs53l32a_s_routing(struct v4l2_subdev *sd,
+			      u32 input, u32 output, u32 config)
 {
 	/* There are 2 physical inputs, but the second input can be
 	   placed in two modes, the first mode bypasses the PGA (gain),
 	   the second goes through the PGA. Hence there are three
 	   possible inputs to choose from. */
-	if (route->input > 2) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if (input > 2) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	cs53l32a_write(sd, 0x01, 0x01 + (route->input << 4));
+	cs53l32a_write(sd, 0x01, 0x01 + (input << 4));
 	return 0;
 }
 
@@ -122,11 +120,6 @@ static int cs53l32a_log_status(struct v4
 	return 0;
 }
 
-static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
@@ -218,8 +211,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cs53l32a",
-	.driverid = I2C_DRIVERID_CS53L32A,
-	.command = cs53l32a_command,
 	.remove = cs53l32a_remove,
 	.probe = cs53l32a_probe,
 	.id_table = cs53l32a_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-audio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,6 @@
 
 #include "cx18-driver.h"
 #include "cx18-io.h"
-#include "cx18-i2c.h"
 #include "cx18-cards.h"
 #include "cx18-audio.h"
 
@@ -33,55 +32,29 @@
    settings. */
 int cx18_audio_set_io(struct cx18 *cx)
 {
-	struct v4l2_routing route;
-	u32 audio_input;
+	const struct cx18_card_audio_input *in;
 	u32 val;
-	int mux_input;
 	int err;
 
 	/* Determine which input to use */
-	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
-		audio_input = cx->card->radio_input.audio_input;
-		mux_input = cx->card->radio_input.muxer_input;
-	} else {
-		audio_input =
-			cx->card->audio_inputs[cx->audio_input].audio_input;
-		mux_input =
-			cx->card->audio_inputs[cx->audio_input].muxer_input;
-	}
+	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+		in = &cx->card->radio_input;
+	else
+		in = &cx->card->audio_inputs[cx->audio_input];
 
 	/* handle muxer chips */
-	route.input = mux_input;
-	route.output = 0;
-	cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	v4l2_subdev_call(cx->sd_extmux, audio, s_routing,
+			 (u32) in->muxer_input, 0, 0);
 
-	route.input = audio_input;
-	err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
-			VIDIOC_INT_S_AUDIO_ROUTING, &route);
+	err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
+			       audio, s_routing, in->audio_input, 0, 0);
 	if (err)
 		return err;
 
+	/* FIXME - this internal mux should be abstracted to a subdev */
 	val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
-	val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
-					(audio_input << 4);
-	cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
-	cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+	val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
+					(in->audio_input << 4);
+	cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
 	return 0;
 }
-
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
-{
-	cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
-			VIDIOC_INT_S_AUDIO_ROUTING, route);
-}
-
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
-{
-	static u32 freqs[3] = { 44100, 48000, 32000 };
-
-	/* The audio clock of the digitizer must match the codec sample
-	   rate otherwise you get some very strange effects. */
-	if (freq > 2)
-		return;
-	cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-audio.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-audio.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-audio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-audio.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,5 +22,3 @@
  */
 
 int cx18_audio_set_io(struct cx18 *cx);
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route);
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-audio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -464,82 +464,76 @@ static void set_mute(struct cx18 *cx, in
 	}
 }
 
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 {
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
 	struct cx18_av_state *state = &cx->av_state;
-	struct v4l2_control *ctrl = arg;
 	int retval;
+	u8 v;
 
-	switch (cmd) {
-	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-	{
-		u8 v;
-		if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
-			v = cx18_av_read(cx, 0x803) & ~0x10;
-			cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-			cx18_av_write(cx, 0x8d3, 0x1f);
-		}
-		v = cx18_av_read(cx, 0x810) | 0x1;
-		cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+		v = cx18_av_read(cx, 0x803) & ~0x10;
+		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+		cx18_av_write(cx, 0x8d3, 0x1f);
+	}
+	v = cx18_av_read(cx, 0x810) | 0x1;
+	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 
-		retval = set_audclk_freq(cx, *(u32 *)arg);
+	retval = set_audclk_freq(cx, freq);
 
-		v = cx18_av_read(cx, 0x810) & ~0x1;
-		cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-		if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
-			v = cx18_av_read(cx, 0x803) | 0x10;
-			cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-		}
-		return retval;
+	v = cx18_av_read(cx, 0x810) & ~0x1;
+	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+		v = cx18_av_read(cx, 0x803) | 0x10;
+		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 	}
+	return retval;
+}
 
-	case VIDIOC_G_CTRL:
-		switch (ctrl->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-			ctrl->value = get_volume(cx);
-			break;
-		case V4L2_CID_AUDIO_BASS:
-			ctrl->value = get_bass(cx);
-			break;
-		case V4L2_CID_AUDIO_TREBLE:
-			ctrl->value = get_treble(cx);
-			break;
-		case V4L2_CID_AUDIO_BALANCE:
-			ctrl->value = get_balance(cx);
-			break;
-		case V4L2_CID_AUDIO_MUTE:
-			ctrl->value = get_mute(cx);
-			break;
-		default:
-			return -EINVAL;
-		}
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		ctrl->value = get_volume(cx);
 		break;
-
-	case VIDIOC_S_CTRL:
-		switch (ctrl->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-			set_volume(cx, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_BASS:
-			set_bass(cx, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_TREBLE:
-			set_treble(cx, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_BALANCE:
-			set_balance(cx, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_MUTE:
-			set_mute(cx, ctrl->value);
-			break;
-		default:
-			return -EINVAL;
-		}
+	case V4L2_CID_AUDIO_BASS:
+		ctrl->value = get_bass(cx);
+		break;
+	case V4L2_CID_AUDIO_TREBLE:
+		ctrl->value = get_treble(cx);
+		break;
+	case V4L2_CID_AUDIO_BALANCE:
+		ctrl->value = get_balance(cx);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = get_mute(cx);
 		break;
-
 	default:
 		return -EINVAL;
 	}
+	return 0;
+}
 
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		set_volume(cx, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_BASS:
+		set_bass(cx, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_TREBLE:
+		set_treble(cx, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_BALANCE:
+		set_balance(cx, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		set_mute(cx, ctrl->value);
+		break;
+	default:
+		return -EINVAL;
+	}
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-core.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,8 +22,10 @@
  *  02110-1301, USA.
  */
 
+#include <media/v4l2-chip-ident.h>
 #include "cx18-driver.h"
 #include "cx18-io.h"
+#include "cx18-cards.h"
 
 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
 {
@@ -97,15 +99,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16
 			     or_value);
 }
 
-/* ----------------------------------------------------------------------- */
-
-static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
-					enum cx18_av_audio_input aud_input);
-static void log_audio_status(struct cx18 *cx);
-static void log_video_status(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-
 static void cx18_av_initialize(struct cx18 *cx)
 {
 	struct cx18_av_state *state = &cx->av_state;
@@ -169,9 +162,14 @@ static void cx18_av_initialize(struct cx
 	/* Set VGA_TRACK_RANGE to 0x20 */
 	cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
 
-	/* Enable VBI capture */
-	cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
-	/* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
+	/*
+	 * Initial VBI setup
+	 * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
+	 * don't clamp raw samples when codes are in use, 1 byte user D-words,
+	 * IDID0 has line #, RP code V bit transition on VBLANK, data during
+	 * blanking intervals
+	 */
+	cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
 
 	/* Set the video input.
 	   The setting in MODE_CTRL gets lost when we do the above setup */
@@ -195,11 +193,60 @@ static void cx18_av_initialize(struct cx
 	state->default_volume = ((state->default_volume / 2) + 23) << 9;
 }
 
-/* ----------------------------------------------------------------------- */
+static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	cx18_av_initialize(cx);
+	return 0;
+}
+
+static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	/*
+	 * The crystal freq used in calculations in this driver will be
+	 * 28.636360 MHz.
+	 * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+	 */
+
+	/*
+	 * VDCLK  Integer = 0x0f, Post Divider = 0x04
+	 * AIMCLK Integer = 0x0e, Post Divider = 0x16
+	 */
+	cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+	/* VDCLK Fraction = 0x2be2fe */
+	/* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+	cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+	/* AIMCLK Fraction = 0x05227ad */
+	/* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+	cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+	return 0;
+}
+
+static int cx18_av_load_fw(struct v4l2_subdev *sd)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	if (!state->is_initialized) {
+		/* initialize on first use */
+		state->is_initialized = 1;
+		cx18_av_initialize(cx);
+	}
+	return 0;
+}
 
 void cx18_av_std_setup(struct cx18 *cx)
 {
 	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_subdev *sd = &state->sd;
 	v4l2_std_id std = state->std;
 	int hblank, hactive, burst, vblank, vactive, sc;
 	int vblank656, src_decimation;
@@ -213,6 +260,7 @@ void cx18_av_std_setup(struct cx18 *cx)
 		cx18_av_write(cx, 0x49f, 0x14);
 
 	if (std & V4L2_STD_625_50) {
+		/* FIXME - revisit these for Sliced VBI */
 		hblank = 132;
 		hactive = 720;
 		burst = 93;
@@ -236,13 +284,40 @@ void cx18_av_std_setup(struct cx18 *cx)
 			sc = 672351;
 		}
 	} else {
+		/*
+		 * The following relationships of half line counts should hold:
+		 * 525 = vsync + vactive + vblank656
+		 * 12 = vblank656 - vblank
+		 *
+		 * vsync:     always 6 half-lines of vsync pulses
+		 * vactive:   half lines of active video
+		 * vblank656: half lines, after line 3/mid-266, of blanked video
+		 * vblank:    half lines, after line 9/272, of blanked video
+		 *
+		 * As far as I can tell:
+		 * vblank656 starts counting from the falling edge of the first
+		 * 	vsync pulse (start of line 4 or mid-266)
+		 * vblank starts counting from the after the 6 vsync pulses and
+		 * 	6 or 5 equalization pulses (start of line 10 or 272)
+		 *
+		 * For 525 line systems the driver will extract VBI information
+		 * from lines 10-21 and lines 273-284.
+		 */
+		vblank656 = 38; /* lines  4 -  22  &  266 - 284 */
+		vblank = 26;	/* lines 10 -  22  &  272 - 284 */
+		vactive = 481;  /* lines 23 - 263  &  285 - 525 */
+
+		/*
+		 * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
+		 * is 858 pixels = 720 active + 138 blanking.  The Hsync leading
+		 * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
+		 * end of active video, leaving 122 pixels of hblank to ignore
+		 * before active video starts.
+		 */
 		hactive = 720;
 		hblank = 122;
-		vactive = 487;
 		luma_lpf = 1;
 		uv_lpf = 1;
-		vblank = 26;
-		vblank656 = 26;
 
 		src_decimation = 0x21f;
 		if (std == V4L2_STD_PAL_60) {
@@ -265,33 +340,35 @@ void cx18_av_std_setup(struct cx18 *cx)
 	pll_int = cx18_av_read(cx, 0x108);
 	pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
 	pll_post = cx18_av_read(cx, 0x109);
-	CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
-			pll_int, pll_frac, pll_post);
+	CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
+			    pll_int, pll_frac, pll_post);
 
 	if (pll_post) {
 		int fin, fsc, pll;
 
 		pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
 		pll /= pll_post;
-		CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
-					pll / 1000000, pll % 1000000);
-		CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
-					pll / 8000000, (pll / 8) % 1000000);
+		CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n",
+				    pll / 1000000, pll % 1000000);
+		CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n",
+				    pll / 8000000, (pll / 8) % 1000000);
 
 		fin = ((u64)src_decimation * pll) >> 12;
-		CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
-					fin / 1000000, fin % 1000000);
+		CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n",
+				    fin / 1000000, fin % 1000000);
 
 		fsc = (((u64)sc) * pll) >> 24L;
-		CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
-					fsc / 1000000, fsc % 1000000);
+		CX18_DEBUG_INFO_DEV(sd,
+				    "Chroma sub-carrier freq = %d.%06d MHz\n",
+				    fsc / 1000000, fsc % 1000000);
 
-		CX18_DEBUG_INFO("hblank %i, hactive %i, "
-			"vblank %i , vactive %i, vblank656 %i, src_dec %i,"
-			"burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
-			" sc 0x%06x\n",
-			hblank, hactive, vblank, vactive, vblank656,
-			src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+		CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
+				    "vactive %i, vblank656 %i, src_dec %i, "
+				    "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
+				    "comb 0x%02x, sc 0x%06x\n",
+				    hblank, hactive, vblank, vactive, vblank656,
+				    src_decimation, burst, luma_lpf, uv_lpf,
+				    comb, sc);
 	}
 
 	/* Sets horizontal blanking delay and active lines */
@@ -325,18 +402,16 @@ void cx18_av_std_setup(struct cx18 *cx)
 	cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
 	cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
 
-	/* Sets VBI parameters */
 	if (std & V4L2_STD_625_50) {
-		cx18_av_write(cx, 0x47f, 0x01);
-		state->vbi_line_offset = 5;
+		state->slicer_line_delay = 1;
+		state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
 	} else {
-		cx18_av_write(cx, 0x47f, 0x00);
-		state->vbi_line_offset = 8;
+		state->slicer_line_delay = 0;
+		state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
 	}
+	cx18_av_write(cx, 0x47f, state->slicer_line_delay);
 }
 
-/* ----------------------------------------------------------------------- */
-
 static void input_change(struct cx18 *cx)
 {
 	struct cx18_av_state *state = &cx->av_state;
@@ -382,17 +457,26 @@ static void input_change(struct cx18 *cx
 	}
 }
 
+static int cx18_av_s_frequency(struct v4l2_subdev *sd,
+			       struct v4l2_frequency *freq)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	input_change(cx);
+	return 0;
+}
+
 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 					enum cx18_av_audio_input aud_input)
 {
 	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_subdev *sd = &state->sd;
 	u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
 			   vid_input <= CX18_AV_COMPOSITE8);
 	u8 reg;
 	u8 v;
 
-	CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
-			vid_input, aud_input);
+	CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
+			    vid_input, aud_input);
 
 	if (is_composite) {
 		reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
@@ -405,8 +489,8 @@ static int set_input(struct cx18 *cx, en
 		    luma > CX18_AV_SVIDEO_LUMA8 ||
 		    chroma < CX18_AV_SVIDEO_CHROMA4 ||
 		    chroma > CX18_AV_SVIDEO_CHROMA8) {
-			CX18_ERR("0x%04x is not a valid video input!\n",
-					vid_input);
+			CX18_ERR_DEV(sd, "0x%04x is not a valid video input!\n",
+				     vid_input);
 			return -EINVAL;
 		}
 		reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
@@ -431,7 +515,8 @@ static int set_input(struct cx18 *cx, en
 	case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
 
 	default:
-		CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
+		CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
+			     aud_input);
 		return -EINVAL;
 	}
 
@@ -461,14 +546,118 @@ static int set_input(struct cx18 *cx, en
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	return set_input(cx, input, state->aud_input);
+}
 
-static int set_v4lstd(struct cx18 *cx)
+static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
-	struct cx18_av_state *state = &cx->av_state;
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	return set_input(cx, state->vid_input, input);
+}
+
+static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	u8 vpres;
+	u8 mode;
+	int val = 0;
+
+	if (state->radio)
+		return 0;
+
+	vpres = cx18_av_read(cx, 0x40e) & 0x20;
+	vt->signal = vpres ? 0xffff : 0x0;
+
+	vt->capability |=
+		    V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+		    V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+	mode = cx18_av_read(cx, 0x804);
+
+	/* get rxsubchans and audmode */
+	if ((mode & 0xf) == 1)
+		val |= V4L2_TUNER_SUB_STEREO;
+	else
+		val |= V4L2_TUNER_SUB_MONO;
+
+	if (mode == 2 || mode == 4)
+		val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+	if (mode & 0x10)
+		val |= V4L2_TUNER_SUB_SAP;
+
+	vt->rxsubchans = val;
+	vt->audmode = state->audmode;
+	return 0;
+}
+
+static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	u8 v;
+
+	if (state->radio)
+		return 0;
+
+	v = cx18_av_read(cx, 0x809);
+	v &= ~0xf;
+
+	switch (vt->audmode) {
+	case V4L2_TUNER_MODE_MONO:
+		/* mono      -> mono
+		   stereo    -> mono
+		   bilingual -> lang1 */
+		break;
+	case V4L2_TUNER_MODE_STEREO:
+	case V4L2_TUNER_MODE_LANG1:
+		/* mono      -> mono
+		   stereo    -> stereo
+		   bilingual -> lang1 */
+		v |= 0x4;
+		break;
+	case V4L2_TUNER_MODE_LANG1_LANG2:
+		/* mono      -> mono
+		   stereo    -> stereo
+		   bilingual -> lang1/lang2 */
+		v |= 0x7;
+		break;
+	case V4L2_TUNER_MODE_LANG2:
+		/* mono      -> mono
+		   stereo    -> stereo
+		   bilingual -> lang2 */
+		v |= 0x1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	cx18_av_write_expect(cx, 0x809, v, v, 0xff);
+	state->audmode = vt->audmode;
+	return 0;
+}
+
+static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
 	u8 fmt = 0; 	/* zero is autodetect */
 	u8 pal_m = 0;
 
+	if (state->radio == 0 && state->std == norm)
+		return 0;
+
+	state->radio = 0;
+	state->std = norm;
+
 	/* First tests should be against specific std */
 	if (state->std == V4L2_STD_NTSC_M_JP) {
 		fmt = 0x2;
@@ -493,7 +682,7 @@ static int set_v4lstd(struct cx18 *cx)
 			fmt = 0xc;
 	}
 
-	CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
+	CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
 
 	/* Follow step 9 of section 3.16 in the cx18_av datasheet.
 	   Without this PAL may display a vertical ghosting effect.
@@ -511,15 +700,22 @@ static int set_v4lstd(struct cx18 *cx)
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_radio(struct v4l2_subdev *sd)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	state->radio = 1;
+	return 0;
+}
 
-static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			CX18_ERR("invalid brightness setting %d\n",
-				    ctrl->value);
+			CX18_ERR_DEV(sd, "invalid brightness setting %d\n",
+				     ctrl->value);
 			return -ERANGE;
 		}
 
@@ -528,8 +724,8 @@ static int set_v4lctrl(struct cx18 *cx,
 
 	case V4L2_CID_CONTRAST:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			CX18_ERR("invalid contrast setting %d\n",
-				    ctrl->value);
+			CX18_ERR_DEV(sd, "invalid contrast setting %d\n",
+				     ctrl->value);
 			return -ERANGE;
 		}
 
@@ -538,8 +734,8 @@ static int set_v4lctrl(struct cx18 *cx,
 
 	case V4L2_CID_SATURATION:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			CX18_ERR("invalid saturation setting %d\n",
-				    ctrl->value);
+			CX18_ERR_DEV(sd, "invalid saturation setting %d\n",
+				     ctrl->value);
 			return -ERANGE;
 		}
 
@@ -548,8 +744,9 @@ static int set_v4lctrl(struct cx18 *cx,
 		break;
 
 	case V4L2_CID_HUE:
-		if (ctrl->value < -127 || ctrl->value > 127) {
-			CX18_ERR("invalid hue setting %d\n", ctrl->value);
+		if (ctrl->value < -128 || ctrl->value > 127) {
+			CX18_ERR_DEV(sd, "invalid hue setting %d\n",
+				     ctrl->value);
 			return -ERANGE;
 		}
 
@@ -561,17 +758,18 @@ static int set_v4lctrl(struct cx18 *cx,
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
+		return cx18_av_audio_s_ctrl(cx, ctrl);
 
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
-static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
@@ -590,31 +788,57 @@ static int get_v4lctrl(struct cx18 *cx,
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
-		return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
+		return cx18_av_audio_g_ctrl(cx, ctrl);
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
-
-static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
 {
-	switch (fmt->type) {
-	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+	case V4L2_CID_CONTRAST:
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+	default:
+		break;
+	}
+
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535,
+			65535 / 100, state->default_volume);
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 	default:
 		return -EINVAL;
 	}
+	return -EINVAL;
+}
 
-	return 0;
+static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	return cx18_av_vbi_g_fmt(cx, fmt);
 }
 
-static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
-	struct cx18_av_state *state = &cx->av_state;
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
 	struct v4l2_pix_format *pix;
 	int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
 	int is_50Hz = !(state->std & V4L2_STD_525_60);
@@ -629,12 +853,26 @@ static int set_v4lfmt(struct cx18 *cx, s
 		Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
 		Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
 
-		Vlines = pix->height + (is_50Hz ? 4 : 7);
+		/*
+		 * This adjustment reflects the excess of vactive, set in
+		 * cx18_av_std_setup(), above standard values:
+		 *
+		 * 480 + 1 for 60 Hz systems
+		 * 576 + 4 for 50 Hz systems
+		 */
+		Vlines = pix->height + (is_50Hz ? 4 : 1);
 
+		/*
+		 * Invalid height and width scaling requests are:
+		 * 1. width less than 1/16 of the source width
+		 * 2. width greater than the source width
+		 * 3. height less than 1/8 of the source height
+		 * 4. height greater than the source height
+		 */
 		if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
 		    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
-			CX18_ERR("%dx%d is not a valid size!\n",
-				    pix->width, pix->height);
+			CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
+				     pix->width, pix->height);
 			return -ERANGE;
 		}
 
@@ -651,8 +889,9 @@ static int set_v4lfmt(struct cx18 *cx, s
 		else
 			filter = 3;
 
-		CX18_DEBUG_INFO("decoder set size %dx%d -> scale  %ux%u\n",
-			    pix->width, pix->height, HSC, VSC);
+		CX18_DEBUG_INFO_DEV(sd,
+				    "decoder set size %dx%d -> scale  %ux%u\n",
+				    pix->width, pix->height, HSC, VSC);
 
 		/* HSCALE=HSC */
 		cx18_av_write(cx, 0x418, HSC & 0xff);
@@ -666,231 +905,32 @@ static int set_v4lfmt(struct cx18 *cx, s
 		break;
 
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+		return cx18_av_vbi_s_fmt(cx, fmt);
 
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+		return cx18_av_vbi_s_fmt(cx, fmt);
 
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
-
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
+static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct cx18_av_state *state = &cx->av_state;
-	struct v4l2_tuner *vt = arg;
-	struct v4l2_routing *route = arg;
-
-	/* ignore these commands */
-	switch (cmd) {
-	case TUNER_SET_TYPE_ADDR:
-		return 0;
-	}
-
-	if (!state->is_initialized) {
-		CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
-		/* initialize on first use */
-		state->is_initialized = 1;
-		cx18_av_initialize(cx);
-	}
-
-	switch (cmd) {
-	case VIDIOC_INT_DECODE_VBI_LINE:
-		return cx18_av_vbi(cx, cmd, arg);
-
-	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		return cx18_av_audio(cx, cmd, arg);
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	case VIDIOC_STREAMON:
-		CX18_DEBUG_INFO("enable output\n");
+	CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
+	if (enable) {
 		cx18_av_write(cx, 0x115, 0x8c);
 		cx18_av_write(cx, 0x116, 0x07);
-		break;
-
-	case VIDIOC_STREAMOFF:
-		CX18_DEBUG_INFO("disable output\n");
+	} else {
 		cx18_av_write(cx, 0x115, 0x00);
 		cx18_av_write(cx, 0x116, 0x00);
-		break;
-
-	case VIDIOC_LOG_STATUS:
-		log_video_status(cx);
-		log_audio_status(cx);
-		break;
-
-	case VIDIOC_G_CTRL:
-		return get_v4lctrl(cx, (struct v4l2_control *)arg);
-
-	case VIDIOC_S_CTRL:
-		return set_v4lctrl(cx, (struct v4l2_control *)arg);
-
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *qc = arg;
-
-		switch (qc->id) {
-		case V4L2_CID_BRIGHTNESS:
-		case V4L2_CID_CONTRAST:
-		case V4L2_CID_SATURATION:
-		case V4L2_CID_HUE:
-			return v4l2_ctrl_query_fill_std(qc);
-		default:
-			break;
-		}
-
-		switch (qc->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-			return v4l2_ctrl_query_fill(qc, 0, 65535,
-				65535 / 100, state->default_volume);
-		case V4L2_CID_AUDIO_MUTE:
-		case V4L2_CID_AUDIO_BALANCE:
-		case V4L2_CID_AUDIO_BASS:
-		case V4L2_CID_AUDIO_TREBLE:
-			return v4l2_ctrl_query_fill_std(qc);
-		default:
-			return -EINVAL;
-		}
-		return -EINVAL;
-	}
-
-	case VIDIOC_G_STD:
-		*(v4l2_std_id *)arg = state->std;
-		break;
-
-	case VIDIOC_S_STD:
-		if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
-			return 0;
-		state->radio = 0;
-		state->std = *(v4l2_std_id *)arg;
-		return set_v4lstd(cx);
-
-	case AUDC_SET_RADIO:
-		state->radio = 1;
-		break;
-
-	case VIDIOC_INT_G_VIDEO_ROUTING:
-		route->input = state->vid_input;
-		route->output = 0;
-		break;
-
-	case VIDIOC_INT_S_VIDEO_ROUTING:
-		return set_input(cx, route->input, state->aud_input);
-
-	case VIDIOC_INT_G_AUDIO_ROUTING:
-		route->input = state->aud_input;
-		route->output = 0;
-		break;
-
-	case VIDIOC_INT_S_AUDIO_ROUTING:
-		return set_input(cx, state->vid_input, route->input);
-
-	case VIDIOC_S_FREQUENCY:
-		input_change(cx);
-		break;
-
-	case VIDIOC_G_TUNER:
-	{
-		u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
-		u8 mode;
-		int val = 0;
-
-		if (state->radio)
-			break;
-
-		vt->signal = vpres ? 0xffff : 0x0;
-
-		vt->capability |=
-		    V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
-		    V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
-		mode = cx18_av_read(cx, 0x804);
-
-		/* get rxsubchans and audmode */
-		if ((mode & 0xf) == 1)
-			val |= V4L2_TUNER_SUB_STEREO;
-		else
-			val |= V4L2_TUNER_SUB_MONO;
-
-		if (mode == 2 || mode == 4)
-			val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
-		if (mode & 0x10)
-			val |= V4L2_TUNER_SUB_SAP;
-
-		vt->rxsubchans = val;
-		vt->audmode = state->audmode;
-		break;
-	}
-
-	case VIDIOC_S_TUNER:
-	{
-		u8 v;
-
-		if (state->radio)
-			break;
-
-		v = cx18_av_read(cx, 0x809);
-		v &= ~0xf;
-
-		switch (vt->audmode) {
-		case V4L2_TUNER_MODE_MONO:
-			/* mono      -> mono
-			   stereo    -> mono
-			   bilingual -> lang1 */
-			break;
-		case V4L2_TUNER_MODE_STEREO:
-		case V4L2_TUNER_MODE_LANG1:
-			/* mono      -> mono
-			   stereo    -> stereo
-			   bilingual -> lang1 */
-			v |= 0x4;
-			break;
-		case V4L2_TUNER_MODE_LANG1_LANG2:
-			/* mono      -> mono
-			   stereo    -> stereo
-			   bilingual -> lang1/lang2 */
-			v |= 0x7;
-			break;
-		case V4L2_TUNER_MODE_LANG2:
-			/* mono      -> mono
-			   stereo    -> stereo
-			   bilingual -> lang2 */
-			v |= 0x1;
-			break;
-		default:
-			return -EINVAL;
-		}
-		cx18_av_write_expect(cx, 0x809, v, v, 0xff);
-		state->audmode = vt->audmode;
-		break;
-	}
-
-	case VIDIOC_G_FMT:
-		return get_v4lfmt(cx, (struct v4l2_format *)arg);
-
-	case VIDIOC_S_FMT:
-		return set_v4lfmt(cx, (struct v4l2_format *)arg);
-
-	case VIDIOC_INT_RESET:
-		cx18_av_initialize(cx);
-		break;
-
-	default:
-		return -EINVAL;
 	}
-
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------- */
-
 static void log_video_status(struct cx18 *cx)
 {
 	static const char *const fmt_strs[] = {
@@ -903,36 +943,40 @@ static void log_video_status(struct cx18
 	};
 
 	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_subdev *sd = &state->sd;
 	u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
 	u8 gen_stat1 = cx18_av_read(cx, 0x40d);
 	u8 gen_stat2 = cx18_av_read(cx, 0x40e);
 	int vid_input = state->vid_input;
 
-	CX18_INFO("Video signal:              %spresent\n",
-		    (gen_stat2 & 0x20) ? "" : "not ");
-	CX18_INFO("Detected format:           %s\n",
-		    fmt_strs[gen_stat1 & 0xf]);
+	CX18_INFO_DEV(sd, "Video signal:              %spresent\n",
+		      (gen_stat2 & 0x20) ? "" : "not ");
+	CX18_INFO_DEV(sd, "Detected format:           %s\n",
+		      fmt_strs[gen_stat1 & 0xf]);
 
-	CX18_INFO("Specified standard:        %s\n",
-		    vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+	CX18_INFO_DEV(sd, "Specified standard:        %s\n",
+		      vidfmt_sel ? fmt_strs[vidfmt_sel]
+				 : "automatic detection");
 
 	if (vid_input >= CX18_AV_COMPOSITE1 &&
 	    vid_input <= CX18_AV_COMPOSITE8) {
-		CX18_INFO("Specified video input:     Composite %d\n",
-			vid_input - CX18_AV_COMPOSITE1 + 1);
+		CX18_INFO_DEV(sd, "Specified video input:     Composite %d\n",
+			      vid_input - CX18_AV_COMPOSITE1 + 1);
 	} else {
-		CX18_INFO("Specified video input:     S-Video (Luma In%d, Chroma In%d)\n",
-			(vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
+		CX18_INFO_DEV(sd, "Specified video input:     "
+			      "S-Video (Luma In%d, Chroma In%d)\n",
+			      (vid_input & 0xf0) >> 4,
+			      (vid_input & 0xf00) >> 8);
 	}
 
-	CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
+	CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
+		      state->audclk_freq);
 }
 
-/* ----------------------------------------------------------------------- */
-
 static void log_audio_status(struct cx18 *cx)
 {
 	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_subdev *sd = &state->sd;
 	u8 download_ctl = cx18_av_read(cx, 0x803);
 	u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
 	u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
@@ -955,7 +999,7 @@ static void log_audio_status(struct cx18
 	case 0xfe: p = "forced mode"; break;
 	default: p = "not defined"; break;
 	}
-	CX18_INFO("Detected audio mode:       %s\n", p);
+	CX18_INFO_DEV(sd, "Detected audio mode:       %s\n", p);
 
 	switch (mod_det_stat1) {
 	case 0x00: p = "not defined"; break;
@@ -980,11 +1024,11 @@ static void log_audio_status(struct cx18
 	case 0xff: p = "no detected audio standard"; break;
 	default: p = "not defined"; break;
 	}
-	CX18_INFO("Detected audio standard:   %s\n", p);
-	CX18_INFO("Audio muted:               %s\n",
-		    (mute_ctl & 0x2) ? "yes" : "no");
-	CX18_INFO("Audio microcontroller:     %s\n",
-		    (download_ctl & 0x10) ? "running" : "stopped");
+	CX18_INFO_DEV(sd, "Detected audio standard:   %s\n", p);
+	CX18_INFO_DEV(sd, "Audio muted:               %s\n",
+		      (mute_ctl & 0x2) ? "yes" : "no");
+	CX18_INFO_DEV(sd, "Audio microcontroller:     %s\n",
+		      (download_ctl & 0x10) ? "running" : "stopped");
 
 	switch (audio_config >> 4) {
 	case 0x00: p = "undefined"; break;
@@ -1005,7 +1049,7 @@ static void log_audio_status(struct cx18
 	case 0x0f: p = "automatic detection"; break;
 	default: p = "undefined"; break;
 	}
-	CX18_INFO("Configured audio standard: %s\n", p);
+	CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
 
 	if ((audio_config >> 4) < 0xF) {
 		switch (audio_config & 0xF) {
@@ -1019,7 +1063,7 @@ static void log_audio_status(struct cx18
 		case 0x07: p = "DUAL3 (AB)"; break;
 		default: p = "undefined";
 		}
-		CX18_INFO("Configured audio mode:     %s\n", p);
+		CX18_INFO_DEV(sd, "Configured audio mode:     %s\n", p);
 	} else {
 		switch (audio_config & 0xF) {
 		case 0x00: p = "BG"; break;
@@ -1037,14 +1081,14 @@ static void log_audio_status(struct cx18
 		case 0x0f: p = "automatic standard and mode detection"; break;
 		default: p = "undefined"; break;
 		}
-		CX18_INFO("Configured audio system:   %s\n", p);
+		CX18_INFO_DEV(sd, "Configured audio system:   %s\n", p);
 	}
 
 	if (aud_input)
-		CX18_INFO("Specified audio input:     Tuner (In%d)\n",
-				aud_input);
+		CX18_INFO_DEV(sd, "Specified audio input:     Tuner (In%d)\n",
+			      aud_input);
 	else
-		CX18_INFO("Specified audio input:     External\n");
+		CX18_INFO_DEV(sd, "Specified audio input:     External\n");
 
 	switch (pref_mode & 0xf) {
 	case 0: p = "mono/language A"; break;
@@ -1057,14 +1101,14 @@ static void log_audio_status(struct cx18
 	case 7: p = "language AB"; break;
 	default: p = "undefined"; break;
 	}
-	CX18_INFO("Preferred audio mode:      %s\n", p);
+	CX18_INFO_DEV(sd, "Preferred audio mode:      %s\n", p);
 
 	if ((audio_config & 0xf) == 0xf) {
 		switch ((afc0 >> 3) & 0x1) {
 		case 0: p = "system DK"; break;
 		case 1: p = "system L"; break;
 		}
-		CX18_INFO("Selected 65 MHz format:    %s\n", p);
+		CX18_INFO_DEV(sd, "Selected 65 MHz format:    %s\n", p);
 
 		switch (afc0 & 0x7) {
 		case 0: p = "Chroma"; break;
@@ -1074,6 +1118,132 @@ static void log_audio_status(struct cx18
 		case 4: p = "autodetect"; break;
 		default: p = "undefined"; break;
 		}
-		CX18_INFO("Selected 45 MHz format:    %s\n", p);
+		CX18_INFO_DEV(sd, "Selected 45 MHz format:    %s\n", p);
 	}
 }
+
+static int cx18_av_log_status(struct v4l2_subdev *sd)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	log_video_status(cx);
+	log_audio_status(cx);
+	return 0;
+}
+
+static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
+{
+	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
+}
+
+static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *chip)
+{
+	struct cx18_av_state *state = to_cx18_av_state(sd);
+
+	if (cx18_av_dbg_match(&chip->match)) {
+		chip->ident = state->id;
+		chip->revision = state->rev;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cx18_av_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	if (!cx18_av_dbg_match(&reg->match))
+		return -EINVAL;
+	if ((reg->reg & 0x3) != 0)
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	reg->size = 4;
+	reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
+	return 0;
+}
+
+static int cx18_av_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	if (!cx18_av_dbg_match(&reg->match))
+		return -EINVAL;
+	if ((reg->reg & 0x3) != 0)
+		return -EINVAL;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
+	return 0;
+}
+#endif
+
+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,
+	.g_ctrl = cx18_av_g_ctrl,
+	.s_ctrl = cx18_av_s_ctrl,
+	.s_std = cx18_av_s_std,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = cx18_av_g_register,
+	.s_register = cx18_av_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
+	.s_radio = cx18_av_s_radio,
+	.s_frequency = cx18_av_s_frequency,
+	.g_tuner = cx18_av_g_tuner,
+	.s_tuner = cx18_av_s_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
+	.s_clock_freq = cx18_av_s_clock_freq,
+	.s_routing = cx18_av_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
+	.s_routing = cx18_av_s_video_routing,
+	.decode_vbi_line = cx18_av_decode_vbi_line,
+	.s_stream = cx18_av_s_stream,
+	.g_fmt = cx18_av_g_fmt,
+	.s_fmt = cx18_av_s_fmt,
+};
+
+static const struct v4l2_subdev_ops cx18_av_ops = {
+	.core = &cx18_av_general_ops,
+	.tuner = &cx18_av_tuner_ops,
+	.audio = &cx18_av_audio_ops,
+	.video = &cx18_av_video_ops,
+};
+
+int cx18_av_probe(struct cx18 *cx)
+{
+	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_subdev *sd;
+
+	state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
+	state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
+		    ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
+
+	state->vid_input = CX18_AV_COMPOSITE7;
+	state->aud_input = CX18_AV_AUDIO8;
+	state->audclk_freq = 48000;
+	state->audmode = V4L2_TUNER_MODE_LANG1;
+	state->slicer_line_delay = 0;
+	state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
+
+	sd = &state->sd;
+	v4l2_subdev_init(sd, &cx18_av_ops);
+	v4l2_set_subdevdata(sd, 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);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-core.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-core.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,8 @@
 #ifndef _CX18_AV_CORE_H_
 #define _CX18_AV_CORE_H_
 
+#include <media/v4l2-device.h>
+
 struct cx18;
 
 enum cx18_av_video_input {
@@ -73,17 +75,40 @@ enum cx18_av_audio_input {
 };
 
 struct cx18_av_state {
+	struct v4l2_subdev sd;
 	int radio;
 	v4l2_std_id std;
 	enum cx18_av_video_input vid_input;
 	enum cx18_av_audio_input aud_input;
 	u32 audclk_freq;
 	int audmode;
-	int vbi_line_offset;
 	int default_volume;
 	u32 id;
 	u32 rev;
 	int is_initialized;
+
+	/*
+	 * The VBI slicer starts operating and counting lines, begining at
+	 * slicer line count of 1, at D lines after the deassertion of VRESET.
+	 * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
+	 * line systems respectively.  Sliced ancillary data captured on VBI
+	 * slicer line M is inserted after the VBI slicer is done with line M,
+	 * when VBI slicer line count is N = M+1.  Thus when the VBI slicer
+	 * reports a VBI slicer line number with ancillary data, the IDID0 byte
+	 * indicates VBI slicer line N.  The actual field line that the captured
+	 * data comes from is
+	 *
+	 * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
+	 *
+	 * L is the line in the field, not frame, from which the VBI data came.
+	 * N is the line reported by the slicer in the ancillary data.
+	 * D is the slicer_line_delay value programmed into register 0x47f.
+	 * S is 6 for 625 line systems or 10 for 525 line systems
+	 * (S+D-2) is the slicer_line_offset used to convert slicer reported
+	 * line counts to actual field lines.
+	 */
+	int slicer_line_delay;
+	int slicer_line_offset;
 };
 
 
@@ -298,6 +323,11 @@ struct cx18_av_state {
 #define CXADEC_SELECT_AUDIO_STANDARD_FM    0xF9  /* FM radio */
 #define CXADEC_SELECT_AUDIO_STANDARD_AUTO  0xFF  /* Auto detect */
 
+static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct cx18_av_state, sd);
+}
+
 /* ----------------------------------------------------------------------- */
 /* cx18_av-core.c 							   */
 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
@@ -310,20 +340,26 @@ u8 cx18_av_read(struct cx18 *cx, u16 add
 u32 cx18_av_read4(struct cx18 *cx, u16 addr);
 int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
 void cx18_av_std_setup(struct cx18 *cx);
 
+int cx18_av_probe(struct cx18 *cx);
+
 /* ----------------------------------------------------------------------- */
 /* cx18_av-firmware.c                                                      */
 int cx18_av_loadfw(struct cx18 *cx);
 
 /* ----------------------------------------------------------------------- */
 /* cx18_av-audio.c                                                         */
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
 void cx18_av_audio_set_path(struct cx18 *cx);
 
 /* ----------------------------------------------------------------------- */
 /* cx18_av-vbi.c                                                           */
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+			   struct v4l2_decode_vbi_line *vbi);
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt);
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-firmware.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-firmware.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-firmware.c	2013-05-03 18:01:52.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-firmware.c	2013-05-03 16:45:43.000000000 -0400
@@ -29,6 +29,7 @@
 
 int cx18_av_loadfw(struct cx18 *cx)
 {
+	struct v4l2_subdev *sd = &cx->av_state.sd;
 	const struct firmware *fw = NULL;
 	u32 size;
 	u32 v;
@@ -36,8 +37,8 @@ int cx18_av_loadfw(struct cx18 *cx)
 	int i;
 	int retries1 = 0;
 
-	if (reject_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
-		CX18_ERR("unable to open firmware %s\n", FWFILE);
+	if (reject_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
+		CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
 		return -EINVAL;
 	}
 
@@ -88,7 +89,7 @@ int cx18_av_loadfw(struct cx18 *cx)
 		retries1++;
 	}
 	if (retries1 >= 5) {
-		CX18_ERR("unable to load firmware %s\n", FWFILE);
+		CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
 		release_firmware(fw);
 		return -EIO;
 	}
@@ -115,9 +116,9 @@ int cx18_av_loadfw(struct cx18 *cx)
 	   are generated) */
 	cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
 
-	/* set alt I2s master clock to /16 and enable alt divider i2s
+	/* set alt I2s master clock to /0x16 and enable alt divider i2s
 	   passthrough */
-	cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
+	cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
 
 	cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
 								  0x3F00FFFF);
@@ -131,7 +132,8 @@ int cx18_av_loadfw(struct cx18 *cx)
 	v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
 	/* If bit 11 is 1, clear bit 10 */
 	if (v & 0x800)
-		cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
+		cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
+				      0, 0x400);
 
 	/* Enable WW auto audio standard detection */
 	v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
@@ -142,6 +144,6 @@ int cx18_av_loadfw(struct cx18 *cx)
 
 	release_firmware(fw);
 
-	CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
+	CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-av-vbi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-av-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,52 @@
 
 #include "cx18-driver.h"
 
+/*
+ * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
+ * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
+ * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
+ * (should!) look like:
+ *	4 byte EAV code:          0xff 0x00 0x00 0xRP
+ *	unknown number of possible idle bytes
+ *	3 byte Anc data preamble: 0x00 0xff 0xff
+ *	1 byte data identifier:   ne010iii (parity bits, 010, DID bits)
+ *	1 byte secondary data id: nessssss (parity bits, SDID bits)
+ *	1 byte data word count:   necccccc (parity bits, NN Dword count)
+ *	2 byte Internal DID:	  VBI-line-# 0x80
+ *	NN data bytes
+ *	1 byte checksum
+ *	Fill bytes needed to fil out to 4*NN bytes of payload
+ *
+ * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
+ * in the vertical blanking interval are:
+ *	0xb0 (Task         0 VerticalBlank HorizontalBlank 0 0 0 0)
+ *	0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code, just
+ * before the first active region line and for active lines, they are:
+ *	0x90 (Task         0 0 HorizontalBlank 0 0 0 0)
+ *	0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
+ *
+ * The user application DID bytes we care about are:
+ *	0x91 (1 0 010        0 !ActiveLine AncDataPresent)
+ *	0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
+ *
+ */
+static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
+
+struct vbi_anc_data {
+	/* u8 eav[4]; */
+	/* u8 idle[]; Variable number of idle bytes */
+	u8 preamble[3];
+	u8 did;
+	u8 sdid;
+	u8 data_count;
+	u8 idid[2];
+	u8 payload[1]; /* data_count of payload */
+	/* u8 checksum; */
+	/* u8 fill[]; Variable number of fill bytes */
+};
+
 static int odd_parity(u8 c)
 {
 	c ^= (c >> 4);
@@ -83,188 +129,189 @@ static int decode_vps(u8 *dst, u8 *p)
 	return err & 0xf0;
 }
 
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
 {
 	struct cx18_av_state *state = &cx->av_state;
-	struct v4l2_format *fmt;
 	struct v4l2_sliced_vbi_format *svbi;
+	static const u16 lcr2vbi[] = {
+		0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
+		0, V4L2_SLICED_WSS_625, 0,	/* 4 */
+		V4L2_SLICED_CAPTION_525,	/* 6 */
+		0, 0, V4L2_SLICED_VPS, 0, 0,	/* 9 */
+		0, 0, 0, 0
+	};
+	int is_pal = !(state->std & V4L2_STD_525_60);
+	int i;
 
-	switch (cmd) {
-	case VIDIOC_G_FMT:
-	{
-		static u16 lcr2vbi[] = {
-			0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
-			0, V4L2_SLICED_WSS_625, 0,	/* 4 */
-			V4L2_SLICED_CAPTION_525,	/* 6 */
-			0, 0, V4L2_SLICED_VPS, 0, 0,	/* 9 */
-			0, 0, 0, 0
-		};
-		int is_pal = !(state->std & V4L2_STD_525_60);
-		int i;
-
-		fmt = arg;
-		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
-			return -EINVAL;
-		svbi = &fmt->fmt.sliced;
-		memset(svbi, 0, sizeof(*svbi));
-		/* we're done if raw VBI is active */
-		if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
-			break;
+	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+		return -EINVAL;
+	svbi = &fmt->fmt.sliced;
+	memset(svbi, 0, sizeof(*svbi));
+	/* we're done if raw VBI is active */
+	if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
+		return 0;
 
-		if (is_pal) {
-			for (i = 7; i <= 23; i++) {
-				u8 v = cx18_av_read(cx, 0x424 + i - 7);
+	if (is_pal) {
+		for (i = 7; i <= 23; i++) {
+			u8 v = cx18_av_read(cx, 0x424 + i - 7);
 
-				svbi->service_lines[0][i] = lcr2vbi[v >> 4];
-				svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
-				svbi->service_set |= svbi->service_lines[0][i] |
-					svbi->service_lines[1][i];
-			}
-		} else {
-			for (i = 10; i <= 21; i++) {
-				u8 v = cx18_av_read(cx, 0x424 + i - 10);
+			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+			svbi->service_set |= svbi->service_lines[0][i] |
+				svbi->service_lines[1][i];
+		}
+	} else {
+		for (i = 10; i <= 21; i++) {
+			u8 v = cx18_av_read(cx, 0x424 + i - 10);
 
-				svbi->service_lines[0][i] = lcr2vbi[v >> 4];
-				svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
-				svbi->service_set |= svbi->service_lines[0][i] |
-					svbi->service_lines[1][i];
-			}
+			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+			svbi->service_set |= svbi->service_lines[0][i] |
+				svbi->service_lines[1][i];
 		}
-		break;
 	}
+	return 0;
+}
 
-	case VIDIOC_S_FMT:
-	{
-		int is_pal = !(state->std & V4L2_STD_525_60);
-		int vbi_offset = is_pal ? 1 : 0;
-		int i, x;
-		u8 lcr[24];
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
+{
+	struct cx18_av_state *state = &cx->av_state;
+	struct v4l2_sliced_vbi_format *svbi;
+	int is_pal = !(state->std & V4L2_STD_525_60);
+	int i, x;
+	u8 lcr[24];
 
-		fmt = arg;
-		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
-		    fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
-			return -EINVAL;
-		svbi = &fmt->fmt.sliced;
-		if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-			/* raw VBI */
-			memset(svbi, 0, sizeof(*svbi));
+	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+			fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+		return -EINVAL;
+	svbi = &fmt->fmt.sliced;
+	if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		/* raw VBI */
+		memset(svbi, 0, sizeof(*svbi));
 
-			/* Setup standard */
-			cx18_av_std_setup(cx);
+		/* Setup standard */
+		cx18_av_std_setup(cx);
 
-			/* VBI Offset */
-			cx18_av_write(cx, 0x47f, vbi_offset);
-			cx18_av_write(cx, 0x404, 0x2e);
-			break;
-		}
+		/* VBI Offset */
+		cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+		cx18_av_write(cx, 0x404, 0x2e);
+		return 0;
+	}
 
-		for (x = 0; x <= 23; x++)
-			lcr[x] = 0x00;
+	for (x = 0; x <= 23; x++)
+		lcr[x] = 0x00;
 
-		/* Setup standard */
-		cx18_av_std_setup(cx);
+	/* Setup standard */
+	cx18_av_std_setup(cx);
 
-		/* Sliced VBI */
-		cx18_av_write(cx, 0x404, 0x32);	/* Ancillary data */
-		cx18_av_write(cx, 0x406, 0x13);
-		cx18_av_write(cx, 0x47f, vbi_offset);
+	/* Sliced VBI */
+	cx18_av_write(cx, 0x404, 0x32);	/* Ancillary data */
+	cx18_av_write(cx, 0x406, 0x13);
+	cx18_av_write(cx, 0x47f, state->slicer_line_delay);
 
-		if (is_pal) {
-			for (i = 0; i <= 6; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
-		} else {
-			for (i = 0; i <= 9; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
+	/* Force impossible lines to 0 */
+	if (is_pal) {
+		for (i = 0; i <= 6; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
+	} else {
+		for (i = 0; i <= 9; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
 
-			for (i = 22; i <= 23; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
-		}
+		for (i = 22; i <= 23; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
+	}
 
-		for (i = 7; i <= 23; i++) {
-			for (x = 0; x <= 1; x++) {
-				switch (svbi->service_lines[1-x][i]) {
-				case V4L2_SLICED_TELETEXT_B:
-					lcr[i] |= 1 << (4 * x);
-					break;
-				case V4L2_SLICED_WSS_625:
-					lcr[i] |= 4 << (4 * x);
-					break;
-				case V4L2_SLICED_CAPTION_525:
-					lcr[i] |= 6 << (4 * x);
-					break;
-				case V4L2_SLICED_VPS:
-					lcr[i] |= 9 << (4 * x);
-					break;
-				}
+	/* Build register values for requested service lines */
+	for (i = 7; i <= 23; i++) {
+		for (x = 0; x <= 1; x++) {
+			switch (svbi->service_lines[1-x][i]) {
+			case V4L2_SLICED_TELETEXT_B:
+				lcr[i] |= 1 << (4 * x);
+				break;
+			case V4L2_SLICED_WSS_625:
+				lcr[i] |= 4 << (4 * x);
+				break;
+			case V4L2_SLICED_CAPTION_525:
+				lcr[i] |= 6 << (4 * x);
+				break;
+			case V4L2_SLICED_VPS:
+				lcr[i] |= 9 << (4 * x);
+				break;
 			}
 		}
+	}
 
-		if (is_pal) {
-			for (x = 1, i = 0x424; i <= 0x434; i++, x++)
-				cx18_av_write(cx, i, lcr[6 + x]);
-		} else {
-			for (x = 1, i = 0x424; i <= 0x430; i++, x++)
-				cx18_av_write(cx, i, lcr[9 + x]);
-			for (i = 0x431; i <= 0x434; i++)
-				cx18_av_write(cx, i, 0);
-		}
-
-		cx18_av_write(cx, 0x43c, 0x16);
-		cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
-		break;
+	if (is_pal) {
+		for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+			cx18_av_write(cx, i, lcr[6 + x]);
+	} else {
+		for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+			cx18_av_write(cx, i, lcr[9 + x]);
+		for (i = 0x431; i <= 0x434; i++)
+			cx18_av_write(cx, i, 0);
 	}
 
-	case VIDIOC_INT_DECODE_VBI_LINE:
-	{
-		struct v4l2_decode_vbi_line *vbi = arg;
-		u8 *p = vbi->p;
-		int id1, id2, l, err = 0;
+	cx18_av_write(cx, 0x43c, 0x16);
+	/* FIXME - should match vblank set in cx18_av_std_setup() */
+	cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
+	return 0;
+}
 
-		if (p[0] || p[1] != 0xff || p[2] != 0xff ||
-		    (p[3] != 0x55 && p[3] != 0x91)) {
-			vbi->line = vbi->type = 0;
-			break;
-		}
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+				   struct v4l2_decode_vbi_line *vbi)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	struct cx18_av_state *state = &cx->av_state;
+	struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
+	u8 *p;
+	int did, sdid, l, err = 0;
 
-		p += 4;
-		id1 = p[-1];
-		id2 = p[0] & 0xf;
-		l = p[2] & 0x3f;
-		l += state->vbi_line_offset;
-		p += 4;
+	/*
+	 * Check for the ancillary data header for sliced VBI
+	 */
+	if (anc->preamble[0] ||
+			anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
+			(anc->did != sliced_vbi_did[0] &&
+			 anc->did != sliced_vbi_did[1])) {
+		vbi->line = vbi->type = 0;
+		return 0;
+	}
 
-		switch (id2) {
-		case 1:
-			id2 = V4L2_SLICED_TELETEXT_B;
-			break;
-		case 4:
-			id2 = V4L2_SLICED_WSS_625;
-			break;
-		case 6:
-			id2 = V4L2_SLICED_CAPTION_525;
-			err = !odd_parity(p[0]) || !odd_parity(p[1]);
-			break;
-		case 9:
-			id2 = V4L2_SLICED_VPS;
-			if (decode_vps(p, p) != 0)
-				err = 1;
-			break;
-		default:
-			id2 = 0;
-			err = 1;
-			break;
-		}
+	did = anc->did;
+	sdid = anc->sdid & 0xf;
+	l = anc->idid[0] & 0x3f;
+	l += state->slicer_line_offset;
+	p = anc->payload;
 
-		vbi->type = err ? 0 : id2;
-		vbi->line = err ? 0 : l;
-		vbi->is_second_field = err ? 0 : (id1 == 0x55);
-		vbi->p = p;
+	/* Decode the SDID set by the slicer */
+	switch (sdid) {
+	case 1:
+		sdid = V4L2_SLICED_TELETEXT_B;
+		break;
+	case 4:
+		sdid = V4L2_SLICED_WSS_625;
+		break;
+	case 6:
+		sdid = V4L2_SLICED_CAPTION_525;
+		err = !odd_parity(p[0]) || !odd_parity(p[1]);
+		break;
+	case 9:
+		sdid = V4L2_SLICED_VPS;
+		if (decode_vps(p, p) != 0)
+			err = 1;
+		break;
+	default:
+		sdid = 0;
+		err = 1;
 		break;
-	}
 	}
 
+	vbi->type = err ? 0 : sdid;
+	vbi->line = err ? 0 : l;
+	vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
+	vbi->p = p;
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-cards.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-cards.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,12 +51,12 @@ static struct cx18_card_tuner_i2c cx18_i
 static const struct cx18_card cx18_card_hvr1600_esmt = {
 	.type = CX18_CARD_HVR_1600_ESMT,
 	.name = "Hauppauge HVR-1600",
-	.comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+	.comment = "Simultaneous Digital and Analog TV capture supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
+	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
-		  CX18_HW_CS5345 | CX18_HW_DVB,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
@@ -97,12 +97,12 @@ static const struct cx18_card cx18_card_
 static const struct cx18_card cx18_card_hvr1600_samsung = {
 	.type = CX18_CARD_HVR_1600_SAMSUNG,
 	.name = "Hauppauge HVR-1600 (Preproduction)",
-	.comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+	.comment = "Simultaneous Digital and Analog TV capture supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
+	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
-		  CX18_HW_CS5345 | CX18_HW_DVB,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
@@ -152,10 +152,10 @@ static const struct cx18_card_pci_info c
 static const struct cx18_card cx18_card_h900 = {
 	.type = CX18_CARD_COMPRO_H900,
 	.name = "Compro VideoMate H900",
-	.comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+	.comment = "Analog TV capture supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
-	.hw_all = CX18_HW_TUNER,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
@@ -201,8 +201,8 @@ static const struct cx18_card cx18_card_
 	.name = "Yuan MPC718",
 	.comment = "Analog video capture works; some audio line in may not.\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
-	.hw_all = CX18_HW_TUNER,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
@@ -249,11 +249,11 @@ static const struct cx18_card_pci_info c
 static const struct cx18_card cx18_card_cnxt_raptor_pal = {
 	.type = CX18_CARD_CNXT_RAPTOR_PAL,
 	.name = "Conexant Raptor PAL/SECAM",
-	.comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+	.comment = "Analog TV capture supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
-	.hw_muxer = CX18_HW_GPIO,
-	.hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_muxer = CX18_HW_GPIO_MUX,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
@@ -306,8 +306,8 @@ static const struct cx18_card cx18_card_
 	.comment = "Experimenters and photos needed for device to work well.\n"
 		  "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
-	.hw_all = CX18_HW_TUNER,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE6 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
@@ -339,19 +339,21 @@ static const struct cx18_card cx18_card_
 /* Leadtek WinFast PVR2100 */
 
 static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
-	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 },
+	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100   */
+	{ PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
 	{ 0, 0, 0 }
 };
 
 static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 	.type = CX18_CARD_LEADTEK_PVR2100,
-	.name = "Leadtek WinFast PVR2100",
+	.name = "Leadtek WinFast PVR2100/DVR3100 H",
 	.comment = "Experimenters and photos needed for device to work well.\n"
 		  "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
-	.hw_audio_ctrl = CX18_HW_CX23418,
-	.hw_muxer = CX18_HW_GPIO,
-	.hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+	.hw_audio_ctrl = CX18_HW_418_AV,
+	.hw_muxer = CX18_HW_GPIO_MUX,
+	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
+		  CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-cards.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-cards.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-cards.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-cards.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,12 +22,13 @@
  */
 
 /* hardware flags */
-#define CX18_HW_TUNER     (1 << 0)
-#define CX18_HW_TVEEPROM  (1 << 1)
-#define CX18_HW_CS5345    (1 << 2)
-#define CX18_HW_GPIO      (1 << 3)
-#define CX18_HW_CX23418   (1 << 4)
-#define CX18_HW_DVB   	  (1 << 5)
+#define CX18_HW_TUNER		(1 << 0)
+#define CX18_HW_TVEEPROM	(1 << 1)
+#define CX18_HW_CS5345		(1 << 2)
+#define CX18_HW_DVB		(1 << 3)
+#define CX18_HW_418_AV		(1 << 4)
+#define CX18_HW_GPIO_MUX	(1 << 5)
+#define CX18_HW_GPIO_RESET_CTRL	(1 << 6)
 
 /* video inputs */
 #define	CX18_CARD_INPUT_VID_TUNER	1
@@ -49,8 +50,7 @@
 /* V4L2 capability aliases */
 #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
 			  V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
-			  V4L2_CAP_VBI_CAPTURE)
-/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
+			  V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
 
 struct cx18_card_video_input {
 	u8  video_type; 	/* video input type */
@@ -122,7 +122,7 @@ struct cx18_card {
 	char *comment;
 	u32 v4l2_capabilities;
 	u32 hw_audio_ctrl;	/* hardware used for the V4L2 controls (only
-				   1 dev allowed) */
+				   1 dev allowed currently) */
 	u32 hw_muxer;		/* hardware used to multiplex audio input */
 	u32 hw_all;		/* all hardware used by the board */
 	struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-controls.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-controls.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-controls.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-controls.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,14 +22,13 @@
  */
 
 #include "cx18-driver.h"
-#include "cx18-av-core.h"
 #include "cx18-cards.h"
 #include "cx18-ioctl.h"
 #include "cx18-audio.h"
-#include "cx18-i2c.h"
 #include "cx18-mailbox.h"
 #include "cx18-controls.h"
 
+/* Must be sorted from low to high control ID! */
 static const u32 user_ctrls[] = {
 	V4L2_CID_USER_CLASS,
 	V4L2_CID_BRIGHTNESS,
@@ -66,7 +65,7 @@ int cx18_queryctrl(struct file *file, vo
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
 	case V4L2_CID_CONTRAST:
-		if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
+		if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
 			qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
 		return 0;
 
@@ -76,7 +75,7 @@ int cx18_queryctrl(struct file *file, vo
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_LOUDNESS:
-		if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
+		if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
 			qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
 		return 0;
 
@@ -125,7 +124,7 @@ static int cx18_s_ctrl(struct cx18 *cx,
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
 	case V4L2_CID_CONTRAST:
-		return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
+		return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
 
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_MUTE:
@@ -133,7 +132,7 @@ static int cx18_s_ctrl(struct cx18 *cx,
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_LOUDNESS:
-		return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
+		return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
 
 	default:
 		CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
@@ -150,7 +149,7 @@ static int cx18_g_ctrl(struct cx18 *cx,
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
 	case V4L2_CID_CONTRAST:
-		return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
+		return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
 
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_MUTE:
@@ -158,7 +157,8 @@ static int cx18_g_ctrl(struct cx18 *cx,
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
 	case V4L2_CID_AUDIO_LOUDNESS:
-		return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
+		return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
+
 	default:
 		CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
 		return -EINVAL;
@@ -166,38 +166,57 @@ static int cx18_g_ctrl(struct cx18 *cx,
 	return 0;
 }
 
-static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt)
+static int cx18_setup_vbi_fmt(struct cx18 *cx,
+			      enum v4l2_mpeg_stream_vbi_fmt fmt,
+			      enum v4l2_mpeg_stream_type type)
 {
 	if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
 		return -EINVAL;
 	if (atomic_read(&cx->ana_capturing) > 0)
 		return -EBUSY;
 
-	/* First try to allocate sliced VBI buffers if needed. */
-	if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) {
+	if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
+	    type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
+		/* We don't do VBI insertion aside from IVTV format in a PS */
+		cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
+		CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
+				"the MPEG stream\n");
+		return 0;
+	}
+
+	/* Allocate sliced VBI buffers if needed. */
+	if (cx->vbi.sliced_mpeg_data[0] == NULL) {
 		int i;
 
 		for (i = 0; i < CX18_VBI_FRAMES; i++) {
-			/* Yuck, hardcoded. Needs to be a define */
-			cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
+			cx->vbi.sliced_mpeg_data[i] =
+			       kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
 			if (cx->vbi.sliced_mpeg_data[i] == NULL) {
 				while (--i >= 0) {
 					kfree(cx->vbi.sliced_mpeg_data[i]);
 					cx->vbi.sliced_mpeg_data[i] = NULL;
 				}
+				cx->vbi.insert_mpeg =
+						  V4L2_MPEG_STREAM_VBI_FMT_NONE;
+				CX18_WARN("Unable to allocate buffers for "
+					  "sliced VBI data insertion\n");
 				return -ENOMEM;
 			}
 		}
 	}
 
 	cx->vbi.insert_mpeg = fmt;
+	CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
+			"when sliced VBI is enabled\n");
 
-	if (cx->vbi.insert_mpeg == 0)
-		return 0;
-	/* Need sliced data for mpeg insertion */
+	/*
+	 * If our current settings have no lines set for capture, store a valid,
+	 * default set of service lines to capture, in our current settings.
+	 */
 	if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
 		if (cx->is_60hz)
-			cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
+			cx->vbi.sliced_in->service_set =
+							V4L2_SLICED_CAPTION_525;
 		else
 			cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
 		cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
@@ -259,10 +278,12 @@ int cx18_s_ext_ctrls(struct file *file,
 		return err;
 	}
 	if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+		static u32 freqs[3] = { 44100, 48000, 32000 };
 		struct cx18_api_func_private priv;
 		struct cx2341x_mpeg_params p = cx->params;
 		int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
 						c, VIDIOC_S_EXT_CTRLS);
+		unsigned int idx;
 
 		if (err)
 			return err;
@@ -277,16 +298,23 @@ int cx18_s_ext_ctrls(struct file *file,
 			fmt.fmt.pix.width = cx->params.width
 						/ (is_mpeg1 ? 2 : 1);
 			fmt.fmt.pix.height = cx->params.height;
-			cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
+			v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
 		}
 		priv.cx = cx;
 		priv.s = &cx->streams[id->type];
 		err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
-		if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
-			err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
+		if (!err &&
+		    (cx->params.stream_vbi_fmt != p.stream_vbi_fmt ||
+		     cx->params.stream_type != p.stream_type))
+			err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt,
+						 p.stream_type);
 		cx->params = p;
 		cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
-		cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
+		idx = p.audio_properties & 0x03;
+		/* The audio clock of the digitizer must match the codec sample
+		   rate otherwise you get some very strange effects. */
+		if (idx < sizeof(freqs))
+			cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
 		return err;
 	}
 	return -EINVAL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-driver.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-driver.c	2013-05-03 16:44:18.000000000 -0400
@@ -39,10 +39,6 @@
 
 #include <media/tveeprom.h>
 
-
-/* var to keep track of the number of array elements in use */
-int cx18_cards_active;
-
 /* If you have already X v4l cards, then set this to X. This way
    the device numbers stay matched. Example: you have a WinTV card
    without radio and a Compro H900 with. Normally this would give a
@@ -50,12 +46,6 @@ int cx18_cards_active;
    setting this to 1 you ensure that radio0 is now also radio1. */
 int cx18_first_minor;
 
-/* Master variable for all cx18 info */
-struct cx18 *cx18_cards[CX18_MAX_CARDS];
-
-/* Protects cx18_cards_active */
-DEFINE_SPINLOCK(cx18_cards_lock);
-
 /* add your revision and whatnot here */
 static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
 	{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl
 
 MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
 
+static atomic_t cx18_instance = ATOMIC_INIT(0);
+
 /* Parameter declarations */
 static int cardtype[CX18_MAX_CARDS];
 static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -159,7 +151,7 @@ MODULE_PARM_DESC(cardtype,
 		 "\t\t\t 4 = Yuan MPC718\n"
 		 "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
 		 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
-		 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
+		 "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n"
 		 "\t\t\t 0 = Autodetect (default)\n"
 		 "\t\t\t-1 = Ignore this card\n\t\t");
 MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -277,11 +269,16 @@ static void cx18_iounmap(struct cx18 *cx
 /* Hauppauge card? get values from tveeprom */
 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
 {
+	struct i2c_client c;
 	u8 eedata[256];
 
-	cx->i2c_client[0].addr = 0xA0 >> 1;
-	tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
-	tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
+	memset(&c, 0, sizeof(c));
+	strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
+	c.adapter = &cx->i2c_adap[0];
+	c.addr = 0xA0 >> 1;
+
+	tveeprom_read(&c, eedata, sizeof(eedata));
+	tveeprom_hauppauge_analog(&c, tv, eedata);
 }
 
 static void cx18_process_eeprom(struct cx18 *cx)
@@ -448,34 +445,38 @@ static void cx18_process_options(struct
 	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
 	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
 	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
-	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
 	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
 	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
 
-	/* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+	/* Ensure stream_buffers & stream_buf_size are valid */
 	for (i = 0; i < CX18_MAX_STREAMS; i++) {
-		/* User said to use 0 buffers */
-		if (cx->stream_buffers[i] == 0) {
-			cx->options.megabytes[i] = 0;
-			cx->stream_buf_size[i] = 0;
-			continue;
-		}
-		/* User said to use 0 MB total */
-		if (cx->options.megabytes[i] <= 0) {
+		if (cx->stream_buffers[i] == 0 ||     /* User said 0 buffers */
+		    cx->options.megabytes[i] <= 0 ||  /* User said 0 MB total */
+		    cx->stream_buf_size[i] <= 0) {    /* User said buf size 0 */
 			cx->options.megabytes[i] = 0;
 			cx->stream_buffers[i] = 0;
 			cx->stream_buf_size[i] = 0;
 			continue;
 		}
-		/* VBI is computed later or user said buffer has size 0 */
-		if (cx->stream_buf_size[i] <= 0) {
-			if (i != CX18_ENC_STREAM_TYPE_VBI) {
-				cx->options.megabytes[i] = 0;
-				cx->stream_buffers[i] = 0;
-				cx->stream_buf_size[i] = 0;
+		/*
+		 * VBI is a special case where the stream_buf_size is fixed
+		 * and already in bytes
+		 */
+		if (i == CX18_ENC_STREAM_TYPE_VBI) {
+			if (cx->stream_buffers[i] < 0) {
+				cx->stream_buffers[i] =
+					cx->options.megabytes[i] * 1024 * 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 * 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];
@@ -487,9 +488,9 @@ static void cx18_process_options(struct
 		cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
 	}
 
-	cx->options.cardtype = cardtype[cx->num];
-	cx->options.tuner = tuner[cx->num];
-	cx->options.radio = radio[cx->num];
+	cx->options.cardtype = cardtype[cx->instance];
+	cx->options.tuner = tuner[cx->instance];
+	cx->options.radio = radio[cx->instance];
 
 	cx->std = cx18_parse_std(cx);
 	if (cx->options.cardtype == -1) {
@@ -502,7 +503,7 @@ static void cx18_process_options(struct
 	else if (cx->options.cardtype != 0)
 		CX18_ERR("Unknown user specified type, trying to autodetect card\n");
 	if (cx->card == NULL) {
-		if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
+		if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
 			cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 			CX18_INFO("Autodetected Hauppauge card\n");
 		}
@@ -512,13 +513,13 @@ static void cx18_process_options(struct
 			if (cx->card->pci_list == NULL)
 				continue;
 			for (j = 0; cx->card->pci_list[j].device; j++) {
-				if (cx->dev->device !=
+				if (cx->pci_dev->device !=
 				    cx->card->pci_list[j].device)
 					continue;
-				if (cx->dev->subsystem_vendor !=
+				if (cx->pci_dev->subsystem_vendor !=
 				    cx->card->pci_list[j].subsystem_vendor)
 					continue;
-				if (cx->dev->subsystem_device !=
+				if (cx->pci_dev->subsystem_device !=
 				    cx->card->pci_list[j].subsystem_device)
 					continue;
 				CX18_INFO("Autodetected %s card\n", cx->card->name);
@@ -531,9 +532,10 @@ done:
 	if (cx->card == NULL) {
 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 		CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
-		     cx->dev->vendor, cx->dev->device);
+			 cx->pci_dev->vendor, cx->pci_dev->device);
 		CX18_ERR("              subsystem vendor/device: [%04x:%04x]\n",
-		     cx->dev->subsystem_vendor, cx->dev->subsystem_device);
+			 cx->pci_dev->subsystem_vendor,
+			 cx->pci_dev->subsystem_device);
 		CX18_ERR("Defaulting to %s card\n", cx->card->name);
 		CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
 		CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
@@ -545,7 +547,7 @@ done:
 }
 
 /* Precondition: the cx18 structure has been memset to 0. Only
-   the dev and num fields have been filled in.
+   the dev and instance fields have been filled in.
    No assumptions on the card type may be made here (see cx18_init_struct2
    for that).
  */
@@ -553,18 +555,14 @@ static int __devinit cx18_init_struct1(s
 {
 	int i;
 
-	cx->base_addr = pci_resource_start(cx->dev, 0);
+	cx->base_addr = pci_resource_start(cx->pci_dev, 0);
 
 	mutex_init(&cx->serialize_lock);
-	mutex_init(&cx->i2c_bus_lock[0]);
-	mutex_init(&cx->i2c_bus_lock[1]);
 	mutex_init(&cx->gpio_lock);
 	mutex_init(&cx->epu2apu_mb_lock);
 	mutex_init(&cx->epu2cpu_mb_lock);
 
-	spin_lock_init(&cx->lock);
-
-	cx->work_queue = create_singlethread_workqueue(cx->name);
+	cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
 	if (cx->work_queue == NULL) {
 		CX18_ERR("Unable to create work hander thread\n");
 		return -ENOMEM;
@@ -587,7 +585,8 @@ static int __devinit cx18_init_struct1(s
 		(cx->params.video_temporal_filter_mode << 1) |
 		(cx->params.video_median_filter_type << 2);
 	cx->params.port = CX2341X_PORT_MEMORY;
-	cx->params.capabilities = CX2341X_CAP_HAS_TS;
+	cx->params.capabilities =
+				CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
 	init_waitqueue_head(&cx->cap_w);
 	init_waitqueue_head(&cx->mb_apu_waitq);
 	init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -597,49 +596,6 @@ 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;
 
-	/*
-	 * The VBI line sizes depend on the pixel clock and the horiz rate
-	 *
-	 * (1/Fh)*(2*Fp) = Samples/line
-	 *     = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
-	 *
-	 *  Sliced VBI is sent as ancillary data during horizontal blanking
-	 *  Raw VBI is sent as active video samples during vertcal blanking
-	 *
-	 *  We use a  BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
-	 *  length of 720 pixels @ 4:2:2 sampling.  Thus...
-	 *
-	 *  For systems that use a 15.734 kHz horizontal rate, such as
-	 *  NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
-	 *
-	 *  (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
-	 *  4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
-	 *
-	 *  For systems that use a 15.625 kHz horizontal rate, such as
-	 *  PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
-	 *
-	 *  (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
-	 *  4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
-	 *
-	 */
-
-	/* FIXME: init these based on tuner std & modify when std changes */
-	/* CX18-AV-Core number of VBI samples output per horizontal line */
-	cx->vbi.raw_decoder_line_size = 1444;   /* 4 byte SAV + 2 * 720 */
-	cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
-
-	/* CX18-AV-Core VBI samples/line possibly rounded up */
-	cx->vbi.raw_size = 1444;   /* Real max size is 1444 */
-	cx->vbi.sliced_size = 284; /* Real max size is  284 */
-
-	/*
-	 * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
-	 * Task Field VerticalBlank HorizontalBlank 0 0 0 0
-	 */
-	cx->vbi.raw_decoder_sav_odd_field = 0x20;     /*   V  */
-	cx->vbi.raw_decoder_sav_even_field = 0x60;    /*  FV  */
-	cx->vbi.sliced_decoder_sav_odd_field = 0xB0;  /* T VH - actually EAV */
-	cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
 	return 0;
 }
 
@@ -668,15 +624,9 @@ static void __devinit cx18_init_struct2(
 		i = 0;
 	cx->active_input = i;
 	cx->audio_input = cx->card->video_inputs[i].audio_index;
-	cx->av_state.vid_input = CX18_AV_COMPOSITE7;
-	cx->av_state.aud_input = CX18_AV_AUDIO8;
-	cx->av_state.audclk_freq = 48000;
-	cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
-	/* FIXME - 8 is NTSC value, investigate */
-	cx->av_state.vbi_line_offset = 8;
 }
 
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
+static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
 			  const struct pci_device_id *pci_id)
 {
 	u16 cmd;
@@ -684,124 +634,125 @@ static int cx18_setup_pci(struct cx18 *c
 
 	CX18_DEBUG_INFO("Enabling pci device\n");
 
-	if (pci_enable_device(dev)) {
-		CX18_ERR("Can't enable device %d!\n", cx->num);
+	if (pci_enable_device(pci_dev)) {
+		CX18_ERR("Can't enable device %d!\n", cx->instance);
 		return -EIO;
 	}
-	if (pci_set_dma_mask(dev, 0xffffffff)) {
-		CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
+	if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
+		CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
 		return -EIO;
 	}
 	if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
-		CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
+		CX18_ERR("Cannot request encoder memory region, card %d\n",
+			 cx->instance);
 		return -EIO;
 	}
 
 	/* Enable bus mastering and memory mapped IO for the CX23418 */
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
 	cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
-	pci_write_config_word(dev, PCI_COMMAND, cmd);
+	pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
 
-	pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev);
+	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
 
 	if (pci_latency < 64 && cx18_pci_latency) {
 		CX18_INFO("Unreasonably low latency timer, "
 			       "setting to 64 (was %d)\n", pci_latency);
-		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-		pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
+		pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
 	}
 
 	CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
 		   "irq: %d, latency: %d, memory: 0x%lx\n",
-		   cx->dev->device, cx->card_rev, dev->bus->number,
-		   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
-		   cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
+		   cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
+		   PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
+		   cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr);
 
 	return 0;
 }
 
-#ifdef MODULE
-static u32 cx18_request_module(struct cx18 *cx, u32 hw,
-		const char *name, u32 id)
-{
-	if ((hw & id) == 0)
-		return hw;
-	if (request_module(name) != 0) {
-		CX18_ERR("Failed to load module %s\n", name);
-		return hw & ~id;
-	}
-	CX18_DEBUG_INFO("Loaded module %s\n", name);
-	return hw;
-}
-#endif
-
-static void cx18_load_and_init_modules(struct cx18 *cx)
+static void cx18_init_subdevs(struct cx18 *cx)
 {
 	u32 hw = cx->card->hw_all;
+	u32 device;
 	int i;
 
-#ifdef MODULE
-	/* load modules */
-#ifdef CONFIG_MEDIA_TUNER_MODULE
-	hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
-#endif
-#ifdef CONFIG_VIDEO_CS5345_MODULE
-	hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
-#endif
-#endif
-
-	/* check which i2c devices are actually found */
-	for (i = 0; i < 32; i++) {
-		u32 device = 1 << i;
+	for (i = 0, device = 1; i < 32; i++, device <<= 1) {
 
 		if (!(device & hw))
 			continue;
-		if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
-		    device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
-			/* These 'devices' do not use i2c probing */
+
+		switch (device) {
+		case CX18_HW_DVB:
+		case CX18_HW_TVEEPROM:
+			/* These subordinate devices do not use probing */
 			cx->hw_flags |= device;
-			continue;
-		}
-		cx18_i2c_register(cx, i);
-		if (cx18_i2c_hw_addr(cx, device) > 0)
+			break;
+		case CX18_HW_418_AV:
+			/* The A/V decoder gets probed earlier to set PLLs */
+			/* Just note that the card uses it (i.e. has analog) */
 			cx->hw_flags |= device;
+			break;
+		case CX18_HW_GPIO_RESET_CTRL:
+			/*
+			 * The Reset Controller gets probed and added to
+			 * hw_flags earlier for i2c adapter/bus initialization
+			 */
+			break;
+		case CX18_HW_GPIO_MUX:
+			if (cx18_gpio_register(cx, device) == 0)
+				cx->hw_flags |= device;
+			break;
+		default:
+			if (cx18_i2c_register(cx, i) == 0)
+				cx->hw_flags |= device;
+			break;
+		}
 	}
 
-	hw = cx->hw_flags;
+	if (cx->hw_flags & CX18_HW_418_AV)
+		cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
+
+	if (cx->card->hw_muxer != 0)
+		cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
 }
 
-static int __devinit cx18_probe(struct pci_dev *dev,
+static int __devinit cx18_probe(struct pci_dev *pci_dev,
 				const struct pci_device_id *pci_id)
 {
 	int retval = 0;
 	int i;
-	int vbi_buf_size;
 	u32 devtype;
 	struct cx18 *cx;
 
-	spin_lock(&cx18_cards_lock);
-
-	/* Make sure we've got a place for this card */
-	if (cx18_cards_active == CX18_MAX_CARDS) {
-		printk(KERN_ERR "cx18:  Maximum number of cards detected (%d).\n",
-			      cx18_cards_active);
-		spin_unlock(&cx18_cards_lock);
+	/* FIXME - module parameter arrays constrain max instances */
+	i = atomic_inc_return(&cx18_instance) - 1;
+	if (i >= CX18_MAX_CARDS) {
+		printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
+		       "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
 		return -ENOMEM;
 	}
 
 	cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
-	if (!cx) {
-		spin_unlock(&cx18_cards_lock);
+	if (cx == NULL) {
+		printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
+		       i);
 		return -ENOMEM;
 	}
-	cx18_cards[cx18_cards_active] = cx;
-	cx->dev = dev;
-	cx->num = cx18_cards_active++;
-	snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
-	CX18_INFO("Initializing card #%d\n", cx->num);
+	cx->pci_dev = pci_dev;
+	cx->instance = i;
 
-	spin_unlock(&cx18_cards_lock);
+	retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
+	if (retval) {
+		printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
+		       "\n", cx->instance);
+		kfree(cx);
+		return retval;
+	}
+	snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
+		 cx->instance);
+	CX18_INFO("Initializing card %d\n", cx->instance);
 
 	cx18_process_options(cx);
 	if (cx->options.cardtype == -1) {
@@ -816,13 +767,10 @@ static int __devinit cx18_probe(struct p
 	CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
 
 	/* PCI Device Setup */
-	retval = cx18_setup_pci(cx, dev, pci_id);
+	retval = cx18_setup_pci(cx, pci_dev, pci_id);
 	if (retval != 0)
 		goto free_workqueue;
 
-	/* save cx in the pci struct for later use */
-	pci_set_drvdata(dev, cx);
-
 	/* map io memory */
 	CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
 		   cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
@@ -856,6 +804,23 @@ static int __devinit cx18_probe(struct p
 
 	cx18_gpio_init(cx);
 
+	/* Initialize integrated A/V decoder early to set PLLs, just in case */
+	retval = cx18_av_probe(cx);
+	if (retval) {
+		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) {
+		if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
+			CX18_WARN("Could not register GPIO reset controller"
+				  "subdevice; proceeding anyway.\n");
+		else
+			cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
+	}
+
 	/* active i2c  */
 	CX18_DEBUG_INFO("activating i2c...\n");
 	retval = init_cx18_i2c(cx);
@@ -864,8 +829,6 @@ static int __devinit cx18_probe(struct p
 		goto free_map;
 	}
 
-	CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
-
 	if (cx->card->hw_all & CX18_HW_TVEEPROM) {
 		/* Based on the model number the cardtype may be changed.
 		   The PCI IDs are not always reliable. */
@@ -881,8 +844,9 @@ static int __devinit cx18_probe(struct p
 	cx18_init_scb(cx);
 
 	/* Register IRQ */
-	retval = request_irq(cx->dev->irq, cx18_irq_handler,
-			     IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
+	retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
+			     IRQF_SHARED | IRQF_DISABLED,
+			     cx->v4l2_dev.name, (void *)cx);
 	if (retval) {
 		CX18_ERR("Failed to register irq %d\n", retval);
 		goto free_i2c;
@@ -917,33 +881,14 @@ static int __devinit cx18_probe(struct p
 	   initialization. */
 	cx18_init_struct2(cx);
 
-	cx18_load_and_init_modules(cx);
+	cx18_init_subdevs(cx);
 
-	if (cx->std & V4L2_STD_525_60) {
+	if (cx->std & V4L2_STD_525_60)
 		cx->is_60hz = 1;
-		cx->is_out_60hz = 1;
-	} else {
+	else
 		cx->is_50hz = 1;
-		cx->is_out_50hz = 1;
-	}
-	cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
-
-	/*
-	 * FIXME: setting the buffer size based on the tuner standard is
-	 * suboptimal, as the CVBS and SVideo inputs could use a different std
-	 * and the buffer could end up being too small in that case.
-	 */
-	vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
-	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
 
-	if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
-		cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
-		   cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
-		   / vbi_buf_size;
-	else
-		cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
-		     cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
-		     / (1024 * 1024);
+	cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
 
 	if (cx->options.radio > 0)
 		cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -956,7 +901,7 @@ static int __devinit cx18_probe(struct p
 		setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
 		setup.tuner_callback = (setup.type == TUNER_XC2028) ?
 			cx18_reset_tuner_gpio : NULL;
-		cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
+		cx18_call_all(cx, tuner, s_type_addr, &setup);
 		if (setup.type == TUNER_XC2028) {
 			static struct xc2028_ctrl ctrl = {
 				.fname = "/*(DEBLOBBED)*/",
@@ -966,7 +911,7 @@ static int __devinit cx18_probe(struct p
 				.tuner = cx->options.tuner,
 				.priv = &ctrl,
 			};
-			cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
+			cx18_call_all(cx, tuner, s_config, &cfg);
 		}
 	}
 
@@ -985,14 +930,13 @@ static int __devinit cx18_probe(struct p
 		goto free_streams;
 	}
 
-	CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
-
+	CX18_INFO("Initialized card: %s\n", cx->card_name);
 	return 0;
 
 free_streams:
 	cx18_streams_cleanup(cx, 1);
 free_irq:
-	free_irq(cx->dev->irq, (void *)cx);
+	free_irq(cx->pci_dev->irq, (void *)cx);
 free_i2c:
 	exit_cx18_i2c(cx);
 free_map:
@@ -1006,11 +950,8 @@ err:
 		retval = -ENODEV;
 	CX18_ERR("Error %d on initialization\n", retval);
 
-	i = cx->num;
-	spin_lock(&cx18_cards_lock);
-	kfree(cx18_cards[i]);
-	cx18_cards[i] = NULL;
-	spin_unlock(&cx18_cards_lock);
+	v4l2_device_unregister(&cx->v4l2_dev);
+	kfree(cx);
 	return retval;
 }
 
@@ -1043,8 +984,21 @@ int cx18_init_on_first_open(struct cx18
 	}
 	set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
 
-	/* Init the firmware twice to work around a silicon bug
-	 * transport related. */
+	/*
+	 * Init the firmware twice to work around a silicon bug
+	 * with the digital TS.
+	 *
+	 * The second firmware load requires us to normalize the APU state,
+	 * or the audio for the first analog capture will be badly incorrect.
+	 *
+	 * I can't seem to call APU_RESETAI and have it succeed without the
+	 * APU capturing audio, so we start and stop it here to do the reset
+	 */
+
+	/* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+	cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+	cx18_vapi(cx, CX18_APU_RESETAI, 0);
+	cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
 
 	fw_retry_count = 3;
 	while (--fw_retry_count > 0) {
@@ -1060,6 +1014,22 @@ int cx18_init_on_first_open(struct cx18
 		return -ENXIO;
 	}
 
+	/*
+	 * The second firmware load requires us to normalize the APU state,
+	 * or the audio for the first analog capture will be badly incorrect.
+	 *
+	 * I can't seem to call APU_RESETAI and have it succeed without the
+	 * APU capturing audio, so we start and stop it here to do the reset
+	 */
+
+	/* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+	cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+	cx18_vapi(cx, CX18_APU_RESETAI, 0);
+	cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
+
+	/* Init the A/V decoder, if it hasn't been already */
+	v4l2_subdev_call(cx->sd_av, core, load_fw);
+
 	vf.tuner = 0;
 	vf.type = V4L2_TUNER_ANALOG_TV;
 	vf.frequency = 6400; /* the tuner 'baseline' frequency */
@@ -1092,9 +1062,11 @@ static void cx18_cancel_epu_work_orders(
 
 static void cx18_remove(struct pci_dev *pci_dev)
 {
-	struct cx18 *cx = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct cx18 *cx = to_cx18(v4l2_dev);
+	int i;
 
-	CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
+	CX18_DEBUG_INFO("Removing Card\n");
 
 	/* Stop all captures */
 	CX18_DEBUG_INFO("Stopping all streams\n");
@@ -1115,15 +1087,22 @@ static void cx18_remove(struct pci_dev *
 
 	exit_cx18_i2c(cx);
 
-	free_irq(cx->dev->irq, (void *)cx);
+	free_irq(cx->pci_dev->irq, (void *)cx);
 
 	cx18_iounmap(cx);
 
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 
-	pci_disable_device(cx->dev);
+	pci_disable_device(cx->pci_dev);
 
-	CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
+	if (cx->vbi.sliced_mpeg_data[0] != NULL)
+		for (i = 0; i < CX18_VBI_FRAMES; i++)
+			kfree(cx->vbi.sliced_mpeg_data[i]);
+
+	CX18_INFO("Removed %s\n", cx->card_name);
+
+	v4l2_device_unregister(v4l2_dev);
+	kfree(cx);
 }
 
 /* define a pci_driver for card detection */
@@ -1138,8 +1117,6 @@ static int module_start(void)
 {
 	printk(KERN_INFO "cx18:  Start initialization, version %s\n", CX18_VERSION);
 
-	memset(cx18_cards, 0, sizeof(cx18_cards));
-
 	/* Validate parameters */
 	if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
 		printk(KERN_ERR "cx18:  Exiting, cx18_first_minor must be between 0 and %d\n",
@@ -1162,16 +1139,7 @@ static int module_start(void)
 
 static void module_cleanup(void)
 {
-	int i;
-
 	pci_unregister_driver(&cx18_pci_driver);
-
-	for (i = 0; i < cx18_cards_active; i++) {
-		if (cx18_cards[i] == NULL)
-			continue;
-		kfree(cx18_cards[i]);
-	}
-
 }
 
 module_init(module_start);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-driver.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-driver.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-driver.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-driver.h	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
@@ -79,7 +80,7 @@
 #define CX18_CARD_YUAN_MPC718 	      3	/* Yuan MPC718 */
 #define CX18_CARD_CNXT_RAPTOR_PAL     4	/* Conexant Raptor PAL */
 #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100     6 /* Leadtek WinFast PVR2100 */
+#define CX18_CARD_LEADTEK_PVR2100     6 /* Leadtek WinFast PVR2100/DVR3100 H */
 #define CX18_CARD_LAST 		      6
 
 #define CX18_ENC_STREAM_TYPE_MPG  0
@@ -143,12 +144,12 @@
 /* Flag to turn on high volume debugging */
 #define CX18_DBGFLG_HIGHVOL (1 << 8)
 
-/* NOTE: extra space before comma in 'cx->num , ## args' is required for
+/* NOTE: extra space before comma in 'fmt , ## args' is required for
    gcc-2.95, otherwise it won't compile. */
 #define CX18_DEBUG(x, type, fmt, args...) \
 	do { \
 		if ((x) & cx18_debug) \
-			printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
+			v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
 	} while (0)
 #define CX18_DEBUG_WARN(fmt, args...)  CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
 #define CX18_DEBUG_INFO(fmt, args...)  CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -162,7 +163,7 @@
 #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
 	do { \
 		if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
-			printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
+			v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
 	} while (0)
 #define CX18_DEBUG_HI_WARN(fmt, args...)  CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
 #define CX18_DEBUG_HI_INFO(fmt, args...)  CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -174,9 +175,58 @@
 #define CX18_DEBUG_HI_IRQ(fmt, args...)   CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
 
 /* Standard kernel messages */
-#define CX18_ERR(fmt, args...)      printk(KERN_ERR  "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_WARN(fmt, args...)     printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_INFO(fmt, args...)     printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
+#define CX18_ERR(fmt, args...)      v4l2_err(&cx->v4l2_dev, fmt , ## args)
+#define CX18_WARN(fmt, args...)     v4l2_warn(&cx->v4l2_dev, fmt , ## args)
+#define CX18_INFO(fmt, args...)     v4l2_info(&cx->v4l2_dev, fmt , ## args)
+
+/* Messages for internal subdevs to use */
+#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
+	do { \
+		if ((x) & cx18_debug) \
+			v4l2_info(dev, " " type ": " fmt , ## args); \
+	} while (0)
+#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
+		CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
+	do { \
+		if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
+			v4l2_info(dev, " " type ": " fmt , ## args); \
+	} while (0)
+#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
+	CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_ERR_DEV(dev, fmt, args...)      v4l2_err(dev, fmt , ## args)
+#define CX18_WARN_DEV(dev, fmt, args...)     v4l2_warn(dev, fmt , ## args)
+#define CX18_INFO_DEV(dev, fmt, args...)     v4l2_info(dev, fmt , ## args)
 
 /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
 #define MPEG_FRAME_TYPE_IFRAME 1
@@ -279,7 +329,7 @@ struct cx18_epu_work_order {
 struct cx18_stream {
 	/* These first four fields are always set, even if the stream
 	   is not actually created. */
-	struct video_device *v4l2dev;	/* NULL when stream not created */
+	struct video_device *video_dev;	/* NULL when stream not created */
 	struct cx18 *cx; 		/* for ease of use */
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
@@ -292,7 +342,6 @@ struct cx18_stream {
 	int dma;		/* can be PCI_DMA_TODEVICE,
 				   PCI_DMA_FROMDEVICE or
 				   PCI_DMA_NONE */
-	u64 dma_pts;
 	wait_queue_head_t waitq;
 
 	/* Buffer Stats */
@@ -318,59 +367,121 @@ struct cx18_open_id {
 /* forward declaration of struct defined in cx18-cards.h */
 struct cx18_card;
 
+/*
+ * A note about "sliced" VBI data as implemented in this driver:
+ *
+ * Currently we collect the sliced VBI in the form of Ancillary Data
+ * packets, inserted by the AV core decoder/digitizer/slicer in the
+ * horizontal blanking region of the VBI lines, in "raw" mode as far as
+ * the Encoder is concerned.  We don't ever tell the Encoder itself
+ * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
+ *
+ * We then process the ancillary data ourselves to send the sliced data
+ * to the user application directly or build up MPEG-2 private stream 1
+ * packets to splice into (only!) MPEG-2 PS streams for the user app.
+ *
+ * (That's how ivtv essentially does it.)
+ *
+ * The Encoder should be able to extract certain sliced VBI data for
+ * us and provide it in a separate stream or splice it into any type of
+ * MPEG PS or TS stream, but this isn't implemented yet.
+ */
+
+/*
+ * Number of "raw" VBI samples per horizontal line we tell the Encoder to
+ * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
+ * It depends on the pixel clock and the horiz rate:
+ *
+ * (1/Fh)*(2*Fp) = Samples/line
+ *     = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
+ *
+ *  Sliced VBI data is sent as ancillary data during horizontal blanking
+ *  Raw VBI is sent as active video samples during vertcal blanking
+ *
+ *  We use a  BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
+ *  length of 720 pixels @ 4:2:2 sampling.  Thus...
+ *
+ *  For systems that use a 15.734 kHz horizontal rate, such as
+ *  NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
+ *
+ *  (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
+ *  4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ *  For systems that use a 15.625 kHz horizontal rate, such as
+ *  PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
+ *
+ *  (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
+ *  4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
+ */
+static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
+static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
+static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
 
 #define CX18_VBI_FRAMES 32
 
-/* VBI data */
 struct vbi_info {
-	u32 enc_size;
-	u32 frame;
-	u8 cc_data_odd[256];
-	u8 cc_data_even[256];
-	int cc_pos;
-	u8 cc_no_update;
-	u8 vps[5];
-	u8 vps_found;
-	int wss;
-	u8 wss_found;
-	u8 wss_no_update;
-	u32 raw_decoder_line_size;
-	u8 raw_decoder_sav_odd_field;
-	u8 raw_decoder_sav_even_field;
-	u32 sliced_decoder_line_size;
-	u8 sliced_decoder_sav_odd_field;
-	u8 sliced_decoder_sav_even_field;
+	/* Current state of v4l2 VBI settings for this device */
 	struct v4l2_format in;
-	/* convenience pointer to sliced struct in vbi_in union */
-	struct v4l2_sliced_vbi_format *sliced_in;
-	u32 service_set_in;
-	int insert_mpeg;
+	struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
+	u32 count;    /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
+	u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
 
-	/* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
-	   One for /dev/vbi0 and one for /dev/vbi8 */
-	struct v4l2_sliced_vbi_data sliced_data[36];
+	u32 frame; /* Count of VBI buffers/frames received from Encoder */
 
-	/* Buffer for VBI data inserted into MPEG stream.
-	   The first byte is a dummy byte that's never used.
-	   The next 16 bytes contain the MPEG header for the VBI data,
-	   the remainder is the actual VBI data.
-	   The max size accepted by the MPEG VBI reinsertion turns out
-	   to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
-	   where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
-	   a single line header byte and 2 * 18 is the number of VBI lines per frame.
+	/*
+	 * Vars for creation and insertion of MPEG Private Stream 1 packets
+	 * of sliced VBI data into an MPEG PS
+	 */
 
-	   However, it seems that the data must be 1K aligned, so we have to
-	   pad the data until the 1 or 2 K boundary.
+	/* Boolean: create and insert Private Stream 1 packets into the PS */
+	int insert_mpeg;
 
-	   This pointer array will allocate 2049 bytes to store each VBI frame. */
+	/*
+	 * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
+	 * Used in cx18-vbi.c only for collecting sliced data, and as a source
+	 * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
+	 * We don't need to save state here, but the array may have been a bit
+	 * too big (2304 bytes) to alloc from the stack.
+	 */
+	struct v4l2_sliced_vbi_data sliced_data[36];
+
+	/*
+	 * A ring buffer of driver-generated MPEG-2 PS
+	 * Program Pack/Private Stream 1 packets for sliced VBI data insertion
+	 * into the MPEG PS stream.
+	 *
+	 * In each sliced_mpeg_data[] buffer is:
+	 * 	16 byte MPEG-2 PS Program Pack Header
+	 * 	16 byte MPEG-2 Private Stream 1 PES Header
+	 * 	 4 byte magic number: "itv0" or "ITV0"
+	 * 	 4 byte first  field line mask, if "itv0"
+	 * 	 4 byte second field line mask, if "itv0"
+	 * 	36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+	 *
+	 * 	Each line in the payload is
+	 *	 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
+	 *	42 bytes of line data
+	 *
+	 * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
+	 * which is the payload size a PVR-350 (CX23415) MPEG decoder will
+	 * accept for VBI data. So, including the headers, it's a maximum 1584
+	 * bytes total.
+	 */
+#define CX18_SLICED_MPEG_DATA_MAXSZ	1584
+	/* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
+#define CX18_SLICED_MPEG_DATA_BUFSZ	(CX18_SLICED_MPEG_DATA_MAXSZ+8)
 	u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
 	u32 sliced_mpeg_size[CX18_VBI_FRAMES];
-	struct cx18_buffer sliced_mpeg_buf;
+
+	/* Count of Program Pack/Program Stream 1 packets inserted into PS */
 	u32 inserted_frame;
 
-	u32 start[2], count;
-	u32 raw_size;
-	u32 sliced_size;
+	/*
+	 * A dummy driver stream transfer 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_buffer sliced_mpeg_buf;
 };
 
 /* Per cx23418, per I2C bus private algo callback data */
@@ -383,16 +494,17 @@ struct cx18_i2c_algo_callback_data {
 
 /* Struct to hold info about cx18 cards */
 struct cx18 {
-	int num;		/* board number, -1 during init! */
-	char name[8];		/* board name for printk and interrupts (e.g. 'cx180') */
-	struct pci_dev *dev;	/* PCI device */
+	int instance;
+	struct pci_dev *pci_dev;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_subdev *sd_av;     /* A/V decoder/digitizer sub-device */
+	struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
+
 	const struct cx18_card *card;	/* card information */
 	const char *card_name;  /* full name of the card */
 	const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
 	u8 is_50hz;
 	u8 is_60hz;
-	u8 is_out_50hz;
-	u8 is_out_60hz;
 	u8 nof_inputs;		/* number of video inputs */
 	u8 nof_audio_inputs;	/* number of audio inputs */
 	u16 buffer_id;		/* buffer ID counter */
@@ -413,10 +525,7 @@ struct cx18 {
 
 	/* dualwatch */
 	unsigned long dualwatch_jiffies;
-	u16 dualwatch_stereo_mode;
-
-	/* Digitizer type */
-	int digitizer;		/* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
+	u32 dualwatch_stereo_mode;
 
 	struct mutex serialize_lock;    /* mutex used to serialize open/close/start/stop/ioctl operations */
 	struct cx18_options options; 	/* User options */
@@ -426,7 +535,6 @@ struct cx18 {
 	unsigned long i_flags;  /* global cx18 flags */
 	atomic_t ana_capturing;	/* count number of active analog capture streams */
 	atomic_t tot_capturing;	/* total count number of active capture streams */
-	spinlock_t lock;        /* lock access to this struct */
 	int search_pack_header;
 
 	int open_id;		/* incremented each time an open occurs, used as
@@ -468,30 +576,30 @@ struct cx18 {
 	struct i2c_adapter i2c_adap[2];
 	struct i2c_algo_bit_data i2c_algo[2];
 	struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
-	struct i2c_client i2c_client[2];
-	struct mutex i2c_bus_lock[2];
-	struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
 
 	/* gpio */
 	u32 gpio_dir;
 	u32 gpio_val;
 	struct mutex gpio_lock;
+	struct v4l2_subdev sd_gpiomux;
+	struct v4l2_subdev sd_resetctrl;
 
 	/* v4l2 and User settings */
 
 	/* codec settings */
 	u32 audio_input;
 	u32 active_input;
-	u32 active_output;
 	v4l2_std_id std;
 	v4l2_std_id tuner_std;	/* The norm of the tuner (fixed) */
 };
 
+static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct cx18, v4l2_dev);
+}
+
 /* Globals */
-extern struct cx18 *cx18_cards[];
-extern int cx18_cards_active;
 extern int cx18_first_minor;
-extern spinlock_t cx18_cards_lock;
 
 /*==============Prototypes==================*/
 
@@ -511,4 +619,22 @@ static inline int cx18_raw_vbi(const str
 	return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
 }
 
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). Ignore any errors. */
+#define cx18_call_hw(cx, hw, o, f, args...) \
+	__v4l2_device_call_subdevs(&(cx)->v4l2_dev, \
+				   !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
+
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). If the callback returns an error
+ * other than 0 or -ENOIOCTLCMD, then return with that error code. */
+#define cx18_call_hw_err(cx, hw, o, f, args...) \
+	__v4l2_device_call_subdevs_until_err( \
+		   &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all_err(cx, o, f, args...) \
+	cx18_call_hw_err(cx, 0, o, f , ##args)
+
 #endif /* CX18_DRIVER_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-dvb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-dvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream
 
 	ret = dvb_register_adapter(&dvb->dvb_adapter,
 			CX18_DRIVER_NAME,
-			THIS_MODULE, &cx->dev->dev, adapter_nr);
+			THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
 	if (ret < 0)
 		goto err_out;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-fileops.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-fileops.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-fileops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-fileops.c	2009-06-09 23:05:27.000000000 -0400
@@ -128,15 +128,15 @@ static void cx18_release_stream(struct c
 static void cx18_dualwatch(struct cx18 *cx)
 {
 	struct v4l2_tuner vt;
-	u16 new_bitmap;
-	u16 new_stereo_mode;
-	const u16 stereo_mask = 0x0300;
-	const u16 dual = 0x0200;
+	u32 new_bitmap;
+	u32 new_stereo_mode;
+	const u32 stereo_mask = 0x0300;
+	const u32 dual = 0x0200;
 	u32 h;
 
 	new_stereo_mode = cx->params.audio_properties & stereo_mask;
 	memset(&vt, 0, sizeof(vt));
-	cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt);
+	cx18_call_all(cx, tuner, g_tuner, &vt);
 	if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
 			(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
 		new_stereo_mode = dual;
@@ -176,6 +176,8 @@ static struct cx18_buffer *cx18_get_buff
 	*err = 0;
 	while (1) {
 		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+			/* Process pending program info updates and pending
+			   VBI data */
 
 			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
 				cx->dualwatch_jiffies = jiffies;
@@ -186,7 +188,6 @@ static struct cx18_buffer *cx18_get_buff
 				while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
 					/* byteswap and process VBI data */
 					cx18_process_vbi_data(cx, buf,
-							      s_vbi->dma_pts,
 							      s_vbi->type);
 					cx18_stream_put_buf_fw(s_vbi, buf);
 				}
@@ -207,8 +208,7 @@ static struct cx18_buffer *cx18_get_buff
 				cx18_buf_swap(buf);
 			else {
 				/* byteswap and process VBI data */
-				cx18_process_vbi_data(cx, buf,
-						s->dma_pts, s->type);
+				cx18_process_vbi_data(cx, buf, s->type);
 			}
 			return buf;
 		}
@@ -260,6 +260,20 @@ static size_t cx18_copy_buf_to_user(stru
 		len = ucount;
 	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
 	    !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
+		/*
+		 * Try to find a good splice point in the PS, just before
+		 * an MPEG-2 Program Pack start code, and provide only
+		 * up to that point to the user, so it's easy to insert VBI data
+		 * the next time around.
+		 */
+		/* FIXME - This only works for an MPEG-2 PS, not a TS */
+		/*
+		 * An MPEG-2 Program Stream (PS) is a series of
+		 * MPEG-2 Program Packs terminated by an
+		 * MPEG Program End Code after the last Program Pack.
+		 * A Program Pack may hold a PS System Header packet and any
+		 * number of Program Elementary Stream (PES) Packets
+		 */
 		const char *start = buf->buf + buf->readpos;
 		const char *p = start + 1;
 		const u8 *q;
@@ -267,38 +281,54 @@ static size_t cx18_copy_buf_to_user(stru
 		int stuffing, i;
 
 		while (start + len > p) {
+			/* Scan for a 0 to find a potential MPEG-2 start code */
 			q = memchr(p, 0, start + len - p);
 			if (q == NULL)
 				break;
 			p = q + 1;
+			/*
+			 * Keep looking if not a
+			 * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
+			 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
+			 */
 			if ((char *)q + 15 >= buf->buf + buf->bytesused ||
 			    q[1] != 0 || q[2] != 1 || q[3] != ch)
 				continue;
+
+			/* If expecting the primary video PES */
 			if (!cx->search_pack_header) {
+				/* Continue if it couldn't be a PES packet */
 				if ((q[6] & 0xc0) != 0x80)
 					continue;
-				if (((q[7] & 0xc0) == 0x80 &&
-				     (q[9] & 0xf0) == 0x20) ||
-				    ((q[7] & 0xc0) == 0xc0 &&
-				     (q[9] & 0xf0) == 0x30)) {
-					ch = 0xba;
+				/* Check if a PTS or PTS & DTS follow */
+				if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
+				     (q[9] & 0xf0) == 0x20) || /* PTS only */
+				    ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
+				     (q[9] & 0xf0) == 0x30)) { /* DTS follows */
+					/* Assume we found the video PES hdr */
+					ch = 0xba; /* next want a Program Pack*/
 					cx->search_pack_header = 1;
-					p = q + 9;
+					p = q + 9; /* Skip this video PES hdr */
 				}
 				continue;
 			}
+
+			/* We may have found a Program Pack start code */
+
+			/* Get the count of stuffing bytes & verify them */
 			stuffing = q[13] & 7;
 			/* all stuffing bytes must be 0xff */
 			for (i = 0; i < stuffing; i++)
 				if (q[14 + i] != 0xff)
 					break;
-			if (i == stuffing &&
-			    (q[4] & 0xc4) == 0x44 &&
-			    (q[12] & 3) == 3 &&
-			    q[14 + stuffing] == 0 &&
+			if (i == stuffing && /* right number of stuffing bytes*/
+			    (q[4] & 0xc4) == 0x44 && /* marker check */
+			    (q[12] & 3) == 3 &&  /* marker check */
+			    q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
 			    q[15 + stuffing] == 0 &&
 			    q[16 + stuffing] == 1) {
-				cx->search_pack_header = 0;
+				/* 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);
 				break;
@@ -578,7 +608,7 @@ int cx18_v4l2_close(struct file *filp)
 		/* Mark that the radio is no longer in use */
 		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 		/* Switch tuner to TV */
-		cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+		cx18_call_all(cx, core, s_std, cx->std);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		cx18_audio_set_io(cx);
 		if (atomic_read(&cx->ana_capturing) > 0) {
@@ -641,7 +671,7 @@ static int cx18_serialized_open(struct c
 		/* We have the radio */
 		cx18_mute(cx);
 		/* Switch tuner to radio */
-		cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
+		cx18_call_all(cx, tuner, s_radio);
 		/* Select the correct audio input (i.e. radio tuner) */
 		cx18_audio_set_io(cx);
 		/* Done! Unmute and continue. */
@@ -652,38 +682,15 @@ static int cx18_serialized_open(struct c
 
 int cx18_v4l2_open(struct file *filp)
 {
-	int res, x, y = 0;
-	struct cx18 *cx = NULL;
-	struct cx18_stream *s = NULL;
-	int minor = video_devdata(filp)->minor;
-
-	/* Find which card this open was on */
-	spin_lock(&cx18_cards_lock);
-	for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
-		/* find out which stream this open was on */
-		for (y = 0; y < CX18_MAX_STREAMS; y++) {
-			if (cx18_cards[x] == NULL)
-				continue;
-			s = &cx18_cards[x]->streams[y];
-			if (s->v4l2dev && s->v4l2dev->minor == minor) {
-				cx = cx18_cards[x];
-				break;
-			}
-		}
-	}
-	spin_unlock(&cx18_cards_lock);
-
-	if (cx == NULL) {
-		/* Couldn't find a device registered
-		   on that minor, shouldn't happen! */
-		printk(KERN_WARNING "No cx18 device found on minor %d\n",
-				minor);
-		return -ENXIO;
-	}
+	int res;
+	struct video_device *video_dev = video_devdata(filp);
+	struct cx18_stream *s = video_get_drvdata(video_dev);
+	struct cx18 *cx = s->cx;;
 
 	mutex_lock(&cx->serialize_lock);
 	if (cx18_init_on_first_open(cx)) {
-		CX18_ERR("Failed to initialize on minor %d\n", minor);
+		CX18_ERR("Failed to initialize on minor %d\n",
+			 video_dev->minor);
 		mutex_unlock(&cx->serialize_lock);
 		return -ENXIO;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-firmware.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-firmware.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-firmware.c	2013-05-03 18:01:54.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-firmware.c	2013-05-03 16:45:45.000000000 -0400
@@ -26,7 +26,6 @@
 #include "cx18-irq.h"
 #include "cx18-firmware.h"
 #include "cx18-cards.h"
-#include "cx18-av-core.h"
 #include <linux/firmware.h>
 
 #define CX18_PROC_SOFT_RESET 		0xc70010
@@ -107,7 +106,7 @@ static int load_cpu_fw_direct(const char
 	u32 __iomem *dst = (u32 __iomem *)mem;
 	const u32 *src;
 
-	if (reject_firmware(&fw, fn, &cx->dev->dev)) {
+	if (reject_firmware(&fw, fn, &cx->pci_dev->dev)) {
 		CX18_ERR("Unable to open firmware %s\n", fn);
 		CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
 		return -ENOMEM;
@@ -151,7 +150,7 @@ static int load_apu_fw_direct(const char
 	u32 apu_version = 0;
 	int sz;
 
-	if (reject_firmware(&fw, fn, &cx->dev->dev)) {
+	if (reject_firmware(&fw, fn, &cx->pci_dev->dev)) {
 		CX18_ERR("unable to open firmware %s\n", fn);
 		CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
 		cx18_setup_page(cx, 0);
@@ -286,23 +285,6 @@ void cx18_init_power(struct cx18 *cx, in
 	cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
 	cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
 
-	/*
-	 * VDCLK  Integer = 0x0f, Post Divider = 0x04
-	 * AIMCLK Integer = 0x0e, Post Divider = 0x16
-	 */
-	cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
-	/* VDCLK Fraction = 0x2be2fe */
-	/* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
-	cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
-	/* AIMCLK Fraction = 0x05227ad */
-	/* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
-	cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
-	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
-	cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-
 	/* Defaults */
 	/* APU = SC or SC/2 = 125/62.5 */
 	/* EPU = SC = 125 */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-gpio.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-gpio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,9 @@
  * gpio13: cs5345 reset pin
 */
 
+/*
+ * File scope utility functions
+ */
 static void gpio_write(struct cx18 *cx)
 {
 	u32 dir_lo = cx->gpio_dir & 0xffff;
@@ -63,73 +66,201 @@ static void gpio_write(struct cx18 *cx)
 					CX18_REG_GPIO_OUT2, val_hi, dir_hi);
 }
 
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
 {
-	const struct cx18_gpio_i2c_slave_reset *p;
+	if (mask == 0)
+		return;
 
-	p = &cx->card->gpio_i2c_slave_reset;
+	mutex_lock(&cx->gpio_lock);
+	cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
+	gpio_write(cx);
+	mutex_unlock(&cx->gpio_lock);
+}
 
-	if ((p->active_lo_mask | p->active_hi_mask) == 0)
+static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
+			   unsigned int assert_msecs,
+			   unsigned int recovery_msecs)
+{
+	u32 mask;
+
+	mask = active_lo | active_hi;
+	if (mask == 0)
 		return;
 
-	/* Assuming that the masks are a subset of the bits in gpio_dir */
+	/*
+	 * Assuming that active_hi and active_lo are a subsets of the bits in
+	 * gpio_dir.  Also assumes that active_lo and active_hi don't overlap
+	 * in any bit position
+	 */
 
 	/* Assert */
-	mutex_lock(&cx->gpio_lock);
-	cx->gpio_val =
-		(cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
-	gpio_write(cx);
-	schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+	gpio_update(cx, mask, ~active_lo);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
 
 	/* Deassert */
-	cx->gpio_val =
-		(cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
-	gpio_write(cx);
-	schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+	gpio_update(cx, mask, ~active_hi);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
+}
+
+/*
+ * GPIO Multiplexer - logical device
+ */
+static int gpiomux_log_status(struct v4l2_subdev *sd)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+	mutex_lock(&cx->gpio_lock);
+	CX18_INFO_DEV(sd, "GPIO:  direction 0x%08x, value 0x%08x\n",
+		      cx->gpio_dir, cx->gpio_val);
 	mutex_unlock(&cx->gpio_lock);
+	return 0;
 }
 
-void cx18_reset_ir_gpio(void *data)
+static int gpiomux_s_radio(struct v4l2_subdev *sd)
 {
-	struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
-	const struct cx18_gpio_i2c_slave_reset *p;
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	p = &cx->card->gpio_i2c_slave_reset;
+	/*
+	 * FIXME - work out the cx->active/audio_input mess - this is
+	 * intended to handle the switch to radio mode and set the
+	 * audio routing, but we need to update the state in cx
+	 */
+	gpio_update(cx, cx->card->gpio_audio_input.mask,
+			cx->card->gpio_audio_input.radio);
+	return 0;
+}
 
-	if (p->ir_reset_mask == 0)
-		return;
+static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	u32 data;
 
-	CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+	switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
+	case 1:
+		data = cx->card->gpio_audio_input.linein;
+		break;
+	case 0:
+		data = cx->card->gpio_audio_input.tuner;
+		break;
+	default:
+		/*
+		 * FIXME - work out the cx->active/audio_input mess - this is
+		 * intended to handle the switch from radio mode and set the
+		 * audio routing, but we need to update the state in cx
+		 */
+		data = cx->card->gpio_audio_input.tuner;
+		break;
+	}
+	gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+	return 0;
+}
 
-	/*
-	   Assert timing for the Z8F0811 on HVR-1600 boards:
-	   1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
-	   2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
-		(6,601,085 nanoseconds ~= 7 milliseconds)
-	   3. DBG pin must be high before chip exits reset for normal operation.
-		DBG is open drain and hopefully pulled high since we don't
-		normally drive it (GPIO 1?) for the HVR-1600
-	   4. Z8F0811 won't exit reset until RESET is deasserted
-	*/
-	mutex_lock(&cx->gpio_lock);
-	cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
-	gpio_write(cx);
-	mutex_unlock(&cx->gpio_lock);
-	schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	u32 data;
+
+	switch (input) {
+	case 0:
+		data = cx->card->gpio_audio_input.tuner;
+		break;
+	case 1:
+		data = cx->card->gpio_audio_input.linein;
+		break;
+	case 2:
+		data = cx->card->gpio_audio_input.radio;
+		break;
+	default:
+		return -EINVAL;
+	}
+	gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
+	.log_status = gpiomux_log_status,
+	.s_std = gpiomux_s_std,
+};
+
+static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
+	.s_radio = gpiomux_s_radio,
+};
+
+static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
+	.s_routing = gpiomux_s_audio_routing,
+};
+
+static const struct v4l2_subdev_ops gpiomux_ops = {
+	.core = &gpiomux_core_ops,
+	.tuner = &gpiomux_tuner_ops,
+	.audio = &gpiomux_audio_ops,
+};
+
+/*
+ * GPIO Reset Controller - logical device
+ */
+static int resetctrl_log_status(struct v4l2_subdev *sd)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	/*
-	   Zilog comes out of reset, loads reset vector address and executes
-	   from there. Required recovery delay unknown.
-	*/
 	mutex_lock(&cx->gpio_lock);
-	cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
-	gpio_write(cx);
+	CX18_INFO_DEV(sd, "GPIO:  direction 0x%08x, value 0x%08x\n",
+		      cx->gpio_dir, cx->gpio_val);
 	mutex_unlock(&cx->gpio_lock);
-	schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+	return 0;
 }
-EXPORT_SYMBOL(cx18_reset_ir_gpio);
-/* This symbol is exported for use by an infrared module for the IR-blaster */
 
+static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
+{
+	struct cx18 *cx = v4l2_get_subdevdata(sd);
+	const struct cx18_gpio_i2c_slave_reset *p;
+
+	p = &cx->card->gpio_i2c_slave_reset;
+	switch (val) {
+	case CX18_GPIO_RESET_I2C:
+		gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
+			       p->msecs_asserted, p->msecs_recovery);
+		break;
+	case CX18_GPIO_RESET_Z8F0811:
+		/*
+		 * Assert timing for the Z8F0811 on HVR-1600 boards:
+		 * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
+		 *    initiate
+		 * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
+		 *    cycles (6,601,085 nanoseconds ~= 7 milliseconds)
+		 * 3. DBG pin must be high before chip exits reset for normal
+		 *    operation.  DBG is open drain and hopefully pulled high
+		 *    since we don't normally drive it (GPIO 1?) for the
+		 *    HVR-1600
+		 * 4. Z8F0811 won't exit reset until RESET is deasserted
+		 * 5. Zilog comes out of reset, loads reset vector address and
+		 *    executes from there. Required recovery delay unknown.
+		 */
+		gpio_reset_seq(cx, p->ir_reset_mask, 0,
+			       p->msecs_asserted, p->msecs_recovery);
+		break;
+	case CX18_GPIO_RESET_XC2028:
+		if (cx->card->tuners[0].tuner == TUNER_XC2028)
+			gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
+				       1, 1);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
+	.log_status = resetctrl_log_status,
+	.reset = resetctrl_reset,
+};
+
+static const struct v4l2_subdev_ops resetctrl_ops = {
+	.core = &resetctrl_core_ops,
+};
+
+/*
+ * External entry points
+ */
 void cx18_gpio_init(struct cx18 *cx)
 {
 	mutex_lock(&cx->gpio_lock);
@@ -156,63 +287,61 @@ void cx18_gpio_init(struct cx18 *cx)
 	mutex_unlock(&cx->gpio_lock);
 }
 
-/* Xceive tuner reset function */
-int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
+int cx18_gpio_register(struct cx18 *cx, u32 hw)
 {
-	struct i2c_algo_bit_data *algo = dev;
-	struct cx18_i2c_algo_callback_data *cb_data = algo->data;
-	struct cx18 *cx = cb_data->cx;
+	struct v4l2_subdev *sd;
+	const struct v4l2_subdev_ops *ops;
+	char *str;
 
-	if (cmd != XC2028_TUNER_RESET)
-		return 0;
-	CX18_DEBUG_INFO("Resetting tuner\n");
+	switch (hw) {
+	case CX18_HW_GPIO_MUX:
+		sd = &cx->sd_gpiomux;
+		ops = &gpiomux_ops;
+		str = "gpio-mux";
+		break;
+	case CX18_HW_GPIO_RESET_CTRL:
+		sd = &cx->sd_resetctrl;
+		ops = &resetctrl_ops;
+		str = "gpio-reset-ctrl";
+		break;
+	default:
+		return -EINVAL;
+	}
 
-	mutex_lock(&cx->gpio_lock);
-	cx->gpio_val &= ~(1 << cx->card->xceive_pin);
-	gpio_write(cx);
-	mutex_unlock(&cx->gpio_lock);
-	schedule_timeout_interruptible(msecs_to_jiffies(1));
+	v4l2_subdev_init(sd, ops);
+	v4l2_set_subdevdata(sd, cx);
+	snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
+	sd->grp_id = hw;
+	return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+}
 
-	mutex_lock(&cx->gpio_lock);
-	cx->gpio_val |= 1 << cx->card->xceive_pin;
-	gpio_write(cx);
-	mutex_unlock(&cx->gpio_lock);
-	schedule_timeout_interruptible(msecs_to_jiffies(1));
-	return 0;
+void cx18_reset_ir_gpio(void *data)
+{
+	struct cx18 *cx = to_cx18((struct v4l2_device *)data);
+
+	if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
+		return;
+
+	CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+
+	v4l2_subdev_call(&cx->sd_resetctrl,
+			 core, reset, CX18_GPIO_RESET_Z8F0811);
 }
+EXPORT_SYMBOL(cx18_reset_ir_gpio);
+/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
 
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
+/* Xceive tuner reset function */
+int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
 {
-	struct v4l2_routing *route = arg;
-	u32 mask, data;
+	struct i2c_algo_bit_data *algo = dev;
+	struct cx18_i2c_algo_callback_data *cb_data = algo->data;
+	struct cx18 *cx = cb_data->cx;
 
-	switch (command) {
-	case VIDIOC_INT_S_AUDIO_ROUTING:
-		if (route->input > 2)
-			return -EINVAL;
-		mask = cx->card->gpio_audio_input.mask;
-		switch (route->input) {
-		case 0:
-			data = cx->card->gpio_audio_input.tuner;
-			break;
-		case 1:
-			data = cx->card->gpio_audio_input.linein;
-			break;
-		case 2:
-		default:
-			data = cx->card->gpio_audio_input.radio;
-			break;
-		}
-		break;
+	if (cmd != XC2028_TUNER_RESET ||
+	    cx->card->tuners[0].tuner != TUNER_XC2028)
+		return 0;
 
-	default:
-		return -EINVAL;
-	}
-	if (mask) {
-		mutex_lock(&cx->gpio_lock);
-		cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
-		gpio_write(cx);
-		mutex_unlock(&cx->gpio_lock);
-	}
-	return 0;
+	CX18_DEBUG_INFO("Resetting XCeive tuner\n");
+	return v4l2_subdev_call(&cx->sd_resetctrl,
+				core, reset, CX18_GPIO_RESET_XC2028);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-gpio.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-gpio.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-gpio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-gpio.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,13 @@
  */
 
 void cx18_gpio_init(struct cx18 *cx);
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
+int cx18_gpio_register(struct cx18 *cx, u32 hw);
+
+enum cx18_gpio_reset_type {
+	CX18_GPIO_RESET_I2C     = 0,
+	CX18_GPIO_RESET_Z8F0811 = 1,
+	CX18_GPIO_RESET_XC2028  = 2,
+};
+
 void cx18_reset_ir_gpio(void *data);
 int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@
 #include "cx18-io.h"
 #include "cx18-cards.h"
 #include "cx18-gpio.h"
-#include "cx18-av-core.h"
 #include "cx18-i2c.h"
 #include "cx18-irq.h"
 
@@ -43,31 +42,37 @@
 #define CX18_CS5345_I2C_ADDR		0x4c
 
 /* This array should match the CX18_HW_ defines */
-static const u8 hw_driverids[] = {
-	I2C_DRIVERID_TUNER,
-	I2C_DRIVERID_TVEEPROM,
-	I2C_DRIVERID_CS5345,
-	0, 		/* CX18_HW_GPIO dummy driver ID */
-	0 		/* CX18_HW_CX23418 dummy driver ID */
-};
-
-/* This array should match the CX18_HW_ defines */
 static const u8 hw_addrs[] = {
-	0,
-	0,
-	CX18_CS5345_I2C_ADDR,
-	0, 		/* CX18_HW_GPIO dummy driver ID */
-	0,		/* CX18_HW_CX23418 dummy driver ID */
+	0,			/* CX18_HW_TUNER */
+	0,			/* CX18_HW_TVEEPROM */
+	CX18_CS5345_I2C_ADDR,	/* CX18_HW_CS5345 */
+	0,			/* CX18_HW_DVB */
+	0,			/* CX18_HW_418_AV */
+	0,			/* CX18_HW_GPIO_MUX */
+	0,			/* CX18_HW_GPIO_RESET_CTRL */
 };
 
 /* This array should match the CX18_HW_ defines */
 /* This might well become a card-specific array */
 static const u8 hw_bus[] = {
-	0,
-	0,
-	0,
-	0, 		/* CX18_HW_GPIO dummy driver ID */
-	0,		/* CX18_HW_CX23418 dummy driver ID */
+	1,	/* CX18_HW_TUNER */
+	0,	/* CX18_HW_TVEEPROM */
+	0,	/* CX18_HW_CS5345 */
+	0,	/* CX18_HW_DVB */
+	0,	/* CX18_HW_418_AV */
+	0,	/* CX18_HW_GPIO_MUX */
+	0,	/* CX18_HW_GPIO_RESET_CTRL */
+};
+
+/* This array should match the CX18_HW_ defines */
+static const char * const hw_modules[] = {
+	"tuner",	/* CX18_HW_TUNER */
+	NULL,		/* CX18_HW_TVEEPROM */
+	"cs5345",	/* CX18_HW_CS5345 */
+	NULL,		/* CX18_HW_DVB */
+	NULL,		/* CX18_HW_418_AV */
+	NULL,		/* CX18_HW_GPIO_MUX */
+	NULL,		/* CX18_HW_GPIO_RESET_CTRL */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -75,83 +80,67 @@ static const char * const hw_devicenames
 	"tuner",
 	"tveeprom",
 	"cs5345",
-	"gpio",
-	"cx23418",
+	"cx23418_DTV",
+	"cx23418_AV",
+	"gpio_mux",
+	"gpio_reset_ctrl",
 };
 
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 {
-	struct i2c_board_info info;
-	struct i2c_client *c;
-	u8 id, bus;
-	int i;
+	struct v4l2_subdev *sd;
+	int bus = hw_bus[idx];
+	struct i2c_adapter *adap = &cx->i2c_adap[bus];
+	const char *mod = hw_modules[idx];
+	const char *type = hw_devicenames[idx];
+	u32 hw = 1 << idx;
 
-	CX18_DEBUG_I2C("i2c client register\n");
-	if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
+	if (idx >= ARRAY_SIZE(hw_addrs))
 		return -1;
-	id = hw_driverids[idx];
-	bus = hw_bus[idx];
-	memset(&info, 0, sizeof(info));
-	strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
-	info.addr = hw_addrs[idx];
-	for (i = 0; i < I2C_CLIENTS_MAX; i++)
-		if (cx->i2c_clients[i] == NULL)
-			break;
 
-	if (i == I2C_CLIENTS_MAX) {
-		CX18_ERR("insufficient room for new I2C client!\n");
-		return -ENOMEM;
-	}
-
-	if (id != I2C_DRIVERID_TUNER) {
-		c = i2c_new_device(&cx->i2c_adap[bus], &info);
-		if (c->driver == NULL)
-			i2c_unregister_device(c);
-		else
-			cx->i2c_clients[i] = c;
-		return cx->i2c_clients[i] ? 0 : -ENODEV;
+	if (hw == CX18_HW_TUNER) {
+		/* special tuner group handling */
+		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+				adap, mod, type, cx->card_i2c->radio);
+		if (sd != NULL)
+			sd->grp_id = hw;
+		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+				adap, mod, type, cx->card_i2c->demod);
+		if (sd != NULL)
+			sd->grp_id = hw;
+		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
+				adap, mod, type, cx->card_i2c->tv);
+		if (sd != NULL)
+			sd->grp_id = hw;
+		return sd != NULL ? 0 : -1;
 	}
 
-	/* special tuner handling */
-	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
-	if (c && c->driver == NULL)
-		i2c_unregister_device(c);
-	else if (c)
-		cx->i2c_clients[i++] = c;
-	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
-	if (c && c->driver == NULL)
-		i2c_unregister_device(c);
-	else if (c)
-		cx->i2c_clients[i++] = c;
-	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
-	if (c && c->driver == NULL)
-		i2c_unregister_device(c);
-	else if (c)
-		cx->i2c_clients[i++] = c;
-	return 0;
-}
+	/* Is it not an I2C device or one we do not wish to register? */
+	if (!hw_addrs[idx])
+		return -1;
 
-static int attach_inform(struct i2c_client *client)
-{
-	return 0;
+	/* It's an I2C device other than an analog tuner */
+	sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]);
+	if (sd != NULL)
+		sd->grp_id = hw;
+	return sd != NULL ? 0 : -1;
 }
 
-static int detach_inform(struct i2c_client *client)
+/* Find the first member of the subdev group id in hw */
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
 {
-	int i;
-	struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
+	struct v4l2_subdev *result = NULL;
+	struct v4l2_subdev *sd;
 
-	CX18_DEBUG_I2C("i2c client detach\n");
-	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
-		if (cx->i2c_clients[i] == client) {
-			cx->i2c_clients[i] = NULL;
+	spin_lock(&cx->v4l2_dev.lock);
+	v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
+		if (sd->grp_id == hw) {
+			result = sd;
 			break;
 		}
 	}
-	CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
-		   client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
-
-	return 0;
+	spin_unlock(&cx->v4l2_dev.lock);
+	return result;
 }
 
 static void cx18_setscl(void *data, int state)
@@ -204,8 +193,6 @@ static struct i2c_adapter cx18_i2c_adap_
 	.id = I2C_HW_B_CX2341X,
 	.algo = NULL,                   /* set by i2c-algo-bit */
 	.algo_data = NULL,              /* filled from template */
-	.client_register = attach_inform,
-	.client_unregister = detach_inform,
 	.owner = THIS_MODULE,
 };
 
@@ -221,152 +208,28 @@ static struct i2c_algo_bit_data cx18_i2c
 	.timeout	= CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
 };
 
-static struct i2c_client cx18_i2c_client_template = {
-	.name = "cx18 internal",
-};
-
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
-{
-	struct i2c_client *client;
-	int retval;
-	int i;
-
-	CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
-	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
-		client = cx->i2c_clients[i];
-		if (client == NULL || client->driver == NULL ||
-				client->driver->command == NULL)
-			continue;
-		if (addr == client->addr) {
-			retval = client->driver->command(client, cmd, arg);
-			return retval;
-		}
-	}
-	if (cmd != VIDIOC_DBG_G_CHIP_IDENT)
-		CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
-			       addr, cmd);
-	return -ENODEV;
-}
-
-/* Find the i2c device based on the driver ID and return
-   its i2c address or -ENODEV if no matching device was found. */
-static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
-{
-	struct i2c_client *client;
-	int retval = -ENODEV;
-	int i;
-
-	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
-		client = cx->i2c_clients[i];
-		if (client == NULL || client->driver == NULL)
-			continue;
-		if (id == client->driver->id) {
-			retval = client->addr;
-			break;
-		}
-	}
-	return retval;
-}
-
-/* Find the i2c device name matching the CX18_HW_ flag */
-static const char *cx18_i2c_hw_name(u32 hw)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
-		if (1 << i == hw)
-			return hw_devicenames[i];
-	return "unknown device";
-}
-
-/* Find the i2c device matching the CX18_HW_ flag and return
-   its i2c address or -ENODEV if no matching device was found. */
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
-		if (1 << i == hw)
-			return cx18_i2c_id_addr(cx, hw_driverids[i]);
-	return -ENODEV;
-}
-
-/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
-   If hw == CX18_HW_GPIO then call the gpio handler. */
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
-{
-	int addr;
-
-	if (hw == 0)
-		return 0;
-
-	if (hw == CX18_HW_GPIO)
-		return cx18_gpio(cx, cmd, arg);
-
-	if (hw == CX18_HW_CX23418)
-		return cx18_av_cmd(cx, cmd, arg);
-
-	addr = cx18_i2c_hw_addr(cx, hw);
-	if (addr < 0) {
-		CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
-			       hw, cx18_i2c_hw_name(hw), cmd);
-		return addr;
-	}
-	return cx18_call_i2c_client(cx, addr, cmd, arg);
-}
-
-/* broadcast cmd for all I2C clients and for the gpio subsystem */
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
-{
-	if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
-		CX18_ERR("adapter is not set\n");
-		return;
-	}
-	cx18_av_cmd(cx, cmd, arg);
-	i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
-	i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
-	if (cx->hw_flags & CX18_HW_GPIO)
-		cx18_gpio(cx, cmd, arg);
-}
-
 /* init + register i2c algo-bit adapter */
 int init_cx18_i2c(struct cx18 *cx)
 {
-	int i;
+	int i, err;
 	CX18_DEBUG_I2C("i2c init\n");
 
-	/* Sanity checks for the I2C hardware arrays. They must be the
-	 * same size and GPIO/CX23418 must be the last entries.
-	 */
-	if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
-	    ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
-	    CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
-	    CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
-	    hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
-		CX18_ERR("Mismatched I2C hardware arrays\n");
-		return -ENODEV;
-	}
-
 	for (i = 0; i < 2; i++) {
-		memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
-			sizeof(struct i2c_adapter));
+		/* Setup algorithm for adapter */
 		memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
 			sizeof(struct i2c_algo_bit_data));
 		cx->i2c_algo_cb_data[i].cx = cx;
 		cx->i2c_algo_cb_data[i].bus_index = i;
 		cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
-		cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
 
+		/* Setup adapter */
+		memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
+			sizeof(struct i2c_adapter));
+		cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
 		sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
-				" #%d-%d", cx->num, i);
-		i2c_set_adapdata(&cx->i2c_adap[i], cx);
-
-		memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
-			sizeof(struct i2c_client));
-		sprintf(cx->i2c_client[i].name +
-				strlen(cx->i2c_client[i].name), "%d", i);
-		cx->i2c_client[i].adapter = &cx->i2c_adap[i];
-		cx->i2c_adap[i].dev.parent = &cx->dev->dev;
+				" #%d-%d", cx->instance, i);
+		i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
+		cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
 	}
 
 	if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
@@ -402,10 +265,21 @@ int init_cx18_i2c(struct cx18 *cx)
 	cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
 	cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
 
-	cx18_reset_i2c_slaves_gpio(cx);
+	cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
+		     core, reset, (u32) CX18_GPIO_RESET_I2C);
 
-	return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
-		i2c_bit_add_bus(&cx->i2c_adap[1]);
+	err = i2c_bit_add_bus(&cx->i2c_adap[0]);
+	if (err)
+		goto err;
+	err = i2c_bit_add_bus(&cx->i2c_adap[1]);
+	if (err)
+		goto err_del_bus_0;
+	return 0;
+
+ err_del_bus_0:
+	i2c_del_adapter(&cx->i2c_adap[0]);
+ err:
+	return err;
 }
 
 void exit_cx18_i2c(struct cx18 *cx)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-i2c.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-i2c.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-i2c.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-i2c.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,11 +21,8 @@
  *  02111-1307  USA
  */
 
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw);
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg);
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg);
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg);
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
 
 /* init + register i2c algo-bit adapter */
 int init_cx18_i2c(struct cx18 *cx);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-ioctl.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,12 +58,21 @@ u16 cx18_service2vbi(int type)
 	}
 }
 
+/* Check if VBI services are allowed on the (field, line) for the video std */
 static int valid_service_line(int field, int line, int is_pal)
 {
-	return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
+	return (is_pal && line >= 6 &&
+		((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
 	       (!is_pal && line >= 10 && line < 22);
 }
 
+/*
+ * For a (field, line, std) and inbound potential set of services for that line,
+ * return the first valid service of those passed in the incoming set for that
+ * line in priority order:
+ * CC, VPS, or WSS over TELETEXT for well known lines
+ * TELETEXT, before VPS, before CC, before WSS, for other lines
+ */
 static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
 {
 	u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
@@ -90,6 +99,10 @@ static u16 select_service_from_set(int f
 	return 0;
 }
 
+/*
+ * Expand the service_set of *fmt into valid service_lines for the std,
+ * and clear the passed in fmt->service_set
+ */
 void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 {
 	u16 set = fmt->service_set;
@@ -102,7 +115,25 @@ void cx18_expand_service_set(struct v4l2
 	}
 }
 
+/*
+ * Sanitize the service_lines in *fmt per the video std, and return 1
+ * if any service_line is left as valid after santization
+ */
+static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+{
+	int f, l;
+	u16 set = 0;
 
+	for (f = 0; f < 2; f++) {
+		for (l = 0; l < 24; l++) {
+			fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
+			set |= fmt->service_lines[f][l];
+		}
+	}
+	return set != 0;
+}
+
+/* Compute the service_set from the assumed valid service_lines of *fmt */
 u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
 {
 	int f, l;
@@ -129,10 +160,8 @@ static int cx18_g_fmt_vid_cap(struct fil
 	pixfmt->priv = 0;
 	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
 		pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
-		/* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
-		pixfmt->sizeimage =
-			pixfmt->height * pixfmt->width +
-			pixfmt->height * (pixfmt->width / 2);
+		/* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+		pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
 		pixfmt->bytesperline = 720;
 	} else {
 		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -149,8 +178,8 @@ static int cx18_g_fmt_vbi_cap(struct fil
 	struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
 
 	vbifmt->sampling_rate = 27000000;
-	vbifmt->offset = 248;
-	vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
+	vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
+	vbifmt->samples_per_line = vbi_active_samples - 4;
 	vbifmt->sample_format = V4L2_PIX_FMT_GREY;
 	vbifmt->start[0] = cx->vbi.start[0];
 	vbifmt->start[1] = cx->vbi.start[1];
@@ -164,7 +193,30 @@ static int cx18_g_fmt_vbi_cap(struct fil
 static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
 					struct v4l2_format *fmt)
 {
-	return -EINVAL;
+	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+	/* sane, V4L2 spec compliant, defaults */
+	vbifmt->reserved[0] = 0;
+	vbifmt->reserved[1] = 0;
+	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+	memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+	vbifmt->service_set = 0;
+
+	/*
+	 * Fetch the configured service_lines and total service_set from the
+	 * digitizer/slicer.  Note, cx18_av_vbi() wipes the passed in
+	 * fmt->fmt.sliced under valid calling conditions
+	 */
+	if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt))
+		return -EINVAL;
+
+	/* Ensure V4L2 spec compliant output */
+	vbifmt->reserved[0] = 0;
+	vbifmt->reserved[1] = 0;
+	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+	vbifmt->service_set = cx18_get_service_set(vbifmt);
+	return 0;
 }
 
 static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
@@ -174,11 +226,18 @@ static int cx18_try_fmt_vid_cap(struct f
 	struct cx18 *cx = id->cx;
 	int w = fmt->fmt.pix.width;
 	int h = fmt->fmt.pix.height;
+	int min_h = 2;
 
 	w = min(w, 720);
-	w = max(w, 1);
+	w = max(w, 2);
+	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
+		/* YUV height must be a multiple of 32 */
+		h &= ~0x1f;
+		min_h = 32;
+	}
 	h = min(h, cx->is_50hz ? 576 : 480);
-	h = max(h, 2);
+	h = max(h, min_h);
+
 	cx18_g_fmt_vid_cap(file, fh, fmt);
 	fmt->fmt.pix.width = w;
 	fmt->fmt.pix.height = h;
@@ -194,7 +253,20 @@ static int cx18_try_fmt_vbi_cap(struct f
 static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
 					struct v4l2_format *fmt)
 {
-	return -EINVAL;
+	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+	vbifmt->reserved[0] = 0;
+	vbifmt->reserved[1] = 0;
+
+	/* If given a service set, expand it validly & clear passed in set */
+	if (vbifmt->service_set)
+		cx18_expand_service_set(vbifmt, cx->is_50hz);
+	/* Sanitize the service_lines, and compute the new set if any valid */
+	if (check_service_set(vbifmt, cx->is_50hz))
+		vbifmt->service_set = cx18_get_service_set(vbifmt);
+	return 0;
 }
 
 static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
@@ -223,7 +295,7 @@ static int cx18_s_fmt_vid_cap(struct fil
 
 	cx->params.width = w;
 	cx->params.height = h;
-	cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+	v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
 	return cx18_g_fmt_vid_cap(file, fh, fmt);
 }
 
@@ -238,54 +310,131 @@ static int cx18_s_fmt_vbi_cap(struct fil
 	if (ret)
 		return ret;
 
+	/*
+	 * Changing the Encoder's Raw VBI parameters won't have any effect
+	 * if any analog capture is ongoing
+	 */
 	if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
 		return -EBUSY;
 
+	/*
+	 * Set the digitizer registers for raw active VBI.
+	 * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
+	 * calling conditions
+	 */
+	ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+	if (ret)
+		return ret;
+
+	/* Store our new v4l2 (non-)sliced VBI state */
 	cx->vbi.sliced_in->service_set = 0;
 	cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
-	cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+
 	return cx18_g_fmt_vbi_cap(file, fh, fmt);
 }
 
 static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
 					struct v4l2_format *fmt)
 {
-	return -EINVAL;
+	struct cx18_open_id *id = fh;
+	struct cx18 *cx = id->cx;
+	int ret;
+	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+	ret = v4l2_prio_check(&cx->prio, &id->prio);
+	if (ret)
+		return ret;
+
+	cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+	/*
+	 * Changing the Encoder's Raw VBI parameters won't have any effect
+	 * if any analog capture is ongoing
+	 */
+	if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
+		return -EBUSY;
+
+	/*
+	 * Set the service_lines requested in the digitizer/slicer registers.
+	 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
+	 * passed in fmt->fmt.sliced under valid calling conditions
+	 */
+	ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+	if (ret)
+		return ret;
+	/* Store our current v4l2 sliced VBI settings */
+	cx->vbi.in.type =  V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+	memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
+	return 0;
 }
 
 static int cx18_g_chip_ident(struct file *file, void *fh,
 				struct v4l2_dbg_chip_ident *chip)
 {
 	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+	int err = 0;
 
 	chip->ident = V4L2_IDENT_NONE;
 	chip->revision = 0;
-	if (v4l2_chip_match_host(&chip->match)) {
-		chip->ident = V4L2_IDENT_CX23418;
-		return 0;
+	switch (chip->match.type) {
+	case V4L2_CHIP_MATCH_HOST:
+		switch (chip->match.addr) {
+		case 0:
+			chip->ident = V4L2_IDENT_CX23418;
+			chip->revision = cx18_read_reg(cx, 0xC72028);
+			break;
+		case 1:
+			/*
+			 * The A/V decoder is always present, but in the rare
+			 * case that the card doesn't have analog, we don't
+			 * use it.  We find it w/o using the cx->sd_av pointer
+			 */
+			cx18_call_hw(cx, CX18_HW_418_AV,
+				     core, g_chip_ident, chip);
+			break;
+		default:
+			/*
+			 * Could return ident = V4L2_IDENT_UNKNOWN if we had
+			 * other host chips at higher addresses, but we don't
+			 */
+			err = -EINVAL; /* per V4L2 spec */
+			break;
+		}
+		break;
+	case V4L2_CHIP_MATCH_I2C_DRIVER:
+		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
+		cx18_call_all(cx, core, g_chip_ident, chip);
+		break;
+	case V4L2_CHIP_MATCH_I2C_ADDR:
+		/*
+		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
+		 * to look if a chip is at the address with no driver.  That's a
+		 * dangerous thing to do with EEPROMs anyway.
+		 */
+		cx18_call_all(cx, core, g_chip_ident, chip);
+		break;
+	default:
+		err = -EINVAL;
+		break;
 	}
-	cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip);
-	return 0;
+	return err;
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
 {
 	struct v4l2_dbg_register *regs = arg;
-	unsigned long flags;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
 		return -EINVAL;
 
-	spin_lock_irqsave(&cx18_cards_lock, flags);
 	regs->size = 4;
-	if (cmd == VIDIOC_DBG_G_REGISTER)
-		regs->val = cx18_read_enc(cx, regs->reg);
-	else
+	if (cmd == VIDIOC_DBG_S_REGISTER)
 		cx18_write_enc(cx, regs->val, regs->reg);
-	spin_unlock_irqrestore(&cx18_cards_lock, flags);
+	else
+		regs->val = cx18_read_enc(cx, regs->reg);
 	return 0;
 }
 
@@ -296,7 +445,8 @@ static int cx18_g_register(struct file *
 
 	if (v4l2_chip_match_host(&reg->match))
 		return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
-	cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg);
+	/* FIXME - errors shouldn't be ignored */
+	cx18_call_all(cx, core, g_register, reg);
 	return 0;
 }
 
@@ -307,7 +457,8 @@ static int cx18_s_register(struct file *
 
 	if (v4l2_chip_match_host(&reg->match))
 		return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
-	cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg);
+	/* FIXME - errors shouldn't be ignored */
+	cx18_call_all(cx, core, s_register, reg);
 	return 0;
 }
 #endif
@@ -335,7 +486,8 @@ static int cx18_querycap(struct file *fi
 
 	strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
 	strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
-	snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev));
+	snprintf(vcap->bus_info, sizeof(vcap->bus_info),
+		 "PCI:%s", pci_name(cx->pci_dev));
 	vcap->version = CX18_DRIVER_VERSION; 	    /* version */
 	vcap->capabilities = cx->v4l2_cap; 	    /* capabilities */
 	return 0;
@@ -403,7 +555,8 @@ static int cx18_s_crop(struct file *file
 
 	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
+	CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
+	return -EINVAL;
 }
 
 static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
@@ -412,7 +565,8 @@ static int cx18_g_crop(struct file *file
 
 	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
+	CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
+	return -EINVAL;
 }
 
 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
@@ -483,7 +637,7 @@ static int cx18_g_frequency(struct file
 	if (vf->tuner != 0)
 		return -EINVAL;
 
-	cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
+	cx18_call_all(cx, tuner, g_frequency, vf);
 	return 0;
 }
 
@@ -502,7 +656,7 @@ int cx18_s_frequency(struct file *file,
 
 	cx18_mute(cx);
 	CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
-	cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
+	cx18_call_all(cx, tuner, s_frequency, vf);
 	cx18_unmute(cx);
 	return 0;
 }
@@ -547,12 +701,11 @@ int cx18_s_std(struct file *file, void *
 	cx->vbi.count = cx->is_50hz ? 18 : 12;
 	cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
 	cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
-	cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
 	CX18_DEBUG_INFO("Switching standard to %llx.\n",
 			(unsigned long long) cx->std);
 
 	/* Tuner */
-	cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+	cx18_call_all(cx, core, s_std, cx->std);
 	return 0;
 }
 
@@ -569,9 +722,7 @@ static int cx18_s_tuner(struct file *fil
 	if (vt->index != 0)
 		return -EINVAL;
 
-	/* Setting tuner can only set audio mode */
-	cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
-
+	cx18_call_all(cx, tuner, s_tuner, vt);
 	return 0;
 }
 
@@ -582,7 +733,7 @@ static int cx18_g_tuner(struct file *fil
 	if (vt->index != 0)
 		return -EINVAL;
 
-	cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
+	cx18_call_all(cx, tuner, g_tuner, vt);
 
 	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
 		strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
@@ -598,7 +749,30 @@ static int cx18_g_tuner(struct file *fil
 static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
 					struct v4l2_sliced_vbi_cap *cap)
 {
-	return -EINVAL;
+	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+	int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+	int f, l;
+
+	if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+		return -EINVAL;
+
+	cap->service_set = 0;
+	for (f = 0; f < 2; f++) {
+		for (l = 0; l < 24; l++) {
+			if (valid_service_line(f, l, cx->is_50hz)) {
+				/*
+				 * We can find all v4l2 supported vbi services
+				 * for the standard, on a valid line for the std
+				 */
+				cap->service_lines[f][l] = set;
+				cap->service_set |= set;
+			} else
+				cap->service_lines[f][l] = 0;
+		}
+	}
+	for (f = 0; f < 3; f++)
+		cap->reserved[f] = 0;
+	return 0;
 }
 
 static int cx18_g_enc_index(struct file *file, void *fh,
@@ -708,13 +882,15 @@ static int cx18_log_status(struct file *
 	struct v4l2_audio audin;
 	int i;
 
-	CX18_INFO("=================  START STATUS CARD #%d  =================\n", cx->num);
+	CX18_INFO("=================  START STATUS CARD #%d  "
+		  "=================\n", cx->instance);
+	CX18_INFO("Version: %s  Card: %s\n", CX18_VERSION, cx->card_name);
 	if (cx->hw_flags & CX18_HW_TVEEPROM) {
 		struct tveeprom tv;
 
 		cx18_read_eeprom(cx, &tv);
 	}
-	cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
+	cx18_call_all(cx, core, log_status);
 	cx18_get_input(cx, cx->active_input, &vidin);
 	cx18_get_audio_input(cx, cx->audio_input, &audin);
 	CX18_INFO("Video Input: %s\n", vidin.name);
@@ -725,12 +901,12 @@ static int cx18_log_status(struct file *
 	mutex_unlock(&cx->gpio_lock);
 	CX18_INFO("Tuner: %s\n",
 		test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?  "Radio" : "TV");
-	cx2341x_log_status(&cx->params, cx->name);
+	cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
 	CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
 	for (i = 0; i < CX18_MAX_STREAMS; i++) {
 		struct cx18_stream *s = &cx->streams[i];
 
-		if (s->v4l2dev == NULL || s->buffers == 0)
+		if (s->video_dev == NULL || s->buffers == 0)
 			continue;
 		CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
 			  s->name, s->s_flags,
@@ -740,7 +916,8 @@ static int cx18_log_status(struct file *
 	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
 			(long long)cx->mpg_data_received,
 			(long long)cx->vbi_data_inserted);
-	CX18_INFO("==================  END STATUS CARD #%d  ==================\n", cx->num);
+	CX18_INFO("==================  END STATUS CARD #%d  "
+		  "==================\n", cx->instance);
 	return 0;
 }
 
@@ -749,20 +926,12 @@ static long cx18_default(struct file *fi
 	struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
 
 	switch (cmd) {
-	case VIDIOC_INT_S_AUDIO_ROUTING: {
-		struct v4l2_routing *route = arg;
-
-		CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
-			route->input, route->output);
-		cx18_audio_set_route(cx, route);
-		break;
-	}
-
 	case VIDIOC_INT_RESET: {
 		u32 val = *(u32 *)arg;
 
 		if ((val == 0) || (val & 0x01))
-			cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
+			cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
+				     (u32) CX18_GPIO_RESET_Z8F0811);
 		break;
 	}
 
@@ -782,6 +951,8 @@ long cx18_v4l2_ioctl(struct file *filp,
 
 	mutex_lock(&cx->serialize_lock);
 
+	/* FIXME - consolidate v4l2_prio_check()'s here */
+
 	if (cx18_debug & CX18_DBGFLG_IOCTL)
 		vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
 	res = video_ioctl2(filp, cmd, arg);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-mailbox.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-mailbox.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-mailbox.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,6 +83,8 @@ static const struct cx18_api_info api_in
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK,			0),
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL,			API_FAST),
 	API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL,			API_SLOW),
+	API_ENTRY(APU, CX18_APU_START,				0),
+	API_ENTRY(APU, CX18_APU_STOP,				0),
 	API_ENTRY(APU, CX18_APU_RESETAI,			0),
 	API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32,			0),
 	API_ENTRY(0, 0,						0),
@@ -98,21 +100,30 @@ static const struct cx18_api_info *find_
 	return NULL;
 }
 
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+/* Call with buf of n*11+1 bytes */
+static char *u32arr2hex(u32 data[], int n, char *buf)
 {
-	char argstr[MAX_MB_ARGUMENTS*11+1];
 	char *p;
 	int i;
 
+	for (i = 0, p = buf; i < n; i++, p += 11) {
+		/* kernel snprintf() appends '\0' always */
+		snprintf(p, 12, " %#010x", data[i]);
+	}
+	*p = '\0';
+	return buf;
+}
+
+static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+{
+	char argstr[MAX_MB_ARGUMENTS*11+1];
+
 	if (!(cx18_debug & CX18_DBGFLG_API))
 		return;
 
-	for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) {
-		/* kernel snprintf() appends '\0' always */
-		snprintf(p, 12, " %#010x", mb->args[i]);
-	}
 	CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
-		"\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr);
+		       "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
+		       u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
 }
 
 
@@ -439,7 +450,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *c
 				"incoming %s to EPU mailbox (sequence no. %u)"
 				"\n",
 				rpu_str[rpu], rpu_str[rpu], order_mb->request);
-		dump_mb(cx, order_mb, "incoming");
+		if (cx18_debug & CX18_DBGFLG_WARN)
+			dump_mb(cx, order_mb, "incoming");
 		order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
 	}
 
@@ -468,16 +480,24 @@ static int cx18_api_call(struct cx18 *cx
 	struct mutex *mb_lock;
 	long int timeout, ret;
 	int i;
+	char argstr[MAX_MB_ARGUMENTS*11+1];
 
 	if (info == NULL) {
 		CX18_WARN("unknown cmd %x\n", cmd);
 		return -EINVAL;
 	}
 
-	if (cmd == CX18_CPU_DE_SET_MDL)
-		CX18_DEBUG_HI_API("%s\n", info->name);
-	else
-		CX18_DEBUG_API("%s\n", info->name);
+	if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
+		if (cmd == CX18_CPU_DE_SET_MDL) {
+			if (cx18_debug & CX18_DBGFLG_HIGHVOL)
+				CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
+						info->name, cmd,
+						u32arr2hex(data, args, argstr));
+		} else
+			CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
+				       info->name, cmd,
+				       u32arr2hex(data, args, argstr));
+	}
 
 	switch (info->rpu) {
 	case APU:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-queue.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-queue.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-queue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-queue.c	2009-06-09 23:05:27.000000000 -0400
@@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream
 		}
 		buf->id = cx->buffer_id++;
 		INIT_LIST_HEAD(&buf->list);
-		buf->dma_handle = pci_map_single(s->cx->dev,
+		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);
@@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream
 
 	/* empty q_free */
 	while ((buf = cx18_dequeue(s, &s->q_free))) {
-		pci_unmap_single(s->cx->dev, buf->dma_handle,
+		pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
 				s->buf_size, s->dma);
 		kfree(buf->buf);
 		kfree(buf);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-queue.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-queue.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-queue.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-queue.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,14 +29,14 @@
 static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
 	struct cx18_buffer *buf)
 {
-	pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
+	pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
 				s->buf_size, s->dma);
 }
 
 static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
 	struct cx18_buffer *buf)
 {
-	pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
+	pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
 				s->buf_size, s->dma);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-streams.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-streams.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-streams.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-streams.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,6 @@
 #include "cx18-streams.h"
 #include "cx18-cards.h"
 #include "cx18-scb.h"
-#include "cx18-av-core.h"
 #include "cx18-dvb.h"
 
 #define CX18_DSP0_INTERRUPT_MASK     	0xd0004C
@@ -101,11 +100,11 @@ static struct {
 static void cx18_stream_init(struct cx18 *cx, int type)
 {
 	struct cx18_stream *s = &cx->streams[type];
-	struct video_device *dev = s->v4l2dev;
+	struct video_device *video_dev = s->video_dev;
 
-	/* we need to keep v4l2dev, so restore it afterwards */
+	/* we need to keep video_dev, so restore it afterwards */
 	memset(s, 0, sizeof(*s));
-	s->v4l2dev = dev;
+	s->video_dev = video_dev;
 
 	/* initialize cx18_stream fields */
 	s->cx = cx;
@@ -130,12 +129,12 @@ static int cx18_prep_dev(struct cx18 *cx
 	struct cx18_stream *s = &cx->streams[type];
 	u32 cap = cx->v4l2_cap;
 	int num_offset = cx18_stream_info[type].num_offset;
-	int num = cx->num + cx18_first_minor + num_offset;
+	int num = cx->instance + cx18_first_minor + num_offset;
 
-	/* These four fields are always initialized. If v4l2dev == NULL, then
+	/* These four fields are always initialized. If video_dev == NULL, then
 	   this stream is not in use. In that case no other fields but these
 	   four can be used. */
-	s->v4l2dev = NULL;
+	s->video_dev = NULL;
 	s->cx = cx;
 	s->type = type;
 	s->name = cx18_stream_info[type].name;
@@ -163,22 +162,22 @@ static int cx18_prep_dev(struct cx18 *cx
 		return 0;
 
 	/* allocate and initialize the v4l2 video device structure */
-	s->v4l2dev = video_device_alloc();
-	if (s->v4l2dev == NULL) {
+	s->video_dev = video_device_alloc();
+	if (s->video_dev == NULL) {
 		CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
 				s->name);
 		return -ENOMEM;
 	}
 
-	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
-			cx->num);
+	snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
+		 cx->v4l2_dev.name, s->name);
 
-	s->v4l2dev->num = num;
-	s->v4l2dev->parent = &cx->dev->dev;
-	s->v4l2dev->fops = &cx18_v4l2_enc_fops;
-	s->v4l2dev->release = video_device_release;
-	s->v4l2dev->tvnorms = V4L2_STD_ALL;
-	cx18_set_funcs(s->v4l2dev);
+	s->video_dev->num = num;
+	s->video_dev->v4l2_dev = &cx->v4l2_dev;
+	s->video_dev->fops = &cx18_v4l2_enc_fops;
+	s->video_dev->release = video_device_release;
+	s->video_dev->tvnorms = V4L2_STD_ALL;
+	cx18_set_funcs(s->video_dev);
 	return 0;
 }
 
@@ -227,28 +226,30 @@ static int cx18_reg_dev(struct cx18 *cx,
 		}
 	}
 
-	if (s->v4l2dev == NULL)
+	if (s->video_dev == NULL)
 		return 0;
 
-	num = s->v4l2dev->num;
+	num = s->video_dev->num;
 	/* card number + user defined offset + device offset */
 	if (type != CX18_ENC_STREAM_TYPE_MPG) {
 		struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
 
-		if (s_mpg->v4l2dev)
-			num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset;
+		if (s_mpg->video_dev)
+			num = s_mpg->video_dev->num
+			    + cx18_stream_info[type].num_offset;
 	}
+	video_set_drvdata(s->video_dev, s);
 
 	/* Register device. First try the desired minor, then any free one. */
-	ret = video_register_device(s->v4l2dev, vfl_type, num);
+	ret = video_register_device(s->video_dev, vfl_type, num);
 	if (ret < 0) {
 		CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
 			s->name, num);
-		video_device_release(s->v4l2dev);
-		s->v4l2dev = NULL;
+		video_device_release(s->video_dev);
+		s->video_dev = NULL;
 		return ret;
 	}
-	num = s->v4l2dev->num;
+	num = s->video_dev->num;
 
 	switch (vfl_type) {
 	case VFL_TYPE_GRABBER:
@@ -312,9 +313,9 @@ void cx18_streams_cleanup(struct cx18 *c
 			cx->streams[type].dvb.enabled = false;
 		}
 
-		vdev = cx->streams[type].v4l2dev;
+		vdev = cx->streams[type].video_dev;
 
-		cx->streams[type].v4l2dev = NULL;
+		cx->streams[type].video_dev = NULL;
 		if (vdev == NULL)
 			continue;
 
@@ -346,46 +347,88 @@ static void cx18_vbi_setup(struct cx18_s
 	}
 
 	/* setup VBI registers */
-	cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
+	v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in);
 
-	/* determine number of lines and total number of VBI bytes.
-	   A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
-	   A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
-	   header, 42 data bytes + checksum (to be confirmed) */
+	/*
+	 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
+	 * VBI when the first analog capture channel starts, as once it starts
+	 * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
+	 * (i.e. for the VBI capture channels).  We also send it for each
+	 * analog capture channel anyway just to make sure we get the proper
+	 * behavior
+	 */
 	if (raw) {
 		lines = cx->vbi.count * 2;
 	} else {
-		lines = cx->is_60hz ? 24 : 38;
-		if (cx->is_60hz)
-			lines += 2;
+		/*
+		 * For 525/60 systems, according to the VIP 2 & BT.656 std:
+		 * The EAV RP code's Field bit toggles on line 4, a few lines
+		 * after the Vertcal Blank bit has already toggled.
+		 * Tell the encoder to capture 21-4+1=18 lines per field,
+		 * since we want lines 10 through 21.
+		 *
+		 * FIXME - revisit for 625/50 systems
+		 */
+		lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
 	}
 
-	cx->vbi.enc_size = lines *
-		(raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
-
 	data[0] = s->handle;
 	/* Lines per field */
 	data[1] = (lines / 2) | ((lines / 2) << 16);
 	/* bytes per line */
-	data[2] = (raw ? cx->vbi.raw_decoder_line_size
-		       : cx->vbi.sliced_decoder_line_size);
+	data[2] = (raw ? vbi_active_samples
+		       : (cx->is_60hz ? vbi_hblank_samples_60Hz
+				      : vbi_hblank_samples_50Hz));
 	/* Every X number of frames a VBI interrupt arrives
 	   (frames as in 25 or 30 fps) */
 	data[3] = 1;
-	/* Setup VBI for the cx25840 digitizer */
+	/*
+	 * Set the SAV/EAV RP codes to look for as start/stop points
+	 * when in VIP-1.1 mode
+	 */
 	if (raw) {
+		/*
+		 * Start codes for beginning of "active" line in vertical blank
+		 * 0x20 (               VerticalBlank                )
+		 * 0x60 (     EvenField VerticalBlank                )
+		 */
 		data[4] = 0x20602060;
+		/*
+		 * End codes for end of "active" raw lines and regular lines
+		 * 0x30 (               VerticalBlank HorizontalBlank)
+		 * 0x70 (     EvenField VerticalBlank HorizontalBlank)
+		 * 0x90 (Task                         HorizontalBlank)
+		 * 0xd0 (Task EvenField               HorizontalBlank)
+		 */
 		data[5] = 0x307090d0;
 	} else {
+		/*
+		 * End codes for active video, we want data in the hblank region
+		 * 0xb0 (Task         0 VerticalBlank HorizontalBlank)
+		 * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
+		 *
+		 * Since the V bit is only allowed to toggle in the EAV RP code,
+		 * just before the first active region line, these two
+		 * are problematic:
+		 * 0x90 (Task                         HorizontalBlank)
+		 * 0xd0 (Task EvenField               HorizontalBlank)
+		 *
+		 * We have set the digitzer such that we don't have to worry
+		 * about these problem codes.
+		 */
 		data[4] = 0xB0F0B0F0;
+		/*
+		 * Start codes for beginning of active line in vertical blank
+		 * 0xa0 (Task           VerticalBlank                )
+		 * 0xe0 (Task EvenField VerticalBlank                )
+		 */
 		data[5] = 0xA0E0A0E0;
 	}
 
 	CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
 			data[0], data[1], data[2], data[3], data[4], data[5]);
 
-	if (s->type == CX18_ENC_STREAM_TYPE_VBI)
-		cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
+	cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
 }
 
 struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
@@ -434,10 +477,10 @@ int cx18_start_v4l2_encode_stream(struct
 	u32 data[MAX_MB_ARGUMENTS];
 	struct cx18 *cx = s->cx;
 	struct cx18_buffer *buf;
-	int ts = 0;
 	int captype = 0;
+	struct cx18_api_func_private priv;
 
-	if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+	if (s->video_dev == NULL && s->dvb.enabled == 0)
 		return -EINVAL;
 
 	CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -453,7 +496,6 @@ int cx18_start_v4l2_encode_stream(struct
 
 	case CX18_ENC_STREAM_TYPE_TS:
 		captype = CAPTURE_CHANNEL_TYPE_TS;
-		ts = 1;
 		break;
 	case CX18_ENC_STREAM_TYPE_YUV:
 		captype = CAPTURE_CHANNEL_TYPE_YUV;
@@ -462,8 +504,16 @@ int cx18_start_v4l2_encode_stream(struct
 		captype = CAPTURE_CHANNEL_TYPE_PCM;
 		break;
 	case CX18_ENC_STREAM_TYPE_VBI:
+#ifdef CX18_ENCODER_PARSES_SLICED
 		captype = cx18_raw_vbi(cx) ?
 		     CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
+#else
+		/*
+		 * Currently we set things up so that Sliced VBI from the
+		 * digitizer is handled as Raw VBI by the encoder
+		 */
+		captype = CAPTURE_CHANNEL_TYPE_VBI;
+#endif
 		cx->vbi.frame = 0;
 		cx->vbi.inserted_frame = 0;
 		memset(cx->vbi.sliced_mpeg_size,
@@ -473,10 +523,6 @@ int cx18_start_v4l2_encode_stream(struct
 		return -EINVAL;
 	}
 
-	/* mute/unmute video */
-	cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
-		  s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
-
 	/* Clear Streamoff flags in case left from last capture */
 	clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 
@@ -484,31 +530,63 @@ int cx18_start_v4l2_encode_stream(struct
 	s->handle = data[0];
 	cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
 
-	if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
-		struct cx18_api_func_private priv;
-
-		/* Stuff from Windows, we don't know what it is */
+	/*
+	 * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
+	 * set up all the parameters, as it is not obvious which parameters the
+	 * firmware shares across capture channel types and which it does not.
+	 *
+	 * Some of the cx18_vapi() calls below apply to only certain capture
+	 * channel types.  We're hoping there's no harm in calling most of them
+	 * anyway, as long as the values are all consistent.  Setting some
+	 * shared parameters will have no effect once an analog capture channel
+	 * has started streaming.
+	 */
+	if (captype != CAPTURE_CHANNEL_TYPE_TS) {
 		cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
 		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
 		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
 		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
-		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
 
+		/*
+		 * Audio related reset according to
+		 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+		 */
+		if (atomic_read(&cx->ana_capturing) == 0)
+			cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
+				  s->handle, 12);
+
+		/*
+		 * Number of lines for Field 1 & Field 2 according to
+		 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+		 * Field 1 is 312 for 625 line systems in BT.656
+		 * Field 2 is 313 for 625 line systems in BT.656
+		 */
 		cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
-			       s->handle, cx->digitizer, cx->digitizer);
+			  s->handle, 312, 313);
 
-		/* Setup VBI */
 		if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
 			cx18_vbi_setup(s);
 
-		/* assign program index info.
-		   Mask 7: select I/P/B, Num_req: 400 max */
+		/*
+		 * assign program index info.
+		 * Mask 7: select I/P/B, Num_req: 400 max
+		 * FIXME - currently we have this hardcoded as disabled
+		 */
 		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
 
-		/* Setup API for Stream */
+		/* Call out to the common CX2341x API setup for user controls */
 		priv.cx = cx;
 		priv.s = s;
 		cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
+
+		/*
+		 * When starting a capture and we're set for radio,
+		 * ensure the video is muted, despite the user control.
+		 */
+		if (!cx->params.video_mute &&
+		    test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
+				  (cx->params.video_mute_yuv << 8) | 1);
 	}
 
 	if (atomic_read(&cx->tot_capturing) == 0) {
@@ -552,7 +630,7 @@ int cx18_start_v4l2_encode_stream(struct
 	}
 
 	/* you're live! sit back and await interrupts :) */
-	if (!ts)
+	if (captype != CAPTURE_CHANNEL_TYPE_TS)
 		atomic_inc(&cx->ana_capturing);
 	atomic_inc(&cx->tot_capturing);
 	return 0;
@@ -565,7 +643,7 @@ void cx18_stop_all_captures(struct cx18
 	for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
 		struct cx18_stream *s = &cx->streams[i];
 
-		if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+		if (s->video_dev == NULL && s->dvb.enabled == 0)
 			continue;
 		if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
 			cx18_stop_v4l2_encode_stream(s, 0);
@@ -577,7 +655,7 @@ int cx18_stop_v4l2_encode_stream(struct
 	struct cx18 *cx = s->cx;
 	unsigned long then;
 
-	if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+	if (s->video_dev == NULL && s->dvb.enabled == 0)
 		return -EINVAL;
 
 	/* This function assumes that you are allowed to stop the capture
@@ -629,7 +707,7 @@ u32 cx18_find_handle(struct cx18 *cx)
 	for (i = 0; i < CX18_MAX_STREAMS; i++) {
 		struct cx18_stream *s = &cx->streams[i];
 
-		if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
+		if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
 			return s->handle;
 	}
 	return CX18_INVALID_TASK_HANDLE;
@@ -647,7 +725,7 @@ struct cx18_stream *cx18_handle_to_strea
 		s = &cx->streams[i];
 		if (s->handle != handle)
 			continue;
-		if (s->v4l2dev || s->dvb.enabled)
+		if (s->video_dev || s->dvb.enabled)
 			return s;
 	}
 	return NULL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-vbi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,16 @@
 #include "cx18-vbi.h"
 #include "cx18-ioctl.h"
 #include "cx18-queue.h"
-#include "cx18-av-core.h"
+
+/*
+ * Raster Reference/Protection (RP) bytes, used in Start/End Active
+ * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
+ * of VBI sample or VBI ancilliary data regions in the digitial ratser line.
+ *
+ * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
+ */
+static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 };    /* __V_, _FV_ */
+static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
 
 static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
 {
@@ -34,10 +43,17 @@ static void copy_vbi_data(struct cx18 *c
 	u32 linemask[2] = { 0, 0 };
 	unsigned short size;
 	static const u8 mpeg_hdr_data[] = {
-		0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
-		0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
-		0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
-		0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
+		/* MPEG-2 Program Pack */
+		0x00, 0x00, 0x01, 0xba,		    /* Prog Pack start code */
+		0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
+		0x01, 0xd1, 0xd3,		    /* Mux Rate, markers */
+		0xfa, 0xff, 0xff,		    /* Res, Suff cnt, Stuff */
+		/* MPEG-2 Private Stream 1 PES Packet */
+		0x00, 0x00, 0x01, 0xbd,		    /* Priv Stream 1 start */
+		0x00, 0x1a,			    /* length */
+		0x84, 0x80, 0x07,		    /* flags, hdr data len */
+		0x21, 0x00, 0x5d, 0x63, 0xa7, 	    /* PTS, markers */
+		0xff, 0xff			    /* stuffing */
 	};
 	const int sd = sizeof(mpeg_hdr_data);	/* start of vbi data */
 	int idx = cx->vbi.frame % CX18_VBI_FRAMES;
@@ -71,7 +87,9 @@ static void copy_vbi_data(struct cx18 *c
 		memcpy(dst + sd + 4, dst + sd + 12, line * 43);
 		size = 4 + ((43 * line + 3) & ~3);
 	} else {
-		memcpy(dst + sd, "cx0", 4);
+		memcpy(dst + sd, "itv0", 4);
+		cpu_to_le32s(&linemask[0]);
+		cpu_to_le32s(&linemask[1]);
 		memcpy(dst + sd + 4, &linemask[0], 8);
 		size = 12 + ((43 * line + 3) & ~3);
 	}
@@ -86,58 +104,76 @@ static void copy_vbi_data(struct cx18 *c
 }
 
 /* Compress raw VBI format, removes leading SAV codes and surplus space
-   after the field.
-   Returns new compressed size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
+   after the frame.  Returns new compressed size. */
+static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
 {
-	u32 line_size = cx->vbi.raw_decoder_line_size;
-	u32 lines = cx->vbi.count;
-	u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
-	u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
+	u32 line_size = vbi_active_samples;
+	u32 lines = cx->vbi.count * 2;
 	u8 *q = buf;
 	u8 *p;
 	int i;
 
+	/* Skip the header */
+	buf += hdr_size;
+
 	for (i = 0; i < lines; i++) {
 		p = buf + i * line_size;
 
 		/* Look for SAV code */
 		if (p[0] != 0xff || p[1] || p[2] ||
-		    (p[3] != sav1 && p[3] != sav2))
+		    (p[3] != raw_vbi_sav_rp[0] &&
+		     p[3] != raw_vbi_sav_rp[1]))
 			break;
-		memcpy(q, p + 4, line_size - 4);
-		q += line_size - 4;
+		if (i == lines - 1) {
+			/* last line is hdr_size bytes short - extrapolate it */
+			memcpy(q, p + 4, line_size - 4 - hdr_size);
+			q += line_size - 4 - hdr_size;
+			p += line_size - hdr_size - 1;
+			memset(q, (int) *p, hdr_size);
+		} else {
+			memcpy(q, p + 4, line_size - 4);
+			q += line_size - 4;
+		}
 	}
 	return lines * (line_size - 4);
 }
 
-
-/* Compressed VBI format, all found sliced blocks put next to one another
-   Returns new compressed size */
-static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
-			       u32 size, u8 sav)
+static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
+			       const u32 hdr_size)
 {
-	u32 line_size = cx->vbi.sliced_decoder_line_size;
 	struct v4l2_decode_vbi_line vbi;
 	int i;
+	u32 line = 0;
+	u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
+				    : vbi_hblank_samples_50Hz;
 
 	/* find the first valid line */
-	for (i = 0; i < size; i++, buf++) {
-		if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
+	for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
+		if (buf[0] == 0xff && !buf[1] && !buf[2] &&
+		    (buf[3] == sliced_vbi_eav_rp[0] ||
+		     buf[3] == sliced_vbi_eav_rp[1]))
 			break;
 	}
 
-	size -= i;
+	/*
+	 * The last line is short by hdr_size bytes, but for the remaining
+	 * checks against size, we pretend that it is not, by counting the
+	 * header bytes we knowingly skipped
+	 */
+	size -= (i - hdr_size);
 	if (size < line_size)
 		return line;
+
 	for (i = 0; i < size / line_size; i++) {
 		u8 *p = buf + i * line_size;
 
-		/* Look for SAV code  */
-		if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
+		/* Look for EAV code  */
+		if (p[0] != 0xff || p[1] || p[2] ||
+		    (p[3] != sliced_vbi_eav_rp[0] &&
+		     p[3] != sliced_vbi_eav_rp[1]))
 			continue;
 		vbi.p = p + 4;
-		cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
+		v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
 		if (vbi.type) {
 			cx->vbi.sliced_data[line].id = vbi.type;
 			cx->vbi.sliced_data[line].field = vbi.is_second_field;
@@ -150,51 +186,56 @@ static u32 compress_sliced_buf(struct cx
 }
 
 void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
-			   u64 pts_stamp, int streamtype)
+			   int streamtype)
 {
+	/*
+	 * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
+	 * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
+	 */
+	struct vbi_data_hdr {
+		__be32 magic;
+		__be32 unknown;
+		__be32 pts;
+	} *hdr = (struct vbi_data_hdr *) buf->buf;
+
 	u8 *p = (u8 *) buf->buf;
 	u32 size = buf->bytesused;
+	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
+	 * line.  This has a side effect of making the header big endian
+	 */
+	cx18_buf_swap(buf);
+
 	/* Raw VBI data */
 	if (cx18_raw_vbi(cx)) {
-		u8 type;
 
-		cx18_buf_swap(buf);
-
-		/* Skip 12 bytes of header that gets stuffed in */
-		size -= 12;
-		memcpy(p, &buf->buf[12], size);
-		type = p[3];
-
-		size = buf->bytesused = compress_raw_buf(cx, p, size);
+		size = buf->bytesused =
+		     compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
 
-		/* second field of the frame? */
-		if (type == cx->vbi.raw_decoder_sav_even_field) {
-			/* Dirty hack needed for backwards
-			   compatibility of old VBI software. */
-			p += size - 4;
-			memcpy(p, &cx->vbi.frame, 4);
-			cx->vbi.frame++;
-		}
+		/*
+		 * Hack needed for compatibility with old VBI software.
+		 * Write the frame # at the last 4 bytes of the frame
+		 */
+		p += size - 4;
+		memcpy(p, &cx->vbi.frame, 4);
+		cx->vbi.frame++;
 		return;
 	}
 
 	/* Sliced VBI data with data insertion */
-	cx18_buf_swap(buf);
 
-	/* first field */
-	lines = compress_sliced_buf(cx, 0, p, size / 2,
-			cx->vbi.sliced_decoder_sav_odd_field);
-	/* second field */
-	/* experimentation shows that the second half does not always
-	   begin at the exact address. So start a bit earlier
-	   (hence 32). */
-	lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
-			size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
+	pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
+						      : 0;
+
+	lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
+
 	/* always return at least one empty line */
 	if (lines == 0) {
 		cx->vbi.sliced_data[0].id = 0;
@@ -206,6 +247,6 @@ void cx18_process_vbi_data(struct cx18 *
 	memcpy(p, &cx->vbi.sliced_data[0], size);
 
 	if (cx->vbi.insert_mpeg)
-		copy_vbi_data(cx, lines, pts_stamp);
+		copy_vbi_data(cx, lines, pts);
 	cx->vbi.frame++;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-vbi.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-vbi.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-vbi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-vbi.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,5 +22,5 @@
  */
 
 void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
-			   u64 pts_stamp, int streamtype);
+			   int streamtype);
 int cx18_used_line(struct cx18 *cx, int line, int field);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-version.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-version.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-version.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-version.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,8 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 0
-#define CX18_DRIVER_VERSION_PATCHLEVEL 4
+#define CX18_DRIVER_VERSION_MINOR 1
+#define CX18_DRIVER_VERSION_PATCHLEVEL 0
 
 #define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
 #define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-video.c linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx18-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,25 +21,12 @@
 
 #include "cx18-driver.h"
 #include "cx18-video.h"
-#include "cx18-av-core.h"
 #include "cx18-cards.h"
 
 void cx18_video_set_io(struct cx18 *cx)
 {
-	struct v4l2_routing route;
 	int inp = cx->active_input;
-	u32 type;
-
-	route.input = cx->card->video_inputs[inp].video_input;
-	route.output = 0;
-	cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
-
-	type = cx->card->video_inputs[inp].video_type;
 
-	if (type == CX18_CARD_INPUT_VID_TUNER)
-		route.input = 0;  /* Tuner */
-	else if (type < CX18_CARD_INPUT_COMPOSITE1)
-		route.input = 2;  /* S-Video */
-	else
-		route.input = 1;  /* Composite */
+	v4l2_subdev_call(cx->sd_av, video, s_routing,
+			cx->card->video_inputs[inp].video_input, 0, 0);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx23418.h linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx23418.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/cx23418.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx23418.h	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,22 @@
 #define APU_CMD_MASK 				0x10000000
 #define APU_CMD_MASK_ACK 			(APU_CMD_MASK | 0x80000000)
 
+#define CX18_APU_ENCODING_METHOD_MPEG		(0 << 28)
+#define CX18_APU_ENCODING_METHOD_AC3		(1 << 28)
+
+/* Description: Command APU to start audio
+   IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
+   IN[1] - caller buffer address, or 0
+   ReturnCode - ??? */
+#define CX18_APU_START				(APU_CMD_MASK | 0x01)
+
+/* Description: Command APU to stop audio
+   IN[0] - encoding method to stop
+   ReturnCode - ??? */
+#define CX18_APU_STOP				(APU_CMD_MASK | 0x02)
+
+/* Description: Command APU to reset the AI
+   ReturnCode - ??? */
 #define CX18_APU_RESETAI 			(APU_CMD_MASK | 0x05)
 
 /* Description: This command indicates that a Memory Descriptor List has been
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx18/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/cx18/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx18/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx18/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@ config VIDEO_CX18
 	select VIDEO_CX2341X
 	select VIDEO_CS5345
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This is a video4linux driver for Conexant cx23418 based
 	  PCI combo video recorder devices.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,586 @@
+/*
+ *  Conexant Cx231xx audio extension
+ *
+ *  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+ *       Based on em28xx 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/sound.h>
+#include <linux/spinlock.h>
+#include <linux/soundcard.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <media/v4l2-common.h>
+#include "cx231xx.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+#define dprintk(fmt, arg...) do {					\
+		if (debug)						\
+			printk(KERN_INFO "cx231xx-audio %s: " fmt,	\
+				__func__, ##arg); 			\
+	} while (0)
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+
+static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
+{
+	int i;
+
+	dprintk("Stopping isoc\n");
+
+	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+		if (dev->adev.urb[i]) {
+			if (!irqs_disabled())
+				usb_kill_urb(dev->adev.urb[i]);
+			else
+				usb_unlink_urb(dev->adev.urb[i]);
+
+			usb_free_urb(dev->adev.urb[i]);
+			dev->adev.urb[i] = NULL;
+
+			kfree(dev->adev.transfer_buffer[i]);
+			dev->adev.transfer_buffer[i] = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static void cx231xx_audio_isocirq(struct urb *urb)
+{
+	struct cx231xx *dev = urb->context;
+	int i;
+	unsigned int oldptr;
+	int period_elapsed = 0;
+	int status;
+	unsigned char *cp;
+	unsigned int stride;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
+
+	switch (urb->status) {
+	case 0:		/* success */
+	case -ETIMEDOUT:	/* NAK */
+		break;
+	case -ECONNRESET:	/* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:		/* error */
+		dprintk("urb completition error %d.\n", urb->status);
+		break;
+	}
+
+	if (dev->adev.capture_pcm_substream) {
+		substream = dev->adev.capture_pcm_substream;
+		runtime = substream->runtime;
+		stride = runtime->frame_bits >> 3;
+
+		for (i = 0; i < urb->number_of_packets; i++) {
+			int length = urb->iso_frame_desc[i].actual_length /
+				     stride;
+			cp = (unsigned char *)urb->transfer_buffer +
+					      urb->iso_frame_desc[i].offset;
+
+			if (!length)
+				continue;
+
+			oldptr = dev->adev.hwptr_done_capture;
+			if (oldptr + length >= runtime->buffer_size) {
+				unsigned int cnt;
+
+				cnt = runtime->buffer_size - oldptr;
+				memcpy(runtime->dma_area + oldptr * stride, cp,
+				       cnt * stride);
+				memcpy(runtime->dma_area, cp + cnt * stride,
+				       length * stride - cnt * stride);
+			} else {
+				memcpy(runtime->dma_area + oldptr * stride, cp,
+				       length * stride);
+			}
+
+			snd_pcm_stream_lock(substream);
+
+			dev->adev.hwptr_done_capture += length;
+			if (dev->adev.hwptr_done_capture >=
+						runtime->buffer_size)
+				dev->adev.hwptr_done_capture -=
+						runtime->buffer_size;
+
+			dev->adev.capture_transfer_done += length;
+			if (dev->adev.capture_transfer_done >=
+				runtime->period_size) {
+				dev->adev.capture_transfer_done -=
+						runtime->period_size;
+				period_elapsed = 1;
+			}
+			snd_pcm_stream_unlock(substream);
+		}
+		if (period_elapsed)
+			snd_pcm_period_elapsed(substream);
+	}
+	urb->status = 0;
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status < 0) {
+		cx231xx_errdev("resubmit of audio urb failed (error=%i)\n",
+			       status);
+	}
+	return;
+}
+
+static int cx231xx_init_audio_isoc(struct cx231xx *dev)
+{
+	int i, errCode;
+	int sb_size;
+
+	cx231xx_info("%s: Starting AUDIO transfers\n", __func__);
+
+	sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
+
+	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+		struct urb *urb;
+		int j, k;
+
+		dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
+		if (!dev->adev.transfer_buffer[i])
+			return -ENOMEM;
+
+		memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
+		urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
+		if (!urb) {
+			cx231xx_errdev("usb_alloc_urb failed!\n");
+			for (j = 0; j < i; j++) {
+				usb_free_urb(dev->adev.urb[j]);
+				kfree(dev->adev.transfer_buffer[j]);
+			}
+			return -ENOMEM;
+		}
+
+		urb->dev = dev->udev;
+		urb->context = dev;
+		urb->pipe = usb_rcvisocpipe(dev->udev,
+						dev->adev.end_point_addr);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_buffer = dev->adev.transfer_buffer[i];
+		urb->interval = 1;
+		urb->complete = cx231xx_audio_isocirq;
+		urb->number_of_packets = CX231XX_NUM_AUDIO_PACKETS;
+		urb->transfer_buffer_length = sb_size;
+
+		for (j = k = 0; j < CX231XX_NUM_AUDIO_PACKETS;
+			j++, k += dev->adev.max_pkt_size) {
+			urb->iso_frame_desc[j].offset = k;
+			urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
+		}
+		dev->adev.urb[i] = urb;
+	}
+
+	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
+		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
+		if (errCode < 0) {
+			cx231xx_isoc_audio_deinit(dev);
+			return errCode;
+		}
+	}
+
+	return errCode;
+}
+
+static int cx231xx_cmd(struct cx231xx *dev, int cmd, int arg)
+{
+	dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
+		"stop" : "start");
+
+	switch (cmd) {
+	case CX231XX_CAPTURE_STREAM_EN:
+		if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+			dev->adev.capture_stream = STREAM_ON;
+			cx231xx_init_audio_isoc(dev);
+		} else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+			dev->adev.capture_stream = STREAM_OFF;
+			cx231xx_isoc_audio_deinit(dev);
+		} else {
+			cx231xx_errdev("An underrun very likely occurred. "
+				       "Ignoring it.\n");
+		}
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
+					size_t size)
+{
+	struct snd_pcm_runtime *runtime = subs->runtime;
+
+	dprintk("Allocating vbuffer\n");
+	if (runtime->dma_area) {
+		if (runtime->dma_bytes > size)
+			return 0;
+
+		vfree(runtime->dma_area);
+	}
+	runtime->dma_area = vmalloc(size);
+	if (!runtime->dma_area)
+		return -ENOMEM;
+
+	runtime->dma_bytes = size;
+
+	return 0;
+}
+
+static struct snd_pcm_hardware snd_cx231xx_hw_capture = {
+	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER 	|
+	    SNDRV_PCM_INFO_MMAP 		|
+	    SNDRV_PCM_INFO_INTERLEAVED 		|
+	    SNDRV_PCM_INFO_MMAP_VALID,
+
+	.formats = SNDRV_PCM_FMTBIT_S16_LE,
+
+	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
+
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.channels_min = 2,
+	.channels_max = 2,
+	.buffer_bytes_max = 62720 * 8,	/* just about the value in usbaudio.c */
+	.period_bytes_min = 64,		/* 12544/2, */
+	.period_bytes_max = 12544,
+	.periods_min = 2,
+	.periods_max = 98,		/* 12544, */
+};
+
+static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
+{
+	struct cx231xx *dev = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret = 0;
+
+	dprintk("opening device and trying to acquire exclusive lock\n");
+
+	if (!dev) {
+		cx231xx_errdev("BUG: cx231xx can't find device struct."
+			       " Can't proceed with open\n");
+		return -ENODEV;
+	}
+
+	/* Sets volume, mute, etc */
+	dev->mute = 0;
+
+	/* set alternate setting for audio interface */
+	/* 1 - 48000 samples per sec */
+	ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1);
+	if (ret < 0) {
+		cx231xx_errdev("failed to set alternate setting !\n");
+
+		return ret;
+	}
+
+	/* inform hardware to start streaming */
+	ret = cx231xx_capture_start(dev, 1, Audio);
+
+	runtime->hw = snd_cx231xx_hw_capture;
+
+	mutex_lock(&dev->lock);
+	dev->adev.users++;
+	mutex_unlock(&dev->lock);
+
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	dev->adev.capture_pcm_substream = substream;
+	runtime->private_data = dev;
+
+	return 0;
+}
+
+static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
+{
+	int ret;
+	struct cx231xx *dev = snd_pcm_substream_chip(substream);
+
+	dprintk("closing device\n");
+
+	/* set alternate setting for audio interface */
+	/* 1 - 48000 samples per sec */
+	ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
+	if (ret < 0) {
+		cx231xx_errdev("failed to set alternate setting !\n");
+
+		return ret;
+	}
+
+	/* inform hardware to start streaming */
+	ret = cx231xx_capture_start(dev, 0, Audio);
+
+	dev->mute = 1;
+	mutex_lock(&dev->lock);
+	dev->adev.users--;
+	mutex_unlock(&dev->lock);
+
+	if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
+		dprintk("audio users: %d\n", dev->adev.users);
+		dprintk("disabling audio stream!\n");
+		dev->adev.shutdown = 0;
+		dprintk("released lock\n");
+		cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, 0);
+	}
+	return 0;
+}
+
+static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
+{
+	unsigned int channels, rate, format;
+	int ret;
+
+	dprintk("Setting capture parameters\n");
+
+	ret = snd_pcm_alloc_vmalloc_buffer(substream,
+					   params_buffer_bytes(hw_params));
+	format = params_format(hw_params);
+	rate = params_rate(hw_params);
+	channels = params_channels(hw_params);
+
+	/* TODO: set up cx231xx audio chip to deliver the correct audio format,
+	   current default is 48000hz multiplexed => 96000hz mono
+	   which shouldn't matter since analogue TV only supports mono */
+	return 0;
+}
+
+static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
+{
+	struct cx231xx *dev = snd_pcm_substream_chip(substream);
+
+	dprintk("Stop capture, if needed\n");
+
+	if (dev->adev.capture_stream == STREAM_ON)
+		cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO);
+
+	return 0;
+}
+
+static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
+				       int cmd)
+{
+	struct cx231xx *dev = snd_pcm_substream_chip(substream);
+	int retval;
+
+	dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+		"start" : "stop");
+
+	spin_lock(&dev->adev.slock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN,
+			    CX231XX_START_AUDIO);
+		retval = 0;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		cx231xx_cmd(dev, CX231XX_CAPTURE_STREAM_EN, CX231XX_STOP_AUDIO);
+		retval = 0;
+		break;
+	default:
+		retval = -EINVAL;
+	}
+
+	spin_unlock(&dev->adev.slock);
+	return retval;
+}
+
+static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
+						     *substream)
+{
+	struct cx231xx *dev;
+	unsigned long flags;
+	snd_pcm_uframes_t hwptr_done;
+
+	dev = snd_pcm_substream_chip(substream);
+
+	spin_lock_irqsave(&dev->adev.slock, flags);
+	hwptr_done = dev->adev.hwptr_done_capture;
+	spin_unlock_irqrestore(&dev->adev.slock, flags);
+
+	return hwptr_done;
+}
+
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
+					     unsigned long offset)
+{
+	void *pageptr = subs->runtime->dma_area + offset;
+
+	return vmalloc_to_page(pageptr);
+}
+
+static struct snd_pcm_ops snd_cx231xx_pcm_capture = {
+	.open = snd_cx231xx_capture_open,
+	.close = snd_cx231xx_pcm_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_cx231xx_hw_capture_params,
+	.hw_free = snd_cx231xx_hw_capture_free,
+	.prepare = snd_cx231xx_prepare,
+	.trigger = snd_cx231xx_capture_trigger,
+	.pointer = snd_cx231xx_capture_pointer,
+	.page = snd_pcm_get_vmalloc_page,
+};
+
+static int cx231xx_audio_init(struct cx231xx *dev)
+{
+	struct cx231xx_audio *adev = &dev->adev;
+	struct snd_pcm *pcm;
+	struct snd_card *card;
+	static int devnr;
+	int err;
+	struct usb_interface *uif;
+	int i, isoc_pipe = 0;
+
+	if (dev->has_alsa_audio != 1) {
+		/* This device does not support the extension (in this case
+		   the device is expecting the snd-usb-audio module or
+		   doesn't have analog audio support at all) */
+		return 0;
+	}
+
+	cx231xx_info("cx231xx-audio.c: probing for cx231xx "
+		     "non standard usbaudio\n");
+
+	err = snd_card_create(index[devnr], "Cx231xx Audio", THIS_MODULE,
+			      0, &card);
+	if (err < 0)
+		return err;
+
+	spin_lock_init(&adev->slock);
+	err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
+	if (err < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+			&snd_cx231xx_pcm_capture);
+	pcm->info_flags = 0;
+	pcm->private_data = dev;
+	strcpy(pcm->name, "Conexant cx231xx Capture");
+	strcpy(card->driver, "Conexant cx231xx Audio");
+	strcpy(card->shortname, "Cx231xx Audio");
+	strcpy(card->longname, "Conexant cx231xx Audio");
+
+	err = snd_card_register(card);
+	if (err < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	adev->sndcard = card;
+	adev->udev = dev->udev;
+
+	/* compute alternate max packet sizes for Audio */
+	uif =
+	    dev->udev->actconfig->interface[dev->current_pcb_config.
+					    hs_config_info[0].interface_info.
+					    audio_index + 1];
+
+	adev->end_point_addr =
+	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+			bEndpointAddress);
+
+	adev->num_alt = uif->num_altsetting;
+	cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+		     adev->end_point_addr, adev->num_alt);
+	adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
+
+	if (adev->alt_max_pkt_size == NULL) {
+		cx231xx_errdev("out of memory!\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < adev->num_alt; i++) {
+		u16 tmp =
+		    le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
+				wMaxPacketSize);
+		adev->alt_max_pkt_size[i] =
+		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+		cx231xx_info("Alternate setting %i, max size= %i\n", i,
+			     adev->alt_max_pkt_size[i]);
+	}
+
+	return 0;
+}
+
+static int cx231xx_audio_fini(struct cx231xx *dev)
+{
+	if (dev == NULL)
+		return 0;
+
+	if (dev->has_alsa_audio != 1) {
+		/* This device does not support the extension (in this case
+		   the device is expecting the snd-usb-audio module or
+		   doesn't have analog audio support at all) */
+		return 0;
+	}
+
+	if (dev->adev.sndcard) {
+		snd_card_free(dev->adev.sndcard);
+		kfree(dev->adev.alt_max_pkt_size);
+		dev->adev.sndcard = NULL;
+	}
+
+	return 0;
+}
+
+static struct cx231xx_ops audio_ops = {
+	.id = CX231XX_AUDIO,
+	.name = "Cx231xx Audio Extension",
+	.init = cx231xx_audio_init,
+	.fini = cx231xx_audio_fini,
+};
+
+static int __init cx231xx_alsa_register(void)
+{
+	return cx231xx_register_extension(&audio_ops);
+}
+
+static void __exit cx231xx_alsa_unregister(void)
+{
+	cx231xx_unregister_extension(&audio_ops);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
+MODULE_DESCRIPTION("Cx231xx Audio driver");
+
+module_init(cx231xx_alsa_register);
+module_exit(cx231xx_alsa_unregister);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-avcore.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2581 @@
+/*
+   cx231xx_avcore.c - driver for Conexant Cx23100/101/102
+		      USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+
+   This program contains the specific code to control the avdecoder chip and
+   other related usb control functions for cx231xx based chipset.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU 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/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "cx231xx.h"
+
+/******************************************************************************
+			-: BLOCK ARRANGEMENT :-
+	I2S block ----------------------|
+	[I2S audio]			|
+					|
+	Analog Front End --> Direct IF -|-> Cx25840 --> Audio
+	[video & audio]			|   [Audio]
+					|
+					|-> Cx25840 --> Video
+					    [Video]
+
+*******************************************************************************/
+
+/******************************************************************************
+ *                    A F E - B L O C K    C O N T R O L   functions          *
+ * 				[ANALOG FRONT END]			      *
+ ******************************************************************************/
+static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
+{
+	return cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+					saddr, 2, data, 1);
+}
+
+static int afe_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
+{
+	int status;
+	u32 temp = 0;
+
+	status = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+					saddr, 2, &temp, 1);
+	*data = (u8) temp;
+	return status;
+}
+
+int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count)
+{
+	int status = 0;
+	u8 temp = 0;
+	u8 afe_power_status = 0;
+	int i = 0;
+
+	/* super block initialize */
+	temp = (u8) (ref_count & 0xff);
+	status = afe_write_byte(dev, SUP_BLK_TUNE2, temp);
+	if (status < 0)
+		return status;
+
+	status = afe_read_byte(dev, SUP_BLK_TUNE2, &afe_power_status);
+	if (status < 0)
+		return status;
+
+	temp = (u8) ((ref_count & 0x300) >> 8);
+	temp |= 0x40;
+	status = afe_write_byte(dev, SUP_BLK_TUNE1, temp);
+	if (status < 0)
+		return status;
+
+	status = afe_write_byte(dev, SUP_BLK_PLL2, 0x0f);
+	if (status < 0)
+		return status;
+
+	/* enable pll     */
+	while (afe_power_status != 0x18) {
+		status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18);
+		if (status < 0) {
+			cx231xx_info(
+			": Init Super Block failed in send cmd\n");
+			break;
+		}
+
+		status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status);
+		afe_power_status &= 0xff;
+		if (status < 0) {
+			cx231xx_info(
+			": Init Super Block failed in receive cmd\n");
+			break;
+		}
+		i++;
+		if (i == 10) {
+			cx231xx_info(
+			": Init Super Block force break in loop !!!!\n");
+			status = -1;
+			break;
+		}
+	}
+
+	if (status < 0)
+		return status;
+
+	/* start tuning filter */
+	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x40);
+	if (status < 0)
+		return status;
+
+	msleep(5);
+
+	/* exit tuning */
+	status = afe_write_byte(dev, SUP_BLK_TUNE3, 0x00);
+
+	return status;
+}
+
+int cx231xx_afe_init_channels(struct cx231xx *dev)
+{
+	int status = 0;
+
+	/* power up all 3 channels, clear pd_buffer */
+	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1, 0x00);
+	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, 0x00);
+	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00);
+
+	/* Enable quantizer calibration */
+	status = afe_write_byte(dev, ADC_COM_QUANT, 0x02);
+
+	/* channel initialize, force modulator (fb) reset */
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x17);
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x17);
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x17);
+
+	/* start quantilizer calibration  */
+	status = afe_write_byte(dev, ADC_CAL_ATEST_CH1, 0x10);
+	status = afe_write_byte(dev, ADC_CAL_ATEST_CH2, 0x10);
+	status = afe_write_byte(dev, ADC_CAL_ATEST_CH3, 0x10);
+	msleep(5);
+
+	/* exit modulator (fb) reset */
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH1, 0x07);
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH2, 0x07);
+	status = afe_write_byte(dev, ADC_FB_FRCRST_CH3, 0x07);
+
+	/* enable the pre_clamp in each channel for single-ended input */
+	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH1, 0xf0);
+	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH2, 0xf0);
+	status = afe_write_byte(dev, ADC_NTF_PRECLMP_EN_CH3, 0xf0);
+
+	/* use diode instead of resistor, so set term_en to 0, res_en to 0  */
+	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+				   ADC_QGAIN_RES_TRM_CH1, 3, 7, 0x00);
+	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+				   ADC_QGAIN_RES_TRM_CH2, 3, 7, 0x00);
+	status = cx231xx_reg_mask_write(dev, AFE_DEVICE_ADDRESS, 8,
+				   ADC_QGAIN_RES_TRM_CH3, 3, 7, 0x00);
+
+	/* dynamic element matching off */
+	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH1, 0x03);
+	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH2, 0x03);
+	status = afe_write_byte(dev, ADC_DCSERVO_DEM_CH3, 0x03);
+
+	return status;
+}
+
+int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev)
+{
+	u8 c_value = 0;
+	int status = 0;
+
+	status = afe_read_byte(dev, ADC_PWRDN_CLAMP_CH2, &c_value);
+	c_value &= (~(0x50));
+	status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2, c_value);
+
+	return status;
+}
+
+/*
+	The Analog Front End in Cx231xx has 3 channels. These
+	channels are used to share between different inputs
+	like tuner, s-video and composite inputs.
+
+	channel 1 ----- pin 1  to pin4(in reg is 1-4)
+	channel 2 ----- pin 5  to pin8(in reg is 5-8)
+	channel 3 ----- pin 9 to pin 12(in reg is 9-11)
+*/
+int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux)
+{
+	u8 ch1_setting = (u8) input_mux;
+	u8 ch2_setting = (u8) (input_mux >> 8);
+	u8 ch3_setting = (u8) (input_mux >> 16);
+	int status = 0;
+	u8 value = 0;
+
+	if (ch1_setting != 0) {
+		status = afe_read_byte(dev, ADC_INPUT_CH1, &value);
+		value &= (!INPUT_SEL_MASK);
+		value |= (ch1_setting - 1) << 4;
+		value &= 0xff;
+		status = afe_write_byte(dev, ADC_INPUT_CH1, value);
+	}
+
+	if (ch2_setting != 0) {
+		status = afe_read_byte(dev, ADC_INPUT_CH2, &value);
+		value &= (!INPUT_SEL_MASK);
+		value |= (ch2_setting - 1) << 4;
+		value &= 0xff;
+		status = afe_write_byte(dev, ADC_INPUT_CH2, value);
+	}
+
+	/* For ch3_setting, the value to put in the register is
+	   7 less than the input number */
+	if (ch3_setting != 0) {
+		status = afe_read_byte(dev, ADC_INPUT_CH3, &value);
+		value &= (!INPUT_SEL_MASK);
+		value |= (ch3_setting - 1) << 4;
+		value &= 0xff;
+		status = afe_write_byte(dev, ADC_INPUT_CH3, value);
+	}
+
+	return status;
+}
+
+int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode)
+{
+	int status = 0;
+
+	/*
+	* FIXME: We need to implement the AFE code for LOW IF and for HI IF.
+	* Currently, only baseband works.
+	*/
+
+	switch (mode) {
+	case AFE_MODE_LOW_IF:
+		/* SetupAFEforLowIF();  */
+		break;
+	case AFE_MODE_BASEBAND:
+		status = cx231xx_afe_setup_AFE_for_baseband(dev);
+		break;
+	case AFE_MODE_EU_HI_IF:
+		/* SetupAFEforEuHiIF(); */
+		break;
+	case AFE_MODE_US_HI_IF:
+		/* SetupAFEforUsHiIF(); */
+		break;
+	case AFE_MODE_JAPAN_HI_IF:
+		/* SetupAFEforJapanHiIF(); */
+		break;
+	}
+
+	if ((mode != dev->afe_mode) &&
+		(dev->video_input == CX231XX_VMUX_TELEVISION))
+		status = cx231xx_afe_adjust_ref_count(dev,
+						     CX231XX_VMUX_TELEVISION);
+
+	dev->afe_mode = mode;
+
+	return status;
+}
+
+int cx231xx_afe_update_power_control(struct cx231xx *dev,
+					enum AV_MODE avmode)
+{
+	u8 afe_power_status = 0;
+	int status = 0;
+
+	switch (dev->model) {
+	case CX231XX_BOARD_CNXT_RDE_250:
+	case CX231XX_BOARD_CNXT_RDU_250:
+		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
+			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+						FLD_PWRDN_ENABLE_PLL)) {
+				status = afe_write_byte(dev, SUP_BLK_PWRDN,
+							FLD_PWRDN_TUNING_BIAS |
+							FLD_PWRDN_ENABLE_PLL);
+				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+							&afe_power_status);
+				if (status < 0)
+					break;
+			}
+
+			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+							0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+							0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+							0x00);
+		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
+			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+							0x70);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+							0x70);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+							0x70);
+
+			status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+						  &afe_power_status);
+			afe_power_status |= FLD_PWRDN_PD_BANDGAP |
+						FLD_PWRDN_PD_BIAS |
+						FLD_PWRDN_PD_TUNECK;
+			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
+						   afe_power_status);
+		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
+			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+						FLD_PWRDN_ENABLE_PLL)) {
+				status = afe_write_byte(dev, SUP_BLK_PWRDN,
+							FLD_PWRDN_TUNING_BIAS |
+							FLD_PWRDN_ENABLE_PLL);
+				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+							&afe_power_status);
+				if (status < 0)
+					break;
+			}
+
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+						0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+						0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+						0x00);
+		} else {
+			cx231xx_info("Invalid AV mode input\n");
+			status = -1;
+		}
+		break;
+	default:
+		if (avmode == POLARIS_AVMODE_ANALOGT_TV) {
+			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+						FLD_PWRDN_ENABLE_PLL)) {
+				status = afe_write_byte(dev, SUP_BLK_PWRDN,
+							FLD_PWRDN_TUNING_BIAS |
+							FLD_PWRDN_ENABLE_PLL);
+				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+							&afe_power_status);
+				if (status < 0)
+					break;
+			}
+
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+							0x40);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+							0x40);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+							0x00);
+		} else if (avmode == POLARIS_AVMODE_DIGITAL) {
+			status = afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+							0x70);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+							0x70);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+							0x70);
+
+			status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+						       &afe_power_status);
+			afe_power_status |= FLD_PWRDN_PD_BANDGAP |
+						FLD_PWRDN_PD_BIAS |
+						FLD_PWRDN_PD_TUNECK;
+			status |= afe_write_byte(dev, SUP_BLK_PWRDN,
+							afe_power_status);
+		} else if (avmode == POLARIS_AVMODE_ENXTERNAL_AV) {
+			while (afe_power_status != (FLD_PWRDN_TUNING_BIAS |
+						FLD_PWRDN_ENABLE_PLL)) {
+				status = afe_write_byte(dev, SUP_BLK_PWRDN,
+							FLD_PWRDN_TUNING_BIAS |
+							FLD_PWRDN_ENABLE_PLL);
+				status |= afe_read_byte(dev, SUP_BLK_PWRDN,
+							&afe_power_status);
+				if (status < 0)
+					break;
+			}
+
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH1,
+							0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH2,
+							0x00);
+			status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3,
+							0x40);
+		} else {
+			cx231xx_info("Invalid AV mode input\n");
+			status = -1;
+		}
+	}			/* switch  */
+
+	return status;
+}
+
+int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input)
+{
+	u8 input_mode = 0;
+	u8 ntf_mode = 0;
+	int status = 0;
+
+	dev->video_input = video_input;
+
+	if (video_input == CX231XX_VMUX_TELEVISION) {
+		status = afe_read_byte(dev, ADC_INPUT_CH3, &input_mode);
+		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH3,
+					&ntf_mode);
+	} else {
+		status = afe_read_byte(dev, ADC_INPUT_CH1, &input_mode);
+		status = afe_read_byte(dev, ADC_NTF_PRECLMP_EN_CH1,
+					&ntf_mode);
+	}
+
+	input_mode = (ntf_mode & 0x3) | ((input_mode & 0x6) << 1);
+
+	switch (input_mode) {
+	case SINGLE_ENDED:
+		dev->afe_ref_count = 0x23C;
+		break;
+	case LOW_IF:
+		dev->afe_ref_count = 0x24C;
+		break;
+	case EU_IF:
+		dev->afe_ref_count = 0x258;
+		break;
+	case US_IF:
+		dev->afe_ref_count = 0x260;
+		break;
+	default:
+		break;
+	}
+
+	status = cx231xx_afe_init_super_block(dev, dev->afe_ref_count);
+
+	return status;
+}
+
+/******************************************************************************
+ *     V I D E O / A U D I O    D E C O D E R    C O N T R O L   functions    *
+ ******************************************************************************/
+static int vid_blk_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
+{
+	return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+					saddr, 2, data, 1);
+}
+
+static int vid_blk_read_byte(struct cx231xx *dev, u16 saddr, u8 *data)
+{
+	int status;
+	u32 temp = 0;
+
+	status = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+					saddr, 2, &temp, 1);
+	*data = (u8) temp;
+	return status;
+}
+
+static int vid_blk_write_word(struct cx231xx *dev, u16 saddr, u32 data)
+{
+	return cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+					saddr, 2, data, 4);
+}
+
+static int vid_blk_read_word(struct cx231xx *dev, u16 saddr, u32 *data)
+{
+	return cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+					saddr, 2, data, 4);
+}
+
+int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input)
+{
+	int status = 0;
+
+	switch (INPUT(input)->type) {
+	case CX231XX_VMUX_COMPOSITE1:
+	case CX231XX_VMUX_SVIDEO:
+		if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
+		    (dev->power_mode != POLARIS_AVMODE_ENXTERNAL_AV)) {
+			/* External AV */
+			status = cx231xx_set_power_mode(dev,
+					POLARIS_AVMODE_ENXTERNAL_AV);
+			if (status < 0) {
+				cx231xx_errdev("%s: set_power_mode : Failed to"
+						" set Power - errCode [%d]!\n",
+						__func__, status);
+				return status;
+			}
+		}
+		status = cx231xx_set_decoder_video_input(dev,
+							 INPUT(input)->type,
+							 INPUT(input)->vmux);
+		break;
+	case CX231XX_VMUX_TELEVISION:
+	case CX231XX_VMUX_CABLE:
+		if ((dev->current_pcb_config.type == USB_BUS_POWER) &&
+		    (dev->power_mode != POLARIS_AVMODE_ANALOGT_TV)) {
+			/* Tuner */
+			status = cx231xx_set_power_mode(dev,
+						POLARIS_AVMODE_ANALOGT_TV);
+			if (status < 0) {
+				cx231xx_errdev("%s: set_power_mode:Failed"
+					" to set Power - errCode [%d]!\n",
+					__func__, status);
+				return status;
+			}
+		}
+		status = cx231xx_set_decoder_video_input(dev,
+							CX231XX_VMUX_COMPOSITE1,
+							INPUT(input)->vmux);
+		break;
+	default:
+		cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n",
+		     __func__, INPUT(input)->type);
+		break;
+	}
+
+	/* save the selection */
+	dev->video_input = input;
+
+	return status;
+}
+
+int cx231xx_set_decoder_video_input(struct cx231xx *dev,
+				u8 pin_type, u8 input)
+{
+	int status = 0;
+	u32 value = 0;
+
+	if (pin_type != dev->video_input) {
+		status = cx231xx_afe_adjust_ref_count(dev, pin_type);
+		if (status < 0) {
+			cx231xx_errdev("%s: adjust_ref_count :Failed to set"
+				"AFE input mux - errCode [%d]!\n",
+				__func__, status);
+			return status;
+		}
+	}
+
+	/* call afe block to set video inputs */
+	status = cx231xx_afe_set_input_mux(dev, input);
+	if (status < 0) {
+		cx231xx_errdev("%s: set_input_mux :Failed to set"
+				" AFE input mux - errCode [%d]!\n",
+				__func__, status);
+		return status;
+	}
+
+	switch (pin_type) {
+	case CX231XX_VMUX_COMPOSITE1:
+		status = vid_blk_read_word(dev, AFE_CTRL, &value);
+		value |= (0 << 13) | (1 << 4);
+		value &= ~(1 << 5);
+
+		/* set [24:23] [22:15] to 0  */
+		value &= (~(0x1ff8000));
+		/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0  */
+		value |= 0x1000000;
+		status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+		status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+		value |= (1 << 7);
+		status = vid_blk_write_word(dev, OUT_CTRL1, value);
+
+		/* Set vip 1.1 output mode */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							OUT_CTRL1,
+							FLD_OUT_MODE,
+							OUT_MODE_VIP11);
+
+		/* Tell DIF object to go to baseband mode  */
+		status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+		if (status < 0) {
+			cx231xx_errdev("%s: cx231xx_dif set to By pass"
+						   " mode- errCode [%d]!\n",
+				__func__, status);
+			return status;
+		}
+
+		/* Read the DFE_CTRL1 register */
+		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+		/* enable the VBI_GATE_EN */
+		value |= FLD_VBI_GATE_EN;
+
+		/* Enable the auto-VGA enable */
+		value |= FLD_VGA_AUTO_EN;
+
+		/* Write it back */
+		status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+		/* Disable auto config of registers */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+					VID_BLK_I2C_ADDRESS,
+					MODE_CTRL, FLD_ACFG_DIS,
+					cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+		/* Set CVBS input mode */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+			VID_BLK_I2C_ADDRESS,
+			MODE_CTRL, FLD_INPUT_MODE,
+			cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_CVBS_0));
+		break;
+	case CX231XX_VMUX_SVIDEO:
+		/* Disable the use of  DIF */
+
+		status = vid_blk_read_word(dev, AFE_CTRL, &value);
+
+		/* set [24:23] [22:15] to 0 */
+		value &= (~(0x1ff8000));
+		/* set FUNC_MODE[24:23] = 2
+		IF_MOD[22:15] = 0 DCR_BYP_CH2[4:4] = 1; */
+		value |= 0x1000010;
+		status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+		/* Tell DIF object to go to baseband mode */
+		status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+		if (status < 0) {
+			cx231xx_errdev("%s: cx231xx_dif set to By pass"
+						   " mode- errCode [%d]!\n",
+				__func__, status);
+			return status;
+		}
+
+		/* Read the DFE_CTRL1 register */
+		status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+		/* enable the VBI_GATE_EN */
+		value |= FLD_VBI_GATE_EN;
+
+		/* Enable the auto-VGA enable */
+		value |= FLD_VGA_AUTO_EN;
+
+		/* Write it back */
+		status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+		/* Disable auto config of registers  */
+		status =  cx231xx_read_modify_write_i2c_dword(dev,
+					VID_BLK_I2C_ADDRESS,
+					MODE_CTRL, FLD_ACFG_DIS,
+					cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+		/* Set YC input mode */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+			VID_BLK_I2C_ADDRESS,
+			MODE_CTRL,
+			FLD_INPUT_MODE,
+			cx231xx_set_field(FLD_INPUT_MODE, INPUT_MODE_YC_1));
+
+		/* Chroma to ADC2 */
+		status = vid_blk_read_word(dev, AFE_CTRL, &value);
+		value |= FLD_CHROMA_IN_SEL;	/* set the chroma in select */
+
+		/* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8)
+		   This sets them to use video
+		   rather than audio.  Only one of the two will be in use. */
+		value &= ~(FLD_VGA_SEL_CH2 | FLD_VGA_SEL_CH3);
+
+		status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+		status = cx231xx_afe_set_mode(dev, AFE_MODE_BASEBAND);
+		break;
+	case CX231XX_VMUX_TELEVISION:
+	case CX231XX_VMUX_CABLE:
+	default:
+		switch (dev->model) {
+		case CX231XX_BOARD_CNXT_RDE_250:
+		case CX231XX_BOARD_CNXT_RDU_250:
+			/* Disable the use of  DIF   */
+
+			status = vid_blk_read_word(dev, AFE_CTRL, &value);
+			value |= (0 << 13) | (1 << 4);
+			value &= ~(1 << 5);
+
+			/* set [24:23] [22:15] to 0 */
+			value &= (~(0x1FF8000));
+			/* set FUNC_MODE[24:23] = 2 IF_MOD[22:15] = 0 */
+			value |= 0x1000000;
+			status = vid_blk_write_word(dev, AFE_CTRL, value);
+
+			status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+			value |= (1 << 7);
+			status = vid_blk_write_word(dev, OUT_CTRL1, value);
+
+			/* Set vip 1.1 output mode */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							OUT_CTRL1, FLD_OUT_MODE,
+							OUT_MODE_VIP11);
+
+			/* Tell DIF object to go to baseband mode */
+			status = cx231xx_dif_set_standard(dev,
+							  DIF_USE_BASEBAND);
+			if (status < 0) {
+				cx231xx_errdev("%s: cx231xx_dif set to By pass"
+						" mode- errCode [%d]!\n",
+						__func__, status);
+				return status;
+			}
+
+			/* Read the DFE_CTRL1 register */
+			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+			/* enable the VBI_GATE_EN */
+			value |= FLD_VBI_GATE_EN;
+
+			/* Enable the auto-VGA enable */
+			value |= FLD_VGA_AUTO_EN;
+
+			/* Write it back */
+			status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+			/* Disable auto config of registers */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+					VID_BLK_I2C_ADDRESS,
+					MODE_CTRL, FLD_ACFG_DIS,
+					cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+			/* Set CVBS input mode */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+				VID_BLK_I2C_ADDRESS,
+				MODE_CTRL, FLD_INPUT_MODE,
+				cx231xx_set_field(FLD_INPUT_MODE,
+						INPUT_MODE_CVBS_0));
+			break;
+		default:
+			/* Enable the DIF for the tuner */
+
+			/* Reinitialize the DIF */
+			status = cx231xx_dif_set_standard(dev, dev->norm);
+			if (status < 0) {
+				cx231xx_errdev("%s: cx231xx_dif set to By pass"
+						" mode- errCode [%d]!\n",
+						__func__, status);
+				return status;
+			}
+
+			/* Make sure bypass is cleared */
+			status = vid_blk_read_word(dev, DIF_MISC_CTRL, &value);
+
+			/* Clear the bypass bit */
+			value &= ~FLD_DIF_DIF_BYPASS;
+
+			/* Enable the use of the DIF block */
+			status = vid_blk_write_word(dev, DIF_MISC_CTRL, value);
+
+			/* Read the DFE_CTRL1 register */
+			status = vid_blk_read_word(dev, DFE_CTRL1, &value);
+
+			/* Disable the VBI_GATE_EN */
+			value &= ~FLD_VBI_GATE_EN;
+
+			/* Enable the auto-VGA enable, AGC, and
+			   set the skip count to 2 */
+			value |= FLD_VGA_AUTO_EN | FLD_AGC_AUTO_EN | 0x00200000;
+
+			/* Write it back */
+			status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+			/* Wait until AGC locks up */
+			msleep(1);
+
+			/* Disable the auto-VGA enable AGC */
+			value &= ~(FLD_VGA_AUTO_EN);
+
+			/* Write it back */
+			status = vid_blk_write_word(dev, DFE_CTRL1, value);
+
+			/* Enable Polaris B0 AGC output */
+			status = vid_blk_read_word(dev, PIN_CTRL, &value);
+			value |= (FLD_OEF_AGC_RF) |
+				 (FLD_OEF_AGC_IFVGA) |
+				 (FLD_OEF_AGC_IF);
+			status = vid_blk_write_word(dev, PIN_CTRL, value);
+
+			/* Set vip 1.1 output mode */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+						VID_BLK_I2C_ADDRESS,
+						OUT_CTRL1, FLD_OUT_MODE,
+						OUT_MODE_VIP11);
+
+			/* Disable auto config of registers */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+					VID_BLK_I2C_ADDRESS,
+					MODE_CTRL, FLD_ACFG_DIS,
+					cx231xx_set_field(FLD_ACFG_DIS, 1));
+
+			/* Set CVBS input mode */
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+				VID_BLK_I2C_ADDRESS,
+				MODE_CTRL, FLD_INPUT_MODE,
+				cx231xx_set_field(FLD_INPUT_MODE,
+						INPUT_MODE_CVBS_0));
+
+			/* Set some bits in AFE_CTRL so that channel 2 or 3
+			 * is ready to receive audio */
+			/* Clear clamp for channels 2 and 3      (bit 16-17) */
+			/* Clear droop comp                      (bit 19-20) */
+			/* Set VGA_SEL (for audio control)       (bit 7-8) */
+			status = vid_blk_read_word(dev, AFE_CTRL, &value);
+
+			value |= FLD_VGA_SEL_CH3 | FLD_VGA_SEL_CH2;
+
+			status = vid_blk_write_word(dev, AFE_CTRL, value);
+			break;
+
+		}
+		break;
+	}
+
+	/* Set raw VBI mode */
+	status = cx231xx_read_modify_write_i2c_dword(dev,
+				VID_BLK_I2C_ADDRESS,
+				OUT_CTRL1, FLD_VBIHACTRAW_EN,
+				cx231xx_set_field(FLD_VBIHACTRAW_EN, 1));
+
+	status = vid_blk_read_word(dev, OUT_CTRL1, &value);
+	if (value & 0x02) {
+		value |= (1 << 19);
+		status = vid_blk_write_word(dev, OUT_CTRL1, value);
+	}
+
+	return status;
+}
+
+/*
+ * Handle any video-mode specific overrides that are different
+ * on a per video standards basis after touching the MODE_CTRL
+ * register which resets many values for autodetect
+ */
+int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
+{
+	int status = 0;
+
+	cx231xx_info("do_mode_ctrl_overrides : 0x%x\n",
+		     (unsigned int)dev->norm);
+
+	/* Change the DFE_CTRL3 bp_percent to fix flagging */
+	status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280);
+
+	if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
+		cx231xx_info("do_mode_ctrl_overrides NTSC\n");
+
+		/* Move the close caption lines out of active video,
+		   adjust the active video start point */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							VERT_TIM_CTRL,
+							FLD_VBLANK_CNT, 0x18);
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							VERT_TIM_CTRL,
+							FLD_VACTIVE_CNT,
+							0x1E6000);
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							VERT_TIM_CTRL,
+							FLD_V656BLANK_CNT,
+							0x1E000000);
+
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							HORIZ_TIM_CTRL,
+							FLD_HBLANK_CNT,
+							cx231xx_set_field
+							(FLD_HBLANK_CNT, 0x79));
+	} else if (dev->norm & V4L2_STD_SECAM) {
+		cx231xx_info("do_mode_ctrl_overrides SECAM\n");
+		status =  cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							VERT_TIM_CTRL,
+							FLD_VBLANK_CNT, 0x24);
+		/* Adjust the active video horizontal start point */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							HORIZ_TIM_CTRL,
+							FLD_HBLANK_CNT,
+							cx231xx_set_field
+							(FLD_HBLANK_CNT, 0x85));
+	} else {
+		cx231xx_info("do_mode_ctrl_overrides PAL\n");
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							VERT_TIM_CTRL,
+							FLD_VBLANK_CNT, 0x24);
+		/* Adjust the active video horizontal start point */
+		status = cx231xx_read_modify_write_i2c_dword(dev,
+							VID_BLK_I2C_ADDRESS,
+							HORIZ_TIM_CTRL,
+							FLD_HBLANK_CNT,
+							cx231xx_set_field
+							(FLD_HBLANK_CNT, 0x85));
+	}
+
+	return status;
+}
+
+int cx231xx_set_audio_input(struct cx231xx *dev, u8 input)
+{
+	int status = 0;
+	enum AUDIO_INPUT ainput = AUDIO_INPUT_LINE;
+
+	switch (INPUT(input)->amux) {
+	case CX231XX_AMUX_VIDEO:
+		ainput = AUDIO_INPUT_TUNER_TV;
+		break;
+	case CX231XX_AMUX_LINE_IN:
+		status = cx231xx_i2s_blk_set_audio_input(dev, input);
+		ainput = AUDIO_INPUT_LINE;
+		break;
+	default:
+		break;
+	}
+
+	status = cx231xx_set_audio_decoder_input(dev, ainput);
+
+	return status;
+}
+
+int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
+				    enum AUDIO_INPUT audio_input)
+{
+	u32 dwval;
+	int status;
+	u8 gen_ctrl;
+	u32 value = 0;
+
+	/* Put it in soft reset   */
+	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
+	gen_ctrl |= 1;
+	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
+
+	switch (audio_input) {
+	case AUDIO_INPUT_LINE:
+		/* setup AUD_IO control from Merlin paralle output */
+		value = cx231xx_set_field(FLD_AUD_CHAN1_SRC,
+					  AUD_CHAN_SRC_PARALLEL);
+		status = vid_blk_write_word(dev, AUD_IO_CTRL, value);
+
+		/* setup input to Merlin, SRC2 connect to AC97
+		   bypass upsample-by-2, slave mode, sony mode, left justify
+		   adr 091c, dat 01000000 */
+		status = vid_blk_read_word(dev, AC97_CTL, &dwval);
+
+		status = vid_blk_write_word(dev, AC97_CTL,
+					   (dwval | FLD_AC97_UP2X_BYPASS));
+
+		/* select the parallel1 and SRC3 */
+		status = vid_blk_write_word(dev, BAND_OUT_SEL,
+				cx231xx_set_field(FLD_SRC3_IN_SEL, 0x0) |
+				cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x0) |
+				cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x0));
+
+		/* unmute all, AC97 in, independence mode
+		   adr 08d0, data 0x00063073 */
+		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063073);
+
+		/* set AVC maximum threshold, adr 08d4, dat ffff0024 */
+		status = vid_blk_read_word(dev, PATH1_VOL_CTL, &dwval);
+		status = vid_blk_write_word(dev, PATH1_VOL_CTL,
+					   (dwval | FLD_PATH1_AVC_THRESHOLD));
+
+		/* set SC maximum threshold, adr 08ec, dat ffffb3a3 */
+		status = vid_blk_read_word(dev, PATH1_SC_CTL, &dwval);
+		status = vid_blk_write_word(dev, PATH1_SC_CTL,
+					   (dwval | FLD_PATH1_SC_THRESHOLD));
+		break;
+
+	case AUDIO_INPUT_TUNER_TV:
+	default:
+
+		/* Setup SRC sources and clocks */
+		status = vid_blk_write_word(dev, BAND_OUT_SEL,
+			cx231xx_set_field(FLD_SRC6_IN_SEL, 0x00)         |
+			cx231xx_set_field(FLD_SRC6_CLK_SEL, 0x01)        |
+			cx231xx_set_field(FLD_SRC5_IN_SEL, 0x00)         |
+			cx231xx_set_field(FLD_SRC5_CLK_SEL, 0x02)        |
+			cx231xx_set_field(FLD_SRC4_IN_SEL, 0x02)         |
+			cx231xx_set_field(FLD_SRC4_CLK_SEL, 0x03)        |
+			cx231xx_set_field(FLD_SRC3_IN_SEL, 0x00)         |
+			cx231xx_set_field(FLD_SRC3_CLK_SEL, 0x00)        |
+			cx231xx_set_field(FLD_BASEBAND_BYPASS_CTL, 0x00) |
+			cx231xx_set_field(FLD_AC97_SRC_SEL, 0x03)        |
+			cx231xx_set_field(FLD_I2S_SRC_SEL, 0x00)         |
+			cx231xx_set_field(FLD_PARALLEL2_SRC_SEL, 0x02)   |
+			cx231xx_set_field(FLD_PARALLEL1_SRC_SEL, 0x01));
+
+		/* Setup the AUD_IO control */
+		status = vid_blk_write_word(dev, AUD_IO_CTRL,
+			cx231xx_set_field(FLD_I2S_PORT_DIR, 0x00)  |
+			cx231xx_set_field(FLD_I2S_OUT_SRC, 0x00)   |
+			cx231xx_set_field(FLD_AUD_CHAN3_SRC, 0x00) |
+			cx231xx_set_field(FLD_AUD_CHAN2_SRC, 0x00) |
+			cx231xx_set_field(FLD_AUD_CHAN1_SRC, 0x03));
+
+		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F063870);
+
+		/* setAudioStandard(_audio_standard); */
+
+		status = vid_blk_write_word(dev, PATH1_CTL1, 0x00063870);
+		switch (dev->model) {
+		case CX231XX_BOARD_CNXT_RDE_250:
+		case CX231XX_BOARD_CNXT_RDU_250:
+			status = cx231xx_read_modify_write_i2c_dword(dev,
+					VID_BLK_I2C_ADDRESS,
+					CHIP_CTRL,
+					FLD_SIF_EN,
+					cx231xx_set_field(FLD_SIF_EN, 1));
+			break;
+		default:
+			break;
+		}
+		break;
+
+	case AUDIO_INPUT_TUNER_FM:
+		/*  use SIF for FM radio
+		   setupFM();
+		   setAudioStandard(_audio_standard);
+		 */
+		break;
+
+	case AUDIO_INPUT_MUTE:
+		status = vid_blk_write_word(dev, PATH1_CTL1, 0x1F011012);
+		break;
+	}
+
+	/* Take it out of soft reset */
+	status = vid_blk_read_byte(dev, GENERAL_CTL, &gen_ctrl);
+	gen_ctrl &= ~1;
+	status = vid_blk_write_byte(dev, GENERAL_CTL, gen_ctrl);
+
+	return status;
+}
+
+/* Set resolution of the video */
+int cx231xx_resolution_set(struct cx231xx *dev)
+{
+	int width, height;
+	u32 hscale, vscale;
+	int status = 0;
+
+	width = dev->width;
+	height = dev->height;
+
+	get_scale(dev, width, height, &hscale, &vscale);
+
+	/* set horzontal scale */
+	status = vid_blk_write_word(dev, HSCALE_CTRL, hscale);
+
+	/* set vertical scale */
+	status = vid_blk_write_word(dev, VSCALE_CTRL, vscale);
+
+	return status;
+}
+
+/******************************************************************************
+ *                    C H I P Specific  C O N T R O L   functions             *
+ ******************************************************************************/
+int cx231xx_init_ctrl_pin_status(struct cx231xx *dev)
+{
+	u32 value;
+	int status = 0;
+
+	status = vid_blk_read_word(dev, PIN_CTRL, &value);
+	value |= (~dev->board.ctl_pin_status_mask);
+	status = vid_blk_write_word(dev, PIN_CTRL, value);
+
+	return status;
+}
+
+int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
+					      u8 analog_or_digital)
+{
+	int status = 0;
+
+	/* first set the direction to output */
+	status = cx231xx_set_gpio_direction(dev,
+					    dev->board.
+					    agc_analog_digital_select_gpio, 1);
+
+	/* 0 - demod ; 1 - Analog mode */
+	status = cx231xx_set_gpio_value(dev,
+				   dev->board.agc_analog_digital_select_gpio,
+				   analog_or_digital);
+
+	return status;
+}
+
+int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex)
+{
+	u8 value[4] = { 0, 0, 0, 0 };
+	int status = 0;
+
+	cx231xx_info("Changing the i2c port for tuner to %d\n", I2CIndex);
+
+	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+				       PWR_CTL_EN, value, 4);
+	if (status < 0)
+		return status;
+
+	if (I2CIndex == I2C_1) {
+		if (value[0] & I2C_DEMOD_EN) {
+			value[0] &= ~I2C_DEMOD_EN;
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						   PWR_CTL_EN, value, 4);
+		}
+	} else {
+		if (!(value[0] & I2C_DEMOD_EN)) {
+			value[0] |= I2C_DEMOD_EN;
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						   PWR_CTL_EN, value, 4);
+		}
+	}
+
+	return status;
+
+}
+
+/******************************************************************************
+ *                 D I F - B L O C K    C O N T R O L   functions             *
+ ******************************************************************************/
+int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
+					  u32 function_mode, u32 standard)
+{
+	int status = 0;
+
+	if (mode == V4L2_TUNER_RADIO) {
+		/* C2HH */
+		/* lo if big signal */
+		status = cx231xx_reg_mask_write(dev,
+				VID_BLK_I2C_ADDRESS, 32,
+				AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+		/* FUNC_MODE = DIF */
+		status = cx231xx_reg_mask_write(dev,
+				VID_BLK_I2C_ADDRESS, 32,
+				AFE_CTRL_C2HH_SRC_CTRL, 23, 24, function_mode);
+		/* IF_MODE */
+		status = cx231xx_reg_mask_write(dev,
+				VID_BLK_I2C_ADDRESS, 32,
+				AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xFF);
+		/* no inv */
+		status = cx231xx_reg_mask_write(dev,
+				VID_BLK_I2C_ADDRESS, 32,
+				AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+	} else if (standard != DIF_USE_BASEBAND) {
+		if (standard & V4L2_STD_MN) {
+			/* lo if big signal */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+			/* FUNC_MODE = DIF */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+					function_mode);
+			/* IF_MODE */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xb);
+			/* no inv */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+			/* 0x124, AUD_CHAN1_SRC = 0x3 */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AUD_IO_CTRL, 0, 31, 0x00000003);
+		} else if ((standard == V4L2_STD_PAL_I) |
+			(standard & V4L2_STD_SECAM)) {
+			/* C2HH setup */
+			/* lo if big signal */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+			/* FUNC_MODE = DIF */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+					function_mode);
+			/* IF_MODE */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xF);
+			/* no inv */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+		} else {
+			/* default PAL BG */
+			/* C2HH setup */
+			/* lo if big signal */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 30, 31, 0x1);
+			/* FUNC_MODE = DIF */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 23, 24,
+					function_mode);
+			/* IF_MODE */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 15, 22, 0xE);
+			/* no inv */
+			status = cx231xx_reg_mask_write(dev,
+					VID_BLK_I2C_ADDRESS, 32,
+					AFE_CTRL_C2HH_SRC_CTRL, 9, 9, 0x1);
+		}
+	}
+
+	return status;
+}
+
+int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard)
+{
+	int status = 0;
+	u32 dif_misc_ctrl_value = 0;
+	u32 func_mode = 0;
+
+	cx231xx_info("%s: setStandard to %x\n", __func__, standard);
+
+	status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value);
+	if (standard != DIF_USE_BASEBAND)
+		dev->norm = standard;
+
+	switch (dev->model) {
+	case CX231XX_BOARD_CNXT_RDE_250:
+	case CX231XX_BOARD_CNXT_RDU_250:
+		func_mode = 0x03;
+		break;
+	default:
+		func_mode = 0x01;
+	}
+
+	status = cx231xx_dif_configure_C2HH_for_low_IF(dev, dev->active_mode,
+						  func_mode, standard);
+
+	if (standard == DIF_USE_BASEBAND) {	/* base band */
+		/* There is a different SRC_PHASE_INC value
+		   for baseband vs. DIF */
+		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC, 0xDF7DF83);
+		status = vid_blk_read_word(dev, DIF_MISC_CTRL,
+						&dif_misc_ctrl_value);
+		dif_misc_ctrl_value |= FLD_DIF_DIF_BYPASS;
+		status = vid_blk_write_word(dev, DIF_MISC_CTRL,
+						dif_misc_ctrl_value);
+	} else if (standard & V4L2_STD_PAL_D) {
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_INT_CURRENT, 0, 31,
+					   0x26001700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_RF_CURRENT, 0, 31,
+					   0x00002660);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VIDEO_AGC_CTRL, 0, 31,
+					   0x72500800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VID_AUD_OVERRIDE, 0, 31,
+					   0x27000100);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3934EA);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_COMP_FLT_CTRL, 0, 31,
+					   0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_PHASE_INC, 0, 31,
+					   0x1befbf06);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_GAIN_CONTROL, 0, 31,
+					   0x000035e8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a023F11;
+	} else if (standard & V4L2_STD_PAL_I) {
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_INT_CURRENT, 0, 31,
+					   0x26001700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_RF_CURRENT, 0, 31,
+					   0x00002660);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VIDEO_AGC_CTRL, 0, 31,
+					   0x72500800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VID_AUD_OVERRIDE, 0, 31,
+					   0x27000100);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AV_SEP_CTRL, 0, 31, 0x5F39A934);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_COMP_FLT_CTRL, 0, 31,
+					   0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_PHASE_INC, 0, 31,
+					   0x1befbf06);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_GAIN_CONTROL, 0, 31,
+					   0x000035e8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a033F11;
+	} else if (standard & V4L2_STD_PAL_M) {
+		/* improved Low Frequency Phase Noise */
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+						0x26001700);
+		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+						0x00002660);
+		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+						0x72500800);
+		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+						0x27000100);
+		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x012c405d);
+		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+						0x009f50c1);
+		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+						0x1befbf06);
+		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+						0x000035e8);
+		status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
+						0x00000000);
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3A0A3F10;
+	} else if (standard & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
+		/* improved Low Frequency Phase Noise */
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0xFF01FF0C);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xbd038c85);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1db4640a);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C1380);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+						0x26001700);
+		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+						0x00002660);
+		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+						0x72500800);
+		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+						0x27000100);
+		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL,
+						0x012c405d);
+		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+						0x009f50c1);
+		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+						0x1befbf06);
+		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+						0x000035e8);
+		status = vid_blk_write_word(dev, DIF_SOFT_RST_CTRL_REVB,
+						0x00000000);
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value = 0x3A093F10;
+	} else if (standard &
+		  (V4L2_STD_SECAM_B | V4L2_STD_SECAM_D | V4L2_STD_SECAM_G |
+		   V4L2_STD_SECAM_K | V4L2_STD_SECAM_K1)) {
+
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_INT_CURRENT, 0, 31,
+					   0x26001700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_RF_CURRENT, 0, 31,
+					   0x00002660);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VID_AUD_OVERRIDE, 0, 31,
+					   0x27000100);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_COMP_FLT_CTRL, 0, 31,
+					   0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_PHASE_INC, 0, 31,
+					   0x1befbf06);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_GAIN_CONTROL, 0, 31,
+					   0x000035e8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VIDEO_AGC_CTRL, 0, 31,
+					   0xf4000000);
+
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a023F11;
+	} else if (standard & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) {
+		/* Is it SECAM_L1? */
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_REF, 0, 31, 0x888C0380);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_IF, 0, 31, 0xe0262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_INT, 0, 31, 0xc2171700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_RF, 0, 31, 0xc2262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_INT_CURRENT, 0, 31,
+					   0x26001700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_RF_CURRENT, 0, 31,
+					   0x00002660);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VID_AUD_OVERRIDE, 0, 31,
+					   0x27000100);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530ec);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_COMP_FLT_CTRL, 0, 31,
+					   0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_PHASE_INC, 0, 31,
+					   0x1befbf06);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_GAIN_CONTROL, 0, 31,
+					   0x000035e8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VIDEO_AGC_CTRL, 0, 31,
+					   0xf2560000);
+
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a023F11;
+
+	} else if (standard & V4L2_STD_NTSC_M) {
+		/* V4L2_STD_NTSC_M (75 IRE Setup) Or
+		   V4L2_STD_NTSC_M_JP (Japan,  0 IRE Setup) */
+
+		/* For NTSC the centre frequency of video coming out of
+		   sidewinder is around 7.1MHz or 3.6MHz depending on the
+		   spectral inversion. so for a non spectrally inverted channel
+		   the pll freq word is 0x03420c49
+		 */
+
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL, 0x6503BC0C);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL1, 0xBD038C85);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL2, 0x1DB4640A);
+		status = vid_blk_write_word(dev, DIF_PLL_CTRL3, 0x00008800);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_REF, 0x444C0380);
+		status = vid_blk_write_word(dev, DIF_AGC_IF_INT_CURRENT,
+						0x26001700);
+		status = vid_blk_write_word(dev, DIF_AGC_RF_CURRENT,
+						0x00002660);
+		status = vid_blk_write_word(dev, DIF_VIDEO_AGC_CTRL,
+						0x04000800);
+		status = vid_blk_write_word(dev, DIF_VID_AUD_OVERRIDE,
+						0x27000100);
+		status = vid_blk_write_word(dev, DIF_AV_SEP_CTRL, 0x01296e1f);
+
+		status = vid_blk_write_word(dev, DIF_COMP_FLT_CTRL,
+						0x009f50c1);
+		status = vid_blk_write_word(dev, DIF_SRC_PHASE_INC,
+						0x1befbf06);
+		status = vid_blk_write_word(dev, DIF_SRC_GAIN_CONTROL,
+						0x000035e8);
+
+		status = vid_blk_write_word(dev, DIF_AGC_CTRL_IF, 0xC2262600);
+		status = vid_blk_write_word(dev, DIF_AGC_CTRL_INT,
+						0xC2262600);
+		status = vid_blk_write_word(dev, DIF_AGC_CTRL_RF, 0xC2262600);
+
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a003F10;
+	} else {
+		/* default PAL BG */
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL, 0, 31, 0x6503bc0c);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL1, 0, 31, 0xbd038c85);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL2, 0, 31, 0x1db4640a);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_PLL_CTRL3, 0, 31, 0x00008800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_REF, 0, 31, 0x444C1380);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_IF, 0, 31, 0xDA302600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_INT, 0, 31, 0xDA261700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_CTRL_RF, 0, 31, 0xDA262600);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_IF_INT_CURRENT, 0, 31,
+					   0x26001700);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AGC_RF_CURRENT, 0, 31,
+					   0x00002660);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VIDEO_AGC_CTRL, 0, 31,
+					   0x72500800);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_VID_AUD_OVERRIDE, 0, 31,
+					   0x27000100);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_AV_SEP_CTRL, 0, 31, 0x3F3530EC);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_COMP_FLT_CTRL, 0, 31,
+					   0x00A653A8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_PHASE_INC, 0, 31,
+					   0x1befbf06);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_SRC_GAIN_CONTROL, 0, 31,
+					   0x000035e8);
+		status = cx231xx_reg_mask_write(dev, VID_BLK_I2C_ADDRESS, 32,
+					   DIF_RPT_VARIANCE, 0, 31, 0x00000000);
+		/* Save the Spec Inversion value */
+		dif_misc_ctrl_value &= FLD_DIF_SPEC_INV;
+		dif_misc_ctrl_value |= 0x3a013F11;
+	}
+
+	/* The AGC values should be the same for all standards,
+	   AUD_SRC_SEL[19] should always be disabled    */
+	dif_misc_ctrl_value &= ~FLD_DIF_AUD_SRC_SEL;
+
+	/* It is still possible to get Set Standard calls even when we
+	   are in FM mode.
+	   This is done to override the value for FM. */
+	if (dev->active_mode == V4L2_TUNER_RADIO)
+		dif_misc_ctrl_value = 0x7a080000;
+
+	/* Write the calculated value for misc ontrol register      */
+	status = vid_blk_write_word(dev, DIF_MISC_CTRL, dif_misc_ctrl_value);
+
+	return status;
+}
+
+int cx231xx_tuner_pre_channel_change(struct cx231xx *dev)
+{
+	int status = 0;
+	u32 dwval;
+
+	/* Set the RF and IF k_agc values to 3 */
+	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
+	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
+	dwval |= 0x33000000;
+
+	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
+
+	return status;
+}
+
+int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
+{
+	int status = 0;
+	u32 dwval;
+
+	/* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for
+	 * SECAM L/B/D standards */
+	status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval);
+	dwval &= ~(FLD_DIF_K_AGC_RF | FLD_DIF_K_AGC_IF);
+
+	if (dev->norm & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_B |
+			 V4L2_STD_SECAM_D))
+		dwval |= 0x88000000;
+	else
+		dwval |= 0x44000000;
+
+	status = vid_blk_write_word(dev, DIF_AGC_IF_REF, dwval);
+
+	return status;
+}
+
+/******************************************************************************
+ *        	    I 2 S - B L O C K    C O N T R O L   functions            *
+ ******************************************************************************/
+int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
+{
+	int status = 0;
+	u32 value;
+
+	status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				       CH_PWR_CTRL1, 1, &value, 1);
+	/* enables clock to delta-sigma and decimation filter */
+	value |= 0x80;
+	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+					CH_PWR_CTRL1, 1, value, 1);
+	/* power up all channel */
+	status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+					CH_PWR_CTRL2, 1, 0x00, 1);
+
+	return status;
+}
+
+int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
+					enum AV_MODE avmode)
+{
+	int status = 0;
+	u32 value = 0;
+
+	if (avmode != POLARIS_AVMODE_ENXTERNAL_AV) {
+		status = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+					  CH_PWR_CTRL2, 1, &value, 1);
+		value |= 0xfe;
+		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+						CH_PWR_CTRL2, 1, value, 1);
+	} else {
+		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+						CH_PWR_CTRL2, 1, 0x00, 1);
+	}
+
+	return status;
+}
+
+/* set i2s_blk for audio input types */
+int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input)
+{
+	int status = 0;
+
+	switch (audio_input) {
+	case CX231XX_AMUX_LINE_IN:
+		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+						CH_PWR_CTRL2, 1, 0x00, 1);
+		status = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+						CH_PWR_CTRL1, 1, 0x80, 1);
+		break;
+	case CX231XX_AMUX_VIDEO:
+	default:
+		break;
+	}
+
+	dev->ctl_ainput = audio_input;
+
+	return status;
+}
+
+/******************************************************************************
+ *                  P O W E R      C O N T R O L   functions                  *
+ ******************************************************************************/
+int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode)
+{
+	u8 value[4] = { 0, 0, 0, 0 };
+	u32 tmp = 0;
+	int status = 0;
+
+	if (dev->power_mode != mode)
+		dev->power_mode = mode;
+	else {
+		cx231xx_info(" setPowerMode::mode = %d, No Change req.\n",
+			     mode);
+		return 0;
+	}
+
+	cx231xx_info(" setPowerMode::mode = %d\n", mode);
+
+	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
+				       4);
+	if (status < 0)
+		return status;
+
+	tmp = *((u32 *) value);
+
+	switch (mode) {
+	case POLARIS_AVMODE_ENXTERNAL_AV:
+
+		tmp &= (~PWR_MODE_MASK);
+
+		tmp |= PWR_AV_EN;
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						PWR_CTL_EN, value, 4);
+		msleep(PWR_SLEEP_INTERVAL);
+
+		tmp |= PWR_ISO_EN;
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status =
+		    cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
+					   value, 4);
+		msleep(PWR_SLEEP_INTERVAL);
+
+		tmp |= POLARIS_AVMODE_ENXTERNAL_AV;
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						PWR_CTL_EN, value, 4);
+
+		/* reset state of xceive tuner */
+		dev->xc_fw_load_done = 0;
+		break;
+
+	case POLARIS_AVMODE_ANALOGT_TV:
+
+		tmp &= (~PWR_DEMOD_EN);
+		tmp |= (I2C_DEMOD_EN);
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						PWR_CTL_EN, value, 4);
+		msleep(PWR_SLEEP_INTERVAL);
+
+		if (!(tmp & PWR_TUNER_EN)) {
+			tmp |= (PWR_TUNER_EN);
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+
+		if (!(tmp & PWR_AV_EN)) {
+			tmp |= PWR_AV_EN;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+		if (!(tmp & PWR_ISO_EN)) {
+			tmp |= PWR_ISO_EN;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+
+		if (!(tmp & POLARIS_AVMODE_ANALOGT_TV)) {
+			tmp |= POLARIS_AVMODE_ANALOGT_TV;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+
+		if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
+		    (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
+			/* tuner path to channel 1 from port 3 */
+			cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+			if (dev->cx231xx_reset_analog_tuner)
+				dev->cx231xx_reset_analog_tuner(dev);
+		}
+		break;
+
+	case POLARIS_AVMODE_DIGITAL:
+		if (!(tmp & PWR_TUNER_EN)) {
+			tmp |= (PWR_TUNER_EN);
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+		if (!(tmp & PWR_AV_EN)) {
+			tmp |= PWR_AV_EN;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+		if (!(tmp & PWR_ISO_EN)) {
+			tmp |= PWR_ISO_EN;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+
+		tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN;
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						PWR_CTL_EN, value, 4);
+		msleep(PWR_SLEEP_INTERVAL);
+
+		if (!(tmp & PWR_DEMOD_EN)) {
+			tmp |= PWR_DEMOD_EN;
+			value[0] = (u8) tmp;
+			value[1] = (u8) (tmp >> 8);
+			value[2] = (u8) (tmp >> 16);
+			value[3] = (u8) (tmp >> 24);
+			status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+							PWR_CTL_EN, value, 4);
+			msleep(PWR_SLEEP_INTERVAL);
+		}
+
+		if ((dev->model == CX231XX_BOARD_CNXT_RDE_250) ||
+		    (dev->model == CX231XX_BOARD_CNXT_RDU_250)) {
+			/* tuner path to channel 1 from port 3 */
+			cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+			if (dev->cx231xx_reset_analog_tuner)
+				dev->cx231xx_reset_analog_tuner(dev);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	msleep(PWR_SLEEP_INTERVAL);
+
+	/* For power saving, only enable Pwr_resetout_n
+	   when digital TV is selected. */
+	if (mode == POLARIS_AVMODE_DIGITAL) {
+		tmp |= PWR_RESETOUT_EN;
+		value[0] = (u8) tmp;
+		value[1] = (u8) (tmp >> 8);
+		value[2] = (u8) (tmp >> 16);
+		value[3] = (u8) (tmp >> 24);
+		status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+						PWR_CTL_EN, value, 4);
+		msleep(PWR_SLEEP_INTERVAL);
+	}
+
+	/* update power control for afe */
+	status = cx231xx_afe_update_power_control(dev, mode);
+
+	/* update power control for i2s_blk */
+	status = cx231xx_i2s_blk_update_power_control(dev, mode);
+
+	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value,
+				       4);
+	cx231xx_info(" The data of PWR_CTL_EN register 0x74"
+				 "=0x%0x,0x%0x,0x%0x,0x%0x\n",
+		     value[0], value[1], value[2], value[3]);
+
+	return status;
+}
+
+int cx231xx_power_suspend(struct cx231xx *dev)
+{
+	u8 value[4] = { 0, 0, 0, 0 };
+	u32 tmp = 0;
+	int status = 0;
+
+	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN,
+				       value, 4);
+	if (status > 0)
+		return status;
+
+	tmp = *((u32 *) value);
+	tmp &= (~PWR_MODE_MASK);
+
+	value[0] = (u8) tmp;
+	value[1] = (u8) (tmp >> 8);
+	value[2] = (u8) (tmp >> 16);
+	value[3] = (u8) (tmp >> 24);
+	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN,
+					value, 4);
+
+	return status;
+}
+
+/******************************************************************************
+ *                  S T R E A M    C O N T R O L   functions                  *
+ ******************************************************************************/
+int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask)
+{
+	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+	u32 tmp = 0;
+	int status = 0;
+
+	cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask);
+	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET,
+				       value, 4);
+	if (status < 0)
+		return status;
+
+	tmp = *((u32 *) value);
+	tmp |= ep_mask;
+	value[0] = (u8) tmp;
+	value[1] = (u8) (tmp >> 8);
+	value[2] = (u8) (tmp >> 16);
+	value[3] = (u8) (tmp >> 24);
+
+	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
+					value, 4);
+
+	return status;
+}
+
+int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask)
+{
+	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+	u32 tmp = 0;
+	int status = 0;
+
+	cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask);
+	status =
+	    cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4);
+	if (status < 0)
+		return status;
+
+	tmp = *((u32 *) value);
+	tmp &= (~ep_mask);
+	value[0] = (u8) tmp;
+	value[1] = (u8) (tmp >> 8);
+	value[2] = (u8) (tmp >> 16);
+	value[3] = (u8) (tmp >> 24);
+
+	status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, EP_MODE_SET,
+					value, 4);
+
+	return status;
+}
+
+int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
+{
+	int status = 0;
+
+	if (dev->udev->speed == USB_SPEED_HIGH) {
+		switch (media_type) {
+		case 81: /* audio */
+			cx231xx_info("%s: Audio enter HANC\n", __func__);
+			status =
+			    cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
+			break;
+
+		case 2:	/* vbi */
+			cx231xx_info("%s: set vanc registers\n", __func__);
+			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
+			break;
+
+		case 3:	/* sliced cc */
+			cx231xx_info("%s: set hanc registers\n", __func__);
+			status =
+			    cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
+			break;
+
+		case 0:	/* video */
+			cx231xx_info("%s: set video registers\n", __func__);
+			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
+			break;
+
+		case 4:	/* ts1 */
+			cx231xx_info("%s: set ts1 registers\n", __func__);
+			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
+			status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
+			break;
+		case 6:	/* ts1 parallel mode */
+			cx231xx_info("%s: set ts1 parrallel mode registers\n",
+				     __func__);
+			status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
+			status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400);
+			break;
+		}
+	} else {
+		status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101);
+	}
+
+	return status;
+}
+
+int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
+{
+	int rc;
+	u32 ep_mask = -1;
+	struct pcb_config *pcb_config;
+
+	/* get EP for media type */
+	pcb_config = (struct pcb_config *)&dev->current_pcb_config;
+
+	if (pcb_config->config_num == 1) {
+		switch (media_type) {
+		case 0:	/* Video */
+			ep_mask = ENABLE_EP4;	/* ep4  [00:1000] */
+			break;
+		case 1:	/* Audio */
+			ep_mask = ENABLE_EP3;	/* ep3  [00:0100] */
+			break;
+		case 2:	/* Vbi */
+			ep_mask = ENABLE_EP5;	/* ep5 [01:0000] */
+			break;
+		case 3:	/* Sliced_cc */
+			ep_mask = ENABLE_EP6;	/* ep6 [10:0000] */
+			break;
+		case 4:	/* ts1 */
+		case 6:	/* ts1 parallel mode */
+			ep_mask = ENABLE_EP1;	/* ep1 [00:0001] */
+			break;
+		case 5:	/* ts2 */
+			ep_mask = ENABLE_EP2;	/* ep2 [00:0010] */
+			break;
+		}
+
+	} else if (pcb_config->config_num > 1) {
+		switch (media_type) {
+		case 0:	/* Video */
+			ep_mask = ENABLE_EP4;	/* ep4  [00:1000] */
+			break;
+		case 1:	/* Audio */
+			ep_mask = ENABLE_EP3;	/* ep3  [00:0100] */
+			break;
+		case 2:	/* Vbi */
+			ep_mask = ENABLE_EP5;	/* ep5 [01:0000] */
+			break;
+		case 3:	/* Sliced_cc */
+			ep_mask = ENABLE_EP6;	/* ep6 [10:0000] */
+			break;
+		case 4:	/* ts1 */
+		case 6:	/* ts1 parallel mode */
+			ep_mask = ENABLE_EP1;	/* ep1 [00:0001] */
+			break;
+		case 5:	/* ts2 */
+			ep_mask = ENABLE_EP2;	/* ep2 [00:0010] */
+			break;
+		}
+
+	}
+
+	if (start) {
+		rc = cx231xx_initialize_stream_xfer(dev, media_type);
+
+		if (rc < 0)
+			return rc;
+
+		/* enable video capture */
+		if (ep_mask > 0)
+			rc = cx231xx_start_stream(dev, ep_mask);
+	} else {
+		/* disable video capture */
+		if (ep_mask > 0)
+			rc = cx231xx_stop_stream(dev, ep_mask);
+	}
+
+	if (dev->mode == CX231XX_ANALOG_MODE)
+		;/* do any in Analog mode */
+	else
+		;/* do any in digital mode */
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(cx231xx_capture_start);
+
+/*****************************************************************************
+*                   G P I O   B I T control functions                        *
+******************************************************************************/
+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+{
+	int status = 0;
+
+	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 0);
+
+	return status;
+}
+
+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val)
+{
+	int status = 0;
+
+	status = cx231xx_send_gpio_cmd(dev, gpio_bit, gpio_val, 4, 0, 1);
+
+	return status;
+}
+
+/*
+* cx231xx_set_gpio_direction
+*      Sets the direction of the GPIO pin to input or output
+*
+* Parameters :
+*      pin_number : The GPIO Pin number to program the direction for
+*                   from 0 to 31
+*      pin_value : The Direction of the GPIO Pin under reference.
+*                      0 = Input direction
+*                      1 = Output direction
+*/
+int cx231xx_set_gpio_direction(struct cx231xx *dev,
+			       int pin_number, int pin_value)
+{
+	int status = 0;
+	u32 value = 0;
+
+	/* Check for valid pin_number - if 32 , bail out */
+	if (pin_number >= 32)
+		return -EINVAL;
+
+	/* input */
+	if (pin_value == 0)
+		value = dev->gpio_dir & (~(1 << pin_number));	/* clear */
+	else
+		value = dev->gpio_dir | (1 << pin_number);
+
+	status = cx231xx_set_gpio_bit(dev, value, (u8 *) &dev->gpio_val);
+
+	/* cache the value for future */
+	dev->gpio_dir = value;
+
+	return status;
+}
+
+/*
+* cx231xx_set_gpio_value
+*      Sets the value of the GPIO pin to Logic high or low. The Pin under
+*      reference should ALREADY BE SET IN OUTPUT MODE !!!!!!!!!
+*
+* Parameters :
+*      pin_number : The GPIO Pin number to program the direction for
+*      pin_value : The value of the GPIO Pin under reference.
+*                      0 = set it to 0
+*                      1 = set it to 1
+*/
+int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value)
+{
+	int status = 0;
+	u32 value = 0;
+
+	/* Check for valid pin_number - if 0xFF , bail out */
+	if (pin_number >= 32)
+		return -EINVAL;
+
+	/* first do a sanity check - if the Pin is not output, make it output */
+	if ((dev->gpio_dir & (1 << pin_number)) == 0x00) {
+		/* It was in input mode */
+		value = dev->gpio_dir | (1 << pin_number);
+		dev->gpio_dir = value;
+		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+					      (u8 *) &dev->gpio_val);
+		value = 0;
+	}
+
+	if (pin_value == 0)
+		value = dev->gpio_val & (~(1 << pin_number));
+	else
+		value = dev->gpio_val | (1 << pin_number);
+
+	/* store the value */
+	dev->gpio_val = value;
+
+	/* toggle bit0 of GP_IO */
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	return status;
+}
+
+/*****************************************************************************
+*                      G P I O I2C related functions                         *
+******************************************************************************/
+int cx231xx_gpio_i2c_start(struct cx231xx *dev)
+{
+	int status = 0;
+
+	/* set SCL to output 1 ; set SDA to output 1 */
+	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
+
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	/* set SCL to output 1; set SDA to output 0 */
+	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	/* set SCL to output 0; set SDA to output 0      */
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	return status;
+}
+
+int cx231xx_gpio_i2c_end(struct cx231xx *dev)
+{
+	int status = 0;
+
+	/* set SCL to output 0; set SDA to output 0      */
+	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	/* set SCL to output 1; set SDA to output 0      */
+	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	/* set SCL to input ,release SCL cable control
+	   set SDA to input ,release SDA cable control */
+	dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
+	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+
+	status =
+	    cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+	if (status < 0)
+		return -EINVAL;
+
+	return status;
+}
+
+int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data)
+{
+	int status = 0;
+	u8 i;
+
+	/* set SCL to output ; set SDA to output */
+	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+
+	for (i = 0; i < 8; i++) {
+		if (((data << i) & 0x80) == 0) {
+			/* set SCL to output 0; set SDA to output 0     */
+			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+			dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+
+			/* set SCL to output 1; set SDA to output 0     */
+			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+
+			/* set SCL to output 0; set SDA to output 0     */
+			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+		} else {
+			/* set SCL to output 0; set SDA to output 1     */
+			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+			dev->gpio_val |= 1 << dev->board.tuner_sda_gpio;
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+
+			/* set SCL to output 1; set SDA to output 1     */
+			dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+
+			/* set SCL to output 0; set SDA to output 1     */
+			dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+			status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+						      (u8 *)&dev->gpio_val);
+		}
+	}
+	return status;
+}
+
+int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 * buf)
+{
+	u8 value = 0;
+	int status = 0;
+	u32 gpio_logic_value = 0;
+	u8 i;
+
+	/* read byte */
+	for (i = 0; i < 8; i++) {	/* send write I2c addr */
+
+		/* set SCL to output 0; set SDA to input */
+		dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+					      (u8 *)&dev->gpio_val);
+
+		/* set SCL to output 1; set SDA to input */
+		dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+		status = cx231xx_set_gpio_bit(dev, dev->gpio_dir,
+					      (u8 *)&dev->gpio_val);
+
+		/* get SDA data bit */
+		gpio_logic_value = dev->gpio_val;
+		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
+					      (u8 *)&dev->gpio_val);
+		if ((dev->gpio_val & (1 << dev->board.tuner_sda_gpio)) != 0)
+			value |= (1 << (8 - i - 1));
+
+		dev->gpio_val = gpio_logic_value;
+	}
+
+	/* set SCL to output 0,finish the read latest SCL signal.
+	   !!!set SDA to input, never to modify SDA direction at
+	   the same times */
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* store the value */
+	*buf = value & 0xff;
+
+	return status;
+}
+
+int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev)
+{
+	int status = 0;
+	u32 gpio_logic_value = 0;
+	int nCnt = 10;
+	int nInit = nCnt;
+
+	/* clock stretch; set SCL to input; set SDA to input;
+	   get SCL value till SCL = 1 */
+	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+	dev->gpio_dir &= ~(1 << dev->board.tuner_scl_gpio);
+
+	gpio_logic_value = dev->gpio_val;
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	do {
+		msleep(2);
+		status = cx231xx_get_gpio_bit(dev, dev->gpio_dir,
+					      (u8 *)&dev->gpio_val);
+		nCnt--;
+	} while (((dev->gpio_val &
+			  (1 << dev->board.tuner_scl_gpio)) == 0) &&
+			 (nCnt > 0));
+
+	if (nCnt == 0)
+		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.  */
+	status = cx231xx_get_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	if ((dev->gpio_val & 1 << dev->board.tuner_sda_gpio) == 0) {
+		dev->gpio_val = gpio_logic_value;
+		dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+		status = 0;
+	} else {
+		dev->gpio_val = gpio_logic_value;
+		dev->gpio_val |= (1 << dev->board.tuner_sda_gpio);
+	}
+
+	/* read SDA end, set the SCL to output 0, after this operation,
+	   SDA direction can be changed. */
+	dev->gpio_val = gpio_logic_value;
+	dev->gpio_dir |= (1 << dev->board.tuner_scl_gpio);
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	return status;
+}
+
+int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev)
+{
+	int status = 0;
+
+	/* set SDA to ouput */
+	dev->gpio_dir |= 1 << dev->board.tuner_sda_gpio;
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set SCL = 0 (output); set SDA = 0 (output) */
+	dev->gpio_val &= ~(1 << dev->board.tuner_sda_gpio);
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set SCL = 1 (output); set SDA = 0 (output) */
+	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set SCL = 0 (output); set SDA = 0 (output) */
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set SDA to input,and then the slave will read data from SDA. */
+	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	return status;
+}
+
+int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev)
+{
+	int status = 0;
+
+	/* set scl to output ; set sda to input */
+	dev->gpio_dir |= 1 << dev->board.tuner_scl_gpio;
+	dev->gpio_dir &= ~(1 << dev->board.tuner_sda_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set scl to output 0; set sda to input */
+	dev->gpio_val &= ~(1 << dev->board.tuner_scl_gpio);
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	/* set scl to output 1; set sda to input */
+	dev->gpio_val |= 1 << dev->board.tuner_scl_gpio;
+	status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, (u8 *)&dev->gpio_val);
+
+	return status;
+}
+
+/*****************************************************************************
+*                      G P I O I2C related functions                         *
+******************************************************************************/
+/* cx231xx_gpio_i2c_read
+ * Function to read data from gpio based I2C interface
+ */
+int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+{
+	int status = 0;
+	int i = 0;
+
+	/* get the lock */
+	mutex_lock(&dev->gpio_i2c_lock);
+
+	/* start */
+	status = cx231xx_gpio_i2c_start(dev);
+
+	/* write dev_addr */
+	status = cx231xx_gpio_i2c_write_byte(dev, (dev_addr << 1) + 1);
+
+	/* readAck */
+	status = cx231xx_gpio_i2c_read_ack(dev);
+
+	/* read data */
+	for (i = 0; i < len; i++) {
+		/* read data */
+		buf[i] = 0;
+		status = cx231xx_gpio_i2c_read_byte(dev, &buf[i]);
+
+		if ((i + 1) != len) {
+			/* only do write ack if we more length */
+			status = cx231xx_gpio_i2c_write_ack(dev);
+		}
+	}
+
+	/* write NAK - inform reads are complete */
+	status = cx231xx_gpio_i2c_write_nak(dev);
+
+	/* write end */
+	status = cx231xx_gpio_i2c_end(dev);
+
+	/* release the lock */
+	mutex_unlock(&dev->gpio_i2c_lock);
+
+	return status;
+}
+
+/* cx231xx_gpio_i2c_write
+ * Function to write data to gpio based I2C interface
+ */
+int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 * buf, u8 len)
+{
+	int status = 0;
+	int i = 0;
+
+	/* get the lock */
+	mutex_lock(&dev->gpio_i2c_lock);
+
+	/* start */
+	status = cx231xx_gpio_i2c_start(dev);
+
+	/* write dev_addr */
+	status = cx231xx_gpio_i2c_write_byte(dev, dev_addr << 1);
+
+	/* read Ack */
+	status = cx231xx_gpio_i2c_read_ack(dev);
+
+	for (i = 0; i < len; i++) {
+		/* Write data */
+		status = cx231xx_gpio_i2c_write_byte(dev, buf[i]);
+
+		/* read Ack */
+		status = cx231xx_gpio_i2c_read_ack(dev);
+	}
+
+	/* write End */
+	status = cx231xx_gpio_i2c_end(dev);
+
+	/* release the lock */
+	mutex_unlock(&dev->gpio_i2c_lock);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2013-05-03 16:44:18.000000000 -0400
@@ -0,0 +1,914 @@
+/*
+   cx231xx-cards.c - driver for Conexant Cx23100/101/102
+				USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+				Based on em28xx 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/usb.h>
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+
+#include <media/cx25840.h>
+#include "xc5000.h"
+
+#include "cx231xx.h"
+
+static int tuner = -1;
+module_param(tuner, int, 0444);
+MODULE_PARM_DESC(tuner, "tuner type");
+
+static unsigned int disable_ir;
+module_param(disable_ir, int, 0444);
+MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
+
+/* Bitmask marking allocated devices from 0 to CX231XX_MAXBOARDS */
+static unsigned long cx231xx_devused;
+
+/*
+ *  Reset sequences for analog/digital modes
+ */
+
+static struct cx231xx_reg_seq RDE250_XCV_TUNER[] = {
+	{0x03, 0x01, 10},
+	{0x03, 0x00, 30},
+	{0x03, 0x01, 10},
+	{-1, -1, -1},
+};
+
+/*
+ *  Board definitions
+ */
+struct cx231xx_board cx231xx_boards[] = {
+	[CX231XX_BOARD_UNKNOWN] = {
+		.name = "Unknown CX231xx video grabber",
+		.tuner_type = TUNER_ABSENT,
+		.input = {{
+				.type = CX231XX_VMUX_TELEVISION,
+				.vmux = CX231XX_VIN_3_1,
+				.amux = CX231XX_AMUX_VIDEO,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_COMPOSITE1,
+				.vmux = CX231XX_VIN_2_1,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_SVIDEO,
+				.vmux = CX231XX_VIN_1_1 |
+					(CX231XX_VIN_1_2 << 8) |
+					CX25840_SVIDEO_ON,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}
+		},
+	},
+	[CX231XX_BOARD_CNXT_RDE_250] = {
+		.name = "Conexant Hybrid TV - RDE250",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.tuner_gpio = RDE250_XCV_TUNER,
+		.tuner_sif_gpio = 0x05,
+		.tuner_scl_gpio = 0x1a,
+		.tuner_sda_gpio = 0x1b,
+		.decoder = CX231XX_AVDECODER,
+		.demod_xfer_mode = 0,
+		.ctl_pin_status_mask = 0xFFFFFFC4,
+		.agc_analog_digital_select_gpio = 0x0c,
+		.gpio_pin_status_mask = 0x4001000,
+		.tuner_i2c_master = 1,
+		.demod_i2c_master = 2,
+		.has_dvb = 1,
+		.demod_addr = 0x02,
+		.norm = V4L2_STD_PAL,
+
+		.input = {{
+				.type = CX231XX_VMUX_TELEVISION,
+				.vmux = CX231XX_VIN_3_1,
+				.amux = CX231XX_AMUX_VIDEO,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_COMPOSITE1,
+				.vmux = CX231XX_VIN_2_1,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_SVIDEO,
+				.vmux = CX231XX_VIN_1_1 |
+					(CX231XX_VIN_1_2 << 8) |
+					CX25840_SVIDEO_ON,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}
+		},
+	},
+
+	[CX231XX_BOARD_CNXT_RDU_250] = {
+		.name = "Conexant Hybrid TV - RDU250",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.tuner_gpio = RDE250_XCV_TUNER,
+		.tuner_sif_gpio = 0x05,
+		.tuner_scl_gpio = 0x1a,
+		.tuner_sda_gpio = 0x1b,
+		.decoder = CX231XX_AVDECODER,
+		.demod_xfer_mode = 0,
+		.ctl_pin_status_mask = 0xFFFFFFC4,
+		.agc_analog_digital_select_gpio = 0x0c,
+		.gpio_pin_status_mask = 0x4001000,
+		.tuner_i2c_master = 1,
+		.demod_i2c_master = 2,
+		.has_dvb = 1,
+		.demod_addr = 0x32,
+		.norm = V4L2_STD_NTSC,
+
+		.input = {{
+				.type = CX231XX_VMUX_TELEVISION,
+				.vmux = CX231XX_VIN_3_1,
+				.amux = CX231XX_AMUX_VIDEO,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_COMPOSITE1,
+				.vmux = CX231XX_VIN_2_1,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}, {
+				.type = CX231XX_VMUX_SVIDEO,
+				.vmux = CX231XX_VIN_1_1 |
+					(CX231XX_VIN_1_2 << 8) |
+					CX25840_SVIDEO_ON,
+				.amux = CX231XX_AMUX_LINE_IN,
+				.gpio = 0,
+			}
+		},
+	},
+};
+const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
+
+/* table of devices that work with this driver */
+struct usb_device_id cx231xx_id_table[] = {
+	{USB_DEVICE(0x0572, 0x5A3C),
+	 .driver_info = CX231XX_BOARD_UNKNOWN},
+	{USB_DEVICE(0x0572, 0x58A2),
+	 .driver_info = CX231XX_BOARD_CNXT_RDE_250},
+	{USB_DEVICE(0x0572, 0x58A1),
+	 .driver_info = CX231XX_BOARD_CNXT_RDU_250},
+	{},
+};
+
+MODULE_DEVICE_TABLE(usb, cx231xx_id_table);
+
+/* cx231xx_tuner_callback
+ * will be used to reset XC5000 tuner using GPIO pin
+ */
+
+int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
+{
+	int rc = 0;
+	struct cx231xx *dev = ptr;
+
+	if (dev->tuner_type == TUNER_XC5000) {
+		if (command == XC5000_TUNER_RESET) {
+			cx231xx_info
+				("Tuner CB: RESET: cmd %d : tuner type %d \n",
+				 command, dev->tuner_type);
+			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+					       1);
+			msleep(10);
+			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+					       0);
+			msleep(330);
+			cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit,
+					       1);
+			msleep(10);
+		}
+	}
+	return rc;
+}
+EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
+
+static inline void cx231xx_set_model(struct cx231xx *dev)
+{
+	memcpy(&dev->board, &cx231xx_boards[dev->model], sizeof(dev->board));
+}
+
+/* Since cx231xx_pre_card_setup() requires a proper dev->model,
+ * this won't work for boards with generic PCI IDs
+ */
+void cx231xx_pre_card_setup(struct cx231xx *dev)
+{
+
+	cx231xx_set_model(dev);
+
+	cx231xx_info("Identified as %s (card=%d)\n",
+		     dev->board.name, dev->model);
+
+	/* set the direction for GPIO pins */
+	cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
+	cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
+	cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
+
+	/* request some modules if any required */
+
+	/* reset the Tuner */
+	cx231xx_gpio_set(dev, dev->board.tuner_gpio);
+
+	/* set the mode to Analog mode initially */
+	cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+
+	/* Unlock device */
+	/* cx231xx_set_mode(dev, CX231XX_SUSPEND); */
+
+}
+
+static void cx231xx_config_tuner(struct cx231xx *dev)
+{
+	struct tuner_setup tun_setup;
+	struct v4l2_frequency f;
+
+	if (dev->tuner_type == TUNER_ABSENT)
+		return;
+
+	tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+	tun_setup.type = dev->tuner_type;
+	tun_setup.addr = dev->tuner_addr;
+	tun_setup.tuner_callback = cx231xx_tuner_callback;
+
+	tuner_call(dev, tuner, s_type_addr, &tun_setup);
+
+#if 0
+	if (tun_setup.type == TUNER_XC5000) {
+		static struct xc2028_ctrl ctrl = {
+			.fname = "/*(DEBLOBBED)*/",
+			.max_len = 64,
+			.demod = 0;
+		};
+		struct v4l2_priv_tun_config cfg = {
+			.tuner = dev->tuner_type,
+			.priv = &ctrl,
+		};
+		tuner_call(dev, tuner, s_config, &cfg);
+	}
+#endif
+	/* configure tuner */
+	f.tuner = 0;
+	f.type = V4L2_TUNER_ANALOG_TV;
+	f.frequency = 9076;	/* just a magic number */
+	dev->ctl_freq = f.frequency;
+	call_all(dev, tuner, s_frequency, &f);
+
+}
+
+/* ----------------------------------------------------------------------- */
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+{
+	if (disable_ir) {
+		ir->get_key = NULL;
+		return;
+	}
+
+	/* detect & configure */
+	switch (dev->model) {
+
+	case CX231XX_BOARD_CNXT_RDE_250:
+		break;
+	case CX231XX_BOARD_CNXT_RDU_250:
+		break;
+	default:
+		break;
+	}
+}
+
+void cx231xx_card_setup(struct cx231xx *dev)
+{
+
+	cx231xx_set_model(dev);
+
+	dev->tuner_type = cx231xx_boards[dev->model].tuner_type;
+	if (cx231xx_boards[dev->model].tuner_addr)
+		dev->tuner_addr = cx231xx_boards[dev->model].tuner_addr;
+
+	/* request some modules */
+	if (dev->board.decoder == CX231XX_AVDECODER) {
+		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+					&dev->i2c_bus[0].i2c_adap,
+					"cx25840", "cx25840", 0x88 >> 1);
+		if (dev->sd_cx25840 == NULL)
+			cx231xx_info("cx25840 subdev registration failure\n");
+		cx25840_call(dev, core, load_fw);
+
+	}
+
+	if (dev->board.tuner_type != TUNER_ABSENT) {
+		dev->sd_tuner =	v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[1].i2c_adap,
+				"tuner", "tuner", 0xc2 >> 1);
+		if (dev->sd_tuner == NULL)
+			cx231xx_info("tuner subdev registration failure\n");
+
+		cx231xx_config_tuner(dev);
+	}
+
+	cx231xx_config_tuner(dev);
+
+#if 0
+	/* TBD  IR will be added later */
+	cx231xx_ir_init(dev);
+#endif
+}
+
+/*
+ * cx231xx_config()
+ * inits registers with sane defaults
+ */
+int cx231xx_config(struct cx231xx *dev)
+{
+	/* TBD need to add cx231xx specific code */
+	dev->mute = 1;		/* maybe not the right place... */
+	dev->volume = 0x1f;
+
+	return 0;
+}
+
+/*
+ * cx231xx_config_i2c()
+ * configure i2c attached devices
+ */
+void cx231xx_config_i2c(struct cx231xx *dev)
+{
+	/* u32 input = INPUT(dev->video_input)->vmux; */
+
+	call_all(dev, video, s_stream, 1);
+}
+
+/*
+ * cx231xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_release_resources(struct cx231xx *dev)
+{
+
+#if 0		/* TBD IR related  */
+	if (dev->ir)
+		cx231xx_ir_fini(dev);
+#endif
+
+	cx231xx_release_analog_resources(dev);
+
+	cx231xx_remove_from_devlist(dev);
+
+	cx231xx_dev_uninit(dev);
+
+	usb_put_dev(dev->udev);
+
+	/* Mark device as unused */
+	cx231xx_devused &= ~(1 << dev->devno);
+}
+
+/*
+ * cx231xx_init_dev()
+ * allocates and inits the device structs, registers i2c bus and v4l device
+ */
+static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
+			    int minor)
+{
+	struct cx231xx *dev = *devhandle;
+	int retval = -ENOMEM;
+	int errCode;
+	unsigned int maxh, maxw;
+
+	dev->udev = udev;
+	mutex_init(&dev->lock);
+	mutex_init(&dev->ctrl_urb_lock);
+	mutex_init(&dev->gpio_i2c_lock);
+
+	spin_lock_init(&dev->video_mode.slock);
+	spin_lock_init(&dev->vbi_mode.slock);
+	spin_lock_init(&dev->sliced_cc_mode.slock);
+
+	init_waitqueue_head(&dev->open);
+	init_waitqueue_head(&dev->wait_frame);
+	init_waitqueue_head(&dev->wait_stream);
+
+	dev->cx231xx_read_ctrl_reg = cx231xx_read_ctrl_reg;
+	dev->cx231xx_write_ctrl_reg = cx231xx_write_ctrl_reg;
+	dev->cx231xx_send_usb_command = cx231xx_send_usb_command;
+	dev->cx231xx_gpio_i2c_read = cx231xx_gpio_i2c_read;
+	dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
+
+	/* Query cx231xx to find what pcb config it is related to */
+	initialize_cx231xx(dev);
+
+	/* Cx231xx pre card setup */
+	cx231xx_pre_card_setup(dev);
+
+	errCode = cx231xx_config(dev);
+	if (errCode) {
+		cx231xx_errdev("error configuring device\n");
+		return -ENOMEM;
+	}
+
+	/* set default norm */
+	dev->norm = dev->board.norm;
+
+	/* register i2c bus */
+	errCode = cx231xx_dev_init(dev);
+	if (errCode < 0) {
+		cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
+			       __func__, errCode);
+		return errCode;
+	}
+
+	/* Do board specific init */
+	cx231xx_card_setup(dev);
+
+	/* configure the device */
+	cx231xx_config_i2c(dev);
+
+	maxw = norm_maxw(dev);
+	maxh = norm_maxh(dev);
+
+	/* set default image size */
+	dev->width = maxw;
+	dev->height = maxh;
+	dev->interlaced = 0;
+	dev->hscale = 0;
+	dev->vscale = 0;
+	dev->video_input = 0;
+
+	errCode = cx231xx_config(dev);
+	if (errCode < 0) {
+		cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
+			       __func__, errCode);
+		return errCode;
+	}
+
+	/* init video dma queues */
+	INIT_LIST_HEAD(&dev->video_mode.vidq.active);
+	INIT_LIST_HEAD(&dev->video_mode.vidq.queued);
+
+	/* init vbi dma queues */
+	INIT_LIST_HEAD(&dev->vbi_mode.vidq.active);
+	INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued);
+
+	/* Reset other chips required if they are tied up with GPIO pins */
+
+	cx231xx_add_into_devlist(dev);
+
+	retval = cx231xx_register_analog_devices(dev);
+	if (retval < 0) {
+		cx231xx_release_resources(dev);
+		goto fail_reg_devices;
+	}
+
+	cx231xx_init_extension(dev);
+
+	return 0;
+
+fail_reg_devices:
+	mutex_unlock(&dev->lock);
+	return retval;
+}
+
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+	struct cx231xx *dev = container_of(work,
+					   struct cx231xx, request_module_wk);
+
+	if (dev->has_alsa_audio)
+		request_module("cx231xx-alsa");
+
+	if (dev->board.has_dvb)
+		request_module("cx231xx-dvb");
+
+}
+
+static void request_modules(struct cx231xx *dev)
+{
+	INIT_WORK(&dev->request_module_wk, request_module_async);
+	schedule_work(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
+/*
+ * cx231xx_usb_probe()
+ * checks for supported devices
+ */
+static int cx231xx_usb_probe(struct usb_interface *interface,
+			     const struct usb_device_id *id)
+{
+	struct usb_device *udev;
+	struct usb_interface *uif;
+	struct cx231xx *dev = NULL;
+	int retval = -ENODEV;
+	int nr = 0, ifnum;
+	int i, isoc_pipe = 0;
+	char *speed;
+	char descr[255] = "";
+	struct usb_interface *lif = NULL;
+	int skip_interface = 0;
+	struct usb_interface_assoc_descriptor *assoc_desc;
+
+	udev = usb_get_dev(interface_to_usbdev(interface));
+	ifnum = interface->altsetting[0].desc.bInterfaceNumber;
+
+	if (!ifnum) {
+		/*
+		 * Interface number 0 - IR interface
+		 */
+		/* Check to see next free device and mark as used */
+		nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
+		cx231xx_devused |= 1 << nr;
+
+		if (nr >= CX231XX_MAXBOARDS) {
+			cx231xx_err(DRIVER_NAME ": Supports only %i cx231xx boards.\n",
+				     CX231XX_MAXBOARDS);
+			cx231xx_devused &= ~(1 << nr);
+			return -ENOMEM;
+		}
+
+		/* allocate memory for our device state and initialize it */
+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+		if (dev == NULL) {
+			cx231xx_err(DRIVER_NAME ": out of memory!\n");
+			cx231xx_devused &= ~(1 << nr);
+			return -ENOMEM;
+		}
+
+		snprintf(dev->name, 29, "cx231xx #%d", nr);
+		dev->devno = nr;
+		dev->model = id->driver_info;
+		dev->video_mode.alt = -1;
+		dev->interface_count++;
+
+		/* reset gpio dir and value */
+		dev->gpio_dir = 0;
+		dev->gpio_val = 0;
+		dev->xc_fw_load_done = 0;
+		dev->has_alsa_audio = 1;
+		dev->power_mode = -1;
+
+		/* 0 - vbi ; 1 -sliced cc mode */
+		dev->vbi_or_sliced_cc_mode = 0;
+
+		/* get maximum no.of IAD interfaces */
+		assoc_desc = udev->actconfig->intf_assoc[0];
+		dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
+
+		/* init CIR module TBD */
+
+		/* store the current interface */
+		lif = interface;
+
+		switch (udev->speed) {
+		case USB_SPEED_LOW:
+			speed = "1.5";
+			break;
+		case USB_SPEED_UNKNOWN:
+		case USB_SPEED_FULL:
+			speed = "12";
+			break;
+		case USB_SPEED_HIGH:
+			speed = "480";
+			break;
+		default:
+			speed = "unknown";
+		}
+
+		if (udev->manufacturer)
+			strlcpy(descr, udev->manufacturer, sizeof(descr));
+
+		if (udev->product) {
+			if (*descr)
+				strlcat(descr, " ", sizeof(descr));
+			strlcat(descr, udev->product, sizeof(descr));
+		}
+		if (*descr)
+			strlcat(descr, " ", sizeof(descr));
+
+		cx231xx_info("New device %s@ %s Mbps "
+		     "(%04x:%04x) with %d interfaces\n",
+		     descr,
+		     speed,
+		     le16_to_cpu(udev->descriptor.idVendor),
+		     le16_to_cpu(udev->descriptor.idProduct),
+		     dev->max_iad_interface_count);
+	} else {
+		/* Get dev structure first */
+		dev = usb_get_intfdata(udev->actconfig->interface[0]);
+		if (dev == NULL) {
+			cx231xx_err(DRIVER_NAME ": out of first interface!\n");
+			return -ENODEV;
+		}
+
+		/* store the interface 0 back */
+		lif = udev->actconfig->interface[0];
+
+		/* increment interface count */
+		dev->interface_count++;
+
+		/* get device number */
+		nr = dev->devno;
+
+		/*
+		 * set skip interface, for all interfaces but
+		 * interface 1 and the last one
+		 */
+		if ((ifnum != 1) && ((dev->interface_count - 1)
+				     != dev->max_iad_interface_count))
+			skip_interface = 1;
+
+		if (ifnum == 1) {
+			assoc_desc = udev->actconfig->intf_assoc[0];
+			if (assoc_desc->bFirstInterface != ifnum) {
+				cx231xx_err(DRIVER_NAME ": Not found "
+					    "matching IAD interface\n");
+				return -ENODEV;
+			}
+		}
+	}
+
+	if (skip_interface)
+		return -ENODEV;
+
+	cx231xx_info("registering interface %d\n", ifnum);
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(lif, dev);
+
+	if ((dev->interface_count - 1) != dev->max_iad_interface_count)
+		return 0;
+
+	/*
+	 * AV device initialization - only done at the last interface
+	 */
+
+	/* Create v4l2 device */
+	retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+	if (retval) {
+		cx231xx_errdev("v4l2_device_register failed\n");
+		cx231xx_devused &= ~(1 << nr);
+		kfree(dev);
+		return -EIO;
+	}
+
+	/* allocate device struct */
+	retval = cx231xx_init_dev(&dev, udev, nr);
+	if (retval) {
+		cx231xx_devused &= ~(1 << dev->devno);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+		return retval;
+	}
+
+	/* compute alternate max packet sizes for video */
+	uif = udev->actconfig->interface[dev->current_pcb_config.
+		       hs_config_info[0].interface_info.video_index + 1];
+
+	dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].
+			endpoint[isoc_pipe].desc.bEndpointAddress);
+
+	dev->video_mode.num_alt = uif->num_altsetting;
+	cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+		     dev->video_mode.end_point_addr,
+		     dev->video_mode.num_alt);
+	dev->video_mode.alt_max_pkt_size =
+		kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
+
+	if (dev->video_mode.alt_max_pkt_size == NULL) {
+		cx231xx_errdev("out of memory!\n");
+		cx231xx_devused &= ~(1 << nr);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < dev->video_mode.num_alt; i++) {
+		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+				desc.wMaxPacketSize);
+		dev->video_mode.alt_max_pkt_size[i] =
+		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+		cx231xx_info("Alternate setting %i, max size= %i\n", i,
+			     dev->video_mode.alt_max_pkt_size[i]);
+	}
+
+	/* compute alternate max packet sizes for vbi */
+	uif = udev->actconfig->interface[dev->current_pcb_config.
+				       hs_config_info[0].interface_info.
+				       vanc_index + 1];
+
+	dev->vbi_mode.end_point_addr =
+	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+			bEndpointAddress);
+
+	dev->vbi_mode.num_alt = uif->num_altsetting;
+	cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+		     dev->vbi_mode.end_point_addr,
+		     dev->vbi_mode.num_alt);
+	dev->vbi_mode.alt_max_pkt_size =
+	    kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL);
+
+	if (dev->vbi_mode.alt_max_pkt_size == NULL) {
+		cx231xx_errdev("out of memory!\n");
+		cx231xx_devused &= ~(1 << nr);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < dev->vbi_mode.num_alt; i++) {
+		u16 tmp =
+		    le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+				desc.wMaxPacketSize);
+		dev->vbi_mode.alt_max_pkt_size[i] =
+		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+		cx231xx_info("Alternate setting %i, max size= %i\n", i,
+			     dev->vbi_mode.alt_max_pkt_size[i]);
+	}
+
+	/* compute alternate max packet sizes for sliced CC */
+	uif = udev->actconfig->interface[dev->current_pcb_config.
+				       hs_config_info[0].interface_info.
+				       hanc_index + 1];
+
+	dev->sliced_cc_mode.end_point_addr =
+	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
+			bEndpointAddress);
+
+	dev->sliced_cc_mode.num_alt = uif->num_altsetting;
+	cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+		     dev->sliced_cc_mode.end_point_addr,
+		     dev->sliced_cc_mode.num_alt);
+	dev->sliced_cc_mode.alt_max_pkt_size =
+		kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL);
+
+	if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
+		cx231xx_errdev("out of memory!\n");
+		cx231xx_devused &= ~(1 << nr);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
+		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+				desc.wMaxPacketSize);
+		dev->sliced_cc_mode.alt_max_pkt_size[i] =
+		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+		cx231xx_info("Alternate setting %i, max size= %i\n", i,
+			     dev->sliced_cc_mode.alt_max_pkt_size[i]);
+	}
+
+	if (dev->current_pcb_config.ts1_source != 0xff) {
+		/* compute alternate max packet sizes for TS1 */
+		uif = udev->actconfig->interface[dev->current_pcb_config.
+					       hs_config_info[0].
+					       interface_info.
+					       ts1_index + 1];
+
+		dev->ts1_mode.end_point_addr =
+		    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
+				desc.bEndpointAddress);
+
+		dev->ts1_mode.num_alt = uif->num_altsetting;
+		cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+			     dev->ts1_mode.end_point_addr,
+			     dev->ts1_mode.num_alt);
+		dev->ts1_mode.alt_max_pkt_size =
+			kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL);
+
+		if (dev->ts1_mode.alt_max_pkt_size == NULL) {
+			cx231xx_errdev("out of memory!\n");
+			cx231xx_devused &= ~(1 << nr);
+			v4l2_device_unregister(&dev->v4l2_dev);
+			kfree(dev);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < dev->ts1_mode.num_alt; i++) {
+			u16 tmp = le16_to_cpu(uif->altsetting[i].
+						endpoint[isoc_pipe].desc.
+						wMaxPacketSize);
+			dev->ts1_mode.alt_max_pkt_size[i] =
+			    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+			cx231xx_info("Alternate setting %i, max size= %i\n", i,
+				     dev->ts1_mode.alt_max_pkt_size[i]);
+		}
+	}
+
+	/* load other modules required */
+	request_modules(dev);
+
+	return 0;
+}
+
+/*
+ * cx231xx_usb_disconnect()
+ * called when the device gets diconencted
+ * video device will be unregistered on v4l2_close in case it is still open
+ */
+static void cx231xx_usb_disconnect(struct usb_interface *interface)
+{
+	struct cx231xx *dev;
+
+	dev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	if (!dev)
+		return;
+
+	if (!dev->udev)
+		return;
+
+	/* delete v4l2 device */
+	v4l2_device_unregister(&dev->v4l2_dev);
+
+	/* wait until all current v4l2 io is finished then deallocate
+	   resources */
+	mutex_lock(&dev->lock);
+
+	wake_up_interruptible_all(&dev->open);
+
+	if (dev->users) {
+		cx231xx_warn
+		    ("device /dev/video%d is open! Deregistration and memory "
+		     "deallocation are deferred on close.\n", dev->vdev->num);
+
+		dev->state |= DEV_MISCONFIGURED;
+		cx231xx_uninit_isoc(dev);
+		dev->state |= DEV_DISCONNECTED;
+		wake_up_interruptible(&dev->wait_frame);
+		wake_up_interruptible(&dev->wait_stream);
+	} else {
+		dev->state |= DEV_DISCONNECTED;
+		cx231xx_release_resources(dev);
+	}
+
+	cx231xx_close_extension(dev);
+
+	mutex_unlock(&dev->lock);
+
+	if (!dev->users) {
+		kfree(dev->video_mode.alt_max_pkt_size);
+		kfree(dev->vbi_mode.alt_max_pkt_size);
+		kfree(dev->sliced_cc_mode.alt_max_pkt_size);
+		kfree(dev->ts1_mode.alt_max_pkt_size);
+		kfree(dev);
+	}
+}
+
+static struct usb_driver cx231xx_usb_driver = {
+	.name = "cx231xx",
+	.probe = cx231xx_usb_probe,
+	.disconnect = cx231xx_usb_disconnect,
+	.id_table = cx231xx_id_table,
+};
+
+static int __init cx231xx_module_init(void)
+{
+	int result;
+
+	printk(KERN_INFO DRIVER_NAME " v4l2 driver loaded.\n");
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&cx231xx_usb_driver);
+	if (result)
+		cx231xx_err(DRIVER_NAME
+			    " usb_register failed. Error number %d.\n", result);
+
+	return result;
+}
+
+static void __exit cx231xx_module_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&cx231xx_usb_driver);
+}
+
+module_init(cx231xx_module_init);
+module_exit(cx231xx_module_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-conf-reg.h linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-conf-reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-conf-reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-conf-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,494 @@
+/*
+   cx231xx_conf-reg.h - driver for Conexant Cx23100/101/102 USB
+			video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot 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 _POLARIS_REG_H_
+#define _POLARIS_REG_H_
+
+#define BOARD_CFG_STAT          0x0
+#define TS_MODE_REG             0x4
+#define TS1_CFG_REG             0x8
+#define TS1_LENGTH_REG          0xc
+#define TS2_CFG_REG             0x10
+#define TS2_LENGTH_REG          0x14
+#define EP_MODE_SET             0x18
+#define CIR_PWR_PTN1            0x1c
+#define CIR_PWR_PTN2            0x20
+#define CIR_PWR_PTN3            0x24
+#define CIR_PWR_MASK0           0x28
+#define CIR_PWR_MASK1           0x2c
+#define CIR_PWR_MASK2           0x30
+#define CIR_GAIN                0x34
+#define CIR_CAR_REG             0x38
+#define CIR_OT_CFG1             0x40
+#define CIR_OT_CFG2             0x44
+#define PWR_CTL_EN              0x74
+
+/* Polaris Endpoints capture mask for register EP_MODE_SET */
+#define ENABLE_EP1              0x01   /* Bit[0]=1 */
+#define ENABLE_EP2              0x02   /* Bit[1]=1 */
+#define ENABLE_EP3              0x04   /* Bit[2]=1 */
+#define ENABLE_EP4              0x08   /* Bit[3]=1 */
+#define ENABLE_EP5              0x10   /* Bit[4]=1 */
+#define ENABLE_EP6              0x20   /* Bit[5]=1 */
+
+/* Bit definition for register PWR_CTL_EN */
+#define PWR_MODE_MASK           0x17f
+#define PWR_AV_EN               0x08   /* bit3 */
+#define PWR_ISO_EN              0x40   /* bit6 */
+#define PWR_AV_MODE             0x30   /* bit4,5  */
+#define PWR_TUNER_EN            0x04   /* bit2 */
+#define PWR_DEMOD_EN            0x02   /* bit1 */
+#define I2C_DEMOD_EN            0x01   /* bit0 */
+#define PWR_RESETOUT_EN         0x100  /* bit8 */
+
+enum AV_MODE{
+       POLARIS_AVMODE_DEFAULT = 0,
+       POLARIS_AVMODE_DIGITAL = 0x10,
+       POLARIS_AVMODE_ANALOGT_TV = 0x20,
+       POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
+
+};
+
+/* Colibri Registers */
+
+#define SINGLE_ENDED            0x0
+#define LOW_IF                  0x4
+#define EU_IF                   0x9
+#define US_IF                   0xa
+
+#define SUP_BLK_TUNE1           0x00
+#define SUP_BLK_TUNE2           0x01
+#define SUP_BLK_TUNE3           0x02
+#define SUP_BLK_XTAL            0x03
+#define SUP_BLK_PLL1            0x04
+#define SUP_BLK_PLL2            0x05
+#define SUP_BLK_PLL3            0x06
+#define SUP_BLK_REF             0x07
+#define SUP_BLK_PWRDN           0x08
+#define SUP_BLK_TESTPAD         0x09
+#define ADC_COM_INT5_STAB_REF   0x0a
+#define ADC_COM_QUANT           0x0b
+#define ADC_COM_BIAS1           0x0c
+#define ADC_COM_BIAS2           0x0d
+#define ADC_COM_BIAS3           0x0e
+#define TESTBUS_CTRL            0x12
+
+#define FLD_PWRDN_TUNING_BIAS	0x10
+#define FLD_PWRDN_ENABLE_PLL	0x08
+#define FLD_PWRDN_PD_BANDGAP	0x04
+#define FLD_PWRDN_PD_BIAS	0x02
+#define FLD_PWRDN_PD_TUNECK	0x01
+
+
+#define ADC_STATUS_CH1          0x20
+#define ADC_STATUS_CH2          0x40
+#define ADC_STATUS_CH3          0x60
+
+#define ADC_STATUS2_CH1         0x21
+#define ADC_STATUS2_CH2         0x41
+#define ADC_STATUS2_CH3         0x61
+
+#define ADC_CAL_ATEST_CH1       0x22
+#define ADC_CAL_ATEST_CH2       0x42
+#define ADC_CAL_ATEST_CH3       0x62
+
+#define ADC_PWRDN_CLAMP_CH1     0x23
+#define ADC_PWRDN_CLAMP_CH2     0x43
+#define ADC_PWRDN_CLAMP_CH3     0x63
+
+#define ADC_CTRL_DAC23_CH1      0x24
+#define ADC_CTRL_DAC23_CH2      0x44
+#define ADC_CTRL_DAC23_CH3      0x64
+
+#define ADC_CTRL_DAC1_CH1       0x25
+#define ADC_CTRL_DAC1_CH2       0x45
+#define ADC_CTRL_DAC1_CH3       0x65
+
+#define ADC_DCSERVO_DEM_CH1     0x26
+#define ADC_DCSERVO_DEM_CH2     0x46
+#define ADC_DCSERVO_DEM_CH3     0x66
+
+#define ADC_FB_FRCRST_CH1       0x27
+#define ADC_FB_FRCRST_CH2       0x47
+#define ADC_FB_FRCRST_CH3       0x67
+
+#define ADC_INPUT_CH1           0x28
+#define ADC_INPUT_CH2           0x48
+#define ADC_INPUT_CH3           0x68
+#define INPUT_SEL_MASK          0x30   /* [5:4] in_sel */
+
+#define ADC_NTF_PRECLMP_EN_CH1  0x29
+#define ADC_NTF_PRECLMP_EN_CH2  0x49
+#define ADC_NTF_PRECLMP_EN_CH3  0x69
+
+#define ADC_QGAIN_RES_TRM_CH1   0x2a
+#define ADC_QGAIN_RES_TRM_CH2   0x4a
+#define ADC_QGAIN_RES_TRM_CH3   0x6a
+
+#define ADC_SOC_PRECLMP_TERM_CH1    0x2b
+#define ADC_SOC_PRECLMP_TERM_CH2    0x4b
+#define ADC_SOC_PRECLMP_TERM_CH3    0x6b
+
+#define TESTBUS_CTRL_CH1        0x32
+#define TESTBUS_CTRL_CH2        0x52
+#define TESTBUS_CTRL_CH3        0x72
+
+/******************************************************************************
+			    * DIF registers *
+ ******************************************************************************/
+#define      DIRECT_IF_REVB_BASE  0x00300
+
+/*****************************************************************************/
+#define      DIF_PLL_FREQ_WORD        (DIRECT_IF_REVB_BASE + 0x00000000)
+/*****************************************************************************/
+#define      FLD_DIF_PLL_LOCK                           0x80000000
+/*  Reserved                                [30:29] */
+#define      FLD_DIF_PLL_FREE_RUN                       0x10000000
+#define      FLD_DIF_PLL_FREQ                           0x0fffffff
+
+/*****************************************************************************/
+#define      DIF_PLL_CTRL             (DIRECT_IF_REVB_BASE + 0x00000004)
+/*****************************************************************************/
+#define      FLD_DIF_KD_PD                              0xff000000
+/*  Reserved                             [23:20] */
+#define      FLD_DIF_KDS_PD                             0x000f0000
+#define      FLD_DIF_KI_PD                              0x0000ff00
+/*  Reserved                             [7:4] */
+#define      FLD_DIF_KIS_PD                             0x0000000f
+
+/*****************************************************************************/
+#define      DIF_PLL_CTRL1            (DIRECT_IF_REVB_BASE + 0x00000008)
+/*****************************************************************************/
+#define      FLD_DIF_KD_FD                              0xff000000
+/*  Reserved                             [23:20] */
+#define      FLD_DIF_KDS_FD                             0x000f0000
+#define      FLD_DIF_KI_FD                              0x0000ff00
+#define      FLD_DIF_SIG_PROP_SZ                        0x000000f0
+#define      FLD_DIF_KIS_FD                             0x0000000f
+
+/*****************************************************************************/
+#define      DIF_PLL_CTRL2            (DIRECT_IF_REVB_BASE + 0x0000000c)
+/*****************************************************************************/
+#define      FLD_DIF_PLL_AGC_REF                        0xfff00000
+#define      FLD_DIF_PLL_AGC_KI                         0x000f0000
+/*  Reserved                             [15] */
+#define      FLD_DIF_FREQ_LIMIT                         0x00007000
+#define      FLD_DIF_K_FD                               0x00000f00
+#define      FLD_DIF_DOWNSMPL_FD                        0x000000ff
+
+/*****************************************************************************/
+#define      DIF_PLL_CTRL3            (DIRECT_IF_REVB_BASE + 0x00000010)
+/*****************************************************************************/
+/*  Reserved                             [31:16] */
+#define      FLD_DIF_PLL_AGC_EN                         0x00008000
+/*  Reserved                             [14:12] */
+#define      FLD_DIF_PLL_MAN_GAIN                       0x00000fff
+
+/*****************************************************************************/
+#define      DIF_AGC_IF_REF           (DIRECT_IF_REVB_BASE + 0x00000014)
+/*****************************************************************************/
+#define      FLD_DIF_K_AGC_RF                           0xf0000000
+#define      FLD_DIF_K_AGC_IF                           0x0f000000
+#define      FLD_DIF_K_AGC_INT                          0x00f00000
+/*  Reserved                             [19:12] */
+#define      FLD_DIF_IF_REF                             0x00000fff
+
+/*****************************************************************************/
+#define      DIF_AGC_CTRL_IF          (DIRECT_IF_REVB_BASE + 0x00000018)
+/*****************************************************************************/
+#define      FLD_DIF_IF_MAX                             0xff000000
+#define      FLD_DIF_IF_MIN                             0x00ff0000
+#define      FLD_DIF_IF_AGC                             0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_AGC_CTRL_INT         (DIRECT_IF_REVB_BASE + 0x0000001c)
+/*****************************************************************************/
+#define      FLD_DIF_INT_MAX                            0xff000000
+#define      FLD_DIF_INT_MIN                            0x00ff0000
+#define      FLD_DIF_INT_AGC                            0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_AGC_CTRL_RF          (DIRECT_IF_REVB_BASE + 0x00000020)
+/*****************************************************************************/
+#define      FLD_DIF_RF_MAX                             0xff000000
+#define      FLD_DIF_RF_MIN                             0x00ff0000
+#define      FLD_DIF_RF_AGC                             0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_AGC_IF_INT_CURRENT   (DIRECT_IF_REVB_BASE + 0x00000024)
+/*****************************************************************************/
+#define      FLD_DIF_IF_AGC_IN                          0xffff0000
+#define      FLD_DIF_INT_AGC_IN                         0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_AGC_RF_CURRENT       (DIRECT_IF_REVB_BASE + 0x00000028)
+/*****************************************************************************/
+/*  Reserved                            [31:16] */
+#define      FLD_DIF_RF_AGC_IN                          0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_VIDEO_AGC_CTRL       (DIRECT_IF_REVB_BASE + 0x0000002c)
+/*****************************************************************************/
+#define      FLD_DIF_AFD                                0xc0000000
+#define      FLD_DIF_K_VID_AGC                          0x30000000
+#define      FLD_DIF_LINE_LENGTH                        0x0fff0000
+#define      FLD_DIF_AGC_GAIN                           0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_VID_AUD_OVERRIDE     (DIRECT_IF_REVB_BASE + 0x00000030)
+/*****************************************************************************/
+#define      FLD_DIF_AUDIO_AGC_OVERRIDE                 0x80000000
+/*  Reserved                             [30:30] */
+#define      FLD_DIF_AUDIO_MAN_GAIN                     0x3f000000
+/*  Reserved                             [23:17] */
+#define      FLD_DIF_VID_AGC_OVERRIDE                   0x00010000
+#define      FLD_DIF_VID_MAN_GAIN                       0x0000ffff
+
+/*****************************************************************************/
+#define      DIF_AV_SEP_CTRL          (DIRECT_IF_REVB_BASE + 0x00000034)
+/*****************************************************************************/
+#define      FLD_DIF_LPF_FREQ                           0xc0000000
+#define      FLD_DIF_AV_PHASE_INC                       0x3f000000
+#define      FLD_DIF_AUDIO_FREQ                         0x00ffffff
+
+/*****************************************************************************/
+#define      DIF_COMP_FLT_CTRL        (DIRECT_IF_REVB_BASE + 0x00000038)
+/*****************************************************************************/
+/*  Reserved                            [31:24] */
+#define      FLD_DIF_IIR23_R2                           0x00ff0000
+#define      FLD_DIF_IIR23_R1                           0x0000ff00
+#define      FLD_DIF_IIR1_R1                            0x000000ff
+
+/*****************************************************************************/
+#define      DIF_MISC_CTRL            (DIRECT_IF_REVB_BASE + 0x0000003c)
+/*****************************************************************************/
+#define      FLD_DIF_DIF_BYPASS                         0x80000000
+#define      FLD_DIF_FM_NYQ_GAIN                        0x40000000
+#define      FLD_DIF_RF_AGC_ENA                         0x20000000
+#define      FLD_DIF_INT_AGC_ENA                        0x10000000
+#define      FLD_DIF_IF_AGC_ENA                         0x08000000
+#define      FLD_DIF_FORCE_RF_IF_LOCK                   0x04000000
+#define      FLD_DIF_VIDEO_AGC_ENA                      0x02000000
+#define      FLD_DIF_RF_AGC_INV                         0x01000000
+#define      FLD_DIF_INT_AGC_INV                        0x00800000
+#define      FLD_DIF_IF_AGC_INV                         0x00400000
+#define      FLD_DIF_SPEC_INV                           0x00200000
+#define      FLD_DIF_AUD_FULL_BW                        0x00100000
+#define      FLD_DIF_AUD_SRC_SEL                        0x00080000
+/*  Reserved                             [18] */
+#define      FLD_DIF_IF_FREQ                            0x00030000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_TIP_OFFSET                         0x00003f00
+/*  Reserved                             [7:5] */
+#define      FLD_DIF_DITHER_ENA                         0x00000010
+/*  Reserved                             [3:1] */
+#define      FLD_DIF_RF_IF_LOCK                         0x00000001
+
+/*****************************************************************************/
+#define      DIF_SRC_PHASE_INC        (DIRECT_IF_REVB_BASE + 0x00000040)
+/*****************************************************************************/
+/*  Reserved                             [31:29] */
+#define      FLD_DIF_PHASE_INC                          0x1fffffff
+
+/*****************************************************************************/
+#define      DIF_SRC_GAIN_CONTROL     (DIRECT_IF_REVB_BASE + 0x00000044)
+/*****************************************************************************/
+/*  Reserved                             [31:16] */
+#define      FLD_DIF_SRC_KI                             0x0000ff00
+#define      FLD_DIF_SRC_KD                             0x000000ff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF01          (DIRECT_IF_REVB_BASE + 0x00000048)
+/*****************************************************************************/
+/*  Reserved                             [31:19] */
+#define      FLD_DIF_BPF_COEFF_0                        0x00070000
+/*  Reserved                             [15:4] */
+#define      FLD_DIF_BPF_COEFF_1                        0x0000000f
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF23          (DIRECT_IF_REVB_BASE + 0x0000004c)
+/*****************************************************************************/
+/*  Reserved                             [31:22] */
+#define      FLD_DIF_BPF_COEFF_2                        0x003f0000
+/*  Reserved                             [15:7] */
+#define      FLD_DIF_BPF_COEFF_3                        0x0000007f
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF45          (DIRECT_IF_REVB_BASE + 0x00000050)
+/*****************************************************************************/
+/*  Reserved                             [31:24] */
+#define      FLD_DIF_BPF_COEFF_4                        0x00ff0000
+/*  Reserved                             [15:8] */
+#define      FLD_DIF_BPF_COEFF_5                        0x000000ff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF67          (DIRECT_IF_REVB_BASE + 0x00000054)
+/*****************************************************************************/
+/*  Reserved                             [31:25] */
+#define      FLD_DIF_BPF_COEFF_6                        0x01ff0000
+/*  Reserved                             [15:9] */
+#define      FLD_DIF_BPF_COEFF_7                        0x000001ff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF89          (DIRECT_IF_REVB_BASE + 0x00000058)
+/*****************************************************************************/
+/*  Reserved                             [31:26] */
+#define      FLD_DIF_BPF_COEFF_8                        0x03ff0000
+/*  Reserved                             [15:10] */
+#define      FLD_DIF_BPF_COEFF_9                        0x000003ff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF1011        (DIRECT_IF_REVB_BASE + 0x0000005c)
+/*****************************************************************************/
+/*  Reserved                             [31:27] */
+#define      FLD_DIF_BPF_COEFF_10                       0x07ff0000
+/*  Reserved                             [15:11] */
+#define      FLD_DIF_BPF_COEFF_11                       0x000007ff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF1213        (DIRECT_IF_REVB_BASE + 0x00000060)
+/*****************************************************************************/
+/*  Reserved                             [31:27] */
+#define      FLD_DIF_BPF_COEFF_12                       0x07ff0000
+/*  Reserved                             [15:12] */
+#define      FLD_DIF_BPF_COEFF_13                       0x00000fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF1415        (DIRECT_IF_REVB_BASE + 0x00000064)
+/*****************************************************************************/
+/*  Reserved                             [31:28] */
+#define      FLD_DIF_BPF_COEFF_14                       0x0fff0000
+/*  Reserved                             [15:12] */
+#define      FLD_DIF_BPF_COEFF_15                       0x00000fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF1617        (DIRECT_IF_REVB_BASE + 0x00000068)
+/*****************************************************************************/
+/*  Reserved                             [31:29] */
+#define      FLD_DIF_BPF_COEFF_16                       0x1fff0000
+/*  Reserved                             [15:13] */
+#define      FLD_DIF_BPF_COEFF_17                       0x00001fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF1819        (DIRECT_IF_REVB_BASE + 0x0000006c)
+/*****************************************************************************/
+/*  Reserved                             [31:29] */
+#define      FLD_DIF_BPF_COEFF_18                       0x1fff0000
+/*  Reserved                             [15:13] */
+#define      FLD_DIF_BPF_COEFF_19                       0x00001fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF2021        (DIRECT_IF_REVB_BASE + 0x00000070)
+/*****************************************************************************/
+/*  Reserved                             [31:29] */
+#define      FLD_DIF_BPF_COEFF_20                       0x1fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_21                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF2223        (DIRECT_IF_REVB_BASE + 0x00000074)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_22                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_23                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF2425        (DIRECT_IF_REVB_BASE + 0x00000078)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_24                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_25                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF2627        (DIRECT_IF_REVB_BASE + 0x0000007c)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_26                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_27                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF2829        (DIRECT_IF_REVB_BASE + 0x00000080)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_28                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_29                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF3031        (DIRECT_IF_REVB_BASE + 0x00000084)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_30                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_31                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF3233        (DIRECT_IF_REVB_BASE + 0x00000088)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_32                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_33                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF3435        (DIRECT_IF_REVB_BASE + 0x0000008c)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_34                       0x3fff0000
+/*  Reserved                             [15:14] */
+#define      FLD_DIF_BPF_COEFF_35                       0x00003fff
+
+/*****************************************************************************/
+#define      DIF_BPF_COEFF36          (DIRECT_IF_REVB_BASE + 0x00000090)
+/*****************************************************************************/
+/*  Reserved                             [31:30] */
+#define      FLD_DIF_BPF_COEFF_36                       0x3fff0000
+/*  Reserved                             [15:0] */
+
+/*****************************************************************************/
+#define      DIF_RPT_VARIANCE         (DIRECT_IF_REVB_BASE + 0x00000094)
+/*****************************************************************************/
+/*  Reserved                             [31:20] */
+#define      FLD_DIF_RPT_VARIANCE                       0x000fffff
+
+/*****************************************************************************/
+#define      DIF_SOFT_RST_CTRL_REVB       (DIRECT_IF_REVB_BASE + 0x00000098)
+/*****************************************************************************/
+/*  Reserved                             [31:8] */
+#define      FLD_DIF_DIF_SOFT_RST                       0x00000080
+#define      FLD_DIF_DIF_REG_RST_MSK                    0x00000040
+#define      FLD_DIF_AGC_RST_MSK                        0x00000020
+#define      FLD_DIF_CMP_RST_MSK                        0x00000010
+#define      FLD_DIF_AVS_RST_MSK                        0x00000008
+#define      FLD_DIF_NYQ_RST_MSK                        0x00000004
+#define      FLD_DIF_DIF_SRC_RST_MSK                    0x00000002
+#define      FLD_DIF_PLL_RST_MSK                        0x00000001
+
+/*****************************************************************************/
+#define      DIF_PLL_FREQ_ERR         (DIRECT_IF_REVB_BASE + 0x0000009c)
+/*****************************************************************************/
+/*  Reserved                             [31:25] */
+#define      FLD_DIF_CTL_IP                             0x01ffffff
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-core.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1200 @@
+/*
+   cx231xx-core.c - driver for Conexant Cx23100/101/102
+				USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+				Based on em28xx 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-common.h>
+
+#include "cx231xx.h"
+#include "cx231xx-reg.h"
+
+/* #define ENABLE_DEBUG_ISOC_FRAMES */
+
+static unsigned int core_debug;
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
+
+#define cx231xx_coredbg(fmt, arg...) do {\
+	if (core_debug) \
+		printk(KERN_INFO "%s %s :"fmt, \
+			 dev->name, __func__ , ##arg); } while (0)
+
+static unsigned int reg_debug;
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
+
+#define cx231xx_regdbg(fmt, arg...) do {\
+	if (reg_debug) \
+		printk(KERN_INFO "%s %s :"fmt, \
+			 dev->name, __func__ , ##arg); } while (0)
+
+static int alt = CX231XX_PINOUT;
+module_param(alt, int, 0644);
+MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
+
+#define cx231xx_isocdbg(fmt, arg...) do {\
+	if (core_debug) \
+		printk(KERN_INFO "%s %s :"fmt, \
+			 dev->name, __func__ , ##arg); } while (0)
+
+/*****************************************************************
+*             Device control list functions     				 *
+******************************************************************/
+
+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
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_remove_from_devlist(struct cx231xx *dev)
+{
+	mutex_lock(&cx231xx_devlist_mutex);
+	list_del(&dev->devlist);
+	mutex_unlock(&cx231xx_devlist_mutex);
+};
+
+void cx231xx_add_into_devlist(struct cx231xx *dev)
+{
+	mutex_lock(&cx231xx_devlist_mutex);
+	list_add_tail(&dev->devlist, &cx231xx_devlist);
+	mutex_unlock(&cx231xx_devlist_mutex);
+};
+
+static LIST_HEAD(cx231xx_extension_devlist);
+static DEFINE_MUTEX(cx231xx_extension_devlist_lock);
+
+int cx231xx_register_extension(struct cx231xx_ops *ops)
+{
+	struct cx231xx *dev = NULL;
+
+	mutex_lock(&cx231xx_devlist_mutex);
+	mutex_lock(&cx231xx_extension_devlist_lock);
+	list_add_tail(&ops->next, &cx231xx_extension_devlist);
+	list_for_each_entry(dev, &cx231xx_devlist, devlist) {
+		if (dev)
+			ops->init(dev);
+	}
+	printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
+	mutex_unlock(&cx231xx_extension_devlist_lock);
+	mutex_unlock(&cx231xx_devlist_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(cx231xx_register_extension);
+
+void cx231xx_unregister_extension(struct cx231xx_ops *ops)
+{
+	struct cx231xx *dev = NULL;
+
+	mutex_lock(&cx231xx_devlist_mutex);
+	list_for_each_entry(dev, &cx231xx_devlist, devlist) {
+		if (dev)
+			ops->fini(dev);
+	}
+
+	mutex_lock(&cx231xx_extension_devlist_lock);
+	printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
+	list_del(&ops->next);
+	mutex_unlock(&cx231xx_extension_devlist_lock);
+	mutex_unlock(&cx231xx_devlist_mutex);
+}
+EXPORT_SYMBOL(cx231xx_unregister_extension);
+
+void cx231xx_init_extension(struct cx231xx *dev)
+{
+	struct cx231xx_ops *ops = NULL;
+
+	mutex_lock(&cx231xx_extension_devlist_lock);
+	if (!list_empty(&cx231xx_extension_devlist)) {
+		list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
+			if (ops->init)
+				ops->init(dev);
+		}
+	}
+	mutex_unlock(&cx231xx_extension_devlist_lock);
+}
+
+void cx231xx_close_extension(struct cx231xx *dev)
+{
+	struct cx231xx_ops *ops = NULL;
+
+	mutex_lock(&cx231xx_extension_devlist_lock);
+	if (!list_empty(&cx231xx_extension_devlist)) {
+		list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
+			if (ops->fini)
+				ops->fini(dev);
+		}
+	}
+	mutex_unlock(&cx231xx_extension_devlist_lock);
+}
+
+/****************************************************************
+*               U S B related functions                         *
+*****************************************************************/
+int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
+			     struct cx231xx_i2c_xfer_data *req_data)
+{
+	int status = 0;
+	struct cx231xx *dev = i2c_bus->dev;
+	struct VENDOR_REQUEST_IN ven_req;
+
+	u8 saddr_len = 0;
+	u8 _i2c_period = 0;
+	u8 _i2c_nostop = 0;
+	u8 _i2c_reserve = 0;
+
+	/* Get the I2C period, nostop and reserve parameters */
+	_i2c_period = i2c_bus->i2c_period;
+	_i2c_nostop = i2c_bus->i2c_nostop;
+	_i2c_reserve = i2c_bus->i2c_reserve;
+
+	saddr_len = req_data->saddr_len;
+
+	/* Set wValue */
+	if (saddr_len == 1)	/* need check saddr_len == 0  */
+		ven_req.wValue =
+		    req_data->
+		    dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
+		    _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
+	else
+		ven_req.wValue =
+		    req_data->
+		    dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 |
+		    _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6;
+
+	/* set channel number */
+	if (req_data->direction & I2C_M_RD) {
+		/* channel number, for read,spec required channel_num +4 */
+		ven_req.bRequest = i2c_bus->nr + 4;
+	} else
+		ven_req.bRequest = i2c_bus->nr;	/* channel number,  */
+
+	/* set index value */
+	switch (saddr_len) {
+	case 0:
+		ven_req.wIndex = 0;	/* need check */
+		break;
+	case 1:
+		ven_req.wIndex = (req_data->saddr_dat & 0xff);
+		break;
+	case 2:
+		ven_req.wIndex = req_data->saddr_dat;
+		break;
+	}
+
+	/* set wLength value */
+	ven_req.wLength = req_data->buf_size;
+
+	/* set bData value */
+	ven_req.bData = 0;
+
+	/* set the direction */
+	if (req_data->direction) {
+		ven_req.direction = USB_DIR_IN;
+		memset(req_data->p_buffer, 0x00, ven_req.wLength);
+	} else
+		ven_req.direction = USB_DIR_OUT;
+
+	/* set the buffer for read / write */
+	ven_req.pBuff = req_data->p_buffer;
+
+
+	/* call common vendor command request */
+	status = cx231xx_send_vendor_cmd(dev, &ven_req);
+	if (status < 0) {
+		cx231xx_info
+		    ("UsbInterface::sendCommand, failed with status -%d\n",
+		     status);
+	}
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_send_usb_command);
+
+/*
+ * cx231xx_read_ctrl_reg()
+ * reads data from the usb device specifying bRequest and wValue
+ */
+int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+			  char *buf, int len)
+{
+	u8 val = 0;
+	int ret;
+	int pipe = usb_rcvctrlpipe(dev->udev, 0);
+
+	if (dev->state & DEV_DISCONNECTED)
+		return -ENODEV;
+
+	if (len > URB_MAX_CTRL_SIZE)
+		return -EINVAL;
+
+	switch (len) {
+	case 1:
+		val = ENABLE_ONE_BYTE;
+		break;
+	case 2:
+		val = ENABLE_TWE_BYTE;
+		break;
+	case 3:
+		val = ENABLE_THREE_BYTE;
+		break;
+	case 4:
+		val = ENABLE_FOUR_BYTE;
+		break;
+	default:
+		val = 0xFF;	/* invalid option */
+	}
+
+	if (val == 0xFF)
+		return -EINVAL;
+
+	if (reg_debug) {
+		cx231xx_isocdbg("(pipe 0x%08x): "
+				"IN:  %02x %02x %02x %02x %02x %02x %02x %02x ",
+				pipe,
+				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				req, 0, val,
+				reg & 0xff, reg >> 8, len & 0xff, len >> 8);
+	}
+
+	mutex_lock(&dev->ctrl_urb_lock);
+	ret = usb_control_msg(dev->udev, pipe, req,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      val, reg, dev->urb_buf, len, HZ);
+	if (ret < 0) {
+		cx231xx_isocdbg(" failed!\n");
+		/* mutex_unlock(&dev->ctrl_urb_lock); */
+		return ret;
+	}
+
+	if (len)
+		memcpy(buf, dev->urb_buf, len);
+
+	mutex_unlock(&dev->ctrl_urb_lock);
+
+	if (reg_debug) {
+		int byte;
+
+		cx231xx_isocdbg("<<<");
+		for (byte = 0; byte < len; byte++)
+			cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
+		cx231xx_isocdbg("\n");
+	}
+
+	return ret;
+}
+
+int cx231xx_send_vendor_cmd(struct cx231xx *dev,
+				struct VENDOR_REQUEST_IN *ven_req)
+{
+	int ret;
+	int pipe = 0;
+
+	if (dev->state & DEV_DISCONNECTED)
+		return -ENODEV;
+
+	if ((ven_req->wLength > URB_MAX_CTRL_SIZE))
+		return -EINVAL;
+
+	if (ven_req->direction)
+		pipe = usb_rcvctrlpipe(dev->udev, 0);
+	else
+		pipe = usb_sndctrlpipe(dev->udev, 0);
+
+	if (reg_debug) {
+		int byte;
+
+		cx231xx_isocdbg("(pipe 0x%08x): "
+				"OUT: %02x %02x %02x %04x %04x %04x >>>",
+				pipe,
+				ven_req->
+				direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				ven_req->bRequest, 0, ven_req->wValue,
+				ven_req->wIndex, ven_req->wLength);
+
+		for (byte = 0; byte < ven_req->wLength; byte++)
+			cx231xx_isocdbg(" %02x",
+					(unsigned char)ven_req->pBuff[byte]);
+		cx231xx_isocdbg("\n");
+	}
+
+	mutex_lock(&dev->ctrl_urb_lock);
+	ret = usb_control_msg(dev->udev, pipe, ven_req->bRequest,
+			      ven_req->
+			      direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      ven_req->wValue, ven_req->wIndex, ven_req->pBuff,
+			      ven_req->wLength, HZ);
+	mutex_unlock(&dev->ctrl_urb_lock);
+
+	return ret;
+}
+
+/*
+ * cx231xx_write_ctrl_reg()
+ * sends data to the usb device, specifying bRequest
+ */
+int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg, char *buf,
+			   int len)
+{
+	u8 val = 0;
+	int ret;
+	int pipe = usb_sndctrlpipe(dev->udev, 0);
+
+	if (dev->state & DEV_DISCONNECTED)
+		return -ENODEV;
+
+	if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
+		return -EINVAL;
+
+	switch (len) {
+	case 1:
+		val = ENABLE_ONE_BYTE;
+		break;
+	case 2:
+		val = ENABLE_TWE_BYTE;
+		break;
+	case 3:
+		val = ENABLE_THREE_BYTE;
+		break;
+	case 4:
+		val = ENABLE_FOUR_BYTE;
+		break;
+	default:
+		val = 0xFF;	/* invalid option */
+	}
+
+	if (val == 0xFF)
+		return -EINVAL;
+
+	if (reg_debug) {
+		int byte;
+
+		cx231xx_isocdbg("(pipe 0x%08x): "
+			"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
+			pipe,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			req, 0, val, reg & 0xff,
+			reg >> 8, len & 0xff, len >> 8);
+
+		for (byte = 0; byte < len; byte++)
+			cx231xx_isocdbg(" %02x", (unsigned char)buf[byte]);
+		cx231xx_isocdbg("\n");
+	}
+
+	mutex_lock(&dev->ctrl_urb_lock);
+	memcpy(dev->urb_buf, buf, len);
+	ret = usb_control_msg(dev->udev, pipe, req,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      val, reg, dev->urb_buf, len, HZ);
+	mutex_unlock(&dev->ctrl_urb_lock);
+
+	return ret;
+}
+
+/****************************************************************
+*           USB Alternate Setting functions                     *
+*****************************************************************/
+
+int cx231xx_set_video_alternate(struct cx231xx *dev)
+{
+	int errCode, prev_alt = dev->video_mode.alt;
+	unsigned int min_pkt_size = dev->width * 2 + 4;
+	u32 usb_interface_index = 0;
+
+	/* When image size is bigger than a certain value,
+	   the frame size should be increased, otherwise, only
+	   green screen will be received.
+	 */
+	if (dev->width * 2 * dev->height > 720 * 240 * 2)
+		min_pkt_size *= 2;
+
+	if (dev->width > 360) {
+		/* resolutions: 720,704,640 */
+		dev->video_mode.alt = 3;
+	} else if (dev->width > 180) {
+		/* resolutions: 360,352,320,240 */
+		dev->video_mode.alt = 2;
+	} else if (dev->width > 0) {
+		/* resolutions: 180,176,160,128,88 */
+		dev->video_mode.alt = 1;
+	} else {
+		/* Change to alt0 BULK to release USB bandwidth */
+		dev->video_mode.alt = 0;
+	}
+
+	/* Get the correct video interface Index */
+	usb_interface_index =
+	    dev->current_pcb_config.hs_config_info[0].interface_info.
+	    video_index + 1;
+
+	if (dev->video_mode.alt != prev_alt) {
+		cx231xx_coredbg("minimum isoc packet size: %u (alt=%d)\n",
+				min_pkt_size, dev->video_mode.alt);
+		dev->video_mode.max_pkt_size =
+		    dev->video_mode.alt_max_pkt_size[dev->video_mode.alt];
+		cx231xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n",
+				dev->video_mode.alt,
+				dev->video_mode.max_pkt_size);
+		cx231xx_info
+		    (" setting alt %d with wMaxPktSize=%u , Interface = %d\n",
+		     dev->video_mode.alt, dev->video_mode.max_pkt_size,
+		     usb_interface_index);
+		errCode =
+		    usb_set_interface(dev->udev, usb_interface_index,
+				      dev->video_mode.alt);
+		if (errCode < 0) {
+			cx231xx_errdev
+			    ("cannot change alt number to %d (error=%i)\n",
+			     dev->video_mode.alt, errCode);
+			return errCode;
+		}
+	}
+	return 0;
+}
+
+int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
+{
+	int status = 0;
+	u32 usb_interface_index = 0;
+	u32 max_pkt_size = 0;
+
+	switch (index) {
+	case INDEX_TS1:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    ts1_index + 1;
+		dev->video_mode.alt = alt;
+		if (dev->ts1_mode.alt_max_pkt_size != NULL)
+			max_pkt_size = dev->ts1_mode.max_pkt_size =
+			    dev->ts1_mode.alt_max_pkt_size[dev->ts1_mode.alt];
+		break;
+	case INDEX_TS2:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    ts2_index + 1;
+		break;
+	case INDEX_AUDIO:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    audio_index + 1;
+		dev->adev.alt = alt;
+		if (dev->adev.alt_max_pkt_size != NULL)
+			max_pkt_size = dev->adev.max_pkt_size =
+			    dev->adev.alt_max_pkt_size[dev->adev.alt];
+		break;
+	case INDEX_VIDEO:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    video_index + 1;
+		dev->video_mode.alt = alt;
+		if (dev->video_mode.alt_max_pkt_size != NULL)
+			max_pkt_size = dev->video_mode.max_pkt_size =
+			    dev->video_mode.alt_max_pkt_size[dev->video_mode.
+							     alt];
+		break;
+	case INDEX_VANC:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    vanc_index + 1;
+		dev->vbi_mode.alt = alt;
+		if (dev->vbi_mode.alt_max_pkt_size != NULL)
+			max_pkt_size = dev->vbi_mode.max_pkt_size =
+			    dev->vbi_mode.alt_max_pkt_size[dev->vbi_mode.alt];
+		break;
+	case INDEX_HANC:
+		usb_interface_index =
+		    dev->current_pcb_config.hs_config_info[0].interface_info.
+		    hanc_index + 1;
+		dev->sliced_cc_mode.alt = alt;
+		if (dev->sliced_cc_mode.alt_max_pkt_size != NULL)
+			max_pkt_size = dev->sliced_cc_mode.max_pkt_size =
+			    dev->sliced_cc_mode.alt_max_pkt_size[dev->
+								 sliced_cc_mode.
+								 alt];
+		break;
+	default:
+		break;
+	}
+
+	if (alt > 0 && max_pkt_size == 0) {
+		cx231xx_errdev
+		("can't change interface %d alt no. to %d: Max. Pkt size = 0\n",
+		usb_interface_index, alt);
+		return -1;
+	}
+
+	cx231xx_info
+	    (" setting alternate %d with wMaxPacketSize=%u , Interface = %d\n",
+	     alt, max_pkt_size, usb_interface_index);
+
+	if (usb_interface_index > 0) {
+		status = usb_set_interface(dev->udev, usb_interface_index, alt);
+		if (status < 0) {
+			cx231xx_errdev
+			("can't change interface %d alt no. to %d (err=%i)\n",
+			usb_interface_index, alt, status);
+			return status;
+		}
+	}
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_set_alt_setting);
+
+int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio)
+{
+	int rc = 0;
+
+	if (!gpio)
+		return rc;
+
+	/* Send GPIO reset sequences specified at board entry */
+	while (gpio->sleep >= 0) {
+		rc = cx231xx_set_gpio_value(dev, gpio->bit, gpio->val);
+		if (rc < 0)
+			return rc;
+
+		if (gpio->sleep > 0)
+			msleep(gpio->sleep);
+
+		gpio++;
+	}
+	return rc;
+}
+
+int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
+{
+	if (dev->mode == set_mode)
+		return 0;
+
+	if (set_mode == CX231XX_SUSPEND) {
+		/* Set the chip in power saving mode */
+		dev->mode = set_mode;
+	}
+
+	/* Resource is locked */
+	if (dev->mode != CX231XX_SUSPEND)
+		return -EINVAL;
+
+	dev->mode = set_mode;
+
+	if (dev->mode == CX231XX_DIGITAL_MODE)
+		;/* Set Digital power mode */
+	else
+		;/* Set Analog Power mode */
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_set_mode);
+
+/*****************************************************************
+*                URB Streaming functions                         *
+******************************************************************/
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void cx231xx_irq_callback(struct urb *urb)
+{
+	struct cx231xx_dmaqueue *dma_q = urb->context;
+	struct cx231xx_video_mode *vmode =
+	    container_of(dma_q, struct cx231xx_video_mode, vidq);
+	struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
+	int rc, i;
+
+	switch (urb->status) {
+	case 0:		/* success */
+	case -ETIMEDOUT:	/* NAK */
+		break;
+	case -ECONNRESET:	/* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:		/* error */
+		cx231xx_isocdbg("urb completition error %d.\n", urb->status);
+		break;
+	}
+
+	/* Copy data from URB */
+	spin_lock(&dev->video_mode.slock);
+	rc = dev->video_mode.isoc_ctl.isoc_copy(dev, urb);
+	spin_unlock(&dev->video_mode.slock);
+
+	/* Reset urb buffers */
+	for (i = 0; i < urb->number_of_packets; i++) {
+		urb->iso_frame_desc[i].status = 0;
+		urb->iso_frame_desc[i].actual_length = 0;
+	}
+	urb->status = 0;
+
+	urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (urb->status) {
+		cx231xx_isocdbg("urb resubmit failed (error=%i)\n",
+				urb->status);
+	}
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void cx231xx_uninit_isoc(struct cx231xx *dev)
+{
+	struct urb *urb;
+	int i;
+
+	cx231xx_isocdbg("cx231xx: called cx231xx_uninit_isoc\n");
+
+	dev->video_mode.isoc_ctl.nfields = -1;
+	for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+		urb = dev->video_mode.isoc_ctl.urb[i];
+		if (urb) {
+			if (!irqs_disabled())
+				usb_kill_urb(urb);
+			else
+				usb_unlink_urb(urb);
+
+			if (dev->video_mode.isoc_ctl.transfer_buffer[i]) {
+				usb_buffer_free(dev->udev,
+						urb->transfer_buffer_length,
+						dev->video_mode.isoc_ctl.
+						transfer_buffer[i],
+						urb->transfer_dma);
+			}
+			usb_free_urb(urb);
+			dev->video_mode.isoc_ctl.urb[i] = NULL;
+		}
+		dev->video_mode.isoc_ctl.transfer_buffer[i] = NULL;
+	}
+
+	kfree(dev->video_mode.isoc_ctl.urb);
+	kfree(dev->video_mode.isoc_ctl.transfer_buffer);
+
+	dev->video_mode.isoc_ctl.urb = NULL;
+	dev->video_mode.isoc_ctl.transfer_buffer = NULL;
+	dev->video_mode.isoc_ctl.num_bufs = 0;
+
+	cx231xx_capture_start(dev, 0, Raw_Video);
+}
+EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc);
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
+		      int num_bufs, int max_pkt_size,
+		      int (*isoc_copy) (struct cx231xx *dev, struct urb *urb))
+{
+	struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
+	int i;
+	int sb_size, pipe;
+	struct urb *urb;
+	int j, k;
+	int rc;
+
+	cx231xx_isocdbg("cx231xx: called cx231xx_prepare_isoc\n");
+
+	dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
+
+	cx231xx_info("Setting Video mux to %d\n", dev->video_input);
+	video_mux(dev, dev->video_input);
+
+	/* De-allocates all pending stuff */
+	cx231xx_uninit_isoc(dev);
+
+	dev->video_mode.isoc_ctl.isoc_copy = isoc_copy;
+	dev->video_mode.isoc_ctl.num_bufs = num_bufs;
+	dma_q->pos = 0;
+	dma_q->is_partial_line = 0;
+	dma_q->last_sav = 0;
+	dma_q->current_field = -1;
+	dma_q->field1_done = 0;
+	dma_q->lines_per_field = dev->height / 2;
+	dma_q->bytes_left_in_line = dev->width << 1;
+	dma_q->lines_completed = 0;
+	for (i = 0; i < 8; i++)
+		dma_q->partial_buf[i] = 0;
+
+	dev->video_mode.isoc_ctl.urb =
+	    kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+	if (!dev->video_mode.isoc_ctl.urb) {
+		cx231xx_errdev("cannot alloc memory for usb buffers\n");
+		return -ENOMEM;
+	}
+
+	dev->video_mode.isoc_ctl.transfer_buffer =
+	    kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+	if (!dev->video_mode.isoc_ctl.transfer_buffer) {
+		cx231xx_errdev("cannot allocate memory for usbtransfer\n");
+		kfree(dev->video_mode.isoc_ctl.urb);
+		return -ENOMEM;
+	}
+
+	dev->video_mode.isoc_ctl.max_pkt_size = max_pkt_size;
+	dev->video_mode.isoc_ctl.buf = NULL;
+
+	sb_size = max_packets * dev->video_mode.isoc_ctl.max_pkt_size;
+
+	/* allocate urbs and transfer buffers */
+	for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+		urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+		if (!urb) {
+			cx231xx_err("cannot alloc isoc_ctl.urb %i\n", i);
+			cx231xx_uninit_isoc(dev);
+			return -ENOMEM;
+		}
+		dev->video_mode.isoc_ctl.urb[i] = urb;
+
+		dev->video_mode.isoc_ctl.transfer_buffer[i] =
+		    usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,
+				     &urb->transfer_dma);
+		if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) {
+			cx231xx_err("unable to allocate %i bytes for transfer"
+				    " buffer %i%s\n",
+				    sb_size, i,
+				    in_interrupt() ? " while in int" : "");
+			cx231xx_uninit_isoc(dev);
+			return -ENOMEM;
+		}
+		memset(dev->video_mode.isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+		pipe =
+		    usb_rcvisocpipe(dev->udev, dev->video_mode.end_point_addr);
+
+		usb_fill_int_urb(urb, dev->udev, pipe,
+				 dev->video_mode.isoc_ctl.transfer_buffer[i],
+				 sb_size, cx231xx_irq_callback, dma_q, 1);
+
+		urb->number_of_packets = max_packets;
+		urb->transfer_flags = URB_ISO_ASAP;
+
+		k = 0;
+		for (j = 0; j < max_packets; j++) {
+			urb->iso_frame_desc[j].offset = k;
+			urb->iso_frame_desc[j].length =
+			    dev->video_mode.isoc_ctl.max_pkt_size;
+			k += dev->video_mode.isoc_ctl.max_pkt_size;
+		}
+	}
+
+	init_waitqueue_head(&dma_q->wq);
+
+	/* submit urbs and enables IRQ */
+	for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) {
+		rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i],
+				    GFP_ATOMIC);
+		if (rc) {
+			cx231xx_err("submit of urb %i failed (error=%i)\n", i,
+				    rc);
+			cx231xx_uninit_isoc(dev);
+			return rc;
+		}
+	}
+
+	cx231xx_capture_start(dev, 1, Raw_Video);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_init_isoc);
+
+/*****************************************************************
+*             Device Init/UnInit functions                       *
+******************************************************************/
+int cx231xx_dev_init(struct cx231xx *dev)
+{
+	int errCode = 0;
+
+	/* Initialize I2C bus */
+
+	/* External Master 1 Bus */
+	dev->i2c_bus[0].nr = 0;
+	dev->i2c_bus[0].dev = dev;
+	dev->i2c_bus[0].i2c_period = I2C_SPEED_1M;	/* 1MHz */
+	dev->i2c_bus[0].i2c_nostop = 0;
+	dev->i2c_bus[0].i2c_reserve = 0;
+
+	/* External Master 2 Bus */
+	dev->i2c_bus[1].nr = 1;
+	dev->i2c_bus[1].dev = dev;
+	dev->i2c_bus[1].i2c_period = I2C_SPEED_1M;	/* 1MHz */
+	dev->i2c_bus[1].i2c_nostop = 0;
+	dev->i2c_bus[1].i2c_reserve = 0;
+
+	/* Internal Master 3 Bus */
+	dev->i2c_bus[2].nr = 2;
+	dev->i2c_bus[2].dev = dev;
+	dev->i2c_bus[2].i2c_period = I2C_SPEED_400K;	/* 400kHz */
+	dev->i2c_bus[2].i2c_nostop = 0;
+	dev->i2c_bus[2].i2c_reserve = 0;
+
+	/* register I2C buses */
+	cx231xx_i2c_register(&dev->i2c_bus[0]);
+	cx231xx_i2c_register(&dev->i2c_bus[1]);
+	cx231xx_i2c_register(&dev->i2c_bus[2]);
+
+	/* init hardware */
+	/* Note : with out calling set power mode function,
+	afe can not be set up correctly */
+	errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: Failed to set Power - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+
+	/* initialize Colibri block */
+	errCode = cx231xx_afe_init_super_block(dev, 0x23c);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: cx231xx_afe init super block - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+	errCode = cx231xx_afe_init_channels(dev);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: cx231xx_afe init channels - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+
+	/* Set DIF in By pass mode */
+	errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+
+	/* I2S block related functions */
+	errCode = cx231xx_i2s_blk_initialize(dev);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: cx231xx_i2s block initialize - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+
+	/* init control pins */
+	errCode = cx231xx_init_ctrl_pin_status(dev);
+	if (errCode < 0) {
+		cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n",
+			       __func__, errCode);
+		return errCode;
+	}
+
+	/* set AGC mode to Analog */
+	errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n",
+		     __func__, errCode);
+		return errCode;
+	}
+
+	/* set all alternate settings to zero initially */
+	cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
+	cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+	cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
+	if (dev->board.has_dvb)
+		cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
+
+	/* set the I2C master port to 3 on channel 1 */
+	errCode = cx231xx_enable_i2c_for_tuner(dev, I2C_3);
+
+	return errCode;
+}
+EXPORT_SYMBOL_GPL(cx231xx_dev_init);
+
+void cx231xx_dev_uninit(struct cx231xx *dev)
+{
+	/* Un Initialize I2C bus */
+	cx231xx_i2c_unregister(&dev->i2c_bus[2]);
+	cx231xx_i2c_unregister(&dev->i2c_bus[1]);
+	cx231xx_i2c_unregister(&dev->i2c_bus[0]);
+}
+EXPORT_SYMBOL_GPL(cx231xx_dev_uninit);
+
+/*****************************************************************
+*              G P I O related functions                         *
+******************************************************************/
+int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 * gpio_val,
+			  u8 len, u8 request, u8 direction)
+{
+	int status = 0;
+	struct VENDOR_REQUEST_IN ven_req;
+
+	/* Set wValue */
+	ven_req.wValue = (u16) (gpio_bit >> 16 & 0xffff);
+
+	/* set request */
+	if (!request) {
+		if (direction)
+			ven_req.bRequest = VRT_GET_GPIO;	/* 0x8 gpio */
+		else
+			ven_req.bRequest = VRT_SET_GPIO;	/* 0x9 gpio */
+	} else {
+		if (direction)
+			ven_req.bRequest = VRT_GET_GPIE;	/* 0xa gpie */
+		else
+			ven_req.bRequest = VRT_SET_GPIE;	/* 0xb gpie */
+	}
+
+	/* set index value */
+	ven_req.wIndex = (u16) (gpio_bit & 0xffff);
+
+	/* set wLength value */
+	ven_req.wLength = len;
+
+	/* set bData value */
+	ven_req.bData = 0;
+
+	/* set the buffer for read / write */
+	ven_req.pBuff = gpio_val;
+
+	/* set the direction */
+	if (direction) {
+		ven_req.direction = USB_DIR_IN;
+		memset(ven_req.pBuff, 0x00, ven_req.wLength);
+	} else
+		ven_req.direction = USB_DIR_OUT;
+
+
+	/* call common vendor command request */
+	status = cx231xx_send_vendor_cmd(dev, &ven_req);
+	if (status < 0) {
+		cx231xx_info
+		    ("UsbInterface::sendCommand, failed with status -%d\n",
+		     status);
+	}
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(cx231xx_send_gpio_cmd);
+
+/*****************************************************************
+ *    C O N T R O L - Register R E A D / W R I T E functions     *
+ *****************************************************************/
+int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode)
+{
+	u8 value[4] = { 0x0, 0x0, 0x0, 0x0 };
+	u32 tmp = 0;
+	int status = 0;
+
+	status =
+	    cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, address, value, 4);
+	if (status < 0)
+		return status;
+
+	tmp = *((u32 *) value);
+	tmp |= mode;
+
+	value[0] = (u8) tmp;
+	value[1] = (u8) (tmp >> 8);
+	value[2] = (u8) (tmp >> 16);
+	value[3] = (u8) (tmp >> 24);
+
+	status =
+	    cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, address, value, 4);
+
+	return status;
+}
+
+/*****************************************************************
+ *            I 2 C Internal C O N T R O L   functions           *
+ *****************************************************************/
+int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
+			  u8 saddr_len, u32 *data, u8 data_len)
+{
+	int status = 0;
+	struct cx231xx_i2c_xfer_data req_data;
+	u8 value[4] = { 0, 0, 0, 0 };
+
+	if (saddr_len == 0)
+		saddr = 0;
+	else if (saddr_len == 0)
+		saddr &= 0xff;
+
+	/* prepare xfer_data struct */
+	req_data.dev_addr = dev_addr >> 1;
+	req_data.direction = I2C_M_RD;
+	req_data.saddr_len = saddr_len;
+	req_data.saddr_dat = saddr;
+	req_data.buf_size = data_len;
+	req_data.p_buffer = (u8 *) value;
+
+	/* usb send command */
+	status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
+
+	if (status >= 0) {
+		/* Copy the data read back to main buffer */
+		if (data_len == 1)
+			*data = value[0];
+		else
+			*data =
+			    value[0] | value[1] << 8 | value[2] << 16 | value[3]
+			    << 24;
+	}
+
+	return status;
+}
+
+int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr, u16 saddr,
+			   u8 saddr_len, u32 data, u8 data_len)
+{
+	int status = 0;
+	u8 value[4] = { 0, 0, 0, 0 };
+	struct cx231xx_i2c_xfer_data req_data;
+
+	value[0] = (u8) data;
+	value[1] = (u8) (data >> 8);
+	value[2] = (u8) (data >> 16);
+	value[3] = (u8) (data >> 24);
+
+	if (saddr_len == 0)
+		saddr = 0;
+	else if (saddr_len == 0)
+		saddr &= 0xff;
+
+	/* prepare xfer_data struct */
+	req_data.dev_addr = dev_addr >> 1;
+	req_data.direction = 0;
+	req_data.saddr_len = saddr_len;
+	req_data.saddr_dat = saddr;
+	req_data.buf_size = data_len;
+	req_data.p_buffer = value;
+
+	/* usb send command */
+	status = dev->cx231xx_send_usb_command(&dev->i2c_bus[0], &req_data);
+
+	return status;
+}
+
+int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
+			   u16 register_address, u8 bit_start, u8 bit_end,
+			   u32 value)
+{
+	int status = 0;
+	u32 tmp;
+	u32 mask = 0;
+	int i;
+
+	if (bit_start > (size - 1) || bit_end > (size - 1))
+		return -1;
+
+	if (size == 8) {
+		status =
+		    cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
+					  &tmp, 1);
+	} else {
+		status =
+		    cx231xx_read_i2c_data(dev, dev_addr, register_address, 2,
+					  &tmp, 4);
+	}
+
+	if (status < 0)
+		return status;
+
+	mask = 1 << bit_end;
+	for (i = bit_end; i > bit_start && i > 0; i--)
+		mask = mask + (1 << (i - 1));
+
+	value <<= bit_start;
+
+	if (size == 8) {
+		tmp &= ~mask;
+		tmp |= value;
+		tmp &= 0xff;
+		status =
+		    cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
+					   tmp, 1);
+	} else {
+		tmp &= ~mask;
+		tmp |= value;
+		status =
+		    cx231xx_write_i2c_data(dev, dev_addr, register_address, 2,
+					   tmp, 4);
+	}
+
+	return status;
+}
+
+int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
+					u16 saddr, u32 mask, u32 value)
+{
+	u32 temp;
+	int status = 0;
+
+	status = cx231xx_read_i2c_data(dev, dev_addr, saddr, 2, &temp, 4);
+
+	if (status < 0)
+		return status;
+
+	temp &= ~mask;
+	temp |= value;
+
+	status = cx231xx_write_i2c_data(dev, dev_addr, saddr, 2, temp, 4);
+
+	return status;
+}
+
+u32 cx231xx_set_field(u32 field_mask, u32 data)
+{
+	u32 temp;
+
+	for (temp = field_mask; (temp & 1) == 0; temp >>= 1)
+		data <<= 1;
+
+	return data;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-dvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,559 @@
+/*
+ DVB device driver for cx231xx
+
+ Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+		Based on em28xx 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+
+#include "cx231xx.h"
+#include <media/v4l2-common.h>
+#include <media/videobuf-vmalloc.h>
+
+#include "xc5000.h"
+#include "dvb_dummy_fe.h"
+
+MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
+MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+#define dprintk(level, fmt, arg...) do {			\
+if (debug >= level) 						\
+	printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg);	\
+} while (0)
+
+#define CX231XX_DVB_NUM_BUFS 5
+#define CX231XX_DVB_MAX_PACKETSIZE 564
+#define CX231XX_DVB_MAX_PACKETS 64
+
+struct cx231xx_dvb {
+	struct dvb_frontend *frontend;
+
+	/* feed count management */
+	struct mutex lock;
+	int nfeeds;
+
+	/* general boilerplate stuff */
+	struct dvb_adapter adapter;
+	struct dvb_demux demux;
+	struct dmxdev dmxdev;
+	struct dmx_frontend fe_hw;
+	struct dmx_frontend fe_mem;
+	struct dvb_net net;
+};
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+	char *errmsg = "Unknown";
+
+	switch (status) {
+	case -ENOENT:
+		errmsg = "unlinked synchronuously";
+		break;
+	case -ECONNRESET:
+		errmsg = "unlinked asynchronuously";
+		break;
+	case -ENOSR:
+		errmsg = "Buffer error (overrun)";
+		break;
+	case -EPIPE:
+		errmsg = "Stalled (device not responding)";
+		break;
+	case -EOVERFLOW:
+		errmsg = "Babble (bad cable?)";
+		break;
+	case -EPROTO:
+		errmsg = "Bit-stuff error (bad cable?)";
+		break;
+	case -EILSEQ:
+		errmsg = "CRC/Timeout (could be anything)";
+		break;
+	case -ETIME:
+		errmsg = "Device does not respond";
+		break;
+	}
+	if (packet < 0) {
+		dprintk(1, "URB status %d [%s].\n", status, errmsg);
+	} else {
+		dprintk(1, "URB packet %d, status %d [%s].\n",
+			packet, status, errmsg);
+	}
+}
+
+static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
+{
+	int i;
+
+	if (!dev)
+		return 0;
+
+	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+		return 0;
+
+	if (urb->status < 0) {
+		print_err_status(dev, -1, urb->status);
+		if (urb->status == -ENOENT)
+			return 0;
+	}
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		int status = urb->iso_frame_desc[i].status;
+
+		if (status < 0) {
+			print_err_status(dev, i, status);
+			if (urb->iso_frame_desc[i].status != -EPROTO)
+				continue;
+		}
+
+		dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer +
+				 urb->iso_frame_desc[i].offset,
+				 urb->iso_frame_desc[i].actual_length);
+	}
+
+	return 0;
+}
+
+static int start_streaming(struct cx231xx_dvb *dvb)
+{
+	int rc;
+	struct cx231xx *dev = dvb->adapter.priv;
+
+	usb_set_interface(dev->udev, 0, 1);
+	rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+	if (rc < 0)
+		return rc;
+
+	return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
+				 CX231XX_DVB_NUM_BUFS,
+				 CX231XX_DVB_MAX_PACKETSIZE, dvb_isoc_copy);
+}
+
+static int stop_streaming(struct cx231xx_dvb *dvb)
+{
+	struct cx231xx *dev = dvb->adapter.priv;
+
+	cx231xx_uninit_isoc(dev);
+
+	cx231xx_set_mode(dev, CX231XX_SUSPEND);
+
+	return 0;
+}
+
+static int start_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct cx231xx_dvb *dvb = demux->priv;
+	int rc, ret;
+
+	if (!demux->dmx.frontend)
+		return -EINVAL;
+
+	mutex_lock(&dvb->lock);
+	dvb->nfeeds++;
+	rc = dvb->nfeeds;
+
+	if (dvb->nfeeds == 1) {
+		ret = start_streaming(dvb);
+		if (ret < 0)
+			rc = ret;
+	}
+
+	mutex_unlock(&dvb->lock);
+	return rc;
+}
+
+static int stop_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct cx231xx_dvb *dvb = demux->priv;
+	int err = 0;
+
+	mutex_lock(&dvb->lock);
+	dvb->nfeeds--;
+
+	if (0 == dvb->nfeeds)
+		err = stop_streaming(dvb);
+
+	mutex_unlock(&dvb->lock);
+	return err;
+}
+
+/* ------------------------------------------------------------------ */
+static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+	struct cx231xx *dev = fe->dvb->priv;
+
+	if (acquire)
+		return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+	else
+		return cx231xx_set_mode(dev, CX231XX_SUSPEND);
+}
+
+/* ------------------------------------------------------------------ */
+
+static struct xc5000_config cnxt_rde250_tunerconfig = {
+	.i2c_address = 0x61,
+	.if_khz = 5380,
+};
+
+/* ------------------------------------------------------------------ */
+#if 0
+static int attach_xc5000(u8 addr, struct cx231xx *dev)
+{
+
+	struct dvb_frontend *fe;
+	struct xc5000_config cfg;
+
+	memset(&cfg, 0, sizeof(cfg));
+	cfg.i2c_adap = &dev->i2c_bus[1].i2c_adap;
+	cfg.i2c_addr = addr;
+
+	if (!dev->dvb->frontend) {
+		printk(KERN_ERR "%s/2: dvb frontend not attached. "
+		       "Can't attach xc5000\n", dev->name);
+		return -EINVAL;
+	}
+
+	fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg);
+	if (!fe) {
+		printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name);
+		dvb_frontend_detach(dev->dvb->frontend);
+		dev->dvb->frontend = NULL;
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name);
+
+	return 0;
+}
+#endif
+
+int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
+{
+	int status = 0;
+
+	if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
+
+		struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
+
+		if (dops->set_analog_params != NULL) {
+			struct analog_parameters params;
+
+			params.frequency = freq;
+			params.std = dev->norm;
+			params.mode = 0;	/* 0- Air; 1 - cable */
+			/*params.audmode = ;       */
+
+			/* Set the analog parameters to set the frequency */
+			cx231xx_info("Setting Frequency for XC5000\n");
+			dops->set_analog_params(dev->dvb->frontend, &params);
+		}
+
+	}
+
+	return status;
+}
+
+int cx231xx_reset_analog_tuner(struct cx231xx *dev)
+{
+	int status = 0;
+
+	if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) {
+
+		struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops;
+
+		if (dops->init != NULL && !dev->xc_fw_load_done) {
+
+			cx231xx_info("Reloading firmware for XC5000\n");
+			status = dops->init(dev->dvb->frontend);
+			if (status == 0) {
+				dev->xc_fw_load_done = 1;
+				cx231xx_info
+				    ("XC5000 firmware download completed\n");
+			} else {
+				dev->xc_fw_load_done = 0;
+				cx231xx_info
+				    ("XC5000 firmware download failed !!!\n");
+			}
+		}
+
+	}
+
+	return status;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int register_dvb(struct cx231xx_dvb *dvb,
+			struct module *module,
+			struct cx231xx *dev, struct device *device)
+{
+	int result;
+
+	mutex_init(&dvb->lock);
+
+	/* register adapter */
+	result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
+				      adapter_nr);
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "%s: dvb_register_adapter failed (errno = %d)\n",
+		       dev->name, result);
+		goto fail_adapter;
+	}
+
+	/* Ensure all frontends negotiate bus access */
+	dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
+
+	dvb->adapter.priv = dev;
+
+	/* register frontend */
+	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "%s: dvb_register_frontend failed (errno = %d)\n",
+		       dev->name, result);
+		goto fail_frontend;
+	}
+
+	/* register demux stuff */
+	dvb->demux.dmx.capabilities =
+	    DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+	    DMX_MEMORY_BASED_FILTERING;
+	dvb->demux.priv = dvb;
+	dvb->demux.filternum = 256;
+	dvb->demux.feednum = 256;
+	dvb->demux.start_feed = start_feed;
+	dvb->demux.stop_feed = stop_feed;
+
+	result = dvb_dmx_init(&dvb->demux);
+	if (result < 0) {
+		printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
+		       dev->name, result);
+		goto fail_dmx;
+	}
+
+	dvb->dmxdev.filternum = 256;
+	dvb->dmxdev.demux = &dvb->demux.dmx;
+	dvb->dmxdev.capabilities = 0;
+	result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+	if (result < 0) {
+		printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
+		       dev->name, result);
+		goto fail_dmxdev;
+	}
+
+	dvb->fe_hw.source = DMX_FRONTEND_0;
+	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
+		       dev->name, result);
+		goto fail_fe_hw;
+	}
+
+	dvb->fe_mem.source = DMX_MEMORY_FE;
+	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
+		       dev->name, result);
+		goto fail_fe_mem;
+	}
+
+	result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (result < 0) {
+		printk(KERN_WARNING
+		       "%s: connect_frontend failed (errno = %d)\n", dev->name,
+		       result);
+		goto fail_fe_conn;
+	}
+
+	/* register network adapter */
+	dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+	return 0;
+
+fail_fe_conn:
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+fail_fe_mem:
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+fail_fe_hw:
+	dvb_dmxdev_release(&dvb->dmxdev);
+fail_dmxdev:
+	dvb_dmx_release(&dvb->demux);
+fail_dmx:
+	dvb_unregister_frontend(dvb->frontend);
+fail_frontend:
+	dvb_frontend_detach(dvb->frontend);
+	dvb_unregister_adapter(&dvb->adapter);
+fail_adapter:
+	return result;
+}
+
+static void unregister_dvb(struct cx231xx_dvb *dvb)
+{
+	dvb_net_release(&dvb->net);
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	dvb_dmxdev_release(&dvb->dmxdev);
+	dvb_dmx_release(&dvb->demux);
+	dvb_unregister_frontend(dvb->frontend);
+	dvb_frontend_detach(dvb->frontend);
+	dvb_unregister_adapter(&dvb->adapter);
+}
+
+static int dvb_init(struct cx231xx *dev)
+{
+	int result = 0;
+	struct cx231xx_dvb *dvb;
+
+	if (!dev->board.has_dvb) {
+		/* This device does not support the extension */
+		return 0;
+	}
+
+	dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
+
+	if (dvb == NULL) {
+		printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n");
+		return -ENOMEM;
+	}
+	dev->dvb = dvb;
+	dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
+	dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
+
+	cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
+	/* init frontend */
+	switch (dev->model) {
+	case CX231XX_BOARD_CNXT_RDE_250:
+
+		/* dev->dvb->frontend = dvb_attach(s5h1411_attach,
+		   &dvico_s5h1411_config,
+		   &dev->i2c_bus[1].i2c_adap); */
+		dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
+
+		if (dev->dvb->frontend == NULL) {
+			printk(DRIVER_NAME
+			       ": Failed to attach dummy front end\n");
+			result = -EINVAL;
+			goto out_free;
+		}
+
+		/* define general-purpose callback pointer */
+		dvb->frontend->callback = cx231xx_tuner_callback;
+
+		if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+			       &dev->i2c_bus[1].i2c_adap,
+			       &cnxt_rde250_tunerconfig) < 0) {
+			result = -EINVAL;
+			goto out_free;
+		}
+
+		break;
+	case CX231XX_BOARD_CNXT_RDU_250:
+
+		dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach);
+
+		if (dev->dvb->frontend == NULL) {
+			printk(DRIVER_NAME
+			       ": Failed to attach dummy front end\n");
+			result = -EINVAL;
+			goto out_free;
+		}
+
+		/* define general-purpose callback pointer */
+		dvb->frontend->callback = cx231xx_tuner_callback;
+
+		if (dvb_attach(xc5000_attach, dev->dvb->frontend,
+			       &dev->i2c_bus[1].i2c_adap,
+			       &cnxt_rde250_tunerconfig) < 0) {
+			result = -EINVAL;
+			goto out_free;
+		}
+		break;
+
+	default:
+		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
+		       " isn't supported yet\n", dev->name);
+		break;
+	}
+	if (NULL == dvb->frontend) {
+		printk(KERN_ERR
+		       "%s/2: frontend initialization failed\n", dev->name);
+		result = -EINVAL;
+		goto out_free;
+	}
+
+	/* register everything */
+	result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
+
+	if (result < 0)
+		goto out_free;
+
+	cx231xx_set_mode(dev, CX231XX_SUSPEND);
+	printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
+	return 0;
+
+out_free:
+	cx231xx_set_mode(dev, CX231XX_SUSPEND);
+	kfree(dvb);
+	dev->dvb = NULL;
+	return result;
+}
+
+static int dvb_fini(struct cx231xx *dev)
+{
+	if (!dev->board.has_dvb) {
+		/* This device does not support the extension */
+		return 0;
+	}
+
+	if (dev->dvb) {
+		unregister_dvb(dev->dvb);
+		dev->dvb = NULL;
+	}
+
+	return 0;
+}
+
+static struct cx231xx_ops dvb_ops = {
+	.id = CX231XX_DVB,
+	.name = "Cx231xx dvb Extension",
+	.init = dvb_init,
+	.fini = dvb_fini,
+};
+
+static int __init cx231xx_dvb_register(void)
+{
+	return cx231xx_register_extension(&dvb_ops);
+}
+
+static void __exit cx231xx_dvb_unregister(void)
+{
+	cx231xx_unregister_extension(&dvb_ops);
+}
+
+module_init(cx231xx_dvb_register);
+module_exit(cx231xx_dvb_unregister);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx.h linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,779 @@
+/*
+   cx231xx.h - driver for Conexant Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+	Based on em28xx 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _CX231XX_H
+#define _CX231XX_H
+
+#include <linux/videodev2.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+
+
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/ir-kbd-i2c.h>
+#if defined(CONFIG_VIDEO_CX231XX_DVB) || \
+	defined(CONFIG_VIDEO_CX231XX_DVB_MODULE)
+#include <media/videobuf-dvb.h>
+#endif
+
+#include "cx231xx-reg.h"
+#include "cx231xx-pcb-cfg.h"
+#include "cx231xx-conf-reg.h"
+
+#define DRIVER_NAME                     "cx231xx"
+#define PWR_SLEEP_INTERVAL              5
+
+/* I2C addresses for control block in Cx231xx */
+#define     AFE_DEVICE_ADDRESS		0x60
+#define     I2S_BLK_DEVICE_ADDRESS	0x98
+#define     VID_BLK_I2C_ADDRESS		0x88
+#define     DIF_USE_BASEBAND            0xFFFFFFFF
+
+/* Boards supported by driver */
+#define CX231XX_BOARD_UNKNOWN		    0
+#define CX231XX_BOARD_CNXT_RDE_250     	1
+#define CX231XX_BOARD_CNXT_RDU_250     	2
+
+/* Limits minimum and default number of buffers */
+#define CX231XX_MIN_BUF                 4
+#define CX231XX_DEF_BUF                 12
+#define CX231XX_DEF_VBI_BUF             6
+
+#define VBI_LINE_COUNT                  17
+#define VBI_LINE_LENGTH                 1440
+
+/*Limits the max URB message size */
+#define URB_MAX_CTRL_SIZE               80
+
+/* Params for validated field */
+#define CX231XX_BOARD_NOT_VALIDATED     1
+#define CX231XX_BOARD_VALIDATED		0
+
+/* maximum number of cx231xx boards */
+#define CX231XX_MAXBOARDS               8
+
+/* maximum number of frames that can be queued */
+#define CX231XX_NUM_FRAMES              5
+
+/* number of buffers for isoc transfers */
+#define CX231XX_NUM_BUFS                8
+
+/* number of packets for each buffer
+   windows requests only 40 packets .. so we better do the same
+   this is what I found out for all alternate numbers there!
+ */
+#define CX231XX_NUM_PACKETS             40
+
+/* default alternate; 0 means choose the best */
+#define CX231XX_PINOUT                  0
+
+#define CX231XX_INTERLACED_DEFAULT      1
+
+/* time to wait when stopping the isoc transfer */
+#define CX231XX_URB_TIMEOUT		\
+		msecs_to_jiffies(CX231XX_NUM_BUFS * CX231XX_NUM_PACKETS)
+
+enum cx231xx_mode {
+	CX231XX_SUSPEND,
+	CX231XX_ANALOG_MODE,
+	CX231XX_DIGITAL_MODE,
+};
+
+enum cx231xx_std_mode {
+	CX231XX_TV_AIR = 0,
+	CX231XX_TV_CABLE
+};
+
+enum cx231xx_stream_state {
+	STREAM_OFF,
+	STREAM_INTERRUPT,
+	STREAM_ON,
+};
+
+struct cx231xx;
+
+struct cx231xx_usb_isoc_ctl {
+	/* max packet size of isoc transaction */
+	int max_pkt_size;
+
+	/* number of allocated urbs */
+	int num_bufs;
+
+	/* urb for isoc transfers */
+	struct urb **urb;
+
+	/* transfer buffers for isoc transfer */
+	char **transfer_buffer;
+
+	/* Last buffer command and region */
+	u8 cmd;
+	int pos, size, pktsize;
+
+	/* Last field: ODD or EVEN? */
+	int field;
+
+	/* Stores incomplete commands */
+	u32 tmp_buf;
+	int tmp_buf_len;
+
+	/* Stores already requested buffers */
+	struct cx231xx_buffer *buf;
+
+	/* Stores the number of received fields */
+	int nfields;
+
+	/* isoc urb callback */
+	int (*isoc_copy) (struct cx231xx *dev, struct urb *urb);
+};
+
+struct cx231xx_fmt {
+	char *name;
+	u32 fourcc;		/* v4l2 format id */
+	int depth;
+	int reg;
+};
+
+/* buffer for one video frame */
+struct cx231xx_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+
+	struct list_head frame;
+	int top_field;
+	int receiving;
+};
+
+struct cx231xx_dmaqueue {
+	struct list_head active;
+	struct list_head queued;
+
+	wait_queue_head_t wq;
+
+	/* Counters to control buffer fill */
+	int pos;
+	u8 is_partial_line;
+	u8 partial_buf[8];
+	u8 last_sav;
+	int current_field;
+	u32 bytes_left_in_line;
+	u32 lines_completed;
+	u8 field1_done;
+	u32 lines_per_field;
+};
+
+/* inputs */
+
+#define MAX_CX231XX_INPUT               4
+
+enum cx231xx_itype {
+	CX231XX_VMUX_COMPOSITE1 = 1,
+	CX231XX_VMUX_SVIDEO,
+	CX231XX_VMUX_TELEVISION,
+	CX231XX_VMUX_CABLE,
+	CX231XX_RADIO,
+	CX231XX_VMUX_DVB,
+	CX231XX_VMUX_DEBUG
+};
+
+enum cx231xx_v_input {
+	CX231XX_VIN_1_1 = 0x1,
+	CX231XX_VIN_2_1,
+	CX231XX_VIN_3_1,
+	CX231XX_VIN_4_1,
+	CX231XX_VIN_1_2 = 0x01,
+	CX231XX_VIN_2_2,
+	CX231XX_VIN_3_2,
+	CX231XX_VIN_1_3 = 0x1,
+	CX231XX_VIN_2_3,
+	CX231XX_VIN_3_3,
+};
+
+/* cx231xx has two audio inputs: tuner and line in */
+enum cx231xx_amux {
+	/* This is the only entry for cx231xx tuner input */
+	CX231XX_AMUX_VIDEO,	/* cx231xx tuner */
+	CX231XX_AMUX_LINE_IN,	/* Line In */
+};
+
+struct cx231xx_reg_seq {
+	unsigned char bit;
+	unsigned char val;
+	int sleep;
+};
+
+struct cx231xx_input {
+	enum cx231xx_itype type;
+	unsigned int vmux;
+	enum cx231xx_amux amux;
+	struct cx231xx_reg_seq *gpio;
+};
+
+#define INPUT(nr) (&cx231xx_boards[dev->model].input[nr])
+
+enum cx231xx_decoder {
+	CX231XX_NODECODER,
+	CX231XX_AVDECODER
+};
+
+enum CX231XX_I2C_MASTER_PORT {
+	I2C_0 = 0,
+	I2C_1 = 1,
+	I2C_2 = 2,
+	I2C_3 = 3
+};
+
+struct cx231xx_board {
+	char *name;
+	int vchannels;
+	int tuner_type;
+	int tuner_addr;
+	v4l2_std_id norm;	/* tv norm */
+
+	/* demod related */
+	int demod_addr;
+	u8 demod_xfer_mode;	/* 0 - Serial; 1 - parallel */
+
+	/* GPIO Pins */
+	struct cx231xx_reg_seq *dvb_gpio;
+	struct cx231xx_reg_seq *suspend_gpio;
+	struct cx231xx_reg_seq *tuner_gpio;
+	u8 tuner_sif_gpio;
+	u8 tuner_scl_gpio;
+	u8 tuner_sda_gpio;
+
+	/* PIN ctrl */
+	u32 ctl_pin_status_mask;
+	u8 agc_analog_digital_select_gpio;
+	u32 gpio_pin_status_mask;
+
+	/* i2c masters */
+	u8 tuner_i2c_master;
+	u8 demod_i2c_master;
+
+	unsigned int max_range_640_480:1;
+	unsigned int has_dvb:1;
+	unsigned int valid:1;
+
+	unsigned char xclk, i2c_speed;
+
+	enum cx231xx_decoder decoder;
+
+	struct cx231xx_input input[MAX_CX231XX_INPUT];
+	struct cx231xx_input radio;
+	IR_KEYTAB_TYPE *ir_codes;
+};
+
+/* device states */
+enum cx231xx_dev_state {
+	DEV_INITIALIZED = 0x01,
+	DEV_DISCONNECTED = 0x02,
+	DEV_MISCONFIGURED = 0x04,
+};
+
+enum AFE_MODE {
+	AFE_MODE_LOW_IF,
+	AFE_MODE_BASEBAND,
+	AFE_MODE_EU_HI_IF,
+	AFE_MODE_US_HI_IF,
+	AFE_MODE_JAPAN_HI_IF
+};
+
+enum AUDIO_INPUT {
+	AUDIO_INPUT_MUTE,
+	AUDIO_INPUT_LINE,
+	AUDIO_INPUT_TUNER_TV,
+	AUDIO_INPUT_SPDIF,
+	AUDIO_INPUT_TUNER_FM
+};
+
+#define CX231XX_AUDIO_BUFS              5
+#define CX231XX_NUM_AUDIO_PACKETS       64
+#define CX231XX_CAPTURE_STREAM_EN       1
+#define CX231XX_STOP_AUDIO              0
+#define CX231XX_START_AUDIO             1
+
+/* cx231xx extensions */
+#define CX231XX_AUDIO                   0x10
+#define CX231XX_DVB                     0x20
+
+struct cx231xx_audio {
+	char name[50];
+	char *transfer_buffer[CX231XX_AUDIO_BUFS];
+	struct urb *urb[CX231XX_AUDIO_BUFS];
+	struct usb_device *udev;
+	unsigned int capture_transfer_done;
+	struct snd_pcm_substream *capture_pcm_substream;
+
+	unsigned int hwptr_done_capture;
+	struct snd_card *sndcard;
+
+	int users, shutdown;
+	enum cx231xx_stream_state capture_stream;
+	spinlock_t slock;
+
+	int alt;		/* alternate */
+	int max_pkt_size;	/* max packet size of isoc transaction */
+	int num_alt;		/* Number of alternative settings */
+	unsigned int *alt_max_pkt_size;	/* array of wMaxPacketSize */
+	u16 end_point_addr;
+};
+
+struct cx231xx;
+
+struct cx231xx_fh {
+	struct cx231xx *dev;
+	unsigned int stream_on:1;	/* Locks streams */
+	int radio;
+
+	struct videobuf_queue vb_vidq;
+
+	enum v4l2_buf_type type;
+};
+
+/*****************************************************************/
+/* set/get i2c */
+/* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */
+#define I2C_SPEED_1M            0x0
+#define I2C_SPEED_400K          0x1
+#define I2C_SPEED_100K          0x2
+#define I2C_SPEED_5M            0x3
+
+/* 0-- STOP transaction */
+#define I2C_STOP                0x0
+/* 1-- do not transmit STOP at end of transaction */
+#define I2C_NOSTOP              0x1
+/* 1--alllow slave to insert clock wait states */
+#define I2C_SYNC                0x1
+
+struct cx231xx_i2c {
+	struct cx231xx *dev;
+
+	int nr;
+
+	/* i2c i/o */
+	struct i2c_adapter i2c_adap;
+	struct i2c_algo_bit_data i2c_algo;
+	struct i2c_client i2c_client;
+	u32 i2c_rc;
+
+	/* different settings for each bus */
+	u8 i2c_period;
+	u8 i2c_nostop;
+	u8 i2c_reserve;
+};
+
+struct cx231xx_i2c_xfer_data {
+	u8 dev_addr;
+	u8 direction;		/* 1 - IN, 0 - OUT */
+	u8 saddr_len;		/* sub address len */
+	u16 saddr_dat;		/* sub addr data */
+	u8 buf_size;		/* buffer size */
+	u8 *p_buffer;		/* pointer to the buffer */
+};
+
+struct VENDOR_REQUEST_IN {
+	u8 bRequest;
+	u16 wValue;
+	u16 wIndex;
+	u16 wLength;
+	u8 direction;
+	u8 bData;
+	u8 *pBuff;
+};
+
+struct cx231xx_ctrl {
+	struct v4l2_queryctrl v;
+	u32 off;
+	u32 reg;
+	u32 mask;
+	u32 shift;
+};
+
+enum TRANSFER_TYPE {
+	Raw_Video = 0,
+	Audio,
+	Vbi,			/* VANC */
+	Sliced_cc,		/* HANC */
+	TS1_serial_mode,
+	TS2,
+	TS1_parallel_mode
+} ;
+
+struct cx231xx_video_mode {
+	/* Isoc control struct */
+	struct cx231xx_dmaqueue vidq;
+	struct cx231xx_usb_isoc_ctl isoc_ctl;
+	spinlock_t slock;
+
+	/* usb transfer */
+	int alt;		/* alternate */
+	int max_pkt_size;	/* max packet size of isoc transaction */
+	int num_alt;		/* Number of alternative settings */
+	unsigned int *alt_max_pkt_size;	/* array of wMaxPacketSize */
+	u16 end_point_addr;
+};
+
+/* main device struct */
+struct cx231xx {
+	/* generic device properties */
+	char name[30];		/* name (including minor) of the device */
+	int model;		/* index in the device_data struct */
+	int devno;		/* marks the number of this device */
+
+	struct cx231xx_board board;
+
+	unsigned int stream_on:1;	/* Locks streams */
+	unsigned int vbi_stream_on:1;	/* Locks streams for VBI */
+	unsigned int has_audio_class:1;
+	unsigned int has_alsa_audio:1;
+
+	struct cx231xx_fmt *format;
+
+	struct v4l2_device v4l2_dev;
+	struct v4l2_subdev *sd_cx25840;
+	struct v4l2_subdev *sd_tuner;
+
+	struct cx231xx_IR *ir;
+
+	struct list_head devlist;
+
+	int tuner_type;		/* type of the tuner */
+	int tuner_addr;		/* tuner address */
+
+	/* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
+	struct cx231xx_i2c i2c_bus[3];
+	unsigned int xc_fw_load_done:1;
+	struct mutex gpio_i2c_lock;
+
+	/* video for linux */
+	int users;		/* user count for exclusive use */
+	struct video_device *vdev;	/* video for linux device struct */
+	v4l2_std_id norm;	/* selected tv norm */
+	int ctl_freq;		/* selected frequency */
+	unsigned int ctl_ainput;	/* selected audio input */
+	int mute;
+	int volume;
+
+	/* frame properties */
+	int width;		/* current frame width */
+	int height;		/* current frame height */
+	unsigned hscale;	/* horizontal scale factor (see datasheet) */
+	unsigned vscale;	/* vertical scale factor (see datasheet) */
+	int interlaced;		/* 1=interlace fileds, 0=just top fileds */
+
+	struct cx231xx_audio adev;
+
+	/* states */
+	enum cx231xx_dev_state state;
+
+	struct work_struct request_module_wk;
+
+	/* locks */
+	struct mutex lock;
+	struct mutex ctrl_urb_lock;	/* protects urb_buf */
+	struct list_head inqueue, outqueue;
+	wait_queue_head_t open, wait_frame, wait_stream;
+	struct video_device *vbi_dev;
+	struct video_device *radio_dev;
+
+	unsigned char eedata[256];
+
+	struct cx231xx_video_mode video_mode;
+	struct cx231xx_video_mode vbi_mode;
+	struct cx231xx_video_mode sliced_cc_mode;
+	struct cx231xx_video_mode ts1_mode;
+
+	struct usb_device *udev;	/* the usb device */
+	char urb_buf[URB_MAX_CTRL_SIZE];	/* urb control msg buffer */
+
+	/* helper funcs that call usb_control_msg */
+	int (*cx231xx_read_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
+				      char *buf, int len);
+	int (*cx231xx_write_ctrl_reg) (struct cx231xx *dev, u8 req, u16 reg,
+				       char *buf, int len);
+	int (*cx231xx_send_usb_command) (struct cx231xx_i2c *i2c_bus,
+				struct cx231xx_i2c_xfer_data *req_data);
+	int (*cx231xx_gpio_i2c_read) (struct cx231xx *dev, u8 dev_addr,
+				      u8 *buf, u8 len);
+	int (*cx231xx_gpio_i2c_write) (struct cx231xx *dev, u8 dev_addr,
+				       u8 *buf, u8 len);
+
+	int (*cx231xx_set_analog_freq) (struct cx231xx *dev, u32 freq);
+	int (*cx231xx_reset_analog_tuner) (struct cx231xx *dev);
+
+	enum cx231xx_mode mode;
+
+	struct cx231xx_dvb *dvb;
+
+	/* Cx231xx supported PCB config's */
+	struct pcb_config current_pcb_config;
+	u8 current_scenario_idx;
+	u8 interface_count;
+	u8 max_iad_interface_count;
+
+	/* GPIO related register direction and values */
+	u32 gpio_dir;
+	u32 gpio_val;
+
+	/* Power Modes */
+	int power_mode;
+
+	/* afe parameters */
+	enum AFE_MODE afe_mode;
+	u32 afe_ref_count;
+
+	/* video related parameters */
+	u32 video_input;
+	u32 active_mode;
+	u8 vbi_or_sliced_cc_mode;	/* 0 - vbi ; 1 - sliced cc mode */
+	enum cx231xx_std_mode std_mode;	/* 0 - Air; 1 - cable */
+
+};
+
+#define cx25840_call(cx231xx, o, f, args...) \
+	v4l2_subdev_call(cx231xx->sd_cx25840, o, f, ##args)
+#define tuner_call(cx231xx, o, f, args...) \
+	v4l2_subdev_call(cx231xx->sd_tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
+
+struct cx231xx_ops {
+	struct list_head next;
+	char *name;
+	int id;
+	int (*init) (struct cx231xx *);
+	int (*fini) (struct cx231xx *);
+};
+
+/* call back functions in dvb module */
+int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq);
+int cx231xx_reset_analog_tuner(struct cx231xx *dev);
+
+/* Provided by cx231xx-i2c.c */
+void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c);
+int cx231xx_i2c_register(struct cx231xx_i2c *bus);
+int cx231xx_i2c_unregister(struct cx231xx_i2c *bus);
+
+/* Internal block control functions */
+int cx231xx_read_i2c_data(struct cx231xx *dev, u8 dev_addr,
+			  u16 saddr, u8 saddr_len, u32 *data, u8 data_len);
+int cx231xx_write_i2c_data(struct cx231xx *dev, u8 dev_addr,
+			   u16 saddr, u8 saddr_len, u32 data, u8 data_len);
+int cx231xx_reg_mask_write(struct cx231xx *dev, u8 dev_addr, u8 size,
+			   u16 register_address, u8 bit_start, u8 bit_end,
+			   u32 value);
+int cx231xx_read_modify_write_i2c_dword(struct cx231xx *dev, u8 dev_addr,
+					u16 saddr, u32 mask, u32 value);
+u32 cx231xx_set_field(u32 field_mask, u32 data);
+
+/* afe related functions */
+int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count);
+int cx231xx_afe_init_channels(struct cx231xx *dev);
+int cx231xx_afe_setup_AFE_for_baseband(struct cx231xx *dev);
+int cx231xx_afe_set_input_mux(struct cx231xx *dev, u32 input_mux);
+int cx231xx_afe_set_mode(struct cx231xx *dev, enum AFE_MODE mode);
+int cx231xx_afe_update_power_control(struct cx231xx *dev,
+					enum AV_MODE avmode);
+int cx231xx_afe_adjust_ref_count(struct cx231xx *dev, u32 video_input);
+
+/* i2s block related functions */
+int cx231xx_i2s_blk_initialize(struct cx231xx *dev);
+int cx231xx_i2s_blk_update_power_control(struct cx231xx *dev,
+					enum AV_MODE avmode);
+int cx231xx_i2s_blk_set_audio_input(struct cx231xx *dev, u8 audio_input);
+
+/* DIF related functions */
+int cx231xx_dif_configure_C2HH_for_low_IF(struct cx231xx *dev, u32 mode,
+					  u32 function_mode, u32 standard);
+int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard);
+int cx231xx_tuner_pre_channel_change(struct cx231xx *dev);
+int cx231xx_tuner_post_channel_change(struct cx231xx *dev);
+
+/* video parser functions */
+u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size,
+			     u32 *p_bytes_used);
+u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
+				 u32 *p_bytes_used);
+int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+		    u8 *p_buffer, u32 bytes_to_copy);
+void cx231xx_reset_video_buffer(struct cx231xx *dev,
+				struct cx231xx_dmaqueue *dma_q);
+u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q);
+u32 cx231xx_copy_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			    u8 *p_line, u32 length, int field_number);
+u32 cx231xx_get_video_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			   u8 sav_eav, u8 *p_buffer, u32 buffer_size);
+void cx231xx_swab(u16 *from, u16 *to, u16 len);
+
+/* Provided by cx231xx-core.c */
+
+u32 cx231xx_request_buffers(struct cx231xx *dev, u32 count);
+void cx231xx_queue_unusedframes(struct cx231xx *dev);
+void cx231xx_release_buffers(struct cx231xx *dev);
+
+/* read from control pipe */
+int cx231xx_read_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+			  char *buf, int len);
+
+/* write to control pipe */
+int cx231xx_write_ctrl_reg(struct cx231xx *dev, u8 req, u16 reg,
+			   char *buf, int len);
+int cx231xx_mode_register(struct cx231xx *dev, u16 address, u32 mode);
+
+int cx231xx_send_vendor_cmd(struct cx231xx *dev,
+				struct VENDOR_REQUEST_IN *ven_req);
+int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus,
+				struct cx231xx_i2c_xfer_data *req_data);
+
+/* Gpio related functions */
+int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val,
+			  u8 len, u8 request, u8 direction);
+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val);
+int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value);
+int cx231xx_set_gpio_direction(struct cx231xx *dev, int pin_number,
+			       int pin_value);
+
+int cx231xx_gpio_i2c_start(struct cx231xx *dev);
+int cx231xx_gpio_i2c_end(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_byte(struct cx231xx *dev, u8 data);
+int cx231xx_gpio_i2c_read_byte(struct cx231xx *dev, u8 *buf);
+int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_ack(struct cx231xx *dev);
+int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev);
+
+int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
+int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len);
+
+/* audio related functions */
+int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
+				    enum AUDIO_INPUT audio_input);
+
+int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
+int cx231xx_resolution_set(struct cx231xx *dev);
+int cx231xx_set_video_alternate(struct cx231xx *dev);
+int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
+int cx231xx_init_isoc(struct cx231xx *dev, int max_packets,
+		      int num_bufs, int max_pkt_size,
+		      int (*isoc_copy) (struct cx231xx *dev,
+					struct urb *urb));
+void cx231xx_uninit_isoc(struct cx231xx *dev);
+int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode);
+int cx231xx_gpio_set(struct cx231xx *dev, struct cx231xx_reg_seq *gpio);
+
+/* Device list functions */
+void cx231xx_release_resources(struct cx231xx *dev);
+void cx231xx_release_analog_resources(struct cx231xx *dev);
+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);
+
+/* hardware init functions */
+int cx231xx_dev_init(struct cx231xx *dev);
+void cx231xx_dev_uninit(struct cx231xx *dev);
+void cx231xx_config_i2c(struct cx231xx *dev);
+int cx231xx_config(struct cx231xx *dev);
+
+/* Stream control functions */
+int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask);
+int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask);
+
+int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type);
+
+/* Power control functions */
+int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode);
+int cx231xx_power_suspend(struct cx231xx *dev);
+
+/* chip specific control functions */
+int cx231xx_init_ctrl_pin_status(struct cx231xx *dev);
+int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
+					      u8 analog_or_digital);
+int cx231xx_enable_i2c_for_tuner(struct cx231xx *dev, u8 I2CIndex);
+
+/* video audio decoder related functions */
+void video_mux(struct cx231xx *dev, int index);
+int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input);
+int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input);
+int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev);
+int cx231xx_set_audio_input(struct cx231xx *dev, u8 input);
+void get_scale(struct cx231xx *dev,
+	       unsigned int width, unsigned int height,
+	       unsigned int *hscale, unsigned int *vscale);
+
+/* Provided by cx231xx-video.c */
+int cx231xx_register_extension(struct cx231xx_ops *dev);
+void cx231xx_unregister_extension(struct cx231xx_ops *dev);
+void cx231xx_init_extension(struct cx231xx *dev);
+void cx231xx_close_extension(struct cx231xx *dev);
+
+/* Provided by cx231xx-cards.c */
+extern void cx231xx_pre_card_setup(struct cx231xx *dev);
+extern void cx231xx_card_setup(struct cx231xx *dev);
+extern struct cx231xx_board cx231xx_boards[];
+extern struct usb_device_id cx231xx_id_table[];
+extern const unsigned int cx231xx_bcount;
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
+int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
+
+/* Provided by cx231xx-input.c */
+int cx231xx_ir_init(struct cx231xx *dev);
+int cx231xx_ir_fini(struct cx231xx *dev);
+
+/* printk macros */
+
+#define cx231xx_err(fmt, arg...) do {\
+	printk(KERN_ERR fmt , ##arg); } while (0)
+
+#define cx231xx_errdev(fmt, arg...) do {\
+	printk(KERN_ERR "%s: "fmt,\
+			dev->name , ##arg); } while (0)
+
+#define cx231xx_info(fmt, arg...) do {\
+	printk(KERN_INFO "%s: "fmt,\
+			dev->name , ##arg); } while (0)
+#define cx231xx_warn(fmt, arg...) do {\
+	printk(KERN_WARNING "%s: "fmt,\
+			dev->name , ##arg); } while (0)
+
+static inline unsigned int norm_maxw(struct cx231xx *dev)
+{
+	if (dev->board.max_range_640_480)
+		return 640;
+	else
+		return 720;
+}
+
+static inline unsigned int norm_maxh(struct cx231xx *dev)
+{
+	if (dev->board.max_range_640_480)
+		return 480;
+	else
+		return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,555 @@
+/*
+   cx231xx-i2c.c - driver for Conexant Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+		Based on em28xx driver
+		Based on Cx23885 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <media/v4l2-common.h>
+#include <media/tuner.h>
+
+#include "cx231xx.h"
+
+/* ----------------------------------------------------------- */
+
+static unsigned int i2c_scan;
+module_param(i2c_scan, int, 0444);
+MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
+
+static unsigned int i2c_debug;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+#define dprintk1(lvl, fmt, args...)			\
+do {							\
+	if (i2c_debug >= lvl) {				\
+		printk(fmt, ##args);			\
+		}					\
+} while (0)
+
+#define dprintk2(lvl, fmt, args...)			\
+do {							\
+	if (i2c_debug >= lvl) {				\
+		printk(KERN_DEBUG "%s at %s: " fmt,	\
+		       dev->name, __func__ , ##args);	\
+      } 						\
+} while (0)
+
+/*
+ * cx231xx_i2c_send_bytes()
+ */
+int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
+			   const struct i2c_msg *msg)
+{
+	struct cx231xx_i2c *bus = i2c_adap->algo_data;
+	struct cx231xx *dev = bus->dev;
+	struct cx231xx_i2c_xfer_data req_data;
+	int status = 0;
+	u16 size = 0;
+	u8 loop = 0;
+	u8 saddr_len = 1;
+	u8 *buf_ptr = NULL;
+	u16 saddr = 0;
+	u8 need_gpio = 0;
+
+	if ((bus->nr == 1) && (msg->addr == 0x61)
+	    && (dev->tuner_type == TUNER_XC5000)) {
+
+		size = msg->len;
+
+		if (size == 2) {	/* register write sub addr */
+			/* Just writing sub address will cause problem
+			* to XC5000. So ignore the request */
+			return 0;
+		} else if (size == 4) {	/* register write with sub addr */
+			if (msg->len >= 2)
+				saddr = msg->buf[0] << 8 | msg->buf[1];
+			else if (msg->len == 1)
+				saddr = msg->buf[0];
+
+			switch (saddr) {
+			case 0x0000:	/* start tuner calibration mode */
+				need_gpio = 1;
+				/* FW Loading is done */
+				dev->xc_fw_load_done = 1;
+				break;
+			case 0x000D:	/* Set signal source */
+			case 0x0001:	/* Set TV standard - Video */
+			case 0x0002:	/* Set TV standard - Audio */
+			case 0x0003:	/* Set RF Frequency */
+				need_gpio = 1;
+				break;
+			default:
+				if (dev->xc_fw_load_done)
+					need_gpio = 1;
+				break;
+			}
+
+			if (need_gpio) {
+				dprintk1(1,
+				"GPIO WRITE: addr 0x%x, len %d, saddr 0x%x\n",
+				msg->addr, msg->len, saddr);
+
+				return dev->cx231xx_gpio_i2c_write(dev,
+								   msg->addr,
+								   msg->buf,
+								   msg->len);
+			}
+		}
+
+		/* special case for Xc5000 tuner case */
+		saddr_len = 1;
+
+		/* adjust the length to correct length */
+		size -= saddr_len;
+		buf_ptr = (u8 *) (msg->buf + 1);
+
+		do {
+			/* prepare xfer_data struct */
+			req_data.dev_addr = msg->addr;
+			req_data.direction = msg->flags;
+			req_data.saddr_len = saddr_len;
+			req_data.saddr_dat = msg->buf[0];
+			req_data.buf_size = size > 16 ? 16 : size;
+			req_data.p_buffer = (u8 *) (buf_ptr + loop * 16);
+
+			bus->i2c_nostop = (size > 16) ? 1 : 0;
+			bus->i2c_reserve = (loop == 0) ? 0 : 1;
+
+			/* usb send command */
+			status = dev->cx231xx_send_usb_command(bus, &req_data);
+			loop++;
+
+			if (size >= 16)
+				size -= 16;
+			else
+				size = 0;
+
+		} while (size > 0);
+
+		bus->i2c_nostop = 0;
+		bus->i2c_reserve = 0;
+
+	} else {		/* regular case */
+
+		/* prepare xfer_data struct */
+		req_data.dev_addr = msg->addr;
+		req_data.direction = msg->flags;
+		req_data.saddr_len = 0;
+		req_data.saddr_dat = 0;
+		req_data.buf_size = msg->len;
+		req_data.p_buffer = msg->buf;
+
+		/* usb send command */
+		status = dev->cx231xx_send_usb_command(bus, &req_data);
+	}
+
+	return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_recv_bytes()
+ * read a byte from the i2c device
+ */
+static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
+				  const struct i2c_msg *msg)
+{
+	struct cx231xx_i2c *bus = i2c_adap->algo_data;
+	struct cx231xx *dev = bus->dev;
+	struct cx231xx_i2c_xfer_data req_data;
+	int status = 0;
+	u16 saddr = 0;
+	u8 need_gpio = 0;
+
+	if ((bus->nr == 1) && (msg->addr == 0x61)
+	    && dev->tuner_type == TUNER_XC5000) {
+
+		if (msg->len == 2)
+			saddr = msg->buf[0] << 8 | msg->buf[1];
+		else if (msg->len == 1)
+			saddr = msg->buf[0];
+
+		if (dev->xc_fw_load_done) {
+
+			switch (saddr) {
+			case 0x0009:	/* BUSY check */
+				dprintk1(1,
+				"GPIO R E A D: Special case BUSY check \n");
+				/*Try read BUSY register, just set it to zero*/
+				msg->buf[0] = 0;
+				if (msg->len == 2)
+					msg->buf[1] = 0;
+				return 0;
+			case 0x0004:	/* read Lock status */
+				need_gpio = 1;
+				break;
+
+			}
+
+			if (need_gpio) {
+				/* this is a special case to handle Xceive tuner
+				clock stretch issue with gpio based I2C */
+
+				dprintk1(1,
+				"GPIO R E A D: addr 0x%x, len %d, saddr 0x%x\n",
+				msg->addr, msg->len,
+				msg->buf[0] << 8 | msg->buf[1]);
+
+				status =
+				    dev->cx231xx_gpio_i2c_write(dev, msg->addr,
+								msg->buf,
+								msg->len);
+				status =
+				    dev->cx231xx_gpio_i2c_read(dev, msg->addr,
+							       msg->buf,
+							       msg->len);
+				return status;
+			}
+		}
+
+		/* prepare xfer_data struct */
+		req_data.dev_addr = msg->addr;
+		req_data.direction = msg->flags;
+		req_data.saddr_len = msg->len;
+		req_data.saddr_dat = msg->buf[0] << 8 | msg->buf[1];
+		req_data.buf_size = msg->len;
+		req_data.p_buffer = msg->buf;
+
+		/* usb send command */
+		status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+	} else {
+
+		/* prepare xfer_data struct */
+		req_data.dev_addr = msg->addr;
+		req_data.direction = msg->flags;
+		req_data.saddr_len = 0;
+		req_data.saddr_dat = 0;
+		req_data.buf_size = msg->len;
+		req_data.p_buffer = msg->buf;
+
+		/* usb send command */
+		status = dev->cx231xx_send_usb_command(bus, &req_data);
+	}
+
+	return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_recv_bytes_with_saddr()
+ * read a byte from the i2c device
+ */
+static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
+					     const struct i2c_msg *msg1,
+					     const struct i2c_msg *msg2)
+{
+	struct cx231xx_i2c *bus = i2c_adap->algo_data;
+	struct cx231xx *dev = bus->dev;
+	struct cx231xx_i2c_xfer_data req_data;
+	int status = 0;
+	u16 saddr = 0;
+	u8 need_gpio = 0;
+
+	if (msg1->len == 2)
+		saddr = msg1->buf[0] << 8 | msg1->buf[1];
+	else if (msg1->len == 1)
+		saddr = msg1->buf[0];
+
+	if ((bus->nr == 1) && (msg2->addr == 0x61)
+	    && dev->tuner_type == TUNER_XC5000) {
+
+		if ((msg2->len < 16)) {
+
+			dprintk1(1,
+			"i2c_read: addr 0x%x, len %d, saddr 0x%x, len %d\n",
+			msg2->addr, msg2->len, saddr, msg1->len);
+
+			switch (saddr) {
+			case 0x0008:	/* read FW load status */
+				need_gpio = 1;
+				break;
+			case 0x0004:	/* read Lock status */
+				need_gpio = 1;
+				break;
+			}
+
+			if (need_gpio) {
+				status =
+				    dev->cx231xx_gpio_i2c_write(dev, msg1->addr,
+								msg1->buf,
+								msg1->len);
+				status =
+				    dev->cx231xx_gpio_i2c_read(dev, msg2->addr,
+							       msg2->buf,
+							       msg2->len);
+				return status;
+			}
+		}
+	}
+
+	/* prepare xfer_data struct */
+	req_data.dev_addr = msg2->addr;
+	req_data.direction = msg2->flags;
+	req_data.saddr_len = msg1->len;
+	req_data.saddr_dat = saddr;
+	req_data.buf_size = msg2->len;
+	req_data.p_buffer = msg2->buf;
+
+	/* usb send command */
+	status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+	return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_check_for_device()
+ * check if there is a i2c_device at the supplied address
+ */
+static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap,
+					const struct i2c_msg *msg)
+{
+	struct cx231xx_i2c *bus = i2c_adap->algo_data;
+	struct cx231xx *dev = bus->dev;
+	struct cx231xx_i2c_xfer_data req_data;
+	int status = 0;
+
+	/* prepare xfer_data struct */
+	req_data.dev_addr = msg->addr;
+	req_data.direction = msg->flags;
+	req_data.saddr_len = 0;
+	req_data.saddr_dat = 0;
+	req_data.buf_size = 0;
+	req_data.p_buffer = NULL;
+
+	/* usb send command */
+	status = dev->cx231xx_send_usb_command(bus, &req_data);
+
+	return status < 0 ? status : 0;
+}
+
+/*
+ * cx231xx_i2c_xfer()
+ * the main i2c transfer function
+ */
+static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap,
+			    struct i2c_msg msgs[], int num)
+{
+	struct cx231xx_i2c *bus = i2c_adap->algo_data;
+	struct cx231xx *dev = bus->dev;
+	int addr, rc, i, byte;
+
+	if (num <= 0)
+		return 0;
+
+	for (i = 0; i < num; i++) {
+
+		addr = msgs[i].addr >> 1;
+
+		dprintk2(2, "%s %s addr=%x len=%d:",
+			 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
+			 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
+		if (!msgs[i].len) {
+			/* no len: check only for device presence */
+			rc = cx231xx_i2c_check_for_device(i2c_adap, &msgs[i]);
+			if (rc < 0) {
+				dprintk2(2, " no device\n");
+				return rc;
+			}
+
+		} else if (msgs[i].flags & I2C_M_RD) {
+			/* read bytes */
+			rc = cx231xx_i2c_recv_bytes(i2c_adap, &msgs[i]);
+			if (i2c_debug >= 2) {
+				for (byte = 0; byte < msgs[i].len; byte++)
+					printk(" %02x", msgs[i].buf[byte]);
+			}
+		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
+			   msgs[i].addr == msgs[i + 1].addr
+			   && (msgs[i].len <= 2) && (bus->nr < 2)) {
+			/* read bytes */
+			rc = cx231xx_i2c_recv_bytes_with_saddr(i2c_adap,
+							       &msgs[i],
+							       &msgs[i + 1]);
+			if (i2c_debug >= 2) {
+				for (byte = 0; byte < msgs[i].len; byte++)
+					printk(" %02x", msgs[i].buf[byte]);
+			}
+			i++;
+		} else {
+			/* write bytes */
+			if (i2c_debug >= 2) {
+				for (byte = 0; byte < msgs[i].len; byte++)
+					printk(" %02x", msgs[i].buf[byte]);
+			}
+			rc = cx231xx_i2c_send_bytes(i2c_adap, &msgs[i]);
+		}
+		if (rc < 0)
+			goto err;
+		if (i2c_debug >= 2)
+			printk("\n");
+	}
+
+	return num;
+err:
+	dprintk2(2, " ERROR: %i\n", rc);
+	return rc;
+}
+
+/* ----------------------------------------------------------- */
+
+/*
+ * functionality()
+ */
+static u32 functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
+}
+
+/*
+ * attach_inform()
+ * gets called when a device attaches to the i2c bus
+ * does some basic configuration
+ */
+static int attach_inform(struct i2c_client *client)
+{
+	struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
+	struct cx231xx *dev = bus->dev;
+
+	switch (client->addr << 1) {
+	case 0x8e:
+		{
+			struct IR_i2c *ir = i2c_get_clientdata(client);
+			dprintk1(1, "attach_inform: IR detected (%s).\n",
+				 ir->phys);
+			cx231xx_set_ir(dev, ir);
+			break;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static struct i2c_algorithm cx231xx_algo = {
+	.master_xfer = cx231xx_i2c_xfer,
+	.functionality = functionality,
+};
+
+static struct i2c_adapter cx231xx_adap_template = {
+	.owner = THIS_MODULE,
+	.name = "cx231xx",
+	.id = I2C_HW_B_CX231XX,
+	.algo = &cx231xx_algo,
+	.client_register = attach_inform,
+};
+
+static struct i2c_client cx231xx_client_template = {
+	.name = "cx231xx internal",
+};
+
+/* ----------------------------------------------------------- */
+
+/*
+ * i2c_devs
+ * incomplete list of known devices
+ */
+static char *i2c_devs[128] = {
+	[0x60 >> 1] = "colibri",
+	[0x88 >> 1] = "hammerhead",
+	[0x8e >> 1] = "CIR",
+	[0x32 >> 1] = "GeminiIII",
+	[0x02 >> 1] = "Aquarius",
+	[0xa0 >> 1] = "eeprom",
+	[0xc0 >> 1] = "tuner/XC3028",
+	[0xc2 >> 1] = "tuner/XC5000",
+};
+
+/*
+ * cx231xx_do_i2c_scan()
+ * check i2c address range for devices
+ */
+void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c)
+{
+	unsigned char buf;
+	int i, rc;
+
+	cx231xx_info(": Checking for I2C devices ..\n");
+	for (i = 0; i < 128; i++) {
+		c->addr = i;
+		rc = i2c_master_recv(c, &buf, 0);
+		if (rc < 0)
+			continue;
+		cx231xx_info("%s: i2c scan: found device @ 0x%x  [%s]\n",
+			     dev->name, i << 1,
+			     i2c_devs[i] ? i2c_devs[i] : "???");
+	}
+	cx231xx_info(": Completed Checking for I2C devices.\n");
+}
+
+/*
+ * cx231xx_i2c_register()
+ * register i2c bus
+ */
+int cx231xx_i2c_register(struct cx231xx_i2c *bus)
+{
+	struct cx231xx *dev = bus->dev;
+
+	BUG_ON(!dev->cx231xx_send_usb_command);
+
+	memcpy(&bus->i2c_adap, &cx231xx_adap_template, sizeof(bus->i2c_adap));
+	memcpy(&bus->i2c_algo, &cx231xx_algo, sizeof(bus->i2c_algo));
+	memcpy(&bus->i2c_client, &cx231xx_client_template,
+	       sizeof(bus->i2c_client));
+
+	bus->i2c_adap.dev.parent = &dev->udev->dev;
+
+	strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
+
+	bus->i2c_algo.data = bus;
+	bus->i2c_adap.algo_data = bus;
+	i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
+	i2c_add_adapter(&bus->i2c_adap);
+
+	bus->i2c_client.adapter = &bus->i2c_adap;
+
+	if (0 == bus->i2c_rc) {
+		if (i2c_scan)
+			cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+	} else
+		cx231xx_warn("%s: i2c bus %d register FAILED\n",
+			     dev->name, bus->nr);
+
+	return bus->i2c_rc;
+}
+
+/*
+ * cx231xx_i2c_unregister()
+ * unregister i2c_bus
+ */
+int cx231xx_i2c_unregister(struct cx231xx_i2c *bus)
+{
+	i2c_del_adapter(&bus->i2c_adap);
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-input.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-input.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-input.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,246 @@
+/*
+  handle cx231xx IR remotes via linux kernel input layer.
+
+  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+		Based on em28xx driver
+
+		< This is a place holder for IR now.>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU 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/delay.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "cx231xx.h"
+
+static unsigned int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
+
+#define i2cdprintk(fmt, arg...) \
+	if (ir_debug) { \
+		printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+	}
+
+#define dprintk(fmt, arg...) \
+	if (ir_debug) { \
+		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
+	}
+
+/**********************************************************
+ Polling structure used by cx231xx IR's
+ **********************************************************/
+
+struct cx231xx_ir_poll_result {
+	unsigned int toggle_bit:1;
+	unsigned int read_count:7;
+	u8 rc_address;
+	u8 rc_data[4];
+};
+
+struct cx231xx_IR {
+	struct cx231xx *dev;
+	struct input_dev *input;
+	struct ir_input_state ir;
+	char name[32];
+	char phys[32];
+
+	/* poll external decoder */
+	int polling;
+	struct work_struct work;
+	struct timer_list timer;
+	unsigned int last_toggle:1;
+	unsigned int last_readcount;
+	unsigned int repeat_interval;
+
+	int (*get_key) (struct cx231xx_IR *, struct cx231xx_ir_poll_result *);
+};
+
+/**********************************************************
+ Polling code for cx231xx
+ **********************************************************/
+
+static void cx231xx_ir_handle_key(struct cx231xx_IR *ir)
+{
+	int result;
+	int do_sendkey = 0;
+	struct cx231xx_ir_poll_result poll_result;
+
+	/* read the registers containing the IR status */
+	result = ir->get_key(ir, &poll_result);
+	if (result < 0) {
+		dprintk("ir->get_key() failed %d\n", result);
+		return;
+	}
+
+	dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n",
+		poll_result.toggle_bit, poll_result.read_count,
+		ir->last_readcount, poll_result.rc_data[0]);
+
+	if (ir->dev->chip_id == CHIP_ID_EM2874) {
+		/* The em2874 clears the readcount field every time the
+		   register is read.  The em2860/2880 datasheet says that it
+		   is supposed to clear the readcount, but it doesn't.  So with
+		   the em2874, we are looking for a non-zero read count as
+		   opposed to a readcount that is incrementing */
+		ir->last_readcount = 0;
+	}
+
+	if (poll_result.read_count == 0) {
+		/* The button has not been pressed since the last read */
+	} else if (ir->last_toggle != poll_result.toggle_bit) {
+		/* A button has been pressed */
+		dprintk("button has been pressed\n");
+		ir->last_toggle = poll_result.toggle_bit;
+		ir->repeat_interval = 0;
+		do_sendkey = 1;
+	} else if (poll_result.toggle_bit == ir->last_toggle &&
+		   poll_result.read_count > 0 &&
+		   poll_result.read_count != ir->last_readcount) {
+		/* The button is still being held down */
+		dprintk("button being held down\n");
+
+		/* Debouncer for first keypress */
+		if (ir->repeat_interval++ > 9) {
+			/* Start repeating after 1 second */
+			do_sendkey = 1;
+		}
+	}
+
+	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_nokey(ir->input, &ir->ir);
+	}
+
+	ir->last_readcount = poll_result.read_count;
+	return;
+}
+
+static void ir_timer(unsigned long data)
+{
+	struct cx231xx_IR *ir = (struct cx231xx_IR *)data;
+
+	schedule_work(&ir->work);
+}
+
+static void cx231xx_ir_work(struct work_struct *work)
+{
+	struct cx231xx_IR *ir = container_of(work, struct cx231xx_IR, work);
+
+	cx231xx_ir_handle_key(ir);
+	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+}
+
+void cx231xx_ir_start(struct cx231xx_IR *ir)
+{
+	setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
+	INIT_WORK(&ir->work, cx231xx_ir_work);
+	schedule_work(&ir->work);
+}
+
+static void cx231xx_ir_stop(struct cx231xx_IR *ir)
+{
+	del_timer_sync(&ir->timer);
+	flush_scheduled_work();
+}
+
+int cx231xx_ir_init(struct cx231xx *dev)
+{
+	struct cx231xx_IR *ir;
+	struct input_dev *input_dev;
+	u8 ir_config;
+	int err = -ENOMEM;
+
+	if (dev->board.ir_codes == NULL) {
+		/* No remote control support */
+		return 0;
+	}
+
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev)
+		goto err_out_free;
+
+	ir->input = input_dev;
+
+	/* Setup the proper handler based on the chip */
+	switch (dev->chip_id) {
+	default:
+		printk("Unrecognized cx231xx chip id: IR not supported\n");
+		goto err_out_free;
+	}
+
+	/* This is how often we ask the chip for IR information */
+	ir->polling = 100;	/* ms */
+
+	/* init input device */
+	snprintf(ir->name, sizeof(ir->name), "cx231xx IR (%s)", dev->name);
+
+	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);
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_USB;
+	input_dev->id.version = 1;
+	input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+	input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+	input_dev->dev.parent = &dev->udev->dev;
+	/* record handles to ourself */
+	ir->dev = dev;
+	dev->ir = ir;
+
+	cx231xx_ir_start(ir);
+
+	/* all done */
+	err = input_register_device(ir->input);
+	if (err)
+		goto err_out_stop;
+
+	return 0;
+err_out_stop:
+	cx231xx_ir_stop(ir);
+	dev->ir = NULL;
+err_out_free:
+	input_free_device(input_dev);
+	kfree(ir);
+	return err;
+}
+
+int cx231xx_ir_fini(struct cx231xx *dev)
+{
+	struct cx231xx_IR *ir = dev->ir;
+
+	/* skip detach on non attached boards */
+	if (!ir)
+		return 0;
+
+	cx231xx_ir_stop(ir);
+	input_unregister_device(ir->input);
+	kfree(ir);
+
+	/* done */
+	dev->ir = NULL;
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,795 @@
+/*
+   cx231xx-pcb-config.c - driver for Conexant
+		Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot 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 "cx231xx.h"
+#include "cx231xx-conf-reg.h"
+
+static unsigned int pcb_debug;
+module_param(pcb_debug, int, 0644);
+MODULE_PARM_DESC(pcb_debug, "enable pcb config debug messages [video]");
+
+/******************************************************************************/
+
+struct pcb_config cx231xx_Scenario[] = {
+	{
+	 INDEX_SELFPOWER_DIGITAL_ONLY,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 MOD_DIGITAL,		/* mode */
+	 SOURCE_TS_BDA,		/* ts1_source, digital tv only */
+	 NOT_SUPPORTED,		/* ts2_source  */
+	 NOT_SUPPORTED,		/* analog source */
+
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index   */
+	 0,			/* external_index */
+
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   ,
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed config */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_SELFPOWER_DUAL_DIGITAL,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 MOD_DIGITAL,		/* mode */
+	 SOURCE_TS_BDA,		/* ts1_source, digital tv only */
+	 0,			/* ts2_source,need update from register */
+	 NOT_SUPPORTED,		/* analog source */
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    2,			/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    2,			/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_SELFPOWER_ANALOG_ONLY,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 MOD_ANALOG | MOD_DIF | MOD_EXTERNAL,	/* mode ,analog tv only */
+	 NOT_SUPPORTED,		/* ts1_source, NOT SUPPORT */
+	 NOT_SUPPORTED,		/* ts2_source,NOT SUPPORT */
+	 0,			/* analog source, need update */
+
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    1,			/* AUDIO */
+	    2,			/* VIDEO */
+	    3,			/* VANC */
+	    4,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    1,			/* AUDIO */
+	    2,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_SELFPOWER_DUAL,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 /* mode ,analog tv and digital path */
+	 MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+	 0,			/* ts1_source,will update in register */
+	 NOT_SUPPORTED,		/* ts2_source,NOT SUPPORT */
+	 0,			/* analog source need update */
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    4,			/* VANC */
+	    5,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_SELFPOWER_TRIPLE,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 /* mode ,analog tv and digital path */
+	 MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+	 0,			/* ts1_source, update in register */
+	 0,			/* ts2_source,update in register */
+	 0,			/* analog source, need update */
+
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    2,			/* TS2 index */
+	    3,			/* AUDIO */
+	    4,			/* VIDEO */
+	    5,			/* VANC */
+	    6,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    2,			/* TS2 index */
+	    3,			/* AUDIO */
+	    4,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_SELFPOWER_COMPRESSOR,	/* index */
+	 USB_SELF_POWER,	/* power_type */
+	 0,			/* speed , not decide yet */
+	 /* mode ,analog tv AND DIGITAL path */
+	 MOD_ANALOG | MOD_DIF | MOD_DIGITAL | MOD_EXTERNAL,
+	 NOT_SUPPORTED,		/* ts1_source, disable */
+	 SOURCE_TS_BDA,		/* ts2_source */
+	 0,			/* analog source,need update */
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    1,			/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    4,			/* VANC */
+	    5,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed  */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    1,			/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+	{
+	 INDEX_BUSPOWER_DIGITAL_ONLY,	/* index */
+	 USB_BUS_POWER,		/* power_type */
+	 0,			/* speed , not decide yet */
+	 MOD_DIGITAL,		/* mode ,analog tv AND DIGITAL path */
+	 SOURCE_TS_BDA,		/* ts1_source, disable */
+	 NOT_SUPPORTED,		/* ts2_source */
+	 NOT_SUPPORTED,		/* analog source */
+
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index  = 2 */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 /* full-speed */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index  = 2 */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    NOT_SUPPORTED,	/* AUDIO */
+	    NOT_SUPPORTED,	/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+	{
+	 INDEX_BUSPOWER_ANALOG_ONLY,	/* index */
+	 USB_BUS_POWER,		/* power_type */
+	 0,			/* speed , not decide yet */
+	 MOD_ANALOG,		/* mode ,analog tv AND DIGITAL path */
+	 NOT_SUPPORTED,		/* ts1_source, disable */
+	 NOT_SUPPORTED,		/* ts2_source */
+	 SOURCE_ANALOG,		/* analog source--analog */
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    1,			/* AUDIO */
+	    2,			/* VIDEO */
+	    3,			/* VANC */
+	    4,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 {			/* full-speed */
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    NOT_SUPPORTED,	/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    1,			/* AUDIO */
+	    2,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+	{
+	 INDEX_BUSPOWER_DIF_ONLY,	/* index */
+	 USB_BUS_POWER,		/* power_type */
+	 0,			/* speed , not decide yet */
+	 /* mode ,analog tv AND DIGITAL path */
+	 MOD_DIF | MOD_ANALOG | MOD_DIGITAL | MOD_EXTERNAL,
+	 SOURCE_TS_BDA,		/* ts1_source, disable */
+	 NOT_SUPPORTED,		/* ts2_source */
+	 SOURCE_DIF | SOURCE_ANALOG | SOURCE_EXTERNAL,	/* analog source, dif */
+	 0,			/* digital_index  */
+	 0,			/* analog index */
+	 0,			/* dif_index */
+	 0,			/* external_index */
+	 1,			/* only one configuration */
+	 {
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    4,			/* VANC */
+	    5,			/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 ,
+	 {			/* full speed */
+	  {
+	   0,			/* config index */
+	   {
+	    0,			/* interrupt ep index */
+	    1,			/* ts1 index */
+	    NOT_SUPPORTED,	/* TS2 index */
+	    2,			/* AUDIO */
+	    3,			/* VIDEO */
+	    NOT_SUPPORTED,	/* VANC */
+	    NOT_SUPPORTED,	/* HANC */
+	    NOT_SUPPORTED	/* ir_index */
+	    }
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  ,
+	  {NOT_SUPPORTED, {NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED, NOT_SUPPORTED, NOT_SUPPORTED,
+			   NOT_SUPPORTED}
+	   }
+	  }
+	 }
+	,
+
+};
+
+/*****************************************************************/
+
+u32 initialize_cx231xx(struct cx231xx *dev)
+{
+	u32 config_info = 0;
+	struct pcb_config *p_pcb_info;
+	u8 usb_speed = 1;	/* from register,1--HS, 0--FS  */
+	u8 data[4] = { 0, 0, 0, 0 };
+	u32 ts1_source = 0;
+	u32 ts2_source = 0;
+	u32 analog_source = 0;
+	u8 _current_scenario_idx = 0xff;
+
+	ts1_source = SOURCE_TS_BDA;
+	ts2_source = SOURCE_TS_BDA;
+
+	/* read board config register to find out which
+	pcb config it is related to */
+	cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4);
+
+	config_info = *((u32 *) data);
+	usb_speed = (u8) (config_info & 0x1);
+
+	/* Verify this device belongs to Bus power or Self power device */
+	if (config_info & BUS_POWER) {	/* bus-power */
+		switch (config_info & BUSPOWER_MASK) {
+		case TS1_PORT | BUS_POWER:
+			cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY].speed =
+			    usb_speed;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_BUSPOWER_DIGITAL_ONLY];
+			_current_scenario_idx = INDEX_BUSPOWER_DIGITAL_ONLY;
+			break;
+		case AVDEC_ENABLE | BUS_POWER:
+			cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY].speed =
+			    usb_speed;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_BUSPOWER_ANALOG_ONLY];
+			_current_scenario_idx = INDEX_BUSPOWER_ANALOG_ONLY;
+			break;
+		case AVDEC_ENABLE | BUS_POWER | TS1_PORT:
+			cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY].speed =
+			    usb_speed;
+			p_pcb_info = &cx231xx_Scenario[INDEX_BUSPOWER_DIF_ONLY];
+			_current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY;
+			break;
+		default:
+			cx231xx_info("bad config in buspower!!!!\n");
+			cx231xx_info("config_info=%x\n",
+				     (config_info & BUSPOWER_MASK));
+			return 1;
+		}
+	} else {		/* self-power */
+
+		switch (config_info & SELFPOWER_MASK) {
+		case TS1_PORT | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY].speed =
+			    usb_speed;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_SELFPOWER_DIGITAL_ONLY];
+			_current_scenario_idx = INDEX_SELFPOWER_DIGITAL_ONLY;
+			break;
+		case TS1_TS2_PORT | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].speed =
+			    usb_speed;
+			cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL].
+			    ts2_source = ts2_source;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_SELFPOWER_DUAL_DIGITAL];
+			_current_scenario_idx = INDEX_SELFPOWER_DUAL_DIGITAL;
+			break;
+		case AVDEC_ENABLE | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].speed =
+			    usb_speed;
+			cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY].
+			    analog_source = analog_source;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_SELFPOWER_ANALOG_ONLY];
+			_current_scenario_idx = INDEX_SELFPOWER_ANALOG_ONLY;
+			break;
+		case AVDEC_ENABLE | TS1_PORT | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].speed =
+			    usb_speed;
+			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].ts1_source =
+			    ts1_source;
+			cx231xx_Scenario[INDEX_SELFPOWER_DUAL].analog_source =
+			    analog_source;
+			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_DUAL];
+			_current_scenario_idx = INDEX_SELFPOWER_DUAL;
+			break;
+		case AVDEC_ENABLE | TS1_TS2_PORT | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].speed =
+			    usb_speed;
+			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts1_source =
+			    ts1_source;
+			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].ts2_source =
+			    ts2_source;
+			cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE].analog_source =
+			    analog_source;
+			p_pcb_info = &cx231xx_Scenario[INDEX_SELFPOWER_TRIPLE];
+			_current_scenario_idx = INDEX_SELFPOWER_TRIPLE;
+			break;
+		case AVDEC_ENABLE | TS1VIP_TS2_PORT | SELF_POWER:
+			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].speed =
+			    usb_speed;
+			cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR].
+			    analog_source = analog_source;
+			p_pcb_info =
+			    &cx231xx_Scenario[INDEX_SELFPOWER_COMPRESSOR];
+			_current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR;
+			break;
+		default:
+			cx231xx_info("bad senario!!!!!\n");
+			cx231xx_info("config_info=%x\n",
+				     (config_info & SELFPOWER_MASK));
+			return 1;
+		}
+	}
+
+	dev->current_scenario_idx = _current_scenario_idx;
+
+	memcpy(&dev->current_pcb_config, p_pcb_info,
+		   sizeof(struct pcb_config));
+
+	if (pcb_debug) {
+		cx231xx_info("SC(0x00) register = 0x%x\n", config_info);
+		cx231xx_info("scenario %d\n",
+			    (dev->current_pcb_config.index) + 1);
+		cx231xx_info("type=%x\n", dev->current_pcb_config.type);
+		cx231xx_info("mode=%x\n", dev->current_pcb_config.mode);
+		cx231xx_info("speed=%x\n", dev->current_pcb_config.speed);
+		cx231xx_info("ts1_source=%x\n",
+			     dev->current_pcb_config.ts1_source);
+		cx231xx_info("ts2_source=%x\n",
+			     dev->current_pcb_config.ts2_source);
+		cx231xx_info("analog_source=%x\n",
+			     dev->current_pcb_config.analog_source);
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-pcb-cfg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,231 @@
+/*
+   cx231xx-pcb-cfg.h - driver for Conexant
+		Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot 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 _PCB_CONFIG_H_
+#define _PCB_CONFIG_H_
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+/***************************************************************************
+				* Class Information *
+***************************************************************************/
+#define CLASS_DEFAULT       0xFF
+
+enum VENDOR_REQUEST_TYPE {
+	/* Set/Get I2C */
+	VRT_SET_I2C0 = 0x0,
+	VRT_SET_I2C1 = 0x1,
+	VRT_SET_I2C2 = 0x2,
+	VRT_GET_I2C0 = 0x4,
+	VRT_GET_I2C1 = 0x5,
+	VRT_GET_I2C2 = 0x6,
+
+	/* Set/Get GPIO */
+	VRT_SET_GPIO = 0x8,
+	VRT_GET_GPIO = 0x9,
+
+	/* Set/Get GPIE */
+	VRT_SET_GPIE = 0xA,
+	VRT_GET_GPIE = 0xB,
+
+	/* Set/Get Register Control/Status */
+	VRT_SET_REGISTER = 0xC,
+	VRT_GET_REGISTER = 0xD,
+
+	/* Get Extended Compat ID Descriptor */
+	VRT_GET_EXTCID_DESC = 0xFF,
+};
+
+enum BYTE_ENABLE_MASK {
+	ENABLE_ONE_BYTE = 0x1,
+	ENABLE_TWE_BYTE = 0x3,
+	ENABLE_THREE_BYTE = 0x7,
+	ENABLE_FOUR_BYTE = 0xF,
+};
+
+#define SPEED_MASK      0x1
+enum USB_SPEED{
+	FULL_SPEED = 0x0,	/* 0: full speed */
+	HIGH_SPEED = 0x1	/* 1: high speed */
+};
+
+enum _true_false{
+	FALSE = 0,
+	TRUE = 1
+};
+
+#define TS_MASK         0x6
+enum TS_PORT{
+	NO_TS_PORT = 0x0,	/* 2'b00: Neither port used. PCB not a Hybrid,
+				   only offers Analog TV or Video */
+	TS1_PORT = 0x4,		/* 2'b10: TS1 Input (Hybrid mode :
+				Digital or External Analog/Compressed source) */
+	TS1_TS2_PORT = 0x6,	/* 2'b11: TS1 & TS2 Inputs
+				(Dual inputs from Digital and/or
+				External Analog/Compressed sources) */
+	TS1_EXT_CLOCK = 0x6,	/* 2'b11: TS1 & TS2 as selector
+						to external clock */
+	TS1VIP_TS2_PORT = 0x2	/* 2'b01: TS1 used as 656/VIP Output,
+				   TS2 Input (from Compressor) */
+};
+
+#define EAVP_MASK       0x8
+enum EAV_PRESENT{
+	NO_EXTERNAL_AV = 0x0,	/* 0: No External A/V inputs
+						(no need for i2s blcok),
+						Analog Tuner must be present */
+	EXTERNAL_AV = 0x8	/* 1: External A/V inputs
+						present (requires i2s blk) */
+};
+
+#define ATM_MASK        0x30
+enum AT_MODE{
+	DIF_TUNER = 0x30,	/* 2'b11: IF Tuner (requires use of DIF) */
+	BASEBAND_SOUND = 0x20,	/* 2'b10: Baseband Composite &
+						Sound-IF Signals present */
+	NO_TUNER = 0x10		/* 2'b0x: No Analog Tuner present */
+};
+
+#define PWR_SEL_MASK    0x40
+enum POWE_TYPE{
+	SELF_POWER = 0x0,	/* 0: self power */
+	BUS_POWER = 0x40	/* 1: bus power */
+};
+
+enum USB_POWE_TYPE{
+	USB_SELF_POWER = 0,
+	USB_BUS_POWER
+};
+
+#define BO_0_MASK       0x80
+enum AVDEC_STATUS{
+	AVDEC_DISABLE = 0x0,	/* 0: A/V Decoder Disabled */
+	AVDEC_ENABLE = 0x80	/* 1: A/V Decoder Enabled */
+};
+
+#define BO_1_MASK       0x100
+
+#define BUSPOWER_MASK   0xC4	/* for Polaris spec 0.8 */
+#define SELFPOWER_MASK  0x86
+
+/***************************************************************************/
+#define NOT_DECIDE_YET  0xFE
+#define NOT_SUPPORTED   0xFF
+
+/***************************************************************************
+				* for mod field use *
+***************************************************************************/
+#define MOD_DIGITAL     0x1
+#define MOD_ANALOG      0x2
+#define MOD_DIF         0x4
+#define MOD_EXTERNAL    0x8
+#define CAP_ALL_MOD     0x0f
+
+/***************************************************************************
+				* source define *
+***************************************************************************/
+#define SOURCE_DIGITAL          0x1
+#define SOURCE_ANALOG           0x2
+#define SOURCE_DIF              0x4
+#define SOURCE_EXTERNAL         0x8
+#define SOURCE_TS_BDA			0x10
+#define SOURCE_TS_ENCODE		0x20
+#define SOURCE_TS_EXTERNAL   	0x40
+
+/***************************************************************************
+				* interface information define *
+***************************************************************************/
+struct INTERFACE_INFO {
+	u8 interrupt_index;
+	u8 ts1_index;
+	u8 ts2_index;
+	u8 audio_index;
+	u8 video_index;
+	u8 vanc_index;		/* VBI */
+	u8 hanc_index;		/* Sliced CC */
+	u8 ir_index;
+};
+
+enum INDEX_INTERFACE_INFO{
+	INDEX_INTERRUPT = 0x0,
+	INDEX_TS1,
+	INDEX_TS2,
+	INDEX_AUDIO,
+	INDEX_VIDEO,
+	INDEX_VANC,
+	INDEX_HANC,
+	INDEX_IR,
+};
+
+/***************************************************************************
+				* configuration information define *
+***************************************************************************/
+struct CONFIG_INFO {
+	u8 config_index;
+	struct INTERFACE_INFO interface_info;
+};
+
+struct pcb_config {
+	u8 index;
+	u8 type;		/* bus power or self power,
+					   self power--0, bus_power--1 */
+	u8 speed;		/* usb speed, 2.0--1, 1.1--0 */
+	u8 mode;		/* digital , anlog, dif or external A/V */
+	u32 ts1_source;		/* three source -- BDA,External,encode */
+	u32 ts2_source;
+	u32 analog_source;
+	u8 digital_index;	/* bus-power used */
+	u8 analog_index;	/* bus-power used */
+	u8 dif_index;		/* bus-power used */
+	u8 external_index;	/* bus-power used */
+	u8 config_num;		/* current config num, 0,1,2,
+						   for self-power, always 0 */
+	struct CONFIG_INFO hs_config_info[3];
+	struct CONFIG_INFO fs_config_info[3];
+};
+
+enum INDEX_PCB_CONFIG{
+	INDEX_SELFPOWER_DIGITAL_ONLY = 0x0,
+	INDEX_SELFPOWER_DUAL_DIGITAL,
+	INDEX_SELFPOWER_ANALOG_ONLY,
+	INDEX_SELFPOWER_DUAL,
+	INDEX_SELFPOWER_TRIPLE,
+	INDEX_SELFPOWER_COMPRESSOR,
+	INDEX_BUSPOWER_DIGITAL_ONLY,
+	INDEX_BUSPOWER_ANALOG_ONLY,
+	INDEX_BUSPOWER_DIF_ONLY,
+	INDEX_BUSPOWER_EXTERNAL_ONLY,
+	INDEX_BUSPOWER_EXTERNAL_ANALOG,
+	INDEX_BUSPOWER_EXTERNAL_DIF,
+	INDEX_BUSPOWER_EXTERNAL_DIGITAL,
+	INDEX_BUSPOWER_DIGITAL_ANALOG,
+	INDEX_BUSPOWER_DIGITAL_DIF,
+	INDEX_BUSPOWER_DIGITAL_ANALOG_EXTERNAL,
+	INDEX_BUSPOWER_DIGITAL_DIF_EXTERNAL,
+};
+
+/***************************************************************************/
+struct cx231xx;
+
+u32 initialize_cx231xx(struct cx231xx *p_dev);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-reg.h linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1564 @@
+/*
+   cx231xx-reg.h - driver for Conexant Cx23100/101/102
+	       USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot 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 _CX231XX_REG_H
+#define _CX231XX_REG_H
+
+/*****************************************************************************
+				* VBI codes *
+*****************************************************************************/
+
+#define SAV_ACTIVE_VIDEO_FIELD1		0x80
+#define EAV_ACTIVE_VIDEO_FIELD1		0x90
+
+#define SAV_ACTIVE_VIDEO_FIELD2		0xc0
+#define EAV_ACTIVE_VIDEO_FIELD2		0xd0
+
+#define SAV_VBLANK_FIELD1		0xa0
+#define EAV_VBLANK_FIELD1		0xb0
+
+#define SAV_VBLANK_FIELD2		0xe0
+#define EAV_VBLANK_FIELD2		0xf0
+
+#define SAV_VBI_FIELD1			0x20
+#define EAV_VBI_FIELD1			0x30
+
+#define SAV_VBI_FIELD2			0x60
+#define EAV_VBI_FIELD2			0x70
+
+/*****************************************************************************/
+/* Audio ADC Registers */
+#define CH_PWR_CTRL1			0x0000000e
+#define CH_PWR_CTRL2			0x0000000f
+/*****************************************************************************/
+
+#define      HOST_REG1                0x000
+#define      FLD_FORCE_CHIP_SEL       0x80
+#define      FLD_AUTO_INC_DIS         0x20
+#define      FLD_PREFETCH_EN          0x10
+/* Reserved [2:3] */
+#define      FLD_DIGITAL_PWR_DN       0x02
+#define      FLD_SLEEP                0x01
+
+/*****************************************************************************/
+#define      HOST_REG2                0x001
+
+/*****************************************************************************/
+#define      HOST_REG3                0x002
+
+/*****************************************************************************/
+/* added for polaris */
+#define      GPIO_PIN_CTL0            0x3
+#define      GPIO_PIN_CTL1            0x4
+#define      GPIO_PIN_CTL2            0x5
+#define      GPIO_PIN_CTL3            0x6
+#define      TS1_PIN_CTL0             0x7
+#define      TS1_PIN_CTL1             0x8
+/*****************************************************************************/
+
+#define      FLD_CLK_IN_EN            0x80
+#define      FLD_XTAL_CTRL            0x70
+#define      FLD_BB_CLK_MODE          0x0C
+#define      FLD_REF_DIV_PLL          0x02
+#define      FLD_REF_SEL_PLL1         0x01
+
+/*****************************************************************************/
+#define      CHIP_CTRL                0x100
+/* Reserved [27] */
+/* Reserved [31:21] */
+#define      FLD_CHIP_ACFG_DIS        0x00100000
+/* Reserved [19] */
+#define      FLD_DUAL_MODE_ADC2       0x00040000
+#define      FLD_SIF_EN               0x00020000
+#define      FLD_SOFT_RST             0x00010000
+#define      FLD_DEVICE_ID            0x0000ffff
+
+/*****************************************************************************/
+#define      AFE_CTRL                 0x104
+#define      AFE_CTRL_C2HH_SRC_CTRL   0x104
+#define      FLD_DIF_OUT_SEL          0xc0000000
+#define      FLD_AUX_PLL_CLK_ALT_SEL  0x3c000000
+#define      FLD_UV_ORDER_MODE        0x02000000
+#define      FLD_FUNC_MODE            0x01800000
+#define      FLD_ROT1_PHASE_CTL       0x007f8000
+#define      FLD_AUD_IN_SEL           0x00004000
+#define      FLD_LUMA_IN_SEL          0x00002000
+#define      FLD_CHROMA_IN_SEL        0x00001000
+/* reserve [11:10] */
+#define      FLD_INV_SPEC_DIS         0x00000200
+#define      FLD_VGA_SEL_CH3          0x00000100
+#define      FLD_VGA_SEL_CH2          0x00000080
+#define      FLD_VGA_SEL_CH1          0x00000040
+#define      FLD_DCR_BYP_CH1          0x00000020
+#define      FLD_DCR_BYP_CH2          0x00000010
+#define      FLD_DCR_BYP_CH3          0x00000008
+#define      FLD_EN_12DB_CH3          0x00000004
+#define      FLD_EN_12DB_CH2          0x00000002
+#define      FLD_EN_12DB_CH1          0x00000001
+
+/* redefine in Cx231xx */
+/*****************************************************************************/
+#define      DC_CTRL1                 0x108
+/* reserve [31:30] */
+#define      FLD_CLAMP_LVL_CH1        0x3fff8000
+#define      FLD_CLAMP_LVL_CH2        0x00007fff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      DC_CTRL2                 0x10c
+/* reserve [31:28] */
+#define      FLD_CLAMP_LVL_CH3        0x00fffe00
+#define      FLD_CLAMP_WIND_LENTH     0x000001e0
+#define      FLD_C2HH_SAT_MIN         0x0000001e
+#define      FLD_FLT_BYP_SEL          0x00000001
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      DC_CTRL3                 0x110
+/* reserve [31:16] */
+#define      FLD_ERR_GAIN_CTL         0x00070000
+#define      FLD_LPF_MIN              0x0000ffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      DC_CTRL4                 0x114
+/* reserve [31:31] */
+#define      FLD_INTG_CH1             0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      DC_CTRL5                 0x118
+/* reserve [31:31] */
+#define      FLD_INTG_CH2             0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      DC_CTRL6                 0x11c
+/* reserve [31:31] */
+#define      FLD_INTG_CH3             0x7fffffff
+/*****************************************************************************/
+
+/*****************************************************************************/
+#define      PIN_CTRL                 0x120
+#define      FLD_OEF_AGC_RF           0x00000001
+#define      FLD_OEF_AGC_IFVGA        0x00000002
+#define      FLD_OEF_AGC_IF           0x00000004
+#define      FLD_REG_BO_PUD           0x80000000
+#define      FLD_IR_IRQ_STAT          0x40000000
+#define      FLD_AUD_IRQ_STAT         0x20000000
+#define      FLD_VID_IRQ_STAT         0x10000000
+/* Reserved [27:26] */
+#define      FLD_IRQ_N_OUT_EN         0x02000000
+#define      FLD_IRQ_N_POLAR          0x01000000
+/* Reserved [23:6] */
+#define      FLD_OE_AUX_PLL_CLK       0x00000020
+#define      FLD_OE_I2S_BCLK          0x00000010
+#define      FLD_OE_I2S_WCLK          0x00000008
+#define      FLD_OE_AGC_IF            0x00000004
+#define      FLD_OE_AGC_IFVGA         0x00000002
+#define      FLD_OE_AGC_RF            0x00000001
+
+/*****************************************************************************/
+#define      AUD_IO_CTRL              0x124
+/* Reserved [31:8] */
+#define      FLD_I2S_PORT_DIR         0x00000080
+#define      FLD_I2S_OUT_SRC          0x00000040
+#define      FLD_AUD_CHAN3_SRC        0x00000030
+#define      FLD_AUD_CHAN2_SRC        0x0000000c
+#define      FLD_AUD_CHAN1_SRC        0x00000003
+
+/*****************************************************************************/
+#define      AUD_LOCK1                0x128
+#define      FLD_AUD_LOCK_KI_SHIFT    0xc0000000
+#define      FLD_AUD_LOCK_KD_SHIFT    0x30000000
+/* Reserved [27:25] */
+#define      FLD_EN_AV_LOCK           0x01000000
+#define      FLD_VID_COUNT            0x00ffffff
+
+/*****************************************************************************/
+#define      AUD_LOCK2                0x12c
+#define      FLD_AUD_LOCK_KI_MULT     0xf0000000
+#define      FLD_AUD_LOCK_KD_MULT     0x0F000000
+/* Reserved [23:22] */
+#define      FLD_AUD_LOCK_FREQ_SHIFT  0x00300000
+#define      FLD_AUD_COUNT            0x000fffff
+
+/*****************************************************************************/
+#define      AFE_DIAG_CTRL1           0x134
+/* Reserved [31:16] */
+#define      FLD_CUV_DLY_LENGTH       0x0000ff00
+#define      FLD_YC_DLY_LENGTH        0x000000ff
+
+/*****************************************************************************/
+/* Poalris redefine */
+#define      AFE_DIAG_CTRL3           0x138
+/* Reserved [31:26] */
+#define      FLD_AUD_DUAL_FLAG_POL    0x02000000
+#define      FLD_VID_DUAL_FLAG_POL    0x01000000
+/* Reserved [23:23] */
+#define      FLD_COL_CLAMP_DIS_CH1    0x00400000
+#define      FLD_COL_CLAMP_DIS_CH2    0x00200000
+#define      FLD_COL_CLAMP_DIS_CH3    0x00100000
+
+#define      TEST_CTRL1               0x144
+/* Reserved [31:29] */
+#define      FLD_LBIST_EN             0x10000000
+/* Reserved [27:10] */
+#define      FLD_FI_BIST_INTR_R       0x0000200
+#define      FLD_FI_BIST_INTR_L       0x0000100
+#define      FLD_BIST_FAIL_AUD_PLL    0x0000080
+#define      FLD_BIST_INTR_AUD_PLL    0x0000040
+#define      FLD_BIST_FAIL_VID_PLL    0x0000020
+#define      FLD_BIST_INTR_VID_PLL    0x0000010
+/* Reserved [3:1] */
+#define      FLD_CIR_TEST_DIS         0x00000001
+
+/*****************************************************************************/
+#define      TEST_CTRL2               0x148
+#define      FLD_TSXCLK_POL_CTL       0x80000000
+#define      FLD_ISO_CTL_SEL          0x40000000
+#define      FLD_ISO_CTL_EN           0x20000000
+#define      FLD_BIST_DEBUGZ          0x10000000
+#define      FLD_AUD_BIST_TEST_H      0x0f000000
+/* Reserved [23:22] */
+#define      FLD_FLTRN_BIST_TEST_H    0x00020000
+#define      FLD_VID_BIST_TEST_H      0x00010000
+/* Reserved [19:17] */
+#define      FLD_BIST_TEST_H          0x00010000
+/* Reserved [15:13] */
+#define      FLD_TAB_EN               0x00001000
+/* Reserved [11:0] */
+
+/*****************************************************************************/
+#define      BIST_STAT                0x14c
+#define      FLD_AUD_BIST_FAIL_H      0xfff00000
+#define      FLD_FLTRN_BIST_FAIL_H    0x00180000
+#define      FLD_VID_BIST_FAIL_H      0x00070000
+#define      FLD_AUD_BIST_TST_DONE    0x0000fff0
+#define      FLD_FLTRN_BIST_TST_DONE  0x00000008
+#define      FLD_VID_BIST_TST_DONE    0x00000007
+
+/*****************************************************************************/
+/* DirectIF registers definition have been moved to DIF_reg.h                */
+/*****************************************************************************/
+#define      MODE_CTRL                0x400
+#define      FLD_AFD_PAL60_DIS        0x20000000
+#define      FLD_AFD_FORCE_SECAM      0x10000000
+#define      FLD_AFD_FORCE_PALNC      0x08000000
+#define      FLD_AFD_FORCE_PAL        0x04000000
+#define      FLD_AFD_PALM_SEL         0x03000000
+#define      FLD_CKILL_MODE           0x00300000
+#define      FLD_COMB_NOTCH_MODE      0x00c00000       /* bit[19:18] */
+#define      FLD_CLR_LOCK_STAT        0x00020000
+#define      FLD_FAST_LOCK_MD         0x00010000
+#define      FLD_WCEN                 0x00008000
+#define      FLD_CAGCEN               0x00004000
+#define      FLD_CKILLEN              0x00002000
+#define      FLD_AUTO_SC_LOCK         0x00001000
+#define      FLD_MAN_SC_FAST_LOCK     0x00000800
+#define      FLD_INPUT_MODE           0x00000600
+#define      FLD_AFD_ACQUIRE          0x00000100
+#define      FLD_AFD_NTSC_SEL         0x00000080
+#define      FLD_AFD_PAL_SEL          0x00000040
+#define      FLD_ACFG_DIS             0x00000020
+#define      FLD_SQ_PIXEL             0x00000010
+#define      FLD_VID_FMT_SEL          0x0000000f
+
+/*****************************************************************************/
+#define      OUT_CTRL1                0x404
+#define      FLD_POLAR                0x7f000000
+/* Reserved [23] */
+#define      FLD_RND_MODE             0x00600000
+#define      FLD_VIPCLAMP_EN          0x00100000
+#define      FLD_VIPBLANK_EN          0x00080000
+#define      FLD_VIP_OPT_AL           0x00040000
+#define      FLD_IDID0_SOURCE         0x00020000
+#define      FLD_DCMODE               0x00010000
+#define      FLD_CLK_GATING           0x0000c000
+#define      FLD_CLK_INVERT           0x00002000
+#define      FLD_HSFMT                0x00001000
+#define      FLD_VALIDFMT             0x00000800
+#define      FLD_ACTFMT               0x00000400
+#define      FLD_SWAPRAW              0x00000200
+#define      FLD_CLAMPRAW_EN          0x00000100
+#define      FLD_BLUE_FIELD_EN        0x00000080
+#define      FLD_BLUE_FIELD_ACT       0x00000040
+#define      FLD_TASKBIT_VAL          0x00000020
+#define      FLD_ANC_DATA_EN          0x00000010
+#define      FLD_VBIHACTRAW_EN        0x00000008
+#define      FLD_MODE10B              0x00000004
+#define      FLD_OUT_MODE             0x00000003
+
+/*****************************************************************************/
+#define      OUT_CTRL2                0x408
+#define      FLD_AUD_GRP              0xc0000000
+#define      FLD_SAMPLE_RATE          0x30000000
+#define      FLD_AUD_ANC_EN           0x08000000
+#define      FLD_EN_C                 0x04000000
+#define      FLD_EN_B                 0x02000000
+#define      FLD_EN_A                 0x01000000
+/* Reserved [23:20] */
+#define      FLD_IDID1_LSB            0x000c0000
+#define      FLD_IDID0_LSB            0x00030000
+#define      FLD_IDID1_MSB            0x0000ff00
+#define      FLD_IDID0_MSB            0x000000ff
+
+/*****************************************************************************/
+#define      GEN_STAT                 0x40c
+#define      FLD_VCR_DETECT           0x00800000
+#define      FLD_SPECIAL_PLAY_N       0x00400000
+#define      FLD_VPRES                0x00200000
+#define      FLD_AGC_LOCK             0x00100000
+#define      FLD_CSC_LOCK             0x00080000
+#define      FLD_VLOCK                0x00040000
+#define      FLD_SRC_LOCK             0x00020000
+#define      FLD_HLOCK                0x00010000
+#define      FLD_VSYNC_N              0x00008000
+#define      FLD_SRC_FIFO_UFLOW       0x00004000
+#define      FLD_SRC_FIFO_OFLOW       0x00002000
+#define      FLD_FIELD                0x00001000
+#define      FLD_AFD_FMT_STAT         0x00000f00
+#define      FLD_MV_TYPE2_PAIR        0x00000080
+#define      FLD_MV_T3CS              0x00000040
+#define      FLD_MV_CS                0x00000020
+#define      FLD_MV_PSP               0x00000010
+/* Reserved [3] */
+#define      FLD_MV_CDAT              0x00000003
+
+/*****************************************************************************/
+#define      INT_STAT_MASK            0x410
+#define      FLD_COMB_3D_FIFO_MSK     0x80000000
+#define      FLD_WSS_DAT_AVAIL_MSK    0x40000000
+#define      FLD_GS2_DAT_AVAIL_MSK    0x20000000
+#define      FLD_GS1_DAT_AVAIL_MSK    0x10000000
+#define      FLD_CC_DAT_AVAIL_MSK     0x08000000
+#define      FLD_VPRES_CHANGE_MSK     0x04000000
+#define      FLD_MV_CHANGE_MSK        0x02000000
+#define      FLD_END_VBI_EVEN_MSK     0x01000000
+#define      FLD_END_VBI_ODD_MSK      0x00800000
+#define      FLD_FMT_CHANGE_MSK       0x00400000
+#define      FLD_VSYNC_TRAIL_MSK      0x00200000
+#define      FLD_HLOCK_CHANGE_MSK     0x00100000
+#define      FLD_VLOCK_CHANGE_MSK     0x00080000
+#define      FLD_CSC_LOCK_CHANGE_MSK  0x00040000
+#define      FLD_SRC_FIFO_UFLOW_MSK   0x00020000
+#define      FLD_SRC_FIFO_OFLOW_MSK   0x00010000
+#define      FLD_COMB_3D_FIFO_STAT    0x00008000
+#define      FLD_WSS_DAT_AVAIL_STAT   0x00004000
+#define      FLD_GS2_DAT_AVAIL_STAT   0x00002000
+#define      FLD_GS1_DAT_AVAIL_STAT   0x00001000
+#define      FLD_CC_DAT_AVAIL_STAT    0x00000800
+#define      FLD_VPRES_CHANGE_STAT    0x00000400
+#define      FLD_MV_CHANGE_STAT       0x00000200
+#define      FLD_END_VBI_EVEN_STAT    0x00000100
+#define      FLD_END_VBI_ODD_STAT     0x00000080
+#define      FLD_FMT_CHANGE_STAT      0x00000040
+#define      FLD_VSYNC_TRAIL_STAT     0x00000020
+#define      FLD_HLOCK_CHANGE_STAT    0x00000010
+#define      FLD_VLOCK_CHANGE_STAT    0x00000008
+#define      FLD_CSC_LOCK_CHANGE_STAT 0x00000004
+#define      FLD_SRC_FIFO_UFLOW_STAT  0x00000002
+#define      FLD_SRC_FIFO_OFLOW_STAT  0x00000001
+
+/*****************************************************************************/
+#define      LUMA_CTRL                0x414
+#define      BRIGHTNESS_CTRL_BYTE     0x414
+#define      CONTRAST_CTRL_BYTE       0x415
+#define      LUMA_CTRL_BYTE_3         0x416
+#define      FLD_LUMA_CORE_SEL        0x00c00000
+#define      FLD_RANGE                0x00300000
+/* Reserved [19] */
+#define      FLD_PEAK_EN              0x00040000
+#define      FLD_PEAK_SEL             0x00030000
+#define      FLD_CNTRST               0x0000ff00
+#define      FLD_BRITE                0x000000ff
+
+/*****************************************************************************/
+#define      HSCALE_CTRL              0x418
+#define      FLD_HFILT                0x03000000
+#define      FLD_HSCALE               0x00ffffff
+
+/*****************************************************************************/
+#define      VSCALE_CTRL              0x41c
+#define      FLD_LINE_AVG_DIS         0x01000000
+/* Reserved [23:20] */
+#define      FLD_VS_INTRLACE          0x00080000
+#define      FLD_VFILT                0x00070000
+/* Reserved [15:13] */
+#define      FLD_VSCALE               0x00001fff
+
+/*****************************************************************************/
+#define      CHROMA_CTRL              0x420
+#define      USAT_CTRL_BYTE           0x420
+#define      VSAT_CTRL_BYTE           0x421
+#define      HUE_CTRL_BYTE            0x422
+#define      FLD_C_LPF_EN             0x20000000
+#define      FLD_CHR_DELAY            0x1c000000
+#define      FLD_C_CORE_SEL           0x03000000
+#define      FLD_HUE                  0x00ff0000
+#define      FLD_VSAT                 0x0000ff00
+#define      FLD_USAT                 0x000000ff
+
+/*****************************************************************************/
+#define      VBI_LINE_CTRL1           0x424
+#define      FLD_VBI_MD_LINE4         0xff000000
+#define      FLD_VBI_MD_LINE3         0x00ff0000
+#define      FLD_VBI_MD_LINE2         0x0000ff00
+#define      FLD_VBI_MD_LINE1         0x000000ff
+
+/*****************************************************************************/
+#define      VBI_LINE_CTRL2           0x428
+#define      FLD_VBI_MD_LINE8         0xff000000
+#define      FLD_VBI_MD_LINE7         0x00ff0000
+#define      FLD_VBI_MD_LINE6         0x0000ff00
+#define      FLD_VBI_MD_LINE5         0x000000ff
+
+/*****************************************************************************/
+#define      VBI_LINE_CTRL3           0x42c
+#define      FLD_VBI_MD_LINE12        0xff000000
+#define      FLD_VBI_MD_LINE11        0x00ff0000
+#define      FLD_VBI_MD_LINE10        0x0000ff00
+#define      FLD_VBI_MD_LINE9         0x000000ff
+
+/*****************************************************************************/
+#define      VBI_LINE_CTRL4           0x430
+#define      FLD_VBI_MD_LINE16        0xff000000
+#define      FLD_VBI_MD_LINE15        0x00ff0000
+#define      FLD_VBI_MD_LINE14        0x0000ff00
+#define      FLD_VBI_MD_LINE13        0x000000ff
+
+/*****************************************************************************/
+#define      VBI_LINE_CTRL5           0x434
+#define      FLD_VBI_MD_LINE17        0x000000ff
+
+/*****************************************************************************/
+#define      VBI_FC_CFG               0x438
+#define      FLD_FC_ALT2              0xff000000
+#define      FLD_FC_ALT1              0x00ff0000
+#define      FLD_FC_ALT2_TYPE         0x0000f000
+#define      FLD_FC_ALT1_TYPE         0x00000f00
+/* Reserved [7:1] */
+#define      FLD_FC_SEARCH_MODE       0x00000001
+
+/*****************************************************************************/
+#define      VBI_MISC_CFG1            0x43c
+#define      FLD_TTX_PKTADRU          0xfff00000
+#define      FLD_TTX_PKTADRL          0x000fff00
+/* Reserved [7:6] */
+#define      FLD_MOJI_PACK_DIS        0x00000020
+#define      FLD_VPS_DEC_DIS          0x00000010
+#define      FLD_CRI_MARG_SCALE       0x0000000c
+#define      FLD_EDGE_RESYNC_EN       0x00000002
+#define      FLD_ADAPT_SLICE_DIS      0x00000001
+
+/*****************************************************************************/
+#define      VBI_MISC_CFG2            0x440
+#define      FLD_HAMMING_TYPE         0x0f000000
+/* Reserved [23:20] */
+#define      FLD_WSS_FIFO_RST         0x00080000
+#define      FLD_GS2_FIFO_RST         0x00040000
+#define      FLD_GS1_FIFO_RST         0x00020000
+#define      FLD_CC_FIFO_RST          0x00010000
+/* Reserved [15:12] */
+#define      FLD_VBI3_SDID            0x00000f00
+#define      FLD_VBI2_SDID            0x000000f0
+#define      FLD_VBI1_SDID            0x0000000f
+
+/*****************************************************************************/
+#define      VBI_PAY1                 0x444
+#define      FLD_GS1_FIFO_DAT         0xFF000000
+#define      FLD_GS1_STAT             0x00FF0000
+#define      FLD_CC_FIFO_DAT          0x0000FF00
+#define      FLD_CC_STAT              0x000000FF
+
+/*****************************************************************************/
+#define      VBI_PAY2                 0x448
+#define      FLD_WSS_FIFO_DAT         0xff000000
+#define      FLD_WSS_STAT             0x00ff0000
+#define      FLD_GS2_FIFO_DAT         0x0000ff00
+#define      FLD_GS2_STAT             0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST1_CFG1           0x44c
+/* Reserved [31] */
+#define      FLD_VBI1_CRIWIN          0x7f000000
+#define      FLD_VBI1_SLICE_DIST      0x00f00000
+#define      FLD_VBI1_BITINC          0x000fff00
+#define      FLD_VBI1_HDELAY          0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST1_CFG2           0x450
+#define      FLD_VBI1_FC_LENGTH       0x1f000000
+#define      FLD_VBI1_FRAME_CODE      0x00ffffff
+
+/*****************************************************************************/
+#define      VBI_CUST1_CFG3           0x454
+#define      FLD_VBI1_HAM_EN          0x80000000
+#define      FLD_VBI1_FIFO_MODE       0x70000000
+#define      FLD_VBI1_FORMAT_TYPE     0x0f000000
+#define      FLD_VBI1_PAYLD_LENGTH    0x00ff0000
+#define      FLD_VBI1_CRI_LENGTH      0x0000f000
+#define      FLD_VBI1_CRI_MARGIN      0x00000f00
+#define      FLD_VBI1_CRI_TIME        0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST2_CFG1           0x458
+/* Reserved [31] */
+#define      FLD_VBI2_CRIWIN          0x7f000000
+#define      FLD_VBI2_SLICE_DIST      0x00f00000
+#define      FLD_VBI2_BITINC          0x000fff00
+#define      FLD_VBI2_HDELAY          0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST2_CFG2           0x45c
+#define      FLD_VBI2_FC_LENGTH       0x1f000000
+#define      FLD_VBI2_FRAME_CODE      0x00ffffff
+
+/*****************************************************************************/
+#define      VBI_CUST2_CFG3           0x460
+#define      FLD_VBI2_HAM_EN          0x80000000
+#define      FLD_VBI2_FIFO_MODE       0x70000000
+#define      FLD_VBI2_FORMAT_TYPE     0x0f000000
+#define      FLD_VBI2_PAYLD_LENGTH    0x00ff0000
+#define      FLD_VBI2_CRI_LENGTH      0x0000f000
+#define      FLD_VBI2_CRI_MARGIN      0x00000f00
+#define      FLD_VBI2_CRI_TIME        0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST3_CFG1           0x464
+/* Reserved [31] */
+#define      FLD_VBI3_CRIWIN          0x7f000000
+#define      FLD_VBI3_SLICE_DIST      0x00f00000
+#define      FLD_VBI3_BITINC          0x000fff00
+#define      FLD_VBI3_HDELAY          0x000000ff
+
+/*****************************************************************************/
+#define      VBI_CUST3_CFG2           0x468
+#define      FLD_VBI3_FC_LENGTH       0x1f000000
+#define      FLD_VBI3_FRAME_CODE      0x00ffffff
+
+/*****************************************************************************/
+#define      VBI_CUST3_CFG3           0x46c
+#define      FLD_VBI3_HAM_EN          0x80000000
+#define      FLD_VBI3_FIFO_MODE       0x70000000
+#define      FLD_VBI3_FORMAT_TYPE     0x0f000000
+#define      FLD_VBI3_PAYLD_LENGTH    0x00ff0000
+#define      FLD_VBI3_CRI_LENGTH      0x0000f000
+#define      FLD_VBI3_CRI_MARGIN      0x00000f00
+#define      FLD_VBI3_CRI_TIME        0x000000ff
+
+/*****************************************************************************/
+#define      HORIZ_TIM_CTRL           0x470
+#define      FLD_BGDEL_CNT            0xff000000
+/* Reserved [23:22] */
+#define      FLD_HACTIVE_CNT          0x003ff000
+/* Reserved [11:10] */
+#define      FLD_HBLANK_CNT           0x000003ff
+
+/*****************************************************************************/
+#define      VERT_TIM_CTRL            0x474
+#define      FLD_V656BLANK_CNT        0xff000000
+/* Reserved [23:22] */
+#define      FLD_VACTIVE_CNT          0x003ff000
+/* Reserved [11:10] */
+#define      FLD_VBLANK_CNT           0x000003ff
+
+/*****************************************************************************/
+#define      SRC_COMB_CFG             0x478
+#define      FLD_CCOMB_2LN_CHECK      0x80000000
+#define      FLD_CCOMB_3LN_EN         0x40000000
+#define      FLD_CCOMB_2LN_EN         0x20000000
+#define      FLD_CCOMB_3D_EN          0x10000000
+/* Reserved [27] */
+#define      FLD_LCOMB_3LN_EN         0x04000000
+#define      FLD_LCOMB_2LN_EN         0x02000000
+#define      FLD_LCOMB_3D_EN          0x01000000
+#define      FLD_LUMA_LPF_SEL         0x00c00000
+#define      FLD_UV_LPF_SEL           0x00300000
+#define      FLD_BLEND_SLOPE          0x000f0000
+#define      FLD_CCOMB_REDUCE_EN      0x00008000
+/* Reserved [14:10] */
+#define      FLD_SRC_DECIM_RATIO      0x000003ff
+
+/*****************************************************************************/
+#define      CHROMA_VBIOFF_CFG        0x47c
+#define      FLD_VBI_VOFFSET          0x1f000000
+/* Reserved [23:20] */
+#define      FLD_SC_STEP              0x000fffff
+
+/*****************************************************************************/
+#define      FIELD_COUNT              0x480
+#define      FLD_FIELD_COUNT_FLD      0x000003ff
+
+/*****************************************************************************/
+#define      MISC_TIM_CTRL            0x484
+#define      FLD_DEBOUNCE_COUNT       0xc0000000
+#define      FLD_VT_LINE_CNT_HYST     0x30000000
+/* Reserved [27] */
+#define      FLD_AFD_STAT             0x07ff0000
+#define      FLD_VPRES_VERT_EN        0x00008000
+/* Reserved [14:12] */
+#define      FLD_HR32                 0x00000800
+#define      FLD_TDALGN               0x00000400
+#define      FLD_TDFIELD              0x00000200
+/* Reserved [8:6] */
+#define      FLD_TEMPDEC              0x0000003f
+
+/*****************************************************************************/
+#define      DFE_CTRL1                0x488
+#define      FLD_CLAMP_AUTO_EN        0x80000000
+#define      FLD_AGC_AUTO_EN          0x40000000
+#define      FLD_VGA_CRUSH_EN         0x20000000
+#define      FLD_VGA_AUTO_EN          0x10000000
+#define      FLD_VBI_GATE_EN          0x08000000
+#define      FLD_CLAMP_LEVEL          0x07000000
+/* Reserved [23:22] */
+#define      FLD_CLAMP_SKIP_CNT       0x00300000
+#define      FLD_AGC_GAIN             0x000fff00
+/* Reserved [7:6] */
+#define      FLD_VGA_GAIN             0x0000003f
+
+/*****************************************************************************/
+#define      DFE_CTRL2                0x48c
+#define      FLD_VGA_ACQUIRE_RANGE    0x00ff0000
+#define      FLD_VGA_TRACK_RANGE      0x0000ff00
+#define      FLD_VGA_SYNC             0x000000ff
+
+/*****************************************************************************/
+#define      DFE_CTRL3                0x490
+#define      FLD_BP_PERCENT           0xff000000
+#define      FLD_DFT_THRESHOLD        0x00ff0000
+/* Reserved [15:12] */
+#define      FLD_SYNC_WIDTH_SEL       0x00000600
+#define      FLD_BP_LOOP_GAIN         0x00000300
+#define      FLD_SYNC_LOOP_GAIN       0x000000c0
+/* Reserved [5:4] */
+#define      FLD_AGC_LOOP_GAIN        0x0000000c
+#define      FLD_DCC_LOOP_GAIN        0x00000003
+
+/*****************************************************************************/
+#define      PLL_CTRL                 0x494
+#define      FLD_PLL_KD               0xff000000
+#define      FLD_PLL_KI               0x00ff0000
+#define      FLD_PLL_MAX_OFFSET       0x0000ffff
+
+/*****************************************************************************/
+#define      HTL_CTRL                 0x498
+/* Reserved [31:24] */
+#define      FLD_AUTO_LOCK_SPD        0x00080000
+#define      FLD_MAN_FAST_LOCK        0x00040000
+#define      FLD_HTL_15K_EN           0x00020000
+#define      FLD_HTL_500K_EN          0x00010000
+#define      FLD_HTL_KD               0x0000ff00
+#define      FLD_HTL_KI               0x000000ff
+
+/*****************************************************************************/
+#define      COMB_CTRL                0x49c
+#define      FLD_COMB_PHASE_LIMIT     0xff000000
+#define      FLD_CCOMB_ERR_LIMIT      0x00ff0000
+#define      FLD_LUMA_THRESHOLD       0x0000ff00
+#define      FLD_LCOMB_ERR_LIMIT      0x000000ff
+
+/*****************************************************************************/
+#define      CRUSH_CTRL               0x4a0
+#define      FLD_WTW_EN               0x00400000
+#define      FLD_CRUSH_FREQ           0x00200000
+#define      FLD_MAJ_SEL_EN           0x00100000
+#define      FLD_MAJ_SEL              0x000c0000
+/* Reserved [17:15] */
+#define      FLD_SYNC_TIP_REDUCE      0x00007e00
+/* Reserved [8:6] */
+#define      FLD_SYNC_TIP_INC         0x0000003f
+
+/*****************************************************************************/
+#define      SOFT_RST_CTRL            0x4a4
+#define      FLD_VD_SOFT_RST          0x00008000
+/* Reserved [14:12] */
+#define      FLD_REG_RST_MSK          0x00000800
+#define      FLD_VOF_RST_MSK          0x00000400
+#define      FLD_MVDET_RST_MSK        0x00000200
+#define      FLD_VBI_RST_MSK          0x00000100
+#define      FLD_SCALE_RST_MSK        0x00000080
+#define      FLD_CHROMA_RST_MSK       0x00000040
+#define      FLD_LUMA_RST_MSK         0x00000020
+#define      FLD_VTG_RST_MSK          0x00000010
+#define      FLD_YCSEP_RST_MSK        0x00000008
+#define      FLD_SRC_RST_MSK          0x00000004
+#define      FLD_DFE_RST_MSK          0x00000002
+/* Reserved [0] */
+
+/*****************************************************************************/
+#define      MV_DT_CTRL1              0x4a8
+/* Reserved [31:29] */
+#define      FLD_PSP_STOP_LINE        0x1f000000
+/* Reserved [23:21] */
+#define      FLD_PSP_STRT_LINE        0x001f0000
+/* Reserved [15] */
+#define      FLD_PSP_LLIMW            0x00007f00
+/* Reserved [7] */
+#define      FLD_PSP_ULIMW            0x0000007f
+
+/*****************************************************************************/
+#define      MV_DT_CTRL2              0x4aC
+#define      FLD_CS_STOPWIN           0xff000000
+#define      FLD_CS_STRTWIN           0x00ff0000
+#define      FLD_CS_WIDTH             0x0000ff00
+#define      FLD_PSP_SPEC_VAL         0x000000ff
+
+/*****************************************************************************/
+#define      MV_DT_CTRL3              0x4B0
+#define      FLD_AUTO_RATE_DIS        0x80000000
+#define      FLD_HLOCK_DIS            0x40000000
+#define      FLD_SEL_FIELD_CNT        0x20000000
+#define      FLD_CS_TYPE2_SEL         0x10000000
+#define      FLD_CS_LINE_THRSH_SEL    0x08000000
+#define      FLD_CS_ATHRESH_SEL       0x04000000
+#define      FLD_PSP_SPEC_SEL         0x02000000
+#define      FLD_PSP_LINES_SEL        0x01000000
+#define      FLD_FIELD_CNT            0x00f00000
+#define      FLD_CS_TYPE2_CNT         0x000fc000
+#define      FLD_CS_LINE_CNT          0x00003f00
+#define      FLD_CS_ATHRESH_LEV       0x000000ff
+
+/*****************************************************************************/
+#define      CHIP_VERSION             0x4b4
+/* Cx231xx redefine  */
+#define      VERSION                  0x4b4
+#define      FLD_REV_ID               0x000000ff
+
+/*****************************************************************************/
+#define      MISC_DIAG_CTRL           0x4b8
+/* Reserved [31:24] */
+#define      FLD_SC_CONVERGE_THRESH   0x00ff0000
+#define      FLD_CCOMB_ERR_LIMIT_3D   0x0000ff00
+#define      FLD_LCOMB_ERR_LIMIT_3D   0x000000ff
+
+/*****************************************************************************/
+#define      VBI_PASS_CTRL            0x4bc
+#define      FLD_VBI_PASS_MD          0x00200000
+#define      FLD_VBI_SETUP_DIS        0x00100000
+#define      FLD_PASS_LINE_CTRL       0x000fffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      VCR_DET_CTRL             0x4c0
+#define      FLD_EN_FIELD_PHASE_DET   0x80000000
+#define      FLD_EN_HEAD_SW_DET       0x40000000
+#define      FLD_FIELD_PHASE_LENGTH   0x01ff0000
+/* Reserved [29:25] */
+#define      FLD_FIELD_PHASE_DELAY    0x0000ff00
+#define      FLD_FIELD_PHASE_LIMIT    0x000000f0
+#define      FLD_HEAD_SW_DET_LIMIT    0x0000000f
+
+/*****************************************************************************/
+#define      DL_CTL                   0x800
+#define      DL_CTL_ADDRESS_LOW       0x800    /* Byte 1 in DL_CTL */
+#define      DL_CTL_ADDRESS_HIGH      0x801    /* Byte 2 in DL_CTL */
+#define      DL_CTL_DATA              0x802    /* Byte 3 in DL_CTL */
+#define      DL_CTL_CONTROL           0x803    /* Byte 4 in DL_CTL */
+/* Reserved [31:5] */
+#define      FLD_START_8051           0x10000000
+#define      FLD_DL_ENABLE            0x08000000
+#define      FLD_DL_AUTO_INC          0x04000000
+#define      FLD_DL_MAP               0x03000000
+
+/*****************************************************************************/
+#define      STD_DET_STATUS           0x804
+#define      FLD_SPARE_STATUS1        0xff000000
+#define      FLD_SPARE_STATUS0        0x00ff0000
+#define      FLD_MOD_DET_STATUS1      0x0000ff00
+#define      FLD_MOD_DET_STATUS0      0x000000ff
+
+/*****************************************************************************/
+#define      AUD_BUILD_NUM            0x806
+#define      AUD_VER_NUM              0x807
+#define      STD_DET_CTL              0x808
+#define      STD_DET_CTL_AUD_CTL      0x808    /* Byte 1 in STD_DET_CTL */
+#define      STD_DET_CTL_PREF_MODE    0x809    /* Byte 2 in STD_DET_CTL */
+#define      FLD_SPARE_CTL0           0xff000000
+#define      FLD_DIS_DBX              0x00800000
+#define      FLD_DIS_BTSC             0x00400000
+#define      FLD_DIS_NICAM_A2         0x00200000
+#define      FLD_VIDEO_PRESENT        0x00100000
+#define      FLD_DW8051_VIDEO_FORMAT  0x000f0000
+#define      FLD_PREF_DEC_MODE        0x0000ff00
+#define      FLD_AUD_CONFIG           0x000000ff
+
+/*****************************************************************************/
+#define      DW8051_INT               0x80c
+#define      FLD_VIDEO_PRESENT_CHANGE 0x80000000
+#define      FLD_VIDEO_CHANGE         0x40000000
+#define      FLD_RDS_READY            0x20000000
+#define      FLD_AC97_INT             0x10000000
+#define      FLD_NICAM_BIT_ERROR_TOO_HIGH         0x08000000
+#define      FLD_NICAM_LOCK           0x04000000
+#define      FLD_NICAM_UNLOCK         0x02000000
+#define      FLD_DFT4_TH_CMP          0x01000000
+/* Reserved [23:22] */
+#define      FLD_LOCK_IND_INT         0x00200000
+#define      FLD_DFT3_TH_CMP          0x00100000
+#define      FLD_DFT2_TH_CMP          0x00080000
+#define      FLD_DFT1_TH_CMP          0x00040000
+#define      FLD_FM2_DFT_TH_CMP       0x00020000
+#define      FLD_FM1_DFT_TH_CMP       0x00010000
+#define      FLD_VIDEO_PRESENT_EN     0x00008000
+#define      FLD_VIDEO_CHANGE_EN      0x00004000
+#define      FLD_RDS_READY_EN         0x00002000
+#define      FLD_AC97_INT_EN          0x00001000
+#define      FLD_NICAM_BIT_ERROR_TOO_HIGH_EN      0x00000800
+#define      FLD_NICAM_LOCK_EN        0x00000400
+#define      FLD_NICAM_UNLOCK_EN      0x00000200
+#define      FLD_DFT4_TH_CMP_EN       0x00000100
+/* Reserved [7] */
+#define      FLD_DW8051_INT6_CTL1     0x00000040
+#define      FLD_DW8051_INT5_CTL1     0x00000020
+#define      FLD_DW8051_INT4_CTL1     0x00000010
+#define      FLD_DW8051_INT3_CTL1     0x00000008
+#define      FLD_DW8051_INT2_CTL1     0x00000004
+#define      FLD_DW8051_INT1_CTL1     0x00000002
+#define      FLD_DW8051_INT0_CTL1     0x00000001
+
+/*****************************************************************************/
+#define      GENERAL_CTL              0x810
+#define      FLD_RDS_INT              0x80000000
+#define      FLD_NBER_INT             0x40000000
+#define      FLD_NLL_INT              0x20000000
+#define      FLD_IFL_INT              0x10000000
+#define      FLD_FDL_INT              0x08000000
+#define      FLD_AFC_INT              0x04000000
+#define      FLD_AMC_INT              0x02000000
+#define      FLD_AC97_INT_CTL         0x01000000
+#define      FLD_RDS_INT_DIS          0x00800000
+#define      FLD_NBER_INT_DIS         0x00400000
+#define      FLD_NLL_INT_DIS          0x00200000
+#define      FLD_IFL_INT_DIS          0x00100000
+#define      FLD_FDL_INT_DIS          0x00080000
+#define      FLD_FC_INT_DIS           0x00040000
+#define      FLD_AMC_INT_DIS          0x00020000
+#define      FLD_AC97_INT_DIS         0x00010000
+#define      FLD_REV_NUM              0x0000ff00
+/* Reserved [7:5] */
+#define      FLD_DBX_SOFT_RESET_REG   0x00000010
+#define      FLD_AD_SOFT_RESET_REG    0x00000008
+#define      FLD_SRC_SOFT_RESET_REG   0x00000004
+#define      FLD_CDMOD_SOFT_RESET     0x00000002
+#define      FLD_8051_SOFT_RESET      0x00000001
+
+/*****************************************************************************/
+#define      AAGC_CTL                 0x814
+#define      FLD_AFE_12DB_EN          0x80000000
+#define      FLD_AAGC_DEFAULT_EN      0x40000000
+#define      FLD_AAGC_DEFAULT         0x3f000000
+/* Reserved [23] */
+#define      FLD_AAGC_GAIN            0x00600000
+#define      FLD_AAGC_TH              0x001f0000
+/* Reserved [15:14] */
+#define      FLD_AAGC_HYST2           0x00003f00
+/* Reserved [7:6] */
+#define      FLD_AAGC_HYST1           0x0000003f
+
+/*****************************************************************************/
+#define      IF_SRC_CTL               0x818
+#define      FLD_DBX_BYPASS           0x80000000
+/* Reserved [30:25] */
+#define      FLD_IF_SRC_MODE          0x01000000
+/* Reserved [23:18] */
+#define      FLD_IF_SRC_PHASE_INC     0x0001ffff
+
+/*****************************************************************************/
+#define      ANALOG_DEMOD_CTL         0x81c
+#define      FLD_ROT1_PHACC_PROG      0xffff0000
+/* Reserved [15] */
+#define      FLD_FM1_DELAY_FIX        0x00007000
+#define      FLD_PDF4_SHIFT           0x00000c00
+#define      FLD_PDF3_SHIFT           0x00000300
+#define      FLD_PDF2_SHIFT           0x000000c0
+#define      FLD_PDF1_SHIFT           0x00000030
+#define      FLD_FMBYPASS_MODE2       0x00000008
+#define      FLD_FMBYPASS_MODE1       0x00000004
+#define      FLD_NICAM_MODE           0x00000002
+#define      FLD_BTSC_FMRADIO_MODE    0x00000001
+
+/*****************************************************************************/
+#define      ROT_FREQ_CTL             0x820
+#define      FLD_ROT3_PHACC_PROG      0xffff0000
+#define      FLD_ROT2_PHACC_PROG      0x0000ffff
+
+/*****************************************************************************/
+#define      FM_CTL                   0x824
+#define      FLD_FM2_DC_FB_SHIFT      0xf0000000
+#define      FLD_FM2_DC_INT_SHIFT     0x0f000000
+#define      FLD_FM2_AFC_RESET        0x00800000
+#define      FLD_FM2_DC_PASS_IN       0x00400000
+#define      FLD_FM2_DAGC_SHIFT       0x00380000
+#define      FLD_FM2_CORDIC_SHIFT     0x00070000
+#define      FLD_FM1_DC_FB_SHIFT      0x0000f000
+#define      FLD_FM1_DC_INT_SHIFT     0x00000f00
+#define      FLD_FM1_AFC_RESET        0x00000080
+#define      FLD_FM1_DC_PASS_IN       0x00000040
+#define      FLD_FM1_DAGC_SHIFT       0x00000038
+#define      FLD_FM1_CORDIC_SHIFT     0x00000007
+
+/*****************************************************************************/
+#define      LPF_PDF_CTL              0x828
+/* Reserved [31:30] */
+#define      FLD_LPF32_SHIFT1         0x30000000
+#define      FLD_LPF32_SHIFT2         0x0c000000
+#define      FLD_LPF160_SHIFTA        0x03000000
+#define      FLD_LPF160_SHIFTB        0x00c00000
+#define      FLD_LPF160_SHIFTC        0x00300000
+#define      FLD_LPF32_COEF_SEL2      0x000c0000
+#define      FLD_LPF32_COEF_SEL1      0x00030000
+#define      FLD_LPF160_COEF_SELC     0x0000c000
+#define      FLD_LPF160_COEF_SELB     0x00003000
+#define      FLD_LPF160_COEF_SELA     0x00000c00
+#define      FLD_LPF160_IN_EN_REG     0x00000300
+#define      FLD_PDF4_PDF_SEL         0x000000c0
+#define      FLD_PDF3_PDF_SEL         0x00000030
+#define      FLD_PDF2_PDF_SEL         0x0000000c
+#define      FLD_PDF1_PDF_SEL         0x00000003
+
+/*****************************************************************************/
+#define      DFT1_CTL1                0x82c
+#define      FLD_DFT1_DWELL           0xffff0000
+#define      FLD_DFT1_FREQ            0x0000ffff
+
+/*****************************************************************************/
+#define      DFT1_CTL2                0x830
+#define      FLD_DFT1_THRESHOLD       0xffffff00
+#define      FLD_DFT1_CMP_CTL         0x00000080
+#define      FLD_DFT1_AVG             0x00000070
+/* Reserved [3:1] */
+#define      FLD_DFT1_START           0x00000001
+
+/*****************************************************************************/
+#define      DFT1_STATUS              0x834
+#define      FLD_DFT1_DONE            0x80000000
+#define      FLD_DFT1_TH_CMP_STAT     0x40000000
+#define      FLD_DFT1_RESULT          0x3fffffff
+
+/*****************************************************************************/
+#define      DFT2_CTL1                0x838
+#define      FLD_DFT2_DWELL           0xffff0000
+#define      FLD_DFT2_FREQ            0x0000ffff
+
+/*****************************************************************************/
+#define      DFT2_CTL2                0x83C
+#define      FLD_DFT2_THRESHOLD       0xffffff00
+#define      FLD_DFT2_CMP_CTL         0x00000080
+#define      FLD_DFT2_AVG             0x00000070
+/* Reserved [3:1] */
+#define      FLD_DFT2_START           0x00000001
+
+/*****************************************************************************/
+#define      DFT2_STATUS              0x840
+#define      FLD_DFT2_DONE            0x80000000
+#define      FLD_DFT2_TH_CMP_STAT     0x40000000
+#define      FLD_DFT2_RESULT          0x3fffffff
+
+/*****************************************************************************/
+#define      DFT3_CTL1                0x844
+#define      FLD_DFT3_DWELL           0xffff0000
+#define      FLD_DFT3_FREQ            0x0000ffff
+
+/*****************************************************************************/
+#define      DFT3_CTL2                0x848
+#define      FLD_DFT3_THRESHOLD       0xffffff00
+#define      FLD_DFT3_CMP_CTL         0x00000080
+#define      FLD_DFT3_AVG             0x00000070
+/* Reserved [3:1] */
+#define      FLD_DFT3_START           0x00000001
+
+/*****************************************************************************/
+#define      DFT3_STATUS              0x84c
+#define      FLD_DFT3_DONE            0x80000000
+#define      FLD_DFT3_TH_CMP_STAT     0x40000000
+#define      FLD_DFT3_RESULT          0x3fffffff
+
+/*****************************************************************************/
+#define      DFT4_CTL1                0x850
+#define      FLD_DFT4_DWELL           0xffff0000
+#define      FLD_DFT4_FREQ            0x0000ffff
+
+/*****************************************************************************/
+#define      DFT4_CTL2                0x854
+#define      FLD_DFT4_THRESHOLD       0xffffff00
+#define      FLD_DFT4_CMP_CTL         0x00000080
+#define      FLD_DFT4_AVG             0x00000070
+/* Reserved [3:1] */
+#define      FLD_DFT4_START           0x00000001
+
+/*****************************************************************************/
+#define      DFT4_STATUS              0x858
+#define      FLD_DFT4_DONE            0x80000000
+#define      FLD_DFT4_TH_CMP_STAT     0x40000000
+#define      FLD_DFT4_RESULT          0x3fffffff
+
+/*****************************************************************************/
+#define      AM_MTS_DET               0x85c
+#define      FLD_AM_MTS_MODE          0x80000000
+/* Reserved [30:26] */
+#define      FLD_AM_SUB               0x02000000
+#define      FLD_AM_GAIN_EN           0x01000000
+/* Reserved [23:16] */
+#define      FLD_AMMTS_GAIN_SCALE     0x0000e000
+#define      FLD_MTS_PDF_SHIFT        0x00001800
+#define      FLD_AM_REG_GAIN          0x00000700
+#define      FLD_AGC_REF              0x000000ff
+
+/*****************************************************************************/
+#define      ANALOG_MUX_CTL           0x860
+/* Reserved [31:29] */
+#define      FLD_MUX21_SEL            0x10000000
+#define      FLD_MUX20_SEL            0x08000000
+#define      FLD_MUX19_SEL            0x04000000
+#define      FLD_MUX18_SEL            0x02000000
+#define      FLD_MUX17_SEL            0x01000000
+#define      FLD_MUX16_SEL            0x00800000
+#define      FLD_MUX15_SEL            0x00400000
+#define      FLD_MUX14_SEL            0x00300000
+#define      FLD_MUX13_SEL            0x000C0000
+#define      FLD_MUX12_SEL            0x00020000
+#define      FLD_MUX11_SEL            0x00018000
+#define      FLD_MUX10_SEL            0x00004000
+#define      FLD_MUX9_SEL             0x00002000
+#define      FLD_MUX8_SEL             0x00001000
+#define      FLD_MUX7_SEL             0x00000800
+#define      FLD_MUX6_SEL             0x00000600
+#define      FLD_MUX5_SEL             0x00000100
+#define      FLD_MUX4_SEL             0x000000c0
+#define      FLD_MUX3_SEL             0x00000030
+#define      FLD_MUX2_SEL             0x0000000c
+#define      FLD_MUX1_SEL             0x00000003
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DPLL_CTRL1               0x864
+#define      DIG_PLL_CTL1             0x864
+
+#define      FLD_PLL_STATUS           0x07000000
+#define      FLD_BANDWIDTH_SELECT     0x00030000
+#define      FLD_PLL_SHIFT_REG        0x00007000
+#define      FLD_PHASE_SHIFT          0x000007ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DPLL_CTRL2               0x868
+#define      DIG_PLL_CTL2             0x868
+#define      FLD_PLL_UNLOCK_THR       0xff000000
+#define      FLD_PLL_LOCK_THR         0x00ff0000
+/* Reserved [15:8] */
+#define      FLD_AM_PDF_SEL2          0x000000c0
+#define      FLD_AM_PDF_SEL1          0x00000030
+#define      FLD_DPLL_FSM_CTRL        0x0000000c
+/* Reserved [1] */
+#define      FLD_PLL_PILOT_DET        0x00000001
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DPLL_CTRL3               0x86c
+#define      DIG_PLL_CTL3             0x86c
+#define      FLD_DISABLE_LOOP         0x01000000
+#define      FLD_A1_DS1_SEL           0x000c0000
+#define      FLD_A1_DS2_SEL           0x00030000
+#define      FLD_A1_KI                0x0000ff00
+#define      FLD_A1_KD                0x000000ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DPLL_CTRL4               0x870
+#define      DIG_PLL_CTL4             0x870
+#define      FLD_A2_DS1_SEL           0x000c0000
+#define      FLD_A2_DS2_SEL           0x00030000
+#define      FLD_A2_KI                0x0000ff00
+#define      FLD_A2_KD                0x000000ff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DPLL_CTRL5               0x874
+#define      DIG_PLL_CTL5             0x874
+#define      FLD_TRK_DS1_SEL          0x000c0000
+#define      FLD_TRK_DS2_SEL          0x00030000
+#define      FLD_TRK_KI               0x0000ff00
+#define      FLD_TRK_KD               0x000000ff
+
+/*****************************************************************************/
+#define      DEEMPH_GAIN_CTL          0x878
+#define      FLD_DEEMPH2_GAIN         0xFFFF0000
+#define      FLD_DEEMPH1_GAIN         0x0000FFFF
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_COEFF1            0x87c
+#define      DEEMPH_COEF1             0x87c
+#define      FLD_DEEMPH_B0            0xffff0000
+#define      FLD_DEEMPH_A0            0x0000ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_COEFF2            0x880
+#define      DEEMPH_COEF2             0x880
+#define      FLD_DEEMPH_B1            0xFFFF0000
+#define      FLD_DEEMPH_A1            0x0000FFFF
+
+/*****************************************************************************/
+#define      DBX1_CTL1                0x884
+#define      FLD_DBX1_WBE_GAIN        0xffff0000
+#define      FLD_DBX1_IN_GAIN         0x0000ffff
+
+/*****************************************************************************/
+#define      DBX1_CTL2                0x888
+#define      FLD_DBX1_SE_BYPASS       0xffff0000
+#define      FLD_DBX1_SE_GAIN         0x0000ffff
+
+/*****************************************************************************/
+#define      DBX1_RMS_SE              0x88C
+#define      FLD_DBX1_RMS_WBE         0xffff0000
+#define      FLD_DBX1_RMS_SE_FLD      0x0000ffff
+
+/*****************************************************************************/
+#define      DBX2_CTL1                0x890
+#define      FLD_DBX2_WBE_GAIN        0xffff0000
+#define      FLD_DBX2_IN_GAIN         0x0000ffff
+
+/*****************************************************************************/
+#define      DBX2_CTL2                0x894
+#define      FLD_DBX2_SE_BYPASS       0xffff0000
+#define      FLD_DBX2_SE_GAIN         0x0000ffff
+
+/*****************************************************************************/
+#define      DBX2_RMS_SE              0x898
+#define      FLD_DBX2_RMS_WBE         0xffff0000
+#define      FLD_DBX2_RMS_SE_FLD      0x0000ffff
+
+/*****************************************************************************/
+#define      AM_FM_DIFF               0x89c
+/* Reserved [31] */
+#define      FLD_FM_DIFF_OUT          0x7fff0000
+/* Reserved [15] */
+#define      FLD_AM_DIFF_OUT          0x00007fff
+
+/*****************************************************************************/
+#define      NICAM_FAW                0x8a0
+#define      FLD_FAWDETWINEND         0xFc000000
+#define      FLD_FAWDETWINSTR         0x03ff0000
+/* Reserved [15:12] */
+#define      FLD_FAWDETTHRSHLD3       0x00000f00
+#define      FLD_FAWDETTHRSHLD2       0x000000f0
+#define      FLD_FAWDETTHRSHLD1       0x0000000f
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_GAIN              0x8a4
+#define      NICAM_DEEMPHGAIN         0x8a4
+/* Reserved [31:18] */
+#define      FLD_DEEMPHGAIN           0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_NUMER1            0x8a8
+#define      NICAM_DEEMPHNUMER1       0x8a8
+/* Reserved [31:18] */
+#define      FLD_DEEMPHNUMER1         0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_NUMER2            0x8ac
+#define      NICAM_DEEMPHNUMER2       0x8ac
+/* Reserved [31:18] */
+#define      FLD_DEEMPHNUMER2         0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_DENOM1            0x8b0
+#define      NICAM_DEEMPHDENOM1       0x8b0
+/* Reserved [31:18] */
+#define      FLD_DEEMPHDENOM1         0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      DEEMPH_DENOM2            0x8b4
+#define      NICAM_DEEMPHDENOM2       0x8b4
+/* Reserved [31:18] */
+#define      FLD_DEEMPHDENOM2         0x0003ffff
+
+/*****************************************************************************/
+#define      NICAM_ERRLOG_CTL1        0x8B8
+/* Reserved [31:28] */
+#define      FLD_ERRINTRPTTHSHLD1     0x0fff0000
+/* Reserved [15:12] */
+#define      FLD_ERRLOGPERIOD         0x00000fff
+
+/*****************************************************************************/
+#define      NICAM_ERRLOG_CTL2        0x8bc
+/* Reserved [31:28] */
+#define      FLD_ERRINTRPTTHSHLD3     0x0fff0000
+/* Reserved [15:12] */
+#define      FLD_ERRINTRPTTHSHLD2     0x00000fff
+
+/*****************************************************************************/
+#define      NICAM_ERRLOG_STS1        0x8c0
+/* Reserved [31:28] */
+#define      FLD_ERRLOG2              0x0fff0000
+/* Reserved [15:12] */
+#define      FLD_ERRLOG1              0x00000fff
+
+/*****************************************************************************/
+#define      NICAM_ERRLOG_STS2        0x8c4
+/* Reserved [31:12] */
+#define      FLD_ERRLOG3              0x00000fff
+
+/*****************************************************************************/
+#define      NICAM_STATUS             0x8c8
+/* Reserved [31:20] */
+#define      FLD_NICAM_CIB            0x000c0000
+#define      FLD_NICAM_LOCK_STAT      0x00020000
+#define      FLD_NICAM_MUTE           0x00010000
+#define      FLD_NICAMADDIT_DATA      0x0000ffe0
+#define      FLD_NICAMCNTRL           0x0000001f
+
+/*****************************************************************************/
+#define      DEMATRIX_CTL             0x8cc
+#define      FLD_AC97_IN_SHIFT        0xf0000000
+#define      FLD_I2S_IN_SHIFT         0x0f000000
+#define      FLD_DEMATRIX_SEL_CTL     0x00ff0000
+/* Reserved [15:11] */
+#define      FLD_DMTRX_BYPASS         0x00000400
+#define      FLD_DEMATRIX_MODE        0x00000300
+/* Reserved [7:6] */
+#define      FLD_PH_DBX_SEL           0x00000020
+#define      FLD_PH_CH_SEL            0x00000010
+#define      FLD_PHASE_FIX            0x0000000f
+
+/*****************************************************************************/
+#define      PATH1_CTL1               0x8d0
+/* Reserved [31:29] */
+#define      FLD_PATH1_MUTE_CTL       0x1f000000
+/* Reserved [23:22] */
+#define      FLD_PATH1_AVC_CG         0x00300000
+#define      FLD_PATH1_AVC_RT         0x000f0000
+#define      FLD_PATH1_AVC_AT         0x0000f000
+#define      FLD_PATH1_AVC_STEREO     0x00000800
+#define      FLD_PATH1_AVC_CR         0x00000700
+#define      FLD_PATH1_AVC_RMS_CON    0x000000f0
+#define      FLD_PATH1_SEL_CTL        0x0000000f
+
+/*****************************************************************************/
+#define      PATH1_VOL_CTL            0x8d4
+#define      FLD_PATH1_AVC_THRESHOLD  0x7fff0000
+#define      FLD_PATH1_BAL_LEFT       0x00008000
+#define      FLD_PATH1_BAL_LEVEL      0x00007f00
+#define      FLD_PATH1_VOLUME         0x000000ff
+
+/*****************************************************************************/
+#define      PATH1_EQ_CTL             0x8d8
+/* Reserved [31:30] */
+#define      FLD_PATH1_EQ_TREBLE_VOL  0x3f000000
+/* Reserved [23:22] */
+#define      FLD_PATH1_EQ_MID_VOL     0x003f0000
+/* Reserved [15:14] */
+#define      FLD_PATH1_EQ_BASS_VOL    0x00003f00
+/* Reserved [7:1] */
+#define      FLD_PATH1_EQ_BAND_SEL    0x00000001
+
+/*****************************************************************************/
+#define      PATH1_SC_CTL             0x8dc
+#define      FLD_PATH1_SC_THRESHOLD   0x7fff0000
+#define      FLD_PATH1_SC_RT          0x0000f000
+#define      FLD_PATH1_SC_AT          0x00000f00
+#define      FLD_PATH1_SC_STEREO      0x00000080
+#define      FLD_PATH1_SC_CR          0x00000070
+#define      FLD_PATH1_SC_RMS_CON     0x0000000f
+
+/*****************************************************************************/
+#define      PATH2_CTL1               0x8e0
+/* Reserved [31:26] */
+#define      FLD_PATH2_MUTE_CTL       0x03000000
+/* Reserved [23:22] */
+#define      FLD_PATH2_AVC_CG         0x00300000
+#define      FLD_PATH2_AVC_RT         0x000f0000
+#define      FLD_PATH2_AVC_AT         0x0000f000
+#define      FLD_PATH2_AVC_STEREO     0x00000800
+#define      FLD_PATH2_AVC_CR         0x00000700
+#define      FLD_PATH2_AVC_RMS_CON    0x000000f0
+#define      FLD_PATH2_SEL_CTL        0x0000000f
+
+/*****************************************************************************/
+#define      PATH2_VOL_CTL            0x8e4
+#define      FLD_PATH2_AVC_THRESHOLD  0xffff0000
+#define      FLD_PATH2_BAL_LEFT       0x00008000
+#define      FLD_PATH2_BAL_LEVEL      0x00007f00
+#define      FLD_PATH2_VOLUME         0x000000ff
+
+/*****************************************************************************/
+#define      PATH2_EQ_CTL             0x8e8
+/* Reserved [31:30] */
+#define      FLD_PATH2_EQ_TREBLE_VOL  0x3f000000
+/* Reserved [23:22] */
+#define      FLD_PATH2_EQ_MID_VOL     0x003f0000
+/* Reserved [15:14] */
+#define      FLD_PATH2_EQ_BASS_VOL    0x00003f00
+/* Reserved [7:1] */
+#define      FLD_PATH2_EQ_BAND_SEL    0x00000001
+
+/*****************************************************************************/
+#define      PATH2_SC_CTL             0x8eC
+#define      FLD_PATH2_SC_THRESHOLD   0xffff0000
+#define      FLD_PATH2_SC_RT          0x0000f000
+#define      FLD_PATH2_SC_AT          0x00000f00
+#define      FLD_PATH2_SC_STEREO      0x00000080
+#define      FLD_PATH2_SC_CR          0x00000070
+#define      FLD_PATH2_SC_RMS_CON     0x0000000f
+
+/*****************************************************************************/
+#define      SRC_CTL                  0x8f0
+#define      FLD_SRC_STATUS           0xffffff00
+#define      FLD_FIFO_LF_EN           0x000000fc
+#define      FLD_BYPASS_LI            0x00000002
+#define      FLD_BYPASS_PF            0x00000001
+
+/*****************************************************************************/
+#define      SRC_LF_COEF              0x8f4
+#define      FLD_LOOP_FILTER_COEF2    0xffff0000
+#define      FLD_LOOP_FILTER_COEF1    0x0000ffff
+
+/*****************************************************************************/
+#define      SRC1_CTL                 0x8f8
+/* Reserved [31:28] */
+#define      FLD_SRC1_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC1_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      SRC2_CTL                 0x8fc
+/* Reserved [31:28] */
+#define      FLD_SRC2_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC2_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      SRC3_CTL                 0x900
+/* Reserved [31:28] */
+#define      FLD_SRC3_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC3_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      SRC4_CTL                 0x904
+/* Reserved [31:28] */
+#define      FLD_SRC4_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC4_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      SRC5_CTL                 0x908
+/* Reserved [31:28] */
+#define      FLD_SRC5_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC5_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      SRC6_CTL                 0x90c
+/* Reserved [31:28] */
+#define      FLD_SRC6_FIFO_RD_TH      0x0f000000
+/* Reserved [23:18] */
+#define      FLD_SRC6_PHASE_INC       0x0003ffff
+
+/*****************************************************************************/
+#define      BAND_OUT_SEL             0x910
+#define      FLD_SRC6_IN_SEL          0xc0000000
+#define      FLD_SRC6_CLK_SEL         0x30000000
+#define      FLD_SRC5_IN_SEL          0x0c000000
+#define      FLD_SRC5_CLK_SEL         0x03000000
+#define      FLD_SRC4_IN_SEL          0x00c00000
+#define      FLD_SRC4_CLK_SEL         0x00300000
+#define      FLD_SRC3_IN_SEL          0x000c0000
+#define      FLD_SRC3_CLK_SEL         0x00030000
+#define      FLD_BASEBAND_BYPASS_CTL  0x0000ff00
+#define      FLD_AC97_SRC_SEL         0x000000c0
+#define      FLD_I2S_SRC_SEL          0x00000030
+#define      FLD_PARALLEL2_SRC_SEL    0x0000000c
+#define      FLD_PARALLEL1_SRC_SEL    0x00000003
+
+/*****************************************************************************/
+#define      I2S_IN_CTL               0x914
+/* Reserved [31:11] */
+#define      FLD_I2S_UP2X_BW20K       0x00000400
+#define      FLD_I2S_UP2X_BYPASS      0x00000200
+#define      FLD_I2S_IN_MASTER_MODE   0x00000100
+#define      FLD_I2S_IN_SONY_MODE     0x00000080
+#define      FLD_I2S_IN_RIGHT_JUST    0x00000040
+#define      FLD_I2S_IN_WS_SEL        0x00000020
+#define      FLD_I2S_IN_BCN_DEL       0x0000001f
+
+/*****************************************************************************/
+#define      I2S_OUT_CTL              0x918
+/* Reserved [31:17] */
+#define      FLD_I2S_OUT_SOFT_RESET_EN  0x00010000
+/* Reserved [15:9] */
+#define      FLD_I2S_OUT_MASTER_MODE  0x00000100
+#define      FLD_I2S_OUT_SONY_MODE    0x00000080
+#define      FLD_I2S_OUT_RIGHT_JUST   0x00000040
+#define      FLD_I2S_OUT_WS_SEL       0x00000020
+#define      FLD_I2S_OUT_BCN_DEL      0x0000001f
+
+/*****************************************************************************/
+#define      AC97_CTL                 0x91c
+/* Reserved [31:26] */
+#define      FLD_AC97_UP2X_BW20K      0x02000000
+#define      FLD_AC97_UP2X_BYPASS     0x01000000
+/* Reserved [23:17] */
+#define      FLD_AC97_RST_ACL         0x00010000
+/* Reserved [15:9] */
+#define      FLD_AC97_WAKE_UP_SYNC    0x00000100
+/* Reserved [7:1] */
+#define      FLD_AC97_SHUTDOWN        0x00000001
+
+/* Cx231xx redefine */
+#define      QPSK_IAGC_CTL1  		0x94c
+#define      QPSK_IAGC_CTL2  		0x950
+#define      QPSK_FEPR_FREQ  		0x954
+#define      QPSK_BTL_CTL1  		0x958
+#define      QPSK_BTL_CTL2  		0x95c
+#define      QPSK_CTL_CTL1  		0x960
+#define      QPSK_CTL_CTL2  		0x964
+#define      QPSK_MF_FAGC_CTL 		0x968
+#define      QPSK_EQ_CTL  		0x96c
+#define      QPSK_LOCK_CTL  		0x970
+
+/*****************************************************************************/
+#define      FM1_DFT_CTL              0x9a8
+#define      FLD_FM1_DFT_THRESHOLD    0xffff0000
+/* Reserved [15:8] */
+#define      FLD_FM1_DFT_CMP_CTL      0x00000080
+#define      FLD_FM1_DFT_AVG          0x00000070
+/* Reserved [3:1] */
+#define      FLD_FM1_DFT_START        0x00000001
+
+/*****************************************************************************/
+#define      FM1_DFT_STATUS           0x9ac
+#define      FLD_FM1_DFT_DONE         0x80000000
+/* Reserved [30:19] */
+#define      FLD_FM_DFT_TH_CMP        0x00040000
+#define      FLD_FM1_DFT              0x0003ffff
+
+/*****************************************************************************/
+#define      FM2_DFT_CTL              0x9b0
+#define      FLD_FM2_DFT_THRESHOLD    0xffff0000
+/* Reserved [15:8] */
+#define      FLD_FM2_DFT_CMP_CTL      0x00000080
+#define      FLD_FM2_DFT_AVG          0x00000070
+/* Reserved [3:1] */
+#define      FLD_FM2_DFT_START        0x00000001
+
+/*****************************************************************************/
+#define      FM2_DFT_STATUS           0x9b4
+#define      FLD_FM2_DFT_DONE         0x80000000
+/* Reserved [30:19] */
+#define      FLD_FM2_DFT_TH_CMP_STAT  0x00040000
+#define      FLD_FM2_DFT              0x0003ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      AAGC_STATUS_REG          0x9b8
+#define      AAGC_STATUS              0x9b8
+/* Reserved [31:27] */
+#define      FLD_FM2_DAGC_OUT         0x07000000
+/* Reserved [23:19] */
+#define      FLD_FM1_DAGC_OUT         0x00070000
+/* Reserved [15:6] */
+#define      FLD_AFE_VGA_OUT          0x0000003f
+
+/*****************************************************************************/
+#define      MTS_GAIN_STATUS          0x9bc
+/* Reserved [31:14] */
+#define      FLD_MTS_GAIN             0x00003fff
+
+#define      RDS_OUT                  0x9c0
+#define      FLD_RDS_Q                0xffff0000
+#define      FLD_RDS_I                0x0000ffff
+
+/*****************************************************************************/
+#define      AUTOCONFIG_REG           0x9c4
+/* Reserved [31:4] */
+#define      FLD_AUTOCONFIG_MODE      0x0000000f
+
+#define      FM_AFC                   0x9c8
+#define      FLD_FM2_AFC              0xffff0000
+#define      FLD_FM1_AFC              0x0000ffff
+
+/*****************************************************************************/
+/* Cx231xx redefine */
+#define      NEW_SPARE                0x9cc
+#define      NEW_SPARE_REG            0x9cc
+
+/*****************************************************************************/
+#define      DBX_ADJ                  0x9d0
+/* Reserved [31:28] */
+#define      FLD_DBX2_ADJ             0x0fff0000
+/* Reserved [15:12] */
+#define      FLD_DBX1_ADJ             0x00000fff
+
+#define      VID_FMT_AUTO              0
+#define      VID_FMT_NTSC_M            1
+#define      VID_FMT_NTSC_J            2
+#define      VID_FMT_NTSC_443          3
+#define      VID_FMT_PAL_BDGHI         4
+#define      VID_FMT_PAL_M             5
+#define      VID_FMT_PAL_N             6
+#define      VID_FMT_PAL_NC            7
+#define      VID_FMT_PAL_60            8
+#define      VID_FMT_SECAM             12
+#define      VID_FMT_SECAM_60          13
+
+#define      INPUT_MODE_CVBS_0         0       /* INPUT_MODE_VALUE(0) */
+#define      INPUT_MODE_YC_1           1       /* INPUT_MODE_VALUE(1) */
+#define      INPUT_MODE_YC2_2          2       /* INPUT_MODE_VALUE(2) */
+#define      INPUT_MODE_YUV_3          3       /* INPUT_MODE_VALUE(3) */
+
+#define      LUMA_LPF_LOW_BANDPASS     0       /* 0.6Mhz LPF BW */
+#define      LUMA_LPF_MEDIUM_BANDPASS  1       /* 1.0Mhz LPF BW */
+#define      LUMA_LPF_HIGH_BANDPASS    2       /* 1.5Mhz LPF BW */
+
+#define      UV_LPF_LOW_BANDPASS       0       /* 0.6Mhz LPF BW */
+#define      UV_LPF_MEDIUM_BANDPASS    1       /* 1.0Mhz LPF BW */
+#define      UV_LPF_HIGH_BANDPASS      2       /* 1.5Mhz LPF BW */
+
+#define      TWO_TAP_FILT              0
+#define      THREE_TAP_FILT            1
+#define      FOUR_TAP_FILT             2
+#define      FIVE_TAP_FILT             3
+
+#define      AUD_CHAN_SRC_PARALLEL     0
+#define      AUD_CHAN_SRC_I2S_INPUT    1
+#define      AUD_CHAN_SRC_FLATIRON     2
+#define      AUD_CHAN_SRC_PARALLEL3    3
+
+#define      OUT_MODE_601              0
+#define      OUT_MODE_656              1
+#define      OUT_MODE_VIP11            2
+#define      OUT_MODE_VIP20            3
+
+#define      PHASE_INC_49MHZ          0x0df22
+#define      PHASE_INC_56MHZ          0x0fa5b
+#define      PHASE_INC_28MHZ          0x010000
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,701 @@
+/*
+   cx231xx_vbi.c - driver for Conexant Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+	Based on cx88 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/msp3400.h>
+#include <media/tuner.h>
+
+#include "cx231xx.h"
+#include "cx231xx-vbi.h"
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+	char *errmsg = "Unknown";
+
+	switch (status) {
+	case -ENOENT:
+		errmsg = "unlinked synchronuously";
+		break;
+	case -ECONNRESET:
+		errmsg = "unlinked asynchronuously";
+		break;
+	case -ENOSR:
+		errmsg = "Buffer error (overrun)";
+		break;
+	case -EPIPE:
+		errmsg = "Stalled (device not responding)";
+		break;
+	case -EOVERFLOW:
+		errmsg = "Babble (bad cable?)";
+		break;
+	case -EPROTO:
+		errmsg = "Bit-stuff error (bad cable?)";
+		break;
+	case -EILSEQ:
+		errmsg = "CRC/Timeout (could be anything)";
+		break;
+	case -ETIME:
+		errmsg = "Device does not respond";
+		break;
+	}
+	if (packet < 0) {
+		cx231xx_err(DRIVER_NAME "URB status %d [%s].\n", status,
+			    errmsg);
+	} else {
+		cx231xx_err(DRIVER_NAME "URB packet %d, status %d [%s].\n",
+			    packet, status, errmsg);
+	}
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
+{
+	struct cx231xx_buffer *buf;
+	struct cx231xx_dmaqueue *dma_q = urb->context;
+	int rc = 1;
+	unsigned char *p_buffer;
+	u32 bytes_parsed = 0, buffer_size = 0;
+	u8 sav_eav = 0;
+
+	if (!dev)
+		return 0;
+
+	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+		return 0;
+
+	if (urb->status < 0) {
+		print_err_status(dev, -1, urb->status);
+		if (urb->status == -ENOENT)
+			return 0;
+	}
+
+	buf = dev->vbi_mode.isoc_ctl.buf;
+
+	/* get buffer pointer and length */
+	p_buffer = urb->transfer_buffer;
+	buffer_size = urb->actual_length;
+
+	if (buffer_size > 0) {
+		bytes_parsed = 0;
+
+		if (dma_q->is_partial_line) {
+			/* Handle the case where we were working on a partial
+			   line */
+			sav_eav = dma_q->last_sav;
+		} else {
+			/* Check for a SAV/EAV overlapping the
+			   buffer boundary */
+
+			sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer,
+							  dma_q->partial_buf,
+							  &bytes_parsed);
+		}
+
+		sav_eav &= 0xF0;
+		/* Get the first line if we have some portion of an SAV/EAV from
+		   the last buffer or a partial line */
+		if (sav_eav) {
+			bytes_parsed += cx231xx_get_vbi_line(dev, dma_q,
+				sav_eav,		       /* SAV/EAV */
+				p_buffer + bytes_parsed,       /* p_buffer */
+				buffer_size - bytes_parsed);   /* buffer size */
+		}
+
+		/* Now parse data that is completely in this buffer */
+		dma_q->is_partial_line = 0;
+
+		while (bytes_parsed < buffer_size) {
+			u32 bytes_used = 0;
+
+			sav_eav = cx231xx_find_next_SAV_EAV(
+				p_buffer + bytes_parsed,	/* p_buffer */
+				buffer_size - bytes_parsed, /* buffer size */
+				&bytes_used);	/* bytes used to get SAV/EAV */
+
+			bytes_parsed += bytes_used;
+
+			sav_eav &= 0xF0;
+			if (sav_eav && (bytes_parsed < buffer_size)) {
+				bytes_parsed += cx231xx_get_vbi_line(dev,
+					dma_q, sav_eav,	/* SAV/EAV */
+					p_buffer+bytes_parsed, /* p_buffer */
+					buffer_size-bytes_parsed);/*buf size*/
+			}
+		}
+
+		/* Save the last four bytes of the buffer so we can
+		check the buffer boundary condition next time */
+		memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
+		bytes_parsed = 0;
+	}
+
+	return rc;
+}
+
+/* ------------------------------------------------------------------
+	Vbi buf operations
+   ------------------------------------------------------------------*/
+
+static int
+vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+		 unsigned int *size)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	u32 height = 0;
+
+	height = ((dev->norm & V4L2_STD_625_50) ?
+		  PAL_VBI_LINES : NTSC_VBI_LINES);
+
+	*size = (dev->width * height * 2);
+	if (0 == *count)
+		*count = CX231XX_DEF_VBI_BUF;
+
+	if (*count < CX231XX_MIN_BUF)
+		*count = CX231XX_MIN_BUF;
+
+	return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	unsigned long flags = 0;
+	if (in_interrupt())
+		BUG();
+
+	/* We used to wait for the buffer to finish here, but this didn't work
+	   because, as we were keeping the state as VIDEOBUF_QUEUED,
+	   videobuf_queue_cancel marked it as finished for us.
+	   (Also, it could wedge forever if the hardware was misconfigured.)
+
+	   This should be safe; by the time we get here, the buffer isn't
+	   queued anymore. If we ever start marking the buffers as
+	   VIDEOBUF_ACTIVE, it won't be, though.
+	 */
+	spin_lock_irqsave(&dev->vbi_mode.slock, flags);
+	if (dev->vbi_mode.isoc_ctl.buf == buf)
+		dev->vbi_mode.isoc_ctl.buf = NULL;
+	spin_unlock_irqrestore(&dev->vbi_mode.slock, flags);
+
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+		   enum v4l2_field field)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+	struct cx231xx *dev = fh->dev;
+	int rc = 0, urb_init = 0;
+	u32 height = 0;
+
+	height = ((dev->norm & V4L2_STD_625_50) ?
+		  PAL_VBI_LINES : NTSC_VBI_LINES);
+	buf->vb.size = ((dev->width << 1) * height);
+
+	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	buf->vb.width = dev->width;
+	buf->vb.height = height;
+	buf->vb.field = field;
+	buf->vb.field = V4L2_FIELD_SEQ_TB;
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc < 0)
+			goto fail;
+	}
+
+	if (!dev->vbi_mode.isoc_ctl.num_bufs)
+		urb_init = 1;
+
+	if (urb_init) {
+		rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS,
+					   CX231XX_NUM_VBI_BUFS,
+					   dev->vbi_mode.alt_max_pkt_size[0],
+					   cx231xx_isoc_vbi_copy);
+		if (rc < 0)
+			goto fail;
+	}
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+
+fail:
+	free_buffer(vq, buf);
+	return rc;
+}
+
+static void
+vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq;
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &vidq->active);
+
+}
+
+static void vbi_buffer_release(struct videobuf_queue *vq,
+			       struct videobuf_buffer *vb)
+{
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+
+
+	free_buffer(vq, buf);
+}
+
+struct videobuf_queue_ops cx231xx_vbi_qops = {
+	.buf_setup   = vbi_buffer_setup,
+	.buf_prepare = vbi_buffer_prepare,
+	.buf_queue   = vbi_buffer_queue,
+	.buf_release = vbi_buffer_release,
+};
+
+/* ------------------------------------------------------------------
+	URB control
+   ------------------------------------------------------------------*/
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void cx231xx_irq_vbi_callback(struct urb *urb)
+{
+	struct cx231xx_dmaqueue *dma_q = urb->context;
+	struct cx231xx_video_mode *vmode =
+	    container_of(dma_q, struct cx231xx_video_mode, vidq);
+	struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
+	int rc;
+
+	switch (urb->status) {
+	case 0:		/* success */
+	case -ETIMEDOUT:	/* NAK */
+		break;
+	case -ECONNRESET:	/* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:		/* error */
+		cx231xx_err(DRIVER_NAME "urb completition error %d.\n",
+			    urb->status);
+		break;
+	}
+
+	/* Copy data from URB */
+	spin_lock(&dev->vbi_mode.slock);
+	rc = dev->vbi_mode.isoc_ctl.isoc_copy(dev, urb);
+	spin_unlock(&dev->vbi_mode.slock);
+
+	/* Reset status */
+	urb->status = 0;
+
+	urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (urb->status) {
+		cx231xx_err(DRIVER_NAME "urb resubmit failed (error=%i)\n",
+			    urb->status);
+	}
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void cx231xx_uninit_vbi_isoc(struct cx231xx *dev)
+{
+	struct urb *urb;
+	int i;
+
+	cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_uninit_vbi_isoc\n");
+
+	dev->vbi_mode.isoc_ctl.nfields = -1;
+	for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+		urb = dev->vbi_mode.isoc_ctl.urb[i];
+		if (urb) {
+			if (!irqs_disabled())
+				usb_kill_urb(urb);
+			else
+				usb_unlink_urb(urb);
+
+			if (dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
+
+				kfree(dev->vbi_mode.isoc_ctl.
+				      transfer_buffer[i]);
+				dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
+				    NULL;
+			}
+			usb_free_urb(urb);
+			dev->vbi_mode.isoc_ctl.urb[i] = NULL;
+		}
+		dev->vbi_mode.isoc_ctl.transfer_buffer[i] = NULL;
+	}
+
+	kfree(dev->vbi_mode.isoc_ctl.urb);
+	kfree(dev->vbi_mode.isoc_ctl.transfer_buffer);
+
+	dev->vbi_mode.isoc_ctl.urb = NULL;
+	dev->vbi_mode.isoc_ctl.transfer_buffer = NULL;
+	dev->vbi_mode.isoc_ctl.num_bufs = 0;
+
+	cx231xx_capture_start(dev, 0, Vbi);
+}
+EXPORT_SYMBOL_GPL(cx231xx_uninit_vbi_isoc);
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
+			  int num_bufs, int max_pkt_size,
+			  int (*isoc_copy) (struct cx231xx *dev,
+					    struct urb *urb))
+{
+	struct cx231xx_dmaqueue *dma_q = &dev->vbi_mode.vidq;
+	int i;
+	int sb_size, pipe;
+	struct urb *urb;
+	int rc;
+
+	cx231xx_info(DRIVER_NAME "cx231xx: called cx231xx_prepare_isoc\n");
+
+	/* De-allocates all pending stuff */
+	cx231xx_uninit_vbi_isoc(dev);
+
+	/* clear if any halt */
+	usb_clear_halt(dev->udev,
+		       usb_rcvbulkpipe(dev->udev,
+				       dev->vbi_mode.end_point_addr));
+
+	dev->vbi_mode.isoc_ctl.isoc_copy = isoc_copy;
+	dev->vbi_mode.isoc_ctl.num_bufs = num_bufs;
+	dma_q->pos = 0;
+	dma_q->is_partial_line = 0;
+	dma_q->last_sav = 0;
+	dma_q->current_field = -1;
+	dma_q->bytes_left_in_line = dev->width << 1;
+	dma_q->lines_per_field = ((dev->norm & V4L2_STD_625_50) ?
+				  PAL_VBI_LINES : NTSC_VBI_LINES);
+	dma_q->lines_completed = 0;
+	for (i = 0; i < 8; i++)
+		dma_q->partial_buf[i] = 0;
+
+	dev->vbi_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs,
+					     GFP_KERNEL);
+	if (!dev->vbi_mode.isoc_ctl.urb) {
+		cx231xx_errdev("cannot alloc memory for usb buffers\n");
+		return -ENOMEM;
+	}
+
+	dev->vbi_mode.isoc_ctl.transfer_buffer =
+	    kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL);
+	if (!dev->vbi_mode.isoc_ctl.transfer_buffer) {
+		cx231xx_errdev("cannot allocate memory for usbtransfer\n");
+		kfree(dev->vbi_mode.isoc_ctl.urb);
+		return -ENOMEM;
+	}
+
+	dev->vbi_mode.isoc_ctl.max_pkt_size = max_pkt_size;
+	dev->vbi_mode.isoc_ctl.buf = NULL;
+
+	sb_size = max_packets * dev->vbi_mode.isoc_ctl.max_pkt_size;
+
+	/* allocate urbs and transfer buffers */
+	for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			cx231xx_err(DRIVER_NAME
+				    ": cannot alloc isoc_ctl.urb %i\n", i);
+			cx231xx_uninit_vbi_isoc(dev);
+			return -ENOMEM;
+		}
+		dev->vbi_mode.isoc_ctl.urb[i] = urb;
+		urb->transfer_flags = 0;
+
+		dev->vbi_mode.isoc_ctl.transfer_buffer[i] =
+		    kzalloc(sb_size, GFP_KERNEL);
+		if (!dev->vbi_mode.isoc_ctl.transfer_buffer[i]) {
+			cx231xx_err(DRIVER_NAME
+				    ": unable to allocate %i bytes for transfer"
+				    " buffer %i%s\n", sb_size, i,
+				    in_interrupt() ? " while in int" : "");
+			cx231xx_uninit_vbi_isoc(dev);
+			return -ENOMEM;
+		}
+
+		pipe = usb_rcvbulkpipe(dev->udev, dev->vbi_mode.end_point_addr);
+		usb_fill_bulk_urb(urb, dev->udev, pipe,
+				  dev->vbi_mode.isoc_ctl.transfer_buffer[i],
+				  sb_size, cx231xx_irq_vbi_callback, dma_q);
+	}
+
+	init_waitqueue_head(&dma_q->wq);
+
+	/* submit urbs and enables IRQ */
+	for (i = 0; i < dev->vbi_mode.isoc_ctl.num_bufs; i++) {
+		rc = usb_submit_urb(dev->vbi_mode.isoc_ctl.urb[i], GFP_ATOMIC);
+		if (rc) {
+			cx231xx_err(DRIVER_NAME
+				    ": submit of urb %i failed (error=%i)\n", i,
+				    rc);
+			cx231xx_uninit_vbi_isoc(dev);
+			return rc;
+		}
+	}
+
+	cx231xx_capture_start(dev, 1, Vbi);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cx231xx_init_vbi_isoc);
+
+u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			 u8 sav_eav, u8 *p_buffer, u32 buffer_size)
+{
+	u32 bytes_copied = 0;
+	int current_field = -1;
+
+	switch (sav_eav) {
+
+	case SAV_VBI_FIELD1:
+		current_field = 1;
+		break;
+
+	case SAV_VBI_FIELD2:
+		current_field = 2;
+		break;
+	default:
+		break;
+	}
+
+	if (current_field < 0)
+		return bytes_copied;
+
+	dma_q->last_sav = sav_eav;
+
+	bytes_copied =
+	    cx231xx_copy_vbi_line(dev, dma_q, p_buffer, buffer_size,
+				  current_field);
+
+	return bytes_copied;
+}
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void vbi_buffer_filled(struct cx231xx *dev,
+				     struct cx231xx_dmaqueue *dma_q,
+				     struct cx231xx_buffer *buf)
+{
+	/* Advice that buffer was filled */
+	/* cx231xx_info(DRIVER_NAME "[%p/%d] wakeup\n", buf, buf->vb.i); */
+
+	buf->vb.state = VIDEOBUF_DONE;
+	buf->vb.field_count++;
+	do_gettimeofday(&buf->vb.ts);
+
+	dev->vbi_mode.isoc_ctl.buf = NULL;
+
+	list_del(&buf->vb.queue);
+	wake_up(&buf->vb.done);
+}
+
+u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			  u8 *p_line, u32 length, int field_number)
+{
+	u32 bytes_to_copy;
+	struct cx231xx_buffer *buf;
+	u32 _line_size = dev->width * 2;
+
+	if (dma_q->current_field != field_number)
+		cx231xx_reset_vbi_buffer(dev, dma_q);
+
+	/* get the buffer pointer */
+	buf = dev->vbi_mode.isoc_ctl.buf;
+
+	/* Remember the field number for next time */
+	dma_q->current_field = field_number;
+
+	bytes_to_copy = dma_q->bytes_left_in_line;
+	if (bytes_to_copy > length)
+		bytes_to_copy = length;
+
+	if (dma_q->lines_completed >= dma_q->lines_per_field) {
+		dma_q->bytes_left_in_line -= bytes_to_copy;
+		dma_q->is_partial_line =
+		    (dma_q->bytes_left_in_line == 0) ? 0 : 1;
+		return 0;
+	}
+
+	dma_q->is_partial_line = 1;
+
+	/* If we don't have a buffer, just return the number of bytes we would
+	   have copied if we had a buffer. */
+	if (!buf) {
+		dma_q->bytes_left_in_line -= bytes_to_copy;
+		dma_q->is_partial_line =
+		    (dma_q->bytes_left_in_line == 0) ? 0 : 1;
+		return bytes_to_copy;
+	}
+
+	/* copy the data to video buffer */
+	cx231xx_do_vbi_copy(dev, dma_q, p_line, bytes_to_copy);
+
+	dma_q->pos += bytes_to_copy;
+	dma_q->bytes_left_in_line -= bytes_to_copy;
+
+	if (dma_q->bytes_left_in_line == 0) {
+
+		dma_q->bytes_left_in_line = _line_size;
+		dma_q->lines_completed++;
+		dma_q->is_partial_line = 0;
+
+		if (cx231xx_is_vbi_buffer_done(dev, dma_q) && buf) {
+
+			vbi_buffer_filled(dev, dma_q, buf);
+
+			dma_q->pos = 0;
+			buf = NULL;
+			dma_q->lines_completed = 0;
+		}
+	}
+
+	return bytes_to_copy;
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
+				    struct cx231xx_buffer **buf)
+{
+	struct cx231xx_video_mode *vmode =
+	    container_of(dma_q, struct cx231xx_video_mode, vidq);
+	struct cx231xx *dev = container_of(vmode, struct cx231xx, vbi_mode);
+	char *outp;
+
+	if (list_empty(&dma_q->active)) {
+		cx231xx_err(DRIVER_NAME ": No active queue to serve\n");
+		dev->vbi_mode.isoc_ctl.buf = NULL;
+		*buf = NULL;
+		return;
+	}
+
+	/* Get the next buffer */
+	*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
+
+	/* Cleans up buffer - Usefull for testing for frame/URB loss */
+	outp = videobuf_to_vmalloc(&(*buf)->vb);
+	memset(outp, 0, (*buf)->vb.size);
+
+	dev->vbi_mode.isoc_ctl.buf = *buf;
+
+	return;
+}
+
+void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
+			      struct cx231xx_dmaqueue *dma_q)
+{
+	struct cx231xx_buffer *buf;
+
+	buf = dev->vbi_mode.isoc_ctl.buf;
+
+	if (buf == NULL) {
+		/* first try to get the buffer */
+		get_next_vbi_buf(dma_q, &buf);
+
+		dma_q->pos = 0;
+		dma_q->current_field = -1;
+	}
+
+	dma_q->bytes_left_in_line = dev->width << 1;
+	dma_q->lines_completed = 0;
+}
+
+int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			u8 *p_buffer, u32 bytes_to_copy)
+{
+	u8 *p_out_buffer = NULL;
+	u32 current_line_bytes_copied = 0;
+	struct cx231xx_buffer *buf;
+	u32 _line_size = dev->width << 1;
+	void *startwrite;
+	int offset, lencopy;
+
+	buf = dev->vbi_mode.isoc_ctl.buf;
+
+	if (buf == NULL)
+		return -EINVAL;
+
+	p_out_buffer = videobuf_to_vmalloc(&buf->vb);
+
+	if (dma_q->bytes_left_in_line != _line_size) {
+		current_line_bytes_copied =
+		    _line_size - dma_q->bytes_left_in_line;
+	}
+
+	offset = (dma_q->lines_completed * _line_size) +
+		 current_line_bytes_copied;
+
+	/* prepare destination address */
+	startwrite = p_out_buffer + offset;
+
+	lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
+		  bytes_to_copy : dma_q->bytes_left_in_line;
+
+	memcpy(startwrite, p_buffer, lencopy);
+
+	return 0;
+}
+
+u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
+			      struct cx231xx_dmaqueue *dma_q)
+{
+	u32 height = 0;
+
+	height = ((dev->norm & V4L2_STD_625_50) ?
+		  PAL_VBI_LINES : NTSC_VBI_LINES);
+	return (dma_q->lines_completed == height) ? 1 : 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.h linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-vbi.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+   cx231xx_vbi.h - driver for Conexant Cx23100/101/102 USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+		Based on cx88 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _CX231XX_VBI_H
+#define _CX231XX_VBI_H
+
+extern struct videobuf_queue_ops cx231xx_vbi_qops;
+
+#define   NTSC_VBI_START_LINE 10	/* line 10 - 21 */
+#define   NTSC_VBI_END_LINE   21
+#define   NTSC_VBI_LINES	  (NTSC_VBI_END_LINE-NTSC_VBI_START_LINE+1)
+
+#define   PAL_VBI_START_LINE  6
+#define   PAL_VBI_END_LINE    23
+#define   PAL_VBI_LINES       (PAL_VBI_END_LINE-PAL_VBI_START_LINE+1)
+
+#define   VBI_STRIDE            1440
+#define   VBI_SAMPLES_PER_LINE  1440
+
+#define   CX231XX_NUM_VBI_PACKETS       4
+#define   CX231XX_NUM_VBI_BUFS          5
+
+/* stream functions */
+int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets,
+			  int num_bufs, int max_pkt_size,
+			  int (*isoc_copy) (struct cx231xx *dev,
+					    struct urb *urb));
+
+void cx231xx_uninit_vbi_isoc(struct cx231xx *dev);
+
+/* vbi data copy functions */
+u32 cx231xx_get_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			 u8 sav_eav, u8 *p_buffer, u32 buffer_size);
+
+u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			  u8 *p_line, u32 length, int field_number);
+
+void cx231xx_reset_vbi_buffer(struct cx231xx *dev,
+			      struct cx231xx_dmaqueue *dma_q);
+
+int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+			u8 *p_buffer, u32 bytes_to_copy);
+
+u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
+			      struct cx231xx_dmaqueue *dma_q);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-video.c linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/cx231xx-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2434 @@
+/*
+   cx231xx-video.c - driver for Conexant Cx23100/101/102
+		     USB video capture devices
+
+   Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
+	Based on em28xx driver
+	Based on cx23885 driver
+	Based on cx88 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitmap.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/msp3400.h>
+#include <media/tuner.h>
+
+#include "dvb_frontend.h"
+
+#include "cx231xx.h"
+#include "cx231xx-vbi.h"
+
+#define CX231XX_VERSION_CODE            KERNEL_VERSION(0, 0, 1)
+
+#define DRIVER_AUTHOR   "Srinivasa Deevi <srinivasa.deevi@conexant.com>"
+#define DRIVER_DESC     "Conexant cx231xx based USB video device driver"
+
+#define cx231xx_videodbg(fmt, arg...) do {\
+	if (video_debug) \
+		printk(KERN_INFO "%s %s :"fmt, \
+			 dev->name, __func__ , ##arg); } while (0)
+
+static unsigned int isoc_debug;
+module_param(isoc_debug, int, 0644);
+MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
+
+#define cx231xx_isocdbg(fmt, arg...) \
+do {\
+	if (isoc_debug) { \
+		printk(KERN_INFO "%s %s :"fmt, \
+			 dev->name, __func__ , ##arg); \
+	} \
+  } while (0)
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+static unsigned int card[]     = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int vbi_nr[]   = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET };
+
+module_param_array(card, int, NULL, 0444);
+module_param_array(video_nr, int, NULL, 0444);
+module_param_array(vbi_nr, int, NULL, 0444);
+module_param_array(radio_nr, int, NULL, 0444);
+
+MODULE_PARM_DESC(card, "card type");
+MODULE_PARM_DESC(video_nr, "video device numbers");
+MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
+MODULE_PARM_DESC(radio_nr, "radio device numbers");
+
+static unsigned int video_debug;
+module_param(video_debug, int, 0644);
+MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
+
+/* supported video standards */
+static struct cx231xx_fmt format[] = {
+	{
+	 .name = "16bpp YUY2, 4:2:2, packed",
+	 .fourcc = V4L2_PIX_FMT_YUYV,
+	 .depth = 16,
+	 .reg = 0,
+	 },
+};
+
+/* supported controls */
+/* Common to all boards */
+
+/* ------------------------------------------------------------------- */
+
+static const struct v4l2_queryctrl no_ctl = {
+	.name = "42",
+	.flags = V4L2_CTRL_FLAG_DISABLED,
+};
+
+static struct cx231xx_ctrl cx231xx_ctls[] = {
+	/* --- video --- */
+	{
+		.v = {
+			.id = V4L2_CID_BRIGHTNESS,
+			.name = "Brightness",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 1,
+			.default_value = 0x7f,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.off = 128,
+		.reg = LUMA_CTRL,
+		.mask = 0x00ff,
+		.shift = 0,
+	}, {
+		.v = {
+			.id = V4L2_CID_CONTRAST,
+			.name = "Contrast",
+			.minimum = 0,
+			.maximum = 0xff,
+			.step = 1,
+			.default_value = 0x3f,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.off = 0,
+		.reg = LUMA_CTRL,
+		.mask = 0xff00,
+		.shift = 8,
+	}, {
+		.v = {
+			.id = V4L2_CID_HUE,
+			.name = "Hue",
+			.minimum = 0,
+			.maximum = 0xff,
+			.step = 1,
+			.default_value = 0x7f,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.off = 128,
+		.reg = CHROMA_CTRL,
+		.mask = 0xff0000,
+		.shift = 16,
+	}, {
+	/* strictly, this only describes only U saturation.
+	* V saturation is handled specially through code.
+	*/
+		.v = {
+			.id = V4L2_CID_SATURATION,
+			.name = "Saturation",
+			.minimum = 0,
+			.maximum = 0xff,
+			.step = 1,
+			.default_value = 0x7f,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.off = 0,
+		.reg = CHROMA_CTRL,
+		.mask = 0x00ff,
+		.shift = 0,
+	}, {
+		/* --- audio --- */
+		.v = {
+			.id = V4L2_CID_AUDIO_MUTE,
+			.name = "Mute",
+			.minimum = 0,
+			.maximum = 1,
+			.default_value = 1,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+		},
+		.reg = PATH1_CTL1,
+		.mask = (0x1f << 24),
+		.shift = 24,
+	}, {
+		.v = {
+			.id = V4L2_CID_AUDIO_VOLUME,
+			.name = "Volume",
+			.minimum = 0,
+			.maximum = 0x3f,
+			.step = 1,
+			.default_value = 0x3f,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+		},
+		.reg = PATH1_VOL_CTL,
+		.mask = 0xff,
+		.shift = 0,
+	}
+};
+static const int CX231XX_CTLS = ARRAY_SIZE(cx231xx_ctls);
+
+static const u32 cx231xx_user_ctrls[] = {
+	V4L2_CID_USER_CLASS,
+	V4L2_CID_BRIGHTNESS,
+	V4L2_CID_CONTRAST,
+	V4L2_CID_SATURATION,
+	V4L2_CID_HUE,
+	V4L2_CID_AUDIO_VOLUME,
+#if 0
+	V4L2_CID_AUDIO_BALANCE,
+#endif
+	V4L2_CID_AUDIO_MUTE,
+	0
+};
+
+static const u32 *ctrl_classes[] = {
+	cx231xx_user_ctrls,
+	NULL
+};
+
+/* ------------------------------------------------------------------
+	Video buffer and parser functions
+   ------------------------------------------------------------------*/
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void buffer_filled(struct cx231xx *dev,
+				 struct cx231xx_dmaqueue *dma_q,
+				 struct cx231xx_buffer *buf)
+{
+	/* Advice that buffer was filled */
+	cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+	buf->vb.state = VIDEOBUF_DONE;
+	buf->vb.field_count++;
+	do_gettimeofday(&buf->vb.ts);
+
+	dev->video_mode.isoc_ctl.buf = NULL;
+
+	list_del(&buf->vb.queue);
+	wake_up(&buf->vb.done);
+}
+
+static inline void print_err_status(struct cx231xx *dev, int packet, int status)
+{
+	char *errmsg = "Unknown";
+
+	switch (status) {
+	case -ENOENT:
+		errmsg = "unlinked synchronuously";
+		break;
+	case -ECONNRESET:
+		errmsg = "unlinked asynchronuously";
+		break;
+	case -ENOSR:
+		errmsg = "Buffer error (overrun)";
+		break;
+	case -EPIPE:
+		errmsg = "Stalled (device not responding)";
+		break;
+	case -EOVERFLOW:
+		errmsg = "Babble (bad cable?)";
+		break;
+	case -EPROTO:
+		errmsg = "Bit-stuff error (bad cable?)";
+		break;
+	case -EILSEQ:
+		errmsg = "CRC/Timeout (could be anything)";
+		break;
+	case -ETIME:
+		errmsg = "Device does not respond";
+		break;
+	}
+	if (packet < 0) {
+		cx231xx_isocdbg("URB status %d [%s].\n", status, errmsg);
+	} else {
+		cx231xx_isocdbg("URB packet %d, status %d [%s].\n",
+				packet, status, errmsg);
+	}
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
+				struct cx231xx_buffer **buf)
+{
+	struct cx231xx_video_mode *vmode =
+	    container_of(dma_q, struct cx231xx_video_mode, vidq);
+	struct cx231xx *dev = container_of(vmode, struct cx231xx, video_mode);
+
+	char *outp;
+
+	if (list_empty(&dma_q->active)) {
+		cx231xx_isocdbg("No active queue to serve\n");
+		dev->video_mode.isoc_ctl.buf = NULL;
+		*buf = NULL;
+		return;
+	}
+
+	/* Get the next buffer */
+	*buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue);
+
+	/* Cleans up buffer - Usefull for testing for frame/URB loss */
+	outp = videobuf_to_vmalloc(&(*buf)->vb);
+	memset(outp, 0, (*buf)->vb.size);
+
+	dev->video_mode.isoc_ctl.buf = *buf;
+
+	return;
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
+{
+	struct cx231xx_buffer *buf;
+	struct cx231xx_dmaqueue *dma_q = urb->context;
+	unsigned char *outp = NULL;
+	int i, rc = 1;
+	unsigned char *p_buffer;
+	u32 bytes_parsed = 0, buffer_size = 0;
+	u8 sav_eav = 0;
+
+	if (!dev)
+		return 0;
+
+	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+		return 0;
+
+	if (urb->status < 0) {
+		print_err_status(dev, -1, urb->status);
+		if (urb->status == -ENOENT)
+			return 0;
+	}
+
+	buf = dev->video_mode.isoc_ctl.buf;
+	if (buf != NULL)
+		outp = videobuf_to_vmalloc(&buf->vb);
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		int status = urb->iso_frame_desc[i].status;
+
+		if (status < 0) {
+			print_err_status(dev, i, status);
+			if (urb->iso_frame_desc[i].status != -EPROTO)
+				continue;
+		}
+
+		if (urb->iso_frame_desc[i].actual_length <= 0) {
+			/* cx231xx_isocdbg("packet %d is empty",i); - spammy */
+			continue;
+		}
+		if (urb->iso_frame_desc[i].actual_length >
+		    dev->video_mode.max_pkt_size) {
+			cx231xx_isocdbg("packet bigger than packet size");
+			continue;
+		}
+
+		/*  get buffer pointer and length */
+		p_buffer = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+		buffer_size = urb->iso_frame_desc[i].actual_length;
+		bytes_parsed = 0;
+
+		if (dma_q->is_partial_line) {
+			/* Handle the case of a partial line */
+			sav_eav = dma_q->last_sav;
+		} else {
+			/* Check for a SAV/EAV overlapping
+				the buffer boundary */
+			sav_eav =
+			    cx231xx_find_boundary_SAV_EAV(p_buffer,
+							  dma_q->partial_buf,
+							  &bytes_parsed);
+		}
+
+		sav_eav &= 0xF0;
+		/* Get the first line if we have some portion of an SAV/EAV from
+		   the last buffer or a partial line  */
+		if (sav_eav) {
+			bytes_parsed += cx231xx_get_video_line(dev, dma_q,
+				sav_eav,	/* SAV/EAV */
+				p_buffer + bytes_parsed,	/* p_buffer */
+				buffer_size - bytes_parsed);/* buf size */
+		}
+
+		/* Now parse data that is completely in this buffer */
+		/* dma_q->is_partial_line = 0;  */
+
+		while (bytes_parsed < buffer_size) {
+			u32 bytes_used = 0;
+
+			sav_eav = cx231xx_find_next_SAV_EAV(
+				p_buffer + bytes_parsed,	/* p_buffer */
+				buffer_size - bytes_parsed,	/* buf size */
+				&bytes_used);/* bytes used to get SAV/EAV */
+
+			bytes_parsed += bytes_used;
+
+			sav_eav &= 0xF0;
+			if (sav_eav && (bytes_parsed < buffer_size)) {
+				bytes_parsed += cx231xx_get_video_line(dev,
+					dma_q, sav_eav,	/* SAV/EAV */
+					p_buffer + bytes_parsed,/* p_buffer */
+					buffer_size - bytes_parsed);/*buf size*/
+			}
+		}
+
+		/* Save the last four bytes of the buffer so we can check the
+		   buffer boundary condition next time */
+		memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
+		bytes_parsed = 0;
+
+	}
+	return rc;
+}
+
+u8 cx231xx_find_boundary_SAV_EAV(u8 *p_buffer, u8 *partial_buf,
+				 u32 *p_bytes_used)
+{
+	u32 bytes_used;
+	u8 boundary_bytes[8];
+	u8 sav_eav = 0;
+
+	*p_bytes_used = 0;
+
+	/* Create an array of the last 4 bytes of the last buffer and the first
+	   4 bytes of the current buffer. */
+
+	memcpy(boundary_bytes, partial_buf, 4);
+	memcpy(boundary_bytes + 4, p_buffer, 4);
+
+	/* Check for the SAV/EAV in the boundary buffer */
+	sav_eav = cx231xx_find_next_SAV_EAV((u8 *)&boundary_bytes, 8,
+					    &bytes_used);
+
+	if (sav_eav) {
+		/* found a boundary SAV/EAV.  Updates the bytes used to reflect
+		   only those used in the new buffer */
+		*p_bytes_used = bytes_used - 4;
+	}
+
+	return sav_eav;
+}
+
+u8 cx231xx_find_next_SAV_EAV(u8 *p_buffer, u32 buffer_size, u32 *p_bytes_used)
+{
+	u32 i;
+	u8 sav_eav = 0;
+
+	/*
+	 * Don't search if the buffer size is less than 4.  It causes a page
+	 * fault since buffer_size - 4 evaluates to a large number in that
+	 * case.
+	 */
+	if (buffer_size < 4) {
+		*p_bytes_used = buffer_size;
+		return 0;
+	}
+
+	for (i = 0; i < (buffer_size - 3); i++) {
+
+		if ((p_buffer[i] == 0xFF) &&
+		    (p_buffer[i + 1] == 0x00) && (p_buffer[i + 2] == 0x00)) {
+
+			*p_bytes_used = i + 4;
+			sav_eav = p_buffer[i + 3];
+			return sav_eav;
+		}
+	}
+
+	*p_bytes_used = buffer_size;
+	return 0;
+}
+
+u32 cx231xx_get_video_line(struct cx231xx *dev,
+			   struct cx231xx_dmaqueue *dma_q, u8 sav_eav,
+			   u8 *p_buffer, u32 buffer_size)
+{
+	u32 bytes_copied = 0;
+	int current_field = -1;
+
+	switch (sav_eav) {
+	case SAV_ACTIVE_VIDEO_FIELD1:
+		/* looking for skipped line which occurred in PAL 720x480 mode.
+		   In this case, there will be no active data contained
+		   between the SAV and EAV */
+		if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
+		    (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
+		    ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
+		     (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
+		     (p_buffer[3] == EAV_VBLANK_FIELD1) ||
+		     (p_buffer[3] == EAV_VBLANK_FIELD2)))
+			return bytes_copied;
+		current_field = 1;
+		break;
+
+	case SAV_ACTIVE_VIDEO_FIELD2:
+		/* looking for skipped line which occurred in PAL 720x480 mode.
+		   In this case, there will be no active data contained between
+		   the SAV and EAV */
+		if ((buffer_size > 3) && (p_buffer[0] == 0xFF) &&
+		    (p_buffer[1] == 0x00) && (p_buffer[2] == 0x00) &&
+		    ((p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD1) ||
+		     (p_buffer[3] == EAV_ACTIVE_VIDEO_FIELD2) ||
+		     (p_buffer[3] == EAV_VBLANK_FIELD1)       ||
+		     (p_buffer[3] == EAV_VBLANK_FIELD2)))
+			return bytes_copied;
+		current_field = 2;
+		break;
+	}
+
+	dma_q->last_sav = sav_eav;
+
+	bytes_copied = cx231xx_copy_video_line(dev, dma_q, p_buffer,
+					       buffer_size, current_field);
+
+	return bytes_copied;
+}
+
+u32 cx231xx_copy_video_line(struct cx231xx *dev,
+			    struct cx231xx_dmaqueue *dma_q, u8 *p_line,
+			    u32 length, int field_number)
+{
+	u32 bytes_to_copy;
+	struct cx231xx_buffer *buf;
+	u32 _line_size = dev->width * 2;
+
+	if (dma_q->current_field != field_number)
+		cx231xx_reset_video_buffer(dev, dma_q);
+
+	/* get the buffer pointer */
+	buf = dev->video_mode.isoc_ctl.buf;
+
+	/* Remember the field number for next time */
+	dma_q->current_field = field_number;
+
+	bytes_to_copy = dma_q->bytes_left_in_line;
+	if (bytes_to_copy > length)
+		bytes_to_copy = length;
+
+	if (dma_q->lines_completed >= dma_q->lines_per_field) {
+		dma_q->bytes_left_in_line -= bytes_to_copy;
+		dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0) ?
+					  0 : 1;
+		return 0;
+	}
+
+	dma_q->is_partial_line = 1;
+
+	/* If we don't have a buffer, just return the number of bytes we would
+	   have copied if we had a buffer. */
+	if (!buf) {
+		dma_q->bytes_left_in_line -= bytes_to_copy;
+		dma_q->is_partial_line = (dma_q->bytes_left_in_line == 0)
+					 ? 0 : 1;
+		return bytes_to_copy;
+	}
+
+	/* copy the data to video buffer */
+	cx231xx_do_copy(dev, dma_q, p_line, bytes_to_copy);
+
+	dma_q->pos += bytes_to_copy;
+	dma_q->bytes_left_in_line -= bytes_to_copy;
+
+	if (dma_q->bytes_left_in_line == 0) {
+		dma_q->bytes_left_in_line = _line_size;
+		dma_q->lines_completed++;
+		dma_q->is_partial_line = 0;
+
+		if (cx231xx_is_buffer_done(dev, dma_q) && buf) {
+			buffer_filled(dev, dma_q, buf);
+
+			dma_q->pos = 0;
+			buf = NULL;
+			dma_q->lines_completed = 0;
+		}
+	}
+
+	return bytes_to_copy;
+}
+
+void cx231xx_reset_video_buffer(struct cx231xx *dev,
+				struct cx231xx_dmaqueue *dma_q)
+{
+	struct cx231xx_buffer *buf;
+
+	/* handle the switch from field 1 to field 2 */
+	if (dma_q->current_field == 1) {
+		if (dma_q->lines_completed >= dma_q->lines_per_field)
+			dma_q->field1_done = 1;
+		else
+			dma_q->field1_done = 0;
+	}
+
+	buf = dev->video_mode.isoc_ctl.buf;
+
+	if (buf == NULL) {
+		u8 *outp = NULL;
+		/* first try to get the buffer */
+		get_next_buf(dma_q, &buf);
+
+		if (buf)
+			outp = videobuf_to_vmalloc(&buf->vb);
+
+		dma_q->pos = 0;
+		dma_q->field1_done = 0;
+		dma_q->current_field = -1;
+	}
+
+	/* reset the counters */
+	dma_q->bytes_left_in_line = dev->width << 1;
+	dma_q->lines_completed = 0;
+}
+
+int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
+		    u8 *p_buffer, u32 bytes_to_copy)
+{
+	u8 *p_out_buffer = NULL;
+	u32 current_line_bytes_copied = 0;
+	struct cx231xx_buffer *buf;
+	u32 _line_size = dev->width << 1;
+	void *startwrite;
+	int offset, lencopy;
+
+	buf = dev->video_mode.isoc_ctl.buf;
+
+	if (buf == NULL)
+		return -1;
+
+	p_out_buffer = videobuf_to_vmalloc(&buf->vb);
+
+	current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line;
+
+	/* Offset field 2 one line from the top of the buffer */
+	offset = (dma_q->current_field == 1) ? 0 : _line_size;
+
+	/* Offset for field 2 */
+	startwrite = p_out_buffer + offset;
+
+	/* lines already completed in the current field */
+	startwrite += (dma_q->lines_completed * _line_size * 2);
+
+	/* bytes already completed in the current line */
+	startwrite += current_line_bytes_copied;
+
+	lencopy = dma_q->bytes_left_in_line > bytes_to_copy ?
+		  bytes_to_copy : dma_q->bytes_left_in_line;
+
+	if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + buf->vb.size))
+		return 0;
+
+	/* The below copies the UYVY data straight into video buffer */
+	cx231xx_swab((u16 *) p_buffer, (u16 *) startwrite, (u16) lencopy);
+
+	return 0;
+}
+
+void cx231xx_swab(u16 *from, u16 *to, u16 len)
+{
+	u16 i;
+
+	if (len <= 0)
+		return;
+
+	for (i = 0; i < len / 2; i++)
+		to[i] = (from[i] << 8) | (from[i] >> 8);
+}
+
+u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q)
+{
+	u8 buffer_complete = 0;
+
+	/* Dual field stream */
+	buffer_complete = ((dma_q->current_field == 2) &&
+			   (dma_q->lines_completed >= dma_q->lines_per_field) &&
+			    dma_q->field1_done);
+
+	return buffer_complete;
+}
+
+/* ------------------------------------------------------------------
+	Videobuf operations
+   ------------------------------------------------------------------*/
+
+static int
+buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	struct v4l2_frequency f;
+
+	*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3;
+	if (0 == *count)
+		*count = CX231XX_DEF_BUF;
+
+	if (*count < CX231XX_MIN_BUF)
+		*count = CX231XX_MIN_BUF;
+
+	/* Ask tuner to go to analog mode */
+	memset(&f, 0, sizeof(f));
+	f.frequency = dev->ctl_freq;
+	f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+
+	call_all(dev, tuner, s_frequency, &f);
+
+	return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	unsigned long flags = 0;
+
+	if (in_interrupt())
+		BUG();
+
+	/* We used to wait for the buffer to finish here, but this didn't work
+	   because, as we were keeping the state as VIDEOBUF_QUEUED,
+	   videobuf_queue_cancel marked it as finished for us.
+	   (Also, it could wedge forever if the hardware was misconfigured.)
+
+	   This should be safe; by the time we get here, the buffer isn't
+	   queued anymore. If we ever start marking the buffers as
+	   VIDEOBUF_ACTIVE, it won't be, though.
+	 */
+	spin_lock_irqsave(&dev->video_mode.slock, flags);
+	if (dev->video_mode.isoc_ctl.buf == buf)
+		dev->video_mode.isoc_ctl.buf = NULL;
+	spin_unlock_irqrestore(&dev->video_mode.slock, flags);
+
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+	       enum v4l2_field field)
+{
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+	struct cx231xx *dev = fh->dev;
+	int rc = 0, urb_init = 0;
+
+	/* The only currently supported format is 16 bits/pixel */
+	buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
+			+ 7) >> 3;
+	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	buf->vb.width = dev->width;
+	buf->vb.height = dev->height;
+	buf->vb.field = field;
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc < 0)
+			goto fail;
+	}
+
+	if (!dev->video_mode.isoc_ctl.num_bufs)
+		urb_init = 1;
+
+	if (urb_init) {
+		rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
+				       CX231XX_NUM_BUFS,
+				       dev->video_mode.max_pkt_size,
+				       cx231xx_isoc_copy);
+		if (rc < 0)
+			goto fail;
+	}
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+
+fail:
+	free_buffer(vq, buf);
+	return rc;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = fh->dev;
+	struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &vidq->active);
+
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+			   struct videobuf_buffer *vb)
+{
+	struct cx231xx_buffer *buf =
+	    container_of(vb, struct cx231xx_buffer, vb);
+	struct cx231xx_fh *fh = vq->priv_data;
+	struct cx231xx *dev = (struct cx231xx *)fh->dev;
+
+	cx231xx_isocdbg("cx231xx: called buffer_release\n");
+
+	free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops cx231xx_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+/*********************  v4l2 interface  **************************************/
+
+void video_mux(struct cx231xx *dev, int index)
+{
+	dev->video_input = index;
+	dev->ctl_ainput = INPUT(index)->amux;
+
+	cx231xx_set_video_input_mux(dev, index);
+
+	cx25840_call(dev, video, s_routing, INPUT(index)->vmux, 0, 0);
+
+	cx231xx_set_audio_input(dev, dev->ctl_ainput);
+
+	cx231xx_info("video_mux : %d\n", index);
+
+	/* do mode control overrides if required */
+	cx231xx_do_mode_ctrl_overrides(dev);
+}
+
+/* Usage lock check functions */
+static int res_get(struct cx231xx_fh *fh)
+{
+	struct cx231xx *dev = fh->dev;
+	int rc = 0;
+
+	/* This instance already has stream_on */
+	if (fh->stream_on)
+		return rc;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		if (dev->stream_on)
+			return -EBUSY;
+		dev->stream_on = 1;
+	} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		if (dev->vbi_stream_on)
+			return -EBUSY;
+		dev->vbi_stream_on = 1;
+	} else
+		return -EINVAL;
+
+	fh->stream_on = 1;
+
+	return rc;
+}
+
+static int res_check(struct cx231xx_fh *fh)
+{
+	return fh->stream_on;
+}
+
+static void res_free(struct cx231xx_fh *fh)
+{
+	struct cx231xx *dev = fh->dev;
+
+	fh->stream_on = 0;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		dev->stream_on = 0;
+	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		dev->vbi_stream_on = 0;
+}
+
+static int check_dev(struct cx231xx *dev)
+{
+	if (dev->state & DEV_DISCONNECTED) {
+		cx231xx_errdev("v4l2 ioctl: device not present\n");
+		return -ENODEV;
+	}
+
+	if (dev->state & DEV_MISCONFIGURED) {
+		cx231xx_errdev("v4l2 ioctl: device is misconfigured; "
+			       "close and open it again\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+void get_scale(struct cx231xx *dev,
+	       unsigned int width, unsigned int height,
+	       unsigned int *hscale, unsigned int *vscale)
+{
+	unsigned int maxw = norm_maxw(dev);
+	unsigned int maxh = norm_maxh(dev);
+
+	*hscale = (((unsigned long)maxw) << 12) / width - 4096L;
+	if (*hscale >= 0x4000)
+		*hscale = 0x3fff;
+
+	*vscale = (((unsigned long)maxh) << 12) / height - 4096L;
+	if (*vscale >= 0x4000)
+		*vscale = 0x3fff;
+
+	dev->hscale = *hscale;
+	dev->vscale = *vscale;
+
+}
+
+/* ------------------------------------------------------------------
+	IOCTL vidioc handling
+   ------------------------------------------------------------------*/
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	mutex_lock(&dev->lock);
+
+	f->fmt.pix.width = dev->width;
+	f->fmt.pix.height = dev->height;
+	f->fmt.pix.pixelformat = dev->format->fourcc;;
+	f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;;
+	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(format); i++)
+		if (format[i].fourcc == fourcc)
+			return &format[i];
+
+	return NULL;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int width = f->fmt.pix.width;
+	int height = f->fmt.pix.height;
+	unsigned int maxw = norm_maxw(dev);
+	unsigned int maxh = norm_maxh(dev);
+	unsigned int hscale, vscale;
+	struct cx231xx_fmt *fmt;
+
+	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	if (!fmt) {
+		cx231xx_videodbg("Fourcc format (%08x) invalid.\n",
+				 f->fmt.pix.pixelformat);
+		return -EINVAL;
+	}
+
+	/* width must even because of the YUYV format
+	   height must be even because of interlacing */
+	height &= 0xfffe;
+	width &= 0xfffe;
+
+	if (unlikely(height < 32))
+		height = 32;
+	if (unlikely(height > maxh))
+		height = maxh;
+	if (unlikely(width < 48))
+		width = 48;
+	if (unlikely(width > maxw))
+		width = maxw;
+
+	get_scale(dev, width, height, &hscale, &vscale);
+
+	width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
+	height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+	f->fmt.pix.width = width;
+	f->fmt.pix.height = height;
+	f->fmt.pix.pixelformat = fmt->fourcc;
+	f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
+	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+	struct cx231xx_fmt *fmt;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+
+	vidioc_try_fmt_vid_cap(file, priv, f);
+
+	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	if (!fmt) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+		cx231xx_errdev("%s queue busy\n", __func__);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	if (dev->stream_on && !fh->stream_on) {
+		cx231xx_errdev("%s device in use by another fh\n", __func__);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	/* set new image size */
+	dev->width = f->fmt.pix.width;
+	dev->height = f->fmt.pix.height;
+	dev->format = fmt;
+	get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
+
+	call_all(dev, video, s_fmt, f);
+
+	/* Set the correct alternate setting for this resolution */
+	cx231xx_resolution_set(dev);
+
+out:
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id * id)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	*id = dev->norm;
+	return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	struct v4l2_format f;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);
+
+	mutex_lock(&dev->lock);
+	dev->norm = *norm;
+
+	/* Adjusts width/height, if needed */
+	f.fmt.pix.width = dev->width;
+	f.fmt.pix.height = dev->height;
+	vidioc_try_fmt_vid_cap(file, priv, &f);
+
+	/* set new image size */
+	dev->width = f.fmt.pix.width;
+	dev->height = f.fmt.pix.height;
+	get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
+
+	call_all(dev, core, s_std, dev->norm);
+
+	mutex_unlock(&dev->lock);
+
+	cx231xx_resolution_set(dev);
+
+	/* do mode control overrides */
+	cx231xx_do_mode_ctrl_overrides(dev);
+
+	return 0;
+}
+
+static const char *iname[] = {
+	[CX231XX_VMUX_COMPOSITE1] = "Composite1",
+	[CX231XX_VMUX_SVIDEO]     = "S-Video",
+	[CX231XX_VMUX_TELEVISION] = "Television",
+	[CX231XX_VMUX_CABLE]      = "Cable TV",
+	[CX231XX_VMUX_DVB]        = "DVB",
+	[CX231XX_VMUX_DEBUG]      = "for debug only",
+};
+
+static int vidioc_enum_input(struct file *file, void *priv,
+			     struct v4l2_input *i)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	unsigned int n;
+
+	n = i->index;
+	if (n >= MAX_CX231XX_INPUT)
+		return -EINVAL;
+	if (0 == INPUT(n)->type)
+		return -EINVAL;
+
+	i->index = n;
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+
+	strcpy(i->name, iname[INPUT(n)->type]);
+
+	if ((CX231XX_VMUX_TELEVISION == INPUT(n)->type) ||
+	    (CX231XX_VMUX_CABLE == INPUT(n)->type))
+		i->type = V4L2_INPUT_TYPE_TUNER;
+
+	i->std = dev->vdev->tvnorms;
+
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	*i = dev->video_input;
+
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (i >= MAX_CX231XX_INPUT)
+		return -EINVAL;
+	if (0 == INPUT(i)->type)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+
+	video_mux(dev, i);
+
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	switch (a->index) {
+	case CX231XX_AMUX_VIDEO:
+		strcpy(a->name, "Television");
+		break;
+	case CX231XX_AMUX_LINE_IN:
+		strcpy(a->name, "Line In");
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	a->index = dev->ctl_ainput;
+	a->capability = V4L2_AUDCAP_STEREO;
+
+	return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int status = 0;
+
+	/* Doesn't allow manual routing */
+	if (a->index != dev->ctl_ainput)
+		return -EINVAL;
+
+	dev->ctl_ainput = INPUT(a->index)->amux;
+	status = cx231xx_set_audio_input(dev, dev->ctl_ainput);
+
+	return status;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+			    struct v4l2_queryctrl *qc)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int id = qc->id;
+	int i;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
+	if (unlikely(qc->id == 0))
+		return -EINVAL;
+
+	memset(qc, 0, sizeof(*qc));
+
+	qc->id = id;
+
+	if (qc->id < V4L2_CID_BASE || qc->id >= V4L2_CID_LASTP1)
+		return -EINVAL;
+
+	for (i = 0; i < CX231XX_CTLS; i++)
+		if (cx231xx_ctls[i].v.id == qc->id)
+			break;
+
+	if (i == CX231XX_CTLS) {
+		*qc = no_ctl;
+		return 0;
+	}
+	*qc = cx231xx_ctls[i].v;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, core, queryctrl, qc);
+	mutex_unlock(&dev->lock);
+
+	if (qc->type)
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctrl)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, core, g_ctrl, ctrl);
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctrl)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, core, s_ctrl, ctrl);
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (0 != t->index)
+		return -EINVAL;
+
+	strcpy(t->name, "Tuner");
+
+	t->type = V4L2_TUNER_ANALOG_TV;
+	t->capability = V4L2_TUNER_CAP_NORM;
+	t->rangehigh = 0xffffffffUL;
+	t->signal = 0xffff;	/* LOCKED */
+
+	return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (0 != t->index)
+		return -EINVAL;
+#if 0
+	mutex_lock(&dev->lock);
+	call_all(dev, tuner, s_tuner, t);
+	mutex_unlock(&dev->lock);
+#endif
+	return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+			      struct v4l2_frequency *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	mutex_lock(&dev->lock);
+	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+	f->frequency = dev->ctl_freq;
+
+	call_all(dev, tuner, g_frequency, f);
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+			      struct v4l2_frequency *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if (0 != f->tuner)
+		return -EINVAL;
+
+	if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
+		return -EINVAL;
+	if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
+		return -EINVAL;
+
+	/* set pre channel change settings in DIF first */
+	rc = cx231xx_tuner_pre_channel_change(dev);
+
+	mutex_lock(&dev->lock);
+
+	dev->ctl_freq = f->frequency;
+
+	if (dev->tuner_type == TUNER_XC5000) {
+		if (dev->cx231xx_set_analog_freq != NULL)
+			dev->cx231xx_set_analog_freq(dev, f->frequency);
+	} else
+		call_all(dev, tuner, s_frequency, f);
+
+	mutex_unlock(&dev->lock);
+
+	/* set post channel change settings in DIF first */
+	rc = cx231xx_tuner_post_channel_change(dev);
+
+	cx231xx_info("Set New FREQUENCY to %d\n", f->frequency);
+
+	return rc;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+/*
+  -R, --list-registers=type=<host/i2cdrv/i2caddr>,
+				chip=<chip>[,min=<addr>,max=<addr>]
+		     dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
+  -r, --set-register=type=<host/i2cdrv/i2caddr>,
+				chip=<chip>,reg=<addr>,val=<val>
+		     set the register [VIDIOC_DBG_S_REGISTER]
+
+  if type == host, then <chip> is the hosts chip ID (default 0)
+  if type == i2cdrv (default), then <chip> is the I2C driver name or ID
+  if type == i2caddr, then <chip> is the 7-bit I2C address
+*/
+
+static int vidioc_g_register(struct file *file, void *priv,
+			     struct v4l2_dbg_register *reg)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int ret = 0;
+	u8 value[4] = { 0, 0, 0, 0 };
+	u32 data = 0;
+
+	switch (reg->match.type) {
+	case V4L2_CHIP_MATCH_HOST:
+		switch (reg->match.addr) {
+		case 0:	/* Cx231xx - internal registers */
+			ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+						  (u16)reg->reg, value, 4);
+			reg->val = value[0] | value[1] << 8 |
+				   value[2] << 16 | value[3] << 24;
+			break;
+		case 1:	/* AFE - read byte */
+			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+						  (u16)reg->reg, 2, &data, 1);
+			reg->val = le32_to_cpu(data & 0xff);
+			break;
+		case 14: /* AFE - read dword */
+			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+						  (u16)reg->reg, 2, &data, 4);
+			reg->val = le32_to_cpu(data);
+			break;
+		case 2:	/* Video Block - read byte */
+			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+						  (u16)reg->reg, 2, &data, 1);
+			reg->val = le32_to_cpu(data & 0xff);
+			break;
+		case 24: /* Video Block - read dword */
+			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+						  (u16)reg->reg, 2, &data, 4);
+			reg->val = le32_to_cpu(data);
+			break;
+		case 3:	/* I2S block - read byte */
+			ret = cx231xx_read_i2c_data(dev,
+						    I2S_BLK_DEVICE_ADDRESS,
+						    (u16)reg->reg, 1,
+						    &data, 1);
+			reg->val = le32_to_cpu(data & 0xff);
+			break;
+		case 34: /* I2S Block - read dword */
+			ret =
+			    cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+						  (u16)reg->reg, 1, &data, 4);
+			reg->val = le32_to_cpu(data);
+			break;
+		}
+		return ret < 0 ? ret : 0;
+
+	case V4L2_CHIP_MATCH_I2C_DRIVER:
+		call_all(dev, core, g_register, reg);
+		return 0;
+	case V4L2_CHIP_MATCH_I2C_ADDR:
+		/* Not supported yet */
+		return -EINVAL;
+	default:
+		if (!v4l2_chip_match_host(&reg->match))
+			return -EINVAL;
+	}
+
+	mutex_lock(&dev->lock);
+	call_all(dev, core, g_register, reg);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+			     struct v4l2_dbg_register *reg)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int ret = 0;
+	__le64 buf;
+	u32 value;
+	u8 data[4] = { 0, 0, 0, 0 };
+
+	buf = cpu_to_le64(reg->val);
+
+	switch (reg->match.type) {
+	case V4L2_CHIP_MATCH_HOST:
+		{
+			value = (u32) buf & 0xffffffff;
+
+			switch (reg->match.addr) {
+			case 0:	/* cx231xx internal registers */
+				data[0] = (u8) value;
+				data[1] = (u8) (value >> 8);
+				data[2] = (u8) (value >> 16);
+				data[3] = (u8) (value >> 24);
+				ret = cx231xx_write_ctrl_reg(dev,
+							   VRT_SET_REGISTER,
+							   (u16)reg->reg, data,
+							   4);
+				break;
+			case 1:	/* AFE - read byte */
+				ret = cx231xx_write_i2c_data(dev,
+							AFE_DEVICE_ADDRESS,
+							(u16)reg->reg, 2,
+							value, 1);
+				break;
+			case 14: /* AFE - read dword */
+				ret = cx231xx_write_i2c_data(dev,
+							AFE_DEVICE_ADDRESS,
+							(u16)reg->reg, 2,
+							value, 4);
+				break;
+			case 2:	/* Video Block - read byte */
+				ret =
+				    cx231xx_write_i2c_data(dev,
+							VID_BLK_I2C_ADDRESS,
+							(u16)reg->reg, 2,
+							value, 1);
+				break;
+			case 24: /* Video Block - read dword */
+				ret =
+				    cx231xx_write_i2c_data(dev,
+							VID_BLK_I2C_ADDRESS,
+							(u16)reg->reg, 2,
+							value, 4);
+				break;
+			case 3:	/* I2S block - read byte */
+				ret =
+				    cx231xx_write_i2c_data(dev,
+							I2S_BLK_DEVICE_ADDRESS,
+							(u16)reg->reg, 1,
+							value, 1);
+				break;
+			case 34: /* I2S block - read dword */
+				ret =
+				    cx231xx_write_i2c_data(dev,
+							I2S_BLK_DEVICE_ADDRESS,
+							(u16)reg->reg, 1,
+							value, 4);
+				break;
+			}
+		}
+		return ret < 0 ? ret : 0;
+
+	default:
+		break;
+	}
+
+	mutex_lock(&dev->lock);
+	call_all(dev, core, s_register, reg);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+#endif
+
+static int vidioc_cropcap(struct file *file, void *priv,
+			  struct v4l2_cropcap *cc)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	cc->bounds.left = 0;
+	cc->bounds.top = 0;
+	cc->bounds.width = dev->width;
+	cc->bounds.height = dev->height;
+	cc->defrect = cc->bounds;
+	cc->pixelaspect.numerator = 54;	/* 4:3 FIXME: remove magic numbers */
+	cc->pixelaspect.denominator = 59;
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+			   enum v4l2_buf_type type)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+
+	if (likely(rc >= 0))
+		rc = videobuf_streamon(&fh->vb_vidq);
+
+	call_all(dev, video, s_stream, 1);
+
+	mutex_unlock(&dev->lock);
+
+	return rc;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+			    enum v4l2_buf_type type)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+	    (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+	if (type != fh->type)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+
+	cx25840_call(dev, video, s_stream, 0);
+
+	videobuf_streamoff(&fh->vb_vidq);
+	res_free(fh);
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
+	strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+
+	cap->version = CX231XX_VERSION_CODE;
+
+	cap->capabilities = V4L2_CAP_VBI_CAPTURE |
+#if 0
+		V4L2_CAP_SLICED_VBI_CAPTURE |
+#endif
+		V4L2_CAP_VIDEO_CAPTURE	|
+		V4L2_CAP_AUDIO		|
+		V4L2_CAP_READWRITE	|
+		V4L2_CAP_STREAMING;
+
+	if (dev->tuner_type != TUNER_ABSENT)
+		cap->capabilities |= V4L2_CAP_TUNER;
+
+	return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f)
+{
+	if (unlikely(f->index >= ARRAY_SIZE(format)))
+		return -EINVAL;
+
+	strlcpy(f->description, format[f->index].name, sizeof(f->description));
+	f->pixelformat = format[f->index].fourcc;
+
+	return 0;
+}
+
+/* Sliced VBI ioctls */
+static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
+				       struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+
+	f->fmt.sliced.service_set = 0;
+
+	call_all(dev, video, g_fmt, f);
+
+	if (f->fmt.sliced.service_set == 0)
+		rc = -EINVAL;
+
+	mutex_unlock(&dev->lock);
+	return rc;
+}
+
+static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
+					 struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, video, g_fmt, f);
+	mutex_unlock(&dev->lock);
+
+	if (f->fmt.sliced.service_set == 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+/* RAW VBI ioctls */
+
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
+	    35468950 : 28636363;
+	f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
+	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	f->fmt.vbi.offset = 64 * 4;
+	f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
+	f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_LINES : NTSC_VBI_LINES;
+	f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
+	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+
+	return 0;
+
+}
+
+static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+
+	if (dev->vbi_stream_on && !fh->stream_on) {
+		cx231xx_errdev("%s device in use by another fh\n", __func__);
+		return -EBUSY;
+	}
+
+	f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+	f->fmt.vbi.sampling_rate = (dev->norm & V4L2_STD_625_50) ?
+	    35468950 : 28636363;
+	f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
+	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	f->fmt.vbi.offset = 244;
+	f->fmt.vbi.flags = 0;
+	f->fmt.vbi.start[0] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_START_LINE : NTSC_VBI_START_LINE;
+	f->fmt.vbi.count[0] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_LINES : NTSC_VBI_LINES;
+	f->fmt.vbi.start[1] = (dev->norm & V4L2_STD_625_50) ?
+	    PAL_VBI_START_LINE + 312 : NTSC_VBI_START_LINE + 263;
+	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
+
+	return 0;
+
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *rb)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+	struct cx231xx_fh *fh = priv;
+
+	return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+/* ----------------------------------------------------------- */
+/* RADIO ESPECIFIC IOCTLS                                      */
+/* ----------------------------------------------------------- */
+
+static int radio_querycap(struct file *file, void *priv,
+			  struct v4l2_capability *cap)
+{
+	struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+	strlcpy(cap->driver, "cx231xx", sizeof(cap->driver));
+	strlcpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+
+	cap->version = CX231XX_VERSION_CODE;
+	cap->capabilities = V4L2_CAP_TUNER;
+	return 0;
+}
+
+static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+	if (unlikely(t->index > 0))
+		return -EINVAL;
+
+	strcpy(t->name, "Radio");
+	t->type = V4L2_TUNER_RADIO;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, tuner, s_tuner, t);
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int radio_enum_input(struct file *file, void *priv, struct v4l2_input *i)
+{
+	if (i->index != 0)
+		return -EINVAL;
+	strcpy(i->name, "Radio");
+	i->type = V4L2_INPUT_TYPE_TUNER;
+
+	return 0;
+}
+
+static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+	if (unlikely(a->index))
+		return -EINVAL;
+
+	strcpy(a->name, "Radio");
+	return 0;
+}
+
+static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev;
+
+	if (0 != t->index)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+	call_all(dev, tuner, s_tuner, t);
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int radio_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	return 0;
+}
+
+static int radio_s_input(struct file *file, void *fh, unsigned int i)
+{
+	return 0;
+}
+
+static int radio_queryctrl(struct file *file, void *priv,
+			   struct v4l2_queryctrl *c)
+{
+	int i;
+
+	if (c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
+		return -EINVAL;
+	if (c->id == V4L2_CID_AUDIO_MUTE) {
+		for (i = 0; i < CX231XX_CTLS; i++)
+			if (cx231xx_ctls[i].v.id == c->id)
+				break;
+		*c = cx231xx_ctls[i].v;
+	} else
+		*c = no_ctl;
+	return 0;
+}
+
+/*
+ * cx231xx_v4l2_open()
+ * inits the device and starts isoc transfer
+ */
+static int cx231xx_v4l2_open(struct file *filp)
+{
+	int minor = video_devdata(filp)->minor;
+	int errCode = 0, radio = 0;
+	struct cx231xx *dev = NULL;
+	struct cx231xx_fh *fh;
+	enum v4l2_buf_type fh_type = 0;
+
+	dev = cx231xx_get_device(minor, &fh_type, &radio);
+	if (NULL == dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->lock);
+
+	cx231xx_videodbg("open minor=%d type=%s users=%d\n",
+			 minor, v4l2_type_names[fh_type], dev->users);
+
+#if 0
+	errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+	if (errCode < 0) {
+		cx231xx_errdev
+		    ("Device locked on digital mode. Can't open analog\n");
+		mutex_unlock(&dev->lock);
+		return -EBUSY;
+	}
+#endif
+
+	fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL);
+	if (!fh) {
+		cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");
+		mutex_unlock(&dev->lock);
+		return -ENOMEM;
+	}
+	fh->dev = dev;
+	fh->radio = radio;
+	fh->type = fh_type;
+	filp->private_data = fh;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+		dev->width = norm_maxw(dev);
+		dev->height = norm_maxh(dev);
+		dev->hscale = 0;
+		dev->vscale = 0;
+
+		/* Power up in Analog TV mode */
+		cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV);
+
+#if 0
+		cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
+#endif
+		cx231xx_resolution_set(dev);
+
+		/* set video alternate setting */
+		cx231xx_set_video_alternate(dev);
+
+		/* Needed, since GPIO might have disabled power of
+		   some i2c device */
+		cx231xx_config_i2c(dev);
+
+		/* device needs to be initialized before isoc transfer */
+		dev->video_input = dev->video_input > 2 ? 2 : dev->video_input;
+		video_mux(dev, dev->video_input);
+
+	}
+	if (fh->radio) {
+		cx231xx_videodbg("video_open: setting radio device\n");
+
+		/* cx231xx_start_radio(dev); */
+
+		call_all(dev, tuner, s_radio);
+	}
+
+	dev->users++;
+
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops,
+					    NULL, &dev->video_mode.slock,
+					    fh->type, V4L2_FIELD_INTERLACED,
+					    sizeof(struct cx231xx_buffer), fh);
+	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		/* Set the required alternate setting  VBI interface works in
+		   Bulk mode only */
+		cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+
+		videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
+					    NULL, &dev->vbi_mode.slock,
+					    fh->type, V4L2_FIELD_SEQ_TB,
+					    sizeof(struct cx231xx_buffer), fh);
+	}
+
+	mutex_unlock(&dev->lock);
+
+	return errCode;
+}
+
+/*
+ * cx231xx_realease_resources()
+ * unregisters the v4l2,i2c and usb devices
+ * called when the device gets disconected or at module unload
+*/
+void cx231xx_release_analog_resources(struct cx231xx *dev)
+{
+
+	/*FIXME: I2C IR should be disconnected */
+
+	if (dev->radio_dev) {
+		if (-1 != dev->radio_dev->minor)
+			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)
+			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)
+			video_unregister_device(dev->vdev);
+		else
+			video_device_release(dev->vdev);
+		dev->vdev = NULL;
+	}
+}
+
+/*
+ * cx231xx_v4l2_close()
+ * stops streaming and deallocates all resources allocated by the v4l2
+ * calls and ioctls
+ */
+static int cx231xx_v4l2_close(struct file *filp)
+{
+	struct cx231xx_fh *fh = filp->private_data;
+	struct cx231xx *dev = fh->dev;
+
+	cx231xx_videodbg("users=%d\n", dev->users);
+
+	mutex_lock(&dev->lock);
+
+	if (res_check(fh))
+		res_free(fh);
+
+	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		videobuf_stop(&fh->vb_vidq);
+		videobuf_mmap_free(&fh->vb_vidq);
+
+		/* the device is already disconnect,
+		   free the remaining resources */
+		if (dev->state & DEV_DISCONNECTED) {
+			cx231xx_release_resources(dev);
+			mutex_unlock(&dev->lock);
+			kfree(dev);
+			return 0;
+		}
+
+		/* do this before setting alternate! */
+		cx231xx_uninit_vbi_isoc(dev);
+
+		/* set alternate 0 */
+		if (!dev->vbi_or_sliced_cc_mode)
+			cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
+		else
+			cx231xx_set_alt_setting(dev, INDEX_HANC, 0);
+
+		kfree(fh);
+		dev->users--;
+		wake_up_interruptible_nr(&dev->open, 1);
+		mutex_unlock(&dev->lock);
+		return 0;
+	}
+
+	if (dev->users == 1) {
+		videobuf_stop(&fh->vb_vidq);
+		videobuf_mmap_free(&fh->vb_vidq);
+
+		/* the device is already disconnect,
+		   free the remaining resources */
+		if (dev->state & DEV_DISCONNECTED) {
+			cx231xx_release_resources(dev);
+			mutex_unlock(&dev->lock);
+			kfree(dev);
+			return 0;
+		}
+
+		/* Save some power by putting tuner to sleep */
+		call_all(dev, tuner, s_standby);
+
+		/* do this before setting alternate! */
+		cx231xx_uninit_isoc(dev);
+		cx231xx_set_mode(dev, CX231XX_SUSPEND);
+
+		/* set alternate 0 */
+		cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0);
+	}
+	kfree(fh);
+	dev->users--;
+	wake_up_interruptible_nr(&dev->open, 1);
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+/*
+ * cx231xx_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t
+cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
+		  loff_t *pos)
+{
+	struct cx231xx_fh *fh = filp->private_data;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
+	    (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {
+		mutex_lock(&dev->lock);
+		rc = res_get(fh);
+		mutex_unlock(&dev->lock);
+
+		if (unlikely(rc < 0))
+			return rc;
+
+		return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+					    filp->f_flags & O_NONBLOCK);
+	}
+	return 0;
+}
+
+/*
+ * cx231xx_v4l2_poll()
+ * will allocate buffers when called for the first time
+ */
+static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table * wait)
+{
+	struct cx231xx_fh *fh = filp->private_data;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+	mutex_unlock(&dev->lock);
+
+	if (unlikely(rc < 0))
+		return POLLERR;
+
+	if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) ||
+	    (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type))
+		return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+	else
+		return POLLERR;
+}
+
+/*
+ * cx231xx_v4l2_mmap()
+ */
+static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct cx231xx_fh *fh = filp->private_data;
+	struct cx231xx *dev = fh->dev;
+	int rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	mutex_lock(&dev->lock);
+	rc = res_get(fh);
+	mutex_unlock(&dev->lock);
+
+	if (unlikely(rc < 0))
+		return rc;
+
+	rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+	cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
+			 (unsigned long)vma->vm_start,
+			 (unsigned long)vma->vm_end -
+			 (unsigned long)vma->vm_start, rc);
+
+	return rc;
+}
+
+static const struct v4l2_file_operations cx231xx_v4l_fops = {
+	.owner   = THIS_MODULE,
+	.open    = cx231xx_v4l2_open,
+	.release = cx231xx_v4l2_close,
+	.read    = cx231xx_v4l2_read,
+	.poll    = cx231xx_v4l2_poll,
+	.mmap    = cx231xx_v4l2_mmap,
+	.ioctl   = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap               = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap       = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap          = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap        = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap          = vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_vbi_cap          = vidioc_g_fmt_vbi_cap,
+	.vidioc_try_fmt_vbi_cap        = vidioc_try_fmt_vbi_cap,
+	.vidioc_s_fmt_vbi_cap          = vidioc_try_fmt_vbi_cap,
+	.vidioc_g_audio                =  vidioc_g_audio,
+	.vidioc_s_audio                = vidioc_s_audio,
+	.vidioc_cropcap                = vidioc_cropcap,
+	.vidioc_g_fmt_sliced_vbi_cap   = vidioc_g_fmt_sliced_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+	.vidioc_reqbufs                = vidioc_reqbufs,
+	.vidioc_querybuf               = vidioc_querybuf,
+	.vidioc_qbuf                   = vidioc_qbuf,
+	.vidioc_dqbuf                  = vidioc_dqbuf,
+	.vidioc_s_std                  = vidioc_s_std,
+	.vidioc_g_std                  = vidioc_g_std,
+	.vidioc_enum_input             = vidioc_enum_input,
+	.vidioc_g_input                = vidioc_g_input,
+	.vidioc_s_input                = vidioc_s_input,
+	.vidioc_queryctrl              = vidioc_queryctrl,
+	.vidioc_g_ctrl                 = vidioc_g_ctrl,
+	.vidioc_s_ctrl                 = vidioc_s_ctrl,
+	.vidioc_streamon               = vidioc_streamon,
+	.vidioc_streamoff              = vidioc_streamoff,
+	.vidioc_g_tuner                = vidioc_g_tuner,
+	.vidioc_s_tuner                = vidioc_s_tuner,
+	.vidioc_g_frequency            = vidioc_g_frequency,
+	.vidioc_s_frequency            = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register             = vidioc_g_register,
+	.vidioc_s_register             = vidioc_s_register,
+#endif
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf                   = vidiocgmbuf,
+#endif
+};
+
+static struct video_device cx231xx_vbi_template;
+
+static const struct video_device cx231xx_video_template = {
+	.fops         = &cx231xx_v4l_fops,
+	.release      = video_device_release,
+	.ioctl_ops    = &video_ioctl_ops,
+	.minor        = -1,
+	.tvnorms      = V4L2_STD_ALL,
+	.current_norm = V4L2_STD_PAL,
+};
+
+static const struct v4l2_file_operations radio_fops = {
+	.owner   = THIS_MODULE,
+	.open   = cx231xx_v4l2_open,
+	.release = cx231xx_v4l2_close,
+	.ioctl   = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
+	.vidioc_querycap    = radio_querycap,
+	.vidioc_g_tuner     = radio_g_tuner,
+	.vidioc_enum_input  = radio_enum_input,
+	.vidioc_g_audio     = radio_g_audio,
+	.vidioc_s_tuner     = radio_s_tuner,
+	.vidioc_s_audio     = radio_s_audio,
+	.vidioc_s_input     = radio_s_input,
+	.vidioc_queryctrl   = radio_queryctrl,
+	.vidioc_g_ctrl      = vidioc_g_ctrl,
+	.vidioc_s_ctrl      = vidioc_s_ctrl,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register  = vidioc_g_register,
+	.vidioc_s_register  = vidioc_s_register,
+#endif
+};
+
+static struct video_device cx231xx_radio_template = {
+	.name      = "cx231xx-radio",
+	.fops      = &radio_fops,
+	.ioctl_ops = &radio_ioctl_ops,
+	.minor     = -1,
+};
+
+/******************************** usb interface ******************************/
+
+static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
+		const struct video_device
+		*template, const char *type_name)
+{
+	struct video_device *vfd;
+
+	vfd = video_device_alloc();
+	if (NULL == vfd)
+		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);
+
+	return vfd;
+}
+
+int cx231xx_register_analog_devices(struct cx231xx *dev)
+{
+	int ret;
+
+	cx231xx_info("%s: v4l2 driver version %d.%d.%d\n",
+		     dev->name,
+		     (CX231XX_VERSION_CODE >> 16) & 0xff,
+		     (CX231XX_VERSION_CODE >> 8) & 0xff,
+		     CX231XX_VERSION_CODE & 0xff);
+
+	/* set default norm */
+	/*dev->norm = cx231xx_video_template.current_norm; */
+	dev->width = norm_maxw(dev);
+	dev->height = norm_maxh(dev);
+	dev->interlaced = 0;
+	dev->hscale = 0;
+	dev->vscale = 0;
+
+	/* Analog specific initialization */
+	dev->format = &format[0];
+	/* video_mux(dev, dev->video_input); */
+
+	/* Audio defaults */
+	dev->mute = 1;
+	dev->volume = 0x1f;
+
+	/* enable vbi capturing */
+	/* write code here...  */
+
+	/* allocate and fill video video_device struct */
+	dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video");
+	if (!dev->vdev) {
+		cx231xx_errdev("cannot allocate video_device.\n");
+		return -ENODEV;
+	}
+
+	/* register v4l2 video video_device */
+	ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
+				    video_nr[dev->devno]);
+	if (ret) {
+		cx231xx_errdev("unable to register video device (error=%i).\n",
+			       ret);
+		return ret;
+	}
+
+	cx231xx_info("%s/0: registered device video%d [v4l2]\n",
+		     dev->name, dev->vdev->num);
+
+	/* Initialize VBI template */
+	memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
+	       sizeof(cx231xx_vbi_template));
+	strcpy(cx231xx_vbi_template.name, "cx231xx-vbi");
+
+	/* Allocate and fill vbi video_device struct */
+	dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi");
+
+	/* register v4l2 vbi video_device */
+	ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
+				    vbi_nr[dev->devno]);
+	if (ret < 0) {
+		cx231xx_errdev("unable to register vbi device\n");
+		return ret;
+	}
+
+	cx231xx_info("%s/0: registered device vbi%d\n",
+		     dev->name, dev->vbi_dev->num);
+
+	if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
+		dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
+						   "radio");
+		if (!dev->radio_dev) {
+			cx231xx_errdev("cannot allocate video_device.\n");
+			return -ENODEV;
+		}
+		ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
+					    radio_nr[dev->devno]);
+		if (ret < 0) {
+			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("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
+		     dev->vdev->num, dev->vbi_dev->num);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,35 @@
+config VIDEO_CX231XX
+	tristate "Conexant cx231xx USB video capture support"
+	depends on VIDEO_DEV && I2C && INPUT
+	select VIDEO_TUNER
+	select VIDEO_TVEEPROM
+	select VIDEO_IR
+	select VIDEOBUF_VMALLOC
+	select VIDEO_CX25840
+
+	---help---
+	  This is a video4linux driver for Conexant 231xx USB based TV cards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx231xx
+
+config VIDEO_CX231XX_ALSA
+	tristate "Conexant Cx231xx ALSA audio module"
+	depends on VIDEO_CX231XX && SND
+	select SND_PCM
+
+	---help---
+	  This is an ALSA driver for Cx231xx USB based TV cards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx231xx-alsa
+
+config VIDEO_CX231XX_DVB
+	tristate "DVB/ATSC Support for Cx231xx based TV cards"
+	depends on VIDEO_CX231XX && DVB_CORE
+	select VIDEOBUF_DVB
+	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE
+
+	---help---
+	  This adds support for DVB cards based on the
+	  Conexant cx231xx chips.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx231xx/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx231xx/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,14 @@
+cx231xx-objs     := cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o \
+		    cx231xx-avcore.o cx231xx-pcb-cfg.o cx231xx-vbi.o
+
+cx231xx-alsa-objs := cx231xx-audio.o
+
+obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o
+obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
+obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx2341x.c linux-libre-2.6.30-gnu1/drivers/media/video/cx2341x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx2341x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx2341x.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * cx2341x - generic code for cx23415/6 based devices
+ * cx2341x - generic code for cx23415/6/8 based devices
  *
  * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
  *
@@ -30,7 +30,7 @@
 #include <media/cx2341x.h>
 #include <media/v4l2-common.h>
 
-MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_DESCRIPTION("cx23415/6/8 driver");
 MODULE_AUTHOR("Hans Verkuil");
 MODULE_LICENSE("GPL");
 
@@ -38,6 +38,7 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+/* Must be sorted from low to high control ID! */
 const u32 cx2341x_mpeg_ctrls[] = {
 	V4L2_CID_MPEG_CLASS,
 	V4L2_CID_MPEG_STREAM_TYPE,
@@ -50,6 +51,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
 	V4L2_CID_MPEG_AUDIO_EMPHASIS,
 	V4L2_CID_MPEG_AUDIO_CRC,
 	V4L2_CID_MPEG_AUDIO_MUTE,
+	V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
 	V4L2_CID_MPEG_VIDEO_ENCODING,
 	V4L2_CID_MPEG_VIDEO_ASPECT,
 	V4L2_CID_MPEG_VIDEO_B_FRAMES,
@@ -94,6 +96,7 @@ static const struct cx2341x_mpeg_params
 	.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
 	.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
 	.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+	.audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
 	.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
 	.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
 	.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
@@ -148,6 +151,9 @@ static int cx2341x_get_ctrl(const struct
 	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
 		ctrl->value = params->audio_l2_bitrate;
 		break;
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		ctrl->value = params->audio_ac3_bitrate;
+		break;
 	case V4L2_CID_MPEG_AUDIO_MODE:
 		ctrl->value = params->audio_mode;
 		break;
@@ -256,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx234
 		params->audio_sampling_freq = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		if (busy)
+			return -EBUSY;
+		if (params->capabilities & CX2341X_CAP_HAS_AC3)
+			if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+			    ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+				return -ERANGE;
 		params->audio_encoding = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -263,6 +275,13 @@ static int cx2341x_set_ctrl(struct cx234
 			return -EBUSY;
 		params->audio_l2_bitrate = ctrl->value;
 		break;
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		if (busy)
+			return -EBUSY;
+		if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+			return -EINVAL;
+		params->audio_ac3_bitrate = ctrl->value;
+		break;
 	case V4L2_CID_MPEG_AUDIO_MODE:
 		params->audio_mode = ctrl->value;
 		break;
@@ -481,29 +500,106 @@ int cx2341x_ctrl_query(const struct cx23
 	int err;
 
 	switch (qctrl->id) {
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+				V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
+				V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+
+	case V4L2_CID_MPEG_STREAM_VBI_FMT:
+		if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+			return v4l2_ctrl_query_fill(qctrl,
+					V4L2_MPEG_STREAM_VBI_FMT_NONE,
+					V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
+					V4L2_MPEG_STREAM_VBI_FMT_NONE);
+		return cx2341x_ctrl_query_fill(qctrl,
+				V4L2_MPEG_STREAM_VBI_FMT_NONE,
+				V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+				default_params.stream_vbi_fmt);
+
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
+				V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
+				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+			/*
+			 * The state of L2 & AC3 bitrate controls can change
+			 * when this control changes, but v4l2_ctrl_query_fill()
+			 * already sets V4L2_CTRL_FLAG_UPDATE for
+			 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+			 */
+			return v4l2_ctrl_query_fill(qctrl,
+					V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+					V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+					default_params.audio_encoding);
+		}
+
 		return v4l2_ctrl_query_fill(qctrl,
 				V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
 				V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
 				default_params.audio_encoding);
 
 	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
+		err = v4l2_ctrl_query_fill(qctrl,
 				V4L2_MPEG_AUDIO_L2_BITRATE_192K,
 				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
 				default_params.audio_l2_bitrate);
+		if (err)
+			return err;
+		if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+		    params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return 0;
 
-	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
-	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
-		return -EINVAL;
+	case V4L2_CID_MPEG_AUDIO_MODE:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_MODE_STEREO,
+				V4L2_MPEG_AUDIO_MODE_MONO, 1,
+				V4L2_MPEG_AUDIO_MODE_STEREO);
 
 	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
-		err = v4l2_ctrl_query_fill_std(qctrl);
+		err = v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
+				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
 		if (err == 0 &&
 		    params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
 			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 		return err;
 
+	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+				V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
+				V4L2_MPEG_AUDIO_EMPHASIS_NONE);
+
+	case V4L2_CID_MPEG_AUDIO_CRC:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_CRC_NONE,
+				V4L2_MPEG_AUDIO_CRC_CRC16, 1,
+				V4L2_MPEG_AUDIO_CRC_NONE);
+
+	case V4L2_CID_MPEG_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		err = v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+				V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+				default_params.audio_ac3_bitrate);
+		if (err)
+			return err;
+		if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+			if (params->audio_encoding !=
+						   V4L2_MPEG_AUDIO_ENCODING_AC3)
+				qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		} else
+			qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+		return 0;
+
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
 		/* this setting is read-only for the cx2341x since the
 		   V4L2_CID_MPEG_STREAM_TYPE really determines the
@@ -516,32 +612,51 @@ int cx2341x_ctrl_query(const struct cx23
 			qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		return err;
 
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_VIDEO_ASPECT_1x1,
+				V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
+				V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
+
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
+				params->is_50hz ? 12 : 15);
+
+	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
+
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		err = v4l2_ctrl_query_fill_std(qctrl);
+		err = v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
 		if (err == 0 &&
 		    params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
 			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 		return err;
 
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
+
 	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		err = v4l2_ctrl_query_fill_std(qctrl);
+		err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
 		if (err == 0 &&
 		    params->video_bitrate_mode ==
 				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
 			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 		return err;
 
-	case V4L2_CID_MPEG_STREAM_VBI_FMT:
-		if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
-			return v4l2_ctrl_query_fill_std(qctrl);
-		return cx2341x_ctrl_query_fill(qctrl,
-				V4L2_MPEG_STREAM_VBI_FMT_NONE,
-				V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
-				default_params.stream_vbi_fmt);
+	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
 
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
-				params->is_50hz ? 12 : 15);
+	case V4L2_CID_MPEG_VIDEO_MUTE:
+		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:  /* Init YUV (really YCbCr) to black */
+		return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
 
 	/* CX23415/6 specific */
 	case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
@@ -643,7 +758,7 @@ int cx2341x_ctrl_query(const struct cx23
 				default_params.stream_insert_nav_packets);
 
 	default:
-		return v4l2_ctrl_query_fill_std(qctrl);
+		return -EINVAL;
 
 	}
 }
@@ -671,6 +786,15 @@ const char **cx2341x_ctrl_get_menu(const
 		NULL
 	};
 
+	static const char *mpeg_audio_encoding_l2_ac3[] = {
+		"",
+		"MPEG-1/2 Layer II",
+		"",
+		"",
+		"AC-3",
+		NULL
+	};
+
 	static const char *cx2341x_video_spatial_filter_mode_menu[] = {
 		"Manual",
 		"Auto",
@@ -711,6 +835,9 @@ const char **cx2341x_ctrl_get_menu(const
 	case V4L2_CID_MPEG_STREAM_TYPE:
 		return (p->capabilities & CX2341X_CAP_HAS_TS) ?
 			mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+			mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
 	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
 	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
 		return NULL;
@@ -730,16 +857,34 @@ const char **cx2341x_ctrl_get_menu(const
 }
 EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
 
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG	0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3	1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM	2
+
 static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
 {
-	params->audio_properties = (params->audio_sampling_freq << 0) |
-		((3 - params->audio_encoding) << 2) |
-		((1 + params->audio_l2_bitrate) << 4) |
+	params->audio_properties =
+		(params->audio_sampling_freq << 0) |
 		(params->audio_mode << 8) |
 		(params->audio_mode_extension << 10) |
 		(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
 		  ? 3 : params->audio_emphasis) << 12) |
 		(params->audio_crc << 14);
+
+	if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+	    params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+		params->audio_properties |=
+			/* Not sure if this MPEG Layer II setting is required */
+			((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+			(params->audio_ac3_bitrate << 4) |
+			(CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+	} else {
+		/* Assuming MPEG Layer II */
+		params->audio_properties |=
+			((3 - params->audio_encoding) << 2) |
+			((1 + params->audio_l2_bitrate) << 4);
+	}
 }
 
 int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
@@ -1022,7 +1167,10 @@ void cx2341x_log_status(const struct cx2
 		prefix,
 		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
 		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
-		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+		cx2341x_menu_item(p,
+			   p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+					      ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+					      : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
 		cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
 		p->audio_mute ? " (muted)" : "");
 	if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cimax2.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cimax2.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cimax2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cimax2.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,472 @@
+/*
+ * cimax2.c
+ *
+ * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 "dvb_ca_en50221.h"
+/**** Bit definitions for MC417_RWD and MC417_OEN registers  ***
+  bits 31-16
++-----------+
+| Reserved  |
++-----------+
+  bit 15  bit 14  bit 13 bit 12  bit 11  bit 10  bit 9   bit 8
++-------+-------+-------+-------+-------+-------+-------+-------+
+|  WR#  |  RD#  |       |  ACK# |  ADHI |  ADLO |  CS1# |  CS0# |
++-------+-------+-------+-------+-------+-------+-------+-------+
+ bit 7   bit 6   bit 5   bit 4   bit 3   bit 2   bit 1   bit 0
++-------+-------+-------+-------+-------+-------+-------+-------+
+|  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
++-------+-------+-------+-------+-------+-------+-------+-------+
+***/
+/* MC417 */
+#define NETUP_DATA		0x000000ff
+#define NETUP_WR		0x00008000
+#define NETUP_RD		0x00004000
+#define NETUP_ACK		0x00001000
+#define NETUP_ADHI		0x00000800
+#define NETUP_ADLO		0x00000400
+#define NETUP_CS1		0x00000200
+#define NETUP_CS0		0x00000100
+#define NETUP_EN_ALL		0x00001000
+#define NETUP_CTRL_OFF		(NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD)
+#define NETUP_CI_CTL		0x04
+#define NETUP_CI_RD		1
+
+
+static unsigned int ci_dbg;
+module_param(ci_dbg, int, 0644);
+MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
+
+#define ci_dbg_print(args...) \
+	do { \
+		if (ci_dbg) \
+			printk(KERN_DEBUG args); \
+	} while (0)
+
+/* stores all private variables for communication with CI */
+struct netup_ci_state {
+	struct dvb_ca_en50221 ca;
+	struct mutex ca_mutex;
+	struct i2c_adapter *i2c_adap;
+	u8 ci_i2c_addr;
+	int status;
+	struct work_struct work;
+	void *priv;
+};
+
+struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
+
+int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+						u8 *buf, int len)
+{
+	int ret;
+	struct i2c_msg msg[] = {
+		{
+			.addr	= addr,
+			.flags	= 0,
+			.buf	= &reg,
+			.len	= 1
+		}, {
+			.addr	= addr,
+			.flags	= I2C_M_RD,
+			.buf	= buf,
+			.len	= len
+		}
+	};
+
+	ret = i2c_transfer(i2c_adap, msg, 2);
+
+	if (ret != 2) {
+		ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n",
+						__func__, reg, ret);
+
+		return -1;
+	}
+
+	ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n",
+						__func__, addr, reg, buf[0]);
+
+	return 0;
+}
+
+int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+						u8 *buf, int len)
+{
+	int ret;
+	u8 buffer[len + 1];
+
+	struct i2c_msg msg = {
+		.addr	= addr,
+		.flags	= 0,
+		.buf	= &buffer[0],
+		.len	= len + 1
+	};
+
+	buffer[0] = reg;
+	memcpy(&buffer[1], buf, len);
+
+	ret = i2c_transfer(i2c_adap, &msg, 1);
+
+	if (ret != 1) {
+		ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n",
+						__func__, reg, ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+int netup_ci_get_mem(struct cx23885_dev *dev)
+{
+	int mem;
+	unsigned long timeout = jiffies + msecs_to_jiffies(1);
+
+	for (;;) {
+		mem = cx_read(MC417_RWD);
+		if ((mem & NETUP_ACK) == 0)
+			break;
+		if (time_after(jiffies, timeout))
+			break;
+		udelay(1);
+	}
+
+	cx_set(MC417_RWD, NETUP_CTRL_OFF);
+
+	return mem & 0xff;
+}
+
+int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
+				u8 flag, u8 read, int addr, u8 data)
+{
+	struct netup_ci_state *state = en50221->data;
+	struct cx23885_tsport *port = state->priv;
+	struct cx23885_dev *dev = port->dev;
+
+	u8 store;
+	int mem;
+	int ret;
+
+	if (0 != slot)
+		return -EINVAL;
+
+	ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &store, 1);
+	if (ret != 0)
+		return ret;
+
+	store &= ~0x0c;
+	store |= flag;
+
+	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &store, 1);
+	if (ret != 0)
+		return ret;
+
+	mutex_lock(&gpio_mutex);
+
+	/* write addr */
+	cx_write(MC417_OEN, NETUP_EN_ALL);
+	cx_write(MC417_RWD, NETUP_CTRL_OFF |
+				NETUP_ADLO | (0xff & addr));
+	cx_clear(MC417_RWD, NETUP_ADLO);
+	cx_write(MC417_RWD, NETUP_CTRL_OFF |
+				NETUP_ADHI | (0xff & (addr >> 8)));
+	cx_clear(MC417_RWD, NETUP_ADHI);
+
+	if (read) /* data in */
+		cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
+	else /* data out */
+		cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
+
+	/* choose chip */
+	cx_clear(MC417_RWD,
+			(state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1);
+	/* read/write */
+	cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
+	mem = netup_ci_get_mem(dev);
+
+	mutex_unlock(&gpio_mutex);
+
+	if (!read)
+		if (mem < 0)
+			return -EREMOTEIO;
+
+	ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
+			(read) ? "read" : "write", addr,
+			(flag == NETUP_CI_CTL) ? "ctl" : "mem",
+			(read) ? mem : data);
+
+	if (read)
+		return mem;
+
+	return 0;
+}
+
+int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+						int slot, int addr)
+{
+	return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+						int slot, int addr, u8 data)
+{
+	return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
+}
+
+int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+{
+	return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
+							NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
+							u8 addr, u8 data)
+{
+	return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data);
+}
+
+int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct netup_ci_state *state = en50221->data;
+	u8 buf =  0x80;
+	int ret;
+
+	if (0 != slot)
+		return -EINVAL;
+
+	udelay(500);
+	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &buf, 1);
+
+	if (ret != 0)
+		return ret;
+
+	udelay(500);
+
+	buf = 0x00;
+	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &buf, 1);
+
+	msleep(1000);
+	dvb_ca_en50221_camready_irq(&state->ca, 0);
+
+	return 0;
+
+}
+
+int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+	/* not implemented */
+	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;
+
+	if (0 != slot)
+		return -EINVAL;
+
+	return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &buf, 1);
+}
+
+/* work handler */
+static void netup_read_ci_status(struct work_struct *work)
+{
+	struct netup_ci_state *state =
+			container_of(work, struct netup_ci_state, work);
+	u8 buf[33];
+	int ret;
+
+	ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+							0, &buf[0], 33);
+
+	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[32]);
+
+	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 */
+int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
+{
+	struct cx23885_tsport *port = NULL;
+	struct netup_ci_state *state = NULL;
+
+	if (pci_status & PCI_MSK_GPIO0)
+		port = &dev->ts1;
+	else if (pci_status & PCI_MSK_GPIO1)
+		port = &dev->ts2;
+	else /* who calls ? */
+		return 0;
+
+	state = port->port_priv;
+
+	schedule_work(&state->work);
+
+	return 1;
+}
+
+int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+{
+	struct netup_ci_state *state = en50221->data;
+
+	if (0 != slot)
+		return -EINVAL;
+
+	return state->status;
+}
+
+int netup_ci_init(struct cx23885_tsport *port)
+{
+	struct netup_ci_state *state;
+	u8 cimax_init[34] = {
+		0x00, /* module A control*/
+		0x00, /* auto select mask high A */
+		0x00, /* auto select mask low A */
+		0x00, /* auto select pattern high A */
+		0x00, /* auto select pattern low A */
+		0x44, /* memory access time A */
+		0x00, /* invert input A */
+		0x00, /* RFU */
+		0x00, /* RFU */
+		0x00, /* module B control*/
+		0x00, /* auto select mask high B */
+		0x00, /* auto select mask low B */
+		0x00, /* auto select pattern high B */
+		0x00, /* auto select pattern low B */
+		0x44, /* memory access time B */
+		0x00, /* invert input B */
+		0x00, /* RFU */
+		0x00, /* RFU */
+		0x00, /* auto select mask high Ext */
+		0x00, /* auto select mask low Ext */
+		0x00, /* auto select pattern high Ext */
+		0x00, /* auto select pattern low Ext */
+		0x00, /* RFU */
+		0x02, /* destination - module A */
+		0x01, /* power on (use it like store place) */
+		0x00, /* RFU */
+		0x00, /* int status read only */
+		0x01, /* all int unmasked */
+		0x04, /* int config */
+		0x00, /* USCG1 */
+		0x04, /* ack active low */
+		0x00, /* LOCK = 0 */
+		0x33, /* serial mode, rising in, rising out, MSB first*/
+		0x31, /* syncronization */
+	};
+	int ret;
+
+	ci_dbg_print("%s\n", __func__);
+	state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL);
+	if (!state) {
+		ci_dbg_print("%s: Unable create CI structure!\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	port->port_priv = state;
+
+	switch (port->nr) {
+	case 1:
+		state->ci_i2c_addr = 0x40;
+		mutex_init(&gpio_mutex);
+		break;
+	case 2:
+		state->ci_i2c_addr = 0x41;
+		break;
+	}
+
+	state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap;
+	state->ca.owner = THIS_MODULE;
+	state->ca.read_attribute_mem = netup_ci_read_attribute_mem;
+	state->ca.write_attribute_mem = netup_ci_write_attribute_mem;
+	state->ca.read_cam_control = netup_ci_read_cam_ctl;
+	state->ca.write_cam_control = netup_ci_write_cam_ctl;
+	state->ca.slot_reset = netup_ci_slot_reset;
+	state->ca.slot_shutdown = netup_ci_slot_shutdown;
+	state->ca.slot_ts_enable = netup_ci_slot_ts_ctl;
+	state->ca.poll_slot_status = netup_poll_ci_slot_status;
+	state->ca.data = state;
+	state->priv = port;
+
+	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+						0, &cimax_init[0], 34);
+	/* lock registers */
+	ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+						0x1f, &cimax_init[0x18], 1);
+	/* power on slots */
+	ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+						0x18, &cimax_init[0x18], 1);
+
+	if (0 != ret)
+		goto err;
+
+	ret = dvb_ca_en50221_init(&port->frontends.adapter,
+				   &state->ca,
+				   /* flags */ 0,
+				   /* n_slots */ 1);
+	if (0 != ret)
+		goto err;
+
+	INIT_WORK(&state->work, netup_read_ci_status);
+
+	ci_dbg_print("%s: CI initialized!\n", __func__);
+
+	return 0;
+err:
+	ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
+	kfree(state);
+	return ret;
+}
+
+void netup_ci_exit(struct cx23885_tsport *port)
+{
+	struct netup_ci_state *state;
+
+	if (NULL == port)
+		return;
+
+	state = (struct netup_ci_state *)port->port_priv;
+	if (NULL == state)
+		return;
+
+	if (NULL == state->ca.data)
+		return;
+
+	dvb_ca_en50221_release(&state->ca);
+	kfree(state);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cimax2.h linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cimax2.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cimax2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cimax2.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * cimax2.h
+ *
+ * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 CIMAX2_H
+#define CIMAX2_H
+#include "dvb_ca_en50221.h"
+
+extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+						int slot, int addr);
+extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+						int slot, int addr, u8 data);
+extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
+						int slot, u8 addr);
+extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
+						int slot, u8 addr, u8 data);
+extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status);
+extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
+						int slot, int open);
+extern int netup_ci_init(struct cx23885_tsport *port);
+extern void netup_ci_exit(struct cx23885_tsport *port);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-417.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-417.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 18:01:57.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-417.c	2013-05-03 16:45:47.000000000 -0400
@@ -896,7 +896,7 @@ static int cx23885_load_firmware(struct
 	if (retval != 0) {
 		printk(KERN_ERR
 			"ERROR: Hotplug firmware request failed (%s).\n",
-			CX2341X_FIRM_ENC_FILENAME);
+			CX23885_FIRM_IMAGE_NAME);
 		printk(KERN_ERR "Please fix your hotplug setup, the board will "
 			"not work without firmware loaded!\n");
 		return -1;
@@ -1198,21 +1198,16 @@ static int vidioc_enum_input(struct file
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 	struct cx23885_input *input;
-	unsigned int n;
-
-	n = i->index;
+	int n;
 
-	if (n >= 4)
+	if (i->index >= 4)
 		return -EINVAL;
 
-	input = &cx23885_boards[dev->board].input[n];
+	input = &cx23885_boards[dev->board].input[i->index];
 
 	if (input->type == 0)
 		return -EINVAL;
 
-	memset(i, 0, sizeof(*i));
-	i->index = n;
-
 	/* FIXME
 	 * strcpy(i->name, input->name); */
 	strcpy(i->name, "unset");
@@ -1255,10 +1250,8 @@ static int vidioc_g_tuner(struct file *f
 		return -EINVAL;
 	if (0 != t->index)
 		return -EINVAL;
-	memset(t, 0, sizeof(*t));
 	strcpy(t->name, "Television");
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+	call_all(dev, tuner, g_tuner, t);
 
 	dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
 
@@ -1275,7 +1268,7 @@ static int vidioc_s_tuner(struct file *f
 		return -EINVAL;
 
 	/* Update the A/V core */
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+	call_all(dev, tuner, s_tuner, t);
 
 	return 0;
 }
@@ -1286,14 +1279,12 @@ static int vidioc_g_frequency(struct fil
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	memset(f, 0, sizeof(*f));
 	if (UNSET == dev->tuner_type)
 		return -EINVAL;
 	f->type = V4L2_TUNER_ANALOG_TV;
 	f->frequency = dev->freq;
 
-	/* Assumption that tuner is always on bus 1 */
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+	call_all(dev, tuner, g_frequency, f);
 
 	return 0;
 }
@@ -1320,8 +1311,7 @@ static int vidioc_s_frequency(struct fil
 		return -EINVAL;
 	dev->freq = f->frequency;
 
-	/* Assumption that tuner is always on bus 1 */
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+	call_all(dev, tuner, s_frequency, f);
 
 	cx23885_initialize_codec(dev);
 
@@ -1335,7 +1325,7 @@ static int vidioc_s_ctrl(struct file *fi
 	struct cx23885_dev *dev = fh->dev;
 
 	/* Update the A/V core */
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+	call_all(dev, core, s_ctrl, ctl);
 	return 0;
 }
 
@@ -1346,7 +1336,6 @@ static int vidioc_querycap(struct file *
 	struct cx23885_dev *dev = fh->dev;
 	struct cx23885_tsport  *tsport = &dev->ts1;
 
-	memset(cap, 0, sizeof(*cap));
 	strcpy(cap->driver, dev->name);
 	strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
 		sizeof(cap->card));
@@ -1366,16 +1355,10 @@ static int vidioc_querycap(struct file *
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *f)
 {
-	int index;
-
-	index = f->index;
-	if (index != 0)
+	if (f->index != 0)
 		return -EINVAL;
 
-	memset(f, 0, sizeof(*f));
-	f->index = index;
 	strlcpy(f->description, "MPEG", sizeof(f->description));
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 
 	return 0;
@@ -1387,8 +1370,6 @@ static int vidioc_g_fmt_vid_cap(struct f
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	memset(f, 0, sizeof(*f));
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
@@ -1408,12 +1389,10 @@ static int vidioc_try_fmt_vid_cap(struct
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
 		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
-	f->fmt.pix.sizeimage    =
 	f->fmt.pix.colorspace   = 0;
 	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
 		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
@@ -1426,7 +1405,6 @@ static int vidioc_s_fmt_vid_cap(struct f
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
@@ -1543,12 +1521,7 @@ static int vidioc_log_status(struct file
 	printk(KERN_INFO
 		"%s/2: ============  START LOG STATUS  ============\n",
 	       dev->name);
-	cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
-		NULL);
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
-		NULL);
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
-		NULL);
+	call_all(dev, core, log_status);
 	cx2341x_log_status(&dev->mpeg_params, name);
 	printk(KERN_INFO
 		"%s/2: =============  END LOG STATUS  =============\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-cards.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include "cx23885.h"
 #include "tuner-xc2028.h"
+#include "netup-init.h"
 
 /* ------------------------------------------------------------------ */
 /* board config info                                                  */
@@ -162,6 +163,24 @@ struct cx23885_board cx23885_boards[] =
 		.name		= "Compro VideoMate E650F",
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_TBS_6920] = {
+		.name		= "TurboSight TBS 6920",
+		.portb		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_TEVII_S470] = {
+		.name		= "TeVii S470",
+		.portb		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_DVBWORLD_2005] = {
+		.name		= "DVBWorld DVB-S2 2005",
+		.portb		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
+		.cimax		= 1,
+		.name		= "NetUP Dual DVB-S2 CI",
+		.portb		= CX23885_MPEG_DVB,
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -245,6 +264,22 @@ struct cx23885_subid cx23885_subids[] =
 		.subvendor = 0x185b,
 		.subdevice = 0xe800,
 		.card      = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
+	}, {
+		.subvendor = 0x6920,
+		.subdevice = 0x8888,
+		.card      = CX23885_BOARD_TBS_6920,
+	}, {
+		.subvendor = 0xd470,
+		.subdevice = 0x9022,
+		.card      = CX23885_BOARD_TEVII_S470,
+	}, {
+		.subvendor = 0x0001,
+		.subdevice = 0x2005,
+		.card      = CX23885_BOARD_DVBWORLD_2005,
+	}, {
+		.subvendor = 0x1b55,
+		.subdevice = 0x2a2c,
+		.card      = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -406,9 +441,9 @@ int cx23885_tuner_callback(void *priv, i
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
 		/* Two identical tuners on two different i2c buses,
 		 * we need to reset the correct gpio. */
-		if (port->nr == 0)
+		if (port->nr == 1)
 			bitmask = 0x01;
-		else if (port->nr == 1)
+		else if (port->nr == 2)
 			bitmask = 0x04;
 		break;
 	}
@@ -552,6 +587,38 @@ void cx23885_gpio_setup(struct cx23885_d
 		mdelay(20);
 		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);
+		break;
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		/* GPIO-0 INTA from CiMax1
+		   GPIO-1 INTB from CiMax2
+		   GPIO-2 reset chips
+		   GPIO-3 to GPIO-10 data/addr for CA
+		   GPIO-11 ~CS0 to CiMax1
+		   GPIO-12 ~CS1 to CiMax2
+		   GPIO-13 ADL0 load LSB addr
+		   GPIO-14 ADL1 load MSB addr
+		   GPIO-15 ~RDY from CiMax
+		   GPIO-17 ~RD to CiMax
+		   GPIO-18 ~WR to CiMax
+		 */
+		cx_set(GP0_IO, 0x00040000); /* GPIO as out */
+		/* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */
+		cx_clear(GP0_IO, 0x00030004);
+		mdelay(100);/* reset delay */
+		cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */
+		cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
+		/* GPIO-15 IN as ~ACK, rest as OUT */
+		cx_write(MC417_OEN, 0x00001000);
+		/* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
+		cx_write(MC417_RWD, 0x0000c300);
+		/* enable irq */
+		cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
+		break;
 	}
 }
 
@@ -632,6 +699,21 @@ 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:
+	case CX23885_BOARD_DVBWORLD_2005:
+		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;
+		break;
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		ts1->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
+		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:
@@ -656,7 +738,18 @@ void cx23885_card_setup(struct cx23885_d
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
-		request_module("cx25840");
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[2].i2c_adap,
+				"cx25840", "cx25840", 0x88 >> 1);
+		v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
+		break;
+	}
+
+	/* AUX-PLL 27MHz CLK */
+	switch (dev->board) {
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		netup_initialize(dev);
 		break;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-core.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
 #include <asm/div64.h>
 
 #include "cx23885.h"
+#include "cimax2.h"
 
 MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -791,6 +792,8 @@ static int cx23885_dev_setup(struct cx23
 	dev->pci_bus  = dev->pci->bus->number;
 	dev->pci_slot = PCI_SLOT(dev->pci->devfn);
 	dev->pci_irqmask = 0x001f00;
+	if (cx23885_boards[dev->board].cimax > 0)
+		dev->pci_irqmask |= 0x01800000; /* for CiMaxes */
 
 	/* External Master 1 Bus */
 	dev->i2c_bus[0].nr = 0;
@@ -872,7 +875,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);
-	cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+	call_all(dev, tuner, s_standby);
 	cx23885_ir_init(dev);
 
 	if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1643,7 +1646,9 @@ static irqreturn_t cx23885_irq(int irq,
 	    (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_AUD_EXT) ||
+	    (pci_status & PCI_MSK_GPIO0) ||
+	    (pci_status & PCI_MSK_GPIO1)) {
 
 		if (pci_status & PCI_MSK_RISC_RD)
 			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n",
@@ -1685,8 +1690,20 @@ static irqreturn_t cx23885_irq(int irq,
 			dprintk(7, " (PCI_MSK_AUD_EXT   0x%08x)\n",
 				PCI_MSK_AUD_EXT);
 
+		if (pci_status & PCI_MSK_GPIO0)
+			dprintk(7, " (PCI_MSK_GPIO0     0x%08x)\n",
+				PCI_MSK_GPIO0);
+
+		if (pci_status & PCI_MSK_GPIO1)
+			dprintk(7, " (PCI_MSK_GPIO1     0x%08x)\n",
+				PCI_MSK_GPIO1);
 	}
 
+	if (cx23885_boards[dev->board].cimax > 0 &&
+		((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
+		/* handled += cx23885_irq_gpio(dev, pci_status); */
+		handled += netup_ci_slot_status(dev, pci_status);
+
 	if (ts1_status) {
 		if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
 			handled += cx23885_irq_ts(ts1, ts1_status);
@@ -1722,16 +1739,20 @@ static int __devinit cx23885_initdev(str
 	if (NULL == dev)
 		return -ENOMEM;
 
+	err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+	if (err < 0)
+		goto fail_free;
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
 		err = -EIO;
-		goto fail_free;
+		goto fail_unreg;
 	}
 
 	if (cx23885_dev_setup(dev) < 0) {
 		err = -EINVAL;
-		goto fail_free;
+		goto fail_unreg;
 	}
 
 	/* print pci info */
@@ -1758,11 +1779,18 @@ static int __devinit cx23885_initdev(str
 		goto fail_irq;
 	}
 
-	pci_set_drvdata(pci_dev, dev);
+	switch (dev->board) {
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		cx_set(PCI_INT_MSK, 0x01800000); /* for NetUP */
+		break;
+	}
+
 	return 0;
 
 fail_irq:
 	cx23885_dev_unregister(dev);
+fail_unreg:
+	v4l2_device_unregister(&dev->v4l2_dev);
 fail_free:
 	kfree(dev);
 	return err;
@@ -1770,7 +1798,8 @@ fail_free:
 
 static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
 {
-	struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct cx23885_dev *dev = to_cx23885(v4l2_dev);
 
 	cx23885_shutdown(dev);
 
@@ -1778,13 +1807,13 @@ static void __devexit cx23885_finidev(st
 
 	/* unregister stuff */
 	free_irq(pci_dev->irq, dev);
-	pci_set_drvdata(pci_dev, NULL);
 
 	mutex_lock(&devlist);
 	list_del(&dev->devlist);
 	mutex_unlock(&devlist);
 
 	cx23885_dev_unregister(dev);
+	v4l2_device_unregister(v4l2_dev);
 	kfree(dev);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-dvb.c	2013-05-03 16:44:18.000000000 -0400
@@ -30,6 +30,7 @@
 #include "cx23885.h"
 #include <media/v4l2-common.h>
 
+#include "dvb_ca_en50221.h"
 #include "s5h1409.h"
 #include "s5h1411.h"
 #include "mt2131.h"
@@ -43,6 +44,13 @@
 #include "dib7000p.h"
 #include "dibx000_common.h"
 #include "zl10353.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "lnbh24.h"
+#include "cx24116.h"
+#include "cimax2.h"
+#include "netup-eeprom.h"
+#include "netup-init.h"
 
 static unsigned int debug;
 
@@ -306,6 +314,58 @@ static struct zl10353_config dvico_fusio
 	.demod_address = 0x0f,
 	.if2           = 45600,
 	.no_tuner      = 1,
+	.disable_i2c_gate_ctrl = 1,
+};
+
+static struct stv0900_config netup_stv0900_config = {
+	.demod_address = 0x68,
+	.xtal = 27000000,
+	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+	.diseqc_mode = 2,/* 2/3 PWM */
+	.path1_mode = 2,/*Serial continues clock */
+	.path2_mode = 2,/*Serial continues clock */
+	.tun1_maddress = 0,/* 0x60 */
+	.tun2_maddress = 3,/* 0x63 */
+	.tun1_adc = 1,/* 1 Vpp */
+	.tun2_adc = 1,/* 1 Vpp */
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_a = {
+	.i2c_address = 0x60,
+	.mclk = 27000000,
+	.iq_wiring = 0,
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_b = {
+	.i2c_address = 0x63,
+	.mclk = 27000000,
+	.iq_wiring = 1,
+};
+
+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,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+	.demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+	.demod_address = 0x05,
 };
 
 static int dvb_register(struct cx23885_tsport *port)
@@ -313,6 +373,7 @@ static int dvb_register(struct cx23885_t
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_i2c *i2c_bus = NULL;
 	struct videobuf_dvb_frontend *fe0;
+	int ret;
 
 	/* Get the first frontend */
 	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
@@ -411,7 +472,7 @@ static int dvb_register(struct cx23885_t
 			static struct xc2028_ctrl ctl = {
 				.fname       = "/*(DEBLOBBED)*/",
 				.max_len     = 64,
-				.scode_table = XC3028_FE_OREN538,
+				.demod       = XC3028_FE_OREN538,
 			};
 
 			fe = dvb_attach(xc2028_attach,
@@ -526,6 +587,78 @@ static int dvb_register(struct cx23885_t
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
 		break;
+	case CX23885_BOARD_TBS_6920:
+		i2c_bus = &dev->i2c_bus[0];
+
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
+			&tbs_cx24116_config,
+			&i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL)
+			fe0->dvb.frontend->ops.set_voltage = tbs_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);
+		if (fe0->dvb.frontend != NULL)
+			fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+		break;
+	case CX23885_BOARD_DVBWORLD_2005:
+		i2c_bus = &dev->i2c_bus[1];
+
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
+			&dvbworld_cx24116_config,
+			&i2c_bus->i2c_adap);
+		break;
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		i2c_bus = &dev->i2c_bus[0];
+		switch (port->nr) {
+		/* port B */
+		case 1:
+			fe0->dvb.frontend = dvb_attach(stv0900_attach,
+							&netup_stv0900_config,
+							&i2c_bus->i2c_adap, 0);
+			if (fe0->dvb.frontend != NULL) {
+				if (dvb_attach(stv6110_attach,
+						fe0->dvb.frontend,
+						&netup_stv6110_tunerconfig_a,
+						&i2c_bus->i2c_adap)) {
+					if (!dvb_attach(lnbh24_attach,
+							fe0->dvb.frontend,
+							&i2c_bus->i2c_adap,
+							LNBH24_PCL, 0, 0x09))
+						printk(KERN_ERR
+							"No LNBH24 found!\n");
+
+				}
+			}
+			break;
+		/* port C */
+		case 2:
+			fe0->dvb.frontend = dvb_attach(stv0900_attach,
+							&netup_stv0900_config,
+							&i2c_bus->i2c_adap, 1);
+			if (fe0->dvb.frontend != NULL) {
+				if (dvb_attach(stv6110_attach,
+						fe0->dvb.frontend,
+						&netup_stv6110_tunerconfig_b,
+						&i2c_bus->i2c_adap)) {
+					if (!dvb_attach(lnbh24_attach,
+							fe0->dvb.frontend,
+							&i2c_bus->i2c_adap,
+							LNBH24_PCL, 0, 0x0a))
+						printk(KERN_ERR
+							"No LNBH24 found!\n");
+
+				}
+			}
+			break;
+		}
+		break;
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
 			" isn't supported yet\n",
@@ -541,15 +674,39 @@ static int dvb_register(struct cx23885_t
 	fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+	call_all(dev, tuner, s_standby);
 
 	if (fe0->dvb.frontend->ops.analog_ops.standby)
 		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
 	/* register everything */
-	return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+	ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
 		&dev->pci->dev, adapter_nr, 0);
 
+	/* init CI & MAC */
+	switch (dev->board) {
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
+		static struct netup_card_info cinfo;
+
+		netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
+		memcpy(port->frontends.adapter.proposed_mac,
+				cinfo.port[port->nr - 1].mac, 6);
+		printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC="
+			"%02X:%02X:%02X:%02X:%02X:%02X\n",
+			port->nr,
+			port->frontends.adapter.proposed_mac[0],
+			port->frontends.adapter.proposed_mac[1],
+			port->frontends.adapter.proposed_mac[2],
+			port->frontends.adapter.proposed_mac[3],
+			port->frontends.adapter.proposed_mac[4],
+			port->frontends.adapter.proposed_mac[5]);
+
+		netup_ci_init(port);
+		break;
+		}
+	}
+
+	return ret;
 }
 
 int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -622,6 +779,12 @@ int cx23885_dvb_unregister(struct cx2388
 	if (fe0->dvb.frontend)
 		videobuf_dvb_unregister_bus(&port->frontends);
 
+	switch (port->dev->board) {
+	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+		netup_ci_exit(port);
+		break;
+	}
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885.h linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/i2c-algo-bit.h>
 #include <linux/kdev_t.h>
 
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
@@ -37,7 +37,7 @@
 #include <linux/version.h>
 #include <linux/mutex.h>
 
-#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1)
+#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 2)
 
 #define UNSET (-1U)
 
@@ -67,6 +67,10 @@
 #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
 #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
 #define CX23885_BOARD_COMPRO_VIDEOMATE_E650F   13
+#define CX23885_BOARD_TBS_6920                 14
+#define CX23885_BOARD_TEVII_S470               15
+#define CX23885_BOARD_DVBWORLD_2005            16
+#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI      17
 
 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
 #define CX23885_NORMS (\
@@ -184,6 +188,7 @@ struct cx23885_board {
 	 */
 	u32			clk_freq;
 	struct cx23885_input    input[MAX_CX23885_INPUT];
+	int			cimax; /* for NetUP */
 };
 
 struct cx23885_subid {
@@ -266,11 +271,13 @@ struct cx23885_tsport {
 
 	/* Allow a single tsport to have multiple frontends */
 	u32                        num_frontends;
+	void                       *port_priv;
 };
 
 struct cx23885_dev {
 	struct list_head           devlist;
 	atomic_t                   refcount;
+	struct v4l2_device 	   v4l2_dev;
 
 	/* pci stuff */
 	struct pci_dev             *pci;
@@ -316,6 +323,7 @@ struct cx23885_dev {
 	unsigned int               radio_type;
 	unsigned char              radio_addr;
 	unsigned int               has_radio;
+	struct v4l2_subdev 	   *sd_cx25840;
 
 	/* V4l */
 	u32                        freq;
@@ -336,6 +344,14 @@ struct cx23885_dev {
 
 };
 
+static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
+}
+
+#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 SRAM_CH01  0 /* Video A */
@@ -452,8 +468,6 @@ extern struct videobuf_queue_ops cx23885
 /* cx23885-i2c.c                                                */
 extern int cx23885_i2c_register(struct cx23885_i2c *bus);
 extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
-				     void *arg);
 extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
 
 /* ----------------------------------------------------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -268,64 +268,6 @@ static int i2c_xfer(struct i2c_adapter *
 	return retval;
 }
 
-static int attach_inform(struct i2c_client *client)
-{
-	struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter);
-	struct cx23885_dev *dev = bus->dev;
-	struct tuner_setup tun_setup;
-
-	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-		client->driver->driver.name, client->addr, client->name);
-
-	if (!client->driver->command)
-		return 0;
-
-	if (dev->tuner_type != UNSET) {
-
-		dprintk(1, "%s  (tuner) i2c attach [addr=0x%x,client=%s]\n",
-			client->driver->driver.name, client->addr,
-			client->name);
-
-		if ((dev->tuner_addr == ADDR_UNSET) ||
-			(dev->tuner_addr == client->addr)) {
-
-			dprintk(1, "%s (tuner || addr UNSET)\n",
-				client->driver->driver.name);
-
-			dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-				client->driver->driver.name,
-				client->addr, client->name);
-
-			tun_setup.mode_mask = T_ANALOG_TV;
-			tun_setup.type = dev->tuner_type;
-			tun_setup.addr = dev->tuner_addr;
-
-			client->driver->command(client, TUNER_SET_TYPE_ADDR,
-				&tun_setup);
-		}
-	}
-
-	return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
-	struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
-
-	dprintk(1, "i2c detach [client=%s]\n", client->name);
-
-	return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
-			      unsigned int cmd, void *arg)
-{
-	if (bus->i2c_rc != 0)
-		return;
-
-	i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
 static u32 cx23885_functionality(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -343,9 +285,6 @@ static struct i2c_adapter cx23885_i2c_ad
 	.owner             = THIS_MODULE,
 	.id                = I2C_HW_B_CX23885,
 	.algo              = &cx23885_i2c_algo_template,
-	.class             = I2C_CLASS_TV_ANALOG,
-	.client_register   = attach_inform,
-	.client_unregister = detach_inform,
 };
 
 static struct i2c_client cx23885_i2c_client_template = {
@@ -402,15 +341,18 @@ int cx23885_i2c_register(struct cx23885_
 
 	bus->i2c_algo.data = bus;
 	bus->i2c_adap.algo_data = bus;
-	i2c_set_adapdata(&bus->i2c_adap, bus);
+	i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
 	i2c_add_adapter(&bus->i2c_adap);
 
 	bus->i2c_client.adapter = &bus->i2c_adap;
 
 	if (0 == bus->i2c_rc) {
 		dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
-		if (i2c_scan)
+		if (i2c_scan) {
+			printk(KERN_INFO "%s: scan bus %d:\n",
+					dev->name, bus->nr);
 			do_i2c_scan(dev->name, &bus->i2c_client);
+		}
 	} else
 		printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
 			dev->name, bus->nr);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-reg.h linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-reg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -212,6 +212,8 @@ 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_APB_DMA   (1 << 12)
 #define PCI_MSK_AL_WR     (1 << 11)
 #define PCI_MSK_AL_RD     (1 << 10)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-video.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/cx23885-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/cx23885-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,11 +35,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
 MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
 MODULE_LICENSE("GPL");
@@ -244,6 +239,7 @@ static struct cx23885_ctrl cx23885_ctls[
 };
 static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
 
+/* Must be sorted from low to high control ID! */
 static const u32 cx23885_user_ctrls[] = {
 	V4L2_CID_USER_CLASS,
 	V4L2_CID_BRIGHTNESS,
@@ -303,11 +299,7 @@ static int cx23885_set_tvnorm(struct cx2
 
 	dev->tvnorm = norm;
 
-	/* Tell the analog tuner/demods */
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
-	/* Tell the internal A/V decoder */
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+	call_all(dev, core, s_std, norm);
 
 	return 0;
 }
@@ -324,8 +316,8 @@ static struct video_device *cx23885_vdev
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template;
-	vfd->minor   = -1;
-	vfd->parent  = &pci->dev;
+	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);
@@ -401,9 +393,6 @@ static void res_free(struct cx23885_dev
 
 static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
 {
-	struct v4l2_routing route;
-	memset(&route, 0, sizeof(route));
-
 	dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
 		__func__,
 		input, INPUT(input)->vmux,
@@ -411,11 +400,9 @@ static int cx23885_video_mux(struct cx23
 		INPUT(input)->gpio2, INPUT(input)->gpio3);
 	dev->input = input;
 
-	route.input = INPUT(input)->vmux;
-
 	/* Tell the internal A/V decoder */
-	cx23885_call_i2c_clients(&dev->i2c_bus[2],
-		VIDIOC_INT_S_VIDEO_ROUTING, &route);
+	v4l2_subdev_call(dev->sd_cx25840, video, s_routing,
+			INPUT(input)->vmux, 0, 0);
 
 	return 0;
 }
@@ -891,7 +878,7 @@ static int cx23885_get_control(struct cx
 	struct v4l2_control *ctl)
 {
 	dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+	call_all(dev, core, g_ctrl, ctl);
 	return 0;
 }
 
@@ -1005,7 +992,7 @@ static int vidioc_s_fmt_vid_cap(struct f
 	fh->vidq.field = f->fmt.pix.field;
 	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
 		fh->width, fh->height, fh->vidq.field);
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+	call_all(dev, video, s_fmt, f);
 	return 0;
 }
 
@@ -1285,7 +1272,7 @@ static int vidioc_g_frequency(struct fil
 	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	f->frequency = dev->freq;
 
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+	call_all(dev, tuner, g_frequency, f);
 
 	return 0;
 }
@@ -1300,7 +1287,7 @@ static int cx23885_set_freq(struct cx238
 	mutex_lock(&dev->lock);
 	dev->freq = f->frequency;
 
-	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+	call_all(dev, tuner, s_frequency, f);
 
 	/* When changing channels it is required to reset TVAUDIO */
 	msleep(10);
@@ -1334,7 +1321,7 @@ static int vidioc_g_register(struct file
 	if (!v4l2_chip_match_host(&reg->match))
 		return -EINVAL;
 
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+	call_all(dev, core, g_register, reg);
 
 	return 0;
 }
@@ -1347,7 +1334,7 @@ static int vidioc_s_register(struct file
 	if (!v4l2_chip_match_host(&reg->match))
 		return -EINVAL;
 
-	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+	call_all(dev, core, s_register, reg);
 
 	return 0;
 }
@@ -1528,6 +1515,28 @@ int cx23885_video_register(struct cx2388
 	/* Don't enable VBI yet */
 	cx_set(PCI_INT_MSK, 1);
 
+	if (TUNER_ABSENT != dev->tuner_type) {
+		struct v4l2_subdev *sd = NULL;
+
+		if (dev->tuner_addr)
+			sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[1].i2c_adap,
+				"tuner", "tuner", dev->tuner_addr);
+		else
+			sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[1].i2c_adap,
+				"tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+		if (sd) {
+			struct tuner_setup tun_setup;
+
+			tun_setup.mode_mask = T_ANALOG_TV;
+			tun_setup.type = dev->tuner_type;
+			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+			v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+		}
+	}
+
 
 	/* register v4l devices */
 	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -15,12 +15,15 @@ config VIDEO_CX23885
 	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
-	select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+	select DVB_STV6110 if !DVB_FE_CUSTOMISE
+	select DVB_STV0900 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
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This is a video4linux driver for Conexant 23885 based
 	  TV cards.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,6 @@
-cx23885-objs	:= cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o
+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
 
 obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-eeprom.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-eeprom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,107 @@
+
+/*
+ * netup-eeprom.c
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 "netup-eeprom.h"
+
+#define EEPROM_I2C_ADDR 0x50
+
+int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr)
+{
+	int ret;
+	unsigned char buf[2];
+
+	/* Read from EEPROM */
+	struct i2c_msg msg[] = {
+		{
+			.addr	= EEPROM_I2C_ADDR,
+			.flags	= 0,
+			.buf	= &buf[0],
+			.len	= 1
+		}, {
+			.addr	= EEPROM_I2C_ADDR,
+			.flags	= I2C_M_RD,
+			.buf	= &buf[1],
+			.len	= 1
+		}
+
+	};
+
+	buf[0] = addr;
+	buf[1] = 0x0;
+
+	ret = i2c_transfer(i2c_adap, msg, 2);
+
+	if (ret != 2) {
+		printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret);
+		return -1;
+	}
+
+	return buf[1];
+};
+
+int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data)
+{
+	int ret;
+	unsigned char bufw[2];
+
+	/* Write into EEPROM */
+	struct i2c_msg msg[] = {
+		{
+			.addr	= EEPROM_I2C_ADDR,
+			.flags	= 0,
+			.buf	= &bufw[0],
+			.len	= 2
+		}
+	};
+
+	bufw[0] = addr;
+	bufw[1] = data;
+
+	ret = i2c_transfer(i2c_adap, msg, 1);
+
+	if (ret != 1) {
+		printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret);
+		return -1;
+	}
+
+	mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */
+	return 0;
+};
+
+void netup_get_card_info(struct i2c_adapter *i2c_adap,
+				struct netup_card_info *cinfo)
+{
+	int i, j;
+
+	cinfo->rev =  netup_eeprom_read(i2c_adap, 13);
+
+	for (i = 0, j = 0; i < 6; i++, j++)
+		cinfo->port[0].mac[j] =  netup_eeprom_read(i2c_adap, i);
+
+	for (i = 6, j = 0; i < 12; i++, j++)
+		cinfo->port[1].mac[j] =  netup_eeprom_read(i2c_adap, i);
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-eeprom.h linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-eeprom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * netup-eeprom.h
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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 NETUP_EEPROM_H
+#define NETUP_EEPROM_H
+
+struct netup_port_info {
+	u8 mac[6];/* card MAC address */
+};
+
+struct netup_card_info {
+	struct netup_port_info port[2];/* ports - 1,2 */
+	u8 rev;/* card revision */
+};
+
+extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr);
+extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data);
+extern void netup_get_card_info(struct i2c_adapter *i2c_adap,
+				struct netup_card_info *cinfo);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-init.c linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-init.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-init.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * netup-init.c
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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"
+
+static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val)
+{
+	int ret;
+	u8 buf[3];
+	struct i2c_msg msg = {
+		.addr	= 0x88 >> 1,
+		.flags	= 0,
+		.buf	= buf,
+		.len	= 3
+	};
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+	buf[2] = val;
+
+	ret = i2c_transfer(i2c, &msg, 1);
+
+	if (ret != 1)
+		printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val)
+{
+	int ret;
+	u8 buf[6];
+	struct i2c_msg msg = {
+		.addr	= 0x88 >> 1,
+		.flags	= 0,
+		.buf	= buf,
+		.len	= 6
+	};
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+	buf[2] = val & 0xff;
+	buf[3] = (val >> 8) & 0xff;
+	buf[4] = (val >> 16) & 0xff;
+	buf[5] = val >> 24;
+
+	ret = i2c_transfer(i2c, &msg, 1);
+
+	if (ret != 1)
+		printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg)
+{
+	int ret;
+	u8 buf[2];
+	struct i2c_msg msg = {
+		.addr	= 0x88 >> 1,
+		.flags	= 0,
+		.buf	= buf,
+		.len	= 2
+	};
+
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
+
+	ret = i2c_transfer(i2c, &msg, 1);
+
+	if (ret != 1)
+		printk(KERN_ERR "%s: i2c write error!\n", __func__);
+
+	msg.flags = I2C_M_RD;
+	msg.len = 1;
+
+	ret = i2c_transfer(i2c, &msg, 1);
+
+	if (ret != 1)
+		printk(KERN_ERR "%s: i2c read error!\n", __func__);
+
+	return buf[0];
+}
+
+static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask,
+								u8 or_value)
+{
+	i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value);
+}
+/* set 27MHz on AUX_CLK */
+void netup_initialize(struct cx23885_dev *dev)
+{
+	struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2];
+	struct i2c_adapter *i2c = &i2c_bus->i2c_adap;
+
+	/* Stop microcontroller */
+	i2c_av_and_or(i2c, 0x803, ~0x10, 0x00);
+
+	/* Aux PLL frac for 27 MHz */
+	i2c_av_write4(i2c, 0x114, 0xea0eb3);
+
+	/* Aux PLL int for 27 MHz */
+	i2c_av_write4(i2c, 0x110, 0x090319);
+
+	/* start microcontroller */
+	i2c_av_and_or(i2c, 0x803, ~0x10, 0x10);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-init.h linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-init.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx23885/netup-init.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx23885/netup-init.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * netup-init.h
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ */
+extern void netup_initialize(struct cx23885_dev *dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-audio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,7 @@ static int set_audclk_freq(struct i2c_cl
 
 	/* common for all inputs and rates */
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
-	if (!state->is_cx23885)
+	if (!state->is_cx23885 && !state->is_cx231xx)
 		cx25840_write(client, 0x127, 0x50);
 
 	if (state->aud_input != CX25840_AUDIO_SERIAL) {
@@ -43,11 +43,14 @@ static int set_audclk_freq(struct i2c_cl
 				 * so avoid destroying registers. */
 				break;
 			}
-			/* VID_PLL and AUX_PLL */
-			cx25840_write4(client, 0x108, 0x1006040f);
 
-			/* AUX_PLL_FRAC */
-			cx25840_write4(client, 0x110, 0x01bb39ee);
+			if (!state->is_cx231xx) {
+				/* VID_PLL and AUX_PLL */
+				cx25840_write4(client, 0x108, 0x1006040f);
+
+				/* AUX_PLL_FRAC */
+				cx25840_write4(client, 0x110, 0x01bb39ee);
+			}
 
 			if (state->is_cx25836)
 				break;
@@ -64,11 +67,14 @@ static int set_audclk_freq(struct i2c_cl
 				 * so avoid destroying registers. */
 				break;
 			}
-			/* VID_PLL and AUX_PLL */
-			cx25840_write4(client, 0x108, 0x1009040f);
 
-			/* AUX_PLL_FRAC */
-			cx25840_write4(client, 0x110, 0x00ec6bd6);
+			if (!state->is_cx231xx) {
+				/* VID_PLL and AUX_PLL */
+				cx25840_write4(client, 0x108, 0x1009040f);
+
+				/* AUX_PLL_FRAC */
+				cx25840_write4(client, 0x110, 0x00ec6bd6);
+			}
 
 			if (state->is_cx25836)
 				break;
@@ -85,11 +91,14 @@ static int set_audclk_freq(struct i2c_cl
 				 * so avoid destroying registers. */
 				break;
 			}
-			/* VID_PLL and AUX_PLL */
-			cx25840_write4(client, 0x108, 0x100a040f);
 
-			/* AUX_PLL_FRAC */
-			cx25840_write4(client, 0x110, 0x0098d6e5);
+			if (!state->is_cx231xx) {
+				/* VID_PLL and AUX_PLL */
+				cx25840_write4(client, 0x108, 0x100a040f);
+
+				/* AUX_PLL_FRAC */
+				cx25840_write4(client, 0x110, 0x0098d6e5);
+			}
 
 			if (state->is_cx25836)
 				break;
@@ -108,11 +117,14 @@ static int set_audclk_freq(struct i2c_cl
 				 * so avoid destroying registers. */
 				break;
 			}
-			/* VID_PLL and AUX_PLL */
-			cx25840_write4(client, 0x108, 0x1e08040f);
 
-			/* AUX_PLL_FRAC */
-			cx25840_write4(client, 0x110, 0x012a0869);
+			if (!state->is_cx231xx) {
+				/* VID_PLL and AUX_PLL */
+				cx25840_write4(client, 0x108, 0x1e08040f);
+
+				/* AUX_PLL_FRAC */
+				cx25840_write4(client, 0x110, 0x012a0869);
+			}
 
 			if (state->is_cx25836)
 				break;
@@ -136,11 +148,14 @@ static int set_audclk_freq(struct i2c_cl
 				break;
 			}
 
-			/* VID_PLL and AUX_PLL */
-			cx25840_write4(client, 0x108, 0x1809040f);
 
-			/* AUX_PLL_FRAC */
-			cx25840_write4(client, 0x110, 0x00ec6bd6);
+			if (!state->is_cx231xx) {
+				/* VID_PLL and AUX_PLL */
+				cx25840_write4(client, 0x108, 0x1809040f);
+
+				/* AUX_PLL_FRAC */
+				cx25840_write4(client, 0x110, 0x00ec6bd6);
+			}
 
 			if (state->is_cx25836)
 				break;
@@ -155,7 +170,7 @@ static int set_audclk_freq(struct i2c_cl
 			break;
 
 		case 48000:
-			if (!state->is_cx23885) {
+			if (!state->is_cx23885 && !state->is_cx231xx) {
 				/* VID_PLL and AUX_PLL */
 				cx25840_write4(client, 0x108, 0x180a040f);
 
@@ -166,7 +181,7 @@ static int set_audclk_freq(struct i2c_cl
 			if (state->is_cx25836)
 				break;
 
-			if (!state->is_cx23885) {
+			if (!state->is_cx23885 && !state->is_cx231xx) {
 				/* src1_ctl */
 				cx25840_write4(client, 0x8f8, 0x08018000);
 
@@ -227,10 +242,9 @@ void cx25840_audio_set_path(struct i2c_c
 	/* deassert soft reset */
 	cx25840_and_or(client, 0x810, ~0x1, 0x00);
 
-	if (state->is_cx23885) {
-		/* Ensure the controller is running when we exit */
+	/* Ensure the controller is running when we exit */
+	if (state->is_cx23885 || state->is_cx231xx)
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
-	}
 }
 
 static int get_volume(struct i2c_client *client)
@@ -363,75 +377,74 @@ static void set_mute(struct i2c_client *
 	}
 }
 
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 {
-	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-	struct v4l2_control *ctrl = arg;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct cx25840_state *state = to_state(sd);
 	int retval;
 
-	switch (cmd) {
-	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		if (!state->is_cx25836)
-			cx25840_and_or(client, 0x810, ~0x1, 1);
-		if (state->aud_input != CX25840_AUDIO_SERIAL) {
-			cx25840_and_or(client, 0x803, ~0x10, 0);
-			cx25840_write(client, 0x8d3, 0x1f);
-		}
-		retval = set_audclk_freq(client, *(u32 *)arg);
-		if (state->aud_input != CX25840_AUDIO_SERIAL) {
-			cx25840_and_or(client, 0x803, ~0x10, 0x10);
-		}
-		if (!state->is_cx25836)
-			cx25840_and_or(client, 0x810, ~0x1, 0);
-		return retval;
+	if (!state->is_cx25836)
+		cx25840_and_or(client, 0x810, ~0x1, 1);
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
+		cx25840_and_or(client, 0x803, ~0x10, 0);
+		cx25840_write(client, 0x8d3, 0x1f);
+	}
+	retval = set_audclk_freq(client, freq);
+	if (state->aud_input != CX25840_AUDIO_SERIAL)
+		cx25840_and_or(client, 0x803, ~0x10, 0x10);
+	if (!state->is_cx25836)
+		cx25840_and_or(client, 0x810, ~0x1, 0);
+	return retval;
+}
 
-	case VIDIOC_G_CTRL:
-		switch (ctrl->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-			ctrl->value = get_volume(client);
-			break;
-		case V4L2_CID_AUDIO_BASS:
-			ctrl->value = get_bass(client);
-			break;
-		case V4L2_CID_AUDIO_TREBLE:
-			ctrl->value = get_treble(client);
-			break;
-		case V4L2_CID_AUDIO_BALANCE:
-			ctrl->value = get_balance(client);
-			break;
-		case V4L2_CID_AUDIO_MUTE:
-			ctrl->value = get_mute(client);
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	case VIDIOC_S_CTRL:
-		switch (ctrl->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-			set_volume(client, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_BASS:
-			set_bass(client, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_TREBLE:
-			set_treble(client, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_BALANCE:
-			set_balance(client, ctrl->value);
-			break;
-		case V4L2_CID_AUDIO_MUTE:
-			set_mute(client, ctrl->value);
-			break;
-		default:
-			return -EINVAL;
-		}
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		ctrl->value = get_volume(client);
+		break;
+	case V4L2_CID_AUDIO_BASS:
+		ctrl->value = get_bass(client);
+		break;
+	case V4L2_CID_AUDIO_TREBLE:
+		ctrl->value = get_treble(client);
+		break;
+	case V4L2_CID_AUDIO_BALANCE:
+		ctrl->value = get_balance(client);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = get_mute(client);
 		break;
-
 	default:
 		return -EINVAL;
 	}
+	return 0;
+}
 
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		set_volume(client, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_BASS:
+		set_bass(client, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_TREBLE:
+		set_treble(client, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_BALANCE:
+		set_balance(client, ctrl->value);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		set_mute(client, ctrl->value);
+		break;
+	default:
+		return -EINVAL;
+	}
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-core.c linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@
 #include <linux/delay.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <media/cx25840.h>
 
 #include "cx25840-core.h"
@@ -48,15 +48,12 @@ MODULE_DESCRIPTION("Conexant CX25840 aud
 MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
 MODULE_LICENSE("GPL");
 
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
 static int cx25840_debug;
 
 module_param_named(debug,cx25840_debug, int, 0644);
 
 MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
 
-I2C_CLIENT_INSMOD;
 
 /* ----------------------------------------------------------------------- */
 
@@ -348,6 +345,77 @@ static void cx23885_initialize(struct i2
 
 /* ----------------------------------------------------------------------- */
 
+static void cx231xx_initialize(struct i2c_client *client)
+{
+	DEFINE_WAIT(wait);
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+	struct workqueue_struct *q;
+
+	/* Internal Reset */
+	cx25840_and_or(client, 0x102, ~0x01, 0x01);
+	cx25840_and_or(client, 0x102, ~0x01, 0x00);
+
+	/* Stop microcontroller */
+	cx25840_and_or(client, 0x803, ~0x10, 0x00);
+
+	/* DIF in reset? */
+	cx25840_write(client, 0x398, 0);
+
+	/* Trust the default xtal, no division */
+	/* This changes for the cx23888 products */
+	cx25840_write(client, 0x2, 0x76);
+
+	/* Bring down the regulator for AUX clk */
+	cx25840_write(client, 0x1, 0x40);
+
+	/* Disable DIF bypass */
+	cx25840_write4(client, 0x33c, 0x00000001);
+
+	/* DIF Src phase inc */
+	cx25840_write4(client, 0x340, 0x0df7df83);
+
+	/* Luma */
+	cx25840_write4(client, 0x414, 0x00107d12);
+
+	/* Chroma */
+	cx25840_write4(client, 0x420, 0x3d008282);
+
+	/* ADC2 input select */
+	cx25840_write(client, 0x102, 0x10);
+
+	/* VIN1 & VIN5 */
+	cx25840_write(client, 0x103, 0x11);
+
+	/* Enable format auto detect */
+	cx25840_write(client, 0x400, 0);
+	/* Fast subchroma lock */
+	/* White crush, Chroma AGC & Chroma Killer enabled */
+	cx25840_write(client, 0x401, 0xe8);
+
+	/* Do the firmware load in a work handler to prevent.
+	   Otherwise the kernel is blocked waiting for the
+	   bit-banging i2c interface to finish uploading the
+	   firmware. */
+	INIT_WORK(&state->fw_work, cx25840_work_handler);
+	init_waitqueue_head(&state->fw_wait);
+	q = create_singlethread_workqueue("cx25840_fw");
+	prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+	queue_work(q, &state->fw_work);
+	schedule();
+	finish_wait(&state->fw_wait, &wait);
+	destroy_workqueue(q);
+
+	cx25840_std_setup(client);
+
+	/* (re)set input */
+	set_input(client, state->vid_input, state->aud_input);
+
+	/* start microcontroller */
+	cx25840_and_or(client, 0x803, ~0x10, 0x10);
+}
+
+/* ----------------------------------------------------------------------- */
+
 void cx25840_std_setup(struct i2c_client *client)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
@@ -417,39 +485,41 @@ void cx25840_std_setup(struct i2c_client
 	}
 
 	/* DEBUG: Displays configured PLL frequency */
-	pll_int = cx25840_read(client, 0x108);
-	pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
-	pll_post = cx25840_read(client, 0x109);
-	v4l_dbg(1, cx25840_debug, client,
-				"PLL regs = int: %u, frac: %u, post: %u\n",
-				pll_int, pll_frac, pll_post);
+	if (!state->is_cx231xx) {
+		pll_int = cx25840_read(client, 0x108);
+		pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
+		pll_post = cx25840_read(client, 0x109);
+		v4l_dbg(1, cx25840_debug, client,
+			"PLL regs = int: %u, frac: %u, post: %u\n",
+			pll_int, pll_frac, pll_post);
 
-	if (pll_post) {
-		int fin, fsc;
-		int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
+		if (pll_post) {
+			int fin, fsc;
+			int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
 
-		pll /= pll_post;
-		v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
-				pll / 1000000, pll % 1000000);
-		v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
-				pll / 8000000, (pll / 8) % 1000000);
+			pll /= pll_post;
+			v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
+					pll / 1000000, pll % 1000000);
+			v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
+					pll / 8000000, (pll / 8) % 1000000);
 
-		fin = ((u64)src_decimation * pll) >> 12;
-		v4l_dbg(1, cx25840_debug, client,
-				"ADC Sampling freq = %d.%06d MHz\n",
-				fin / 1000000, fin % 1000000);
+			fin = ((u64)src_decimation * pll) >> 12;
+			v4l_dbg(1, cx25840_debug, client,
+					"ADC Sampling freq = %d.%06d MHz\n",
+					fin / 1000000, fin % 1000000);
 
-		fsc = (((u64)sc) * pll) >> 24L;
-		v4l_dbg(1, cx25840_debug, client,
-				"Chroma sub-carrier freq = %d.%06d MHz\n",
-				fsc / 1000000, fsc % 1000000);
+			fsc = (((u64)sc) * pll) >> 24L;
+			v4l_dbg(1, cx25840_debug, client,
+					"Chroma sub-carrier freq = %d.%06d MHz\n",
+					fsc / 1000000, fsc % 1000000);
 
-		v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
-			"vblank %i, vactive %i, vblank656 %i, src_dec %i, "
-			"burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
-			"sc 0x%06x\n",
-			hblank, hactive, vblank, vactive, vblank656,
-			src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+			v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
+				"vblank %i, vactive %i, vblank656 %i, src_dec %i, "
+				"burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
+				"sc 0x%06x\n",
+				hblank, hactive, vblank, vactive, vblank656,
+				src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+		}
 	}
 
 	/* Sets horizontal blanking delay and active lines */
@@ -599,7 +669,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) {
+	if (!state->is_cx23885 && !state->is_cx231xx) {
 		switch (aud_input) {
 		case CX25840_AUDIO_SERIAL:
 			/* do nothing, use serial audio input */
@@ -622,7 +692,7 @@ static int set_input(struct i2c_client *
 	/* Set INPUT_MODE to Composite (0) or S-Video (1) */
 	cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
 
-	if (!state->is_cx23885) {
+	if (!state->is_cx23885 && !state->is_cx231xx) {
 		/* 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 */
@@ -662,6 +732,19 @@ static int set_input(struct i2c_client *
 		 */
 		cx25840_write(client, 0x918, 0xa0);
 		cx25840_write(client, 0x919, 0x01);
+	} else if (state->is_cx231xx) {
+		/* Audio channel 1 src : Parallel 1 */
+		cx25840_write(client, 0x124, 0x03);
+
+		/* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */
+		cx25840_write(client, 0x914, 0xa0);
+
+		/* I2S_OUT_CTL:
+		 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1
+		 * I2S_OUT_MASTER_MODE = Master
+		 */
+		cx25840_write(client, 0x918, 0xa0);
+		cx25840_write(client, 0x919, 0x01);
 	}
 
 	return 0;
@@ -763,7 +846,7 @@ static int cx25840_s_ctrl(struct v4l2_su
 		break;
 
 	case V4L2_CID_HUE:
-		if (ctrl->value < -127 || ctrl->value > 127) {
+		if (ctrl->value < -128 || ctrl->value > 127) {
 			v4l_err(client, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
@@ -778,7 +861,7 @@ static int cx25840_s_ctrl(struct v4l2_su
 	case V4L2_CID_AUDIO_MUTE:
 		if (state->is_cx25836)
 			return -EINVAL;
-		return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+		return cx25840_audio_s_ctrl(sd, ctrl);
 
 	default:
 		return -EINVAL;
@@ -815,7 +898,7 @@ static int cx25840_g_ctrl(struct v4l2_su
 	case V4L2_CID_AUDIO_MUTE:
 		if (state->is_cx25836)
 			return -EINVAL;
-		return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+		return cx25840_audio_g_ctrl(sd, ctrl);
 	default:
 		return -EINVAL;
 	}
@@ -827,11 +910,9 @@ static int cx25840_g_ctrl(struct v4l2_su
 
 static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
 	switch (fmt->type) {
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+		return cx25840_vbi_g_fmt(sd, fmt);
 	default:
 		return -EINVAL;
 	}
@@ -893,10 +974,10 @@ static int cx25840_s_fmt(struct v4l2_sub
 		break;
 
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+		return cx25840_vbi_s_fmt(sd, fmt);
 
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+		return cx25840_vbi_s_fmt(sd, fmt);
 
 	default:
 		return -EINVAL;
@@ -1101,18 +1182,30 @@ static void log_audio_status(struct i2c_
 
 /* ----------------------------------------------------------------------- */
 
-static int cx25840_init(struct v4l2_subdev *sd, u32 val)
+/* This load_fw operation must be called to load the driver's firmware.
+   Without this the audio standard detection will fail and you will
+   only get mono.
+
+   Since loading the firmware is often problematic when the driver is
+   compiled into the kernel I recommend postponing calling this function
+   until the first open of the video device. Another reason for
+   postponing it is that loading this firmware takes a long time (seconds)
+   due to the slow i2c bus speed. So it will speed up the boot process if
+   you can avoid loading the fw as long as the video device isn't used.  */
+static int cx25840_load_fw(struct v4l2_subdev *sd)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	if (!state->is_initialized) {
-		/* initialize on first use */
+		/* initialize and load firmware */
 		state->is_initialized = 1;
 		if (state->is_cx25836)
 			cx25836_initialize(client);
 		else if (state->is_cx23885)
 			cx23885_initialize(client);
+		else if (state->is_cx231xx)
+			cx231xx_initialize(client);
 		else
 			cx25840_initialize(client);
 	}
@@ -1146,20 +1239,6 @@ static int cx25840_s_register(struct v4l
 }
 #endif
 
-static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi);
-}
-
-static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
-}
-
 static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct cx25840_state *state = to_state(sd);
@@ -1168,7 +1247,7 @@ 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) {
+		if (state->is_cx23885 || state->is_cx231xx) {
 			u8 v = (cx25840_read(client, 0x421) | 0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
@@ -1178,7 +1257,7 @@ static int cx25840_s_stream(struct v4l2_
 					state->is_cx25836 ? 0x04 : 0x07);
 		}
 	} else {
-		if (state->is_cx23885) {
+		if (state->is_cx23885 || state->is_cx231xx) {
 			u8 v = cx25840_read(client, 0x421) & ~(0x0b);
 			cx25840_write(client, 0x421, v);
 		} else {
@@ -1195,10 +1274,12 @@ static int cx25840_queryctrl(struct v4l2
 
 	switch (qc->id) {
 	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_CONTRAST:
 	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
 	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill_std(qc);
+		return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
 	default:
 		break;
 	}
@@ -1210,10 +1291,11 @@ static int cx25840_queryctrl(struct v4l2
 		return v4l2_ctrl_query_fill(qc, 0, 65535,
 				65535 / 100, state->default_volume);
 	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		return v4l2_ctrl_query_fill_std(qc);
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 	default:
 		return -EINVAL;
 	}
@@ -1240,22 +1322,24 @@ static int cx25840_s_radio(struct v4l2_s
 	return 0;
 }
 
-static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_video_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	return set_input(client, route->input, state->aud_input);
+	return set_input(client, input, state->aud_input);
 }
 
-static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct cx25840_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	if (state->is_cx25836)
 		return -EINVAL;
-	return set_input(client, state->vid_input, route->input);
+	return set_input(client, state->vid_input, input);
 }
 
 static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
@@ -1356,6 +1440,8 @@ static int cx25840_reset(struct v4l2_sub
 		cx25836_initialize(client);
 	else if (state->is_cx23885)
 		cx23885_initialize(client);
+	else if (state->is_cx231xx)
+		cx231xx_initialize(client);
 	else
 		cx25840_initialize(client);
 	return 0;
@@ -1380,19 +1466,6 @@ static int cx25840_log_status(struct v4l
 	return 0;
 }
 
-static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	/* ignore this command */
-	if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
-		return 0;
-
-	/* Old-style drivers rely on initialization on first use, so
-	   call the init whenever a command is issued to this driver.
-	   New-style drivers using v4l2_subdev should call init explicitly. */
-	cx25840_init(i2c_get_clientdata(client), 0);
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops cx25840_core_ops = {
@@ -1401,8 +1474,9 @@ static const struct v4l2_subdev_core_ops
 	.g_ctrl = cx25840_g_ctrl,
 	.s_ctrl = cx25840_s_ctrl,
 	.queryctrl = cx25840_queryctrl,
+	.s_std = cx25840_s_std,
 	.reset = cx25840_reset,
-	.init = cx25840_init,
+	.load_fw = cx25840_load_fw,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx25840_g_register,
 	.s_register = cx25840_s_register,
@@ -1411,7 +1485,6 @@ static const struct v4l2_subdev_core_ops
 
 static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
 	.s_frequency = cx25840_s_frequency,
-	.s_std = cx25840_s_std,
 	.s_radio = cx25840_s_radio,
 	.g_tuner = cx25840_g_tuner,
 	.s_tuner = cx25840_s_tuner,
@@ -1468,6 +1541,8 @@ static int cx25840_probe(struct i2c_clie
 		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
 	} else if (device_id == 0x1313) {
 		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+	} else if ((device_id & 0xfff0) == 0x5A30) {
+		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
 	}
 	else {
 		v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
@@ -1490,6 +1565,7 @@ static int cx25840_probe(struct i2c_clie
 	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;
@@ -1528,8 +1604,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "cx25840",
-	.driverid = I2C_DRIVERID_CX25840,
-	.command = cx25840_command,
 	.probe = cx25840_probe,
 	.remove = cx25840_remove,
 	.id_table = cx25840_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-core.h linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-core.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,7 @@ struct cx25840_state {
 	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 */
@@ -75,11 +76,15 @@ int cx25840_loadfw(struct i2c_client *cl
 
 /* ----------------------------------------------------------------------- */
 /* cx25850-audio.c                                                         */
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
 void cx25840_audio_set_path(struct i2c_client *client);
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
 
 /* ----------------------------------------------------------------------- */
 /* cx25850-vbi.c                                                           */
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-firmware.c linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-firmware.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-firmware.c	2013-05-03 18:01:59.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-firmware.c	2013-05-03 16:45:49.000000000 -0400
@@ -25,6 +25,7 @@
 
 #define FWFILE "/*(DEBLOBBED)*/"
 #define FWFILE_CX23885 "/*(DEBLOBBED)*/"
+#define FWFILE_CX231XX "/*(DEBLOBBED)*/"
 
 /*
  * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
@@ -96,9 +97,17 @@ int cx25840_loadfw(struct i2c_client *cl
 	u8 buffer[FWSEND];
 	const u8 *ptr;
 	int size, retval;
+	int MAX_BUF_SIZE = FWSEND;
 
 	if (state->is_cx23885)
 		firmware = FWFILE_CX23885;
+	else if (state->is_cx231xx)
+		firmware = FWFILE_CX231XX;
+
+	if ((state->is_cx231xx) && 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 */
+	}
 
 	if (reject_firmware(&fw, firmware, FWDEV(client)) != 0) {
 		v4l_err(client, "unable to open firmware %s\n", firmware);
@@ -113,7 +122,7 @@ int cx25840_loadfw(struct i2c_client *cl
 	size = fw->size;
 	ptr = fw->data;
 	while (size > 0) {
-		int len = min(FWSEND - 2, size);
+		int len = min(MAX_BUF_SIZE - 2, size);
 
 		memcpy(buffer + 2, ptr, len);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx25840/cx25840-vbi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx25840/cx25840-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,199 +82,181 @@ static int decode_vps(u8 * dst, u8 * p)
 	return err & 0xf0;
 }
 
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
-	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-	struct v4l2_format *fmt;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct cx25840_state *state = to_state(sd);
 	struct v4l2_sliced_vbi_format *svbi;
+	static const u16 lcr2vbi[] = {
+		0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
+		0, V4L2_SLICED_WSS_625, 0,	/* 4 */
+		V4L2_SLICED_CAPTION_525,	/* 6 */
+		0, 0, V4L2_SLICED_VPS, 0, 0,	/* 9 */
+		0, 0, 0, 0
+	};
+	int is_pal = !(state->std & V4L2_STD_525_60);
+	int i;
 
-	switch (cmd) {
-	case VIDIOC_G_FMT:
-	{
-		static u16 lcr2vbi[] = {
-			0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
-			0, V4L2_SLICED_WSS_625, 0,	/* 4 */
-			V4L2_SLICED_CAPTION_525,	/* 6 */
-			0, 0, V4L2_SLICED_VPS, 0, 0,	/* 9 */
-			0, 0, 0, 0
-		};
-		int is_pal = !(state->std & V4L2_STD_525_60);
-		int i;
-
-		fmt = arg;
-		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
-			return -EINVAL;
-		svbi = &fmt->fmt.sliced;
-		memset(svbi, 0, sizeof(*svbi));
-		/* we're done if raw VBI is active */
-		if ((cx25840_read(client, 0x404) & 0x10) == 0)
-			break;
+	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+		return -EINVAL;
+	svbi = &fmt->fmt.sliced;
+	memset(svbi, 0, sizeof(*svbi));
+	/* we're done if raw VBI is active */
+	if ((cx25840_read(client, 0x404) & 0x10) == 0)
+		return 0;
 
-		if (is_pal) {
-			for (i = 7; i <= 23; i++) {
-				u8 v = cx25840_read(client, 0x424 + i - 7);
+	if (is_pal) {
+		for (i = 7; i <= 23; i++) {
+			u8 v = cx25840_read(client, 0x424 + i - 7);
 
-				svbi->service_lines[0][i] = lcr2vbi[v >> 4];
-				svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
-				svbi->service_set |=
-					svbi->service_lines[0][i] | svbi->service_lines[1][i];
-			}
+			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+			svbi->service_set |= svbi->service_lines[0][i] |
+					     svbi->service_lines[1][i];
 		}
-		else {
-			for (i = 10; i <= 21; i++) {
-				u8 v = cx25840_read(client, 0x424 + i - 10);
+	} else {
+		for (i = 10; i <= 21; i++) {
+			u8 v = cx25840_read(client, 0x424 + i - 10);
 
-				svbi->service_lines[0][i] = lcr2vbi[v >> 4];
-				svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
-				svbi->service_set |=
-					svbi->service_lines[0][i] | svbi->service_lines[1][i];
-			}
+			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+			svbi->service_set |= svbi->service_lines[0][i] |
+					     svbi->service_lines[1][i];
 		}
-		break;
 	}
+	return 0;
+}
 
-	case VIDIOC_S_FMT:
-	{
-		int is_pal = !(state->std & V4L2_STD_525_60);
-		int vbi_offset = is_pal ? 1 : 0;
-		int i, x;
-		u8 lcr[24];
-
-		fmt = arg;
-		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
-		    fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
-			return -EINVAL;
-		svbi = &fmt->fmt.sliced;
-		if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-			/* raw VBI */
-			memset(svbi, 0, sizeof(*svbi));
-
-			/* Setup standard */
-			cx25840_std_setup(client);
-
-			/* VBI Offset */
-			cx25840_write(client, 0x47f, vbi_offset);
-			cx25840_write(client, 0x404, 0x2e);
-			break;
-		}
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct cx25840_state *state = to_state(sd);
+	struct v4l2_sliced_vbi_format *svbi;
+	int is_pal = !(state->std & V4L2_STD_525_60);
+	int vbi_offset = is_pal ? 1 : 0;
+	int i, x;
+	u8 lcr[24];
 
-		for (x = 0; x <= 23; x++)
-			lcr[x] = 0x00;
+	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+			fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+		return -EINVAL;
+	svbi = &fmt->fmt.sliced;
+	if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		/* raw VBI */
+		memset(svbi, 0, sizeof(*svbi));
 
 		/* Setup standard */
 		cx25840_std_setup(client);
 
-		/* Sliced VBI */
-		cx25840_write(client, 0x404, 0x32);	/* Ancillary data */
-		cx25840_write(client, 0x406, 0x13);
+		/* VBI Offset */
 		cx25840_write(client, 0x47f, vbi_offset);
+		cx25840_write(client, 0x404, 0x2e);
+		return 0;
+	}
 
-		if (is_pal) {
-			for (i = 0; i <= 6; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
-		} else {
-			for (i = 0; i <= 9; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
+	for (x = 0; x <= 23; x++)
+		lcr[x] = 0x00;
 
-			for (i = 22; i <= 23; i++)
-				svbi->service_lines[0][i] =
-					svbi->service_lines[1][i] = 0;
-		}
+	/* Setup standard */
+	cx25840_std_setup(client);
 
-		for (i = 7; i <= 23; i++) {
-			for (x = 0; x <= 1; x++) {
-				switch (svbi->service_lines[1-x][i]) {
-				case V4L2_SLICED_TELETEXT_B:
-					lcr[i] |= 1 << (4 * x);
-					break;
-				case V4L2_SLICED_WSS_625:
-					lcr[i] |= 4 << (4 * x);
-					break;
-				case V4L2_SLICED_CAPTION_525:
-					lcr[i] |= 6 << (4 * x);
-					break;
-				case V4L2_SLICED_VPS:
-					lcr[i] |= 9 << (4 * x);
-					break;
-				}
-			}
-		}
+	/* Sliced VBI */
+	cx25840_write(client, 0x404, 0x32);	/* Ancillary data */
+	cx25840_write(client, 0x406, 0x13);
+	cx25840_write(client, 0x47f, vbi_offset);
 
-		if (is_pal) {
-			for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
-				cx25840_write(client, i, lcr[6 + x]);
-			}
-		}
-		else {
-			for (x = 1, i = 0x424; i <= 0x430; i++, x++) {
-				cx25840_write(client, i, lcr[9 + x]);
-			}
-			for (i = 0x431; i <= 0x434; i++) {
-				cx25840_write(client, i, 0);
-			}
-		}
+	if (is_pal) {
+		for (i = 0; i <= 6; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
+	} else {
+		for (i = 0; i <= 9; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
 
-		cx25840_write(client, 0x43c, 0x16);
+		for (i = 22; i <= 23; i++)
+			svbi->service_lines[0][i] =
+				svbi->service_lines[1][i] = 0;
+	}
 
-		if (is_pal) {
-			cx25840_write(client, 0x474, 0x2a);
-		} else {
-			cx25840_write(client, 0x474, 0x22);
+	for (i = 7; i <= 23; i++) {
+		for (x = 0; x <= 1; x++) {
+			switch (svbi->service_lines[1-x][i]) {
+			case V4L2_SLICED_TELETEXT_B:
+				lcr[i] |= 1 << (4 * x);
+				break;
+			case V4L2_SLICED_WSS_625:
+				lcr[i] |= 4 << (4 * x);
+				break;
+			case V4L2_SLICED_CAPTION_525:
+				lcr[i] |= 6 << (4 * x);
+				break;
+			case V4L2_SLICED_VPS:
+				lcr[i] |= 9 << (4 * x);
+				break;
+			}
 		}
-		break;
 	}
 
-	case VIDIOC_INT_DECODE_VBI_LINE:
-	{
-		struct v4l2_decode_vbi_line *vbi = arg;
-		u8 *p = vbi->p;
-		int id1, id2, l, err = 0;
+	if (is_pal) {
+		for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+			cx25840_write(client, i, lcr[6 + x]);
+	} else {
+		for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+			cx25840_write(client, i, lcr[9 + x]);
+		for (i = 0x431; i <= 0x434; i++)
+			cx25840_write(client, i, 0);
+	}
 
-		if (p[0] || p[1] != 0xff || p[2] != 0xff ||
-		    (p[3] != 0x55 && p[3] != 0x91)) {
-			vbi->line = vbi->type = 0;
-			break;
-		}
+	cx25840_write(client, 0x43c, 0x16);
+	cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
+	return 0;
+}
 
-		p += 4;
-		id1 = p[-1];
-		id2 = p[0] & 0xf;
-		l = p[2] & 0x3f;
-		l += state->vbi_line_offset;
-		p += 4;
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
+{
+	struct cx25840_state *state = to_state(sd);
+	u8 *p = vbi->p;
+	int id1, id2, l, err = 0;
 
-		switch (id2) {
-		case 1:
-			id2 = V4L2_SLICED_TELETEXT_B;
-			break;
-		case 4:
-			id2 = V4L2_SLICED_WSS_625;
-			break;
-		case 6:
-			id2 = V4L2_SLICED_CAPTION_525;
-			err = !odd_parity(p[0]) || !odd_parity(p[1]);
-			break;
-		case 9:
-			id2 = V4L2_SLICED_VPS;
-			if (decode_vps(p, p) != 0) {
-				err = 1;
-			}
-			break;
-		default:
-			id2 = 0;
-			err = 1;
-			break;
-		}
+	if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+			(p[3] != 0x55 && p[3] != 0x91)) {
+		vbi->line = vbi->type = 0;
+		return 0;
+	}
 
-		vbi->type = err ? 0 : id2;
-		vbi->line = err ? 0 : l;
-		vbi->is_second_field = err ? 0 : (id1 == 0x55);
-		vbi->p = p;
+	p += 4;
+	id1 = p[-1];
+	id2 = p[0] & 0xf;
+	l = p[2] & 0x3f;
+	l += state->vbi_line_offset;
+	p += 4;
+
+	switch (id2) {
+	case 1:
+		id2 = V4L2_SLICED_TELETEXT_B;
+		break;
+	case 4:
+		id2 = V4L2_SLICED_WSS_625;
+		break;
+	case 6:
+		id2 = V4L2_SLICED_CAPTION_525;
+		err = !odd_parity(p[0]) || !odd_parity(p[1]);
+		break;
+	case 9:
+		id2 = V4L2_SLICED_VPS;
+		if (decode_vps(p, p) != 0)
+			err = 1;
+		break;
+	default:
+		id2 = 0;
+		err = 1;
 		break;
-	}
 	}
 
+	vbi->type = err ? 0 : id2;
+	vbi->line = err ? 0 : l;
+	vbi->is_second_field = err ? 0 : (id1 == 0x55);
+	vbi->p = p;
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-alsa.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-alsa.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-alsa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-alsa.c	2009-06-09 23:05:27.000000000 -0400
@@ -745,7 +745,7 @@ static int __devinit snd_cx88_create(str
 		return err;
 	}
 
-	if (!pci_dma_supported(pci,DMA_32BIT_MASK)) {
+	if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
 		dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
 		err = -EIO;
 		cx88_core_put(core,pci);
@@ -803,9 +803,10 @@ static int __devinit cx88_audio_initdev(
 		return (-ENOENT);
 	}
 
-	card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
-	if (!card)
-		return (-ENOMEM);
+	err = snd_card_create(index[devno], id[devno], THIS_MODULE,
+			      sizeof(snd_cx88_card_t), &card);
+	if (err < 0)
+		return err;
 
 	card->private_free = snd_cx88_dev_free;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-blackbird.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-blackbird.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 18:01:59.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-blackbird.c	2013-05-03 16:45:49.000000000 -0400
@@ -746,7 +746,6 @@ static int vidioc_enum_fmt_vid_cap (stru
 		return -EINVAL;
 
 	strlcpy(f->description, "MPEG", sizeof(f->description));
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 	return 0;
 }
@@ -757,7 +756,6 @@ static int vidioc_g_fmt_vid_cap (struct
 	struct cx8802_fh  *fh   = priv;
 	struct cx8802_dev *dev  = fh->dev;
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
@@ -776,7 +774,6 @@ static int vidioc_try_fmt_vid_cap (struc
 	struct cx8802_fh  *fh   = priv;
 	struct cx8802_dev *dev  = fh->dev;
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -793,7 +790,6 @@ static int vidioc_s_fmt_vid_cap (struct
 	struct cx8802_dev *dev  = fh->dev;
 	struct cx88_core  *core = dev->core;
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -919,7 +915,7 @@ static int vidioc_log_status (struct fil
 	snprintf(name, sizeof(name), "%s/2", core->name);
 	printk("%s/2: ============  START LOG STATUS  ============\n",
 		core->name);
-	cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
+	call_all(core, core, log_status);
 	cx2341x_log_status(&dev->params, name);
 	printk("%s/2: =============  END LOG STATUS  =============\n",
 		core->name);
@@ -974,7 +970,7 @@ static int vidioc_g_frequency (struct fi
 
 	f->type = V4L2_TUNER_ANALOG_TV;
 	f->frequency = core->freq;
-	cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+	call_all(core, tuner, g_frequency, f);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-cards.c	2013-05-03 16:44:18.000000000 -0400
@@ -732,6 +732,8 @@ static const struct cx88_board cx88_boar
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		/* Some variants use a tda9874 and so need the tvaudio module. */
+		.audio_chip     = V4L2_IDENT_TVAUDIO,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -1934,6 +1936,39 @@ static const struct cx88_board cx88_boar
 		} },
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	[CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = {
+		.name           = "Terratec Cinergy HT PCI MKII",
+		.tuner_type     = TUNER_XC2028,
+		.tuner_addr     = 0x61,
+		.radio_type     = TUNER_XC2028,
+		.radio_addr     = 0x61,
+		.input          = { {
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0x004ff,
+			.gpio1  = 0x010ff,
+			.gpio2  = 0x00001,
+		}, {
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x004fb,
+			.gpio1  = 0x010ef,
+			.audioroute = 1,
+		}, {
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x004fb,
+			.gpio1  = 0x010ef,
+			.audioroute = 1,
+		} },
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0  = 0x004ff,
+			.gpio1  = 0x010ff,
+			.gpio2  = 0x0ff,
+		},
+		.mpeg           = CX88_MPEG_DVB,
+	},
 };
 
 /* ------------------------------------------------------------------ */
@@ -2343,6 +2378,10 @@ static const struct cx88_subid cx88_subi
 		.subvendor = 0xb200,
 		.subdevice = 0x4200,
 		.card      = CX88_BOARD_SATTRADE_ST4200,
+	}, {
+		.subvendor = 0x153b,
+		.subdevice = 0x1177,
+		.card      = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
 	},
 };
 
@@ -2819,6 +2858,7 @@ void cx88_setup_xc3028(struct cx88_core
 		 */
 		break;
 	case CX88_BOARD_PINNACLE_HYBRID_PCTV:
+	case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
 		ctl->demod = XC3028_FE_ZARLINK456;
 		ctl->mts = 1;
 		break;
@@ -2947,7 +2987,7 @@ static void cx88_card_setup(struct cx88_
 		tea5767_cfg.tuner = TUNER_TEA5767;
 		tea5767_cfg.priv  = &ctl;
 
-		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
+		call_all(core, tuner, s_config, &tea5767_cfg);
 		break;
 	}
 	case  CX88_BOARD_TEVII_S420:
@@ -2972,7 +3012,7 @@ static void cx88_card_setup(struct cx88_
 		tun_setup.type           = core->board.radio_type;
 		tun_setup.addr           = core->board.radio_addr;
 		tun_setup.tuner_callback = cx88_tuner_callback;
-		cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+		call_all(core, tuner, s_type_addr, &tun_setup);
 		mode_mask &= ~T_RADIO;
 	}
 
@@ -2982,7 +3022,7 @@ static void cx88_card_setup(struct cx88_
 		tun_setup.addr           = core->board.tuner_addr;
 		tun_setup.tuner_callback = cx88_tuner_callback;
 
-		cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+		call_all(core, tuner, s_type_addr, &tun_setup);
 	}
 
 	if (core->board.tda9887_conf) {
@@ -2991,7 +3031,7 @@ static void cx88_card_setup(struct cx88_
 		tda9887_cfg.tuner = TUNER_TDA9887;
 		tda9887_cfg.priv  = &core->board.tda9887_conf;
 
-		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
+		call_all(core, tuner, s_config, &tda9887_cfg);
 	}
 
 	if (core->board.tuner_type == TUNER_XC2028) {
@@ -3007,9 +3047,9 @@ static void cx88_card_setup(struct cx88_
 		xc2028_cfg.priv  = &ctl;
 		info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
 			    ctl.fname);
-		cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
+		call_all(core, tuner, s_config, &xc2028_cfg);
 	}
-	cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
+	call_all(core, tuner, s_standby);
 }
 
 /* ------------------------------------------------------------------ */
@@ -3089,6 +3129,8 @@ struct cx88_core *cx88_core_create(struc
 	int i;
 
 	core = kzalloc(sizeof(*core), GFP_KERNEL);
+	if (core == NULL)
+		return NULL;
 
 	atomic_inc(&core->refcount);
 	core->pci_bus  = pci->bus->number;
@@ -3100,7 +3142,15 @@ struct cx88_core *cx88_core_create(struc
 
 	core->nr = nr;
 	sprintf(core->name, "cx88[%d]", core->nr);
+
+	strcpy(core->v4l2_dev.name, core->name);
+	if (v4l2_device_register(NULL, &core->v4l2_dev)) {
+		kfree(core);
+		return NULL;
+	}
+
 	if (0 != cx88_get_resources(core, pci)) {
+		v4l2_device_unregister(&core->v4l2_dev);
 		kfree(core);
 		return NULL;
 	}
@@ -3111,6 +3161,11 @@ struct cx88_core *cx88_core_create(struc
 			      pci_resource_len(pci, 0));
 	core->bmmio = (u8 __iomem *)core->lmmio;
 
+	if (core->lmmio == NULL) {
+		kfree(core);
+		return NULL;
+	}
+
 	/* board config */
 	core->boardnr = UNSET;
 	if (card[core->nr] < ARRAY_SIZE(cx88_boards))
@@ -3149,8 +3204,39 @@ struct cx88_core *cx88_core_create(struc
 	cx88_i2c_init(core, pci);
 
 	/* load tuner module, if needed */
-	if (TUNER_ABSENT != core->board.tuner_type)
-		request_module("tuner");
+	if (TUNER_ABSENT != core->board.tuner_type) {
+		/* Ignore 0x6b and 0x6f on cx88 boards.
+		 * FusionHDTV5 RT Gold has an ir receiver at 0x6b
+		 * and an RTC at 0x6f which can get corrupted if probed. */
+		static const unsigned short tv_addrs[] = {
+			0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
+			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+			0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
+			I2C_CLIENT_END
+		};
+		int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
+
+		/* I don't trust the radio_type as is stored in the card
+		   definitions, so we just probe for it.
+		   The radio_type is sometimes missing, or set to UNSET but
+		   later code configures a tea5767.
+		 */
+		v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap,
+				"tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+		if (has_demod)
+			v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+				&core->i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		if (core->board.tuner_addr == ADDR_UNSET) {
+			v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+				&core->i2c_adap, "tuner", "tuner",
+				has_demod ? tv_addrs + 4 : tv_addrs);
+		} else {
+			v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+				"tuner", "tuner", core->board.tuner_addr);
+		}
+	}
 
 	cx88_card_setup(core);
 	cx88_ir_init(core, pci);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-core.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -991,7 +991,7 @@ int cx88_set_tvnorm(struct cx88_core *co
 	set_tvaudio(core);
 
 	// tell i2c chips
-	cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm);
+	call_all(core, core, s_std, norm);
 
 	// done
 	return 0;
@@ -1011,7 +1011,8 @@ struct video_device *cx88_vdev_init(stru
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev = &core->v4l2_dev;
+	vfd->parent = &pci->dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 core->name, type, core->board.name);
@@ -1058,12 +1059,16 @@ void cx88_core_put(struct cx88_core *cor
 
 	mutex_lock(&devlist);
 	cx88_ir_fini(core);
-	if (0 == core->i2c_rc)
+	if (0 == core->i2c_rc) {
+		if (core->i2c_rtc)
+			i2c_unregister_device(core->i2c_rtc);
 		i2c_del_adapter(&core->i2c_adap);
+	}
 	list_del(&core->devlist);
 	iounmap(core->lmmio);
 	cx88_devcount--;
 	mutex_unlock(&devlist);
+	v4l2_device_unregister(&core->v4l2_dev);
 	kfree(core);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-dvb.c	2013-05-03 16:44:18.000000000 -0400
@@ -241,6 +241,12 @@ static struct mt352_config dvico_fusionh
 	.demod_init    = dvico_dual_demod_init,
 };
 
+static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
+	.demod_address = (0x1e >> 1),
+	.no_tuner      = 1,
+	.if2           = 45600,
+};
+
 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
 {
@@ -1131,6 +1137,16 @@ static int dvb_register(struct cx8802_de
 		if (fe0->dvb.frontend != NULL)
 			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
 		break;
+	case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
+					       &cx88_terratec_cinergy_ht_pci_mkii_config,
+					       &core->i2c_adap);
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+			if (attach_xc3028(0x61, dev) < 0)
+				goto frontend_detach;
+		}
+		break;
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       core->name);
@@ -1152,7 +1168,7 @@ 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 */
-	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
+	call_all(core, tuner, s_standby);
 
 	/* register everything */
 	return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88.h linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
 #include <linux/videodev2.h>
 #include <linux/kdev_t.h>
 
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
@@ -41,7 +41,7 @@
 
 #include <linux/version.h>
 #include <linux/mutex.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,6)
+#define CX88_VERSION_CODE KERNEL_VERSION(0,0,7)
 
 #define UNSET (-1U)
 
@@ -231,6 +231,7 @@ extern struct sram_channel cx88_sram_cha
 #define CX88_BOARD_SATTRADE_ST4200         76
 #define CX88_BOARD_TBS_8910                77
 #define CX88_BOARD_PROF_6200               78
+#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
@@ -302,7 +303,6 @@ struct cx88_dmaqueue {
 	struct btcx_riscmem    stopper;
 	u32                    count;
 };
-struct cx88_core;
 
 struct cx88_core {
 	struct list_head           devlist;
@@ -327,6 +327,8 @@ struct cx88_core {
 	u32                        i2c_state, i2c_rc;
 
 	/* config info -- analog */
+	struct v4l2_device 	   v4l2_dev;
+	struct i2c_client 	   *i2c_rtc;
 	unsigned int               boardnr;
 	struct cx88_board	   board;
 
@@ -365,6 +367,22 @@ struct cx88_core {
 	int			   active_fe_id;
 };
 
+static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
+}
+
+#define call_all(core, o, f, args...) 				\
+	do {							\
+		if (!core->i2c_rc) {				\
+			if (core->gate_ctrl)			\
+				core->gate_ctrl(core, 1);	\
+			v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
+			if (core->gate_ctrl)			\
+				core->gate_ctrl(core, 0);	\
+		}						\
+	} while (0)
+
 struct cx8800_dev;
 struct cx8802_dev;
 
@@ -610,8 +628,6 @@ extern struct videobuf_queue_ops cx8800_
 /* cx88-i2c.c                                                  */
 
 extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-extern void cx88_call_i2c_clients(struct cx88_core *core,
-				  unsigned int cmd, void *arg);
 
 
 /* ----------------------------------------------------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -97,37 +97,6 @@ static int cx8800_bit_getsda(void *data)
 
 /* ----------------------------------------------------------------------- */
 
-static int attach_inform(struct i2c_client *client)
-{
-	struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
-	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-		client->driver->driver.name, client->addr, client->name);
-	return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
-	struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
-	dprintk(1, "i2c detach [client=%s]\n", client->name);
-	return 0;
-}
-
-void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
-{
-	if (0 != core->i2c_rc)
-		return;
-
-	if (core->gate_ctrl)
-		core->gate_ctrl(core, 1);
-
-	i2c_clients_command(&core->i2c_adap, cmd, arg);
-
-	if (core->gate_ctrl)
-		core->gate_ctrl(core, 0);
-}
-
 static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
 	.setsda  = cx8800_bit_setsda,
 	.setscl  = cx8800_bit_setscl,
@@ -173,20 +142,14 @@ int cx88_i2c_init(struct cx88_core *core
 	memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
 	       sizeof(core->i2c_algo));
 
-	if (core->board.tuner_type != TUNER_ABSENT)
-		core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
-	if (core->board.mpeg & CX88_MPEG_DVB)
-		core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
 
 	core->i2c_adap.dev.parent = &pci->dev;
 	strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
 	core->i2c_adap.owner = THIS_MODULE;
 	core->i2c_adap.id = I2C_HW_B_CX2388x;
-	core->i2c_adap.client_register = attach_inform;
-	core->i2c_adap.client_unregister = detach_inform;
 	core->i2c_algo.udelay = i2c_udelay;
 	core->i2c_algo.data = core;
-	i2c_set_adapdata(&core->i2c_adap,core);
+	i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
 	core->i2c_adap.algo_data = &core->i2c_algo;
 	core->i2c_client.adapter = &core->i2c_adap;
 	strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
@@ -222,8 +185,6 @@ int cx88_i2c_init(struct cx88_core *core
 
 /* ----------------------------------------------------------------------- */
 
-EXPORT_SYMBOL(cx88_call_i2c_clients);
-
 /*
  * Local variables:
  * c-basic-offset: 8
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-input.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-input.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-input.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-input.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,8 +48,7 @@ struct cx88_IR {
 
 	/* poll external decoder */
 	int polling;
-	struct work_struct work;
-	struct timer_list timer;
+	struct delayed_work work;
 	u32 gpio_addr;
 	u32 last_gpio;
 	u32 mask_keycode;
@@ -143,27 +142,19 @@ static void cx88_ir_handle_key(struct cx
 	}
 }
 
-static void ir_timer(unsigned long data)
-{
-	struct cx88_IR *ir = (struct cx88_IR *)data;
-
-	schedule_work(&ir->work);
-}
-
 static void cx88_ir_work(struct work_struct *work)
 {
-	struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
+	struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work);
 
 	cx88_ir_handle_key(ir);
-	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 }
 
 void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
 {
 	if (ir->polling) {
-		setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
-		INIT_WORK(&ir->work, cx88_ir_work);
-		schedule_work(&ir->work);
+		INIT_DELAYED_WORK(&ir->work, cx88_ir_work);
+		schedule_delayed_work(&ir->work, 0);
 	}
 	if (ir->sampling) {
 		core->pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -179,10 +170,8 @@ void cx88_ir_stop(struct cx88_core *core
 		core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
 	}
 
-	if (ir->polling) {
-		del_timer_sync(&ir->timer);
-		flush_scheduled_work();
-	}
+	if (ir->polling)
+		cancel_delayed_work_sync(&ir->work);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -226,6 +215,8 @@ int cx88_ir_init(struct cx88_core *core,
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+	case CX88_BOARD_PCHDTV_HD3000:
+	case CX88_BOARD_PCHDTV_HD5500:
 		ir_codes = ir_codes_hauppauge_new;
 		ir_type = IR_TYPE_RC5;
 		ir->sampling = 1;
@@ -466,6 +457,8 @@ void cx88_ir_irq(struct cx88_core *core)
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+	case CX88_BOARD_PCHDTV_HD3000:
+	case CX88_BOARD_PCHDTV_HD5500:
 		ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-mpeg.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-mpeg.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-mpeg.c	2009-06-09 23:05:27.000000000 -0400
@@ -455,7 +455,7 @@ static int cx8802_init_common(struct cx8
 	if (pci_enable_device(dev->pci))
 		return -EIO;
 	pci_set_master(dev->pci);
-	if (!pci_dma_supported(dev->pci,DMA_32BIT_MASK)) {
+	if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) {
 		printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
 		return -EIO;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-video.c linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/cx88-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/cx88-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,11 +41,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_LICENSE("GPL");
@@ -298,6 +293,7 @@ static struct cx88_ctrl cx8800_ctls[] =
 };
 static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
 
+/* Must be sorted from low to high control ID! */
 const u32 cx88_user_ctrls[] = {
 	V4L2_CID_USER_CLASS,
 	V4L2_CID_BRIGHTNESS,
@@ -432,11 +428,8 @@ int cx88_video_mux(struct cx88_core *cor
 		   routes for different inputs. HVR-1300 surely does */
 		if (core->board.audio_chip &&
 		    core->board.audio_chip == V4L2_IDENT_WM8775) {
-			struct v4l2_routing route;
-
-			route.input = INPUT(input).audioroute;
-			cx88_call_i2c_clients(core,
-				VIDIOC_INT_S_AUDIO_ROUTING, &route);
+			call_all(core, audio, s_routing,
+					INPUT(input).audioroute, 0, 0);
 		}
 		/* cx2388's C-ADC is connected to the tuner only.
 		   When used with S-Video, that ADC is busy dealing with
@@ -828,11 +821,8 @@ static int video_open(struct file *file)
 		if (core->board.radio.audioroute) {
 			if(core->board.audio_chip &&
 				core->board.audio_chip == V4L2_IDENT_WM8775) {
-				struct v4l2_routing route;
-
-				route.input = core->board.radio.audioroute;
-				cx88_call_i2c_clients(core,
-					VIDIOC_INT_S_AUDIO_ROUTING, &route);
+				call_all(core, audio, s_routing,
+					core->board.radio.audioroute, 0, 0);
 			}
 			/* "I2S ADC mode" */
 			core->tvaudio = WW_I2SADC;
@@ -843,7 +833,7 @@ static int video_open(struct file *file)
 			cx88_set_tvaudio(core);
 			cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
 		}
-		cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
+		call_all(core, tuner, s_radio);
 	}
 	unlock_kernel();
 
@@ -937,7 +927,7 @@ static int video_release(struct file *fi
 	kfree(fh);
 
 	if(atomic_dec_and_test(&dev->core->users))
-		cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+		call_all(dev->core, tuner, s_standby);
 
 	return 0;
 }
@@ -1276,15 +1266,12 @@ int cx88_enum_input (struct cx88_core  *
 		[ CX88_VMUX_DVB        ] = "DVB",
 		[ CX88_VMUX_DEBUG      ] = "for debug only",
 	};
-	unsigned int n;
+	unsigned int n = i->index;
 
-	n = i->index;
 	if (n >= 4)
 		return -EINVAL;
 	if (0 == INPUT(n).type)
 		return -EINVAL;
-	memset(i,0,sizeof(*i));
-	i->index = n;
 	i->type  = V4L2_INPUT_TYPE_CAMERA;
 	strcpy(i->name,iname[INPUT(n).type]);
 	if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
@@ -1402,7 +1389,7 @@ static int vidioc_g_frequency (struct fi
 	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	f->frequency = core->freq;
 
-	cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+	call_all(core, tuner, g_frequency, f);
 
 	return 0;
 }
@@ -1418,7 +1405,7 @@ int cx88_set_freq (struct cx88_core  *co
 	mutex_lock(&core->lock);
 	core->freq = f->frequency;
 	cx88_newstation(core);
-	cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
+	call_all(core, tuner, s_frequency, f);
 
 	/* When changing channels it is required to reset TVAUDIO */
 	msleep (10);
@@ -1500,7 +1487,7 @@ static int radio_g_tuner (struct file *f
 	strcpy(t->name, "Radio");
 	t->type = V4L2_TUNER_RADIO;
 
-	cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
+	call_all(core, tuner, g_tuner, t);
 	return 0;
 }
 
@@ -1520,7 +1507,6 @@ static int radio_g_audio (struct file *f
 	if (unlikely(a->index))
 		return -EINVAL;
 
-	memset(a,0,sizeof(*a));
 	strcpy(a->name,"Radio");
 	return 0;
 }
@@ -1535,7 +1521,7 @@ static int radio_s_tuner (struct file *f
 	if (0 != t->index)
 		return -EINVAL;
 
-	cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
+	call_all(core, tuner, s_tuner, t);
 
 	return 0;
 }
@@ -1846,7 +1832,7 @@ static int __devinit cx8800_initdev(stru
 	       dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
 
 	pci_set_master(pci_dev);
-	if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) {
+	if (!pci_dma_supported(pci_dev,DMA_BIT_MASK(32))) {
 		printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
 		err = -EIO;
 		goto fail_core;
@@ -1892,12 +1878,27 @@ static int __devinit cx8800_initdev(stru
 	/* load and configure helper modules */
 
 	if (core->board.audio_chip == V4L2_IDENT_WM8775)
-		request_module("wm8775");
+		v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+				"wm8775", "wm8775", 0x36 >> 1);
+
+	if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+		/* This probes for a tda9874 as is used on some
+		   Pixelview Ultra boards. */
+		v4l2_i2c_new_probed_subdev_addr(&core->v4l2_dev,
+				&core->i2c_adap,
+				"tvaudio", "tvaudio", 0xb0 >> 1);
+	}
 
 	switch (core->boardnr) {
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
-	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
+	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
+		static struct i2c_board_info rtc_info = {
+			I2C_BOARD_INFO("isl1208", 0x6f)
+		};
+
 		request_module("rtc-isl1208");
+		core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
+	}
 		/* break intentionally omitted */
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		request_module("ir-kbd-i2c");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/cx88/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/cx88/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/cx88/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/cx88/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,7 @@ 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 MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This adds support for DVB/ATSC cards based on the
 	  Conexant 2388x chip.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/dabusb.c linux-libre-2.6.30-gnu1/drivers/media/video/dabusb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/dabusb.c	2013-05-03 18:02:18.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/dabusb.c	2013-05-03 16:46:09.000000000 -0400
@@ -189,17 +189,20 @@ static void dabusb_iso_complete (struct
 					dst += len;
 				}
 				else
-					err("dabusb_iso_complete: invalid len %d", len);
+					dev_err(&purb->dev->dev,
+						"dabusb_iso_complete: invalid len %d\n", len);
 			}
 			else
 				dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
 		if (dst != purb->actual_length)
-			err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
+			dev_err(&purb->dev->dev,
+				"dst!=purb->actual_length:%d!=%d\n",
+					dst, purb->actual_length);
 	}
 
 	if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
 		s->overruns++;
-		err("overrun (%d)", s->overruns);
+		dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
 	}
 	wake_up (&s->wait);
 }
@@ -220,13 +223,14 @@ static int dabusb_alloc_buffers (pdabusb
 	while (transfer_len < (s->total_buffer_size << 10)) {
 		b = kzalloc(sizeof (buff_t), GFP_KERNEL);
 		if (!b) {
-			err("kzalloc(sizeof(buff_t))==NULL");
+			dev_err(&s->usbdev->dev,
+				"kzalloc(sizeof(buff_t))==NULL\n");
 			goto err;
 		}
 		b->s = s;
 		b->purb = usb_alloc_urb(packets, GFP_KERNEL);
 		if (!b->purb) {
-			err("usb_alloc_urb == NULL");
+			dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
 			kfree (b);
 			goto err;
 		}
@@ -235,7 +239,8 @@ static int dabusb_alloc_buffers (pdabusb
 		if (!b->purb->transfer_buffer) {
 			kfree (b->purb);
 			kfree (b);
-			err("kmalloc(%d)==NULL", transfer_buffer_length);
+			dev_err(&s->usbdev->dev,
+				"kmalloc(%d)==NULL\n", transfer_buffer_length);
 			goto err;
 		}
 
@@ -279,10 +284,11 @@ static int dabusb_bulk (pdabusb_t s, pbu
 
 	ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
 	if(ret<0) {
-		err("dabusb: usb_bulk_msg failed(%d)",ret);
+		dev_err(&s->usbdev->dev,
+			"usb_bulk_msg failed(%d)\n", ret);
 
 		if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
-			err("set_interface failed");
+			dev_err(&s->usbdev->dev, "set_interface failed\n");
 			return -EINVAL;
 		}
 
@@ -291,7 +297,7 @@ static int dabusb_bulk (pdabusb_t s, pbu
 	if( ret == -EPIPE ) {
 		dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
 		if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
-			err("request failed");
+			dev_err(&s->usbdev->dev, "request failed\n");
 	}
 
 	pb->size = actual_length;
@@ -305,7 +311,8 @@ static int dabusb_writemem (pdabusb_t s,
 	unsigned char *transfer_buffer =  kmalloc (len, GFP_KERNEL);
 
 	if (!transfer_buffer) {
-		err("dabusb_writemem: kmalloc(%d) failed.", len);
+		dev_err(&s->usbdev->dev,
+			"dabusb_writemem: kmalloc(%d) failed.\n", len);
 		return -ENOMEM;
 	}
 
@@ -327,13 +334,14 @@ static int dabusb_loadmem (pdabusb_t s,
 {
 	int ret;
 	const struct ihex_binrec *rec;
-	const struct firmware *fw;
+	const struct firmware *uninitialized_var(fw);
 
 	dbg("Enter dabusb_loadmem (internal)");
 
 	ret = reject_firmware(&fw, "/*(DEBLOBBED)*/", &s->usbdev->dev);
 	if (ret) {
-		err("Failed to load \"/*(DEBLOBBED)*/\": %d\n", ret);
+		dev_err(&s->usbdev->dev,
+			"Failed to load \"/*(DEBLOBBED)*/\": %d\n", ret);
 		goto out;
 	}
 	ret = dabusb_8051_reset (s, 1);
@@ -346,9 +354,10 @@ static int dabusb_loadmem (pdabusb_t s,
 		ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
 				       be16_to_cpu(rec->len));
 		if (ret < 0) {
-			err("dabusb_writemem failed (%d %04X %p %d)", ret,
-			    be32_to_cpu(rec->addr), rec->data,
-			    be16_to_cpu(rec->len));
+			dev_err(&s->usbdev->dev,
+				"dabusb_writemem failed (%d %04X %p %d)\n",
+				ret, be32_to_cpu(rec->addr),
+				rec->data, be16_to_cpu(rec->len));
 			break;
 		}
 	}
@@ -396,13 +405,15 @@ static int dabusb_fpga_download (pdabusb
 	dbg("Enter dabusb_fpga_download (internal)");
 
 	if (!b) {
-		err("kmalloc(sizeof(bulk_transfer_t))==NULL");
+		dev_err(&s->usbdev->dev,
+			"kmalloc(sizeof(bulk_transfer_t))==NULL\n");
 		return -ENOMEM;
 	}
 
 	ret = reject_firmware(&fw, "/*(DEBLOBBED)*/", &s->usbdev->dev);
 	if (ret) {
-		err("Failed to load \"/*(DEBLOBBED)*/\": %d\n", ret);
+		dev_err(&s->usbdev->dev,
+			"Failed to load \"/*(DEBLOBBED)*/\": %d\n", ret);
 		kfree(b);
 		return ret;
 	}
@@ -425,7 +436,7 @@ static int dabusb_fpga_download (pdabusb
 		memcpy (b->data + 4, fw->data + 74 + n, 60);
 		ret = dabusb_bulk (s, b);
 		if (ret < 0) {
-			err("dabusb_bulk failed.");
+			dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
 			break;
 		}
 		mdelay (1);
@@ -478,9 +489,11 @@ static int dabusb_startrek (pdabusb_t s)
 
 			ret = usb_submit_urb (end->purb, GFP_KERNEL);
 			if (ret) {
-				err("usb_submit_urb returned:%d", ret);
+				dev_err(&s->usbdev->dev,
+					"usb_submit_urb returned:%d\n", ret);
 				if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
-					err("startrek: dabusb_add_buf_tail failed");
+					dev_err(&s->usbdev->dev,
+						"startrek: dabusb_add_buf_tail failed\n");
 				break;
 			}
 			else
@@ -523,7 +536,8 @@ static ssize_t dabusb_read (struct file
 
 			spin_unlock_irqrestore(&s->lock, flags);
 
-			err("error: rec_buf_list is empty");
+			dev_err(&s->usbdev->dev,
+				"error: rec_buf_list is empty\n");
 			goto err;
 		}
 
@@ -552,7 +566,8 @@ static ssize_t dabusb_read (struct file
 
 			if (list_empty (&s->rec_buff_list)) {
 				spin_unlock_irqrestore(&s->lock, flags);
-				err("error: still no buffer available.");
+				dev_err(&s->usbdev->dev,
+					"error: still no buffer available.\n");
 				goto err;
 			}
 			spin_unlock_irqrestore(&s->lock, flags);
@@ -573,7 +588,7 @@ static ssize_t dabusb_read (struct file
 		dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
 
 		if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
-			err("read: copy_to_user failed");
+			dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
 			if (!ret)
 				ret = -EFAULT;
 			goto err;
@@ -587,7 +602,8 @@ static ssize_t dabusb_read (struct file
 		if (s->readptr == purb->actual_length) {
 			// finished, take next buffer
 			if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
-				err("read: dabusb_add_buf_tail failed");
+				dev_err(&s->usbdev->dev,
+					"read: dabusb_add_buf_tail failed\n");
 			s->readptr = 0;
 		}
 	}
@@ -623,7 +639,7 @@ static int dabusb_open (struct inode *in
 	}
 	if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
 		mutex_unlock(&s->mutex);
-		err("set_interface failed");
+		dev_err(&s->usbdev->dev, "set_interface failed\n");
 		return -EINVAL;
 	}
 	s->opened = 1;
@@ -648,7 +664,7 @@ static int dabusb_release (struct inode
 
 	if (!s->remove_pending) {
 		if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
-			err("set_interface failed");
+			dev_err(&s->usbdev->dev, "set_interface failed\n");
 	}
 	else
 		wake_up (&s->remove_ok);
@@ -657,7 +673,7 @@ static int dabusb_release (struct inode
 	return 0;
 }
 
-static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
 {
 	pdabusb_t s = (pdabusb_t) file->private_data;
 	pbulk_transfer_t pbulk;
@@ -666,13 +682,17 @@ static int dabusb_ioctl (struct inode *i
 
 	dbg("dabusb_ioctl");
 
-	if (s->remove_pending)
+	lock_kernel();
+	if (s->remove_pending) {
+		unlock_kernel();
 		return -EIO;
+	}
 
 	mutex_lock(&s->mutex);
 
 	if (!s->usbdev) {
 		mutex_unlock(&s->mutex);
+		unlock_kernel();
 		return -EIO;
 	}
 
@@ -713,6 +733,7 @@ static int dabusb_ioctl (struct inode *i
 		break;
 	}
 	mutex_unlock(&s->mutex);
+	unlock_kernel();
 	return ret;
 }
 
@@ -721,7 +742,7 @@ static const struct file_operations dabu
 	.owner =	THIS_MODULE,
 	.llseek =	no_llseek,
 	.read =		dabusb_read,
-	.ioctl =	dabusb_ioctl,
+	.unlocked_ioctl =	dabusb_ioctl,
 	.open =		dabusb_open,
 	.release =	dabusb_release,
 };
@@ -764,7 +785,7 @@ static int dabusb_probe (struct usb_inte
 	s->devnum = intf->minor;
 
 	if (usb_reset_configuration (usbdev) < 0) {
-		err("reset_configuration failed");
+		dev_err(&intf->dev, "reset_configuration failed\n");
 		goto reject;
 	}
 	if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
@@ -775,7 +796,7 @@ static int dabusb_probe (struct usb_inte
 		dabusb_fpga_download (s, NULL);
 
 		if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
-			err("set_interface failed");
+			dev_err(&intf->dev, "set_interface failed\n");
 			goto reject;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-audio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 
-static int em28xx_isoc_audio_deinit(struct em28xx *dev)
+static int em28xx_deinit_isoc_audio(struct em28xx *dev)
 {
 	int i;
 
@@ -66,6 +66,7 @@ static int em28xx_isoc_audio_deinit(stru
 			usb_kill_urb(dev->adev.urb[i]);
 		else
 			usb_unlink_urb(dev->adev.urb[i]);
+
 		usb_free_urb(dev->adev.urb[i]);
 		dev->adev.urb[i] = NULL;
 
@@ -87,6 +88,20 @@ static void em28xx_audio_isocirq(struct
 	unsigned int             stride;
 	struct snd_pcm_substream *substream;
 	struct snd_pcm_runtime   *runtime;
+
+	switch (urb->status) {
+	case 0:             /* success */
+	case -ETIMEDOUT:    /* NAK */
+		break;
+	case -ECONNRESET:   /* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:            /* error */
+		dprintk("urb completition error %d.\n", urb->status);
+		break;
+	}
+
 	if (dev->adev.capture_pcm_substream) {
 		substream = dev->adev.capture_pcm_substream;
 		runtime = substream->runtime;
@@ -137,9 +152,6 @@ static void em28xx_audio_isocirq(struct
 	}
 	urb->status = 0;
 
-	if (dev->adev.shutdown)
-		return;
-
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status < 0) {
 		em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
@@ -197,8 +209,7 @@ static int em28xx_init_audio_isoc(struct
 	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
 		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
 		if (errCode) {
-			em28xx_isoc_audio_deinit(dev);
-
+			em28xx_deinit_isoc_audio(dev);
 			return errCode;
 		}
 	}
@@ -213,14 +224,16 @@ static int em28xx_cmd(struct em28xx *dev
 
 	switch (cmd) {
 	case EM28XX_CAPTURE_STREAM_EN:
-		if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+		if (dev->adev.capture_stream == STREAM_OFF &&
+		    arg == EM28XX_START_AUDIO) {
 			dev->adev.capture_stream = STREAM_ON;
 			em28xx_init_audio_isoc(dev);
-		} else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+		} else if (dev->adev.capture_stream == STREAM_ON &&
+			   arg == EM28XX_STOP_AUDIO) {
 			dev->adev.capture_stream = STREAM_OFF;
-			em28xx_isoc_audio_deinit(dev);
+			em28xx_deinit_isoc_audio(dev);
 		} else {
-			printk(KERN_ERR "An underrun very likely occurred. "
+			em28xx_errdev("An underrun very likely occurred. "
 					"Ignoring it.\n");
 		}
 		return 0;
@@ -234,7 +247,7 @@ static int snd_pcm_alloc_vmalloc_buffer(
 {
 	struct snd_pcm_runtime *runtime = subs->runtime;
 
-	dprintk("Alocating vbuffer\n");
+	dprintk("Allocating vbuffer\n");
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes > size)
 			return 0;
@@ -302,7 +315,9 @@ static int snd_em28xx_capture_open(struc
 		dprintk("changing alternate number to 7\n");
 	}
 
+	mutex_lock(&dev->lock);
 	dev->adev.users++;
+	mutex_unlock(&dev->lock);
 
 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 	dev->adev.capture_pcm_substream = substream;
@@ -317,22 +332,15 @@ err:
 static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct em28xx *dev = snd_pcm_substream_chip(substream);
-	dev->adev.users--;
 
 	dprintk("closing device\n");
 
 	dev->mute = 1;
 	mutex_lock(&dev->lock);
+	dev->adev.users--;
 	em28xx_audio_analog_set(dev);
 	mutex_unlock(&dev->lock);
 
-	if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
-		dprintk("audio users: %d\n", dev->adev.users);
-		dprintk("disabling audio stream!\n");
-		dev->adev.shutdown = 0;
-		dprintk("released lock\n");
-		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
-	}
 	return 0;
 }
 
@@ -363,7 +371,7 @@ static int snd_em28xx_hw_capture_free(st
 	dprintk("Stop capture, if needed\n");
 
 	if (dev->adev.capture_stream == STREAM_ON)
-		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
+		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
 
 	return 0;
 }
@@ -377,33 +385,40 @@ static int snd_em28xx_capture_trigger(st
 				      int cmd)
 {
 	struct em28xx *dev = snd_pcm_substream_chip(substream);
+	int retval;
 
-	dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)?
-				       "start": "stop");
+	dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+				       "start" : "stop");
+
+	spin_lock(&dev->adev.slock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
-		return 0;
+		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO);
+		retval = 0;
+		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		dev->adev.shutdown = 1;
-		return 0;
+		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
+		retval = 0;
+		break;
 	default:
-		return -EINVAL;
+		retval = -EINVAL;
 	}
+
+	spin_unlock(&dev->adev.slock);
+	return retval;
 }
 
 static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
 						    *substream)
 {
-       unsigned long flags;
-
+	unsigned long flags;
 	struct em28xx *dev;
 	snd_pcm_uframes_t hwptr_done;
 
 	dev = snd_pcm_substream_chip(substream);
-       spin_lock_irqsave(&dev->adev.slock, flags);
+	spin_lock_irqsave(&dev->adev.slock, flags);
 	hwptr_done = dev->adev.hwptr_done_capture;
-       spin_unlock_irqrestore(&dev->adev.slock, flags);
+	spin_unlock_irqrestore(&dev->adev.slock, flags);
 
 	return hwptr_done;
 }
@@ -448,9 +463,10 @@ static int em28xx_audio_init(struct em28
 	printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
 			 "Rechberger\n");
 
-	card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
+	err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
+			      &card);
+	if (err < 0)
+		return err;
 
 	spin_lock_init(&adev->slock);
 	err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 16:44:18.000000000 -0400
@@ -31,6 +31,8 @@
 #include <media/msp3400.h>
 #include <media/saa7115.h>
 #include <media/tvp5150.h>
+#include <media/tvaudio.h>
+#include <media/i2c-addr.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
@@ -122,6 +124,22 @@ static struct em28xx_reg_seq default_tun
 	{  -1,			-1,		-1,		-1},
 };
 
+/* Mute/unmute */
+static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
+	{EM28XX_R08_GPIO,	5,		7,		10},
+	{  -1,			-1,		-1,		-1},
+};
+
+static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
+	{EM28XX_R08_GPIO,	4,		7,		10},
+	{  -1,			-1,		-1,		-1},
+};
+
+static struct em28xx_reg_seq compro_mute_gpio[] = {
+	{EM28XX_R08_GPIO,	6,		7,		10},
+	{  -1,			-1,		-1,		-1},
+};
+
 /*
  *  Board definitions
  */
@@ -183,6 +201,25 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 	},
+	[EM2820_BOARD_GADMEI_TVR200] = {
+		.name         = "Gadmei TVR200",
+		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_SAA711X,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		} },
+	},
 	[EM2820_BOARD_TERRATEC_CINERGY_250] = {
 		.name         = "Terratec Cinergy 250 USB",
 		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
@@ -225,7 +262,7 @@ struct em28xx_board em28xx_boards[] = {
 		.name         = "Hauppauge WinTV USB 2",
 		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
 		.tda9887_conf = TDA9887_PRESENT |
-				TDA9887_PORT1_ACTIVE|
+				TDA9887_PORT1_ACTIVE |
 				TDA9887_PORT2_ACTIVE,
 		.decoder      = EM28XX_TVP5150,
 		.has_msp34xx  = 1,
@@ -350,26 +387,6 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_VIDEO,
 		} },
 	},
-	[EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
-		.name         = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
-		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,	/* unknown? */
-		.tda9887_conf = TDA9887_PRESENT,	/* unknown? */
-		.decoder      = EM28XX_SAA711X,
-		.input        = { {
-			.type     = EM28XX_VMUX_TELEVISION,
-			.vmux     = SAA7115_COMPOSITE2,
-			.amux     = EM28XX_AMUX_LINE_IN,
-		}, {
-			.type     = EM28XX_VMUX_COMPOSITE1,
-			.vmux     = SAA7115_COMPOSITE0,
-			.amux     = EM28XX_AMUX_LINE_IN,
-		}, {
-			.type     = EM28XX_VMUX_SVIDEO,
-			.vmux     = SAA7115_SVIDEO3,
-			.amux     = EM28XX_AMUX_LINE_IN,
-		} },
-	},
 	[EM2821_BOARD_SUPERCOMP_USB_2] = {
 		.name         = "Supercomp USB 2.0 TV",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -498,7 +515,7 @@ struct em28xx_board em28xx_boards[] = {
 	},
 	[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
 		.name          = "Yakumo MovieMixer",
-		.tuner_type   = TUNER_ABSENT,	/* Capture only device */
+		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
 		.decoder       = EM28XX_TVP5150,
 		.input         = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -604,6 +621,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,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -628,6 +646,7 @@ struct em28xx_board em28xx_boards[] = {
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.mts_firmware = 1,
+		.ir_codes     = ir_codes_hauppauge_new,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -842,11 +861,11 @@ struct em28xx_board em28xx_boards[] = {
 		} },
 	},
 	[EM2800_BOARD_GRABBEEX_USB2800] = {
-		.name         = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
-		.is_em2800    = 1,
-		.decoder      = EM28XX_SAA711X,
-		.tuner_type   = TUNER_ABSENT, /* capture only board */
-		.input        = { {
+		.name       = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+		.is_em2800  = 1,
+		.decoder    = EM28XX_SAA711X,
+		.tuner_type = TUNER_ABSENT, /* capture only board */
+		.input      = { {
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.vmux     = SAA7115_COMPOSITE0,
 			.amux     = EM28XX_AMUX_LINE_IN,
@@ -897,7 +916,7 @@ struct em28xx_board em28xx_boards[] = {
 		} },
 	},
 	[EM2820_BOARD_PINNACLE_DVC_90] = {
-		.name         = "Pinnacle Dazzle DVC 90/DVC 100",
+		.name         = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker",
 		.tuner_type   = TUNER_ABSENT, /* capture only board */
 		.decoder      = EM28XX_SAA711X,
 		.input        = { {
@@ -952,7 +971,7 @@ struct em28xx_board em28xx_boards[] = {
 		} },
 	},
 	[EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
-		.name         = "Pixelview Prolink PlayTV USB 2.0",
+		.name         = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
 		.has_snapshot_button = 1,
 		.tda9887_conf = TDA9887_PRESENT,
 		.tuner_type   = TUNER_YMEC_TVF_5533MF,
@@ -1198,7 +1217,9 @@ struct em28xx_board em28xx_boards[] = {
 		.has_dvb      = 1,
 		.dvb_gpio     = kworld_330u_digital,
 		.xclk             = EM28XX_XCLK_FREQUENCY_12MHZ,
-		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
+		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE |
+				    EM28XX_I2C_EEPROM_ON_BOARD |
+				    EM28XX_I2C_EEPROM_KEY_VALID,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1221,23 +1242,91 @@ struct em28xx_board em28xx_boards[] = {
 	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
 		.name         = "Compro VideoMate ForYou/Stereo",
 		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.tvaudio_addr = 0xb0,
 		.tda9887_conf = TDA9887_PRESENT,
 		.decoder      = EM28XX_TVP5150,
+		.adecoder     = EM28XX_TVAUDIO,
+		.mute_gpio    = compro_mute_gpio,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO,
+			.gpio     = compro_unmute_tv_gpio,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = EM28XX_AMUX_LINE_IN,
+			.gpio     = compro_unmute_svid_gpio,
+		} },
+	},
+	[EM2860_BOARD_KAIOMY_TVNPC_U2] = {
+		.name	      = "Kaiomy TVnPC U2",
+		.vchannels    = 3,
+		.tuner_type   = TUNER_XC2028,
+		.tuner_addr   = 0x61,
+		.mts_firmware = 1,
+		.decoder      = EM28XX_TVP5150,
+		.tuner_gpio   = default_tuner_gpio,
+		.ir_codes     = ir_codes_kaiomy,
+		.input          = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO,
+
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
 			.amux     = EM28XX_AMUX_LINE_IN,
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = TVP5150_SVIDEO,
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
+		.radio		= {
+			.type     = EM28XX_RADIO,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}
+	},
+	[EM2860_BOARD_EASYCAP] = {
+		.name         = "Easy Cap Capture DC-60",
+		.vchannels    = 2,
+		.tuner_type   = TUNER_ABSENT,
+		.decoder      = EM28XX_SAA711X,
+		.input           = { {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		} },
+	},
+	[EM2820_BOARD_IODATA_GVMVP_SZ] = {
+		.name       = "IO-DATA GV-MVP/SZ",
+		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
+		.tuner_gpio   = default_tuner_gpio,
+		.tda9887_conf = TDA9887_PRESENT,
+		.decoder      = EM28XX_TVP5150,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = TVP5150_COMPOSITE0,
+			.amux     = EM28XX_AMUX_VIDEO,
+		}, { /* Composite has not been tested yet */
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = TVP5150_COMPOSITE1,
+			.amux     = EM28XX_AMUX_VIDEO,
+		}, { /* S-video has not been tested yet */
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = TVP5150_SVIDEO,
+			.amux     = EM28XX_AMUX_VIDEO,
+		} },
 	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
 /* table of devices that work with this driver */
-struct usb_device_id em28xx_id_table [] = {
+struct usb_device_id em28xx_id_table[] = {
 	{ USB_DEVICE(0xeb1a, 0x2750),
 			.driver_info = EM2750_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2751),
@@ -1260,6 +1349,8 @@ struct usb_device_id em28xx_id_table []
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0xe300),
 			.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+	{ USB_DEVICE(0xeb1a, 0xe303),
+			.driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
 	{ USB_DEVICE(0xeb1a, 0xe305),
 			.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
 	{ USB_DEVICE(0xeb1a, 0xe310),
@@ -1278,6 +1369,8 @@ struct usb_device_id em28xx_id_table []
 			.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
 	{ USB_DEVICE(0xeb1a, 0xe357),
 			.driver_info = EM2870_BOARD_KWORLD_355U },
+	{ USB_DEVICE(0x1b80, 0xe302),
+			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
 	{ USB_DEVICE(0x0ccd, 0x0036),
 			.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
 	{ USB_DEVICE(0x0ccd, 0x004c),
@@ -1330,6 +1423,8 @@ struct usb_device_id em28xx_id_table []
 			.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
 	{ USB_DEVICE(0x093b, 0xa005),
 			.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
+	{ USB_DEVICE(0x04bb, 0x0515),
+			.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1337,7 +1432,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table
 /*
  * EEPROM hash table for devices with generic USB IDs
  */
-static struct em28xx_hash_table em28xx_eeprom_hash [] = {
+static struct em28xx_hash_table em28xx_eeprom_hash[] = {
 	/* P/N: SA 60002070465 Tuner: TVF7533-MF */
 	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
@@ -1349,6 +1444,25 @@ static struct em28xx_hash_table em28xx_i
 	{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
 	{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
 	{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
+	{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
+};
+
+/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
+static unsigned short saa711x_addrs[] = {
+	0x4a >> 1, 0x48 >> 1,   /* SAA7111, SAA7111A and SAA7113 */
+	0x42 >> 1, 0x40 >> 1,   /* SAA7114, SAA7115 and SAA7118 */
+	I2C_CLIENT_END };
+
+static unsigned short tvp5150_addrs[] = {
+	0xb8 >> 1,
+	0xba >> 1,
+	I2C_CLIENT_END
+};
+
+static unsigned short msp3400_addrs[] = {
+	0x80 >> 1,
+	0x88 >> 1,
+	I2C_CLIENT_END
 };
 
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
@@ -1368,7 +1482,7 @@ int em28xx_tuner_callback(void *ptr, int
 }
 EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
 
-static void inline em28xx_set_model(struct em28xx *dev)
+static inline void em28xx_set_model(struct em28xx *dev)
 {
 	memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
 
@@ -1504,6 +1618,34 @@ void em28xx_pre_card_setup(struct em28xx
 		/* enables audio for that devices */
 		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
 		break;
+
+	case EM2860_BOARD_KAIOMY_TVNPC_U2:
+		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+		em28xx_write_regs(dev, 0x0d, "\x42", 1);
+		em28xx_write_regs(dev, 0x08, "\xfd", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\xff", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\x7f", 1);
+		msleep(10);
+		em28xx_write_regs(dev, 0x08, "\x6b", 1);
+
+		break;
+	case EM2860_BOARD_EASYCAP:
+		em28xx_write_regs(dev, 0x08, "\xf8", 1);
+		break;
+
+	case EM2820_BOARD_IODATA_GVMVP_SZ:
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		msleep(70);
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+		msleep(10);
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		msleep(70);
+		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		msleep(70);
+		break;
 	}
 
 	em28xx_gpio_set(dev, dev->board.tuner_gpio);
@@ -1551,31 +1693,55 @@ static void em28xx_setup_xc3028(struct e
 	}
 }
 
-static void em28xx_config_tuner(struct em28xx *dev)
+static void em28xx_tuner_setup(struct em28xx *dev)
 {
-	struct v4l2_priv_tun_config  xc2028_cfg;
 	struct tuner_setup           tun_setup;
 	struct v4l2_frequency        f;
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return;
 
+	memset(&tun_setup, 0, sizeof(tun_setup));
+
 	tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
-	tun_setup.type = dev->tuner_type;
-	tun_setup.addr = dev->tuner_addr;
 	tun_setup.tuner_callback = em28xx_tuner_callback;
 
-	em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+	if (dev->board.radio.type) {
+		tun_setup.type = dev->board.radio.type;
+		tun_setup.addr = dev->board.radio_addr;
+
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+	}
+
+	if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
+		tun_setup.type   = dev->tuner_type;
+		tun_setup.addr   = dev->tuner_addr;
+
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+	}
+
+	if (dev->tda9887_conf) {
+		struct v4l2_priv_tun_config tda9887_cfg;
+
+		tda9887_cfg.tuner = TUNER_TDA9887;
+		tda9887_cfg.priv = &dev->tda9887_conf;
+
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
+	}
 
 	if (dev->tuner_type == TUNER_XC2028) {
+		struct v4l2_priv_tun_config  xc2028_cfg;
 		struct xc2028_ctrl           ctl;
 
+		memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
+		memset(&ctl, 0, sizeof(ctl));
+
 		em28xx_setup_xc3028(dev, &ctl);
 
 		xc2028_cfg.tuner = TUNER_XC2028;
 		xc2028_cfg.priv  = &ctl;
 
-		em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
 	}
 
 	/* configure tuner */
@@ -1583,7 +1749,7 @@ static void em28xx_config_tuner(struct e
 	f.type = V4L2_TUNER_ANALOG_TV;
 	f.frequency = 9076;     /* just a magic number */
 	dev->ctl_freq = f.frequency;
-	em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
 }
 
 static int em28xx_hint_board(struct em28xx *dev)
@@ -1610,7 +1776,7 @@ static int em28xx_hint_board(struct em28
 			em28xx_errdev("If the board were missdetected, "
 				      "please email this log to:\n");
 			em28xx_errdev("\tV4L Mailing List "
-				      " <video4linux-list@redhat.com>\n");
+				      " <linux-media@vger.kernel.org>\n");
 			em28xx_errdev("Board detected as %s\n",
 				      em28xx_boards[dev->model].name);
 
@@ -1642,7 +1808,7 @@ static int em28xx_hint_board(struct em28
 			em28xx_errdev("If the board were missdetected, "
 				      "please email this log to:\n");
 			em28xx_errdev("\tV4L Mailing List "
-				      " <video4linux-list@redhat.com>\n");
+				      " <linux-media@vger.kernel.org>\n");
 			em28xx_errdev("Board detected as %s\n",
 				      em28xx_boards[dev->model].name);
 
@@ -1655,7 +1821,7 @@ static int em28xx_hint_board(struct em28
 	em28xx_errdev("You may try to use card=<n> insmod option to "
 		      "workaround that.\n");
 	em28xx_errdev("Please send an email with this log to:\n");
-	em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
+	em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n");
 	em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
 	em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
 
@@ -1790,20 +1956,52 @@ void em28xx_card_setup(struct em28xx *de
 	if (tuner >= 0)
 		dev->tuner_type = tuner;
 
-#ifdef CONFIG_MODULES
 	/* request some modules */
 	if (dev->board.has_msp34xx)
-		request_module("msp3400");
+		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"msp3400", "msp3400", msp3400_addrs);
+
 	if (dev->board.decoder == EM28XX_SAA711X)
-		request_module("saa7115");
+		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"saa7115", "saa7115_auto", saa711x_addrs);
+
 	if (dev->board.decoder == EM28XX_TVP5150)
-		request_module("tvp5150");
-	if (dev->board.tuner_type != TUNER_ABSENT)
-		request_module("tuner");
-#endif
+		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"tvp5150", "tvp5150", tvp5150_addrs);
 
-	em28xx_config_tuner(dev);
+	if (dev->board.adecoder == EM28XX_TVAUDIO)
+		v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"tvaudio", "tvaudio", dev->board.tvaudio_addr);
+
+	if (dev->board.tuner_type != TUNER_ABSENT) {
+		int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+		if (dev->board.radio.type)
+			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+				"tuner", "tuner", dev->board.radio_addr);
+
+		if (has_demod)
+			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		if (dev->tuner_addr == 0) {
+			enum v4l2_i2c_tuner_type type =
+				has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+			struct v4l2_subdev *sd;
+
+			sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(type));
+
+			if (sd)
+				dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
+		} else {
+			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+				"tuner", "tuner", dev->tuner_addr);
+		}
+	}
 
+	em28xx_tuner_setup(dev);
 	em28xx_ir_init(dev);
 }
 
@@ -1852,6 +2050,9 @@ void em28xx_release_resources(struct em2
 	em28xx_remove_from_devlist(dev);
 
 	em28xx_i2c_unregister(dev);
+
+	v4l2_device_unregister(&dev->v4l2_dev);
+
 	usb_put_dev(dev->udev);
 
 	/* Mark device as unused */
@@ -1863,6 +2064,7 @@ void em28xx_release_resources(struct em2
  * allocates and inits the device structs, registers i2c bus and v4l device
  */
 static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
+			   struct usb_interface *interface,
 			   int minor)
 {
 	struct em28xx *dev = *devhandle;
@@ -1896,9 +2098,16 @@ static int em28xx_init_dev(struct em28xx
 		}
 	}
 
+	retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+	if (retval < 0) {
+		em28xx_errdev("Call to v4l2_device_register() failed!\n");
+		return retval;
+	}
+
 	/* register i2c bus */
 	errCode = em28xx_i2c_register(dev);
 	if (errCode < 0) {
+		v4l2_device_unregister(&dev->v4l2_dev);
 		em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
 			__func__, errCode);
 		return errCode;
@@ -1910,6 +2119,7 @@ static int em28xx_init_dev(struct em28xx
 	/* Configure audio */
 	errCode = em28xx_audio_setup(dev);
 	if (errCode < 0) {
+		v4l2_device_unregister(&dev->v4l2_dev);
 		em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
 			__func__, errCode);
 	}
@@ -1954,7 +2164,7 @@ static int em28xx_init_dev(struct em28xx
 	em28xx_init_extension(dev);
 
 	/* Save some power by putting tuner to sleep */
-	em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
 
 	return 0;
 
@@ -1973,7 +2183,7 @@ static int em28xx_usb_probe(struct usb_i
 	struct usb_device *udev;
 	struct usb_interface *uif;
 	struct em28xx *dev = NULL;
-	int retval = -ENODEV;
+	int retval;
 	int i, nr, ifnum, isoc_pipe;
 	char *speed;
 	char descr[255] = "";
@@ -1995,7 +2205,8 @@ static int em28xx_usb_probe(struct usb_i
 			interface->altsetting[0].desc.bInterfaceClass);
 
 		em28xx_devused &= ~(1<<nr);
-		return -ENODEV;
+		retval = -ENODEV;
+		goto err;
 	}
 
 	endpoint = &interface->cur_altsetting->endpoint[0].desc;
@@ -2028,7 +2239,8 @@ static int em28xx_usb_probe(struct usb_i
 				"interface not used by the driver\n");
 
 			em28xx_devused &= ~(1<<nr);
-			return -ENODEV;
+			retval = -ENODEV;
+			goto err;
 		}
 	}
 
@@ -2071,7 +2283,8 @@ static int em28xx_usb_probe(struct usb_i
 		printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
 				EM28XX_MAXBOARDS);
 		em28xx_devused &= ~(1<<nr);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err;
 	}
 
 	/* allocate memory for our device state and initialize it */
@@ -2079,7 +2292,8 @@ static int em28xx_usb_probe(struct usb_i
 	if (dev == NULL) {
 		em28xx_err(DRIVER_NAME ": out of memory!\n");
 		em28xx_devused &= ~(1<<nr);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err;
 	}
 
 	snprintf(dev->name, 29, "em28xx #%d", nr);
@@ -2106,7 +2320,8 @@ static int em28xx_usb_probe(struct usb_i
 		em28xx_errdev("out of memory!\n");
 		em28xx_devused &= ~(1<<nr);
 		kfree(dev);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err;
 	}
 
 	for (i = 0; i < dev->num_alt ; i++) {
@@ -2121,12 +2336,11 @@ static int em28xx_usb_probe(struct usb_i
 	/* allocate device struct */
 	mutex_init(&dev->lock);
 	mutex_lock(&dev->lock);
-	retval = em28xx_init_dev(&dev, udev, nr);
+	retval = em28xx_init_dev(&dev, udev, interface, nr);
 	if (retval) {
 		em28xx_devused &= ~(1<<dev->devno);
 		kfree(dev);
-
-		return retval;
+		goto err;
 	}
 
 	/* save our data pointer in this interface device */
@@ -2140,6 +2354,9 @@ static int em28xx_usb_probe(struct usb_i
 	mutex_unlock(&dev->lock);
 
 	return 0;
+
+err:
+	return retval;
 }
 
 /*
@@ -2165,6 +2382,8 @@ static void em28xx_usb_disconnect(struct
 
 	wake_up_interruptible_all(&dev->open);
 
+	v4l2_device_disconnect(&dev->v4l2_dev);
+
 	if (dev->users) {
 		em28xx_warn
 		    ("device /dev/video%d is open! Deregistration and memory "
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-core.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,8 +33,8 @@
 /* #define ENABLE_DEBUG_ISOC_FRAMES */
 
 static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
 
 #define em28xx_coredbg(fmt, arg...) do {\
 	if (core_debug) \
@@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug,"enable debu
 			 dev->name, __func__ , ##arg); } while (0)
 
 static unsigned int reg_debug;
-module_param(reg_debug,int,0644);
-MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
 
 #define em28xx_regdbg(fmt, arg...) do {\
 	if (reg_debug) \
@@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28x
 		return -EINVAL;
 
 	if (reg_debug) {
-		printk( KERN_DEBUG "(pipe 0x%08x): "
+		printk(KERN_DEBUG "(pipe 0x%08x): "
 			"IN:  %02x %02x %02x %02x %02x %02x %02x %02x ",
 			pipe,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx
 	if (reg_debug) {
 		int byte;
 
-		printk( KERN_DEBUG "(pipe 0x%08x): "
+		printk(KERN_DEBUG "(pipe 0x%08x): "
 			"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
 			pipe,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -378,6 +378,11 @@ static int em28xx_set_audio_source(struc
 		}
 	}
 
+	if (dev->board.mute_gpio && dev->mute)
+		em28xx_gpio_set(dev, dev->board.mute_gpio);
+	else
+		em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
+
 	ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0);
 	if (ret < 0)
 		return ret;
@@ -424,7 +429,7 @@ int em28xx_audio_analog_set(struct em28x
 
 	xclk = dev->board.xclk & 0x7f;
 	if (!dev->mute)
-		xclk |= 0x80;
+		xclk |= EM28XX_XCLK_AUDIO_UNMUTE;
 
 	ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
 	if (ret < 0)
@@ -462,7 +467,8 @@ int em28xx_audio_analog_set(struct em28x
 		if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
 			int sel = ac97_return_record_select(dev->ctl_aoutput);
 
-			/* Use the same input for both left and right channels */
+			/* Use the same input for both left and right
+			   channels */
 			sel |= (sel << 8);
 
 			em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
@@ -698,7 +704,7 @@ static int em28xx_scaler_set(struct em28
 		em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
 		/* it seems that both H and V scalers must be active
 		   to work correctly */
-		mode = (h || v)? 0x30: 0x00;
+		mode = (h || v) ? 0x30 : 0x00;
 	}
 	return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
 }
@@ -827,6 +833,19 @@ static void em28xx_irq_callback(struct u
 	struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
 	int rc, i;
 
+	switch (urb->status) {
+	case 0:             /* success */
+	case -ETIMEDOUT:    /* NAK */
+		break;
+	case -ECONNRESET:   /* kill */
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:            /* error */
+		em28xx_isocdbg("urb completition error %d.\n", urb->status);
+		break;
+	}
+
 	/* Copy data from URB */
 	spin_lock(&dev->slock);
 	rc = dev->isoc_ctl.isoc_copy(dev, urb);
@@ -945,7 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev,
 			em28xx_err("unable to allocate %i bytes for transfer"
 					" buffer %i%s\n",
 					sb_size, i,
-					in_interrupt()?" while in int":"");
+					in_interrupt() ? " while in int" : "");
 			em28xx_uninit_isoc(dev);
 			return -ENOMEM;
 		}
@@ -963,7 +982,7 @@ int em28xx_init_isoc(struct em28xx *dev,
 				 em28xx_irq_callback, dma_q, 1);
 
 		urb->number_of_packets = max_packets;
-		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 
 		k = 0;
 		for (j = 0; j < max_packets; j++) {
@@ -999,14 +1018,10 @@ EXPORT_SYMBOL_GPL(em28xx_init_isoc);
  */
 void em28xx_wake_i2c(struct em28xx *dev)
 {
-	struct v4l2_routing route;
-	int zero = 0;
-
-	route.input = INPUT(dev->ctl_input)->vmux;
-	route.output = 0;
-	em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
-	em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
-	em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core,  reset, 0);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			INPUT(dev->ctl_input)->vmux, 0, 0);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-dvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,9 +29,6 @@
 #include "lgdt330x.h"
 #include "zl10353.h"
 #include "s5h1409.h"
-#ifdef EM28XX_DRX397XD_SUPPORT
-#include "drx397xD.h"
-#endif
 
 MODULE_DESCRIPTION("driver for em28xx based DVB cards");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx.h linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include <linux/videodev2.h>
 #include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
 
 #include <linux/i2c.h>
 #include <linux/mutex.h>
@@ -70,7 +71,6 @@
 #define EM2820_BOARD_VIDEOLOGY_20K14XUSB	  30
 #define EM2821_BOARD_USBGEAR_VD204		  31
 #define EM2821_BOARD_SUPERCOMP_USB_2		  32
-#define EM2821_BOARD_PROLINK_PLAYTV_USB2	  33
 #define EM2860_BOARD_TERRATEC_HYBRID_XS		  34
 #define EM2860_BOARD_TYPHOON_DVD_MAKER		  35
 #define EM2860_BOARD_NETGMBH_CAM		  36
@@ -98,6 +98,10 @@
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU	  58
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850	  60
 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2	  61
+#define EM2820_BOARD_GADMEI_TVR200		  62
+#define EM2860_BOARD_KAIOMY_TVNPC_U2              63
+#define EM2860_BOARD_EASYCAP                      64
+#define EM2820_BOARD_IODATA_GVMVP_SZ		  65
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -110,6 +114,10 @@
 #define EM28XX_BOARD_NOT_VALIDATED 1
 #define EM28XX_BOARD_VALIDATED	   0
 
+/* Params for em28xx_cmd() audio */
+#define EM28XX_START_AUDIO      1
+#define EM28XX_STOP_AUDIO       0
+
 /* maximum number of em28xx boards */
 #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 
@@ -154,7 +162,8 @@
 */
 
 /* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT       msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+#define EM28XX_URB_TIMEOUT \
+			msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
 
 /* time in msecs to wait for i2c writes to finish */
 #define EM2800_I2C_WRITE_TIMEOUT 20
@@ -348,6 +357,11 @@ enum em28xx_decoder {
 	EM28XX_SAA711X,
 };
 
+enum em28xx_adecoder {
+	EM28XX_NOADECODER = 0,
+	EM28XX_TVAUDIO,
+};
+
 struct em28xx_board {
 	char *name;
 	int vchannels;
@@ -361,6 +375,7 @@ struct em28xx_board {
 	struct em28xx_reg_seq *dvb_gpio;
 	struct em28xx_reg_seq *suspend_gpio;
 	struct em28xx_reg_seq *tuner_gpio;
+	struct em28xx_reg_seq *mute_gpio;
 
 	unsigned int is_em2800:1;
 	unsigned int has_msp34xx:1;
@@ -371,8 +386,11 @@ struct em28xx_board {
 	unsigned int valid:1;
 
 	unsigned char xclk, i2c_speed;
+	unsigned char radio_addr;
+	unsigned short tvaudio_addr;
 
 	enum em28xx_decoder decoder;
+	enum em28xx_adecoder adecoder;
 
 	struct em28xx_input       input[MAX_EM28XX_INPUT];
 	struct em28xx_input	  radio;
@@ -420,7 +438,7 @@ struct em28xx_audio {
 	unsigned int hwptr_done_capture;
 	struct snd_card            *sndcard;
 
-	int users, shutdown;
+	int users;
 	enum em28xx_stream_state capture_stream;
 	spinlock_t slock;
 };
@@ -445,6 +463,7 @@ struct em28xx {
 	int devno;		/* marks the number of this device */
 	enum em28xx_chip_id chip_id;
 
+	struct v4l2_device v4l2_dev;
 	struct em28xx_board board;
 
 	unsigned int stream_on:1;	/* Locks streams */
@@ -523,7 +542,8 @@ struct em28xx {
 	int num_alt;		/* Number of alternative settings */
 	unsigned int *alt_max_pkt_size;	/* array of wMaxPacketSize */
 	struct urb *urb[EM28XX_NUM_BUFS];	/* urb for isoc transfers */
-	char *transfer_buffer[EM28XX_NUM_BUFS];	/* transfer buffers for isoc transfer */
+	char *transfer_buffer[EM28XX_NUM_BUFS];	/* transfer buffers for isoc
+						   transfer */
 	char urb_buf[URB_MAX_CTRL_SIZE];	/* urb control msg buffer */
 
 	/* helper funcs that call usb_control_msg */
@@ -561,11 +581,9 @@ struct em28xx_ops {
 };
 
 /* Provided by em28xx-i2c.c */
-
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
 void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
+int  em28xx_i2c_register(struct em28xx *dev);
+int  em28xx_i2c_unregister(struct em28xx *dev);
 
 /* Provided by em28xx-core.c */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -402,10 +402,12 @@ static int em28xx_i2c_eeprom(struct em28
 				 dev->name);
 		break;
 	case 2:
-		printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name);
+		printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",
+				 dev->name);
 		break;
 	case 3:
-		printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name);
+		printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",
+				 dev->name);
 		break;
 	}
 
@@ -457,65 +459,15 @@ static u32 functionality(struct i2c_adap
 static int attach_inform(struct i2c_client *client)
 {
 	struct em28xx *dev = client->adapter->algo_data;
+	struct IR_i2c *ir = i2c_get_clientdata(client);
 
 	switch (client->addr << 1) {
-	case 0x86:
-	case 0x84:
-	case 0x96:
-	case 0x94:
-	{
-		struct v4l2_priv_tun_config tda9887_cfg;
-
-		struct tuner_setup tun_setup;
-
-		tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
-		tun_setup.type = TUNER_TDA9887;
-		tun_setup.addr = client->addr;
-
-		em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR,
-			&tun_setup);
-
-		tda9887_cfg.tuner = TUNER_TDA9887;
-		tda9887_cfg.priv = &dev->tda9887_conf;
-		em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG,
-					&tda9887_cfg);
-		break;
-	}
-	case 0x42:
-		dprintk1(1, "attach_inform: saa7114 detected.\n");
-		break;
-	case 0x4a:
-		dprintk1(1, "attach_inform: saa7113 detected.\n");
-		break;
-	case 0xa0:
-		dprintk1(1, "attach_inform: eeprom detected.\n");
-		break;
 	case 0x60:
 	case 0x8e:
-	{
-		struct IR_i2c *ir = i2c_get_clientdata(client);
-		dprintk1(1, "attach_inform: IR detected (%s).\n",
-			ir->phys);
+		dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
 		em28xx_set_ir(dev, ir);
 		break;
 	}
-	case 0x80:
-	case 0x88:
-		dprintk1(1, "attach_inform: msp34xx detected.\n");
-		break;
-	case 0xb8:
-	case 0xba:
-		dprintk1(1, "attach_inform: tvp5150 detected.\n");
-		break;
-
-	default:
-		if (!dev->tuner_addr)
-			dev->tuner_addr = client->addr;
-
-		dprintk1(1, "attach inform: detected I2C address %x\n",
-				client->addr << 1);
-
-	}
 
 	return 0;
 }
@@ -527,7 +479,6 @@ static struct i2c_algorithm em28xx_algo
 
 static struct i2c_adapter em28xx_adap_template = {
 	.owner = THIS_MODULE,
-	.class = I2C_CLASS_TV_ANALOG,
 	.name = "em28xx",
 	.id = I2C_HW_B_EM28XX,
 	.algo = &em28xx_algo,
@@ -552,6 +503,7 @@ static char *i2c_devs[128] = {
 	[0x80 >> 1] = "msp34xx",
 	[0x88 >> 1] = "msp34xx",
 	[0xa0 >> 1] = "eeprom",
+	[0xb0 >> 1] = "tda9874",
 	[0xb8 >> 1] = "tvp5150a",
 	[0xba >> 1] = "tvp5150a",
 	[0xc0 >> 1] = "tuner (analog)",
@@ -587,16 +539,6 @@ void em28xx_do_i2c_scan(struct em28xx *d
 }
 
 /*
- * em28xx_i2c_call_clients()
- * send commands to all attached i2c devices
- */
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
-{
-	BUG_ON(NULL == dev->i2c_adap.algo_data);
-	i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-/*
  * em28xx_i2c_register()
  * register i2c bus
  */
@@ -610,6 +552,7 @@ int em28xx_i2c_register(struct em28xx *d
 	dev->i2c_adap.dev.parent = &dev->udev->dev;
 	strcpy(dev->i2c_adap.name, dev->name);
 	dev->i2c_adap.algo_data = dev;
+	i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
 
 	retval = i2c_add_adapter(&dev->i2c_adap);
 	if (retval < 0) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-input.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-input.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-input.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-input.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,8 +68,7 @@ struct em28xx_IR {
 
 	/* poll external decoder */
 	int polling;
-	struct work_struct work;
-	struct timer_list timer;
+	struct delayed_work work;
 	unsigned int last_toggle:1;
 	unsigned int last_readcount;
 	unsigned int repeat_interval;
@@ -292,32 +291,23 @@ static void em28xx_ir_handle_key(struct
 	return;
 }
 
-static void ir_timer(unsigned long data)
-{
-	struct em28xx_IR *ir = (struct em28xx_IR *)data;
-
-	schedule_work(&ir->work);
-}
-
 static void em28xx_ir_work(struct work_struct *work)
 {
-	struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work);
+	struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
 
 	em28xx_ir_handle_key(ir);
-	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 }
 
 static void em28xx_ir_start(struct em28xx_IR *ir)
 {
-	setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
-	INIT_WORK(&ir->work, em28xx_ir_work);
-	schedule_work(&ir->work);
+	INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
+	schedule_delayed_work(&ir->work, 0);
 }
 
 static void em28xx_ir_stop(struct em28xx_IR *ir)
 {
-	del_timer_sync(&ir->timer);
-	flush_scheduled_work();
+	cancel_delayed_work_sync(&ir->work);
 }
 
 int em28xx_ir_init(struct em28xx *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-video.c linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/em28xx/em28xx-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,7 +49,7 @@
 		      "Sascha Sommer <saschasommer@freenet.de>"
 
 #define DRIVER_DESC         "Empia em28xx based USB video device driver"
-#define EM28XX_VERSION_CODE  KERNEL_VERSION(0, 1, 1)
+#define EM28XX_VERSION_CODE  KERNEL_VERSION(0, 1, 2)
 
 #define em28xx_videodbg(fmt, arg...) do {\
 	if (video_debug) \
@@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em2
 		em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
 			       ((char *)startwrite + lencopy) -
 			       ((char *)outp + buf->vb.size));
-		lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
+		remain = (char *)outp + buf->vb.size - (char *)startwrite;
+		lencopy = remain;
 	}
 	if (lencopy <= 0)
 		return;
@@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em2
 		else
 			lencopy = bytesperline;
 
-		if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+		if ((char *)startwrite + lencopy > (char *)outp +
+		    buf->vb.size) {
 			em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
 				       ((char *)startwrite + lencopy) -
 				       ((char *)outp + buf->vb.size));
@@ -347,7 +349,7 @@ static inline int em28xx_isoc_copy(struc
 		}
 		if (p[0] == 0x22 && p[1] == 0x5a) {
 			em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
-				       len, (p[2] & 1)? "odd" : "even");
+				       len, (p[2] & 1) ? "odd" : "even");
 
 			if (!(p[2] & 1)) {
 				if (buf != NULL)
@@ -398,7 +400,7 @@ buffer_setup(struct videobuf_queue *vq,
 	f.frequency = dev->ctl_freq;
 	f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 
-	em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
 
 	return 0;
 }
@@ -476,7 +478,9 @@ fail:
 static void
 buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 {
-	struct em28xx_buffer    *buf     = container_of(vb, struct em28xx_buffer, vb);
+	struct em28xx_buffer    *buf     = container_of(vb,
+							struct em28xx_buffer,
+							vb);
 	struct em28xx_fh        *fh      = vq->priv_data;
 	struct em28xx           *dev     = fh->dev;
 	struct em28xx_dmaqueue  *vidq    = &dev->vidq;
@@ -489,7 +493,9 @@ buffer_queue(struct videobuf_queue *vq,
 static void buffer_release(struct videobuf_queue *vq,
 				struct videobuf_buffer *vb)
 {
-	struct em28xx_buffer   *buf  = container_of(vb, struct em28xx_buffer, vb);
+	struct em28xx_buffer   *buf  = container_of(vb,
+						    struct em28xx_buffer,
+						    vb);
 	struct em28xx_fh       *fh   = vq->priv_data;
 	struct em28xx          *dev  = (struct em28xx *)fh->dev;
 
@@ -509,10 +515,6 @@ static struct videobuf_queue_ops em28xx_
 
 static void video_mux(struct em28xx *dev, int index)
 {
-	struct v4l2_routing route;
-
-	route.input = INPUT(index)->vmux;
-	route.output = 0;
 	dev->ctl_input = index;
 	dev->ctl_ainput = INPUT(index)->amux;
 	dev->ctl_aoutput = INPUT(index)->aout;
@@ -520,18 +522,22 @@ static void video_mux(struct em28xx *dev
 	if (!dev->ctl_aoutput)
 		dev->ctl_aoutput = EM28XX_AOUT_MASTER;
 
-	em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+			INPUT(index)->vmux, 0, 0);
 
 	if (dev->board.has_msp34xx) {
 		if (dev->i2s_speed) {
-			em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
-				&dev->i2s_speed);
+			v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
+				s_i2s_clock_freq, dev->i2s_speed);
 		}
-		route.input = dev->ctl_ainput;
-		route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
 		/* Note: this is msp3400 specific */
-		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
-			&route);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			 dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
+	}
+
+	if (dev->board.adecoder != EM28XX_NOADECODER) {
+		v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+			dev->ctl_ainput, dev->ctl_aoutput, 0);
 	}
 
 	em28xx_audio_analog_set(dev);
@@ -557,7 +563,7 @@ static int res_get(struct em28xx_fh *fh)
 
 static int res_check(struct em28xx_fh *fh)
 {
-	return (fh->stream_on);
+	return fh->stream_on;
 }
 
 static void res_free(struct em28xx_fh *fh)
@@ -791,7 +797,7 @@ out:
 	return rc;
 }
 
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
 	struct em28xx_fh   *fh  = priv;
 	struct em28xx      *dev = fh->dev;
@@ -816,7 +822,7 @@ static int vidioc_s_std(struct file *fil
 	get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
 
 	em28xx_resolution_set(dev);
-	em28xx_i2c_call_clients(dev, VIDIOC_S_STD, &dev->norm);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
 
 	mutex_unlock(&dev->lock);
 	return 0;
@@ -982,8 +988,9 @@ static int vidioc_queryctrl(struct file
 			}
 		}
 	}
+
 	mutex_lock(&dev->lock);
-	em28xx_i2c_call_clients(dev, VIDIOC_QUERYCTRL, qc);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
 	mutex_unlock(&dev->lock);
 
 	if (qc->type)
@@ -1007,9 +1014,14 @@ static int vidioc_g_ctrl(struct file *fi
 	mutex_lock(&dev->lock);
 
 	if (dev->board.has_msp34xx)
-		em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
-	else
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
+	else {
 		rc = em28xx_get_ctrl(dev, ctrl);
+		if (rc < 0) {
+			v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
+			rc = 0;
+		}
+	}
 
 	mutex_unlock(&dev->lock);
 	return rc;
@@ -1030,7 +1042,7 @@ static int vidioc_s_ctrl(struct file *fi
 	mutex_lock(&dev->lock);
 
 	if (dev->board.has_msp34xx)
-		em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
 	else {
 		rc = 1;
 		for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
@@ -1049,7 +1061,7 @@ static int vidioc_s_ctrl(struct file *fi
 
 	/* Control not found - try to send it to the attached devices */
 	if (rc == 1) {
-		em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
 		rc = 0;
 	}
 
@@ -1074,10 +1086,9 @@ static int vidioc_g_tuner(struct file *f
 	strcpy(t->name, "Tuner");
 
 	mutex_lock(&dev->lock);
-
-	em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
 	mutex_unlock(&dev->lock);
+
 	return 0;
 }
 
@@ -1096,10 +1107,9 @@ static int vidioc_s_tuner(struct file *f
 		return -EINVAL;
 
 	mutex_lock(&dev->lock);
-
-	em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
-
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
 	mutex_unlock(&dev->lock);
+
 	return 0;
 }
 
@@ -1139,7 +1149,7 @@ static int vidioc_s_frequency(struct fil
 	mutex_lock(&dev->lock);
 
 	dev->ctl_freq = f->frequency;
-	em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
 
 	mutex_unlock(&dev->lock);
 
@@ -1168,7 +1178,7 @@ static int vidioc_g_chip_ident(struct fi
 	chip->ident = V4L2_IDENT_NONE;
 	chip->revision = 0;
 
-	em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
 
 	return 0;
 }
@@ -1193,7 +1203,7 @@ static int vidioc_g_register(struct file
 		reg->size = 1;
 		return 0;
 	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
 		return 0;
 	case V4L2_CHIP_MATCH_I2C_ADDR:
 		/* Not supported yet */
@@ -1245,7 +1255,7 @@ static int vidioc_s_register(struct file
 
 		return rc;
 	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
 		return 0;
 	case V4L2_CHIP_MATCH_I2C_ADDR:
 		/* Not supported yet */
@@ -1345,7 +1355,7 @@ static int vidioc_querycap(struct file *
 
 	strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
 	strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
-	strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
 	cap->version = EM28XX_VERSION_CODE;
 
@@ -1388,13 +1398,13 @@ static int vidioc_g_fmt_sliced_vbi_cap(s
 	mutex_lock(&dev->lock);
 
 	f->fmt.sliced.service_set = 0;
-
-	em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
 
 	if (f->fmt.sliced.service_set == 0)
 		rc = -EINVAL;
 
 	mutex_unlock(&dev->lock);
+
 	return rc;
 }
 
@@ -1410,7 +1420,7 @@ static int vidioc_try_set_sliced_vbi_cap
 		return rc;
 
 	mutex_lock(&dev->lock);
-	em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
 	mutex_unlock(&dev->lock);
 
 	if (f->fmt.sliced.service_set == 0)
@@ -1431,7 +1441,7 @@ static int vidioc_reqbufs(struct file *f
 	if (rc < 0)
 		return rc;
 
-	return (videobuf_reqbufs(&fh->vb_vidq, rb));
+	return videobuf_reqbufs(&fh->vb_vidq, rb);
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
@@ -1445,7 +1455,7 @@ static int vidioc_querybuf(struct file *
 	if (rc < 0)
 		return rc;
 
-	return (videobuf_querybuf(&fh->vb_vidq, b));
+	return videobuf_querybuf(&fh->vb_vidq, b);
 }
 
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1458,7 +1468,7 @@ static int vidioc_qbuf(struct file *file
 	if (rc < 0)
 		return rc;
 
-	return (videobuf_qbuf(&fh->vb_vidq, b));
+	return videobuf_qbuf(&fh->vb_vidq, b);
 }
 
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1471,8 +1481,7 @@ static int vidioc_dqbuf(struct file *fil
 	if (rc < 0)
 		return rc;
 
-	return (videobuf_dqbuf(&fh->vb_vidq, b,
-				file->f_flags & O_NONBLOCK));
+	return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
 }
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1496,7 +1505,7 @@ static int radio_querycap(struct file *f
 
 	strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
 	strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
-	strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 
 	cap->version = EM28XX_VERSION_CODE;
 	cap->capabilities = V4L2_CAP_TUNER;
@@ -1515,7 +1524,7 @@ static int radio_g_tuner(struct file *fi
 	t->type = V4L2_TUNER_RADIO;
 
 	mutex_lock(&dev->lock);
-	em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
 	mutex_unlock(&dev->lock);
 
 	return 0;
@@ -1550,7 +1559,7 @@ static int radio_s_tuner(struct file *fi
 		return -EINVAL;
 
 	mutex_lock(&dev->lock);
-	em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
 	mutex_unlock(&dev->lock);
 
 	return 0;
@@ -1638,7 +1647,7 @@ static int em28xx_v4l2_open(struct file
 	}
 	if (fh->radio) {
 		em28xx_videodbg("video_open: setting radio device\n");
-		em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
 	}
 
 	dev->users++;
@@ -1721,7 +1730,7 @@ static int em28xx_v4l2_close(struct file
 		}
 
 		/* Save some power by putting tuner to sleep */
-		em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
 
 		/* do this before setting alternate! */
 		em28xx_uninit_isoc(dev);
@@ -1781,7 +1790,7 @@ em28xx_v4l2_read(struct file *filp, char
  * em28xx_v4l2_poll()
  * will allocate buffers when called for the first time
  */
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
 {
 	struct em28xx_fh *fh = filp->private_data;
 	struct em28xx *dev = fh->dev;
@@ -1934,19 +1943,20 @@ static struct video_device em28xx_radio_
 
 
 static struct video_device *em28xx_vdev_init(struct em28xx *dev,
-					     const struct video_device *template,
-					     const char *type_name)
+					const struct video_device *template,
+					const char *type_name)
 {
 	struct video_device *vfd;
 
 	vfd = video_device_alloc();
 	if (NULL == vfd)
 		return NULL;
-	*vfd = *template;
-	vfd->minor   = -1;
-	vfd->parent = &dev->udev->dev;
-	vfd->release = video_device_release;
-	vfd->debug = video_debug;
+
+	*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);
@@ -1984,8 +1994,9 @@ int em28xx_register_analog_devices(struc
 	/* enable vbi capturing */
 
 /*	em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-       val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
-       em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
+	val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+	em28xx_write_reg(dev, EM28XX_R0F_XCLK,
+			 (EM28XX_XCLK_AUDIO_UNMUTE | val));
 	em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
 	em28xx_set_outfmt(dev);
@@ -2020,7 +2031,8 @@ int em28xx_register_analog_devices(struc
 	}
 
 	if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
-		dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
+		dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
+						  "radio");
 		if (!dev->radio_dev) {
 			em28xx_errdev("cannot allocate video_device.\n");
 			return -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/conex.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/conex.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/conex.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/conex.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,8 +36,12 @@ struct sd {
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
+	u8 quality;
+#define QUALITY_MIN 30
+#define QUALITY_MAX 60
+#define QUALITY_DEF 40
 
-	unsigned char qindex;
+	u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -815,14 +819,13 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 
-	sd->qindex = 0;			/* set the quantization */
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
+	sd->quality = QUALITY_DEF;
 	return 0;
 }
 
@@ -839,6 +842,14 @@ static int sd_init(struct gspca_dev *gsp
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x22);		/* JPEG 411 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	cx11646_initsize(gspca_dev);
 	cx11646_fw(gspca_dev);
 	cx_sensor(gspca_dev);
@@ -849,8 +860,11 @@ static int sd_start(struct gspca_dev *gs
 /* called on streamoff with alt 0 and on disconnect */
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	int retry = 50;
 
+	kfree(sd->jpeg_hdr);
+
 	if (!gspca_dev->present)
 		return;
 	reg_w_val(gspca_dev, 0x0000, 0x00);
@@ -876,6 +890,8 @@ static void sd_pkt_scan(struct gspca_dev
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
 	if (data[0] == 0xff && data[1] == 0xd8) {
 
 		/* start of frame */
@@ -883,9 +899,8 @@ static void sd_pkt_scan(struct gspca_dev
 					data, 0);
 
 		/* put the JPEG header in the new frame */
-		jpeg_put_header(gspca_dev, frame,
-				((struct sd *) gspca_dev)->qindex,
-				0x22);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
 		data += 2;
 		len -= 2;
 	}
@@ -988,6 +1003,34 @@ static int sd_getcolors(struct gspca_dev
 	return 0;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -998,6 +1041,8 @@ static struct sd_desc sd_desc = {
 	.start = sd_start,
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -1029,8 +1074,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/etoms.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/etoms.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/etoms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/etoms.c	2009-06-09 23:05:27.000000000 -0400
@@ -472,19 +472,6 @@ static void setbrightness(struct gspca_d
 		reg_w_val(gspca_dev, ET_O_RED + i, brightness);
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int i;
-	int brightness = 0;
-
-	for (i = 0; i < 4; i++) {
-		reg_r(gspca_dev, ET_O_RED + i, 1);
-		brightness += gspca_dev->usb_buf[0];
-	}
-	sd->brightness = brightness >> 3;
-}
-
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev
 	reg_w(gspca_dev, ET_G_RED, RGBG, 6);
 }
 
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int i;
-	int contrast = 0;
-
-	for (i = 0; i < 4; i++) {
-		reg_r(gspca_dev, ET_G_RED + i, 1);
-		contrast += gspca_dev->usb_buf[0];
-	}
-	sd->contrast = contrast >> 2;
-}
-
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -658,7 +632,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 1;
 	sd->sensor = id->driver_info;
 	if (sd->sensor == SENSOR_PAS106) {
 		cam->cam_mode = sif_mode;
@@ -821,7 +794,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -840,7 +812,6 @@ static int sd_getcontrast(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcontrast(gspca_dev);
 	*val = sd->contrast;
 	return 0;
 }
@@ -859,7 +830,6 @@ static int sd_getcolors(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcolors(gspca_dev);
 	*val = sd->colors;
 	return 0;
 }
@@ -928,8 +898,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/finepix.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/finepix.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/finepix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/finepix.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Fujifilm FinePix USB
 MODULE_LICENSE("GPL");
 
 /* Default timeout, in ms */
-#define FPIX_TIMEOUT (HZ / 10)
+#define FPIX_TIMEOUT 250
 
 /* Maximum transfer size to use. The windows driver reads by chunks of
  * 0x2000 bytes, so do the same. Note: reading more seems to work
@@ -38,38 +38,15 @@ MODULE_LICENSE("GPL");
 struct usb_fpix {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	/*
-	 * USB stuff
-	 */
-	struct usb_ctrlrequest ctrlreq;
-	struct urb *control_urb;
-	struct timer_list bulk_timer;
-
-	enum {
-		FPIX_NOP,	/* inactive, else streaming */
-		FPIX_RESET,	/* must reset */
-		FPIX_REQ_FRAME,	/* requesting a frame */
-		FPIX_READ_FRAME,	/* reading frame */
-	} state;
-
-	/*
-	 * Driver stuff
-	 */
-	struct delayed_work wqe;
-	struct completion can_close;
-	int streaming;
+	struct work_struct work_struct;
+	struct workqueue_struct *work_thread;
 };
 
 /* Delay after which claim the next frame. If the delay is too small,
  * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
- * will fail every 4 or 5 frames, but 30ms is perfect. */
-#define NEXT_FRAME_DELAY  (((HZ * 30) + 999) / 1000)
-
-#define dev_new_state(new_state) {				\
-		PDEBUG(D_STREAM, "new state from %d to %d at %s:%d",	\
-			dev->state, new_state, __func__, __LINE__);	\
-		dev->state = new_state;					\
-}
+ * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
+ * 30ms is bad while 35ms is perfect. */
+#define NEXT_FRAME_DELAY 35
 
 /* These cameras only support 320x200. */
 static const struct v4l2_pix_format fpix_mode[1] = {
@@ -80,316 +57,183 @@ static const struct v4l2_pix_format fpix
 		.priv = 0}
 };
 
-/* Reads part of a frame */
-static void read_frame_part(struct usb_fpix *dev)
+/* send a command to the webcam */
+static int command(struct gspca_dev *gspca_dev,
+		int order)	/* 0: reset, 1: frame request */
 {
-	int ret;
-
-	PDEBUG(D_STREAM, "read_frame_part");
+	static u8 order_values[2][12] = {
+		{0xc6, 0, 0, 0, 0, 0, 0,    0, 0x20, 0, 0, 0},	/* reset */
+		{0xd3, 0, 0, 0, 0, 0, 0, 0x01,    0, 0, 0, 0},	/* fr req */
+	};
 
-	/* Reads part of a frame */
-	ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC);
-	if (ret) {
-		dev_new_state(FPIX_RESET);
-		schedule_delayed_work(&dev->wqe, 1);
-		PDEBUG(D_STREAM, "usb_submit_urb failed with %d",
-			ret);
-	} else {
-		/* Sometimes we never get a callback, so use a timer.
-		 * Is this masking a bug somewhere else? */
-		dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150);
-		add_timer(&dev->bulk_timer);
-	}
+	memcpy(gspca_dev->usb_buf, order_values[order], 12);
+	return usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			USB_REQ_GET_STATUS,
+			USB_DIR_OUT | USB_TYPE_CLASS |
+			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
+			12, FPIX_TIMEOUT);
 }
 
-/* Callback for URBs. */
-static void urb_callback(struct urb *urb)
+/* workqueue */
+static void dostream(struct work_struct *work)
 {
-	struct gspca_dev *gspca_dev = urb->context;
-	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
-	PDEBUG(D_PACK,
-		"enter urb_callback - status=%d, length=%d",
-		urb->status, urb->actual_length);
+	struct usb_fpix *dev = container_of(work, struct usb_fpix, 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;
 
-	if (dev->state == FPIX_READ_FRAME)
-		del_timer(&dev->bulk_timer);
+	/* synchronize with the main driver */
+	mutex_lock(&gspca_dev->usb_lock);
+	mutex_unlock(&gspca_dev->usb_lock);
+	PDEBUG(D_STREAM, "dostream started");
 
-	if (urb->status != 0) {
-		/* We kill a stuck urb every 50 frames on average, so don't
-		 * display a log message for that. */
-		if (urb->status != -ECONNRESET)
-			PDEBUG(D_STREAM, "bad URB status %d", urb->status);
-		dev_new_state(FPIX_RESET);
-		schedule_delayed_work(&dev->wqe, 1);
-	}
+	/* loop reading a frame */
+again:
+	while (gspca_dev->present && gspca_dev->streaming) {
 
-	switch (dev->state) {
-	case FPIX_REQ_FRAME:
-		dev_new_state(FPIX_READ_FRAME);
-		read_frame_part(dev);
-		break;
+		/* request a frame */
+		mutex_lock(&gspca_dev->usb_lock);
+		ret = command(gspca_dev, 1);
+		mutex_unlock(&gspca_dev->usb_lock);
+		if (ret < 0)
+			break;
+		if (!gspca_dev->present || !gspca_dev->streaming)
+			break;
 
-	case FPIX_READ_FRAME: {
-		unsigned char *data = urb->transfer_buffer;
-		struct gspca_frame *frame;
+		/* the frame comes in parts */
+		for (;;) {
+			ret = usb_bulk_msg(gspca_dev->dev,
+					urb->pipe,
+					data,
+					FPIX_MAX_TRANSFER,
+					&len, FPIX_TIMEOUT);
+			if (ret < 0) {
+				/* Most of the time we get a timeout
+				 * error. Just restart. */
+				goto 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;
 
-		frame = gspca_get_i_frame(&dev->gspca_dev);
-		if (frame == NULL)
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-		if (urb->actual_length < FPIX_MAX_TRANSFER ||
-			(data[urb->actual_length-2] == 0xff &&
-				data[urb->actual_length-1] == 0xd9)) {
+			if (len < FPIX_MAX_TRANSFER ||
+				(data[len - 2] == 0xff &&
+					data[len - 1] == 0xd9)) {
 
-			/* If the result is less than what was asked
-			 * for, then it's the end of the
-			 * frame. Sometime the jpeg is not complete,
-			 * 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)
-				gspca_frame_add(gspca_dev, LAST_PACKET,
-						frame,
-						data, urb->actual_length);
-			dev_new_state(FPIX_REQ_FRAME);
-			schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY);
-		} else {
+				/* If the result is less than what was asked
+				 * for, then it's the end of the
+				 * frame. Sometimes the jpeg is not complete,
+				 * 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);
+				break;
+			}
 
 			/* got a partial image */
 			if (frame)
 				gspca_frame_add(gspca_dev,
 						gspca_dev->last_packet_type
-								== LAST_PACKET
+							== LAST_PACKET
 						? FIRST_PACKET : INTER_PACKET,
-						frame,
-					data, urb->actual_length);
-			read_frame_part(dev);
+						frame, data, len);
 		}
-		break;
-	    }
-
-	case FPIX_NOP:
-	case FPIX_RESET:
-		PDEBUG(D_STREAM, "invalid state %d", dev->state);
-		break;
-	}
-}
-
-/* Request a new frame */
-static void request_frame(struct usb_fpix *dev)
-{
-	int ret;
-	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-
-	/* Setup command packet */
-	memset(gspca_dev->usb_buf, 0, 12);
-	gspca_dev->usb_buf[0] = 0xd3;
-	gspca_dev->usb_buf[7] = 0x01;
-
-	/* Request a frame */
-	dev->ctrlreq.bRequestType =
-		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
-	dev->ctrlreq.bRequest = USB_REQ_GET_STATUS;
-	dev->ctrlreq.wValue = 0;
-	dev->ctrlreq.wIndex = 0;
-	dev->ctrlreq.wLength = cpu_to_le16(12);
 
-	usb_fill_control_urb(dev->control_urb,
-			     gspca_dev->dev,
-			     usb_sndctrlpipe(gspca_dev->dev, 0),
-			     (unsigned char *) &dev->ctrlreq,
-			     gspca_dev->usb_buf,
-			     12, urb_callback, gspca_dev);
-
-	ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC);
-	if (ret) {
-		dev_new_state(FPIX_RESET);
-		schedule_delayed_work(&dev->wqe, 1);
-		PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret);
-	}
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* State machine. */
-static void fpix_sm(struct work_struct *work)
-{
-	struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work);
-
-	PDEBUG(D_STREAM, "fpix_sm state %d", dev->state);
-
-	/* verify that the device wasn't unplugged */
-	if (!dev->gspca_dev.present) {
-		PDEBUG(D_STREAM, "device is gone");
-		dev_new_state(FPIX_NOP);
-		complete(&dev->can_close);
-		return;
-	}
-
-	if (!dev->streaming) {
-		PDEBUG(D_STREAM, "stopping state machine");
-		dev_new_state(FPIX_NOP);
-		complete(&dev->can_close);
-		return;
+		/* We must wait before trying reading the next
+		 * frame. If we don't, or if the delay is too short,
+		 * the camera will disconnect. */
+		msleep(NEXT_FRAME_DELAY);
 	}
 
-	switch (dev->state) {
-	case FPIX_RESET:
-		dev_new_state(FPIX_REQ_FRAME);
-		schedule_delayed_work(&dev->wqe, HZ / 10);
-		break;
-
-	case FPIX_REQ_FRAME:
-		/* get an image */
-		request_frame(dev);
-		break;
-
-	case FPIX_NOP:
-	case FPIX_READ_FRAME:
-		PDEBUG(D_STREAM, "invalid state %d", dev->state);
-		break;
-	}
+out:
+	PDEBUG(D_STREAM, "dostream stopped");
 }
 
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 		const struct usb_device_id *id)
 {
+	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
 	struct cam *cam = &gspca_dev->cam;
 
 	cam->cam_mode = fpix_mode;
 	cam->nmodes = 1;
-	cam->epaddr = 0x01;	/* todo: correct for all cams? */
 	cam->bulk_size = FPIX_MAX_TRANSFER;
 
-/*	gspca_dev->nbalt = 1;	 * use bulk transfer */
-	return 0;
-}
-
-/* Stop streaming and free the ressources allocated by sd_start. */
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
-	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
-	dev->streaming = 0;
-
-	/* Stop the state machine */
-	if (dev->state != FPIX_NOP)
-		wait_for_completion(&dev->can_close);
-}
-
-/* called on streamoff with alt 0 and disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
-	usb_free_urb(dev->control_urb);
-	dev->control_urb = NULL;
-}
-
-/* Kill an URB that hasn't completed. */
-static void timeout_kill(unsigned long data)
-{
-	struct urb *urb = (struct urb *) data;
+	INIT_WORK(&dev->work_struct, dostream);
 
-	usb_unlink_urb(urb);
+	return 0;
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
-	INIT_DELAYED_WORK(&dev->wqe, fpix_sm);
-
-	init_timer(&dev->bulk_timer);
-	dev->bulk_timer.function = timeout_kill;
-
 	return 0;
 }
 
+/* start the camera */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-	int ret;
-	int size_ret;
+	int ret, len;
 
 	/* Init the device */
-	memset(gspca_dev->usb_buf, 0, 12);
-	gspca_dev->usb_buf[0] = 0xc6;
-	gspca_dev->usb_buf[8] = 0x20;
-
-	ret = usb_control_msg(gspca_dev->dev,
-			usb_sndctrlpipe(gspca_dev->dev, 0),
-			USB_REQ_GET_STATUS,
-			USB_DIR_OUT | USB_TYPE_CLASS |
-			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
-			12, FPIX_TIMEOUT);
-
-	if (ret != 12) {
-		PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
-		ret = -EIO;
-		goto error;
+	ret = command(gspca_dev, 0);
+	if (ret < 0) {
+		PDEBUG(D_STREAM, "init failed %d", ret);
+		return ret;
 	}
 
 	/* Read the result of the command. Ignore the result, for it
 	 * varies with the device. */
 	ret = usb_bulk_msg(gspca_dev->dev,
-			usb_rcvbulkpipe(gspca_dev->dev,
-					gspca_dev->cam.epaddr),
-			gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
+			gspca_dev->urb[0]->pipe,
+			gspca_dev->urb[0]->transfer_buffer,
+			FPIX_MAX_TRANSFER, &len,
 			FPIX_TIMEOUT);
-	if (ret != 0) {
-		PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret);
-		ret = -EIO;
-		goto error;
+	if (ret < 0) {
+		PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret);
+		return ret;
 	}
 
 	/* Request a frame, but don't read it */
-	memset(gspca_dev->usb_buf, 0, 12);
-	gspca_dev->usb_buf[0] = 0xd3;
-	gspca_dev->usb_buf[7] = 0x01;
-
-	ret = usb_control_msg(gspca_dev->dev,
-			usb_sndctrlpipe(gspca_dev->dev, 0),
-			USB_REQ_GET_STATUS,
-			USB_DIR_OUT | USB_TYPE_CLASS |
-			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
-			12, FPIX_TIMEOUT);
-	if (ret != 12) {
-		PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
-		ret = -EIO;
-		goto error;
+	ret = command(gspca_dev, 1);
+	if (ret < 0) {
+		PDEBUG(D_STREAM, "frame request failed %d", ret);
+		return ret;
 	}
 
 	/* Again, reset bulk in endpoint */
-	usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
-	/* Allocate a control URB */
-	dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!dev->control_urb) {
-		PDEBUG(D_STREAM, "No free urbs available");
-		ret = -EIO;
-		goto error;
-	}
-
-	/* Various initializations. */
-	init_completion(&dev->can_close);
-	dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0];
-	dev->gspca_dev.urb[0]->complete = urb_callback;
-	dev->streaming = 1;
+	usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
 
-	/* Schedule a frame request. */
-	dev_new_state(FPIX_REQ_FRAME);
-	schedule_delayed_work(&dev->wqe, 1);
+	/* Start the workqueue function to do the streaming */
+	dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+	queue_work(dev->work_thread, &dev->work_struct);
 
 	return 0;
+}
 
-error:
-	/* Free the ressources */
-	sd_stopN(gspca_dev);
-	sd_stop0(gspca_dev);
-	return ret;
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
+
+	/* wait for the work queue to terminate */
+	mutex_unlock(&gspca_dev->usb_lock);
+	destroy_workqueue(dev->work_thread);
+	mutex_lock(&gspca_dev->usb_lock);
+	dev->work_thread = NULL;
 }
 
 /* Table of supported USB devices */
@@ -424,12 +268,11 @@ MODULE_DEVICE_TABLE(usb, device_table);
 
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
-	.name = MODULE_NAME,
+	.name   = MODULE_NAME,
 	.config = sd_config,
-	.init = sd_init,
-	.start = sd_start,
-	.stopN = sd_stopN,
-	.stop0 = sd_stop0,
+	.init   = sd_init,
+	.start  = sd_start,
+	.stop0  = sd_stop0,
 };
 
 /* -- device connect -- */
@@ -443,24 +286,28 @@ static int sd_probe(struct usb_interface
 }
 
 static struct usb_driver sd_driver = {
-	.name = MODULE_NAME,
-	.id_table = device_table,
-	.probe = sd_probe,
+	.name       = MODULE_NAME,
+	.id_table   = device_table,
+	.probe      = sd_probe,
 	.disconnect = gspca_disconnect,
 #ifdef CONFIG_PM
 	.suspend = gspca_suspend,
-	.resume = gspca_resume,
+	.resume  = gspca_resume,
 #endif
 };
 
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/gspca.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/gspca.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/gspca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/gspca.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,15 +38,16 @@
 #include "gspca.h"
 
 /* global values */
-#define DEF_NURBS 2		/* default number of URBs */
+#define DEF_NURBS 3		/* default number of URBs */
+#if DEF_NURBS > MAX_NURBS
+#error "DEF_NURBS too big"
+#endif
 
 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 4, 0)
-
-static int video_nr = -1;
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 5, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -126,16 +127,18 @@ static void fill_frame(struct gspca_dev
 			struct urb *urb)
 {
 	struct gspca_frame *frame;
-	__u8 *data;		/* address of data in the iso message */
+	u8 *data;		/* address of data in the iso message */
 	int i, len, st;
 	cam_pkt_op pkt_scan;
 
 	if (urb->status != 0) {
+		if (urb->status == -ESHUTDOWN)
+			return;		/* disconnection */
 #ifdef CONFIG_PM
 		if (!gspca_dev->frozen)
 #endif
 			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;		/* disconnection ? */
+		return;
 	}
 	pkt_scan = gspca_dev->sd_desc->pkt_scan;
 	for (i = 0; i < urb->number_of_packets; i++) {
@@ -166,7 +169,7 @@ static void fill_frame(struct gspca_dev
 		/* let the packet be analyzed by the subdriver */
 		PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
 			i, urb->iso_frame_desc[i].offset, len);
-		data = (__u8 *) urb->transfer_buffer
+		data = (u8 *) urb->transfer_buffer
 					+ urb->iso_frame_desc[i].offset;
 		pkt_scan(gspca_dev, frame, data, len);
 	}
@@ -182,8 +185,7 @@ static void fill_frame(struct gspca_dev
  *
  * Analyse each packet and call the subdriver for copy to the frame buffer.
  */
-static void isoc_irq(struct urb *urb
-)
+static void isoc_irq(struct urb *urb)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
 
@@ -196,8 +198,7 @@ static void isoc_irq(struct urb *urb
 /*
  * bulk message interrupt from the USB device
  */
-static void bulk_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;
@@ -209,6 +210,8 @@ static void bulk_irq(struct urb *urb
 	switch (urb->status) {
 	case 0:
 		break;
+	case -ESHUTDOWN:
+		return;		/* disconnection */
 	case -ECONNRESET:
 		urb->status = 0;
 		break;
@@ -217,7 +220,7 @@ static void bulk_irq(struct urb *urb
 		if (!gspca_dev->frozen)
 #endif
 			PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
-		return;		/* disconnection ? */
+		return;
 	}
 
 	/* check the availability of the frame buffer */
@@ -322,6 +325,7 @@ static int gspca_is_compressed(__u32 for
 	case V4L2_PIX_FMT_JPEG:
 	case V4L2_PIX_FMT_SPCA561:
 	case V4L2_PIX_FMT_PAC207:
+	case V4L2_PIX_FMT_MR97310A:
 		return 1;
 	}
 	return 0;
@@ -422,10 +426,8 @@ static void destroy_urbs(struct gspca_de
 		if (urb == NULL)
 			break;
 
-		BUG_ON(!gspca_dev->dev);
 		gspca_dev->urb[i] = NULL;
-		if (!gspca_dev->present)
-			usb_kill_urb(urb);
+		usb_kill_urb(urb);
 		if (urb->transfer_buffer != NULL)
 			usb_buffer_free(gspca_dev->dev,
 					urb->transfer_buffer_length,
@@ -439,22 +441,16 @@ static void destroy_urbs(struct gspca_de
  * look for an input transfer endpoint in an alternate setting
  */
 static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
-					  __u8 epaddr,
 					  __u8 xfer)
 {
 	struct usb_host_endpoint *ep;
 	int i, attr;
 
-	epaddr |= USB_DIR_IN;
 	for (i = 0; i < alt->desc.bNumEndpoints; i++) {
 		ep = &alt->endpoint[i];
-		if (ep->desc.bEndpointAddress == epaddr) {
-			attr = ep->desc.bmAttributes
-						& USB_ENDPOINT_XFERTYPE_MASK;
-			if (attr == xfer)
-				return ep;
-			break;
-		}
+		attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+		if (attr == xfer)
+			return ep;
 	}
 	return NULL;
 }
@@ -478,23 +474,23 @@ static struct usb_host_endpoint *get_ep(
 	i = gspca_dev->alt;			/* previous alt setting */
 
 	/* try isoc */
-	while (--i > 0) {			/* alt 0 is unusable */
+	while (--i >= 0) {
 		ep = alt_xfer(&intf->altsetting[i],
-				gspca_dev->cam.epaddr,
 				USB_ENDPOINT_XFER_ISOC);
 		if (ep)
 			break;
 	}
 
-	/* if no isoc, try bulk */
+	/* if no isoc, try bulk (alt 0 only) */
 	if (ep == NULL) {
 		ep = alt_xfer(&intf->altsetting[0],
-				gspca_dev->cam.epaddr,
 				USB_ENDPOINT_XFER_BULK);
 		if (ep == NULL) {
 			err("no transfer endpoint found");
 			return NULL;
 		}
+		i = 0;
+		gspca_dev->bulk = 1;
 	}
 	PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
 			i, ep->desc.bEndpointAddress);
@@ -521,7 +517,7 @@ static int create_urbs(struct gspca_dev
 	/* calculate the packet size and the number of packets */
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize);
 
-	if (gspca_dev->alt != 0) {		/* isoc */
+	if (!gspca_dev->bulk) {			/* isoc */
 
 		/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
 		psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -601,6 +597,11 @@ static int gspca_init_transfer(struct gs
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
 
+	if (!gspca_dev->present) {
+		ret = -ENODEV;
+		goto out;
+	}
+
 	/* set the higher alternate setting and
 	 * loop until urb submit succeeds */
 	gspca_dev->alt = gspca_dev->nbalt;
@@ -616,10 +617,9 @@ static int gspca_init_transfer(struct gs
 			goto out;
 
 		/* clear the bulk endpoint */
-		if (gspca_dev->alt == 0)	/* if bulk transfer */
+		if (gspca_dev->bulk)
 			usb_clear_halt(gspca_dev->dev,
-					usb_rcvintpipe(gspca_dev->dev,
-						 gspca_dev->cam.epaddr));
+					gspca_dev->urb[0]->pipe);
 
 		/* start the cam */
 		ret = gspca_dev->sd_desc->start(gspca_dev);
@@ -630,7 +630,7 @@ static int gspca_init_transfer(struct gs
 		gspca_dev->streaming = 1;
 
 		/* some bulk transfers are started by the subdriver */
-		if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
+		if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
 			break;
 
 		/* submit the URBs */
@@ -671,11 +671,14 @@ static int gspca_set_alt0(struct gspca_d
 static void gspca_stream_off(struct gspca_dev *gspca_dev)
 {
 	gspca_dev->streaming = 0;
-	if (gspca_dev->present
-	    && gspca_dev->sd_desc->stopN)
-		gspca_dev->sd_desc->stopN(gspca_dev);
-	destroy_urbs(gspca_dev);
-	gspca_set_alt0(gspca_dev);
+	if (gspca_dev->present) {
+		if (gspca_dev->sd_desc->stopN)
+			gspca_dev->sd_desc->stopN(gspca_dev);
+		destroy_urbs(gspca_dev);
+		gspca_set_alt0(gspca_dev);
+	}
+
+	/* always call stop0 to free the subdriver's resources */
 	if (gspca_dev->sd_desc->stop0)
 		gspca_dev->sd_desc->stop0(gspca_dev);
 	PDEBUG(D_STREAM, "stream off OK");
@@ -762,7 +765,6 @@ static int vidioc_enum_fmt_vid_cap(struc
 	fmtdesc->pixelformat = fmt_tb[index];
 	if (gspca_is_compressed(fmt_tb[index]))
 		fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
-	fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
 	fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
 	fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
@@ -957,8 +959,15 @@ static int vidioc_querycap(struct file *
 			   struct v4l2_capability *cap)
 {
 	struct gspca_dev *gspca_dev = priv;
+	int ret;
 
-	memset(cap, 0, sizeof *cap);
+	/* protect the access to the usb device */
+	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+		return -ERESTARTSYS;
+	if (!gspca_dev->present) {
+		ret = -ENODEV;
+		goto out;
+	}
 	strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
 	if (gspca_dev->dev->product != NULL) {
 		strncpy(cap->card, gspca_dev->dev->product,
@@ -969,13 +978,15 @@ static int vidioc_querycap(struct file *
 			le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
 			le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
 	}
-	strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
-		sizeof cap->bus_info);
+	usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
 	cap->version = DRIVER_VERSION_NUMBER;
 	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
 			  | V4L2_CAP_STREAMING
 			  | V4L2_CAP_READWRITE;
-	return 0;
+	ret = 0;
+out:
+	mutex_unlock(&gspca_dev->usb_lock);
+	return ret;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
@@ -1038,7 +1049,10 @@ 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;
-		ret = ctrls->set(gspca_dev, ctrl->value);
+		if (gspca_dev->present)
+			ret = ctrls->set(gspca_dev, ctrl->value);
+		else
+			ret = -ENODEV;
 		mutex_unlock(&gspca_dev->usb_lock);
 		return ret;
 	}
@@ -1062,7 +1076,10 @@ static int vidioc_g_ctrl(struct file *fi
 			return -EINVAL;
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
-		ret = ctrls->get(gspca_dev, &ctrl->value);
+		if (gspca_dev->present)
+			ret = ctrls->get(gspca_dev, &ctrl->value);
+		else
+			ret = -ENODEV;
 		mutex_unlock(&gspca_dev->usb_lock);
 		return ret;
 	}
@@ -1081,7 +1098,6 @@ static int vidioc_s_audio(struct file *f
 static int vidioc_g_audio(struct file *file, void *priv,
 			 struct v4l2_audio *audio)
 {
-	memset(audio, 0, sizeof *audio);
 	strcpy(audio->name, "Microphone");
 	return 0;
 }
@@ -1115,8 +1131,8 @@ static int vidioc_enum_input(struct file
 
 	if (input->index != 0)
 		return -EINVAL;
-	memset(input, 0, sizeof *input);
 	input->type = V4L2_INPUT_TYPE_CAMERA;
+	input->status = gspca_dev->cam.input_flags;
 	strncpy(input->name, gspca_dev->sd_desc->name,
 		sizeof input->name);
 	return 0;
@@ -1224,10 +1240,7 @@ static int vidioc_streamon(struct file *
 		return -EINVAL;
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
-	if (!gspca_dev->present) {
-		ret = -ENODEV;
-		goto out;
-	}
+
 	if (gspca_dev->nframes == 0
 	    || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
 		ret = -EINVAL;
@@ -1295,7 +1308,10 @@ static int vidioc_g_jpegcomp(struct file
 		return -EINVAL;
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
-	ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+	if (gspca_dev->present)
+		ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+	else
+		ret = -ENODEV;
 	mutex_unlock(&gspca_dev->usb_lock);
 	return ret;
 }
@@ -1310,7 +1326,10 @@ static int vidioc_s_jpegcomp(struct file
 		return -EINVAL;
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
-	ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+	if (gspca_dev->present)
+		ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+	else
+		ret = -ENODEV;
 	mutex_unlock(&gspca_dev->usb_lock);
 	return ret;
 }
@@ -1320,8 +1339,6 @@ static int vidioc_g_parm(struct file *fi
 {
 	struct gspca_dev *gspca_dev = priv;
 
-	memset(parm, 0, sizeof *parm);
-	parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	parm->parm.capture.readbuffers = gspca_dev->nbufread;
 
 	if (gspca_dev->sd_desc->get_streamparm) {
@@ -1329,7 +1346,11 @@ static int vidioc_g_parm(struct file *fi
 
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
-		ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+		if (gspca_dev->present)
+			ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
+								 parm);
+		else
+			ret = -ENODEV;
 		mutex_unlock(&gspca_dev->usb_lock);
 		return ret;
 	}
@@ -1354,7 +1375,11 @@ static int vidioc_s_parm(struct file *fi
 
 		if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 			return -ERESTARTSYS;
-		ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+		if (gspca_dev->present)
+			ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
+								 parm);
+		else
+			ret = -ENODEV;
 		mutex_unlock(&gspca_dev->usb_lock);
 		return ret;
 	}
@@ -1382,7 +1407,6 @@ static int vidiocgmbuf(struct file *file
 		{
 			struct v4l2_format fmt;
 
-			memset(&fmt, 0, sizeof fmt);
 			fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 			i = gspca_dev->cam.nmodes - 1;	/* highest mode */
 			fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
@@ -1528,7 +1552,8 @@ static int frame_wait(struct gspca_dev *
 
 	if (gspca_dev->sd_desc->dq_callback) {
 		mutex_lock(&gspca_dev->usb_lock);
-		gspca_dev->sd_desc->dq_callback(gspca_dev);
+		if (gspca_dev->present)
+			gspca_dev->sd_desc->dq_callback(gspca_dev);
 		mutex_unlock(&gspca_dev->usb_lock);
 	}
 	return j;
@@ -1550,6 +1575,9 @@ static int vidioc_dqbuf(struct file *fil
 	if (v4l2_buf->memory != gspca_dev->memory)
 		return -EINVAL;
 
+	if (!gspca_dev->present)
+		return -ENODEV;
+
 	/* if not streaming, be sure the application will not loop forever */
 	if (!(file->f_flags & O_NONBLOCK)
 	    && !gspca_dev->streaming && gspca_dev->users == 1)
@@ -1700,8 +1728,6 @@ static unsigned int dev_poll(struct file
 	PDEBUG(D_FRAM, "poll");
 
 	poll_wait(file, &gspca_dev->wq, wait);
-	if (!gspca_dev->present)
-		return POLLERR;
 
 	/* if reqbufs is not done, the user would use read() */
 	if (gspca_dev->nframes == 0) {
@@ -1714,10 +1740,6 @@ static unsigned int dev_poll(struct file
 
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
 		return POLLERR;
-	if (!gspca_dev->present) {
-		ret = POLLERR;
-		goto out;
-	}
 
 	/* check the next incoming buffer */
 	i = gspca_dev->fr_o;
@@ -1726,8 +1748,9 @@ static unsigned int dev_poll(struct file
 		ret = POLLIN | POLLRDNORM;	/* something to read */
 	else
 		ret = 0;
-out:
 	mutex_unlock(&gspca_dev->queue_lock);
+	if (!gspca_dev->present)
+		return POLLHUP;
 	return ret;
 }
 
@@ -1925,7 +1948,7 @@ int gspca_dev_probe(struct usb_interface
 	gspca_dev->present = 1;
 	ret = video_register_device(&gspca_dev->vdev,
 				  VFL_TYPE_GRABBER,
-				  video_nr);
+				  -1);
 	if (ret < 0) {
 		err("video_register_device err %d", ret);
 		goto out;
@@ -1953,10 +1976,16 @@ void gspca_disconnect(struct usb_interfa
 
 	mutex_lock(&gspca_dev->usb_lock);
 	gspca_dev->present = 0;
-	mutex_unlock(&gspca_dev->usb_lock);
 
-	destroy_urbs(gspca_dev);
+	if (gspca_dev->streaming) {
+		destroy_urbs(gspca_dev);
+		wake_up_interruptible(&gspca_dev->wq);
+	}
+
+	/* the device is freed at exit of this function */
 	gspca_dev->dev = NULL;
+	mutex_unlock(&gspca_dev->usb_lock);
+
 	usb_set_intfdata(intf, NULL);
 
 	/* release the device */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/gspca.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/gspca.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/gspca.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/gspca.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,19 +33,13 @@ extern int gspca_debug;
 #endif
 #undef err
 #define err(fmt, args...) \
-	do {\
-		printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
-	} while (0)
+	printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args)
 #undef info
 #define info(fmt, args...) \
-	do {\
-		printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
-	} while (0)
+	printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args)
 #undef warn
 #define warn(fmt, args...) \
-	do {\
-		printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
-	} while (0)
+	printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args)
 
 #define GSPCA_MAX_FRAMES 16	/* maximum number of video frame buffers */
 /* image transfers */
@@ -62,7 +56,7 @@ struct cam {
 				 * - cannot be > MAX_NURBS
 				 * - when 0 and bulk_size != 0 means
 				 *   1 URB and submit done by subdriver */
-	__u8 epaddr;
+	u32 input_flags;	/* value for ENUM_INPUT status flags */
 };
 
 struct gspca_dev;
@@ -174,6 +168,7 @@ struct gspca_dev {
 	__u8 iface;			/* USB interface number */
 	__u8 alt;			/* USB alternate setting */
 	__u8 nbalt;			/* number of USB alternate settings */
+	u8 bulk;			/* image transfer by 0:isoc / 1:bulk */
 };
 
 int gspca_dev_probe(struct usb_interface *intf,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/jpeg.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/jpeg.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/jpeg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/jpeg.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,171 +24,39 @@
  *
  */
 
-/* start of jpeg frame + quantization table */
-static const unsigned char quant[][0x88] = {
-/* index 0 - Q40*/
-    {
+/*
+ * generation options
+ *	CONEX_CAM	Conexant if present
+ */
+
+/* JPEG header */
+static const u8 jpeg_head[] = {
 	0xff, 0xd8,			/* jpeg */
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,					/* quantization table part 1 */
-     20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
-     33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
-     70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
-     109,
-     119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
-     126, 129, 124,
-1,					/* quantization table part 2 */
-     21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
-     124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
-     124, 124, 124,
-     124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
-     124, 124, 124,
-     124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
-     124, 124, 124},
-/* index 1 - Q50 */
-    {
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-     16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
-     26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
-     56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
-     95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
-     103, 99,
-1,
-    17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
-/* index 2 Q60 */
-    {
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-     13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
-     21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
-     45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
-     76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
-1,
-     14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
-     79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
-     79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
-     79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
-/* index 3 - Q70 */
-    {
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-     10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
-     16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
-     34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
-     57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
-1,
-     10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
-     59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
-     59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
-     59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
-/* index 4 - Q80 */
-    {
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-      6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
-     10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
-     22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
-     38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
-1,
-      7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
-     40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
-     40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
-     40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
-/* index 5 - Q85 */
-    {
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-     5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
-     8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
-     17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
-     29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
-1,
-     5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
-     30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
-     30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
-     30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
-/* index 6 - 86 */
-{
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-	0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
-	0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
-	0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
-	0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
-	0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
-	0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
-	0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
-	0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
-1,
-	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
-	0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
-	0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- },
-/* index 7 - 88 */
-{
-	0xff, 0xd8,
-	0xff, 0xdb, 0x00, 0x84,		/* DQT */
-0,
-	0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
-	0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
-	0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
-	0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
-	0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
-	0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
-	0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
-	0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
-1,
-	0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
-	0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-},
-/* index 8 - ?? */
-{
-	0xff, 0xd8,
+
+/* quantization table quality 50% */
 	0xff, 0xdb, 0x00, 0x84,		/* DQT */
 0,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
-	0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
-	0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
-	0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
-	0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
-	0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
-	0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+#define JPEG_QT0_OFFSET 7
+	0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+	0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+	0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+	0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+	0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+	0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+	0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+	0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
 1,
-	0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
-	0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
-}
-};
+#define JPEG_QT1_OFFSET 72
+	0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+	0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
 
-/* huffman table + start of SOF0 */
-static unsigned char huffman[] = {
+/* huffman table */
 	0xff, 0xc4, 0x01, 0xa2,
 	0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
 	0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -244,58 +112,57 @@ static unsigned char huffman[] = {
 	0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
 #ifdef CONEX_CAM
 /* the Conexant frames start with SOF0 */
+#define JPEG_HDR_SZ 556
 #else
 	0xff, 0xc0, 0x00, 0x11,		/* SOF0 (start of frame 0 */
 	0x08,				/* data precision */
-#endif
-};
-
-#ifndef CONEX_CAM
-/* variable part:
- *	0x01, 0xe0,			 height
- *	0x02, 0x80,			 width
- *	0x03,				 component number
- *		0x01,
- *			0x21,			samples Y
- */
-
-/* end of header */
-static unsigned char eoh[] = {
+#define JPEG_HEIGHT_OFFSET 561
+	0x01, 0xe0,			/* height */
+	0x02, 0x80,			/* width */
+	0x03,				/* component number */
+		0x01,
+			0x21,		/* samples Y */
 			0x00,		/* quant Y */
 		0x02, 0x11, 0x01,	/* samples CbCr - quant CbCr */
 		0x03, 0x11, 0x01,
 
 	0xff, 0xda, 0x00, 0x0c,		/* SOS (start of scan) */
 	0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-};
+#define JPEG_HDR_SZ 589
 #endif
+};
 
-/* -- output the JPEG header -- */
-static void jpeg_put_header(struct gspca_dev *gspca_dev,
-			    struct gspca_frame *frame,
-			    int qindex,
-			    int samplesY)
+/* define the JPEG header */
+static void jpeg_define(u8 *jpeg_hdr,
+			int height,
+			int width,
+			int samplesY)
 {
+	memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
 #ifndef CONEX_CAM
-	unsigned char tmpbuf[8];
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
 #endif
+}
 
-	gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
-			(unsigned char *) quant[qindex], sizeof quant[0]);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			(unsigned char *) huffman, sizeof huffman);
-#ifndef CONEX_CAM
-	tmpbuf[0] = gspca_dev->height >> 8;
-	tmpbuf[1] = gspca_dev->height & 0xff;
-	tmpbuf[2] = gspca_dev->width >> 8;
-	tmpbuf[3] = gspca_dev->width & 0xff;
-	tmpbuf[4] = 0x03;		/* component number */
-	tmpbuf[5] = 0x01;		/* first component */
-	tmpbuf[6] = samplesY;
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			tmpbuf, 7);
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-			eoh, sizeof eoh);
-#endif
+/* set the JPEG quality */
+static void jpeg_set_qual(u8 *jpeg_hdr,
+			  int quality)
+{
+	int i, sc;
+
+	if (quality < 50)
+		sc = 5000 / quality;
+	else
+		sc = 200 - quality * 2;
+	for (i = 0; i < 64; i++) {
+		jpeg_hdr[JPEG_QT0_OFFSET + i] =
+			(jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+		jpeg_hdr[JPEG_QT1_OFFSET + i] =
+			(jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+	}
 }
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/gspca/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,15 @@ config USB_GSPCA_MARS
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_mars.
 
+config USB_GSPCA_MR97310A
+	tristate "Mars-Semi MR97310A USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the MR97310A chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_mr97310a.
+
 config USB_GSPCA_OV519
 	tristate "OV519 USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -167,6 +176,24 @@ config USB_GSPCA_SPCA561
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_spca561.
 
+config USB_GSPCA_SQ905
+	tristate "SQ Technologies SQ905 based USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the SQ905 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_sq905.
+
+config USB_GSPCA_SQ905C
+	tristate "SQ Technologies SQ905C based USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the SQ905C chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_sq905c.
+
 config USB_GSPCA_STK014
 	tristate "Syntek DV4000 (STK014) USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_bridge.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_bridge.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_bridge.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_bridge.h	2009-06-09 23:05:27.000000000 -0400
@@ -112,14 +112,14 @@ static const unsigned char sensor_urb_sk
 struct sd {
 	struct gspca_dev gspca_dev;
 
-	/* The name of the m5602 camera */
-	char *name;
-
 	/* A pointer to the currently connected sensor */
-	struct m5602_sensor *sensor;
+	const struct m5602_sensor *sensor;
 
 	struct sd_desc *desc;
 
+	/* Sensor private data */
+	void *sensor_priv;
+
 	/* The current frame's id, used to detect frame boundaries */
 	u8 frame_id;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_core.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,7 +51,7 @@ int m5602_read_bridge(struct sd *sd, u8
 	       address, *i2c_data);
 
 	/* usb_control_msg(...) returns the number of bytes sent upon success,
-	mask that and return zero upon success instead*/
+	mask that and return zero instead*/
 	return (err < 0) ? err : 0;
 }
 
@@ -76,7 +76,7 @@ int m5602_write_bridge(struct sd *sd, u8
 				4, M5602_URB_MSG_TIMEOUT);
 
 	/* usb_control_msg(...) returns the number of bytes sent upon success,
-	   mask that and return zero upon success instead */
+	   mask that and return zero instead */
 	return (err < 0) ? err : 0;
 }
 
@@ -92,29 +92,29 @@ int m5602_read_sensor(struct sd *sd, con
 		err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
 	} while ((*i2c_data & I2C_BUSY) && !err);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
 				 sd->sensor->i2c_slave_id);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
 	if (err < 0)
-		goto out;
+		return err;
 
 	if (sd->sensor->i2c_regW == 1) {
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len);
 		if (err < 0)
-			goto out;
+			return err;
 
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
 		if (err < 0)
-			goto out;
+			return err;
 	} else {
 		err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
 		if (err < 0)
-			goto out;
+			return err;
 	}
 
 	for (i = 0; (i < len) && !err; i++) {
@@ -123,7 +123,6 @@ int m5602_read_sensor(struct sd *sd, con
 		PDEBUG(D_CONF, "Reading sensor register "
 			       "0x%x containing 0x%x ", address, *i2c_data);
 	}
-out:
 	return err;
 }
 
@@ -310,7 +309,11 @@ static void m5602_urb_complete(struct gs
 
 static void m5602_stop_transfer(struct gspca_dev *gspca_dev)
 {
-	/* Is there are a command to stop a data transfer? */
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	/* Run the sensor specific end transfer sequence */
+	if (sd->sensor->stop)
+		sd->sensor->stop(sd);
 }
 
 /* sub-driver description, the ctrl and nctrl is filled at probe time */
@@ -332,7 +335,6 @@ static int m5602_configure(struct gspca_
 	int err;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
 	sd->desc = &sd_desc;
 
 	if (dump_bridge)
@@ -360,6 +362,17 @@ static int m5602_probe(struct usb_interf
 			       THIS_MODULE);
 }
 
+void m5602_disconnect(struct usb_interface *intf)
+{
+	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (sd->sensor->disconnect)
+		sd->sensor->disconnect(sd);
+
+	gspca_disconnect(intf);
+}
+
 static struct usb_driver sd_driver = {
 	.name = MODULE_NAME,
 	.id_table = m5602_table,
@@ -368,14 +381,16 @@ static struct usb_driver sd_driver = {
 	.suspend = gspca_suspend,
 	.resume = gspca_resume,
 #endif
-	.disconnect = gspca_disconnect
+	.disconnect = m5602_disconnect
 };
 
 /* -- module insert / remove -- */
 static int __init mod_m5602_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,61 @@
 
 #include "m5602_mt9m111.h"
 
+static struct v4l2_pix_format mt9m111_modes[] = {
+	{
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+const static struct ctrl mt9m111_ctrls[] = {
+	{
+		{
+			.id		= V4L2_CID_VFLIP,
+			.type           = V4L2_CTRL_TYPE_BOOLEAN,
+			.name           = "vertical flip",
+			.minimum        = 0,
+			.maximum        = 1,
+			.step           = 1,
+			.default_value  = 0
+		},
+		.set = mt9m111_set_vflip,
+		.get = mt9m111_get_vflip
+	}, {
+		{
+			.id             = V4L2_CID_HFLIP,
+			.type           = V4L2_CTRL_TYPE_BOOLEAN,
+			.name           = "horizontal flip",
+			.minimum        = 0,
+			.maximum        = 1,
+			.step           = 1,
+			.default_value  = 0
+		},
+		.set = mt9m111_set_hflip,
+		.get = mt9m111_get_hflip
+	}, {
+		{
+			.id             = V4L2_CID_GAIN,
+			.type           = V4L2_CTRL_TYPE_INTEGER,
+			.name           = "gain",
+			.minimum        = 0,
+			.maximum        = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
+			.step           = 1,
+			.default_value  = DEFAULT_GAIN,
+			.flags          = V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = mt9m111_set_gain,
+		.get = mt9m111_get_gain
+	}
+};
+
+
 static void mt9m111_dump_registers(struct sd *sd);
 
 int mt9m111_probe(struct sd *sd)
@@ -62,10 +117,10 @@ int mt9m111_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
-	sd->gspca_dev.cam.cam_mode = mt9m111.modes;
-	sd->gspca_dev.cam.nmodes = mt9m111.nmodes;
-	sd->desc->ctrls = mt9m111.ctrls;
-	sd->desc->nctrls = mt9m111.nctrls;
+	sd->gspca_dev.cam.cam_mode = mt9m111_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
+	sd->desc->ctrls = mt9m111_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
 	return 0;
 }
 
@@ -125,16 +180,15 @@ int mt9m111_set_vflip(struct gspca_dev *
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[0] = (data[0] & 0xfe) | val;
 	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 				   data, 2);
-out:
 	return err;
 }
 
@@ -163,16 +217,15 @@ int mt9m111_set_hflip(struct gspca_dev *
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
 	err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 					data, 2);
-out:
 	return err;
 }
 
@@ -204,7 +257,7 @@ int mt9m111_set_gain(struct gspca_dev *g
 	/* Set the correct page map */
 	err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
 		return -EINVAL;
@@ -229,7 +282,7 @@ int mt9m111_set_gain(struct gspca_dev *g
 
 	err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
 				   data, 2);
-out:
+
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_mt9m111.h	2009-06-09 23:05:27.000000000 -0400
@@ -94,7 +94,7 @@ int mt9m111_set_hflip(struct gspca_dev *
 int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor mt9m111 = {
+const static struct m5602_sensor mt9m111 = {
 	.name = "MT9M111",
 
 	.i2c_slave_id = 0xba,
@@ -102,64 +102,7 @@ static struct m5602_sensor mt9m111 = {
 
 	.probe = mt9m111_probe,
 	.init = mt9m111_init,
-	.power_down = mt9m111_power_down,
-
-	.nctrls = 3,
-	.ctrls = {
-	{
-		{
-			.id		= V4L2_CID_VFLIP,
-			.type           = V4L2_CTRL_TYPE_BOOLEAN,
-			.name           = "vertical flip",
-			.minimum        = 0,
-			.maximum        = 1,
-			.step           = 1,
-			.default_value  = 0
-		},
-		.set = mt9m111_set_vflip,
-		.get = mt9m111_get_vflip
-	}, {
-		{
-			.id             = V4L2_CID_HFLIP,
-			.type           = V4L2_CTRL_TYPE_BOOLEAN,
-			.name           = "horizontal flip",
-			.minimum        = 0,
-			.maximum        = 1,
-			.step           = 1,
-			.default_value  = 0
-		},
-		.set = mt9m111_set_hflip,
-		.get = mt9m111_get_hflip
-	}, {
-		{
-			.id             = V4L2_CID_GAIN,
-			.type           = V4L2_CTRL_TYPE_INTEGER,
-			.name           = "gain",
-			.minimum        = 0,
-			.maximum        = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
-			.step           = 1,
-			.default_value  = DEFAULT_GAIN,
-			.flags          = V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = mt9m111_set_gain,
-		.get = mt9m111_get_gain
-	}
-	},
-
-	.nmodes = 1,
-	.modes = {
-	{
-		M5602_DEFAULT_FRAME_WIDTH,
-		M5602_DEFAULT_FRAME_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
-		.bytesperline = M5602_DEFAULT_FRAME_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
+	.power_down = mt9m111_power_down
 };
 
 static const unsigned char preinit_mt9m111[][4] =
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,14 +65,177 @@ static
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700")
 		}
 	},
-	{ }
+	{}
+};
+
+const static struct ctrl ov9650_ctrls[] = {
+#define EXPOSURE_IDX 0
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "exposure",
+			.minimum	= 0x00,
+			.maximum	= 0x1ff,
+			.step		= 0x4,
+			.default_value 	= EXPOSURE_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = ov9650_set_exposure,
+		.get = ov9650_get_exposure
+	},
+#define GAIN_IDX 1
+	{
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "gain",
+			.minimum	= 0x00,
+			.maximum	= 0x3ff,
+			.step		= 0x1,
+			.default_value	= GAIN_DEFAULT,
+			.flags		= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = ov9650_set_gain,
+		.get = ov9650_get_gain
+	},
+#define RED_BALANCE_IDX 2
+	{
+		{
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "red balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0xff,
+			.step 		= 0x1,
+			.default_value 	= RED_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = ov9650_set_red_balance,
+		.get = ov9650_get_red_balance
+	},
+#define BLUE_BALANCE_IDX 3
+	{
+		{
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "blue balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0xff,
+			.step 		= 0x1,
+			.default_value 	= BLUE_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = ov9650_set_blue_balance,
+		.get = ov9650_get_blue_balance
+	},
+#define HFLIP_IDX 4
+	{
+		{
+			.id 		= V4L2_CID_HFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "horizontal flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = ov9650_set_hflip,
+		.get = ov9650_get_hflip
+	},
+#define VFLIP_IDX 5
+	{
+		{
+			.id 		= V4L2_CID_VFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "vertical flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = ov9650_set_vflip,
+		.get = ov9650_get_vflip
+	},
+#define AUTO_WHITE_BALANCE_IDX 6
+	{
+		{
+			.id 		= V4L2_CID_AUTO_WHITE_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto white balance",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov9650_set_auto_white_balance,
+		.get = ov9650_get_auto_white_balance
+	},
+#define AUTO_GAIN_CTRL_IDX 7
+	{
+		{
+			.id 		= V4L2_CID_AUTOGAIN,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto gain control",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov9650_set_auto_gain,
+		.get = ov9650_get_auto_gain
+	}
+};
+
+static struct v4l2_pix_format ov9650_modes[] = {
+	{
+		176,
+		144,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			176 * 144,
+		.bytesperline = 176,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 9
+	}, {
+		320,
+		240,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			320 * 240,
+		.bytesperline = 320,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 8
+	}, {
+		352,
+		288,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			352 * 288,
+		.bytesperline = 352,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 9
+	}, {
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 9
+	}
 };
 
 static void ov9650_dump_registers(struct sd *sd);
 
 int ov9650_probe(struct sd *sd)
 {
+	int err = 0;
 	u8 prod_id = 0, ver_id = 0, i;
+	s32 *sensor_settings;
 
 	if (force_sensor) {
 		if (force_sensor == OV9650_SENSOR) {
@@ -86,16 +249,20 @@ int ov9650_probe(struct sd *sd)
 
 	info("Probing for an ov9650 sensor");
 
-	/* Run the pre-init to actually probe the unit */
-	for (i = 0; i < ARRAY_SIZE(preinit_ov9650); i++) {
+	/* Run the pre-init before probing the sensor */
+	for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
 		u8 data = preinit_ov9650[i][2];
 		if (preinit_ov9650[i][0] == SENSOR)
-			m5602_write_sensor(sd,
-					    preinit_ov9650[i][1], &data, 1);
+			err = m5602_write_sensor(sd,
+				preinit_ov9650[i][1], &data, 1);
 		else
-			m5602_write_bridge(sd, preinit_ov9650[i][1], data);
+			err = m5602_write_bridge(sd,
+				preinit_ov9650[i][1], data);
 	}
 
+	if (err < 0)
+		return err;
+
 	if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1))
 		return -ENODEV;
 
@@ -106,14 +273,28 @@ int ov9650_probe(struct sd *sd)
 		info("Detected an ov9650 sensor");
 		goto sensor_found;
 	}
-
 	return -ENODEV;
 
 sensor_found:
-	sd->gspca_dev.cam.cam_mode = ov9650.modes;
-	sd->gspca_dev.cam.nmodes = ov9650.nmodes;
-	sd->desc->ctrls = ov9650.ctrls;
-	sd->desc->nctrls = ov9650.nctrls;
+	sensor_settings = kmalloc(
+		ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL);
+	if (!sensor_settings)
+		return -ENOMEM;
+
+	sd->gspca_dev.cam.cam_mode = ov9650_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes);
+	sd->desc->ctrls = ov9650_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls);
+
+	for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++)
+		sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value;
+	sd->sensor_priv = sensor_settings;
+
+	if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
+		info("vflip quirk active");
+		sensor_settings[VFLIP_IDX] = 1;
+	}
+
 	return 0;
 }
 
@@ -121,6 +302,7 @@ int ov9650_init(struct sd *sd)
 {
 	int i, err = 0;
 	u8 data;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	if (dump_sensor)
 		ov9650_dump_registers(sd);
@@ -134,70 +316,157 @@ int ov9650_init(struct sd *sd)
 			err = m5602_write_bridge(sd, init_ov9650[i][1], data);
 	}
 
-	if (dmi_check_system(ov9650_flip_dmi_table) && !err) {
-		info("vflip quirk active");
-		data = 0x30;
-		err = m5602_write_sensor(sd, OV9650_MVFP, &data, 1);
-	}
+	err = ov9650_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_red_balance(&sd->gspca_dev, sensor_settings[RED_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_blue_balance(&sd->gspca_dev, sensor_settings[BLUE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_auto_white_balance(&sd->gspca_dev, sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov9650_set_auto_gain(&sd->gspca_dev, sensor_settings[AUTO_GAIN_CTRL_IDX]);
 	return err;
 }
 
 int ov9650_start(struct sd *sd)
 {
+	u8 data;
 	int i, err = 0;
 	struct cam *cam = &sd->gspca_dev.cam;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+	int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+	int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+	int hor_offs = OV9650_LEFT_OFFSET;
 
+	if (sensor_settings[VFLIP_IDX])
+		ver_offs--;
+
+	if (width <= 320)
+		hor_offs /= 2;
+
+	/* Synthesize the vsync/hsync setup */
 	for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
-		u8 data = res_init_ov9650[i][1];
-		err = m5602_write_bridge(sd, res_init_ov9650[i][0], data);
+		if (res_init_ov9650[i][0] == BRIDGE)
+			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];
+			err = m5602_write_sensor(sd,
+				res_init_ov9650[i][1], &data, 1);
+		}
 	}
 	if (err < 0)
 		return err;
 
-	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
-	{
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
+				 ((ver_offs >> 8) & 0xff));
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < 2 && !err; i++)
+		err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+				 (hor_offs >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+				 ((width + hor_offs) >> 8) & 0xff);
+	if (err < 0)
+		return err;
+
+	err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
+				 ((width + hor_offs) & 0xff));
+	if (err < 0)
+		return err;
+
+	switch (width) {
 	case 640:
 		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
 
-		for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
-			u8 data = VGA_ov9650[i][2];
-			if (VGA_ov9650[i][0] == SENSOR)
-				err = m5602_write_sensor(sd,
-					VGA_ov9650[i][1], &data, 1);
-			else
-				err = m5602_write_bridge(sd, VGA_ov9650[i][1], data);
-		}
+		data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
+		       OV9650_RAW_RGB_SELECT;
+		err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 		break;
 
 	case 352:
 		PDEBUG(D_V4L2, "Configuring camera for CIF mode");
 
-		for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
-			u8 data = CIF_ov9650[i][2];
-			if (CIF_ov9650[i][0] == SENSOR)
-				err = m5602_write_sensor(sd,
-					CIF_ov9650[i][1], &data, 1);
-			else
-				err = m5602_write_bridge(sd, CIF_ov9650[i][1], data);
-		}
+		data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
+				OV9650_RAW_RGB_SELECT;
+		err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 		break;
 
 	case 320:
 		PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
 
-		for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
-			u8 data = QVGA_ov9650[i][2];
-			if (QVGA_ov9650[i][0] == SENSOR)
-				err = m5602_write_sensor(sd,
-					QVGA_ov9650[i][1], &data, 1);
-			else
-				err = m5602_write_bridge(sd, QVGA_ov9650[i][1], data);
-		}
+		data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
+				OV9650_RAW_RGB_SELECT;
+		err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
+		break;
+
+	case 176:
+		PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
+
+		data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
+			OV9650_RAW_RGB_SELECT;
+		err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
 		break;
 	}
 	return err;
 }
 
+int ov9650_stop(struct sd *sd)
+{
+	u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X;
+	return m5602_write_sensor(sd, OV9650_COM2, &data, 1);
+}
+
 int ov9650_power_down(struct sd *sd)
 {
 	int i, err = 0;
@@ -214,76 +483,63 @@ int ov9650_power_down(struct sd *sd)
 	return err;
 }
 
-int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+void ov9650_disconnect(struct sd *sd)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-	u8 i2c_data;
-	int err;
-
-	err = m5602_read_sensor(sd, OV9650_COM1, &i2c_data, 1);
-	if (err < 0)
-		goto out;
-	*val = i2c_data & 0x03;
+	ov9650_stop(sd);
+	ov9650_power_down(sd);
 
-	err = m5602_read_sensor(sd, OV9650_AECH, &i2c_data, 1);
-	if (err < 0)
-		goto out;
-	*val |= (i2c_data << 2);
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
 
-	err = m5602_read_sensor(sd, OV9650_AECHM, &i2c_data, 1);
-	if (err < 0)
-		goto out;
-	*val |= (i2c_data & 0x3f) << 10;
+int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
+	*val = sensor_settings[EXPOSURE_IDX];
 	PDEBUG(D_V4L2, "Read exposure %d", *val);
-out:
-	return err;
+	return 0;
 }
 
 int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(D_V4L2, "Set exposure to %d",
-	       val & 0xffff);
+	PDEBUG(D_V4L2, "Set exposure to %d", val);
 
+	sensor_settings[EXPOSURE_IDX] = val;
 	/* The 6 MSBs */
 	i2c_data = (val >> 10) & 0x3f;
 	err = m5602_write_sensor(sd, OV9650_AECHM,
 				  &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* The 8 middle bits */
 	i2c_data = (val >> 2) & 0xff;
 	err = m5602_write_sensor(sd, OV9650_AECH,
 				  &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* The 2 LSBs */
 	i2c_data = val & 0x03;
 	err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1);
-
-out:
 	return err;
 }
 
 int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
-	*val = (i2c_data & 0x03) << 8;
-
-	err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
-	*val |= i2c_data;
+	*val = sensor_settings[GAIN_IDX];
 	PDEBUG(D_V4L2, "Read gain %d", *val);
-	return err;
+	return 0;
 }
 
 int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -291,15 +547,25 @@ int ov9650_set_gain(struct gspca_dev *gs
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Setting gain to %d", val);
+
+	sensor_settings[GAIN_IDX] = val;
 
 	/* The 2 MSB */
 	/* Read the OV9650_VREF register first to avoid
 	   corrupting the VREF high and low bits */
-	m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
+	err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
 	/* Mask away all uninteresting bits */
 	i2c_data = ((val & 0x0300) >> 2) |
 			(i2c_data & 0x3F);
 	err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
+	if (err < 0)
+		return err;
 
 	/* The 8 LSBs */
 	i2c_data = val & 0xff;
@@ -309,16 +575,12 @@ int ov9650_set_gain(struct gspca_dev *gs
 
 int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_RED, &i2c_data, 1);
-	*val = i2c_data;
-
+	*val = sensor_settings[RED_BALANCE_IDX];
 	PDEBUG(D_V4L2, "Read red gain %d", *val);
-
-	return err;
+	return 0;
 }
 
 int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -326,28 +588,26 @@ int ov9650_set_red_balance(struct gspca_
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	PDEBUG(D_V4L2, "Set red gain to %d",
-			     val & 0xff);
+	PDEBUG(D_V4L2, "Set red gain to %d", val);
+
+	sensor_settings[RED_BALANCE_IDX] = val;
 
 	i2c_data = val & 0xff;
 	err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
-
 	return err;
 }
 
 int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
-	*val = i2c_data;
-
+	*val = sensor_settings[BLUE_BALANCE_IDX];
 	PDEBUG(D_V4L2, "Read blue gain %d", *val);
 
-	return err;
+	return 0;
 }
 
 int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -355,30 +615,25 @@ int ov9650_set_blue_balance(struct gspca
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	PDEBUG(D_V4L2, "Set blue gain to %d",
-	       val & 0xff);
+	PDEBUG(D_V4L2, "Set blue gain to %d", val);
+
+	sensor_settings[BLUE_BALANCE_IDX] = val;
 
 	i2c_data = val & 0xff;
 	err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
-
 	return err;
 }
 
 int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-	if (dmi_check_system(ov9650_flip_dmi_table))
-		*val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
-	else
-		*val = (i2c_data & OV9650_HFLIP) >> 5;
+	*val = sensor_settings[HFLIP_IDX];
 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-
-	return err;
+	return 0;
 }
 
 int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -386,38 +641,26 @@ int ov9650_set_hflip(struct gspca_dev *g
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
-	err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-	if (err < 0)
-		goto out;
-
-	if (dmi_check_system(ov9650_flip_dmi_table))
-		i2c_data = ((i2c_data & 0xdf) |
-			   (((val ? 0 : 1) & 0x01) << 5));
-	else
-		i2c_data = ((i2c_data & 0xdf) |
-			   ((val & 0x01) << 5));
 
+	sensor_settings[HFLIP_IDX] = val;
+	i2c_data = ((val & 0x01) << 5) | (sensor_settings[VFLIP_IDX] << 4);
 	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-out:
+
 	return err;
 }
 
 int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-	if (dmi_check_system(ov9650_flip_dmi_table))
-		*val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
-	else
-		*val = (i2c_data & 0x10) >> 4;
+	*val = sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
-	return err;
+	return 0;
 }
 
 int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -425,40 +668,32 @@ int ov9650_set_vflip(struct gspca_dev *g
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
-	err = m5602_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
+	sensor_settings[VFLIP_IDX] = val;
+
+	i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
+	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
-	if (dmi_check_system(ov9650_flip_dmi_table))
-		i2c_data = ((i2c_data & 0xef) |
-				(((val ? 0 : 1) & 0x01) << 4));
-	else
-		i2c_data = ((i2c_data & 0xef) |
-				((val & 0x01) << 4));
+	/* When vflip is toggled we need to readjust the bridge hsync/vsync */
+	if (gspca_dev->streaming)
+		err = ov9650_start(sd);
 
-	err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1);
-out:
 	return err;
 }
 
 int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
-	if (err < 0)
-		goto out;
-	*val = (i2c_data & 0x03) << 8;
-
-	err = m5602_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
-	*val |= i2c_data;
+	*val = sensor_settings[GAIN_IDX];
 	PDEBUG(D_V4L2, "Read gain %d", *val);
-out:
-	return err;
+
+	return 0;
 }
 
 int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -466,40 +701,38 @@ int ov9650_set_brightness(struct gspca_d
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff);
+	PDEBUG(D_V4L2, "Set gain to %d", val);
+
+	sensor_settings[GAIN_IDX] = val;
 
 	/* Read the OV9650_VREF register first to avoid
 		corrupting the VREF high and low bits */
 	err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* Mask away all uninteresting bits */
 	i2c_data = ((val & 0x0300) >> 2) | (i2c_data & 0x3F);
 	err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* The 8 LSBs */
 	i2c_data = val & 0xff;
 	err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1);
 
-out:
 	return err;
 }
 
 int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
-	*val = (i2c_data & OV9650_AWB_EN) >> 1;
-	PDEBUG(D_V4L2, "Read auto white balance %d", *val);
-
-	return err;
+	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+	return 0;
 }
 
 int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
@@ -507,29 +740,29 @@ int ov9650_set_auto_white_balance(struct
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
+
+	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
 	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
 	err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-out:
+
 	return err;
 }
 
 int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
-	*val = (i2c_data & OV9650_AGC_EN) >> 2;
+	*val = sensor_settings[AUTO_GAIN_CTRL_IDX];
 	PDEBUG(D_V4L2, "Read auto gain control %d", *val);
-
-	return err;
+	return 0;
 }
 
 int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
@@ -537,15 +770,18 @@ int ov9650_set_auto_gain(struct gspca_de
 	int err;
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
 	PDEBUG(D_V4L2, "Set auto gain control to %d", val);
+
+	sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
 	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
 	err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1);
-out:
+
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_ov9650.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #define OV9650_BAVE			0x05
 #define OV9650_GEAVE			0x06
 #define OV9650_RSVD7			0x07
+#define OV9650_COM2			0x09
 #define OV9650_PID			0x0a
 #define OV9650_VER			0x0b
 #define OV9650_COM3			0x0c
@@ -96,6 +97,7 @@
 #define OV9650_VGA_SELECT		(1 << 6)
 #define OV9650_CIF_SELECT		(1 << 5)
 #define OV9650_QVGA_SELECT		(1 << 4)
+#define OV9650_QCIF_SELECT		(1 << 3)
 #define OV9650_RGB_SELECT		(1 << 2)
 #define OV9650_RAW_RGB_SELECT		(1 << 0)
 
@@ -115,10 +117,15 @@
 #define OV9650_VFLIP			(1 << 4)
 #define OV9650_HFLIP			(1 << 5)
 
+#define OV9650_SOFT_SLEEP		(1 << 4)
+#define OV9650_OUTPUT_DRIVE_2X		(1 << 0)
+
+#define OV9650_LEFT_OFFSET		0x62
+
 #define GAIN_DEFAULT			0x14
 #define RED_GAIN_DEFAULT		0x70
 #define BLUE_GAIN_DEFAULT		0x20
-#define EXPOSURE_DEFAULT		0x5003
+#define EXPOSURE_DEFAULT		0x1ff
 
 /*****************************************************************************/
 
@@ -129,7 +136,9 @@ extern int dump_sensor;
 int ov9650_probe(struct sd *sd);
 int ov9650_init(struct sd *sd);
 int ov9650_start(struct sd *sd);
+int ov9650_stop(struct sd *sd);
 int ov9650_power_down(struct sd *sd);
+void ov9650_disconnect(struct sd *sd);
 
 int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
 int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -150,152 +159,16 @@ int ov9650_set_auto_white_balance(struct
 int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
 int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor ov9650 = {
+const static struct m5602_sensor ov9650 = {
 	.name = "OV9650",
 	.i2c_slave_id = 0x60,
 	.i2c_regW = 1,
 	.probe = ov9650_probe,
 	.init = ov9650_init,
 	.start = ov9650_start,
+	.stop = ov9650_stop,
 	.power_down = ov9650_power_down,
-
-	.nctrls = 8,
-	.ctrls = {
-	{
-		{
-			.id		= V4L2_CID_EXPOSURE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "exposure",
-			.minimum	= 0x00,
-			.maximum	= 0xffff,
-			.step		= 0x1,
-			.default_value 	= EXPOSURE_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = ov9650_set_exposure,
-		.get = ov9650_get_exposure
-	}, {
-		{
-			.id		= V4L2_CID_GAIN,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "gain",
-			.minimum	= 0x00,
-			.maximum	= 0x3ff,
-			.step		= 0x1,
-			.default_value	= GAIN_DEFAULT,
-			.flags		= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = ov9650_set_gain,
-		.get = ov9650_get_gain
-	}, {
-		{
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "red balance",
-			.minimum 	= 0x00,
-			.maximum 	= 0xff,
-			.step 		= 0x1,
-			.default_value 	= RED_GAIN_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = ov9650_set_red_balance,
-		.get = ov9650_get_red_balance
-	}, {
-		{
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "blue balance",
-			.minimum 	= 0x00,
-			.maximum 	= 0xff,
-			.step 		= 0x1,
-			.default_value 	= BLUE_GAIN_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = ov9650_set_blue_balance,
-		.get = ov9650_get_blue_balance
-	}, {
-		{
-			.id 		= V4L2_CID_HFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "horizontal flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = ov9650_set_hflip,
-		.get = ov9650_get_hflip
-	}, {
-		{
-			.id 		= V4L2_CID_VFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "vertical flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = ov9650_set_vflip,
-		.get = ov9650_get_vflip
-	}, {
-		{
-			.id 		= V4L2_CID_AUTO_WHITE_BALANCE,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "auto white balance",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = ov9650_set_auto_white_balance,
-		.get = ov9650_get_auto_white_balance
-	}, {
-		{
-			.id 		= V4L2_CID_AUTOGAIN,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "auto gain control",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = ov9650_set_auto_gain,
-		.get = ov9650_get_auto_gain
-	}
-	},
-
-	.nmodes = 3,
-	.modes = {
-	{
-		320,
-		240,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			320 * 240,
-		.bytesperline = 320,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	}, {
-		352,
-		288,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			352 * 288,
-		.bytesperline = 352,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	}, {
-		640,
-		480,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			640 * 480,
-		.bytesperline = 640,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	}
-	}
+	.disconnect = ov9650_disconnect,
 };
 
 static const unsigned char preinit_ov9650[][3] =
@@ -345,6 +218,10 @@ static const unsigned char init_ov9650[]
 
 	/* Reset chip */
 	{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+	/* One extra reset is needed in order to make the sensor behave
+	   properly when resuming from ram */
+	{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
+
 	/* Enable double clock */
 	{SENSOR, OV9650_CLKRC, 0x80},
 	/* Do something out of spec with the power */
@@ -427,18 +304,12 @@ static const unsigned char init_ov9650[]
 	/* Enable denoise, and white-pixel erase */
 	{SENSOR, OV9650_COM22, 0x23},
 
-	/* Set the high bits of the exposure value */
-	{SENSOR, OV9650_AECH, ((EXPOSURE_DEFAULT & 0xff00) >> 8)},
-
 	/* Enable VARIOPIXEL */
 	{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
 	{SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
 
-	/* Set the low bits of the exposure value */
-	{SENSOR, OV9650_COM1, (EXPOSURE_DEFAULT & 0xff)},
-	{SENSOR, OV9650_GAIN, GAIN_DEFAULT},
-	{SENSOR, OV9650_BLUE, BLUE_GAIN_DEFAULT},
-	{SENSOR, OV9650_RED, RED_GAIN_DEFAULT},
+	/* Put the sensor in soft sleep mode */
+	{SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
 };
 
 static const unsigned char power_down_ov9650[][3] =
@@ -461,73 +332,15 @@ static const unsigned char power_down_ov
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 };
 
-static const unsigned char res_init_ov9650[][2] =
-{
-	{M5602_XB_LINE_OF_FRAME_H, 0x82},
-	{M5602_XB_LINE_OF_FRAME_L, 0x00},
-	{M5602_XB_PIX_OF_LINE_H, 0x82},
-	{M5602_XB_PIX_OF_LINE_L, 0x00},
-	{M5602_XB_SIG_INI, 0x01}
-};
-
-static const unsigned char VGA_ov9650[][3] =
-{
-	/* Moves the view window in a vertical orientation */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
-
-	{SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
-			      OV9650_RGB_SELECT |
-			      OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char CIF_ov9650[][3] =
-{
-	/* Moves the view window in a vertical orientation */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
-
-	{SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
-			      OV9650_RGB_SELECT |
-			      OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char QVGA_ov9650[][3] =
+static const unsigned char res_init_ov9650[][3] =
 {
-	/* Moves the view window in a vertical orientation */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
-	{BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
+	{SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
 
-	{SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
-			      OV9650_RGB_SELECT |
-			      OV9650_RAW_RGB_SELECT},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01}
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,99 @@
 
 #include "m5602_po1030.h"
 
+static struct v4l2_pix_format po1030_modes[] = {
+	{
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+const static struct ctrl po1030_ctrls[] = {
+	{
+		{
+			.id 		= V4L2_CID_GAIN,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "gain",
+			.minimum 	= 0x00,
+			.maximum 	= 0x4f,
+			.step 		= 0x1,
+			.default_value 	= PO1030_GLOBAL_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = po1030_set_gain,
+		.get = po1030_get_gain
+	}, {
+		{
+			.id 		= V4L2_CID_EXPOSURE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "exposure",
+			.minimum 	= 0x00,
+			.maximum 	= 0x02ff,
+			.step 		= 0x1,
+			.default_value 	= PO1030_EXPOSURE_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = po1030_set_exposure,
+		.get = po1030_get_exposure
+	}, {
+		{
+			.id 		= V4L2_CID_RED_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "red balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0xff,
+			.step 		= 0x1,
+			.default_value 	= PO1030_RED_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = po1030_set_red_balance,
+		.get = po1030_get_red_balance
+	}, {
+		{
+			.id 		= V4L2_CID_BLUE_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_INTEGER,
+			.name 		= "blue balance",
+			.minimum 	= 0x00,
+			.maximum 	= 0xff,
+			.step 		= 0x1,
+			.default_value 	= PO1030_BLUE_GAIN_DEFAULT,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = po1030_set_blue_balance,
+		.get = po1030_get_blue_balance
+	}, {
+		{
+			.id 		= V4L2_CID_HFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "horizontal flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_hflip,
+		.get = po1030_get_hflip
+	}, {
+		{
+			.id 		= V4L2_CID_VFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "vertical flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_vflip,
+		.get = po1030_get_vflip
+	}
+};
+
 static void po1030_dump_registers(struct sd *sd);
 
 int po1030_probe(struct sd *sd)
@@ -59,10 +152,10 @@ int po1030_probe(struct sd *sd)
 	return -ENODEV;
 
 sensor_found:
-	sd->gspca_dev.cam.cam_mode = po1030.modes;
-	sd->gspca_dev.cam.nmodes = po1030.nmodes;
-	sd->desc->ctrls = po1030.ctrls;
-	sd->desc->nctrls = po1030.nctrls;
+	sd->gspca_dev.cam.cam_mode = po1030_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
+	sd->desc->ctrls = po1030_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
 	return 0;
 }
 
@@ -108,7 +201,7 @@ int po1030_get_exposure(struct gspca_dev
 	err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
 				 &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	*val = (i2c_data << 8);
 
 	err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
@@ -116,7 +209,7 @@ int po1030_get_exposure(struct gspca_dev
 	*val |= i2c_data;
 
 	PDEBUG(D_V4L2, "Exposure read as %d", *val);
-out:
+
 	return err;
 }
 
@@ -135,7 +228,7 @@ int po1030_set_exposure(struct gspca_dev
 	err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
 				  &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	i2c_data = (val & 0xff);
 	PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
@@ -143,7 +236,6 @@ int po1030_set_exposure(struct gspca_dev
 	err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
 				  &i2c_data, 1);
 
-out:
 	return err;
 }
 
@@ -186,14 +278,13 @@ int po1030_set_hflip(struct gspca_dev *g
 	PDEBUG(D_V4L2, "Set hflip %d", val);
 	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
 
 	err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
 				 &i2c_data, 1);
 
-out:
 	return err;
 }
 
@@ -222,14 +313,13 @@ int po1030_set_vflip(struct gspca_dev *g
 	PDEBUG(D_V4L2, "Set vflip %d", val);
 	err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
 
 	err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
 				 &i2c_data, 1);
 
-out:
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_po1030.h	2009-06-09 23:05:27.000000000 -0400
@@ -141,7 +141,7 @@ int po1030_set_hflip(struct gspca_dev *g
 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor po1030 = {
+static const struct m5602_sensor po1030 = {
 	.name = "PO1030",
 
 	.i2c_slave_id = 0xdc,
@@ -150,102 +150,6 @@ static struct m5602_sensor po1030 = {
 	.probe = po1030_probe,
 	.init = po1030_init,
 	.power_down = po1030_power_down,
-
-	.nctrls = 6,
-	.ctrls = {
-	{
-		{
-			.id 		= V4L2_CID_GAIN,
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "gain",
-			.minimum 	= 0x00,
-			.maximum 	= 0x4f,
-			.step 		= 0x1,
-			.default_value 	= PO1030_GLOBAL_GAIN_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = po1030_set_gain,
-		.get = po1030_get_gain
-	}, {
-		{
-			.id 		= V4L2_CID_EXPOSURE,
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "exposure",
-			.minimum 	= 0x00,
-			.maximum 	= 0x02ff,
-			.step 		= 0x1,
-			.default_value 	= PO1030_EXPOSURE_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = po1030_set_exposure,
-		.get = po1030_get_exposure
-	}, {
-		{
-			.id 		= V4L2_CID_RED_BALANCE,
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "red balance",
-			.minimum 	= 0x00,
-			.maximum 	= 0xff,
-			.step 		= 0x1,
-			.default_value 	= PO1030_RED_GAIN_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = po1030_set_red_balance,
-		.get = po1030_get_red_balance
-	}, {
-		{
-			.id 		= V4L2_CID_BLUE_BALANCE,
-			.type 		= V4L2_CTRL_TYPE_INTEGER,
-			.name 		= "blue balance",
-			.minimum 	= 0x00,
-			.maximum 	= 0xff,
-			.step 		= 0x1,
-			.default_value 	= PO1030_BLUE_GAIN_DEFAULT,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = po1030_set_blue_balance,
-		.get = po1030_get_blue_balance
-	}, {
-		{
-			.id 		= V4L2_CID_HFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "horizontal flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0,
-		},
-		.set = po1030_set_hflip,
-		.get = po1030_get_hflip
-	}, {
-		{
-			.id 		= V4L2_CID_VFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "vertical flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0,
-		},
-		.set = po1030_set_vflip,
-		.get = po1030_get_vflip
-	}
-	},
-
-	.nmodes = 1,
-	.modes = {
-	{
-		M5602_DEFAULT_FRAME_WIDTH,
-		M5602_DEFAULT_FRAME_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
-		.bytesperline = M5602_DEFAULT_FRAME_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
 };
 
 static const unsigned char preinit_po1030[][3] =
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,76 @@ static
 	{ }
 };
 
+static struct v4l2_pix_format s5k4aa_modes[] = {
+	{
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+const static struct ctrl s5k4aa_ctrls[] = {
+	{
+		{
+			.id 		= V4L2_CID_VFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "vertical flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = s5k4aa_set_vflip,
+		.get = s5k4aa_get_vflip
+
+	}, {
+		{
+			.id 		= V4L2_CID_HFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "horizontal flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = s5k4aa_set_hflip,
+		.get = s5k4aa_get_hflip
+
+	}, {
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Gain",
+			.minimum	= 0,
+			.maximum	= 127,
+			.step		= 1,
+			.default_value	= 0xa0,
+			.flags		= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = s5k4aa_set_gain,
+		.get = s5k4aa_get_gain
+	}, {
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Exposure",
+			.minimum	= 13,
+			.maximum	= 0xfff,
+			.step		= 1,
+			.default_value	= 0x100,
+			.flags		= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = s5k4aa_set_exposure,
+		.get = s5k4aa_get_exposure
+	}
+};
+
 static void s5k4aa_dump_registers(struct sd *sd);
 
 int s5k4aa_probe(struct sd *sd)
@@ -115,14 +185,56 @@ int s5k4aa_probe(struct sd *sd)
 		info("Detected a s5k4aa sensor");
 
 sensor_found:
-	sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
-	sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
-	sd->desc->ctrls = s5k4aa.ctrls;
-	sd->desc->nctrls = s5k4aa.nctrls;
-
+	sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
+	sd->desc->ctrls = s5k4aa_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls);
 	return 0;
 }
 
+int s5k4aa_start(struct sd *sd)
+{
+	int i, err = 0;
+	u8 data[2];
+	struct cam *cam = &sd->gspca_dev.cam;
+
+	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width)
+	{
+	case 640:
+		PDEBUG(D_V4L2, "Configuring camera for VGA mode");
+
+		for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
+			switch (VGA_s5k4aa[i][0]) {
+			case BRIDGE:
+				err = m5602_write_bridge(sd,
+						 VGA_s5k4aa[i][1],
+						 VGA_s5k4aa[i][2]);
+			break;
+
+			case SENSOR:
+				data[0] = VGA_s5k4aa[i][2];
+				err = m5602_write_sensor(sd,
+						 VGA_s5k4aa[i][1],
+						 data, 1);
+			break;
+
+			case SENSOR_LONG:
+				data[0] = VGA_s5k4aa[i][2];
+				data[1] = VGA_s5k4aa[i][3];
+				err = m5602_write_sensor(sd,
+						  VGA_s5k4aa[i][1],
+						  data, 2);
+			break;
+
+			default:
+				err("Invalid stream command, exiting init");
+				return -EINVAL;
+			}
+		}
+	}
+	return err;
+}
+
 int s5k4aa_init(struct sd *sd)
 {
 	int i, err = 0;
@@ -194,17 +306,17 @@ int s5k4aa_get_exposure(struct gspca_dev
 
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	*val = data << 8;
 	err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
 	*val |= data;
 	PDEBUG(D_V4L2, "Read exposure %d", *val);
-out:
+
 	return err;
 }
 
@@ -217,14 +329,14 @@ int s5k4aa_set_exposure(struct gspca_dev
 	PDEBUG(D_V4L2, "Set exposure to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	data = (val >> 8) & 0xff;
 	err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	data = val & 0xff;
 	err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
-out:
+
 	return err;
 }
 
@@ -236,13 +348,12 @@ int s5k4aa_get_vflip(struct gspca_dev *g
 
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	*val = (data & S5K4AA_RM_V_FLIP) >> 7;
 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
-out:
 	return err;
 }
 
@@ -255,32 +366,32 @@ int s5k4aa_set_vflip(struct gspca_dev *g
 	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	data = ((data & ~S5K4AA_RM_V_FLIP)
 			| ((val & 0x01) << 7));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	if (val) {
 		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 		if (err < 0)
-			goto out;
+			return err;
 
 		data++;
 		err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	} else {
 		err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 		if (err < 0)
-			goto out;
+			return err;
 
 		data--;
 		err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
 	}
-out:
+
 	return err;
 }
 
@@ -292,12 +403,12 @@ int s5k4aa_get_hflip(struct gspca_dev *g
 
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	*val = (data & S5K4AA_RM_H_FLIP) >> 6;
 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
-out:
+
 	return err;
 }
 
@@ -311,32 +422,32 @@ int s5k4aa_set_hflip(struct gspca_dev *g
 	       val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
 	err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	if (val) {
 		err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 		if (err < 0)
-			goto out;
+			return err;
 		data++;
 		err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 		if (err < 0)
-			goto out;
+			return err;
 	} else {
 		err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 		if (err < 0)
-			goto out;
+			return err;
 		data--;
 		err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
 	}
-out:
+
 	return err;
 }
 
@@ -348,13 +459,12 @@ int s5k4aa_get_gain(struct gspca_dev *gs
 
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
 	*val = data;
 	PDEBUG(D_V4L2, "Read gain %d", *val);
 
-out:
 	return err;
 }
 
@@ -367,12 +477,11 @@ int s5k4aa_set_gain(struct gspca_dev *gs
 	PDEBUG(D_V4L2, "Set gain to %d", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data = val & 0xff;
 	err = m5602_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
 
-out:
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k4aa.h	2009-06-09 23:05:27.000000000 -0400
@@ -65,6 +65,7 @@ extern int dump_sensor;
 
 int s5k4aa_probe(struct sd *sd);
 int s5k4aa_init(struct sd *sd);
+int s5k4aa_start(struct sd *sd);
 int s5k4aa_power_down(struct sd *sd);
 
 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -76,84 +77,14 @@ int s5k4aa_set_hflip(struct gspca_dev *g
 int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor s5k4aa = {
+static const struct m5602_sensor s5k4aa = {
 	.name = "S5K4AA",
 	.probe = s5k4aa_probe,
 	.init = s5k4aa_init,
+	.start = s5k4aa_start,
 	.power_down = s5k4aa_power_down,
 	.i2c_slave_id = 0x5a,
 	.i2c_regW = 2,
-	.nctrls = 4,
-	.ctrls = {
-	{
-		{
-			.id 		= V4L2_CID_VFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "vertical flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = s5k4aa_set_vflip,
-		.get = s5k4aa_get_vflip
-
-	}, {
-		{
-			.id 		= V4L2_CID_HFLIP,
-			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name 		= "horizontal flip",
-			.minimum 	= 0,
-			.maximum 	= 1,
-			.step 		= 1,
-			.default_value 	= 0
-		},
-		.set = s5k4aa_set_hflip,
-		.get = s5k4aa_get_hflip
-
-	}, {
-		{
-			.id		= V4L2_CID_GAIN,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Gain",
-			.minimum	= 0,
-			.maximum	= 127,
-			.step		= 1,
-			.default_value	= 0xa0,
-			.flags		= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = s5k4aa_set_gain,
-		.get = s5k4aa_get_gain
-	}, {
-		{
-			.id		= V4L2_CID_EXPOSURE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Exposure",
-			.minimum	= 13,
-			.maximum	= 0xfff,
-			.step		= 1,
-			.default_value	= 0x100,
-			.flags		= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = s5k4aa_set_exposure,
-		.get = s5k4aa_get_exposure
-	}
-	},
-
-	.nmodes = 1,
-	.modes = {
-	{
-		M5602_DEFAULT_FRAME_WIDTH,
-		M5602_DEFAULT_FRAME_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
-		.bytesperline = M5602_DEFAULT_FRAME_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
 };
 
 static const unsigned char preinit_s5k4aa[][4] =
@@ -275,6 +206,65 @@ static const unsigned char init_s5k4aa[]
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
+	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
+	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	/* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
+	/* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
+	{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
+
+	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+	{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
+		| S5K4AA_RM_COL_SKIP_2X, 0x00},
+	/* 0x37 : Fix image stability when light is too bright and improves
+	 * image quality in 640x480, but worsens it in 1280x1024 */
+	{SENSOR, 0x37, 0x01, 0x00},
+	/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
+	{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
+	{SENSOR, S5K4AA_ROWSTART_LO, 0x2a, 0x00},
+	{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
+	{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
+	/* window_height_hi, window_height_lo : 960 = 0x03c0 */
+	{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
+	{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
+	/* window_width_hi, window_width_lo : 1280 = 0x0500 */
+	{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
+	{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
+	{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
+	{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
+	{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
+	{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
+	{SENSOR, 0x11, 0x04, 0x00},
+	{SENSOR, 0x12, 0xc3, 0x00},
+	{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
+	{SENSOR, 0x02, 0x0e, 0x00},
+	{SENSOR_LONG, S5K4AA_GLOBAL_GAIN__, 0x0f, 0x00},
+	{SENSOR, S5K4AA_GAIN_1, 0x0b, 0x00},
+	{SENSOR, S5K4AA_GAIN_2, 0xa0, 0x00}
+};
+
+static const unsigned char VGA_s5k4aa[][4] =
+{
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
 	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
 	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,88 @@
 
 #include "m5602_s5k83a.h"
 
+static struct v4l2_pix_format s5k83a_modes[] = {
+	{
+		640,
+		480,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			640 * 480,
+		.bytesperline = 640,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+const static struct ctrl s5k83a_ctrls[] = {
+	{
+		{
+			.id = V4L2_CID_BRIGHTNESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "brightness",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 0x01,
+			.default_value = S5K83A_DEFAULT_BRIGHTNESS,
+			.flags = V4L2_CTRL_FLAG_SLIDER
+		},
+			.set = s5k83a_set_brightness,
+			.get = s5k83a_get_brightness
+
+	}, {
+		{
+			.id = V4L2_CID_WHITENESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "whiteness",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 0x01,
+			.default_value = S5K83A_DEFAULT_WHITENESS,
+			.flags = V4L2_CTRL_FLAG_SLIDER
+		},
+			.set = s5k83a_set_whiteness,
+			.get = s5k83a_get_whiteness,
+	}, {
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "gain",
+			.minimum = 0x00,
+			.maximum = S5K83A_MAXIMUM_GAIN,
+			.step = 0x01,
+			.default_value = S5K83A_DEFAULT_GAIN,
+			.flags = V4L2_CTRL_FLAG_SLIDER
+		},
+			.set = s5k83a_set_gain,
+			.get = s5k83a_get_gain
+	}, {
+		{
+			.id         = V4L2_CID_HFLIP,
+			.type       = V4L2_CTRL_TYPE_BOOLEAN,
+			.name       = "horizontal flip",
+			.minimum    = 0,
+			.maximum    = 1,
+			.step       = 1,
+			.default_value  = 0
+		},
+			.set = s5k83a_set_hflip,
+			.get = s5k83a_get_hflip
+	}, {
+		{
+		 .id         = V4L2_CID_VFLIP,
+		.type       = V4L2_CTRL_TYPE_BOOLEAN,
+		.name       = "vertical flip",
+		.minimum    = 0,
+		.maximum    = 1,
+		.step       = 1,
+		.default_value  = 0
+		},
+		.set = s5k83a_set_vflip,
+		.get = s5k83a_get_vflip
+	}
+};
+
 static void s5k83a_dump_registers(struct sd *sd);
 
 int s5k83a_probe(struct sd *sd)
@@ -63,10 +145,10 @@ int s5k83a_probe(struct sd *sd)
 		info("Detected a s5k83a sensor");
 
 sensor_found:
-	sd->gspca_dev.cam.cam_mode = s5k83a.modes;
-	sd->gspca_dev.cam.nmodes = s5k83a.nmodes;
-	sd->desc->ctrls = s5k83a.ctrls;
-	sd->desc->nctrls = s5k83a.nctrls;
+	sd->gspca_dev.cam.cam_mode = s5k83a_modes;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
+	sd->desc->ctrls = s5k83a_ctrls;
+	sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
 	return 0;
 }
 
@@ -108,6 +190,16 @@ int s5k83a_init(struct sd *sd)
 	return (err < 0) ? err : 0;
 }
 
+int s5k83a_start(struct sd *sd)
+{
+	return s5k83a_set_led_indication(sd, 1);
+}
+
+int s5k83a_stop(struct sd *sd)
+{
+	return s5k83a_set_led_indication(sd, 0);
+}
+
 int s5k83a_power_down(struct sd *sd)
 {
 	return 0;
@@ -163,12 +255,11 @@ int s5k83a_get_brightness(struct gspca_d
 
 	err = m5602_read_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[1] = data[1] << 1;
 	*val = data[1];
 
-out:
 	return err;
 }
 
@@ -182,13 +273,13 @@ int s5k83a_set_brightness(struct gspca_d
 	data[1] = 0x20;
 	err = m5602_write_sensor(sd, 0x14, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[0] = 0x01;
 	data[1] = 0x00;
 	err = m5602_write_sensor(sd, 0x0d, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* FIXME: This is not sane, we need to figure out the composition
 		  of these registers */
@@ -196,7 +287,6 @@ int s5k83a_set_brightness(struct gspca_d
 	data[1] = val >> 1; /* brightness, high 7 bits */
 	err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 2);
 
-out:
 	return err;
 }
 
@@ -208,11 +298,10 @@ int s5k83a_get_whiteness(struct gspca_de
 
 	err = m5602_read_sensor(sd, S5K83A_WHITENESS, &data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	*val = data;
 
-out:
 	return err;
 }
 
@@ -236,7 +325,7 @@ int s5k83a_get_gain(struct gspca_dev *gs
 
 	err = m5602_read_sensor(sd, S5K83A_GAIN, data, 2);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[1] = data[1] & 0x3f;
 	if (data[1] > S5K83A_MAXIMUM_GAIN)
@@ -244,7 +333,6 @@ int s5k83a_get_gain(struct gspca_dev *gs
 
 	*val = data[1];
 
-out:
 	return err;
 }
 
@@ -269,12 +357,11 @@ int s5k83a_get_vflip(struct gspca_dev *g
 	data[0] = 0x05;
 	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
 	*val = (data[0] | 0x40) ? 1 : 0;
 
-out:
 	return err;
 }
 
@@ -287,23 +374,22 @@ int s5k83a_set_vflip(struct gspca_dev *g
 	data[0] = 0x05;
 	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* set or zero six bit, seven is hflip */
 	data[0] = (val) ? (data[0] & 0x80) | 0x40 | S5K83A_FLIP_MASK
 			: (data[0] & 0x80) | S5K83A_FLIP_MASK;
 	err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[0] = (val) ? 0x0b : 0x0a;
 	err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
 
-out:
 	return err;
 }
 
@@ -316,12 +402,11 @@ int s5k83a_get_hflip(struct gspca_dev *g
 	data[0] = 0x05;
 	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
 	*val = (data[0] | 0x80) ? 1 : 0;
 
-out:
 	return err;
 }
 
@@ -334,21 +419,40 @@ int s5k83a_set_hflip(struct gspca_dev *g
 	data[0] = 0x05;
 	err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	err = m5602_read_sensor(sd, S5K83A_FLIP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	/* set or zero seven bit, six is vflip */
 	data[0] = (val) ? (data[0] & 0x40) | 0x80 | S5K83A_FLIP_MASK
 			: (data[0] & 0x40) | S5K83A_FLIP_MASK;
 	err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
 	if (err < 0)
-		goto out;
+		return err;
 
 	data[0] = (val) ? 0x0a : 0x0b;
 	err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
-out:
+
 	return err;
 }
+
+int s5k83a_set_led_indication(struct sd *sd, u8 val)
+{
+	int err = 0;
+	u8 data[1];
+
+	err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
+	if (err < 0)
+		return err;
+
+	if (val)
+		data[0] = data[0] | S5K83A_GPIO_LED_MASK;
+	else
+		data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
+
+	err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
+
+	return (err < 0) ? err : 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_s5k83a.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@
 #define S5K83A_DEFAULT_GAIN			0x00
 #define S5K83A_MAXIMUM_GAIN			0x3c
 #define S5K83A_FLIP_MASK			0x10
-
+#define S5K83A_GPIO_LED_MASK		0x10
 
 /*****************************************************************************/
 
@@ -44,8 +44,12 @@ extern int dump_sensor;
 
 int s5k83a_probe(struct sd *sd);
 int s5k83a_init(struct sd *sd);
+int s5k83a_start(struct sd *sd);
+int s5k83a_stop(struct sd *sd);
 int s5k83a_power_down(struct sd *sd);
 
+int s5k83a_set_led_indication(struct sd *sd, u8 val);
+
 int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
 int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k83a_set_whiteness(struct gspca_dev *gspca_dev, __s32 val);
@@ -57,95 +61,15 @@ int s5k83a_set_vflip(struct gspca_dev *g
 int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 
-static struct m5602_sensor s5k83a = {
+static const struct m5602_sensor s5k83a = {
 	.name = "S5K83A",
 	.probe = s5k83a_probe,
 	.init = s5k83a_init,
+	.start = s5k83a_start,
+	.stop = s5k83a_stop,
 	.power_down = s5k83a_power_down,
 	.i2c_slave_id = 0x5a,
 	.i2c_regW = 2,
-	.nctrls = 5,
-	.ctrls = {
-	{
-		{
-			.id = V4L2_CID_BRIGHTNESS,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "brightness",
-			.minimum = 0x00,
-			.maximum = 0xff,
-			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_BRIGHTNESS,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-			.set = s5k83a_set_brightness,
-			.get = s5k83a_get_brightness
-
-	}, {
-		{
-			.id = V4L2_CID_WHITENESS,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "whiteness",
-			.minimum = 0x00,
-			.maximum = 0xff,
-			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_WHITENESS,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-			.set = s5k83a_set_whiteness,
-			.get = s5k83a_get_whiteness,
-	}, {
-		{
-			.id = V4L2_CID_GAIN,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "gain",
-			.minimum = 0x00,
-			.maximum = S5K83A_MAXIMUM_GAIN,
-			.step = 0x01,
-			.default_value = S5K83A_DEFAULT_GAIN,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-			.set = s5k83a_set_gain,
-			.get = s5k83a_get_gain
-	}, {
-		{
-			.id         = V4L2_CID_HFLIP,
-			.type       = V4L2_CTRL_TYPE_BOOLEAN,
-			.name       = "horizontal flip",
-			.minimum    = 0,
-			.maximum    = 1,
-			.step       = 1,
-			.default_value  = 0
-		},
-			.set = s5k83a_set_hflip,
-			.get = s5k83a_get_hflip
-	}, {
-		{
-		 .id         = V4L2_CID_VFLIP,
-		.type       = V4L2_CTRL_TYPE_BOOLEAN,
-		.name       = "vertical flip",
-		.minimum    = 0,
-		.maximum    = 1,
-		.step       = 1,
-		.default_value  = 0
-		},
-		.set = s5k83a_set_vflip,
-		.get = s5k83a_get_vflip
-		}
-	},
-	.nmodes = 1,
-	.modes = {
-	{
-		M5602_DEFAULT_FRAME_WIDTH,
-		M5602_DEFAULT_FRAME_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			M5602_DEFAULT_FRAME_WIDTH * M5602_DEFAULT_FRAME_HEIGHT,
-		.bytesperline = M5602_DEFAULT_FRAME_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
 };
 
 static const unsigned char preinit_s5k83a[][4] =
@@ -381,7 +305,7 @@ static const unsigned char init_s5k83a[]
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
 	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_sensor.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_sensor.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/m5602_sensor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/m5602_sensor.h	2009-06-09 23:05:27.000000000 -0400
@@ -21,11 +21,6 @@
 
 #include "m5602_bridge.h"
 
-#define M5602_DEFAULT_FRAME_WIDTH  640
-#define M5602_DEFAULT_FRAME_HEIGHT 480
-
-#define M5602_MAX_CTRLS		(V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
 /* Enumerates all supported sensors */
 enum sensors {
 	OV9650_SENSOR	= 1,
@@ -61,14 +56,14 @@ struct m5602_sensor {
 	/* Executed when the camera starts to send data */
 	int (*start)(struct sd *sd);
 
-	/* Performs a power down sequence */
-	int (*power_down)(struct sd *sd);
+	/* Executed when the camera ends to send data */
+	int (*stop)(struct sd *sd);
 
-	int nctrls;
-	struct ctrl ctrls[M5602_MAX_CTRLS];
+	/* Executed when the device is disconnected */
+	void (*disconnect)(struct sd *sd);
 
-	char nmodes;
-	struct v4l2_pix_format modes[];
+	/* Performs a power down sequence */
+	int (*power_down)(struct sd *sd);
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/m5602/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/m5602/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,5 +7,4 @@ gspca_m5602-objs := m5602_core.o \
 		    m5602_s5k83a.o \
 		    m5602_s5k4aa.o
 
-EXTRA_CFLAGS += -Idrivers/media/video/gspca
-
+EXTRA_CFLAGS += -Idrivers/media/video/gspca
\ No newline at end of file
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/gspca/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,50 +1,56 @@
-obj-$(CONFIG_USB_GSPCA)		+= gspca_main.o
-obj-$(CONFIG_USB_GSPCA_CONEX)	+= gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_ETOMS)	+= gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX)	+= gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_MARS)	+= gspca_mars.o
-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_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SONIXB)	+= gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ)	+= gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014)	+= gspca_stk014.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
-obj-$(CONFIG_USB_GSPCA_ZC3XX)	+= gspca_zc3xx.o
+obj-$(CONFIG_USB_GSPCA)          += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_CONEX)    += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_ETOMS)    += gspca_etoms.o
+obj-$(CONFIG_USB_GSPCA_FINEPIX)  += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_MARS)     += gspca_mars.o
+obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
+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_PAC7311)  += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SONIXB)   += gspca_sonixb.o
+obj-$(CONFIG_USB_GSPCA_SONIXJ)   += gspca_sonixj.o
+obj-$(CONFIG_USB_GSPCA_SPCA500)  += gspca_spca500.o
+obj-$(CONFIG_USB_GSPCA_SPCA501)  += gspca_spca501.o
+obj-$(CONFIG_USB_GSPCA_SPCA505)  += gspca_spca505.o
+obj-$(CONFIG_USB_GSPCA_SPCA506)  += gspca_spca506.o
+obj-$(CONFIG_USB_GSPCA_SPCA508)  += gspca_spca508.o
+obj-$(CONFIG_USB_GSPCA_SPCA561)  += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SQ905)    += gspca_sq905.o
+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_T613)     += gspca_t613.o
+obj-$(CONFIG_USB_GSPCA_TV8532)   += gspca_tv8532.o
+obj-$(CONFIG_USB_GSPCA_VC032X)   += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_ZC3XX)    += gspca_zc3xx.o
 
-gspca_main-objs			:= gspca.o
-gspca_conex-objs		:= conex.o
-gspca_etoms-objs		:= etoms.o
-gspca_finepix-objs		:= finepix.o
-gspca_mars-objs			:= mars.o
-gspca_ov519-objs		:= ov519.o
-gspca_ov534-objs		:= ov534.o
-gspca_pac207-objs		:= pac207.o
-gspca_pac7311-objs		:= pac7311.o
-gspca_sonixb-objs		:= sonixb.o
-gspca_sonixj-objs		:= sonixj.o
-gspca_spca500-objs		:= spca500.o
-gspca_spca501-objs		:= spca501.o
-gspca_spca505-objs		:= spca505.o
-gspca_spca506-objs		:= spca506.o
-gspca_spca508-objs		:= spca508.o
-gspca_spca561-objs		:= spca561.o
-gspca_stk014-objs		:= stk014.o
-gspca_sunplus-objs		:= sunplus.o
-gspca_t613-objs			:= t613.o
-gspca_tv8532-objs		:= tv8532.o
-gspca_vc032x-objs		:= vc032x.o
-gspca_zc3xx-objs		:= zc3xx.o
+gspca_main-objs     := gspca.o
+gspca_conex-objs    := conex.o
+gspca_etoms-objs    := etoms.o
+gspca_finepix-objs  := finepix.o
+gspca_mars-objs     := mars.o
+gspca_mr97310a-objs := mr97310a.o
+gspca_ov519-objs    := ov519.o
+gspca_ov534-objs    := ov534.o
+gspca_pac207-objs   := pac207.o
+gspca_pac7311-objs  := pac7311.o
+gspca_sonixb-objs   := sonixb.o
+gspca_sonixj-objs   := sonixj.o
+gspca_spca500-objs  := spca500.o
+gspca_spca501-objs  := spca501.o
+gspca_spca505-objs  := spca505.o
+gspca_spca506-objs  := spca506.o
+gspca_spca508-objs  := spca508.o
+gspca_spca561-objs  := spca561.o
+gspca_sq905-objs    := sq905.o
+gspca_sq905c-objs   := sq905c.o
+gspca_stk014-objs   := stk014.o
+gspca_sunplus-objs  := sunplus.o
+gspca_t613-objs     := t613.o
+gspca_tv8532-objs   := tv8532.o
+gspca_vc032x-objs   := vc032x.o
+gspca_zc3xx-objs    := zc3xx.o
 
-obj-$(CONFIG_USB_M5602)		+= m5602/
-obj-$(CONFIG_USB_STV06XX) 	+= stv06xx/
+obj-$(CONFIG_USB_M5602)   += m5602/
+obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/mars.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/mars.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/mars.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/mars.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,17 +32,91 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	char qindex;
+	u8 brightness;
+	u8 colors;
+	u8 gamma;
+	u8 sharpness;
+	u8 quality;
+#define QUALITY_MIN 40
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
+
+	u8 *jpeg_hdr;
 };
 
 /* 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_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(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 struct ctrl sd_ctrls[] = {
+	{
+	    {
+		.id      = V4L2_CID_BRIGHTNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Brightness",
+		.minimum = 0,
+		.maximum = 30,
+		.step    = 1,
+#define BRIGHTNESS_DEF 15
+		.default_value = BRIGHTNESS_DEF,
+	    },
+	    .set = sd_setbrightness,
+	    .get = sd_getbrightness,
+	},
+	{
+	    {
+		.id      = V4L2_CID_SATURATION,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Color",
+		.minimum = 1,
+		.maximum = 255,
+		.step    = 1,
+#define COLOR_DEF 200
+		.default_value = COLOR_DEF,
+	    },
+	    .set = sd_setcolors,
+	    .get = sd_getcolors,
+	},
+	{
+	    {
+		.id      = V4L2_CID_GAMMA,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Gamma",
+		.minimum = 0,
+		.maximum = 3,
+		.step    = 1,
+#define GAMMA_DEF 1
+		.default_value = GAMMA_DEF,
+	    },
+	    .set = sd_setgamma,
+	    .get = sd_getgamma,
+	},
+	{
+	    {
+		.id	 = V4L2_CID_SHARPNESS,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Sharpness",
+		.minimum = 0,
+		.maximum = 2,
+		.step    = 1,
+#define SHARPNESS_DEF 1
+		.default_value = SHARPNESS_DEF,
+	    },
+	    .set = sd_setsharpness,
+	    .get = sd_getsharpness,
+	},
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 320,
-		.sizeimage = 320 * 240 * 3 / 8 + 589,
+		.sizeimage = 320 * 240 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 2},
 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -52,65 +126,45 @@ static const struct v4l2_pix_format vga_
 		.priv = 1},
 };
 
-/* MI Register table //elvis */
-enum {
-	REG_HW_MI_0,
-	REG_HW_MI_1,
-	REG_HW_MI_2,
-	REG_HW_MI_3,
-	REG_HW_MI_4,
-	REG_HW_MI_5,
-	REG_HW_MI_6,
-	REG_HW_MI_7,
-	REG_HW_MI_9 = 0x09,
-	REG_HW_MI_B = 0x0B,
-	REG_HW_MI_C,
-	REG_HW_MI_D,
-	REG_HW_MI_1E = 0x1E,
-	REG_HW_MI_20 = 0x20,
-	REG_HW_MI_2B = 0x2B,
-	REG_HW_MI_2C,
-	REG_HW_MI_2D,
-	REG_HW_MI_2E,
-	REG_HW_MI_35 = 0x35,
-	REG_HW_MI_5F = 0x5f,
-	REG_HW_MI_60,
-	REG_HW_MI_61,
-	REG_HW_MI_62,
-	REG_HW_MI_63,
-	REG_HW_MI_64,
-	REG_HW_MI_F1 = 0xf1,
-	ATTR_TOTAL_MI_REG = 0xf2
+static const __u8 mi_data[0x20] = {
+/*	 01    02   03     04    05    06    07    08 */
+	0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
+/*	 09    0a   0b     0c    0d    0e    0f    10 */
+	0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
+/*	 11    12   13     14    15    16    17    18 */
+	0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
+/*	 19    1a   1b     1c    1d    1e    1f    20 */
+	0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
 };
 
-/* the bytes to write are in gspca_dev->usb_buf */
+/* write <len> bytes from gspca_dev->usb_buf */
 static int reg_w(struct gspca_dev *gspca_dev,
-		 __u16 index, int len)
+		 int len)
 {
-	int rc;
+	int alen, ret;
 
-	rc = usb_control_msg(gspca_dev->dev,
-			 usb_sndbulkpipe(gspca_dev->dev, 4),
-			 0x12,
-			 0xc8,		/* ?? */
-			 0,		/* value */
-			 index, gspca_dev->usb_buf, len, 500);
-	if (rc < 0)
-		PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
-	return rc;
+	ret = usb_bulk_msg(gspca_dev->dev,
+			usb_sndbulkpipe(gspca_dev->dev, 4),
+			gspca_dev->usb_buf,
+			len,
+			&alen,
+			500);	/* timeout in milliseconds */
+	if (ret < 0)
+		PDEBUG(D_ERR, "reg write [%02x] error %d",
+			gspca_dev->usb_buf[0], ret);
+	return ret;
 }
 
-static void bulk_w(struct gspca_dev *gspca_dev,
-		   __u16 *pch,
-		   __u16 Address)
+static void mi_w(struct gspca_dev *gspca_dev,
+		 u8 addr,
+		 u8 value)
 {
 	gspca_dev->usb_buf[0] = 0x1f;
 	gspca_dev->usb_buf[1] = 0;			/* control byte */
-	gspca_dev->usb_buf[2] = Address;
-	gspca_dev->usb_buf[3] = *pch >> 8;		/* high byte */
-	gspca_dev->usb_buf[4] = *pch;			/* low byte */
+	gspca_dev->usb_buf[2] = addr;
+	gspca_dev->usb_buf[3] = value;
 
-	reg_w(gspca_dev, Address, 5);
+	reg_w(gspca_dev, 4);
 }
 
 /* this function is called at probe time */
@@ -121,10 +175,14 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
-	sd->qindex = 1;			/* set the quantization table */
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->colors = COLOR_DEF;
+	sd->gamma = GAMMA_DEF;
+	sd->sharpness = SHARPNESS_DEF;
+	sd->quality = QUALITY_DEF;
+	gspca_dev->nbalt = 9;		/* use the altsetting 08 */
 	return 0;
 }
 
@@ -136,24 +194,22 @@ static int sd_init(struct gspca_dev *gsp
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	int err_code;
-	__u8 *data;
-	__u16 *MI_buf;
-	int h_size, v_size;
-	int intpipe;
+	u8 *data;
+	int i;
 
-	PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
-	err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
-	if (err_code < 0) {
-		PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
-		return err_code;
-	}
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x21);		/* JPEG 422 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 
 	data = gspca_dev->usb_buf;
+
 	data[0] = 0x01;		/* address */
 	data[1] = 0x01;
-
-	err_code = reg_w(gspca_dev, data[0], 2);
+	err_code = reg_w(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
@@ -163,30 +219,28 @@ static int sd_start(struct gspca_dev *gs
 	data[0] = 0x00;		/* address */
 	data[1] = 0x0c | 0x01;	/* reg 0 */
 	data[2] = 0x01;		/* reg 1 */
-	h_size = gspca_dev->width;
-	v_size = gspca_dev->height;
-	data[3] = h_size / 8;	/* h_size , reg 2 */
-	data[4] = v_size / 8;	/* v_size , reg 3 */
+	data[3] = gspca_dev->width / 8;		/* h_size , reg 2 */
+	data[4] = gspca_dev->height / 8;	/* v_size , reg 3 */
 	data[5] = 0x30;		/* reg 4, MI, PAS5101 :
 				 *	0x30 for 24mhz , 0x28 for 12mhz */
-	data[6] = 4;		/* reg 5, H start */
-	data[7] = 0xc0;		/* reg 6, gamma 1.5 */
-	data[8] = 3;		/* reg 7, V start */
+	data[6] = 0x02;		/* reg 5, H start - was 0x04 */
+	data[7] = sd->gamma * 0x40;	/* reg 0x06: gamma */
+	data[8] = 0x01;		/* reg 7, V start - was 0x03 */
 /*	if (h_size == 320 ) */
 /*		data[9]= 0x56;	 * reg 8, 24MHz, 2:1 scale down */
 /*	else */
 	data[9] = 0x52;		/* reg 8, 24MHz, no scale down */
-	data[10] = 0x5d;	/* reg 9, I2C device address
-				 *	[for PAS5101 (0x40)] [for MI (0x5d)] */
+/*jfm: from win trace*/
+	data[10] = 0x18;
 
-	err_code = reg_w(gspca_dev, data[0], 11);
+	err_code = reg_w(gspca_dev, 11);
 	if (err_code < 0)
 		return err_code;
 
 	data[0] = 0x23;		/* address */
 	data[1] = 0x09;		/* reg 35, append frame header */
 
-	err_code = reg_w(gspca_dev, data[0], 2);
+	err_code = reg_w(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
@@ -197,137 +251,57 @@ static int sd_start(struct gspca_dev *gs
 /*	else */
 	data[1] = 50;		/* 50 reg 60, pc-cam frame size
 				 *	(unit: 4KB) 200KB */
-	err_code = reg_w(gspca_dev, data[0], 2);
+	err_code = reg_w(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
-	if (0) {			/* fixed dark-gain */
-		data[1] = 0;		/* reg 94, Y Gain (1.75) */
-		data[2] = 0;		/* reg 95, UV Gain (1.75) */
-		data[3] = 0x3f;		/* reg 96, Y Gain/UV Gain/disable
-					 *	auto dark-gain */
-		data[4] = 0;		/* reg 97, set fixed dark level */
-		data[5] = 0;		/* reg 98, don't care */
-	} else {			/* auto dark-gain */
-		data[1] = 0;		/* reg 94, Y Gain (auto) */
-		data[2] = 0;		/* reg 95, UV Gain (1.75) */
-		data[3] = 0x78;		/* reg 96, Y Gain/UV Gain/disable
-					 *	auto dark-gain */
-		switch (gspca_dev->width) {
-/*		case 1280: */
-/*			data[4] = 154;
-				 * reg 97, %3 shadow point (unit: 256 pixel) */
-/*			data[5] = 51;
-				 * reg 98, %1 highlight point
-				 *	(uint: 256 pixel) */
-/*			break; */
-		default:
-/*		case 640: */
-			data[4] = 36;	/* reg 97, %3 shadow point
-					 *	(unit: 256 pixel) */
-			data[5] = 12;	/* reg 98, %1 highlight point
-					 *	(uint: 256 pixel) */
-			break;
-		case 320:
-			data[4] = 9;	/* reg 97, %3 shadow point
-					 *	(unit: 256 pixel) */
-			data[5] = 3;	/* reg 98, %1 highlight point
-					 *	(uint: 256 pixel) */
-			break;
-		}
-	}
 	/* auto dark-gain */
 	data[0] = 0x5e;		/* address */
+	data[1] = 0;		/* reg 94, Y Gain (auto) */
+/*jfm: from win trace*/
+				/* reg 0x5f/0x60 (LE) = saturation */
+				/* h (60): xxxx x100
+				 * l (5f): xxxx x000 */
+	data[2] = sd->colors << 3;
+	data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
+	data[4] = sd->brightness; /* reg 0x61 = brightness */
+	data[5] = 0x00;
 
-	err_code = reg_w(gspca_dev, data[0], 6);
+	err_code = reg_w(gspca_dev, 6);
 	if (err_code < 0)
 		return err_code;
 
 	data[0] = 0x67;
-	data[1] = 0x13;		/* reg 103, first pixel B, disable sharpness */
-	err_code = reg_w(gspca_dev, data[0], 2);
+/*jfm: from win trace*/
+	data[1] = sd->sharpness * 4 + 3;
+	data[2] = 0x14;
+	err_code = reg_w(gspca_dev, 3);
 	if (err_code < 0)
 		return err_code;
 
-	/*
-	 * initialize the value of MI sensor...
-	 */
-	MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
-	MI_buf[REG_HW_MI_1] = 0x000a;
-	MI_buf[REG_HW_MI_2] = 0x000c;
-	MI_buf[REG_HW_MI_3] = 0x0405;
-	MI_buf[REG_HW_MI_4] = 0x0507;
-	/* mi_Attr_Reg_[REG_HW_MI_5]	 = 0x01ff;//13 */
-	MI_buf[REG_HW_MI_5] = 0x0013;	/* 13 */
-	MI_buf[REG_HW_MI_6] = 0x001f;	/* vertical blanking */
-	/* mi_Attr_Reg_[REG_HW_MI_6]	 = 0x0400;  // vertical blanking */
-	MI_buf[REG_HW_MI_7] = 0x0002;
-	/* mi_Attr_Reg_[REG_HW_MI_9]	 = 0x015f; */
-	/* mi_Attr_Reg_[REG_HW_MI_9]	 = 0x030f; */
-	MI_buf[REG_HW_MI_9] = 0x0374;
-	MI_buf[REG_HW_MI_B] = 0x0000;
-	MI_buf[REG_HW_MI_C] = 0x0000;
-	MI_buf[REG_HW_MI_D] = 0x0000;
-	MI_buf[REG_HW_MI_1E] = 0x8000;
-/* mi_Attr_Reg_[REG_HW_MI_20]	  = 0x1104; */
-	MI_buf[REG_HW_MI_20] = 0x1104;	/* 0x111c; */
-	MI_buf[REG_HW_MI_2B] = 0x0008;
-/* mi_Attr_Reg_[REG_HW_MI_2C]	  = 0x000f; */
-	MI_buf[REG_HW_MI_2C] = 0x001f;	/* lita suggest */
-	MI_buf[REG_HW_MI_2D] = 0x0008;
-	MI_buf[REG_HW_MI_2E] = 0x0008;
-	MI_buf[REG_HW_MI_35] = 0x0051;
-	MI_buf[REG_HW_MI_5F] = 0x0904;	/* fail to write */
-	MI_buf[REG_HW_MI_60] = 0x0000;
-	MI_buf[REG_HW_MI_61] = 0x0000;
-	MI_buf[REG_HW_MI_62] = 0x0498;
-	MI_buf[REG_HW_MI_63] = 0x0000;
-	MI_buf[REG_HW_MI_64] = 0x0000;
-	MI_buf[REG_HW_MI_F1] = 0x0001;
-	/* changing while setting up the different value of dx/dy */
-
-	if (gspca_dev->width != 1280) {
-		MI_buf[0x01] = 0x010a;
-		MI_buf[0x02] = 0x014c;
-		MI_buf[0x03] = 0x01e5;
-		MI_buf[0x04] = 0x0287;
-	}
-	MI_buf[0x20] = 0x1104;
+	data[0] = 0x69;
+	data[1] = 0x2f;
+	data[2] = 0x28;
+	data[3] = 0x42;
+	err_code = reg_w(gspca_dev, 4);
+	if (err_code < 0)
+		return err_code;
 
-	bulk_w(gspca_dev, MI_buf + 1, 1);
-	bulk_w(gspca_dev, MI_buf + 2, 2);
-	bulk_w(gspca_dev, MI_buf + 3, 3);
-	bulk_w(gspca_dev, MI_buf + 4, 4);
-	bulk_w(gspca_dev, MI_buf + 5, 5);
-	bulk_w(gspca_dev, MI_buf + 6, 6);
-	bulk_w(gspca_dev, MI_buf + 7, 7);
-	bulk_w(gspca_dev, MI_buf + 9, 9);
-	bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
-	bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
-	bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
-	bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
-	bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
-	bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
-	bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
-	bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
-	bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
-	bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
-	bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
-	bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
-	bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
-	bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
-	bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
-	bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
-	bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
-	kfree(MI_buf);
+	data[0] = 0x63;
+	data[1] = 0x07;
+	err_code = reg_w(gspca_dev, 2);
+/*jfm: win trace - many writes here to reg 0x64*/
+	if (err_code < 0)
+		return err_code;
 
-	intpipe = usb_sndintpipe(gspca_dev->dev, 0);
-	err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+	/* initialize the MI sensor */
+	for (i = 0; i < sizeof mi_data; i++)
+		mi_w(gspca_dev, i + 1, mi_data[i]);
 
 	data[0] = 0x00;
 	data[1] = 0x4d;		/* ISOC transfering enable... */
-	reg_w(gspca_dev, data[0], 2);
-	return err_code;
+	reg_w(gspca_dev, 2);
+	return 0;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -336,11 +310,18 @@ static void sd_stopN(struct gspca_dev *g
 
 	gspca_dev->usb_buf[0] = 1;
 	gspca_dev->usb_buf[1] = 0;
-	result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+	result = reg_w(gspca_dev, 2);
 	if (result < 0)
 		PDEBUG(D_ERR, "Camera Stop failed");
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	kfree(sd->jpeg_hdr);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -363,16 +344,16 @@ static void sd_pkt_scan(struct gspca_dev
 			    || data[5 + p] == 0x65
 			    || data[5 + p] == 0x66
 			    || data[5 + p] == 0x67) {
-				PDEBUG(D_PACK, "sof offset: %d leng: %d",
+				PDEBUG(D_PACK, "sof offset: %d len: %d",
 					p, len);
 				frame = gspca_frame_add(gspca_dev, LAST_PACKET,
-							frame, data, 0);
+							frame, data, p);
 
 				/* put the JPEG header */
-				jpeg_put_header(gspca_dev, frame,
-						sd->qindex, 0x21);
-				data += 16;
-				len -= 16;
+				gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+					sd->jpeg_hdr, JPEG_HDR_SZ);
+				data += p + 16;
+				len -= p + 16;
 				break;
 			}
 		}
@@ -380,6 +361,121 @@ static void sd_pkt_scan(struct gspca_dev
 	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) {
+		gspca_dev->usb_buf[0] = 0x61;
+		gspca_dev->usb_buf[1] = val;
+		reg_w(gspca_dev, 2);
+	}
+	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_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->colors = val;
+	if (gspca_dev->streaming) {
+
+		/* see sd_start */
+		gspca_dev->usb_buf[0] = 0x5f;
+		gspca_dev->usb_buf[1] = sd->colors << 3;
+		gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
+		reg_w(gspca_dev, 3);
+	}
+	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_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gamma = val;
+	if (gspca_dev->streaming) {
+		gspca_dev->usb_buf[0] = 0x06;
+		gspca_dev->usb_buf[1] = val * 0x40;
+		reg_w(gspca_dev, 2);
+	}
+	return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gamma;
+	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) {
+		gspca_dev->usb_buf[0] = 0x67;
+		gspca_dev->usb_buf[1] = val * 4 + 3;
+		reg_w(gspca_dev, 2);
+	}
+	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_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -389,7 +485,10 @@ static const struct sd_desc sd_desc = {
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -421,8 +520,11 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/mr97310a.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/mr97310a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/mr97310a.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/mr97310a.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,362 @@
+/*
+ * Mars MR97310A library
+ *
+ * Copyright (C) 2009 Kyle Guinn <elyk03@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
+ * 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 "mr97310a"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;  /* !! must be the first item */
+	u8 sof_read;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+	{160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 4},
+	{176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+		.bytesperline = 176,
+		.sizeimage = 176 * 144,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3},
+	{320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+		.bytesperline = 352,
+		.sizeimage = 352 * 288,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev, int len)
+{
+	int rc;
+
+	rc = usb_bulk_msg(gspca_dev->dev,
+			  usb_sndbulkpipe(gspca_dev->dev, 4),
+			  gspca_dev->usb_buf, len, NULL, 500);
+	if (rc < 0)
+		PDEBUG(D_ERR, "reg write [%02x] error %d",
+		       gspca_dev->usb_buf[0], rc);
+	return rc;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+		     const struct usb_device_id *id)
+{
+	struct cam *cam;
+
+	cam = &gspca_dev->cam;
+	cam->cam_mode = vga_mode;
+	cam->nmodes = ARRAY_SIZE(vga_mode);
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u8 *data = gspca_dev->usb_buf;
+	int err_code;
+
+	sd->sof_read = 0;
+
+	/* Note:  register descriptions guessed from MR97113A driver */
+
+	data[0] = 0x01;
+	data[1] = 0x01;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x00;
+	data[1] = 0x0d;
+	data[2] = 0x01;
+	data[5] = 0x2b;
+	data[7] = 0x00;
+	data[9] = 0x50;  /* reg 8, no scale down */
+	data[10] = 0xc0;
+
+	switch (gspca_dev->width) {
+	case 160:
+		data[9] |= 0x0c;  /* reg 8, 4:1 scale down */
+		/* fall thru */
+	case 320:
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
+		/* fall thru */
+	case 640:
+	default:
+		data[3] = 0x50;  /* reg 2, H size */
+		data[4] = 0x78;  /* reg 3, V size */
+		data[6] = 0x04;  /* reg 5, H start */
+		data[8] = 0x03;  /* reg 7, V start */
+		break;
+
+	case 176:
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
+		/* fall thru */
+	case 352:
+		data[3] = 0x2c;  /* reg 2, H size */
+		data[4] = 0x48;  /* reg 3, V size */
+		data[6] = 0x94;  /* reg 5, H start */
+		data[8] = 0x63;  /* reg 7, V start */
+		break;
+	}
+
+	err_code = reg_w(gspca_dev, 11);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x0a;
+	data[1] = 0x80;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x14;
+	data[1] = 0x0a;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1b;
+	data[1] = 0x00;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x15;
+	data[1] = 0x16;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x16;
+	data[1] = 0x10;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x17;
+	data[1] = 0x3a;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x18;
+	data[1] = 0x68;
+	err_code = reg_w(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x00;
+	data[2] = 0x02;
+	data[3] = 0x06;
+	data[4] = 0x59;
+	data[5] = 0x0c;
+	data[6] = 0x16;
+	data[7] = 0x00;
+	data[8] = 0x07;
+	data[9] = 0x00;
+	data[10] = 0x01;
+	err_code = reg_w(gspca_dev, 11);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x04;
+	data[2] = 0x11;
+	data[3] = 0x01;
+	err_code = reg_w(gspca_dev, 4);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x00;
+	data[2] = 0x0a;
+	data[3] = 0x00;
+	data[4] = 0x01;
+	data[5] = 0x00;
+	data[6] = 0x00;
+	data[7] = 0x01;
+	data[8] = 0x00;
+	data[9] = 0x0a;
+	err_code = reg_w(gspca_dev, 10);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x04;
+	data[2] = 0x11;
+	data[3] = 0x01;
+	err_code = reg_w(gspca_dev, 4);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x00;
+	data[2] = 0x12;
+	data[3] = 0x00;
+	data[4] = 0x63;
+	data[5] = 0x00;
+	data[6] = 0x70;
+	data[7] = 0x00;
+	data[8] = 0x00;
+	err_code = reg_w(gspca_dev, 9);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x1f;
+	data[1] = 0x04;
+	data[2] = 0x11;
+	data[3] = 0x01;
+	err_code = reg_w(gspca_dev, 4);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x00;
+	data[1] = 0x4d;  /* ISOC transfering enable... */
+	err_code = reg_w(gspca_dev, 2);
+	return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	int result;
+
+	gspca_dev->usb_buf[0] = 1;
+	gspca_dev->usb_buf[1] = 0;
+	result = reg_w(gspca_dev, 2);
+	if (result < 0)
+		PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+/* 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 */
+{
+	unsigned char *sof;
+
+	sof = pac_find_sof(gspca_dev, data, len);
+	if (sof) {
+		int n;
+
+		/* finish decoding current frame */
+		n = sof - data;
+		if (n > sizeof pac_sof_marker)
+			n -= sizeof pac_sof_marker;
+		else
+			n = 0;
+		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+					data, n);
+		/* Start next frame. */
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			pac_sof_marker, sizeof pac_sof_marker);
+		len -= sof - data;
+		data = sof;
+	}
+	gspca_frame_add(gspca_dev, INTER_PACKET, frame, 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,
+	.pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x08ca, 0x0111)},
+	{}
+};
+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)
+{
+	if (usb_register(&sd_driver) < 0)
+		return -1;
+	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.29-gnu1/drivers/media/video/gspca/ov519.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov519.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/ov519.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov519.c	2009-06-09 23:05:27.000000000 -0400
@@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *g
 	}
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = OV511_ENDPOINT_ADDRESS;
 	if (!sd->sif) {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2177,8 +2176,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/ov534.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov534.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/ov534.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov534.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,8 @@
 /*
- * ov534/ov772x gspca driver
+ * 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
  *
  * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
  * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
@@ -26,7 +27,7 @@
 
 #include "gspca.h"
 
-#define OV534_REG_ADDRESS	0xf1	/* ? */
+#define OV534_REG_ADDRESS	0xf1	/* sensor address */
 #define OV534_REG_SUBADDR	0xf2
 #define OV534_REG_WRITE		0xf3
 #define OV534_REG_READ		0xf4
@@ -46,9 +47,13 @@ MODULE_LICENSE("GPL");
 /* specific webcam descriptor */
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
-	__u32 last_fid;
 	__u32 last_pts;
-	int frame_rate;
+	u16 last_fid;
+	u8 frame_rate;
+
+	u8 sensor;
+#define SENSOR_OV772X 0
+#define SENSOR_OV965X 1
 };
 
 /* V4L2 controls supported by the driver */
@@ -63,114 +68,7 @@ static const struct v4l2_pix_format vga_
 	 .priv = 0},
 };
 
-static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
-	struct usb_device *udev = gspca_dev->dev;
-	int ret;
-
-	PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
-	gspca_dev->usb_buf[0] = val;
-	ret = usb_control_msg(udev,
-			      usb_sndctrlpipe(udev, 0),
-			      0x1,
-			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			      0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	if (ret < 0)
-		PDEBUG(D_ERR, "write failed");
-}
-
-static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
-	struct usb_device *udev = gspca_dev->dev;
-	int ret;
-
-	ret = usb_control_msg(udev,
-			      usb_rcvctrlpipe(udev, 0),
-			      0x1,
-			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			      0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
-	if (ret < 0)
-		PDEBUG(D_ERR, "read failed");
-	return gspca_dev->usb_buf[0];
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
-{
-	u8 data;
-
-	PDEBUG(D_CONF, "led status: %d", status);
-
-	data = ov534_reg_read(gspca_dev, 0x21);
-	data |= 0x80;
-	ov534_reg_write(gspca_dev, 0x21, data);
-
-	data = ov534_reg_read(gspca_dev, 0x23);
-	if (status)
-		data |= 0x80;
-	else
-		data &= ~(0x80);
-
-	ov534_reg_write(gspca_dev, 0x23, data);
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
-	u8 data;
-	int i;
-
-	for (i = 0; i < 5; i++) {
-		data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
-
-		switch (data) {
-		case 0x00:
-			return 1;
-		case 0x04:
-			return 0;
-		case 0x03:
-			break;
-		default:
-			PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
-			       data, i + 1);
-		}
-	}
-	return 0;
-}
-
-static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
-	PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
-	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
-	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
-	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
-	if (!sccb_check_status(gspca_dev))
-		PDEBUG(D_ERR, "sccb_reg_write failed");
-}
-
-#ifdef GSPCA_DEBUG
-static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
-	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
-	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
-	if (!sccb_check_status(gspca_dev))
-		PDEBUG(D_ERR, "sccb_reg_read failed 1");
-
-	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
-	if (!sccb_check_status(gspca_dev))
-		PDEBUG(D_ERR, "sccb_reg_read failed 2");
-
-	return ov534_reg_read(gspca_dev, OV534_REG_READ);
-}
-#endif
-
-static const __u8 ov534_reg_initdata[][2] = {
-	{ 0xe7, 0x3a },
-
-	{ OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
-
+static const u8 bridge_init_ov722x[][2] = {
 	{ 0xc2, 0x0c },
 	{ 0x88, 0xf8 },
 	{ 0xc3, 0x69 },
@@ -228,7 +126,7 @@ static const __u8 ov534_reg_initdata[][2
 	{ 0xc2, 0x0c },
 };
 
-static const __u8 ov772x_reg_initdata[][2] = {
+static const u8 sensor_init_ov722x[][2] = {
 	{ 0x12, 0x80 },
 	{ 0x11, 0x01 },
 
@@ -311,6 +209,456 @@ static const __u8 ov772x_reg_initdata[][
 	{ 0x0c, 0xd0 }
 };
 
+static const u8 bridge_init_ov965x[][2] = {
+	{0x88, 0xf8},
+	{0x89, 0xff},
+	{0x76, 0x03},
+	{0x92, 0x03},
+	{0x95, 0x10},
+	{0xe2, 0x00},
+	{0xe7, 0x3e},
+	{0x8d, 0x1c},
+	{0x8e, 0x00},
+	{0x8f, 0x00},
+	{0x1f, 0x00},
+	{0xc3, 0xf9},
+	{0x89, 0xff},
+	{0x88, 0xf8},
+	{0x76, 0x03},
+	{0x92, 0x01},
+	{0x93, 0x18},
+	{0x1c, 0x0a},
+	{0x1d, 0x48},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x34, 0x05},
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0x34, 0x05},
+	{0xe7, 0x2e},
+	{0x31, 0xf9},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x25, 0x42},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x[][2] = {
+	{0x12, 0x80},	/* com7 - reset */
+	{0x00, 0x00},	/* gain */
+	{0x01, 0x80},	/* blue */
+	{0x02, 0x80},	/* red */
+	{0x03, 0x1b},	/* vref */
+	{0x04, 0x03},	/* com1 - exposure low bits */
+	{0x0b, 0x57},	/* ver */
+	{0x0e, 0x61},	/* com5 */
+	{0x0f, 0x42},	/* com6 */
+	{0x11, 0x00},	/* clkrc */
+	{0x12, 0x02},	/* com7 */
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x14, 0x28},	/* com9 */
+	{0x16, 0x24},	/* rsvd16 */
+	{0x17, 0x1d},	/* hstart*/
+	{0x18, 0xbd},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x81},	/* vstop*/
+	{0x1e, 0x04},	/* mvfp */
+	{0x24, 0x3c},	/* aew */
+	{0x25, 0x36},	/* aeb */
+	{0x26, 0x71},	/* vpt */
+	{0x27, 0x08},	/* bbias */
+	{0x28, 0x08},	/* gbbias */
+	{0x29, 0x15},	/* gr com */
+	{0x2a, 0x00},
+	{0x2b, 0x00},
+	{0x2c, 0x08},	/* rbias */
+	{0x32, 0xff},	/* href */
+	{0x33, 0x00},	/* chlf */
+	{0x34, 0x3f},	/* arblm */
+	{0x35, 0x00},	/* rsvd35 */
+	{0x36, 0xf8},	/* rsvd36 */
+	{0x38, 0x72},	/* acom38 */
+	{0x39, 0x57},	/* ofon */
+	{0x3a, 0x80},	/* tslb */
+	{0x3b, 0xc4},
+	{0x3d, 0x99},	/* com13 */
+	{0x3f, 0xc1},
+	{0x40, 0xc0},	/* com15 */
+	{0x41, 0x40},	/* com16 */
+	{0x42, 0xc0},
+	{0x43, 0x0a},
+	{0x44, 0xf0},
+	{0x45, 0x46},
+	{0x46, 0x62},
+	{0x47, 0x2a},
+	{0x48, 0x3c},
+	{0x4a, 0xfc},
+	{0x4b, 0xfc},
+	{0x4c, 0x7f},
+	{0x4d, 0x7f},
+	{0x4e, 0x7f},
+	{0x4f, 0x98},
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},
+	{0x59, 0x85},
+	{0x5a, 0xa9},
+	{0x5b, 0x64},
+	{0x5c, 0x84},
+	{0x5d, 0x53},
+	{0x5e, 0x0e},
+	{0x5f, 0xf0},
+	{0x60, 0xf0},
+	{0x61, 0xf0},
+	{0x62, 0x00},	/* lcc1 */
+	{0x63, 0x00},	/* lcc2 */
+	{0x64, 0x02},	/* lcc3 */
+	{0x65, 0x16},	/* lcc4 */
+	{0x66, 0x01},	/* lcc5 */
+	{0x69, 0x02},	/* hv */
+	{0x6b, 0x5a},	/* dbvl */
+	{0x6c, 0x04},
+	{0x6d, 0x55},
+	{0x6e, 0x00},
+	{0x6f, 0x9d},
+	{0x70, 0x21},
+	{0x71, 0x78},
+	{0x72, 0x00},
+	{0x73, 0x01},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0x77, 0x02},
+	{0x7a, 0x12},
+	{0x7b, 0x08},
+	{0x7c, 0x16},
+	{0x7d, 0x30},
+	{0x7e, 0x5e},
+	{0x7f, 0x72},
+	{0x80, 0x82},
+	{0x81, 0x8e},
+	{0x82, 0x9a},
+	{0x83, 0xa4},
+	{0x84, 0xac},
+	{0x85, 0xb8},
+	{0x86, 0xc3},
+	{0x87, 0xd6},
+	{0x88, 0xe6},
+	{0x89, 0xf2},
+	{0x8a, 0x03},
+	{0x8c, 0x89},
+	{0x14, 0x28},	/* com9 */
+	{0x90, 0x7d},
+	{0x91, 0x7b},
+	{0x9d, 0x03},
+	{0x9e, 0x04},
+	{0x9f, 0x7a},
+	{0xa0, 0x79},
+	{0xa1, 0x40},	/* aechm */
+	{0xa4, 0x50},
+	{0xa5, 0x68},	/* com26 */
+	{0xa6, 0x4a},
+	{0xa8, 0xc1},	/* acoma8 */
+	{0xa9, 0xef},	/* acoma9 */
+	{0xaa, 0x92},
+	{0xab, 0x04},
+	{0xac, 0x80},
+	{0xad, 0x80},
+	{0xae, 0x80},
+	{0xaf, 0x80},
+	{0xb2, 0xf2},
+	{0xb3, 0x20},
+	{0xb4, 0x20},
+	{0xb5, 0x00},
+	{0xb6, 0xaf},
+	{0xbb, 0xae},
+	{0xbc, 0x7f},
+	{0xdb, 0x7f},
+	{0xbe, 0x7f},
+	{0xbf, 0x7f},
+	{0xc0, 0xe2},
+	{0xc1, 0xc0},
+	{0xc2, 0x01},
+	{0xc3, 0x4e},
+	{0xc6, 0x85},
+	{0xc7, 0x80},
+	{0xc9, 0xe0},
+	{0xca, 0xe8},
+	{0xcb, 0xf0},
+	{0xcc, 0xd8},
+	{0xcd, 0xf1},
+	{0x4f, 0x98},
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},
+	{0xff, 0x41},	/* read 41, write ff 00 */
+	{0x41, 0x40},	/* com16 */
+	{0xc5, 0x03},
+	{0x6a, 0x02},
+
+	{0x12, 0x62},	/* com7 - VGA + CIF */
+	{0x36, 0xfa},	/* rsvd36 */
+	{0x69, 0x0a},	/* hv */
+	{0x8c, 0x89},	/* com22 */
+	{0x14, 0x28},	/* com9 */
+	{0x3e, 0x0c},
+	{0x41, 0x40},	/* com16 */
+	{0x72, 0x00},
+	{0x73, 0x00},
+	{0x74, 0x3a},
+	{0x75, 0x35},
+	{0x76, 0x01},
+	{0xc7, 0x80},
+	{0x03, 0x12},	/* vref */
+	{0x17, 0x16},	/* hstart */
+	{0x18, 0x02},	/* hstop */
+	{0x19, 0x01},	/* vstrt */
+	{0x1a, 0x3d},	/* vstop */
+	{0x32, 0xff},	/* href */
+	{0xc0, 0xaa},
+};
+
+static const u8 bridge_init_ov965x_2[][2] = {
+	{0x94, 0xaa},
+	{0xf1, 0x60},
+	{0xe5, 0x04},
+	{0xc0, 0x50},
+	{0xc1, 0x3c},
+	{0x8c, 0x00},
+	{0x8d, 0x1c},
+	{0x34, 0x05},
+
+	{0xc2, 0x0c},
+	{0xc3, 0xf9},
+	{0xda, 0x01},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x3c},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0xa0},
+	{0x5b, 0x78},
+	{0x35, 0x02},
+	{0xd9, 0x10},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x_2[][2] = {
+	{0x3b, 0xc4},
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},	/* gain */
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x03},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x05},
+	{0xc5, 0x07},
+	{0xa2, 0x4b},
+	{0xa3, 0x3e},
+	{0x2d, 0x00},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc0},
+	{0x2d, 0x00},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc1},
+	{0x3f, 0x01},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc1},
+	{0x4f, 0x98},
+	{0x50, 0x98},
+	{0x51, 0x00},
+	{0x52, 0x28},
+	{0x53, 0x70},
+	{0x54, 0x98},
+	{0x58, 0x1a},
+	{0xff, 0x41},	/* read 41, write ff 00 */
+	{0x41, 0x40},	/* com16 */
+	{0x56, 0x40},
+	{0x55, 0x8f},
+	{0x10, 0x25},	/* aech - exposure high bits */
+	{0xff, 0x13},	/* read 13, write ff 00 */
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+};
+
+static const u8 bridge_start_ov965x[][2] = {
+	{0xc2, 0x4c},
+	{0xc3, 0xf9},
+	{0x50, 0x00},
+	{0x51, 0xa0},
+	{0x52, 0x78},
+	{0x53, 0x00},
+	{0x54, 0x00},
+	{0x55, 0x00},
+	{0x57, 0x00},
+	{0x5c, 0x00},
+	{0x5a, 0x28},
+	{0x5b, 0x1e},
+	{0x35, 0x00},
+	{0xd9, 0x21},
+	{0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x[][2] = {
+	{0x3b, 0xe4},
+	{0x1e, 0x04},	/* mvfp */
+	{0x13, 0xe0},	/* com8 */
+	{0x00, 0x00},
+	{0x13, 0xe7},	/* com8 - everything (AGC, AWB and AEC) */
+	{0x11, 0x01},	/* clkrc */
+	{0x6b, 0x5a},	/* dblv */
+	{0x6a, 0x02},
+	{0xc5, 0x03},
+	{0xa2, 0x96},
+	{0xa3, 0x7d},
+	{0xff, 0x13},	/* read 13, write ff 00 */
+	{0x13, 0xe7},
+	{0x3a, 0x80},
+	{0xff, 0x42},	/* read 42, write ff 00 */
+	{0x42, 0xc1},
+};
+
+
+static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+	struct usb_device *udev = gspca_dev->dev;
+	int ret;
+
+	PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
+	gspca_dev->usb_buf[0] = val;
+	ret = usb_control_msg(udev,
+			      usb_sndctrlpipe(udev, 0),
+			      0x01,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+	if (ret < 0)
+		PDEBUG(D_ERR, "write failed");
+}
+
+static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+	struct usb_device *udev = gspca_dev->dev;
+	int ret;
+
+	ret = usb_control_msg(udev,
+			      usb_rcvctrlpipe(udev, 0),
+			      0x01,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+	PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
+	if (ret < 0)
+		PDEBUG(D_ERR, "read failed");
+	return gspca_dev->usb_buf[0];
+}
+
+/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
+ * (direction and output)? */
+static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
+{
+	u8 data;
+
+	PDEBUG(D_CONF, "led status: %d", status);
+
+	data = ov534_reg_read(gspca_dev, 0x21);
+	data |= 0x80;
+	ov534_reg_write(gspca_dev, 0x21, data);
+
+	data = ov534_reg_read(gspca_dev, 0x23);
+	if (status)
+		data |= 0x80;
+	else
+		data &= ~0x80;
+
+	ov534_reg_write(gspca_dev, 0x23, data);
+
+	if (!status) {
+		data = ov534_reg_read(gspca_dev, 0x21);
+		data &= ~0x80;
+		ov534_reg_write(gspca_dev, 0x21, data);
+	}
+}
+
+static int sccb_check_status(struct gspca_dev *gspca_dev)
+{
+	u8 data;
+	int i;
+
+	for (i = 0; i < 5; i++) {
+		data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
+
+		switch (data) {
+		case 0x00:
+			return 1;
+		case 0x04:
+			return 0;
+		case 0x03:
+			break;
+		default:
+			PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
+			       data, i + 1);
+		}
+	}
+	return 0;
+}
+
+static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+{
+	PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
+	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
+	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
+
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_reg_write failed");
+}
+
+static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_reg_read failed 1");
+
+	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
+	if (!sccb_check_status(gspca_dev))
+		PDEBUG(D_ERR, "sccb_reg_read failed 2");
+
+	return ov534_reg_read(gspca_dev, OV534_REG_READ);
+}
+
+/* output a bridge sequence (reg - val) */
+static void reg_w_array(struct gspca_dev *gspca_dev,
+			const u8 (*data)[2], int len)
+{
+	while (--len >= 0) {
+		ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+		data++;
+	}
+}
+
+/* output a sensor sequence (reg - val) */
+static void sccb_w_array(struct gspca_dev *gspca_dev,
+			const u8 (*data)[2], int len)
+{
+	while (--len >= 0) {
+		if ((*data)[0] != 0xff) {
+			sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+		} else {
+			sccb_reg_read(gspca_dev, (*data)[1]);
+			sccb_reg_write(gspca_dev, 0xff, 0x00);
+		}
+		data++;
+	}
+}
+
 /* set framerate */
 static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
 {
@@ -346,40 +694,17 @@ static void ov534_set_frame_rate(struct
 	PDEBUG(D_PROBE, "frame_rate: %d", fr);
 }
 
-/* setup method */
-static void ov534_setup(struct gspca_dev *gspca_dev)
-{
-	int i;
-
-	/* Initialize bridge chip */
-	for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
-		ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
-				ov534_reg_initdata[i][1]);
-
-	PDEBUG(D_PROBE, "sensor is ov%02x%02x",
-		sccb_reg_read(gspca_dev, 0x0a),
-		sccb_reg_read(gspca_dev, 0x0b));
-
-	ov534_set_led(gspca_dev, 1);
-
-	/* Initialize sensor */
-	for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
-		sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
-			       ov772x_reg_initdata[i][1]);
-
-	ov534_reg_write(gspca_dev, 0xe0, 0x09);
-	ov534_set_led(gspca_dev, 0);
-}
-
 /* 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;
 
+	sd->sensor = id->driver_info;
+
 	cam = &gspca_dev->cam;
 
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
 
@@ -392,26 +717,102 @@ 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)
 {
-	ov534_setup(gspca_dev);
-	ov534_set_frame_rate(gspca_dev);
+	struct sd *sd = (struct sd *) gspca_dev;
+	u16 sensor_id;
+	static const u8 sensor_addr[2] = {
+		0x42,			/* 0 SENSOR_OV772X */
+		0x60,			/* 1 SENSOR_OV965X */
+	};
+
+	/* reset bridge */
+	ov534_reg_write(gspca_dev, 0xe7, 0x3a);
+	ov534_reg_write(gspca_dev, 0xe0, 0x08);
+	msleep(100);
+
+	/* initialize the sensor address */
+	ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
+				sensor_addr[sd->sensor]);
+
+	/* reset sensor */
+	sccb_reg_write(gspca_dev, 0x12, 0x80);
+	msleep(10);
+
+	/* probe the sensor */
+	sccb_reg_read(gspca_dev, 0x0a);
+	sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
+	sccb_reg_read(gspca_dev, 0x0b);
+	sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
+	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+
+	/* initialize */
+	switch (sd->sensor) {
+	case SENSOR_OV772X:
+		reg_w_array(gspca_dev, bridge_init_ov722x,
+				ARRAY_SIZE(bridge_init_ov722x));
+		ov534_set_led(gspca_dev, 1);
+		sccb_w_array(gspca_dev, sensor_init_ov722x,
+				ARRAY_SIZE(sensor_init_ov722x));
+		ov534_reg_write(gspca_dev, 0xe0, 0x09);
+		ov534_set_led(gspca_dev, 0);
+		ov534_set_frame_rate(gspca_dev);
+		break;
+	default:
+/*	case SENSOR_OV965X: */
+		reg_w_array(gspca_dev, bridge_init_ov965x,
+				ARRAY_SIZE(bridge_init_ov965x));
+		sccb_w_array(gspca_dev, sensor_init_ov965x,
+				ARRAY_SIZE(sensor_init_ov965x));
+		reg_w_array(gspca_dev, bridge_init_ov965x_2,
+				ARRAY_SIZE(bridge_init_ov965x_2));
+		sccb_w_array(gspca_dev, sensor_init_ov965x_2,
+				ARRAY_SIZE(sensor_init_ov965x_2));
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+		ov534_reg_write(gspca_dev, 0xe0, 0x01);
+		ov534_set_led(gspca_dev, 0);
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	}
 
 	return 0;
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
-	/* start streaming data */
-	ov534_set_led(gspca_dev, 1);
-	ov534_reg_write(gspca_dev, 0xe0, 0x00);
+	struct sd *sd = (struct sd *) gspca_dev;
 
+	switch (sd->sensor) {
+	case SENSOR_OV772X:
+		ov534_set_led(gspca_dev, 1);
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+		break;
+	default:
+/*	case SENSOR_OV965X: */
+		reg_w_array(gspca_dev, bridge_start_ov965x,
+				ARRAY_SIZE(bridge_start_ov965x));
+		sccb_w_array(gspca_dev, sensor_start_ov965x,
+				ARRAY_SIZE(sensor_start_ov965x));
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+		ov534_set_led(gspca_dev, 1);
+/*fixme: other sensor start omitted*/
+	}
 	return 0;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	/* stop streaming data */
-	ov534_reg_write(gspca_dev, 0xe0, 0x09);
-	ov534_set_led(gspca_dev, 0);
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	switch (sd->sensor) {
+	case SENSOR_OV772X:
+		ov534_reg_write(gspca_dev, 0xe0, 0x09);
+		ov534_set_led(gspca_dev, 0);
+		break;
+	default:
+/*	case SENSOR_OV965X: */
+		ov534_reg_write(gspca_dev, 0xe0, 0x01);
+		ov534_set_led(gspca_dev, 0);
+		ov534_reg_write(gspca_dev, 0xe0, 0x00);
+		break;
+	}
 }
 
 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -429,75 +830,75 @@ static void sd_pkt_scan(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u32 this_pts;
-	int this_fid;
+	u16 this_fid;
 	int remaining_len = len;
-	__u8 *next_data = data;
 
-scan_next:
-	if (remaining_len <= 0)
-		return;
+	do {
+		len = min(remaining_len, 2040);		/*fixme: was 2048*/
 
-	data = next_data;
-	len = min(remaining_len, 2048);
-	remaining_len -= len;
-	next_data += len;
+		/* Payloads are prefixed with a UVC-style header.  We
+		   consider a frame to start when the FID toggles, or the PTS
+		   changes.  A frame ends when EOF is set, and we've received
+		   the correct number of bytes. */
 
-	/* Payloads are prefixed with a UVC-style header.  We
-	   consider a frame to start when the FID toggles, or the PTS
-	   changes.  A frame ends when EOF is set, and we've received
-	   the correct number of bytes. */
+		/* Verify UVC header.  Header length is always 12 */
+		if (data[0] != 12 || len < 12) {
+			PDEBUG(D_PACK, "bad header");
+			goto discard;
+		}
 
-	/* Verify UVC header.  Header length is always 12 */
-	if (data[0] != 12 || len < 12) {
-		PDEBUG(D_PACK, "bad header");
-		goto discard;
-	}
+		/* Check errors */
+		if (data[1] & UVC_STREAM_ERR) {
+			PDEBUG(D_PACK, "payload error");
+			goto discard;
+		}
 
-	/* Check errors */
-	if (data[1] & UVC_STREAM_ERR) {
-		PDEBUG(D_PACK, "payload error");
-		goto discard;
-	}
+		/* Extract PTS and FID */
+		if (!(data[1] & UVC_STREAM_PTS)) {
+			PDEBUG(D_PACK, "PTS not present");
+			goto discard;
+		}
+		this_pts = (data[5] << 24) | (data[4] << 16)
+						| (data[3] << 8) | data[2];
+		this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
 
-	/* Extract PTS and FID */
-	if (!(data[1] & UVC_STREAM_PTS)) {
-		PDEBUG(D_PACK, "PTS not present");
-		goto discard;
-	}
-	this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
-	this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
+		/* If PTS or FID has changed, start a new frame. */
+		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+					NULL, 0);
+			sd->last_pts = this_pts;
+			sd->last_fid = this_fid;
+		}
 
-	/* If PTS or FID has changed, start a new frame. */
-	if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
-		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
-		sd->last_pts = this_pts;
-		sd->last_fid = this_fid;
-	}
+		/* Add the data from this payload */
+		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+					data + 12, len - 12);
 
-	/* Add the data from this payload */
-	gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-				data + 12, len - 12);
+		/* If this packet is marked as EOF, end the frame */
+		if (data[1] & UVC_STREAM_EOF) {
+			sd->last_pts = 0;
 
-	/* If this packet is marked as EOF, end the frame */
-	if (data[1] & UVC_STREAM_EOF) {
-		sd->last_pts = 0;
+			if (frame->data_end - frame->data !=
+			    gspca_dev->width * gspca_dev->height * 2) {
+				PDEBUG(D_PACK, "short frame");
+				goto discard;
+			}
 
-		if ((frame->data_end - frame->data) !=
-		    (gspca_dev->width * gspca_dev->height * 2)) {
-			PDEBUG(D_PACK, "short frame");
-			goto discard;
+			frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+						NULL, 0);
 		}
 
-		gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
-	}
-
-	/* Done this payload */
-	goto scan_next;
+		/* Done this payload */
+		goto scan_next;
 
 discard:
-	/* Discard data until a new frame starts. */
-	gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
-	goto scan_next;
+		/* Discard data until a new frame starts. */
+		gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+
+scan_next:
+		remaining_len -= len;
+		data += len;
+	} while (remaining_len > 0);
 }
 
 /* get stream parameters (framerate) */
@@ -556,9 +957,8 @@ static const struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x06f8, 0x3002)},	/* Hercules Blog Webcam */
-	{USB_DEVICE(0x06f8, 0x3003)},	/* Hercules Dualpix HD Weblog */
-	{USB_DEVICE(0x1415, 0x2000)},	/* Sony HD Eye for PS3 (SLEH 00201) */
+	{USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
+	{USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
 	{}
 };
 
@@ -585,8 +985,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/pac207.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/pac207.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/pac207.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/pac207.c	2009-06-09 23:05:27.000000000 -0400
@@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *g
 		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x05;
 	cam->cam_mode = sif_mode;
 	cam->nmodes = ARRAY_SIZE(sif_mode);
 	sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
@@ -536,6 +535,7 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x093a, 0x2470)},
 	{USB_DEVICE(0x093a, 0x2471)},
 	{USB_DEVICE(0x093a, 0x2472)},
+	{USB_DEVICE(0x093a, 0x2474)},
 	{USB_DEVICE(0x093a, 0x2476)},
 	{USB_DEVICE(0x145f, 0x013a)},
 	{USB_DEVICE(0x2001, 0xf115)},
@@ -565,8 +565,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/pac7311.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/pac7311.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/pac7311.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/pac7311.c	2009-06-09 23:05:27.000000000 -0400
@@ -498,7 +498,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x05;
 
 	sd->sensor = id->driver_info;
 	if (sd->sensor == SENSOR_PAC7302) {
@@ -1097,8 +1096,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sonixb.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sonixb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sonixb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sonixb.c	2009-06-09 23:05:27.000000000 -0400
@@ -870,7 +870,6 @@ static int sd_config(struct gspca_dev *g
 	gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	if (!(sensor_data[sd->sensor].flags & F_SIF)) {
 		cam->cam_mode = vga_mode;
 		cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1272,8 +1271,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sonixj.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sonixj.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sonixj.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sonixj.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,36 +35,47 @@ struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
 	atomic_t avg_lum;
-	unsigned int exposure;
+	u32 exposure;
 
-	__u16 brightness;
-	__u8 contrast;
-	__u8 colors;
-	__u8 autogain;
-	__u8 blue;
-	__u8 red;
-	__u8 vflip;			/* ov7630 only */
-	__u8 infrared;			/* mi0360 only */
+	u16 brightness;
+	u8 contrast;
+	u8 colors;
+	u8 autogain;
+	u8 blue;
+	u8 red;
+	u8 gamma;
+	u8 vflip;			/* ov7630/ov7648 only */
+	u8 infrared;			/* mt9v111 only */
+	u8 quality;			/* image quality */
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
+	u8 jpegqual;			/* webcam quality */
 
-	__s8 ag_cnt;
+	u8 reg18;
+
+	s8 ag_cnt;
 #define AG_CNT_START 13
 
-	__u8 qindex;
-	__u8 bridge;
+	u8 bridge;
 #define BRIDGE_SN9C102P 0
 #define BRIDGE_SN9C105 1
 #define BRIDGE_SN9C110 2
 #define BRIDGE_SN9C120 3
 #define BRIDGE_SN9C325 4
-	__u8 sensor;			/* Type of image sensor chip */
+	u8 sensor;			/* Type of image sensor chip */
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
 #define SENSOR_MO4000 2
-#define SENSOR_OM6802 3
-#define SENSOR_OV7630 4
-#define SENSOR_OV7648 5
-#define SENSOR_OV7660 6
-	__u8 i2c_base;
+#define SENSOR_MT9V111 3
+#define SENSOR_OM6802 4
+#define SENSOR_OV7630 5
+#define SENSOR_OV7648 6
+#define SENSOR_OV7660 7
+#define SENSOR_SP80708 8
+	u8 i2c_base;
+
+	u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -78,6 +89,8 @@ static int sd_setblue_balance(struct gsp
 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(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_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -158,6 +171,20 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setred_balance,
 	    .get = sd_getred_balance,
 	},
+	{
+	    {
+		.id      = V4L2_CID_GAMMA,
+		.type    = V4L2_CTRL_TYPE_INTEGER,
+		.name    = "Gamma",
+		.minimum = 0,
+		.maximum = 40,
+		.step    = 1,
+#define GAMMA_DEF 20
+		.default_value = GAMMA_DEF,
+	    },
+	    .set = sd_setgamma,
+	    .get = sd_getgamma,
+	},
 #define AUTOGAIN_IDX 5
 	{
 	    {
@@ -173,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
 	},
-/* ov7630 only */
+/* ov7630/ov7648 only */
 #define VFLIP_IDX 6
 	{
 	    {
@@ -183,13 +210,13 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 1,
 		.step    = 1,
-#define VFLIP_DEF 1
+#define VFLIP_DEF 0			/* vflip def = 1 for ov7630 */
 		.default_value = VFLIP_DEF,
 	    },
 	    .set = sd_setvflip,
 	    .get = sd_getvflip,
 	},
-/* mi0360 only */
+/* mt9v111 only */
 #define INFRARED_IDX 7
 	{
 	    {
@@ -211,18 +238,22 @@ static struct ctrl sd_ctrls[] = {
 static __u32 ctrl_dis[] = {
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_HV7131R 0 */
-	(1 << VFLIP_IDX),
+	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_MI0360 1 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
 						/* SENSOR_MO4000 2 */
+	(1 << VFLIP_IDX),
+						/* SENSOR_MT9V111 3 */
 	(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
-						/* SENSOR_OM6802 3 */
+						/* SENSOR_OM6802 4 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
-						/* SENSOR_OV7630 4 */
+						/* SENSOR_OV7630 5 */
+	(1 << INFRARED_IDX),
+						/* SENSOR_OV7648 6 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
-						/* SENSOR_OV7648 5 */
+						/* SENSOR_OV7660 7 */
 	(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
-						/* SENSOR_OV7660 6 */
+						/* SENSOR_SP80708 8 */
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -243,196 +274,228 @@ static const struct v4l2_pix_format vga_
 		.priv = 0},
 };
 
-/*Data from sn9c102p+hv71331r */
-static const __u8 sn_hv7131[] = {
+/*Data from sn9c102p+hv7131r */
+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,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x03,	0x28,	0x1e,	0x41,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x0a,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00
+/*	reg18	reg19	reg1a	reg1b */
+	0x0a,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_mi0360[] = {
+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,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x61,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x06,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00
+/*	reg18	reg19	reg1a	reg1b */
+	0x06,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_mo4000[] = {
+static const u8 sn_mo4000[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
-	0x12,	0x23,	0x60,	0x00,	0x1a,	0x00,	0x20,	0x18,
+	0x00,	0x23,	0x60,	0x00,	0x1a,	0x00,	0x20,	0x18,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
 	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	 0x00,	0x0b,	0x0f,	0x14,	0x28,	0x1e,	0x40,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x08,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00
+/*	reg18	reg19	reg1a	reg1b */
+	0x08,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_om6802[] = {
+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,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x00,	0x02,	0x1c,	0x28,	0x1e,	0x40,
+/*	reg18	reg19	reg1a	reg1b */
+	0x06,	0x00,	0x00,	0x00
+};
+
+static const u8 sn_om6802[0x1c] = {
 /*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
 	0x00,	0x23,	0x72,	0x00,	0x1a,	0x34,	0x27,	0x20,
 /*	reg8	reg9	rega	regb	regc	regd	rege	regf */
 	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x51,	0x01,	0x00,	0x28,	0x1e,	0x40,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x05,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
-	0x08,	0x22,	0x44,	0x63,	0x7d,	0x92,	0xa3,	0xaf,
-	0xbc,	0xc4,	0xcd,	0xd5,	0xdc,	0xe1,	0xe8,	0xef,
-	0xf7
+/*	reg18	reg19	reg1a	reg1b */
+	0x05,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_ov7630[] = {
+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,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x0b,	0x00,	0x00,	0x00,	0x00,	0x00
+/*	reg18	reg19	reg1a	reg1b */
+	0x0b,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_ov7648[] = {
+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,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x00,	0x01,	0x00,	0x28,	0x1e,	0x00,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x0b,	0x00,	0x00,	0x00,	0x00,	0x00
+/*	reg18	reg19	reg1a	reg1b */
+	0x0b,	0x00,	0x00,	0x00
 };
 
-static const __u8 sn_ov7660[]	= {
+static const u8 sn_ov7660[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,	0x21,	0x07,	0x00,	0x00,	0x00,	0x00,	0x10,
 /*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
 	0x03,	0x00,	0x01,	0x01,	0x08,	0x28,	0x1e,	0x20,
-/*	reg18	reg19	reg1a	reg1b	reg1c	reg1d	reg1e	reg1f */
-	0x07,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	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,
+/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
+	0x03,	0x00,	0x00,	0x03,	0x04,	0x28,	0x1e,	0x00,
+/*	reg18	reg19	reg1a	reg1b */
+	0x07,	0x00,	0x00,	0x00
 };
 
 /* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const __u8 *sn_tb[] = {
+static const u8 *sn_tb[] = {
 	sn_hv7131,
 	sn_mi0360,
 	sn_mo4000,
+	sn_mt9v111,
 	sn_om6802,
 	sn_ov7630,
 	sn_ov7648,
-	sn_ov7660
+	sn_ov7660,
+	sn_sp80708
 };
 
-static const __u8 gamma_def[] = {
+/* default gamma table */
+static const u8 gamma_def[17] = {
 	0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
 	0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
 };
+/* gamma for sensors HV7131R and MT9V111 */
+static const u8 gamma_spec_1[17] = {
+	0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
+	0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
+};
+/* gamma for sensor SP80708 */
+static const u8 gamma_spec_2[17] = {
+	0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
+	0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
+};
 
 /* color matrix and offsets */
-static const __u8 reg84[] = {
+static const u8 reg84[] = {
 	0x14, 0x00, 0x27, 0x00, 0x07, 0x00,	/* YR YG YB gains */
 	0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,	/* UR UG UB */
 	0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,	/* VR VG VB */
 	0x00, 0x00, 0x00			/* YUV offsets */
 };
-static const __u8 hv7131r_sensor_init[][8] = {
-	{0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
-	{0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
-	{0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
-	{0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
-	{0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+static const u8 hv7131r_sensor_init[][8] = {
+	{0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
+	{0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
+/*	{0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+	{0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
+/*	{0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
 
-	{0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
-	{0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
-	{0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
-	{0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
-	{0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
-	{0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
-	{0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
-	{0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
+	{0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+	{0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
+	{0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
+	{0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+	{0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
 
-	{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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+	{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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
 
-	{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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{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, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
 	{}
 };
-static const __u8 mi0360_sensor_init[][8] = {
-	{0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
-	{0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
-	{0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
-	{0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
-	{0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
-	{0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
-	{0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
-	{0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
-	{0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
-	{0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+static const u8 mi0360_sensor_init[][8] = {
+	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+	{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+	{0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+	{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+	{0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
+	{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+	{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+	{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+	{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+	{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
 
-	{0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
-	{0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
-	{0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
+	{0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+	{0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
+	{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
 
-	{0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
-	{0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
-	{0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+	{0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+	{0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
+	{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
 
-	{0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
-	{0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
-/*	{0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/*	{0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
-	{0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
-	{0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+	{0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
+	{0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
+/*	{0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/*	{0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+	{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
 	{}
 };
-static const __u8 mo4000_sensor_init[][8] = {
+static const u8 mo4000_sensor_init[][8] = {
 	{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -455,7 +518,49 @@ static const __u8 mo4000_sensor_init[][8
 	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
 	{}
 };
-static __u8 om6802_sensor_init[][8] = {
+static const u8 mt9v111_sensor_init[][8] = {
+	{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
+	/* delay 20 ms */
+	{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 */
+	{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
+	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
+	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
+	{0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
+	{0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
+	{0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
+	{0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
+	{0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
+	{0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
+	{0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
+	{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},
+	/*******/
+	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
+	{0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
+	{0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
+	/*******/
+	{0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
+	{0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
+	{0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
+	{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
+	{}
+};
+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},
@@ -489,7 +594,7 @@ static __u8 om6802_sensor_init[][8] = {
 /*	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
 	{}
 };
-static const __u8 ov7630_sensor_init[][8] = {
+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 */
@@ -543,7 +648,7 @@ static const __u8 ov7630_sensor_init[][8
 	{}
 };
 
-static const __u8 ov7648_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 */
 	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -572,7 +677,8 @@ static const __u8 ov7648_sensor_init[][8
 	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
 /*...*/
 /*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
+/*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
+							 * set by setvflip */
 	{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
 /*	{0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
@@ -589,7 +695,7 @@ static const __u8 ov7648_sensor_init[][8
 	{}
 };
 
-static const __u8 ov7660_sensor_init[][8] = {
+static const u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
 /*		(delay 20ms) */
 	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
@@ -678,28 +784,92 @@ static const __u8 ov7660_sensor_init[][8
 	{}
 };
 
-static const __u8 qtable4[] = {
-	0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
-	0x06, 0x08, 0x0A, 0x11,
-	0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
-	0x19, 0x19, 0x17, 0x15,
-	0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
-	0x21, 0x2E, 0x21, 0x23,
-	0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
-	0x25, 0x29, 0x2C, 0x29,
-	0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
-	0x17, 0x1B, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
-	0x29, 0x29, 0x29, 0x29
+static const u8 sp80708_sensor_init[][8] = {
+	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
+	/********/
+	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+	{0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
+	{}
 };
 
 /* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
-		  __u16 value, int len)
+		  u16 value, int len)
 {
 #ifdef GSPCA_DEBUG
 	if (len > USB_BUF_SZ) {
@@ -718,10 +888,10 @@ static void reg_r(struct gspca_dev *gspc
 }
 
 static void reg_w1(struct gspca_dev *gspca_dev,
-		   __u16 value,
-		   __u8 data)
+		   u16 value,
+		   u8 data)
 {
-	PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+	PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
 	gspca_dev->usb_buf[0] = data;
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -733,11 +903,11 @@ static void reg_w1(struct gspca_dev *gsp
 			500);
 }
 static void reg_w(struct gspca_dev *gspca_dev,
-			  __u16 value,
-			  const __u8 *buffer,
+			  u16 value,
+			  const u8 *buffer,
 			  int len)
 {
-	PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+	PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
 		value, buffer[0], buffer[1]);
 #ifdef GSPCA_DEBUG
 	if (len > USB_BUF_SZ) {
@@ -756,7 +926,7 @@ static void reg_w(struct gspca_dev *gspc
 }
 
 /* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
+static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -781,7 +951,7 @@ static void i2c_w1(struct gspca_dev *gsp
 
 /* I2C write 8 bytes */
 static void i2c_w8(struct gspca_dev *gspca_dev,
-		   const __u8 *buffer)
+		   const u8 *buffer)
 {
 	memcpy(gspca_dev->usb_buf, buffer, 8);
 	usb_control_msg(gspca_dev->dev,
@@ -795,10 +965,10 @@ static void i2c_w8(struct gspca_dev *gsp
 }
 
 /* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 mode[8];
+	u8 mode[8];
 
 	mode[0] = 0x81 | 0x10;
 	mode[1] = sd->i2c_base;
@@ -817,7 +987,7 @@ static void i2c_r5(struct gspca_dev *gsp
 	reg_r(gspca_dev, 0x0a, 5);
 }
 
-static int probesensor(struct gspca_dev *gspca_dev)
+static int hv7131r_probe(struct gspca_dev *gspca_dev)
 {
 	i2c_w1(gspca_dev, 0x02, 0);			/* sensor wakeup */
 	msleep(10);
@@ -839,16 +1009,66 @@ static int probesensor(struct gspca_dev
 	return -ENODEV;
 }
 
+static void mi0360_probe(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, j;
+	u16 val = 0;
+	static const u8 probe_tb[][4][8] = {
+	    {					/* mi0360 */
+		{0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+		{0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+		{0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+		{0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
+	    },
+	    {					/* mt9v111 */
+		{0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
+		{0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
+		{0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+		{}
+	    },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
+		reg_w1(gspca_dev, 0x17, 0x62);
+		reg_w1(gspca_dev, 0x01, 0x08);
+		for (j = 0; j < 3; j++)
+			i2c_w8(gspca_dev, probe_tb[i][j]);
+		msleep(2);
+		reg_r(gspca_dev, 0x0a, 5);
+		val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
+		if (probe_tb[i][3][0] != 0)
+			i2c_w8(gspca_dev, probe_tb[i][3]);
+		reg_w1(gspca_dev, 0x01, 0x29);
+		reg_w1(gspca_dev, 0x17, 0x42);
+		if (val != 0xffff)
+			break;
+	}
+	switch (val) {
+	case 0x823a:
+		PDEBUG(D_PROBE, "Sensor mt9v111");
+		sd->sensor = SENSOR_MT9V111;
+		sd->i2c_base = 0x5c;
+		break;
+	case 0x8243:
+		PDEBUG(D_PROBE, "Sensor mi0360");
+		break;
+	default:
+		PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+		break;
+	}
+}
+
 static int configure_gpio(struct gspca_dev *gspca_dev,
-			  const __u8 *sn9c1xx)
+			  const u8 *sn9c1xx)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	const __u8 *reg9a;
-	static const __u8 reg9a_def[] =
+	const u8 *reg9a;
+	static const u8 reg9a_def[] =
 		{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
-	static const __u8 reg9a_sn9c325[] =
+	static const u8 reg9a_sn9c325[] =
 		{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
-	static const __u8 regd4[] = {0x60, 0x00, 0x00};
+	static const u8 regd4[] = {0x60, 0x00, 0x00};
 
 	reg_w1(gspca_dev, 0xf1, 0x00);
 	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -872,6 +1092,12 @@ static int configure_gpio(struct gspca_d
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
 	switch (sd->sensor) {
+	case SENSOR_MT9V111:
+		reg_w1(gspca_dev, 0x01, 0x61);
+		reg_w1(gspca_dev, 0x17, 0x61);
+		reg_w1(gspca_dev, 0x01, 0x60);
+		reg_w1(gspca_dev, 0x01, 0x40);
+		break;
 	case SENSOR_OM6802:
 		reg_w1(gspca_dev, 0x02, 0x71);
 		reg_w1(gspca_dev, 0x01, 0x42);
@@ -900,12 +1126,20 @@ static int configure_gpio(struct gspca_d
 			break;
 		}
 		/* fall thru */
+	case SENSOR_SP80708:
+		reg_w1(gspca_dev, 0x01, 0x63);
+		reg_w1(gspca_dev, 0x17, 0x20);
+		reg_w1(gspca_dev, 0x01, 0x62);
+		reg_w1(gspca_dev, 0x01, 0x42);
+		mdelay(100);
+		reg_w1(gspca_dev, 0x02, 0x62);
+		break;
 	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 (probesensor(gspca_dev) < 0)
+			if (hv7131r_probe(gspca_dev) < 0)
 				return -ENODEV;
 		}
 		break;
@@ -916,7 +1150,7 @@ static int configure_gpio(struct gspca_d
 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
 {
 	int i = 0;
-	static const __u8 SetSensorClk[] =	/* 0x08 Mclk */
+	static const u8 SetSensorClk[] =	/* 0x08 Mclk */
 		{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
 
 	while (hv7131r_sensor_init[i][0]) {
@@ -946,6 +1180,19 @@ static void mo4000_InitSensor(struct gsp
 	}
 }
 
+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;
@@ -1010,6 +1257,19 @@ static void ov7660_InitSensor(struct gsp
 	}
 }
 
+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 */
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
@@ -1018,7 +1278,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
 
@@ -1026,16 +1285,21 @@ static int sd_config(struct gspca_dev *g
 	sd->sensor = id->driver_info >> 8;
 	sd->i2c_base = id->driver_info;
 
-	sd->qindex = 4;			/* set the quantization table */
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
 	sd->blue = BLUE_BALANCE_DEF;
 	sd->red = RED_BALANCE_DEF;
+	sd->gamma = GAMMA_DEF;
 	sd->autogain = AUTOGAIN_DEF;
 	sd->ag_cnt = -1;
-	sd->vflip = VFLIP_DEF;
+	if (sd->sensor != SENSOR_OV7630)
+		sd->vflip = 0;
+	else
+		sd->vflip = 1;
 	sd->infrared = INFRARED_DEF;
+	sd->quality = QUALITY_DEF;
+	sd->jpegqual = 80;
 
 	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
 	return 0;
@@ -1045,8 +1309,8 @@ static int sd_config(struct gspca_dev *g
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 regGpio[] = { 0x29, 0x74 };
-	__u8 regF1;
+	u8 regGpio[] = { 0x29, 0x74 };
+	u8 regF1;
 
 	/* setup a selector by bridge */
 	reg_w1(gspca_dev, 0xf1, 0x01);
@@ -1064,11 +1328,15 @@ static int sd_init(struct gspca_dev *gsp
 	case BRIDGE_SN9C105:
 		if (regF1 != 0x11)
 			return -ENODEV;
+		if (sd->sensor == SENSOR_MI0360)
+			mi0360_probe(gspca_dev);
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
 	case BRIDGE_SN9C120:
 		if (regF1 != 0x12)
 			return -ENODEV;
+		if (sd->sensor == SENSOR_MI0360)
+			mi0360_probe(gspca_dev);
 		regGpio[1] = 0x70;
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
@@ -1086,20 +1354,14 @@ static int sd_init(struct gspca_dev *gsp
 	return 0;
 }
 
-static unsigned int setexposure(struct gspca_dev *gspca_dev,
-				unsigned int expo)
+static u32 setexposure(struct gspca_dev *gspca_dev,
+			u32 expo)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	static const __u8 doit[] =		/* update sensor */
-		{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
-	static const __u8 sensorgo[] =		/* sensor on */
-		{ 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
-	static const __u8 gainMo[] =
-		{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
 
 	switch (sd->sensor) {
 	case SENSOR_HV7131R: {
-		__u8 Expodoit[] =
+		u8 Expodoit[] =
 			{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
 
 		Expodoit[3] = expo >> 16;
@@ -1109,8 +1371,12 @@ static unsigned int setexposure(struct g
 		break;
 	    }
 	case SENSOR_MI0360: {
-		__u8 expoMi[] =	 /* exposure 0x0635 -> 4 fp/s 0x10 */
+		u8 expoMi[] =		/* exposure 0x0635 -> 4 fp/s 0x10 */
 			{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+		static const u8 doit[] =		/* update sensor */
+			{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+		static const u8 sensorgo[] =		/* sensor on */
+			{ 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
 
 		if (expo > 0x0635)
 			expo = 0x0635;
@@ -1124,10 +1390,12 @@ static unsigned int setexposure(struct g
 		break;
 	    }
 	case SENSOR_MO4000: {
-		__u8 expoMof[] =
+		u8 expoMof[] =
 			{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
-		__u8 expoMo10[] =
+		u8 expoMo10[] =
 			{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+		static const u8 gainMo[] =
+			{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
 
 		if (expo > 0x1fff)
 			expo = 0x1fff;
@@ -1139,14 +1407,27 @@ static unsigned int setexposure(struct g
 				| ((expo & 0x0003) << 4);
 		i2c_w8(gspca_dev, expoMo10);
 		i2c_w8(gspca_dev, gainMo);
-		PDEBUG(D_CONF, "set exposure %d",
+		PDEBUG(D_FRAM, "set exposure %d",
 			((expoMo10[3] & 0x07) << 10)
 			| (expoMof[3] << 2)
 			| ((expoMo10[3] & 0x30) >> 4));
 		break;
 	    }
+	case SENSOR_MT9V111: {
+		u8 expo_c1[] =
+			{ 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+		if (expo > 0x0280)
+			expo = 0x0280;
+		else if (expo < 0x0040)
+			expo = 0x0040;
+		expo_c1[3] = expo >> 8;
+		expo_c1[4] = expo;
+		i2c_w8(gspca_dev, expo_c1);
+		break;
+	    }
 	case SENSOR_OM6802: {
-		__u8 gainOm[] =
+		u8 gainOm[] =
 			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
 
 		if (expo > 0x03ff)
@@ -1156,7 +1437,7 @@ static unsigned int setexposure(struct g
 		gainOm[3] = expo >> 2;
 		i2c_w8(gspca_dev, gainOm);
 		reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
-		PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+		PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
 		break;
 	    }
 	}
@@ -1167,7 +1448,7 @@ static void setbrightness(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned int expo;
-	__u8 k2;
+	u8 k2;
 
 	k2 = ((int) sd->brightness - 0x8000) >> 10;
 	switch (sd->sensor) {
@@ -1184,6 +1465,10 @@ static void setbrightness(struct gspca_d
 		expo = sd->brightness >> 4;
 		sd->exposure = setexposure(gspca_dev, expo);
 		break;
+	case SENSOR_MT9V111:
+		expo = sd->brightness >> 8;
+		sd->exposure = setexposure(gspca_dev, expo);
+		break;
 	case SENSOR_OM6802:
 		expo = sd->brightness >> 6;
 		sd->exposure = setexposure(gspca_dev, expo);
@@ -1191,14 +1476,15 @@ static void setbrightness(struct gspca_d
 		break;
 	}
 
-	reg_w1(gspca_dev, 0x96, k2);		/* color matrix Y offset */
+	if (sd->sensor != SENSOR_MT9V111)
+		reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 k2;
-	__u8 contrast[6];
+	u8 k2;
+	u8 contrast[6];
 
 	k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;	/* 10..40 */
 	contrast[0] = (k2 + 1) / 2;		/* red */
@@ -1214,8 +1500,8 @@ static void setcolors(struct gspca_dev *
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, v;
-	__u8 reg8a[12];			/* U & V gains */
-	static __s16 uv[6] = {		/* same as reg84 in signed decimal */
+	u8 reg8a[12];			/* U & V gains */
+	static s16 uv[6] = {		/* same as reg84 in signed decimal */
 		-24, -38, 64,		/* UR UG UB */
 		 62, -51, -9		/* VR VG VB */
 	};
@@ -1236,22 +1522,75 @@ static void setredblue(struct gspca_dev
 	reg_w1(gspca_dev, 0x06, sd->blue);
 }
 
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i;
+	u8 gamma[17];
+	const u8 *gamma_base;
+	static const u8 delta[17] = {
+		0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
+		0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
+	};
+
+	switch (sd->sensor) {
+	case SENSOR_HV7131R:
+	case SENSOR_MT9V111:
+		gamma_base = gamma_spec_1;
+		break;
+	case SENSOR_SP80708:
+		gamma_base = gamma_spec_2;
+		break;
+	default:
+		gamma_base = gamma_def;
+		break;
+	}
+
+	for (i = 0; i < sizeof gamma; i++)
+		gamma[i] = gamma_base[i]
+			+ delta[i] * (sd->gamma - GAMMA_DEF) / 32;
+	reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
+}
+
 static void setautogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
 		return;
+	switch (sd->sensor) {
+	case SENSOR_OV7630:
+	case SENSOR_OV7648: {
+		u8 comb;
+
+		if (sd->sensor == SENSOR_OV7630)
+			comb = 0xc0;
+		else
+			comb = 0xa0;
+		if (sd->autogain)
+			comb |= 0x02;
+		i2c_w1(&sd->gspca_dev, 0x13, comb);
+		return;
+	    }
+	}
 	if (sd->autogain)
 		sd->ag_cnt = AG_CNT_START;
 	else
 		sd->ag_cnt = -1;
 }
 
+/* ov7630/ov7648 only */
 static void setvflip(struct sd *sd)
 {
-	i2c_w1(&sd->gspca_dev, 0x75,			/* COMN */
-		sd->vflip ? 0x82 : 0x02);
+	u8 comn;
+
+	if (sd->sensor == SENSOR_OV7630)
+		comn = 0x02;
+	else
+		comn = 0x06;
+	if (sd->vflip)
+		comn |= 0x80;
+	i2c_w1(&sd->gspca_dev, 0x75, comn);
 }
 
 static void setinfrared(struct sd *sd)
@@ -1262,20 +1601,63 @@ static void setinfrared(struct sd *sd)
 		sd->infrared ? 0x66 : 0x64);
 }
 
+static void setjpegqual(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int i, sc;
+
+	if (sd->jpegqual < 50)
+		sc = 5000 / sd->jpegqual;
+	else
+		sc = 200 - sd->jpegqual * 2;
+#if USB_BUF_SZ < 64
+#error "No room enough in usb_buf for quantization table"
+#endif
+	for (i = 0; i < 64; i++)
+		gspca_dev->usb_buf[i] =
+			(jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			0x0100, 0,
+			gspca_dev->usb_buf, 64,
+			500);
+	for (i = 0; i < 64; i++)
+		gspca_dev->usb_buf[i] =
+			(jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0x08,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			0x0140, 0,
+			gspca_dev->usb_buf, 64,
+			500);
+
+	sd->reg18 ^= 0x40;
+	reg_w1(gspca_dev, 0x18, sd->reg18);
+}
+
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	__u8 reg1, reg17, reg18;
-	const __u8 *sn9c1xx;
+	u8 reg1, reg17;
+	const u8 *sn9c1xx;
 	int mode;
-	static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
-	static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
-	static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */
-	static const __u8 CE_ov76xx[] =
+	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+	static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */
+	static const u8 CE_ov76xx[] =
 				{ 0x32, 0xdd, 0x32, 0xdd };
 
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x21);		/* JPEG 422 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	sn9c1xx = sn_tb[(int) sd->sensor];
 	configure_gpio(gspca_dev, sn9c1xx);
 
@@ -1292,6 +1674,9 @@ static int sd_start(struct gspca_dev *gs
 	reg_w1(gspca_dev, 0xc9, 0x3c);
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
 	switch (sd->sensor) {
+	case SENSOR_MT9V111:
+		reg17 = 0xe0;
+		break;
 	case SENSOR_OV7630:
 		reg17 = 0xe2;
 		break;
@@ -1315,14 +1700,24 @@ static int sd_start(struct gspca_dev *gs
 	reg_w1(gspca_dev, 0x07, sn9c1xx[7]);	/* green */
 	reg_w1(gspca_dev, 0x06, sn9c1xx[6]);	/* blue */
 	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
-	reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+
+	setgamma(gspca_dev);
+
 	for (i = 0; i < 8; i++)
 		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
 	switch (sd->sensor) {
+	case SENSOR_MT9V111:
+		reg_w1(gspca_dev, 0x9a, 0x07);
+		reg_w1(gspca_dev, 0x99, 0x59);
+		break;
 	case SENSOR_OV7648:
 		reg_w1(gspca_dev, 0x9a, 0x0a);
 		reg_w1(gspca_dev, 0x99, 0x60);
 		break;
+	case SENSOR_SP80708:
+		reg_w1(gspca_dev, 0x9a, 0x05);
+		reg_w1(gspca_dev, 0x99, 0x59);
+		break;
 	case SENSOR_OV7660:
 		if (sd->bridge == BRIDGE_SN9C120) {
 			reg_w1(gspca_dev, 0x9a, 0x05);
@@ -1358,6 +1753,15 @@ static int sd_start(struct gspca_dev *gs
 /*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
 		}
 		break;
+	case SENSOR_MT9V111:
+		mt9v111_InitSensor(gspca_dev);
+		if (mode) {
+			reg1 = 0x04;	/* 320 clk 48Mhz */
+		} else {
+/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
+			reg17 = 0xc2;
+		}
+		break;
 	case SENSOR_OM6802:
 		om6802_InitSensor(gspca_dev);
 		reg17 = 0x64;		/* 640 MCKSIZE */
@@ -1373,8 +1777,7 @@ static int sd_start(struct gspca_dev *gs
 		reg17 = 0x21;
 /*		reg1 = 0x42;		 * 42 - 46? */
 		break;
-	default:
-/*	case SENSOR_OV7660: */
+	case SENSOR_OV7660:
 		ov7660_InitSensor(gspca_dev);
 		if (sd->bridge == BRIDGE_SN9C120) {
 			if (mode) {		/* 320x240 - 160x120 */
@@ -1387,6 +1790,16 @@ static int sd_start(struct gspca_dev *gs
 					 * inverse power down */
 		}
 		break;
+	default:
+/*	case SENSOR_SP80708: */
+		sp80708_InitSensor(gspca_dev);
+		if (mode) {
+/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
+		} else {
+			reg1 = 0x46;	 /* 640 clk 48Mz */
+			reg17 = 0xa2;
+		}
+		break;
 	}
 	reg_w(gspca_dev, 0xc0, C0, 6);
 	reg_w(gspca_dev, 0xca, CA, 4);
@@ -1403,20 +1816,13 @@ static int sd_start(struct gspca_dev *gs
 	}
 
 	/* here change size mode 0 -> VGA; 1 -> CIF */
-	reg18 = sn9c1xx[0x18] | (mode << 4);
-	reg_w1(gspca_dev, 0x18, reg18 | 0x40);
-
-	reg_w(gspca_dev, 0x100, qtable4, 0x40);
-	reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
-
-	reg_w1(gspca_dev, 0x18, reg18);
+	sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
+	reg_w1(gspca_dev, 0x18, sd->reg18);
+	setjpegqual(gspca_dev);
 
 	reg_w1(gspca_dev, 0x17, reg17);
 	reg_w1(gspca_dev, 0x01, reg1);
 	switch (sd->sensor) {
-	case SENSOR_MI0360:
-		setinfrared(sd);
-		break;
 	case SENSOR_OV7630:
 		setvflip(sd);
 		break;
@@ -1430,14 +1836,14 @@ static int sd_start(struct gspca_dev *gs
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	static const __u8 stophv7131[] =
+	static const u8 stophv7131[] =
 		{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
-	static const __u8 stopmi0360[] =
+	static const u8 stopmi0360[] =
 		{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
-	static const __u8 stopov7648[] =
+	static const u8 stopov7648[] =
 		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
-	__u8 data;
-	const __u8 *sn9c1xx;
+	u8 data;
+	const u8 *sn9c1xx;
 
 	data = 0x0b;
 	switch (sd->sensor) {
@@ -1452,6 +1858,7 @@ static void sd_stopN(struct gspca_dev *g
 	case SENSOR_OV7648:
 		i2c_w8(gspca_dev, stopov7648);
 		/* fall thru */
+	case SENSOR_MT9V111:
 	case SENSOR_OV7630:
 		data = 0x29;
 		break;
@@ -1468,13 +1875,20 @@ static void sd_stopN(struct gspca_dev *g
 	reg_w1(gspca_dev, 0xf1, 0x00);
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	kfree(sd->jpeg_hdr);
+}
+
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int delta;
 	int expotimes;
-	__u8 luma_mean = 130;
-	__u8 luma_delta = 20;
+	u8 luma_mean = 130;
+	u8 luma_delta = 20;
 
 	/* Thanks S., without your advice, autobright should not work :) */
 	if (sd->ag_cnt < 0)
@@ -1499,6 +1913,7 @@ static void do_autogain(struct gspca_dev
 		default:
 /*		case SENSOR_MO4000: */
 /*		case SENSOR_MI0360: */
+/*		case SENSOR_MT9V111: */
 /*		case SENSOR_OM6802: */
 			expotimes = sd->exposure;
 			expotimes += (luma_mean - delta) >> 6;
@@ -1516,7 +1931,7 @@ static void do_autogain(struct gspca_dev
 /* 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;
@@ -1550,7 +1965,8 @@ static void sd_pkt_scan(struct gspca_dev
 	if (gspca_dev->last_packet_type == LAST_PACKET) {
 
 		/* put the JPEG 422 header */
-		jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
@@ -1645,6 +2061,24 @@ static int sd_getred_balance(struct gspc
 	return 0;
 }
 
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gamma = val;
+	if (gspca_dev->streaming)
+		setgamma(gspca_dev);
+	return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gamma;
+	return 0;
+}
+
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1699,6 +2133,34 @@ static int sd_getinfrared(struct gspca_d
 	return 0;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -1708,8 +2170,11 @@ static const struct sd_desc sd_desc = {
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.dq_callback = do_autogain,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -1724,9 +2189,7 @@ static const __devinitdata struct usb_de
 #endif
 	{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
 	{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-#endif
 	{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
 	{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
 	{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
@@ -1764,10 +2227,10 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+#endif
 	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
 /*	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
-#endif
-	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
+	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -1794,8 +2257,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	info("registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca500.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca500.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca500.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca500.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,8 +38,11 @@ struct sd {
 	unsigned char brightness;
 	unsigned char contrast;
 	unsigned char colors;
+	u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
 
-	char qindex;
 	char subtype;
 #define AgfaCl20 0
 #define AiptekPocketDV 1
@@ -56,6 +59,8 @@ struct sd {
 #define Optimedia 12
 #define PalmPixDC85 13
 #define ToptroIndus 14
+
+	u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -629,7 +634,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	sd->subtype = id->driver_info;
 	if (sd->subtype != LogitechClickSmart310) {
 		cam->cam_mode = vga_mode;
@@ -638,10 +642,10 @@ static int sd_config(struct gspca_dev *g
 		cam->cam_mode = sif_mode;
 		cam->nmodes = ARRAY_SIZE(sif_mode);
 	}
-	sd->qindex = 5;
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
+	sd->quality = QUALITY_DEF;
 	return 0;
 }
 
@@ -667,6 +671,12 @@ static int sd_start(struct gspca_dev *gs
 	__u8 Data;
 	__u8 xmult, ymult;
 
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x22);		/* JPEG 411 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	if (sd->subtype == LogitechClickSmart310) {
 		xmult = 0x16;
 		ymult = 0x12;
@@ -713,7 +723,8 @@ static int sd_start(struct gspca_dev *gs
 		write_vector(gspca_dev, spca500_visual_defaults);
 		spca500_setmode(gspca_dev, xmult, ymult);
 		/* enable drop packet */
-		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+		if (err < 0)
 			PDEBUG(D_ERR, "failed to enable drop packet");
 		reg_w(gspca_dev, 0x00, 0x8880, 3);
 		err = spca50x_setup_qtable(gspca_dev,
@@ -881,6 +892,13 @@ static void sd_stopN(struct gspca_dev *g
 		gspca_dev->usb_buf[0]);
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	kfree(sd->jpeg_hdr);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -901,7 +919,8 @@ static void sd_pkt_scan(struct gspca_dev
 					ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		data += SPCA500_OFFSET_DATA;
 		len -= SPCA500_OFFSET_DATA;
@@ -937,16 +956,6 @@ static void setbrightness(struct gspca_d
 			(__u8) (sd->brightness - 128));
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
-
-	ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
-	if (ret >= 0)
-		sd->brightness = ret + 128;
-}
-
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -954,16 +963,6 @@ static void setcontrast(struct gspca_dev
 	reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
 }
 
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
-
-	ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
-	if (ret >= 0)
-		sd->contrast = ret;
-}
-
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -971,16 +970,6 @@ static void setcolors(struct gspca_dev *
 	reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
 }
 
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
-
-	ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
-	if (ret >= 0)
-		sd->colors = ret;
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -995,7 +984,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -1014,7 +1002,6 @@ static int sd_getcontrast(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcontrast(gspca_dev);
 	*val = sd->contrast;
 	return 0;
 }
@@ -1033,11 +1020,38 @@ static int sd_getcolors(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcolors(gspca_dev);
 	*val = sd->colors;
 	return 0;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -1047,7 +1061,10 @@ static struct sd_desc sd_desc = {
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -1093,8 +1110,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca501.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca501.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca501.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca501.c	2009-06-09 23:05:27.000000000 -0400
@@ -1883,10 +1883,6 @@ static void setbrightness(struct gspca_d
 	reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-}
-
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1897,10 +1893,6 @@ static void setcontrast(struct gspca_dev
 				  sd->contrast & 0xff);
 }
 
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1908,10 +1900,6 @@ static void setcolors(struct gspca_dev *
 	reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
 }
 
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-}
-
 static void setblue_balance(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1934,7 +1922,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 	sd->subtype = id->driver_info;
@@ -2084,7 +2071,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -2103,7 +2089,6 @@ static int sd_getcontrast(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcontrast(gspca_dev);
 	*val = sd->contrast;
 	return 0;
 }
@@ -2122,7 +2107,6 @@ static int sd_getcolors(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcolors(gspca_dev);
 	*val = sd->colors;
 	return 0;
 }
@@ -2211,8 +2195,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca505.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca505.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca505.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca505.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,9 +31,9 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;		/* !! must be the first item */
 
-	unsigned char brightness;
+	u8 brightness;
 
-	char subtype;
+	u8 subtype;
 #define IntelPCCameraPro 0
 #define Nxultra 1
 };
@@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca
 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
@@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 255,
 		.step    = 1,
-		.default_value = 127,
+#define BRIGHTNESS_DEF 127
+		.default_value = BRIGHTNESS_DEF,
 	    },
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
@@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_
 		.bytesperline = 160,
 		.sizeimage = 160 * 120 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 5},
+		.priv = 4},
 	{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 		.bytesperline = 176,
 		.sizeimage = 176 * 144 * 3 / 2,
 		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 4},
+		.priv = 3},
 	{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
 		.bytesperline = 320,
 		.sizeimage = 320 * 240 * 3 / 2,
@@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_
 
 #define SPCA50X_USB_CTRL 0x00	/* spca505 */
 #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+
 #define SPCA50X_REG_GLOBAL 0x03	/* spca505 */
 #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
 #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
@@ -101,230 +102,230 @@ static const struct v4l2_pix_format vga_
 #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
 #define SPCA50X_GMISC3_SAA7113RST 0x20	/* Not sure about this one spca505 */
 
+/* Image format and compression control */
+#define SPCA50X_REG_COMPRESS 0x04
+
 /*
  * Data to initialize a SPCA505. Common to the CCD and external modes
  */
-static const __u16 spca505_init_data[][3] = {
-	/* line	   bmRequest,value,index */
-	/* 1819 */
+static const u8 spca505_init_data[][3] = {
+	/* bmRequest,value,index */
 	{SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
 	/* Sensor reset */
-	/* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
-	/* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+	{SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+	{SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
 	/* Block USB reset */
-	/* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
-		SPCA50X_GLOBAL_MISC0},
+	{SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
 
-	/* 1831 */ {0x5, 0x01, 0x10},
+	{0x05, 0x01, 0x10},
 					/* Maybe power down some stuff */
-	/* 1834 */ {0x5, 0x0f, 0x11},
+	{0x05, 0x0f, 0x11},
 
 	/* Setup internal CCD  ? */
-	/* 1837 */ {0x6, 0x10, 0x08},
-	/* 1840 */ {0x6, 0x00, 0x09},
-	/* 1843 */ {0x6, 0x00, 0x0a},
-	/* 1846 */ {0x6, 0x00, 0x0b},
-	/* 1849 */ {0x6, 0x10, 0x0c},
-	/* 1852 */ {0x6, 0x00, 0x0d},
-	/* 1855 */ {0x6, 0x00, 0x0e},
-	/* 1858 */ {0x6, 0x00, 0x0f},
-	/* 1861 */ {0x6, 0x10, 0x10},
-	/* 1864 */ {0x6, 0x02, 0x11},
-	/* 1867 */ {0x6, 0x00, 0x12},
-	/* 1870 */ {0x6, 0x04, 0x13},
-	/* 1873 */ {0x6, 0x02, 0x14},
-	/* 1876 */ {0x6, 0x8a, 0x51},
-	/* 1879 */ {0x6, 0x40, 0x52},
-	/* 1882 */ {0x6, 0xb6, 0x53},
-	/* 1885 */ {0x6, 0x3d, 0x54},
+	{0x06, 0x10, 0x08},
+	{0x06, 0x00, 0x09},
+	{0x06, 0x00, 0x0a},
+	{0x06, 0x00, 0x0b},
+	{0x06, 0x10, 0x0c},
+	{0x06, 0x00, 0x0d},
+	{0x06, 0x00, 0x0e},
+	{0x06, 0x00, 0x0f},
+	{0x06, 0x10, 0x10},
+	{0x06, 0x02, 0x11},
+	{0x06, 0x00, 0x12},
+	{0x06, 0x04, 0x13},
+	{0x06, 0x02, 0x14},
+	{0x06, 0x8a, 0x51},
+	{0x06, 0x40, 0x52},
+	{0x06, 0xb6, 0x53},
+	{0x06, 0x3d, 0x54},
 	{}
 };
 
 /*
  * Data to initialize the camera using the internal CCD
  */
-static const __u16 spca505_open_data_ccd[][3] = {
-	/* line	   bmRequest,value,index */
+static const u8 spca505_open_data_ccd[][3] = {
+	/* bmRequest,value,index */
 	/* Internal CCD data set */
-	/* 1891 */ {0x3, 0x04, 0x01},
+	{0x03, 0x04, 0x01},
 	/* This could be a reset */
-	/* 1894 */ {0x3, 0x00, 0x01},
+	{0x03, 0x00, 0x01},
 
 	/* Setup compression and image registers. 0x6 and 0x7 seem to be
 	   related to H&V hold, and are resolution mode specific */
-		/* 1897 */ {0x4, 0x10, 0x01},
+		{0x04, 0x10, 0x01},
 		/* DIFF(0x50), was (0x10) */
-	/* 1900 */ {0x4, 0x00, 0x04},
-	/* 1903 */ {0x4, 0x00, 0x05},
-	/* 1906 */ {0x4, 0x20, 0x06},
-	/* 1909 */ {0x4, 0x20, 0x07},
+	{0x04, 0x00, 0x04},
+	{0x04, 0x00, 0x05},
+	{0x04, 0x20, 0x06},
+	{0x04, 0x20, 0x07},
 
-	/* 1912 */ {0x8, 0x0a, 0x00},
+	{0x08, 0x0a, 0x00},
 	/* DIFF (0x4a), was (0xa) */
 
-	/* 1915 */ {0x5, 0x00, 0x10},
-	/* 1918 */ {0x5, 0x00, 0x11},
-	/* 1921 */ {0x5, 0x00, 0x00},
+	{0x05, 0x00, 0x10},
+	{0x05, 0x00, 0x11},
+	{0x05, 0x00, 0x00},
 	/* DIFF not written */
-	/* 1924 */ {0x5, 0x00, 0x01},
+	{0x05, 0x00, 0x01},
 	/* DIFF not written */
-	/* 1927 */ {0x5, 0x00, 0x02},
+	{0x05, 0x00, 0x02},
 	/* DIFF not written */
-	/* 1930 */ {0x5, 0x00, 0x03},
+	{0x05, 0x00, 0x03},
 	/* DIFF not written */
-	/* 1933 */ {0x5, 0x00, 0x04},
+	{0x05, 0x00, 0x04},
 	/* DIFF not written */
-		/* 1936 */ {0x5, 0x80, 0x05},
+		{0x05, 0x80, 0x05},
 		/* DIFF not written */
-		/* 1939 */ {0x5, 0xe0, 0x06},
+		{0x05, 0xe0, 0x06},
 		/* DIFF not written */
-		/* 1942 */ {0x5, 0x20, 0x07},
+		{0x05, 0x20, 0x07},
 		/* DIFF not written */
-		/* 1945 */ {0x5, 0xa0, 0x08},
+		{0x05, 0xa0, 0x08},
 		/* DIFF not written */
-		/* 1948 */ {0x5, 0x0, 0x12},
+		{0x05, 0x0, 0x12},
 		/* DIFF not written */
-	/* 1951 */ {0x5, 0x02, 0x0f},
+	{0x05, 0x02, 0x0f},
 	/* DIFF not written */
-		/* 1954 */ {0x5, 0x10, 0x46},
+		{0x05, 0x10, 0x46},
 		/* DIFF not written */
-		/* 1957 */ {0x5, 0x8, 0x4a},
+		{0x05, 0x8, 0x4a},
 		/* DIFF not written */
 
-	/* 1960 */ {0x3, 0x08, 0x03},
+	{0x03, 0x08, 0x03},
 	/* DIFF (0x3,0x28,0x3) */
-	/* 1963 */ {0x3, 0x08, 0x01},
-	/* 1966 */ {0x3, 0x0c, 0x03},
+	{0x03, 0x08, 0x01},
+	{0x03, 0x0c, 0x03},
 	/* DIFF not written */
-		/* 1969 */ {0x3, 0x21, 0x00},
+		{0x03, 0x21, 0x00},
 		/* DIFF (0x39) */
 
 /* Extra block copied from init to hopefully ensure CCD is in a sane state */
-	/* 1837 */ {0x6, 0x10, 0x08},
-	/* 1840 */ {0x6, 0x00, 0x09},
-	/* 1843 */ {0x6, 0x00, 0x0a},
-	/* 1846 */ {0x6, 0x00, 0x0b},
-	/* 1849 */ {0x6, 0x10, 0x0c},
-	/* 1852 */ {0x6, 0x00, 0x0d},
-	/* 1855 */ {0x6, 0x00, 0x0e},
-	/* 1858 */ {0x6, 0x00, 0x0f},
-	/* 1861 */ {0x6, 0x10, 0x10},
-	/* 1864 */ {0x6, 0x02, 0x11},
-	/* 1867 */ {0x6, 0x00, 0x12},
-	/* 1870 */ {0x6, 0x04, 0x13},
-	/* 1873 */ {0x6, 0x02, 0x14},
-	/* 1876 */ {0x6, 0x8a, 0x51},
-	/* 1879 */ {0x6, 0x40, 0x52},
-	/* 1882 */ {0x6, 0xb6, 0x53},
-	/* 1885 */ {0x6, 0x3d, 0x54},
+	{0x06, 0x10, 0x08},
+	{0x06, 0x00, 0x09},
+	{0x06, 0x00, 0x0a},
+	{0x06, 0x00, 0x0b},
+	{0x06, 0x10, 0x0c},
+	{0x06, 0x00, 0x0d},
+	{0x06, 0x00, 0x0e},
+	{0x06, 0x00, 0x0f},
+	{0x06, 0x10, 0x10},
+	{0x06, 0x02, 0x11},
+	{0x06, 0x00, 0x12},
+	{0x06, 0x04, 0x13},
+	{0x06, 0x02, 0x14},
+	{0x06, 0x8a, 0x51},
+	{0x06, 0x40, 0x52},
+	{0x06, 0xb6, 0x53},
+	{0x06, 0x3d, 0x54},
 	/* End of extra block */
 
-		/* 1972 */ {0x6, 0x3f, 0x1},
+		{0x06, 0x3f, 0x1},
 		/* Block skipped */
-	/* 1975 */ {0x6, 0x10, 0x02},
-	/* 1978 */ {0x6, 0x64, 0x07},
-	/* 1981 */ {0x6, 0x10, 0x08},
-	/* 1984 */ {0x6, 0x00, 0x09},
-	/* 1987 */ {0x6, 0x00, 0x0a},
-	/* 1990 */ {0x6, 0x00, 0x0b},
-	/* 1993 */ {0x6, 0x10, 0x0c},
-	/* 1996 */ {0x6, 0x00, 0x0d},
-	/* 1999 */ {0x6, 0x00, 0x0e},
-	/* 2002 */ {0x6, 0x00, 0x0f},
-	/* 2005 */ {0x6, 0x10, 0x10},
-	/* 2008 */ {0x6, 0x02, 0x11},
-	/* 2011 */ {0x6, 0x00, 0x12},
-	/* 2014 */ {0x6, 0x04, 0x13},
-	/* 2017 */ {0x6, 0x02, 0x14},
-	/* 2020 */ {0x6, 0x8a, 0x51},
-	/* 2023 */ {0x6, 0x40, 0x52},
-	/* 2026 */ {0x6, 0xb6, 0x53},
-	/* 2029 */ {0x6, 0x3d, 0x54},
-	/* 2032 */ {0x6, 0x60, 0x57},
-	/* 2035 */ {0x6, 0x20, 0x58},
-	/* 2038 */ {0x6, 0x15, 0x59},
-	/* 2041 */ {0x6, 0x05, 0x5a},
+	{0x06, 0x10, 0x02},
+	{0x06, 0x64, 0x07},
+	{0x06, 0x10, 0x08},
+	{0x06, 0x00, 0x09},
+	{0x06, 0x00, 0x0a},
+	{0x06, 0x00, 0x0b},
+	{0x06, 0x10, 0x0c},
+	{0x06, 0x00, 0x0d},
+	{0x06, 0x00, 0x0e},
+	{0x06, 0x00, 0x0f},
+	{0x06, 0x10, 0x10},
+	{0x06, 0x02, 0x11},
+	{0x06, 0x00, 0x12},
+	{0x06, 0x04, 0x13},
+	{0x06, 0x02, 0x14},
+	{0x06, 0x8a, 0x51},
+	{0x06, 0x40, 0x52},
+	{0x06, 0xb6, 0x53},
+	{0x06, 0x3d, 0x54},
+	{0x06, 0x60, 0x57},
+	{0x06, 0x20, 0x58},
+	{0x06, 0x15, 0x59},
+	{0x06, 0x05, 0x5a},
 
-	/* 2044 */ {0x5, 0x01, 0xc0},
-	/* 2047 */ {0x5, 0x10, 0xcb},
-		/* 2050 */ {0x5, 0x80, 0xc1},
+	{0x05, 0x01, 0xc0},
+	{0x05, 0x10, 0xcb},
+		{0x05, 0x80, 0xc1},
 		/* */
-		/* 2053 */ {0x5, 0x0, 0xc2},
+		{0x05, 0x0, 0xc2},
 		/* 4 was 0 */
-	/* 2056 */ {0x5, 0x00, 0xca},
-		/* 2059 */ {0x5, 0x80, 0xc1},
+	{0x05, 0x00, 0xca},
+		{0x05, 0x80, 0xc1},
 		/*  */
-	/* 2062 */ {0x5, 0x04, 0xc2},
-	/* 2065 */ {0x5, 0x00, 0xca},
-		/* 2068 */ {0x5, 0x0, 0xc1},
+	{0x05, 0x04, 0xc2},
+	{0x05, 0x00, 0xca},
+		{0x05, 0x0, 0xc1},
 		/*  */
-	/* 2071 */ {0x5, 0x00, 0xc2},
-	/* 2074 */ {0x5, 0x00, 0xca},
-		/* 2077 */ {0x5, 0x40, 0xc1},
+	{0x05, 0x00, 0xc2},
+	{0x05, 0x00, 0xca},
+		{0x05, 0x40, 0xc1},
 		/* */
-	/* 2080 */ {0x5, 0x17, 0xc2},
-	/* 2083 */ {0x5, 0x00, 0xca},
-		/* 2086 */ {0x5, 0x80, 0xc1},
+	{0x05, 0x17, 0xc2},
+	{0x05, 0x00, 0xca},
+		{0x05, 0x80, 0xc1},
 		/* */
-	/* 2089 */ {0x5, 0x06, 0xc2},
-	/* 2092 */ {0x5, 0x00, 0xca},
-		/* 2095 */ {0x5, 0x80, 0xc1},
+	{0x05, 0x06, 0xc2},
+	{0x05, 0x00, 0xca},
+		{0x05, 0x80, 0xc1},
 		/* */
-	/* 2098 */ {0x5, 0x04, 0xc2},
-	/* 2101 */ {0x5, 0x00, 0xca},
+	{0x05, 0x04, 0xc2},
+	{0x05, 0x00, 0xca},
 
-	/* 2104 */ {0x3, 0x4c, 0x3},
-	/* 2107 */ {0x3, 0x18, 0x1},
+	{0x03, 0x4c, 0x3},
+	{0x03, 0x18, 0x1},
 
-	/* 2110 */ {0x6, 0x70, 0x51},
-	/* 2113 */ {0x6, 0xbe, 0x53},
-	/* 2116 */ {0x6, 0x71, 0x57},
-	/* 2119 */ {0x6, 0x20, 0x58},
-	/* 2122 */ {0x6, 0x05, 0x59},
-	/* 2125 */ {0x6, 0x15, 0x5a},
+	{0x06, 0x70, 0x51},
+	{0x06, 0xbe, 0x53},
+	{0x06, 0x71, 0x57},
+	{0x06, 0x20, 0x58},
+	{0x06, 0x05, 0x59},
+	{0x06, 0x15, 0x5a},
 
-	/* 2128 */ {0x4, 0x00, 0x08},
+	{0x04, 0x00, 0x08},
 	/* Compress = OFF (0x1 to turn on) */
-	/* 2131 */ {0x4, 0x12, 0x09},
-	/* 2134 */ {0x4, 0x21, 0x0a},
-	/* 2137 */ {0x4, 0x10, 0x0b},
-	/* 2140 */ {0x4, 0x21, 0x0c},
-	/* 2143 */ {0x4, 0x05, 0x00},
+	{0x04, 0x12, 0x09},
+	{0x04, 0x21, 0x0a},
+	{0x04, 0x10, 0x0b},
+	{0x04, 0x21, 0x0c},
+	{0x04, 0x05, 0x00},
 	/* was 5 (Image Type ? ) */
-	/* 2146 */ {0x4, 0x00, 0x01},
+	{0x04, 0x00, 0x01},
 
-	/* 2149 */ {0x6, 0x3f, 0x01},
+	{0x06, 0x3f, 0x01},
 
-	/* 2152 */ {0x4, 0x00, 0x04},
-	/* 2155 */ {0x4, 0x00, 0x05},
-	/* 2158 */ {0x4, 0x40, 0x06},
-	/* 2161 */ {0x4, 0x40, 0x07},
+	{0x04, 0x00, 0x04},
+	{0x04, 0x00, 0x05},
+	{0x04, 0x40, 0x06},
+	{0x04, 0x40, 0x07},
 
-	/* 2164 */ {0x6, 0x1c, 0x17},
-	/* 2167 */ {0x6, 0xe2, 0x19},
-	/* 2170 */ {0x6, 0x1c, 0x1b},
-	/* 2173 */ {0x6, 0xe2, 0x1d},
-	/* 2176 */ {0x6, 0xaa, 0x1f},
-	/* 2179 */ {0x6, 0x70, 0x20},
+	{0x06, 0x1c, 0x17},
+	{0x06, 0xe2, 0x19},
+	{0x06, 0x1c, 0x1b},
+	{0x06, 0xe2, 0x1d},
+	{0x06, 0xaa, 0x1f},
+	{0x06, 0x70, 0x20},
 
-	/* 2182 */ {0x5, 0x01, 0x10},
-	/* 2185 */ {0x5, 0x00, 0x11},
-	/* 2188 */ {0x5, 0x01, 0x00},
-	/* 2191 */ {0x5, 0x05, 0x01},
-		/* 2194 */ {0x5, 0x00, 0xc1},
+	{0x05, 0x01, 0x10},
+	{0x05, 0x00, 0x11},
+	{0x05, 0x01, 0x00},
+	{0x05, 0x05, 0x01},
+		{0x05, 0x00, 0xc1},
 		/* */
-	/* 2197 */ {0x5, 0x00, 0xc2},
-	/* 2200 */ {0x5, 0x00, 0xca},
+	{0x05, 0x00, 0xc2},
+	{0x05, 0x00, 0xca},
 
-	/* 2203 */ {0x6, 0x70, 0x51},
-	/* 2206 */ {0x6, 0xbe, 0x53},
+	{0x06, 0x70, 0x51},
+	{0x06, 0xbe, 0x53},
 	{}
 };
 
 /*
-   Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
  * SPCA505b chip based cameras initialization data
- *
  */
 /* jfm */
 #define initial_brightness 0x7f	/* 0x0(white)-0xff(black) */
@@ -332,7 +333,7 @@ static const __u16 spca505_open_data_ccd
 /*
  * Data to initialize a SPCA505. Common to the CCD and external modes
  */
-static const __u16 spca505b_init_data[][3] = {
+static const u8 spca505b_init_data[][3] = {
 /* start */
 	{0x02, 0x00, 0x00},		/* init */
 	{0x02, 0x00, 0x01},
@@ -396,7 +397,7 @@ static const __u16 spca505b_init_data[][
 /*
  * Data to initialize the camera using the internal CCD
  */
-static const __u16 spca505b_open_data_ccd[][3] = {
+static const u8 spca505b_open_data_ccd[][3] = {
 
 /* {0x02,0x00,0x00}, */
 	{0x03, 0x04, 0x01},		/* rst */
@@ -426,7 +427,7 @@ static const __u16 spca505b_open_data_cc
 	{0x05, 0x00, 0x12},
 	{0x05, 0x6f, 0x00},
 	{0x05, initial_brightness >> 6, 0x00},
-	{0x05, initial_brightness << 2, 0x01},
+	{0x05, (initial_brightness << 2) & 0xff, 0x01},
 	{0x05, 0x00, 0x02},
 	{0x05, 0x01, 0x03},
 	{0x05, 0x00, 0x04},
@@ -436,7 +437,7 @@ static const __u16 spca505b_open_data_cc
 	{0x05, 0xa0, 0x08},
 	{0x05, 0x00, 0x12},
 	{0x05, 0x02, 0x0f},
-	{0x05, 128, 0x14},		/* max exposure off (0=on) */
+	{0x05, 0x80, 0x14},		/* max exposure off (0=on) */
 	{0x05, 0x01, 0xb0},
 	{0x05, 0x01, 0xbf},
 	{0x03, 0x02, 0x06},
@@ -560,26 +561,26 @@ static const __u16 spca505b_open_data_cc
 	{0x06, 0x32, 0x20},
 
 	{0x05, initial_brightness >> 6, 0x00},
-	{0x05, initial_brightness << 2, 0x01},
+	{0x05, (initial_brightness << 2) & 0xff, 0x01},
 	{0x05, 0x06, 0xc1},
 	{0x05, 0x58, 0xc2},
-	{0x05, 0x0, 0xca},
-	{0x05, 0x0, 0x11},
+	{0x05, 0x00, 0xca},
+	{0x05, 0x00, 0x11},
 	{}
 };
 
 static int reg_write(struct usb_device *dev,
-		     __u16 reg, __u16 index, __u16 value)
+		     u16 req, u16 index, u16 value)
 {
 	int ret;
 
 	ret = usb_control_msg(dev,
 			usb_sndctrlpipe(dev, 0),
-			reg,
+			req,
 			USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index, NULL, 0, 500);
-	PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
-		reg, index, value, ret);
+	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;
@@ -587,42 +588,34 @@ static int reg_write(struct usb_device *
 
 /* returns: negative is error, pos or zero is data */
 static int reg_read(struct gspca_dev *gspca_dev,
-			__u16 reg,	/* bRequest */
-			__u16 index,	/* wIndex */
-			__u16 length)	/* wLength (1 or 2 only) */
+			u16 req,	/* bRequest */
+			u16 index)	/* wIndex */
 {
 	int ret;
 
-	gspca_dev->usb_buf[1] = 0;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
-			reg,
+			req,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			(__u16) 0,		/* value */
-			(__u16) index,
-			gspca_dev->usb_buf, length,
+			0,			/* value */
+			index,
+			gspca_dev->usb_buf, 2,
 			500);			/* timeout */
-	if (ret < 0) {
-		PDEBUG(D_ERR, "reg_read err %d", ret);
-		return -1;
-	}
+	if (ret < 0)
+		return ret;
 	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
 }
 
 static int write_vector(struct gspca_dev *gspca_dev,
-			const __u16 data[][3])
+			const u8 data[][3])
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int ret, i = 0;
 
-	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+	while (data[i][0] != 0) {
 		ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
-		if (ret < 0) {
-			PDEBUG(D_ERR,
-				"Register write failed for 0x%x,0x%x,0x%x",
-				data[i][0], data[i][1], data[i][2]);
+		if (ret < 0)
 			return ret;
-		}
 		i++;
 	}
 	return 0;
@@ -636,14 +629,13 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	sd->subtype = id->driver_info;
 	if (sd->subtype != IntelPCCameraPro)
-		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+		cam->nmodes = ARRAY_SIZE(vga_mode);
 	else			/* no 640x480 for IntelPCCameraPro */
-		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
-	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+		cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
+	sd->brightness = BRIGHTNESS_DEF;
 
 	if (sd->subtype == Nxultra) {
 		if (write_vector(gspca_dev, spca505b_init_data))
@@ -658,81 +650,71 @@ 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)
 {
+	return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
 	struct sd *sd = (struct sd *) gspca_dev;
-	int ret;
+	u8 brightness = sd->brightness;
+
+	reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
+	reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *dev = gspca_dev->dev;
+	int ret, mode;
+	static u8 mode_tb[][3] = {
+	/*	  r00   r06   r07	*/
+		{0x00, 0x10, 0x10},	/* 640x480 */
+		{0x01, 0x1a, 0x1a},	/* 352x288 */
+		{0x02, 0x1c, 0x1d},	/* 320x240 */
+		{0x04, 0x34, 0x34},	/* 176x144 */
+		{0x05, 0x40, 0x40}	/* 160x120 */
+	};
 
-	PDEBUG(D_STREAM, "Initializing SPCA505");
 	if (sd->subtype == Nxultra)
 		write_vector(gspca_dev, spca505b_open_data_ccd);
 	else
 		write_vector(gspca_dev, spca505_open_data_ccd);
-	ret = reg_read(gspca_dev, 6, 0x16, 2);
+	ret = reg_read(gspca_dev, 0x06, 0x16);
 
 	if (ret < 0) {
-		PDEBUG(D_ERR|D_STREAM,
-		       "register read failed for after vector read err = %d",
+		PDEBUG(D_ERR|D_CONF,
+		       "register read failed err: %d",
 		       ret);
-		return -EIO;
+		return ret;
 	}
-	PDEBUG(D_STREAM,
-		"After vector read returns : 0x%x should be 0x0101",
-		ret & 0xffff);
-
-	ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
-	if (ret < 0) {
-		PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
-		       ret);
-		return -EIO;
+	if (ret != 0x0101) {
+		PDEBUG(D_ERR|D_CONF,
+			"After vector read returns 0x%04x should be 0x0101",
+			ret);
 	}
-	reg_write(gspca_dev->dev, 5, 0xc2, 18);
-	return 0;
-}
 
-static int sd_start(struct gspca_dev *gspca_dev)
-{
-	struct usb_device *dev = gspca_dev->dev;
-	int ret;
+	ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
+	if (ret < 0)
+		return ret;
+	reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
 
 	/* necessary because without it we can see stream
 	 * only once after loading module */
 	/* stopping usb registers Tomasz change */
-	reg_write(dev, 0x02, 0x0, 0x0);
-	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
-	case 0:
-		reg_write(dev, 0x04, 0x00, 0x00);
-		reg_write(dev, 0x04, 0x06, 0x10);
-		reg_write(dev, 0x04, 0x07, 0x10);
-		break;
-	case 1:
-		reg_write(dev, 0x04, 0x00, 0x01);
-		reg_write(dev, 0x04, 0x06, 0x1a);
-		reg_write(dev, 0x04, 0x07, 0x1a);
-		break;
-	case 2:
-		reg_write(dev, 0x04, 0x00, 0x02);
-		reg_write(dev, 0x04, 0x06, 0x1c);
-		reg_write(dev, 0x04, 0x07, 0x1d);
-		break;
-	case 4:
-		reg_write(dev, 0x04, 0x00, 0x04);
-		reg_write(dev, 0x04, 0x06, 0x34);
-		reg_write(dev, 0x04, 0x07, 0x34);
-		break;
-	default:
-/*	case 5: */
-		reg_write(dev, 0x04, 0x00, 0x05);
-		reg_write(dev, 0x04, 0x06, 0x40);
-		reg_write(dev, 0x04, 0x07, 0x40);
-		break;
-	}
-/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+	reg_write(dev, 0x02, 0x00, 0x00);
+
+	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+	reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
+	reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
+	reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
+
 	ret = reg_write(dev, SPCA50X_REG_USB,
 			 SPCA50X_USB_CTRL,
 			 SPCA50X_CUSB_ENABLE);
 
-/*	reg_write(dev, 0x5, 0x0, 0x0); */
-/*	reg_write(dev, 0x5, 0x0, 0x1); */
-/*	reg_write(dev, 0x5, 0x11, 0x2); */
+	setbrightness(gspca_dev);
+
 	return ret;
 }
 
@@ -750,15 +732,15 @@ static void sd_stop0(struct gspca_dev *g
 
 	/* This maybe reset or power control */
 	reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
-	reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
-	reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
-	reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
-	reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+	reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
+	reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
+	reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
+	reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
 }
 
 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]) {
@@ -771,7 +753,6 @@ static void sd_pkt_scan(struct gspca_dev
 				data, len);
 		break;
 	case 0xff:			/* drop */
-/*		gspca_dev->last_packet_type = DISCARD_PACKET; */
 		break;
 	default:
 		data += 1;
@@ -782,24 +763,6 @@ static void sd_pkt_scan(struct gspca_dev
 	}
 }
 
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	__u8 brightness = sd->brightness;
-	reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
-	reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
-
-}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->brightness = 255
-		- ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
-			+ (reg_read(gspca_dev, 5, 0x0, 1) << 6));
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -814,7 +777,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -863,8 +825,11 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca506.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca506.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca506.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca506.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspc
 	}
 }
 
-static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
-{
-	int retry = 60;
-
-	reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
-	reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
-	reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
-	while (--retry) {
-		reg_r(gspca_dev, 0x07, 0x0003, 2);
-		if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
-			break;
-	}
-	if (retry == 0)
-		return -1;
-	reg_r(gspca_dev, 0x07, 0x0000, 1);
-	return gspca_dev->usb_buf[0];
-}
-
 static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
 				 __u16 norme,
 				 __u16 channel)
@@ -303,7 +285,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
@@ -596,13 +577,6 @@ static void setbrightness(struct gspca_d
 	spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
-}
-
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -612,13 +586,6 @@ static void setcontrast(struct gspca_dev
 	spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 }
 
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
-}
-
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -628,13 +595,6 @@ static void setcolors(struct gspca_dev *
 	spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 }
 
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
-}
-
 static void sethue(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -644,13 +604,6 @@ static void sethue(struct gspca_dev *gsp
 	spca506_WriteI2c(gspca_dev, 0x01, 0x09);
 }
 
-static void gethue(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -665,7 +618,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -684,7 +636,6 @@ static int sd_getcontrast(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcontrast(gspca_dev);
 	*val = sd->contrast;
 	return 0;
 }
@@ -703,7 +654,6 @@ static int sd_getcolors(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcolors(gspca_dev);
 	*val = sd->colors;
 	return 0;
 }
@@ -722,7 +672,6 @@ static int sd_gethue(struct gspca_dev *g
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	gethue(gspca_dev);
 	*val = sd->hue;
 	return 0;
 }
@@ -772,8 +721,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca508.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca508.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca508.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca508.c	2009-06-09 23:05:27.000000000 -0400
@@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_
  * Initialization data: this is the first set-up data written to the
  * device (before the open data).
  */
-static const __u16 spca508_init_data[][3] =
-#define IGN(x)			/* nothing */
+static const u16 spca508_init_data[][2] =
 {
 	/*  line   URB      value, index */
 	/* 44274  1804 */ {0x0000, 0x870b},
@@ -589,11 +588,10 @@ static const __u16 spca508_init_data[][3
 	{}
 };
 
-
 /*
  * Initialization data for Intel EasyPC Camera CS110
  */
-static const __u16 spca508cs110_init_data[][3] = {
+static const u16 spca508cs110_init_data[][2] = {
 	{0x0000, 0x870b}, /* Reset CTL3 */
 	{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
 	{0x0000, 0x8111}, /* Normal operation on reset */
@@ -677,7 +675,7 @@ static const __u16 spca508cs110_init_dat
 	{}
 };
 
-static const __u16 spca508_sightcam_init_data[][3] = {
+static const u16 spca508_sightcam_init_data[][2] = {
 /* This line seems to setup the frame/canvas */
 	/*368  */ {0x000f, 0x8402},
 
@@ -760,7 +758,7 @@ static const __u16 spca508_sightcam_init
 	{}
 };
 
-static const __u16 spca508_sightcam2_init_data[][3] = {
+static const u16 spca508_sightcam2_init_data[][2] = {
 /* 35 */ {0x0020, 0x8112},
 
 /* 36 */ {0x000f, 0x8402},
@@ -1107,7 +1105,7 @@ static const __u16 spca508_sightcam2_ini
 /*
  * Initialization data for Creative Webcam Vista
  */
-static const __u16 spca508_vista_init_data[][3] = {
+static const u16 spca508_vista_init_data[][2] = {
 	{0x0008, 0x8200},	/* Clear register */
 	{0x0000, 0x870b},	/* Reset CTL3 */
 	{0x0020, 0x8112},	/* Video Drop packet enable */
@@ -1309,18 +1307,18 @@ static const __u16 spca508_vista_init_da
 
 	{0x0050, 0x8703},
 	{0x0002, 0x8704},	/* External input CKIx1 */
-	{0x0001, 0x870C},	/* Select CKOx2 output */
-	{0x009A, 0x8600},	/* Line memory Read Counter (L) */
+	{0x0001, 0x870c},	/* Select CKOx2 output */
+	{0x009a, 0x8600},	/* Line memory Read Counter (L) */
 	{0x0001, 0x8606},  /* 1 Line memory Read Counter (H) Result: (d)410 */
 	{0x0023, 0x8601},
 	{0x0010, 0x8602},
-	{0x000A, 0x8603},
+	{0x000a, 0x8603},
 	{0x009A, 0x8600},
-	{0x0001, 0x865B},	/* 1 Horizontal Offset for Valid Pixel(L) */
-	{0x0003, 0x865C},	/* Vertical offset for valid lines (L) */
-	{0x0058, 0x865D},	/* Horizontal valid pixels window (L) */
-	{0x0048, 0x865E},	/* Vertical valid lines window (L) */
-	{0x0000, 0x865F},
+	{0x0001, 0x865b},	/* 1 Horizontal Offset for Valid Pixel(L) */
+	{0x0003, 0x865c},	/* Vertical offset for valid lines (L) */
+	{0x0058, 0x865d},	/* Horizontal valid pixels window (L) */
+	{0x0048, 0x865e},	/* Vertical valid lines window (L) */
+	{0x0000, 0x865f},
 
 	{0x0006, 0x8660},
 		    /* Enable nibble data input, select nibble input order */
@@ -1328,63 +1326,63 @@ static const __u16 spca508_vista_init_da
 	{0x0013, 0x8608},	/* A11 Coeficients for color correction */
 	{0x0028, 0x8609},
 		    /* Note: these values are confirmed at the end of array */
-	{0x0005, 0x860A},	/* ... */
-	{0x0025, 0x860B},
-	{0x00E1, 0x860C},
-	{0x00FA, 0x860D},
-	{0x00F4, 0x860E},
-	{0x00E8, 0x860F},
+	{0x0005, 0x860a},	/* ... */
+	{0x0025, 0x860b},
+	{0x00e1, 0x860c},
+	{0x00fa, 0x860D},
+	{0x00f4, 0x860e},
+	{0x00e8, 0x860f},
 	{0x0025, 0x8610},	/* A33 Coef. */
-	{0x00FC, 0x8611},	/* White balance offset: R */
+	{0x00fc, 0x8611},	/* White balance offset: R */
 	{0x0001, 0x8612},	/* White balance offset: Gr */
-	{0x00FE, 0x8613},	/* White balance offset: B */
+	{0x00fe, 0x8613},	/* White balance offset: B */
 	{0x0000, 0x8614},	/* White balance offset: Gb */
 
 	{0x0064, 0x8651},	/* R gain for white balance (L) */
 	{0x0040, 0x8652},	/* Gr gain for white balance (L) */
 	{0x0066, 0x8653},	/* B gain for white balance (L) */
 	{0x0040, 0x8654},	/* Gb gain for white balance (L) */
-	{0x0001, 0x863F},	/* Enable fixed gamma correction */
+	{0x0001, 0x863f},	/* Enable fixed gamma correction */
 
-	{0x00A1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128 */
+	{0x00a1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128 */
 	/* UV division: UV no change, Enable New edge enhancement */
 	{0x0018, 0x8657},	/* Edge gain high threshold */
 	{0x0020, 0x8658},	/* Edge gain low threshold */
 	{0x000A, 0x8659},	/* Edge bandwidth high threshold */
-	{0x0005, 0x865A},	/* Edge bandwidth low threshold */
+	{0x0005, 0x865a},	/* Edge bandwidth low threshold */
 	{0x0064, 0x8607},	/* UV filter enable */
 
 	{0x0016, 0x8660},
-	{0x0000, 0x86B0},	/* Bad pixels compensation address */
-	{0x00DC, 0x86B1},	/* X coord for bad pixels compensation (L) */
-	{0x0000, 0x86B2},
-	{0x0009, 0x86B3},	/* Y coord for bad pixels compensation (L) */
-	{0x0000, 0x86B4},
+	{0x0000, 0x86b0},	/* Bad pixels compensation address */
+	{0x00dc, 0x86b1},	/* X coord for bad pixels compensation (L) */
+	{0x0000, 0x86b2},
+	{0x0009, 0x86b3},	/* Y coord for bad pixels compensation (L) */
+	{0x0000, 0x86b4},
 
-	{0x0001, 0x86B0},
-	{0x00F5, 0x86B1},
-	{0x0000, 0x86B2},
-	{0x00C6, 0x86B3},
-	{0x0000, 0x86B4},
+	{0x0001, 0x86b0},
+	{0x00f5, 0x86b1},
+	{0x0000, 0x86b2},
+	{0x00c6, 0x86b3},
+	{0x0000, 0x86b4},
 
-	{0x0002, 0x86B0},
-	{0x001C, 0x86B1},
-	{0x0001, 0x86B2},
-	{0x00D7, 0x86B3},
-	{0x0000, 0x86B4},
+	{0x0002, 0x86b0},
+	{0x001c, 0x86b1},
+	{0x0001, 0x86b2},
+	{0x00d7, 0x86b3},
+	{0x0000, 0x86b4},
 
-	{0x0003, 0x86B0},
-	{0x001C, 0x86B1},
-	{0x0001, 0x86B2},
-	{0x00D8, 0x86B3},
-	{0x0000, 0x86B4},
+	{0x0003, 0x86b0},
+	{0x001c, 0x86b1},
+	{0x0001, 0x86b2},
+	{0x00d8, 0x86b3},
+	{0x0000, 0x86b4},
 
-	{0x0004, 0x86B0},
-	{0x001D, 0x86B1},
-	{0x0001, 0x86B2},
-	{0x00D8, 0x86B3},
-	{0x0000, 0x86B4},
-	{0x001E, 0x8660},
+	{0x0004, 0x86b0},
+	{0x001d, 0x86b1},
+	{0x0001, 0x86b2},
+	{0x00d8, 0x86b3},
+	{0x0000, 0x86b4},
+	{0x001e, 0x8660},
 
 	/* READ { 0, 0x0000, 0x8608 } ->
 		0000: 13  */
@@ -1449,7 +1447,7 @@ static int reg_read(struct gspca_dev *gs
 }
 
 static int write_vector(struct gspca_dev *gspca_dev,
-			const __u16 data[][3])
+			const u16 data[][2])
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int ret, i = 0;
@@ -1487,7 +1485,6 @@ static int sd_config(struct gspca_dev *g
 	PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	cam->cam_mode = sif_mode;
 	cam->nmodes = ARRAY_SIZE(sif_mode);
 
@@ -1593,13 +1590,6 @@ static void setbrightness(struct gspca_d
 	reg_write(gspca_dev->dev, 0x8654, brightness);
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	sd->brightness = reg_read(gspca_dev, 0x8651);
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1614,7 +1604,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -1666,8 +1655,11 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca561.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca561.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/spca561.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/spca561.c	2009-06-09 23:05:27.000000000 -0400
@@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_
 #define SPCA561_OFFSET_WIN1GBAVE 14
 #define SPCA561_OFFSET_FREQ 15
 #define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_OFFSET_DATA 1
 #define SPCA561_INDEX_I2C_BASE 0x8800
 #define SPCA561_SNAPBIT 0x20
 #define SPCA561_SNAPCTRL 0x40
 
-static const __u16 rev72a_init_data1[][2] = {
+static const u16 rev72a_reset[][2] = {
 	{0x0000, 0x8114},	/* Software GPIO output data */
 	{0x0001, 0x8114},	/* Software GPIO output data */
 	{0x0000, 0x8112},	/* Some kind of reset */
+	{}
+};
+static const __u16 rev72a_init_data1[][2] = {
 	{0x0003, 0x8701},	/* PCLK clock delay adjustment */
 	{0x0001, 0x8703},	/* HSYNC from cmos inverted */
 	{0x0011, 0x8118},	/* Enable and conf sensor */
 	{0x0001, 0x8118},	/* Conf sensor */
 	{0x0092, 0x8804},	/* I know nothing about these */
 	{0x0010, 0x8802},	/* 0x88xx registers, so I won't */
-	{0x000d, 0x8805},	/* sensor default setting */
 	{}
 };
-static const __u16 rev72a_init_sensor1[][2] = {
-				/* ms-win values */
-	{0x0001, 0x0018},	/* 0x01 <- 0x0d */
-	{0x0002, 0x0065},	/* 0x02 <- 0x18 */
-	{0x0004, 0x0121},	/* 0x04 <- 0x0165 */
-	{0x0005, 0x00aa},	/* 0x05 <- 0x21 */
-	{0x0007, 0x0004},	/* 0x07 <- 0xaa */
-	{0x0020, 0x1502},	/* 0x20 <- 0x1504 */
-	{0x0039, 0x0010},	/* 0x39 <- 0x02 */
-	{0x0035, 0x0049},	/* 0x35 <- 0x10 */
-	{0x0009, 0x100b},	/* 0x09 <- 0x1049 */
-	{0x0028, 0x000f},	/* 0x28 <- 0x0b */
-	{0x003b, 0x003c},	/* 0x3b <- 0x0f */
-	{0x003c, 0x0000},	/* 0x3c <- 0x00 */
+static const u16 rev72a_init_sensor1[][2] = {
+	{0x0001, 0x000d},
+	{0x0002, 0x0018},
+	{0x0004, 0x0165},
+	{0x0005, 0x0021},
+	{0x0007, 0x00aa},
+	{0x0020, 0x1504},
+	{0x0039, 0x0002},
+	{0x0035, 0x0010},
+	{0x0009, 0x1049},
+	{0x0028, 0x000b},
+	{0x003b, 0x000f},
+	{0x003c, 0x0000},
 	{}
 };
 static const __u16 rev72a_init_data2[][2] = {
@@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2
 	{0x0002, 0x8201},	/* Output address for r/w serial EEPROM */
 	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
 	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
-	{0x0007, 0x8201},	/* Output address for r/w serial EEPROM */
-	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
-	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
-	{0x0010, 0x8660},	/* Compensation memory stuff */
-	{0x0018, 0x8660},	/* Compensation memory stuff */
-
-	{0x0004, 0x8611},	/* R offset for white balance */
-	{0x0004, 0x8612},	/* Gr offset for white balance */
-	{0x0007, 0x8613},	/* B offset for white balance */
+/* from ms-win */
+	{0x0000, 0x8611},	/* R offset for white balance */
+	{0x00fd, 0x8612},	/* Gr offset for white balance */
+	{0x0003, 0x8613},	/* B offset for white balance */
 	{0x0000, 0x8614},	/* Gb offset for white balance */
 /* from ms-win */
 	{0x0035, 0x8651},	/* R gain for white balance */
@@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2
 	{0x005f, 0x8653},	/* B gain for white balance */
 	{0x0040, 0x8654},	/* Gb gain for white balance */
 	{0x0002, 0x8502},	/* Maximum average bit rate stuff */
-
 	{0x0011, 0x8802},
+
 	{0x0087, 0x8700},	/* Set master clock (96Mhz????) */
 	{0x0081, 0x8702},	/* Master clock output enable */
 
@@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2
 	{0x0003, 0x865c},	/* Vertical offset for valid lines */
 	{}
 };
-static const __u16 rev72a_init_sensor2[][2] = {
-				/* ms-win values */
-	{0x0003, 0x0121},	/* 0x03 <- 0x01 0x21 //289 */
-	{0x0004, 0x0165},	/* 0x04 <- 0x01 0x65 //357 */
-	{0x0005, 0x002f},	/* 0x05 <- 0x2f */
-	{0x0006, 0x0000},	/* 0x06 <- 0 */
-	{0x000a, 0x0002},	/* 0x0a <- 2 */
-	{0x0009, 0x1061},	/* 0x09 <- 0x1061 */
-	{0x0035, 0x0014},	/* 0x35 <- 0x14 */
-	{}
-};
-static const __u16 rev72a_init_data3[][2] = {
-	{0x0030, 0x8112},	/* ISO and drop packet enable */
-/*fixme: should stop here*/
-	{0x0000, 0x8112},	/* Some kind of reset ???? */
-	{0x0009, 0x8118},	/* Enable sensor and set standby */
-	{0x0000, 0x8114},	/* Software GPIO output data */
-	{0x0000, 0x8114},	/* Software GPIO output data */
-	{0x0001, 0x8114},	/* Software GPIO output data */
-	{0x0000, 0x8112},	/* Some kind of reset ??? */
-	{0x0003, 0x8701},
-	{0x0001, 0x8703},
-	{0x0011, 0x8118},
-	{0x0001, 0x8118},
-	/***************/
-	{0x0092, 0x8804},
-	{0x0010, 0x8802},
-	{0x000d, 0x8805},
-	{0x0001, 0x8801},
-	{0x0000, 0x8800},
-	{0x0018, 0x8805},
-	{0x0002, 0x8801},
-	{0x0000, 0x8800},
-	{0x0065, 0x8805},
-	{0x0004, 0x8801},
-	{0x0001, 0x8800},
-	{0x0021, 0x8805},
-	{0x0005, 0x8801},
-	{0x0000, 0x8800},
-	{0x00aa, 0x8805},
-	{0x0007, 0x8801},	/* mode 0xaa */
-	{0x0000, 0x8800},
-	{0x0004, 0x8805},
-	{0x0020, 0x8801},
-	{0x0015, 0x8800},	/* mode 0x0415 */
-	{0x0002, 0x8805},
-	{0x0039, 0x8801},
-	{0x0000, 0x8800},
-	{0x0010, 0x8805},
-	{0x0035, 0x8801},
-	{0x0000, 0x8800},
-	{0x0049, 0x8805},
-	{0x0009, 0x8801},
-	{0x0010, 0x8800},
-	{0x000b, 0x8805},
-	{0x0028, 0x8801},
-	{0x0000, 0x8800},
-	{0x000f, 0x8805},
-	{0x003b, 0x8801},
-	{0x0000, 0x8800},
-	{0x0000, 0x8805},
-	{0x003c, 0x8801},
-	{0x0000, 0x8800},
-	{0x0002, 0x8502},
-	{0x0039, 0x8801},
-	{0x0000, 0x8805},
-	{0x0000, 0x8800},
-
-	{0x0087, 0x8700},	/* overwrite by start */
-	{0x0081, 0x8702},
-	{0x0000, 0x8500},
-/*	{0x0010, 0x8500},  -- Previous line was this */
-	{0x0002, 0x865b},
-	{0x0003, 0x865c},
-	/***************/
-	{0x0003, 0x8801},	/* 0x121-> 289 */
-	{0x0021, 0x8805},
-	{0x0001, 0x8800},
-	{0x0004, 0x8801},	/* 0x165 -> 357 */
-	{0x0065, 0x8805},
-	{0x0001, 0x8800},
-	{0x0005, 0x8801},	/* 0x2f //blanking control colonne */
-	{0x002f, 0x8805},
-	{0x0000, 0x8800},
-	{0x0006, 0x8801},	/* 0x00 //blanking mode row */
-	{0x0000, 0x8805},
-	{0x0000, 0x8800},
-	{0x000a, 0x8801},	/* 0x01 //0x02 */
-	{0x0001, 0x8805},
-	{0x0000, 0x8800},
-	{0x0009, 0x8801},	/* 0x1061 - setexposure times && pixel clock
+static const u16 rev72a_init_sensor2[][2] = {
+	{0x0003, 0x0121},
+	{0x0004, 0x0165},
+	{0x0005, 0x002f},	/* blanking control column */
+	{0x0006, 0x0000},	/* blanking mode row*/
+	{0x000a, 0x0002},
+	{0x0009, 0x1061},	/* setexposure times && pixel clock
 				 * 0001 0 | 000 0110 0001 */
-	{0x0061, 0x8805},	/* 61 31 */
-	{0x0008, 0x8800},	/* 08 */
-	{0x0035, 0x8801},	/* 0x14 - set gain general */
-	{0x001f, 0x8805},	/* 0x14 */
-	{0x0000, 0x8800},
-	{0x000e, 0x8112},	/* white balance - was 30 */
+	{0x0035, 0x0014},
 	{}
 };
 
@@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *
 		reg_r(gspca_dev, 0x8803, 1);
 		if (!gspca_dev->usb_buf[0])
 			return;
+		msleep(10);
 	} while (--retry);
 }
 
@@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gs
 			reg_r(gspca_dev, 0x8805, 1);
 			return ((int) value << 8) | gspca_dev->usb_buf[0];
 		}
+		msleep(10);
 	} while (--retry);
 	return -1;
 }
@@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *g
 	}
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
 
 	sd->chip_revision = id->driver_info;
@@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev
 static int sd_init_72a(struct gspca_dev *gspca_dev)
 {
 	PDEBUG(D_STREAM, "Chip revision: 072a");
+	write_vector(gspca_dev, rev72a_reset);
+	msleep(200);
 	write_vector(gspca_dev, rev72a_init_data1);
 	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
 	write_vector(gspca_dev, rev72a_init_data2);
 	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
-	write_vector(gspca_dev, rev72a_init_data3);
+	reg_w_val(gspca_dev->dev, 0x8112, 0x30);
 	return 0;
 }
 
@@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev
 	int Clck;
 	int mode;
 
+	write_vector(gspca_dev, rev72a_reset);
+	msleep(200);
+	write_vector(gspca_dev, rev72a_init_data1);
+	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
+
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 	switch (mode) {
 	default:
-/*	case 0:
-	case 1: */
+	case 0:
+		Clck = 0x27;		/* ms-win 0x87 */
+		break;
+	case 1:
 		Clck = 0x25;
 		break;
 	case 2:
@@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev
 		Clck = 0x21;
 		break;
 	}
-	reg_w_val(dev, 0x8500, mode);	/* mode */
 	reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
-	reg_w_val(dev, 0x8112, 0x10 | 0x20);
+	reg_w_val(dev, 0x8702, 0x81);
+	reg_w_val(dev, 0x8500, mode);	/* mode */
+	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
 	setcontrast(gspca_dev);
 /*	setbrightness(gspca_dev);	 * fixme: bad values */
-	setwhite(gspca_dev);
 	setautogain(gspca_dev);
+	reg_w_val(dev, 0x8112, 0x10 | 0x20);
 	return 0;
 }
 
@@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (data[0]) {			/* sequence number */
+	len--;
+	switch (*data++) {			/* sequence number */
 	case 0:					/* start of frame */
 		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
 					data, 0);
-		data += SPCA561_OFFSET_DATA;
-		len -= SPCA561_OFFSET_DATA;
 		if (data[1] & 0x10) {
 			/* compressed bayer */
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev
 	case 0xff:			/* drop (empty mpackets) */
 		return;
 	}
-	data++;
-	len--;
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
@@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sq905.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sq905.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sq905.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sq905.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,462 @@
+/*
+ * SQ905 subdriver
+ *
+ * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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
+ */
+
+/*
+ * History and Acknowledgments
+ *
+ * The original Linux driver for SQ905 based cameras was written by
+ * Marcell Lengyel and furter developed by many other contributers
+ * and is available from http://sourceforge.net/projects/sqcam/
+ *
+ * This driver takes advantage of the reverse engineering work done for
+ * that driver and for libgphoto2 but shares no code with them.
+ *
+ * This driver has used as a base the finepix driver and other gspca
+ * based drivers and may still contain code fragments taken from those
+ * drivers.
+ */
+
+#define MODULE_NAME "sq905"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
+		"Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905_CMD_TIMEOUT 500
+#define SQ905_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905_MAX_TRANSFER 0x8000
+#define FRAME_HEADER_LEN 64
+
+/* The known modes, or registers. These go in the "value" slot. */
+
+/* 00 is "none" obviously */
+
+#define SQ905_BULK_READ	0x03	/* precedes any bulk read */
+#define SQ905_COMMAND	0x06	/* precedes the command codes below */
+#define SQ905_PING	0x07	/* when reading an "idling" command */
+#define SQ905_READ_DONE 0xc0    /* ack bulk read completed */
+
+/* Any non-zero value in the bottom 2 bits of the 2nd byte of
+ * the ID appears to indicate the camera can do 640*480. If the
+ * LSB of that byte is set the image is just upside down, otherwise
+ * it is rotated 180 degrees. */
+#define SQ905_HIRES_MASK	0x00000300
+#define SQ905_ORIENTATION_MASK	0x00000100
+
+/* Some command codes. These go in the "index" slot. */
+
+#define SQ905_ID      0xf0	/* asks for model string */
+#define SQ905_CONFIG  0x20	/* gets photo alloc. table, not used here */
+#define SQ905_DATA    0x30	/* accesses photo data, not used here */
+#define SQ905_CLEAR   0xa0	/* clear everything */
+#define SQ905_CAPTURE_LOW  0x60	/* Starts capture at 160x120 */
+#define SQ905_CAPTURE_MED  0x61	/* Starts capture at 320x240 */
+#define SQ905_CAPTURE_HIGH 0x62	/* Starts capture at 640x480 (some cams only) */
+/* note that the capture command also controls the output dimensions */
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+
+	/*
+	 * Driver stuff
+	 */
+	struct work_struct work_struct;
+	struct workqueue_struct *work_thread;
+};
+
+static struct v4l2_pix_format sq905_mode[] = {
+	{ 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 160,
+		.sizeimage = 160 * 120,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+	{ 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+	{ 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0}
+};
+
+/*
+ * Send a command to the camera.
+ */
+static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
+{
+	int ret;
+
+	gspca_dev->usb_buf[0] = '\0';
+	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_COMMAND, index, gspca_dev->usb_buf, 1,
+			      SQ905_CMD_TIMEOUT);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+			__func__, ret);
+		return ret;
+	}
+
+	ret = usb_control_msg(gspca_dev->dev,
+			      usb_sndctrlpipe(gspca_dev->dev, 0),
+			      USB_REQ_SYNCH_FRAME,                /* request */
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      SQ905_PING, 0, gspca_dev->usb_buf, 1,
+			      SQ905_CMD_TIMEOUT);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)",
+			__func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Acknowledge the end of a frame - see warning on sq905_command.
+ */
+static int sq905_ack_frame(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	gspca_dev->usb_buf[0] = '\0';
+	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_READ_DONE, 0, gspca_dev->usb_buf, 1,
+			      SQ905_CMD_TIMEOUT);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ *  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)
+{
+	int ret;
+	int act_len;
+
+	gspca_dev->usb_buf[0] = '\0';
+	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 (ret < 0) {
+		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+		return ret;
+	}
+	ret = usb_bulk_msg(gspca_dev->dev,
+			   usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+			   data, size, &act_len, SQ905_DATA_TIMEOUT);
+
+	/* successful, it returns 0, otherwise  negative */
+	if (ret < 0 || act_len != size) {
+		PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d",
+			ret, act_len, size);
+		return -EIO;
+	}
+	return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface we take the gspca
+ * usb_lock when performing USB operations. In practice the only thing we need
+ * to protect against is the usb_set_interface call that gspca makes during
+ * stream_off as the camera doesn't provide any controls that the user could try
+ * to change.
+ */
+static void sq905_dostream(struct work_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 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;
+	u8 *data;
+	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;
+	}
+
+	frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
+			+ 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) {
+			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);
+			if (ret < 0)
+				goto quit_stream;
+			mutex_unlock(&gspca_dev->usb_lock);
+			PDEBUG(D_STREAM,
+				"Got %d bytes out of %d for frame",
+				data_len, bytes_left);
+			bytes_left -= data_len;
+			data = buffer;
+			if (!header_read) {
+				packet_type = FIRST_PACKET;
+				/* The first 64 bytes of each frame are
+				 * a header full of FF 00 bytes */
+				data += FRAME_HEADER_LEN;
+				data_len -= FRAME_HEADER_LEN;
+				header_read = 1;
+			} else if (bytes_left == 0) {
+				packet_type = LAST_PACKET;
+			} 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;
+			}
+		}
+		/* 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)
+		sq905_command(gspca_dev, SQ905_CLEAR);
+	mutex_unlock(&gspca_dev->usb_lock);
+	kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+		const struct usb_device_id *id)
+{
+	struct cam *cam = &gspca_dev->cam;
+	struct sd *dev = (struct sd *) gspca_dev;
+
+	/* We don't use the buffer gspca allocates so make it small. */
+	cam->bulk_size = 64;
+
+	INIT_WORK(&dev->work_struct, sq905_dostream);
+
+	return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+
+	/* wait for the work queue to terminate */
+	mutex_unlock(&gspca_dev->usb_lock);
+	/* This waits for sq905_dostream to finish */
+	destroy_workqueue(dev->work_thread);
+	dev->work_thread = NULL;
+	mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	u32 ident;
+	int ret;
+
+	/* connect to the camera and read
+	 * the model ID and process that and put it away.
+	 */
+	ret = sq905_command(gspca_dev, SQ905_CLEAR);
+	if (ret < 0)
+		return ret;
+	ret = sq905_command(gspca_dev, SQ905_ID);
+	if (ret < 0)
+		return ret;
+	ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+	if (ret < 0)
+		return ret;
+	/* usb_buf is allocated with kmalloc so is aligned.
+	 * Camera model number is the right way round if we assume this
+	 * reverse engineered ID is supposed to be big endian. */
+	ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf);
+	ret = sq905_command(gspca_dev, SQ905_CLEAR);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+	gspca_dev->cam.cam_mode = sq905_mode;
+	gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
+	if (!(ident & SQ905_HIRES_MASK))
+		gspca_dev->cam.nmodes--;
+
+	if (ident & SQ905_ORIENTATION_MASK)
+		gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP;
+	else
+		gspca_dev->cam.input_flags = V4L2_IN_ST_VFLIP |
+					     V4L2_IN_ST_HFLIP;
+	return 0;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+	int ret;
+
+	/* "Open the shutter" and set size, to start capture */
+	switch (gspca_dev->curr_mode) {
+	default:
+/*	case 2: */
+		PDEBUG(D_STREAM, "Start streaming at high resolution");
+		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
+		break;
+	case 1:
+		PDEBUG(D_STREAM, "Start streaming at medium resolution");
+		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
+		break;
+	case 0:
+		PDEBUG(D_STREAM, "Start streaming at low resolution");
+		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
+	}
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Start streaming command failed");
+		return ret;
+	}
+	/* Start the workqueue function to do the streaming */
+	dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+	queue_work(dev->work_thread, &dev->work_struct);
+
+	return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x2770, 0x9120)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name   = MODULE_NAME,
+	.config = sd_config,
+	.init   = sd_init,
+	.start  = sd_start,
+	.stop0  = sd_stop0,
+};
+
+/* -- 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.29-gnu1/drivers/media/video/gspca/sq905c.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sq905c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sq905c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sq905c.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,328 @@
+/*
+ * SQ905C subdriver
+ *
+ * Copyright (C) 2009 Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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
+ */
+
+/*
+ *
+ * This driver uses work done in
+ * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore.
+ *
+ * This driver has also used as a base the sq905c driver
+ * and may contain code fragments from it.
+ */
+
+#define MODULE_NAME "sq905c"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905C_CMD_TIMEOUT 500
+#define SQ905C_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905C_MAX_TRANSFER 0x8000
+
+#define FRAME_HEADER_LEN 0x50
+
+/* Commands. These go in the "value" slot. */
+#define SQ905C_CLEAR   0xa0		/* clear everything */
+#define SQ905C_CAPTURE_LOW 0xa040	/* Starts capture at 160x120 */
+#define SQ905C_CAPTURE_MED 0x1440	/* Starts capture at 320x240 */
+#define SQ905C_CAPTURE_HI 0x2840	/* Starts capture at 320x240 */
+
+/* For capture, this must go in the "index" slot. */
+#define SQ905C_CAPTURE_INDEX 0x110f
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+	const struct v4l2_pix_format *cap_mode;
+	/* Driver stuff */
+	struct work_struct work_struct;
+	struct workqueue_struct *work_thread;
+};
+
+/*
+ * Most of these cameras will do 640x480 and 320x240. 160x120 works
+ * in theory but gives very poor output. Therefore, not supported.
+ * The 0x2770:0x9050 cameras have max resolution of 320x240.
+ */
+static struct v4l2_pix_format sq905c_mode[] = {
+	{ 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
+	{ 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0}
+};
+
+/* Send a command to the camera. */
+static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
+{
+	int ret;
+
+	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,
+			      command, index, NULL, 0,
+			      SQ905C_CMD_TIMEOUT);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+			__func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface the gspca usb_lock is
+ * used when performing the one USB control operation inside the workqueue,
+ * which tells the camera to close the stream. In practice the only thing
+ * which needs to be protected against is the usb_set_interface call that
+ * gspca makes during stream_off. Otherwise the camera doesn't provide any
+ * controls that the user could try to change.
+ */
+static void sq905c_dostream(struct work_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;
+
+	buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+	if (!buffer) {
+		PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+		goto quit_stream;
+	}
+
+	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),
+				buffer, FRAME_HEADER_LEN, &act_len,
+				SQ905C_DATA_TIMEOUT);
+		PDEBUG(D_STREAM,
+			"Got %d bytes out of %d for header",
+			act_len, FRAME_HEADER_LEN);
+		if (ret < 0 || act_len < FRAME_HEADER_LEN)
+			goto quit_stream;
+		/* size is read from 4 bytes starting 0x40, little endian */
+		bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
+					|(buffer[0x43]<<24);
+		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) {
+			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,
+				SQ905C_DATA_TIMEOUT);
+			if (ret < 0 || act_len < data_len)
+				goto quit_stream;
+			PDEBUG(D_STREAM,
+				"Got %d bytes out of %d for frame",
+				data_len, bytes_left);
+			bytes_left -= data_len;
+			if (bytes_left == 0)
+				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;
+		}
+	}
+quit_stream:
+	mutex_lock(&gspca_dev->usb_lock);
+	if (gspca_dev->present)
+		sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+	mutex_unlock(&gspca_dev->usb_lock);
+	kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+		const struct usb_device_id *id)
+{
+	struct cam *cam = &gspca_dev->cam;
+	struct sd *dev = (struct sd *) gspca_dev;
+
+	PDEBUG(D_PROBE,
+		"SQ9050 camera detected"
+		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+	cam->cam_mode = sq905c_mode;
+	cam->nmodes = 2;
+	if (id->idProduct == 0x9050)
+		cam->nmodes = 1;
+	/* We don't use the buffer gspca allocates so make it small. */
+	cam->bulk_size = 32;
+	INIT_WORK(&dev->work_struct, sq905c_dostream);
+	return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+
+	/* wait for the work queue to terminate */
+	mutex_unlock(&gspca_dev->usb_lock);
+	/* This waits for sq905c_dostream to finish */
+	destroy_workqueue(dev->work_thread);
+	dev->work_thread = NULL;
+	mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	int ret;
+
+	/* connect to the camera and reset it. */
+	ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+	return ret;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+	int ret;
+
+	dev->cap_mode = gspca_dev->cam.cam_mode;
+	/* "Open the shutter" and set size, to start capture */
+	switch (gspca_dev->width) {
+	case 640:
+		PDEBUG(D_STREAM, "Start streaming at high resolution");
+		dev->cap_mode++;
+		ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
+						SQ905C_CAPTURE_INDEX);
+		break;
+	default: /* 320 */
+	PDEBUG(D_STREAM, "Start streaming at medium resolution");
+		ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
+						SQ905C_CAPTURE_INDEX);
+	}
+
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Start streaming command failed");
+		return ret;
+	}
+	/* Start the workqueue function to do the streaming */
+	dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+	queue_work(dev->work_thread, &dev->work_struct);
+
+	return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x2770, 0x905c)},
+	{USB_DEVICE(0x2770, 0x9050)},
+	{USB_DEVICE(0x2770, 0x913d)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name   = MODULE_NAME,
+	.config = sd_config,
+	.init   = sd_init,
+	.start  = sd_start,
+	.stop0  = sd_stop0,
+};
+
+/* -- 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.29-gnu1/drivers/media/video/gspca/stk014.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stk014.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stk014.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stk014.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,10 +35,13 @@ struct sd {
 	unsigned char contrast;
 	unsigned char colors;
 	unsigned char lightfreq;
-};
+	u8 quality;
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
 
-/* global parameters */
-static int sd_quant = 7;		/* <= 4 KO - 7: good (enough!) */
+	u8 *jpeg_hdr;
+};
 
 /* V4L2 controls supported by the driver */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -180,7 +183,7 @@ static int rcv_val(struct gspca_dev *gsp
 	reg_w(gspca_dev, 0x63b, 0);
 	reg_w(gspca_dev, 0x630, 5);
 	ret = usb_bulk_msg(dev,
-			usb_rcvbulkpipe(dev, 5),
+			usb_rcvbulkpipe(dev, 0x05),
 			gspca_dev->usb_buf,
 			4,		/* length */
 			&alen,
@@ -294,15 +297,14 @@ static int sd_config(struct gspca_dev *g
 			const struct usb_device_id *id)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct cam *cam = &gspca_dev->cam;
 
-	cam->epaddr = 0x02;
 	gspca_dev->cam.cam_mode = vga_mode;
 	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
 	sd->colors = COLOR_DEF;
 	sd->lightfreq = FREQ_DEF;
+	sd->quality = QUALITY_DEF;
 	return 0;
 }
 
@@ -326,8 +328,15 @@ static int sd_init(struct gspca_dev *gsp
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	int ret, value;
 
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x22);		/* JPEG 411 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	/* work on alternate 1 */
 	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 
@@ -399,11 +408,19 @@ static void sd_stopN(struct gspca_dev *g
 	PDEBUG(D_STREAM, "camera stopped");
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	kfree(sd->jpeg_hdr);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	static unsigned char ffd9[] = {0xff, 0xd9};
 
 	/* a frame starts with:
@@ -420,7 +437,8 @@ static void sd_pkt_scan(struct gspca_dev
 					ffd9, 2);
 
 		/* put the JPEG 411 header */
-		jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
 
 		/* beginning of the frame */
 #define STKHDRSZ 12
@@ -520,6 +538,34 @@ static int sd_querymenu(struct gspca_dev
 	return -EINVAL;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -529,8 +575,11 @@ 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 -- */
@@ -562,8 +611,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	info("registered");
 	return 0;
 }
@@ -575,6 +626,3 @@ static void __exit sd_mod_exit(void)
 
 module_init(sd_mod_init);
 module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_d
 	PDEBUG(D_PROBE, "Configuring camera");
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
 	sd->desc = sd_desc;
 	gspca_dev->sd_desc = &sd->desc;
 
@@ -501,8 +500,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,66 @@
 
 #include "stv06xx_hdcs.h"
 
+static const struct ctrl hdcs1x00_ctrl[] = {
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "exposure",
+			.minimum	= 0x00,
+			.maximum	= 0xffff,
+			.step		= 0x1,
+			.default_value 	= HDCS_DEFAULT_EXPOSURE,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = hdcs_set_exposure,
+		.get = hdcs_get_exposure
+	}, {
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "gain",
+			.minimum	= 0x00,
+			.maximum	= 0xff,
+			.step		= 0x1,
+			.default_value 	= HDCS_DEFAULT_GAIN,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = hdcs_set_gain,
+		.get = hdcs_get_gain
+	}
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+	{
+		HDCS_1X00_DEF_WIDTH,
+		HDCS_1X00_DEF_HEIGHT,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+		.bytesperline = HDCS_1X00_DEF_WIDTH,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	}
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+	{
+		HDCS_1020_DEF_WIDTH,
+		HDCS_1020_DEF_HEIGHT,
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_FIELD_NONE,
+		.sizeimage =
+			HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+		.bytesperline = HDCS_1020_DEF_WIDTH,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	}
+};
+
 enum hdcs_power_state {
 	HDCS_STATE_SLEEP,
 	HDCS_STATE_IDLE,
@@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd
 
 	info("HDCS-1000/1100 sensor detected");
 
-	sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
-	sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
-	sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
-	sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+	sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+	sd->desc.ctrls = hdcs1x00_ctrl;
+	sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
 
 	hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
 	if (!hdcs)
@@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd
 
 	info("HDCS-1020 sensor detected");
 
-	sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
-	sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
-	sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
-	sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+	sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+	sd->desc.ctrls = hdcs1020_ctrl;
+	sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
 
 	hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
 	if (!hdcs)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h	2009-06-09 23:05:27.000000000 -0400
@@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sens
 	.stop = hdcs_stop,
 	.disconnect = hdcs_disconnect,
 	.dump = hdcs_dump,
-
-	.nctrls = 2,
-	.ctrls = {
-	{
-		{
-			.id		= V4L2_CID_EXPOSURE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "exposure",
-			.minimum	= 0x00,
-			.maximum	= 0xffff,
-			.step		= 0x1,
-			.default_value 	= HDCS_DEFAULT_EXPOSURE,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = hdcs_set_exposure,
-		.get = hdcs_get_exposure
-	},
-	{
-		{
-			.id		= V4L2_CID_GAIN,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "gain",
-			.minimum	= 0x00,
-			.maximum	= 0xff,
-			.step		= 0x1,
-			.default_value 	= HDCS_DEFAULT_GAIN,
-			.flags         	= V4L2_CTRL_FLAG_SLIDER
-		},
-		.set = hdcs_set_gain,
-		.get = hdcs_get_gain
-	}
-	},
-
-	.nmodes = 1,
-	.modes = {
-	{
-		HDCS_1X00_DEF_WIDTH,
-		HDCS_1X00_DEF_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
-		.bytesperline = HDCS_1X00_DEF_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
 };
 
 const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
@@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sens
 	.i2c_addr = (0x55 << 1),
 	.i2c_len = 1,
 
-	.nctrls = 0,
-	.ctrls = {},
-
 	.init = hdcs_init,
 	.probe = hdcs_probe_1020,
 	.start = hdcs_start,
 	.stop = hdcs_stop,
 	.dump = hdcs_dump,
-
-	.nmodes = 1,
-	.modes = {
-	{
-		HDCS_1020_DEF_WIDTH,
-		HDCS_1020_DEF_HEIGHT,
-		V4L2_PIX_FMT_SBGGR8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
-		.bytesperline = HDCS_1020_DEF_WIDTH,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 1
-	}
-	}
 };
 
 static const u16 stv_bridge_init[][2] = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,132 @@
 
 #include "stv06xx_pb0100.h"
 
+static const struct ctrl pb0100_ctrl[] = {
+#define GAIN_IDX 0
+	{
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Gain",
+			.minimum	= 0,
+			.maximum	= 255,
+			.step		= 1,
+			.default_value  = 128
+		},
+		.set = pb0100_set_gain,
+		.get = pb0100_get_gain
+	},
+#define RED_BALANCE_IDX 1
+	{
+		{
+			.id		= V4L2_CID_RED_BALANCE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Red Balance",
+			.minimum	= -255,
+			.maximum	= 255,
+			.step		= 1,
+			.default_value  = 0
+		},
+		.set = pb0100_set_red_balance,
+		.get = pb0100_get_red_balance
+	},
+#define BLUE_BALANCE_IDX 2
+	{
+		{
+			.id		= V4L2_CID_BLUE_BALANCE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Blue Balance",
+			.minimum	= -255,
+			.maximum	= 255,
+			.step		= 1,
+			.default_value  = 0
+		},
+		.set = pb0100_set_blue_balance,
+		.get = pb0100_get_blue_balance
+	},
+#define EXPOSURE_IDX 3
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Exposure",
+			.minimum	= 0,
+			.maximum	= 511,
+			.step		= 1,
+			.default_value  = 12
+		},
+		.set = pb0100_set_exposure,
+		.get = pb0100_get_exposure
+	},
+#define AUTOGAIN_IDX 4
+	{
+		{
+			.id		= V4L2_CID_AUTOGAIN,
+			.type		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name		= "Automatic Gain and Exposure",
+			.minimum	= 0,
+			.maximum	= 1,
+			.step		= 1,
+			.default_value  = 1
+		},
+		.set = pb0100_set_autogain,
+		.get = pb0100_get_autogain
+	},
+#define AUTOGAIN_TARGET_IDX 5
+	{
+		{
+			.id		= V4L2_CTRL_CLASS_USER + 0x1000,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "Automatic Gain Target",
+			.minimum	= 0,
+			.maximum	= 255,
+			.step		= 1,
+			.default_value  = 128
+		},
+		.set = pb0100_set_autogain_target,
+		.get = pb0100_get_autogain_target
+	},
+#define NATURAL_IDX 6
+	{
+		{
+			.id		= V4L2_CTRL_CLASS_USER + 0x1001,
+			.type		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name		= "Natural Light Source",
+			.minimum	= 0,
+			.maximum	= 1,
+			.step		= 1,
+			.default_value  = 1
+		},
+		.set = pb0100_set_natural,
+		.get = pb0100_get_natural
+	}
+};
+
+static struct v4l2_pix_format pb0100_mode[] = {
+/* low res / subsample modes disabled as they are only half res horizontal,
+   halving the vertical resolution does not seem to work */
+	{
+		320,
+		240,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 320 * 240,
+		.bytesperline = 320,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = PB0100_CROP_TO_VGA
+	},
+	{
+		352,
+		288,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 352 * 288,
+		.bytesperline = 352,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
 static int pb0100_probe(struct sd *sd)
 {
 	u16 sensor;
@@ -59,20 +185,19 @@ static int pb0100_probe(struct sd *sd)
 
 	if ((sensor >> 8) == 0x64) {
 		sensor_settings = kmalloc(
-				stv06xx_sensor_pb0100.nctrls * sizeof(s32),
+				ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
 				GFP_KERNEL);
 		if (!sensor_settings)
 			return -ENOMEM;
 
 		info("Photobit pb0100 sensor detected");
 
-		sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
-		sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
-		sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
-		sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
-		for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
-			sensor_settings[i] = stv06xx_sensor_pb0100.
-					     ctrls[i].qctrl.default_value;
+		sd->gspca_dev.cam.cam_mode = pb0100_mode;
+		sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
+		sd->desc.ctrls = pb0100_ctrl;
+		sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
+		for (i = 0; i < sd->desc.nctrls; i++)
+			sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
 		sd->sensor_priv = sensor_settings;
 
 		return 0;
@@ -143,6 +268,12 @@ out:
 	return (err < 0) ? err : 0;
 }
 
+static void pb0100_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
 /* FIXME: Sort the init commands out and put them into tables,
 	  this is only for getting the camera to work */
 /* FIXME: No error handling for now,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h	2009-06-09 23:05:27.000000000 -0400
@@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd);
 static int pb0100_init(struct sd *sd);
 static int pb0100_stop(struct sd *sd);
 static int pb0100_dump(struct sd *sd);
+static void pb0100_disconnect(struct sd *sd);
 
 /* V4L2 controls supported by the driver */
 static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -137,139 +138,12 @@ const struct stv06xx_sensor stv06xx_sens
 	.i2c_addr = 0xba,
 	.i2c_len = 2,
 
-	.nctrls = 7,
-	.ctrls = {
-#define GAIN_IDX 0
-	{
-		{
-			.id		= V4L2_CID_GAIN,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Gain",
-			.minimum	= 0,
-			.maximum	= 255,
-			.step		= 1,
-			.default_value  = 128
-		},
-		.set = pb0100_set_gain,
-		.get = pb0100_get_gain
-	},
-#define RED_BALANCE_IDX 1
-	{
-		{
-			.id		= V4L2_CID_RED_BALANCE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Red Balance",
-			.minimum	= -255,
-			.maximum	= 255,
-			.step		= 1,
-			.default_value  = 0
-		},
-		.set = pb0100_set_red_balance,
-		.get = pb0100_get_red_balance
-	},
-#define BLUE_BALANCE_IDX 2
-	{
-		{
-			.id		= V4L2_CID_BLUE_BALANCE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Blue Balance",
-			.minimum	= -255,
-			.maximum	= 255,
-			.step		= 1,
-			.default_value  = 0
-		},
-		.set = pb0100_set_blue_balance,
-		.get = pb0100_get_blue_balance
-	},
-#define EXPOSURE_IDX 3
-	{
-		{
-			.id		= V4L2_CID_EXPOSURE,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Exposure",
-			.minimum	= 0,
-			.maximum	= 511,
-			.step		= 1,
-			.default_value  = 12
-		},
-		.set = pb0100_set_exposure,
-		.get = pb0100_get_exposure
-	},
-#define AUTOGAIN_IDX 4
-	{
-		{
-			.id		= V4L2_CID_AUTOGAIN,
-			.type		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name		= "Automatic Gain and Exposure",
-			.minimum	= 0,
-			.maximum	= 1,
-			.step		= 1,
-			.default_value  = 1
-		},
-		.set = pb0100_set_autogain,
-		.get = pb0100_get_autogain
-	},
-#define AUTOGAIN_TARGET_IDX 5
-	{
-		{
-			.id		= V4L2_CTRL_CLASS_USER + 0x1000,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "Automatic Gain Target",
-			.minimum	= 0,
-			.maximum	= 255,
-			.step		= 1,
-			.default_value  = 128
-		},
-		.set = pb0100_set_autogain_target,
-		.get = pb0100_get_autogain_target
-	},
-#define NATURAL_IDX 6
-	{
-		{
-			.id		= V4L2_CTRL_CLASS_USER + 0x1001,
-			.type		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name		= "Natural Light Source",
-			.minimum	= 0,
-			.maximum	= 1,
-			.step		= 1,
-			.default_value  = 1
-		},
-		.set = pb0100_set_natural,
-		.get = pb0100_get_natural
-	},
-	},
-
 	.init = pb0100_init,
 	.probe = pb0100_probe,
 	.start = pb0100_start,
 	.stop = pb0100_stop,
 	.dump = pb0100_dump,
-
-	.nmodes = 2,
-	.modes = {
-/* low res / subsample modes disabled as they are only half res horizontal,
-   halving the vertical resolution does not seem to work */
-	{
-		320,
-		240,
-		V4L2_PIX_FMT_SGRBG8,
-		V4L2_FIELD_NONE,
-		.sizeimage = 320 * 240,
-		.bytesperline = 320,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = PB0100_CROP_TO_VGA
-	},
-	{
-		352,
-		288,
-		V4L2_PIX_FMT_SGRBG8,
-		V4L2_FIELD_NONE,
-		.sizeimage = 352 * 288,
-		.bytesperline = 352,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	},
-	}
+	.disconnect = pb0100_disconnect,
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06
 extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
 extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
 
-#define STV06XX_MAX_CTRLS		(V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
 struct stv06xx_sensor {
 	/* Defines the name of a sensor */
 	char name[32];
@@ -81,12 +79,6 @@ struct stv06xx_sensor {
 
 	/* Instructs the sensor to dump all its contents */
 	int (*dump)(struct sd *sd);
-
-	int nctrls;
-	struct ctrl ctrls[STV06XX_MAX_CTRLS];
-
-	char nmodes;
-	struct v4l2_pix_format modes[];
 };
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,26 +29,92 @@
 
 #include "stv06xx_vv6410.h"
 
+static struct v4l2_pix_format vv6410_mode[] = {
+	{
+		356,
+		292,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_FIELD_NONE,
+		.sizeimage = 356 * 292,
+		.bytesperline = 356,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	}
+};
+
+static const struct ctrl vv6410_ctrl[] = {
+#define HFLIP_IDX 0
+	{
+		{
+			.id		= V4L2_CID_HFLIP,
+			.type		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name		= "horizontal flip",
+			.minimum	= 0,
+			.maximum	= 1,
+			.step		= 1,
+			.default_value	= 0
+		},
+		.set = vv6410_set_hflip,
+		.get = vv6410_get_hflip
+	},
+#define VFLIP_IDX 1
+	{
+		{
+			.id		= V4L2_CID_VFLIP,
+			.type		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name		= "vertical flip",
+			.minimum	= 0,
+			.maximum	= 1,
+			.step		= 1,
+			.default_value 	= 0
+		},
+		.set = vv6410_set_vflip,
+		.get = vv6410_get_vflip
+	},
+#define GAIN_IDX 2
+	{
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "analog gain",
+			.minimum	= 0,
+			.maximum	= 15,
+			.step		= 1,
+			.default_value  = 0
+		},
+		.set = vv6410_set_analog_gain,
+		.get = vv6410_get_analog_gain
+	}
+};
+
 static int vv6410_probe(struct sd *sd)
 {
 	u16 data;
-	int err;
+	int err, i;
+	s32 *sensor_settings;
 
 	err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
-
 	if (err < 0)
 		return -ENODEV;
 
 	if (data == 0x19) {
 		info("vv6410 sensor detected");
 
-		sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
-		sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
-		sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
-		sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
+		sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32),
+					  GFP_KERNEL);
+		if (!sensor_settings)
+			return -ENOMEM;
+
+		sd->gspca_dev.cam.cam_mode = vv6410_mode;
+		sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
+		sd->desc.ctrls = vv6410_ctrl;
+		sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl);
+
+		for (i = 0; i < sd->desc.nctrls; i++)
+			sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value;
+		sd->sensor_priv = sensor_settings;
 		return 0;
 	}
-
 	return -ENODEV;
 }
 
@@ -80,6 +146,12 @@ static int vv6410_init(struct sd *sd)
 	return (err < 0) ? err : 0;
 }
 
+static void vv6410_disconnect(struct sd *sd)
+{
+	sd->sensor = NULL;
+	kfree(sd->sensor_priv);
+}
+
 static int vv6410_start(struct sd *sd)
 {
 	int err;
@@ -156,17 +228,13 @@ static int vv6410_dump(struct sd *sd)
 
 static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u16 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
-	*val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
-
+	*val = sensor_settings[HFLIP_IDX];
 	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
-	return (err < 0) ? err : 0;
+	return 0;
 }
 
 static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,6 +242,9 @@ static int vv6410_set_hflip(struct gspca
 	int err;
 	u16 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[HFLIP_IDX] = val;
 	err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
 	if (err < 0)
 		return err;
@@ -191,17 +262,13 @@ static int vv6410_set_hflip(struct gspca
 
 static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u16 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
-	*val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
-
+	*val = sensor_settings[VFLIP_IDX];
 	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
-	return (err < 0) ? err : 0;
+	return 0;
 }
 
 static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -209,6 +276,9 @@ static int vv6410_set_vflip(struct gspca
 	int err;
 	u16 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	sensor_settings[VFLIP_IDX] = val;
 	err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
 	if (err < 0)
 		return err;
@@ -226,24 +296,23 @@ static int vv6410_set_vflip(struct gspca
 
 static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
-	int err;
-	u16 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
-	err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
-
-	*val = i2c_data & 0xf;
+	*val = sensor_settings[GAIN_IDX];
 
 	PDEBUG(D_V4L2, "Read analog gain %d", *val);
 
-	return (err < 0) ? err : 0;
+	return 0;
 }
 
 static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	int err;
 	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
 
+	sensor_settings[GAIN_IDX] = val;
 	PDEBUG(D_V4L2, "Set analog gain to %d", val);
 	err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h	2009-06-09 23:05:27.000000000 -0400
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd);
 static int vv6410_init(struct sd *sd);
 static int vv6410_stop(struct sd *sd);
 static int vv6410_dump(struct sd *sd);
+static void vv6410_disconnect(struct sd *sd);
 
 /* V4L2 controls supported by the driver */
 static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -197,62 +198,7 @@ const struct stv06xx_sensor stv06xx_sens
 	.start = vv6410_start,
 	.stop = vv6410_stop,
 	.dump = vv6410_dump,
-
-	.nctrls = 3,
-	.ctrls = {
-	{
-		{
-			.id		= V4L2_CID_HFLIP,
-			.type		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name		= "horizontal flip",
-			.minimum	= 0,
-			.maximum	= 1,
-			.step		= 1,
-			.default_value	= 0
-		},
-		.set = vv6410_set_hflip,
-		.get = vv6410_get_hflip
-	}, {
-		{
-			.id		= V4L2_CID_VFLIP,
-			.type		= V4L2_CTRL_TYPE_BOOLEAN,
-			.name		= "vertical flip",
-			.minimum	= 0,
-			.maximum	= 1,
-			.step		= 1,
-			.default_value 	= 0
-		},
-		.set = vv6410_set_vflip,
-		.get = vv6410_get_vflip
-	}, {
-		{
-			.id		= V4L2_CID_GAIN,
-			.type		= V4L2_CTRL_TYPE_INTEGER,
-			.name		= "analog gain",
-			.minimum	= 0,
-			.maximum	= 15,
-			.step		= 1,
-			.default_value  = 0
-		},
-		.set = vv6410_set_analog_gain,
-		.get = vv6410_get_analog_gain
-	}
-	},
-
-	.nmodes = 1,
-	.modes = {
-	{
-		356,
-		292,
-		V4L2_PIX_FMT_SGRBG8,
-		V4L2_FIELD_NONE,
-		.sizeimage =
-			356 * 292,
-		.bytesperline = 356,
-		.colorspace = V4L2_COLORSPACE_SRGB,
-		.priv = 0
-	}
-	}
+	.disconnect = vv6410_disconnect,
 };
 
 /* If NULL, only single value to write, stored in len */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sunplus.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sunplus.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/sunplus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/sunplus.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,8 +39,11 @@ struct sd {
 	unsigned char contrast;
 	unsigned char colors;
 	unsigned char autogain;
+	u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
 
-	char qindex;
 	char bridge;
 #define BRIDGE_SPCA504 0
 #define BRIDGE_SPCA504B 1
@@ -52,6 +55,8 @@ struct sd {
 #define LogitechClickSmart420 2
 #define LogitechClickSmart820 3
 #define MegapixV4 4
+
+	u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -812,7 +817,6 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 
 	sd->bridge = id->driver_info >> 8;
 	sd->subtype = id->driver_info;
@@ -850,10 +854,10 @@ static int sd_config(struct gspca_dev *g
 		cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
 		break;
 	}
-	sd->qindex = 5;			/* set the quantization table */
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+	sd->quality = QUALITY_DEF;
 	return 0;
 }
 
@@ -970,6 +974,12 @@ static int sd_start(struct gspca_dev *gs
 	__u8 i;
 	__u8 info[6];
 
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x22);		/* JPEG 411 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	if (sd->bridge == BRIDGE_SPCA504B)
 		spca504B_setQtable(gspca_dev);
 	spca504B_SetSizeType(gspca_dev);
@@ -1079,6 +1089,13 @@ static void sd_stopN(struct gspca_dev *g
 	}
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	kfree(sd->jpeg_hdr);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1155,9 +1172,8 @@ static void sd_pkt_scan(struct gspca_dev
 					ffd9, 2);
 
 		/* put the JPEG header in the new frame */
-		jpeg_put_header(gspca_dev, frame,
-				((struct sd *) gspca_dev)->qindex,
-				0x22);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
 	}
 
 	/* add 0x00 after 0xff */
@@ -1198,26 +1214,6 @@ static void setbrightness(struct gspca_d
 	}
 }
 
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	__u16 brightness = 0;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
-		break;
-	case BRIDGE_SPCA536:
-		brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
-		break;
-	}
-	sd->brightness = ((brightness & 0xff) - 128) % 255;
-}
-
 static void setcontrast(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1237,24 +1233,6 @@ static void setcontrast(struct gspca_dev
 	}
 }
 
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
-		break;
-	case BRIDGE_SPCA536:
-		sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
-		break;
-	}
-}
-
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1274,24 +1252,6 @@ static void setcolors(struct gspca_dev *
 	}
 }
 
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
-		break;
-	case BRIDGE_SPCA536:
-		sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
-		break;
-	}
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1306,7 +1266,6 @@ static int sd_getbrightness(struct gspca
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getbrightness(gspca_dev);
 	*val = sd->brightness;
 	return 0;
 }
@@ -1325,7 +1284,6 @@ static int sd_getcontrast(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcontrast(gspca_dev);
 	*val = sd->contrast;
 	return 0;
 }
@@ -1344,7 +1302,6 @@ static int sd_getcolors(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	getcolors(gspca_dev);
 	*val = sd->colors;
 	return 0;
 }
@@ -1365,6 +1322,34 @@ static int sd_getautogain(struct gspca_d
 	return 0;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -1374,7 +1359,10 @@ static const struct sd_desc sd_desc = {
 	.init = sd_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
+	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -1465,8 +1453,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/t613.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/t613.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/t613.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/t613.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,20 +37,21 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	unsigned char brightness;
-	unsigned char contrast;
-	unsigned char colors;
-	unsigned char autogain;
-	unsigned char gamma;
-	unsigned char sharpness;
-	unsigned char freq;
-	unsigned char whitebalance;
-	unsigned char mirror;
-	unsigned char effect;
+	u8 brightness;
+	u8 contrast;
+	u8 colors;
+	u8 autogain;
+	u8 gamma;
+	u8 sharpness;
+	u8 freq;
+	u8 whitebalance;
+	u8 mirror;
+	u8 effect;
 
-	__u8 sensor;
-#define SENSOR_TAS5130A 0
-#define SENSOR_OM6802 1
+	u8 sensor;
+#define SENSOR_OM6802 0
+#define SENSOR_OTHER 1
+#define SENSOR_TAS5130A 2
 };
 
 /* V4L2 controls supported by the driver */
@@ -78,7 +79,6 @@ static int sd_querymenu(struct gspca_dev
 			struct v4l2_querymenu *menu);
 
 static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
 	{
 	 {
 	  .id = V4L2_CID_BRIGHTNESS,
@@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 14,
 	  .step = 1,
-	  .default_value = 8,
+#define BRIGHTNESS_DEF 8
+	  .default_value = BRIGHTNESS_DEF,
 	  },
 	 .set = sd_setbrightness,
 	 .get = sd_getbrightness,
 	 },
-#define SD_CONTRAST 1
 	{
 	 {
 	  .id = V4L2_CID_CONTRAST,
@@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 0x0d,
 	  .step = 1,
-	  .default_value = 0x07,
+#define CONTRAST_DEF 0x07
+	  .default_value = CONTRAST_DEF,
 	  },
 	 .set = sd_setcontrast,
 	 .get = sd_getcontrast,
 	 },
-#define SD_COLOR 2
 	{
 	 {
 	  .id = V4L2_CID_SATURATION,
@@ -115,7 +115,8 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 0x0f,
 	  .step = 1,
-	  .default_value = 0x05,
+#define COLORS_DEF 0x05
+	  .default_value = COLORS_DEF,
 	  },
 	 .set = sd_setcolors,
 	 .get = sd_getcolors,
@@ -135,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
 	 .set = sd_setgamma,
 	 .get = sd_getgamma,
 	 },
-#define SD_AUTOGAIN 4
 	{
 	 {
 	  .id = V4L2_CID_GAIN,	/* here, i activate only the lowlight,
@@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 1,
 	  .step = 1,
-	  .default_value = 0x01,
+#define AUTOGAIN_DEF 0x01
+	  .default_value = AUTOGAIN_DEF,
 	  },
 	 .set = sd_setlowlight,
 	 .get = sd_getlowlight,
 	 },
-#define SD_MIRROR 5
 	{
 	 {
 	  .id = V4L2_CID_HFLIP,
@@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 1,
 	  .step = 1,
-	  .default_value = 0,
+#define MIRROR_DEF 0
+	  .default_value = MIRROR_DEF,
 	  },
 	 .set = sd_setflip,
 	 .get = sd_getflip
 	},
-#define SD_LIGHTFREQ 6
 	{
 	 {
 	  .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 1,		/* 1 -> 0x50, 2->0x60 */
 	  .maximum = 2,
 	  .step = 1,
-	  .default_value = 1,
+#define FREQ_DEF 1
+	  .default_value = FREQ_DEF,
 	  },
 	 .set = sd_setfreq,
 	 .get = sd_getfreq},
 
-#define SD_WHITE_BALANCE 7
 	{
 	 {
 	  .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 1,
 	  .step = 1,
-	  .default_value = 0,
+#define WHITE_BALANCE_DEF 0
+	  .default_value = WHITE_BALANCE_DEF,
 	  },
 	 .set = sd_setwhitebalance,
 	 .get = sd_getwhitebalance
 	},
-#define SD_SHARPNESS 8		/* (aka definition on win) */
 	{
 	 {
 	  .id = V4L2_CID_SHARPNESS,
@@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 15,
 	  .step = 1,
-	  .default_value = 0x06,
+#define SHARPNESS_DEF 0x06
+	  .default_value = SHARPNESS_DEF,
 	  },
 	 .set = sd_setsharpness,
 	 .get = sd_getsharpness,
 	 },
-#define SD_EFFECTS 9
 	{
 	 {
 	  .id = V4L2_CID_EFFECTS,
@@ -216,7 +216,8 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 4,
 	  .step = 1,
-	  .default_value = 0,
+#define EFFECTS_DEF 0
+	  .default_value = EFFECTS_DEF,
 	  },
 	 .set = sd_seteffect,
 	 .get = sd_geteffect
@@ -263,28 +264,50 @@ static const struct v4l2_pix_format vga_
 
 /* sensor specific data */
 struct additional_sensor_data {
-	const __u8 data1[20];
-	const __u8 data2[18];
-	const __u8 data3[18];
-	const __u8 data4[4];
-	const __u8 data5[6];
-	const __u8 stream[4];
+	const u8 data1[10];
+	const u8 data2[9];
+	const u8 data3[9];
+	const u8 data4[4];
+	const u8 data5[6];
+	const u8 stream[4];
 };
 
-const static struct additional_sensor_data sensor_data[] = {
+static const struct additional_sensor_data sensor_data[] = {
+    {				/* OM6802 */
+	.data1 =
+		{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
+		 0xb3, 0xfc},
+	.data2 =
+		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+		 0xff},
+	.data4 =	/*Freq (50/60Hz). Splitted for test purpose */
+		{0x66, 0xca, 0xa8, 0xf0},
+	.data5 =	/* this could be removed later */
+		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+	.stream =
+		{0x0b, 0x04, 0x0a, 0x78},
+    },
+    {				/* OTHER */
+	.data1 =
+		{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
+		 0xe8, 0xfc},
+	.data2 =
+		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+		 0xd9},
+	.data4 =
+		{0x66, 0x00, 0xa8, 0xa8},
+	.data5 =
+		{0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
+	.stream =
+		{0x0b, 0x04, 0x0a, 0x00},
+    },
     {				/* TAS5130A */
 	.data1 =
-		{0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
-		 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
-		 0xd8, 0xc8, 0xd9, 0xfc},
+		{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
+		 0xc8, 0xfc},
 	.data2 =
-		{0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
-		 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
-		 0xe8, 0xe0},
-	.data3 =
-		{0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
-		 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
-		 0xcf, 0xe0},
+		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+		 0xe0},
 	.data4 =	/* Freq (50/60Hz). Splitted for test purpose */
 		{0x66, 0x00, 0xa8, 0xe8},
 	.data5 =
@@ -292,32 +315,12 @@ const static struct additional_sensor_da
 	.stream =
 		{0x0b, 0x04, 0x0a, 0x40},
     },
-    {				/* OM6802 */
-	.data1 =
-		{0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
-		 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
-		 0xd8, 0xb3, 0xd9, 0xfc},
-	.data2 =
-		{0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
-		 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
-		 0xe8, 0xff},
-	.data3 =
-		{0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
-		 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
-		 0xcf, 0xff},
-	.data4 =	/*Freq (50/60Hz). Splitted for test purpose */
-		{0x66, 0xca, 0xa8, 0xf0 },
-	.data5 =	/* this could be removed later */
-		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
-	.stream =
-		{0x0b, 0x04, 0x0a, 0x78},
-    }
 };
 
 #define MAX_EFFECTS 7
 /* easily done by soft, this table could be removed,
  * i keep it here just in case */
-static const __u8 effects_table[MAX_EFFECTS][6] = {
+static const u8 effects_table[MAX_EFFECTS][6] = {
 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},	/* Normal */
 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},	/* Repujar */
 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},	/* Monochrome */
@@ -327,90 +330,58 @@ static const __u8 effects_table[MAX_EFFE
 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},	/* Negative */
 };
 
-static const __u8 gamma_table[GAMMA_MAX][34] = {
-	{0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,	/* 0 */
-	 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
-	 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
-	 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75,	/* 1 */
-	 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
-	 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
-	 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b,	/* 2 */
-	 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
-	 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
-	 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,	/* 3 */
-	 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
-	 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
-	 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55,	/* 4 */
-	 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
-	 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
-	 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48,	/* 5 */
-	 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
-	 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
-	 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,	/* 6 */
-	 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
-	 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
-	 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,	/* 7 */
-	 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
-	 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
-	 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,	/* 8 */
-	 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
-	 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
-	 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,	/* 9 */
-	 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
-	 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
-	 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44,	/* 10 */
-	 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
-	 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
-	 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52,	/* 11 */
-	 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
-	 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
-	 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e,	/* 12 */
-	 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
-	 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
-	 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83,	/* 13 */
-	 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
-	 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
-	 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a,	/* 14 */
-	 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
-	 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
-	 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
-	 0xa0, 0xff},
-	{0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7,	/* 15 */
-	 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
-	 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
-	 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
-	 0xa0, 0xff}
+static const u8 gamma_table[GAMMA_MAX][17] = {
+	{0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9,	/* 0 */
+	 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+	 0xff},
+	{0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad,	/* 1 */
+	 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+	 0xff},
+	{0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6,	/* 2 */
+	 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+	 0xff},
+	{0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e,	/* 3 */
+	 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+	 0xff},
+	{0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95,	/* 4 */
+	 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+	 0xff},
+	{0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87,	/* 5 */
+	 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+	 0xff},
+	{0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67,	/* 6 */
+	 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+	 0xff},
+	{0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70,	/* 7 */
+	 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
+	 0xff},
+	{0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79,	/* 8 */
+	 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+	 0xff},
+	{0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84,	/* 9 */
+	 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+	 0xff},
+	{0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e,	/* 10 */
+	 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+	 0xff},
+	{0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B,	/* 11 */
+	 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+	 0xff},
+	{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,	/* 12 */
+	 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
+	 0xff},
+	{0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,	/* 13 */
+	 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
+	 0xff},
+	{0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,	/* 14 */
+	 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
+	 0xff},
+	{0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,	/* 15 */
+	 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
+	 0xff}
 };
 
-static const __u8 tas5130a_sensor_init[][8] = {
+static const u8 tas5130a_sensor_init[][8] = {
 	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
 	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
@@ -418,11 +389,11 @@ static const __u8 tas5130a_sensor_init[]
 	{},
 };
 
-static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
 
 /* read 1 byte */
-static int reg_r(struct gspca_dev *gspca_dev,
-		   __u16 index)
+static u8 reg_r(struct gspca_dev *gspca_dev,
+		   u16 index)
 {
 	usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -435,7 +406,7 @@ static int reg_r(struct gspca_dev *gspca
 }
 
 static void reg_w(struct gspca_dev *gspca_dev,
-		  __u16 index)
+		  u16 index)
 {
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -446,7 +417,7 @@ static void reg_w(struct gspca_dev *gspc
 }
 
 static void reg_w_buf(struct gspca_dev *gspca_dev,
-		  const __u8 *buffer, __u16 len)
+		  const u8 *buffer, u16 len)
 {
 	if (len <= USB_BUF_SZ) {
 		memcpy(gspca_dev->usb_buf, buffer, len);
@@ -457,7 +428,7 @@ static void reg_w_buf(struct gspca_dev *
 				0x01, 0,
 				gspca_dev->usb_buf, len, 500);
 	} else {
-		__u8 *tmpbuf;
+		u8 *tmpbuf;
 
 		tmpbuf = kmalloc(len, GFP_KERNEL);
 		memcpy(tmpbuf, buffer, len);
@@ -471,14 +442,41 @@ static void reg_w_buf(struct gspca_dev *
 	}
 }
 
+/* write values to consecutive registers */
+static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
+			u8 reg,
+			const u8 *buffer, u16 len)
+{
+	int i;
+	u8 *p, *tmpbuf;
+
+	if (len * 2 <= USB_BUF_SZ)
+		p = tmpbuf = gspca_dev->usb_buf;
+	else
+		p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
+	i = len;
+	while (--i >= 0) {
+		*p++ = reg++;
+		*p++ = *buffer++;
+	}
+	usb_control_msg(gspca_dev->dev,
+			usb_sndctrlpipe(gspca_dev->dev, 0),
+			0,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0x01, 0,
+			tmpbuf, len * 2, 500);
+	if (len * 2 > USB_BUF_SZ)
+		kfree(tmpbuf);
+}
+
 /* Reported as OM6802*/
 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
 {
 	int i;
-	const __u8 *p;
-	__u8 byte;
-	__u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
-	static const __u8 sensor_init[] = {
+	const u8 *p;
+	u8 byte;
+	u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+	static const u8 sensor_init[] = {
 		0xdf, 0x6d,
 		0xdd, 0x18,
 		0x5a, 0xe0,
@@ -497,7 +495,7 @@ static void om6802_sensor_init(struct gs
 	};
 
 	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
-	msleep(5);
+	msleep(100);
 	i = 4;
 	while (--i > 0) {
 		byte = reg_r(gspca_dev, 0x0060);
@@ -538,20 +536,20 @@ static int sd_config(struct gspca_dev *g
 	struct cam *cam;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 
 	cam->cam_mode = vga_mode_t16;
 	cam->nmodes = ARRAY_SIZE(vga_mode_t16);
 
-	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
-	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
-	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->colors = COLORS_DEF;
 	sd->gamma = GAMMA_DEF;
-	sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
-	sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
-	sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
-	sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
-	sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+	sd->autogain = AUTOGAIN_DEF;
+	sd->mirror = MIRROR_DEF;
+	sd->freq = FREQ_DEF;
+	sd->whitebalance = WHITE_BALANCE_DEF;
+	sd->sharpness = SHARPNESS_DEF;
+	sd->effect = EFFECTS_DEF;
 	return 0;
 }
 
@@ -559,7 +557,7 @@ static void setbrightness(struct gspca_d
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned int brightness;
-	__u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+	u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
 
 	brightness = sd->brightness;
 	if (brightness < 7) {
@@ -576,7 +574,7 @@ static void setcontrast(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	unsigned int contrast = sd->contrast;
-	__u16 reg_to_write;
+	u16 reg_to_write;
 
 	if (contrast < 7)
 		reg_to_write = 0x8ea9 - contrast * 0x200;
@@ -589,7 +587,7 @@ static void setcontrast(struct gspca_dev
 static void setcolors(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u16 reg_to_write;
+	u16 reg_to_write;
 
 	reg_to_write = 0x80bb + sd->colors * 0x100;	/* was 0xc0 */
 	reg_w(gspca_dev, reg_to_write);
@@ -600,14 +598,15 @@ static void setgamma(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
-	reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+	reg_w_ixbuf(gspca_dev, 0x90,
+		gamma_table[sd->gamma], sizeof gamma_table[0]);
 }
 
 static void setwhitebalance(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	__u8 white_balance[8] =
+	u8 white_balance[8] =
 		{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
 
 	if (sd->whitebalance)
@@ -619,7 +618,7 @@ static void setwhitebalance(struct gspca
 static void setsharpness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u16 reg_to_write;
+	u16 reg_to_write;
 
 	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
 
@@ -635,18 +634,22 @@ static int sd_init(struct gspca_dev *gsp
 	 * to see the initial parameters.*/
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	__u8 byte, test_byte;
+	u16 sensor_id;
+	u8 test_byte = 0;
+	u16 reg80, reg8e;
 
-	static const __u8 read_indexs[] =
-		{ 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
-		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
-	static const __u8 n1[] =
+	static const u8 read_indexs[] =
+		{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
+		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
+	static const u8 n1[] =
 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
-	static const __u8 n2[] =
+	static const u8 n2[] =
 			{0x08, 0x00};
-	static const __u8 n3[] =
+	static const u8 n3[6] =
 			{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
-	static const __u8 n4[] =
+	static const u8 n3_other[6] =
+			{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
+	static const u8 n4[] =
 		{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
 		 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
 		 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -656,40 +659,61 @@ static int sd_init(struct gspca_dev *gsp
 		 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
 		 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
 		 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
-	static const __u8 nset9[4] =
-			{ 0x0b, 0x04, 0x0a, 0x78 };
-	static const __u8 nset8[6] =
+	static const u8 n4_other[] =
+		{0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+		 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+		 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+		 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+		 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+		 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+		 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+		 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
+	static const u8 nset8[6] =
 			{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
+	static const u8 nset8_other[6] =
+			{ 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
+	static const u8 nset9[4] =
+			{ 0x0b, 0x04, 0x0a, 0x78 };
+	static const u8 nset9_other[4] =
+			{ 0x0b, 0x04, 0x0a, 0x00 };
 
-	byte = reg_r(gspca_dev, 0x06);
-	test_byte = reg_r(gspca_dev, 0x07);
-	if (byte == 0x08 && test_byte == 0x07) {
-		PDEBUG(D_CONF, "sensor om6802");
-		sd->sensor = SENSOR_OM6802;
-	} else if (byte == 0x08 && test_byte == 0x01) {
-		PDEBUG(D_CONF, "sensor tas5130a");
-		sd->sensor = SENSOR_TAS5130A;
-	} else {
-		PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
+	sensor_id = (reg_r(gspca_dev, 0x06) << 8)
+			| reg_r(gspca_dev, 0x07);
+	switch (sensor_id & 0xff0f) {
+	case 0x0801:
+		PDEBUG(D_PROBE, "sensor tas5130a");
 		sd->sensor = SENSOR_TAS5130A;
+		break;
+	case 0x0803:
+		PDEBUG(D_PROBE, "sensor 'other'");
+		sd->sensor = SENSOR_OTHER;
+		break;
+	case 0x0807:
+		PDEBUG(D_PROBE, "sensor om6802");
+		sd->sensor = SENSOR_OM6802;
+		break;
+	default:
+		PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
+		return -EINVAL;
 	}
 
-	reg_w_buf(gspca_dev, n1, sizeof n1);
-	test_byte = 0;
-	i = 5;
-	while (--i >= 0) {
-		reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
-		test_byte = reg_r(gspca_dev, 0x0063);
-		msleep(100);
-		if (test_byte == 0x17)
-			break;		/* OK */
-	}
-	if (i < 0) {
-		err("Bad sensor reset %02x", test_byte);
-/*		return -EIO; */
+	if (sd->sensor != SENSOR_OTHER) {
+		reg_w_buf(gspca_dev, n1, sizeof n1);
+		i = 5;
+		while (--i >= 0) {
+			reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+			test_byte = reg_r(gspca_dev, 0x0063);
+			msleep(100);
+			if (test_byte == 0x17)
+				break;		/* OK */
+		}
+		if (i < 0) {
+			err("Bad sensor reset %02x", test_byte);
+/*			return -EIO; */
 /*fixme: test - continue */
+		}
+		reg_w_buf(gspca_dev, n2, sizeof n2);
 	}
-	reg_w_buf(gspca_dev, n2, sizeof n2);
 
 	i = 0;
 	while (read_indexs[i] != 0x00) {
@@ -699,21 +723,31 @@ static int sd_init(struct gspca_dev *gsp
 		i++;
 	}
 
-	reg_w_buf(gspca_dev, n3, sizeof n3);
-	reg_w_buf(gspca_dev, n4, sizeof n4);
-	reg_r(gspca_dev, 0x0080);
-	reg_w(gspca_dev, 0x2c80);
+	if (sd->sensor != SENSOR_OTHER) {
+		reg_w_buf(gspca_dev, n3, sizeof n3);
+		reg_w_buf(gspca_dev, n4, sizeof n4);
+		reg_r(gspca_dev, 0x0080);
+		reg_w(gspca_dev, 0x2c80);
+		reg80 = 0x3880;
+		reg8e = 0x338e;
+	} else {
+		reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
+		reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
+		sd->gamma = 5;
+		reg80 = 0xac80;
+		reg8e = 0xb88e;
+	}
 
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+	reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
 			sizeof sensor_data[sd->sensor].data1);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
-			sizeof sensor_data[sd->sensor].data3);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+	reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+			sizeof sensor_data[sd->sensor].data2);
+	reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
 			sizeof sensor_data[sd->sensor].data2);
 
-	reg_w(gspca_dev, 0x3880);
-	reg_w(gspca_dev, 0x3880);
-	reg_w(gspca_dev, 0x338e);
+	reg_w(gspca_dev, reg80);
+	reg_w(gspca_dev, reg80);
+	reg_w(gspca_dev, reg8e);
 
 	setbrightness(gspca_dev);
 	setcontrast(gspca_dev);
@@ -730,16 +764,20 @@ static int sd_init(struct gspca_dev *gsp
 			sizeof sensor_data[sd->sensor].data4);
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
 			sizeof sensor_data[sd->sensor].data5);
-	reg_w_buf(gspca_dev, nset8, sizeof nset8);
-	reg_w_buf(gspca_dev, nset9, sizeof nset9);
-
-	reg_w(gspca_dev, 0x2880);
+	if (sd->sensor != SENSOR_OTHER) {
+		reg_w_buf(gspca_dev, nset8, sizeof nset8);
+		reg_w_buf(gspca_dev, nset9, sizeof nset9);
+		reg_w(gspca_dev, 0x2880);
+	} else {
+		reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
+		reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
+	}
 
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+	reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
 			sizeof sensor_data[sd->sensor].data1);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
-			sizeof sensor_data[sd->sensor].data3);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+	reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+			sizeof sensor_data[sd->sensor].data2);
+	reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
 			sizeof sensor_data[sd->sensor].data2);
 
 	return 0;
@@ -748,7 +786,7 @@ static int sd_init(struct gspca_dev *gsp
 static void setflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 flipcmd[8] =
+	u8 flipcmd[8] =
 		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
 
 	if (sd->mirror)
@@ -778,7 +816,7 @@ static void seteffect(struct gspca_dev *
 static void setlightfreq(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+	u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
 
 	if (sd->freq == 2)	/* 60hz */
 		freq[1] = 0x00;
@@ -791,22 +829,22 @@ static void setlightfreq(struct gspca_de
 static void poll_sensor(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	static const __u8 poll1[] =
+	static const u8 poll1[] =
 		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
 		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
 		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
 		 0x60, 0x14};
-	static const __u8 poll2[] =
+	static const u8 poll2[] =
 		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
 		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
-	static const __u8 poll3[] =
+	static const u8 poll3[] =
 		{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
-	static const __u8 poll4[] =
+	static const u8 poll4[] =
 		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
 		 0xc2, 0x80, 0xc3, 0x10};
 
-	if (sd->sensor != SENSOR_TAS5130A) {
+	if (sd->sensor == SENSOR_OM6802) {
 		PDEBUG(D_STREAM, "[Sensor requires polling]");
 		reg_w_buf(gspca_dev, poll1, sizeof poll1);
 		reg_w_buf(gspca_dev, poll2, sizeof poll2);
@@ -819,13 +857,14 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, mode;
-	__u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
-	static const __u8 t3[] =
-		{ 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
-		  0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+	u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+	static const u8 t3[] =
+		{ 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
 	switch (mode) {
+	case 0:		/* 640x480 (0x00) */
+		break;
 	case 1:		/* 352x288 */
 		t2[1] = 0x40;
 		break;
@@ -835,14 +874,20 @@ static int sd_start(struct gspca_dev *gs
 	case 3:		/* 176x144 */
 		t2[1] = 0x50;
 		break;
-	case 4:		/* 160x120 */
+	default:
+/*	case 4:		 * 160x120 */
 		t2[1] = 0x20;
 		break;
-	default:	/* 640x480 (0x00) */
-		break;
 	}
 
-	if (sd->sensor == SENSOR_TAS5130A) {
+	switch (sd->sensor) {
+	case SENSOR_OM6802:
+		om6802_sensor_init(gspca_dev);
+		break;
+	case SENSOR_OTHER:
+		break;
+	default:
+/*	case SENSOR_TAS5130A: */
 		i = 0;
 		while (tas5130a_sensor_init[i][0] != 0) {
 			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -854,14 +899,13 @@ static int sd_start(struct gspca_dev *gs
 		reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
 				 sizeof tas5130a_sensor_init[0]);
 		reg_w(gspca_dev, 0x3c80);
-	} else {
-		om6802_sensor_init(gspca_dev);
+		break;
 	}
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
 			sizeof sensor_data[sd->sensor].data4);
 	reg_r(gspca_dev, 0x0012);
 	reg_w_buf(gspca_dev, t2, sizeof t2);
-	reg_w_buf(gspca_dev, t3, sizeof t3);
+	reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
 	reg_w(gspca_dev, 0x0013);
 	msleep(15);
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
@@ -885,16 +929,18 @@ static void sd_stopN(struct gspca_dev *g
 	msleep(20);
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
 			sizeof sensor_data[sd->sensor].stream);
-	msleep(20);
-	reg_w(gspca_dev, 0x0309);
+	if (sd->sensor != SENSOR_OTHER) {
+		msleep(20);
+		reg_w(gspca_dev, 0x0309);
+	}
 }
 
 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 */
 {
-	static __u8 ffd9[] = { 0xff, 0xd9 };
+	static u8 ffd9[] = { 0xff, 0xd9 };
 
 	if (data[0] == 0x5a) {
 		/* Control Packet, after this came the header again,
@@ -1172,8 +1218,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/tv8532.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/tv8532.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/tv8532.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/tv8532.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,6 @@ struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
 	__u16 brightness;
-	__u16 contrast;
 
 	__u8 packet;
 };
@@ -39,38 +38,22 @@ 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 struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
 	{
 	 {
 	  .id = V4L2_CID_BRIGHTNESS,
 	  .type = V4L2_CTRL_TYPE_INTEGER,
 	  .name = "Brightness",
 	  .minimum = 1,
-	  .maximum = 0x2ff,
+	  .maximum = 0x15f,	/* = 352 - 1 */
 	  .step = 1,
-	  .default_value = 0x18f,
+#define BRIGHTNESS_DEF 0x14c
+	  .default_value = BRIGHTNESS_DEF,
 	  },
 	 .set = sd_setbrightness,
 	 .get = sd_getbrightness,
 	 },
-#define SD_CONTRAST 1
-	{
-	 {
-	  .id = V4L2_CID_CONTRAST,
-	  .type = V4L2_CTRL_TYPE_INTEGER,
-	  .name = "Contrast",
-	  .minimum = 0,
-	  .maximum = 0xffff,
-	  .step = 1,
-	  .default_value = 0x7fff,
-	  },
-	 .set = sd_setcontrast,
-	 .get = sd_getcontrast,
-	 },
 };
 
 static const struct v4l2_pix_format sif_mode[] = {
@@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_
 		.priv = 0},
 };
 
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-#define TESTCLK 0x10		/* reg 0x2c -> 0x12 //10 */
-#define TESTCOMP 0x90		/* reg 0x28 -> 0x80 */
-#define TESTLINE 0x81		/* reg 0x29 -> 0x81 */
-#define QCIFLINE 0x41		/* reg 0x29 -> 0x81 */
-#define TESTPTL 0x14		/* reg 0x2D -> 0x14 */
-#define TESTPTH 0x01		/* reg 0x2E -> 0x01 */
-#define TESTPTBL 0x12		/* reg 0x2F -> 0x0a */
-#define TESTPTBH 0x01		/* reg 0x30 -> 0x01 */
-#define ADWIDTHL 0xe8		/* reg 0x0c -> 0xe8 */
-#define ADWIDTHH 0x03		/* reg 0x0d -> 0x03 */
-#define ADHEIGHL 0x90		/* reg 0x0e -> 0x91 //93 */
-#define ADHEIGHH 0x01		/* reg 0x0f -> 0x01 */
-#define EXPOL 0x8f		/* reg 0x1c -> 0x8f */
-#define EXPOH 0x01		/* reg 0x1d -> 0x01 */
-#define ADCBEGINL 0x44		/* reg 0x10 -> 0x46 //47 */
-#define ADCBEGINH 0x00		/* reg 0x11 -> 0x00 */
-#define ADRBEGINL 0x0a		/* reg 0x14 -> 0x0b //0x0c */
-#define ADRBEGINH 0x00		/* reg 0x15 -> 0x00 */
-#define TV8532_CMD_UPDATE 0x84
-
-#define TV8532_EEprom_Add 0x03
-#define TV8532_EEprom_DataL 0x04
-#define TV8532_EEprom_DataM 0x05
-#define TV8532_EEprom_DataH 0x06
-#define TV8532_EEprom_TableLength 0x07
-#define TV8532_EEprom_Write 0x08
-#define TV8532_PART_CTRL 0x00
-#define TV8532_CTRL 0x01
-#define TV8532_CMD_EEprom_Open 0x30
-#define TV8532_CMD_EEprom_Close 0x29
-#define TV8532_UDP_UPDATE 0x31
-#define TV8532_GPIO 0x39
-#define TV8532_GPIO_OE 0x3B
-#define TV8532_REQ_RegWrite 0x02
-#define TV8532_REQ_RegRead 0x03
-
-#define TV8532_ADWIDTH_L 0x0C
-#define TV8532_ADWIDTH_H 0x0D
-#define TV8532_ADHEIGHT_L 0x0E
-#define TV8532_ADHEIGHT_H 0x0F
-#define TV8532_EXPOSURE 0x1C
-#define TV8532_QUANT_COMP 0x28
-#define TV8532_MODE_PACKET 0x29
-#define TV8532_SETCLK 0x2C
-#define TV8532_POINT_L 0x2D
-#define TV8532_POINT_H 0x2E
-#define TV8532_POINTB_L 0x2F
-#define TV8532_POINTB_H 0x30
-#define TV8532_BUDGET_L 0x2A
-#define TV8532_BUDGET_H 0x2B
-#define TV8532_VID_L 0x34
-#define TV8532_VID_H 0x35
-#define TV8532_PID_L 0x36
-#define TV8532_PID_H 0x37
-#define TV8532_DeviceID 0x83
-#define TV8532_AD_SLOPE 0x91
-#define TV8532_AD_BITCTRL 0x94
-#define TV8532_AD_COLBEGIN_L 0x10
-#define TV8532_AD_COLBEGIN_H 0x11
-#define TV8532_AD_ROWBEGIN_L 0x14
-#define TV8532_AD_ROWBEGIN_H 0x15
+/* TV-8532A (ICM532A) registers (LE) */
+#define R00_PART_CONTROL 0x00
+#define		LATENT_CHANGE	0x80
+#define		EXPO_CHANGE	0x04
+#define R01_TIMING_CONTROL_LOW 0x01
+#define		CMD_EEprom_Open 0x30
+#define		CMD_EEprom_Close 0x29
+#define R03_TABLE_ADDR 0x03
+#define R04_WTRAM_DATA_L 0x04
+#define R05_WTRAM_DATA_M 0x05
+#define R06_WTRAM_DATA_H 0x06
+#define R07_TABLE_LEN	0x07
+#define R08_RAM_WRITE_ACTION 0x08
+#define R0C_AD_WIDTHL	0x0c
+#define R0D_AD_WIDTHH	0x0d
+#define R0E_AD_HEIGHTL	0x0e
+#define R0F_AD_HEIGHTH	0x0f
+#define R10_AD_COL_BEGINL 0x10
+#define R11_AD_COL_BEGINH 0x11
+#define		MIRROR		0x04	/* [10] */
+#define R14_AD_ROW_BEGINL 0x14
+#define R15_AD_ROWBEGINH  0x15
+#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R28_QUANT	0x28
+#define R29_LINE	0x29
+#define R2C_POLARITY	0x2c
+#define R2D_POINT	0x2d
+#define R2E_POINTH	0x2e
+#define R2F_POINTB	0x2f
+#define R30_POINTBH	0x30
+#define R31_UPD		0x31
+#define R2A_HIGH_BUDGET 0x2a
+#define R2B_LOW_BUDGET	0x2b
+#define R34_VID		0x34
+#define R35_VIDH	0x35
+#define R36_PID		0x36
+#define R37_PIDH	0x37
+#define R39_Test1	0x39		/* GPIO */
+#define R3B_Test3	0x3B		/* GPIO */
+#define R83_AD_IDH	0x83
+#define R91_AD_SLOPEREG 0x91
+#define R94_AD_BITCONTROL 0x94
 
-static const __u32 tv_8532_eeprom_data[] = {
-/*	add		dataL	   dataM	dataH */
-	0x00010001, 0x01018011, 0x02050014, 0x0305001c,
-	0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
-	0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
-	0x0c0509f1, 0
+static const u8 eeprom_data[][3] = {
+/*	dataH dataM dataL */
+	{0x01, 0x00, 0x01},
+	{0x01, 0x80, 0x11},
+	{0x05, 0x00, 0x14},
+	{0x05, 0x00, 0x1c},
+	{0x0d, 0x00, 0x1e},
+	{0x05, 0x00, 0x1f},
+	{0x05, 0x05, 0x19},
+	{0x05, 0x01, 0x1b},
+	{0x05, 0x09, 0x1e},
+	{0x0d, 0x89, 0x2e},
+	{0x05, 0x89, 0x2f},
+	{0x05, 0x0d, 0xd9},
+	{0x05, 0x09, 0xf1},
 };
 
 static int reg_r(struct gspca_dev *gspca_dev,
@@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca
 {
 	usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
-			TV8532_REQ_RegRead,
+			0x03,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,	/* value */
 			index, gspca_dev->usb_buf, 1,
@@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca
 }
 
 /* write 1 byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
+static void reg_w1(struct gspca_dev *gspca_dev,
 		  __u16 index, __u8 value)
 {
 	gspca_dev->usb_buf[0] = value;
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
-			TV8532_REQ_RegWrite,
+			0x02,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,	/* value */
 			index, gspca_dev->usb_buf, 1, 500);
 }
 
 /* write 2 bytes */
-static void reg_w_2(struct gspca_dev *gspca_dev,
-		  __u16 index, __u8 val1, __u8 val2)
+static void reg_w2(struct gspca_dev *gspca_dev,
+		  u16 index, u16 value)
 {
-	gspca_dev->usb_buf[0] = val1;
-	gspca_dev->usb_buf[1] = val2;
+	gspca_dev->usb_buf[0] = value;
+	gspca_dev->usb_buf[1] = value >> 8;
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
-			TV8532_REQ_RegWrite,
+			0x02,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0,	/* value */
 			index, gspca_dev->usb_buf, 2, 500);
@@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gs
 
 static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
 {
-	int i = 0;
-	__u8 reg, data0, data1, data2;
+	int i;
 
-	reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
-	reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
-/*	msleep(1); */
-	while (tv_8532_eeprom_data[i]) {
-		reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
-		reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
-		/* msleep(1); */
-		data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
-		reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
-		/* msleep(1); */
-		data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
-		reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
-		/* msleep(1); */
-		data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
-		reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
-		/* msleep(1); */
-		reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
-		/* msleep(10); */
-		i++;
+	reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
+	for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
+		reg_w1(gspca_dev, R03_TABLE_ADDR, i);
+		reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
+		reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
+		reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
+		reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
 	}
-	reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
-/*	msleep(1); */
-	reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+	reg_w1(gspca_dev, R07_TABLE_LEN, i);
+	reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
 	msleep(10);
 }
 
@@ -238,79 +193,76 @@ static int sd_config(struct gspca_dev *g
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
 
-	tv_8532WriteEEprom(gspca_dev);
-
 	cam = &gspca_dev->cam;
-	cam->epaddr = 1;
 	cam->cam_mode = sif_mode;
-	cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+	cam->nmodes = ARRAY_SIZE(sif_mode);
 
-	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
-	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+	sd->brightness = BRIGHTNESS_DEF;
 	return 0;
 }
 
 static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
 {
-	__u8 data;
+	int i;
+	static u8 reg_tb[] = {
+		R0C_AD_WIDTHL,
+		R0D_AD_WIDTHH,
+		R28_QUANT,
+		R29_LINE,
+		R2C_POLARITY,
+		R2D_POINT,
+		R2E_POINTH,
+		R2F_POINTB,
+		R30_POINTBH,
+		R2A_HIGH_BUDGET,
+		R2B_LOW_BUDGET,
+		R34_VID,
+		R35_VIDH,
+		R36_PID,
+		R37_PIDH,
+		R83_AD_IDH,
+		R10_AD_COL_BEGINL,
+		R11_AD_COL_BEGINH,
+		R14_AD_ROW_BEGINL,
+		R15_AD_ROWBEGINH,
+		0
+	};
 
-	data = reg_r(gspca_dev, 0x0001);
-	PDEBUG(D_USBI, "register 0x01-> %x", data);
-	data = reg_r(gspca_dev, 0x0002);
-	PDEBUG(D_USBI, "register 0x02-> %x", data);
-	reg_r(gspca_dev, TV8532_ADWIDTH_L);
-	reg_r(gspca_dev, TV8532_ADWIDTH_H);
-	reg_r(gspca_dev, TV8532_QUANT_COMP);
-	reg_r(gspca_dev, TV8532_MODE_PACKET);
-	reg_r(gspca_dev, TV8532_SETCLK);
-	reg_r(gspca_dev, TV8532_POINT_L);
-	reg_r(gspca_dev, TV8532_POINT_H);
-	reg_r(gspca_dev, TV8532_POINTB_L);
-	reg_r(gspca_dev, TV8532_POINTB_H);
-	reg_r(gspca_dev, TV8532_BUDGET_L);
-	reg_r(gspca_dev, TV8532_BUDGET_H);
-	reg_r(gspca_dev, TV8532_VID_L);
-	reg_r(gspca_dev, TV8532_VID_H);
-	reg_r(gspca_dev, TV8532_PID_L);
-	reg_r(gspca_dev, TV8532_PID_H);
-	reg_r(gspca_dev, TV8532_DeviceID);
-	reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
-	reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
-	reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
-	reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+	i = 0;
+	do {
+		reg_r(gspca_dev, reg_tb[i]);
+		i++;
+	} while (reg_tb[i] != 0);
 }
 
 static void tv_8532_setReg(struct gspca_dev *gspca_dev)
 {
-	reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
-			ADCBEGINL);			/* 0x10 */
-	reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
-			ADCBEGINH);			/* also digital gain */
-	reg_w_1(gspca_dev, TV8532_PART_CTRL,
-			TV8532_CMD_UPDATE);		/* 0x00<-0x84 */
+	reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+						/* begin active line */
+	reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+						/* mirror and digital gain */
+	reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+						/* = 0x84 */
 
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+	reg_w1(gspca_dev, R3B_Test3, 0x0a);	/* Test0Sel = 10 */
 	/******************************************************/
-	reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
-	reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
-	reg_w_2(gspca_dev, TV8532_EXPOSURE,
-			EXPOL, EXPOH);			/* 350d 0x014c; 1c */
-	reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
-			ADCBEGINL);			/* 0x10 */
-	reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
-			ADCBEGINH);			/* also digital gain */
-	reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
-			ADRBEGINL);			/* 0x14 */
+	reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
+	reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
+	reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+	reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+						/* begin active line */
+	reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+						/* mirror and digital gain */
+	reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
 
-	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00);	/* 0x91 */
-	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02);	/* 0x94 */
+	reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+	reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
 
-	reg_w_1(gspca_dev, TV8532_CTRL,
-			TV8532_CMD_EEprom_Close);	/* 0x01 */
+	reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
 
-	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00);	/* 0x91 */
-	reg_w_1(gspca_dev, TV8532_PART_CTRL,
-			TV8532_CMD_UPDATE);		/* 0x00<-0x84 */
+	reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+	reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+						/* = 0x84 */
 }
 
 static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
@@ -319,54 +271,55 @@ static void tv_8532_PollReg(struct gspca
 
 	/* strange polling from tgc */
 	for (i = 0; i < 10; i++) {
-		reg_w_1(gspca_dev, TV8532_SETCLK,
-			TESTCLK);		/* 0x48; //0x08; 0x2c */
-		reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
-		reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01);	/* 0x31 */
+		reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+		reg_w1(gspca_dev, R00_PART_CONTROL,
+				LATENT_CHANGE | EXPO_CHANGE);
+		reg_w1(gspca_dev, R31_UPD, 0x01);
 	}
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
-	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+	tv_8532WriteEEprom(gspca_dev);
+
+	reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32);	/* slope begin 1,7V,
+							 * slope rate 2 */
+	reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
 	tv_8532ReadRegisters(gspca_dev);
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
-	reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
-				ADHEIGHH);	/* 401d 0x0169; 0e */
-	reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
-				EXPOH);		/* 350d 0x014c; 1c */
-	reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL);	/* 0x20; 0x0c */
-	reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH);	/* 0x0d */
+	reg_w1(gspca_dev, R3B_Test3, 0x0b);
+	reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
+	reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+	reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
+	reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
 
 	/*******************************************************************/
-	reg_w_1(gspca_dev, TV8532_QUANT_COMP,
-			TESTCOMP);	/* 0x72 compressed mode 0x28 */
-	reg_w_1(gspca_dev, TV8532_MODE_PACKET,
-			TESTLINE);	/* 0x84; // CIF | 4 packet 0x29 */
+	reg_w1(gspca_dev, R28_QUANT, 0x90);
+					/* no compress - fixed Q - quant 0 */
+	reg_w1(gspca_dev, R29_LINE, 0x81);
+					/* 0x84; // CIF | 4 packet 0x29 */
 
 	/************************************************/
-	reg_w_1(gspca_dev, TV8532_SETCLK,
-			TESTCLK);		/* 0x48; //0x08; 0x2c */
-	reg_w_1(gspca_dev, TV8532_POINT_L,
-			TESTPTL);		/* 0x38; 0x2d */
-	reg_w_1(gspca_dev, TV8532_POINT_H,
-			TESTPTH);		/* 0x04; 0x2e */
-	reg_w_1(gspca_dev, TV8532_POINTB_L,
-			TESTPTBL);		/* 0x04; 0x2f */
-	reg_w_1(gspca_dev, TV8532_POINTB_H,
-			TESTPTBH);		/* 0x04; 0x30 */
-	reg_w_1(gspca_dev, TV8532_PART_CTRL,
-			TV8532_CMD_UPDATE);	/* 0x00<-0x84 */
+	reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+						/* 0x48; //0x08; 0x2c */
+	reg_w1(gspca_dev, R2D_POINT, 0x14);
+						/* 0x38; 0x2d */
+	reg_w1(gspca_dev, R2E_POINTH, 0x01);
+						/* 0x04; 0x2e */
+	reg_w1(gspca_dev, R2F_POINTB, 0x12);
+						/* 0x04; 0x2f */
+	reg_w1(gspca_dev, R30_POINTBH, 0x01);
+						/* 0x04; 0x30 */
+	reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+						/* 0x00<-0x84 */
 	/*************************************************/
-	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01);	/* 0x31 */
+	reg_w1(gspca_dev, R31_UPD, 0x01);	/* update registers */
 	msleep(200);
-	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */
+	reg_w1(gspca_dev, R31_UPD, 0x00);		/* end update */
 	/*************************************************/
 	tv_8532_setReg(gspca_dev);
 	/*************************************************/
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+	reg_w1(gspca_dev, R3B_Test3, 0x0b);	/* Test0Sel = 11 = GPIO */
 	/*************************************************/
 	tv_8532_setReg(gspca_dev);
 	/*************************************************/
@@ -377,11 +330,10 @@ static int sd_init(struct gspca_dev *gsp
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int brightness = sd->brightness;
 
-	reg_w_2(gspca_dev, TV8532_EXPOSURE,
-		brightness >> 8, brightness);		/* 1c */
-	reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+	reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+	reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+						/* 0x84 */
 }
 
 /* -- start the camera -- */
@@ -389,57 +341,50 @@ static int sd_start(struct gspca_dev *gs
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
-	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+	reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32);	/* slope begin 1,7V,
+							 * slope rate 2 */
+	reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
 	tv_8532ReadRegisters(gspca_dev);
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
-	reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
-		ADHEIGHL, ADHEIGHH);	/* 401d 0x0169; 0e */
-/*	reg_w_2(gspca_dev, TV8532_EXPOSURE,
-		EXPOL, EXPOH);		 * 350d 0x014c; 1c */
+	reg_w1(gspca_dev, R3B_Test3, 0x0b);
+
+	reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
 	setbrightness(gspca_dev);
 
-	reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL);	/* 0x20; 0x0c */
-	reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH);	/* 0x0d */
+	reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);		/* 0x20; 0x0c */
+	reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
 
 	/************************************************/
-	reg_w_1(gspca_dev, TV8532_QUANT_COMP,
-			TESTCOMP);	/* 0x72 compressed mode 0x28 */
+	reg_w1(gspca_dev, R28_QUANT, 0x90);
+					/* 0x72 compressed mode 0x28 */
 	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
 		/* 176x144 */
-		reg_w_1(gspca_dev, TV8532_MODE_PACKET,
-			QCIFLINE);	/* 0x84; // CIF | 4 packet 0x29 */
+		reg_w1(gspca_dev, R29_LINE, 0x41);
+					/* CIF - 2 lines/packet */
 	} else {
 		/* 352x288 */
-		reg_w_1(gspca_dev, TV8532_MODE_PACKET,
-			TESTLINE);	/* 0x84; // CIF | 4 packet 0x29 */
+		reg_w1(gspca_dev, R29_LINE, 0x81);
+					/* CIF - 2 lines/packet */
 	}
 	/************************************************/
-	reg_w_1(gspca_dev, TV8532_SETCLK,
-			TESTCLK);		/* 0x48; //0x08; 0x2c */
-	reg_w_1(gspca_dev, TV8532_POINT_L,
-			TESTPTL);		/* 0x38; 0x2d */
-	reg_w_1(gspca_dev, TV8532_POINT_H,
-			TESTPTH);		/* 0x04; 0x2e */
-	reg_w_1(gspca_dev, TV8532_POINTB_L,
-			TESTPTBL);		/* 0x04; 0x2f */
-	reg_w_1(gspca_dev, TV8532_POINTB_H,
-			TESTPTBH);		/* 0x04; 0x30 */
-	reg_w_1(gspca_dev, TV8532_PART_CTRL,
-			TV8532_CMD_UPDATE);	/* 0x00<-0x84 */
+	reg_w1(gspca_dev, R2C_POLARITY, 0x10);		/* slow clock */
+	reg_w1(gspca_dev, R2D_POINT, 0x14);
+	reg_w1(gspca_dev, R2E_POINTH, 0x01);
+	reg_w1(gspca_dev, R2F_POINTB, 0x12);
+	reg_w1(gspca_dev, R30_POINTBH, 0x01);
+	reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
 	/************************************************/
-	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01);	/* 0x31 */
+	reg_w1(gspca_dev, R31_UPD, 0x01);	/* update registers */
 	msleep(200);
-	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */
+	reg_w1(gspca_dev, R31_UPD, 0x00);		/* end update */
 	/************************************************/
 	tv_8532_setReg(gspca_dev);
 	/************************************************/
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+	reg_w1(gspca_dev, R3B_Test3, 0x0b);	/* Test0Sel = 11 = GPIO */
 	/************************************************/
 	tv_8532_setReg(gspca_dev);
 	/************************************************/
 	tv_8532_PollReg(gspca_dev);
-	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */
+	reg_w1(gspca_dev, R31_UPD, 0x00);	/* end update */
 
 	gspca_dev->empty_packet = 0;		/* check the empty packets */
 	sd->packet = 0;				/* ignore the first packets */
@@ -449,7 +394,7 @@ static int sd_start(struct gspca_dev *gs
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+	reg_w1(gspca_dev, R3B_Test3, 0x0b);	/* Test0Sel = 11 = GPIO */
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -473,9 +418,9 @@ static void sd_pkt_scan(struct gspca_dev
 
 	/* each packet contains:
 	 * - header 2 bytes
-	 * - RG line
+	 * - RGRG line
 	 * - 4 bytes
-	 * - GB line
+	 * - GBGB line
 	 * - 4 bytes
 	 */
 	gspca_frame_add(gspca_dev, packet_type0,
@@ -484,10 +429,6 @@ static void sd_pkt_scan(struct gspca_dev
 			frame, data + gspca_dev->width + 6, gspca_dev->width);
 }
 
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -506,24 +447,6 @@ static int sd_getbrightness(struct gspca
 	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)
-		setcontrast(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;
-}
-
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
@@ -570,8 +493,10 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/vc032x.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/vc032x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/vc032x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/vc032x.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,18 +37,21 @@ struct sd {
 	__u8 lightfreq;
 	__u8 sharpness;
 
+	u8 image_offset;
+
 	char bridge;
 #define BRIDGE_VC0321 0
 #define BRIDGE_VC0323 1
 	char sensor;
 #define SENSOR_HV7131R 0
 #define SENSOR_MI0360 1
-#define SENSOR_MI1320 2
-#define SENSOR_MI1310_SOC 3
-#define SENSOR_OV7660 4
-#define SENSOR_OV7670 5
-#define SENSOR_PO1200 6
-#define SENSOR_PO3130NC 7
+#define SENSOR_MI1310_SOC 2
+#define SENSOR_MI1320 3
+#define SENSOR_MI1320_SOC 4
+#define SENSOR_OV7660 5
+#define SENSOR_OV7670 6
+#define SENSOR_PO1200 7
+#define SENSOR_PO3130NC 8
 };
 
 /* V4L2 controls supported by the driver */
@@ -149,8 +152,29 @@ static const struct v4l2_pix_format vc03
 		.sizeimage = 640 * 480 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
+	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 1024 * 1 / 4 + 590,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 2},
+};
+static const struct v4l2_pix_format bi_mode[] = {
+	{320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240 * 2,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2},
+	{640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480 * 2,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1},
+	{1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 1024 * 2,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0},
 };
-
 static const struct v4l2_pix_format svga_mode[] = {
 	{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 		.bytesperline = 800,
@@ -400,92 +424,208 @@ static const __u8 mi0360_initQVGA_JPG[][
 static const __u8 mi1310_socinitVGA_JPG[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},
 	{0xb0, 0x04, 0x02, 0xcc},
-	{0xb3, 0x00, 0x64, 0xcc},
-	{0xb3, 0x00, 0x65, 0xcc},
-	{0xb3, 0x05, 0x00, 0xcc},
-	{0xb3, 0x06, 0x00, 0xcc},
+	{0xb3, 0x00, 0x24, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x03, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
 	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x34, 0x02, 0xcc},
 	{0xb3, 0x35, 0xdd, 0xcc},
-	{0xb3, 0x02, 0x00, 0xcc},
 	{0xb3, 0x03, 0x0a, 0xcc},
-	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x04, 0x0d, 0xcc},
 	{0xb3, 0x20, 0x00, 0xcc},
 	{0xb3, 0x21, 0x00, 0xcc},
-	{0xb3, 0x22, 0x03, 0xcc},
-	{0xb3, 0x23, 0xc0, 0xcc},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
 	{0xb3, 0x14, 0x00, 0xcc},
 	{0xb3, 0x15, 0x00, 0xcc},
-	{0xb3, 0x16, 0x04, 0xcc},
-	{0xb3, 0x17, 0xff, 0xcc},
-	{0xb3, 0x00, 0x65, 0xcc},
-	{0xb8, 0x00, 0x00, 0xcc},
-	{0xbc, 0x00, 0xd0, 0xcc},
-	{0xbc, 0x01, 0x01, 0xcc},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0xc8, 0x9f, 0x0b, 0xbb},
-	{0x5b, 0x00, 0x01, 0xbb},
-	{0x2f, 0xde, 0x20, 0xbb},
+	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb8, 0x01, 0x7d, 0xcc},
+	{0xb8, 0x81, 0x09, 0xcc},
+	{0xb8, 0x27, 0x20, 0xcc},
+	{0xb8, 0x26, 0x80, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb8, 0x00, 0x13, 0xcc},
+	{0xbc, 0x00, 0x71, 0xcc},
+	{0xb8, 0x81, 0x01, 0xcc},
+	{0xb8, 0x2c, 0x5a, 0xcc},
+	{0xb8, 0x2d, 0xff, 0xcc},
+	{0xb8, 0x2e, 0xee, 0xcc},
+	{0xb8, 0x2f, 0xfb, 0xcc},
+	{0xb8, 0x30, 0x52, 0xcc},
+	{0xb8, 0x31, 0xf8, 0xcc},
+	{0xb8, 0x32, 0xf1, 0xcc},
+	{0xb8, 0x33, 0xff, 0xcc},
+	{0xb8, 0x34, 0x54, 0xcc},
+	{0xb8, 0x35, 0x00, 0xcc},
+	{0xb8, 0x36, 0x00, 0xcc},
+	{0xb8, 0x37, 0x00, 0xcc},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x20, 0x03, 0x02, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x0d, 0x00, 0x09, 0xbb},
+	{0x0d, 0x00, 0x08, 0xbb},
 	{0xf0, 0x00, 0x01, 0xbb},
-	{0x05, 0x00, 0x07, 0xbb},
-	{0x34, 0x00, 0x00, 0xbb},
-	{0x35, 0xff, 0x00, 0xbb},
-	{0xdc, 0x07, 0x02, 0xbb},
-	{0xdd, 0x3c, 0x18, 0xbb},
-	{0xde, 0x92, 0x6d, 0xbb},
-	{0xdf, 0xcd, 0xb1, 0xbb},
-	{0xe0, 0xff, 0xe7, 0xbb},
-	{0x06, 0xf0, 0x0d, 0xbb},
-	{0x06, 0x70, 0x0e, 0xbb},
-	{0x4c, 0x00, 0x01, 0xbb},
-	{0x4d, 0x00, 0x01, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0x2e, 0x0c, 0x55, 0xbb},
-	{0x21, 0xb6, 0x6e, 0xbb},
-	{0x36, 0x30, 0x10, 0xbb},
-	{0x37, 0x00, 0xc1, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x06, 0x00, 0x14, 0xbb},
+	{0x3a, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x9b, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x07, 0x00, 0x84, 0xbb},
-	{0x08, 0x02, 0x4a, 0xbb},
-	{0x05, 0x01, 0x10, 0xbb},
-	{0x06, 0x00, 0x39, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0x58, 0x02, 0x67, 0xbb},
-	{0x57, 0x02, 0x00, 0xbb},
-	{0x5a, 0x02, 0x67, 0xbb},
-	{0x59, 0x02, 0x00, 0xbb},
-	{0x5c, 0x12, 0x0d, 0xbb},
-	{0x5d, 0x16, 0x11, 0xbb},
-	{0x39, 0x06, 0x18, 0xbb},
-	{0x3a, 0x06, 0x18, 0xbb},
-	{0x3b, 0x06, 0x18, 0xbb},
-	{0x3c, 0x06, 0x18, 0xbb},
-	{0x64, 0x7b, 0x5b, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0x36, 0x30, 0x10, 0xbb},
-	{0x37, 0x00, 0xc0, 0xbb},
-	{0xbc, 0x0e, 0x00, 0xcc},
-	{0xbc, 0x0f, 0x05, 0xcc},
-	{0xbc, 0x10, 0xc0, 0xcc},
-	{0xbc, 0x11, 0x03, 0xcc},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x2b, 0x00, 0x28, 0xbb},
+	{0x2c, 0x00, 0x30, 0xbb},
+	{0x2d, 0x00, 0x30, 0xbb},
+	{0x2e, 0x00, 0x28, 0xbb},
+	{0x41, 0x00, 0xd7, 0xbb},
+	{0x09, 0x02, 0x3a, 0xbb},
+	{0x0c, 0x00, 0x00, 0xbb},
+	{0x20, 0x00, 0x00, 0xbb},
+	{0x05, 0x00, 0x8c, 0xbb},
+	{0x06, 0x00, 0x32, 0xbb},
+	{0x07, 0x00, 0xc6, 0xbb},
+	{0x08, 0x00, 0x19, 0xbb},
+	{0x24, 0x80, 0x6f, 0xbb},
+	{0xc8, 0x00, 0x0f, 0xbb},
+	{0x20, 0x00, 0x0f, 0xbb},
 	{0xb6, 0x00, 0x00, 0xcc},
 	{0xb6, 0x03, 0x02, 0xcc},
 	{0xb6, 0x02, 0x80, 0xcc},
 	{0xb6, 0x05, 0x01, 0xcc},
 	{0xb6, 0x04, 0xe0, 0xcc},
-	{0xb6, 0x12, 0xf8, 0xcc},
-	{0xb6, 0x13, 0x25, 0xcc},
+	{0xb6, 0x12, 0x78, 0xcc},
 	{0xb6, 0x18, 0x02, 0xcc},
 	{0xb6, 0x17, 0x58, 0xcc},
 	{0xb6, 0x16, 0x00, 0xcc},
 	{0xb6, 0x22, 0x12, 0xcc},
 	{0xb6, 0x23, 0x0b, 0xcc},
+	{0xb3, 0x02, 0x02, 0xcc},
 	{0xbf, 0xc0, 0x39, 0xcc},
 	{0xbf, 0xc1, 0x04, 0xcc},
-	{0xbf, 0xcc, 0x00, 0xcc},
+	{0xbf, 0xcc, 0x10, 0xcc},
+	{0xb9, 0x12, 0x00, 0xcc},
+	{0xb9, 0x13, 0x0a, 0xcc},
+	{0xb9, 0x14, 0x0a, 0xcc},
+	{0xb9, 0x15, 0x0a, 0xcc},
+	{0xb9, 0x16, 0x0a, 0xcc},
+	{0xb9, 0x18, 0x00, 0xcc},
+	{0xb9, 0x19, 0x0f, 0xcc},
+	{0xb9, 0x1a, 0x0f, 0xcc},
+	{0xb9, 0x1b, 0x0f, 0xcc},
+	{0xb9, 0x1c, 0x0f, 0xcc},
+	{0xb8, 0x8e, 0x00, 0xcc},
+	{0xb8, 0x8f, 0xff, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0x03, 0x03, 0xc0, 0xbb},
+	{0x06, 0x00, 0x10, 0xbb},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb8, 0x0c, 0x20, 0xcc},
+	{0xb8, 0x0d, 0x70, 0xcc},
+	{0xb6, 0x13, 0x13, 0xcc},
+	{0x2f, 0x00, 0xC0, 0xbb},
+	{0xb8, 0xa0, 0x12, 0xcc},
+	{},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0xb3, 0x00, 0x24, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x03, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},
+	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x0d, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb8, 0x01, 0x7d, 0xcc},
+	{0xb8, 0x81, 0x09, 0xcc},
+	{0xb8, 0x27, 0x20, 0xcc},
+	{0xb8, 0x26, 0x80, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb8, 0x00, 0x13, 0xcc},
+	{0xbc, 0x00, 0xd1, 0xcc},
+	{0xb8, 0x81, 0x01, 0xcc},
+	{0xb8, 0x2c, 0x5a, 0xcc},
+	{0xb8, 0x2d, 0xff, 0xcc},
+	{0xb8, 0x2e, 0xee, 0xcc},
+	{0xb8, 0x2f, 0xfb, 0xcc},
+	{0xb8, 0x30, 0x52, 0xcc},
+	{0xb8, 0x31, 0xf8, 0xcc},
+	{0xb8, 0x32, 0xf1, 0xcc},
+	{0xb8, 0x33, 0xff, 0xcc},
+	{0xb8, 0x34, 0x54, 0xcc},
+	{0xb8, 0x35, 0x00, 0xcc},
+	{0xb8, 0x36, 0x00, 0xcc},
+	{0xb8, 0x37, 0x00, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x0d, 0x00, 0x09, 0xbb},
+	{0x0d, 0x00, 0x08, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x06, 0x00, 0x14, 0xbb},
+	{0x3a, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x9b, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x2b, 0x00, 0x28, 0xbb},
+	{0x2c, 0x00, 0x30, 0xbb},
+	{0x2d, 0x00, 0x30, 0xbb},
+	{0x2e, 0x00, 0x28, 0xbb},
+	{0x41, 0x00, 0xd7, 0xbb},
+	{0x09, 0x02, 0x3a, 0xbb},
+	{0x0c, 0x00, 0x00, 0xbb},
+	{0x20, 0x00, 0x00, 0xbb},
+	{0x05, 0x00, 0x8c, 0xbb},
+	{0x06, 0x00, 0x32, 0xbb},
+	{0x07, 0x00, 0xc6, 0xbb},
+	{0x08, 0x00, 0x19, 0xbb},
+	{0x24, 0x80, 0x6f, 0xbb},
+	{0xc8, 0x00, 0x0f, 0xbb},
+	{0x20, 0x00, 0x0f, 0xbb},
+	{0xb6, 0x00, 0x00, 0xcc},
+	{0xb6, 0x03, 0x01, 0xcc},
+	{0xb6, 0x02, 0x40, 0xcc},
+	{0xb6, 0x05, 0x00, 0xcc},
+	{0xb6, 0x04, 0xf0, 0xcc},
+	{0xb6, 0x12, 0x78, 0xcc},
+	{0xb6, 0x18, 0x00, 0xcc},
+	{0xb6, 0x17, 0x96, 0xcc},
+	{0xb6, 0x16, 0x00, 0xcc},
+	{0xb6, 0x22, 0x12, 0xcc},
+	{0xb6, 0x23, 0x0b, 0xcc},
+	{0xb3, 0x02, 0x02, 0xcc},
+	{0xbf, 0xc0, 0x39, 0xcc},
+	{0xbf, 0xc1, 0x04, 0xcc},
+	{0xbf, 0xcc, 0x10, 0xcc},
+	{0xb9, 0x12, 0x00, 0xcc},
+	{0xb9, 0x13, 0x0a, 0xcc},
+	{0xb9, 0x14, 0x0a, 0xcc},
+	{0xb9, 0x15, 0x0a, 0xcc},
+	{0xb9, 0x16, 0x0a, 0xcc},
+	{0xb9, 0x18, 0x00, 0xcc},
+	{0xb9, 0x19, 0x0f, 0xcc},
+	{0xb9, 0x1a, 0x0f, 0xcc},
+	{0xb9, 0x1b, 0x0f, 0xcc},
+	{0xb9, 0x1c, 0x0f, 0xcc},
+	{0xb8, 0x8e, 0x00, 0xcc},
+	{0xb8, 0x8f, 0xff, 0xcc},
 	{0xbc, 0x02, 0x18, 0xcc},
 	{0xbc, 0x03, 0x50, 0xcc},
 	{0xbc, 0x04, 0x18, 0xcc},
@@ -496,131 +636,123 @@ static const __u8 mi1310_socinitVGA_JPG[
 	{0xbc, 0x0a, 0x10, 0xcc},
 	{0xbc, 0x0b, 0x00, 0xcc},
 	{0xbc, 0x0c, 0x00, 0xcc},
-	{0xb3, 0x5c, 0x01, 0xcc},
-	{0xf0, 0x00, 0x01, 0xbb},
-	{0x80, 0x00, 0x03, 0xbb},
-	{0x81, 0xc7, 0x14, 0xbb},
-	{0x82, 0xeb, 0xe8, 0xbb},
-	{0x83, 0xfe, 0xf4, 0xbb},
-	{0x84, 0xcd, 0x10, 0xbb},
-	{0x85, 0xf3, 0xee, 0xbb},
-	{0x86, 0xff, 0xf1, 0xbb},
-	{0x87, 0xcd, 0x10, 0xbb},
-	{0x88, 0xf3, 0xee, 0xbb},
-	{0x89, 0x01, 0xf1, 0xbb},
-	{0x8a, 0xe5, 0x17, 0xbb},
-	{0x8b, 0xe8, 0xe2, 0xbb},
-	{0x8c, 0xf7, 0xed, 0xbb},
-	{0x8d, 0x00, 0xff, 0xbb},
-	{0x8e, 0xec, 0x10, 0xbb},
-	{0x8f, 0xf0, 0xed, 0xbb},
-	{0x90, 0xf9, 0xf2, 0xbb},
-	{0x91, 0x00, 0x00, 0xbb},
-	{0x92, 0xe9, 0x0d, 0xbb},
-	{0x93, 0xf4, 0xf2, 0xbb},
-	{0x94, 0xfb, 0xf5, 0xbb},
-	{0x95, 0x00, 0xff, 0xbb},
-	{0xb6, 0x0f, 0x08, 0xbb},
-	{0xb7, 0x3d, 0x16, 0xbb},
-	{0xb8, 0x0c, 0x04, 0xbb},
-	{0xb9, 0x1c, 0x07, 0xbb},
-	{0xba, 0x0a, 0x03, 0xbb},
-	{0xbb, 0x1b, 0x09, 0xbb},
-	{0xbc, 0x17, 0x0d, 0xbb},
-	{0xbd, 0x23, 0x1d, 0xbb},
-	{0xbe, 0x00, 0x28, 0xbb},
-	{0xbf, 0x11, 0x09, 0xbb},
-	{0xc0, 0x16, 0x15, 0xbb},
-	{0xc1, 0x00, 0x1b, 0xbb},
-	{0xc2, 0x0e, 0x07, 0xbb},
-	{0xc3, 0x14, 0x10, 0xbb},
-	{0xc4, 0x00, 0x17, 0xbb},
-	{0x06, 0x74, 0x8e, 0xbb},
-	{0xf0, 0x00, 0x01, 0xbb},
-	{0x06, 0xf4, 0x8e, 0xbb},
-	{0x00, 0x00, 0x50, 0xdd},
-	{0x06, 0x74, 0x8e, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0x24, 0x50, 0x20, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},
-	{0x34, 0x0c, 0x50, 0xbb},
 	{0xb3, 0x01, 0x41, 0xcc},
-	{0xf0, 0x00, 0x00, 0xbb},
 	{0x03, 0x03, 0xc0, 0xbb},
+	{0x06, 0x00, 0x10, 0xbb},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb8, 0x0c, 0x20, 0xcc},
+	{0xb8, 0x0d, 0x70, 0xcc},
+	{0xb6, 0x13, 0x13, 0xcc},
+	{0x2f, 0x00, 0xC0, 0xbb},
+	{0xb8, 0xa0, 0x12, 0xcc},
 	{},
 };
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
-	{0xb0, 0x03, 0x19, 0xcc},	{0xb0, 0x04, 0x02, 0xcc},
-	{0xb3, 0x00, 0x64, 0xcc},	{0xb3, 0x00, 0x65, 0xcc},
-	{0xb3, 0x05, 0x00, 0xcc},	{0xb3, 0x06, 0x00, 0xcc},
-	{0xb3, 0x08, 0x01, 0xcc},	{0xb3, 0x09, 0x0c, 0xcc},
-	{0xb3, 0x34, 0x02, 0xcc},	{0xb3, 0x35, 0xdd, 0xcc},
-	{0xb3, 0x02, 0x00, 0xcc},	{0xb3, 0x03, 0x0a, 0xcc},
-	{0xb3, 0x04, 0x05, 0xcc},	{0xb3, 0x20, 0x00, 0xcc},
-	{0xb3, 0x21, 0x00, 0xcc},	{0xb3, 0x22, 0x03, 0xcc},
-	{0xb3, 0x23, 0xc0, 0xcc},	{0xb3, 0x14, 0x00, 0xcc},
-	{0xb3, 0x15, 0x00, 0xcc},	{0xb3, 0x16, 0x04, 0xcc},
-	{0xb3, 0x17, 0xff, 0xcc},	{0xb3, 0x00, 0x65, 0xcc},
-	{0xb8, 0x00, 0x00, 0xcc},	{0xbc, 0x00, 0xf0, 0xcc},
-	{0xbc, 0x01, 0x01, 0xcc},	{0xf0, 0x00, 0x02, 0xbb},
-	{0xc8, 0x9f, 0x0b, 0xbb},	{0x5b, 0x00, 0x01, 0xbb},
-	{0x2f, 0xde, 0x20, 0xbb},	{0xf0, 0x00, 0x00, 0xbb},
-	{0x20, 0x03, 0x02, 0xbb},	{0xf0, 0x00, 0x01, 0xbb},
-	{0x05, 0x00, 0x07, 0xbb},	{0x34, 0x00, 0x00, 0xbb},
-	{0x35, 0xff, 0x00, 0xbb},	{0xdc, 0x07, 0x02, 0xbb},
-	{0xdd, 0x3c, 0x18, 0xbb},	{0xde, 0x92, 0x6d, 0xbb},
-	{0xdf, 0xcd, 0xb1, 0xbb},	{0xe0, 0xff, 0xe7, 0xbb},
-	{0x06, 0xf0, 0x0d, 0xbb},	{0x06, 0x70, 0x0e, 0xbb},
-	{0x4c, 0x00, 0x01, 0xbb},	{0x4d, 0x00, 0x01, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},	{0x2e, 0x0c, 0x55, 0xbb},
-	{0x21, 0xb6, 0x6e, 0xbb},	{0x36, 0x30, 0x10, 0xbb},
-	{0x37, 0x00, 0xc1, 0xbb},	{0xf0, 0x00, 0x00, 0xbb},
-	{0x07, 0x00, 0x84, 0xbb},	{0x08, 0x02, 0x4a, 0xbb},
-	{0x05, 0x01, 0x10, 0xbb},	{0x06, 0x00, 0x39, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},	{0x58, 0x02, 0x67, 0xbb},
-	{0x57, 0x02, 0x00, 0xbb},	{0x5a, 0x02, 0x67, 0xbb},
-	{0x59, 0x02, 0x00, 0xbb},	{0x5c, 0x12, 0x0d, 0xbb},
-	{0x5d, 0x16, 0x11, 0xbb},	{0x39, 0x06, 0x18, 0xbb},
-	{0x3a, 0x06, 0x18, 0xbb},	{0x3b, 0x06, 0x18, 0xbb},
-	{0x3c, 0x06, 0x18, 0xbb},	{0x64, 0x7b, 0x5b, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},	{0x36, 0x30, 0x10, 0xbb},
-	{0x37, 0x00, 0xc0, 0xbb},	{0xbc, 0x0e, 0x00, 0xcc},
-	{0xbc, 0x0f, 0x05, 0xcc},	{0xbc, 0x10, 0xc0, 0xcc},
-	{0xbc, 0x11, 0x03, 0xcc},	{0xb6, 0x00, 0x00, 0xcc},
-	{0xb6, 0x03, 0x01, 0xcc},	{0xb6, 0x02, 0x40, 0xcc},
-	{0xb6, 0x05, 0x00, 0xcc},	{0xb6, 0x04, 0xf0, 0xcc},
-	{0xb6, 0x12, 0xf8, 0xcc},	{0xb6, 0x13, 0x25, 0xcc},
-	{0xb6, 0x18, 0x00, 0xcc},	{0xb6, 0x17, 0x96, 0xcc},
-	{0xb6, 0x16, 0x00, 0xcc},	{0xb6, 0x22, 0x12, 0xcc},
-	{0xb6, 0x23, 0x0b, 0xcc},	{0xbf, 0xc0, 0x39, 0xcc},
-	{0xbf, 0xc1, 0x04, 0xcc},	{0xbf, 0xcc, 0x00, 0xcc},
-	{0xb3, 0x5c, 0x01, 0xcc},	{0xf0, 0x00, 0x01, 0xbb},
-	{0x80, 0x00, 0x03, 0xbb},	{0x81, 0xc7, 0x14, 0xbb},
-	{0x82, 0xeb, 0xe8, 0xbb},	{0x83, 0xfe, 0xf4, 0xbb},
-	{0x84, 0xcd, 0x10, 0xbb},	{0x85, 0xf3, 0xee, 0xbb},
-	{0x86, 0xff, 0xf1, 0xbb},	{0x87, 0xcd, 0x10, 0xbb},
-	{0x88, 0xf3, 0xee, 0xbb},	{0x89, 0x01, 0xf1, 0xbb},
-	{0x8a, 0xe5, 0x17, 0xbb},	{0x8b, 0xe8, 0xe2, 0xbb},
-	{0x8c, 0xf7, 0xed, 0xbb},	{0x8d, 0x00, 0xff, 0xbb},
-	{0x8e, 0xec, 0x10, 0xbb},	{0x8f, 0xf0, 0xed, 0xbb},
-	{0x90, 0xf9, 0xf2, 0xbb},	{0x91, 0x00, 0x00, 0xbb},
-	{0x92, 0xe9, 0x0d, 0xbb},	{0x93, 0xf4, 0xf2, 0xbb},
-	{0x94, 0xfb, 0xf5, 0xbb},	{0x95, 0x00, 0xff, 0xbb},
-	{0xb6, 0x0f, 0x08, 0xbb},	{0xb7, 0x3d, 0x16, 0xbb},
-	{0xb8, 0x0c, 0x04, 0xbb},	{0xb9, 0x1c, 0x07, 0xbb},
-	{0xba, 0x0a, 0x03, 0xbb},	{0xbb, 0x1b, 0x09, 0xbb},
-	{0xbc, 0x17, 0x0d, 0xbb},	{0xbd, 0x23, 0x1d, 0xbb},
-	{0xbe, 0x00, 0x28, 0xbb},	{0xbf, 0x11, 0x09, 0xbb},
-	{0xc0, 0x16, 0x15, 0xbb},	{0xc1, 0x00, 0x1b, 0xbb},
-	{0xc2, 0x0e, 0x07, 0xbb},	{0xc3, 0x14, 0x10, 0xbb},
-	{0xc4, 0x00, 0x17, 0xbb},	{0x06, 0x74, 0x8e, 0xbb},
-	{0xf0, 0x00, 0x01, 0xbb},	{0x06, 0xf4, 0x8e, 0xbb},
-	{0x00, 0x00, 0x50, 0xdd},	{0x06, 0x74, 0x8e, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},	{0x24, 0x50, 0x20, 0xbb},
-	{0xf0, 0x00, 0x02, 0xbb},	{0x34, 0x0c, 0x50, 0xbb},
-	{0xb3, 0x01, 0x41, 0xcc},	{0xf0, 0x00, 0x00, 0xbb},
-	{0x03, 0x03, 0xc0, 0xbb},
-	{},
+static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0xb3, 0x00, 0x24, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x05, 0x00, 0xcc},
+	{0xb3, 0x06, 0x01, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},
+	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x0d, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x22, 0x04, 0xcc},
+	{0xb3, 0x23, 0x00, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x16, 0x04, 0xcc},
+	{0xb3, 0x17, 0xff, 0xcc},
+	{0xb8, 0x01, 0x7d, 0xcc},
+	{0xb8, 0x81, 0x09, 0xcc},
+	{0xb8, 0x27, 0x20, 0xcc},
+	{0xb8, 0x26, 0x80, 0xcc},
+	{0xb8, 0x06, 0x00, 0xcc},
+	{0xb8, 0x07, 0x05, 0xcc},
+	{0xb8, 0x08, 0x00, 0xcc},
+	{0xb8, 0x09, 0x04, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb8, 0x00, 0x11, 0xcc},
+	{0xbc, 0x00, 0x71, 0xcc},
+	{0xb8, 0x81, 0x01, 0xcc},
+	{0xb8, 0x2c, 0x5a, 0xcc},
+	{0xb8, 0x2d, 0xff, 0xcc},
+	{0xb8, 0x2e, 0xee, 0xcc},
+	{0xb8, 0x2f, 0xfb, 0xcc},
+	{0xb8, 0x30, 0x52, 0xcc},
+	{0xb8, 0x31, 0xf8, 0xcc},
+	{0xb8, 0x32, 0xf1, 0xcc},
+	{0xb8, 0x33, 0xff, 0xcc},
+	{0xb8, 0x34, 0x54, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x0d, 0x00, 0x09, 0xbb},
+	{0x0d, 0x00, 0x08, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x06, 0x00, 0x14, 0xbb},
+	{0x3a, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x9b, 0x10, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x01, 0x00, 0xdd},
+	{0x2b, 0x00, 0x28, 0xbb},
+	{0x2c, 0x00, 0x30, 0xbb},
+	{0x2d, 0x00, 0x30, 0xbb},
+	{0x2e, 0x00, 0x28, 0xbb},
+	{0x41, 0x00, 0xd7, 0xbb},
+	{0x09, 0x02, 0x3a, 0xbb},
+	{0x0c, 0x00, 0x00, 0xbb},
+	{0x20, 0x00, 0x00, 0xbb},
+	{0x05, 0x00, 0x8c, 0xbb},
+	{0x06, 0x00, 0x32, 0xbb},
+	{0x07, 0x00, 0xc6, 0xbb},
+	{0x08, 0x00, 0x19, 0xbb},
+	{0x24, 0x80, 0x6f, 0xbb},
+	{0xc8, 0x00, 0x0f, 0xbb},
+	{0x20, 0x00, 0x03, 0xbb},
+	{0xb6, 0x00, 0x00, 0xcc},
+	{0xb6, 0x03, 0x05, 0xcc},
+	{0xb6, 0x02, 0x00, 0xcc},
+	{0xb6, 0x05, 0x04, 0xcc},
+	{0xb6, 0x04, 0x00, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb6, 0x18, 0x0a, 0xcc},
+	{0xb6, 0x17, 0x00, 0xcc},
+	{0xb6, 0x16, 0x00, 0xcc},
+	{0xb6, 0x22, 0x12, 0xcc},
+	{0xb6, 0x23, 0x0b, 0xcc},
+	{0xb3, 0x02, 0x02, 0xcc},
+	{0xbf, 0xc0, 0x39, 0xcc},
+	{0xbf, 0xc1, 0x04, 0xcc},
+	{0xbf, 0xcc, 0x10, 0xcc},
+	{0xb9, 0x12, 0x00, 0xcc},
+	{0xb9, 0x13, 0x14, 0xcc},
+	{0xb9, 0x14, 0x14, 0xcc},
+	{0xb9, 0x15, 0x14, 0xcc},
+	{0xb9, 0x16, 0x14, 0xcc},
+	{0xb9, 0x18, 0x00, 0xcc},
+	{0xb9, 0x19, 0x1e, 0xcc},
+	{0xb9, 0x1a, 0x1e, 0xcc},
+	{0xb9, 0x1b, 0x1e, 0xcc},
+	{0xb9, 0x1c, 0x1e, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xb8, 0x8e, 0x00, 0xcc},
+	{0xb8, 0x8f, 0xff, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb8, 0x0c, 0x20, 0xcc},
+	{0xb8, 0x0d, 0x70, 0xcc},
+	{0xb6, 0x13, 0x13, 0xcc},
+	{0x2f, 0x00, 0xC0, 0xbb},
+	{0xb8, 0xa0, 0x12, 0xcc},
+	{}
 };
 
 static const __u8 mi1320_gamma[17] = {
@@ -778,6 +910,345 @@ static const __u8 mi1320_initQVGA_data[]
 	{}
 };
 
+static const u8 mi1320_soc_InitVGA[][4] = {
+	{0xb3, 0x01, 0x01, 0xcc},
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},
+	{0xb3, 0x35, 0xc8, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},
+	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb8, 0x00, 0x00, 0xcc},
+	{0xbc, 0x00, 0x71, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xc8, 0x00, 0x00, 0xbb},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x07, 0x00, 0xe0, 0xbb},
+	{0x08, 0x00, 0x0b, 0xbb},
+	{0x21, 0x00, 0x0c, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0xbf, 0xc0, 0x26, 0xcc},
+	{0xbf, 0xc1, 0x02, 0xcc},
+	{0xbf, 0xcc, 0x04, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x05, 0x01, 0x78, 0xbb},
+	{0x06, 0x00, 0x11, 0xbb},
+	{0x07, 0x01, 0x42, 0xbb},
+	{0x08, 0x00, 0x11, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0x21, 0x80, 0x00, 0xbb},
+	{0x22, 0x0d, 0x0f, 0xbb},
+	{0x24, 0x80, 0x00, 0xbb},
+	{0x59, 0x00, 0xff, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x39, 0x03, 0xca, 0xbb},
+	{0x3a, 0x06, 0x80, 0xbb},
+	{0x3b, 0x01, 0x52, 0xbb},
+	{0x3c, 0x05, 0x40, 0xbb},
+	{0x57, 0x01, 0x9c, 0xbb},
+	{0x58, 0x01, 0xee, 0xbb},
+	{0x59, 0x00, 0xf0, 0xbb},
+	{0x5a, 0x01, 0x20, 0xbb},
+	{0x5c, 0x1d, 0x17, 0xbb},
+	{0x5d, 0x22, 0x1c, 0xbb},
+	{0x64, 0x1e, 0x1c, 0xbb},
+	{0x5b, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x22, 0xa0, 0x78, 0xbb},
+	{0x23, 0xa0, 0x78, 0xbb},
+	{0x24, 0x7f, 0x00, 0xbb},
+	{0x28, 0xea, 0x02, 0xbb},
+	{0x29, 0x86, 0x7a, 0xbb},
+	{0x5e, 0x52, 0x4c, 0xbb},
+	{0x5f, 0x20, 0x24, 0xbb},
+	{0x60, 0x00, 0x02, 0xbb},
+	{0x02, 0x00, 0xee, 0xbb},
+	{0x03, 0x39, 0x23, 0xbb},
+	{0x04, 0x07, 0x24, 0xbb},
+	{0x09, 0x00, 0xc0, 0xbb},
+	{0x0a, 0x00, 0x79, 0xbb},
+	{0x0b, 0x00, 0x04, 0xbb},
+	{0x0c, 0x00, 0x5c, 0xbb},
+	{0x0d, 0x00, 0xd9, 0xbb},
+	{0x0e, 0x00, 0x53, 0xbb},
+	{0x0f, 0x00, 0x21, 0xbb},
+	{0x10, 0x00, 0xa4, 0xbb},
+	{0x11, 0x00, 0xe5, 0xbb},
+	{0x15, 0x00, 0x00, 0xbb},
+	{0x16, 0x00, 0x00, 0xbb},
+	{0x17, 0x00, 0x00, 0xbb},
+	{0x18, 0x00, 0x00, 0xbb},
+	{0x19, 0x00, 0x00, 0xbb},
+	{0x1a, 0x00, 0x00, 0xbb},
+	{0x1b, 0x00, 0x00, 0xbb},
+	{0x1c, 0x00, 0x00, 0xbb},
+	{0x1d, 0x00, 0x00, 0xbb},
+	{0x1e, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x06, 0xe0, 0x0e, 0xbb},
+	{0x06, 0x60, 0x0e, 0xbb},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{}
+};
+static const u8 mi1320_soc_InitQVGA[][4] = {
+	{0xb3, 0x01, 0x01, 0xcc},
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},
+	{0xb3, 0x35, 0xc8, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},
+	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb8, 0x00, 0x00, 0xcc},
+	{0xbc, 0x00, 0xd1, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0xc8, 0x00, 0x00, 0xbb},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x07, 0x00, 0xe0, 0xbb},
+	{0x08, 0x00, 0x0b, 0xbb},
+	{0x21, 0x00, 0x0c, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0xbf, 0xc0, 0x26, 0xcc},
+	{0xbf, 0xc1, 0x02, 0xcc},
+	{0xbf, 0xcc, 0x04, 0xcc},
+	{0xbc, 0x02, 0x18, 0xcc},
+	{0xbc, 0x03, 0x50, 0xcc},
+	{0xbc, 0x04, 0x18, 0xcc},
+	{0xbc, 0x05, 0x00, 0xcc},
+	{0xbc, 0x06, 0x00, 0xcc},
+	{0xbc, 0x08, 0x30, 0xcc},
+	{0xbc, 0x09, 0x40, 0xcc},
+	{0xbc, 0x0a, 0x10, 0xcc},
+	{0xbc, 0x0b, 0x00, 0xcc},
+	{0xbc, 0x0c, 0x00, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x05, 0x01, 0x78, 0xbb},
+	{0x06, 0x00, 0x11, 0xbb},
+	{0x07, 0x01, 0x42, 0xbb},
+	{0x08, 0x00, 0x11, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0x21, 0x80, 0x00, 0xbb},
+	{0x22, 0x0d, 0x0f, 0xbb},
+	{0x24, 0x80, 0x00, 0xbb},
+	{0x59, 0x00, 0xff, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x39, 0x03, 0xca, 0xbb},
+	{0x3a, 0x06, 0x80, 0xbb},
+	{0x3b, 0x01, 0x52, 0xbb},
+	{0x3c, 0x05, 0x40, 0xbb},
+	{0x57, 0x01, 0x9c, 0xbb},
+	{0x58, 0x01, 0xee, 0xbb},
+	{0x59, 0x00, 0xf0, 0xbb},
+	{0x5a, 0x01, 0x20, 0xbb},
+	{0x5c, 0x1d, 0x17, 0xbb},
+	{0x5d, 0x22, 0x1c, 0xbb},
+	{0x64, 0x1e, 0x1c, 0xbb},
+	{0x5b, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x22, 0xa0, 0x78, 0xbb},
+	{0x23, 0xa0, 0x78, 0xbb},
+	{0x24, 0x7f, 0x00, 0xbb},
+	{0x28, 0xea, 0x02, 0xbb},
+	{0x29, 0x86, 0x7a, 0xbb},
+	{0x5e, 0x52, 0x4c, 0xbb},
+	{0x5f, 0x20, 0x24, 0xbb},
+	{0x60, 0x00, 0x02, 0xbb},
+	{0x02, 0x00, 0xee, 0xbb},
+	{0x03, 0x39, 0x23, 0xbb},
+	{0x04, 0x07, 0x24, 0xbb},
+	{0x09, 0x00, 0xc0, 0xbb},
+	{0x0a, 0x00, 0x79, 0xbb},
+	{0x0b, 0x00, 0x04, 0xbb},
+	{0x0c, 0x00, 0x5c, 0xbb},
+	{0x0d, 0x00, 0xd9, 0xbb},
+	{0x0e, 0x00, 0x53, 0xbb},
+	{0x0f, 0x00, 0x21, 0xbb},
+	{0x10, 0x00, 0xa4, 0xbb},
+	{0x11, 0x00, 0xe5, 0xbb},
+	{0x15, 0x00, 0x00, 0xbb},
+	{0x16, 0x00, 0x00, 0xbb},
+	{0x17, 0x00, 0x00, 0xbb},
+	{0x18, 0x00, 0x00, 0xbb},
+	{0x19, 0x00, 0x00, 0xbb},
+	{0x1a, 0x00, 0x00, 0xbb},
+	{0x1b, 0x00, 0x00, 0xbb},
+	{0x1c, 0x00, 0x00, 0xbb},
+	{0x1d, 0x00, 0x00, 0xbb},
+	{0x1e, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x06, 0xe0, 0x0e, 0xbb},
+	{0x06, 0x60, 0x0e, 0xbb},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{}
+};
+static const u8 mi1320_soc_InitSXGA[][4] = {
+	{0xb3, 0x01, 0x01, 0xcc},
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x01, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},
+	{0xb3, 0x35, 0xc8, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},
+	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x22, 0x04, 0xcc},
+	{0xb3, 0x23, 0x00, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x16, 0x04, 0xcc},
+	{0xb3, 0x17, 0xff, 0xcc},
+	{0xb3, 0x00, 0x67, 0xcc},
+	{0xbc, 0x00, 0x71, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0xc8, 0x9f, 0x0b, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0x5b, 0x00, 0x01, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x00, 0x00, 0x30, 0xdd},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0xbf, 0xc0, 0x26, 0xcc},
+	{0xbf, 0xc1, 0x02, 0xcc},
+	{0xbf, 0xcc, 0x04, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x05, 0x01, 0x78, 0xbb},
+	{0x06, 0x00, 0x11, 0xbb},
+	{0x07, 0x01, 0x42, 0xbb},
+	{0x08, 0x00, 0x11, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0x21, 0x80, 0x00, 0xbb},
+	{0x22, 0x0d, 0x0f, 0xbb},
+	{0x24, 0x80, 0x00, 0xbb},
+	{0x59, 0x00, 0xff, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x39, 0x03, 0xca, 0xbb},
+	{0x3a, 0x06, 0x80, 0xbb},
+	{0x3b, 0x01, 0x52, 0xbb},
+	{0x3c, 0x05, 0x40, 0xbb},
+	{0x57, 0x01, 0x9c, 0xbb},
+	{0x58, 0x01, 0xee, 0xbb},
+	{0x59, 0x00, 0xf0, 0xbb},
+	{0x5a, 0x01, 0x20, 0xbb},
+	{0x5c, 0x1d, 0x17, 0xbb},
+	{0x5d, 0x22, 0x1c, 0xbb},
+	{0x64, 0x1e, 0x1c, 0xbb},
+	{0x5b, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x22, 0xa0, 0x78, 0xbb},
+	{0x23, 0xa0, 0x78, 0xbb},
+	{0x24, 0x7f, 0x00, 0xbb},
+	{0x28, 0xea, 0x02, 0xbb},
+	{0x29, 0x86, 0x7a, 0xbb},
+	{0x5e, 0x52, 0x4c, 0xbb},
+	{0x5f, 0x20, 0x24, 0xbb},
+	{0x60, 0x00, 0x02, 0xbb},
+	{0x02, 0x00, 0xee, 0xbb},
+	{0x03, 0x39, 0x23, 0xbb},
+	{0x04, 0x07, 0x24, 0xbb},
+	{0x09, 0x00, 0xc0, 0xbb},
+	{0x0a, 0x00, 0x79, 0xbb},
+	{0x0b, 0x00, 0x04, 0xbb},
+	{0x0c, 0x00, 0x5c, 0xbb},
+	{0x0d, 0x00, 0xd9, 0xbb},
+	{0x0e, 0x00, 0x53, 0xbb},
+	{0x0f, 0x00, 0x21, 0xbb},
+	{0x10, 0x00, 0xa4, 0xbb},
+	{0x11, 0x00, 0xe5, 0xbb},
+	{0x15, 0x00, 0x00, 0xbb},
+	{0x16, 0x00, 0x00, 0xbb},
+	{0x17, 0x00, 0x00, 0xbb},
+	{0x18, 0x00, 0x00, 0xbb},
+	{0x19, 0x00, 0x00, 0xbb},
+	{0x1a, 0x00, 0x00, 0xbb},
+	{0x1b, 0x00, 0x00, 0xbb},
+	{0x1c, 0x00, 0x00, 0xbb},
+	{0x1d, 0x00, 0x00, 0xbb},
+	{0x1e, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x06, 0xe0, 0x0e, 0xbb},
+	{0x06, 0x60, 0x0e, 0xbb},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x05, 0x01, 0x13, 0xbb},
+	{0x06, 0x00, 0x11, 0xbb},
+	{0x07, 0x00, 0x85, 0xbb},
+	{0x08, 0x00, 0x27, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},
+	{0x21, 0x80, 0x00, 0xbb},
+	{0x22, 0x0d, 0x0f, 0xbb},
+	{0x24, 0x80, 0x00, 0xbb},
+	{0x59, 0x00, 0xff, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x39, 0x03, 0x0d, 0xbb},
+	{0x3a, 0x06, 0x1b, 0xbb},
+	{0x3b, 0x00, 0x95, 0xbb},
+	{0x3c, 0x04, 0xdb, 0xbb},
+	{0x57, 0x02, 0x00, 0xbb},
+	{0x58, 0x02, 0x66, 0xbb},
+	{0x59, 0x00, 0xff, 0xbb},
+	{0x5a, 0x01, 0x33, 0xbb},
+	{0x5c, 0x12, 0x0d, 0xbb},
+	{0x5d, 0x16, 0x11, 0xbb},
+	{0x64, 0x5e, 0x1c, 0xbb},
+	{}
+};
 static const __u8 po3130_gamma[17] = {
 	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
 	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
@@ -1764,26 +2235,43 @@ static const __u8 po1200_initVGA_data[][
 };
 
 struct sensor_info {
-	int sensorId;
-	__u8 I2cAdd;
-	__u8 IdAdd;
-	__u16 VpId;
-	__u8 m1;
-	__u8 m2;
-	__u8 op;
-	};
+	s8 sensorId;
+	u8 I2cAdd;
+	u8 IdAdd;
+	u16 VpId;
+	u8 m1;
+	u8 m2;
+	u8 op;
+};
 
 static const struct sensor_info sensor_info_data[] = {
 /*      sensorId,         I2cAdd,	IdAdd,  VpId,  m1,    m2,  op */
-	{SENSOR_HV7131R,    0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
-	{SENSOR_OV7660,     0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+	{-1,		    0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
+/* (tested in vc032x_probe_sensor) */
+/*	{-1,		    0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */
 	{SENSOR_PO3130NC,   0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01},
-	{SENSOR_MI1320,     0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
-	{SENSOR_OV7670,     0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
 	{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
 /* (tested in vc032x_probe_sensor) */
 /*	{SENSOR_MI0360,	    0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+	{SENSOR_HV7131R,    0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+	{-1,		    0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+	{-1,		    0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+	{SENSOR_OV7660,     0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+/*	{SENSOR_PO3130NC,   0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+	{-1,		    0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/*	{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+/*	{-1,		    0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */
+	{-1,		    0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
 	{SENSOR_PO1200,     0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+	{-1,		    0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
+	{-1,		    0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+	{-1,		    0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
+	{SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
+/*fixme: previously detected?*/
+	{SENSOR_MI1320,     0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
+/*fixme: not in the ms-win probe - may be found before?*/
+	{SENSOR_OV7670,     0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
 };
 
 /* read 'len' bytes in gspca_dev->usb_buf */
@@ -1814,51 +2302,49 @@ static void reg_w(struct usb_device *dev
 			500);
 }
 
-static void read_sensor_register(struct gspca_dev *gspca_dev,
-				__u16 address, __u16 *value)
+static u16 read_sensor_register(struct gspca_dev *gspca_dev,
+				u16 address)
 {
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 ldata, mdata, hdata;
+	u8 ldata, mdata, hdata;
 	int retry = 50;
 
-	*value = 0;
-
 	reg_r(gspca_dev, 0xa1, 0xb33f, 1);
-	/*PDEBUG(D_PROBE, " I2c Bus Busy Wait  0x%02X ", tmpvalue); */
 	if (!(gspca_dev->usb_buf[0] & 0x02)) {
-		PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
-			gspca_dev->usb_buf[0] & 0x02);
-		return;
+		PDEBUG(D_ERR, "I2c Bus Busy Wait %02x",
+			gspca_dev->usb_buf[0]);
+		return 0;
 	}
 	reg_w(dev, 0xa0, address, 0xb33a);
 	reg_w(dev, 0xa0, 0x02, 0xb339);
 
-	reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-	while (retry-- && gspca_dev->usb_buf[0]) {
+	do {
 		reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-/*		PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
-		msleep(1);
-	}
+		if (gspca_dev->usb_buf[0] == 0x00)
+			break;
+		msleep(40);
+	} while (--retry >= 0);
+
 	reg_r(gspca_dev, 0xa1, 0xb33e, 1);
 	ldata = gspca_dev->usb_buf[0];
 	reg_r(gspca_dev, 0xa1, 0xb33d, 1);
 	mdata = gspca_dev->usb_buf[0];
 	reg_r(gspca_dev, 0xa1, 0xb33c, 1);
 	hdata = gspca_dev->usb_buf[0];
-	PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
-		hdata, mdata, ldata);
+	if (hdata != 0 && mdata != 0 && ldata != 0)
+		PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
+			hdata, mdata, ldata);
 	reg_r(gspca_dev, 0xa1, 0xb334, 1);
 	if (gspca_dev->usb_buf[0] == 0x02)
-		*value = (hdata << 8) + mdata;
-	else
-		*value = hdata;
+		return (hdata << 8) + mdata;
+	return hdata;
 }
 
 static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int i;
-	__u16 value;
+	u16 value;
 	const struct sensor_info *ptsensor_info;
 
 	reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
@@ -1872,48 +2358,51 @@ static int vc032x_probe_sensor(struct gs
 		reg_w(dev, 0xa0, 0x0c, 0xb309);
 		reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
 		reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
-		read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
-		if (value == ptsensor_info->VpId)
-			return ptsensor_info->sensorId;
+		value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
+		if (value == 0 && ptsensor_info->IdAdd == 0x82)
+			value = read_sensor_register(gspca_dev, 0x83);
+		if (value != 0) {
+			PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)",
+				value, i);
+			if (value == ptsensor_info->VpId)
+				return ptsensor_info->sensorId;
 
-		/* special case for MI0360 */
-		if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
-		    && value == 0x8243)
-			return SENSOR_MI0360;
+			switch (value) {
+			case 0x7673:
+				return SENSOR_OV7670;
+			case 0x8243:
+				return SENSOR_MI0360;
+			}
+/*fixme: should return here*/
+		}
 	}
 	return -1;
 }
 
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
-			__u8 reg, const __u8 *val, __u8 size)
+static void i2c_write(struct gspca_dev *gspca_dev,
+			u8 reg, const u8 *val,
+			u8 size)		/* 1 or 2 */
 {
 	struct usb_device *dev = gspca_dev->dev;
+	int retry;
 
-	if (size > 3 || size < 1)
-		return -EINVAL;
 	reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
 	reg_w(dev, 0xa0, size, 0xb334);
 	reg_w(dev, 0xa0, reg, 0xb33a);
-	switch (size) {
-	case 1:
-		reg_w(dev, 0xa0, val[0], 0xb336);
-		break;
-	case 2:
-		reg_w(dev, 0xa0, val[0], 0xb336);
-		reg_w(dev, 0xa0, val[1], 0xb337);
-		break;
-	case 3:
-		reg_w(dev, 0xa0, val[0], 0xb336);
+	reg_w(dev, 0xa0, val[0], 0xb336);
+	if (size > 1)
 		reg_w(dev, 0xa0, val[1], 0xb337);
-		reg_w(dev, 0xa0, val[2], 0xb338);
-		break;
-	default:
-		reg_w(dev, 0xa0, 0x01, 0xb334);
-		return -EINVAL;
-	}
 	reg_w(dev, 0xa0, 0x01, 0xb339);
-	reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-	return gspca_dev->usb_buf[0] == 0;
+	retry = 4;
+	do {
+		reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+		if (gspca_dev->usb_buf[0] == 0)
+			break;
+		msleep(20);
+	} while (--retry > 0);
+	if (retry <= 0)
+		PDEBUG(D_ERR, "i2c_write failed");
 }
 
 static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -1938,7 +2427,7 @@ static void usb_exchange(struct gspca_de
 			return;
 		case 0xcc:			/* normal write */
 			reg_w(dev, 0xa0, data[i][2],
-					((data[i][0])<<8) | data[i][1]);
+					(data[i][0]) << 8 | data[i][1]);
 			break;
 		case 0xaa:			/* i2c op */
 			i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
@@ -1955,19 +2444,6 @@ static void usb_exchange(struct gspca_de
 	/*not reached*/
 }
 
-/*
- "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
- "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
- */
-
-static void vc0321_reset(struct gspca_dev *gspca_dev)
-{
-	reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
-	reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
-	msleep(100);
-	reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
-	msleep(100);
-}
 
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
@@ -1979,10 +2455,7 @@ static int sd_config(struct gspca_dev *g
 	int sensor;
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x02;
 	sd->bridge = id->driver_info;
-
-	vc0321_reset(gspca_dev);
 	sensor = vc032x_probe_sensor(gspca_dev);
 	switch (sensor) {
 	case -1:
@@ -2001,6 +2474,9 @@ static int sd_config(struct gspca_dev *g
 	case SENSOR_MI1320:
 		PDEBUG(D_PROBE, "Find Sensor MI1320");
 		break;
+	case SENSOR_MI1320_SOC:
+		PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+		break;
 	case SENSOR_OV7660:
 		PDEBUG(D_PROBE, "Find Sensor OV7660");
 		break;
@@ -2020,12 +2496,23 @@ static int sd_config(struct gspca_dev *g
 		cam->cam_mode = vc0321_mode;
 		cam->nmodes = ARRAY_SIZE(vc0321_mode);
 	} else {
-		if (sensor != SENSOR_PO1200) {
-			cam->cam_mode = vc0323_mode;
-			cam->nmodes = ARRAY_SIZE(vc0323_mode);
-		} else {
+		switch (sensor) {
+		case SENSOR_PO1200:
 			cam->cam_mode = svga_mode;
 			cam->nmodes = ARRAY_SIZE(svga_mode);
+			break;
+		case SENSOR_MI1310_SOC:
+			cam->cam_mode = vc0323_mode;
+			cam->nmodes = ARRAY_SIZE(vc0323_mode);
+			break;
+		case SENSOR_MI1320_SOC:
+			cam->cam_mode = bi_mode;
+			cam->nmodes = ARRAY_SIZE(bi_mode);
+			break;
+		default:
+			cam->cam_mode = vc0323_mode;
+			cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
+			break;
 		}
 	}
 
@@ -2061,7 +2548,7 @@ static int sd_config(struct gspca_dev *g
 	return 0;
 }
 
-/* this function is called at probe and time */
+/* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
 	return 0;
@@ -2124,9 +2611,15 @@ static void setsharpness(struct gspca_de
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	const __u8 (*init)[4];
 	const __u8 *GammaT = NULL;
 	const __u8 *MatrixT = NULL;
 	int mode;
+	static const u8 (*mi1320_soc_init[])[4] = {
+		mi1320_soc_InitSXGA,
+		mi1320_soc_InitVGA,
+		mi1320_soc_InitQVGA,
+	};
 
 	/* Assume start use the good resolution from gspca_dev->mode */
 	if (sd->bridge == BRIDGE_VC0321) {
@@ -2134,6 +2627,13 @@ static int sd_start(struct gspca_dev *gs
 		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
 		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
 		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+		sd->image_offset = 46;
+	} else {
+		if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
+				== V4L2_PIX_FMT_JPEG)
+			sd->image_offset = 0;
+		else
+			sd->image_offset = 32;
 	}
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2141,115 +2641,87 @@ static int sd_start(struct gspca_dev *gs
 	case SENSOR_HV7131R:
 		GammaT = hv7131r_gamma;
 		MatrixT = hv7131r_matrix;
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, hv7131r_initQVGA_data);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, hv7131r_initVGA_data);
-		}
+		if (mode)
+			init = hv7131r_initQVGA_data;	/* 320x240 */
+		else
+			init = hv7131r_initVGA_data;	/* 640x480 */
 		break;
 	case SENSOR_OV7660:
 		GammaT = ov7660_gamma;
 		MatrixT = ov7660_matrix;
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, ov7660_initQVGA_data);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, ov7660_initVGA_data);
-		}
+		if (mode)
+			init = ov7660_initQVGA_data;	/* 320x240 */
+		else
+			init = ov7660_initVGA_data;	/* 640x480 */
 		break;
 	case SENSOR_OV7670:
 		/*GammaT = ov7660_gamma; */
 		/*MatrixT = ov7660_matrix; */
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, ov7670_initVGA_JPG);
-		}
+		if (mode)
+			init = ov7670_initQVGA_JPG;	/* 320x240 */
+		else
+			init = ov7670_initVGA_JPG;	/* 640x480 */
 		break;
 	case SENSOR_MI0360:
 		GammaT = mi1320_gamma;
 		MatrixT = mi0360_matrix;
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, mi0360_initVGA_JPG);
-		}
+		if (mode)
+			init = mi0360_initQVGA_JPG;	/* 320x240 */
+		else
+			init = mi0360_initVGA_JPG;	/* 640x480 */
 		break;
 	case SENSOR_MI1310_SOC:
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+		GammaT = mi1320_gamma;
+		MatrixT = mi1320_matrix;
+		switch (mode) {
+		case 1:
+			init = mi1310_socinitQVGA_JPG;	/* 320x240 */
+			break;
+		case 0:
+			init = mi1310_socinitVGA_JPG;	/* 640x480 */
+			break;
+		default:
+			init = mi1310_soc_InitSXGA_JPG;	/* 1280x1024 */
+			break;
 		}
 		break;
 	case SENSOR_MI1320:
 		GammaT = mi1320_gamma;
 		MatrixT = mi1320_matrix;
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, mi1320_initQVGA_data);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, mi1320_initVGA_data);
-		}
+		if (mode)
+			init = mi1320_initQVGA_data;	/* 320x240 */
+		else
+			init = mi1320_initVGA_data;	/* 640x480 */
+		break;
+	case SENSOR_MI1320_SOC:
+		GammaT = mi1320_gamma;
+		MatrixT = mi1320_matrix;
+		init = mi1320_soc_init[mode];
 		break;
 	case SENSOR_PO3130NC:
 		GammaT = po3130_gamma;
 		MatrixT = po3130_matrix;
-		if (mode) {
-			/* 320x240 */
-			usb_exchange(gspca_dev, po3130_initQVGA_data);
-		} else {
-			/* 640x480 */
-			usb_exchange(gspca_dev, po3130_initVGA_data);
-		}
-		usb_exchange(gspca_dev, po3130_rundata);
+		if (mode)
+			init = po3130_initQVGA_data;	/* 320x240 */
+		else
+			init = po3130_initVGA_data;	/* 640x480 */
+		usb_exchange(gspca_dev, init);
+		init = po3130_rundata;
 		break;
-	case SENSOR_PO1200:
+	default:
+/*	case SENSOR_PO1200: */
 		GammaT = po1200_gamma;
 		MatrixT = po1200_matrix;
-		usb_exchange(gspca_dev, po1200_initVGA_data);
+		init = po1200_initVGA_data;
 		break;
-	default:
-		PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
-		return -EMEDIUMTYPE;
 	}
+	usb_exchange(gspca_dev, init);
 	if (GammaT && MatrixT) {
 		put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
 		put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
 		put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
 		put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
 
-		/* Seem SHARPNESS */
-		/*
-		reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
-		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
-		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
-		*/
-		/* all 0x40 ??? do nothing
-		reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
-		reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
-		reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
-		*/
-		/* Only works for HV7131R ??
-		reg_r (gspca_dev, 0xa1, 0xb881, 1);
-		reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
-		reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
-		*/
-		/* only hv7131r et ov7660
-		reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
-		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
-		reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
-		*/
 		/* set the led on 0x0892 0x0896 */
 		if (sd->sensor != SENSOR_PO1200) {
 			reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
@@ -2296,12 +2768,8 @@ static void sd_pkt_scan(struct gspca_dev
 			"vc032x header packet found len %d", len);
 		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
 						data, 0);
-		if (sd->bridge == BRIDGE_VC0321) {
-#define VCHDRSZ 46
-			data += VCHDRSZ;
-			len -= VCHDRSZ;
-#undef VCHDRSZ
-		}
+		data += sd->image_offset;
+		len -= sd->image_offset;
 		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
 				data, len);
 		return;
@@ -2399,7 +2867,8 @@ static int sd_querymenu(struct gspca_dev
 		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
 			strcpy((char *) menu->name, "50 Hz");
 			return 0;
-		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+		default:
+/*		case 2:		 * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
 			strcpy((char *) menu->name, "60 Hz");
 			return 0;
 		}
@@ -2424,6 +2893,7 @@ static const struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
 	{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
 	{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
 	{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
@@ -2432,6 +2902,7 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
 	{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
 	{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+	{USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323},
 	{USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
 	{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
 	{}
@@ -2460,8 +2931,11 @@ static struct usb_driver sd_driver = {
 /* -- module insert / remove -- */
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/gspca/zc3xx.c linux-libre-2.6.30-gnu1/drivers/media/video/gspca/zc3xx.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/gspca/zc3xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/gspca/zc3xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #define MODULE_NAME "zc3xx"
 
 #include "gspca.h"
+#include "jpeg.h"
 
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
 		"Serge A. Suchkov <Serge.A.S@tochka.ru>");
@@ -31,7 +32,7 @@ MODULE_LICENSE("GPL");
 
 static int force_sensor = -1;
 
-#include "jpeg.h"
+#define QUANT_VAL 1		/* quantization table */
 #include "zc3xx-reg.h"
 
 /* specific webcam descriptor */
@@ -44,30 +45,36 @@ struct sd {
 	__u8 autogain;
 	__u8 lightfreq;
 	__u8 sharpness;
+	u8 quality;			/* image quality */
+#define QUALITY_MIN 40
+#define QUALITY_MAX 60
+#define QUALITY_DEF 50
 
-	char qindex;
 	signed char sensor;		/* Type of image sensor chip */
 /* !! values used in different tables */
-#define SENSOR_CS2102 0
-#define SENSOR_CS2102K 1
-#define SENSOR_GC0305 2
-#define SENSOR_HDCS2020b 3
-#define SENSOR_HV7131B 4
-#define SENSOR_HV7131C 5
-#define SENSOR_ICM105A 6
-#define SENSOR_MC501CB 7
-#define SENSOR_OV7620 8
-/*#define SENSOR_OV7648 8 - same values */
-#define SENSOR_OV7630C 9
-#define SENSOR_PAS106 10
-#define SENSOR_PAS202B 11
-#define SENSOR_PB0330 12
-#define SENSOR_PO2030 13
-#define SENSOR_TAS5130CK 14
-#define SENSOR_TAS5130CXX 15
-#define SENSOR_TAS5130C_VF0250 16
-#define SENSOR_MAX 17
+#define SENSOR_ADCM2700 0
+#define SENSOR_CS2102 1
+#define SENSOR_CS2102K 2
+#define SENSOR_GC0305 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#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
 	unsigned short chip_revision;
+
+	u8 *jpeg_hdr;
 };
 
 /* V4L2 controls supported by the driver */
@@ -206,6 +213,213 @@ struct usb_action {
 	__u16	idx;
 };
 
+static const struct usb_action adcm2700_Initial[] = {
+	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc */
+	{0xa0, 0x04, ZC3XX_R002_CLOCKSELECT},		/* 00,02,04,cc */
+	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},		/* 00,08,03,cc */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,d3,cc */
+	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},	/* 00,03,02,cc */
+	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},		/* 00,04,80,cc */
+	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},	/* 00,05,01,cc */
+	{0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW},	/* 00,06,d8,cc */
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},	/* 00,01,01,cc */
+	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,03,cc */
+	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,01,cc */
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,05,cc */
+	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},		/* 00,98,00,cc */
+	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},		/* 00,9a,00,cc */
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},		/* 01,1a,00,cc */
+	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},		/* 01,1c,00,cc */
+	{0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW},		/* 00,9c,de,cc */
+	{0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},		/* 00,9e,86,cc */
+	{0xbb, 0x00, 0x0400},				/* 04,00,00,bb */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x0f, 0x140f},				/* 14,0f,0f,bb */
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},	/* 01,01,37,cc */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0d,cc */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},		/* 01,89,06,cc */
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},		/* 01,c5,03,cc */
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},		/* 01,cb,13,cc */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},	/* 02,50,08,cc */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},		/* 03,01,08,cc */
+	{0xa0, 0x58, ZC3XX_R116_RGAIN},			/* 01,16,58,cc */
+	{0xa0, 0x5a, ZC3XX_R118_BGAIN},			/* 01,18,5a,cc */
+	{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,02,cc */
+	{0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,d3,cc */
+	{0xbb, 0x00, 0x0408},				/* 04,00,08,bb */
+	{0xdd, 0x00, 0x0200},				/* 00,02,00,dd */
+	{0xbb, 0x00, 0x0400},				/* 04,00,00,bb */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x0f, 0x140f},				/* 14,0f,0f,bb */
+	{0xbb, 0xe0, 0x0c2e},				/* 0c,e0,2e,bb */
+	{0xbb, 0x01, 0x2000},				/* 20,01,00,bb */
+	{0xbb, 0x96, 0x2400},				/* 24,96,00,bb */
+	{0xbb, 0x06, 0x1006},				/* 10,06,06,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x5f, 0x2090},				/* 20,5f,90,bb */
+	{0xbb, 0x01, 0x8000},				/* 80,01,00,bb */
+	{0xbb, 0x09, 0x8400},				/* 84,09,00,bb */
+	{0xbb, 0x86, 0x0002},				/* 00,86,02,bb */
+	{0xbb, 0xe6, 0x0401},				/* 04,e6,01,bb */
+	{0xbb, 0x86, 0x0802},				/* 08,86,02,bb */
+	{0xbb, 0xe6, 0x0c01},				/* 0c,e6,01,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0000},				/* 00,fe,00,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0020},				/* 00,fe,20,aa */
+/*mswin+*/
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+	{0xaa, 0xfe, 0x0002},
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+	{0xaa, 0xb4, 0xcd37},
+	{0xaa, 0xa4, 0x0004},
+	{0xaa, 0xa8, 0x0007},
+	{0xaa, 0xac, 0x0004},
+/*mswin-*/
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0000},				/* 00,fe,00,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x04, 0x0400},				/* 04,04,00,bb */
+	{0xdd, 0x00, 0x0100},				/* 00,01,00,dd */
+	{0xbb, 0x01, 0x0400},				/* 04,01,00,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xbb, 0x41, 0x2803},				/* 28,41,03,bb */
+	{0xbb, 0x40, 0x2c03},				/* 2c,40,03,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
+	{}
+};
+static const struct usb_action adcm2700_InitialScale[] = {
+	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc */
+	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},		/* 00,02,10,cc */
+	{0xa0, 0x00, ZC3XX_R008_CLOCKSETTING},		/* 00,08,03,cc */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,d3,cc */
+	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},	/* 00,03,02,cc */
+	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},		/* 00,04,80,cc */
+	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},	/* 00,05,01,cc */
+	{0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW},	/* 00,06,d0,cc */
+	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},	/* 00,01,01,cc */
+	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,03,cc */
+	{0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,01,cc */
+	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,05,cc */
+	{0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},		/* 00,98,00,cc */
+	{0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},		/* 00,9a,00,cc */
+	{0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},		/* 01,1a,00,cc */
+	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},		/* 01,1c,00,cc */
+	{0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},		/* 00,9c,d8,cc */
+	{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},		/* 00,9e,88,cc */
+	{0xbb, 0x00, 0x0400},				/* 04,00,00,bb */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x0f, 0x140f},				/* 14,0f,0f,bb */
+	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},	/* 01,01,37,cc */
+	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0d,cc */
+	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},		/* 01,89,06,cc */
+	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},		/* 01,c5,03,cc */
+	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},		/* 01,cb,13,cc */
+	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},	/* 02,50,08,cc */
+	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},		/* 03,01,08,cc */
+	{0xa0, 0x58, ZC3XX_R116_RGAIN},			/* 01,16,58,cc */
+	{0xa0, 0x5a, ZC3XX_R118_BGAIN},			/* 01,18,5a,cc */
+	{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,02,cc */
+	{0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,d3,cc */
+	{0xbb, 0x00, 0x0408},				/* 04,00,08,bb */
+	{0xdd, 0x00, 0x0200},				/* 00,02,00,dd */
+	{0xbb, 0x00, 0x0400},				/* 04,00,00,bb */
+	{0xdd, 0x00, 0x0050},				/* 00,00,50,dd */
+	{0xbb, 0x0f, 0x140f},				/* 14,0f,0f,bb */
+	{0xbb, 0xe0, 0x0c2e},				/* 0c,e0,2e,bb */
+	{0xbb, 0x01, 0x2000},				/* 20,01,00,bb */
+	{0xbb, 0x96, 0x2400},				/* 24,96,00,bb */
+	{0xbb, 0x06, 0x1006},				/* 10,06,06,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x5f, 0x2090},				/* 20,5f,90,bb */
+	{0xbb, 0x01, 0x8000},				/* 80,01,00,bb */
+	{0xbb, 0x09, 0x8400},				/* 84,09,00,bb */
+	{0xbb, 0x86, 0x0002},				/* 00,88,02,bb */
+	{0xbb, 0xe6, 0x0401},				/* 04,e6,01,bb */
+	{0xbb, 0x86, 0x0802},				/* 08,88,02,bb */
+	{0xbb, 0xe6, 0x0c01},				/* 0c,e6,01,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0000},				/* 00,fe,00,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0020},				/* 00,fe,20,aa */
+	/*******/
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xaa, 0xfe, 0x0000},				/* 00,fe,00,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xdd, 0x00, 0x0010},				/* 00,00,10,dd */
+	{0xbb, 0x04, 0x0400},				/* 04,04,00,bb */
+	{0xdd, 0x00, 0x0100},				/* 00,01,00,dd */
+	{0xbb, 0x01, 0x0400},				/* 04,01,00,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xbb, 0x41, 0x2803},				/* 28,41,03,bb */
+	{0xbb, 0x40, 0x2c03},				/* 2c,40,03,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
+	{}
+};
+static const struct usb_action adcm2700_50HZ[] = {
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xbb, 0x05, 0x8400},				/* 84,05,00,bb */
+	{0xbb, 0xd0, 0xb007},				/* b0,d0,07,bb */
+	{0xbb, 0xa0, 0xb80f},				/* b8,a0,0f,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
+	{0xaa, 0x26, 0x00d0},				/* 00,26,d0,aa */
+	{0xaa, 0x28, 0x0002},				/* 00,28,02,aa */
+	{}
+};
+static const struct usb_action adcm2700_60HZ[] = {
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xbb, 0x07, 0x8400},				/* 84,07,00,bb */
+	{0xbb, 0x82, 0xb006},				/* b0,82,06,bb */
+	{0xbb, 0x04, 0xb80d},				/* b8,04,0d,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
+	{0xaa, 0x26, 0x0057},				/* 00,26,57,aa */
+	{0xaa, 0x28, 0x0002},				/* 00,28,02,aa */
+	{}
+};
+static const struct usb_action adcm2700_NoFliker[] = {
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0002},				/* 00,fe,02,aa */
+	{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,0a,cc */
+	{0xbb, 0x07, 0x8400},				/* 84,07,00,bb */
+	{0xbb, 0x05, 0xb000},				/* b0,05,00,bb */
+	{0xbb, 0xa0, 0xb801},				/* b8,a0,01,bb */
+	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc */
+	{0xaa, 0xfe, 0x0010},				/* 00,fe,10,aa */
+	{}
+};
 static const struct usb_action cs2102_Initial[] = {
 	{0xa1, 0x01, 0x0008},
 	{0xa1, 0x01, 0x0008},
@@ -877,7 +1091,7 @@ static const struct usb_action cs2102K_I
 };
 
 static const struct usb_action cs2102K_InitialScale[] = {
-	{0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
 	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
 	{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -894,6 +1108,7 @@ static const struct usb_action cs2102K_I
 	{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
 	{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
 	{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+/*fixme: next sequence = i2c exchanges*/
 	{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
 	{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
 	{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
@@ -1077,207 +1292,6 @@ static const struct usb_action cs2102K_I
 	{0xa0, 0x60, ZC3XX_R116_RGAIN},
 	{0xa0, 0x40, ZC3XX_R117_GGAIN},
 	{0xa0, 0x4c, ZC3XX_R118_BGAIN},
-	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
-	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
-	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
-	{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
-	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
-	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
-	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
-	{0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
-	{0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
-	{0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{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, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
-	{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
-	{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
-	{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
-	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},
-	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
-	{0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
-	{0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
-	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
-	{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
-	{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
-	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
-	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
-	{0xa0, 0x00, 0x01ad},
-	{0xa0, 0x01, 0x01b1},
-	{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x60, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x4c, ZC3XX_R118_BGAIN},
-	{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},	/* clock ? */
-	{0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},	/* sharpness+ */
-	{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, 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},
-	{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
-	{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
-	{0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
-	{0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
-	{0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
-	{0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
-	{0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
-	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
-	{0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
-	{0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
-	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
-	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
-	{0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
-	{0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
-	{0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
-	{0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
-	{0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
-	{0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
-	{0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
-	{0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
-	{0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
-	{0xa0, 0x60, ZC3XX_R116_RGAIN},
-	{0xa0, 0x40, ZC3XX_R117_GGAIN},
-	{0xa0, 0x4c, ZC3XX_R118_BGAIN},
 	{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
 	{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
 	{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
@@ -1334,6 +1348,7 @@ static const struct usb_action cs2102K_I
 	{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
 	{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
 	{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+/*fixme:what does the next sequence?*/
 	{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
 	{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
 	{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
@@ -6237,7 +6252,7 @@ static const struct usb_action tas5130c_
 	{}
 };
 
-static int reg_r_i(struct gspca_dev *gspca_dev,
+static u8 reg_r_i(struct gspca_dev *gspca_dev,
 		__u16 index)
 {
 	usb_control_msg(gspca_dev->dev,
@@ -6250,10 +6265,10 @@ static int reg_r_i(struct gspca_dev *gsp
 	return gspca_dev->usb_buf[0];
 }
 
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
 		__u16 index)
 {
-	int ret;
+	u8 ret;
 
 	ret = reg_r_i(gspca_dev, index);
 	PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
@@ -6286,8 +6301,8 @@ static __u16 i2c_read(struct gspca_dev *
 	__u8 retbyte;
 	__u16 retval;
 
-	reg_w_i(gspca_dev->dev, reg, 0x92);
-	reg_w_i(gspca_dev->dev, 0x02, 0x90);		/* <- read command */
+	reg_w_i(gspca_dev->dev, reg, 0x0092);
+	reg_w_i(gspca_dev->dev, 0x02, 0x0090);		/* <- read command */
 	msleep(25);
 	retbyte = reg_r_i(gspca_dev, 0x0091);		/* read status */
 	retval = reg_r_i(gspca_dev, 0x0095);		/* read Lowbyte */
@@ -6332,6 +6347,12 @@ static void usb_exchange(struct gspca_de
 				  action->idx & 0xff,		/* valL */
 				  action->idx >> 8);		/* valH */
 			break;
+		case 0xbb:
+			i2c_write(gspca_dev,
+				  action->idx >> 8,		/* reg */
+				  action->idx & 0xff,		/* valL */
+				  action->val);			/* valH */
+			break;
 		default:
 /*		case 0xdd:	 * delay */
 			msleep(action->val / 64 + 10);
@@ -6347,6 +6368,10 @@ static void setmatrix(struct gspca_dev *
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
 	const __u8 *matrix;
+	static const u8 adcm2700_matrix[9] =
+/*		{0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
+/*ms-win*/
+		{0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
 	static const __u8 gc0305_matrix[9] =
 		{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
 	static const __u8 ov7620_matrix[9] =
@@ -6358,23 +6383,24 @@ static void setmatrix(struct gspca_dev *
 	static const __u8 vf0250_matrix[9] =
 		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
 	static const __u8 *matrix_tb[SENSOR_MAX] = {
-		NULL,		/* SENSOR_CS2102 0 */
-		NULL,		/* SENSOR_CS2102K 1 */
-		gc0305_matrix,	/* SENSOR_GC0305 2 */
-		NULL,		/* SENSOR_HDCS2020b 3 */
-		NULL,		/* SENSOR_HV7131B 4 */
-		NULL,		/* SENSOR_HV7131C 5 */
-		NULL,		/* SENSOR_ICM105A 6 */
-		NULL,		/* SENSOR_MC501CB 7 */
-		ov7620_matrix,	/* SENSOR_OV7620 8 */
-		NULL,		/* SENSOR_OV7630C 9 */
-		NULL,		/* SENSOR_PAS106 10 */
-		pas202b_matrix,	/* SENSOR_PAS202B 11 */
-		NULL,		/* SENSOR_PB0330 12 */
-		po2030_matrix,	/* SENSOR_PO2030 13 */
-		NULL,		/* SENSOR_TAS5130CK 14 */
-		NULL,		/* SENSOR_TAS5130CXX 15 */
-		vf0250_matrix,	/* SENSOR_TAS5130C_VF0250 16 */
+		adcm2700_matrix, /* SENSOR_ADCM2700 0 */
+		NULL,		/* SENSOR_CS2102 1 */
+		NULL,		/* SENSOR_CS2102K 2 */
+		gc0305_matrix,	/* SENSOR_GC0305 3 */
+		NULL,		/* SENSOR_HDCS2020b 4 */
+		NULL,		/* SENSOR_HV7131B 5 */
+		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 */
 	};
 
 	matrix = matrix_tb[sd->sensor];
@@ -6398,8 +6424,11 @@ static void setbrightness(struct gspca_d
 /*fixme: is it really write to 011d and 018d for all other sensors? */
 	brightness = sd->brightness;
 	reg_w(gspca_dev->dev, brightness, 0x011d);
-	if (sd->sensor == SENSOR_HV7131B)
+	switch (sd->sensor) {
+	case SENSOR_ADCM2700:
+	case SENSOR_HV7131B:
 		return;
+	}
 	if (brightness < 0x70)
 		brightness += 0x10;
 	else
@@ -6536,10 +6565,10 @@ static void setquality(struct gspca_dev
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 quality;
 	__u8 frxt;
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_HV7131B:
 	case SENSOR_OV7620:
@@ -6547,26 +6576,18 @@ static void setquality(struct gspca_dev
 		return;
 	}
 /*fixme: is it really 0008 0007 0018 for all other sensors? */
-	quality = sd->qindex;
-	reg_w(dev, quality, 0x0008);
+	reg_w(dev, QUANT_VAL, 0x0008);
 	frxt = 0x30;
 	reg_w(dev, frxt, 0x0007);
-	switch (quality) {
-	case 0:
-	case 1:
-	case 2:
-		frxt = 0xff;
-		break;
-	case 3:
-		frxt = 0xf0;
-		break;
-	case 4:
-		frxt = 0xe0;
-		break;
-	case 5:
-		frxt = 0x20;
-		break;
-	}
+#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
+	frxt = 0xff;
+#elif QUANT_VAL == 3
+	frxt = 0xf0;
+#elif QUANT_VAL == 4
+	frxt = 0xe0;
+#else
+	frxt = 0x20;
+#endif
 	reg_w(dev, frxt, 0x0018);
 }
 
@@ -6583,71 +6604,75 @@ static int setlightfreq(struct gspca_dev
 	int i, mode;
 	const struct usb_action *zc3_freq;
 	static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
-/* SENSOR_CS2102 0 */
+/* SENSOR_ADCM2700 0 */
+		{adcm2700_NoFliker, adcm2700_NoFliker,
+		 adcm2700_50HZ, adcm2700_50HZ,
+		 adcm2700_60HZ, adcm2700_60HZ},
+/* SENSOR_CS2102 1 */
 		{cs2102_NoFliker, cs2102_NoFlikerScale,
 		 cs2102_50HZ, cs2102_50HZScale,
 		 cs2102_60HZ, cs2102_60HZScale},
-/* SENSOR_CS2102K 1 */
+/* SENSOR_CS2102K 2 */
 		{cs2102_NoFliker, cs2102_NoFlikerScale,
 		 NULL, NULL, /* currently disabled */
 		 NULL, NULL},
-/* SENSOR_GC0305 2 */
+/* SENSOR_GC0305 3 */
 		{gc0305_NoFliker, gc0305_NoFliker,
 		 gc0305_50HZ, gc0305_50HZ,
 		 gc0305_60HZ, gc0305_60HZ},
-/* SENSOR_HDCS2020b 3 */
+/* SENSOR_HDCS2020b 4 */
 		{hdcs2020b_NoFliker, hdcs2020b_NoFliker,
 		 hdcs2020b_50HZ, hdcs2020b_50HZ,
 		 hdcs2020b_60HZ, hdcs2020b_60HZ},
-/* SENSOR_HV7131B 4 */
+/* SENSOR_HV7131B 5 */
 		{hv7131b_NoFlikerScale, hv7131b_NoFliker,
 		 hv7131b_50HZScale, hv7131b_50HZ,
 		 hv7131b_60HZScale, hv7131b_60HZ},
-/* SENSOR_HV7131C 5 */
+/* SENSOR_HV7131C 6 */
 		{NULL, NULL,
 		 NULL, NULL,
 		 NULL, NULL},
-/* SENSOR_ICM105A 6 */
+/* SENSOR_ICM105A 7 */
 		{icm105a_NoFliker, icm105a_NoFlikerScale,
 		 icm105a_50HZ, icm105a_50HZScale,
 		 icm105a_60HZ, icm105a_60HZScale},
-/* SENSOR_MC501CB 7 */
+/* SENSOR_MC501CB 8 */
 		{MC501CB_NoFliker, MC501CB_NoFlikerScale,
 		 MC501CB_50HZ, MC501CB_50HZScale,
 		 MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 8 */
+/* SENSOR_OV7620 9 */
 		{OV7620_NoFliker, OV7620_NoFliker,
 		 OV7620_50HZ, OV7620_50HZ,
 		 OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 9 */
+/* SENSOR_OV7630C 10 */
 		{NULL, NULL,
 		 NULL, NULL,
 		 NULL, NULL},
-/* SENSOR_PAS106 10 */
+/* SENSOR_PAS106 11 */
 		{pas106b_NoFliker, pas106b_NoFliker,
 		 pas106b_50HZ, pas106b_50HZ,
 		 pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 11 */
+/* SENSOR_PAS202B 12 */
 		{pas202b_NoFlikerScale, pas202b_NoFliker,
 		 pas202b_50HZScale, pas202b_50HZ,
 		 pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 12 */
+/* SENSOR_PB0330 13 */
 		{pb0330_NoFliker, pb0330_NoFlikerScale,
 		 pb0330_50HZ, pb0330_50HZScale,
 		 pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 13 */
+/* SENSOR_PO2030 14 */
 		{PO2030_NoFliker, PO2030_NoFliker,
 		 PO2030_50HZ, PO2030_50HZ,
 		 PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 14 */
+/* SENSOR_TAS5130CK 15 */
 		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
 		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
 		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 15 */
+/* SENSOR_TAS5130CXX 16 */
 		{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
 		 tas5130cxx_50HZ, tas5130cxx_50HZScale,
 		 tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 16 */
+/* SENSOR_TAS5130C_VF0250 17 */
 		{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
 		 tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
 		 tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6701,6 +6726,7 @@ static void send_unknown(struct usb_devi
 		reg_w(dev, 0x0c, 0x003b);
 		reg_w(dev, 0x08, 0x0038);
 		break;
+	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
 	case SENSOR_PB0330:
@@ -6743,26 +6769,25 @@ static int sif_probe(struct gspca_dev *g
 static int vga_2wr_probe(struct gspca_dev *gspca_dev)
 {
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 retbyte;
-	__u16 checkword;
+	u16 retword;
 
 	start_2wr_probe(dev, 0x00);		/* HV7131B */
 	i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x01);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x01);
+	if (retword != 0)
 		return 0x00;			/* HV7131B */
 
 	start_2wr_probe(dev, 0x04);		/* CS2102 */
 	i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x01);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x01);
+	if (retword != 0)
 		return 0x04;			/* CS2102 */
 
 	start_2wr_probe(dev, 0x06);		/* OmniVision */
 	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x11);
-	if (retbyte != 0) {
+	retword = i2c_read(gspca_dev, 0x11);
+	if (retword != 0) {
 		/* (should have returned 0xaa) --> Omnivision? */
 		/* reg_r 0x10 -> 0x06 -->  */
 		goto ov_check;
@@ -6770,40 +6795,40 @@ static int vga_2wr_probe(struct gspca_de
 
 	start_2wr_probe(dev, 0x08);		/* HDCS2020 */
 	i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x15);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x15);
+	if (retword != 0)
 		return 0x08;			/* HDCS2020 */
 
 	start_2wr_probe(dev, 0x0a);		/* PB0330 */
 	i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
-	retbyte = i2c_read(gspca_dev, 0x07);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x07);
+	if (retword != 0)
 		return 0x0a;			/* PB0330 */
-	retbyte = i2c_read(gspca_dev, 0x03);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x03);
+	if (retword != 0)
 		return 0x0a;			/* PB0330 ?? */
-	retbyte = i2c_read(gspca_dev, 0x04);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x04);
+	if (retword != 0)
 		return 0x0a;			/* PB0330 ?? */
 
 	start_2wr_probe(dev, 0x0c);		/* ICM105A */
 	i2c_write(gspca_dev, 0x01, 0x11, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x01);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x01);
+	if (retword != 0)
 		return 0x0c;			/* ICM105A */
 
 	start_2wr_probe(dev, 0x0e);		/* PAS202BCB */
 	reg_w(dev, 0x08, 0x008d);
 	i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
 	msleep(500);
-	retbyte = i2c_read(gspca_dev, 0x03);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x03);
+	if (retword != 0)
 		return 0x0e;			/* PAS202BCB */
 
 	start_2wr_probe(dev, 0x02);		/* ?? */
 	i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
-	retbyte = i2c_read(gspca_dev, 0x01);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x01);
+	if (retword != 0)
 		return 0x02;			/* ?? */
 ov_check:
 	reg_r(gspca_dev, 0x0010);		/* ?? */
@@ -6817,12 +6842,10 @@ ov_check:
 	msleep(500);
 	reg_w(dev, 0x01, 0x0012);
 	i2c_write(gspca_dev, 0x12, 0x80, 0x00);	/* sensor reset */
-	retbyte = i2c_read(gspca_dev, 0x0a);
-	checkword = retbyte << 8;
-	retbyte = i2c_read(gspca_dev, 0x0b);
-	checkword |= retbyte;
-	PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
-	switch (checkword) {
+	retword = i2c_read(gspca_dev, 0x0a) << 8;
+	retword |= i2c_read(gspca_dev, 0x0b);
+	PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+	switch (retword) {
 	case 0x7631:				/* OV7630C */
 		reg_w(dev, 0x06, 0x0010);
 		break;
@@ -6832,7 +6855,7 @@ ov_check:
 	default:
 		return -1;			/* not OmniVision */
 	}
-	return checkword;
+	return retword;
 }
 
 struct sensor_by_chipset_revision {
@@ -6845,6 +6868,7 @@ static const struct sensor_by_chipset_re
 	{0x8001, 0x13},
 	{0x8000, 0x14},		/* CS2102K */
 	{0x8400, 0x15},		/* TAS5130K */
+	{0x4001, 0x16},		/* ADCM2700 */
 };
 
 static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6853,7 +6877,7 @@ static int vga_3wr_probe(struct gspca_de
 	struct usb_device *dev = gspca_dev->dev;
 	int i;
 	__u8 retbyte;
-	__u16 checkword;
+	u16 retword;
 
 /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
 	reg_w(dev, 0x02, 0x0010);
@@ -6865,27 +6889,25 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x03, 0x0012);
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0012);
-	retbyte = i2c_read(gspca_dev, 0x14);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x14);
+	if (retword != 0)
 		return 0x11;			/* HV7131R */
-	retbyte = i2c_read(gspca_dev, 0x15);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x15);
+	if (retword != 0)
 		return 0x11;			/* HV7131R */
-	retbyte = i2c_read(gspca_dev, 0x16);
-	if (retbyte != 0)
+	retword = i2c_read(gspca_dev, 0x16);
+	if (retword != 0)
 		return 0x11;			/* HV7131R */
 
 	reg_w(dev, 0x02, 0x0010);
-	retbyte = reg_r(gspca_dev, 0x000b);
-	checkword = retbyte << 8;
-	retbyte = reg_r(gspca_dev, 0x000a);
-	checkword |= retbyte;
-	PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+	retword = reg_r(gspca_dev, 0x000b) << 8;
+	retword |= reg_r(gspca_dev, 0x000a);
+	PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
 	reg_r(gspca_dev, 0x0010);
 	/* this is tested only once anyway */
 	for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
-		if (chipset_revision_sensor[i].revision == checkword) {
-			sd->chip_revision = checkword;
+		if (chipset_revision_sensor[i].revision == retword) {
+			sd->chip_revision = retword;
 			send_unknown(dev, SENSOR_PB0330);
 			return chipset_revision_sensor[i].internal_sensor_id;
 		}
@@ -6897,8 +6919,8 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x0a, 0x0010);
 	reg_w(dev, 0x03, 0x0012);
 	reg_w(dev, 0x01, 0x0012);
-	retbyte = i2c_read(gspca_dev, 0x00);
-	if (retbyte != 0) {
+	retword = i2c_read(gspca_dev, 0x00);
+	if (retword != 0) {
 		PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
 		return 0x0a;			/* ?? */
 	}
@@ -6910,14 +6932,14 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x03, 0x0012);
 	msleep(2);
 	reg_w(dev, 0x01, 0x0012);
-	retbyte = i2c_read(gspca_dev, 0x00);
-	if (retbyte != 0) {
-		PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
-		if (retbyte == 0x11)			/* VF0250 */
+	retword = i2c_read(gspca_dev, 0x00);
+	if (retword != 0) {
+		PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+		if (retword == 0x0011)			/* VF0250 */
 			return 0x0250;
-		if (retbyte == 0x29)			/* gc0305 */
+		if (retword == 0x0029)			/* gc0305 */
 			send_unknown(dev, SENSOR_GC0305);
-		return retbyte;
+		return retword;
 	}
 
 	reg_w(dev, 0x01, 0x0000);	/* check OmniVision */
@@ -6927,8 +6949,8 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x06, 0x0010);
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0012);
-	if (i2c_read(gspca_dev, 0x1c) == 0x7f	/* OV7610 - manufacturer ID */
-	    && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+	if (i2c_read(gspca_dev, 0x1c) == 0x007f	/* OV7610 - manufacturer ID */
+	    && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
 		send_unknown(dev, SENSOR_OV7620);
 		return 0x06;		/* OmniVision confirm ? */
 	}
@@ -6942,16 +6964,14 @@ static int vga_3wr_probe(struct gspca_de
 /*	msleep(150); */
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0012);
-	retbyte = i2c_read(gspca_dev, 0x0000);		/* ID 0 */
-	checkword = retbyte << 8;
-	retbyte = i2c_read(gspca_dev, 0x0001);		/* ID 1 */
-	checkword |= retbyte;
-	PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
-	if (checkword == 0x2030) {
+	retword = i2c_read(gspca_dev, 0x00) << 8;	/* ID 0 */
+	retword |= i2c_read(gspca_dev, 0x01);		/* ID 1 */
+	PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+	if (retword == 0x2030) {
 		retbyte = i2c_read(gspca_dev, 0x02);	/* revision number */
 		PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
 		send_unknown(dev, SENSOR_PO2030);
-		return checkword;
+		return retword;
 	}
 
 	reg_w(dev, 0x01, 0x0000);
@@ -6962,10 +6982,10 @@ static int vga_3wr_probe(struct gspca_de
 	reg_w(dev, 0x01, 0x0012);
 	reg_w(dev, 0x05, 0x0001);
 	reg_w(dev, 0xd3, 0x008b);
-	retbyte = i2c_read(gspca_dev, 0x01);
-	if (retbyte != 0) {
-		PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
-		return 0x0a;			/* ?? */
+	retword = i2c_read(gspca_dev, 0x01);
+	if (retword != 0) {
+		PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+		return retword;
 	}
 	return -1;
 }
@@ -6973,7 +6993,7 @@ static int vga_3wr_probe(struct gspca_de
 static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int sensor, sensor2;
+	int sensor;
 
 	switch (sd->sensor) {
 	case SENSOR_MC501CB:
@@ -6988,16 +7008,9 @@ static int zcxx_probeSensor(struct gspca
 		break;
 	}
 	sensor = vga_2wr_probe(gspca_dev);
-	if (sensor >= 0) {
-		if (sensor < 0x7600)
-			return sensor;
-		/* next probe is needed for OmniVision ? */
-	}
-	sensor2 = vga_3wr_probe(gspca_dev);
-	if (sensor2 >= 0
-	    && sensor >= 0)
+	if (sensor >= 0)
 		return sensor;
-	return sensor2;
+	return vga_3wr_probe(gspca_dev);
 }
 
 /* this function is called at probe time */
@@ -7009,23 +7022,24 @@ static int sd_config(struct gspca_dev *g
 	int sensor;
 	int vga = 1;		/* 1: vga, 0: sif */
 	static const __u8 gamma[SENSOR_MAX] = {
-		5,	/* SENSOR_CS2102 0 */
-		5,	/* SENSOR_CS2102K 1 */
-		4,	/* SENSOR_GC0305 2 */
-		4,	/* SENSOR_HDCS2020b 3 */
-		4,	/* SENSOR_HV7131B 4 */
-		4,	/* SENSOR_HV7131C 5 */
-		4,	/* SENSOR_ICM105A 6 */
-		4,	/* SENSOR_MC501CB 7 */
-		3,	/* SENSOR_OV7620 8 */
-		4,	/* SENSOR_OV7630C 9 */
-		4,	/* SENSOR_PAS106 10 */
-		4,	/* SENSOR_PAS202B 11 */
-		4,	/* SENSOR_PB0330 12 */
-		4,	/* SENSOR_PO2030 13 */
-		4,	/* SENSOR_TAS5130CK 14 */
-		4,	/* SENSOR_TAS5130CXX 15 */
-		3,	/* SENSOR_TAS5130C_VF0250 16 */
+		4,	/* SENSOR_ADCM2700 0 */
+		5,	/* SENSOR_CS2102 1 */
+		5,	/* SENSOR_CS2102K 2 */
+		4,	/* SENSOR_GC0305 3 */
+		4,	/* SENSOR_HDCS2020b 4 */
+		4,	/* SENSOR_HV7131B 5 */
+		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 */
 	};
 
 	/* define some sensors from the vendor/product */
@@ -7033,7 +7047,7 @@ static int sd_config(struct gspca_dev *g
 	sd->sensor = id->driver_info;
 	sensor = zcxx_probeSensor(gspca_dev);
 	if (sensor >= 0)
-		PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+		PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
 	if ((unsigned) force_sensor < SENSOR_MAX) {
 		sd->sensor = force_sensor;
 		PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
@@ -7112,6 +7126,10 @@ static int sd_config(struct gspca_dev *g
 				sd->chip_revision);
 			sd->sensor = SENSOR_TAS5130CK;
 			break;
+		case 0x16:
+			PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+			sd->sensor = SENSOR_ADCM2700;
+			break;
 		case 0x29:
 			PDEBUG(D_PROBE, "Find Sensor GC0305");
 			sd->sensor = SENSOR_GC0305;
@@ -7129,12 +7147,16 @@ static int sd_config(struct gspca_dev *g
 			PDEBUG(D_PROBE, "Find Sensor OV7620");
 			sd->sensor = SENSOR_OV7620;
 			break;
+		case 0x7631:
+			PDEBUG(D_PROBE, "Find Sensor OV7630C");
+			sd->sensor = SENSOR_OV7630C;
+			break;
 		case 0x7648:
 			PDEBUG(D_PROBE, "Find Sensor OV7648");
 			sd->sensor = SENSOR_OV7620;	/* same sensor (?) */
 			break;
 		default:
-			PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+			PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor);
 			return -EINVAL;
 		}
 	}
@@ -7147,7 +7169,6 @@ static int sd_config(struct gspca_dev *g
 	}
 
 	cam = &gspca_dev->cam;
-	cam->epaddr = 0x01;
 /*fixme:test*/
 	gspca_dev->nbalt--;
 	if (vga) {
@@ -7157,12 +7178,12 @@ static int sd_config(struct gspca_dev *g
 		cam->cam_mode = sif_mode;
 		cam->nmodes = ARRAY_SIZE(sif_mode);
 	}
-	sd->qindex = 1;
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->gamma = gamma[(int) sd->sensor];
 	sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
 	sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
+	sd->quality = QUALITY_DEF;
 
 	switch (sd->sensor) {
 	case SENSOR_GC0305:
@@ -7196,27 +7217,34 @@ static int sd_start(struct gspca_dev *gs
 	const struct usb_action *zc3_init;
 	int mode;
 	static const struct usb_action *init_tb[SENSOR_MAX][2] = {
-		{cs2102_InitialScale, cs2102_Initial},		/* 0 */
-		{cs2102K_InitialScale, cs2102K_Initial},	/* 1 */
-		{gc0305_Initial, gc0305_InitialScale},		/* 2 */
-		{hdcs2020xb_InitialScale, hdcs2020xb_Initial},	/* 3 */
-		{hv7131bxx_InitialScale, hv7131bxx_Initial},	/* 4 */
-		{hv7131cxx_InitialScale, hv7131cxx_Initial},	/* 5 */
-		{icm105axx_InitialScale, icm105axx_Initial},	/* 6 */
-		{MC501CB_InitialScale, MC501CB_Initial},	/* 7 */
-		{OV7620_mode0, OV7620_mode1},			/* 8 */
-		{ov7630c_InitialScale, ov7630c_Initial},	/* 9 */
-		{pas106b_InitialScale, pas106b_Initial},	/* 10 */
-		{pas202b_Initial, pas202b_InitialScale},	/* 11 */
-		{pb0330xx_InitialScale, pb0330xx_Initial},	/* 12 */
+		{adcm2700_Initial, adcm2700_InitialScale},	/* 0 */
+		{cs2102_InitialScale, cs2102_Initial},		/* 1 */
+		{cs2102K_InitialScale, cs2102K_Initial},	/* 2 */
+		{gc0305_Initial, gc0305_InitialScale},		/* 3 */
+		{hdcs2020xb_InitialScale, hdcs2020xb_Initial},	/* 4 */
+		{hv7131bxx_InitialScale, hv7131bxx_Initial},	/* 5 */
+		{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},			/* 13 */
-		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 14 */
-		{tas5130cxx_InitialScale, tas5130cxx_Initial},	/* 15 */
+		{PO2030_mode0, PO2030_mode1},			/* 14 */
+		{tas5130CK_InitialScale, tas5130CK_Initial},	/* 15 */
+		{tas5130cxx_InitialScale, tas5130cxx_Initial},	/* 16 */
 		{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
-								/* 16 */
+								/* 17 */
 	};
 
+	/* create the JPEG header */
+	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x21);		/* JPEG 422 */
+	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 	zc3_init = init_tb[(int) sd->sensor][mode];
 	switch (sd->sensor) {
@@ -7243,11 +7271,12 @@ static int sd_start(struct gspca_dev *gs
 	usb_exchange(gspca_dev, zc3_init);
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM2700:
 	case SENSOR_GC0305:
 	case SENSOR_OV7620:
 	case SENSOR_PO2030:
 	case SENSOR_TAS5130C_VF0250:
-		msleep(100);			/* ?? */
+/*		msleep(100);			 * ?? */
 		reg_r(gspca_dev, 0x0002);	/* --> 0x40 */
 		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
 		reg_w(dev, 0x15, 0x01ae);
@@ -7260,6 +7289,7 @@ static int sd_start(struct gspca_dev *gs
 	setmatrix(gspca_dev);
 	setbrightness(gspca_dev);
 	switch (sd->sensor) {
+	case SENSOR_ADCM2700:
 	case SENSOR_OV7620:
 		reg_r(gspca_dev, 0x0008);
 		reg_w(dev, 0x00, 0x0008);
@@ -7301,6 +7331,13 @@ static int sd_start(struct gspca_dev *gs
 	setlightfreq(gspca_dev);
 
 	switch (sd->sensor) {
+	case SENSOR_ADCM2700:
+		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
+		reg_w(dev, 0x15, 0x01ae);
+		reg_w(dev, 0x02, 0x0180);
+						/* ms-win + */
+		reg_w(dev, 0x40, 0x0117);
+		break;
 	case SENSOR_GC0305:
 		reg_w(dev, 0x09, 0x01ad);	/* (from win traces) */
 		reg_w(dev, 0x15, 0x01ae);
@@ -7323,19 +7360,16 @@ static int sd_start(struct gspca_dev *gs
 
 	setautogain(gspca_dev);
 	switch (sd->sensor) {
-	case SENSOR_PAS202B:
-		reg_w(dev, 0x00, 0x0007);	/* (from win traces) */
-		break;
 	case SENSOR_PO2030:
 		msleep(500);
 		reg_r(gspca_dev, 0x0008);
 		reg_r(gspca_dev, 0x0007);
+		/*fall thru*/
+	case SENSOR_PAS202B:
 		reg_w(dev, 0x00, 0x0007);	/* (from win traces) */
-		reg_w(dev, 0x02, 0x0008);
+		reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
 		break;
 	}
-	if (sd->sensor == SENSOR_PAS202B)
-		reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
 	return 0;
 }
 
@@ -7344,6 +7378,7 @@ static void sd_stop0(struct gspca_dev *g
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	kfree(sd->jpeg_hdr);
 	if (!gspca_dev->present)
 		return;
 	send_unknown(gspca_dev->dev, sd->sensor);
@@ -7354,14 +7389,15 @@ static void sd_pkt_scan(struct gspca_dev
 			__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);
 		/* put the JPEG header in the new frame */
-		jpeg_put_header(gspca_dev, frame,
-				((struct sd *) gspca_dev)->qindex,
-				0x21);
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+			sd->jpeg_hdr, JPEG_HDR_SZ);
+
 		/* remove the webcam's header:
 		 * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
 		 *	- 'ss ss' is the frame sequence number (BE)
@@ -7503,6 +7539,34 @@ static int sd_querymenu(struct gspca_dev
 	return -EINVAL;
 }
 
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming)
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
@@ -7513,6 +7577,8 @@ static const struct sd_desc sd_desc = {
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
 };
 
 static const __devinitdata struct usb_device_id device_table[] = {
@@ -7563,11 +7629,9 @@ static const __devinitdata struct usb_de
 	{USB_DEVICE(0x055f, 0xd004)},
 	{USB_DEVICE(0x0698, 0x2003)},
 	{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
-	{USB_DEVICE(0x0ac8, 0x0302)},
+	{USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x0ac8, 0x301b)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
 	{USB_DEVICE(0x0ac8, 0x303b)},
-#endif
 	{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
 	{USB_DEVICE(0x0ac8, 0x307b)},
 	{USB_DEVICE(0x10fd, 0x0128)},
@@ -7600,8 +7664,10 @@ static struct usb_driver sd_driver = {
 
 static int __init sd_mod_init(void)
 {
-	if (usb_register(&sd_driver) < 0)
-		return -1;
+	int ret;
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
 	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-control.c linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-control.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-control.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-control.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,201 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008      Janne Grunau (j@jannau.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, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
+{
+	int ret;
+	char request_type = 0x38, snd_request = 0x01;
+
+	msleep(10);
+
+	mutex_lock(&dev->usbc_mutex);
+	dev->usbc_buf[0] = valbuf;
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      snd_request, 0x00 | request_type,
+			      value, CTRL_DEFAULT_INDEX,
+			      dev->usbc_buf, 1, 10000);
+
+	mutex_unlock(&dev->usbc_mutex);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "config call request for value 0x%x returned %d\n", value,
+		 ret);
+
+	return ret < 0 ? ret : 0;
+}
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+{
+	struct hdpvr_video_info *vidinf = NULL;
+#ifdef HDPVR_DEBUG
+	char print_buf[15];
+#endif
+	int ret;
+
+	vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
+	if (!vidinf) {
+		v4l2_err(&dev->v4l2_dev, "out of memory\n");
+		goto err;
+	}
+
+	mutex_lock(&dev->usbc_mutex);
+	ret = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      0x81, 0x80 | 0x38,
+			      0x1400, 0x0003,
+			      dev->usbc_buf, 5,
+			      1000);
+	if (ret == 5) {
+		vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+		vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+		vidinf->fps	= dev->usbc_buf[4];
+	}
+
+#ifdef HDPVR_DEBUG
+	if (hdpvr_debug & MSG_INFO) {
+		hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
+				   sizeof(print_buf), 0);
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+			 "get video info returned: %d, %s\n", ret, print_buf);
+	}
+#endif
+	mutex_unlock(&dev->usbc_mutex);
+
+	if (!vidinf->width || !vidinf->height || !vidinf->fps) {
+		kfree(vidinf);
+		vidinf = NULL;
+	}
+err:
+	return vidinf;
+}
+
+int get_input_lines_info(struct hdpvr_device *dev)
+{
+#ifdef HDPVR_DEBUG
+	char print_buf[9];
+#endif
+	int ret, lines;
+
+	mutex_lock(&dev->usbc_mutex);
+	ret = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      0x81, 0x80 | 0x38,
+			      0x1800, 0x0003,
+			      dev->usbc_buf, 3,
+			      1000);
+
+#ifdef HDPVR_DEBUG
+	if (hdpvr_debug & MSG_INFO) {
+		hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
+				   sizeof(print_buf), 0);
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+			 "get input lines info returned: %d, %s\n", ret,
+			 print_buf);
+	}
+#endif
+	lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+	mutex_unlock(&dev->usbc_mutex);
+	return lines;
+}
+
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev)
+{
+	int ret;
+
+	mutex_lock(&dev->usbc_mutex);
+	memset(dev->usbc_buf, 0, 4);
+	dev->usbc_buf[0] = dev->options.bitrate;
+	dev->usbc_buf[2] = dev->options.peak_bitrate;
+
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      0x01, 0x38, CTRL_BITRATE_VALUE,
+			      CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);
+	mutex_unlock(&dev->usbc_mutex);
+
+	return ret;
+}
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+		    enum v4l2_mpeg_audio_encoding codec)
+{
+	int ret = 0;
+
+	if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+		mutex_lock(&dev->usbc_mutex);
+		memset(dev->usbc_buf, 0, 2);
+		dev->usbc_buf[0] = input;
+		if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)
+			dev->usbc_buf[1] = 0;
+		else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)
+			dev->usbc_buf[1] = 1;
+		else {
+			mutex_unlock(&dev->usbc_mutex);
+			v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
+				 codec);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		ret = usb_control_msg(dev->udev,
+				      usb_sndctrlpipe(dev->udev, 0),
+				      0x01, 0x38, CTRL_AUDIO_INPUT_VALUE,
+				      CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,
+				      1000);
+		mutex_unlock(&dev->usbc_mutex);
+		if (ret == 2)
+			ret = 0;
+	} else
+		ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE,
+					dev->options.audio_input+1);
+error:
+	return ret;
+}
+
+int hdpvr_set_options(struct hdpvr_device *dev)
+{
+       hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
+
+       hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
+			 dev->options.video_input+1);
+
+       hdpvr_set_audio(dev, dev->options.audio_input+1,
+		       dev->options.audio_codec);
+
+       hdpvr_set_bitrate(dev);
+       hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+			 dev->options.bitrate_mode);
+       hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
+
+       hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
+       hdpvr_config_call(dev, CTRL_CONTRAST,   dev->options.contrast);
+       hdpvr_config_call(dev, CTRL_HUE,        dev->options.hue);
+       hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
+       hdpvr_config_call(dev, CTRL_SHARPNESS,  dev->options.sharpness);
+
+       return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-core.c linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,466 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2008      Janne Grunau (j@jannau.net)
+ * Copyright (C) 2008      John Poet
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET};
+module_param_array(video_nr, int, NULL, 0);
+MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+
+/* holds the number of currently registered devices */
+static atomic_t dev_nr = ATOMIC_INIT(-1);
+
+int hdpvr_debug;
+module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
+
+uint default_video_input = HDPVR_VIDEO_INPUTS;
+module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
+		 "1=S-Video / 2=Composite");
+
+uint default_audio_input = HDPVR_AUDIO_INPUTS;
+module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
+		 "1=RCA front / 2=S/PDIF");
+
+static int boost_audio;
+module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(boost_audio, "boost the audio signal");
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id hdpvr_table[] = {
+	{ USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
+	{ USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
+	{ USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
+	{ }					/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, hdpvr_table);
+
+
+void hdpvr_delete(struct hdpvr_device *dev)
+{
+	hdpvr_free_buffers(dev);
+
+	if (dev->video_dev)
+		video_device_release(dev->video_dev);
+
+	usb_put_dev(dev->udev);
+}
+
+static void challenge(u8 *bytes)
+{
+	u64 *i64P, tmp64;
+	uint i, idx;
+
+	for (idx = 0; idx < 32; ++idx) {
+
+		if (idx & 0x3)
+			bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3];
+
+		switch (idx & 0x3) {
+		case 0x3:
+			bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
+			bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
+			break;
+		case 0x1:
+			bytes[0] *= 8;
+			bytes[0] += 7*idx + 4;
+			bytes[6] += bytes[3] * 3;
+			break;
+		case 0x0:
+			bytes[3 - (idx >> 3)] = bytes[idx >> 2];
+			bytes[5] += bytes[6] * 3;
+			for (i = 0; i < 3; i++)
+				bytes[3] *= bytes[3] + 1;
+			break;
+		case 0x2:
+			for (i = 0; i < 3; i++)
+				bytes[1] *= bytes[6] + 1;
+			for (i = 0; i < 3; i++) {
+				i64P = (u64 *)bytes;
+				tmp64 = le64_to_cpup(i64P);
+				tmp64 <<= bytes[7] & 0x0f;
+				*i64P += cpu_to_le64(tmp64);
+			}
+			break;
+		}
+	}
+}
+
+/* try to init the device like the windows driver */
+static int device_authorization(struct hdpvr_device *dev)
+{
+
+	int ret, retval = -ENOMEM;
+	char request_type = 0x38, rcv_request = 0x81;
+	char *response;
+#ifdef HDPVR_DEBUG
+	size_t buf_size = 46;
+	char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
+	if (!print_buf) {
+		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+		goto error;
+	}
+#endif
+
+	mutex_lock(&dev->usbc_mutex);
+	ret = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      rcv_request, 0x80 | request_type,
+			      0x0400, 0x0003,
+			      dev->usbc_buf, 46,
+			      10000);
+	if (ret != 46) {
+		v4l2_err(&dev->v4l2_dev,
+			 "unexpected answer of status request, len %d\n", ret);
+		goto error;
+	}
+#ifdef HDPVR_DEBUG
+	else {
+		hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
+				   sizeof(print_buf), 0);
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+			 "Status request returned, len %d: %s\n",
+			 ret, print_buf);
+	}
+#endif
+	if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
+		dev->flags &= ~HDPVR_FLAG_AC3_CAP;
+	} else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
+		dev->flags |= HDPVR_FLAG_AC3_CAP;
+	} else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
+		v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, "
+			  "the driver might not work\n", dev->usbc_buf[1]);
+		dev->flags |= HDPVR_FLAG_AC3_CAP;
+	} else {
+		v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
+			dev->usbc_buf[1]);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	response = dev->usbc_buf+38;
+#ifdef HDPVR_DEBUG
+	hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 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);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
+		 print_buf);
+#endif
+
+	msleep(100);
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      0xd1, 0x00 | request_type,
+			      0x0000, 0x0000,
+			      response, 8,
+			      10000);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "magic request returned %d\n", ret);
+	mutex_unlock(&dev->usbc_mutex);
+
+	retval = ret != 8;
+error:
+	return retval;
+}
+
+static int hdpvr_device_init(struct hdpvr_device *dev)
+{
+	int ret;
+	u8 *buf;
+	struct hdpvr_video_info *vidinf;
+
+	if (device_authorization(dev))
+		return -EACCES;
+
+	/* default options for init */
+	hdpvr_set_options(dev);
+
+	/* set filter options */
+	mutex_lock(&dev->usbc_mutex);
+	buf = dev->usbc_buf;
+	buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      0x01, 0x38,
+			      CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
+			      buf, 4,
+			      1000);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "control request returned %d\n", ret);
+	mutex_unlock(&dev->usbc_mutex);
+
+	vidinf = get_video_info(dev);
+	if (!vidinf)
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+			"no valid video signal or device init failed\n");
+	else
+		kfree(vidinf);
+
+	/* enable fan and bling leds */
+	mutex_lock(&dev->usbc_mutex);
+	buf[0] = 0x1;
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      0xd4, 0x38, 0, 0, buf, 1,
+			      1000);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "control request returned %d\n", ret);
+
+	/* boost analog audio */
+	buf[0] = boost_audio;
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      0xd5, 0x38, 0, 0, buf, 1,
+			      1000);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "control request returned %d\n", ret);
+	mutex_unlock(&dev->usbc_mutex);
+
+	dev->status = STATUS_IDLE;
+	return 0;
+}
+
+static const struct hdpvr_options hdpvr_default_options = {
+	.video_std	= HDPVR_60HZ,
+	.video_input	= HDPVR_COMPONENT,
+	.audio_input	= HDPVR_RCA_BACK,
+	.bitrate	= 65, /* 6 mbps */
+	.peak_bitrate	= 90, /* 9 mbps */
+	.bitrate_mode	= HDPVR_CONSTANT,
+	.gop_mode	= HDPVR_SIMPLE_IDR_GOP,
+	.audio_codec	= V4L2_MPEG_AUDIO_ENCODING_AAC,
+	.brightness	= 0x86,
+	.contrast	= 0x80,
+	.hue		= 0x80,
+	.saturation	= 0x80,
+	.sharpness	= 0x80,
+};
+
+static int hdpvr_probe(struct usb_interface *interface,
+		       const struct usb_device_id *id)
+{
+	struct hdpvr_device *dev;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	size_t buffer_size;
+	int i;
+	int retval = -ENOMEM;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		err("Out of memory");
+		goto error;
+	}
+
+	/* register v4l2_device early so it can be used for printks */
+	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+		err("v4l2_device_register failed");
+		goto error;
+	}
+
+	mutex_init(&dev->io_mutex);
+	mutex_init(&dev->i2c_mutex);
+	mutex_init(&dev->usbc_mutex);
+	dev->usbc_buf = kmalloc(64, GFP_KERNEL);
+	if (!dev->usbc_buf) {
+		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+		goto error;
+	}
+
+	init_waitqueue_head(&dev->wait_buffer);
+	init_waitqueue_head(&dev->wait_data);
+
+	dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
+	if (!dev->workqueue)
+		goto error;
+
+	/* init video transfer queues */
+	INIT_LIST_HEAD(&dev->free_buff_list);
+	INIT_LIST_HEAD(&dev->rec_buff_list);
+
+	dev->options = hdpvr_default_options;
+
+	if (default_video_input < HDPVR_VIDEO_INPUTS)
+		dev->options.video_input = default_video_input;
+
+	if (default_audio_input < HDPVR_AUDIO_INPUTS)
+		dev->options.audio_input = default_audio_input;
+
+	dev->udev = usb_get_dev(interface_to_usbdev(interface));
+
+	/* set up the endpoint information */
+	/* use only the first bulk-in and bulk-out endpoints */
+	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if (!dev->bulk_in_endpointAddr &&
+		    usb_endpoint_is_bulk_in(endpoint)) {
+			/* USB interface description is buggy, reported max
+			 * packet size is 512 bytes, windows driver uses 8192 */
+			buffer_size = 8192;
+			dev->bulk_in_size = buffer_size;
+			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+		}
+
+	}
+	if (!dev->bulk_in_endpointAddr) {
+		v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
+		goto error;
+	}
+
+	/* init the device */
+	if (hdpvr_device_init(dev)) {
+		v4l2_err(&dev->v4l2_dev, "device init failed\n");
+		goto error;
+	}
+
+	mutex_lock(&dev->io_mutex);
+	if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
+		v4l2_err(&dev->v4l2_dev,
+			 "allocating transfer buffers failed\n");
+		goto error;
+	}
+	mutex_unlock(&dev->io_mutex);
+
+	if (hdpvr_register_videodev(dev, &interface->dev,
+				    video_nr[atomic_inc_return(&dev_nr)])) {
+		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+		goto error;
+	}
+
+#ifdef CONFIG_I2C
+	/* until i2c is working properly */
+	retval = 0; /* hdpvr_register_i2c_adapter(dev); */
+	if (retval < 0) {
+		v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
+		goto error;
+	}
+#endif /* CONFIG_I2C */
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, dev);
+
+	/* let the user know what node this device is now attached to */
+	v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
+		  dev->video_dev->minor);
+	return 0;
+
+error:
+	if (dev) {
+		mutex_unlock(&dev->io_mutex);
+		/* this frees allocated memory */
+		hdpvr_delete(dev);
+	}
+	return retval;
+}
+
+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;
+	v4l2_device_disconnect(&dev->v4l2_dev);
+	video_unregister_device(dev->video_dev);
+	wake_up_interruptible(&dev->wait_data);
+	wake_up_interruptible(&dev->wait_buffer);
+	mutex_unlock(&dev->io_mutex);
+	msleep(100);
+	flush_workqueue(dev->workqueue);
+	mutex_lock(&dev->io_mutex);
+	hdpvr_cancel_queue(dev);
+	destroy_workqueue(dev->workqueue);
+	mutex_unlock(&dev->io_mutex);
+
+	/* deregister I2C adapter */
+#ifdef CONFIG_I2C
+	mutex_lock(&dev->i2c_mutex);
+	if (dev->i2c_adapter)
+		i2c_del_adapter(dev->i2c_adapter);
+	kfree(dev->i2c_adapter);
+	dev->i2c_adapter = NULL;
+	mutex_unlock(&dev->i2c_mutex);
+#endif /* CONFIG_I2C */
+
+	atomic_dec(&dev_nr);
+
+	v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+
+	v4l2_device_unregister(&dev->v4l2_dev);
+	kfree(dev->usbc_buf);
+	kfree(dev);
+}
+
+
+static struct usb_driver hdpvr_usb_driver = {
+	.name =		"hdpvr",
+	.probe =	hdpvr_probe,
+	.disconnect =	hdpvr_disconnect,
+	.id_table =	hdpvr_table,
+};
+
+static int __init hdpvr_init(void)
+{
+	int result;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&hdpvr_usb_driver);
+	if (result)
+		err("usb_register failed. Error number %d", result);
+
+	return result;
+}
+
+static void __exit hdpvr_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&hdpvr_usb_driver);
+}
+
+module_init(hdpvr_init);
+module_exit(hdpvr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Janne Grunau");
+MODULE_DESCRIPTION("Hauppauge HD PVR driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr.h linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,303 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008      Janne Grunau (j@jannau.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, version 2.
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+
+#define HDPVR_MAJOR_VERSION 0
+#define HDPVR_MINOR_VERSION 2
+#define HDPVR_RELEASE 0
+#define HDPVR_VERSION \
+	KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
+
+#define HDPVR_MAX 8
+
+/* Define these values to match your devices */
+#define HD_PVR_VENDOR_ID	0x2040
+#define HD_PVR_PRODUCT_ID	0x4900
+#define HD_PVR_PRODUCT_ID1	0x4901
+#define HD_PVR_PRODUCT_ID2	0x4902
+
+#define UNSET    (-1U)
+
+#define NUM_BUFFERS 64
+
+#define HDPVR_FIRMWARE_VERSION		0x8
+#define HDPVR_FIRMWARE_VERSION_AC3	0xd
+
+/* #define HDPVR_DEBUG */
+
+extern int hdpvr_debug;
+
+#define MSG_INFO	1
+#define MSG_BUFFER	2
+
+struct hdpvr_options {
+	u8	video_std;
+	u8	video_input;
+	u8	audio_input;
+	u8	bitrate;	/* in 100kbps */
+	u8	peak_bitrate;	/* in 100kbps */
+	u8	bitrate_mode;
+	u8	gop_mode;
+	enum v4l2_mpeg_audio_encoding	audio_codec;
+	u8	brightness;
+	u8	contrast;
+	u8	hue;
+	u8	saturation;
+	u8	sharpness;
+};
+
+/* Structure to hold all of our device specific stuff */
+struct hdpvr_device {
+	/* the v4l device for this device */
+	struct video_device	*video_dev;
+	/* the usb device for this device */
+	struct usb_device	*udev;
+	/* v4l2-device unused */
+	struct v4l2_device	v4l2_dev;
+
+	/* the max packet size of the bulk endpoint */
+	size_t			bulk_in_size;
+	/* the address of the bulk in endpoint */
+	__u8			bulk_in_endpointAddr;
+
+	/* holds the current device status */
+	__u8			status;
+	/* count the number of openers */
+	uint			open_count;
+
+	/* holds the cureent set options */
+	struct hdpvr_options	options;
+
+	uint			flags;
+
+	/* synchronize I/O */
+	struct mutex		io_mutex;
+	/* available buffers */
+	struct list_head	free_buff_list;
+	/* in progress buffers */
+	struct list_head	rec_buff_list;
+	/* waitqueue for buffers */
+	wait_queue_head_t	wait_buffer;
+	/* waitqueue for data */
+	wait_queue_head_t	wait_data;
+	/**/
+	struct workqueue_struct	*workqueue;
+	/**/
+	struct work_struct	worker;
+
+	/* I2C adapter */
+	struct i2c_adapter	*i2c_adapter;
+	/* I2C lock */
+	struct mutex		i2c_mutex;
+
+	/* usb control transfer buffer and lock */
+	struct mutex		usbc_mutex;
+	u8			*usbc_buf;
+};
+
+
+/* buffer one bulk urb of data */
+struct hdpvr_buffer {
+	struct list_head	buff_list;
+
+	struct urb		*urb;
+
+	struct hdpvr_device	*dev;
+
+	uint			pos;
+
+	__u8			status;
+};
+
+/* */
+
+struct hdpvr_video_info {
+	u16	width;
+	u16	height;
+	u8	fps;
+};
+
+enum {
+	STATUS_UNINITIALIZED	= 0,
+	STATUS_IDLE,
+	STATUS_STARTING,
+	STATUS_SHUTTING_DOWN,
+	STATUS_STREAMING,
+	STATUS_ERROR,
+	STATUS_DISCONNECTED,
+};
+
+enum {
+	HDPVR_FLAG_AC3_CAP = 1,
+};
+
+enum {
+	BUFSTAT_UNINITIALIZED = 0,
+	BUFSTAT_AVAILABLE,
+	BUFSTAT_INPROGRESS,
+	BUFSTAT_READY,
+};
+
+#define CTRL_START_STREAMING_VALUE	0x0700
+#define CTRL_STOP_STREAMING_VALUE	0x0800
+#define CTRL_BITRATE_VALUE		0x1000
+#define CTRL_BITRATE_MODE_VALUE		0x1200
+#define CTRL_GOP_MODE_VALUE		0x1300
+#define CTRL_VIDEO_INPUT_VALUE		0x1500
+#define CTRL_VIDEO_STD_TYPE		0x1700
+#define CTRL_AUDIO_INPUT_VALUE		0x2500
+#define CTRL_BRIGHTNESS			0x2900
+#define CTRL_CONTRAST			0x2a00
+#define CTRL_HUE			0x2b00
+#define CTRL_SATURATION			0x2c00
+#define CTRL_SHARPNESS			0x2d00
+#define CTRL_LOW_PASS_FILTER_VALUE	0x3100
+
+#define CTRL_DEFAULT_INDEX		0x0003
+
+
+	/* :0 s 38 01 1000 0003 0004 4 = 0a00ca00
+	 * BITRATE SETTING
+	 *   1st and 2nd byte (little endian): average bitrate in 100 000 bit/s
+	 *                                     min: 1 mbit/s, max: 13.5 mbit/s
+	 *   3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s
+	 *                                     min: average + 100kbit/s,
+	 *                                      max: 20.2 mbit/s
+	 */
+
+	/* :0 s 38 01 1200 0003 0001 1 = 02
+	 * BIT RATE MODE
+	 *  constant = 1, variable (peak) = 2, variable (average) = 3
+	 */
+
+	/* :0 s 38 01 1300 0003 0001 1 = 03
+	 * GOP MODE (2 bit)
+	 *    low bit 0/1: advanced/simple GOP
+	 *   high bit 0/1: IDR(4/32/128) / no IDR (4/32/0)
+	 */
+
+	/* :0 s 38 01 1700 0003 0001 1 = 00
+	 * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz
+	 */
+
+	/* :0 s 38 01 3100 0003 0004 4 = 03030000
+	 * FILTER CONTROL
+	 *   1st byte luma low pass filter strength,
+	 *   2nd byte chroma low pass filter strength,
+	 *   3rd byte MF enable chroma, min=0, max=1
+	 *   4th byte n
+	 */
+
+
+	/* :0 s 38 b9 0001 0000 0000 0 */
+
+
+
+/* :0 s 38 d3 0000 0000 0001 1 = 00 */
+/* 		ret = usb_control_msg(dev->udev, */
+/* 				      usb_sndctrlpipe(dev->udev, 0), */
+/* 				      0xd3, 0x38, */
+/* 				      0, 0, */
+/* 				      "\0", 1, */
+/* 				      1000); */
+
+/* 		info("control request returned %d", ret); */
+/* 		msleep(5000); */
+
+
+	/* :0 s b8 81 1400 0003 0005 5 <
+	 * :0 0 5 = d0024002 19
+	 * QUERY FRAME SIZE AND RATE
+	 *   1st and 2nd byte (little endian): horizontal resolution
+	 *   3rd and 4th byte (little endian): vertical resolution
+	 *   5th byte: frame rate
+	 */
+
+	/* :0 s b8 81 1800 0003 0003 3 <
+	 * :0 0 3 = 030104
+	 * QUERY SIGNAL AND DETECTED LINES, maybe INPUT
+	 */
+
+enum hdpvr_video_std {
+	HDPVR_60HZ = 0,
+	HDPVR_50HZ,
+};
+
+enum hdpvr_video_input {
+	HDPVR_COMPONENT = 0,
+	HDPVR_SVIDEO,
+	HDPVR_COMPOSITE,
+	HDPVR_VIDEO_INPUTS
+};
+
+enum hdpvr_audio_inputs {
+	HDPVR_RCA_BACK = 0,
+	HDPVR_RCA_FRONT,
+	HDPVR_SPDIF,
+	HDPVR_AUDIO_INPUTS
+};
+
+enum hdpvr_bitrate_mode {
+	HDPVR_CONSTANT = 1,
+	HDPVR_VARIABLE_PEAK,
+	HDPVR_VARIABLE_AVERAGE,
+};
+
+enum hdpvr_gop_mode {
+	HDPVR_ADVANCED_IDR_GOP = 0,
+	HDPVR_SIMPLE_IDR_GOP,
+	HDPVR_ADVANCED_NOIDR_GOP,
+	HDPVR_SIMPLE_NOIDR_GOP,
+};
+
+void hdpvr_delete(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* hardware control functions */
+int hdpvr_set_options(struct hdpvr_device *dev);
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev);
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+		    enum v4l2_mpeg_audio_encoding codec);
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value,
+		      unsigned char valbuf);
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+
+/* :0 s b8 81 1800 0003 0003 3 < */
+/* :0 0 3 = 0301ff */
+int get_input_lines_info(struct hdpvr_device *dev);
+
+
+/*========================================================================*/
+/* v4l2 registration */
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+			    int devnumber);
+
+int hdpvr_cancel_queue(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* i2c adapter registration */
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* buffer management */
+int hdpvr_free_buffers(struct hdpvr_device *dev);
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,145 @@
+
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008      Janne Grunau (j@jannau.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, version 2.
+ *
+ */
+
+#include <linux/i2c.h>
+
+#include "hdpvr.h"
+
+#define CTRL_READ_REQUEST	0xb8
+#define CTRL_WRITE_REQUEST	0x38
+
+#define REQTYPE_I2C_READ	0xb1
+#define REQTYPE_I2C_WRITE	0xb0
+#define REQTYPE_I2C_WRITE_STATT	0xd0
+
+static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
+			  char *data, int len)
+{
+	int ret;
+	char *buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      REQTYPE_I2C_READ, CTRL_READ_REQUEST,
+			      0x100|addr, 0, buf, len, 1000);
+
+	if (ret == len) {
+		memcpy(data, buf, len);
+		ret = 0;
+	} else if (ret >= 0)
+		ret = -EIO;
+
+	kfree(buf);
+
+	return ret;
+}
+
+static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
+			   char *data, int len)
+{
+	int ret;
+	char *buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	memcpy(buf, data, len);
+	ret = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
+			      0x100|addr, 0, buf, len, 1000);
+
+	if (ret < 0)
+		goto error;
+
+	ret = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
+			      0, 0, buf, 2, 1000);
+
+	if (ret == 2)
+		ret = 0;
+	else if (ret >= 0)
+		ret = -EIO;
+
+error:
+	kfree(buf);
+	return ret;
+}
+
+static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
+			  int num)
+{
+	struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
+	int retval = 0, i, addr;
+
+	if (num <= 0)
+		return 0;
+
+	mutex_lock(&dev->i2c_mutex);
+
+	for (i = 0; i < num && !retval; i++) {
+		addr = msgs[i].addr << 1;
+
+		if (msgs[i].flags & I2C_M_RD)
+			retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
+						msgs[i].len);
+		else
+			retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
+						 msgs[i].len);
+	}
+
+	mutex_unlock(&dev->i2c_mutex);
+
+	return retval ? retval : num;
+}
+
+static u32 hdpvr_functionality(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm hdpvr_algo = {
+	.master_xfer   = hdpvr_transfer,
+	.functionality = hdpvr_functionality,
+};
+
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
+{
+	struct i2c_adapter *i2c_adap;
+	int retval = -ENOMEM;
+
+	i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+	if (i2c_adap == NULL)
+		goto error;
+
+	strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
+		sizeof(i2c_adap->name));
+	i2c_adap->algo  = &hdpvr_algo;
+	i2c_adap->class = I2C_CLASS_TV_ANALOG;
+	i2c_adap->id    = I2C_HW_B_HDPVR;
+	i2c_adap->owner = THIS_MODULE;
+	i2c_adap->dev.parent = &dev->udev->dev;
+
+	i2c_set_adapdata(i2c_adap, dev);
+
+	retval = i2c_add_adapter(i2c_adap);
+
+	if (!retval)
+		dev->i2c_adapter = i2c_adap;
+	else
+		kfree(i2c_adap);
+
+error:
+	return retval;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-video.c linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/hdpvr-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1248 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008      Janne Grunau (j@jannau.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, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include "hdpvr.h"
+
+#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
+
+#define print_buffer_status() { \
+		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,	\
+			 "%s:%d buffer stat: %d free, %d proc\n",	\
+			 __func__, __LINE__,				\
+			 list_size(&dev->free_buff_list),		\
+			 list_size(&dev->rec_buff_list)); }
+
+struct hdpvr_fh {
+	struct hdpvr_device	*dev;
+};
+
+static uint list_size(struct list_head *list)
+{
+	struct list_head *tmp;
+	uint count = 0;
+
+	list_for_each(tmp, list) {
+		count++;
+	}
+
+	return count;
+}
+
+/*=========================================================================*/
+/* urb callback */
+static void hdpvr_read_bulk_callback(struct urb *urb)
+{
+	struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
+	struct hdpvr_device *dev = buf->dev;
+
+	/* marking buffer as received and wake waiting */
+	buf->status = BUFSTAT_READY;
+	wake_up_interruptible(&dev->wait_data);
+}
+
+/*=========================================================================*/
+/* bufffer bits */
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_cancel_queue(struct hdpvr_device *dev)
+{
+	struct hdpvr_buffer *buf;
+
+	list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
+		usb_kill_urb(buf->urb);
+		buf->status = BUFSTAT_AVAILABLE;
+	}
+
+	list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
+
+	return 0;
+}
+
+static int hdpvr_free_queue(struct list_head *q)
+{
+	struct list_head *tmp;
+	struct list_head *p;
+	struct hdpvr_buffer *buf;
+	struct urb *urb;
+
+	for (p = q->next; p != q;) {
+		buf = list_entry(p, struct hdpvr_buffer, buff_list);
+
+		urb = buf->urb;
+		usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+				urb->transfer_buffer, urb->transfer_dma);
+		usb_free_urb(urb);
+		tmp = p->next;
+		list_del(p);
+		kfree(buf);
+		p = tmp;
+	}
+
+	return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_free_buffers(struct hdpvr_device *dev)
+{
+	hdpvr_cancel_queue(dev);
+
+	hdpvr_free_queue(&dev->free_buff_list);
+	hdpvr_free_queue(&dev->rec_buff_list);
+
+	return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
+{
+	uint i;
+	int retval = -ENOMEM;
+	u8 *mem;
+	struct hdpvr_buffer *buf;
+	struct urb *urb;
+
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "allocating %u buffers\n", count);
+
+	for (i = 0; i < count; i++) {
+
+		buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
+		if (!buf) {
+			v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
+			goto exit;
+		}
+		buf->dev = dev;
+
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
+			goto exit;
+		}
+		buf->urb = urb;
+
+		mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
+				       &urb->transfer_dma);
+		if (!mem) {
+			v4l2_err(&dev->v4l2_dev,
+				 "cannot allocate usb transfer buffer\n");
+			goto exit;
+		}
+
+		usb_fill_bulk_urb(buf->urb, dev->udev,
+				  usb_rcvbulkpipe(dev->udev,
+						  dev->bulk_in_endpointAddr),
+				  mem, dev->bulk_in_size,
+				  hdpvr_read_bulk_callback, buf);
+
+		buf->status = BUFSTAT_AVAILABLE;
+		list_add_tail(&buf->buff_list, &dev->free_buff_list);
+	}
+	return 0;
+exit:
+	hdpvr_free_buffers(dev);
+	return retval;
+}
+
+static int hdpvr_submit_buffers(struct hdpvr_device *dev)
+{
+	struct hdpvr_buffer *buf;
+	struct urb *urb;
+	int ret = 0, err_count = 0;
+
+	mutex_lock(&dev->io_mutex);
+
+	while (dev->status == STATUS_STREAMING &&
+	       !list_empty(&dev->free_buff_list)) {
+
+		buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
+				 buff_list);
+		if (buf->status != BUFSTAT_AVAILABLE) {
+			v4l2_err(&dev->v4l2_dev,
+				 "buffer not marked as availbale\n");
+			ret = -EFAULT;
+			goto err;
+		}
+
+		urb = buf->urb;
+		urb->status = 0;
+		urb->actual_length = 0;
+		ret = usb_submit_urb(urb, GFP_KERNEL);
+		if (ret) {
+			v4l2_err(&dev->v4l2_dev,
+				 "usb_submit_urb in %s returned %d\n",
+				 __func__, ret);
+			if (++err_count > 2)
+				break;
+			continue;
+		}
+		buf->status = BUFSTAT_INPROGRESS;
+		list_move_tail(&buf->buff_list, &dev->rec_buff_list);
+	}
+err:
+	print_buffer_status();
+	mutex_unlock(&dev->io_mutex);
+	return ret;
+}
+
+static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
+{
+	struct hdpvr_buffer *buf;
+
+	mutex_lock(&dev->io_mutex);
+
+	if (list_empty(&dev->rec_buff_list)) {
+		mutex_unlock(&dev->io_mutex);
+		return NULL;
+	}
+
+	buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
+			 buff_list);
+	mutex_unlock(&dev->io_mutex);
+
+	return buf;
+}
+
+static void hdpvr_transmit_buffers(struct work_struct *work)
+{
+	struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
+						worker);
+
+	while (dev->status == STATUS_STREAMING) {
+
+		if (hdpvr_submit_buffers(dev)) {
+			v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
+			goto error;
+		}
+		if (wait_event_interruptible(dev->wait_buffer,
+				!list_empty(&dev->free_buff_list) ||
+					     dev->status != STATUS_STREAMING))
+			goto error;
+	}
+
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "transmit worker exited\n");
+	return;
+error:
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "transmit buffers errored\n");
+	dev->status = STATUS_ERROR;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_start_streaming(struct hdpvr_device *dev)
+{
+	int ret;
+	struct hdpvr_video_info *vidinf;
+
+	if (dev->status == STATUS_STREAMING)
+		return 0;
+	else if (dev->status != STATUS_IDLE)
+		return -EAGAIN;
+
+	vidinf = get_video_info(dev);
+
+	if (vidinf) {
+		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			 "video signal: %dx%d@%dhz\n", vidinf->width,
+			 vidinf->height, vidinf->fps);
+		kfree(vidinf);
+
+		/* start streaming 2 request */
+		ret = usb_control_msg(dev->udev,
+				      usb_sndctrlpipe(dev->udev, 0),
+				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			 "encoder start control request returned %d\n", ret);
+
+		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+
+		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+		queue_work(dev->workqueue, &dev->worker);
+
+		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			 "streaming started\n");
+		dev->status = STATUS_STREAMING;
+
+		return 0;
+	}
+	msleep(250);
+	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+		 "no video signal at input %d\n", dev->options.video_input);
+	return -EAGAIN;
+}
+
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_stop_streaming(struct hdpvr_device *dev)
+{
+	uint actual_length, c = 0;
+	u8 *buf;
+
+	if (dev->status == STATUS_IDLE)
+		return 0;
+	else if (dev->status != STATUS_STREAMING)
+		return -EAGAIN;
+
+	buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
+	if (!buf)
+		v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
+			 "for emptying the internal device buffer. "
+			 "Next capture start will be slow\n");
+
+	dev->status = STATUS_SHUTTING_DOWN;
+	hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
+	mutex_unlock(&dev->io_mutex);
+
+	wake_up_interruptible(&dev->wait_buffer);
+	msleep(50);
+
+	flush_workqueue(dev->workqueue);
+
+	mutex_lock(&dev->io_mutex);
+	/* kill the still outstanding urbs */
+	hdpvr_cancel_queue(dev);
+
+	/* emptying the device buffer beforeshutting it down */
+	while (buf && ++c < 500 &&
+	       !usb_bulk_msg(dev->udev,
+			     usb_rcvbulkpipe(dev->udev,
+					     dev->bulk_in_endpointAddr),
+			     buf, dev->bulk_in_size, &actual_length,
+			     BULK_URB_TIMEOUT)) {
+		/* wait */
+		msleep(5);
+		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			 "%2d: got %d bytes\n", c, actual_length);
+	}
+	kfree(buf);
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+		 "used %d urbs to empty device buffers\n", c-1);
+	msleep(10);
+
+	dev->status = STATUS_IDLE;
+
+	return 0;
+}
+
+
+/*=======================================================================*/
+/*
+ * video 4 linux 2 file operations
+ */
+
+static int hdpvr_open(struct file *file)
+{
+	struct hdpvr_device *dev;
+	struct hdpvr_fh *fh;
+	int retval = -ENOMEM;
+
+	dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
+	if (!dev) {
+		v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
+		retval = -ENODEV;
+		goto err;
+	}
+
+	fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
+	if (!fh) {
+		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+		goto err;
+	}
+	/* lock the device to allow correctly handling errors
+	 * in resumption */
+	mutex_lock(&dev->io_mutex);
+	dev->open_count++;
+
+	fh->dev = dev;
+
+	/* save our object in the file's private structure */
+	file->private_data = fh;
+
+	retval = 0;
+err:
+	mutex_unlock(&dev->io_mutex);
+	return retval;
+}
+
+static int hdpvr_release(struct file *file)
+{
+	struct hdpvr_fh		*fh  = (struct hdpvr_fh *)file->private_data;
+	struct hdpvr_device	*dev = fh->dev;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->io_mutex);
+	if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
+		hdpvr_stop_streaming(dev);
+
+	mutex_unlock(&dev->io_mutex);
+
+	return 0;
+}
+
+/*
+ * hdpvr_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
+			  loff_t *pos)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	struct hdpvr_buffer *buf = NULL;
+	struct urb *urb;
+	unsigned int ret = 0;
+	int rem, cnt;
+
+	if (*pos)
+		return -ESPIPE;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->io_mutex);
+	if (dev->status == STATUS_IDLE) {
+		if (hdpvr_start_streaming(dev)) {
+			v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+				 "start_streaming failed\n");
+			ret = -EIO;
+			msleep(200);
+			dev->status = STATUS_IDLE;
+			mutex_unlock(&dev->io_mutex);
+			goto err;
+		}
+		print_buffer_status();
+	}
+	mutex_unlock(&dev->io_mutex);
+
+	/* wait for the first buffer */
+	if (!(file->f_flags & O_NONBLOCK)) {
+		if (wait_event_interruptible(dev->wait_data,
+					     hdpvr_get_next_buffer(dev)))
+			return -ERESTARTSYS;
+	}
+
+	buf = hdpvr_get_next_buffer(dev);
+
+	while (count > 0 && buf) {
+
+		if (buf->status != BUFSTAT_READY &&
+		    dev->status != STATUS_DISCONNECTED) {
+			/* return nonblocking */
+			if (file->f_flags & O_NONBLOCK) {
+				if (!ret)
+					ret = -EAGAIN;
+				goto err;
+			}
+
+			if (wait_event_interruptible(dev->wait_data,
+					      buf->status == BUFSTAT_READY)) {
+				ret = -ERESTARTSYS;
+				goto err;
+			}
+		}
+
+		if (buf->status != BUFSTAT_READY)
+			break;
+
+		/* set remaining bytes to copy */
+		urb = buf->urb;
+		rem = urb->actual_length - buf->pos;
+		cnt = rem > count ? count : rem;
+
+		if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
+				 cnt)) {
+			v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
+			if (!ret)
+				ret = -EFAULT;
+			goto err;
+		}
+
+		buf->pos += cnt;
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+
+		/* finished, take next buffer */
+		if (buf->pos == urb->actual_length) {
+			mutex_lock(&dev->io_mutex);
+			buf->pos = 0;
+			buf->status = BUFSTAT_AVAILABLE;
+
+			list_move_tail(&buf->buff_list, &dev->free_buff_list);
+
+			print_buffer_status();
+
+			mutex_unlock(&dev->io_mutex);
+
+			wake_up_interruptible(&dev->wait_buffer);
+
+			buf = hdpvr_get_next_buffer(dev);
+		}
+	}
+err:
+	if (!ret && !buf)
+		ret = -EAGAIN;
+	return ret;
+}
+
+static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
+{
+	struct hdpvr_buffer *buf = NULL;
+	struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	unsigned int mask = 0;
+
+	mutex_lock(&dev->io_mutex);
+
+	if (video_is_unregistered(dev->video_dev))
+		return -EIO;
+
+	if (dev->status == STATUS_IDLE) {
+		if (hdpvr_start_streaming(dev)) {
+			v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+				 "start_streaming failed\n");
+			dev->status = STATUS_IDLE;
+		}
+
+		print_buffer_status();
+	}
+	mutex_unlock(&dev->io_mutex);
+
+	buf = hdpvr_get_next_buffer(dev);
+	/* only wait if no data is available */
+	if (!buf || buf->status != BUFSTAT_READY) {
+		poll_wait(filp, &dev->wait_data, wait);
+		buf = hdpvr_get_next_buffer(dev);
+	}
+	if (buf && buf->status == BUFSTAT_READY)
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+
+static const struct v4l2_file_operations hdpvr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= hdpvr_open,
+	.release	= hdpvr_release,
+	.read		= hdpvr_read,
+	.poll		= hdpvr_poll,
+	.unlocked_ioctl	= video_ioctl2,
+};
+
+/*=======================================================================*/
+/*
+ * V4L2 ioctl handling
+ */
+
+static int vidioc_querycap(struct file *file, void  *priv,
+			   struct v4l2_capability *cap)
+{
+	struct hdpvr_device *dev = video_drvdata(file);
+
+	strcpy(cap->driver, "hdpvr");
+	strcpy(cap->card, "Haupauge HD PVR");
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+	cap->version = HDPVR_VERSION;
+	cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
+				V4L2_CAP_AUDIO         |
+				V4L2_CAP_READWRITE;
+	return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *private_data,
+			v4l2_std_id *std)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	u8 std_type = 1;
+
+	if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
+		std_type = 0;
+
+	return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
+}
+
+static const char *iname[] = {
+	[HDPVR_COMPONENT] = "Component",
+	[HDPVR_SVIDEO]    = "S-Video",
+	[HDPVR_COMPOSITE] = "Composite",
+};
+
+static int vidioc_enum_input(struct file *file, void *priv,
+				struct v4l2_input *i)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	unsigned int n;
+
+	n = i->index;
+	if (n >= HDPVR_VIDEO_INPUTS)
+		return -EINVAL;
+
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+
+	strncpy(i->name, iname[n], sizeof(i->name) - 1);
+	i->name[sizeof(i->name) - 1] = '\0';
+
+	i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
+
+	i->std = dev->video_dev->tvnorms;
+
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *private_data,
+			  unsigned int index)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int retval;
+
+	if (index >= HDPVR_VIDEO_INPUTS)
+		return -EINVAL;
+
+	if (dev->status != STATUS_IDLE)
+		return -EAGAIN;
+
+	retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
+	if (!retval)
+		dev->options.video_input = index;
+
+	return retval;
+}
+
+static int vidioc_g_input(struct file *file, void *private_data,
+			  unsigned int *index)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+
+	*index = dev->options.video_input;
+	return 0;
+}
+
+
+static const char *audio_iname[] = {
+	[HDPVR_RCA_FRONT] = "RCA front",
+	[HDPVR_RCA_BACK]  = "RCA back",
+	[HDPVR_SPDIF]     = "SPDIF",
+};
+
+static int vidioc_enumaudio(struct file *file, void *priv,
+				struct v4l2_audio *audio)
+{
+	unsigned int n;
+
+	n = audio->index;
+	if (n >= HDPVR_AUDIO_INPUTS)
+		return -EINVAL;
+
+	audio->capability = V4L2_AUDCAP_STEREO;
+
+	strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
+	audio->name[sizeof(audio->name) - 1] = '\0';
+
+	return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *private_data,
+			  struct v4l2_audio *audio)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int retval;
+
+	if (audio->index >= HDPVR_AUDIO_INPUTS)
+		return -EINVAL;
+
+	if (dev->status != STATUS_IDLE)
+		return -EAGAIN;
+
+	retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
+	if (!retval)
+		dev->options.audio_input = audio->index;
+
+	return retval;
+}
+
+static int vidioc_g_audio(struct file *file, void *private_data,
+			  struct v4l2_audio *audio)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+
+	audio->index = dev->options.audio_input;
+	audio->capability = V4L2_AUDCAP_STEREO;
+	strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
+	audio->name[sizeof(audio->name) - 1] = '\0';
+	return 0;
+}
+
+static const s32 supported_v4l2_ctrls[] = {
+	V4L2_CID_BRIGHTNESS,
+	V4L2_CID_CONTRAST,
+	V4L2_CID_SATURATION,
+	V4L2_CID_HUE,
+	V4L2_CID_SHARPNESS,
+	V4L2_CID_MPEG_AUDIO_ENCODING,
+	V4L2_CID_MPEG_VIDEO_ENCODING,
+	V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+	V4L2_CID_MPEG_VIDEO_BITRATE,
+	V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+};
+
+static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
+			  int ac3)
+{
+	int err;
+
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+	case V4L2_CID_SHARPNESS:
+		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		return v4l2_ctrl_query_fill(
+			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
+			ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
+			: V4L2_MPEG_AUDIO_ENCODING_AAC,
+			1, V4L2_MPEG_AUDIO_ENCODING_AAC);
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		return v4l2_ctrl_query_fill(
+			qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
+			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
+			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
+
+/* 	case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
+/* 		return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		return v4l2_ctrl_query_fill(
+			qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
+					    6500000);
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
+					   9000000);
+		if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
+			qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
+		return err;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int vidioc_queryctrl(struct file *file, void *private_data,
+			    struct v4l2_queryctrl *qc)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int i, next;
+	u32 id = qc->id;
+
+	memset(qc, 0, sizeof(*qc));
+
+	next = !!(id &  V4L2_CTRL_FLAG_NEXT_CTRL);
+	qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
+
+	for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
+		if (next) {
+			if (qc->id < supported_v4l2_ctrls[i])
+				qc->id = supported_v4l2_ctrls[i];
+			else
+				continue;
+		}
+
+		if (qc->id == supported_v4l2_ctrls[i])
+			return fill_queryctrl(&dev->options, qc,
+					      dev->flags & HDPVR_FLAG_AC3_CAP);
+
+		if (qc->id < supported_v4l2_ctrls[i])
+			break;
+	}
+
+	return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *private_data,
+			 struct v4l2_control *ctrl)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = dev->options.brightness;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = dev->options.contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = dev->options.saturation;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = dev->options.hue;
+		break;
+	case V4L2_CID_SHARPNESS:
+		ctrl->value = dev->options.sharpness;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *private_data,
+			 struct v4l2_control *ctrl)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int retval;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
+		if (!retval)
+			dev->options.brightness = ctrl->value;
+		break;
+	case V4L2_CID_CONTRAST:
+		retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
+		if (!retval)
+			dev->options.contrast = ctrl->value;
+		break;
+	case V4L2_CID_SATURATION:
+		retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
+		if (!retval)
+			dev->options.saturation = ctrl->value;
+		break;
+	case V4L2_CID_HUE:
+		retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
+		if (!retval)
+			dev->options.hue = ctrl->value;
+		break;
+	case V4L2_CID_SHARPNESS:
+		retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
+		if (!retval)
+			dev->options.sharpness = ctrl->value;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return retval;
+}
+
+
+static int hdpvr_get_ctrl(struct hdpvr_options *opt,
+			  struct v4l2_ext_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		ctrl->value = opt->audio_codec;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
+		break;
+/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* 		ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
+/* 		break; */
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
+			? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
+			: V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		ctrl->value = opt->bitrate * 100000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		ctrl->value = opt->peak_bitrate * 100000;
+		break;
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+			      struct v4l2_ext_controls *ctrls)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int i, err = 0;
+
+	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+		for (i = 0; i < ctrls->count; i++) {
+			struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+			err = hdpvr_get_ctrl(&dev->options, ctrl);
+			if (err) {
+				ctrls->error_idx = i;
+				break;
+			}
+		}
+		return err;
+
+	}
+
+	return -EINVAL;
+}
+
+
+static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
+{
+	int ret = -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
+		    (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
+			ret = 0;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
+			ret = 0;
+		break;
+/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* 		if (ctrl->value == 0 || ctrl->value == 128) */
+/* 			ret = 0; */
+/* 		break; */
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
+		    ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+			ret = 0;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+	{
+		uint bitrate = ctrl->value / 100000;
+		if (bitrate >= 10 && bitrate <= 135)
+			ret = 0;
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+	{
+		uint peak_bitrate = ctrl->value / 100000;
+		if (peak_bitrate >= 10 && peak_bitrate <= 202)
+			ret = 0;
+		break;
+	}
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
+			ret = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+				struct v4l2_ext_controls *ctrls)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int i, err = 0;
+
+	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+		for (i = 0; i < ctrls->count; i++) {
+			struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+			err = hdpvr_try_ctrl(ctrl,
+					     dev->flags & HDPVR_FLAG_AC3_CAP);
+			if (err) {
+				ctrls->error_idx = i;
+				break;
+			}
+		}
+		return err;
+	}
+
+	return -EINVAL;
+}
+
+
+static int hdpvr_set_ctrl(struct hdpvr_device *dev,
+			  struct v4l2_ext_control *ctrl)
+{
+	struct hdpvr_options *opt = &dev->options;
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+			opt->audio_codec = ctrl->value;
+			ret = hdpvr_set_audio(dev, opt->audio_input,
+					      opt->audio_codec);
+		}
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		break;
+/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
+/* 			opt->gop_mode |= 0x2; */
+/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* 					  opt->gop_mode); */
+/* 		} */
+/* 		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
+/* 			opt->gop_mode &= ~0x2; */
+/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* 					  opt->gop_mode); */
+/* 		} */
+/* 		break; */
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
+		    opt->bitrate_mode != HDPVR_CONSTANT) {
+			opt->bitrate_mode = HDPVR_CONSTANT;
+			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+					  opt->bitrate_mode);
+		}
+		if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+		    opt->bitrate_mode == HDPVR_CONSTANT) {
+			opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
+			hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+					  opt->bitrate_mode);
+		}
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE: {
+		uint bitrate = ctrl->value / 100000;
+
+		opt->bitrate = bitrate;
+		if (bitrate >= opt->peak_bitrate)
+			opt->peak_bitrate = bitrate+1;
+
+		hdpvr_set_bitrate(dev);
+		break;
+	}
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
+		uint peak_bitrate = ctrl->value / 100000;
+
+		if (opt->bitrate_mode == HDPVR_CONSTANT)
+			break;
+
+		if (opt->bitrate < peak_bitrate) {
+			opt->peak_bitrate = peak_bitrate;
+			hdpvr_set_bitrate(dev);
+		} else
+			ret = -EINVAL;
+		break;
+	}
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		break;
+	default:
+		return -EINVAL;
+	}
+	return ret;
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+			      struct v4l2_ext_controls *ctrls)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int i, err = 0;
+
+	if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+		for (i = 0; i < ctrls->count; i++) {
+			struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+			err = hdpvr_try_ctrl(ctrl,
+					     dev->flags & HDPVR_FLAG_AC3_CAP);
+			if (err) {
+				ctrls->error_idx = i;
+				break;
+			}
+			err = hdpvr_set_ctrl(dev, ctrl);
+			if (err) {
+				ctrls->error_idx = i;
+				break;
+			}
+		}
+		return err;
+
+	}
+
+	return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
+				    struct v4l2_fmtdesc *f)
+{
+
+	if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	f->flags = V4L2_FMT_FLAG_COMPRESSED;
+	strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
+	f->pixelformat = V4L2_PIX_FMT_MPEG;
+
+	return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
+				struct v4l2_format *f)
+{
+	struct hdpvr_fh *fh = file->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	struct hdpvr_video_info *vid_info;
+
+	if (!dev)
+		return -ENODEV;
+
+	vid_info = get_video_info(dev);
+	if (!vid_info)
+		return -EFAULT;
+
+	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	f->fmt.pix.pixelformat	= V4L2_PIX_FMT_MPEG;
+	f->fmt.pix.width	= vid_info->width;
+	f->fmt.pix.height	= vid_info->height;
+	f->fmt.pix.sizeimage	= dev->bulk_in_size;
+	f->fmt.pix.colorspace	= 0;
+	f->fmt.pix.bytesperline	= 0;
+	f->fmt.pix.field	= V4L2_FIELD_ANY;
+
+	kfree(vid_info);
+	return 0;
+}
+
+static int vidioc_encoder_cmd(struct file *filp, void *priv,
+			       struct v4l2_encoder_cmd *a)
+{
+	struct hdpvr_fh *fh = filp->private_data;
+	struct hdpvr_device *dev = fh->dev;
+	int res;
+
+	mutex_lock(&dev->io_mutex);
+
+	memset(&a->raw, 0, sizeof(a->raw));
+	switch (a->cmd) {
+	case V4L2_ENC_CMD_START:
+		a->flags = 0;
+		res = hdpvr_start_streaming(dev);
+		break;
+	case V4L2_ENC_CMD_STOP:
+		res = hdpvr_stop_streaming(dev);
+		break;
+	default:
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+			 "Unsupported encoder cmd %d\n", a->cmd);
+		res = -EINVAL;
+	}
+	mutex_unlock(&dev->io_mutex);
+	return res;
+}
+
+static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
+					struct v4l2_encoder_cmd *a)
+{
+	switch (a->cmd) {
+	case V4L2_ENC_CMD_START:
+	case V4L2_ENC_CMD_STOP:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+	.vidioc_s_std		= vidioc_s_std,
+	.vidioc_enum_input	= vidioc_enum_input,
+	.vidioc_g_input		= vidioc_g_input,
+	.vidioc_s_input		= vidioc_s_input,
+	.vidioc_enumaudio	= vidioc_enumaudio,
+	.vidioc_g_audio		= vidioc_g_audio,
+	.vidioc_s_audio		= vidioc_s_audio,
+	.vidioc_queryctrl	= vidioc_queryctrl,
+	.vidioc_g_ctrl		= vidioc_g_ctrl,
+	.vidioc_s_ctrl		= vidioc_s_ctrl,
+	.vidioc_g_ext_ctrls	= vidioc_g_ext_ctrls,
+	.vidioc_s_ext_ctrls	= vidioc_s_ext_ctrls,
+	.vidioc_try_ext_ctrls	= vidioc_try_ext_ctrls,
+	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt_vid_cap,
+	.vidioc_encoder_cmd	= vidioc_encoder_cmd,
+	.vidioc_try_encoder_cmd	= vidioc_try_encoder_cmd,
+};
+
+static void hdpvr_device_release(struct video_device *vdev)
+{
+	struct hdpvr_device *dev = video_get_drvdata(vdev);
+
+	hdpvr_delete(dev);
+}
+
+static const struct video_device hdpvr_video_template = {
+/* 	.type			= VFL_TYPE_GRABBER, */
+/* 	.type2			= VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
+	.fops			= &hdpvr_fops,
+	.release		= hdpvr_device_release,
+	.ioctl_ops 		= &hdpvr_ioctl_ops,
+	.tvnorms 		=
+		V4L2_STD_NTSC  | V4L2_STD_SECAM | V4L2_STD_PAL_B |
+		V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
+		V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
+		V4L2_STD_PAL_60,
+};
+
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+			    int devnum)
+{
+	/* setup and register video device */
+	dev->video_dev = video_device_alloc();
+	if (!dev->video_dev) {
+		v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
+		goto error;
+	}
+
+	*(dev->video_dev) = hdpvr_video_template;
+	strcpy(dev->video_dev->name, "Hauppauge HD PVR");
+	dev->video_dev->parent = parent;
+	video_set_drvdata(dev->video_dev, dev);
+
+	if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
+		v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
+		goto error;
+	}
+
+	return 0;
+error:
+	return -ENOMEM;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,10 @@
+
+config VIDEO_HDPVR
+	tristate "Hauppauge HD PVR support"
+	depends on VIDEO_DEV
+	---help---
+	  This is a video4linux driver for Hauppauge's HD PVR USB device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hdpvr
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/hdpvr/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hdpvr/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,9 @@
+hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-video.o
+
+hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
+
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hexium_gemini.c linux-libre-2.6.30-gnu1/drivers/media/video/hexium_gemini.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hexium_gemini.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hexium_gemini.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,17 +56,6 @@ struct hexium_data
 	u8 byte;
 };
 
-static struct saa7146_extension_ioctls ioctls[] = {
-	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_QUERYCTRL, 	SAA7146_BEFORE },
-	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_STD,		SAA7146_AFTER },
-	{ VIDIOC_G_CTRL,	SAA7146_BEFORE },
-	{ VIDIOC_S_CTRL,	SAA7146_BEFORE },
-	{ 0,			0 }
-};
-
 #define HEXIUM_CONTROLS	1
 static struct v4l2_queryctrl hexium_controls[] = {
 	{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct he
 	return 0;
 }
 
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+	if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+		return -EINVAL;
+
+	memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+	DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+	*input = hexium->cur_input;
+
+	DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+	if (input < 0 || input >= HEXIUM_INPUTS)
+		return -EINVAL;
+
+	hexium->cur_input = input;
+	hexium_set_input(hexium, input);
+	return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+   which gets registered *after* this function. because of this we have
+   to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	int i;
+
+	for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+		if (hexium_controls[i].id == qc->id) {
+			*qc = hexium_controls[i];
+			DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+			return 0;
+		}
+	}
+	return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+	int i;
+
+	for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+		if (hexium_controls[i].id == vc->id)
+			break;
+	}
+
+	if (i < 0)
+		return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+	if (vc->id == V4L2_CID_PRIVATE_BASE) {
+		vc->value = hexium->cur_bw;
+		DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+	int i = 0;
+
+	for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+		if (hexium_controls[i].id == vc->id)
+			break;
+	}
+
+	if (i < 0)
+		return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+	if (vc->id == V4L2_CID_PRIVATE_BASE)
+		hexium->cur_bw = vc->value;
+
+	DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+	if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+		hexium_set_standard(hexium, hexium_pal);
+		return 0;
+	}
+	if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+		hexium_set_standard(hexium, hexium_ntsc);
+		return 0;
+	}
+	if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+		hexium_set_standard(hexium, hexium_secam);
+		return 0;
+	}
+	if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+		hexium_set_standard(hexium, hexium_pal_bw);
+		return 0;
+	}
+	if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+		hexium_set_standard(hexium, hexium_ntsc_bw);
+		return 0;
+	}
+	if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+		/* fixme: is there no bw secam mode? */
+		return -EINVAL;
+
+	return -EINVAL;
+}
+
+
 static struct saa7146_ext_vv vv_data;
 
 /* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_
 	hexium->cur_input = 0;
 
 	saa7146_vv_init(dev, &vv_data);
+	vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+	vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+	vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+	vv_data.ops.vidioc_g_input = vidioc_g_input;
+	vv_data.ops.vidioc_s_input = vidioc_s_input;
 	if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
 		printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
 		return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_
 	return 0;
 }
 
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
-	struct saa7146_vv *vv = dev->vv_data;
-*/
-	switch (cmd) {
-	case VIDIOC_ENUMINPUT:
-		{
-			struct v4l2_input *i = arg;
-			DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
-			if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
-				return -EINVAL;
-			}
-
-			memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
-			DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
-			return 0;
-		}
-	case VIDIOC_G_INPUT:
-		{
-			int *input = (int *) arg;
-			*input = hexium->cur_input;
-
-			DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
-			return 0;
-		}
-	case VIDIOC_S_INPUT:
-		{
-			int input = *(int *) arg;
-
-			DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
-			if (input < 0 || input >= HEXIUM_INPUTS) {
-				return -EINVAL;
-			}
-
-			hexium->cur_input = input;
-			hexium_set_input(hexium, input);
-
-			return 0;
-		}
-		/* the saa7146 provides some controls (brightness, contrast, saturation)
-		   which gets registered *after* this function. because of this we have
-		   to return with a value != 0 even if the function succeded.. */
-	case VIDIOC_QUERYCTRL:
-		{
-			struct v4l2_queryctrl *qc = arg;
-			int i;
-
-			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-				if (hexium_controls[i].id == qc->id) {
-					*qc = hexium_controls[i];
-					DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
-					return 0;
-				}
-			}
-			return -EAGAIN;
-		}
-	case VIDIOC_G_CTRL:
-		{
-			struct v4l2_control *vc = arg;
-			int i;
-
-			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-				if (hexium_controls[i].id == vc->id) {
-					break;
-				}
-			}
-
-			if (i < 0) {
-				return -EAGAIN;
-			}
-
-			switch (vc->id) {
-			case V4L2_CID_PRIVATE_BASE:{
-					vc->value = hexium->cur_bw;
-					DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
-					return 0;
-				}
-			}
-			return -EINVAL;
-		}
-
-	case VIDIOC_S_CTRL:
-		{
-			struct v4l2_control *vc = arg;
-			int i = 0;
-
-			for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
-				if (hexium_controls[i].id == vc->id) {
-					break;
-				}
-			}
-
-			if (i < 0) {
-				return -EAGAIN;
-			}
-
-			switch (vc->id) {
-			case V4L2_CID_PRIVATE_BASE:{
-					hexium->cur_bw = vc->value;
-					break;
-				}
-			}
-
-			DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
-			if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-				hexium_set_standard(hexium, hexium_pal);
-				return 0;
-			}
-			if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-				hexium_set_standard(hexium, hexium_ntsc);
-				return 0;
-			}
-			if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-				hexium_set_standard(hexium, hexium_secam);
-				return 0;
-			}
-			if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
-				hexium_set_standard(hexium, hexium_pal_bw);
-				return 0;
-			}
-			if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
-				hexium_set_standard(hexium, hexium_ntsc_bw);
-				return 0;
-			}
-			if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
-				/* fixme: is there no bw secam mode? */
-				return -EINVAL;
-			}
-
-			return -EINVAL;
-		}
-	default:
-/*
-		DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
 {
 	struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
 	.stds = &hexium_standards[0],
 	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
 	.std_callback = &std_callback,
-	.ioctls = &ioctls[0],
-	.ioctl = hexium_ioctl,
 };
 
 static struct saa7146_extension hexium_extension = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/hexium_orion.c linux-libre-2.6.30-gnu1/drivers/media/video/hexium_orion.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/hexium_orion.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/hexium_orion.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,14 +57,6 @@ struct hexium_data
 	u8 byte;
 };
 
-static struct saa7146_extension_ioctls ioctls[] = {
-	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_STD,		SAA7146_AFTER },
-	{ 0,			0 }
-};
-
 struct hexium
 {
 	int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexiu
 	return 0;
 }
 
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+	if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+		return -EINVAL;
+
+	memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+	DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+	return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+	*input = hexium->cur_input;
+
+	DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+	return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+	if (input < 0 || input >= HEXIUM_INPUTS)
+		return -EINVAL;
+
+	hexium->cur_input = input;
+	hexium_set_input(hexium, input);
+
+	return 0;
+}
+
 static struct saa7146_ext_vv vv_data;
 
 /* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_
 	DEB_EE((".\n"));
 
 	saa7146_vv_init(dev, &vv_data);
+	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+	vv_data.ops.vidioc_g_input = vidioc_g_input;
+	vv_data.ops.vidioc_s_input = vidioc_s_input;
 	if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
 		printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
 		return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_
 	return 0;
 }
 
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
-	struct saa7146_dev *dev = fh->dev;
-	struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
-	struct saa7146_vv *vv = dev->vv_data;
-*/
-	switch (cmd) {
-	case VIDIOC_ENUMINPUT:
-		{
-			struct v4l2_input *i = arg;
-			DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
-			if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
-				return -EINVAL;
-			}
-
-			memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
-			DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
-			return 0;
-		}
-	case VIDIOC_G_INPUT:
-		{
-			int *input = (int *) arg;
-			*input = hexium->cur_input;
-
-			DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
-			return 0;
-		}
-	case VIDIOC_S_INPUT:
-		{
-			int input = *(int *) arg;
-
-			if (input < 0 || input >= HEXIUM_INPUTS) {
-				return -EINVAL;
-			}
-
-			hexium->cur_input = input;
-			hexium_set_input(hexium, input);
-
-			return 0;
-		}
-	default:
-/*
-		DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-
 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
 {
 	return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
 	.stds = &hexium_standards[0],
 	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
 	.std_callback = &std_callback,
-	.ioctls = &ioctls[0],
-	.ioctl = hexium_ioctl,
 };
 
 static struct saa7146_extension extension = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/indycam.c linux-libre-2.6.30-gnu1/drivers/media/video/indycam.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/indycam.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/indycam.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,10 +19,12 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#include <linux/videodev.h>
 /* IndyCam decodes stream of photons into digital image representation ;-) */
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 #include "indycam.h"
 
@@ -33,6 +35,7 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION);
 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
 MODULE_LICENSE("GPL");
 
+
 // #define INDYCAM_DEBUG
 
 #ifdef INDYCAM_DEBUG
@@ -44,11 +47,14 @@ MODULE_LICENSE("GPL");
 #endif
 
 struct indycam {
-	struct i2c_client *client;
+	struct v4l2_subdev sd;
 	u8 version;
 };
 
-static struct i2c_driver i2c_driver_indycam;
+static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct indycam, sd);
+}
 
 static const u8 initseq[] = {
 	INDYCAM_CONTROL_AGCENA,		/* INDYCAM_CONTROL */
@@ -63,8 +69,9 @@ static const u8 initseq[] = {
 
 /* IndyCam register handling */
 
-static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
+static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
 
 	if (reg == INDYCAM_REG_RESET) {
@@ -87,12 +94,12 @@ static int indycam_read_reg(struct i2c_c
 	return 0;
 }
 
-static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
+static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int err;
 
-	if ((reg == INDYCAM_REG_BRIGHTNESS)
-	    || (reg == INDYCAM_REG_VERSION)) {
+	if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
 		dprintk("indycam_write_reg(): "
 			"skipping read-only register %d\n", reg);
 		return 0;
@@ -108,13 +115,13 @@ static int indycam_write_reg(struct i2c_
 	return err;
 }
 
-static int indycam_write_block(struct i2c_client *client, u8 reg,
+static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
 			       u8 length, u8 *data)
 {
 	int i, err;
 
 	for (i = 0; i < length; i++) {
-		err = indycam_write_reg(client, reg + i, data[i]);
+		err = indycam_write_reg(sd, reg + i, data[i]);
 		if (err)
 			return err;
 	}
@@ -125,79 +132,78 @@ static int indycam_write_block(struct i2
 /* Helper functions */
 
 #ifdef INDYCAM_DEBUG
-static void indycam_regdump_debug(struct i2c_client *client)
+static void indycam_regdump_debug(struct v4l2_subdev *sd)
 {
 	int i;
 	u8 val;
 
 	for (i = 0; i < 9; i++) {
-		indycam_read_reg(client, i, &val);
+		indycam_read_reg(sd, i, &val);
 		dprintk("Reg %d = 0x%02x\n", i, val);
 	}
 }
 #endif
 
-static int indycam_get_control(struct i2c_client *client,
-			       struct indycam_control *ctrl)
+static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct indycam *camera = i2c_get_clientdata(client);
+	struct indycam *camera = to_indycam(sd);
 	u8 reg;
 	int ret = 0;
 
-	switch (ctrl->type) {
-	case INDYCAM_CONTROL_AGC:
-	case INDYCAM_CONTROL_AWB:
-		ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
 		if (ret)
 			return -EIO;
-		if (ctrl->type == INDYCAM_CONTROL_AGC)
+		if (ctrl->id == V4L2_CID_AUTOGAIN)
 			ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
 				? 1 : 0;
 		else
 			ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
 				? 1 : 0;
 		break;
-	case INDYCAM_CONTROL_SHUTTER:
-		ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
+	case V4L2_CID_EXPOSURE:
+		ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
 		break;
-	case INDYCAM_CONTROL_GAIN:
-		ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
+	case V4L2_CID_GAIN:
+		ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = (s32)reg;
 		break;
-	case INDYCAM_CONTROL_RED_BALANCE:
-		ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
+	case V4L2_CID_RED_BALANCE:
+		ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = (s32)reg;
 		break;
-	case INDYCAM_CONTROL_BLUE_BALANCE:
-		ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
+	case V4L2_CID_BLUE_BALANCE:
+		ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = (s32)reg;
 		break;
 	case INDYCAM_CONTROL_RED_SATURATION:
-		ret = indycam_read_reg(client,
+		ret = indycam_read_reg(sd,
 				       INDYCAM_REG_RED_SATURATION, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = (s32)reg;
 		break;
 	case INDYCAM_CONTROL_BLUE_SATURATION:
-		ret = indycam_read_reg(client,
+		ret = indycam_read_reg(sd,
 				       INDYCAM_REG_BLUE_SATURATION, &reg);
 		if (ret)
 			return -EIO;
 		ctrl->value = (s32)reg;
 		break;
-	case INDYCAM_CONTROL_GAMMA:
+	case V4L2_CID_GAMMA:
 		if (camera->version == CAMERA_VERSION_MOOSE) {
-			ret = indycam_read_reg(client,
+			ret = indycam_read_reg(sd,
 					       INDYCAM_REG_GAMMA, &reg);
 			if (ret)
 				return -EIO;
@@ -213,21 +219,20 @@ static int indycam_get_control(struct i2
 	return ret;
 }
 
-static int indycam_set_control(struct i2c_client *client,
-			       struct indycam_control *ctrl)
+static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct indycam *camera = i2c_get_clientdata(client);
+	struct indycam *camera = to_indycam(sd);
 	u8 reg;
 	int ret = 0;
 
-	switch (ctrl->type) {
-	case INDYCAM_CONTROL_AGC:
-	case INDYCAM_CONTROL_AWB:
-		ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
 		if (ret)
 			break;
 
-		if (ctrl->type == INDYCAM_CONTROL_AGC) {
+		if (ctrl->id == V4L2_CID_AUTOGAIN) {
 			if (ctrl->value)
 				reg |= INDYCAM_CONTROL_AGCENA;
 			else
@@ -239,34 +244,34 @@ static int indycam_set_control(struct i2
 				reg &= ~INDYCAM_CONTROL_AWBCTL;
 		}
 
-		ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
+		ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
 		break;
-	case INDYCAM_CONTROL_SHUTTER:
+	case V4L2_CID_EXPOSURE:
 		reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
-		ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
+		ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
 		break;
-	case INDYCAM_CONTROL_GAIN:
-		ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
+	case V4L2_CID_GAIN:
+		ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
 		break;
-	case INDYCAM_CONTROL_RED_BALANCE:
-		ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
+	case V4L2_CID_RED_BALANCE:
+		ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
 					ctrl->value);
 		break;
-	case INDYCAM_CONTROL_BLUE_BALANCE:
-		ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
+	case V4L2_CID_BLUE_BALANCE:
+		ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
 					ctrl->value);
 		break;
 	case INDYCAM_CONTROL_RED_SATURATION:
-		ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION,
+		ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
 					ctrl->value);
 		break;
 	case INDYCAM_CONTROL_BLUE_SATURATION:
-		ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
+		ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
 					ctrl->value);
 		break;
-	case INDYCAM_CONTROL_GAMMA:
+	case V4L2_CID_GAMMA:
 		if (camera->version == CAMERA_VERSION_MOOSE) {
-			ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
+			ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
 						ctrl->value);
 		}
 		break;
@@ -279,192 +284,103 @@ static int indycam_set_control(struct i2
 
 /* I2C-interface */
 
-static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
+static int indycam_g_chip_ident(struct v4l2_subdev *sd,
+		struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct indycam *camera = to_indycam(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
+		       camera->version);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops indycam_core_ops = {
+	.g_chip_ident = indycam_g_chip_ident,
+	.g_ctrl = indycam_g_ctrl,
+	.s_ctrl = indycam_s_ctrl,
+};
+
+static const struct v4l2_subdev_ops indycam_ops = {
+	.core = &indycam_core_ops,
+};
+
+static int indycam_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
 {
 	int err = 0;
 	struct indycam *camera;
-	struct i2c_client *client;
+	struct v4l2_subdev *sd;
 
-	printk(KERN_INFO "SGI IndyCam driver version %s\n",
-	       INDYCAM_MODULE_VERSION);
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
 	camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
-	if (!camera) {
-		err = -ENOMEM;
-		goto out_free_client;
-	}
-
-	client->addr = addr;
-	client->adapter = adap;
-	client->driver = &i2c_driver_indycam;
-	client->flags = 0;
-	strcpy(client->name, "IndyCam client");
-	i2c_set_clientdata(client, camera);
-
-	camera->client = client;
+	if (!camera)
+		return -ENOMEM;
 
-	err = i2c_attach_client(client);
-	if (err)
-		goto out_free_camera;
+	sd = &camera->sd;
+	v4l2_i2c_subdev_init(sd, client, &indycam_ops);
 
 	camera->version = i2c_smbus_read_byte_data(client,
 						   INDYCAM_REG_VERSION);
 	if (camera->version != CAMERA_VERSION_INDY &&
 	    camera->version != CAMERA_VERSION_MOOSE) {
-		err = -ENODEV;
-		goto out_detach_client;
+		kfree(camera);
+		return -ENODEV;
 	}
+
 	printk(KERN_INFO "IndyCam v%d.%d detected\n",
 	       INDYCAM_VERSION_MAJOR(camera->version),
 	       INDYCAM_VERSION_MINOR(camera->version));
 
-	indycam_regdump(client);
+	indycam_regdump(sd);
 
 	// initialize
-	err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
+	err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
 	if (err) {
 		printk(KERN_ERR "IndyCam initialization failed\n");
-		err = -EIO;
-		goto out_detach_client;
+		kfree(camera);
+		return -EIO;
 	}
 
-	indycam_regdump(client);
+	indycam_regdump(sd);
 
 	// white balance
-	err = indycam_write_reg(client, INDYCAM_REG_CONTROL,
+	err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
 			  INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
 	if (err) {
 		printk(KERN_ERR "IndyCam: White balancing camera failed\n");
-		err = -EIO;
-		goto out_detach_client;
+		kfree(camera);
+		return -EIO;
 	}
 
-	indycam_regdump(client);
+	indycam_regdump(sd);
 
 	printk(KERN_INFO "IndyCam initialized\n");
 
 	return 0;
-
-out_detach_client:
-	i2c_detach_client(client);
-out_free_camera:
-	kfree(camera);
-out_free_client:
-	kfree(client);
-	return err;
 }
 
-static int indycam_probe(struct i2c_adapter *adap)
-{
-	/* Indy specific crap */
-	if (adap->id == I2C_HW_SGI_VINO)
-		return indycam_attach(adap, INDYCAM_ADDR, 0);
-	/* Feel free to add probe here :-) */
-	return -ENODEV;
-}
-
-static int indycam_detach(struct i2c_client *client)
-{
-	struct indycam *camera = i2c_get_clientdata(client);
-
-	i2c_detach_client(client);
-	kfree(camera);
-	kfree(client);
-	return 0;
-}
-
-static int indycam_command(struct i2c_client *client, unsigned int cmd,
-			   void *arg)
+static int indycam_remove(struct i2c_client *client)
 {
-	// struct indycam *camera = i2c_get_clientdata(client);
-
-	/* The old video_decoder interface just isn't enough,
-	 * so we'll use some custom commands. */
-	switch (cmd) {
-	case DECODER_GET_CAPABILITIES: {
-		struct video_decoder_capability *cap = arg;
-
-		cap->flags  = VIDEO_DECODER_NTSC;
-		cap->inputs = 1;
-		cap->outputs = 1;
-		break;
-	}
-	case DECODER_GET_STATUS: {
-		int *iarg = arg;
-
-		*iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC |
-			DECODER_STATUS_COLOR;
-		break;
-	}
-	case DECODER_SET_NORM: {
-		int *iarg = arg;
-
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
-	case DECODER_SET_INPUT:	{
-		int *iarg = arg;
-
-		if (*iarg != 0)
-			return -EINVAL;
-		break;
-	}
-	case DECODER_SET_OUTPUT: {
-		int *iarg = arg;
-
-		if (*iarg != 0)
-			return -EINVAL;
-		break;
-	}
-	case DECODER_ENABLE_OUTPUT: {
-		/* Always enabled */
-		break;
-	}
-	case DECODER_SET_PICTURE: {
-		// struct video_picture *pic = arg;
-		/* TODO: convert values for indycam_set_controls() */
-		break;
-	}
-	case DECODER_INDYCAM_GET_CONTROL: {
-		return indycam_get_control(client, arg);
-	}
-	case DECODER_INDYCAM_SET_CONTROL: {
-		return indycam_set_control(client, arg);
-	}
-	default:
-		return -EINVAL;
-	}
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_indycam(sd));
 	return 0;
 }
 
-static struct i2c_driver i2c_driver_indycam = {
-	.driver = {
-		.name 	= "indycam",
-	},
-	.id		= I2C_DRIVERID_INDYCAM,
-	.attach_adapter = indycam_probe,
-	.detach_client	= indycam_detach,
-	.command	= indycam_command,
+static const struct i2c_device_id indycam_id[] = {
+	{ "indycam", 0 },
+	{ }
 };
+MODULE_DEVICE_TABLE(i2c, indycam_id);
 
-static int __init indycam_init(void)
-{
-	return i2c_add_driver(&i2c_driver_indycam);
-}
-
-static void __exit indycam_exit(void)
-{
-	i2c_del_driver(&i2c_driver_indycam);
-}
-
-module_init(indycam_init);
-module_exit(indycam_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "indycam",
+	.probe = indycam_probe,
+	.remove = indycam_remove,
+	.id_table = indycam_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/indycam.h linux-libre-2.6.30-gnu1/drivers/media/video/indycam.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/indycam.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/indycam.h	2009-06-09 23:05:27.000000000 -0400
@@ -87,22 +87,7 @@
 
 /* Driver interface definitions */
 
-#define INDYCAM_CONTROL_AGC			0	/* boolean */
-#define INDYCAM_CONTROL_AWB			1	/* boolean */
-#define INDYCAM_CONTROL_SHUTTER			2
-#define INDYCAM_CONTROL_GAIN			3
-#define INDYCAM_CONTROL_RED_BALANCE		4
-#define INDYCAM_CONTROL_BLUE_BALANCE		5
-#define INDYCAM_CONTROL_RED_SATURATION		6
-#define INDYCAM_CONTROL_BLUE_SATURATION		7
-#define INDYCAM_CONTROL_GAMMA			8
-
-struct indycam_control {
-	u8 type;
-	s32 value;
-};
-
-#define	DECODER_INDYCAM_GET_CONTROL	_IOR('d', 193, struct indycam_control)
-#define	DECODER_INDYCAM_SET_CONTROL	_IOW('d', 194, struct indycam_control)
+#define INDYCAM_CONTROL_RED_SATURATION		(V4L2_CID_PRIVATE_BASE + 0)
+#define INDYCAM_CONTROL_BLUE_SATURATION		(V4L2_CID_PRIVATE_BASE + 1)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ir-kbd-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/ir-kbd-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ir-kbd-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ir-kbd-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,8 @@
  *      Henry Wong <henry@stuffedcow.net>
  *      Mark Schultz <n9xmj@yahoo.com>
  *      Brian Rogers <brian_rogers@comcast.net>
+ * modified for AVerMedia Cardbus by
+ *      Oldrich Jedlicka <oldium.pro@seznam.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
@@ -216,6 +218,46 @@ static int get_key_knc1(struct IR_i2c *i
 	return 1;
 }
 
+static int get_key_avermedia_cardbus(struct IR_i2c *ir,
+				     u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char subaddr, key, keygroup;
+	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+				   .buf = &subaddr, .len = 1},
+				 { .addr = ir->c.addr, .flags = I2C_M_RD,
+				  .buf = &key, .len = 1} };
+	subaddr = 0x0d;
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+
+	if (key == 0xff)
+		return 0;
+
+	subaddr = 0x0b;
+	msg[1].buf = &keygroup;
+	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+		dprintk(1, "read error\n");
+		return -EIO;
+	}
+
+	if (keygroup == 0xff)
+		return 0;
+
+	dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+	if (keygroup < 2 || keygroup > 3) {
+		/* Only a warning */
+		dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
+								keygroup, key);
+	}
+	key |= (keygroup & 1) << 6;
+
+	*ir_key = key;
+	*ir_raw = key;
+	return 1;
+}
+
 /* ----------------------------------------------------------------------- */
 
 static void ir_key_poll(struct IR_i2c *ir)
@@ -237,15 +279,9 @@ static void ir_key_poll(struct IR_i2c *i
 	}
 }
 
-static void ir_timer(unsigned long data)
-{
-	struct IR_i2c *ir = (struct IR_i2c*)data;
-	schedule_work(&ir->work);
-}
-
 static void ir_work(struct work_struct *work)
 {
-	struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
+	struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
 	int polling_interval = 100;
 
 	/* MSI TV@nywhere Plus requires more frequent polling
@@ -254,7 +290,7 @@ static void ir_work(struct work_struct *
 		polling_interval = 50;
 
 	ir_key_poll(ir);
-	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(polling_interval));
 }
 
 /* ----------------------------------------------------------------------- */
@@ -360,6 +396,12 @@ static int ir_attach(struct i2c_adapter
 			ir_type     = IR_TYPE_OTHER;
 		}
 		break;
+	case 0x40:
+		name        = "AVerMedia Cardbus remote";
+		ir->get_key = get_key_avermedia_cardbus;
+		ir_type     = IR_TYPE_OTHER;
+		ir_codes    = ir_codes_avermedia_cardbus;
+		break;
 	default:
 		/* shouldn't happen */
 		printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
@@ -404,11 +446,8 @@ static int ir_attach(struct i2c_adapter
 	       ir->input->name, ir->input->phys, adap->name);
 
 	/* start polling via eventd */
-	INIT_WORK(&ir->work, ir_work);
-	init_timer(&ir->timer);
-	ir->timer.function = ir_timer;
-	ir->timer.data     = (unsigned long)ir;
-	schedule_work(&ir->work);
+	INIT_DELAYED_WORK(&ir->work, ir_work);
+	schedule_delayed_work(&ir->work, 0);
 
 	return 0;
 
@@ -425,8 +464,7 @@ static int ir_detach(struct i2c_client *
 	struct IR_i2c *ir = i2c_get_clientdata(client);
 
 	/* kill outstanding polls */
-	del_timer_sync(&ir->timer);
-	flush_scheduled_work();
+	cancel_delayed_work_sync(&ir->work);
 
 	/* unregister devices */
 	input_unregister_device(ir->input);
@@ -524,6 +562,22 @@ static int ir_probe(struct i2c_adapter *
 			ir_attach(adap, msg.addr, 0, 0);
 	}
 
+	/* Special case for AVerMedia Cardbus remote */
+	if (adap->id == I2C_HW_SAA7134) {
+		unsigned char subaddr, data;
+		struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
+					   .buf = &subaddr, .len = 1},
+					 { .addr = 0x40, .flags = I2C_M_RD,
+					   .buf = &data, .len = 1} };
+		subaddr = 0x0d;
+		rc = i2c_transfer(adap, msg, 2);
+		dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
+			msg[0].addr, subaddr, adap->name,
+			(2 == rc) ? "yes" : "no");
+		if (2 == rc)
+			ir_attach(adap, msg[0].addr, 0, 0);
+	}
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-controls.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-controls.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,7 @@
 #include "ivtv-mailbox.h"
 #include "ivtv-controls.h"
 
+/* Must be sorted from low to high control ID! */
 static const u32 user_ctrls[] = {
 	V4L2_CID_USER_CLASS,
 	V4L2_CID_BRIGHTNESS,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-driver.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-driver.c	2013-05-03 16:44:18.000000000 -0400
@@ -305,14 +305,17 @@ int ivtv_waitq(wait_queue_head_t *waitq)
 /* Generic utility functions */
 int ivtv_msleep_timeout(unsigned int msecs, int intr)
 {
-	int ret;
 	int timeout = msecs_to_jiffies(msecs);
 
 	do {
 		set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 		timeout = schedule_timeout(timeout);
-		if (intr && (ret = signal_pending(current)))
-			return ret;
+		if (intr) {
+			int ret = signal_pending(current);
+
+			if (ret)
+				return ret;
+		}
 	} while (timeout);
 	return 0;
 }
@@ -357,7 +360,7 @@ void ivtv_read_eeprom(struct ivtv *itv,
 static void ivtv_process_eeprom(struct ivtv *itv)
 {
 	struct tveeprom tv;
-	int pci_slot = PCI_SLOT(itv->dev->devfn);
+	int pci_slot = PCI_SLOT(itv->pdev->devfn);
 
 	ivtv_read_eeprom(itv, &tv);
 
@@ -604,7 +607,7 @@ static void ivtv_process_options(struct
 	itv->std = ivtv_parse_std(itv);
 	if (itv->std == 0 && tunertype >= 0)
 		itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
-	itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
+	itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
 	chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
 	if (itv->options.cardtype == -1) {
 		IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
@@ -617,9 +620,9 @@ static void ivtv_process_options(struct
 		IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
 	}
 	if (itv->card == NULL) {
-		if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
-		    itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
-		    itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
+		if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
+		    itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
+		    itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
 			itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
 			IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
 					chipname);
@@ -630,13 +633,13 @@ static void ivtv_process_options(struct
 			if (itv->card->pci_list == NULL)
 				continue;
 			for (j = 0; itv->card->pci_list[j].device; j++) {
-				if (itv->dev->device !=
+				if (itv->pdev->device !=
 				    itv->card->pci_list[j].device)
 					continue;
-				if (itv->dev->subsystem_vendor !=
+				if (itv->pdev->subsystem_vendor !=
 				    itv->card->pci_list[j].subsystem_vendor)
 					continue;
-				if (itv->dev->subsystem_device !=
+				if (itv->pdev->subsystem_device !=
 				    itv->card->pci_list[j].subsystem_device)
 					continue;
 				IVTV_INFO("Autodetected %s card (%s based)\n",
@@ -650,9 +653,9 @@ done:
 	if (itv->card == NULL) {
 		itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
 		IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
-		     itv->dev->vendor, itv->dev->device);
+		     itv->pdev->vendor, itv->pdev->device);
 		IVTV_ERR("              subsystem vendor/device: [%04x:%04x]\n",
-		     itv->dev->subsystem_vendor, itv->dev->subsystem_device);
+		     itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
 		IVTV_ERR("              %s based\n", chipname);
 		IVTV_ERR("Defaulting to %s card\n", itv->card->name);
 		IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
@@ -671,7 +674,7 @@ done:
  */
 static int __devinit ivtv_init_struct1(struct ivtv *itv)
 {
-	itv->base_addr = pci_resource_start(itv->dev, 0);
+	itv->base_addr = pci_resource_start(itv->pdev, 0);
 	itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
 	itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
 
@@ -682,7 +685,7 @@ static int __devinit ivtv_init_struct1(s
 	spin_lock_init(&itv->lock);
 	spin_lock_init(&itv->dma_reg_lock);
 
-	itv->irq_work_queues = create_singlethread_workqueue(itv->device.name);
+	itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name);
 	if (itv->irq_work_queues == NULL) {
 		IVTV_ERR("Could not create ivtv workqueue\n");
 		return -1;
@@ -766,7 +769,7 @@ static void __devinit ivtv_init_struct2(
 	itv->audio_input = itv->card->video_inputs[i].audio_index;
 }
 
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
+static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
 			  const struct pci_device_id *pci_id)
 {
 	u16 cmd;
@@ -775,11 +778,11 @@ static int ivtv_setup_pci(struct ivtv *i
 
 	IVTV_DEBUG_INFO("Enabling pci device\n");
 
-	if (pci_enable_device(dev)) {
+	if (pci_enable_device(pdev)) {
 		IVTV_ERR("Can't enable device!\n");
 		return -EIO;
 	}
-	if (pci_set_dma_mask(dev, 0xffffffff)) {
+	if (pci_set_dma_mask(pdev, 0xffffffff)) {
 		IVTV_ERR("No suitable DMA available.\n");
 		return -EIO;
 	}
@@ -805,11 +808,11 @@ static int ivtv_setup_pci(struct ivtv *i
 	}
 
 	/* Check for bus mastering */
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
 	if (!(cmd & PCI_COMMAND_MASTER)) {
 		IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
-		pci_set_master(dev);
-		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		pci_set_master(pdev);
+		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
 		if (!(cmd & PCI_COMMAND_MASTER)) {
 			IVTV_ERR("Bus Mastering is not enabled\n");
 			return -ENXIO;
@@ -817,26 +820,26 @@ static int ivtv_setup_pci(struct ivtv *i
 	}
 	IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
 
-	pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
+	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
 
 	if (pci_latency < 64 && ivtv_pci_latency) {
 		IVTV_INFO("Unreasonably low latency timer, "
 			       "setting to 64 (was %d)\n", pci_latency);
-		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-		pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+		pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
 	}
 	/* This config space value relates to DMA latencies. The
 	   default value 0x8080 is too low however and will lead
 	   to DMA errors. 0xffff is the max value which solves
 	   these problems. */
-	pci_write_config_dword(dev, 0x40, 0xffff);
+	pci_write_config_dword(pdev, 0x40, 0xffff);
 
 	IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
 		   "irq: %d, latency: %d, memory: 0x%lx\n",
-		   itv->dev->device, card_rev, dev->bus->number,
-		   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
-		   itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
+		   pdev->device, card_rev, pdev->bus->number,
+		   PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+		   pdev->irq, pci_latency, (unsigned long)itv->base_addr);
 
 	return 0;
 }
@@ -884,12 +887,9 @@ static void ivtv_load_and_init_modules(s
 	}
 	else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
 		 itv->card->type == IVTV_CARD_GV_MVPRX2E) {
-		struct v4l2_crystal_freq crystal_freq;
-
 		/* The crystal frequency of GVMVPRX is 24.576MHz */
-		crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;
-		crystal_freq.flags = SAA7115_FREQ_FL_UCGC;
-		v4l2_subdev_call(itv->sd_video, video, s_crystal_freq, &crystal_freq);
+		v4l2_subdev_call(itv->sd_video, video, s_crystal_freq,
+			SAA7115_FREQ_24_576_MHZ, SAA7115_FREQ_FL_UCGC);
 	}
 
 	if (hw & IVTV_HW_CX25840) {
@@ -935,7 +935,7 @@ static void ivtv_load_and_init_modules(s
 	}
 }
 
-static int __devinit ivtv_probe(struct pci_dev *dev,
+static int __devinit ivtv_probe(struct pci_dev *pdev,
 				const struct pci_device_id *pci_id)
 {
 	int retval = 0;
@@ -945,17 +945,17 @@ static int __devinit ivtv_probe(struct p
 	itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
 	if (itv == NULL)
 		return -ENOMEM;
-	itv->dev = dev;
+	itv->pdev = pdev;
 	itv->instance = atomic_inc_return(&ivtv_instance) - 1;
 
-	retval = v4l2_device_register(&dev->dev, &itv->device);
+	retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
 	if (retval) {
 		kfree(itv);
 		return retval;
 	}
 	/* "ivtv + PCI ID" is a bit of a mouthful, so use
 	   "ivtv + instance" instead. */
-	snprintf(itv->device.name, sizeof(itv->device.name),
+	snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
 			"ivtv%d", itv->instance);
 	IVTV_INFO("Initializing card %d\n", itv->instance);
 
@@ -972,12 +972,11 @@ static int __devinit ivtv_probe(struct p
 	IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
 
 	/* PCI Device Setup */
-	if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
-		if (retval == -EIO)
-			goto free_workqueue;
-		else if (retval == -ENXIO)
-			goto free_mem;
-	}
+	retval = ivtv_setup_pci(itv, pdev, pci_id);
+	if (retval == -EIO)
+		goto free_workqueue;
+	if (retval == -ENXIO)
+		goto free_mem;
 
 	/* map io memory */
 	IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -1154,8 +1153,8 @@ static int __devinit ivtv_probe(struct p
 	ivtv_set_irq_mask(itv, 0xffffffff);
 
 	/* Register IRQ */
-	retval = request_irq(itv->dev->irq, ivtv_irq_handler,
-	     IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv);
+	retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
+	     IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
 	if (retval) {
 		IVTV_ERR("Failed to register irq %d\n", retval);
 		goto free_i2c;
@@ -1177,7 +1176,7 @@ static int __devinit ivtv_probe(struct p
 free_streams:
 	ivtv_streams_cleanup(itv, 1);
 free_irq:
-	free_irq(itv->dev->irq, (void *)itv);
+	free_irq(itv->pdev->irq, (void *)itv);
 free_i2c:
 	exit_ivtv_i2c(itv);
 free_io:
@@ -1194,7 +1193,7 @@ err:
 		retval = -ENODEV;
 	IVTV_ERR("Error %d on initialization\n", retval);
 
-	v4l2_device_unregister(&itv->device);
+	v4l2_device_unregister(&itv->v4l2_dev);
 	kfree(itv);
 	return retval;
 }
@@ -1235,7 +1234,7 @@ int ivtv_init_on_first_open(struct ivtv
 	if (itv->card->hw_all & IVTV_HW_CX25840) {
 		struct v4l2_control ctrl;
 
-		v4l2_subdev_call(itv->sd_video, core, init, 0);
+		v4l2_subdev_call(itv->sd_video, core, load_fw);
 		/* CX25840_CID_ENABLE_PVR150_WORKAROUND */
 		ctrl.id = V4L2_CID_PRIVATE_BASE;
 		ctrl.value = itv->pvr150_workaround;
@@ -1292,10 +1291,10 @@ int ivtv_init_on_first_open(struct ivtv
 	return 0;
 }
 
-static void ivtv_remove(struct pci_dev *pci_dev)
+static void ivtv_remove(struct pci_dev *pdev)
 {
-	struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev);
-	struct ivtv *itv = to_ivtv(dev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct ivtv *itv = to_ivtv(v4l2_dev);
 	int i;
 
 	IVTV_DEBUG_INFO("Removing card\n");
@@ -1336,11 +1335,9 @@ static void ivtv_remove(struct pci_dev *
 	ivtv_streams_cleanup(itv, 1);
 	ivtv_udma_free(itv);
 
-	v4l2_device_unregister(&itv->device);
-
 	exit_ivtv_i2c(itv);
 
-	free_irq(itv->dev->irq, (void *)itv);
+	free_irq(itv->pdev->irq, (void *)itv);
 	ivtv_iounmap(itv);
 
 	release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
@@ -1348,11 +1345,13 @@ static void ivtv_remove(struct pci_dev *
 	if (itv->has_cx23415)
 		release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
 
-	pci_disable_device(itv->dev);
+	pci_disable_device(itv->pdev);
 	for (i = 0; i < IVTV_VBI_FRAMES; i++)
 		kfree(itv->vbi.sliced_mpeg_data[i]);
 
 	printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
+
+	v4l2_device_unregister(&itv->v4l2_dev);
 	kfree(itv);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-driver.h linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-driver.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-driver.h	2009-06-09 23:05:27.000000000 -0400
@@ -133,7 +133,7 @@ extern int ivtv_debug;
 #define IVTV_DEBUG(x, type, fmt, args...) \
 	do { \
 		if ((x) & ivtv_debug) \
-			v4l2_info(&itv->device, " " type ": " fmt , ##args);	\
+			v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args);	\
 	} while (0)
 #define IVTV_DEBUG_WARN(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
 #define IVTV_DEBUG_INFO(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
@@ -149,7 +149,7 @@ extern int ivtv_debug;
 #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
 	do { \
 		if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) 	\
-			v4l2_info(&itv->device, " " type ": " fmt , ##args);	\
+			v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args);	\
 	} while (0)
 #define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
 #define IVTV_DEBUG_HI_INFO(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
@@ -163,9 +163,9 @@ extern int ivtv_debug;
 #define IVTV_DEBUG_HI_YUV(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV,   "yuv",   fmt , ## args)
 
 /* Standard kernel messages */
-#define IVTV_ERR(fmt, args...)      v4l2_err(&itv->device, fmt , ## args)
-#define IVTV_WARN(fmt, args...)     v4l2_warn(&itv->device, fmt , ## args)
-#define IVTV_INFO(fmt, args...)     v4l2_info(&itv->device, fmt , ## args)
+#define IVTV_ERR(fmt, args...)      v4l2_err(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_WARN(fmt, args...)     v4l2_warn(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_INFO(fmt, args...)     v4l2_info(&itv->v4l2_dev, fmt , ## args)
 
 /* output modes (cx23415 only) */
 #define OUT_NONE        0
@@ -315,7 +315,7 @@ struct ivtv;				/* forward reference */
 struct ivtv_stream {
 	/* These first four fields are always set, even if the stream
 	   is not actually created. */
-	struct video_device *v4l2dev;	/* NULL when stream not created */
+	struct video_device *vdev;	/* NULL when stream not created */
 	struct ivtv *itv; 		/* for ease of use */
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
@@ -592,7 +592,7 @@ struct ivtv_card;
 /* Struct to hold info about ivtv cards */
 struct ivtv {
 	/* General fixed card data */
-	struct pci_dev *dev;		/* PCI device */
+	struct pci_dev *pdev;		/* PCI device */
 	const struct ivtv_card *card;	/* card information */
 	const char *card_name;          /* full name of the card */
 	const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
@@ -612,7 +612,7 @@ struct ivtv {
 	volatile void __iomem *reg_mem; /* pointer to mapped registers */
 	struct ivtv_options options; 	/* user options */
 
-	struct v4l2_device device;
+	struct v4l2_device v4l2_dev;
 	struct v4l2_subdev sd_gpio;	/* GPIO sub-device */
 	u16 instance;
 
@@ -696,7 +696,7 @@ struct ivtv {
 	u64 vbi_data_inserted;          /* number of VBI bytes inserted into the MPEG stream */
 	u32 last_dec_timing[3];         /* cache last retrieved pts/scr/frame values */
 	unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
-	u16 dualwatch_stereo_mode;      /* current detected dualwatch stereo mode */
+	u32 dualwatch_stereo_mode;      /* current detected dualwatch stereo mode */
 
 
 	/* VBI state info */
@@ -719,9 +719,9 @@ struct ivtv {
 	struct osd_info *osd_info;      /* ivtvfb private OSD info */
 };
 
-static inline struct ivtv *to_ivtv(struct v4l2_device *dev)
+static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
 {
-	return container_of(dev, struct ivtv, device);
+	return container_of(v4l2_dev, struct ivtv, v4l2_dev);
 }
 
 /* Globals */
@@ -788,7 +788,7 @@ static inline int ivtv_raw_vbi(const str
 /* Call the specified callback for all subdevs matching hw (if 0, then
    match them all). Ignore any errors. */
 #define ivtv_call_hw(itv, hw, o, f, args...) 				\
-	__v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+	__v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
 
 #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
 
@@ -796,7 +796,7 @@ static inline int ivtv_raw_vbi(const str
    match them all). If the callback returns an error other than 0 or
    -ENOIOCTLCMD, then return with that error code. */
 #define ivtv_call_hw_err(itv, hw, o, f, args...)  		\
-	__v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+	__v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
 
 #define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtvfb.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtvfb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtvfb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtvfb.c	2009-06-09 23:05:27.000000000 -0400
@@ -298,7 +298,8 @@ static int ivtvfb_prep_dec_dma_to_device
 	prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
 	/* if no UDMA is pending and no UDMA is in progress, then the DMA
 	   is finished */
-	while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
+	while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
+	       test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
 		/* don't interrupt if the DMA is in progress but break off
 		   a still pending DMA. */
 		got_sig = signal_pending(current);
@@ -1192,12 +1193,12 @@ static int ivtvfb_init_card(struct ivtv
 static int __init ivtvfb_callback_init(struct device *dev, void *p)
 {
 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
-	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
 
 	if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
 		if (ivtvfb_init_card(itv) == 0) {
 			IVTVFB_INFO("Framebuffer registered on %s\n",
-					itv->device.name);
+					itv->v4l2_dev.name);
 			(*(int *)p)++;
 		}
 	}
@@ -1207,7 +1208,7 @@ static int __init ivtvfb_callback_init(s
 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
 {
 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
-	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
 
 	if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
 		if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-fileops.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-fileops.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-fileops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-fileops.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_str
 static void ivtv_dualwatch(struct ivtv *itv)
 {
 	struct v4l2_tuner vt;
-	u16 new_bitmap;
-	u16 new_stereo_mode;
-	const u16 stereo_mask = 0x0300;
-	const u16 dual = 0x0200;
+	u32 new_bitmap;
+	u32 new_stereo_mode;
+	const u32 stereo_mask = 0x0300;
+	const u32 dual = 0x0200;
 
 	new_stereo_mode = itv->params.audio_properties & stereo_mask;
 	memset(&vt, 0, sizeof(vt));
@@ -857,15 +857,12 @@ int ivtv_v4l2_close(struct file *filp)
 		/* Mark that the radio is no longer in use */
 		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
 		/* Switch tuner to TV */
-		ivtv_call_all(itv, tuner, s_std, itv->std);
+		ivtv_call_all(itv, core, s_std, itv->std);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		ivtv_audio_set_io(itv);
-		if (itv->hw_flags & IVTV_HW_SAA711X)
-		{
-			struct v4l2_crystal_freq crystal_freq;
-			crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
-			crystal_freq.flags = 0;
-			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
+		if (itv->hw_flags & IVTV_HW_SAA711X) {
+			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
+					SAA7115_FREQ_32_11_MHZ, 0);
 		}
 		if (atomic_read(&itv->capturing) > 0) {
 			/* Undo video mute */
@@ -956,10 +953,8 @@ static int ivtv_serialized_open(struct i
 		/* Select the correct audio input (i.e. radio tuner) */
 		ivtv_audio_set_io(itv);
 		if (itv->hw_flags & IVTV_HW_SAA711X) {
-			struct v4l2_crystal_freq crystal_freq;
-			crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
-			crystal_freq.flags = SAA7115_FREQ_FL_APLL;
-			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, &crystal_freq);
+			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
+				SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
 		}
 		/* Done! Unmute and continue. */
 		ivtv_unmute(itv);
@@ -991,7 +986,7 @@ 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",
-				s->v4l2dev->minor);
+				vdev->minor);
 		mutex_unlock(&itv->serialize_lock);
 		return -ENXIO;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-firmware.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-firmware.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-firmware.c	2013-05-03 18:02:01.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-firmware.c	2013-05-03 16:45:51.000000000 -0400
@@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn
 	int retries = 3;
 
 retry:
-	if (retries && reject_firmware(&fw, fn, &itv->dev->dev) == 0) {
+	if (retries && reject_firmware(&fw, fn, &itv->pdev->dev) == 0) {
 		int i;
 		volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
 		const u32 *src = (const u32 *)fw->data;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-gpio.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-gpio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -190,8 +190,8 @@ static int subdev_g_tuner(struct v4l2_su
 
 	mask = itv->card->gpio_audio_detect.mask;
 	if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
-		vt->rxsubchans = V4L2_TUNER_MODE_STEREO |
-			V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
+		vt->rxsubchans = V4L2_TUNER_SUB_STEREO |
+			V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
 	else
 		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
 	return 0;
@@ -248,15 +248,16 @@ static int subdev_s_std(struct v4l2_subd
 	return 0;
 }
 
-static int subdev_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_audio_routing(struct v4l2_subdev *sd,
+				  u32 input, u32 output, u32 config)
 {
 	struct ivtv *itv = sd_to_ivtv(sd);
 	u16 mask, data;
 
-	if (route->input > 2)
+	if (input > 2)
 		return -EINVAL;
 	mask = itv->card->gpio_audio_input.mask;
-	switch (route->input) {
+	switch (input) {
 	case 0:
 		data = itv->card->gpio_audio_input.tuner;
 		break;
@@ -318,17 +319,18 @@ static int subdev_log_status(struct v4l2
 	return 0;
 }
 
-static int subdev_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int subdev_s_video_routing(struct v4l2_subdev *sd,
+				  u32 input, u32 output, u32 config)
 {
 	struct ivtv *itv = sd_to_ivtv(sd);
 	u16 mask, data;
 
-	if (route->input > 2) /* 0:Tuner 1:Composite 2:S-Video */
+	if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
 		return -EINVAL;
 	mask = itv->card->gpio_video_input.mask;
-	if  (route->input == 0)
+	if (input == 0)
 		data = itv->card->gpio_video_input.tuner;
-	else if  (route->input == 1)
+	else if (input == 1)
 		data = itv->card->gpio_video_input.composite;
 	else
 		data = itv->card->gpio_video_input.svideo;
@@ -342,10 +344,10 @@ static const struct v4l2_subdev_core_ops
 	.g_ctrl = subdev_g_ctrl,
 	.s_ctrl = subdev_s_ctrl,
 	.queryctrl = subdev_queryctrl,
+	.s_std = subdev_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
-	.s_std = subdev_s_std,
 	.s_radio = subdev_s_radio,
 	.g_tuner = subdev_g_tuner,
 	.s_tuner = subdev_s_tuner,
@@ -384,7 +386,7 @@ int ivtv_gpio_init(struct ivtv *itv)
 	write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
 	write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
 	v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
-	snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name);
+	snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
 	itv->sd_gpio.grp_id = IVTV_HW_GPIO;
-	return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio);
+	return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -161,15 +161,18 @@ int ivtv_i2c_register(struct ivtv *itv,
 		return -1;
 	if (hw == IVTV_HW_TUNER) {
 		/* special tuner handling */
-		sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+				adap, mod, type,
 				itv->card_i2c->radio);
 		if (sd)
 			sd->grp_id = 1 << idx;
-		sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+				adap, mod, type,
 				itv->card_i2c->demod);
 		if (sd)
 			sd->grp_id = 1 << idx;
-		sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+				adap, mod, type,
 				itv->card_i2c->tv);
 		if (sd)
 			sd->grp_id = 1 << idx;
@@ -178,11 +181,11 @@ int ivtv_i2c_register(struct ivtv *itv,
 	if (!hw_addrs[idx])
 		return -1;
 	if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
-		unsigned short addrs[2] = { hw_addrs[idx], I2C_CLIENT_END };
-
-		sd = v4l2_i2c_new_probed_subdev(adap, mod, type, addrs);
+		sd = v4l2_i2c_new_probed_subdev_addr(&itv->v4l2_dev,
+				adap, mod, type, hw_addrs[idx]);
 	} else {
-		sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
+		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
+				adap, mod, type, hw_addrs[idx]);
 	}
 	if (sd)
 		sd->grp_id = 1 << idx;
@@ -194,14 +197,14 @@ struct v4l2_subdev *ivtv_find_hw(struct
 	struct v4l2_subdev *result = NULL;
 	struct v4l2_subdev *sd;
 
-	spin_lock(&itv->device.lock);
-	v4l2_device_for_each_subdev(sd, &itv->device) {
+	spin_lock(&itv->v4l2_dev.lock);
+	v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
 		if (sd->grp_id == hw) {
 			result = sd;
 			break;
 		}
 	}
-	spin_unlock(&itv->device.lock);
+	spin_unlock(&itv->v4l2_dev.lock);
 	return result;
 }
 
@@ -472,8 +475,8 @@ static int ivtv_read(struct ivtv *itv, u
    intervening stop condition */
 static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
 {
-	struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
-	struct ivtv *itv = to_ivtv(drv);
+	struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+	struct ivtv *itv = to_ivtv(v4l2_dev);
 	int retval;
 	int i;
 
@@ -604,12 +607,12 @@ int init_ivtv_i2c(struct ivtv *itv)
 
 	sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
 		itv->instance);
-	i2c_set_adapdata(&itv->i2c_adap, &itv->device);
+	i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
 
 	memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
 	       sizeof(struct i2c_client));
 	itv->i2c_client.adapter = &itv->i2c_adap;
-	itv->i2c_adap.dev.parent = &itv->dev->dev;
+	itv->i2c_adap.dev.parent = &itv->pdev->dev;
 
 	IVTV_DEBUG_I2C("setting scl and sda to 1\n");
 	ivtv_setscl(itv, 1);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-ioctl.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -180,7 +180,7 @@ int ivtv_set_speed(struct ivtv *itv, int
 
 		/* Wait for any DMA to finish */
 		prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
-		while (itv->i_flags & IVTV_F_I_DMA) {
+		while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
 			got_sig = signal_pending(current);
 			if (got_sig)
 				break;
@@ -345,10 +345,8 @@ static int ivtv_g_fmt_vid_cap(struct fil
 	pixfmt->priv = 0;
 	if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
 		pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
-		/* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
-		pixfmt->sizeimage =
-			pixfmt->height * pixfmt->width +
-			pixfmt->height * (pixfmt->width / 2);
+		/* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+		pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
 		pixfmt->bytesperline = 720;
 	} else {
 		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -469,11 +467,17 @@ static int ivtv_try_fmt_vid_cap(struct f
 	struct ivtv *itv = id->itv;
 	int w = fmt->fmt.pix.width;
 	int h = fmt->fmt.pix.height;
+	int min_h = 2;
 
 	w = min(w, 720);
 	w = max(w, 2);
+	if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+		/* YUV height must be a multiple of 32 */
+		h &= ~0x1f;
+		min_h = 32;
+	}
 	h = min(h, itv->is_50hz ? 576 : 480);
-	h = max(h, 2);
+	h = max(h, min_h);
 	ivtv_g_fmt_vid_cap(file, fh, fmt);
 	fmt->fmt.pix.width = w;
 	fmt->fmt.pix.height = h;
@@ -766,7 +770,7 @@ static int ivtv_querycap(struct file *fi
 
 	strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
 	strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
-	snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
+	snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
 	vcap->version = IVTV_DRIVER_VERSION; 	    /* version */
 	vcap->capabilities = itv->v4l2_cap; 	    /* capabilities */
 	return 0;
@@ -1029,7 +1033,6 @@ static int ivtv_g_output(struct file *fi
 static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
 {
 	struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
-	struct v4l2_routing route;
 
 	if (outp >= itv->card->nof_outputs)
 		return -EINVAL;
@@ -1042,9 +1045,9 @@ static int ivtv_s_output(struct file *fi
 		   itv->active_output, outp);
 
 	itv->active_output = outp;
-	route.input = SAA7127_INPUT_TYPE_NORMAL;
-	route.output = itv->card->video_outputs[outp].video_output;
-	ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, &route);
+	ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
+			SAA7127_INPUT_TYPE_NORMAL,
+			itv->card->video_outputs[outp].video_output, 0);
 
 	return 0;
 }
@@ -1117,7 +1120,7 @@ int ivtv_s_std(struct file *file, void *
 	IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
 
 	/* Tuner */
-	ivtv_call_all(itv, tuner, s_std, itv->std);
+	ivtv_call_all(itv, core, s_std, itv->std);
 
 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
 		/* set display standard */
@@ -1513,12 +1516,12 @@ static int ivtv_log_status(struct file *
 	}
 	IVTV_INFO("Tuner:  %s\n",
 		test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
-	cx2341x_log_status(&itv->params, itv->device.name);
+	cx2341x_log_status(&itv->params, itv->v4l2_dev.name);
 	IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);
 	for (i = 0; i < IVTV_MAX_STREAMS; i++) {
 		struct ivtv_stream *s = &itv->streams[i];
 
-		if (s->v4l2dev == NULL || s->buffers == 0)
+		if (s->vdev == NULL || s->buffers == 0)
 			continue;
 		IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
 				(s->buffers - s->q_free.buffers) * 100 / s->buffers,
@@ -1707,7 +1710,8 @@ static int ivtv_decoder_ioctls(struct fi
 			   we are waiting unlock first and later lock again. */
 			mutex_unlock(&itv->serialize_lock);
 			prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
-			if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
+			if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
+			    !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
 				schedule();
 			finish_wait(&itv->event_waitq, &wait);
 			mutex_lock(&itv->serialize_lock);
@@ -1731,13 +1735,6 @@ static long ivtv_default(struct file *fi
 	struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
 	switch (cmd) {
-	case VIDIOC_INT_S_AUDIO_ROUTING: {
-		struct v4l2_routing *route = arg;
-
-		ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, route);
-		break;
-	}
-
 	case VIDIOC_INT_RESET: {
 		u32 val = *(u32 *)arg;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-irq.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-irq.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct
 
 	IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
 	if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
-			s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+			s->vdev == NULL || !ivtv_use_pio(s)) {
 		itv->cur_pio_stream = -1;
 		/* trigger PIO complete user interrupt */
 		write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
@@ -109,7 +109,7 @@ static int stream_enc_dma_append(struct
 	int rc;
 
 	/* sanity checks */
-	if (s->v4l2dev == NULL) {
+	if (s->vdev == NULL) {
 		IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
 		return -1;
 	}
@@ -196,7 +196,7 @@ static int stream_enc_dma_append(struct
 				bytes_needed, s->name);
 		return -1;
 	}
-	if (rc && !s->buffers_stolen && (s->s_flags & IVTV_F_S_APPL_IO)) {
+	if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) {
 		IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
 		IVTV_WARN("Cause: the application is not reading fast enough.\n");
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-queue.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-queue.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-queue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-queue.c	2009-06-09 23:05:27.000000000 -0400
@@ -230,7 +230,8 @@ int ivtv_stream_alloc(struct ivtv_stream
 		return -ENOMEM;
 	}
 	if (ivtv_might_use_dma(s)) {
-		s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
+		s->sg_handle = pci_map_single(itv->pdev, s->sg_dma,
+				sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 		ivtv_stream_sync_for_cpu(s);
 	}
 
@@ -248,7 +249,7 @@ int ivtv_stream_alloc(struct ivtv_stream
 		}
 		INIT_LIST_HEAD(&buf->list);
 		if (ivtv_might_use_dma(s)) {
-			buf->dma_handle = pci_map_single(s->itv->dev,
+			buf->dma_handle = pci_map_single(s->itv->pdev,
 				buf->buf, s->buf_size + 256, s->dma);
 			ivtv_buf_sync_for_cpu(s, buf);
 		}
@@ -271,7 +272,7 @@ void ivtv_stream_free(struct ivtv_stream
 	/* empty q_free */
 	while ((buf = ivtv_dequeue(s, &s->q_free))) {
 		if (ivtv_might_use_dma(s))
-			pci_unmap_single(s->itv->dev, buf->dma_handle,
+			pci_unmap_single(s->itv->pdev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 		kfree(buf->buf);
 		kfree(buf);
@@ -280,7 +281,7 @@ void ivtv_stream_free(struct ivtv_stream
 	/* Free SG Array/Lists */
 	if (s->sg_dma != NULL) {
 		if (s->sg_handle != IVTV_DMA_UNMAPPED) {
-			pci_unmap_single(s->itv->dev, s->sg_handle,
+			pci_unmap_single(s->itv->pdev, s->sg_handle,
 				 sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 			s->sg_handle = IVTV_DMA_UNMAPPED;
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-queue.h linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-queue.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-queue.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-queue.h	2009-06-09 23:05:27.000000000 -0400
@@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct iv
 static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
 	if (ivtv_use_dma(s))
-		pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
+		pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 }
 
 static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
 {
 	if (ivtv_use_dma(s))
-		pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
+		pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
 				s->buf_size + 256, s->dma);
 }
 
@@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream
 static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
 {
 	if (ivtv_use_dma(s))
-		pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle,
+		pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
 			sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 }
 
 static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
 {
 	if (ivtv_use_dma(s))
-		pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle,
+		pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
 			sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-routing.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-routing.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-routing.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-routing.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,7 +34,7 @@
 void ivtv_audio_set_io(struct ivtv *itv)
 {
 	const struct ivtv_card_audio_input *in;
-	struct v4l2_routing route;
+	u32 input, output = 0;
 
 	/* Determine which input to use */
 	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
@@ -43,73 +43,77 @@ void ivtv_audio_set_io(struct ivtv *itv)
 		in = &itv->card->audio_inputs[itv->audio_input];
 
 	/* handle muxer chips */
-	route.input = in->muxer_input;
-	route.output = 0;
+	input = in->muxer_input;
 	if (itv->card->hw_muxer & IVTV_HW_M52790)
-		route.output = M52790_OUT_STEREO;
-	v4l2_subdev_call(itv->sd_muxer, audio, s_routing, &route);
+		output = M52790_OUT_STEREO;
+	v4l2_subdev_call(itv->sd_muxer, audio, s_routing,
+			input, output, 0);
 
-	route.input = in->audio_input;
-	route.output = 0;
+	input = in->audio_input;
+	output = 0;
 	if (itv->card->hw_audio & IVTV_HW_MSP34XX)
-		route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-	ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, &route);
+		output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+	ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
+			input, output, 0);
 }
 
 /* Selects the video input and output according to the current
    settings. */
 void ivtv_video_set_io(struct ivtv *itv)
 {
-	struct v4l2_routing route;
 	int inp = itv->active_input;
+	u32 input;
 	u32 type;
 
-	route.input = itv->card->video_inputs[inp].video_input;
-	route.output = 0;
-	v4l2_subdev_call(itv->sd_video, video, s_routing, &route);
+	v4l2_subdev_call(itv->sd_video, video, s_routing,
+		itv->card->video_inputs[inp].video_input, 0, 0);
 
 	type = itv->card->video_inputs[inp].video_type;
 
 	if (type == IVTV_CARD_INPUT_VID_TUNER) {
-		route.input = 0;  /* Tuner */
+		input = 0;  /* Tuner */
 	} else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
-		route.input = 2;  /* S-Video */
+		input = 2;  /* S-Video */
 	} else {
-		route.input = 1;  /* Composite */
+		input = 1;  /* Composite */
 	}
 
 	if (itv->card->hw_video & IVTV_HW_GPIO)
-		ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing,
+				input, 0, 0);
 
 	if (itv->card->hw_video & IVTV_HW_UPD64031A) {
 		if (type == IVTV_CARD_INPUT_VID_TUNER ||
 		    type >= IVTV_CARD_INPUT_COMPOSITE1) {
 			/* Composite: GR on, connect to 3DYCS */
-			route.input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
+			input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
 		} else {
 			/* S-Video: GR bypassed, turn it off */
-			route.input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
+			input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
 		}
-		route.input |= itv->card->gr_config;
+		input |= itv->card->gr_config;
 
-		ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing,
+				input, 0, 0);
 	}
 
 	if (itv->card->hw_video & IVTV_HW_UPD6408X) {
-		route.input = UPD64083_YCS_MODE;
+		input = UPD64083_YCS_MODE;
 		if (type > IVTV_CARD_INPUT_VID_TUNER &&
 		    type < IVTV_CARD_INPUT_COMPOSITE1) {
-			/* S-Video uses YCNR mode and internal Y-ADC, the upd64031a
-			   is not used. */
-			route.input |= UPD64083_YCNR_MODE;
+			/* S-Video uses YCNR mode and internal Y-ADC, the
+			   upd64031a is not used. */
+			input |= UPD64083_YCNR_MODE;
 		}
 		else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
-		  /* Use upd64031a output for tuner and composite(CX23416GYC only) inputs */
-		  if ((type == IVTV_CARD_INPUT_VID_TUNER)||
-		      (itv->card->type == IVTV_CARD_CX23416GYC)) {
-		    route.input |= UPD64083_EXT_Y_ADC;
-		  }
+			/* Use upd64031a output for tuner and
+			   composite(CX23416GYC only) inputs */
+			if (type == IVTV_CARD_INPUT_VID_TUNER ||
+			    itv->card->type == IVTV_CARD_CX23416GYC) {
+				input |= UPD64083_EXT_Y_ADC;
+			}
 		}
-		ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, &route);
+		ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing,
+				input, 0, 0);
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-streams.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-streams.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-streams.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,11 +137,11 @@ static struct {
 static void ivtv_stream_init(struct ivtv *itv, int type)
 {
 	struct ivtv_stream *s = &itv->streams[type];
-	struct video_device *dev = s->v4l2dev;
+	struct video_device *vdev = s->vdev;
 
-	/* we need to keep v4l2dev, so restore it afterwards */
+	/* we need to keep vdev, so restore it afterwards */
 	memset(s, 0, sizeof(*s));
-	s->v4l2dev = dev;
+	s->vdev = vdev;
 
 	/* initialize ivtv_stream fields */
 	s->itv = itv;
@@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *it
 	int num_offset = ivtv_stream_info[type].num_offset;
 	int num = itv->instance + ivtv_first_minor + num_offset;
 
-	/* These four fields are always initialized. If v4l2dev == NULL, then
+	/* These four fields are always initialized. If vdev == NULL, then
 	   this stream is not in use. In that case no other fields but these
 	   four can be used. */
-	s->v4l2dev = NULL;
+	s->vdev = NULL;
 	s->itv = itv;
 	s->type = type;
 	s->name = ivtv_stream_info[type].name;
@@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *it
 	ivtv_stream_init(itv, type);
 
 	/* allocate and initialize the v4l2 video device structure */
-	s->v4l2dev = video_device_alloc();
-	if (s->v4l2dev == NULL) {
+	s->vdev = video_device_alloc();
+	if (s->vdev == NULL) {
 		IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
 		return -ENOMEM;
 	}
 
-	snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s",
-			itv->device.name, s->name);
+	snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
+			itv->v4l2_dev.name, s->name);
 
-	s->v4l2dev->num = num;
-	s->v4l2dev->v4l2_dev = &itv->device;
-	s->v4l2dev->fops = ivtv_stream_info[type].fops;
-	s->v4l2dev->release = video_device_release;
-	s->v4l2dev->tvnorms = V4L2_STD_ALL;
-	ivtv_set_funcs(s->v4l2dev);
+	s->vdev->num = num;
+	s->vdev->v4l2_dev = &itv->v4l2_dev;
+	s->vdev->fops = ivtv_stream_info[type].fops;
+	s->vdev->release = video_device_release;
+	s->vdev->tvnorms = V4L2_STD_ALL;
+	ivtv_set_funcs(s->vdev);
 	return 0;
 }
 
@@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv)
 		if (ivtv_prep_dev(itv, type))
 			break;
 
-		if (itv->streams[type].v4l2dev == NULL)
+		if (itv->streams[type].vdev == NULL)
 			continue;
 
 		/* Allocate Stream */
@@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv
 	int vfl_type = ivtv_stream_info[type].vfl_type;
 	int num;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return 0;
 
-	num = s->v4l2dev->num;
+	num = s->vdev->num;
 	/* card number + user defined offset + device offset */
 	if (type != IVTV_ENC_STREAM_TYPE_MPG) {
 		struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
 
-		if (s_mpg->v4l2dev)
-			num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
+		if (s_mpg->vdev)
+			num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
 	}
-	video_set_drvdata(s->v4l2dev, s);
+	video_set_drvdata(s->vdev, s);
 
 	/* Register device. First try the desired minor, then any free one. */
-	if (video_register_device(s->v4l2dev, vfl_type, num)) {
+	if (video_register_device(s->vdev, vfl_type, num)) {
 		IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
 				s->name, num);
-		video_device_release(s->v4l2dev);
-		s->v4l2dev = NULL;
+		video_device_release(s->vdev);
+		s->vdev = NULL;
 		return -ENOMEM;
 	}
-	num = s->v4l2dev->num;
+	num = s->vdev->num;
 
 	switch (vfl_type) {
 	case VFL_TYPE_GRABBER:
@@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *i
 
 	/* Teardown all streams */
 	for (type = 0; type < IVTV_MAX_STREAMS; type++) {
-		struct video_device *vdev = itv->streams[type].v4l2dev;
+		struct video_device *vdev = itv->streams[type].vdev;
 
-		itv->streams[type].v4l2dev = NULL;
+		itv->streams[type].vdev = NULL;
 		if (vdev == NULL)
 			continue;
 
@@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct
 	int captype = 0, subtype = 0;
 	int enable_passthrough = 0;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return -EINVAL;
 
 	IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream
 	struct cx2341x_mpeg_params *p = &itv->params;
 	int datatype;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return -EINVAL;
 
 	IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
@@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct
 {
 	struct ivtv *itv = s->itv;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return -EINVAL;
 
 	if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
@@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv
 	for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
 		struct ivtv_stream *s = &itv->streams[i];
 
-		if (s->v4l2dev == NULL)
+		if (s->vdev == NULL)
 			continue;
 		if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
 			ivtv_stop_v4l2_encode_stream(s, 0);
@@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct
 	int cap_type;
 	int stopmode;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return -EINVAL;
 
 	/* This function assumes that you are allowed to stop the capture
@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct
 {
 	struct ivtv *itv = s->itv;
 
-	if (s->v4l2dev == NULL)
+	if (s->vdev == NULL)
 		return -EINVAL;
 
 	if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
@@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *i
 	struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
 	struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
 
-	if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL)
+	if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
 		return -EINVAL;
 
 	IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-udma.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-udma.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-udma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-udma.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,7 +93,7 @@ void ivtv_udma_alloc(struct ivtv *itv)
 {
 	if (itv->udma.SG_handle == 0) {
 		/* Map DMA Page Array Buffer */
-		itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray,
+		itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
 			   sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
 		ivtv_udma_sync_for_cpu(itv);
 	}
@@ -147,7 +147,7 @@ int ivtv_udma_setup(struct ivtv *itv, un
 	}
 
 	/* Map SG List */
-	dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+	dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
 
 	/* Fill SG Array with new values */
 	ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
@@ -172,7 +172,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
 
 	/* Unmap Scatterlist */
 	if (dma->SG_length) {
-		pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+		pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
 		dma->SG_length = 0;
 	}
 	/* sync DMA */
@@ -191,13 +191,13 @@ void ivtv_udma_free(struct ivtv *itv)
 
 	/* Unmap SG Array */
 	if (itv->udma.SG_handle) {
-		pci_unmap_single(itv->dev, itv->udma.SG_handle,
+		pci_unmap_single(itv->pdev, itv->udma.SG_handle,
 			 sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
 	}
 
 	/* Unmap Scatterlist */
 	if (itv->udma.SG_length) {
-		pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
+		pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
 	}
 
 	for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-udma.h linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-udma.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-udma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-udma.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv);
 
 static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
 {
-	pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+	pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
 		sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
 }
 
 static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
 {
-	pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+	pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
 		sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-vbi.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-vbi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-vbi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-vbi.c	2009-06-09 23:05:27.000000000 -0400
@@ -185,6 +185,8 @@ static void copy_vbi_data(struct ivtv *i
 		size = 4 + ((43 * line + 3) & ~3);
 	} else {
 		memcpy(dst + sd, "itv0", 4);
+		cpu_to_le32s(&linemask[0]);
+		cpu_to_le32s(&linemask[1]);
 		memcpy(dst + sd + 4, &linemask[0], 8);
 		size = 12 + ((43 * line + 3) & ~3);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-version.h linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-version.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-version.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-version.h	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@
 #define IVTV_DRIVER_NAME "ivtv"
 #define IVTV_DRIVER_VERSION_MAJOR 1
 #define IVTV_DRIVER_VERSION_MINOR 4
-#define IVTV_DRIVER_VERSION_PATCHLEVEL 0
+#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
 
 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
 #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-yuv.c linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-yuv.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ivtv/ivtv-yuv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-yuv.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct
 		dma->page_count = 0;
 		return -ENOMEM;
 	}
-	dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+	dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
 
 	/* Fill SG Array with new values */
 	ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
@@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *i
 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
 	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
 	if (yi->blanking_ptr) {
-		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
+		yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
 	} else {
 		yi->blanking_dmaptr = 0;
 		IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
@@ -1063,7 +1063,8 @@ static int ivtv_yuv_udma_frame(struct iv
 	prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
 	/* if no UDMA is pending and no UDMA is in progress, then the DMA
 	   is finished */
-	while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
+	while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
+	       test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
 		/* don't interrupt if the DMA is in progress but break off
 		   a still pending DMA. */
 		got_sig = signal_pending(current);
@@ -1237,7 +1238,7 @@ void ivtv_yuv_close(struct ivtv *itv)
 	if (yi->blanking_ptr) {
 		kfree(yi->blanking_ptr);
 		yi->blanking_ptr = NULL;
-		pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
+		pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
 	}
 
 	/* Invalidate the old dimension information */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -249,11 +249,25 @@ config VIDEO_VP27SMPX
 	  To compile this driver as a module, choose M here: the
 	  module will be called vp27smpx.
 
+comment "RDS decoders"
+
+config VIDEO_SAA6588
+	tristate "SAA6588 Radio Chip RDS decoder support"
+	depends on VIDEO_V4L2 && I2C
+
+	help
+	  Support for this Radio Data System (RDS) decoder. This allows
+	  seeing radio station identification transmitted using this
+	  standard.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa6588.
+
 comment "Video decoders"
 
 config VIDEO_BT819
 	tristate "BT819A VideoStream decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for BT819A video decoder.
 
@@ -262,7 +276,7 @@ config VIDEO_BT819
 
 config VIDEO_BT856
 	tristate "BT856 VideoStream decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for BT856 video decoder.
 
@@ -271,7 +285,7 @@ config VIDEO_BT856
 
 config VIDEO_BT866
 	tristate "BT866 VideoStream decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for BT866 video decoder.
 
@@ -280,7 +294,7 @@ config VIDEO_BT866
 
 config VIDEO_KS0127
 	tristate "KS0127 video decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for KS0127 video decoder.
 
@@ -307,38 +321,18 @@ config VIDEO_TCM825X
 
 config VIDEO_SAA7110
 	tristate "Philips SAA7110 video decoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the Philips SAA7110 video decoders.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7110.
 
-config VIDEO_SAA7111
-	tristate "Philips SAA7111 video decoder"
-	depends on VIDEO_V4L1 && I2C
-	---help---
-	  Support for the Philips SAA711 video decoder.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa7111.
-
-config VIDEO_SAA7114
-	tristate "Philips SAA7114 video decoder"
-	depends on VIDEO_V4L1 && I2C
-	---help---
-	  Support for the Philips SAA7114 video decoder. This driver
-	  is used only on Zoran driver and should be moved soon to
-	  SAA711x module.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa7114.
-
 config VIDEO_SAA711X
-	tristate "Philips SAA7113/4/5 video decoders"
+	tristate "Philips SAA7111/3/4/5 video decoders"
 	depends on VIDEO_V4L2 && I2C
 	---help---
-	  Support for the Philips SAA7113/4/5 video decoders.
+	  Support for the Philips SAA7111/3/4/5 video decoders.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7115.
@@ -383,7 +377,7 @@ config VIDEO_TVP5150
 
 config VIDEO_VPX3220
 	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for VPX322x video decoders.
 
@@ -421,7 +415,7 @@ config VIDEO_SAA7127
 
 config VIDEO_SAA7185
 	tristate "Philips SAA7185 video encoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the Philips SAA7185 video encoder.
 
@@ -430,7 +424,7 @@ config VIDEO_SAA7185
 
 config VIDEO_ADV7170
 	tristate "Analog Devices ADV7170 video encoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the Analog Devices ADV7170 video encoder driver
 
@@ -439,7 +433,7 @@ config VIDEO_ADV7170
 
 config VIDEO_ADV7175
 	tristate "Analog Devices ADV7175 video encoder"
-	depends on VIDEO_V4L1 && I2C
+	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the Analog Devices ADV7175 video encoder driver
 
@@ -487,18 +481,6 @@ config VIDEO_VIVI
 
 source "drivers/media/video/bt8xx/Kconfig"
 
-config VIDEO_SAA6588
-	tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
-	depends on I2C && VIDEO_BT848
-
-	help
-	  Support for  Radio Data System (RDS) decoder. This allows seeing
-	  radio station identification transmitted using this standard.
-	  Currently, it works only with bt8x8 chips.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa6588.
-
 config VIDEO_PMS
 	tristate "Mediavision Pro Movie Studio Video For Linux"
 	depends on ISA && VIDEO_V4L1
@@ -602,7 +584,6 @@ config VIDEO_SAA5249
 config VIDEO_VINO
 	tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
 	depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
-	select I2C_ALGO_SGI
 	select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
 	help
 	  Say Y here to build in support for the Vino video input system found
@@ -639,7 +620,7 @@ config VIDEO_MXB
 	depends on PCI && VIDEO_V4L1 && I2C
 	select VIDEO_SAA7146_VV
 	select VIDEO_TUNER
-	select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
@@ -728,13 +709,6 @@ config SOC_CAMERA_MT9M001
 	  This driver supports MT9M001 cameras from Micron, monochrome
 	  and colour models.
 
-config MT9M001_PCA9536_SWITCH
-	bool "pca9536 datawidth switch for mt9m001"
-	depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO
-	help
-	  Select this if your MT9M001 camera uses a PCA9536 I2C GPIO
-	  extender to switch between 8 and 10 bit datawidth modes
-
 config SOC_CAMERA_MT9M111
 	tristate "mt9m111 and mt9m112 support"
 	depends on SOC_CAMERA && I2C
@@ -754,13 +728,6 @@ config SOC_CAMERA_MT9V022
 	help
 	  This driver supports MT9V022 cameras from Micron
 
-config MT9V022_PCA9536_SWITCH
-	bool "pca9536 datawidth switch for mt9v022"
-	depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO
-	help
-	  Select this if your MT9V022 camera uses a PCA9536 I2C GPIO
-	  extender to switch between 8 and 10 bit datawidth modes
-
 config SOC_CAMERA_TW9910
 	tristate "tw9910 support"
 	depends on SOC_CAMERA && I2C
@@ -779,6 +746,25 @@ config SOC_CAMERA_OV772X
 	help
 	  This is a ov772x camera driver
 
+config MX1_VIDEO
+	bool
+
+config VIDEO_MX1
+	tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
+	depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
+	select FIQ
+	select VIDEOBUF_DMA_CONTIG
+	select MX1_VIDEO
+	---help---
+	  This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
+
+config VIDEO_MX3
+	tristate "i.MX3x Camera Sensor Interface driver"
+	depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
+	select VIDEOBUF_DMA_CONTIG
+	---help---
+	  This is a v4l2 driver for the i.MX3x Camera Sensor Interface
+
 config VIDEO_PXA27x
 	tristate "PXA27x Quick Capture Interface driver"
 	depends on VIDEO_DEV && PXA27x && SOC_CAMERA
@@ -817,8 +803,12 @@ source "drivers/media/video/gspca/Kconfi
 
 source "drivers/media/video/pvrusb2/Kconfig"
 
+source "drivers/media/video/hdpvr/Kconfig"
+
 source "drivers/media/video/em28xx/Kconfig"
 
+source "drivers/media/video/cx231xx/Kconfig"
+
 source "drivers/media/video/usbvision/Kconfig"
 
 source "drivers/media/video/usbvideo/Kconfig"
@@ -928,5 +918,4 @@ config USB_S2255
 	  This driver can be compiled as a module, called s2255drv.
 
 endif # V4L_USB_DRIVERS
-
 endif # VIDEO_CAPTURE_DRIVERS
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ks0127.c linux-libre-2.6.30-gnu1/drivers/media/video/ks0127.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ks0127.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ks0127.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,19 +39,20 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 #include "ks0127.h"
 
 MODULE_DESCRIPTION("KS0127 video decoder driver");
 MODULE_AUTHOR("Ryan Drake");
 MODULE_LICENSE("GPL");
 
-#define KS_TYPE_UNKNOWN	0
-#define KS_TYPE_0122S	1
-#define KS_TYPE_0127	2
-#define KS_TYPE_0127B	3
+/* Addresses */
+#define I2C_KS0127_ADDON   0xD8
+#define I2C_KS0127_ONBOARD 0xDA
+
 
 /* ks0127 control registers */
 #define KS_STAT     0x00
@@ -197,15 +198,17 @@ struct adjust {
 };
 
 struct ks0127 {
-	int		format_width;
-	int		format_height;
-	int		cap_width;
-	int		cap_height;
-	int		norm;
-	int		ks_type;
+	struct v4l2_subdev sd;
+	v4l2_std_id	norm;
+	int		ident;
 	u8 		regs[256];
 };
 
+static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ks0127, sd);
+}
+
 
 static int debug; /* insmod parameter */
 
@@ -311,43 +314,45 @@ static void init_reg_defaults(void)
  */
 
 
-static u8 ks0127_read(struct i2c_client *c, u8 reg)
+static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	char val = 0;
 	struct i2c_msg msgs[] = {
-		{ c->addr, 0, sizeof(reg), &reg },
-		{ c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+		{ client->addr, 0, sizeof(reg), &reg },
+		{ client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
 	};
 	int ret;
 
-	ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 	if (ret != ARRAY_SIZE(msgs))
-		v4l_dbg(1, debug, c, "read error\n");
+		v4l2_dbg(1, debug, sd, "read error\n");
 
 	return val;
 }
 
 
-static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
+static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
 {
-	struct ks0127 *ks = i2c_get_clientdata(c);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ks0127 *ks = to_ks0127(sd);
 	char msg[] = { reg, val };
 
-	if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
-		v4l_dbg(1, debug, c, "write error\n");
+	if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg))
+		v4l2_dbg(1, debug, sd, "write error\n");
 
 	ks->regs[reg] = val;
 }
 
 
 /* generic bit-twiddling */
-static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
 {
-	struct ks0127 *ks = i2c_get_clientdata(client);
+	struct ks0127 *ks = to_ks0127(sd);
 
 	u8 val = ks->regs[reg];
 	val = (val & and_v) | or_v;
-	ks0127_write(client, reg, val);
+	ks0127_write(sd, reg, val);
 }
 
 
@@ -355,439 +360,360 @@ static void ks0127_and_or(struct i2c_cli
 /****************************************************************************
 * ks0127 private api
 ****************************************************************************/
-static void ks0127_reset(struct i2c_client *c)
+static void ks0127_init(struct v4l2_subdev *sd)
 {
-	struct ks0127 *ks = i2c_get_clientdata(c);
+	struct ks0127 *ks = to_ks0127(sd);
 	u8 *table = reg_defaults;
 	int i;
 
-	ks->ks_type = KS_TYPE_UNKNOWN;
+	ks->ident = V4L2_IDENT_KS0127;
 
-	v4l_dbg(1, debug, c, "reset\n");
+	v4l2_dbg(1, debug, sd, "reset\n");
 	msleep(1);
 
 	/* initialize all registers to known values */
 	/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
 
 	for (i = 1; i < 33; i++)
-		ks0127_write(c, i, table[i]);
+		ks0127_write(sd, i, table[i]);
 
 	for (i = 35; i < 40; i++)
-		ks0127_write(c, i, table[i]);
+		ks0127_write(sd, i, table[i]);
 
 	for (i = 41; i < 56; i++)
-		ks0127_write(c, i, table[i]);
+		ks0127_write(sd, i, table[i]);
 
 	for (i = 58; i < 64; i++)
-		ks0127_write(c, i, table[i]);
+		ks0127_write(sd, i, table[i]);
 
 
-	if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
-		ks->ks_type = KS_TYPE_0122S;
-		v4l_dbg(1, debug, c, "ks0122s found\n");
+	if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
+		ks->ident = V4L2_IDENT_KS0122S;
+		v4l2_dbg(1, debug, sd, "ks0122s found\n");
 		return;
 	}
 
-	switch (ks0127_read(c, KS_CMDE) & 0x0f) {
+	switch (ks0127_read(sd, KS_CMDE) & 0x0f) {
 	case 0:
-		ks->ks_type = KS_TYPE_0127;
-		v4l_dbg(1, debug, c, "ks0127 found\n");
+		v4l2_dbg(1, debug, sd, "ks0127 found\n");
 		break;
 
 	case 9:
-		ks->ks_type = KS_TYPE_0127B;
-		v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
+		ks->ident = V4L2_IDENT_KS0127B;
+		v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
 		break;
 
 	default:
-		v4l_dbg(1, debug, c, "unknown revision\n");
+		v4l2_dbg(1, debug, sd, "unknown revision\n");
 		break;
 	}
 }
 
-static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
+static int ks0127_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
-	struct ks0127 *ks = i2c_get_clientdata(c);
-	int		*iarg = (int *)arg;
-	int		status;
-
-	if (!ks)
-		return -ENODEV;
-
-	switch (cmd) {
-	case DECODER_INIT:
-		v4l_dbg(1, debug, c, "DECODER_INIT\n");
-		ks0127_reset(c);
-		break;
-
-	case DECODER_SET_INPUT:
-		switch(*iarg) {
-		case KS_INPUT_COMPOSITE_1:
-		case KS_INPUT_COMPOSITE_2:
-		case KS_INPUT_COMPOSITE_3:
-		case KS_INPUT_COMPOSITE_4:
-		case KS_INPUT_COMPOSITE_5:
-		case KS_INPUT_COMPOSITE_6:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_INPUT %d: Composite\n", *iarg);
-			/* autodetect 50/60 Hz */
-			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
-			/* VSE=0 */
-			ks0127_and_or(c, KS_CMDA,   ~0x40, 0x00);
-			/* set input line */
-			ks0127_and_or(c, KS_CMDB,   0xb0, *iarg);
-			/* non-freerunning mode */
-			ks0127_and_or(c, KS_CMDC,   0x70, 0x0a);
-			/* analog input */
-			ks0127_and_or(c, KS_CMDD,   0x03, 0x00);
-			/* enable chroma demodulation */
-			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
-			/* chroma trap, HYBWR=1 */
-			ks0127_and_or(c, KS_LUMA,   0x00,
-				       (reg_defaults[KS_LUMA])|0x0c);
-			/* scaler fullbw, luma comb off */
-			ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
-			/* manual chroma comb .25 .5 .25 */
-			ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
-
-			/* chroma path delay */
-			ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
+	struct ks0127 *ks = to_ks0127(sd);
 
-			ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
-			ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
-			ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
-			ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
-			break;
+	switch (input) {
+	case KS_INPUT_COMPOSITE_1:
+	case KS_INPUT_COMPOSITE_2:
+	case KS_INPUT_COMPOSITE_3:
+	case KS_INPUT_COMPOSITE_4:
+	case KS_INPUT_COMPOSITE_5:
+	case KS_INPUT_COMPOSITE_6:
+		v4l2_dbg(1, debug, sd,
+			"s_routing %d: Composite\n", input);
+		/* autodetect 50/60 Hz */
+		ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
+		/* VSE=0 */
+		ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
+		/* set input line */
+		ks0127_and_or(sd, KS_CMDB,   0xb0, input);
+		/* non-freerunning mode */
+		ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
+		/* analog input */
+		ks0127_and_or(sd, KS_CMDD,   0x03, 0x00);
+		/* enable chroma demodulation */
+		ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+		/* chroma trap, HYBWR=1 */
+		ks0127_and_or(sd, KS_LUMA,   0x00,
+			       (reg_defaults[KS_LUMA])|0x0c);
+		/* scaler fullbw, luma comb off */
+		ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
+		/* manual chroma comb .25 .5 .25 */
+		ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
 
-		case KS_INPUT_SVIDEO_1:
-		case KS_INPUT_SVIDEO_2:
-		case KS_INPUT_SVIDEO_3:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_INPUT %d: S-Video\n", *iarg);
-			/* autodetect 50/60 Hz */
-			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
-			/* VSE=0 */
-			ks0127_and_or(c, KS_CMDA,   ~0x40, 0x00);
-			/* set input line */
-			ks0127_and_or(c, KS_CMDB,   0xb0, *iarg);
-			/* non-freerunning mode */
-			ks0127_and_or(c, KS_CMDC,   0x70, 0x0a);
-			/* analog input */
-			ks0127_and_or(c, KS_CMDD,   0x03, 0x00);
-			/* enable chroma demodulation */
-			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
-			ks0127_and_or(c, KS_LUMA, 0x00,
-				       reg_defaults[KS_LUMA]);
-			/* disable luma comb */
-			ks0127_and_or(c, KS_VERTIA, 0x08,
-				       (reg_defaults[KS_VERTIA]&0xf0)|0x01);
-			ks0127_and_or(c, KS_VERTIC, 0x0f,
-				       reg_defaults[KS_VERTIC]&0xf0);
+		/* chroma path delay */
+		ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90);
 
-			ks0127_and_or(c, KS_CHROMB, 0x0f,
-				       reg_defaults[KS_CHROMB]&0xf0);
+		ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+		ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+		ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+		ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+		break;
 
-			ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
-			ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
-			ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
-			ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
-			break;
+	case KS_INPUT_SVIDEO_1:
+	case KS_INPUT_SVIDEO_2:
+	case KS_INPUT_SVIDEO_3:
+		v4l2_dbg(1, debug, sd,
+			"s_routing %d: S-Video\n", input);
+		/* autodetect 50/60 Hz */
+		ks0127_and_or(sd, KS_CMDA,   0xfc, 0x00);
+		/* VSE=0 */
+		ks0127_and_or(sd, KS_CMDA,   ~0x40, 0x00);
+		/* set input line */
+		ks0127_and_or(sd, KS_CMDB,   0xb0, input);
+		/* non-freerunning mode */
+		ks0127_and_or(sd, KS_CMDC,   0x70, 0x0a);
+		/* analog input */
+		ks0127_and_or(sd, KS_CMDD,   0x03, 0x00);
+		/* enable chroma demodulation */
+		ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+		ks0127_and_or(sd, KS_LUMA, 0x00,
+			       reg_defaults[KS_LUMA]);
+		/* disable luma comb */
+		ks0127_and_or(sd, KS_VERTIA, 0x08,
+			       (reg_defaults[KS_VERTIA]&0xf0)|0x01);
+		ks0127_and_or(sd, KS_VERTIC, 0x0f,
+			       reg_defaults[KS_VERTIC]&0xf0);
 
-		case KS_INPUT_YUV656:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_INPUT 15: YUV656\n");
-			if (ks->norm == VIDEO_MODE_NTSC ||
-			    ks->norm == KS_STD_PAL_M)
-				/* force 60 Hz */
-				ks0127_and_or(c, KS_CMDA,   0xfc, 0x03);
-			else
-				/* force 50 Hz */
-				ks0127_and_or(c, KS_CMDA,   0xfc, 0x02);
+		ks0127_and_or(sd, KS_CHROMB, 0x0f,
+			       reg_defaults[KS_CHROMB]&0xf0);
 
-			ks0127_and_or(c, KS_CMDA,   0xff, 0x40); /* VSE=1 */
-			/* set input line and VALIGN */
-			ks0127_and_or(c, KS_CMDB,   0xb0, (*iarg | 0x40));
-			/* freerunning mode, */
-			/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
-			ks0127_and_or(c, KS_CMDC,   0x70, 0x87);
-			/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
-			ks0127_and_or(c, KS_CMDD,   0x03, 0x08);
-			/* disable chroma demodulation */
-			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
-			/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
-			ks0127_and_or(c, KS_LUMA,   0x00, 0x71);
-			ks0127_and_or(c, KS_VERTIC, 0x0f,
-				       reg_defaults[KS_VERTIC]&0xf0);
+		ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+		ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+		ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+		ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+		break;
 
-			/* scaler fullbw, luma comb off */
-			ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
+	case KS_INPUT_YUV656:
+		v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
+		if (ks->norm & V4L2_STD_525_60)
+			/* force 60 Hz */
+			ks0127_and_or(sd, KS_CMDA,   0xfc, 0x03);
+		else
+			/* force 50 Hz */
+			ks0127_and_or(sd, KS_CMDA,   0xfc, 0x02);
 
-			ks0127_and_or(c, KS_CHROMB, 0x0f,
-				       reg_defaults[KS_CHROMB]&0xf0);
+		ks0127_and_or(sd, KS_CMDA,   0xff, 0x40); /* VSE=1 */
+		/* set input line and VALIGN */
+		ks0127_and_or(sd, KS_CMDB,   0xb0, (input | 0x40));
+		/* freerunning mode, */
+		/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
+		ks0127_and_or(sd, KS_CMDC,   0x70, 0x87);
+		/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
+		ks0127_and_or(sd, KS_CMDD,   0x03, 0x08);
+		/* disable chroma demodulation */
+		ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
+		/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
+		ks0127_and_or(sd, KS_LUMA,   0x00, 0x71);
+		ks0127_and_or(sd, KS_VERTIC, 0x0f,
+			       reg_defaults[KS_VERTIC]&0xf0);
 
-			ks0127_and_or(c, KS_CON, 0x00, 0x00);
-			ks0127_and_or(c, KS_BRT, 0x00, 32);	/* spec: 34 */
-				/* spec: 229 (e5) */
-			ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
-			ks0127_and_or(c, KS_HUE, 0x00, 0);
+		/* scaler fullbw, luma comb off */
+		ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
 
-			ks0127_and_or(c, KS_UGAIN, 0x00, 238);
-			ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
+		ks0127_and_or(sd, KS_CHROMB, 0x0f,
+			       reg_defaults[KS_CHROMB]&0xf0);
 
-			/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
-			ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
-			ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
-			break;
+		ks0127_and_or(sd, KS_CON, 0x00, 0x00);
+		ks0127_and_or(sd, KS_BRT, 0x00, 32);	/* spec: 34 */
+			/* spec: 229 (e5) */
+		ks0127_and_or(sd, KS_SAT, 0x00, 0xe8);
+		ks0127_and_or(sd, KS_HUE, 0x00, 0);
 
-		default:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_INPUT: Unknown input %d\n", *iarg);
-			break;
-		}
+		ks0127_and_or(sd, KS_UGAIN, 0x00, 238);
+		ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00);
 
-		/* hack: CDMLPF sometimes spontaneously switches on; */
-		/* force back off */
-		ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
+		/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
+		ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f);
+		ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00);
 		break;
 
-	case DECODER_SET_OUTPUT:
-		switch(*iarg) {
-		case KS_OUTPUT_YUV656E:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
-			return -EINVAL;
-
-		case KS_OUTPUT_EXV:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_OUTPUT: OUTPUT_EXV\n");
-			ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
-			break;
-		}
+	default:
+		v4l2_dbg(1, debug, sd,
+			"s_routing: Unknown input %d\n", input);
 		break;
+	}
 
-	case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
-		/* Set to automatic SECAM/Fsc mode */
-		ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
-
-		ks->norm = *iarg;
-		switch (*iarg) {
-		/* this is untested !! */
-		/* It just detects PAL_N/NTSC_M (no special frequencies) */
-		/* And you have to set the standard a second time afterwards */
-		case VIDEO_MODE_AUTO:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_NORM: AUTO\n");
-
-			/* The chip determines the format */
-			/* based on the current field rate */
-			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
-			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
-			/* This is wrong for PAL ! As I said, */
-			/* you need to set the standard once again !! */
-			ks->format_height = 240;
-			ks->format_width = 704;
-			break;
-
-		case VIDEO_MODE_NTSC:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_NORM: NTSC_M\n");
-			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
-			ks->format_height = 240;
-			ks->format_width = 704;
-			break;
-
-		case KS_STD_NTSC_N:
-			v4l_dbg(1, debug, c,
-				"KS0127_SET_NORM: NTSC_N (fixme)\n");
-			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
-			ks->format_height = 240;
-			ks->format_width = 704;
-			break;
-
-		case VIDEO_MODE_PAL:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_NORM: PAL_N\n");
-			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
-			ks->format_height = 290;
-			ks->format_width = 704;
-			break;
+	/* hack: CDMLPF sometimes spontaneously switches on; */
+	/* force back off */
+	ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]);
+	return 0;
+}
 
-		case KS_STD_PAL_M:
-			v4l_dbg(1, debug, c,
-				"KS0127_SET_NORM: PAL_M (fixme)\n");
-			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
-			ks->format_height = 290;
-			ks->format_width = 704;
-			break;
+static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct ks0127 *ks = to_ks0127(sd);
 
-		case VIDEO_MODE_SECAM:
-			v4l_dbg(1, debug, c,
-				"KS0127_SET_NORM: SECAM\n");
-			ks->format_height = 290;
-			ks->format_width = 704;
+	/* Set to automatic SECAM/Fsc mode */
+	ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
 
-			/* set to secam autodetection */
-			ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
-			ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
-			schedule_timeout_interruptible(HZ/10+1);
+	ks->norm = std;
+	if (std & V4L2_STD_NTSC) {
+		v4l2_dbg(1, debug, sd,
+			"s_std: NTSC_M\n");
+		ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+	} else if (std & V4L2_STD_PAL_N) {
+		v4l2_dbg(1, debug, sd,
+			"s_std: NTSC_N (fixme)\n");
+		ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+	} else if (std & V4L2_STD_PAL) {
+		v4l2_dbg(1, debug, sd,
+			"s_std: PAL_N\n");
+		ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+	} else if (std & V4L2_STD_PAL_M) {
+		v4l2_dbg(1, debug, sd,
+			"s_std: PAL_M (fixme)\n");
+		ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+	} else if (std & V4L2_STD_SECAM) {
+		v4l2_dbg(1, debug, sd,
+			"s_std: SECAM\n");
 
-			/* did it autodetect? */
-			if (ks0127_read(c, KS_DEMOD) & 0x40)
-				break;
+		/* set to secam autodetection */
+		ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
+		ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
+		schedule_timeout_interruptible(HZ/10+1);
 
+		/* did it autodetect? */
+		if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
 			/* force to secam mode */
-			ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
-			break;
-
-		default:
-			v4l_dbg(1, debug, c,
-				"DECODER_SET_NORM: Unknown norm %d\n", *iarg);
-			break;
-		}
-		break;
+			ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
+	} else {
+		v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
+			       (unsigned long long)std);
+	}
+	return 0;
+}
 
-	case DECODER_SET_PICTURE:
-		v4l_dbg(1, debug, c,
-			"DECODER_SET_PICTURE: not yet supported\n");
-		return -EINVAL;
+static int ks0127_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable);
+	if (enable) {
+		/* All output pins on */
+		ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
+		/* Obey the OEN pin */
+		ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
+	} else {
+		/* Video output pins off */
+		ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
+		/* Ignore the OEN pin */
+		ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80);
+	}
+	return 0;
+}
 
-	/* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
-	/* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
-	/* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
-	/* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
-	/* sam todo: KS0127_SET_AGC_MODE: */
-	/* sam todo: KS0127_SET_AGC: */
-	/* sam todo: KS0127_SET_CHROMA_MODE: */
-	/* sam todo: KS0127_SET_PIXCLK_MODE: */
-	/* sam todo: KS0127_SET_GAMMA_MODE: */
-	/* sam todo: KS0127_SET_UGAIN: */
-	/* sam todo: KS0127_SET_VGAIN: */
-	/* sam todo: KS0127_SET_INVALY: */
-	/* sam todo: KS0127_SET_INVALU: */
-	/* sam todo: KS0127_SET_INVALV: */
-	/* sam todo: KS0127_SET_UNUSEY: */
-	/* sam todo: KS0127_SET_UNUSEU: */
-	/* sam todo: KS0127_SET_UNUSEV: */
-	/* sam todo: KS0127_SET_VSALIGN_MODE: */
+static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
+{
+	int stat = V4L2_IN_ST_NO_SIGNAL;
+	u8 status;
+	v4l2_std_id std = V4L2_STD_ALL;
 
-	case DECODER_ENABLE_OUTPUT:
-	{
-		int enable;
+	status = ks0127_read(sd, KS_STAT);
+	if (!(status & 0x20))		 /* NOVID not set */
+		stat = 0;
+	if (!(status & 0x01))		      /* CLOCK set */
+		stat |= V4L2_IN_ST_NO_COLOR;
+	if ((status & 0x08))		   /* PALDET set */
+		std = V4L2_STD_PAL;
+	else
+		std = V4L2_STD_NTSC;
+	if (pstd)
+		*pstd = std;
+	if (pstatus)
+		*pstatus = stat;
+	return 0;
+}
 
-		iarg = arg;
-		enable = (*iarg != 0);
-		if (enable) {
-			v4l_dbg(1, debug, c,
-				"DECODER_ENABLE_OUTPUT on\n");
-			/* All output pins on */
-			ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
-			/* Obey the OEN pin */
-			ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
-		} else {
-			v4l_dbg(1, debug, c,
-				"DECODER_ENABLE_OUTPUT off\n");
-			/* Video output pins off */
-			ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
-			/* Ignore the OEN pin */
-			ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
-		}
-		break;
-	}
+static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	v4l2_dbg(1, debug, sd, "querystd\n");
+	return ks0127_status(sd, NULL, std);
+}
 
-	/* sam todo: KS0127_SET_OUTPUT_MODE: */
-	/* sam todo: KS0127_SET_WIDTH: */
-	/* sam todo: KS0127_SET_HEIGHT: */
-	/* sam todo: KS0127_SET_HSCALE: */
+static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	v4l2_dbg(1, debug, sd, "g_input_status\n");
+	return ks0127_status(sd, status, NULL);
+}
 
-	case DECODER_GET_STATUS:
-		v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
-		*iarg = 0;
-		status = ks0127_read(c, KS_STAT);
-		if (!(status & 0x20))		 /* NOVID not set */
-			*iarg = (*iarg | DECODER_STATUS_GOOD);
-		if ((status & 0x01))		      /* CLOCK set */
-			*iarg = (*iarg | DECODER_STATUS_COLOR);
-		if ((status & 0x08))		   /* PALDET set */
-			*iarg = (*iarg | DECODER_STATUS_PAL);
-		else
-			*iarg = (*iarg | DECODER_STATUS_NTSC);
-		break;
+static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ks0127 *ks = to_ks0127(sd);
 
-	/* Catch any unknown command */
-	default:
-		v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
-		return -EINVAL;
-	}
-	return 0;
+	return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
 }
 
+/* ----------------------------------------------------------------------- */
 
-/* Addresses to scan */
-#define I2C_KS0127_ADDON   0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+static const struct v4l2_subdev_core_ops ks0127_core_ops = {
+	.g_chip_ident = ks0127_g_chip_ident,
+	.s_std = ks0127_s_std,
+};
 
-static unsigned short normal_i2c[] = {
-	I2C_KS0127_ADDON >> 1,
-	I2C_KS0127_ONBOARD >> 1,
-	I2C_CLIENT_END
+static const struct v4l2_subdev_video_ops ks0127_video_ops = {
+	.s_routing = ks0127_s_routing,
+	.s_stream = ks0127_s_stream,
+	.querystd = ks0127_querystd,
+	.g_input_status = ks0127_g_input_status,
 };
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops ks0127_ops = {
+	.core = &ks0127_core_ops,
+	.video = &ks0127_video_ops,
+};
 
-static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
+/* ----------------------------------------------------------------------- */
+
+
+static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct ks0127 *ks;
+	struct v4l2_subdev *sd;
 
-	v4l_info(c, "%s chip found @ 0x%x (%s)\n",
-		c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
-		c->addr << 1, c->adapter->name);
+	v4l_info(client, "%s chip found @ 0x%x (%s)\n",
+		client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+		client->addr << 1, client->adapter->name);
 
 	ks = kzalloc(sizeof(*ks), GFP_KERNEL);
 	if (ks == NULL)
 		return -ENOMEM;
-
-	i2c_set_clientdata(c, ks);
-
-	ks->ks_type = KS_TYPE_UNKNOWN;
+	sd = &ks->sd;
+	v4l2_i2c_subdev_init(sd, client, &ks0127_ops);
 
 	/* power up */
 	init_reg_defaults();
-	ks0127_write(c, KS_CMDA, 0x2c);
+	ks0127_write(sd, KS_CMDA, 0x2c);
 	mdelay(10);
 
 	/* reset the device */
-	ks0127_reset(c);
+	ks0127_init(sd);
 	return 0;
 }
 
-static int ks0127_remove(struct i2c_client *c)
+static int ks0127_remove(struct i2c_client *client)
 {
-	struct ks0127 *ks = i2c_get_clientdata(c);
-
-	ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
-	ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-	kfree(ks);
+	v4l2_device_unregister_subdev(sd);
+	ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
+	ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
+	kfree(to_ks0127(sd));
 	return 0;
 }
 
-static int ks0127_legacy_probe(struct i2c_adapter *adapter)
-{
-	return adapter->id == I2C_HW_B_ZR36067;
-}
-
 static const struct i2c_device_id ks0127_id[] = {
 	{ "ks0127", 0 },
+	{ "ks0127b", 0 },
+	{ "ks0122s", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ks0127_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "ks0127",
-	.driverid = I2C_DRIVERID_KS0127,
-	.command = ks0127_command,
 	.probe = ks0127_probe,
 	.remove = ks0127_remove,
-	.legacy_probe = ks0127_legacy_probe,
 	.id_table = ks0127_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ks0127.h linux-libre-2.6.30-gnu1/drivers/media/video/ks0127.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ks0127.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ks0127.h	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,6 @@
 #ifndef KS0127_H
 #define KS0127_H
 
-#include <linux/videodev.h>
-
 /* input channels */
 #define KS_INPUT_COMPOSITE_1    0
 #define KS_INPUT_COMPOSITE_2    1
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/m52790.c linux-libre-2.6.30-gnu1/drivers/media/video/m52790.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/m52790.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/m52790.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,12 +69,13 @@ static int m52790_write(struct v4l2_subd
    part of the audio output routing. The normal case is that another
    chip takes care of the actual muting so making it part of the
    output routing seems to be the right thing to do for now. */
-static int m52790_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int m52790_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
 	struct m52790_state *state = to_state(sd);
 
-	state->input = route->input;
-	state->output = route->output;
+	state->input = input;
+	state->output = output;
 	m52790_write(sd);
 	return 0;
 }
@@ -132,11 +133,6 @@ static int m52790_log_status(struct v4l2
 	return 0;
 }
 
-static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops m52790_core_ops = {
@@ -210,8 +206,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "m52790",
-	.driverid = I2C_DRIVERID_M52790,
-	.command = m52790_command,
 	.probe = m52790_probe,
 	.remove = m52790_remove,
 	.id_table = m52790_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,7 @@ stkwebcam-objs	:=	stk-webcam.o stk-senso
 
 omap2cam-objs	:=	omap24xxcam.o omap24xxcam-dma.o
 
-videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-subdev.o
+videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o
 
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
 ifeq ($(CONFIG_COMPAT),y)
@@ -30,7 +30,6 @@ obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
 obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
 obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
-obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
 
 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
 obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
@@ -43,8 +42,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
 obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
 obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
 obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
-obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o
-obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o
 obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
 obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
 obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
@@ -70,6 +67,7 @@ obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
 obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
@@ -122,6 +120,8 @@ obj-$(CONFIG_USB_PWC)           += pwc/
 obj-$(CONFIG_USB_ZC0301)        += zc0301/
 obj-$(CONFIG_USB_GSPCA)         += gspca/
 
+obj-$(CONFIG_VIDEO_HDPVR)	+= hdpvr/
+
 obj-$(CONFIG_USB_IBMCAM)        += usbvideo/
 obj-$(CONFIG_USB_KONICAWC)      += usbvideo/
 obj-$(CONFIG_USB_VICAM)         += usbvideo/
@@ -134,10 +134,12 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
 obj-$(CONFIG_VIDEO_VIVI) += vivi.o
 obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
-obj-$(CONFIG_VIDEO_PXA27x)	+= pxa_camera.o
+obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
+obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
+obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
-obj-$(CONFIG_SOC_CAMERA)	+= soc_camera.o
+obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
 obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
 obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/meye.c linux-libre-2.6.30-gnu1/drivers/media/video/meye.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/meye.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/meye.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,7 @@ static int ptable_alloc(void)
 	memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
 
 	/* give only 32 bit DMA addresses */
-	if (dma_set_mask(&meye.mchip_dev->dev, DMA_32BIT_MASK))
+	if (dma_set_mask(&meye.mchip_dev->dev, DMA_BIT_MASK(32)))
 		return -1;
 
 	meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
@@ -1017,7 +1017,6 @@ static int meyeioc_stilljcapt(int *len)
 static int vidioc_querycap(struct file *file, void *fh,
 				struct v4l2_capability *cap)
 {
-	memset(cap, 0, sizeof(*cap));
 	strcpy(cap->driver, "meye");
 	strcpy(cap->card, "meye");
 	sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
@@ -1036,8 +1035,6 @@ static int vidioc_enum_input(struct file
 	if (i->index != 0)
 		return -EINVAL;
 
-	memset(i, 0, sizeof(*i));
-	i->index = 0;
 	strcpy(i->name, "Camera");
 	i->type = V4L2_INPUT_TYPE_CAMERA;
 
@@ -1259,22 +1256,13 @@ static int vidioc_enum_fmt_vid_cap(struc
 	if (f->index > 1)
 		return -EINVAL;
 
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (f->index == 0) {
 		/* standard YUV 422 capture */
-		memset(f, 0, sizeof(*f));
-		f->index = 0;
-		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 		f->flags = 0;
 		strcpy(f->description, "YUV422");
 		f->pixelformat = V4L2_PIX_FMT_YUYV;
 	} else {
 		/* compressed MJPEG capture */
-		memset(f, 0, sizeof(*f));
-		f->index = 1;
-		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 		f->flags = V4L2_FMT_FLAG_COMPRESSED;
 		strcpy(f->description, "MJPEG");
 		f->pixelformat = V4L2_PIX_FMT_MJPEG;
@@ -1286,9 +1274,6 @@ static int vidioc_enum_fmt_vid_cap(struc
 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
 				struct v4l2_format *f)
 {
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
 	    f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
 		return -EINVAL;
@@ -1319,12 +1304,6 @@ static int vidioc_try_fmt_vid_cap(struct
 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
 				    struct v4l2_format *f)
 {
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
 	switch (meye.mchip_mode) {
 	case MCHIP_HIC_MODE_CONT_OUT:
 	default:
@@ -1341,8 +1320,6 @@ static int vidioc_g_fmt_vid_cap(struct f
 	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
 	f->fmt.pix.sizeimage = f->fmt.pix.height *
 			       f->fmt.pix.bytesperline;
-	f->fmt.pix.colorspace = 0;
-	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -1350,9 +1327,6 @@ static int vidioc_g_fmt_vid_cap(struct f
 static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
 				    struct v4l2_format *f)
 {
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
 	    f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
 		return -EINVAL;
@@ -1398,9 +1372,6 @@ static int vidioc_reqbufs(struct file *f
 {
 	int i;
 
-	if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (req->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
@@ -1441,15 +1412,11 @@ static int vidioc_reqbufs(struct file *f
 
 static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
 {
-	int index = buf->index;
+	unsigned int index = buf->index;
 
-	if (index < 0 || index >= gbuffers)
+	if (index >= gbuffers)
 		return -EINVAL;
 
-	memset(buf, 0, sizeof(*buf));
-
-	buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	buf->index = index;
 	buf->bytesused = meye.grab_buffer[index].size;
 	buf->flags = V4L2_BUF_FLAG_MAPPED;
 
@@ -1471,13 +1438,10 @@ static int vidioc_querybuf(struct file *
 
 static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
 {
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
-	if (buf->index < 0 || buf->index >= gbuffers)
+	if (buf->index >= gbuffers)
 		return -EINVAL;
 
 	if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
@@ -1497,9 +1461,6 @@ static int vidioc_dqbuf(struct file *fil
 {
 	int reqnr;
 
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-driver.c linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,7 +56,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <media/msp3400.h>
 #include <media/tvaudio.h>
 #include "msp3400-driver.h"
@@ -108,10 +108,6 @@ MODULE_PARM_DESC(dolby, "Activates Dolby
 /* DSP unit subaddress */
 #define I2C_MSP_DSP     0x12
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
 
 /* ----------------------------------------------------------------------- */
 /* functions for talking to the MSP3400C Sound processor                   */
@@ -366,29 +362,6 @@ int msp_sleep(struct msp_state *state, i
 }
 
 /* ------------------------------------------------------------------------ */
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode)
-{
-	if (rxsubchans == V4L2_TUNER_SUB_MONO)
-		return VIDEO_SOUND_MONO;
-	if (rxsubchans == V4L2_TUNER_SUB_STEREO)
-		return VIDEO_SOUND_STEREO;
-	if (audmode == V4L2_TUNER_MODE_LANG2)
-		return VIDEO_SOUND_LANG2;
-	return VIDEO_SOUND_LANG1;
-}
-
-static int msp_mode_v4l1_to_v4l2(int mode)
-{
-	if (mode & VIDEO_SOUND_STEREO)
-		return V4L2_TUNER_MODE_STEREO;
-	if (mode & VIDEO_SOUND_LANG2)
-		return V4L2_TUNER_MODE_LANG2;
-	if (mode & VIDEO_SOUND_LANG1)
-		return V4L2_TUNER_MODE_LANG1;
-	return V4L2_TUNER_MODE_MONO;
-}
-#endif
 
 static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
@@ -482,96 +455,6 @@ static int msp_s_ctrl(struct v4l2_subdev
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	struct msp_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	switch (cmd) {
-	/* --- v4l ioctls --- */
-	/* take care: bttv does userspace copying, we'll get a
-	   kernel pointer here... */
-	case VIDIOCGAUDIO:
-	{
-		struct video_audio *va = arg;
-
-		va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE;
-		if (state->has_sound_processing)
-			va->flags |= VIDEO_AUDIO_BALANCE |
-				VIDEO_AUDIO_BASS |
-				VIDEO_AUDIO_TREBLE;
-		if (state->muted)
-			va->flags |= VIDEO_AUDIO_MUTE;
-		va->volume = state->volume;
-		va->balance = state->volume ? state->balance : 32768;
-		va->bass = state->bass;
-		va->treble = state->treble;
-
-		if (state->radio)
-			break;
-		if (state->opmode == OPMODE_AUTOSELECT)
-			msp_detect_stereo(client);
-		va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode);
-		break;
-	}
-
-	case VIDIOCSAUDIO:
-	{
-		struct video_audio *va = arg;
-
-		state->muted = (va->flags & VIDEO_AUDIO_MUTE);
-		state->volume = va->volume;
-		state->balance = va->balance;
-		state->bass = va->bass;
-		state->treble = va->treble;
-		msp_set_audio(client);
-
-		if (va->mode != 0 && state->radio == 0 &&
-		    state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) {
-			state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
-			msp_set_audmode(client);
-		}
-		break;
-	}
-
-	case VIDIOCSCHAN:
-	{
-		struct video_channel *vc = arg;
-		int update = 0;
-		v4l2_std_id std;
-
-		if (state->radio)
-			update = 1;
-		state->radio = 0;
-		if (vc->norm == VIDEO_MODE_PAL)
-			std = V4L2_STD_PAL;
-		else if (vc->norm == VIDEO_MODE_SECAM)
-			std = V4L2_STD_SECAM;
-		else
-			std = V4L2_STD_NTSC;
-		if (std != state->v4l2_std) {
-			state->v4l2_std = std;
-			update = 1;
-		}
-		if (update)
-			msp_wake_thread(client);
-		break;
-	}
-
-	case VIDIOCSFREQ:
-	{
-		/* new channel -- kick audio carrier scan */
-		msp_wake_thread(client);
-		break;
-	}
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
-#endif
-
 /* --- v4l2 ioctls --- */
 static int msp_s_radio(struct v4l2_subdev *sd)
 {
@@ -622,25 +505,26 @@ static int msp_s_std(struct v4l2_subdev
 	return 0;
 }
 
-static int msp_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int msp_s_routing(struct v4l2_subdev *sd,
+			 u32 input, u32 output, u32 config)
 {
 	struct msp_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int tuner = (rt->input >> 3) & 1;
-	int sc_in = rt->input & 0x7;
-	int sc1_out = rt->output & 0xf;
-	int sc2_out = (rt->output >> 4) & 0xf;
+	int tuner = (input >> 3) & 1;
+	int sc_in = input & 0x7;
+	int sc1_out = output & 0xf;
+	int sc2_out = (output >> 4) & 0xf;
 	u16 val, reg;
 	int i;
 	int extern_input = 1;
 
-	if (state->routing.input == rt->input &&
-			state->routing.output == rt->output)
+	if (state->route_in == input && state->route_out == output)
 		return 0;
-	state->routing = *rt;
+	state->route_in = input;
+	state->route_out = output;
 	/* check if the tuner input is used */
 	for (i = 0; i < 5; i++) {
-		if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
+		if (((input >> (4 + i * 4)) & 0xf) == 0)
 			extern_input = 0;
 	}
 	state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
@@ -713,22 +597,24 @@ static int msp_queryctrl(struct v4l2_sub
 	struct msp_state *state = to_state(sd);
 
 	switch (qc->id) {
-		case V4L2_CID_AUDIO_VOLUME:
-		case V4L2_CID_AUDIO_MUTE:
-			return v4l2_ctrl_query_fill_std(qc);
-		default:
-			break;
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+	default:
+		break;
 	}
 	if (!state->has_sound_processing)
 		return -EINVAL;
 	switch (qc->id) {
-		case V4L2_CID_AUDIO_LOUDNESS:
-		case V4L2_CID_AUDIO_BALANCE:
-		case V4L2_CID_AUDIO_BASS:
-		case V4L2_CID_AUDIO_TREBLE:
-			return v4l2_ctrl_query_fill_std(qc);
-		default:
-			return -EINVAL;
+	case V4L2_CID_AUDIO_LOUDNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
+	default:
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -788,7 +674,7 @@ static int msp_log_status(struct v4l2_su
 	}
 	v4l_info(client, "Audmode:  0x%04x\n", state->audmode);
 	v4l_info(client, "Routing:  0x%08x (input) 0x%08x (output)\n",
-			state->routing.input, state->routing.output);
+			state->route_in, state->route_out);
 	v4l_info(client, "ACB:      0x%04x\n", state->acb);
 	return 0;
 }
@@ -807,11 +693,6 @@ static int msp_resume(struct i2c_client
 	return 0;
 }
 
-static int msp_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops msp_core_ops = {
@@ -820,9 +701,7 @@ static const struct v4l2_subdev_core_ops
 	.g_ctrl = msp_g_ctrl,
 	.s_ctrl = msp_s_ctrl,
 	.queryctrl = msp_queryctrl,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-	.ioctl = msp_ioctl,
-#endif
+	.s_std = msp_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
@@ -830,7 +709,6 @@ static const struct v4l2_subdev_tuner_op
 	.g_tuner = msp_g_tuner,
 	.s_tuner = msp_s_tuner,
 	.s_radio = msp_s_radio,
-	.s_std = msp_s_std,
 };
 
 static const struct v4l2_subdev_audio_ops msp_audio_ops = {
@@ -884,8 +762,8 @@ static int msp_probe(struct i2c_client *
 	state->i2s_mode = 0;
 	init_waitqueue_head(&state->wq);
 	/* These are the reset input/output positions */
-	state->routing.input = MSP_INPUT_DEFAULT;
-	state->routing.output = MSP_OUTPUT_DEFAULT;
+	state->route_in = MSP_INPUT_DEFAULT;
+	state->route_out = MSP_OUTPUT_DEFAULT;
 
 	state->rev1 = msp_read_dsp(client, 0x1e);
 	if (state->rev1 != -1)
@@ -1039,8 +917,6 @@ MODULE_DEVICE_TABLE(i2c, msp_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "msp3400",
-	.driverid = I2C_DRIVERID_MSP3400,
-	.command = msp_command,
 	.probe = msp_probe,
 	.remove = msp_remove,
 	.suspend = msp_suspend,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-driver.h linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-driver.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-driver.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-driver.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,7 +80,8 @@ struct msp_state {
 	int i2s_mode;
 	int main, second;	/* sound carrier */
 	int input;
-	struct v4l2_routing routing;
+	u32 route_in;
+	u32 route_out;
 
 	/* v4l2 */
 	int audmode;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-kthreads.c linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-kthreads.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/msp3400-kthreads.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/msp3400-kthreads.c	2009-06-09 23:05:27.000000000 -0400
@@ -188,7 +188,7 @@ void msp3400c_set_mode(struct i2c_client
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
 	struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
-	int tuner = (state->routing.input >> 3) & 1;
+	int tuner = (state->route_in >> 3) & 1;
 	int i;
 
 	v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
@@ -896,7 +896,7 @@ static void msp34xxg_set_source(struct i
 static void msp34xxg_set_sources(struct i2c_client *client)
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
-	u32 in = state->routing.input;
+	u32 in = state->route_in;
 
 	msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
 	/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
@@ -912,7 +912,7 @@ static void msp34xxg_set_sources(struct
 static void msp34xxg_reset(struct i2c_client *client)
 {
 	struct msp_state *state = to_state(i2c_get_clientdata(client));
-	int tuner = (state->routing.input >> 3) & 1;
+	int tuner = (state->route_in >> 3) & 1;
 	int modus;
 
 	/* initialize std to 1 (autodetect) to signal that no standard is
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mt9m001.c linux-libre-2.6.30-gnu1/drivers/media/video/mt9m001.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mt9m001.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mt9m001.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
-#include <linux/gpio.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
@@ -73,9 +72,7 @@ struct mt9m001 {
 	struct i2c_client *client;
 	struct soc_camera_device icd;
 	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
-	int switch_gpio;
 	unsigned char autoexposure;
-	unsigned char datawidth;
 };
 
 static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -181,92 +178,28 @@ static int mt9m001_stop_capture(struct s
 	return 0;
 }
 
-static int bus_switch_request(struct mt9m001 *mt9m001,
-			      struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-	int ret;
-	unsigned int gpio = icl->gpio;
-
-	if (gpio_is_valid(gpio)) {
-		/* We have a data bus switch. */
-		ret = gpio_request(gpio, "mt9m001");
-		if (ret < 0) {
-			dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n",
-				gpio);
-			return ret;
-		}
-
-		ret = gpio_direction_output(gpio, 0);
-		if (ret < 0) {
-			dev_err(&mt9m001->client->dev,
-				"Cannot set GPIO %u to output\n", gpio);
-			gpio_free(gpio);
-			return ret;
-		}
-	}
-
-	mt9m001->switch_gpio = gpio;
-#else
-	mt9m001->switch_gpio = -EINVAL;
-#endif
-	return 0;
-}
-
-static void bus_switch_release(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-	if (gpio_is_valid(mt9m001->switch_gpio))
-		gpio_free(mt9m001->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-	if (!gpio_is_valid(mt9m001->switch_gpio))
-		return -ENODEV;
-
-	gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit);
-	return 0;
-#else
-	return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-	return gpio_is_valid(mt9m001->switch_gpio);
-#else
-	return 0;
-#endif
-}
-
 static int mt9m001_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
-	int ret;
+	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
 
-	/* Flags validity verified in test_bus_param */
+	/* Only one width bit may be set */
+	if (!is_power_of_2(width_flag))
+		return -EINVAL;
 
-	if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
-	    (mt9m001->datawidth != 9  && (width_flag == SOCAM_DATAWIDTH_9)) ||
-	    (mt9m001->datawidth != 8  && (width_flag == SOCAM_DATAWIDTH_8))) {
-		/* Well, we actually only can do 10 or 8 bits... */
-		if (width_flag == SOCAM_DATAWIDTH_9)
-			return -EINVAL;
-		ret = bus_switch_act(mt9m001,
-				     width_flag == SOCAM_DATAWIDTH_8);
-		if (ret < 0)
-			return ret;
+	if (icl->set_bus_param)
+		return icl->set_bus_param(icl, width_flag);
 
-		mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
-	}
+	/*
+	 * Without board specific bus width settings we only support the
+	 * sensors native bus width
+	 */
+	if (width_flag == SOCAM_DATAWIDTH_10)
+		return 0;
 
-	return 0;
+	return -EINVAL;
 }
 
 static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
@@ -274,18 +207,20 @@ static unsigned long mt9m001_query_bus_p
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
 	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
 	/* MT9M001 has all capture_format parameters fixed */
-	unsigned long flags = SOCAM_DATAWIDTH_10 | SOCAM_PCLK_SAMPLE_RISING |
+	unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
 		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-		SOCAM_MASTER;
+		SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
 
-	if (bus_switch_possible(mt9m001))
-		flags |= SOCAM_DATAWIDTH_8;
+	if (icl->query_bus_param)
+		flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
+	else
+		flags |= SOCAM_DATAWIDTH_10;
 
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
-static int mt9m001_set_fmt(struct soc_camera_device *icd,
-			   __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9m001_set_crop(struct soc_camera_device *icd,
+			    struct v4l2_rect *rect)
 {
 	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
 	int ret;
@@ -324,6 +259,20 @@ static int mt9m001_set_fmt(struct soc_ca
 	return ret;
 }
 
+static int mt9m001_set_fmt(struct soc_camera_device *icd,
+			   struct v4l2_format *f)
+{
+	struct v4l2_rect rect = {
+		.left	= icd->x_current,
+		.top	= icd->y_current,
+		.width	= f->fmt.pix.width,
+		.height	= f->fmt.pix.height,
+	};
+
+	/* No support for scaling so far, just crop. TODO: use skipping */
+	return mt9m001_set_crop(icd, &rect);
+}
+
 static int mt9m001_try_fmt(struct soc_camera_device *icd,
 			   struct v4l2_format *f)
 {
@@ -449,6 +398,7 @@ static struct soc_camera_ops mt9m001_ops
 	.release		= mt9m001_release,
 	.start_capture		= mt9m001_start_capture,
 	.stop_capture		= mt9m001_stop_capture,
+	.set_crop		= mt9m001_set_crop,
 	.set_fmt		= mt9m001_set_fmt,
 	.try_fmt		= mt9m001_try_fmt,
 	.set_bus_param		= mt9m001_set_bus_param,
@@ -583,6 +533,7 @@ static int mt9m001_video_probe(struct so
 	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
 	s32 data;
 	int ret;
+	unsigned long flags;
 
 	/* We must have a parent by now. And it cannot be a wrong one.
 	 * So this entire test is completely redundant. */
@@ -603,18 +554,10 @@ static int mt9m001_video_probe(struct so
 	case 0x8421:
 		mt9m001->model = V4L2_IDENT_MT9M001C12ST;
 		icd->formats = mt9m001_colour_formats;
-		if (gpio_is_valid(icl->gpio))
-			icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats);
-		else
-			icd->num_formats = 1;
 		break;
 	case 0x8431:
 		mt9m001->model = V4L2_IDENT_MT9M001C12STM;
 		icd->formats = mt9m001_monochrome_formats;
-		if (gpio_is_valid(icl->gpio))
-			icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
-		else
-			icd->num_formats = 1;
 		break;
 	default:
 		ret = -ENODEV;
@@ -623,6 +566,26 @@ static int mt9m001_video_probe(struct so
 		goto ei2c;
 	}
 
+	icd->num_formats = 0;
+
+	/*
+	 * This is a 10bit sensor, so by default we only allow 10bit.
+	 * The platform may support different bus widths due to
+	 * different routing of the data lines.
+	 */
+	if (icl->query_bus_param)
+		flags = icl->query_bus_param(icl);
+	else
+		flags = SOCAM_DATAWIDTH_10;
+
+	if (flags & SOCAM_DATAWIDTH_10)
+		icd->num_formats++;
+	else
+		icd->formats++;
+
+	if (flags & SOCAM_DATAWIDTH_8)
+		icd->num_formats++;
+
 	dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
 		 data == 0x8431 ? "C12STM" : "C12ST");
 
@@ -688,18 +651,10 @@ static int mt9m001_probe(struct i2c_clie
 	icd->height_max	= 1024;
 	icd->y_skip_top	= 1;
 	icd->iface	= icl->bus_id;
-	/* Default datawidth - this is the only width this camera (normally)
-	 * supports. It is only with extra logic that it can support
-	 * other widths. Therefore it seems to be a sensible default. */
-	mt9m001->datawidth = 10;
 	/* Simulated autoexposure. If enabled, we calculate shutter width
 	 * ourselves in the driver based on vertical blanking and frame width */
 	mt9m001->autoexposure = 1;
 
-	ret = bus_switch_request(mt9m001, icl);
-	if (ret)
-		goto eswinit;
-
 	ret = soc_camera_device_register(icd);
 	if (ret)
 		goto eisdr;
@@ -707,8 +662,6 @@ static int mt9m001_probe(struct i2c_clie
 	return 0;
 
 eisdr:
-	bus_switch_release(mt9m001);
-eswinit:
 	kfree(mt9m001);
 	return ret;
 }
@@ -718,7 +671,6 @@ static int mt9m001_remove(struct i2c_cli
 	struct mt9m001 *mt9m001 = i2c_get_clientdata(client);
 
 	soc_camera_device_unregister(&mt9m001->icd);
-	bus_switch_release(mt9m001);
 	kfree(mt9m001);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mt9m111.c linux-libre-2.6.30-gnu1/drivers/media/video/mt9m111.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mt9m111.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mt9m111.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,7 +152,7 @@ struct mt9m111 {
 	struct soc_camera_device icd;
 	int model;	/* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
 	enum mt9m111_context context;
-	unsigned int left, top, width, height;
+	struct v4l2_rect rect;
 	u32 pixfmt;
 	unsigned char autoexposure;
 	unsigned char datawidth;
@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct so
 		return reg_write(CONTEXT_CONTROL, valA);
 }
 
-static int mt9m111_setup_rect(struct soc_camera_device *icd)
+static int mt9m111_setup_rect(struct soc_camera_device *icd,
+			      struct v4l2_rect *rect)
 {
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
 	int ret, is_raw_format;
-	int width = mt9m111->width;
-	int height = mt9m111->height;
+	int width = rect->width;
+	int height = rect->height;
 
 	if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
 	    || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc
 	else
 		is_raw_format = 0;
 
-	ret = reg_write(COLUMN_START, mt9m111->left);
+	ret = reg_write(COLUMN_START, rect->left);
 	if (!ret)
-		ret = reg_write(ROW_START, mt9m111->top);
+		ret = reg_write(ROW_START, rect->top);
 
 	if (is_raw_format) {
 		if (!ret)
@@ -393,6 +394,8 @@ static int mt9m111_disable(struct soc_ca
 
 static int mt9m111_reset(struct soc_camera_device *icd)
 {
+	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
 	int ret;
 
 	ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -401,6 +404,10 @@ static int mt9m111_reset(struct soc_came
 	if (!ret)
 		ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
 				| MT9M111_RESET_RESET_SOC);
+
+	if (icl->reset)
+		icl->reset(&mt9m111->client->dev);
+
 	return ret;
 }
 
@@ -420,7 +427,7 @@ static unsigned long mt9m111_query_bus_p
 	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
 	unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
 		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-		SOCAM_DATAWIDTH_8;
+		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
 
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
@@ -430,6 +437,22 @@ static int mt9m111_set_bus_param(struct
 	return 0;
 }
 
+static int mt9m111_set_crop(struct soc_camera_device *icd,
+			    struct v4l2_rect *rect)
+{
+	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	int ret;
+
+	dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
+		__func__, rect->left, rect->top, rect->width,
+		rect->height);
+
+	ret = mt9m111_setup_rect(icd, rect);
+	if (!ret)
+		mt9m111->rect = *rect;
+	return ret;
+}
+
 static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
 {
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
@@ -480,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc
 }
 
 static int mt9m111_set_fmt(struct soc_camera_device *icd,
-			   __u32 pixfmt, struct v4l2_rect *rect)
+			   struct v4l2_format *f)
 {
 	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	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,
+	};
 	int ret;
 
-	mt9m111->left = rect->left;
-	mt9m111->top = rect->top;
-	mt9m111->width = rect->width;
-	mt9m111->height = rect->height;
-
 	dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
-		__func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width,
-		mt9m111->height);
+		__func__, pix->pixelformat, rect.left, rect.top, rect.width,
+		rect.height);
 
-	ret = mt9m111_setup_rect(icd);
+	ret = mt9m111_setup_rect(icd, &rect);
 	if (!ret)
-		ret = mt9m111_set_pixfmt(icd, pixfmt);
+		ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
+	if (!ret)
+		mt9m111->rect = rect;
 	return ret;
 }
 
@@ -627,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops
 	.release		= mt9m111_release,
 	.start_capture		= mt9m111_start_capture,
 	.stop_capture		= mt9m111_stop_capture,
+	.set_crop		= mt9m111_set_crop,
 	.set_fmt		= mt9m111_set_fmt,
 	.try_fmt		= mt9m111_try_fmt,
 	.query_bus_param	= mt9m111_query_bus_param,
@@ -811,7 +839,7 @@ static int mt9m111_restore_state(struct
 
 	mt9m111_set_context(icd, mt9m111->context);
 	mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
-	mt9m111_setup_rect(icd);
+	mt9m111_setup_rect(icd, &mt9m111->rect);
 	mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
 	mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
 	mt9m111_set_global_gain(icd, icd->gain);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mt9t031.c linux-libre-2.6.30-gnu1/drivers/media/video/mt9t031.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mt9t031.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mt9t031.c	2009-06-09 23:05:27.000000000 -0400
@@ -141,31 +141,50 @@ static int get_shutter(struct soc_camera
 
 static int mt9t031_init(struct soc_camera_device *icd)
 {
+	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
 	int ret;
 
-	/* Disable chip output, synchronous option update */
-	dev_dbg(icd->vdev->parent, "%s\n", __func__);
+	if (icl->power) {
+		ret = icl->power(&mt9t031->client->dev, 1);
+		if (ret < 0) {
+			dev_err(icd->vdev->parent,
+				"Platform failed to power-on the camera.\n");
+			return ret;
+		}
+	}
 
+	/* Disable chip output, synchronous option update */
 	ret = reg_write(icd, MT9T031_RESET, 1);
 	if (ret >= 0)
 		ret = reg_write(icd, MT9T031_RESET, 0);
 	if (ret >= 0)
-		ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+		ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+
+	if (ret < 0 && icl->power)
+		icl->power(&mt9t031->client->dev, 0);
 
 	return ret >= 0 ? 0 : -EIO;
 }
 
 static int mt9t031_release(struct soc_camera_device *icd)
 {
+	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+
 	/* Disable the chip */
-	reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+	reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
+
+	if (icl->power)
+		icl->power(&mt9t031->client->dev, 0);
+
 	return 0;
 }
 
 static int mt9t031_start_capture(struct soc_camera_device *icd)
 {
 	/* Switch to master "normal" mode */
-	if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+	if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
 		return -EIO;
 	return 0;
 }
@@ -173,7 +192,7 @@ static int mt9t031_start_capture(struct
 static int mt9t031_stop_capture(struct soc_camera_device *icd)
 {
 	/* Stop sensor readout */
-	if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+	if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
 		return -EIO;
 	return 0;
 }
@@ -186,9 +205,9 @@ static int mt9t031_set_bus_param(struct
 		return -EINVAL;
 
 	if (flags & SOCAM_PCLK_SAMPLE_FALLING)
-		reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
-	else
 		reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+	else
+		reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
 
 	return 0;
 }
@@ -201,67 +220,73 @@ static unsigned long mt9t031_query_bus_p
 	return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
 }
 
-static int mt9t031_set_fmt(struct soc_camera_device *icd,
-			   __u32 pixfmt, struct v4l2_rect *rect)
+/* Round up minima and round down maxima */
+static void recalculate_limits(struct soc_camera_device *icd,
+			       u16 xskip, u16 yskip)
+{
+	icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
+	icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
+	icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
+	icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
+	icd->width_max = MT9T031_MAX_WIDTH / xskip;
+	icd->height_max = MT9T031_MAX_HEIGHT / yskip;
+}
+
+static int mt9t031_set_params(struct soc_camera_device *icd,
+			      struct v4l2_rect *rect, u16 xskip, u16 yskip)
 {
 	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
 	int ret;
+	u16 xbin, ybin, width, height, left, top;
 	const u16 hblank = MT9T031_HORIZONTAL_BLANK,
 		vblank = MT9T031_VERTICAL_BLANK;
-	u16 xbin, xskip = mt9t031->xskip, ybin, yskip = mt9t031->yskip,
-		width = rect->width * xskip, height = rect->height * yskip;
 
-	if (pixfmt) {
-		/* S_FMT - use binning and skipping for scaling, recalculate */
-		/* Is this more optimal than just a division? */
-		for (xskip = 8; xskip > 1; xskip--)
-			if (rect->width * xskip <= icd->width_max)
-				break;
-
-		for (yskip = 8; yskip > 1; yskip--)
-			if (rect->height * yskip <= icd->height_max)
-				break;
+	/* Make sure we don't exceed sensor limits */
+	if (rect->left + rect->width > icd->width_max)
+		rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
 
-		width = rect->width * xskip;
-		height = rect->height * yskip;
+	if (rect->top + rect->height > icd->height_max)
+		rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
 
-		dev_dbg(&icd->dev, "xskip %u, width %u, yskip %u, height %u\n",
-			xskip, width, yskip, height);
-	}
+	width = rect->width * xskip;
+	height = rect->height * yskip;
+	left = rect->left * xskip;
+	top = rect->top * yskip;
 
 	xbin = min(xskip, (u16)3);
 	ybin = min(yskip, (u16)3);
 
-	/* Make sure we don't exceed frame limits */
-	if (rect->left + width > icd->width_max)
-		rect->left = (icd->width_max - width) / 2;
-
-	if (rect->top + height > icd->height_max)
-		rect->top = (icd->height_max - height) / 2;
+	dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n",
+		xskip, width, rect->width, yskip, height, rect->height);
 
-	/* Could just do roundup(rect->left, [xy]bin); but this is cheaper */
+	/* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */
 	switch (xbin) {
 	case 2:
-		rect->left = (rect->left + 1) & ~1;
+		left = (left + 3) & ~3;
 		break;
 	case 3:
-		rect->left = roundup(rect->left, 3);
+		left = roundup(left, 6);
 	}
 
 	switch (ybin) {
 	case 2:
-		rect->top = (rect->top + 1) & ~1;
+		top = (top + 3) & ~3;
 		break;
 	case 3:
-		rect->top = roundup(rect->top, 3);
+		top = roundup(top, 6);
 	}
 
+	/* Disable register update, reconfigure atomically */
+	ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1);
+	if (ret < 0)
+		return ret;
+
 	/* Blanking and start values - default... */
 	ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
 	if (ret >= 0)
 		ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
 
-	if (pixfmt) {
+	if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
 		/* Binning, skipping */
 		if (ret >= 0)
 			ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
@@ -270,14 +295,14 @@ static int mt9t031_set_fmt(struct soc_ca
 			ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
 					((ybin - 1) << 4) | (yskip - 1));
 	}
-	dev_dbg(&icd->dev, "new left %u, top %u\n", rect->left, rect->top);
+	dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
 
 	/* 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(icd, MT9T031_COLUMN_START, rect->left);
+		ret = reg_write(icd, MT9T031_COLUMN_START, left);
 	if (ret >= 0)
-		ret = reg_write(icd, MT9T031_ROW_START, rect->top);
+		ret = reg_write(icd, MT9T031_ROW_START, top);
 	if (ret >= 0)
 		ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
 	if (ret >= 0)
@@ -297,12 +322,58 @@ static int mt9t031_set_fmt(struct soc_ca
 		}
 	}
 
-	if (!ret && pixfmt) {
+	/* Re-enable register update, commit all changes */
+	if (ret >= 0)
+		ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
+
+	return ret < 0 ? ret : 0;
+}
+
+static int mt9t031_set_crop(struct soc_camera_device *icd,
+			    struct v4l2_rect *rect)
+{
+	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+
+	/* CROP - no change in scaling, or in limits */
+	return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
+}
+
+static int mt9t031_set_fmt(struct soc_camera_device *icd,
+			   struct v4l2_format *f)
+{
+	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	int ret;
+	u16 xskip, yskip;
+	struct v4l2_rect rect = {
+		.left	= icd->x_current,
+		.top	= icd->y_current,
+		.width	= f->fmt.pix.width,
+		.height	= f->fmt.pix.height,
+	};
+
+	/*
+	 * try_fmt has put rectangle within limits.
+	 * S_FMT - use binning and skipping for scaling, recalculate
+	 * limits, used for cropping
+	 */
+	/* Is this more optimal than just a division? */
+	for (xskip = 8; xskip > 1; xskip--)
+		if (rect.width * xskip <= MT9T031_MAX_WIDTH)
+			break;
+
+	for (yskip = 8; yskip > 1; yskip--)
+		if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
+			break;
+
+	recalculate_limits(icd, xskip, yskip);
+
+	ret = mt9t031_set_params(icd, &rect, xskip, yskip);
+	if (!ret) {
 		mt9t031->xskip = xskip;
 		mt9t031->yskip = yskip;
 	}
 
-	return ret < 0 ? ret : 0;
+	return ret;
 }
 
 static int mt9t031_try_fmt(struct soc_camera_device *icd,
@@ -310,14 +381,14 @@ static int mt9t031_try_fmt(struct soc_ca
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (pix->height < icd->height_min)
-		pix->height = icd->height_min;
-	if (pix->height > icd->height_max)
-		pix->height = icd->height_max;
-	if (pix->width < icd->width_min)
-		pix->width = icd->width_min;
-	if (pix->width > icd->width_max)
-		pix->width = icd->width_max;
+	if (pix->height < MT9T031_MIN_HEIGHT)
+		pix->height = MT9T031_MIN_HEIGHT;
+	if (pix->height > MT9T031_MAX_HEIGHT)
+		pix->height = MT9T031_MAX_HEIGHT;
+	if (pix->width < MT9T031_MIN_WIDTH)
+		pix->width = MT9T031_MIN_WIDTH;
+	if (pix->width > MT9T031_MAX_WIDTH)
+		pix->width = MT9T031_MAX_WIDTH;
 
 	pix->width &= ~0x01; /* has to be even */
 	pix->height &= ~0x01; /* has to be even */
@@ -390,6 +461,14 @@ static const struct v4l2_queryctrl mt9t0
 		.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",
@@ -431,6 +510,7 @@ static struct soc_camera_ops mt9t031_ops
 	.release		= mt9t031_release,
 	.start_capture		= mt9t031_start_capture,
 	.stop_capture		= mt9t031_stop_capture,
+	.set_crop		= mt9t031_set_crop,
 	.set_fmt		= mt9t031_set_fmt,
 	.try_fmt		= mt9t031_try_fmt,
 	.set_bus_param		= mt9t031_set_bus_param,
@@ -513,21 +593,23 @@ static int mt9t031_set_control(struct so
 			if (data < 0)
 				return -EIO;
 		} else {
-			/* Pack it into 1.125..15 variable step, register values 9..67 */
+			/* Pack it into 1.125..128 variable step, register values 9..0x7860 */
 			/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
 			unsigned long range = qctrl->maximum - qctrl->default_value - 1;
+			/* calculated gain: map 65..127 to 9..1024 step 0.125 */
 			unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
-					       111 + range / 2) / range + 9;
+					       1015 + range / 2) / range + 9;
 
-			if (gain <= 32)
+			if (gain <= 32)		/* calculated gain 9..32 -> 9..32 */
 				data = gain;
-			else if (gain <= 64)
+			else if (gain <= 64)	/* calculated gain 33..64 -> 0x51..0x60 */
 				data = ((gain - 32) * 16 + 16) / 32 + 80;
 			else
-				data = ((gain - 64) * 7 + 28) / 56 + 96;
+				/* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
+				data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
 
-			dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
-				 reg_read(icd, MT9T031_GLOBAL_GAIN), data);
+			dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
+				reg_read(icd, MT9T031_GLOBAL_GAIN), data);
 			data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mt9v022.c linux-libre-2.6.30-gnu1/drivers/media/video/mt9v022.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mt9v022.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mt9v022.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
-#include <linux/gpio.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
@@ -89,9 +88,7 @@ struct mt9v022 {
 	struct i2c_client *client;
 	struct soc_camera_device icd;
 	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
-	int switch_gpio;
 	u16 chip_control;
-	unsigned char datawidth;
 };
 
 static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -209,66 +206,6 @@ static int mt9v022_stop_capture(struct s
 	return 0;
 }
 
-static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
-	int ret;
-	unsigned int gpio = icl->gpio;
-
-	if (gpio_is_valid(gpio)) {
-		/* We have a data bus switch. */
-		ret = gpio_request(gpio, "mt9v022");
-		if (ret < 0) {
-			dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio);
-			return ret;
-		}
-
-		ret = gpio_direction_output(gpio, 0);
-		if (ret < 0) {
-			dev_err(&mt9v022->client->dev,
-				"Cannot set GPIO %u to output\n", gpio);
-			gpio_free(gpio);
-			return ret;
-		}
-	}
-
-	mt9v022->switch_gpio = gpio;
-#else
-	mt9v022->switch_gpio = -EINVAL;
-#endif
-	return 0;
-}
-
-static void bus_switch_release(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
-	if (gpio_is_valid(mt9v022->switch_gpio))
-		gpio_free(mt9v022->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
-	if (!gpio_is_valid(mt9v022->switch_gpio))
-		return -ENODEV;
-
-	gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit);
-	return 0;
-#else
-	return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
-	return gpio_is_valid(mt9v022->switch_gpio);
-#else
-	return 0;
-#endif
-}
-
 static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
@@ -282,19 +219,17 @@ static int mt9v022_set_bus_param(struct
 	if (!is_power_of_2(width_flag))
 		return -EINVAL;
 
-	if ((mt9v022->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
-	    (mt9v022->datawidth != 9  && (width_flag == SOCAM_DATAWIDTH_9)) ||
-	    (mt9v022->datawidth != 8  && (width_flag == SOCAM_DATAWIDTH_8))) {
-		/* Well, we actually only can do 10 or 8 bits... */
-		if (width_flag == SOCAM_DATAWIDTH_9)
-			return -EINVAL;
-
-		ret = bus_switch_act(mt9v022,
-				     width_flag == SOCAM_DATAWIDTH_8);
-		if (ret < 0)
+	if (icl->set_bus_param) {
+		ret = icl->set_bus_param(icl, width_flag);
+		if (ret)
 			return ret;
-
-		mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
+	} else {
+		/*
+		 * Without board specific bus width settings we only support the
+		 * sensors native bus width
+		 */
+		if (width_flag != SOCAM_DATAWIDTH_10)
+			return -EINVAL;
 	}
 
 	flags = soc_camera_apply_sensor_flags(icl, flags);
@@ -328,44 +263,27 @@ static int mt9v022_set_bus_param(struct
 static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 {
 	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	unsigned int width_flag = SOCAM_DATAWIDTH_10;
+	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	unsigned int width_flag;
 
-	if (bus_switch_possible(mt9v022))
-		width_flag |= SOCAM_DATAWIDTH_8;
+	if (icl->query_bus_param)
+		width_flag = icl->query_bus_param(icl) &
+			SOCAM_DATAWIDTH_MASK;
+	else
+		width_flag = SOCAM_DATAWIDTH_10;
 
 	return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
 		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
-		SOCAM_MASTER | SOCAM_SLAVE |
+		SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
 		width_flag;
 }
 
-static int mt9v022_set_fmt(struct soc_camera_device *icd,
-			   __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9v022_set_crop(struct soc_camera_device *icd,
+			    struct v4l2_rect *rect)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
 	int ret;
 
-	/* The caller provides a supported format, as verified per call to
-	 * icd->try_fmt(), datawidth is from our supported format list */
-	switch (pixfmt) {
-	case V4L2_PIX_FMT_GREY:
-	case V4L2_PIX_FMT_Y16:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
-			return -EINVAL;
-		break;
-	case V4L2_PIX_FMT_SBGGR8:
-	case V4L2_PIX_FMT_SBGGR16:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
-			return -EINVAL;
-		break;
-	case 0:
-		/* No format change, only geometry */
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	/* Like in example app. Contradicts the datasheet though */
 	ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
 	if (ret >= 0) {
@@ -403,6 +321,42 @@ static int mt9v022_set_fmt(struct soc_ca
 	return 0;
 }
 
+static int mt9v022_set_fmt(struct soc_camera_device *icd,
+			   struct v4l2_format *f)
+{
+	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_rect rect = {
+		.left	= icd->x_current,
+		.top	= icd->y_current,
+		.width	= pix->width,
+		.height	= pix->height,
+	};
+
+	/* 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:
+		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+			return -EINVAL;
+		break;
+	case V4L2_PIX_FMT_SBGGR8:
+	case V4L2_PIX_FMT_SBGGR16:
+		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+			return -EINVAL;
+		break;
+	case 0:
+		/* No format change, only geometry */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* No support for scaling on this camera, just crop. */
+	return mt9v022_set_crop(icd, &rect);
+}
+
 static int mt9v022_try_fmt(struct soc_camera_device *icd,
 			   struct v4l2_format *f)
 {
@@ -544,6 +498,7 @@ static struct soc_camera_ops mt9v022_ops
 	.release		= mt9v022_release,
 	.start_capture		= mt9v022_start_capture,
 	.stop_capture		= mt9v022_stop_capture,
+	.set_crop		= mt9v022_set_crop,
 	.set_fmt		= mt9v022_set_fmt,
 	.try_fmt		= mt9v022_try_fmt,
 	.set_bus_param		= mt9v022_set_bus_param,
@@ -699,6 +654,7 @@ static int mt9v022_video_probe(struct so
 	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
 	s32 data;
 	int ret;
+	unsigned long flags;
 
 	if (!icd->dev.parent ||
 	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
@@ -732,22 +688,36 @@ static int mt9v022_video_probe(struct so
 		ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
 		icd->formats = mt9v022_colour_formats;
-		if (gpio_is_valid(icl->gpio))
-			icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats);
-		else
-			icd->num_formats = 1;
 	} else {
 		ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
 		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
 		icd->formats = mt9v022_monochrome_formats;
-		if (gpio_is_valid(icl->gpio))
-			icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats);
-		else
-			icd->num_formats = 1;
 	}
 
-	if (!ret)
-		ret = soc_camera_video_start(icd);
+	if (ret < 0)
+		goto eisis;
+
+	icd->num_formats = 0;
+
+	/*
+	 * This is a 10bit sensor, so by default we only allow 10bit.
+	 * The platform may support different bus widths due to
+	 * different routing of the data lines.
+	 */
+	if (icl->query_bus_param)
+		flags = icl->query_bus_param(icl);
+	else
+		flags = SOCAM_DATAWIDTH_10;
+
+	if (flags & SOCAM_DATAWIDTH_10)
+		icd->num_formats++;
+	else
+		icd->formats++;
+
+	if (flags & SOCAM_DATAWIDTH_8)
+		icd->num_formats++;
+
+	ret = soc_camera_video_start(icd);
 	if (ret < 0)
 		goto eisis;
 
@@ -812,14 +782,6 @@ static int mt9v022_probe(struct i2c_clie
 	icd->height_max	= 480;
 	icd->y_skip_top	= 1;
 	icd->iface	= icl->bus_id;
-	/* Default datawidth - this is the only width this camera (normally)
-	 * supports. It is only with extra logic that it can support
-	 * other widths. Therefore it seems to be a sensible default. */
-	mt9v022->datawidth = 10;
-
-	ret = bus_switch_request(mt9v022, icl);
-	if (ret)
-		goto eswinit;
 
 	ret = soc_camera_device_register(icd);
 	if (ret)
@@ -828,8 +790,6 @@ static int mt9v022_probe(struct i2c_clie
 	return 0;
 
 eisdr:
-	bus_switch_release(mt9v022);
-eswinit:
 	kfree(mt9v022);
 	return ret;
 }
@@ -839,7 +799,6 @@ static int mt9v022_remove(struct i2c_cli
 	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
 
 	soc_camera_device_unregister(&mt9v022->icd);
-	bus_switch_release(mt9v022);
 	kfree(mt9v022);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mx1_camera.c linux-libre-2.6.30-gnu1/drivers/media/video/mx1_camera.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mx1_camera.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mx1_camera.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,827 @@
+/*
+ * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
+ *
+ * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * Based on PXA SoC camera driver
+ * Copyright (C) 2006, Sascha Hauer, Pengutronix
+ * 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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-contig.h>
+
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <mach/dma-mx1-mx2.h>
+#include <mach/hardware.h>
+#include <mach/mx1_camera.h>
+
+/*
+ * CSI registers
+ */
+#define DMA_CCR(x)	(0x8c + ((x) << 6))	/* Control Registers */
+#define DMA_DIMR	0x08			/* Interrupt mask Register */
+#define CSICR1		0x00			/* CSI Control Register 1 */
+#define CSISR		0x08			/* CSI Status Register */
+#define CSIRXR		0x10			/* CSI RxFIFO Register */
+
+#define CSICR1_RXFF_LEVEL(x)	(((x) & 0x3) << 19)
+#define CSICR1_SOF_POL		(1 << 17)
+#define CSICR1_SOF_INTEN	(1 << 16)
+#define CSICR1_MCLKDIV(x)	(((x) & 0xf) << 12)
+#define CSICR1_MCLKEN		(1 << 9)
+#define CSICR1_FCC		(1 << 8)
+#define CSICR1_BIG_ENDIAN	(1 << 7)
+#define CSICR1_CLR_RXFIFO	(1 << 5)
+#define CSICR1_GCLK_MODE	(1 << 4)
+#define CSICR1_DATA_POL		(1 << 2)
+#define CSICR1_REDGE		(1 << 1)
+#define CSICR1_EN		(1 << 0)
+
+#define CSISR_SFF_OR_INT	(1 << 25)
+#define CSISR_RFF_OR_INT	(1 << 24)
+#define CSISR_STATFF_INT	(1 << 21)
+#define CSISR_RXFF_INT		(1 << 18)
+#define CSISR_SOF_INT		(1 << 16)
+#define CSISR_DRDY		(1 << 0)
+
+#define VERSION_CODE KERNEL_VERSION(0, 0, 1)
+#define DRIVER_NAME "mx1-camera"
+
+#define CSI_IRQ_MASK	(CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
+			CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
+
+#define CSI_BUS_FLAGS	(SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \
+			SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \
+			SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
+			SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \
+			SOCAM_DATAWIDTH_8)
+
+#define MAX_VIDEO_MEM 16	/* Video memory limit in megabytes */
+
+/*
+ * Structures
+ */
+
+/* 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;
+};
+
+/* 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 */
+struct mx1_camera_dev {
+	struct soc_camera_device	*icd;
+	struct mx1_camera_pdata		*pdata;
+	struct mx1_buffer		*active;
+	struct device			*dev;
+	struct resource			*res;
+	struct clk			*clk;
+	struct list_head		capture;
+
+	void __iomem			*base;
+	int				dma_chan;
+	unsigned int			irq;
+	unsigned long			mclk;
+
+	spinlock_t			lock;
+};
+
+/*
+ *  Videobuf operations
+ */
+static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
+			      unsigned int *size)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+
+	*size = icd->width * icd->height *
+		((icd->current_fmt->depth + 7) >> 3);
+
+	if (!*count)
+		*count = 32;
+
+	while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+		(*count)--;
+
+	dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+
+	return 0;
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+	struct videobuf_buffer *vb = &buf->vb;
+
+	BUG_ON(in_interrupt());
+
+	dev_dbg(&icd->dev, "%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 */
+	videobuf_waiton(vb, 0, 0);
+	videobuf_dma_contig_free(vq, vb);
+
+	vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int mx1_videobuf_prepare(struct videobuf_queue *vq,
+		struct videobuf_buffer *vb, enum v4l2_field field)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+	int ret;
+
+	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+		vb, vb->baddr, vb->bsize);
+
+	/* Added list head initialization on alloc */
+	WARN_ON(!list_empty(&vb->queue));
+
+	BUG_ON(NULL == icd->current_fmt);
+
+	/* 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 ||
+	    vb->width	!= icd->width ||
+	    vb->height	!= icd->height ||
+	    vb->field	!= field) {
+		buf->fmt	= icd->current_fmt;
+		vb->width	= icd->width;
+		vb->height	= icd->height;
+		vb->field	= field;
+		vb->state	= VIDEOBUF_NEEDS_INIT;
+	}
+
+	vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+	if (0 != vb->baddr && vb->bsize < vb->size) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (vb->state == VIDEOBUF_NEEDS_INIT) {
+		ret = videobuf_iolock(vq, vb, NULL);
+		if (ret)
+			goto fail;
+
+		vb->state = VIDEOBUF_PREPARED;
+	}
+
+	buf->inwork = 0;
+
+	return 0;
+
+fail:
+	free_buffer(vq, buf);
+out:
+	buf->inwork = 0;
+	return ret;
+}
+
+static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
+{
+	struct videobuf_buffer *vbuf = &pcdev->active->vb;
+	int ret;
+
+	if (unlikely(!pcdev->active)) {
+		dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+		return -EFAULT;
+	}
+
+	/* setup sg list for future DMA */
+	ret = imx_dma_setup_single(pcdev->dma_chan,
+		videobuf_to_dma_contig(vbuf),
+		vbuf->size, pcdev->res->start +
+		CSIRXR, DMA_MODE_READ);
+	if (unlikely(ret))
+		dev_err(pcdev->dev, "Failed to setup DMA sg list\n");
+
+	return ret;
+}
+
+static void mx1_videobuf_queue(struct videobuf_queue *vq,
+						struct videobuf_buffer *vb)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx1_camera_dev *pcdev = ici->priv;
+	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+	unsigned long flags;
+
+	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+		vb, vb->baddr, vb->bsize);
+
+	spin_lock_irqsave(&pcdev->lock, flags);
+
+	list_add_tail(&vb->queue, &pcdev->capture);
+
+	vb->state = VIDEOBUF_ACTIVE;
+
+	if (!pcdev->active) {
+		pcdev->active = buf;
+
+		/* setup sg list for future DMA */
+		if (!mx1_camera_setup_dma(pcdev)) {
+			unsigned int temp;
+			/* enable SOF irq */
+			temp = __raw_readl(pcdev->base + CSICR1) |
+							CSICR1_SOF_INTEN;
+			__raw_writel(temp, pcdev->base + CSICR1);
+		}
+	}
+
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+}
+
+static void mx1_videobuf_release(struct videobuf_queue *vq,
+				 struct videobuf_buffer *vb)
+{
+	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
+#ifdef DEBUG
+	struct soc_camera_device *icd = vq->priv_data;
+
+	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+		vb, vb->baddr, vb->bsize);
+
+	switch (vb->state) {
+	case VIDEOBUF_ACTIVE:
+		dev_dbg(&icd->dev, "%s (active)\n", __func__);
+		break;
+	case VIDEOBUF_QUEUED:
+		dev_dbg(&icd->dev, "%s (queued)\n", __func__);
+		break;
+	case VIDEOBUF_PREPARED:
+		dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
+		break;
+	default:
+		dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
+		break;
+	}
+#endif
+
+	free_buffer(vq, buf);
+}
+
+static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
+			      struct videobuf_buffer *vb,
+			      struct mx1_buffer *buf)
+{
+	/* _init is used to debug races, see comment in mx1_camera_reqbufs() */
+	list_del_init(&vb->queue);
+	vb->state = VIDEOBUF_DONE;
+	do_gettimeofday(&vb->ts);
+	vb->field_count++;
+	wake_up(&vb->done);
+
+	if (list_empty(&pcdev->capture)) {
+		pcdev->active = NULL;
+		return;
+	}
+
+	pcdev->active = list_entry(pcdev->capture.next,
+				   struct mx1_buffer, vb.queue);
+
+	/* setup sg list for future DMA */
+	if (likely(!mx1_camera_setup_dma(pcdev))) {
+		unsigned int temp;
+
+		/* enable SOF irq */
+		temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
+		__raw_writel(temp, pcdev->base + CSICR1);
+	}
+}
+
+static void mx1_camera_dma_irq(int channel, void *data)
+{
+	struct mx1_camera_dev *pcdev = data;
+	struct mx1_buffer *buf;
+	struct videobuf_buffer *vb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pcdev->lock, flags);
+
+	imx_dma_disable(channel);
+
+	if (unlikely(!pcdev->active)) {
+		dev_err(pcdev->dev, "DMA End IRQ with no active buffer\n");
+		goto out;
+	}
+
+	vb = &pcdev->active->vb;
+	buf = container_of(vb, struct mx1_buffer, vb);
+	WARN_ON(buf->inwork || list_empty(&vb->queue));
+	dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+		vb, vb->baddr, vb->bsize);
+
+	mx1_camera_wakeup(pcdev, vb, buf);
+out:
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+}
+
+static struct videobuf_queue_ops mx1_videobuf_ops = {
+	.buf_setup	= mx1_videobuf_setup,
+	.buf_prepare	= mx1_videobuf_prepare,
+	.buf_queue	= mx1_videobuf_queue,
+	.buf_release	= mx1_videobuf_release,
+};
+
+static void mx1_camera_init_videobuf(struct videobuf_queue *q,
+				     struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx1_camera_dev *pcdev = ici->priv;
+
+	videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, pcdev->dev,
+					&pcdev->lock,
+					V4L2_BUF_TYPE_VIDEO_CAPTURE,
+					V4L2_FIELD_NONE,
+					sizeof(struct mx1_buffer), icd);
+}
+
+static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
+{
+	unsigned int mclk = pcdev->mclk;
+	unsigned long div;
+	unsigned long lcdclk;
+
+	lcdclk = clk_get_rate(pcdev->clk);
+
+	/* 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->dev, "System clock %lukHz, target freq %dkHz, "
+		"divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
+
+	return div;
+}
+
+static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
+{
+	unsigned int csicr1 = CSICR1_EN;
+
+	dev_dbg(pcdev->dev, "Activate device\n");
+
+	clk_enable(pcdev->clk);
+
+	/* enable CSI before doing anything else */
+	__raw_writel(csicr1, pcdev->base + CSICR1);
+
+	csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
+	csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
+	csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
+
+	__raw_writel(csicr1, pcdev->base + CSICR1);
+}
+
+static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
+{
+	dev_dbg(pcdev->dev, "Deactivate device\n");
+
+	/* Disable all CSI interface */
+	__raw_writel(0x00, pcdev->base + CSICR1);
+
+	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 */
+static int mx1_camera_add_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx1_camera_dev *pcdev = ici->priv;
+	int ret;
+
+	if (pcdev->icd) {
+		ret = -EBUSY;
+		goto ebusy;
+	}
+
+	dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	mx1_camera_activate(pcdev);
+	ret = icd->ops->init(icd);
+
+	if (!ret)
+		pcdev->icd = icd;
+
+ebusy:
+	return ret;
+}
+
+static void mx1_camera_remove_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx1_camera_dev *pcdev = ici->priv;
+	unsigned int csicr1;
+
+	BUG_ON(icd != pcdev->icd);
+
+	/* disable interrupts */
+	csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
+	__raw_writel(csicr1, pcdev->base + CSICR1);
+
+	/* Stop DMA engine */
+	imx_dma_disable(pcdev->dma_chan);
+
+	dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n",
+		 icd->devnum);
+
+	icd->ops->release(icd);
+
+	mx1_camera_deactivate(pcdev);
+
+	pcdev->icd = NULL;
+}
+
+static int mx1_camera_set_crop(struct soc_camera_device *icd,
+			       struct v4l2_rect *rect)
+{
+	return icd->ops->set_crop(icd, rect);
+}
+
+static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx1_camera_dev *pcdev = ici->priv;
+	unsigned long camera_flags, common_flags;
+	unsigned int csicr1;
+	int ret;
+
+	camera_flags = icd->ops->query_bus_param(icd);
+
+	/* MX1 supports only 8bit buswidth */
+	common_flags = soc_camera_bus_param_compatible(camera_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)) {
+			if (!pcdev->pdata ||
+			     pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
+				common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+			else
+				common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+	}
+
+	if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+		(common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+			if (!pcdev->pdata ||
+			     pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
+				common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+			else
+				common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+	}
+
+	if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
+		(common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+			if (!pcdev->pdata ||
+			     pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
+				common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+			else
+				common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+	}
+
+	ret = icd->ops->set_bus_param(icd, common_flags);
+	if (ret < 0)
+		return ret;
+
+	csicr1 = __raw_readl(pcdev->base + CSICR1);
+
+	if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
+		csicr1 |= CSICR1_REDGE;
+	if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
+		csicr1 |= CSICR1_SOF_POL;
+	if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+		csicr1 |= CSICR1_DATA_POL;
+
+	__raw_writel(csicr1, pcdev->base + CSICR1);
+
+	return 0;
+}
+
+static int mx1_camera_set_fmt(struct soc_camera_device *icd,
+			      struct v4l2_format *f)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	int ret;
+
+	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+	if (!xlate) {
+		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		return -EINVAL;
+	}
+
+	ret = icd->ops->set_fmt(icd, f);
+	if (!ret) {
+		icd->buswidth = xlate->buswidth;
+		icd->current_fmt = xlate->host_fmt;
+	}
+
+	return ret;
+}
+
+static int mx1_camera_try_fmt(struct soc_camera_device *icd,
+			      struct v4l2_format *f)
+{
+	/* TODO: limit to mx1 hardware capabilities */
+
+	/* limit to sensor capabilities */
+	return icd->ops->try_fmt(icd, f);
+}
+
+static int mx1_camera_reqbufs(struct soc_camera_file *icf,
+			      struct v4l2_requestbuffers *p)
+{
+	int 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 */
+	for (i = 0; i < p->count; i++) {
+		struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i],
+						      struct mx1_buffer, vb);
+		buf->inwork = 0;
+		INIT_LIST_HEAD(&buf->vb.queue);
+	}
+
+	return 0;
+}
+
+static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
+{
+	struct soc_camera_file *icf = file->private_data;
+	struct mx1_buffer *buf;
+
+	buf = list_entry(icf->vb_vidq.stream.next, struct mx1_buffer,
+			 vb.stream);
+
+	poll_wait(file, &buf->vb.done, pt);
+
+	if (buf->vb.state == VIDEOBUF_DONE ||
+	    buf->vb.state == VIDEOBUF_ERROR)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static int mx1_camera_querycap(struct soc_camera_host *ici,
+			       struct v4l2_capability *cap)
+{
+	/* cap->name is set by the friendly caller:-> */
+	strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
+	cap->version = VERSION_CODE;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+
+	return 0;
+}
+
+static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
+	.owner		= THIS_MODULE,
+	.add		= mx1_camera_add_device,
+	.remove		= mx1_camera_remove_device,
+	.set_bus_param	= mx1_camera_set_bus_param,
+	.set_crop	= mx1_camera_set_crop,
+	.set_fmt	= mx1_camera_set_fmt,
+	.try_fmt	= mx1_camera_try_fmt,
+	.init_videobuf	= mx1_camera_init_videobuf,
+	.reqbufs	= mx1_camera_reqbufs,
+	.poll		= mx1_camera_poll,
+	.querycap	= mx1_camera_querycap,
+};
+
+/* Should be allocated dynamically too, but we have only one. */
+static struct soc_camera_host mx1_soc_camera_host = {
+	.drv_name	= DRIVER_NAME,
+	.ops		= &mx1_soc_camera_host_ops,
+};
+
+static struct fiq_handler fh = {
+	.name		= "csi_sof"
+};
+
+static int __init mx1_camera_probe(struct platform_device *pdev)
+{
+	struct mx1_camera_dev *pcdev;
+	struct resource *res;
+	struct pt_regs regs;
+	struct clk *clk;
+	void __iomem *base;
+	unsigned int irq;
+	int err = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!res || !irq) {
+		err = -ENODEV;
+		goto exit;
+	}
+
+	clk = clk_get(&pdev->dev, "csi_clk");
+	if (IS_ERR(clk)) {
+		err = PTR_ERR(clk);
+		goto exit;
+	}
+
+	pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
+	if (!pcdev) {
+		dev_err(&pdev->dev, "Could not allocate pcdev\n");
+		err = -ENOMEM;
+		goto exit_put_clk;
+	}
+
+	dev_set_drvdata(&pdev->dev, pcdev);
+	pcdev->res = res;
+	pcdev->clk = clk;
+
+	pcdev->pdata = pdev->dev.platform_data;
+
+	if (pcdev->pdata)
+		pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
+
+	if (!pcdev->mclk) {
+		dev_warn(&pdev->dev,
+			 "mclk_10khz == 0! Please, fix your platform data. "
+			 "Using default 20MHz\n");
+		pcdev->mclk = 20000000;
+	}
+
+	INIT_LIST_HEAD(&pcdev->capture);
+	spin_lock_init(&pcdev->lock);
+
+	/*
+	 * Request the regions.
+	 */
+	if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
+		err = -EBUSY;
+		goto exit_kfree;
+	}
+
+	base = ioremap(res->start, resource_size(res));
+	if (!base) {
+		err = -ENOMEM;
+		goto exit_release;
+	}
+	pcdev->irq = irq;
+	pcdev->base = base;
+	pcdev->dev = &pdev->dev;
+
+	/* request dma */
+	pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
+	if (pcdev->dma_chan < 0) {
+		dev_err(pcdev->dev, "Can't request DMA for MX1 CSI\n");
+		err = -EBUSY;
+		goto exit_iounmap;
+	}
+	dev_dbg(pcdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
+
+	imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
+			       pcdev);
+
+	imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
+			       IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+	/* burst length : 16 words = 64 bytes */
+	imx_dma_config_burstlen(pcdev->dma_chan, 0);
+
+	/* request irq */
+	err = claim_fiq(&fh);
+	if (err) {
+		dev_err(pcdev->dev, "Camera interrupt register failed \n");
+		goto exit_free_dma;
+	}
+
+	set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
+						   &mx1_camera_sof_fiq_start);
+
+	regs.ARM_r8 = DMA_BASE + DMA_DIMR;
+	regs.ARM_r9 = DMA_BASE + DMA_CCR(pcdev->dma_chan);
+	regs.ARM_r10 = (long)pcdev->base + CSICR1;
+	regs.ARM_fp = (long)pcdev->base + CSISR;
+	regs.ARM_sp = 1 << pcdev->dma_chan;
+	set_fiq_regs(&regs);
+
+	mxc_set_irq_fiq(irq, 1);
+	enable_fiq(irq);
+
+	mx1_soc_camera_host.priv	= pcdev;
+	mx1_soc_camera_host.dev.parent	= &pdev->dev;
+	mx1_soc_camera_host.nr		= pdev->id;
+	err = soc_camera_host_register(&mx1_soc_camera_host);
+	if (err)
+		goto exit_free_irq;
+
+	dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
+
+	return 0;
+
+exit_free_irq:
+	disable_fiq(irq);
+	mxc_set_irq_fiq(irq, 0);
+	release_fiq(&fh);
+exit_free_dma:
+	imx_dma_free(pcdev->dma_chan);
+exit_iounmap:
+	iounmap(base);
+exit_release:
+	release_mem_region(res->start, resource_size(res));
+exit_kfree:
+	kfree(pcdev);
+exit_put_clk:
+	clk_put(clk);
+exit:
+	return err;
+}
+
+static int __exit mx1_camera_remove(struct platform_device *pdev)
+{
+	struct mx1_camera_dev *pcdev = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	imx_dma_free(pcdev->dma_chan);
+	disable_fiq(pcdev->irq);
+	mxc_set_irq_fiq(pcdev->irq, 0);
+	release_fiq(&fh);
+
+	clk_put(pcdev->clk);
+
+	soc_camera_host_unregister(&mx1_soc_camera_host);
+
+	iounmap(pcdev->base);
+
+	res = pcdev->res;
+	release_mem_region(res->start, resource_size(res));
+
+	kfree(pcdev);
+
+	dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
+
+	return 0;
+}
+
+static struct platform_driver mx1_camera_driver = {
+	.driver 	= {
+		.name	= DRIVER_NAME,
+	},
+	.remove		= __exit_p(mx1_camera_remove),
+};
+
+static int __init mx1_camera_init(void)
+{
+	return platform_driver_probe(&mx1_camera_driver, mx1_camera_probe);
+}
+
+static void __exit mx1_camera_exit(void)
+{
+	return platform_driver_unregister(&mx1_camera_driver);
+}
+
+module_init(mx1_camera_init);
+module_exit(mx1_camera_exit);
+
+MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
+MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mx3_camera.c linux-libre-2.6.30-gnu1/drivers/media/video/mx3_camera.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mx3_camera.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mx3_camera.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1216 @@
+/*
+ * V4L2 Driver for i.MX3x camera host
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.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/version.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/soc_camera.h>
+
+#include <mach/ipu.h>
+#include <mach/mx3_camera.h>
+
+#define MX3_CAM_DRV_NAME "mx3-camera"
+
+/* CMOS Sensor Interface Registers */
+#define CSI_REG_START		0x60
+
+#define CSI_SENS_CONF		(0x60 - CSI_REG_START)
+#define CSI_SENS_FRM_SIZE	(0x64 - CSI_REG_START)
+#define CSI_ACT_FRM_SIZE	(0x68 - CSI_REG_START)
+#define CSI_OUT_FRM_CTRL	(0x6C - CSI_REG_START)
+#define CSI_TST_CTRL		(0x70 - CSI_REG_START)
+#define CSI_CCIR_CODE_1		(0x74 - CSI_REG_START)
+#define CSI_CCIR_CODE_2		(0x78 - CSI_REG_START)
+#define CSI_CCIR_CODE_3		(0x7C - CSI_REG_START)
+#define CSI_FLASH_STROBE_1	(0x80 - CSI_REG_START)
+#define CSI_FLASH_STROBE_2	(0x84 - CSI_REG_START)
+
+#define CSI_SENS_CONF_VSYNC_POL_SHIFT		0
+#define CSI_SENS_CONF_HSYNC_POL_SHIFT		1
+#define CSI_SENS_CONF_DATA_POL_SHIFT		2
+#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT		3
+#define CSI_SENS_CONF_SENS_PRTCL_SHIFT		4
+#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT		7
+#define CSI_SENS_CONF_DATA_FMT_SHIFT		8
+#define CSI_SENS_CONF_DATA_WIDTH_SHIFT		10
+#define CSI_SENS_CONF_EXT_VSYNC_SHIFT		15
+#define CSI_SENS_CONF_DIVRATIO_SHIFT		16
+
+#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444	(0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_YUV422		(2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_BAYER		(3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+
+#define MAX_VIDEO_MEM 16
+
+struct mx3_camera_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer			vb;
+	const struct soc_camera_data_format	*fmt;
+
+	/* One descriptot per scatterlist (per frame) */
+	struct dma_async_tx_descriptor		*txd;
+
+	/* We have to "build" a scatterlist ourselves - one element per frame */
+	struct scatterlist			sg;
+};
+
+/**
+ * struct mx3_camera_dev - i.MX3x camera (CSI) object
+ * @dev:		camera device, to which the coherent buffer is attached
+ * @icd:		currently attached camera sensor
+ * @clk:		pointer to clock
+ * @base:		remapped register base address
+ * @pdata:		platform data
+ * @platform_flags:	platform flags
+ * @mclk:		master clock frequency in Hz
+ * @capture:		list of capture videobuffers
+ * @lock:		protects video buffer lists
+ * @active:		active video buffer
+ * @idmac_channel:	array of pointers to IPU DMAC DMA channels
+ * @soc_host:		embedded soc_host object
+ */
+struct mx3_camera_dev {
+	struct device		*dev;
+	/*
+	 * i.MX3x is only supposed to handle one camera on its Camera Sensor
+	 * Interface. If anyone ever builds hardware to enable more than one
+	 * camera _simultaneously_, they will have to modify this driver too
+	 */
+	struct soc_camera_device *icd;
+	struct clk		*clk;
+
+	void __iomem		*base;
+
+	struct mx3_camera_pdata	*pdata;
+
+	unsigned long		platform_flags;
+	unsigned long		mclk;
+
+	struct list_head	capture;
+	spinlock_t		lock;		/* Protects video buffer lists */
+	struct mx3_camera_buffer *active;
+
+	/* IDMAC / dmaengine interface */
+	struct idmac_channel	*idmac_channel[1];	/* We need one channel */
+
+	struct soc_camera_host	soc_host;
+};
+
+struct dma_chan_request {
+	struct mx3_camera_dev	*mx3_cam;
+	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);
+}
+
+static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
+{
+	__raw_writel(value, mx3->base + reg);
+}
+
+/* Called from the IPU IDMAC ISR */
+static void mx3_cam_dma_done(void *arg)
+{
+	struct idmac_tx_desc *desc = to_tx_desc(arg);
+	struct dma_chan *chan = desc->txd.chan;
+	struct idmac_channel *ichannel = to_idmac_chan(chan);
+	struct mx3_camera_dev *mx3_cam = ichannel->client;
+	struct videobuf_buffer *vb;
+
+	dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
+		desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
+
+	spin_lock(&mx3_cam->lock);
+	if (mx3_cam->active) {
+		vb = &mx3_cam->active->vb;
+
+		list_del_init(&vb->queue);
+		vb->state = VIDEOBUF_DONE;
+		do_gettimeofday(&vb->ts);
+		vb->field_count++;
+		wake_up(&vb->done);
+	}
+
+	if (list_empty(&mx3_cam->capture)) {
+		mx3_cam->active = NULL;
+		spin_unlock(&mx3_cam->lock);
+
+		/*
+		 * stop capture - without further buffers IPU_CHA_BUF0_RDY will
+		 * not get updated
+		 */
+		return;
+	}
+
+	mx3_cam->active = list_entry(mx3_cam->capture.next,
+				     struct mx3_camera_buffer, vb.queue);
+	mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
+	spin_unlock(&mx3_cam->lock);
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+	struct videobuf_buffer *vb = &buf->vb;
+	struct dma_async_tx_descriptor *txd = buf->txd;
+	struct idmac_channel *ichan;
+
+	BUG_ON(in_interrupt());
+
+	dev_dbg(&icd->dev, "%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
+	 */
+	videobuf_waiton(vb, 0, 0);
+	if (txd) {
+		ichan = to_idmac_chan(txd->chan);
+		async_tx_ack(txd);
+	}
+	videobuf_dma_contig_free(vq, vb);
+	buf->txd = NULL;
+
+	vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+/*
+ * Videobuf operations
+ */
+
+/*
+ * Calculate the __buffer__ (not data) size and number of buffers.
+ * Called with .vb_lock held
+ */
+static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
+			      unsigned int *size)
+{
+	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);
+
+	if (!mx3_cam->idmac_channel[0])
+		return -EINVAL;
+
+	*size = icd->width * icd->height * bpp;
+
+	if (!*count)
+		*count = 32;
+
+	if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+		*count = MAX_VIDEO_MEM * 1024 * 1024 / *size;
+
+	return 0;
+}
+
+/* Called with .vb_lock held */
+static int mx3_videobuf_prepare(struct videobuf_queue *vq,
+		struct videobuf_buffer *vb, enum v4l2_field field)
+{
+	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;
+	struct mx3_camera_buffer *buf =
+		container_of(vb, struct mx3_camera_buffer, vb);
+	/* current_fmt _must_ always be set */
+	size_t new_size = icd->width * icd->height *
+		((icd->current_fmt->depth + 7) >> 3);
+	int ret;
+
+	/*
+	 * I think, in buf_prepare you only have to protect global data,
+	 * the actual buffer is yours
+	 */
+
+	if (buf->fmt	!= icd->current_fmt ||
+	    vb->width	!= icd->width ||
+	    vb->height	!= icd->height ||
+	    vb->field	!= field) {
+		buf->fmt	= icd->current_fmt;
+		vb->width	= icd->width;
+		vb->height	= icd->height;
+		vb->field	= field;
+		if (vb->state != VIDEOBUF_NEEDS_INIT)
+			free_buffer(vq, buf);
+	}
+
+	if (vb->baddr && vb->bsize < new_size) {
+		/* User provided buffer, but it is too small */
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (vb->state == VIDEOBUF_NEEDS_INIT) {
+		struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+		struct scatterlist *sg = &buf->sg;
+
+		/*
+		 * The total size of video-buffers that will be allocated / mapped.
+		 * *size that we calculated in videobuf_setup gets assigned to
+		 * vb->bsize, and now we use the same calculation to get vb->size.
+		 */
+		vb->size = new_size;
+
+		/* This actually (allocates and) maps buffers */
+		ret = videobuf_iolock(vq, vb, NULL);
+		if (ret)
+			goto fail;
+
+		/*
+		 * We will have to configure the IDMAC channel. It has two slots
+		 * for DMA buffers, we shall enter the first two buffers there,
+		 * and then submit new buffers in DMA-ready interrupts
+		 */
+		sg_init_table(sg, 1);
+		sg_dma_address(sg)	= videobuf_to_dma_contig(vb);
+		sg_dma_len(sg)		= vb->size;
+
+		buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
+			&ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
+			DMA_PREP_INTERRUPT);
+		if (!buf->txd) {
+			ret = -EIO;
+			goto fail;
+		}
+
+		buf->txd->callback_param	= buf->txd;
+		buf->txd->callback		= mx3_cam_dma_done;
+
+		vb->state = VIDEOBUF_PREPARED;
+	}
+
+	return 0;
+
+fail:
+	free_buffer(vq, buf);
+out:
+	return ret;
+}
+
+static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
+{
+	/* Add more formats as need arises and test possibilities appear... */
+	switch (fourcc) {
+	case V4L2_PIX_FMT_RGB565:
+		return IPU_PIX_FMT_RGB565;
+	case V4L2_PIX_FMT_RGB24:
+		return IPU_PIX_FMT_RGB24;
+	case V4L2_PIX_FMT_RGB332:
+		return IPU_PIX_FMT_RGB332;
+	case V4L2_PIX_FMT_YUV422P:
+		return IPU_PIX_FMT_YVU422P;
+	default:
+		return IPU_PIX_FMT_GENERIC;
+	}
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_queue(struct videobuf_queue *vq,
+			       struct videobuf_buffer *vb)
+{
+	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;
+	struct mx3_camera_buffer *buf =
+		container_of(vb, struct mx3_camera_buffer, vb);
+	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;
+	unsigned long flags;
+
+	/* This is the configuration of one sg-element */
+	video->out_pixel_fmt	= fourcc_to_ipu_pix(data_fmt->fourcc);
+	video->out_width	= icd->width;
+	video->out_height	= icd->height;
+	video->out_stride	= icd->width;
+
+#ifdef DEBUG
+	/* helps to see what DMA actually has written */
+	memset((void *)vb->baddr, 0xaa, vb->bsize);
+#endif
+
+	spin_lock_irqsave(&mx3_cam->lock, flags);
+
+	list_add_tail(&vb->queue, &mx3_cam->capture);
+
+	if (!mx3_cam->active) {
+		mx3_cam->active = buf;
+		vb->state = VIDEOBUF_ACTIVE;
+	} else {
+		vb->state = VIDEOBUF_QUEUED;
+	}
+
+	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+	cookie = txd->tx_submit(txd);
+	dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+	if (cookie >= 0)
+		return;
+
+	/* Submit error */
+	vb->state = VIDEOBUF_PREPARED;
+
+	spin_lock_irqsave(&mx3_cam->lock, flags);
+
+	list_del_init(&vb->queue);
+
+	if (mx3_cam->active == buf)
+		mx3_cam->active = NULL;
+
+	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_release(struct videobuf_queue *vq,
+				 struct videobuf_buffer *vb)
+{
+	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;
+	struct mx3_camera_buffer *buf =
+		container_of(vb, struct mx3_camera_buffer, vb);
+	unsigned long flags;
+
+	dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n",
+		mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
+		 vb->state, list_empty(&vb->queue) ? "" : "not ");
+	spin_lock_irqsave(&mx3_cam->lock, flags);
+	if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
+	    !list_empty(&vb->queue)) {
+		vb->state = VIDEOBUF_ERROR;
+
+		list_del_init(&vb->queue);
+		if (mx3_cam->active == buf)
+			mx3_cam->active = NULL;
+	}
+	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+	free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops mx3_videobuf_ops = {
+	.buf_setup      = mx3_videobuf_setup,
+	.buf_prepare    = mx3_videobuf_prepare,
+	.buf_queue      = mx3_videobuf_queue,
+	.buf_release    = mx3_videobuf_release,
+};
+
+static void mx3_camera_init_videobuf(struct videobuf_queue *q,
+				     struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+
+	videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev,
+				       &mx3_cam->lock,
+				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+				       V4L2_FIELD_NONE,
+				       sizeof(struct mx3_camera_buffer), icd);
+}
+
+/* First part of ipu_csi_init_interface() */
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
+				struct soc_camera_device *icd)
+{
+	u32 conf;
+	long rate;
+
+	/* Set default size: ipu_csi_set_window_size() */
+	csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
+	/* ...and position to 0:0: ipu_csi_set_window_pos() */
+	conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+	csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
+
+	/* We use only gated clock synchronisation mode so far */
+	conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
+
+	/* Set generic data, platform-biggest bus-width */
+	conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+	if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
+		conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+	else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
+		conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+	else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
+		conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+	else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
+		conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+
+	if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
+		conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
+	if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
+		conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
+	if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+		conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+	if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+		conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+	if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+		conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+	if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+		conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+
+	/* ipu_csi_init_interface() */
+	csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
+
+	clk_enable(mx3_cam->clk);
+	rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
+	dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+	if (rate)
+		clk_set_rate(mx3_cam->clk, rate);
+}
+
+/* Called with .video_lock held */
+static int mx3_camera_add_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	int ret;
+
+	if (mx3_cam->icd) {
+		ret = -EBUSY;
+		goto ebusy;
+	}
+
+	mx3_camera_activate(mx3_cam, icd);
+	ret = icd->ops->init(icd);
+	if (ret < 0) {
+		clk_disable(mx3_cam->clk);
+		goto einit;
+	}
+
+	mx3_cam->icd = icd;
+
+einit:
+ebusy:
+	if (!ret)
+		dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
+			 icd->devnum);
+
+	return ret;
+}
+
+/* Called with .video_lock held */
+static void mx3_camera_remove_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+
+	BUG_ON(icd != mx3_cam->icd);
+
+	if (*ichan) {
+		dma_release_channel(&(*ichan)->dma_chan);
+		*ichan = NULL;
+	}
+
+	icd->ops->release(icd);
+
+	clk_disable(mx3_cam->clk);
+
+	mx3_cam->icd = NULL;
+
+	dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
+static bool channel_change_requested(struct soc_camera_device *icd,
+				     struct v4l2_rect *rect)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+
+	/* Do buffers have to be re-allocated or channel re-configured? */
+	return ichan && rect->width * rect->height > icd->width * icd->height;
+}
+
+static int test_platform_param(struct mx3_camera_dev *mx3_cam,
+			       unsigned char buswidth, unsigned long *flags)
+{
+	/*
+	 * Platform specified synchronization and pixel clock polarities are
+	 * only a recommendation and are only used during probing. MX3x
+	 * camera interface only works in master mode, i.e., uses HSYNC and
+	 * VSYNC signals from the sensor
+	 */
+	*flags = SOCAM_MASTER |
+		SOCAM_HSYNC_ACTIVE_HIGH |
+		SOCAM_HSYNC_ACTIVE_LOW |
+		SOCAM_VSYNC_ACTIVE_HIGH |
+		SOCAM_VSYNC_ACTIVE_LOW |
+		SOCAM_PCLK_SAMPLE_RISING |
+		SOCAM_PCLK_SAMPLE_FALLING |
+		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 */
+	switch (buswidth) {
+	case 15:
+		if (!(mx3_cam->platform_flags & MX3_CAMERA_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))
+			return -EINVAL;
+		*flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
+			SOCAM_DATAWIDTH_4;
+		break;
+	case 8:
+		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8))
+			return -EINVAL;
+		*flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+		break;
+	case 4:
+		if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4))
+			return -EINVAL;
+		*flags |= SOCAM_DATAWIDTH_4;
+		break;
+	default:
+		dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
+				    const unsigned int depth)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	unsigned long bus_flags, camera_flags;
+	int ret = test_platform_param(mx3_cam, depth, &bus_flags);
+
+	dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+
+	if (ret < 0)
+		return ret;
+
+	camera_flags = icd->ops->query_bus_param(icd);
+
+	ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+	if (ret < 0)
+		dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n",
+			 camera_flags, bus_flags);
+
+	return ret;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+	struct dma_chan_request *rq = arg;
+	struct mx3_camera_pdata *pdata;
+
+	if (!rq)
+		return false;
+
+	pdata = rq->mx3_cam->dev->platform_data;
+
+	return rq->id == chan->chan_id &&
+		pdata->dma_dev == chan->device->dev;
+}
+
+static const struct soc_camera_data_format mx3_camera_formats[] = {
+	{
+		.name		= "Bayer (sRGB) 8 bit",
+		.depth		= 8,
+		.fourcc		= V4L2_PIX_FMT_SBGGR8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
+	}, {
+		.name		= "Monochrome 8 bit",
+		.depth		= 8,
+		.fourcc		= V4L2_PIX_FMT_GREY,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	},
+};
+
+static bool buswidth_supported(struct soc_camera_host *ici, int depth)
+{
+	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;
+}
+
+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;
+
+	buswidth = icd->formats[idx].depth;
+
+	if (!buswidth_supported(ici, buswidth))
+		return 0;
+
+	ret = mx3_camera_try_bus_param(icd, buswidth);
+	if (ret < 0)
+		return 0;
+
+	switch (icd->formats[idx].fourcc) {
+	case V4L2_PIX_FMT_SGRBG10:
+		formats++;
+		if (xlate) {
+			xlate->host_fmt = &mx3_camera_formats[0];
+			xlate->cam_fmt = icd->formats + idx;
+			xlate->buswidth = buswidth;
+			xlate++;
+			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+				mx3_camera_formats[0].name,
+				icd->formats[idx].name);
+		}
+		goto passthrough;
+	case V4L2_PIX_FMT_Y16:
+		formats++;
+		if (xlate) {
+			xlate->host_fmt = &mx3_camera_formats[1];
+			xlate->cam_fmt = icd->formats + idx;
+			xlate->buswidth = buswidth;
+			xlate++;
+			dev_dbg(&ici->dev, "Providing format %s using %s\n",
+				mx3_camera_formats[0].name,
+				icd->formats[idx].name);
+		}
+	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(&ici->dev,
+				"Providing format %s in pass-through mode\n",
+				icd->formats[idx].name);
+		}
+	}
+
+	return formats;
+}
+
+static void configure_geometry(struct mx3_camera_dev *mx3_cam,
+			       struct v4l2_rect *rect)
+{
+	u32 ctrl, width_field, height_field;
+
+	/* Setup frame size - this cannot be changed on-the-fly... */
+	width_field = rect->width - 1;
+	height_field = rect->height - 1;
+	csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
+
+	csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
+	csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
+
+	csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
+
+	/* ...and position */
+	ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+	/* Sensor does the cropping */
+	csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
+
+	/*
+	 * No need to free resources here if we fail, we'll see if we need to
+	 * do this next time we are called
+	 */
+}
+
+static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
+{
+	dma_cap_mask_t mask;
+	struct dma_chan *chan;
+	struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+	/* We have to use IDMAC_IC_7 for Bayer / generic data */
+	struct dma_chan_request rq = {.mx3_cam = mx3_cam,
+				      .id = IDMAC_IC_7};
+
+	if (*ichan) {
+		struct videobuf_buffer *vb, *_vb;
+		dma_release_channel(&(*ichan)->dma_chan);
+		*ichan = NULL;
+		mx3_cam->active = NULL;
+		list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
+			list_del_init(&vb->queue);
+			vb->state = VIDEOBUF_ERROR;
+			wake_up(&vb->done);
+		}
+	}
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	dma_cap_set(DMA_PRIVATE, mask);
+	chan = dma_request_channel(mask, chan_filter, &rq);
+	if (!chan)
+		return -EBUSY;
+
+	*ichan = to_idmac_chan(chan);
+	(*ichan)->client = mx3_cam;
+
+	return 0;
+}
+
+static int mx3_camera_set_crop(struct soc_camera_device *icd,
+			       struct v4l2_rect *rect)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+
+	/*
+	 * We now know pixel formats and can decide upon DMA-channel(s)
+	 * So far only direct camera-to-memory is supported
+	 */
+	if (channel_change_requested(icd, rect)) {
+		int ret = acquire_dma_channel(mx3_cam);
+		if (ret < 0)
+			return ret;
+	}
+
+	configure_geometry(mx3_cam, rect);
+
+	return icd->ops->set_crop(icd, rect);
+}
+
+static int mx3_camera_set_fmt(struct soc_camera_device *icd,
+			      struct v4l2_format *f)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_rect rect = {
+		.left	= icd->x_current,
+		.top	= icd->y_current,
+		.width	= pix->width,
+		.height	= pix->height,
+	};
+	int ret;
+
+	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+	if (!xlate) {
+		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		return -EINVAL;
+	}
+
+	ret = acquire_dma_channel(mx3_cam);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Might have to perform a complete interface initialisation like in
+	 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
+	 * mxc_v4l2_s_fmt()
+	 */
+
+	configure_geometry(mx3_cam, &rect);
+
+	ret = icd->ops->set_fmt(icd, f);
+	if (!ret) {
+		icd->buswidth = xlate->buswidth;
+		icd->current_fmt = xlate->host_fmt;
+	}
+
+	return ret;
+}
+
+static int mx3_camera_try_fmt(struct soc_camera_device *icd,
+			      struct v4l2_format *f)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	__u32 pixfmt = pix->pixelformat;
+	enum v4l2_field field;
+	int ret;
+
+	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+	if (pixfmt && !xlate) {
+		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		return -EINVAL;
+	}
+
+	/* limit to MX3 hardware capabilities */
+	if (pix->height > 4096)
+		pix->height = 4096;
+	if (pix->width > 4096)
+		pix->width = 4096;
+
+	pix->bytesperline = pix->width *
+		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+	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 = icd->ops->try_fmt(icd, f);
+	pix->pixelformat = xlate->host_fmt->fourcc;
+
+	field = pix->field;
+
+	if (field == V4L2_FIELD_ANY) {
+		pix->field = V4L2_FIELD_NONE;
+	} else if (field != V4L2_FIELD_NONE) {
+		dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int mx3_camera_reqbufs(struct soc_camera_file *icf,
+			      struct v4l2_requestbuffers *p)
+{
+	return 0;
+}
+
+static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
+{
+	struct soc_camera_file *icf = file->private_data;
+
+	return videobuf_poll_stream(file, &icf->vb_vidq, pt);
+}
+
+static int mx3_camera_querycap(struct soc_camera_host *ici,
+			       struct v4l2_capability *cap)
+{
+	/* cap->name is set by the firendly caller:-> */
+	strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
+	cap->version = KERNEL_VERSION(0, 2, 2);
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+
+	return 0;
+}
+
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	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_camera_format_xlate *xlate;
+
+	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+	if (!xlate) {
+		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+		return -EINVAL;
+	}
+
+	dev_dbg(&ici->dev, "requested bus width %d bit: %d\n",
+		icd->buswidth, ret);
+
+	if (ret < 0)
+		return ret;
+
+	camera_flags = icd->ops->query_bus_param(icd);
+
+	common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+	if (!common_flags) {
+		dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n",
+			camera_flags, bus_flags);
+		return -EINVAL;
+	}
+
+	/* Make choices, based on platform preferences */
+	if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+		if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+			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 (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+	}
+
+	if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+		if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+			common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+	}
+
+	if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+	    (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+		if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+			common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+		else
+			common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+	}
+
+	/* 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;
+	else if (common_flags & SOCAM_DATAWIDTH_10)
+		common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+			SOCAM_DATAWIDTH_10;
+	else if (common_flags & SOCAM_DATAWIDTH_8)
+		common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+			SOCAM_DATAWIDTH_8;
+	else
+		common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+			SOCAM_DATAWIDTH_4;
+
+	ret = icd->ops->set_bus_param(icd, common_flags);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * So far only gated clock mode is supported. Add a line
+	 *	(3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
+	 * below and select the required mode when supporting other
+	 * synchronisation protocols.
+	 */
+	sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
+		~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
+		  (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
+		  (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
+		  (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
+		  (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
+		  (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
+
+	/* TODO: Support RGB and YUV formats */
+
+	/* This has been set in mx3_camera_activate(), but we clear it above */
+	sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+	if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+		sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+	if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+		sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+	if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+		sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+	if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+		sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+
+	/* Just do what we're asked to do */
+	switch (xlate->host_fmt->depth) {
+	case 4:
+		dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+		break;
+	case 8:
+		dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+		break;
+	case 10:
+		dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+		break;
+	default:
+		/*
+		 * Actually it can only be 15 now, default is just to silence
+		 * compiler warnings
+		 */
+	case 15:
+		dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+	}
+
+	csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
+
+	dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+
+	return 0;
+}
+
+static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
+	.owner		= THIS_MODULE,
+	.add		= mx3_camera_add_device,
+	.remove		= mx3_camera_remove_device,
+	.set_crop	= mx3_camera_set_crop,
+	.set_fmt	= mx3_camera_set_fmt,
+	.try_fmt	= mx3_camera_try_fmt,
+	.get_formats	= mx3_camera_get_formats,
+	.init_videobuf	= mx3_camera_init_videobuf,
+	.reqbufs	= mx3_camera_reqbufs,
+	.poll		= mx3_camera_poll,
+	.querycap	= mx3_camera_querycap,
+	.set_bus_param	= mx3_camera_set_bus_param,
+};
+
+static int mx3_camera_probe(struct platform_device *pdev)
+{
+	struct mx3_camera_dev *mx3_cam;
+	struct resource *res;
+	void __iomem *base;
+	int err = 0;
+	struct soc_camera_host *soc_host;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		err = -ENODEV;
+		goto egetres;
+	}
+
+	mx3_cam = vmalloc(sizeof(*mx3_cam));
+	if (!mx3_cam) {
+		dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
+		err = -ENOMEM;
+		goto ealloc;
+	}
+	memset(mx3_cam, 0, sizeof(*mx3_cam));
+
+	mx3_cam->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mx3_cam->clk)) {
+		err = PTR_ERR(mx3_cam->clk);
+		goto eclkget;
+	}
+
+	dev_set_drvdata(&pdev->dev, mx3_cam);
+
+	mx3_cam->pdata = pdev->dev.platform_data;
+	mx3_cam->platform_flags = mx3_cam->pdata->flags;
+	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. */
+		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;
+	}
+
+	mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
+	if (!mx3_cam->mclk) {
+		dev_warn(&pdev->dev,
+			 "mclk_10khz == 0! Please, fix your platform data. "
+			 "Using default 20MHz\n");
+		mx3_cam->mclk = 20000000;
+	}
+
+	/* list of video-buffers */
+	INIT_LIST_HEAD(&mx3_cam->capture);
+	spin_lock_init(&mx3_cam->lock);
+
+	base = ioremap(res->start, res->end - res->start + 1);
+	if (!base) {
+		err = -ENOMEM;
+		goto eioremap;
+	}
+
+	mx3_cam->base	= base;
+	mx3_cam->dev	= &pdev->dev;
+
+	soc_host		= &mx3_cam->soc_host;
+	soc_host->drv_name	= MX3_CAM_DRV_NAME;
+	soc_host->ops		= &mx3_soc_camera_host_ops;
+	soc_host->priv		= mx3_cam;
+	soc_host->dev.parent	= &pdev->dev;
+	soc_host->nr		= pdev->id;
+	err = soc_camera_host_register(soc_host);
+	if (err)
+		goto ecamhostreg;
+
+	/* IDMAC interface */
+	dmaengine_get();
+
+	return 0;
+
+ecamhostreg:
+	iounmap(base);
+eioremap:
+	clk_put(mx3_cam->clk);
+eclkget:
+	vfree(mx3_cam);
+ealloc:
+egetres:
+	return err;
+}
+
+static int __devexit mx3_camera_remove(struct platform_device *pdev)
+{
+	struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev);
+
+	clk_put(mx3_cam->clk);
+
+	soc_camera_host_unregister(&mx3_cam->soc_host);
+
+	iounmap(mx3_cam->base);
+
+	/*
+	 * The channel has either not been allocated,
+	 * or should have been released
+	 */
+	if (WARN_ON(mx3_cam->idmac_channel[0]))
+		dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
+
+	vfree(mx3_cam);
+
+	dmaengine_put();
+
+	dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
+
+	return 0;
+}
+
+static struct platform_driver mx3_camera_driver = {
+	.driver 	= {
+		.name	= MX3_CAM_DRV_NAME,
+	},
+	.probe		= mx3_camera_probe,
+	.remove		= __exit_p(mx3_camera_remove),
+};
+
+
+static int __devinit mx3_camera_init(void)
+{
+	return platform_driver_register(&mx3_camera_driver);
+}
+
+static void __exit mx3_camera_exit(void)
+{
+	platform_driver_unregister(&mx3_camera_driver);
+}
+
+module_init(mx3_camera_init);
+module_exit(mx3_camera_exit);
+
+MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_LICENSE("GPL v2");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/mxb.c linux-libre-2.6.30-gnu1/drivers/media/video/mxb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/mxb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/mxb.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,16 +25,20 @@
 
 #include <media/saa7146_vv.h>
 #include <media/tuner.h>
-#include <linux/video_decoder.h>
 #include <media/v4l2-common.h>
 #include <media/saa7115.h>
 
 #include "mxb.h"
 #include "tea6415c.h"
 #include "tea6420.h"
-#include "tda9840.h"
 
-#define I2C_SAA7111 0x24
+#define	I2C_SAA5246A  0x11
+#define I2C_SAA7111A  0x24
+#define	I2C_TDA9840   0x42
+#define	I2C_TEA6415C  0x43
+#define	I2C_TEA6420_1 0x4c
+#define	I2C_TEA6420_2 0x4d
+#define	I2C_TUNER     0x60
 
 #define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
 
@@ -79,57 +83,40 @@ static struct {
 static int video_audio_connect[MXB_INPUTS] =
 	{ 0, 1, 3, 3 };
 
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the CD-output */
-static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
-		{
-		{{1,1,0},{1,1,0}},	/* Tuner */
-		{{5,1,0},{6,1,0}},	/* AUX 1 */
-		{{4,1,0},{6,1,0}},	/* AUX 2 */
-		{{3,1,0},{6,1,0}},	/* AUX 3 */
-		{{1,1,0},{3,1,0}},	/* Radio */
-		{{1,1,0},{2,1,0}},	/* CD-Rom */
-		{{6,1,0},{6,1,0}}	/* Mute */
-		};
+struct mxb_routing {
+	u32 input;
+	u32 output;
+};
 
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the line-output */
-static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
-		{
-		{{2,3,0},{1,2,0}},
-		{{5,3,0},{6,2,0}},
-		{{4,3,0},{6,2,0}},
-		{{3,3,0},{6,2,0}},
-		{{2,3,0},{3,2,0}},
-		{{2,3,0},{2,2,0}},
-		{{6,3,0},{6,2,0}}	/* Mute */
-		};
+/* These are the necessary input-output-pins for bringing one audio source
+   (see above) to the CD-output. Note that gain is set to 0 in this table. */
+static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+	{ { 1, 1 }, { 1, 1 } },	/* Tuner */
+	{ { 5, 1 }, { 6, 1 } },	/* AUX 1 */
+	{ { 4, 1 }, { 6, 1 } },	/* AUX 2 */
+	{ { 3, 1 }, { 6, 1 } },	/* AUX 3 */
+	{ { 1, 1 }, { 3, 1 } },	/* Radio */
+	{ { 1, 1 }, { 2, 1 } },	/* CD-Rom */
+	{ { 6, 1 }, { 6, 1 } }	/* Mute */
+};
+
+/* These are the necessary input-output-pins for bringing one audio source
+   (see above) to the line-output. Note that gain is set to 0 in this table. */
+static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+	{ { 2, 3 }, { 1, 2 } },
+	{ { 5, 3 }, { 6, 2 } },
+	{ { 4, 3 }, { 6, 2 } },
+	{ { 3, 3 }, { 6, 2 } },
+	{ { 2, 3 }, { 3, 2 } },
+	{ { 2, 3 }, { 2, 2 } },
+	{ { 6, 3 }, { 6, 2 } }	/* Mute */
+};
 
 #define MAXCONTROLS	1
 static struct v4l2_queryctrl mxb_controls[] = {
 	{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
 };
 
-static struct saa7146_extension_ioctls ioctls[] = {
-	{ VIDIOC_ENUMINPUT, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_INPUT,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_QUERYCTRL, 	SAA7146_BEFORE },
-	{ VIDIOC_G_CTRL,	SAA7146_BEFORE },
-	{ VIDIOC_S_CTRL,	SAA7146_BEFORE },
-	{ VIDIOC_G_TUNER, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_TUNER, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_FREQUENCY,	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_FREQUENCY, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_G_AUDIO, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_S_AUDIO, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_DBG_G_REGISTER, 	SAA7146_EXCLUSIVE },
-	{ VIDIOC_DBG_S_REGISTER, 	SAA7146_EXCLUSIVE },
-	{ MXB_S_AUDIO_CD, 	SAA7146_EXCLUSIVE },	/* custom control */
-	{ MXB_S_AUDIO_LINE, 	SAA7146_EXCLUSIVE },	/* custom control */
-	{ 0,			0 }
-};
-
 struct mxb
 {
 	struct video_device	*video_dev;
@@ -137,12 +124,12 @@ struct mxb
 
 	struct i2c_adapter	i2c_adapter;
 
-	struct i2c_client	*saa7111a;
-	struct i2c_client	*tda9840;
-	struct i2c_client	*tea6415c;
-	struct i2c_client	*tuner;
-	struct i2c_client	*tea6420_1;
-	struct i2c_client	*tea6420_2;
+	struct v4l2_subdev	*saa7111a;
+	struct v4l2_subdev	*tda9840;
+	struct v4l2_subdev	*tea6415c;
+	struct v4l2_subdev	*tuner;
+	struct v4l2_subdev	*tea6420_1;
+	struct v4l2_subdev	*tea6420_2;
 
 	int	cur_mode;	/* current audio mode (mono, stereo, ...) */
 	int	cur_input;	/* current input */
@@ -150,84 +137,70 @@ struct mxb
 	struct v4l2_frequency	cur_freq;	/* current frequency the tuner is tuned to */
 };
 
-static struct saa7146_extension extension;
+#define saa7111a_call(mxb, o, f, args...) \
+	v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
+#define tda9840_call(mxb, o, f, args...) \
+	v4l2_subdev_call(mxb->tda9840, o, f, ##args)
+#define tea6415c_call(mxb, o, f, args...) \
+	v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
+#define tuner_call(mxb, o, f, args...) \
+	v4l2_subdev_call(mxb->tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
 
-static int mxb_check_clients(struct device *dev, void *data)
+static inline void tea6420_route_cd(struct mxb *mxb, int idx)
 {
-	struct mxb *mxb = data;
-	struct i2c_client *client = i2c_verify_client(dev);
-
-	if (!client)
-		return 0;
-
-	if (I2C_ADDR_TEA6420_1 == client->addr)
-		mxb->tea6420_1 = client;
-	if (I2C_ADDR_TEA6420_2 == client->addr)
-		mxb->tea6420_2 = client;
-	if (I2C_TEA6415C_2 == client->addr)
-		mxb->tea6415c = client;
-	if (I2C_ADDR_TDA9840 == client->addr)
-		mxb->tda9840 = client;
-	if (I2C_SAA7111 == client->addr)
-		mxb->saa7111a = client;
-	if (0x60 == client->addr)
-		mxb->tuner = client;
-
-	return 0;
+	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+		TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
+	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+		TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
 }
 
-static int mxb_probe(struct saa7146_dev* dev)
+static inline void tea6420_route_line(struct mxb *mxb, int idx)
 {
-	struct mxb* mxb = NULL;
-	int result;
+	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
+		TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
+	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
+		TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
+}
 
-	result = request_module("saa7115");
-	if (result < 0) {
-		printk("mxb: saa7111 i2c module not available.\n");
-		return -ENODEV;
-	}
-	result = request_module("tea6420");
-	if (result < 0) {
-		printk("mxb: tea6420 i2c module not available.\n");
-		return -ENODEV;
-	}
-	result = request_module("tea6415c");
-	if (result < 0) {
-		printk("mxb: tea6415c i2c module not available.\n");
-		return -ENODEV;
-	}
-	result = request_module("tda9840");
-	if (result < 0) {
-		printk("mxb: tda9840 i2c module not available.\n");
-		return -ENODEV;
-	}
-	result = request_module("tuner");
-	if (result < 0) {
-		printk("mxb: tuner i2c module not available.\n");
-		return -ENODEV;
-	}
+static struct saa7146_extension extension;
+
+static int mxb_probe(struct saa7146_dev *dev)
+{
+	struct mxb *mxb = NULL;
 
 	mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
-	if( NULL == mxb ) {
+	if (mxb == NULL) {
 		DEB_D(("not enough kernel memory.\n"));
 		return -ENOMEM;
 	}
 
-	mxb->i2c_adapter = (struct i2c_adapter) {
-		.class = I2C_CLASS_TV_ANALOG,
-	};
-
 	snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
 
 	saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
-	if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
+	if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
 		DEB_S(("cannot register i2c-device. skipping.\n"));
 		kfree(mxb);
 		return -EFAULT;
 	}
 
-	/* loop through all i2c-devices on the bus and look who is there */
-	device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+	mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"saa7115", "saa7111", I2C_SAA7111A);
+	mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"tea6420", "tea6420", I2C_TEA6420_1);
+	mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"tea6420", "tea6420", I2C_TEA6420_2);
+	mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"tea6415c", "tea6415c", I2C_TEA6415C);
+	mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"tda9840", "tda9840", I2C_TDA9840);
+	mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"tuner", "tuner", I2C_TUNER);
+	if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
+			"saa5246a", "saa5246a", I2C_SAA5246A)) {
+		printk(KERN_INFO "mxb: found teletext decoder\n");
+	}
 
 	/* check if all devices are present */
 	if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
@@ -312,50 +285,40 @@ static int mxb_init_done(struct saa7146_
 	struct i2c_msg msg;
 	struct tuner_setup tun_setup;
 	v4l2_std_id std = V4L2_STD_PAL_BG;
-	struct v4l2_routing route;
 
 	int i = 0, err = 0;
-	struct tea6415c_multiplex vm;
 
 	/* select video mode in saa7111a */
-	mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
+	saa7111a_call(mxb, core, s_std, std);
 
 	/* select tuner-output on saa7111a */
 	i = 0;
-	route.input = SAA7115_COMPOSITE0;
-	route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
-	mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
+		SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
 
 	/* select a tuner type */
 	tun_setup.mode_mask = T_ANALOG_TV;
 	tun_setup.addr = ADDR_UNSET;
 	tun_setup.type = TUNER_PHILIPS_PAL;
-	mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
+	tuner_call(mxb, tuner, s_type_addr, &tun_setup);
 	/* tune in some frequency on tuner */
 	mxb->cur_freq.tuner = 0;
 	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
 	mxb->cur_freq.frequency = freq;
-	mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
-					&mxb->cur_freq);
+	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
 
 	/* set a default video standard */
-	mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+	tuner_call(mxb, core, s_std, std);
 
 	/* mute audio on tea6420s */
-	mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
-	mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
-	mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
-	mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
+	tea6420_route_line(mxb, 6);
+	tea6420_route_cd(mxb, 6);
 
-	/* switch to tuner-channel on tea6415c*/
-	vm.out = 17;
-	vm.in  = 3;
-	mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+	/* switch to tuner-channel on tea6415c */
+	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 
-	/* select tuner-output on multicable on tea6415c*/
-	vm.in  = 3;
-	vm.out = 13;
-	mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+	/* select tuner-output on multicable on tea6415c */
+	tea6415c_call(mxb, video, s_routing, 3, 13, 0);
 
 	/* the rest for mxb */
 	mxb->cur_input = 0;
@@ -424,395 +387,380 @@ void mxb_irq_bh(struct saa7146_dev* dev,
 }
 */
 
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
 {
-	struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
-	DEB_EE(("dev:%p\n", dev));
-
-	/* checking for i2c-devices can be omitted here, because we
-	   already did this in "mxb_vl42_probe" */
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	int i;
 
-	saa7146_vv_init(dev, &vv_data);
-	if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
-		ERR(("cannot register capture v4l2 device. skipping.\n"));
-		return -1;
+	for (i = MAXCONTROLS - 1; i >= 0; i--) {
+		if (mxb_controls[i].id == qc->id) {
+			*qc = mxb_controls[i];
+			DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+			return 0;
+		}
 	}
+	return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
 
-	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
-	if (MXB_BOARD_CAN_DO_VBI(dev)) {
-		if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
-			ERR(("cannot register vbi v4l2 device. skipping.\n"));
-		}
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+	int i;
+
+	for (i = MAXCONTROLS - 1; i >= 0; i--) {
+		if (mxb_controls[i].id == vc->id)
+			break;
 	}
 
-	i2c_use_client(mxb->tea6420_1);
-	i2c_use_client(mxb->tea6420_2);
-	i2c_use_client(mxb->tea6415c);
-	i2c_use_client(mxb->tda9840);
-	i2c_use_client(mxb->saa7111a);
-	i2c_use_client(mxb->tuner);
+	if (i < 0)
+		return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
 
-	printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+	if (vc->id == V4L2_CID_AUDIO_MUTE) {
+		vc->value = mxb->cur_mute;
+		DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
+		return 0;
+	}
 
-	mxb_num++;
-	mxb_init_done(dev);
+	DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
 	return 0;
 }
 
-static int mxb_detach(struct saa7146_dev *dev)
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
 {
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+	int i = 0;
 
-	DEB_EE(("dev:%p\n", dev));
+	for (i = MAXCONTROLS - 1; i >= 0; i--) {
+		if (mxb_controls[i].id == vc->id)
+			break;
+	}
 
-	i2c_release_client(mxb->tea6420_1);
-	i2c_release_client(mxb->tea6420_2);
-	i2c_release_client(mxb->tea6415c);
-	i2c_release_client(mxb->tda9840);
-	i2c_release_client(mxb->saa7111a);
-	i2c_release_client(mxb->tuner);
+	if (i < 0)
+		return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
 
-	saa7146_unregister_device(&mxb->video_dev,dev);
-	if (MXB_BOARD_CAN_DO_VBI(dev))
-		saa7146_unregister_device(&mxb->vbi_dev, dev);
-	saa7146_vv_release(dev);
+	if (vc->id == V4L2_CID_AUDIO_MUTE) {
+		mxb->cur_mute = vc->value;
+		/* switch the audio-source */
+		tea6420_route_line(mxb, vc->value ? 6 :
+				video_audio_connect[mxb->cur_input]);
+		DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+	}
+	return 0;
+}
 
-	mxb_num--;
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+	DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+	if (i->index < 0 || i->index >= MXB_INPUTS)
+		return -EINVAL;
+	memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
+	return 0;
+}
 
-	i2c_del_adapter(&mxb->i2c_adapter);
-	kfree(mxb);
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+	*i = mxb->cur_input;
 
+	DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
 	return 0;
 }
 
-static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
 {
-	struct saa7146_dev *dev = fh->dev;
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
-	struct saa7146_vv *vv = dev->vv_data;
+	int err = 0;
+	int i = 0;
 
-	switch(cmd) {
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input *i = arg;
+	DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
 
-		DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
-		if (i->index < 0 || i->index >= MXB_INPUTS)
-			return -EINVAL;
-		memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
-		return 0;
-	}
-	/* the saa7146 provides some controls (brightness, contrast, saturation)
-	   which gets registered *after* this function. because of this we have
-	   to return with a value != 0 even if the function succeded.. */
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *qc = arg;
-		int i;
+	if (input < 0 || input >= MXB_INPUTS)
+		return -EINVAL;
 
-		for (i = MAXCONTROLS - 1; i >= 0; i--) {
-			if (mxb_controls[i].id == qc->id) {
-				*qc = mxb_controls[i];
-				DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
-				return 0;
-			}
-		}
-		return -EAGAIN;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *vc = arg;
-		int i;
+	mxb->cur_input = input;
 
-		for (i = MAXCONTROLS - 1; i >= 0; i--) {
-			if (mxb_controls[i].id == vc->id)
-				break;
-		}
+	saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
+			input_port_selection[input].hps_sync);
 
-		if (i < 0)
-			return -EAGAIN;
+	/* prepare switching of tea6415c and saa7111a;
+	   have a look at the 'background'-file for further informations  */
+	switch (input) {
+	case TUNER:
+		i = SAA7115_COMPOSITE0;
 
-		if (vc->id == V4L2_CID_AUDIO_MUTE) {
-			vc->value = mxb->cur_mute;
-			DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
-			return 0;
-		}
+		err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 
-		DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
-		return 0;
+		/* connect tuner-output always to multicable */
+		if (!err)
+			err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
+		break;
+	case AUX3_YC:
+		/* nothing to be done here. aux3_yc is
+		   directly connected to the saa711a */
+		i = SAA7115_SVIDEO1;
+		break;
+	case AUX3:
+		/* nothing to be done here. aux3 is
+		   directly connected to the saa711a */
+		i = SAA7115_COMPOSITE1;
+		break;
+	case AUX1:
+		i = SAA7115_COMPOSITE0;
+		err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
+		break;
 	}
 
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *vc = arg;
-		int i = 0;
+	if (err)
+		return err;
 
-		for (i = MAXCONTROLS - 1; i >= 0; i--) {
-			if (mxb_controls[i].id == vc->id)
-				break;
-		}
+	/* switch video in saa7111a */
+	if (saa7111a_call(mxb, video, s_routing, i, 0, 0))
+		printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
 
-		if (i < 0)
-			return -EAGAIN;
+	/* switch the audio-source only if necessary */
+	if (0 == mxb->cur_mute)
+		tea6420_route_line(mxb, video_audio_connect[input]);
 
-		if (vc->id == V4L2_CID_AUDIO_MUTE) {
-			mxb->cur_mute = vc->value;
-			if (!vc->value) {
-				/* switch the audio-source */
-				mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
-						&TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
-				mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
-						&TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
-			} else {
-				mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
-						&TEA6420_line[6][0]);
-				mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
-						&TEA6420_line[6][1]);
-			}
-			DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
-		}
-		return 0;
-	}
-	case VIDIOC_G_INPUT:
-	{
-		int *input = (int *)arg;
-		*input = mxb->cur_input;
+	return 0;
+}
 
-		DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
-		return 0;
-	}
-	case VIDIOC_S_INPUT:
-	{
-		int input = *(int *)arg;
-		struct tea6415c_multiplex vm;
-		struct v4l2_routing route;
-		int i = 0;
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 
-		DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+	if (t->index) {
+		DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
+		return -EINVAL;
+	}
 
-		if (input < 0 || input >= MXB_INPUTS)
-			return -EINVAL;
+	DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
 
-		mxb->cur_input = input;
+	memset(t, 0, sizeof(*t));
+	strlcpy(t->name, "TV Tuner", sizeof(t->name));
+	t->type = V4L2_TUNER_ANALOG_TV;
+	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+	t->audmode = mxb->cur_mode;
+	return call_all(dev, tuner, g_tuner, t);
+}
 
-		saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
-				input_port_selection[input].hps_sync);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 
-		/* prepare switching of tea6415c and saa7111a;
-		   have a look at the 'background'-file for further informations  */
-		switch (input) {
-		case TUNER:
-			i = SAA7115_COMPOSITE0;
-			vm.in  = 3;
-			vm.out = 17;
+	if (t->index) {
+		DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
+		return -EINVAL;
+	}
 
-			if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
-				printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
-				return -EFAULT;
-			}
-			/* connect tuner-output always to multicable */
-			vm.in  = 3;
-			vm.out = 13;
-			break;
-		case AUX3_YC:
-			/* nothing to be done here. aux3_yc is
-			   directly connected to the saa711a */
-			i = SAA7115_SVIDEO1;
-			break;
-		case AUX3:
-			/* nothing to be done here. aux3 is
-			   directly connected to the saa711a */
-			i = SAA7115_COMPOSITE1;
-			break;
-		case AUX1:
-			i = SAA7115_COMPOSITE0;
-			vm.in  = 1;
-			vm.out = 17;
-			break;
-		}
+	mxb->cur_mode = t->audmode;
+	return call_all(dev, tuner, s_tuner, t);
+}
 
-		/* switch video in tea6415c only if necessary */
-		switch (input) {
-		case TUNER:
-		case AUX1:
-			if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
-				printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
-				return -EFAULT;
-			}
-			break;
-		default:
-			break;
-		}
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 
-		/* switch video in saa7111a */
-		route.input = i;
-		route.output = 0;
-		if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
-			printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+	if (mxb->cur_input) {
+		DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
+					mxb->cur_input));
+		return -EINVAL;
+	}
 
-		/* switch the audio-source only if necessary */
-		if( 0 == mxb->cur_mute ) {
-			mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
-					&TEA6420_line[video_audio_connect[input]][0]);
-			mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
-				       &TEA6420_line[video_audio_connect[input]][1]);
-		}
+	*f = mxb->cur_freq;
 
-		return 0;
-	}
-	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *t = arg;
+	DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
+	return 0;
+}
 
-		if (t->index) {
-			DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
-			return -EINVAL;
-		}
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+	struct saa7146_vv *vv = dev->vv_data;
 
-		DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+	if (f->tuner)
+		return -EINVAL;
 
-		memset(t, 0, sizeof(*t));
-		i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
+	if (V4L2_TUNER_ANALOG_TV != f->type)
+		return -EINVAL;
 
-		strlcpy(t->name, "TV Tuner", sizeof(t->name));
-		t->type = V4L2_TUNER_ANALOG_TV;
-		t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
-			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-		t->audmode = mxb->cur_mode;
-		return 0;
+	if (mxb->cur_input) {
+		DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
+		return -EINVAL;
 	}
-	case VIDIOC_S_TUNER:
-	{
-		struct v4l2_tuner *t = arg;
 
-		if (t->index) {
-			DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
-			return -EINVAL;
-		}
+	mxb->cur_freq = *f;
+	DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
 
-		mxb->cur_mode = t->audmode;
-		i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
-		return 0;
-	}
-	case VIDIOC_G_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
+	/* tune in desired frequency */
+	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
 
-		if (mxb->cur_input) {
-			DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
-						mxb->cur_input));
-			return -EINVAL;
-		}
+	/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
+	spin_lock(&dev->slock);
+	vv->vbi_fieldcount = 0;
+	spin_unlock(&dev->slock);
 
-		*f = mxb->cur_freq;
+	return 0;
+}
 
-		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
-		return 0;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+	if (a->index < 0 || a->index > MXB_INPUTS) {
+		DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
+		return -EINVAL;
 	}
-	case VIDIOC_S_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
 
-		if (f->tuner)
-			return -EINVAL;
+	DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
+	memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+	return 0;
+}
 
-		if (V4L2_TUNER_ANALOG_TV != f->type)
-			return -EINVAL;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
+	return 0;
+}
 
-		if (mxb->cur_input) {
-			DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
-			return -EINVAL;
-		}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-		mxb->cur_freq = *f;
-		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
+	return call_all(dev, core, g_register, reg);
+}
 
-		/* tune in desired frequency */
-		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
+static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-		/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
-		spin_lock(&dev->slock);
-		vv->vbi_fieldcount = 0;
-		spin_unlock(&dev->slock);
+	return call_all(dev, core, s_register, reg);
+}
+#endif
 
-		return 0;
-	}
+static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
+{
+	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+	switch (cmd) {
 	case MXB_S_AUDIO_CD:
 	{
-		int i = *(int*)arg;
+		int i = *(int *)arg;
 
 		if (i < 0 || i >= MXB_AUDIOS) {
-			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
+			DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
 			return -EINVAL;
 		}
 
-		DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
-
-		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
-		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
+		DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
 
+		tea6420_route_cd(mxb, i);
 		return 0;
 	}
 	case MXB_S_AUDIO_LINE:
 	{
-		int i = *(int*)arg;
+		int i = *(int *)arg;
 
 		if (i < 0 || i >= MXB_AUDIOS) {
-			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
+			DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
 			return -EINVAL;
 		}
 
-		DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
-		mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
-		mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
-
+		DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
+		tea6420_route_line(mxb, i);
 		return 0;
 	}
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
+	default:
+/*
+		DEB2(printk("does not handle this ioctl.\n"));
+*/
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
 
-		if (a->index < 0 || a->index > MXB_INPUTS) {
-			DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
-			return -EINVAL;
-		}
+static struct saa7146_ext_vv vv_data;
 
-		DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
-		memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+/* this function only gets called when the probing was successful */
+static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
 
-		return 0;
-	}
-	case VIDIOC_S_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
+	DEB_EE(("dev:%p\n", dev));
 
-		DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
-		return 0;
-	}
+	/* checking for i2c-devices can be omitted here, because we
+	   already did this in "mxb_vl42_probe" */
+
+	saa7146_vv_init(dev, &vv_data);
+	vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+	vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+	vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+	vv_data.ops.vidioc_g_input = vidioc_g_input;
+	vv_data.ops.vidioc_s_input = vidioc_s_input;
+	vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
+	vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
+	vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
+	vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
+	vv_data.ops.vidioc_g_audio = vidioc_g_audio;
+	vv_data.ops.vidioc_s_audio = vidioc_s_audio;
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	case VIDIOC_DBG_S_REGISTER:
-	case VIDIOC_DBG_G_REGISTER:
-		i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
-		return 0;
+	vv_data.ops.vidioc_g_register = vidioc_g_register;
+	vv_data.ops.vidioc_s_register = vidioc_s_register;
 #endif
-	default:
-/*
-		DEB2(printk("does not handle this ioctl.\n"));
-*/
-		return -ENOIOCTLCMD;
+	vv_data.ops.vidioc_default = vidioc_default;
+	if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+		ERR(("cannot register capture v4l2 device. skipping.\n"));
+		return -1;
 	}
+
+	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+	if (MXB_BOARD_CAN_DO_VBI(dev)) {
+		if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+			ERR(("cannot register vbi v4l2 device. skipping.\n"));
+		}
+	}
+
+	printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+
+	mxb_num++;
+	mxb_init_done(dev);
+	return 0;
+}
+
+static int mxb_detach(struct saa7146_dev *dev)
+{
+	struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+	DEB_EE(("dev:%p\n", dev));
+
+	saa7146_unregister_device(&mxb->video_dev,dev);
+	if (MXB_BOARD_CAN_DO_VBI(dev))
+		saa7146_unregister_device(&mxb->vbi_dev, dev);
+	saa7146_vv_release(dev);
+
+	mxb_num--;
+
+	i2c_del_adapter(&mxb->i2c_adapter);
+	kfree(mxb);
+
 	return 0;
 }
 
 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
 {
 	struct mxb *mxb = (struct mxb *)dev->ext_priv;
-	int zero = 0;
-	int one = 1;
 
 	if (V4L2_STD_PAL_I == standard->id) {
 		v4l2_std_id std = V4L2_STD_PAL_I;
@@ -821,8 +769,8 @@ static int std_callback(struct saa7146_d
 		/* set the 7146 gpio register -- I don't know what this does exactly */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		/* unset the 7111 gpio register -- I don't know what this does exactly */
-		mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
-		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+		saa7111a_call(mxb, core, s_gpio, 0);
+		tuner_call(mxb, core, s_std, std);
 	} else {
 		v4l2_std_id std = V4L2_STD_PAL_BG;
 
@@ -830,8 +778,8 @@ static int std_callback(struct saa7146_d
 		/* set the 7146 gpio register -- I don't know what this does exactly */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		/* set the 7111 gpio register -- I don't know what this does exactly */
-		mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
-		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+		saa7111a_call(mxb, core, s_gpio, 1);
+		tuner_call(mxb, core, s_std, std);
 	}
 	return 0;
 }
@@ -885,8 +833,6 @@ static struct saa7146_ext_vv vv_data = {
 	.stds		= &standard[0],
 	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
 	.std_callback	= &std_callback,
-	.ioctls		= &ioctls[0],
-	.ioctl		= mxb_ioctl,
 };
 
 static struct saa7146_extension extension = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/omap24xxcam.c linux-libre-2.6.30-gnu1/drivers/media/video/omap24xxcam.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/omap24xxcam.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/omap24xxcam.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,17 +80,17 @@ static int omap24xxcam_clock_get(struct
 {
 	int rval = 0;
 
-	cam->fck = clk_get(cam->dev, "cam_fck");
+	cam->fck = clk_get(cam->dev, "fck");
 	if (IS_ERR(cam->fck)) {
-		dev_err(cam->dev, "can't get cam_fck");
+		dev_err(cam->dev, "can't get camera fck");
 		rval = PTR_ERR(cam->fck);
 		omap24xxcam_clock_put(cam);
 		return rval;
 	}
 
-	cam->ick = clk_get(cam->dev, "cam_ick");
+	cam->ick = clk_get(cam->dev, "ick");
 	if (IS_ERR(cam->ick)) {
-		dev_err(cam->dev, "can't get cam_ick");
+		dev_err(cam->dev, "can't get camera ick");
 		rval = PTR_ERR(cam->ick);
 		omap24xxcam_clock_put(cam);
 	}
@@ -1285,9 +1285,6 @@ static int vidioc_g_parm(struct file *fi
 	struct omap24xxcam_device *cam = ofh->cam;
 	int rval;
 
-	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	mutex_lock(&cam->mutex);
 	rval = vidioc_int_g_parm(cam->sdev, a);
 	mutex_unlock(&cam->mutex);
@@ -1303,9 +1300,6 @@ static int vidioc_s_parm(struct file *fi
 	struct v4l2_streamparm old_streamparm;
 	int rval;
 
-	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	mutex_lock(&cam->mutex);
 	if (cam->streaming) {
 		rval = -EBUSY;
@@ -1665,7 +1659,6 @@ static int omap24xxcam_device_register(s
 	vfd->parent = cam->dev;
 
 	strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
-	vfd->vfl_type		 = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
 	vfd->fops		 = &omap24xxcam_fops;
 	vfd->minor		 = -1;
 	vfd->ioctl_ops		 = &omap24xxcam_ioctl_fops;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ov7670.c linux-libre-2.6.30-gnu1/drivers/media/video/ov7670.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ov7670.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ov7670.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,18 +12,22 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/i2c.h>
 #include <linux/delay.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
-#include <linux/i2c.h>
+#include <media/v4l2-i2c-drv.h>
 
 
 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
 MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
 MODULE_LICENSE("GPL");
 
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
 /*
  * Basic window sizes.  These probably belong somewhere more globally
  * useful.
@@ -189,11 +193,16 @@ MODULE_LICENSE("GPL");
  */
 struct ov7670_format_struct;  /* coming later */
 struct ov7670_info {
+	struct v4l2_subdev sd;
 	struct ov7670_format_struct *fmt;  /* Current format */
 	unsigned char sat;		/* Saturation value */
 	int hue;			/* Hue value */
 };
 
+static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ov7670_info, sd);
+}
 
 
 
@@ -400,24 +409,27 @@ static struct regval_list ov7670_fmt_raw
  * Low-level register I/O.
  */
 
-static int ov7670_read(struct i2c_client *c, unsigned char reg,
+static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
 		unsigned char *value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
 
-	ret = i2c_smbus_read_byte_data(c, reg);
+	ret = i2c_smbus_read_byte_data(client, reg);
 	if (ret >= 0) {
-		*value = (unsigned char) ret;
+		*value = (unsigned char)ret;
 		ret = 0;
 	}
 	return ret;
 }
 
 
-static int ov7670_write(struct i2c_client *c, unsigned char reg,
+static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
 		unsigned char value)
 {
-	int ret = i2c_smbus_write_byte_data(c, reg, value);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = i2c_smbus_write_byte_data(client, reg, value);
+
 	if (reg == REG_COM7 && (value & COM7_RESET))
 		msleep(2);  /* Wait for reset to run */
 	return ret;
@@ -427,10 +439,10 @@ static int ov7670_write(struct i2c_clien
 /*
  * Write a list of register settings; ff/ff stops the process.
  */
-static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
+static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals)
 {
 	while (vals->reg_num != 0xff || vals->value != 0xff) {
-		int ret = ov7670_write(c, vals->reg_num, vals->value);
+		int ret = ov7670_write(sd, vals->reg_num, vals->value);
 		if (ret < 0)
 			return ret;
 		vals++;
@@ -442,34 +454,35 @@ static int ov7670_write_array(struct i2c
 /*
  * Stuff that knows about the sensor.
  */
-static void ov7670_reset(struct i2c_client *client)
+static int ov7670_reset(struct v4l2_subdev *sd, u32 val)
 {
-	ov7670_write(client, REG_COM7, COM7_RESET);
+	ov7670_write(sd, REG_COM7, COM7_RESET);
 	msleep(1);
+	return 0;
 }
 
 
-static int ov7670_init(struct i2c_client *client)
+static int ov7670_init(struct v4l2_subdev *sd, u32 val)
 {
-	return ov7670_write_array(client, ov7670_default_regs);
+	return ov7670_write_array(sd, ov7670_default_regs);
 }
 
 
 
-static int ov7670_detect(struct i2c_client *client)
+static int ov7670_detect(struct v4l2_subdev *sd)
 {
 	unsigned char v;
 	int ret;
 
-	ret = ov7670_init(client);
+	ret = ov7670_init(sd, 0);
 	if (ret < 0)
 		return ret;
-	ret = ov7670_read(client, REG_MIDH, &v);
+	ret = ov7670_read(sd, REG_MIDH, &v);
 	if (ret < 0)
 		return ret;
 	if (v != 0x7f) /* OV manuf. id. */
 		return -ENODEV;
-	ret = ov7670_read(client, REG_MIDL, &v);
+	ret = ov7670_read(sd, REG_MIDL, &v);
 	if (ret < 0)
 		return ret;
 	if (v != 0xa2)
@@ -477,12 +490,12 @@ static int ov7670_detect(struct i2c_clie
 	/*
 	 * OK, we know we have an OmniVision chip...but which one?
 	 */
-	ret = ov7670_read(client, REG_PID, &v);
+	ret = ov7670_read(sd, REG_PID, &v);
 	if (ret < 0)
 		return ret;
 	if (v != 0x76)  /* PID + VER = 0x76 / 0x73 */
 		return -ENODEV;
-	ret = ov7670_read(client, REG_VER, &v);
+	ret = ov7670_read(sd, REG_VER, &v);
 	if (ret < 0)
 		return ret;
 	if (v != 0x73)  /* PID + VER = 0x76 / 0x73 */
@@ -627,7 +640,7 @@ static struct ov7670_win_size {
 /*
  * Store a set of start/stop values into the camera.
  */
-static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
+static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
 		int vstart, int vstop)
 {
 	int ret;
@@ -637,26 +650,26 @@ static int ov7670_set_hw(struct i2c_clie
  * hstart are in href[2:0], bottom 3 of hstop in href[5:3].  There is
  * a mystery "edge offset" value in the top two bits of href.
  */
-	ret =  ov7670_write(client, REG_HSTART, (hstart >> 3) & 0xff);
-	ret += ov7670_write(client, REG_HSTOP, (hstop >> 3) & 0xff);
-	ret += ov7670_read(client, REG_HREF, &v);
+	ret =  ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
+	ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
+	ret += ov7670_read(sd, REG_HREF, &v);
 	v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
 	msleep(10);
-	ret += ov7670_write(client, REG_HREF, v);
+	ret += ov7670_write(sd, REG_HREF, v);
 /*
  * Vertical: similar arrangement, but only 10 bits.
  */
-	ret += ov7670_write(client, REG_VSTART, (vstart >> 2) & 0xff);
-	ret += ov7670_write(client, REG_VSTOP, (vstop >> 2) & 0xff);
-	ret += ov7670_read(client, REG_VREF, &v);
+	ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
+	ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
+	ret += ov7670_read(sd, REG_VREF, &v);
 	v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
 	msleep(10);
-	ret += ov7670_write(client, REG_VREF, v);
+	ret += ov7670_write(sd, REG_VREF, v);
 	return ret;
 }
 
 
-static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
+static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
 {
 	struct ov7670_format_struct *ofmt;
 
@@ -671,7 +684,8 @@ static int ov7670_enum_fmt(struct i2c_cl
 }
 
 
-static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
+static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
+		struct v4l2_format *fmt,
 		struct ov7670_format_struct **ret_fmt,
 		struct ov7670_win_size **ret_wsize)
 {
@@ -715,18 +729,23 @@ static int ov7670_try_fmt(struct i2c_cli
 	return 0;
 }
 
+static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+	return ov7670_try_fmt_internal(sd, fmt, NULL, NULL);
+}
+
 /*
  * Set a format.
  */
-static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
+static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
 	int ret;
 	struct ov7670_format_struct *ovfmt;
 	struct ov7670_win_size *wsize;
-	struct ov7670_info *info = i2c_get_clientdata(c);
-	unsigned char com7, clkrc;
+	struct ov7670_info *info = to_state(sd);
+	unsigned char com7, clkrc = 0;
 
-	ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
+	ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
 	if (ret)
 		return ret;
 	/*
@@ -735,7 +754,7 @@ static int ov7670_s_fmt(struct i2c_clien
 	 * the colors.
 	 */
 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
-		ret = ov7670_read(c, REG_CLKRC, &clkrc);
+		ret = ov7670_read(sd, REG_CLKRC, &clkrc);
 		if (ret)
 			return ret;
 	}
@@ -747,20 +766,20 @@ static int ov7670_s_fmt(struct i2c_clien
 	 */
 	com7 = ovfmt->regs[0].value;
 	com7 |= wsize->com7_bit;
-	ov7670_write(c, REG_COM7, com7);
+	ov7670_write(sd, REG_COM7, com7);
 	/*
 	 * Now write the rest of the array.  Also store start/stops
 	 */
-	ov7670_write_array(c, ovfmt->regs + 1);
-	ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart,
+	ov7670_write_array(sd, ovfmt->regs + 1);
+	ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
 			wsize->vstop);
 	ret = 0;
 	if (wsize->regs)
-		ret = ov7670_write_array(c, wsize->regs);
+		ret = ov7670_write_array(sd, wsize->regs);
 	info->fmt = ovfmt;
 
 	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0)
-		ret = ov7670_write(c, REG_CLKRC, clkrc);
+		ret = ov7670_write(sd, REG_CLKRC, clkrc);
 	return ret;
 }
 
@@ -768,7 +787,7 @@ static int ov7670_s_fmt(struct i2c_clien
  * Implement G/S_PARM.  There is a "high quality" mode we could try
  * to do someday; for now, we just do the frame rate tweak.
  */
-static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
 {
 	struct v4l2_captureparm *cp = &parms->parm.capture;
 	unsigned char clkrc;
@@ -776,7 +795,7 @@ static int ov7670_g_parm(struct i2c_clie
 
 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	ret = ov7670_read(c, REG_CLKRC, &clkrc);
+	ret = ov7670_read(sd, REG_CLKRC, &clkrc);
 	if (ret < 0)
 		return ret;
 	memset(cp, 0, sizeof(struct v4l2_captureparm));
@@ -788,7 +807,7 @@ static int ov7670_g_parm(struct i2c_clie
 	return 0;
 }
 
-static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
 {
 	struct v4l2_captureparm *cp = &parms->parm.capture;
 	struct v4l2_fract *tpf = &cp->timeperframe;
@@ -802,7 +821,7 @@ static int ov7670_s_parm(struct i2c_clie
 	/*
 	 * CLKRC has a reserved bit, so let's preserve it.
 	 */
-	ret = ov7670_read(c, REG_CLKRC, &clkrc);
+	ret = ov7670_read(sd, REG_CLKRC, &clkrc);
 	if (ret < 0)
 		return ret;
 	if (tpf->numerator == 0 || tpf->denominator == 0)
@@ -816,7 +835,7 @@ static int ov7670_s_parm(struct i2c_clie
 	clkrc = (clkrc & 0x80) | div;
 	tpf->numerator = 1;
 	tpf->denominator = OV7670_FRAME_RATE/div;
-	return ov7670_write(c, REG_CLKRC, clkrc);
+	return ov7670_write(sd, REG_CLKRC, clkrc);
 }
 
 
@@ -829,7 +848,7 @@ static int ov7670_s_parm(struct i2c_clie
 
 
 
-static int ov7670_store_cmatrix(struct i2c_client *client,
+static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
 		int matrix[CMATRIX_LEN])
 {
 	int i, ret;
@@ -839,7 +858,7 @@ static int ov7670_store_cmatrix(struct i
 	 * Weird crap seems to exist in the upper part of
 	 * the sign bits register, so let's preserve it.
 	 */
-	ret = ov7670_read(client, REG_CMATRIX_SIGN, &signbits);
+	ret = ov7670_read(sd, REG_CMATRIX_SIGN, &signbits);
 	signbits &= 0xc0;
 
 	for (i = 0; i < CMATRIX_LEN; i++) {
@@ -858,9 +877,9 @@ static int ov7670_store_cmatrix(struct i
 			else
 				raw = matrix[i] & 0xff;
 		}
-		ret += ov7670_write(client, REG_CMATRIX_BASE + i, raw);
+		ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
 	}
-	ret += ov7670_write(client, REG_CMATRIX_SIGN, signbits);
+	ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
 	return ret;
 }
 
@@ -943,29 +962,29 @@ static void ov7670_calc_cmatrix(struct o
 
 
 
-static int ov7670_t_sat(struct i2c_client *client, int value)
+static int ov7670_s_sat(struct v4l2_subdev *sd, int value)
 {
-	struct ov7670_info *info = i2c_get_clientdata(client);
+	struct ov7670_info *info = to_state(sd);
 	int matrix[CMATRIX_LEN];
 	int ret;
 
 	info->sat = value;
 	ov7670_calc_cmatrix(info, matrix);
-	ret = ov7670_store_cmatrix(client, matrix);
+	ret = ov7670_store_cmatrix(sd, matrix);
 	return ret;
 }
 
-static int ov7670_q_sat(struct i2c_client *client, __s32 *value)
+static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value)
 {
-	struct ov7670_info *info = i2c_get_clientdata(client);
+	struct ov7670_info *info = to_state(sd);
 
 	*value = info->sat;
 	return 0;
 }
 
-static int ov7670_t_hue(struct i2c_client *client, int value)
+static int ov7670_s_hue(struct v4l2_subdev *sd, int value)
 {
-	struct ov7670_info *info = i2c_get_clientdata(client);
+	struct ov7670_info *info = to_state(sd);
 	int matrix[CMATRIX_LEN];
 	int ret;
 
@@ -973,14 +992,14 @@ static int ov7670_t_hue(struct i2c_clien
 		return -EINVAL;
 	info->hue = value;
 	ov7670_calc_cmatrix(info, matrix);
-	ret = ov7670_store_cmatrix(client, matrix);
+	ret = ov7670_store_cmatrix(sd, matrix);
 	return ret;
 }
 
 
-static int ov7670_q_hue(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value)
 {
-	struct ov7670_info *info = i2c_get_clientdata(client);
+	struct ov7670_info *info = to_state(sd);
 
 	*value = info->hue;
 	return 0;
@@ -994,8 +1013,7 @@ static unsigned char ov7670_sm_to_abs(un
 {
 	if ((v & 0x80) == 0)
 		return v + 128;
-	else
-		return 128 - (v & 0x7f);
+	return 128 - (v & 0x7f);
 }
 
 
@@ -1003,369 +1021,275 @@ static unsigned char ov7670_abs_to_sm(un
 {
 	if (v > 127)
 		return v & 0x7f;
-	else
-		return (128 - v) | 0x80;
+	return (128 - v) | 0x80;
 }
 
-static int ov7670_t_brightness(struct i2c_client *client, int value)
+static int ov7670_s_brightness(struct v4l2_subdev *sd, int value)
 {
 	unsigned char com8 = 0, v;
 	int ret;
 
-	ov7670_read(client, REG_COM8, &com8);
+	ov7670_read(sd, REG_COM8, &com8);
 	com8 &= ~COM8_AEC;
-	ov7670_write(client, REG_COM8, com8);
+	ov7670_write(sd, REG_COM8, com8);
 	v = ov7670_abs_to_sm(value);
-	ret = ov7670_write(client, REG_BRIGHT, v);
+	ret = ov7670_write(sd, REG_BRIGHT, v);
 	return ret;
 }
 
-static int ov7670_q_brightness(struct i2c_client *client, __s32 *value)
+static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value)
 {
 	unsigned char v = 0;
-	int ret = ov7670_read(client, REG_BRIGHT, &v);
+	int ret = ov7670_read(sd, REG_BRIGHT, &v);
 
 	*value = ov7670_sm_to_abs(v);
 	return ret;
 }
 
-static int ov7670_t_contrast(struct i2c_client *client, int value)
+static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
 {
-	return ov7670_write(client, REG_CONTRAS, (unsigned char) value);
+	return ov7670_write(sd, REG_CONTRAS, (unsigned char) value);
 }
 
-static int ov7670_q_contrast(struct i2c_client *client, __s32 *value)
+static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value)
 {
 	unsigned char v = 0;
-	int ret = ov7670_read(client, REG_CONTRAS, &v);
+	int ret = ov7670_read(sd, REG_CONTRAS, &v);
 
 	*value = v;
 	return ret;
 }
 
-static int ov7670_q_hflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value)
 {
 	int ret;
 	unsigned char v = 0;
 
-	ret = ov7670_read(client, REG_MVFP, &v);
+	ret = ov7670_read(sd, REG_MVFP, &v);
 	*value = (v & MVFP_MIRROR) == MVFP_MIRROR;
 	return ret;
 }
 
 
-static int ov7670_t_hflip(struct i2c_client *client, int value)
+static int ov7670_s_hflip(struct v4l2_subdev *sd, int value)
 {
 	unsigned char v = 0;
 	int ret;
 
-	ret = ov7670_read(client, REG_MVFP, &v);
+	ret = ov7670_read(sd, REG_MVFP, &v);
 	if (value)
 		v |= MVFP_MIRROR;
 	else
 		v &= ~MVFP_MIRROR;
 	msleep(10);  /* FIXME */
-	ret += ov7670_write(client, REG_MVFP, v);
+	ret += ov7670_write(sd, REG_MVFP, v);
 	return ret;
 }
 
 
 
-static int ov7670_q_vflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value)
 {
 	int ret;
 	unsigned char v = 0;
 
-	ret = ov7670_read(client, REG_MVFP, &v);
+	ret = ov7670_read(sd, REG_MVFP, &v);
 	*value = (v & MVFP_FLIP) == MVFP_FLIP;
 	return ret;
 }
 
 
-static int ov7670_t_vflip(struct i2c_client *client, int value)
+static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
 {
 	unsigned char v = 0;
 	int ret;
 
-	ret = ov7670_read(client, REG_MVFP, &v);
+	ret = ov7670_read(sd, REG_MVFP, &v);
 	if (value)
 		v |= MVFP_FLIP;
 	else
 		v &= ~MVFP_FLIP;
 	msleep(10);  /* FIXME */
-	ret += ov7670_write(client, REG_MVFP, v);
+	ret += ov7670_write(sd, REG_MVFP, v);
 	return ret;
 }
 
-
-static struct ov7670_control {
-	struct v4l2_queryctrl qc;
-	int (*query)(struct i2c_client *c, __s32 *value);
-	int (*tweak)(struct i2c_client *c, int value);
-} ov7670_controls[] =
+static int ov7670_queryctrl(struct v4l2_subdev *sd,
+		struct v4l2_queryctrl *qc)
 {
-	{
-		.qc = {
-			.id = V4L2_CID_BRIGHTNESS,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "Brightness",
-			.minimum = 0,
-			.maximum = 255,
-			.step = 1,
-			.default_value = 0x80,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-		.tweak = ov7670_t_brightness,
-		.query = ov7670_q_brightness,
-	},
-	{
-		.qc = {
-			.id = V4L2_CID_CONTRAST,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "Contrast",
-			.minimum = 0,
-			.maximum = 127,
-			.step = 1,
-			.default_value = 0x40,   /* XXX ov7670 spec */
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-		.tweak = ov7670_t_contrast,
-		.query = ov7670_q_contrast,
-	},
-	{
-		.qc = {
-			.id = V4L2_CID_SATURATION,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "Saturation",
-			.minimum = 0,
-			.maximum = 256,
-			.step = 1,
-			.default_value = 0x80,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-		.tweak = ov7670_t_sat,
-		.query = ov7670_q_sat,
-	},
-	{
-		.qc = {
-			.id = V4L2_CID_HUE,
-			.type = V4L2_CTRL_TYPE_INTEGER,
-			.name = "HUE",
-			.minimum = -180,
-			.maximum = 180,
-			.step = 5,
-			.default_value = 0,
-			.flags = V4L2_CTRL_FLAG_SLIDER
-		},
-		.tweak = ov7670_t_hue,
-		.query = ov7670_q_hue,
-	},
-	{
-		.qc = {
-			.id = V4L2_CID_VFLIP,
-			.type = V4L2_CTRL_TYPE_BOOLEAN,
-			.name = "Vertical flip",
-			.minimum = 0,
-			.maximum = 1,
-			.step = 1,
-			.default_value = 0,
-		},
-		.tweak = ov7670_t_vflip,
-		.query = ov7670_q_vflip,
-	},
-	{
-		.qc = {
-			.id = V4L2_CID_HFLIP,
-			.type = V4L2_CTRL_TYPE_BOOLEAN,
-			.name = "Horizontal mirror",
-			.minimum = 0,
-			.maximum = 1,
-			.step = 1,
-			.default_value = 0,
-		},
-		.tweak = ov7670_t_hflip,
-		.query = ov7670_q_hflip,
-	},
-};
-#define N_CONTROLS (ARRAY_SIZE(ov7670_controls))
+	/* Fill in min, max, step and default value for these controls. */
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+	case V4L2_CID_CONTRAST:
+		return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+	case V4L2_CID_VFLIP:
+	case V4L2_CID_HFLIP:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);
+	}
+	return -EINVAL;
+}
 
-static struct ov7670_control *ov7670_find_control(__u32 id)
+static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	int i;
-
-	for (i = 0; i < N_CONTROLS; i++)
-		if (ov7670_controls[i].qc.id == id)
-			return ov7670_controls + i;
-	return NULL;
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return ov7670_g_brightness(sd, &ctrl->value);
+	case V4L2_CID_CONTRAST:
+		return ov7670_g_contrast(sd, &ctrl->value);
+	case V4L2_CID_SATURATION:
+		return ov7670_g_sat(sd, &ctrl->value);
+	case V4L2_CID_HUE:
+		return ov7670_g_hue(sd, &ctrl->value);
+	case V4L2_CID_VFLIP:
+		return ov7670_g_vflip(sd, &ctrl->value);
+	case V4L2_CID_HFLIP:
+		return ov7670_g_hflip(sd, &ctrl->value);
+	}
+	return -EINVAL;
 }
 
+static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return ov7670_s_brightness(sd, ctrl->value);
+	case V4L2_CID_CONTRAST:
+		return ov7670_s_contrast(sd, ctrl->value);
+	case V4L2_CID_SATURATION:
+		return ov7670_s_sat(sd, ctrl->value);
+	case V4L2_CID_HUE:
+		return ov7670_s_hue(sd, ctrl->value);
+	case V4L2_CID_VFLIP:
+		return ov7670_s_vflip(sd, ctrl->value);
+	case V4L2_CID_HFLIP:
+		return ov7670_s_hflip(sd, ctrl->value);
+	}
+	return -EINVAL;
+}
 
-static int ov7670_queryctrl(struct i2c_client *client,
-		struct v4l2_queryctrl *qc)
+static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
+		struct v4l2_dbg_chip_ident *chip)
 {
-	struct ov7670_control *ctrl = ov7670_find_control(qc->id);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (ctrl == NULL)
-		return -EINVAL;
-	*qc = ctrl->qc;
-	return 0;
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
 }
 
-static int ov7670_g_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	unsigned char val = 0;
 	int ret;
 
-	if (octrl == NULL)
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
 		return -EINVAL;
-	ret = octrl->query(client, &ctrl->value);
-	if (ret >= 0)
-		return 0;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	ret = ov7670_read(sd, reg->reg & 0xff, &val);
+	reg->val = val;
+	reg->size = 1;
 	return ret;
 }
 
-static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
-	int ret;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (octrl == NULL)
+	if (!v4l2_chip_match_i2c_client(client, &reg->match))
 		return -EINVAL;
-	ret =  octrl->tweak(client, ctrl->value);
-	if (ret >= 0)
-		return 0;
-	return ret;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
+	return 0;
 }
+#endif
 
+/* ----------------------------------------------------------------------- */
 
+static const struct v4l2_subdev_core_ops ov7670_core_ops = {
+	.g_chip_ident = ov7670_g_chip_ident,
+	.g_ctrl = ov7670_g_ctrl,
+	.s_ctrl = ov7670_s_ctrl,
+	.queryctrl = ov7670_queryctrl,
+	.reset = ov7670_reset,
+	.init = ov7670_init,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ov7670_g_register,
+	.s_register = ov7670_s_register,
+#endif
+};
 
+static const struct v4l2_subdev_video_ops ov7670_video_ops = {
+	.enum_fmt = ov7670_enum_fmt,
+	.try_fmt = ov7670_try_fmt,
+	.s_fmt = ov7670_s_fmt,
+	.s_parm = ov7670_s_parm,
+	.g_parm = ov7670_g_parm,
+};
 
+static const struct v4l2_subdev_ops ov7670_ops = {
+	.core = &ov7670_core_ops,
+	.video = &ov7670_video_ops,
+};
 
+/* ----------------------------------------------------------------------- */
 
-/*
- * Basic i2c stuff.
- */
-static struct i2c_driver ov7670_driver;
-
-static int ov7670_attach(struct i2c_adapter *adapter)
+static int ov7670_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	int ret;
-	struct i2c_client *client;
+	struct v4l2_subdev *sd;
 	struct ov7670_info *info;
+	int ret;
 
-	/*
-	 * For now: only deal with adapters we recognize.
-	 */
-	if (adapter->id != I2C_HW_SMBUS_CAFE)
-		return -ENODEV;
-
-	client = kzalloc(sizeof (struct i2c_client), GFP_KERNEL);
-	if (! client)
+	info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+	if (info == NULL)
 		return -ENOMEM;
-	client->adapter = adapter;
-	client->addr = OV7670_I2C_ADDR;
-	client->driver = &ov7670_driver,
-	strcpy(client->name, "OV7670");
-	/*
-	 * Set up our info structure.
-	 */
-	info = kzalloc(sizeof (struct ov7670_info), GFP_KERNEL);
-	if (! info) {
-		ret = -ENOMEM;
-		goto out_free;
+	sd = &info->sd;
+	v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
+
+	/* Make sure it's an ov7670 */
+	ret = ov7670_detect(sd);
+	if (ret) {
+		v4l_dbg(1, debug, client,
+			"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
+			client->addr << 1, client->adapter->name);
+		kfree(info);
+		return ret;
 	}
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
 	info->fmt = &ov7670_formats[0];
 	info->sat = 128;	/* Review this */
-	i2c_set_clientdata(client, info);
-
-	/*
-	 * Make sure it's an ov7670
-	 */
-	ret = ov7670_detect(client);
-	if (ret)
-		goto out_free_info;
-	ret = i2c_attach_client(client);
-	if (ret)
-		goto out_free_info;
-	return 0;
 
-  out_free_info:
-	kfree(info);
-  out_free:
-	kfree(client);
-	return ret;
-}
-
-
-static int ov7670_detach(struct i2c_client *client)
-{
-	i2c_detach_client(client);
-	kfree(i2c_get_clientdata(client));
-	kfree(client);
 	return 0;
 }
 
 
-static int ov7670_command(struct i2c_client *client, unsigned int cmd,
-		void *arg)
+static int ov7670_remove(struct i2c_client *client)
 {
-	switch (cmd) {
-	case VIDIOC_DBG_G_CHIP_IDENT:
-		return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0);
-
-	case VIDIOC_INT_RESET:
-		ov7670_reset(client);
-		return 0;
-
-	case VIDIOC_INT_INIT:
-		return ov7670_init(client);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-	case VIDIOC_ENUM_FMT:
-		return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg);
-	case VIDIOC_TRY_FMT:
-		return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
-	case VIDIOC_S_FMT:
-		return ov7670_s_fmt(client, (struct v4l2_format *) arg);
-	case VIDIOC_QUERYCTRL:
-		return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
-	case VIDIOC_S_CTRL:
-		return ov7670_s_ctrl(client, (struct v4l2_control *) arg);
-	case VIDIOC_G_CTRL:
-		return ov7670_g_ctrl(client, (struct v4l2_control *) arg);
-	case VIDIOC_S_PARM:
-		return ov7670_s_parm(client, (struct v4l2_streamparm *) arg);
-	case VIDIOC_G_PARM:
-		return ov7670_g_parm(client, (struct v4l2_streamparm *) arg);
-	}
-	return -EINVAL;
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+	return 0;
 }
 
-
-
-static struct i2c_driver ov7670_driver = {
-	.driver = {
-		.name = "ov7670",
-	},
-	.id 		= I2C_DRIVERID_OV7670,
-	.attach_adapter = ov7670_attach,
-	.detach_client	= ov7670_detach,
-	.command	= ov7670_command,
+static const struct i2c_device_id ov7670_id[] = {
+	{ "ov7670", 0 },
+	{ }
 };
+MODULE_DEVICE_TABLE(i2c, ov7670_id);
 
-
-/*
- * Module initialization
- */
-static int __init ov7670_mod_init(void)
-{
-	printk(KERN_NOTICE "OmniVision ov7670 sensor driver, at your service\n");
-	return i2c_add_driver(&ov7670_driver);
-}
-
-static void __exit ov7670_mod_exit(void)
-{
-	i2c_del_driver(&ov7670_driver);
-}
-
-module_init(ov7670_mod_init);
-module_exit(ov7670_mod_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "ov7670",
+	.probe = ov7670_probe,
+	.remove = ov7670_remove,
+	.id_table = ov7670_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ov772x.c linux-libre-2.6.30-gnu1/drivers/media/video/ov772x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ov772x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ov772x.c	2009-06-09 23:05:27.000000000 -0400
@@ -169,11 +169,11 @@
 #define GAM15       0x8C /* Gamma Curve 15th segment input end point */
 #define SLOP        0x8D /* Gamma curve highest segment slope */
 #define DNSTH       0x8E /* De-noise threshold */
-#define EDGE0       0x8F /* Edge enhancement control 0 */
-#define EDGE1       0x90 /* Edge enhancement control 1 */
+#define EDGE_STRNGT 0x8F /* Edge strength  control when manual mode */
+#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
 #define DNSOFF      0x91 /* Auto De-noise threshold control */
-#define EDGE2       0x92 /* Edge enhancement strength low  point control */
-#define EDGE3       0x93 /* Edge enhancement strength high point control */
+#define EDGE_UPPER  0x92 /* Edge strength upper limit when Auto mode */
+#define EDGE_LOWER  0x93 /* Edge strength lower limit when Auto mode */
 #define MTX1        0x94 /* Matrix coefficient 1 */
 #define MTX2        0x95 /* Matrix coefficient 2 */
 #define MTX3        0x96 /* Matrix coefficient 3 */
@@ -217,10 +217,11 @@
 #define OCAP_4x         0x03	/* 4x */
 
 /* COM3 */
-#define SWAP_MASK       0x38
+#define SWAP_MASK       (SWAP_RGB | SWAP_YUV | SWAP_ML)
+#define IMG_MASK        (VFLIP_IMG | HFLIP_IMG)
 
-#define VFIMG_ON_OFF    0x80	/* Vertical flip image ON/OFF selection */
-#define HMIMG_ON_OFF    0x40	/* Horizontal mirror image ON/OFF selection */
+#define VFLIP_IMG       0x80	/* Vertical flip image ON/OFF selection */
+#define HFLIP_IMG       0x40	/* Horizontal mirror image ON/OFF selection */
 #define SWAP_RGB        0x20	/* Swap B/R  output sequence in RGB mode */
 #define SWAP_YUV        0x10	/* Swap Y/UV output sequence in YUV mode */
 #define SWAP_ML         0x08	/* Swap output MSB/LSB */
@@ -271,11 +272,13 @@
 #define SLCT_QVGA       0x40	/*   1 : QVGA */
 #define ITU656_ON_OFF   0x20	/* ITU656 protocol ON/OFF selection */
 				/* RGB output format control */
+#define FMT_MASK        0x0c	/*      Mask of color format */
 #define FMT_GBR422      0x00	/*      00 : GBR 4:2:2 */
 #define FMT_RGB565      0x04	/*      01 : RGB 565 */
 #define FMT_RGB555      0x08	/*      10 : RGB 555 */
 #define FMT_RGB444      0x0c	/* 11 : RGB 444 */
 				/* Output format control */
+#define OFMT_MASK       0x03    /*      Mask of output format */
 #define OFMT_YUV        0x00	/*      00 : YUV */
 #define OFMT_P_BRAW     0x01	/*      01 : Processed Bayer RAW */
 #define OFMT_RGB        0x02	/*      10 : RGB */
@@ -299,7 +302,7 @@
 #define GAIN_2x         0x00	/*    000 :   2x */
 #define GAIN_4x         0x10	/*    001 :   4x */
 #define GAIN_8x         0x20	/*    010 :   8x */
-#define GAIN_16x        0x30	/* 011 :  16x */
+#define GAIN_16x        0x30	/*    011 :  16x */
 #define GAIN_32x        0x40	/*    100 :  32x */
 #define GAIN_64x        0x50	/* 101 :  64x */
 #define GAIN_128x       0x60	/* 110 : 128x */
@@ -355,12 +358,13 @@
 #define VOSZ_VGA        0xF0
 #define VOSZ_QVGA       0x78
 
-/*
- * bit configure (32 bit)
- * this is used in struct ov772x_color_format :: option
- */
-#define OP_UV       0x00000001
-#define OP_SWAP_RGB 0x00000002
+/* DSPAUTO (DSP Auto Function ON/OFF Control) */
+#define AWB_ACTRL       0x80 /* AWB auto threshold control */
+#define DENOISE_ACTRL   0x40 /* De-noise auto threshold control */
+#define EDGE_ACTRL      0x20 /* Edge enhancement auto strength control */
+#define UV_ACTRL        0x10 /* UV adjust auto slope control */
+#define SCAL0_ACTRL     0x08 /* Auto scaling factor control */
+#define SCAL1_2_ACTRL   0x04 /* Auto scaling factor control */
 
 /*
  * ID
@@ -380,8 +384,9 @@ struct regval_list {
 struct ov772x_color_format {
 	char                     *name;
 	__u32                     fourcc;
-	const struct regval_list *regs;
-	unsigned int              option;
+	u8                        dsp3;
+	u8                        com3;
+	u8                        com7;
 };
 
 struct ov772x_win_size {
@@ -399,39 +404,13 @@ struct ov772x_priv {
 	const struct ov772x_color_format *fmt;
 	const struct ov772x_win_size     *win;
 	int                               model;
+	unsigned int                      flag_vflip:1;
+	unsigned int                      flag_hflip:1;
 };
 
 #define ENDMARKER { 0xff, 0xff }
 
 /*
- * register setting for color format
- */
-static const struct regval_list ov772x_RGB555_regs[] = {
-	{ COM3, 0x00 },
-	{ COM7, FMT_RGB555 | OFMT_RGB },
-	ENDMARKER,
-};
-
-static const struct regval_list ov772x_RGB565_regs[] = {
-	{ COM3, 0x00 },
-	{ COM7, FMT_RGB565 | OFMT_RGB },
-	ENDMARKER,
-};
-
-static const struct regval_list ov772x_YYUV_regs[] = {
-	{ COM3, SWAP_YUV },
-	{ COM7, OFMT_YUV },
-	ENDMARKER,
-};
-
-static const struct regval_list ov772x_UVYY_regs[] = {
-	{ COM3, 0x00 },
-	{ COM7, OFMT_YUV },
-	ENDMARKER,
-};
-
-
-/*
  * register setting for window size
  */
 static const struct regval_list ov772x_qvga_regs[] = {
@@ -500,38 +479,48 @@ static const struct soc_camera_data_form
 /*
  * color format list
  */
-#define T_YUYV 0
 static const struct ov772x_color_format ov772x_cfmts[] = {
-	[T_YUYV] = {
+	{
 		SETFOURCC(YUYV),
-		.regs   = ov772x_YYUV_regs,
+		.dsp3   = 0x0,
+		.com3   = SWAP_YUV,
+		.com7   = OFMT_YUV,
 	},
 	{
 		SETFOURCC(YVYU),
-		.regs   = ov772x_YYUV_regs,
-		.option = OP_UV,
+		.dsp3   = UV_ON,
+		.com3   = SWAP_YUV,
+		.com7   = OFMT_YUV,
 	},
 	{
 		SETFOURCC(UYVY),
-		.regs   = ov772x_UVYY_regs,
+		.dsp3   = 0x0,
+		.com3   = 0x0,
+		.com7   = OFMT_YUV,
 	},
 	{
 		SETFOURCC(RGB555),
-		.regs   = ov772x_RGB555_regs,
-		.option = OP_SWAP_RGB,
+		.dsp3   = 0x0,
+		.com3   = SWAP_RGB,
+		.com7   = FMT_RGB555 | OFMT_RGB,
 	},
 	{
 		SETFOURCC(RGB555X),
-		.regs   = ov772x_RGB555_regs,
+		.dsp3   = 0x0,
+		.com3   = 0x0,
+		.com7   = FMT_RGB555 | OFMT_RGB,
 	},
 	{
 		SETFOURCC(RGB565),
-		.regs   = ov772x_RGB565_regs,
-		.option = OP_SWAP_RGB,
+		.dsp3   = 0x0,
+		.com3   = SWAP_RGB,
+		.com7   = FMT_RGB565 | OFMT_RGB,
 	},
 	{
 		SETFOURCC(RGB565X),
-		.regs   = ov772x_RGB565_regs,
+		.dsp3   = 0x0,
+		.com3   = 0x0,
+		.com7   = FMT_RGB565 | OFMT_RGB,
 	},
 };
 
@@ -562,6 +551,27 @@ static const struct ov772x_win_size ov77
 	.regs     = ov772x_qvga_regs,
 };
 
+static const struct v4l2_queryctrl ov772x_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,
+	},
+};
+
 
 /*
  * general function
@@ -587,8 +597,11 @@ static int ov772x_mask_set(struct i2c_cl
 					  u8  set)
 {
 	s32 val = i2c_smbus_read_byte_data(client, command);
+	if (val < 0)
+		return val;
+
 	val &= ~mask;
-	val |=  set;
+	val |= set & mask;
 
 	return i2c_smbus_write_byte_data(client, command, val);
 }
@@ -635,74 +648,24 @@ static int ov772x_release(struct soc_cam
 static int ov772x_start_capture(struct soc_camera_device *icd)
 {
 	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	int                 ret;
-
-	if (!priv->win)
-		priv->win = &ov772x_win_vga;
-	if (!priv->fmt)
-		priv->fmt = &ov772x_cfmts[T_YUYV];
-
-	/*
-	 * reset hardware
-	 */
-	ov772x_reset(priv->client);
-
-	/*
-	 * set color format
-	 */
-	ret = ov772x_write_array(priv->client, priv->fmt->regs);
-	if (ret < 0)
-		goto start_end;
-
-	/*
-	 * set size format
-	 */
-	ret = ov772x_write_array(priv->client, priv->win->regs);
-	if (ret < 0)
-		goto start_end;
-
-	/*
-	 * set COM7 bit ( QVGA or VGA )
-	 */
-	ret = ov772x_mask_set(priv->client,
-			      COM7, SLCT_MASK, priv->win->com7_bit);
-	if (ret < 0)
-		goto start_end;
 
-	/*
-	 * set UV setting
-	 */
-	if (priv->fmt->option & OP_UV) {
-		ret = ov772x_mask_set(priv->client,
-				      DSP_CTRL3, UV_MASK, UV_ON);
-		if (ret < 0)
-			goto start_end;
+	if (!priv->win || !priv->fmt) {
+		dev_err(&icd->dev, "norm or win select error\n");
+		return -EPERM;
 	}
 
-	/*
-	 * set SWAP setting
-	 */
-	if (priv->fmt->option & OP_SWAP_RGB) {
-		ret = ov772x_mask_set(priv->client,
-				      COM3, SWAP_MASK, SWAP_RGB);
-		if (ret < 0)
-			goto start_end;
-	}
+	ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0);
 
 	dev_dbg(&icd->dev,
 		 "format %s, win %s\n", priv->fmt->name, priv->win->name);
 
-start_end:
-	priv->fmt = NULL;
-	priv->win = NULL;
-
-	return ret;
+	return 0;
 }
 
 static int ov772x_stop_capture(struct soc_camera_device *icd)
 {
 	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	ov772x_reset(priv->client);
+	ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
 	return 0;
 }
 
@@ -715,14 +678,57 @@ static int ov772x_set_bus_param(struct s
 static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
 {
 	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	struct soc_camera_link *icl = priv->client->dev.platform_data;
+	struct soc_camera_link *icl = &priv->info->link;
 	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-		priv->info->buswidth;
+		SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
 
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
+static int ov772x_get_control(struct soc_camera_device *icd,
+			      struct v4l2_control *ctrl)
+{
+	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+	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;
+}
+
+static int ov772x_set_control(struct soc_camera_device *icd,
+			      struct v4l2_control *ctrl)
+{
+	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	int ret = 0;
+	u8 val;
+
+	switch (ctrl->id) {
+	case V4L2_CID_VFLIP:
+		val = ctrl->value ? VFLIP_IMG : 0x00;
+		priv->flag_vflip = ctrl->value;
+		if (priv->info->flags & OV772X_FLAG_VFLIP)
+			val ^= VFLIP_IMG;
+		ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val);
+		break;
+	case V4L2_CID_HFLIP:
+		val = ctrl->value ? HFLIP_IMG : 0x00;
+		priv->flag_hflip = ctrl->value;
+		if (priv->info->flags & OV772X_FLAG_HFLIP)
+			val ^= HFLIP_IMG;
+		ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val);
+		break;
+	}
+
+	return ret;
+}
+
 static int ov772x_get_chip_id(struct soc_camera_device *icd,
 			      struct v4l2_dbg_chip_ident   *id)
 {
@@ -787,13 +793,11 @@ ov772x_select_win(u32 width, u32 height)
 	return win;
 }
 
-
-static int ov772x_set_fmt(struct soc_camera_device *icd,
-			  __u32                     pixfmt,
-			  struct v4l2_rect         *rect)
+static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
+			     u32 pixfmt)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
 	int ret = -EINVAL;
+	u8  val;
 	int i;
 
 	/*
@@ -803,19 +807,148 @@ static int ov772x_set_fmt(struct soc_cam
 	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
 		if (pixfmt == ov772x_cfmts[i].fourcc) {
 			priv->fmt = ov772x_cfmts + i;
-			ret = 0;
 			break;
 		}
 	}
+	if (!priv->fmt)
+		goto ov772x_set_fmt_error;
 
 	/*
 	 * select win
 	 */
-	priv->win = ov772x_select_win(rect->width, rect->height);
+	priv->win = ov772x_select_win(width, height);
+
+	/*
+	 * reset hardware
+	 */
+	ov772x_reset(priv->client);
+
+	/*
+	 * Edge Ctrl
+	 */
+	if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
+
+		/*
+		 * Manual Edge Control Mode
+		 *
+		 * Edge auto strength bit is set by default.
+		 * Remove it when manual mode.
+		 */
+
+		ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
+				      priv->info->edgectrl.threshold);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_STRNGT, EDGE_STRENGTH_MASK,
+				      priv->info->edgectrl.strength);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+	} else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
+		/*
+		 * Auto Edge Control Mode
+		 *
+		 * set upper and lower limit
+		 */
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_UPPER, EDGE_UPPER_MASK,
+				      priv->info->edgectrl.upper);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+
+		ret = ov772x_mask_set(priv->client,
+				      EDGE_LOWER, EDGE_LOWER_MASK,
+				      priv->info->edgectrl.lower);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	/*
+	 * set size format
+	 */
+	ret = ov772x_write_array(priv->client, priv->win->regs);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	/*
+	 * set DSP_CTRL3
+	 */
+	val = priv->fmt->dsp3;
+	if (val) {
+		ret = ov772x_mask_set(priv->client,
+				      DSP_CTRL3, UV_MASK, val);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	/*
+	 * set COM3
+	 */
+	val = priv->fmt->com3;
+	if (priv->info->flags & OV772X_FLAG_VFLIP)
+		val |= VFLIP_IMG;
+	if (priv->info->flags & OV772X_FLAG_HFLIP)
+		val |= HFLIP_IMG;
+	if (priv->flag_vflip)
+		val ^= VFLIP_IMG;
+	if (priv->flag_hflip)
+		val ^= HFLIP_IMG;
+
+	ret = ov772x_mask_set(priv->client,
+			      COM3, SWAP_MASK | IMG_MASK, val);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	/*
+	 * set COM7
+	 */
+	val = priv->win->com7_bit | priv->fmt->com7;
+	ret = ov772x_mask_set(priv->client,
+			      COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
+			      val);
+	if (ret < 0)
+		goto ov772x_set_fmt_error;
+
+	return ret;
+
+ov772x_set_fmt_error:
+
+	ov772x_reset(priv->client);
+	priv->win = NULL;
+	priv->fmt = NULL;
 
 	return ret;
 }
 
+static int ov772x_set_crop(struct soc_camera_device *icd,
+			   struct v4l2_rect *rect)
+{
+	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+	if (!priv->fmt)
+		return -EINVAL;
+
+	return ov772x_set_params(priv, rect->width, rect->height,
+				 priv->fmt->fourcc);
+}
+
+static int ov772x_set_fmt(struct soc_camera_device *icd,
+			  struct v4l2_format *f)
+{
+	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	return ov772x_set_params(priv, pix->width, pix->height,
+				 pix->pixelformat);
+}
+
 static int ov772x_try_fmt(struct soc_camera_device *icd,
 			  struct v4l2_format       *f)
 {
@@ -889,7 +1022,6 @@ static int ov772x_video_probe(struct soc
 		 i2c_smbus_read_byte_data(priv->client, MIDH),
 		 i2c_smbus_read_byte_data(priv->client, MIDL));
 
-
 	return soc_camera_video_start(icd);
 }
 
@@ -906,10 +1038,15 @@ static struct soc_camera_ops ov772x_ops
 	.release		= ov772x_release,
 	.start_capture		= ov772x_start_capture,
 	.stop_capture		= ov772x_stop_capture,
+	.set_crop		= ov772x_set_crop,
 	.set_fmt		= ov772x_set_fmt,
 	.try_fmt		= ov772x_try_fmt,
 	.set_bus_param		= ov772x_set_bus_param,
 	.query_bus_param	= ov772x_query_bus_param,
+	.controls		= ov772x_controls,
+	.num_controls		= ARRAY_SIZE(ov772x_controls),
+	.get_control		= ov772x_get_control,
+	.set_control		= ov772x_set_control,
 	.get_chip_id		= ov772x_get_chip_id,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.get_register		= ov772x_get_register,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ovcamchip/ovcamchip_core.c linux-libre-2.6.30-gnu1/drivers/media/video/ovcamchip/ovcamchip_core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/ovcamchip/ovcamchip_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ovcamchip/ovcamchip_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,9 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-i2c-drv.h>
 #include "ovcamchip_priv.h"
 
 #define DRIVER_VERSION "v2.27 for Linux 2.6"
@@ -44,6 +47,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
+
 /* Registers common to all chips, that are needed for detection */
 #define GENERIC_REG_ID_HIGH       0x1C	/* manufacturer ID MSB */
 #define GENERIC_REG_ID_LOW        0x1D	/* manufacturer ID LSB */
@@ -61,10 +65,6 @@ static char *chip_names[NUM_CC_TYPES] =
 	[CC_OV6630AF]	= "OV6630AF",
 };
 
-/* Forward declarations */
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
 /* ----------------------------------------------------------------------- */
 
 int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
@@ -253,112 +253,36 @@ static int ovcamchip_detect(struct i2c_c
 
 	/* Test for 7xx0 */
 	PDEBUG(3, "Testing for 0V7xx0");
-	c->addr = OV7xx0_SID;
-	if (init_camchip(c) < 0) {
-		/* Test for 6xx0 */
-		PDEBUG(3, "Testing for 0V6xx0");
-		c->addr = OV6xx0_SID;
-		if (init_camchip(c) < 0) {
-			return -ENODEV;
-		} else {
-			if (ov6xx0_detect(c) < 0) {
-				PERROR("Failed to init OV6xx0");
-				return -EIO;
-			}
-		}
-	} else {
+	if (init_camchip(c) < 0)
+		return -ENODEV;
+	/* 7-bit addresses with bit 0 set are for the OV7xx0 */
+	if (c->addr & 1) {
 		if (ov7xx0_detect(c) < 0) {
 			PERROR("Failed to init OV7xx0");
 			return -EIO;
 		}
+		return 0;
+	}
+	/* Test for 6xx0 */
+	PDEBUG(3, "Testing for 0V6xx0");
+	if (ov6xx0_detect(c) < 0) {
+		PERROR("Failed to init OV6xx0");
+		return -EIO;
 	}
-
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static int ovcamchip_attach(struct i2c_adapter *adap)
-{
-	int rc = 0;
-	struct ovcamchip *ov;
-	struct i2c_client *c;
-
-	/* I2C is not a PnP bus, so we can never be certain that we're talking
-	 * to the right chip. To prevent damage to EEPROMS and such, only
-	 * attach to adapters that are known to contain OV camera chips. */
-
-	switch (adap->id) {
-	case I2C_HW_SMBUS_OV511:
-	case I2C_HW_SMBUS_OV518:
-	case I2C_HW_SMBUS_W9968CF:
-		PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
-		break;
-	default:
-		PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id);
-		return -ENODEV;
-	}
-
-	c = kmalloc(sizeof *c, GFP_KERNEL);
-	if (!c) {
-		rc = -ENOMEM;
-		goto no_client;
-	}
-	memcpy(c, &client_template, sizeof *c);
-	c->adapter = adap;
-	strcpy(c->name, "OV????");
-
-	ov = kzalloc(sizeof *ov, GFP_KERNEL);
-	if (!ov) {
-		rc = -ENOMEM;
-		goto no_ov;
-	}
-	i2c_set_clientdata(c, ov);
-
-	rc = ovcamchip_detect(c);
-	if (rc < 0)
-		goto error;
-
-	strcpy(c->name, chip_names[ov->subtype]);
-
-	PDEBUG(1, "Camera chip detection complete");
-
-	i2c_attach_client(c);
-
-	return rc;
-error:
-	kfree(ov);
-no_ov:
-	kfree(c);
-no_client:
-	PDEBUG(1, "returning %d", rc);
-	return rc;
-}
-
-static int ovcamchip_detach(struct i2c_client *c)
-{
-	struct ovcamchip *ov = i2c_get_clientdata(c);
-	int rc;
-
-	rc = ov->sops->free(c);
-	if (rc < 0)
-		return rc;
-
-	i2c_detach_client(c);
-
-	kfree(ov);
-	kfree(c);
-	return 0;
-}
-
-static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
+static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
-	struct ovcamchip *ov = i2c_get_clientdata(c);
+	struct ovcamchip *ov = to_ovcamchip(sd);
+	struct i2c_client *c = v4l2_get_subdevdata(sd);
 
 	if (!ov->initialized &&
 	    cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
 	    cmd != OVCAMCHIP_CMD_INITIALIZE) {
-		dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n");
+		v4l2_err(sd, "Camera chip not initialized yet!\n");
 		return -EPERM;
 	}
 
@@ -379,10 +303,10 @@ static int ovcamchip_command(struct i2c_
 
 		if (ov->mono) {
 			if (ov->subtype != CC_OV7620)
-				dev_warn(&c->dev, "Warning: Monochrome not "
+				v4l2_warn(sd, "Monochrome not "
 					"implemented for this chip\n");
 			else
-				dev_info(&c->dev, "Initializing chip as "
+				v4l2_info(sd, "Initializing chip as "
 					"monochrome\n");
 		}
 
@@ -400,35 +324,72 @@ static int ovcamchip_command(struct i2c_
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver driver = {
-	.driver = {
-		.name =		"ovcamchip",
-	},
-	.id =			I2C_DRIVERID_OVCAMCHIP,
-	.attach_adapter =	ovcamchip_attach,
-	.detach_client =	ovcamchip_detach,
-	.command =		ovcamchip_command,
+static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
+	.ioctl = ovcamchip_ioctl,
 };
 
-static struct i2c_client client_template = {
-	.name =		"(unset)",
-	.driver =	&driver,
+static const struct v4l2_subdev_ops ovcamchip_ops = {
+	.core = &ovcamchip_core_ops,
 };
 
-static int __init ovcamchip_init(void)
+static int ovcamchip_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-#ifdef DEBUG
-	ovcamchip_debug = debug;
-#endif
+	struct ovcamchip *ov;
+	struct v4l2_subdev *sd;
+	int rc = 0;
 
-	PINFO(DRIVER_VERSION " : " DRIVER_DESC);
-	return i2c_add_driver(&driver);
+	ov = kzalloc(sizeof *ov, GFP_KERNEL);
+	if (!ov) {
+		rc = -ENOMEM;
+		goto no_ov;
+	}
+	sd = &ov->sd;
+	v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);
+
+	rc = ovcamchip_detect(client);
+	if (rc < 0)
+		goto error;
+
+	v4l_info(client, "%s found @ 0x%02x (%s)\n",
+			chip_names[ov->subtype], client->addr << 1, client->adapter->name);
+
+	PDEBUG(1, "Camera chip detection complete");
+
+	return rc;
+error:
+	kfree(ov);
+no_ov:
+	PDEBUG(1, "returning %d", rc);
+	return rc;
 }
 
-static void __exit ovcamchip_exit(void)
+static int ovcamchip_remove(struct i2c_client *client)
 {
-	i2c_del_driver(&driver);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ovcamchip *ov = to_ovcamchip(sd);
+	int rc;
+
+	v4l2_device_unregister_subdev(sd);
+	rc = ov->sops->free(client);
+	if (rc < 0)
+		return rc;
+
+	kfree(ov);
+	return 0;
 }
 
-module_init(ovcamchip_init);
-module_exit(ovcamchip_exit);
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id ovcamchip_id[] = {
+	{ "ovcamchip", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "ovcamchip",
+	.probe = ovcamchip_probe,
+	.remove = ovcamchip_remove,
+	.id_table = ovcamchip_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/ovcamchip/ovcamchip_priv.h linux-libre-2.6.30-gnu1/drivers/media/video/ovcamchip/ovcamchip_priv.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/ovcamchip/ovcamchip_priv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/ovcamchip/ovcamchip_priv.h	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
 #define __LINUX_OVCAMCHIP_PRIV_H
 
 #include <linux/i2c.h>
+#include <media/v4l2-subdev.h>
 #include <media/ovcamchip.h>
 
 #ifdef DEBUG
@@ -46,6 +47,7 @@ struct ovcamchip_ops {
 };
 
 struct ovcamchip {
+	struct v4l2_subdev sd;
 	struct ovcamchip_ops *sops;
 	void *spriv;               /* Private data for OV7x10.c etc... */
 	int subtype;               /* = SEN_OV7610 etc... */
@@ -53,6 +55,11 @@ struct ovcamchip {
 	int initialized;           /* OVCAMCHIP_CMD_INITIALIZE was successful */
 };
 
+static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ovcamchip, sd);
+}
+
 extern struct ovcamchip_ops ov6x20_ops;
 extern struct ovcamchip_ops ov6x30_ops;
 extern struct ovcamchip_ops ov7x10_ops;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -40,10 +40,10 @@ config VIDEO_PVRUSB2_DVB
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
 	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
-	select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
-	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
+	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	---help---
 
 	  This option enables a DVB interface for the pvrusb2 driver.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/Makefile linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/Makefile
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,14 +2,15 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2
 obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
 obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
 
-pvrusb2-objs	:= pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
-		   pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
+pvrusb2-objs	:= pvrusb2-i2c-core.o \
+		   pvrusb2-audio.o \
 		   pvrusb2-encoder.o pvrusb2-video-v4l.o \
-		   pvrusb2-eeprom.o pvrusb2-tuner.o \
+		   pvrusb2-eeprom.o \
 		   pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
 		   pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
 		   pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
 		   pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
+		   pvrusb2-cs53l32a.o \
 		   $(obj-pvrusb2-dvb-y) \
 		   $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,14 +26,6 @@
 #include <media/msp3400.h>
 #include <media/v4l2-common.h>
 
-struct pvr2_msp3400_handler {
-	struct pvr2_hdw *hdw;
-	struct pvr2_i2c_client *client;
-	struct pvr2_i2c_handler i2c_handler;
-	unsigned long stale_mask;
-};
-
-
 
 struct routing_scheme {
 	const int *def;
@@ -63,123 +55,33 @@ static const struct routing_scheme routi
 	},
 };
 
-/* This function selects the correct audio input source */
-static void set_stereo(struct pvr2_msp3400_handler *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	struct v4l2_routing route;
-	const struct routing_scheme *sp;
-	unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
-
-	if ((sid < ARRAY_SIZE(routing_schemes)) &&
-	    ((sp = routing_schemes + sid) != NULL) &&
-	    (hdw->input_val >= 0) &&
-	    (hdw->input_val < sp->cnt)) {
-		route.input = sp->def[hdw->input_val];
-	} else {
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
-			   " Invalid routing scheme (%u) and/or input (%d)",
-			   sid,hdw->input_val);
-		return;
-	}
-	route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_stereo(struct pvr2_msp3400_handler *ctxt)
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->input_dirty;
-}
-
-
-struct pvr2_msp3400_ops {
-	void (*update)(struct pvr2_msp3400_handler *);
-	int (*check)(struct pvr2_msp3400_handler *);
-};
-
-
-static const struct pvr2_msp3400_ops msp3400_ops[] = {
-	{ .update = set_stereo, .check = check_stereo},
-};
-
+	if (hdw->input_dirty || hdw->force_dirty) {
+		const struct routing_scheme *sp;
+		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
 
-static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
-{
-	unsigned long msk;
-	unsigned int idx;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
 
-	for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
-		msk = 1 << idx;
-		if (ctxt->stale_mask & msk) continue;
-		if (msp3400_ops[idx].check(ctxt)) {
-			ctxt->stale_mask |= msk;
+		if ((sid < ARRAY_SIZE(routing_schemes)) &&
+		    ((sp = routing_schemes + sid) != NULL) &&
+		    (hdw->input_val >= 0) &&
+		    (hdw->input_val < sp->cnt)) {
+			input = sp->def[hdw->input_val];
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "*** WARNING *** subdev msp3400 set_input:"
+				   " Invalid routing scheme (%u)"
+				   " and/or input (%d)",
+				   sid, hdw->input_val);
+			return;
 		}
-	}
-	return ctxt->stale_mask != 0;
-}
-
-
-static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
-{
-	unsigned long msk;
-	unsigned int idx;
-
-	for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
-		msk = 1 << idx;
-		if (!(ctxt->stale_mask & msk)) continue;
-		ctxt->stale_mask &= ~msk;
-		msp3400_ops[idx].update(ctxt);
+		sd->ops->audio->s_routing(sd, input,
+			MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
 	}
 }
 
-
-static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
-{
-	ctxt->client->handler = NULL;
-	kfree(ctxt);
-}
-
-
-static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
-					  char *buf,unsigned int cnt)
-{
-	return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
-}
-
-
-static const struct pvr2_i2c_handler_functions msp3400_funcs = {
-	.detach = (void (*)(void *))pvr2_msp3400_detach,
-	.check = (int (*)(void *))msp3400_check,
-	.update = (void (*)(void *))msp3400_update,
-	.describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
-};
-
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
-	struct pvr2_msp3400_handler *ctxt;
-	if (cp->handler) return 0;
-
-	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
-	if (!ctxt) return 0;
-
-	ctxt->i2c_handler.func_data = ctxt;
-	ctxt->i2c_handler.func_table = &msp3400_funcs;
-	ctxt->client = cp;
-	ctxt->hdw = hdw;
-	ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1;
-	cp->handler = &ctxt->i2c_handler;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
-		   cp->client->addr);
-	return !0;
-}
-
-
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
   *** Local Variables: ***
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-audio.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,10 +22,8 @@
 #ifndef __PVRUSB2_AUDIO_H
 #define __PVRUSB2_AUDIO_H
 
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
 #endif /* __PVRUSB2_AUDIO_H */
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ *
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.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
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+
+   This source file is specifically designed to interface with the
+   v4l-dvb cs53l32a module.
+
+*/
+
+#include "pvrusb2-cs53l32a.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct routing_scheme {
+	const int *def;
+	unsigned int cnt;
+};
+
+
+static const int routing_scheme1[] = {
+	[PVR2_CVAL_INPUT_TV] = 2,  /* 1 or 2 seems to work here */
+	[PVR2_CVAL_INPUT_RADIO] = 2,
+	[PVR2_CVAL_INPUT_COMPOSITE] = 0,
+	[PVR2_CVAL_INPUT_SVIDEO] =  0,
+};
+
+static const struct routing_scheme routing_schemes[] = {
+	[PVR2_ROUTING_SCHEME_ONAIR] = {
+		.def = routing_scheme1,
+		.cnt = ARRAY_SIZE(routing_scheme1),
+	},
+};
+
+
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
+{
+	if (hdw->input_dirty || hdw->force_dirty) {
+		const struct routing_scheme *sp;
+		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+			   hdw->input_val);
+		if ((sid < ARRAY_SIZE(routing_schemes)) &&
+		    ((sp = routing_schemes + sid) != NULL) &&
+		    (hdw->input_val >= 0) &&
+		    (hdw->input_val < sp->cnt)) {
+			input = sp->def[hdw->input_val];
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "*** WARNING *** subdev v4l2 set_input:"
+				   " Invalid routing scheme (%u)"
+				   " and/or input (%d)",
+				   sid, hdw->input_val);
+			return;
+		}
+		sd->ops->audio->s_routing(sd, input, 0, 0);
+	}
+}
+
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ *
+ *
+ *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ *  Copyright (C) 2004 Aurelien Alleaume <slts@free.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
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You 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 __PVRUSB2_CS53L32A_H
+#define __PVRUSB2_CS53L32A_H
+
+/*
+
+   This module connects the pvrusb2 driver to the I2C chip level
+   driver which handles device video processing.  This interface is
+   used internally by the driver; higher level code should only
+   interact through the interface provided by pvrusb2-hdw.h.
+
+*/
+
+
+#include "pvrusb2-hdw-internal.h"
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
+
+#endif /* __PVRUSB2_AUDIO_CS53L32A_H */
+
+/*
+  Stuff for Emacs to see, in order to encourage consistent editing style:
+  *** Local Variables: ***
+  *** mode: c ***
+  *** fill-column: 70 ***
+  *** tab-width: 8 ***
+  *** c-basic-offset: 8 ***
+  *** End: ***
+  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-ctrl.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-ctrl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-ctrl.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,14 +137,12 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *
 int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
 {
 	int ret = 0;
-	if (!cptr) return 0;
+	if (!cptr) return -EINVAL;
 	LOCK_TAKE(cptr->hdw->big_lock); do {
-		if (cptr->info->type == pvr2_ctl_int) {
-			if (cptr->info->get_def_value) {
-				ret = cptr->info->get_def_value(cptr, valptr);
-			} else {
-				*valptr = cptr->info->default_value;
-			}
+		if (cptr->info->get_def_value) {
+			ret = cptr->info->get_def_value(cptr, valptr);
+		} else {
+			*valptr = cptr->info->default_value;
 		}
 	} while(0); LOCK_GIVE(cptr->hdw->big_lock);
 	return ret;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 
 #include "pvrusb2-cx2584x-v4l.h"
 #include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
 
 
 #include "pvrusb2-hdw-internal.h"
@@ -39,14 +38,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-struct pvr2_v4l_cx2584x {
-	struct pvr2_i2c_handler handler;
-	struct pvr2_decoder_ctrl ctrl;
-	struct pvr2_i2c_client *client;
-	struct pvr2_hdw *hdw;
-	unsigned long stale_mask;
-};
-
 
 struct routing_scheme_item {
 	int vid;
@@ -110,219 +101,40 @@ static const struct routing_scheme routi
 	},
 };
 
-static void set_input(struct pvr2_v4l_cx2584x *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	struct v4l2_routing route;
-	enum cx25840_video_input vid_input;
-	enum cx25840_audio_input aud_input;
-	const struct routing_scheme *sp;
-	unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
-	memset(&route,0,sizeof(route));
-
-	if ((sid < ARRAY_SIZE(routing_schemes)) &&
-	    ((sp = routing_schemes + sid) != NULL) &&
-	    (hdw->input_val >= 0) &&
-	    (hdw->input_val < sp->cnt)) {
-		vid_input = sp->def[hdw->input_val].vid;
-		aud_input = sp->def[hdw->input_val].aud;
-	} else {
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "*** WARNING *** i2c cx2584x set_input:"
-			   " Invalid routing scheme (%u) and/or input (%d)",
-			   sid,hdw->input_val);
-		return;
-	}
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
-		   vid_input,aud_input);
-	route.input = (u32)vid_input;
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
-	route.input = (u32)aud_input;
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_cx2584x *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
-	u32 val;
-	struct pvr2_hdw *hdw = ctxt->hdw;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
-		   hdw->srate_val);
-	switch (hdw->srate_val) {
-	default:
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
-		val = 48000;
-		break;
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
-		val = 44100;
-		break;
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
-		val = 32000;
-		break;
-	}
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_cx2584x_ops {
-	void (*update)(struct pvr2_v4l_cx2584x *);
-	int (*check)(struct pvr2_v4l_cx2584x *);
-};
-
-
-static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
-	{ .update = set_input, .check = check_input},
-	{ .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
-{
-	ctxt->client->handler = NULL;
-	pvr2_hdw_set_decoder(ctxt->hdw,NULL);
-	kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
-	unsigned long msk;
-	unsigned int idx;
+	pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
+	if (hdw->input_dirty || hdw->force_dirty) {
+		enum cx25840_video_input vid_input;
+		enum cx25840_audio_input aud_input;
+		const struct routing_scheme *sp;
+		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
 
-	for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
-		msk = 1 << idx;
-		if (ctxt->stale_mask & msk) continue;
-		if (decoder_ops[idx].check(ctxt)) {
-			ctxt->stale_mask |= msk;
+		if ((sid < ARRAY_SIZE(routing_schemes)) &&
+		    ((sp = routing_schemes + sid) != NULL) &&
+		    (hdw->input_val >= 0) &&
+		    (hdw->input_val < sp->cnt)) {
+			vid_input = sp->def[hdw->input_val].vid;
+			aud_input = sp->def[hdw->input_val].aud;
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "*** WARNING *** subdev cx2584x set_input:"
+				   " Invalid routing scheme (%u)"
+				   " and/or input (%d)",
+				   sid, hdw->input_val);
+			return;
 		}
-	}
-	return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
-{
-	unsigned long msk;
-	unsigned int idx;
-
-	for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
-		msk = 1 << idx;
-		if (!(ctxt->stale_mask & msk)) continue;
-		ctxt->stale_mask &= ~msk;
-		decoder_ops[idx].update(ctxt);
-	}
-}
-
-
-static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
-{
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
-	pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
-	int ret;
-	/* Attempt to query the decoder - let's see if it will answer */
-	struct v4l2_queryctrl qc;
-
-	memset(&qc,0,sizeof(qc));
-
-	qc.id = V4L2_CID_BRIGHTNESS;
-
-	ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
-	return ret == 0; /* Return true if it answered */
-}
-
 
-static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
-				     char *buf,unsigned int cnt)
-{
-	return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
-}
-
-
-static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
-{
-	int ret;
-	ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
-	.detach = (void (*)(void *))decoder_detach,
-	.check = (int (*)(void *))decoder_check,
-	.update = (void (*)(void *))decoder_update,
-	.describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
-			       struct pvr2_i2c_client *cp)
-{
-	struct pvr2_v4l_cx2584x *ctxt;
-
-	if (hdw->decoder_ctrl) return 0;
-	if (cp->handler) return 0;
-	if (!decoder_detect(cp)) return 0;
-
-	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
-	if (!ctxt) return 0;
-
-	ctxt->handler.func_data = ctxt;
-	ctxt->handler.func_table = &hfuncs;
-	ctxt->ctrl.ctxt = ctxt;
-	ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
-	ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
-	ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
-	ctxt->client = cp;
-	ctxt->hdw = hdw;
-	ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
-	pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
-	cp->handler = &ctxt->handler;
-	{
-		/*
-		  Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
-		  of nuttiness for cx25840 causes that module to
-		  correctly set up its video scaling.  This is really
-		  a problem in the cx25840 module itself, but we work
-		  around it here.  The problem has not been seen in
-		  ivtv because there VBI is supported and set up.  We
-		  don't do VBI here (at least not yet) and thus we
-		  never attempted to even set it up.
-		 */
-		struct v4l2_format fmt;
-		memset(&fmt,0,sizeof(fmt));
-		fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
-		pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
+		pvr2_trace(PVR2_TRACE_CHIPS,
+			   "subdev cx2584x set_input vid=0x%x aud=0x%x",
+			   vid_input, aud_input);
+		sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
+		sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
 	}
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
-		   cp->client->addr);
-	return !0;
 }
 
 
 
-
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
   *** Local Variables: ***
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,9 +34,9 @@
 
 
 
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
 
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
 
 
 #endif /* __PVRUSB2_CX2584X_V4L_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,6 @@
 #include "pvrusb2-debugifc.h"
 #include "pvrusb2-hdw.h"
 #include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-core.h"
 
 struct debugifc_mask_item {
 	const char *name;
@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2
 	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
 	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-	ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
-	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
-	ccnt = pvr2_i2c_report(hdw,buf,acnt);
-	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 
 	return bcnt;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-debugifc.h	2009-06-09 23:05:27.000000000 -0400
@@ -22,16 +22,16 @@
 
 struct pvr2_hdw;
 
-/* Non-intrusively print some useful debugging info from inside the
-   driver.  This should work even if the driver appears to be
-   wedged. */
-int pvr2_debugifc_print_info(struct pvr2_hdw *,
-			     char *buf_ptr,unsigned int buf_size);
-
 /* Print general status of driver.  This will also trigger a probe of
    the USB link.  Unlike print_info(), this one synchronizes with the
    driver so the information should be self-consistent (but it will
    hang if the driver is wedged). */
+int pvr2_debugifc_print_info(struct pvr2_hdw *,
+			     char *buf_ptr, unsigned int buf_size);
+
+/* Non-intrusively print some useful debugging info from inside the
+   driver.  This should work even if the driver appears to be
+   wedged. */
 int pvr2_debugifc_print_status(struct pvr2_hdw *,
 			       char *buf_ptr,unsigned int buf_size);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c	2013-05-03 18:02:03.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.c	2013-05-03 16:45:53.000000000 -0400
@@ -46,10 +46,11 @@ pvr2_device_desc structures.
 /*------------------------------------------------------------------------*/
 /* Hauppauge PVR-USB2 Model 29xxx */
 
-static const char *pvr2_client_29xxx[] = {
-	"msp3400",
-	"saa7115",
-	"tuner",
+static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_SAA7115 },
+	{ .module_id = PVR2_CLIENT_ID_MSP3400 },
+	{ .module_id = PVR2_CLIENT_ID_TUNER },
+	{ .module_id = PVR2_CLIENT_ID_DEMOD },
 };
 
 static const char *pvr2_fw1_names_29xxx[] = {
@@ -59,8 +60,8 @@ static const char *pvr2_fw1_names_29xxx[
 static const struct pvr2_device_desc pvr2_device_29xxx = {
 		.description = "WinTV PVR USB2 Model Category 29xxx",
 		.shortname = "29xxx",
-		.client_modules.lst = pvr2_client_29xxx,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx),
+		.client_table.lst = pvr2_cli_29xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
 		.fx2_firmware.lst = pvr2_fw1_names_29xxx,
 		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
 		.flag_has_hauppauge_rom = !0,
@@ -77,10 +78,11 @@ static const struct pvr2_device_desc pvr
 /*------------------------------------------------------------------------*/
 /* Hauppauge PVR-USB2 Model 24xxx */
 
-static const char *pvr2_client_24xxx[] = {
-	"cx25840",
-	"tuner",
-	"wm8775",
+static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+	{ .module_id = PVR2_CLIENT_ID_TUNER },
+	{ .module_id = PVR2_CLIENT_ID_WM8775 },
+	{ .module_id = PVR2_CLIENT_ID_DEMOD },
 };
 
 static const char *pvr2_fw1_names_24xxx[] = {
@@ -90,8 +92,8 @@ static const char *pvr2_fw1_names_24xxx[
 static const struct pvr2_device_desc pvr2_device_24xxx = {
 		.description = "WinTV PVR USB2 Model Category 24xxx",
 		.shortname = "24xxx",
-		.client_modules.lst = pvr2_client_24xxx,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx),
+		.client_table.lst = pvr2_cli_24xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
 		.fx2_firmware.lst = pvr2_fw1_names_24xxx,
 		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
 		.flag_has_cx25840 = !0,
@@ -111,16 +113,16 @@ static const struct pvr2_device_desc pvr
 /*------------------------------------------------------------------------*/
 /* GOTVIEW USB2.0 DVD2 */
 
-static const char *pvr2_client_gotview_2[] = {
-	"cx25840",
-	"tuner",
+static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+	{ .module_id = PVR2_CLIENT_ID_TUNER },
 };
 
 static const struct pvr2_device_desc pvr2_device_gotview_2 = {
 		.description = "Gotview USB 2.0 DVD 2",
 		.shortname = "gv2",
-		.client_modules.lst = pvr2_client_gotview_2,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+		.client_table.lst = pvr2_cli_gotview_2,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
 		.flag_has_cx25840 = !0,
 		.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
 		.flag_has_analogtuner = !0,
@@ -140,8 +142,8 @@ static const struct pvr2_device_desc pvr
 static const struct pvr2_device_desc pvr2_device_gotview_2d = {
 		.description = "Gotview USB 2.0 DVD Deluxe",
 		.shortname = "gv2d",
-		.client_modules.lst = pvr2_client_gotview_2,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+		.client_table.lst = pvr2_cli_gotview_2,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
 		.flag_has_cx25840 = !0,
 		.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
 		.flag_has_analogtuner = !0,
@@ -181,29 +183,29 @@ static int pvr2_lgh06xf_attach(struct pv
 	return 0;
 }
 
-static struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
 	.frontend_attach = pvr2_lgdt3303_attach,
 	.tuner_attach    = pvr2_lgh06xf_attach,
 };
 #endif
 
-static const char *pvr2_client_onair_creator[] = {
-	"saa7115",
-	"tuner",
-	"cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = {
+	{ .module_id = PVR2_CLIENT_ID_SAA7115 },
+	{ .module_id = PVR2_CLIENT_ID_CS53L32A },
+	{ .module_id = PVR2_CLIENT_ID_TUNER },
 };
 
 static const struct pvr2_device_desc pvr2_device_onair_creator = {
 		.description = "OnAir Creator Hybrid USB tuner",
 		.shortname = "oac",
-		.client_modules.lst = pvr2_client_onair_creator,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator),
+		.client_table.lst = pvr2_cli_onair_creator,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator),
 		.default_tuner_type = TUNER_LG_TDVS_H06XF,
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
 		.flag_digital_requires_cx23416 = !0,
-		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
 		.default_std_mask = V4L2_STD_NTSC_M,
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -241,29 +243,29 @@ static int pvr2_fcv1236d_attach(struct p
 	return 0;
 }
 
-static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
 	.frontend_attach = pvr2_lgdt3302_attach,
 	.tuner_attach    = pvr2_fcv1236d_attach,
 };
 #endif
 
-static const char *pvr2_client_onair_usb2[] = {
-	"saa7115",
-	"tuner",
-	"cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = {
+	{ .module_id = PVR2_CLIENT_ID_SAA7115 },
+	{ .module_id = PVR2_CLIENT_ID_CS53L32A },
+	{ .module_id = PVR2_CLIENT_ID_TUNER },
 };
 
 static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
 		.description = "OnAir USB2 Hybrid USB tuner",
 		.shortname = "oa2",
-		.client_modules.lst = pvr2_client_onair_usb2,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2),
+		.client_table.lst = pvr2_cli_onair_usb2,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2),
 		.default_tuner_type = TUNER_PHILIPS_FCV1236D,
 		.flag_has_analogtuner = !0,
 		.flag_has_composite = !0,
 		.flag_has_svideo = !0,
 		.flag_digital_requires_cx23416 = !0,
-		.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+		.signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
 		.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
 		.default_std_mask = V4L2_STD_NTSC_M,
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -314,15 +316,16 @@ static int pvr2_73xxx_tda18271_8295_atta
 	return 0;
 }
 
-static struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
 	.frontend_attach = pvr2_tda10048_attach,
 	.tuner_attach    = pvr2_73xxx_tda18271_8295_attach,
 };
 #endif
 
-static const char *pvr2_client_73xxx[] = {
-	"cx25840",
-	"tuner",
+static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
+	{ .module_id = PVR2_CLIENT_ID_CX25840 },
+	{ .module_id = PVR2_CLIENT_ID_TUNER,
+	  .i2c_address_list = "\x42"},
 };
 
 static const char *pvr2_fw1_names_73xxx[] = {
@@ -332,8 +335,8 @@ static const char *pvr2_fw1_names_73xxx[
 static const struct pvr2_device_desc pvr2_device_73xxx = {
 		.description = "WinTV HVR-1900 Model Category 73xxx",
 		.shortname = "73xxx",
-		.client_modules.lst = pvr2_client_73xxx,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx),
+		.client_table.lst = pvr2_cli_73xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
 		.fx2_firmware.lst = pvr2_fw1_names_73xxx,
 		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx),
 		.flag_has_cx25840 = !0,
@@ -418,22 +421,17 @@ static int pvr2_tda18271_8295_attach(str
 	return 0;
 }
 
-static struct pvr2_dvb_props pvr2_750xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_750xx_dvb_props = {
 	.frontend_attach = pvr2_s5h1409_attach,
 	.tuner_attach    = pvr2_tda18271_8295_attach,
 };
 
-static struct pvr2_dvb_props pvr2_751xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
 	.frontend_attach = pvr2_s5h1411_attach,
 	.tuner_attach    = pvr2_tda18271_8295_attach,
 };
 #endif
 
-static const char *pvr2_client_75xxx[] = {
-	"cx25840",
-	"tuner",
-};
-
 static const char *pvr2_fw1_names_75xxx[] = {
 		"/*(DEBLOBBED)*/",
 };
@@ -441,8 +439,8 @@ static const char *pvr2_fw1_names_75xxx[
 static const struct pvr2_device_desc pvr2_device_750xx = {
 		.description = "WinTV HVR-1950 Model Category 750xx",
 		.shortname = "750xx",
-		.client_modules.lst = pvr2_client_75xxx,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+		.client_table.lst = pvr2_cli_73xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
 		.fx2_firmware.lst = pvr2_fw1_names_75xxx,
 		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
 		.flag_has_cx25840 = !0,
@@ -463,8 +461,8 @@ static const struct pvr2_device_desc pvr
 static const struct pvr2_device_desc pvr2_device_751xx = {
 		.description = "WinTV HVR-1950 Model Category 751xx",
 		.shortname = "751xx",
-		.client_modules.lst = pvr2_client_75xxx,
-		.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+		.client_table.lst = pvr2_cli_73xxx,
+		.client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
 		.fx2_firmware.lst = pvr2_fw1_names_75xxx,
 		.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
 		.flag_has_cx25840 = !0,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-devattr.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,34 @@
 */
 
 
+#define PVR2_CLIENT_ID_NULL 0
+#define PVR2_CLIENT_ID_MSP3400 1
+#define PVR2_CLIENT_ID_CX25840 2
+#define PVR2_CLIENT_ID_SAA7115 3
+#define PVR2_CLIENT_ID_TUNER 4
+#define PVR2_CLIENT_ID_CS53L32A 5
+#define PVR2_CLIENT_ID_WM8775 6
+#define PVR2_CLIENT_ID_DEMOD 7
+
+struct pvr2_device_client_desc {
+	/* One ovr PVR2_CLIENT_ID_xxxx */
+	unsigned char module_id;
+
+	/* Null-terminated array of I2C addresses to try in order
+	   initialize the module.  It's safe to make this null terminated
+	   since we're never going to encounter an i2c device with an
+	   address of zero.  If this is a null pointer or zero-length,
+	   then no I2C addresses have been specified, in which case we'll
+	   try some compiled in defaults for now. */
+	unsigned char *i2c_address_list;
+};
+
+struct pvr2_device_client_table {
+	const struct pvr2_device_client_desc *lst;
+	unsigned char cnt;
+};
+
+
 struct pvr2_string_table {
 	const char **lst;
 	unsigned int cnt;
@@ -40,6 +68,7 @@ struct pvr2_string_table {
 
 #define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
 #define PVR2_ROUTING_SCHEME_GOTVIEW 1
+#define PVR2_ROUTING_SCHEME_ONAIR 2
 
 #define PVR2_DIGITAL_SCHEME_NONE 0
 #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -66,6 +95,9 @@ struct pvr2_device_desc {
 	/* List of additional client modules we need to load */
 	struct pvr2_string_table client_modules;
 
+	/* List of defined client modules we need to load */
+	struct pvr2_device_client_table client_table;
+
 	/* List of FX2 firmware file names we should search; if empty then
 	   FX2 firmware check / load is skipped and we assume the device
 	   was initialized from internal ROM. */
@@ -73,7 +105,7 @@ struct pvr2_device_desc {
 
 #ifdef CONFIG_VIDEO_PVRUSB2_DVB
 	/* callback functions to handle attachment of digital tuner & demod */
-	struct pvr2_dvb_props *dvb_props;
+	const struct pvr2_dvb_props *dvb_props;
 
 #endif
 	/* Initial standard bits to use for this device, if not zero.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-dvb.c	2009-06-09 23:05:27.000000000 -0400
@@ -321,7 +321,7 @@ static int pvr2_dvb_adapter_exit(struct
 static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
 {
 	struct pvr2_hdw *hdw = adap->channel.hdw;
-	struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
+	const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
 	int ret = 0;
 
 	if (dvb_props == NULL) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-encoder.c	2009-06-09 23:05:27.000000000 -0400
@@ -347,7 +347,7 @@ static int pvr2_encoder_prep_config(stru
 	int encMisc3Arg = 0;
 
 #if 0
-	/* This inexplicable bit happens in the Hauppage windows
+	/* This inexplicable bit happens in the Hauppauge windows
 	   driver (for both 24xxx and 29xxx devices).  However I
 	   currently see no difference in behavior with or without
 	   this stuff.  Leave this here as a note of its existence,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 18:02:01.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 16:45:51.000000000 -0400
@@ -24,17 +24,22 @@
 #include <linux/firmware.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/tuner.h>
 #include "pvrusb2.h"
 #include "pvrusb2-std.h"
 #include "pvrusb2-util.h"
 #include "pvrusb2-hdw.h"
 #include "pvrusb2-i2c-core.h"
-#include "pvrusb2-tuner.h"
 #include "pvrusb2-eeprom.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-encoder.h"
 #include "pvrusb2-debug.h"
 #include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2-wm8775.h"
+#include "pvrusb2-video-v4l.h"
+#include "pvrusb2-cx2584x-v4l.h"
+#include "pvrusb2-cs53l32a.h"
+#include "pvrusb2-audio.h"
 
 #define TV_MIN_FREQ     55250000L
 #define TV_MAX_FREQ    850000000L
@@ -104,6 +109,39 @@ MODULE_PARM_DESC(radio_freq, "specify in
 /* size of a firmware chunk */
 #define FIRMWARE_CHUNK_SIZE 0x2000
 
+typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *,
+					struct v4l2_subdev *);
+
+static const pvr2_subdev_update_func pvr2_module_update_functions[] = {
+	[PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update,
+	[PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update,
+	[PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update,
+	[PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update,
+	[PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update,
+};
+
+static const char *module_names[] = {
+	[PVR2_CLIENT_ID_MSP3400] = "msp3400",
+	[PVR2_CLIENT_ID_CX25840] = "cx25840",
+	[PVR2_CLIENT_ID_SAA7115] = "saa7115",
+	[PVR2_CLIENT_ID_TUNER] = "tuner",
+	[PVR2_CLIENT_ID_DEMOD] = "tuner",
+	[PVR2_CLIENT_ID_CS53L32A] = "cs53l32a",
+	[PVR2_CLIENT_ID_WM8775] = "wm8775",
+};
+
+
+static const unsigned char *module_i2c_addresses[] = {
+	[PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
+	[PVR2_CLIENT_ID_DEMOD] = "\x43",
+	[PVR2_CLIENT_ID_MSP3400] = "\x40",
+	[PVR2_CLIENT_ID_SAA7115] = "\x21",
+	[PVR2_CLIENT_ID_WM8775] = "\x1b",
+	[PVR2_CLIENT_ID_CX25840] = "\x44",
+	[PVR2_CLIENT_ID_CS53L32A] = "\x11",
+};
+
+
 /* Define the list of additional controls we'll dynamically construct based
    on query of the cx2341x module. */
 struct pvr2_mpeg_ids {
@@ -277,7 +315,6 @@ static int pvr2_hdw_set_input(struct pvr
 static void pvr2_hdw_state_sched(struct pvr2_hdw *);
 static int pvr2_hdw_state_eval(struct pvr2_hdw *);
 static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
-static void pvr2_hdw_worker_i2c(struct work_struct *work);
 static void pvr2_hdw_worker_poll(struct work_struct *work);
 static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
 static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
@@ -642,7 +679,7 @@ static int ctrl_freq_max_get(struct pvr2
 	unsigned long fv;
 	struct pvr2_hdw *hdw = cptr->hdw;
 	if (hdw->tuner_signal_stale) {
-		pvr2_i2c_core_status_poll(hdw);
+		pvr2_hdw_status_poll(hdw);
 	}
 	fv = hdw->tuner_signal_info.rangehigh;
 	if (!fv) {
@@ -664,7 +701,7 @@ static int ctrl_freq_min_get(struct pvr2
 	unsigned long fv;
 	struct pvr2_hdw *hdw = cptr->hdw;
 	if (hdw->tuner_signal_stale) {
-		pvr2_i2c_core_status_poll(hdw);
+		pvr2_hdw_status_poll(hdw);
 	}
 	fv = hdw->tuner_signal_info.rangelow;
 	if (!fv) {
@@ -858,7 +895,7 @@ static void ctrl_stdcur_clear_dirty(stru
 static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
 {
 	struct pvr2_hdw *hdw = cptr->hdw;
-	pvr2_i2c_core_status_poll(hdw);
+	pvr2_hdw_status_poll(hdw);
 	*vp = hdw->tuner_signal_info.signal;
 	return 0;
 }
@@ -868,7 +905,7 @@ static int ctrl_audio_modes_present_get(
 	int val = 0;
 	unsigned int subchan;
 	struct pvr2_hdw *hdw = cptr->hdw;
-	pvr2_i2c_core_status_poll(hdw);
+	pvr2_hdw_status_poll(hdw);
 	subchan = hdw->tuner_signal_info.rxsubchans;
 	if (subchan & V4L2_TUNER_SUB_MONO) {
 		val |= (1 << V4L2_TUNER_MODE_MONO);
@@ -1283,6 +1320,12 @@ const char *pvr2_hdw_get_bus_info(struct
 }
 
 
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
+{
+	return hdw->identifier;
+}
+
+
 unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
 {
 	return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1418,7 +1461,6 @@ static int pvr2_upload_firmware1(struct
 		return ret;
 	}
 
-	usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
 	usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
 
 	pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
@@ -1634,33 +1676,27 @@ static const char *pvr2_get_state_name(u
 
 static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
 {
-	if (!hdw->decoder_ctrl) {
-		if (!hdw->flag_decoder_missed) {
-			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-				   "WARNING: No decoder present");
-			hdw->flag_decoder_missed = !0;
-			trace_stbit("flag_decoder_missed",
-				    hdw->flag_decoder_missed);
-		}
-		return -EIO;
+	/* Even though we really only care about the video decoder chip at
+	   this point, we'll broadcast stream on/off to all sub-devices
+	   anyway, just in case somebody else wants to hear the
+	   command... */
+	pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
+		   (enablefl ? "on" : "off"));
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
+	if (hdw->decoder_client_id) {
+		/* We get here if the encoder has been noticed.  Otherwise
+		   we'll issue a warning to the user (which should
+		   normally never happen). */
+		return 0;
 	}
-	hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
-	return 0;
-}
-
-
-void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
-{
-	if (hdw->decoder_ctrl == ptr) return;
-	hdw->decoder_ctrl = ptr;
-	if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
-		hdw->flag_decoder_missed = 0;
+	if (!hdw->flag_decoder_missed) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "WARNING: No decoder present");
+		hdw->flag_decoder_missed = !0;
 		trace_stbit("flag_decoder_missed",
 			    hdw->flag_decoder_missed);
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "Decoder has appeared");
-		pvr2_hdw_state_sched(hdw);
 	}
+	return -EIO;
 }
 
 
@@ -1927,6 +1963,166 @@ static void pvr2_hdw_setup_std(struct pv
 }
 
 
+static unsigned int pvr2_copy_i2c_addr_list(
+	unsigned short *dst, const unsigned char *src,
+	unsigned int dst_max)
+{
+	unsigned int cnt = 0;
+	if (!src) return 0;
+	while (src[cnt] && (cnt + 1) < dst_max) {
+		dst[cnt] = src[cnt];
+		cnt++;
+	}
+	dst[cnt] = I2C_CLIENT_END;
+	return cnt;
+}
+
+
+static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+				const struct pvr2_device_client_desc *cd)
+{
+	const char *fname;
+	unsigned char mid;
+	struct v4l2_subdev *sd;
+	unsigned int i2ccnt;
+	const unsigned char *p;
+	/* Arbitrary count - max # i2c addresses we will probe */
+	unsigned short i2caddr[25];
+
+	mid = cd->module_id;
+	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",
+			   mid,
+			   hdw->hdw_desc->description);
+		return -EINVAL;
+	}
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Module ID %u (%s) for device %s being loaded...",
+		   mid, fname,
+		   hdw->hdw_desc->description);
+
+	i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
+					 ARRAY_SIZE(i2caddr));
+	if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
+			 module_i2c_addresses[mid] : NULL) != NULL)) {
+		/* Second chance: Try default i2c address list */
+		i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
+						 ARRAY_SIZE(i2caddr));
+		if (i2ccnt) {
+			pvr2_trace(PVR2_TRACE_INIT,
+				   "Module ID %u:"
+				   " Using default i2c address list",
+				   mid);
+		}
+	}
+
+	if (!i2ccnt) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Module ID %u (%s) for device %s:"
+			   " No i2c addresses",
+			   mid, fname, hdw->hdw_desc->description);
+		return -EINVAL;
+	}
+
+	/* Note how the 2nd and 3rd arguments are the same for both
+	 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev().  Why?
+	 * Well the 2nd argument is the module name to load, while the 3rd
+	 * argument is documented in the framework as being the "chipid" -
+	 * and every other place where I can find examples of this, the
+	 * "chipid" appears to just be the module name again.  So here we
+	 * just do the same thing. */
+	if (i2ccnt == 1) {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Module ID %u:"
+			   " Setting up with specified i2c address 0x%x",
+			   mid, i2caddr[0]);
+		sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
+					 fname, fname,
+					 i2caddr[0]);
+	} else {
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "Module ID %u:"
+			   " Setting up with address probe list",
+			   mid);
+		sd = v4l2_i2c_new_probed_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
+						fname, fname,
+						i2caddr);
+	}
+
+	if (!sd) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Module ID %u (%s) for device %s failed to load",
+			   mid, fname, hdw->hdw_desc->description);
+		return -EIO;
+	}
+
+	/* Tag this sub-device instance with the module ID we know about.
+	   In other places we'll use that tag to determine if the instance
+	   requires special handling. */
+	sd->grp_id = mid;
+
+	pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
+
+
+	/* client-specific setup... */
+	switch (mid) {
+	case PVR2_CLIENT_ID_CX25840:
+		hdw->decoder_client_id = mid;
+		{
+			/*
+			  Mike Isely <isely@pobox.com> 19-Nov-2006 - This
+			  bit of nuttiness for cx25840 causes that module
+			  to correctly set up its video scaling.  This is
+			  really a problem in the cx25840 module itself,
+			  but we work around it here.  The problem has not
+			  been seen in ivtv because there VBI is supported
+			  and set up.  We don't do VBI here (at least not
+			  yet) and thus we never attempted to even set it
+			  up.
+			*/
+			struct v4l2_format fmt;
+			pvr2_trace(PVR2_TRACE_INIT,
+				   "Module ID %u:"
+				   " Executing cx25840 VBI hack",
+				   mid);
+			memset(&fmt, 0, sizeof(fmt));
+			fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+			v4l2_device_call_all(&hdw->v4l2_dev, mid,
+					     video, s_fmt, &fmt);
+		}
+		break;
+	case PVR2_CLIENT_ID_SAA7115:
+		hdw->decoder_client_id = mid;
+		break;
+	default: break;
+	}
+
+	return 0;
+}
+
+
+static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
+{
+	unsigned int idx;
+	const struct pvr2_string_table *cm;
+	const struct pvr2_device_client_table *ct;
+	int okFl = !0;
+
+	cm = &hdw->hdw_desc->client_modules;
+	for (idx = 0; idx < cm->cnt; idx++) {
+		request_module(cm->lst[idx]);
+	}
+
+	ct = &hdw->hdw_desc->client_table;
+	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);
+}
+
+
 static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
 {
 	int ret;
@@ -1966,9 +2162,7 @@ static void pvr2_hdw_setup_low(struct pv
 
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
-	for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
-		request_module(hdw->hdw_desc->client_modules.lst[idx]);
-	}
+	hdw->force_dirty = !0;
 
 	if (!hdw->hdw_desc->flag_no_powerup) {
 		pvr2_hdw_cmd_powerup(hdw);
@@ -1987,6 +2181,11 @@ static void pvr2_hdw_setup_low(struct pv
 	pvr2_i2c_core_init(hdw);
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
+	pvr2_hdw_load_modules(hdw);
+	if (!pvr2_hdw_dev_ok(hdw)) return;
+
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, core, load_fw);
+
 	for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
 		cptr = hdw->controls + idx;
 		if (cptr->info->skip_init) continue;
@@ -2024,6 +2223,19 @@ static void pvr2_hdw_setup_low(struct pv
 		hdw->std_mask_eeprom = V4L2_STD_ALL;
 	}
 
+	if (hdw->serial_number) {
+		idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+				"sn-%lu", hdw->serial_number);
+	} else if (hdw->unit_number >= 0) {
+		idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+				"unit-%c",
+				hdw->unit_number + 'a');
+	} else {
+		idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+				"unit-??");
+	}
+	hdw->identifier[idx] = 0;
+
 	pvr2_hdw_setup_std(hdw);
 
 	if (!get_default_tuner_type(hdw)) {
@@ -2032,8 +2244,6 @@ static void pvr2_hdw_setup_low(struct pv
 			   hdw->tuner_type);
 	}
 
-	pvr2_i2c_core_check_stale(hdw);
-	hdw->tuner_updated = 0;
 
 	if (!pvr2_hdw_dev_ok(hdw)) return;
 
@@ -2171,11 +2381,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 	struct pvr2_hdw *hdw = NULL;
 	int valid_std_mask;
 	struct pvr2_ctrl *cptr;
+	struct usb_device *usb_dev;
 	const struct pvr2_device_desc *hdw_desc;
 	__u8 ifnum;
 	struct v4l2_queryctrl qctrl;
 	struct pvr2_ctl_info *ciptr;
 
+	usb_dev = interface_to_usbdev(intf);
+
 	hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
 
 	if (hdw_desc == NULL) {
@@ -2360,6 +2573,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 	hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
 	if (!hdw->ctl_read_urb) goto fail;
 
+	if (v4l2_device_register(&intf->dev, &hdw->v4l2_dev) != 0) {
+		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+			   "Error registering with v4l core, giving up");
+		goto fail;
+	}
 	mutex_lock(&pvr2_unit_mtx); do {
 		for (idx = 0; idx < PVR_NUM; idx++) {
 			if (unit_pointers[idx]) continue;
@@ -2382,7 +2600,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 
 	hdw->workqueue = create_singlethread_workqueue(hdw->name);
 	INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
-	INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
 
 	pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
 		   hdw->unit_number,hdw->name);
@@ -2391,12 +2608,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct
 	hdw->flag_ok = !0;
 
 	hdw->usb_intf = intf;
-	hdw->usb_dev = interface_to_usbdev(intf);
+	hdw->usb_dev = usb_dev;
 
-	scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
-		  "usb %s address %d",
-		  dev_name(&hdw->usb_dev->dev),
-		  hdw->usb_dev->devnum);
+	usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
 
 	ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
 	usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2454,6 +2668,10 @@ static void pvr2_hdw_remove_usb_stuff(st
 		hdw->ctl_write_buffer = NULL;
 	}
 	hdw->flag_disconnected = !0;
+	/* If we don't do this, then there will be a dangling struct device
+	   reference to our disappearing device persisting inside the V4L
+	   core... */
+	v4l2_device_disconnect(&hdw->v4l2_dev);
 	hdw->usb_dev = NULL;
 	hdw->usb_intf = NULL;
 	pvr2_hdw_render_useless(hdw);
@@ -2481,10 +2699,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *h
 		pvr2_stream_destroy(hdw->vid_stream);
 		hdw->vid_stream = NULL;
 	}
-	if (hdw->decoder_ctrl) {
-		hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
-	}
 	pvr2_i2c_core_done(hdw);
+	v4l2_device_unregister(&hdw->v4l2_dev);
 	pvr2_hdw_remove_usb_stuff(hdw);
 	mutex_lock(&pvr2_unit_mtx); do {
 		if ((hdw->unit_number >= 0) &&
@@ -2678,6 +2894,151 @@ static const char *get_ctrl_typename(enu
 }
 
 
+static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
+				    const char *name, int val)
+{
+	struct v4l2_control ctrl;
+	pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
+	memset(&ctrl, 0, sizeof(ctrl));
+	ctrl.id = id;
+	ctrl.value = val;
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
+}
+
+#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
+	if ((hdw)->lab##_dirty || (hdw)->force_dirty) {		\
+		pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
+	}
+
+/* Execute whatever commands are required to update the state of all the
+   sub-devices so that they match our current control values. */
+static void pvr2_subdev_update(struct pvr2_hdw *hdw)
+{
+	struct v4l2_subdev *sd;
+	unsigned int id;
+	pvr2_subdev_update_func fp;
+
+	pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
+
+	if (hdw->tuner_updated || hdw->force_dirty) {
+		struct tuner_setup setup;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
+			   hdw->tuner_type);
+		if (((int)(hdw->tuner_type)) >= 0) {
+			memset(&setup, 0, sizeof(setup));
+			setup.addr = ADDR_UNSET;
+			setup.type = hdw->tuner_type;
+			setup.mode_mask = T_RADIO | T_ANALOG_TV;
+			v4l2_device_call_all(&hdw->v4l2_dev, 0,
+					     tuner, s_type_addr, &setup);
+		}
+	}
+
+	if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
+		if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+			v4l2_device_call_all(&hdw->v4l2_dev, 0,
+					     tuner, s_radio);
+		} else {
+			v4l2_std_id vs;
+			vs = hdw->std_mask_cur;
+			v4l2_device_call_all(&hdw->v4l2_dev, 0,
+					     core, s_std, vs);
+		}
+		hdw->tuner_signal_stale = !0;
+		hdw->cropcap_stale = !0;
+	}
+
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
+	PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
+
+	if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
+		struct v4l2_tuner vt;
+		memset(&vt, 0, sizeof(vt));
+		vt.audmode = hdw->audiomode_val;
+		v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
+	}
+
+	if (hdw->freqDirty || hdw->force_dirty) {
+		unsigned long fv;
+		struct v4l2_frequency freq;
+		fv = pvr2_hdw_get_cur_freq(hdw);
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv);
+		if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw);
+		memset(&freq, 0, sizeof(freq));
+		if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
+			/* ((fv * 1000) / 62500) */
+			freq.frequency = (fv * 2) / 125;
+		} else {
+			freq.frequency = fv / 62500;
+		}
+		/* tuner-core currently doesn't seem to care about this, but
+		   let's set it anyway for completeness. */
+		if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+			freq.type = V4L2_TUNER_RADIO;
+		} else {
+			freq.type = V4L2_TUNER_ANALOG_TV;
+		}
+		freq.tuner = 0;
+		v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner,
+				     s_frequency, &freq);
+	}
+
+	if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
+		struct v4l2_format fmt;
+		memset(&fmt, 0, sizeof(fmt));
+		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		fmt.fmt.pix.width = hdw->res_hor_val;
+		fmt.fmt.pix.height = hdw->res_ver_val;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
+			   fmt.fmt.pix.width, fmt.fmt.pix.height);
+		v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt);
+	}
+
+	if (hdw->srate_dirty || hdw->force_dirty) {
+		u32 val;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
+			   hdw->srate_val);
+		switch (hdw->srate_val) {
+		default:
+		case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
+			val = 48000;
+			break;
+		case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
+			val = 44100;
+			break;
+		case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
+			val = 32000;
+			break;
+		}
+		v4l2_device_call_all(&hdw->v4l2_dev, 0,
+				     audio, s_clock_freq, val);
+	}
+
+	/* Unable to set crop parameters; there is apparently no equivalent
+	   for VIDIOC_S_CROP */
+
+	v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+		id = sd->grp_id;
+		if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
+		fp = pvr2_module_update_functions[id];
+		if (!fp) continue;
+		(*fp)(hdw, sd);
+	}
+
+	if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
+		pvr2_hdw_status_poll(hdw);
+	}
+}
+
+
 /* Figure out if we need to commit control changes.  If so, mark internal
    state flags to indicate this fact and return true.  Otherwise do nothing
    else and return false. */
@@ -2686,7 +3047,7 @@ static int pvr2_hdw_commit_setup(struct
 	unsigned int idx;
 	struct pvr2_ctrl *cptr;
 	int value;
-	int commit_flag = 0;
+	int commit_flag = hdw->force_dirty;
 	char buf[100];
 	unsigned int bcnt,ccnt;
 
@@ -2842,18 +3203,6 @@ static int pvr2_hdw_commit_execute(struc
 		cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
 	}
 
-	/* Scan i2c core at this point - before we clear all the dirty
-	   bits.  Various parts of the i2c core will notice dirty bits as
-	   appropriate and arrange to broadcast or directly send updates to
-	   the client drivers in order to keep everything in sync */
-	pvr2_i2c_core_check_stale(hdw);
-
-	for (idx = 0; idx < hdw->control_cnt; idx++) {
-		cptr = hdw->controls + idx;
-		if (!cptr->info->clear_dirty) continue;
-		cptr->info->clear_dirty(cptr);
-	}
-
 	if (hdw->active_stream_type != hdw->desired_stream_type) {
 		/* Handle any side effects of stream config here */
 		hdw->active_stream_type = hdw->desired_stream_type;
@@ -2873,8 +3222,16 @@ static int pvr2_hdw_commit_execute(struc
 		}
 	}
 
-	/* Now execute i2c core update */
-	pvr2_i2c_core_sync(hdw);
+	/* Check and update state for all sub-devices. */
+	pvr2_subdev_update(hdw);
+
+	hdw->tuner_updated = 0;
+	hdw->force_dirty = 0;
+	for (idx = 0; idx < hdw->control_cnt; idx++) {
+		cptr = hdw->controls + idx;
+		if (!cptr->info->clear_dirty) continue;
+		cptr->info->clear_dirty(cptr);
+	}
 
 	if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
 	    hdw->state_encoder_run) {
@@ -2904,15 +3261,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw
 }
 
 
-static void pvr2_hdw_worker_i2c(struct work_struct *work)
-{
-	struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
-	LOCK_TAKE(hdw->big_lock); do {
-		pvr2_i2c_core_sync(hdw);
-	} while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
 static void pvr2_hdw_worker_poll(struct work_struct *work)
 {
 	int fl = 0;
@@ -2973,7 +3321,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw
 void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
 {
 	LOCK_TAKE(hdw->big_lock); do {
-		pvr2_i2c_core_status_poll(hdw);
+		pvr2_hdw_status_poll(hdw);
 	} while (0); LOCK_GIVE(hdw->big_lock);
 }
 
@@ -2983,7 +3331,7 @@ static int pvr2_hdw_check_cropcap(struct
 	if (!hdw->cropcap_stale) {
 		return 0;
 	}
-	pvr2_i2c_core_status_poll(hdw);
+	pvr2_hdw_status_poll(hdw);
 	if (hdw->cropcap_stale) {
 		return -EIO;
 	}
@@ -3010,7 +3358,7 @@ int pvr2_hdw_get_tuner_status(struct pvr
 {
 	LOCK_TAKE(hdw->big_lock); do {
 		if (hdw->tuner_signal_stale) {
-			pvr2_i2c_core_status_poll(hdw);
+			pvr2_hdw_status_poll(hdw);
 		}
 		memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
 	} while (0); LOCK_GIVE(hdw->big_lock);
@@ -3029,11 +3377,8 @@ void pvr2_hdw_trigger_module_log(struct
 {
 	int nr = pvr2_hdw_get_unit_number(hdw);
 	LOCK_TAKE(hdw->big_lock); do {
-		hdw->log_requested = !0;
 		printk(KERN_INFO "pvrusb2: =================  START STATUS CARD #%d  =================\n", nr);
-		pvr2_i2c_core_check_stale(hdw);
-		hdw->log_requested = 0;
-		pvr2_i2c_core_sync(hdw);
+		v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
 		pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
 		cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
 		pvr2_hdw_state_log_state(hdw);
@@ -3716,22 +4061,16 @@ int pvr2_hdw_cmd_powerdown(struct pvr2_h
 
 int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
 {
-	if (!hdw->decoder_ctrl) {
-		pvr2_trace(PVR2_TRACE_INIT,
-			   "Unable to reset decoder: nothing attached");
-		return -ENOTTY;
-	}
-
-	if (!hdw->decoder_ctrl->force_reset) {
-		pvr2_trace(PVR2_TRACE_INIT,
-			   "Unable to reset decoder: not implemented");
-		return -ENOTTY;
-	}
-
 	pvr2_trace(PVR2_TRACE_INIT,
 		   "Requesting decoder reset");
-	hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
-	return 0;
+	if (hdw->decoder_client_id) {
+		v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+				     core, reset, 0);
+		return 0;
+	}
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Unable to reset decoder: nothing attached");
+	return -ENOTTY;
 }
 
 
@@ -4476,6 +4815,79 @@ static unsigned int pvr2_hdw_report_unlo
 }
 
 
+/* Generate report containing info about attached sub-devices and attached
+   i2c clients, including an indication of which attached i2c clients are
+   actually sub-devices. */
+static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
+					    char *buf, unsigned int acnt)
+{
+	struct v4l2_subdev *sd;
+	unsigned int tcnt = 0;
+	unsigned int ccnt;
+	struct i2c_client *client;
+	struct list_head *item;
+	void *cd;
+	const char *p;
+	unsigned int id;
+
+	ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
+	tcnt += ccnt;
+	v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+		id = sd->grp_id;
+		p = NULL;
+		if (id < ARRAY_SIZE(module_names)) p = module_names[id];
+		if (p) {
+			ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
+			tcnt += ccnt;
+		} else {
+			ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+					 " (unknown id=%u)", id);
+			tcnt += ccnt;
+		}
+	}
+	ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+	tcnt += ccnt;
+
+	ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
+	tcnt += ccnt;
+
+	mutex_lock(&hdw->i2c_adap.clist_lock);
+	list_for_each(item, &hdw->i2c_adap.clients) {
+		client = list_entry(item, struct i2c_client, list);
+		ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+				 "  %s: i2c=%02x", client->name, client->addr);
+		tcnt += ccnt;
+		cd = i2c_get_clientdata(client);
+		v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+			if (cd == sd) {
+				id = sd->grp_id;
+				p = NULL;
+				if (id < ARRAY_SIZE(module_names)) {
+					p = module_names[id];
+				}
+				if (p) {
+					ccnt = scnprintf(buf + tcnt,
+							 acnt - tcnt,
+							 " subdev=%s", p);
+					tcnt += ccnt;
+				} else {
+					ccnt = scnprintf(buf + tcnt,
+							 acnt - tcnt,
+							 " subdev= id %u)",
+							 id);
+					tcnt += ccnt;
+				}
+				break;
+			}
+		}
+		ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+		tcnt += ccnt;
+	}
+	mutex_unlock(&hdw->i2c_adap.clist_lock);
+	return tcnt;
+}
+
+
 unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
 				   char *buf,unsigned int acnt)
 {
@@ -4490,6 +4902,8 @@ unsigned int pvr2_hdw_state_report(struc
 		buf[0] = '\n'; ccnt = 1;
 		bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	}
+	ccnt = pvr2_hdw_report_clients(hdw, buf, acnt);
+	bcnt += ccnt; acnt -= ccnt; buf += ccnt;
 	LOCK_GIVE(hdw->big_lock);
 	return bcnt;
 }
@@ -4497,14 +4911,25 @@ unsigned int pvr2_hdw_state_report(struc
 
 static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
 {
-	char buf[128];
-	unsigned int idx,ccnt;
+	char buf[256];
+	unsigned int idx, ccnt;
+	unsigned int lcnt, ucnt;
 
 	for (idx = 0; ; idx++) {
 		ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
 		if (!ccnt) break;
 		printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
 	}
+	ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
+	ucnt = 0;
+	while (ucnt < ccnt) {
+		lcnt = 0;
+		while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
+			lcnt++;
+		}
+		printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
+		ucnt += lcnt + 1;
+	}
 }
 
 
@@ -4641,6 +5066,30 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hd
 }
 
 
+void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
+{
+	struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
+	memset(vtp, 0, sizeof(*vtp));
+	hdw->tuner_signal_stale = 0;
+	/* Note: There apparently is no replacement for VIDIOC_CROPCAP
+	   using v4l2-subdev - therefore we can't support that AT ALL right
+	   now.  (Of course, no sub-drivers seem to implement it either.
+	   But now it's a a chicken and egg problem...) */
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner,
+			     &hdw->tuner_signal_info);
+	pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
+		   " type=%u strength=%u audio=0x%x cap=0x%x"
+		   " low=%u hi=%u",
+		   vtp->type,
+		   vtp->signal, vtp->rxsubchans, vtp->capability,
+		   vtp->rangelow, vtp->rangehigh);
+
+	/* We have to do this to avoid getting into constant polling if
+	   there's nobody to answer a poll of cropcap info. */
+	hdw->cropcap_stale = 0;
+}
+
+
 unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
 {
 	return hdw->input_avail_mask;
@@ -4736,7 +5185,6 @@ int pvr2_hdw_register_access(struct pvr2
 			     int setFl, u64 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	struct pvr2_i2c_client *cp;
 	struct v4l2_dbg_register req;
 	int stat = 0;
 	int okFl = 0;
@@ -4746,21 +5194,9 @@ int pvr2_hdw_register_access(struct pvr2
 	req.match = *match;
 	req.reg = reg_id;
 	if (setFl) req.val = *val_ptr;
-	mutex_lock(&hdw->i2c_list_lock); do {
-		list_for_each_entry(cp, &hdw->i2c_clients, list) {
-			if (!v4l2_chip_match_i2c_client(
-				    cp->client,
-				    &req.match)) {
-				continue;
-			}
-			stat = pvr2_i2c_client_cmd(
-				cp,(setFl ? VIDIOC_DBG_S_REGISTER :
-				    VIDIOC_DBG_G_REGISTER),&req);
-			if (!setFl) *val_ptr = req.val;
-			okFl = !0;
-			break;
-		}
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
+	/* It would be nice to know if a sub-device answered the request */
+	v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
+	if (!setFl) *val_ptr = req.val;
 	if (okFl) {
 		return stat;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.h	2009-06-09 23:05:27.000000000 -0400
@@ -132,6 +132,9 @@ unsigned long pvr2_hdw_get_sn(struct pvr
 /* Retrieve bus location info of device */
 const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
 
+/* Retrieve per-instance string identifier for this specific device */
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
+
 /* Called when hardware has been unplugged */
 void pvr2_hdw_disconnect(struct pvr2_hdw *);
 
@@ -236,8 +239,7 @@ void pvr2_hdw_v4l_store_minor_number(str
 				     enum pvr2_v4l_type index,int);
 
 /* Direct read/write access to chip's registers:
-   match_type - how to interpret match_chip (e.g. driver ID, i2c address)
-   match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
+   match - specify criteria to identify target chip (this is a v4l dbg struct)
    reg_id  - register number to access
    setFl   - true to set the register, false to read it
    val_ptr - storage location for source / result. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/mutex.h>
 #include "pvrusb2-hdw.h"
 #include "pvrusb2-io.h"
+#include <media/v4l2-device.h>
 #include <media/cx2341x.h>
 #include "pvrusb2-devattr.h"
 
@@ -57,8 +58,6 @@
 #define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
 #define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
 
-struct pvr2_decoder;
-
 typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
 typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
 typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int);
@@ -139,22 +138,6 @@ struct pvr2_ctrl {
 };
 
 
-struct pvr2_decoder_ctrl {
-	void *ctxt;
-	void (*detach)(void *);
-	void (*enable)(void *,int);
-	void (*force_reset)(void *);
-};
-
-#define PVR2_I2C_PEND_DETECT  0x01  /* Need to detect a client type */
-#define PVR2_I2C_PEND_CLIENT  0x02  /* Client needs a specific update */
-#define PVR2_I2C_PEND_REFRESH 0x04  /* Client has specific pending bits */
-#define PVR2_I2C_PEND_STALE   0x08  /* Broadcast pending bits */
-
-#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
-			   PVR2_I2C_PEND_CLIENT |\
-			   PVR2_I2C_PEND_REFRESH |\
-			   PVR2_I2C_PEND_STALE)
 
 /* Disposition of firmware1 loading situation */
 #define FW1_STATE_UNKNOWN 0
@@ -179,6 +162,8 @@ struct pvr2_hdw {
 	struct usb_device *usb_dev;
 	struct usb_interface *usb_intf;
 
+	/* Our handle into the v4l2 sub-device architecture */
+	struct v4l2_device v4l2_dev;
 	/* Device description, anything that must adjust behavior based on
 	   device specific info will use information held here. */
 	const struct pvr2_device_desc *hdw_desc;
@@ -186,7 +171,6 @@ struct pvr2_hdw {
 	/* Kernel worker thread handling */
 	struct workqueue_struct *workqueue;
 	struct work_struct workpoll;     /* Update driver state */
-	struct work_struct worki2csync;  /* Update i2c clients */
 
 	/* Video spigot */
 	struct pvr2_stream *vid_stream;
@@ -195,20 +179,26 @@ struct pvr2_hdw {
 	struct mutex big_lock_mutex;
 	int big_lock_held;  /* For debugging */
 
+	/* This is a simple string which identifies the instance of this
+	   driver.  It is unique within the set of existing devices, but
+	   there is no attempt to keep the name consistent with the same
+	   physical device each time. */
 	char name[32];
 
+	/* This is a simple string which identifies the physical device
+	   instance itself - if possible.  (If not possible, then it is
+	   based on the specific driver instance, similar to name above.)
+	   The idea here is that userspace might hopefully be able to use
+	   this recognize specific tuners.  It will encode a serial number,
+	   if available. */
+	char identifier[32];
+
 	/* I2C stuff */
 	struct i2c_adapter i2c_adap;
 	struct i2c_algorithm i2c_algo;
 	pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
 	int i2c_cx25840_hack_state;
 	int i2c_linked;
-	unsigned int i2c_pend_types;    /* Which types of update are needed */
-	unsigned long i2c_pend_mask;    /* Change bits we need to scan */
-	unsigned long i2c_stale_mask;   /* Pending broadcast change bits */
-	unsigned long i2c_active_mask;  /* All change bits currently in use */
-	struct list_head i2c_clients;
-	struct mutex i2c_list_lock;
 
 	/* Frequency table */
 	unsigned int freqTable[FREQTABLE_SIZE];
@@ -275,6 +265,7 @@ struct pvr2_hdw {
 	wait_queue_head_t state_wait_data;
 
 
+	int force_dirty;        /* consider all controls dirty if true */
 	int flag_ok;            /* device in known good state */
 	int flag_disconnected;  /* flag_ok == 0 due to disconnect */
 	int flag_init_ok;       /* true if structure is fully initialized */
@@ -283,17 +274,13 @@ struct pvr2_hdw {
 	int flag_decoder_missed;/* We've noticed missing decoder */
 	int flag_tripped;       /* Indicates overall failure to start */
 
-	struct pvr2_decoder_ctrl *decoder_ctrl;
+	unsigned int decoder_client_id;
 
 	// CPU firmware info (used to help find / save firmware data)
 	char *fw_buffer;
 	unsigned int fw_size;
 	int fw_cpu_flag; /* True if we are dealing with the CPU */
 
-	// True if there is a request to trigger logging of state in each
-	// module.
-	int log_requested;
-
 	/* Tuner / frequency control stuff */
 	unsigned int tuner_type;
 	int tuner_updated;
@@ -391,7 +378,8 @@ struct pvr2_hdw {
 
 /* This function gets the current frequency */
 unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
-void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *);
+
+void pvr2_hdw_status_poll(struct pvr2_hdw *);
 
 #endif /* __PVRUSB2_HDW_INTERNAL_H */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,113 +0,0 @@
-/*
- *
- *
- *  Copyright (C) 2005 Mike Isely <isely@pobox.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
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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 "pvrusb2-i2c-core.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-audio.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-wm8775.h"
-
-#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-
-#define OP_STANDARD 0
-#define OP_AUDIOMODE 1
-#define OP_BCSH 2
-#define OP_VOLUME 3
-#define OP_FREQ 4
-#define OP_AUDIORATE 5
-#define OP_CROP 6
-#define OP_SIZE 7
-#define OP_LOG 8
-
-static const struct pvr2_i2c_op * const ops[] = {
-	[OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
-	[OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
-	[OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
-	[OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
-	[OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
-	[OP_CROP] = &pvr2_i2c_op_v4l2_crop,
-	[OP_SIZE] = &pvr2_i2c_op_v4l2_size,
-	[OP_LOG] = &pvr2_i2c_op_v4l2_log,
-};
-
-void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
-	int id;
-	id = cp->client->driver->id;
-	cp->ctl_mask = ((1 << OP_STANDARD) |
-			(1 << OP_AUDIOMODE) |
-			(1 << OP_BCSH) |
-			(1 << OP_VOLUME) |
-			(1 << OP_FREQ) |
-			(1 << OP_CROP) |
-			(1 << OP_SIZE) |
-			(1 << OP_LOG));
-	cp->status_poll = pvr2_v4l2_cmd_status_poll;
-
-	if (id == I2C_DRIVERID_MSP3400) {
-		if (pvr2_i2c_msp3400_setup(hdw,cp)) {
-			return;
-		}
-	}
-	if (id == I2C_DRIVERID_TUNER) {
-		if (pvr2_i2c_tuner_setup(hdw,cp)) {
-			return;
-		}
-	}
-	if (id == I2C_DRIVERID_CX25840) {
-		if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
-			return;
-		}
-	}
-	if (id == I2C_DRIVERID_WM8775) {
-		if (pvr2_i2c_wm8775_setup(hdw,cp)) {
-			return;
-		}
-	}
-	if (id == I2C_DRIVERID_SAA711X) {
-		if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
-			return;
-		}
-	}
-}
-
-
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
-{
-	if (idx >= ARRAY_SIZE(ops))
-		return NULL;
-	return ops[idx];
-}
-
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 75 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,322 +0,0 @@
-/*
- *
- *
- *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *  Copyright (C) 2004 Aurelien Alleaume <slts@free.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
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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 "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-static void set_standard(struct pvr2_hdw *hdw)
-{
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
-
-	if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
-		pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL);
-	} else {
-		v4l2_std_id vs;
-		vs = hdw->std_mask_cur;
-		pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
-	}
-	hdw->tuner_signal_stale = !0;
-	hdw->cropcap_stale = !0;
-}
-
-
-static int check_standard(struct pvr2_hdw *hdw)
-{
-	return (hdw->input_dirty != 0) || (hdw->std_dirty != 0);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
-	.check = check_standard,
-	.update = set_standard,
-	.name = "v4l2_standard",
-};
-
-
-static void set_bcsh(struct pvr2_hdw *hdw)
-{
-	struct v4l2_control ctrl;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
-		   " b=%d c=%d s=%d h=%d",
-		   hdw->brightness_val,hdw->contrast_val,
-		   hdw->saturation_val,hdw->hue_val);
-	memset(&ctrl,0,sizeof(ctrl));
-	ctrl.id = V4L2_CID_BRIGHTNESS;
-	ctrl.value = hdw->brightness_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_CONTRAST;
-	ctrl.value = hdw->contrast_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_SATURATION;
-	ctrl.value = hdw->saturation_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_HUE;
-	ctrl.value = hdw->hue_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_bcsh(struct pvr2_hdw *hdw)
-{
-	return (hdw->brightness_dirty ||
-		hdw->contrast_dirty ||
-		hdw->saturation_dirty ||
-		hdw->hue_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
-	.check = check_bcsh,
-	.update = set_bcsh,
-	.name = "v4l2_bcsh",
-};
-
-
-static void set_volume(struct pvr2_hdw *hdw)
-{
-	struct v4l2_control ctrl;
-	pvr2_trace(PVR2_TRACE_CHIPS,
-		   "i2c v4l2 set_volume"
-		   "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
-		   hdw->volume_val,
-		   hdw->balance_val,
-		   hdw->bass_val,
-		   hdw->treble_val,
-		   hdw->mute_val);
-	memset(&ctrl,0,sizeof(ctrl));
-	ctrl.id = V4L2_CID_AUDIO_MUTE;
-	ctrl.value = hdw->mute_val ? 1 : 0;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_AUDIO_VOLUME;
-	ctrl.value = hdw->volume_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_AUDIO_BALANCE;
-	ctrl.value = hdw->balance_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_AUDIO_BASS;
-	ctrl.value = hdw->bass_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-	ctrl.id = V4L2_CID_AUDIO_TREBLE;
-	ctrl.value = hdw->treble_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_volume(struct pvr2_hdw *hdw)
-{
-	return (hdw->volume_dirty ||
-		hdw->balance_dirty ||
-		hdw->bass_dirty ||
-		hdw->treble_dirty ||
-		hdw->mute_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
-	.check = check_volume,
-	.update = set_volume,
-	.name = "v4l2_volume",
-};
-
-
-static void set_audiomode(struct pvr2_hdw *hdw)
-{
-	struct v4l2_tuner vt;
-	memset(&vt,0,sizeof(vt));
-	vt.audmode = hdw->audiomode_val;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt);
-}
-
-
-static int check_audiomode(struct pvr2_hdw *hdw)
-{
-	return (hdw->input_dirty ||
-		hdw->audiomode_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = {
-	.check = check_audiomode,
-	.update = set_audiomode,
-	.name = "v4l2_audiomode",
-};
-
-
-static void set_frequency(struct pvr2_hdw *hdw)
-{
-	unsigned long fv;
-	struct v4l2_frequency freq;
-	fv = pvr2_hdw_get_cur_freq(hdw);
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
-	if (hdw->tuner_signal_stale) {
-		pvr2_i2c_core_status_poll(hdw);
-	}
-	memset(&freq,0,sizeof(freq));
-	if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
-		// ((fv * 1000) / 62500)
-		freq.frequency = (fv * 2) / 125;
-	} else {
-		freq.frequency = fv / 62500;
-	}
-	/* tuner-core currently doesn't seem to care about this, but
-	   let's set it anyway for completeness. */
-	if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
-		freq.type = V4L2_TUNER_RADIO;
-	} else {
-		freq.type = V4L2_TUNER_ANALOG_TV;
-	}
-	freq.tuner = 0;
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
-}
-
-
-static int check_frequency(struct pvr2_hdw *hdw)
-{
-	return hdw->freqDirty != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
-	.check = check_frequency,
-	.update = set_frequency,
-	.name = "v4l2_freq",
-};
-
-
-static void set_size(struct pvr2_hdw *hdw)
-{
-	struct v4l2_format fmt;
-
-	memset(&fmt,0,sizeof(fmt));
-
-	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	fmt.fmt.pix.width = hdw->res_hor_val;
-	fmt.fmt.pix.height = hdw->res_ver_val;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
-			   fmt.fmt.pix.width,fmt.fmt.pix.height);
-
-	pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
-}
-
-
-static int check_size(struct pvr2_hdw *hdw)
-{
-	return (hdw->res_hor_dirty || hdw->res_ver_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
-	.check = check_size,
-	.update = set_size,
-	.name = "v4l2_size",
-};
-
-
-static void set_crop(struct pvr2_hdw *hdw)
-{
-	struct v4l2_crop crop;
-
-	memset(&crop, 0, sizeof crop);
-	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	crop.c.left = hdw->cropl_val;
-	crop.c.top = hdw->cropt_val;
-	crop.c.height = hdw->croph_val;
-	crop.c.width = hdw->cropw_val;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,
-		   "i2c v4l2 set_crop crop=%d:%d:%d:%d",
-		   crop.c.width, crop.c.height, crop.c.left, crop.c.top);
-
-	pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
-}
-
-static int check_crop(struct pvr2_hdw *hdw)
-{
-	return (hdw->cropl_dirty || hdw->cropt_dirty ||
-		hdw->cropw_dirty || hdw->croph_dirty);
-}
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
-	.check = check_crop,
-	.update = set_crop,
-	.name = "v4l2_crop",
-};
-
-
-static void do_log(struct pvr2_hdw *hdw)
-{
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
-	pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
-
-}
-
-
-static int check_log(struct pvr2_hdw *hdw)
-{
-	return hdw->log_requested != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
-	.check = check_log,
-	.update = do_log,
-	.name = "v4l2_log",
-};
-
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
-{
-	pvr2_i2c_client_cmd(cp,
-			    (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
-}
-
-
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
-{
-	int stat;
-	struct pvr2_hdw *hdw = cp->hdw;
-	if (hdw->cropcap_stale) {
-		hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
-					   &hdw->cropcap_info);
-		if (stat == 0) {
-			/* Check was successful, so the data is no
-			   longer considered stale. */
-			hdw->cropcap_stale = 0;
-		}
-	}
-	pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
-}
-
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 70 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- *
- *
- *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *  Copyright (C) 2004 Aurelien Alleaume <slts@free.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
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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 __PVRUSB2_CMD_V4L2_H
-#define __PVRUSB2_CMD_V4L2_H
-
-#include "pvrusb2-i2c-core.h"
-
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
-
-#endif /* __PVRUSB2_CMD_V4L2_H */
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 70 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,6 +18,7 @@
  *
  */
 
+#include <linux/i2c.h>
 #include "pvrusb2-i2c-core.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
@@ -29,8 +30,7 @@
 /*
 
   This module attempts to implement a compliant I2C adapter for the pvrusb2
-  device.  By doing this we can then make use of existing functionality in
-  V4L (e.g. tuner.c) rather than rolling our own.
+  device.
 
 */
 
@@ -42,10 +42,6 @@ static int ir_mode[PVR_NUM] = { [0 ... P
 module_param_array(ir_mode, int, NULL, 0444);
 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
 
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
-					     unsigned int detail,
-					     char *buf,unsigned int maxlen);
-
 static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
 			  u8 i2c_addr,      /* I2C address we're talking to */
 			  u8 *data,         /* Data to write */
@@ -524,417 +520,6 @@ static u32 pvr2_i2c_functionality(struct
 	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
 }
 
-static int pvr2_i2c_core_singleton(struct i2c_client *cp,
-				   unsigned int cmd,void *arg)
-{
-	int stat;
-	if (!cp) return -EINVAL;
-	if (!(cp->driver)) return -EINVAL;
-	if (!(cp->driver->command)) return -EINVAL;
-	if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
-	stat = cp->driver->command(cp,cmd,arg);
-	module_put(cp->driver->driver.owner);
-	return stat;
-}
-
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
-{
-	int stat;
-	if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
-		char buf[100];
-		unsigned int cnt;
-		cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
-					       buf,sizeof(buf));
-		pvr2_trace(PVR2_TRACE_I2C_CMD,
-			   "i2c COMMAND (code=%u 0x%x) to %.*s",
-			   cmd,cmd,cnt,buf);
-	}
-	stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
-	if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
-		char buf[100];
-		unsigned int cnt;
-		cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
-					       buf,sizeof(buf));
-		pvr2_trace(PVR2_TRACE_I2C_CMD,
-			   "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
-	}
-	return stat;
-}
-
-int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
-{
-	struct pvr2_i2c_client *cp, *ncp;
-	int stat = -EINVAL;
-
-	if (!hdw) return stat;
-
-	mutex_lock(&hdw->i2c_list_lock);
-	list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
-		if (!cp->recv_enable) continue;
-		mutex_unlock(&hdw->i2c_list_lock);
-		stat = pvr2_i2c_client_cmd(cp,cmd,arg);
-		mutex_lock(&hdw->i2c_list_lock);
-	}
-	mutex_unlock(&hdw->i2c_list_lock);
-	return stat;
-}
-
-
-static int handler_check(struct pvr2_i2c_client *cp)
-{
-	struct pvr2_i2c_handler *hp = cp->handler;
-	if (!hp) return 0;
-	if (!hp->func_table->check) return 0;
-	return hp->func_table->check(hp->func_data) != 0;
-}
-
-#define BUFSIZE 500
-
-
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
-{
-	struct pvr2_i2c_client *cp;
-	mutex_lock(&hdw->i2c_list_lock); do {
-		struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
-		memset(vtp,0,sizeof(*vtp));
-		list_for_each_entry(cp, &hdw->i2c_clients, list) {
-			if (!cp->detected_flag) continue;
-			if (!cp->status_poll) continue;
-			cp->status_poll(cp);
-		}
-		hdw->tuner_signal_stale = 0;
-		pvr2_trace(PVR2_TRACE_CHIPS,"i2c status poll"
-			   " type=%u strength=%u audio=0x%x cap=0x%x"
-			   " low=%u hi=%u",
-			   vtp->type,
-			   vtp->signal,vtp->rxsubchans,vtp->capability,
-			   vtp->rangelow,vtp->rangehigh);
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-
-/* Issue various I2C operations to bring chip-level drivers into sync with
-   state stored in this driver. */
-void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
-{
-	unsigned long msk;
-	unsigned int idx;
-	struct pvr2_i2c_client *cp, *ncp;
-
-	if (!hdw->i2c_linked) return;
-	if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
-		return;
-	}
-	mutex_lock(&hdw->i2c_list_lock); do {
-		pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
-		if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
-			/* One or more I2C clients have attached since we
-			   last synced.  So scan the list and identify the
-			   new clients. */
-			char *buf;
-			unsigned int cnt;
-			unsigned long amask = 0;
-			buf = kmalloc(BUFSIZE,GFP_KERNEL);
-			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
-			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
-			list_for_each_entry(cp, &hdw->i2c_clients, list) {
-				if (!cp->detected_flag) {
-					cp->ctl_mask = 0;
-					pvr2_i2c_probe(hdw,cp);
-					cp->detected_flag = !0;
-					msk = cp->ctl_mask;
-					cnt = 0;
-					if (buf) {
-						cnt = pvr2_i2c_client_describe(
-							cp,
-							PVR2_I2C_DETAIL_ALL,
-							buf,BUFSIZE);
-					}
-					trace_i2c("Probed: %.*s",cnt,buf);
-					if (handler_check(cp)) {
-						hdw->i2c_pend_types |=
-							PVR2_I2C_PEND_CLIENT;
-					}
-					cp->pend_mask = msk;
-					hdw->i2c_pend_mask |= msk;
-					hdw->i2c_pend_types |=
-						PVR2_I2C_PEND_REFRESH;
-				}
-				amask |= cp->ctl_mask;
-			}
-			hdw->i2c_active_mask = amask;
-			if (buf) kfree(buf);
-		}
-		if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
-			/* Need to do one or more global updates.  Arrange
-			   for this to happen. */
-			unsigned long m2;
-			pvr2_trace(PVR2_TRACE_I2C_CORE,
-				   "i2c: PEND_STALE (0x%lx)",
-				   hdw->i2c_stale_mask);
-			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
-			list_for_each_entry(cp, &hdw->i2c_clients, list) {
-				m2 = hdw->i2c_stale_mask;
-				m2 &= cp->ctl_mask;
-				m2 &= ~cp->pend_mask;
-				if (m2) {
-					pvr2_trace(PVR2_TRACE_I2C_CORE,
-						   "i2c: cp=%p setting 0x%lx",
-						   cp,m2);
-					cp->pend_mask |= m2;
-				}
-			}
-			hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
-			hdw->i2c_stale_mask = 0;
-			hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
-		}
-		if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
-			/* One or more client handlers are asking for an
-			   update.  Run through the list of known clients
-			   and update each one. */
-			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
-			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
-			list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
-						 list) {
-				if (!cp->handler) continue;
-				if (!cp->handler->func_table->update) continue;
-				pvr2_trace(PVR2_TRACE_I2C_CORE,
-					   "i2c: cp=%p update",cp);
-				mutex_unlock(&hdw->i2c_list_lock);
-				cp->handler->func_table->update(
-					cp->handler->func_data);
-				mutex_lock(&hdw->i2c_list_lock);
-				/* If client's update function set some
-				   additional pending bits, account for that
-				   here. */
-				if (cp->pend_mask & ~hdw->i2c_pend_mask) {
-					hdw->i2c_pend_mask |= cp->pend_mask;
-					hdw->i2c_pend_types |=
-						PVR2_I2C_PEND_REFRESH;
-				}
-			}
-		}
-		if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
-			const struct pvr2_i2c_op *opf;
-			unsigned long pm;
-			/* Some actual updates are pending.  Walk through
-			   each update type and perform it. */
-			pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
-				   " (0x%lx)",hdw->i2c_pend_mask);
-			hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
-			pm = hdw->i2c_pend_mask;
-			hdw->i2c_pend_mask = 0;
-			for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
-				if (!(pm & msk)) continue;
-				pm &= ~msk;
-				list_for_each_entry(cp, &hdw->i2c_clients,
-						    list) {
-					if (cp->pend_mask & msk) {
-						cp->pend_mask &= ~msk;
-						cp->recv_enable = !0;
-					} else {
-						cp->recv_enable = 0;
-					}
-				}
-				opf = pvr2_i2c_get_op(idx);
-				if (!opf) continue;
-				mutex_unlock(&hdw->i2c_list_lock);
-				opf->update(hdw);
-				mutex_lock(&hdw->i2c_list_lock);
-			}
-		}
-		pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
-{
-	unsigned long msk,sm,pm;
-	unsigned int idx;
-	const struct pvr2_i2c_op *opf;
-	struct pvr2_i2c_client *cp;
-	unsigned int pt = 0;
-
-	pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
-
-	pm = hdw->i2c_active_mask;
-	sm = 0;
-	for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
-		if (!(msk & pm)) continue;
-		pm &= ~msk;
-		opf = pvr2_i2c_get_op(idx);
-		if (!opf) continue;
-		if (opf->check(hdw)) {
-			sm |= msk;
-		}
-	}
-	if (sm) pt |= PVR2_I2C_PEND_STALE;
-
-	list_for_each_entry(cp, &hdw->i2c_clients, list)
-		if (handler_check(cp))
-			pt |= PVR2_I2C_PEND_CLIENT;
-
-	if (pt) {
-		mutex_lock(&hdw->i2c_list_lock); do {
-			hdw->i2c_pend_types |= pt;
-			hdw->i2c_stale_mask |= sm;
-			hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
-		} while (0); mutex_unlock(&hdw->i2c_list_lock);
-	}
-
-	pvr2_trace(PVR2_TRACE_I2C_CORE,
-		   "i2c: types=0x%x stale=0x%lx pend=0x%lx",
-		   hdw->i2c_pend_types,
-		   hdw->i2c_stale_mask,
-		   hdw->i2c_pend_mask);
-	pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
-
-	return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
-}
-
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
-					     unsigned int detail,
-					     char *buf,unsigned int maxlen)
-{
-	unsigned int ccnt,bcnt;
-	int spcfl = 0;
-	const struct pvr2_i2c_op *opf;
-
-	ccnt = 0;
-	if (detail & PVR2_I2C_DETAIL_DEBUG) {
-		bcnt = scnprintf(buf,maxlen,
-				 "ctxt=%p ctl_mask=0x%lx",
-				 cp,cp->ctl_mask);
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		spcfl = !0;
-	}
-	bcnt = scnprintf(buf,maxlen,
-			 "%s%s @ 0x%x",
-			 (spcfl ? " " : ""),
-			 cp->client->name,
-			 cp->client->addr);
-	ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-	if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
-	    cp->handler && cp->handler->func_table->describe) {
-		bcnt = scnprintf(buf,maxlen," (");
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		bcnt = cp->handler->func_table->describe(
-			cp->handler->func_data,buf,maxlen);
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		bcnt = scnprintf(buf,maxlen,")");
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-	}
-	if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
-		unsigned int idx;
-		unsigned long msk,sm;
-
-		bcnt = scnprintf(buf,maxlen," [");
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		sm = 0;
-		spcfl = 0;
-		for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
-			if (!(cp->ctl_mask & msk)) continue;
-			opf = pvr2_i2c_get_op(idx);
-			if (opf) {
-				bcnt = scnprintf(buf,maxlen,"%s%s",
-						 spcfl ? " " : "",
-						 opf->name);
-				ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-				spcfl = !0;
-			} else {
-				sm |= msk;
-			}
-		}
-		if (sm) {
-			bcnt = scnprintf(buf,maxlen,"%s%lx",
-					 idx != 0 ? " " : "",sm);
-			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		}
-		bcnt = scnprintf(buf,maxlen,"]");
-		ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-	}
-	return ccnt;
-}
-
-unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
-			     char *buf,unsigned int maxlen)
-{
-	unsigned int ccnt,bcnt;
-	struct pvr2_i2c_client *cp;
-	ccnt = 0;
-	mutex_lock(&hdw->i2c_list_lock); do {
-		list_for_each_entry(cp, &hdw->i2c_clients, list) {
-			bcnt = pvr2_i2c_client_describe(
-				cp,
-				(PVR2_I2C_DETAIL_HANDLER|
-				 PVR2_I2C_DETAIL_CTLMASK),
-				buf,maxlen);
-			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-			bcnt = scnprintf(buf,maxlen,"\n");
-			ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
-		}
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
-	return ccnt;
-}
-
-static int pvr2_i2c_attach_inform(struct i2c_client *client)
-{
-	struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
-	struct pvr2_i2c_client *cp;
-	int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
-	cp = kzalloc(sizeof(*cp),GFP_KERNEL);
-	trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
-		  client->name,
-		  client->addr,cp);
-	if (!cp) return -ENOMEM;
-	cp->hdw = hdw;
-	INIT_LIST_HEAD(&cp->list);
-	cp->client = client;
-	mutex_lock(&hdw->i2c_list_lock); do {
-		hdw->cropcap_stale = !0;
-		list_add_tail(&cp->list,&hdw->i2c_clients);
-		hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
-	if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
-	return 0;
-}
-
-static int pvr2_i2c_detach_inform(struct i2c_client *client)
-{
-	struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
-	struct pvr2_i2c_client *cp, *ncp;
-	unsigned long amask = 0;
-	int foundfl = 0;
-	mutex_lock(&hdw->i2c_list_lock); do {
-		hdw->cropcap_stale = !0;
-		list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
-			if (cp->client == client) {
-				trace_i2c("pvr2_i2c_detach"
-					  " [client=%s @ 0x%x ctxt=%p]",
-					  client->name,
-					  client->addr,cp);
-				if (cp->handler &&
-				    cp->handler->func_table->detach) {
-					cp->handler->func_table->detach(
-						cp->handler->func_data);
-				}
-				list_del(&cp->list);
-				kfree(cp);
-				foundfl = !0;
-				continue;
-			}
-			amask |= cp->ctl_mask;
-		}
-		hdw->i2c_active_mask = amask;
-	} while (0); mutex_unlock(&hdw->i2c_list_lock);
-	if (!foundfl) {
-		trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
-			  client->name,
-			  client->addr);
-	}
-	return 0;
-}
-
 static struct i2c_algorithm pvr2_i2c_algo_template = {
 	.master_xfer   = pvr2_i2c_xfer,
 	.functionality = pvr2_i2c_functionality,
@@ -942,10 +527,8 @@ static struct i2c_algorithm pvr2_i2c_alg
 
 static struct i2c_adapter pvr2_i2c_adap_template = {
 	.owner         = THIS_MODULE,
-	.class	   = I2C_CLASS_TV_ANALOG,
+	.class	       = 0,
 	.id            = I2C_HW_B_BT848,
-	.client_register = pvr2_i2c_attach_inform,
-	.client_unregister = pvr2_i2c_detach_inform,
 };
 
 
@@ -1009,12 +592,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw
 	hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
 	hdw->i2c_adap.algo = &hdw->i2c_algo;
 	hdw->i2c_adap.algo_data = hdw;
-	hdw->i2c_pend_mask = 0;
-	hdw->i2c_stale_mask = 0;
-	hdw->i2c_active_mask = 0;
-	INIT_LIST_HEAD(&hdw->i2c_clients);
-	mutex_init(&hdw->i2c_list_lock);
 	hdw->i2c_linked = !0;
+	i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
 	i2c_add_adapter(&hdw->i2c_adap);
 	if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
 		/* Probe for a different type of IR receiver on this
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,68 +20,13 @@
 #ifndef __PVRUSB2_I2C_CORE_H
 #define __PVRUSB2_I2C_CORE_H
 
-#include <linux/list.h>
-#include <linux/i2c.h>
-
 struct pvr2_hdw;
-struct pvr2_i2c_client;
-struct pvr2_i2c_handler;
-struct pvr2_i2c_handler_functions;
-struct pvr2_i2c_op;
-struct pvr2_i2c_op_functions;
-
-struct pvr2_i2c_client {
-	struct i2c_client *client;
-	struct pvr2_i2c_handler *handler;
-	struct list_head list;
-	struct pvr2_hdw *hdw;
-	int detected_flag;
-	int recv_enable;
-	unsigned long pend_mask;
-	unsigned long ctl_mask;
-	void (*status_poll)(struct pvr2_i2c_client *);
-};
-
-struct pvr2_i2c_handler {
-	void *func_data;
-	const struct pvr2_i2c_handler_functions *func_table;
-};
-
-struct pvr2_i2c_handler_functions {
-	void (*detach)(void *);
-	int (*check)(void *);
-	void (*update)(void *);
-	unsigned int (*describe)(void *,char *,unsigned int);
-};
-
-struct pvr2_i2c_op {
-	int (*check)(struct pvr2_hdw *);
-	void (*update)(struct pvr2_hdw *);
-	const char *name;
-};
 
 void pvr2_i2c_core_init(struct pvr2_hdw *);
 void pvr2_i2c_core_done(struct pvr2_hdw *);
 
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
-int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
-void pvr2_i2c_core_sync(struct pvr2_hdw *);
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
-unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
-#define PVR2_I2C_DETAIL_DEBUG   0x0001
-#define PVR2_I2C_DETAIL_HANDLER 0x0002
-#define PVR2_I2C_DETAIL_CTLMASK 0x0004
-#define PVR2_I2C_DETAIL_ALL (\
-	PVR2_I2C_DETAIL_DEBUG |\
-	PVR2_I2C_DETAIL_HANDLER |\
-	PVR2_I2C_DETAIL_CTLMASK)
-
-void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
 
-#endif /* __PVRUSB2_I2C_CORE_H */
+#endif /* __PVRUSB2_I2C_ADAPTER_H */
 
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-main.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,10 +137,10 @@ static int __init pvr_init(void)
 	ret = usb_register(&pvr_driver);
 
 	if (ret == 0)
-		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
 		       DRIVER_DESC "\n");
 	if (pvrusb2_debug)
-		printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n",
+		printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
 		       pvrusb2_debug,pvrusb2_debug);
 
 	pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,14 +153,16 @@ static ssize_t show_def(struct device *c
 	struct pvr2_sysfs_ctl_item *cip;
 	int val;
 	int ret;
+	unsigned int cnt = 0;
 	cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
 	ret = pvr2_ctrl_get_def(cip->cptr, &val);
-	pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %d, stat=%d",
-			 cip->chptr, cip->ctl_id, val, ret);
-	if (ret < 0) {
-		return ret;
-	}
-	return scnprintf(buf, PAGE_SIZE, "%d\n", val);
+	if (ret < 0) return ret;
+	ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
+				     buf, PAGE_SIZE - 1, &cnt);
+	pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
+			 cip->chptr, cip->ctl_id, cnt, buf, val);
+	buf[cnt] = '\n';
+	return cnt + 1;
 }
 
 static ssize_t show_val_norm(struct device *class_dev,
@@ -627,16 +629,8 @@ static void class_dev_create(struct pvr2
 	pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
 
 	class_dev->class = &class_ptr->class;
-	if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
-		dev_set_name(class_dev, "sn-%lu",
-			 pvr2_hdw_get_sn(sfp->channel.hdw));
-	} else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
-		dev_set_name(class_dev, "unit-%c",
-			 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
-	} else {
-		kfree(class_dev);
-		return;
-	}
+	dev_set_name(class_dev, "%s",
+		     pvr2_hdw_get_device_identifier(sfp->channel.hdw));
 
 	class_dev->parent = &usb_dev->dev;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,120 +0,0 @@
-/*
- *
- *
- *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *  Copyright (C) 2004 Aurelien Alleaume <slts@free.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
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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 "pvrusb2.h"
-#include "pvrusb2-util.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-
-struct pvr2_tuner_handler {
-	struct pvr2_hdw *hdw;
-	struct pvr2_i2c_client *client;
-	struct pvr2_i2c_handler i2c_handler;
-	int type_update_fl;
-};
-
-
-static void set_type(struct pvr2_tuner_handler *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	struct tuner_setup setup;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
-	if (((int)(hdw->tuner_type)) < 0) return;
-
-	setup.addr = ADDR_UNSET;
-	setup.type = hdw->tuner_type;
-	setup.mode_mask = T_RADIO | T_ANALOG_TV;
-	/* We may really want mode_mask to be T_ANALOG_TV for now */
-	pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
-	ctxt->type_update_fl = 0;
-}
-
-
-static int tuner_check(struct pvr2_tuner_handler *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	if (hdw->tuner_updated) ctxt->type_update_fl = !0;
-	return ctxt->type_update_fl != 0;
-}
-
-
-static void tuner_update(struct pvr2_tuner_handler *ctxt)
-{
-	if (ctxt->type_update_fl) set_type(ctxt);
-}
-
-
-static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
-{
-	ctxt->client->handler = NULL;
-	kfree(ctxt);
-}
-
-
-static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
-{
-	return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
-}
-
-
-static const struct pvr2_i2c_handler_functions tuner_funcs = {
-	.detach = (void (*)(void *))pvr2_tuner_detach,
-	.check = (int (*)(void *))tuner_check,
-	.update = (void (*)(void *))tuner_update,
-	.describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
-};
-
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
-	struct pvr2_tuner_handler *ctxt;
-	if (cp->handler) return 0;
-
-	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
-	if (!ctxt) return 0;
-
-	ctxt->i2c_handler.func_data = ctxt;
-	ctxt->i2c_handler.func_table = &tuner_funcs;
-	ctxt->type_update_fl = !0;
-	ctxt->client = cp;
-	ctxt->hdw = hdw;
-	cp->handler = &ctxt->i2c_handler;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
-		   cp->client->addr);
-	return !0;
-}
-
-
-
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 70 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-tuner.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- *
- *
- *  Copyright (C) 2005 Mike Isely <isely@pobox.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
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You 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 __PVRUSB2_TUNER_H
-#define __PVRUSB2_TUNER_H
-
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
-#endif /* __PVRUSB2_TUNER_H */
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 70 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-v4l2.c	2009-06-09 23:05:27.000000000 -0400
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capabi
 	.card           = "Hauppauge WinTV pvr-usb2",
 	.bus_info       = "usb",
 	.version        = KERNEL_VERSION(0,8,0),
-	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
 			   V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
 			   V4L2_CAP_READWRITE),
 	.reserved       = {0,0,0,0}
@@ -952,10 +952,6 @@ static long pvr2_v4l2_ioctl(struct file
 			   unsigned int cmd, unsigned long arg)
 {
 
-/* Temporary hack : use ivtv api until a v4l2 one is available. */
-#define IVTV_IOC_G_CODEC        0xFFEE7703
-#define IVTV_IOC_S_CODEC        0xFFEE7704
-	if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
 	return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
 }
 
@@ -1268,8 +1264,9 @@ static void pvr2_v4l2_dev_init(struct pv
 		dip->minor_type = pvr2_v4l_type_video;
 		nr_ptr = video_nr;
 		if (!dip->stream) {
-			err("Failed to set up pvrusb2 v4l video dev"
-			    " due to missing stream instance");
+			pr_err(KBUILD_MODNAME
+				": Failed to set up pvrusb2 v4l video dev"
+				" due to missing stream instance\n");
 			return;
 		}
 		break;
@@ -1286,8 +1283,8 @@ static void pvr2_v4l2_dev_init(struct pv
 		break;
 	default:
 		/* Bail out (this should be impossible) */
-		err("Failed to set up pvrusb2 v4l dev"
-		    " due to unrecognized config");
+		pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+		    " due to unrecognized config\n");
 		return;
 	}
 
@@ -1303,7 +1300,8 @@ static void pvr2_v4l2_dev_init(struct pv
 				   dip->v4l_type, mindevnum) < 0) &&
 	    (video_register_device(&dip->devbase,
 				   dip->v4l_type, -1) < 0)) {
-		err("Failed to register pvrusb2 v4l device");
+		pr_err(KBUILD_MODNAME
+			": Failed to register pvrusb2 v4l device\n");
 	}
 
 	printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,7 @@
 */
 
 #include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
+
 
 
 #include "pvrusb2-hdw-internal.h"
@@ -39,15 +39,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-struct pvr2_v4l_decoder {
-	struct pvr2_i2c_handler handler;
-	struct pvr2_decoder_ctrl ctrl;
-	struct pvr2_i2c_client *client;
-	struct pvr2_hdw *hdw;
-	unsigned long stale_mask;
-};
-
-
 struct routing_scheme {
 	const int *def;
 	unsigned int cnt;
@@ -63,190 +54,51 @@ static const int routing_scheme0[] = {
 	[PVR2_CVAL_INPUT_SVIDEO] =  SAA7115_SVIDEO2,
 };
 
+static const int routing_scheme1[] = {
+	[PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
+	[PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
+	[PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
+	[PVR2_CVAL_INPUT_SVIDEO] =  SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
+};
+
 static const struct routing_scheme routing_schemes[] = {
 	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
 		.def = routing_scheme0,
 		.cnt = ARRAY_SIZE(routing_scheme0),
 	},
+	[PVR2_ROUTING_SCHEME_ONAIR] = {
+		.def = routing_scheme1,
+		.cnt = ARRAY_SIZE(routing_scheme1),
+	},
 };
 
-static void set_input(struct pvr2_v4l_decoder *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	struct v4l2_routing route;
-	const struct routing_scheme *sp;
-	unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
-
-	if ((sid < ARRAY_SIZE(routing_schemes)) &&
-	    ((sp = routing_schemes + sid) != NULL) &&
-	    (hdw->input_val >= 0) &&
-	    (hdw->input_val < sp->cnt)) {
-		route.input = sp->def[hdw->input_val];
-	} else {
-		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-			   "*** WARNING *** i2c v4l2 set_input:"
-			   " Invalid routing scheme (%u) and/or input (%d)",
-			   sid,hdw->input_val);
-		return;
-	}
-
-	route.output = 0;
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_decoder *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_decoder *ctxt)
-{
-	u32 val;
-	struct pvr2_hdw *hdw = ctxt->hdw;
-
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
-		   hdw->srate_val);
-	switch (hdw->srate_val) {
-	default:
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
-		val = 48000;
-		break;
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
-		val = 44100;
-		break;
-	case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
-		val = 32000;
-		break;
-	}
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_decoder *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_decoder_ops {
-	void (*update)(struct pvr2_v4l_decoder *);
-	int (*check)(struct pvr2_v4l_decoder *);
-};
-
-
-static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
-	{ .update = set_input, .check = check_input},
-	{ .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
-{
-	ctxt->client->handler = NULL;
-	pvr2_hdw_set_decoder(ctxt->hdw,NULL);
-	kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_decoder *ctxt)
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
-	unsigned long msk;
-	unsigned int idx;
+	if (hdw->input_dirty || hdw->force_dirty) {
+		const struct routing_scheme *sp;
+		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+		u32 input;
 
-	for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
-		msk = 1 << idx;
-		if (ctxt->stale_mask & msk) continue;
-		if (decoder_ops[idx].check(ctxt)) {
-			ctxt->stale_mask |= msk;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+			   hdw->input_val);
+		if ((sid < ARRAY_SIZE(routing_schemes)) &&
+		    ((sp = routing_schemes + sid) != NULL) &&
+		    (hdw->input_val >= 0) &&
+		    (hdw->input_val < sp->cnt)) {
+			input = sp->def[hdw->input_val];
+		} else {
+			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+				   "*** WARNING *** subdev v4l2 set_input:"
+				   " Invalid routing scheme (%u)"
+				   " and/or input (%d)",
+				   sid, hdw->input_val);
+			return;
 		}
+		sd->ops->video->s_routing(sd, input, 0, 0);
 	}
-	return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_decoder *ctxt)
-{
-	unsigned long msk;
-	unsigned int idx;
-
-	for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
-		msk = 1 << idx;
-		if (!(ctxt->stale_mask & msk)) continue;
-		ctxt->stale_mask &= ~msk;
-		decoder_ops[idx].update(ctxt);
-	}
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
-	/* Attempt to query the decoder - let's see if it will answer */
-	struct v4l2_tuner vt;
-	int ret;
-
-	memset(&vt,0,sizeof(vt));
-	ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
-	return ret == 0; /* Return true if it answered */
-}
-
-
-static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
-{
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
-	pvr2_v4l2_cmd_stream(ctxt->client,fl);
 }
 
 
-static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
-{
-	return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
-	.detach = (void (*)(void *))decoder_detach,
-	.check = (int (*)(void *))decoder_check,
-	.update = (void (*)(void *))decoder_update,
-	.describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
-			       struct pvr2_i2c_client *cp)
-{
-	struct pvr2_v4l_decoder *ctxt;
-
-	if (hdw->decoder_ctrl) return 0;
-	if (cp->handler) return 0;
-	if (!decoder_detect(cp)) return 0;
-
-	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
-	if (!ctxt) return 0;
-
-	ctxt->handler.func_data = ctxt;
-	ctxt->handler.func_table = &hfuncs;
-	ctxt->ctrl.ctxt = ctxt;
-	ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
-	ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
-	ctxt->client = cp;
-	ctxt->hdw = hdw;
-	ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
-	pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
-	cp->handler = &ctxt->handler;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
-		   cp->client->addr);
-	return !0;
-}
-
-
-
-
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
   *** Local Variables: ***
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h	2009-06-09 23:05:27.000000000 -0400
@@ -32,11 +32,8 @@
 */
 
 
-
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
 
 #endif /* __PVRUSB2_VIDEO_V4L_H */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,6 @@
 */
 
 #include "pvrusb2-wm8775.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
 
 
 #include "pvrusb2-hdw-internal.h"
@@ -37,128 +36,29 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-struct pvr2_v4l_wm8775 {
-	struct pvr2_i2c_handler handler;
-	struct pvr2_i2c_client *client;
-	struct pvr2_hdw *hdw;
-	unsigned long stale_mask;
-};
-
-
-static void set_input(struct pvr2_v4l_wm8775 *ctxt)
-{
-	struct v4l2_routing route;
-	struct pvr2_hdw *hdw = ctxt->hdw;
-
-	memset(&route,0,sizeof(route));
-
-	switch(hdw->input_val) {
-	case PVR2_CVAL_INPUT_RADIO:
-		route.input = 1;
-		break;
-	default:
-		/* All other cases just use the second input */
-		route.input = 2;
-		break;
-	}
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
-		   hdw->input_val,route.input);
-
-	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-static int check_input(struct pvr2_v4l_wm8775 *ctxt)
-{
-	struct pvr2_hdw *hdw = ctxt->hdw;
-	return hdw->input_dirty != 0;
-}
-
-
-struct pvr2_v4l_wm8775_ops {
-	void (*update)(struct pvr2_v4l_wm8775 *);
-	int (*check)(struct pvr2_v4l_wm8775 *);
-};
-
-
-static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
-	{ .update = set_input, .check = check_input},
-};
-
-
-static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
-				     char *buf,unsigned int cnt)
-{
-	return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
-}
-
-
-static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
-{
-	ctxt->client->handler = NULL;
-	kfree(ctxt);
-}
-
-
-static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 {
-	unsigned long msk;
-	unsigned int idx;
+	if (hdw->input_dirty || hdw->force_dirty) {
+		u32 input;
 
-	for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
-		msk = 1 << idx;
-		if (ctxt->stale_mask & msk) continue;
-		if (wm8775_ops[idx].check(ctxt)) {
-			ctxt->stale_mask |= msk;
+		switch (hdw->input_val) {
+		case PVR2_CVAL_INPUT_RADIO:
+			input = 1;
+			break;
+		default:
+			/* All other cases just use the second input */
+			input = 2;
+			break;
 		}
-	}
-	return ctxt->stale_mask != 0;
-}
-
-
-static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
-{
-	unsigned long msk;
-	unsigned int idx;
+		pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
+			   " set_input(val=%d route=0x%x)",
+			   hdw->input_val, input);
 
-	for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
-		msk = 1 << idx;
-		if (!(ctxt->stale_mask & msk)) continue;
-		ctxt->stale_mask &= ~msk;
-		wm8775_ops[idx].update(ctxt);
+		sd->ops->audio->s_routing(sd, input, 0, 0);
 	}
 }
 
 
-static const struct pvr2_i2c_handler_functions hfuncs = {
-	.detach = (void (*)(void *))wm8775_detach,
-	.check = (int (*)(void *))wm8775_check,
-	.update = (void (*)(void *))wm8775_update,
-	.describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
-};
-
-
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
-	struct pvr2_v4l_wm8775 *ctxt;
-
-	if (cp->handler) return 0;
-
-	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
-	if (!ctxt) return 0;
-
-	ctxt->handler.func_data = ctxt;
-	ctxt->handler.func_table = &hfuncs;
-	ctxt->client = cp;
-	ctxt->hdw = hdw;
-	ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
-	cp->handler = &ctxt->handler;
-	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
-		   cp->client->addr);
-	return !0;
-}
-
-
-
 
 /*
   Stuff for Emacs to see, in order to encourage consistent editing style:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.h linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-wm8775.h	2009-06-09 23:05:27.000000000 -0400
@@ -34,9 +34,9 @@
 
 
 
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
 
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
 
 
 #endif /* __PVRUSB2_WM8775_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pwc/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/pwc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/pwc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pwc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -35,3 +35,13 @@ config USB_PWC_DEBUG
 	  Say Y here in order to have the pwc driver generate verbose debugging
 	  messages.
 	  A special module options 'trace' is used to control the verbosity.
+
+config USB_PWC_INPUT_EVDEV
+	bool "USB Philips Cameras input events device support"
+	default y
+	depends on USB_PWC=INPUT || INPUT=y
+	---help---
+	  This option makes USB Philips cameras register the snapshot button as
+	  an input device to report button events.
+
+	  If you are in doubt, say Y.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc-ctrl.c linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc-ctrl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc-ctrl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc-ctrl.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,35 +159,67 @@ static void pwc_set_image_buffer_size(st
 
 /****************************************************************************/
 
+static int _send_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, int index, void *buf, int buflen, int timeout)
+{
+	int rc;
+	void *kbuf = NULL;
 
-#define SendControlMsg(request, value, buflen) \
-	usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \
-		request, \
-		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
-		value, \
-		pdev->vcinterface, \
-		&buf, buflen, 500)
+	if (buflen) {
+		kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+		if (kbuf == NULL)
+			return -ENOMEM;
+		memcpy(kbuf, buf, buflen);
+	}
 
-#define RecvControlMsg(request, value, buflen) \
-	usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \
-		request, \
-		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \
-		value, \
-		pdev->vcinterface, \
-		&buf, buflen, 500)
+	rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
+		request,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		index,
+		kbuf, buflen, timeout);
 
+	kfree(kbuf);
+	return rc;
+}
 
-static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen)
+static int recv_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, void *buf, int buflen)
 {
-	return usb_control_msg(udev,
-		usb_sndctrlpipe(udev, 0),
+	int rc;
+	void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+
+	if (kbuf == NULL)
+		return -ENOMEM;
+
+	rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
+		request,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		pdev->vcinterface,
+		kbuf, buflen, 500);
+	memcpy(buf, kbuf, buflen);
+	kfree(kbuf);
+	return rc;
+}
+
+static inline int send_video_command(struct pwc_device *pdev,
+	int index, void *buf, int buflen)
+{
+	return _send_control_msg(pdev,
 		SET_EP_STREAM_CTL,
-		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		VIDEO_OUTPUT_CONTROL_FORMATTER,
 		index,
 		buf, buflen, 1000);
 }
 
+static inline int send_control_msg(struct pwc_device *pdev,
+	u8 request, u16 value, void *buf, int buflen)
+{
+	return _send_control_msg(pdev,
+		request, value, pdev->vcinterface, buf, buflen, 500);
+}
+
 
 
 static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
@@ -224,7 +256,7 @@ static int set_video_mode_Nala(struct pw
 		return -EINVAL;
 
 	memcpy(buf, pEntry->mode, 3);
-	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
+	ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
 	if (ret < 0) {
 		PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
 		return ret;
@@ -285,7 +317,7 @@ static int set_video_mode_Timon(struct p
 	memcpy(buf, pChoose->mode, 13);
 	if (snapshot)
 		buf[0] |= 0x80;
-	ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13);
+	ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
 	if (ret < 0)
 		return ret;
 
@@ -358,7 +390,7 @@ static int set_video_mode_Kiara(struct p
 		buf[0] |= 0x80;
 
 	/* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
-	ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12);
+	ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
 	if (ret < 0)
 		return ret;
 
@@ -530,7 +562,8 @@ int pwc_get_brightness(struct pwc_device
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -545,7 +578,8 @@ int pwc_set_brightness(struct pwc_device
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 9) & 0x7f;
-	return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf));
 }
 
 /* CONTRAST */
@@ -555,7 +589,8 @@ int pwc_get_contrast(struct pwc_device *
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -570,7 +605,8 @@ int pwc_set_contrast(struct pwc_device *
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 10) & 0x3f;
-	return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf));
 }
 
 /* GAMMA */
@@ -580,7 +616,8 @@ int pwc_get_gamma(struct pwc_device *pde
 	char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return buf;
@@ -595,7 +632,8 @@ int pwc_set_gamma(struct pwc_device *pde
 	if (value > 0xffff)
 		value = 0xffff;
 	buf = (value >> 11) & 0x1f;
-	return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf));
 }
 
 
@@ -613,7 +651,8 @@ int pwc_get_saturation(struct pwc_device
 		saturation_register = SATURATION_MODE_FORMATTER2;
 	else
 		saturation_register = SATURATION_MODE_FORMATTER1;
-	ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = (signed)buf;
@@ -636,7 +675,8 @@ int pwc_set_saturation(struct pwc_device
 		saturation_register = SATURATION_MODE_FORMATTER2;
 	else
 		saturation_register = SATURATION_MODE_FORMATTER1;
-	return SendControlMsg(SET_CHROM_CTL, saturation_register, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, saturation_register, &buf, sizeof(buf));
 }
 
 /* AGC */
@@ -651,7 +691,8 @@ int pwc_set_agc(struct pwc_device *pdev,
 	else
 		buf = 0xff; /* fixed */
 
-	ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (!mode && ret >= 0) {
 		if (value < 0)
@@ -659,7 +700,8 @@ int pwc_set_agc(struct pwc_device *pdev,
 		if (value > 0xffff)
 			value = 0xffff;
 		buf = (value >> 10) & 0x3F;
-		ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+		ret = send_control_msg(pdev,
+			SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
 	}
 	if (ret < 0)
 		return ret;
@@ -671,12 +713,14 @@ int pwc_get_agc(struct pwc_device *pdev,
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
 	if (buf != 0) { /* fixed */
-		ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		if (buf > 0x3F)
@@ -684,7 +728,8 @@ int pwc_get_agc(struct pwc_device *pdev,
 		*value = (buf << 10);
 	}
 	else { /* auto */
-		ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		/* Gah... this value ranges from 0x00 ... 0x9F */
@@ -707,7 +752,8 @@ int pwc_set_shutter_speed(struct pwc_dev
 	else
 		buf[0] = 0xff; /* fixed */
 
-	ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (!mode && ret >= 0) {
 		if (value < 0)
@@ -726,7 +772,9 @@ int pwc_set_shutter_speed(struct pwc_dev
 			buf[0] = value >> 8;
 		}
 
-		ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
+		ret = send_control_msg(pdev,
+			SET_LUM_CTL, PRESET_SHUTTER_FORMATTER,
+			&buf, sizeof(buf));
 	}
 	return ret;
 }
@@ -737,7 +785,8 @@ int pwc_get_shutter_speed(struct pwc_dev
 	unsigned char buf[2];
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf[0] + (buf[1] << 8);
@@ -764,7 +813,9 @@ int pwc_camera_power(struct pwc_device *
 		buf = 0x00; /* active */
 	else
 		buf = 0xFF; /* power save */
-	return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 
@@ -773,20 +824,20 @@ int pwc_camera_power(struct pwc_device *
 
 int pwc_restore_user(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0);
 }
 
 int pwc_save_user(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0);
 }
 
 int pwc_restore_factory(struct pwc_device *pdev)
 {
-	char buf; /* dummy */
-	return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0);
 }
 
  /* ************************************************* */
@@ -814,7 +865,8 @@ int pwc_set_awb(struct pwc_device *pdev,
 
 	buf = mode & 0x07; /* just the lowest three bits */
 
-	ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (ret < 0)
 		return ret;
@@ -826,7 +878,8 @@ int pwc_get_awb(struct pwc_device *pdev)
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf));
 
 	if (ret < 0)
 		return ret;
@@ -843,7 +896,9 @@ int pwc_set_red_gain(struct pwc_device *
 		value = 0xffff;
 	/* only the msb is considered */
 	buf = value >> 8;
-	return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_red_gain(struct pwc_device *pdev, int *value)
@@ -851,7 +906,9 @@ int pwc_get_red_gain(struct pwc_device *
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 	    return ret;
 	*value = buf << 8;
@@ -869,7 +926,9 @@ int pwc_set_blue_gain(struct pwc_device
 		value = 0xffff;
 	/* only the msb is considered */
 	buf = value >> 8;
-	return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
@@ -877,7 +936,9 @@ int pwc_get_blue_gain(struct pwc_device
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 	    return ret;
 	*value = buf << 8;
@@ -894,7 +955,8 @@ static int pwc_read_red_gain(struct pwc_
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 8;
@@ -906,7 +968,8 @@ static int pwc_read_blue_gain(struct pwc
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 8;
@@ -920,7 +983,8 @@ static int pwc_set_wb_speed(struct pwc_d
 
 	/* useful range is 0x01..0x20 */
 	buf = speed / 0x7f0;
-	return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
@@ -928,7 +992,8 @@ static int pwc_get_wb_speed(struct pwc_d
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf * 0x7f0;
@@ -942,7 +1007,8 @@ static int pwc_set_wb_delay(struct pwc_d
 
 	/* useful range is 0x01..0x3F */
 	buf = (delay >> 10);
-	return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
@@ -950,7 +1016,8 @@ static int pwc_get_wb_delay(struct pwc_d
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*value = buf << 10;
@@ -978,7 +1045,8 @@ int pwc_set_leds(struct pwc_device *pdev
 	buf[0] = on_value;
 	buf[1] = off_value;
 
-	return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2);
+	return send_control_msg(pdev,
+		SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
 }
 
 static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
@@ -992,7 +1060,8 @@ static int pwc_get_leds(struct pwc_devic
 		return 0;
 	}
 
-	ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*on_value = buf[0] * 100;
@@ -1009,7 +1078,8 @@ int pwc_set_contour(struct pwc_device *p
 		buf = 0xff; /* auto contour on */
 	else
 		buf = 0x0; /* auto contour off */
-	ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
@@ -1019,7 +1089,8 @@ int pwc_set_contour(struct pwc_device *p
 		contour = 0xffff;
 
 	buf = (contour >> 10); /* contour preset is [0..3f] */
-	ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+	ret = send_control_msg(pdev,
+		SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -1030,13 +1101,16 @@ int pwc_get_contour(struct pwc_device *p
 	unsigned char buf;
 	int ret;
 
-	ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
 	if (buf == 0) {
 		/* auto mode off, query current preset value */
-		ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
+		ret = recv_control_msg(pdev,
+			GET_LUM_CTL, PRESET_CONTOUR_FORMATTER,
+			&buf, sizeof(buf));
 		if (ret < 0)
 			return ret;
 		*contour = buf << 10;
@@ -1055,7 +1129,9 @@ int pwc_set_backlight(struct pwc_device
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
@@ -1063,7 +1139,9 @@ int pwc_get_backlight(struct pwc_device
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*backlight = !!buf;
@@ -1078,7 +1156,8 @@ int pwc_set_colour_mode(struct pwc_devic
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_get_colour_mode(struct pwc_device *pdev, int *colour)
@@ -1086,7 +1165,8 @@ int pwc_get_colour_mode(struct pwc_devic
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*colour = !!buf;
@@ -1102,7 +1182,8 @@ int pwc_set_flicker(struct pwc_device *p
 		buf = 0xff;
 	else
 		buf = 0x0;
-	return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
@@ -1110,7 +1191,8 @@ int pwc_get_flicker(struct pwc_device *p
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*flicker = !!buf;
@@ -1126,7 +1208,9 @@ int pwc_set_dynamic_noise(struct pwc_dev
 	if (noise > 3)
 		noise = 3;
 	buf = noise;
-	return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+		&buf, sizeof(buf));
 }
 
 int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
@@ -1134,7 +1218,9 @@ int pwc_get_dynamic_noise(struct pwc_dev
 	int ret;
 	unsigned char buf;
 
-	ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
+	ret = recv_control_msg(pdev,
+		GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER,
+		&buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	*noise = buf;
@@ -1146,7 +1232,8 @@ static int _pwc_mpt_reset(struct pwc_dev
 	unsigned char buf;
 
 	buf = flags & 0x03; // only lower two bits are currently used
-	return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
+	return send_control_msg(pdev,
+		SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_mpt_reset(struct pwc_device *pdev, int flags)
@@ -1175,7 +1262,8 @@ static int _pwc_mpt_set_angle(struct pwc
 	buf[1] = (pan >> 8) & 0xFF;
 	buf[2] = tilt & 0xFF;
 	buf[3] = (tilt >> 8) & 0xFF;
-	return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4);
+	return send_control_msg(pdev,
+		SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
 }
 
 int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
@@ -1211,7 +1299,8 @@ static int pwc_mpt_get_status(struct pwc
 	int ret;
 	unsigned char buf[5];
 
-	ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
+	ret = recv_control_msg(pdev,
+		GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	status->status = buf[0] & 0x7; // 3 bits are used for reporting
@@ -1233,7 +1322,8 @@ int pwc_get_cmos_sensor(struct pwc_devic
 	else
 		request = SENSOR_TYPE_FORMATTER2;
 
-	ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
+	ret = recv_control_msg(pdev,
+		GET_STATUS_CTL, request, &buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 	if (pdev->type < 675)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc.h linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc.h	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,9 @@
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/input.h>
+#endif
 
 #include "pwc-uncompress.h"
 #include <media/pwc-ioctl.h>
@@ -255,6 +258,9 @@ struct pwc_device
    int pan_angle;			/* in degrees * 100 */
    int tilt_angle;			/* absolute angle; 0,0 is home position */
    int snapshot_button_status;		/* set to 1 when the user push the button, reset to 0 when this value is read */
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+   struct input_dev *button_dev;	/* webcam snapshot button input */
+#endif
 
    /*** Misc. data ***/
    wait_queue_head_t frameq;		/* When waiting for a frame to finish... */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc-if.c linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc-if.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pwc/pwc-if.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pwc/pwc-if.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,7 @@
    - Xavier Roche: QuickCam Pro 4000 ID
    - Jens Knudsen: QuickCam Zoom ID
    - J. Debert: QuickCam for Notebooks ID
+   - Pham Thanh Nam: webcam snapshot button as an event input device
 */
 
 #include <linux/errno.h>
@@ -61,6 +62,9 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/usb/input.h>
+#endif
 #include <linux/vmalloc.h>
 #include <asm/io.h>
 
@@ -586,6 +590,23 @@ static void pwc_frame_dumped(struct pwc_
 				pdev->vframe_count);
 }
 
+static void pwc_snapshot_button(struct pwc_device *pdev, int down)
+{
+	if (down) {
+		PWC_TRACE("Snapshot button pressed.\n");
+		pdev->snapshot_button_status = 1;
+	} else {
+		PWC_TRACE("Snapshot button released.\n");
+	}
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+	if (pdev->button_dev) {
+		input_report_key(pdev->button_dev, BTN_0, down);
+		input_sync(pdev->button_dev);
+	}
+#endif
+}
+
 static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
 {
 	int awake = 0;
@@ -603,13 +624,7 @@ static int pwc_rcv_short_packet(struct p
 			pdev->vframes_error++;
 		}
 		if ((ptr[0] ^ pdev->vmirror) & 0x01) {
-			if (ptr[0] & 0x01) {
-				pdev->snapshot_button_status = 1;
-				PWC_TRACE("Snapshot button pressed.\n");
-			}
-			else {
-				PWC_TRACE("Snapshot button released.\n");
-			}
+			pwc_snapshot_button(pdev, ptr[0] & 0x01);
 		}
 		if ((ptr[0] ^ pdev->vmirror) & 0x02) {
 			if (ptr[0] & 0x02)
@@ -633,12 +648,7 @@ static int pwc_rcv_short_packet(struct p
 	else if (pdev->type == 740 || pdev->type == 720) {
 		unsigned char *ptr = (unsigned char *)fbuf->data;
 		if ((ptr[0] ^ pdev->vmirror) & 0x01) {
-			if (ptr[0] & 0x01) {
-				pdev->snapshot_button_status = 1;
-				PWC_TRACE("Snapshot button pressed.\n");
-			}
-			else
-				PWC_TRACE("Snapshot button released.\n");
+			pwc_snapshot_button(pdev, ptr[0] & 0x01);
 		}
 		pdev->vmirror = ptr[0] & 0x03;
 	}
@@ -1115,6 +1125,7 @@ static int pwc_video_open(struct file *f
 	}
 
 	mutex_lock(&pdev->modlock);
+	pwc_construct(pdev); /* set min/max sizes correct */
 	if (!pdev->usb_init) {
 		PWC_DEBUG_OPEN("Doing first time initialization.\n");
 		pdev->usb_init = 1;
@@ -1139,7 +1150,6 @@ static int pwc_video_open(struct file *f
 	if (pwc_set_leds(pdev, led_on, led_off) < 0)
 		PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
 
-	pwc_construct(pdev); /* set min/max sizes correct */
 
 	/* So far, so good. Allocate memory. */
 	i = pwc_allocate_buffers(pdev);
@@ -1216,6 +1226,15 @@ static void pwc_cleanup(struct pwc_devic
 {
 	pwc_remove_sysfs_files(pdev->vdev);
 	video_unregister_device(pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+	if (pdev->button_dev) {
+		input_unregister_device(pdev->button_dev);
+		input_free_device(pdev->button_dev);
+		kfree(pdev->button_dev->phys);
+		pdev->button_dev = NULL;
+	}
+#endif
 }
 
 /* Note that all cleanup is done in the reverse order as in _open */
@@ -1483,6 +1502,9 @@ static int usb_pwc_probe(struct usb_inte
 	int features = 0;
 	int video_nr = -1; /* default: use next available device */
 	char serial_number[30], *name;
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+	char *phys = NULL;
+#endif
 
 	vendor_id = le16_to_cpu(udev->descriptor.idVendor);
 	product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1807,6 +1829,35 @@ static int usb_pwc_probe(struct usb_inte
 	pwc_set_leds(pdev, 0, 0);
 	pwc_camera_power(pdev, 0);
 
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+	/* register webcam snapshot button input device */
+	pdev->button_dev = input_allocate_device();
+	if (!pdev->button_dev) {
+		PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
+		return -ENOMEM;
+	}
+
+	pdev->button_dev->name = "PWC snapshot button";
+	phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
+	if (!phys) {
+		input_free_device(pdev->button_dev);
+		return -ENOMEM;
+	}
+	pdev->button_dev->phys = phys;
+	usb_to_input_id(pdev->udev, &pdev->button_dev->id);
+	pdev->button_dev->dev.parent = &pdev->udev->dev;
+	pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
+	pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+
+	rc = input_register_device(pdev->button_dev);
+	if (rc) {
+		input_free_device(pdev->button_dev);
+		kfree(pdev->button_dev->phys);
+		pdev->button_dev = NULL;
+		return rc;
+	}
+#endif
+
 	return 0;
 
 err_unreg:
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/pxa_camera.c linux-libre-2.6.30-gnu1/drivers/media/video/pxa_camera.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/pxa_camera.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/pxa_camera.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/videodev2.h>
 
 #include <mach/dma.h>
-#include <mach/pxa-regs.h>
 #include <mach/camera.h>
 
 #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
@@ -164,6 +163,13 @@
 			CICR0_EOFM | CICR0_FOM)
 
 /*
+ * YUV422P picture size should be a multiple of 16, so the heuristic aligns
+ * height, width on 4 byte boundaries to reach the 16 multiple for the size.
+ */
+#define YUV422P_X_Y_ALIGN 4
+#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
+
+/*
  * Structures
  */
 enum pxa_camera_active_dma {
@@ -237,20 +243,11 @@ static int pxa_videobuf_setup(struct vid
 			      unsigned int *size)
 {
 	struct soc_camera_device *icd = vq->priv_data;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
 
 	dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
 
-	/* planar capture requires Y, U and V buffers to be page aligned */
-	if (pcdev->channels == 3) {
-		*size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */
-		*size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */
-		*size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */
-	} else {
-		*size = icd->width * icd->height *
-			((icd->current_fmt->depth + 7) >> 3);
-	}
+	*size = roundup(icd->width * icd->height *
+			((icd->current_fmt->depth + 7) >> 3), 8);
 
 	if (0 == *count)
 		*count = 32;
@@ -290,19 +287,63 @@ static void free_buffer(struct videobuf_
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
 
+static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
+			       int sg_first_ofs, int size)
+{
+	int i, offset, dma_len, xfer_len;
+	struct scatterlist *sg;
+
+	offset = sg_first_ofs;
+	for_each_sg(sglist, sg, sglen, i) {
+		dma_len = sg_dma_len(sg);
+
+		/* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
+		xfer_len = roundup(min(dma_len - offset, size), 8);
+
+		size = max(0, size - xfer_len);
+		offset = 0;
+		if (size == 0)
+			break;
+	}
+
+	BUG_ON(size != 0);
+	return i + 1;
+}
+
+/**
+ * pxa_init_dma_channel - init dma descriptors
+ * @pcdev: pxa camera device
+ * @buf: pxa buffer to find pxa dma channel
+ * @dma: dma video buffer
+ * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
+ * @cibr: camera Receive Buffer Register
+ * @size: bytes to transfer
+ * @sg_first: first element of sg_list
+ * @sg_first_ofs: offset in first element of sg_list
+ *
+ * Prepares the pxa dma descriptors to transfer one camera channel.
+ * Beware sg_first and sg_first_ofs are both input and output parameters.
+ *
+ * Returns 0 or -ENOMEM if no coherent memory is available
+ */
 static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 				struct pxa_buffer *buf,
 				struct videobuf_dmabuf *dma, int channel,
-				int sglen, int sg_start, int cibr,
-				unsigned int size)
+				int cibr, int size,
+				struct scatterlist **sg_first, int *sg_first_ofs)
 {
 	struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
-	int i;
+	struct scatterlist *sg;
+	int i, offset, sglen;
+	int dma_len = 0, xfer_len = 0;
 
 	if (pxa_dma->sg_cpu)
 		dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
 				  pxa_dma->sg_cpu, pxa_dma->sg_dma);
 
+	sglen = calculate_dma_sglen(*sg_first, dma->sglen,
+				    *sg_first_ofs, size);
+
 	pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
 	pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
 					     &pxa_dma->sg_dma, GFP_KERNEL);
@@ -310,31 +351,75 @@ static int pxa_init_dma_channel(struct p
 		return -ENOMEM;
 
 	pxa_dma->sglen = sglen;
+	offset = *sg_first_ofs;
 
-	for (i = 0; i < sglen; i++) {
-		int sg_i = sg_start + i;
-		struct scatterlist *sg = dma->sglist;
-		unsigned int dma_len = sg_dma_len(&sg[sg_i]), xfer_len;
+	dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+		*sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
 
-		pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
-		pxa_dma->sg_cpu[i].dtadr = sg_dma_address(&sg[sg_i]);
+
+	for_each_sg(*sg_first, sg, sglen, i) {
+		dma_len = sg_dma_len(sg);
 
 		/* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
-		xfer_len = (min(dma_len, size) + 7) & ~7;
+		xfer_len = roundup(min(dma_len - offset, size), 8);
 
+		size = max(0, size - xfer_len);
+
+		pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
+		pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
 		pxa_dma->sg_cpu[i].dcmd =
 			DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
-		size -= dma_len;
+#ifdef DEBUG
+		if (!i)
+			pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
+#endif
 		pxa_dma->sg_cpu[i].ddadr =
 			pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
+
+		dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+			 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
+			 sg_dma_address(sg) + offset, xfer_len);
+		offset = 0;
+
+		if (size == 0)
+			break;
 	}
 
-	pxa_dma->sg_cpu[sglen - 1].ddadr = DDADR_STOP;
-	pxa_dma->sg_cpu[sglen - 1].dcmd |= DCMD_ENDIRQEN;
+	pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
+	pxa_dma->sg_cpu[sglen].dcmd  = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
+
+	/*
+	 * Handle 1 special case :
+	 *  - in 3 planes (YUV422P format), we might finish with xfer_len equal
+	 *    to dma_len (end on PAGE boundary). In this case, the sg element
+	 *    for next plane should be the next after the last used to store the
+	 *    last scatter gather RAM page
+	 */
+	if (xfer_len >= dma_len) {
+		*sg_first_ofs = xfer_len - dma_len;
+		*sg_first = sg_next(sg);
+	} else {
+		*sg_first_ofs = xfer_len;
+		*sg_first = sg;
+	}
 
 	return 0;
 }
 
+static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
+				    struct pxa_buffer *buf)
+{
+	buf->active_dma = DMA_Y;
+	if (pcdev->channels == 3)
+		buf->active_dma |= DMA_U | DMA_V;
+}
+
+/*
+ * Please check the DMA prepared buffer structure in :
+ *   Documentation/video4linux/pxa_camera.txt
+ * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
+ * modification while DMA chain is running will work anyway.
+ */
 static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 		struct videobuf_buffer *vb, enum v4l2_field field)
 {
@@ -343,7 +428,6 @@ static int pxa_videobuf_prepare(struct v
 	struct pxa_camera_dev *pcdev = ici->priv;
 	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
 	int ret;
-	int sglen_y,  sglen_yu = 0, sglen_u = 0, sglen_v = 0;
 	int size_y, size_u = 0, size_v = 0;
 
 	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
@@ -382,62 +466,58 @@ static int pxa_videobuf_prepare(struct v
 	}
 
 	if (vb->state == VIDEOBUF_NEEDS_INIT) {
-		unsigned int size = vb->size;
+		int size = vb->size;
+		int next_ofs = 0;
 		struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+		struct scatterlist *sg;
 
 		ret = videobuf_iolock(vq, vb, NULL);
 		if (ret)
 			goto fail;
 
 		if (pcdev->channels == 3) {
-			/* FIXME the calculations should be more precise */
-			sglen_y = dma->sglen / 2;
-			sglen_u = sglen_v = dma->sglen / 4 + 1;
-			sglen_yu = sglen_y + sglen_u;
 			size_y = size / 2;
 			size_u = size_v = size / 4;
 		} else {
-			sglen_y = dma->sglen;
 			size_y = size;
 		}
 
-		/* init DMA for Y channel */
-		ret = pxa_init_dma_channel(pcdev, buf, dma, 0, sglen_y,
-					   0, 0x28, size_y);
+		sg = dma->sglist;
 
+		/* init DMA for Y channel */
+		ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
+					   &sg, &next_ofs);
 		if (ret) {
 			dev_err(pcdev->dev,
 				"DMA initialization for Y/RGB failed\n");
 			goto fail;
 		}
 
-		if (pcdev->channels == 3) {
-			/* init DMA for U channel */
-			ret = pxa_init_dma_channel(pcdev, buf, dma, 1, sglen_u,
-						   sglen_y, 0x30, size_u);
-			if (ret) {
-				dev_err(pcdev->dev,
-					"DMA initialization for U failed\n");
-				goto fail_u;
-			}
+		/* init DMA for U channel */
+		if (size_u)
+			ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
+						   size_u, &sg, &next_ofs);
+		if (ret) {
+			dev_err(pcdev->dev,
+				"DMA initialization for U failed\n");
+			goto fail_u;
+		}
 
-			/* init DMA for V channel */
-			ret = pxa_init_dma_channel(pcdev, buf, dma, 2, sglen_v,
-						   sglen_yu, 0x38, size_v);
-			if (ret) {
-				dev_err(pcdev->dev,
-					"DMA initialization for V failed\n");
-				goto fail_v;
-			}
+		/* init DMA for V channel */
+		if (size_v)
+			ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
+						   size_v, &sg, &next_ofs);
+		if (ret) {
+			dev_err(pcdev->dev,
+				"DMA initialization for V failed\n");
+			goto fail_v;
 		}
 
 		vb->state = VIDEOBUF_PREPARED;
 	}
 
 	buf->inwork = 0;
-	buf->active_dma = DMA_Y;
-	if (pcdev->channels == 3)
-		buf->active_dma |= DMA_U | DMA_V;
+	pxa_videobuf_set_actdma(pcdev, buf);
 
 	return 0;
 
@@ -454,88 +534,113 @@ out:
 	return ret;
 }
 
-static void pxa_videobuf_queue(struct videobuf_queue *vq,
-			       struct videobuf_buffer *vb)
+/**
+ * pxa_dma_start_channels - start DMA channel for active buffer
+ * @pcdev: pxa camera device
+ *
+ * Initialize DMA channels to the beginning of the active video buffer, and
+ * start these channels.
+ */
+static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
 {
-	struct soc_camera_device *icd = vq->priv_data;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
-	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
+	int i;
 	struct pxa_buffer *active;
-	unsigned long flags;
+
+	active = pcdev->active;
+
+	for (i = 0; i < pcdev->channels; i++) {
+		dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+			i, active->dmas[i].sg_dma);
+		DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
+		DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
+	}
+}
+
+static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
+{
 	int i;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
-		vb, vb->baddr, vb->bsize);
-	spin_lock_irqsave(&pcdev->lock, flags);
+	for (i = 0; i < pcdev->channels; i++) {
+		dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i);
+		DCSR(pcdev->dma_chans[i]) = 0;
+	}
+}
 
-	list_add_tail(&vb->queue, &pcdev->capture);
+static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
+				 struct pxa_buffer *buf)
+{
+	int i;
+	struct pxa_dma_desc *buf_last_desc;
 
-	vb->state = VIDEOBUF_ACTIVE;
-	active = pcdev->active;
+	for (i = 0; i < pcdev->channels; i++) {
+		buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
+		buf_last_desc->ddadr = DDADR_STOP;
 
-	if (!active) {
-		unsigned long cifr, cicr0;
+		if (pcdev->sg_tail[i])
+			/* Link the new buffer to the old tail */
+			pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
 
-		cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
-		__raw_writel(cifr, pcdev->base + CIFR);
+		/* Update the channel tail */
+		pcdev->sg_tail[i] = buf_last_desc;
+	}
+}
 
-		for (i = 0; i < pcdev->channels; i++) {
-			DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma;
-			DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
-			pcdev->sg_tail[i] = buf->dmas[i].sg_cpu + buf->dmas[i].sglen - 1;
-		}
+/**
+ * pxa_camera_start_capture - start video capturing
+ * @pcdev: camera device
+ *
+ * Launch capturing. DMA channels should not be active yet. They should get
+ * activated at the end of frame interrupt, to capture only whole frames, and
+ * never begin the capture of a partial frame.
+ */
+static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
+{
+	unsigned long cicr0, cifr;
 
-		pcdev->active = buf;
+	dev_dbg(pcdev->dev, "%s\n", __func__);
+	/* Reset the FIFOs */
+	cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+	__raw_writel(cifr, pcdev->base + CIFR);
+	/* Enable End-Of-Frame Interrupt */
+	cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
+	cicr0 &= ~CICR0_EOFM;
+	__raw_writel(cicr0, pcdev->base + CICR0);
+}
 
-		cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
-		__raw_writel(cicr0, pcdev->base + CICR0);
-	} else {
-		struct pxa_cam_dma *buf_dma;
-		struct pxa_cam_dma *act_dma;
-		int nents;
+static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
+{
+	unsigned long cicr0;
 
-		for (i = 0; i < pcdev->channels; i++) {
-			buf_dma = &buf->dmas[i];
-			act_dma = &active->dmas[i];
-			nents = buf_dma->sglen;
+	pxa_dma_stop_channels(pcdev);
 
-			/* Stop DMA engine */
-			DCSR(pcdev->dma_chans[i]) = 0;
+	cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
+	__raw_writel(cicr0, pcdev->base + CICR0);
 
-			/* Add the descriptors we just initialized to
-			   the currently running chain */
-			pcdev->sg_tail[i]->ddadr = buf_dma->sg_dma;
-			pcdev->sg_tail[i] = buf_dma->sg_cpu + buf_dma->sglen - 1;
+	pcdev->active = NULL;
+	dev_dbg(pcdev->dev, "%s\n", __func__);
+}
 
-			/* Setup a dummy descriptor with the DMA engines current
-			 * state
-			 */
-			buf_dma->sg_cpu[nents].dsadr =
-				pcdev->res->start + 0x28 + i*8; /* CIBRx */
-			buf_dma->sg_cpu[nents].dtadr =
-				DTADR(pcdev->dma_chans[i]);
-			buf_dma->sg_cpu[nents].dcmd =
-				DCMD(pcdev->dma_chans[i]);
+static void pxa_videobuf_queue(struct videobuf_queue *vq,
+			       struct videobuf_buffer *vb)
+{
+	struct soc_camera_device *icd = vq->priv_data;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct pxa_camera_dev *pcdev = ici->priv;
+	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
+	unsigned long flags;
 
-			if (DDADR(pcdev->dma_chans[i]) == DDADR_STOP) {
-				/* The DMA engine is on the last
-				   descriptor, set the next descriptors
-				   address to the descriptors we just
-				   initialized */
-				buf_dma->sg_cpu[nents].ddadr = buf_dma->sg_dma;
-			} else {
-				buf_dma->sg_cpu[nents].ddadr =
-					DDADR(pcdev->dma_chans[i]);
-			}
+	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
+		vb, vb->baddr, vb->bsize, pcdev->active);
 
-			/* The next descriptor is the dummy descriptor */
-			DDADR(pcdev->dma_chans[i]) = buf_dma->sg_dma + nents *
-				sizeof(struct pxa_dma_desc);
+	spin_lock_irqsave(&pcdev->lock, flags);
 
-			DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
-		}
-	}
+	list_add_tail(&vb->queue, &pcdev->capture);
+
+	vb->state = VIDEOBUF_ACTIVE;
+	pxa_dma_add_tail_buf(pcdev, buf);
+
+	if (!pcdev->active)
+		pxa_camera_start_capture(pcdev);
 
 	spin_unlock_irqrestore(&pcdev->lock, flags);
 }
@@ -573,7 +678,7 @@ static void pxa_camera_wakeup(struct pxa
 			      struct videobuf_buffer *vb,
 			      struct pxa_buffer *buf)
 {
-	unsigned long cicr0;
+	int i;
 
 	/* _init is used to debug races, see comment in pxa_camera_reqbufs() */
 	list_del_init(&vb->queue);
@@ -581,15 +686,12 @@ static void pxa_camera_wakeup(struct pxa
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
+	dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
 
 	if (list_empty(&pcdev->capture)) {
-		pcdev->active = NULL;
-		DCSR(pcdev->dma_chans[0]) = 0;
-		DCSR(pcdev->dma_chans[1]) = 0;
-		DCSR(pcdev->dma_chans[2]) = 0;
-
-		cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
-		__raw_writel(cicr0, pcdev->base + CICR0);
+		pxa_camera_stop_capture(pcdev);
+		for (i = 0; i < pcdev->channels; i++)
+			pcdev->sg_tail[i] = NULL;
 		return;
 	}
 
@@ -597,6 +699,35 @@ static void pxa_camera_wakeup(struct pxa
 				   struct pxa_buffer, vb.queue);
 }
 
+/**
+ * pxa_camera_check_link_miss - check missed DMA linking
+ * @pcdev: camera device
+ *
+ * The DMA chaining is done with DMA running. This means a tiny temporal window
+ * remains, where a buffer is queued on the chain, while the chain is already
+ * stopped. This means the tailed buffer would never be transfered by DMA.
+ * This function restarts the capture for this corner case, where :
+ *  - DADR() == DADDR_STOP
+ *  - a videobuffer is queued on the pcdev->capture list
+ *
+ * Please check the "DMA hot chaining timeslice issue" in
+ *   Documentation/video4linux/pxa_camera.txt
+ *
+ * Context: should only be called within the dma irq handler
+ */
+static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
+{
+	int i, is_dma_stopped = 1;
+
+	for (i = 0; i < pcdev->channels; i++)
+		if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
+			is_dma_stopped = 0;
+	dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+		__func__, pcdev->active, is_dma_stopped);
+	if (pcdev->active && is_dma_stopped)
+		pxa_camera_start_capture(pcdev);
+}
+
 static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 			       enum pxa_camera_active_dma act_dma)
 {
@@ -604,61 +735,70 @@ static void pxa_camera_dma_irq(int chann
 	unsigned long flags;
 	u32 status, camera_status, overrun;
 	struct videobuf_buffer *vb;
-	unsigned long cifr, cicr0;
 
 	spin_lock_irqsave(&pcdev->lock, flags);
 
 	status = DCSR(channel);
-	DCSR(channel) = status | DCSR_ENDINTR;
+	DCSR(channel) = status;
+
+	camera_status = __raw_readl(pcdev->base + CISR);
+	overrun = CISR_IFO_0;
+	if (pcdev->channels == 3)
+		overrun |= CISR_IFO_1 | CISR_IFO_2;
 
 	if (status & DCSR_BUSERR) {
 		dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
 		goto out;
 	}
 
-	if (!(status & DCSR_ENDINTR)) {
+	if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
 		dev_err(pcdev->dev, "Unknown DMA IRQ source, "
 			"status: 0x%08x\n", status);
 		goto out;
 	}
 
-	if (!pcdev->active) {
-		dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n");
-		goto out;
-	}
-
-	camera_status = __raw_readl(pcdev->base + CISR);
-	overrun = CISR_IFO_0;
-	if (pcdev->channels == 3)
-		overrun |= CISR_IFO_1 | CISR_IFO_2;
-	if (camera_status & overrun) {
-		dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status);
-		/* Stop the Capture Interface */
-		cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
-		__raw_writel(cicr0, pcdev->base + CICR0);
-
-		/* Stop DMA */
-		DCSR(channel) = 0;
-		/* Reset the FIFOs */
-		cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
-		__raw_writel(cifr, pcdev->base + CIFR);
-		/* Enable End-Of-Frame Interrupt */
-		cicr0 &= ~CICR0_EOFM;
-		__raw_writel(cicr0, pcdev->base + CICR0);
-		/* Restart the Capture Interface */
-		__raw_writel(cicr0 | CICR0_ENB, pcdev->base + CICR0);
+	/*
+	 * pcdev->active should not be NULL in DMA irq handler.
+	 *
+	 * But there is one corner case : if capture was stopped due to an
+	 * overrun of channel 1, and at that same channel 2 was completed.
+	 *
+	 * When handling the overrun in DMA irq for channel 1, we'll stop the
+	 * capture and restart it (and thus set pcdev->active to NULL). But the
+	 * DMA irq handler will already be pending for channel 2. So on entering
+	 * the DMA irq handler for channel 2 there will be no active buffer, yet
+	 * that is normal.
+	 */
+	if (!pcdev->active)
 		goto out;
-	}
 
 	vb = &pcdev->active->vb;
 	buf = container_of(vb, struct pxa_buffer, vb);
 	WARN_ON(buf->inwork || list_empty(&vb->queue));
-	dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
-		vb, vb->baddr, vb->bsize);
 
-	buf->active_dma &= ~act_dma;
-	if (!buf->active_dma)
-		pxa_camera_wakeup(pcdev, vb, buf);
+	dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+		__func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
+		status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
+
+	if (status & DCSR_ENDINTR) {
+		/*
+		 * It's normal if the last frame creates an overrun, as there
+		 * are no more DMA descriptors to fetch from QCI fifos
+		 */
+		if (camera_status & overrun &&
+		    !list_is_last(pcdev->capture.next, &pcdev->capture)) {
+			dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n",
+				camera_status);
+			pxa_camera_stop_capture(pcdev);
+			pxa_camera_start_capture(pcdev);
+			goto out;
+		}
+		buf->active_dma &= ~act_dma;
+		if (!buf->active_dma) {
+			pxa_camera_wakeup(pcdev, vb, buf);
+			pxa_camera_check_link_miss(pcdev);
+		}
+	}
 
 out:
 	spin_unlock_irqrestore(&pcdev->lock, flags);
@@ -787,6 +927,8 @@ static irqreturn_t pxa_camera_irq(int ir
 {
 	struct pxa_camera_dev *pcdev = data;
 	unsigned long status, cicr0;
+	struct pxa_buffer *buf;
+	struct videobuf_buffer *vb;
 
 	status = __raw_readl(pcdev->base + CISR);
 	dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
@@ -797,12 +939,14 @@ static irqreturn_t pxa_camera_irq(int ir
 	__raw_writel(status, pcdev->base + CISR);
 
 	if (status & CISR_EOF) {
-		int i;
-		for (i = 0; i < pcdev->channels; i++) {
-			DDADR(pcdev->dma_chans[i]) =
-				pcdev->active->dmas[i].sg_dma;
-			DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
-		}
+		pcdev->active = list_first_entry(&pcdev->capture,
+					   struct pxa_buffer, vb.queue);
+		vb = &pcdev->active->vb;
+		buf = container_of(vb, struct pxa_buffer, vb);
+		pxa_videobuf_set_actdma(pcdev, buf);
+
+		pxa_dma_start_channels(pcdev);
+
 		cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
 		__raw_writel(cicr0, pcdev->base + CICR0);
 	}
@@ -879,6 +1023,7 @@ static int test_platform_param(struct px
 		SOCAM_HSYNC_ACTIVE_LOW |
 		SOCAM_VSYNC_ACTIVE_HIGH |
 		SOCAM_VSYNC_ACTIVE_LOW |
+		SOCAM_DATA_ACTIVE_HIGH |
 		SOCAM_PCLK_SAMPLE_RISING |
 		SOCAM_PCLK_SAMPLE_FALLING;
 
@@ -1150,8 +1295,43 @@ static int pxa_camera_get_formats(struct
 	return formats;
 }
 
+static int pxa_camera_set_crop(struct soc_camera_device *icd,
+			       struct v4l2_rect *rect)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct pxa_camera_dev *pcdev = ici->priv;
+	struct soc_camera_sense sense = {
+		.master_clock = pcdev->mclk,
+		.pixel_clock_max = pcdev->ciclk / 4,
+	};
+	int ret;
+
+	/* If PCLK is used to latch data from the sensor, check sense */
+	if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
+		icd->sense = &sense;
+
+	ret = icd->ops->set_crop(icd, rect);
+
+	icd->sense = NULL;
+
+	if (ret < 0) {
+		dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+			 rect->width, rect->height, rect->left, rect->top);
+	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
+		if (sense.pixel_clock > sense.pixel_clock_max) {
+			dev_err(&ici->dev,
+				"pixel clock %lu set by the camera too high!",
+				sense.pixel_clock);
+			return -EIO;
+		}
+		recalculate_fifo_timeout(pcdev, sense.pixel_clock);
+	}
+
+	return ret;
+}
+
 static int pxa_camera_set_fmt(struct soc_camera_device *icd,
-			      __u32 pixfmt, struct v4l2_rect *rect)
+			      struct v4l2_format *f)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
@@ -1161,35 +1341,30 @@ static int pxa_camera_set_fmt(struct soc
 		.master_clock = pcdev->mclk,
 		.pixel_clock_max = pcdev->ciclk / 4,
 	};
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_format cam_f = *f;
 	int ret;
 
-	if (pixfmt) {
-		xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
-		if (!xlate) {
-			dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
-			return -EINVAL;
-		}
-
-		cam_fmt = xlate->cam_fmt;
+	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+	if (!xlate) {
+		dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+		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)
 		icd->sense = &sense;
 
-	switch (pixfmt) {
-	case 0:				/* Only geometry change */
-		ret = icd->ops->set_fmt(icd, pixfmt, rect);
-		break;
-	default:
-		ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
-	}
+	cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
+	ret = icd->ops->set_fmt(icd, &cam_f);
 
 	icd->sense = NULL;
 
 	if (ret < 0) {
 		dev_warn(&ici->dev, "Failed to configure for format %x\n",
-			 pixfmt);
+			 pix->pixelformat);
 	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
 			dev_err(&ici->dev,
@@ -1200,7 +1375,7 @@ static int pxa_camera_set_fmt(struct soc
 		recalculate_fifo_timeout(pcdev, sense.pixel_clock);
 	}
 
-	if (pixfmt && !ret) {
+	if (!ret) {
 		icd->buswidth = xlate->buswidth;
 		icd->current_fmt = xlate->host_fmt;
 	}
@@ -1235,6 +1410,18 @@ static int pxa_camera_try_fmt(struct soc
 		pix->width = 2048;
 	pix->width &= ~0x01;
 
+	/*
+	 * YUV422P planar format requires images size to be a 16 bytes
+	 * multiple. If not, zeros will be inserted between Y and U planes, and
+	 * U and V planes, and YUV422P standard would be violated.
+	 */
+	if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
+		if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+			pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
+		if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+			pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
+	}
+
 	pix->bytesperline = pix->width *
 		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
 	pix->sizeimage = pix->height * pix->bytesperline;
@@ -1342,18 +1529,8 @@ static int pxa_camera_resume(struct soc_
 		ret = pcdev->icd->ops->resume(pcdev->icd);
 
 	/* Restart frame capture if active buffer exists */
-	if (!ret && pcdev->active) {
-		unsigned long cifr, cicr0;
-
-		/* Reset the FIFOs */
-		cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
-		__raw_writel(cifr, pcdev->base + CIFR);
-
-		cicr0 = __raw_readl(pcdev->base + CICR0);
-		cicr0 &= ~CICR0_EOFM;	/* Enable End-Of-Frame Interrupt */
-		cicr0 |= CICR0_ENB;	/* Restart the Capture Interface */
-		__raw_writel(cicr0, pcdev->base + CICR0);
-	}
+	if (!ret && pcdev->active)
+		pxa_camera_start_capture(pcdev);
 
 	return ret;
 }
@@ -1364,6 +1541,7 @@ static struct soc_camera_host_ops pxa_so
 	.remove		= pxa_camera_remove_device,
 	.suspend	= pxa_camera_suspend,
 	.resume		= pxa_camera_resume,
+	.set_crop	= pxa_camera_set_crop,
 	.get_formats	= pxa_camera_get_formats,
 	.set_fmt	= pxa_camera_set_fmt,
 	.try_fmt	= pxa_camera_try_fmt,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/s2255drv.c linux-libre-2.6.30-gnu1/drivers/media/video/s2255drv.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/s2255drv.c	2013-05-03 18:02:21.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/s2255drv.c	2013-05-03 16:46:11.000000000 -0400
@@ -336,14 +336,19 @@ static long s2255_vendor_req(struct s225
 			     u16 index, u16 value, void *buf,
 			     s32 buf_len, int bOut);
 
+/* dev_err macro with driver name */
+#define S2255_DRIVER_NAME "s2255"
+#define s2255_dev_err(dev, fmt, arg...)					\
+		dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
+
 #define dprintk(level, fmt, arg...)					\
 	do {								\
 		if (*s2255_debug >= (level)) {				\
-			printk(KERN_DEBUG "s2255: " fmt, ##arg);	\
+			printk(KERN_DEBUG S2255_DRIVER_NAME		\
+				": " fmt, ##arg);			\
 		}							\
 	} while (0)
 
-
 static struct usb_driver s2255_driver;
 
 
@@ -528,14 +533,14 @@ static void s2255_fwchunk_complete(struc
 	int len;
 	dprintk(100, "udev %p urb %p", udev, urb);
 	if (urb->status) {
-		dev_err(&udev->dev, "URB failed with status %d", urb->status);
+		dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
 		atomic_set(&data->fw_state, S2255_FW_FAILED);
 		/* wake up anything waiting for the firmware */
 		wake_up(&data->wait_fw);
 		return;
 	}
 	if (data->fw_urb == NULL) {
-		dev_err(&udev->dev, "s2255 disconnected\n");
+		s2255_dev_err(&udev->dev, "disconnected\n");
 		atomic_set(&data->fw_state, S2255_FW_FAILED);
 		/* wake up anything waiting for the firmware */
 		wake_up(&data->wait_fw);
@@ -717,7 +722,6 @@ static void free_buffer(struct videobuf_
 {
 	dprintk(4, "%s\n", __func__);
 
-	videobuf_waiton(&buf->vb, 0, 0);
 	videobuf_vmalloc_free(&buf->vb);
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
@@ -841,8 +845,7 @@ static int vidioc_querycap(struct file *
 	struct s2255_dev *dev = fh->dev;
 	strlcpy(cap->driver, "s2255", sizeof(cap->driver));
 	strlcpy(cap->card, "s2255", sizeof(cap->card));
-	strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
-		sizeof(cap->bus_info));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
 	cap->version = S2255_VERSION;
 	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 	return 0;
@@ -1234,6 +1237,7 @@ static int s2255_set_mode(struct s2255_d
 	buffer[1] = (u32) chn_rev;
 	buffer[2] = CMD_SET_MODE;
 	memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
+	dev->setmode_ready[chn] = 0;
 	res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
 	if (debug)
 		dump_verify_mode(dev, mode);
@@ -1242,7 +1246,6 @@ static int s2255_set_mode(struct s2255_d
 
 	/* wait at least 3 frames before continuing */
 	if (mode->restart) {
-		dev->setmode_ready[chn] = 0;
 		wait_event_timeout(dev->wait_setmode[chn],
 				   (dev->setmode_ready[chn] != 0),
 				   msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
@@ -1278,7 +1281,7 @@ static int vidioc_streamon(struct file *
 	}
 
 	if (!res_get(dev, fh)) {
-		dev_err(&dev->udev->dev, "s2255: stream busy\n");
+		s2255_dev_err(&dev->udev->dev, "stream busy\n");
 		return -EBUSY;
 	}
 
@@ -1320,7 +1323,6 @@ static int vidioc_streamon(struct file *
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
-	int res;
 	struct s2255_fh *fh = priv;
 	struct s2255_dev *dev = fh->dev;
 
@@ -1334,9 +1336,7 @@ static int vidioc_streamoff(struct file
 		return -EINVAL;
 	}
 	s2255_stop_acquire(dev, fh->channel);
-	res = videobuf_streamoff(&fh->vb_vidq);
-	if (res < 0)
-		return res;
+	videobuf_streamoff(&fh->vb_vidq);
 	res_free(dev, fh);
 	return 0;
 }
@@ -1545,7 +1545,8 @@ static int s2255_open(struct file *file)
 
 	switch (atomic_read(&dev->fw_data->fw_state)) {
 	case S2255_FW_FAILED:
-		err("2255 firmware load failed. retrying.\n");
+		s2255_dev_err(&dev->udev->dev,
+			"firmware load failed. retrying.\n");
 		s2255_fwload_start(dev, 1);
 		wait_event_timeout(dev->fw_data->wait_fw,
 				   ((atomic_read(&dev->fw_data->fw_state)
@@ -1702,13 +1703,13 @@ static void s2255_destroy(struct kref *k
 	kfree(dev->fw_data);
 	usb_put_dev(dev->udev);
 	dprintk(1, "%s", __func__);
-	kfree(dev);
 
 	while (!list_empty(&s2255_devlist)) {
 		list = s2255_devlist.next;
 		list_del(list);
 	}
 	mutex_unlock(&dev->open_lock);
+	kfree(dev);
 }
 
 static int s2255_close(struct file *file)
@@ -2173,7 +2174,8 @@ static int s2255_board_init(struct s2255
 
 	printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
 	if (fw_ver < CUR_USB_FWVER)
-		err("usb firmware not up to date %d\n", fw_ver);
+		dev_err(&dev->udev->dev,
+			"usb firmware not up to date %d\n", fw_ver);
 
 	for (j = 0; j < MAX_CHANNELS; j++) {
 		dev->b_acquire[j] = 0;
@@ -2228,13 +2230,13 @@ static void read_pipe_completion(struct
 	dprintk(100, "read pipe completion %p, status %d\n", purb,
 		purb->status);
 	if (pipe_info == NULL) {
-		err("no context !");
+		dev_err(&purb->dev->dev, "no context!\n");
 		return;
 	}
 
 	dev = pipe_info->dev;
 	if (dev == NULL) {
-		err("no context !");
+		dev_err(&purb->dev->dev, "no context!\n");
 		return;
 	}
 	status = purb->status;
@@ -2286,7 +2288,7 @@ static int s2255_start_readpipe(struct s
 		pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!pipe_info->stream_urb) {
 			dev_err(&dev->udev->dev,
-				"ReadStream: Unable to alloc URB");
+				"ReadStream: Unable to alloc URB\n");
 			return -ENOMEM;
 		}
 		/* transfer buffer allocated in board_init */
@@ -2391,7 +2393,7 @@ static void s2255_stop_readpipe(struct s
 	int j;
 
 	if (dev == NULL) {
-		err("s2255: invalid device");
+		s2255_dev_err(&dev->udev->dev, "invalid device\n");
 		return;
 	}
 	dprintk(4, "stop read pipe\n");
@@ -2453,7 +2455,7 @@ static int s2255_probe(struct usb_interf
 	/* allocate memory for our device state and initialize it to zero */
 	dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
 	if (dev == NULL) {
-		err("s2255: out of memory");
+		s2255_dev_err(&interface->dev, "out of memory\n");
 		goto error;
 	}
 
@@ -2487,7 +2489,7 @@ static int s2255_probe(struct usb_interf
 	}
 
 	if (!dev->read_endpoint) {
-		dev_err(&interface->dev, "Could not find bulk-in endpoint");
+		dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
 		goto error;
 	}
 
@@ -2583,7 +2585,7 @@ static void s2255_disconnect(struct usb_
 }
 
 static struct usb_driver s2255_driver = {
-	.name = "s2255",
+	.name = S2255_DRIVER_NAME,
 	.probe = s2255_probe,
 	.disconnect = s2255_disconnect,
 	.id_table = s2255_table,
@@ -2597,7 +2599,8 @@ static int __init usb_s2255_init(void)
 	result = usb_register(&s2255_driver);
 
 	if (result)
-		err("usb_register failed. Error number %d", result);
+		pr_err(KBUILD_MODNAME
+			": usb_register failed. Error number %d\n", result);
 
 	dprintk(2, "s2255_init: done\n");
 	return result;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa5246a.c linux-libre-2.6.30-gnu1/drivers/media/video/saa5246a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa5246a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa5246a.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,10 +46,11 @@
 #include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
 MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
@@ -388,13 +389,19 @@ MODULE_LICENSE("GPL");
 
 struct saa5246a_device
 {
+	struct v4l2_subdev sd;
+	struct video_device *vdev;
 	u8     pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
 	int    is_searching[NUM_DAUS];
-	struct i2c_client *client;
 	unsigned long in_use;
 	struct mutex lock;
 };
 
+static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa5246a_device, sd);
+}
+
 static struct video_device saa_template;	/* Declared near bottom */
 
 /*
@@ -403,12 +410,13 @@ static struct video_device saa_template;
 
 static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
 	char buf[64];
 
 	buf[0] = reg;
 	memcpy(buf+1, data, count);
 
-	if(i2c_master_send(t->client, buf, count+1)==count+1)
+	if (i2c_master_send(client, buf, count + 1) == count + 1)
 		return 0;
 	return -1;
 }
@@ -436,7 +444,9 @@ static int i2c_senddata(struct saa5246a_
  */
 static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
 {
-	if(i2c_master_recv(t->client, buf, count)!=count)
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+	if (i2c_master_recv(client, buf, count) != count)
 		return -1;
 	return 0;
 }
@@ -961,9 +971,6 @@ static int saa5246a_open(struct file *fi
 {
 	struct saa5246a_device *t = video_drvdata(file);
 
-	if (t->client == NULL)
-		return -ENODEV;
-
 	if (test_and_set_bit(0, &t->in_use))
 		return -EBUSY;
 
@@ -1033,18 +1040,29 @@ static struct video_device saa_template
 	.minor    = -1,
 };
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5246a_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_SAA5246A, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa5246a_core_ops = {
+	.g_chip_ident = saa5246a_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5246a_ops = {
+	.core = &saa5246a_core_ops,
+};
 
-I2C_CLIENT_INSMOD;
 
 static int saa5246a_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	int pgbuf;
 	int err;
-	struct video_device *vd;
 	struct saa5246a_device *t;
+	struct v4l2_subdev *sd;
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
@@ -1053,40 +1071,42 @@ static int saa5246a_probe(struct i2c_cli
 	t = kzalloc(sizeof(*t), GFP_KERNEL);
 	if (t == NULL)
 		return -ENOMEM;
+	sd = &t->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa5246a_ops);
 	mutex_init(&t->lock);
 
 	/* Now create a video4linux device */
-	vd = video_device_alloc();
-	if (vd == NULL) {
+	t->vdev = video_device_alloc();
+	if (t->vdev == NULL) {
 		kfree(t);
 		return -ENOMEM;
 	}
-	i2c_set_clientdata(client, vd);
-	memcpy(vd, &saa_template, sizeof(*vd));
+	memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
 
 	for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
 		memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
 		t->is_searching[pgbuf] = false;
 	}
-	video_set_drvdata(vd, t);
+	video_set_drvdata(t->vdev, t);
 
 	/* Register it */
-	err = video_register_device(vd, VFL_TYPE_VTX, -1);
+	err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
 	if (err < 0) {
+		video_device_release(t->vdev);
 		kfree(t);
-		video_device_release(vd);
 		return err;
 	}
-	t->client = client;
 	return 0;
 }
 
 static int saa5246a_remove(struct i2c_client *client)
 {
-	struct video_device *vd = i2c_get_clientdata(client);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa5246a_device *t = to_dev(sd);
 
-	video_unregister_device(vd);
-	kfree(video_get_drvdata(vd));
+	video_unregister_device(t->vdev);
+	v4l2_device_unregister_subdev(sd);
+	kfree(t);
 	return 0;
 }
 
@@ -1098,7 +1118,6 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa5246a",
-	.driverid = I2C_DRIVERID_SAA5249,
 	.probe = saa5246a_probe,
 	.remove = saa5246a_remove,
 	.id_table = saa5246a_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa5249.c linux-libre-2.6.30-gnu1/drivers/media/video/saa5249.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa5249.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa5249.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,15 +50,17 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
 MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver");
 MODULE_LICENSE("GPL");
 
+
 #define VTX_VER_MAJ 1
 #define VTX_VER_MIN 8
 
@@ -95,17 +97,23 @@ typedef struct {
 
 struct saa5249_device
 {
+	struct v4l2_subdev sd;
+	struct video_device *vdev;
 	vdau_t vdau[NUM_DAUS];			/* Data for virtual DAUs (the 5249 only has one */
 						/* real DAU, so we have to simulate some more) */
 	int vtx_use_count;
 	int is_searching[NUM_DAUS];
 	int disp_mode;
 	int virtual_mode;
-	struct i2c_client *client;
 	unsigned long in_use;
 	struct mutex lock;
 };
 
+static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa5249_device, sd);
+}
+
 
 #define CCTWR 34		/* I²C write/read-address of vtx-chip */
 #define CCTRD 35
@@ -147,12 +155,13 @@ static void jdelay(unsigned long delay)
 
 static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
 	char buf[64];
 
 	buf[0] = reg;
 	memcpy(buf+1, data, count);
 
-	if (i2c_master_send(t->client, buf, count + 1) == count + 1)
+	if (i2c_master_send(client, buf, count + 1) == count + 1)
 		return 0;
 	return -1;
 }
@@ -180,7 +189,9 @@ static int i2c_senddata(struct saa5249_d
 
 static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
 {
-	if(i2c_master_recv(t->client, buf, count)!=count)
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+	if (i2c_master_recv(client, buf, count) != count)
 		return -1;
 	return 0;
 }
@@ -497,9 +508,6 @@ static int saa5249_open(struct file *fil
 	struct saa5249_device *t = video_drvdata(file);
 	int pgbuf;
 
-	if (t->client == NULL)
-		return -ENODEV;
-
 	if (test_and_set_bit(0, &t->in_use))
 		return -EBUSY;
 
@@ -553,18 +561,28 @@ static struct video_device saa_template
 	.release 	= video_device_release,
 };
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-I2C_CLIENT_INSMOD;
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa5249_core_ops = {
+	.g_chip_ident = saa5249_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5249_ops = {
+	.core = &saa5249_core_ops,
+};
 
 static int saa5249_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	int pgbuf;
 	int err;
-	struct video_device *vd;
 	struct saa5249_device *t;
+	struct v4l2_subdev *sd;
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
@@ -573,16 +591,18 @@ static int saa5249_probe(struct i2c_clie
 	t = kzalloc(sizeof(*t), GFP_KERNEL);
 	if (t == NULL)
 		return -ENOMEM;
+	sd = &t->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa5249_ops);
 	mutex_init(&t->lock);
 
 	/* Now create a video4linux device */
-	vd = kmalloc(sizeof(struct video_device), GFP_KERNEL);
-	if (vd == NULL) {
+	t->vdev = video_device_alloc();
+	if (t->vdev == NULL) {
+		kfree(t);
 		kfree(client);
 		return -ENOMEM;
 	}
-	i2c_set_clientdata(client, vd);
-	memcpy(vd, &saa_template, sizeof(*vd));
+	memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
 
 	for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
 		memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
@@ -593,26 +613,26 @@ static int saa5249_probe(struct i2c_clie
 		t->vdau[pgbuf].stopped = true;
 		t->is_searching[pgbuf] = false;
 	}
-	video_set_drvdata(vd, t);
+	video_set_drvdata(t->vdev, t);
 
 	/* Register it */
-	err = video_register_device(vd, VFL_TYPE_VTX, -1);
+	err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
 	if (err < 0) {
+		video_device_release(t->vdev);
 		kfree(t);
-		kfree(vd);
 		return err;
 	}
-	t->client = client;
 	return 0;
 }
 
 static int saa5249_remove(struct i2c_client *client)
 {
-	struct video_device *vd = i2c_get_clientdata(client);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa5249_device *t = to_dev(sd);
 
-	video_unregister_device(vd);
-	kfree(video_get_drvdata(vd));
-	kfree(vd);
+	video_unregister_device(t->vdev);
+	v4l2_device_unregister_subdev(sd);
+	kfree(t);
 	return 0;
 }
 
@@ -624,7 +644,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa5249",
-	.driverid = I2C_DRIVERID_SAA5249,
 	.probe = saa5249_probe,
 	.remove = saa5249_remove,
 	.id_table = saa5249_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa6588.c linux-libre-2.6.30-gnu1/drivers/media/video/saa6588.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa6588.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa6588.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,7 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -32,15 +32,10 @@
 #include <asm/uaccess.h>
 
 #include <media/rds.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
-	0x20 >> 1,
-	0x22 >> 1,
-	I2C_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
 
 /* insmod options */
 static unsigned int debug;
@@ -72,9 +67,8 @@ MODULE_LICENSE("GPL");
 #define dprintk     if (debug) printk
 
 struct saa6588 {
-	struct i2c_client client;
-	struct work_struct work;
-	struct timer_list timer;
+	struct v4l2_subdev sd;
+	struct delayed_work work;
 	spinlock_t lock;
 	unsigned char *buffer;
 	unsigned int buf_size;
@@ -86,8 +80,10 @@ struct saa6588 {
 	int data_available_for_read;
 };
 
-static struct i2c_driver driver;
-static struct i2c_client client_template;
+static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa6588, sd);
+}
 
 /* ---------------------------------------------------------------------- */
 
@@ -258,6 +254,7 @@ static void block_to_buf(struct saa6588
 
 static void saa6588_i2c_poll(struct saa6588 *s)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
 	unsigned long flags;
 	unsigned char tmpbuf[6];
 	unsigned char blocknum;
@@ -265,7 +262,7 @@ static void saa6588_i2c_poll(struct saa6
 
 	/* Although we only need 3 bytes, we have to read at least 6.
 	   SAA6588 returns garbage otherwise */
-	if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
+	if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
 		if (debug > 1)
 			dprintk(PREFIX "read error!\n");
 		return;
@@ -316,23 +313,17 @@ static void saa6588_i2c_poll(struct saa6
 	wake_up_interruptible(&s->read_queue);
 }
 
-static void saa6588_timer(unsigned long data)
-{
-	struct saa6588 *s = (struct saa6588 *)data;
-
-	schedule_work(&s->work);
-}
-
 static void saa6588_work(struct work_struct *work)
 {
-	struct saa6588 *s = container_of(work, struct saa6588, work);
+	struct saa6588 *s = container_of(work, struct saa6588, work.work);
 
 	saa6588_i2c_poll(s);
-	mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
+	schedule_delayed_work(&s->work, msecs_to_jiffies(20));
 }
 
 static int saa6588_configure(struct saa6588 *s)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
 	unsigned char buf[3];
 	int rc;
 
@@ -380,7 +371,8 @@ static int saa6588_configure(struct saa6
 	dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
 		buf[0], buf[1], buf[2]);
 
-	if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
+	rc = i2c_master_send(client, buf, 3);
+	if (rc != 3)
 		printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
 
 	return 0;
@@ -388,70 +380,10 @@ static int saa6588_configure(struct saa6
 
 /* ---------------------------------------------------------------------- */
 
-static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
-{
-	struct saa6588 *s;
-	client_template.adapter = adap;
-	client_template.addr = addr;
-
-	printk(PREFIX "chip found @ 0x%x\n", addr << 1);
-
-	if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
-		return -ENOMEM;
-
-	s->buf_size = bufblocks * 3;
-
-	if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
-		kfree(s);
-		return -ENOMEM;
-	}
-	spin_lock_init(&s->lock);
-	s->client = client_template;
-	s->block_count = 0;
-	s->wr_index = 0;
-	s->rd_index = 0;
-	s->last_blocknum = 0xff;
-	init_waitqueue_head(&s->read_queue);
-	s->data_available_for_read = 0;
-	i2c_set_clientdata(&s->client, s);
-	i2c_attach_client(&s->client);
-
-	saa6588_configure(s);
-
-	/* start polling via eventd */
-	INIT_WORK(&s->work, saa6588_work);
-	init_timer(&s->timer);
-	s->timer.function = saa6588_timer;
-	s->timer.data = (unsigned long)s;
-	schedule_work(&s->work);
-	return 0;
-}
-
-static int saa6588_probe(struct i2c_adapter *adap)
-{
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, saa6588_attach);
-	return 0;
-}
-
-static int saa6588_detach(struct i2c_client *client)
-{
-	struct saa6588 *s = i2c_get_clientdata(client);
-
-	del_timer_sync(&s->timer);
-	flush_scheduled_work();
-
-	i2c_detach_client(client);
-	kfree(s->buffer);
-	kfree(s);
-	return 0;
-}
-
-static int saa6588_command(struct i2c_client *client, unsigned int cmd,
-							void *arg)
+static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
-	struct saa6588 *s = i2c_get_clientdata(client);
-	struct rds_command *a = (struct rds_command *)arg;
+	struct saa6588 *s = to_saa6588(sd);
+	struct rds_command *a = arg;
 
 	switch (cmd) {
 		/* --- open() for /dev/radio --- */
@@ -479,45 +411,94 @@ static int saa6588_command(struct i2c_cl
 
 	default:
 		/* nothing */
-		break;
+		return -ENOIOCTLCMD;
 	}
 	return 0;
 }
 
+static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver driver = {
-	.driver = {
-		.name = "saa6588",
-	},
-	.id = -1,		/* FIXME */
-	.attach_adapter = saa6588_probe,
-	.detach_client = saa6588_detach,
-	.command = saa6588_command,
+static const struct v4l2_subdev_core_ops saa6588_core_ops = {
+	.g_chip_ident = saa6588_g_chip_ident,
+	.ioctl = saa6588_ioctl,
 };
 
-static struct i2c_client client_template = {
-	.name = "saa6588",
-	.driver = &driver,
+static const struct v4l2_subdev_ops saa6588_ops = {
+	.core = &saa6588_core_ops,
 };
 
-static int __init saa6588_init_module(void)
+/* ---------------------------------------------------------------------- */
+
+static int saa6588_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
-	return i2c_add_driver(&driver);
+	struct saa6588 *s;
+	struct v4l2_subdev *sd;
+
+	v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	s = kzalloc(sizeof(*s), GFP_KERNEL);
+	if (s == NULL)
+		return -ENOMEM;
+
+	s->buf_size = bufblocks * 3;
+
+	s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
+	if (s->buffer == NULL) {
+		kfree(s);
+		return -ENOMEM;
+	}
+	sd = &s->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
+	spin_lock_init(&s->lock);
+	s->block_count = 0;
+	s->wr_index = 0;
+	s->rd_index = 0;
+	s->last_blocknum = 0xff;
+	init_waitqueue_head(&s->read_queue);
+	s->data_available_for_read = 0;
+
+	saa6588_configure(s);
+
+	/* start polling via eventd */
+	INIT_DELAYED_WORK(&s->work, saa6588_work);
+	schedule_delayed_work(&s->work, 0);
+	return 0;
 }
 
-static void __exit saa6588_cleanup_module(void)
+static int saa6588_remove(struct i2c_client *client)
 {
-	i2c_del_driver(&driver);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa6588 *s = to_saa6588(sd);
+
+	v4l2_device_unregister_subdev(sd);
+
+	cancel_delayed_work_sync(&s->work);
+
+	kfree(s->buffer);
+	kfree(s);
+	return 0;
 }
 
-module_init(saa6588_init_module);
-module_exit(saa6588_cleanup_module);
+/* ----------------------------------------------------------------------- */
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+static const struct i2c_device_id saa6588_id[] = {
+	{ "saa6588", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa6588_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa6588",
+	.probe = saa6588_probe,
+	.remove = saa6588_remove,
+	.id_table = saa6588_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7110.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7110.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7110.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7110.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,15 +33,16 @@
 #include <linux/wait.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
 MODULE_AUTHOR("Pauline Middelink");
 MODULE_LICENSE("GPL");
 
+
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -52,9 +53,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 #define SAA7110_NR_REG		0x35
 
 struct saa7110 {
+	struct v4l2_subdev sd;
 	u8 reg[SAA7110_NR_REG];
 
-	int norm;
+	v4l2_std_id norm;
 	int input;
 	int enable;
 	int bright;
@@ -65,20 +67,28 @@ struct saa7110 {
 	wait_queue_head_t wq;
 };
 
+static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa7110, sd);
+}
+
 /* ----------------------------------------------------------------------- */
 /* I2C support functions						   */
 /* ----------------------------------------------------------------------- */
 
-static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
-	struct saa7110 *decoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa7110 *decoder = to_saa7110(sd);
 
 	decoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa7110 *decoder = to_saa7110(sd);
 	int ret = -1;
 	u8 reg = *data;		/* first register to write to */
 
@@ -89,15 +99,13 @@ static int saa7110_write_block(struct i2
 	/* the saa7110 has an autoincrement function, use it if
 	 * the adapter understands raw I2C */
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		struct saa7110 *decoder = i2c_get_clientdata(client);
-
 		ret = i2c_master_send(client, data, len);
 
 		/* Cache the written data */
 		memcpy(decoder->reg + reg, data + 1, len - 1);
 	} else {
 		for (++data, --len; len; len--) {
-			ret = saa7110_write(client, reg++, *data++);
+			ret = saa7110_write(sd, reg++, *data++);
 			if (ret < 0)
 				break;
 		}
@@ -106,8 +114,10 @@ static int saa7110_write_block(struct i2
 	return ret;
 }
 
-static inline int saa7110_read(struct i2c_client *client)
+static inline int saa7110_read(struct v4l2_subdev *sd)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_read_byte(client);
 }
 
@@ -115,11 +125,11 @@ static inline int saa7110_read(struct i2
 /* SAA7110 functions							   */
 /* ----------------------------------------------------------------------- */
 
-#define FRESP_06H_COMPST 0x03	//0x13
-#define FRESP_06H_SVIDEO 0x83	//0xC0
+#define FRESP_06H_COMPST 0x03	/*0x13*/
+#define FRESP_06H_SVIDEO 0x83	/*0xC0*/
 
 
-static int saa7110_selmux(struct i2c_client *client, int chan)
+static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
 {
 	static const unsigned char modes[9][8] = {
 		/* mode 0 */
@@ -150,17 +160,17 @@ static int saa7110_selmux(struct i2c_cli
 		{FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
 			      0x44, 0x75, 0x21}
 	};
-	struct saa7110 *decoder = i2c_get_clientdata(client);
+	struct saa7110 *decoder = to_saa7110(sd);
 	const unsigned char *ptr = modes[chan];
 
-	saa7110_write(client, 0x06, ptr[0]);	/* Luminance control    */
-	saa7110_write(client, 0x20, ptr[1]);	/* Analog Control #1    */
-	saa7110_write(client, 0x21, ptr[2]);	/* Analog Control #2    */
-	saa7110_write(client, 0x22, ptr[3]);	/* Mixer Control #1     */
-	saa7110_write(client, 0x2C, ptr[4]);	/* Mixer Control #2     */
-	saa7110_write(client, 0x30, ptr[5]);	/* ADCs gain control    */
-	saa7110_write(client, 0x31, ptr[6]);	/* Mixer Control #3     */
-	saa7110_write(client, 0x21, ptr[7]);	/* Analog Control #2    */
+	saa7110_write(sd, 0x06, ptr[0]);	/* Luminance control    */
+	saa7110_write(sd, 0x20, ptr[1]);	/* Analog Control #1    */
+	saa7110_write(sd, 0x21, ptr[2]);	/* Analog Control #2    */
+	saa7110_write(sd, 0x22, ptr[3]);	/* Mixer Control #1     */
+	saa7110_write(sd, 0x2C, ptr[4]);	/* Mixer Control #2     */
+	saa7110_write(sd, 0x30, ptr[5]);	/* ADCs gain control    */
+	saa7110_write(sd, 0x31, ptr[6]);	/* Mixer Control #3     */
+	saa7110_write(sd, 0x21, ptr[7]);	/* Analog Control #2    */
 	decoder->input = chan;
 
 	return 0;
@@ -176,246 +186,257 @@ static const unsigned char initseq[1 + S
 	/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
 };
 
-static int determine_norm(struct i2c_client *client)
+static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
 {
 	DEFINE_WAIT(wait);
-	struct saa7110 *decoder = i2c_get_clientdata(client);
+	struct saa7110 *decoder = to_saa7110(sd);
 	int status;
 
 	/* mode changed, start automatic detection */
-	saa7110_write_block(client, initseq, sizeof(initseq));
-	saa7110_selmux(client, decoder->input);
+	saa7110_write_block(sd, initseq, sizeof(initseq));
+	saa7110_selmux(sd, decoder->input);
 	prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
 	schedule_timeout(msecs_to_jiffies(250));
 	finish_wait(&decoder->wq, &wait);
-	status = saa7110_read(client);
+	status = saa7110_read(sd);
 	if (status & 0x40) {
-		v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
-		return decoder->norm;	// no change
+		v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
+		return decoder->norm;	/* no change*/
 	}
 	if ((status & 3) == 0) {
-		saa7110_write(client, 0x06, 0x83);
+		saa7110_write(sd, 0x06, 0x83);
 		if (status & 0x20) {
-			v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
-			//saa7110_write(client,0x2E,0x81);
-			return VIDEO_MODE_NTSC;
+			v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
+			/*saa7110_write(sd,0x2E,0x81);*/
+			return V4L2_STD_NTSC;
 		}
-		v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
-		//saa7110_write(client,0x2E,0x9A);
-		return VIDEO_MODE_PAL;
+		v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
+		/*saa7110_write(sd,0x2E,0x9A);*/
+		return V4L2_STD_PAL;
 	}
-	//saa7110_write(client,0x06,0x03);
+	/*saa7110_write(sd,0x06,0x03);*/
 	if (status & 0x20) {	/* 60Hz */
-		v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
-		saa7110_write(client, 0x0D, 0x86);
-		saa7110_write(client, 0x0F, 0x50);
-		saa7110_write(client, 0x11, 0x2C);
-		//saa7110_write(client,0x2E,0x81);
-		return VIDEO_MODE_NTSC;
+		v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
+		saa7110_write(sd, 0x0D, 0x86);
+		saa7110_write(sd, 0x0F, 0x50);
+		saa7110_write(sd, 0x11, 0x2C);
+		/*saa7110_write(sd,0x2E,0x81);*/
+		return V4L2_STD_NTSC;
 	}
 
 	/* 50Hz -> PAL/SECAM */
-	saa7110_write(client, 0x0D, 0x86);
-	saa7110_write(client, 0x0F, 0x10);
-	saa7110_write(client, 0x11, 0x59);
-	//saa7110_write(client,0x2E,0x9A);
+	saa7110_write(sd, 0x0D, 0x86);
+	saa7110_write(sd, 0x0F, 0x10);
+	saa7110_write(sd, 0x11, 0x59);
+	/*saa7110_write(sd,0x2E,0x9A);*/
 
 	prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
 	schedule_timeout(msecs_to_jiffies(250));
 	finish_wait(&decoder->wq, &wait);
 
-	status = saa7110_read(client);
+	status = saa7110_read(sd);
 	if ((status & 0x03) == 0x01) {
-		v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
-		saa7110_write(client, 0x0D, 0x87);
-		return VIDEO_MODE_SECAM;
+		v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
+		saa7110_write(sd, 0x0D, 0x87);
+		return V4L2_STD_SECAM;
 	}
-	v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
-	return VIDEO_MODE_PAL;
+	v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
+	return V4L2_STD_PAL;
 }
 
-static int
-saa7110_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
 {
-	struct saa7110 *decoder = i2c_get_clientdata(client);
-	int v;
+	struct saa7110 *decoder = to_saa7110(sd);
+	int res = V4L2_IN_ST_NO_SIGNAL;
+	int status = saa7110_read(sd);
 
-	switch (cmd) {
-	case 0:
-		//saa7110_write_block(client, initseq, sizeof(initseq));
-		break;
+	v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
+		       status, (unsigned long long)decoder->norm);
+	if (!(status & 0x40))
+		res = 0;
+	if (!(status & 0x03))
+		res |= V4L2_IN_ST_NO_COLOR;
 
-	case DECODER_GET_CAPABILITIES:
-	{
-		struct video_decoder_capability *dc = arg;
+	*pstatus = res;
+	return 0;
+}
 
-		dc->flags =
-		    VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
-		    VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
-		dc->inputs = SAA7110_MAX_INPUT;
-		dc->outputs = SAA7110_MAX_OUTPUT;
-		break;
+static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	*(v4l2_std_id *)std = determine_norm(sd);
+	return 0;
+}
+
+static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct saa7110 *decoder = to_saa7110(sd);
+
+	if (decoder->norm != std) {
+		decoder->norm = std;
+		/*saa7110_write(sd, 0x06, 0x03);*/
+		if (std & V4L2_STD_NTSC) {
+			saa7110_write(sd, 0x0D, 0x86);
+			saa7110_write(sd, 0x0F, 0x50);
+			saa7110_write(sd, 0x11, 0x2C);
+			/*saa7110_write(sd, 0x2E, 0x81);*/
+			v4l2_dbg(1, debug, sd, "switched to NTSC\n");
+		} else if (std & V4L2_STD_PAL) {
+			saa7110_write(sd, 0x0D, 0x86);
+			saa7110_write(sd, 0x0F, 0x10);
+			saa7110_write(sd, 0x11, 0x59);
+			/*saa7110_write(sd, 0x2E, 0x9A);*/
+			v4l2_dbg(1, debug, sd, "switched to PAL\n");
+		} else if (std & V4L2_STD_SECAM) {
+			saa7110_write(sd, 0x0D, 0x87);
+			saa7110_write(sd, 0x0F, 0x10);
+			saa7110_write(sd, 0x11, 0x59);
+			/*saa7110_write(sd, 0x2E, 0x9A);*/
+			v4l2_dbg(1, debug, sd, "switched to SECAM\n");
+		} else {
+			return -EINVAL;
+		}
 	}
+	return 0;
+}
 
-	case DECODER_GET_STATUS:
-	{
-		int status;
-		int res = 0;
+static int saa7110_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
+{
+	struct saa7110 *decoder = to_saa7110(sd);
 
-		status = saa7110_read(client);
-		v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
-			       status, decoder->norm);
-		if (!(status & 0x40))
-			res |= DECODER_STATUS_GOOD;
-		if (status & 0x03)
-			res |= DECODER_STATUS_COLOR;
+	if (input < 0 || input >= SAA7110_MAX_INPUT) {
+		v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
+		return -EINVAL;
+	}
+	if (decoder->input != input) {
+		saa7110_selmux(sd, input);
+		v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
+	}
+	return 0;
+}
 
-		switch (decoder->norm) {
-		case VIDEO_MODE_NTSC:
-			res |= DECODER_STATUS_NTSC;
-			break;
-		case VIDEO_MODE_PAL:
-			res |= DECODER_STATUS_PAL;
-			break;
-		case VIDEO_MODE_SECAM:
-			res |= DECODER_STATUS_SECAM;
-			break;
-		}
-		*(int *) arg = res;
-		break;
+static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct saa7110 *decoder = to_saa7110(sd);
+
+	if (decoder->enable != enable) {
+		decoder->enable = enable;
+		saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
+		v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
 	}
+	return 0;
+}
 
-	case DECODER_SET_NORM:
-		v = *(int *) arg;
-		if (decoder->norm != v) {
-			decoder->norm = v;
-			//saa7110_write(client, 0x06, 0x03);
-			switch (v) {
-			case VIDEO_MODE_NTSC:
-				saa7110_write(client, 0x0D, 0x86);
-				saa7110_write(client, 0x0F, 0x50);
-				saa7110_write(client, 0x11, 0x2C);
-				//saa7110_write(client, 0x2E, 0x81);
-				v4l_dbg(1, debug, client, "switched to NTSC\n");
-				break;
-			case VIDEO_MODE_PAL:
-				saa7110_write(client, 0x0D, 0x86);
-				saa7110_write(client, 0x0F, 0x10);
-				saa7110_write(client, 0x11, 0x59);
-				//saa7110_write(client, 0x2E, 0x9A);
-				v4l_dbg(1, debug, client, "switched to PAL\n");
-				break;
-			case VIDEO_MODE_SECAM:
-				saa7110_write(client, 0x0D, 0x87);
-				saa7110_write(client, 0x0F, 0x10);
-				saa7110_write(client, 0x11, 0x59);
-				//saa7110_write(client, 0x2E, 0x9A);
-				v4l_dbg(1, debug, client, "switched to SECAM\n");
-				break;
-			case VIDEO_MODE_AUTO:
-				v4l_dbg(1, debug, client, "switched to AUTO\n");
-				decoder->norm = determine_norm(client);
-				*(int *) arg = decoder->norm;
-				break;
-			default:
-				return -EPERM;
-			}
-		}
-		break;
+static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+	case V4L2_CID_CONTRAST:
+	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+	case V4L2_CID_HUE:
+		return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
 
-	case DECODER_SET_INPUT:
-		v = *(int *) arg;
-		if (v < 0 || v >= SAA7110_MAX_INPUT) {
-			v4l_dbg(1, debug, client, "input=%d not available\n", v);
-			return -EINVAL;
-		}
-		if (decoder->input != v) {
-			saa7110_selmux(client, v);
-			v4l_dbg(1, debug, client, "switched to input=%d\n", v);
-		}
-		break;
+static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct saa7110 *decoder = to_saa7110(sd);
 
-	case DECODER_SET_OUTPUT:
-		v = *(int *) arg;
-		/* not much choice of outputs */
-		if (v != 0)
-			return -EINVAL;
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = decoder->bright;
 		break;
-
-	case DECODER_ENABLE_OUTPUT:
-		v = *(int *) arg;
-		if (decoder->enable != v) {
-			decoder->enable = v;
-			saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
-			v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
-		}
+	case V4L2_CID_CONTRAST:
+		ctrl->value = decoder->contrast;
 		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = decoder->sat;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = decoder->hue;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
 
-	case DECODER_SET_PICTURE:
-	{
-		struct video_picture *pic = arg;
+static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct saa7110 *decoder = to_saa7110(sd);
 
-		if (decoder->bright != pic->brightness) {
-			/* We want 0 to 255 we get 0-65535 */
-			decoder->bright = pic->brightness;
-			saa7110_write(client, 0x19, decoder->bright >> 8);
-		}
-		if (decoder->contrast != pic->contrast) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->contrast = pic->contrast;
-			saa7110_write(client, 0x13,
-				      decoder->contrast >> 9);
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (decoder->bright != ctrl->value) {
+			decoder->bright = ctrl->value;
+			saa7110_write(sd, 0x19, decoder->bright);
 		}
-		if (decoder->sat != pic->colour) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->sat = pic->colour;
-			saa7110_write(client, 0x12, decoder->sat >> 9);
+		break;
+	case V4L2_CID_CONTRAST:
+		if (decoder->contrast != ctrl->value) {
+			decoder->contrast = ctrl->value;
+			saa7110_write(sd, 0x13, decoder->contrast);
 		}
-		if (decoder->hue != pic->hue) {
-			/* We want -128 to 127 we get 0-65535 */
-			decoder->hue = pic->hue;
-			saa7110_write(client, 0x07,
-				      (decoder->hue >> 8) - 128);
+		break;
+	case V4L2_CID_SATURATION:
+		if (decoder->sat != ctrl->value) {
+			decoder->sat = ctrl->value;
+			saa7110_write(sd, 0x12, decoder->sat);
 		}
 		break;
-	}
-
-	case DECODER_DUMP:
-		if (!debug)
-			break;
-		for (v = 0; v < SAA7110_NR_REG; v += 16) {
-			int j;
-			v4l_dbg(1, debug, client, "%02x:", v);
-			for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
-				printk(KERN_CONT " %02x", decoder->reg[v + j]);
-			printk(KERN_CONT "\n");
+	case V4L2_CID_HUE:
+		if (decoder->hue != ctrl->value) {
+			decoder->hue = ctrl->value;
+			saa7110_write(sd, 0x07, decoder->hue);
 		}
 		break;
-
 	default:
-		v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
 		return -EINVAL;
 	}
 	return 0;
 }
 
+static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
+static const struct v4l2_subdev_core_ops saa7110_core_ops = {
+	.g_chip_ident = saa7110_g_chip_ident,
+	.g_ctrl = saa7110_g_ctrl,
+	.s_ctrl = saa7110_s_ctrl,
+	.queryctrl = saa7110_queryctrl,
+	.s_std = saa7110_s_std,
+};
 
-static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_video_ops saa7110_video_ops = {
+	.s_routing = saa7110_s_routing,
+	.s_stream = saa7110_s_stream,
+	.querystd = saa7110_querystd,
+	.g_input_status = saa7110_g_input_status,
+};
 
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops saa7110_ops = {
+	.core = &saa7110_core_ops,
+	.video = &saa7110_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
 
 static int saa7110_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct saa7110 *decoder;
+	struct v4l2_subdev *sd;
 	int rv;
 
 	/* Check if the adapter supports the needed features */
@@ -429,7 +450,9 @@ static int saa7110_probe(struct i2c_clie
 	decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
-	decoder->norm = VIDEO_MODE_PAL;
+	sd = &decoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
+	decoder->norm = V4L2_STD_PAL;
 	decoder->input = 0;
 	decoder->enable = 1;
 	decoder->bright = 32768;
@@ -437,30 +460,29 @@ static int saa7110_probe(struct i2c_clie
 	decoder->hue = 32768;
 	decoder->sat = 32768;
 	init_waitqueue_head(&decoder->wq);
-	i2c_set_clientdata(client, decoder);
 
-	rv = saa7110_write_block(client, initseq, sizeof(initseq));
+	rv = saa7110_write_block(sd, initseq, sizeof(initseq));
 	if (rv < 0) {
-		v4l_dbg(1, debug, client, "init status %d\n", rv);
+		v4l2_dbg(1, debug, sd, "init status %d\n", rv);
 	} else {
 		int ver, status;
-		saa7110_write(client, 0x21, 0x10);
-		saa7110_write(client, 0x0e, 0x18);
-		saa7110_write(client, 0x0D, 0x04);
-		ver = saa7110_read(client);
-		saa7110_write(client, 0x0D, 0x06);
-		//mdelay(150);
-		status = saa7110_read(client);
-		v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+		saa7110_write(sd, 0x21, 0x10);
+		saa7110_write(sd, 0x0e, 0x18);
+		saa7110_write(sd, 0x0D, 0x04);
+		ver = saa7110_read(sd);
+		saa7110_write(sd, 0x0D, 0x06);
+		/*mdelay(150);*/
+		status = saa7110_read(sd);
+		v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
 			       ver, status);
-		saa7110_write(client, 0x0D, 0x86);
-		saa7110_write(client, 0x0F, 0x10);
-		saa7110_write(client, 0x11, 0x59);
-		//saa7110_write(client, 0x2E, 0x9A);
+		saa7110_write(sd, 0x0D, 0x86);
+		saa7110_write(sd, 0x0F, 0x10);
+		saa7110_write(sd, 0x11, 0x59);
+		/*saa7110_write(sd, 0x2E, 0x9A);*/
 	}
 
-	//saa7110_selmux(client,0);
-	//determine_norm(client);
+	/*saa7110_selmux(sd,0);*/
+	/*determine_norm(sd);*/
 	/* setup and implicit mode 0 select has been performed */
 
 	return 0;
@@ -468,7 +490,10 @@ static int saa7110_probe(struct i2c_clie
 
 static int saa7110_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_saa7110(sd));
 	return 0;
 }
 
@@ -482,8 +507,6 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7110",
-	.driverid = I2C_DRIVERID_SAA7110,
-	.command = saa7110_command,
 	.probe = saa7110_probe,
 	.remove = saa7110_remove,
 	.id_table = saa7110_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7111.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7111.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7111.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7111.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,492 +0,0 @@
-/*
- * saa7111 - Philips SAA7111A video decoder driver version 0.0.3
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *    - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * Changes by Michael Hunold <michael@mihu.de>
- *    - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU 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/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
-MODULE_AUTHOR("Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-#define SAA7111_NR_REG		0x18
-
-struct saa7111 {
-	unsigned char reg[SAA7111_NR_REG];
-
-	int norm;
-	int input;
-	int enable;
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
-{
-	struct saa7111 *decoder = i2c_get_clientdata(client);
-
-	decoder->reg[reg] = value;
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
-{
-	struct saa7111 *decoder = i2c_get_clientdata(client);
-
-	if (decoder->reg[reg] != value) {
-		decoder->reg[reg] = value;
-		i2c_smbus_write_byte_data(client, reg, value);
-	}
-}
-
-static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
-	int ret = -1;
-	u8 reg;
-
-	/* the saa7111 has an autoincrement function, use it if
-	 * the adapter understands raw I2C */
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		/* do raw I2C, not smbus compatible */
-		struct saa7111 *decoder = i2c_get_clientdata(client);
-		u8 block_data[32];
-		int block_len;
-
-		while (len >= 2) {
-			block_len = 0;
-			block_data[block_len++] = reg = data[0];
-			do {
-				block_data[block_len++] =
-				    decoder->reg[reg++] = data[1];
-				len -= 2;
-				data += 2;
-			} while (len >= 2 && data[0] == reg && block_len < 32);
-			ret = i2c_master_send(client, block_data, block_len);
-			if (ret < 0)
-				break;
-		}
-	} else {
-		/* do some slow I2C emulation kind of thing */
-		while (len >= 2) {
-			reg = *data++;
-			ret = saa7111_write(client, reg, *data++);
-			if (ret < 0)
-				break;
-			len -= 2;
-		}
-	}
-
-	return ret;
-}
-
-static int saa7111_init_decoder(struct i2c_client *client,
-		struct video_decoder_init *init)
-{
-	return saa7111_write_block(client, init->data, init->len);
-}
-
-static inline int saa7111_read(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char saa7111_i2c_init[] = {
-	0x00, 0x00,		/* 00 - ID byte */
-	0x01, 0x00,		/* 01 - reserved */
-
-	/*front end */
-	0x02, 0xd0,		/* 02 - FUSE=3, GUDL=2, MODE=0 */
-	0x03, 0x23,		/* 03 - HLNRS=0, VBSL=1, WPOFF=0,
-				 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
-	0x04, 0x00,		/* 04 - GAI1=256 */
-	0x05, 0x00,		/* 05 - GAI2=256 */
-
-	/* decoder */
-	0x06, 0xf3,		/* 06 - HSB at  13(50Hz) /  17(60Hz)
-				 * pixels after end of last line */
-	/*0x07, 0x13,     * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
-				 * after end of last line */
-	0x07, 0xe8,		/* 07 - HSS seems to be needed to
-				 * work with NTSC, too */
-	0x08, 0xc8,		/* 08 - AUFD=1, FSEL=1, EXFIL=0,
-				 * VTRC=1, HPLL=0, VNOI=0 */
-	0x09, 0x01,		/* 09 - BYPS=0, PREF=0, BPSS=0,
-				 * VBLB=0, UPTCV=0, APER=1 */
-	0x0a, 0x80,		/* 0a - BRIG=128 */
-	0x0b, 0x47,		/* 0b - CONT=1.109 */
-	0x0c, 0x40,		/* 0c - SATN=1.0 */
-	0x0d, 0x00,		/* 0d - HUE=0 */
-	0x0e, 0x01,		/* 0e - CDTO=0, CSTD=0, DCCF=0,
-				 * FCTC=0, CHBW=1 */
-	0x0f, 0x00,		/* 0f - reserved */
-	0x10, 0x48,		/* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
-	0x11, 0x1c,		/* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
-				 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
-	0x12, 0x00,		/* 12 - output control 2 */
-	0x13, 0x00,		/* 13 - output control 3 */
-	0x14, 0x00,		/* 14 - reserved */
-	0x15, 0x00,		/* 15 - VBI */
-	0x16, 0x00,		/* 16 - VBI */
-	0x17, 0x00,		/* 17 - VBI */
-};
-
-static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	struct saa7111 *decoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-		break;
-	case DECODER_INIT:
-	{
-		struct video_decoder_init *init = arg;
-		struct video_decoder_init vdi;
-
-		if (NULL != init)
-			return saa7111_init_decoder(client, init);
-		vdi.data = saa7111_i2c_init;
-		vdi.len = sizeof(saa7111_i2c_init);
-		return saa7111_init_decoder(client, &vdi);
-	}
-
-	case DECODER_DUMP:
-	{
-		int i;
-
-		for (i = 0; i < SAA7111_NR_REG; i += 16) {
-			int j;
-
-			v4l_info(client, "%03x", i);
-			for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
-				printk(KERN_CONT " %02x",
-				       saa7111_read(client, i + j));
-			}
-			printk(KERN_CONT "\n");
-		}
-		break;
-	}
-
-	case DECODER_GET_CAPABILITIES:
-	{
-		struct video_decoder_capability *cap = arg;
-
-		cap->flags = VIDEO_DECODER_PAL |
-			     VIDEO_DECODER_NTSC |
-			     VIDEO_DECODER_SECAM |
-			     VIDEO_DECODER_AUTO |
-			     VIDEO_DECODER_CCIR;
-		cap->inputs = 8;
-		cap->outputs = 1;
-		break;
-	}
-
-	case DECODER_GET_STATUS:
-	{
-		int *iarg = arg;
-		int status;
-		int res;
-
-		status = saa7111_read(client, 0x1f);
-		v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
-		res = 0;
-		if ((status & (1 << 6)) == 0) {
-			res |= DECODER_STATUS_GOOD;
-		}
-		switch (decoder->norm) {
-		case VIDEO_MODE_NTSC:
-			res |= DECODER_STATUS_NTSC;
-			break;
-		case VIDEO_MODE_PAL:
-			res |= DECODER_STATUS_PAL;
-			break;
-		case VIDEO_MODE_SECAM:
-			res |= DECODER_STATUS_SECAM;
-			break;
-		default:
-		case VIDEO_MODE_AUTO:
-			if ((status & (1 << 5)) != 0) {
-				res |= DECODER_STATUS_NTSC;
-			} else {
-				res |= DECODER_STATUS_PAL;
-			}
-			break;
-		}
-		if ((status & (1 << 0)) != 0) {
-			res |= DECODER_STATUS_COLOR;
-		}
-		*iarg = res;
-		break;
-	}
-
-	case DECODER_SET_GPIO:
-	{
-		int *iarg = arg;
-		if (0 != *iarg) {
-			saa7111_write(client, 0x11,
-				(decoder->reg[0x11] | 0x80));
-		} else {
-			saa7111_write(client, 0x11,
-				(decoder->reg[0x11] & 0x7f));
-		}
-		break;
-	}
-
-	case DECODER_SET_VBI_BYPASS:
-	{
-		int *iarg = arg;
-		if (0 != *iarg) {
-			saa7111_write(client, 0x13,
-				(decoder->reg[0x13] & 0xf0) | 0x0a);
-		} else {
-			saa7111_write(client, 0x13,
-				(decoder->reg[0x13] & 0xf0));
-		}
-		break;
-	}
-
-	case DECODER_SET_NORM:
-	{
-		int *iarg = arg;
-
-		switch (*iarg) {
-
-		case VIDEO_MODE_NTSC:
-			saa7111_write(client, 0x08,
-				      (decoder->reg[0x08] & 0x3f) | 0x40);
-			saa7111_write(client, 0x0e,
-				      (decoder->reg[0x0e] & 0x8f));
-			break;
-
-		case VIDEO_MODE_PAL:
-			saa7111_write(client, 0x08,
-				      (decoder->reg[0x08] & 0x3f) | 0x00);
-			saa7111_write(client, 0x0e,
-				      (decoder->reg[0x0e] & 0x8f));
-			break;
-
-		case VIDEO_MODE_SECAM:
-			saa7111_write(client, 0x08,
-				      (decoder->reg[0x08] & 0x3f) | 0x00);
-			saa7111_write(client, 0x0e,
-				      (decoder->reg[0x0e] & 0x8f) | 0x50);
-			break;
-
-		case VIDEO_MODE_AUTO:
-			saa7111_write(client, 0x08,
-				      (decoder->reg[0x08] & 0x3f) | 0x80);
-			saa7111_write(client, 0x0e,
-				      (decoder->reg[0x0e] & 0x8f));
-			break;
-
-		default:
-			return -EINVAL;
-
-		}
-		decoder->norm = *iarg;
-		break;
-	}
-
-	case DECODER_SET_INPUT:
-	{
-		int *iarg = arg;
-
-		if (*iarg < 0 || *iarg > 7) {
-			return -EINVAL;
-		}
-
-		if (decoder->input != *iarg) {
-			decoder->input = *iarg;
-			/* select mode */
-			saa7111_write(client, 0x02,
-				      (decoder->
-				       reg[0x02] & 0xf8) | decoder->input);
-			/* bypass chrominance trap for modes 4..7 */
-			saa7111_write(client, 0x09,
-				      (decoder->
-				       reg[0x09] & 0x7f) | ((decoder->
-							     input >
-							     3) ? 0x80 :
-							    0));
-		}
-		break;
-	}
-
-	case DECODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
-
-		/* not much choice of outputs */
-		if (*iarg != 0) {
-			return -EINVAL;
-		}
-		break;
-	}
-
-	case DECODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-		int enable = (*iarg != 0);
-
-		if (decoder->enable != enable) {
-			decoder->enable = enable;
-
-			/* RJ: If output should be disabled (for
-			 * playing videos), we also need a open PLL.
-			 * The input is set to 0 (where no input
-			 * source is connected), although this
-			 * is not necessary.
-			 *
-			 * If output should be enabled, we have to
-			 * reverse the above.
-			 */
-
-			if (decoder->enable) {
-				saa7111_write(client, 0x02,
-					      (decoder->
-					       reg[0x02] & 0xf8) |
-					      decoder->input);
-				saa7111_write(client, 0x08,
-					      (decoder->reg[0x08] & 0xfb));
-				saa7111_write(client, 0x11,
-					      (decoder->
-					       reg[0x11] & 0xf3) | 0x0c);
-			} else {
-				saa7111_write(client, 0x02,
-					      (decoder->reg[0x02] & 0xf8));
-				saa7111_write(client, 0x08,
-					      (decoder->
-					       reg[0x08] & 0xfb) | 0x04);
-				saa7111_write(client, 0x11,
-					      (decoder->reg[0x11] & 0xf3));
-			}
-		}
-		break;
-	}
-
-	case DECODER_SET_PICTURE:
-	{
-		struct video_picture *pic = arg;
-
-		/* We want 0 to 255 we get 0-65535 */
-		saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
-		/* We want 0 to 127 we get 0-65535 */
-		saa7111_write(client, 0x0b, pic->contrast >> 9);
-		/* We want 0 to 127 we get 0-65535 */
-		saa7111_write(client, 0x0c, pic->colour >> 9);
-		/* We want -128 to 127 we get 0-65535 */
-		saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
-		break;
-	}
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7111_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	int i;
-	struct saa7111 *decoder;
-	struct video_decoder_init vdi;
-
-	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	v4l_info(client, "chip found @ 0x%x (%s)\n",
-			client->addr << 1, client->adapter->name);
-
-	decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
-	if (decoder == NULL) {
-		kfree(client);
-		return -ENOMEM;
-	}
-	decoder->norm = VIDEO_MODE_NTSC;
-	decoder->input = 0;
-	decoder->enable = 1;
-	i2c_set_clientdata(client, decoder);
-
-	vdi.data = saa7111_i2c_init;
-	vdi.len = sizeof(saa7111_i2c_init);
-	i = saa7111_init_decoder(client, &vdi);
-	if (i < 0) {
-		v4l_dbg(1, debug, client, "init status %d\n", i);
-	} else {
-		v4l_dbg(1, debug, client, "revision %x\n",
-			saa7111_read(client, 0x00) >> 4);
-	}
-	return 0;
-}
-
-static int saa7111_remove(struct i2c_client *client)
-{
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7111_id[] = {
-	{ "saa7111_old", 0 },	/* "saa7111" maps to the saa7115 driver */
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, saa7111_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
-	.name = "saa7111",
-	.driverid = I2C_DRIVERID_SAA7111A,
-	.command = saa7111_command,
-	.probe = saa7111_probe,
-	.remove = saa7111_remove,
-	.id_table = saa7111_id,
-};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7114.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7114.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7114.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7114.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1068 +0,0 @@
-/*
- * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
- *
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Based on saa7111 driver by Dave Perks
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *    - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU 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/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7114 {
-	unsigned char reg[0xf0 * 2];
-
-	int norm;
-	int input;
-	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
-	int playback;
-};
-
-#define   I2C_DELAY   10
-
-
-//#define SAA_7114_NTSC_HSYNC_START       (-3)
-//#define SAA_7114_NTSC_HSYNC_STOP        (-18)
-
-#define SAA_7114_NTSC_HSYNC_START  (-17)
-#define SAA_7114_NTSC_HSYNC_STOP   (-32)
-
-//#define SAA_7114_NTSC_HOFFSET           (5)
-#define SAA_7114_NTSC_HOFFSET		(6)
-#define SAA_7114_NTSC_VOFFSET           (10)
-#define SAA_7114_NTSC_WIDTH             (720)
-#define SAA_7114_NTSC_HEIGHT            (250)
-
-#define SAA_7114_SECAM_HSYNC_START      (-17)
-#define SAA_7114_SECAM_HSYNC_STOP       (-32)
-
-#define SAA_7114_SECAM_HOFFSET          (2)
-#define SAA_7114_SECAM_VOFFSET          (10)
-#define SAA_7114_SECAM_WIDTH            (720)
-#define SAA_7114_SECAM_HEIGHT           (300)
-
-#define SAA_7114_PAL_HSYNC_START        (-17)
-#define SAA_7114_PAL_HSYNC_STOP         (-32)
-
-#define SAA_7114_PAL_HOFFSET            (2)
-#define SAA_7114_PAL_VOFFSET            (10)
-#define SAA_7114_PAL_WIDTH              (720)
-#define SAA_7114_PAL_HEIGHT             (300)
-
-
-
-#define SAA_7114_VERTICAL_CHROMA_OFFSET         0	//0x50504040
-#define SAA_7114_VERTICAL_LUMA_OFFSET           0
-
-#define REG_ADDR(x) (((x) << 1) + 1)
-#define LOBYTE(x) ((unsigned char)((x) & 0xff))
-#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
-#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
-#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
-
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
-	int ret = -1;
-	u8 reg;
-
-	/* the saa7114 has an autoincrement function, use it if
-	 * the adapter understands raw I2C */
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		/* do raw I2C, not smbus compatible */
-		u8 block_data[32];
-		int block_len;
-
-		while (len >= 2) {
-			block_len = 0;
-			block_data[block_len++] = reg = data[0];
-			do {
-				block_data[block_len++] = data[1];
-				reg++;
-				len -= 2;
-				data += 2;
-			} while (len >= 2 && data[0] == reg && block_len < 32);
-			ret = i2c_master_send(client, block_data, block_len);
-			if (ret < 0)
-				break;
-		}
-	} else {
-		/* do some slow I2C emulation kind of thing */
-		while (len >= 2) {
-			reg = *data++;
-			ret = saa7114_write(client, reg, *data++);
-			if (ret < 0)
-				break;
-			len -= 2;
-		}
-	}
-
-	return ret;
-}
-
-static inline int saa7114_read(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-// initially set NTSC, composite
-
-
-static const unsigned char init[] = {
-	0x00, 0x00,		/* 00 - ID byte , chip version,
-				 * read only */
-	0x01, 0x08,		/* 01 - X,X,X,X, IDEL3 to IDEL0 -
-				 * horizontal increment delay,
-				 * recommended position */
-	0x02, 0x00,		/* 02 - FUSE=3, GUDL=2, MODE=0 ;
-				 * input control */
-	0x03, 0x10,		/* 03 - HLNRS=0, VBSL=1, WPOFF=0,
-				 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
-	0x04, 0x90,		/* 04 - GAI1=256 */
-	0x05, 0x90,		/* 05 - GAI2=256 */
-	0x06, SAA_7114_NTSC_HSYNC_START,	/* 06 - HSB: hsync start,
-				 * depends on the video standard */
-	0x07, SAA_7114_NTSC_HSYNC_STOP,	/* 07 - HSS: hsync stop, depends
-				 *on the video standard */
-	0x08, 0xb8,		/* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
-				 * HPLL: free running in playback, locked
-				 * in capture, VNOI=0 */
-	0x09, 0x80,		/* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
-				 * UPTCV=0, APER=1; depends from input */
-	0x0a, 0x80,		/* 0a - BRIG=128 */
-	0x0b, 0x44,		/* 0b - CONT=1.109 */
-	0x0c, 0x40,		/* 0c - SATN=1.0 */
-	0x0d, 0x00,		/* 0d - HUE=0 */
-	0x0e, 0x84,		/* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
-				 * CCOMB; depends from video standard */
-	0x0f, 0x24,		/* 0f - ACGC,CGAIN6 to CGAIN0; depends
-				 * from video standard */
-	0x10, 0x03,		/* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
-				 * LCBW2 to 0 */
-	0x11, 0x59,		/* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
-				 * YDEL2 to 0 */
-	0x12, 0xc9,		/* 12 - RT signal control RTSE13 to 10
-				 * and 03 to 00 */
-	0x13, 0x80,		/* 13 - RT/X port output control  */
-	0x14, 0x00,		/* 14 - analog, ADC, compatibility control */
-	0x15, 0x00,		/* 15 - VGATE start FID change  */
-	0x16, 0xfe,		/* 16 - VGATE stop */
-	0x17, 0x00,		/* 17 - Misc., VGATE MSBs */
-	0x18, 0x40,		/* RAWG */
-	0x19, 0x80,		/* RAWO */
-	0x1a, 0x00,
-	0x1b, 0x00,
-	0x1c, 0x00,
-	0x1d, 0x00,
-	0x1e, 0x00,
-	0x1f, 0x00,		/* status byte, read only */
-	0x20, 0x00,		/* video decoder reserved part */
-	0x21, 0x00,
-	0x22, 0x00,
-	0x23, 0x00,
-	0x24, 0x00,
-	0x25, 0x00,
-	0x26, 0x00,
-	0x27, 0x00,
-	0x28, 0x00,
-	0x29, 0x00,
-	0x2a, 0x00,
-	0x2b, 0x00,
-	0x2c, 0x00,
-	0x2d, 0x00,
-	0x2e, 0x00,
-	0x2f, 0x00,
-	0x30, 0xbc,		/* audio clock generator */
-	0x31, 0xdf,
-	0x32, 0x02,
-	0x33, 0x00,
-	0x34, 0xcd,
-	0x35, 0xcc,
-	0x36, 0x3a,
-	0x37, 0x00,
-	0x38, 0x03,
-	0x39, 0x10,
-	0x3a, 0x00,
-	0x3b, 0x00,
-	0x3c, 0x00,
-	0x3d, 0x00,
-	0x3e, 0x00,
-	0x3f, 0x00,
-	0x40, 0x00,		/* VBI data slicer */
-	0x41, 0xff,
-	0x42, 0xff,
-	0x43, 0xff,
-	0x44, 0xff,
-	0x45, 0xff,
-	0x46, 0xff,
-	0x47, 0xff,
-	0x48, 0xff,
-	0x49, 0xff,
-	0x4a, 0xff,
-	0x4b, 0xff,
-	0x4c, 0xff,
-	0x4d, 0xff,
-	0x4e, 0xff,
-	0x4f, 0xff,
-	0x50, 0xff,
-	0x51, 0xff,
-	0x52, 0xff,
-	0x53, 0xff,
-	0x54, 0xff,
-	0x55, 0xff,
-	0x56, 0xff,
-	0x57, 0xff,
-	0x58, 0x40,		// framing code
-	0x59, 0x47,		// horizontal offset
-	0x5a, 0x06,		// vertical offset
-	0x5b, 0x83,		// field offset
-	0x5c, 0x00,		// reserved
-	0x5d, 0x3e,		// header and data
-	0x5e, 0x00,		// sliced data
-	0x5f, 0x00,		// reserved
-	0x60, 0x00,		/* video decoder reserved part */
-	0x61, 0x00,
-	0x62, 0x00,
-	0x63, 0x00,
-	0x64, 0x00,
-	0x65, 0x00,
-	0x66, 0x00,
-	0x67, 0x00,
-	0x68, 0x00,
-	0x69, 0x00,
-	0x6a, 0x00,
-	0x6b, 0x00,
-	0x6c, 0x00,
-	0x6d, 0x00,
-	0x6e, 0x00,
-	0x6f, 0x00,
-	0x70, 0x00,		/* video decoder reserved part */
-	0x71, 0x00,
-	0x72, 0x00,
-	0x73, 0x00,
-	0x74, 0x00,
-	0x75, 0x00,
-	0x76, 0x00,
-	0x77, 0x00,
-	0x78, 0x00,
-	0x79, 0x00,
-	0x7a, 0x00,
-	0x7b, 0x00,
-	0x7c, 0x00,
-	0x7d, 0x00,
-	0x7e, 0x00,
-	0x7f, 0x00,
-	0x80, 0x00,		/* X-port, I-port and scaler */
-	0x81, 0x00,
-	0x82, 0x00,
-	0x83, 0x00,
-	0x84, 0xc5,
-	0x85, 0x0d,		// hsync and vsync ?
-	0x86, 0x40,
-	0x87, 0x01,
-	0x88, 0x00,
-	0x89, 0x00,
-	0x8a, 0x00,
-	0x8b, 0x00,
-	0x8c, 0x00,
-	0x8d, 0x00,
-	0x8e, 0x00,
-	0x8f, 0x00,
-	0x90, 0x03,		/* Task A definition           */
-	0x91, 0x08,
-	0x92, 0x00,
-	0x93, 0x40,
-	0x94, 0x00,		// window settings
-	0x95, 0x00,
-	0x96, 0x00,
-	0x97, 0x00,
-	0x98, 0x00,
-	0x99, 0x00,
-	0x9a, 0x00,
-	0x9b, 0x00,
-	0x9c, 0x00,
-	0x9d, 0x00,
-	0x9e, 0x00,
-	0x9f, 0x00,
-	0xa0, 0x01,		/* horizontal integer prescaling ratio */
-	0xa1, 0x00,		/* horizontal prescaler accumulation
-				 * sequence length */
-	0xa2, 0x00,		/* UV FIR filter, Y FIR filter, prescaler
-				 * DC gain */
-	0xa3, 0x00,
-	0xa4, 0x80,		// luminance brightness
-	0xa5, 0x40,		// luminance gain
-	0xa6, 0x40,		// chrominance saturation
-	0xa7, 0x00,
-	0xa8, 0x00,		// horizontal luminance scaling increment
-	0xa9, 0x04,
-	0xaa, 0x00,		// horizontal luminance phase offset
-	0xab, 0x00,
-	0xac, 0x00,		// horizontal chrominance scaling increment
-	0xad, 0x02,
-	0xae, 0x00,		// horizontal chrominance phase offset
-	0xaf, 0x00,
-	0xb0, 0x00,		// vertical luminance scaling increment
-	0xb1, 0x04,
-	0xb2, 0x00,		// vertical chrominance scaling increment
-	0xb3, 0x04,
-	0xb4, 0x00,
-	0xb5, 0x00,
-	0xb6, 0x00,
-	0xb7, 0x00,
-	0xb8, 0x00,
-	0xb9, 0x00,
-	0xba, 0x00,
-	0xbb, 0x00,
-	0xbc, 0x00,
-	0xbd, 0x00,
-	0xbe, 0x00,
-	0xbf, 0x00,
-	0xc0, 0x02,		// Task B definition
-	0xc1, 0x08,
-	0xc2, 0x00,
-	0xc3, 0x40,
-	0xc4, 0x00,		// window settings
-	0xc5, 0x00,
-	0xc6, 0x00,
-	0xc7, 0x00,
-	0xc8, 0x00,
-	0xc9, 0x00,
-	0xca, 0x00,
-	0xcb, 0x00,
-	0xcc, 0x00,
-	0xcd, 0x00,
-	0xce, 0x00,
-	0xcf, 0x00,
-	0xd0, 0x01,		// horizontal integer prescaling ratio
-	0xd1, 0x00,		// horizontal prescaler accumulation sequence length
-	0xd2, 0x00,		// UV FIR filter, Y FIR filter, prescaler DC gain
-	0xd3, 0x00,
-	0xd4, 0x80,		// luminance brightness
-	0xd5, 0x40,		// luminance gain
-	0xd6, 0x40,		// chrominance saturation
-	0xd7, 0x00,
-	0xd8, 0x00,		// horizontal luminance scaling increment
-	0xd9, 0x04,
-	0xda, 0x00,		// horizontal luminance phase offset
-	0xdb, 0x00,
-	0xdc, 0x00,		// horizontal chrominance scaling increment
-	0xdd, 0x02,
-	0xde, 0x00,		// horizontal chrominance phase offset
-	0xdf, 0x00,
-	0xe0, 0x00,		// vertical luminance scaling increment
-	0xe1, 0x04,
-	0xe2, 0x00,		// vertical chrominance scaling increment
-	0xe3, 0x04,
-	0xe4, 0x00,
-	0xe5, 0x00,
-	0xe6, 0x00,
-	0xe7, 0x00,
-	0xe8, 0x00,
-	0xe9, 0x00,
-	0xea, 0x00,
-	0xeb, 0x00,
-	0xec, 0x00,
-	0xed, 0x00,
-	0xee, 0x00,
-	0xef, 0x00
-};
-
-static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	struct saa7114 *decoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-		//dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
-		//saa7114_write_block(client, init, sizeof(init));
-		break;
-
-	case DECODER_DUMP:
-	{
-		int i;
-
-		if (!debug)
-			break;
-		v4l_info(client, "decoder dump\n");
-
-		for (i = 0; i < 32; i += 16) {
-			int j;
-
-			v4l_info(client, "%03x", i);
-			for (j = 0; j < 16; ++j) {
-				printk(KERN_CONT " %02x",
-				       saa7114_read(client, i + j));
-			}
-			printk(KERN_CONT "\n");
-		}
-		break;
-	}
-
-	case DECODER_GET_CAPABILITIES:
-	{
-		struct video_decoder_capability *cap = arg;
-
-		v4l_dbg(1, debug, client, "get capabilities\n");
-
-		cap->flags = VIDEO_DECODER_PAL |
-			     VIDEO_DECODER_NTSC |
-			     VIDEO_DECODER_AUTO |
-			     VIDEO_DECODER_CCIR;
-		cap->inputs = 8;
-		cap->outputs = 1;
-		break;
-	}
-
-	case DECODER_GET_STATUS:
-	{
-		int *iarg = arg;
-		int status;
-		int res;
-
-		status = saa7114_read(client, 0x1f);
-
-		v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
-		res = 0;
-		if ((status & (1 << 6)) == 0) {
-			res |= DECODER_STATUS_GOOD;
-		}
-		switch (decoder->norm) {
-		case VIDEO_MODE_NTSC:
-			res |= DECODER_STATUS_NTSC;
-			break;
-		case VIDEO_MODE_PAL:
-			res |= DECODER_STATUS_PAL;
-			break;
-		case VIDEO_MODE_SECAM:
-			res |= DECODER_STATUS_SECAM;
-			break;
-		default:
-		case VIDEO_MODE_AUTO:
-			if ((status & (1 << 5)) != 0) {
-				res |= DECODER_STATUS_NTSC;
-			} else {
-				res |= DECODER_STATUS_PAL;
-			}
-			break;
-		}
-		if ((status & (1 << 0)) != 0) {
-			res |= DECODER_STATUS_COLOR;
-		}
-		*iarg = res;
-		break;
-	}
-
-	case DECODER_SET_NORM:
-	{
-		int *iarg = arg;
-
-		short int hoff = 0, voff = 0, w = 0, h = 0;
-
-		v4l_dbg(1, debug, client, "set norm\n");
-
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			v4l_dbg(1, debug, client, "NTSC\n");
-			decoder->reg[REG_ADDR(0x06)] =
-			    SAA_7114_NTSC_HSYNC_START;
-			decoder->reg[REG_ADDR(0x07)] =
-			    SAA_7114_NTSC_HSYNC_STOP;
-
-			decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8;	// PLL free when playback, PLL close when capture
-
-			decoder->reg[REG_ADDR(0x0e)] = 0x85;
-			decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
-			hoff = SAA_7114_NTSC_HOFFSET;
-			voff = SAA_7114_NTSC_VOFFSET;
-			w = SAA_7114_NTSC_WIDTH;
-			h = SAA_7114_NTSC_HEIGHT;
-
-			break;
-
-		case VIDEO_MODE_PAL:
-			v4l_dbg(1, debug, client, "PAL\n");
-			decoder->reg[REG_ADDR(0x06)] =
-			    SAA_7114_PAL_HSYNC_START;
-			decoder->reg[REG_ADDR(0x07)] =
-			    SAA_7114_PAL_HSYNC_STOP;
-
-			decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8;	// PLL free when playback, PLL close when capture
-
-			decoder->reg[REG_ADDR(0x0e)] = 0x81;
-			decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
-			hoff = SAA_7114_PAL_HOFFSET;
-			voff = SAA_7114_PAL_VOFFSET;
-			w = SAA_7114_PAL_WIDTH;
-			h = SAA_7114_PAL_HEIGHT;
-
-			break;
-
-		default:
-			v4l_dbg(1, debug, client, "Unknown video mode\n");
-			return -EINVAL;
-		}
-
-
-		decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff);	// hoffset low
-		decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f;	// hoffset high
-		decoder->reg[REG_ADDR(0x96)] = LOBYTE(w);	// width low
-		decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f;	// width high
-		decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff);	// voffset low
-		decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f;	// voffset high
-		decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2);	// height low
-		decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f;	// height high
-		decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w);	// out width low
-		decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f;	// out width high
-		decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h);	// out height low
-		decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f;	// out height high
-
-		decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff);	// hoffset low
-		decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f;	// hoffset high
-		decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w);	// width low
-		decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f;	// width high
-		decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff);	// voffset low
-		decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f;	// voffset high
-		decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2);	// height low
-		decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f;	// height high
-		decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w);	// out width low
-		decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f;	// out width high
-		decoder->reg[REG_ADDR(0xce)] = LOBYTE(h);	// out height low
-		decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f;	// out height high
-
-
-		saa7114_write(client, 0x80, 0x06);	// i-port and scaler back end clock selection, task A&B off
-		saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
-		saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
-
-		saa7114_write_block(client, decoder->reg + (0x06 << 1),
-				    3 << 1);
-		saa7114_write_block(client, decoder->reg + (0x0e << 1),
-				    2 << 1);
-		saa7114_write_block(client, decoder->reg + (0x5a << 1),
-				    2 << 1);
-
-		saa7114_write_block(client, decoder->reg + (0x94 << 1),
-				    (0x9f + 1 - 0x94) << 1);
-		saa7114_write_block(client, decoder->reg + (0xc4 << 1),
-				    (0xcf + 1 - 0xc4) << 1);
-
-		saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
-		saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
-		saa7114_write(client, 0x80, 0x36);	// i-port and scaler back end clock selection
-
-		decoder->norm = *iarg;
-		break;
-	}
-
-	case DECODER_SET_INPUT:
-	{
-		int *iarg = arg;
-
-		v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
-		if (*iarg < 0 || *iarg > 7) {
-			return -EINVAL;
-		}
-
-		if (decoder->input != *iarg) {
-			v4l_dbg(1, debug, client, "now setting %s input\n",
-				*iarg >= 6 ? "S-Video" : "Composite");
-			decoder->input = *iarg;
-
-			/* select mode */
-			decoder->reg[REG_ADDR(0x02)] =
-			    (decoder->
-			     reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
-							    input <
-							    6 ? 0x0 : 0x9);
-			saa7114_write(client, 0x02,
-				      decoder->reg[REG_ADDR(0x02)]);
-
-			/* bypass chrominance trap for modes 6..9 */
-			decoder->reg[REG_ADDR(0x09)] =
-			    (decoder->
-			     reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
-							    input <
-							    6 ? 0x0 :
-							    0x80);
-			saa7114_write(client, 0x09,
-				      decoder->reg[REG_ADDR(0x09)]);
-
-			decoder->reg[REG_ADDR(0x0e)] =
-			    decoder->input <
-			    6 ? decoder->
-			    reg[REG_ADDR(0x0e)] | 1 : decoder->
-			    reg[REG_ADDR(0x0e)] & ~1;
-			saa7114_write(client, 0x0e,
-				      decoder->reg[REG_ADDR(0x0e)]);
-		}
-		break;
-	}
-
-	case DECODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
-
-		v4l_dbg(1, debug, client, "set output\n");
-
-		/* not much choice of outputs */
-		if (*iarg != 0) {
-			return -EINVAL;
-		}
-		break;
-	}
-
-	case DECODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-		int enable = (*iarg != 0);
-
-		v4l_dbg(1, debug, client, "%s output\n",
-			enable ? "enable" : "disable");
-
-		decoder->playback = !enable;
-
-		if (decoder->enable != enable) {
-			decoder->enable = enable;
-
-			/* RJ: If output should be disabled (for
-			 * playing videos), we also need a open PLL.
-			 * The input is set to 0 (where no input
-			 * source is connected), although this
-			 * is not necessary.
-			 *
-			 * If output should be enabled, we have to
-			 * reverse the above.
-			 */
-
-			if (decoder->enable) {
-				decoder->reg[REG_ADDR(0x08)] = 0xb8;
-				decoder->reg[REG_ADDR(0x12)] = 0xc9;
-				decoder->reg[REG_ADDR(0x13)] = 0x80;
-				decoder->reg[REG_ADDR(0x87)] = 0x01;
-			} else {
-				decoder->reg[REG_ADDR(0x08)] = 0x7c;
-				decoder->reg[REG_ADDR(0x12)] = 0x00;
-				decoder->reg[REG_ADDR(0x13)] = 0x00;
-				decoder->reg[REG_ADDR(0x87)] = 0x00;
-			}
-
-			saa7114_write_block(client,
-					    decoder->reg + (0x12 << 1),
-					    2 << 1);
-			saa7114_write(client, 0x08,
-				      decoder->reg[REG_ADDR(0x08)]);
-			saa7114_write(client, 0x87,
-				      decoder->reg[REG_ADDR(0x87)]);
-			saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
-			saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
-			saa7114_write(client, 0x80, 0x36);
-
-		}
-		break;
-	}
-
-	case DECODER_SET_PICTURE:
-	{
-		struct video_picture *pic = arg;
-
-		v4l_dbg(1, debug, client,
-			"decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
-			pic->brightness, pic->contrast, pic->colour, pic->hue);
-
-		if (decoder->bright != pic->brightness) {
-			/* We want 0 to 255 we get 0-65535 */
-			decoder->bright = pic->brightness;
-			saa7114_write(client, 0x0a, decoder->bright >> 8);
-		}
-		if (decoder->contrast != pic->contrast) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->contrast = pic->contrast;
-			saa7114_write(client, 0x0b,
-				      decoder->contrast >> 9);
-		}
-		if (decoder->sat != pic->colour) {
-			/* We want 0 to 127 we get 0-65535 */
-			decoder->sat = pic->colour;
-			saa7114_write(client, 0x0c, decoder->sat >> 9);
-		}
-		if (decoder->hue != pic->hue) {
-			/* We want -128 to 127 we get 0-65535 */
-			decoder->hue = pic->hue;
-			saa7114_write(client, 0x0d,
-				      (decoder->hue - 32768) >> 8);
-		}
-		break;
-	}
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7114_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	int i, err[30];
-	short int hoff = SAA_7114_NTSC_HOFFSET;
-	short int voff = SAA_7114_NTSC_VOFFSET;
-	short int w = SAA_7114_NTSC_WIDTH;
-	short int h = SAA_7114_NTSC_HEIGHT;
-	struct saa7114 *decoder;
-
-	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	v4l_info(client, "chip found @ 0x%x (%s)\n",
-			client->addr << 1, client->adapter->name);
-
-	decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
-	if (decoder == NULL)
-		return -ENOMEM;
-	decoder->norm = VIDEO_MODE_NTSC;
-	decoder->input = -1;
-	decoder->enable = 1;
-	decoder->bright = 32768;
-	decoder->contrast = 32768;
-	decoder->hue = 32768;
-	decoder->sat = 32768;
-	decoder->playback = 0;	// initially capture mode useda
-	i2c_set_clientdata(client, decoder);
-
-	memcpy(decoder->reg, init, sizeof(init));
-
-	decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff);	// hoffset low
-	decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f;	// hoffset high
-	decoder->reg[REG_ADDR(0x96)] = LOBYTE(w);	// width low
-	decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f;	// width high
-	decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff);	// voffset low
-	decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f;	// voffset high
-	decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2);	// height low
-	decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f;	// height high
-	decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w);	// out width low
-	decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f;	// out width high
-	decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h);	// out height low
-	decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f;	// out height high
-
-	decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff);	// hoffset low
-	decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f;	// hoffset high
-	decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w);	// width low
-	decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f;	// width high
-	decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff);	// voffset low
-	decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f;	// voffset high
-	decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2);	// height low
-	decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f;	// height high
-	decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w);	// out width low
-	decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f;	// out width high
-	decoder->reg[REG_ADDR(0xce)] = LOBYTE(h);	// out height low
-	decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f;	// out height high
-
-	decoder->reg[REG_ADDR(0xb8)] =
-	    LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xb9)] =
-	    HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xba)] =
-	    LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xbb)] =
-	    HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
-	decoder->reg[REG_ADDR(0xbc)] =
-	    LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xbd)] =
-	    HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xbe)] =
-	    LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xbf)] =
-	    HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
-	decoder->reg[REG_ADDR(0xe8)] =
-	    LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xe9)] =
-	    HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xea)] =
-	    LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-	decoder->reg[REG_ADDR(0xeb)] =
-	    HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
-	decoder->reg[REG_ADDR(0xec)] =
-	    LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xed)] =
-	    HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xee)] =
-	    LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-	decoder->reg[REG_ADDR(0xef)] =
-	    HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
-
-	decoder->reg[REG_ADDR(0x13)] = 0x80;	// RTC0 on
-	decoder->reg[REG_ADDR(0x87)] = 0x01;	// I-Port
-	decoder->reg[REG_ADDR(0x12)] = 0xc9;	// RTS0
-
-	decoder->reg[REG_ADDR(0x02)] = 0xc0;	// set composite1 input, aveasy
-	decoder->reg[REG_ADDR(0x09)] = 0x00;	// chrominance trap
-	decoder->reg[REG_ADDR(0x0e)] |= 1;	// combfilter on
-
-
-	v4l_dbg(1, debug, client, "starting init\n");
-
-	err[0] =
-	    saa7114_write_block(client, decoder->reg + (0x20 << 1),
-				0x10 << 1);
-	err[1] =
-	    saa7114_write_block(client, decoder->reg + (0x30 << 1),
-				0x10 << 1);
-	err[2] =
-	    saa7114_write_block(client, decoder->reg + (0x63 << 1),
-				(0x7f + 1 - 0x63) << 1);
-	err[3] =
-	    saa7114_write_block(client, decoder->reg + (0x89 << 1),
-				6 << 1);
-	err[4] =
-	    saa7114_write_block(client, decoder->reg + (0xb8 << 1),
-				8 << 1);
-	err[5] =
-	    saa7114_write_block(client, decoder->reg + (0xe8 << 1),
-				8 << 1);
-
-
-	for (i = 0; i <= 5; i++) {
-		if (err[i] < 0) {
-			v4l_dbg(1, debug, client,
-				"init error %d at stage %d, leaving attach.\n",
-				i, err[i]);
-			kfree(decoder);
-			return -EIO;
-		}
-	}
-
-	for (i = 6; i < 8; i++) {
-		v4l_dbg(1, debug, client,
-			"reg[0x%02x] = 0x%02x (0x%02x)\n",
-			i, saa7114_read(client, i),
-			decoder->reg[REG_ADDR(i)]);
-	}
-
-	v4l_dbg(1, debug, client,
-		"performing decoder reset sequence\n");
-
-	err[6] = saa7114_write(client, 0x80, 0x06);	// i-port and scaler backend clock selection, task A&B off
-	err[7] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
-	err[8] = saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
-
-	for (i = 6; i <= 8; i++) {
-		if (err[i] < 0) {
-			v4l_dbg(1, debug, client,
-				"init error %d at stage %d, leaving attach.\n",
-				i, err[i]);
-			kfree(decoder);
-			return -EIO;
-		}
-	}
-
-	v4l_dbg(1, debug, client, "performing the rest of init\n");
-
-	err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
-	err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1);	// big seq
-	err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1);	// slicer
-	err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1);	// ?
-	err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1);	// ?
-	err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1);	// Task A
-	err[15] =
-	    saa7114_write_block(client, decoder->reg + (0x94 << 1),
-				12 << 1);
-	err[16] =
-	    saa7114_write_block(client, decoder->reg + (0xa0 << 1),
-				8 << 1);
-	err[17] =
-	    saa7114_write_block(client, decoder->reg + (0xa8 << 1),
-				8 << 1);
-	err[18] =
-	    saa7114_write_block(client, decoder->reg + (0xb0 << 1),
-				8 << 1);
-	err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1);	// Task B
-	err[15] =
-	    saa7114_write_block(client, decoder->reg + (0xc4 << 1),
-				12 << 1);
-	err[16] =
-	    saa7114_write_block(client, decoder->reg + (0xd0 << 1),
-				8 << 1);
-	err[17] =
-	    saa7114_write_block(client, decoder->reg + (0xd8 << 1),
-				8 << 1);
-	err[18] =
-	    saa7114_write_block(client, decoder->reg + (0xe0 << 1),
-				8 << 1);
-
-	for (i = 9; i <= 18; i++) {
-		if (err[i] < 0) {
-			v4l_dbg(1, debug, client,
-				"init error %d at stage %d, leaving attach.\n",
-				i, err[i]);
-			kfree(decoder);
-			return -EIO;
-		}
-	}
-
-
-	for (i = 6; i < 8; i++) {
-		v4l_dbg(1, debug, client,
-			"reg[0x%02x] = 0x%02x (0x%02x)\n",
-			i, saa7114_read(client, i),
-			decoder->reg[REG_ADDR(i)]);
-	}
-
-
-	for (i = 0x11; i <= 0x13; i++) {
-		v4l_dbg(1, debug, client,
-			"reg[0x%02x] = 0x%02x (0x%02x)\n",
-			i, saa7114_read(client, i),
-			decoder->reg[REG_ADDR(i)]);
-	}
-
-
-	v4l_dbg(1, debug, client, "setting video input\n");
-
-	err[19] =
-	    saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
-	err[20] =
-	    saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
-	err[21] =
-	    saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
-
-	for (i = 19; i <= 21; i++) {
-		if (err[i] < 0) {
-			v4l_dbg(1, debug, client,
-				"init error %d at stage %d, leaving attach.\n",
-				i, err[i]);
-			kfree(decoder);
-			return -EIO;
-		}
-	}
-
-	v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
-
-	err[22] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
-	err[23] = saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
-	err[24] = saa7114_write(client, 0x80, 0x36);	// i-port and scaler backend clock selection, task A&B off
-
-
-	for (i = 22; i <= 24; i++) {
-		if (err[i] < 0) {
-			v4l_dbg(1, debug, client,
-				"init error %d at stage %d, leaving attach.\n",
-				i, err[i]);
-			kfree(decoder);
-			return -EIO;
-		}
-	}
-
-	err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
-	err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
-	err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
-
-	v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
-		saa7114_read(client, 0x00) >> 4,
-		saa7114_read(client, 0x1f));
-	v4l_dbg(1, debug, client,
-		"power save control: 0x%02x, scaler status: 0x%02x\n",
-		saa7114_read(client, 0x88),
-		saa7114_read(client, 0x8f));
-
-
-	for (i = 0x94; i < 0x96; i++) {
-		v4l_dbg(1, debug, client,
-			"reg[0x%02x] = 0x%02x (0x%02x)\n",
-			i, saa7114_read(client, i),
-			decoder->reg[REG_ADDR(i)]);
-	}
-
-	//i = saa7114_write_block(client, init, sizeof(init));
-	return 0;
-}
-
-static int saa7114_remove(struct i2c_client *client)
-{
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7114_id[] = {
-	{ "saa7114_old", 0 },	/* "saa7114" maps to the saa7115 driver */
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, saa7114_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
-	.name = "saa7114",
-	.driverid = I2C_DRIVERID_SAA7114,
-	.command = saa7114_command,
-	.probe = saa7114_probe,
-	.remove = saa7114_remove,
-	.id_table = saa7114_id,
-};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7115.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7115.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7115.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7115.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <media/saa7115.h>
 #include <asm/div64.h>
 
@@ -62,12 +62,6 @@ module_param(debug, bool, 0644);
 
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-static unsigned short normal_i2c[] = {
-		0x4a >> 1, 0x48 >> 1,	/* SAA7111, SAA7111A and SAA7113 */
-		0x42 >> 1, 0x40 >> 1,	/* SAA7114, SAA7115 and SAA7118 */
-		I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
 
 struct saa711x_state {
 	struct v4l2_subdev sd;
@@ -778,7 +772,7 @@ static int saa711x_s_ctrl(struct v4l2_su
 		break;
 
 	case V4L2_CID_HUE:
-		if (ctrl->value < -127 || ctrl->value > 127) {
+		if (ctrl->value < -128 || ctrl->value > 127) {
 			v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
@@ -931,8 +925,8 @@ static void saa711x_set_v4lstd(struct v4
 	/* Prevent unnecessary standard changes. During a standard
 	   change the I-Port is temporarily disabled. Any devices
 	   reading from that port can get confused.
-	   Note that VIDIOC_S_STD is also used to switch from
-	   radio to TV mode, so if a VIDIOC_S_STD is broadcast to
+	   Note that s_std is also used to switch from
+	   radio to TV mode, so if a s_std is broadcast to
 	   all I2C devices then you do not want to have an unwanted
 	   side-effect here. */
 	if (std == state->std)
@@ -1206,10 +1200,12 @@ static int saa711x_queryctrl(struct v4l2
 {
 	switch (qc->id) {
 	case V4L2_CID_BRIGHTNESS:
+		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
 	case V4L2_CID_CONTRAST:
 	case V4L2_CID_SATURATION:
+		return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
 	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill_std(qc);
+		return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
 	default:
 		return -EINVAL;
 	}
@@ -1232,30 +1228,32 @@ static int saa711x_s_radio(struct v4l2_s
 	return 0;
 }
 
-static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa711x_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa711x_state *state = to_state(sd);
-	u32 input = route->input;
 	u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
 
-	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
+	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
+		input, output);
+
 	/* saa7111/3 does not have these inputs */
 	if ((state->ident == V4L2_IDENT_SAA7113 ||
 	     state->ident == V4L2_IDENT_SAA7111) &&
-	    (route->input == SAA7115_COMPOSITE4 ||
-	     route->input == SAA7115_COMPOSITE5)) {
+	    (input == SAA7115_COMPOSITE4 ||
+	     input == SAA7115_COMPOSITE5)) {
 		return -EINVAL;
 	}
-	if (route->input > SAA7115_SVIDEO3)
+	if (input > SAA7115_SVIDEO3)
 		return -EINVAL;
-	if (route->output > SAA7115_IPORT_ON)
+	if (output > SAA7115_IPORT_ON)
 		return -EINVAL;
-	if (state->input == route->input && state->output == route->output)
+	if (state->input == input && state->output == output)
 		return 0;
 	v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
-		(route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
-		(route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
-	state->input = route->input;
+		(input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
+		(output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
+	state->input = input;
 
 	/* saa7111 has slightly different input numbering */
 	if (state->ident == V4L2_IDENT_SAA7111) {
@@ -1264,10 +1262,10 @@ static int saa711x_s_routing(struct v4l2
 		/* saa7111 specific */
 		saa711x_write(sd, R_10_CHROMA_CNTL_2,
 				(saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
-				((route->output & 0xc0) ^ 0x40));
+				((output & 0xc0) ^ 0x40));
 		saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
 				(saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
-				((route->output & 2) ? 0x0a : 0));
+				((output & 2) ? 0x0a : 0));
 	}
 
 	/* select mode */
@@ -1280,7 +1278,7 @@ static int saa711x_s_routing(struct v4l2
 			(saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
 			(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
 
-	state->output = route->output;
+	state->output = output;
 	if (state->ident == V4L2_IDENT_SAA7114 ||
 			state->ident == V4L2_IDENT_SAA7115) {
 		saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
@@ -1308,25 +1306,25 @@ static int saa711x_s_stream(struct v4l2_
 	v4l2_dbg(1, debug, sd, "%s output\n",
 			enable ? "enable" : "disable");
 
-	if (state->enable != enable) {
-		state->enable = enable;
-		saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
-				state->enable);
-	}
+	if (state->enable == enable)
+		return 0;
+	state->enable = enable;
+	if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
+		return 0;
+	saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
 	return 0;
 }
 
-static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq)
+static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
 {
 	struct saa711x_state *state = to_state(sd);
 
-	if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
-			freq->freq != SAA7115_FREQ_24_576_MHZ)
+	if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
 		return -EINVAL;
-	state->crystal_freq = freq->freq;
-	state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
-	state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
-	state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
+	state->crystal_freq = freq;
+	state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
+	state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
+	state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
 	saa711x_s_clock_freq(sd, state->audclk_freq);
 	return 0;
 }
@@ -1370,6 +1368,47 @@ static int saa711x_g_vbi_data(struct v4l
 	}
 }
 
+static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	struct saa711x_state *state = to_state(sd);
+	int reg1e;
+
+	*std = V4L2_STD_ALL;
+	if (state->ident != V4L2_IDENT_SAA7115)
+		return 0;
+	reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+
+	switch (reg1e & 0x03) {
+	case 1:
+		*std = V4L2_STD_NTSC;
+		break;
+	case 2:
+		*std = V4L2_STD_PAL;
+		break;
+	case 3:
+		*std = V4L2_STD_SECAM;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct saa711x_state *state = to_state(sd);
+	int reg1e = 0x80;
+	int reg1f;
+
+	*status = V4L2_IN_ST_NO_SIGNAL;
+	if (state->ident == V4L2_IDENT_SAA7115)
+		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
+	if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
+		*status = 0;
+	return 0;
+}
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
@@ -1454,11 +1493,6 @@ static int saa711x_log_status(struct v4l
 	return 0;
 }
 
-static int saa711x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
@@ -1467,6 +1501,7 @@ static const struct v4l2_subdev_core_ops
 	.g_ctrl = saa711x_g_ctrl,
 	.s_ctrl = saa711x_s_ctrl,
 	.queryctrl = saa711x_queryctrl,
+	.s_std = saa711x_s_std,
 	.reset = saa711x_reset,
 	.s_gpio = saa711x_s_gpio,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1476,7 +1511,6 @@ static const struct v4l2_subdev_core_ops
 };
 
 static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
-	.s_std = saa711x_s_std,
 	.s_radio = saa711x_s_radio,
 	.g_tuner = saa711x_g_tuner,
 };
@@ -1493,6 +1527,8 @@ static const struct v4l2_subdev_video_op
 	.g_vbi_data = saa711x_g_vbi_data,
 	.decode_vbi_line = saa711x_decode_vbi_line,
 	.s_stream = saa711x_s_stream,
+	.querystd = saa711x_querystd,
+	.g_input_status = saa711x_g_input_status,
 };
 
 static const struct v4l2_subdev_ops saa711x_ops = {
@@ -1630,10 +1666,7 @@ MODULE_DEVICE_TABLE(i2c, saa7115_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7115",
-	.driverid = I2C_DRIVERID_SAA711X,
-	.command = saa711x_command,
 	.probe = saa711x_probe,
 	.remove = saa711x_remove,
-	.legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
 	.id_table = saa7115_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7127.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7127.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7127.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7127.c	2009-06-09 23:05:27.000000000 -0400
@@ -570,15 +570,16 @@ static int saa7127_s_std_output(struct v
 	return saa7127_set_std(sd, std);
 }
 
-static int saa7127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa7127_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct saa7127_state *state = to_state(sd);
 	int rc = 0;
 
-	if (state->input_type != route->input)
-		rc = saa7127_set_input_type(sd, route->input);
-	if (rc == 0 && state->output_type != route->output)
-		rc = saa7127_set_output_type(sd, route->output);
+	if (state->input_type != input)
+		rc = saa7127_set_input_type(sd, input);
+	if (rc == 0 && state->output_type != output)
+		rc = saa7127_set_output_type(sd, output);
 	return rc;
 }
 
@@ -810,7 +811,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7127",
-	.driverid = I2C_DRIVERID_SAA7127,
 	.probe = saa7127_probe,
 	.remove = saa7127_remove,
 	.id_table = saa7127_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@ config VIDEO_SAA7134
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select CRC32
+	select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
 	---help---
 	  This is a video4linux driver for Philips SAA713x based
 	  TV cards.
@@ -35,8 +36,16 @@ config VIDEO_SAA7134_DVB
 	select DVB_TDA10086 if !DVB_FE_CUSTOMISE
 	select DVB_TDA826X if !DVB_FE_CUSTOMISE
 	select DVB_ISL6421 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+	select DVB_ISL6405 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+	select DVB_ZL10036 if !DVB_FE_CUSTOMISE
+	select DVB_MT312 if !DVB_FE_CUSTOMISE
+	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+	select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This adds support for DVB cards based on the
 	  Philips saa7134 chip.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa6752hs.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa6752hs.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa6752hs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa6752hs.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,9 +33,10 @@
 #include <linux/i2c.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 
@@ -44,10 +45,6 @@
 #define MPEG_TOTAL_TARGET_BITRATE_MAX  27000
 #define MPEG_PID_MAX ((1 << 14) - 1)
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-
-I2C_CLIENT_INSMOD;
 
 MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
 MODULE_AUTHOR("Andrew de Quincey");
@@ -95,6 +92,7 @@ static const struct v4l2_format v4l2_for
 };
 
 struct saa6752hs_state {
+	struct v4l2_subdev            sd;
 	int 			      chip;
 	u32 			      revision;
 	int 			      has_ac3;
@@ -115,6 +113,11 @@ enum saa6752hs_command {
 	SAA6752HS_COMMAND_MAX
 };
 
+static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa6752hs_state, sd);
+}
+
 /* ---------------------------------------------------------------------- */
 
 static u8 PAT[] = {
@@ -360,185 +363,191 @@ static int saa6752hs_set_bitrate(struct
 	return 0;
 }
 
-static void saa6752hs_set_subsampling(struct i2c_client *client,
-				      struct v4l2_format *f)
-{
-	struct saa6752hs_state *h = i2c_get_clientdata(client);
-	int dist_352, dist_480, dist_720;
-
-	/*
-	  FIXME: translate and round width/height into EMPRESS
-	  subsample type:
-
-	  type   |   PAL   |  NTSC
-	  ---------------------------
-	  SIF    | 352x288 | 352x240
-	  1/2 D1 | 352x576 | 352x480
-	  2/3 D1 | 480x576 | 480x480
-	  D1     | 720x576 | 720x480
-	*/
 
-	dist_352 = abs(f->fmt.pix.width - 352);
-	dist_480 = abs(f->fmt.pix.width - 480);
-	dist_720 = abs(f->fmt.pix.width - 720);
-	if (dist_720 < dist_480) {
-		f->fmt.pix.width = 720;
-		f->fmt.pix.height = 576;
-		h->video_format = SAA6752HS_VF_D1;
-	}
-	else if (dist_480 < dist_352) {
-		f->fmt.pix.width = 480;
-		f->fmt.pix.height = 576;
-		h->video_format = SAA6752HS_VF_2_3_D1;
-	}
-	else {
-		f->fmt.pix.width = 352;
-		if (abs(f->fmt.pix.height - 576) <
-		    abs(f->fmt.pix.height - 288)) {
-			f->fmt.pix.height = 576;
-			h->video_format = SAA6752HS_VF_1_2_D1;
-		}
-		else {
-			f->fmt.pix.height = 288;
-			h->video_format = SAA6752HS_VF_SIF;
-		}
+static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
+		struct v4l2_ext_control *ctrl)
+{
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_PMT:
+		ctrl->value = params->ts_pid_pmt;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+		ctrl->value = params->ts_pid_audio;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+		ctrl->value = params->ts_pid_video;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_PCR:
+		ctrl->value = params->ts_pid_pcr;
+		break;
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		ctrl->value = params->au_encoding;
+		break;
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		ctrl->value = params->au_l2_bitrate;
+		break;
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		if (!has_ac3)
+			return -EINVAL;
+		ctrl->value = params->au_ac3_bitrate;
+		break;
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		ctrl->value = params->vi_aspect;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		ctrl->value = params->vi_bitrate * 1000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		ctrl->value = params->vi_bitrate_peak * 1000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		ctrl->value = params->vi_bitrate_mode;
+		break;
+	default:
+		return -EINVAL;
 	}
+	return 0;
 }
 
-
 static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
-		struct v4l2_ext_control *ctrl, unsigned int cmd)
+		struct v4l2_ext_control *ctrl, int set)
 {
 	int old = 0, new;
-	int set = (cmd == VIDIOC_S_EXT_CTRLS);
 
 	new = ctrl->value;
 	switch (ctrl->id) {
-		case V4L2_CID_MPEG_STREAM_TYPE:
-			old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
-			if (set && new != old)
-				return -ERANGE;
-			new = old;
-			break;
-		case V4L2_CID_MPEG_STREAM_PID_PMT:
-			old = params->ts_pid_pmt;
-			if (set && new > MPEG_PID_MAX)
-				return -ERANGE;
-			if (new > MPEG_PID_MAX)
-				new = MPEG_PID_MAX;
-			params->ts_pid_pmt = new;
-			break;
-		case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-			old = params->ts_pid_audio;
-			if (set && new > MPEG_PID_MAX)
-				return -ERANGE;
-			if (new > MPEG_PID_MAX)
-				new = MPEG_PID_MAX;
-			params->ts_pid_audio = new;
-			break;
-		case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-			old = params->ts_pid_video;
-			if (set && new > MPEG_PID_MAX)
-				return -ERANGE;
-			if (new > MPEG_PID_MAX)
-				new = MPEG_PID_MAX;
-			params->ts_pid_video = new;
-			break;
-		case V4L2_CID_MPEG_STREAM_PID_PCR:
-			old = params->ts_pid_pcr;
-			if (set && new > MPEG_PID_MAX)
-				return -ERANGE;
-			if (new > MPEG_PID_MAX)
-				new = MPEG_PID_MAX;
-			params->ts_pid_pcr = new;
-			break;
-		case V4L2_CID_MPEG_AUDIO_ENCODING:
-			old = params->au_encoding;
-			if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
-			    (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
-				return -ERANGE;
-			new = old;
-			break;
-		case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-			old = params->au_l2_bitrate;
-			if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
-				   new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
-				return -ERANGE;
-			if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
-				new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
-			else
-				new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
-			params->au_l2_bitrate = new;
-			break;
-		case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-			if (!has_ac3)
-				return -EINVAL;
-			old = params->au_ac3_bitrate;
-			if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
-				   new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
-				return -ERANGE;
-			if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
-				new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
-			else
-				new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
-			params->au_ac3_bitrate = new;
-			break;
-		case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-			old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
-			if (set && new != old)
-				return -ERANGE;
-			new = old;
-			break;
-		case V4L2_CID_MPEG_VIDEO_ENCODING:
-			old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-			if (set && new != old)
-				return -ERANGE;
-			new = old;
-			break;
-		case V4L2_CID_MPEG_VIDEO_ASPECT:
-			old = params->vi_aspect;
-			if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
-				   new != V4L2_MPEG_VIDEO_ASPECT_4x3)
-				return -ERANGE;
-			if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
-				new = V4L2_MPEG_VIDEO_ASPECT_4x3;
-			params->vi_aspect = new;
-			break;
-		case V4L2_CID_MPEG_VIDEO_BITRATE:
-			old = params->vi_bitrate * 1000;
-			new = 1000 * (new / 1000);
-			if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-				return -ERANGE;
-			if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-				new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-			params->vi_bitrate = new / 1000;
-			break;
-		case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-			old = params->vi_bitrate_peak * 1000;
-			new = 1000 * (new / 1000);
-			if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-				return -ERANGE;
-			if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-				new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-			params->vi_bitrate_peak = new / 1000;
-			break;
-		case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-			old = params->vi_bitrate_mode;
-			params->vi_bitrate_mode = new;
-			break;
-		default:
+	case V4L2_CID_MPEG_STREAM_TYPE:
+		old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+		if (set && new != old)
+			return -ERANGE;
+		new = old;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_PMT:
+		old = params->ts_pid_pmt;
+		if (set && new > MPEG_PID_MAX)
+			return -ERANGE;
+		if (new > MPEG_PID_MAX)
+			new = MPEG_PID_MAX;
+		params->ts_pid_pmt = new;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+		old = params->ts_pid_audio;
+		if (set && new > MPEG_PID_MAX)
+			return -ERANGE;
+		if (new > MPEG_PID_MAX)
+			new = MPEG_PID_MAX;
+		params->ts_pid_audio = new;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+		old = params->ts_pid_video;
+		if (set && new > MPEG_PID_MAX)
+			return -ERANGE;
+		if (new > MPEG_PID_MAX)
+			new = MPEG_PID_MAX;
+		params->ts_pid_video = new;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_PCR:
+		old = params->ts_pid_pcr;
+		if (set && new > MPEG_PID_MAX)
+			return -ERANGE;
+		if (new > MPEG_PID_MAX)
+			new = MPEG_PID_MAX;
+		params->ts_pid_pcr = new;
+		break;
+	case V4L2_CID_MPEG_AUDIO_ENCODING:
+		old = params->au_encoding;
+		if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+		    (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
+			return -ERANGE;
+		new = old;
+		break;
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		old = params->au_l2_bitrate;
+		if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
+			   new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
+			return -ERANGE;
+		if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
+			new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
+		else
+			new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
+		params->au_l2_bitrate = new;
+		break;
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		if (!has_ac3)
 			return -EINVAL;
+		old = params->au_ac3_bitrate;
+		if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
+			   new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
+			return -ERANGE;
+		if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
+			new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
+		else
+			new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
+		params->au_ac3_bitrate = new;
+		break;
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+		if (set && new != old)
+			return -ERANGE;
+		new = old;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+		if (set && new != old)
+			return -ERANGE;
+		new = old;
+		break;
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		old = params->vi_aspect;
+		if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
+			   new != V4L2_MPEG_VIDEO_ASPECT_4x3)
+			return -ERANGE;
+		if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
+			new = V4L2_MPEG_VIDEO_ASPECT_4x3;
+		params->vi_aspect = new;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		old = params->vi_bitrate * 1000;
+		new = 1000 * (new / 1000);
+		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+			return -ERANGE;
+		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+		params->vi_bitrate = new / 1000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		old = params->vi_bitrate_peak * 1000;
+		new = 1000 * (new / 1000);
+		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+			return -ERANGE;
+		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+		params->vi_bitrate_peak = new / 1000;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		old = params->vi_bitrate_mode;
+		params->vi_bitrate_mode = new;
+		break;
+	default:
+		return -EINVAL;
 	}
-	if (cmd == VIDIOC_G_EXT_CTRLS)
-		ctrl->value = old;
-	else
-		ctrl->value = new;
+	ctrl->value = new;
 	return 0;
 }
 
-static int saa6752hs_qctrl(struct saa6752hs_state *h,
-		struct v4l2_queryctrl *qctrl)
+
+static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
 {
+	struct saa6752hs_state *h = to_state(sd);
 	struct saa6752hs_mpeg_params *params = &h->params;
 	int err;
 
@@ -583,7 +592,7 @@ static int saa6752hs_qctrl(struct saa675
 				V4L2_MPEG_VIDEO_ASPECT_4x3);
 
 	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		err = v4l2_ctrl_query_fill_std(qctrl);
+		err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
 		if (err == 0 &&
 		    params->vi_bitrate_mode ==
 				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
@@ -597,12 +606,20 @@ static int saa6752hs_qctrl(struct saa675
 				V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
 
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		return v4l2_ctrl_query_fill(qctrl,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
 	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
 	case V4L2_CID_MPEG_STREAM_PID_PMT:
+		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
 	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
 	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
 	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		return v4l2_ctrl_query_fill_std(qctrl);
+		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
 
 	default:
 		break;
@@ -610,8 +627,7 @@ static int saa6752hs_qctrl(struct saa675
 	return -EINVAL;
 }
 
-static int saa6752hs_qmenu(struct saa6752hs_state *h,
-		struct v4l2_querymenu *qmenu)
+static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
 {
 	static const u32 mpeg_audio_encoding[] = {
 		V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -632,11 +648,12 @@ static int saa6752hs_qmenu(struct saa675
 		V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
 		V4L2_CTRL_MENU_IDS_END
 	};
+	struct saa6752hs_state *h = to_state(sd);
 	struct v4l2_queryctrl qctrl;
 	int err;
 
 	qctrl.id = qmenu->id;
-	err = saa6752hs_qctrl(h, &qctrl);
+	err = saa6752hs_queryctrl(sd, &qctrl);
 	if (err)
 		return err;
 	switch (qmenu->id) {
@@ -656,17 +673,16 @@ static int saa6752hs_qmenu(struct saa675
 	return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
 }
 
-static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
+static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
 {
 	unsigned char buf[9], buf2[4];
-	struct saa6752hs_state *h;
+	struct saa6752hs_state *h = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	unsigned size;
 	u32 crc;
 	unsigned char localPAT[256];
 	unsigned char localPMT[256];
 
-	h = i2c_get_clientdata(client);
-
 	/* Set video format - must be done first as it resets other settings */
 	set_reg8(client, 0x41, h->video_format);
 
@@ -762,7 +778,7 @@ static int saa6752hs_init(struct i2c_cli
 	buf[3] = 0x82;
 	buf[4] = 0xB0;
 	buf[5] = buf2[0];
-	switch(h->params.vi_aspect) {
+	switch (h->params.vi_aspect) {
 	case V4L2_MPEG_VIDEO_ASPECT_16x9:
 		buf[6] = buf2[1] | 0x40;
 		break;
@@ -770,7 +786,6 @@ static int saa6752hs_init(struct i2c_cli
 	default:
 		buf[6] = buf2[1] & 0xBF;
 		break;
-		break;
 	}
 	buf[7] = buf2[2];
 	buf[8] = buf2[3];
@@ -779,81 +794,158 @@ static int saa6752hs_init(struct i2c_cli
 	return 0;
 }
 
-static int
-saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
 {
-	struct saa6752hs_state *h = i2c_get_clientdata(client);
-	struct v4l2_ext_controls *ctrls = arg;
+	struct saa6752hs_state *h = to_state(sd);
 	struct saa6752hs_mpeg_params params;
-	int err = 0;
 	int i;
 
-	switch (cmd) {
-	case VIDIOC_INT_INIT:
-		/* apply settings and start encoder */
-		saa6752hs_init(client, *(u32 *)arg);
-		break;
-	case VIDIOC_S_EXT_CTRLS:
-		if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-			return -EINVAL;
-		/* fall through */
-	case VIDIOC_TRY_EXT_CTRLS:
-	case VIDIOC_G_EXT_CTRLS:
-		if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-			return -EINVAL;
-		params = h->params;
-		for (i = 0; i < ctrls->count; i++) {
-			err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
-			if (err) {
-				ctrls->error_idx = i;
-				return err;
-			}
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+		return -EINVAL;
+
+	params = h->params;
+	for (i = 0; i < ctrls->count; i++) {
+		int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
+
+		if (err) {
+			ctrls->error_idx = i;
+			return err;
 		}
+	}
+	if (set)
 		h->params = params;
-		break;
-	case VIDIOC_QUERYCTRL:
-		return saa6752hs_qctrl(h, arg);
-	case VIDIOC_QUERYMENU:
-		return saa6752hs_qmenu(h, arg);
-	case VIDIOC_G_FMT:
-	{
-	   struct v4l2_format *f = arg;
+	return 0;
+}
 
-	   if (h->video_format == SAA6752HS_VF_UNKNOWN)
-		   h->video_format = SAA6752HS_VF_D1;
-	   f->fmt.pix.width =
-		   v4l2_format_table[h->video_format].fmt.pix.width;
-	   f->fmt.pix.height =
-		   v4l2_format_table[h->video_format].fmt.pix.height;
-	   break ;
-	}
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *f = arg;
+static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+	return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
+}
 
-		saa6752hs_set_subsampling(client, f);
-		break;
+static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+	return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
+}
+
+static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+	struct saa6752hs_state *h = to_state(sd);
+	int i;
+
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+		return -EINVAL;
+
+	for (i = 0; i < ctrls->count; i++) {
+		int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
+
+		if (err) {
+			ctrls->error_idx = i;
+			return err;
+		}
 	}
-	case VIDIOC_S_STD:
-		h->standard = *((v4l2_std_id *) arg);
-		break;
+	return 0;
+}
 
-	case VIDIOC_DBG_G_CHIP_IDENT:
-		return v4l2_chip_ident_i2c_client(client,
-				arg, h->chip, h->revision);
+static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct saa6752hs_state *h = to_state(sd);
 
-	default:
-		/* nothing */
-		break;
+	if (h->video_format == SAA6752HS_VF_UNKNOWN)
+		h->video_format = SAA6752HS_VF_D1;
+	f->fmt.pix.width =
+		v4l2_format_table[h->video_format].fmt.pix.width;
+	f->fmt.pix.height =
+		v4l2_format_table[h->video_format].fmt.pix.height;
+	return 0;
+}
+
+static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct saa6752hs_state *h = to_state(sd);
+	int dist_352, dist_480, dist_720;
+
+	/*
+	  FIXME: translate and round width/height into EMPRESS
+	  subsample type:
+
+	  type   |   PAL   |  NTSC
+	  ---------------------------
+	  SIF    | 352x288 | 352x240
+	  1/2 D1 | 352x576 | 352x480
+	  2/3 D1 | 480x576 | 480x480
+	  D1     | 720x576 | 720x480
+	*/
+
+	dist_352 = abs(f->fmt.pix.width - 352);
+	dist_480 = abs(f->fmt.pix.width - 480);
+	dist_720 = abs(f->fmt.pix.width - 720);
+	if (dist_720 < dist_480) {
+		f->fmt.pix.width = 720;
+		f->fmt.pix.height = 576;
+		h->video_format = SAA6752HS_VF_D1;
+	} else if (dist_480 < dist_352) {
+		f->fmt.pix.width = 480;
+		f->fmt.pix.height = 576;
+		h->video_format = SAA6752HS_VF_2_3_D1;
+	} else {
+		f->fmt.pix.width = 352;
+		if (abs(f->fmt.pix.height - 576) <
+		    abs(f->fmt.pix.height - 288)) {
+			f->fmt.pix.height = 576;
+			h->video_format = SAA6752HS_VF_1_2_D1;
+		} else {
+			f->fmt.pix.height = 288;
+			h->video_format = SAA6752HS_VF_SIF;
+		}
 	}
+	return 0;
+}
 
-	return err;
+static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct saa6752hs_state *h = to_state(sd);
+
+	h->standard = std;
+	return 0;
+}
+
+static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa6752hs_state *h = to_state(sd);
+
+	return v4l2_chip_ident_i2c_client(client,
+			chip, h->chip, h->revision);
 }
 
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
+	.g_chip_ident = saa6752hs_g_chip_ident,
+	.init = saa6752hs_init,
+	.queryctrl = saa6752hs_queryctrl,
+	.querymenu = saa6752hs_querymenu,
+	.g_ext_ctrls = saa6752hs_g_ext_ctrls,
+	.s_ext_ctrls = saa6752hs_s_ext_ctrls,
+	.try_ext_ctrls = saa6752hs_try_ext_ctrls,
+	.s_std = saa6752hs_s_std,
+};
+
+static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
+	.s_fmt = saa6752hs_s_fmt,
+	.g_fmt = saa6752hs_g_fmt,
+};
+
+static const struct v4l2_subdev_ops saa6752hs_ops = {
+	.core = &saa6752hs_core_ops,
+	.video = &saa6752hs_video_ops,
+};
+
 static int saa6752hs_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+		const struct i2c_device_id *id)
 {
 	struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
+	struct v4l2_subdev *sd;
 	u8 addr = 0x13;
 	u8 data[12];
 
@@ -861,6 +953,8 @@ static int saa6752hs_probe(struct i2c_cl
 			client->addr << 1, client->adapter->name);
 	if (h == NULL)
 		return -ENOMEM;
+	sd = &h->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
 
 	i2c_master_send(client, &addr, 1);
 	i2c_master_recv(client, data, sizeof(data));
@@ -874,14 +968,15 @@ static int saa6752hs_probe(struct i2c_cl
 	}
 	h->params = param_defaults;
 	h->standard = 0; /* Assume 625 input lines */
-
-	i2c_set_clientdata(client, h);
 	return 0;
 }
 
 static int saa6752hs_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
 	return 0;
 }
 
@@ -893,8 +988,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa6752hs",
-	.driverid = I2C_DRIVERID_SAA6752HS,
-	.command = saa6752hs_command,
 	.probe = saa6752hs_probe,
 	.remove = saa6752hs_remove,
 	.id_table = saa6752hs_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-alsa.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-alsa.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-alsa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-alsa.c	2009-06-09 23:05:27.000000000 -0400
@@ -990,10 +990,10 @@ static int alsa_card_saa7134_create(stru
 	if (!enable[devnum])
 		return -ENODEV;
 
-	card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
-
-	if (card == NULL)
-		return -ENOMEM;
+	err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
+			      sizeof(snd_card_saa7134_t), &card);
+	if (err < 0)
+		return err;
 
 	strcpy(card->driver, "SAA7134");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-cards.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-cards.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 18:00:30.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-cards.c	2013-05-03 16:44:18.000000000 -0400
@@ -31,6 +31,7 @@
 #include <media/v4l2-common.h>
 #include <media/tveeprom.h>
 #include "tea5767.h"
+#include "tda18271.h"
 
 /* commly used strings */
 static char name_mute[]    = "mute";
@@ -272,6 +273,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.empress_addr 	= 0x20,
 
 		.inputs         = {{
 			.name = name_comp1,
@@ -408,6 +410,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.tda9887_conf	= TDA9887_PRESENT,
 		.gpiomask	= 0x820000,
 		.inputs		= {{
@@ -818,6 +821,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 4,
@@ -977,6 +981,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 1,
@@ -1699,6 +1704,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -2364,6 +2370,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.empress_addr 	= 0x21,
 		.inputs		= {{
 			.name   = "Composite 0",
 			.vmux   = 0,
@@ -3291,6 +3298,68 @@ struct saa7134_board saa7134_boards[] =
 			.gpio = 0x0200100,
 		},
 	},
+	[SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
+		.name           = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tuner_config   = 3,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.ts_type	= SAA7134_MPEG_TS_SERIAL,
+		.gpiomask       = 0x0800100, /* GPIO 21 is an INPUT */
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x0000100,
+		}, {
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+			.gpio = 0x0800100, /* GPIO 23 HI for FM */
+		},
+	},
+	[SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
+		.name           = "Hauppauge WinTV-HVR1110r3",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tuner_config   = 3,
+		.gpiomask       = 0x0800100, /* GPIO 21 is an INPUT */
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x0000100,
+		}, {
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+			.gpio = 0x0800100, /* GPIO 23 HI for FM */
+		},
+	},
 	[SAA7134_BOARD_CINERGY_HT_PCMCIA] = {
 		.name           = "Terratec Cinergy HT PCMCIA",
 		.audio_clock    = 0x00187de7,
@@ -4070,6 +4139,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.name = name_tv,
@@ -4106,6 +4176,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.name = name_tv,
@@ -4143,6 +4214,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.empress_addr 	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.name = name_tv,
@@ -4323,13 +4395,13 @@ struct saa7134_board saa7134_boards[] =
 			 .amux = TV,
 			 .tv   = 1,
 		 }, {
-			 .name = name_comp,
-			 .vmux = 0,
+			 .name = name_comp1,
+			 .vmux = 3,
 			 .amux = LINE1,
 		 }, {
 			 .name = name_svideo,
 			 .vmux = 8,
-			 .amux = LINE1,
+			 .amux = LINE2,
 		 } },
 		 .radio = {
 			 .name = name_radio,
@@ -4421,8 +4493,7 @@ struct saa7134_board saa7134_boards[] =
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		/* no DVB support for now */
-		/* .mpeg           = SAA7134_MPEG_DVB, */
+		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs         = { {
 			.name = name_comp,
 			.vmux = 1,
@@ -4437,13 +4508,17 @@ struct saa7134_board saa7134_boards[] =
 		/* Matthias Schwarzott <zzam@gentoo.org> */
 		.name           = "Avermedia DVB-S Hybrid+FM A700",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_ABSENT, /* TUNER_XC2028 */
+		.tuner_type     = TUNER_XC2028,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		/* no DVB support for now */
-		/* .mpeg           = SAA7134_MPEG_DVB, */
+		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs         = { {
+			.name   = name_tv,
+			.vmux   = 4,
+			.amux   = TV,
+			.tv     = 1,
+		}, {
 			.name = name_comp,
 			.vmux = 1,
 			.amux = LINE1,
@@ -4452,6 +4527,10 @@ struct saa7134_board saa7134_boards[] =
 			.vmux = 6,
 			.amux = LINE1,
 		} },
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+		},
 	},
 	[SAA7134_BOARD_BEHOLD_H6] = {
 		/* Igor Kuznetsov <igk@igk.ru> */
@@ -4611,7 +4690,7 @@ struct saa7134_board saa7134_boards[] =
 		.tuner_type     = TUNER_YMEC_TVF_5533MF,
 		.radio_type     = TUNER_TEA5767,
 		.tuner_addr     = ADDR_UNSET,
-		.radio_addr     = ADDR_UNSET,
+		.radio_addr     = 0x60,
 		.gpiomask       = 0x80000700,
 		.inputs = { {
 			.name   = name_tv,
@@ -5405,6 +5484,36 @@ struct pci_device_id saa7134_pci_tbl[] =
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x0070,
+		.subdevice    = 0x6706,
+		.driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x0070,
+		.subdevice    = 0x6707,
+		.driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x0070,
+		.subdevice    = 0x6708,
+		.driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x0070,
+		.subdevice    = 0x6709,
+		.driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x0070,
+		.subdevice    = 0x670a,
+		.driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x153b,
 		.subdevice    = 0x1172,
 		.driver_data  = SAA7134_BOARD_CINERGY_HT_PCMCIA,
@@ -5814,6 +5923,11 @@ static int saa7134_xc2028_callback(struc
 			msleep(10);
 			saa7134_set_gpio(dev, 21, 1);
 		break;
+		case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+			saa7134_set_gpio(dev, 18, 0);
+			msleep(10);
+			saa7134_set_gpio(dev, 18, 1);
+		break;
 		}
 	return 0;
 	}
@@ -5821,8 +5935,8 @@ static int saa7134_xc2028_callback(struc
 }
 
 
-static int saa7134_tda8290_callback(struct saa7134_dev *dev,
-				    int command, int arg)
+static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
+					 int command, int arg)
 {
 	u8 sync_control;
 
@@ -5848,6 +5962,65 @@ static int saa7134_tda8290_callback(stru
 	return 0;
 }
 
+static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
+						      enum tda18271_mode mode)
+{
+	/* toggle AGC switch through GPIO 26 */
+	switch (mode) {
+	case TDA18271_ANALOG:
+		saa7134_set_gpio(dev, 26, 0);
+		break;
+	case TDA18271_DIGITAL:
+		saa7134_set_gpio(dev, 26, 1);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
+					  int command, int arg)
+{
+	int ret = 0;
+
+	switch (command) {
+	case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
+		switch (dev->board) {
+		case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+		case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+			ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int saa7134_tda8290_callback(struct saa7134_dev *dev,
+				    int command, int arg)
+{
+	int ret;
+
+	switch (dev->board) {
+	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+	case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+		/* tda8290 + tda18271 */
+		ret = saa7134_tda8290_18271_callback(dev, command, arg);
+		break;
+	default:
+		/* tda8290 + tda827x */
+		ret = saa7134_tda8290_827x_callback(dev, command, arg);
+		break;
+	}
+	return ret;
+}
+
 int saa7134_tuner_callback(void *priv, int component, int command, int arg)
 {
 	struct saa7134_dev *dev = priv;
@@ -5878,11 +6051,16 @@ static void hauppauge_eeprom(struct saa7
 	switch (tv.model) {
 	case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
 	case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+	case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
+	case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+	case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
 	case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
 	case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */
 	case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
 	case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
 	case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
+	case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
+	case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
 		break;
 	default:
 		printk(KERN_WARNING "%s: warning: "
@@ -6019,6 +6197,11 @@ int saa7134_board_init1(struct saa7134_d
 		msleep(10);
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+		saa7134_set_gpio(dev, 23, 0);
+		msleep(10);
+		saa7134_set_gpio(dev, 23, 1);
+		dev->has_remote = SAA7134_REMOTE_I2C;
+		break;
 	case SAA7134_BOARD_AVERMEDIA_M103:
 		saa7134_set_gpio(dev, 23, 0);
 		msleep(10);
@@ -6054,6 +6237,16 @@ int saa7134_board_init1(struct saa7134_d
 
 		saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
 		break;
+	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+	case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+		/* GPIO 26 high for digital, low for analog */
+		saa7134_set_gpio(dev, 26, 0);
+		msleep(1);
+
+		saa7134_set_gpio(dev, 22, 0);
+		msleep(10);
+		saa7134_set_gpio(dev, 22, 1);
+		break;
 	/* i2c remotes */
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
@@ -6079,15 +6272,11 @@ int saa7134_board_init1(struct saa7134_d
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x8c040007, 0x8c040007);
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
 		break;
-	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
 	case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
 		/* write windows gpio values */
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x80040100, 0x80040100);
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
-		printk("%s: %s: hybrid analog/dvb card\n"
-		       "%s: Sorry, only analog s-video and composite input "
-		       "are supported for now.\n",
-			dev->name, card(dev).name, dev->name);
 		break;
 	}
 	return 0;
@@ -6109,7 +6298,7 @@ static void saa7134_tuner_setup(struct s
 
 		tun_setup.mode_mask = T_RADIO;
 
-		saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+		saa_call_all(dev, tuner, s_type_addr, &tun_setup);
 		mode_mask &= ~T_RADIO;
 	}
 
@@ -6121,7 +6310,7 @@ static void saa7134_tuner_setup(struct s
 
 		tun_setup.mode_mask = mode_mask;
 
-		saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+		saa_call_all(dev, tuner, s_type_addr, &tun_setup);
 	}
 
 	if (dev->tda9887_conf) {
@@ -6130,8 +6319,7 @@ static void saa7134_tuner_setup(struct s
 		tda9887_cfg.tuner = TUNER_TDA9887;
 		tda9887_cfg.priv = &dev->tda9887_conf;
 
-		saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
-					 &tda9887_cfg);
+		saa_call_all(dev, tuner, s_config, &tda9887_cfg);
 	}
 
 	if (dev->tuner_type == TUNER_XC2028) {
@@ -6148,6 +6336,7 @@ static void saa7134_tuner_setup(struct s
 		case SAA7134_BOARD_AVERMEDIA_A16D:
 		case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
 		case SAA7134_BOARD_AVERMEDIA_M103:
+		case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
 			ctl.demod = XC3028_FE_ZARLINK456;
 			break;
 		default:
@@ -6158,7 +6347,7 @@ static void saa7134_tuner_setup(struct s
 		xc2028_cfg.tuner = TUNER_XC2028;
 		xc2028_cfg.priv  = &ctl;
 
-		saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+		saa_call_all(dev, tuner, s_config, &xc2028_cfg);
 	}
 }
 
@@ -6168,9 +6357,20 @@ int saa7134_board_init2(struct saa7134_d
 	unsigned char buf;
 	int board;
 
+	/* Put here the code that enables the chips that are needed
+	   for analog mode and doesn't depend on the tuner attachment.
+	   It is also a good idea to get tuner type from eeprom, etc before
+	   initializing tuner, since we can avoid loading tuner driver
+	   on devices that has TUNER_ABSENT
+	 */
 	switch (dev->board) {
 	case SAA7134_BOARD_BMK_MPEX_NOTUNER:
 	case SAA7134_BOARD_BMK_MPEX_TUNER:
+		/* Checks if the device has a tuner at 0x60 addr
+		   If the device doesn't have a tuner, TUNER_ABSENT
+		   will be used at tuner_type, avoiding loading tuner
+		   without needing it
+		 */
 		dev->i2c_client.addr = 0x60;
 		board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
 			? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6188,11 +6388,15 @@ int saa7134_board_init2(struct saa7134_d
 		u8 subaddr;
 		u8 data[3];
 		int ret, tuner_t;
-
 		struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
 					{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+
 		subaddr= 0x14;
 		tuner_t = 0;
+
+		/* Retrieve device data from eeprom, checking for the
+		   proper tuner_type.
+		 */
 		ret = i2c_transfer(&dev->i2c_adap, msg, 2);
 		if (ret != 2) {
 			printk(KERN_ERR "EEPROM read failure\n");
@@ -6248,12 +6452,14 @@ int saa7134_board_init2(struct saa7134_d
 				dev->name, saa7134_boards[dev->board].name);
 			break;
 		}
+		/* break intentionally omitted */
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
 	{
 
-		/* The Philips EUROPA based hybrid boards have the tuner connected through
-		 * the channel decoder. We have to make it transparent to find it
+		/* The Philips EUROPA based hybrid boards have the tuner
+		   connected through the channel decoder. We have to make it
+		   transparent to find it
 		 */
 		u8 data[] = { 0x07, 0x02};
 		struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
@@ -6274,21 +6480,15 @@ int saa7134_board_init2(struct saa7134_d
 		if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
 			dev->tuner_type = TUNER_PHILIPS_TDA8290;
 
-			saa7134_tuner_setup(dev);
-
 			data[2] = 0x68;
 			i2c_transfer(&dev->i2c_adap, &msg, 1);
-
-			/* Tuner setup is handled before I2C transfer.
-			   Due to that, there's no need to do it later
-			 */
-			return 0;
+			break;
 		}
 		i2c_transfer(&dev->i2c_adap, &msg, 1);
 		break;
 	}
-       case SAA7134_BOARD_ASUSTeK_TVFM7135:
-       /* The card below is detected as card=53, but is different */
+	case SAA7134_BOARD_ASUSTeK_TVFM7135:
+	/* The card below is detected as card=53, but is different */
 	       if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
 		       dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
 		       printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6296,6 +6496,10 @@ int saa7134_board_init2(struct saa7134_d
 		       dev->name, saa7134_boards[dev->board].name);
 	       }
 	       break;
+	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+	case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+		hauppauge_eeprom(dev, dev->eedata+0x80);
+		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
 		hauppauge_eeprom(dev, dev->eedata+0x80);
 		/* break intentionally omitted */
@@ -6351,22 +6555,6 @@ int saa7134_board_init2(struct saa7134_d
 		i2c_transfer(&dev->i2c_adap, &msg, 1);
 		break;
 	}
-	case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
-	case SAA7134_BOARD_KWORLD_ATSC110:
-	{
-		/* enable tuner */
-		int i;
-		static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
-					      0x00, 0x14, 0x04, 0x17, 0x00 };
-		dev->i2c_client.addr = 0x0a;
-		for (i = 0; i < 5; i++)
-			if (2 != i2c_master_send(&dev->i2c_client,
-						 &buffer[i*2], 2))
-				printk(KERN_WARNING
-				       "%s: Unable to enable tuner(%i).\n",
-				       dev->name, i);
-		break;
-	}
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
 		/* The T200 and the T200A share the same pci id.  Consequently,
@@ -6375,9 +6563,9 @@ int saa7134_board_init2(struct saa7134_d
 
 		/* Don't do this if the board was specifically selected with an
 		 * insmod option or if we have the default configuration T200*/
-		if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+		if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
 			break;
-		if(dev->eedata[0x41] == 0x02) {
+		if (dev->eedata[0x41] == 0x02) {
 			/* Reconfigure board  as T200A */
 			dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
 			dev->tuner_type   = saa7134_boards[dev->board].tuner_type;
@@ -6390,6 +6578,62 @@ int saa7134_board_init2(struct saa7134_d
 			break;
 		}
 		break;
+	case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+	case SAA7134_BOARD_KWORLD_ATSC110:
+	{
+		struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+		int i;
+		static u8 buffer[][2] = {
+			{ 0x10, 0x12 },
+			{ 0x13, 0x04 },
+			{ 0x16, 0x00 },
+			{ 0x14, 0x04 },
+			{ 0x17, 0x00 },
+		};
+
+		for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+			msg.buf = &buffer[i][0];
+			msg.len = ARRAY_SIZE(buffer[0]);
+			if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+				printk(KERN_WARNING
+				       "%s: Unable to enable tuner(%i).\n",
+				       dev->name, i);
+		}
+		break;
+	}
+	} /* switch() */
+
+	/* initialize tuner */
+	if (TUNER_ABSENT != dev->tuner_type) {
+		int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+		/* Note: radio tuner address is always filled in,
+		   so we do not need to probe for a radio tuner device. */
+		if (dev->radio_type != UNSET)
+			v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				dev->radio_addr);
+		if (has_demod)
+			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		if (dev->tuner_addr == ADDR_UNSET) {
+			enum v4l2_i2c_tuner_type type =
+				has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				v4l2_i2c_tuner_addrs(type));
+		} else {
+			v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_adap, "tuner", "tuner",
+				dev->tuner_addr);
+		}
+	}
+
+	saa7134_tuner_setup(dev);
+
+	switch (dev->board) {
 	case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
 	{
 		struct v4l2_priv_tun_config tea5767_cfg;
@@ -6401,12 +6645,10 @@ int saa7134_board_init2(struct saa7134_d
 		ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
 		tea5767_cfg.tuner = TUNER_TEA5767;
 		tea5767_cfg.priv  = &ctl;
-		saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
+		saa_call_all(dev, tuner, s_config, &tea5767_cfg);
 		break;
 	}
 	} /* switch() */
 
-	saa7134_tuner_setup(dev);
-
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-core.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -54,13 +54,9 @@ static unsigned int gpio_tracking;
 module_param(gpio_tracking, int, 0644);
 MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
 
-static unsigned int alsa;
+static unsigned int alsa = 1;
 module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
-static unsigned int oss;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
 
 static unsigned int latency = UNSET;
 module_param(latency, int, 0444);
@@ -90,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device
 MODULE_PARM_DESC(tuner,    "tuner type");
 MODULE_PARM_DESC(card,     "card type");
 
-static DEFINE_MUTEX(devlist_lock);
+DEFINE_MUTEX(saa7134_devlist_lock);
+EXPORT_SYMBOL(saa7134_devlist_lock);
 LIST_HEAD(saa7134_devlist);
+EXPORT_SYMBOL(saa7134_devlist);
 static LIST_HEAD(mops_list);
 static unsigned int saa7134_devcount;
 
@@ -156,10 +154,10 @@ static void request_module_async(struct
 		request_module("saa7134-empress");
 	if (card_is_dvb(dev))
 		request_module("saa7134-dvb");
-	if (alsa)
-		request_module("saa7134-alsa");
-	if (oss)
-		request_module("saa7134-oss");
+	if (alsa) {
+		if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
+			request_module("saa7134-alsa");
+	}
 }
 
 static void request_submodules(struct saa7134_dev *dev)
@@ -778,7 +776,7 @@ static struct video_device *vdev_init(st
 		return NULL;
 	*vfd = *template;
 	vfd->minor   = -1;
-	vfd->parent  = &dev->pci->dev;
+	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	vfd->debug   = video_debug;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
@@ -851,6 +849,10 @@ static int __devinit saa7134_initdev(str
 	if (NULL == dev)
 		return -ENOMEM;
 
+	err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+	if (err)
+		goto fail0;
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
@@ -909,7 +911,7 @@ static int __devinit saa7134_initdev(str
 	       pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
 	       dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
 	pci_set_master(pci_dev);
-	if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) {
+	if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
 		printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
 		err = -EIO;
 		goto fail1;
@@ -927,6 +929,8 @@ static int __devinit saa7134_initdev(str
 	dev->autodetected = card[dev->nr] != dev->board;
 	dev->tuner_type = saa7134_boards[dev->board].tuner_type;
 	dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
+	dev->radio_type = saa7134_boards[dev->board].radio_type;
+	dev->radio_addr = saa7134_boards[dev->board].radio_addr;
 	dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
 	if (UNSET != tuner[dev->nr])
 		dev->tuner_type = tuner[dev->nr];
@@ -971,23 +975,47 @@ static int __devinit saa7134_initdev(str
 	/* wait a bit, register i2c bus */
 	msleep(100);
 	saa7134_i2c_register(dev);
-
-	/* initialize hardware #2 */
-	if (TUNER_ABSENT != dev->tuner_type)
-		request_module("tuner");
 	saa7134_board_init2(dev);
 
 	saa7134_hwinit2(dev);
 
 	/* load i2c helpers */
 	if (card_is_empress(dev)) {
-		request_module("saa6752hs");
+		struct v4l2_subdev *sd =
+			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+				"saa6752hs", "saa6752hs",
+				saa7134_boards[dev->board].empress_addr);
+
+		if (sd)
+			sd->grp_id = GRP_EMPRESS;
+	}
+
+	if (saa7134_boards[dev->board].rds_addr) {
+		struct v4l2_subdev *sd;
+
+		sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev,
+				&dev->i2c_adap,	"saa6588", "saa6588",
+				saa7134_boards[dev->board].rds_addr);
+		if (sd)
+			printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
 	}
 
 	request_submodules(dev);
 
 	v4l2_prio_init(&dev->prio);
 
+	mutex_lock(&saa7134_devlist_lock);
+	list_for_each_entry(mops, &mops_list, next)
+		mpeg_ops_attach(mops, dev);
+	list_add_tail(&dev->devlist, &saa7134_devlist);
+	mutex_unlock(&saa7134_devlist_lock);
+
+	/* check for signal */
+	saa7134_irq_video_signalchange(dev);
+
+	if (TUNER_ABSENT != dev->tuner_type)
+		saa_call_all(dev, tuner, s_standby);
+
 	/* register v4l devices */
 	if (saa7134_no_overlay > 0)
 		printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
@@ -1023,24 +1051,10 @@ static int __devinit saa7134_initdev(str
 	}
 
 	/* everything worked */
-	pci_set_drvdata(pci_dev,dev);
 	saa7134_devcount++;
 
-	mutex_lock(&devlist_lock);
-	list_for_each_entry(mops, &mops_list, next)
-		mpeg_ops_attach(mops, dev);
-	list_add_tail(&dev->devlist,&saa7134_devlist);
-	mutex_unlock(&devlist_lock);
-
-	/* check for signal */
-	saa7134_irq_video_signalchange(dev);
-
-	if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
+	if (saa7134_dmasound_init && !dev->dmasound.priv_data)
 		saa7134_dmasound_init(dev);
-	}
-
-	if (TUNER_ABSENT != dev->tuner_type)
-		saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
 
 	return 0;
 
@@ -1055,13 +1069,16 @@ static int __devinit saa7134_initdev(str
 	release_mem_region(pci_resource_start(pci_dev,0),
 			   pci_resource_len(pci_dev,0));
  fail1:
+	v4l2_device_unregister(&dev->v4l2_dev);
+ fail0:
 	kfree(dev);
 	return err;
 }
 
 static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 {
-	struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
 	struct saa7134_mpeg_ops *mops;
 
 	/* Release DMA sound modules if present */
@@ -1088,11 +1105,11 @@ static void __devexit saa7134_finidev(st
 	saa7134_hwfini(dev);
 
 	/* unregister */
-	mutex_lock(&devlist_lock);
+	mutex_lock(&saa7134_devlist_lock);
 	list_del(&dev->devlist);
 	list_for_each_entry(mops, &mops_list, next)
 		mpeg_ops_detach(mops, dev);
-	mutex_unlock(&devlist_lock);
+	mutex_unlock(&saa7134_devlist_lock);
 	saa7134_devcount--;
 
 	saa7134_i2c_unregister(dev);
@@ -1113,7 +1130,8 @@ static void __devexit saa7134_finidev(st
 	release_mem_region(pci_resource_start(pci_dev,0),
 			   pci_resource_len(pci_dev,0));
 
-	pci_set_drvdata(pci_dev, NULL);
+
+	v4l2_device_unregister(&dev->v4l2_dev);
 
 	/* free memory */
 	kfree(dev);
@@ -1148,8 +1166,8 @@ static int saa7134_buffer_requeue(struct
 
 static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 {
-
-	struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
 
 	/* disable overlay - apps should enable it explicitly on resume*/
 	dev->ovenable = 0;
@@ -1185,7 +1203,8 @@ static int saa7134_suspend(struct pci_de
 
 static int saa7134_resume(struct pci_dev *pci_dev)
 {
-	struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
 	unsigned long flags;
 
 	pci_set_power_state(pci_dev, PCI_D0);
@@ -1247,11 +1266,11 @@ int saa7134_ts_register(struct saa7134_m
 {
 	struct saa7134_dev *dev;
 
-	mutex_lock(&devlist_lock);
+	mutex_lock(&saa7134_devlist_lock);
 	list_for_each_entry(dev, &saa7134_devlist, devlist)
 		mpeg_ops_attach(ops, dev);
 	list_add_tail(&ops->next,&mops_list);
-	mutex_unlock(&devlist_lock);
+	mutex_unlock(&saa7134_devlist_lock);
 	return 0;
 }
 
@@ -1259,11 +1278,11 @@ void saa7134_ts_unregister(struct saa713
 {
 	struct saa7134_dev *dev;
 
-	mutex_lock(&devlist_lock);
+	mutex_lock(&saa7134_devlist_lock);
 	list_del(&ops->next);
 	list_for_each_entry(dev, &saa7134_devlist, devlist)
 		mpeg_ops_detach(ops, dev);
-	mutex_unlock(&devlist_lock);
+	mutex_unlock(&saa7134_devlist_lock);
 }
 
 EXPORT_SYMBOL(saa7134_ts_register);
@@ -1307,8 +1326,6 @@ module_exit(saa7134_fini);
 /* ----------------------------------------------------------- */
 
 EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_i2c_call_clients);
-EXPORT_SYMBOL(saa7134_devlist);
 EXPORT_SYMBOL(saa7134_boards);
 
 /* ----------------- for the DMA sound modules --------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-dvb.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-dvb.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 18:02:12.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-dvb.c	2013-05-03 16:46:03.000000000 -0400
@@ -48,9 +48,15 @@
 #include "isl6405.h"
 #include "lnbp21.h"
 #include "tuner-simple.h"
+#include "tda18271.h"
+#include "lgdt3305.h"
+#include "tda8290.h"
 
 #include "zl10353.h"
 
+#include "zl10036.h"
+#include "mt312.h"
+
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_LICENSE("GPL");
 
@@ -189,7 +195,7 @@ static int mt352_pinnacle_tuner_set_para
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 	i2c_transfer(&dev->i2c_adap, &msg, 1);
-	saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+	saa_call_all(dev, tuner, s_frequency, &f);
 	msg.buf = on;
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
@@ -950,6 +956,45 @@ static struct nxt200x_config kworldatsc1
 	.demod_address    = 0x0a,
 };
 
+/* ------------------------------------------------------------------ */
+
+static struct mt312_config avertv_a700_mt312 = {
+	.demod_address = 0x0e,
+	.voltage_inverted = 1,
+};
+
+static struct zl10036_config avertv_a700_tuner = {
+	.tuner_address = 0x60,
+};
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+	.i2c_addr           = 0x0e,
+	.mpeg_mode          = LGDT3305_MPEG_SERIAL,
+	.tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
+	.tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+	.deny_i2c_rptr      = 1,
+	.spectral_inversion = 1,
+	.qam_if_khz         = 4000,
+	.vsb_if_khz         = 3250,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x58, },
+	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x58, },
+};
+
+static struct tda18271_config hcw_tda18271_config = {
+	.std_map = &hauppauge_tda18271_std_map,
+	.gate    = TDA18271_GATE_ANALOG,
+	.config  = 3,
+};
+
+static struct tda829x_config tda829x_no_probe = {
+	.probe_tuner = TDA829X_DONT_PROBE,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -1076,6 +1121,19 @@ static int dvb_init(struct saa7134_dev *
 					 &tda827x_cfg_1) < 0)
 			goto dettach_frontend;
 		break;
+	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+		fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+					       &hcw_lgdt3305_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend) {
+			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,
+				   &hcw_tda18271_config);
+		}
+		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 		if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
 					 &tda827x_cfg_0) < 0)
@@ -1376,6 +1434,19 @@ static int dvb_init(struct saa7134_dev *
 				   TUNER_PHILIPS_FMD1216ME_MK3);
 		}
 		break;
+	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+	case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+		/* Zarlink ZL10313 */
+		fe0->dvb.frontend = dvb_attach(mt312_attach,
+			&avertv_a700_mt312, &dev->i2c_adap);
+		if (fe0->dvb.frontend) {
+			if (dvb_attach(zl10036_attach, fe0->dvb.frontend,
+					&avertv_a700_tuner, &dev->i2c_adap) == NULL) {
+				wprintk("%s: No zl10036 found!\n",
+					__func__);
+			}
+		}
+		break;
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		break;
@@ -1449,7 +1520,7 @@ static int dvb_fini(struct saa7134_dev *
 		tda9887_cfg.priv  = &on;
 
 		/* otherwise we don't detect the tuner on next insmod */
-		saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+		saa_call_all(dev, tuner, s_config, &tda9887_cfg);
 	} else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
 		if ((dev->eedata[2] == 0x07) && use_frontend) {
 			/* turn off the 2nd lnb supply */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-empress.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-empress.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-empress.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,7 +76,7 @@ static int ts_init_encoder(struct saa713
 		break;
 	}
 	ts_reset_encoder(dev);
-	saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes);
+	saa_call_all(dev, core, init, leading_null_bytes);
 	dev->empress_started = 1;
 	return 0;
 }
@@ -234,7 +234,7 @@ static int empress_g_fmt_vid_cap(struct
 {
 	struct saa7134_dev *dev = file->private_data;
 
-	saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+	saa_call_all(dev, video, g_fmt, f);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -247,7 +247,7 @@ static int empress_s_fmt_vid_cap(struct
 {
 	struct saa7134_dev *dev = file->private_data;
 
-	saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
+	saa_call_all(dev, video, s_fmt, f);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -317,7 +317,7 @@ static int empress_s_ext_ctrls(struct fi
 	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
 		return -EINVAL;
 
-	err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+	err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
 	ts_init_encoder(dev);
 
 	return err;
@@ -330,7 +330,7 @@ static int empress_g_ext_ctrls(struct fi
 
 	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
 		return -EINVAL;
-	return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+	return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
 }
 
 static int empress_g_ctrl(struct file *file, void *priv,
@@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *f
 static int empress_queryctrl(struct file *file, void *priv,
 					struct v4l2_queryctrl *c)
 {
+	/* Must be sorted from low to high control ID! */
 	static const u32 user_ctrls[] = {
 		V4L2_CID_USER_CLASS,
 		V4L2_CID_BRIGHTNESS,
@@ -364,6 +365,7 @@ static int empress_queryctrl(struct file
 		0
 	};
 
+	/* Must be sorted from low to high control ID! */
 	static const u32 mpeg_ctrls[] = {
 		V4L2_CID_MPEG_CLASS,
 		V4L2_CID_MPEG_STREAM_TYPE,
@@ -388,10 +390,10 @@ static int empress_queryctrl(struct file
 	if (c->id == 0)
 		return -EINVAL;
 	if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
-		return v4l2_ctrl_query_fill_std(c);
+		return v4l2_ctrl_query_fill(c, 0, 0, 0, 0);
 	if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
 		return saa7134_queryctrl(file, priv, c);
-	return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+	return saa_call_empress(dev, core, queryctrl, c);
 }
 
 static int empress_querymenu(struct file *file, void *priv,
@@ -401,7 +403,7 @@ static int empress_querymenu(struct file
 
 	if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
 		return -EINVAL;
-	return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
+	return saa_call_empress(dev, core, querymenu, c);
 }
 
 static int empress_g_chip_ident(struct file *file, void *fh,
@@ -411,14 +413,11 @@ static int empress_g_chip_ident(struct f
 
 	chip->ident = V4L2_IDENT_NONE;
 	chip->revision = 0;
-	if (dev->mpeg_i2c_client == NULL)
-		return -EINVAL;
 	if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
 	    !strcmp(chip->match.name, "saa6752hs"))
-		return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
-	if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR &&
-	    chip->match.addr == dev->mpeg_i2c_client->addr)
-		return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+		return saa_call_empress(dev, core, g_chip_ident, chip);
+	if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
+		return saa_call_empress(dev, core, g_chip_ident, chip);
 	return -EINVAL;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134.h linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,7 @@
  */
 
 #include <linux/version.h>
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,14)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,15)
 
 #include <linux/pci.h>
 #include <linux/i2c.h>
@@ -35,6 +35,7 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
@@ -277,6 +278,8 @@ struct saa7134_format {
 #define SAA7134_BOARD_ASUSTeK_TIGER         152
 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
+#define SAA7134_BOARD_HAUPPAUGE_HVR1120     155
+#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
@@ -309,6 +312,11 @@ enum saa7134_mpeg_type {
 	SAA7134_MPEG_DVB,
 };
 
+enum saa7134_mpeg_ts_type {
+	SAA7134_MPEG_TS_PARALLEL = 0,
+	SAA7134_MPEG_TS_SERIAL,
+};
+
 struct saa7134_board {
 	char                    *name;
 	unsigned int            audio_clock;
@@ -324,6 +332,8 @@ struct saa7134_board {
 	unsigned int		radio_type;
 	unsigned char		tuner_addr;
 	unsigned char		radio_addr;
+	unsigned char		empress_addr;
+	unsigned char		rds_addr;
 
 	unsigned int            tda9887_conf;
 	unsigned int            tuner_config;
@@ -331,6 +341,7 @@ struct saa7134_board {
 	/* peripheral I/O */
 	enum saa7134_video_out  video_out;
 	enum saa7134_mpeg_type  mpeg;
+	enum saa7134_mpeg_ts_type ts_type;
 	unsigned int            vid_port_opts;
 };
 
@@ -445,7 +456,6 @@ struct saa7134_dmasound {
 	unsigned int               bufsize;
 	struct saa7134_pgtable     pt;
 	struct videobuf_dmabuf     dma;
-	wait_queue_head_t          wq;
 	unsigned int               dma_blk;
 	unsigned int               read_offset;
 	unsigned int               read_count;
@@ -482,6 +492,7 @@ struct saa7134_dev {
 	struct mutex               lock;
 	spinlock_t                 slock;
 	struct v4l2_prio_state     prio;
+	struct v4l2_device         v4l2_dev;
 	/* workstruct for loading modules */
 	struct work_struct request_module_wk;
 
@@ -572,7 +583,6 @@ struct saa7134_dev {
 	enum saa7134_ts_status 	   ts_state;
 	unsigned int 		   buff_cnt;
 	struct saa7134_mpeg_ops    *mops;
-	struct i2c_client 	   *mpeg_i2c_client;
 
 	/* SAA7134_MPEG_EMPRESS only */
 	struct video_device        *empress_dev;
@@ -588,6 +598,7 @@ struct saa7134_dev {
 	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
 	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
 #endif
+	void (*gate_ctrl)(struct saa7134_dev *dev, int open);
 };
 
 /* ----------------------------------------------------------- */
@@ -616,10 +627,31 @@ struct saa7134_dev {
 		V4L2_STD_NTSC   | V4L2_STD_PAL_M | \
 		V4L2_STD_PAL_60)
 
+#define GRP_EMPRESS (1)
+#define saa_call_all(dev, o, f, args...) do {				\
+	if (dev->gate_ctrl)						\
+		dev->gate_ctrl(dev, 1);					\
+	v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args);	\
+	if (dev->gate_ctrl)						\
+		dev->gate_ctrl(dev, 0);					\
+} while (0)
+
+#define saa_call_empress(dev, o, f, args...) ({				\
+	long _rc;							\
+	if (dev->gate_ctrl)						\
+		dev->gate_ctrl(dev, 1);					\
+	_rc = v4l2_device_call_until_err(&(dev)->v4l2_dev,		\
+					 GRP_EMPRESS, o, f , ##args);	\
+	if (dev->gate_ctrl)						\
+		dev->gate_ctrl(dev, 0);					\
+	_rc;								\
+})
+
 /* ----------------------------------------------------------- */
 /* saa7134-core.c                                              */
 
 extern struct list_head  saa7134_devlist;
+extern struct mutex saa7134_devlist_lock;
 extern int saa7134_no_overlay;
 
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
@@ -668,10 +700,6 @@ int saa7134_tuner_callback(void *priv, i
 
 int saa7134_i2c_register(struct saa7134_dev *dev);
 int saa7134_i2c_unregister(struct saa7134_dev *dev);
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
-			      unsigned int cmd, void *arg);
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
-			      unsigned int cmd, void *arg);
 
 
 /* ----------------------------------------------------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -255,7 +255,7 @@ static int saa7134_i2c_xfer(struct i2c_a
 			addr  = msgs[i].addr << 1;
 			if (msgs[i].flags & I2C_M_RD)
 				addr |= 1;
-			if (i > 0 && msgs[i].flags & I2C_M_RD) {
+			if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) {
 				/* workaround for a saa7134 i2c bug
 				 * needed to talk to the mt352 demux
 				 * thanks to pinnacle for the hint */
@@ -327,8 +327,6 @@ static int attach_inform(struct i2c_clie
 
 	d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
 		client->driver->driver.name, client->addr, client->name);
-	if (client->addr == 0x20 && client->driver && client->driver->command)
-		dev->mpeg_i2c_client = client;
 
 	/* Am I an i2c remote control? */
 
@@ -357,7 +355,6 @@ static struct i2c_algorithm saa7134_algo
 
 static struct i2c_adapter saa7134_adap_template = {
 	.owner         = THIS_MODULE,
-	.class         = I2C_CLASS_TV_ANALOG,
 	.name          = "saa7134",
 	.id            = I2C_HW_SAA7134,
 	.algo          = &saa7134_algo,
@@ -421,29 +418,13 @@ static void do_i2c_scan(char *name, stru
 	}
 }
 
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
-			      unsigned int cmd, void *arg)
-{
-	BUG_ON(NULL == dev->i2c_adap.algo_data);
-	i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
-					      unsigned int cmd, void *arg)
-{
-	if (dev->mpeg_i2c_client == NULL)
-		return -EINVAL;
-	return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
-								cmd, arg);
-}
-EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752);
-
 int saa7134_i2c_register(struct saa7134_dev *dev)
 {
 	dev->i2c_adap = saa7134_adap_template;
 	dev->i2c_adap.dev.parent = &dev->pci->dev;
 	strcpy(dev->i2c_adap.name,dev->name);
 	dev->i2c_adap.algo_data = dev;
+	i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
 	i2c_add_adapter(&dev->i2c_adap);
 
 	dev->i2c_client = saa7134_client_template;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-ts.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-ts.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-ts.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,8 +79,19 @@ static int buffer_activate(struct saa713
 		saa_writeb(SAA7134_TS_SERIAL1, 0x00);
 
 		/* Start TS stream */
-		saa_writeb(SAA7134_TS_SERIAL0, 0x40);
-		saa_writeb(SAA7134_TS_PARALLEL, 0xEC);
+		switch (saa7134_boards[dev->board].ts_type) {
+		case SAA7134_MPEG_TS_PARALLEL:
+			saa_writeb(SAA7134_TS_SERIAL0, 0x40);
+			saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+			break;
+		case SAA7134_MPEG_TS_SERIAL:
+			saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
+			saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+			saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
+			saa_writeb(SAA7134_TS_SERIAL1, 0x02);
+			break;
+		}
+
 		dev->ts_state = SAA7134_TS_STARTED;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-video.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7134/saa7134-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/saa7134-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,11 +30,7 @@
 #include "saa7134-reg.h"
 #include "saa7134.h"
 #include <media/v4l2-common.h>
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
+#include <media/rds.h>
 
 /* ------------------------------------------------------------------ */
 
@@ -452,6 +448,7 @@ static const struct v4l2_queryctrl video
 		.name          = "y offset odd field",
 		.minimum       = 0,
 		.maximum       = 128,
+		.step          = 1,
 		.default_value = 0,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},{
@@ -459,6 +456,7 @@ static const struct v4l2_queryctrl video
 		.name          = "y offset even field",
 		.minimum       = 0,
 		.maximum       = 128,
+		.step          = 1,
 		.default_value = 0,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},{
@@ -627,10 +625,10 @@ void saa7134_set_tvnorm_hw(struct saa713
 	saa7134_set_decoder(dev);
 
 	if (card_in(dev, dev->ctl_input).tv)
-		saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+		saa_call_all(dev, core, s_std, dev->tvnorm->id);
 	/* Set the correct norm for the saa6752hs. This function
 	   does nothing if there is no saa6752hs. */
-	saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+	saa_call_empress(dev, core, s_std, dev->tvnorm->id);
 }
 
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1266,8 +1264,7 @@ int saa7134_s_ctrl_internal(struct saa71
 			else
 				dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
 
-			saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
-						 &tda9887_cfg);
+			saa_call_all(dev, tuner, s_config, &tda9887_cfg);
 		}
 		break;
 	}
@@ -1334,7 +1331,7 @@ static int video_open(struct file *file)
 	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	int radio = 0;
 
-	lock_kernel();
+	mutex_lock(&saa7134_devlist_lock);
 	list_for_each_entry(dev, &saa7134_devlist, devlist) {
 		if (dev->video_dev && (dev->video_dev->minor == minor))
 			goto found;
@@ -1347,19 +1344,20 @@ static int video_open(struct file *file)
 			goto found;
 		}
 	}
-	unlock_kernel();
+	mutex_unlock(&saa7134_devlist_lock);
 	return -ENODEV;
- found:
+
+found:
+	mutex_unlock(&saa7134_devlist_lock);
 
 	dprintk("open minor=%d radio=%d type=%s\n",minor,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;
-	}
+
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
@@ -1387,12 +1385,11 @@ static int video_open(struct file *file)
 	if (fh->radio) {
 		/* switch to radio mode */
 		saa7134_tvaudio_setinput(dev,&card(dev).radio);
-		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
+		saa_call_all(dev, tuner, s_radio);
 	} else {
 		/* switch to video/vbi mode */
 		video_mux(dev,dev->ctl_input);
 	}
-	unlock_kernel();
 	return 0;
 }
 
@@ -1466,6 +1463,7 @@ static int video_release(struct file *fi
 {
 	struct saa7134_fh  *fh  = file->private_data;
 	struct saa7134_dev *dev = fh->dev;
+	struct rds_command cmd;
 	unsigned long flags;
 
 	/* turn off overlay */
@@ -1498,7 +1496,9 @@ static int video_release(struct file *fi
 	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
 	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
-	saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+	saa_call_all(dev, tuner, s_standby);
+	if (fh->radio)
+		saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
 
 	/* free stuff */
 	videobuf_mmap_free(&fh->cap);
@@ -1519,6 +1519,37 @@ static int video_mmap(struct file *file,
 	return videobuf_mmap_mapper(saa7134_queue(fh), vma);
 }
 
+static ssize_t radio_read(struct file *file, char __user *data,
+			 size_t count, loff_t *ppos)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct rds_command cmd;
+
+	cmd.block_count = count/3;
+	cmd.buffer = data;
+	cmd.instance = file;
+	cmd.result = -ENODEV;
+
+	saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd);
+
+	return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+	struct saa7134_fh *fh = file->private_data;
+	struct saa7134_dev *dev = fh->dev;
+	struct rds_command cmd;
+
+	cmd.instance = file;
+	cmd.event_list = wait;
+	cmd.result = -ENODEV;
+	saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd);
+
+	return cmd.result;
+}
+
 /* ------------------------------------------------------------------ */
 
 static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
@@ -2041,7 +2072,7 @@ static int saa7134_s_frequency(struct fi
 	mutex_lock(&dev->lock);
 	dev->ctl_freq = f->frequency;
 
-	saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+	saa_call_all(dev, tuner, s_frequency, f);
 
 	saa7134_tvaudio_do_scan(dev);
 	mutex_unlock(&dev->lock);
@@ -2299,7 +2330,7 @@ static int radio_g_tuner(struct file *fi
 	strcpy(t->name, "Radio");
 	t->type = V4L2_TUNER_RADIO;
 
-	saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+	saa_call_all(dev, tuner, g_tuner, t);
 	if (dev->input->amux == TV) {
 		t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
 		t->rxsubchans = (saa_readb(0x529) & 0x08) ?
@@ -2316,7 +2347,7 @@ static int radio_s_tuner(struct file *fi
 	if (0 != t->index)
 		return -EINVAL;
 
-	saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+	saa_call_all(dev, tuner, s_tuner, t);
 	return 0;
 }
 
@@ -2443,8 +2474,10 @@ static const struct v4l2_ioctl_ops video
 static const struct v4l2_file_operations radio_fops = {
 	.owner	  = THIS_MODULE,
 	.open	  = video_open,
+	.read     = radio_read,
 	.release  = video_release,
 	.ioctl	  = video_ioctl2,
+	.poll     = radio_poll,
 };
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7146.h linux-libre-2.6.30-gnu1/drivers/media/video/saa7146.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7146.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7146.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,8 +25,6 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-#include <linux/videodev.h>
-
 #ifndef O_NONCAP
 #define O_NONCAP	O_TRUNC
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa717x.c linux-libre-2.6.30-gnu1/drivers/media/video/saa717x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa717x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa717x.c	2009-06-09 23:05:27.000000000 -0400
@@ -931,7 +931,7 @@ static int saa717x_s_ctrl(struct v4l2_su
 		break;
 
 	case V4L2_CID_HUE:
-		if (ctrl->value < -127 || ctrl->value > 127) {
+		if (ctrl->value < -128 || ctrl->value > 127) {
 			v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
@@ -1104,22 +1104,22 @@ static struct v4l2_queryctrl saa717x_qct
 	},
 };
 
-static int saa717x_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_video_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct saa717x_state *decoder = to_state(sd);
-	int inp = route->input;
-	int is_tuner = inp & 0x80;  /* tuner input flag */
+	int is_tuner = input & 0x80;  /* tuner input flag */
 
-	inp &= 0x7f;
+	input &= 0x7f;
 
-	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", inp);
+	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 (inp < 0 || inp > 9 || inp == 5)
+	if (input < 0 || input > 9 || input == 5)
 		return -EINVAL;
 
-	if (decoder->input != inp) {
-		int input_line = inp;
+	if (decoder->input != input) {
+		int input_line = input;
 
 		decoder->input = input_line;
 		v4l2_dbg(1, debug, sd,  "now setting %s input %d\n",
@@ -1276,12 +1276,13 @@ static int saa717x_s_std(struct v4l2_sub
 	return 0;
 }
 
-static int saa717x_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
+				   u32 input, u32 output, u32 config)
 {
 	struct saa717x_state *decoder = to_state(sd);
 
-	if (route->input < 3) { /* FIXME! --tadachi */
-		decoder->audio_input = route->input;
+	if (input < 3) { /* FIXME! --tadachi */
+		decoder->audio_input = input;
 		v4l2_dbg(1, debug, sd,
 				"set decoder audio input to %d\n",
 				decoder->audio_input);
@@ -1380,11 +1381,6 @@ static int saa717x_g_tuner(struct v4l2_s
 	return 0;
 }
 
-static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa717x_core_ops = {
@@ -1395,12 +1391,12 @@ static const struct v4l2_subdev_core_ops
 	.queryctrl = saa717x_queryctrl,
 	.g_ctrl = saa717x_g_ctrl,
 	.s_ctrl = saa717x_s_ctrl,
+	.s_std = saa717x_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
 	.g_tuner = saa717x_g_tuner,
 	.s_tuner = saa717x_s_tuner,
-	.s_std = saa717x_s_std,
 	.s_radio = saa717x_s_radio,
 };
 
@@ -1528,10 +1524,7 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa717x",
-	.driverid = I2C_DRIVERID_SAA717X,
-	.command = saa717x_command,
 	.probe = saa717x_probe,
 	.remove = saa717x_remove,
-	.legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
 	.id_table = saa717x_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7185.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7185.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7185.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7185.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,52 +30,58 @@
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
 MODULE_LICENSE("GPL");
 
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+
 /* ----------------------------------------------------------------------- */
 
 struct saa7185 {
+	struct v4l2_subdev sd;
 	unsigned char reg[128];
 
-	int norm;
-	int enable;
-	int bright;
-	int contrast;
-	int hue;
-	int sat;
+	v4l2_std_id norm;
 };
 
+static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa7185, sd);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static inline int saa7185_read(struct i2c_client *client)
+static inline int saa7185_read(struct v4l2_subdev *sd)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_read_byte(client);
 }
 
-static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
-	struct saa7185 *encoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa7185 *encoder = to_saa7185(sd);
 
-	v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
+	v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value);
 	encoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static int saa7185_write_block(struct i2c_client *client,
+static int saa7185_write_block(struct v4l2_subdev *sd,
 		const u8 *data, unsigned int len)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa7185 *encoder = to_saa7185(sd);
 	int ret = -1;
 	u8 reg;
 
@@ -83,7 +89,6 @@ static int saa7185_write_block(struct i2
 	 * the adapter understands raw I2C */
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		/* do raw I2C, not smbus compatible */
-		struct saa7185 *encoder = i2c_get_clientdata(client);
 		u8 block_data[32];
 		int block_len;
 
@@ -104,7 +109,7 @@ static int saa7185_write_block(struct i2
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			ret = saa7185_write(client, reg, *data++);
+			ret = saa7185_write(sd, reg, *data++);
 			if (ret < 0)
 				break;
 			len -= 2;
@@ -213,133 +218,107 @@ static const unsigned char init_ntsc[] =
 	0x66, 0x21,		/* FSC3 */
 };
 
-static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	struct saa7185 *encoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-		saa7185_write_block(client, init_common,
-				    sizeof(init_common));
-		switch (encoder->norm) {
-
-		case VIDEO_MODE_NTSC:
-			saa7185_write_block(client, init_ntsc,
-					    sizeof(init_ntsc));
-			break;
-
-		case VIDEO_MODE_PAL:
-			saa7185_write_block(client, init_pal,
-					    sizeof(init_pal));
-			break;
-		}
-		break;
-
-	case ENCODER_GET_CAPABILITIES:
-	{
-		struct video_encoder_capability *cap = arg;
-
-		cap->flags =
-		    VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
-		    VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
-		cap->inputs = 1;
-		cap->outputs = 1;
-		break;
-	}
-
-	case ENCODER_SET_NORM:
-	{
-		int *iarg = arg;
-
-		//saa7185_write_block(client, init_common, sizeof(init_common));
 
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			saa7185_write_block(client, init_ntsc,
-					    sizeof(init_ntsc));
-			break;
-
-		case VIDEO_MODE_PAL:
-			saa7185_write_block(client, init_pal,
-					    sizeof(init_pal));
-			break;
+static int saa7185_init(struct v4l2_subdev *sd, u32 val)
+{
+	struct saa7185 *encoder = to_saa7185(sd);
 
-		case VIDEO_MODE_SECAM:
-		default:
-			return -EINVAL;
-		}
-		encoder->norm = *iarg;
-		break;
-	}
+	saa7185_write_block(sd, init_common, sizeof(init_common));
+	if (encoder->norm & V4L2_STD_NTSC)
+		saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+	else
+		saa7185_write_block(sd, init_pal, sizeof(init_pal));
+	return 0;
+}
 
-	case ENCODER_SET_INPUT:
-	{
-		int *iarg = arg;
+static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct saa7185 *encoder = to_saa7185(sd);
 
-		/* RJ: *iarg = 0: input is from SA7111
-		 *iarg = 1: input is from ZR36060 */
+	if (std & V4L2_STD_NTSC)
+		saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+	else if (std & V4L2_STD_PAL)
+		saa7185_write_block(sd, init_pal, sizeof(init_pal));
+	else
+		return -EINVAL;
+	encoder->norm = std;
+	return 0;
+}
 
-		switch (*iarg) {
-		case 0:
-			/* Switch RTCE to 1 */
-			saa7185_write(client, 0x61,
-				      (encoder->reg[0x61] & 0xf7) | 0x08);
-			saa7185_write(client, 0x6e, 0x01);
-			break;
+static int saa7185_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
+{
+	struct saa7185 *encoder = to_saa7185(sd);
 
-		case 1:
-			/* Switch RTCE to 0 */
-			saa7185_write(client, 0x61,
-				      (encoder->reg[0x61] & 0xf7) | 0x00);
-			/* SW: a slight sync problem... */
-			saa7185_write(client, 0x6e, 0x00);
-			break;
+	/* RJ: input = 0: input is from SA7111
+	 input = 1: input is from ZR36060 */
 
-		default:
-			return -EINVAL;
-		}
+	switch (input) {
+	case 0:
+		/* turn off colorbar */
+		saa7185_write(sd, 0x3a, 0x0f);
+		/* Switch RTCE to 1 */
+		saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+		saa7185_write(sd, 0x6e, 0x01);
 		break;
-	}
 
-	case ENCODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
-
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
+	case 1:
+		/* turn off colorbar */
+		saa7185_write(sd, 0x3a, 0x0f);
+		/* Switch RTCE to 0 */
+		saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
+		/* SW: a slight sync problem... */
+		saa7185_write(sd, 0x6e, 0x00);
 		break;
-	}
 
-	case ENCODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
-
-		encoder->enable = !!*iarg;
-		saa7185_write(client, 0x61,
-			      (encoder->reg[0x61] & 0xbf) |
-			      (encoder->enable ? 0x00 : 0x40));
+	case 2:
+		/* turn on colorbar */
+		saa7185_write(sd, 0x3a, 0x8f);
+		/* Switch RTCE to 0 */
+		saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+		/* SW: a slight sync problem... */
+		saa7185_write(sd, 0x6e, 0x01);
 		break;
-	}
 
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
+static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
+}
+
 /* ----------------------------------------------------------------------- */
 
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops saa7185_core_ops = {
+	.g_chip_ident = saa7185_g_chip_ident,
+	.init = saa7185_init,
+};
+
+static const struct v4l2_subdev_video_ops saa7185_video_ops = {
+	.s_std_output = saa7185_s_std_output,
+	.s_routing = saa7185_s_routing,
+};
+
+static const struct v4l2_subdev_ops saa7185_ops = {
+	.core = &saa7185_core_ops,
+	.video = &saa7185_video_ops,
+};
 
-I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
 
 static int saa7185_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	int i;
 	struct saa7185 *encoder;
+	struct v4l2_subdev *sd;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -351,28 +330,29 @@ static int saa7185_probe(struct i2c_clie
 	encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
-	encoder->norm = VIDEO_MODE_NTSC;
-	encoder->enable = 1;
-	i2c_set_clientdata(client, encoder);
+	encoder->norm = V4L2_STD_NTSC;
+	sd = &encoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa7185_ops);
 
-	i = saa7185_write_block(client, init_common, sizeof(init_common));
+	i = saa7185_write_block(sd, init_common, sizeof(init_common));
 	if (i >= 0)
-		i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+		i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
 	if (i < 0)
-		v4l_dbg(1, debug, client, "init error %d\n", i);
+		v4l2_dbg(1, debug, sd, "init error %d\n", i);
 	else
-		v4l_dbg(1, debug, client, "revision 0x%x\n",
-				saa7185_read(client) >> 5);
+		v4l2_dbg(1, debug, sd, "revision 0x%x\n",
+				saa7185_read(sd) >> 5);
 	return 0;
 }
 
 static int saa7185_remove(struct i2c_client *client)
 {
-	struct saa7185 *encoder = i2c_get_clientdata(client);
-
-	saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40);	/* SW: output off is active */
-	//saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa7185 *encoder = to_saa7185(sd);
 
+	v4l2_device_unregister_subdev(sd);
+	/* SW: output off is active */
+	saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
 	kfree(encoder);
 	return 0;
 }
@@ -387,8 +367,6 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "saa7185",
-	.driverid = I2C_DRIVERID_SAA7185B,
-	.command = saa7185_command,
 	.probe = saa7185_probe,
 	.remove = saa7185_remove,
 	.id_table = saa7185_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7191.c linux-libre-2.6.30-gnu1/drivers/media/video/saa7191.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7191.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7191.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,9 +19,11 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 #include "saa7191.h"
 
@@ -32,6 +34,7 @@ MODULE_VERSION(SAA7191_MODULE_VERSION);
 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
 MODULE_LICENSE("GPL");
 
+
 // #define SAA7191_DEBUG
 
 #ifdef SAA7191_DEBUG
@@ -44,17 +47,20 @@ MODULE_LICENSE("GPL");
 #define SAA7191_SYNC_DELAY	100	/* milliseconds */
 
 struct saa7191 {
-	struct i2c_client *client;
+	struct v4l2_subdev sd;
 
 	/* the register values are stored here as the actual
 	 * I2C-registers are write-only */
 	u8 reg[25];
 
 	int input;
-	int norm;
+	v4l2_std_id norm;
 };
 
-static struct i2c_driver i2c_driver_saa7191;
+static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa7191, sd);
+}
 
 static const u8 initseq[] = {
 	0,	/* Subaddress */
@@ -100,15 +106,14 @@ static const u8 initseq[] = {
 
 /* SAA7191 register handling */
 
-static u8 saa7191_read_reg(struct i2c_client *client,
-			   u8 reg)
+static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
 {
-	return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
+	return to_saa7191(sd)->reg[reg];
 }
 
-static int saa7191_read_status(struct i2c_client *client,
-			       u8 *value)
+static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
 
 	ret = i2c_master_recv(client, value, 1);
@@ -121,21 +126,23 @@ static int saa7191_read_status(struct i2
 }
 
 
-static int saa7191_write_reg(struct i2c_client *client, u8 reg,
-			     u8 value)
+static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
-	((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	to_saa7191(sd)->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
 /* the first byte of data must be the first subaddress number (register) */
-static int saa7191_write_block(struct i2c_client *client,
+static int saa7191_write_block(struct v4l2_subdev *sd,
 			       u8 length, const u8 *data)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct saa7191 *decoder = to_saa7191(sd);
 	int i;
 	int ret;
 
-	struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
 	for (i = 0; i < (length - 1); i++) {
 		decoder->reg[data[0] + i] = data[i + 1];
 	}
@@ -152,11 +159,12 @@ static int saa7191_write_block(struct i2
 
 /* Helper functions */
 
-static int saa7191_set_input(struct i2c_client *client, int input)
+static int saa7191_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
-	struct saa7191 *decoder = i2c_get_clientdata(client);
-	u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
-	u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
+	struct saa7191 *decoder = to_saa7191(sd);
+	u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+	u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
 	int err;
 
 	switch (input) {
@@ -175,10 +183,10 @@ static int saa7191_set_input(struct i2c_
 		return -EINVAL;
 	}
 
-	err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
+	err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
 	if (err)
 		return -EIO;
-	err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
+	err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
 	if (err)
 		return -EIO;
 
@@ -187,42 +195,38 @@ static int saa7191_set_input(struct i2c_
 	return 0;
 }
 
-static int saa7191_set_norm(struct i2c_client *client, int norm)
+static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 {
-	struct saa7191 *decoder = i2c_get_clientdata(client);
-	u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
-	u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
-	u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
+	struct saa7191 *decoder = to_saa7191(sd);
+	u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+	u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
+	u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV);
 	int err;
 
-	switch(norm) {
-	case SAA7191_NORM_PAL:
+	if (norm & V4L2_STD_PAL) {
 		stdc &= ~SAA7191_STDC_SECS;
 		ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
 		chcv = SAA7191_CHCV_PAL;
-		break;
-	case SAA7191_NORM_NTSC:
+	} else if (norm & V4L2_STD_NTSC) {
 		stdc &= ~SAA7191_STDC_SECS;
 		ctl3 &= ~SAA7191_CTL3_AUFD;
 		ctl3 |= SAA7191_CTL3_FSEL;
 		chcv = SAA7191_CHCV_NTSC;
-		break;
-	case SAA7191_NORM_SECAM:
+	} else if (norm & V4L2_STD_SECAM) {
 		stdc |= SAA7191_STDC_SECS;
 		ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
 		chcv = SAA7191_CHCV_PAL;
-		break;
-	default:
+	} else {
 		return -EINVAL;
 	}
 
-	err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
 	if (err)
 		return -EIO;
-	err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+	err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
 	if (err)
 		return -EIO;
-	err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
+	err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
 	if (err)
 		return -EIO;
 
@@ -230,19 +234,19 @@ static int saa7191_set_norm(struct i2c_c
 
 	dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
 		stdc, chcv);
-	dprintk("norm: %d\n", norm);
+	dprintk("norm: %llx\n", norm);
 
 	return 0;
 }
 
-static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
+static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
 {
 	int i = 0;
 
 	dprintk("Checking for signal...\n");
 
 	for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
-		if (saa7191_read_status(client, status))
+		if (saa7191_read_status(sd, status))
 			return -EIO;
 
 		if (((*status) & SAA7191_STATUS_HLCK) == 0) {
@@ -258,31 +262,34 @@ static int saa7191_wait_for_signal(struc
 	return -EBUSY;
 }
 
-static int saa7191_autodetect_norm_extended(struct i2c_client *client)
+static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
 {
-	u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
-	u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+	struct saa7191 *decoder = to_saa7191(sd);
+	u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+	u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
 	u8 status;
+	v4l2_std_id old_norm = decoder->norm;
 	int err = 0;
 
 	dprintk("SAA7191 extended signal auto-detection...\n");
 
+	*norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
 	stdc &= ~SAA7191_STDC_SECS;
 	ctl3 &= ~(SAA7191_CTL3_FSEL);
 
-	err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+	err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
 	if (err) {
 		err = -EIO;
 		goto out;
 	}
-	err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
 	if (err) {
 		err = -EIO;
 		goto out;
 	}
 
 	ctl3 |= SAA7191_CTL3_AUFD;
-	err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
 	if (err) {
 		err = -EIO;
 		goto out;
@@ -290,53 +297,54 @@ static int saa7191_autodetect_norm_exten
 
 	msleep(SAA7191_SYNC_DELAY);
 
-	err = saa7191_wait_for_signal(client, &status);
+	err = saa7191_wait_for_signal(sd, &status);
 	if (err)
 		goto out;
 
 	if (status & SAA7191_STATUS_FIDT) {
 		/* 60Hz signal -> NTSC */
 		dprintk("60Hz signal: NTSC\n");
-		return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+		*norm = V4L2_STD_NTSC;
+		return 0;
 	}
 
 	/* 50Hz signal */
 	dprintk("50Hz signal: Trying PAL...\n");
 
 	/* try PAL first */
-	err = saa7191_set_norm(client, SAA7191_NORM_PAL);
+	err = saa7191_s_std(sd, V4L2_STD_PAL);
 	if (err)
 		goto out;
 
 	msleep(SAA7191_SYNC_DELAY);
 
-	err = saa7191_wait_for_signal(client, &status);
+	err = saa7191_wait_for_signal(sd, &status);
 	if (err)
 		goto out;
 
 	/* not 50Hz ? */
 	if (status & SAA7191_STATUS_FIDT) {
 		dprintk("No 50Hz signal\n");
-		err = -EAGAIN;
-		goto out;
+		saa7191_s_std(sd, old_norm);
+		return -EAGAIN;
 	}
 
 	if (status & SAA7191_STATUS_CODE) {
 		dprintk("PAL\n");
-		return 0;
+		*norm = V4L2_STD_PAL;
+		return saa7191_s_std(sd, old_norm);
 	}
 
 	dprintk("No color detected with PAL - Trying SECAM...\n");
 
 	/* no color detected ? -> try SECAM */
-	err = saa7191_set_norm(client,
-			       SAA7191_NORM_SECAM);
+	err = saa7191_s_std(sd, V4L2_STD_SECAM);
 	if (err)
 		goto out;
 
 	msleep(SAA7191_SYNC_DELAY);
 
-	err = saa7191_wait_for_signal(client, &status);
+	err = saa7191_wait_for_signal(sd, &status);
 	if (err)
 		goto out;
 
@@ -350,32 +358,17 @@ static int saa7191_autodetect_norm_exten
 	if (status & SAA7191_STATUS_CODE) {
 		/* Color detected -> SECAM */
 		dprintk("SECAM\n");
-		return 0;
+		*norm = V4L2_STD_SECAM;
+		return saa7191_s_std(sd, old_norm);
 	}
 
 	dprintk("No color detected with SECAM - Going back to PAL.\n");
 
-	/* still no color detected ?
-	 * -> set norm back to PAL */
-	err = saa7191_set_norm(client,
-			       SAA7191_NORM_PAL);
-	if (err)
-		goto out;
-
 out:
-	ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
-	if (ctl3 & SAA7191_CTL3_AUFD) {
-		ctl3 &= ~(SAA7191_CTL3_AUFD);
-		err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
-		if (err) {
-			err = -EIO;
-		}
-	}
-
-	return err;
+	return saa7191_s_std(sd, old_norm);
 }
 
-static int saa7191_autodetect_norm(struct i2c_client *client)
+static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
 {
 	u8 status;
 
@@ -383,7 +376,7 @@ static int saa7191_autodetect_norm(struc
 
 	dprintk("Reading status...\n");
 
-	if (saa7191_read_status(client, &status))
+	if (saa7191_read_status(sd, &status))
 		return -EIO;
 
 	dprintk("Checking for signal...\n");
@@ -399,26 +392,25 @@ static int saa7191_autodetect_norm(struc
 	if (status & SAA7191_STATUS_FIDT) {
 		/* 60hz signal -> NTSC */
 		dprintk("NTSC\n");
-		return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+		return saa7191_s_std(sd, V4L2_STD_NTSC);
 	} else {
 		/* 50hz signal -> PAL */
 		dprintk("PAL\n");
-		return saa7191_set_norm(client, SAA7191_NORM_PAL);
+		return saa7191_s_std(sd, V4L2_STD_PAL);
 	}
 }
 
-static int saa7191_get_control(struct i2c_client *client,
-			       struct saa7191_control *ctrl)
+static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	u8 reg;
 	int ret = 0;
 
-	switch (ctrl->type) {
+	switch (ctrl->id) {
 	case SAA7191_CONTROL_BANDPASS:
 	case SAA7191_CONTROL_BANDPASS_WEIGHT:
 	case SAA7191_CONTROL_CORING:
-		reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
-		switch (ctrl->type) {
+		reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+		switch (ctrl->id) {
 		case SAA7191_CONTROL_BANDPASS:
 			ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
 				>> SAA7191_LUMA_BPSS_SHIFT;
@@ -435,15 +427,15 @@ static int saa7191_get_control(struct i2
 		break;
 	case SAA7191_CONTROL_FORCE_COLOUR:
 	case SAA7191_CONTROL_CHROMA_GAIN:
-		reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
-		if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
+		reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+		if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
 			ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
 		else
 			ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
 				>> SAA7191_GAIN_LFIS_SHIFT;
 		break;
-	case SAA7191_CONTROL_HUE:
-		reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
+	case V4L2_CID_HUE:
+		reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
 		if (reg < 0x80)
 			reg += 0x80;
 		else
@@ -451,18 +443,18 @@ static int saa7191_get_control(struct i2
 		ctrl->value = (s32)reg;
 		break;
 	case SAA7191_CONTROL_VTRC:
-		reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+		reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
 		ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
 		break;
 	case SAA7191_CONTROL_LUMA_DELAY:
-		reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+		reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
 		ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
 			>> SAA7191_CTL3_YDEL_SHIFT;
 		if (ctrl->value >= 4)
 			ctrl->value -= 8;
 		break;
 	case SAA7191_CONTROL_VNR:
-		reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+		reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
 		ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
 			>> SAA7191_CTL4_VNOI_SHIFT;
 		break;
@@ -473,18 +465,17 @@ static int saa7191_get_control(struct i2
 	return ret;
 }
 
-static int saa7191_set_control(struct i2c_client *client,
-			       struct saa7191_control *ctrl)
+static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	u8 reg;
 	int ret = 0;
 
-	switch (ctrl->type) {
+	switch (ctrl->id) {
 	case SAA7191_CONTROL_BANDPASS:
 	case SAA7191_CONTROL_BANDPASS_WEIGHT:
 	case SAA7191_CONTROL_CORING:
-		reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
-		switch (ctrl->type) {
+		reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+		switch (ctrl->id) {
 		case SAA7191_CONTROL_BANDPASS:
 			reg &= ~SAA7191_LUMA_BPSS_MASK;
 			reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
@@ -501,12 +492,12 @@ static int saa7191_set_control(struct i2
 				& SAA7191_LUMA_CORI_MASK;
 			break;
 		}
-		ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
 		break;
 	case SAA7191_CONTROL_FORCE_COLOUR:
 	case SAA7191_CONTROL_CHROMA_GAIN:
-		reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
-		if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
+		reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+		if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
 			if (ctrl->value)
 				reg |= SAA7191_GAIN_COLO;
 			else
@@ -516,41 +507,41 @@ static int saa7191_set_control(struct i2
 			reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
 				& SAA7191_GAIN_LFIS_MASK;
 		}
-		ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
 		break;
-	case SAA7191_CONTROL_HUE:
+	case V4L2_CID_HUE:
 		reg = ctrl->value & 0xff;
 		if (reg < 0x80)
 			reg += 0x80;
 		else
 			reg -= 0x80;
-		ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
 		break;
 	case SAA7191_CONTROL_VTRC:
-		reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+		reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
 		if (ctrl->value)
 			reg |= SAA7191_STDC_VTRC;
 		else
 			reg &= ~SAA7191_STDC_VTRC;
-		ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
 		break;
 	case SAA7191_CONTROL_LUMA_DELAY: {
 		s32 value = ctrl->value;
 		if (value < 0)
 			value += 8;
-		reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+		reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
 		reg &= ~SAA7191_CTL3_YDEL_MASK;
 		reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
 			& SAA7191_CTL3_YDEL_MASK;
-		ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
 		break;
 	}
 	case SAA7191_CONTROL_VNR:
-		reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+		reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
 		reg &= ~SAA7191_CTL4_VNOI_MASK;
 		reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
 			& SAA7191_CTL4_VNOI_MASK;
-		ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
+		ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
 		break;
 	default:
 		ret = -EINVAL;
@@ -561,247 +552,104 @@ static int saa7191_set_control(struct i2
 
 /* I2C-interface */
 
-static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
+static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
 {
-	int err = 0;
-	struct saa7191 *decoder;
-	struct i2c_client *client;
-
-	printk(KERN_INFO "Philips SAA7191 driver version %s\n",
-	       SAA7191_MODULE_VERSION);
-
-	client = kzalloc(sizeof(*client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
-	if (!decoder) {
-		err = -ENOMEM;
-		goto out_free_client;
-	}
-
-	client->addr = addr;
-	client->adapter = adap;
-	client->driver = &i2c_driver_saa7191;
-	client->flags = 0;
-	strcpy(client->name, "saa7191 client");
-	i2c_set_clientdata(client, decoder);
-
-	decoder->client = client;
-
-	err = i2c_attach_client(client);
-	if (err)
-		goto out_free_decoder;
-
-	err = saa7191_write_block(client, sizeof(initseq), initseq);
-	if (err) {
-		printk(KERN_ERR "SAA7191 initialization failed\n");
-		goto out_detach_client;
-	}
-
-	printk(KERN_INFO "SAA7191 initialized\n");
-
-	decoder->input = SAA7191_INPUT_COMPOSITE;
-	decoder->norm = SAA7191_NORM_PAL;
-
-	err = saa7191_autodetect_norm(client);
-	if (err && (err != -EBUSY)) {
-		printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
-	}
+	u8 status_reg;
+	int res = V4L2_IN_ST_NO_SIGNAL;
 
+	if (saa7191_read_status(sd, &status_reg))
+		return -EIO;
+	if ((status_reg & SAA7191_STATUS_HLCK) == 0)
+		res = 0;
+	if (!(status_reg & SAA7191_STATUS_CODE))
+		res |= V4L2_IN_ST_NO_COLOR;
+	*status = res;
 	return 0;
-
-out_detach_client:
-	i2c_detach_client(client);
-out_free_decoder:
-	kfree(decoder);
-out_free_client:
-	kfree(client);
-	return err;
 }
 
-static int saa7191_probe(struct i2c_adapter *adap)
-{
-	/* Always connected to VINO */
-	if (adap->id == I2C_HW_SGI_VINO)
-		return saa7191_attach(adap, SAA7191_ADDR, 0);
-	/* Feel free to add probe here :-) */
-	return -ENODEV;
-}
 
-static int saa7191_detach(struct i2c_client *client)
+static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
+		struct v4l2_dbg_chip_ident *chip)
 {
-	struct saa7191 *decoder = i2c_get_clientdata(client);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	i2c_detach_client(client);
-	kfree(decoder);
-	kfree(client);
-	return 0;
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
 }
 
-static int saa7191_command(struct i2c_client *client, unsigned int cmd,
-			   void *arg)
-{
-	struct saa7191 *decoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case DECODER_GET_CAPABILITIES: {
-		struct video_decoder_capability *cap = arg;
+/* ----------------------------------------------------------------------- */
 
-		cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
-			      VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
-		cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
-		cap->outputs = 1;
-		break;
-	}
-	case DECODER_GET_STATUS: {
-		int *iarg = arg;
-		u8 status;
-		int res = 0;
+static const struct v4l2_subdev_core_ops saa7191_core_ops = {
+	.g_chip_ident = saa7191_g_chip_ident,
+	.g_ctrl = saa7191_g_ctrl,
+	.s_ctrl = saa7191_s_ctrl,
+	.s_std = saa7191_s_std,
+};
 
-		if (saa7191_read_status(client, &status)) {
-			return -EIO;
-		}
-		if ((status & SAA7191_STATUS_HLCK) == 0)
-			res |= DECODER_STATUS_GOOD;
-		if (status & SAA7191_STATUS_CODE)
-			res |= DECODER_STATUS_COLOR;
-		switch (decoder->norm) {
-		case SAA7191_NORM_NTSC:
-			res |= DECODER_STATUS_NTSC;
-			break;
-		case SAA7191_NORM_PAL:
-			res |= DECODER_STATUS_PAL;
-			break;
-		case SAA7191_NORM_SECAM:
-			res |= DECODER_STATUS_SECAM;
-			break;
-		case SAA7191_NORM_AUTO:
-		default:
-			if (status & SAA7191_STATUS_FIDT)
-				res |= DECODER_STATUS_NTSC;
-			else
-				res |= DECODER_STATUS_PAL;
-			break;
-		}
-		*iarg = res;
-		break;
-	}
-	case DECODER_SET_NORM: {
-		int *iarg = arg;
+static const struct v4l2_subdev_video_ops saa7191_video_ops = {
+	.s_routing = saa7191_s_routing,
+	.querystd = saa7191_querystd,
+	.g_input_status = saa7191_g_input_status,
+};
 
-		switch (*iarg) {
-		case VIDEO_MODE_AUTO:
-			return saa7191_autodetect_norm(client);
-		case VIDEO_MODE_PAL:
-			return saa7191_set_norm(client, SAA7191_NORM_PAL);
-		case VIDEO_MODE_NTSC:
-			return saa7191_set_norm(client, SAA7191_NORM_NTSC);
-		case VIDEO_MODE_SECAM:
-			return saa7191_set_norm(client, SAA7191_NORM_SECAM);
-		default:
-			return -EINVAL;
-		}
-		break;
-	}
-	case DECODER_SET_INPUT:	{
-		int *iarg = arg;
+static const struct v4l2_subdev_ops saa7191_ops = {
+	.core = &saa7191_core_ops,
+	.video = &saa7191_video_ops,
+};
 
-		switch (client->adapter->id) {
-		case I2C_HW_SGI_VINO:
-			return saa7191_set_input(client, *iarg);
-		default:
-			if (*iarg != 0)
-				return -EINVAL;
-		}
-		break;
-	}
-	case DECODER_SET_OUTPUT: {
-		int *iarg = arg;
+static int saa7191_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	int err = 0;
+	struct saa7191 *decoder;
+	struct v4l2_subdev *sd;
 
-		/* not much choice of outputs */
-		if (*iarg != 0)
-			return -EINVAL;
-		break;
-	}
-	case DECODER_ENABLE_OUTPUT: {
-		/* Always enabled */
-		break;
-	}
-	case DECODER_SET_PICTURE: {
-		struct video_picture *pic = arg;
-		unsigned val;
-		int err;
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
-		val = (pic->hue >> 8) - 0x80;
+	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+	if (!decoder)
+		return -ENOMEM;
 
-		err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
-		if (err)
-			return -EIO;
+	sd = &decoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
 
-		break;
+	err = saa7191_write_block(sd, sizeof(initseq), initseq);
+	if (err) {
+		printk(KERN_ERR "SAA7191 initialization failed\n");
+		kfree(decoder);
+		return err;
 	}
-	case DECODER_SAA7191_GET_STATUS: {
-		struct saa7191_status *status = arg;
-		u8 status_reg;
-
-		if (saa7191_read_status(client, &status_reg))
-			return -EIO;
 
-		status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
-			? 1 : 0;
-		status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
-			? 1 : 0;
-		status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
-
-		status->input = decoder->input;
-		status->norm = decoder->norm;
+	printk(KERN_INFO "SAA7191 initialized\n");
 
-		break;
-	}
-	case DECODER_SAA7191_SET_NORM: {
-		int *norm = arg;
+	decoder->input = SAA7191_INPUT_COMPOSITE;
+	decoder->norm = V4L2_STD_PAL;
 
-		switch (*norm) {
-		case SAA7191_NORM_AUTO:
-			return saa7191_autodetect_norm(client);
-		case SAA7191_NORM_AUTO_EXT:
-			return saa7191_autodetect_norm_extended(client);
-		default:
-			return saa7191_set_norm(client, *norm);
-		}
-	}
-	case DECODER_SAA7191_GET_CONTROL: {
-		return saa7191_get_control(client, arg);
-	}
-	case DECODER_SAA7191_SET_CONTROL: {
-		return saa7191_set_control(client, arg);
-	}
-	default:
-		return -EINVAL;
-	}
+	err = saa7191_autodetect_norm(sd);
+	if (err && (err != -EBUSY))
+		printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
 
 	return 0;
 }
 
-static struct i2c_driver i2c_driver_saa7191 = {
-	.driver = {
-		.name 	= "saa7191",
-	},
-	.id		= I2C_DRIVERID_SAA7191,
-	.attach_adapter = saa7191_probe,
-	.detach_client	= saa7191_detach,
-	.command	= saa7191_command
-};
-
-static int saa7191_init(void)
+static int saa7191_remove(struct i2c_client *client)
 {
-	return i2c_add_driver(&i2c_driver_saa7191);
-}
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
-static void saa7191_exit(void)
-{
-	i2c_del_driver(&i2c_driver_saa7191);
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_saa7191(sd));
+	return 0;
 }
 
-module_init(saa7191_init);
-module_exit(saa7191_exit);
+static const struct i2c_device_id saa7191_id[] = {
+	{ "saa7191", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa7191_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa7191",
+	.probe = saa7191_probe,
+	.remove = saa7191_remove,
+	.id_table = saa7191_id,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/saa7191.h linux-libre-2.6.30-gnu1/drivers/media/video/saa7191.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/saa7191.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/saa7191.h	2009-06-09 23:05:27.000000000 -0400
@@ -176,11 +176,9 @@
 #define SAA7191_INPUT_COMPOSITE	0
 #define SAA7191_INPUT_SVIDEO	1
 
-#define SAA7191_NORM_AUTO	0
 #define SAA7191_NORM_PAL	1
 #define SAA7191_NORM_NTSC	2
 #define SAA7191_NORM_SECAM	3
-#define SAA7191_NORM_AUTO_EXT	4	/* extended auto-detection */
 
 struct saa7191_status {
 	/* 0=no signal, 1=signal detected */
@@ -232,24 +230,16 @@ struct saa7191_status {
 #define SAA7191_VNR_MAX			0x03
 #define SAA7191_VNR_DEFAULT		0x00
 
-#define SAA7191_CONTROL_BANDPASS	0
-#define SAA7191_CONTROL_BANDPASS_WEIGHT	1
-#define SAA7191_CONTROL_CORING		2
-#define SAA7191_CONTROL_FORCE_COLOUR	3	/* boolean */
-#define SAA7191_CONTROL_CHROMA_GAIN	4
-#define SAA7191_CONTROL_HUE		5
-#define SAA7191_CONTROL_VTRC		6	/* boolean */
-#define SAA7191_CONTROL_LUMA_DELAY	7
-#define SAA7191_CONTROL_VNR		8
-
-struct saa7191_control {
-	u8 type;
-	s32 value;
-};
+#define SAA7191_CONTROL_BANDPASS	(V4L2_CID_PRIVATE_BASE + 0)
+#define SAA7191_CONTROL_BANDPASS_WEIGHT	(V4L2_CID_PRIVATE_BASE + 1)
+#define SAA7191_CONTROL_CORING		(V4L2_CID_PRIVATE_BASE + 2)
+#define SAA7191_CONTROL_FORCE_COLOUR	(V4L2_CID_PRIVATE_BASE + 3)
+#define SAA7191_CONTROL_CHROMA_GAIN	(V4L2_CID_PRIVATE_BASE + 4)
+#define SAA7191_CONTROL_VTRC		(V4L2_CID_PRIVATE_BASE + 5)
+#define SAA7191_CONTROL_LUMA_DELAY	(V4L2_CID_PRIVATE_BASE + 6)
+#define SAA7191_CONTROL_VNR		(V4L2_CID_PRIVATE_BASE + 7)
 
 #define	DECODER_SAA7191_GET_STATUS	_IOR('d', 195, struct saa7191_status)
 #define	DECODER_SAA7191_SET_NORM	_IOW('d', 196, int)
-#define	DECODER_SAA7191_GET_CONTROL	_IOR('d', 197, struct saa7191_control)
-#define	DECODER_SAA7191_SET_CONTROL	_IOW('d', 198, struct saa7191_control)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/sh_mobile_ceu_camera.c linux-libre-2.6.30-gnu1/drivers/media/video/sh_mobile_ceu_camera.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/sh_mobile_ceu_camera.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,13 +94,37 @@ struct sh_mobile_ceu_dev {
 	spinlock_t lock;
 	struct list_head capture;
 	struct videobuf_buffer *active;
-	int is_interlace;
+	int is_interlaced;
 
 	struct sh_mobile_ceu_info *pdata;
 
 	const struct soc_camera_data_format *camera_fmt;
 };
 
+static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
+{
+	unsigned long flags;
+
+	flags = SOCAM_MASTER |
+		SOCAM_PCLK_SAMPLE_RISING |
+		SOCAM_HSYNC_ACTIVE_HIGH |
+		SOCAM_HSYNC_ACTIVE_LOW |
+		SOCAM_VSYNC_ACTIVE_HIGH |
+		SOCAM_VSYNC_ACTIVE_LOW |
+		SOCAM_DATA_ACTIVE_HIGH;
+
+	if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
+		flags |= SOCAM_DATAWIDTH_8;
+
+	if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
+		flags |= SOCAM_DATAWIDTH_16;
+
+	if (flags & SOCAM_DATAWIDTH_MASK)
+		return flags;
+
+	return 0;
+}
+
 static void ceu_write(struct sh_mobile_ceu_dev *priv,
 		      unsigned long reg_offs, u32 data)
 {
@@ -150,6 +174,7 @@ static void free_buffer(struct videobuf_
 	if (in_interrupt())
 		BUG();
 
+	videobuf_waiton(&buf->vb, 0, 0);
 	videobuf_dma_contig_free(vq, &buf->vb);
 	dev_dbg(&icd->dev, "%s freed\n", __func__);
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
@@ -181,7 +206,7 @@ static void sh_mobile_ceu_capture(struct
 
 	phys_addr_top = videobuf_to_dma_contig(pcdev->active);
 	ceu_write(pcdev, CDAYR, phys_addr_top);
-	if (pcdev->is_interlace) {
+	if (pcdev->is_interlaced) {
 		phys_addr_bottom = phys_addr_top + icd->width;
 		ceu_write(pcdev, CDBYR, phys_addr_bottom);
 	}
@@ -193,7 +218,7 @@ static void sh_mobile_ceu_capture(struct
 	case V4L2_PIX_FMT_NV61:
 		phys_addr_top += icd->width * icd->height;
 		ceu_write(pcdev, CDACR, phys_addr_top);
-		if (pcdev->is_interlace) {
+		if (pcdev->is_interlaced) {
 			phys_addr_bottom = phys_addr_top + icd->width;
 			ceu_write(pcdev, CDBCR, phys_addr_bottom);
 		}
@@ -396,7 +421,7 @@ static int sh_mobile_ceu_set_bus_param(s
 
 	camera_flags = icd->ops->query_bus_param(icd);
 	common_flags = soc_camera_bus_param_compatible(camera_flags,
-						       pcdev->pdata->flags);
+						       make_bus_param(pcdev));
 	if (!common_flags)
 		return -EINVAL;
 
@@ -457,7 +482,7 @@ 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_interlace) ? 0x101 : 0);
+	ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
 
 	mdelay(1);
 
@@ -473,7 +498,7 @@ static int sh_mobile_ceu_set_bus_param(s
 	}
 
 	height = icd->height;
-	if (pcdev->is_interlace) {
+	if (pcdev->is_interlaced) {
 		height /= 2;
 		cdwdr_width *= 2;
 	}
@@ -517,7 +542,7 @@ 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,
-						       pcdev->pdata->flags);
+						       make_bus_param(pcdev));
 	if (!common_flags)
 		return -EINVAL;
 
@@ -562,11 +587,29 @@ static int sh_mobile_ceu_get_formats(str
 	if (ret < 0)
 		return 0;
 
+	/* Beginning of a pass */
+	if (!idx)
+		icd->host_priv = 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:
+		if (icd->host_priv)
+			goto add_single_format;
+
+		/*
+		 * Our case is simple so far: for any of the above four camera
+		 * formats we add all our four synthesized NV* formats, so,
+		 * just marking the device with a single flag suffices. If
+		 * the format generation rules are more complex, you would have
+		 * to actually hang your already added / counted formats onto
+		 * the host_priv pointer and check whether the format you're
+		 * going to add now is already there.
+		 */
+		icd->host_priv = (void *)sh_mobile_ceu_formats;
+
 		n = ARRAY_SIZE(sh_mobile_ceu_formats);
 		formats += n;
 		for (k = 0; xlate && k < n; k++) {
@@ -579,6 +622,7 @@ static int sh_mobile_ceu_get_formats(str
 				icd->formats[idx].name);
 		}
 	default:
+add_single_format:
 		/* Generic pass-through */
 		formats++;
 		if (xlate) {
@@ -595,24 +639,30 @@ static int sh_mobile_ceu_get_formats(str
 	return formats;
 }
 
+static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
+				  struct v4l2_rect *rect)
+{
+	return icd->ops->set_crop(icd, rect);
+}
+
 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
-				 __u32 pixfmt, struct v4l2_rect *rect)
+				 struct v4l2_format *f)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	__u32 pixfmt = f->fmt.pix.pixelformat;
 	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_format cam_f = *f;
 	int ret;
 
-	if (!pixfmt)
-		return icd->ops->set_fmt(icd, pixfmt, rect);
-
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
 		dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
-	ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
+	cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
+	ret = icd->ops->set_fmt(icd, &cam_f);
 
 	if (!ret) {
 		icd->buswidth = xlate->buswidth;
@@ -662,13 +712,13 @@ static int sh_mobile_ceu_try_fmt(struct
 
 	switch (f->fmt.pix.field) {
 	case V4L2_FIELD_INTERLACED:
-		pcdev->is_interlace = 1;
+		pcdev->is_interlaced = 1;
 		break;
 	case V4L2_FIELD_ANY:
 		f->fmt.pix.field = V4L2_FIELD_NONE;
 		/* fall-through */
 	case V4L2_FIELD_NONE:
-		pcdev->is_interlace = 0;
+		pcdev->is_interlaced = 0;
 		break;
 	default:
 		ret = -EINVAL;
@@ -734,7 +784,8 @@ static void sh_mobile_ceu_init_videobuf(
 				       &sh_mobile_ceu_videobuf_ops,
 				       &ici->dev, &pcdev->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
-				       V4L2_FIELD_ANY,
+				       pcdev->is_interlaced ?
+				       V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
 				       sizeof(struct sh_mobile_ceu_buffer),
 				       icd);
 }
@@ -744,6 +795,7 @@ static struct soc_camera_host_ops sh_mob
 	.add		= sh_mobile_ceu_add_device,
 	.remove		= sh_mobile_ceu_remove_device,
 	.get_formats	= sh_mobile_ceu_get_formats,
+	.set_crop	= sh_mobile_ceu_set_crop,
 	.set_fmt	= sh_mobile_ceu_set_fmt,
 	.try_fmt	= sh_mobile_ceu_try_fmt,
 	.reqbufs	= sh_mobile_ceu_reqbufs,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h linux-libre-2.6.30-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/sn9c102/sn9c102_devtable.h	2009-06-09 23:05:27.000000000 -0400
@@ -96,9 +96,7 @@ static const struct usb_device_id sn9c10
 #if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
 	{ SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
-#endif
 	{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
-#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
 #endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -123,7 +121,9 @@ static const struct usb_device_id sn9c10
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
 #endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
+#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
 	{ }
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/soc_camera.c linux-libre-2.6.30-gnu1/drivers/media/video/soc_camera.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/soc_camera.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/soc_camera.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,10 @@
 #include <media/videobuf-core.h>
 #include <media/soc_camera.h>
 
+/* Default to VGA resolution */
+#define DEFAULT_WIDTH	640
+#define DEFAULT_HEIGHT	480
+
 static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
 static DEFINE_MUTEX(list_lock);
@@ -256,6 +260,46 @@ static void soc_camera_free_user_formats
 	vfree(icd->user_formats);
 }
 
+/* Called with .vb_lock held */
+static int soc_camera_set_fmt(struct soc_camera_file *icf,
+			      struct v4l2_format *f)
+{
+	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	int ret;
+
+	/* We always call try_fmt() before set_fmt() or set_crop() */
+	ret = ici->ops->try_fmt(icd, f);
+	if (ret < 0)
+		return ret;
+
+	ret = ici->ops->set_fmt(icd, f);
+	if (ret < 0) {
+		return ret;
+	} else if (!icd->current_fmt ||
+		   icd->current_fmt->fourcc != pix->pixelformat) {
+		dev_err(&ici->dev,
+			"Host driver hasn't set up current format correctly!\n");
+		return -EINVAL;
+	}
+
+	icd->width		= pix->width;
+	icd->height		= pix->height;
+	icf->vb_vidq.field	=
+		icd->field	= pix->field;
+
+	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
+			 f->type);
+
+	dev_dbg(&icd->dev, "set width: %d height: %d\n",
+		icd->width, icd->height);
+
+	/* set physical bus parameters */
+	return ici->ops->set_bus_param(icd, pix->pixelformat);
+}
+
 static int soc_camera_open(struct file *file)
 {
 	struct video_device *vdev;
@@ -297,14 +341,28 @@ static int soc_camera_open(struct file *
 
 	/* Now we really have to activate the camera */
 	if (icd->use_count == 1) {
-		ret = soc_camera_init_user_formats(icd);
-		if (ret < 0)
-			goto eiufmt;
+		/* Restore parameters before the last close() per V4L2 API */
+		struct v4l2_format f = {
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.fmt.pix = {
+				.width		= icd->width,
+				.height		= icd->height,
+				.field		= icd->field,
+				.pixelformat	= icd->current_fmt->fourcc,
+				.colorspace	= icd->current_fmt->colorspace,
+			},
+		};
+
 		ret = ici->ops->add(icd);
 		if (ret < 0) {
 			dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
 			goto eiciadd;
 		}
+
+		/* Try to configure with default parameters */
+		ret = soc_camera_set_fmt(icf, &f);
+		if (ret < 0)
+			goto esfmt;
 	}
 
 	mutex_unlock(&icd->video_lock);
@@ -316,10 +374,13 @@ static int soc_camera_open(struct file *
 
 	return 0;
 
-	/* First two errors are entered with the .video_lock held */
+	/*
+	 * First three errors are entered with the .video_lock held
+	 * and use_count == 1
+	 */
+esfmt:
+	ici->ops->remove(icd);
 eiciadd:
-	soc_camera_free_user_formats(icd);
-eiufmt:
 	icd->use_count--;
 	mutex_unlock(&icd->video_lock);
 	module_put(ici->ops->owner);
@@ -339,10 +400,9 @@ static int soc_camera_close(struct file
 
 	mutex_lock(&icd->video_lock);
 	icd->use_count--;
-	if (!icd->use_count) {
+	if (!icd->use_count)
 		ici->ops->remove(icd);
-		soc_camera_free_user_formats(icd);
-	}
+
 	mutex_unlock(&icd->video_lock);
 
 	module_put(icd->ops->owner);
@@ -415,18 +475,10 @@ static int soc_camera_s_fmt_vid_cap(stru
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	__u32 pixfmt = pix->pixelformat;
 	int ret;
-	struct v4l2_rect rect;
 
 	WARN_ON(priv != file->private_data);
 
-	ret = soc_camera_try_fmt_vid_cap(file, priv, f);
-	if (ret < 0)
-		return ret;
-
 	mutex_lock(&icf->vb_vidq.vb_lock);
 
 	if (videobuf_queue_is_busy(&icf->vb_vidq)) {
@@ -435,33 +487,7 @@ static int soc_camera_s_fmt_vid_cap(stru
 		goto unlock;
 	}
 
-	rect.left	= icd->x_current;
-	rect.top	= icd->y_current;
-	rect.width	= pix->width;
-	rect.height	= pix->height;
-	ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect);
-	if (ret < 0) {
-		goto unlock;
-	} else if (!icd->current_fmt ||
-		   icd->current_fmt->fourcc != pixfmt) {
-		dev_err(&ici->dev,
-			"Host driver hasn't set up current format correctly!\n");
-		ret = -EINVAL;
-		goto unlock;
-	}
-
-	icd->width		= rect.width;
-	icd->height		= rect.height;
-	icf->vb_vidq.field	= pix->field;
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
-			 f->type);
-
-	dev_dbg(&icd->dev, "set width: %d height: %d\n",
-		icd->width, icd->height);
-
-	/* set physical bus parameters */
-	ret = ici->ops->set_bus_param(icd, pixfmt);
+	ret = soc_camera_set_fmt(icf, f);
 
 unlock:
 	mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -648,8 +674,8 @@ static int soc_camera_cropcap(struct fil
 	a->bounds.height		= icd->height_max;
 	a->defrect.left			= icd->x_min;
 	a->defrect.top			= icd->y_min;
-	a->defrect.width		= 640;
-	a->defrect.height		= 480;
+	a->defrect.width		= DEFAULT_WIDTH;
+	a->defrect.height		= DEFAULT_HEIGHT;
 	a->pixelaspect.numerator	= 1;
 	a->pixelaspect.denominator	= 1;
 
@@ -685,7 +711,7 @@ static int soc_camera_s_crop(struct file
 	/* Cropping is allowed during a running capture, guard consistency */
 	mutex_lock(&icf->vb_vidq.vb_lock);
 
-	ret = ici->ops->set_fmt(icd, 0, &a->c);
+	ret = ici->ops->set_crop(icd, &a->c);
 	if (!ret) {
 		icd->width	= a->c.width;
 		icd->height	= a->c.height;
@@ -738,7 +764,10 @@ static int soc_camera_s_register(struct
 
 static int device_register_link(struct soc_camera_device *icd)
 {
-	int ret = device_register(&icd->dev);
+	int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
+
+	if (!ret)
+		ret = device_register(&icd->dev);
 
 	if (ret < 0) {
 		/* Prevent calling device_unregister() */
@@ -844,9 +873,18 @@ static int soc_camera_probe(struct devic
 		qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
 		icd->exposure = qctrl ? qctrl->default_value :
 			(unsigned short)~0;
+
+		ret = soc_camera_init_user_formats(icd);
+		if (ret < 0)
+			goto eiufmt;
+
+		icd->height	= DEFAULT_HEIGHT;
+		icd->width	= DEFAULT_WIDTH;
+		icd->field	= V4L2_FIELD_ANY;
 	}
-	ici->ops->remove(icd);
 
+eiufmt:
+	ici->ops->remove(icd);
 eiadd:
 	mutex_unlock(&icd->video_lock);
 	module_put(ici->ops->owner);
@@ -865,6 +903,8 @@ static int soc_camera_remove(struct devi
 	if (icd->ops->remove)
 		icd->ops->remove(icd);
 
+	soc_camera_free_user_formats(icd);
+
 	return 0;
 }
 
@@ -918,6 +958,7 @@ int soc_camera_host_register(struct soc_
 	if (!ici || !ici->ops ||
 	    !ici->ops->try_fmt ||
 	    !ici->ops->set_fmt ||
+	    !ici->ops->set_crop ||
 	    !ici->ops->set_bus_param ||
 	    !ici->ops->querycap ||
 	    !ici->ops->init_videobuf ||
@@ -998,6 +1039,7 @@ int soc_camera_device_register(struct so
 	    !icd->ops->release ||
 	    !icd->ops->start_capture ||
 	    !icd->ops->stop_capture ||
+	    !icd->ops->set_crop ||
 	    !icd->ops->set_fmt ||
 	    !icd->ops->try_fmt ||
 	    !icd->ops->query_bus_param ||
@@ -1021,7 +1063,6 @@ int soc_camera_device_register(struct so
 
 	icd->devnum = num;
 	icd->dev.bus = &soc_camera_bus_type;
-	dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
 
 	icd->dev.release	= dummy_release;
 	icd->use_count		= 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/soc_camera_platform.c linux-libre-2.6.30-gnu1/drivers/media/video/soc_camera_platform.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/soc_camera_platform.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/soc_camera_platform.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,8 +79,14 @@ soc_camera_platform_query_bus_param(stru
 	return p->bus_param;
 }
 
+static int soc_camera_platform_set_crop(struct soc_camera_device *icd,
+					struct v4l2_rect *rect)
+{
+	return 0;
+}
+
 static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
-				       __u32 pixfmt, struct v4l2_rect *rect)
+				       struct v4l2_format *f)
 {
 	return 0;
 }
@@ -125,6 +131,7 @@ static struct soc_camera_ops soc_camera_
 	.release		= soc_camera_platform_release,
 	.start_capture		= soc_camera_platform_start_capture,
 	.stop_capture		= soc_camera_platform_stop_capture,
+	.set_crop		= soc_camera_platform_set_crop,
 	.set_fmt		= soc_camera_platform_set_fmt,
 	.try_fmt		= soc_camera_platform_try_fmt,
 	.set_bus_param		= soc_camera_platform_set_bus_param,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/stk-webcam.c linux-libre-2.6.30-gnu1/drivers/media/video/stk-webcam.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/stk-webcam.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/stk-webcam.c	2009-06-09 23:05:27.000000000 -0400
@@ -933,8 +933,6 @@ static int stk_vidioc_s_ctrl(struct file
 static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
 		void *priv, struct v4l2_fmtdesc *fmtd)
 {
-	fmtd->flags = 0;
-
 	switch (fmtd->index) {
 	case 0:
 		fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
@@ -992,7 +990,6 @@ static int stk_vidioc_g_fmt_vid_cap(stru
 	pix_format->height = stk_sizes[i].h;
 	pix_format->field = V4L2_FIELD_NONE;
 	pix_format->colorspace = V4L2_COLORSPACE_SRGB;
-	pix_format->priv = 0;
 	pix_format->pixelformat = dev->vsettings.palette;
 	if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
 		pix_format->bytesperline = pix_format->width;
@@ -1115,8 +1112,6 @@ static int stk_vidioc_reqbufs(struct fil
 
 	if (dev == NULL)
 		return -ENODEV;
-	if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 	if (rb->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 	if (is_streaming(dev)
@@ -1139,16 +1134,10 @@ static int stk_vidioc_reqbufs(struct fil
 static int stk_vidioc_querybuf(struct file *filp,
 		void *priv, struct v4l2_buffer *buf)
 {
-	int index;
 	struct stk_camera *dev = priv;
 	struct stk_sio_buffer *sbuf;
 
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	index = buf->index;
-
-	if (index < 0 || index >= dev->n_sbufs)
+	if (buf->index < 0 || buf->index >= dev->n_sbufs)
 		return -EINVAL;
 	sbuf = dev->sio_bufs + buf->index;
 	*buf = sbuf->v4lbuf;
@@ -1161,8 +1150,6 @@ static int stk_vidioc_qbuf(struct file *
 	struct stk_camera *dev = priv;
 	struct stk_sio_buffer *sbuf;
 	unsigned long flags;
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
@@ -1189,8 +1176,7 @@ static int stk_vidioc_dqbuf(struct file
 	unsigned long flags;
 	int ret;
 
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
-		|| !is_streaming(dev))
+	if (!is_streaming(dev))
 		return -EINVAL;
 
 	if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
@@ -1249,16 +1235,10 @@ static int stk_vidioc_streamoff(struct f
 static int stk_vidioc_g_parm(struct file *filp,
 		void *priv, struct v4l2_streamparm *sp)
 {
-	if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	sp->parm.capture.capability = 0;
-	sp->parm.capture.capturemode = 0;
 	/*FIXME This is not correct */
 	sp->parm.capture.timeperframe.numerator = 1;
 	sp->parm.capture.timeperframe.denominator = 30;
 	sp->parm.capture.readbuffers = 2;
-	sp->parm.capture.extendedmode = 0;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tcm825x.c linux-libre-2.6.30-gnu1/drivers/media/video/tcm825x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tcm825x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tcm825x.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ struct tcm825x_sensor {
 };
 
 /* list of image formats supported by TCM825X sensor */
-const static struct v4l2_fmtdesc tcm825x_formats[] = {
+static const struct v4l2_fmtdesc tcm825x_formats[] = {
 	{
 		.description = "YUYV (YUV 4:2:2), packed",
 		.pixelformat = V4L2_PIX_FMT_UYVY,
@@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x
  * TCM825X register configuration for all combinations of pixel format and
  * image size
  */
-const static struct tcm825x_reg subqcif	=	{ 0x20, TCM825X_PICSIZ };
-const static struct tcm825x_reg qcif	=	{ 0x18, TCM825X_PICSIZ };
-const static struct tcm825x_reg cif	=	{ 0x14, TCM825X_PICSIZ };
-const static struct tcm825x_reg qqvga	=	{ 0x0c, TCM825X_PICSIZ };
-const static struct tcm825x_reg qvga	=	{ 0x04, TCM825X_PICSIZ };
-const static struct tcm825x_reg vga	=	{ 0x00, TCM825X_PICSIZ };
+static const struct tcm825x_reg subqcif	=	{ 0x20, TCM825X_PICSIZ };
+static const struct tcm825x_reg qcif	=	{ 0x18, TCM825X_PICSIZ };
+static const struct tcm825x_reg cif	=	{ 0x14, TCM825X_PICSIZ };
+static const struct tcm825x_reg qqvga	=	{ 0x0c, TCM825X_PICSIZ };
+static const struct tcm825x_reg qvga	=	{ 0x04, TCM825X_PICSIZ };
+static const struct tcm825x_reg vga	=	{ 0x00, TCM825X_PICSIZ };
 
-const static struct tcm825x_reg yuv422	=	{ 0x00, TCM825X_PICFMT };
-const static struct tcm825x_reg rgb565	=	{ 0x02, TCM825X_PICFMT };
+static const struct tcm825x_reg yuv422	=	{ 0x00, TCM825X_PICFMT };
+static const struct tcm825x_reg rgb565	=	{ 0x02, TCM825X_PICFMT };
 
 /* Our own specific controls */
 #define V4L2_CID_ALC				V4L2_CID_PRIVATE_BASE
@@ -248,10 +248,10 @@ static struct vcontrol {
 };
 
 
-const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
+static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
 { &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
 
-const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
+static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
 { &yuv422, &rgb565 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tcm825x.h linux-libre-2.6.30-gnu1/drivers/media/video/tcm825x.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/tcm825x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tcm825x.h	2009-06-09 23:05:27.000000000 -0400
@@ -188,7 +188,7 @@ struct tcm825x_platform_data {
 /* Array of image sizes supported by TCM825X.  These must be ordered from
  * smallest image size to largest.
  */
-const static struct capture_size tcm825x_sizes[] = {
+static const struct capture_size tcm825x_sizes[] = {
 	{ 128,  96 }, /* subQCIF */
 	{ 160, 120 }, /* QQVGA */
 	{ 176, 144 }, /* QCIF */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tda7432.c linux-libre-2.6.30-gnu1/drivers/media/video/tda7432.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tda7432.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tda7432.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/i2c-addr.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 #ifndef VIDEO_AUDIO_BALANCE
 # define VIDEO_AUDIO_BALANCE 32
@@ -69,13 +69,6 @@ MODULE_PARM_DESC(maxvol,"Set maximium vo
 module_param(maxvol, int, S_IRUGO | S_IWUSR);
 
 
-/* Address to scan (I2C address of this chip) */
-static unsigned short normal_i2c[] = {
-	I2C_ADDR_TDA7432 >> 1,
-	I2C_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
 
 /* Structure of address and subaddresses for the tda7432 */
 
@@ -421,21 +414,18 @@ static int tda7432_s_ctrl(struct v4l2_su
 static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
 {
 	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
 	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		return v4l2_ctrl_query_fill_std(qc);
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 	}
 	return -EINVAL;
 }
 
-static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tda7432_core_ops = {
@@ -498,8 +488,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tda7432",
-	.driverid = I2C_DRIVERID_TDA7432,
-	.command = tda7432_command,
 	.probe = tda7432_probe,
 	.remove = tda7432_remove,
 	.id_table = tda7432_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tda9840.c linux-libre-2.6.30-gnu1/drivers/media/video/tda9840.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tda9840.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tda9840.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,8 +30,8 @@
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include "tda9840.h"
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 MODULE_DESCRIPTION("tda9840 driver");
@@ -56,11 +56,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 #define TDA9840_SET_BOTH_R              0x16
 #define TDA9840_SET_EXTERNAL            0x7a
 
-/* addresses to scan, found only at 0x42 (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
 
 static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
 {
@@ -137,60 +132,17 @@ static int tda9840_g_tuner(struct v4l2_s
 	return 0;
 }
 
-static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
-	int byte;
-
-	switch (cmd) {
-	case TDA9840_LEVEL_ADJUST:
-		byte = *(int *)arg;
-		v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
-
-		/* check for correct range */
-		if (byte > 25 || byte < -20)
-			return -EINVAL;
-
-		/* calculate actual value to set, see specs, page 18 */
-		byte /= 5;
-		if (0 < byte)
-			byte += 0x8;
-		else
-			byte = -byte;
-		tda9840_write(sd, LEVEL_ADJUST, byte);
-		break;
-
-	case TDA9840_STEREO_ADJUST:
-		byte = *(int *)arg;
-		v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
-
-		/* check for correct range */
-		if (byte > 25 || byte < -24)
-			return -EINVAL;
-
-		/* calculate actual value to set */
-		byte /= 5;
-		if (0 < byte)
-			byte += 0x20;
-		else
-			byte = -byte;
-
-		tda9840_write(sd, STEREO_ADJUST, byte);
-		break;
-	default:
-		return -ENOIOCTLCMD;
-	}
-	return 0;
-}
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
 }
 
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tda9840_core_ops = {
-	.ioctl = tda9840_ioctl,
+	.g_chip_ident = tda9840_g_chip_ident,
 };
 
 static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
@@ -209,8 +161,6 @@ static int tda9840_probe(struct i2c_clie
 			  const struct i2c_device_id *id)
 {
 	struct v4l2_subdev *sd;
-	int result;
-	int byte;
 
 	/* let's see whether this adapter can support what we need */
 	if (!i2c_check_functionality(client->adapter,
@@ -227,15 +177,9 @@ static int tda9840_probe(struct i2c_clie
 	v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
 
 	/* set initial values for level & stereo - adjustment, mode */
-	byte = 0;
-	result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
-	result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
+	tda9840_write(sd, LEVEL_ADJUST, 0);
+	tda9840_write(sd, STEREO_ADJUST, 0);
 	tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
-	if (result) {
-		v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
-		kfree(sd);
-		return -ENODEV;
-	}
 	return 0;
 }
 
@@ -248,12 +192,6 @@ static int tda9840_remove(struct i2c_cli
 	return 0;
 }
 
-static int tda9840_legacy_probe(struct i2c_adapter *adapter)
-{
-	/* Let's see whether this is a known adapter we can attach to.
-	   Prevents conflicts with tvaudio.c. */
-	return adapter->id == I2C_HW_SAA7146;
-}
 static const struct i2c_device_id tda9840_id[] = {
 	{ "tda9840", 0 },
 	{ }
@@ -262,10 +200,7 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tda9840",
-	.driverid = I2C_DRIVERID_TDA9840,
-	.command = tda9840_command,
 	.probe = tda9840_probe,
 	.remove = tda9840_remove,
-	.legacy_probe = tda9840_legacy_probe,
 	.id_table = tda9840_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tda9840.h linux-libre-2.6.30-gnu1/drivers/media/video/tda9840.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/tda9840.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tda9840.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef __INCLUDED_TDA9840__
-#define __INCLUDED_TDA9840__
-
-#define	I2C_ADDR_TDA9840		0x42
-
-/* values may range between +2.5 and -2.0;
-   the value has to be multiplied with 10 */
-#define TDA9840_LEVEL_ADJUST	_IOW('v',3,int)
-
-/* values may range between +2.5 and -2.4;
-   the value has to be multiplied with 10 */
-#define TDA9840_STEREO_ADJUST	_IOW('v',4,int)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tda9875.c linux-libre-2.6.30-gnu1/drivers/media/video/tda9875.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tda9875.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tda9875.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,20 +28,13 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <media/i2c-addr.h>
 
 static int debug; /* insmod parameter */
 module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_LICENSE("GPL");
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] =  {
-    I2C_ADDR_TDA9875 >> 1,
-    I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
 
 /* This is a superset of the TDA9875 */
 struct tda9875 {
@@ -313,18 +306,14 @@ static int tda9875_queryctrl(struct v4l2
 {
 	switch (qc->id) {
 	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		return v4l2_ctrl_query_fill_std(qc);
+		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 	}
 	return -EINVAL;
 }
 
-static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tda9875_core_ops = {
@@ -401,8 +390,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tda9875",
-	.driverid = I2C_DRIVERID_TDA9875,
-	.command = tda9875_command,
 	.probe = tda9875_probe,
 	.remove = tda9875_remove,
 	.id_table = tda9875_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tea6415c.c linux-libre-2.6.30-gnu1/drivers/media/video/tea6415c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tea6415c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tea6415c.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,8 @@
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 #include "tea6415c.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,25 +45,21 @@ module_param(debug, int, 0644);
 
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
-static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
 
-/* makes a connection between the input-pin 'i' and the output-pin 'o'
-   for the tea6415c-client 'client' */
-static int switch_matrix(struct i2c_client *client, int i, int o)
+/* makes a connection between the input-pin 'i' and the output-pin 'o' */
+static int tea6415c_s_routing(struct v4l2_subdev *sd,
+			      u32 i, u32 o, u32 config)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u8 byte = 0;
 	int ret;
 
-	v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o);
+	v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
 
 	/* check if the pins are valid */
 	if (0 == ((1 == i ||  3 == i ||  5 == i ||  6 == i ||  8 == i || 10 == i || 20 == i || 11 == i)
 	      && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
-		return -1;
+		return -EINVAL;
 
 	/* to understand this, have a look at the tea6415c-specs (p.5) */
 	switch (o) {
@@ -115,37 +112,33 @@ static int switch_matrix(struct i2c_clie
 
 	ret = i2c_smbus_write_byte(client, byte);
 	if (ret) {
-		v4l_dbg(1, debug, client,
+		v4l2_dbg(1, debug, sd,
 			"i2c_smbus_write_byte() failed, ret:%d\n", ret);
 		return -EIO;
 	}
 	return ret;
 }
 
-static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
-	if (cmd == TEA6415C_SWITCH) {
-		struct i2c_client *client = v4l2_get_subdevdata(sd);
-		struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
-
-		return switch_matrix(client, v->in, v->out);
-	}
-	return -ENOIOCTLCMD;
-}
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
 }
 
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
-	.ioctl = tea6415c_ioctl,
+	.g_chip_ident = tea6415c_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
+	.s_routing = tea6415c_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6415c_ops = {
 	.core = &tea6415c_core_ops,
+	.video = &tea6415c_video_ops,
 };
 
 /* this function is called by i2c_probe */
@@ -176,13 +169,6 @@ static int tea6415c_remove(struct i2c_cl
 	return 0;
 }
 
-static int tea6415c_legacy_probe(struct i2c_adapter *adapter)
-{
-	/* Let's see whether this is a known adapter we can attach to.
-	   Prevents conflicts with tvaudio.c. */
-	return adapter->id == I2C_HW_SAA7146;
-}
-
 static const struct i2c_device_id tea6415c_id[] = {
 	{ "tea6415c", 0 },
 	{ }
@@ -191,10 +177,7 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tea6415c",
-	.driverid = I2C_DRIVERID_TEA6415C,
-	.command = tea6415c_command,
 	.probe = tea6415c_probe,
 	.remove = tea6415c_remove,
-	.legacy_probe = tea6415c_legacy_probe,
 	.id_table = tea6415c_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tea6415c.h linux-libre-2.6.30-gnu1/drivers/media/video/tea6415c.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/tea6415c.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tea6415c.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,6 @@
 #ifndef __INCLUDED_TEA6415C__
 #define __INCLUDED_TEA6415C__
 
-/* possible i2c-addresses */
-#define	I2C_TEA6415C_1		0x03
-#define	I2C_TEA6415C_2		0x43
-
 /* the tea6415c's design is quite brain-dead. although there are
    8 inputs and 6 outputs, these aren't enumerated in any way. because
    I don't want to say "connect input pin 20 to output pin 17", I define
@@ -28,12 +24,4 @@
 #define TEA6415C_INPUT7 1
 #define TEA6415C_INPUT8 11
 
-struct tea6415c_multiplex
-{
-	int	in;	/* input-pin */
-	int	out;	/* output-pin */
-};
-
-#define TEA6415C_SWITCH		_IOW('v',1,struct tea6415c_multiplex)
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tea6420.c linux-libre-2.6.30-gnu1/drivers/media/video/tea6420.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tea6420.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tea6420.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,7 +32,8 @@
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 #include "tea6420.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,24 +45,23 @@ module_param(debug, int, 0644);
 
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
 
 /* make a connection between the input 'i' and the output 'o'
-   with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
-static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
+   with gain 'g' (note: i = 6 means 'mute') */
+static int tea6420_s_routing(struct v4l2_subdev *sd,
+			     u32 i, u32 o, u32 config)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int g = (o >> 4) & 0xf;
 	u8 byte;
 	int ret;
 
-	v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g);
+	o &= 0xf;
+	v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
 
 	/* check if the parameters are valid */
 	if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
-		return -1;
+		return -EINVAL;
 
 	byte = ((o - 1) << 5);
 	byte |= (i - 1);
@@ -83,37 +83,33 @@ static int tea6420_switch(struct i2c_cli
 
 	ret = i2c_smbus_write_byte(client, byte);
 	if (ret) {
-		v4l_dbg(1, debug, client,
+		v4l2_dbg(1, debug, sd,
 			"i2c_smbus_write_byte() failed, ret:%d\n", ret);
 		return -EIO;
 	}
 	return 0;
 }
 
-static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
-	if (cmd == TEA6420_SWITCH) {
-		struct i2c_client *client = v4l2_get_subdevdata(sd);
-		struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
-
-		return tea6420_switch(client, a->in, a->out, a->gain);
-	}
-	return -ENOIOCTLCMD;
-}
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
 }
 
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tea6420_core_ops = {
-	.ioctl = tea6420_ioctl,
+	.g_chip_ident = tea6420_g_chip_ident,
+};
+
+static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
+	.s_routing = tea6420_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6420_ops = {
 	.core = &tea6420_core_ops,
+	.audio = &tea6420_audio_ops,
 };
 
 /* this function is called by i2c_probe */
@@ -130,20 +126,19 @@ static int tea6420_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
+	sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (sd == NULL)
+		return -ENOMEM;
+	v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
+
 	/* set initial values: set "mute"-input to all outputs at gain 0 */
 	err = 0;
-	for (i = 1; i < 5; i++) {
-		err += tea6420_switch(client, 6, i, 0);
-	}
+	for (i = 1; i < 5; i++)
+		err += tea6420_s_routing(sd, 6, i, 0);
 	if (err) {
 		v4l_dbg(1, debug, client, "could not initialize tea6420\n");
 		return -ENODEV;
 	}
-
-	sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
-	if (sd == NULL)
-		return -ENOMEM;
-	v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
 	return 0;
 }
 
@@ -156,13 +151,6 @@ static int tea6420_remove(struct i2c_cli
 	return 0;
 }
 
-static int tea6420_legacy_probe(struct i2c_adapter *adapter)
-{
-	/* Let's see whether this is a known adapter we can attach to.
-	   Prevents conflicts with tvaudio.c. */
-	return adapter->id == I2C_HW_SAA7146;
-}
-
 static const struct i2c_device_id tea6420_id[] = {
 	{ "tea6420", 0 },
 	{ }
@@ -171,10 +159,7 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tea6420",
-	.driverid = I2C_DRIVERID_TEA6420,
-	.command = tea6420_command,
 	.probe = tea6420_probe,
 	.remove = tea6420_remove,
-	.legacy_probe = tea6420_legacy_probe,
 	.id_table = tea6420_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tea6420.h linux-libre-2.6.30-gnu1/drivers/media/video/tea6420.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/tea6420.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tea6420.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,17 +1,24 @@
 #ifndef __INCLUDED_TEA6420__
 #define __INCLUDED_TEA6420__
 
-/* possible addresses */
-#define	I2C_ADDR_TEA6420_1		0x4c
-#define	I2C_ADDR_TEA6420_2		0x4d
+/* input pins */
+#define TEA6420_OUTPUT1 1
+#define TEA6420_OUTPUT2 2
+#define TEA6420_OUTPUT3 3
+#define TEA6420_OUTPUT4 4
 
-struct tea6420_multiplex
-{
-	int	in;	/* input of audio switch */
-	int	out;	/* output of audio switch  */
-	int	gain;	/* gain of connection */
-};
+/* output pins */
+#define TEA6420_INPUT1 1
+#define TEA6420_INPUT2 2
+#define TEA6420_INPUT3 3
+#define TEA6420_INPUT4 4
+#define TEA6420_INPUT5 5
+#define TEA6420_INPUT6 6
 
-#define TEA6420_SWITCH		_IOW('v',1,struct tea6420_multiplex)
+/* gain on the output pins, ORed with the output pin */
+#define TEA6420_GAIN0 0x00
+#define TEA6420_GAIN2 0x20
+#define TEA6420_GAIN4 0x40
+#define TEA6420_GAIN6 0x60
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tlv320aic23b.c linux-libre-2.6.30-gnu1/drivers/media/video/tlv320aic23b.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tlv320aic23b.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tlv320aic23b.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,15 +31,12 @@
 #include <linux/i2c-id.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("tlv320aic23b driver");
 MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
 MODULE_LICENSE("GPL");
 
-static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
 
 /* ----------------------------------------------------------------------- */
 
@@ -121,11 +118,6 @@ static int tlv320aic23b_log_status(struc
 	return 0;
 }
 
-static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
@@ -208,8 +200,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tlv320aic23b",
-	.driverid = I2C_DRIVERID_TLV320AIC23B,
-	.command = tlv320aic23b_command,
 	.probe = tlv320aic23b_probe,
 	.remove = tlv320aic23b_remove,
 	.id_table = tlv320aic23b_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tuner-core.c linux-libre-2.6.30-gnu1/drivers/media/video/tuner-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tuner-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tuner-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,12 +15,12 @@
 #include <linux/i2c.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/tuner.h>
 #include <media/tuner-types.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include "mt20xx.h"
 #include "tda8290.h"
 #include "tea5761.h"
@@ -101,18 +101,6 @@ static inline struct tuner *to_tuner(str
 	return container_of(sd, struct tuner, sd);
 }
 
-/* standard i2c insmod options */
-static unsigned short normal_i2c[] = {
-#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
-	0x10,
-#endif
-	0x42, 0x43, 0x4a, 0x4b,			/* tda8290 */
-	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
-	I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
 
 /* insmod options used at init time => read/only */
 static unsigned int addr;
@@ -364,7 +352,8 @@ static void set_type(struct i2c_client *
 	}
 
 	t->type = type;
-	t->config = new_config;
+	/* prevent invalid config values */
+	t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
 	if (tuner_callback != NULL) {
 		tuner_dbg("defining GPIO callback\n");
 		t->fe.callback = tuner_callback;
@@ -452,7 +441,8 @@ static void set_type(struct i2c_client *
 		struct dvb_tuner_ops *xc_tuner_ops;
 
 		xc5000_cfg.i2c_address	  = t->i2c->addr;
-		xc5000_cfg.if_khz	  = 5380;
+		/* if_khz will be set when the digital dvb_attach() occurs */
+		xc5000_cfg.if_khz	  = 0;
 		if (!dvb_attach(xc5000_attach,
 				&t->fe, t->i2c->adapter, &xc5000_cfg))
 			goto attach_failed;
@@ -776,22 +766,21 @@ static int tuner_s_radio(struct v4l2_sub
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
-			== -EINVAL)
+	if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
 		return 0;
 	if (t->radio_freq)
 		set_freq(client, t->radio_freq);
 	return 0;
 }
 
-static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
+static int tuner_s_standby(struct v4l2_subdev *sd)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
 	tuner_dbg("Putting tuner to sleep\n");
 
-	if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
+	if (check_mode(t, "s_standby") == -EINVAL)
 		return 0;
 	t->mode = T_STANDBY;
 	if (analog_ops->standby)
@@ -799,132 +788,6 @@ static int tuner_s_standby(struct v4l2_s
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
-	switch (cmd) {
-	case VIDIOCSAUDIO:
-		if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
-			return 0;
-		if (check_v4l2(t) == -EINVAL)
-			return 0;
-
-		/* Should be implemented, since bttv calls it */
-		tuner_dbg("VIDIOCSAUDIO not implemented.\n");
-		break;
-	case VIDIOCSCHAN:
-		{
-			static const v4l2_std_id map[] = {
-				[VIDEO_MODE_PAL] = V4L2_STD_PAL,
-				[VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
-				[VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
-				[4 /* bttv */ ] = V4L2_STD_PAL_M,
-				[5 /* bttv */ ] = V4L2_STD_PAL_N,
-				[6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
-			};
-			struct video_channel *vc = arg;
-
-			if (check_v4l2(t) == -EINVAL)
-				return 0;
-
-			if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL)
-				return 0;
-
-			if (vc->norm < ARRAY_SIZE(map))
-				t->std = map[vc->norm];
-			tuner_fixup_std(t);
-			if (t->tv_freq)
-				set_tv_freq(client, t->tv_freq);
-			return 0;
-		}
-	case VIDIOCSFREQ:
-		{
-			unsigned long *v = arg;
-
-			if (check_mode(t, "VIDIOCSFREQ") == -EINVAL)
-				return 0;
-			if (check_v4l2(t) == -EINVAL)
-				return 0;
-
-			set_freq(client, *v);
-			return 0;
-		}
-	case VIDIOCGTUNER:
-		{
-			struct video_tuner *vt = arg;
-
-			if (check_mode(t, "VIDIOCGTUNER") == -EINVAL)
-				return 0;
-			if (check_v4l2(t) == -EINVAL)
-				return 0;
-
-			if (V4L2_TUNER_RADIO == t->mode) {
-				if (fe_tuner_ops->get_status) {
-					u32 tuner_status;
-
-					fe_tuner_ops->get_status(&t->fe, &tuner_status);
-					if (tuner_status & TUNER_STATUS_STEREO)
-						vt->flags |= VIDEO_TUNER_STEREO_ON;
-					else
-						vt->flags &= ~VIDEO_TUNER_STEREO_ON;
-				} else {
-					if (analog_ops->is_stereo) {
-						if (analog_ops->is_stereo(&t->fe))
-							vt->flags |=
-								VIDEO_TUNER_STEREO_ON;
-						else
-							vt->flags &=
-								~VIDEO_TUNER_STEREO_ON;
-					}
-				}
-				if (analog_ops->has_signal)
-					vt->signal =
-						analog_ops->has_signal(&t->fe);
-
-				vt->flags |= VIDEO_TUNER_LOW;	/* Allow freqs at 62.5 Hz */
-
-				vt->rangelow = radio_range[0] * 16000;
-				vt->rangehigh = radio_range[1] * 16000;
-
-			} else {
-				vt->rangelow = tv_range[0] * 16;
-				vt->rangehigh = tv_range[1] * 16;
-			}
-
-			return 0;
-		}
-	case VIDIOCGAUDIO:
-		{
-			struct video_audio *va = arg;
-
-			if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL)
-				return 0;
-			if (check_v4l2(t) == -EINVAL)
-				return 0;
-
-			if (V4L2_TUNER_RADIO == t->mode) {
-				if (fe_tuner_ops->get_status) {
-					u32 tuner_status;
-
-					fe_tuner_ops->get_status(&t->fe, &tuner_status);
-					va->mode = (tuner_status & TUNER_STATUS_STEREO)
-					    ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
-				} else if (analog_ops->is_stereo)
-					va->mode = analog_ops->is_stereo(&t->fe)
-					    ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
-			}
-			return 0;
-		}
-	}
-	return -ENOIOCTLCMD;
-}
-#endif
-
 static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
 {
 	struct tuner *t = to_tuner(sd);
@@ -950,8 +813,7 @@ static int tuner_s_std(struct v4l2_subde
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
-			== -EINVAL)
+	if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
 		return 0;
 
 	switch_v4l2();
@@ -968,8 +830,7 @@ static int tuner_s_frequency(struct v4l2
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY")
-			== -EINVAL)
+	if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
 		return 0;
 	switch_v4l2();
 	set_freq(client, f->frequency);
@@ -982,7 +843,7 @@ static int tuner_g_frequency(struct v4l2
 	struct tuner *t = to_tuner(sd);
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
+	if (check_mode(t, "g_frequency") == -EINVAL)
 		return 0;
 	switch_v4l2();
 	f->type = t->mode;
@@ -1006,7 +867,7 @@ static int tuner_g_tuner(struct v4l2_sub
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
+	if (check_mode(t, "g_tuner") == -EINVAL)
 		return 0;
 	switch_v4l2();
 
@@ -1055,7 +916,7 @@ static int tuner_s_tuner(struct v4l2_sub
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
+	if (check_mode(t, "s_tuner") == -EINVAL)
 		return 0;
 
 	switch_v4l2();
@@ -1078,11 +939,6 @@ static int tuner_log_status(struct v4l2_
 	return 0;
 }
 
-static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 static int tuner_suspend(struct i2c_client *c, pm_message_t state)
 {
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
@@ -1107,18 +963,28 @@ static int tuner_resume(struct i2c_clien
 	return 0;
 }
 
+static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	/* TUNER_SET_CONFIG is still called by tuner-simple.c, so we have
+	   to handle it here.
+	   There must be a better way of doing this... */
+	switch (cmd) {
+	case TUNER_SET_CONFIG:
+		return tuner_s_config(sd, arg);
+	}
+	return -ENOIOCTLCMD;
+}
+
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tuner_core_ops = {
 	.log_status = tuner_log_status,
-	.s_standby = tuner_s_standby,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-	.ioctl = tuner_ioctl,
-#endif
+	.s_std = tuner_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
-	.s_std = tuner_s_std,
 	.s_radio = tuner_s_radio,
 	.g_tuner = tuner_g_tuner,
 	.s_tuner = tuner_s_tuner,
@@ -1126,6 +992,7 @@ 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 = {
@@ -1153,7 +1020,7 @@ static void tuner_lookup(struct i2c_adap
 		int mode_mask;
 
 		if (pos->i2c->adapter != adap ||
-		    pos->i2c->driver->id != I2C_DRIVERID_TUNER)
+		    strcmp(pos->i2c->driver->driver.name, "tuner"))
 			continue;
 
 		mode_mask = pos->mode_mask & ~T_STANDBY;
@@ -1297,40 +1164,6 @@ register_client:
 	return 0;
 }
 
-static int tuner_legacy_probe(struct i2c_adapter *adap)
-{
-	if (0 != addr) {
-		normal_i2c[0] = addr;
-		normal_i2c[1] = I2C_CLIENT_END;
-	}
-
-	if ((adap->class & I2C_CLASS_TV_ANALOG) == 0)
-		return 0;
-
-	/* HACK: Ignore 0x6b and 0x6f on cx88 boards.
-	 * FusionHDTV5 RT Gold has an ir receiver at 0x6b
-	 * and an RTC at 0x6f which can get corrupted if probed.
-	 */
-	if ((adap->id == I2C_HW_B_CX2388x) ||
-	    (adap->id == I2C_HW_B_CX23885)) {
-		unsigned int i = 0;
-
-		while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END)
-			i += 2;
-		if (i + 4 < I2C_CLIENT_MAX_OPTS) {
-			ignore[i+0] = adap->nr;
-			ignore[i+1] = 0x6b;
-			ignore[i+2] = adap->nr;
-			ignore[i+3] = 0x6f;
-			ignore[i+4] = I2C_CLIENT_END;
-		} else
-			printk(KERN_WARNING "tuner: "
-			       "too many options specified "
-			       "in i2c probe ignore list!\n");
-	}
-	return 1;
-}
-
 static int tuner_remove(struct i2c_client *client)
 {
 	struct tuner *t = to_tuner(i2c_get_clientdata(client));
@@ -1357,13 +1190,11 @@ MODULE_DEVICE_TABLE(i2c, tuner_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tuner",
-	.driverid = I2C_DRIVERID_TUNER,
-	.command = tuner_command,
 	.probe = tuner_probe,
 	.remove = tuner_remove,
+	.command = tuner_command,
 	.suspend = tuner_suspend,
 	.resume = tuner_resume,
-	.legacy_probe = tuner_legacy_probe,
 	.id_table = tuner_id,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tvaudio.c linux-libre-2.6.30-gnu1/drivers/media/video/tvaudio.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tvaudio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tvaudio.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
@@ -35,7 +35,7 @@
 #include <media/tvaudio.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 #include <media/i2c-addr.h>
 
@@ -136,20 +136,6 @@ static inline struct CHIPSTATE *to_state
 	return container_of(sd, struct CHIPSTATE, sd);
 }
 
-/* ---------------------------------------------------------------------- */
-/* i2c addresses                                                          */
-
-static unsigned short normal_i2c[] = {
-	I2C_ADDR_TDA8425   >> 1,
-	I2C_ADDR_TEA6300   >> 1,
-	I2C_ADDR_TEA6420   >> 1,
-	I2C_ADDR_TDA9840   >> 1,
-	I2C_ADDR_TDA985x_L >> 1,
-	I2C_ADDR_TDA985x_H >> 1,
-	I2C_ADDR_TDA9874   >> 1,
-	I2C_ADDR_PIC16C54  >> 1,
-	I2C_CLIENT_END };
-I2C_CLIENT_INSMOD;
 
 /* ---------------------------------------------------------------------- */
 /* i2c I/O functions                                                      */
@@ -1047,6 +1033,116 @@ static int tda9874a_initialize(struct CH
 	return 0;
 }
 
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9875                 */
+/* The TDA9875 is made by Philips Semiconductor
+ * http://www.semiconductors.philips.com
+ * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
+ *
+ */
+
+/* subaddresses for TDA9875 */
+#define TDA9875_MUT         0x12  /*General mute  (value --> 0b11001100*/
+#define TDA9875_CFG         0x01  /* Config register (value --> 0b00000000 */
+#define TDA9875_DACOS       0x13  /*DAC i/o select (ADC) 0b0000100*/
+#define TDA9875_LOSR        0x16  /*Line output select regirter 0b0100 0001*/
+
+#define TDA9875_CH1V        0x0c  /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V        0x0d  /*Channel 2 volume (mute)*/
+#define TDA9875_SC1         0x14  /*SCART 1 in (mono)*/
+#define TDA9875_SC2         0x15  /*SCART 2 in (mono)*/
+
+#define TDA9875_ADCIS       0x17  /*ADC input select (mono) 0b0110 000*/
+#define TDA9875_AER         0x19  /*Audio effect (AVL+Pseudo) 0b0000 0110*/
+#define TDA9875_MCS         0x18  /*Main channel select (DAC) 0b0000100*/
+#define TDA9875_MVL         0x1a  /* Main volume gauche */
+#define TDA9875_MVR         0x1b  /* Main volume droite */
+#define TDA9875_MBA         0x1d  /* Main Basse */
+#define TDA9875_MTR         0x1e  /* Main treble */
+#define TDA9875_ACS         0x1f  /* Auxilary channel select (FM) 0b0000000*/
+#define TDA9875_AVL         0x20  /* Auxilary volume gauche */
+#define TDA9875_AVR         0x21  /* Auxilary volume droite */
+#define TDA9875_ABA         0x22  /* Auxilary Basse */
+#define TDA9875_ATR         0x23  /* Auxilary treble */
+
+#define TDA9875_MSR         0x02  /* Monitor select register */
+#define TDA9875_C1MSB       0x03  /* Carrier 1 (FM) frequency register MSB */
+#define TDA9875_C1MIB       0x04  /* Carrier 1 (FM) frequency register (16-8]b */
+#define TDA9875_C1LSB       0x05  /* Carrier 1 (FM) frequency register LSB */
+#define TDA9875_C2MSB       0x06  /* Carrier 2 (nicam) frequency register MSB */
+#define TDA9875_C2MIB       0x07  /* Carrier 2 (nicam) frequency register (16-8]b */
+#define TDA9875_C2LSB       0x08  /* Carrier 2 (nicam) frequency register LSB */
+#define TDA9875_DCR         0x09  /* Demodulateur configuration regirter*/
+#define TDA9875_DEEM        0x0a  /* FM de-emphasis regirter*/
+#define TDA9875_FMAT        0x0b  /* FM Matrix regirter*/
+
+/* values */
+#define TDA9875_MUTE_ON	    0xff /* general mute */
+#define TDA9875_MUTE_OFF    0xcc /* general no mute */
+
+static int tda9875_initialize(struct CHIPSTATE *chip)
+{
+	chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
+	chip_write(chip, TDA9875_MSR, 0x03);    /* Monitor 0b00000XXX*/
+	chip_write(chip, TDA9875_C1MSB, 0x00);  /*Car1(FM) MSB XMHz*/
+	chip_write(chip, TDA9875_C1MIB, 0x00);  /*Car1(FM) MIB XMHz*/
+	chip_write(chip, TDA9875_C1LSB, 0x00);  /*Car1(FM) LSB XMHz*/
+	chip_write(chip, TDA9875_C2MSB, 0x00);  /*Car2(NICAM) MSB XMHz*/
+	chip_write(chip, TDA9875_C2MIB, 0x00);  /*Car2(NICAM) MIB XMHz*/
+	chip_write(chip, TDA9875_C2LSB, 0x00);  /*Car2(NICAM) LSB XMHz*/
+	chip_write(chip, TDA9875_DCR, 0x00);    /*Demod config 0x00*/
+	chip_write(chip, TDA9875_DEEM, 0x44);   /*DE-Emph 0b0100 0100*/
+	chip_write(chip, TDA9875_FMAT, 0x00);   /*FM Matrix reg 0x00*/
+	chip_write(chip, TDA9875_SC1, 0x00);    /* SCART 1 (SC1)*/
+	chip_write(chip, TDA9875_SC2, 0x01);    /* SCART 2 (sc2)*/
+
+	chip_write(chip, TDA9875_CH1V, 0x10);  /* Channel volume 1 mute*/
+	chip_write(chip, TDA9875_CH2V, 0x10);  /* Channel volume 2 mute */
+	chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
+	chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
+	chip_write(chip, TDA9875_LOSR, 0x00);  /* line out (in:mono)*/
+	chip_write(chip, TDA9875_AER, 0x00);   /*06 Effect (AVL+PSEUDO) */
+	chip_write(chip, TDA9875_MCS, 0x44);   /* Main ch select (DAC) */
+	chip_write(chip, TDA9875_MVL, 0x03);   /* Vol Main left 10dB */
+	chip_write(chip, TDA9875_MVR, 0x03);   /* Vol Main right 10dB*/
+	chip_write(chip, TDA9875_MBA, 0x00);   /* Main Bass Main 0dB*/
+	chip_write(chip, TDA9875_MTR, 0x00);   /* Main Treble Main 0dB*/
+	chip_write(chip, TDA9875_ACS, 0x44);   /* Aux chan select (dac)*/
+	chip_write(chip, TDA9875_AVL, 0x00);   /* Vol Aux left 0dB*/
+	chip_write(chip, TDA9875_AVR, 0x00);   /* Vol Aux right 0dB*/
+	chip_write(chip, TDA9875_ABA, 0x00);   /* Aux Bass Main 0dB*/
+	chip_write(chip, TDA9875_ATR, 0x00);   /* Aux Aigus Main 0dB*/
+
+	chip_write(chip, TDA9875_MUT, 0xcc);   /* General mute  */
+	return 0;
+}
+
+static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
+static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); }
+static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
+
+/* ----------------------------------------------------------------------- */
+
+
+/* *********************** *
+ * i2c interface functions *
+ * *********************** */
+
+static int tda9875_checkit(struct CHIPSTATE *chip)
+{
+	struct v4l2_subdev *sd = &chip->sd;
+	int dic, rev;
+
+	dic = chip_read2(chip, 254);
+	rev = chip_read2(chip, 255);
+
+	if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
+		v4l2_info(sd, "found tda9875%s rev. %d.\n",
+			dic == 0 ? "" : "A", rev);
+		return 1;
+	}
+	return 0;
+}
 
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tea6420                */
@@ -1280,6 +1376,7 @@ static int tda9850  = 1;
 static int tda9855  = 1;
 static int tda9873  = 1;
 static int tda9874a = 1;
+static int tda9875  = 1;
 static int tea6300;	/* default 0 - address clash with msp34xx */
 static int tea6320;	/* default 0 - address clash with msp34xx */
 static int tea6420  = 1;
@@ -1292,6 +1389,7 @@ module_param(tda9850, int, 0444);
 module_param(tda9855, int, 0444);
 module_param(tda9873, int, 0444);
 module_param(tda9874a, int, 0444);
+module_param(tda9875, int, 0444);
 module_param(tea6300, int, 0444);
 module_param(tea6320, int, 0444);
 module_param(tea6420, int, 0444);
@@ -1349,6 +1447,26 @@ static struct CHIPDESC chiplist[] = {
 		.setmode    = tda9874a_setmode,
 	},
 	{
+		.name       = "tda9875",
+		.insmodopt  = &tda9875,
+		.addr_lo    = I2C_ADDR_TDA9875 >> 1,
+		.addr_hi    = I2C_ADDR_TDA9875 >> 1,
+		.flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+		/* callbacks */
+		.initialize = tda9875_initialize,
+		.checkit    = tda9875_checkit,
+		.volfunc    = tda9875_volume,
+		.bassfunc   = tda9875_bass,
+		.treblefunc = tda9875_treble,
+		.leftreg    = TDA9875_MVL,
+		.rightreg   = TDA9875_MVR,
+		.bassreg    = TDA9875_MBA,
+		.treblereg  = TDA9875_MTR,
+		.leftinit   = 58880,
+		.rightinit  = 58880,
+	},
+	{
 		.name       = "tda9850",
 		.insmodopt  = &tda9850,
 		.addr_lo    = I2C_ADDR_TDA985x_L >> 1,
@@ -1511,6 +1629,8 @@ static int tvaudio_g_ctrl(struct v4l2_su
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
+		if (!(desc->flags & CHIP_HAS_INPUTSEL))
+			break;
 		ctrl->value=chip->muted;
 		return 0;
 	case V4L2_CID_AUDIO_VOLUME:
@@ -1552,6 +1672,9 @@ static int tvaudio_s_ctrl(struct v4l2_su
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
+		if (!(desc->flags & CHIP_HAS_INPUTSEL))
+			break;
+
 		if (ctrl->value < 0 || ctrl->value >= 2)
 			return -ERANGE;
 		chip->muted = ctrl->value;
@@ -1636,32 +1759,40 @@ static int tvaudio_queryctrl(struct v4l2
 
 	switch (qc->id) {
 	case V4L2_CID_AUDIO_MUTE:
+		if (desc->flags & CHIP_HAS_INPUTSEL)
+			return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
+		if (desc->flags & CHIP_HAS_VOLUME)
+			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+		break;
 	case V4L2_CID_AUDIO_BALANCE:
-		if (!(desc->flags & CHIP_HAS_VOLUME))
-			return -EINVAL;
+		if (desc->flags & CHIP_HAS_VOLUME)
+			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 		break;
 	case V4L2_CID_AUDIO_BASS:
 	case V4L2_CID_AUDIO_TREBLE:
-		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-			return -EINVAL;
+		if (desc->flags & CHIP_HAS_BASSTREBLE)
+			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 		break;
 	default:
-		return -EINVAL;
+		break;
 	}
-	return v4l2_ctrl_query_fill_std(qc);
+	return -EINVAL;
 }
 
-static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
+static int tvaudio_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct CHIPSTATE *chip = to_state(sd);
 	struct CHIPDESC *desc = chip->desc;
 
-	if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+	if (!(desc->flags & CHIP_HAS_INPUTSEL))
+		return 0;
+	if (input >= 4)
 		return -EINVAL;
 	/* There are four inputs: tuner, radio, extern and intern. */
-	chip->input = rt->input;
+	chip->input = input;
 	if (chip->muted)
 		return 0;
 	chip_write_masked(chip, desc->inputreg,
@@ -1675,8 +1806,11 @@ static int tvaudio_s_tuner(struct v4l2_s
 	struct CHIPDESC *desc = chip->desc;
 	int mode = 0;
 
+	if (!desc->setmode)
+		return 0;
 	if (chip->radio)
 		return 0;
+
 	switch (vt->audmode) {
 	case V4L2_TUNER_MODE_MONO:
 	case V4L2_TUNER_MODE_STEREO:
@@ -1692,7 +1826,7 @@ static int tvaudio_s_tuner(struct v4l2_s
 	}
 	chip->audmode = vt->audmode;
 
-	if (desc->setmode && mode) {
+	if (mode) {
 		chip->watch_stereo = 0;
 		/* del_timer(&chip->wt); */
 		chip->mode = mode;
@@ -1707,15 +1841,17 @@ static int tvaudio_g_tuner(struct v4l2_s
 	struct CHIPDESC *desc = chip->desc;
 	int mode = V4L2_TUNER_MODE_MONO;
 
+	if (!desc->getmode)
+		return 0;
 	if (chip->radio)
 		return 0;
+
 	vt->audmode = chip->audmode;
 	vt->rxsubchans = 0;
 	vt->capability = V4L2_TUNER_CAP_STEREO |
 		V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
 
-	if (desc->getmode)
-		mode = desc->getmode(chip);
+	mode = desc->getmode(chip);
 
 	if (mode & V4L2_TUNER_MODE_MONO)
 		vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
@@ -1769,11 +1905,6 @@ static int tvaudio_g_chip_ident(struct v
 	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
 }
 
-static int tvaudio_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
@@ -1781,12 +1912,12 @@ static const struct v4l2_subdev_core_ops
 	.queryctrl = tvaudio_queryctrl,
 	.g_ctrl = tvaudio_g_ctrl,
 	.s_ctrl = tvaudio_s_ctrl,
+	.s_std = tvaudio_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
 	.s_radio = tvaudio_s_radio,
 	.s_frequency = tvaudio_s_frequency,
-	.s_std = tvaudio_s_std,
 	.s_tuner = tvaudio_s_tuner,
 	.s_tuner = tvaudio_g_tuner,
 };
@@ -1901,6 +2032,7 @@ static int tvaudio_probe(struct i2c_clie
 	}
 
 	chip->thread = NULL;
+	init_timer(&chip->wt);
 	if (desc->flags & CHIP_NEED_CHECKMODE) {
 		if (!desc->getmode || !desc->setmode) {
 			/* This shouldn't be happen. Warn user, but keep working
@@ -1910,7 +2042,6 @@ static int tvaudio_probe(struct i2c_clie
 			return 0;
 		}
 		/* start async thread */
-		init_timer(&chip->wt);
 		chip->wt.function = chip_thread_wake;
 		chip->wt.data     = (unsigned long)chip;
 		chip->thread = kthread_run(chip_thread, chip, client->name);
@@ -1939,17 +2070,6 @@ static int tvaudio_remove(struct i2c_cli
 	return 0;
 }
 
-static int tvaudio_legacy_probe(struct i2c_adapter *adap)
-{
-	/* don't attach on saa7146 based cards,
-	   because dedicated drivers are used */
-	if ((adap->id == I2C_HW_SAA7146))
-		return 0;
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return 1;
-	return 0;
-}
-
 /* This driver supports many devices and the idea is to let the driver
    detect which device is present. So rather than listing all supported
    devices here, we pretend to support a single, fake device type. */
@@ -1961,10 +2081,7 @@ MODULE_DEVICE_TABLE(i2c, tvaudio_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tvaudio",
-	.driverid = I2C_DRIVERID_TVAUDIO,
-	.command = tvaudio_command,
 	.probe = tvaudio_probe,
 	.remove = tvaudio_remove,
-	.legacy_probe = tvaudio_legacy_probe,
 	.id_table = tvaudio_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tveeprom.c linux-libre-2.6.30-gnu1/drivers/media/video/tveeprom.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tveeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tveeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -261,7 +261,12 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        		"MaxLinear MXL5005_v2"},
 	{ TUNER_PHILIPS_TDA8290, 	"Philips 18271_8295"},
 	/* 150-159 */
-	{ TUNER_ABSENT,                 "Xceive XC5000"},
+	{ TUNER_XC5000,                 "Xceive XC5000"},
+	{ TUNER_ABSENT,                 "Xceive XC3028L"},
+	{ TUNER_ABSENT,                 "NXP 18271C2_716x"},
+	{ TUNER_ABSENT,                 "Xceive XC4000"},
+	{ TUNER_ABSENT,                 "Dibcom 7070"},
+	{ TUNER_PHILIPS_TDA8290,        "NXP 18271C2"},
 };
 
 /* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tvp514x.c linux-libre-2.6.30-gnu1/drivers/media/video/tvp514x.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tvp514x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tvp514x.c	2009-06-09 23:05:27.000000000 -0400
@@ -86,9 +86,12 @@ struct tvp514x_std_info {
 	struct v4l2_standard standard;
 };
 
+static struct tvp514x_reg tvp514x_reg_list_default[0x40];
 /**
- * struct tvp514x_decoded - TVP5146/47 decoder object
+ * struct tvp514x_decoder - TVP5146/47 decoder object
  * @v4l2_int_device: Slave handle
+ * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
+ * @tvp514x_regs: copy of hw's regs with preset values.
  * @pdata: Board specific
  * @client: I2C client data
  * @id: Entry from I2C table
@@ -103,7 +106,9 @@ struct tvp514x_std_info {
  * @route: input and output routing at chip level
  */
 struct tvp514x_decoder {
-	struct v4l2_int_device *v4l2_int_device;
+	struct v4l2_int_device v4l2_int_device;
+	struct v4l2_int_slave tvp514x_slave;
+	struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
 	const struct tvp514x_platform_data *pdata;
 	struct i2c_client *client;
 
@@ -124,7 +129,7 @@ struct tvp514x_decoder {
 };
 
 /* TVP514x default register values */
-static struct tvp514x_reg tvp514x_reg_list[] = {
+static struct tvp514x_reg tvp514x_reg_list_default[] = {
 	{TOK_WRITE, REG_INPUT_SEL, 0x05},	/* Composite selected */
 	{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
 	{TOK_WRITE, REG_VIDEO_STD, 0x00},	/* Auto mode */
@@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp5
 
 	/* common register initialization */
 	err =
-	    tvp514x_write_regs(decoder->client, tvp514x_reg_list);
+	    tvp514x_write_regs(decoder->client, decoder->tvp514x_regs);
 	if (err)
 		return err;
 
@@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_d
 		return err;
 
 	decoder->current_std = i;
-	tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std;
+	decoder->tvp514x_regs[REG_VIDEO_STD].val =
+		decoder->std_list[i].video_std;
 
 	v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
 			decoder->std_list[i].standard.name);
@@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_i
 	if (err)
 		return err;
 
-	tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
-	tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel;
+	decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
+	decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
 
 	/* Clear status */
 	msleep(LOCK_RETRY_DELAY);
@@ -686,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_i
 			break;	/* Input detected */
 	}
 
-	if ((current_std == STD_INVALID) || (try_count < 0))
+	if ((current_std == STD_INVALID) || (try_count <= 0))
 		return -EINVAL;
 
 	decoder->current_std = current_std;
@@ -719,10 +725,9 @@ ioctl_queryctrl(struct v4l2_int_device *
 
 	switch (qctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
-		/* Brightness supported is same as standard one (0-255),
-		 * so make use of standard API provided.
+		/* Brightness supported is (0-255),
 		 */
-		err = v4l2_ctrl_query_fill_std(qctrl);
+		err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
 		break;
 	case V4L2_CID_CONTRAST:
 	case V4L2_CID_SATURATION:
@@ -779,16 +784,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s,
 
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
-		ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val;
+		ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
 		break;
 	case V4L2_CID_CONTRAST:
-		ctrl->value = tvp514x_reg_list[REG_CONTRAST].val;
+		ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
 		break;
 	case V4L2_CID_SATURATION:
-		ctrl->value = tvp514x_reg_list[REG_SATURATION].val;
+		ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
 		break;
 	case V4L2_CID_HUE:
-		ctrl->value = tvp514x_reg_list[REG_HUE].val;
+		ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
 		if (ctrl->value == 0x7F)
 			ctrl->value = 180;
 		else if (ctrl->value == 0x80)
@@ -798,7 +803,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s,
 
 		break;
 	case V4L2_CID_AUTOGAIN:
-		ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val;
+		ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
 		if ((ctrl->value & 0x3) == 3)
 			ctrl->value = 1;
 		else
@@ -848,7 +853,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s,
 				value);
 		if (err)
 			return err;
-		tvp514x_reg_list[REG_BRIGHTNESS].val = value;
+		decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
 		break;
 	case V4L2_CID_CONTRAST:
 		if (ctrl->value < 0 || ctrl->value > 255) {
@@ -861,7 +866,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s,
 				value);
 		if (err)
 			return err;
-		tvp514x_reg_list[REG_CONTRAST].val = value;
+		decoder->tvp514x_regs[REG_CONTRAST].val = value;
 		break;
 	case V4L2_CID_SATURATION:
 		if (ctrl->value < 0 || ctrl->value > 255) {
@@ -874,7 +879,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s,
 				value);
 		if (err)
 			return err;
-		tvp514x_reg_list[REG_SATURATION].val = value;
+		decoder->tvp514x_regs[REG_SATURATION].val = value;
 		break;
 	case V4L2_CID_HUE:
 		if (value == 180)
@@ -893,7 +898,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s,
 				value);
 		if (err)
 			return err;
-		tvp514x_reg_list[REG_HUE].val = value;
+		decoder->tvp514x_regs[REG_HUE].val = value;
 		break;
 	case V4L2_CID_AUTOGAIN:
 		if (value == 1)
@@ -910,7 +915,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s,
 				value);
 		if (err)
 			return err;
-		tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value;
+		decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
 		break;
 	default:
 		v4l_err(decoder->client,
@@ -1275,7 +1280,7 @@ static int ioctl_init(struct v4l2_int_de
 	struct tvp514x_decoder *decoder = s->priv;
 
 	/* Set default standard to auto */
-	tvp514x_reg_list[REG_VIDEO_STD].val =
+	decoder->tvp514x_regs[REG_VIDEO_STD].val =
 	    VIDEO_STD_AUTO_SWITCH_BIT;
 
 	return tvp514x_configure(decoder);
@@ -1344,11 +1349,6 @@ static struct v4l2_int_ioctl_desc tvp514
 		(v4l2_int_ioctl_func *) ioctl_s_routing},
 };
 
-static struct v4l2_int_slave tvp514x_slave = {
-	.ioctls = tvp514x_ioctl_desc,
-	.num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
-};
-
 static struct tvp514x_decoder tvp514x_dev = {
 	.state = STATE_NOT_DETECTED,
 
@@ -1369,17 +1369,15 @@ static struct tvp514x_decoder tvp514x_de
 	.current_std = STD_NTSC_MJ,
 	.std_list = tvp514x_std_list,
 	.num_stds = ARRAY_SIZE(tvp514x_std_list),
-
-};
-
-static struct v4l2_int_device tvp514x_int_device = {
-	.module = THIS_MODULE,
-	.name = TVP514X_MODULE_NAME,
-	.priv = &tvp514x_dev,
-	.type = v4l2_int_type_slave,
-	.u = {
-	      .slave = &tvp514x_slave,
-	      },
+	.v4l2_int_device = {
+		.module = THIS_MODULE,
+		.name = TVP514X_MODULE_NAME,
+		.type = v4l2_int_type_slave,
+	},
+	.tvp514x_slave = {
+		.ioctls = tvp514x_ioctl_desc,
+		.num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
+	},
 };
 
 /**
@@ -1392,26 +1390,37 @@ static struct v4l2_int_device tvp514x_in
 static int
 tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-	struct tvp514x_decoder *decoder = &tvp514x_dev;
+	struct tvp514x_decoder *decoder;
 	int err;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	decoder->pdata = client->dev.platform_data;
-	if (!decoder->pdata) {
+	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+	if (!decoder)
+		return -ENOMEM;
+
+	if (!client->dev.platform_data) {
 		v4l_err(client, "No platform data!!\n");
-		return -ENODEV;
+		err = -ENODEV;
+		goto out_free;
 	}
+
+	*decoder = tvp514x_dev;
+	decoder->v4l2_int_device.priv = decoder;
+	decoder->pdata = client->dev.platform_data;
+	decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
+	memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
+			sizeof(tvp514x_reg_list_default));
 	/*
 	 * Fetch platform specific data, and configure the
 	 * tvp514x_reg_list[] accordingly. Since this is one
 	 * time configuration, no need to preserve.
 	 */
-	tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
+	decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
 			(decoder->pdata->clk_polarity << 1);
-	tvp514x_reg_list[REG_SYNC_CONTROL].val |=
+	decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
 			((decoder->pdata->hs_polarity << 2) |
 			(decoder->pdata->vs_polarity << 3));
 	/*
@@ -1419,23 +1428,27 @@ tvp514x_probe(struct i2c_client *client,
 	 */
 	decoder->id = (struct i2c_device_id *)id;
 	/* Attach to Master */
-	strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
-	decoder->v4l2_int_device = &tvp514x_int_device;
+	strcpy(decoder->v4l2_int_device.u.slave->attach_to,
+			decoder->pdata->master);
 	decoder->client = client;
 	i2c_set_clientdata(client, decoder);
 
 	/* Register with V4L2 layer as slave device */
-	err = v4l2_int_device_register(decoder->v4l2_int_device);
+	err = v4l2_int_device_register(&decoder->v4l2_int_device);
 	if (err) {
 		i2c_set_clientdata(client, NULL);
 		v4l_err(client,
 			"Unable to register to v4l2. Err[%d]\n", err);
+		goto out_free;
 
 	} else
 		v4l_info(client, "Registered to v4l2 master %s!!\n",
 				decoder->pdata->master);
-
 	return 0;
+
+out_free:
+	kfree(decoder);
+	return err;
 }
 
 /**
@@ -1452,9 +1465,9 @@ static int __exit tvp514x_remove(struct
 	if (!client->adapter)
 		return -ENODEV;	/* our client isn't attached */
 
-	v4l2_int_device_unregister(decoder->v4l2_int_device);
+	v4l2_int_device_unregister(&decoder->v4l2_int_device);
 	i2c_set_clientdata(client, NULL);
-
+	kfree(decoder);
 	return 0;
 }
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tvp5150.c linux-libre-2.6.30-gnu1/drivers/media/video/tvp5150.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tvp5150.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tvp5150.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,10 +8,9 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
-#include <linux/video_decoder.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 #include <media/v4l2-chip-ident.h>
 
 #include "tvp5150_reg.h"
@@ -20,14 +19,6 @@ MODULE_DESCRIPTION("Texas Instruments TV
 MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_LICENSE("GPL");
 
-/* standard i2c insmod options */
-static unsigned short normal_i2c[] = {
-	0xb8 >> 1,
-	0xba >> 1,
-	I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
 
 static int debug;
 module_param(debug, int, 0);
@@ -78,7 +69,8 @@ struct tvp5150 {
 	struct v4l2_subdev sd;
 
 	v4l2_std_id norm;	/* Current set standard */
-	struct v4l2_routing route;
+	u32 input;
+	u32 output;
 	int enable;
 	int bright;
 	int contrast;
@@ -289,10 +281,10 @@ static inline void tvp5150_selmux(struct
 	int input = 0;
 	unsigned char val;
 
-	if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
+	if ((decoder->output & TVP5150_BLACK_SCREEN) || !decoder->enable)
 		input = 8;
 
-	switch (decoder->route.input) {
+	switch (decoder->input) {
 	case TVP5150_COMPOSITE1:
 		input |= 2;
 		/* fall through */
@@ -308,8 +300,8 @@ static inline void tvp5150_selmux(struct
 
 	v4l2_dbg(1, debug, sd, "Selecting video route: route input=%i, output=%i "
 			"=> tvp5150 input=%i, opmode=%i\n",
-			decoder->route.input,decoder->route.output,
-			input, opmode );
+			decoder->input, decoder->output,
+			input, opmode);
 
 	tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
 	tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
@@ -318,7 +310,7 @@ static inline void tvp5150_selmux(struct
 	 * For Composite and TV, it should be the reverse
 	 */
 	val = tvp5150_read(sd, TVP5150_MISC_CTL);
-	if (decoder->route.input == TVP5150_SVIDEO)
+	if (decoder->input == TVP5150_SVIDEO)
 		val = (val & ~0x40) | 0x10;
 	else
 		val = (val & ~0x10) | 0x40;
@@ -632,7 +624,7 @@ static int tvp5150_g_sliced_vbi_cap(stru
 	const struct i2c_vbi_ram_value *regs = vbi_ram_default;
 	int line;
 
-	v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n");
+	v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n");
 	memset(cap, 0, sizeof *cap);
 
 	while (regs->reg != (u16)-1 ) {
@@ -831,7 +823,7 @@ static int tvp5150_reset(struct v4l2_sub
 
 static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n");
+	v4l2_dbg(1, debug, sd, "g_ctrl called\n");
 
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
@@ -861,7 +853,7 @@ static int tvp5150_s_ctrl(struct v4l2_su
 		if (ctrl->value < tvp5150_qctrl[i].minimum ||
 		    ctrl->value > tvp5150_qctrl[i].maximum)
 			return -ERANGE;
-		v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n",
+		v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
 					ctrl->id, ctrl->value);
 		break;
 	}
@@ -887,11 +879,13 @@ static int tvp5150_s_ctrl(struct v4l2_su
 			I2C Command
  ****************************************************************************/
 
-static int tvp5150_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int tvp5150_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
 
-	decoder->route = *route;
+	decoder->input = input;
+	decoder->output = output;
 	tvp5150_selmux(sd);
 	return 0;
 }
@@ -1015,7 +1009,7 @@ static int tvp5150_queryctrl(struct v4l2
 {
 	int i;
 
-	v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n");
+	v4l2_dbg(1, debug, sd, "queryctrl called\n");
 
 	for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
 		if (qc->id && qc->id == tvp5150_qctrl[i].id) {
@@ -1027,11 +1021,6 @@ static int tvp5150_queryctrl(struct v4l2
 	return -EINVAL;
 }
 
-static int tvp5150_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
@@ -1039,6 +1028,7 @@ static const struct v4l2_subdev_core_ops
 	.g_ctrl = tvp5150_g_ctrl,
 	.s_ctrl = tvp5150_s_ctrl,
 	.queryctrl = tvp5150_queryctrl,
+	.s_std = tvp5150_s_std,
 	.reset = tvp5150_reset,
 	.g_chip_ident = tvp5150_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1048,7 +1038,6 @@ static const struct v4l2_subdev_core_ops
 };
 
 static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
-	.s_std = tvp5150_s_std,
 	.g_tuner = tvp5150_g_tuner,
 };
 
@@ -1091,7 +1080,7 @@ static int tvp5150_probe(struct i2c_clie
 		 c->addr << 1, c->adapter->name);
 
 	core->norm = V4L2_STD_ALL;	/* Default is autodetect */
-	core->route.input = TVP5150_COMPOSITE1;
+	core->input = TVP5150_COMPOSITE1;
 	core->enable = 1;
 	core->bright = 128;
 	core->contrast = 128;
@@ -1126,10 +1115,7 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "tvp5150",
-	.driverid = I2C_DRIVERID_TVP5150,
-	.command = tvp5150_command,
 	.probe = tvp5150_probe,
 	.remove = tvp5150_remove,
-	.legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
 	.id_table = tvp5150_id,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/tw9910.c linux-libre-2.6.30-gnu1/drivers/media/video/tw9910.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/tw9910.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/tw9910.c	2009-06-09 23:05:27.000000000 -0400
@@ -460,9 +460,11 @@ static int tw9910_mask_set(struct i2c_cl
 			   u8 mask, u8 set)
 {
 	s32 val = i2c_smbus_read_byte_data(client, command);
+	if (val < 0)
+		return val;
 
 	val &= ~mask;
-	val |=  set;
+	val |= set & mask;
 
 	return i2c_smbus_write_byte_data(client, command, val);
 }
@@ -639,8 +641,8 @@ static int tw9910_set_register(struct so
 }
 #endif
 
-static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
-			      struct v4l2_rect *rect)
+static int tw9910_set_crop(struct soc_camera_device *icd,
+			   struct v4l2_rect *rect)
 {
 	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
 	int                 ret  = -EINVAL;
@@ -731,8 +733,33 @@ tw9910_set_fmt_error:
 	return ret;
 }
 
+static int tw9910_set_fmt(struct soc_camera_device *icd,
+			  struct v4l2_format *f)
+{
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_rect rect = {
+		.left	= icd->x_current,
+		.top	= icd->y_current,
+		.width	= pix->width,
+		.height	= pix->height,
+	};
+	int i;
+
+	/*
+	 * 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))
+		return -EINVAL;
+
+	return tw9910_set_crop(icd, &rect);
+}
+
 static int tw9910_try_fmt(struct soc_camera_device *icd,
-			      struct v4l2_format *f)
+			  struct v4l2_format *f)
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	const struct tw9910_scale_ctrl *scale;
@@ -820,6 +847,7 @@ static struct soc_camera_ops tw9910_ops
 	.release		= tw9910_release,
 	.start_capture		= tw9910_start_capture,
 	.stop_capture		= tw9910_stop_capture,
+	.set_crop		= tw9910_set_crop,
 	.set_fmt		= tw9910_set_fmt,
 	.try_fmt		= tw9910_try_fmt,
 	.set_bus_param		= tw9910_set_bus_param,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/upd64031a.c linux-libre-2.6.30-gnu1/drivers/media/video/upd64031a.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/upd64031a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/upd64031a.c	2009-06-09 23:05:27.000000000 -0400
@@ -124,17 +124,18 @@ static int upd64031a_s_frequency(struct
 
 /* ------------------------------------------------------------------------ */
 
-static int upd64031a_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64031a_s_routing(struct v4l2_subdev *sd,
+			       u32 input, u32 output, u32 config)
 {
 	struct upd64031a_state *state = to_state(sd);
 	u8 r00, r05, r08;
 
-	state->gr_mode = (route->input & 3) << 6;
-	state->direct_3dycs_connect = (route->input & 0xc) << 4;
+	state->gr_mode = (input & 3) << 6;
+	state->direct_3dycs_connect = (input & 0xc) << 4;
 	state->ext_comp_sync =
-		(route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
+		(input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
 	state->ext_vert_sync =
-		(route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
+		(input & UPD64031A_VERTICAL_EXTERNAL) << 2;
 	r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
 	r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
 		state->ext_comp_sync | state->ext_vert_sync;
@@ -187,11 +188,6 @@ static int upd64031a_s_register(struct v
 }
 #endif
 
-static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
@@ -267,8 +263,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "upd64031a",
-	.driverid = I2C_DRIVERID_UPD64031A,
-	.command = upd64031a_command,
 	.probe = upd64031a_probe,
 	.remove = upd64031a_remove,
 	.id_table = upd64031a_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/upd64083.c linux-libre-2.6.30-gnu1/drivers/media/video/upd64083.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/upd64083.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/upd64083.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,15 +102,16 @@ static u8 upd64083_read(struct v4l2_subd
 
 /* ------------------------------------------------------------------------ */
 
-static int upd64083_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int upd64083_s_routing(struct v4l2_subdev *sd,
+			      u32 input, u32 output, u32 config)
 {
 	struct upd64083_state *state = to_state(sd);
 	u8 r00, r02;
 
-	if (route->input > 7 || (route->input & 6) == 6)
+	if (input > 7 || (input & 6) == 6)
 		return -EINVAL;
-	state->mode = (route->input & 3) << 6;
-	state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
+	state->mode = (input & 3) << 6;
+	state->ext_y_adc = (input & UPD64083_EXT_Y_ADC) << 3;
 	r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
 	r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
 	upd64083_write(sd, R00, r00);
@@ -164,11 +165,6 @@ static int upd64083_log_status(struct v4
 	return 0;
 }
 
-static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops upd64083_core_ops = {
@@ -239,8 +235,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "upd64083",
-	.driverid = I2C_DRIVERID_UPD64083,
-	.command = upd64083_command,
 	.probe = upd64083_probe,
 	.remove = upd64083_remove,
 	.id_table = upd64083_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/usbvideo/vicam.c linux-libre-2.6.30-gnu1/drivers/media/video/usbvideo/vicam.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/usbvideo/vicam.c	2013-05-03 18:02:23.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/usbvideo/vicam.c	2013-05-03 16:46:13.000000000 -0400
@@ -191,7 +191,7 @@ initialize_camera(struct vicam_camera *c
 {
 	int err;
 	const struct ihex_binrec *rec;
-	const struct firmware *fw;
+	const struct firmware *uninitialized_var(fw);
 
 	err = reject_firmware(&fw, "/*(DEBLOBBED)*/", &cam->udev->dev);
 	if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-core.c linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-core.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/spinlock.h>
 #include <asm/io.h>
 #include <linux/videodev2.h>
-#include <linux/video_decoder.h>
 #include <linux/i2c.h>
 
 #include <media/saa7115.h>
@@ -381,8 +380,9 @@ int usbvision_scratch_alloc(struct usb_u
 	usbvision->scratch = vmalloc_32(scratch_buf_size);
 	scratch_reset(usbvision);
 	if(usbvision->scratch == NULL) {
-		err("%s: unable to allocate %d bytes for scratch",
-		    __func__, scratch_buf_size);
+		dev_err(&usbvision->dev->dev,
+			"%s: unable to allocate %d bytes for scratch\n",
+				__func__, scratch_buf_size);
 		return -ENOMEM;
 	}
 	return 0;
@@ -491,8 +491,9 @@ int usbvision_decompress_alloc(struct us
 	int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
 	usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
 	if (usbvision->IntraFrameBuffer == NULL) {
-		err("%s: unable to allocate %d for compr. frame buffer",
-		    __func__, IFB_size);
+		dev_err(&usbvision->dev->dev,
+			"%s: unable to allocate %d for compr. frame buffer\n",
+				__func__, IFB_size);
 		return -ENOMEM;
 	}
 	return 0;
@@ -1514,8 +1515,9 @@ static void usbvision_isocIrq(struct urb
 	errCode = usb_submit_urb (urb, GFP_ATOMIC);
 
 	if(errCode) {
-		err("%s: usb_submit_urb failed: error %d",
-		    __func__, errCode);
+		dev_err(&usbvision->dev->dev,
+			"%s: usb_submit_urb failed: error %d\n",
+				__func__, errCode);
 	}
 
 	return;
@@ -1546,7 +1548,8 @@ int usbvision_read_reg(struct usb_usbvis
 				0, (__u16) reg, buffer, 1, HZ);
 
 	if (errCode < 0) {
-		err("%s: failed: error %d", __func__, errCode);
+		dev_err(&usbvision->dev->dev,
+			"%s: failed: error %d\n", __func__, errCode);
 		return errCode;
 	}
 	return buffer[0];
@@ -1574,7 +1577,8 @@ int usbvision_write_reg(struct usb_usbvi
 				USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
 
 	if (errCode < 0) {
-		err("%s: failed: error %d", __func__, errCode);
+		dev_err(&usbvision->dev->dev,
+			"%s: failed: error %d\n", __func__, errCode);
 	}
 	return errCode;
 }
@@ -1850,7 +1854,8 @@ int usbvision_set_output(struct usb_usbv
 				 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
 
 		if (errCode < 0) {
-			err("%s failed: error %d", __func__, errCode);
+			dev_err(&usbvision->dev->dev,
+				"%s failed: error %d\n", __func__, errCode);
 			return errCode;
 		}
 		usbvision->curwidth = usbvision->stretch_width * UsbWidth;
@@ -2236,7 +2241,7 @@ static int usbvision_set_dram_settings(s
 			     (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
 
 	if (rc < 0) {
-		err("%sERROR=%d", __func__, rc);
+		dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
 		return rc;
 	}
 
@@ -2432,8 +2437,9 @@ int usbvision_set_alternate(struct usb_u
 		PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
 		errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
 		if (errCode < 0) {
-			err ("cannot change alternate number to %d (error=%i)",
-							dev->ifaceAlt, errCode);
+			dev_err(&dev->dev->dev,
+				"cannot change alternate number to %d (error=%i)\n",
+					dev->ifaceAlt, errCode);
 			return errCode;
 		}
 	}
@@ -2484,7 +2490,8 @@ int usbvision_init_isoc(struct usb_usbvi
 
 		urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
 		if (urb == NULL) {
-			err("%s: usb_alloc_urb() failed", __func__);
+			dev_err(&usbvision->dev->dev,
+				"%s: usb_alloc_urb() failed\n", __func__);
 			return -ENOMEM;
 		}
 		usbvision->sbuf[bufIdx].urb = urb;
@@ -2496,7 +2503,7 @@ int usbvision_init_isoc(struct usb_usbvi
 		urb->dev = dev;
 		urb->context = usbvision;
 		urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
-		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 		urb->interval = 1;
 		urb->transfer_buffer = usbvision->sbuf[bufIdx].data;
 		urb->complete = usbvision_isocIrq;
@@ -2516,8 +2523,9 @@ int usbvision_init_isoc(struct usb_usbvi
 			errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
 						 GFP_KERNEL);
 		if (errCode) {
-			err("%s: usb_submit_urb(%d) failed: error %d",
-			    __func__, bufIdx, errCode);
+			dev_err(&usbvision->dev->dev,
+				"%s: usb_submit_urb(%d) failed: error %d\n",
+					__func__, bufIdx, errCode);
 		}
 	}
 
@@ -2566,8 +2574,9 @@ void usbvision_stop_isoc(struct usb_usbv
 		errCode = usb_set_interface(usbvision->dev, usbvision->iface,
 					    usbvision->ifaceAlt);
 		if (errCode < 0) {
-			err("%s: usb_set_interface() failed: error %d",
-			    __func__, errCode);
+			dev_err(&usbvision->dev->dev,
+				"%s: usb_set_interface() failed: error %d\n",
+					__func__, errCode);
 			usbvision->last_error = errCode;
 		}
 		regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
@@ -2588,7 +2597,6 @@ int usbvision_muxsel(struct usb_usbvisio
 	/* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
 	int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
 	int audio[]= {1, 0, 0, 0};
-	struct v4l2_routing route;
 	//channel 0 is TV with audiochannel 1 (tuner mono)
 	//channel 1 is Composite with audio channel 0 (line in)
 	//channel 2 is S-Video with audio channel 0 (line in)
@@ -2621,9 +2629,7 @@ int usbvision_muxsel(struct usb_usbvisio
 			mode[2] = SAA7115_SVIDEO1;
 			break;
 	}
-	route.input = mode[channel];
-	route.output = 0;
-	call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route);
+	call_all(usbvision, video, s_routing, mode[channel], 0, 0);
 	usbvision_set_audio(usbvision, audio[channel]);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision.h linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision.h	2009-06-09 23:05:27.000000000 -0400
@@ -6,7 +6,7 @@
  *                         Dwaine Garden <dwainegarden@rogers.com>
  *
  *
- * Report problems to v4l MailingList : http://www.redhat.com/mailman/listinfo/video4linux-list
+ * Report problems to v4l MailingList: linux-media@vger.kernel.org
  *
  * This module is part of usbvision driver project.
  * Updates to driver completed by Dwaine P. Garden
@@ -35,7 +35,7 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include <linux/videodev2.h>
 
@@ -357,13 +357,13 @@ extern struct usbvision_device_data_st u
 extern struct usb_device_id usbvision_table[];
 
 struct usb_usbvision {
+	struct v4l2_device v4l2_dev;
 	struct video_device *vdev;         				/* Video Device */
 	struct video_device *rdev;               			/* Radio Device */
 	struct video_device *vbi; 					/* VBI Device   */
 
 	/* i2c Declaration Section*/
 	struct i2c_adapter i2c_adap;
-	struct i2c_client i2c_client;
 
 	struct urb *ctrlUrb;
 	unsigned char ctrlUrbBuffer[8];
@@ -374,7 +374,6 @@ struct usb_usbvision {
 	/* configuration part */
 	int have_tuner;
 	int tuner_type;
-	int tuner_addr;
 	int bridgeType;							// NT1003, NT1004, NT1005
 	int radio;
 	int video_inputs;						// # of inputs
@@ -464,6 +463,8 @@ struct usb_usbvision {
 	int ComprBlockTypes[4];
 };
 
+#define call_all(usbvision, o, f, args...) \
+	v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args)
 
 /* --------------------------------------------------------------- */
 /* defined in usbvision-i2c.c                                      */
@@ -475,7 +476,6 @@ struct usb_usbvision {
 /* ----------------------------------------------------------------------- */
 int usbvision_i2c_register(struct usb_usbvision *usbvision);
 int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
 
 /* defined in usbvision-core.c                                      */
 int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-i2c.c linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-i2c.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-i2c.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
@@ -119,7 +118,8 @@ static inline int usb_find_address(struc
 		/* try extended address code... */
 		ret = try_write_address(i2c_adap, addr, retries);
 		if (ret != 1) {
-			err("died at extended address code, while writing");
+			dev_err(&i2c_adap->dev,
+				"died at extended address code,	while writing\n");
 			return -EREMOTEIO;
 		}
 		add[0] = addr;
@@ -128,7 +128,8 @@ static inline int usb_find_address(struc
 			addr |= 0x01;
 			ret = try_read_address(i2c_adap, addr, retries);
 			if (ret != 1) {
-				err("died at extended address code, while reading");
+				dev_err(&i2c_adap->dev,
+					"died at extended address code, while reading\n");
 				return -EREMOTEIO;
 			}
 		}
@@ -200,142 +201,90 @@ static struct i2c_algorithm usbvision_al
 };
 
 
-/*
- * registering functions to load algorithms at runtime
- */
-static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
-{
-	PDEBUG(DBG_I2C, "I2C   debugging is enabled [i2c]");
-	PDEBUG(DBG_I2C, "ALGO   debugging is enabled [i2c]");
-
-	/* register new adapter to i2c module... */
-
-	adap->algo = &usbvision_algo;
-
-	adap->timeout = 100;	/* default values, should       */
-	adap->retries = 3;	/* be replaced by defines       */
-
-	i2c_add_adapter(adap);
-
-	PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
-
-	return 0;
-}
-
 /* ----------------------------------------------------------------------- */
 /* usbvision specific I2C functions                                        */
 /* ----------------------------------------------------------------------- */
 static struct i2c_adapter i2c_adap_template;
-static struct i2c_client i2c_client_template;
 
 int usbvision_i2c_register(struct usb_usbvision *usbvision)
 {
+	static unsigned short saa711x_addrs[] = {
+		0x4a >> 1, 0x48 >> 1,	/* SAA7111, SAA7111A and SAA7113 */
+		0x42 >> 1, 0x40 >> 1,	/* SAA7114, SAA7115 and SAA7118 */
+		I2C_CLIENT_END };
+
 	memcpy(&usbvision->i2c_adap, &i2c_adap_template,
 	       sizeof(struct i2c_adapter));
-	memcpy(&usbvision->i2c_client, &i2c_client_template,
-	       sizeof(struct i2c_client));
 
 	sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
 		" #%d", usbvision->vdev->num);
 	PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
 	usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
 
-	i2c_set_adapdata(&usbvision->i2c_adap, usbvision);
-	i2c_set_clientdata(&usbvision->i2c_client, usbvision);
-
-	usbvision->i2c_client.adapter = &usbvision->i2c_adap;
+	i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
 
 	if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
 		printk(KERN_ERR "usbvision_register: can't write reg\n");
 		return -EBUSY;
 	}
 
-#ifdef CONFIG_MODULES
+	PDEBUG(DBG_I2C, "I2C   debugging is enabled [i2c]");
+	PDEBUG(DBG_I2C, "ALGO   debugging is enabled [i2c]");
+
+	/* register new adapter to i2c module... */
+
+	usbvision->i2c_adap.algo = &usbvision_algo;
+
+	usbvision->i2c_adap.timeout = 100;	/* default values, should       */
+	usbvision->i2c_adap.retries = 3;	/* be replaced by defines       */
+
+	i2c_add_adapter(&usbvision->i2c_adap);
+
+	PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
+
 	/* Request the load of the i2c modules we need */
 	switch (usbvision_device_data[usbvision->DevModel].Codec) {
 	case CODEC_SAA7113:
-		request_module("saa7115");
-		break;
 	case CODEC_SAA7111:
-		request_module("saa7115");
+		v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+				&usbvision->i2c_adap, "saa7115",
+				"saa7115_auto", saa711x_addrs);
 		break;
 	}
 	if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
-		request_module("tuner");
-	}
-#endif
-
-	return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
-}
+		struct v4l2_subdev *sd;
+		enum v4l2_i2c_tuner_type type;
+		struct tuner_setup tun_setup;
 
-int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
-{
+		sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+				&usbvision->i2c_adap, "tuner",
+				"tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		/* depending on whether we found a demod or not, select
+		   the tuner type. */
+		type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
-	i2c_del_adapter(&(usbvision->i2c_adap));
+		sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+				&usbvision->i2c_adap, "tuner",
+				"tuner", v4l2_i2c_tuner_addrs(type));
 
-	PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
+		if (usbvision->tuner_type != -1) {
+			tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+			tun_setup.type = usbvision->tuner_type;
+			tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+			call_all(usbvision, tuner, s_type_addr, &tun_setup);
+		}
+	}
 
 	return 0;
 }
 
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
-		      void *arg)
-{
-	i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
-}
-
-static int attach_inform(struct i2c_client *client)
+int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
 {
-	struct usb_usbvision *usbvision;
-
-	usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-
-	switch (client->addr << 1) {
-		case 0x42 << 1:
-		case 0x43 << 1:
-		case 0x4a << 1:
-		case 0x4b << 1:
-			PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
-			break;
-		case 0x42:
-			PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
-			break;
-		case 0x4a:
-			PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.");
-			break;
-		case 0x48:
-			PDEBUG(DBG_I2C,"attach_inform: saa7111 detected.");
-			break;
-		case 0xa0:
-			PDEBUG(DBG_I2C,"attach_inform: eeprom detected.");
-			break;
-
-		default:
-			{
-				struct tuner_setup tun_setup;
-
-				PDEBUG(DBG_I2C,"attach inform: detected I2C address %x", client->addr << 1);
-				usbvision->tuner_addr = client->addr;
 
-				if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
-					tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
-					tun_setup.type = usbvision->tuner_type;
-					tun_setup.addr = usbvision->tuner_addr;
-					call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
-				}
-			}
-			break;
-	}
-	return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
-	struct usb_usbvision *usbvision;
+	i2c_del_adapter(&(usbvision->i2c_adap));
 
-	usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
+	PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
 
-	PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
 	return 0;
 }
 
@@ -511,14 +460,6 @@ static int usbvision_i2c_read(struct usb
 static struct i2c_adapter i2c_adap_template = {
 	.owner = THIS_MODULE,
 	.name              = "usbvision",
-	.id                = I2C_HW_B_BT848, /* FIXME */
-	.client_register   = attach_inform,
-	.client_unregister = detach_inform,
-	.class		   = I2C_CLASS_TV_ANALOG,
-};
-
-static struct i2c_client i2c_client_template = {
-	.name		= "usbvision internal",
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-video.c linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/usbvision/usbvision-video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/usbvision/usbvision-video.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * USB USBVISION Video device driver 0.9.9
+ * USB USBVISION Video device driver 0.9.10
  *
  *
  *
@@ -59,7 +59,6 @@
 #include <linux/spinlock.h>
 #include <asm/io.h>
 #include <linux/videodev2.h>
-#include <linux/video_decoder.h>
 #include <linux/i2c.h>
 
 #include <media/saa7115.h>
@@ -80,7 +79,7 @@
 #define DRIVER_LICENSE "GPL"
 #define USBVISION_DRIVER_VERSION_MAJOR 0
 #define USBVISION_DRIVER_VERSION_MINOR 9
-#define USBVISION_DRIVER_VERSION_PATCHLEVEL 9
+#define USBVISION_DRIVER_VERSION_PATCHLEVEL 10
 #define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\
 USBVISION_DRIVER_VERSION_MINOR,\
 USBVISION_DRIVER_VERSION_PATCHLEVEL)
@@ -212,7 +211,7 @@ static ssize_t show_hue(struct device *c
 	ctrl.id = V4L2_CID_HUE;
 	ctrl.value = 0;
 	if(usbvision->user)
-		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+		call_all(usbvision, core, g_ctrl, &ctrl);
 	return sprintf(buf, "%d\n", ctrl.value);
 }
 static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -227,7 +226,7 @@ static ssize_t show_contrast(struct devi
 	ctrl.id = V4L2_CID_CONTRAST;
 	ctrl.value = 0;
 	if(usbvision->user)
-		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+		call_all(usbvision, core, g_ctrl, &ctrl);
 	return sprintf(buf, "%d\n", ctrl.value);
 }
 static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -242,7 +241,7 @@ static ssize_t show_brightness(struct de
 	ctrl.id = V4L2_CID_BRIGHTNESS;
 	ctrl.value = 0;
 	if(usbvision->user)
-		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+		call_all(usbvision, core, g_ctrl, &ctrl);
 	return sprintf(buf, "%d\n", ctrl.value);
 }
 static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -257,7 +256,7 @@ static ssize_t show_saturation(struct de
 	ctrl.id = V4L2_CID_SATURATION;
 	ctrl.value = 0;
 	if(usbvision->user)
-		call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+		call_all(usbvision, core, g_ctrl, &ctrl);
 	return sprintf(buf, "%d\n", ctrl.value);
 }
 static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -329,7 +328,7 @@ static void usbvision_create_sysfs(struc
 			return;
 	} while (0);
 
-	err("%s error: %d\n", __func__, res);
+	dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
 }
 
 static void usbvision_remove_sysfs(struct video_device *vdev)
@@ -487,8 +486,9 @@ static int vidioc_g_register (struct fil
 	/* NT100x has a 8-bit register space */
 	errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
 	if (errCode < 0) {
-		err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
-		    __func__, errCode);
+		dev_err(&usbvision->vdev->dev,
+			"%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
+				__func__, errCode);
 		return errCode;
 	}
 	reg->val = errCode;
@@ -507,8 +507,9 @@ static int vidioc_s_register (struct fil
 	/* NT100x has a 8-bit register space */
 	errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
 	if (errCode < 0) {
-		err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
-		    __func__, errCode);
+		dev_err(&usbvision->vdev->dev,
+			"%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
+				__func__, errCode);
 		return errCode;
 	}
 	return 0;
@@ -524,8 +525,7 @@ static int vidioc_querycap (struct file
 	strlcpy(vc->card,
 		usbvision_device_data[usbvision->DevModel].ModelString,
 		sizeof(vc->card));
-	strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
-		sizeof(vc->bus_info));
+	usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
 	vc->version = USBVISION_DRIVER_VERSION;
 	vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
 		V4L2_CAP_AUDIO |
@@ -621,8 +621,7 @@ static int vidioc_s_std (struct file *fi
 	usbvision->tvnormId=*id;
 
 	mutex_lock(&usbvision->lock);
-	call_i2c_clients(usbvision, VIDIOC_S_STD,
-			 &usbvision->tvnormId);
+	call_all(usbvision, core, s_std, usbvision->tvnormId);
 	mutex_unlock(&usbvision->lock);
 	/* propagate the change to the decoder */
 	usbvision_muxsel(usbvision, usbvision->ctl_input);
@@ -644,7 +643,7 @@ static int vidioc_g_tuner (struct file *
 		strcpy(vt->name, "Television");
 	}
 	/* Let clients fill in the remainder of this struct */
-	call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt);
+	call_all(usbvision, tuner, g_tuner, vt);
 
 	return 0;
 }
@@ -658,7 +657,7 @@ static int vidioc_s_tuner (struct file *
 	if (!usbvision->have_tuner || vt->index)
 		return -EINVAL;
 	/* let clients handle this */
-	call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
+	call_all(usbvision, tuner, s_tuner, vt);
 
 	return 0;
 }
@@ -689,7 +688,7 @@ static int vidioc_s_frequency (struct fi
 		return -EINVAL;
 
 	usbvision->freq = freq->frequency;
-	call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq);
+	call_all(usbvision, tuner, s_frequency, freq);
 
 	return 0;
 }
@@ -698,7 +697,6 @@ static int vidioc_g_audio (struct file *
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
 
-	memset(a,0,sizeof(*a));
 	if(usbvision->radio) {
 		strcpy(a->name,"Radio");
 	} else {
@@ -722,12 +720,8 @@ static int vidioc_queryctrl (struct file
 			    struct v4l2_queryctrl *ctrl)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
-	int id=ctrl->id;
 
-	memset(ctrl,0,sizeof(*ctrl));
-	ctrl->id=id;
-
-	call_i2c_clients(usbvision, VIDIOC_QUERYCTRL, ctrl);
+	call_all(usbvision, core, queryctrl, ctrl);
 
 	if (!ctrl->type)
 		return -EINVAL;
@@ -739,7 +733,7 @@ static int vidioc_g_ctrl (struct file *f
 				struct v4l2_control *ctrl)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
-	call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
+	call_all(usbvision, core, g_ctrl, ctrl);
 
 	return 0;
 }
@@ -748,7 +742,7 @@ static int vidioc_s_ctrl (struct file *f
 				struct v4l2_control *ctrl)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
-	call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
+	call_all(usbvision, core, s_ctrl, ctrl);
 
 	return 0;
 }
@@ -763,8 +757,7 @@ static int vidioc_reqbufs (struct file *
 
 	/* Check input validity:
 	   the user must do a VIDEO CAPTURE and MMAP method. */
-	if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
-	   (vr->memory != V4L2_MEMORY_MMAP))
+	if (vr->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
 	if(usbvision->streaming == Stream_On) {
@@ -789,9 +782,6 @@ static int vidioc_querybuf (struct file
 
 	/* FIXME : must control
 	   that buffers are mapped (VIDIOC_REQBUFS has been called) */
-	if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
-		return -EINVAL;
-	}
 	if(vb->index>=usbvision->num_frames)  {
 		return -EINVAL;
 	}
@@ -825,9 +815,6 @@ static int vidioc_qbuf (struct file *fil
 	unsigned long lock_flags;
 
 	/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
-	if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
-		return -EINVAL;
-	}
 	if(vb->index>=usbvision->num_frames)  {
 		return -EINVAL;
 	}
@@ -862,9 +849,6 @@ static int vidioc_dqbuf (struct file *fi
 	struct usbvision_frame *f;
 	unsigned long lock_flags;
 
-	if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
 	if (list_empty(&(usbvision->outqueue))) {
 		if (usbvision->streaming == Stream_Idle)
 			return -EINVAL;
@@ -899,10 +883,9 @@ static int vidioc_dqbuf (struct file *fi
 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
-	int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	usbvision->streaming = Stream_On;
-	call_i2c_clients(usbvision,VIDIOC_STREAMON , &b);
+	call_all(usbvision, video, s_stream, 1);
 
 	return 0;
 }
@@ -911,7 +894,6 @@ static int vidioc_streamoff(struct file
 			    void *priv, enum v4l2_buf_type type)
 {
 	struct usb_usbvision *usbvision = video_drvdata(file);
-	int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -919,7 +901,7 @@ static int vidioc_streamoff(struct file
 	if(usbvision->streaming == Stream_On) {
 		usbvision_stream_interrupt(usbvision);
 		/* Stop all video streamings */
-		call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b);
+		call_all(usbvision, video, s_stream, 0);
 	}
 	usbvision_empty_framequeues(usbvision);
 
@@ -932,11 +914,8 @@ static int vidioc_enum_fmt_vid_cap (stru
 	if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
 		return -EINVAL;
 	}
-	vfd->flags = 0;
-	vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
 	vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
-	memset(vfd->reserved, 0, sizeof(vfd->reserved));
 	return 0;
 }
 
@@ -1042,7 +1021,7 @@ static ssize_t usbvision_v4l2_read(struc
 	if(usbvision->streaming != Stream_On) {
 		/* no stream is running, make it running ! */
 		usbvision->streaming = Stream_On;
-		call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
+		call_all(usbvision, video, s_stream, 1);
 	}
 
 	/* Then, enqueue as many frames as possible
@@ -1189,7 +1168,9 @@ static int usbvision_radio_open(struct f
 	mutex_lock(&usbvision->lock);
 
 	if (usbvision->user) {
-		err("%s: Someone tried to open an already opened USBVision Radio!", __func__);
+		dev_err(&usbvision->rdev->dev,
+			"%s: Someone tried to open an already opened USBVision Radio!\n",
+				__func__);
 		errCode = -EBUSY;
 	}
 	else {
@@ -1211,7 +1192,7 @@ static int usbvision_radio_open(struct f
 
 		// If so far no errors then we shall start the radio
 		usbvision->radio = 1;
-		call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
+		call_all(usbvision, tuner, s_radio);
 		usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
 		usbvision->user++;
 	}
@@ -1413,7 +1394,8 @@ static struct video_device *usbvision_vd
 	struct video_device *vdev;
 
 	if (usb_dev == NULL) {
-		err("%s: usbvision->dev is not set", __func__);
+		dev_err(&usbvision->dev->dev,
+			"%s: usbvision->dev is not set\n", __func__);
 		return NULL;
 	}
 
@@ -1423,7 +1405,7 @@ static struct video_device *usbvision_vd
 	}
 	*vdev = *vdev_template;
 //	vdev->minor   = -1;
-	vdev->parent  = &usb_dev->dev;
+	vdev->v4l2_dev = &usbvision->v4l2_dev;
 	snprintf(vdev->name, sizeof(vdev->name), "%s", name);
 	video_set_drvdata(vdev, usbvision);
 	return vdev;
@@ -1524,7 +1506,9 @@ static int __devinit usbvision_register_
 	return 0;
 
  err_exit:
-	err("USBVision[%d]: video_register_device() failed", usbvision->nr);
+	dev_err(&usbvision->dev->dev,
+		"USBVision[%d]: video_register_device() failed\n",
+			usbvision->nr);
 	usbvision_unregister_video(usbvision);
 	return -1;
 }
@@ -1538,37 +1522,35 @@ static int __devinit usbvision_register_
  * Returns NULL on error, a pointer to usb_usbvision else.
  *
  */
-static struct usb_usbvision *usbvision_alloc(struct usb_device *dev)
+static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
+					     struct usb_interface *intf)
 {
 	struct usb_usbvision *usbvision;
 
-	if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) ==
-	    NULL) {
-		goto err_exit;
-	}
+	usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL);
+	if (usbvision == NULL)
+		return NULL;
 
 	usbvision->dev = dev;
+	if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
+		goto err_free;
 
 	mutex_init(&usbvision->lock);	/* available */
 
 	// prepare control urb for control messages during interrupts
 	usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
-	if (usbvision->ctrlUrb == NULL) {
-		goto err_exit;
-	}
+	if (usbvision->ctrlUrb == NULL)
+		goto err_unreg;
 	init_waitqueue_head(&usbvision->ctrlUrb_wq);
 
 	usbvision_init_powerOffTimer(usbvision);
 
 	return usbvision;
 
-err_exit:
-	if (usbvision && usbvision->ctrlUrb) {
-		usb_free_urb(usbvision->ctrlUrb);
-	}
-	if (usbvision) {
-		kfree(usbvision);
-	}
+err_unreg:
+	v4l2_device_unregister(&usbvision->v4l2_dev);
+err_free:
+	kfree(usbvision);
 	return NULL;
 }
 
@@ -1598,6 +1580,7 @@ static void usbvision_release(struct usb
 		usb_free_urb(usbvision->ctrlUrb);
 	}
 
+	v4l2_device_unregister(&usbvision->v4l2_dev);
 	kfree(usbvision);
 
 	PDEBUG(DBG_PROBE, "success");
@@ -1675,20 +1658,21 @@ static int __devinit usbvision_probe(str
 	}
 	endpoint = &interface->endpoint[1].desc;
 	if (!usb_endpoint_xfer_isoc(endpoint)) {
-		err("%s: interface %d. has non-ISO endpoint!",
+		dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
 		    __func__, ifnum);
-		err("%s: Endpoint attributes %d",
+		dev_err(&intf->dev, "%s: Endpoint attributes %d",
 		    __func__, endpoint->bmAttributes);
 		return -ENODEV;
 	}
 	if (usb_endpoint_dir_out(endpoint)) {
-		err("%s: interface %d. has ISO OUT endpoint!",
+		dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
 		    __func__, ifnum);
 		return -ENODEV;
 	}
 
-	if ((usbvision = usbvision_alloc(dev)) == NULL) {
-		err("%s: couldn't allocate USBVision struct", __func__);
+	usbvision = usbvision_alloc(dev, intf);
+	if (usbvision == NULL) {
+		dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -1711,7 +1695,7 @@ static int __devinit usbvision_probe(str
 	usbvision->alt_max_pkt_size = kmalloc(32*
 					      usbvision->num_alt,GFP_KERNEL);
 	if (usbvision->alt_max_pkt_size == NULL) {
-		err("usbvision: out of memory!\n");
+		dev_err(&intf->dev, "usbvision: out of memory!\n");
 		mutex_unlock(&usbvision->lock);
 		return -ENOMEM;
 	}
@@ -1733,8 +1717,6 @@ static int __devinit usbvision_probe(str
 		usbvision->tuner_type = usbvision_device_data[model].TunerType;
 	}
 
-	usbvision->tuner_addr = ADDR_UNSET;
-
 	usbvision->DevModel = model;
 	usbvision->remove_pending = 0;
 	usbvision->iface = ifnum;
@@ -1772,7 +1754,8 @@ static void __devexit usbvision_disconne
 	PDEBUG(DBG_PROBE, "");
 
 	if (usbvision == NULL) {
-		err("%s: usb_get_intfdata() failed", __func__);
+		dev_err(&usbvision->dev->dev,
+			"%s: usb_get_intfdata() failed\n", __func__);
 		return;
 	}
 	usb_set_intfdata (intf, NULL);
@@ -1782,6 +1765,8 @@ static void __devexit usbvision_disconne
 	// At this time we ask to cancel outstanding URBs
 	usbvision_stop_isoc(usbvision);
 
+	v4l2_device_disconnect(&usbvision->v4l2_dev);
+
 	if (usbvision->power) {
 		usbvision_i2c_unregister(usbvision);
 		usbvision_power_off(usbvision);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/uvc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -9,7 +9,7 @@ config USB_VIDEO_CLASS
 config USB_VIDEO_CLASS_INPUT_EVDEV
 	bool "UVC input events device support"
 	default y
-	depends on USB_VIDEO_CLASS && INPUT
+	depends on USB_VIDEO_CLASS=INPUT || INPUT=y
 	---help---
 	  This option makes USB Video Class devices register an input device
 	  to report button events.
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_ctrl.c linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_ctrl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_ctrl.c	2009-06-09 23:05:27.000000000 -0400
@@ -786,7 +786,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video
 	memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
 	v4l2_ctrl->id = mapping->id;
 	v4l2_ctrl->type = mapping->v4l2_type;
-	strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+	strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
 	v4l2_ctrl->flags = 0;
 
 	if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_driver.c linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -314,7 +314,7 @@ static int uvc_parse_format(struct uvc_d
 		fmtdesc = uvc_format_by_guid(&buffer[5]);
 
 		if (fmtdesc != NULL) {
-			strncpy(format->name, fmtdesc->name,
+			strlcpy(format->name, fmtdesc->name,
 				sizeof format->name);
 			format->fcc = fmtdesc->fcc;
 		} else {
@@ -345,7 +345,7 @@ static int uvc_parse_format(struct uvc_d
 			return -EINVAL;
 		}
 
-		strncpy(format->name, "MJPEG", sizeof format->name);
+		strlcpy(format->name, "MJPEG", sizeof format->name);
 		format->fcc = V4L2_PIX_FMT_MJPEG;
 		format->flags = UVC_FMT_FLAG_COMPRESSED;
 		format->bpp = 0;
@@ -363,13 +363,13 @@ static int uvc_parse_format(struct uvc_d
 
 		switch (buffer[8] & 0x7f) {
 		case 0:
-			strncpy(format->name, "SD-DV", sizeof format->name);
+			strlcpy(format->name, "SD-DV", sizeof format->name);
 			break;
 		case 1:
-			strncpy(format->name, "SDL-DV", sizeof format->name);
+			strlcpy(format->name, "SDL-DV", sizeof format->name);
 			break;
 		case 2:
-			strncpy(format->name, "HD-DV", sizeof format->name);
+			strlcpy(format->name, "HD-DV", sizeof format->name);
 			break;
 		default:
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
@@ -379,7 +379,7 @@ static int uvc_parse_format(struct uvc_d
 			return -EINVAL;
 		}
 
-		strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+		strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
 			sizeof format->name);
 
 		format->fcc = V4L2_PIX_FMT_DV;
@@ -1526,7 +1526,7 @@ static int uvc_register_video(struct uvc
 	vdev->minor = -1;
 	vdev->fops = &uvc_fops;
 	vdev->release = video_device_release;
-	strncpy(vdev->name, dev->name, sizeof vdev->name);
+	strlcpy(vdev->name, dev->name, sizeof vdev->name);
 
 	/* Set the driver data before calling video_register_device, otherwise
 	 * uvc_v4l2_open might race us.
@@ -1621,7 +1621,7 @@ static int uvc_probe(struct usb_interfac
 	dev->quirks = id->driver_info | uvc_quirks_param;
 
 	if (udev->product != NULL)
-		strncpy(dev->name, udev->product, sizeof dev->name);
+		strlcpy(dev->name, udev->product, sizeof dev->name);
 	else
 		snprintf(dev->name, sizeof dev->name,
 			"UVC Camera (%04x:%04x)",
@@ -1726,14 +1726,17 @@ static int uvc_suspend(struct usb_interf
 static int __uvc_resume(struct usb_interface *intf, int reset)
 {
 	struct uvc_device *dev = usb_get_intfdata(intf);
-	int ret;
 
 	uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
 		intf->cur_altsetting->desc.bInterfaceNumber);
 
 	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) {
-		if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0)
-			return ret;
+		if (reset) {
+			int ret = uvc_ctrl_resume_device(dev);
+
+			if (ret < 0)
+				return ret;
+		}
 
 		return uvc_status_resume(dev);
 	}
@@ -1833,6 +1836,15 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0 },
+	/* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x058f,
+	  .idProduct		= 0x3820,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Apple Built-In iSight */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1852,6 +1864,15 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* ViMicro */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_VENDOR
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0ac8,
+	  .idProduct		= 0x0000,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
 	/* MT6227 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1879,7 +1900,7 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
-	/* Asus F9SG */
+	/* Syntek (Asus F9SG) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
 	  .idVendor		= 0x174f,
@@ -1896,6 +1917,15 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* Syntek (JAOtech Smart Terminal) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x174f,
+	  .idProduct		= 0x8a34,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
 	/* Lenovo Thinkpad SL500 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_status.c linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_status.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_status.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_status.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,26 +24,19 @@
 #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
 static int uvc_input_init(struct uvc_device *dev)
 {
-	struct usb_device *udev = dev->udev;
 	struct input_dev *input;
-	char *phys = NULL;
 	int ret;
 
 	input = input_allocate_device();
 	if (input == NULL)
 		return -ENOMEM;
 
-	phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
-			GFP_KERNEL);
-	if (phys == NULL) {
-		ret = -ENOMEM;
-		goto error;
-	}
-	sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+	usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+	strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
 
 	input->name = dev->name;
-	input->phys = phys;
-	usb_to_input_id(udev, &input->id);
+	input->phys = dev->input_phys;
+	usb_to_input_id(dev->udev, &input->id);
 	input->dev.parent = &dev->intf->dev;
 
 	__set_bit(EV_KEY, input->evbit);
@@ -57,7 +50,6 @@ static int uvc_input_init(struct uvc_dev
 
 error:
 	input_free_device(input);
-	kfree(phys);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_v4l2.c linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_v4l2.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_v4l2.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uv
 		return -EINVAL;
 
 	menu_info = &mapping->menu_info[query_menu->index];
-	strncpy(query_menu->name, menu_info->name, 32);
+	strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
 	return 0;
 }
 
@@ -486,10 +486,10 @@ static long uvc_v4l2_do_ioctl(struct fil
 		struct v4l2_capability *cap = arg;
 
 		memset(cap, 0, sizeof *cap);
-		strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
-		strncpy(cap->card, vdev->name, 32);
-		strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
-			sizeof cap->bus_info);
+		strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
+		strlcpy(cap->card, vdev->name, sizeof cap->card);
+		usb_make_path(video->dev->udev,
+			      cap->bus_info, sizeof(cap->bus_info));
 		cap->version = DRIVER_VERSION_NUMBER;
 		if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
@@ -620,7 +620,7 @@ static long uvc_v4l2_do_ioctl(struct fil
 
 		memset(input, 0, sizeof *input);
 		input->index = index;
-		strncpy(input->name, iterm->name, sizeof input->name);
+		strlcpy(input->name, iterm->name, sizeof input->name);
 		if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
 			input->type = V4L2_INPUT_TYPE_CAMERA;
 		break;
@@ -673,16 +673,22 @@ static long uvc_v4l2_do_ioctl(struct fil
 	{
 		struct v4l2_fmtdesc *fmt = arg;
 		struct uvc_format *format;
+		enum v4l2_buf_type type = fmt->type;
+		__u32 index = fmt->index;
 
 		if (fmt->type != video->streaming->type ||
 		    fmt->index >= video->streaming->nformats)
 			return -EINVAL;
 
+		memset(fmt, 0, sizeof(*fmt));
+		fmt->index = index;
+		fmt->type = type;
+
 		format = &video->streaming->format[fmt->index];
 		fmt->flags = 0;
 		if (format->flags & UVC_FMT_FLAG_COMPRESSED)
 			fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
-		strncpy(fmt->description, format->name,
+		strlcpy(fmt->description, format->name,
 			sizeof fmt->description);
 		fmt->description[sizeof fmt->description - 1] = 0;
 		fmt->pixelformat = format->fcc;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_video.c linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_video.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvc_video.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvc_video.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *de
 	return 0;
 }
 
-static void uvc_fixup_buffer_size(struct uvc_video_device *video,
+static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl)
 {
 	struct uvc_format *format;
@@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct
 	      video->dev->uvc_version < 0x0110))
 		ctrl->dwMaxVideoFrameSize =
 			frame->dwMaxVideoFrameBufferSize;
+
+	if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+	    video->streaming->intf->num_altsetting > 1) {
+		u32 interval;
+		u32 bandwidth;
+
+		interval = (ctrl->dwFrameInterval > 100000)
+			 ? ctrl->dwFrameInterval
+			 : frame->dwFrameInterval[0];
+
+		/* Compute a bandwidth estimation by multiplying the frame
+		 * size by the number of video frames per second, divide the
+		 * result by the number of USB frames (or micro-frames for
+		 * high-speed devices) per second and add the UVC header size
+		 * (assumed to be 12 bytes long).
+		 */
+		bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
+		bandwidth *= 10000000 / interval + 1;
+		bandwidth /= 1000;
+		if (video->dev->udev->speed == USB_SPEED_HIGH)
+			bandwidth /= 8;
+		bandwidth += 12;
+
+		ctrl->dwMaxPayloadTransferSize = bandwidth;
+	}
 }
 
 static int uvc_get_video_ctrl(struct uvc_video_device *video,
@@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc
 		ctrl->bMaxVersion = 0;
 	}
 
-	/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
-	 * Try to get the value from the format and frame descriptors.
+	/* Some broken devices return null or wrong dwMaxVideoFrameSize and
+	 * dwMaxPayloadTransferSize fields. Try to get the value from the
+	 * format and frame descriptors.
 	 */
-	uvc_fixup_buffer_size(video, ctrl);
+	uvc_fixup_video_ctrl(video, ctrl);
 	ret = 0;
 
 out:
@@ -540,6 +566,9 @@ static void uvc_video_decode_bulk(struct
 	u8 *mem;
 	int len, ret;
 
+	if (urb->actual_length == 0)
+		return;
+
 	mem = urb->transfer_buffer;
 	len = urb->actual_length;
 	video->bulk.payload_size += len;
@@ -699,27 +728,47 @@ static void uvc_free_urb_buffers(struct
  * already allocated when resuming from suspend, in which case it will
  * return without touching the buffers.
  *
- * Return 0 on success or -ENOMEM when out of memory.
+ * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
+ * system is too low on memory try successively smaller numbers of packets
+ * until allocation succeeds.
+ *
+ * Return the number of allocated packets on success or 0 when out of memory.
  */
 static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
-	unsigned int size)
+	unsigned int size, unsigned int psize, gfp_t gfp_flags)
 {
+	unsigned int npackets;
 	unsigned int i;
 
 	/* Buffers are already allocated, bail out. */
 	if (video->urb_size)
-		return 0;
+		return video->urb_size / psize;
 
-	for (i = 0; i < UVC_URBS; ++i) {
-		video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
-			size, GFP_KERNEL, &video->urb_dma[i]);
-		if (video->urb_buffer[i] == NULL) {
-			uvc_free_urb_buffers(video);
-			return -ENOMEM;
+	/* Compute the number of packets. Bulk endpoints might transfer UVC
+	 * payloads accross multiple URBs.
+	 */
+	npackets = DIV_ROUND_UP(size, psize);
+	if (npackets > UVC_MAX_PACKETS)
+		npackets = UVC_MAX_PACKETS;
+
+	/* Retry allocations until one succeed. */
+	for (; npackets > 1; npackets /= 2) {
+		for (i = 0; i < UVC_URBS; ++i) {
+			video->urb_buffer[i] = usb_buffer_alloc(
+				video->dev->udev, psize * npackets,
+				gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
+			if (!video->urb_buffer[i]) {
+				uvc_free_urb_buffers(video);
+				break;
+			}
+		}
+
+		if (i == UVC_URBS) {
+			video->urb_size = psize * npackets;
+			return npackets;
 		}
 	}
 
-	video->urb_size = size;
 	return 0;
 }
 
@@ -753,29 +802,19 @@ static int uvc_init_video_isoc(struct uv
 {
 	struct urb *urb;
 	unsigned int npackets, i, j;
-	__u16 psize;
-	__u32 size;
+	u16 psize;
+	u32 size;
 
-	/* Compute the number of isochronous packets to allocate by dividing
-	 * the maximum video frame size by the packet size. Limit the result
-	 * to UVC_MAX_ISO_PACKETS.
-	 */
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize);
 	psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-
 	size = video->streaming->ctrl.dwMaxVideoFrameSize;
-	if (size > UVC_MAX_FRAME_SIZE)
-		return -EINVAL;
 
-	npackets = DIV_ROUND_UP(size, psize);
-	if (npackets > UVC_MAX_ISO_PACKETS)
-		npackets = UVC_MAX_ISO_PACKETS;
+	npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+	if (npackets == 0)
+		return -ENOMEM;
 
 	size = npackets * psize;
 
-	if (uvc_alloc_urb_buffers(video, size) < 0)
-		return -ENOMEM;
-
 	for (i = 0; i < UVC_URBS; ++i) {
 		urb = usb_alloc_urb(npackets, gfp_flags);
 		if (urb == NULL) {
@@ -814,25 +853,20 @@ static int uvc_init_video_bulk(struct uv
 	struct usb_host_endpoint *ep, gfp_t gfp_flags)
 {
 	struct urb *urb;
-	unsigned int pipe, i;
-	__u16 psize;
-	__u32 size;
+	unsigned int npackets, pipe, i;
+	u16 psize;
+	u32 size;
 
-	/* Compute the bulk URB size. Some devices set the maximum payload
-	 * size to a value too high for memory-constrained devices. We must
-	 * then transfer the payload accross multiple URBs. To be consistant
-	 * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
-	 * URB.
-	 */
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
 	size = video->streaming->ctrl.dwMaxPayloadTransferSize;
 	video->bulk.max_payload_size = size;
-	if (size > psize * UVC_MAX_ISO_PACKETS)
-		size = psize * UVC_MAX_ISO_PACKETS;
 
-	if (uvc_alloc_urb_buffers(video, size) < 0)
+	npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+	if (npackets == 0)
 		return -ENOMEM;
 
+	size = npackets * psize;
+
 	if (usb_endpoint_dir_in(&ep->desc))
 		pipe = usb_rcvbulkpipe(video->dev->udev,
 				       ep->desc.bEndpointAddress);
@@ -1021,11 +1055,20 @@ int uvc_video_init(struct uvc_video_devi
 	 */
 	usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
 
-	/* Some webcams don't suport GET_DEF requests on the probe control. We
-	 * fall back to GET_CUR if GET_DEF fails.
+	/* Set the streaming probe control with default streaming parameters
+	 * retrieved from the device. Webcams that don't suport GET_DEF
+	 * requests on the probe control will just keep their current streaming
+	 * parameters.
 	 */
-	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
-	    (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+	if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0)
+		uvc_set_video_ctrl(video, probe, 1);
+
+	/* Initialize the streaming parameters with the probe control current
+	 * value. This makes sure SET_CUR requests on the streaming commit
+	 * control will always use values retrieved from a successful GET_CUR
+	 * request on the probe control, as required by the UVC specification.
+	 */
+	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
 		return ret;
 
 	/* Check if the default format descriptor exists. Use the first
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvcvideo.h linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvcvideo.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/uvc/uvcvideo.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/uvc/uvcvideo.h	2009-06-09 23:05:27.000000000 -0400
@@ -296,10 +296,8 @@ struct uvc_xu_control {
 
 /* Number of isochronous URBs. */
 #define UVC_URBS		5
-/* Maximum number of packets per isochronous URB. */
-#define UVC_MAX_ISO_PACKETS	40
-/* Maximum frame size in bytes, for sanity checking. */
-#define UVC_MAX_FRAME_SIZE	(16*1024*1024)
+/* Maximum number of packets per URB. */
+#define UVC_MAX_PACKETS		32
 /* Maximum number of video buffers. */
 #define UVC_MAX_VIDEO_BUFFERS	32
 /* Maximum status buffer size in bytes of interrupt URB. */
@@ -316,6 +314,7 @@ struct uvc_xu_control {
 #define UVC_QUIRK_STREAM_NO_FID		0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
 #define UVC_QUIRK_PRUNE_CONTROLS	0x00000040
+#define UVC_QUIRK_FIX_BANDWIDTH		0x00000080
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
@@ -649,6 +648,7 @@ struct uvc_device {
 	struct urb *int_urb;
 	__u8 *status;
 	struct input_dev *input;
+	char input_phys[64];
 
 	/* Video Streaming interfaces */
 	struct list_head streaming;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l1-compat.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l1-compat.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l1-compat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l1-compat.c	2009-06-09 23:05:27.000000000 -0400
@@ -575,6 +575,8 @@ static noinline long v4l1_compat_get_inp
 			chan->norm = VIDEO_MODE_NTSC;
 		if (sid & V4L2_STD_SECAM)
 			chan->norm = VIDEO_MODE_SECAM;
+		if (sid == V4L2_STD_ALL)
+			chan->norm = VIDEO_MODE_AUTO;
 	}
 done:
 	return err;
@@ -601,6 +603,9 @@ static noinline long v4l1_compat_set_inp
 	case VIDEO_MODE_SECAM:
 		sid = V4L2_STD_SECAM;
 		break;
+	case VIDEO_MODE_AUTO:
+		sid = V4L2_STD_ALL;
+		break;
 	}
 	if (0 != sid) {
 		err = drv(file, VIDIOC_S_STD, &sid);
@@ -804,9 +809,9 @@ static noinline long v4l1_compat_select_
 
 	t.index = tun->tuner;
 
-	err = drv(file, VIDIOC_S_INPUT, &t);
+	err = drv(file, VIDIOC_S_TUNER, &t);
 	if (err < 0)
-		dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err);
+		dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err);
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-common.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-common.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-common.c	2009-06-09 23:05:27.000000000 -0400
@@ -334,6 +334,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
 		"Aperture Priority Mode",
 		NULL
 	};
+	static const char *colorfx[] = {
+		"None",
+		"Black & White",
+		"Sepia",
+		NULL
+	};
 
 	switch (id) {
 		case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -370,6 +376,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
 			return camera_power_line_frequency;
 		case V4L2_CID_EXPOSURE_AUTO:
 			return camera_exposure_auto;
+		case V4L2_CID_COLORFX:
+			return colorfx;
 		default:
 			return NULL;
 	}
@@ -382,16 +390,16 @@ const char *v4l2_ctrl_get_name(u32 id)
 	switch (id) {
 	/* USER controls */
 	case V4L2_CID_USER_CLASS: 		return "User Controls";
+	case V4L2_CID_BRIGHTNESS: 		return "Brightness";
+	case V4L2_CID_CONTRAST: 		return "Contrast";
+	case V4L2_CID_SATURATION: 		return "Saturation";
+	case V4L2_CID_HUE: 			return "Hue";
 	case V4L2_CID_AUDIO_VOLUME: 		return "Volume";
-	case V4L2_CID_AUDIO_MUTE: 		return "Mute";
 	case V4L2_CID_AUDIO_BALANCE: 		return "Balance";
 	case V4L2_CID_AUDIO_BASS: 		return "Bass";
 	case V4L2_CID_AUDIO_TREBLE: 		return "Treble";
+	case V4L2_CID_AUDIO_MUTE: 		return "Mute";
 	case V4L2_CID_AUDIO_LOUDNESS: 		return "Loudness";
-	case V4L2_CID_BRIGHTNESS: 		return "Brightness";
-	case V4L2_CID_CONTRAST: 		return "Contrast";
-	case V4L2_CID_SATURATION: 		return "Saturation";
-	case V4L2_CID_HUE: 			return "Hue";
 	case V4L2_CID_BLACK_LEVEL:		return "Black Level";
 	case V4L2_CID_AUTO_WHITE_BALANCE:	return "White Balance, Automatic";
 	case V4L2_CID_DO_WHITE_BALANCE:		return "Do White Balance";
@@ -412,6 +420,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_BACKLIGHT_COMPENSATION:	return "Backlight Compensation";
 	case V4L2_CID_CHROMA_AGC:		return "Chroma AGC";
 	case V4L2_CID_COLOR_KILLER:		return "Color Killer";
+	case V4L2_CID_COLORFX:			return "Color Effects";
 
 	/* MPEG controls */
 	case V4L2_CID_MPEG_CLASS: 		return "MPEG Encoder Controls";
@@ -490,16 +499,25 @@ int v4l2_ctrl_query_fill(struct v4l2_que
 	case V4L2_CID_HFLIP:
 	case V4L2_CID_VFLIP:
 	case V4L2_CID_HUE_AUTO:
+	case V4L2_CID_CHROMA_AGC:
+	case V4L2_CID_COLOR_KILLER:
 	case V4L2_CID_MPEG_AUDIO_MUTE:
 	case V4L2_CID_MPEG_VIDEO_MUTE:
 	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 	case V4L2_CID_MPEG_VIDEO_PULLDOWN:
 	case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+	case V4L2_CID_FOCUS_AUTO:
 	case V4L2_CID_PRIVACY:
 		qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
 		min = 0;
 		max = step = 1;
 		break;
+	case V4L2_CID_PAN_RESET:
+	case V4L2_CID_TILT_RESET:
+		qctrl->type = V4L2_CTRL_TYPE_BUTTON;
+		qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+		min = max = step = def = 0;
+		break;
 	case V4L2_CID_POWER_LINE_FREQUENCY:
 	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
@@ -517,6 +535,7 @@ int v4l2_ctrl_query_fill(struct v4l2_que
 	case V4L2_CID_MPEG_STREAM_TYPE:
 	case V4L2_CID_MPEG_STREAM_VBI_FMT:
 	case V4L2_CID_EXPOSURE_AUTO:
+	case V4L2_CID_COLORFX:
 		qctrl->type = V4L2_CTRL_TYPE_MENU;
 		step = 1;
 		break;
@@ -547,161 +566,29 @@ int v4l2_ctrl_query_fill(struct v4l2_que
 	case V4L2_CID_CONTRAST:
 	case V4L2_CID_SATURATION:
 	case V4L2_CID_HUE:
+	case V4L2_CID_RED_BALANCE:
+	case V4L2_CID_BLUE_BALANCE:
+	case V4L2_CID_GAMMA:
+	case V4L2_CID_SHARPNESS:
 		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 		break;
+	case V4L2_CID_PAN_RELATIVE:
+	case V4L2_CID_TILT_RELATIVE:
+	case V4L2_CID_FOCUS_RELATIVE:
+	case V4L2_CID_ZOOM_RELATIVE:
+		qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+		break;
 	}
 	qctrl->minimum = min;
 	qctrl->maximum = max;
 	qctrl->step = step;
 	qctrl->default_value = def;
 	qctrl->reserved[0] = qctrl->reserved[1] = 0;
-	snprintf(qctrl->name, sizeof(qctrl->name), name);
+	strlcpy(qctrl->name, name, sizeof(qctrl->name));
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 
-/* Fill in a struct v4l2_queryctrl with standard values based on
-   the control ID. */
-int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
-{
-	switch (qctrl->id) {
-	/* USER controls */
-	case V4L2_CID_USER_CLASS:
-	case V4L2_CID_MPEG_CLASS:
-		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
-	case V4L2_CID_AUDIO_MUTE:
-	case V4L2_CID_AUDIO_LOUDNESS:
-		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-	case V4L2_CID_AUDIO_BALANCE:
-	case V4L2_CID_AUDIO_BASS:
-	case V4L2_CID_AUDIO_TREBLE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
-	case V4L2_CID_BRIGHTNESS:
-		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
-	case V4L2_CID_CONTRAST:
-	case V4L2_CID_SATURATION:
-		return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
-	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
-
-	/* MPEG controls */
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
-				V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
-				V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
-	case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_L1_BITRATE_32K,
-				V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
-				V4L2_MPEG_AUDIO_L1_BITRATE_256K);
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_L2_BITRATE_32K,
-				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
-				V4L2_MPEG_AUDIO_L2_BITRATE_224K);
-	case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_L3_BITRATE_32K,
-				V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
-				V4L2_MPEG_AUDIO_L3_BITRATE_192K);
-	case V4L2_CID_MPEG_AUDIO_AAC_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000);
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_32K,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_384K);
-	case V4L2_CID_MPEG_AUDIO_MODE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_MODE_STEREO,
-				V4L2_MPEG_AUDIO_MODE_MONO, 1,
-				V4L2_MPEG_AUDIO_MODE_STEREO);
-	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
-				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
-				V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
-	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_EMPHASIS_NONE,
-				V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
-				V4L2_MPEG_AUDIO_EMPHASIS_NONE);
-	case V4L2_CID_MPEG_AUDIO_CRC:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_CRC_NONE,
-				V4L2_MPEG_AUDIO_CRC_CRC16, 1,
-				V4L2_MPEG_AUDIO_CRC_NONE);
-	case V4L2_CID_MPEG_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ASPECT_1x1,
-				V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
-				V4L2_MPEG_VIDEO_ASPECT_4x3);
-	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
-		return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
-	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
-	case V4L2_CID_MPEG_VIDEO_PULLDOWN:
-		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
-	case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
-		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
-	case V4L2_CID_MPEG_VIDEO_MUTE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
-	case V4L2_CID_MPEG_VIDEO_MUTE_YUV:  /* Init YUV (really YCbCr) to black */
-		return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
-	case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
-		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
-	case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
-		return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
-	case V4L2_CID_MPEG_STREAM_VBI_FMT:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_STREAM_VBI_FMT_NONE,
-				V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
-				V4L2_MPEG_STREAM_VBI_FMT_NONE);
-	default:
-		return -EINVAL;
-	}
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
-
 /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
    the menu. The qctrl pointer may be NULL, in which case it is ignored.
    If menu_items is NULL, then the menu items are retrieved using
@@ -720,7 +607,7 @@ int v4l2_ctrl_query_menu(struct v4l2_que
 	for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
 	if (menu_items[i] == NULL || menu_items[i][0] == '\0')
 		return -EINVAL;
-	snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
+	strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_ctrl_query_menu);
@@ -737,8 +624,8 @@ int v4l2_ctrl_query_menu_valid_items(str
 		return -EINVAL;
 	while (*ids != V4L2_CTRL_MENU_IDS_END) {
 		if (*ids++ == qmenu->index) {
-			snprintf(qmenu->name, sizeof(qmenu->name),
-				       menu_items[qmenu->index]);
+			strlcpy(qmenu->name, menu_items[qmenu->index],
+					sizeof(qmenu->name));
 			return 0;
 		}
 	}
@@ -749,7 +636,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid
 /* ctrl_classes points to an array of u32 pointers, the last element is
    a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
    Each array must be sorted low to high and belong to the same control
-   class. The array of u32 pointer must also be sorted, from low class IDs
+   class. The array of u32 pointers must also be sorted, from low class IDs
    to high class IDs.
 
    This function returns the first ID that follows after the given ID.
@@ -852,33 +739,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client
 
 /* ----------------------------------------------------------------- */
 
-/* Helper function for I2C legacy drivers */
-
-int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
-		const char *name,
-		int (*probe)(struct i2c_client *, const struct i2c_device_id *))
-{
-	struct i2c_client *client;
-	int err;
-
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = driver;
-	strlcpy(client->name, name, sizeof(client->name));
+/* I2C Helper functions */
 
-	err = probe(client, NULL);
-	if (err == 0) {
-		i2c_attach_client(client);
-	} else {
-		kfree(client);
-	}
-	return err != -ENOMEM ? 0 : err;
-}
-EXPORT_SYMBOL(v4l2_i2c_attach);
 
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 		const struct v4l2_subdev_ops *ops)
@@ -898,22 +760,20 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
 
 
-/* Load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
-   returns the v4l2_device and that i2c_get_clientdata(client)
-   returns the v4l2_subdev. */
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
+/* Load an i2c sub-device. */
+struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter,
 		const char *module_name, const char *client_type, u8 addr)
 {
-	struct v4l2_device *dev = i2c_get_adapdata(adapter);
 	struct v4l2_subdev *sd = NULL;
 	struct i2c_client *client;
 	struct i2c_board_info info;
 
-	BUG_ON(!dev);
-#ifdef MODULE
+	BUG_ON(!v4l2_dev);
+
 	if (module_name)
 		request_module(module_name);
-#endif
+
 	/* Setup the i2c board info with the device type and
 	   the device address. */
 	memset(&info, 0, sizeof(info));
@@ -927,41 +787,44 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(
 	   We need better support from the kernel so that we
 	   can easily wait for the load to finish. */
 	if (client == NULL || client->driver == NULL)
-		return NULL;
+		goto error;
 
 	/* Lock the module so we can safely get the v4l2_subdev pointer */
 	if (!try_module_get(client->driver->driver.owner))
-		return NULL;
+		goto error;
 	sd = i2c_get_clientdata(client);
 
 	/* Register with the v4l2_device which increases the module's
 	   use count as well. */
-	if (v4l2_device_register_subdev(dev, sd))
+	if (v4l2_device_register_subdev(v4l2_dev, sd))
 		sd = NULL;
 	/* Decrease the module use count to match the first try_module_get. */
 	module_put(client->driver->driver.owner);
-	return sd;
 
+error:
+	/* If we have a client but no subdev, then something went wrong and
+	   we must unregister the client. */
+	if (client && sd == NULL)
+		i2c_unregister_device(client);
+	return sd;
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
 
-/* Probe and load an i2c sub-device. It assumes that i2c_get_adapdata(adapter)
-   returns the v4l2_device and that i2c_get_clientdata(client)
-   returns the v4l2_subdev. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
+/* Probe and load an i2c sub-device. */
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
+	struct i2c_adapter *adapter,
 	const char *module_name, const char *client_type,
 	const unsigned short *addrs)
 {
-	struct v4l2_device *dev = i2c_get_adapdata(adapter);
 	struct v4l2_subdev *sd = NULL;
 	struct i2c_client *client = NULL;
 	struct i2c_board_info info;
 
-	BUG_ON(!dev);
-#ifdef MODULE
+	BUG_ON(!v4l2_dev);
+
 	if (module_name)
 		request_module(module_name);
-#endif
+
 	/* Setup the i2c board info with the device type and
 	   the device address. */
 	memset(&info, 0, sizeof(info));
@@ -974,21 +837,83 @@ struct v4l2_subdev *v4l2_i2c_new_probed_
 	   We need better support from the kernel so that we
 	   can easily wait for the load to finish. */
 	if (client == NULL || client->driver == NULL)
-		return NULL;
+		goto error;
 
 	/* Lock the module so we can safely get the v4l2_subdev pointer */
 	if (!try_module_get(client->driver->driver.owner))
-		return NULL;
+		goto error;
 	sd = i2c_get_clientdata(client);
 
 	/* Register with the v4l2_device which increases the module's
 	   use count as well. */
-	if (v4l2_device_register_subdev(dev, sd))
+	if (v4l2_device_register_subdev(v4l2_dev, sd))
 		sd = NULL;
 	/* Decrease the module use count to match the first try_module_get. */
 	module_put(client->driver->driver.owner);
+
+error:
+	/* If we have a client but no subdev, then something went wrong and
+	   we must unregister the client. */
+	if (client && sd == NULL)
+		i2c_unregister_device(client);
 	return sd;
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
 
+struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter,
+		const char *module_name, const char *client_type, u8 addr)
+{
+	unsigned short addrs[2] = { addr, I2C_CLIENT_END };
+
+	return v4l2_i2c_new_probed_subdev(v4l2_dev, adapter,
+			module_name, client_type, addrs);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
+
+/* Return i2c client address of v4l2_subdev. */
+unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return client ? client->addr : I2C_CLIENT_END;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
+
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+   addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+	static const unsigned short radio_addrs[] = {
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
+		0x10,
+#endif
+		0x60,
+		I2C_CLIENT_END
+	};
+	static const unsigned short demod_addrs[] = {
+		0x42, 0x43, 0x4a, 0x4b,
+		I2C_CLIENT_END
+	};
+	static const unsigned short tv_addrs[] = {
+		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
+		0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+		0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+		I2C_CLIENT_END
+	};
+
+	switch (type) {
+	case ADDRS_RADIO:
+		return radio_addrs;
+	case ADDRS_DEMOD:
+		return demod_addrs;
+	case ADDRS_TV:
+		return tv_addrs;
+	case ADDRS_TV_WITH_DEMOD:
+		return tv_addrs + 4;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-compat-ioctl32.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-compat-ioctl32.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-compat-ioctl32.c	2009-06-09 23:05:27.000000000 -0400
@@ -1047,7 +1047,6 @@ long v4l2_compat_ioctl32(struct file *fi
 	case VIDIOC_DBG_S_REGISTER:
 	case VIDIOC_DBG_G_REGISTER:
 	case VIDIOC_DBG_G_CHIP_IDENT:
-	case VIDIOC_G_CHIP_IDENT_OLD:
 	case VIDIOC_S_HW_FREQ_SEEK:
 		ret = do_video_ioctl(file, cmd, arg);
 		break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-dev.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-dev.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-dev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-dev.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,6 +198,23 @@ static long v4l2_unlocked_ioctl(struct f
 	return vdev->fops->unlocked_ioctl(filp, cmd, arg);
 }
 
+#ifdef CONFIG_MMU
+#define v4l2_get_unmapped_area NULL
+#else
+static unsigned long v4l2_get_unmapped_area(struct file *filp,
+		unsigned long addr, unsigned long len, unsigned long pgoff,
+		unsigned long flags)
+{
+	struct video_device *vdev = video_devdata(filp);
+
+	if (!vdev->fops->get_unmapped_area)
+		return -ENOSYS;
+	if (video_is_unregistered(vdev))
+		return -ENODEV;
+	return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
+}
+#endif
+
 static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
 {
 	struct video_device *vdev = video_devdata(filp);
@@ -212,7 +229,7 @@ static int v4l2_mmap(struct file *filp,
 static int v4l2_open(struct inode *inode, struct file *filp)
 {
 	struct video_device *vdev;
-	int ret;
+	int ret = 0;
 
 	/* Check if the video device is available */
 	mutex_lock(&videodev_lock);
@@ -226,7 +243,9 @@ static int v4l2_open(struct inode *inode
 	/* and increase the device refcount */
 	video_get(vdev);
 	mutex_unlock(&videodev_lock);
-	ret = vdev->fops->open(filp);
+	if (vdev->fops->open)
+		ret = vdev->fops->open(filp);
+
 	/* decrease the refcount in case of an error */
 	if (ret)
 		video_put(vdev);
@@ -237,7 +256,10 @@ static int v4l2_open(struct inode *inode
 static int v4l2_release(struct inode *inode, struct file *filp)
 {
 	struct video_device *vdev = video_devdata(filp);
-	int ret = vdev->fops->release(filp);
+	int ret = 0;
+
+	if (vdev->fops->release)
+		vdev->fops->release(filp);
 
 	/* decrease the refcount unconditionally since the release()
 	   return value is ignored. */
@@ -250,6 +272,7 @@ static const struct file_operations v4l2
 	.read = v4l2_read,
 	.write = v4l2_write,
 	.open = v4l2_open,
+	.get_unmapped_area = v4l2_get_unmapped_area,
 	.mmap = v4l2_mmap,
 	.unlocked_ioctl = v4l2_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
@@ -265,6 +288,7 @@ static const struct file_operations v4l2
 	.read = v4l2_read,
 	.write = v4l2_write,
 	.open = v4l2_open,
+	.get_unmapped_area = v4l2_get_unmapped_area,
 	.mmap = v4l2_mmap,
 	.ioctl = v4l2_ioctl,
 #ifdef CONFIG_COMPAT
@@ -288,37 +312,38 @@ static const struct file_operations v4l2
  */
 static int get_index(struct video_device *vdev, int num)
 {
-	u32 used = 0;
-	const int max_index = sizeof(used) * 8 - 1;
+	/* This can be static since this function is called with the global
+	   videodev_lock held. */
+	static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
 	int i;
 
-	/* Currently a single v4l driver instance cannot create more than
-	   32 devices.
-	   Increase to u64 or an array of u32 if more are needed. */
-	if (num > max_index) {
+	if (num >= VIDEO_NUM_DEVICES) {
 		printk(KERN_ERR "videodev: %s num is too large\n", __func__);
 		return -EINVAL;
 	}
 
-	/* Some drivers do not set the parent. In that case always return 0. */
+	/* Some drivers do not set the parent. In that case always return
+	   num or 0. */
 	if (vdev->parent == NULL)
-		return 0;
+		return num >= 0 ? num : 0;
+
+	bitmap_zero(used, VIDEO_NUM_DEVICES);
 
 	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
 		if (video_device[i] != NULL &&
 		    video_device[i]->parent == vdev->parent) {
-			used |= 1 << video_device[i]->index;
+			set_bit(video_device[i]->index, used);
 		}
 	}
 
 	if (num >= 0) {
-		if (used & (1 << num))
+		if (test_bit(num, used))
 			return -ENFILE;
 		return num;
 	}
 
-	i = ffz(used);
-	return i > max_index ? -ENFILE : i;
+	i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
+	return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
 }
 
 int video_register_device(struct video_device *vdev, int type, int nr)
@@ -365,12 +390,11 @@ int video_register_device_index(struct v
 
 	/* A minor value of -1 marks this video device as never
 	   having been registered */
-	if (vdev)
-		vdev->minor = -1;
+	vdev->minor = -1;
 
 	/* the release callback MUST be present */
-	WARN_ON(!vdev || !vdev->release);
-	if (!vdev || !vdev->release)
+	WARN_ON(!vdev->release);
+	if (!vdev->release)
 		return -EINVAL;
 
 	/* Part 1: check device type */
@@ -395,7 +419,7 @@ int video_register_device_index(struct v
 
 	vdev->vfl_type = type;
 	vdev->cdev = NULL;
-	if (vdev->v4l2_dev)
+	if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
 		vdev->parent = vdev->v4l2_dev->dev;
 
 	/* Part 2: find a free minor, kernel number and device index. */
@@ -582,6 +606,7 @@ module_exit(videodev_exit)
 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
 
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-device.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-device.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-device.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,48 +26,66 @@
 
 int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
 {
-	if (dev == NULL || v4l2_dev == NULL)
+	if (v4l2_dev == NULL)
 		return -EINVAL;
-	/* Warn if we apparently re-register a device */
-	WARN_ON(dev_get_drvdata(dev) != NULL);
+
 	INIT_LIST_HEAD(&v4l2_dev->subdevs);
 	spin_lock_init(&v4l2_dev->lock);
 	v4l2_dev->dev = dev;
-	snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
-			dev->driver->name, dev->bus_id);
+	if (dev == NULL) {
+		/* If dev == NULL, then name must be filled in by the caller */
+		WARN_ON(!v4l2_dev->name[0]);
+		return 0;
+	}
+
+	/* Set name to driver name + device name if it is empty. */
+	if (!v4l2_dev->name[0])
+		snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
+			dev->driver->name, dev_name(dev));
+	if (dev_get_drvdata(dev))
+		v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n");
 	dev_set_drvdata(dev, v4l2_dev);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register);
 
+void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
+{
+	if (v4l2_dev->dev) {
+		dev_set_drvdata(v4l2_dev->dev, NULL);
+		v4l2_dev->dev = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
+
 void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
 {
 	struct v4l2_subdev *sd, *next;
 
-	if (v4l2_dev == NULL || v4l2_dev->dev == NULL)
+	if (v4l2_dev == NULL)
 		return;
-	dev_set_drvdata(v4l2_dev->dev, NULL);
-	/* unregister subdevs */
+	v4l2_device_disconnect(v4l2_dev);
+
+	/* Unregister subdevs */
 	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
 		v4l2_device_unregister_subdev(sd);
-
-	v4l2_dev->dev = NULL;
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister);
 
-int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd)
+int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
+						struct v4l2_subdev *sd)
 {
 	/* Check for valid input */
-	if (dev == NULL || sd == NULL || !sd->name[0])
+	if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
 		return -EINVAL;
 	/* Warn if we apparently re-register a subdev */
-	WARN_ON(sd->dev != NULL);
+	WARN_ON(sd->v4l2_dev != NULL);
 	if (!try_module_get(sd->owner))
 		return -ENODEV;
-	sd->dev = dev;
-	spin_lock(&dev->lock);
-	list_add_tail(&sd->list, &dev->subdevs);
-	spin_unlock(&dev->lock);
+	sd->v4l2_dev = v4l2_dev;
+	spin_lock(&v4l2_dev->lock);
+	list_add_tail(&sd->list, &v4l2_dev->subdevs);
+	spin_unlock(&v4l2_dev->lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
@@ -75,12 +93,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_s
 void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
 {
 	/* return if it isn't registered */
-	if (sd == NULL || sd->dev == NULL)
+	if (sd == NULL || sd->v4l2_dev == NULL)
 		return;
-	spin_lock(&sd->dev->lock);
+	spin_lock(&sd->v4l2_dev->lock);
 	list_del(&sd->list);
-	spin_unlock(&sd->dev->lock);
-	sd->dev = NULL;
+	spin_unlock(&sd->v4l2_dev->lock);
+	sd->v4l2_dev = NULL;
 	module_put(sd->owner);
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-ioctl.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 
 #define __OLD_VIDIOC_ /* To allow fixing old calls */
+#include <linux/videodev.h>
 #include <linux/videodev2.h>
 
 #ifdef CONFIG_VIDEO_V4L1
@@ -24,7 +25,7 @@
 #endif
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
+#include <media/v4l2-chip-ident.h>
 
 #define dbgarg(cmd, fmt, arg...) \
 		do {							\
@@ -41,6 +42,12 @@
 			printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
 		} while (0)
 
+/* Zero out the end of the struct pointed to by p.  Everthing after, but
+ * not including, the specified field is cleared. */
+#define CLEAR_AFTER_FIELD(p, field) \
+	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
+	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
+
 struct std_descr {
 	v4l2_std_id std;
 	const char *descr;
@@ -100,25 +107,27 @@ const char *v4l2_norm_to_name(v4l2_std_i
 }
 EXPORT_SYMBOL(v4l2_norm_to_name);
 
+/* Returns frame period for the given standard */
+void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
+{
+	if (id & V4L2_STD_525_60) {
+		frameperiod->numerator = 1001;
+		frameperiod->denominator = 30000;
+	} else {
+		frameperiod->numerator = 1;
+		frameperiod->denominator = 25;
+	}
+}
+EXPORT_SYMBOL(v4l2_video_std_frame_period);
+
 /* Fill in the fields of a v4l2_standard structure according to the
    'id' and 'transmission' parameters.  Returns negative on error.  */
 int v4l2_video_std_construct(struct v4l2_standard *vs,
 			     int id, const char *name)
 {
-	u32 index = vs->index;
-
-	memset(vs, 0, sizeof(struct v4l2_standard));
-	vs->index = index;
-	vs->id    = id;
-	if (id & V4L2_STD_525_60) {
-		vs->frameperiod.numerator = 1001;
-		vs->frameperiod.denominator = 30000;
-		vs->framelines = 525;
-	} else {
-		vs->frameperiod.numerator = 1;
-		vs->frameperiod.denominator = 25;
-		vs->framelines = 625;
-	}
+	vs->id = id;
+	v4l2_video_std_frame_period(id, &vs->frameperiod);
+	vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
 	strlcpy(vs->name, name, sizeof(vs->name));
 	return 0;
 }
@@ -272,45 +281,6 @@ static const char *v4l2_ioctls[] = {
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
-static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
-	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
-	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
-	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
-	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
-	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
-	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
-	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
-	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
-	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
-	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
-#endif
-	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
-
-	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
-	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
-	[_IOC_NR(TUNER_SET_CONFIG)]            = "TUNER_SET_CONFIG",
-
-	[_IOC_NR(VIDIOC_INT_S_TUNER_MODE)]     = "VIDIOC_INT_S_TUNER_MODE",
-	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
-	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
-	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
-	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ",
-	[_IOC_NR(VIDIOC_INT_S_STANDBY)]        = "VIDIOC_INT_S_STANDBY",
-	[_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)]  = "VIDIOC_INT_S_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)]  = "VIDIOC_INT_G_AUDIO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)]  = "VIDIOC_INT_S_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)]  = "VIDIOC_INT_G_VIDEO_ROUTING",
-	[_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)]   = "VIDIOC_INT_S_CRYSTAL_FREQ",
-	[_IOC_NR(VIDIOC_INT_INIT)]   	       = "VIDIOC_INT_INIT",
-	[_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)]     = "VIDIOC_INT_G_STD_OUTPUT",
-	[_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)]     = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
 /* Common ioctl debug function. This function can be used by
    external ioctl messages as well as internal V4L ioctl */
 void v4l_printk_ioctl(unsigned int cmd)
@@ -319,12 +289,8 @@ void v4l_printk_ioctl(unsigned int cmd)
 
 	switch (_IOC_TYPE(cmd)) {
 	case 'd':
-		if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
-			type = "v4l2_int";
-			break;
-		}
-		printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
-		return;
+		type = "v4l2_int";
+		break;
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 	case 'v':
 		if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
@@ -584,39 +550,39 @@ static int check_fmt(const struct v4l2_i
 
 	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (ops->vidioc_try_fmt_vid_cap)
+		if (ops->vidioc_g_fmt_vid_cap)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (ops->vidioc_try_fmt_vid_overlay)
+		if (ops->vidioc_g_fmt_vid_overlay)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (ops->vidioc_try_fmt_vid_out)
+		if (ops->vidioc_g_fmt_vid_out)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		if (ops->vidioc_try_fmt_vid_out_overlay)
+		if (ops->vidioc_g_fmt_vid_out_overlay)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		if (ops->vidioc_try_fmt_vbi_cap)
+		if (ops->vidioc_g_fmt_vbi_cap)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		if (ops->vidioc_try_fmt_vbi_out)
+		if (ops->vidioc_g_fmt_vbi_out)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		if (ops->vidioc_try_fmt_sliced_vbi_cap)
+		if (ops->vidioc_g_fmt_sliced_vbi_cap)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		if (ops->vidioc_try_fmt_sliced_vbi_out)
+		if (ops->vidioc_g_fmt_sliced_vbi_out)
 			return 0;
 		break;
 	case V4L2_BUF_TYPE_PRIVATE:
-		if (ops->vidioc_try_fmt_type_private)
+		if (ops->vidioc_g_fmt_type_private)
 			return 0;
 		break;
 	}
@@ -654,8 +620,6 @@ static long __video_do_ioctl(struct file
 	if (cmd == VIDIOCGMBUF) {
 		struct video_mbuf *p = arg;
 
-		memset(p, 0, sizeof(*p));
-
 		if (!ops->vidiocgmbuf)
 			return ret;
 		ret = ops->vidiocgmbuf(file, fh, p);
@@ -682,7 +646,6 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_QUERYCAP:
 	{
 		struct v4l2_capability *cap = (struct v4l2_capability *)arg;
-		memset(cap, 0, sizeof(*cap));
 
 		if (!ops->vidioc_querycap)
 			break;
@@ -725,16 +688,8 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_ENUM_FMT:
 	{
 		struct v4l2_fmtdesc *f = arg;
-		enum v4l2_buf_type type;
-		unsigned int index;
 
-		index = f->index;
-		type  = f->type;
-		memset(f, 0, sizeof(*f));
-		f->index = index;
-		f->type  = type;
-
-		switch (type) {
+		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 			if (ops->vidioc_enum_fmt_vid_cap)
 				ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
@@ -771,8 +726,6 @@ static long __video_do_ioctl(struct file
 	{
 		struct v4l2_format *f = (struct v4l2_format *)arg;
 
-		memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
-
 		/* FIXME: Should be one dump per type */
 		dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
 
@@ -835,44 +788,53 @@ static long __video_do_ioctl(struct file
 
 		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.pix);
 			v4l_print_pix_fmt(vfd, &f->fmt.pix);
 			if (ops->vidioc_s_fmt_vid_cap)
 				ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			CLEAR_AFTER_FIELD(f, fmt.win);
 			if (ops->vidioc_s_fmt_vid_overlay)
 				ret = ops->vidioc_s_fmt_vid_overlay(file,
 								    fh, f);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.pix);
 			v4l_print_pix_fmt(vfd, &f->fmt.pix);
 			if (ops->vidioc_s_fmt_vid_out)
 				ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+			CLEAR_AFTER_FIELD(f, fmt.win);
 			if (ops->vidioc_s_fmt_vid_out_overlay)
 				ret = ops->vidioc_s_fmt_vid_out_overlay(file,
 					fh, f);
 			break;
 		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.vbi);
 			if (ops->vidioc_s_fmt_vbi_cap)
 				ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_VBI_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.vbi);
 			if (ops->vidioc_s_fmt_vbi_out)
 				ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.sliced);
 			if (ops->vidioc_s_fmt_sliced_vbi_cap)
 				ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
 									fh, f);
 			break;
 		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.sliced);
 			if (ops->vidioc_s_fmt_sliced_vbi_out)
 				ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
 									fh, f);
 			break;
 		case V4L2_BUF_TYPE_PRIVATE:
+			/* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
 			if (ops->vidioc_s_fmt_type_private)
 				ret = ops->vidioc_s_fmt_type_private(file,
 								fh, f);
@@ -889,46 +851,55 @@ static long __video_do_ioctl(struct file
 						v4l2_type_names));
 		switch (f->type) {
 		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.pix);
 			if (ops->vidioc_try_fmt_vid_cap)
 				ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
 			if (!ret)
 				v4l_print_pix_fmt(vfd, &f->fmt.pix);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+			CLEAR_AFTER_FIELD(f, fmt.win);
 			if (ops->vidioc_try_fmt_vid_overlay)
 				ret = ops->vidioc_try_fmt_vid_overlay(file,
 					fh, f);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.pix);
 			if (ops->vidioc_try_fmt_vid_out)
 				ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
 			if (!ret)
 				v4l_print_pix_fmt(vfd, &f->fmt.pix);
 			break;
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+			CLEAR_AFTER_FIELD(f, fmt.win);
 			if (ops->vidioc_try_fmt_vid_out_overlay)
 				ret = ops->vidioc_try_fmt_vid_out_overlay(file,
 				       fh, f);
 			break;
 		case V4L2_BUF_TYPE_VBI_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.vbi);
 			if (ops->vidioc_try_fmt_vbi_cap)
 				ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_VBI_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.vbi);
 			if (ops->vidioc_try_fmt_vbi_out)
 				ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
 			break;
 		case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+			CLEAR_AFTER_FIELD(f, fmt.sliced);
 			if (ops->vidioc_try_fmt_sliced_vbi_cap)
 				ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
 								fh, f);
 			break;
 		case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+			CLEAR_AFTER_FIELD(f, fmt.sliced);
 			if (ops->vidioc_try_fmt_sliced_vbi_out)
 				ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
 								fh, f);
 			break;
 		case V4L2_BUF_TYPE_PRIVATE:
+			/* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
 			if (ops->vidioc_try_fmt_type_private)
 				ret = ops->vidioc_try_fmt_type_private(file,
 								fh, f);
@@ -951,6 +922,9 @@ static long __video_do_ioctl(struct file
 		if (ret)
 			break;
 
+		if (p->type < V4L2_BUF_TYPE_PRIVATE)
+			CLEAR_AFTER_FIELD(p, memory);
+
 		ret = ops->vidioc_reqbufs(file, fh, p);
 		dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
 				p->count,
@@ -1088,7 +1062,6 @@ static long __video_do_ioctl(struct file
 			return -EINVAL;
 
 		v4l2_video_std_construct(p, curr_id, descr);
-		p->index = index;
 
 		dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
 				"framelines=%d\n", p->index,
@@ -1153,12 +1126,9 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_ENUMINPUT:
 	{
 		struct v4l2_input *p = arg;
-		int i = p->index;
 
 		if (!ops->vidioc_enum_input)
 			break;
-		memset(p, 0, sizeof(*p));
-		p->index = i;
 
 		ret = ops->vidioc_enum_input(file, fh, p);
 		if (!ret)
@@ -1197,12 +1167,9 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_ENUMOUTPUT:
 	{
 		struct v4l2_output *p = arg;
-		int i = p->index;
 
 		if (!ops->vidioc_enum_output)
 			break;
-		memset(p, 0, sizeof(*p));
-		p->index = i;
 
 		ret = ops->vidioc_enum_output(file, fh, p);
 		if (!ret)
@@ -1378,13 +1345,10 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_G_AUDIO:
 	{
 		struct v4l2_audio *p = arg;
-		__u32 index = p->index;
 
 		if (!ops->vidioc_g_audio)
 			break;
 
-		memset(p, 0, sizeof(*p));
-		p->index = index;
 		ret = ops->vidioc_g_audio(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
@@ -1426,7 +1390,7 @@ static long __video_do_ioctl(struct file
 
 		if (!ops->vidioc_g_audout)
 			break;
-		dbgarg(cmd, "Enum for index=%d\n", p->index);
+
 		ret = ops->vidioc_g_audout(file, fh, p);
 		if (!ret)
 			dbgarg2("index=%d, name=%s, capability=%d, "
@@ -1479,15 +1443,10 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_G_CROP:
 	{
 		struct v4l2_crop *p = arg;
-		__u32 type;
 
 		if (!ops->vidioc_g_crop)
 			break;
 
-		type = p->type;
-		memset(p, 0, sizeof(*p));
-		p->type = type;
-
 		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
 		ret = ops->vidioc_g_crop(file, fh, p);
 		if (!ret)
@@ -1508,16 +1467,11 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_CROPCAP:
 	{
 		struct v4l2_cropcap *p = arg;
-		__u32 type;
 
 		/*FIXME: Should also show v4l2_fract pixelaspect */
 		if (!ops->vidioc_cropcap)
 			break;
 
-		type = p->type;
-		memset(p, 0, sizeof(*p));
-		p->type = type;
-
 		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
 		ret = ops->vidioc_cropcap(file, fh, p);
 		if (!ret) {
@@ -1533,8 +1487,6 @@ static long __video_do_ioctl(struct file
 		if (!ops->vidioc_g_jpegcomp)
 			break;
 
-		memset(p, 0, sizeof(*p));
-
 		ret = ops->vidioc_g_jpegcomp(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "quality=%d, APPn=%d, "
@@ -1575,7 +1527,6 @@ static long __video_do_ioctl(struct file
 
 		if (!ops->vidioc_encoder_cmd)
 			break;
-		memset(&p->raw, 0, sizeof(p->raw));
 		ret = ops->vidioc_encoder_cmd(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1587,7 +1538,6 @@ static long __video_do_ioctl(struct file
 
 		if (!ops->vidioc_try_encoder_cmd)
 			break;
-		memset(&p->raw, 0, sizeof(p->raw));
 		ret = ops->vidioc_try_encoder_cmd(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1596,23 +1546,18 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_G_PARM:
 	{
 		struct v4l2_streamparm *p = arg;
-		__u32 type = p->type;
-
-		memset(p, 0, sizeof(*p));
-		p->type = type;
 
 		if (ops->vidioc_g_parm) {
+			ret = check_fmt(ops, p->type);
+			if (ret)
+				break;
 			ret = ops->vidioc_g_parm(file, fh, p);
 		} else {
-			struct v4l2_standard s;
-
 			if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 				return -EINVAL;
 
-			v4l2_video_std_construct(&s, vfd->current_norm,
-						 v4l2_norm_to_name(vfd->current_norm));
-
-			p->parm.capture.timeperframe = s.frameperiod;
+			v4l2_video_std_frame_period(vfd->current_norm,
+						    &p->parm.capture.timeperframe);
 			ret = 0;
 		}
 
@@ -1625,6 +1570,10 @@ static long __video_do_ioctl(struct file
 
 		if (!ops->vidioc_s_parm)
 			break;
+		ret = check_fmt(ops, p->type);
+		if (ret)
+			break;
+
 		dbgarg(cmd, "type=%d\n", p->type);
 		ret = ops->vidioc_s_parm(file, fh, p);
 		break;
@@ -1632,14 +1581,10 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_G_TUNER:
 	{
 		struct v4l2_tuner *p = arg;
-		__u32 index = p->index;
 
 		if (!ops->vidioc_g_tuner)
 			break;
 
-		memset(p, 0, sizeof(*p));
-		p->index = index;
-
 		ret = ops->vidioc_g_tuner(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1676,8 +1621,6 @@ static long __video_do_ioctl(struct file
 		if (!ops->vidioc_g_frequency)
 			break;
 
-		memset(p->reserved, 0, sizeof(p->reserved));
-
 		ret = ops->vidioc_g_frequency(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1698,12 +1641,13 @@ static long __video_do_ioctl(struct file
 	case VIDIOC_G_SLICED_VBI_CAP:
 	{
 		struct v4l2_sliced_vbi_cap *p = arg;
-		__u32 type = p->type;
 
 		if (!ops->vidioc_g_sliced_vbi_cap)
 			break;
-		memset(p, 0, sizeof(*p));
-		p->type = type;
+
+		/* Clear up to type, everything after type is zerod already */
+		memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
+
 		dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
 		ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
 		if (!ret)
@@ -1745,16 +1689,13 @@ static long __video_do_ioctl(struct file
 
 		if (!ops->vidioc_g_chip_ident)
 			break;
+		p->ident = V4L2_IDENT_NONE;
+		p->revision = 0;
 		ret = ops->vidioc_g_chip_ident(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
 		break;
 	}
-	case VIDIOC_G_CHIP_IDENT_OLD:
-		printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n");
-		printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n");
-		return -EINVAL;
-
 	case VIDIOC_S_HW_FREQ_SEEK:
 	{
 		struct v4l2_hw_freq_seek *p = arg;
@@ -1774,8 +1715,6 @@ static long __video_do_ioctl(struct file
 		if (!ops->vidioc_enum_framesizes)
 			break;
 
-		memset(p, 0, sizeof(*p));
-
 		ret = ops->vidioc_enum_framesizes(file, fh, p);
 		dbgarg(cmd,
 			"index=%d, pixelformat=%d, type=%d ",
@@ -1807,8 +1746,6 @@ static long __video_do_ioctl(struct file
 		if (!ops->vidioc_enum_frameintervals)
 			break;
 
-		memset(p, 0, sizeof(*p));
-
 		ret = ops->vidioc_enum_frameintervals(file, fh, p);
 		dbgarg(cmd,
 			"index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
@@ -1857,6 +1794,45 @@ static long __video_do_ioctl(struct file
 	return ret;
 }
 
+/* In some cases, only a few fields are used as input, i.e. when the app sets
+ * "index" and then the driver fills in the rest of the structure for the thing
+ * with that index.  We only need to copy up the first non-input field.  */
+static unsigned long cmd_input_size(unsigned int cmd)
+{
+	/* Size of structure up to and including 'field' */
+#define CMDINSIZE(cmd, type, field) 				\
+	case VIDIOC_##cmd: 					\
+		return offsetof(struct v4l2_##type, field) + 	\
+			sizeof(((struct v4l2_##type *)0)->field);
+
+	switch (cmd) {
+		CMDINSIZE(ENUM_FMT,		fmtdesc,	type);
+		CMDINSIZE(G_FMT,		format,		type);
+		CMDINSIZE(QUERYBUF,		buffer,		type);
+		CMDINSIZE(G_PARM,		streamparm,	type);
+		CMDINSIZE(ENUMSTD,		standard,	index);
+		CMDINSIZE(ENUMINPUT,		input,		index);
+		CMDINSIZE(G_CTRL,		control,	id);
+		CMDINSIZE(G_TUNER,		tuner,		index);
+		CMDINSIZE(QUERYCTRL,		queryctrl,	id);
+		CMDINSIZE(QUERYMENU,		querymenu,	index);
+		CMDINSIZE(ENUMOUTPUT,		output,		index);
+		CMDINSIZE(G_MODULATOR,		modulator,	index);
+		CMDINSIZE(G_FREQUENCY,		frequency,	tuner);
+		CMDINSIZE(CROPCAP,		cropcap,	type);
+		CMDINSIZE(G_CROP,		crop,		type);
+		CMDINSIZE(ENUMAUDIO,		audio, 		index);
+		CMDINSIZE(ENUMAUDOUT,		audioout, 	index);
+		CMDINSIZE(ENCODER_CMD,		encoder_cmd,	flags);
+		CMDINSIZE(TRY_ENCODER_CMD,	encoder_cmd,	flags);
+		CMDINSIZE(G_SLICED_VBI_CAP,	sliced_vbi_cap,	type);
+		CMDINSIZE(ENUM_FRAMESIZES,	frmsizeenum,	pixel_format);
+		CMDINSIZE(ENUM_FRAMEINTERVALS,	frmivalenum,	height);
+	default:
+		return _IOC_SIZE(cmd);
+	}
+}
+
 long video_ioctl2(struct file *file,
 	       unsigned int cmd, unsigned long arg)
 {
@@ -1875,13 +1851,7 @@ long video_ioctl2(struct file *file,
 		       cmd == VIDIOC_TRY_EXT_CTRLS);
 
 	/*  Copy arguments into temp kernel buffer  */
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:
-		parg = NULL;
-		break;
-	case _IOC_READ:
-	case _IOC_WRITE:
-	case (_IOC_WRITE | _IOC_READ):
+	if (_IOC_DIR(cmd) != _IOC_NONE) {
 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
 			parg = sbuf;
 		} else {
@@ -1893,10 +1863,19 @@ long video_ioctl2(struct file *file,
 		}
 
 		err = -EFAULT;
-		if (_IOC_DIR(cmd) & _IOC_WRITE)
-			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+		if (_IOC_DIR(cmd) & _IOC_WRITE) {
+			unsigned long n = cmd_input_size(cmd);
+
+			if (copy_from_user(parg, (void __user *)arg, n))
 				goto out;
-		break;
+
+			/* zero out anything we don't copy from userspace */
+			if (n < _IOC_SIZE(cmd))
+				memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
+		} else {
+			/* read-only ioctl */
+			memset(parg, 0, _IOC_SIZE(cmd));
+		}
 	}
 
 	if (is_ext_ctrl) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-subdev.c linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-subdev.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/v4l2-subdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/v4l2-subdev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,110 +0,0 @@
-/*
-    V4L2 sub-device support.
-
-    Copyright (C) 2008  Hans Verkuil <hverkuil@xs4all.nl>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU 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/ioctl.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-subdev.h>
-
-int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_QUERYCTRL:
-		return v4l2_subdev_call(sd, core, queryctrl, arg);
-	case VIDIOC_G_CTRL:
-		return v4l2_subdev_call(sd, core, g_ctrl, arg);
-	case VIDIOC_S_CTRL:
-		return v4l2_subdev_call(sd, core, s_ctrl, arg);
-	case VIDIOC_QUERYMENU:
-		return v4l2_subdev_call(sd, core, querymenu, arg);
-	case VIDIOC_LOG_STATUS:
-		return v4l2_subdev_call(sd, core, log_status);
-	case VIDIOC_DBG_G_CHIP_IDENT:
-		return v4l2_subdev_call(sd, core, g_chip_ident, arg);
-	case VIDIOC_INT_S_STANDBY:
-		return v4l2_subdev_call(sd, core, s_standby, arg ? (*(u32 *)arg) : 0);
-	case VIDIOC_INT_RESET:
-		return v4l2_subdev_call(sd, core, reset, arg ? (*(u32 *)arg) : 0);
-	case VIDIOC_INT_S_GPIO:
-		return v4l2_subdev_call(sd, core, s_gpio, arg ? (*(u32 *)arg) : 0);
-	case VIDIOC_INT_INIT:
-		return v4l2_subdev_call(sd, core, init, arg ? (*(u32 *)arg) : 0);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	case VIDIOC_DBG_G_REGISTER:
-		return v4l2_subdev_call(sd, core, g_register, arg);
-	case VIDIOC_DBG_S_REGISTER:
-		return v4l2_subdev_call(sd, core, s_register, arg);
-#endif
-
-	case VIDIOC_INT_S_TUNER_MODE:
-		return v4l2_subdev_call(sd, tuner, s_mode, *(enum v4l2_tuner_type *)arg);
-	case AUDC_SET_RADIO:
-		return v4l2_subdev_call(sd, tuner, s_radio);
-	case VIDIOC_S_TUNER:
-		return v4l2_subdev_call(sd, tuner, s_tuner, arg);
-	case VIDIOC_G_TUNER:
-		return v4l2_subdev_call(sd, tuner, g_tuner, arg);
-	case VIDIOC_S_STD:
-		return v4l2_subdev_call(sd, tuner, s_std, *(v4l2_std_id *)arg);
-	case VIDIOC_S_FREQUENCY:
-		return v4l2_subdev_call(sd, tuner, s_frequency, arg);
-	case VIDIOC_G_FREQUENCY:
-		return v4l2_subdev_call(sd, tuner, g_frequency, arg);
-	case TUNER_SET_TYPE_ADDR:
-		return v4l2_subdev_call(sd, tuner, s_type_addr, arg);
-	case TUNER_SET_CONFIG:
-		return v4l2_subdev_call(sd, tuner, s_config, arg);
-
-	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		return v4l2_subdev_call(sd, audio, s_clock_freq, *(u32 *)arg);
-	case VIDIOC_INT_S_AUDIO_ROUTING:
-		return v4l2_subdev_call(sd, audio, s_routing, arg);
-	case VIDIOC_INT_I2S_CLOCK_FREQ:
-		return v4l2_subdev_call(sd, audio, s_i2s_clock_freq, *(u32 *)arg);
-
-	case VIDIOC_INT_S_VIDEO_ROUTING:
-		return v4l2_subdev_call(sd, video, s_routing, arg);
-	case VIDIOC_INT_S_CRYSTAL_FREQ:
-		return v4l2_subdev_call(sd, video, s_crystal_freq, arg);
-	case VIDIOC_INT_DECODE_VBI_LINE:
-		return v4l2_subdev_call(sd, video, decode_vbi_line, arg);
-	case VIDIOC_INT_S_VBI_DATA:
-		return v4l2_subdev_call(sd, video, s_vbi_data, arg);
-	case VIDIOC_INT_G_VBI_DATA:
-		return v4l2_subdev_call(sd, video, g_vbi_data, arg);
-	case VIDIOC_G_SLICED_VBI_CAP:
-		return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg);
-	case VIDIOC_S_FMT:
-		return v4l2_subdev_call(sd, video, s_fmt, arg);
-	case VIDIOC_G_FMT:
-		return v4l2_subdev_call(sd, video, g_fmt, arg);
-	case VIDIOC_INT_S_STD_OUTPUT:
-		return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
-	case VIDIOC_STREAMON:
-		return v4l2_subdev_call(sd, video, s_stream, 1);
-	case VIDIOC_STREAMOFF:
-		return v4l2_subdev_call(sd, video, s_stream, 0);
-
-	default:
-		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
-	}
-}
-EXPORT_SYMBOL_GPL(v4l2_subdev_command);
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/videobuf-dma-contig.c linux-libre-2.6.30-gnu1/drivers/media/video/videobuf-dma-contig.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/videobuf-dma-contig.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/videobuf-dma-contig.c	2009-06-09 23:05:27.000000000 -0400
@@ -400,7 +400,7 @@ void videobuf_dma_contig_free(struct vid
 	   So, it should free memory only if the memory were allocated for
 	   read() operation.
 	 */
-	if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+	if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
 		return;
 
 	if (!mem)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/videobuf-vmalloc.c linux-libre-2.6.30-gnu1/drivers/media/video/videobuf-vmalloc.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/videobuf-vmalloc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/videobuf-vmalloc.c	2009-06-09 23:05:27.000000000 -0400
@@ -425,7 +425,7 @@ void videobuf_vmalloc_free (struct video
 	   So, it should free memory only if the memory were allocated for
 	   read() operation.
 	 */
-	if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
+	if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
 		return;
 
 	if (!mem)
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/vino.c linux-libre-2.6.30-gnu1/drivers/media/video/vino.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/vino.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/vino.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,12 @@
  *
  * Based on the previous version of the driver for 2.4 kernels by:
  * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
+ *
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
  */
 
 /*
@@ -33,12 +39,10 @@
 #include <linux/kmod.h>
 
 #include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
 
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
 #include <linux/mutex.h>
 
 #include <asm/paccess.h>
@@ -56,8 +60,8 @@
 // #define VINO_DEBUG
 // #define VINO_DEBUG_INT
 
-#define VINO_MODULE_VERSION "0.0.5"
-#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)
+#define VINO_MODULE_VERSION "0.0.6"
+#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 6)
 
 MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
 MODULE_VERSION(VINO_MODULE_VERSION);
@@ -139,13 +143,23 @@ MODULE_LICENSE("GPL");
 #define VINO_DATA_NORM_PAL		1
 #define VINO_DATA_NORM_SECAM		2
 #define VINO_DATA_NORM_D1		3
-/* The following are special entries that can be used to
- * autodetect the norm. */
-#define VINO_DATA_NORM_AUTO		0xfe
-#define VINO_DATA_NORM_AUTO_EXT		0xff
 
 #define VINO_DATA_NORM_COUNT		4
 
+/* I2C controller flags */
+#define SGI_I2C_FORCE_IDLE		(0 << 0)
+#define SGI_I2C_NOT_IDLE		(1 << 0)
+#define SGI_I2C_WRITE			(0 << 1)
+#define SGI_I2C_READ			(1 << 1)
+#define SGI_I2C_RELEASE_BUS		(0 << 2)
+#define SGI_I2C_HOLD_BUS		(1 << 2)
+#define SGI_I2C_XFER_DONE		(0 << 4)
+#define SGI_I2C_XFER_BUSY		(1 << 4)
+#define SGI_I2C_ACK			(0 << 5)
+#define SGI_I2C_NACK			(1 << 5)
+#define SGI_I2C_BUS_OK			(0 << 7)
+#define SGI_I2C_BUS_ERR			(1 << 7)
+
 /* Internal data structure definitions */
 
 struct vino_input {
@@ -289,22 +303,20 @@ struct vino_channel_settings {
 	struct vino_interrupt_data int_data;
 
 	/* V4L support */
-	struct video_device *v4l_device;
-};
-
-struct vino_client {
-	/* the channel which owns this client:
-	 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
-	unsigned int owner;
-	struct i2c_client *driver;
+	struct video_device *vdev;
 };
 
 struct vino_settings {
+	struct v4l2_device v4l2_dev;
 	struct vino_channel_settings a;
 	struct vino_channel_settings b;
 
-	struct vino_client decoder;
-	struct vino_client camera;
+	/* the channel which owns this client:
+	 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
+	unsigned int decoder_owner;
+	struct v4l2_subdev *decoder;
+	unsigned int camera_owner;
+	struct v4l2_subdev *camera;
 
 	/* a lock for vino register access */
 	spinlock_t vino_lock;
@@ -344,11 +356,16 @@ static struct sgi_vino *vino;
 
 static struct vino_settings *vino_drvdata;
 
+#define camera_call(o, f, args...) \
+	v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
+#define decoder_call(o, f, args...) \
+	v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
+
 static const char *vino_driver_name = "vino";
 static const char *vino_driver_description = "SGI VINO";
 static const char *vino_bus_name = "GIO64 bus";
-static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
-static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
+static const char *vino_vdev_name_a = "SGI VINO Channel A";
+static const char *vino_vdev_name_b = "SGI VINO Channel B";
 
 static void vino_capture_tasklet(unsigned long channel);
 
@@ -360,11 +377,11 @@ static const struct vino_input vino_inpu
 		.name		= "Composite",
 		.std		= V4L2_STD_NTSC | V4L2_STD_PAL
 		| V4L2_STD_SECAM,
-	},{
+	}, {
 		.name		= "S-Video",
 		.std		= V4L2_STD_NTSC | V4L2_STD_PAL
 		| V4L2_STD_SECAM,
-	},{
+	}, {
 		.name		= "D1/IndyCam",
 		.std		= V4L2_STD_NTSC,
 	}
@@ -376,17 +393,17 @@ static const struct vino_data_format vin
 		.bpp		= 1,
 		.pixelformat	= V4L2_PIX_FMT_GREY,
 		.colorspace	= V4L2_COLORSPACE_SMPTE170M,
-	},{
+	}, {
 		.description	= "8-bit dithered RGB 3-3-2",
 		.bpp		= 1,
 		.pixelformat	= V4L2_PIX_FMT_RGB332,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
-	},{
+	}, {
 		.description	= "32-bit RGB",
 		.bpp		= 4,
 		.pixelformat	= V4L2_PIX_FMT_RGB32,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
-	},{
+	}, {
 		.description	= "YUV 4:2:2",
 		.bpp		= 2,
 		.pixelformat	= V4L2_PIX_FMT_YUYV, // XXX: swapped?
@@ -417,7 +434,7 @@ static const struct vino_data_norm vino_
 			+ VINO_NTSC_HEIGHT / 2 - 1,
 			.right	= VINO_NTSC_WIDTH,
 		},
-	},{
+	}, {
 		.description	= "PAL",
 		.std		= V4L2_STD_PAL,
 		.fps_min	= 5,
@@ -439,7 +456,7 @@ static const struct vino_data_norm vino_
 			+ VINO_PAL_HEIGHT / 2 - 1,
 			.right	= VINO_PAL_WIDTH,
 		},
-	},{
+	}, {
 		.description	= "SECAM",
 		.std		= V4L2_STD_SECAM,
 		.fps_min	= 5,
@@ -461,7 +478,7 @@ static const struct vino_data_norm vino_
 			+ VINO_PAL_HEIGHT / 2 - 1,
 			.right	= VINO_PAL_WIDTH,
 		},
-	},{
+	}, {
 		.description	= "NTSC/D1",
 		.std		= V4L2_STD_NTSC,
 		.fps_min	= 6,
@@ -497,9 +514,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = 1,
 		.step = 1,
 		.default_value = INDYCAM_AGC_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_AGC, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_AUTO_WHITE_BALANCE,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
 		.name = "Automatic White Balance",
@@ -507,9 +522,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = 1,
 		.step = 1,
 		.default_value = INDYCAM_AWB_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_AWB, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_GAIN,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Gain",
@@ -517,29 +530,23 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = INDYCAM_GAIN_MAX,
 		.step = 1,
 		.default_value = INDYCAM_GAIN_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_GAIN, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE,
+	}, {
+		.id = INDYCAM_CONTROL_RED_SATURATION,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Red Saturation",
 		.minimum = INDYCAM_RED_SATURATION_MIN,
 		.maximum = INDYCAM_RED_SATURATION_MAX,
 		.step = 1,
 		.default_value = INDYCAM_RED_SATURATION_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 1,
+	}, {
+		.id = INDYCAM_CONTROL_BLUE_SATURATION,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Blue Saturation",
 		.minimum = INDYCAM_BLUE_SATURATION_MIN,
 		.maximum = INDYCAM_BLUE_SATURATION_MAX,
 		.step = 1,
 		.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_RED_BALANCE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Red Balance",
@@ -547,9 +554,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = INDYCAM_RED_BALANCE_MAX,
 		.step = 1,
 		.default_value = INDYCAM_RED_BALANCE_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_BLUE_BALANCE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Blue Balance",
@@ -557,9 +562,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = INDYCAM_BLUE_BALANCE_MAX,
 		.step = 1,
 		.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_EXPOSURE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Shutter Control",
@@ -567,9 +570,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = INDYCAM_SHUTTER_MAX,
 		.step = 1,
 		.default_value = INDYCAM_SHUTTER_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
-	},{
+	}, {
 		.id = V4L2_CID_GAMMA,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Gamma",
@@ -577,8 +578,6 @@ struct v4l2_queryctrl vino_indycam_v4l2_
 		.maximum = INDYCAM_GAMMA_MAX,
 		.step = 1,
 		.default_value = INDYCAM_GAMMA_DEFAULT,
-		.flags = 0,
-		.reserved = { INDYCAM_CONTROL_GAMMA, 0 },
 	}
 };
 
@@ -593,209 +592,73 @@ struct v4l2_queryctrl vino_saa7191_v4l2_
 		.maximum = SAA7191_HUE_MAX,
 		.step = 1,
 		.default_value = SAA7191_HUE_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_HUE, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE,
+	}, {
+		.id = SAA7191_CONTROL_BANDPASS,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Luminance Bandpass",
 		.minimum = SAA7191_BANDPASS_MIN,
 		.maximum = SAA7191_BANDPASS_MAX,
 		.step = 1,
 		.default_value = SAA7191_BANDPASS_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_BANDPASS, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 1,
+	}, {
+		.id = SAA7191_CONTROL_BANDPASS_WEIGHT,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Luminance Bandpass Weight",
 		.minimum = SAA7191_BANDPASS_WEIGHT_MIN,
 		.maximum = SAA7191_BANDPASS_WEIGHT_MAX,
 		.step = 1,
 		.default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 2,
+	}, {
+		.id = SAA7191_CONTROL_CORING,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "HF Luminance Coring",
 		.minimum = SAA7191_CORING_MIN,
 		.maximum = SAA7191_CORING_MAX,
 		.step = 1,
 		.default_value = SAA7191_CORING_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_CORING, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 3,
+	}, {
+		.id = SAA7191_CONTROL_FORCE_COLOUR,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
 		.name = "Force Colour",
 		.minimum = SAA7191_FORCE_COLOUR_MIN,
 		.maximum = SAA7191_FORCE_COLOUR_MAX,
 		.step = 1,
 		.default_value = SAA7191_FORCE_COLOUR_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 4,
+	}, {
+		.id = SAA7191_CONTROL_CHROMA_GAIN,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Chrominance Gain Control",
 		.minimum = SAA7191_CHROMA_GAIN_MIN,
 		.maximum = SAA7191_CHROMA_GAIN_MAX,
 		.step = 1,
 		.default_value = SAA7191_CHROMA_GAIN_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 5,
+	}, {
+		.id = SAA7191_CONTROL_VTRC,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
 		.name = "VTR Time Constant",
 		.minimum = SAA7191_VTRC_MIN,
 		.maximum = SAA7191_VTRC_MAX,
 		.step = 1,
 		.default_value = SAA7191_VTRC_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_VTRC, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 6,
+	}, {
+		.id = SAA7191_CONTROL_LUMA_DELAY,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Luminance Delay Compensation",
 		.minimum = SAA7191_LUMA_DELAY_MIN,
 		.maximum = SAA7191_LUMA_DELAY_MAX,
 		.step = 1,
 		.default_value = SAA7191_LUMA_DELAY_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
-	},{
-		.id = V4L2_CID_PRIVATE_BASE + 7,
+	}, {
+		.id = SAA7191_CONTROL_VNR,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Vertical Noise Reduction",
 		.minimum = SAA7191_VNR_MIN,
 		.maximum = SAA7191_VNR_MAX,
 		.step = 1,
 		.default_value = SAA7191_VNR_DEFAULT,
-		.flags = 0,
-		.reserved = { SAA7191_CONTROL_VNR, 0 },
-	}
-};
-
-/* VINO I2C bus functions */
-
-unsigned i2c_vino_getctrl(void *data)
-{
-	return vino->i2c_control;
-}
-
-void i2c_vino_setctrl(void *data, unsigned val)
-{
-	vino->i2c_control = val;
-}
-
-unsigned i2c_vino_rdata(void *data)
-{
-	return vino->i2c_data;
-}
-
-void i2c_vino_wdata(void *data, unsigned val)
-{
-	vino->i2c_data = val;
-}
-
-static struct i2c_algo_sgi_data i2c_sgi_vino_data =
-{
-	.getctrl = &i2c_vino_getctrl,
-	.setctrl = &i2c_vino_setctrl,
-	.rdata   = &i2c_vino_rdata,
-	.wdata   = &i2c_vino_wdata,
-	.xfer_timeout = 200,
-	.ack_timeout  = 1000,
-};
-
-/*
- * There are two possible clients on VINO I2C bus, so we limit usage only
- * to them.
- */
-static int i2c_vino_client_reg(struct i2c_client *client)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-	switch (client->driver->id) {
-	case I2C_DRIVERID_SAA7191:
-		if (vino_drvdata->decoder.driver)
-			ret = -EBUSY;
-		else
-			vino_drvdata->decoder.driver = client;
-		break;
-	case I2C_DRIVERID_INDYCAM:
-		if (vino_drvdata->camera.driver)
-			ret = -EBUSY;
-		else
-			vino_drvdata->camera.driver = client;
-		break;
-	default:
-		ret = -ENODEV;
-	}
-	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
-	return ret;
-}
-
-static int i2c_vino_client_unreg(struct i2c_client *client)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-	if (client == vino_drvdata->decoder.driver) {
-		if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
-			ret = -EBUSY;
-		else
-			vino_drvdata->decoder.driver = NULL;
-	} else if (client == vino_drvdata->camera.driver) {
-		if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
-			ret = -EBUSY;
-		else
-			vino_drvdata->camera.driver = NULL;
 	}
-	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
-	return ret;
-}
-
-static struct i2c_adapter vino_i2c_adapter =
-{
-	.name			= "VINO I2C bus",
-	.id			= I2C_HW_SGI_VINO,
-	.algo_data		= &i2c_sgi_vino_data,
-	.client_register	= &i2c_vino_client_reg,
-	.client_unregister	= &i2c_vino_client_unreg,
 };
 
-static int vino_i2c_add_bus(void)
-{
-	return i2c_sgi_add_bus(&vino_i2c_adapter);
-}
-
-static int vino_i2c_del_bus(void)
-{
-	return i2c_del_adapter(&vino_i2c_adapter);
-}
-
-static int i2c_camera_command(unsigned int cmd, void *arg)
-{
-	return vino_drvdata->camera.driver->
-		driver->command(vino_drvdata->camera.driver,
-				cmd, arg);
-}
-
-static int i2c_decoder_command(unsigned int cmd, void *arg)
-{
-	return vino_drvdata->decoder.driver->
-		driver->command(vino_drvdata->decoder.driver,
-				cmd, arg);
-}
-
 /* VINO framebuffer/DMA descriptor management */
 
 static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
@@ -1741,6 +1604,184 @@ static inline void vino_set_default_fram
 	vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
 }
 
+/* VINO I2C bus functions */
+
+struct i2c_algo_sgi_data {
+	void *data;	/* private data for lowlevel routines */
+	unsigned (*getctrl)(void *data);
+	void (*setctrl)(void *data, unsigned val);
+	unsigned (*rdata)(void *data);
+	void (*wdata)(void *data, unsigned val);
+
+	int xfer_timeout;
+	int ack_timeout;
+};
+
+static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int wait_ack(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	if (wait_xfer_done(adap))
+		return -ETIMEDOUT;
+	for (i = 0; i < adap->ack_timeout; i++) {
+		if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int force_idle(struct i2c_algo_sgi_data *adap)
+{
+	int i;
+
+	adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
+	for (i = 0; i < adap->xfer_timeout; i++) {
+		if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
+			goto out;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+out:
+	if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
+		return -EIO;
+	return 0;
+}
+
+static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
+		      int rd)
+{
+	if (rd)
+		adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
+	/* Check if bus is idle, eventually force it to do so */
+	if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
+		if (force_idle(adap))
+			return -EIO;
+	/* Write out the i2c chip address and specify operation */
+	adap->setctrl(adap->data,
+		      SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
+	if (rd)
+		addr |= 1;
+	adap->wdata(adap->data, addr);
+	if (wait_ack(adap))
+		return -EIO;
+	return 0;
+}
+
+static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+		    unsigned int len)
+{
+	int i;
+
+	adap->setctrl(adap->data,
+		      SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
+	for (i = 0; i < len; i++) {
+		if (wait_xfer_done(adap))
+			return -EIO;
+		buf[i] = adap->rdata(adap->data);
+	}
+	adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
+
+	return 0;
+
+}
+
+static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+		     unsigned int len)
+{
+	int i;
+
+	/* We are already in write state */
+	for (i = 0; i < len; i++) {
+		adap->wdata(adap->data, buf[i]);
+		if (wait_ack(adap))
+			return -EIO;
+	}
+	return 0;
+}
+
+static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+		    int num)
+{
+	struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *p;
+	int i, err = 0;
+
+	for (i = 0; !err && i < num; i++) {
+		p = &msgs[i];
+		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+		if (err || !p->len)
+			continue;
+		if (p->flags & I2C_M_RD)
+			err = i2c_read(adap, p->buf, p->len);
+		else
+			err = i2c_write(adap, p->buf, p->len);
+	}
+
+	return (err < 0) ? err : i;
+}
+
+static u32 sgi_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sgi_algo = {
+	.master_xfer	= sgi_xfer,
+	.functionality	= sgi_func,
+};
+
+static unsigned i2c_vino_getctrl(void *data)
+{
+	return vino->i2c_control;
+}
+
+static void i2c_vino_setctrl(void *data, unsigned val)
+{
+	vino->i2c_control = val;
+}
+
+static unsigned i2c_vino_rdata(void *data)
+{
+	return vino->i2c_data;
+}
+
+static void i2c_vino_wdata(void *data, unsigned val)
+{
+	vino->i2c_data = val;
+}
+
+static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
+	.getctrl = &i2c_vino_getctrl,
+	.setctrl = &i2c_vino_setctrl,
+	.rdata   = &i2c_vino_rdata,
+	.wdata   = &i2c_vino_wdata,
+	.xfer_timeout = 200,
+	.ack_timeout  = 1000,
+};
+
+static struct i2c_adapter vino_i2c_adapter = {
+	.name			= "VINO I2C bus",
+	.id			= I2C_HW_SGI_VINO,
+	.algo			= &sgi_algo,
+	.algo_data		= &i2c_sgi_vino_data,
+	.owner 			= THIS_MODULE,
+};
+
 /*
  * Prepare VINO for DMA transfer...
  * (execute only with vino_lock and input_lock locked)
@@ -2490,86 +2531,15 @@ static int vino_get_saa7191_input(int in
 	}
 }
 
-static int vino_get_saa7191_norm(unsigned int data_norm)
-{
-	switch (data_norm) {
-	case VINO_DATA_NORM_AUTO:
-		return SAA7191_NORM_AUTO;
-	case VINO_DATA_NORM_AUTO_EXT:
-		return SAA7191_NORM_AUTO_EXT;
-	case VINO_DATA_NORM_PAL:
-		return SAA7191_NORM_PAL;
-	case VINO_DATA_NORM_NTSC:
-		return SAA7191_NORM_NTSC;
-	case VINO_DATA_NORM_SECAM:
-		return SAA7191_NORM_SECAM;
-	default:
-		printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
-		       "invalid norm!\n");
-		return -1;
-	}
-}
-
-static int vino_get_from_saa7191_norm(int saa7191_norm)
-{
-	switch (saa7191_norm) {
-	case SAA7191_NORM_PAL:
-		return VINO_DATA_NORM_PAL;
-	case SAA7191_NORM_NTSC:
-		return VINO_DATA_NORM_NTSC;
-	case SAA7191_NORM_SECAM:
-		return VINO_DATA_NORM_SECAM;
-	default:
-		printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
-		       "invalid norm!\n");
-		return VINO_DATA_NORM_NONE;
-	}
-}
-
-static int vino_saa7191_set_norm(unsigned int *data_norm)
-{
-	int saa7191_norm, new_data_norm;
-	int err = 0;
-
-	saa7191_norm = vino_get_saa7191_norm(*data_norm);
-
-	err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
-				  &saa7191_norm);
-	if (err)
-		goto out;
-
-	if ((*data_norm == VINO_DATA_NORM_AUTO)
-	    || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
-		struct saa7191_status status;
-
-		err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
-					  &status);
-		if (err)
-			goto out;
-
-		new_data_norm =
-			vino_get_from_saa7191_norm(status.norm);
-		if (new_data_norm == VINO_DATA_NORM_NONE) {
-			err = -EINVAL;
-			goto out;
-		}
-
-		*data_norm = (unsigned int)new_data_norm;
-	}
-
-out:
-	return err;
-}
-
 /* execute with input_lock locked */
 static int vino_is_input_owner(struct vino_channel_settings *vcs)
 {
 	switch(vcs->input) {
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO:
-		return (vino_drvdata->decoder.owner == vcs->channel);
+		return vino_drvdata->decoder_owner == vcs->channel;
 	case VINO_INPUT_D1:
-		return (vino_drvdata->camera.owner == vcs->channel);
+		return vino_drvdata->camera_owner == vcs->channel;
 	default:
 		return 0;
 	}
@@ -2585,23 +2555,21 @@ static int vino_acquire_input(struct vin
 	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
 	/* First try D1 and then SAA7191 */
-	if (vino_drvdata->camera.driver
-	    && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
-		i2c_use_client(vino_drvdata->camera.driver);
-		vino_drvdata->camera.owner = vcs->channel;
+	if (vino_drvdata->camera
+	    && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
+		vino_drvdata->camera_owner = vcs->channel;
 		vcs->input = VINO_INPUT_D1;
 		vcs->data_norm = VINO_DATA_NORM_D1;
-	} else if (vino_drvdata->decoder.driver
-		   && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
-		int input, data_norm;
-		int saa7191_input;
+	} else if (vino_drvdata->decoder
+		   && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
+		int input;
+		int data_norm;
+		v4l2_std_id norm;
 
-		i2c_use_client(vino_drvdata->decoder.driver);
 		input = VINO_INPUT_COMPOSITE;
 
-		saa7191_input = vino_get_saa7191_input(input);
-		ret = i2c_decoder_command(DECODER_SET_INPUT,
-					  &saa7191_input);
+		ret = decoder_call(video, s_routing,
+				vino_get_saa7191_input(input), 0, 0);
 		if (ret) {
 			ret = -EINVAL;
 			goto out;
@@ -2612,12 +2580,15 @@ static int vino_acquire_input(struct vin
 		/* Don't hold spinlocks while auto-detecting norm
 		 * as it may take a while... */
 
-		data_norm = VINO_DATA_NORM_AUTO_EXT;
-
-		ret = vino_saa7191_set_norm(&data_norm);
-		if ((ret == -EBUSY) || (ret == -EAGAIN)) {
-			data_norm = VINO_DATA_NORM_PAL;
-			ret = vino_saa7191_set_norm(&data_norm);
+		ret = decoder_call(video, querystd, &norm);
+		if (!ret) {
+			for (data_norm = 0; data_norm < 3; data_norm++) {
+				if (vino_data_norms[data_norm].std & norm)
+					break;
+			}
+			if (data_norm == 3)
+				data_norm = VINO_DATA_NORM_PAL;
+			ret = decoder_call(core, s_std, norm);
 		}
 
 		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2627,7 +2598,7 @@ static int vino_acquire_input(struct vin
 			goto out;
 		}
 
-		vino_drvdata->decoder.owner = vcs->channel;
+		vino_drvdata->decoder_owner = vcs->channel;
 
 		vcs->input = input;
 		vcs->data_norm = data_norm;
@@ -2672,25 +2643,23 @@ static int vino_set_input(struct vino_ch
 	switch (input) {
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO:
-		if (!vino_drvdata->decoder.driver) {
+		if (!vino_drvdata->decoder) {
 			ret = -EINVAL;
 			goto out;
 		}
 
-		if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
-			i2c_use_client(vino_drvdata->decoder.driver);
-			vino_drvdata->decoder.owner = vcs->channel;
+		if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
+			vino_drvdata->decoder_owner = vcs->channel;
 		}
 
-		if (vino_drvdata->decoder.owner == vcs->channel) {
+		if (vino_drvdata->decoder_owner == vcs->channel) {
 			int data_norm;
-			int saa7191_input;
+			v4l2_std_id norm;
 
-			saa7191_input = vino_get_saa7191_input(input);
-			ret = i2c_decoder_command(DECODER_SET_INPUT,
-						  &saa7191_input);
+			ret = decoder_call(video, s_routing,
+					vino_get_saa7191_input(input), 0, 0);
 			if (ret) {
-				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+				vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
 				ret = -EINVAL;
 				goto out;
 			}
@@ -2700,18 +2669,21 @@ static int vino_set_input(struct vino_ch
 			/* Don't hold spinlocks while auto-detecting norm
 			 * as it may take a while... */
 
-			data_norm = VINO_DATA_NORM_AUTO_EXT;
-
-			ret = vino_saa7191_set_norm(&data_norm);
-			if ((ret  == -EBUSY) || (ret == -EAGAIN)) {
-				data_norm = VINO_DATA_NORM_PAL;
-				ret = vino_saa7191_set_norm(&data_norm);
+			ret = decoder_call(video, querystd, &norm);
+			if (!ret) {
+				for (data_norm = 0; data_norm < 3; data_norm++) {
+					if (vino_data_norms[data_norm].std & norm)
+						break;
+				}
+				if (data_norm == 3)
+					data_norm = VINO_DATA_NORM_PAL;
+				ret = decoder_call(core, s_std, norm);
 			}
 
 			spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
 			if (ret) {
-				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+				vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
 				ret = -EINVAL;
 				goto out;
 			}
@@ -2728,37 +2700,31 @@ static int vino_set_input(struct vino_ch
 			vcs->data_norm = vcs2->data_norm;
 		}
 
-		if (vino_drvdata->camera.owner == vcs->channel) {
+		if (vino_drvdata->camera_owner == vcs->channel) {
 			/* Transfer the ownership or release the input */
 			if (vcs2->input == VINO_INPUT_D1) {
-				vino_drvdata->camera.owner = vcs2->channel;
+				vino_drvdata->camera_owner = vcs2->channel;
 			} else {
-				i2c_release_client(vino_drvdata->
-						   camera.driver);
-				vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+				vino_drvdata->camera_owner = VINO_NO_CHANNEL;
 			}
 		}
 		break;
 	case VINO_INPUT_D1:
-		if (!vino_drvdata->camera.driver) {
+		if (!vino_drvdata->camera) {
 			ret = -EINVAL;
 			goto out;
 		}
 
-		if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
-			i2c_use_client(vino_drvdata->camera.driver);
-			vino_drvdata->camera.owner = vcs->channel;
-		}
+		if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
+			vino_drvdata->camera_owner = vcs->channel;
 
-		if (vino_drvdata->decoder.owner == vcs->channel) {
+		if (vino_drvdata->decoder_owner == vcs->channel) {
 			/* Transfer the ownership or release the input */
 			if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
 				 (vcs2->input == VINO_INPUT_SVIDEO)) {
-				vino_drvdata->decoder.owner = vcs2->channel;
+				vino_drvdata->decoder_owner = vcs2->channel;
 			} else {
-				i2c_release_client(vino_drvdata->
-						   decoder.driver);
-				vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+				vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
 			}
 		}
 
@@ -2795,20 +2761,18 @@ static void vino_release_input(struct vi
 	/* Release ownership of the channel
 	 * and if the other channel takes input from
 	 * the same source, transfer the ownership */
-	if (vino_drvdata->camera.owner == vcs->channel) {
+	if (vino_drvdata->camera_owner == vcs->channel) {
 		if (vcs2->input == VINO_INPUT_D1) {
-			vino_drvdata->camera.owner = vcs2->channel;
+			vino_drvdata->camera_owner = vcs2->channel;
 		} else {
-			i2c_release_client(vino_drvdata->camera.driver);
-			vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+			vino_drvdata->camera_owner = VINO_NO_CHANNEL;
 		}
-	} else if (vino_drvdata->decoder.owner == vcs->channel) {
+	} else if (vino_drvdata->decoder_owner == vcs->channel) {
 		if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
 			 (vcs2->input == VINO_INPUT_SVIDEO)) {
-			vino_drvdata->decoder.owner = vcs2->channel;
+			vino_drvdata->decoder_owner = vcs2->channel;
 		} else {
-			i2c_release_client(vino_drvdata->decoder.driver);
-			vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+			vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
 		}
 	}
 	vcs->input = VINO_INPUT_NONE;
@@ -2829,18 +2793,16 @@ static int vino_set_data_norm(struct vin
 	switch (vcs->input) {
 	case VINO_INPUT_D1:
 		/* only one "norm" supported */
-		if ((data_norm != VINO_DATA_NORM_D1)
-		    && (data_norm != VINO_DATA_NORM_AUTO)
-		    && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+		if (data_norm != VINO_DATA_NORM_D1)
 			return -EINVAL;
 		break;
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO: {
+		v4l2_std_id norm;
+
 		if ((data_norm != VINO_DATA_NORM_PAL)
 		    && (data_norm != VINO_DATA_NORM_NTSC)
-		    && (data_norm != VINO_DATA_NORM_SECAM)
-		    && (data_norm != VINO_DATA_NORM_AUTO)
-		    && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+		    && (data_norm != VINO_DATA_NORM_SECAM))
 			return -EINVAL;
 
 		spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
@@ -2848,7 +2810,8 @@ static int vino_set_data_norm(struct vin
 		/* Don't hold spinlocks while setting norm
 		 * as it may take a while... */
 
-		err = vino_saa7191_set_norm(&data_norm);
+		norm = vino_data_norms[data_norm].std;
+		err = decoder_call(core, s_std, norm);
 
 		spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
 
@@ -2884,41 +2847,13 @@ static int vino_find_data_format(__u32 p
 	return VINO_DATA_FMT_NONE;
 }
 
-static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
-{
-	int data_norm = VINO_DATA_NORM_NONE;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-	switch(vcs->input) {
-	case VINO_INPUT_COMPOSITE:
-	case VINO_INPUT_SVIDEO:
-		if (index == 0) {
-			data_norm = VINO_DATA_NORM_PAL;
-		} else if (index == 1) {
-			data_norm = VINO_DATA_NORM_NTSC;
-		} else if (index == 2) {
-			data_norm = VINO_DATA_NORM_SECAM;
-		}
-		break;
-	case VINO_INPUT_D1:
-		if (index == 0) {
-			data_norm = VINO_DATA_NORM_D1;
-		}
-		break;
-	}
-	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
-	return data_norm;
-}
-
-static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
+static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
 {
 	int input = VINO_INPUT_NONE;
 	unsigned long flags;
 
 	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-	if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+	if (vino_drvdata->decoder && vino_drvdata->camera) {
 		switch (index) {
 		case 0:
 			input = VINO_INPUT_COMPOSITE;
@@ -2930,7 +2865,7 @@ static int vino_enum_input(struct vino_c
 			input = VINO_INPUT_D1;
 			break;
 		}
-	} else if (vino_drvdata->decoder.driver) {
+	} else if (vino_drvdata->decoder) {
 		switch (index) {
 		case 0:
 			input = VINO_INPUT_COMPOSITE;
@@ -2939,7 +2874,7 @@ static int vino_enum_input(struct vino_c
 			input = VINO_INPUT_SVIDEO;
 			break;
 		}
-	} else if (vino_drvdata->camera.driver) {
+	} else if (vino_drvdata->camera) {
 		switch (index) {
 		case 0:
 			input = VINO_INPUT_D1;
@@ -2957,7 +2892,7 @@ static __u32 vino_find_input_index(struc
 	__u32 index = 0;
 	// FIXME: detect when no inputs available
 
-	if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+	if (vino_drvdata->decoder && vino_drvdata->camera) {
 		switch (vcs->input) {
 		case VINO_INPUT_COMPOSITE:
 			index = 0;
@@ -2969,7 +2904,7 @@ static __u32 vino_find_input_index(struc
 			index = 2;
 			break;
 		}
-	} else if (vino_drvdata->decoder.driver) {
+	} else if (vino_drvdata->decoder) {
 		switch (vcs->input) {
 		case VINO_INPUT_COMPOSITE:
 			index = 0;
@@ -2978,7 +2913,7 @@ static __u32 vino_find_input_index(struc
 			index = 1;
 			break;
 		}
-	} else if (vino_drvdata->camera.driver) {
+	} else if (vino_drvdata->camera) {
 		switch (vcs->input) {
 		case VINO_INPUT_D1:
 			index = 0;
@@ -2991,7 +2926,8 @@ static __u32 vino_find_input_index(struc
 
 /* V4L2 ioctls */
 
-static void vino_v4l2_querycap(struct v4l2_capability *cap)
+static int vino_querycap(struct file *file, void *__fh,
+		struct v4l2_capability *cap)
 {
 	memset(cap, 0, sizeof(struct v4l2_capability));
 
@@ -3003,16 +2939,18 @@ static void vino_v4l2_querycap(struct v4
 		V4L2_CAP_VIDEO_CAPTURE |
 		V4L2_CAP_STREAMING;
 	// V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
+	return 0;
 }
 
-static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
+static int vino_enum_input(struct file *file, void *__fh,
 			       struct v4l2_input *i)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	__u32 index = i->index;
 	int input;
 	dprintk("requested index = %d\n", index);
 
-	input = vino_enum_input(vcs, index);
+	input = vino_int_enum_input(vcs, index);
 	if (input == VINO_INPUT_NONE)
 		return -EINVAL;
 
@@ -3023,20 +2961,15 @@ static int vino_v4l2_enuminput(struct vi
 	i->std = vino_inputs[input].std;
 	strcpy(i->name, vino_inputs[input].name);
 
-	if ((input == VINO_INPUT_COMPOSITE)
-	    || (input == VINO_INPUT_SVIDEO)) {
-		struct saa7191_status status;
-		i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
-		i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
-		i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
-	}
-
+	if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
+		decoder_call(video, g_input_status, &i->status);
 	return 0;
 }
 
-static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
+static int vino_g_input(struct file *file, void *__fh,
 			     unsigned int *i)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	__u32 index;
 	int input;
 	unsigned long flags;
@@ -3057,52 +2990,24 @@ static int vino_v4l2_g_input(struct vino
 	return 0;
 }
 
-static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
-			     unsigned int *i)
+static int vino_s_input(struct file *file, void *__fh,
+			     unsigned int i)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	int input;
-	dprintk("requested input = %d\n", *i);
+	dprintk("requested input = %d\n", i);
 
-	input = vino_enum_input(vcs, *i);
+	input = vino_int_enum_input(vcs, i);
 	if (input == VINO_INPUT_NONE)
 		return -EINVAL;
 
 	return vino_set_input(vcs, input);
 }
 
-static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
-			     struct v4l2_standard *s)
-{
-	int index = s->index;
-	int data_norm;
-
-	data_norm = vino_enum_data_norm(vcs, index);
-	dprintk("standard index = %d\n", index);
-
-	if (data_norm == VINO_DATA_NORM_NONE)
-		return -EINVAL;
-
-	dprintk("standard name = %s\n",
-	       vino_data_norms[data_norm].description);
-
-	memset(s, 0, sizeof(struct v4l2_standard));
-	s->index = index;
-
-	s->id = vino_data_norms[data_norm].std;
-	s->frameperiod.numerator = 1;
-	s->frameperiod.denominator =
-		vino_data_norms[data_norm].fps_max;
-	s->framelines =
-		vino_data_norms[data_norm].framelines;
-	strcpy(s->name,
-	       vino_data_norms[data_norm].description);
-
-	return 0;
-}
-
-static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
+static int vino_querystd(struct file *file, void *__fh,
 			      v4l2_std_id *std)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 	int err = 0;
 
@@ -3114,19 +3019,7 @@ static int vino_v4l2_querystd(struct vin
 		break;
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO: {
-		struct saa7191_status status;
-
-		i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
-
-		if (status.signal) {
-			if (status.signal_60hz) {
-				*std = V4L2_STD_NTSC;
-			} else {
-				*std = V4L2_STD_PAL | V4L2_STD_SECAM;
-			}
-		} else {
-			*std = vino_inputs[vcs->input].std;
-		}
+		decoder_call(video, querystd, std);
 		break;
 	}
 	default:
@@ -3138,9 +3031,10 @@ static int vino_v4l2_querystd(struct vin
 	return err;
 }
 
-static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
+static int vino_g_std(struct file *file, void *__fh,
 			   v4l2_std_id *std)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 
 	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -3153,9 +3047,10 @@ static int vino_v4l2_g_std(struct vino_c
 	return 0;
 }
 
-static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
+static int vino_s_std(struct file *file, void *__fh,
 			   v4l2_std_id *std)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 	int ret = 0;
 
@@ -3176,12 +3071,7 @@ static int vino_v4l2_s_std(struct vino_c
 		if (vcs->input == VINO_INPUT_D1)
 			goto out;
 
-		if (((*std) & V4L2_STD_PAL)
-		    && ((*std) & V4L2_STD_NTSC)
-		    && ((*std) & V4L2_STD_SECAM)) {
-			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
-						 &flags);
-		} else if ((*std) & V4L2_STD_PAL) {
+		if ((*std) & V4L2_STD_PAL) {
 			ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
 						 &flags);
 		} else if ((*std) & V4L2_STD_NTSC) {
@@ -3207,185 +3097,144 @@ out:
 	return ret;
 }
 
-static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
+static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
 			      struct v4l2_fmtdesc *fd)
 {
-	enum v4l2_buf_type type = fd->type;
-	int index = fd->index;
-	dprintk("format index = %d\n", index);
-
-	switch (fd->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if ((fd->index < 0) ||
-		    (fd->index >= VINO_DATA_FMT_COUNT))
-			return -EINVAL;
-		dprintk("format name = %s\n",
-		       vino_data_formats[index].description);
+	dprintk("format index = %d\n", fd->index);
 
-		memset(fd, 0, sizeof(struct v4l2_fmtdesc));
-		fd->index = index;
-		fd->type = type;
-		fd->pixelformat = vino_data_formats[index].pixelformat;
-		strcpy(fd->description, vino_data_formats[index].description);
-		break;
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
+	if (fd->index >= VINO_DATA_FMT_COUNT)
 		return -EINVAL;
-	}
+	dprintk("format name = %s\n", vino_data_formats[fd->index].description);
 
+	fd->pixelformat = vino_data_formats[fd->index].pixelformat;
+	strcpy(fd->description, vino_data_formats[fd->index].description);
 	return 0;
 }
 
-static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
+static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
 			     struct v4l2_format *f)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	struct vino_channel_settings tempvcs;
 	unsigned long flags;
+	struct v4l2_pix_format *pf = &f->fmt.pix;
 
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct v4l2_pix_format *pf = &f->fmt.pix;
-
-		dprintk("requested: w = %d, h = %d\n",
-		       pf->width, pf->height);
-
-		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-		memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
-		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+	dprintk("requested: w = %d, h = %d\n",
+			pf->width, pf->height);
 
-		tempvcs.data_format = vino_find_data_format(pf->pixelformat);
-		if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
-			tempvcs.data_format = VINO_DATA_FMT_GREY;
-			pf->pixelformat =
-				vino_data_formats[tempvcs.data_format].
-				pixelformat;
-		}
+	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+	memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
+	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
 
-		/* data format must be set before clipping/scaling */
-		vino_set_scaling(&tempvcs, pf->width, pf->height);
+	tempvcs.data_format = vino_find_data_format(pf->pixelformat);
+	if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
+		tempvcs.data_format = VINO_DATA_FMT_GREY;
+		pf->pixelformat =
+			vino_data_formats[tempvcs.data_format].
+			pixelformat;
+	}
 
-		dprintk("data format = %s\n",
-		       vino_data_formats[tempvcs.data_format].description);
+	/* data format must be set before clipping/scaling */
+	vino_set_scaling(&tempvcs, pf->width, pf->height);
 
-		pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
-			tempvcs.decimation;
-		pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
-			tempvcs.decimation;
+	dprintk("data format = %s\n",
+			vino_data_formats[tempvcs.data_format].description);
 
-		pf->field = V4L2_FIELD_INTERLACED;
-		pf->bytesperline = tempvcs.line_size;
-		pf->sizeimage = tempvcs.line_size *
-			(tempvcs.clipping.bottom - tempvcs.clipping.top) /
-			tempvcs.decimation;
-		pf->colorspace =
-			vino_data_formats[tempvcs.data_format].colorspace;
+	pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
+		tempvcs.decimation;
+	pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+		tempvcs.decimation;
 
-		pf->priv = 0;
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
-	}
+	pf->field = V4L2_FIELD_INTERLACED;
+	pf->bytesperline = tempvcs.line_size;
+	pf->sizeimage = tempvcs.line_size *
+		(tempvcs.clipping.bottom - tempvcs.clipping.top) /
+		tempvcs.decimation;
+	pf->colorspace =
+		vino_data_formats[tempvcs.data_format].colorspace;
 
+	pf->priv = 0;
 	return 0;
 }
 
-static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
+static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
 			   struct v4l2_format *f)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
+	struct v4l2_pix_format *pf = &f->fmt.pix;
 
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct v4l2_pix_format *pf = &f->fmt.pix;
-
-		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
-		pf->width = (vcs->clipping.right - vcs->clipping.left) /
-			vcs->decimation;
-		pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
-			vcs->decimation;
-		pf->pixelformat =
-			vino_data_formats[vcs->data_format].pixelformat;
+	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
-		pf->field = V4L2_FIELD_INTERLACED;
-		pf->bytesperline = vcs->line_size;
-		pf->sizeimage = vcs->line_size *
-			(vcs->clipping.bottom - vcs->clipping.top) /
-			vcs->decimation;
-		pf->colorspace =
-			vino_data_formats[vcs->data_format].colorspace;
+	pf->width = (vcs->clipping.right - vcs->clipping.left) /
+		vcs->decimation;
+	pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
+		vcs->decimation;
+	pf->pixelformat =
+		vino_data_formats[vcs->data_format].pixelformat;
 
-		pf->priv = 0;
+	pf->field = V4L2_FIELD_INTERLACED;
+	pf->bytesperline = vcs->line_size;
+	pf->sizeimage = vcs->line_size *
+		(vcs->clipping.bottom - vcs->clipping.top) /
+		vcs->decimation;
+	pf->colorspace =
+		vino_data_formats[vcs->data_format].colorspace;
 
-		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
-	}
+	pf->priv = 0;
 
+	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
 	return 0;
 }
 
-static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
+static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
 			   struct v4l2_format *f)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	int data_format;
 	unsigned long flags;
+	struct v4l2_pix_format *pf = &f->fmt.pix;
 
-	switch (f->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct v4l2_pix_format *pf = &f->fmt.pix;
-
-		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
-		data_format = vino_find_data_format(pf->pixelformat);
+	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
-		if (data_format == VINO_DATA_FMT_NONE) {
-			vcs->data_format = VINO_DATA_FMT_GREY;
-			pf->pixelformat =
-				vino_data_formats[vcs->data_format].
-				pixelformat;
-		} else {
-			vcs->data_format = data_format;
-		}
+	data_format = vino_find_data_format(pf->pixelformat);
 
-		/* data format must be set before clipping/scaling */
-		vino_set_scaling(vcs, pf->width, pf->height);
+	if (data_format == VINO_DATA_FMT_NONE) {
+		vcs->data_format = VINO_DATA_FMT_GREY;
+		pf->pixelformat =
+			vino_data_formats[vcs->data_format].
+			pixelformat;
+	} else {
+		vcs->data_format = data_format;
+	}
 
-		dprintk("data format = %s\n",
-		       vino_data_formats[vcs->data_format].description);
+	/* data format must be set before clipping/scaling */
+	vino_set_scaling(vcs, pf->width, pf->height);
 
-		pf->width = vcs->clipping.right - vcs->clipping.left;
-		pf->height = vcs->clipping.bottom - vcs->clipping.top;
+	dprintk("data format = %s\n",
+	       vino_data_formats[vcs->data_format].description);
 
-		pf->field = V4L2_FIELD_INTERLACED;
-		pf->bytesperline = vcs->line_size;
-		pf->sizeimage = vcs->line_size *
-			(vcs->clipping.bottom - vcs->clipping.top) /
-			vcs->decimation;
-		pf->colorspace =
-			vino_data_formats[vcs->data_format].colorspace;
+	pf->width = vcs->clipping.right - vcs->clipping.left;
+	pf->height = vcs->clipping.bottom - vcs->clipping.top;
 
-		pf->priv = 0;
+	pf->field = V4L2_FIELD_INTERLACED;
+	pf->bytesperline = vcs->line_size;
+	pf->sizeimage = vcs->line_size *
+		(vcs->clipping.bottom - vcs->clipping.top) /
+		vcs->decimation;
+	pf->colorspace =
+		vino_data_formats[vcs->data_format].colorspace;
 
-		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
-	}
+	pf->priv = 0;
 
+	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
 	return 0;
 }
 
-static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
+static int vino_cropcap(struct file *file, void *__fh,
 			     struct v4l2_cropcap *ccap)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	const struct vino_data_norm *norm;
 	unsigned long flags;
 
@@ -3415,9 +3264,10 @@ static int vino_v4l2_cropcap(struct vino
 	return 0;
 }
 
-static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
+static int vino_g_crop(struct file *file, void *__fh,
 			    struct v4l2_crop *c)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 
 	switch (c->type) {
@@ -3439,9 +3289,10 @@ static int vino_v4l2_g_crop(struct vino_
 	return 0;
 }
 
-static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
+static int vino_s_crop(struct file *file, void *__fh,
 			    struct v4l2_crop *c)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 
 	switch (c->type) {
@@ -3461,108 +3312,83 @@ static int vino_v4l2_s_crop(struct vino_
 	return 0;
 }
 
-static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
+static int vino_g_parm(struct file *file, void *__fh,
 			    struct v4l2_streamparm *sp)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
+	struct v4l2_captureparm *cp = &sp->parm.capture;
 
-	switch (sp->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct v4l2_captureparm *cp = &sp->parm.capture;
-		memset(cp, 0, sizeof(struct v4l2_captureparm));
-
-		cp->capability = V4L2_CAP_TIMEPERFRAME;
-		cp->timeperframe.numerator = 1;
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+	cp->timeperframe.numerator = 1;
 
-		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
-		cp->timeperframe.denominator = vcs->fps;
+	cp->timeperframe.denominator = vcs->fps;
 
-		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
 
-		// TODO: cp->readbuffers = xxx;
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
-	}
+	/* TODO: cp->readbuffers = xxx; */
 
 	return 0;
 }
 
-static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
+static int vino_s_parm(struct file *file, void *__fh,
 			    struct v4l2_streamparm *sp)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
+	struct v4l2_captureparm *cp = &sp->parm.capture;
 
-	switch (sp->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct v4l2_captureparm *cp = &sp->parm.capture;
-
-		spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
-		if ((cp->timeperframe.numerator == 0) ||
-		    (cp->timeperframe.denominator == 0)) {
-			/* reset framerate */
-			vino_set_default_framerate(vcs);
-		} else {
-			vino_set_framerate(vcs, cp->timeperframe.denominator /
-					   cp->timeperframe.numerator);
-		}
-
-		spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+	spin_lock_irqsave(&vino_drvdata->input_lock, flags);
 
-		// TODO: set buffers according to cp->readbuffers
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
+	if ((cp->timeperframe.numerator == 0) ||
+	    (cp->timeperframe.denominator == 0)) {
+		/* reset framerate */
+		vino_set_default_framerate(vcs);
+	} else {
+		vino_set_framerate(vcs, cp->timeperframe.denominator /
+				   cp->timeperframe.numerator);
 	}
 
+	spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
 	return 0;
 }
 
-static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
+static int vino_reqbufs(struct file *file, void *__fh,
 			     struct v4l2_requestbuffers *rb)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
+
 	if (vcs->reading)
 		return -EBUSY;
 
-	switch (rb->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		// TODO: check queue type
-		if (rb->memory != V4L2_MEMORY_MMAP) {
-			dprintk("type not mmap\n");
-			return -EINVAL;
-		}
+	/* TODO: check queue type */
+	if (rb->memory != V4L2_MEMORY_MMAP) {
+		dprintk("type not mmap\n");
+		return -EINVAL;
+	}
 
-		dprintk("count = %d\n", rb->count);
-		if (rb->count > 0) {
-			if (vino_is_capturing(vcs)) {
-				dprintk("busy, capturing\n");
-				return -EBUSY;
-			}
+	dprintk("count = %d\n", rb->count);
+	if (rb->count > 0) {
+		if (vino_is_capturing(vcs)) {
+			dprintk("busy, capturing\n");
+			return -EBUSY;
+		}
 
-			if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
-				dprintk("busy, buffers still mapped\n");
-				return -EBUSY;
-			} else {
-				vcs->streaming = 0;
-				vino_queue_free(&vcs->fb_queue);
-				vino_queue_init(&vcs->fb_queue, &rb->count);
-			}
+		if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
+			dprintk("busy, buffers still mapped\n");
+			return -EBUSY;
 		} else {
 			vcs->streaming = 0;
-			vino_capture_stop(vcs);
 			vino_queue_free(&vcs->fb_queue);
+			vino_queue_init(&vcs->fb_queue, &rb->count);
 		}
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
+	} else {
+		vcs->streaming = 0;
+		vino_capture_stop(vcs);
+		vino_queue_free(&vcs->fb_queue);
 	}
 
 	return 0;
@@ -3606,156 +3432,135 @@ static void vino_v4l2_get_buffer_status(
 		fb->id, fb->size, fb->data_size, fb->offset);
 }
 
-static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
+static int vino_querybuf(struct file *file, void *__fh,
 			      struct v4l2_buffer *b)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
+	struct vino_framebuffer *fb;
+
 	if (vcs->reading)
 		return -EBUSY;
 
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct vino_framebuffer *fb;
-
-		// TODO: check queue type
-		if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
-			dprintk("invalid index = %d\n",
-			       b->index);
-			return -EINVAL;
-		}
-
-		fb = vino_queue_get_buffer(&vcs->fb_queue,
-					   b->index);
-		if (fb == NULL) {
-			dprintk("vino_queue_get_buffer() failed");
-			return -EINVAL;
-		}
-
-		vino_v4l2_get_buffer_status(vcs, fb, b);
-		break;
+	/* TODO: check queue type */
+	if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
+		dprintk("invalid index = %d\n",
+		       b->index);
+		return -EINVAL;
 	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
+
+	fb = vino_queue_get_buffer(&vcs->fb_queue,
+				   b->index);
+	if (fb == NULL) {
+		dprintk("vino_queue_get_buffer() failed");
 		return -EINVAL;
 	}
 
+	vino_v4l2_get_buffer_status(vcs, fb, b);
+
 	return 0;
 }
 
-static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
+static int vino_qbuf(struct file *file, void *__fh,
 			  struct v4l2_buffer *b)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
+	struct vino_framebuffer *fb;
+	int ret;
+
 	if (vcs->reading)
 		return -EBUSY;
 
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct vino_framebuffer *fb;
-		int ret;
-
-		// TODO: check queue type
-		if (b->memory != V4L2_MEMORY_MMAP) {
-			dprintk("type not mmap\n");
-			return -EINVAL;
-		}
+	/* TODO: check queue type */
+	if (b->memory != V4L2_MEMORY_MMAP) {
+		dprintk("type not mmap\n");
+		return -EINVAL;
+	}
 
-		fb = vino_capture_enqueue(vcs, b->index);
-		if (fb == NULL)
-			return -EINVAL;
+	fb = vino_capture_enqueue(vcs, b->index);
+	if (fb == NULL)
+		return -EINVAL;
 
-		vino_v4l2_get_buffer_status(vcs, fb, b);
+	vino_v4l2_get_buffer_status(vcs, fb, b);
 
-		if (vcs->streaming) {
-			ret = vino_capture_next(vcs, 1);
-			if (ret)
-				return ret;
-		}
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
+	if (vcs->streaming) {
+		ret = vino_capture_next(vcs, 1);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
 }
 
-static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
-			   struct v4l2_buffer *b,
-			   unsigned int nonblocking)
+static int vino_dqbuf(struct file *file, void *__fh,
+			   struct v4l2_buffer *b)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
+	unsigned int nonblocking = file->f_flags & O_NONBLOCK;
+	struct vino_framebuffer *fb;
+	unsigned int incoming, outgoing;
+	int err;
+
 	if (vcs->reading)
 		return -EBUSY;
 
-	switch (b->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
-		struct vino_framebuffer *fb;
-		unsigned int incoming, outgoing;
-		int err;
+	/* TODO: check queue type */
 
-		// TODO: check queue type
+	err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
+	if (err) {
+		dprintk("vino_queue_get_incoming() failed\n");
+		return -EINVAL;
+	}
+	err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
+	if (err) {
+		dprintk("vino_queue_get_outgoing() failed\n");
+		return -EINVAL;
+	}
 
-		err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
-		if (err) {
-			dprintk("vino_queue_get_incoming() failed\n");
+	dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
+
+	if (outgoing == 0) {
+		if (incoming == 0) {
+			dprintk("no incoming or outgoing buffers\n");
 			return -EINVAL;
 		}
-		err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
-		if (err) {
-			dprintk("vino_queue_get_outgoing() failed\n");
-			return -EINVAL;
+		if (nonblocking) {
+			dprintk("non-blocking I/O was selected and "
+				"there are no buffers to dequeue\n");
+			return -EAGAIN;
 		}
 
-		dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
-
-		if (outgoing == 0) {
-			if (incoming == 0) {
-				dprintk("no incoming or outgoing buffers\n");
-				return -EINVAL;
-			}
-			if (nonblocking) {
-				dprintk("non-blocking I/O was selected and "
-					"there are no buffers to dequeue\n");
-				return -EAGAIN;
-			}
-
+		err = vino_wait_for_frame(vcs);
+		if (err) {
 			err = vino_wait_for_frame(vcs);
 			if (err) {
-				err = vino_wait_for_frame(vcs);
-				if (err) {
-					/* interrupted or
-					 * no frames captured because
-					 * of frame skipping */
-					// vino_capture_failed(vcs);
-					return -EIO;
-				}
+				/* interrupted or no frames captured because of
+				 * frame skipping */
+				/* vino_capture_failed(vcs); */
+				return -EIO;
 			}
 		}
+	}
 
-		fb = vino_queue_remove(&vcs->fb_queue, &b->index);
-		if (fb == NULL) {
-			dprintk("vino_queue_remove() failed\n");
-			return -EINVAL;
-		}
-
-		err = vino_check_buffer(vcs, fb);
+	fb = vino_queue_remove(&vcs->fb_queue, &b->index);
+	if (fb == NULL) {
+		dprintk("vino_queue_remove() failed\n");
+		return -EINVAL;
+	}
 
-		vino_v4l2_get_buffer_status(vcs, fb, b);
+	err = vino_check_buffer(vcs, fb);
 
-		if (err)
-			return -EIO;
+	vino_v4l2_get_buffer_status(vcs, fb, b);
 
-		break;
-	}
-	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-	default:
-		return -EINVAL;
-	}
+	if (err)
+		return -EIO;
 
 	return 0;
 }
 
-static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
+static int vino_streamon(struct file *file, void *__fh,
+		enum v4l2_buf_type i)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned int incoming;
 	int ret;
 	if (vcs->reading)
@@ -3792,8 +3597,10 @@ static int vino_v4l2_streamon(struct vin
 	return 0;
 }
 
-static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
+static int vino_streamoff(struct file *file, void *__fh,
+		enum v4l2_buf_type i)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	if (vcs->reading)
 		return -EBUSY;
 
@@ -3806,9 +3613,10 @@ static int vino_v4l2_streamoff(struct vi
 	return 0;
 }
 
-static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
+static int vino_queryctrl(struct file *file, void *__fh,
 			       struct v4l2_queryctrl *queryctrl)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 	int i;
 	int err = 0;
@@ -3855,9 +3663,10 @@ static int vino_v4l2_queryctrl(struct vi
 	return err;
 }
 
-static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
+static int vino_g_ctrl(struct file *file, void *__fh,
 			    struct v4l2_control *control)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 	int i;
 	int err = 0;
@@ -3866,56 +3675,38 @@ static int vino_v4l2_g_ctrl(struct vino_
 
 	switch (vcs->input) {
 	case VINO_INPUT_D1: {
-		struct indycam_control indycam_ctrl;
-
+		err = -EINVAL;
 		for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
-			if (vino_indycam_v4l2_controls[i].id ==
-			    control->id) {
-				goto found1;
+			if (vino_indycam_v4l2_controls[i].id == control->id) {
+				err = 0;
+				break;
 			}
 		}
 
-		err = -EINVAL;
-		goto out;
-
-found1:
-		indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
-
-		err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
-					 &indycam_ctrl);
-		if (err) {
-			err = -EINVAL;
+		if (err)
 			goto out;
-		}
 
-		control->value = indycam_ctrl.value;
+		err = camera_call(core, g_ctrl, control);
+		if (err)
+			err = -EINVAL;
 		break;
 	}
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO: {
-		struct saa7191_control saa7191_ctrl;
-
+		err = -EINVAL;
 		for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
-			if (vino_saa7191_v4l2_controls[i].id ==
-			    control->id) {
-				goto found2;
+			if (vino_saa7191_v4l2_controls[i].id == control->id) {
+				err = 0;
+				break;
 			}
 		}
 
-		err = -EINVAL;
-		goto out;
-
-found2:
-		saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
-
-		err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
-					  &saa7191_ctrl);
-		if (err) {
-			err = -EINVAL;
+		if (err)
 			goto out;
-		}
 
-		control->value = saa7191_ctrl.value;
+		err = decoder_call(core, g_ctrl, control);
+		if (err)
+			err = -EINVAL;
 		break;
 	}
 	default:
@@ -3928,9 +3719,10 @@ out:
 	return err;
 }
 
-static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
+static int vino_s_ctrl(struct file *file, void *__fh,
 			    struct v4l2_control *control)
 {
+	struct vino_channel_settings *vcs = video_drvdata(file);
 	unsigned long flags;
 	int i;
 	int err = 0;
@@ -3944,65 +3736,43 @@ static int vino_v4l2_s_ctrl(struct vino_
 
 	switch (vcs->input) {
 	case VINO_INPUT_D1: {
-		struct indycam_control indycam_ctrl;
-
+		err = -EINVAL;
 		for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
-			if (vino_indycam_v4l2_controls[i].id ==
-			    control->id) {
-				if ((control->value >=
-				     vino_indycam_v4l2_controls[i].minimum)
-				    && (control->value <=
-					vino_indycam_v4l2_controls[i].
-					maximum)) {
-					goto found1;
-				} else {
-					err = -ERANGE;
-					goto out;
-				}
+			if (vino_indycam_v4l2_controls[i].id == control->id) {
+				err = 0;
+				break;
 			}
 		}
-
-		err = -EINVAL;
-		goto out;
-
-found1:
-		indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
-		indycam_ctrl.value = control->value;
-
-		err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
-					 &indycam_ctrl);
+		if (err)
+			goto out;
+		if (control->value < vino_indycam_v4l2_controls[i].minimum ||
+		    control->value > vino_indycam_v4l2_controls[i].maximum) {
+			err = -ERANGE;
+			goto out;
+		}
+		err = camera_call(core, s_ctrl, control);
 		if (err)
 			err = -EINVAL;
 		break;
 	}
 	case VINO_INPUT_COMPOSITE:
 	case VINO_INPUT_SVIDEO: {
-		struct saa7191_control saa7191_ctrl;
-
+		err = -EINVAL;
 		for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
-			if (vino_saa7191_v4l2_controls[i].id ==
-			    control->id) {
-				if ((control->value >=
-				     vino_saa7191_v4l2_controls[i].minimum)
-				    && (control->value <=
-					vino_saa7191_v4l2_controls[i].
-					maximum)) {
-					goto found2;
-				} else {
-					err = -ERANGE;
-					goto out;
-				}
+			if (vino_saa7191_v4l2_controls[i].id == control->id) {
+				err = 0;
+				break;
 			}
 		}
-		err = -EINVAL;
-		goto out;
-
-found2:
-		saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
-		saa7191_ctrl.value = control->value;
+		if (err)
+			goto out;
+		if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
+		    control->value > vino_saa7191_v4l2_controls[i].maximum) {
+			err = -ERANGE;
+			goto out;
+		}
 
-		err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
-					  &saa7191_ctrl);
+		err = decoder_call(core, s_ctrl, control);
 		if (err)
 			err = -EINVAL;
 		break;
@@ -4233,116 +4003,9 @@ over:
 		ret = POLLIN | POLLRDNORM;
 
 error:
-
 	return ret;
 }
 
-static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
-	struct vino_channel_settings *vcs = video_drvdata(file);
-
-#ifdef VINO_DEBUG
-	switch (_IOC_TYPE(cmd)) {
-	case 'v':
-		dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
-		break;
-	case 'V':
-		dprintk("ioctl(): V4L2 %s (0x%08x)\n",
-			v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
-		break;
-	default:
-		dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
-	}
-#endif
-
-	switch (cmd) {
-	/* V4L2 interface */
-	case VIDIOC_QUERYCAP: {
-		vino_v4l2_querycap(arg);
-		break;
-	}
-	case VIDIOC_ENUMINPUT: {
-		return vino_v4l2_enuminput(vcs, arg);
-	}
-	case VIDIOC_G_INPUT: {
-		return vino_v4l2_g_input(vcs, arg);
-	}
-	case VIDIOC_S_INPUT: {
-		return vino_v4l2_s_input(vcs, arg);
-	}
-	case VIDIOC_ENUMSTD: {
-		return vino_v4l2_enumstd(vcs, arg);
-	}
-	case VIDIOC_QUERYSTD: {
-		return vino_v4l2_querystd(vcs, arg);
-	}
-	case VIDIOC_G_STD: {
-		return vino_v4l2_g_std(vcs, arg);
-	}
-	case VIDIOC_S_STD: {
-		return vino_v4l2_s_std(vcs, arg);
-	}
-	case VIDIOC_ENUM_FMT: {
-		return vino_v4l2_enum_fmt(vcs, arg);
-	}
-	case VIDIOC_TRY_FMT: {
-		return vino_v4l2_try_fmt(vcs, arg);
-	}
-	case VIDIOC_G_FMT: {
-		return vino_v4l2_g_fmt(vcs, arg);
-	}
-	case VIDIOC_S_FMT: {
-		return vino_v4l2_s_fmt(vcs, arg);
-	}
-	case VIDIOC_CROPCAP: {
-		return vino_v4l2_cropcap(vcs, arg);
-	}
-	case VIDIOC_G_CROP: {
-		return vino_v4l2_g_crop(vcs, arg);
-	}
-	case VIDIOC_S_CROP: {
-		return vino_v4l2_s_crop(vcs, arg);
-	}
-	case VIDIOC_G_PARM: {
-		return vino_v4l2_g_parm(vcs, arg);
-	}
-	case VIDIOC_S_PARM: {
-		return vino_v4l2_s_parm(vcs, arg);
-	}
-	case VIDIOC_REQBUFS: {
-		return vino_v4l2_reqbufs(vcs, arg);
-	}
-	case VIDIOC_QUERYBUF: {
-		return vino_v4l2_querybuf(vcs, arg);
-	}
-	case VIDIOC_QBUF: {
-		return vino_v4l2_qbuf(vcs, arg);
-	}
-	case VIDIOC_DQBUF: {
-		return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
-	}
-	case VIDIOC_STREAMON: {
-		return vino_v4l2_streamon(vcs);
-	}
-	case VIDIOC_STREAMOFF: {
-		return vino_v4l2_streamoff(vcs);
-	}
-	case VIDIOC_QUERYCTRL: {
-		return vino_v4l2_queryctrl(vcs, arg);
-	}
-	case VIDIOC_G_CTRL: {
-		return vino_v4l2_g_ctrl(vcs, arg);
-	}
-	case VIDIOC_S_CTRL: {
-		return vino_v4l2_s_ctrl(vcs, arg);
-	}
-	default:
-		return -ENOIOCTLCMD;
-	}
-
-	return 0;
-}
-
 static long vino_ioctl(struct file *file,
 		      unsigned int cmd, unsigned long arg)
 {
@@ -4352,7 +4015,7 @@ static long vino_ioctl(struct file *file
 	if (mutex_lock_interruptible(&vcs->mutex))
 		return -EINTR;
 
-	ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
+	ret = video_ioctl2(file, cmd, arg);
 
 	mutex_unlock(&vcs->mutex);
 
@@ -4364,45 +4027,75 @@ static long vino_ioctl(struct file *file
 /* __initdata */
 static int vino_init_stage;
 
+const struct v4l2_ioctl_ops vino_ioctl_ops = {
+	.vidioc_enum_fmt_vid_cap     = vino_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap 	     = vino_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap  	     = vino_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap	     = vino_try_fmt_vid_cap,
+	.vidioc_querycap    	     = vino_querycap,
+	.vidioc_enum_input   	     = vino_enum_input,
+	.vidioc_g_input      	     = vino_g_input,
+	.vidioc_s_input      	     = vino_s_input,
+	.vidioc_g_std 		     = vino_g_std,
+	.vidioc_s_std 		     = vino_s_std,
+	.vidioc_querystd             = vino_querystd,
+	.vidioc_cropcap      	     = vino_cropcap,
+	.vidioc_s_crop       	     = vino_s_crop,
+	.vidioc_g_crop       	     = vino_g_crop,
+	.vidioc_s_parm 		     = vino_s_parm,
+	.vidioc_g_parm 		     = vino_g_parm,
+	.vidioc_reqbufs              = vino_reqbufs,
+	.vidioc_querybuf             = vino_querybuf,
+	.vidioc_qbuf                 = vino_qbuf,
+	.vidioc_dqbuf                = vino_dqbuf,
+	.vidioc_streamon             = vino_streamon,
+	.vidioc_streamoff            = vino_streamoff,
+	.vidioc_queryctrl            = vino_queryctrl,
+	.vidioc_g_ctrl               = vino_g_ctrl,
+	.vidioc_s_ctrl               = vino_s_ctrl,
+};
+
 static const struct v4l2_file_operations vino_fops = {
 	.owner		= THIS_MODULE,
 	.open		= vino_open,
 	.release	= vino_close,
-	.ioctl		= vino_ioctl,
+	.unlocked_ioctl	= vino_ioctl,
 	.mmap		= vino_mmap,
 	.poll		= vino_poll,
 };
 
-static struct video_device v4l_device_template = {
+static struct video_device vdev_template = {
 	.name		= "NOT SET",
 	.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)
 {
 	switch(stage) {
+	case 11:
+		video_unregister_device(vino_drvdata->b.vdev);
+		vino_drvdata->b.vdev = NULL;
 	case 10:
-		video_unregister_device(vino_drvdata->b.v4l_device);
-		vino_drvdata->b.v4l_device = NULL;
+		video_unregister_device(vino_drvdata->a.vdev);
+		vino_drvdata->a.vdev = NULL;
 	case 9:
-		video_unregister_device(vino_drvdata->a.v4l_device);
-		vino_drvdata->a.v4l_device = NULL;
+		i2c_del_adapter(&vino_i2c_adapter);
 	case 8:
-		vino_i2c_del_bus();
-	case 7:
 		free_irq(SGI_VINO_IRQ, NULL);
+	case 7:
+		if (vino_drvdata->b.vdev) {
+			video_device_release(vino_drvdata->b.vdev);
+			vino_drvdata->b.vdev = NULL;
+		}
 	case 6:
-		if (vino_drvdata->b.v4l_device) {
-			video_device_release(vino_drvdata->b.v4l_device);
-			vino_drvdata->b.v4l_device = NULL;
+		if (vino_drvdata->a.vdev) {
+			video_device_release(vino_drvdata->a.vdev);
+			vino_drvdata->a.vdev = NULL;
 		}
 	case 5:
-		if (vino_drvdata->a.v4l_device) {
-			video_device_release(vino_drvdata->a.v4l_device);
-			vino_drvdata->a.v4l_device = NULL;
-		}
-	case 4:
 		/* all entries in dma_cpu dummy table have the same address */
 		dma_unmap_single(NULL,
 				 vino_drvdata->dummy_desc_table.dma_cpu[0],
@@ -4412,8 +4105,10 @@ static void vino_module_cleanup(int stag
 				  (void *)vino_drvdata->
 				  dummy_desc_table.dma_cpu,
 				  vino_drvdata->dummy_desc_table.dma);
-	case 3:
+	case 4:
 		free_page(vino_drvdata->dummy_page);
+	case 3:
+		v4l2_device_unregister(&vino_drvdata->v4l2_dev);
 	case 2:
 		kfree(vino_drvdata);
 	case 1:
@@ -4468,6 +4163,7 @@ static int vino_probe(void)
 static int vino_init(void)
 {
 	dma_addr_t dma_dummy_address;
+	int err;
 	int i;
 
 	vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
@@ -4476,6 +4172,12 @@ static int vino_init(void)
 		return -ENOMEM;
 	}
 	vino_init_stage++;
+	strlcpy(vino_drvdata->v4l2_dev.name, "vino",
+			sizeof(vino_drvdata->v4l2_dev.name));
+	err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
+	if (err)
+		return err;
+	vino_init_stage++;
 
 	/* create a dummy dma descriptor */
 	vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
@@ -4542,19 +4244,20 @@ static int vino_init_channel_settings(st
 	spin_lock_init(&vcs->fb_queue.queue_lock);
 	init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
 
-	vcs->v4l_device = video_device_alloc();
-	if (!vcs->v4l_device) {
+	vcs->vdev = video_device_alloc();
+	if (!vcs->vdev) {
 		vino_module_cleanup(vino_init_stage);
 		return -ENOMEM;
 	}
 	vino_init_stage++;
 
-	memcpy(vcs->v4l_device, &v4l_device_template,
+	memcpy(vcs->vdev, &vdev_template,
 	       sizeof(struct video_device));
-	strcpy(vcs->v4l_device->name, name);
-	vcs->v4l_device->release = video_device_release;
+	strcpy(vcs->vdev->name, name);
+	vcs->vdev->release = video_device_release;
+	vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
 
-	video_set_drvdata(vcs->v4l_device, vcs);
+	video_set_drvdata(vcs->vdev, vcs);
 
 	return 0;
 }
@@ -4580,12 +4283,12 @@ static int __init vino_module_init(void)
 	spin_lock_init(&vino_drvdata->input_lock);
 
 	ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
-				    vino_v4l_device_name_a);
+				    vino_vdev_name_a);
 	if (ret)
 		return ret;
 
 	ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
-				    vino_v4l_device_name_b);
+				    vino_vdev_name_b);
 	if (ret)
 		return ret;
 
@@ -4601,15 +4304,16 @@ static int __init vino_module_init(void)
 	}
 	vino_init_stage++;
 
-	ret = vino_i2c_add_bus();
+	ret = i2c_add_adapter(&vino_i2c_adapter);
 	if (ret) {
 		printk(KERN_ERR "VINO I2C bus registration failed\n");
 		vino_module_cleanup(vino_init_stage);
 		return ret;
 	}
+	i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
 	vino_init_stage++;
 
-	ret = video_register_device(vino_drvdata->a.v4l_device,
+	ret = video_register_device(vino_drvdata->a.vdev,
 				    VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		printk(KERN_ERR "VINO channel A Video4Linux-device "
@@ -4619,7 +4323,7 @@ static int __init vino_module_init(void)
 	}
 	vino_init_stage++;
 
-	ret = video_register_device(vino_drvdata->b.v4l_device,
+	ret = video_register_device(vino_drvdata->b.vdev,
 				    VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		printk(KERN_ERR "VINO channel B Video4Linux-device "
@@ -4629,10 +4333,12 @@ static int __init vino_module_init(void)
 	}
 	vino_init_stage++;
 
-#ifdef MODULE
-	request_module("saa7191");
-	request_module("indycam");
-#endif
+	vino_drvdata->decoder =
+		v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
+			&vino_i2c_adapter, "saa7191", "saa7191", 0x45);
+	vino_drvdata->camera =
+		v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
+			&vino_i2c_adapter, "indycam", "indycam", 0x2b);
 
 	dprintk("init complete!\n");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/vivi.c linux-libre-2.6.30-gnu1/drivers/media/video/vivi.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/vivi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/vivi.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,17 +28,14 @@
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <linux/dma-mapping.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
 #include <linux/interrupt.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/freezer.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include "font.h"
 
 #define VIVI_MODULE_NAME "vivi"
 
@@ -47,18 +44,32 @@
 #define WAKE_DENOMINATOR 1001
 #define BUFFER_TIMEOUT     msecs_to_jiffies(500)  /* 0.5 seconds */
 
-#include "font.h"
-
 #define VIVI_MAJOR_VERSION 0
-#define VIVI_MINOR_VERSION 5
+#define VIVI_MINOR_VERSION 6
 #define VIVI_RELEASE 0
 #define VIVI_VERSION \
 	KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
 
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
-static int video_nr = -1;		/* /dev/videoN, -1 for autodetect */
-static int n_devs = 1;			/* Number of virtual devices */
+MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
+MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+static unsigned n_devs = 1;
+module_param(n_devs, uint, 0644);
+MODULE_PARM_DESC(n_devs, "number of video devices to create");
+
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+static unsigned int vid_limit = 16;
+module_param(vid_limit, uint, 0644);
+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
 
 /* supported controls */
 static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -69,7 +80,7 @@ static struct v4l2_queryctrl vivi_qctrl[
 		.maximum       = 65535,
 		.step          = 65535/100,
 		.default_value = 65535,
-		.flags         = 0,
+		.flags         = V4L2_CTRL_FLAG_SLIDER,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
 	}, {
 		.id            = V4L2_CID_BRIGHTNESS,
@@ -79,7 +90,7 @@ static struct v4l2_queryctrl vivi_qctrl[
 		.maximum       = 255,
 		.step          = 1,
 		.default_value = 127,
-		.flags         = 0,
+		.flags         = V4L2_CTRL_FLAG_SLIDER,
 	}, {
 		.id            = V4L2_CID_CONTRAST,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
@@ -88,7 +99,7 @@ static struct v4l2_queryctrl vivi_qctrl[
 		.maximum       = 255,
 		.step          = 0x1,
 		.default_value = 0x10,
-		.flags         = 0,
+		.flags         = V4L2_CTRL_FLAG_SLIDER,
 	}, {
 		.id            = V4L2_CID_SATURATION,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
@@ -97,7 +108,7 @@ static struct v4l2_queryctrl vivi_qctrl[
 		.maximum       = 255,
 		.step          = 0x1,
 		.default_value = 127,
-		.flags         = 0,
+		.flags         = V4L2_CTRL_FLAG_SLIDER,
 	}, {
 		.id            = V4L2_CID_HUE,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
@@ -106,17 +117,12 @@ static struct v4l2_queryctrl vivi_qctrl[
 		.maximum       = 127,
 		.step          = 0x1,
 		.default_value = 0,
-		.flags         = 0,
+		.flags         = V4L2_CTRL_FLAG_SLIDER,
 	}
 };
 
-static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
-
-#define dprintk(dev, level, fmt, arg...)				\
-	do {								\
-		if (dev->vfd->debug >= (level))				\
-			printk(KERN_DEBUG "vivi: " fmt , ## arg);	\
-	} while (0)
+#define dprintk(dev, level, fmt, arg...) \
+	v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
 
 /* ------------------------------------------------------------------
 	Basic structures
@@ -206,6 +212,7 @@ static LIST_HEAD(vivi_devlist);
 
 struct vivi_dev {
 	struct list_head           vivi_devlist;
+	struct v4l2_device 	   v4l2_dev;
 
 	spinlock_t                 slock;
 	struct mutex		   mutex;
@@ -223,6 +230,12 @@ struct vivi_dev {
 	char                       timestr[13];
 
 	int			   mv_count;	/* Controls bars movement */
+
+	/* Input Number */
+	int			   input;
+
+	/* Control 'registers' */
+	int 			   qctl_regs[ARRAY_SIZE(vivi_qctrl)];
 };
 
 struct vivi_fh {
@@ -235,6 +248,7 @@ struct vivi_fh {
 
 	enum v4l2_buf_type         type;
 	unsigned char              bars[8][3];
+	int			   input; 	/* Input Number on bars */
 };
 
 /* ------------------------------------------------------------------
@@ -254,18 +268,72 @@ enum colors {
 	BLACK,
 };
 
-static u8 bars[8][3] = {
 	/* R   G   B */
-	{204, 204, 204},  /* white */
-	{208, 208,   0},  /* ambar */
-	{  0, 206, 206},  /* cyan */
-	{  0, 239,   0},  /* green */
-	{239,   0, 239},  /* magenta */
-	{205,   0,   0},  /* red */
-	{  0,   0, 255},  /* blue */
-	{  0,   0,   0},  /* black */
+#define COLOR_WHITE	{204, 204, 204}
+#define COLOR_AMBAR	{208, 208,   0}
+#define COLOR_CIAN	{  0, 206, 206}
+#define	COLOR_GREEN	{  0, 239,   0}
+#define COLOR_MAGENTA	{239,   0, 239}
+#define COLOR_RED	{205,   0,   0}
+#define COLOR_BLUE	{  0,   0, 255}
+#define COLOR_BLACK	{  0,   0,   0}
+
+struct bar_std {
+	u8 bar[8][3];
+};
+
+/* Maximum number of bars are 10 - otherwise, the input print code
+   should be modified */
+static struct bar_std bars[] = {
+	{	/* Standard ITU-R color bar sequence */
+		{
+			COLOR_WHITE,
+			COLOR_AMBAR,
+			COLOR_CIAN,
+			COLOR_GREEN,
+			COLOR_MAGENTA,
+			COLOR_RED,
+			COLOR_BLUE,
+			COLOR_BLACK,
+		}
+	}, {
+		{
+			COLOR_WHITE,
+			COLOR_AMBAR,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_AMBAR,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_AMBAR,
+		}
+	}, {
+		{
+			COLOR_WHITE,
+			COLOR_CIAN,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_CIAN,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_CIAN,
+		}
+	}, {
+		{
+			COLOR_WHITE,
+			COLOR_GREEN,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_GREEN,
+			COLOR_BLACK,
+			COLOR_WHITE,
+			COLOR_GREEN,
+		}
+	},
 };
 
+#define NUM_INPUTS ARRAY_SIZE(bars)
+
 #define TO_Y(r, g, b) \
 	(((16829 * r + 33039 * g + 6416 * b  + 32768) >> 16) + 16)
 /* RGB to  V(Cr) Color transform */
@@ -275,9 +343,10 @@ static u8 bars[8][3] = {
 #define TO_U(r, g, b) \
 	(((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
 
-#define TSTAMP_MIN_Y 24
-#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
-#define TSTAMP_MIN_X 64
+#define TSTAMP_MIN_Y	24
+#define TSTAMP_MAX_Y	(TSTAMP_MIN_Y + 15)
+#define TSTAMP_INPUT_X	10
+#define TSTAMP_MIN_X	(54 + TSTAMP_INPUT_X)
 
 static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
 {
@@ -392,9 +461,29 @@ static void gen_line(struct vivi_fh *fh,
 		pos += 4; /* only 16 bpp supported for now */
 	}
 
-	/* Checks if it is possible to show timestamp */
+	/* Prints input entry number */
+
+	/* Checks if it is possible to input number */
 	if (TSTAMP_MAX_Y >= hmax)
 		goto end;
+
+	if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
+		goto end;
+
+	if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
+		chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
+		pos = TSTAMP_INPUT_X;
+		for (i = 0; i < 7; i++) {
+			/* Draw white font on black background */
+			if (chr & 1 << (7 - i))
+				gen_twopix(fh, basep + pos, WHITE);
+			else
+				gen_twopix(fh, basep + pos, BLACK);
+			pos += 2;
+		}
+	}
+
+	/* Checks if it is possible to show timestamp */
 	if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
 		goto end;
 
@@ -577,7 +666,7 @@ static int vivi_start_thread(struct vivi
 	dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
 
 	if (IS_ERR(dma_q->kthread)) {
-		printk(KERN_ERR "vivi: kernel_thread() failed\n");
+		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
 		return PTR_ERR(dma_q->kthread);
 	}
 	/* Wakes thread */
@@ -720,8 +809,12 @@ static struct videobuf_queue_ops vivi_vi
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
+	struct vivi_fh  *fh  = priv;
+	struct vivi_dev *dev = fh->dev;
+
 	strcpy(cap->driver, "vivi");
 	strcpy(cap->card, "vivi");
+	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
 	cap->version = VIVI_VERSION;
 	cap->capabilities =	V4L2_CAP_VIDEO_CAPTURE |
 				V4L2_CAP_STREAMING     |
@@ -807,38 +900,19 @@ static int vidioc_try_fmt_vid_cap(struct
 	return 0;
 }
 
-/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-					struct v4l2_format *f)
+/* precalculate color bar values to speed up rendering */
+static void precalculate_bars(struct vivi_fh *fh)
 {
-	struct vivi_fh  *fh = priv;
-	struct videobuf_queue *q = &fh->vb_vidq;
+	struct vivi_dev *dev = fh->dev;
 	unsigned char r, g, b;
 	int k, is_yuv;
 
-	int ret = vidioc_try_fmt_vid_cap(file, fh, f);
-	if (ret < 0)
-		return (ret);
-
-	mutex_lock(&q->vb_lock);
-
-	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
-		dprintk(fh->dev, 1, "%s queue busy\n", __func__);
-		ret = -EBUSY;
-		goto out;
-	}
-
-	fh->fmt           = get_format(f);
-	fh->width         = f->fmt.pix.width;
-	fh->height        = f->fmt.pix.height;
-	fh->vb_vidq.field = f->fmt.pix.field;
-	fh->type          = f->type;
+	fh->input = dev->input;
 
-	/* precalculate color bar values to speed up rendering */
 	for (k = 0; k < 8; k++) {
-		r = bars[k][0];
-		g = bars[k][1];
-		b = bars[k][2];
+		r = bars[fh->input].bar[k][0];
+		g = bars[fh->input].bar[k][1];
+		b = bars[fh->input].bar[k][2];
 		is_yuv = 0;
 
 		switch (fh->fmt->fourcc) {
@@ -871,11 +945,40 @@ static int vidioc_s_fmt_vid_cap(struct f
 		}
 	}
 
+}
+
+/*FIXME: This seems to be generic enough to be at videodev2 */
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	struct vivi_fh *fh = priv;
+	struct videobuf_queue *q = &fh->vb_vidq;
+
+	int ret = vidioc_try_fmt_vid_cap(file, fh, f);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&q->vb_lock);
+
+	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+		dprintk(fh->dev, 1, "%s queue busy\n", __func__);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	fh->fmt           = get_format(f);
+	fh->width         = f->fmt.pix.width;
+	fh->height        = f->fmt.pix.height;
+	fh->vb_vidq.field = f->fmt.pix.field;
+	fh->type          = f->type;
+
+	precalculate_bars(fh);
+
 	ret = 0;
 out:
 	mutex_unlock(&q->vb_lock);
 
-	return (ret);
+	return ret;
 }
 
 static int vidioc_reqbufs(struct file *file, void *priv,
@@ -950,27 +1053,36 @@ static int vidioc_s_std(struct file *fil
 static int vidioc_enum_input(struct file *file, void *priv,
 				struct v4l2_input *inp)
 {
-	if (inp->index != 0)
+	if (inp->index >= NUM_INPUTS)
 		return -EINVAL;
 
 	inp->type = V4L2_INPUT_TYPE_CAMERA;
 	inp->std = V4L2_STD_525_60;
-	strcpy(inp->name, "Camera");
+	sprintf(inp->name, "Camera %u", inp->index);
 
 	return (0);
 }
 
 static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 {
-	*i = 0;
+	struct vivi_fh *fh = priv;
+	struct vivi_dev *dev = fh->dev;
+
+	*i = dev->input;
 
 	return (0);
 }
 static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 {
-	if (i > 0)
+	struct vivi_fh *fh = priv;
+	struct vivi_dev *dev = fh->dev;
+
+	if (i >= NUM_INPUTS)
 		return -EINVAL;
 
+	dev->input = i;
+	precalculate_bars(fh);
+
 	return (0);
 }
 
@@ -993,12 +1105,14 @@ static int vidioc_queryctrl(struct file
 static int vidioc_g_ctrl(struct file *file, void *priv,
 			 struct v4l2_control *ctrl)
 {
+	struct vivi_fh *fh = priv;
+	struct vivi_dev *dev = fh->dev;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
 		if (ctrl->id == vivi_qctrl[i].id) {
-			ctrl->value = qctl_regs[i];
-			return (0);
+			ctrl->value = dev->qctl_regs[i];
+			return 0;
 		}
 
 	return -EINVAL;
@@ -1006,16 +1120,18 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
+	struct vivi_fh *fh = priv;
+	struct vivi_dev *dev = fh->dev;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
 		if (ctrl->id == vivi_qctrl[i].id) {
-			if (ctrl->value < vivi_qctrl[i].minimum
-			    || ctrl->value > vivi_qctrl[i].maximum) {
-					return (-ERANGE);
-				}
-			qctl_regs[i] = ctrl->value;
-			return (0);
+			if (ctrl->value < vivi_qctrl[i].minimum ||
+			    ctrl->value > vivi_qctrl[i].maximum) {
+				return -ERANGE;
+			}
+			dev->qctl_regs[i] = ctrl->value;
+			return 0;
 		}
 	return -EINVAL;
 }
@@ -1026,32 +1142,20 @@ static int vidioc_s_ctrl(struct file *fi
 
 static int vivi_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct vivi_dev *dev;
+	struct vivi_dev *dev = video_drvdata(file);
 	struct vivi_fh *fh = NULL;
-	int i;
 	int retval = 0;
 
-	printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
-
-	lock_kernel();
-	list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
-		if (dev->vfd->minor == minor)
-			goto found;
-	unlock_kernel();
-	return -ENODEV;
-
-found:
 	mutex_lock(&dev->mutex);
 	dev->users++;
 
 	if (dev->users > 1) {
 		dev->users--;
-		retval = -EBUSY;
-		goto unlock;
+		mutex_unlock(&dev->mutex);
+		return -EBUSY;
 	}
 
-	dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
+	dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 
 	/* allocate + initialize per filehandle data */
@@ -1059,14 +1163,11 @@ found:
 	if (NULL == fh) {
 		dev->users--;
 		retval = -ENOMEM;
-		goto unlock;
 	}
-unlock:
 	mutex_unlock(&dev->mutex);
-	if (retval) {
-		unlock_kernel();
+
+	if (retval)
 		return retval;
-	}
 
 	file->private_data = fh;
 	fh->dev      = dev;
@@ -1076,10 +1177,6 @@ unlock:
 	fh->width    = 640;
 	fh->height   = 480;
 
-	/* Put all controls at a sane state */
-	for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
-		qctl_regs[i] = vivi_qctrl[i].default_value;
-
 	/* Resets frame counters */
 	dev->h = 0;
 	dev->m = 0;
@@ -1095,7 +1192,6 @@ unlock:
 			sizeof(struct vivi_buffer), fh);
 
 	vivi_start_thread(fh);
-	unlock_kernel();
 
 	return 0;
 }
@@ -1151,32 +1247,6 @@ static int vivi_close(struct file *file)
 	return 0;
 }
 
-static int vivi_release(void)
-{
-	struct vivi_dev *dev;
-	struct list_head *list;
-
-	while (!list_empty(&vivi_devlist)) {
-		list = vivi_devlist.next;
-		list_del(list);
-		dev = list_entry(list, struct vivi_dev, vivi_devlist);
-
-		if (-1 != dev->vfd->minor) {
-			printk(KERN_INFO "%s: unregistering /dev/video%d\n",
-				VIVI_MODULE_NAME, dev->vfd->num);
-			video_unregister_device(dev->vfd);
-		} else {
-			printk(KERN_INFO "%s: releasing /dev/video%d\n",
-				VIVI_MODULE_NAME, dev->vfd->num);
-			video_device_release(dev->vfd);
-		}
-
-		kfree(dev);
-	}
-
-	return 0;
-}
-
 static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct vivi_fh  *fh = file->private_data;
@@ -1239,87 +1309,130 @@ static struct video_device vivi_template
 	.tvnorms              = V4L2_STD_525_60,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
+
 /* -----------------------------------------------------------------
 	Initialization and module stuff
    ------------------------------------------------------------------*/
 
-/* This routine allocates from 1 to n_devs virtual drivers.
+static int vivi_release(void)
+{
+	struct vivi_dev *dev;
+	struct list_head *list;
 
-   The real maximum number of virtual drivers will depend on how many drivers
-   will succeed. This is limited to the maximum number of devices that
-   videodev supports. Since there are 64 minors for video grabbers, this is
-   currently the theoretical maximum limit. However, a further limit does
-   exist at videodev that forbids any driver to register more than 32 video
-   grabbers.
- */
-static int __init vivi_init(void)
+	while (!list_empty(&vivi_devlist)) {
+		list = vivi_devlist.next;
+		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);
+		video_unregister_device(dev->vfd);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+	}
+
+	return 0;
+}
+
+static int __init vivi_create_instance(int inst)
 {
-	int ret = -ENOMEM, i;
 	struct vivi_dev *dev;
 	struct video_device *vfd;
+	int ret, i;
 
-	if (n_devs <= 0)
-		n_devs = 1;
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
 
-	for (i = 0; i < n_devs; i++) {
-		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (!dev)
-			break;
+	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+			"%s-%03d", VIVI_MODULE_NAME, inst);
+	ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+	if (ret)
+		goto free_dev;
 
-		/* init video dma queues */
-		INIT_LIST_HEAD(&dev->vidq.active);
-		init_waitqueue_head(&dev->vidq.wq);
+	/* init video dma queues */
+	INIT_LIST_HEAD(&dev->vidq.active);
+	init_waitqueue_head(&dev->vidq.wq);
 
-		/* initialize locks */
-		spin_lock_init(&dev->slock);
-		mutex_init(&dev->mutex);
+	/* initialize locks */
+	spin_lock_init(&dev->slock);
+	mutex_init(&dev->mutex);
 
-		vfd = video_device_alloc();
-		if (!vfd) {
-			kfree(dev);
-			break;
-		}
+	ret = -ENOMEM;
+	vfd = video_device_alloc();
+	if (!vfd)
+		goto unreg_dev;
 
-		*vfd = vivi_template;
+	*vfd = vivi_template;
 
-		ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
-		if (ret < 0) {
-			video_device_release(vfd);
-			kfree(dev);
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+	if (ret < 0)
+		goto rel_vdev;
 
-			/* If some registers succeeded, keep driver */
-			if (i)
-				ret = 0;
+	video_set_drvdata(vfd, dev);
 
-			break;
-		}
+	/* Set all controls to their default value. */
+	for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
+		dev->qctl_regs[i] = vivi_qctrl[i].default_value;
 
-		/* Now that everything is fine, let's add it to device list */
-		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+	/* 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->minor);
+	snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+			vivi_template.name, vfd->num);
 
-		if (video_nr >= 0)
-			video_nr++;
+	if (video_nr >= 0)
+		video_nr++;
 
-		dev->vfd = vfd;
-		printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
-			VIVI_MODULE_NAME, vfd->num);
+	dev->vfd = vfd;
+	v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
+			vfd->num);
+	return 0;
+
+rel_vdev:
+	video_device_release(vfd);
+unreg_dev:
+	v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+	kfree(dev);
+	return ret;
+}
+
+/* This routine allocates from 1 to n_devs virtual drivers.
+
+   The real maximum number of virtual drivers will depend on how many drivers
+   will succeed. This is limited to the maximum number of devices that
+   videodev supports, which is equal to VIDEO_NUM_DEVICES.
+ */
+static int __init vivi_init(void)
+{
+	int ret = 0, i;
+
+	if (n_devs <= 0)
+		n_devs = 1;
+
+	for (i = 0; i < n_devs; i++) {
+		ret = vivi_create_instance(i);
+		if (ret) {
+			/* If some instantiations succeeded, keep driver */
+			if (i)
+				ret = 0;
+			break;
+		}
 	}
 
 	if (ret < 0) {
-		vivi_release();
 		printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
-	} else {
-		printk(KERN_INFO "Video Technology Magazine Virtual Video "
+		return ret;
+	}
+
+	printk(KERN_INFO "Video Technology Magazine Virtual Video "
 			"Capture Board ver %u.%u.%u successfully loaded.\n",
 			(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
 			VIVI_VERSION & 0xFF);
 
-		/* n_devs will reflect the actual number of allocated devices */
-		n_devs = i;
-	}
+	/* n_devs will reflect the actual number of allocated devices */
+	n_devs = i;
 
 	return ret;
 }
@@ -1331,19 +1444,3 @@ static void __exit vivi_exit(void)
 
 module_init(vivi_init);
 module_exit(vivi_exit);
-
-MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
-MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
-MODULE_LICENSE("Dual BSD/GPL");
-
-module_param(video_nr, uint, 0444);
-MODULE_PARM_DESC(video_nr, "video iminor start number");
-
-module_param(n_devs, uint, 0444);
-MODULE_PARM_DESC(n_devs, "number of video devices to create");
-
-module_param_named(debug, vivi_template.debug, int, 0444);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/vp27smpx.c linux-libre-2.6.30-gnu1/drivers/media/video/vp27smpx.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/vp27smpx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/vp27smpx.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,21 +129,16 @@ static int vp27smpx_log_status(struct v4
 	return 0;
 }
 
-static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
 	.log_status = vp27smpx_log_status,
 	.g_chip_ident = vp27smpx_g_chip_ident,
+	.s_std = vp27smpx_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
 	.s_radio = vp27smpx_s_radio,
-	.s_std = vp27smpx_s_std,
 	.s_tuner = vp27smpx_s_tuner,
 	.g_tuner = vp27smpx_g_tuner,
 };
@@ -206,8 +201,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "vp27smpx",
-	.driverid = I2C_DRIVERID_VP27SMPX,
-	.command = vp27smpx_command,
 	.probe = vp27smpx_probe,
 	.remove = vp27smpx_remove,
 	.id_table = vp27smpx_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/vpx3220.c linux-libre-2.6.30-gnu1/drivers/media/video/vpx3220.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/vpx3220.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/vpx3220.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,10 +24,10 @@
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
 MODULE_AUTHOR("Laurent Pinchart");
@@ -37,14 +37,17 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
+
 #define VPX_TIMEOUT_COUNT  10
 
 /* ----------------------------------------------------------------------- */
 
 struct vpx3220 {
+	struct v4l2_subdev sd;
 	unsigned char reg[255];
 
-	int norm;
+	v4l2_std_id norm;
+	int ident;
 	int input;
 	int enable;
 	int bright;
@@ -53,30 +56,38 @@ struct vpx3220 {
 	int sat;
 };
 
+static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct vpx3220, sd);
+}
+
 static char *inputs[] = { "internal", "composite", "svideo" };
 
 /* ----------------------------------------------------------------------- */
 
-static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct vpx3220 *decoder = i2c_get_clientdata(client);
 
 	decoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int vpx3220_read(struct i2c_client *client, u8 reg)
+static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int vpx3220_fp_status(struct i2c_client *client)
+static int vpx3220_fp_status(struct v4l2_subdev *sd)
 {
 	unsigned char status;
 	unsigned int i;
 
 	for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
-		status = vpx3220_read(client, 0x29);
+		status = vpx3220_read(sd, 0x29);
 
 		if (!(status & 4))
 			return 0;
@@ -90,57 +101,60 @@ static int vpx3220_fp_status(struct i2c_
 	return -1;
 }
 
-static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
+static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 	/* Write the 16-bit address to the FPWR register */
 	if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
-		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+		v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
 		return -1;
 	}
 
-	if (vpx3220_fp_status(client) < 0)
+	if (vpx3220_fp_status(sd) < 0)
 		return -1;
 
 	/* Write the 16-bit data to the FPDAT register */
 	if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
-		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+		v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
 		return -1;
 	}
 
 	return 0;
 }
 
-static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
+static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	s16 data;
 
 	/* Write the 16-bit address to the FPRD register */
 	if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
-		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+		v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
 		return -1;
 	}
 
-	if (vpx3220_fp_status(client) < 0)
+	if (vpx3220_fp_status(sd) < 0)
 		return -1;
 
 	/* Read the 16-bit data from the FPDAT register */
 	data = i2c_smbus_read_word_data(client, 0x28);
 	if (data == -1) {
-		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+		v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
 		return -1;
 	}
 
 	return swab16(data);
 }
 
-static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
 {
 	u8 reg;
 	int ret = -1;
 
 	while (len >= 2) {
 		reg = *data++;
-		ret = vpx3220_write(client, reg, *data++);
+		ret = vpx3220_write(sd, reg, *data++);
 		if (ret < 0)
 			break;
 		len -= 2;
@@ -149,7 +163,7 @@ static int vpx3220_write_block(struct i2
 	return ret;
 }
 
-static int vpx3220_write_fp_block(struct i2c_client *client,
+static int vpx3220_write_fp_block(struct v4l2_subdev *sd,
 		const u16 *data, unsigned int len)
 {
 	u8 reg;
@@ -157,7 +171,7 @@ static int vpx3220_write_fp_block(struct
 
 	while (len > 1) {
 		reg = *data++;
-		ret |= vpx3220_fp_write(client, reg, *data++);
+		ret |= vpx3220_fp_write(sd, reg, *data++);
 		len -= 2;
 	}
 
@@ -259,276 +273,274 @@ static const unsigned short init_fp[] =
 	0x4b, 0x298,		/* PLL gain */
 };
 
-static void vpx3220_dump_i2c(struct i2c_client *client)
+
+static int vpx3220_init(struct v4l2_subdev *sd, u32 val)
 {
-	int len = sizeof(init_common);
-	const unsigned char *data = init_common;
+	struct vpx3220 *decoder = to_vpx3220(sd);
 
-	while (len > 1) {
-		v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
-			*data, vpx3220_read(client, *data));
-		data += 2;
-		len -= 2;
-	}
+	vpx3220_write_block(sd, init_common, sizeof(init_common));
+	vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+	if (decoder->norm & V4L2_STD_NTSC)
+		vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+	else if (decoder->norm & V4L2_STD_PAL)
+		vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+	else if (decoder->norm & V4L2_STD_SECAM)
+		vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+	else
+		vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+	return 0;
 }
 
-static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
 {
-	struct vpx3220 *decoder = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case 0:
-	{
-		vpx3220_write_block(client, init_common,
-				    sizeof(init_common));
-		vpx3220_write_fp_block(client, init_fp,
-				       sizeof(init_fp) >> 1);
-		switch (decoder->norm) {
-		case VIDEO_MODE_NTSC:
-			vpx3220_write_fp_block(client, init_ntsc,
-					       sizeof(init_ntsc) >> 1);
-			break;
-
-		case VIDEO_MODE_PAL:
-			vpx3220_write_fp_block(client, init_pal,
-					       sizeof(init_pal) >> 1);
-			break;
-		case VIDEO_MODE_SECAM:
-			vpx3220_write_fp_block(client, init_secam,
-					       sizeof(init_secam) >> 1);
-			break;
-		default:
-			vpx3220_write_fp_block(client, init_pal,
-					       sizeof(init_pal) >> 1);
-			break;
-		}
-		break;
-	}
-
-	case DECODER_DUMP:
-	{
-		vpx3220_dump_i2c(client);
-		break;
-	}
-
-	case DECODER_GET_CAPABILITIES:
-	{
-		struct video_decoder_capability *cap = arg;
+	int res = V4L2_IN_ST_NO_SIGNAL, status;
+	v4l2_std_id std = 0;
 
-		v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
+	status = vpx3220_fp_read(sd, 0x0f3);
 
-		cap->flags = VIDEO_DECODER_PAL |
-			     VIDEO_DECODER_NTSC |
-			     VIDEO_DECODER_SECAM |
-			     VIDEO_DECODER_AUTO |
-			     VIDEO_DECODER_CCIR;
-		cap->inputs = 3;
-		cap->outputs = 1;
-		break;
-	}
+	v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
 
-	case DECODER_GET_STATUS:
-	{
-		int res = 0, status;
+	if (status < 0)
+		return status;
 
-		v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
+	if ((status & 0x20) == 0) {
+		res = 0;
 
-		status = vpx3220_fp_read(client, 0x0f3);
+		switch (status & 0x18) {
+		case 0x00:
+		case 0x10:
+		case 0x14:
+		case 0x18:
+			std = V4L2_STD_PAL;
+			break;
 
-		v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
+		case 0x08:
+			std = V4L2_STD_SECAM;
+			break;
 
-		if (status < 0)
-			return status;
+		case 0x04:
+		case 0x0c:
+		case 0x1c:
+			std = V4L2_STD_NTSC;
+			break;
+		}
+	}
+	if (pstd)
+		*pstd = std;
+	if (pstatus)
+		*pstatus = status;
+	return 0;
+}
 
-		if ((status & 0x20) == 0) {
-			res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
+static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	v4l2_dbg(1, debug, sd, "querystd\n");
+	return vpx3220_status(sd, NULL, std);
+}
 
-			switch (status & 0x18) {
-			case 0x00:
-			case 0x10:
-			case 0x14:
-			case 0x18:
-				res |= DECODER_STATUS_PAL;
-				break;
+static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	v4l2_dbg(1, debug, sd, "g_input_status\n");
+	return vpx3220_status(sd, status, NULL);
+}
 
-			case 0x08:
-				res |= DECODER_STATUS_SECAM;
-				break;
+static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct vpx3220 *decoder = to_vpx3220(sd);
+	int temp_input;
 
-			case 0x04:
-			case 0x0c:
-			case 0x1c:
-				res |= DECODER_STATUS_NTSC;
-				break;
-			}
-		}
+	/* Here we back up the input selection because it gets
+	   overwritten when we fill the registers with the
+	   choosen video norm */
+	temp_input = vpx3220_fp_read(sd, 0xf2);
 
-		*(int *) arg = res;
-		break;
+	v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
+	if (std & V4L2_STD_NTSC) {
+		vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+		v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
+	} else if (std & V4L2_STD_PAL) {
+		vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+		v4l2_dbg(1, debug, sd, "norm switched to PAL\n");
+	} else if (std & V4L2_STD_SECAM) {
+		vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+		v4l2_dbg(1, debug, sd, "norm switched to SECAM\n");
+	} else {
+		return -EINVAL;
 	}
 
-	case DECODER_SET_NORM:
-	{
-		int *iarg = arg, data;
-		int temp_input;
-
-		/* Here we back up the input selection because it gets
-		   overwritten when we fill the registers with the
-		   choosen video norm */
-		temp_input = vpx3220_fp_read(client, 0xf2);
-
-		v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
-		switch (*iarg) {
-		case VIDEO_MODE_NTSC:
-			vpx3220_write_fp_block(client, init_ntsc,
-					       sizeof(init_ntsc) >> 1);
-			v4l_dbg(1, debug, client, "norm switched to NTSC\n");
-			break;
+	decoder->norm = std;
 
-		case VIDEO_MODE_PAL:
-			vpx3220_write_fp_block(client, init_pal,
-					       sizeof(init_pal) >> 1);
-			v4l_dbg(1, debug, client, "norm switched to PAL\n");
-			break;
+	/* And here we set the backed up video input again */
+	vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010);
+	udelay(10);
+	return 0;
+}
 
-		case VIDEO_MODE_SECAM:
-			vpx3220_write_fp_block(client, init_secam,
-					       sizeof(init_secam) >> 1);
-			v4l_dbg(1, debug, client, "norm switched to SECAM\n");
-			break;
+static int vpx3220_s_routing(struct v4l2_subdev *sd,
+			     u32 input, u32 output, u32 config)
+{
+	int data;
 
-		case VIDEO_MODE_AUTO:
-			/* FIXME This is only preliminary support */
-			data = vpx3220_fp_read(client, 0xf2) & 0x20;
-			vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
-			v4l_dbg(1, debug, client, "norm switched to AUTO\n");
-			break;
+	/* RJ:   input = 0: ST8 (PCTV) input
+		 input = 1: COMPOSITE  input
+		 input = 2: SVHS       input  */
 
-		default:
-			return -EINVAL;
-		}
-		decoder->norm = *iarg;
+	const int input_vals[3][2] = {
+		{0x0c, 0},
+		{0x0d, 0},
+		{0x0e, 1}
+	};
 
-		/* And here we set the backed up video input again */
-		vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
-		udelay(10);
-		break;
-	}
+	if (input < 0 || input > 2)
+		return -EINVAL;
 
-	case DECODER_SET_INPUT:
-	{
-		int *iarg = arg, data;
+	v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[input]);
 
-		/* RJ:  *iarg = 0: ST8 (PCTV) input
-		 *iarg = 1: COMPOSITE  input
-		 *iarg = 2: SVHS       input  */
+	vpx3220_write(sd, 0x33, input_vals[input][0]);
 
-		const int input[3][2] = {
-			{0x0c, 0},
-			{0x0d, 0},
-			{0x0e, 1}
-		};
+	data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
+	if (data < 0)
+		return data;
+	/* 0x0010 is required to latch the setting */
+	vpx3220_fp_write(sd, 0xf2,
+			data | (input_vals[input][1] << 5) | 0x0010);
 
-		if (*iarg < 0 || *iarg > 2)
-			return -EINVAL;
+	udelay(10);
+	return 0;
+}
 
-		v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
+static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
 
-		vpx3220_write(client, 0x33, input[*iarg][0]);
+	vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
+	return 0;
+}
 
-		data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
-		if (data < 0)
-			return data;
-		/* 0x0010 is required to latch the setting */
-		vpx3220_fp_write(client, 0xf2,
-				 data | (input[*iarg][1] << 5) | 0x0010);
+static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	switch (qc->id) {
+	case V4L2_CID_BRIGHTNESS:
+		v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+		break;
 
-		udelay(10);
+	case V4L2_CID_CONTRAST:
+		v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
 		break;
-	}
 
-	case DECODER_SET_OUTPUT:
-	{
-		int *iarg = arg;
+	case V4L2_CID_SATURATION:
+		v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
+		break;
 
-		/* not much choice of outputs */
-		if (*iarg != 0) {
-			return -EINVAL;
-		}
+	case V4L2_CID_HUE:
+		v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
 		break;
-	}
 
-	case DECODER_ENABLE_OUTPUT:
-	{
-		int *iarg = arg;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
 
-		v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
+static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct vpx3220 *decoder = to_vpx3220(sd);
 
-		vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = decoder->bright;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = decoder->contrast;
 		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = decoder->sat;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = decoder->hue;
+		break;
+	default:
+		return -EINVAL;
 	}
+	return 0;
+}
 
-	case DECODER_SET_PICTURE:
-	{
-		struct video_picture *pic = arg;
+static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct vpx3220 *decoder = to_vpx3220(sd);
 
-		if (decoder->bright != pic->brightness) {
-			/* We want -128 to 128 we get 0-65535 */
-			decoder->bright = pic->brightness;
-			vpx3220_write(client, 0xe6,
-				      (decoder->bright - 32768) >> 8);
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (decoder->bright != ctrl->value) {
+			decoder->bright = ctrl->value;
+			vpx3220_write(sd, 0xe6, decoder->bright);
 		}
-		if (decoder->contrast != pic->contrast) {
-			/* We want 0 to 64 we get 0-65535 */
+		break;
+	case V4L2_CID_CONTRAST:
+		if (decoder->contrast != ctrl->value) {
 			/* Bit 7 and 8 is for noise shaping */
-			decoder->contrast = pic->contrast;
-			vpx3220_write(client, 0xe7,
-				      (decoder->contrast >> 10) + 192);
+			decoder->contrast = ctrl->value;
+			vpx3220_write(sd, 0xe7, decoder->contrast + 192);
 		}
-		if (decoder->sat != pic->colour) {
-			/* We want 0 to 4096 we get 0-65535 */
-			decoder->sat = pic->colour;
-			vpx3220_fp_write(client, 0xa0,
-					 decoder->sat >> 4);
+		break;
+	case V4L2_CID_SATURATION:
+		if (decoder->sat != ctrl->value) {
+			decoder->sat = ctrl->value;
+			vpx3220_fp_write(sd, 0xa0, decoder->sat);
 		}
-		if (decoder->hue != pic->hue) {
-			/* We want -512 to 512 we get 0-65535 */
-			decoder->hue = pic->hue;
-			vpx3220_fp_write(client, 0x1c,
-					 ((decoder->hue - 32768) >> 6) & 0xFFF);
+		break;
+	case V4L2_CID_HUE:
+		if (decoder->hue != ctrl->value) {
+			decoder->hue = ctrl->value;
+			vpx3220_fp_write(sd, 0x1c, decoder->hue);
 		}
 		break;
-	}
-
 	default:
 		return -EINVAL;
 	}
-
 	return 0;
 }
 
-static int vpx3220_init_client(struct i2c_client *client)
+static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
-	vpx3220_write_block(client, init_common, sizeof(init_common));
-	vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
-	/* Default to PAL */
-	vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1);
+	struct vpx3220 *decoder = to_vpx3220(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	return 0;
+	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
 }
 
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
+	.g_chip_ident = vpx3220_g_chip_ident,
+	.init = vpx3220_init,
+	.g_ctrl = vpx3220_g_ctrl,
+	.s_ctrl = vpx3220_s_ctrl,
+	.queryctrl = vpx3220_queryctrl,
+	.s_std = vpx3220_s_std,
+};
+
+static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
+	.s_routing = vpx3220_s_routing,
+	.s_stream = vpx3220_s_stream,
+	.querystd = vpx3220_querystd,
+	.g_input_status = vpx3220_g_input_status,
+};
+
+static const struct v4l2_subdev_ops vpx3220_ops = {
+	.core = &vpx3220_core_ops,
+	.video = &vpx3220_video_ops,
+};
+
 /* -----------------------------------------------------------------------
  * Client management code
  */
 
-static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
 static int vpx3220_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct vpx3220 *decoder;
+	struct v4l2_subdev *sd;
 	const char *name = NULL;
 	u8 ver;
 	u16 pn;
@@ -541,18 +553,20 @@ static int vpx3220_probe(struct i2c_clie
 	decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
-	decoder->norm = VIDEO_MODE_PAL;
+	sd = &decoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &vpx3220_ops);
+	decoder->norm = V4L2_STD_PAL;
 	decoder->input = 0;
 	decoder->enable = 1;
 	decoder->bright = 32768;
 	decoder->contrast = 32768;
 	decoder->hue = 32768;
 	decoder->sat = 32768;
-	i2c_set_clientdata(client, decoder);
 
 	ver = i2c_smbus_read_byte_data(client, 0x00);
 	pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
 		i2c_smbus_read_byte_data(client, 0x01);
+	decoder->ident = V4L2_IDENT_VPX3220A;
 	if (ver == 0xec) {
 		switch (pn) {
 		case 0x4680:
@@ -560,26 +574,34 @@ static int vpx3220_probe(struct i2c_clie
 			break;
 		case 0x4260:
 			name = "vpx3216b";
+			decoder->ident = V4L2_IDENT_VPX3216B;
 			break;
 		case 0x4280:
 			name = "vpx3214c";
+			decoder->ident = V4L2_IDENT_VPX3214C;
 			break;
 		}
 	}
 	if (name)
-		v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+		v4l2_info(sd, "%s found @ 0x%x (%s)\n", name,
 			client->addr << 1, client->adapter->name);
 	else
-		v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+		v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n",
 			ver, pn, client->addr << 1, client->adapter->name);
 
-	vpx3220_init_client(client);
+	vpx3220_write_block(sd, init_common, sizeof(init_common));
+	vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+	/* Default to PAL */
+	vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
 	return 0;
 }
 
 static int vpx3220_remove(struct i2c_client *client)
 {
-	kfree(i2c_get_clientdata(client));
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_vpx3220(sd));
 	return 0;
 }
 
@@ -593,8 +615,6 @@ MODULE_DEVICE_TABLE(i2c, vpx3220_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "vpx3220",
-	.driverid = I2C_DRIVERID_VPX3220,
-	.command = vpx3220_command,
 	.probe = vpx3220_probe,
 	.remove = vpx3220_remove,
 	.id_table = vpx3220_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/w9966.c linux-libre-2.6.30-gnu1/drivers/media/video/w9966.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/w9966.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/w9966.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,7 +57,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/videodev2.h>
+#include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/parport.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/w9968cf.c linux-libre-2.6.30-gnu1/drivers/media/video/w9968cf.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/w9968cf.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/w9968cf.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,6 +42,7 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <linux/page-flags.h>
+#include <linux/videodev.h>
 #include <media/v4l2-ioctl.h>
 
 #include "w9968cf.h"
@@ -68,7 +69,6 @@ MODULE_VERSION(W9968CF_MODULE_VERSION);
 MODULE_LICENSE(W9968CF_MODULE_LICENSE);
 MODULE_SUPPORTED_DEVICE("Video");
 
-static int ovmod_load = W9968CF_OVMOD_LOAD;
 static unsigned short simcams = W9968CF_SIMCAMS;
 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
@@ -111,9 +111,6 @@ static int specific_debug = W9968CF_SPEC
 
 static unsigned int param_nv[24]; /* number of values per parameter */
 
-#ifdef CONFIG_MODULES
-module_param(ovmod_load, bool, 0644);
-#endif
 module_param(simcams, ushort, 0644);
 module_param_array(video_nr, short, &param_nv[0], 0444);
 module_param_array(packet_size, uint, &param_nv[1], 0444);
@@ -144,18 +141,6 @@ module_param(debug, ushort, 0644);
 module_param(specific_debug, bool, 0644);
 #endif
 
-#ifdef CONFIG_MODULES
-MODULE_PARM_DESC(ovmod_load,
-		 "\n<0|1> Automatic 'ovcamchip' module loading."
-		 "\n0 disabled, 1 enabled."
-		 "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
-		 "\nmodule in the system, according to its configuration, and"
-		 "\nattempts to load that module automatically. This action is"
-		 "\nperformed once as soon as the 'w9968cf' module is loaded"
-		 "\ninto memory."
-		 "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
-		 "\n");
-#endif
 MODULE_PARM_DESC(simcams,
 		 "\n<n> Number of cameras allowed to stream simultaneously."
 		 "\nn may vary from 0 to "
@@ -443,8 +428,6 @@ static int w9968cf_i2c_smbus_xfer(struct
 				  unsigned short flags, char read_write,
 				  u8 command, int size, union i2c_smbus_data*);
 static u32 w9968cf_i2c_func(struct i2c_adapter*);
-static int w9968cf_i2c_attach_inform(struct i2c_client*);
-static int w9968cf_i2c_detach_inform(struct i2c_client*);
 
 /* Memory management */
 static void* rvmalloc(unsigned long size);
@@ -1443,19 +1426,11 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapte
 		       unsigned short flags, char read_write, u8 command,
 		       int size, union i2c_smbus_data *data)
 {
-	struct w9968cf_device* cam = i2c_get_adapdata(adapter);
+	struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+	struct w9968cf_device *cam = to_cam(v4l2_dev);
 	u8 i;
 	int err = 0;
 
-	switch (addr) {
-		case OV6xx0_SID:
-		case OV7xx0_SID:
-			break;
-		default:
-			DBG(4, "Rejected slave ID 0x%04X", addr)
-			return -EINVAL;
-	}
-
 	if (size == I2C_SMBUS_BYTE) {
 		/* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
 		addr <<= 1;
@@ -1463,8 +1438,17 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapte
 		if (read_write == I2C_SMBUS_WRITE)
 			err = w9968cf_i2c_adap_write_byte(cam, addr, command);
 		else if (read_write == I2C_SMBUS_READ)
-			err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
-
+			for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
+				err = w9968cf_i2c_adap_read_byte(cam, addr,
+							 &data->byte);
+				if (err) {
+					if (w9968cf_smbus_refresh_bus(cam)) {
+						err = -EIO;
+						break;
+					}
+				} else
+					break;
+			}
 	} else if (size == I2C_SMBUS_BYTE_DATA) {
 		addr <<= 1;
 
@@ -1491,7 +1475,6 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapte
 		DBG(4, "Unsupported I2C transfer mode (%d)", size)
 		return -EINVAL;
 	}
-
 	return err;
 }
 
@@ -1504,44 +1487,6 @@ static u32 w9968cf_i2c_func(struct i2c_a
 }
 
 
-static int w9968cf_i2c_attach_inform(struct i2c_client* client)
-{
-	struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-	int id = client->driver->id, err = 0;
-
-	if (id == I2C_DRIVERID_OVCAMCHIP) {
-		cam->sensor_client = client;
-		err = w9968cf_sensor_init(cam);
-		if (err) {
-			cam->sensor_client = NULL;
-			return err;
-		}
-	} else {
-		DBG(4, "Rejected client [%s] with driver [%s]",
-		    client->name, client->driver->driver.name)
-		return -EINVAL;
-	}
-
-	DBG(5, "I2C attach client [%s] with driver [%s]",
-	    client->name, client->driver->driver.name)
-
-	return 0;
-}
-
-
-static int w9968cf_i2c_detach_inform(struct i2c_client* client)
-{
-	struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-
-	if (cam->sensor_client == client)
-		cam->sensor_client = NULL;
-
-	DBG(5, "I2C detach client [%s]", client->name)
-
-	return 0;
-}
-
-
 static int w9968cf_i2c_init(struct w9968cf_device* cam)
 {
 	int err = 0;
@@ -1554,15 +1499,13 @@ static int w9968cf_i2c_init(struct w9968
 	static struct i2c_adapter adap = {
 		.id =                I2C_HW_SMBUS_W9968CF,
 		.owner =             THIS_MODULE,
-		.client_register =   w9968cf_i2c_attach_inform,
-		.client_unregister = w9968cf_i2c_detach_inform,
 		.algo =              &algo,
 	};
 
 	memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
 	strcpy(cam->i2c_adapter.name, "w9968cf");
 	cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
-	i2c_set_adapdata(&cam->i2c_adapter, cam);
+	i2c_set_adapdata(&cam->i2c_adapter, &cam->v4l2_dev);
 
 	DBG(6, "Registering I2C adapter with kernel...")
 
@@ -2165,13 +2108,9 @@ w9968cf_sensor_get_control(struct w9968c
 static int
 w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
 {
-	struct i2c_client* c = cam->sensor_client;
-	int rc = 0;
-
-	if (!c || !c->driver || !c->driver->command)
-		return -EINVAL;
+	int rc;
 
-	rc = c->driver->command(c, cmd, arg);
+	rc = v4l2_subdev_call(cam->sensor_sd, core, ioctl, cmd, arg);
 	/* The I2C driver returns -EPERM on non-supported controls */
 	return (rc < 0 && rc != -EPERM) ? rc : 0;
 }
@@ -2346,7 +2285,7 @@ static int w9968cf_sensor_init(struct w9
 		goto error;
 
 	/* NOTE: Make sure width and height are a multiple of 16 */
-	switch (cam->sensor_client->addr) {
+	switch (v4l2_i2c_subdev_addr(cam->sensor_sd)) {
 		case OV6xx0_SID:
 			cam->maxwidth = 352;
 			cam->maxheight = 288;
@@ -2651,6 +2590,7 @@ static void w9968cf_release_resources(st
 	w9968cf_deallocate_memory(cam);
 	kfree(cam->control_buffer);
 	kfree(cam->data_buffer);
+	v4l2_device_unregister(&cam->v4l2_dev);
 
 	mutex_unlock(&w9968cf_devlist_mutex);
 }
@@ -3480,6 +3420,11 @@ w9968cf_usb_probe(struct usb_interface*
 	struct list_head* ptr;
 	u8 sc = 0; /* number of simultaneous cameras */
 	static unsigned short dev_nr; /* 0 - we are handling device number n */
+	static unsigned short addrs[] = {
+		OV7xx0_SID,
+		OV6xx0_SID,
+		I2C_CLIENT_END
+	};
 
 	if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[0].idVendor &&
 	    le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
@@ -3495,12 +3440,14 @@ w9968cf_usb_probe(struct usb_interface*
 	if (!cam)
 		return -ENOMEM;
 
+	err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
+	if (err)
+		goto fail0;
+
 	mutex_init(&cam->dev_mutex);
 	mutex_lock(&cam->dev_mutex);
 
 	cam->usbdev = udev;
-	/* NOTE: a local copy is used to avoid possible race conditions */
-	memcpy(&cam->dev, &udev->dev, sizeof(struct device));
 
 	DBG(2, "%s detected", symbolic(camlist, mod_id))
 
@@ -3549,7 +3496,7 @@ w9968cf_usb_probe(struct usb_interface*
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
 	video_set_drvdata(cam->v4ldev, cam);
-	cam->v4ldev->parent = &cam->dev;
+	cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
 
 	err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
 				    video_nr[dev_nr]);
@@ -3576,9 +3523,14 @@ w9968cf_usb_probe(struct usb_interface*
 	w9968cf_turn_on_led(cam);
 
 	w9968cf_i2c_init(cam);
+	cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->v4l2_dev,
+			&cam->i2c_adapter,
+			"ovcamchip", "ovcamchip", addrs);
 
 	usb_set_intfdata(intf, cam);
 	mutex_unlock(&cam->dev_mutex);
+
+	err = w9968cf_sensor_init(cam);
 	return 0;
 
 fail: /* Free unused memory */
@@ -3587,6 +3539,8 @@ fail: /* Free unused memory */
 	if (cam->v4ldev)
 		video_device_release(cam->v4ldev);
 	mutex_unlock(&cam->dev_mutex);
+	v4l2_device_unregister(&cam->v4l2_dev);
+fail0:
 	kfree(cam);
 	return err;
 }
@@ -3597,15 +3551,16 @@ static void w9968cf_usb_disconnect(struc
 	struct w9968cf_device* cam =
 	   (struct w9968cf_device*)usb_get_intfdata(intf);
 
-	down_write(&w9968cf_disconnect);
-
 	if (cam) {
+		down_write(&w9968cf_disconnect);
 		/* Prevent concurrent accesses to data */
 		mutex_lock(&cam->dev_mutex);
 
 		cam->disconnected = 1;
 
-		DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
+		DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id));
+
+		v4l2_device_disconnect(&cam->v4l2_dev);
 
 		wake_up_interruptible_all(&cam->open);
 
@@ -3621,12 +3576,12 @@ static void w9968cf_usb_disconnect(struc
 			w9968cf_release_resources(cam);
 
 		mutex_unlock(&cam->dev_mutex);
+		up_write(&w9968cf_disconnect);
 
-		if (!cam->users)
+		if (!cam->users) {
 			kfree(cam);
+		}
 	}
-
-	up_write(&w9968cf_disconnect);
 }
 
 
@@ -3650,9 +3605,6 @@ static int __init w9968cf_module_init(vo
 	KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
 	KDBG(3, W9968CF_MODULE_AUTHOR)
 
-	if (ovmod_load)
-		request_module("ovcamchip");
-
 	if ((err = usb_register(&w9968cf_usb_driver)))
 		return err;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/w9968cf.h linux-libre-2.6.30-gnu1/drivers/media/video/w9968cf.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/w9968cf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/w9968cf.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/rwsem.h>
 #include <linux/mutex.h>
 
+#include <media/v4l2-device.h>
 #include <media/ovcamchip.h>
 
 #include "w9968cf_vpp.h"
@@ -42,7 +43,6 @@
  * Default values                                                           *
  ****************************************************************************/
 
-#define W9968CF_OVMOD_LOAD      1  /* automatic 'ovcamchip' module loading */
 #define W9968CF_VPPMOD_LOAD     1  /* automatic 'w9968cf-vpp' module loading */
 
 /* Comment/uncomment the following line to enable/disable debugging messages */
@@ -134,7 +134,7 @@ static const struct w9968cf_format w9968
 
 #define W9968CF_MODULE_NAME     "V4L driver for W996[87]CF JPEG USB " \
 				"Dual Mode Camera Chip"
-#define W9968CF_MODULE_VERSION  "1:1.33-basic"
+#define W9968CF_MODULE_VERSION  "1:1.34-basic"
 #define W9968CF_MODULE_AUTHOR   "(C) 2002-2004 Luca Risolia"
 #define W9968CF_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define W9968CF_MODULE_LICENSE  "GPL"
@@ -195,10 +195,9 @@ enum w9968cf_vpp_flag {
 
 /* Main device driver structure */
 struct w9968cf_device {
-	struct device dev; /* device structure */
-
 	enum w9968cf_model_id id;   /* private device identifier */
 
+	struct v4l2_device v4l2_dev;
 	struct video_device* v4ldev; /* -> V4L structure */
 	struct list_head v4llist;    /* entry of the list of V4L cameras */
 
@@ -265,7 +264,7 @@ struct w9968cf_device {
 
 	/* I2C interface to kernel */
 	struct i2c_adapter i2c_adapter;
-	struct i2c_client* sensor_client;
+	struct v4l2_subdev *sensor_sd;
 
 	/* Locks */
 	struct mutex dev_mutex,    /* for probe, disconnect,open and close */
@@ -277,6 +276,11 @@ struct w9968cf_device {
 	char command[16]; /* name of the program holding the device */
 };
 
+static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct w9968cf_device, v4l2_dev);
+}
+
 
 /****************************************************************************
  * Macros for debugging                                                     *
@@ -291,14 +295,14 @@ struct w9968cf_device {
 	if ( ((specific_debug) && (debug == (level))) ||                      \
 	     ((!specific_debug) && (debug >= (level))) ) {                    \
 		if ((level) == 1)                                             \
-			dev_err(&cam->dev, fmt "\n", ## args);                \
+			v4l2_err(&cam->v4l2_dev, fmt "\n", ## args);          \
 		else if ((level) == 2 || (level) == 3)                        \
-			dev_info(&cam->dev, fmt "\n", ## args);               \
+			v4l2_info(&cam->v4l2_dev, fmt "\n", ## args);         \
 		else if ((level) == 4)                                        \
-			dev_warn(&cam->dev, fmt "\n", ## args);               \
+			v4l2_warn(&cam->v4l2_dev, fmt "\n", ## args);         \
 		else if ((level) >= 5)                                        \
-			dev_info(&cam->dev, "[%s:%d] " fmt "\n",              \
-				 __func__, __LINE__ , ## args);           \
+			v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n",        \
+				 __func__, __LINE__ , ## args);               \
 	}                                                                     \
 }
 /* For generic kernel (not device specific) messages */
@@ -321,7 +325,7 @@ struct w9968cf_device {
 
 #undef PDBG
 #define PDBG(fmt, args...)                                                    \
-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
+v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
 
 #undef PDBGG
 #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/wm8739.c linux-libre-2.6.30-gnu1/drivers/media/video/wm8739.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/wm8739.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/wm8739.c	2009-06-09 23:05:27.000000000 -0400
@@ -252,11 +252,6 @@ static int wm8739_log_status(struct v4l2
 	return 0;
 }
 
-static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops wm8739_core_ops = {
@@ -343,8 +338,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "wm8739",
-	.driverid = I2C_DRIVERID_WM8739,
-	.command = wm8739_command,
 	.probe = wm8739_probe,
 	.remove = wm8739_remove,
 	.id_table = wm8739_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/wm8775.c linux-libre-2.6.30-gnu1/drivers/media/video/wm8775.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/wm8775.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/wm8775.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,15 +34,12 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
 
 MODULE_DESCRIPTION("wm8775 driver");
 MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
 MODULE_LICENSE("GPL");
 
-static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
 
 
 /* ----------------------------------------------------------------------- */
@@ -82,7 +79,8 @@ static int wm8775_write(struct v4l2_subd
 	return -1;
 }
 
-static int wm8775_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+static int wm8775_s_routing(struct v4l2_subdev *sd,
+			    u32 input, u32 output, u32 config)
 {
 	struct wm8775_state *state = to_state(sd);
 
@@ -91,11 +89,11 @@ static int wm8775_s_routing(struct v4l2_
 	   16 combinations.
 	   If only one input is active (the normal case) then the
 	   input values 1, 2, 4 or 8 should be used. */
-	if (route->input > 15) {
-		v4l2_err(sd, "Invalid input %d.\n", route->input);
+	if (input > 15) {
+		v4l2_err(sd, "Invalid input %d.\n", input);
 		return -EINVAL;
 	}
-	state->input = route->input;
+	state->input = input;
 	if (state->muted)
 		return 0;
 	wm8775_write(sd, R21, 0x0c0);
@@ -161,11 +159,6 @@ static int wm8775_s_frequency(struct v4l
 	return 0;
 }
 
-static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
-	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops wm8775_core_ops = {
@@ -268,8 +261,6 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id);
 
 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 	.name = "wm8775",
-	.driverid = I2C_DRIVERID_WM8775,
-	.command = wm8775_command,
 	.probe = wm8775_probe,
 	.remove = wm8775_remove,
 	.id_table = wm8775_id,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zc0301/zc0301_sensor.h linux-libre-2.6.30-gnu1/drivers/media/video/zc0301/zc0301_sensor.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/zc0301/zc0301_sensor.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zc0301/zc0301_sensor.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,12 +58,20 @@ zc0301_attach_sensor(struct zc0301_devic
 	.idProduct = (prod),                                                  \
 	.bInterfaceClass = (intclass)
 
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 #define ZC0301_ID_TABLE                                                       \
 static const struct usb_device_id zc0301_id_table[] =  {                      \
 	{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */            \
 	{ ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */           \
 	{ }                                                                   \
 };
+#else
+#define ZC0301_ID_TABLE                                                       \
+static const struct usb_device_id zc0301_id_table[] =  {                      \
+	{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */            \
+	{ }                                                                   \
+};
+#endif
 
 /*****************************************************************************/
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/Kconfig linux-libre-2.6.30-gnu1/drivers/media/video/zoran/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 config VIDEO_ZORAN
 	tristate "Zoran ZR36057/36067 Video For Linux"
-	depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS
+	depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS
 	help
 	  Say Y for support for MJPEG capture cards based on the Zoran
 	  36057/36067 PCI controller chipset. This includes the Iomega
@@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060
 config VIDEO_ZORAN_BUZ
 	tristate "Iomega Buz support"
 	depends on VIDEO_ZORAN_ZR36060
-	select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
 	help
 	  Support for the Iomega Buz MJPEG capture/playback card.
@@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33
 config VIDEO_ZORAN_LML33R10
 	tristate "Linux Media Labs LML33R10 support"
 	depends on VIDEO_ZORAN_ZR36060
-	select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
 	help
 	  support for the Linux Media Labs LML33R10 MJPEG capture/playback
@@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10
 
 config VIDEO_ZORAN_AVS6EYES
 	tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
-	depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1
+	depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL
 	select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/videocodec.h linux-libre-2.6.30-gnu1/drivers/media/video/zoran/videocodec.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/videocodec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/videocodec.h	2009-06-09 23:05:27.000000000 -0400
@@ -97,7 +97,7 @@
 	       available) - it returns 0 if the mode is possible
    set_size -> this fn-ref. sets the norm and image size for
 	       compression/decompression (returns 0 on success)
-	       the norm param is defined in videodev.h (VIDEO_MODE_*)
+	       the norm param is defined in videodev2.h (V4L2_STD_*)
 
    additional setup may be available, too - but the codec should work with
    some default values even without this
@@ -144,9 +144,8 @@ M                       zr36055[1] 0001
 #ifndef __LINUX_VIDEOCODEC_H
 #define __LINUX_VIDEOCODEC_H
 
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 
-//should be in videodev.h ??? (VID_DO_....)
 #define CODEC_DO_COMPRESSION 0
 #define CODEC_DO_EXPANSION   1
 
@@ -237,10 +236,6 @@ struct vfe_settings {
 	__u32 width, height;	/* Area to capture */
 	__u16 decimation;	/* Decimation divider */
 	__u16 flags;		/* Flags for capture */
-/* flags are the same as in struct video_capture - see videodev.h:
-#define VIDEO_CAPTURE_ODD		0
-#define VIDEO_CAPTURE_EVEN		1
-*/
 	__u16 quality;		/* quality of the video */
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_card.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_card.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_card.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_card.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,8 +38,7 @@
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
 #include <linux/spinlock.h>
 #include <linux/sem.h>
 #include <linux/kmod.h>
@@ -47,11 +46,10 @@
 
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
 #include <linux/mutex.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
+#include <media/v4l2-common.h>
+#include <media/bt819.h>
 
 #include "videocodec.h"
 #include "zoran.h"
@@ -108,25 +106,8 @@ static int video_nr[BUZ_MAX] = { [0 ...
 module_param_array(video_nr, int, NULL, 0444);
 MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
 
-/*
-   Number and size of grab buffers for Video 4 Linux
-   The vast majority of applications should not need more than 2,
-   the very popular BTTV driver actually does ONLY have 2.
-   Time sensitive applications might need more, the maximum
-   is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
-
-   The size is set so that the maximum possible request
-   can be satisfied. Decrease  it, if bigphys_area alloc'd
-   memory is low. If you don't have the bigphys_area patch,
-   set it to 128 KB. Will you allow only to grab small
-   images with V4L, but that's better than nothing.
-
-   v4l_bufsize has to be given in KB !
-
-*/
-
-int v4l_nbufs = 2;
-int v4l_bufsize = 128;		/* Everybody should be able to work with this setting */
+int v4l_nbufs = 4;
+int v4l_bufsize = 864;		/* Everybody should be able to work with this setting */
 module_param(v4l_nbufs, int, 0644);
 MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
 module_param(v4l_bufsize, int, 0644);
@@ -273,7 +254,7 @@ zr36016_write (struct videocodec *codec,
 static void
 dc10_init (struct zoran *zr)
 {
-	dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr));
+	dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
 
 	/* Pixel clock selection */
 	GPIO(zr, 4, 0);
@@ -285,13 +266,13 @@ dc10_init (struct zoran *zr)
 static void
 dc10plus_init (struct zoran *zr)
 {
-	dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr));
+	dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
 }
 
 static void
 buz_init (struct zoran *zr)
 {
-	dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr));
+	dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
 
 	/* some stuff from Iomega */
 	pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
@@ -302,7 +283,7 @@ buz_init (struct zoran *zr)
 static void
 lml33_init (struct zoran *zr)
 {
-	dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr));
+	dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
 
 	GPIO(zr, 2, 1);		// Set Composite input/output
 }
@@ -332,50 +313,6 @@ avs6eyes_init (struct zoran *zr)
 }
 
 static char *
-i2cid_to_modulename (u16 i2c_id)
-{
-	char *name = NULL;
-
-	switch (i2c_id) {
-	case I2C_DRIVERID_SAA7110:
-		name = "saa7110";
-		break;
-	case I2C_DRIVERID_SAA7111A:
-		name = "saa7111";
-		break;
-	case I2C_DRIVERID_SAA7114:
-		name = "saa7114";
-		break;
-	case I2C_DRIVERID_SAA7185B:
-		name = "saa7185";
-		break;
-	case I2C_DRIVERID_ADV7170:
-		name = "adv7170";
-		break;
-	case I2C_DRIVERID_ADV7175:
-		name = "adv7175";
-		break;
-	case I2C_DRIVERID_BT819:
-		name = "bt819";
-		break;
-	case I2C_DRIVERID_BT856:
-		name = "bt856";
-		break;
-	case I2C_DRIVERID_BT866:
-		name = "bt866";
-		break;
-	case I2C_DRIVERID_VPX3220:
-		name = "vpx3220";
-		break;
-	case I2C_DRIVERID_KS0127:
-		name = "ks0127";
-		break;
-	}
-
-	return name;
-}
-
-static char *
 codecid_to_modulename (u16 codecid)
 {
 	char *name = NULL;
@@ -425,11 +362,24 @@ static struct tvnorm f60ccir601_lm33r10
 static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
 static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
 
+static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
+static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
+static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
+static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
+static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
+static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
+static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
+static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
+
 static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	{
 		.type = DC10_old,
 		.name = "DC10(old)",
-		.i2c_decoder = I2C_DRIVERID_VPX3220,
+		.i2c_decoder = "vpx3220a",
+		.mod_decoder = "vpx3220",
+		.addrs_decoder = vpx3220_addrs,
 		.video_codec = CODEC_TYPE_ZR36050,
 		.video_vfe = CODEC_TYPE_ZR36016,
 
@@ -439,7 +389,7 @@ static struct card_info zoran_cards[NUM_
 			{ 2, "S-Video" },
 			{ 0, "Internal/comp" }
 		},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 			&f50sqpixel_dc10,
 			&f60sqpixel_dc10,
@@ -457,8 +407,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = DC10_new,
 		.name = "DC10(new)",
-		.i2c_decoder = I2C_DRIVERID_SAA7110,
-		.i2c_encoder = I2C_DRIVERID_ADV7175,
+		.i2c_decoder = "saa7110",
+		.mod_decoder = "saa7110",
+		.addrs_decoder = saa7110_addrs,
+		.i2c_encoder = "adv7175",
+		.mod_encoder = "adv7175",
+		.addrs_encoder = adv717x_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 3,
@@ -467,7 +421,7 @@ static struct card_info zoran_cards[NUM_
 				{ 7, "S-Video" },
 				{ 5, "Internal/comp" }
 			},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 				&f50sqpixel,
 				&f60sqpixel,
@@ -484,8 +438,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = DC10plus,
 		.name = "DC10plus",
-		.i2c_decoder = I2C_DRIVERID_SAA7110,
-		.i2c_encoder = I2C_DRIVERID_ADV7175,
+		.i2c_decoder = "saa7110",
+		.mod_decoder = "saa7110",
+		.addrs_decoder = saa7110_addrs,
+		.i2c_encoder = "adv7175",
+		.mod_encoder = "adv7175",
+		.addrs_encoder = adv717x_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 3,
@@ -494,7 +452,7 @@ static struct card_info zoran_cards[NUM_
 			{ 7, "S-Video" },
 			{ 5, "Internal/comp" }
 		},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 			&f50sqpixel,
 			&f60sqpixel,
@@ -512,8 +470,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = DC30,
 		.name = "DC30",
-		.i2c_decoder = I2C_DRIVERID_VPX3220,
-		.i2c_encoder = I2C_DRIVERID_ADV7175,
+		.i2c_decoder = "vpx3220a",
+		.mod_decoder = "vpx3220",
+		.addrs_decoder = vpx3220_addrs,
+		.i2c_encoder = "adv7175",
+		.mod_encoder = "adv7175",
+		.addrs_encoder = adv717x_addrs,
 		.video_codec = CODEC_TYPE_ZR36050,
 		.video_vfe = CODEC_TYPE_ZR36016,
 
@@ -523,7 +485,7 @@ static struct card_info zoran_cards[NUM_
 			{ 2, "S-Video" },
 			{ 0, "Internal/comp" }
 		},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 			&f50sqpixel_dc10,
 			&f60sqpixel_dc10,
@@ -541,8 +503,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = DC30plus,
 		.name = "DC30plus",
-		.i2c_decoder = I2C_DRIVERID_VPX3220,
-		.i2c_encoder = I2C_DRIVERID_ADV7175,
+		.i2c_decoder = "vpx3220a",
+		.mod_decoder = "vpx3220",
+		.addrs_decoder = vpx3220_addrs,
+		.i2c_encoder = "adv7175",
+		.mod_encoder = "adv7175",
+		.addrs_encoder = adv717x_addrs,
 		.video_codec = CODEC_TYPE_ZR36050,
 		.video_vfe = CODEC_TYPE_ZR36016,
 
@@ -552,7 +518,7 @@ static struct card_info zoran_cards[NUM_
 			{ 2, "S-Video" },
 			{ 0, "Internal/comp" }
 		},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 			&f50sqpixel_dc10,
 			&f60sqpixel_dc10,
@@ -570,8 +536,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = LML33,
 		.name = "LML33",
-		.i2c_decoder = I2C_DRIVERID_BT819,
-		.i2c_encoder = I2C_DRIVERID_BT856,
+		.i2c_decoder = "bt819a",
+		.mod_decoder = "bt819",
+		.addrs_decoder = bt819_addrs,
+		.i2c_encoder = "bt856",
+		.mod_encoder = "bt856",
+		.addrs_encoder = bt856_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 2,
@@ -579,7 +549,7 @@ static struct card_info zoran_cards[NUM_
 			{ 0, "Composite" },
 			{ 7, "S-Video" }
 		},
-		.norms = 2,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
 		.tvn = {
 			&f50ccir601_lml33,
 			&f60ccir601_lml33,
@@ -597,8 +567,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = LML33R10,
 		.name = "LML33R10",
-		.i2c_decoder = I2C_DRIVERID_SAA7114,
-		.i2c_encoder = I2C_DRIVERID_ADV7170,
+		.i2c_decoder = "saa7114",
+		.mod_decoder = "saa7115",
+		.addrs_decoder = saa7114_addrs,
+		.i2c_encoder = "adv7170",
+		.mod_encoder = "adv7170",
+		.addrs_encoder = adv717x_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 2,
@@ -606,7 +580,7 @@ static struct card_info zoran_cards[NUM_
 			{ 0, "Composite" },
 			{ 7, "S-Video" }
 		},
-		.norms = 2,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
 		.tvn = {
 			&f50ccir601_lm33r10,
 			&f60ccir601_lm33r10,
@@ -624,8 +598,12 @@ static struct card_info zoran_cards[NUM_
 	}, {
 		.type = BUZ,
 		.name = "Buz",
-		.i2c_decoder = I2C_DRIVERID_SAA7111A,
-		.i2c_encoder = I2C_DRIVERID_SAA7185B,
+		.i2c_decoder = "saa7111",
+		.mod_decoder = "saa7115",
+		.addrs_decoder = saa7111_addrs,
+		.i2c_encoder = "saa7185",
+		.mod_encoder = "saa7185",
+		.addrs_encoder = saa7185_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 2,
@@ -633,7 +611,7 @@ static struct card_info zoran_cards[NUM_
 			{ 3, "Composite" },
 			{ 7, "S-Video" }
 		},
-		.norms = 3,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
 		.tvn = {
 			&f50ccir601,
 			&f60ccir601,
@@ -653,8 +631,12 @@ static struct card_info zoran_cards[NUM_
 		.name = "6-Eyes",
 		/* AverMedia chose not to brand the 6-Eyes. Thus it
 		   can't be autodetected, and requires card=x. */
-		.i2c_decoder = I2C_DRIVERID_KS0127,
-		.i2c_encoder = I2C_DRIVERID_BT866,
+		.i2c_decoder = "ks0127",
+		.mod_decoder = "ks0127",
+		.addrs_decoder = ks0127_addrs,
+		.i2c_encoder = "bt866",
+		.mod_encoder = "bt866",
+		.addrs_encoder = bt866_addrs,
 		.video_codec = CODEC_TYPE_ZR36060,
 
 		.inputs = 10,
@@ -670,7 +652,7 @@ static struct card_info zoran_cards[NUM_
 			{10, "S-Video 3" },
 			{15, "YCbCr" }
 		},
-		.norms = 2,
+		.norms = V4L2_STD_NTSC|V4L2_STD_PAL,
 		.tvn = {
 			&f50ccir601_avs6eyes,
 			&f60ccir601_avs6eyes,
@@ -735,69 +717,6 @@ zoran_i2c_setscl (void *data,
 	btwrite(zr->i2cbr, ZR36057_I2CBR);
 }
 
-static int
-zoran_i2c_client_register (struct i2c_client *client)
-{
-	struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
-	int res = 0;
-
-	dprintk(2,
-		KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
-		ZR_DEVNAME(zr), client->driver->id);
-
-	mutex_lock(&zr->resource_lock);
-
-	if (zr->user > 0) {
-		/* we're already busy, so we keep a reference to
-		 * them... Could do a lot of stuff here, but this
-		 * is easiest. (Did I ever mention I'm a lazy ass?)
-		 */
-		res = -EBUSY;
-		goto clientreg_unlock_and_return;
-	}
-
-	if (client->driver->id == zr->card.i2c_decoder)
-		zr->decoder = client;
-	else if (client->driver->id == zr->card.i2c_encoder)
-		zr->encoder = client;
-	else {
-		res = -ENODEV;
-		goto clientreg_unlock_and_return;
-	}
-
-clientreg_unlock_and_return:
-	mutex_unlock(&zr->resource_lock);
-
-	return res;
-}
-
-static int
-zoran_i2c_client_unregister (struct i2c_client *client)
-{
-	struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
-	int res = 0;
-
-	dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
-
-	mutex_lock(&zr->resource_lock);
-
-	if (zr->user > 0) {
-		res = -EBUSY;
-		goto clientunreg_unlock_and_return;
-	}
-
-	/* try to locate it */
-	if (client == zr->encoder) {
-		zr->encoder = NULL;
-	} else if (client == zr->decoder) {
-		zr->decoder = NULL;
-		snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id);
-	}
-clientunreg_unlock_and_return:
-	mutex_unlock(&zr->resource_lock);
-	return res;
-}
-
 static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
 	.setsda = zoran_i2c_setsda,
 	.setscl = zoran_i2c_setscl,
@@ -813,13 +732,10 @@ zoran_register_i2c (struct zoran *zr)
 	memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
 	       sizeof(struct i2c_algo_bit_data));
 	zr->i2c_algo.data = zr;
-	zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
 	zr->i2c_adapter.id = I2C_HW_B_ZR36067;
-	zr->i2c_adapter.client_register = zoran_i2c_client_register;
-	zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
 	strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
 		sizeof(zr->i2c_adapter.name));
-	i2c_set_adapdata(&zr->i2c_adapter, zr);
+	i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
 	zr->i2c_adapter.algo_data = &zr->i2c_algo;
 	zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
 	return i2c_bit_add_bus(&zr->i2c_adapter);
@@ -835,19 +751,20 @@ zoran_unregister_i2c (struct zoran *zr)
 
 int
 zoran_check_jpg_settings (struct zoran              *zr,
-			  struct zoran_jpg_settings *settings)
+			  struct zoran_jpg_settings *settings,
+			  int try)
 {
 	int err = 0, err0 = 0;
 
 	dprintk(4,
 		KERN_DEBUG
-		"%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
-		ZR_DEVNAME(zr), settings->decimation, settings->HorDcm,
+		"%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
+		ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
 		settings->VerDcm, settings->TmpDcm);
 	dprintk(4,
 		KERN_DEBUG
-		"%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n",
-		ZR_DEVNAME(zr), settings->img_x, settings->img_y,
+		"%s: %s - x: %d, y: %d, w: %d, y: %d\n",
+		ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
 		settings->img_width, settings->img_height);
 	/* Check decimation, set default values for decimation = 1, 2, 4 */
 	switch (settings->decimation) {
@@ -879,8 +796,8 @@ zoran_check_jpg_settings (struct zoran
 		if (zr->card.type == DC10_new) {
 			dprintk(1,
 				KERN_DEBUG
-				"%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - HDec by 4 is not supported on the DC10\n",
+				ZR_DEVNAME(zr), __func__);
 			err0++;
 			break;
 		}
@@ -900,50 +817,73 @@ zoran_check_jpg_settings (struct zoran
 		/* We have to check the data the user has set */
 
 		if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
-		    (zr->card.type == DC10_new || settings->HorDcm != 4))
+		    (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+			settings->HorDcm = clamp(settings->HorDcm, 1, 2);
 			err0++;
-		if (settings->VerDcm != 1 && settings->VerDcm != 2)
+		}
+		if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+			settings->VerDcm = clamp(settings->VerDcm, 1, 2);
 			err0++;
-		if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+		}
+		if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+			settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
 			err0++;
+		}
 		if (settings->field_per_buff != 1 &&
-		    settings->field_per_buff != 2)
+		    settings->field_per_buff != 2) {
+			settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
 			err0++;
-		if (settings->img_x < 0)
+		}
+		if (settings->img_x < 0) {
+			settings->img_x = 0;
 			err0++;
-		if (settings->img_y < 0)
+		}
+		if (settings->img_y < 0) {
+			settings->img_y = 0;
 			err0++;
-		if (settings->img_width < 0)
+		}
+		if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+			settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
 			err0++;
-		if (settings->img_height < 0)
+		}
+		if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+			settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
 			err0++;
-		if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+		}
+		if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+			settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
 			err0++;
-		if (settings->img_y + settings->img_height >
-		    BUZ_MAX_HEIGHT / 2)
+		}
+		if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+			settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
+			err0++;
+		}
+		if (settings->img_width % (16 * settings->HorDcm) != 0) {
+			settings->img_width -= settings->img_width % (16 * settings->HorDcm);
+			if (settings->img_width == 0)
+				settings->img_width = 16 * settings->HorDcm;
+			err0++;
+		}
+		if (settings->img_height % (8 * settings->VerDcm) != 0) {
+			settings->img_height -= settings->img_height % (8 * settings->VerDcm);
+			if (settings->img_height == 0)
+				settings->img_height = 8 * settings->VerDcm;
 			err0++;
-		if (settings->HorDcm && settings->VerDcm) {
-			if (settings->img_width %
-			    (16 * settings->HorDcm) != 0)
-				err0++;
-			if (settings->img_height %
-			    (8 * settings->VerDcm) != 0)
-				err0++;
 		}
 
-		if (err0) {
+		if (!try && err0) {
 			dprintk(1,
 				KERN_ERR
-				"%s: check_jpg_settings() - error in params for decimation = 0\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - error in params for decimation = 0\n",
+				ZR_DEVNAME(zr), __func__);
 			err++;
 		}
 		break;
 	default:
 		dprintk(1,
 			KERN_ERR
-			"%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n",
-			ZR_DEVNAME(zr), settings->decimation);
+			"%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
+			ZR_DEVNAME(zr), __func__, settings->decimation);
 		err++;
 		break;
 	}
@@ -1021,12 +961,10 @@ zoran_open_init_params (struct zoran *zr
 	       sizeof(zr->jpg_settings.jpg_comp.COM_data));
 	zr->jpg_settings.jpg_comp.jpeg_markers =
 	    JPEG_MARKER_DHT | JPEG_MARKER_DQT;
-	i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+	i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
 	if (i)
-		dprintk(1,
-			KERN_ERR
-			"%s: zoran_open_init_params() internal error\n",
-			ZR_DEVNAME(zr));
+		dprintk(1, KERN_ERR "%s: %s internal error\n",
+			ZR_DEVNAME(zr), __func__);
 
 	clear_interrupt_counters(zr);
 	zr->testing = 0;
@@ -1062,13 +1000,11 @@ static int __devinit
 zr36057_init (struct zoran *zr)
 {
 	int j, err;
-	int two = 2;
-	int zero = 0;
 
 	dprintk(1,
 		KERN_INFO
-		"%s: zr36057_init() - initializing card[%d], zr=%p\n",
-		ZR_DEVNAME(zr), zr->id, zr);
+		"%s: %s - initializing card[%d], zr=%p\n",
+		ZR_DEVNAME(zr), __func__, zr->id, zr);
 
 	/* default setup of all parameters which will persist between opens */
 	zr->user = 0;
@@ -1079,24 +1015,32 @@ zr36057_init (struct zoran *zr)
 	zr->jpg_buffers.allocated = 0;
 	zr->v4l_buffers.allocated = 0;
 
-	zr->buffer.base = (void *) vidmem;
-	zr->buffer.width = 0;
-	zr->buffer.height = 0;
-	zr->buffer.depth = 0;
-	zr->buffer.bytesperline = 0;
+	zr->vbuf_base = (void *) vidmem;
+	zr->vbuf_width = 0;
+	zr->vbuf_height = 0;
+	zr->vbuf_depth = 0;
+	zr->vbuf_bytesperline = 0;
 
 	/* Avoid nonsense settings from user for default input/norm */
-	if (default_norm < VIDEO_MODE_PAL &&
-	    default_norm > VIDEO_MODE_SECAM)
-		default_norm = VIDEO_MODE_PAL;
-	zr->norm = default_norm;
-	if (!(zr->timing = zr->card.tvn[zr->norm])) {
+	if (default_norm < 0 && default_norm > 2)
+		default_norm = 0;
+	if (default_norm == 0) {
+		zr->norm = V4L2_STD_PAL;
+		zr->timing = zr->card.tvn[0];
+	} else if (default_norm == 1) {
+		zr->norm = V4L2_STD_NTSC;
+		zr->timing = zr->card.tvn[1];
+	} else {
+		zr->norm = V4L2_STD_SECAM;
+		zr->timing = zr->card.tvn[2];
+	}
+	if (zr->timing == NULL) {
 		dprintk(1,
 			KERN_WARNING
-			"%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
-			ZR_DEVNAME(zr));
-		zr->norm = VIDEO_MODE_PAL;
-		zr->timing = zr->card.tvn[zr->norm];
+			"%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
+			ZR_DEVNAME(zr), __func__);
+		zr->norm = V4L2_STD_PAL;
+		zr->timing = zr->card.tvn[0];
 	}
 
 	if (default_input > zr->card.inputs-1) {
@@ -1108,12 +1052,6 @@ zr36057_init (struct zoran *zr)
 	}
 	zr->input = default_input;
 
-	/* Should the following be reset at every open ? */
-	zr->hue = 32768;
-	zr->contrast = 32768;
-	zr->saturation = 32768;
-	zr->brightness = 32768;
-
 	/* default setup (will be repeated at every open) */
 	zoran_open_init_params(zr);
 
@@ -1124,8 +1062,8 @@ zr36057_init (struct zoran *zr)
 	if (!zr->stat_com || !zr->video_dev) {
 		dprintk(1,
 			KERN_ERR
-			"%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - kmalloc (STAT_COM) failed\n",
+			ZR_DEVNAME(zr), __func__);
 		err = -ENOMEM;
 		goto exit_free;
 	}
@@ -1137,6 +1075,7 @@ zr36057_init (struct zoran *zr)
 	 *   Now add the template and register the device unit.
 	 */
 	memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
+	zr->video_dev->parent = &zr->pci_dev->dev;
 	strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
 	err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
 	if (err < 0)
@@ -1148,8 +1087,8 @@ zr36057_init (struct zoran *zr)
 		detect_guest_activity(zr);
 	test_interrupts(zr);
 	if (!pass_through) {
-		decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
-		encoder_command(zr, ENCODER_SET_INPUT, &two);
+		decoder_call(zr, video, s_stream, 0);
+		encoder_call(zr, video, s_routing, 2, 0, 0);
 	}
 
 	zr->zoran_proc = NULL;
@@ -1164,7 +1103,8 @@ exit_free:
 
 static void __devexit zoran_remove(struct pci_dev *pdev)
 {
-	struct zoran *zr = pci_get_drvdata(pdev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+	struct zoran *zr = to_zoran(v4l2_dev);
 
 	if (!zr->initialized)
 		goto exit_free;
@@ -1197,7 +1137,7 @@ static void __devexit zoran_remove(struc
 	pci_disable_device(zr->pci_dev);
 	video_unregister_device(zr->video_dev);
 exit_free:
-	pci_set_drvdata(pdev, NULL);
+	v4l2_device_unregister(&zr->v4l2_dev);
 	kfree(zr);
 }
 
@@ -1215,10 +1155,8 @@ zoran_setup_videocodec (struct zoran *zr
 
 	m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
 	if (!m) {
-		dprintk(1,
-			KERN_ERR
-			"%s: zoran_setup_videocodec() - no memory\n",
-			ZR_DEVNAME(zr));
+		dprintk(1, KERN_ERR "%s: %s - no memory\n",
+			ZR_DEVNAME(zr), __func__);
 		return m;
 	}
 
@@ -1256,6 +1194,18 @@ zoran_setup_videocodec (struct zoran *zr
 	return m;
 }
 
+static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct zoran *zr = to_zoran(sd->v4l2_dev);
+
+	/* Bt819 needs to reset its FIFO buffer using #FRST pin and
+	   LML33 card uses GPIO(7) for that. */
+	if (cmd == BT819_FIFO_RESET_LOW)
+		GPIO(zr, 7, 0);
+	else if (cmd == BT819_FIFO_RESET_HIGH)
+		GPIO(zr, 7, 1);
+}
+
 /*
  *   Scan for a Buz card (actually for the PCI controller ZR36057),
  *   request the irq and map the io memory
@@ -1269,34 +1219,33 @@ static int __devinit zoran_probe(struct
 	struct videocodec_master *master_vfe = NULL;
 	struct videocodec_master *master_codec = NULL;
 	int card_num;
-	char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+	char *codec_name, *vfe_name;
 	unsigned int nr;
 
 
 	nr = zoran_num++;
 	if (nr >= BUZ_MAX) {
-		dprintk(1,
-			KERN_ERR
-			"%s: driver limited to %d card(s) maximum\n",
+		dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
 			ZORAN_NAME, BUZ_MAX);
 		return -ENOENT;
 	}
 
 	zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
 	if (!zr) {
-		dprintk(1,
-			KERN_ERR
-			"%s: find_zr36057() - kzalloc failed\n",
-			ZORAN_NAME);
+		dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
+			ZORAN_NAME, __func__);
 		return -ENOMEM;
 	}
+	zr->v4l2_dev.notify = zoran_subdev_notify;
+	if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
+		goto zr_free_mem;
 	zr->pci_dev = pdev;
 	zr->id = nr;
 	snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
 	spin_lock_init(&zr->spinlock);
 	mutex_init(&zr->resource_lock);
 	if (pci_enable_device(pdev))
-		goto zr_free_mem;
+		goto zr_unreg;
 	pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
 
 	dprintk(1,
@@ -1323,7 +1272,7 @@ static int __devinit zoran_probe(struct
 				KERN_ERR
 				"%s: It is not possible to auto-detect ZR36057 based cards\n",
 				ZR_DEVNAME(zr));
-			goto zr_free_mem;
+			goto zr_unreg;
 		}
 
 		card_num = ent->driver_data;
@@ -1332,7 +1281,7 @@ static int __devinit zoran_probe(struct
 				KERN_ERR
 				"%s: Unknown card, try specifying card=X module parameter\n",
 				ZR_DEVNAME(zr));
-			goto zr_free_mem;
+			goto zr_unreg;
 		}
 		dprintk(3,
 			KERN_DEBUG
@@ -1345,7 +1294,7 @@ static int __devinit zoran_probe(struct
 				KERN_ERR
 				"%s: User specified card type %d out of range (0 .. %d)\n",
 				ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
-			goto zr_free_mem;
+			goto zr_unreg;
 		}
 	}
 
@@ -1360,11 +1309,9 @@ static int __devinit zoran_probe(struct
 
 	zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
 	if (!zr->zr36057_mem) {
-		dprintk(1,
-			KERN_ERR
-			"%s: %s() - ioremap failed\n",
+		dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
 			ZR_DEVNAME(zr), __func__);
-		goto zr_free_mem;
+		goto zr_unreg;
 	}
 
 	result = request_irq(zr->pci_dev->irq, zoran_irq,
@@ -1373,18 +1320,18 @@ static int __devinit zoran_probe(struct
 		if (result == -EINVAL) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - bad irq number or handler\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - bad irq number or handler\n",
+				ZR_DEVNAME(zr), __func__);
 		} else if (result == -EBUSY) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
-				ZR_DEVNAME(zr), zr->pci_dev->irq);
+				"%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
+				ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
 		} else {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - can't assign irq, error code %d\n",
-				ZR_DEVNAME(zr), result);
+				"%s: %s - can't assign irq, error code %d\n",
+				ZR_DEVNAME(zr), __func__, result);
 		}
 		goto zr_unmap;
 	}
@@ -1394,9 +1341,7 @@ static int __devinit zoran_probe(struct
 			     &latency);
 	need_latency = zr->revision > 1 ? 32 : 48;
 	if (latency != need_latency) {
-		dprintk(2,
-			KERN_INFO
-			"%s: Changing PCI latency from %d to %d\n",
+		dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
 			ZR_DEVNAME(zr), latency, need_latency);
 		pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
 				      need_latency);
@@ -1407,54 +1352,22 @@ static int __devinit zoran_probe(struct
 	dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
 		ZR_DEVNAME(zr));
 
-	/* i2c decoder */
-	if (decoder[zr->id] != -1) {
-		i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
-		zr->card.i2c_decoder = decoder[zr->id];
-	} else if (zr->card.i2c_decoder != 0) {
-		i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
-	} else {
-		i2c_dec_name = NULL;
-	}
-
-	if (i2c_dec_name) {
-		result = request_module(i2c_dec_name);
-		if (result < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s: failed to load module %s: %d\n",
-				ZR_DEVNAME(zr), i2c_dec_name, result);
-		}
-	}
-
-	/* i2c encoder */
-	if (encoder[zr->id] != -1) {
-		i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
-		zr->card.i2c_encoder = encoder[zr->id];
-	} else if (zr->card.i2c_encoder != 0) {
-		i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
-	} else {
-		i2c_enc_name = NULL;
-	}
-
-	if (i2c_enc_name) {
-		result = request_module(i2c_enc_name);
-		if (result < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s: failed to load module %s: %d\n",
-				ZR_DEVNAME(zr), i2c_enc_name, result);
-		}
-	}
-
 	if (zoran_register_i2c(zr) < 0) {
-		dprintk(1,
-			KERN_ERR
-			"%s: find_zr36057() - can't initialize i2c bus\n",
-			ZR_DEVNAME(zr));
+		dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
+			ZR_DEVNAME(zr), __func__);
 		goto zr_free_irq;
 	}
 
+	zr->decoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+		&zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
+		zr->card.addrs_decoder);
+
+	if (zr->card.mod_encoder)
+		zr->encoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+			&zr->i2c_adapter,
+			zr->card.mod_encoder, zr->card.i2c_encoder,
+			zr->card.addrs_encoder);
+
 	dprintk(2,
 		KERN_INFO "%s: Initializing videocodec bus...\n",
 		ZR_DEVNAME(zr));
@@ -1495,17 +1408,13 @@ static int __devinit zoran_probe(struct
 			goto zr_unreg_i2c;
 		zr->codec = videocodec_attach(master_codec);
 		if (!zr->codec) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() - no codec found\n",
-				ZR_DEVNAME(zr));
+			dprintk(1, KERN_ERR "%s: %s - no codec found\n",
+				ZR_DEVNAME(zr), __func__);
 			goto zr_free_codec;
 		}
 		if (zr->codec->type != zr->card.video_codec) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() - wrong codec\n",
-				ZR_DEVNAME(zr));
+			dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
+				ZR_DEVNAME(zr), __func__);
 			goto zr_detach_codec;
 		}
 	}
@@ -1515,17 +1424,13 @@ static int __devinit zoran_probe(struct
 			goto zr_detach_codec;
 		zr->vfe = videocodec_attach(master_vfe);
 		if (!zr->vfe) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() - no VFE found\n",
-				ZR_DEVNAME(zr));
+			dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
+				ZR_DEVNAME(zr), __func__);
 			goto zr_free_vfe;
 		}
 		if (zr->vfe->type != zr->card.video_vfe) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() = wrong VFE\n",
-				ZR_DEVNAME(zr));
+			dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
+				ZR_DEVNAME(zr), __func__);
 			goto zr_detach_vfe;
 		}
 	}
@@ -1533,8 +1438,7 @@ static int __devinit zoran_probe(struct
 	/* take care of Natoma chipset and a revision 1 zr36057 */
 	if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
 		zr->jpg_buffers.need_contiguous = 1;
-		dprintk(1,
-			KERN_INFO
+		dprintk(1, KERN_INFO
 			"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
 			ZR_DEVNAME(zr));
 	}
@@ -1544,8 +1448,6 @@ static int __devinit zoran_probe(struct
 
 	zoran_proc_init(zr);
 
-	pci_set_drvdata(pdev, zr);
-
 	return 0;
 
 zr_detach_vfe:
@@ -1563,6 +1465,8 @@ zr_free_irq:
 	free_irq(zr->pci_dev->irq, zr);
 zr_unmap:
 	iounmap(zr->zr36057_mem);
+zr_unreg:
+	v4l2_device_unregister(&zr->v4l2_dev);
 zr_free_mem:
 	kfree(zr);
 
@@ -1613,9 +1517,6 @@ static int __init zoran_init(void)
 			ZORAN_NAME, vidmem);
 	}
 
-	/* random nonsense */
-	dprintk(6, KERN_DEBUG "Jotti is een held!\n");
-
 	/* some mainboards might not do PCI-PCI data transfer well */
 	if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
 		dprintk(1,
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_card.h linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_card.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_card.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_card.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,8 @@ extern int zr36067_debug;
 extern struct video_device zoran_template;
 
 extern int zoran_check_jpg_settings(struct zoran *zr,
-				    struct zoran_jpg_settings *settings);
+				    struct zoran_jpg_settings *settings,
+				    int try);
 extern void zoran_open_init_params(struct zoran *zr);
 extern void zoran_vdev_release(struct video_device *vdev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_device.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_device.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_device.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,13 +36,12 @@
 #include <linux/proc_fs.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <linux/spinlock.h>
 #include <linux/sem.h>
 
 #include <linux/pci.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
 #include <linux/delay.h>
 #include <linux/wait.h>
 
@@ -312,9 +311,9 @@ zr36057_adjust_vfe (struct zoran
 	case BUZ_MODE_MOTION_COMPRESS:
 	case BUZ_MODE_IDLE:
 	default:
-		if (zr->norm == VIDEO_MODE_NTSC ||
+		if ((zr->norm & V4L2_STD_NTSC) ||
 		    (zr->card.type == LML33R10 &&
-		     zr->norm == VIDEO_MODE_PAL))
+		     (zr->norm & V4L2_STD_PAL)))
 			btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
 		else
 			btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
@@ -355,14 +354,6 @@ zr36057_set_vfe (struct zoran
 	dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
 		ZR_DEVNAME(zr), video_width, video_height);
 
-	if (zr->norm != VIDEO_MODE_PAL &&
-	    zr->norm != VIDEO_MODE_NTSC &&
-	    zr->norm != VIDEO_MODE_SECAM) {
-		dprintk(1,
-			KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
-			ZR_DEVNAME(zr), zr->norm);
-		return;
-	}
 	if (video_width < BUZ_MIN_WIDTH ||
 	    video_height < BUZ_MIN_HEIGHT ||
 	    video_width > Wa || video_height > Ha) {
@@ -426,7 +417,7 @@ zr36057_set_vfe (struct zoran
 	 * we get the correct colors when uncompressing to the screen  */
 	//reg |= ZR36057_VFESPFR_VCLKPol; /**/
 	/* RJ: Don't know if that is needed for NTSC also */
-	if (zr->norm != VIDEO_MODE_NTSC)
+	if (!(zr->norm & V4L2_STD_NTSC))
 		reg |= ZR36057_VFESPFR_ExtFl;	// NEEDED!!!!!!! Wolfgang
 	reg |= ZR36057_VFESPFR_TopField;
 	if (HorDcm >= 48) {
@@ -497,11 +488,11 @@ zr36057_overlay (struct zoran *zr,
 		 * All error messages are internal driver checking only! */
 
 		/* video display top and bottom registers */
-		reg = (long) zr->buffer.base +
+		reg = (long) zr->vbuf_base +
 		    zr->overlay_settings.x *
 		    ((zr->overlay_settings.format->depth + 7) / 8) +
 		    zr->overlay_settings.y *
-		    zr->buffer.bytesperline;
+		    zr->vbuf_bytesperline;
 		btwrite(reg, ZR36057_VDTR);
 		if (reg & 3)
 			dprintk(1,
@@ -509,15 +500,15 @@ zr36057_overlay (struct zoran *zr,
 				"%s: zr36057_overlay() - video_address not aligned\n",
 				ZR_DEVNAME(zr));
 		if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
-			reg += zr->buffer.bytesperline;
+			reg += zr->vbuf_bytesperline;
 		btwrite(reg, ZR36057_VDBR);
 
 		/* video stride, status, and frame grab register */
-		reg = zr->buffer.bytesperline -
+		reg = zr->vbuf_bytesperline -
 		    zr->overlay_settings.width *
 		    ((zr->overlay_settings.format->depth + 7) / 8);
 		if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
-			reg += zr->buffer.bytesperline;
+			reg += zr->vbuf_bytesperline;
 		if (reg & 3)
 			dprintk(1,
 				KERN_ERR
@@ -544,12 +535,8 @@ zr36057_overlay (struct zoran *zr,
  *  and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
  */
 
-void
-write_overlay_mask (struct file       *file,
-		    struct video_clip *vp,
-		    int                count)
+void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
 	u32 *mask;
@@ -563,10 +550,10 @@ write_overlay_mask (struct file       *f
 
 	for (i = 0; i < count; ++i) {
 		/* pick up local copy of clip */
-		x = vp[i].x;
-		y = vp[i].y;
-		width = vp[i].width;
-		height = vp[i].height;
+		x = vp[i].c.left;
+		y = vp[i].c.top;
+		width = vp[i].c.width;
+		height = vp[i].c.height;
 
 		/* trim clips that extend beyond the window */
 		if (x < 0) {
@@ -981,8 +968,6 @@ void
 zr36057_enable_jpg (struct zoran          *zr,
 		    enum zoran_codec_mode  mode)
 {
-	static int zero;
-	static int one = 1;
 	struct vfe_settings cap;
 	int field_size =
 	    zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
@@ -1007,8 +992,8 @@ zr36057_enable_jpg (struct zoran
 		 * the video bus direction set to input.
 		 */
 		set_videobus_dir(zr, 0);
-		decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
-		encoder_command(zr, ENCODER_SET_INPUT, &zero);
+		decoder_call(zr, video, s_stream, 1);
+		encoder_call(zr, video, s_routing, 0, 0, 0);
 
 		/* Take the JPEG codec and the VFE out of sleep */
 		jpeg_codec_sleep(zr, 0);
@@ -1054,9 +1039,9 @@ zr36057_enable_jpg (struct zoran
 		/* In motion decompression mode, the decoder output must be disabled, and
 		 * the video bus direction set to output.
 		 */
-		decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
+		decoder_call(zr, video, s_stream, 0);
 		set_videobus_dir(zr, 1);
-		encoder_command(zr, ENCODER_SET_INPUT, &one);
+		encoder_call(zr, video, s_routing, 1, 0, 0);
 
 		/* Take the JPEG codec and the VFE out of sleep */
 		jpeg_codec_sleep(zr, 0);
@@ -1100,8 +1085,8 @@ zr36057_enable_jpg (struct zoran
 		jpeg_codec_sleep(zr, 1);
 		zr36057_adjust_vfe(zr, mode);
 
-		decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
-		encoder_command(zr, ENCODER_SET_INPUT, &zero);
+		decoder_call(zr, video, s_stream, 1);
+		encoder_call(zr, video, s_routing, 0, 0, 0);
 
 		dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
 		break;
@@ -1132,7 +1117,7 @@ zoran_feed_stat_com (struct zoran *zr)
 			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
 		} else {
 			/* fill 2 stat_com entries */
 			i = ((zr->jpg_dma_head -
@@ -1140,9 +1125,9 @@ zoran_feed_stat_com (struct zoran *zr)
 			if (!(zr->stat_com[i] & cpu_to_le32(1)))
 				break;
 			zr->stat_com[i] =
-			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
 			zr->stat_com[i + 1] =
-			    cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+			    cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
 		}
 		zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
 		zr->jpg_dma_head++;
@@ -1162,7 +1147,7 @@ zoran_reap_stat_com (struct zoran *zr)
 	u32 stat_com;
 	unsigned int seq;
 	unsigned int dif;
-	struct zoran_jpg_buffer *buffer;
+	struct zoran_buffer *buffer;
 	int frame;
 
 	/* In motion decompress we don't have a hardware frame counter,
@@ -1208,22 +1193,52 @@ zoran_reap_stat_com (struct zoran *zr)
 	}
 }
 
+static void zoran_restart(struct zoran *zr)
+{
+	/* Now the stat_comm buffer is ready for restart */
+	int status = 0, mode;
+
+	if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
+		decoder_call(zr, video, g_input_status, &status);
+		mode = CODEC_DO_COMPRESSION;
+	} else {
+		status = V4L2_IN_ST_NO_SIGNAL;
+		mode = CODEC_DO_EXPANSION;
+	}
+	if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+	    !(status & V4L2_IN_ST_NO_SIGNAL)) {
+		/********** RESTART code *************/
+		jpeg_codec_reset(zr);
+		zr->codec->set_mode(zr->codec, mode);
+		zr36057_set_jpg(zr, zr->codec_mode);
+		jpeg_start(zr);
+
+		if (zr->num_errors <= 8)
+			dprintk(2, KERN_INFO "%s: Restart\n",
+				ZR_DEVNAME(zr));
+
+		zr->JPEG_missed = 0;
+		zr->JPEG_error = 2;
+		/********** End RESTART code ***********/
+	}
+}
+
 static void
 error_handler (struct zoran *zr,
 	       u32           astat,
 	       u32           stat)
 {
+	int i, j;
+
 	/* This is JPEG error handling part */
-	if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) &&
-	    (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) {
-		//dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode);
+	if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
+	    zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) {
 		return;
 	}
 
 	if ((stat & 1) == 0 &&
 	    zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
-	    zr->jpg_dma_tail - zr->jpg_que_tail >=
-	     zr->jpg_buffers.num_buffers) {
+	    zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) {
 		/* No free buffers... */
 		zoran_reap_stat_com(zr);
 		zoran_feed_stat_com(zr);
@@ -1232,142 +1247,95 @@ error_handler (struct zoran *zr,
 		return;
 	}
 
-	if (zr->JPEG_error != 1) {
-		/*
-		 * First entry: error just happened during normal operation
-		 *
-		 * In BUZ_MODE_MOTION_COMPRESS:
-		 *
-		 * Possible glitch in TV signal. In this case we should
-		 * stop the codec and wait for good quality signal before
-		 * restarting it to avoid further problems
-		 *
-		 * In BUZ_MODE_MOTION_DECOMPRESS:
-		 *
-		 * Bad JPEG frame: we have to mark it as processed (codec crashed
-		 * and was not able to do it itself), and to remove it from queue.
-		 */
-		btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
-		udelay(1);
-		stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
-		btwrite(0, ZR36057_JPC);
-		btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
-		jpeg_codec_reset(zr);
-		jpeg_codec_sleep(zr, 1);
-		zr->JPEG_error = 1;
-		zr->num_errors++;
-
-		/* Report error */
-		if (zr36067_debug > 1 && zr->num_errors <= 8) {
-			long frame;
-			frame =
-			    zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
-			printk(KERN_ERR
-			       "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
-			       ZR_DEVNAME(zr), stat, zr->last_isr,
-			       zr->jpg_que_tail, zr->jpg_dma_tail,
-			       zr->jpg_dma_head, zr->jpg_que_head,
-			       zr->jpg_seq_num, frame);
-			printk("stat_com frames:");
-			{
-				int i, j;
-				for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
-					for (i = 0;
-					     i < zr->jpg_buffers.num_buffers;
-					     i++) {
-						if (le32_to_cpu(zr->stat_com[j]) ==
-						    zr->jpg_buffers.
-						    buffer[i].
-						    frag_tab_bus) {
-							printk("% d->%d",
-							       j, i);
-						}
-					}
-				}
-				printk("\n");
-			}
-		}
-		/* Find an entry in stat_com and rotate contents */
-		{
-			int i;
+	if (zr->JPEG_error == 1) {
+		zoran_restart(zr);
+		return;
+	}
 
-			if (zr->jpg_settings.TmpDcm == 1)
-				i = (zr->jpg_dma_tail -
-				     zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
-			else
-				i = ((zr->jpg_dma_tail -
-				      zr->jpg_err_shift) & 1) * 2;
-			if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
-				/* Mimic zr36067 operation */
-				zr->stat_com[i] |= cpu_to_le32(1);
-				if (zr->jpg_settings.TmpDcm != 1)
-					zr->stat_com[i + 1] |= cpu_to_le32(1);
-				/* Refill */
-				zoran_reap_stat_com(zr);
-				zoran_feed_stat_com(zr);
-				wake_up_interruptible(&zr->jpg_capq);
-				/* Find an entry in stat_com again after refill */
-				if (zr->jpg_settings.TmpDcm == 1)
-					i = (zr->jpg_dma_tail -
-					     zr->jpg_err_shift) &
-					    BUZ_MASK_STAT_COM;
-				else
-					i = ((zr->jpg_dma_tail -
-					      zr->jpg_err_shift) & 1) * 2;
-			}
-			if (i) {
-				/* Rotate stat_comm entries to make current entry first */
-				int j;
-				__le32 bus_addr[BUZ_NUM_STAT_COM];
+	/*
+	 * First entry: error just happened during normal operation
+	 *
+	 * In BUZ_MODE_MOTION_COMPRESS:
+	 *
+	 * Possible glitch in TV signal. In this case we should
+	 * stop the codec and wait for good quality signal before
+	 * restarting it to avoid further problems
+	 *
+	 * In BUZ_MODE_MOTION_DECOMPRESS:
+	 *
+	 * Bad JPEG frame: we have to mark it as processed (codec crashed
+	 * and was not able to do it itself), and to remove it from queue.
+	 */
+	btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
+	udelay(1);
+	stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
+	btwrite(0, ZR36057_JPC);
+	btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+	jpeg_codec_reset(zr);
+	jpeg_codec_sleep(zr, 1);
+	zr->JPEG_error = 1;
+	zr->num_errors++;
 
-				/* Here we are copying the stat_com array, which
-				 * is already in little endian format, so
-				 * no endian conversions here
-				 */
-				memcpy(bus_addr, zr->stat_com,
-				       sizeof(bus_addr));
-				for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
-					zr->stat_com[j] =
-					    bus_addr[(i + j) &
-						     BUZ_MASK_STAT_COM];
+	/* Report error */
+	if (zr36067_debug > 1 && zr->num_errors <= 8) {
+		long frame;
 
-				}
-				zr->jpg_err_shift += i;
-				zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+		frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
+		printk(KERN_ERR
+		       "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
+		       ZR_DEVNAME(zr), stat, zr->last_isr,
+		       zr->jpg_que_tail, zr->jpg_dma_tail,
+		       zr->jpg_dma_head, zr->jpg_que_head,
+		       zr->jpg_seq_num, frame);
+		printk(KERN_INFO "stat_com frames:");
+		for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+			for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
+				if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
+					printk(KERN_CONT "% d->%d", j, i);
 			}
-			if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
-				zr->jpg_err_seq = zr->jpg_seq_num;	/* + 1; */
 		}
+		printk(KERN_CONT "\n");
 	}
+	/* Find an entry in stat_com and rotate contents */
+	if (zr->jpg_settings.TmpDcm == 1)
+		i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+	else
+		i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+	if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
+		/* Mimic zr36067 operation */
+		zr->stat_com[i] |= cpu_to_le32(1);
+		if (zr->jpg_settings.TmpDcm != 1)
+			zr->stat_com[i + 1] |= cpu_to_le32(1);
+		/* Refill */
+		zoran_reap_stat_com(zr);
+		zoran_feed_stat_com(zr);
+		wake_up_interruptible(&zr->jpg_capq);
+		/* Find an entry in stat_com again after refill */
+		if (zr->jpg_settings.TmpDcm == 1)
+			i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+		else
+			i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+	}
+	if (i) {
+		/* Rotate stat_comm entries to make current entry first */
+		int j;
+		__le32 bus_addr[BUZ_NUM_STAT_COM];
 
-	/* Now the stat_comm buffer is ready for restart */
-	do {
-		int status, mode;
-
-		if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
-			decoder_command(zr, DECODER_GET_STATUS, &status);
-			mode = CODEC_DO_COMPRESSION;
-		} else {
-			status = 0;
-			mode = CODEC_DO_EXPANSION;
-		}
-		if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
-		    (status & DECODER_STATUS_GOOD)) {
-			/********** RESTART code *************/
-			jpeg_codec_reset(zr);
-			zr->codec->set_mode(zr->codec, mode);
-			zr36057_set_jpg(zr, zr->codec_mode);
-			jpeg_start(zr);
+		/* Here we are copying the stat_com array, which
+		 * is already in little endian format, so
+		 * no endian conversions here
+		 */
+		memcpy(bus_addr, zr->stat_com, sizeof(bus_addr));
 
-			if (zr->num_errors <= 8)
-				dprintk(2, KERN_INFO "%s: Restart\n",
-					ZR_DEVNAME(zr));
+		for (j = 0; j < BUZ_NUM_STAT_COM; j++)
+			zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM];
 
-			zr->JPEG_missed = 0;
-			zr->JPEG_error = 2;
-			/********** End RESTART code ***********/
-		}
-	} while (0);
+		zr->jpg_err_shift += i;
+		zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+	}
+	if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
+		zr->jpg_err_seq = zr->jpg_seq_num;	/* + 1; */
+	zoran_restart(zr);
 }
 
 irqreturn_t
@@ -1425,10 +1393,8 @@ zoran_irq (int             irq,
 			 * We simply ignore them */
 
 			if (zr->v4l_memgrab_active) {
-
 				/* A lot more checks should be here ... */
-				if ((btread(ZR36057_VSSFGR) &
-				     ZR36057_VSSFGR_SnapShot) == 0)
+				if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
 					dprintk(1,
 						KERN_WARNING
 						"%s: BuzIRQ with SnapShot off ???\n",
@@ -1436,10 +1402,7 @@ zoran_irq (int             irq,
 
 				if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
 					/* There is a grab on a frame going on, check if it has finished */
-
-					if ((btread(ZR36057_VSSFGR) &
-					     ZR36057_VSSFGR_FrameGrab) ==
-					    0) {
+					if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
 						/* it is finished, notify the user */
 
 						zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
@@ -1457,9 +1420,7 @@ zoran_irq (int             irq,
 
 				if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
 				    zr->v4l_pend_tail != zr->v4l_pend_head) {
-
-					int frame = zr->v4l_pend[zr->v4l_pend_tail &
-							 V4L_MASK_FRAME];
+					int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
 					u32 reg;
 
 					zr->v4l_grab_frame = frame;
@@ -1468,27 +1429,17 @@ zoran_irq (int             irq,
 
 					/* Buffer address */
 
-					reg =
-					    zr->v4l_buffers.buffer[frame].
-					    fbuffer_bus;
+					reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
 					btwrite(reg, ZR36057_VDTR);
-					if (zr->v4l_settings.height >
-					    BUZ_MAX_HEIGHT / 2)
-						reg +=
-						    zr->v4l_settings.
-						    bytesperline;
+					if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+						reg += zr->v4l_settings.bytesperline;
 					btwrite(reg, ZR36057_VDBR);
 
 					/* video stride, status, and frame grab register */
 					reg = 0;
-					if (zr->v4l_settings.height >
-					    BUZ_MAX_HEIGHT / 2)
-						reg +=
-						    zr->v4l_settings.
-						    bytesperline;
-					reg =
-					    (reg <<
-					     ZR36057_VSSFGR_DispStride);
+					if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+						reg += zr->v4l_settings.bytesperline;
+					reg = (reg << ZR36057_VSSFGR_DispStride);
 					reg |= ZR36057_VSSFGR_VidOvf;
 					reg |= ZR36057_VSSFGR_SnapShot;
 					reg |= ZR36057_VSSFGR_FrameGrab;
@@ -1506,77 +1457,66 @@ zoran_irq (int             irq,
 #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
 		if (astat & ZR36057_ISR_CodRepIRQ) {
 			zr->intr_counter_CodRepIRQ++;
-			IDEBUG(printk
-			       (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
+			IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
 				ZR_DEVNAME(zr)));
 			btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
 		}
 #endif				/* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
 
 #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
-		if (astat & ZR36057_ISR_JPEGRepIRQ) {
+		if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
+		    (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+		     zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
+			if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) {
+				char sc[] = "0000";
+				char sv[5];
+				int i;
 
-			if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
-			    zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
-				if (zr36067_debug > 1 &&
-				    (!zr->frame_num || zr->JPEG_error)) {
-					printk(KERN_INFO
-					       "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
-					       ZR_DEVNAME(zr), stat,
-					       zr->jpg_settings.odd_even,
-					       zr->jpg_settings.
-					       field_per_buff,
-					       zr->JPEG_missed);
-					{
-						char sc[] = "0000";
-						char sv[5];
-						int i;
-						strcpy(sv, sc);
-						for (i = 0; i < 4; i++) {
-							if (le32_to_cpu(zr->stat_com[i]) & 1)
-								sv[i] = '1';
-						}
-						sv[4] = 0;
-						printk(KERN_INFO
-						       "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
-						       ZR_DEVNAME(zr), sv,
-						       zr->jpg_que_tail,
-						       zr->jpg_dma_tail,
-						       zr->jpg_dma_head,
-						       zr->jpg_que_head);
-					}
-				} else {
-					if (zr->JPEG_missed > zr->JPEG_max_missed)	// Get statistics
-						zr->JPEG_max_missed =
-						    zr->JPEG_missed;
-					if (zr->JPEG_missed <
-					    zr->JPEG_min_missed)
-						zr->JPEG_min_missed =
-						    zr->JPEG_missed;
+				printk(KERN_INFO
+				       "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
+				       ZR_DEVNAME(zr), stat,
+				       zr->jpg_settings.odd_even,
+				       zr->jpg_settings.field_per_buff,
+				       zr->JPEG_missed);
+
+				strcpy(sv, sc);
+				for (i = 0; i < 4; i++) {
+					if (le32_to_cpu(zr->stat_com[i]) & 1)
+						sv[i] = '1';
 				}
+				sv[4] = 0;
+				printk(KERN_INFO
+				       "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
+				       ZR_DEVNAME(zr), sv,
+				       zr->jpg_que_tail,
+				       zr->jpg_dma_tail,
+				       zr->jpg_dma_head,
+				       zr->jpg_que_head);
+			} else {
+				/* Get statistics */
+				if (zr->JPEG_missed > zr->JPEG_max_missed)
+					zr->JPEG_max_missed = zr->JPEG_missed;
+				if (zr->JPEG_missed < zr->JPEG_min_missed)
+					zr->JPEG_min_missed = zr->JPEG_missed;
+			}
 
-				if (zr36067_debug > 2 && zr->frame_num < 6) {
-					int i;
-					printk("%s: seq=%ld stat_com:",
-					       ZR_DEVNAME(zr), zr->jpg_seq_num);
-					for (i = 0; i < 4; i++) {
-						printk(" %08x",
-						       le32_to_cpu(zr->stat_com[i]));
-					}
-					printk("\n");
+			if (zr36067_debug > 2 && zr->frame_num < 6) {
+				int i;
+
+				printk(KERN_INFO "%s: seq=%ld stat_com:",
+				       ZR_DEVNAME(zr), zr->jpg_seq_num);
+				for (i = 0; i < 4; i++) {
+					printk(KERN_CONT " %08x",
+					       le32_to_cpu(zr->stat_com[i]));
 				}
-				zr->frame_num++;
-				zr->JPEG_missed = 0;
-				zr->JPEG_error = 0;
-				zoran_reap_stat_com(zr);
-				zoran_feed_stat_com(zr);
-				wake_up_interruptible(&zr->jpg_capq);
-			} /*else {
-			      dprintk(1,
-					KERN_ERR
-					"%s: JPEG interrupt while not in motion (de)compress mode!\n",
-					ZR_DEVNAME(zr));
-			}*/
+				printk(KERN_CONT "\n");
+			}
+			zr->frame_num++;
+			zr->JPEG_missed = 0;
+			zr->JPEG_error = 0;
+			zoran_reap_stat_com(zr);
+			zoran_feed_stat_com(zr);
+			wake_up_interruptible(&zr->jpg_capq);
 		}
 #endif				/* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
 
@@ -1585,8 +1525,7 @@ zoran_irq (int             irq,
 		    zr->JPEG_missed > 25 ||
 		    zr->JPEG_error == 1	||
 		    ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
-		     (zr->frame_num & (zr->JPEG_missed >
-				       zr->jpg_settings.field_per_buff)))) {
+		     (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
 			error_handler(zr, astat, stat);
 		}
 
@@ -1628,8 +1567,6 @@ zoran_set_pci_master (struct zoran *zr,
 void
 zoran_init_hardware (struct zoran *zr)
 {
-	int j, zero = 0;
-
 	/* Enable bus-mastering */
 	zoran_set_pci_master(zr, 1);
 
@@ -1638,15 +1575,14 @@ zoran_init_hardware (struct zoran *zr)
 		zr->card.init(zr);
 	}
 
-	j = zr->card.input[zr->input].muxsel;
-
-	decoder_command(zr, 0, NULL);
-	decoder_command(zr, DECODER_SET_NORM, &zr->norm);
-	decoder_command(zr, DECODER_SET_INPUT, &j);
+	decoder_call(zr, core, init, 0);
+	decoder_call(zr, core, s_std, zr->norm);
+	decoder_call(zr, video, s_routing,
+		zr->card.input[zr->input].muxsel, 0, 0);
 
-	encoder_command(zr, 0, NULL);
-	encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
-	encoder_command(zr, ENCODER_SET_INPUT, &zero);
+	encoder_call(zr, core, init, 0);
+	encoder_call(zr, video, s_std_output, zr->norm);
+	encoder_call(zr, video, s_routing, 0, 0, 0);
 
 	/* toggle JPEG codec sleep to sync PLL */
 	jpeg_codec_sleep(zr, 1);
@@ -1706,42 +1642,3 @@ zr36057_init_vfe (struct zoran *zr)
 		reg |= ZR36057_VDCR_Triton;
 	btwrite(reg, ZR36057_VDCR);
 }
-
-/*
- * Interface to decoder and encoder chips using i2c bus
- */
-
-int
-decoder_command (struct zoran *zr,
-		 int           cmd,
-		 void         *data)
-{
-	if (zr->decoder == NULL)
-		return -EIO;
-
-	if (zr->card.type == LML33 &&
-	    (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) {
-		int res;
-
-		// Bt819 needs to reset its FIFO buffer using #FRST pin and
-		// LML33 card uses GPIO(7) for that.
-		GPIO(zr, 7, 0);
-		res = zr->decoder->driver->command(zr->decoder, cmd, data);
-		// Pull #FRST high.
-		GPIO(zr, 7, 1);
-		return res;
-	} else
-		return zr->decoder->driver->command(zr->decoder, cmd,
-						    data);
-}
-
-int
-encoder_command (struct zoran *zr,
-		 int           cmd,
-		 void         *data)
-{
-	if (zr->encoder == NULL)
-		return -1;
-
-	return zr->encoder->driver->command(zr->encoder, cmd, data);
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_device.h linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_device.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_device.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_device.h	2009-06-09 23:05:27.000000000 -0400
@@ -54,8 +54,8 @@ extern int jpeg_codec_reset(struct zoran
 /* zr360x7 access to raw capture */
 extern void zr36057_overlay(struct zoran *zr,
 			    int on);
-extern void write_overlay_mask(struct file *file,
-			       struct video_clip *vp,
+extern void write_overlay_mask(struct zoran_fh *fh,
+			       struct v4l2_clip *vp,
 			       int count);
 extern void zr36057_set_memgrab(struct zoran *zr,
 				int mode);
@@ -87,11 +87,9 @@ extern int jpg_bufsize;
 extern int pass_through;
 
 /* i2c */
-extern int decoder_command(struct zoran *zr,
-			   int cmd,
-			   void *data);
-extern int encoder_command(struct zoran *zr,
-			   int cmd,
-			   void *data);
+#define decoder_call(zr, o, f, args...) \
+	v4l2_subdev_call(zr->decoder, o, f, ##args)
+#define encoder_call(zr, o, f, args...) \
+	v4l2_subdev_call(zr->encoder, o, f, ##args)
 
 #endif				/* __ZORAN_DEVICE_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_driver.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_driver.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,16 +58,6 @@
 #include <linux/i2c-algo-bit.h>
 
 #include <linux/spinlock.h>
-#define     MAP_NR(x)       virt_to_page(x)
-#define     ZORAN_VID_TYPE  ( \
-				VID_TYPE_CAPTURE | \
-				VID_TYPE_OVERLAY | \
-				VID_TYPE_CLIPPING | \
-				VID_TYPE_FRAMERAM | \
-				VID_TYPE_SCALES | \
-				VID_TYPE_MJPEG_DECODER | \
-				VID_TYPE_MJPEG_ENCODER \
-			     )
 
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
@@ -79,36 +69,17 @@
 #include <asm/uaccess.h>
 #include <linux/proc_fs.h>
 
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
 #include <linux/mutex.h>
 #include "zoran.h"
 #include "zoran_device.h"
 #include "zoran_card.h"
 
-	/* we declare some card type definitions here, they mean
-	 * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
-#define ZORAN_V4L2_VID_FLAGS ( \
-				V4L2_CAP_STREAMING |\
-				V4L2_CAP_VIDEO_CAPTURE |\
-				V4L2_CAP_VIDEO_OUTPUT |\
-				V4L2_CAP_VIDEO_OVERLAY \
-			      )
-
-
-#if defined(CONFIG_VIDEO_V4L1_COMPAT)
-#define ZFMT(pal, fcc, cs) \
-	.palette = (pal), .fourcc = (fcc), .colorspace = (cs)
-#else
-#define ZFMT(pal, fcc, cs) \
-	.fourcc = (fcc), .colorspace = (cs)
-#endif
 
 const struct zoran_format zoran_formats[] = {
 	{
 		.name = "15-bit RGB LE",
-		ZFMT(VIDEO_PALETTE_RGB555,
-		     V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_RGB555,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 15,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
@@ -116,16 +87,16 @@ const struct zoran_format zoran_formats[
 			   ZR36057_VFESPFR_LittleEndian,
 	}, {
 		.name = "15-bit RGB BE",
-		ZFMT(-1,
-		     V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_RGB555X,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 15,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
 	}, {
 		.name = "16-bit RGB LE",
-		ZFMT(VIDEO_PALETTE_RGB565,
-		     V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
@@ -133,56 +104,56 @@ const struct zoran_format zoran_formats[
 			   ZR36057_VFESPFR_LittleEndian,
 	}, {
 		.name = "16-bit RGB BE",
-		ZFMT(-1,
-		     V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_RGB565X,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
 	}, {
 		.name = "24-bit RGB",
-		ZFMT(VIDEO_PALETTE_RGB24,
-		     V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_BGR24,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 24,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
 	}, {
 		.name = "32-bit RGB LE",
-		ZFMT(VIDEO_PALETTE_RGB32,
-		     V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_BGR32,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 32,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
 	}, {
 		.name = "32-bit RGB BE",
-		ZFMT(-1,
-		     V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
+		.fourcc = V4L2_PIX_FMT_RGB32,
+		.colorspace = V4L2_COLORSPACE_SRGB,
 		.depth = 32,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_RGB888,
 	}, {
 		.name = "4:2:2, packed, YUYV",
-		ZFMT(VIDEO_PALETTE_YUV422,
-		     V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
+		.fourcc = V4L2_PIX_FMT_YUYV,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_YUV422,
 	}, {
 		.name = "4:2:2, packed, UYVY",
-		ZFMT(VIDEO_PALETTE_UYVY,
-		     V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
+		.fourcc = V4L2_PIX_FMT_UYVY,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
 		.depth = 16,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_OVERLAY,
 		.vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
 	}, {
 		.name = "Hardware-encoded Motion-JPEG",
-		ZFMT(-1,
-		     V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
+		.fourcc = V4L2_PIX_FMT_MJPEG,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
 		.depth = 0,
 		.flags = ZORAN_FORMAT_CAPTURE |
 			 ZORAN_FORMAT_PLAYBACK |
@@ -191,13 +162,6 @@ const struct zoran_format zoran_formats[
 };
 #define NUM_FORMATS ARRAY_SIZE(zoran_formats)
 
-// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
-
-
-static int lock_norm;	/* 0 = default 1 = Don't change TV standard (norm) */
-module_param(lock_norm, int, 0644);
-MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
-
 	/* small helper function for calculating buffersizes for v4l2
 	 * we calculate the nearest higher power-of-two, which
 	 * will be the recommended buffersize */
@@ -222,221 +186,106 @@ zoran_v4l2_calc_bufsize (struct zoran_jp
 }
 
 /* forward references */
-static void v4l_fbuffer_free(struct file *file);
-static void jpg_fbuffer_free(struct file *file);
+static void v4l_fbuffer_free(struct zoran_fh *fh);
+static void jpg_fbuffer_free(struct zoran_fh *fh);
+
+/* Set mapping mode */
+static void map_mode_raw(struct zoran_fh *fh)
+{
+	fh->map_mode = ZORAN_MAP_MODE_RAW;
+	fh->buffers.buffer_size = v4l_bufsize;
+	fh->buffers.num_buffers = v4l_nbufs;
+}
+static void map_mode_jpg(struct zoran_fh *fh, int play)
+{
+	fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC;
+	fh->buffers.buffer_size = jpg_bufsize;
+	fh->buffers.num_buffers = jpg_nbufs;
+}
+static inline const char *mode_name(enum zoran_map_mode mode)
+{
+	return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG";
+}
 
 /*
  *   Allocate the V4L grab buffers
  *
  *   These have to be pysically contiguous.
- *   If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
- *   else we try to allocate them with bigphysarea_alloc_pages
- *   if the bigphysarea patch is present in the kernel,
- *   else we try to use high memory (if the user has bootet
- *   Linux with the necessary memory left over).
  */
 
-static unsigned long
-get_high_mem (unsigned long size)
-{
-/*
- * Check if there is usable memory at the end of Linux memory
- * of at least size. Return the physical address of this memory,
- * return 0 on failure.
- *
- * The idea is from Alexandro Rubini's book "Linux device drivers".
- * The driver from him which is downloadable from O'Reilly's
- * web site misses the "virt_to_phys(high_memory)" part
- * (and therefore doesn't work at all - at least with 2.2.x kernels).
- *
- * It should be unnecessary to mention that THIS IS DANGEROUS,
- * if more than one driver at a time has the idea to use this memory!!!!
- */
-
-	volatile unsigned char __iomem *mem;
-	unsigned char c;
-	unsigned long hi_mem_ph;
-	unsigned long i;
-
-	/* Map the high memory to user space */
-
-	hi_mem_ph = virt_to_phys(high_memory);
-
-	mem = ioremap(hi_mem_ph, size);
-	if (!mem) {
-		dprintk(1,
-			KERN_ERR "%s: get_high_mem() - ioremap failed\n",
-			ZORAN_NAME);
-		return 0;
-	}
-
-	for (i = 0; i < size; i++) {
-		/* Check if it is memory */
-		c = i & 0xff;
-		writeb(c, mem + i);
-		if (readb(mem + i) != c)
-			break;
-		c = 255 - c;
-		writeb(c, mem + i);
-		if (readb(mem + i) != c)
-			break;
-		writeb(0, mem + i);	/* zero out memory */
-
-		/* give the kernel air to breath */
-		if ((i & 0x3ffff) == 0x3ffff)
-			schedule();
-	}
-
-	iounmap(mem);
-
-	if (i != size) {
-		dprintk(1,
-			KERN_ERR
-			"%s: get_high_mem() - requested %lu, avail %lu\n",
-			ZORAN_NAME, size, i);
-		return 0;
-	}
-
-	return hi_mem_ph;
-}
-
-static int
-v4l_fbuffer_alloc (struct file *file)
+static int v4l_fbuffer_alloc(struct zoran_fh *fh)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int i, off;
 	unsigned char *mem;
-	unsigned long pmem = 0;
 
-	/* we might have old buffers lying around... */
-	if (fh->v4l_buffers.ready_to_be_freed) {
-		v4l_fbuffer_free(file);
-	}
-
-	for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
-		if (fh->v4l_buffers.buffer[i].fbuffer)
+	for (i = 0; i < fh->buffers.num_buffers; i++) {
+		if (fh->buffers.buffer[i].v4l.fbuffer)
 			dprintk(2,
 				KERN_WARNING
-				"%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
-				ZR_DEVNAME(zr), i);
+				"%s: %s - buffer %d already allocated!?\n",
+				ZR_DEVNAME(zr), __func__, i);
 
 		//udelay(20);
-		if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
-			/* Use kmalloc */
-
-			mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
-			if (!mem) {
-				dprintk(1,
-					KERN_ERR
-					"%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
-					ZR_DEVNAME(zr), i);
-				v4l_fbuffer_free(file);
-				return -ENOBUFS;
-			}
-			fh->v4l_buffers.buffer[i].fbuffer = mem;
-			fh->v4l_buffers.buffer[i].fbuffer_phys =
-			    virt_to_phys(mem);
-			fh->v4l_buffers.buffer[i].fbuffer_bus =
-			    virt_to_bus(mem);
-			for (off = 0; off < fh->v4l_buffers.buffer_size;
-			     off += PAGE_SIZE)
-				SetPageReserved(MAP_NR(mem + off));
-			dprintk(4,
-				KERN_INFO
-				"%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
-				ZR_DEVNAME(zr), i, (unsigned long) mem,
-				virt_to_bus(mem));
-		} else {
-
-			/* Use high memory which has been left at boot time */
-
-			/* Ok., Ok. this is an evil hack - we make
-			 * the assumption that physical addresses are
-			 * the same as bus addresses (true at least
-			 * for Intel processors). The whole method of
-			 * obtaining and using this memory is not very
-			 * nice - but I hope it saves some poor users
-			 * from kernel hacking, which might have even
-			 * more evil results */
-
-			if (i == 0) {
-				int size =
-				    fh->v4l_buffers.num_buffers *
-				    fh->v4l_buffers.buffer_size;
-
-				pmem = get_high_mem(size);
-				if (pmem == 0) {
-					dprintk(1,
-						KERN_ERR
-						"%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
-						ZR_DEVNAME(zr), size >> 10);
-					return -ENOBUFS;
-				}
-				fh->v4l_buffers.buffer[0].fbuffer = NULL;
-				fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
-				fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
-				dprintk(4,
-					KERN_INFO
-					"%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
-					ZR_DEVNAME(zr), size >> 10);
-			} else {
-				fh->v4l_buffers.buffer[i].fbuffer = NULL;
-				fh->v4l_buffers.buffer[i].fbuffer_phys =
-				    pmem + i * fh->v4l_buffers.buffer_size;
-				fh->v4l_buffers.buffer[i].fbuffer_bus =
-				    pmem + i * fh->v4l_buffers.buffer_size;
-			}
+		mem = kmalloc(fh->buffers.buffer_size,
+			      GFP_KERNEL | __GFP_NOWARN);
+		if (!mem) {
+			dprintk(1,
+				KERN_ERR
+				"%s: %s - kmalloc for V4L buf %d failed\n",
+				ZR_DEVNAME(zr), __func__, i);
+			v4l_fbuffer_free(fh);
+			return -ENOBUFS;
 		}
+		fh->buffers.buffer[i].v4l.fbuffer = mem;
+		fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
+		fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
+		for (off = 0; off < fh->buffers.buffer_size;
+		     off += PAGE_SIZE)
+			SetPageReserved(virt_to_page(mem + off));
+		dprintk(4,
+			KERN_INFO
+			"%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
+			ZR_DEVNAME(zr), __func__, i, (unsigned long) mem,
+			(unsigned long long)virt_to_bus(mem));
 	}
 
-	fh->v4l_buffers.allocated = 1;
+	fh->buffers.allocated = 1;
 
 	return 0;
 }
 
 /* free the V4L grab buffers */
-static void
-v4l_fbuffer_free (struct file *file)
+static void v4l_fbuffer_free(struct zoran_fh *fh)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int i, off;
 	unsigned char *mem;
 
-	dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
+	dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__);
 
-	for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
-		if (!fh->v4l_buffers.buffer[i].fbuffer)
+	for (i = 0; i < fh->buffers.num_buffers; i++) {
+		if (!fh->buffers.buffer[i].v4l.fbuffer)
 			continue;
 
-		if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
-			mem = fh->v4l_buffers.buffer[i].fbuffer;
-			for (off = 0; off < fh->v4l_buffers.buffer_size;
-			     off += PAGE_SIZE)
-				ClearPageReserved(MAP_NR(mem + off));
-			kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
-		}
-		fh->v4l_buffers.buffer[i].fbuffer = NULL;
+		mem = fh->buffers.buffer[i].v4l.fbuffer;
+		for (off = 0; off < fh->buffers.buffer_size;
+		     off += PAGE_SIZE)
+			ClearPageReserved(virt_to_page(mem + off));
+		kfree(fh->buffers.buffer[i].v4l.fbuffer);
+		fh->buffers.buffer[i].v4l.fbuffer = NULL;
 	}
 
-	fh->v4l_buffers.allocated = 0;
-	fh->v4l_buffers.ready_to_be_freed = 0;
+	fh->buffers.allocated = 0;
 }
 
 /*
  *   Allocate the MJPEG grab buffers.
  *
- *   If the requested buffer size is smaller than MAX_KMALLOC_MEM,
- *   kmalloc is used to request a physically contiguous area,
- *   else we allocate the memory in framgents with get_zeroed_page.
- *
  *   If a Natoma chipset is present and this is a revision 1 zr36057,
  *   each MJPEG buffer needs to be physically contiguous.
  *   (RJ: This statement is from Dave Perks' original driver,
  *   I could never check it because I have a zr36067)
- *   The driver cares about this because it reduces the buffer
- *   size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
  *
  *   RJ: The contents grab buffers needs never be accessed in the driver.
  *       Therefore there is no need to allocate them with vmalloc in order
@@ -458,162 +307,128 @@ v4l_fbuffer_free (struct file *file)
  *       and fragment buffers are not little-endian.
  */
 
-static int
-jpg_fbuffer_alloc (struct file *file)
+static int jpg_fbuffer_alloc(struct zoran_fh *fh)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int i, j, off;
-	unsigned long mem;
-
-	/* we might have old buffers lying around */
-	if (fh->jpg_buffers.ready_to_be_freed) {
-		jpg_fbuffer_free(file);
-	}
+	u8 *mem;
 
-	for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
-		if (fh->jpg_buffers.buffer[i].frag_tab)
+	for (i = 0; i < fh->buffers.num_buffers; i++) {
+		if (fh->buffers.buffer[i].jpg.frag_tab)
 			dprintk(2,
 				KERN_WARNING
-				"%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
-				ZR_DEVNAME(zr), i);
+				"%s: %s - buffer %d already allocated!?\n",
+				ZR_DEVNAME(zr), __func__, i);
 
 		/* Allocate fragment table for this buffer */
 
-		mem = get_zeroed_page(GFP_KERNEL);
+		mem = (void *)get_zeroed_page(GFP_KERNEL);
 		if (mem == 0) {
 			dprintk(1,
 				KERN_ERR
-				"%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
-				ZR_DEVNAME(zr), i);
-			jpg_fbuffer_free(file);
+				"%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
+				ZR_DEVNAME(zr), __func__, i);
+			jpg_fbuffer_free(fh);
 			return -ENOBUFS;
 		}
-		fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem;
-		fh->jpg_buffers.buffer[i].frag_tab_bus =
-		    virt_to_bus((void *) mem);
+		fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
+		fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
 
-		//if (alloc_contig) {
-		if (fh->jpg_buffers.need_contiguous) {
-			mem =
-			    (unsigned long) kmalloc(fh->jpg_buffers.
-						    buffer_size,
-						    GFP_KERNEL);
-			if (mem == 0) {
+		if (fh->buffers.need_contiguous) {
+			mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
+			if (mem == NULL) {
 				dprintk(1,
 					KERN_ERR
-					"%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
-					ZR_DEVNAME(zr), i);
-				jpg_fbuffer_free(file);
+					"%s: %s - kmalloc failed for buffer %d\n",
+					ZR_DEVNAME(zr), __func__, i);
+				jpg_fbuffer_free(fh);
 				return -ENOBUFS;
 			}
-			fh->jpg_buffers.buffer[i].frag_tab[0] =
-			    cpu_to_le32(virt_to_bus((void *) mem));
-			fh->jpg_buffers.buffer[i].frag_tab[1] =
-			    cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
-			for (off = 0; off < fh->jpg_buffers.buffer_size;
-			     off += PAGE_SIZE)
-				SetPageReserved(MAP_NR(mem + off));
+			fh->buffers.buffer[i].jpg.frag_tab[0] =
+				cpu_to_le32(virt_to_bus(mem));
+			fh->buffers.buffer[i].jpg.frag_tab[1] =
+				cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
+			for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+				SetPageReserved(virt_to_page(mem + off));
 		} else {
-			/* jpg_bufsize is allreay page aligned */
-			for (j = 0;
-			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
-			     j++) {
-				mem = get_zeroed_page(GFP_KERNEL);
-				if (mem == 0) {
+			/* jpg_bufsize is already page aligned */
+			for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+				mem = (void *)get_zeroed_page(GFP_KERNEL);
+				if (mem == NULL) {
 					dprintk(1,
 						KERN_ERR
-						"%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
-						ZR_DEVNAME(zr), i);
-					jpg_fbuffer_free(file);
+						"%s: %s - get_zeroed_page failed for buffer %d\n",
+						ZR_DEVNAME(zr), __func__, i);
+					jpg_fbuffer_free(fh);
 					return -ENOBUFS;
 				}
 
-				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
-				    cpu_to_le32(virt_to_bus((void *) mem));
-				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
-								   1] =
-				    cpu_to_le32((PAGE_SIZE / 4) << 1);
-				SetPageReserved(MAP_NR(mem));
+				fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
+					cpu_to_le32(virt_to_bus(mem));
+				fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
+					cpu_to_le32((PAGE_SIZE >> 2) << 1);
+				SetPageReserved(virt_to_page(mem));
 			}
 
-			fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
+			fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1);
 		}
 	}
 
 	dprintk(4,
-		KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
-		ZR_DEVNAME(zr),
-		(fh->jpg_buffers.num_buffers *
-		 fh->jpg_buffers.buffer_size) >> 10);
+		KERN_DEBUG "%s: %s - %d KB allocated\n",
+		ZR_DEVNAME(zr), __func__,
+		(fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10);
 
-	fh->jpg_buffers.allocated = 1;
+	fh->buffers.allocated = 1;
 
 	return 0;
 }
 
 /* free the MJPEG grab buffers */
-static void
-jpg_fbuffer_free (struct file *file)
+static void jpg_fbuffer_free(struct zoran_fh *fh)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int i, j, off;
 	unsigned char *mem;
+	__le32 frag_tab;
+	struct zoran_buffer *buffer;
 
-	dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
+	dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
 
-	for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
-		if (!fh->jpg_buffers.buffer[i].frag_tab)
+	for (i = 0, buffer = &fh->buffers.buffer[0];
+	     i < fh->buffers.num_buffers; i++, buffer++) {
+		if (!buffer->jpg.frag_tab)
 			continue;
 
-		//if (alloc_contig) {
-		if (fh->jpg_buffers.need_contiguous) {
-			if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
-				mem = (unsigned char *) bus_to_virt(le32_to_cpu(
-					fh->jpg_buffers.buffer[i].frag_tab[0]));
-				for (off = 0;
-				     off < fh->jpg_buffers.buffer_size;
-				     off += PAGE_SIZE)
-					ClearPageReserved(MAP_NR
-							  (mem + off));
+		if (fh->buffers.need_contiguous) {
+			frag_tab = buffer->jpg.frag_tab[0];
+
+			if (frag_tab) {
+				mem = bus_to_virt(le32_to_cpu(frag_tab));
+				for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+					ClearPageReserved(virt_to_page(mem + off));
 				kfree(mem);
-				fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
-				fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
+				buffer->jpg.frag_tab[0] = 0;
+				buffer->jpg.frag_tab[1] = 0;
 			}
 		} else {
-			for (j = 0;
-			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
-			     j++) {
-				if (!fh->jpg_buffers.buffer[i].
-				    frag_tab[2 * j])
+			for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+				frag_tab = buffer->jpg.frag_tab[2 * j];
+
+				if (!frag_tab)
 					break;
-				ClearPageReserved(MAP_NR
-						  (bus_to_virt
-						   (le32_to_cpu
-						    (fh->jpg_buffers.
-						     buffer[i].frag_tab[2 *
-								       j]))));
-				free_page((unsigned long)
-					  bus_to_virt
-						  (le32_to_cpu
-						   (fh->jpg_buffers.
-						      buffer[i].
-						      frag_tab[2 * j])));
-				fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
-				    0;
-				fh->jpg_buffers.buffer[i].frag_tab[2 * j +
-								   1] = 0;
+				ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
+				free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab)));
+				buffer->jpg.frag_tab[2 * j] = 0;
+				buffer->jpg.frag_tab[2 * j + 1] = 0;
 			}
 		}
 
-		free_page((unsigned long) fh->jpg_buffers.buffer[i].
-			  frag_tab);
-		fh->jpg_buffers.buffer[i].frag_tab = NULL;
+		free_page((unsigned long)buffer->jpg.frag_tab);
+		buffer->jpg.frag_tab = NULL;
 	}
 
-	fh->jpg_buffers.allocated = 0;
-	fh->jpg_buffers.ready_to_be_freed = 0;
+	fh->buffers.allocated = 0;
 }
 
 /*
@@ -621,12 +436,11 @@ jpg_fbuffer_free (struct file *file)
  */
 
 static int
-zoran_v4l_set_format (struct file               *file,
+zoran_v4l_set_format (struct zoran_fh           *fh,
 		      int                        width,
 		      int                        height,
 		      const struct zoran_format *format)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int bpp;
 
@@ -636,19 +450,19 @@ zoran_v4l_set_format (struct file
 	    height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_set_format() - wrong frame size (%dx%d)\n",
-			ZR_DEVNAME(zr), width, height);
+			"%s: %s - wrong frame size (%dx%d)\n",
+			ZR_DEVNAME(zr), __func__, width, height);
 		return -EINVAL;
 	}
 
 	bpp = (format->depth + 7) / 8;
 
 	/* Check against available buffer size */
-	if (height * width * bpp > fh->v4l_buffers.buffer_size) {
+	if (height * width * bpp > fh->buffers.buffer_size) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
-			ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
+			"%s: %s - video buffer size (%d kB) is too small\n",
+			ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10);
 		return -EINVAL;
 	}
 
@@ -657,8 +471,8 @@ zoran_v4l_set_format (struct file
 	if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_set_format() - wrong frame alingment\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - wrong frame alignment\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
@@ -670,43 +484,40 @@ zoran_v4l_set_format (struct file
 	return 0;
 }
 
-static int
-zoran_v4l_queue_frame (struct file *file,
-		       int          num)
+static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	unsigned long flags;
 	int res = 0;
 
-	if (!fh->v4l_buffers.allocated) {
+	if (!fh->buffers.allocated) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_queue_frame() - buffers not yet allocated\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - buffers not yet allocated\n",
+			ZR_DEVNAME(zr), __func__);
 		res = -ENOMEM;
 	}
 
 	/* No grabbing outside the buffer range! */
-	if (num >= fh->v4l_buffers.num_buffers || num < 0) {
+	if (num >= fh->buffers.num_buffers || num < 0) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_queue_frame() - buffer %d is out of range\n",
-			ZR_DEVNAME(zr), num);
+			"%s: %s - buffer %d is out of range\n",
+			ZR_DEVNAME(zr), __func__, num);
 		res = -EINVAL;
 	}
 
 	spin_lock_irqsave(&zr->spinlock, flags);
 
-	if (fh->v4l_buffers.active == ZORAN_FREE) {
+	if (fh->buffers.active == ZORAN_FREE) {
 		if (zr->v4l_buffers.active == ZORAN_FREE) {
-			zr->v4l_buffers = fh->v4l_buffers;
-			fh->v4l_buffers.active = ZORAN_ACTIVE;
+			zr->v4l_buffers = fh->buffers;
+			fh->buffers.active = ZORAN_ACTIVE;
 		} else {
 			dprintk(1,
 				KERN_ERR
-				"%s: v4l_queue_frame() - another session is already capturing\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - another session is already capturing\n",
+				ZR_DEVNAME(zr), __func__);
 			res = -EBUSY;
 		}
 	}
@@ -717,7 +528,7 @@ zoran_v4l_queue_frame (struct file *file
 		default:
 		case BUZ_STATE_PEND:
 			if (zr->v4l_buffers.active == ZORAN_FREE) {
-				fh->v4l_buffers.active = ZORAN_FREE;
+				fh->buffers.active = ZORAN_FREE;
 				zr->v4l_buffers.allocated = 0;
 			}
 			res = -EBUSY;	/* what are you doing? */
@@ -725,19 +536,17 @@ zoran_v4l_queue_frame (struct file *file
 		case BUZ_STATE_DONE:
 			dprintk(2,
 				KERN_WARNING
-				"%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
-				ZR_DEVNAME(zr), num);
+				"%s: %s - queueing buffer %d in state DONE!?\n",
+				ZR_DEVNAME(zr), __func__, num);
 		case BUZ_STATE_USER:
 			/* since there is at least one unused buffer there's room for at least
 			 * one more pend[] entry */
-			zr->v4l_pend[zr->v4l_pend_head++ &
-					V4L_MASK_FRAME] = num;
+			zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num;
 			zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
 			zr->v4l_buffers.buffer[num].bs.length =
 			    fh->v4l_settings.bytesperline *
 			    zr->v4l_settings.height;
-			fh->v4l_buffers.buffer[num] =
-			    zr->v4l_buffers.buffer[num];
+			fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num];
 			break;
 		}
 	}
@@ -745,65 +554,7 @@ zoran_v4l_queue_frame (struct file *file
 	spin_unlock_irqrestore(&zr->spinlock, flags);
 
 	if (!res && zr->v4l_buffers.active == ZORAN_FREE)
-		zr->v4l_buffers.active = fh->v4l_buffers.active;
-
-	return res;
-}
-
-static int
-v4l_grab (struct file       *file,
-	  struct video_mmap *mp)
-{
-	struct zoran_fh *fh = file->private_data;
-	struct zoran *zr = fh->zr;
-	int res = 0, i;
-
-	for (i = 0; i < NUM_FORMATS; i++) {
-		if (zoran_formats[i].palette == mp->format &&
-		    zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
-		    !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
-			break;
-	}
-	if (i == NUM_FORMATS || zoran_formats[i].depth == 0) {
-		dprintk(1,
-			KERN_ERR
-			"%s: v4l_grab() - wrong bytes-per-pixel format\n",
-			ZR_DEVNAME(zr));
-		return -EINVAL;
-	}
-
-	/*
-	 * To minimize the time spent in the IRQ routine, we avoid setting up
-	 * the video front end there.
-	 * If this grab has different parameters from a running streaming capture
-	 * we stop the streaming capture and start it over again.
-	 */
-	if (zr->v4l_memgrab_active &&
-	    (zr->v4l_settings.width != mp->width ||
-	     zr->v4l_settings.height != mp->height ||
-	     zr->v4l_settings.format->palette != mp->format)) {
-		res = wait_grab_pending(zr);
-		if (res)
-			return res;
-	}
-	if ((res = zoran_v4l_set_format(file,
-					mp->width,
-					mp->height,
-					&zoran_formats[i])))
-		return res;
-	zr->v4l_settings = fh->v4l_settings;
-
-	/* queue the frame in the pending queue */
-	if ((res = zoran_v4l_queue_frame(file, mp->frame))) {
-		fh->v4l_buffers.active = ZORAN_FREE;
-		return res;
-	}
-
-	/* put the 36057 into frame grabbing mode */
-	if (!res && !zr->v4l_memgrab_active)
-		zr36057_set_memgrab(zr, 1);
-
-	//dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr));
+		zr->v4l_buffers.active = fh->buffers.active;
 
 	return res;
 }
@@ -812,27 +563,24 @@ v4l_grab (struct file       *file,
  * Sync on a V4L buffer
  */
 
-static int
-v4l_sync (struct file *file,
-	  int          frame)
+static int v4l_sync(struct zoran_fh *fh, int frame)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	unsigned long flags;
 
-	if (fh->v4l_buffers.active == ZORAN_FREE) {
+	if (fh->buffers.active == ZORAN_FREE) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_sync() - no grab active for this session\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - no grab active for this session\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
 	/* check passed-in frame number */
-	if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
+	if (frame >= fh->buffers.num_buffers || frame < 0) {
 		dprintk(1,
-			KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
-			ZR_DEVNAME(zr), frame);
+			KERN_ERR "%s: %s - frame %d is invalid\n",
+			ZR_DEVNAME(zr), __func__, frame);
 		return -EINVAL;
 	}
 
@@ -840,15 +588,14 @@ v4l_sync (struct file *file,
 	if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
 		dprintk(1,
 			KERN_ERR
-			"%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - attempt to sync on a buffer which was not queued?\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EPROTO;
 	}
 
 	/* wait on this buffer to get ready */
 	if (!wait_event_interruptible_timeout(zr->v4l_capq,
-				(zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
-				10*HZ))
+		(zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ))
 		return -ETIME;
 	if (signal_pending(current))
 		return -ERESTARTSYS;
@@ -856,11 +603,11 @@ v4l_sync (struct file *file,
 	/* buffer should now be in BUZ_STATE_DONE */
 	if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
 		dprintk(2,
-			KERN_ERR "%s: v4l_sync() - internal state error\n",
-			ZR_DEVNAME(zr));
+			KERN_ERR "%s: %s - internal state error\n",
+			ZR_DEVNAME(zr), __func__);
 
 	zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
-	fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
+	fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
 
 	spin_lock_irqsave(&zr->spinlock, flags);
 
@@ -868,8 +615,7 @@ v4l_sync (struct file *file,
 	if (zr->v4l_pend_tail == zr->v4l_pend_head) {
 		zr36057_set_memgrab(zr, 0);
 		if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
-			fh->v4l_buffers.active = zr->v4l_buffers.active =
-			    ZORAN_FREE;
+			fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE;
 			zr->v4l_buffers.allocated = 0;
 		}
 	}
@@ -883,31 +629,28 @@ v4l_sync (struct file *file,
  *   Queue a MJPEG buffer for capture/playback
  */
 
-static int
-zoran_jpg_queue_frame (struct file          *file,
-		       int                   num,
-		       enum zoran_codec_mode mode)
+static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num,
+				 enum zoran_codec_mode mode)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	unsigned long flags;
 	int res = 0;
 
 	/* Check if buffers are allocated */
-	if (!fh->jpg_buffers.allocated) {
+	if (!fh->buffers.allocated) {
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_queue_frame() - buffers not yet allocated\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - buffers not yet allocated\n",
+			ZR_DEVNAME(zr), __func__);
 		return -ENOMEM;
 	}
 
 	/* No grabbing outside the buffer range! */
-	if (num >= fh->jpg_buffers.num_buffers || num < 0) {
+	if (num >= fh->buffers.num_buffers || num < 0) {
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_queue_frame() - buffer %d out of range\n",
-			ZR_DEVNAME(zr), num);
+			"%s: %s - buffer %d out of range\n",
+			ZR_DEVNAME(zr), __func__, num);
 		return -EINVAL;
 	}
 
@@ -918,20 +661,20 @@ zoran_jpg_queue_frame (struct file
 		/* wrong codec mode active - invalid */
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_queue_frame() - codec in wrong mode\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - codec in wrong mode\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
-	if (fh->jpg_buffers.active == ZORAN_FREE) {
+	if (fh->buffers.active == ZORAN_FREE) {
 		if (zr->jpg_buffers.active == ZORAN_FREE) {
-			zr->jpg_buffers = fh->jpg_buffers;
-			fh->jpg_buffers.active = ZORAN_ACTIVE;
+			zr->jpg_buffers = fh->buffers;
+			fh->buffers.active = ZORAN_ACTIVE;
 		} else {
 			dprintk(1,
 				KERN_ERR
-				"%s: jpg_queue_frame() - another session is already capturing\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - another session is already capturing\n",
+				ZR_DEVNAME(zr), __func__);
 			res = -EBUSY;
 		}
 	}
@@ -948,23 +691,21 @@ zoran_jpg_queue_frame (struct file
 		case BUZ_STATE_DONE:
 			dprintk(2,
 				KERN_WARNING
-				"%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - queing frame in BUZ_STATE_DONE state!?\n",
+				ZR_DEVNAME(zr), __func__);
 		case BUZ_STATE_USER:
 			/* since there is at least one unused buffer there's room for at
 			 *least one more pend[] entry */
-			zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
-			    num;
+			zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num;
 			zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
-			fh->jpg_buffers.buffer[num] =
-			    zr->jpg_buffers.buffer[num];
+			fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num];
 			zoran_feed_stat_com(zr);
 			break;
 		default:
 		case BUZ_STATE_DMA:
 		case BUZ_STATE_PEND:
 			if (zr->jpg_buffers.active == ZORAN_FREE) {
-				fh->jpg_buffers.active = ZORAN_FREE;
+				fh->buffers.active = ZORAN_FREE;
 				zr->jpg_buffers.allocated = 0;
 			}
 			res = -EBUSY;	/* what are you doing? */
@@ -974,47 +715,41 @@ zoran_jpg_queue_frame (struct file
 
 	spin_unlock_irqrestore(&zr->spinlock, flags);
 
-	if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
-		zr->jpg_buffers.active = fh->jpg_buffers.active;
-	}
+	if (!res && zr->jpg_buffers.active == ZORAN_FREE)
+		zr->jpg_buffers.active = fh->buffers.active;
 
 	return res;
 }
 
-static int
-jpg_qbuf (struct file          *file,
-	  int                   frame,
-	  enum zoran_codec_mode mode)
+static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	int res = 0;
 
 	/* Does the user want to stop streaming? */
 	if (frame < 0) {
 		if (zr->codec_mode == mode) {
-			if (fh->jpg_buffers.active == ZORAN_FREE) {
+			if (fh->buffers.active == ZORAN_FREE) {
 				dprintk(1,
 					KERN_ERR
-					"%s: jpg_qbuf(-1) - session not active\n",
-					ZR_DEVNAME(zr));
+					"%s: %s(-1) - session not active\n",
+					ZR_DEVNAME(zr), __func__);
 				return -EINVAL;
 			}
-			fh->jpg_buffers.active = zr->jpg_buffers.active =
-			    ZORAN_FREE;
+			fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE;
 			zr->jpg_buffers.allocated = 0;
 			zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
 			return 0;
 		} else {
 			dprintk(1,
 				KERN_ERR
-				"%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - stop streaming but not in streaming mode\n",
+				ZR_DEVNAME(zr), __func__);
 			return -EINVAL;
 		}
 	}
 
-	if ((res = zoran_jpg_queue_frame(file, frame, mode)))
+	if ((res = zoran_jpg_queue_frame(fh, frame, mode)))
 		return res;
 
 	/* Start the jpeg codec when the first frame is queued  */
@@ -1028,28 +763,25 @@ jpg_qbuf (struct file          *file,
  *   Sync on a MJPEG buffer
  */
 
-static int
-jpg_sync (struct file       *file,
-	  struct zoran_sync *bs)
+static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 	unsigned long flags;
 	int frame;
 
-	if (fh->jpg_buffers.active == ZORAN_FREE) {
+	if (fh->buffers.active == ZORAN_FREE) {
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_sync() - capture is not currently active\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - capture is not currently active\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 	if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
 	    zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_sync() - codec not in streaming mode\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - codec not in streaming mode\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 	if (!wait_event_interruptible_timeout(zr->jpg_capq,
@@ -1064,8 +796,8 @@ jpg_sync (struct file       *file,
 					   sizeof(isr), &isr);
 		dprintk(1,
 			KERN_ERR
-			"%s: jpg_sync() - timeout: codec isr=0x%02x\n",
-			ZR_DEVNAME(zr), isr);
+			"%s: %s - timeout: codec isr=0x%02x\n",
+			ZR_DEVNAME(zr), __func__, isr);
 
 		return -ETIME;
 
@@ -1083,28 +815,26 @@ jpg_sync (struct file       *file,
 	/* buffer should now be in BUZ_STATE_DONE */
 	if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
 		dprintk(2,
-			KERN_ERR "%s: jpg_sync() - internal state error\n",
-			ZR_DEVNAME(zr));
+			KERN_ERR "%s: %s - internal state error\n",
+			ZR_DEVNAME(zr), __func__);
 
 	*bs = zr->jpg_buffers.buffer[frame].bs;
 	bs->frame = frame;
 	zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
-	fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
+	fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
 
 	spin_unlock_irqrestore(&zr->spinlock, flags);
 
 	return 0;
 }
 
-static void
-zoran_open_init_session (struct file *file)
+static void zoran_open_init_session(struct zoran_fh *fh)
 {
 	int i;
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
 	/* Per default, map the V4L Buffers */
-	fh->map_mode = ZORAN_MAP_MODE_RAW;
+	map_mode_raw(fh);
 
 	/* take over the card's current settings */
 	fh->overlay_settings = zr->overlay_settings;
@@ -1114,40 +844,21 @@ zoran_open_init_session (struct file *fi
 
 	/* v4l settings */
 	fh->v4l_settings = zr->v4l_settings;
-
-	/* v4l_buffers */
-	memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
-	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
-		fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */
-		fh->v4l_buffers.buffer[i].bs.frame = i;
-	}
-	fh->v4l_buffers.allocated = 0;
-	fh->v4l_buffers.ready_to_be_freed = 0;
-	fh->v4l_buffers.active = ZORAN_FREE;
-	fh->v4l_buffers.buffer_size = v4l_bufsize;
-	fh->v4l_buffers.num_buffers = v4l_nbufs;
-
 	/* jpg settings */
 	fh->jpg_settings = zr->jpg_settings;
 
-	/* jpg_buffers */
-	memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
-	for (i = 0; i < BUZ_MAX_FRAME; i++) {
-		fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */
-		fh->jpg_buffers.buffer[i].bs.frame = i;
+	/* buffers */
+	memset(&fh->buffers, 0, sizeof(fh->buffers));
+	for (i = 0; i < MAX_FRAME; i++) {
+		fh->buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */
+		fh->buffers.buffer[i].bs.frame = i;
 	}
-	fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
-	fh->jpg_buffers.allocated = 0;
-	fh->jpg_buffers.ready_to_be_freed = 0;
-	fh->jpg_buffers.active = ZORAN_FREE;
-	fh->jpg_buffers.buffer_size = jpg_bufsize;
-	fh->jpg_buffers.num_buffers = jpg_nbufs;
+	fh->buffers.allocated = 0;
+	fh->buffers.active = ZORAN_FREE;
 }
 
-static void
-zoran_close_end_session (struct file *file)
+static void zoran_close_end_session(struct zoran_fh *fh)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
 	/* overlay */
@@ -1159,36 +870,32 @@ zoran_close_end_session (struct file *fi
 		zr->overlay_mask = NULL;
 	}
 
-	/* v4l capture */
-	if (fh->v4l_buffers.active != ZORAN_FREE) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&zr->spinlock, flags);
-		zr36057_set_memgrab(zr, 0);
-		zr->v4l_buffers.allocated = 0;
-		zr->v4l_buffers.active = fh->v4l_buffers.active =
-		    ZORAN_FREE;
-		spin_unlock_irqrestore(&zr->spinlock, flags);
-	}
+	if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+		/* v4l capture */
+		if (fh->buffers.active != ZORAN_FREE) {
+			unsigned long flags;
 
-	/* v4l buffers */
-	if (fh->v4l_buffers.allocated ||
-	    fh->v4l_buffers.ready_to_be_freed) {
-		v4l_fbuffer_free(file);
-	}
+			spin_lock_irqsave(&zr->spinlock, flags);
+			zr36057_set_memgrab(zr, 0);
+			zr->v4l_buffers.allocated = 0;
+			zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+			spin_unlock_irqrestore(&zr->spinlock, flags);
+		}
 
-	/* jpg capture */
-	if (fh->jpg_buffers.active != ZORAN_FREE) {
-		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-		zr->jpg_buffers.allocated = 0;
-		zr->jpg_buffers.active = fh->jpg_buffers.active =
-		    ZORAN_FREE;
-	}
+		/* v4l buffers */
+		if (fh->buffers.allocated)
+			v4l_fbuffer_free(fh);
+	} else {
+		/* jpg capture */
+		if (fh->buffers.active != ZORAN_FREE) {
+			zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+			zr->jpg_buffers.allocated = 0;
+			zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
+		}
 
-	/* jpg buffers */
-	if (fh->jpg_buffers.allocated ||
-	    fh->jpg_buffers.ready_to_be_freed) {
-		jpg_fbuffer_free(file);
+		/* jpg buffers */
+		if (fh->buffers.allocated)
+			jpg_fbuffer_free(fh);
 	}
 }
 
@@ -1202,15 +909,11 @@ static int zoran_open(struct file *file)
 	struct zoran_fh *fh;
 	int res, first_open = 0;
 
-	dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
+	dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
+		ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
 
 	lock_kernel();
 
-	/* see fs/device.c - the kernel already locks during open(),
-	 * so locking ourselves only causes deadlocks */
-	/*mutex_lock(&zr->resource_lock);*/
-
 	if (zr->user >= 2048) {
 		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
 			ZR_DEVNAME(zr), zr->user);
@@ -1218,41 +921,15 @@ static int zoran_open(struct file *file)
 		goto fail_unlock;
 	}
 
-	if (!zr->decoder) {
-		dprintk(1,
-			KERN_ERR "%s: no TV decoder loaded for device!\n",
-			ZR_DEVNAME(zr));
-		res = -EIO;
-		goto fail_unlock;
-	}
-
-	if (!try_module_get(zr->decoder->driver->driver.owner)) {
-		dprintk(1,
-			KERN_ERR
-			"%s: failed to grab ownership of video decoder\n",
-			ZR_DEVNAME(zr));
-		res = -EIO;
-		goto fail_unlock;
-	}
-	if (zr->encoder &&
-	    !try_module_get(zr->encoder->driver->driver.owner)) {
-		dprintk(1,
-			KERN_ERR
-			"%s: failed to grab ownership of video encoder\n",
-			ZR_DEVNAME(zr));
-		res = -EIO;
-		goto fail_decoder;
-	}
-
 	/* now, create the open()-specific file_ops struct */
 	fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
 	if (!fh) {
 		dprintk(1,
 			KERN_ERR
-			"%s: zoran_open() - allocation of zoran_fh failed\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - allocation of zoran_fh failed\n",
+			ZR_DEVNAME(zr), __func__);
 		res = -ENOMEM;
-		goto fail_encoder;
+		goto fail_unlock;
 	}
 	/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
 	 * on norm-change! */
@@ -1261,8 +938,8 @@ static int zoran_open(struct file *file)
 	if (!fh->overlay_mask) {
 		dprintk(1,
 			KERN_ERR
-			"%s: zoran_open() - allocation of overlay_mask failed\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - allocation of overlay_mask failed\n",
+			ZR_DEVNAME(zr), __func__);
 		res = -ENOMEM;
 		goto fail_fh;
 	}
@@ -1284,18 +961,13 @@ static int zoran_open(struct file *file)
 	/* set file_ops stuff */
 	file->private_data = fh;
 	fh->zr = zr;
-	zoran_open_init_session(file);
+	zoran_open_init_session(fh);
 	unlock_kernel();
 
 	return 0;
 
 fail_fh:
 	kfree(fh);
-fail_encoder:
-	if (zr->encoder)
-		module_put(zr->encoder->driver->driver.owner);
-fail_decoder:
-	module_put(zr->decoder->driver->driver.owner);
 fail_unlock:
 	unlock_kernel();
 
@@ -1311,14 +983,14 @@ zoran_close(struct file  *file)
 	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
-	dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
+	dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n",
+		ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1);
 
 	/* kernel locks (fs/device.c), so don't do that ourselves
 	 * (prevents deadlocks) */
 	/*mutex_lock(&zr->resource_lock);*/
 
-	zoran_close_end_session(file);
+	zoran_close_end_session(fh);
 
 	if (zr->user-- == 1) {	/* Last process */
 		/* Clean up JPEG process */
@@ -1346,9 +1018,8 @@ zoran_close(struct file  *file)
 		zoran_set_pci_master(zr, 0);
 
 		if (!pass_through) {	/* Switch to color bar */
-			int zero = 0, two = 2;
-			decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
-			encoder_command(zr, ENCODER_SET_INPUT, &two);
+			decoder_call(zr, video, s_stream, 0);
+			encoder_call(zr, video, s_routing, 2, 0, 0);
 		}
 	}
 
@@ -1356,14 +1027,7 @@ zoran_close(struct file  *file)
 	kfree(fh->overlay_mask);
 	kfree(fh);
 
-	/* release locks on the i2c modules */
-	module_put(zr->decoder->driver->driver.owner);
-	if (zr->encoder)
-		module_put(zr->encoder->driver->driver.owner);
-
-	/*mutex_unlock(&zr->resource_lock);*/
-
-	dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
+	dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__);
 
 	return 0;
 }
@@ -1391,15 +1055,13 @@ zoran_write (struct file *file,
 	return -EINVAL;
 }
 
-static int
-setup_fbuffer (struct file               *file,
+static int setup_fbuffer(struct zoran_fh *fh,
 	       void                      *base,
 	       const struct zoran_format *fmt,
 	       int                        width,
 	       int                        height,
 	       int                        bytesperline)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
 	/* (Ronald) v4l/v4l2 guidelines */
@@ -1427,8 +1089,8 @@ setup_fbuffer (struct file
 		 * friendly and silently do as if nothing went wrong */
 		dprintk(3,
 			KERN_ERR
-			"%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - forced overlay turnoff because framebuffer changed\n",
+			ZR_DEVNAME(zr), __func__);
 		zr36057_overlay(zr, 0);
 	}
 #endif
@@ -1436,31 +1098,31 @@ setup_fbuffer (struct file
 	if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_fbuffer() - no valid overlay format given\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - no valid overlay format given\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 	if (height <= 0 || width <= 0 || bytesperline <= 0) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
-			ZR_DEVNAME(zr), width, height, bytesperline);
+			"%s: %s - invalid height/width/bpl value (%d|%d|%d)\n",
+			ZR_DEVNAME(zr), __func__, width, height, bytesperline);
 		return -EINVAL;
 	}
 	if (bytesperline & 3) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
-			ZR_DEVNAME(zr), bytesperline);
+			"%s: %s - bytesperline (%d) must be 4-byte aligned\n",
+			ZR_DEVNAME(zr), __func__, bytesperline);
 		return -EINVAL;
 	}
 
-	zr->buffer.base = (void *) ((unsigned long) base & ~3);
-	zr->buffer.height = height;
-	zr->buffer.width = width;
-	zr->buffer.depth = fmt->depth;
+	zr->vbuf_base = (void *) ((unsigned long) base & ~3);
+	zr->vbuf_height = height;
+	zr->vbuf_width = width;
+	zr->vbuf_depth = fmt->depth;
 	zr->overlay_settings.format = fmt;
-	zr->buffer.bytesperline = bytesperline;
+	zr->vbuf_bytesperline = bytesperline;
 
 	/* The user should set new window parameters */
 	zr->overlay_settings.is_set = 0;
@@ -1469,35 +1131,27 @@ setup_fbuffer (struct file
 }
 
 
-static int
-setup_window (struct file       *file,
-	      int                x,
-	      int                y,
-	      int                width,
-	      int                height,
-	      struct video_clip __user *clips,
-	      int                clipcount,
-	      void              __user *bitmap)
+static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height,
+	struct v4l2_clip __user *clips, int clipcount, void __user *bitmap)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
-	struct video_clip *vcp = NULL;
+	struct v4l2_clip *vcp = NULL;
 	int on, end;
 
 
-	if (!zr->buffer.base) {
+	if (!zr->vbuf_base) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_window() - frame buffer has to be set first\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - frame buffer has to be set first\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
 	if (!fh->overlay_settings.format) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_window() - no overlay format set\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - no overlay format set\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
@@ -1505,13 +1159,13 @@ setup_window (struct file       *file,
 	 * The video front end needs 4-byte alinged line sizes, we correct that
 	 * silently here if necessary
 	 */
-	if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
+	if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) {
 		end = (x + width) & ~1;	/* round down */
 		x = (x + 1) & ~1;	/* round up */
 		width = end - x;
 	}
 
-	if (zr->buffer.depth == 24) {
+	if (zr->vbuf_depth == 24) {
 		end = (x + width) & ~3;	/* round down */
 		x = (x + 3) & ~3;	/* round up */
 		width = end - x;
@@ -1527,8 +1181,8 @@ setup_window (struct file       *file,
 	    width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_window() - width = %d or height = %d invalid\n",
-			ZR_DEVNAME(zr), width, height);
+			"%s: %s - width = %d or height = %d invalid\n",
+			ZR_DEVNAME(zr), __func__, width, height);
 		return -EINVAL;
 	}
 
@@ -1566,20 +1220,20 @@ setup_window (struct file       *file,
 		}
 	} else if (clipcount > 0) {
 		/* write our own bitmap from the clips */
-		vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
+		vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4));
 		if (vcp == NULL) {
 			dprintk(1,
 				KERN_ERR
-				"%s: setup_window() - Alloc of clip mask failed\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - Alloc of clip mask failed\n",
+				ZR_DEVNAME(zr), __func__);
 			return -ENOMEM;
 		}
 		if (copy_from_user
-		    (vcp, clips, sizeof(struct video_clip) * clipcount)) {
+		    (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) {
 			vfree(vcp);
 			return -EFAULT;
 		}
-		write_overlay_mask(file, vcp, clipcount);
+		write_overlay_mask(fh, vcp, clipcount);
 		vfree(vcp);
 	}
 
@@ -1595,11 +1249,8 @@ setup_window (struct file       *file,
 	return wait_grab_pending(zr);
 }
 
-static int
-setup_overlay (struct file *file,
-	       int          on)
+static int setup_overlay(struct zoran_fh *fh, int on)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
 	/* If there is nothing to do, return immediatly */
@@ -1612,16 +1263,16 @@ setup_overlay (struct file *file,
 	    fh->overlay_active == ZORAN_FREE) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_overlay() - overlay is already active for another session\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - overlay is already active for another session\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EBUSY;
 	}
 	if (!on && zr->overlay_active != ZORAN_FREE &&
 	    fh->overlay_active == ZORAN_FREE) {
 		dprintk(1,
 			KERN_ERR
-			"%s: setup_overlay() - you cannot cancel someone else's session\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - you cannot cancel someone else's session\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EPERM;
 	}
 
@@ -1634,18 +1285,18 @@ setup_overlay (struct file *file,
 			zr36057_overlay(zr, 0);
 		zr->overlay_mask = NULL;
 	} else {
-		if (!zr->buffer.base || !fh->overlay_settings.is_set) {
+		if (!zr->vbuf_base || !fh->overlay_settings.is_set) {
 			dprintk(1,
 				KERN_ERR
-				"%s: setup_overlay() - buffer or window not set\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - buffer or window not set\n",
+				ZR_DEVNAME(zr), __func__);
 			return -EINVAL;
 		}
 		if (!fh->overlay_settings.format) {
 			dprintk(1,
 				KERN_ERR
-				"%s: setup_overlay() - no overlay format set\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - no overlay format set\n",
+				ZR_DEVNAME(zr), __func__);
 			return -EINVAL;
 		}
 		zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
@@ -1662,41 +1313,47 @@ setup_overlay (struct file *file,
 	return wait_grab_pending(zr);
 }
 
-	/* get the status of a buffer in the clients buffer queue */
-static int
-zoran_v4l2_buffer_status (struct file        *file,
-			  struct v4l2_buffer *buf,
-			  int                 num)
+/* get the status of a buffer in the clients buffer queue */
+static int zoran_v4l2_buffer_status(struct zoran_fh *fh,
+				    struct v4l2_buffer *buf, int num)
 {
-	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
+	unsigned long flags;
 
 	buf->flags = V4L2_BUF_FLAG_MAPPED;
 
 	switch (fh->map_mode) {
 	case ZORAN_MAP_MODE_RAW:
-
 		/* check range */
-		if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
-		    !fh->v4l_buffers.allocated) {
+		if (num < 0 || num >= fh->buffers.num_buffers ||
+		    !fh->buffers.allocated) {
 			dprintk(1,
 				KERN_ERR
-				"%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - wrong number or buffers not allocated\n",
+				ZR_DEVNAME(zr), __func__);
 			return -EINVAL;
 		}
 
+		spin_lock_irqsave(&zr->spinlock, flags);
+		dprintk(3,
+			KERN_DEBUG
+			"%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n",
+			ZR_DEVNAME(zr), __func__,
+			"FAL"[fh->buffers.active], num,
+			"UPMD"[zr->v4l_buffers.buffer[num].state],
+			fh->buffers.buffer[num].map ? 'Y' : 'N');
+		spin_unlock_irqrestore(&zr->spinlock, flags);
+
 		buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		buf->length = fh->v4l_buffers.buffer_size;
+		buf->length = fh->buffers.buffer_size;
 
 		/* get buffer */
-		buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
-		if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
-		    fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
-			buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
+		buf->bytesused = fh->buffers.buffer[num].bs.length;
+		if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+		    fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+			buf->sequence = fh->buffers.buffer[num].bs.seq;
 			buf->flags |= V4L2_BUF_FLAG_DONE;
-			buf->timestamp =
-			    fh->v4l_buffers.buffer[num].bs.timestamp;
+			buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
 		} else {
 			buf->flags |= V4L2_BUF_FLAG_QUEUED;
 		}
@@ -1712,28 +1369,26 @@ zoran_v4l2_buffer_status (struct file
 	case ZORAN_MAP_MODE_JPG_PLAY:
 
 		/* check range */
-		if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
-		    !fh->jpg_buffers.allocated) {
+		if (num < 0 || num >= fh->buffers.num_buffers ||
+		    !fh->buffers.allocated) {
 			dprintk(1,
 				KERN_ERR
-				"%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - wrong number or buffers not allocated\n",
+				ZR_DEVNAME(zr), __func__);
 			return -EINVAL;
 		}
 
 		buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
 			      V4L2_BUF_TYPE_VIDEO_CAPTURE :
 			      V4L2_BUF_TYPE_VIDEO_OUTPUT;
-		buf->length = fh->jpg_buffers.buffer_size;
+		buf->length = fh->buffers.buffer_size;
 
 		/* these variables are only written after frame has been captured */
-		if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
-		    fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
-			buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
-			buf->timestamp =
-			    fh->jpg_buffers.buffer[num].bs.timestamp;
-			buf->bytesused =
-			    fh->jpg_buffers.buffer[num].bs.length;
+		if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+		    fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+			buf->sequence = fh->buffers.buffer[num].bs.seq;
+			buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
+			buf->bytesused = fh->buffers.buffer[num].bs.length;
 			buf->flags |= V4L2_BUF_FLAG_DONE;
 		} else {
 			buf->flags |= V4L2_BUF_FLAG_QUEUED;
@@ -1741,14 +1396,11 @@ zoran_v4l2_buffer_status (struct file
 
 		/* which fields are these? */
 		if (fh->jpg_settings.TmpDcm != 1)
-			buf->field =
-			    fh->jpg_settings.
-			    odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
+			buf->field = fh->jpg_settings.odd_even ?
+				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
 		else
-			buf->field =
-			    fh->jpg_settings.
-			    odd_even ? V4L2_FIELD_SEQ_TB :
-			    V4L2_FIELD_SEQ_BT;
+			buf->field = fh->jpg_settings.odd_even ?
+				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
 
 		break;
 
@@ -1756,8 +1408,8 @@ zoran_v4l2_buffer_status (struct file
 
 		dprintk(5,
 			KERN_ERR
-			"%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
-			ZR_DEVNAME(zr), buf->type, fh->map_mode);
+			"%s: %s - invalid buffer type|map_mode (%d|%d)\n",
+			ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode);
 		return -EINVAL;
 	}
 
@@ -1770,81 +1422,55 @@ zoran_v4l2_buffer_status (struct file
 
 static int
 zoran_set_norm (struct zoran *zr,
-		int           norm) /* VIDEO_MODE_* */
+		v4l2_std_id norm)
 {
-	int norm_encoder, on;
+	int on;
 
 	if (zr->v4l_buffers.active != ZORAN_FREE ||
 	    zr->jpg_buffers.active != ZORAN_FREE) {
 		dprintk(1,
 			KERN_WARNING
-			"%s: set_norm() called while in playback/capture mode\n",
-			ZR_DEVNAME(zr));
+			"%s: %s called while in playback/capture mode\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EBUSY;
 	}
 
-	if (lock_norm && norm != zr->norm) {
-		if (lock_norm > 1) {
-			dprintk(1,
-				KERN_WARNING
-				"%s: set_norm() - TV standard is locked, can not switch norm\n",
-				ZR_DEVNAME(zr));
-			return -EPERM;
-		} else {
-			dprintk(1,
-				KERN_WARNING
-				"%s: set_norm() - TV standard is locked, norm was not changed\n",
-				ZR_DEVNAME(zr));
-			norm = zr->norm;
-		}
-	}
-
-	if (norm != VIDEO_MODE_AUTO &&
-	    (norm < 0 || norm >= zr->card.norms ||
-	     !zr->card.tvn[norm])) {
+	if (!(norm & zr->card.norms)) {
 		dprintk(1,
-			KERN_ERR "%s: set_norm() - unsupported norm %d\n",
-			ZR_DEVNAME(zr), norm);
+			KERN_ERR "%s: %s - unsupported norm %llx\n",
+			ZR_DEVNAME(zr), __func__, norm);
 		return -EINVAL;
 	}
 
-	if (norm == VIDEO_MODE_AUTO) {
-		int status;
-
-		/* if we have autodetect, ... */
-		struct video_decoder_capability caps;
-		decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
-		if (!(caps.flags & VIDEO_DECODER_AUTO)) {
-			dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
-				ZR_DEVNAME(zr));
-			return -EINVAL;
-		}
+	if (norm == V4L2_STD_ALL) {
+		int status = 0;
+		v4l2_std_id std = 0;
 
-		decoder_command(zr, DECODER_SET_NORM, &norm);
+		decoder_call(zr, video, querystd, &std);
+		decoder_call(zr, core, s_std, std);
 
 		/* let changes come into effect */
 		ssleep(2);
 
-		decoder_command(zr, DECODER_GET_STATUS, &status);
-		if (!(status & DECODER_STATUS_GOOD)) {
+		decoder_call(zr, video, g_input_status, &status);
+		if (status & V4L2_IN_ST_NO_SIGNAL) {
 			dprintk(1,
 				KERN_ERR
-				"%s: set_norm() - no norm detected\n",
-				ZR_DEVNAME(zr));
+				"%s: %s - no norm detected\n",
+				ZR_DEVNAME(zr), __func__);
 			/* reset norm */
-			decoder_command(zr, DECODER_SET_NORM, &zr->norm);
+			decoder_call(zr, core, s_std, zr->norm);
 			return -EIO;
 		}
 
-		if (status & DECODER_STATUS_NTSC)
-			norm = VIDEO_MODE_NTSC;
-		else if (status & DECODER_STATUS_SECAM)
-			norm = VIDEO_MODE_SECAM;
-		else
-			norm = VIDEO_MODE_PAL;
+		norm = std;
 	}
-	zr->timing = zr->card.tvn[norm];
-	norm_encoder = norm;
+	if (norm & V4L2_STD_SECAM)
+		zr->timing = zr->card.tvn[2];
+	else if (norm & V4L2_STD_NTSC)
+		zr->timing = zr->card.tvn[1];
+	else
+		zr->timing = zr->card.tvn[0];
 
 	/* We switch overlay off and on since a change in the
 	 * norm needs different VFE settings */
@@ -1852,8 +1478,8 @@ zoran_set_norm (struct zoran *zr,
 	if (on)
 		zr36057_overlay(zr, 0);
 
-	decoder_command(zr, DECODER_SET_NORM, &norm);
-	encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
+	decoder_call(zr, core, s_std, norm);
+	encoder_call(zr, video, s_std_output, norm);
 
 	if (on)
 		zr36057_overlay(zr, 1);
@@ -1868,8 +1494,6 @@ static int
 zoran_set_input (struct zoran *zr,
 		 int           input)
 {
-	int realinput;
-
 	if (input == zr->input) {
 		return 0;
 	}
@@ -1878,23 +1502,23 @@ zoran_set_input (struct zoran *zr,
 	    zr->jpg_buffers.active != ZORAN_FREE) {
 		dprintk(1,
 			KERN_WARNING
-			"%s: set_input() called while in playback/capture mode\n",
-			ZR_DEVNAME(zr));
+			"%s: %s called while in playback/capture mode\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EBUSY;
 	}
 
 	if (input < 0 || input >= zr->card.inputs) {
 		dprintk(1,
 			KERN_ERR
-			"%s: set_input() - unnsupported input %d\n",
-			ZR_DEVNAME(zr), input);
+			"%s: %s - unnsupported input %d\n",
+			ZR_DEVNAME(zr), __func__, input);
 		return -EINVAL;
 	}
 
-	realinput = zr->card.input[input].muxsel;
 	zr->input = input;
 
-	decoder_command(zr, DECODER_SET_INPUT, &realinput);
+	decoder_call(zr, video, s_routing,
+			zr->card.input[input].muxsel, 0, 0);
 
 	return 0;
 }
@@ -1903,410 +1527,14 @@ zoran_set_input (struct zoran *zr,
  *   ioctl routine
  */
 
-static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
 {
-	struct zoran_fh *fh = file->private_data;
+	struct zoran_fh *fh = __fh;
 	struct zoran *zr = fh->zr;
-	/* CAREFUL: used in multiple places here */
 	struct zoran_jpg_settings settings;
 
-	/* we might have older buffers lying around... We don't want
-	 * to wait, but we do want to try cleaning them up ASAP. So
-	 * we try to obtain the lock and free them. If that fails, we
-	 * don't do anything and wait for the next turn. In the end,
-	 * zoran_close() or a new allocation will still free them...
-	 * This is just a 'the sooner the better' extra 'feature'
-	 *
-	 * We don't free the buffers right on munmap() because that
-	 * causes oopses (kfree() inside munmap() oopses for no
-	 * apparent reason - it's also not reproduceable in any way,
-	 * but moving the free code outside the munmap() handler fixes
-	 * all this... If someone knows why, please explain me (Ronald)
-	 */
-	if (mutex_trylock(&zr->resource_lock)) {
-		/* we obtained it! Let's try to free some things */
-		if (fh->jpg_buffers.ready_to_be_freed)
-			jpg_fbuffer_free(file);
-		if (fh->v4l_buffers.ready_to_be_freed)
-			v4l_fbuffer_free(file);
-
-		mutex_unlock(&zr->resource_lock);
-	}
-
 	switch (cmd) {
-
-	case VIDIOCGCAP:
-	{
-		struct video_capability *vcap = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
-
-		memset(vcap, 0, sizeof(struct video_capability));
-		strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1);
-		vcap->type = ZORAN_VID_TYPE;
-
-		vcap->channels = zr->card.inputs;
-		vcap->audios = 0;
-		mutex_lock(&zr->resource_lock);
-		vcap->maxwidth = BUZ_MAX_WIDTH;
-		vcap->maxheight = BUZ_MAX_HEIGHT;
-		vcap->minwidth = BUZ_MIN_WIDTH;
-		vcap->minheight = BUZ_MIN_HEIGHT;
-		mutex_unlock(&zr->resource_lock);
-
-		return 0;
-	}
-		break;
-
-	case VIDIOCGCHAN:
-	{
-		struct video_channel *vchan = arg;
-		int channel = vchan->channel;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n",
-			ZR_DEVNAME(zr), vchan->channel);
-
-		memset(vchan, 0, sizeof(struct video_channel));
-		if (channel > zr->card.inputs || channel < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOCGCHAN on not existing channel %d\n",
-				ZR_DEVNAME(zr), channel);
-			return -EINVAL;
-		}
-
-		strcpy(vchan->name, zr->card.input[channel].name);
-
-		vchan->tuners = 0;
-		vchan->flags = 0;
-		vchan->type = VIDEO_TYPE_CAMERA;
-		mutex_lock(&zr->resource_lock);
-		vchan->norm = zr->norm;
-		mutex_unlock(&zr->resource_lock);
-		vchan->channel = channel;
-
-		return 0;
-	}
-		break;
-
-		/* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
-		 *
-		 * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
-		 * *                                 ^^^^^^^
-		 * * The famos BTTV driver has it implemented with a struct video_channel argument
-		 * * and we follow it for compatibility reasons
-		 * *
-		 * * BTW: this is the only way the user can set the norm!
-		 */
-
-	case VIDIOCSCHAN:
-	{
-		struct video_channel *vchan = arg;
-		int res;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOCSCHAN - channel=%d, norm=%d\n",
-			ZR_DEVNAME(zr), vchan->channel, vchan->norm);
-
-		mutex_lock(&zr->resource_lock);
-		if ((res = zoran_set_input(zr, vchan->channel)))
-			goto schan_unlock_and_return;
-		if ((res = zoran_set_norm(zr, vchan->norm)))
-			goto schan_unlock_and_return;
-
-		/* Make sure the changes come into effect */
-		res = wait_grab_pending(zr);
-	schan_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
-		break;
-
-	case VIDIOCGPICT:
-	{
-		struct video_picture *vpict = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr));
-
-		memset(vpict, 0, sizeof(struct video_picture));
-		mutex_lock(&zr->resource_lock);
-		vpict->hue = zr->hue;
-		vpict->brightness = zr->brightness;
-		vpict->contrast = zr->contrast;
-		vpict->colour = zr->saturation;
-		if (fh->overlay_settings.format) {
-			vpict->depth = fh->overlay_settings.format->depth;
-			vpict->palette = fh->overlay_settings.format->palette;
-		} else {
-			vpict->depth = 0;
-		}
-		mutex_unlock(&zr->resource_lock);
-
-		return 0;
-	}
-		break;
-
-	case VIDIOCSPICT:
-	{
-		struct video_picture *vpict = arg;
-		int i;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n",
-			ZR_DEVNAME(zr), vpict->brightness, vpict->hue,
-			vpict->colour, vpict->contrast, vpict->depth,
-			vpict->palette);
-
-		for (i = 0; i < NUM_FORMATS; i++) {
-			const struct zoran_format *fmt = &zoran_formats[i];
-
-			if (fmt->palette != -1 &&
-			    fmt->flags & ZORAN_FORMAT_OVERLAY &&
-			    fmt->palette == vpict->palette &&
-			    fmt->depth == vpict->depth)
-				break;
-		}
-		if (i == NUM_FORMATS) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOCSPICT - Invalid palette %d\n",
-				ZR_DEVNAME(zr), vpict->palette);
-			return -EINVAL;
-		}
-
-		mutex_lock(&zr->resource_lock);
-
-		decoder_command(zr, DECODER_SET_PICTURE, vpict);
-
-		zr->hue = vpict->hue;
-		zr->contrast = vpict->contrast;
-		zr->saturation = vpict->colour;
-		zr->brightness = vpict->brightness;
-
-		fh->overlay_settings.format = &zoran_formats[i];
-
-		mutex_unlock(&zr->resource_lock);
-
-		return 0;
-	}
-		break;
-
-	case VIDIOCCAPTURE:
-	{
-		int *on = arg, res;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n",
-			ZR_DEVNAME(zr), *on);
-
-		mutex_lock(&zr->resource_lock);
-		res = setup_overlay(file, *on);
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
-	}
-		break;
-
-	case VIDIOCGWIN:
-	{
-		struct video_window *vwin = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr));
-
-		memset(vwin, 0, sizeof(struct video_window));
-		mutex_lock(&zr->resource_lock);
-		vwin->x = fh->overlay_settings.x;
-		vwin->y = fh->overlay_settings.y;
-		vwin->width = fh->overlay_settings.width;
-		vwin->height = fh->overlay_settings.height;
-		mutex_unlock(&zr->resource_lock);
-		vwin->clipcount = 0;
-		return 0;
-	}
-		break;
-
-	case VIDIOCSWIN:
-	{
-		struct video_window *vwin = arg;
-		int res;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n",
-			ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width,
-			vwin->height, vwin->clipcount);
-
-		mutex_lock(&zr->resource_lock);
-		res =
-		    setup_window(file, vwin->x, vwin->y, vwin->width,
-				 vwin->height, vwin->clips,
-				 vwin->clipcount, NULL);
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
-	}
-		break;
-
-	case VIDIOCGFBUF:
-	{
-		struct video_buffer *vbuf = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr));
-
-		mutex_lock(&zr->resource_lock);
-		*vbuf = zr->buffer;
-		mutex_unlock(&zr->resource_lock);
-		return 0;
-	}
-		break;
-
-	case VIDIOCSFBUF:
-	{
-		struct video_buffer *vbuf = arg;
-		int i, res = 0;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
-			ZR_DEVNAME(zr), vbuf->base, vbuf->width,
-			vbuf->height, vbuf->depth, vbuf->bytesperline);
-
-		for (i = 0; i < NUM_FORMATS; i++)
-			if (zoran_formats[i].depth == vbuf->depth)
-				break;
-		if (i == NUM_FORMATS) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
-				ZR_DEVNAME(zr), vbuf->depth);
-			return -EINVAL;
-		}
-
-		mutex_lock(&zr->resource_lock);
-		res =
-		    setup_fbuffer(file, vbuf->base, &zoran_formats[i],
-				  vbuf->width, vbuf->height,
-				  vbuf->bytesperline);
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
-	}
-		break;
-
-	case VIDIOCSYNC:
-	{
-		int *frame = arg, res;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n",
-			ZR_DEVNAME(zr), *frame);
-
-		mutex_lock(&zr->resource_lock);
-		res = v4l_sync(file, *frame);
-		mutex_unlock(&zr->resource_lock);
-		if (!res)
-			zr->v4l_sync_tail++;
-		return res;
-	}
-		break;
-
-	case VIDIOCMCAPTURE:
-	{
-		struct video_mmap *vmap = arg;
-		int res;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n",
-			ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height,
-			vmap->format);
-
-		mutex_lock(&zr->resource_lock);
-		res = v4l_grab(file, vmap);
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
-		break;
-
-	case VIDIOCGMBUF:
-	{
-		struct video_mbuf *vmbuf = arg;
-		int i, res = 0;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr));
-
-		vmbuf->size =
-		    fh->v4l_buffers.num_buffers *
-		    fh->v4l_buffers.buffer_size;
-		vmbuf->frames = fh->v4l_buffers.num_buffers;
-		for (i = 0; i < vmbuf->frames; i++) {
-			vmbuf->offsets[i] =
-			    i * fh->v4l_buffers.buffer_size;
-		}
-
-		mutex_lock(&zr->resource_lock);
-
-		if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOCGMBUF - buffers already allocated\n",
-				ZR_DEVNAME(zr));
-			res = -EINVAL;
-			goto v4l1reqbuf_unlock_and_return;
-		}
-
-		if (v4l_fbuffer_alloc(file)) {
-			res = -ENOMEM;
-			goto v4l1reqbuf_unlock_and_return;
-		}
-
-		/* The next mmap will map the V4L buffers */
-		fh->map_mode = ZORAN_MAP_MODE_RAW;
-	v4l1reqbuf_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
-	}
-		break;
-
-	case VIDIOCGUNIT:
-	{
-		struct video_unit *vunit = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr));
-
-		vunit->video = zr->video_dev->minor;
-		vunit->vbi = VIDEO_NO_UNIT;
-		vunit->radio = VIDEO_NO_UNIT;
-		vunit->audio = VIDEO_NO_UNIT;
-		vunit->teletext = VIDEO_NO_UNIT;
-
-		return 0;
-	}
-		break;
-
-		/*
-		 * RJ: In principal we could support subcaptures for V4L grabbing.
-		 *     Not even the famous BTTV driver has them, however.
-		 *     If there should be a strong demand, one could consider
-		 *     to implement them.
-		 */
-	case VIDIOCGCAPTURE:
-	{
-		dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n",
-			ZR_DEVNAME(zr));
-		return -EINVAL;
-	}
-		break;
-
-	case VIDIOCSCAPTURE:
-	{
-		dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n",
-			ZR_DEVNAME(zr));
-		return -EINVAL;
-	}
-		break;
-
 	case BUZIOC_G_PARAMS:
 	{
 		struct zoran_params *bparams = arg;
@@ -2319,7 +1547,13 @@ static long zoran_do_ioctl(struct file *
 
 		mutex_lock(&zr->resource_lock);
 
-		bparams->norm = zr->norm;
+		if (zr->norm & V4L2_STD_NTSC)
+			bparams->norm = VIDEO_MODE_NTSC;
+		else if (zr->norm & V4L2_STD_PAL)
+			bparams->norm = VIDEO_MODE_PAL;
+		else
+			bparams->norm = VIDEO_MODE_SECAM;
+
 		bparams->input = zr->input;
 
 		bparams->decimation = fh->jpg_settings.decimation;
@@ -2352,7 +1586,6 @@ static long zoran_do_ioctl(struct file *
 
 		return 0;
 	}
-		break;
 
 	case BUZIOC_S_PARAMS:
 	{
@@ -2395,18 +1628,17 @@ static long zoran_do_ioctl(struct file *
 
 		/* Check the params first before overwriting our
 		 * nternal values */
-		if (zoran_check_jpg_settings(zr, &settings)) {
+		if (zoran_check_jpg_settings(zr, &settings, 0)) {
 			res = -EINVAL;
 			goto sparams_unlock_and_return;
 		}
 
 		fh->jpg_settings = settings;
-	sparams_unlock_and_return:
+sparams_unlock_and_return:
 		mutex_unlock(&zr->resource_lock);
 
 		return res;
 	}
-		break;
 
 	case BUZIOC_REQBUFS:
 	{
@@ -2430,38 +1662,34 @@ static long zoran_do_ioctl(struct file *
 		 * tables to a Maximum of 2 MB */
 		if (breq->size > jpg_bufsize)
 			breq->size = jpg_bufsize;
-		if (fh->jpg_buffers.need_contiguous &&
-		    breq->size > MAX_KMALLOC_MEM)
-			breq->size = MAX_KMALLOC_MEM;
 
 		mutex_lock(&zr->resource_lock);
 
-		if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
+		if (fh->buffers.allocated) {
 			dprintk(1,
 				KERN_ERR
-				"%s: BUZIOC_REQBUFS - buffers allready allocated\n",
+				"%s: BUZIOC_REQBUFS - buffers already allocated\n",
 				ZR_DEVNAME(zr));
 			res = -EBUSY;
 			goto jpgreqbuf_unlock_and_return;
 		}
 
-		fh->jpg_buffers.num_buffers = breq->count;
-		fh->jpg_buffers.buffer_size = breq->size;
+		/* The next mmap will map the MJPEG buffers - could
+		 * also be *_PLAY, but it doesn't matter here */
+		map_mode_jpg(fh, 0);
+		fh->buffers.num_buffers = breq->count;
+		fh->buffers.buffer_size = breq->size;
 
-		if (jpg_fbuffer_alloc(file)) {
+		if (jpg_fbuffer_alloc(fh)) {
 			res = -ENOMEM;
 			goto jpgreqbuf_unlock_and_return;
 		}
 
-		/* The next mmap will map the MJPEG buffers - could
-		 * also be *_PLAY, but it doesn't matter here */
-		fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
-	jpgreqbuf_unlock_and_return:
+jpgreqbuf_unlock_and_return:
 		mutex_unlock(&zr->resource_lock);
 
 		return res;
 	}
-		break;
 
 	case BUZIOC_QBUF_CAPT:
 	{
@@ -2471,12 +1699,11 @@ static long zoran_do_ioctl(struct file *
 			ZR_DEVNAME(zr), *frame);
 
 		mutex_lock(&zr->resource_lock);
-		res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
+		res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS);
 		mutex_unlock(&zr->resource_lock);
 
 		return res;
 	}
-		break;
 
 	case BUZIOC_QBUF_PLAY:
 	{
@@ -2486,12 +1713,11 @@ static long zoran_do_ioctl(struct file *
 			ZR_DEVNAME(zr), *frame);
 
 		mutex_lock(&zr->resource_lock);
-		res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
+		res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS);
 		mutex_unlock(&zr->resource_lock);
 
 		return res;
 	}
-		break;
 
 	case BUZIOC_SYNC:
 	{
@@ -2501,17 +1727,25 @@ static long zoran_do_ioctl(struct file *
 		dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
 
 		mutex_lock(&zr->resource_lock);
-		res = jpg_sync(file, bsync);
+
+		if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+			dprintk(2, KERN_WARNING
+				"%s: %s - not in jpg capture mode\n",
+				ZR_DEVNAME(zr), __func__);
+			res = -EINVAL;
+		} else {
+			res = jpg_sync(fh, bsync);
+		}
 		mutex_unlock(&zr->resource_lock);
 
 		return res;
 	}
-		break;
 
 	case BUZIOC_G_STATUS:
 	{
 		struct zoran_status *bstat = arg;
-		int norm, input, status, res = 0;
+		int status = 0, res = 0;
+		v4l2_std_id norm;
 
 		dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
 
@@ -2523,9 +1757,6 @@ static long zoran_do_ioctl(struct file *
 			return -EINVAL;
 		}
 
-		input = zr->card.input[bstat->input].muxsel;
-		norm = VIDEO_MODE_AUTO;
-
 		mutex_lock(&zr->resource_lock);
 
 		if (zr->codec_mode != BUZ_MODE_IDLE) {
@@ -2537,1629 +1768,1261 @@ static long zoran_do_ioctl(struct file *
 			goto gstat_unlock_and_return;
 		}
 
-		decoder_command(zr, DECODER_SET_INPUT, &input);
-		decoder_command(zr, DECODER_SET_NORM, &norm);
+		decoder_call(zr, video, s_routing,
+				zr->card.input[bstat->input].muxsel, 0, 0);
 
 		/* sleep 1 second */
 		ssleep(1);
 
 		/* Get status of video decoder */
-		decoder_command(zr, DECODER_GET_STATUS, &status);
+		decoder_call(zr, video, querystd, &norm);
+		decoder_call(zr, video, g_input_status, &status);
 
 		/* restore previous input and norm */
-		input = zr->card.input[zr->input].muxsel;
-		decoder_command(zr, DECODER_SET_INPUT, &input);
-		decoder_command(zr, DECODER_SET_NORM, &zr->norm);
-	gstat_unlock_and_return:
+		decoder_call(zr, video, s_routing,
+				zr->card.input[zr->input].muxsel, 0, 0);
+gstat_unlock_and_return:
 		mutex_unlock(&zr->resource_lock);
 
 		if (!res) {
 			bstat->signal =
-			    (status & DECODER_STATUS_GOOD) ? 1 : 0;
-			if (status & DECODER_STATUS_NTSC)
+			    (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
+			if (norm & V4L2_STD_NTSC)
 				bstat->norm = VIDEO_MODE_NTSC;
-			else if (status & DECODER_STATUS_SECAM)
+			else if (norm & V4L2_STD_SECAM)
 				bstat->norm = VIDEO_MODE_SECAM;
 			else
 				bstat->norm = VIDEO_MODE_PAL;
 
 			bstat->color =
-			    (status & DECODER_STATUS_COLOR) ? 1 : 0;
+			    (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
 		}
 
 		return res;
 	}
-		break;
 
-		/* The new video4linux2 capture interface - much nicer than video4linux1, since
-		 * it allows for integrating the JPEG capturing calls inside standard v4l2
-		 */
-
-	case VIDIOC_QUERYCAP:
-	{
-		struct v4l2_capability *cap = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
-
-		memset(cap, 0, sizeof(*cap));
-		strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
-		strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
-		snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
-			 pci_name(zr->pci_dev));
-		cap->version =
-		    KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
-				   RELEASE_VERSION);
-		cap->capabilities = ZORAN_V4L2_VID_FLAGS;
-
-		return 0;
+	default:
+		return -EINVAL;
 	}
-		break;
-
-	case VIDIOC_ENUM_FMT:
-	{
-		struct v4l2_fmtdesc *fmt = arg;
-		int index = fmt->index, num = -1, i, flag = 0, type =
-		    fmt->type;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n",
-			ZR_DEVNAME(zr), fmt->index);
+}
 
-		switch (fmt->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-			flag = ZORAN_FORMAT_CAPTURE;
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			flag = ZORAN_FORMAT_PLAYBACK;
-			break;
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			flag = ZORAN_FORMAT_OVERLAY;
-			break;
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_ENUM_FMT - unknown type %d\n",
-				ZR_DEVNAME(zr), fmt->type);
-			return -EINVAL;
-		}
+static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int i, res = 0;
 
-		for (i = 0; i < NUM_FORMATS; i++) {
-			if (zoran_formats[i].flags & flag)
-				num++;
-			if (num == fmt->index)
-				break;
-		}
-		if (fmt->index < 0 /* late, but not too late */  ||
-		    i == NUM_FORMATS)
-			return -EINVAL;
 
-		memset(fmt, 0, sizeof(*fmt));
-		fmt->index = index;
-		fmt->type = type;
-		strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
-		fmt->pixelformat = zoran_formats[i].fourcc;
-		if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
-			fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+	mutex_lock(&zr->resource_lock);
 
-		return 0;
+	if (fh->buffers.allocated) {
+		dprintk(1,
+			KERN_ERR
+			"%s: VIDIOCGMBUF - buffers already allocated\n",
+			ZR_DEVNAME(zr));
+		res = -EINVAL;
+		goto v4l1reqbuf_unlock_and_return;
 	}
-		break;
-
-	case VIDIOC_G_FMT:
-	{
-		struct v4l2_format *fmt = arg;
-		int type = fmt->type;
-
-		dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr));
-
-		memset(fmt, 0, sizeof(*fmt));
-		fmt->type = type;
-
-		switch (fmt->type) {
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-
-			mutex_lock(&zr->resource_lock);
-
-			fmt->fmt.win.w.left = fh->overlay_settings.x;
-			fmt->fmt.win.w.top = fh->overlay_settings.y;
-			fmt->fmt.win.w.width = fh->overlay_settings.width;
-			fmt->fmt.win.w.height =
-			    fh->overlay_settings.height;
-			if (fh->overlay_settings.width * 2 >
-			    BUZ_MAX_HEIGHT)
-				fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
-			else
-				fmt->fmt.win.field = V4L2_FIELD_TOP;
-
-			mutex_unlock(&zr->resource_lock);
 
-			break;
-
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
-			mutex_lock(&zr->resource_lock);
+	/* The next mmap will map the V4L buffers */
+	map_mode_raw(fh);
 
-			if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-			    fh->map_mode == ZORAN_MAP_MODE_RAW) {
+	if (v4l_fbuffer_alloc(fh)) {
+		res = -ENOMEM;
+		goto v4l1reqbuf_unlock_and_return;
+	}
 
-				fmt->fmt.pix.width =
-				    fh->v4l_settings.width;
-				fmt->fmt.pix.height =
-				    fh->v4l_settings.height;
-				fmt->fmt.pix.sizeimage =
-				    fh->v4l_settings.bytesperline *
-				    fh->v4l_settings.height;
-				fmt->fmt.pix.pixelformat =
-				    fh->v4l_settings.format->fourcc;
-				fmt->fmt.pix.colorspace =
-				    fh->v4l_settings.format->colorspace;
-				fmt->fmt.pix.bytesperline =
-				    fh->v4l_settings.bytesperline;
-				if (BUZ_MAX_HEIGHT <
-				    (fh->v4l_settings.height * 2))
-					fmt->fmt.pix.field =
-					    V4L2_FIELD_INTERLACED;
-				else
-					fmt->fmt.pix.field =
-					    V4L2_FIELD_TOP;
+	vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
+	vmbuf->frames = fh->buffers.num_buffers;
+	for (i = 0; i < vmbuf->frames; i++)
+		vmbuf->offsets[i] = i * fh->buffers.buffer_size;
 
-			} else {
+v4l1reqbuf_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-				fmt->fmt.pix.width =
-				    fh->jpg_settings.img_width /
-				    fh->jpg_settings.HorDcm;
-				fmt->fmt.pix.height =
-				    fh->jpg_settings.img_height /
-				    (fh->jpg_settings.VerDcm *
-				     fh->jpg_settings.TmpDcm);
-				fmt->fmt.pix.sizeimage =
-				    zoran_v4l2_calc_bufsize(&fh->
-							    jpg_settings);
-				fmt->fmt.pix.pixelformat =
-				    V4L2_PIX_FMT_MJPEG;
-				if (fh->jpg_settings.TmpDcm == 1)
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_SEQ_BT :
-					     V4L2_FIELD_SEQ_BT);
-				else
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_TOP :
-					     V4L2_FIELD_BOTTOM);
+	return res;
+}
+#endif
 
-				fmt->fmt.pix.bytesperline = 0;
-				fmt->fmt.pix.colorspace =
-				    V4L2_COLORSPACE_SMPTE170M;
-			}
+static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			mutex_unlock(&zr->resource_lock);
+	memset(cap, 0, sizeof(*cap));
+	strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
+	strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
+		 pci_name(zr->pci_dev));
+	cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
+			   RELEASE_VERSION);
+	cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
+			    V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY;
+	return 0;
+}
 
-			break;
+static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
+{
+	unsigned int num, i;
 
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_G_FMT - unsupported type %d\n",
-				ZR_DEVNAME(zr), fmt->type);
-			return -EINVAL;
+	for (num = i = 0; i < NUM_FORMATS; i++) {
+		if (zoran_formats[i].flags & flag && num++ == fmt->index) {
+			strncpy(fmt->description, zoran_formats[i].name,
+				sizeof(fmt->description) - 1);
+			/* fmt struct pre-zeroed, so adding '\0' not neeed */
+			fmt->pixelformat = zoran_formats[i].fourcc;
+			if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
+				fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+			return 0;
 		}
-		return 0;
 	}
-		break;
+	return -EINVAL;
+}
 
-	case VIDIOC_S_FMT:
-	{
-		struct v4l2_format *fmt = arg;
-		int i, res = 0;
-		__le32 printformat;
+static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
+					    struct v4l2_fmtdesc *f)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
-			ZR_DEVNAME(zr), fmt->type);
+	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
+}
 
-		switch (fmt->type) {
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
+					    struct v4l2_fmtdesc *f)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
-				fmt->fmt.win.w.left, fmt->fmt.win.w.top,
-				fmt->fmt.win.w.width,
-				fmt->fmt.win.w.height,
-				fmt->fmt.win.clipcount,
-				fmt->fmt.win.bitmap);
-			mutex_lock(&zr->resource_lock);
-			res =
-			    setup_window(file, fmt->fmt.win.w.left,
-					 fmt->fmt.win.w.top,
-					 fmt->fmt.win.w.width,
-					 fmt->fmt.win.w.height,
-					 (struct video_clip __user *)
-					   fmt->fmt.win.clips,
-					 fmt->fmt.win.clipcount,
-					 fmt->fmt.win.bitmap);
-			mutex_unlock(&zr->resource_lock);
-			return res;
-			break;
+	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
+}
 
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
+					    struct v4l2_fmtdesc *f)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			printformat =
-			    __cpu_to_le32(fmt->fmt.pix.pixelformat);
-			dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
-				fmt->fmt.pix.width, fmt->fmt.pix.height,
-				fmt->fmt.pix.pixelformat,
-				(char *) &printformat);
+	return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
+}
 
-			/* we can be requested to do JPEG/raw playback/capture */
-			if (!
-			    (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-			     (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-			      fmt->fmt.pix.pixelformat ==
-			      V4L2_PIX_FMT_MJPEG))) {
-				dprintk(1,
-					KERN_ERR
-					"%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
-					ZR_DEVNAME(zr), fmt->type,
-					fmt->fmt.pix.pixelformat,
-					(char *) &printformat);
-				return -EINVAL;
-			}
+static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
-				mutex_lock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-				settings = fh->jpg_settings;
+	fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
+	fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 /
+		(fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
+	fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+	fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
+	if (fh->jpg_settings.TmpDcm == 1)
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+	else
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+	fmt->fmt.pix.bytesperline = 0;
+	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
-				if (fh->v4l_buffers.allocated ||
-				    fh->jpg_buffers.allocated) {
-					dprintk(1,
-						KERN_ERR
-						"%s: VIDIOC_S_FMT - cannot change capture mode\n",
-						ZR_DEVNAME(zr));
-					res = -EBUSY;
-					goto sfmtjpg_unlock_and_return;
-				}
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-				/* we actually need to set 'real' parameters now */
-				if ((fmt->fmt.pix.height * 2) >
-				    BUZ_MAX_HEIGHT)
-					settings.TmpDcm = 1;
-				else
-					settings.TmpDcm = 2;
-				settings.decimation = 0;
-				if (fmt->fmt.pix.height <=
-				    fh->jpg_settings.img_height / 2)
-					settings.VerDcm = 2;
-				else
-					settings.VerDcm = 1;
-				if (fmt->fmt.pix.width <=
-				    fh->jpg_settings.img_width / 4)
-					settings.HorDcm = 4;
-				else if (fmt->fmt.pix.width <=
-					 fh->jpg_settings.img_width / 2)
-					settings.HorDcm = 2;
-				else
-					settings.HorDcm = 1;
-				if (settings.TmpDcm == 1)
-					settings.field_per_buff = 2;
-				else
-					settings.field_per_buff = 1;
+static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-				/* check */
-				if ((res =
-				     zoran_check_jpg_settings(zr,
-							      &settings)))
-					goto sfmtjpg_unlock_and_return;
+	if (fh->map_mode != ZORAN_MAP_MODE_RAW)
+		return zoran_g_fmt_vid_out(file, fh, fmt);
 
-				/* it's ok, so set them */
-				fh->jpg_settings = settings;
+	mutex_lock(&zr->resource_lock);
+	fmt->fmt.pix.width = fh->v4l_settings.width;
+	fmt->fmt.pix.height = fh->v4l_settings.height;
+	fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
+					fh->v4l_settings.height;
+	fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
+	fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+	fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+	if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+		fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+	else
+		fmt->fmt.pix.field = V4L2_FIELD_TOP;
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-				/* tell the user what we actually did */
-				fmt->fmt.pix.width =
-				    settings.img_width / settings.HorDcm;
-				fmt->fmt.pix.height =
-				    settings.img_height * 2 /
-				    (settings.TmpDcm * settings.VerDcm);
-				if (settings.TmpDcm == 1)
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_SEQ_TB :
-					     V4L2_FIELD_SEQ_BT);
-				else
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_TOP :
-					     V4L2_FIELD_BOTTOM);
-				fh->jpg_buffers.buffer_size =
-				    zoran_v4l2_calc_bufsize(&fh->
-							    jpg_settings);
-				fmt->fmt.pix.bytesperline = 0;
-				fmt->fmt.pix.sizeimage =
-				    fh->jpg_buffers.buffer_size;
-				fmt->fmt.pix.colorspace =
-				    V4L2_COLORSPACE_SMPTE170M;
+static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-				/* we hereby abuse this variable to show that
-				 * we're gonna do mjpeg capture */
-				fh->map_mode =
-				    (fmt->type ==
-				     V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
-				    ZORAN_MAP_MODE_JPG_REC :
-				    ZORAN_MAP_MODE_JPG_PLAY;
-			sfmtjpg_unlock_and_return:
-				mutex_unlock(&zr->resource_lock);
-			} else {
-				for (i = 0; i < NUM_FORMATS; i++)
-					if (fmt->fmt.pix.pixelformat ==
-					    zoran_formats[i].fourcc)
-						break;
-				if (i == NUM_FORMATS) {
-					dprintk(1,
-						KERN_ERR
-						"%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
-						ZR_DEVNAME(zr),
-						fmt->fmt.pix.pixelformat,
-						(char *) &printformat);
-					return -EINVAL;
-				}
-				mutex_lock(&zr->resource_lock);
-				if (fh->jpg_buffers.allocated ||
-				    (fh->v4l_buffers.allocated &&
-				     fh->v4l_buffers.active !=
-				     ZORAN_FREE)) {
-					dprintk(1,
-						KERN_ERR
-						"%s: VIDIOC_S_FMT - cannot change capture mode\n",
-						ZR_DEVNAME(zr));
-					res = -EBUSY;
-					goto sfmtv4l_unlock_and_return;
-				}
-				if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
-					fmt->fmt.pix.height =
-					    BUZ_MAX_HEIGHT;
-				if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
-					fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+	mutex_lock(&zr->resource_lock);
 
-				if ((res =
-				     zoran_v4l_set_format(file,
-							  fmt->fmt.pix.
-							  width,
-							  fmt->fmt.pix.
-							  height,
-							  &zoran_formats
-							  [i])))
-					goto sfmtv4l_unlock_and_return;
+	fmt->fmt.win.w.left = fh->overlay_settings.x;
+	fmt->fmt.win.w.top = fh->overlay_settings.y;
+	fmt->fmt.win.w.width = fh->overlay_settings.width;
+	fmt->fmt.win.w.height = fh->overlay_settings.height;
+	if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
+		fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
+	else
+		fmt->fmt.win.field = V4L2_FIELD_TOP;
 
-				/* tell the user the
-				 * results/missing stuff */
-				fmt->fmt.pix.bytesperline =
-					fh->v4l_settings.bytesperline;
-				fmt->fmt.pix.sizeimage =
-					fh->v4l_settings.height *
-					fh->v4l_settings.bytesperline;
-				fmt->fmt.pix.colorspace =
-					fh->v4l_settings.format->colorspace;
-				if (BUZ_MAX_HEIGHT <
-				    (fh->v4l_settings.height * 2))
-					fmt->fmt.pix.field =
-					    V4L2_FIELD_INTERLACED;
-				else
-					fmt->fmt.pix.field =
-					    V4L2_FIELD_TOP;
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-				fh->map_mode = ZORAN_MAP_MODE_RAW;
-			sfmtv4l_unlock_and_return:
-				mutex_unlock(&zr->resource_lock);
-			}
+static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			break;
+	mutex_lock(&zr->resource_lock);
 
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_S_FMT - unsupported type %d\n",
-				ZR_DEVNAME(zr), fmt->type);
-			return -EINVAL;
-		}
+	if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
+		fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
+	if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
+		fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
+	if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
+		fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
+	if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
+		fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
 
-		return res;
-	}
-		break;
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-	case VIDIOC_G_FBUF:
-	{
-		struct v4l2_framebuffer *fb = arg;
+static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	struct zoran_jpg_settings settings;
+	int res = 0;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr));
+	if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+		return -EINVAL;
 
-		memset(fb, 0, sizeof(*fb));
-		mutex_lock(&zr->resource_lock);
-		fb->base = zr->buffer.base;
-		fb->fmt.width = zr->buffer.width;
-		fb->fmt.height = zr->buffer.height;
-		if (zr->overlay_settings.format) {
-			fb->fmt.pixelformat =
-				fh->overlay_settings.format->fourcc;
-		}
-		fb->fmt.bytesperline = zr->buffer.bytesperline;
-		mutex_unlock(&zr->resource_lock);
-		fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
-		fb->fmt.field = V4L2_FIELD_INTERLACED;
-		fb->flags = V4L2_FBUF_FLAG_OVERLAY;
-		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+	mutex_lock(&zr->resource_lock);
+	settings = fh->jpg_settings;
 
-		return 0;
+	/* we actually need to set 'real' parameters now */
+	if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
+		settings.TmpDcm = 1;
+	else
+		settings.TmpDcm = 2;
+	settings.decimation = 0;
+	if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+		settings.VerDcm = 2;
+	else
+		settings.VerDcm = 1;
+	if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+		settings.HorDcm = 4;
+	else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+		settings.HorDcm = 2;
+	else
+		settings.HorDcm = 1;
+	if (settings.TmpDcm == 1)
+		settings.field_per_buff = 2;
+	else
+		settings.field_per_buff = 1;
+
+	if (settings.HorDcm > 1) {
+		settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+		settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+	} else {
+		settings.img_x = 0;
+		settings.img_width = BUZ_MAX_WIDTH;
 	}
-		break;
 
-	case VIDIOC_S_FBUF:
-	{
-		int i, res = 0;
-		struct v4l2_framebuffer *fb = arg;
-		__le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
+	/* check */
+	res = zoran_check_jpg_settings(zr, &settings, 1);
+	if (res)
+		goto tryfmt_unlock_and_return;
 
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n",
-			ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height,
-			fb->fmt.bytesperline, fb->fmt.pixelformat,
-			(char *) &printformat);
+	/* tell the user what we actually did */
+	fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+	fmt->fmt.pix.height = settings.img_height * 2 /
+		(settings.TmpDcm * settings.VerDcm);
+	if (settings.TmpDcm == 1)
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+	else
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
 
-		for (i = 0; i < NUM_FORMATS; i++)
-			if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
-				break;
-		if (i == NUM_FORMATS) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
-				ZR_DEVNAME(zr), fb->fmt.pixelformat,
-				(char *) &printformat);
-			return -EINVAL;
-		}
+	fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
+	fmt->fmt.pix.bytesperline = 0;
+	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+tryfmt_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		mutex_lock(&zr->resource_lock);
-		res =
-		    setup_fbuffer(file, fb->base, &zoran_formats[i],
-				  fb->fmt.width, fb->fmt.height,
-				  fb->fmt.bytesperline);
-		mutex_unlock(&zr->resource_lock);
+static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int bpp;
+	int i;
 
-		return res;
-	}
-		break;
+	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+		return zoran_try_fmt_vid_out(file, fh, fmt);
 
-	case VIDIOC_OVERLAY:
-	{
-		int *on = arg, res;
+	mutex_lock(&zr->resource_lock);
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n",
-			ZR_DEVNAME(zr), *on);
+	for (i = 0; i < NUM_FORMATS; i++)
+		if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
+			break;
 
-		mutex_lock(&zr->resource_lock);
-		res = setup_overlay(file, *on);
+	if (i == NUM_FORMATS) {
 		mutex_unlock(&zr->resource_lock);
-
-		return res;
+		return -EINVAL;
 	}
-		break;
-
-	case VIDIOC_REQBUFS:
-	{
-		struct v4l2_requestbuffers *req = arg;
-		int res = 0;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
-			ZR_DEVNAME(zr), req->type);
-
-		if (req->memory != V4L2_MEMORY_MMAP) {
-			dprintk(1,
-				KERN_ERR
-				"%s: only MEMORY_MMAP capture is supported, not %d\n",
-				ZR_DEVNAME(zr), req->memory);
-			return -EINVAL;
-		}
 
-		mutex_lock(&zr->resource_lock);
-
-		if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_REQBUFS - buffers allready allocated\n",
-				ZR_DEVNAME(zr));
-			res = -EBUSY;
-			goto v4l2reqbuf_unlock_and_return;
-		}
-
-		if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
-		    req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-
-			/* control user input */
-			if (req->count < 2)
-				req->count = 2;
-			if (req->count > v4l_nbufs)
-				req->count = v4l_nbufs;
-			fh->v4l_buffers.num_buffers = req->count;
-
-			if (v4l_fbuffer_alloc(file)) {
-				res = -ENOMEM;
-				goto v4l2reqbuf_unlock_and_return;
-			}
+	bpp = (zoran_formats[i].depth + 7) / 8;
+	fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
+	if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+		fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+	if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
+		fmt->fmt.pix.width = BUZ_MIN_WIDTH;
+	if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+		fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+	if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
+		fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
+	mutex_unlock(&zr->resource_lock);
 
-			/* The next mmap will map the V4L buffers */
-			fh->map_mode = ZORAN_MAP_MODE_RAW;
+	return 0;
+}
 
-		} else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
-			   fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res;
 
-			/* we need to calculate size ourselves now */
-			if (req->count < 4)
-				req->count = 4;
-			if (req->count > jpg_nbufs)
-				req->count = jpg_nbufs;
-			fh->jpg_buffers.num_buffers = req->count;
-			fh->jpg_buffers.buffer_size =
-			    zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+	dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
+			fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+			fmt->fmt.win.w.width,
+			fmt->fmt.win.w.height,
+			fmt->fmt.win.clipcount,
+			fmt->fmt.win.bitmap);
+	mutex_lock(&zr->resource_lock);
+	res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+			   fmt->fmt.win.w.width, fmt->fmt.win.w.height,
+			   (struct v4l2_clip __user *)fmt->fmt.win.clips,
+			   fmt->fmt.win.clipcount, fmt->fmt.win.bitmap);
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-			if (jpg_fbuffer_alloc(file)) {
-				res = -ENOMEM;
-				goto v4l2reqbuf_unlock_and_return;
-			}
+static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	__le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
+	struct zoran_jpg_settings settings;
+	int res = 0;
 
-			/* The next mmap will map the MJPEG buffers */
-			if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-				fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
-			else
-				fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
+	dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
+			fmt->fmt.pix.width, fmt->fmt.pix.height,
+			fmt->fmt.pix.pixelformat,
+			(char *) &printformat);
+	if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+		return -EINVAL;
 
-		} else {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_REQBUFS - unknown type %d\n",
-				ZR_DEVNAME(zr), req->type);
-			res = -EINVAL;
-			goto v4l2reqbuf_unlock_and_return;
-		}
-	v4l2reqbuf_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-		return 0;
+	if (fh->buffers.allocated) {
+		dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+			ZR_DEVNAME(zr));
+		res = -EBUSY;
+		goto sfmtjpg_unlock_and_return;
 	}
-		break;
-
-	case VIDIOC_QUERYBUF:
-	{
-		struct v4l2_buffer *buf = arg;
-		__u32 type = buf->type;
-		int index = buf->index, res;
-
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
-			ZR_DEVNAME(zr), buf->index, buf->type);
 
-		memset(buf, 0, sizeof(*buf));
-		buf->type = type;
-		buf->index = index;
+	settings = fh->jpg_settings;
 
-		mutex_lock(&zr->resource_lock);
-		res = zoran_v4l2_buffer_status(file, buf, buf->index);
-		mutex_unlock(&zr->resource_lock);
+	/* we actually need to set 'real' parameters now */
+	if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
+		settings.TmpDcm = 1;
+	else
+		settings.TmpDcm = 2;
+	settings.decimation = 0;
+	if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+		settings.VerDcm = 2;
+	else
+		settings.VerDcm = 1;
+	if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+		settings.HorDcm = 4;
+	else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+		settings.HorDcm = 2;
+	else
+		settings.HorDcm = 1;
+	if (settings.TmpDcm == 1)
+		settings.field_per_buff = 2;
+	else
+		settings.field_per_buff = 1;
 
-		return res;
+	if (settings.HorDcm > 1) {
+		settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+		settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+	} else {
+		settings.img_x = 0;
+		settings.img_width = BUZ_MAX_WIDTH;
 	}
-		break;
 
-	case VIDIOC_QBUF:
-	{
-		struct v4l2_buffer *buf = arg;
-		int res = 0, codec_mode, buf_type;
+	/* check */
+	res = zoran_check_jpg_settings(zr, &settings, 0);
+	if (res)
+		goto sfmtjpg_unlock_and_return;
 
-		dprintk(3,
-			KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n",
-			ZR_DEVNAME(zr), buf->type, buf->index);
+	/* it's ok, so set them */
+	fh->jpg_settings = settings;
 
-		mutex_lock(&zr->resource_lock);
+	map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
 
-		switch (fh->map_mode) {
-		case ZORAN_MAP_MODE_RAW:
-			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-				dprintk(1,
-					KERN_ERR
-					"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
-					ZR_DEVNAME(zr), buf->type, fh->map_mode);
-				res = -EINVAL;
-				goto qbuf_unlock_and_return;
-			}
+	/* tell the user what we actually did */
+	fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+	fmt->fmt.pix.height = settings.img_height * 2 /
+		(settings.TmpDcm * settings.VerDcm);
+	if (settings.TmpDcm == 1)
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+	else
+		fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+				V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+	fmt->fmt.pix.bytesperline = 0;
+	fmt->fmt.pix.sizeimage = fh->buffers.buffer_size;
+	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
-			res = zoran_v4l_queue_frame(file, buf->index);
-			if (res)
-				goto qbuf_unlock_and_return;
-			if (!zr->v4l_memgrab_active &&
-			    fh->v4l_buffers.active == ZORAN_LOCKED)
-				zr36057_set_memgrab(zr, 1);
-			break;
+sfmtjpg_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		case ZORAN_MAP_MODE_JPG_REC:
-		case ZORAN_MAP_MODE_JPG_PLAY:
-			if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
-				buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-				codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
-			} else {
-				buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-				codec_mode = BUZ_MODE_MOTION_COMPRESS;
-			}
+static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
+					struct v4l2_format *fmt)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int i;
+	int res = 0;
 
-			if (buf->type != buf_type) {
-				dprintk(1,
-					KERN_ERR
-					"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
-					ZR_DEVNAME(zr), buf->type, fh->map_mode);
-				res = -EINVAL;
-				goto qbuf_unlock_and_return;
-			}
+	if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+		return zoran_s_fmt_vid_out(file, fh, fmt);
 
-			res =
-			    zoran_jpg_queue_frame(file, buf->index,
-						  codec_mode);
-			if (res != 0)
-				goto qbuf_unlock_and_return;
-			if (zr->codec_mode == BUZ_MODE_IDLE &&
-			    fh->jpg_buffers.active == ZORAN_LOCKED) {
-				zr36057_enable_jpg(zr, codec_mode);
-			}
+	for (i = 0; i < NUM_FORMATS; i++)
+		if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
 			break;
+	if (i == NUM_FORMATS) {
+		dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
+			ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
+		return -EINVAL;
+	}
 
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_QBUF - unsupported type %d\n",
-				ZR_DEVNAME(zr), buf->type);
-			res = -EINVAL;
-			goto qbuf_unlock_and_return;
-		}
-	qbuf_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-		return res;
+	if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) ||
+	    fh->buffers.active != ZORAN_FREE) {
+		dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+				ZR_DEVNAME(zr));
+		res = -EBUSY;
+		goto sfmtv4l_unlock_and_return;
 	}
-		break;
-
-	case VIDIOC_DQBUF:
-	{
-		struct v4l2_buffer *buf = arg;
-		int res = 0, buf_type, num = -1;	/* compiler borks here (?) */
+	if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+		fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+	if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+		fmt->fmt.pix.width = BUZ_MAX_WIDTH;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
-			ZR_DEVNAME(zr), buf->type);
+	map_mode_raw(fh);
 
-		mutex_lock(&zr->resource_lock);
+	res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height,
+				   &zoran_formats[i]);
+	if (res)
+		goto sfmtv4l_unlock_and_return;
 
-		switch (fh->map_mode) {
-		case ZORAN_MAP_MODE_RAW:
-			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-				dprintk(1,
-					KERN_ERR
-					"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
-					ZR_DEVNAME(zr), buf->type, fh->map_mode);
-				res = -EINVAL;
-				goto dqbuf_unlock_and_return;
-			}
+	/* tell the user the results/missing stuff */
+	fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+	fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
+	fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+	if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+		fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+	else
+		fmt->fmt.pix.field = V4L2_FIELD_TOP;
 
-			num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
-			if (file->f_flags & O_NONBLOCK &&
-			    zr->v4l_buffers.buffer[num].state !=
-			    BUZ_STATE_DONE) {
-				res = -EAGAIN;
-				goto dqbuf_unlock_and_return;
-			}
-			res = v4l_sync(file, num);
-			if (res)
-				goto dqbuf_unlock_and_return;
-			else
-				zr->v4l_sync_tail++;
-			res = zoran_v4l2_buffer_status(file, buf, num);
-			break;
+sfmtv4l_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		case ZORAN_MAP_MODE_JPG_REC:
-		case ZORAN_MAP_MODE_JPG_PLAY:
-		{
-			struct zoran_sync bs;
+static int zoran_g_fbuf(struct file *file, void *__fh,
+		struct v4l2_framebuffer *fb)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-			if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
-				buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-			else
-				buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	memset(fb, 0, sizeof(*fb));
+	mutex_lock(&zr->resource_lock);
+	fb->base = zr->vbuf_base;
+	fb->fmt.width = zr->vbuf_width;
+	fb->fmt.height = zr->vbuf_height;
+	if (zr->overlay_settings.format)
+		fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
+	fb->fmt.bytesperline = zr->vbuf_bytesperline;
+	mutex_unlock(&zr->resource_lock);
+	fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+	fb->fmt.field = V4L2_FIELD_INTERLACED;
+	fb->flags = V4L2_FBUF_FLAG_OVERLAY;
+	fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
 
-			if (buf->type != buf_type) {
-				dprintk(1,
-					KERN_ERR
-					"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
-					ZR_DEVNAME(zr), buf->type, fh->map_mode);
-				res = -EINVAL;
-				goto dqbuf_unlock_and_return;
-			}
+	return 0;
+}
 
-			num =
-			    zr->jpg_pend[zr->
-					 jpg_que_tail & BUZ_MASK_FRAME];
+static int zoran_s_fbuf(struct file *file, void *__fh,
+		struct v4l2_framebuffer *fb)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int i, res = 0;
+	__le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
 
-			if (file->f_flags & O_NONBLOCK &&
-			    zr->jpg_buffers.buffer[num].state !=
-			    BUZ_STATE_DONE) {
-				res = -EAGAIN;
-				goto dqbuf_unlock_and_return;
-			}
-			res = jpg_sync(file, &bs);
-			if (res)
-				goto dqbuf_unlock_and_return;
-			res =
-			    zoran_v4l2_buffer_status(file, buf, bs.frame);
+	for (i = 0; i < NUM_FORMATS; i++)
+		if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
 			break;
-		}
-
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_DQBUF - unsupported type %d\n",
-				ZR_DEVNAME(zr), buf->type);
-			res = -EINVAL;
-			goto dqbuf_unlock_and_return;
-		}
-	dqbuf_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
+	if (i == NUM_FORMATS) {
+		dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
+			ZR_DEVNAME(zr), fb->fmt.pixelformat,
+			(char *)&printformat);
+		return -EINVAL;
 	}
-		break;
 
-	case VIDIOC_STREAMON:
-	{
-		int res = 0;
+	mutex_lock(&zr->resource_lock);
+	res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width,
+			    fb->fmt.height, fb->fmt.bytesperline);
+	mutex_unlock(&zr->resource_lock);
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
+	return res;
+}
 
-		mutex_lock(&zr->resource_lock);
+static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res;
 
-		switch (fh->map_mode) {
-		case ZORAN_MAP_MODE_RAW:	/* raw capture */
-			if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
-			    fh->v4l_buffers.active != ZORAN_ACTIVE) {
-				res = -EBUSY;
-				goto strmon_unlock_and_return;
-			}
+	mutex_lock(&zr->resource_lock);
+	res = setup_overlay(fh, on);
+	mutex_unlock(&zr->resource_lock);
 
-			zr->v4l_buffers.active = fh->v4l_buffers.active =
-			    ZORAN_LOCKED;
-			zr->v4l_settings = fh->v4l_settings;
+	return res;
+}
 
-			zr->v4l_sync_tail = zr->v4l_pend_tail;
-			if (!zr->v4l_memgrab_active &&
-			    zr->v4l_pend_head != zr->v4l_pend_tail) {
-				zr36057_set_memgrab(zr, 1);
-			}
-			break;
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type);
 
-		case ZORAN_MAP_MODE_JPG_REC:
-		case ZORAN_MAP_MODE_JPG_PLAY:
-			/* what is the codec mode right now? */
-			if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
-			    fh->jpg_buffers.active != ZORAN_ACTIVE) {
-				res = -EBUSY;
-				goto strmon_unlock_and_return;
-			}
+static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0;
 
-			zr->jpg_buffers.active = fh->jpg_buffers.active =
-			    ZORAN_LOCKED;
+	if (req->memory != V4L2_MEMORY_MMAP) {
+		dprintk(2,
+				KERN_ERR
+				"%s: only MEMORY_MMAP capture is supported, not %d\n",
+				ZR_DEVNAME(zr), req->memory);
+		return -EINVAL;
+	}
 
-			if (zr->jpg_que_head != zr->jpg_que_tail) {
-				/* Start the jpeg codec when the first frame is queued  */
-				jpeg_start(zr);
-			}
+	if (req->count == 0)
+		return zoran_streamoff(file, fh, req->type);
 
-			break;
-		default:
-			dprintk(1,
+	mutex_lock(&zr->resource_lock);
+	if (fh->buffers.allocated) {
+		dprintk(2,
 				KERN_ERR
-				"%s: VIDIOC_STREAMON - invalid map mode %d\n",
-				ZR_DEVNAME(zr), fh->map_mode);
-			res = -EINVAL;
-			goto strmon_unlock_and_return;
-		}
-	strmon_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-
-		return res;
+				"%s: VIDIOC_REQBUFS - buffers already allocated\n",
+				ZR_DEVNAME(zr));
+		res = -EBUSY;
+		goto v4l2reqbuf_unlock_and_return;
 	}
-		break;
 
-	case VIDIOC_STREAMOFF:
-	{
-		int i, res = 0;
+	if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
+	    req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		/* control user input */
+		if (req->count < 2)
+			req->count = 2;
+		if (req->count > v4l_nbufs)
+			req->count = v4l_nbufs;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
+		/* The next mmap will map the V4L buffers */
+		map_mode_raw(fh);
+		fh->buffers.num_buffers = req->count;
 
-		mutex_lock(&zr->resource_lock);
+		if (v4l_fbuffer_alloc(fh)) {
+			res = -ENOMEM;
+			goto v4l2reqbuf_unlock_and_return;
+		}
+	} else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
+		   fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+		/* we need to calculate size ourselves now */
+		if (req->count < 4)
+			req->count = 4;
+		if (req->count > jpg_nbufs)
+			req->count = jpg_nbufs;
 
-		switch (fh->map_mode) {
-		case ZORAN_MAP_MODE_RAW:	/* raw capture */
-			if (fh->v4l_buffers.active == ZORAN_FREE &&
-			    zr->v4l_buffers.active != ZORAN_FREE) {
-				res = -EPERM;	/* stay off other's settings! */
-				goto strmoff_unlock_and_return;
-			}
-			if (zr->v4l_buffers.active == ZORAN_FREE)
-				goto strmoff_unlock_and_return;
+		/* The next mmap will map the MJPEG buffers */
+		map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		fh->buffers.num_buffers = req->count;
+		fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
 
-			/* unload capture */
-			if (zr->v4l_memgrab_active) {
-				unsigned long flags;
+		if (jpg_fbuffer_alloc(fh)) {
+			res = -ENOMEM;
+			goto v4l2reqbuf_unlock_and_return;
+		}
+	} else {
+		dprintk(1,
+				KERN_ERR
+				"%s: VIDIOC_REQBUFS - unknown type %d\n",
+				ZR_DEVNAME(zr), req->type);
+		res = -EINVAL;
+		goto v4l2reqbuf_unlock_and_return;
+	}
+v4l2reqbuf_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-				spin_lock_irqsave(&zr->spinlock, flags);
-				zr36057_set_memgrab(zr, 0);
-				spin_unlock_irqrestore(&zr->spinlock, flags);
-			}
+	return res;
+}
 
-			for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
-				zr->v4l_buffers.buffer[i].state =
-				    BUZ_STATE_USER;
-			fh->v4l_buffers = zr->v4l_buffers;
+static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res;
 
-			zr->v4l_buffers.active = fh->v4l_buffers.active =
-			    ZORAN_FREE;
+	mutex_lock(&zr->resource_lock);
+	res = zoran_v4l2_buffer_status(fh, buf, buf->index);
+	mutex_unlock(&zr->resource_lock);
 
-			zr->v4l_grab_seq = 0;
-			zr->v4l_pend_head = zr->v4l_pend_tail = 0;
-			zr->v4l_sync_tail = 0;
+	return res;
+}
 
-			break;
+static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0, codec_mode, buf_type;
 
-		case ZORAN_MAP_MODE_JPG_REC:
-		case ZORAN_MAP_MODE_JPG_PLAY:
-			if (fh->jpg_buffers.active == ZORAN_FREE &&
-			    zr->jpg_buffers.active != ZORAN_FREE) {
-				res = -EPERM;	/* stay off other's settings! */
-				goto strmoff_unlock_and_return;
-			}
-			if (zr->jpg_buffers.active == ZORAN_FREE)
-				goto strmoff_unlock_and_return;
+	mutex_lock(&zr->resource_lock);
 
-			res =
-			    jpg_qbuf(file, -1,
-				     (fh->map_mode ==
-				      ZORAN_MAP_MODE_JPG_REC) ?
-				     BUZ_MODE_MOTION_COMPRESS :
-				     BUZ_MODE_MOTION_DECOMPRESS);
-			if (res)
-				goto strmoff_unlock_and_return;
-			break;
-		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
-				ZR_DEVNAME(zr), fh->map_mode);
+	switch (fh->map_mode) {
+	case ZORAN_MAP_MODE_RAW:
+		if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+			dprintk(1, KERN_ERR
+				"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+				ZR_DEVNAME(zr), buf->type, fh->map_mode);
 			res = -EINVAL;
-			goto strmoff_unlock_and_return;
+			goto qbuf_unlock_and_return;
 		}
-	strmoff_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
 
-		return res;
-	}
+		res = zoran_v4l_queue_frame(fh, buf->index);
+		if (res)
+			goto qbuf_unlock_and_return;
+		if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED)
+			zr36057_set_memgrab(zr, 1);
 		break;
 
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n",
-			ZR_DEVNAME(zr), ctrl->id);
-
-		/* we only support hue/saturation/contrast/brightness */
-		if (ctrl->id < V4L2_CID_BRIGHTNESS ||
-		    ctrl->id > V4L2_CID_HUE)
-			return -EINVAL;
-		else {
-			int id = ctrl->id;
-			memset(ctrl, 0, sizeof(*ctrl));
-			ctrl->id = id;
+	case ZORAN_MAP_MODE_JPG_REC:
+	case ZORAN_MAP_MODE_JPG_PLAY:
+		if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+			buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+			codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
+		} else {
+			buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+			codec_mode = BUZ_MODE_MOTION_COMPRESS;
 		}
 
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
-			break;
-		case V4L2_CID_CONTRAST:
-			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
-			break;
-		case V4L2_CID_SATURATION:
-			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
-			break;
-		case V4L2_CID_HUE:
-			strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
-			break;
+		if (buf->type != buf_type) {
+			dprintk(1, KERN_ERR
+				"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+				ZR_DEVNAME(zr), buf->type, fh->map_mode);
+			res = -EINVAL;
+			goto qbuf_unlock_and_return;
 		}
 
-		ctrl->minimum = 0;
-		ctrl->maximum = 65535;
-		ctrl->step = 1;
-		ctrl->default_value = 32768;
-		ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+		res = zoran_jpg_queue_frame(fh, buf->index, codec_mode);
+		if (res != 0)
+			goto qbuf_unlock_and_return;
+		if (zr->codec_mode == BUZ_MODE_IDLE &&
+		    fh->buffers.active == ZORAN_LOCKED)
+			zr36057_enable_jpg(zr, codec_mode);
 
-		return 0;
-	}
 		break;
 
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
-			ZR_DEVNAME(zr), ctrl->id);
-
-		/* we only support hue/saturation/contrast/brightness */
-		if (ctrl->id < V4L2_CID_BRIGHTNESS ||
-		    ctrl->id > V4L2_CID_HUE)
-			return -EINVAL;
-
-		mutex_lock(&zr->resource_lock);
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = zr->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = zr->contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->value = zr->saturation;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->value = zr->hue;
-			break;
-		}
-		mutex_unlock(&zr->resource_lock);
-
-		return 0;
-	}
+	default:
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_QBUF - unsupported type %d\n",
+			ZR_DEVNAME(zr), buf->type);
+		res = -EINVAL;
 		break;
+	}
+qbuf_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-		struct video_picture pict;
+	return res;
+}
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n",
-			ZR_DEVNAME(zr), ctrl->id);
+static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0, buf_type, num = -1;	/* compiler borks here (?) */
 
-		/* we only support hue/saturation/contrast/brightness */
-		if (ctrl->id < V4L2_CID_BRIGHTNESS ||
-		    ctrl->id > V4L2_CID_HUE)
-			return -EINVAL;
+	mutex_lock(&zr->resource_lock);
 
-		if (ctrl->value < 0 || ctrl->value > 65535) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
-				ZR_DEVNAME(zr), ctrl->value, ctrl->id);
-			return -EINVAL;
+	switch (fh->map_mode) {
+	case ZORAN_MAP_MODE_RAW:
+		if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+			dprintk(1, KERN_ERR
+				"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+				ZR_DEVNAME(zr), buf->type, fh->map_mode);
+			res = -EINVAL;
+			goto dqbuf_unlock_and_return;
 		}
 
-		mutex_lock(&zr->resource_lock);
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			zr->brightness = ctrl->value;
-			break;
-		case V4L2_CID_CONTRAST:
-			zr->contrast = ctrl->value;
-			break;
-		case V4L2_CID_SATURATION:
-			zr->saturation = ctrl->value;
-			break;
-		case V4L2_CID_HUE:
-			zr->hue = ctrl->value;
-			break;
+		num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
+		if (file->f_flags & O_NONBLOCK &&
+		    zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
+			res = -EAGAIN;
+			goto dqbuf_unlock_and_return;
 		}
-		pict.brightness = zr->brightness;
-		pict.contrast = zr->contrast;
-		pict.colour = zr->saturation;
-		pict.hue = zr->hue;
-
-		decoder_command(zr, DECODER_SET_PICTURE, &pict);
-
-		mutex_unlock(&zr->resource_lock);
-
-		return 0;
-	}
+		res = v4l_sync(fh, num);
+		if (res)
+			goto dqbuf_unlock_and_return;
+		zr->v4l_sync_tail++;
+		res = zoran_v4l2_buffer_status(fh, buf, num);
 		break;
 
-	case VIDIOC_ENUMSTD:
+	case ZORAN_MAP_MODE_JPG_REC:
+	case ZORAN_MAP_MODE_JPG_PLAY:
 	{
-		struct v4l2_standard *std = arg;
+		struct zoran_sync bs;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n",
-			ZR_DEVNAME(zr), std->index);
+		if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
+			buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+		else
+			buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-		if (std->index < 0 || std->index >= (zr->card.norms + 1))
-			return -EINVAL;
-		else {
-			int id = std->index;
-			memset(std, 0, sizeof(*std));
-			std->index = id;
+		if (buf->type != buf_type) {
+			dprintk(1, KERN_ERR
+				"%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+				ZR_DEVNAME(zr), buf->type, fh->map_mode);
+			res = -EINVAL;
+			goto dqbuf_unlock_and_return;
 		}
 
-		if (std->index == zr->card.norms) {
-			/* if we have autodetect, ... */
-			struct video_decoder_capability caps;
-			decoder_command(zr, DECODER_GET_CAPABILITIES,
-					&caps);
-			if (caps.flags & VIDEO_DECODER_AUTO) {
-				std->id = V4L2_STD_ALL;
-				strncpy(std->name, "Autodetect", sizeof(std->name)-1);
-				return 0;
-			} else
-				return -EINVAL;
-		}
-		switch (std->index) {
-		case 0:
-			std->id = V4L2_STD_PAL;
-			strncpy(std->name, "PAL", sizeof(std->name)-1);
-			std->frameperiod.numerator = 1;
-			std->frameperiod.denominator = 25;
-			std->framelines = zr->card.tvn[0]->Ht;
-			break;
-		case 1:
-			std->id = V4L2_STD_NTSC;
-			strncpy(std->name, "NTSC", sizeof(std->name)-1);
-			std->frameperiod.numerator = 1001;
-			std->frameperiod.denominator = 30000;
-			std->framelines = zr->card.tvn[1]->Ht;
-			break;
-		case 2:
-			std->id = V4L2_STD_SECAM;
-			strncpy(std->name, "SECAM", sizeof(std->name)-1);
-			std->frameperiod.numerator = 1;
-			std->frameperiod.denominator = 25;
-			std->framelines = zr->card.tvn[2]->Ht;
-			break;
-		}
+		num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
 
-		return 0;
+		if (file->f_flags & O_NONBLOCK &&
+		    zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
+			res = -EAGAIN;
+			goto dqbuf_unlock_and_return;
+		}
+		res = jpg_sync(fh, &bs);
+		if (res)
+			goto dqbuf_unlock_and_return;
+		res = zoran_v4l2_buffer_status(fh, buf, bs.frame);
+		break;
 	}
+
+	default:
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_DQBUF - unsupported type %d\n",
+			ZR_DEVNAME(zr), buf->type);
+		res = -EINVAL;
 		break;
+	}
+dqbuf_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-	case VIDIOC_G_STD:
-	{
-		v4l2_std_id *std = arg;
-		int norm;
+	return res;
+}
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr));
+static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0;
 
-		mutex_lock(&zr->resource_lock);
-		norm = zr->norm;
-		mutex_unlock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-		switch (norm) {
-		case VIDEO_MODE_PAL:
-			*std = V4L2_STD_PAL;
-			break;
-		case VIDEO_MODE_NTSC:
-			*std = V4L2_STD_NTSC;
-			break;
-		case VIDEO_MODE_SECAM:
-			*std = V4L2_STD_SECAM;
-			break;
+	switch (fh->map_mode) {
+	case ZORAN_MAP_MODE_RAW:	/* raw capture */
+		if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
+		    fh->buffers.active != ZORAN_ACTIVE) {
+			res = -EBUSY;
+			goto strmon_unlock_and_return;
 		}
 
-		return 0;
-	}
+		zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED;
+		zr->v4l_settings = fh->v4l_settings;
+
+		zr->v4l_sync_tail = zr->v4l_pend_tail;
+		if (!zr->v4l_memgrab_active &&
+		    zr->v4l_pend_head != zr->v4l_pend_tail) {
+			zr36057_set_memgrab(zr, 1);
+		}
 		break;
 
-	case VIDIOC_S_STD:
-	{
-		int norm = -1, res = 0;
-		v4l2_std_id *std = arg;
+	case ZORAN_MAP_MODE_JPG_REC:
+	case ZORAN_MAP_MODE_JPG_PLAY:
+		/* what is the codec mode right now? */
+		if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
+		    fh->buffers.active != ZORAN_ACTIVE) {
+			res = -EBUSY;
+			goto strmon_unlock_and_return;
+		}
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
-			ZR_DEVNAME(zr), (unsigned long long)*std);
+		zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED;
 
-		if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
-			norm = VIDEO_MODE_PAL;
-		else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
-			norm = VIDEO_MODE_NTSC;
-		else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
-			norm = VIDEO_MODE_SECAM;
-		else if (*std == V4L2_STD_ALL)
-			norm = VIDEO_MODE_AUTO;
-		else {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
-				ZR_DEVNAME(zr), (unsigned long long)*std);
-			return -EINVAL;
+		if (zr->jpg_que_head != zr->jpg_que_tail) {
+			/* Start the jpeg codec when the first frame is queued  */
+			jpeg_start(zr);
 		}
+		break;
 
-		mutex_lock(&zr->resource_lock);
-		if ((res = zoran_set_norm(zr, norm)))
-			goto sstd_unlock_and_return;
-
-		res = wait_grab_pending(zr);
-	sstd_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
+	default:
+		dprintk(1,
+			KERN_ERR
+			"%s: VIDIOC_STREAMON - invalid map mode %d\n",
+			ZR_DEVNAME(zr), fh->map_mode);
+		res = -EINVAL;
 		break;
+	}
+strmon_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input *inp = arg;
-		int status;
+	return res;
+}
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n",
-			ZR_DEVNAME(zr), inp->index);
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int i, res = 0;
+	unsigned long flags;
 
-		if (inp->index < 0 || inp->index >= zr->card.inputs)
-			return -EINVAL;
-		else {
-			int id = inp->index;
-			memset(inp, 0, sizeof(*inp));
-			inp->index = id;
-		}
+	mutex_lock(&zr->resource_lock);
 
-		strncpy(inp->name, zr->card.input[inp->index].name,
-			sizeof(inp->name) - 1);
-		inp->type = V4L2_INPUT_TYPE_CAMERA;
-		inp->std = V4L2_STD_ALL;
+	switch (fh->map_mode) {
+	case ZORAN_MAP_MODE_RAW:	/* raw capture */
+		if (fh->buffers.active == ZORAN_FREE &&
+		    zr->v4l_buffers.active != ZORAN_FREE) {
+			res = -EPERM;	/* stay off other's settings! */
+			goto strmoff_unlock_and_return;
+		}
+		if (zr->v4l_buffers.active == ZORAN_FREE)
+			goto strmoff_unlock_and_return;
 
-		/* Get status of video decoder */
-		mutex_lock(&zr->resource_lock);
-		decoder_command(zr, DECODER_GET_STATUS, &status);
-		mutex_unlock(&zr->resource_lock);
+		spin_lock_irqsave(&zr->spinlock, flags);
+		/* unload capture */
+		if (zr->v4l_memgrab_active) {
 
-		if (!(status & DECODER_STATUS_GOOD)) {
-			inp->status |= V4L2_IN_ST_NO_POWER;
-			inp->status |= V4L2_IN_ST_NO_SIGNAL;
+			zr36057_set_memgrab(zr, 0);
 		}
-		if (!(status & DECODER_STATUS_COLOR))
-			inp->status |= V4L2_IN_ST_NO_COLOR;
 
-		return 0;
-	}
-		break;
+		for (i = 0; i < fh->buffers.num_buffers; i++)
+			zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
+		fh->buffers = zr->v4l_buffers;
 
-	case VIDIOC_G_INPUT:
-	{
-		int *input = arg;
+		zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr));
+		zr->v4l_grab_seq = 0;
+		zr->v4l_pend_head = zr->v4l_pend_tail = 0;
+		zr->v4l_sync_tail = 0;
 
-		mutex_lock(&zr->resource_lock);
-		*input = zr->input;
-		mutex_unlock(&zr->resource_lock);
+		spin_unlock_irqrestore(&zr->spinlock, flags);
 
-		return 0;
-	}
 		break;
 
-	case VIDIOC_S_INPUT:
-	{
-		int *input = arg, res = 0;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n",
-			ZR_DEVNAME(zr), *input);
-
-		mutex_lock(&zr->resource_lock);
-		if ((res = zoran_set_input(zr, *input)))
-			goto sinput_unlock_and_return;
+	case ZORAN_MAP_MODE_JPG_REC:
+	case ZORAN_MAP_MODE_JPG_PLAY:
+		if (fh->buffers.active == ZORAN_FREE &&
+		    zr->jpg_buffers.active != ZORAN_FREE) {
+			res = -EPERM;	/* stay off other's settings! */
+			goto strmoff_unlock_and_return;
+		}
+		if (zr->jpg_buffers.active == ZORAN_FREE)
+			goto strmoff_unlock_and_return;
 
-		/* Make sure the changes come into effect */
-		res = wait_grab_pending(zr);
-	sinput_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
+		res = jpg_qbuf(fh, -1,
+			     (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
+			     BUZ_MODE_MOTION_COMPRESS :
+			     BUZ_MODE_MOTION_DECOMPRESS);
+		if (res)
+			goto strmoff_unlock_and_return;
 		break;
+	default:
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
+			ZR_DEVNAME(zr), fh->map_mode);
+		res = -EINVAL;
+		break;
+	}
+strmoff_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-	case VIDIOC_ENUMOUTPUT:
-	{
-		struct v4l2_output *outp = arg;
+	return res;
+}
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n",
-			ZR_DEVNAME(zr), outp->index);
+static int zoran_queryctrl(struct file *file, void *__fh,
+					struct v4l2_queryctrl *ctrl)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		if (outp->index != 0)
-			return -EINVAL;
+	/* we only support hue/saturation/contrast/brightness */
+	if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+	    ctrl->id > V4L2_CID_HUE)
+		return -EINVAL;
 
-		memset(outp, 0, sizeof(*outp));
-		outp->index = 0;
-		outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
-		strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
+	decoder_call(zr, core, queryctrl, ctrl);
 
-		return 0;
-	}
-		break;
+	return 0;
+}
 
-	case VIDIOC_G_OUTPUT:
-	{
-		int *output = arg;
+static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr));
+	/* we only support hue/saturation/contrast/brightness */
+	if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+	    ctrl->id > V4L2_CID_HUE)
+		return -EINVAL;
 
-		*output = 0;
+	mutex_lock(&zr->resource_lock);
+	decoder_call(zr, core, g_ctrl, ctrl);
+	mutex_unlock(&zr->resource_lock);
 
-		return 0;
-	}
-		break;
+	return 0;
+}
 
-	case VIDIOC_S_OUTPUT:
-	{
-		int *output = arg;
+static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n",
-			ZR_DEVNAME(zr), *output);
+	/* we only support hue/saturation/contrast/brightness */
+	if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+	    ctrl->id > V4L2_CID_HUE)
+		return -EINVAL;
 
-		if (*output != 0)
-			return -EINVAL;
+	mutex_lock(&zr->resource_lock);
+	decoder_call(zr, core, s_ctrl, ctrl);
+	mutex_unlock(&zr->resource_lock);
 
-		return 0;
-	}
-		break;
+	return 0;
+}
 
-		/* cropping (sub-frame capture) */
-	case VIDIOC_CROPCAP:
-	{
-		struct v4l2_cropcap *cropcap = arg;
-		int type = cropcap->type, res = 0;
+static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n",
-			ZR_DEVNAME(zr), cropcap->type);
+	mutex_lock(&zr->resource_lock);
+	*std = zr->norm;
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-		memset(cropcap, 0, sizeof(*cropcap));
-		cropcap->type = type;
+static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0;
 
-		mutex_lock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
+	res = zoran_set_norm(zr, *std);
+	if (res)
+		goto sstd_unlock_and_return;
 
-		if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-		    (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
-				ZR_DEVNAME(zr));
-			res = -EINVAL;
-			goto cropcap_unlock_and_return;
-		}
+	res = wait_grab_pending(zr);
+sstd_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		cropcap->bounds.top = cropcap->bounds.left = 0;
-		cropcap->bounds.width = BUZ_MAX_WIDTH;
-		cropcap->bounds.height = BUZ_MAX_HEIGHT;
-		cropcap->defrect.top = cropcap->defrect.left = 0;
-		cropcap->defrect.width = BUZ_MIN_WIDTH;
-		cropcap->defrect.height = BUZ_MIN_HEIGHT;
-	cropcap_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
-		break;
+static int zoran_enum_input(struct file *file, void *__fh,
+				 struct v4l2_input *inp)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-	case VIDIOC_G_CROP:
-	{
-		struct v4l2_crop *crop = arg;
-		int type = crop->type, res = 0;
+	if (inp->index < 0 || inp->index >= zr->card.inputs)
+		return -EINVAL;
+	else {
+		int id = inp->index;
+		memset(inp, 0, sizeof(*inp));
+		inp->index = id;
+	}
 
-		dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n",
-			ZR_DEVNAME(zr), crop->type);
+	strncpy(inp->name, zr->card.input[inp->index].name,
+		sizeof(inp->name) - 1);
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	inp->std = V4L2_STD_ALL;
 
-		memset(crop, 0, sizeof(*crop));
-		crop->type = type;
+	/* Get status of video decoder */
+	mutex_lock(&zr->resource_lock);
+	decoder_call(zr, video, g_input_status, &inp->status);
+	mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-		mutex_lock(&zr->resource_lock);
+static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
 
-		if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-		    (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
-				ZR_DEVNAME(zr));
-			res = -EINVAL;
-			goto gcrop_unlock_and_return;
-		}
+	mutex_lock(&zr->resource_lock);
+	*input = zr->input;
+	mutex_unlock(&zr->resource_lock);
 
-		crop->c.top = fh->jpg_settings.img_y;
-		crop->c.left = fh->jpg_settings.img_x;
-		crop->c.width = fh->jpg_settings.img_width;
-		crop->c.height = fh->jpg_settings.img_height;
+	return 0;
+}
 
-	gcrop_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
+static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res;
 
-		return res;
-	}
-		break;
+	mutex_lock(&zr->resource_lock);
+	res = zoran_set_input(zr, input);
+	if (res)
+		goto sinput_unlock_and_return;
 
-	case VIDIOC_S_CROP:
-	{
-		struct v4l2_crop *crop = arg;
-		int res = 0;
+	/* Make sure the changes come into effect */
+	res = wait_grab_pending(zr);
+sinput_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		settings = fh->jpg_settings;
+static int zoran_enum_output(struct file *file, void *__fh,
+				  struct v4l2_output *outp)
+{
+	if (outp->index != 0)
+		return -EINVAL;
 
-		dprintk(3,
-			KERN_ERR
-			"%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n",
-			ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top,
-			crop->c.width, crop->c.height);
+	memset(outp, 0, sizeof(*outp));
+	outp->index = 0;
+	outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
+	strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
 
-		mutex_lock(&zr->resource_lock);
+	return 0;
+}
 
-		if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_S_CROP - cannot change settings while active\n",
-				ZR_DEVNAME(zr));
-			res = -EBUSY;
-			goto scrop_unlock_and_return;
-		}
+static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
+{
+	*output = 0;
 
-		if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-		    (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-		     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
-			dprintk(1,
-				KERN_ERR
-				"%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
-				ZR_DEVNAME(zr));
-			res = -EINVAL;
-			goto scrop_unlock_and_return;
-		}
+	return 0;
+}
 
-		/* move into a form that we understand */
-		settings.img_x = crop->c.left;
-		settings.img_y = crop->c.top;
-		settings.img_width = crop->c.width;
-		settings.img_height = crop->c.height;
+static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
+{
+	if (output != 0)
+		return -EINVAL;
 
-		/* check validity */
-		if ((res = zoran_check_jpg_settings(zr, &settings)))
-			goto scrop_unlock_and_return;
+	return 0;
+}
 
-		/* accept */
-		fh->jpg_settings = settings;
+/* cropping (sub-frame capture) */
+static int zoran_cropcap(struct file *file, void *__fh,
+					struct v4l2_cropcap *cropcap)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int type = cropcap->type, res = 0;
 
-	scrop_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-		return res;
-	}
-		break;
+	memset(cropcap, 0, sizeof(*cropcap));
+	cropcap->type = type;
 
-	case VIDIOC_G_JPEGCOMP:
-	{
-		struct v4l2_jpegcompression *params = arg;
+	mutex_lock(&zr->resource_lock);
 
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n",
+	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+	    (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
 			ZR_DEVNAME(zr));
+		res = -EINVAL;
+		goto cropcap_unlock_and_return;
+	}
 
-		memset(params, 0, sizeof(*params));
+	cropcap->bounds.top = cropcap->bounds.left = 0;
+	cropcap->bounds.width = BUZ_MAX_WIDTH;
+	cropcap->bounds.height = BUZ_MAX_HEIGHT;
+	cropcap->defrect.top = cropcap->defrect.left = 0;
+	cropcap->defrect.width = BUZ_MIN_WIDTH;
+	cropcap->defrect.height = BUZ_MIN_HEIGHT;
+cropcap_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-		mutex_lock(&zr->resource_lock);
+static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int type = crop->type, res = 0;
 
-		params->quality = fh->jpg_settings.jpg_comp.quality;
-		params->APPn = fh->jpg_settings.jpg_comp.APPn;
-		memcpy(params->APP_data,
-		       fh->jpg_settings.jpg_comp.APP_data,
-		       fh->jpg_settings.jpg_comp.APP_len);
-		params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
-		memcpy(params->COM_data,
-		       fh->jpg_settings.jpg_comp.COM_data,
-		       fh->jpg_settings.jpg_comp.COM_len);
-		params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
-		params->jpeg_markers =
-		    fh->jpg_settings.jpg_comp.jpeg_markers;
+	memset(crop, 0, sizeof(*crop));
+	crop->type = type;
 
-		mutex_unlock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-		return 0;
+	if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+	    (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+		dprintk(1,
+			KERN_ERR
+			"%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+			ZR_DEVNAME(zr));
+		res = -EINVAL;
+		goto gcrop_unlock_and_return;
 	}
-		break;
 
-	case VIDIOC_S_JPEGCOMP:
-	{
-		struct v4l2_jpegcompression *params = arg;
-		int res = 0;
-
-		settings = fh->jpg_settings;
+	crop->c.top = fh->jpg_settings.img_y;
+	crop->c.left = fh->jpg_settings.img_x;
+	crop->c.width = fh->jpg_settings.img_width;
+	crop->c.height = fh->jpg_settings.img_height;
 
-		dprintk(3,
-			KERN_DEBUG
-			"%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
-			ZR_DEVNAME(zr), params->quality, params->APPn,
-			params->APP_len, params->COM_len);
+gcrop_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-		settings.jpg_comp = *params;
+	return res;
+}
 
-		mutex_lock(&zr->resource_lock);
+static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0;
+	struct zoran_jpg_settings settings;
 
-		if (fh->v4l_buffers.active != ZORAN_FREE ||
-		    fh->jpg_buffers.active != ZORAN_FREE) {
-			dprintk(1,
-				KERN_WARNING
-				"%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
-				ZR_DEVNAME(zr));
-			res = -EBUSY;
-			goto sjpegc_unlock_and_return;
-		}
+	settings = fh->jpg_settings;
 
-		if ((res = zoran_check_jpg_settings(zr, &settings)))
-			goto sjpegc_unlock_and_return;
-		if (!fh->jpg_buffers.allocated)
-			fh->jpg_buffers.buffer_size =
-			    zoran_v4l2_calc_bufsize(&fh->jpg_settings);
-		fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
-	sjpegc_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
+	mutex_lock(&zr->resource_lock);
 
-		return 0;
+	if (fh->buffers.allocated) {
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_S_CROP - cannot change settings while active\n",
+			ZR_DEVNAME(zr));
+		res = -EBUSY;
+		goto scrop_unlock_and_return;
 	}
-		break;
-
-	case VIDIOC_QUERYSTD:	/* why is this useful? */
-	{
-		v4l2_std_id *std = arg;
-
-		dprintk(3,
-			KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n",
-			ZR_DEVNAME(zr), (unsigned long long)*std);
-
-		if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC ||
-		    *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM &&
-					     zr->card.norms == 3)) {
-			return 0;
-		}
 
-		return -EINVAL;
+	if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+	    (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+	     fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+		dprintk(1, KERN_ERR
+			"%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+			ZR_DEVNAME(zr));
+		res = -EINVAL;
+		goto scrop_unlock_and_return;
 	}
-		break;
-
-	case VIDIOC_TRY_FMT:
-	{
-		struct v4l2_format *fmt = arg;
-		int res = 0;
-
-		dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n",
-			ZR_DEVNAME(zr), fmt->type);
-
-		switch (fmt->type) {
-		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-			mutex_lock(&zr->resource_lock);
-
-			if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
-				fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
-			if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
-				fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
-			if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
-				fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
-			if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
-				fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
-
-			mutex_unlock(&zr->resource_lock);
-			break;
 
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-			if (fmt->fmt.pix.bytesperline > 0)
-				return -EINVAL;
+	/* move into a form that we understand */
+	settings.img_x = crop->c.left;
+	settings.img_y = crop->c.top;
+	settings.img_width = crop->c.width;
+	settings.img_height = crop->c.height;
 
-			mutex_lock(&zr->resource_lock);
+	/* check validity */
+	res = zoran_check_jpg_settings(zr, &settings, 0);
+	if (res)
+		goto scrop_unlock_and_return;
 
-			if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
-				settings = fh->jpg_settings;
+	/* accept */
+	fh->jpg_settings = settings;
 
-				/* we actually need to set 'real' parameters now */
-				if ((fmt->fmt.pix.height * 2) >
-				    BUZ_MAX_HEIGHT)
-					settings.TmpDcm = 1;
-				else
-					settings.TmpDcm = 2;
-				settings.decimation = 0;
-				if (fmt->fmt.pix.height <=
-				    fh->jpg_settings.img_height / 2)
-					settings.VerDcm = 2;
-				else
-					settings.VerDcm = 1;
-				if (fmt->fmt.pix.width <=
-				    fh->jpg_settings.img_width / 4)
-					settings.HorDcm = 4;
-				else if (fmt->fmt.pix.width <=
-					 fh->jpg_settings.img_width / 2)
-					settings.HorDcm = 2;
-				else
-					settings.HorDcm = 1;
-				if (settings.TmpDcm == 1)
-					settings.field_per_buff = 2;
-				else
-					settings.field_per_buff = 1;
+scrop_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+	return res;
+}
 
-				/* check */
-				if ((res =
-				     zoran_check_jpg_settings(zr,
-							      &settings)))
-					goto tryfmt_unlock_and_return;
+static int zoran_g_jpegcomp(struct file *file, void *__fh,
+					struct v4l2_jpegcompression *params)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	memset(params, 0, sizeof(*params));
 
-				/* tell the user what we actually did */
-				fmt->fmt.pix.width =
-				    settings.img_width / settings.HorDcm;
-				fmt->fmt.pix.height =
-				    settings.img_height * 2 /
-				    (settings.TmpDcm * settings.VerDcm);
-				if (settings.TmpDcm == 1)
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_SEQ_TB :
-					     V4L2_FIELD_SEQ_BT);
-				else
-					fmt->fmt.pix.field =
-					    (fh->jpg_settings.
-					     odd_even ? V4L2_FIELD_TOP :
-					     V4L2_FIELD_BOTTOM);
+	mutex_lock(&zr->resource_lock);
 
-				fmt->fmt.pix.sizeimage =
-				    zoran_v4l2_calc_bufsize(&settings);
-			} else if (fmt->type ==
-				   V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-				int i;
+	params->quality = fh->jpg_settings.jpg_comp.quality;
+	params->APPn = fh->jpg_settings.jpg_comp.APPn;
+	memcpy(params->APP_data,
+	       fh->jpg_settings.jpg_comp.APP_data,
+	       fh->jpg_settings.jpg_comp.APP_len);
+	params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
+	memcpy(params->COM_data,
+	       fh->jpg_settings.jpg_comp.COM_data,
+	       fh->jpg_settings.jpg_comp.COM_len);
+	params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
+	params->jpeg_markers =
+	    fh->jpg_settings.jpg_comp.jpeg_markers;
 
-				for (i = 0; i < NUM_FORMATS; i++)
-					if (zoran_formats[i].fourcc ==
-					    fmt->fmt.pix.pixelformat)
-						break;
-				if (i == NUM_FORMATS) {
-					res = -EINVAL;
-					goto tryfmt_unlock_and_return;
-				}
+	mutex_unlock(&zr->resource_lock);
 
-				if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
-					fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-				if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
-					fmt->fmt.pix.width = BUZ_MIN_WIDTH;
-				if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
-					fmt->fmt.pix.height =
-					    BUZ_MAX_HEIGHT;
-				if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
-					fmt->fmt.pix.height =
-					    BUZ_MIN_HEIGHT;
-			} else {
-				res = -EINVAL;
-				goto tryfmt_unlock_and_return;
-			}
-		tryfmt_unlock_and_return:
-			mutex_unlock(&zr->resource_lock);
+	return 0;
+}
 
-			return res;
-			break;
+static int zoran_s_jpegcomp(struct file *file, void *__fh,
+					struct v4l2_jpegcompression *params)
+{
+	struct zoran_fh *fh = __fh;
+	struct zoran *zr = fh->zr;
+	int res = 0;
+	struct zoran_jpg_settings settings;
 
-		default:
-			return -EINVAL;
-		}
+	settings = fh->jpg_settings;
 
-		return 0;
-	}
-		break;
+	settings.jpg_comp = *params;
 
-	default:
-		dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
-			ZR_DEVNAME(zr), cmd);
-		return -ENOIOCTLCMD;
-		break;
+	mutex_lock(&zr->resource_lock);
 
+	if (fh->buffers.active != ZORAN_FREE) {
+		dprintk(1, KERN_WARNING
+			"%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
+			ZR_DEVNAME(zr));
+		res = -EBUSY;
+		goto sjpegc_unlock_and_return;
 	}
-	return 0;
-}
 
+	res = zoran_check_jpg_settings(zr, &settings, 0);
+	if (res)
+		goto sjpegc_unlock_and_return;
+	if (!fh->buffers.allocated)
+		fh->buffers.buffer_size =
+			zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+	fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
+sjpegc_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
 
-static long
-zoran_ioctl(struct file  *file,
-	    unsigned int  cmd,
-	    unsigned long arg)
-{
-	return video_usercopy(file, cmd, arg, zoran_do_ioctl);
+	return res;
 }
 
 static unsigned int
@@ -4191,11 +3054,11 @@ zoran_poll (struct file *file,
 			KERN_DEBUG
 			"%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
 			ZR_DEVNAME(zr), __func__,
-			"FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
+			"FAL"[fh->buffers.active], zr->v4l_sync_tail,
 			"UPMD"[zr->v4l_buffers.buffer[frame].state],
 			zr->v4l_pend_tail, zr->v4l_pend_head);
 		/* Process is the one capturing? */
-		if (fh->v4l_buffers.active != ZORAN_FREE &&
+		if (fh->buffers.active != ZORAN_FREE &&
 		    /* Buffer ready to DQBUF? */
 		    zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
 			res = POLLIN | POLLRDNORM;
@@ -4213,10 +3076,10 @@ zoran_poll (struct file *file,
 			KERN_DEBUG
 			"%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
 			ZR_DEVNAME(zr), __func__,
-			"FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
+			"FAL"[fh->buffers.active], zr->jpg_que_tail,
 			"UPMD"[zr->jpg_buffers.buffer[frame].state],
 			zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
-		if (fh->jpg_buffers.active != ZORAN_FREE &&
+		if (fh->buffers.active != ZORAN_FREE &&
 		    zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
 			if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
 				res = POLLIN | POLLRDNORM;
@@ -4230,8 +3093,8 @@ zoran_poll (struct file *file,
 	default:
 		dprintk(1,
 			KERN_ERR
-			"%s: zoran_poll() - internal error, unknown map_mode=%d\n",
-			ZR_DEVNAME(zr), fh->map_mode);
+			"%s: %s - internal error, unknown map_mode=%d\n",
+			ZR_DEVNAME(zr), __func__, fh->map_mode);
 		res = POLLNVAL;
 	}
 
@@ -4265,98 +3128,53 @@ static void
 zoran_vm_close (struct vm_area_struct *vma)
 {
 	struct zoran_mapping *map = vma->vm_private_data;
-	struct file *file = map->file;
-	struct zoran_fh *fh = file->private_data;
+	struct zoran_fh *fh = map->file->private_data;
 	struct zoran *zr = fh->zr;
 	int i;
 
-	map->count--;
-	if (map->count == 0) {
-		switch (fh->map_mode) {
-		case ZORAN_MAP_MODE_JPG_REC:
-		case ZORAN_MAP_MODE_JPG_PLAY:
-
-			dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
-				ZR_DEVNAME(zr));
-
-			for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
-				if (fh->jpg_buffers.buffer[i].map == map) {
-					fh->jpg_buffers.buffer[i].map =
-					    NULL;
-				}
-			}
-			kfree(map);
-
-			for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
-				if (fh->jpg_buffers.buffer[i].map)
-					break;
-			if (i == fh->jpg_buffers.num_buffers) {
-				mutex_lock(&zr->resource_lock);
-
-				if (fh->jpg_buffers.active != ZORAN_FREE) {
-					jpg_qbuf(file, -1, zr->codec_mode);
-					zr->jpg_buffers.allocated = 0;
-					zr->jpg_buffers.active =
-					    fh->jpg_buffers.active =
-					    ZORAN_FREE;
-				}
-				//jpg_fbuffer_free(file);
-				fh->jpg_buffers.allocated = 0;
-				fh->jpg_buffers.ready_to_be_freed = 1;
-
-				mutex_unlock(&zr->resource_lock);
-			}
-
-			break;
-
-		case ZORAN_MAP_MODE_RAW:
-
-			dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
-				ZR_DEVNAME(zr));
-
-			for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
-				if (fh->v4l_buffers.buffer[i].map == map) {
-					/* unqueue/unmap */
-					fh->v4l_buffers.buffer[i].map =
-					    NULL;
-				}
-			}
-			kfree(map);
+	if (--map->count > 0)
+		return;
 
-			for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
-				if (fh->v4l_buffers.buffer[i].map)
-					break;
-			if (i == fh->v4l_buffers.num_buffers) {
-				mutex_lock(&zr->resource_lock);
+	dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
+		__func__, mode_name(fh->map_mode));
 
-				if (fh->v4l_buffers.active != ZORAN_FREE) {
-					unsigned long flags;
+	for (i = 0; i < fh->buffers.num_buffers; i++) {
+		if (fh->buffers.buffer[i].map == map)
+			fh->buffers.buffer[i].map = NULL;
+	}
+	kfree(map);
 
-					spin_lock_irqsave(&zr->spinlock, flags);
-					zr36057_set_memgrab(zr, 0);
-					zr->v4l_buffers.allocated = 0;
-					zr->v4l_buffers.active =
-					    fh->v4l_buffers.active =
-					    ZORAN_FREE;
-					spin_unlock_irqrestore(&zr->spinlock, flags);
-				}
-				//v4l_fbuffer_free(file);
-				fh->v4l_buffers.allocated = 0;
-				fh->v4l_buffers.ready_to_be_freed = 1;
+	/* Any buffers still mapped? */
+	for (i = 0; i < fh->buffers.num_buffers; i++)
+		if (fh->buffers.buffer[i].map)
+			return;
 
-				mutex_unlock(&zr->resource_lock);
-			}
+	dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
+		__func__, mode_name(fh->map_mode));
 
-			break;
+	mutex_lock(&zr->resource_lock);
 
-		default:
-			printk(KERN_ERR
-			       "%s: munmap() - internal error - unknown map mode %d\n",
-			       ZR_DEVNAME(zr), fh->map_mode);
-			break;
+	if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+		if (fh->buffers.active != ZORAN_FREE) {
+			unsigned long flags;
 
+			spin_lock_irqsave(&zr->spinlock, flags);
+			zr36057_set_memgrab(zr, 0);
+			zr->v4l_buffers.allocated = 0;
+			zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+			spin_unlock_irqrestore(&zr->spinlock, flags);
+		}
+		v4l_fbuffer_free(fh);
+	} else {
+		if (fh->buffers.active != ZORAN_FREE) {
+			jpg_qbuf(fh, -1, zr->codec_mode);
+			zr->jpg_buffers.allocated = 0;
+			zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
 		}
+		jpg_fbuffer_free(fh);
 	}
+
+	mutex_unlock(&zr->resource_lock);
 }
 
 static struct vm_operations_struct zoran_vm_ops = {
@@ -4379,90 +3197,106 @@ zoran_mmap (struct file           *file,
 	int res = 0;
 
 	dprintk(3,
-		KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
-		ZR_DEVNAME(zr),
-		fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
-		vma->vm_start, vma->vm_end, size);
+		KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
+		ZR_DEVNAME(zr), __func__,
+		mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size);
 
 	if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
 	    !(vma->vm_flags & VM_WRITE)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
-			ZR_DEVNAME(zr));
+			"%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n",
+			ZR_DEVNAME(zr), __func__);
 		return -EINVAL;
 	}
 
-	switch (fh->map_mode) {
+	mutex_lock(&zr->resource_lock);
 
-	case ZORAN_MAP_MODE_JPG_REC:
-	case ZORAN_MAP_MODE_JPG_PLAY:
+	if (!fh->buffers.allocated) {
+		dprintk(1,
+			KERN_ERR
+			"%s: %s(%s) - buffers not yet allocated\n",
+			ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode));
+		res = -ENOMEM;
+		goto mmap_unlock_and_return;
+	}
 
-		/* lock */
-		mutex_lock(&zr->resource_lock);
+	first = offset / fh->buffers.buffer_size;
+	last = first - 1 + size / fh->buffers.buffer_size;
+	if (offset % fh->buffers.buffer_size != 0 ||
+	    size % fh->buffers.buffer_size != 0 || first < 0 ||
+	    last < 0 || first >= fh->buffers.num_buffers ||
+	    last >= fh->buffers.buffer_size) {
+		dprintk(1,
+			KERN_ERR
+			"%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
+			ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size,
+			fh->buffers.buffer_size,
+			fh->buffers.num_buffers);
+		res = -EINVAL;
+		goto mmap_unlock_and_return;
+	}
 
-		/* Map the MJPEG buffers */
-		if (!fh->jpg_buffers.allocated) {
+	/* Check if any buffers are already mapped */
+	for (i = first; i <= last; i++) {
+		if (fh->buffers.buffer[i].map) {
 			dprintk(1,
 				KERN_ERR
-				"%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
-				ZR_DEVNAME(zr));
-			res = -ENOMEM;
-			goto jpg_mmap_unlock_and_return;
+				"%s: %s(%s) - buffer %d already mapped\n",
+				ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i);
+			res = -EBUSY;
+			goto mmap_unlock_and_return;
 		}
+	}
 
-		first = offset / fh->jpg_buffers.buffer_size;
-		last = first - 1 + size / fh->jpg_buffers.buffer_size;
-		if (offset % fh->jpg_buffers.buffer_size != 0 ||
-		    size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
-		    last < 0 || first >= fh->jpg_buffers.num_buffers ||
-		    last >= fh->jpg_buffers.num_buffers) {
-			dprintk(1,
-				KERN_ERR
-				"%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
-				ZR_DEVNAME(zr), offset, size,
-				fh->jpg_buffers.buffer_size,
-				fh->jpg_buffers.num_buffers);
-			res = -EINVAL;
-			goto jpg_mmap_unlock_and_return;
-		}
+	/* map these buffers */
+	map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
+	if (!map) {
+		res = -ENOMEM;
+		goto mmap_unlock_and_return;
+	}
+	map->file = file;
+	map->count = 1;
+
+	vma->vm_ops = &zoran_vm_ops;
+	vma->vm_flags |= VM_DONTEXPAND;
+	vma->vm_private_data = map;
+
+	if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
 		for (i = first; i <= last; i++) {
-			if (fh->jpg_buffers.buffer[i].map) {
+			todo = size;
+			if (todo > fh->buffers.buffer_size)
+				todo = fh->buffers.buffer_size;
+			page = fh->buffers.buffer[i].v4l.fbuffer_phys;
+			if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
+							todo, PAGE_SHARED)) {
 				dprintk(1,
 					KERN_ERR
-					"%s: mmap(MJPEG) - buffer %d already mapped\n",
-					ZR_DEVNAME(zr), i);
-				res = -EBUSY;
-				goto jpg_mmap_unlock_and_return;
+					"%s: %s(V4L) - remap_pfn_range failed\n",
+					ZR_DEVNAME(zr), __func__);
+				res = -EAGAIN;
+				goto mmap_unlock_and_return;
 			}
+			size -= todo;
+			start += todo;
+			fh->buffers.buffer[i].map = map;
+			if (size == 0)
+				break;
 		}
-
-		/* map these buffers (v4l_buffers[i]) */
-		map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
-		if (!map) {
-			res = -ENOMEM;
-			goto jpg_mmap_unlock_and_return;
-		}
-		map->file = file;
-		map->count = 1;
-
-		vma->vm_ops = &zoran_vm_ops;
-		vma->vm_flags |= VM_DONTEXPAND;
-		vma->vm_private_data = map;
-
+	} else {
 		for (i = first; i <= last; i++) {
 			for (j = 0;
-			     j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
+			     j < fh->buffers.buffer_size / PAGE_SIZE;
 			     j++) {
 				fraglen =
-				    (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				    (le32_to_cpu(fh->buffers.buffer[i].jpg.
 				     frag_tab[2 * j + 1]) & ~1) << 1;
 				todo = size;
 				if (todo > fraglen)
 					todo = fraglen;
 				pos =
-				    le32_to_cpu(fh->jpg_buffers.
-				    buffer[i].frag_tab[2 * j]);
+				    le32_to_cpu(fh->buffers.
+				    buffer[i].jpg.frag_tab[2 * j]);
 				/* should just be pos on i386 */
 				page = virt_to_phys(bus_to_virt(pos))
 								>> PAGE_SHIFT;
@@ -4470,123 +3304,82 @@ zoran_mmap (struct file           *file,
 							todo, PAGE_SHARED)) {
 					dprintk(1,
 						KERN_ERR
-						"%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
-						ZR_DEVNAME(zr));
+						"%s: %s(V4L) - remap_pfn_range failed\n",
+						ZR_DEVNAME(zr), __func__);
 					res = -EAGAIN;
-					goto jpg_mmap_unlock_and_return;
+					goto mmap_unlock_and_return;
 				}
 				size -= todo;
 				start += todo;
 				if (size == 0)
 					break;
-				if (le32_to_cpu(fh->jpg_buffers.buffer[i].
+				if (le32_to_cpu(fh->buffers.buffer[i].jpg.
 				    frag_tab[2 * j + 1]) & 1)
 					break;	/* was last fragment */
 			}
-			fh->jpg_buffers.buffer[i].map = map;
+			fh->buffers.buffer[i].map = map;
 			if (size == 0)
 				break;
 
 		}
-	jpg_mmap_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-
-		break;
-
-	case ZORAN_MAP_MODE_RAW:
-
-		mutex_lock(&zr->resource_lock);
-
-		/* Map the V4L buffers */
-		if (!fh->v4l_buffers.allocated) {
-			dprintk(1,
-				KERN_ERR
-				"%s: zoran_mmap(V4L) - buffers not yet allocated\n",
-				ZR_DEVNAME(zr));
-			res = -ENOMEM;
-			goto v4l_mmap_unlock_and_return;
-		}
-
-		first = offset / fh->v4l_buffers.buffer_size;
-		last = first - 1 + size / fh->v4l_buffers.buffer_size;
-		if (offset % fh->v4l_buffers.buffer_size != 0 ||
-		    size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
-		    last < 0 || first >= fh->v4l_buffers.num_buffers ||
-		    last >= fh->v4l_buffers.buffer_size) {
-			dprintk(1,
-				KERN_ERR
-				"%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
-				ZR_DEVNAME(zr), offset, size,
-				fh->v4l_buffers.buffer_size,
-				fh->v4l_buffers.num_buffers);
-			res = -EINVAL;
-			goto v4l_mmap_unlock_and_return;
-		}
-		for (i = first; i <= last; i++) {
-			if (fh->v4l_buffers.buffer[i].map) {
-				dprintk(1,
-					KERN_ERR
-					"%s: mmap(V4L) - buffer %d already mapped\n",
-					ZR_DEVNAME(zr), i);
-				res = -EBUSY;
-				goto v4l_mmap_unlock_and_return;
-			}
-		}
-
-		/* map these buffers (v4l_buffers[i]) */
-		map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
-		if (!map) {
-			res = -ENOMEM;
-			goto v4l_mmap_unlock_and_return;
-		}
-		map->file = file;
-		map->count = 1;
-
-		vma->vm_ops = &zoran_vm_ops;
-		vma->vm_flags |= VM_DONTEXPAND;
-		vma->vm_private_data = map;
-
-		for (i = first; i <= last; i++) {
-			todo = size;
-			if (todo > fh->v4l_buffers.buffer_size)
-				todo = fh->v4l_buffers.buffer_size;
-			page = fh->v4l_buffers.buffer[i].fbuffer_phys;
-			if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
-							todo, PAGE_SHARED)) {
-				dprintk(1,
-					KERN_ERR
-					"%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
-					ZR_DEVNAME(zr));
-				res = -EAGAIN;
-				goto v4l_mmap_unlock_and_return;
-			}
-			size -= todo;
-			start += todo;
-			fh->v4l_buffers.buffer[i].map = map;
-			if (size == 0)
-				break;
-		}
-	v4l_mmap_unlock_and_return:
-		mutex_unlock(&zr->resource_lock);
-
-		break;
-
-	default:
-		dprintk(1,
-			KERN_ERR
-			"%s: zoran_mmap() - internal error - unknown map mode %d\n",
-			ZR_DEVNAME(zr), fh->map_mode);
-		break;
 	}
 
+mmap_unlock_and_return:
+	mutex_unlock(&zr->resource_lock);
+
 	return 0;
 }
 
+static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
+	.vidioc_querycap    		    = zoran_querycap,
+	.vidioc_cropcap       		    = zoran_cropcap,
+	.vidioc_s_crop       		    = zoran_s_crop,
+	.vidioc_g_crop       		    = zoran_g_crop,
+	.vidioc_enum_input     		    = zoran_enum_input,
+	.vidioc_g_input      		    = zoran_g_input,
+	.vidioc_s_input      		    = zoran_s_input,
+	.vidioc_enum_output    		    = zoran_enum_output,
+	.vidioc_g_output     		    = zoran_g_output,
+	.vidioc_s_output     		    = zoran_s_output,
+	.vidioc_g_fbuf			    = zoran_g_fbuf,
+	.vidioc_s_fbuf			    = zoran_s_fbuf,
+	.vidioc_g_std 			    = zoran_g_std,
+	.vidioc_s_std 			    = zoran_s_std,
+	.vidioc_g_jpegcomp 		    = zoran_g_jpegcomp,
+	.vidioc_s_jpegcomp 		    = zoran_s_jpegcomp,
+	.vidioc_overlay			    = zoran_overlay,
+	.vidioc_reqbufs			    = zoran_reqbufs,
+	.vidioc_querybuf		    = zoran_querybuf,
+	.vidioc_qbuf			    = zoran_qbuf,
+	.vidioc_dqbuf			    = zoran_dqbuf,
+	.vidioc_streamon		    = zoran_streamon,
+	.vidioc_streamoff		    = zoran_streamoff,
+	.vidioc_enum_fmt_vid_cap 	    = zoran_enum_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_out 	    = zoran_enum_fmt_vid_out,
+	.vidioc_enum_fmt_vid_overlay 	    = zoran_enum_fmt_vid_overlay,
+	.vidioc_g_fmt_vid_cap 		    = zoran_g_fmt_vid_cap,
+	.vidioc_g_fmt_vid_out               = zoran_g_fmt_vid_out,
+	.vidioc_g_fmt_vid_overlay           = zoran_g_fmt_vid_overlay,
+	.vidioc_s_fmt_vid_cap  		    = zoran_s_fmt_vid_cap,
+	.vidioc_s_fmt_vid_out               = zoran_s_fmt_vid_out,
+	.vidioc_s_fmt_vid_overlay           = zoran_s_fmt_vid_overlay,
+	.vidioc_try_fmt_vid_cap  	    = zoran_try_fmt_vid_cap,
+	.vidioc_try_fmt_vid_out 	    = zoran_try_fmt_vid_out,
+	.vidioc_try_fmt_vid_overlay 	    = zoran_try_fmt_vid_overlay,
+	.vidioc_queryctrl 		    = zoran_queryctrl,
+	.vidioc_s_ctrl       		    = zoran_s_ctrl,
+	.vidioc_g_ctrl       		    = zoran_g_ctrl,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidioc_default 		    = zoran_default,
+	.vidiocgmbuf 			    = zoran_vidiocgmbuf,
+#endif
+};
+
 static const struct v4l2_file_operations zoran_fops = {
 	.owner = THIS_MODULE,
 	.open = zoran_open,
 	.release = zoran_close,
-	.ioctl = zoran_ioctl,
+	.ioctl = video_ioctl2,
 	.read = zoran_read,
 	.write = zoran_write,
 	.mmap = zoran_mmap,
@@ -4596,7 +3389,9 @@ static const struct v4l2_file_operations
 struct video_device zoran_template __devinitdata = {
 	.name = ZORAN_NAME,
 	.fops = &zoran_fops,
+	.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.29-gnu1/drivers/media/video/zoran/zoran.h linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran.h
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,8 @@
 #ifndef _BUZ_H_
 #define _BUZ_H_
 
+#include <media/v4l2-device.h>
+
 struct zoran_requestbuffers {
 	unsigned long count;	/* Number of buffers for MJPEG grabbing */
 	unsigned long size;	/* Size PER BUFFER in bytes */
@@ -141,8 +143,8 @@ Private IOCTL to set up for displaying M
 #ifdef __KERNEL__
 
 #define MAJOR_VERSION 0		/* driver major version */
-#define MINOR_VERSION 9		/* driver minor version */
-#define RELEASE_VERSION 5	/* release version */
+#define MINOR_VERSION 10	/* driver minor version */
+#define RELEASE_VERSION 0	/* release version */
 
 #define ZORAN_NAME    "ZORAN"	/* name of the device */
 
@@ -170,7 +172,7 @@ Private IOCTL to set up for displaying M
 #endif
 #define   V4L_MASK_FRAME   (V4L_MAX_FRAME - 1)
 
-#define MAX_KMALLOC_MEM (128*1024)
+#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME)
 
 #include "zr36057.h"
 
@@ -240,9 +242,6 @@ enum gpcs_type {
 
 struct zoran_format {
 	char *name;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-	int palette;
-#endif
 	__u32 fourcc;
 	int colorspace;
 	int depth;
@@ -283,21 +282,21 @@ struct zoran_mapping {
 	int count;
 };
 
-struct zoran_jpg_buffer {
-	struct zoran_mapping *map;
-	__le32 *frag_tab;		/* addresses of frag table */
-	u32 frag_tab_bus;	/* same value cached to save time in ISR */
-	enum zoran_buffer_state state;	/* non-zero if corresponding buffer is in use in grab queue */
-	struct zoran_sync bs;	/* DONE: info to return to application */
-};
-
-struct zoran_v4l_buffer {
+struct zoran_buffer {
 	struct zoran_mapping *map;
-	char *fbuffer;		/* virtual  address of frame buffer */
-	unsigned long fbuffer_phys;	/* physical address of frame buffer */
-	unsigned long fbuffer_bus;	/* bus      address of frame buffer */
-	enum zoran_buffer_state state;	/* state: unused/pending/done */
-	struct zoran_sync bs;	/* DONE: info to return to application */
+	enum zoran_buffer_state state;	/* state: unused/pending/dma/done */
+	struct zoran_sync bs;		/* DONE: info to return to application */
+	union {
+		struct {
+			__le32 *frag_tab;	/* addresses of frag table */
+			u32 frag_tab_bus;	/* same value cached to save time in ISR */
+		} jpg;
+		struct {
+			char *fbuffer;		/* virtual address of frame buffer */
+			unsigned long fbuffer_phys;/* physical address of frame buffer */
+			unsigned long fbuffer_bus;/* bus address of frame buffer */
+		} v4l;
+	};
 };
 
 enum zoran_lock_activity {
@@ -307,21 +306,13 @@ enum zoran_lock_activity {
 };
 
 /* buffer collections */
-struct zoran_jpg_struct {
+struct zoran_buffer_col {
 	enum zoran_lock_activity active;	/* feature currently in use? */
-	struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME];	/* buffers */
-	int num_buffers, buffer_size;
+	unsigned int num_buffers, buffer_size;
+	struct zoran_buffer buffer[MAX_FRAME];	/* buffers */
 	u8 allocated;		/* Flag if buffers are allocated  */
-	u8 ready_to_be_freed;	/* hack - see zoran_driver.c */
 	u8 need_contiguous;	/* Flag if contiguous buffers are needed */
-};
-
-struct zoran_v4l_struct {
-	enum zoran_lock_activity active;	/* feature currently in use? */
-	struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME];	/* buffers */
-	int num_buffers, buffer_size;
-	u8 allocated;		/* Flag if buffers are allocated  */
-	u8 ready_to_be_freed;	/* hack - see zoran_driver.c */
+	/* only applies to jpg buffers, raw buffers are always contiguous */
 };
 
 struct zoran;
@@ -330,23 +321,27 @@ struct zoran;
 struct zoran_fh {
 	struct zoran *zr;
 
-	enum zoran_map_mode map_mode;	/* Flag which bufferset will map by next mmap() */
+	enum zoran_map_mode map_mode;		/* Flag which bufferset will map by next mmap() */
 
 	struct zoran_overlay_settings overlay_settings;
-	u32 *overlay_mask;	/* overlay mask */
-	enum zoran_lock_activity overlay_active;	/* feature currently in use? */
+	u32 *overlay_mask;			/* overlay mask */
+	enum zoran_lock_activity overlay_active;/* feature currently in use? */
 
-	struct zoran_v4l_settings v4l_settings;	/* structure with a lot of things to play with */
-	struct zoran_v4l_struct v4l_buffers;	/* V4L buffers' info */
+	struct zoran_buffer_col buffers;	/* buffers' info */
 
+	struct zoran_v4l_settings v4l_settings;	/* structure with a lot of things to play with */
 	struct zoran_jpg_settings jpg_settings;	/* structure with a lot of things to play with */
-	struct zoran_jpg_struct jpg_buffers;	/* MJPEG buffers' info */
 };
 
 struct card_info {
 	enum card_type type;
 	char name[32];
-	u16 i2c_decoder, i2c_encoder;			/* I2C types */
+	const char *i2c_decoder;	/* i2c decoder device */
+	const char *mod_decoder;	/* i2c decoder module */
+	const unsigned short *addrs_decoder;
+	const char *i2c_encoder;	/* i2c encoder device */
+	const char *mod_encoder;	/* i2c encoder module */
+	const unsigned short *addrs_encoder;
 	u16 video_vfe, video_codec;			/* videocodec types */
 	u16 audio_chip;					/* audio type */
 
@@ -356,7 +351,7 @@ struct card_info {
 		char name[32];
 	} input[BUZ_MAX_INPUT];
 
-	int norms;
+	v4l2_std_id norms;
 	struct tvnorm *tvn[3];	/* supported TV norms */
 
 	u32 jpeg_int;		/* JPEG interrupt */
@@ -377,14 +372,15 @@ struct card_info {
 };
 
 struct zoran {
+	struct v4l2_device v4l2_dev;
 	struct video_device *video_dev;
 
 	struct i2c_adapter i2c_adapter;	/* */
 	struct i2c_algo_bit_data i2c_algo;	/* */
 	u32 i2cbr;
 
-	struct i2c_client *decoder;	/* video decoder i2c client */
-	struct i2c_client *encoder;	/* video encoder i2c client */
+	struct v4l2_subdev *decoder;	/* video decoder sub-device */
+	struct v4l2_subdev *encoder;	/* video encoder sub-device */
 
 	struct videocodec *codec;	/* video codec */
 	struct videocodec *vfe;	/* video front end */
@@ -405,9 +401,15 @@ struct zoran {
 	spinlock_t spinlock;	/* Spinlock */
 
 	/* Video for Linux parameters */
-	int input, norm;	/* card's norm and input - norm=VIDEO_MODE_* */
-	int hue, saturation, contrast, brightness;	/* Current picture params */
-	struct video_buffer buffer;	/* Current buffer params */
+	int input;	/* card's norm and input - norm=VIDEO_MODE_* */
+	v4l2_std_id norm;
+
+	/* Current buffer params */
+	void    *vbuf_base;
+	int     vbuf_height, vbuf_width;
+	int     vbuf_depth;
+	int     vbuf_bytesperline;
+
 	struct zoran_overlay_settings overlay_settings;
 	u32 *overlay_mask;	/* overlay mask */
 	enum zoran_lock_activity overlay_active;	/* feature currently in use? */
@@ -427,7 +429,7 @@ struct zoran {
 	unsigned long v4l_pend_tail;
 	unsigned long v4l_sync_tail;
 	int v4l_pend[V4L_MAX_FRAME];
-	struct zoran_v4l_struct v4l_buffers;	/* V4L buffers' info */
+	struct zoran_buffer_col v4l_buffers;	/* V4L buffers' info */
 
 	/* Buz MJPEG parameters */
 	enum zoran_codec_mode codec_mode;	/* status of codec */
@@ -454,7 +456,7 @@ struct zoran {
 	int jpg_pend[BUZ_MAX_FRAME];
 
 	/* array indexed by frame number */
-	struct zoran_jpg_struct jpg_buffers;	/* MJPEG buffers' info */
+	struct zoran_buffer_col jpg_buffers;	/* MJPEG buffers' info */
 
 	/* Additional stuff for testing */
 #ifdef CONFIG_PROC_FS
@@ -488,6 +490,11 @@ struct zoran {
 	wait_queue_head_t test_q;
 };
 
+static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct zoran, v4l2_dev);
+}
+
 /* There was something called _ALPHA_BUZ that used the PCI address instead of
  * the kernel iomapped address for btread/btwrite.  */
 #define btwrite(dat,adr)    writel((dat), zr->zr36057_mem+(adr))
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_procfs.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_procfs.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zoran_procfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zoran_procfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,7 +36,7 @@
 #include <linux/pci.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/spinlock.h>
 #include <linux/sem.h>
 #include <linux/seq_file.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36016.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36016.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36016.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36016.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,15 +34,10 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-/* includes for structures and defines regarding video
-   #include<linux/videodev.h> */
-
 /* I/O commands, error codes */
 #include <asm/io.h>
-//#include<errno.h>
 
 /* v4l  API */
-#include <linux/videodev.h>
 
 /* headerfile of this module */
 #include"zr36016.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36050.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36050.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36050.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36050.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,12 +34,8 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-/* includes for structures and defines regarding video
-   #include<linux/videodev.h> */
-
 /* I/O commands, error codes */
 #include <asm/io.h>
-//#include<errno.h>
 
 /* headerfile of this module */
 #include "zr36050.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36060.c linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36060.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zoran/zr36060.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zoran/zr36060.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,12 +34,8 @@
 #include <linux/types.h>
 #include <linux/wait.h>
 
-/* includes for structures and defines regarding video
-   #include<linux/videodev.h> */
-
 /* I/O commands, error codes */
 #include <asm/io.h>
-//#include<errno.h>
 
 /* headerfile of this module */
 #include "zr36060.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/media/video/zr364xx.c linux-libre-2.6.30-gnu1/drivers/media/video/zr364xx.c
--- linux-libre-2.6.29-gnu1/drivers/media/video/zr364xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/media/video/zr364xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
@@ -96,6 +95,7 @@ static struct usb_device_id device_table
 	{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
 	{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
 	{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
+	{USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
 	{}			/* Terminating entry */
 };
 
@@ -425,7 +425,6 @@ static ssize_t zr364xx_read(struct file
 static int zr364xx_vidioc_querycap(struct file *file, void *priv,
 				   struct v4l2_capability *cap)
 {
-	memset(cap, 0, sizeof(*cap));
 	strcpy(cap->driver, DRIVER_DESC);
 	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
 	return 0;
@@ -436,8 +435,6 @@ static int zr364xx_vidioc_enum_input(str
 {
 	if (i->index != 0)
 		return -EINVAL;
-	memset(i, 0, sizeof(*i));
-	i->index = 0;
 	strcpy(i->name, DRIVER_DESC " Camera");
 	i->type = V4L2_INPUT_TYPE_CAMERA;
 	return 0;
@@ -529,11 +526,6 @@ static int zr364xx_vidioc_enum_fmt_vid_c
 {
 	if (f->index > 0)
 		return -EINVAL;
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	memset(f, 0, sizeof(*f));
-	f->index = 0;
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->flags = V4L2_FMT_FLAG_COMPRESSED;
 	strcpy(f->description, "JPEG");
 	f->pixelformat = V4L2_PIX_FMT_JPEG;
@@ -550,8 +542,6 @@ static int zr364xx_vidioc_try_fmt_vid_ca
 		return -ENODEV;
 	cam = video_get_drvdata(vdev);
 
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
 		return -EINVAL;
 	if (f->fmt.pix.field != V4L2_FIELD_ANY &&
@@ -577,10 +567,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(
 		return -ENODEV;
 	cam = video_get_drvdata(vdev);
 
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
 	f->fmt.pix.field = V4L2_FIELD_NONE;
 	f->fmt.pix.width = cam->width;
@@ -602,8 +588,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(
 		return -ENODEV;
 	cam = video_get_drvdata(vdev);
 
-	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
 	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
 		return -EINVAL;
 	if (f->fmt.pix.field != V4L2_FIELD_ANY &&
diff -druNp linux-libre-2.6.29-gnu1/drivers/memstick/host/jmb38x_ms.c linux-libre-2.6.30-gnu1/drivers/memstick/host/jmb38x_ms.c
--- linux-libre-2.6.29-gnu1/drivers/memstick/host/jmb38x_ms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/memstick/host/jmb38x_ms.c	2009-06-09 23:05:27.000000000 -0400
@@ -877,7 +877,7 @@ static int jmb38x_ms_probe(struct pci_de
 	int pci_dev_busy = 0;
 	int rc, cnt;
 
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc)
 		return rc;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/message/fusion/mptbase.c linux-libre-2.6.30-gnu1/drivers/message/fusion/mptbase.c
--- linux-libre-2.6.29-gnu1/drivers/message/fusion/mptbase.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/message/fusion/mptbase.c	2009-06-09 23:05:27.000000000 -0400
@@ -1534,13 +1534,13 @@ mpt_mapresources(MPT_ADAPTER *ioc)
 
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
-	    && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
+	    && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
 		    ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
 		    ioc->name));
-	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
-	    && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
+	    && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
 		    ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
 		    ioc->name));
@@ -5934,7 +5934,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS
 
 	/* Initalize the timer
 	 */
-	init_timer(&pCfg->timer);
+	init_timer_on_stack(&pCfg->timer);
 	pCfg->timer.data = (unsigned long) ioc;
 	pCfg->timer.function = mpt_timer_expired;
 	pCfg->wait_done = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/message/fusion/mptsas.c linux-libre-2.6.30-gnu1/drivers/message/fusion/mptsas.c
--- linux-libre-2.6.29-gnu1/drivers/message/fusion/mptsas.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/message/fusion/mptsas.c	2009-06-09 23:05:27.000000000 -0400
@@ -2279,9 +2279,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER
 	mutex_lock(&ioc->sas_topology_mutex);
 	list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
 
-		if (port_info->phy_info &&
-		    (!(port_info->phy_info[0].identify.device_info &
-		    MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+		if (!(port_info->phy_info[0].identify.device_info &
+		    MPI_SAS_DEVICE_INFO_SMP_TARGET))
 			continue;
 
 		if (mptsas_sas_expander_pg0(ioc, &buffer,
diff -druNp linux-libre-2.6.29-gnu1/drivers/message/i2o/i2o_proc.c linux-libre-2.6.30-gnu1/drivers/message/i2o/i2o_proc.c
--- linux-libre-2.6.29-gnu1/drivers/message/i2o/i2o_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/message/i2o/i2o_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -2037,8 +2037,6 @@ static int __init i2o_proc_fs_create(voi
 	if (!i2o_proc_dir_root)
 		return -1;
 
-	i2o_proc_dir_root->owner = THIS_MODULE;
-
 	list_for_each_entry(c, &i2o_controllers, list)
 	    i2o_proc_iop_add(i2o_proc_dir_root, c);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/message/i2o/memory.c linux-libre-2.6.30-gnu1/drivers/message/i2o/memory.c
--- linux-libre-2.6.29-gnu1/drivers/message/i2o/memory.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/message/i2o/memory.c	2009-06-09 23:05:27.000000000 -0400
@@ -185,9 +185,9 @@ int i2o_dma_alloc(struct device *dev, st
 	int dma_64 = 0;
 
 	mutex_lock(&mem_lock);
-	if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+	if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_BIT_MASK(64))) {
 		dma_64 = 1;
-		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 			mutex_unlock(&mem_lock);
 			return -ENOMEM;
 		}
@@ -196,7 +196,7 @@ int i2o_dma_alloc(struct device *dev, st
 	addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL);
 
 	if ((sizeof(dma_addr_t) > 4) && dma_64)
-		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
 			printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
 	mutex_unlock(&mem_lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/message/i2o/pci.c linux-libre-2.6.30-gnu1/drivers/message/i2o/pci.c
--- linux-libre-2.6.29-gnu1/drivers/message/i2o/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/message/i2o/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -334,7 +334,7 @@ static int __devinit i2o_pci_probe(struc
 		return rc;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
 		       pci_name(pdev));
 		rc = -ENODEV;
@@ -397,7 +397,7 @@ static int __devinit i2o_pci_probe(struc
 		}
 #ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
 		if (sizeof(dma_addr_t) > 4) {
-			if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+			if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
 				printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
 				       c->name);
 			else {
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/da903x.c linux-libre-2.6.30-gnu1/drivers/mfd/da903x.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/da903x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/da903x.c	2009-06-09 23:05:27.000000000 -0400
@@ -413,7 +413,7 @@ static void da903x_irq_work(struct work_
 	enable_irq(chip->client->irq);
 }
 
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
 {
 	struct da903x_chip *chip = data;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/htc-pasic3.c linux-libre-2.6.30-gnu1/drivers/mfd/htc-pasic3.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/htc-pasic3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/htc-pasic3.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,18 +12,17 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <linux/ds1wm.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
 #include <linux/mfd/htc-pasic3.h>
 
 struct pasic3_data {
 	void __iomem *mapping;
 	unsigned int bus_shift;
-	struct platform_device *ds1wm_pdev;
-	struct platform_device *led_pdev;
 };
 
 #define REG_ADDR  5
@@ -65,46 +64,15 @@ EXPORT_SYMBOL(pasic3_read_register); /*
  * LEDs
  */
 
-static int led_device_add(struct device *pasic3_dev,
-				const struct pasic3_leds_machinfo *pdata)
-{
-	struct pasic3_data *asic = pasic3_dev->driver_data;
-	struct platform_device *pdev;
-	int ret;
-
-	pdev = platform_device_alloc("pasic3-led", -1);
-	if (!pdev) {
-		dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
-		return -ENOMEM;
-	}
-
-	ret = platform_device_add_data(pdev, pdata,
-					sizeof(struct pasic3_leds_machinfo));
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add LED platform data\n");
-		goto exit_pdev_put;
-	}
-
-	pdev->dev.parent = pasic3_dev;
-	ret = platform_device_add(pdev);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add LED platform device\n");
-		goto exit_pdev_put;
-	}
-
-	asic->led_pdev = pdev;
-	return 0;
-
-exit_pdev_put:
-	platform_device_put(pdev);
-	return ret;
-}
+static struct mfd_cell led_cell __initdata = {
+	.name = "leds-pasic3",
+};
 
 /*
  * DS1WM
  */
 
-static void ds1wm_enable(struct platform_device *pdev)
+static int ds1wm_enable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
 	int c;
@@ -113,9 +81,10 @@ static void ds1wm_enable(struct platform
 	pasic3_write_register(dev, 0x28, c & 0x7f);
 
 	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+	return 0;
 }
 
-static void ds1wm_disable(struct platform_device *pdev)
+static int ds1wm_disable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
 	int c;
@@ -124,56 +93,33 @@ static void ds1wm_disable(struct platfor
 	pasic3_write_register(dev, 0x28, c | 0x80);
 
 	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+	return 0;
 }
 
-static struct ds1wm_platform_data ds1wm_pdata = {
-	.bus_shift = 2,
-	.enable    = ds1wm_enable,
-	.disable   = ds1wm_disable,
+static struct ds1wm_driver_data ds1wm_pdata = {
+	.active_high = 0,
 };
 
-static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
-{
-	struct device *pasic3_dev = &pasic3_pdev->dev;
-	struct pasic3_data *asic = pasic3_dev->driver_data;
-	struct platform_device *pdev;
-	int ret;
-
-	pdev = platform_device_alloc("ds1wm", -1);
-	if (!pdev) {
-		dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
-		return -ENOMEM;
-	}
-
-	ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
-						pasic3_pdev->num_resources);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
-		goto exit_pdev_put;
-	}
-
-	ds1wm_pdata.bus_shift = asic->bus_shift;
-	ret = platform_device_add_data(pdev, &ds1wm_pdata,
-					sizeof(struct ds1wm_platform_data));
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
-		goto exit_pdev_put;
-	}
-
-	pdev->dev.parent = pasic3_dev;
-	ret = platform_device_add(pdev);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
-		goto exit_pdev_put;
-	}
-
-	asic->ds1wm_pdev = pdev;
-	return 0;
+static struct resource ds1wm_resources[] __initdata = {
+	[0] = {
+		.start  = 0,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0,
+		.end    = 0,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
 
-exit_pdev_put:
-	platform_device_put(pdev);
-	return ret;
-}
+static struct mfd_cell ds1wm_cell __initdata = {
+	.name          = "ds1wm",
+	.enable        = ds1wm_enable,
+	.disable       = ds1wm_disable,
+	.driver_data   = &ds1wm_pdata,
+	.num_resources = 2,
+	.resources     = ds1wm_resources,
+};
 
 static int __init pasic3_probe(struct platform_device *pdev)
 {
@@ -182,12 +128,27 @@ static int __init pasic3_probe(struct pl
 	struct pasic3_data *asic;
 	struct resource *r;
 	int ret;
+	int irq = 0;
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (r) {
+		ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+			(IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+		irq = r->start;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (r) {
+		ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+			(IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+		irq = r->start;
+	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r)
 		return -ENXIO;
 
-	if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
+	if (!request_mem_region(r->start, resource_size(r), "pasic3"))
 		return -EBUSY;
 
 	asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
@@ -196,24 +157,33 @@ static int __init pasic3_probe(struct pl
 
 	platform_set_drvdata(pdev, asic);
 
-	if (pdata && pdata->bus_shift)
-		asic->bus_shift = pdata->bus_shift;
-	else
-		asic->bus_shift = 2;
-
-	asic->mapping = ioremap(r->start, r->end - r->start + 1);
+	asic->mapping = ioremap(r->start, resource_size(r));
 	if (!asic->mapping) {
 		dev_err(dev, "couldn't ioremap PASIC3\n");
 		kfree(asic);
 		return -ENOMEM;
 	}
 
-	ret = ds1wm_device_add(pdev, asic->bus_shift);
-	if (ret < 0)
-		dev_warn(dev, "failed to register DS1WM\n");
+	/* calculate bus shift from mem resource */
+	asic->bus_shift = (resource_size(r) - 5) >> 3;
 
-	if (pdata->led_pdata) {
-		ret = led_device_add(dev, pdata->led_pdata);
+	if (pdata && pdata->clock_rate) {
+		ds1wm_pdata.clock_rate = pdata->clock_rate;
+		/* the first 5 PASIC3 registers control the DS1WM */
+		ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
+		ds1wm_cell.platform_data = &ds1wm_cell;
+		ds1wm_cell.data_size = sizeof(ds1wm_cell);
+		ret = mfd_add_devices(&pdev->dev, pdev->id,
+				&ds1wm_cell, 1, r, irq);
+		if (ret < 0)
+			dev_warn(dev, "failed to register DS1WM\n");
+	}
+
+	if (pdata && pdata->led_pdata) {
+		led_cell.driver_data = pdata->led_pdata;
+		led_cell.platform_data = &led_cell;
+		led_cell.data_size = sizeof(ds1wm_cell);
+		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
 		if (ret < 0)
 			dev_warn(dev, "failed to register LED device\n");
 	}
@@ -226,14 +196,11 @@ static int pasic3_remove(struct platform
 	struct pasic3_data *asic = platform_get_drvdata(pdev);
 	struct resource *r;
 
-	if (asic->led_pdev)
-		platform_device_unregister(asic->led_pdev);
-	if (asic->ds1wm_pdev)
-		platform_device_unregister(asic->ds1wm_pdev);
+	mfd_remove_devices(&pdev->dev);
 
 	iounmap(asic->mapping);
 	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));
 	kfree(asic);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/Kconfig linux-libre-2.6.30-gnu1/drivers/mfd/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/mfd/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -52,6 +52,7 @@ config HTC_EGPIO
 
 config HTC_PASIC3
 	tristate "HTC PASIC3 LED/DS1WM chip support"
+	select MFD_CORE
 	help
 	  This core driver provides register access for the LED/DS1WM
 	  chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -88,7 +89,7 @@ config MENELAUS
 	help
 	  If you say yes here you get support for the Texas Instruments
 	  TWL92330/Menelaus Power Management chip. This include voltage
-	  regulators, Dual slot memory card tranceivers, real-time clock
+	  regulators, Dual slot memory card transceivers, real-time clock
 	  and other features that are often used in portable devices like
 	  cell phones and PDAs.
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/mcp-core.c linux-libre-2.6.30-gnu1/drivers/mfd/mcp-core.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/mcp-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/mcp-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc);
 
 int mcp_host_register(struct mcp *mcp)
 {
-	strcpy(mcp->attached_device.bus_id, "mcp0");
+	dev_set_name(&mcp->attached_device, "mcp0");
 	return device_register(&mcp->attached_device);
 }
 EXPORT_SYMBOL(mcp_host_register);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/pcf50633-core.c linux-libre-2.6.30-gnu1/drivers/mfd/pcf50633-core.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/pcf50633-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/pcf50633-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/sysfs.h>
-#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -444,7 +443,7 @@ static irqreturn_t pcf50633_irq(int irq,
 	dev_dbg(pcf->dev, "pcf50633_irq\n");
 
 	get_device(pcf->dev);
-	disable_irq(pcf->irq);
+	disable_irq_nosync(pcf->irq);
 	schedule_work(&pcf->irq_work);
 
 	return IRQ_HANDLED;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/t7l66xb.c linux-libre-2.6.30-gnu1/drivers/mfd/t7l66xb.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/t7l66xb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/t7l66xb.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,7 +108,7 @@ static int t7l66xb_mmc_disable(struct pl
 
 /*--------------------------------------------------------------------------*/
 
-const static struct resource t7l66xb_mmc_resources[] = {
+static const struct resource t7l66xb_mmc_resources[] = {
 	{
 		.start = 0x800,
 		.end	= 0x9ff,
@@ -126,7 +126,7 @@ const static struct resource t7l66xb_mmc
 	},
 };
 
-const static struct resource t7l66xb_nand_resources[] = {
+static const struct resource t7l66xb_nand_resources[] = {
 	{
 		.start	= 0xc00,
 		.end	= 0xc07,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/tc6393xb.c linux-libre-2.6.30-gnu1/drivers/mfd/tc6393xb.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/tc6393xb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/tc6393xb.c	2009-06-09 23:05:27.000000000 -0400
@@ -172,7 +172,7 @@ static struct resource __devinitdata tc6
 	},
 };
 
-const static struct resource tc6393xb_ohci_resources[] = {
+static const struct resource tc6393xb_ohci_resources[] = {
 	{
 		.start	= 0x3000,
 		.end	= 0x31ff,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/twl4030-core.c linux-libre-2.6.30-gnu1/drivers/mfd/twl4030-core.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/twl4030-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/twl4030-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_dat
 
 	/* 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))
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/twl4030-irq.c linux-libre-2.6.30-gnu1/drivers/mfd/twl4030-irq.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/twl4030-irq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/twl4030-irq.c	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,7 @@ static int twl4030_irq_thread(void *data
 	long irq = (long)data;
 	struct irq_desc *desc = irq_to_desc(irq);
 	static unsigned i2c_errors;
-	const static unsigned max_i2c_errors = 100;
+	static const unsigned max_i2c_errors = 100;
 
 	if (!desc) {
 		pr_err("twl4030: Invalid IRQ: %ld\n", irq);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/ucb1x00-core.c linux-libre-2.6.30-gnu1/drivers/mfd/ucb1x00-core.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/ucb1x00-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/ucb1x00-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp
 
 	ucb->dev.class = &ucb1x00_class;
 	ucb->dev.parent = &mcp->attached_device;
-	strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id));
+	dev_set_name(&ucb->dev, "ucb1x00");
 
 	spin_lock_init(&ucb->lock);
 	spin_lock_init(&ucb->io_lock);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mfd/wm8350-core.c linux-libre-2.6.30-gnu1/drivers/mfd/wm8350-core.c
--- linux-libre-2.6.29-gnu1/drivers/mfd/wm8350-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mfd/wm8350-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,10 +79,6 @@ static int wm8350_phys_read(struct wm835
 		/* Cache is CPU endian */
 		dest[i - reg] = be16_to_cpu(dest[i - reg]);
 
-		/* Satisfy non-volatile bits from cache */
-		dest[i - reg] &= wm8350_reg_io_map[i].vol;
-		dest[i - reg] |= wm8350->reg_cache[i];
-
 		/* Mask out non-readable bits */
 		dest[i - reg] &= wm8350_reg_io_map[i].readable;
 	}
@@ -182,9 +178,6 @@ static int wm8350_write(struct wm8350 *w
 			(wm8350->reg_cache[i] & ~wm8350_reg_io_map[i].writable)
 			| src[i - reg];
 
-		/* Don't store volatile bits */
-		wm8350->reg_cache[i] &= ~wm8350_reg_io_map[i].vol;
-
 		src[i - reg] = cpu_to_be16(src[i - reg]);
 	}
 
@@ -1111,7 +1104,7 @@ int wm8350_read_auxadc(struct wm8350 *wm
 	do {
 		schedule_timeout_interruptible(1);
 		reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
-	} while (--tries && (reg & WM8350_AUXADC_POLL));
+	} while ((reg & WM8350_AUXADC_POLL) && --tries);
 
 	if (!tries)
 		dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1238,7 +1231,7 @@ static int wm8350_create_cache(struct wm
 	}
 
 	wm8350->reg_cache =
-	    kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
+		kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
 	if (wm8350->reg_cache == NULL)
 		return -ENOMEM;
 
@@ -1246,19 +1239,21 @@ static int wm8350_create_cache(struct wm
 	 * a PMIC so the device many not be in a virgin state and we
 	 * can't rely on the silicon values.
 	 */
+	ret = wm8350->read_dev(wm8350, 0,
+			       sizeof(u16) * (WM8350_MAX_REGISTER + 1),
+			       wm8350->reg_cache);
+	if (ret < 0) {
+		dev_err(wm8350->dev,
+			"failed to read initial cache values\n");
+		goto out;
+	}
+
+	/* Mask out uncacheable/unreadable bits and the audio. */
 	for (i = 0; i < WM8350_MAX_REGISTER; i++) {
-		/* audio register range */
 		if (wm8350_reg_io_map[i].readable &&
 		    (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
-			ret = wm8350->read_dev(wm8350, i, 2, (char *)&value);
-			if (ret < 0) {
-				dev_err(wm8350->dev,
-				       "failed to read initial cache value\n");
-				goto out;
-			}
-			value = be16_to_cpu(value);
+			value = be16_to_cpu(wm8350->reg_cache[i]);
 			value &= wm8350_reg_io_map[i].readable;
-			value &= ~wm8350_reg_io_map[i].vol;
 			wm8350->reg_cache[i] = value;
 		} else
 			wm8350->reg_cache[i] = reg_map[i];
@@ -1435,7 +1430,21 @@ int wm8350_device_init(struct wm8350 *wm
 	mutex_init(&wm8350->irq_mutex);
 	INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
 	if (irq) {
-		ret = request_irq(irq, wm8350_irq, 0,
+		int flags = 0;
+
+		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_irq(irq, wm8350_irq, flags,
 				  "wm8350", wm8350);
 		if (ret != 0) {
 			dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/eeprom/at24.c linux-libre-2.6.30-gnu1/drivers/misc/eeprom/at24.c
--- linux-libre-2.6.29-gnu1/drivers/misc/eeprom/at24.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/eeprom/at24.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,7 @@
 
 struct at24_data {
 	struct at24_platform_data chip;
+	struct memory_accessor macc;
 	bool use_smbus;
 
 	/*
@@ -225,14 +226,11 @@ static ssize_t at24_eeprom_read(struct a
 		return status;
 }
 
-static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+static ssize_t at24_read(struct at24_data *at24,
 		char *buf, loff_t off, size_t count)
 {
-	struct at24_data *at24;
 	ssize_t retval = 0;
 
-	at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
 	if (unlikely(!count))
 		return count;
 
@@ -262,12 +260,14 @@ static ssize_t at24_bin_read(struct kobj
 	return retval;
 }
 
+static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t off, size_t count)
+{
+	struct at24_data *at24;
 
-/*
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
- * eeprom data. For example, it might hold a board's Ethernet address, or
- * board-specific calibration data generated on the manufacturing floor.
- */
+	at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+	return at24_read(at24, buf, off, count);
+}
 
 
 /*
@@ -278,7 +278,7 @@ static ssize_t at24_bin_read(struct kobj
  * We only use page mode writes; the alternative is sloooow. This routine
  * writes at most one page.
  */
-static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
+static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
 		unsigned offset, size_t count)
 {
 	struct i2c_client *client;
@@ -347,14 +347,11 @@ static ssize_t at24_eeprom_write(struct
 	return -ETIMEDOUT;
 }
 
-static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
-		char *buf, loff_t off, size_t count)
+static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off,
+			  size_t count)
 {
-	struct at24_data *at24;
 	ssize_t retval = 0;
 
-	at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
 	if (unlikely(!count))
 		return count;
 
@@ -384,6 +381,39 @@ static ssize_t at24_bin_write(struct kob
 	return retval;
 }
 
+static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
+		char *buf, loff_t off, size_t count)
+{
+	struct at24_data *at24;
+
+	at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+	return at24_write(at24, buf, off, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This lets other kernel code access the eeprom data. For example, it
+ * might hold a board's Ethernet address, or board-specific calibration
+ * data generated on the manufacturing floor.
+ */
+
+static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
+			 off_t offset, size_t count)
+{
+	struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+	return at24_read(at24, buf, offset, count);
+}
+
+static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf,
+			  off_t offset, size_t count)
+{
+	struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+	return at24_write(at24, buf, offset, count);
+}
+
 /*-------------------------------------------------------------------------*/
 
 static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -413,6 +443,9 @@ static int at24_probe(struct i2c_client
 		 * is recommended anyhow.
 		 */
 		chip.page_size = 1;
+
+		chip.setup = NULL;
+		chip.context = NULL;
 	}
 
 	if (!is_power_of_2(chip.byte_len))
@@ -463,6 +496,8 @@ static int at24_probe(struct i2c_client
 	at24->bin.read = at24_bin_read;
 	at24->bin.size = chip.byte_len;
 
+	at24->macc.read = at24_macc_read;
+
 	writable = !(chip.flags & AT24_FLAG_READONLY);
 	if (writable) {
 		if (!use_smbus || i2c_check_functionality(client->adapter,
@@ -470,6 +505,8 @@ static int at24_probe(struct i2c_client
 
 			unsigned write_max = chip.page_size;
 
+			at24->macc.write = at24_macc_write;
+
 			at24->bin.write = at24_bin_write;
 			at24->bin.attr.mode |= S_IWUSR;
 
@@ -520,6 +557,10 @@ static int at24_probe(struct i2c_client
 		at24->write_max,
 		use_smbus ? ", use_smbus" : "");
 
+	/* export data to kernel code */
+	if (chip.setup)
+		chip.setup(&at24->macc, chip.context);
+
 	return 0;
 
 err_clients:
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/eeprom/at25.c linux-libre-2.6.30-gnu1/drivers/misc/eeprom/at25.c
--- linux-libre-2.6.29-gnu1/drivers/misc/eeprom/at25.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/eeprom/at25.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,7 @@
 
 struct at25_data {
 	struct spi_device	*spi;
+	struct memory_accessor	mem;
 	struct mutex		lock;
 	struct spi_eeprom	chip;
 	struct bin_attribute	bin;
@@ -75,6 +76,13 @@ at25_ee_read(
 	struct spi_transfer	t[2];
 	struct spi_message	m;
 
+	if (unlikely(offset >= at25->bin.size))
+		return 0;
+	if ((offset + count) > at25->bin.size)
+		count = at25->bin.size - offset;
+	if (unlikely(!count))
+		return count;
+
 	cp = command;
 	*cp++ = AT25_READ;
 
@@ -127,25 +135,26 @@ at25_bin_read(struct kobject *kobj, stru
 	dev = container_of(kobj, struct device, kobj);
 	at25 = dev_get_drvdata(dev);
 
-	if (unlikely(off >= at25->bin.size))
-		return 0;
-	if ((off + count) > at25->bin.size)
-		count = at25->bin.size - off;
-	if (unlikely(!count))
-		return count;
-
 	return at25_ee_read(at25, buf, off, count);
 }
 
 
 static ssize_t
-at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
+at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
+	      size_t count)
 {
 	ssize_t			status = 0;
 	unsigned		written = 0;
 	unsigned		buf_size;
 	u8			*bounce;
 
+	if (unlikely(off >= at25->bin.size))
+		return -EFBIG;
+	if ((off + count) > at25->bin.size)
+		count = at25->bin.size - off;
+	if (unlikely(!count))
+		return count;
+
 	/* Temp buffer starts with command and address */
 	buf_size = at25->chip.page_size;
 	if (buf_size > io_limit)
@@ -253,18 +262,31 @@ at25_bin_write(struct kobject *kobj, str
 	dev = container_of(kobj, struct device, kobj);
 	at25 = dev_get_drvdata(dev);
 
-	if (unlikely(off >= at25->bin.size))
-		return -EFBIG;
-	if ((off + count) > at25->bin.size)
-		count = at25->bin.size - off;
-	if (unlikely(!count))
-		return count;
-
 	return at25_ee_write(at25, buf, off, count);
 }
 
 /*-------------------------------------------------------------------------*/
 
+/* Let in-kernel code access the eeprom data. */
+
+static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
+			 off_t offset, size_t count)
+{
+	struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+	return at25_ee_read(at25, buf, offset, count);
+}
+
+static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
+			  off_t offset, size_t count)
+{
+	struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+	return at25_ee_write(at25, buf, offset, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
 static int at25_probe(struct spi_device *spi)
 {
 	struct at25_data	*at25 = NULL;
@@ -317,6 +339,10 @@ static int at25_probe(struct spi_device
 	at25->addrlen = addrlen;
 
 	/* Export the EEPROM bytes through sysfs, since that's convenient.
+	 * And maybe to other kernel code; it might hold a board's Ethernet
+	 * address, or board-specific calibration data generated on the
+	 * manufacturing floor.
+	 *
 	 * Default to root-only access to the data; EEPROMs often hold data
 	 * that's sensitive for read and/or write, like ethernet addresses,
 	 * security codes, board-specific manufacturing calibrations, etc.
@@ -324,17 +350,22 @@ static int at25_probe(struct spi_device
 	at25->bin.attr.name = "eeprom";
 	at25->bin.attr.mode = S_IRUSR;
 	at25->bin.read = at25_bin_read;
+	at25->mem.read = at25_mem_read;
 
 	at25->bin.size = at25->chip.byte_len;
 	if (!(chip->flags & EE_READONLY)) {
 		at25->bin.write = at25_bin_write;
 		at25->bin.attr.mode |= S_IWUSR;
+		at25->mem.write = at25_mem_write;
 	}
 
 	err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
 	if (err)
 		goto fail;
 
+	if (chip->setup)
+		chip->setup(&at25->mem, chip->context);
+
 	dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
 		(at25->bin.size < 1024)
 			? at25->bin.size
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/eeprom/Kconfig linux-libre-2.6.30-gnu1/drivers/misc/eeprom/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/misc/eeprom/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/eeprom/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@ menu "EEPROM support"
 
 config EEPROM_AT24
 	tristate "I2C EEPROMs from most vendors"
-	depends on I2C && SYSFS && EXPERIMENTAL
+	depends on I2C && SYSFS
 	help
 	  Enable this driver to get read/write support to most I2C EEPROMs,
 	  after you configure the driver to know about each EEPROM on
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/enclosure.c linux-libre-2.6.30-gnu1/drivers/misc/enclosure.c
--- linux-libre-2.6.29-gnu1/drivers/misc/enclosure.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/enclosure.c	2009-06-09 23:05:27.000000000 -0400
@@ -119,7 +119,7 @@ enclosure_register(struct device *dev, c
 	edev->edev.class = &enclosure_class;
 	edev->edev.parent = get_device(dev);
 	edev->cb = cb;
-	dev_set_name(&edev->edev, name);
+	dev_set_name(&edev->edev, "%s", name);
 	err = device_register(&edev->edev);
 	if (err)
 		goto err;
@@ -255,8 +255,8 @@ enclosure_component_register(struct encl
 	ecomp->number = number;
 	cdev = &ecomp->cdev;
 	cdev->parent = get_device(&edev->edev);
-	if (name)
-		dev_set_name(cdev, name);
+	if (name && name[0])
+		dev_set_name(cdev, "%s", name);
 	else
 		dev_set_name(cdev, "%u", number);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/hpilo.c linux-libre-2.6.30-gnu1/drivers/misc/hpilo.c
--- linux-libre-2.6.29-gnu1/drivers/misc/hpilo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/hpilo.c	2009-06-09 23:05:27.000000000 -0400
@@ -209,7 +209,7 @@ static void ilo_ccb_close(struct pci_dev
 	/* give iLO some time to process stop request */
 	for (retries = MAX_WAIT; retries > 0; retries--) {
 		doorbell_set(driver_ccb);
-		udelay(1);
+		udelay(WAIT_TIME);
 		if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
 		    &&
 		    !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
@@ -312,7 +312,7 @@ static int ilo_ccb_open(struct ilo_hwinf
 	for (i = MAX_WAIT; i > 0; i--) {
 		if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
 			break;
-		udelay(1);
+		udelay(WAIT_TIME);
 	}
 
 	if (i) {
@@ -759,7 +759,7 @@ static void __exit ilo_exit(void)
 	class_destroy(ilo_class);
 }
 
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.1");
 MODULE_ALIAS(ILO_NAME);
 MODULE_DESCRIPTION(ILO_NAME);
 MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/hpilo.h linux-libre-2.6.30-gnu1/drivers/misc/hpilo.h
--- linux-libre-2.6.29-gnu1/drivers/misc/hpilo.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/hpilo.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,8 +19,12 @@
 #define MAX_ILO_DEV	1
 /* max number of files */
 #define MAX_OPEN	(MAX_CCB * MAX_ILO_DEV)
+/* total wait time in usec */
+#define MAX_WAIT_TIME	10000
+/* per spin wait time in usec */
+#define WAIT_TIME	10
 /* spin counter for open/close delay */
-#define MAX_WAIT	10000
+#define MAX_WAIT	(MAX_WAIT_TIME / WAIT_TIME)
 
 /*
  * Per device, used to track global memory allocations.
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/isl29003.c linux-libre-2.6.30-gnu1/drivers/misc/isl29003.c
--- linux-libre-2.6.29-gnu1/drivers/misc/isl29003.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/misc/isl29003.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,475 @@
+/*
+ *  isl29003.c - Linux kernel module for
+ * 	Intersil ISL29003 ambient light sensor
+ *
+ *  See file:Documentation/misc-devices/isl29003
+ *
+ *  Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  Based on code written by
+ *  	Rodolfo Giometti <giometti@linux.it>
+ *  	Eurotech S.p.A. <info@eurotech.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
+ *  (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/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ISL29003_DRV_NAME	"isl29003"
+#define DRIVER_VERSION		"1.0"
+
+#define ISL29003_REG_COMMAND		0x00
+#define ISL29003_ADC_ENABLED		(1 << 7)
+#define ISL29003_ADC_PD			(1 << 6)
+#define ISL29003_TIMING_INT		(1 << 5)
+#define ISL29003_MODE_SHIFT		(2)
+#define ISL29003_MODE_MASK		(0x3 << ISL29003_MODE_SHIFT)
+#define ISL29003_RES_SHIFT		(0)
+#define ISL29003_RES_MASK		(0x3 << ISL29003_RES_SHIFT)
+
+#define ISL29003_REG_CONTROL		0x01
+#define ISL29003_INT_FLG		(1 << 5)
+#define ISL29003_RANGE_SHIFT		(2)
+#define ISL29003_RANGE_MASK		(0x3 << ISL29003_RANGE_SHIFT)
+#define ISL29003_INT_PERSISTS_SHIFT	(0)
+#define ISL29003_INT_PERSISTS_MASK	(0xf << ISL29003_INT_PERSISTS_SHIFT)
+
+#define ISL29003_REG_IRQ_THRESH_HI	0x02
+#define ISL29003_REG_IRQ_THRESH_LO	0x03
+#define ISL29003_REG_LSB_SENSOR		0x04
+#define ISL29003_REG_MSB_SENSOR		0x05
+#define ISL29003_REG_LSB_TIMER		0x06
+#define ISL29003_REG_MSB_TIMER		0x07
+
+#define ISL29003_NUM_CACHABLE_REGS	4
+
+struct isl29003_data {
+	struct i2c_client *client;
+	struct mutex lock;
+	u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
+	u8 power_state_before_suspend;
+};
+
+static int gain_range[] = {
+	1000, 4000, 16000, 64000
+};
+
+/*
+ * register access helpers
+ */
+
+static int __isl29003_read_reg(struct i2c_client *client,
+			       u32 reg, u8 mask, u8 shift)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	return (data->reg_cache[reg] & mask) >> shift;
+}
+
+static int __isl29003_write_reg(struct i2c_client *client,
+				u32 reg, u8 mask, u8 shift, u8 val)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int ret = 0;
+	u8 tmp;
+
+	if (reg >= ISL29003_NUM_CACHABLE_REGS)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+
+	tmp = data->reg_cache[reg];
+	tmp &= ~mask;
+	tmp |= val << shift;
+
+	ret = i2c_smbus_write_byte_data(client, reg, tmp);
+	if (!ret)
+		data->reg_cache[reg] = tmp;
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+/*
+ * internally used functions
+ */
+
+/* range */
+static int isl29003_get_range(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
+		ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
+}
+
+static int isl29003_set_range(struct i2c_client *client, int range)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
+		ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
+}
+
+/* resolution */
+static int isl29003_get_resolution(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_resolution(struct i2c_client *client, int res)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
+}
+
+/* mode */
+static int isl29003_get_mode(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_mode(struct i2c_client *client, int mode)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
+}
+
+/* power_state */
+static int isl29003_set_power_state(struct i2c_client *client, int state)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+				ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
+				state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
+}
+
+static int isl29003_get_power_state(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
+	return ~cmdreg & ISL29003_ADC_PD;
+}
+
+static int isl29003_get_adc_value(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int lsb, msb, range, bitdepth;
+
+	mutex_lock(&data->lock);
+	lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
+
+	if (lsb < 0) {
+		mutex_unlock(&data->lock);
+		return lsb;
+	}
+
+	msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
+	mutex_unlock(&data->lock);
+
+	if (msb < 0)
+		return msb;
+
+	range = isl29003_get_range(client);
+	bitdepth = (4 - isl29003_get_resolution(client)) * 4;
+	return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
+}
+
+/*
+ * sysfs layer
+ */
+
+/* range */
+static ssize_t isl29003_show_range(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%i\n", isl29003_get_range(client));
+}
+
+static ssize_t isl29003_store_range(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+		return -EINVAL;
+
+	ret = isl29003_set_range(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
+		   isl29003_show_range, isl29003_store_range);
+
+
+/* resolution */
+static ssize_t isl29003_show_resolution(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_resolution(client));
+}
+
+static ssize_t isl29003_store_resolution(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+		return -EINVAL;
+
+	ret = isl29003_set_resolution(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
+		   isl29003_show_resolution, isl29003_store_resolution);
+
+/* mode */
+static ssize_t isl29003_show_mode(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_mode(client));
+}
+
+static ssize_t isl29003_store_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
+		return -EINVAL;
+
+	ret = isl29003_set_mode(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+		   isl29003_show_mode, isl29003_store_mode);
+
+
+/* power state */
+static ssize_t isl29003_show_power_state(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_power_state(client));
+}
+
+static ssize_t isl29003_store_power_state(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
+		return -EINVAL;
+
+	ret = isl29003_set_power_state(client, val);
+	return ret ? ret : count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+		   isl29003_show_power_state, isl29003_store_power_state);
+
+
+/* lux */
+static ssize_t isl29003_show_lux(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	/* No LUX data if not operational */
+	if (!isl29003_get_power_state(client))
+		return -EBUSY;
+
+	return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
+}
+
+static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
+
+static struct attribute *isl29003_attributes[] = {
+	&dev_attr_range.attr,
+	&dev_attr_resolution.attr,
+	&dev_attr_mode.attr,
+	&dev_attr_power_state.attr,
+	&dev_attr_lux.attr,
+	NULL
+};
+
+static const struct attribute_group isl29003_attr_group = {
+	.attrs = isl29003_attributes,
+};
+
+static int isl29003_init_client(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int i;
+
+	/* read all the registers once to fill the cache.
+	 * if one of the reads fails, we consider the init failed */
+	for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
+		int v = i2c_smbus_read_byte_data(client, i);
+		if (v < 0)
+			return -ENODEV;
+
+		data->reg_cache[i] = v;
+	}
+
+	/* set defaults */
+	isl29003_set_range(client, 0);
+	isl29003_set_resolution(client, 0);
+	isl29003_set_mode(client, 0);
+	isl29003_set_power_state(client, 0);
+
+	return 0;
+}
+
+/*
+ * I2C layer
+ */
+
+static int __devinit isl29003_probe(struct i2c_client *client,
+				    const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct isl29003_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+		return -EIO;
+
+	data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->client = client;
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->lock);
+
+	/* initialize the ISL29003 chip */
+	err = isl29003_init_client(client);
+	if (err)
+		goto exit_kfree;
+
+	/* register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
+	if (err)
+		goto exit_kfree;
+
+	dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
+	return 0;
+
+exit_kfree:
+	kfree(data);
+	return err;
+}
+
+static int __devexit isl29003_remove(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
+	isl29003_set_power_state(client, 0);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+
+	data->power_state_before_suspend = isl29003_get_power_state(client);
+	return isl29003_set_power_state(client, 0);
+}
+
+static int isl29003_resume(struct i2c_client *client)
+{
+	int i;
+	struct isl29003_data *data = i2c_get_clientdata(client);
+
+	/* restore registers from cache */
+	for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
+		if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+			return -EIO;
+
+	return isl29003_set_power_state(client,
+		data->power_state_before_suspend);
+}
+
+#else
+#define isl29003_suspend	NULL
+#define isl29003_resume		NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id isl29003_id[] = {
+	{ "isl29003", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, isl29003_id);
+
+static struct i2c_driver isl29003_driver = {
+	.driver = {
+		.name	= ISL29003_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.suspend = isl29003_suspend,
+	.resume	= isl29003_resume,
+	.probe	= isl29003_probe,
+	.remove	= __devexit_p(isl29003_remove),
+	.id_table = isl29003_id,
+};
+
+static int __init isl29003_init(void)
+{
+	return i2c_add_driver(&isl29003_driver);
+}
+
+static void __exit isl29003_exit(void)
+{
+	i2c_del_driver(&isl29003_driver);
+}
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29003_init);
+module_exit(isl29003_exit);
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/Kconfig linux-libre-2.6.30-gnu1/drivers/misc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/misc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -18,8 +18,8 @@ config ATMEL_PWM
 	depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
 	help
 	  This option enables device driver support for the PWM channels
-	  on certain Atmel prcoessors.  Pulse Width Modulation is used for
-	  purposes including software controlled power-efficent backlights
+	  on certain Atmel processors.  Pulse Width Modulation is used for
+	  purposes including software controlled power-efficient backlights
 	  on LCD displays, motor control, and waveform generation.
 
 config ATMEL_TCLIB
@@ -142,7 +142,7 @@ config ATMEL_SSC
 	tristate "Device driver for Atmel SSC peripheral"
 	depends on AVR32 || ARCH_AT91
 	---help---
-	  This option enables device driver support for Atmel Syncronized
+	  This option enables device driver support for Atmel Synchronized
 	  Serial Communication peripheral (SSC).
 
 	  The SSC peripheral supports a wide variety of serial frame based
@@ -162,10 +162,10 @@ config ENCLOSURE_SERVICES
 config SGI_XP
 	tristate "Support communication between SGI SSIs"
 	depends on NET
-	depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_64) && SMP
+	depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
 	select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
 	select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
-	select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
+	select SGI_GRU if X86_64 && SMP
 	---help---
 	  An SGI machine can be divided into multiple Single System
 	  Images which act independently of each other and have
@@ -189,7 +189,7 @@ config HP_ILO
 
 config SGI_GRU
 	tristate "SGI GRU driver"
-	depends on (X86_64 || IA64_SGI_UV || IA64_GENERIC) && SMP
+	depends on X86_UV && SMP
 	default n
 	select MMU_NOTIFIER
 	---help---
@@ -223,6 +223,16 @@ config DELL_LAPTOP
 	This driver adds support for rfkill and backlight control to Dell
 	laptops.
 
+config ISL29003
+	tristate "Intersil ISL29003 ambient light sensor"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here you get support for the Intersil ISL29003
+	  ambient light sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called isl29003.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/Makefile linux-libre-2.6.30-gnu1/drivers/misc/Makefile
--- linux-libre-2.6.29-gnu1/drivers/misc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -18,5 +18,6 @@ obj-$(CONFIG_KGDB_TESTS)	+= kgdbts.o
 obj-$(CONFIG_SGI_XP)		+= sgi-xp/
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
+obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-y				+= eeprom/
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grufault.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grufault.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grufault.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grufault.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/security.h>
 #include <asm/pgtable.h>
 #include "gru.h"
 #include "grutables.h"
@@ -266,6 +267,44 @@ err:
 	return 1;
 }
 
+static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr,
+		    int write, int atomic, unsigned long *gpa, int *pageshift)
+{
+	struct mm_struct *mm = gts->ts_mm;
+	struct vm_area_struct *vma;
+	unsigned long paddr;
+	int ret, ps;
+
+	vma = find_vma(mm, vaddr);
+	if (!vma)
+		goto inval;
+
+	/*
+	 * Atomic lookup is faster & usually works even if called in non-atomic
+	 * context.
+	 */
+	rmb();	/* Must/check ms_range_active before loading PTEs */
+	ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &ps);
+	if (ret) {
+		if (atomic)
+			goto upm;
+		if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, &ps))
+			goto inval;
+	}
+	if (is_gru_paddr(paddr))
+		goto inval;
+	paddr = paddr & ~((1UL << ps) - 1);
+	*gpa = uv_soc_phys_ram_to_gpa(paddr);
+	*pageshift = ps;
+	return 0;
+
+inval:
+	return -1;
+upm:
+	return -2;
+}
+
+
 /*
  * Drop a TLB entry into the GRU. The fault is described by info in an TFH.
  *	Input:
@@ -280,10 +319,8 @@ static int gru_try_dropin(struct gru_thr
 			  struct gru_tlb_fault_handle *tfh,
 			  unsigned long __user *cb)
 {
-	struct mm_struct *mm = gts->ts_mm;
-	struct vm_area_struct *vma;
-	int pageshift, asid, write, ret;
-	unsigned long paddr, gpa, vaddr;
+	int pageshift = 0, asid, write, ret, atomic = !cb;
+	unsigned long gpa = 0, vaddr = 0;
 
 	/*
 	 * NOTE: The GRU contains magic hardware that eliminates races between
@@ -317,28 +354,19 @@ static int gru_try_dropin(struct gru_thr
 	if (atomic_read(&gts->ts_gms->ms_range_active))
 		goto failactive;
 
-	vma = find_vma(mm, vaddr);
-	if (!vma)
+	ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
+	if (ret == -1)
 		goto failinval;
+	if (ret == -2)
+		goto failupm;
 
-	/*
-	 * Atomic lookup is faster & usually works even if called in non-atomic
-	 * context.
-	 */
-	rmb();	/* Must/check ms_range_active before loading PTEs */
-	ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
-	if (ret) {
-		if (!cb)
+	if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
+		gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
+		if (atomic || !gru_update_cch(gts, 0)) {
+			gts->ts_force_cch_reload = 1;
 			goto failupm;
-		if (non_atomic_pte_lookup(vma, vaddr, write, &paddr,
-					  &pageshift))
-			goto failinval;
+		}
 	}
-	if (is_gru_paddr(paddr))
-		goto failinval;
-
-	paddr = paddr & ~((1UL << pageshift) - 1);
-	gpa = uv_soc_phys_ram_to_gpa(paddr);
 	gru_cb_set_istatus_active(cb);
 	tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
 			  GRU_PAGESIZE(pageshift));
@@ -368,6 +396,7 @@ failupm:
 
 failfmm:
 	/* FMM state on UPM call */
+	gru_flush_cache(tfh);
 	STAT(tlb_dropin_fail_fmm);
 	gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
 	return 0;
@@ -448,6 +477,7 @@ irqreturn_t gru_intr(int irq, void *dev_
 			up_read(&gts->ts_mm->mmap_sem);
 		} else {
 			tfh_user_polling_mode(tfh);
+			STAT(intr_mm_lock_failed);
 		}
 	}
 	return IRQ_HANDLED;
@@ -497,10 +527,8 @@ int gru_handle_user_call_os(unsigned lon
 	if (!gts)
 		return -EINVAL;
 
-	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
-		ret = -EINVAL;
+	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
@@ -508,6 +536,20 @@ int gru_handle_user_call_os(unsigned lon
 	 * 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;
+	}
+
+	/*
+	 * CCH may contain stale data if ts_force_cch_reload is set.
+	 */
+	if (gts->ts_gru && gts->ts_force_cch_reload) {
+		gru_update_cch(gts, 0);
+		gts->ts_force_cch_reload = 0;
+	}
+
 	ret = -EAGAIN;
 	cbrnum = thread_cbr_number(gts, ucbnum);
 	if (gts->ts_force_unload) {
@@ -541,11 +583,13 @@ int gru_get_exception_detail(unsigned lo
 	if (!gts)
 		return -EINVAL;
 
-	if (gts->ts_gru) {
-		ucbnum = get_cb_number((void *)excdet.cb);
+	ucbnum = get_cb_number((void *)excdet.cb);
+	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
+		ret = -EINVAL;
+	} else if (gts->ts_gru) {
 		cbrnum = thread_cbr_number(gts, ucbnum);
 		cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
-		prefetchw(cbe);		/* Harmless on hardware, required for emulator */
+		prefetchw(cbe);/* Harmless on hardware, required for emulator */
 		excdet.opc = cbe->opccpy;
 		excdet.exopc = cbe->exopccpy;
 		excdet.ecause = cbe->ecause;
@@ -567,6 +611,31 @@ int gru_get_exception_detail(unsigned lo
 /*
  * User request to unload a context. Content is saved for possible reload.
  */
+static int gru_unload_all_contexts(void)
+{
+	struct gru_thread_state *gts;
+	struct gru_state *gru;
+	int gid, ctxnum;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	foreach_gid(gid) {
+		gru = GID_TO_GRU(gid);
+		spin_lock(&gru->gs_lock);
+		for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
+			gts = gru->gs_gts[ctxnum];
+			if (gts && mutex_trylock(&gts->ts_ctxlock)) {
+				spin_unlock(&gru->gs_lock);
+				gru_unload_context(gts, 1);
+				gru_unlock_gts(gts);
+				spin_lock(&gru->gs_lock);
+			}
+		}
+		spin_unlock(&gru->gs_lock);
+	}
+	return 0;
+}
+
 int gru_user_unload_context(unsigned long arg)
 {
 	struct gru_thread_state *gts;
@@ -578,6 +647,9 @@ int gru_user_unload_context(unsigned lon
 
 	gru_dbg(grudev, "gseg 0x%lx\n", req.gseg);
 
+	if (!req.gseg)
+		return gru_unload_all_contexts();
+
 	gts = gru_find_lock_gts(req.gseg);
 	if (!gts)
 		return -EINVAL;
@@ -609,7 +681,7 @@ int gru_user_flush_tlb(unsigned long arg
 	if (!gts)
 		return -EINVAL;
 
-	gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.vaddr + req.len);
+	gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len);
 	gru_unlock_gts(gts);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grufile.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grufile.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grufile.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grufile.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,28 +36,18 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
+#include <asm/uv/uv.h>
 #include "gru.h"
 #include "grulib.h"
 #include "grutables.h"
 
-#if defined CONFIG_X86_64
-#include <asm/genapic.h>
-#include <asm/irq.h>
-#define IS_UV()		is_uv_system()
-#elif defined CONFIG_IA64
-#include <asm/system.h>
-#include <asm/sn/simulator.h>
-/* temp support for running on hardware simulator */
-#define IS_UV()		IS_MEDUSA() || ia64_platform_is("uv")
-#else
-#define IS_UV()		0
-#endif
-
 #include <asm/uv/uv_hub.h>
 #include <asm/uv/uv_mmrs.h>
 
 struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly;
-unsigned long gru_start_paddr, gru_end_paddr __read_mostly;
+unsigned long gru_start_paddr __read_mostly;
+unsigned long gru_end_paddr __read_mostly;
+unsigned int gru_max_gids __read_mostly;
 struct gru_stats_s gru_stats;
 
 /* Guaranteed user available resources on each node */
@@ -113,7 +103,7 @@ static int gru_file_mmap(struct file *fi
 		return -EPERM;
 
 	if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
-	    			vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
+				vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
 		return -EINVAL;
 
 	vma->vm_flags |=
@@ -285,8 +275,11 @@ static void gru_init_chiplet(struct gru_
 	gru->gs_blade_id = bid;
 	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);
-	gru_dbg(grudev, "bid %d, nid %d, gru %x, vaddr %p (0x%lx)\n",
+	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->gs_gru_base_paddr);
 	gru_kservices_init(gru);
@@ -307,7 +300,7 @@ static int gru_init_tables(unsigned long
 	for_each_online_node(nid) {
 		bid = uv_node_to_blade_id(nid);
 		pnode = uv_node_to_pnode(nid);
-		if (gru_base[bid])
+		if (bid < 0 || gru_base[bid])
 			continue;
 		page = alloc_pages_node(nid, GFP_KERNEL, order);
 		if (!page)
@@ -320,11 +313,11 @@ static int gru_init_tables(unsigned long
 		dsrbytes = 0;
 		cbrs = 0;
 		for (gru = gru_base[bid]->bs_grus, chip = 0;
-		     		chip < GRU_CHIPLETS_PER_BLADE;
+				chip < GRU_CHIPLETS_PER_BLADE;
 				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, bid, nid, chip);
+			gru_init_chiplet(gru, paddr, vaddr, nid, 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;
@@ -381,7 +374,7 @@ static int __init gru_init(void)
 	char id[10];
 	void *gru_start_vaddr;
 
-	if (!IS_UV())
+	if (!is_uv_system())
 		return 0;
 
 #if defined CONFIG_IA64
@@ -389,19 +382,19 @@ static int __init gru_init(void)
 #else
 	gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR) &
 				0x7fffffffffffUL;
-
 #endif
 	gru_start_vaddr = __va(gru_start_paddr);
-	gru_end_paddr = gru_start_paddr + MAX_NUMNODES * GRU_SIZE;
+	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 failures because
+		/* TODO: fix irq handling on x86. For now ignore failure because
 		 * interrupts are not required & not yet fully supported */
 		if (ret) {
-			printk("!!!WARNING: GRU ignoring request failure!!!\n");
+			printk(KERN_WARNING
+			       "!!!WARNING: GRU ignoring request failure!!!\n");
 			ret = 0;
 		}
 		if (ret) {
@@ -447,16 +440,19 @@ exit1:
 
 static void __exit gru_exit(void)
 {
-	int i, bid;
+	int i, bid, gid;
 	int order = get_order(sizeof(struct gru_state) *
 			      GRU_CHIPLETS_PER_BLADE);
 
-	if (!IS_UV())
+	if (!is_uv_system())
 		return;
 
 	for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
 		free_irq(IRQ_GRU + i, NULL);
 
+	foreach_gid(gid)
+		gru_kservices_exit(GID_TO_GRU(gid));
+
 	for (bid = 0; bid < GRU_MAX_BLADES; bid++)
 		free_pages((unsigned long)gru_base[bid], order);
 
@@ -481,7 +477,11 @@ struct vm_operations_struct gru_vm_ops =
 	.fault		= gru_fault,
 };
 
+#ifndef MODULE
 fs_initcall(gru_init);
+#else
+module_init(gru_init);
+#endif
 module_exit(gru_exit);
 
 module_param(gru_options, ulong, 0644);
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruhandles.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruhandles.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruhandles.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruhandles.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,183 @@
+/*
+ *              GRU KERNEL MCS INSTRUCTIONS
+ *
+ *  Copyright (c) 2008 Silicon Graphics, 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/kernel.h>
+#include "gru.h"
+#include "grulib.h"
+#include "grutables.h"
+
+/* 10 sec */
+#ifdef CONFIG_IA64
+#include <asm/processor.h>
+#define GRU_OPERATION_TIMEOUT	(((cycles_t) local_cpu_data->itc_freq)*10)
+#else
+#include <asm/tsc.h>
+#define GRU_OPERATION_TIMEOUT	((cycles_t) tsc_khz*10*1000)
+#endif
+
+/* Extract the status field from a kernel handle */
+#define GET_MSEG_HANDLE_STATUS(h)	(((*(unsigned long *)(h)) >> 16) & 3)
+
+struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
+static void update_mcs_stats(enum mcs_op op, unsigned long 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;
+}
+
+static void start_instruction(void *h)
+{
+	unsigned long *w0 = h;
+
+	wmb();		/* setting CMD bit must be last */
+	*w0 = *w0 | 1;
+	gru_flush_cache(h);
+}
+
+static int wait_instruction_complete(void *h, enum mcs_op opc)
+{
+	int status;
+	cycles_t start_time = get_cycles();
+
+	while (1) {
+		cpu_relax();
+		status = GET_MSEG_HANDLE_STATUS(h);
+		if (status != CCHSTATUS_ACTIVE)
+			break;
+		if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
+			panic("GRU %p is malfunctioning\n", h);
+	}
+	if (gru_options & OPT_STATS)
+		update_mcs_stats(opc, get_cycles() - start_time);
+	return status;
+}
+
+int cch_allocate(struct gru_context_configuration_handle *cch,
+		int asidval, int sizeavail, unsigned long cbrmap,
+		unsigned long dsrmap)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		cch->asid[i] = (asidval++);
+		cch->sizeavail[i] = sizeavail;
+	}
+	cch->dsr_allocation_map = dsrmap;
+	cch->cbr_allocation_map = cbrmap;
+	cch->opc = CCHOP_ALLOCATE;
+	start_instruction(cch);
+	return wait_instruction_complete(cch, cchop_allocate);
+}
+
+int cch_start(struct gru_context_configuration_handle *cch)
+{
+	cch->opc = CCHOP_START;
+	start_instruction(cch);
+	return wait_instruction_complete(cch, cchop_start);
+}
+
+int cch_interrupt(struct gru_context_configuration_handle *cch)
+{
+	cch->opc = CCHOP_INTERRUPT;
+	start_instruction(cch);
+	return wait_instruction_complete(cch, cchop_interrupt);
+}
+
+int cch_deallocate(struct gru_context_configuration_handle *cch)
+{
+	cch->opc = CCHOP_DEALLOCATE;
+	start_instruction(cch);
+	return wait_instruction_complete(cch, cchop_deallocate);
+}
+
+int cch_interrupt_sync(struct gru_context_configuration_handle
+				     *cch)
+{
+	cch->opc = CCHOP_INTERRUPT_SYNC;
+	start_instruction(cch);
+	return wait_instruction_complete(cch, cchop_interrupt_sync);
+}
+
+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)
+{
+	tgh->vaddr = vaddr;
+	tgh->asid = asid;
+	tgh->pagesize = pagesize;
+	tgh->n = n;
+	tgh->global = global;
+	tgh->vaddrmask = vaddrmask;
+	tgh->ctxbitmap = ctxbitmap;
+	tgh->opc = TGHOP_TLBINV;
+	start_instruction(tgh);
+	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)
+{
+	tfh->fillasid = asid;
+	tfh->fillvaddr = vaddr;
+	tfh->pfn = pfn;
+	tfh->dirty = dirty;
+	tfh->pagesize = pagesize;
+	tfh->opc = TFHOP_WRITE_ONLY;
+	start_instruction(tfh);
+}
+
+void tfh_write_restart(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 = paddr >> GRU_PADDR_SHIFT;
+	tfh->gaa = gaa;
+	tfh->dirty = dirty;
+	tfh->pagesize = pagesize;
+	tfh->opc = TFHOP_WRITE_RESTART;
+	start_instruction(tfh);
+}
+
+void tfh_restart(struct gru_tlb_fault_handle *tfh)
+{
+	tfh->opc = TFHOP_RESTART;
+	start_instruction(tfh);
+}
+
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
+{
+	tfh->opc = TFHOP_USER_POLLING_MODE;
+	start_instruction(tfh);
+}
+
+void tfh_exception(struct gru_tlb_fault_handle *tfh)
+{
+	tfh->opc = TFHOP_EXCEPTION;
+	start_instruction(tfh);
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruhandles.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruhandles.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruhandles.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruhandles.h	2009-06-09 23:05:27.000000000 -0400
@@ -489,170 +489,28 @@ enum gru_cbr_state {
  * 	 64m			26	8
  * 	...
  */
-#define GRU_PAGESIZE(sh)	((((sh) > 20 ? (sh) + 2: (sh)) >> 1) - 6)
+#define GRU_PAGESIZE(sh)	((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
 #define GRU_SIZEAVAIL(sh)	(1UL << GRU_PAGESIZE(sh))
 
 /* minimum TLB purge count to ensure a full purge */
 #define GRUMAXINVAL		1024UL
 
+int cch_allocate(struct gru_context_configuration_handle *cch,
+       int asidval, int sizeavail, unsigned long cbrmap, unsigned long dsrmap);
 
-/* Extract the status field from a kernel handle */
-#define GET_MSEG_HANDLE_STATUS(h)	(((*(unsigned long *)(h)) >> 16) & 3)
-
-static inline void start_instruction(void *h)
-{
-	unsigned long *w0 = h;
-
-	wmb();		/* setting CMD bit must be last */
-	*w0 = *w0 | 1;
-	gru_flush_cache(h);
-}
-
-static inline int wait_instruction_complete(void *h)
-{
-	int status;
-
-	do {
-		cpu_relax();
-		barrier();
-		status = GET_MSEG_HANDLE_STATUS(h);
-	} while (status == CCHSTATUS_ACTIVE);
-	return status;
-}
-
-#if defined CONFIG_IA64
-static inline void cch_allocate_set_asids(
-		  struct gru_context_configuration_handle *cch, int asidval)
-{
-	int i;
-
-	for (i = 0; i <= RGN_HPAGE; i++) {  /*  assume HPAGE is last region */
-		cch->asid[i] = (asidval++);
-#if 0
-		/* ZZZ hugepages not supported yet */
-		if (i == RGN_HPAGE)
-			cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
-		else
-#endif
-			cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
-	}
-}
-#elif defined CONFIG_X86_64
-static inline void cch_allocate_set_asids(
-		  struct gru_context_configuration_handle *cch, int asidval)
-{
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		cch->asid[i] = asidval++;
-		cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
-			GRU_SIZEAVAIL(21);
-	}
-}
-#endif
-
-static inline int cch_allocate(struct gru_context_configuration_handle *cch,
-			       int asidval, unsigned long cbrmap,
-			       unsigned long dsrmap)
-{
-	cch_allocate_set_asids(cch, asidval);
-	cch->dsr_allocation_map = dsrmap;
-	cch->cbr_allocation_map = cbrmap;
-	cch->opc = CCHOP_ALLOCATE;
-	start_instruction(cch);
-	return wait_instruction_complete(cch);
-}
-
-static inline int cch_start(struct gru_context_configuration_handle *cch)
-{
-	cch->opc = CCHOP_START;
-	start_instruction(cch);
-	return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt(struct gru_context_configuration_handle *cch)
-{
-	cch->opc = CCHOP_INTERRUPT;
-	start_instruction(cch);
-	return wait_instruction_complete(cch);
-}
-
-static inline int cch_deallocate(struct gru_context_configuration_handle *cch)
-{
-	cch->opc = CCHOP_DEALLOCATE;
-	start_instruction(cch);
-	return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt_sync(struct gru_context_configuration_handle
-				     *cch)
-{
-	cch->opc = CCHOP_INTERRUPT_SYNC;
-	start_instruction(cch);
-	return wait_instruction_complete(cch);
-}
-
-static inline 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)
-{
-	tgh->vaddr = vaddr;
-	tgh->asid = asid;
-	tgh->pagesize = pagesize;
-	tgh->n = n;
-	tgh->global = global;
-	tgh->vaddrmask = vaddrmask;
-	tgh->ctxbitmap = ctxbitmap;
-	tgh->opc = TGHOP_TLBINV;
-	start_instruction(tgh);
-	return wait_instruction_complete(tgh);
-}
-
-static inline void tfh_write_only(struct gru_tlb_fault_handle *tfh,
-				  unsigned long pfn, unsigned long vaddr,
-				  int asid, int dirty, int pagesize)
-{
-	tfh->fillasid = asid;
-	tfh->fillvaddr = vaddr;
-	tfh->pfn = pfn;
-	tfh->dirty = dirty;
-	tfh->pagesize = pagesize;
-	tfh->opc = TFHOP_WRITE_ONLY;
-	start_instruction(tfh);
-}
-
-static inline void tfh_write_restart(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 = paddr >> GRU_PADDR_SHIFT;
-	tfh->gaa = gaa;
-	tfh->dirty = dirty;
-	tfh->pagesize = pagesize;
-	tfh->opc = TFHOP_WRITE_RESTART;
-	start_instruction(tfh);
-}
-
-static inline void tfh_restart(struct gru_tlb_fault_handle *tfh)
-{
-	tfh->opc = TFHOP_RESTART;
-	start_instruction(tfh);
-}
-
-static inline void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
-{
-	tfh->opc = TFHOP_USER_POLLING_MODE;
-	start_instruction(tfh);
-}
-
-static inline void tfh_exception(struct gru_tlb_fault_handle *tfh)
-{
-	tfh->opc = TFHOP_EXCEPTION;
-	start_instruction(tfh);
-}
+int cch_start(struct gru_context_configuration_handle *cch);
+int cch_interrupt(struct gru_context_configuration_handle *cch);
+int cch_deallocate(struct gru_context_configuration_handle *cch);
+int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
+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);
+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);
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
+void tfh_exception(struct gru_tlb_fault_handle *tfh);
 
 #endif /* __GRUHANDLES_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gru_instructions.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gru_instructions.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gru_instructions.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gru_instructions.h	2009-06-09 23:05:27.000000000 -0400
@@ -19,8 +19,11 @@
 #ifndef __GRU_INSTRUCTIONS_H__
 #define __GRU_INSTRUCTIONS_H__
 
-#define gru_flush_cache_hook(p)
-#define gru_emulator_wait_hook(p, w)
+extern int gru_check_status_proc(void *cb);
+extern int gru_wait_proc(void *cb);
+extern void gru_wait_abort_proc(void *cb);
+
+
 
 /*
  * Architecture dependent functions
@@ -29,16 +32,16 @@
 #if defined(CONFIG_IA64)
 #include <linux/compiler.h>
 #include <asm/intrinsics.h>
-#define __flush_cache(p)		ia64_fc(p)
+#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_int(p, v)					\
 		do {							\
 			barrier();					\
 			*((volatile int *)(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_int(p, v)					\
 		do {							\
 			barrier();					\
 			*(int *)p = v;					\
@@ -558,20 +561,19 @@ extern int gru_get_cb_exception_detail(v
 
 #define GRU_EXC_STR_SIZE		256
 
-extern int gru_check_status_proc(void *cb);
-extern int gru_wait_proc(void *cb);
-extern void gru_wait_abort_proc(void *cb);
 
 /*
  * Control block definition for checking status
  */
 struct gru_control_block_status {
 	unsigned int	icmd		:1;
-	unsigned int	unused1		:31;
+	unsigned int	ima		:3;
+	unsigned int	reserved0	:4;
+	unsigned int	unused1		:24;
 	unsigned int	unused2		:24;
 	unsigned int	istatus		:2;
 	unsigned int	isubstatus	:4;
-	unsigned int	inused3		:2;
+	unsigned int	unused3		:2;
 };
 
 /* Get CB status */
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grukservices.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grukservices.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grukservices.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grukservices.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,8 +52,10 @@
  */
 
 /* Blade percpu resources PERMANENTLY reserved for kernel use */
-#define GRU_NUM_KERNEL_CBR      1
+#define GRU_NUM_KERNEL_CBR	1
 #define GRU_NUM_KERNEL_DSR_BYTES 256
+#define GRU_NUM_KERNEL_DSR_CL	(GRU_NUM_KERNEL_DSR_BYTES /		\
+					GRU_CACHE_LINE_BYTES)
 #define KERNEL_CTXNUM           15
 
 /* GRU instruction attributes for all instructions */
@@ -94,7 +96,6 @@ struct message_header {
 	char	fill;
 };
 
-#define QLINES(mq)	((mq) + offsetof(struct message_queue, qlines))
 #define HSTATUS(mq, h)	((mq) + offsetof(struct message_queue, hstatus[h]))
 
 static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
@@ -122,7 +123,7 @@ int gru_get_cb_exception_detail(void *cb
 	struct gru_control_block_extended *cbe;
 
 	cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
-	prefetchw(cbe);         /* Harmless on hardware, required for emulator */
+	prefetchw(cbe);	/* Harmless on hardware, required for emulator */
 	excdet->opc = cbe->opccpy;
 	excdet->exopc = cbe->exopccpy;
 	excdet->ecause = cbe->ecause;
@@ -250,7 +251,8 @@ static inline void restore_present2(void
  * Create a message queue.
  * 	qlines - message queue size in cache lines. Includes 2-line header.
  */
-int gru_create_message_queue(void *p, unsigned int bytes)
+int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+		void *p, unsigned int bytes, int nasid, int vector, int apicid)
 {
 	struct message_queue *mq = p;
 	unsigned int qlines;
@@ -265,6 +267,12 @@ int gru_create_message_queue(void *p, un
 	mq->hstatus[0] = 0;
 	mq->hstatus[1] = 1;
 	mq->head = gru_mesq_head(2, qlines / 2 + 1);
+	mqd->mq = mq;
+	mqd->mq_gpa = uv_gpa(mq);
+	mqd->qlines = qlines;
+	mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
+	mqd->interrupt_vector = vector;
+	mqd->interrupt_apicid = apicid;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(gru_create_message_queue);
@@ -277,8 +285,8 @@ EXPORT_SYMBOL_GPL(gru_create_message_que
  *		-1 - if mesq sent successfully but queue not full
  *		>0 - unexpected error. MQE_xxx returned
  */
-static int send_noop_message(void *cb,
-				unsigned long mq, void *mesg)
+static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
+				void *mesg)
 {
 	const struct message_header noop_header = {
 					.present = MQS_NOOP, .lines = 1};
@@ -289,7 +297,7 @@ static int send_noop_message(void *cb,
 	STAT(mesq_noop);
 	save_mhdr = *mhdr;
 	*mhdr = noop_header;
-	gru_mesq(cb, mq, gru_get_tri(mhdr), 1, IMA);
+	gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA);
 	ret = gru_wait(cb);
 
 	if (ret) {
@@ -313,7 +321,7 @@ static int send_noop_message(void *cb,
 			break;
 		case CBSS_PUT_NACKED:
 			STAT(mesq_noop_put_nacked);
-			m = mq + (gru_get_amo_value_head(cb) << 6);
+			m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
 			gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1,
 						IMA);
 			if (gru_wait(cb) == CBS_IDLE)
@@ -333,30 +341,20 @@ static int send_noop_message(void *cb,
 /*
  * Handle a gru_mesq full.
  */
-static int send_message_queue_full(void *cb,
-			   unsigned long mq, void *mesg, int lines)
+static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
+				void *mesg, int lines)
 {
 	union gru_mesqhead mqh;
 	unsigned int limit, head;
 	unsigned long avalue;
-	int half, qlines, save;
+	int half, qlines;
 
 	/* Determine if switching to first/second half of q */
 	avalue = gru_get_amo_value(cb);
 	head = gru_get_amo_value_head(cb);
 	limit = gru_get_amo_value_limit(cb);
 
-	/*
-	 * Fetch "qlines" from the queue header. Since the queue may be
-	 * in memory that can't be accessed using socket addresses, use
-	 * the GRU to access the data. Use DSR space from the message.
-	 */
-	save = *(int *)mesg;
-	gru_vload(cb, QLINES(mq), gru_get_tri(mesg), XTYPE_W, 1, 1, IMA);
-	if (gru_wait(cb) != CBS_IDLE)
-		goto cberr;
-	qlines = *(int *)mesg;
-	*(int *)mesg = save;
+	qlines = mqd->qlines;
 	half = (limit != qlines);
 
 	if (half)
@@ -365,7 +363,7 @@ static int send_message_queue_full(void
 		mqh = gru_mesq_head(2, qlines / 2 + 1);
 
 	/* Try to get lock for switching head pointer */
-	gru_gamir(cb, EOP_IR_CLR, HSTATUS(mq, half), XTYPE_DW, IMA);
+	gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA);
 	if (gru_wait(cb) != CBS_IDLE)
 		goto cberr;
 	if (!gru_get_amo_value(cb)) {
@@ -375,8 +373,8 @@ static int send_message_queue_full(void
 
 	/* Got the lock. Send optional NOP if queue not full, */
 	if (head != limit) {
-		if (send_noop_message(cb, mq, mesg)) {
-			gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half),
+		if (send_noop_message(cb, mqd, mesg)) {
+			gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half),
 					XTYPE_DW, IMA);
 			if (gru_wait(cb) != CBS_IDLE)
 				goto cberr;
@@ -387,14 +385,16 @@ static int send_message_queue_full(void
 	}
 
 	/* Then flip queuehead to other half of queue. */
-	gru_gamer(cb, EOP_ERR_CSWAP, mq, XTYPE_DW, mqh.val, avalue, IMA);
+	gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue,
+							IMA);
 	if (gru_wait(cb) != CBS_IDLE)
 		goto cberr;
 
 	/* If not successfully in swapping queue head, clear the hstatus lock */
 	if (gru_get_amo_value(cb) != avalue) {
 		STAT(mesq_qf_switch_head_failed);
-		gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA);
+		gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW,
+							IMA);
 		if (gru_wait(cb) != CBS_IDLE)
 			goto cberr;
 	}
@@ -404,15 +404,25 @@ cberr:
 	return MQE_UNEXPECTED_CB_ERR;
 }
 
+/*
+ * 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 gru_mesq failure. Some of these failures are software recoverable
  * or retryable.
  */
-static int send_message_failure(void *cb,
-				unsigned long mq,
-				void *mesg,
-				int lines)
+static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
+				void *mesg, int lines)
 {
 	int substatus, ret = 0;
 	unsigned long m;
@@ -429,7 +439,7 @@ static int send_message_failure(void *cb
 		break;
 	case CBSS_QLIMIT_REACHED:
 		STAT(mesq_send_qlimit_reached);
-		ret = send_message_queue_full(cb, mq, mesg, lines);
+		ret = send_message_queue_full(cb, mqd, mesg, lines);
 		break;
 	case CBSS_AMO_NACKED:
 		STAT(mesq_send_amo_nacked);
@@ -437,12 +447,14 @@ static int send_message_failure(void *cb
 		break;
 	case CBSS_PUT_NACKED:
 		STAT(mesq_send_put_nacked);
-		m =mq + (gru_get_amo_value_head(cb) << 6);
+		m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
 		gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
-		if (gru_wait(cb) == CBS_IDLE)
+		if (gru_wait(cb) == CBS_IDLE) {
 			ret = MQE_OK;
-		else
+			send_message_queue_interrupt(mqd);
+		} else {
 			ret = MQE_UNEXPECTED_CB_ERR;
+		}
 		break;
 	default:
 		BUG();
@@ -452,12 +464,12 @@ static int send_message_failure(void *cb
 
 /*
  * Send a message to a message queue
- * 	cb	GRU control block to use to send message
- * 	mq	message queue
+ * 	mqd	message queue descriptor
  * 	mesg	message. ust be vaddr within a GSEG
  * 	bytes	message size (<= 2 CL)
  */
-int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
+int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg,
+				unsigned int bytes)
 {
 	struct message_header *mhdr;
 	void *cb;
@@ -481,10 +493,10 @@ int gru_send_message_gpa(unsigned long m
 
 	do {
 		ret = MQE_OK;
-		gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA);
+		gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA);
 		istatus = gru_wait(cb);
 		if (istatus != CBS_IDLE)
-			ret = send_message_failure(cb, mq, dsr, clines);
+			ret = send_message_failure(cb, mqd, dsr, clines);
 	} while (ret == MQIE_AGAIN);
 	gru_free_cpu_resources(cb, dsr);
 
@@ -497,9 +509,9 @@ EXPORT_SYMBOL_GPL(gru_send_message_gpa);
 /*
  * Advance the receive pointer for the queue to the next message.
  */
-void gru_free_message(void *rmq, void *mesg)
+void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg)
 {
-	struct message_queue *mq = rmq;
+	struct message_queue *mq = mqd->mq;
 	struct message_header *mhdr = mq->next;
 	void *next, *pnext;
 	int half = -1;
@@ -529,16 +541,16 @@ EXPORT_SYMBOL_GPL(gru_free_message);
  * present. User must call next_message() to move to next message.
  * 	rmq	message queue
  */
-void *gru_get_next_message(void *rmq)
+void *gru_get_next_message(struct gru_message_queue_desc *mqd)
 {
-	struct message_queue *mq = rmq;
+	struct message_queue *mq = mqd->mq;
 	struct message_header *mhdr = mq->next;
 	int present = mhdr->present;
 
 	/* skip NOOP messages */
 	STAT(mesq_receive);
 	while (present == MQS_NOOP) {
-		gru_free_message(rmq, mhdr);
+		gru_free_message(mqd, mhdr);
 		mhdr = mq->next;
 		present = mhdr->present;
 	}
@@ -576,7 +588,7 @@ int gru_copy_gpa(unsigned long dest_gpa,
 	if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
 		return MQE_BUG_NO_RESOURCES;
 	gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
-		  XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_BYTES, IMA);
+		  XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA);
 	ret = gru_wait(cb);
 	gru_free_cpu_resources(cb, dsr);
 	return ret;
@@ -611,7 +623,7 @@ static int quicktest(struct gru_state *g
 
 	if (word0 != word1 || word0 != MAGIC) {
 		printk
-		    ("GRU quicktest err: gru %d, found 0x%lx, expected 0x%lx\n",
+		    ("GRU quicktest err: gid %d, found 0x%lx, expected 0x%lx\n",
 		     gru->gs_gid, word1, MAGIC);
 		BUG();		/* ZZZ should not be fatal */
 	}
@@ -660,15 +672,15 @@ int gru_kservices_init(struct gru_state
 	cch->tlb_int_enable = 0;
 	cch->tfm_done_bit_enable = 0;
 	cch->unmap_enable = 1;
-	err = cch_allocate(cch, 0, cbr_map, dsr_map);
+	err = cch_allocate(cch, 0, 0, cbr_map, dsr_map);
 	if (err) {
 		gru_dbg(grudev,
-			"Unable to allocate kernel CCH: gru %d, err %d\n",
+			"Unable to allocate kernel CCH: gid %d, err %d\n",
 			gru->gs_gid, err);
 		BUG();
 	}
 	if (cch_start(cch)) {
-		gru_dbg(grudev, "Unable to start kernel CCH: gru %d, err %d\n",
+		gru_dbg(grudev, "Unable to start kernel CCH: gid %d, err %d\n",
 			gru->gs_gid, err);
 		BUG();
 	}
@@ -678,3 +690,22 @@ int gru_kservices_init(struct gru_state
 		quicktest(gru);
 	return 0;
 }
+
+void gru_kservices_exit(struct gru_state *gru)
+{
+	struct gru_context_configuration_handle *cch;
+	struct gru_blade_state *bs;
+
+	bs = gru->gs_blade;
+	if (gru != &bs->bs_grus[1])
+		return;
+
+	cch = get_cch(gru->gs_gru_base_vaddr, KERNEL_CTXNUM);
+	lock_cch_handle(cch);
+	if (cch_interrupt_sync(cch))
+		BUG();
+	if (cch_deallocate(cch))
+		BUG();
+	unlock_cch_handle(cch);
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grukservices.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grukservices.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grukservices.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grukservices.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,15 @@
  * 	- gru_create_message_queue() needs interrupt vector info
  */
 
+struct gru_message_queue_desc {
+	void		*mq;			/* message queue vaddress */
+	unsigned long	mq_gpa;			/* global address of mq */
+	int		qlines;			/* queue size in CL */
+	int		interrupt_vector;	/* interrupt vector */
+	int		interrupt_pnode;	/* pnode for interrupt */
+	int		interrupt_apicid;	/* lapicid for interrupt */
+};
+
 /*
  * Initialize a user allocated chunk of memory to be used as
  * a message queue. The caller must ensure that the queue is
@@ -51,14 +60,19 @@
  * to manage the queue.
  *
  *  Input:
- * 	p	pointer to user allocated memory.
+ * 	mqd	pointer to message queue descriptor
+ * 	p	pointer to user allocated mesq memory.
  * 	bytes	size of message queue in bytes
+ *      vector	interrupt vector (zero if no interrupts)
+ *      nasid	nasid of blade where interrupt is delivered
+ *      apicid	apicid of cpu for interrupt
  *
  *  Errors:
  *  	0	OK
  *  	>0	error
  */
-extern int gru_create_message_queue(void *p, unsigned int bytes);
+extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+		void *p, unsigned int bytes, int nasid, int vector, int apicid);
 
 /*
  * Send a message to a message queue.
@@ -68,7 +82,7 @@ extern int gru_create_message_queue(void
  *
  *
  *   Input:
- * 	xmq	message queue - must be a UV global physical address
+ * 	mqd	pointer to message queue descriptor
  * 	mesg	pointer to message. Must be 64-bit aligned
  * 	bytes	size of message in bytes
  *
@@ -77,8 +91,8 @@ extern int gru_create_message_queue(void
  *     >0	Send failure - see error codes below
  *
  */
-extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg,
-						unsigned int bytes);
+extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
+			void *mesg, unsigned int bytes);
 
 /* Status values for gru_send_message() */
 #define MQE_OK			0	/* message sent successfully */
@@ -94,10 +108,11 @@ extern int gru_send_message_gpa(unsigned
  * API extensions may allow for out-of-order freeing.
  *
  *   Input
- * 	mq	message queue
+ * 	mqd	pointer to message queue descriptor
  * 	mesq	message being freed
  */
-extern void gru_free_message(void *mq, void *mesq);
+extern void gru_free_message(struct gru_message_queue_desc *mqd,
+			     void *mesq);
 
 /*
  * Get next message from message queue. Returns pointer to
@@ -106,13 +121,13 @@ extern void gru_free_message(void *mq, v
  * in order to move the queue pointers to next message.
  *
  *   Input
- * 	mq	message queue
+ * 	mqd	pointer to message queue descriptor
  *
  *   Output:
  *	p	pointer to message
  *	NULL	no message available
  */
-extern void *gru_get_next_message(void *mq);
+extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
 
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grumain.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grumain.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grumain.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grumain.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,10 +76,9 @@ int gru_cpu_fault_map_id(void)
 /* Hit the asid limit. Start over */
 static int gru_wrap_asid(struct gru_state *gru)
 {
-	gru_dbg(grudev, "gru %p\n", gru);
+	gru_dbg(grudev, "gid %d\n", gru->gs_gid);
 	STAT(asid_wrap);
 	gru->gs_asid_gen++;
-	gru_flush_all_tlb(gru);
 	return MIN_ASID;
 }
 
@@ -88,19 +87,21 @@ static int gru_reset_asid_limit(struct g
 {
 	int i, gid, inuse_asid, limit;
 
-	gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+	gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
 	STAT(asid_next);
 	limit = MAX_ASID;
 	if (asid >= limit)
 		asid = gru_wrap_asid(gru);
+	gru_flush_all_tlb(gru);
 	gid = gru->gs_gid;
 again:
 	for (i = 0; i < GRU_NUM_CCH; i++) {
 		if (!gru->gs_gts[i])
 			continue;
 		inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid;
-		gru_dbg(grudev, "gru %p, inuse_asid 0x%x, cxtnum %d, gts %p\n",
-			gru, inuse_asid, i, gru->gs_gts[i]);
+		gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
+			gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms,
+			inuse_asid, i);
 		if (inuse_asid == asid) {
 			asid += ASID_INC;
 			if (asid >= limit) {
@@ -120,8 +121,8 @@ again:
 	}
 	gru->gs_asid_limit = limit;
 	gru->gs_asid = asid;
-	gru_dbg(grudev, "gru %p, new asid 0x%x, new_limit 0x%x\n", gru, asid,
-		limit);
+	gru_dbg(grudev, "gid %d, new asid 0x%x, new_limit 0x%x\n", gru->gs_gid,
+					asid, limit);
 	return asid;
 }
 
@@ -130,14 +131,12 @@ static int gru_assign_asid(struct gru_st
 {
 	int asid;
 
-	spin_lock(&gru->gs_asid_lock);
 	gru->gs_asid += ASID_INC;
 	asid = gru->gs_asid;
 	if (asid >= gru->gs_asid_limit)
 		asid = gru_reset_asid_limit(gru, asid);
-	spin_unlock(&gru->gs_asid_lock);
 
-	gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+	gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
 	return asid;
 }
 
@@ -215,17 +214,20 @@ static int check_gru_resources(struct gr
  * TLB manangment requires tracking all GRU chiplets that have loaded a GSEG
  * context.
  */
-static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
-			       int ctxnum)
+static int gru_load_mm_tracker(struct gru_state *gru,
+					struct gru_thread_state *gts)
 {
+	struct gru_mm_struct *gms = gts->ts_gms;
 	struct gru_mm_tracker *asids = &gms->ms_asids[gru->gs_gid];
-	unsigned short ctxbitmap = (1 << ctxnum);
+	unsigned short ctxbitmap = (1 << gts->ts_ctxnum);
 	int asid;
 
 	spin_lock(&gms->ms_asid_lock);
 	asid = asids->mt_asid;
 
-	if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) {
+	spin_lock(&gru->gs_asid_lock);
+	if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
+			  gru->gs_asid_gen)) {
 		asid = gru_assign_asid(gru);
 		asids->mt_asid = asid;
 		asids->mt_asid_gen = gru->gs_asid_gen;
@@ -233,6 +235,7 @@ static int gru_load_mm_tracker(struct gr
 	} else {
 		STAT(asid_reuse);
 	}
+	spin_unlock(&gru->gs_asid_lock);
 
 	BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
 	asids->mt_ctxbitmap |= ctxbitmap;
@@ -241,24 +244,28 @@ static int gru_load_mm_tracker(struct gr
 	spin_unlock(&gms->ms_asid_lock);
 
 	gru_dbg(grudev,
-		"gru %x, gms %p, ctxnum 0x%d, asid 0x%x, asidmap 0x%lx\n",
-		gru->gs_gid, gms, ctxnum, asid, gms->ms_asidmap[0]);
+		"gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n",
+		gru->gs_gid, gts, gms, gts->ts_ctxnum, asid,
+		gms->ms_asidmap[0]);
 	return asid;
 }
 
 static void gru_unload_mm_tracker(struct gru_state *gru,
-				  struct gru_mm_struct *gms, int ctxnum)
+					struct gru_thread_state *gts)
 {
+	struct gru_mm_struct *gms = gts->ts_gms;
 	struct gru_mm_tracker *asids;
 	unsigned short ctxbitmap;
 
 	asids = &gms->ms_asids[gru->gs_gid];
-	ctxbitmap = (1 << ctxnum);
+	ctxbitmap = (1 << gts->ts_ctxnum);
 	spin_lock(&gms->ms_asid_lock);
+	spin_lock(&gru->gs_asid_lock);
 	BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
 	asids->mt_ctxbitmap ^= ctxbitmap;
-	gru_dbg(grudev, "gru %x, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
-		gru->gs_gid, gms, ctxnum, gms->ms_asidmap[0]);
+	gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
+		gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
+	spin_unlock(&gru->gs_asid_lock);
 	spin_unlock(&gms->ms_asid_lock);
 }
 
@@ -319,6 +326,7 @@ static struct gru_thread_state *gru_allo
 	gts->ts_vma = vma;
 	gts->ts_tlb_int_select = -1;
 	gts->ts_gms = gru_register_mmu_notifier();
+	gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
 	if (!gts->ts_gms)
 		goto err;
 
@@ -399,7 +407,7 @@ static void gru_free_gru_context(struct
 	struct gru_state *gru;
 
 	gru = gts->ts_gru;
-	gru_dbg(grudev, "gts %p, gru %p\n", gts, gru);
+	gru_dbg(grudev, "gts %p, gid %d\n", gts, gru->gs_gid);
 
 	spin_lock(&gru->gs_lock);
 	gru->gs_gts[gts->ts_ctxnum] = NULL;
@@ -408,6 +416,7 @@ static void gru_free_gru_context(struct
 	__clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
 	gts->ts_ctxnum = NULLCTX;
 	gts->ts_gru = NULL;
+	gts->ts_blade = -1;
 	spin_unlock(&gru->gs_lock);
 
 	gts_drop(gts);
@@ -432,8 +441,8 @@ static inline long gru_copy_handle(void
 	return GRU_HANDLE_BYTES;
 }
 
-static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
-				unsigned long length)
+static void gru_prefetch_context(void *gseg, void *cb, void *cbe,
+				unsigned long cbrmap, unsigned long length)
 {
 	int i, scr;
 
@@ -500,12 +509,12 @@ 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);
 	lock_cch_handle(cch);
 	if (cch_interrupt_sync(cch))
 		BUG();
-	gru_dbg(grudev, "gts %p\n", gts);
 
-	gru_unload_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+	gru_unload_mm_tracker(gru, gts);
 	if (savestate)
 		gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr,
 					ctxnum, gts->ts_cbr_map,
@@ -534,7 +543,7 @@ static void gru_load_context(struct gru_
 	cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
 
 	lock_cch_handle(cch);
-	asid = gru_load_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+	asid = gru_load_mm_tracker(gru, gts);
 	cch->tfm_fault_bit_enable =
 	    (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
 	     || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
@@ -544,7 +553,8 @@ static void gru_load_context(struct gru_
 		cch->tlb_int_select = gts->ts_tlb_int_select;
 	}
 	cch->tfm_done_bit_enable = 0;
-	err = cch_allocate(cch, asid, gts->ts_cbr_map, gts->ts_dsr_map);
+	err = cch_allocate(cch, asid, gts->ts_sizeavail, gts->ts_cbr_map,
+				gts->ts_dsr_map);
 	if (err) {
 		gru_dbg(grudev,
 			"err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
@@ -565,11 +575,12 @@ static void gru_load_context(struct gru_
 /*
  * 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.
  */
-static int gru_update_cch(struct gru_thread_state *gts, int int_select)
+int gru_update_cch(struct gru_thread_state *gts, int force_unload)
 {
 	struct gru_context_configuration_handle *cch;
 	struct gru_state *gru = gts->ts_gru;
@@ -583,9 +594,11 @@ static int gru_update_cch(struct gru_thr
 			goto exit;
 		if (cch_interrupt(cch))
 			BUG();
-		if (int_select >= 0) {
-			gts->ts_tlb_int_select = int_select;
-			cch->tlb_int_select = int_select;
+		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();
 		} else {
 			for (i = 0; i < 8; i++)
 				cch->asid[i] = 0;
@@ -617,7 +630,7 @@ 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, gru_cpu_fault_map_id());
+	return gru_update_cch(gts, 0);
 }
 
 
@@ -688,7 +701,7 @@ static void gru_steal_context(struct gru
 		STAT(steal_context_failed);
 	}
 	gru_dbg(grudev,
-		"stole gru %x, ctxnum %d from gts %p. Need cb %d, ds %d;"
+		"stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;"
 		" avail cb %ld, ds %ld\n",
 		gru->gs_gid, ctxnum, ngts, cbr, dsr, hweight64(gru->gs_cbr_map),
 		hweight64(gru->gs_dsr_map));
@@ -727,6 +740,7 @@ 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);
@@ -737,7 +751,7 @@ again:
 
 		STAT(assign_context);
 		gru_dbg(grudev,
-			"gseg %p, gts %p, gru %x, ctx %d, cbr %d, dsr %d\n",
+			"gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n",
 			gseg_virtual_address(gts->ts_gru, gts->ts_ctxnum), gts,
 			gts->ts_gru->gs_gid, gts->ts_ctxnum,
 			gts->ts_cbr_au_count, gts->ts_dsr_au_count);
@@ -773,8 +787,8 @@ int gru_fault(struct vm_area_struct *vma
 		return VM_FAULT_SIGBUS;
 
 again:
-	preempt_disable();
 	mutex_lock(&gts->ts_ctxlock);
+	preempt_disable();
 	if (gts->ts_gru) {
 		if (gts->ts_gru->gs_blade_id != uv_numa_blade_id()) {
 			STAT(migrated_nopfn_unload);
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruprocfs.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruprocfs.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/gruprocfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/gruprocfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,7 +62,9 @@ static int statistics_show(struct seq_fi
 	printstat(s, asid_wrap);
 	printstat(s, asid_reuse);
 	printstat(s, intr);
+	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);
@@ -120,6 +122,30 @@ static ssize_t statistics_write(struct f
 	return count;
 }
 
+static int mcs_statistics_show(struct seq_file *s, void *p)
+{
+	int op;
+	unsigned long total, count, max;
+	static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
+		"cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
+
+	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);
+		max = mcs_op_statistics[op].max;
+		seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
+			   count ? total / count : 0, max);
+	}
+	return 0;
+}
+
+static ssize_t mcs_statistics_write(struct file *file,
+			const char __user *userbuf, size_t count, loff_t *data)
+{
+	memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics));
+	return count;
+}
+
 static int options_show(struct seq_file *s, void *p)
 {
 	seq_printf(s, "0x%lx\n", gru_options);
@@ -135,6 +161,7 @@ static ssize_t options_write(struct file
 	if (copy_from_user
 	    (buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
 		return -EFAULT;
+	buf[count - 1] = '\0';
 	if (!strict_strtoul(buf, 10, &val))
 		gru_options = val;
 
@@ -199,7 +226,7 @@ static void seq_stop(struct seq_file *fi
 
 static void *seq_start(struct seq_file *file, loff_t *gid)
 {
-	if (*gid < GRU_MAX_GRUS)
+	if (*gid < gru_max_gids)
 		return gid;
 	return NULL;
 }
@@ -207,7 +234,7 @@ static void *seq_start(struct seq_file *
 static void *seq_next(struct seq_file *file, void *data, loff_t *gid)
 {
 	(*gid)++;
-	if (*gid < GRU_MAX_GRUS)
+	if (*gid < gru_max_gids)
 		return gid;
 	return NULL;
 }
@@ -231,6 +258,11 @@ static int statistics_open(struct inode
 	return single_open(file, statistics_show, NULL);
 }
 
+static int mcs_statistics_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mcs_statistics_show, NULL);
+}
+
 static int options_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, options_show, NULL);
@@ -255,6 +287,14 @@ static const struct file_operations stat
 	.release 	= single_release,
 };
 
+static const struct file_operations mcs_statistics_fops = {
+	.open 		= mcs_statistics_open,
+	.read 		= seq_read,
+	.write 		= mcs_statistics_write,
+	.llseek 	= seq_lseek,
+	.release 	= single_release,
+};
+
 static const struct file_operations options_fops = {
 	.open 		= options_open,
 	.read 		= seq_read,
@@ -283,6 +323,7 @@ static struct proc_entry {
 	struct proc_dir_entry *entry;
 } proc_files[] = {
 	{"statistics", 0644, &statistics_fops},
+	{"mcs_statistics", 0644, &mcs_statistics_fops},
 	{"debug_options", 0644, &options_fops},
 	{"cch_status", 0444, &cch_fops},
 	{"gru_status", 0444, &gru_fops},
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grutables.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grutables.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grutables.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grutables.h	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,7 @@
 extern struct gru_stats_s gru_stats;
 extern struct gru_blade_state *gru_base[];
 extern unsigned long gru_start_paddr, gru_end_paddr;
+extern unsigned int gru_max_gids;
 
 #define GRU_MAX_BLADES		MAX_NUMNODES
 #define GRU_MAX_GRUS		(GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
@@ -184,7 +185,9 @@ struct gru_stats_s {
 	atomic_long_t asid_wrap;
 	atomic_long_t asid_reuse;
 	atomic_long_t intr;
+	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;
@@ -237,6 +240,17 @@ struct gru_stats_s {
 
 };
 
+enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
+	cchop_deallocate, tghop_invalidate, mcsop_last};
+
+struct mcs_op_statistic {
+	atomic_long_t	count;
+	atomic_long_t	total;
+	unsigned long	max;
+};
+
+extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
 #define OPT_DPRINT	1
 #define OPT_STATS	2
 #define GRU_QUICKLOOK	4
@@ -278,13 +292,12 @@ struct gru_stats_s {
 /* Generate a GRU asid value from a GRU base asid & a virtual address. */
 #if defined CONFIG_IA64
 #define VADDR_HI_BIT		64
-#define GRUREGION(addr)		((addr) >> (VADDR_HI_BIT - 3) & 3)
 #elif defined CONFIG_X86_64
 #define VADDR_HI_BIT		48
-#define GRUREGION(addr)		(0)		/* ZZZ could do better */
 #else
 #error "Unsupported architecture"
 #endif
+#define GRUREGION(addr)		((addr) >> (VADDR_HI_BIT - 3) & 3)
 #define GRUASID(asid, addr)	((asid) + GRUREGION(addr))
 
 /*------------------------------------------------------------------------------
@@ -297,12 +310,12 @@ struct gru_state;
  * This structure is pointed to from the mmstruct via the notifier pointer.
  * There is one of these per address space.
  */
-struct gru_mm_tracker {
-	unsigned int		mt_asid_gen;	/* ASID wrap count */
-	int			mt_asid;	/* current base ASID for gru */
-	unsigned short		mt_ctxbitmap;	/* bitmap of contexts using
+struct gru_mm_tracker {				/* pack to reduce size */
+	unsigned int		mt_asid_gen:24;	/* ASID wrap count */
+	unsigned int		mt_asid:24;	/* current base ASID for gru */
+	unsigned short		mt_ctxbitmap:16;/* bitmap of contexts using
 						   asid */
-};
+} __attribute__ ((packed));
 
 struct gru_mm_struct {
 	struct mmu_notifier	ms_notifier;
@@ -348,6 +361,7 @@ 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 */
+	unsigned short		ts_sizeavail;	/* Pagesizes in use */
 	int			ts_tsid;	/* thread that owns the
 						   structure */
 	int			ts_tlb_int_select;/* target cpu if interrupts
@@ -359,6 +373,9 @@ struct gru_thread_state {
 						   required for contest */
 	unsigned char		ts_cbr_au_count;/* Number of CBR resources
 						   required for contest */
+	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
@@ -392,12 +409,12 @@ struct gru_state {
 							   gru segments (64) */
 	void			*gs_gru_base_vaddr;	/* Virtual address of
 							   gru segments (64) */
-	unsigned char		gs_gid;			/* unique GRU number */
+	unsigned short		gs_gid;			/* unique GRU number */
+	unsigned short		gs_blade_id;		/* blade of GRU */
 	unsigned char		gs_tgh_local_shift;	/* used to pick TGH for
 							   local flush */
 	unsigned char		gs_tgh_first_remote;	/* starting TGH# for
 							   remote flush */
-	unsigned short		gs_blade_id;		/* blade of GRU */
 	spinlock_t		gs_asid_lock;		/* lock used for
 							   assigning asids */
 	spinlock_t		gs_lock;		/* lock used for
@@ -492,6 +509,10 @@ struct gru_blade_state {
 			(i) < GRU_CHIPLETS_PER_BLADE;			\
 			(i)++, (gru)++)
 
+/* Scan all GRUs */
+#define foreach_gid(gid)						\
+	for ((gid) = 0; (gid) < gru_max_gids; (gid)++)
+
 /* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */
 #define for_each_gts_on_gru(gts, gru, ctxnum)				\
 	for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++)		\
@@ -578,9 +599,11 @@ extern struct gru_thread_state *gru_find
 extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
 				*vma, int tsid);
 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 void gts_drop(struct gru_thread_state *gts);
 extern void gru_tgh_flush_init(struct gru_state *gru);
 extern int gru_kservices_init(struct gru_state *gru);
+extern void gru_kservices_exit(struct gru_state *gru);
 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grutlbpurge.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grutlbpurge.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/grutlbpurge.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/grutlbpurge.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,7 @@ void gru_flush_tlb_range(struct gru_mm_s
 	"  FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n",
 				gid, asid, num, asids->mt_ctxbitmap);
 			tgh = get_lock_tgh_handle(gru);
-			tgh_invalidate(tgh, start, 0, asid, grupagesize, 0,
+			tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
 				       num - 1, asids->mt_ctxbitmap);
 			get_unlock_tgh_handle(tgh);
 		} else {
@@ -210,11 +210,10 @@ void gru_flush_all_tlb(struct gru_state
 {
 	struct gru_tlb_global_handle *tgh;
 
-	gru_dbg(grudev, "gru %p, gid %d\n", gru, gru->gs_gid);
+	gru_dbg(grudev, "gid %d\n", gru->gs_gid);
 	tgh = get_lock_tgh_handle(gru);
-	tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0);
+	tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0xffff);
 	get_unlock_tgh_handle(tgh);
-	preempt_enable();
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/Makefile linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/Makefile
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-gru/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-gru/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,5 +3,5 @@ ifdef CONFIG_SGI_GRU_DEBUG
 endif
 
 obj-$(CONFIG_SGI_GRU) := gru.o
-gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o
+gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_channel.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_channel.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_channel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_channel.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -39,34 +39,38 @@ xpc_process_connect(struct xpc_channel *
 
 	if (!(ch->flags & XPC_C_SETUP)) {
 		spin_unlock_irqrestore(&ch->lock, *irq_flags);
-		ret = xpc_setup_msg_structures(ch);
+		ret = xpc_arch_ops.setup_msg_structures(ch);
 		spin_lock_irqsave(&ch->lock, *irq_flags);
 
 		if (ret != xpSuccess)
 			XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
+		else
+			ch->flags |= XPC_C_SETUP;
 
-		ch->flags |= XPC_C_SETUP;
-
-		if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
+		if (ch->flags & XPC_C_DISCONNECTING)
 			return;
 	}
 
 	if (!(ch->flags & XPC_C_OPENREPLY)) {
 		ch->flags |= XPC_C_OPENREPLY;
-		xpc_send_chctl_openreply(ch, irq_flags);
+		xpc_arch_ops.send_chctl_openreply(ch, irq_flags);
 	}
 
 	if (!(ch->flags & XPC_C_ROPENREPLY))
 		return;
 
-	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */
+	if (!(ch->flags & XPC_C_OPENCOMPLETE)) {
+		ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED);
+		xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags);
+	}
+
+	if (!(ch->flags & XPC_C_ROPENCOMPLETE))
+		return;
 
 	dev_info(xpc_chan, "channel %d to partition %d connected\n",
 		 ch->number, ch->partid);
 
-	spin_unlock_irqrestore(&ch->lock, *irq_flags);
-	xpc_create_kthreads(ch, 1, 0);
-	spin_lock_irqsave(&ch->lock, *irq_flags);
+	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */
 }
 
 /*
@@ -96,7 +100,7 @@ xpc_process_disconnect(struct xpc_channe
 
 	if (part->act_state == XPC_P_AS_DEACTIVATING) {
 		/* can't proceed until the other side disengages from us */
-		if (xpc_partition_engaged(ch->partid))
+		if (xpc_arch_ops.partition_engaged(ch->partid))
 			return;
 
 	} else {
@@ -108,7 +112,7 @@ xpc_process_disconnect(struct xpc_channe
 
 		if (!(ch->flags & XPC_C_CLOSEREPLY)) {
 			ch->flags |= XPC_C_CLOSEREPLY;
-			xpc_send_chctl_closereply(ch, irq_flags);
+			xpc_arch_ops.send_chctl_closereply(ch, irq_flags);
 		}
 
 		if (!(ch->flags & XPC_C_RCLOSEREPLY))
@@ -118,7 +122,7 @@ xpc_process_disconnect(struct xpc_channe
 	/* wake those waiting for notify completion */
 	if (atomic_read(&ch->n_to_notify) > 0) {
 		/* we do callout while holding ch->lock, callout can't block */
-		xpc_notify_senders_of_disconnect(ch);
+		xpc_arch_ops.notify_senders_of_disconnect(ch);
 	}
 
 	/* both sides are disconnected now */
@@ -132,7 +136,7 @@ xpc_process_disconnect(struct xpc_channe
 	DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
 
 	/* it's now safe to free the channel's message queues */
-	xpc_teardown_msg_structures(ch);
+	xpc_arch_ops.teardown_msg_structures(ch);
 
 	ch->func = NULL;
 	ch->key = NULL;
@@ -144,8 +148,9 @@ xpc_process_disconnect(struct xpc_channe
 
 	/*
 	 * Mark the channel disconnected and clear all other flags, including
-	 * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but
-	 * not including XPC_C_WDISCONNECT (if it was set).
+	 * XPC_C_SETUP (because of call to
+	 * xpc_arch_ops.teardown_msg_structures()) but not including
+	 * XPC_C_WDISCONNECT (if it was set).
 	 */
 	ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
 
@@ -183,6 +188,8 @@ xpc_process_openclose_chctl_flags(struct
 	    &part->remote_openclose_args[ch_number];
 	struct xpc_channel *ch = &part->channels[ch_number];
 	enum xp_retval reason;
+	enum xp_retval ret;
+	int create_kthread = 0;
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
 
@@ -195,8 +202,7 @@ again:
 		 * has had a chance to see that the channel is disconnected.
 		 */
 		ch->delayed_chctl_flags |= chctl_flags;
-		spin_unlock_irqrestore(&ch->lock, irq_flags);
-		return;
+		goto out;
 	}
 
 	if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) {
@@ -238,8 +244,7 @@ again:
 					    XPC_CHCTL_CLOSEREQUEST;
 					spin_unlock(&part->chctl_lock);
 				}
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
-				return;
+				goto out;
 			}
 
 			XPC_SET_REASON(ch, 0, 0);
@@ -249,7 +254,8 @@ again:
 			ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
 		}
 
-		chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY);
+		chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY |
+		    XPC_CHCTL_OPENCOMPLETE);
 
 		/*
 		 * The meaningful CLOSEREQUEST connection state fields are:
@@ -268,8 +274,7 @@ again:
 			XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
 
 			DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		xpc_process_disconnect(ch, &irq_flags);
@@ -282,8 +287,7 @@ again:
 
 		if (ch->flags & XPC_C_DISCONNECTED) {
 			DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
@@ -298,8 +302,7 @@ again:
 				    XPC_CHCTL_CLOSEREPLY;
 				spin_unlock(&part->chctl_lock);
 			}
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		ch->flags |= XPC_C_RCLOSEREPLY;
@@ -319,14 +322,12 @@ again:
 
 		if (part->act_state == XPC_P_AS_DEACTIVATING ||
 		    (ch->flags & XPC_C_ROPENREQUEST)) {
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
 			ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 		DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
 				       XPC_C_OPENREQUEST)));
@@ -340,8 +341,7 @@ again:
 		 */
 		if (args->entry_size == 0 || args->local_nentries == 0) {
 			/* assume OPENREQUEST was delayed by mistake */
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
@@ -351,8 +351,7 @@ again:
 			if (args->entry_size != ch->entry_size) {
 				XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
 						       &irq_flags);
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
-				return;
+				goto out;
 			}
 		} else {
 			ch->entry_size = args->entry_size;
@@ -374,15 +373,13 @@ again:
 			args->local_msgqueue_pa, args->local_nentries,
 			args->remote_nentries, ch->partid, ch->number);
 
-		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
-		}
+		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+			goto out;
+
 		if (!(ch->flags & XPC_C_OPENREQUEST)) {
 			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
 					       &irq_flags);
-			spin_unlock_irqrestore(&ch->lock, irq_flags);
-			return;
+			goto out;
 		}
 
 		DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
@@ -399,8 +396,13 @@ again:
 		DBUG_ON(args->local_nentries == 0);
 		DBUG_ON(args->remote_nentries == 0);
 
+		ret = xpc_arch_ops.save_remote_msgqueue_pa(ch,
+						      args->local_msgqueue_pa);
+		if (ret != xpSuccess) {
+			XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
+			goto out;
+		}
 		ch->flags |= XPC_C_ROPENREPLY;
-		xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
 
 		if (args->local_nentries < ch->remote_nentries) {
 			dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
@@ -424,7 +426,36 @@ again:
 		xpc_process_connect(ch, &irq_flags);
 	}
 
+	if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) {
+
+		dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from "
+			"partid=%d, channel=%d\n", ch->partid, ch->number);
+
+		if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
+			goto out;
+
+		if (!(ch->flags & XPC_C_OPENREQUEST) ||
+		    !(ch->flags & XPC_C_OPENREPLY)) {
+			XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
+					       &irq_flags);
+			goto out;
+		}
+
+		DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
+		DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY));
+		DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
+
+		ch->flags |= XPC_C_ROPENCOMPLETE;
+
+		xpc_process_connect(ch, &irq_flags);
+		create_kthread = 1;
+	}
+
+out:
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+	if (create_kthread)
+		xpc_create_kthreads(ch, 1, 0);
 }
 
 /*
@@ -502,7 +533,7 @@ xpc_connect_channel(struct xpc_channel *
 	/* initiate the connection */
 
 	ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
-	xpc_send_chctl_openrequest(ch, &irq_flags);
+	xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags);
 
 	xpc_process_connect(ch, &irq_flags);
 
@@ -520,7 +551,7 @@ xpc_process_sent_chctl_flags(struct xpc_
 	int ch_number;
 	u32 ch_flags;
 
-	chctl.all_flags = xpc_get_chctl_all_flags(part);
+	chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part);
 
 	/*
 	 * Initiate channel connections for registered channels.
@@ -558,10 +589,6 @@ xpc_process_sent_chctl_flags(struct xpc_
 			if (!(ch_flags & XPC_C_OPENREQUEST)) {
 				DBUG_ON(ch_flags & XPC_C_SETUP);
 				(void)xpc_connect_channel(ch);
-			} else {
-				spin_lock_irqsave(&ch->lock, irq_flags);
-				xpc_process_connect(ch, &irq_flags);
-				spin_unlock_irqrestore(&ch->lock, irq_flags);
 			}
 			continue;
 		}
@@ -573,7 +600,7 @@ xpc_process_sent_chctl_flags(struct xpc_
 		 */
 
 		if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
-			xpc_process_msg_chctl_flags(part, ch_number);
+			xpc_arch_ops.process_msg_chctl_flags(part, ch_number);
 	}
 }
 
@@ -749,7 +776,7 @@ xpc_disconnect_channel(const int line, s
 		       XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
 		       XPC_C_CONNECTING | XPC_C_CONNECTED);
 
-	xpc_send_chctl_closerequest(ch, irq_flags);
+	xpc_arch_ops.send_chctl_closerequest(ch, irq_flags);
 
 	if (channel_was_connected)
 		ch->flags |= XPC_C_WASCONNECTED;
@@ -856,8 +883,8 @@ xpc_initiate_send(short partid, int ch_n
 	DBUG_ON(payload == NULL);
 
 	if (xpc_part_ref(part)) {
-		ret = xpc_send_payload(&part->channels[ch_number], flags,
-				       payload, payload_size, 0, NULL, NULL);
+		ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+				  flags, payload, payload_size, 0, NULL, NULL);
 		xpc_part_deref(part);
 	}
 
@@ -908,9 +935,8 @@ xpc_initiate_send_notify(short partid, i
 	DBUG_ON(func == NULL);
 
 	if (xpc_part_ref(part)) {
-		ret = xpc_send_payload(&part->channels[ch_number], flags,
-				       payload, payload_size, XPC_N_CALL, func,
-				       key);
+		ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
+			  flags, payload, payload_size, XPC_N_CALL, func, key);
 		xpc_part_deref(part);
 	}
 	return ret;
@@ -924,7 +950,7 @@ xpc_deliver_payload(struct xpc_channel *
 {
 	void *payload;
 
-	payload = xpc_get_deliverable_payload(ch);
+	payload = xpc_arch_ops.get_deliverable_payload(ch);
 	if (payload != NULL) {
 
 		/*
@@ -978,7 +1004,7 @@ xpc_initiate_received(short partid, int
 	DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
 
 	ch = &part->channels[ch_number];
-	xpc_received_payload(ch, payload);
+	xpc_arch_ops.received_payload(ch, payload);
 
 	/* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload()  */
 	xpc_msgqueue_deref(ch);
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc.h	2009-06-09 23:05:27.000000000 -0400
@@ -90,16 +90,21 @@ struct xpc_rsvd_page {
 	short max_npartitions;	/* value of XPC_MAX_PARTITIONS */
 	u8 version;
 	u8 pad1[3];		/* align to next u64 in 1st 64-byte cacheline */
+	unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
 	union {
-		unsigned long vars_pa;	/* phys address of struct xpc_vars */
-		unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */
+		struct {
+			unsigned long vars_pa;	/* phys addr */
+		} sn2;
+		struct {
+			unsigned long heartbeat_gpa; /* phys addr */
+			unsigned long activate_gru_mq_desc_gpa; /* phys addr */
+		} uv;
 	} sn;
-	unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
-	u64 pad2[10];		/* align to last u64 in 2nd 64-byte cacheline */
+	u64 pad2[9];		/* align to last u64 in 2nd 64-byte cacheline */
 	u64 SAL_nasids_size;	/* SAL: size of each nasid mask in bytes */
 };
 
-#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
+#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
 
 /*
  * Define the structures by which XPC variables can be exported to other
@@ -180,6 +185,17 @@ struct xpc_vars_part_sn2 {
 				 (XPC_RP_MACH_NASIDS(_rp) + \
 				  xpc_nasid_mask_nlongs))
 
+
+/*
+ * The following structure describes the partition's heartbeat info which
+ * will be periodically read by other partitions to determine whether this
+ * XPC is still 'alive'.
+ */
+struct xpc_heartbeat_uv {
+	unsigned long value;
+	unsigned long offline;	/* if 0, heartbeat should be changing */
+};
+
 /*
  * Info pertinent to a GRU message queue using a watch list for irq generation.
  */
@@ -189,14 +205,17 @@ struct xpc_gru_mq_uv {
 	int irq;		/* irq raised when message is received in mq */
 	int mmr_blade;		/* blade where watchlist was allocated from */
 	unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
+	unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
 	int watchlist_num;	/* number of watchlist allocatd by BIOS */
+	void *gru_mq_desc;	/* opaque structure used by the GRU driver */
 };
 
 /*
  * The activate_mq is used to send/receive GRU messages that affect XPC's
- * heartbeat, partition active state, and channel state. This is UV only.
+ * partition active state and channel state. This is uv only.
  */
 struct xpc_activate_mq_msghdr_uv {
+	unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
 	short partid;		/* sender's partid */
 	u8 act_state;		/* sender's act_state at time msg sent */
 	u8 type;		/* message's type */
@@ -205,34 +224,28 @@ struct xpc_activate_mq_msghdr_uv {
 
 /* activate_mq defined message types */
 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV		0
-#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV		1
-#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV	2
-#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV		3
 
-#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		4
-#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		5
+#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		1
+#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		2
 
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	6
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		7
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	8
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		9
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	3
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		4
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	5
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		6
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV	7
 
-#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		10
-#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		11
+#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		8
+#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		9
 
 struct xpc_activate_mq_msg_uv {
 	struct xpc_activate_mq_msghdr_uv hdr;
 };
 
-struct xpc_activate_mq_msg_heartbeat_req_uv {
-	struct xpc_activate_mq_msghdr_uv hdr;
-	u64 heartbeat;
-};
-
 struct xpc_activate_mq_msg_activate_req_uv {
 	struct xpc_activate_mq_msghdr_uv hdr;
 	unsigned long rp_gpa;
-	unsigned long activate_mq_gpa;
+	unsigned long heartbeat_gpa;
+	unsigned long activate_gru_mq_desc_gpa;
 };
 
 struct xpc_activate_mq_msg_deactivate_req_uv {
@@ -263,7 +276,12 @@ struct xpc_activate_mq_msg_chctl_openrep
 	short ch_number;
 	short remote_nentries;	/* ??? Is this needed? What is? */
 	short local_nentries;	/* ??? Is this needed? What is? */
-	unsigned long local_notify_mq_gpa;
+	unsigned long notify_gru_mq_desc_gpa;
+};
+
+struct xpc_activate_mq_msg_chctl_opencomplete_uv {
+	struct xpc_activate_mq_msghdr_uv hdr;
+	short ch_number;
 };
 
 /*
@@ -510,8 +528,8 @@ struct xpc_channel_sn2 {
 };
 
 struct xpc_channel_uv {
-	unsigned long remote_notify_mq_gpa;	/* gru phys address of remote */
-						/* partition's notify mq */
+	void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
+					 /* gru mq descriptor */
 
 	struct xpc_send_msg_slot_uv *send_msg_slots;
 	void *recv_msg_slots;	/* each slot will hold a xpc_notify_mq_msg_uv */
@@ -571,30 +589,32 @@ struct xpc_channel {
 
 #define	XPC_C_WASCONNECTED	0x00000001	/* channel was connected */
 
-#define	XPC_C_ROPENREPLY	0x00000002	/* remote open channel reply */
-#define	XPC_C_OPENREPLY		0x00000004	/* local open channel reply */
-#define	XPC_C_ROPENREQUEST	0x00000008     /* remote open channel request */
-#define	XPC_C_OPENREQUEST	0x00000010	/* local open channel request */
+#define XPC_C_ROPENCOMPLETE	0x00000002    /* remote open channel complete */
+#define XPC_C_OPENCOMPLETE	0x00000004     /* local open channel complete */
+#define	XPC_C_ROPENREPLY	0x00000008	/* remote open channel reply */
+#define	XPC_C_OPENREPLY		0x00000010	/* local open channel reply */
+#define	XPC_C_ROPENREQUEST	0x00000020     /* remote open channel request */
+#define	XPC_C_OPENREQUEST	0x00000040	/* local open channel request */
 
-#define	XPC_C_SETUP		0x00000020 /* channel's msgqueues are alloc'd */
-#define	XPC_C_CONNECTEDCALLOUT	0x00000040     /* connected callout initiated */
+#define	XPC_C_SETUP		0x00000080 /* channel's msgqueues are alloc'd */
+#define	XPC_C_CONNECTEDCALLOUT	0x00000100     /* connected callout initiated */
 #define	XPC_C_CONNECTEDCALLOUT_MADE \
-				0x00000080     /* connected callout completed */
-#define	XPC_C_CONNECTED		0x00000100	/* local channel is connected */
-#define	XPC_C_CONNECTING	0x00000200	/* channel is being connected */
+				0x00000200     /* connected callout completed */
+#define	XPC_C_CONNECTED		0x00000400	/* local channel is connected */
+#define	XPC_C_CONNECTING	0x00000800	/* channel is being connected */
 
-#define	XPC_C_RCLOSEREPLY	0x00000400	/* remote close channel reply */
-#define	XPC_C_CLOSEREPLY	0x00000800	/* local close channel reply */
-#define	XPC_C_RCLOSEREQUEST	0x00001000    /* remote close channel request */
-#define	XPC_C_CLOSEREQUEST	0x00002000     /* local close channel request */
+#define	XPC_C_RCLOSEREPLY	0x00001000	/* remote close channel reply */
+#define	XPC_C_CLOSEREPLY	0x00002000	/* local close channel reply */
+#define	XPC_C_RCLOSEREQUEST	0x00004000    /* remote close channel request */
+#define	XPC_C_CLOSEREQUEST	0x00008000     /* local close channel request */
 
-#define	XPC_C_DISCONNECTED	0x00004000	/* channel is disconnected */
-#define	XPC_C_DISCONNECTING	0x00008000   /* channel is being disconnected */
+#define	XPC_C_DISCONNECTED	0x00010000	/* channel is disconnected */
+#define	XPC_C_DISCONNECTING	0x00020000   /* channel is being disconnected */
 #define	XPC_C_DISCONNECTINGCALLOUT \
-				0x00010000 /* disconnecting callout initiated */
+				0x00040000 /* disconnecting callout initiated */
 #define	XPC_C_DISCONNECTINGCALLOUT_MADE \
-				0x00020000 /* disconnecting callout completed */
-#define	XPC_C_WDISCONNECT	0x00040000  /* waiting for channel disconnect */
+				0x00080000 /* disconnecting callout completed */
+#define	XPC_C_WDISCONNECT	0x00100000  /* waiting for channel disconnect */
 
 /*
  * The channel control flags (chctl) union consists of a 64-bit variable which
@@ -613,11 +633,13 @@ union xpc_channel_ctl_flags {
 #define	XPC_CHCTL_CLOSEREPLY	0x02
 #define	XPC_CHCTL_OPENREQUEST	0x04
 #define	XPC_CHCTL_OPENREPLY	0x08
-#define	XPC_CHCTL_MSGREQUEST	0x10
+#define XPC_CHCTL_OPENCOMPLETE	0x10
+#define	XPC_CHCTL_MSGREQUEST	0x20
 
 #define XPC_OPENCLOSE_CHCTL_FLAGS \
 			(XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
-			 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
+			 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
+			 XPC_CHCTL_OPENCOMPLETE)
 #define XPC_MSG_CHCTL_FLAGS	XPC_CHCTL_MSGREQUEST
 
 static inline int
@@ -682,20 +704,26 @@ struct xpc_partition_sn2 {
 };
 
 struct xpc_partition_uv {
-	unsigned long remote_activate_mq_gpa;	/* gru phys address of remote */
-						/* partition's activate mq */
+	unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
+	struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
+						  /* partition's heartbeat */
+	unsigned long activate_gru_mq_desc_gpa;	/* phys addr of parititon's */
+						/* activate mq's gru mq */
+						/* descriptor */
+	void *cached_activate_gru_mq_desc; /* cached copy of partition's */
+					   /* activate mq's gru mq descriptor */
+	struct mutex cached_activate_gru_mq_desc_mutex;
 	spinlock_t flags_lock;	/* protect updating of flags */
 	unsigned int flags;	/* general flags */
 	u8 remote_act_state;	/* remote partition's act_state */
 	u8 act_state_req;	/* act_state request from remote partition */
 	enum xp_retval reason;	/* reason for deactivate act_state request */
-	u64 heartbeat;		/* incremented by remote partition */
 };
 
 /* struct xpc_partition_uv flags */
 
-#define XPC_P_HEARTBEAT_OFFLINE_UV	0x00000001
-#define XPC_P_ENGAGED_UV		0x00000002
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV	0x00000001
+#define XPC_P_ENGAGED_UV			0x00000002
 
 /* struct xpc_partition_uv act_state change requests */
 
@@ -752,6 +780,62 @@ struct xpc_partition {
 
 } ____cacheline_aligned;
 
+struct xpc_arch_operations {
+	int (*setup_partitions) (void);
+	void (*teardown_partitions) (void);
+	void (*process_activate_IRQ_rcvd) (void);
+	enum xp_retval (*get_partition_rsvd_page_pa)
+		(void *, u64 *, unsigned long *, size_t *);
+	int (*setup_rsvd_page) (struct xpc_rsvd_page *);
+
+	void (*allow_hb) (short);
+	void (*disallow_hb) (short);
+	void (*disallow_all_hbs) (void);
+	void (*increment_heartbeat) (void);
+	void (*offline_heartbeat) (void);
+	void (*online_heartbeat) (void);
+	void (*heartbeat_init) (void);
+	void (*heartbeat_exit) (void);
+	enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
+
+	void (*request_partition_activation) (struct xpc_rsvd_page *,
+						 unsigned long, int);
+	void (*request_partition_reactivation) (struct xpc_partition *);
+	void (*request_partition_deactivation) (struct xpc_partition *);
+	void (*cancel_partition_deactivation_request) (struct xpc_partition *);
+	enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
+	void (*teardown_ch_structures) (struct xpc_partition *);
+
+	enum xp_retval (*make_first_contact) (struct xpc_partition *);
+
+	u64 (*get_chctl_all_flags) (struct xpc_partition *);
+	void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
+	void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
+	void (*process_msg_chctl_flags) (struct xpc_partition *, int);
+
+	enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
+						      unsigned long);
+
+	enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
+	void (*teardown_msg_structures) (struct xpc_channel *);
+
+	void (*indicate_partition_engaged) (struct xpc_partition *);
+	void (*indicate_partition_disengaged) (struct xpc_partition *);
+	void (*assume_partition_disengaged) (short);
+	int (*partition_engaged) (short);
+	int (*any_partition_engaged) (void);
+
+	int (*n_of_deliverable_payloads) (struct xpc_channel *);
+	enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
+					   u16, u8, xpc_notify_func, void *);
+	void *(*get_deliverable_payload) (struct xpc_channel *);
+	void (*received_payload) (struct xpc_channel *, void *);
+	void (*notify_senders_of_disconnect) (struct xpc_channel *);
+};
+
 /* struct xpc_partition act_state values (for XPC HB) */
 
 #define	XPC_P_AS_INACTIVE	0x00	/* partition is not active */
@@ -792,66 +876,17 @@ extern struct xpc_registration xpc_regis
 /* found in xpc_main.c */
 extern struct device *xpc_part;
 extern struct device *xpc_chan;
+extern struct xpc_arch_operations xpc_arch_ops;
 extern int xpc_disengage_timelimit;
 extern int xpc_disengage_timedout;
 extern int xpc_activate_IRQ_rcvd;
 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
 extern wait_queue_head_t xpc_activate_IRQ_wq;
-extern void *xpc_heartbeating_to_mask;
 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
 extern void xpc_disconnect_wait(int);
-extern int (*xpc_setup_partitions_sn) (void);
-extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
-							 unsigned long *,
-							 size_t *);
-extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
-extern void (*xpc_heartbeat_init) (void);
-extern void (*xpc_heartbeat_exit) (void);
-extern void (*xpc_increment_heartbeat) (void);
-extern void (*xpc_offline_heartbeat) (void);
-extern void (*xpc_online_heartbeat) (void);
-extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
-extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
-extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
-extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
-extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
-extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
-extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
-extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
-extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
-extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
-						 unsigned long, int);
-extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
-extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_deactivation_request) (
-							struct xpc_partition *);
-extern void (*xpc_process_activate_IRQ_rcvd) (void);
-extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
-extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
-
-extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
-extern int (*xpc_partition_engaged) (short);
-extern int (*xpc_any_partition_engaged) (void);
-extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_assume_partition_disengaged) (short);
-
-extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
-					    unsigned long *);
-extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
-					  unsigned long *);
-extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
-					   unsigned long *);
-extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-
-extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
-					    unsigned long);
-
-extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
-					   u16, u8, xpc_notify_func, void *);
-extern void (*xpc_received_payload) (struct xpc_channel *, void *);
 
 /* found in xpc_sn2.c */
 extern int xpc_init_sn2(void);
@@ -898,40 +933,6 @@ extern void xpc_disconnect_channel(const
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 
-static inline int
-xpc_hb_allowed(short partid, void *heartbeating_to_mask)
-{
-	return test_bit(partid, heartbeating_to_mask);
-}
-
-static inline int
-xpc_any_hbs_allowed(void)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
-static inline void
-xpc_allow_hb(short partid)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	set_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_hb(short partid)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	clear_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_all_hbs(void)
-{
-	DBUG_ON(xpc_heartbeating_to_mask == NULL);
-	bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
 static inline void
 xpc_wakeup_channel_mgr(struct xpc_partition *part)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_main.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_main.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -150,7 +150,6 @@ DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ
 
 static unsigned long xpc_hb_check_timeout;
 static struct timer_list xpc_hb_timer;
-void *xpc_heartbeating_to_mask;
 
 /* notification that the xpc_hb_checker thread has exited */
 static DECLARE_COMPLETION(xpc_hb_checker_exited);
@@ -170,61 +169,7 @@ static struct notifier_block xpc_die_not
 	.notifier_call = xpc_system_die,
 };
 
-int (*xpc_setup_partitions_sn) (void);
-enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
-						  unsigned long *rp_pa,
-						  size_t *len);
-int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp);
-void (*xpc_heartbeat_init) (void);
-void (*xpc_heartbeat_exit) (void);
-void (*xpc_increment_heartbeat) (void);
-void (*xpc_offline_heartbeat) (void);
-void (*xpc_online_heartbeat) (void);
-enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *part);
-
-enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
-void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
-u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *part);
-enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch);
-void (*xpc_teardown_msg_structures) (struct xpc_channel *ch);
-void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number);
-int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch);
-void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch);
-
-void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
-					  unsigned long remote_rp_pa,
-					  int nasid);
-void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
-void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
-void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
-
-void (*xpc_process_activate_IRQ_rcvd) (void);
-enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *part);
-void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *part);
-
-void (*xpc_indicate_partition_engaged) (struct xpc_partition *part);
-int (*xpc_partition_engaged) (short partid);
-int (*xpc_any_partition_engaged) (void);
-void (*xpc_indicate_partition_disengaged) (struct xpc_partition *part);
-void (*xpc_assume_partition_disengaged) (short partid);
-
-void (*xpc_send_chctl_closerequest) (struct xpc_channel *ch,
-				     unsigned long *irq_flags);
-void (*xpc_send_chctl_closereply) (struct xpc_channel *ch,
-				   unsigned long *irq_flags);
-void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch,
-				    unsigned long *irq_flags);
-void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
-				  unsigned long *irq_flags);
-
-void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
-				     unsigned long msgqueue_pa);
-
-enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
-				    void *payload, u16 payload_size,
-				    u8 notify_type, xpc_notify_func func,
-				    void *key);
-void (*xpc_received_payload) (struct xpc_channel *ch, void *payload);
+struct xpc_arch_operations xpc_arch_ops;
 
 /*
  * Timer function to enforce the timelimit on the partition disengage.
@@ -239,7 +184,7 @@ xpc_timeout_partition_disengage(unsigned
 	(void)xpc_partition_disengaged(part);
 
 	DBUG_ON(part->disengage_timeout != 0);
-	DBUG_ON(xpc_partition_engaged(XPC_PARTID(part)));
+	DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
 }
 
 /*
@@ -250,7 +195,7 @@ xpc_timeout_partition_disengage(unsigned
 static void
 xpc_hb_beater(unsigned long dummy)
 {
-	xpc_increment_heartbeat();
+	xpc_arch_ops.increment_heartbeat();
 
 	if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
 		wake_up_interruptible(&xpc_activate_IRQ_wq);
@@ -262,7 +207,7 @@ xpc_hb_beater(unsigned long dummy)
 static void
 xpc_start_hb_beater(void)
 {
-	xpc_heartbeat_init();
+	xpc_arch_ops.heartbeat_init();
 	init_timer(&xpc_hb_timer);
 	xpc_hb_timer.function = xpc_hb_beater;
 	xpc_hb_beater(0);
@@ -272,7 +217,7 @@ static void
 xpc_stop_hb_beater(void)
 {
 	del_timer_sync(&xpc_hb_timer);
-	xpc_heartbeat_exit();
+	xpc_arch_ops.heartbeat_exit();
 }
 
 /*
@@ -301,7 +246,7 @@ xpc_check_remote_hb(void)
 			continue;
 		}
 
-		ret = xpc_get_remote_heartbeat(part);
+		ret = xpc_arch_ops.get_remote_heartbeat(part);
 		if (ret != xpSuccess)
 			XPC_DEACTIVATE_PARTITION(part, ret);
 	}
@@ -318,7 +263,7 @@ xpc_hb_checker(void *ignore)
 
 	/* this thread was marked active by xpc_hb_init() */
 
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(XPC_HB_CHECK_CPU));
+	set_cpus_allowed_ptr(current, cpumask_of(XPC_HB_CHECK_CPU));
 
 	/* set our heartbeating to other partitions into motion */
 	xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
@@ -352,7 +297,7 @@ xpc_hb_checker(void *ignore)
 			force_IRQ = 0;
 			dev_dbg(xpc_part, "processing activate IRQs "
 				"received\n");
-			xpc_process_activate_IRQ_rcvd();
+			xpc_arch_ops.process_activate_IRQ_rcvd();
 		}
 
 		/* wait for IRQ or timeout */
@@ -527,7 +472,7 @@ xpc_setup_ch_structures(struct xpc_parti
 		init_waitqueue_head(&ch->idle_wq);
 	}
 
-	ret = xpc_setup_ch_structures_sn(part);
+	ret = xpc_arch_ops.setup_ch_structures(part);
 	if (ret != xpSuccess)
 		goto out_2;
 
@@ -571,7 +516,7 @@ xpc_teardown_ch_structures(struct xpc_pa
 
 	/* now we can begin tearing down the infrastructure */
 
-	xpc_teardown_ch_structures_sn(part);
+	xpc_arch_ops.teardown_ch_structures(part);
 
 	kfree(part->remote_openclose_args_base);
 	part->remote_openclose_args = NULL;
@@ -619,12 +564,12 @@ xpc_activating(void *__partid)
 
 	dev_dbg(xpc_part, "activating partition %d\n", partid);
 
-	xpc_allow_hb(partid);
+	xpc_arch_ops.allow_hb(partid);
 
 	if (xpc_setup_ch_structures(part) == xpSuccess) {
 		(void)xpc_part_ref(part);	/* this will always succeed */
 
-		if (xpc_make_first_contact(part) == xpSuccess) {
+		if (xpc_arch_ops.make_first_contact(part) == xpSuccess) {
 			xpc_mark_partition_active(part);
 			xpc_channel_mgr(part);
 			/* won't return until partition is deactivating */
@@ -634,12 +579,12 @@ xpc_activating(void *__partid)
 		xpc_teardown_ch_structures(part);
 	}
 
-	xpc_disallow_hb(partid);
+	xpc_arch_ops.disallow_hb(partid);
 	xpc_mark_partition_inactive(part);
 
 	if (part->reason == xpReactivating) {
 		/* interrupting ourselves results in activating partition */
-		xpc_request_partition_reactivation(part);
+		xpc_arch_ops.request_partition_reactivation(part);
 	}
 
 	return 0;
@@ -712,10 +657,13 @@ xpc_activate_kthreads(struct xpc_channel
 static void
 xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
 {
+	int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+		xpc_arch_ops.n_of_deliverable_payloads;
+
 	do {
 		/* deliver messages to their intended recipients */
 
-		while (xpc_n_of_deliverable_payloads(ch) > 0 &&
+		while (n_of_deliverable_payloads(ch) > 0 &&
 		       !(ch->flags & XPC_C_DISCONNECTING)) {
 			xpc_deliver_payload(ch);
 		}
@@ -731,7 +679,7 @@ xpc_kthread_waitmsgs(struct xpc_partitio
 			"wait_event_interruptible_exclusive()\n");
 
 		(void)wait_event_interruptible_exclusive(ch->idle_wq,
-				(xpc_n_of_deliverable_payloads(ch) > 0 ||
+				(n_of_deliverable_payloads(ch) > 0 ||
 				 (ch->flags & XPC_C_DISCONNECTING)));
 
 		atomic_dec(&ch->kthreads_idle);
@@ -748,6 +696,8 @@ xpc_kthread_start(void *args)
 	struct xpc_channel *ch;
 	int n_needed;
 	unsigned long irq_flags;
+	int (*n_of_deliverable_payloads) (struct xpc_channel *) =
+		xpc_arch_ops.n_of_deliverable_payloads;
 
 	dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
 		partid, ch_number);
@@ -776,7 +726,7 @@ xpc_kthread_start(void *args)
 			 * additional kthreads to help deliver them. We only
 			 * need one less than total #of messages to deliver.
 			 */
-			n_needed = xpc_n_of_deliverable_payloads(ch) - 1;
+			n_needed = n_of_deliverable_payloads(ch) - 1;
 			if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
 				xpc_activate_kthreads(ch, n_needed);
 
@@ -804,7 +754,7 @@ xpc_kthread_start(void *args)
 
 	if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
 	    atomic_dec_return(&part->nchannels_engaged) == 0) {
-		xpc_indicate_partition_disengaged(part);
+		xpc_arch_ops.indicate_partition_disengaged(part);
 	}
 
 	xpc_msgqueue_deref(ch);
@@ -836,6 +786,8 @@ xpc_create_kthreads(struct xpc_channel *
 	u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
 	struct task_struct *kthread;
+	void (*indicate_partition_disengaged) (struct xpc_partition *) =
+		xpc_arch_ops.indicate_partition_disengaged;
 
 	while (needed-- > 0) {
 
@@ -857,7 +809,7 @@ xpc_create_kthreads(struct xpc_channel *
 
 		} else if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
 			   atomic_inc_return(&part->nchannels_engaged) == 1) {
-				xpc_indicate_partition_engaged(part);
+			xpc_arch_ops.indicate_partition_engaged(part);
 		}
 		(void)xpc_part_ref(part);
 		xpc_msgqueue_ref(ch);
@@ -879,7 +831,7 @@ xpc_create_kthreads(struct xpc_channel *
 
 			if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
 			    atomic_dec_return(&part->nchannels_engaged) == 0) {
-				xpc_indicate_partition_disengaged(part);
+				indicate_partition_disengaged(part);
 			}
 			xpc_msgqueue_deref(ch);
 			xpc_part_deref(part);
@@ -992,12 +944,13 @@ xpc_setup_partitions(void)
 		atomic_set(&part->references, 0);
 	}
 
-	return xpc_setup_partitions_sn();
+	return xpc_arch_ops.setup_partitions();
 }
 
 static void
 xpc_teardown_partitions(void)
 {
+	xpc_arch_ops.teardown_partitions();
 	kfree(xpc_partitions);
 }
 
@@ -1053,7 +1006,7 @@ xpc_do_exit(enum xp_retval reason)
 				disengage_timeout = part->disengage_timeout;
 		}
 
-		if (xpc_any_partition_engaged()) {
+		if (xpc_arch_ops.any_partition_engaged()) {
 			if (time_is_before_jiffies(printmsg_time)) {
 				dev_info(xpc_part, "waiting for remote "
 					 "partitions to deactivate, timeout in "
@@ -1084,8 +1037,7 @@ xpc_do_exit(enum xp_retval reason)
 
 	} while (1);
 
-	DBUG_ON(xpc_any_partition_engaged());
-	DBUG_ON(xpc_any_hbs_allowed() != 0);
+	DBUG_ON(xpc_arch_ops.any_partition_engaged());
 
 	xpc_teardown_rsvd_page();
 
@@ -1150,15 +1102,15 @@ xpc_die_deactivate(void)
 	/* keep xpc_hb_checker thread from doing anything (just in case) */
 	xpc_exiting = 1;
 
-	xpc_disallow_all_hbs();	/*indicate we're deactivated */
+	xpc_arch_ops.disallow_all_hbs();   /*indicate we're deactivated */
 
 	for (partid = 0; partid < xp_max_npartitions; partid++) {
 		part = &xpc_partitions[partid];
 
-		if (xpc_partition_engaged(partid) ||
+		if (xpc_arch_ops.partition_engaged(partid) ||
 		    part->act_state != XPC_P_AS_INACTIVE) {
-			xpc_request_partition_deactivation(part);
-			xpc_indicate_partition_disengaged(part);
+			xpc_arch_ops.request_partition_deactivation(part);
+			xpc_arch_ops.indicate_partition_disengaged(part);
 		}
 	}
 
@@ -1175,7 +1127,7 @@ xpc_die_deactivate(void)
 	wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5;
 
 	while (1) {
-		any_engaged = xpc_any_partition_engaged();
+		any_engaged = xpc_arch_ops.any_partition_engaged();
 		if (!any_engaged) {
 			dev_info(xpc_part, "all partitions have deactivated\n");
 			break;
@@ -1184,7 +1136,7 @@ xpc_die_deactivate(void)
 		if (!keep_waiting--) {
 			for (partid = 0; partid < xp_max_npartitions;
 			     partid++) {
-				if (xpc_partition_engaged(partid)) {
+				if (xpc_arch_ops.partition_engaged(partid)) {
 					dev_info(xpc_part, "deactivate from "
 						 "remote partition %d timed "
 						 "out\n", partid);
@@ -1231,7 +1183,7 @@ xpc_system_die(struct notifier_block *nb
 		/* fall through */
 	case DIE_MCA_MONARCH_ENTER:
 	case DIE_INIT_MONARCH_ENTER:
-		xpc_offline_heartbeat();
+		xpc_arch_ops.offline_heartbeat();
 		break;
 
 	case DIE_KDEBUG_LEAVE:
@@ -1242,7 +1194,7 @@ xpc_system_die(struct notifier_block *nb
 		/* fall through */
 	case DIE_MCA_MONARCH_LEAVE:
 	case DIE_INIT_MONARCH_LEAVE:
-		xpc_online_heartbeat();
+		xpc_arch_ops.online_heartbeat();
 		break;
 	}
 #else
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_partition.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_partition.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_partition.c	2009-06-09 23:05:27.000000000 -0400
@@ -70,6 +70,9 @@ xpc_get_rsvd_page_pa(int nasid)
 	size_t buf_len = 0;
 	void *buf = buf;
 	void *buf_base = NULL;
+	enum xp_retval (*get_partition_rsvd_page_pa)
+		(void *, u64 *, unsigned long *, size_t *) =
+		xpc_arch_ops.get_partition_rsvd_page_pa;
 
 	while (1) {
 
@@ -79,8 +82,7 @@ xpc_get_rsvd_page_pa(int nasid)
 		 * ??? function or have two versions? Rename rp_pa for UV to
 		 * ??? rp_gpa?
 		 */
-		ret = xpc_get_partition_rsvd_page_pa(buf, &cookie, &rp_pa,
-						     &len);
+		ret = get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, &len);
 
 		dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, "
 			"address=0x%016lx, len=0x%016lx\n", ret,
@@ -172,7 +174,7 @@ xpc_setup_rsvd_page(void)
 	xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
 	xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
 
-	ret = xpc_setup_rsvd_page_sn(rp);
+	ret = xpc_arch_ops.setup_rsvd_page(rp);
 	if (ret != 0)
 		return ret;
 
@@ -264,7 +266,7 @@ xpc_partition_disengaged(struct xpc_part
 	short partid = XPC_PARTID(part);
 	int disengaged;
 
-	disengaged = !xpc_partition_engaged(partid);
+	disengaged = !xpc_arch_ops.partition_engaged(partid);
 	if (part->disengage_timeout) {
 		if (!disengaged) {
 			if (time_is_after_jiffies(part->disengage_timeout)) {
@@ -280,7 +282,7 @@ xpc_partition_disengaged(struct xpc_part
 			dev_info(xpc_part, "deactivate request to remote "
 				 "partition %d timed out\n", partid);
 			xpc_disengage_timedout = 1;
-			xpc_assume_partition_disengaged(partid);
+			xpc_arch_ops.assume_partition_disengaged(partid);
 			disengaged = 1;
 		}
 		part->disengage_timeout = 0;
@@ -294,7 +296,7 @@ xpc_partition_disengaged(struct xpc_part
 		if (part->act_state != XPC_P_AS_INACTIVE)
 			xpc_wakeup_channel_mgr(part);
 
-		xpc_cancel_partition_deactivation_request(part);
+		xpc_arch_ops.cancel_partition_deactivation_request(part);
 	}
 	return disengaged;
 }
@@ -339,7 +341,7 @@ xpc_deactivate_partition(const int line,
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		if (reason == xpReactivating) {
 			/* we interrupt ourselves to reactivate partition */
-			xpc_request_partition_reactivation(part);
+			xpc_arch_ops.request_partition_reactivation(part);
 		}
 		return;
 	}
@@ -358,7 +360,7 @@ xpc_deactivate_partition(const int line,
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
 
 	/* ask remote partition to deactivate with regard to us */
-	xpc_request_partition_deactivation(part);
+	xpc_arch_ops.request_partition_deactivation(part);
 
 	/* set a timelimit on the disengage phase of the deactivation request */
 	part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
@@ -496,7 +498,7 @@ xpc_discovery(void)
 				continue;
 			}
 
-			xpc_request_partition_activation(remote_rp,
+			xpc_arch_ops.request_partition_activation(remote_rp,
 							 remote_rp_pa, nasid);
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_sn2.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_sn2.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_sn2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_sn2.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -60,12 +60,18 @@ static struct xpc_vars_sn2 *xpc_vars_sn2
 static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
 
 static int
-xpc_setup_partitions_sn_sn2(void)
+xpc_setup_partitions_sn2(void)
 {
 	/* nothing needs to be done */
 	return 0;
 }
 
+static void
+xpc_teardown_partitions_sn2(void)
+{
+	/* nothing needs to be done */
+}
+
 /* SH_IPI_ACCESS shub register value on startup */
 static u64 xpc_sh1_IPI_access_sn2;
 static u64 xpc_sh2_IPI_access0_sn2;
@@ -425,6 +431,13 @@ xpc_send_chctl_openreply_sn2(struct xpc_
 }
 
 static void
+xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch,
+				unsigned long *irq_flags)
+{
+	XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags);
+}
+
+static void
 xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch)
 {
 	XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL);
@@ -436,11 +449,12 @@ xpc_send_chctl_local_msgrequest_sn2(stru
 	XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST);
 }
 
-static void
+static enum xp_retval
 xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch,
 				unsigned long msgqueue_pa)
 {
 	ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa;
+	return xpSuccess;
 }
 
 /*
@@ -614,7 +628,7 @@ xpc_get_partition_rsvd_page_pa_sn2(void
 
 
 static int
-xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp)
 {
 	struct amo *amos_page;
 	int i;
@@ -622,7 +636,7 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rs
 
 	xpc_vars_sn2 = XPC_RP_VARS(rp);
 
-	rp->sn.vars_pa = xp_pa(xpc_vars_sn2);
+	rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2);
 
 	/* vars_part array follows immediately after vars */
 	xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
@@ -686,6 +700,33 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rs
 	return 0;
 }
 
+static int
+xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask)
+{
+	return test_bit(partid, heartbeating_to_mask);
+}
+
+static void
+xpc_allow_hb_sn2(short partid)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	set_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_hb_sn2(short partid)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
+}
+
+static void
+xpc_disallow_all_hbs_sn2(void)
+{
+	DBUG_ON(xpc_vars_sn2 == NULL);
+	bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions);
+}
+
 static void
 xpc_increment_heartbeat_sn2(void)
 {
@@ -712,7 +753,6 @@ xpc_heartbeat_init_sn2(void)
 	DBUG_ON(xpc_vars_sn2 == NULL);
 
 	bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
-	xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0];
 	xpc_online_heartbeat_sn2();
 }
 
@@ -744,9 +784,9 @@ xpc_get_remote_heartbeat_sn2(struct xpc_
 		remote_vars->heartbeating_to_mask[0]);
 
 	if ((remote_vars->heartbeat == part->last_heartbeat &&
-	    remote_vars->heartbeat_offline == 0) ||
-	    !xpc_hb_allowed(sn_partition_id,
-			    &remote_vars->heartbeating_to_mask)) {
+	    !remote_vars->heartbeat_offline) ||
+	    !xpc_hb_allowed_sn2(sn_partition_id,
+				remote_vars->heartbeating_to_mask)) {
 		ret = xpNoHeartbeat;
 	} else {
 		part->last_heartbeat = remote_vars->heartbeat;
@@ -965,7 +1005,7 @@ xpc_identify_activate_IRQ_req_sn2(int na
 		return;
 	}
 
-	remote_vars_pa = remote_rp->sn.vars_pa;
+	remote_vars_pa = remote_rp->sn.sn2.vars_pa;
 	remote_rp_version = remote_rp->version;
 	remote_rp_ts_jiffies = remote_rp->ts_jiffies;
 
@@ -1122,7 +1162,7 @@ xpc_process_activate_IRQ_rcvd_sn2(void)
  * Setup the channel structures that are sn2 specific.
  */
 static enum xp_retval
-xpc_setup_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_setup_ch_structures_sn2(struct xpc_partition *part)
 {
 	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	struct xpc_channel_sn2 *ch_sn2;
@@ -1244,7 +1284,7 @@ out_1:
  * Teardown the channel structures that are sn2 specific.
  */
 static void
-xpc_teardown_ch_structures_sn_sn2(struct xpc_partition *part)
+xpc_teardown_ch_structures_sn2(struct xpc_partition *part)
 {
 	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	short partid = XPC_PARTID(part);
@@ -1737,20 +1777,20 @@ xpc_clear_remote_msgqueue_flags_sn2(stru
 {
 	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg_sn2 *msg;
-	s64 put;
+	s64 put, remote_nentries = ch->remote_nentries;
 
 	/* flags are zeroed when the buffer is allocated */
-	if (ch_sn2->remote_GP.put < ch->remote_nentries)
+	if (ch_sn2->remote_GP.put < remote_nentries)
 		return;
 
-	put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries);
+	put = max(ch_sn2->w_remote_GP.put, remote_nentries);
 	do {
 		msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
-					     (put % ch->remote_nentries) *
+					     (put % remote_nentries) *
 					     ch->entry_size);
 		DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
 		DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
-		DBUG_ON(msg->number != put - ch->remote_nentries);
+		DBUG_ON(msg->number != put - remote_nentries);
 		msg->flags = 0;
 	} while (++put < ch_sn2->remote_GP.put);
 }
@@ -2308,60 +2348,70 @@ xpc_received_payload_sn2(struct xpc_chan
 		xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
 }
 
-int
-xpc_init_sn2(void)
-{
-	int ret;
-	size_t buf_size;
+static struct xpc_arch_operations xpc_arch_ops_sn2 = {
+	.setup_partitions = xpc_setup_partitions_sn2,
+	.teardown_partitions = xpc_teardown_partitions_sn2,
+	.process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2,
+	.get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2,
+	.setup_rsvd_page = xpc_setup_rsvd_page_sn2,
 
-	xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2;
-	xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
-	xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2;
-	xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
-	xpc_offline_heartbeat = xpc_offline_heartbeat_sn2;
-	xpc_online_heartbeat = xpc_online_heartbeat_sn2;
-	xpc_heartbeat_init = xpc_heartbeat_init_sn2;
-	xpc_heartbeat_exit = xpc_heartbeat_exit_sn2;
-	xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_sn2;
+	.allow_hb = xpc_allow_hb_sn2,
+	.disallow_hb = xpc_disallow_hb_sn2,
+	.disallow_all_hbs = xpc_disallow_all_hbs_sn2,
+	.increment_heartbeat = xpc_increment_heartbeat_sn2,
+	.offline_heartbeat = xpc_offline_heartbeat_sn2,
+	.online_heartbeat = xpc_online_heartbeat_sn2,
+	.heartbeat_init = xpc_heartbeat_init_sn2,
+	.heartbeat_exit = xpc_heartbeat_exit_sn2,
+	.get_remote_heartbeat = xpc_get_remote_heartbeat_sn2,
 
-	xpc_request_partition_activation = xpc_request_partition_activation_sn2;
-	xpc_request_partition_reactivation =
-	    xpc_request_partition_reactivation_sn2;
-	xpc_request_partition_deactivation =
-	    xpc_request_partition_deactivation_sn2;
-	xpc_cancel_partition_deactivation_request =
-	    xpc_cancel_partition_deactivation_request_sn2;
+	.request_partition_activation =
+		xpc_request_partition_activation_sn2,
+	.request_partition_reactivation =
+		xpc_request_partition_reactivation_sn2,
+	.request_partition_deactivation =
+		xpc_request_partition_deactivation_sn2,
+	.cancel_partition_deactivation_request =
+		xpc_cancel_partition_deactivation_request_sn2,
 
-	xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2;
-	xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_sn2;
-	xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_sn2;
-	xpc_make_first_contact = xpc_make_first_contact_sn2;
+	.setup_ch_structures = xpc_setup_ch_structures_sn2,
+	.teardown_ch_structures = xpc_teardown_ch_structures_sn2,
 
-	xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_sn2;
-	xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_sn2;
-	xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2;
-	xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2;
-	xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2;
+	.make_first_contact = xpc_make_first_contact_sn2,
 
-	xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2;
+	.get_chctl_all_flags = xpc_get_chctl_all_flags_sn2,
+	.send_chctl_closerequest = xpc_send_chctl_closerequest_sn2,
+	.send_chctl_closereply = xpc_send_chctl_closereply_sn2,
+	.send_chctl_openrequest = xpc_send_chctl_openrequest_sn2,
+	.send_chctl_openreply = xpc_send_chctl_openreply_sn2,
+	.send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2,
+	.process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2,
 
-	xpc_setup_msg_structures = xpc_setup_msg_structures_sn2;
-	xpc_teardown_msg_structures = xpc_teardown_msg_structures_sn2;
+	.save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2,
 
-	xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2;
-	xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2;
-	xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2;
-	xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2;
+	.setup_msg_structures = xpc_setup_msg_structures_sn2,
+	.teardown_msg_structures = xpc_teardown_msg_structures_sn2,
 
-	xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2;
-	xpc_indicate_partition_disengaged =
-	    xpc_indicate_partition_disengaged_sn2;
-	xpc_partition_engaged = xpc_partition_engaged_sn2;
-	xpc_any_partition_engaged = xpc_any_partition_engaged_sn2;
-	xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2;
+	.indicate_partition_engaged = xpc_indicate_partition_engaged_sn2,
+	.indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2,
+	.partition_engaged = xpc_partition_engaged_sn2,
+	.any_partition_engaged = xpc_any_partition_engaged_sn2,
+	.assume_partition_disengaged = xpc_assume_partition_disengaged_sn2,
 
-	xpc_send_payload = xpc_send_payload_sn2;
-	xpc_received_payload = xpc_received_payload_sn2;
+	.n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2,
+	.send_payload = xpc_send_payload_sn2,
+	.get_deliverable_payload = xpc_get_deliverable_payload_sn2,
+	.received_payload = xpc_received_payload_sn2,
+	.notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2,
+};
+
+int
+xpc_init_sn2(void)
+{
+	int ret;
+	size_t buf_size;
+
+	xpc_arch_ops = xpc_arch_ops_sn2;
 
 	if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
 		dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_uv.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_uv.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xpc_uv.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,8 +31,22 @@
 #include "../sgi-gru/grukservices.h"
 #include "xpc.h"
 
-static atomic64_t xpc_heartbeat_uv;
-static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
+#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+struct uv_IO_APIC_route_entry {
+	__u64	vector		:  8,
+		delivery_mode	:  3,
+		dest_mode	:  1,
+		delivery_status	:  1,
+		polarity	:  1,
+		__reserved_1	:  1,
+		trigger		:  1,
+		mask		:  1,
+		__reserved_2	: 15,
+		dest		: 32;
+};
+#endif
+
+static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
 
 #define XPC_ACTIVATE_MSG_SIZE_UV	(1 * GRU_CACHE_LINE_BYTES)
 #define XPC_ACTIVATE_MQ_SIZE_UV		(4 * XP_MAX_NPARTITIONS_UV * \
@@ -48,7 +62,7 @@ static struct xpc_gru_mq_uv *xpc_activat
 static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
 
 static int
-xpc_setup_partitions_sn_uv(void)
+xpc_setup_partitions_uv(void)
 {
 	short partid;
 	struct xpc_partition_uv *part_uv;
@@ -56,26 +70,52 @@ xpc_setup_partitions_sn_uv(void)
 	for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
 		part_uv = &xpc_partitions[partid].sn.uv;
 
+		mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex);
 		spin_lock_init(&part_uv->flags_lock);
 		part_uv->remote_act_state = XPC_P_AS_INACTIVE;
 	}
 	return 0;
 }
 
+static void
+xpc_teardown_partitions_uv(void)
+{
+	short partid;
+	struct xpc_partition_uv *part_uv;
+	unsigned long irq_flags;
+
+	for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
+		part_uv = &xpc_partitions[partid].sn.uv;
+
+		if (part_uv->cached_activate_gru_mq_desc != NULL) {
+			mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+			spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+			part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+			spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+			kfree(part_uv->cached_activate_gru_mq_desc);
+			part_uv->cached_activate_gru_mq_desc = NULL;
+			mutex_unlock(&part_uv->
+				     cached_activate_gru_mq_desc_mutex);
+		}
+	}
+}
+
 static int
 xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
 {
+	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);
 	if (mq->irq < 0) {
 		dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
-			mq->irq);
+			-mq->irq);
+		return mq->irq;
 	}
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-	int mmr_pnode;
-	unsigned long mmr_value;
+	mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
 
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
 	if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
 		mq->irq = SGI_XPC_ACTIVATE;
 	else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
@@ -83,10 +123,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_
 	else
 		return -EINVAL;
 
-	mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-	mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
-
-	uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
+	mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
+	uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
 #else
 	#error not a supported configuration
 #endif
@@ -127,7 +165,7 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc
 		return ret;
 	}
 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-	ret = sn_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
+	ret = sn_mq_watchlist_alloc(mq->mmr_blade, (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",
@@ -168,12 +206,22 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
 	int pg_order;
 	struct page *page;
 	struct xpc_gru_mq_uv *mq;
+	struct uv_IO_APIC_route_entry *mmr_value;
 
 	mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
 	if (mq == NULL) {
 		dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
 			"a xpc_gru_mq_uv structure\n");
 		ret = -ENOMEM;
+		goto out_0;
+	}
+
+	mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc),
+				  GFP_KERNEL);
+	if (mq->gru_mq_desc == NULL) {
+		dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
+			"a gru_message_queue_desc structure\n");
+		ret = -ENOMEM;
 		goto out_1;
 	}
 
@@ -194,14 +242,6 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
 	}
 	mq->address = page_address(page);
 
-	ret = gru_create_message_queue(mq->address, mq_size);
-	if (ret != 0) {
-		dev_err(xpc_part, "gru_create_message_queue() returned "
-			"error=%d\n", ret);
-		ret = -EINVAL;
-		goto out_3;
-	}
-
 	/* enable generation of irq when GRU mq operation occurs to this mq */
 	ret = xpc_gru_mq_watchlist_alloc_uv(mq);
 	if (ret != 0)
@@ -214,10 +254,20 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
 	ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
 	if (ret != 0) {
 		dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
-			mq->irq, ret);
+			mq->irq, -ret);
 		goto out_5;
 	}
 
+	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);
+	if (ret != 0) {
+		dev_err(xpc_part, "gru_create_message_queue() returned "
+			"error=%d\n", ret);
+		ret = -EINVAL;
+		goto out_6;
+	}
+
 	/* allow other partitions to access this GRU mq */
 	xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
 	if (xp_ret != xpSuccess) {
@@ -237,8 +287,10 @@ out_4:
 out_3:
 	free_pages((unsigned long)mq->address, pg_order);
 out_2:
-	kfree(mq);
+	kfree(mq->gru_mq_desc);
 out_1:
+	kfree(mq);
+out_0:
 	return ERR_PTR(ret);
 }
 
@@ -268,13 +320,14 @@ xpc_destroy_gru_mq_uv(struct xpc_gru_mq_
 }
 
 static enum xp_retval
-xpc_send_gru_msg(unsigned long mq_gpa, void *msg, size_t msg_size)
+xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg,
+		 size_t msg_size)
 {
 	enum xp_retval xp_ret;
 	int ret;
 
 	while (1) {
-		ret = gru_send_message_gpa(mq_gpa, msg, msg_size);
+		ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size);
 		if (ret == MQE_OK) {
 			xp_ret = xpSuccess;
 			break;
@@ -369,41 +422,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc
 		/* syncing of remote_act_state was just done above */
 		break;
 
-	case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-		break;
-	}
-	case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-
-		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
-		part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV;
-		spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
-		break;
-	}
-	case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: {
-		struct xpc_activate_mq_msg_heartbeat_req_uv *msg;
-
-		msg = container_of(msg_hdr,
-				   struct xpc_activate_mq_msg_heartbeat_req_uv,
-				   hdr);
-		part_uv->heartbeat = msg->heartbeat;
-
-		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
-		part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV;
-		spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
-		break;
-	}
 	case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: {
 		struct xpc_activate_mq_msg_activate_req_uv *msg;
 
@@ -421,7 +439,16 @@ xpc_handle_activate_mq_msg_uv(struct xpc
 		part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
 		part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
 		part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
-		part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa;
+		part_uv->heartbeat_gpa = msg->heartbeat_gpa;
+
+		if (msg->activate_gru_mq_desc_gpa !=
+		    part_uv->activate_gru_mq_desc_gpa) {
+			spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+			part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+			spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+			part_uv->activate_gru_mq_desc_gpa =
+			    msg->activate_gru_mq_desc_gpa;
+		}
 		spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
 
 		(*wakeup_hb_checker)++;
@@ -498,7 +525,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc
 		args = &part->remote_openclose_args[msg->ch_number];
 		args->remote_nentries = msg->remote_nentries;
 		args->local_nentries = msg->local_nentries;
-		args->local_msgqueue_pa = msg->local_notify_mq_gpa;
+		args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa;
 
 		spin_lock_irqsave(&part->chctl_lock, irq_flags);
 		part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY;
@@ -507,6 +534,17 @@ xpc_handle_activate_mq_msg_uv(struct xpc
 		xpc_wakeup_channel_mgr(part);
 		break;
 	}
+	case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
+		struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
+
+		msg = container_of(msg_hdr, struct
+				xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
+		spin_lock_irqsave(&part->chctl_lock, irq_flags);
+		part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE;
+		spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
+
+		xpc_wakeup_channel_mgr(part);
+	}
 	case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV:
 		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
 		part_uv->flags |= XPC_P_ENGAGED_UV;
@@ -558,9 +596,10 @@ xpc_handle_activate_IRQ_uv(int irq, void
 	short partid;
 	struct xpc_partition *part;
 	int wakeup_hb_checker = 0;
+	int part_referenced;
 
 	while (1) {
-		msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address);
+		msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc);
 		if (msg_hdr == NULL)
 			break;
 
@@ -571,14 +610,15 @@ xpc_handle_activate_IRQ_uv(int irq, void
 				partid);
 		} else {
 			part = &xpc_partitions[partid];
-			if (xpc_part_ref(part)) {
-				xpc_handle_activate_mq_msg_uv(part, msg_hdr,
-							    &wakeup_hb_checker);
+
+			part_referenced = xpc_part_ref(part);
+			xpc_handle_activate_mq_msg_uv(part, msg_hdr,
+						      &wakeup_hb_checker);
+			if (part_referenced)
 				xpc_part_deref(part);
-			}
 		}
 
-		gru_free_message(xpc_activate_mq_uv->address, msg_hdr);
+		gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr);
 	}
 
 	if (wakeup_hb_checker)
@@ -588,21 +628,73 @@ xpc_handle_activate_IRQ_uv(int irq, void
 }
 
 static enum xp_retval
+xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc,
+				unsigned long gru_mq_desc_gpa)
+{
+	enum xp_retval ret;
+
+	ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa,
+			       sizeof(struct gru_message_queue_desc));
+	if (ret == xpSuccess)
+		gru_mq_desc->mq = NULL;
+
+	return ret;
+}
+
+static enum xp_retval
 xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size,
 			 int msg_type)
 {
 	struct xpc_activate_mq_msghdr_uv *msg_hdr = msg;
+	struct xpc_partition_uv *part_uv = &part->sn.uv;
+	struct gru_message_queue_desc *gru_mq_desc;
+	unsigned long irq_flags;
+	enum xp_retval ret;
 
 	DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV);
 
 	msg_hdr->type = msg_type;
-	msg_hdr->partid = XPC_PARTID(part);
+	msg_hdr->partid = xp_partition_id;
 	msg_hdr->act_state = part->act_state;
 	msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies;
 
+	mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+again:
+	if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) {
+		gru_mq_desc = part_uv->cached_activate_gru_mq_desc;
+		if (gru_mq_desc == NULL) {
+			gru_mq_desc = kmalloc(sizeof(struct
+					      gru_message_queue_desc),
+					      GFP_KERNEL);
+			if (gru_mq_desc == NULL) {
+				ret = xpNoMemory;
+				goto done;
+			}
+			part_uv->cached_activate_gru_mq_desc = gru_mq_desc;
+		}
+
+		ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc,
+						      part_uv->
+						      activate_gru_mq_desc_gpa);
+		if (ret != xpSuccess)
+			goto done;
+
+		spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+		part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+		spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+	}
+
 	/* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */
-	return xpc_send_gru_msg(part->sn.uv.remote_activate_mq_gpa, msg,
-				msg_size);
+	ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg,
+			       msg_size);
+	if (ret != xpSuccess) {
+		smp_rmb();	/* ensure a fresh copy of part_uv->flags */
+		if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV))
+			goto again;
+	}
+done:
+	mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex);
+	return ret;
 }
 
 static void
@@ -620,7 +712,7 @@ static void
 xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags,
 			 void *msg, size_t msg_size, int msg_type)
 {
-	struct xpc_partition *part = &xpc_partitions[ch->number];
+	struct xpc_partition *part = &xpc_partitions[ch->partid];
 	enum xp_retval ret;
 
 	ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
@@ -643,7 +735,7 @@ xpc_send_local_activate_IRQ_uv(struct xp
 
 	/*
 	 * !!! Make our side think that the remote partition sent an activate
-	 * !!! message our way by doing what the activate IRQ handler would
+	 * !!! mq message our way by doing what the activate IRQ handler would
 	 * !!! do had one really been sent.
 	 */
 
@@ -690,89 +782,82 @@ xpc_get_partition_rsvd_page_pa_uv(void *
 }
 
 static int
-xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
+xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp)
 {
-	rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address);
+	xpc_heartbeat_uv =
+	    &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat;
+	rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv);
+	rp->sn.uv.activate_gru_mq_desc_gpa =
+	    uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
 	return 0;
 }
 
 static void
-xpc_send_heartbeat_uv(int msg_type)
+xpc_allow_hb_uv(short partid)
 {
-	short partid;
-	struct xpc_partition *part;
-	struct xpc_activate_mq_msg_heartbeat_req_uv msg;
-
-	/*
-	 * !!! On uv we're broadcasting a heartbeat message every 5 seconds.
-	 * !!! Whereas on sn2 we're bte_copy'ng the heartbeat info every 20
-	 * !!! seconds. This is an increase in numalink traffic.
-	 * ??? Is this good?
-	 */
-
-	msg.heartbeat = atomic64_inc_return(&xpc_heartbeat_uv);
-
-	partid = find_first_bit(xpc_heartbeating_to_mask_uv,
-				XP_MAX_NPARTITIONS_UV);
-
-	while (partid < XP_MAX_NPARTITIONS_UV) {
-		part = &xpc_partitions[partid];
+}
 
-		xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
-					      msg_type);
+static void
+xpc_disallow_hb_uv(short partid)
+{
+}
 
-		partid = find_next_bit(xpc_heartbeating_to_mask_uv,
-				       XP_MAX_NPARTITIONS_UV, partid + 1);
-	}
+static void
+xpc_disallow_all_hbs_uv(void)
+{
 }
 
 static void
 xpc_increment_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV);
+	xpc_heartbeat_uv->value++;
 }
 
 static void
 xpc_offline_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+	xpc_increment_heartbeat_uv();
+	xpc_heartbeat_uv->offline = 1;
 }
 
 static void
 xpc_online_heartbeat_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV);
+	xpc_increment_heartbeat_uv();
+	xpc_heartbeat_uv->offline = 0;
 }
 
 static void
 xpc_heartbeat_init_uv(void)
 {
-	atomic64_set(&xpc_heartbeat_uv, 0);
-	bitmap_zero(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
-	xpc_heartbeating_to_mask = &xpc_heartbeating_to_mask_uv[0];
+	xpc_heartbeat_uv->value = 1;
+	xpc_heartbeat_uv->offline = 0;
 }
 
 static void
 xpc_heartbeat_exit_uv(void)
 {
-	xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV);
+	xpc_offline_heartbeat_uv();
 }
 
 static enum xp_retval
 xpc_get_remote_heartbeat_uv(struct xpc_partition *part)
 {
 	struct xpc_partition_uv *part_uv = &part->sn.uv;
-	enum xp_retval ret = xpNoHeartbeat;
+	enum xp_retval ret;
 
-	if (part_uv->remote_act_state != XPC_P_AS_INACTIVE &&
-	    part_uv->remote_act_state != XPC_P_AS_DEACTIVATING) {
+	ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat),
+			       part_uv->heartbeat_gpa,
+			       sizeof(struct xpc_heartbeat_uv));
+	if (ret != xpSuccess)
+		return ret;
 
-		if (part_uv->heartbeat != part->last_heartbeat ||
-		    (part_uv->flags & XPC_P_HEARTBEAT_OFFLINE_UV)) {
+	if (part_uv->cached_heartbeat.value == part->last_heartbeat &&
+	    !part_uv->cached_heartbeat.offline) {
 
-			part->last_heartbeat = part_uv->heartbeat;
-			ret = xpSuccess;
-		}
+		ret = xpNoHeartbeat;
+	} else {
+		part->last_heartbeat = part_uv->cached_heartbeat.value;
 	}
 	return ret;
 }
@@ -787,7 +872,9 @@ xpc_request_partition_activation_uv(stru
 
 	part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
 	part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
-	part->sn.uv.remote_activate_mq_gpa = remote_rp->sn.activate_mq_gpa;
+	part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa;
+	part->sn.uv.activate_gru_mq_desc_gpa =
+	    remote_rp->sn.uv.activate_gru_mq_desc_gpa;
 
 	/*
 	 * ??? Is it a good idea to make this conditional on what is
@@ -795,7 +882,9 @@ xpc_request_partition_activation_uv(stru
 	 */
 	if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
 		msg.rp_gpa = uv_gpa(xpc_rsvd_page);
-		msg.activate_mq_gpa = xpc_rsvd_page->sn.activate_mq_gpa;
+		msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa;
+		msg.activate_gru_mq_desc_gpa =
+		    xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa;
 		xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
 					   XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
 	}
@@ -857,7 +946,8 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_he
 		if (head->first == NULL)
 			head->last = NULL;
 	}
-	head->n_entries++;
+	head->n_entries--;
+	BUG_ON(head->n_entries < 0);
 	spin_unlock_irqrestore(&head->lock, irq_flags);
 	first->next = NULL;
 	return first;
@@ -876,8 +966,7 @@ xpc_put_fifo_entry_uv(struct xpc_fifo_he
 	else
 		head->first = last;
 	head->last = last;
-	head->n_entries--;
-	BUG_ON(head->n_entries < 0);
+	head->n_entries++;
 	spin_unlock_irqrestore(&head->lock, irq_flags);
 }
 
@@ -891,7 +980,7 @@ xpc_n_of_fifo_entries_uv(struct xpc_fifo
  * Setup the channel structures that are uv specific.
  */
 static enum xp_retval
-xpc_setup_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_setup_ch_structures_uv(struct xpc_partition *part)
 {
 	struct xpc_channel_uv *ch_uv;
 	int ch_number;
@@ -910,7 +999,7 @@ xpc_setup_ch_structures_sn_uv(struct xpc
  * Teardown the channel structures that are uv specific.
  */
 static void
-xpc_teardown_ch_structures_sn_uv(struct xpc_partition *part)
+xpc_teardown_ch_structures_uv(struct xpc_partition *part)
 {
 	/* nothing needs to be done */
 	return;
@@ -1037,6 +1126,12 @@ xpc_setup_msg_structures_uv(struct xpc_c
 
 	DBUG_ON(ch->flags & XPC_C_SETUP);
 
+	ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct
+						   gru_message_queue_desc),
+						   GFP_KERNEL);
+	if (ch_uv->cached_notify_gru_mq_desc == NULL)
+		return xpNoMemory;
+
 	ret = xpc_allocate_send_msg_slot_uv(ch);
 	if (ret == xpSuccess) {
 
@@ -1060,7 +1155,8 @@ xpc_teardown_msg_structures_uv(struct xp
 
 	DBUG_ON(!spin_is_locked(&ch->lock));
 
-	ch_uv->remote_notify_mq_gpa = 0;
+	kfree(ch_uv->cached_notify_gru_mq_desc);
+	ch_uv->cached_notify_gru_mq_desc = NULL;
 
 	if (ch->flags & XPC_C_SETUP) {
 		xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
@@ -1111,12 +1207,22 @@ xpc_send_chctl_openreply_uv(struct xpc_c
 	msg.ch_number = ch->number;
 	msg.local_nentries = ch->local_nentries;
 	msg.remote_nentries = ch->remote_nentries;
-	msg.local_notify_mq_gpa = uv_gpa(xpc_notify_mq_uv);
+	msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc);
 	xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
 				    XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV);
 }
 
 static void
+xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags)
+{
+	struct xpc_activate_mq_msg_chctl_opencomplete_uv msg;
+
+	msg.ch_number = ch->number;
+	xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
+				    XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV);
+}
+
+static void
 xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
 {
 	unsigned long irq_flags;
@@ -1128,11 +1234,15 @@ xpc_send_chctl_local_msgrequest_uv(struc
 	xpc_wakeup_channel_mgr(part);
 }
 
-static void
+static enum xp_retval
 xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch,
-			       unsigned long msgqueue_pa)
+			       unsigned long gru_mq_desc_gpa)
 {
-	ch->sn.uv.remote_notify_mq_gpa = msgqueue_pa;
+	struct xpc_channel_uv *ch_uv = &ch->sn.uv;
+
+	DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL);
+	return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc,
+					       gru_mq_desc_gpa);
 }
 
 static void
@@ -1339,7 +1449,8 @@ xpc_handle_notify_IRQ_uv(int irq, void *
 	short partid;
 	struct xpc_partition *part;
 
-	while ((msg = gru_get_next_message(xpc_notify_mq_uv)) != NULL) {
+	while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) !=
+	       NULL) {
 
 		partid = msg->hdr.partid;
 		if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
@@ -1354,7 +1465,7 @@ xpc_handle_notify_IRQ_uv(int irq, void *
 			}
 		}
 
-		gru_free_message(xpc_notify_mq_uv, msg);
+		gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg);
 	}
 
 	return IRQ_HANDLED;
@@ -1438,7 +1549,8 @@ xpc_send_payload_uv(struct xpc_channel *
 	msg->hdr.msg_slot_number = msg_slot->msg_slot_number;
 	memcpy(&msg->payload, payload, payload_size);
 
-	ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, msg_size);
+	ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
+			       msg_size);
 	if (ret == xpSuccess)
 		goto out_1;
 
@@ -1529,7 +1641,7 @@ xpc_received_payload_uv(struct xpc_chann
 	msg->hdr.partid = xp_partition_id;
 	msg->hdr.size = 0;	/* size of zero indicates this is an ACK */
 
-	ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg,
+	ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
 			       sizeof(struct xpc_notify_mq_msghdr_uv));
 	if (ret != xpSuccess)
 		XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
@@ -1537,57 +1649,67 @@ xpc_received_payload_uv(struct xpc_chann
 	msg->hdr.msg_slot_number += ch->remote_nentries;
 }
 
-int
-xpc_init_uv(void)
-{
-	xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv;
-	xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv;
-	xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv;
-	xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv;
-	xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
-	xpc_offline_heartbeat = xpc_offline_heartbeat_uv;
-	xpc_online_heartbeat = xpc_online_heartbeat_uv;
-	xpc_heartbeat_init = xpc_heartbeat_init_uv;
-	xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
-	xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_uv;
+static struct xpc_arch_operations xpc_arch_ops_uv = {
+	.setup_partitions = xpc_setup_partitions_uv,
+	.teardown_partitions = xpc_teardown_partitions_uv,
+	.process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv,
+	.get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv,
+	.setup_rsvd_page = xpc_setup_rsvd_page_uv,
 
-	xpc_request_partition_activation = xpc_request_partition_activation_uv;
-	xpc_request_partition_reactivation =
-	    xpc_request_partition_reactivation_uv;
-	xpc_request_partition_deactivation =
-	    xpc_request_partition_deactivation_uv;
-	xpc_cancel_partition_deactivation_request =
-	    xpc_cancel_partition_deactivation_request_uv;
+	.allow_hb = xpc_allow_hb_uv,
+	.disallow_hb = xpc_disallow_hb_uv,
+	.disallow_all_hbs = xpc_disallow_all_hbs_uv,
+	.increment_heartbeat = xpc_increment_heartbeat_uv,
+	.offline_heartbeat = xpc_offline_heartbeat_uv,
+	.online_heartbeat = xpc_online_heartbeat_uv,
+	.heartbeat_init = xpc_heartbeat_init_uv,
+	.heartbeat_exit = xpc_heartbeat_exit_uv,
+	.get_remote_heartbeat = xpc_get_remote_heartbeat_uv,
 
-	xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_uv;
-	xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_uv;
+	.request_partition_activation =
+		xpc_request_partition_activation_uv,
+	.request_partition_reactivation =
+		xpc_request_partition_reactivation_uv,
+	.request_partition_deactivation =
+		xpc_request_partition_deactivation_uv,
+	.cancel_partition_deactivation_request =
+		xpc_cancel_partition_deactivation_request_uv,
 
-	xpc_make_first_contact = xpc_make_first_contact_uv;
+	.setup_ch_structures = xpc_setup_ch_structures_uv,
+	.teardown_ch_structures = xpc_teardown_ch_structures_uv,
 
-	xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_uv;
-	xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_uv;
-	xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv;
-	xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv;
-	xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv;
+	.make_first_contact = xpc_make_first_contact_uv,
 
-	xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv;
+	.get_chctl_all_flags = xpc_get_chctl_all_flags_uv,
+	.send_chctl_closerequest = xpc_send_chctl_closerequest_uv,
+	.send_chctl_closereply = xpc_send_chctl_closereply_uv,
+	.send_chctl_openrequest = xpc_send_chctl_openrequest_uv,
+	.send_chctl_openreply = xpc_send_chctl_openreply_uv,
+	.send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv,
+	.process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv,
 
-	xpc_setup_msg_structures = xpc_setup_msg_structures_uv;
-	xpc_teardown_msg_structures = xpc_teardown_msg_structures_uv;
+	.save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv,
 
-	xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_uv;
-	xpc_indicate_partition_disengaged =
-	    xpc_indicate_partition_disengaged_uv;
-	xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_uv;
-	xpc_partition_engaged = xpc_partition_engaged_uv;
-	xpc_any_partition_engaged = xpc_any_partition_engaged_uv;
+	.setup_msg_structures = xpc_setup_msg_structures_uv,
+	.teardown_msg_structures = xpc_teardown_msg_structures_uv,
 
-	xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv;
-	xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv;
-	xpc_send_payload = xpc_send_payload_uv;
-	xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv;
-	xpc_get_deliverable_payload = xpc_get_deliverable_payload_uv;
-	xpc_received_payload = xpc_received_payload_uv;
+	.indicate_partition_engaged = xpc_indicate_partition_engaged_uv,
+	.indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv,
+	.assume_partition_disengaged = xpc_assume_partition_disengaged_uv,
+	.partition_engaged = xpc_partition_engaged_uv,
+	.any_partition_engaged = xpc_any_partition_engaged_uv,
+
+	.n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv,
+	.send_payload = xpc_send_payload_uv,
+	.get_deliverable_payload = xpc_get_deliverable_payload_uv,
+	.received_payload = xpc_received_payload_uv,
+	.notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
+};
+
+int
+xpc_init_uv(void)
+{
+	xpc_arch_ops = xpc_arch_ops_uv;
 
 	if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
 		dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xp.h linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xp.h
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xp.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,19 +15,19 @@
 
 #include <linux/mutex.h>
 
-#ifdef CONFIG_IA64
+#if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
+#include <asm/uv/uv.h>
+#define is_uv()		is_uv_system()
+#endif
+
+#ifndef is_uv
+#define is_uv()		0
+#endif
+
+#if defined CONFIG_IA64
 #include <asm/system.h>
 #include <asm/sn/arch.h>	/* defines is_shub1() and is_shub2() */
 #define is_shub()	ia64_platform_is("sn2")
-#ifdef CONFIG_IA64_SGI_UV
-#define is_uv()		ia64_platform_is("uv")
-#else
-#define is_uv()		0
-#endif
-#endif
-#ifdef CONFIG_X86_64
-#include <asm/genapic.h>
-#define is_uv()		is_uv_system()
 #endif
 
 #ifndef is_shub1
@@ -42,10 +42,6 @@
 #define is_shub()	0
 #endif
 
-#ifndef is_uv
-#define is_uv()		0
-#endif
-
 #ifdef USE_DBUG_ON
 #define DBUG_ON(condition)	BUG_ON(condition)
 #else
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xp_main.c linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xp_main.c
--- linux-libre-2.6.29-gnu1/drivers/misc/sgi-xp/xp_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/sgi-xp/xp_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -248,19 +248,19 @@ xp_init(void)
 	enum xp_retval ret;
 	int ch_number;
 
+	/* initialize the connection registration mutex */
+	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
+		mutex_init(&xpc_registrations[ch_number].mutex);
+
 	if (is_shub())
 		ret = xp_init_sn2();
 	else if (is_uv())
 		ret = xp_init_uv();
 	else
-		ret = xpUnsupported;
+		ret = 0;
 
 	if (ret != xpSuccess)
-		return -ENODEV;
-
-	/* initialize the connection registration mutex */
-	for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
-		mutex_init(&xpc_registrations[ch_number].mutex);
+		return ret;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/misc/tifm_7xx1.c linux-libre-2.6.30-gnu1/drivers/misc/tifm_7xx1.c
--- linux-libre-2.6.29-gnu1/drivers/misc/tifm_7xx1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/misc/tifm_7xx1.c	2009-06-09 23:05:27.000000000 -0400
@@ -324,7 +324,7 @@ static int tifm_7xx1_probe(struct pci_de
 	int pci_dev_busy = 0;
 	int rc;
 
-	rc = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
 	if (rc)
 		return rc;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/card/block.c linux-libre-2.6.30-gnu1/drivers/mmc/card/block.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/card/block.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/card/block.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,8 @@
 
 #include "queue.h"
 
+MODULE_ALIAS("mmc:block");
+
 /*
  * max 8 partitions per card
  */
@@ -252,6 +254,14 @@ static int mmc_blk_issue_rq(struct mmc_q
 		brq.data.blocks = req->nr_sectors;
 
 		/*
+		 * The block layer doesn't support all sector count
+		 * restrictions, so we need to be prepared for too big
+		 * requests.
+		 */
+		if (brq.data.blocks > card->host->max_blk_count)
+			brq.data.blocks = card->host->max_blk_count;
+
+		/*
 		 * After a read error, we redo the request one sector at a time
 		 * in order to accurately determine which sectors can be read
 		 * successfully.
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/card/sdio_uart.c linux-libre-2.6.30-gnu1/drivers/mmc/card/sdio_uart.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/card/sdio_uart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/card/sdio_uart.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/seq_file.h>
 #include <linux/serial_reg.h>
 #include <linux/circ_buf.h>
 #include <linux/gfp.h>
@@ -933,67 +934,64 @@ static int sdio_uart_tiocmset(struct tty
 	return result;
 }
 
-static int sdio_uart_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int sdio_uart_proc_show(struct seq_file *m, void *v)
 {
-	int i, len = 0;
-	off_t begin = 0;
+	int i;
 
-	len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+	seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
 		       "", "", "");
-	for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+	for (i = 0; i < UART_NR; i++) {
 		struct sdio_uart_port *port = sdio_uart_port_get(i);
 		if (port) {
-			len += sprintf(page+len, "%d: uart:SDIO", i);
+			seq_printf(m, "%d: uart:SDIO", i);
 			if(capable(CAP_SYS_ADMIN)) {
-				len += sprintf(page + len, " tx:%d rx:%d",
+				seq_printf(m, " tx:%d rx:%d",
 					       port->icount.tx, port->icount.rx);
 				if (port->icount.frame)
-					len += sprintf(page + len, " fe:%d",
+					seq_printf(m, " fe:%d",
 						       port->icount.frame);
 				if (port->icount.parity)
-					len += sprintf(page + len, " pe:%d",
+					seq_printf(m, " pe:%d",
 						       port->icount.parity);
 				if (port->icount.brk)
-					len += sprintf(page + len, " brk:%d",
+					seq_printf(m, " brk:%d",
 						       port->icount.brk);
 				if (port->icount.overrun)
-					len += sprintf(page + len, " oe:%d",
+					seq_printf(m, " oe:%d",
 						       port->icount.overrun);
 				if (port->icount.cts)
-					len += sprintf(page + len, " cts:%d",
+					seq_printf(m, " cts:%d",
 						       port->icount.cts);
 				if (port->icount.dsr)
-					len += sprintf(page + len, " dsr:%d",
+					seq_printf(m, " dsr:%d",
 						       port->icount.dsr);
 				if (port->icount.rng)
-					len += sprintf(page + len, " rng:%d",
+					seq_printf(m, " rng:%d",
 						       port->icount.rng);
 				if (port->icount.dcd)
-					len += sprintf(page + len, " dcd:%d",
+					seq_printf(m, " dcd:%d",
 						       port->icount.dcd);
 			}
-			strcat(page, "\n");
-			len++;
 			sdio_uart_port_put(port);
-		}
-
-		if (len + begin > off + count)
-			goto done;
-		if (len + begin < off) {
-			begin += len;
-			len = 0;
+			seq_putc(m, '\n');
 		}
 	}
-	*eof = 1;
+	return 0;
+}
 
-done:
-	if (off >= len + begin)
-		return 0;
-	*start = page + (off - begin);
-	return (count < begin + len - off) ? count : (begin + len - off);
+static int sdio_uart_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sdio_uart_proc_show, NULL);
 }
 
+static const struct file_operations sdio_uart_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sdio_uart_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static const struct tty_operations sdio_uart_ops = {
 	.open			= sdio_uart_open,
 	.close			= sdio_uart_close,
@@ -1007,7 +1005,7 @@ static const struct tty_operations sdio_
 	.break_ctl		= sdio_uart_break_ctl,
 	.tiocmget		= sdio_uart_tiocmget,
 	.tiocmset		= sdio_uart_tiocmset,
-	.read_proc		= sdio_uart_read_proc,
+	.proc_fops		= &sdio_uart_proc_fops,
 };
 
 static struct tty_driver *sdio_uart_tty_driver;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/bus.c linux-libre-2.6.30-gnu1/drivers/mmc/core/bus.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,6 +84,14 @@ mmc_bus_uevent(struct device *dev, struc
 	}
 
 	retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
+	if (retval)
+		return retval;
+
+	/*
+	 * Request the mmc_block device.  Note: that this is a direct request
+	 * for the module it carries no information as to what is inserted.
+	 */
+	retval = add_uevent_var(env, "MODALIAS=mmc:block");
 
 	return retval;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/core.c linux-libre-2.6.30-gnu1/drivers/mmc/core/core.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/leds.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -297,6 +298,21 @@ void mmc_set_data_timeout(struct mmc_dat
 			data->timeout_clks = 0;
 		}
 	}
+	/*
+	 * Some cards need very high timeouts if driven in SPI mode.
+	 * The worst observed timeout was 900ms after writing a
+	 * continuous stream of data until the internal logic
+	 * overflowed.
+	 */
+	if (mmc_host_is_spi(card->host)) {
+		if (data->flags & MMC_DATA_WRITE) {
+			if (data->timeout_ns < 1000000000)
+				data->timeout_ns = 1000000000;	/* 1s */
+		} else {
+			if (data->timeout_ns < 100000000)
+				data->timeout_ns =  100000000;	/* 100ms */
+		}
+	}
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
@@ -523,6 +539,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min,
 }
 EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
 
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator.  This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+	int			result = 0;
+	int			count;
+	int			i;
+
+	count = regulator_count_voltages(supply);
+	if (count < 0)
+		return count;
+
+	for (i = 0; i < count; i++) {
+		int		vdd_uV;
+		int		vdd_mV;
+
+		vdd_uV = regulator_list_voltage(supply, i);
+		if (vdd_uV <= 0)
+			continue;
+
+		vdd_mV = vdd_uV / 1000;
+		result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ * @supply: regulator to use
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage.  This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
+{
+	int			result = 0;
+	int			min_uV, max_uV;
+	int			enabled;
+
+	enabled = regulator_is_enabled(supply);
+	if (enabled < 0)
+		return enabled;
+
+	if (vdd_bit) {
+		int		tmp;
+		int		voltage;
+
+		/* REVISIT mmc_vddrange_to_ocrmask() may have set some
+		 * bits this regulator doesn't quite support ... don't
+		 * be too picky, most cards and regulators are OK with
+		 * a 0.1V range goof (it's a small error percentage).
+		 */
+		tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+		if (tmp == 0) {
+			min_uV = 1650 * 1000;
+			max_uV = 1950 * 1000;
+		} else {
+			min_uV = 1900 * 1000 + tmp * 100 * 1000;
+			max_uV = min_uV + 100 * 1000;
+		}
+
+		/* avoid needless changes to this voltage; the regulator
+		 * might not allow this operation
+		 */
+		voltage = regulator_get_voltage(supply);
+		if (voltage < 0)
+			result = voltage;
+		else if (voltage < min_uV || voltage > max_uV)
+			result = regulator_set_voltage(supply, min_uV, max_uV);
+		else
+			result = 0;
+
+		if (result == 0 && !enabled)
+			result = regulator_enable(supply);
+	} else if (enabled) {
+		result = regulator_disable(supply);
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
 /*
  * Mask off any voltages we don't support and select
  * the lowest voltage
@@ -591,7 +706,7 @@ static void mmc_power_up(struct mmc_host
 	 * This delay should be sufficient to allow the power supply
 	 * to reach the minimum voltage.
 	 */
-	mmc_delay(2);
+	mmc_delay(10);
 
 	host->ios.clock = host->f_min;
 	host->ios.power_mode = MMC_POWER_ON;
@@ -601,7 +716,7 @@ static void mmc_power_up(struct mmc_host
 	 * This delay must be at least 74 clock sizes, or 1 ms, or the
 	 * time required to reach a stable voltage.
 	 */
-	mmc_delay(2);
+	mmc_delay(10);
 }
 
 static void mmc_power_off(struct mmc_host *host)
@@ -815,6 +930,7 @@ void mmc_stop_host(struct mmc_host *host
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
 	mmc_bus_get(host);
@@ -842,6 +958,7 @@ void mmc_stop_host(struct mmc_host *host
  */
 int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
 {
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
 	mmc_bus_get(host);
@@ -875,6 +992,7 @@ int mmc_resume_host(struct mmc_host *hos
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		mmc_power_up(host);
+		mmc_select_voltage(host, host->ocr);
 		BUG_ON(!host->bus_ops->resume);
 		host->bus_ops->resume(host);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/debugfs.c linux-libre-2.6.30-gnu1/drivers/mmc/core/debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/debugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -184,6 +184,68 @@ static int mmc_dbg_card_status_get(void
 DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
 		NULL, "%08llx\n");
 
+#define EXT_CSD_STR_LEN 1025
+
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
+{
+	struct mmc_card *card = inode->i_private;
+	char *buf;
+	ssize_t n = 0;
+	u8 *ext_csd;
+	int err, i;
+
+	buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ext_csd = kmalloc(512, GFP_KERNEL);
+	if (!ext_csd) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	mmc_claim_host(card->host);
+	err = mmc_send_ext_csd(card, ext_csd);
+	mmc_release_host(card->host);
+	if (err)
+		goto out_free;
+
+	for (i = 511; i >= 0; i--)
+		n += sprintf(buf + n, "%02x", ext_csd[i]);
+	n += sprintf(buf + n, "\n");
+	BUG_ON(n != EXT_CSD_STR_LEN);
+
+	filp->private_data = buf;
+	kfree(ext_csd);
+	return 0;
+
+out_free:
+	kfree(buf);
+	kfree(ext_csd);
+	return err;
+}
+
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
+				size_t cnt, loff_t *ppos)
+{
+	char *buf = filp->private_data;
+
+	return simple_read_from_buffer(ubuf, cnt, ppos,
+				       buf, EXT_CSD_STR_LEN);
+}
+
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static struct file_operations mmc_dbg_ext_csd_fops = {
+	.open		= mmc_ext_csd_open,
+	.read		= mmc_ext_csd_read,
+	.release	= mmc_ext_csd_release,
+};
+
 void mmc_add_card_debugfs(struct mmc_card *card)
 {
 	struct mmc_host	*host = card->host;
@@ -211,6 +273,11 @@ void mmc_add_card_debugfs(struct mmc_car
 					&mmc_dbg_card_status_fops))
 			goto err;
 
+	if (mmc_card_mmc(card))
+		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
+					&mmc_dbg_ext_csd_fops))
+			goto err;
+
 	return;
 
 err:
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/mmc.c linux-libre-2.6.30-gnu1/drivers/mmc/core/mmc.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/mmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/mmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -208,7 +208,7 @@ static int mmc_read_ext_csd(struct mmc_c
 	}
 
 	ext_csd_struct = ext_csd[EXT_CSD_REV];
-	if (ext_csd_struct > 2) {
+	if (ext_csd_struct > 3) {
 		printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
 			"version %d\n", mmc_hostname(card->host),
 			ext_csd_struct);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/sd.c linux-libre-2.6.30-gnu1/drivers/mmc/core/sd.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/sd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/sd.c	2009-06-09 23:05:27.000000000 -0400
@@ -363,15 +363,6 @@ static int mmc_sd_init_card(struct mmc_h
 		goto err;
 
 	/*
-	 * For SPI, enable CRC as appropriate.
-	 */
-	if (mmc_host_is_spi(host)) {
-		err = mmc_spi_set_crc(host, use_spi_crc);
-		if (err)
-			goto err;
-	}
-
-	/*
 	 * Fetch CID from card.
 	 */
 	if (mmc_host_is_spi(host))
@@ -456,6 +447,18 @@ static int mmc_sd_init_card(struct mmc_h
 		if (err)
 			goto free_card;
 	}
+
+	/*
+	 * For SPI, enable CRC as appropriate.
+	 * This CRC enable is located AFTER the reading of the
+	 * card registers because some SDHC cards are not able
+	 * to provide valid CRCs for non-512-byte blocks.
+	 */
+	if (mmc_host_is_spi(host)) {
+		err = mmc_spi_set_crc(host, use_spi_crc);
+		if (err)
+			goto free_card;
+	}
 
 	/*
 	 * Attempt to change to high-speed (if supported)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/sdio_cis.c linux-libre-2.6.30-gnu1/drivers/mmc/core/sdio_cis.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/sdio_cis.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/sdio_cis.c	2009-06-09 23:05:27.000000000 -0400
@@ -223,10 +223,18 @@ static int sdio_read_cis(struct mmc_card
 		if (tpl_code == 0xff)
 			break;
 
+		/* null entries have no link field or data */
+		if (tpl_code == 0x00)
+			continue;
+
 		ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
 		if (ret)
 			break;
 
+		/* a size of 0xff also means we're done */
+		if (tpl_link == 0xff)
+			break;
+
 		this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
 		if (!this)
 			return -ENOMEM;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/core/sdio_ops.c linux-libre-2.6.30-gnu1/drivers/mmc/core/sdio_ops.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/core/sdio_ops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/core/sdio_ops.c	2009-06-09 23:05:27.000000000 -0400
@@ -76,6 +76,10 @@ int mmc_io_rw_direct(struct mmc_card *ca
 	BUG_ON(!card);
 	BUG_ON(fn > 7);
 
+	/* sanity check */
+	if (addr & ~0x1FFFF)
+		return -EINVAL;
+
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = SD_IO_RW_DIRECT;
@@ -125,6 +129,10 @@ int mmc_io_rw_extended(struct mmc_card *
 	WARN_ON(blocks == 0);
 	WARN_ON(blksz == 0);
 
+	/* sanity check */
+	if (addr & ~0x1FFFF)
+		return -EINVAL;
+
 	memset(&mrq, 0, sizeof(struct mmc_request));
 	memset(&cmd, 0, sizeof(struct mmc_command));
 	memset(&data, 0, sizeof(struct mmc_data));
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/atmel-mci.c linux-libre-2.6.30-gnu1/drivers/mmc/host/atmel-mci.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/atmel-mci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/atmel-mci.c	2009-06-09 23:05:27.000000000 -0400
@@ -812,7 +812,7 @@ static void atmci_set_ios(struct mmc_hos
 		slot->sdc_reg |= MCI_SDCBUS_1BIT;
 		break;
 	case MMC_BUS_WIDTH_4:
-		slot->sdc_reg = MCI_SDCBUS_4BIT;
+		slot->sdc_reg |= MCI_SDCBUS_4BIT;
 		break;
 	}
 
@@ -1603,7 +1603,7 @@ static int __init atmci_probe(struct pla
 
 	tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);
 
-	ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host);
+	ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
 	if (ret)
 		goto err_request_irq;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/imxmmc.c linux-libre-2.6.30-gnu1/drivers/mmc/host/imxmmc.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/imxmmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/imxmmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -307,13 +307,6 @@ static void imxmci_setup_data(struct imx
 
 	wmb();
 
-	if (host->actual_bus_width == MMC_BUS_WIDTH_4)
-		BLR(host->dma) = 0;	/* burst 64 byte read / 64 bytes write */
-	else
-		BLR(host->dma) = 16;	/* burst 16 byte read / 16 bytes write */
-
-	RSSR(host->dma) = DMA_REQ_SDHC;
-
 	set_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
 	clear_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events);
 
@@ -818,9 +811,11 @@ static void imxmci_set_ios(struct mmc_ho
 	if (ios->bus_width == MMC_BUS_WIDTH_4) {
 		host->actual_bus_width = MMC_BUS_WIDTH_4;
 		imx_gpio_mode(PB11_PF_SD_DAT3);
+		BLR(host->dma) = 0;	/* burst 64 byte read/write */
 	} else {
 		host->actual_bus_width = MMC_BUS_WIDTH_1;
 		imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11);
+		BLR(host->dma) = 16;	/* burst 16 byte read/write */
 	}
 
 	if (host->power_mode != ios->power_mode) {
@@ -938,7 +933,7 @@ static void imxmci_check_status(unsigned
 	mod_timer(&host->timer, jiffies + (HZ>>1));
 }
 
-static int imxmci_probe(struct platform_device *pdev)
+static int __init imxmci_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
 	struct imxmci_host *host = NULL;
@@ -1034,6 +1029,7 @@ static int imxmci_probe(struct platform_
 	}
 	host->dma_allocated = 1;
 	imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host);
+	RSSR(host->dma) = DMA_REQ_SDHC;
 
 	tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host);
 	host->status_reg=0;
@@ -1079,7 +1075,7 @@ out:
 	return ret;
 }
 
-static int imxmci_remove(struct platform_device *pdev)
+static int __exit imxmci_remove(struct platform_device *pdev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
@@ -1145,8 +1141,7 @@ static int imxmci_resume(struct platform
 #endif /* CONFIG_PM */
 
 static struct platform_driver imxmci_driver = {
-	.probe		= imxmci_probe,
-	.remove		= imxmci_remove,
+	.remove		= __exit_p(imxmci_remove),
 	.suspend	= imxmci_suspend,
 	.resume		= imxmci_resume,
 	.driver		= {
@@ -1157,7 +1152,7 @@ static struct platform_driver imxmci_dri
 
 static int __init imxmci_init(void)
 {
-	return platform_driver_register(&imxmci_driver);
+	return platform_driver_probe(&imxmci_driver, imxmci_probe);
 }
 
 static void __exit imxmci_exit(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/Kconfig linux-libre-2.6.30-gnu1/drivers/mmc/host/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,13 @@ config MMC_SDHCI
 
 	  If unsure, say N.
 
+config MMC_SDHCI_IO_ACCESSORS
+	bool
+	depends on MMC_SDHCI
+	help
+	  This is silent Kconfig symbol that is selected by the drivers that
+	  need to overwrite SDHCI IO memory accessors.
+
 config MMC_SDHCI_PCI
 	tristate "SDHCI support on PCI bus"
 	depends on MMC_SDHCI && PCI
@@ -65,6 +72,17 @@ config MMC_RICOH_MMC
 
 	  If unsure, say Y.
 
+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.
+
+	  If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
@@ -171,13 +189,24 @@ config MMC_TIFM_SD
           To compile this driver as a module, choose M here: the
 	  module will be called tifm_sd.
 
+config MMC_MVSDIO
+	tristate "Marvell MMC/SD/SDIO host driver"
+	depends on PLAT_ORION
+	---help---
+	  This selects the Marvell SDIO host driver.
+	  SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
+	  SoC controllers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mvsdio.
+
 config MMC_SPI
 	tristate "MMC/SD/SDIO over SPI"
 	depends on SPI_MASTER && !HIGHMEM && HAS_DMA
 	select CRC7
 	select CRC_ITU_T
 	help
-	  Some systems accss MMC/SD/SDIO cards using a SPI controller
+	  Some systems access MMC/SD/SDIO cards using a SPI controller
 	  instead of using a "native" MMC/SD/SDIO controller.  This has a
 	  disadvantage of being relatively high overhead, but a compensating
 	  advantage of working on many systems without dedicated MMC/SD/SDIO
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/Makefile linux-libre-2.6.30-gnu1/drivers/mmc/host/Makefile
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@ 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_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_MMC_OMAP_HS)	+= omap_hsmmc.
 obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_ATMELMCI)	+= atmel-mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
+obj-$(CONFIG_MMC_MVSDIO)	+= mvsdio.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_MMC_SPI)		+= of_mmc_spi.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/mmci.c linux-libre-2.6.30-gnu1/drivers/mmc/host/mmci.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/mmci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/mmci.c	2009-06-09 23:05:27.000000000 -0400
@@ -490,7 +490,7 @@ static void mmci_check_status(unsigned l
 	mod_timer(&host->timer, jiffies + HZ);
 }
 
-static int mmci_probe(struct amba_device *dev, void *id)
+static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct mmc_platform_data *plat = dev->dev.platform_data;
 	struct mmci_host *host;
@@ -514,6 +514,7 @@ static int mmci_probe(struct amba_device
 	}
 
 	host = mmc_priv(mmc);
+	host->mmc = mmc;
 	/* Bits 12 thru 19 is the designer */
 	host->hw_designer = (dev->periphid >> 12) & 0xff;
 	/* Bits 20 thru 23 is the revison */
@@ -545,7 +546,6 @@ static int mmci_probe(struct amba_device
 		host->mclk = clk_get_rate(host->clk);
 		DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
 	}
-	host->mmc = mmc;
 	host->base = ioremap(dev->res.start, SZ_4K);
 	if (!host->base) {
 		ret = -ENOMEM;
@@ -633,7 +633,7 @@ static int mmci_probe(struct amba_device
 	return ret;
 }
 
-static int mmci_remove(struct amba_device *dev)
+static int __devexit mmci_remove(struct amba_device *dev)
 {
 	struct mmc_host *mmc = amba_get_drvdata(dev);
 
@@ -730,7 +730,7 @@ static struct amba_driver mmci_driver =
 		.name	= DRIVER_NAME,
 	},
 	.probe		= mmci_probe,
-	.remove		= mmci_remove,
+	.remove		= __devexit_p(mmci_remove),
 	.suspend	= mmci_suspend,
 	.resume		= mmci_resume,
 	.id_table	= mmci_ids,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/mmc_spi.c linux-libre-2.6.30-gnu1/drivers/mmc/host/mmc_spi.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/mmc_spi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/mmc_spi.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <linux/hrtimer.h>
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/bio.h>
 #include <linux/dma-mapping.h>
@@ -95,7 +95,7 @@
  * reads which takes nowhere near that long.  Older cards may be able to use
  * shorter timeouts ... but why bother?
  */
-#define r1b_timeout		ktime_set(3, 0)
+#define r1b_timeout		(HZ * 3)
 
 
 /****************************************************************************/
@@ -183,12 +183,11 @@ mmc_spi_readbytes(struct mmc_spi_host *h
 	return status;
 }
 
-static int
-mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
+static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
+			unsigned n, u8 byte)
 {
 	u8		*cp = host->data->status;
-
-	timeout = ktime_add(timeout, ktime_get());
+	unsigned long start = jiffies;
 
 	while (1) {
 		int		status;
@@ -203,22 +202,26 @@ mmc_spi_skip(struct mmc_spi_host *host,
 				return cp[i];
 		}
 
-		/* REVISIT investigate msleep() to avoid busy-wait I/O
-		 * in at least some cases.
-		 */
-		if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
+		if (time_is_before_jiffies(start + timeout))
 			break;
+
+		/* If we need long timeouts, we may release the CPU.
+		 * We use jiffies here because we want to have a relation
+		 * between elapsed time and the blocking of the scheduler.
+		 */
+		if (time_is_before_jiffies(start+1))
+			schedule();
 	}
 	return -ETIMEDOUT;
 }
 
 static inline int
-mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
+mmc_spi_wait_unbusy(struct mmc_spi_host *host, unsigned long timeout)
 {
 	return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
 }
 
-static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)
+static int mmc_spi_readtoken(struct mmc_spi_host *host, unsigned long timeout)
 {
 	return mmc_spi_skip(host, timeout, 1, 0xff);
 }
@@ -251,6 +254,10 @@ static int mmc_spi_response_get(struct m
 	u8	*cp = host->data->status;
 	u8	*end = cp + host->t.len;
 	int	value = 0;
+	int	bitshift;
+	u8 	leftover = 0;
+	unsigned short rotator;
+	int 	i;
 	char	tag[32];
 
 	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
@@ -268,9 +275,8 @@ static int mmc_spi_response_get(struct m
 
 	/* Data block reads (R1 response types) may need more data... */
 	if (cp == end) {
-		unsigned	i;
-
 		cp = host->data->status;
+		end = cp+1;
 
 		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
 		 * status byte ... and we already scanned 2 bytes.
@@ -279,8 +285,11 @@ static int mmc_spi_response_get(struct m
 		 * so it can always DMA directly into the target buffer.
 		 * It'd probably be better to memcpy() the first chunk and
 		 * avoid extra i/o calls...
+		 *
+		 * Note we check for more than 8 bytes, because in practice,
+		 * some SD cards are slow...
 		 */
-		for (i = 2; i < 9; i++) {
+		for (i = 2; i < 16; i++) {
 			value = mmc_spi_readbytes(host, 1);
 			if (value < 0)
 				goto done;
@@ -292,20 +301,34 @@ static int mmc_spi_response_get(struct m
 	}
 
 checkstatus:
-	if (*cp & 0x80) {
-		dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
-					tag, *cp);
-		value = -EBADR;
-		goto done;
+	bitshift = 0;
+	if (*cp & 0x80)	{
+		/* Houston, we have an ugly card with a bit-shifted response */
+		rotator = *cp++ << 8;
+		/* read the next byte */
+		if (cp == end) {
+			value = mmc_spi_readbytes(host, 1);
+			if (value < 0)
+				goto done;
+			cp = host->data->status;
+			end = cp+1;
+		}
+		rotator |= *cp++;
+		while (rotator & 0x8000) {
+			bitshift++;
+			rotator <<= 1;
+		}
+		cmd->resp[0] = rotator >> 8;
+		leftover = rotator;
+	} else {
+		cmd->resp[0] = *cp++;
 	}
-
-	cmd->resp[0] = *cp++;
 	cmd->error = 0;
 
 	/* Status byte: the entire seven-bit R1 response.  */
 	if (cmd->resp[0] != 0) {
 		if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
-					| R1_SPI_ILLEGAL_COMMAND)
+				      | R1_SPI_ILLEGAL_COMMAND)
 				& cmd->resp[0])
 			value = -EINVAL;
 		else if (R1_SPI_COM_CRC & cmd->resp[0])
@@ -333,12 +356,45 @@ checkstatus:
 	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
 	 */
 	case MMC_RSP_SPI_R2:
-		cmd->resp[0] |= *cp << 8;
+		/* read the next byte */
+		if (cp == end) {
+			value = mmc_spi_readbytes(host, 1);
+			if (value < 0)
+				goto done;
+			cp = host->data->status;
+			end = cp+1;
+		}
+		if (bitshift) {
+			rotator = leftover << 8;
+			rotator |= *cp << bitshift;
+			cmd->resp[0] |= (rotator & 0xFF00);
+		} else {
+			cmd->resp[0] |= *cp << 8;
+		}
 		break;
 
 	/* SPI R3, R4, or R7 == R1 + 4 bytes */
 	case MMC_RSP_SPI_R3:
-		cmd->resp[1] = get_unaligned_be32(cp);
+		rotator = leftover << 8;
+		cmd->resp[1] = 0;
+		for (i = 0; i < 4; i++) {
+			cmd->resp[1] <<= 8;
+			/* read the next byte */
+			if (cp == end) {
+				value = mmc_spi_readbytes(host, 1);
+				if (value < 0)
+					goto done;
+				cp = host->data->status;
+				end = cp+1;
+			}
+			if (bitshift) {
+				rotator |= *cp++ << bitshift;
+				cmd->resp[1] |= (rotator >> 8);
+				rotator <<= 8;
+			} else {
+				cmd->resp[1] |= *cp++;
+			}
+		}
 		break;
 
 	/* SPI R1 == just one status byte */
@@ -604,11 +660,12 @@ mmc_spi_setup_data_message(
  */
 static int
 mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
-	ktime_t timeout)
+	unsigned long timeout)
 {
 	struct spi_device	*spi = host->spi;
 	int			status, i;
 	struct scratch		*scratch = host->data;
+	u32			pattern;
 
 	if (host->mmc->use_spi_crc)
 		scratch->crc_val = cpu_to_be16(
@@ -636,8 +693,27 @@ mmc_spi_writeblock(struct mmc_spi_host *
 	 * doesn't necessarily tell whether the write operation succeeded;
 	 * it just says if the transmission was ok and whether *earlier*
 	 * writes succeeded; see the standard.
+	 *
+	 * In practice, there are (even modern SDHC-)cards which are late
+	 * in sending the response, and miss the time frame by a few bits,
+	 * so we have to cope with this situation and check the response
+	 * bit-by-bit. Arggh!!!
 	 */
-	switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+	pattern  = scratch->status[0] << 24;
+	pattern |= scratch->status[1] << 16;
+	pattern |= scratch->status[2] << 8;
+	pattern |= scratch->status[3];
+
+	/* First 3 bit of pattern are undefined */
+	pattern |= 0xE0000000;
+
+	/* left-adjust to leading 0 bit */
+	while (pattern & 0x80000000)
+		pattern <<= 1;
+	/* right-adjust for pattern matching. Code is in bit 4..0 now. */
+	pattern >>= 27;
+
+	switch (pattern) {
 	case SPI_RESPONSE_ACCEPTED:
 		status = 0;
 		break;
@@ -668,8 +744,9 @@ mmc_spi_writeblock(struct mmc_spi_host *
 	/* Return when not busy.  If we didn't collect that status yet,
 	 * we'll need some more I/O.
 	 */
-	for (i = 1; i < sizeof(scratch->status); i++) {
-		if (scratch->status[i] != 0)
+	for (i = 4; i < sizeof(scratch->status); i++) {
+		/* card is non-busy if the most recent bit is 1 */
+		if (scratch->status[i] & 0x01)
 			return 0;
 	}
 	return mmc_spi_wait_unbusy(host, timeout);
@@ -693,11 +770,13 @@ mmc_spi_writeblock(struct mmc_spi_host *
  */
 static int
 mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
-	ktime_t timeout)
+	unsigned long timeout)
 {
 	struct spi_device	*spi = host->spi;
 	int			status;
 	struct scratch		*scratch = host->data;
+	unsigned int 		bitshift;
+	u8			leftover;
 
 	/* At least one SD card sends an all-zeroes byte when N(CX)
 	 * applies, before the all-ones bytes ... just cope with that.
@@ -709,38 +788,60 @@ mmc_spi_readblock(struct mmc_spi_host *h
 	if (status == 0xff || status == 0)
 		status = mmc_spi_readtoken(host, timeout);
 
-	if (status == SPI_TOKEN_SINGLE) {
-		if (host->dma_dev) {
-			dma_sync_single_for_device(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-			dma_sync_single_for_device(host->dma_dev,
-					t->rx_dma, t->len,
-					DMA_FROM_DEVICE);
-		}
+	if (status < 0) {
+		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+		return status;
+	}
 
-		status = spi_sync(spi, &host->m);
+	/* The token may be bit-shifted...
+	 * the first 0-bit precedes the data stream.
+	 */
+	bitshift = 7;
+	while (status & 0x80) {
+		status <<= 1;
+		bitshift--;
+	}
+	leftover = status << 1;
 
-		if (host->dma_dev) {
-			dma_sync_single_for_cpu(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-			dma_sync_single_for_cpu(host->dma_dev,
-					t->rx_dma, t->len,
-					DMA_FROM_DEVICE);
-		}
+	if (host->dma_dev) {
+		dma_sync_single_for_device(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+		dma_sync_single_for_device(host->dma_dev,
+				t->rx_dma, t->len,
+				DMA_FROM_DEVICE);
+	}
 
-	} else {
-		dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+	status = spi_sync(spi, &host->m);
 
-		/* we've read extra garbage, timed out, etc */
-		if (status < 0)
-			return status;
+	if (host->dma_dev) {
+		dma_sync_single_for_cpu(host->dma_dev,
+				host->data_dma, sizeof(*scratch),
+				DMA_BIDIRECTIONAL);
+		dma_sync_single_for_cpu(host->dma_dev,
+				t->rx_dma, t->len,
+				DMA_FROM_DEVICE);
+	}
 
-		/* low four bits are an R2 subset, fifth seems to be
-		 * vendor specific ... map them all to generic error..
+	if (bitshift) {
+		/* Walk through the data and the crc and do
+		 * all the magic to get byte-aligned data.
 		 */
-		return -EIO;
+		u8 *cp = t->rx_buf;
+		unsigned int len;
+		unsigned int bitright = 8 - bitshift;
+		u8 temp;
+		for (len = t->len; len; len--) {
+			temp = *cp;
+			*cp++ = leftover | (temp >> bitshift);
+			leftover = temp << bitright;
+		}
+		cp = (u8 *) &scratch->crc_val;
+		temp = *cp;
+		*cp++ = leftover | (temp >> bitshift);
+		leftover = temp << bitright;
+		temp = *cp;
+		*cp = leftover | (temp >> bitshift);
 	}
 
 	if (host->mmc->use_spi_crc) {
@@ -779,7 +880,7 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 	unsigned		n_sg;
 	int			multiple = (data->blocks > 1);
 	u32			clock_rate;
-	ktime_t			timeout;
+	unsigned long		timeout;
 
 	if (data->flags & MMC_DATA_READ)
 		direction = DMA_FROM_DEVICE;
@@ -793,8 +894,9 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 	else
 		clock_rate = spi->max_speed_hz;
 
-	timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns +
-			data->timeout_clks * 1000000 / clock_rate);
+	timeout = data->timeout_ns +
+		  data->timeout_clks * 1000000 / clock_rate;
+	timeout = usecs_to_jiffies((unsigned int)(timeout / 1000)) + 1;
 
 	/* Handle scatterlist segments one at a time, with synch for
 	 * each 512-byte block
@@ -1204,10 +1306,12 @@ static int mmc_spi_probe(struct spi_devi
 
 	/* MMC and SD specs only seem to care that sampling is on the
 	 * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
-	 * should be legit.  We'll use mode 0 since it seems to be a
-	 * bit less troublesome on some hardware ... unclear why.
+	 * should be legit.  We'll use mode 0 since the steady state is 0,
+	 * which is appropriate for hotplugging, unless the platform data
+	 * specify mode 3 (if hardware is not compatible to mode 0).
 	 */
-	spi->mode = SPI_MODE_0;
+	if (spi->mode != SPI_MODE_3)
+		spi->mode = SPI_MODE_0;
 	spi->bits_per_word = 8;
 
 	status = spi_setup(spi);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/mvsdio.c linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/mvsdio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,919 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * Authors: Maen Suleiman, Nicolas Pitre
+ * Copyright (C) 2008-2009 Marvell 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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mbus.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <asm/sizes.h>
+#include <asm/unaligned.h>
+#include <plat/mvsdio.h>
+
+#include "mvsdio.h"
+
+#define DRIVER_NAME	"mvsdio"
+
+static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int nodma;
+
+struct mvsd_host {
+	void __iomem *base;
+	struct mmc_request *mrq;
+	spinlock_t lock;
+	unsigned int xfer_mode;
+	unsigned int intr_en;
+	unsigned int ctrl;
+	unsigned int pio_size;
+	void *pio_ptr;
+	unsigned int sg_frags;
+	unsigned int ns_per_clk;
+	unsigned int clock;
+	unsigned int base_clock;
+	struct timer_list timer;
+	struct mmc_host *mmc;
+	struct device *dev;
+	struct resource *res;
+	int irq;
+	int gpio_card_detect;
+	int gpio_write_protect;
+};
+
+#define mvsd_write(offs, val)	writel(val, iobase + (offs))
+#define mvsd_read(offs)		readl(iobase + (offs))
+
+static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
+{
+	void __iomem *iobase = host->base;
+	unsigned int tmout;
+	int tmout_index;
+
+	/*
+	 * Hardware weirdness.  The FIFO_EMPTY bit of the HW_STATE
+	 * register is sometimes not set before a while when some
+	 * "unusual" data block sizes are used (such as with the SWITCH
+	 * command), even despite the fact that the XFER_DONE interrupt
+	 * was raised.  And if another data transfer starts before
+	 * this bit comes to good sense (which eventually happens by
+	 * itself) then the new transfer simply fails with a timeout.
+	 */
+	if (!(mvsd_read(MVSD_HW_STATE) & (1 << 13))) {
+		unsigned long t = jiffies + HZ;
+		unsigned int hw_state,  count = 0;
+		do {
+			if (time_after(jiffies, t)) {
+				dev_warn(host->dev, "FIFO_EMPTY bit missing\n");
+				break;
+			}
+			hw_state = mvsd_read(MVSD_HW_STATE);
+			count++;
+		} while (!(hw_state & (1 << 13)));
+		dev_dbg(host->dev, "*** wait for FIFO_EMPTY bit "
+				   "(hw=0x%04x, count=%d, jiffies=%ld)\n",
+				   hw_state, count, jiffies - (t - HZ));
+	}
+
+	/* If timeout=0 then maximum timeout index is used. */
+	tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
+	tmout += data->timeout_clks;
+	tmout_index = fls(tmout - 1) - 12;
+	if (tmout_index < 0)
+		tmout_index = 0;
+	if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
+		tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
+
+	dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+		(data->flags & MMC_DATA_READ) ? "read" : "write",
+		(u32)sg_virt(data->sg), data->blocks, data->blksz,
+		tmout, tmout_index);
+
+	host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
+	host->ctrl |= MVSD_HOST_CTRL_TMOUT(tmout_index);
+	mvsd_write(MVSD_HOST_CTRL, host->ctrl);
+	mvsd_write(MVSD_BLK_COUNT, data->blocks);
+	mvsd_write(MVSD_BLK_SIZE, data->blksz);
+
+	if (nodma || (data->blksz | data->sg->offset) & 3) {
+		/*
+		 * We cannot do DMA on a buffer which offset or size
+		 * is not aligned on a 4-byte boundary.
+		 */
+		host->pio_size = data->blocks * data->blksz;
+		host->pio_ptr = sg_virt(data->sg);
+		if (!nodma)
+			printk(KERN_DEBUG "%s: fallback to PIO for data "
+					  "at 0x%p size %d\n",
+					  mmc_hostname(host->mmc),
+					  host->pio_ptr, host->pio_size);
+		return 1;
+	} else {
+		dma_addr_t phys_addr;
+		int dma_dir = (data->flags & MMC_DATA_READ) ?
+			DMA_FROM_DEVICE : DMA_TO_DEVICE;
+		host->sg_frags = dma_map_sg(mmc_dev(host->mmc), data->sg,
+					    data->sg_len, dma_dir);
+		phys_addr = sg_dma_address(data->sg);
+		mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
+		mvsd_write(MVSD_SYS_ADDR_HI,  (u32)phys_addr >> 16);
+		return 0;
+	}
+}
+
+static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	struct mmc_command *cmd = mrq->cmd;
+	u32 cmdreg = 0, xfer = 0, intr = 0;
+	unsigned long flags;
+
+	BUG_ON(host->mrq != NULL);
+	host->mrq = mrq;
+
+	dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n",
+		cmd->opcode, mvsd_read(MVSD_HW_STATE));
+
+	cmdreg = MVSD_CMD_INDEX(cmd->opcode);
+
+	if (cmd->flags & MMC_RSP_BUSY)
+		cmdreg |= MVSD_CMD_RSP_48BUSY;
+	else if (cmd->flags & MMC_RSP_136)
+		cmdreg |= MVSD_CMD_RSP_136;
+	else if (cmd->flags & MMC_RSP_PRESENT)
+		cmdreg |= MVSD_CMD_RSP_48;
+	else
+		cmdreg |= MVSD_CMD_RSP_NONE;
+
+	if (cmd->flags & MMC_RSP_CRC)
+		cmdreg |= MVSD_CMD_CHECK_CMDCRC;
+
+	if (cmd->flags & MMC_RSP_OPCODE)
+		cmdreg |= MVSD_CMD_INDX_CHECK;
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		cmdreg |= MVSD_UNEXPECTED_RESP;
+		intr |= MVSD_NOR_UNEXP_RSP;
+	}
+
+	if (mrq->data) {
+		struct mmc_data *data = mrq->data;
+		int pio;
+
+		cmdreg |= MVSD_CMD_DATA_PRESENT | MVSD_CMD_CHECK_DATACRC16;
+		xfer |= MVSD_XFER_MODE_HW_WR_DATA_EN;
+		if (data->flags & MMC_DATA_READ)
+			xfer |= MVSD_XFER_MODE_TO_HOST;
+
+		pio = mvsd_setup_data(host, data);
+		if (pio) {
+			xfer |= MVSD_XFER_MODE_PIO;
+			/* PIO section of mvsd_irq has comments on those bits */
+			if (data->flags & MMC_DATA_WRITE)
+				intr |= MVSD_NOR_TX_AVAIL;
+			else if (host->pio_size > 32)
+				intr |= MVSD_NOR_RX_FIFO_8W;
+			else
+				intr |= MVSD_NOR_RX_READY;
+		}
+
+		if (data->stop) {
+			struct mmc_command *stop = data->stop;
+			u32 cmd12reg = 0;
+
+			mvsd_write(MVSD_AUTOCMD12_ARG_LOW, stop->arg & 0xffff);
+			mvsd_write(MVSD_AUTOCMD12_ARG_HI,  stop->arg >> 16);
+
+			if (stop->flags & MMC_RSP_BUSY)
+				cmd12reg |= MVSD_AUTOCMD12_BUSY;
+			if (stop->flags & MMC_RSP_OPCODE)
+				cmd12reg |= MVSD_AUTOCMD12_INDX_CHECK;
+			cmd12reg |= MVSD_AUTOCMD12_INDEX(stop->opcode);
+			mvsd_write(MVSD_AUTOCMD12_CMD, cmd12reg);
+
+			xfer |= MVSD_XFER_MODE_AUTO_CMD12;
+			intr |= MVSD_NOR_AUTOCMD12_DONE;
+		} else {
+			intr |= MVSD_NOR_XFER_DONE;
+		}
+	} else {
+		intr |= MVSD_NOR_CMD_DONE;
+	}
+
+	mvsd_write(MVSD_ARG_LOW, cmd->arg & 0xffff);
+	mvsd_write(MVSD_ARG_HI,  cmd->arg >> 16);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+	host->xfer_mode |= xfer;
+	mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+	mvsd_write(MVSD_NOR_INTR_STATUS, ~MVSD_NOR_CARD_INT);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_CMD, cmdreg);
+
+	host->intr_en &= MVSD_NOR_CARD_INT;
+	host->intr_en |= intr | MVSD_NOR_ERROR;
+	mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+	mvsd_write(MVSD_ERR_INTR_EN, 0xffff);
+
+	mod_timer(&host->timer, jiffies + 5 * HZ);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static u32 mvsd_finish_cmd(struct mvsd_host *host, struct mmc_command *cmd,
+			   u32 err_status)
+{
+	void __iomem *iobase = host->base;
+
+	if (cmd->flags & MMC_RSP_136) {
+		unsigned int response[8], i;
+		for (i = 0; i < 8; i++)
+			response[i] = mvsd_read(MVSD_RSP(i));
+		cmd->resp[0] =		((response[0] & 0x03ff) << 22) |
+					((response[1] & 0xffff) << 6) |
+					((response[2] & 0xfc00) >> 10);
+		cmd->resp[1] =		((response[2] & 0x03ff) << 22) |
+					((response[3] & 0xffff) << 6) |
+					((response[4] & 0xfc00) >> 10);
+		cmd->resp[2] =		((response[4] & 0x03ff) << 22) |
+					((response[5] & 0xffff) << 6) |
+					((response[6] & 0xfc00) >> 10);
+		cmd->resp[3] =		((response[6] & 0x03ff) << 22) |
+					((response[7] & 0x3fff) << 8);
+	} else if (cmd->flags & MMC_RSP_PRESENT) {
+		unsigned int response[3], i;
+		for (i = 0; i < 3; i++)
+			response[i] = mvsd_read(MVSD_RSP(i));
+		cmd->resp[0] =		((response[2] & 0x003f) << (8 - 8)) |
+					((response[1] & 0xffff) << (14 - 8)) |
+					((response[0] & 0x03ff) << (30 - 8));
+		cmd->resp[1] =		((response[0] & 0xfc00) >> 10);
+		cmd->resp[2] = 0;
+		cmd->resp[3] = 0;
+	}
+
+	if (err_status & MVSD_ERR_CMD_TIMEOUT) {
+		cmd->error = -ETIMEDOUT;
+	} else if (err_status & (MVSD_ERR_CMD_CRC | MVSD_ERR_CMD_ENDBIT |
+				 MVSD_ERR_CMD_INDEX | MVSD_ERR_CMD_STARTBIT)) {
+		cmd->error = -EILSEQ;
+	}
+	err_status &= ~(MVSD_ERR_CMD_TIMEOUT | MVSD_ERR_CMD_CRC |
+			MVSD_ERR_CMD_ENDBIT | MVSD_ERR_CMD_INDEX |
+			MVSD_ERR_CMD_STARTBIT);
+
+	return err_status;
+}
+
+static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+			    u32 err_status)
+{
+	void __iomem *iobase = host->base;
+
+	if (host->pio_ptr) {
+		host->pio_ptr = NULL;
+		host->pio_size = 0;
+	} else {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
+			     (data->flags & MMC_DATA_READ) ?
+				DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	}
+
+	if (err_status & MVSD_ERR_DATA_TIMEOUT)
+		data->error = -ETIMEDOUT;
+	else if (err_status & (MVSD_ERR_DATA_CRC | MVSD_ERR_DATA_ENDBIT))
+		data->error = -EILSEQ;
+	else if (err_status & MVSD_ERR_XFER_SIZE)
+		data->error = -EBADE;
+	err_status &= ~(MVSD_ERR_DATA_TIMEOUT | MVSD_ERR_DATA_CRC |
+			MVSD_ERR_DATA_ENDBIT | MVSD_ERR_XFER_SIZE);
+
+	dev_dbg(host->dev, "data done: blocks_left=%d, bytes_left=%d\n",
+		mvsd_read(MVSD_CURR_BLK_LEFT), mvsd_read(MVSD_CURR_BYTE_LEFT));
+	data->bytes_xfered =
+		(data->blocks - mvsd_read(MVSD_CURR_BLK_LEFT)) * data->blksz;
+	/* We can't be sure about the last block when errors are detected */
+	if (data->bytes_xfered && data->error)
+		data->bytes_xfered -= data->blksz;
+
+	/* Handle Auto cmd 12 response */
+	if (data->stop) {
+		unsigned int response[3], i;
+		for (i = 0; i < 3; i++)
+			response[i] = mvsd_read(MVSD_AUTO_RSP(i));
+		data->stop->resp[0] =	((response[2] & 0x003f) << (8 - 8)) |
+					((response[1] & 0xffff) << (14 - 8)) |
+					((response[0] & 0x03ff) << (30 - 8));
+		data->stop->resp[1] =	((response[0] & 0xfc00) >> 10);
+		data->stop->resp[2] = 0;
+		data->stop->resp[3] = 0;
+
+		if (err_status & MVSD_ERR_AUTOCMD12) {
+			u32 err_cmd12 = mvsd_read(MVSD_AUTOCMD12_ERR_STATUS);
+			dev_dbg(host->dev, "c12err 0x%04x\n", err_cmd12);
+			if (err_cmd12 & MVSD_AUTOCMD12_ERR_NOTEXE)
+				data->stop->error = -ENOEXEC;
+			else if (err_cmd12 & MVSD_AUTOCMD12_ERR_TIMEOUT)
+				data->stop->error = -ETIMEDOUT;
+			else if (err_cmd12)
+				data->stop->error = -EILSEQ;
+			err_status &= ~MVSD_ERR_AUTOCMD12;
+		}
+	}
+
+	return err_status;
+}
+
+static irqreturn_t mvsd_irq(int irq, void *dev)
+{
+	struct mvsd_host *host = dev;
+	void __iomem *iobase = host->base;
+	u32 intr_status, intr_done_mask;
+	int irq_handled = 0;
+
+	intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+	dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
+		intr_status, mvsd_read(MVSD_NOR_INTR_EN),
+		mvsd_read(MVSD_HW_STATE));
+
+	spin_lock(&host->lock);
+
+	/* PIO handling, if needed. Messy business... */
+	if (host->pio_size &&
+	    (intr_status & host->intr_en &
+	     (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+		u16 *p = host->pio_ptr;
+		int s = host->pio_size;
+		while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
+			readsw(iobase + MVSD_FIFO, p, 16);
+			p += 16;
+			s -= 32;
+			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		/*
+		 * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+		 * doesn't appear to assert when there is exactly 32 bytes
+		 * (8 words) left to fetch in a transfer.
+		 */
+		if (s <= 32) {
+			while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				s -= 4;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
+				u16 val[2] = {0, 0};
+				val[0] = mvsd_read(MVSD_FIFO);
+				val[1] = mvsd_read(MVSD_FIFO);
+				memcpy(p, &val, s);
+				s = 0;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			} else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+				host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+				host->intr_en |= MVSD_NOR_RX_READY;
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, intr_status, mvsd_read(MVSD_HW_STATE));
+		host->pio_ptr = p;
+		host->pio_size = s;
+		irq_handled = 1;
+	} else if (host->pio_size &&
+		   (intr_status & host->intr_en &
+		    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+		u16 *p = host->pio_ptr;
+		int s = host->pio_size;
+		/*
+		 * The TX_FIFO_8W bit is unreliable. When set, bursting
+		 * 16 halfwords all at once in the FIFO drops data. Actually
+		 * TX_AVAIL does go off after only one word is pushed even if
+		 * TX_FIFO_8W remains set.
+		 */
+		while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			s -= 4;
+			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		if (s < 4) {
+			if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
+				u16 val[2] = {0, 0};
+				memcpy(&val, p, s);
+				mvsd_write(MVSD_FIFO, val[0]);
+				mvsd_write(MVSD_FIFO, val[1]);
+				s = 0;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, intr_status, mvsd_read(MVSD_HW_STATE));
+		host->pio_ptr = p;
+		host->pio_size = s;
+		irq_handled = 1;
+	}
+
+	mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);
+
+	intr_done_mask = MVSD_NOR_CARD_INT | MVSD_NOR_RX_READY |
+			 MVSD_NOR_RX_FIFO_8W | MVSD_NOR_TX_FIFO_8W;
+	if (intr_status & host->intr_en & ~intr_done_mask) {
+		struct mmc_request *mrq = host->mrq;
+		struct mmc_command *cmd = mrq->cmd;
+		u32 err_status = 0;
+
+		del_timer(&host->timer);
+		host->mrq = NULL;
+
+		host->intr_en &= MVSD_NOR_CARD_INT;
+		mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+		mvsd_write(MVSD_ERR_INTR_EN, 0);
+
+		spin_unlock(&host->lock);
+
+		if (intr_status & MVSD_NOR_UNEXP_RSP) {
+			cmd->error = -EPROTO;
+		} else if (intr_status & MVSD_NOR_ERROR) {
+			err_status = mvsd_read(MVSD_ERR_INTR_STATUS);
+			dev_dbg(host->dev, "err 0x%04x\n", err_status);
+		}
+
+		err_status = mvsd_finish_cmd(host, cmd, err_status);
+		if (mrq->data)
+			err_status = mvsd_finish_data(host, mrq->data, err_status);
+		if (err_status) {
+			printk(KERN_ERR "%s: unhandled error status %#04x\n",
+					mmc_hostname(host->mmc), err_status);
+			cmd->error = -ENOMSG;
+		}
+
+		mmc_request_done(host->mmc, mrq);
+		irq_handled = 1;
+	} else
+		spin_unlock(&host->lock);
+
+	if (intr_status & MVSD_NOR_CARD_INT) {
+		mmc_signal_sdio_irq(host->mmc);
+		irq_handled = 1;
+	}
+
+	if (irq_handled)
+		return IRQ_HANDLED;
+
+	printk(KERN_ERR "%s: unhandled interrupt status=0x%04x en=0x%04x "
+			"pio=%d\n", mmc_hostname(host->mmc), intr_status,
+			host->intr_en, host->pio_size);
+	return IRQ_NONE;
+}
+
+static void mvsd_timeout_timer(unsigned long data)
+{
+	struct mvsd_host *host = (struct mvsd_host *)data;
+	void __iomem *iobase = host->base;
+	struct mmc_request *mrq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	mrq = host->mrq;
+	if (mrq) {
+		printk(KERN_ERR "%s: Timeout waiting for hardware interrupt.\n",
+				mmc_hostname(host->mmc));
+		printk(KERN_ERR "%s: hw_state=0x%04x, intr_status=0x%04x "
+				"intr_en=0x%04x\n", mmc_hostname(host->mmc),
+				mvsd_read(MVSD_HW_STATE),
+				mvsd_read(MVSD_NOR_INTR_STATUS),
+				mvsd_read(MVSD_NOR_INTR_EN));
+
+		host->mrq = NULL;
+
+		mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+
+		host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+		mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+		host->intr_en &= MVSD_NOR_CARD_INT;
+		mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+		mvsd_write(MVSD_ERR_INTR_EN, 0);
+		mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+
+		mrq->cmd->error = -ETIMEDOUT;
+		mvsd_finish_cmd(host, mrq->cmd, 0);
+		if (mrq->data) {
+			mrq->data->error = -ETIMEDOUT;
+			mvsd_finish_data(host, mrq->data, 0);
+		}
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (mrq)
+		mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
+{
+	struct mvsd_host *host = dev;
+	mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+	return IRQ_HANDLED;
+}
+
+static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (enable) {
+		host->xfer_mode |= MVSD_XFER_MODE_INT_CHK_EN;
+		host->intr_en |= MVSD_NOR_CARD_INT;
+	} else {
+		host->xfer_mode &= ~MVSD_XFER_MODE_INT_CHK_EN;
+		host->intr_en &= ~MVSD_NOR_CARD_INT;
+	}
+	mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+	mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int mvsd_get_ro(struct mmc_host *mmc)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+
+	if (host->gpio_write_protect)
+		return gpio_get_value(host->gpio_write_protect);
+
+	/*
+	 * Board doesn't support read only detection; let the mmc core
+	 * decide what to do.
+	 */
+	return -ENOSYS;
+}
+
+static void mvsd_power_up(struct mvsd_host *host)
+{
+	void __iomem *iobase = host->base;
+	dev_dbg(host->dev, "power up\n");
+	mvsd_write(MVSD_NOR_INTR_EN, 0);
+	mvsd_write(MVSD_ERR_INTR_EN, 0);
+	mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+	mvsd_write(MVSD_XFER_MODE, 0);
+	mvsd_write(MVSD_NOR_STATUS_EN, 0xffff);
+	mvsd_write(MVSD_ERR_STATUS_EN, 0xffff);
+	mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_power_down(struct mvsd_host *host)
+{
+	void __iomem *iobase = host->base;
+	dev_dbg(host->dev, "power down\n");
+	mvsd_write(MVSD_NOR_INTR_EN, 0);
+	mvsd_write(MVSD_ERR_INTR_EN, 0);
+	mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+	mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+	mvsd_write(MVSD_NOR_STATUS_EN, 0);
+	mvsd_write(MVSD_ERR_STATUS_EN, 0);
+	mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	u32 ctrl_reg = 0;
+
+	if (ios->power_mode == MMC_POWER_UP)
+		mvsd_power_up(host);
+
+	if (ios->clock == 0) {
+		mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+		mvsd_write(MVSD_CLK_DIV, MVSD_BASE_DIV_MAX);
+		host->clock = 0;
+		dev_dbg(host->dev, "clock off\n");
+	} else if (ios->clock != host->clock) {
+		u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
+		if (m > MVSD_BASE_DIV_MAX)
+			m = MVSD_BASE_DIV_MAX;
+		mvsd_write(MVSD_CLK_DIV, m);
+		host->clock = ios->clock;
+		host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
+		dev_dbg(host->dev, "clock=%d (%d), div=0x%04x\n",
+			ios->clock, host->base_clock / (m+1), m);
+	}
+
+	/* default transfer mode */
+	ctrl_reg |= MVSD_HOST_CTRL_BIG_ENDIAN;
+	ctrl_reg &= ~MVSD_HOST_CTRL_LSB_FIRST;
+
+	/* default to maximum timeout */
+	ctrl_reg |= MVSD_HOST_CTRL_TMOUT_MASK;
+	ctrl_reg |= MVSD_HOST_CTRL_TMOUT_EN;
+
+	if (ios->bus_mode == MMC_BUSMODE_PUSHPULL)
+		ctrl_reg |= MVSD_HOST_CTRL_PUSH_PULL_EN;
+
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+	/*
+	 * The HI_SPEED_EN bit is causing trouble with many (but not all)
+	 * high speed SD, SDHC and SDIO cards.  Not enabling that bit
+	 * makes all cards work.  So let's just ignore that bit for now
+	 * and revisit this issue if problems for not enabling this bit
+	 * are ever reported.
+	 */
+#if 0
+	if (ios->timing == MMC_TIMING_MMC_HS ||
+	    ios->timing == MMC_TIMING_SD_HS)
+		ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
+#endif
+
+	host->ctrl = ctrl_reg;
+	mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
+	dev_dbg(host->dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
+		(ctrl_reg & MVSD_HOST_CTRL_PUSH_PULL_EN) ?
+			"push-pull" : "open-drain",
+		(ctrl_reg & MVSD_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+			"4bit-width" : "1bit-width",
+		(ctrl_reg & MVSD_HOST_CTRL_HI_SPEED_EN) ?
+			"high-speed" : "");
+
+	if (ios->power_mode == MMC_POWER_OFF)
+		mvsd_power_down(host);
+}
+
+static const struct mmc_host_ops mvsd_ops = {
+	.request		= mvsd_request,
+	.get_ro			= mvsd_get_ro,
+	.set_ios		= mvsd_set_ios,
+	.enable_sdio_irq	= mvsd_enable_sdio_irq,
+};
+
+static void __init mv_conf_mbus_windows(struct mvsd_host *host,
+					struct mbus_dram_target_info *dram)
+{
+	void __iomem *iobase = host->base;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		writel(0, iobase + MVSD_WINDOW_CTRL(i));
+		writel(0, iobase + MVSD_WINDOW_BASE(i));
+	}
+
+	for (i = 0; i < dram->num_cs; i++) {
+		struct mbus_dram_window *cs = dram->cs + i;
+		writel(((cs->size - 1) & 0xffff0000) |
+		       (cs->mbus_attr << 8) |
+		       (dram->mbus_dram_target_id << 4) | 1,
+		       iobase + MVSD_WINDOW_CTRL(i));
+		writel(cs->base, iobase + MVSD_WINDOW_BASE(i));
+	}
+}
+
+static int __init mvsd_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = NULL;
+	struct mvsd_host *host = NULL;
+	const struct mvsdio_platform_data *mvsd_data;
+	struct resource *r;
+	int ret, irq;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	mvsd_data = pdev->dev.platform_data;
+	if (!r || irq < 0 || !mvsd_data)
+		return -ENXIO;
+
+	r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
+	if (!r)
+		return -EBUSY;
+
+	mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->dev = &pdev->dev;
+	host->res = r;
+	host->base_clock = mvsd_data->clock / 2;
+
+	mmc->ops = &mvsd_ops;
+
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+		    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+
+	mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+	mmc->f_max = maxfreq;
+
+	mmc->max_blk_size = 2048;
+	mmc->max_blk_count = 65535;
+
+	mmc->max_hw_segs = 1;
+	mmc->max_phys_segs = 1;
+	mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+	spin_lock_init(&host->lock);
+
+	host->base = ioremap(r->start, SZ_4K);
+	if (!host->base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* (Re-)program MBUS remapping windows if we are asked to. */
+	if (mvsd_data->dram != NULL)
+		mv_conf_mbus_windows(host, mvsd_data->dram);
+
+	mvsd_power_down(host);
+
+	ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+	if (ret) {
+		printk(KERN_ERR "%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+		goto out;
+	} else
+		host->irq = irq;
+
+	if (mvsd_data->gpio_card_detect) {
+		ret = gpio_request(mvsd_data->gpio_card_detect,
+				   DRIVER_NAME " cd");
+		if (ret == 0) {
+			gpio_direction_input(mvsd_data->gpio_card_detect);
+			irq = gpio_to_irq(mvsd_data->gpio_card_detect);
+			ret = request_irq(irq, mvsd_card_detect_irq,
+					  IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+					  DRIVER_NAME " cd", host);
+			if (ret == 0)
+				host->gpio_card_detect =
+					mvsd_data->gpio_card_detect;
+			else
+				gpio_free(mvsd_data->gpio_card_detect);
+		}
+	}
+	if (!host->gpio_card_detect)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	if (mvsd_data->gpio_write_protect) {
+		ret = gpio_request(mvsd_data->gpio_write_protect,
+				   DRIVER_NAME " wp");
+		if (ret == 0) {
+			gpio_direction_input(mvsd_data->gpio_write_protect);
+			host->gpio_write_protect =
+				mvsd_data->gpio_write_protect;
+		}
+	}
+
+	setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
+	platform_set_drvdata(pdev, mmc);
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto out;
+
+	printk(KERN_NOTICE "%s: %s driver initialized, ",
+			   mmc_hostname(mmc), DRIVER_NAME);
+	if (host->gpio_card_detect)
+		printk("using GPIO %d for card detection\n",
+		       host->gpio_card_detect);
+	else
+		printk("lacking card detect (fall back to polling)\n");
+	return 0;
+
+out:
+	if (host) {
+		if (host->irq)
+			free_irq(host->irq, host);
+		if (host->gpio_card_detect) {
+			free_irq(gpio_to_irq(host->gpio_card_detect), host);
+			gpio_free(host->gpio_card_detect);
+		}
+		if (host->gpio_write_protect)
+			gpio_free(host->gpio_write_protect);
+		if (host->base)
+			iounmap(host->base);
+	}
+	if (r)
+		release_resource(r);
+	if (mmc)
+		mmc_free_host(mmc);
+
+	return ret;
+}
+
+static int __exit mvsd_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+	if (mmc) {
+		struct mvsd_host *host = mmc_priv(mmc);
+
+		if (host->gpio_card_detect) {
+			free_irq(gpio_to_irq(host->gpio_card_detect), host);
+			gpio_free(host->gpio_card_detect);
+		}
+		mmc_remove_host(mmc);
+		free_irq(host->irq, host);
+		if (host->gpio_write_protect)
+			gpio_free(host->gpio_write_protect);
+		del_timer_sync(&host->timer);
+		mvsd_power_down(host);
+		iounmap(host->base);
+		release_resource(host->res);
+		mmc_free_host(mmc);
+	}
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mvsd_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc)
+		ret = mmc_suspend_host(mmc, state);
+
+	return ret;
+}
+
+static int mvsd_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc)
+		ret = mmc_resume_host(mmc);
+
+	return ret;
+}
+#else
+#define mvsd_suspend	NULL
+#define mvsd_resume	NULL
+#endif
+
+static struct platform_driver mvsd_driver = {
+	.remove		= __exit_p(mvsd_remove),
+	.suspend	= mvsd_suspend,
+	.resume		= mvsd_resume,
+	.driver		= {
+		.name	= DRIVER_NAME,
+	},
+};
+
+static int __init mvsd_init(void)
+{
+	return platform_driver_probe(&mvsd_driver, mvsd_probe);
+}
+
+static void __exit mvsd_exit(void)
+{
+	platform_driver_unregister(&mvsd_driver);
+}
+
+module_init(mvsd_init);
+module_exit(mvsd_exit);
+
+/* maximum card clock frequency (default 50MHz) */
+module_param(maxfreq, int, 0);
+
+/* force PIO transfers all the time */
+module_param(nodma, int, 0);
+
+MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
+MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mvsdio");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/mvsdio.h linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.h
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/mvsdio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2008 Marvell Semiconductors, 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.
+ */
+
+#ifndef __MVSDIO_H
+#define __MVSDIO_H
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX			50000000
+#define MVSD_BASE_DIV_MAX			0x7ff
+
+
+/*
+ * Register offsets
+ */
+
+#define MVSD_SYS_ADDR_LOW			0x000
+#define MVSD_SYS_ADDR_HI			0x004
+#define MVSD_BLK_SIZE				0x008
+#define MVSD_BLK_COUNT				0x00c
+#define MVSD_ARG_LOW				0x010
+#define MVSD_ARG_HI				0x014
+#define MVSD_XFER_MODE				0x018
+#define MVSD_CMD				0x01c
+#define MVSD_RSP(i)				(0x020 + ((i)<<2))
+#define MVSD_RSP0				0x020
+#define MVSD_RSP1				0x024
+#define MVSD_RSP2				0x028
+#define MVSD_RSP3				0x02c
+#define MVSD_RSP4				0x030
+#define MVSD_RSP5				0x034
+#define MVSD_RSP6				0x038
+#define MVSD_RSP7				0x03c
+#define MVSD_FIFO				0x040
+#define MVSD_RSP_CRC7				0x044
+#define MVSD_HW_STATE				0x048
+#define MVSD_HOST_CTRL				0x050
+#define MVSD_BLK_GAP_CTRL			0x054
+#define MVSD_CLK_CTRL				0x058
+#define MVSD_SW_RESET				0x05c
+#define MVSD_NOR_INTR_STATUS			0x060
+#define MVSD_ERR_INTR_STATUS			0x064
+#define MVSD_NOR_STATUS_EN			0x068
+#define MVSD_ERR_STATUS_EN			0x06c
+#define MVSD_NOR_INTR_EN			0x070
+#define MVSD_ERR_INTR_EN			0x074
+#define MVSD_AUTOCMD12_ERR_STATUS		0x078
+#define MVSD_CURR_BYTE_LEFT			0x07c
+#define MVSD_CURR_BLK_LEFT			0x080
+#define MVSD_AUTOCMD12_ARG_LOW			0x084
+#define MVSD_AUTOCMD12_ARG_HI			0x088
+#define MVSD_AUTOCMD12_CMD			0x08c
+#define MVSD_AUTO_RSP(i)			(0x090 + ((i)<<2))
+#define MVSD_AUTO_RSP0				0x090
+#define MVSD_AUTO_RSP1				0x094
+#define MVSD_AUTO_RSP2				0x098
+#define MVSD_CLK_DIV				0x128
+
+#define MVSD_WINDOW_CTRL(i)			(0x108 + ((i) << 3))
+#define MVSD_WINDOW_BASE(i)			(0x10c + ((i) << 3))
+
+
+/*
+ * MVSD_CMD
+ */
+
+#define MVSD_CMD_RSP_NONE			(0 << 0)
+#define MVSD_CMD_RSP_136			(1 << 0)
+#define MVSD_CMD_RSP_48				(2 << 0)
+#define MVSD_CMD_RSP_48BUSY			(3 << 0)
+
+#define MVSD_CMD_CHECK_DATACRC16		(1 << 2)
+#define MVSD_CMD_CHECK_CMDCRC			(1 << 3)
+#define MVSD_CMD_INDX_CHECK			(1 << 4)
+#define MVSD_CMD_DATA_PRESENT			(1 << 5)
+#define MVSD_UNEXPECTED_RESP			(1 << 7)
+#define MVSD_CMD_INDEX(x)			((x) << 8)
+
+
+/*
+ * MVSD_AUTOCMD12_CMD
+ */
+
+#define MVSD_AUTOCMD12_BUSY			(1 << 0)
+#define MVSD_AUTOCMD12_INDX_CHECK		(1 << 1)
+#define MVSD_AUTOCMD12_INDEX(x)			((x) << 8)
+
+/*
+ * MVSD_XFER_MODE
+ */
+
+#define MVSD_XFER_MODE_WR_DATA_START		(1 << 0)
+#define MVSD_XFER_MODE_HW_WR_DATA_EN		(1 << 1)
+#define MVSD_XFER_MODE_AUTO_CMD12		(1 << 2)
+#define MVSD_XFER_MODE_INT_CHK_EN		(1 << 3)
+#define MVSD_XFER_MODE_TO_HOST			(1 << 4)
+#define MVSD_XFER_MODE_STOP_CLK			(1 << 5)
+#define MVSD_XFER_MODE_PIO			(1 << 6)
+
+
+/*
+ * MVSD_HOST_CTRL
+ */
+
+#define MVSD_HOST_CTRL_PUSH_PULL_EN 		(1 << 0)
+
+#define MVSD_HOST_CTRL_CARD_TYPE_MEM_ONLY 	(0 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_ONLY 	(1 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO 	(2 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MMC 	(3 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_MASK	 	(3 << 1)
+
+#define MVSD_HOST_CTRL_BIG_ENDIAN 		(1 << 3)
+#define MVSD_HOST_CTRL_LSB_FIRST 		(1 << 4)
+#define MVSD_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define MVSD_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+#define MVSD_HOST_CTRL_TMOUT_MAX 		0xf
+#define MVSD_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define MVSD_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define MVSD_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+
+/*
+ * MVSD_SW_RESET
+ */
+
+#define MVSD_SW_RESET_NOW			(1 << 8)
+
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define MVSD_NOR_CMD_DONE			(1 << 0)
+#define MVSD_NOR_XFER_DONE			(1 << 1)
+#define MVSD_NOR_BLK_GAP_EVT			(1 << 2)
+#define MVSD_NOR_DMA_DONE			(1 << 3)
+#define MVSD_NOR_TX_AVAIL			(1 << 4)
+#define MVSD_NOR_RX_READY			(1 << 5)
+#define MVSD_NOR_CARD_INT			(1 << 8)
+#define MVSD_NOR_READ_WAIT_ON			(1 << 9)
+#define MVSD_NOR_RX_FIFO_8W			(1 << 10)
+#define MVSD_NOR_TX_FIFO_8W			(1 << 11)
+#define MVSD_NOR_SUSPEND_ON			(1 << 12)
+#define MVSD_NOR_AUTOCMD12_DONE			(1 << 13)
+#define MVSD_NOR_UNEXP_RSP			(1 << 14)
+#define MVSD_NOR_ERROR				(1 << 15)
+
+
+/*
+ * Error status bits
+ */
+
+#define MVSD_ERR_CMD_TIMEOUT			(1 << 0)
+#define MVSD_ERR_CMD_CRC			(1 << 1)
+#define MVSD_ERR_CMD_ENDBIT			(1 << 2)
+#define MVSD_ERR_CMD_INDEX			(1 << 3)
+#define MVSD_ERR_DATA_TIMEOUT			(1 << 4)
+#define MVSD_ERR_DATA_CRC			(1 << 5)
+#define MVSD_ERR_DATA_ENDBIT			(1 << 6)
+#define MVSD_ERR_AUTOCMD12			(1 << 8)
+#define MVSD_ERR_CMD_STARTBIT			(1 << 9)
+#define MVSD_ERR_XFER_SIZE			(1 << 10)
+#define MVSD_ERR_RESP_T_BIT			(1 << 11)
+#define MVSD_ERR_CRC_ENDBIT			(1 << 12)
+#define MVSD_ERR_CRC_STARTBIT			(1 << 13)
+#define MVSD_ERR_CRC_STATUS			(1 << 14)
+
+
+/*
+ * CMD12 error status bits
+ */
+
+#define MVSD_AUTOCMD12_ERR_NOTEXE		(1 << 0)
+#define MVSD_AUTOCMD12_ERR_TIMEOUT		(1 << 1)
+#define MVSD_AUTOCMD12_ERR_CRC			(1 << 2)
+#define MVSD_AUTOCMD12_ERR_ENDBIT		(1 << 3)
+#define MVSD_AUTOCMD12_ERR_INDEX		(1 << 4)
+#define MVSD_AUTOCMD12_ERR_RESP_T_BIT		(1 << 5)
+#define MVSD_AUTOCMD12_ERR_RESP_STARTBIT	(1 << 6)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/mxcmmc.c linux-libre-2.6.30-gnu1/drivers/mmc/host/mxcmmc.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/mxcmmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/mxcmmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,7 @@
 #define HAS_DMA
 #endif
 
-#define DRIVER_NAME "imx-mmc"
+#define DRIVER_NAME "mxc-mmc"
 
 #define MMC_REG_STR_STP_CLK		0x00
 #define MMC_REG_STATUS			0x04
@@ -140,6 +140,8 @@ struct mxcmci_host {
 	struct work_struct	datawork;
 };
 
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
+
 static inline int mxcmci_use_dma(struct mxcmci_host *host)
 {
 	return host->do_dma;
@@ -160,7 +162,7 @@ static void mxcmci_softreset(struct mxcm
 	writew(0xff, host->base + MMC_REG_RES_TO);
 }
 
-static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
+static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
 {
 	unsigned int nob = data->blocks;
 	unsigned int blksz = data->blksz;
@@ -168,6 +170,7 @@ static void mxcmci_setup_data(struct mxc
 #ifdef HAS_DMA
 	struct scatterlist *sg;
 	int i;
+	int ret;
 #endif
 	if (data->flags & MMC_DATA_STREAM)
 		nob = 0xffff;
@@ -183,7 +186,7 @@ static void mxcmci_setup_data(struct mxc
 	for_each_sg(data->sg, sg, data->sg_len, i) {
 		if (sg->offset & 3 || sg->length & 3) {
 			host->do_dma = 0;
-			return;
+			return 0;
 		}
 	}
 
@@ -192,23 +195,30 @@ static void mxcmci_setup_data(struct mxc
 		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
 					     data->sg_len,  host->dma_dir);
 
-		imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
-				 host->res->start + MMC_REG_BUFFER_ACCESS,
-				 DMA_MODE_READ);
+		ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
+				datasize,
+				host->res->start + MMC_REG_BUFFER_ACCESS,
+				DMA_MODE_READ);
 	} else {
 		host->dma_dir = DMA_TO_DEVICE;
 		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
 					     data->sg_len,  host->dma_dir);
 
-		imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
-				 host->res->start + MMC_REG_BUFFER_ACCESS,
-				 DMA_MODE_WRITE);
+		ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
+				datasize,
+				host->res->start + MMC_REG_BUFFER_ACCESS,
+				DMA_MODE_WRITE);
 	}
 
+	if (ret) {
+		dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret);
+		return ret;
+	}
 	wmb();
 
 	imx_dma_enable(host->dma);
 #endif /* HAS_DMA */
+	return 0;
 }
 
 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
@@ -345,8 +355,11 @@ static int mxcmci_poll_status(struct mxc
 		stat = readl(host->base + MMC_REG_STATUS);
 		if (stat & STATUS_ERR_MASK)
 			return stat;
-		if (time_after(jiffies, timeout))
+		if (time_after(jiffies, timeout)) {
+			mxcmci_softreset(host);
+			mxcmci_set_clk_rate(host, host->clock);
 			return STATUS_TIME_OUT_READ;
+		}
 		if (stat & mask)
 			return 0;
 		cpu_relax();
@@ -531,6 +544,7 @@ static void mxcmci_request(struct mmc_ho
 {
 	struct mxcmci_host *host = mmc_priv(mmc);
 	unsigned int cmdat = host->cmdat;
+	int error;
 
 	WARN_ON(host->req != NULL);
 
@@ -540,7 +554,12 @@ static void mxcmci_request(struct mmc_ho
 	host->do_dma = 1;
 #endif
 	if (req->data) {
-		mxcmci_setup_data(host, req->data);
+		error = mxcmci_setup_data(host, req->data);
+		if (error) {
+			req->cmd->error = error;
+			goto out;
+		}
+
 
 		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
 
@@ -548,7 +567,9 @@ static void mxcmci_request(struct mmc_ho
 			cmdat |= CMD_DAT_CONT_WRITE;
 	}
 
-	if (mxcmci_start_cmd(host, req->cmd, cmdat))
+	error = mxcmci_start_cmd(host, req->cmd, cmdat);
+out:
+	if (error)
 		mxcmci_finish_request(host, req);
 }
 
@@ -707,7 +728,7 @@ static int mxcmci_probe(struct platform_
 	host->res = r;
 	host->irq = irq;
 
-	host->clk = clk_get(&pdev->dev, "sdhc_clk");
+	host->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
 		goto out_iounmap;
@@ -724,7 +745,9 @@ static int mxcmci_probe(struct platform_
 		goto out_clk_put;
 	}
 
-	mmc->f_min = clk_get_rate(host->clk) >> 7;
+	mmc->f_min = clk_get_rate(host->clk) >> 16;
+	if (mmc->f_min < 400000)
+		mmc->f_min = 400000;
 	mmc->f_max = clk_get_rate(host->clk) >> 1;
 
 	/* recommended in data sheet */
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/of_mmc_spi.c linux-libre-2.6.30-gnu1/drivers/mmc/host/of_mmc_spi.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/of_mmc_spi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/of_mmc_spi.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_ge
 		if (!gpio_is_valid(oms->gpios[i]))
 			continue;
 
-		ret = gpio_request(oms->gpios[i], dev->bus_id);
+		ret = gpio_request(oms->gpios[i], dev_name(dev));
 		if (ret < 0) {
 			oms->gpios[i] = -EINVAL;
 			continue;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/omap.c linux-libre-2.6.30-gnu1/drivers/mmc/host/omap.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/omap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/omap.c	2009-06-09 23:05:27.000000000 -0400
@@ -157,8 +157,6 @@ struct mmc_omap_host {
 	struct timer_list	dma_timer;
 	unsigned		dma_len;
 
-	short			power_pin;
-
 	struct mmc_omap_slot    *slots[OMAP_MMC_MAX_SLOTS];
 	struct mmc_omap_slot    *current_slot;
 	spinlock_t              slot_lock;
@@ -824,7 +822,7 @@ static irqreturn_t mmc_omap_irq(int irq,
 		del_timer(&host->cmd_abort_timer);
 		host->abort = 1;
 		OMAP_MMC_WRITE(host, IE, 0);
-		disable_irq(host->irq);
+		disable_irq_nosync(host->irq);
 		schedule_work(&host->cmd_abort_work);
 		return IRQ_HANDLED;
 	}
@@ -1460,18 +1458,12 @@ static int __init mmc_omap_probe(struct
 	if (!host->virt_base)
 		goto err_ioremap;
 
-	if (cpu_is_omap24xx()) {
-		host->iclk = clk_get(&pdev->dev, "mmc_ick");
-		if (IS_ERR(host->iclk))
-			goto err_free_mmc_host;
-		clk_enable(host->iclk);
-	}
-
-	if (!cpu_is_omap24xx())
-		host->fclk = clk_get(&pdev->dev, "mmc_ck");
-	else
-		host->fclk = clk_get(&pdev->dev, "mmc_fck");
+	host->iclk = clk_get(&pdev->dev, "ick");
+	if (IS_ERR(host->iclk))
+		goto err_free_mmc_host;
+	clk_enable(host->iclk);
 
+	host->fclk = clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
 		ret = PTR_ERR(host->fclk);
 		goto err_free_iclk;
@@ -1536,10 +1528,10 @@ static int mmc_omap_remove(struct platfo
 	if (host->pdata->cleanup)
 		host->pdata->cleanup(&pdev->dev);
 
-	if (host->iclk && !IS_ERR(host->iclk))
-		clk_put(host->iclk);
-	if (host->fclk && !IS_ERR(host->fclk))
-		clk_put(host->fclk);
+	mmc_omap_fclk_enable(host, 0);
+	clk_put(host->fclk);
+	clk_disable(host->iclk);
+	clk_put(host->iclk);
 
 	iounmap(host->virt_base);
 	release_mem_region(pdev->resource[0].start,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/omap_hsmmc.c linux-libre-2.6.30-gnu1/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/omap_hsmmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/omap_hsmmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -56,6 +56,7 @@
 #define SDVS18			(0x5 << 9)
 #define SDVS30			(0x6 << 9)
 #define SDVS33			(0x7 << 9)
+#define SDVS_MASK		0x00000E00
 #define SDVSCLR			0xFFFFF1FF
 #define SDVSDET			0x00000400
 #define AUTOIDLE		0x1
@@ -76,6 +77,7 @@
 #define MSBS			(1 << 5)
 #define BCE			(1 << 1)
 #define FOUR_BIT		(1 << 1)
+#define DW8			(1 << 5)
 #define CC			0x1
 #define TC			0x02
 #define OD			0x1
@@ -98,10 +100,8 @@
  */
 #define OMAP_MMC1_DEVID		0
 #define OMAP_MMC2_DEVID		1
+#define OMAP_MMC3_DEVID		2
 
-#define OMAP_MMC_DATADIR_NONE	0
-#define OMAP_MMC_DATADIR_READ	1
-#define OMAP_MMC_DATADIR_WRITE	2
 #define MMC_TIMEOUT_MS		20
 #define OMAP_MMC_MASTER_CLOCK	96000000
 #define DRIVER_NAME		"mmci-omap-hs"
@@ -137,18 +137,18 @@ struct mmc_omap_host {
 	resource_size_t		mapbase;
 	unsigned int		id;
 	unsigned int		dma_len;
-	unsigned int		dma_dir;
+	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
-	unsigned char		datadir;
 	u32			*buffer;
 	u32			bytesleft;
 	int			suspended;
 	int			irq;
 	int			carddetect;
 	int			use_dma, dma_ch;
-	int			initstr;
+	int			dma_line_tx, dma_line_rx;
 	int			slot_id;
 	int			dbclk_enabled;
+	int			response_busy;
 	struct	omap_mmc_platform_data	*pdata;
 };
 
@@ -218,7 +218,7 @@ mmc_omap_show_slot_name(struct device *d
 	struct mmc_omap_host *host = mmc_priv(mmc);
 	struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
 
-	return sprintf(buf, "slot:%s\n", slot.name);
+	return sprintf(buf, "%s\n", slot.name);
 }
 
 static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -243,10 +243,14 @@ mmc_omap_start_command(struct mmc_omap_h
 	OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
 	OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
 
+	host->response_busy = 0;
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136)
 			resptype = 1;
-		else
+		else if (cmd->flags & MMC_RSP_BUSY) {
+			resptype = 3;
+			host->response_busy = 1;
+		} else
 			resptype = 2;
 	}
 
@@ -275,19 +279,34 @@ mmc_omap_start_command(struct mmc_omap_h
 	OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
 }
 
+static int
+mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)
+{
+	if (data->flags & MMC_DATA_WRITE)
+		return DMA_TO_DEVICE;
+	else
+		return DMA_FROM_DEVICE;
+}
+
 /*
  * Notify the transfer complete to MMC core
  */
 static void
 mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 {
+	if (!data) {
+		struct mmc_request *mrq = host->mrq;
+
+		host->mrq = NULL;
+		mmc_request_done(host->mmc, mrq);
+		return;
+	}
+
 	host->data = NULL;
 
 	if (host->use_dma && host->dma_ch != -1)
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
-			host->dma_dir);
-
-	host->datadir = OMAP_MMC_DATADIR_NONE;
+			mmc_omap_get_dma_dir(host, data));
 
 	if (!data->error)
 		data->bytes_xfered += data->blocks * (data->blksz);
@@ -322,7 +341,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *
 			cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
 		}
 	}
-	if (host->data == NULL || cmd->error) {
+	if ((host->data == NULL && !host->response_busy) || cmd->error) {
 		host->mrq = NULL;
 		mmc_request_done(host->mmc, cmd->mrq);
 	}
@@ -331,19 +350,18 @@ mmc_omap_cmd_done(struct mmc_omap_host *
 /*
  * DMA clean up for command errors
  */
-static void mmc_dma_cleanup(struct mmc_omap_host *host)
+static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno)
 {
-	host->data->error = -ETIMEDOUT;
+	host->data->error = errno;
 
 	if (host->use_dma && host->dma_ch != -1) {
 		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
-			host->dma_dir);
+			mmc_omap_get_dma_dir(host, host->data));
 		omap_free_dma(host->dma_ch);
 		host->dma_ch = -1;
 		up(&host->sem);
 	}
 	host->data = NULL;
-	host->datadir = OMAP_MMC_DATADIR_NONE;
 }
 
 /*
@@ -412,9 +430,11 @@ static irqreturn_t mmc_omap_irq(int irq,
 	struct mmc_data *data;
 	int end_cmd = 0, end_trans = 0, status;
 
-	if (host->cmd == NULL && host->data == NULL) {
+	if (host->mrq == NULL) {
 		OMAP_HSMMC_WRITE(host->base, STAT,
 			OMAP_HSMMC_READ(host->base, STAT));
+		/* Flush posted write */
+		OMAP_HSMMC_READ(host->base, STAT);
 		return IRQ_HANDLED;
 	}
 
@@ -437,18 +457,24 @@ static irqreturn_t mmc_omap_irq(int irq,
 				}
 				end_cmd = 1;
 			}
-			if (host->data) {
-				mmc_dma_cleanup(host);
+			if (host->data || host->response_busy) {
+				if (host->data)
+					mmc_dma_cleanup(host, -ETIMEDOUT);
+				host->response_busy = 0;
 				mmc_omap_reset_controller_fsm(host, SRD);
 			}
 		}
 		if ((status & DATA_TIMEOUT) ||
 			(status & DATA_CRC)) {
-			if (host->data) {
-				if (status & DATA_TIMEOUT)
-					mmc_dma_cleanup(host);
+			if (host->data || host->response_busy) {
+				int err = (status & DATA_TIMEOUT) ?
+						-ETIMEDOUT : -EILSEQ;
+
+				if (host->data)
+					mmc_dma_cleanup(host, err);
 				else
-					host->data->error = -EILSEQ;
+					host->mrq->cmd->error = err;
+				host->response_busy = 0;
 				mmc_omap_reset_controller_fsm(host, SRD);
 				end_trans = 1;
 			}
@@ -464,8 +490,10 @@ static irqreturn_t mmc_omap_irq(int irq,
 	}
 
 	OMAP_HSMMC_WRITE(host->base, STAT, status);
+	/* Flush posted write */
+	OMAP_HSMMC_READ(host->base, STAT);
 
-	if (end_cmd || (status & CC))
+	if (end_cmd || ((status & CC) && host->cmd))
 		mmc_omap_cmd_done(host, host->cmd);
 	if (end_trans || (status & TC))
 		mmc_omap_xfer_done(host, data);
@@ -473,6 +501,19 @@ static irqreturn_t mmc_omap_irq(int irq,
 	return IRQ_HANDLED;
 }
 
+static void set_sd_bus_power(struct mmc_omap_host *host)
+{
+	unsigned long i;
+
+	OMAP_HSMMC_WRITE(host->base, HCTL,
+			 OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+	for (i = 0; i < loops_per_jiffy; i++) {
+		if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+			break;
+		cpu_relax();
+	}
+}
+
 /*
  * Switch MMC interface voltage ... only relevant for MMC1.
  *
@@ -485,9 +526,6 @@ static int omap_mmc_switch_opcond(struct
 	u32 reg_val = 0;
 	int ret;
 
-	if (host->id != OMAP_MMC1_DEVID)
-		return 0;
-
 	/* Disable the clocks */
 	clk_disable(host->fclk);
 	clk_disable(host->iclk);
@@ -532,9 +570,7 @@ static int omap_mmc_switch_opcond(struct
 		reg_val |= SDVS30;
 
 	OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-		OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+	set_sd_bus_power(host);
 
 	return 0;
 err:
@@ -551,7 +587,10 @@ static void mmc_omap_detect(struct work_
 						mmc_carddetect_work);
 	struct omap_mmc_slot_data *slot = &mmc_slot(host);
 
-	host->carddetect = slot->card_detect(slot->card_detect_irq);
+	if (mmc_slot(host).card_detect)
+		host->carddetect = slot->card_detect(slot->card_detect_irq);
+	else
+		host->carddetect = -ENOSYS;
 
 	sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
 	if (host->carddetect) {
@@ -574,6 +613,48 @@ static irqreturn_t omap_mmc_cd_handler(i
 	return IRQ_HANDLED;
 }
 
+static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host,
+				     struct mmc_data *data)
+{
+	int sync_dev;
+
+	if (data->flags & MMC_DATA_WRITE)
+		sync_dev = host->dma_line_tx;
+	else
+		sync_dev = host->dma_line_rx;
+	return sync_dev;
+}
+
+static void mmc_omap_config_dma_params(struct mmc_omap_host *host,
+				       struct mmc_data *data,
+				       struct scatterlist *sgl)
+{
+	int blksz, nblk, dma_ch;
+
+	dma_ch = host->dma_ch;
+	if (data->flags & MMC_DATA_WRITE) {
+		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+			sg_dma_address(sgl), 0, 0);
+	} else {
+		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+					(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+			sg_dma_address(sgl), 0, 0);
+	}
+
+	blksz = host->data->blksz;
+	nblk = sg_dma_len(sgl) / blksz;
+
+	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+			blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
+			mmc_omap_get_dma_sync_dev(host, data),
+			!(data->flags & MMC_DATA_WRITE));
+
+	omap_start_dma(dma_ch);
+}
+
 /*
  * DMA call back function
  */
@@ -587,48 +668,46 @@ static void mmc_omap_dma_cb(int lch, u16
 	if (host->dma_ch < 0)
 		return;
 
+	host->dma_sg_idx++;
+	if (host->dma_sg_idx < host->dma_len) {
+		/* Fire up the next transfer. */
+		mmc_omap_config_dma_params(host, host->data,
+					   host->data->sg + host->dma_sg_idx);
+		return;
+	}
+
 	omap_free_dma(host->dma_ch);
 	host->dma_ch = -1;
 	/*
 	 * DMA Callback: run in interrupt context.
-	 * mutex_unlock will through a kernel warning if used.
+	 * mutex_unlock will throw a kernel warning if used.
 	 */
 	up(&host->sem);
 }
 
 /*
- * Configure dma src and destination parameters
- */
-static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
-				struct mmc_data *data)
-{
-	if (sync_dir == 0) {
-		omap_set_dma_dest_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_src_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(&data->sg[0]), 0, 0);
-	} else {
-		omap_set_dma_src_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_dest_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(&data->sg[0]), 0, 0);
-	}
-	return 0;
-}
-/*
  * Routine to configure and start DMA for the MMC card
  */
 static int
 mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
 {
-	int sync_dev, sync_dir = 0;
-	int dma_ch = 0, ret = 0, err = 1;
+	int dma_ch = 0, ret = 0, err = 1, i;
 	struct mmc_data *data = req->data;
 
+	/* Sanity check: all the SG entries must be aligned by block size. */
+	for (i = 0; i < host->dma_len; i++) {
+		struct scatterlist *sgl;
+
+		sgl = data->sg + i;
+		if (sgl->length % data->blksz)
+			return -EINVAL;
+	}
+	if ((data->blksz % 4) != 0)
+		/* REVISIT: The MMC buffer increments only when MSB is written.
+		 * Return error for blksz which is non multiple of four.
+		 */
+		return -EINVAL;
+
 	/*
 	 * If for some reason the DMA transfer is still active,
 	 * we wait for timeout period and free the dma
@@ -647,49 +726,22 @@ mmc_omap_start_dma_transfer(struct mmc_o
 			return err;
 	}
 
-	if (!(data->flags & MMC_DATA_WRITE)) {
-		host->dma_dir = DMA_FROM_DEVICE;
-		if (host->id == OMAP_MMC1_DEVID)
-			sync_dev = OMAP24XX_DMA_MMC1_RX;
-		else
-			sync_dev = OMAP24XX_DMA_MMC2_RX;
-	} else {
-		host->dma_dir = DMA_TO_DEVICE;
-		if (host->id == OMAP_MMC1_DEVID)
-			sync_dev = OMAP24XX_DMA_MMC1_TX;
-		else
-			sync_dev = OMAP24XX_DMA_MMC2_TX;
-	}
-
-	ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
-			host, &dma_ch);
+	ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD",
+			       mmc_omap_dma_cb,host, &dma_ch);
 	if (ret != 0) {
-		dev_dbg(mmc_dev(host->mmc),
+		dev_err(mmc_dev(host->mmc),
 			"%s: omap_request_dma() failed with %d\n",
 			mmc_hostname(host->mmc), ret);
 		return ret;
 	}
 
 	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
-			data->sg_len, host->dma_dir);
+			data->sg_len, mmc_omap_get_dma_dir(host, data));
 	host->dma_ch = dma_ch;
+	host->dma_sg_idx = 0;
 
-	if (!(data->flags & MMC_DATA_WRITE))
-		mmc_omap_config_dma_param(1, host, data);
-	else
-		mmc_omap_config_dma_param(0, host, data);
-
-	if ((data->blksz % 4) == 0)
-		omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
-			(data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
-			sync_dev, sync_dir);
-	else
-		/* REVISIT: The MMC buffer increments only when MSB is written.
-		 * Return error for blksz which is non multiple of four.
-		 */
-		return -EINVAL;
+	mmc_omap_config_dma_params(host, data, data->sg);
 
-	omap_start_dma(dma_ch);
 	return 0;
 }
 
@@ -739,7 +791,6 @@ mmc_omap_prepare_data(struct mmc_omap_ho
 	host->data = req->data;
 
 	if (req->data == NULL) {
-		host->datadir = OMAP_MMC_DATADIR_NONE;
 		OMAP_HSMMC_WRITE(host->base, BLK, 0);
 		return 0;
 	}
@@ -748,9 +799,6 @@ mmc_omap_prepare_data(struct mmc_omap_ho
 					| (req->data->blocks << 16));
 	set_data_timeout(host, req);
 
-	host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
-			OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
-
 	if (host->use_dma) {
 		ret = mmc_omap_start_dma_transfer(host, req);
 		if (ret != 0) {
@@ -782,36 +830,29 @@ static void omap_mmc_set_ios(struct mmc_
 	u16 dsor = 0;
 	unsigned long regval;
 	unsigned long timeout;
+	u32 con;
 
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF:
 		mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
-		/*
-		 * Reset interface voltage to 3V if it's 1.8V now;
-		 * only relevant on MMC-1, the others always use 1.8V.
-		 *
-		 * REVISIT: If we are able to detect cards after unplugging
-		 * a 1.8V card, this code should not be needed.
-		 */
-		if (host->id != OMAP_MMC1_DEVID)
-			break;
-		if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
-			int vdd = fls(host->mmc->ocr_avail) - 1;
-			if (omap_mmc_switch_opcond(host, vdd) != 0)
-				host->mmc->ios.vdd = vdd;
-		}
 		break;
 	case MMC_POWER_UP:
 		mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
 		break;
 	}
 
+	con = OMAP_HSMMC_READ(host->base, CON);
 	switch (mmc->ios.bus_width) {
+	case MMC_BUS_WIDTH_8:
+		OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+		break;
 	case MMC_BUS_WIDTH_4:
+		OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
 		OMAP_HSMMC_WRITE(host->base, HCTL,
 			OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
 		break;
 	case MMC_BUS_WIDTH_1:
+		OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
 		OMAP_HSMMC_WRITE(host->base, HCTL,
 			OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
 		break;
@@ -891,6 +932,33 @@ static int omap_hsmmc_get_ro(struct mmc_
 	return pdata->slots[0].get_ro(host->dev, 0);
 }
 
+static void omap_hsmmc_init(struct mmc_omap_host *host)
+{
+	u32 hctl, capa, value;
+
+	/* Only MMC1 supports 3.0V */
+	if (host->id == OMAP_MMC1_DEVID) {
+		hctl = SDVS30;
+		capa = VS30 | VS18;
+	} else {
+		hctl = SDVS18;
+		capa = VS18;
+	}
+
+	value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+	OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+
+	value = OMAP_HSMMC_READ(host->base, CAPA);
+	OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
+
+	/* Set the controller to AUTO IDLE mode */
+	value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
+	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+
+	/* Set SD bus power bit */
+	set_sd_bus_power(host);
+}
+
 static struct mmc_host_ops mmc_omap_ops = {
 	.request = omap_mmc_request,
 	.set_ios = omap_mmc_set_ios,
@@ -906,7 +974,6 @@ static int __init omap_mmc_probe(struct
 	struct mmc_omap_host *host = NULL;
 	struct resource *res;
 	int ret = 0, irq;
-	u32 hctl, capa;
 
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -956,13 +1023,13 @@ static int __init omap_mmc_probe(struct
 
 	sema_init(&host->sem, 1);
 
-	host->iclk = clk_get(&pdev->dev, "mmchs_ick");
+	host->iclk = clk_get(&pdev->dev, "ick");
 	if (IS_ERR(host->iclk)) {
 		ret = PTR_ERR(host->iclk);
 		host->iclk = NULL;
 		goto err1;
 	}
-	host->fclk = clk_get(&pdev->dev, "mmchs_fck");
+	host->fclk = clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
 		ret = PTR_ERR(host->fclk);
 		host->fclk = NULL;
@@ -996,10 +1063,11 @@ static int __init omap_mmc_probe(struct
 		else
 			host->dbclk_enabled = 1;
 
-#ifdef CONFIG_MMC_BLOCK_BOUNCE
-	mmc->max_phys_segs = 1;
-	mmc->max_hw_segs = 1;
-#endif
+	/* Since we do only SG emulation, we can have as many segs
+	 * as we want. */
+	mmc->max_phys_segs = 1024;
+	mmc->max_hw_segs = 1024;
+
 	mmc->max_blk_size = 512;       /* Block Length at max can be 1024 */
 	mmc->max_blk_count = 0xFFFF;    /* No. of Blocks is 16 bits */
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1008,31 +1076,31 @@ static int __init omap_mmc_probe(struct
 	mmc->ocr_avail = mmc_slot(host).ocr_mask;
 	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
 
-	if (pdata->slots[host->slot_id].wires >= 4)
+	if (pdata->slots[host->slot_id].wires >= 8)
+		mmc->caps |= MMC_CAP_8_BIT_DATA;
+	else if (pdata->slots[host->slot_id].wires >= 4)
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-	/* Only MMC1 supports 3.0V */
-	if (host->id == OMAP_MMC1_DEVID) {
-		hctl = SDVS30;
-		capa = VS30 | VS18;
-	} else {
-		hctl = SDVS18;
-		capa = VS18;
-	}
-
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-			OMAP_HSMMC_READ(host->base, HCTL) | hctl);
-
-	OMAP_HSMMC_WRITE(host->base, CAPA,
-			OMAP_HSMMC_READ(host->base, CAPA) | capa);
-
-	/* Set the controller to AUTO IDLE mode */
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
-			OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+	omap_hsmmc_init(host);
 
-	/* Set SD bus power bit */
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-			OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+	/* Select DMA lines */
+	switch (host->id) {
+	case OMAP_MMC1_DEVID:
+		host->dma_line_tx = OMAP24XX_DMA_MMC1_TX;
+		host->dma_line_rx = OMAP24XX_DMA_MMC1_RX;
+		break;
+	case OMAP_MMC2_DEVID:
+		host->dma_line_tx = OMAP24XX_DMA_MMC2_TX;
+		host->dma_line_rx = OMAP24XX_DMA_MMC2_RX;
+		break;
+	case OMAP_MMC3_DEVID:
+		host->dma_line_tx = OMAP34XX_DMA_MMC3_TX;
+		host->dma_line_rx = OMAP34XX_DMA_MMC3_RX;
+		break;
+	default:
+		dev_err(mmc_dev(host->mmc), "Invalid MMC id\n");
+		goto err_irq;
+	}
 
 	/* Request IRQ for MMC operations */
 	ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
@@ -1051,7 +1119,7 @@ static int __init omap_mmc_probe(struct
 	}
 
 	/* Request IRQ for card detect */
-	if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+	if ((mmc_slot(host).card_detect_irq)) {
 		ret = request_irq(mmc_slot(host).card_detect_irq,
 				  omap_mmc_cd_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -1074,8 +1142,8 @@ static int __init omap_mmc_probe(struct
 		if (ret < 0)
 			goto err_slot_name;
 	}
-	if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
-			host->pdata->slots[host->slot_id].get_cover_state) {
+	if (mmc_slot(host).card_detect_irq &&
+	    host->pdata->slots[host->slot_id].get_cover_state) {
 		ret = device_create_file(&mmc->class_dev,
 					&dev_attr_cover_switch);
 		if (ret < 0)
@@ -1173,20 +1241,8 @@ static int omap_mmc_suspend(struct platf
 						" level suspend\n");
 			}
 
-			if (host->id == OMAP_MMC1_DEVID
-					&& !(OMAP_HSMMC_READ(host->base, HCTL)
-							& SDVSDET)) {
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					& SDVSCLR);
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					| SDVS30);
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					| SDBP);
-			}
-
+			OMAP_HSMMC_WRITE(host->base, HCTL,
+					 OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
 			clk_disable(host->fclk);
 			clk_disable(host->iclk);
 			clk_disable(host->dbclk);
@@ -1222,6 +1278,8 @@ static int omap_mmc_resume(struct platfo
 			dev_dbg(mmc_dev(host->mmc),
 					"Enabling debounce clk failed\n");
 
+		omap_hsmmc_init(host);
+
 		if (host->pdata->resume) {
 			ret = host->pdata->resume(&pdev->dev, host->slot_id);
 			if (ret)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/pxamci.c linux-libre-2.6.30-gnu1/drivers/mmc/host/pxamci.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/pxamci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/pxamci.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,9 +30,8 @@
 
 #include <asm/sizes.h>
 
-#include <mach/dma.h>
 #include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
 #include <mach/mmc.h>
 
 #include "pxamci.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci.c linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_
 	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
 
 	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
-		readl(host->ioaddr + SDHCI_DMA_ADDRESS),
-		readw(host->ioaddr + SDHCI_HOST_VERSION));
+		sdhci_readl(host, SDHCI_DMA_ADDRESS),
+		sdhci_readw(host, SDHCI_HOST_VERSION));
 	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
-		readw(host->ioaddr + SDHCI_BLOCK_SIZE),
-		readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+		sdhci_readw(host, SDHCI_BLOCK_SIZE),
+		sdhci_readw(host, SDHCI_BLOCK_COUNT));
 	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_ARGUMENT),
-		readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+		sdhci_readl(host, SDHCI_ARGUMENT),
+		sdhci_readw(host, SDHCI_TRANSFER_MODE));
 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_PRESENT_STATE),
-		readb(host->ioaddr + SDHCI_HOST_CONTROL));
+		sdhci_readl(host, SDHCI_PRESENT_STATE),
+		sdhci_readb(host, SDHCI_HOST_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
-		readb(host->ioaddr + SDHCI_POWER_CONTROL),
-		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+		sdhci_readb(host, SDHCI_POWER_CONTROL),
+		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
-		readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
-		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
+		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
-		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
-		readl(host->ioaddr + SDHCI_INT_STATUS));
+		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
+		sdhci_readl(host, SDHCI_INT_STATUS));
 	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_INT_ENABLE),
-		readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+		sdhci_readl(host, SDHCI_INT_ENABLE),
+		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
-		readw(host->ioaddr + SDHCI_ACMD12_ERR),
-		readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+		sdhci_readw(host, SDHCI_ACMD12_ERR),
+		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
 	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_CAPABILITIES),
-		readl(host->ioaddr + SDHCI_MAX_CURRENT));
+		sdhci_readl(host, SDHCI_CAPABILITIES),
+		sdhci_readl(host, SDHCI_MAX_CURRENT));
 
 	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
 }
@@ -87,17 +87,65 @@ static void sdhci_dumpregs(struct sdhci_
  *                                                                           *
 \*****************************************************************************/
 
+static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+	u32 ier;
+
+	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+	ier &= ~clear;
+	ier |= set;
+	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqs(host, 0, irqs);
+}
+
+static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqs(host, irqs, 0);
+}
+
+static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
+{
+	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		return;
+
+	if (enable)
+		sdhci_unmask_irqs(host, irqs);
+	else
+		sdhci_mask_irqs(host, irqs);
+}
+
+static void sdhci_enable_card_detection(struct sdhci_host *host)
+{
+	sdhci_set_card_detection(host, true);
+}
+
+static void sdhci_disable_card_detection(struct sdhci_host *host)
+{
+	sdhci_set_card_detection(host, false);
+}
+
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
+	u32 uninitialized_var(ier);
 
 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
-		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
 			SDHCI_CARD_PRESENT))
 			return;
 	}
 
-	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+
+	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
 	if (mask & SDHCI_RESET_ALL)
 		host->clock = 0;
@@ -106,7 +154,7 @@ static void sdhci_reset(struct sdhci_hos
 	timeout = 100;
 
 	/* hw clears the bit when it's done */
-	while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
 				mmc_hostname(host->mmc), (int)mask);
@@ -116,42 +164,44 @@ static void sdhci_reset(struct sdhci_hos
 		timeout--;
 		mdelay(1);
 	}
+
+	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
 }
 
 static void sdhci_init(struct sdhci_host *host)
 {
-	u32 intmask;
-
 	sdhci_reset(host, SDHCI_RESET_ALL);
 
-	intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
+		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
 		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
 		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
-		SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
-		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
-		SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
-		SDHCI_INT_ADMA_ERROR;
+		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+}
 
-	writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
-	writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+static void sdhci_reinit(struct sdhci_host *host)
+{
+	sdhci_init(host);
+	sdhci_enable_card_detection(host);
 }
 
 static void sdhci_activate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl |= SDHCI_CTRL_LED;
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
 static void sdhci_deactivate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl &= ~SDHCI_CTRL_LED;
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +255,7 @@ static void sdhci_read_block_pio(struct
 
 		while (len) {
 			if (chunk == 0) {
-				scratch = readl(host->ioaddr + SDHCI_BUFFER);
+				scratch = sdhci_readl(host, SDHCI_BUFFER);
 				chunk = 4;
 			}
 
@@ -257,7 +307,7 @@ static void sdhci_write_block_pio(struct
 			len--;
 
 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
-				writel(scratch, host->ioaddr + SDHCI_BUFFER);
+				sdhci_writel(host, scratch, SDHCI_BUFFER);
 				chunk = 0;
 				scratch = 0;
 			}
@@ -292,7 +342,10 @@ static void sdhci_transfer_pio(struct sd
 		(host->data->blocks == 1))
 		mask = ~0;
 
-	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
+			udelay(100);
+
 		if (host->data->flags & MMC_DATA_READ)
 			sdhci_read_block_pio(host);
 		else
@@ -561,6 +614,17 @@ static u8 sdhci_calc_timeout(struct sdhc
 	return count;
 }
 
+static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+{
+	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+	if (host->flags & SDHCI_REQ_USE_DMA)
+		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+	else
+		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+}
+
 static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
 {
 	u8 count;
@@ -581,7 +645,7 @@ static void sdhci_prepare_data(struct sd
 	host->data_early = 0;
 
 	count = sdhci_calc_timeout(host, data);
-	writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
 
 	if (host->flags & SDHCI_USE_DMA)
 		host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +725,8 @@ static void sdhci_prepare_data(struct sd
 				WARN_ON(1);
 				host->flags &= ~SDHCI_REQ_USE_DMA;
 			} else {
-				writel(host->adma_addr,
-					host->ioaddr + SDHCI_ADMA_ADDRESS);
+				sdhci_writel(host, host->adma_addr,
+					SDHCI_ADMA_ADDRESS);
 			}
 		} else {
 			int sg_cnt;
@@ -681,8 +745,8 @@ static void sdhci_prepare_data(struct sd
 				host->flags &= ~SDHCI_REQ_USE_DMA;
 			} else {
 				WARN_ON(sg_cnt != 1);
-				writel(sg_dma_address(data->sg),
-					host->ioaddr + SDHCI_DMA_ADDRESS);
+				sdhci_writel(host, sg_dma_address(data->sg),
+					SDHCI_DMA_ADDRESS);
 			}
 		}
 	}
@@ -693,14 +757,14 @@ static void sdhci_prepare_data(struct sd
 	 * is ADMA.
 	 */
 	if (host->version >= SDHCI_SPEC_200) {
-		ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
 			(host->flags & SDHCI_USE_ADMA))
 			ctrl |= SDHCI_CTRL_ADMA32;
 		else
 			ctrl |= SDHCI_CTRL_SDMA;
-		writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 	}
 
 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -709,10 +773,11 @@ static void sdhci_prepare_data(struct sd
 		host->blocks = data->blocks;
 	}
 
+	sdhci_set_transfer_irqs(host);
+
 	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
-	writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
-		host->ioaddr + SDHCI_BLOCK_SIZE);
-	writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
 }
 
 static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +798,7 @@ static void sdhci_set_transfer_mode(stru
 	if (host->flags & SDHCI_REQ_USE_DMA)
 		mode |= SDHCI_TRNS_DMA;
 
-	writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
 }
 
 static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +867,7 @@ static void sdhci_send_command(struct sd
 	if (host->mrq->data && (cmd == host->mrq->data->stop))
 		mask &= ~SDHCI_DATA_INHIBIT;
 
-	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Controller never released "
 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +886,7 @@ static void sdhci_send_command(struct sd
 
 	sdhci_prepare_data(host, cmd->data);
 
-	writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
 
 	sdhci_set_transfer_mode(host, cmd->data);
 
@@ -849,8 +914,7 @@ static void sdhci_send_command(struct sd
 	if (cmd->data)
 		flags |= SDHCI_CMD_DATA;
 
-	writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
-		host->ioaddr + SDHCI_COMMAND);
+	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
 }
 
 static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +927,15 @@ static void sdhci_finish_command(struct
 		if (host->cmd->flags & MMC_RSP_136) {
 			/* CRC is stripped so we need to do some shifting. */
 			for (i = 0;i < 4;i++) {
-				host->cmd->resp[i] = readl(host->ioaddr +
+				host->cmd->resp[i] = sdhci_readl(host,
 					SDHCI_RESPONSE + (3-i)*4) << 8;
 				if (i != 3)
 					host->cmd->resp[i] |=
-						readb(host->ioaddr +
+						sdhci_readb(host,
 						SDHCI_RESPONSE + (3-i)*4-1);
 			}
 		} else {
-			host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+			host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
 		}
 	}
 
@@ -895,7 +959,13 @@ static void sdhci_set_clock(struct sdhci
 	if (clock == host->clock)
 		return;
 
-	writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	if (host->ops->set_clock) {
+		host->ops->set_clock(host, clock);
+		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+			return;
+	}
+
+	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
 		goto out;
@@ -908,11 +978,11 @@ static void sdhci_set_clock(struct sdhci
 
 	clk = div << SDHCI_DIVIDER_SHIFT;
 	clk |= SDHCI_CLOCK_INT_EN;
-	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
 	/* Wait max 10 ms */
 	timeout = 10;
-	while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 		& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +995,7 @@ static void sdhci_set_clock(struct sdhci
 	}
 
 	clk |= SDHCI_CLOCK_CARD_EN;
-	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
 out:
 	host->clock = clock;
@@ -939,7 +1009,7 @@ static void sdhci_set_power(struct sdhci
 		return;
 
 	if (power == (unsigned short)-1) {
-		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 		goto out;
 	}
 
@@ -948,7 +1018,7 @@ static void sdhci_set_power(struct sdhci
 	 * a new value. Some controllers don't seem to like this though.
 	 */
 	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
-		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 
 	pwr = SDHCI_POWER_ON;
 
@@ -973,10 +1043,9 @@ static void sdhci_set_power(struct sdhci
 	 * and set turn on power at the same time, so set the voltage first.
 	 */
 	if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
-		writeb(pwr & ~SDHCI_POWER_ON,
-				host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
 
-	writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 
 out:
 	host->power = power;
@@ -991,6 +1060,7 @@ out:
 static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sdhci_host *host;
+	bool present;
 	unsigned long flags;
 
 	host = mmc_priv(mmc);
@@ -1005,8 +1075,14 @@ static void sdhci_request(struct mmc_hos
 
 	host->mrq = mrq;
 
-	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
-		|| (host->flags & SDHCI_DEVICE_DEAD)) {
+	/* If polling, assume that the card is always present. */
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		present = true;
+	else
+		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+				SDHCI_CARD_PRESENT;
+
+	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	} else
@@ -1034,8 +1110,8 @@ static void sdhci_set_ios(struct mmc_hos
 	 * Should clear out any weird states.
 	 */
 	if (ios->power_mode == MMC_POWER_OFF) {
-		writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-		sdhci_init(host);
+		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+		sdhci_reinit(host);
 	}
 
 	sdhci_set_clock(host, ios->clock);
@@ -1045,7 +1121,7 @@ static void sdhci_set_ios(struct mmc_hos
 	else
 		sdhci_set_power(host, ios->vdd);
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
 	if (ios->bus_width == MMC_BUS_WIDTH_4)
 		ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1133,7 @@ static void sdhci_set_ios(struct mmc_hos
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 	/*
 	 * Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,10 +1161,12 @@ static int sdhci_get_ro(struct mmc_host
 	if (host->flags & SDHCI_DEVICE_DEAD)
 		present = 0;
 	else
-		present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+		present = sdhci_readl(host, SDHCI_PRESENT_STATE);
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
+	if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
+		return !!(present & SDHCI_WRITE_PROTECT);
 	return !(present & SDHCI_WRITE_PROTECT);
 }
 
@@ -1096,7 +1174,6 @@ static void sdhci_enable_sdio_irq(struct
 {
 	struct sdhci_host *host;
 	unsigned long flags;
-	u32 ier;
 
 	host = mmc_priv(mmc);
 
@@ -1105,15 +1182,10 @@ static void sdhci_enable_sdio_irq(struct
 	if (host->flags & SDHCI_DEVICE_DEAD)
 		goto out;
 
-	ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
-
-	ier &= ~SDHCI_INT_CARD_INT;
 	if (enable)
-		ier |= SDHCI_INT_CARD_INT;
-
-	writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
-	writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
+		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+	else
+		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
 out:
 	mmiowb();
 
@@ -1142,7 +1214,7 @@ static void sdhci_tasklet_card(unsigned
 
 	spin_lock_irqsave(&host->lock, flags);
 
-	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+	if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
 		if (host->mrq) {
 			printk(KERN_ERR "%s: Card removed during transfer!\n",
 				mmc_hostname(host->mmc));
@@ -1346,8 +1418,8 @@ static void sdhci_data_irq(struct sdhci_
 		 * we need to at least restart the transfer.
 		 */
 		if (intmask & SDHCI_INT_DMA_END)
-			writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
-				host->ioaddr + SDHCI_DMA_ADDRESS);
+			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
+				SDHCI_DMA_ADDRESS);
 
 		if (intmask & SDHCI_INT_DATA_END) {
 			if (host->cmd) {
@@ -1373,7 +1445,7 @@ static irqreturn_t sdhci_irq(int irq, vo
 
 	spin_lock(&host->lock);
 
-	intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
 
 	if (!intmask || intmask == 0xffffffff) {
 		result = IRQ_NONE;
@@ -1384,22 +1456,22 @@ static irqreturn_t sdhci_irq(int irq, vo
 		mmc_hostname(host->mmc), intmask);
 
 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
-		writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
+			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
 		tasklet_schedule(&host->card_tasklet);
 	}
 
 	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
 
 	if (intmask & SDHCI_INT_CMD_MASK) {
-		writel(intmask & SDHCI_INT_CMD_MASK,
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
+			SDHCI_INT_STATUS);
 		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
 	}
 
 	if (intmask & SDHCI_INT_DATA_MASK) {
-		writel(intmask & SDHCI_INT_DATA_MASK,
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
+			SDHCI_INT_STATUS);
 		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
 	}
 
@@ -1410,7 +1482,7 @@ static irqreturn_t sdhci_irq(int irq, vo
 	if (intmask & SDHCI_INT_BUS_POWER) {
 		printk(KERN_ERR "%s: Card is consuming too much power!\n",
 			mmc_hostname(host->mmc));
-		writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
 	}
 
 	intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1497,7 @@ static irqreturn_t sdhci_irq(int irq, vo
 			mmc_hostname(host->mmc), intmask);
 		sdhci_dumpregs(host);
 
-		writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
 	}
 
 	result = IRQ_HANDLED;
@@ -1455,6 +1527,8 @@ int sdhci_suspend_host(struct sdhci_host
 {
 	int ret;
 
+	sdhci_disable_card_detection(host);
+
 	ret = mmc_suspend_host(host->mmc, state);
 	if (ret)
 		return ret;
@@ -1487,6 +1561,8 @@ int sdhci_resume_host(struct sdhci_host
 	if (ret)
 		return ret;
 
+	sdhci_enable_card_detection(host);
+
 	return 0;
 }
 
@@ -1537,7 +1613,7 @@ int sdhci_add_host(struct sdhci_host *ho
 
 	sdhci_reset(host, SDHCI_RESET_ALL);
 
-	host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
 				>> SDHCI_SPEC_VER_SHIFT;
 	if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1622,7 @@ int sdhci_add_host(struct sdhci_host *ho
 			host->version);
 	}
 
-	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_DMA;
@@ -1614,19 +1690,27 @@ int sdhci_add_host(struct sdhci_host *ho
 
 	host->max_clk =
 		(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+	host->max_clk *= 1000000;
 	if (host->max_clk == 0) {
-		printk(KERN_ERR "%s: Hardware doesn't specify base clock "
-			"frequency.\n", mmc_hostname(mmc));
-		return -ENODEV;
+		if (!host->ops->get_max_clock) {
+			printk(KERN_ERR
+			       "%s: Hardware doesn't specify base clock "
+			       "frequency.\n", mmc_hostname(mmc));
+			return -ENODEV;
+		}
+		host->max_clk = host->ops->get_max_clock(host);
 	}
-	host->max_clk *= 1000000;
 
 	host->timeout_clk =
 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
 	if (host->timeout_clk == 0) {
-		printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
-			"frequency.\n", mmc_hostname(mmc));
-		return -ENODEV;
+		if (!host->ops->get_timeout_clock) {
+			printk(KERN_ERR
+			       "%s: Hardware doesn't specify timeout clock "
+			       "frequency.\n", mmc_hostname(mmc));
+			return -ENODEV;
+		}
+		host->timeout_clk = host->ops->get_timeout_clock(host);
 	}
 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
 		host->timeout_clk *= 1000;
@@ -1642,6 +1726,9 @@ int sdhci_add_host(struct sdhci_host *ho
 	if (caps & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
 
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
 	mmc->ocr_avail = 0;
 	if (caps & SDHCI_CAN_VDD_330)
 		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1690,13 +1777,19 @@ int sdhci_add_host(struct sdhci_host *ho
 	 * Maximum block size. This varies from controller to controller and
 	 * is specified in the capabilities register.
 	 */
-	mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
-	if (mmc->max_blk_size >= 3) {
-		printk(KERN_WARNING "%s: Invalid maximum block size, "
-			"assuming 512 bytes\n", mmc_hostname(mmc));
-		mmc->max_blk_size = 512;
-	} else
-		mmc->max_blk_size = 512 << mmc->max_blk_size;
+	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
+		mmc->max_blk_size = 2;
+	} else {
+		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+				SDHCI_MAX_BLOCK_SHIFT;
+		if (mmc->max_blk_size >= 3) {
+			printk(KERN_WARNING "%s: Invalid maximum block size, "
+				"assuming 512 bytes\n", mmc_hostname(mmc));
+			mmc->max_blk_size = 0;
+		}
+	}
+
+	mmc->max_blk_size = 512 << mmc->max_blk_size;
 
 	/*
 	 * Maximum block count.
@@ -1746,6 +1839,8 @@ int sdhci_add_host(struct sdhci_host *ho
 		(host->flags & SDHCI_USE_ADMA)?"A":"",
 		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
 
+	sdhci_enable_card_detection(host);
+
 	return 0;
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -1782,6 +1877,8 @@ void sdhci_remove_host(struct sdhci_host
 		spin_unlock_irqrestore(&host->lock, flags);
 	}
 
+	sdhci_disable_card_detection(host);
+
 	mmc_remove_host(host->mmc);
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -1838,7 +1935,7 @@ module_exit(sdhci_drv_exit);
 
 module_param(debug_quirks, uint, 0444);
 
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci.h linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci.h
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci.h	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,9 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/io.h>
 
 /*
  * Controller registers
@@ -122,7 +125,8 @@
 #define  SDHCI_INT_DATA_MASK	(SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
 		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
 		SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
-		SDHCI_INT_DATA_END_BIT)
+		SDHCI_INT_DATA_END_BIT | SDHCI_ADMA_ERROR)
+#define SDHCI_INT_ALL_MASK	((unsigned int)-1)
 
 #define SDHCI_ACMD12_ERR	0x3C
 
@@ -210,6 +214,18 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_SMALL_PIO			(1<<13)
 /* Controller does not provide transfer-complete interrupt when not busy */
 #define SDHCI_QUIRK_NO_BUSY_IRQ				(1<<14)
+/* Controller has unreliable card detection */
+#define SDHCI_QUIRK_BROKEN_CARD_DETECTION		(1<<15)
+/* Controller reports inverted write-protect state */
+#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT		(1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
+/* Controller does not like fast PIO transfers */
+#define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
+/* Controller losing signal/interrupt enable states after reset */
+#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET		(1<<19)
+/* Controller has to be forced to use block size of 2048 bytes */
+#define SDHCI_QUIRK_FORCE_BLK_SZ_2048			(1<<20)
 
 	int			irq;		/* Device IRQ */
 	void __iomem *		ioaddr;		/* Mapped address */
@@ -267,9 +283,105 @@ struct sdhci_host {
 
 
 struct sdhci_ops {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+	u32		(*readl)(struct sdhci_host *host, int reg);
+	u16		(*readw)(struct sdhci_host *host, int reg);
+	u8		(*readb)(struct sdhci_host *host, int reg);
+	void		(*writel)(struct sdhci_host *host, u32 val, int reg);
+	void		(*writew)(struct sdhci_host *host, u16 val, int reg);
+	void		(*writeb)(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+	void	(*set_clock)(struct sdhci_host *host, unsigned int clock);
+
 	int		(*enable_dma)(struct sdhci_host *host);
+	unsigned int	(*get_max_clock)(struct sdhci_host *host);
+	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
 };
 
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	if (unlikely(host->ops->writel))
+		host->ops->writel(host, val, reg);
+	else
+		writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	if (unlikely(host->ops->writew))
+		host->ops->writew(host, val, reg);
+	else
+		writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	if (unlikely(host->ops->writeb))
+		host->ops->writeb(host, val, reg);
+	else
+		writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readl))
+		return host->ops->readl(host, reg);
+	else
+		return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readw))
+		return host->ops->readw(host, reg);
+	else
+		return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readb))
+		return host->ops->readb(host, reg);
+	else
+		return readb(host->ioaddr + reg);
+}
+
+#else
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+	return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+	return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+	return readb(host->ioaddr + reg);
+}
+
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
 
 extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
 	size_t priv_size);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci-of.c linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci-of.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci-of.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci-of.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,316 @@
+/*
+ * 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 "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
+
+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;
+
+	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	int div;
+	int pre_div = 2;
+
+	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+	if (clock == 0)
+		goto out;
+
+	if (host->max_clk / 16 > clock) {
+		for (; pre_div < 256; pre_div *= 2) {
+			if (host->max_clk / pre_div < clock * 16)
+				break;
+		}
+	}
+
+	for (div = 1; div <= 16; div++) {
+		if (host->max_clk / (div * pre_div) <= clock)
+			break;
+	}
+
+	pre_div >>= 1;
+
+	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_timeout_clock(struct sdhci_host *host)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+
+	return of_host->clock / 1000;
+}
+
+static struct sdhci_of_data sdhci_esdhc = {
+	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+		  SDHCI_QUIRK_NO_BUSY_IRQ |
+		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
+		  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_timeout_clock = esdhc_get_timeout_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 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 (!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;
+	}
+
+	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.29-gnu1/drivers/mmc/host/sdhci-pci.c linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci-pci.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/sdhci-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/sdhci-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -380,7 +380,7 @@ static int sdhci_pci_enable_dma(struct s
 			"doesn't fully claim to support it.\n");
 	}
 
-	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
 
@@ -522,8 +522,8 @@ static struct sdhci_pci_slot * __devinit
 
 	host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot));
 	if (IS_ERR(host)) {
-		ret = PTR_ERR(host);
-		goto unmap;
+		dev_err(&pdev->dev, "cannot allocate host\n");
+		return ERR_PTR(PTR_ERR(host));
 	}
 
 	slot = sdhci_priv(host);
@@ -541,7 +541,7 @@ static struct sdhci_pci_slot * __devinit
 	ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
 	if (ret) {
 		dev_err(&pdev->dev, "cannot request region\n");
-		return ERR_PTR(ret);
+		goto free;
 	}
 
 	addr = pci_resource_start(pdev, bar);
@@ -572,6 +572,8 @@ unmap:
 
 release:
 	pci_release_region(pdev, bar);
+
+free:
 	sdhci_free_host(host);
 
 	return ERR_PTR(ret);
@@ -729,6 +731,6 @@ static void __exit sdhci_drv_exit(void)
 module_init(sdhci_drv_init);
 module_exit(sdhci_drv_exit);
 
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/tmio_mmc.c linux-libre-2.6.30-gnu1/drivers/mmc/host/tmio_mmc.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/tmio_mmc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/tmio_mmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -568,11 +568,11 @@ static int __devinit tmio_mmc_probe(stru
 	host->mmc = mmc;
 	platform_set_drvdata(dev, mmc);
 
-	host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
+	host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
 	if (!host->ctl)
 		goto host_free;
 
-	host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
+	host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
 	if (!host->cnf)
 		goto unmap_ctl;
 
@@ -650,10 +650,10 @@ static int __devexit tmio_mmc_remove(str
 	if (mmc) {
 		struct tmio_mmc_host *host = mmc_priv(mmc);
 		mmc_remove_host(mmc);
-		mmc_free_host(mmc);
 		free_irq(host->irq, host);
 		iounmap(host->ctl);
 		iounmap(host->cnf);
+		mmc_free_host(mmc);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/tmio_mmc.h linux-libre-2.6.30-gnu1/drivers/mmc/host/tmio_mmc.h
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/tmio_mmc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/tmio_mmc.h	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,9 @@
  * published by the Free Software Foundation.
  *
  */
+
+#include <linux/highmem.h>
+
 #define CNF_CMD     0x04
 #define CNF_CTL_BASE   0x10
 #define CNF_INT_PIN  0x3d
diff -druNp linux-libre-2.6.29-gnu1/drivers/mmc/host/wbsd.c linux-libre-2.6.30-gnu1/drivers/mmc/host/wbsd.c
--- linux-libre-2.6.29-gnu1/drivers/mmc/host/wbsd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mmc/host/wbsd.c	2009-06-09 23:05:27.000000000 -0400
@@ -2036,7 +2036,7 @@ module_param_named(irq, param_irq, uint,
 module_param_named(dma, param_dma, int, 0444);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
+MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
 
 #ifdef CONFIG_PNP
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/ar7part.c linux-libre-2.6.30-gnu1/drivers/mtd/ar7part.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/ar7part.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/ar7part.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,8 +44,6 @@ struct ar7_bin_rec {
 	unsigned int address;
 };
 
-static struct mtd_partition ar7_parts[AR7_PARTS];
-
 static int create_mtd_partitions(struct mtd_info *master,
 				 struct mtd_partition **pparts,
 				 unsigned long origin)
@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct
 	unsigned int root_offset = ROOT_OFFSET;
 
 	int retries = 10;
+	struct mtd_partition *ar7_parts;
 
+	ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
+	if (!ar7_parts)
+		return -ENOMEM;
 	ar7_parts[0].name = "loader";
 	ar7_parts[0].offset = 0;
 	ar7_parts[0].size = master->erasesize;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c linux-libre-2.6.30-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/chips/cfi_cmdset_0001.c	2009-06-09 23:05:27.000000000 -0400
@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_oper
 			remove_wait_queue(&chip->wq, &wait);
 			spin_lock(chip->mutex);
 		}
-		if (chip->erase_suspended || chip->write_suspended)  {
-			/* Suspend has occured while sleep: reset timeout */
+		if (chip->erase_suspended && chip_state == FL_ERASING)  {
+			/* Erase suspend occured while sleep: reset timeout */
 			timeo = reset_timeo;
 			chip->erase_suspended = 0;
+		}
+		if (chip->write_suspended && chip_state == FL_WRITING)  {
+			/* Write suspend occured while sleep: reset timeout */
+			timeo = reset_timeo;
 			chip->write_suspended = 0;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c linux-libre-2.6.30-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/chips/cfi_cmdset_0002.c	2009-06-09 23:05:27.000000000 -0400
@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(stru
 	}
 }
 
+static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	if (cfi->cfiq->BufWriteTimeoutTyp) {
+		pr_warning("Don't use write buffer on ST flash M29W128G\n");
+		cfi->cfiq->BufWriteTimeoutTyp = 0;
+	}
+}
+
 static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
 #ifdef AMD_BOOTLOC_BUG
@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[
 	{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
 	{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
 	{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+	{ CFI_MFR_ST,  0x227E, fixup_M29W128G_write_buffer, NULL, },
 #if !FORCE_WORD_WRITE
 	{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/chips/jedec_probe.c linux-libre-2.6.30-gnu1/drivers/mtd/chips/jedec_probe.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/chips/jedec_probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/chips/jedec_probe.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,6 +159,7 @@
 #define SST39LF800	0x2781
 #define SST39LF160	0x2782
 #define SST39VF1601	0x234b
+#define SST39VF3201	0x235b
 #define SST39LF512	0x00D4
 #define SST39LF010	0x00D5
 #define SST39LF020	0x00D6
@@ -1489,6 +1490,21 @@ static const struct amd_flash_info jedec
 			ERASEINFO(0x1000,256),
 			ERASEINFO(0x1000,256)
 		}
+	}, {
+		.mfr_id		= MANUFACTURER_SST,     /* should be CFI */
+		.dev_id		= SST39VF3201,
+		.name		= "SST 39VF3201",
+		.devtypes	= CFI_DEVICETYPE_X16,
+		.uaddr		= MTD_UADDR_0xAAAA_0x5555,
+		.dev_size	= SIZE_4MiB,
+		.cmd_set	= P_ID_AMD_STD,
+		.nr_regions	= 4,
+		.regions	= {
+			ERASEINFO(0x1000,256),
+			ERASEINFO(0x1000,256),
+			ERASEINFO(0x1000,256),
+			ERASEINFO(0x1000,256)
+		}
 	}, {
 		.mfr_id		= MANUFACTURER_SST,
 		.dev_id		= SST36VF3203,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/chips/map_ram.c linux-libre-2.6.30-gnu1/drivers/mtd/chips/map_ram.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/chips/map_ram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/chips/map_ram.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,8 @@ static int mapram_write (struct mtd_info
 static int mapram_erase (struct mtd_info *, struct erase_info *);
 static void mapram_nop (struct mtd_info *);
 static struct mtd_info *map_ram_probe(struct map_info *map);
+static unsigned long mapram_unmapped_area(struct mtd_info *, unsigned long,
+					  unsigned long, unsigned long);
 
 
 static struct mtd_chip_driver mapram_chipdrv = {
@@ -64,6 +66,7 @@ static struct mtd_info *map_ram_probe(st
 	mtd->type = MTD_RAM;
 	mtd->size = map->size;
 	mtd->erase = mapram_erase;
+	mtd->get_unmapped_area = mapram_unmapped_area;
 	mtd->read = mapram_read;
 	mtd->write = mapram_write;
 	mtd->sync = mapram_nop;
@@ -79,6 +82,20 @@ static struct mtd_info *map_ram_probe(st
 }
 
 
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long mapram_unmapped_area(struct mtd_info *mtd,
+					  unsigned long len,
+					  unsigned long offset,
+					  unsigned long flags)
+{
+	struct map_info *map = mtd->priv;
+	return (unsigned long) map->virt + offset;
+}
+
 static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
 	struct map_info *map = mtd->priv;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/chips/map_rom.c linux-libre-2.6.30-gnu1/drivers/mtd/chips/map_rom.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/chips/map_rom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/chips/map_rom.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,8 @@ static int maprom_write (struct mtd_info
 static void maprom_nop (struct mtd_info *);
 static struct mtd_info *map_rom_probe(struct map_info *map);
 static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
+static unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long,
+					  unsigned long, unsigned long);
 
 static struct mtd_chip_driver maprom_chipdrv = {
 	.probe	= map_rom_probe,
@@ -40,6 +42,7 @@ static struct mtd_info *map_rom_probe(st
 	mtd->name = map->name;
 	mtd->type = MTD_ROM;
 	mtd->size = map->size;
+	mtd->get_unmapped_area = maprom_unmapped_area;
 	mtd->read = maprom_read;
 	mtd->write = maprom_write;
 	mtd->sync = maprom_nop;
@@ -53,6 +56,20 @@ static struct mtd_info *map_rom_probe(st
 }
 
 
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long maprom_unmapped_area(struct mtd_info *mtd,
+					  unsigned long len,
+					  unsigned long offset,
+					  unsigned long flags)
+{
+	struct map_info *map = mtd->priv;
+	return (unsigned long) map->virt + offset;
+}
+
 static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
 	struct map_info *map = mtd->priv;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/cmdlinepart.c linux-libre-2.6.30-gnu1/drivers/mtd/cmdlinepart.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/cmdlinepart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/cmdlinepart.c	2009-06-09 23:05:27.000000000 -0400
@@ -335,7 +335,11 @@ static int parse_cmdline_partitions(stru
 				}
 				offset += part->parts[i].size;
 			}
-			*pparts = part->parts;
+			*pparts = kmemdup(part->parts,
+					sizeof(*part->parts) * part->num_parts,
+					GFP_KERNEL);
+			if (!*pparts)
+				return -ENOMEM;
 			return part->num_parts;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2000.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2000.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2000.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2000.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,6 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2001.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2001.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2001.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2001.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,6 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2001plus.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2001plus.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/doc2001plus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/doc2001plus.c	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,6 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/docecc.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/docecc.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/docecc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/docecc.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/m25p80.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/m25p80.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/m25p80.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/m25p80.c	2009-06-09 23:05:27.000000000 -0400
@@ -54,7 +54,7 @@
 #define	SR_SRWD			0x80	/* SR write protect */
 
 /* Define max times to check status register before we give up. */
-#define	MAX_READY_WAIT_COUNT	100000
+#define	MAX_READY_WAIT_JIFFIES	(10 * HZ)	/* eg. M25P128 specs 6s max sector erase */
 #define	CMD_SIZE		4
 
 #ifdef CONFIG_M25PXX_USE_FAST_READ
@@ -65,12 +65,6 @@
 #define FAST_READ_DUMMY_BYTE 0
 #endif
 
-#ifdef CONFIG_MTD_PARTITIONS
-#define	mtd_has_partitions()	(1)
-#else
-#define	mtd_has_partitions()	(0)
-#endif
-
 /****************************************************************************/
 
 struct m25p {
@@ -145,20 +139,20 @@ static inline int write_enable(struct m2
  */
 static int wait_till_ready(struct m25p *flash)
 {
-	int count;
+	unsigned long deadline;
 	int sr;
 
-	/* one chip guarantees max 5 msec wait here after page writes,
-	 * but potentially three seconds (!) after page erase.
-	 */
-	for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
+	deadline = jiffies + MAX_READY_WAIT_JIFFIES;
+
+	do {
 		if ((sr = read_sr(flash)) < 0)
 			break;
 		else if (!(sr & SR_WIP))
 			return 0;
 
-		/* REVISIT sometimes sleeping would be best */
-	}
+		cond_resched();
+
+	} while (!time_after_eq(jiffies, deadline));
 
 	return 1;
 }
@@ -252,10 +246,12 @@ static int m25p80_erase(struct mtd_info
 	mutex_lock(&flash->lock);
 
 	/* whole-chip erase? */
-	if (len == flash->mtd.size && erase_chip(flash)) {
-		instr->state = MTD_ERASE_FAILED;
-		mutex_unlock(&flash->lock);
-		return -EIO;
+	if (len == flash->mtd.size) {
+		if (erase_chip(flash)) {
+			instr->state = MTD_ERASE_FAILED;
+			mutex_unlock(&flash->lock);
+			return -EIO;
+		}
 
 	/* REVISIT in some cases we could speed up erasing large regions
 	 * by using OPCODE_SE instead of OPCODE_BE_4K.  We may have set up
@@ -678,6 +674,8 @@ static int __devinit m25p_probe(struct s
 		flash->mtd.erasesize = info->sector_size;
 	}
 
+	flash->mtd.dev.parent = &spi->dev;
+
 	dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
 			(long long)flash->mtd.size >> 10);
 
@@ -708,12 +706,13 @@ static int __devinit m25p_probe(struct s
 		struct mtd_partition	*parts = NULL;
 		int			nr_parts = 0;
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-		static const char *part_probes[] = { "cmdlinepart", NULL, };
+		if (mtd_has_cmdlinepart()) {
+			static const char *part_probes[]
+					= { "cmdlinepart", NULL, };
 
-		nr_parts = parse_mtd_partitions(&flash->mtd,
-				part_probes, &parts, 0);
-#endif
+			nr_parts = parse_mtd_partitions(&flash->mtd,
+					part_probes, &parts, 0);
+		}
 
 		if (nr_parts <= 0 && data && data->parts) {
 			parts = data->parts;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/mtd_dataflash.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/mtd_dataflash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/mtd_dataflash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/mtd_dataflash.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,12 +98,6 @@ struct dataflash {
 	struct mtd_info		mtd;
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
-#define	mtd_has_partitions()	(1)
-#else
-#define	mtd_has_partitions()	(0)
-#endif
-
 /* ......................................................................... */
 
 /*
@@ -184,7 +178,7 @@ static int dataflash_erase(struct mtd_in
 		/* Calculate flash page address; use block erase (for speed) if
 		 * we're at a block boundary and need to erase the whole block.
 		 */
-		pageaddr = div_u64(instr->len, priv->page_size);
+		pageaddr = div_u64(instr->addr, priv->page_size);
 		do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize;
 		pageaddr = pageaddr << priv->page_offset;
 
@@ -670,6 +664,8 @@ add_dataflash_otp(struct spi_device *spi
 	device->write = dataflash_write;
 	device->priv = priv;
 
+	device->dev.parent = &spi->dev;
+
 	if (revision >= 'c')
 		otp_tag = otp_setup(device, revision);
 
@@ -682,11 +678,13 @@ add_dataflash_otp(struct spi_device *spi
 		struct mtd_partition	*parts;
 		int			nr_parts = 0;
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-		static const char *part_probes[] = { "cmdlinepart", NULL, };
+		if (mtd_has_cmdlinepart()) {
+			static const char *part_probes[]
+					= { "cmdlinepart", NULL, };
 
-		nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
-#endif
+			nr_parts = parse_mtd_partitions(device,
+					part_probes, &parts, 0);
+		}
 
 		if (nr_parts <= 0 && pdata && pdata->parts) {
 			parts = pdata->parts;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/devices/mtdram.c linux-libre-2.6.30-gnu1/drivers/mtd/devices/mtdram.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/devices/mtdram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/devices/mtdram.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,6 +65,19 @@ static void ram_unpoint(struct mtd_info
 {
 }
 
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
+					   unsigned long len,
+					   unsigned long offset,
+					   unsigned long flags)
+{
+	return (unsigned long) mtd->priv + offset;
+}
+
 static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char *buf)
 {
@@ -116,6 +129,7 @@ int mtdram_init_device(struct mtd_info *
 	mtd->erase = ram_erase;
 	mtd->point = ram_point;
 	mtd->unpoint = ram_unpoint;
+	mtd->get_unmapped_area = ram_get_unmapped_area;
 	mtd->read = ram_read;
 	mtd->write = ram_write;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/inftlmount.c linux-libre-2.6.30-gnu1/drivers/mtd/inftlmount.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/inftlmount.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/inftlmount.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/internal.h linux-libre-2.6.30-gnu1/drivers/mtd/internal.h
--- linux-libre-2.6.29-gnu1/drivers/mtd/internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/internal.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+/* Internal MTD definitions
+ *
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * mtdbdi.c
+ */
+extern struct backing_dev_info mtd_bdi_unmappable;
+extern struct backing_dev_info mtd_bdi_ro_mappable;
+extern struct backing_dev_info mtd_bdi_rw_mappable;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/Makefile linux-libre-2.6.30-gnu1/drivers/mtd/Makefile
--- linux-libre-2.6.29-gnu1/drivers/mtd/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)		+= mtd.o
-mtd-y				:= mtdcore.o mtdsuper.o
+mtd-y				:= mtdcore.o mtdsuper.o mtdbdi.o
 mtd-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
 
 obj-$(CONFIG_MTD_CONCAT)	+= mtdconcat.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/integrator-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/integrator-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/integrator-flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/integrator-flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
@@ -38,7 +39,6 @@
 
 #include <asm/mach/flash.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #ifdef CONFIG_ARCH_P720T
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/Kconfig linux-libre-2.6.30-gnu1/drivers/mtd/maps/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -529,12 +529,6 @@ config MTD_DMV182
         help
           Map driver for Dy-4 SVME/DMV-182 board.
 
-config MTD_SHARP_SL
-	tristate "ROM mapped on Sharp SL Series"
-	depends on ARCH_PXA
-	help
-	  This enables access to the flash chip on the Sharp SL Series of PDAs.
-
 config MTD_INTEL_VR_NOR
 	tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
 	depends on PCI
@@ -542,6 +536,12 @@ config MTD_INTEL_VR_NOR
 	  Map driver for a NOR flash bank located on the Expansion Bus of the
 	  Intel Vermilion Range chipset.
 
+config MTD_RBTX4939
+	tristate "Map driver for RBTX4939 board"
+	depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS
+	help
+	  Map driver for NOR flash chips on RBTX4939 board.
+
 config MTD_PLATRAM
 	tristate "Map driver for platform device RAM (mtd-ram)"
 	select MTD_RAM
@@ -551,5 +551,15 @@ config MTD_PLATRAM
 
 	  This selection automatically selects the map_ram driver.
 
-endmenu
+config MTD_VMU
+	tristate "Map driver for Dreamcast VMU"
+	depends on MAPLE
+	help
+	  This driver enables access to the Dreamcast Visual Memory Unit (VMU).
 
+	  Most Dreamcast users will want to say Y here.
+
+	  To build this as a module select M here, the module will be called
+	  vmu-flash.
+
+endmenu
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/Makefile linux-libre-2.6.30-gnu1/drivers/mtd/maps/Makefile
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -56,8 +56,9 @@ obj-$(CONFIG_MTD_IXP4XX)	+= ixp4xx.o
 obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
 obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
 obj-$(CONFIG_MTD_DMV182)	+= dmv182.o
-obj-$(CONFIG_MTD_SHARP_SL)	+= sharpsl-flash.o
 obj-$(CONFIG_MTD_PLATRAM)	+= plat-ram.o
 obj-$(CONFIG_MTD_OMAP_NOR)	+= omap_nor.o
 obj-$(CONFIG_MTD_INTEL_VR_NOR)	+= intel_vr_nor.o
 obj-$(CONFIG_MTD_BFIN_ASYNC)	+= bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939)	+= rbtx4939-flash.o
+obj-$(CONFIG_MTD_VMU)		+= vmu-flash.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/omap_nor.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/omap_nor.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/omap_nor.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/omap_nor.c	2009-06-09 23:05:27.000000000 -0400
@@ -115,6 +115,8 @@ static int __init omapflash_probe(struct
 	}
 	info->mtd->owner = THIS_MODULE;
 
+	info->mtd->dev.parent = &pdev->dev;
+
 #ifdef CONFIG_MTD_PARTITIONS
 	err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
 	if (err > 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/physmap.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/physmap.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/physmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/physmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -147,6 +147,7 @@ static int physmap_flash_probe(struct pl
 			devices_found++;
 		}
 		info->mtd[i]->owner = THIS_MODULE;
+		info->mtd[i]->dev.parent = &dev->dev;
 	}
 
 	if (devices_found == 1) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/physmap_of.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/physmap_of.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/physmap_of.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/physmap_of.c	2009-06-09 23:05:27.000000000 -0400
@@ -219,6 +219,7 @@ static int __devinit of_flash_probe(stru
 		goto err_out;
 	}
 	info->mtd->owner = THIS_MODULE;
+	info->mtd->dev.parent = &dev->dev;
 
 #ifdef CONFIG_MTD_PARTITIONS
 	/* First look for RedBoot table or partitions on the command
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/plat-ram.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/plat-ram.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/plat-ram.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/plat-ram.c	2009-06-09 23:05:27.000000000 -0400
@@ -224,6 +224,7 @@ static int platram_probe(struct platform
 	}
 
 	info->mtd->owner = THIS_MODULE;
+	info->mtd->dev.parent = &pdev->dev;
 
 	platram_setrw(info, PLATRAM_RW);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/pxa2xx-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/pxa2xx-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/pxa2xx-flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 
-static int __init pxa2xx_flash_probe(struct device *dev)
+static int __init pxa2xx_flash_probe(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	struct flash_platform_data *flash = pdev->dev.platform_data;
 	struct pxa2xx_flash_info *info;
 	struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(str
 		add_mtd_device(info->mtd);
 	}
 
-	dev_set_drvdata(dev, info);
+	platform_set_drvdata(pdev, info);
 	return 0;
 }
 
-static int __exit pxa2xx_flash_remove(struct device *dev)
+static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
 {
-	struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+	struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 
-	dev_set_drvdata(dev, NULL);
+	platform_set_drvdata(dev, NULL);
 
 #ifdef CONFIG_MTD_PARTITIONS
 	if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(st
 }
 
 #ifdef CONFIG_PM
-static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
 {
-	struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+	struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 	int ret = 0;
 
 	if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct d
 	return ret;
 }
 
-static int pxa2xx_flash_resume(struct device *dev)
+static int pxa2xx_flash_resume(struct platform_device *dev)
 {
-	struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+	struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 
 	if (info->mtd && info->mtd->resume)
 		info->mtd->resume(info->mtd);
 	return 0;
 }
-static void pxa2xx_flash_shutdown(struct device *dev)
+static void pxa2xx_flash_shutdown(struct platform_device *dev)
 {
-	struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+	struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 
 	if (info && info->mtd->suspend(info->mtd) == 0)
 		info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct
 #define pxa2xx_flash_shutdown NULL
 #endif
 
-static struct device_driver pxa2xx_flash_driver = {
-	.name		= "pxa2xx-flash",
-	.bus		= &platform_bus_type,
+static struct platform_driver pxa2xx_flash_driver = {
+	.driver = {
+		.name		= "pxa2xx-flash",
+		.owner		= THIS_MODULE,
+	},
 	.probe		= pxa2xx_flash_probe,
-	.remove		= __exit_p(pxa2xx_flash_remove),
+	.remove		= __devexit_p(pxa2xx_flash_remove),
 	.suspend	= pxa2xx_flash_suspend,
 	.resume		= pxa2xx_flash_resume,
 	.shutdown	= pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash
 
 static int __init init_pxa2xx_flash(void)
 {
-	return driver_register(&pxa2xx_flash_driver);
+	return platform_driver_register(&pxa2xx_flash_driver);
 }
 
 static void __exit cleanup_pxa2xx_flash(void)
 {
-	driver_unregister(&pxa2xx_flash_driver);
+	platform_driver_unregister(&pxa2xx_flash_driver);
 }
 
 module_init(init_pxa2xx_flash);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/rbtx4939-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/rbtx4939-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/rbtx4939-flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/rbtx4939-flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,208 @@
+/*
+ * rbtx4939-flash (based on physmap.c)
+ *
+ * This is a simplified physmap driver with map_init callback function.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/txx9/rbtx4939.h>
+
+struct rbtx4939_flash_info {
+	struct mtd_info *mtd;
+	struct map_info map;
+#ifdef CONFIG_MTD_PARTITIONS
+	int nr_parts;
+	struct mtd_partition *parts;
+#endif
+};
+
+static int rbtx4939_flash_remove(struct platform_device *dev)
+{
+	struct rbtx4939_flash_info *info;
+
+	info = platform_get_drvdata(dev);
+	if (!info)
+		return 0;
+	platform_set_drvdata(dev, NULL);
+
+	if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+		struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
+
+		if (info->nr_parts) {
+			del_mtd_partitions(info->mtd);
+			kfree(info->parts);
+		} else if (pdata->nr_parts)
+			del_mtd_partitions(info->mtd);
+		else
+			del_mtd_device(info->mtd);
+#else
+		del_mtd_device(info->mtd);
+#endif
+		map_destroy(info->mtd);
+	}
+	return 0;
+}
+
+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
+#endif
+
+static int rbtx4939_flash_probe(struct platform_device *dev)
+{
+	struct rbtx4939_flash_data *pdata;
+	struct rbtx4939_flash_info *info;
+	struct resource *res;
+	const char **probe_type;
+	int err = 0;
+	unsigned long size;
+
+	pdata = dev->dev.platform_data;
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info),
+			    GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	platform_set_drvdata(dev, info);
+
+	size = resource_size(res);
+	pr_notice("rbtx4939 platform flash device: %pR\n", res);
+
+	if (!devm_request_mem_region(&dev->dev, res->start, size,
+				     dev_name(&dev->dev)))
+		return -EBUSY;
+
+	info->map.name = dev_name(&dev->dev);
+	info->map.phys = res->start;
+	info->map.size = size;
+	info->map.bankwidth = pdata->width;
+
+	info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size);
+	if (!info->map.virt)
+		return -EBUSY;
+
+	if (pdata->map_init)
+		(*pdata->map_init)(&info->map);
+	else
+		simple_map_init(&info->map);
+
+	probe_type = rom_probe_types;
+	for (; !info->mtd && *probe_type; probe_type++)
+		info->mtd = do_map_probe(*probe_type, &info->map);
+	if (!info->mtd) {
+		dev_err(&dev->dev, "map_probe failed\n");
+		err = -ENXIO;
+		goto err_out;
+	}
+	info->mtd->owner = THIS_MODULE;
+	if (err)
+		goto err_out;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	err = parse_mtd_partitions(info->mtd, part_probe_types,
+				&info->parts, 0);
+	if (err > 0) {
+		add_mtd_partitions(info->mtd, info->parts, err);
+		info->nr_parts = err;
+		return 0;
+	}
+
+	if (pdata->nr_parts) {
+		pr_notice("Using rbtx4939 partition information\n");
+		add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+		return 0;
+	}
+#endif
+
+	add_mtd_device(info->mtd);
+	return 0;
+
+err_out:
+	rbtx4939_flash_remove(dev);
+	return err;
+}
+
+#ifdef CONFIG_PM
+static int rbtx4939_flash_suspend(struct platform_device *dev,
+				  pm_message_t state)
+{
+	struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+	if (info->mtd->suspend)
+		return info->mtd->suspend(info->mtd);
+	return 0;
+}
+
+static int rbtx4939_flash_resume(struct platform_device *dev)
+{
+	struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+	if (info->mtd->resume)
+		info->mtd->resume(info->mtd);
+	return 0;
+}
+
+static void rbtx4939_flash_shutdown(struct platform_device *dev)
+{
+	struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+	if (info->mtd->suspend && info->mtd->resume)
+		if (info->mtd->suspend(info->mtd) == 0)
+			info->mtd->resume(info->mtd);
+}
+#else
+#define rbtx4939_flash_suspend NULL
+#define rbtx4939_flash_resume NULL
+#define rbtx4939_flash_shutdown NULL
+#endif
+
+static struct platform_driver rbtx4939_flash_driver = {
+	.probe		= rbtx4939_flash_probe,
+	.remove		= rbtx4939_flash_remove,
+	.suspend	= rbtx4939_flash_suspend,
+	.resume		= rbtx4939_flash_resume,
+	.shutdown	= rbtx4939_flash_shutdown,
+	.driver		= {
+		.name	= "rbtx4939-flash",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init rbtx4939_flash_init(void)
+{
+	return platform_driver_register(&rbtx4939_flash_driver);
+}
+
+static void __exit rbtx4939_flash_exit(void)
+{
+	platform_driver_unregister(&rbtx4939_flash_driver);
+}
+
+module_init(rbtx4939_flash_init);
+module_exit(rbtx4939_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RBTX4939 MTD map driver");
+MODULE_ALIAS("platform:rbtx4939-flash");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/sa1100-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/sa1100-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/sa1100-flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/sa1100-flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
@@ -19,7 +20,6 @@
 #include <linux/mtd/concat.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/sizes.h>
 #include <asm/mach/flash.h>
 
@@ -351,7 +351,7 @@ sa1100_setup_mtd(struct platform_device
 
 static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 
-static int __init sa1100_mtd_probe(struct platform_device *pdev)
+static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
 {
 	struct flash_platform_data *plat = pdev->dev.platform_data;
 	struct mtd_partition *parts;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/sharpsl-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/sharpsl-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/sharpsl-flash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/sharpsl-flash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- * sharpsl-flash.c
- *
- * Copyright (C) 2001 Lineo Japan, Inc.
- * Copyright (C) 2002  SHARP
- *
- * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
- *          Handle mapping of the flash on the RPX Lite and CLLF boards
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-
-#define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x00800000
-#define BANK_WIDTH 2
-
-static struct mtd_info *mymtd;
-
-struct map_info sharpsl_map = {
-	.name = "sharpsl-flash",
-	.size = WINDOW_SIZE,
-	.bankwidth = BANK_WIDTH,
-	.phys = WINDOW_ADDR
-};
-
-static struct mtd_partition sharpsl_partitions[1] = {
-	{
-		name:		"Boot PROM Filesystem",
-	}
-};
-
-static int __init init_sharpsl(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	char *part_type = "static";
-
-	printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
-		WINDOW_SIZE, WINDOW_ADDR);
-	sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-	if (!sharpsl_map.virt) {
-		printk("Failed to ioremap\n");
-		return -EIO;
-	}
-
-	simple_map_init(&sharpsl_map);
-
-	mymtd = do_map_probe("map_rom", &sharpsl_map);
-	if (!mymtd) {
-		iounmap(sharpsl_map.virt);
-		return -ENXIO;
-	}
-
-	mymtd->owner = THIS_MODULE;
-
-	if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
-		|| machine_is_poodle()) {
-		sharpsl_partitions[0].size=0x006d0000;
-		sharpsl_partitions[0].offset=0x00120000;
-	} else if (machine_is_tosa()) {
-		sharpsl_partitions[0].size=0x006a0000;
-		sharpsl_partitions[0].offset=0x00160000;
-	} else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
-		sharpsl_partitions[0].size=0x006b0000;
-		sharpsl_partitions[0].offset=0x00140000;
-	} else {
-		map_destroy(mymtd);
-		iounmap(sharpsl_map.virt);
-		return -ENODEV;
-	}
-
-	parts = sharpsl_partitions;
-	nb_parts = ARRAY_SIZE(sharpsl_partitions);
-
-	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-	add_mtd_partitions(mymtd, parts, nb_parts);
-
-	return 0;
-}
-
-static void __exit cleanup_sharpsl(void)
-{
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
-	}
-	if (sharpsl_map.virt) {
-		iounmap(sharpsl_map.virt);
-		sharpsl_map.virt = 0;
-	}
-}
-
-module_init(init_sharpsl);
-module_exit(cleanup_sharpsl);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
-MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/maps/vmu-flash.c linux-libre-2.6.30-gnu1/drivers/mtd/maps/vmu-flash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/maps/vmu-flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/maps/vmu-flash.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,832 @@
+/* vmu-flash.c
+ * Driver for SEGA Dreamcast Visual Memory Unit
+ *
+ * Copyright (c) Adrian McMenamin 2002 - 2009
+ * Copyright (c) Paul Mundt 2001
+ *
+ * Licensed under version 2 of the
+ * GNU General Public Licence
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/maple.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+struct vmu_cache {
+	unsigned char *buffer;		/* Cache */
+	unsigned int block;		/* Which block was cached */
+	unsigned long jiffies_atc;	/* When was it cached? */
+	int valid;
+};
+
+struct mdev_part {
+	struct maple_device *mdev;
+	int partition;
+};
+
+struct vmupart {
+	u16 user_blocks;
+	u16 root_block;
+	u16 numblocks;
+	char *name;
+	struct vmu_cache *pcache;
+};
+
+struct memcard {
+	u16 tempA;
+	u16 tempB;
+	u32 partitions;
+	u32 blocklen;
+	u32 writecnt;
+	u32 readcnt;
+	u32 removeable;
+	int partition;
+	int read;
+	unsigned char *blockread;
+	struct vmupart *parts;
+	struct mtd_info *mtd;
+};
+
+struct vmu_block {
+	unsigned int num; /* block number */
+	unsigned int ofs; /* block offset */
+};
+
+static struct vmu_block *ofs_to_block(unsigned long src_ofs,
+	struct mtd_info *mtd, int partition)
+{
+	struct vmu_block *vblock;
+	struct maple_device *mdev;
+	struct memcard *card;
+	struct mdev_part *mpart;
+	int num;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	card = maple_get_drvdata(mdev);
+
+	if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
+		goto failed;
+
+	num = src_ofs / card->blocklen;
+	if (num > card->parts[partition].numblocks)
+		goto failed;
+
+	vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
+	if (!vblock)
+		goto failed;
+
+	vblock->num = num;
+	vblock->ofs = src_ofs % card->blocklen;
+	return vblock;
+
+failed:
+	return NULL;
+}
+
+/* Maple bus callback function for reads */
+static void vmu_blockread(struct mapleq *mq)
+{
+	struct maple_device *mdev;
+	struct memcard *card;
+
+	mdev = mq->dev;
+	card = maple_get_drvdata(mdev);
+	/* copy the read in data */
+
+	if (unlikely(!card->blockread))
+		return;
+
+	memcpy(card->blockread, mq->recvbuf->buf + 12,
+		card->blocklen/card->readcnt);
+
+}
+
+/* Interface with maple bus to read blocks
+ * caching the results so that other parts
+ * of the driver can access block reads */
+static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
+	struct mtd_info *mtd)
+{
+	struct memcard *card;
+	struct mdev_part *mpart;
+	struct maple_device *mdev;
+	int partition, error = 0, x, wait;
+	unsigned char *blockread = NULL;
+	struct vmu_cache *pcache;
+	__be32 sendbuf;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	partition = mpart->partition;
+	card = maple_get_drvdata(mdev);
+	pcache = card->parts[partition].pcache;
+	pcache->valid = 0;
+
+	/* prepare the cache for this block */
+	if (!pcache->buffer) {
+		pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
+		if (!pcache->buffer) {
+			dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
+				" to lack of memory\n", mdev->port,
+				mdev->unit);
+			error = -ENOMEM;
+			goto outB;
+		}
+	}
+
+	/*
+	* Reads may be phased - again the hardware spec
+	* supports this - though may not be any devices in
+	* the wild that implement it, but we will here
+	*/
+	for (x = 0; x < card->readcnt; x++) {
+		sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
+
+		if (atomic_read(&mdev->busy) == 1) {
+			wait_event_interruptible_timeout(mdev->maple_wait,
+				atomic_read(&mdev->busy) == 0, HZ);
+			if (atomic_read(&mdev->busy) == 1) {
+				dev_notice(&mdev->dev, "VMU at (%d, %d)"
+					" is busy\n", mdev->port, mdev->unit);
+				error = -EAGAIN;
+				goto outB;
+			}
+		}
+
+		atomic_set(&mdev->busy, 1);
+		blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
+		if (!blockread) {
+			error = -ENOMEM;
+			atomic_set(&mdev->busy, 0);
+			goto outB;
+		}
+		card->blockread = blockread;
+
+		maple_getcond_callback(mdev, vmu_blockread, 0,
+			MAPLE_FUNC_MEMCARD);
+		error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+				MAPLE_COMMAND_BREAD, 2, &sendbuf);
+		/* Very long timeouts seem to be needed when box is stressed */
+		wait = wait_event_interruptible_timeout(mdev->maple_wait,
+			(atomic_read(&mdev->busy) == 0 ||
+			atomic_read(&mdev->busy) == 2), HZ * 3);
+		/*
+		* MTD layer does not handle hotplugging well
+		* so have to return errors when VMU is unplugged
+		* in the middle of a read (busy == 2)
+		*/
+		if (error || atomic_read(&mdev->busy) == 2) {
+			if (atomic_read(&mdev->busy) == 2)
+				error = -ENXIO;
+			atomic_set(&mdev->busy, 0);
+			card->blockread = NULL;
+			goto outA;
+		}
+		if (wait == 0 || wait == -ERESTARTSYS) {
+			card->blockread = NULL;
+			atomic_set(&mdev->busy, 0);
+			error = -EIO;
+			list_del_init(&(mdev->mq->list));
+			kfree(mdev->mq->sendbuf);
+			mdev->mq->sendbuf = NULL;
+			if (wait == -ERESTARTSYS) {
+				dev_warn(&mdev->dev, "VMU read on (%d, %d)"
+					" interrupted on block 0x%X\n",
+					mdev->port, mdev->unit, num);
+			} else
+				dev_notice(&mdev->dev, "VMU read on (%d, %d)"
+					" timed out on block 0x%X\n",
+					mdev->port, mdev->unit, num);
+			goto outA;
+		}
+
+		memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
+			card->blocklen/card->readcnt);
+
+		memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
+			card->blockread, card->blocklen/card->readcnt);
+		card->blockread = NULL;
+		pcache->block = num;
+		pcache->jiffies_atc = jiffies;
+		pcache->valid = 1;
+		kfree(blockread);
+	}
+
+	return error;
+
+outA:
+	kfree(blockread);
+outB:
+	return error;
+}
+
+/* communicate with maple bus for phased writing */
+static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
+	struct mtd_info *mtd)
+{
+	struct memcard *card;
+	struct mdev_part *mpart;
+	struct maple_device *mdev;
+	int partition, error, locking, x, phaselen, wait;
+	__be32 *sendbuf;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	partition = mpart->partition;
+	card = maple_get_drvdata(mdev);
+
+	phaselen = card->blocklen/card->writecnt;
+
+	sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
+	if (!sendbuf) {
+		error = -ENOMEM;
+		goto fail_nosendbuf;
+	}
+	for (x = 0; x < card->writecnt; x++) {
+		sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
+		memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
+		/* wait until the device is not busy doing something else
+		* or 1 second - which ever is longer */
+		if (atomic_read(&mdev->busy) == 1) {
+			wait_event_interruptible_timeout(mdev->maple_wait,
+				atomic_read(&mdev->busy) == 0, HZ);
+			if (atomic_read(&mdev->busy) == 1) {
+				error = -EBUSY;
+				dev_notice(&mdev->dev, "VMU write at (%d, %d)"
+					"failed - device is busy\n",
+					mdev->port, mdev->unit);
+				goto fail_nolock;
+			}
+		}
+		atomic_set(&mdev->busy, 1);
+
+		locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+			MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
+		wait = wait_event_interruptible_timeout(mdev->maple_wait,
+			atomic_read(&mdev->busy) == 0, HZ/10);
+		if (locking) {
+			error = -EIO;
+			atomic_set(&mdev->busy, 0);
+			goto fail_nolock;
+		}
+		if (atomic_read(&mdev->busy) == 2) {
+			atomic_set(&mdev->busy, 0);
+		} else if (wait == 0 || wait == -ERESTARTSYS) {
+			error = -EIO;
+			dev_warn(&mdev->dev, "Write at (%d, %d) of block"
+				" 0x%X at phase %d failed: could not"
+				" communicate with VMU", mdev->port,
+				mdev->unit, num, x);
+			atomic_set(&mdev->busy, 0);
+			kfree(mdev->mq->sendbuf);
+			mdev->mq->sendbuf = NULL;
+			list_del_init(&(mdev->mq->list));
+			goto fail_nolock;
+		}
+	}
+	kfree(sendbuf);
+
+	return card->blocklen;
+
+fail_nolock:
+	kfree(sendbuf);
+fail_nosendbuf:
+	dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
+		mdev->unit);
+	return error;
+}
+
+/* mtd function to simulate reading byte by byte */
+static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
+	struct mtd_info *mtd)
+{
+	struct vmu_block *vblock;
+	struct memcard *card;
+	struct mdev_part *mpart;
+	struct maple_device *mdev;
+	unsigned char *buf, ret;
+	int partition, error;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	partition = mpart->partition;
+	card = maple_get_drvdata(mdev);
+	*retval =  0;
+
+	buf = kmalloc(card->blocklen, GFP_KERNEL);
+	if (!buf) {
+		*retval = 1;
+		ret = -ENOMEM;
+		goto finish;
+	}
+
+	vblock = ofs_to_block(ofs, mtd, partition);
+	if (!vblock) {
+		*retval = 3;
+		ret = -ENOMEM;
+		goto out_buf;
+	}
+
+	error = maple_vmu_read_block(vblock->num, buf, mtd);
+	if (error) {
+		ret = error;
+		*retval = 2;
+		goto out_vblock;
+	}
+
+	ret = buf[vblock->ofs];
+
+out_vblock:
+	kfree(vblock);
+out_buf:
+	kfree(buf);
+finish:
+	return ret;
+}
+
+/* mtd higher order function to read flash */
+static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen,  u_char *buf)
+{
+	struct maple_device *mdev;
+	struct memcard *card;
+	struct mdev_part *mpart;
+	struct vmu_cache *pcache;
+	struct vmu_block *vblock;
+	int index = 0, retval, partition, leftover, numblocks;
+	unsigned char cx;
+
+	if (len < 1)
+		return -EIO;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	partition = mpart->partition;
+	card = maple_get_drvdata(mdev);
+
+	numblocks = card->parts[partition].numblocks;
+	if (from + len > numblocks * card->blocklen)
+		len = numblocks * card->blocklen - from;
+	if (len == 0)
+		return -EIO;
+	/* Have we cached this bit already? */
+	pcache = card->parts[partition].pcache;
+	do {
+		vblock =  ofs_to_block(from + index, mtd, partition);
+		if (!vblock)
+			return -ENOMEM;
+		/* Have we cached this and is the cache valid and timely? */
+		if (pcache->valid &&
+			time_before(jiffies, pcache->jiffies_atc + HZ) &&
+			(pcache->block == vblock->num)) {
+			/* we have cached it, so do necessary copying */
+			leftover = card->blocklen - vblock->ofs;
+			if (vblock->ofs + len - index < card->blocklen) {
+				/* only a bit of this block to copy */
+				memcpy(buf + index,
+					pcache->buffer + vblock->ofs,
+					len - index);
+				index = len;
+			} else {
+				/* otherwise copy remainder of whole block */
+				memcpy(buf + index, pcache->buffer +
+					vblock->ofs, leftover);
+				index += leftover;
+			}
+		} else {
+			/*
+			* Not cached so read one byte -
+			* but cache the rest of the block
+			*/
+			cx = vmu_flash_read_char(from + index, &retval, mtd);
+			if (retval) {
+				*retlen = index;
+				kfree(vblock);
+				return cx;
+			}
+			memset(buf + index, cx, 1);
+			index++;
+		}
+		kfree(vblock);
+	} while (len > index);
+	*retlen = index;
+
+	return 0;
+}
+
+static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
+	size_t *retlen, const u_char *buf)
+{
+	struct maple_device *mdev;
+	struct memcard *card;
+	struct mdev_part *mpart;
+	int index = 0, partition, error = 0, numblocks;
+	struct vmu_cache *pcache;
+	struct vmu_block *vblock;
+	unsigned char *buffer;
+
+	mpart = mtd->priv;
+	mdev = mpart->mdev;
+	partition = mpart->partition;
+	card = maple_get_drvdata(mdev);
+
+	/* simple sanity checks */
+	if (len < 1) {
+		error = -EIO;
+		goto failed;
+	}
+	numblocks = card->parts[partition].numblocks;
+	if (to + len > numblocks * card->blocklen)
+		len = numblocks * card->blocklen - to;
+	if (len == 0) {
+		error = -EIO;
+		goto failed;
+	}
+
+	vblock = ofs_to_block(to, mtd, partition);
+	if (!vblock) {
+		error = -ENOMEM;
+		goto failed;
+	}
+
+	buffer = kmalloc(card->blocklen, GFP_KERNEL);
+	if (!buffer) {
+		error = -ENOMEM;
+		goto fail_buffer;
+	}
+
+	do {
+		/* Read in the block we are to write to */
+		error = maple_vmu_read_block(vblock->num, buffer, mtd);
+		if (error)
+			goto fail_io;
+
+		do {
+			buffer[vblock->ofs] = buf[index];
+			vblock->ofs++;
+			index++;
+			if (index >= len)
+				break;
+		} while (vblock->ofs < card->blocklen);
+
+		/* write out new buffer */
+		error = maple_vmu_write_block(vblock->num, buffer, mtd);
+		/* invalidate the cache */
+		pcache = card->parts[partition].pcache;
+		pcache->valid = 0;
+
+		if (error != card->blocklen)
+			goto fail_io;
+
+		vblock->num++;
+		vblock->ofs = 0;
+	} while (len > index);
+
+	kfree(buffer);
+	*retlen = index;
+	kfree(vblock);
+	return 0;
+
+fail_io:
+	kfree(buffer);
+fail_buffer:
+	kfree(vblock);
+failed:
+	dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
+	return error;
+}
+
+static void vmu_flash_sync(struct mtd_info *mtd)
+{
+	/* Do nothing here */
+}
+
+/* Maple bus callback function to recursively query hardware details */
+static void vmu_queryblocks(struct mapleq *mq)
+{
+	struct maple_device *mdev;
+	unsigned short *res;
+	struct memcard *card;
+	__be32 partnum;
+	struct vmu_cache *pcache;
+	struct mdev_part *mpart;
+	struct mtd_info *mtd_cur;
+	struct vmupart *part_cur;
+	int error;
+
+	mdev = mq->dev;
+	card = maple_get_drvdata(mdev);
+	res = (unsigned short *) (mq->recvbuf->buf);
+	card->tempA = res[12];
+	card->tempB = res[6];
+
+	dev_info(&mdev->dev, "VMU device at partition %d has %d user "
+		"blocks with a root block at %d\n", card->partition,
+		card->tempA, card->tempB);
+
+	part_cur = &card->parts[card->partition];
+	part_cur->user_blocks = card->tempA;
+	part_cur->root_block = card->tempB;
+	part_cur->numblocks = card->tempB + 1;
+	part_cur->name = kmalloc(12, GFP_KERNEL);
+	if (!part_cur->name)
+		goto fail_name;
+
+	sprintf(part_cur->name, "vmu%d.%d.%d",
+		mdev->port, mdev->unit, card->partition);
+	mtd_cur = &card->mtd[card->partition];
+	mtd_cur->name = part_cur->name;
+	mtd_cur->type = 8;
+	mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
+	mtd_cur->size = part_cur->numblocks * card->blocklen;
+	mtd_cur->erasesize = card->blocklen;
+	mtd_cur->write = vmu_flash_write;
+	mtd_cur->read = vmu_flash_read;
+	mtd_cur->sync = vmu_flash_sync;
+	mtd_cur->writesize = card->blocklen;
+
+	mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
+	if (!mpart)
+		goto fail_mpart;
+
+	mpart->mdev = mdev;
+	mpart->partition = card->partition;
+	mtd_cur->priv = mpart;
+	mtd_cur->owner = THIS_MODULE;
+
+	pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
+	if (!pcache)
+		goto fail_cache_create;
+	part_cur->pcache = pcache;
+
+	error = add_mtd_device(mtd_cur);
+	if (error)
+		goto fail_mtd_register;
+
+	maple_getcond_callback(mdev, NULL, 0,
+		MAPLE_FUNC_MEMCARD);
+
+	/*
+	* Set up a recursive call to the (probably theoretical)
+	* second or more partition
+	*/
+	if (++card->partition < card->partitions) {
+		partnum = cpu_to_be32(card->partition << 24);
+		maple_getcond_callback(mdev, vmu_queryblocks, 0,
+			MAPLE_FUNC_MEMCARD);
+		maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+			MAPLE_COMMAND_GETMINFO, 2, &partnum);
+	}
+	return;
+
+fail_mtd_register:
+	dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
+		"error is 0x%X\n", mdev->port, mdev->unit, error);
+	for (error = 0; error <= card->partition; error++) {
+		kfree(((card->parts)[error]).pcache);
+		((card->parts)[error]).pcache = NULL;
+	}
+fail_cache_create:
+fail_mpart:
+	for (error = 0; error <= card->partition; error++) {
+		kfree(((card->mtd)[error]).priv);
+		((card->mtd)[error]).priv = NULL;
+	}
+	maple_getcond_callback(mdev, NULL, 0,
+		MAPLE_FUNC_MEMCARD);
+	kfree(part_cur->name);
+fail_name:
+	return;
+}
+
+/* Handles very basic info about the flash, queries for details */
+static int __devinit vmu_connect(struct maple_device *mdev)
+{
+	unsigned long test_flash_data, basic_flash_data;
+	int c, error;
+	struct memcard *card;
+	u32 partnum = 0;
+
+	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;
+
+	basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
+
+	card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
+	if (!card) {
+		error = ENOMEM;
+		goto fail_nomem;
+	}
+
+	card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
+	card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
+	card->writecnt = basic_flash_data >> 12 & 0xF;
+	card->readcnt = basic_flash_data >> 8 & 0xF;
+	card->removeable = basic_flash_data >> 7 & 1;
+
+	card->partition = 0;
+
+	/*
+	* Not sure there are actually any multi-partition devices in the
+	* real world, but the hardware supports them, so, so will we
+	*/
+	card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
+		GFP_KERNEL);
+	if (!card->parts) {
+		error = -ENOMEM;
+		goto fail_partitions;
+	}
+
+	card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
+		GFP_KERNEL);
+	if (!card->mtd) {
+		error = -ENOMEM;
+		goto fail_mtd_info;
+	}
+
+	maple_set_drvdata(mdev, card);
+
+	/*
+	* We want to trap meminfo not get cond
+	* so set interval to zero, but rely on maple bus
+	* driver to pass back the results of the meminfo
+	*/
+	maple_getcond_callback(mdev, vmu_queryblocks, 0,
+		MAPLE_FUNC_MEMCARD);
+
+	/* Make sure we are clear to go */
+	if (atomic_read(&mdev->busy) == 1) {
+		wait_event_interruptible_timeout(mdev->maple_wait,
+			atomic_read(&mdev->busy) == 0, HZ);
+		if (atomic_read(&mdev->busy) == 1) {
+			dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
+				mdev->port, mdev->unit);
+			error = -EAGAIN;
+			goto fail_device_busy;
+		}
+	}
+
+	atomic_set(&mdev->busy, 1);
+
+	/*
+	* Set up the minfo call: vmu_queryblocks will handle
+	* the information passed back
+	*/
+	error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+		MAPLE_COMMAND_GETMINFO, 2, &partnum);
+	if (error) {
+		dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
+			" error is 0x%X\n", mdev->port, mdev->unit, error);
+		goto fail_mtd_info;
+	}
+	return 0;
+
+fail_device_busy:
+	kfree(card->mtd);
+fail_mtd_info:
+	kfree(card->parts);
+fail_partitions:
+	kfree(card);
+fail_nomem:
+	return error;
+}
+
+static void __devexit vmu_disconnect(struct maple_device *mdev)
+{
+	struct memcard *card;
+	struct mdev_part *mpart;
+	int x;
+
+	mdev->callback = NULL;
+	card = maple_get_drvdata(mdev);
+	for (x = 0; x < card->partitions; x++) {
+		mpart = ((card->mtd)[x]).priv;
+		mpart->mdev = NULL;
+		del_mtd_device(&((card->mtd)[x]));
+		kfree(((card->parts)[x]).name);
+	}
+	kfree(card->parts);
+	kfree(card->mtd);
+	kfree(card);
+}
+
+/* Callback to handle eccentricities of both mtd subsystem
+ * and general flakyness of Dreamcast VMUs
+ */
+static int vmu_can_unload(struct maple_device *mdev)
+{
+	struct memcard *card;
+	int x;
+	struct mtd_info *mtd;
+
+	card = maple_get_drvdata(mdev);
+	for (x = 0; x < card->partitions; x++) {
+		mtd = &((card->mtd)[x]);
+		if (mtd->usecount > 0)
+			return 0;
+	}
+	return 1;
+}
+
+#define ERRSTR "VMU at (%d, %d) file error -"
+
+static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
+{
+	enum maple_file_errors error = ((int *)recvbuf)[1];
+
+	switch (error) {
+
+	case MAPLE_FILEERR_INVALID_PARTITION:
+		dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
+			mdev->port, mdev->unit);
+		break;
+
+	case MAPLE_FILEERR_PHASE_ERROR:
+		dev_notice(&mdev->dev, ERRSTR " phase error\n",
+			mdev->port, mdev->unit);
+		break;
+
+	case MAPLE_FILEERR_INVALID_BLOCK:
+		dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
+			mdev->port, mdev->unit);
+		break;
+
+	case MAPLE_FILEERR_WRITE_ERROR:
+		dev_notice(&mdev->dev, ERRSTR " write error\n",
+			mdev->port, mdev->unit);
+		break;
+
+	case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
+		dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
+			mdev->port, mdev->unit);
+		break;
+
+	case MAPLE_FILEERR_BAD_CRC:
+		dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
+			mdev->port, mdev->unit);
+		break;
+
+	default:
+		dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
+			mdev->port, mdev->unit, error);
+	}
+}
+
+
+static int __devinit probe_maple_vmu(struct device *dev)
+{
+	int error;
+	struct maple_device *mdev = to_maple_dev(dev);
+	struct maple_driver *mdrv = to_maple_driver(dev->driver);
+
+	mdev->can_unload = vmu_can_unload;
+	mdev->fileerr_handler = vmu_file_error;
+	mdev->driver = mdrv;
+
+	error = vmu_connect(mdev);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int __devexit remove_maple_vmu(struct device *dev)
+{
+	struct maple_device *mdev = to_maple_dev(dev);
+
+	vmu_disconnect(mdev);
+	return 0;
+}
+
+static struct maple_driver vmu_flash_driver = {
+	.function =	MAPLE_FUNC_MEMCARD,
+	.drv = {
+		.name =		"Dreamcast_visual_memory",
+		.probe =	probe_maple_vmu,
+		.remove = 	__devexit_p(remove_maple_vmu),
+	},
+};
+
+static int __init vmu_flash_map_init(void)
+{
+	return maple_driver_register(&vmu_flash_driver);
+}
+
+static void __exit vmu_flash_map_exit(void)
+{
+	maple_driver_unregister(&vmu_flash_driver);
+}
+
+module_init(vmu_flash_map_init);
+module_exit(vmu_flash_map_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian McMenamin");
+MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdbdi.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdbdi.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdbdi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdbdi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,43 @@
+/* MTD backing device capabilities
+ *
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/backing-dev.h>
+#include <linux/mtd/mtd.h>
+#include "internal.h"
+
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+	.capabilities	= BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+	.capabilities	= (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+			   BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+	.capabilities	= (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+			   BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+			   BDI_CAP_WRITE_MAP),
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtd_blkdevs.c linux-libre-2.6.30-gnu1/drivers/mtd/mtd_blkdevs.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtd_blkdevs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtd_blkdevs.c	2009-06-09 23:05:27.000000000 -0400
@@ -286,6 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blkt
 	gd->private_data = new;
 	new->blkcore_priv = gd;
 	gd->queue = tr->blkcore_priv->rq;
+	gd->driverfs_dev = new->mtd->dev.parent;
 
 	if (new->readonly)
 		set_disk_ro(gd, 1);
@@ -382,11 +383,12 @@ 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);
 		blk_cleanup_queue(tr->blkcore_priv->rq);
 		unregister_blkdev(tr->major, tr->name);
 		kfree(tr->blkcore_priv);
 		mutex_unlock(&mtd_table_mutex);
-		return PTR_ERR(tr->blkcore_priv->thread);
+		return ret;
 	}
 
 	INIT_LIST_HEAD(&tr->devs);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdchar.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdchar.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdchar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdchar.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,39 +13,13 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 
 #include <asm/uaccess.h>
 
-static struct class *mtd_class;
-
-static void mtd_notify_add(struct mtd_info* mtd)
-{
-	if (!mtd)
-		return;
-
-	device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
-		      NULL, "mtd%d", mtd->index);
-
-	device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
-		      NULL, "mtd%dro", mtd->index);
-}
-
-static void mtd_notify_remove(struct mtd_info* mtd)
-{
-	if (!mtd)
-		return;
-
-	device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
-	device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
-}
-
-static struct mtd_notifier notifier = {
-	.add	= mtd_notify_add,
-	.remove	= mtd_notify_remove,
-};
 
 /*
  * Data structure to hold the pointer to the mtd device as well
@@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode,
 		goto out;
 	}
 
-	if (MTD_ABSENT == mtd->type) {
+	if (mtd->type == MTD_ABSENT) {
 		put_mtd_device(mtd);
 		ret = -ENODEV;
 		goto out;
 	}
 
+	if (mtd->backing_dev_info)
+		file->f_mapping->backing_dev_info = mtd->backing_dev_info;
+
 	/* You can't open it RW if it's not a writeable device */
 	if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
 		put_mtd_device(mtd);
@@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode
 	return ret;
 } /* memory_ioctl */
 
+/*
+ * try to determine where a shared mapping can be made
+ * - only supported for NOMMU at the moment (MMU can't doesn't copy private
+ *   mappings)
+ */
+#ifndef CONFIG_MMU
+static unsigned long mtd_get_unmapped_area(struct file *file,
+					   unsigned long addr,
+					   unsigned long len,
+					   unsigned long pgoff,
+					   unsigned long flags)
+{
+	struct mtd_file_info *mfi = file->private_data;
+	struct mtd_info *mtd = mfi->mtd;
+
+	if (mtd->get_unmapped_area) {
+		unsigned long offset;
+
+		if (addr != 0)
+			return (unsigned long) -EINVAL;
+
+		if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
+			return (unsigned long) -EINVAL;
+
+		offset = pgoff << PAGE_SHIFT;
+		if (offset > mtd->size - len)
+			return (unsigned long) -EINVAL;
+
+		return mtd->get_unmapped_area(mtd, len, offset, flags);
+	}
+
+	/* can't map directly */
+	return (unsigned long) -ENOSYS;
+}
+#endif
+
+/*
+ * set up a mapping for shared memory segments
+ */
+static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
+{
+#ifdef CONFIG_MMU
+	struct mtd_file_info *mfi = file->private_data;
+	struct mtd_info *mtd = mfi->mtd;
+
+	if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
+		return 0;
+	return -ENOSYS;
+#else
+	return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
+#endif
+}
+
 static const struct file_operations mtd_fops = {
 	.owner		= THIS_MODULE,
 	.llseek		= mtd_lseek,
@@ -789,39 +819,36 @@ static const struct file_operations mtd_
 	.ioctl		= mtd_ioctl,
 	.open		= mtd_open,
 	.release	= mtd_close,
+	.mmap		= mtd_mmap,
+#ifndef CONFIG_MMU
+	.get_unmapped_area = mtd_get_unmapped_area,
+#endif
 };
 
 static int __init init_mtdchar(void)
 {
-	if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) {
+	int status;
+
+	status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);
+	if (status < 0) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
 		       MTD_CHAR_MAJOR);
-		return -EAGAIN;
 	}
 
-	mtd_class = class_create(THIS_MODULE, "mtd");
-
-	if (IS_ERR(mtd_class)) {
-		printk(KERN_ERR "Error creating mtd class.\n");
-		unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
-		return PTR_ERR(mtd_class);
-	}
-
-	register_mtd_user(&notifier);
-	return 0;
+	return status;
 }
 
 static void __exit cleanup_mtdchar(void)
 {
-	unregister_mtd_user(&notifier);
-	class_destroy(mtd_class);
 	unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
 }
 
 module_init(init_mtdchar);
 module_exit(cleanup_mtdchar);
 
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
 MODULE_DESCRIPTION("Direct character-device access to MTD devices");
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdconcat.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdconcat.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdconcat.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdconcat.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/concat.h>
@@ -684,6 +685,40 @@ static int concat_block_markbad(struct m
 }
 
 /*
+ * try to support NOMMU mmaps on concatenated devices
+ * - we don't support subdev spanning as we can't guarantee it'll work
+ */
+static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
+					      unsigned long len,
+					      unsigned long offset,
+					      unsigned long flags)
+{
+	struct mtd_concat *concat = CONCAT(mtd);
+	int i;
+
+	for (i = 0; i < concat->num_subdev; i++) {
+		struct mtd_info *subdev = concat->subdev[i];
+
+		if (offset >= subdev->size) {
+			offset -= subdev->size;
+			continue;
+		}
+
+		/* we've found the subdev over which the mapping will reside */
+		if (offset + len > subdev->size)
+			return (unsigned long) -EINVAL;
+
+		if (subdev->get_unmapped_area)
+			return subdev->get_unmapped_area(subdev, len, offset,
+							 flags);
+
+		break;
+	}
+
+	return (unsigned long) -ENOSYS;
+}
+
+/*
  * This function constructs a virtual MTD device by concatenating
  * num_devs MTD devices. A pointer to the new device object is
  * stored to *new_dev upon success. This function does _not_
@@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struc
 
 	concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
 
+	concat->mtd.backing_dev_info = subdev[0]->backing_dev_info;
+
 	concat->subdev[0] = subdev[0];
 
 	for (i = 1; i < num_devs; i++) {
@@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struc
 				concat->mtd.flags |=
 				    subdev[i]->flags & MTD_WRITEABLE;
 		}
+
+		/* only permit direct mapping if the BDIs are all the same
+		 * - copy-mapping is still permitted
+		 */
+		if (concat->mtd.backing_dev_info !=
+		    subdev[i]->backing_dev_info)
+			concat->mtd.backing_dev_info =
+				&default_backing_dev_info;
+
 		concat->mtd.size += subdev[i]->size;
 		concat->mtd.ecc_stats.badblocks +=
 			subdev[i]->ecc_stats.badblocks;
@@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struc
 	concat->mtd.unlock = concat_unlock;
 	concat->mtd.suspend = concat_suspend;
 	concat->mtd.resume = concat_resume;
+	concat->mtd.get_unmapped_area = concat_get_unmapped_area;
 
 	/*
 	 * Combine the erase block size info of the subdevices:
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdcore.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdcore.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdcore.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdcore.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,9 +19,13 @@
 #include <linux/proc_fs.h>
 
 #include <linux/mtd/mtd.h>
+#include "internal.h"
 
 #include "mtdcore.h"
 
+
+static struct class *mtd_class;
+
 /* These are exported solely for the purpose of mtd_blkdevs.c. You
    should not use them for _anything_ else */
 DEFINE_MUTEX(mtd_table_mutex);
@@ -32,6 +36,172 @@ EXPORT_SYMBOL_GPL(mtd_table);
 
 static LIST_HEAD(mtd_notifiers);
 
+
+#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
+#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
+#else
+#define MTD_DEVT(index) 0
+#endif
+
+/* REVISIT once MTD uses the driver model better, whoever allocates
+ * the mtd_info will probably want to use the release() hook...
+ */
+static void mtd_release(struct device *dev)
+{
+	dev_t index = MTD_DEVT(dev_to_mtd(dev)->index);
+
+	/* remove /dev/mtdXro node if needed */
+	if (index)
+		device_destroy(mtd_class, index + 1);
+}
+
+static ssize_t mtd_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+	char *type;
+
+	switch (mtd->type) {
+	case MTD_ABSENT:
+		type = "absent";
+		break;
+	case MTD_RAM:
+		type = "ram";
+		break;
+	case MTD_ROM:
+		type = "rom";
+		break;
+	case MTD_NORFLASH:
+		type = "nor";
+		break;
+	case MTD_NANDFLASH:
+		type = "nand";
+		break;
+	case MTD_DATAFLASH:
+		type = "dataflash";
+		break;
+	case MTD_UBIVOLUME:
+		type = "ubi";
+		break;
+	default:
+		type = "unknown";
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
+
+static ssize_t mtd_flags_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
+
+}
+static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
+
+static ssize_t mtd_size_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%llu\n",
+		(unsigned long long)mtd->size);
+
+}
+static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
+
+static ssize_t mtd_erasesize_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
+
+}
+static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
+
+static ssize_t mtd_writesize_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
+
+}
+static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
+
+static ssize_t mtd_subpagesize_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+	unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize);
+
+}
+static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL);
+
+static ssize_t mtd_oobsize_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
+
+}
+static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
+
+static ssize_t mtd_numeraseregions_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
+
+}
+static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
+	NULL);
+
+static ssize_t mtd_name_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct mtd_info *mtd = dev_to_mtd(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
+
+}
+static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
+
+static struct attribute *mtd_attrs[] = {
+	&dev_attr_type.attr,
+	&dev_attr_flags.attr,
+	&dev_attr_size.attr,
+	&dev_attr_erasesize.attr,
+	&dev_attr_writesize.attr,
+	&dev_attr_subpagesize.attr,
+	&dev_attr_oobsize.attr,
+	&dev_attr_numeraseregions.attr,
+	&dev_attr_name.attr,
+	NULL,
+};
+
+struct attribute_group mtd_group = {
+	.attrs		= mtd_attrs,
+};
+
+struct attribute_group *mtd_groups[] = {
+	&mtd_group,
+	NULL,
+};
+
+static struct device_type mtd_devtype = {
+	.name		= "mtd",
+	.groups		= mtd_groups,
+	.release	= mtd_release,
+};
+
 /**
  *	add_mtd_device - register an MTD device
  *	@mtd: pointer to new MTD device info structure
@@ -40,12 +210,27 @@ static LIST_HEAD(mtd_notifiers);
  *	notify each currently active MTD 'user' of its arrival. Returns
  *	zero on success or 1 on failure, which currently will only happen
  *	if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
+ *	or there's a sysfs error.
  */
 
 int add_mtd_device(struct mtd_info *mtd)
 {
 	int i;
 
+	if (!mtd->backing_dev_info) {
+		switch (mtd->type) {
+		case MTD_RAM:
+			mtd->backing_dev_info = &mtd_bdi_rw_mappable;
+			break;
+		case MTD_ROM:
+			mtd->backing_dev_info = &mtd_bdi_ro_mappable;
+			break;
+		default:
+			mtd->backing_dev_info = &mtd_bdi_unmappable;
+			break;
+		}
+	}
+
 	BUG_ON(mtd->writesize == 0);
 	mutex_lock(&mtd_table_mutex);
 
@@ -80,6 +265,23 @@ int add_mtd_device(struct mtd_info *mtd)
 					       mtd->name);
 			}
 
+			/* Caller should have set dev.parent to match the
+			 * physical device.
+			 */
+			mtd->dev.type = &mtd_devtype;
+			mtd->dev.class = mtd_class;
+			mtd->dev.devt = MTD_DEVT(i);
+			dev_set_name(&mtd->dev, "mtd%d", i);
+			if (device_register(&mtd->dev) != 0) {
+				mtd_table[i] = NULL;
+				break;
+			}
+
+			if (MTD_DEVT(i))
+				device_create(mtd_class, mtd->dev.parent,
+						MTD_DEVT(i) + 1,
+						NULL, "mtd%dro", i);
+
 			DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
 			/* No need to get a refcount on the module containing
 			   the notifier, since we hold the mtd_table_mutex */
@@ -124,6 +326,8 @@ int del_mtd_device (struct mtd_info *mtd
 	} else {
 		struct mtd_notifier *not;
 
+		device_unregister(&mtd->dev);
+
 		/* No need to get a refcount on the module containing
 		   the notifier, since we hold the mtd_table_mutex */
 		list_for_each_entry(not, &mtd_notifiers, list)
@@ -393,28 +597,38 @@ done:
         return ((count < begin+len-off) ? count : begin+len-off);
 }
 
+#endif /* CONFIG_PROC_FS */
+
 /*====================================================================*/
 /* Init code */
 
 static int __init init_mtd(void)
 {
+	mtd_class = class_create(THIS_MODULE, "mtd");
+
+	if (IS_ERR(mtd_class)) {
+		pr_err("Error creating mtd class.\n");
+		return PTR_ERR(mtd_class);
+	}
+#ifdef CONFIG_PROC_FS
 	if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
 		proc_mtd->read_proc = mtd_read_proc;
+#endif /* CONFIG_PROC_FS */
 	return 0;
 }
 
 static void __exit cleanup_mtd(void)
 {
+#ifdef CONFIG_PROC_FS
         if (proc_mtd)
 		remove_proc_entry( "mtd", NULL);
+#endif /* CONFIG_PROC_FS */
+	class_destroy(mtd_class);
 }
 
 module_init(init_mtd);
 module_exit(cleanup_mtd);
 
-#endif /* CONFIG_PROC_FS */
-
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
 MODULE_DESCRIPTION("Core MTD registration and access routines");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdoops.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdoops.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdoops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdoops.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,6 +44,7 @@ static struct mtdoops_context {
 	int oops_pages;
 	int nextpage;
 	int nextcount;
+	char *name;
 
 	void *oops_buf;
 
@@ -273,6 +274,9 @@ static void mtdoops_notify_add(struct mt
 {
 	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;
 
@@ -357,8 +361,10 @@ mtdoops_console_write(struct console *co
 	spin_lock_irqsave(&cxt->writecount_lock, flags);
 
 	/* Check ready status didn't change whilst waiting for the lock */
-	if (!cxt->ready)
+	if (!cxt->ready) {
+		spin_unlock_irqrestore(&cxt->writecount_lock, flags);
 		return;
+	}
 
 	if (cxt->writecount == 0) {
 		u32 *stamp = cxt->oops_buf;
@@ -383,8 +389,12 @@ static int __init mtdoops_console_setup(
 {
 	struct mtdoops_context *cxt = co->data;
 
-	if (cxt->mtd_index != -1)
+	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;
 
@@ -412,6 +422,7 @@ static int __init mtdoops_console_init(v
 
 	cxt->mtd_index = -1;
 	cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
+	spin_lock_init(&cxt->writecount_lock);
 
 	if (!cxt->oops_buf) {
 		printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
@@ -432,6 +443,7 @@ static void __exit mtdoops_console_exit(
 
 	unregister_mtd_user(&mtdoops_notifier);
 	unregister_console(&mtdoops_console);
+	kfree(cxt->name);
 	vfree(cxt->oops_buf);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdpart.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdpart.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdpart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdpart.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,8 +48,11 @@ static int part_read(struct mtd_info *mt
 		size_t *retlen, u_char *buf)
 {
 	struct mtd_part *part = PART(mtd);
+	struct mtd_ecc_stats stats;
 	int res;
 
+	stats = part->master->ecc_stats;
+
 	if (from >= mtd->size)
 		len = 0;
 	else if (from + len > mtd->size)
@@ -58,9 +61,9 @@ static int part_read(struct mtd_info *mt
 				   len, retlen, buf);
 	if (unlikely(res)) {
 		if (res == -EUCLEAN)
-			mtd->ecc_stats.corrected++;
+			mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
 		if (res == -EBADMSG)
-			mtd->ecc_stats.failed++;
+			mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
 	}
 	return res;
 }
@@ -84,6 +87,18 @@ static void part_unpoint(struct mtd_info
 	part->master->unpoint(part->master, from + part->offset, len);
 }
 
+static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
+					    unsigned long len,
+					    unsigned long offset,
+					    unsigned long flags)
+{
+	struct mtd_part *part = PART(mtd);
+
+	offset += part->offset;
+	return part->master->get_unmapped_area(part->master, len, offset,
+					       flags);
+}
+
 static int part_read_oob(struct mtd_info *mtd, loff_t from,
 		struct mtd_oob_ops *ops)
 {
@@ -342,6 +357,12 @@ static struct mtd_part *add_one_partitio
 
 	slave->mtd.name = part->name;
 	slave->mtd.owner = master->owner;
+	slave->mtd.backing_dev_info = master->backing_dev_info;
+
+	/* NOTE:  we don't arrange MTDs as a tree; it'd be error-prone
+	 * to have the same data be in two different partitions.
+	 */
+	slave->mtd.dev.parent = master->dev.parent;
 
 	slave->mtd.read = part_read;
 	slave->mtd.write = part_write;
@@ -354,6 +375,8 @@ static struct mtd_part *add_one_partitio
 		slave->mtd.unpoint = part_unpoint;
 	}
 
+	if (master->get_unmapped_area)
+		slave->mtd.get_unmapped_area = part_get_unmapped_area;
 	if (master->read_oob)
 		slave->mtd.read_oob = part_read_oob;
 	if (master->write_oob)
@@ -493,7 +516,9 @@ out_register:
  * This function, given a master MTD object and a partition table, creates
  * and registers slave MTD objects which are bound to the master according to
  * the partition definitions.
- * (Q: should we register the master MTD object as well?)
+ *
+ * We don't register the master, or expect the caller to have done so,
+ * for reasons of data integrity.
  */
 
 int add_mtd_partitions(struct mtd_info *master,
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/mtdsuper.c linux-libre-2.6.30-gnu1/drivers/mtd/mtdsuper.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/mtdsuper.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/mtdsuper.c	2009-06-09 23:05:27.000000000 -0400
@@ -74,20 +74,22 @@ static int get_sb_mtd_aux(struct file_sy
 
 	ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
 	if (ret < 0) {
-		up_write(&sb->s_umount);
-		deactivate_super(sb);
+		deactivate_locked_super(sb);
 		return ret;
 	}
 
 	/* go */
 	sb->s_flags |= MS_ACTIVE;
-	return simple_set_mnt(mnt, sb);
+	simple_set_mnt(mnt, sb);
+
+	return 0;
 
 	/* new mountpoint for an already mounted superblock */
 already_mounted:
 	DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
 	      mtd->index, mtd->name);
-	ret = simple_set_mnt(mnt, sb);
+	simple_set_mnt(mnt, sb);
+	ret = 0;
 	goto out_put;
 
 out_error:
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/bf5xx_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/bf5xx_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/bf5xx_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/bf5xx_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -552,7 +552,6 @@ static void bf5xx_nand_dma_write_buf(str
 static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
 {
 	int ret;
-	unsigned short val;
 
 	/* Do not use dma */
 	if (!hardware_ecc)
@@ -560,13 +559,6 @@ static int bf5xx_nand_dma_init(struct bf
 
 	init_completion(&info->dma_completion);
 
-#ifdef CONFIG_BF54x
-	/* Setup DMAC1 channel mux for NFC which shared with SDH */
-	val = bfin_read_DMAC1_PERIMUX();
-	val &= 0xFFFE;
-	bfin_write_DMAC1_PERIMUX(val);
-	SSYNC();
-#endif
 	/* Request NFC DMA channel */
 	ret = request_dma(CH_NFC, "BF5XX NFC driver");
 	if (ret < 0) {
@@ -574,7 +566,13 @@ static int bf5xx_nand_dma_init(struct bf
 		return ret;
 	}
 
-	set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info);
+#ifdef CONFIG_BF54x
+	/* Setup DMAC1 channel mux for NFC which shared with SDH */
+	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
+	SSYNC();
+#endif
+
+	set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
 
 	/* Turn off the DMA channel first */
 	disable_dma(CH_NFC);
@@ -632,7 +630,7 @@ static int bf5xx_nand_hw_init(struct bf5
 /*
  * Device management interface
  */
-static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
+static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
 {
 	struct mtd_info *mtd = &info->mtd;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/cafe_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/cafe_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/cafe_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/cafe_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -332,7 +332,7 @@ static void cafe_select_chip(struct mtd_
 		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
 }
 
-static int cafe_nand_interrupt(int irq, void *id)
+static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 {
 	struct mtd_info *mtd = id;
 	struct cafe_priv *cafe = mtd->priv;
@@ -654,6 +654,7 @@ static int __devinit cafe_nand_probe(str
 	}
 	cafe = (void *)(&mtd[1]);
 
+	mtd->dev.parent = &pdev->dev;
 	mtd->priv = cafe;
 	mtd->owner = THIS_MODULE;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/cmx270_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/cmx270_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/cmx270_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/cmx270_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,8 +26,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
 
 #define GPIO_NAND_CS	(11)
 #define GPIO_NAND_RB	(89)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/davinci_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/davinci_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/davinci_nand.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/davinci_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,571 @@
+/*
+ * davinci_nand.c - NAND Flash Driver for DaVinci family chips
+ *
+ * Copyright Â© 2006 Texas Instruments.
+ *
+ * Port to 2.6.23 Copyright Â© 2008 by:
+ *   Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ *   Troy Kisky <troy.kisky@boundarydevices.com>
+ *   Dirk Behme <Dirk.Behme@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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/nand.h>
+
+#include <asm/mach-types.h>
+
+
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips.  It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
+struct davinci_nand_info {
+	struct mtd_info		mtd;
+	struct nand_chip	chip;
+
+	struct device		*dev;
+	struct clk		*clk;
+	bool			partitioned;
+
+	void __iomem		*base;
+	void __iomem		*vaddr;
+
+	uint32_t		ioaddr;
+	uint32_t		current_cs;
+
+	uint32_t		mask_chipsel;
+	uint32_t		mask_ale;
+	uint32_t		mask_cle;
+
+	uint32_t		core_chipsel;
+};
+
+static DEFINE_SPINLOCK(davinci_nand_lock);
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
+
+
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+		int offset)
+{
+	return __raw_readl(info->base + offset);
+}
+
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+		int offset, unsigned long value)
+{
+	__raw_writel(value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Access to hardware control lines:  ALE, CLE, secondary chipselect.
+ */
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+				   unsigned int ctrl)
+{
+	struct davinci_nand_info	*info = to_davinci_nand(mtd);
+	uint32_t			addr = info->current_cs;
+	struct nand_chip		*nand = mtd->priv;
+
+	/* Did the control lines change? */
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
+			addr |= info->mask_cle;
+		else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
+			addr |= info->mask_ale;
+
+		nand->IO_ADDR_W = (void __iomem __force *)addr;
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct davinci_nand_info	*info = to_davinci_nand(mtd);
+	uint32_t			addr = info->ioaddr;
+
+	/* maybe kick in a second chipselect */
+	if (chip > 0)
+		addr |= info->mask_chipsel;
+	info->current_cs = addr;
+
+	info->chip.IO_ADDR_W = (void __iomem __force *)addr;
+	info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 1-bit hardware ECC ... context maintained for each core chipselect
+ */
+
+static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	return davinci_nand_readl(info, NANDF1ECC_OFFSET
+			+ 4 * info->core_chipsel);
+}
+
+static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
+{
+	struct davinci_nand_info *info;
+	uint32_t nandcfr;
+	unsigned long flags;
+
+	info = to_davinci_nand(mtd);
+
+	/* Reset ECC hardware */
+	nand_davinci_readecc_1bit(mtd);
+
+	spin_lock_irqsave(&davinci_nand_lock, flags);
+
+	/* Restart ECC hardware */
+	nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
+	nandcfr |= BIT(8 + info->core_chipsel);
+	davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
+
+	spin_unlock_irqrestore(&davinci_nand_lock, flags);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
+				      const u_char *dat, u_char *ecc_code)
+{
+	unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
+	unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
+	/* invert so that erased block ecc is correct */
+	ecc24 = ~ecc24;
+	ecc_code[0] = (u_char)(ecc24);
+	ecc_code[1] = (u_char)(ecc24 >> 8);
+	ecc_code[2] = (u_char)(ecc24 >> 16);
+
+	return 0;
+}
+
+static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
+				     u_char *read_ecc, u_char *calc_ecc)
+{
+	struct nand_chip *chip = mtd->priv;
+	uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
+					  (read_ecc[2] << 16);
+	uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
+					  (calc_ecc[2] << 16);
+	uint32_t diff = eccCalc ^ eccNand;
+
+	if (diff) {
+		if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+			/* Correctable error */
+			if ((diff >> (12 + 3)) < chip->ecc.size) {
+				dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
+				return 1;
+			} else {
+				return -1;
+			}
+		} else if (!(diff & (diff - 1))) {
+			/* Single bit ECC error in the ECC itself,
+			 * nothing to fix */
+			return 1;
+		} else {
+			/* Uncorrectable error */
+			return -1;
+		}
+
+	}
+	return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE:  NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
+ * how these chips are normally wired.  This translates to both 8 and 16
+ * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+ *
+ * For now we assume that configuration, or any other one which ignores
+ * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
+ * and have that transparently morphed into multiple NAND operations.
+ */
+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+		ioread32_rep(chip->IO_ADDR_R, buf, len >> 2);
+	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+		ioread16_rep(chip->IO_ADDR_R, buf, len >> 1);
+	else
+		ioread8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+static void nand_davinci_write_buf(struct mtd_info *mtd,
+		const uint8_t *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+		iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2);
+	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+		iowrite16_rep(chip->IO_ADDR_R, buf, len >> 1);
+	else
+		iowrite8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+/*
+ * Check hardware register for wait status. Returns 1 if device is ready,
+ * 0 if it is still busy.
+ */
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+}
+
+static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
+{
+	uint32_t regval, a1cr;
+
+	/*
+	 * NAND FLASH timings @ PLL1 == 459 MHz
+	 *  - AEMIF.CLK freq   = PLL1/6 = 459/6 = 76.5 MHz
+	 *  - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
+	 */
+	regval = 0
+		| (0 << 31)           /* selectStrobe */
+		| (0 << 30)           /* extWait (never with NAND) */
+		| (1 << 26)           /* writeSetup      10 ns */
+		| (3 << 20)           /* writeStrobe     40 ns */
+		| (1 << 17)           /* writeHold       10 ns */
+		| (0 << 13)           /* readSetup       10 ns */
+		| (3 << 7)            /* readStrobe      60 ns */
+		| (0 << 4)            /* readHold        10 ns */
+		| (3 << 2)            /* turnAround      ?? ns */
+		| (0 << 0)            /* asyncSize       8-bit bus */
+		;
+	a1cr = davinci_nand_readl(info, A1CR_OFFSET);
+	if (a1cr != regval) {
+		dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
+		       "reg to 0x%08x, was 0x%08x, should be done by " \
+		       "bootloader.\n", regval, a1cr);
+		davinci_nand_writel(info, A1CR_OFFSET, regval);
+	}
+}
+
+/*----------------------------------------------------------------------*/
+
+static int __init nand_davinci_probe(struct platform_device *pdev)
+{
+	struct davinci_nand_pdata	*pdata = pdev->dev.platform_data;
+	struct davinci_nand_info	*info;
+	struct resource			*res1;
+	struct resource			*res2;
+	void __iomem			*vaddr;
+	void __iomem			*base;
+	int				ret;
+	uint32_t			val;
+	nand_ecc_modes_t		ecc_mode;
+
+	/* which external chipselect will we be managing? */
+	if (pdev->id < 0 || pdev->id > 3)
+		return -ENODEV;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&pdev->dev, "unable to allocate memory\n");
+		ret = -ENOMEM;
+		goto err_nomem;
+	}
+
+	platform_set_drvdata(pdev, info);
+
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res1 || !res2) {
+		dev_err(&pdev->dev, "resource missing\n");
+		ret = -EINVAL;
+		goto err_nomem;
+	}
+
+	vaddr = ioremap(res1->start, res1->end - res1->start);
+	base = ioremap(res2->start, res2->end - res2->start);
+	if (!vaddr || !base) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		ret = -EINVAL;
+		goto err_ioremap;
+	}
+
+	info->dev		= &pdev->dev;
+	info->base		= base;
+	info->vaddr		= vaddr;
+
+	info->mtd.priv		= &info->chip;
+	info->mtd.name		= dev_name(&pdev->dev);
+	info->mtd.owner		= THIS_MODULE;
+
+	info->mtd.dev.parent	= &pdev->dev;
+
+	info->chip.IO_ADDR_R	= vaddr;
+	info->chip.IO_ADDR_W	= vaddr;
+	info->chip.chip_delay	= 0;
+	info->chip.select_chip	= nand_davinci_select_chip;
+
+	/* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+	info->chip.options	= pdata ? pdata->options : 0;
+
+	info->ioaddr		= (uint32_t __force) vaddr;
+
+	info->current_cs	= info->ioaddr;
+	info->core_chipsel	= pdev->id;
+	info->mask_chipsel	= pdata->mask_chipsel;
+
+	/* use nandboot-capable ALE/CLE masks by default */
+	if (pdata && pdata->mask_ale)
+		info->mask_ale	= pdata->mask_cle;
+	else
+		info->mask_ale	= MASK_ALE;
+	if (pdata && pdata->mask_cle)
+		info->mask_cle	= pdata->mask_cle;
+	else
+		info->mask_cle	= MASK_CLE;
+
+	/* Set address of hardware control function */
+	info->chip.cmd_ctrl	= nand_davinci_hwcontrol;
+	info->chip.dev_ready	= nand_davinci_dev_ready;
+
+	/* Speed up buffer I/O */
+	info->chip.read_buf     = nand_davinci_read_buf;
+	info->chip.write_buf    = nand_davinci_write_buf;
+
+	/* use board-specific ECC config; else, the best available */
+	if (pdata)
+		ecc_mode = pdata->ecc_mode;
+	else
+		ecc_mode = NAND_ECC_HW;
+
+	switch (ecc_mode) {
+	case NAND_ECC_NONE:
+	case NAND_ECC_SOFT:
+		break;
+	case NAND_ECC_HW:
+		info->chip.ecc.calculate = nand_davinci_calculate_1bit;
+		info->chip.ecc.correct = nand_davinci_correct_1bit;
+		info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
+		info->chip.ecc.size = 512;
+		info->chip.ecc.bytes = 3;
+		break;
+	case NAND_ECC_HW_SYNDROME:
+		/* FIXME implement */
+		info->chip.ecc.size = 512;
+		info->chip.ecc.bytes = 10;
+
+		dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
+		/* FALL THROUGH */
+	default:
+		ret = -EINVAL;
+		goto err_ecc;
+	}
+	info->chip.ecc.mode = ecc_mode;
+
+	info->clk = clk_get(&pdev->dev, "aemif");
+	if (IS_ERR(info->clk)) {
+		ret = PTR_ERR(info->clk);
+		dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
+		goto err_clk;
+	}
+
+	ret = clk_enable(info->clk);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
+			ret);
+		goto err_clk_enable;
+	}
+
+	/* EMIF timings should normally be set by the boot loader,
+	 * especially after boot-from-NAND.  The *only* reason to
+	 * have this special casing for the DM6446 EVM is to work
+	 * with boot-from-NOR ... with CS0 manually re-jumpered
+	 * (after startup) so it addresses the NAND flash, not NOR.
+	 * Even for dev boards, that's unusually rude...
+	 */
+	if (machine_is_davinci_evm())
+		nand_dm6446evm_flash_init(info);
+
+	spin_lock_irq(&davinci_nand_lock);
+
+	/* put CSxNAND into NAND mode */
+	val = davinci_nand_readl(info, NANDFCR_OFFSET);
+	val |= BIT(info->core_chipsel);
+	davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+	spin_unlock_irq(&davinci_nand_lock);
+
+	/* Scan to find existence of the device(s) */
+	ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1);
+	if (ret < 0) {
+		dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
+		goto err_scan;
+	}
+
+	if (mtd_has_partitions()) {
+		struct mtd_partition	*mtd_parts = NULL;
+		int			mtd_parts_nb = 0;
+
+		if (mtd_has_cmdlinepart()) {
+			static const char *probes[] __initconst =
+				{ "cmdlinepart", NULL };
+
+			const char		*master_name;
+
+			/* Set info->mtd.name = 0 temporarily */
+			master_name		= info->mtd.name;
+			info->mtd.name		= (char *)0;
+
+			/* info->mtd.name == 0, means: don't bother checking
+			   <mtd-id> */
+			mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
+							    &mtd_parts, 0);
+
+			/* Restore info->mtd.name */
+			info->mtd.name = master_name;
+		}
+
+		if (mtd_parts_nb <= 0 && pdata) {
+			mtd_parts = pdata->parts;
+			mtd_parts_nb = pdata->nr_parts;
+		}
+
+		/* Register any partitions */
+		if (mtd_parts_nb > 0) {
+			ret = add_mtd_partitions(&info->mtd,
+					mtd_parts, mtd_parts_nb);
+			if (ret == 0)
+				info->partitioned = true;
+		}
+
+	} else if (pdata && pdata->nr_parts) {
+		dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
+				pdata->nr_parts, info->mtd.name);
+	}
+
+	/* If there's no partition info, just package the whole chip
+	 * as a single MTD device.
+	 */
+	if (!info->partitioned)
+		ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
+
+	if (ret < 0)
+		goto err_scan;
+
+	val = davinci_nand_readl(info, NRCSR_OFFSET);
+	dev_info(&pdev->dev, "controller rev. %d.%d\n",
+	       (val >> 8) & 0xff, val & 0xff);
+
+	return 0;
+
+err_scan:
+	clk_disable(info->clk);
+
+err_clk_enable:
+	clk_put(info->clk);
+
+err_ecc:
+err_clk:
+err_ioremap:
+	if (base)
+		iounmap(base);
+	if (vaddr)
+		iounmap(vaddr);
+
+err_nomem:
+	kfree(info);
+	return ret;
+}
+
+static int __exit nand_davinci_remove(struct platform_device *pdev)
+{
+	struct davinci_nand_info *info = platform_get_drvdata(pdev);
+	int status;
+
+	if (mtd_has_partitions() && info->partitioned)
+		status = del_mtd_partitions(&info->mtd);
+	else
+		status = del_mtd_device(&info->mtd);
+
+	iounmap(info->base);
+	iounmap(info->vaddr);
+
+	nand_release(&info->mtd);
+
+	clk_disable(info->clk);
+	clk_put(info->clk);
+
+	kfree(info);
+
+	return 0;
+}
+
+static struct platform_driver nand_davinci_driver = {
+	.remove		= __exit_p(nand_davinci_remove),
+	.driver		= {
+		.name	= "davinci_nand",
+	},
+};
+MODULE_ALIAS("platform:davinci_nand");
+
+static int __init nand_davinci_init(void)
+{
+	return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
+}
+module_init(nand_davinci_init);
+
+static void __exit nand_davinci_exit(void)
+{
+	platform_driver_unregister(&nand_davinci_driver);
+}
+module_exit(nand_davinci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("Davinci NAND flash driver");
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/diskonchip.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/diskonchip.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/diskonchip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/diskonchip.c	2009-06-09 23:05:27.000000000 -0400
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/excite_nandflash.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/excite_nandflash.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/excite_nandflash.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/excite_nandflash.c	2009-06-09 23:05:27.000000000 -0400
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct m
  * The binding to the mtd and all allocated
  * resources are released.
  */
-static int __exit excite_nand_remove(struct device *dev)
+static int __exit excite_nand_remove(struct platform_device *dev)
 {
-	struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+	struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
 
-	dev_set_drvdata(dev, NULL);
+	platform_set_drvdata(dev, NULL);
 
 	if (unlikely(!this)) {
 		printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(str
  * it can allocate all necessary resources then calls the
  * nand layer to look for devices.
 */
-static int __init excite_nand_probe(struct device *dev)
+static int __init excite_nand_probe(struct platform_device *pdev)
 {
-	struct platform_device * const pdev = to_platform_device(dev);
 	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 */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(stru
 	}
 
 	/* bind private data into driver */
-	dev_set_drvdata(dev, drvdata);
+	platform_set_drvdata(pdev, drvdata);
 
 	/* allocate and map the resource */
 	drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(stru
 	return 0;
 }
 
-static struct device_driver excite_nand_driver = {
-	.name = "excite_nand",
-	.bus = &platform_bus_type,
+static struct platform_driver excite_nand_driver = {
+	.driver = {
+		.name = "excite_nand",
+		.owner		= THIS_MODULE,
+	},
 	.probe = excite_nand_probe,
-	.remove = __exit_p(excite_nand_remove)
+	.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 driver_register(&excite_nand_driver);
+	return platform_driver_register(&excite_nand_driver);
 }
 
 static void __exit excite_nand_exit(void)
 {
-	driver_unregister(&excite_nand_driver);
+	platform_driver_unregister(&excite_nand_driver);
 }
 
 module_init(excite_nand_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/fsl_upm.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/fsl_upm.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/fsl_upm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/fsl_upm.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,10 @@
 #include <linux/io.h>
 #include <asm/fsl_lbc.h>
 
+#define FSL_UPM_WAIT_RUN_PATTERN  0x1
+#define FSL_UPM_WAIT_WRITE_BYTE   0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
 struct fsl_upm_nand {
 	struct device *dev;
 	struct mtd_info mtd;
@@ -36,8 +40,12 @@ struct fsl_upm_nand {
 	uint8_t upm_addr_offset;
 	uint8_t upm_cmd_offset;
 	void __iomem *io_base;
-	int rnb_gpio;
+	int rnb_gpio[NAND_MAX_CHIPS];
+	uint32_t mchip_offsets[NAND_MAX_CHIPS];
+	uint32_t mchip_count;
+	uint32_t mchip_number;
 	int chip_delay;
+	uint32_t wait_flags;
 };
 
 #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -46,7 +54,7 @@ static int fun_chip_ready(struct mtd_inf
 {
 	struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
 
-	if (gpio_get_value(fun->rnb_gpio))
+	if (gpio_get_value(fun->rnb_gpio[fun->mchip_number]))
 		return 1;
 
 	dev_vdbg(fun->dev, "busy\n");
@@ -55,9 +63,9 @@ static int fun_chip_ready(struct mtd_inf
 
 static void fun_wait_rnb(struct fsl_upm_nand *fun)
 {
-	int cnt = 1000000;
+	if (fun->rnb_gpio[fun->mchip_number] >= 0) {
+		int cnt = 1000000;
 
-	if (fun->rnb_gpio >= 0) {
 		while (--cnt && !fun_chip_ready(&fun->mtd))
 			cpu_relax();
 		if (!cnt)
@@ -69,7 +77,9 @@ static void fun_wait_rnb(struct fsl_upm_
 
 static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
+	struct nand_chip *chip = mtd->priv;
 	struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
+	u32 mar;
 
 	if (!(ctrl & fun->last_ctrl)) {
 		fsl_upm_end_pattern(&fun->upm);
@@ -87,9 +97,28 @@ static void fun_cmd_ctrl(struct mtd_info
 			fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
 	}
 
-	fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
+	mar = (cmd << (32 - fun->upm.width)) |
+		fun->mchip_offsets[fun->mchip_number];
+	fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar);
 
-	fun_wait_rnb(fun);
+	if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+		fun_wait_rnb(fun);
+}
+
+static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
+
+	if (mchip_nr == -1) {
+		chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+	} else if (mchip_nr >= 0) {
+		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;
+	} else {
+		BUG();
+	}
 }
 
 static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -115,8 +144,11 @@ static void fun_write_buf(struct mtd_inf
 
 	for (i = 0; i < len; i++) {
 		out_8(fun->chip.IO_ADDR_W, buf[i]);
-		fun_wait_rnb(fun);
+		if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+			fun_wait_rnb(fun);
 	}
+	if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+		fun_wait_rnb(fun);
 }
 
 static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
@@ -137,8 +169,10 @@ static int __devinit fun_chip_init(struc
 	fun->chip.read_buf = fun_read_buf;
 	fun->chip.write_buf = fun_write_buf;
 	fun->chip.ecc.mode = NAND_ECC_SOFT;
+	if (fun->mchip_count > 1)
+		fun->chip.select_chip = fun_select_chip;
 
-	if (fun->rnb_gpio >= 0)
+	if (fun->rnb_gpio[0] >= 0)
 		fun->chip.dev_ready = fun_chip_ready;
 
 	fun->mtd.priv = &fun->chip;
@@ -155,7 +189,7 @@ static int __devinit fun_chip_init(struc
 		goto err;
 	}
 
-	ret = nand_scan(&fun->mtd, 1);
+	ret = nand_scan(&fun->mtd, fun->mchip_count);
 	if (ret)
 		goto err;
 
@@ -185,8 +219,10 @@ static int __devinit fun_probe(struct of
 	struct fsl_upm_nand *fun;
 	struct resource io_res;
 	const uint32_t *prop;
+	int rnb_gpio;
 	int ret;
 	int size;
+	int i;
 
 	fun = kzalloc(sizeof(*fun), GFP_KERNEL);
 	if (!fun)
@@ -208,7 +244,7 @@ static int __devinit fun_probe(struct of
 	if (!prop || size != sizeof(uint32_t)) {
 		dev_err(&ofdev->dev, "can't get UPM address offset\n");
 		ret = -EINVAL;
-		goto err2;
+		goto err1;
 	}
 	fun->upm_addr_offset = *prop;
 
@@ -216,21 +252,40 @@ static int __devinit fun_probe(struct of
 	if (!prop || size != sizeof(uint32_t)) {
 		dev_err(&ofdev->dev, "can't get UPM command offset\n");
 		ret = -EINVAL;
-		goto err2;
+		goto err1;
 	}
 	fun->upm_cmd_offset = *prop;
 
-	fun->rnb_gpio = of_get_gpio(ofdev->node, 0);
-	if (fun->rnb_gpio >= 0) {
-		ret = gpio_request(fun->rnb_gpio, dev_name(&ofdev->dev));
-		if (ret) {
-			dev_err(&ofdev->dev, "can't request RNB gpio\n");
+	prop = of_get_property(ofdev->node,
+			       "fsl,upm-addr-line-cs-offsets", &size);
+	if (prop && (size / sizeof(uint32_t)) > 0) {
+		fun->mchip_count = size / sizeof(uint32_t);
+		if (fun->mchip_count >= NAND_MAX_CHIPS) {
+			dev_err(&ofdev->dev, "too much multiple chips\n");
+			goto err1;
+		}
+		for (i = 0; i < fun->mchip_count; i++)
+			fun->mchip_offsets[i] = prop[i];
+	} else {
+		fun->mchip_count = 1;
+	}
+
+	for (i = 0; i < fun->mchip_count; i++) {
+		fun->rnb_gpio[i] = -1;
+		rnb_gpio = of_get_gpio(ofdev->node, i);
+		if (rnb_gpio >= 0) {
+			ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
+			if (ret) {
+				dev_err(&ofdev->dev,
+					"can't request RNB gpio #%d\n", i);
+				goto err2;
+			}
+			gpio_direction_input(rnb_gpio);
+			fun->rnb_gpio[i] = rnb_gpio;
+		} else if (rnb_gpio == -EINVAL) {
+			dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i);
 			goto err2;
 		}
-		gpio_direction_input(fun->rnb_gpio);
-	} else if (fun->rnb_gpio == -EINVAL) {
-		dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
-		goto err2;
 	}
 
 	prop = of_get_property(ofdev->node, "chip-delay", NULL);
@@ -239,8 +294,15 @@ static int __devinit fun_probe(struct of
 	else
 		fun->chip_delay = 50;
 
+	prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+	if (prop && size == sizeof(uint32_t))
+		fun->wait_flags = *prop;
+	else
+		fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
+				  FSL_UPM_WAIT_WRITE_BYTE;
+
 	fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
-					  io_res.end - io_res.start + 1);
+					    io_res.end - io_res.start + 1);
 	if (!fun->io_base) {
 		ret = -ENOMEM;
 		goto err2;
@@ -257,8 +319,11 @@ static int __devinit fun_probe(struct of
 
 	return 0;
 err2:
-	if (fun->rnb_gpio >= 0)
-		gpio_free(fun->rnb_gpio);
+	for (i = 0; i < fun->mchip_count; i++) {
+		if (fun->rnb_gpio[i] < 0)
+			break;
+		gpio_free(fun->rnb_gpio[i]);
+	}
 err1:
 	kfree(fun);
 
@@ -268,12 +333,16 @@ err1:
 static int __devexit fun_remove(struct of_device *ofdev)
 {
 	struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
+	int i;
 
 	nand_release(&fun->mtd);
 	kfree(fun->mtd.name);
 
-	if (fun->rnb_gpio >= 0)
-		gpio_free(fun->rnb_gpio);
+	for (i = 0; i < fun->mchip_count; i++) {
+		if (fun->rnb_gpio[i] < 0)
+			break;
+		gpio_free(fun->rnb_gpio[i]);
+	}
 
 	kfree(fun);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/Kconfig linux-libre-2.6.30-gnu1/drivers/mtd/nand/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -273,7 +273,7 @@ config MTD_NAND_CAFE
 
 config MTD_NAND_CS553X
 	tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
-	depends on X86_32 && (X86_PC || X86_GENERICARCH)
+	depends on X86_32
 	help
 	  The CS553x companion chips for the AMD Geode processor
 	  include NAND flash controllers with built-in hardware ECC
@@ -334,7 +334,7 @@ config MTD_NAND_ATMEL_ECC_NONE
 endchoice
 
 config MTD_NAND_PXA3xx
-	bool "Support for NAND flash devices on PXA3xx"
+	tristate "Support for NAND flash devices on PXA3xx"
 	depends on MTD_NAND && PXA3xx
 	help
 	  This enables the driver for the NAND flash device found on
@@ -427,4 +427,23 @@ config MTD_NAND_SH_FLCTL
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
 	  for NAND Flash using FLCTL. This driver support SH7723.
 
+config MTD_NAND_DAVINCI
+        tristate "Support NAND on DaVinci SoC"
+        depends on ARCH_DAVINCI
+        help
+	  Enable the driver for NAND flash chips on Texas Instruments
+	  DaVinci processors.
+
+config MTD_NAND_TXX9NDFMC
+	tristate "NAND Flash support for TXx9 SoC"
+	depends on SOC_TX4938 || SOC_TX4939
+	help
+	  This enables the NAND flash controller on the TXx9 SoCs.
+
+config MTD_NAND_SOCRATES
+	tristate "Support for NAND on Socrates board"
+	depends on MTD_NAND && SOCRATES
+	help
+	  Enables support for NAND Flash chips wired onto Socrates board.
+
 endif # MTD_NAND
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/Makefile linux-libre-2.6.30-gnu1/drivers/mtd/nand/Makefile
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550
 obj-$(CONFIG_MTD_NAND_BF5XX)		+= bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o
 obj-$(CONFIG_MTD_NAND_S3C2410)		+= s3c2410.o
+obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
 obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= diskonchip.o
 obj-$(CONFIG_MTD_NAND_H1900)		+= h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)	+= rtc_from4.o
@@ -36,5 +37,7 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_
 obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
 obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
+obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
+obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 
 nand-objs := nand_base.o nand_bbt.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/mxc_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/mxc_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/mxc_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/mxc_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -831,6 +831,7 @@ static void mxc_nand_command(struct mtd_
 		break;
 
 	case NAND_CMD_READID:
+		host->col_addr = 0;
 		send_read_id(host);
 		break;
 
@@ -866,6 +867,8 @@ static int __init mxcnd_probe(struct pla
 	mtd = &host->mtd;
 	mtd->priv = this;
 	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = &pdev->dev;
+	mtd->name = "mxc_nand";
 
 	/* 50 us command delay time */
 	this->chip_delay = 5;
@@ -880,9 +883,11 @@ static int __init mxcnd_probe(struct pla
 	this->read_buf = mxc_nand_read_buf;
 	this->verify_buf = mxc_nand_verify_buf;
 
-	host->clk = clk_get(&pdev->dev, "nfc_clk");
-	if (IS_ERR(host->clk))
+	host->clk = clk_get(&pdev->dev, "nfc");
+	if (IS_ERR(host->clk)) {
+		err = PTR_ERR(host->clk);
 		goto eclk;
+	}
 
 	clk_enable(host->clk);
 	host->clk_act = 1;
@@ -895,7 +900,7 @@ static int __init mxcnd_probe(struct pla
 
 	host->regs = ioremap(res->start, res->end - res->start + 1);
 	if (!host->regs) {
-		err = -EIO;
+		err = -ENOMEM;
 		goto eres;
 	}
 
@@ -1010,30 +1015,35 @@ static int __devexit mxcnd_remove(struct
 #ifdef CONFIG_PM
 static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct mtd_info *info = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct nand_chip *nand_chip = mtd->priv;
+	struct mxc_nand_host *host = nand_chip->priv;
 	int ret = 0;
 
 	DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n");
-	if (info)
-		ret = info->suspend(info);
-
-	/* Disable the NFC clock */
-	clk_disable(nfc_clk);	/* FIXME */
+	if (mtd) {
+		ret = mtd->suspend(mtd);
+		/* Disable the NFC clock */
+		clk_disable(host->clk);
+	}
 
 	return ret;
 }
 
 static int mxcnd_resume(struct platform_device *pdev)
 {
-	struct mtd_info *info = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct nand_chip *nand_chip = mtd->priv;
+	struct mxc_nand_host *host = nand_chip->priv;
 	int ret = 0;
 
 	DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
-	/* Enable the NFC clock */
-	clk_enable(nfc_clk);	/* FIXME */
 
-	if (info)
-		info->resume(info);
+	if (mtd) {
+		/* Enable the NFC clock */
+		clk_enable(host->clk);
+		mtd->resume(mtd);
+	}
 
 	return ret;
 }
@@ -1054,13 +1064,7 @@ static struct platform_driver mxcnd_driv
 
 static int __init mxc_nd_init(void)
 {
-	/* Register the device driver structure. */
-	pr_info("MXC MTD nand Driver\n");
-	if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) {
-		printk(KERN_ERR "Driver register failed for mxcnd_driver\n");
-		return -ENODEV;
-	}
-	return 0;
+	return platform_driver_probe(&mxcnd_driver, mxcnd_probe);
 }
 
 static void __exit mxc_nd_cleanup(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/nand_base.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/nand_base.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/nand_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/nand_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,6 +82,20 @@ static struct nand_ecclayout nand_oob_64
 		 .length = 38}}
 };
 
+static struct nand_ecclayout nand_oob_128 = {
+	.eccbytes = 48,
+	.eccpos = {
+		   80, 81, 82, 83, 84, 85, 86, 87,
+		   88, 89, 90, 91, 92, 93, 94, 95,
+		   96, 97, 98, 99, 100, 101, 102, 103,
+		   104, 105, 106, 107, 108, 109, 110, 111,
+		   112, 113, 114, 115, 116, 117, 118, 119,
+		   120, 121, 122, 123, 124, 125, 126, 127},
+	.oobfree = {
+		{.offset = 2,
+		 .length = 78}}
+};
+
 static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
 			   int new_state);
 
@@ -748,6 +762,8 @@ static int nand_wait(struct mtd_info *mt
  * @mtd:	mtd info structure
  * @chip:	nand chip info structure
  * @buf:	buffer to store read data
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
  */
 static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 			      uint8_t *buf)
@@ -758,6 +774,47 @@ static int nand_read_page_raw(struct mtd
 }
 
 /**
+ * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ *
+ * We need a special oob layout and handling even when OOB isn't used.
+ */
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+			      uint8_t *buf)
+{
+	int eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	uint8_t *oob = chip->oob_poi;
+	int steps, size;
+
+	for (steps = chip->ecc.steps; steps > 0; steps--) {
+		chip->read_buf(mtd, buf, eccsize);
+		buf += eccsize;
+
+		if (chip->ecc.prepad) {
+			chip->read_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->read_buf(mtd, oob, eccbytes);
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->read_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	size = mtd->oobsize - (oob - chip->oob_poi);
+	if (size)
+		chip->read_buf(mtd, oob, size);
+
+	return 0;
+}
+
+/**
  * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
  * @mtd:	mtd info structure
  * @chip:	nand chip info structure
@@ -1482,6 +1539,8 @@ static int nand_read_oob(struct mtd_info
  * @mtd:	mtd info structure
  * @chip:	nand chip info structure
  * @buf:	data buffer
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
  */
 static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf)
@@ -1491,6 +1550,44 @@ static void nand_write_page_raw(struct m
 }
 
 /**
+ * nand_write_page_raw_syndrome - [Intern] raw page write function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	data buffer
+ *
+ * We need a special oob layout and handling even when ECC isn't checked.
+ */
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+				const uint8_t *buf)
+{
+	int eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	uint8_t *oob = chip->oob_poi;
+	int steps, size;
+
+	for (steps = chip->ecc.steps; steps > 0; steps--) {
+		chip->write_buf(mtd, buf, eccsize);
+		buf += eccsize;
+
+		if (chip->ecc.prepad) {
+			chip->write_buf(mtd, oob, chip->ecc.prepad);
+			oob += chip->ecc.prepad;
+		}
+
+		chip->read_buf(mtd, oob, eccbytes);
+		oob += eccbytes;
+
+		if (chip->ecc.postpad) {
+			chip->write_buf(mtd, oob, chip->ecc.postpad);
+			oob += chip->ecc.postpad;
+		}
+	}
+
+	size = mtd->oobsize - (oob - chip->oob_poi);
+	if (size)
+		chip->write_buf(mtd, oob, size);
+}
+/**
  * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
  * @mtd:	mtd info structure
  * @chip:	nand chip info structure
@@ -1863,7 +1960,7 @@ static int nand_do_write_oob(struct mtd_
 	}
 
 	if (unlikely(ops->ooboffs >= len)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
 			"Attempt to start write outside oob\n");
 		return -EINVAL;
 	}
@@ -1873,7 +1970,7 @@ static int nand_do_write_oob(struct mtd_
 		     ops->ooboffs + ops->ooblen >
 			((mtd->size >> chip->page_shift) -
 			 (to >> chip->page_shift)) * len)) {
-		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
 			"Attempt write beyond end of device\n");
 		return -EINVAL;
 	}
@@ -1929,8 +2026,8 @@ static int nand_write_oob(struct mtd_inf
 
 	/* Do not allow writes past end of device */
 	if (ops->datbuf && (to + ops->len) > mtd->size) {
-		DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
-		      "Attempt read beyond end of device\n");
+		DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
+		      "Attempt write beyond end of device\n");
 		return -EINVAL;
 	}
 
@@ -2555,6 +2652,9 @@ int nand_scan_tail(struct mtd_info *mtd)
 		case 64:
 			chip->ecc.layout = &nand_oob_64;
 			break;
+		case 128:
+			chip->ecc.layout = &nand_oob_128;
+			break;
 		default:
 			printk(KERN_WARNING "No oob scheme defined for "
 			       "oobsize %d\n", mtd->oobsize);
@@ -2569,10 +2669,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 	 * check ECC mode, default to software if 3byte/512byte hardware ECC is
 	 * selected and we have 256 byte pagesize fallback to software ECC
 	 */
-	if (!chip->ecc.read_page_raw)
-		chip->ecc.read_page_raw = nand_read_page_raw;
-	if (!chip->ecc.write_page_raw)
-		chip->ecc.write_page_raw = nand_write_page_raw;
 
 	switch (chip->ecc.mode) {
 	case NAND_ECC_HW:
@@ -2581,6 +2677,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 			chip->ecc.read_page = nand_read_page_hwecc;
 		if (!chip->ecc.write_page)
 			chip->ecc.write_page = nand_write_page_hwecc;
+		if (!chip->ecc.read_page_raw)
+			chip->ecc.read_page_raw = nand_read_page_raw;
+		if (!chip->ecc.write_page_raw)
+			chip->ecc.write_page_raw = nand_write_page_raw;
 		if (!chip->ecc.read_oob)
 			chip->ecc.read_oob = nand_read_oob_std;
 		if (!chip->ecc.write_oob)
@@ -2602,6 +2702,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 			chip->ecc.read_page = nand_read_page_syndrome;
 		if (!chip->ecc.write_page)
 			chip->ecc.write_page = nand_write_page_syndrome;
+		if (!chip->ecc.read_page_raw)
+			chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
+		if (!chip->ecc.write_page_raw)
+			chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
 		if (!chip->ecc.read_oob)
 			chip->ecc.read_oob = nand_read_oob_syndrome;
 		if (!chip->ecc.write_oob)
@@ -2620,6 +2724,8 @@ int nand_scan_tail(struct mtd_info *mtd)
 		chip->ecc.read_page = nand_read_page_swecc;
 		chip->ecc.read_subpage = nand_read_subpage;
 		chip->ecc.write_page = nand_write_page_swecc;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
 		chip->ecc.read_oob = nand_read_oob_std;
 		chip->ecc.write_oob = nand_write_oob_std;
 		chip->ecc.size = 256;
@@ -2632,6 +2738,8 @@ int nand_scan_tail(struct mtd_info *mtd)
 		chip->ecc.read_page = nand_read_page_raw;
 		chip->ecc.write_page = nand_write_page_raw;
 		chip->ecc.read_oob = nand_read_oob_std;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
 		chip->ecc.write_oob = nand_write_oob_std;
 		chip->ecc.size = mtd->writesize;
 		chip->ecc.bytes = 0;
@@ -2676,6 +2784,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 			break;
 		case 4:
 		case 8:
+		case 16:
 			mtd->subpage_sft = 2;
 			break;
 		}
@@ -2720,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd)
 	return chip->scan_bbt(mtd);
 }
 
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
    test if this is a module _anyway_ -- they'd have to try _really_ hard
    to call us from in-kernel code if the core NAND support is modular. */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
 #define caller_is_module() \
-	module_text_address((unsigned long)__builtin_return_address(0))
+	is_module_text_address((unsigned long)__builtin_return_address(0))
 #endif
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/ndfc.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/ndfc.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/ndfc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/ndfc.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_co
 		return -ENODEV;
 
 	ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
-				   ndfc->ofdev->dev.bus_id, flash_np->name);
+			dev_name(&ndfc->ofdev->dev), flash_np->name);
 	if (!ndfc->mtd.name) {
 		ret = -ENOMEM;
 		goto err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/plat_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/plat_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/plat_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/plat_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,7 +30,7 @@ struct plat_nand_data {
 /*
  * Probe for the NAND device.
  */
-static int __init plat_nand_probe(struct platform_device *pdev)
+static int __devinit plat_nand_probe(struct platform_device *pdev)
 {
 	struct platform_nand_data *pdata = pdev->dev.platform_data;
 	struct plat_nand_data *data;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/pxa3xx_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/pxa3xx_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/pxa3xx_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/irq.h>
 
 #include <mach/dma.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa3xx_nand.h>
 
 #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
@@ -171,7 +170,13 @@ static int use_dma = 1;
 module_param(use_dma, bool, 0444);
 MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
 
-#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
+/*
+ * Default NAND flash controller configuration setup by the
+ * bootloader. This configuration is used only when pdata->keep_config is set
+ */
+static struct pxa3xx_nand_timing default_timing;
+static struct pxa3xx_nand_flash default_flash;
+
 static struct pxa3xx_nand_cmdset smallpage_cmdset = {
 	.read1		= 0x0000,
 	.read2		= 0x0050,
@@ -198,6 +203,7 @@ static struct pxa3xx_nand_cmdset largepa
 	.lock_status	= 0x007A,
 };
 
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
 static struct pxa3xx_nand_timing samsung512MbX16_timing = {
 	.tCH	= 10,
 	.tCS	= 0,
@@ -297,9 +303,23 @@ static struct pxa3xx_nand_flash *builtin
 #define NDTR1_tWHR(c)	(min((c), 15) << 4)
 #define NDTR1_tAR(c)	(min((c), 15) << 0)
 
+#define tCH_NDTR0(r)	(((r) >> 19) & 0x7)
+#define tCS_NDTR0(r)	(((r) >> 16) & 0x7)
+#define tWH_NDTR0(r)	(((r) >> 11) & 0x7)
+#define tWP_NDTR0(r)	(((r) >> 8) & 0x7)
+#define tRH_NDTR0(r)	(((r) >> 3) & 0x7)
+#define tRP_NDTR0(r)	(((r) >> 0) & 0x7)
+
+#define tR_NDTR1(r)	(((r) >> 16) & 0xffff)
+#define tWHR_NDTR1(r)	(((r) >> 4) & 0xf)
+#define tAR_NDTR1(r)	(((r) >> 0) & 0xf)
+
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)	(int)(((ns) * (clk / 1000000) / 1000) - 1)
 
+/* convert nand flash controller clock cycles to nano-seconds */
+#define cycle2ns(c, clk)	((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
+
 static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
 				   const struct pxa3xx_nand_timing *t)
 {
@@ -921,6 +941,82 @@ static int pxa3xx_nand_config_flash(stru
 	return 0;
 }
 
+static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
+				      struct pxa3xx_nand_timing *t)
+{
+	unsigned long nand_clk = clk_get_rate(info->clk);
+	uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
+	uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
+
+	t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
+	t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
+	t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
+	t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
+	t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
+	t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
+
+	t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
+	t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
+	t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
+}
+
+static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
+{
+	uint32_t ndcr = nand_readl(info, NDCR);
+	struct nand_flash_dev *type = NULL;
+	uint32_t id = -1;
+	int i;
+
+	default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
+	default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
+	default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
+	default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
+
+	if (default_flash.page_size == 2048)
+		default_flash.cmdset = &largepage_cmdset;
+	else
+		default_flash.cmdset = &smallpage_cmdset;
+
+	/* set info fields needed to __readid */
+	info->flash_info = &default_flash;
+	info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+	info->reg_ndcr = ndcr;
+
+	if (__readid(info, &id))
+		return -ENODEV;
+
+	/* Lookup the flash id */
+	id = (id >> 8) & 0xff;		/* device id is byte 2 */
+	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+		if (id == nand_flash_ids[i].id) {
+			type =  &nand_flash_ids[i];
+			break;
+		}
+	}
+
+	if (!type)
+		return -ENODEV;
+
+	/* fill the missing flash information */
+	i = __ffs(default_flash.page_per_block * default_flash.page_size);
+	default_flash.num_blocks = type->chipsize << (20 - i);
+
+	info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
+
+	/* calculate addressing information */
+	info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
+
+	if (default_flash.num_blocks * default_flash.page_per_block > 65536)
+		info->row_addr_cycles = 3;
+	else
+		info->row_addr_cycles = 2;
+
+	pxa3xx_nand_detect_timing(info, &default_timing);
+	default_flash.timing = &default_timing;
+
+	return 0;
+}
+
 static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
 				    const struct pxa3xx_nand_platform_data *pdata)
 {
@@ -928,6 +1024,10 @@ static int pxa3xx_nand_detect_flash(stru
 	uint32_t id = -1;
 	int i;
 
+	if (pdata->keep_config)
+		if (pxa3xx_nand_detect_config(info) == 0)
+			return 0;
+
 	for (i = 0; i<pdata->num_flash; ++i) {
 		f = pdata->flash + i;
 
@@ -1079,6 +1179,7 @@ static int pxa3xx_nand_probe(struct plat
 
 	this = &info->nand_chip;
 	mtd->priv = info;
+	mtd->owner = THIS_MODULE;
 
 	info->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(info->clk)) {
@@ -1118,14 +1219,14 @@ static int pxa3xx_nand_probe(struct plat
 		goto fail_put_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 fail_put_clk;
 	}
 
-	info->mmio_base = ioremap(r->start, r->end - r->start + 1);
+	info->mmio_base = ioremap(r->start, resource_size(r));
 	if (info->mmio_base == NULL) {
 		dev_err(&pdev->dev, "ioremap() failed\n");
 		ret = -ENODEV;
@@ -1174,7 +1275,7 @@ fail_free_buf:
 fail_free_io:
 	iounmap(info->mmio_base);
 fail_free_res:
-	release_mem_region(r->start, r->end - r->start + 1);
+	release_mem_region(r->start, resource_size(r));
 fail_put_clk:
 	clk_disable(info->clk);
 	clk_put(info->clk);
@@ -1187,6 +1288,7 @@ 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;
 
 	platform_set_drvdata(pdev, NULL);
 
@@ -1199,6 +1301,14 @@ static int pxa3xx_nand_remove(struct pla
 				info->data_buff, info->data_buff_phys);
 	} else
 		kfree(info->data_buff);
+
+	iounmap(info->mmio_base);
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(r->start, resource_size(r));
+
+	clk_disable(info->clk);
+	clk_put(info->clk);
+
 	kfree(mtd);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/sh_flctl.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/sh_flctl.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/sh_flctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/sh_flctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,7 +58,7 @@ static struct nand_bbt_descr flctl_4secc
 };
 
 static struct nand_bbt_descr flctl_4secc_largepage = {
-	.options = 0,
+	.options = NAND_BBT_SCAN2NDPAGE,
 	.offs = 58,
 	.len = 2,
 	.pattern = scan_ff_pattern,
@@ -149,7 +149,7 @@ static void wait_wfifo_ready(struct sh_f
 	printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
 }
 
-static int wait_recfifo_ready(struct sh_flctl *flctl)
+static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
 {
 	uint32_t timeout = LOOP_TIMEOUT_MAX;
 	int checked[4];
@@ -183,7 +183,12 @@ static int wait_recfifo_ready(struct sh_
 				uint8_t org;
 				int index;
 
-				index = data >> 16;
+				if (flctl->page_size)
+					index = (512 * sector_number) +
+						(data >> 16);
+				else
+					index = data >> 16;
+
 				org = flctl->done_buff[index];
 				flctl->done_buff[index] = org ^ (data & 0xFF);
 				checked[i] = 1;
@@ -238,14 +243,14 @@ static void read_fiforeg(struct sh_flctl
 	}
 }
 
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
+static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
 {
 	int i;
 	unsigned long *ecc_buf = (unsigned long *)buff;
 	void *fifo_addr = (void *)FLECFIFO(flctl);
 
 	for (i = 0; i < 4; i++) {
-		if (wait_recfifo_ready(flctl))
+		if (wait_recfifo_ready(flctl , sector))
 			return 1;
 		ecc_buf[i] = readl(fifo_addr);
 		ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
@@ -384,7 +389,8 @@ static void execmd_read_page_sector(stru
 		read_fiforeg(flctl, 512, 512 * sector);
 
 		ret = read_ecfiforeg(flctl,
-			&flctl->done_buff[mtd->writesize + 16 * sector]);
+			&flctl->done_buff[mtd->writesize + 16 * sector],
+			sector);
 
 		if (ret)
 			flctl->hwecc_cant_correct[sector] = 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/socrates_nand.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/socrates_nand.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/socrates_nand.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/socrates_nand.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,325 @@
+/*
+ * drivers/mtd/nand/socrates_nand.c
+ *
+ *  Copyright Â© 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can 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/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define FPGA_NAND_CMD_MASK		(0x7 << 28)
+#define FPGA_NAND_CMD_COMMAND		(0x0 << 28)
+#define FPGA_NAND_CMD_ADDR		(0x1 << 28)
+#define FPGA_NAND_CMD_READ		(0x2 << 28)
+#define FPGA_NAND_CMD_WRITE		(0x3 << 28)
+#define FPGA_NAND_BUSY			(0x1 << 15)
+#define FPGA_NAND_ENABLE		(0x1 << 31)
+#define FPGA_NAND_DATA_SHIFT		16
+
+struct socrates_nand_host {
+	struct nand_chip	nand_chip;
+	struct mtd_info		mtd;
+	void __iomem		*io_base;
+	struct device		*dev;
+};
+
+/**
+ * socrates_nand_write_buf -  write buffer to chip
+ * @mtd:	MTD device structure
+ * @buf:	data buffer
+ * @len:	number of bytes to write
+ */
+static void socrates_nand_write_buf(struct mtd_info *mtd,
+		const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+	struct socrates_nand_host *host = this->priv;
+
+	for (i = 0; i < len; i++) {
+		out_be32(host->io_base, FPGA_NAND_ENABLE |
+				FPGA_NAND_CMD_WRITE |
+				(buf[i] << FPGA_NAND_DATA_SHIFT));
+	}
+}
+
+/**
+ * socrates_nand_read_buf -  read chip data into buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer to store date
+ * @len:	number of bytes to read
+ */
+static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+	struct socrates_nand_host *host = this->priv;
+	uint32_t val;
+
+	val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
+
+	out_be32(host->io_base, val);
+	for (i = 0; i < len; i++) {
+		buf[i] = (in_be32(host->io_base) >>
+				FPGA_NAND_DATA_SHIFT) & 0xff;
+	}
+}
+
+/**
+ * socrates_nand_read_byte -  read one byte from the chip
+ * @mtd:	MTD device structure
+ */
+static uint8_t socrates_nand_read_byte(struct mtd_info *mtd)
+{
+	uint8_t byte;
+	socrates_nand_read_buf(mtd, &byte, sizeof(byte));
+	return byte;
+}
+
+/**
+ * socrates_nand_read_word -  read one word from the chip
+ * @mtd:	MTD device structure
+ */
+static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
+{
+	uint16_t word;
+	socrates_nand_read_buf(mtd, (uint8_t *)&word, sizeof(word));
+	return word;
+}
+
+/**
+ * socrates_nand_verify_buf -  Verify chip data against buffer
+ * @mtd:	MTD device structure
+ * @buf:	buffer containing the data to compare
+ * @len:	number of bytes to compare
+ */
+static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
+		int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		if (buf[i] != socrates_nand_read_byte(mtd))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+		unsigned int ctrl)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct socrates_nand_host *host = nand_chip->priv;
+	uint32_t val;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		val = FPGA_NAND_CMD_COMMAND;
+	else
+		val = FPGA_NAND_CMD_ADDR;
+
+	if (ctrl & NAND_NCE)
+		val |= FPGA_NAND_ENABLE;
+
+	val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
+
+	out_be32(host->io_base, val);
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int socrates_nand_device_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct socrates_nand_host *host = nand_chip->priv;
+
+	if (in_be32(host->io_base) & FPGA_NAND_BUSY)
+		return 0; /* busy */
+	return 1;
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/*
+ * Probe for the NAND device.
+ */
+static int __devinit socrates_nand_probe(struct of_device *ofdev,
+					 const struct of_device_id *ofid)
+{
+	struct socrates_nand_host *host;
+	struct mtd_info *mtd;
+	struct nand_chip *nand_chip;
+	int res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	struct mtd_partition *partitions = NULL;
+	int num_partitions = 0;
+#endif
+
+	/* Allocate memory for the device structure (and zero it) */
+	host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
+	if (!host) {
+		printk(KERN_ERR
+		       "socrates_nand: failed to allocate device structure.\n");
+		return -ENOMEM;
+	}
+
+	host->io_base = of_iomap(ofdev->node, 0);
+	if (host->io_base == NULL) {
+		printk(KERN_ERR "socrates_nand: ioremap failed\n");
+		kfree(host);
+		return -EIO;
+	}
+
+	mtd = &host->mtd;
+	nand_chip = &host->nand_chip;
+	host->dev = &ofdev->dev;
+
+	nand_chip->priv = host;		/* link the private data structures */
+	mtd->priv = nand_chip;
+	mtd->name = "socrates_nand";
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = &ofdev->dev;
+
+	/*should never be accessed directly */
+	nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
+	nand_chip->IO_ADDR_W = (void *)0xdeadbeef;
+
+	nand_chip->cmd_ctrl = socrates_nand_cmd_ctrl;
+	nand_chip->read_byte = socrates_nand_read_byte;
+	nand_chip->read_word = socrates_nand_read_word;
+	nand_chip->write_buf = socrates_nand_write_buf;
+	nand_chip->read_buf = socrates_nand_read_buf;
+	nand_chip->verify_buf = socrates_nand_verify_buf;
+	nand_chip->dev_ready = socrates_nand_device_ready;
+
+	nand_chip->ecc.mode = NAND_ECC_SOFT;	/* enable ECC */
+
+	/* TODO: I have no idea what real delay is. */
+	nand_chip->chip_delay = 20;		/* 20us command delay time */
+
+	dev_set_drvdata(&ofdev->dev, host);
+
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, 1)) {
+		res = -ENXIO;
+		goto out;
+	}
+
+	/* second phase scan */
+	if (nand_scan_tail(mtd)) {
+		res = -ENXIO;
+		goto out;
+	}
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+	num_partitions = parse_mtd_partitions(mtd, part_probes,
+					      &partitions, 0);
+	if (num_partitions < 0) {
+		res = num_partitions;
+		goto release;
+	}
+#endif
+
+#ifdef CONFIG_MTD_OF_PARTS
+	if (num_partitions == 0) {
+		num_partitions = of_mtd_parse_partitions(&ofdev->dev,
+							 ofdev->node,
+							 &partitions);
+		if (num_partitions < 0) {
+			res = num_partitions;
+			goto release;
+		}
+	}
+#endif
+	if (partitions && (num_partitions > 0))
+		res = add_mtd_partitions(mtd, partitions, num_partitions);
+	else
+#endif
+		res = add_mtd_device(mtd);
+
+	if (!res)
+		return res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+release:
+#endif
+	nand_release(mtd);
+
+out:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	iounmap(host->io_base);
+	kfree(host);
+	return res;
+}
+
+/*
+ * Remove a NAND device.
+ */
+static int __devexit socrates_nand_remove(struct of_device *ofdev)
+{
+	struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
+	struct mtd_info *mtd = &host->mtd;
+
+	nand_release(mtd);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	iounmap(host->io_base);
+	kfree(host);
+
+	return 0;
+}
+
+static struct of_device_id socrates_nand_match[] =
+{
+	{
+		.compatible   = "abb,socrates-nand",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, socrates_nand_match);
+
+static struct of_platform_driver socrates_nand_driver = {
+	.name		= "socrates_nand",
+	.match_table	= socrates_nand_match,
+	.probe		= socrates_nand_probe,
+	.remove		= __devexit_p(socrates_nand_remove),
+};
+
+static int __init socrates_nand_init(void)
+{
+	return of_register_platform_driver(&socrates_nand_driver);
+}
+
+static void __exit socrates_nand_exit(void)
+{
+	of_unregister_platform_driver(&socrates_nand_driver);
+}
+
+module_init(socrates_nand_init);
+module_exit(socrates_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ilya Yanok");
+MODULE_DESCRIPTION("NAND driver for Socrates board");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nand/txx9ndfmc.c linux-libre-2.6.30-gnu1/drivers/mtd/nand/txx9ndfmc.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nand/txx9ndfmc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nand/txx9ndfmc.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,428 @@
+/*
+ * TXx9 NAND flash memory controller driver
+ * Based on RBTX49xx patch from CELF patch archive.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2004-2007
+ * All Rights Reserved.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <asm/txx9/ndfmc.h>
+
+/* TXX9 NDFMC Registers */
+#define TXX9_NDFDTR	0x00
+#define TXX9_NDFMCR	0x04
+#define TXX9_NDFSR	0x08
+#define TXX9_NDFISR	0x0c
+#define TXX9_NDFIMR	0x10
+#define TXX9_NDFSPR	0x14
+#define TXX9_NDFRSTR	0x18	/* not TX4939 */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TXX9_NDFMCR_WE	0x80
+#define TXX9_NDFMCR_ECC_ALL	0x60
+#define TXX9_NDFMCR_ECC_RESET	0x60
+#define TXX9_NDFMCR_ECC_READ	0x40
+#define TXX9_NDFMCR_ECC_ON	0x20
+#define TXX9_NDFMCR_ECC_OFF	0x00
+#define TXX9_NDFMCR_CE	0x10
+#define TXX9_NDFMCR_BSPRT	0x04	/* TX4925/TX4926 only */
+#define TXX9_NDFMCR_ALE	0x02
+#define TXX9_NDFMCR_CLE	0x01
+/* TX4939 only */
+#define TXX9_NDFMCR_X16	0x0400
+#define TXX9_NDFMCR_DMAREQ_MASK	0x0300
+#define TXX9_NDFMCR_DMAREQ_NODMA	0x0000
+#define TXX9_NDFMCR_DMAREQ_128	0x0100
+#define TXX9_NDFMCR_DMAREQ_256	0x0200
+#define TXX9_NDFMCR_DMAREQ_512	0x0300
+#define TXX9_NDFMCR_CS_MASK	0x0c
+#define TXX9_NDFMCR_CS(ch)	((ch) << 2)
+
+/* NDFMCR : NDFMC Status */
+#define TXX9_NDFSR_BUSY	0x80
+/* TX4939 only */
+#define TXX9_NDFSR_DMARUN	0x40
+
+/* NDFMCR : NDFMC Reset */
+#define TXX9_NDFRSTR_RST	0x01
+
+struct txx9ndfmc_priv {
+	struct platform_device *dev;
+	struct nand_chip chip;
+	struct mtd_info mtd;
+	int cs;
+	char mtdname[BUS_ID_SIZE + 2];
+};
+
+#define MAX_TXX9NDFMC_DEV	4
+struct txx9ndfmc_drvdata {
+	struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
+	void __iomem *base;
+	unsigned char hold;	/* in gbusclock */
+	unsigned char spw;	/* in gbusclock */
+	struct nand_hw_control hw_control;
+#ifdef CONFIG_MTD_PARTITIONS
+	struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
+#endif
+};
+
+static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct txx9ndfmc_priv *txx9_priv = chip->priv;
+	return txx9_priv->dev;
+}
+
+static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
+{
+	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+	return drvdata->base + (reg << plat->shift);
+}
+
+static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
+{
+	return __raw_readl(ndregaddr(dev, reg));
+}
+
+static void txx9ndfmc_write(struct platform_device *dev,
+			    u32 val, unsigned int reg)
+{
+	__raw_writel(val, ndregaddr(dev, reg));
+}
+
+static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+
+	return txx9ndfmc_read(dev, TXX9_NDFDTR);
+}
+
+static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
+	while (len--)
+		__raw_writel(*buf++, ndfdtr);
+	txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+	while (len--)
+		*buf++ = __raw_readl(ndfdtr);
+}
+
+static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+	while (len--)
+		if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
+			return -EFAULT;
+	return 0;
+}
+
+static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
+			       unsigned int ctrl)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct txx9ndfmc_priv *txx9_priv = chip->priv;
+	struct platform_device *dev = txx9_priv->dev;
+	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+		mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
+		mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
+		mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
+		/* TXX9_NDFMCR_CE bit is 0:high 1:low */
+		mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
+		if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
+			mcr &= ~TXX9_NDFMCR_CS_MASK;
+			mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
+		}
+		txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+	}
+	if (cmd != NAND_CMD_NONE)
+		txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
+	if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
+		/* dummy write to update external latch */
+		if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
+			txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
+	}
+	mmiowb();
+}
+
+static int txx9ndfmc_dev_ready(struct mtd_info *mtd)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+
+	return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
+}
+
+static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
+				   uint8_t *ecc_code)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+	mcr &= ~TXX9_NDFMCR_ECC_ALL;
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
+	ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+	ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+	ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+	return 0;
+}
+
+static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct platform_device *dev = mtd_to_platdev(mtd);
+	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+	mcr &= ~TXX9_NDFMCR_ECC_ALL;
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_initialize(struct platform_device *dev)
+{
+	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+	int tmout = 100;
+
+	if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
+		; /* no NDFRSTR.  Write to NDFSPR resets the NDFMC. */
+	else {
+		/* reset NDFMC */
+		txx9ndfmc_write(dev,
+				txx9ndfmc_read(dev, TXX9_NDFRSTR) |
+				TXX9_NDFRSTR_RST,
+				TXX9_NDFRSTR);
+		while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
+			if (--tmout == 0) {
+				dev_err(&dev->dev, "reset failed.\n");
+				break;
+			}
+			udelay(1);
+		}
+	}
+	/* setup Hold Time, Strobe Pulse Width */
+	txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
+	txx9ndfmc_write(dev,
+			(plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
+			TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
+}
+
+#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
+	DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
+
+static int __init txx9ndfmc_probe(struct platform_device *dev)
+{
+	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+#ifdef CONFIG_MTD_PARTITIONS
+	static const char *probes[] = { "cmdlinepart", NULL };
+#endif
+	int hold, spw;
+	int i;
+	struct txx9ndfmc_drvdata *drvdata;
+	unsigned long gbusclk = plat->gbus_clock;
+	struct resource *res;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+	if (!devm_request_mem_region(&dev->dev, res->start,
+				     resource_size(res), dev_name(&dev->dev)))
+		return -EBUSY;
+	drvdata->base = devm_ioremap(&dev->dev, res->start,
+				     resource_size(res));
+	if (!drvdata->base)
+		return -EBUSY;
+
+	hold = plat->hold ?: 20; /* tDH */
+	spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
+
+	hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
+	spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
+	if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
+		hold -= 2;	/* actual hold time : (HOLD + 2) BUSCLK */
+	spw -= 1;	/* actual wait time : (SPW + 1) BUSCLK */
+	hold = clamp(hold, 1, 15);
+	drvdata->hold = hold;
+	spw = clamp(spw, 1, 15);
+	drvdata->spw = spw;
+	dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
+		 (gbusclk + 500000) / 1000000, hold, spw);
+
+	spin_lock_init(&drvdata->hw_control.lock);
+	init_waitqueue_head(&drvdata->hw_control.wq);
+
+	platform_set_drvdata(dev, drvdata);
+	txx9ndfmc_initialize(dev);
+
+	for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+		struct txx9ndfmc_priv *txx9_priv;
+		struct nand_chip *chip;
+		struct mtd_info *mtd;
+#ifdef CONFIG_MTD_PARTITIONS
+		int nr_parts;
+#endif
+
+		if (!(plat->ch_mask & (1 << i)))
+			continue;
+		txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
+				    GFP_KERNEL);
+		if (!txx9_priv) {
+			dev_err(&dev->dev, "Unable to allocate "
+				"TXx9 NDFMC MTD device structure.\n");
+			continue;
+		}
+		chip = &txx9_priv->chip;
+		mtd = &txx9_priv->mtd;
+		mtd->owner = THIS_MODULE;
+
+		mtd->priv = chip;
+
+		chip->read_byte = txx9ndfmc_read_byte;
+		chip->read_buf = txx9ndfmc_read_buf;
+		chip->write_buf = txx9ndfmc_write_buf;
+		chip->verify_buf = txx9ndfmc_verify_buf;
+		chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
+		chip->dev_ready = txx9ndfmc_dev_ready;
+		chip->ecc.calculate = txx9ndfmc_calculate_ecc;
+		chip->ecc.correct = nand_correct_data;
+		chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
+		chip->ecc.mode = NAND_ECC_HW;
+		chip->ecc.size = 256;
+		chip->ecc.bytes = 3;
+		chip->chip_delay = 100;
+		chip->controller = &drvdata->hw_control;
+
+		chip->priv = txx9_priv;
+		txx9_priv->dev = dev;
+
+		if (plat->ch_mask != 1) {
+			txx9_priv->cs = i;
+			sprintf(txx9_priv->mtdname, "%s.%u",
+				dev_name(&dev->dev), i);
+		} else {
+			txx9_priv->cs = -1;
+			strcpy(txx9_priv->mtdname, dev_name(&dev->dev));
+		}
+		if (plat->wide_mask & (1 << i))
+			chip->options |= NAND_BUSWIDTH_16;
+
+		if (nand_scan(mtd, 1)) {
+			kfree(txx9_priv);
+			continue;
+		}
+		mtd->name = txx9_priv->mtdname;
+
+#ifdef CONFIG_MTD_PARTITIONS
+		nr_parts = parse_mtd_partitions(mtd, probes,
+						&drvdata->parts[i], 0);
+		if (nr_parts > 0)
+			add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
+#endif
+		add_mtd_device(mtd);
+		drvdata->mtds[i] = mtd;
+	}
+
+	return 0;
+}
+
+static int __exit txx9ndfmc_remove(struct platform_device *dev)
+{
+	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+	int i;
+
+	platform_set_drvdata(dev, NULL);
+	if (!drvdata)
+		return 0;
+	for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+		struct mtd_info *mtd = drvdata->mtds[i];
+		struct nand_chip *chip;
+		struct txx9ndfmc_priv *txx9_priv;
+
+		if (!mtd)
+			continue;
+		chip = mtd->priv;
+		txx9_priv = chip->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+		del_mtd_partitions(mtd);
+		kfree(drvdata->parts[i]);
+#endif
+		del_mtd_device(mtd);
+		kfree(txx9_priv);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int txx9ndfmc_resume(struct platform_device *dev)
+{
+	if (platform_get_drvdata(dev))
+		txx9ndfmc_initialize(dev);
+	return 0;
+}
+#else
+#define txx9ndfmc_resume NULL
+#endif
+
+static struct platform_driver txx9ndfmc_driver = {
+	.remove		= __exit_p(txx9ndfmc_remove),
+	.resume		= txx9ndfmc_resume,
+	.driver		= {
+		.name	= "txx9ndfmc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init txx9ndfmc_init(void)
+{
+	return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
+}
+
+static void __exit txx9ndfmc_exit(void)
+{
+	platform_driver_unregister(&txx9ndfmc_driver);
+}
+
+module_init(txx9ndfmc_init);
+module_exit(txx9ndfmc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
+MODULE_ALIAS("platform:txx9ndfmc");
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/nftlcore.c linux-libre-2.6.30-gnu1/drivers/mtd/nftlcore.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/nftlcore.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/nftlcore.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,11 +15,11 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/hdreg.h>
+#include <linux/blkdev.h>
 
 #include <linux/kmod.h>
 #include <linux/mtd/mtd.h>
@@ -818,3 +818,4 @@ module_exit(cleanup_nftl);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
 MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
+MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/ofpart.c linux-libre-2.6.30-gnu1/drivers/mtd/ofpart.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/ofpart.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/ofpart.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,6 +46,13 @@ int __devinit of_mtd_parse_partitions(st
 		const u32 *reg;
 		int len;
 
+		/* check if this is a partition node */
+		partname = of_get_property(pp, "name", &len);
+		if (strcmp(partname, "partition") != 0) {
+			nr_parts--;
+			continue;
+		}
+
 		reg = of_get_property(pp, "reg", &len);
 		if (!reg || (len != 2 * sizeof(u32))) {
 			of_node_put(pp);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/onenand/generic.c linux-libre-2.6.30-gnu1/drivers/mtd/onenand/generic.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/onenand/generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/onenand/generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,10 +36,9 @@ struct onenand_info {
 	struct onenand_chip	onenand;
 };
 
-static int __devinit generic_onenand_probe(struct device *dev)
+static int __devinit generic_onenand_probe(struct platform_device *pdev)
 {
 	struct onenand_info *info;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct flash_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res = pdev->resource;
 	unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_pro
 	if (!info)
 		return -ENOMEM;
 
-	if (!request_mem_region(res->start, size, dev->driver->name)) {
+	if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
 		err = -EBUSY;
 		goto out_free_info;
 	}
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_pro
 #endif
 		err = add_mtd_device(&info->mtd);
 
-	dev_set_drvdata(&pdev->dev, info);
+	platform_set_drvdata(pdev, info);
 
 	return 0;
 
@@ -96,14 +95,13 @@ out_free_info:
 	return err;
 }
 
-static int __devexit generic_onenand_remove(struct device *dev)
+static int __devexit generic_onenand_remove(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+	struct onenand_info *info = platform_get_drvdata(pdev);
 	struct resource *res = pdev->resource;
 	unsigned long size = res->end - res->start + 1;
 
-	dev_set_drvdata(&pdev->dev, NULL);
+	platform_set_drvdata(pdev, NULL);
 
 	if (info) {
 		if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_rem
 	return 0;
 }
 
-static struct device_driver generic_onenand_driver = {
-	.name		= DRIVER_NAME,
-	.bus		= &platform_bus_type,
+static struct platform_driver generic_onenand_driver = {
+	.driver = {
+		.name		= DRIVER_NAME,
+		.owner		= THIS_MODULE,
+	},
 	.probe		= generic_onenand_probe,
 	.remove		= __devexit_p(generic_onenand_remove),
 };
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);
 
 static int __init generic_onenand_init(void)
 {
-	return driver_register(&generic_onenand_driver);
+	return platform_driver_register(&generic_onenand_driver);
 }
 
 static void __exit generic_onenand_exit(void)
 {
-	driver_unregister(&generic_onenand_driver);
+	platform_driver_unregister(&generic_onenand_driver);
 }
 
 module_init(generic_onenand_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/onenand/omap2.c linux-libre-2.6.30-gnu1/drivers/mtd/onenand/omap2.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/onenand/omap2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/onenand/omap2.c	2009-06-09 23:05:27.000000000 -0400
@@ -294,6 +294,10 @@ static int omap3_onenand_read_bufferram(
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
 		goto out_copy;
 
+	/* panic_write() may be in an interrupt context */
+	if (in_interrupt())
+		goto out_copy;
+
 	if (buf >= high_memory) {
 		struct page *p1;
 
@@ -672,6 +676,8 @@ static int __devinit omap2_onenand_probe
 	c->mtd.priv = &c->onenand;
 	c->mtd.owner = THIS_MODULE;
 
+	c->mtd.dev.parent = &pdev->dev;
+
 	if (c->dma_channel >= 0) {
 		struct onenand_chip *this = &c->onenand;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/onenand/onenand_base.c linux-libre-2.6.30-gnu1/drivers/mtd/onenand/onenand_base.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/onenand/onenand_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/onenand/onenand_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -1455,7 +1455,8 @@ static int onenand_write_ops_nolock(stru
 				struct mtd_oob_ops *ops)
 {
 	struct onenand_chip *this = mtd->priv;
-	int written = 0, column, thislen, subpage;
+	int written = 0, column, thislen = 0, subpage = 0;
+	int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
 	int oobwritten = 0, oobcolumn, thisooblen, oobsize;
 	size_t len = ops->len;
 	size_t ooblen = ops->ooblen;
@@ -1482,6 +1483,10 @@ static int onenand_write_ops_nolock(stru
                 return -EINVAL;
         }
 
+	/* Check zero length */
+	if (!len)
+		return 0;
+
 	if (ops->mode == MTD_OOB_AUTO)
 		oobsize = this->ecclayout->oobavail;
 	else
@@ -1492,79 +1497,121 @@ static int onenand_write_ops_nolock(stru
 	column = to & (mtd->writesize - 1);
 
 	/* Loop until all data write */
-	while (written < len) {
-		u_char *wbuf = (u_char *) buf;
+	while (1) {
+		if (written < len) {
+			u_char *wbuf = (u_char *) buf;
 
-		thislen = min_t(int, mtd->writesize - column, len - written);
-		thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
+			thislen = min_t(int, mtd->writesize - column, len - written);
+			thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
 
-		cond_resched();
+			cond_resched();
 
-		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
+			this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
 
-		/* Partial page write */
-		subpage = thislen < mtd->writesize;
-		if (subpage) {
-			memset(this->page_buf, 0xff, mtd->writesize);
-			memcpy(this->page_buf + column, buf, thislen);
-			wbuf = this->page_buf;
-		}
+			/* Partial page write */
+			subpage = thislen < mtd->writesize;
+			if (subpage) {
+				memset(this->page_buf, 0xff, mtd->writesize);
+				memcpy(this->page_buf + column, buf, thislen);
+				wbuf = this->page_buf;
+			}
 
-		this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
+			this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
 
-		if (oob) {
-			oobbuf = this->oob_buf;
+			if (oob) {
+				oobbuf = this->oob_buf;
 
-			/* We send data to spare ram with oobsize
-			 * to prevent byte access */
-			memset(oobbuf, 0xff, mtd->oobsize);
-			if (ops->mode == MTD_OOB_AUTO)
-				onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
-			else
-				memcpy(oobbuf + oobcolumn, oob, thisooblen);
+				/* We send data to spare ram with oobsize
+				 * to prevent byte access */
+				memset(oobbuf, 0xff, mtd->oobsize);
+				if (ops->mode == MTD_OOB_AUTO)
+					onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
+				else
+					memcpy(oobbuf + oobcolumn, oob, thisooblen);
 
-			oobwritten += thisooblen;
-			oob += thisooblen;
-			oobcolumn = 0;
+				oobwritten += thisooblen;
+				oob += thisooblen;
+				oobcolumn = 0;
+			} else
+				oobbuf = (u_char *) ffchars;
+
+			this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
 		} else
-			oobbuf = (u_char *) ffchars;
+			ONENAND_SET_NEXT_BUFFERRAM(this);
 
-		this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+		/*
+		 * 2 PLANE, MLC, and Flex-OneNAND doesn't support
+		 * write-while-programe feature.
+		 */
+		if (!ONENAND_IS_2PLANE(this) && !first) {
+			ONENAND_SET_PREV_BUFFERRAM(this);
 
-		this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
+			ret = this->wait(mtd, FL_WRITING);
 
-		ret = this->wait(mtd, FL_WRITING);
+			/* In partial page write we don't update bufferram */
+			onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
+			if (ret) {
+				written -= prevlen;
+				printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+				break;
+			}
 
-		/* In partial page write we don't update bufferram */
-		onenand_update_bufferram(mtd, to, !ret && !subpage);
-		if (ONENAND_IS_2PLANE(this)) {
-			ONENAND_SET_BUFFERRAM1(this);
-			onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
-		}
+			if (written == len) {
+				/* 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);
+				break;
+			}
 
-		if (ret) {
-			printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
-			break;
+			ONENAND_SET_NEXT_BUFFERRAM(this);
 		}
 
-		/* 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);
-			break;
-		}
+		this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
 
-		written += thislen;
+		/*
+		 * 2 PLANE, MLC, and Flex-OneNAND wait here
+		 */
+		if (ONENAND_IS_2PLANE(this)) {
+			ret = this->wait(mtd, FL_WRITING);
 
-		if (written == len)
-			break;
+			/* 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 filaed %d\n", 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);
+				break;
+			}
+
+			written += thislen;
+
+			if (written == len)
+				break;
+
+		} else
+			written += thislen;
 
 		column = 0;
+		prev_subpage = subpage;
+		prev = to;
+		prevlen = thislen;
 		to += thislen;
 		buf += thislen;
+		first = 0;
 	}
 
+	/* In error case, clear all bufferrams */
+	if (written != len)
+		onenand_invalidate_bufferram(mtd, 0, -1);
+
 	ops->retlen = written;
+	ops->oobretlen = oobwritten;
 
 	return ret;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/tests/mtd_oobtest.c linux-libre-2.6.30-gnu1/drivers/mtd/tests/mtd_oobtest.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/tests/mtd_oobtest.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/tests/mtd_oobtest.c	2009-06-09 23:05:27.000000000 -0400
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum)
 		ops.ooblen    = use_len;
 		ops.oobretlen = 0;
 		ops.ooboffs   = use_offset;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		err = mtd->write_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum)
 		ops.ooblen    = use_len;
 		ops.oobretlen = 0;
 		ops.ooboffs   = use_offset;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd->read_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum)
 			ops.ooblen    = mtd->ecclayout->oobavail;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = readbuf;
 			err = mtd->read_oob(mtd, addr, &ops);
 			if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(i
 	ops.ooblen    = len;
 	ops.oobretlen = 0;
 	ops.ooboffs   = 0;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
 	err = mtd->read_oob(mtd, addr, &ops);
 	if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void)
 	ops.ooblen    = 1;
 	ops.oobretlen = 0;
 	ops.ooboffs   = mtd->ecclayout->oobavail;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = writebuf;
 	printk(PRINT_PREF "attempting to start write past end of OOB\n");
 	printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void)
 	ops.ooblen    = 1;
 	ops.oobretlen = 0;
 	ops.ooboffs   = mtd->ecclayout->oobavail;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
 	printk(PRINT_PREF "attempting to start read past end of OOB\n");
 	printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void)
 		ops.ooblen    = mtd->ecclayout->oobavail + 1;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		printk(PRINT_PREF "attempting to write past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void)
 		ops.ooblen    = mtd->ecclayout->oobavail + 1;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		printk(PRINT_PREF "attempting to read past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void)
 		ops.ooblen    = mtd->ecclayout->oobavail;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 1;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		printk(PRINT_PREF "attempting to write past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void)
 		ops.ooblen    = mtd->ecclayout->oobavail;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 1;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		printk(PRINT_PREF "attempting to read past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
 			ops.ooblen    = sz;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = writebuf;
 			err = mtd->write_oob(mtd, addr, &ops);
 			if (err)
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
 		ops.ooblen    = mtd->ecclayout->oobavail * 2;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd->read_oob(mtd, addr, &ops);
 		if (err)
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/tests/mtd_readtest.c linux-libre-2.6.30-gnu1/drivers/mtd/tests/mtd_readtest.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/tests/mtd_readtest.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/tests/mtd_readtest.c	2009-06-09 23:05:27.000000000 -0400
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int e
 			ops.ooblen    = mtd->oobsize;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = oobbuf;
 			ret = mtd->read_oob(mtd, addr, &ops);
 			if (ret || ops.oobretlen != mtd->oobsize) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/mtd/ubi/cdev.c linux-libre-2.6.30-gnu1/drivers/mtd/ubi/cdev.c
--- linux-libre-2.6.29-gnu1/drivers/mtd/ubi/cdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/mtd/ubi/cdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -186,6 +186,16 @@ static loff_t vol_cdev_llseek(struct fil
 	return new_offset;
 }
 
+static int vol_cdev_fsync(struct file *file, struct dentry *dentry,
+			  int datasync)
+{
+	struct ubi_volume_desc *desc = file->private_data;
+	struct ubi_device *ubi = desc->vol->ubi;
+
+	return ubi_sync(ubi->ubi_num);
+}
+
+
 static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
 			     loff_t *offp)
 {
@@ -1073,6 +1083,7 @@ const struct file_operations ubi_vol_cde
 	.llseek         = vol_cdev_llseek,
 	.read           = vol_cdev_read,
 	.write          = vol_cdev_write,
+	.fsync		= vol_cdev_fsync,
 	.unlocked_ioctl = vol_cdev_ioctl,
 	.compat_ioctl   = vol_cdev_compat_ioctl,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c501.c linux-libre-2.6.30-gnu1/drivers/net/3c501.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c501.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c501.c	2009-06-09 23:05:27.000000000 -0400
@@ -197,6 +197,17 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops el_netdev_ops = {
+	.ndo_open		= el_open,
+	.ndo_stop		= el1_close,
+	.ndo_start_xmit 	= el_start_xmit,
+	.ndo_tx_timeout		= el_timeout,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /**
  *	el1_probe1:
  *	@dev: The device structure to use
@@ -305,12 +316,8 @@ static int __init el1_probe1(struct net_
 	 *	The EL1-specific entries in the device structure.
 	 */
 
-	dev->open = &el_open;
-	dev->hard_start_xmit = &el_start_xmit;
-	dev->tx_timeout = &el_timeout;
+	dev->netdev_ops = &el_netdev_ops;
 	dev->watchdog_timeo = HZ;
-	dev->stop = &el1_close;
-	dev->set_multicast_list = &set_multicast_list;
 	dev->ethtool_ops = &netdev_ethtool_ops;
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c503.c linux-libre-2.6.30-gnu1/drivers/net/3c503.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c503.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c503.c	2009-06-09 23:05:27.000000000 -0400
@@ -353,9 +353,6 @@ el2_probe1(struct net_device *dev, int i
 
     dev->netdev_ops = &el2_netdev_ops;
     dev->ethtool_ops = &netdev_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-    dev->poll_controller = eip_poll;
-#endif
 
     retval = register_netdev(dev);
     if (retval)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c505.c linux-libre-2.6.30-gnu1/drivers/net/3c505.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c505.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c505.c	2009-06-09 23:05:27.000000000 -0400
@@ -1354,6 +1354,17 @@ static int __init elp_autodetect(struct
 	return 0;		/* Because of this, the layer above will return -ENODEV */
 }
 
+static const struct net_device_ops elp_netdev_ops = {
+	.ndo_open		= elp_open,
+	.ndo_stop		= elp_close,
+	.ndo_get_stats 		= elp_get_stats,
+	.ndo_start_xmit		= elp_start_xmit,
+	.ndo_tx_timeout 	= elp_timeout,
+	.ndo_set_multicast_list = elp_set_mc_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 /******************************************************
  *
@@ -1558,13 +1569,8 @@ static int __init elplus_setup(struct ne
 		printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
 	}
 
-	dev->open = elp_open;				/* local */
-	dev->stop = elp_close;				/* local */
-	dev->get_stats = elp_get_stats;			/* local */
-	dev->hard_start_xmit = elp_start_xmit;		/* local */
-	dev->tx_timeout = elp_timeout;			/* local */
+	dev->netdev_ops = &elp_netdev_ops;
 	dev->watchdog_timeo = 10*HZ;
-	dev->set_multicast_list = elp_set_mc_list;	/* local */
 	dev->ethtool_ops = &netdev_ethtool_ops;		/* local */
 
 	dev->mem_start = dev->mem_end = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c507.c linux-libre-2.6.30-gnu1/drivers/net/3c507.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c507.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c507.c	2009-06-09 23:05:27.000000000 -0400
@@ -352,6 +352,16 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops netdev_ops = {
+	.ndo_open		= el16_open,
+	.ndo_stop		= el16_close,
+	.ndo_start_xmit 	= el16_send_packet,
+	.ndo_tx_timeout 	= el16_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init el16_probe1(struct net_device *dev, int ioaddr)
 {
 	static unsigned char init_ID_done, version_printed;
@@ -449,10 +459,7 @@ static int __init el16_probe1(struct net
 		goto out1;
 	}
 
- 	dev->open = el16_open;
- 	dev->stop = el16_close;
-	dev->hard_start_xmit = el16_send_packet;
-	dev->tx_timeout = el16_tx_timeout;
+	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->ethtool_ops = &netdev_ethtool_ops;
  	dev->flags &= ~IFF_MULTICAST;	/* Multicast doesn't work */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c509.c linux-libre-2.6.30-gnu1/drivers/net/3c509.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c509.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c509.c	2009-06-09 23:05:27.000000000 -0400
@@ -480,9 +480,13 @@ static int pnp_registered;
 
 #ifdef CONFIG_EISA
 static struct eisa_device_id el3_eisa_ids[] = {
+		{ "TCM5090" },
+		{ "TCM5091" },
 		{ "TCM5092" },
 		{ "TCM5093" },
+		{ "TCM5094" },
 		{ "TCM5095" },
+		{ "TCM5098" },
 		{ "" }
 };
 MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
@@ -537,6 +541,21 @@ static struct mca_driver el3_mca_driver
 static int mca_registered;
 #endif /* CONFIG_MCA */
 
+static const struct net_device_ops netdev_ops = {
+	.ndo_open 		= el3_open,
+	.ndo_stop	 	= el3_close,
+	.ndo_start_xmit 	= el3_start_xmit,
+	.ndo_get_stats 		= el3_get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_tx_timeout 	= el3_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= el3_poll_controller,
+#endif
+};
+
 static int __devinit el3_common_init(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
@@ -553,16 +572,8 @@ static int __devinit el3_common_init(str
 	}
 
 	/* The EL3-specific entries in the device structure. */
-	dev->open = &el3_open;
-	dev->hard_start_xmit = &el3_start_xmit;
-	dev->stop = &el3_close;
-	dev->get_stats = &el3_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->tx_timeout = el3_tx_timeout;
+	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = el3_poll_controller;
-#endif
 	SET_ETHTOOL_OPS(dev, &ethtool_ops);
 
 	err = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c515.c linux-libre-2.6.30-gnu1/drivers/net/3c515.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c515.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c515.c	2009-06-09 23:05:27.000000000 -0400
@@ -563,6 +563,20 @@ no_pnp:
 	return NULL;
 }
 
+
+static const struct net_device_ops netdev_ops = {
+	.ndo_open		= corkscrew_open,
+	.ndo_stop		= corkscrew_close,
+	.ndo_start_xmit		= corkscrew_start_xmit,
+	.ndo_tx_timeout		= corkscrew_timeout,
+	.ndo_get_stats		= corkscrew_get_stats,
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+
 static int corkscrew_setup(struct net_device *dev, int ioaddr,
 			    struct pnp_dev *idev, int card_number)
 {
@@ -681,13 +695,8 @@ static int corkscrew_setup(struct net_de
 	vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
 
 	/* The 3c51x-specific entries in the device structure. */
-	dev->open = &corkscrew_open;
-	dev->hard_start_xmit = &corkscrew_start_xmit;
-	dev->tx_timeout = &corkscrew_timeout;
+	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = (400 * HZ) / 1000;
-	dev->stop = &corkscrew_close;
-	dev->get_stats = &corkscrew_get_stats;
-	dev->set_multicast_list = &set_rx_mode;
 	dev->ethtool_ops = &netdev_ethtool_ops;
 
 	return register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c523.c linux-libre-2.6.30-gnu1/drivers/net/3c523.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c523.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c523.c	2009-06-09 23:05:27.000000000 -0400
@@ -403,6 +403,20 @@ static int elmc_getinfo(char *buf, int s
 	return len;
 }				/* elmc_getinfo() */
 
+static const struct net_device_ops netdev_ops = {
+	.ndo_open 		= elmc_open,
+	.ndo_stop		= elmc_close,
+	.ndo_get_stats		= elmc_get_stats,
+	.ndo_start_xmit		= elmc_send_packet,
+	.ndo_tx_timeout		= elmc_timeout,
+#ifdef ELMC_MULTICAST
+	.ndo_set_multicast_list = set_multicast_list,
+#endif
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*****************************************************************/
 
 static int __init do_elmc_probe(struct net_device *dev)
@@ -544,17 +558,8 @@ static int __init do_elmc_probe(struct n
 	printk(KERN_INFO "%s: hardware address %pM\n",
 	       dev->name, dev->dev_addr);
 
-	dev->open = &elmc_open;
-	dev->stop = &elmc_close;
-	dev->get_stats = &elmc_get_stats;
-	dev->hard_start_xmit = &elmc_send_packet;
-	dev->tx_timeout = &elmc_timeout;
+	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = HZ;
-#ifdef ELMC_MULTICAST
-	dev->set_multicast_list = &set_multicast_list;
-#else
-	dev->set_multicast_list = NULL;
-#endif
 	dev->ethtool_ops = &netdev_ethtool_ops;
 
 	/* note that we haven't actually requested the IRQ from the kernel.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c527.c linux-libre-2.6.30-gnu1/drivers/net/3c527.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c527.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c527.c	2009-06-09 23:05:27.000000000 -0400
@@ -288,6 +288,18 @@ struct net_device *__init mc32_probe(int
 	return ERR_PTR(-ENODEV);
 }
 
+static const struct net_device_ops netdev_ops = {
+	.ndo_open		= mc32_open,
+	.ndo_stop		= mc32_close,
+	.ndo_start_xmit		= mc32_send_packet,
+	.ndo_get_stats		= mc32_get_stats,
+	.ndo_set_multicast_list = mc32_set_multicast_list,
+	.ndo_tx_timeout		= mc32_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /**
  * mc32_probe1	-	Check a given slot for a board and test the card
  * @dev:  Device structure to fill in
@@ -518,12 +530,7 @@ static int __init mc32_probe1(struct net
 	printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
 		dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
 
-	dev->open		= mc32_open;
-	dev->stop		= mc32_close;
-	dev->hard_start_xmit	= mc32_send_packet;
-	dev->get_stats		= mc32_get_stats;
-	dev->set_multicast_list = mc32_set_multicast_list;
-	dev->tx_timeout		= mc32_timeout;
+	dev->netdev_ops		= &netdev_ops;
 	dev->watchdog_timeo	= HZ*5;	/* Board does all the work */
 	dev->ethtool_ops	= &netdev_ethtool_ops;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/3c59x.c linux-libre-2.6.30-gnu1/drivers/net/3c59x.c
--- linux-libre-2.6.29-gnu1/drivers/net/3c59x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/3c59x.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,8 +102,8 @@ static int vortex_debug = 1;
 #include <linux/delay.h>
 
 
-static char version[] __devinitdata =
-DRV_NAME ": Donald Becker and others.\n";
+static const char version[] __devinitconst =
+	DRV_NAME ": Donald Becker and others.\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
@@ -992,6 +992,42 @@ out:
 	return rc;
 }
 
+static const struct net_device_ops boomrang_netdev_ops = {
+	.ndo_open		= vortex_open,
+	.ndo_stop		= vortex_close,
+	.ndo_start_xmit		= boomerang_start_xmit,
+	.ndo_tx_timeout		= vortex_tx_timeout,
+	.ndo_get_stats		= vortex_get_stats,
+#ifdef CONFIG_PCI
+	.ndo_do_ioctl 		= vortex_ioctl,
+#endif
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= poll_vortex,
+#endif
+};
+
+static const struct net_device_ops vortex_netdev_ops = {
+	.ndo_open		= vortex_open,
+	.ndo_stop		= vortex_close,
+	.ndo_start_xmit		= vortex_start_xmit,
+	.ndo_tx_timeout		= vortex_tx_timeout,
+	.ndo_get_stats		= vortex_get_stats,
+#ifdef CONFIG_PCI
+	.ndo_do_ioctl 		= vortex_ioctl,
+#endif
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= poll_vortex,
+#endif
+};
+
 /*
  * Start up the PCI/EISA device which is described by *gendev.
  * Return 0 on success.
@@ -1366,18 +1402,16 @@ static int __devinit vortex_probe1(struc
 	}
 
 	/* The 3c59x-specific entries in the device structure. */
-	dev->open = vortex_open;
 	if (vp->full_bus_master_tx) {
-		dev->hard_start_xmit = boomerang_start_xmit;
+		dev->netdev_ops = &boomrang_netdev_ops;
 		/* Actually, it still should work with iommu. */
 		if (card_idx < MAX_UNITS &&
 		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
 				hw_checksums[card_idx] == 1)) {
 			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 		}
-	} else {
-		dev->hard_start_xmit = vortex_start_xmit;
-	}
+	} else
+		dev->netdev_ops =  &vortex_netdev_ops;
 
 	if (print_info) {
 		printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
@@ -1386,18 +1420,9 @@ static int __devinit vortex_probe1(struc
 				(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
 	}
 
-	dev->stop = vortex_close;
-	dev->get_stats = vortex_get_stats;
-#ifdef CONFIG_PCI
-	dev->do_ioctl = vortex_ioctl;
-#endif
 	dev->ethtool_ops = &vortex_ethtool_ops;
-	dev->set_multicast_list = set_rx_mode;
-	dev->tx_timeout = vortex_tx_timeout;
 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = poll_vortex;
-#endif
+
 	if (pdev) {
 		vp->pm_state_valid = 1;
  		pci_save_state(VORTEX_PCI(vp));
@@ -2883,7 +2908,7 @@ static void vortex_get_drvinfo(struct ne
 		strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
 	} else {
 		if (VORTEX_EISA(vp))
-			sprintf(info->bus_info, dev_name(vp->gendev));
+			strcpy(info->bus_info, dev_name(vp->gendev));
 		else
 			sprintf(info->bus_info, "EISA 0x%lx %d",
 					dev->base_addr, dev->irq);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/8139cp.c linux-libre-2.6.30-gnu1/drivers/net/8139cp.c
--- linux-libre-2.6.29-gnu1/drivers/net/8139cp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/8139cp.c	2009-06-09 23:05:27.000000000 -0400
@@ -604,7 +604,7 @@ rx_next:
 
 		spin_lock_irqsave(&cp->lock, flags);
 		cpw16_f(IntrMask, cp_intr_mask);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		spin_unlock_irqrestore(&cp->lock, flags);
 	}
 
@@ -641,9 +641,9 @@ static irqreturn_t cp_interrupt (int irq
 	}
 
 	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
-		if (netif_rx_schedule_prep(&cp->napi)) {
+		if (napi_schedule_prep(&cp->napi)) {
 			cpw16_f(IntrMask, cp_norx_intr_mask);
-			__netif_rx_schedule(&cp->napi);
+			__napi_schedule(&cp->napi);
 		}
 
 	if (status & (TxOK | TxErr | TxEmpty | SWInt))
@@ -1530,7 +1530,7 @@ static void cp_get_ethtool_stats (struct
 
 	/* begin NIC statistics dump */
 	cpw32(StatsAddr + 4, (u64)dma >> 32);
-	cpw32(StatsAddr, ((u64)dma & DMA_32BIT_MASK) | DumpStats);
+	cpw32(StatsAddr, ((u64)dma & DMA_BIT_MASK(32)) | DumpStats);
 	cpr32(StatsAddr);
 
 	for (i = 0; i < 1000; i++) {
@@ -1602,6 +1602,28 @@ static int cp_ioctl (struct net_device *
 	return rc;
 }
 
+static int cp_set_mac_address(struct net_device *dev, void *p)
+{
+	struct cp_private *cp = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	spin_lock_irq(&cp->lock);
+
+	cpw8_f(Cfg9346, Cfg9346_Unlock);
+	cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
+	cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
+	cpw8_f(Cfg9346, Cfg9346_Lock);
+
+	spin_unlock_irq(&cp->lock);
+
+	return 0;
+}
+
 /* Serial EEPROM section. */
 
 /*  EEPROM_Ctrl bits. */
@@ -1821,7 +1843,7 @@ static const struct net_device_ops cp_ne
 	.ndo_open		= cp_open,
 	.ndo_stop		= cp_close,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_mac_address 	= cp_set_mac_address,
 	.ndo_set_multicast_list	= cp_set_rx_mode,
 	.ndo_get_stats		= cp_get_stats,
 	.ndo_do_ioctl		= cp_ioctl,
@@ -1907,19 +1929,19 @@ static int cp_init_one (struct pci_dev *
 
 	/* Configure DMA attributes. */
 	if ((sizeof(dma_addr_t) > 4) &&
-	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 	} else {
 		pci_using_dac = 0;
 
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_err(&pdev->dev,
 				   "No usable DMA configuration, aborting.\n");
 			goto err_out_res;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			dev_err(&pdev->dev,
 				   "No usable consistent DMA configuration, "
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/8139too.c linux-libre-2.6.30-gnu1/drivers/net/8139too.c
--- linux-libre-2.6.29-gnu1/drivers/net/8139too.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/8139too.c	2009-06-09 23:05:27.000000000 -0400
@@ -640,6 +640,7 @@ static int rtl8139_start_xmit (struct sk
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void rtl8139_poll_controller(struct net_device *dev);
 #endif
+static int rtl8139_set_mac_address(struct net_device *dev, void *p);
 static int rtl8139_poll(struct napi_struct *napi, int budget);
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
 static int rtl8139_close (struct net_device *dev);
@@ -917,7 +918,7 @@ static const struct net_device_ops rtl81
 	.ndo_stop		= rtl8139_close,
 	.ndo_get_stats		= rtl8139_get_stats,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_mac_address 	= rtl8139_set_mac_address,
 	.ndo_start_xmit		= rtl8139_start_xmit,
 	.ndo_set_multicast_list	= rtl8139_set_rx_mode,
 	.ndo_do_ioctl		= netdev_ioctl,
@@ -1382,6 +1383,11 @@ static void rtl8139_hw_start (struct net
 	RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
 	RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
 
+	tp->cur_rx = 0;
+
+	/* init Rx ring buffer DMA address */
+	RTL_W32_F (RxBuf, tp->rx_ring_dma);
+
 	/* Must enable Tx/Rx before setting transfer thresholds! */
 	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
@@ -1389,8 +1395,6 @@ static void rtl8139_hw_start (struct net
 	RTL_W32 (RxConfig, tp->rx_config);
 	RTL_W32 (TxConfig, rtl8139_tx_config);
 
-	tp->cur_rx = 0;
-
 	rtl_check_media (dev, 1);
 
 	if (tp->chipset >= CH_8139B) {
@@ -1405,9 +1409,6 @@ static void rtl8139_hw_start (struct net
 	/* Lock Config[01234] and BMCR register writes */
 	RTL_W8 (Cfg9346, Cfg9346_Lock);
 
-	/* init Rx ring buffer DMA address */
-	RTL_W32_F (RxBuf, tp->rx_ring_dma);
-
 	/* init Tx buffer DMA addresses */
 	for (i = 0; i < NUM_TX_DESC; i++)
 		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
@@ -2128,7 +2129,7 @@ static int rtl8139_poll(struct napi_stru
 		 */
 		spin_lock_irqsave(&tp->lock, flags);
 		RTL_W16_F(IntrMask, rtl8139_intr_mask);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 	spin_unlock(&tp->rx_lock);
@@ -2178,9 +2179,9 @@ static irqreturn_t rtl8139_interrupt (in
 	/* Receive packets are processed by poll routine.
 	   If not running start it now. */
 	if (status & RxAckBits){
-		if (netif_rx_schedule_prep(&tp->napi)) {
+		if (napi_schedule_prep(&tp->napi)) {
 			RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
-			__netif_rx_schedule(&tp->napi);
+			__napi_schedule(&tp->napi);
 		}
 	}
 
@@ -2215,6 +2216,29 @@ static void rtl8139_poll_controller(stru
 }
 #endif
 
+static int rtl8139_set_mac_address(struct net_device *dev, void *p)
+{
+	struct rtl8139_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	spin_lock_irq(&tp->lock);
+
+	RTL_W8_F(Cfg9346, Cfg9346_Unlock);
+	RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+	RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+	RTL_W8_F(Cfg9346, Cfg9346_Lock);
+
+	spin_unlock_irq(&tp->lock);
+
+	return 0;
+}
+
 static int rtl8139_close (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/82596.c linux-libre-2.6.30-gnu1/drivers/net/82596.c
--- linux-libre-2.6.29-gnu1/drivers/net/82596.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/82596.c	2009-06-09 23:05:27.000000000 -0400
@@ -1122,6 +1122,17 @@ static void print_eth(unsigned char *add
 static int io = 0x300;
 static int irq = 10;
 
+static const struct net_device_ops i596_netdev_ops = {
+	.ndo_open 		= i596_open,
+	.ndo_stop		= i596_close,
+	.ndo_start_xmit		= i596_start_xmit,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_tx_timeout		= i596_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 struct net_device * __init i82596_probe(int unit)
 {
 	struct net_device *dev;
@@ -1232,11 +1243,7 @@ found:
 	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
 
 	/* The 82596-specific entries in the device structure. */
-	dev->open = i596_open;
-	dev->stop = i596_close;
-	dev->hard_start_xmit = i596_start_xmit;
-	dev->set_multicast_list = set_multicast_list;
-	dev->tx_timeout = i596_tx_timeout;
+	dev->netdev_ops = &i596_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	dev->ml_priv = (void *)(dev->mem_start);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/a2065.c linux-libre-2.6.30-gnu1/drivers/net/a2065.c
--- linux-libre-2.6.29-gnu1/drivers/net/a2065.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/a2065.c	2009-06-09 23:05:27.000000000 -0400
@@ -552,18 +552,13 @@ static int lance_start_xmit (struct sk_b
 	struct lance_private *lp = netdev_priv(dev);
 	volatile struct lance_regs *ll = lp->ll;
 	volatile struct lance_init_block *ib = lp->init_block;
-	int entry, skblen, len;
+	int entry, skblen;
 	int status = 0;
 	unsigned long flags;
 
-	skblen = skb->len;
-	len = skblen;
-
-	if (len < ETH_ZLEN) {
-		len = ETH_ZLEN;
-		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
-	}
+	if (skb_padto(skb, ETH_ZLEN))
+		return 0;
+	skblen = max_t(unsigned, skb->len, ETH_ZLEN);
 
 	local_irq_save(flags);
 
@@ -586,15 +581,11 @@ static int lance_start_xmit (struct sk_b
 	}
 #endif
 	entry = lp->tx_new & lp->tx_ring_mod_mask;
-	ib->btx_ring [entry].length = (-len) | 0xf000;
+	ib->btx_ring [entry].length = (-skblen) | 0xf000;
 	ib->btx_ring [entry].misc = 0;
 
 	skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen);
 
-	/* Clear the slack of the packet, do I need this? */
-	if (len != skblen)
-		memset ((void *) &ib->tx_buf [entry][skblen], 0, len - skblen);
-
 	/* Now, give the packet to the lance */
 	ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
 	lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
@@ -701,6 +692,17 @@ static struct zorro_driver a2065_driver
 	.remove		= __devexit_p(a2065_remove_one),
 };
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_set_multicast_list	= lance_set_multicast,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit a2065_init_one(struct zorro_dev *z,
 				    const struct zorro_device_id *ent)
 {
@@ -762,12 +764,8 @@ static int __devinit a2065_init_one(stru
 	priv->rx_ring_mod_mask = RX_RING_MOD_MASK;
 	priv->tx_ring_mod_mask = TX_RING_MOD_MASK;
 
-	dev->open = &lance_open;
-	dev->stop = &lance_close;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->tx_timeout = &lance_tx_timeout;
+	dev->netdev_ops = &lance_netdev_ops;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &lance_set_multicast;
 	dev->dma = 0;
 
 	init_timer(&priv->multicast_timer);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ac3200.c linux-libre-2.6.30-gnu1/drivers/net/ac3200.c
--- linux-libre-2.6.29-gnu1/drivers/net/ac3200.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ac3200.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,6 +143,22 @@ out:
 }
 #endif
 
+static const struct net_device_ops ac_netdev_ops = {
+	.ndo_open		= ac_open,
+	.ndo_stop 		= ac_close_card,
+
+	.ndo_start_xmit		= ei_start_xmit,
+	.ndo_tx_timeout		= ei_tx_timeout,
+	.ndo_get_stats		= ei_get_stats,
+	.ndo_set_multicast_list = ei_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ei_poll,
+#endif
+};
+
 static int __init ac_probe1(int ioaddr, struct net_device *dev)
 {
 	int i, retval;
@@ -253,11 +269,7 @@ static int __init ac_probe1(int ioaddr,
 	ei_status.block_output = &ac_block_output;
 	ei_status.get_8390_hdr = &ac_get_8390_hdr;
 
-	dev->open = &ac_open;
-	dev->stop = &ac_close_card;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = ei_poll;
-#endif
+	dev->netdev_ops = &ac_netdev_ops;
 	NS8390_init(dev, 0);
 
 	retval = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/acenic.c linux-libre-2.6.30-gnu1/drivers/net/acenic.c
--- linux-libre-2.6.29-gnu1/drivers/net/acenic.c	2013-05-03 18:02:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/acenic.c	2013-05-03 16:46:17.000000000 -0400
@@ -437,7 +437,7 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C
 MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
 
 
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
   "acenic.c: v0.92 08/05/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
@@ -1161,9 +1161,9 @@ static int __devinit ace_init(struct net
 	/*
 	 * Configure DMA attributes.
 	 */
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		ap->pci_using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		ap->pci_using_dac = 0;
 	} else {
 		ecode = -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/amd8111e.c linux-libre-2.6.30-gnu1/drivers/net/amd8111e.c
--- linux-libre-2.6.29-gnu1/drivers/net/amd8111e.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/amd8111e.c	2009-06-09 23:05:27.000000000 -0400
@@ -831,7 +831,7 @@ static int amd8111e_rx_poll(struct napi_
 	if (rx_pkt_limit > 0) {
 		/* Receive descriptor is empty now */
 		spin_lock_irqsave(&lp->lock, flags);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		writel(VAL0|RINTEN0, mmio + INTEN0);
 		writel(VAL2 | RDMD0, mmio + CMD0);
 		spin_unlock_irqrestore(&lp->lock, flags);
@@ -1170,11 +1170,11 @@ static irqreturn_t amd8111e_interrupt(in
 
 	/* Check if Receive Interrupt has occurred. */
 	if (intr0 & RINT0) {
-		if (netif_rx_schedule_prep(&lp->napi)) {
+		if (napi_schedule_prep(&lp->napi)) {
 			/* Disable receive interupts */
 			writel(RINTEN0, mmio + INTEN0);
 			/* Schedule a polling routine */
-			__netif_rx_schedule(&lp->napi);
+			__napi_schedule(&lp->napi);
 		} else if (intren0 & RINTEN0) {
 			printk("************Driver bug! \
 				interrupt while in poll\n");
@@ -1871,7 +1871,7 @@ static int __devinit amd8111e_probe_one(
 	}
 
 	/* Initialize DMA */
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
 		printk(KERN_ERR "amd8111e: DMA not supported,"
 			"exiting.\n");
 		goto err_free_reg;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/appletalk/cops.c linux-libre-2.6.30-gnu1/drivers/net/appletalk/cops.c
--- linux-libre-2.6.29-gnu1/drivers/net/appletalk/cops.c	2013-05-03 18:03:35.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/appletalk/cops.c	2013-05-03 16:47:26.000000000 -0400
@@ -170,7 +170,6 @@ static unsigned int cops_debug = COPS_DE
 
 struct cops_local
 {
-        struct net_device_stats stats;
         int board;			/* Holds what board type is. */
 	int nodeid;			/* Set to 1 once have nodeid. */
         unsigned char node_acquire;	/* Node ID when acquired. */
@@ -196,7 +195,6 @@ static int  cops_send_packet (struct sk_
 static void set_multicast_list (struct net_device *dev);
 static int  cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static int  cops_close (struct net_device *dev);
-static struct net_device_stats *cops_get_stats (struct net_device *dev);
 
 static void cleanup_card(struct net_device *dev)
 {
@@ -259,6 +257,15 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops cops_netdev_ops = {
+	.ndo_open               = cops_open,
+        .ndo_stop               = cops_close,
+	.ndo_start_xmit   	= cops_send_packet,
+	.ndo_tx_timeout		= cops_timeout,
+        .ndo_do_ioctl           = cops_ioctl,
+	.ndo_set_multicast_list = set_multicast_list,
+};
+
 /*
  *      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
@@ -332,16 +339,9 @@ static int __init cops_probe1(struct net
 	/* Copy local board variable to lp struct. */
 	lp->board               = board;
 
-	dev->hard_start_xmit    = cops_send_packet;
-	dev->tx_timeout		= cops_timeout;
+	dev->netdev_ops 	= &cops_netdev_ops;
 	dev->watchdog_timeo	= HZ * 2;
 
-        dev->get_stats          = cops_get_stats;
-	dev->open               = cops_open;
-        dev->stop               = cops_close;
-        dev->do_ioctl           = cops_ioctl;
-	dev->set_multicast_list = set_multicast_list;
-        dev->mc_list            = NULL;
 
 	/* Tell the user where the card is and what mode we're in. */
 	if(board==DAYNA)
@@ -796,7 +796,7 @@ static void cops_rx(struct net_device *d
         {
                 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
 			dev->name);
-                lp->stats.rx_dropped++;
+                dev->stats.rx_dropped++;
                 while(pkt_len--)        /* Discard packet */
                         inb(ioaddr);
                 spin_unlock_irqrestore(&lp->lock, flags);
@@ -818,7 +818,7 @@ static void cops_rx(struct net_device *d
         {
 		printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", 
 			dev->name, pkt_len);
-                lp->stats.tx_errors++;
+                dev->stats.tx_errors++;
                 dev_kfree_skb_any(skb);
                 return;
         }
@@ -835,7 +835,7 @@ static void cops_rx(struct net_device *d
         if(rsp_type != LAP_RESPONSE)
         {
                 printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
-                lp->stats.tx_errors++;
+                dev->stats.tx_errors++;
                 dev_kfree_skb_any(skb);
                 return;
         }
@@ -845,8 +845,8 @@ static void cops_rx(struct net_device *d
         skb_reset_transport_header(skb);    /* Point to data (Skip header). */
 
         /* Update the counters. */
-        lp->stats.rx_packets++;
-        lp->stats.rx_bytes += skb->len;
+        dev->stats.rx_packets++;
+        dev->stats.rx_bytes += skb->len;
 
         /* Send packet to a higher place. */
         netif_rx(skb);
@@ -857,7 +857,7 @@ static void cops_timeout(struct net_devi
         struct cops_local *lp = netdev_priv(dev);
         int ioaddr = dev->base_addr;
 
-	lp->stats.tx_errors++;
+	dev->stats.tx_errors++;
         if(lp->board==TANGENT)
         {
 		if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
@@ -915,8 +915,8 @@ static int cops_send_packet(struct sk_bu
 	spin_unlock_irqrestore(&lp->lock, flags);	/* Restore interrupts. */
 
 	/* Done sending packet, update counters and cleanup. */
-	lp->stats.tx_packets++;
-	lp->stats.tx_bytes += skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
         return 0;
@@ -985,15 +985,6 @@ static int cops_close(struct net_device
         return 0;
 }
 
-/*
- *      Get the current statistics.
- *      This may be called with the card open or closed.
- */
-static struct net_device_stats *cops_get_stats(struct net_device *dev)
-{
-        struct cops_local *lp = netdev_priv(dev);
-        return &lp->stats;
-}
 
 #ifdef MODULE
 static struct net_device *cops_dev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/appletalk/ltpc.c linux-libre-2.6.30-gnu1/drivers/net/appletalk/ltpc.c
--- linux-libre-2.6.29-gnu1/drivers/net/appletalk/ltpc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/appletalk/ltpc.c	2009-06-09 23:05:27.000000000 -0400
@@ -261,7 +261,6 @@ static unsigned char *ltdmacbuf;
 
 struct ltpc_private
 {
-	struct net_device_stats stats;
 	struct atalk_addr my_addr;
 };
 
@@ -699,7 +698,6 @@ static int do_read(struct net_device *de
 static struct timer_list ltpc_timer;
 
 static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev);
 
 static int read_30 ( struct net_device *dev)
 {
@@ -726,8 +724,6 @@ static int sendup_buffer (struct net_dev
 	int dnode, snode, llaptype, len; 
 	int sklen;
 	struct sk_buff *skb;
-	struct ltpc_private *ltpc_priv = netdev_priv(dev);
-	struct net_device_stats *stats = &ltpc_priv->stats;
 	struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf;
 
 	if (ltc->command != LT_RCVLAP) {
@@ -779,8 +775,8 @@ static int sendup_buffer (struct net_dev
 
 	skb_reset_transport_header(skb);
 
-	stats->rx_packets++;
-	stats->rx_bytes+=skb->len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
 
 	/* toss it onwards */
 	netif_rx(skb);
@@ -904,10 +900,6 @@ static int ltpc_xmit(struct sk_buff *skb
 	/* in kernel 1.3.xx, on entry skb->data points to ddp header,
 	 * and skb->len is the length of the ddp data + ddp header
 	 */
-
-	struct ltpc_private *ltpc_priv = netdev_priv(dev);
-	struct net_device_stats *stats = &ltpc_priv->stats;
-
 	int i;
 	struct lt_sendlap cbuf;
 	unsigned char *hdr;
@@ -936,20 +928,13 @@ static int ltpc_xmit(struct sk_buff *skb
 		printk("\n");
 	}
 
-	stats->tx_packets++;
-	stats->tx_bytes+=skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
 
 	dev_kfree_skb(skb);
 	return 0;
 }
 
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
-{
-	struct ltpc_private *ltpc_priv = netdev_priv(dev);
-	struct net_device_stats *stats = &ltpc_priv->stats;
-	return stats;
-}
-
 /* initialization stuff */
   
 static int __init ltpc_probe_dma(int base, int dma)
@@ -1027,6 +1012,12 @@ static int __init ltpc_probe_dma(int bas
 	return (want & 2) ? 3 : 1;
 }
 
+static const struct net_device_ops ltpc_netdev = {
+	.ndo_start_xmit		= ltpc_xmit,
+	.ndo_do_ioctl		= ltpc_ioctl,
+	.ndo_set_multicast_list = set_multicast_list,
+};
+
 struct net_device * __init ltpc_probe(void)
 {
 	struct net_device *dev;
@@ -1133,14 +1124,7 @@ struct net_device * __init ltpc_probe(vo
 	else
 		printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d.  Using polled mode.\n",io,dma);
 
-	/* Fill in the fields of the device structure with ethernet-generic values. */
-	dev->hard_start_xmit = ltpc_xmit;
-	dev->get_stats = ltpc_get_stats;
-
-	/* add the ltpc-specific things */
-	dev->do_ioctl = &ltpc_ioctl;
-
-	dev->set_multicast_list = &set_multicast_list;
+	dev->netdev_ops = &ltpc_netdev;
 	dev->mc_list = NULL;
 	dev->base_addr = io;
 	dev->irq = irq;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/arcnet.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/arcnet.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/arcnet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/arcnet.c	2009-06-09 23:05:27.000000000 -0400
@@ -95,17 +95,16 @@ EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
 EXPORT_SYMBOL(alloc_arcdev);
 EXPORT_SYMBOL(arcnet_interrupt);
+EXPORT_SYMBOL(arcnet_open);
+EXPORT_SYMBOL(arcnet_close);
+EXPORT_SYMBOL(arcnet_send_packet);
+EXPORT_SYMBOL(arcnet_timeout);
 
 /* Internal function prototypes */
-static int arcnet_open(struct net_device *dev);
-static int arcnet_close(struct net_device *dev);
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
-static void arcnet_timeout(struct net_device *dev);
 static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
 			 unsigned short type, const void *daddr,
 			 const void *saddr, unsigned len);
 static int arcnet_rebuild_header(struct sk_buff *skb);
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
 static int go_tx(struct net_device *dev);
 
 static int debug = ARCNET_DEBUG;
@@ -322,11 +321,18 @@ static const struct header_ops arcnet_he
 	.rebuild = arcnet_rebuild_header,
 };
 
+static const struct net_device_ops arcnet_netdev_ops = {
+	.ndo_open	= arcnet_open,
+	.ndo_stop	= arcnet_close,
+	.ndo_start_xmit = arcnet_send_packet,
+	.ndo_tx_timeout = arcnet_timeout,
+};
 
 /* Setup a struct device for ARCnet. */
 static void arcdev_setup(struct net_device *dev)
 {
 	dev->type = ARPHRD_ARCNET;
+	dev->netdev_ops = &arcnet_netdev_ops;
 	dev->header_ops = &arcnet_header_ops;
 	dev->hard_header_len = sizeof(struct archdr);
 	dev->mtu = choose_mtu();
@@ -339,18 +345,9 @@ static void arcdev_setup(struct net_devi
 	/* New-style flags. */
 	dev->flags = IFF_BROADCAST;
 
-	/*
-	 * Put in this stuff here, so we don't have to export the symbols to
-	 * the chipset drivers.
-	 */
-	dev->open = arcnet_open;
-	dev->stop = arcnet_close;
-	dev->hard_start_xmit = arcnet_send_packet;
-	dev->tx_timeout = arcnet_timeout;
-	dev->get_stats = arcnet_get_stats;
 }
 
-struct net_device *alloc_arcdev(char *name)
+struct net_device *alloc_arcdev(const char *name)
 {
 	struct net_device *dev;
 
@@ -372,7 +369,7 @@ struct net_device *alloc_arcdev(char *na
  * that "should" only need to be set once at boot, so that there is
  * non-reboot way to recover if something goes wrong.
  */
-static int arcnet_open(struct net_device *dev)
+int arcnet_open(struct net_device *dev)
 {
 	struct arcnet_local *lp = netdev_priv(dev);
 	int count, newmtu, error;
@@ -383,7 +380,6 @@ static int arcnet_open(struct net_device
 		return -ENODEV;
 
 	BUGLVL(D_PROTO) {
-		int count;
 		BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
 		       arc_proto_default->suffix);
 		for (count = 0; count < 256; count++)
@@ -472,7 +468,7 @@ static int arcnet_open(struct net_device
 
 
 /* The inverse routine to arcnet_open - shuts down the card. */
-static int arcnet_close(struct net_device *dev)
+int arcnet_close(struct net_device *dev)
 {
 	struct arcnet_local *lp = netdev_priv(dev);
 
@@ -583,8 +579,8 @@ static int arcnet_rebuild_header(struct
 	} else {
 		BUGMSG(D_NORMAL,
 		       "I don't understand ethernet protocol %Xh addresses!\n", type);
-		lp->stats.tx_errors++;
-		lp->stats.tx_aborted_errors++;
+		dev->stats.tx_errors++;
+		dev->stats.tx_aborted_errors++;
 	}
 
 	/* if we couldn't resolve the address... give up. */
@@ -601,7 +597,7 @@ static int arcnet_rebuild_header(struct
 
 
 /* Called by the kernel in order to transmit a packet. */
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct arcnet_local *lp = netdev_priv(dev);
 	struct archdr *pkt;
@@ -645,7 +641,7 @@ static int arcnet_send_packet(struct sk_
 		    !proto->ack_tx) {
 			/* done right away and we don't want to acknowledge
 			   the package later - forget about it now */
-			lp->stats.tx_bytes += skb->len;
+			dev->stats.tx_bytes += skb->len;
 			freeskb = 1;
 		} else {
 			/* do it the 'split' way */
@@ -709,7 +705,7 @@ static int go_tx(struct net_device *dev)
 	/* start sending */
 	ACOMMAND(TXcmd | (lp->cur_tx << 3));
 
-	lp->stats.tx_packets++;
+	dev->stats.tx_packets++;
 	lp->lasttrans_dest = lp->lastload_dest;
 	lp->lastload_dest = 0;
 	lp->excnak_pending = 0;
@@ -720,7 +716,7 @@ static int go_tx(struct net_device *dev)
 
 
 /* Called by the kernel when transmit times out */
-static void arcnet_timeout(struct net_device *dev)
+void arcnet_timeout(struct net_device *dev)
 {
 	unsigned long flags;
 	struct arcnet_local *lp = netdev_priv(dev);
@@ -732,11 +728,11 @@ static void arcnet_timeout(struct net_de
 		msg = " - missed IRQ?";
 	} else {
 		msg = "";
-		lp->stats.tx_aborted_errors++;
+		dev->stats.tx_aborted_errors++;
 		lp->timed_out = 1;
 		ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
 	}
-	lp->stats.tx_errors++;
+	dev->stats.tx_errors++;
 
 	/* make sure we didn't miss a TX or a EXC NAK IRQ */
 	AINTMASK(0);
@@ -865,8 +861,8 @@ irqreturn_t arcnet_interrupt(int irq, vo
 						       "transmit was not acknowledged! "
 						       "(status=%Xh, dest=%02Xh)\n",
 						       status, lp->lasttrans_dest);
-						lp->stats.tx_errors++;
-						lp->stats.tx_carrier_errors++;
+						dev->stats.tx_errors++;
+						dev->stats.tx_carrier_errors++;
 					} else {
 						BUGMSG(D_DURING,
 						       "broadcast was not acknowledged; that's normal "
@@ -905,7 +901,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 				if (txbuf != -1) {
 					if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
 						/* that was the last segment */
-						lp->stats.tx_bytes += lp->outgoing.skb->len;
+						dev->stats.tx_bytes += lp->outgoing.skb->len;
 						if(!lp->outgoing.proto->ack_tx)
 						  {
 						    dev_kfree_skb_irq(lp->outgoing.skb);
@@ -930,7 +926,7 @@ irqreturn_t arcnet_interrupt(int irq, vo
 		}
 		if (status & lp->intmask & RECONflag) {
 			ACOMMAND(CFLAGScmd | CONFIGclear);
-			lp->stats.tx_carrier_errors++;
+			dev->stats.tx_carrier_errors++;
 
 			BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
 			       status);
@@ -1038,8 +1034,8 @@ static void arcnet_rx(struct net_device
 	       "(%d+4 bytes)\n",
 	       bufnum, pkt.hard.source, pkt.hard.dest, length);
 
-	lp->stats.rx_packets++;
-	lp->stats.rx_bytes += length + ARC_HDR_SIZE;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += length + ARC_HDR_SIZE;
 
 	/* call the right receiver for the protocol */
 	if (arc_proto_map[soft->proto]->is_ip) {
@@ -1067,18 +1063,6 @@ static void arcnet_rx(struct net_device
 }
 
 
-
-/* 
- * Get the current statistics.  This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
-{
-	struct arcnet_local *lp = netdev_priv(dev);
-	return &lp->stats;
-}
-
-
 static void null_rx(struct net_device *dev, int bufnum,
 		    struct archdr *pkthdr, int length)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/arc-rawmode.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/arc-rawmode.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/arc-rawmode.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/arc-rawmode.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,7 +102,7 @@ static void rx(struct net_device *dev, i
 	skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
 	if (skb == NULL) {
 		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	skb_put(skb, length + ARC_HDR_SIZE);
@@ -122,7 +122,7 @@ static void rx(struct net_device *dev, i
 
 	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
 
-	skb->protocol = __constant_htons(ETH_P_ARCNET);
+	skb->protocol = cpu_to_be16(ETH_P_ARCNET);
 ;
 	netif_rx(skb);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/capmode.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/capmode.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/capmode.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/capmode.c	2009-06-09 23:05:27.000000000 -0400
@@ -119,7 +119,7 @@ static void rx(struct net_device *dev, i
 	skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
 	if (skb == NULL) {
 		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
@@ -148,7 +148,7 @@ static void rx(struct net_device *dev, i
 
 	BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
 
-	skb->protocol = __constant_htons(ETH_P_ARCNET);
+	skb->protocol = cpu_to_be16(ETH_P_ARCNET);
 ;
 	netif_rx(skb);
 }
@@ -282,7 +282,7 @@ static int ack_tx(struct net_device *dev
   BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
 	 *((int*)&ackpkt->soft.cap.cookie[0]));
 
-  ackskb->protocol = __constant_htons(ETH_P_ARCNET);
+  ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
 
   BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
   netif_rx(ackskb);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020.c	2009-06-09 23:05:27.000000000 -0400
@@ -149,6 +149,14 @@ int com20020_check(struct net_device *de
 	return 0;
 }
 
+const struct net_device_ops com20020_netdev_ops = {
+	.ndo_open	= arcnet_open,
+	.ndo_stop	= arcnet_close,
+	.ndo_start_xmit = arcnet_send_packet,
+	.ndo_tx_timeout = arcnet_timeout,
+	.ndo_set_multicast_list = com20020_set_mc_list,
+};
+
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
@@ -170,8 +178,6 @@ int com20020_found(struct net_device *de
 	lp->hw.copy_from_card = com20020_copy_from_card;
 	lp->hw.close = com20020_close;
 
-	dev->set_multicast_list = com20020_set_mc_list;
-
 	if (!dev->dev_addr[0])
 		dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8);	/* FIXME: do this some other way! */
 
@@ -342,6 +348,7 @@ static void com20020_set_mc_list(struct
     defined(CONFIG_ARCNET_COM20020_CS_MODULE)
 EXPORT_SYMBOL(com20020_check);
 EXPORT_SYMBOL(com20020_found);
+EXPORT_SYMBOL(com20020_netdev_ops);
 #endif
 
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020-isa.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020-isa.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020-isa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020-isa.c	2009-06-09 23:05:27.000000000 -0400
@@ -151,6 +151,8 @@ static int __init com20020_init(void)
 	if (node && node != 0xff)
 		dev->dev_addr[0] = node;
 
+	dev->netdev_ops = &com20020_netdev_ops;
+
 	lp = netdev_priv(dev);
 	lp->backplane = backplane;
 	lp->clockp = clockp & 7;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020-pci.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020-pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/com20020-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/com20020-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -72,6 +72,9 @@ static int __devinit com20020pci_probe(s
 	dev = alloc_arcdev(device);
 	if (!dev)
 		return -ENOMEM;
+
+	dev->netdev_ops = &com20020_netdev_ops;
+
 	lp = netdev_priv(dev);
 
 	pci_set_drvdata(pdev, dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/rfc1051.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/rfc1051.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/rfc1051.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/rfc1051.c	2009-06-09 23:05:27.000000000 -0400
@@ -88,7 +88,6 @@ MODULE_LICENSE("GPL");
  */
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-	struct arcnet_local *lp = netdev_priv(dev);
 	struct archdr *pkt = (struct archdr *) skb->data;
 	struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
 	int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -112,8 +111,8 @@ static __be16 type_trans(struct sk_buff
 		return htons(ETH_P_ARP);
 
 	default:
-		lp->stats.rx_errors++;
-		lp->stats.rx_crc_errors++;
+		dev->stats.rx_errors++;
+		dev->stats.rx_crc_errors++;
 		return 0;
 	}
 
@@ -140,7 +139,7 @@ static void rx(struct net_device *dev, i
 	skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
 	if (skb == NULL) {
 		BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	skb_put(skb, length + ARC_HDR_SIZE);
@@ -168,7 +167,6 @@ static void rx(struct net_device *dev, i
 static int build_header(struct sk_buff *skb, struct net_device *dev,
 			unsigned short type, uint8_t daddr)
 {
-	struct arcnet_local *lp = netdev_priv(dev);
 	int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
 	struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
 	struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -184,8 +182,8 @@ static int build_header(struct sk_buff *
 	default:
 		BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
 		       type, type);
-		lp->stats.tx_errors++;
-		lp->stats.tx_aborted_errors++;
+		dev->stats.tx_errors++;
+		dev->stats.tx_aborted_errors++;
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arcnet/rfc1201.c linux-libre-2.6.30-gnu1/drivers/net/arcnet/rfc1201.c
--- linux-libre-2.6.29-gnu1/drivers/net/arcnet/rfc1201.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arcnet/rfc1201.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,7 +92,6 @@ static __be16 type_trans(struct sk_buff
 {
 	struct archdr *pkt = (struct archdr *) skb->data;
 	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
-	struct arcnet_local *lp = netdev_priv(dev);
 	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
 
 	/* Pull off the arcnet header. */
@@ -121,8 +120,8 @@ static __be16 type_trans(struct sk_buff
 	case ARC_P_NOVELL_EC:
 		return htons(ETH_P_802_3);
 	default:
-		lp->stats.rx_errors++;
-		lp->stats.rx_crc_errors++;
+		dev->stats.rx_errors++;
+		dev->stats.rx_crc_errors++;
 		return 0;
 	}
 
@@ -172,8 +171,8 @@ static void rx(struct net_device *dev, i
 			 in->sequence, soft->split_flag, soft->sequence);
 			lp->rfc1201.aborted_seq = soft->sequence;
 			dev_kfree_skb_irq(in->skb);
-			lp->stats.rx_errors++;
-			lp->stats.rx_missed_errors++;
+			dev->stats.rx_errors++;
+			dev->stats.rx_missed_errors++;
 			in->skb = NULL;
 		}
 		in->sequence = soft->sequence;
@@ -181,7 +180,7 @@ static void rx(struct net_device *dev, i
 		skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
 		if (skb == NULL) {
 			BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
-			lp->stats.rx_dropped++;
+			dev->stats.rx_dropped++;
 			return;
 		}
 		skb_put(skb, length + ARC_HDR_SIZE);
@@ -213,7 +212,7 @@ static void rx(struct net_device *dev, i
 					BUGMSG(D_EXTRA,
 					       "ARP source address was 00h, set to %02Xh.\n",
 					       saddr);
-					lp->stats.rx_crc_errors++;
+					dev->stats.rx_crc_errors++;
 					*cptr = saddr;
 				} else {
 					BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
@@ -222,8 +221,8 @@ static void rx(struct net_device *dev, i
 			} else {
 				BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
 				       arp->ar_hln, arp->ar_pln);
-				lp->stats.rx_errors++;
-				lp->stats.rx_crc_errors++;
+				dev->stats.rx_errors++;
+				dev->stats.rx_crc_errors++;
 			}
 		}
 		BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
@@ -257,8 +256,8 @@ static void rx(struct net_device *dev, i
 			       soft->split_flag);
 			dev_kfree_skb_irq(in->skb);
 			in->skb = NULL;
-			lp->stats.rx_errors++;
-			lp->stats.rx_missed_errors++;
+			dev->stats.rx_errors++;
+			dev->stats.rx_missed_errors++;
 			in->lastpacket = in->numpackets = 0;
 		}
 		if (soft->split_flag & 1) {	/* first packet in split */
@@ -269,8 +268,8 @@ static void rx(struct net_device *dev, i
 				       "(splitflag=%d, seq=%d)\n",
 				       in->sequence, soft->split_flag,
 				       soft->sequence);
-				lp->stats.rx_errors++;
-				lp->stats.rx_missed_errors++;
+				dev->stats.rx_errors++;
+				dev->stats.rx_missed_errors++;
 				dev_kfree_skb_irq(in->skb);
 			}
 			in->sequence = soft->sequence;
@@ -281,8 +280,8 @@ static void rx(struct net_device *dev, i
 				BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
 				       soft->split_flag);
 				lp->rfc1201.aborted_seq = soft->sequence;
-				lp->stats.rx_errors++;
-				lp->stats.rx_length_errors++;
+				dev->stats.rx_errors++;
+				dev->stats.rx_length_errors++;
 				return;
 			}
 			in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
@@ -290,7 +289,7 @@ static void rx(struct net_device *dev, i
 			if (skb == NULL) {
 				BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
 				lp->rfc1201.aborted_seq = soft->sequence;
-				lp->stats.rx_dropped++;
+				dev->stats.rx_dropped++;
 				return;
 			}
 			skb->dev = dev;
@@ -314,8 +313,8 @@ static void rx(struct net_device *dev, i
 					       "first! (splitflag=%d, seq=%d, aborted=%d)\n",
 					soft->split_flag, soft->sequence,
 					       lp->rfc1201.aborted_seq);
-					lp->stats.rx_errors++;
-					lp->stats.rx_missed_errors++;
+					dev->stats.rx_errors++;
+					dev->stats.rx_missed_errors++;
 				}
 				return;
 			}
@@ -325,8 +324,8 @@ static void rx(struct net_device *dev, i
 				if (packetnum <= in->lastpacket - 1) {
 					BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
 					       soft->split_flag);
-					lp->stats.rx_errors++;
-					lp->stats.rx_frame_errors++;
+					dev->stats.rx_errors++;
+					dev->stats.rx_frame_errors++;
 					return;
 				}
 				/* "bad" duplicate, kill reassembly */
@@ -336,8 +335,8 @@ static void rx(struct net_device *dev, i
 				lp->rfc1201.aborted_seq = soft->sequence;
 				dev_kfree_skb_irq(in->skb);
 				in->skb = NULL;
-				lp->stats.rx_errors++;
-				lp->stats.rx_missed_errors++;
+				dev->stats.rx_errors++;
+				dev->stats.rx_missed_errors++;
 				in->lastpacket = in->numpackets = 0;
 				return;
 			}
@@ -404,8 +403,8 @@ static int build_header(struct sk_buff *
 	default:
 		BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
 		       type, type);
-		lp->stats.tx_errors++;
-		lp->stats.tx_aborted_errors++;
+		dev->stats.tx_errors++;
+		dev->stats.tx_aborted_errors++;
 		return 0;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ariadne.c linux-libre-2.6.30-gnu1/drivers/net/ariadne.c
--- linux-libre-2.6.29-gnu1/drivers/net/ariadne.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ariadne.c	2009-06-09 23:05:27.000000000 -0400
@@ -155,6 +155,18 @@ static struct zorro_driver ariadne_drive
     .remove	= __devexit_p(ariadne_remove_one),
 };
 
+static const struct net_device_ops ariadne_netdev_ops = {
+	.ndo_open		= ariadne_open,
+	.ndo_stop		= ariadne_close,
+	.ndo_start_xmit		= ariadne_start_xmit,
+	.ndo_tx_timeout		= ariadne_tx_timeout,
+	.ndo_get_stats		= ariadne_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit ariadne_init_one(struct zorro_dev *z,
 				      const struct zorro_device_id *ent)
 {
@@ -197,13 +209,8 @@ static int __devinit ariadne_init_one(st
     dev->mem_start = ZTWO_VADDR(mem_start);
     dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE;
 
-    dev->open = &ariadne_open;
-    dev->stop = &ariadne_close;
-    dev->hard_start_xmit = &ariadne_start_xmit;
-    dev->tx_timeout = &ariadne_tx_timeout;
+    dev->netdev_ops = &ariadne_netdev_ops;
     dev->watchdog_timeo = 5*HZ;
-    dev->get_stats = &ariadne_get_stats;
-    dev->set_multicast_list = &set_multicast_list;
 
     err = register_netdev(dev);
     if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/am79c961a.c linux-libre-2.6.30-gnu1/drivers/net/arm/am79c961a.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/am79c961a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/am79c961a.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,9 +27,9 @@
 #include <linux/crc32.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #define TX_BUFFERS 15
@@ -665,6 +665,20 @@ static void __init am79c961_banner(void)
 	if (net_debug && version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 }
+static const struct net_device_ops am79c961_netdev_ops = {
+	.ndo_open		= am79c961_open,
+	.ndo_stop		= am79c961_close,
+	.ndo_start_xmit		= am79c961_sendpacket,
+	.ndo_get_stats		= am79c961_getstats,
+	.ndo_set_multicast_list	= am79c961_setmulticastlist,
+	.ndo_tx_timeout		= am79c961_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= am79c961_poll_controller,
+#endif
+};
 
 static int __init am79c961_probe(struct platform_device *pdev)
 {
@@ -732,15 +746,7 @@ static int __init am79c961_probe(struct
 	if (am79c961_hw_init(dev))
 		goto release;
 
-	dev->open		= am79c961_open;
-	dev->stop		= am79c961_close;
-	dev->hard_start_xmit	= am79c961_sendpacket;
-	dev->get_stats		= am79c961_getstats;
-	dev->set_multicast_list	= am79c961_setmulticastlist;
-	dev->tx_timeout		= am79c961_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller	= am79c961_poll_controller;
-#endif
+	dev->netdev_ops = &am79c961_netdev_ops;
 
 	ret = register_netdev(dev);
 	if (ret == 0) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/at91_ether.c linux-libre-2.6.30-gnu1/drivers/net/arm/at91_ether.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/at91_ether.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/at91_ether.c	2009-06-09 23:05:27.000000000 -0400
@@ -577,7 +577,7 @@ static void at91ether_sethashtable(struc
 /*
  * Enable/Disable promiscuous and multicast modes.
  */
-static void at91ether_set_rx_mode(struct net_device *dev)
+static void at91ether_set_multicast_list(struct net_device *dev)
 {
 	unsigned long cfg;
 
@@ -808,7 +808,7 @@ static int at91ether_close(struct net_de
 /*
  * Transmit packet.
  */
-static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
+static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct at91_private *lp = netdev_priv(dev);
 
@@ -828,7 +828,7 @@ static int at91ether_tx(struct sk_buff *
 
 		dev->trans_start = jiffies;
 	} else {
-		printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
+		printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
 		return 1;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
 				on this skb, he also reports -ENETDOWN and printk's, so either
 				we free and return(0) or don't free and return 1 */
@@ -965,6 +965,21 @@ static void at91ether_poll_controller(st
 }
 #endif
 
+static const struct net_device_ops at91ether_netdev_ops = {
+	.ndo_open		= at91ether_open,
+	.ndo_stop		= at91ether_close,
+	.ndo_start_xmit		= at91ether_start_xmit,
+	.ndo_get_stats		= at91ether_stats,
+	.ndo_set_multicast_list	= at91ether_set_multicast_list,
+	.ndo_set_mac_address	= set_mac_address,
+	.ndo_do_ioctl		= at91ether_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= at91ether_poll_controller,
+#endif
+};
+
 /*
  * Initialize the ethernet interface
  */
@@ -1005,17 +1020,8 @@ static int __init at91ether_setup(unsign
 	spin_lock_init(&lp->lock);
 
 	ether_setup(dev);
-	dev->open = at91ether_open;
-	dev->stop = at91ether_close;
-	dev->hard_start_xmit = at91ether_tx;
-	dev->get_stats = at91ether_stats;
-	dev->set_multicast_list = at91ether_set_rx_mode;
-	dev->set_mac_address = set_mac_address;
+	dev->netdev_ops = &at91ether_netdev_ops;
 	dev->ethtool_ops = &at91ether_ethtool_ops;
-	dev->do_ioctl = at91ether_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = at91ether_poll_controller;
-#endif
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/ep93xx_eth.c linux-libre-2.6.30-gnu1/drivers/net/arm/ep93xx_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/ep93xx_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/ep93xx_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,7 +153,7 @@ struct ep93xx_descs
 struct ep93xx_priv
 {
 	struct resource		*res;
-	void			*base_addr;
+	void __iomem		*base_addr;
 	int			irq;
 
 	struct ep93xx_descs	*descs;
@@ -298,7 +298,7 @@ poll_some_more:
 		int more = 0;
 
 		spin_lock_irq(&ep->rx_lock);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
 		if (ep93xx_have_more_rx(ep)) {
 			wrl(ep, REG_INTEN, REG_INTEN_TX);
@@ -307,7 +307,7 @@ poll_some_more:
 		}
 		spin_unlock_irq(&ep->rx_lock);
 
-		if (more && netif_rx_reschedule(napi))
+		if (more && napi_reschedule(napi))
 			goto poll_some_more;
 	}
 
@@ -415,9 +415,9 @@ static irqreturn_t ep93xx_irq(int irq, v
 
 	if (status & REG_INTSTS_RX) {
 		spin_lock(&ep->rx_lock);
-		if (likely(netif_rx_schedule_prep(&ep->napi))) {
+		if (likely(napi_schedule_prep(&ep->napi))) {
 			wrl(ep, REG_INTEN, REG_INTEN_TX);
-			__netif_rx_schedule(&ep->napi);
+			__napi_schedule(&ep->napi);
 		}
 		spin_unlock(&ep->rx_lock);
 	}
@@ -770,7 +770,18 @@ static struct ethtool_ops ep93xx_ethtool
 	.get_link		= ep93xx_get_link,
 };
 
-struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
+static const struct net_device_ops ep93xx_netdev_ops = {
+	.ndo_open		= ep93xx_open,
+	.ndo_stop		= ep93xx_close,
+	.ndo_start_xmit		= ep93xx_xmit,
+	.ndo_get_stats		= ep93xx_get_stats,
+	.ndo_do_ioctl		= ep93xx_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
+static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
 {
 	struct net_device *dev;
 
@@ -780,12 +791,8 @@ struct net_device *ep93xx_dev_alloc(stru
 
 	memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN);
 
-	dev->get_stats = ep93xx_get_stats;
 	dev->ethtool_ops = &ep93xx_ethtool_ops;
-	dev->hard_start_xmit = ep93xx_xmit;
-	dev->open = ep93xx_open;
-	dev->stop = ep93xx_close;
-	dev->do_ioctl = ep93xx_ioctl;
+	dev->netdev_ops = &ep93xx_netdev_ops;
 
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/ether1.c linux-libre-2.6.30-gnu1/drivers/net/arm/ether1.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/ether1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/ether1.c	2009-06-09 23:05:27.000000000 -0400
@@ -991,6 +991,18 @@ static void __devinit ether1_banner(void
 		printk(KERN_INFO "%s", version);
 }
 
+static const struct net_device_ops ether1_netdev_ops = {
+	.ndo_open		= ether1_open,
+	.ndo_stop		= ether1_close,
+	.ndo_start_xmit		= ether1_sendpacket,
+	.ndo_get_stats		= ether1_getstats,
+	.ndo_set_multicast_list	= ether1_setmulticastlist,
+	.ndo_tx_timeout		= ether1_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit
 ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
@@ -1031,12 +1043,7 @@ ether1_probe(struct expansion_card *ec,
 		goto free;
 	}
 
-	dev->open		= ether1_open;
-	dev->stop		= ether1_close;
-	dev->hard_start_xmit    = ether1_sendpacket;
-	dev->get_stats		= ether1_getstats;
-	dev->set_multicast_list = ether1_setmulticastlist;
-	dev->tx_timeout		= ether1_timeout;
+	dev->netdev_ops		= &ether1_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 
 	ret = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/ether3.c linux-libre-2.6.30-gnu1/drivers/net/arm/ether3.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/ether3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/ether3.c	2009-06-09 23:05:27.000000000 -0400
@@ -770,6 +770,18 @@ static void __devinit ether3_banner(void
 		printk(KERN_INFO "%s", version);
 }
 
+static const struct net_device_ops ether3_netdev_ops = {
+	.ndo_open		= ether3_open,
+	.ndo_stop		= ether3_close,
+	.ndo_start_xmit		= ether3_sendpacket,
+	.ndo_get_stats		= ether3_getstats,
+	.ndo_set_multicast_list	= ether3_setmulticastlist,
+	.ndo_tx_timeout		= ether3_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __devinit
 ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
@@ -846,12 +858,7 @@ ether3_probe(struct expansion_card *ec,
 		goto free;
 	}
 
-	dev->open		= ether3_open;
-	dev->stop		= ether3_close;
-	dev->hard_start_xmit	= ether3_sendpacket;
-	dev->get_stats		= ether3_getstats;
-	dev->set_multicast_list	= ether3_setmulticastlist;
-	dev->tx_timeout		= ether3_timeout;
+	dev->netdev_ops		= &ether3_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ / 100;
 
 	ret = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/ixp4xx_eth.c linux-libre-2.6.30-gnu1/drivers/net/arm/ixp4xx_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/ixp4xx_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/ixp4xx_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -335,11 +335,20 @@ static int ixp4xx_mdio_register(void)
 	if (!(mdio_bus = mdiobus_alloc()))
 		return -ENOMEM;
 
-	/* All MII PHY accesses use NPE-B Ethernet registers */
-	spin_lock_init(&mdio_lock);
-	mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
-	__raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+	if (cpu_is_ixp43x()) {
+		/* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
+			return -ENODEV;
+		mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
+	} else {
+		/* All MII PHY accesses use NPE-B Ethernet registers */
+		if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
+			return -ENODEV;
+		mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
+	}
 
+	__raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+	spin_lock_init(&mdio_lock);
 	mdio_bus->name = "IXP4xx MII Bus";
 	mdio_bus->read = &ixp4xx_mdio_read;
 	mdio_bus->write = &ixp4xx_mdio_write;
@@ -473,7 +482,7 @@ static void eth_rx_irq(void *pdev)
 	printk(KERN_DEBUG "%s: eth_rx_irq\n", dev->name);
 #endif
 	qmgr_disable_irq(port->plat->rxq);
-	netif_rx_schedule(&port->napi);
+	napi_schedule(&port->napi);
 }
 
 static int eth_poll(struct napi_struct *napi, int budget)
@@ -498,16 +507,16 @@ static int eth_poll(struct napi_struct *
 
 		if ((n = queue_get_desc(rxq, port, 0)) < 0) {
 #if DEBUG_RX
-			printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
+			printk(KERN_DEBUG "%s: eth_poll napi_complete\n",
 			       dev->name);
 #endif
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			qmgr_enable_irq(rxq);
 			if (!qmgr_stat_empty(rxq) &&
-			    netif_rx_reschedule(napi)) {
+			    napi_reschedule(napi)) {
 #if DEBUG_RX
 				printk(KERN_DEBUG "%s: eth_poll"
-				       " netif_rx_reschedule successed\n",
+				       " napi_reschedule successed\n",
 				       dev->name);
 #endif
 				qmgr_disable_irq(rxq);
@@ -1036,7 +1045,7 @@ static int eth_open(struct net_device *d
 	}
 	ports_open++;
 	/* we may already have RX data, enables IRQ */
-	netif_rx_schedule(&port->napi);
+	napi_schedule(&port->napi);
 	return 0;
 }
 
@@ -1165,7 +1174,7 @@ static int __devinit eth_init_one(struct
 		regs_phys  = IXP4XX_EthC_BASE_PHYS;
 		break;
 	default:
-		err = -ENOSYS;
+		err = -ENODEV;
 		goto err_free;
 	}
 
@@ -1180,15 +1189,10 @@ static int __devinit eth_init_one(struct
 		goto err_free;
 	}
 
-	if (register_netdev(dev)) {
-		err = -EIO;
-		goto err_npe_rel;
-	}
-
 	port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name);
 	if (!port->mem_res) {
 		err = -EBUSY;
-		goto err_unreg;
+		goto err_npe_rel;
 	}
 
 	port->plat = plat;
@@ -1206,20 +1210,25 @@ static int __devinit eth_init_one(struct
 	snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
 	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
 				   PHY_INTERFACE_MODE_MII);
-	if (IS_ERR(port->phydev)) {
-		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-		return PTR_ERR(port->phydev);
-	}
+	if ((err = IS_ERR(port->phydev)))
+		goto err_free_mem;
 
 	port->phydev->irq = PHY_POLL;
 
+	if ((err = register_netdev(dev)))
+		goto err_phy_dis;
+
 	printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy,
 	       npe_name(port->npe));
 
 	return 0;
 
-err_unreg:
-	unregister_netdev(dev);
+err_phy_dis:
+	phy_disconnect(port->phydev);
+err_free_mem:
+	npe_port_tab[NPE_ID(port->id)] = NULL;
+	platform_set_drvdata(pdev, NULL);
+	release_resource(port->mem_res);
 err_npe_rel:
 	npe_release(port->npe);
 err_free:
@@ -1233,6 +1242,7 @@ static int __devexit eth_remove_one(stru
 	struct port *port = netdev_priv(dev);
 
 	unregister_netdev(dev);
+	phy_disconnect(port->phydev);
 	npe_port_tab[NPE_ID(port->id)] = NULL;
 	platform_set_drvdata(pdev, NULL);
 	npe_release(port->npe);
@@ -1250,9 +1260,6 @@ static struct platform_driver ixp4xx_eth
 static int __init eth_init_module(void)
 {
 	int err;
-	if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
-		return -ENOSYS;
-
 	if ((err = ixp4xx_mdio_register()))
 		return err;
 	return platform_driver_register(&ixp4xx_eth_driver);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/arm/ks8695net.c linux-libre-2.6.30-gnu1/drivers/net/arm/ks8695net.c
--- linux-libre-2.6.29-gnu1/drivers/net/arm/ks8695net.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/arm/ks8695net.c	2009-06-09 23:05:27.000000000 -0400
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *nd
 {
 	strlcpy(info->driver, MODULENAME, sizeof(info->driver));
 	strlcpy(info->version, MODULEVERSION, sizeof(info->version));
-	strlcpy(info->bus_info, ndev->dev.parent->bus_id,
+	strlcpy(info->bus_info, dev_name(ndev->dev.parent),
 		sizeof(info->bus_info));
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/at1700.c linux-libre-2.6.30-gnu1/drivers/net/at1700.c
--- linux-libre-2.6.29-gnu1/drivers/net/at1700.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/at1700.c	2009-06-09 23:05:27.000000000 -0400
@@ -249,6 +249,17 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops at1700_netdev_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_start_xmit 	= net_send_packet,
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_tx_timeout 	= net_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
    "signature", the default bit pattern after a reset.  This *doesn't* work --
    there is no way to reset the bus interface without a complete power-cycle!
@@ -448,13 +459,7 @@ found:
 	if (net_debug)
 		printk(version);
 
-	memset(lp, 0, sizeof(struct net_local));
-
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit = net_send_packet;
-	dev->set_multicast_list = &set_rx_mode;
-	dev->tx_timeout = net_tx_timeout;
+	dev->netdev_ops = &at1700_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	spin_lock_init(&lp->lock);
@@ -828,7 +833,6 @@ set_rx_mode(struct net_device *dev)
 	struct net_local *lp = netdev_priv(dev);
 	unsigned char mc_filter[8];		 /* Multicast hash filter */
 	unsigned long flags;
-	int i;
 
 	if (dev->flags & IFF_PROMISC) {
 		memset(mc_filter, 0xff, sizeof(mc_filter));
@@ -857,6 +861,7 @@ set_rx_mode(struct net_device *dev)
 
 	spin_lock_irqsave (&lp->lock, flags);
 	if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
+		int i;
 		int saved_bank = inw(ioaddr + CONFIG_0);
 		/* Switch to bank 1 and set the multicast table. */
 		outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atarilance.c linux-libre-2.6.30-gnu1/drivers/net/atarilance.c
--- linux-libre-2.6.29-gnu1/drivers/net/atarilance.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atarilance.c	2009-06-09 23:05:27.000000000 -0400
@@ -453,6 +453,16 @@ static noinline int __init addr_accessib
 	return( ret );
 }
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_set_mac_address	= lance_set_mac_address,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
 
 static unsigned long __init lance_probe1( struct net_device *dev,
 					   struct lance_addr *init_rec )
@@ -623,15 +633,9 @@ static unsigned long __init lance_probe1
 	if (did_version++ == 0)
 		DPRINTK( 1, ( version ));
 
-	/* The LANCE-specific entries in the device structure. */
-	dev->open = &lance_open;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->stop = &lance_close;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = &lance_set_mac_address;
+	dev->netdev_ops = &lance_netdev_ops;
 
 	/* XXX MSch */
-	dev->tx_timeout = lance_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	return( 1 );
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atl1c/atl1c.h linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c.h
--- linux-libre-2.6.29-gnu1/drivers/net/atl1c/atl1c.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,7 +45,6 @@
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/tcp.h>
-#include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/workqueue.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atl1c/atl1c_main.c linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/atl1c/atl1c_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -2532,8 +2532,8 @@ static int __devinit atl1c_probe(struct
 	 * various kernel subsystems to support the mechanics required by a
 	 * fixed-high-32-bit system.
 	 */
-	if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
-	    (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+	if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+	    (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
 		dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
 		goto err_dma;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e.h linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e.h
--- linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e.h	2009-06-09 23:05:27.000000000 -0400
@@ -448,7 +448,7 @@ struct atl1e_adapter {
 	/* All Descriptor memory */
 	dma_addr_t  	ring_dma;
 	void     	*ring_vir_addr;
-	int             ring_size;
+	u32             ring_size;
 
 	struct atl1e_tx_ring tx_ring;
 	struct atl1e_rx_ring rx_ring;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e_main.c linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,6 +37,7 @@ char atl1e_driver_version[] = DRV_VERSIO
  */
 static struct pci_device_id atl1e_pci_tbl[] = {
 	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
 	/* required last entry */
 	{ 0 }
 };
@@ -1326,9 +1327,9 @@ static irqreturn_t atl1e_intr(int irq, v
 			AT_WRITE_REG(hw, REG_IMR,
 				     IMR_NORMAL_MASK & ~ISR_RX_EVENT);
 			AT_WRITE_FLUSH(hw);
-			if (likely(netif_rx_schedule_prep(
+			if (likely(napi_schedule_prep(
 				   &adapter->napi)))
-				__netif_rx_schedule(&adapter->napi);
+				__napi_schedule(&adapter->napi);
 		}
 	} while (--max_ints > 0);
 	/* re-enable Interrupt*/
@@ -1514,7 +1515,7 @@ static int atl1e_clean(struct napi_struc
 	/* If no Tx and not enough Rx work done, exit the polling mode */
 	if (work_done < budget) {
 quit_polling:
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
 		AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
 		/* test debug */
@@ -2326,8 +2327,8 @@ static int __devinit atl1e_probe(struct
 	 * various kernel subsystems to support the mechanics required by a
 	 * fixed-high-32-bit system.
 	 */
-	if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
-	    (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+	if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+	    (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
 		dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
 		goto err_dma;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e_param.c linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e_param.c
--- linux-libre-2.6.29-gnu1/drivers/net/atl1e/atl1e_param.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atl1e/atl1e_param.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@
 
 #define ATL1E_PARAM(x, desc) \
 	static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
-	static int num_##x; \
+	static unsigned int num_##x; \
 	module_param_array_named(x, x, int, &num_##x, 0); \
 	MODULE_PARM_DESC(x, desc);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atlx/atl1.c linux-libre-2.6.30-gnu1/drivers/net/atlx/atl1.c
--- linux-libre-2.6.29-gnu1/drivers/net/atlx/atl1.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atlx/atl1.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,6 +82,12 @@
 
 #include "atl1.h"
 
+#define ATLX_DRIVER_VERSION "2.1.3"
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
+	Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATLX_DRIVER_VERSION);
+
 /* Temporary hack for merging atl1 and atl2 */
 #include "atlx.c"
 
@@ -105,7 +111,7 @@
  * Default Value: 100 (200us)
  */
 static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_int_mod_timer;
+static unsigned int num_int_mod_timer;
 module_param_array_named(int_mod_timer, int_mod_timer, int,
 	&num_int_mod_timer, 0);
 MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
@@ -2929,7 +2935,7 @@ static int __devinit atl1_probe(struct p
 	 * various kernel subsystems to support the mechanics required by a
 	 * fixed-high-32-bit system.
 	 */
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		dev_err(&pdev->dev, "no usable DMA configuration\n");
 		goto err_dma;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atlx/atl2.c linux-libre-2.6.30-gnu1/drivers/net/atlx/atl2.c
--- linux-libre-2.6.29-gnu1/drivers/net/atlx/atl2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atlx/atl2.c	2009-06-09 23:05:27.000000000 -0400
@@ -1358,8 +1358,8 @@ static int __devinit atl2_probe(struct p
 	 * until the kernel has the proper infrastructure to support 64-bit DMA
 	 * on these devices.
 	 */
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) &&
-		pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
+		pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
 		goto err_dma;
 	}
@@ -2854,7 +2854,7 @@ static void atl2_force_ps(struct atl2_hw
 #else
 #define ATL2_PARAM(X, desc) \
     static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
-    static int num_##X = 0; \
+    static unsigned int num_##X; \
     module_param_array_named(X, X, int, &num_##X, 0); \
     MODULE_PARM_DESC(X, desc);
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/atlx/atlx.h linux-libre-2.6.30-gnu1/drivers/net/atlx/atlx.h
--- linux-libre-2.6.29-gnu1/drivers/net/atlx/atlx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/atlx/atlx.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,12 +29,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
-	Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATLX_DRIVER_VERSION);
-
 #define ATLX_ERR_PHY			2
 #define ATLX_ERR_PHY_SPEED		7
 #define ATLX_ERR_PHY_RES		8
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/au1000_eth.c linux-libre-2.6.30-gnu1/drivers/net/au1000_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/au1000_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/au1000_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,24 +81,6 @@ MODULE_AUTHOR(DRV_AUTHOR);
 MODULE_DESCRIPTION(DRV_DESC);
 MODULE_LICENSE("GPL");
 
-// prototypes
-static void hard_stop(struct net_device *);
-static void enable_rx_tx(struct net_device *dev);
-static struct net_device * au1000_probe(int port_num);
-static int au1000_init(struct net_device *);
-static int au1000_open(struct net_device *);
-static int au1000_close(struct net_device *);
-static int au1000_tx(struct sk_buff *, struct net_device *);
-static int au1000_rx(struct net_device *);
-static irqreturn_t au1000_interrupt(int, void *);
-static void au1000_tx_timeout(struct net_device *);
-static void set_rx_mode(struct net_device *);
-static int au1000_ioctl(struct net_device *, struct ifreq *, int);
-static int au1000_mdio_read(struct net_device *, int, int);
-static void au1000_mdio_write(struct net_device *, int, int, u16);
-static void au1000_adjust_link(struct net_device *);
-static void enable_mac(struct net_device *, int);
-
 /*
  * Theory of operation
  *
@@ -188,6 +170,26 @@ struct au1000_private *au_macs[NUM_ETH_I
 # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
 #endif
 
+static void enable_mac(struct net_device *dev, int force_reset)
+{
+	unsigned long flags;
+	struct au1000_private *aup = netdev_priv(dev);
+
+	spin_lock_irqsave(&aup->lock, flags);
+
+	if(force_reset || (!aup->mac_enabled)) {
+		*aup->enable = MAC_EN_CLOCK_ENABLE;
+		au_sync_delay(2);
+		*aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+				| MAC_EN_CLOCK_ENABLE);
+		au_sync_delay(2);
+
+		aup->mac_enabled = 1;
+	}
+
+	spin_unlock_irqrestore(&aup->lock, flags);
+}
+
 /*
  * MII operations
  */
@@ -281,6 +283,107 @@ static int au1000_mdiobus_reset(struct m
 	return 0;
 }
 
+static void hard_stop(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+
+	if (au1000_debug > 4)
+		printk(KERN_INFO "%s: hard stop\n", dev->name);
+
+	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+	au_sync_delay(10);
+}
+
+static void enable_rx_tx(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+
+	if (au1000_debug > 4)
+		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+
+	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+	au_sync_delay(10);
+}
+
+static void
+au1000_adjust_link(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	struct phy_device *phydev = aup->phy_dev;
+	unsigned long flags;
+
+	int status_change = 0;
+
+	BUG_ON(!aup->phy_dev);
+
+	spin_lock_irqsave(&aup->lock, flags);
+
+	if (phydev->link && (aup->old_speed != phydev->speed)) {
+		// speed changed
+
+		switch(phydev->speed) {
+		case SPEED_10:
+		case SPEED_100:
+			break;
+		default:
+			printk(KERN_WARNING
+			       "%s: Speed (%d) is not 10/100 ???\n",
+			       dev->name, phydev->speed);
+			break;
+		}
+
+		aup->old_speed = phydev->speed;
+
+		status_change = 1;
+	}
+
+	if (phydev->link && (aup->old_duplex != phydev->duplex)) {
+		// duplex mode changed
+
+		/* switching duplex mode requires to disable rx and tx! */
+		hard_stop(dev);
+
+		if (DUPLEX_FULL == phydev->duplex)
+			aup->mac->control = ((aup->mac->control
+					     | MAC_FULL_DUPLEX)
+					     & ~MAC_DISABLE_RX_OWN);
+		else
+			aup->mac->control = ((aup->mac->control
+					      & ~MAC_FULL_DUPLEX)
+					     | MAC_DISABLE_RX_OWN);
+		au_sync_delay(1);
+
+		enable_rx_tx(dev);
+		aup->old_duplex = phydev->duplex;
+
+		status_change = 1;
+	}
+
+	if(phydev->link != aup->old_link) {
+		// link state changed
+
+		if (!phydev->link) {
+			/* link went down */
+			aup->old_speed = 0;
+			aup->old_duplex = -1;
+		}
+
+		aup->old_link = phydev->link;
+		status_change = 1;
+	}
+
+	spin_unlock_irqrestore(&aup->lock, flags);
+
+	if (status_change) {
+		if (phydev->link)
+			printk(KERN_INFO "%s: link up (%d/%s)\n",
+			       dev->name, phydev->speed,
+			       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+		else
+			printk(KERN_INFO "%s: link down\n", dev->name);
+	}
+}
+
 static int mii_probe (struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
@@ -355,8 +458,8 @@ static int mii_probe (struct net_device
 	/* now we are supposed to have a proper phydev, to attach to... */
 	BUG_ON(phydev->attached_dev);
 
-	phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
-			PHY_INTERFACE_MODE_MII);
+	phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link,
+			0, PHY_INTERFACE_MODE_MII);
 
 	if (IS_ERR(phydev)) {
 		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -381,8 +484,8 @@ static int mii_probe (struct net_device
 	aup->phy_dev = phydev;
 
 	printk(KERN_INFO "%s: attached PHY driver [%s] "
-	       "(mii_bus:phy_addr=%s, irq=%d)\n",
-	       dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+	       "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+	       phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 
 	return 0;
 }
@@ -412,48 +515,6 @@ void ReleaseDB(struct au1000_private *au
 	aup->pDBfree = pDB;
 }
 
-static void enable_rx_tx(struct net_device *dev)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
-
-	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
-	au_sync_delay(10);
-}
-
-static void hard_stop(struct net_device *dev)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: hard stop\n", dev->name);
-
-	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
-	au_sync_delay(10);
-}
-
-static void enable_mac(struct net_device *dev, int force_reset)
-{
-	unsigned long flags;
-	struct au1000_private *aup = netdev_priv(dev);
-
-	spin_lock_irqsave(&aup->lock, flags);
-
-	if(force_reset || (!aup->mac_enabled)) {
-		*aup->enable = MAC_EN_CLOCK_ENABLE;
-		au_sync_delay(2);
-		*aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
-				| MAC_EN_CLOCK_ENABLE);
-		au_sync_delay(2);
-
-		aup->mac_enabled = 1;
-	}
-
-	spin_unlock_irqrestore(&aup->lock, flags);
-}
-
 static void reset_mac_unlocked(struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
@@ -542,30 +603,6 @@ static struct {
 static int num_ifs;
 
 /*
- * Setup the base address and interrupt of the Au1xxx ethernet macs
- * based on cpu type and whether the interface is enabled in sys_pinfunc
- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
- */
-static int __init au1000_init_module(void)
-{
-	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
-	struct net_device *dev;
-	int i, found_one = 0;
-
-	num_ifs = NUM_ETH_INTERFACES - ni;
-
-	for(i = 0; i < num_ifs; i++) {
-		dev = au1000_probe(i);
-		iflist[i].dev = dev;
-		if (dev)
-			found_one++;
-	}
-	if (!found_one)
-		return -ENODEV;
-	return 0;
-}
-
-/*
  * ethtool operations
  */
 
@@ -611,199 +648,6 @@ static const struct ethtool_ops au1000_e
 	.get_link = ethtool_op_get_link,
 };
 
-static struct net_device * au1000_probe(int port_num)
-{
-	static unsigned version_printed = 0;
-	struct au1000_private *aup = NULL;
-	struct net_device *dev = NULL;
-	db_dest_t *pDB, *pDBfree;
-	char ethaddr[6];
-	int irq, i, err;
-	u32 base, macen;
-
-	if (port_num >= NUM_ETH_INTERFACES)
- 		return NULL;
-
-	base  = CPHYSADDR(iflist[port_num].base_addr );
-	macen = CPHYSADDR(iflist[port_num].macen_addr);
-	irq = iflist[port_num].irq;
-
-	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
-	    !request_mem_region(macen, 4, "Au1x00 ENET"))
-		return NULL;
-
-	if (version_printed++ == 0)
-		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
-
-	dev = alloc_etherdev(sizeof(struct au1000_private));
-	if (!dev) {
-		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
-		return NULL;
-	}
-
-	if ((err = register_netdev(dev)) != 0) {
-		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
-				DRV_NAME, err);
-		free_netdev(dev);
-		return NULL;
-	}
-
-	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
-		dev->name, base, irq);
-
-	aup = netdev_priv(dev);
-
-	spin_lock_init(&aup->lock);
-
-	/* Allocate the data buffers */
-	/* Snooping works fine with eth on all au1xxx */
-	aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
-						(NUM_TX_BUFFS + NUM_RX_BUFFS),
-						&aup->dma_addr,	0);
-	if (!aup->vaddr) {
-		free_netdev(dev);
-		release_mem_region( base, MAC_IOSIZE);
-		release_mem_region(macen, 4);
-		return NULL;
-	}
-
-	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
-
-	/* Setup some variables for quick register address access */
-	aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
-	aup->mac_id = port_num;
-	au_macs[port_num] = aup;
-
-	if (port_num == 0) {
-		if (prom_get_ethernet_addr(ethaddr) == 0)
-			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
-		else {
-			printk(KERN_INFO "%s: No MAC address found\n",
-					 dev->name);
-				/* Use the hard coded MAC addresses */
-		}
-
-		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-	} else if (port_num == 1)
-		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-
-	/*
-	 * Assign to the Ethernet ports two consecutive MAC addresses
-	 * to match those that are printed on their stickers
-	 */
-	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
-	dev->dev_addr[5] += port_num;
-
-	*aup->enable = 0;
-	aup->mac_enabled = 0;
-
-	aup->mii_bus = mdiobus_alloc();
-	if (aup->mii_bus == NULL)
-		goto err_out;
-
-	aup->mii_bus->priv = dev;
-	aup->mii_bus->read = au1000_mdiobus_read;
-	aup->mii_bus->write = au1000_mdiobus_write;
-	aup->mii_bus->reset = au1000_mdiobus_reset;
-	aup->mii_bus->name = "au1000_eth_mii";
-	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
-	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-	for(i = 0; i < PHY_MAX_ADDR; ++i)
-		aup->mii_bus->irq[i] = PHY_POLL;
-
-	/* if known, set corresponding PHY IRQs */
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-# if defined(AU1XXX_PHY0_IRQ)
-	if (AU1XXX_PHY0_BUSID == aup->mac_id)
-		aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
-# endif
-# if defined(AU1XXX_PHY1_IRQ)
-	if (AU1XXX_PHY1_BUSID == aup->mac_id)
-		aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
-# endif
-#endif
-	mdiobus_register(aup->mii_bus);
-
-	if (mii_probe(dev) != 0) {
-		goto err_out;
-	}
-
-	pDBfree = NULL;
-	/* setup the data buffer descriptors and attach a buffer to each one */
-	pDB = aup->db;
-	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
-		pDB->pnext = pDBfree;
-		pDBfree = pDB;
-		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
-		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
-		pDB++;
-	}
-	aup->pDBfree = pDBfree;
-
-	for (i = 0; i < NUM_RX_DMA; i++) {
-		pDB = GetFreeDB(aup);
-		if (!pDB) {
-			goto err_out;
-		}
-		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
-		aup->rx_db_inuse[i] = pDB;
-	}
-	for (i = 0; i < NUM_TX_DMA; i++) {
-		pDB = GetFreeDB(aup);
-		if (!pDB) {
-			goto err_out;
-		}
-		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
-		aup->tx_dma_ring[i]->len = 0;
-		aup->tx_db_inuse[i] = pDB;
-	}
-
-	dev->base_addr = base;
-	dev->irq = irq;
-	dev->open = au1000_open;
-	dev->hard_start_xmit = au1000_tx;
-	dev->stop = au1000_close;
-	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &au1000_ioctl;
-	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
-	dev->tx_timeout = au1000_tx_timeout;
-	dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
-	/*
-	 * The boot code uses the ethernet controller, so reset it to start
-	 * fresh.  au1000_init() expects that the device is in reset state.
-	 */
-	reset_mac(dev);
-
-	return dev;
-
-err_out:
-	if (aup->mii_bus != NULL) {
-		mdiobus_unregister(aup->mii_bus);
-		mdiobus_free(aup->mii_bus);
-	}
-
-	/* here we should have a valid dev plus aup-> register addresses
-	 * so we can reset the mac properly.*/
-	reset_mac(dev);
-
-	for (i = 0; i < NUM_RX_DMA; i++) {
-		if (aup->rx_db_inuse[i])
-			ReleaseDB(aup, aup->rx_db_inuse[i]);
-	}
-	for (i = 0; i < NUM_TX_DMA; i++) {
-		if (aup->tx_db_inuse[i])
-			ReleaseDB(aup, aup->tx_db_inuse[i]);
-	}
-	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
-			     (void *)aup->vaddr, aup->dma_addr);
-	unregister_netdev(dev);
-	free_netdev(dev);
-	release_mem_region( base, MAC_IOSIZE);
-	release_mem_region(macen, 4);
-	return NULL;
-}
 
 /*
  * Initialize the interface.
@@ -864,83 +708,170 @@ static int au1000_init(struct net_device
 	return 0;
 }
 
-static void
-au1000_adjust_link(struct net_device *dev)
+static inline void update_rx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = netdev_priv(dev);
-	struct phy_device *phydev = aup->phy_dev;
-	unsigned long flags;
+	struct net_device_stats *ps = &dev->stats;
 
-	int status_change = 0;
+	ps->rx_packets++;
+	if (status & RX_MCAST_FRAME)
+		ps->multicast++;
 
-	BUG_ON(!aup->phy_dev);
+	if (status & RX_ERROR) {
+		ps->rx_errors++;
+		if (status & RX_MISSED_FRAME)
+			ps->rx_missed_errors++;
+		if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
+			ps->rx_length_errors++;
+		if (status & RX_CRC_ERROR)
+			ps->rx_crc_errors++;
+		if (status & RX_COLL)
+			ps->collisions++;
+	}
+	else
+		ps->rx_bytes += status & RX_FRAME_LEN_MASK;
 
-	spin_lock_irqsave(&aup->lock, flags);
+}
 
-	if (phydev->link && (aup->old_speed != phydev->speed)) {
-		// speed changed
+/*
+ * Au1000 receive routine.
+ */
+static int au1000_rx(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	struct sk_buff *skb;
+	volatile rx_dma_t *prxd;
+	u32 buff_stat, status;
+	db_dest_t *pDB;
+	u32	frmlen;
 
-		switch(phydev->speed) {
-		case SPEED_10:
-		case SPEED_100:
-			break;
-		default:
-			printk(KERN_WARNING
-			       "%s: Speed (%d) is not 10/100 ???\n",
-			       dev->name, phydev->speed);
-			break;
-		}
+	if (au1000_debug > 5)
+		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
 
-		aup->old_speed = phydev->speed;
+	prxd = aup->rx_dma_ring[aup->rx_head];
+	buff_stat = prxd->buff_stat;
+	while (buff_stat & RX_T_DONE)  {
+		status = prxd->status;
+		pDB = aup->rx_db_inuse[aup->rx_head];
+		update_rx_stats(dev, status);
+		if (!(status & RX_ERROR))  {
 
-		status_change = 1;
+			/* good frame */
+			frmlen = (status & RX_FRAME_LEN_MASK);
+			frmlen -= 4; /* Remove FCS */
+			skb = dev_alloc_skb(frmlen + 2);
+			if (skb == NULL) {
+				printk(KERN_ERR
+				       "%s: Memory squeeze, dropping packet.\n",
+				       dev->name);
+				dev->stats.rx_dropped++;
+				continue;
+			}
+			skb_reserve(skb, 2);	/* 16 byte IP header align */
+			skb_copy_to_linear_data(skb,
+				(unsigned char *)pDB->vaddr, frmlen);
+			skb_put(skb, frmlen);
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);	/* pass the packet to upper layers */
+		}
+		else {
+			if (au1000_debug > 4) {
+				if (status & RX_MISSED_FRAME)
+					printk("rx miss\n");
+				if (status & RX_WDOG_TIMER)
+					printk("rx wdog\n");
+				if (status & RX_RUNT)
+					printk("rx runt\n");
+				if (status & RX_OVERLEN)
+					printk("rx overlen\n");
+				if (status & RX_COLL)
+					printk("rx coll\n");
+				if (status & RX_MII_ERROR)
+					printk("rx mii error\n");
+				if (status & RX_CRC_ERROR)
+					printk("rx crc error\n");
+				if (status & RX_LEN_ERROR)
+					printk("rx len error\n");
+				if (status & RX_U_CNTRL_FRAME)
+					printk("rx u control frame\n");
+				if (status & RX_MISSED_FRAME)
+					printk("rx miss\n");
+			}
+		}
+		prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
+		aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
+		au_sync();
+
+		/* next descriptor */
+		prxd = aup->rx_dma_ring[aup->rx_head];
+		buff_stat = prxd->buff_stat;
 	}
+	return 0;
+}
 
-	if (phydev->link && (aup->old_duplex != phydev->duplex)) {
-		// duplex mode changed
+static void update_tx_stats(struct net_device *dev, u32 status)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	struct net_device_stats *ps = &dev->stats;
 
-		/* switching duplex mode requires to disable rx and tx! */
-		hard_stop(dev);
+	if (status & TX_FRAME_ABORTED) {
+		if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
+			if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
+				/* any other tx errors are only valid
+				 * in half duplex mode */
+				ps->tx_errors++;
+				ps->tx_aborted_errors++;
+			}
+		}
+		else {
+			ps->tx_errors++;
+			ps->tx_aborted_errors++;
+			if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
+				ps->tx_carrier_errors++;
+		}
+	}
+}
 
-		if (DUPLEX_FULL == phydev->duplex)
-			aup->mac->control = ((aup->mac->control
-					     | MAC_FULL_DUPLEX)
-					     & ~MAC_DISABLE_RX_OWN);
-		else
-			aup->mac->control = ((aup->mac->control
-					      & ~MAC_FULL_DUPLEX)
-					     | MAC_DISABLE_RX_OWN);
-		au_sync_delay(1);
+/*
+ * Called from the interrupt service routine to acknowledge
+ * the TX DONE bits.  This is a must if the irq is setup as
+ * edge triggered.
+ */
+static void au1000_tx_ack(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	volatile tx_dma_t *ptxd;
 
-		enable_rx_tx(dev);
-		aup->old_duplex = phydev->duplex;
+	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
-		status_change = 1;
-	}
+	while (ptxd->buff_stat & TX_T_DONE) {
+		update_tx_stats(dev, ptxd->status);
+		ptxd->buff_stat &= ~TX_T_DONE;
+		ptxd->len = 0;
+		au_sync();
 
-	if(phydev->link != aup->old_link) {
-		// link state changed
+		aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
+		ptxd = aup->tx_dma_ring[aup->tx_tail];
 
-		if (!phydev->link) {
-			/* link went down */
-			aup->old_speed = 0;
-			aup->old_duplex = -1;
+		if (aup->tx_full) {
+			aup->tx_full = 0;
+			netif_wake_queue(dev);
 		}
-
-		aup->old_link = phydev->link;
-		status_change = 1;
 	}
+}
 
-	spin_unlock_irqrestore(&aup->lock, flags);
+/*
+ * Au1000 interrupt service routine.
+ */
+static irqreturn_t au1000_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
 
-	if (status_change) {
-		if (phydev->link)
-			printk(KERN_INFO "%s: link up (%d/%s)\n",
-			       dev->name, phydev->speed,
-			       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
-		else
-			printk(KERN_INFO "%s: link down\n", dev->name);
-	}
+	/* Handle RX interrupts first to minimize chance of overrun */
+
+	au1000_rx(dev);
+	au1000_tx_ack(dev);
+	return IRQ_RETVAL(1);
 }
 
 static int au1000_open(struct net_device *dev)
@@ -1003,88 +934,6 @@ static int au1000_close(struct net_devic
 	return 0;
 }
 
-static void __exit au1000_cleanup_module(void)
-{
-	int i, j;
-	struct net_device *dev;
-	struct au1000_private *aup;
-
-	for (i = 0; i < num_ifs; i++) {
-		dev = iflist[i].dev;
-		if (dev) {
-			aup = netdev_priv(dev);
-			unregister_netdev(dev);
-			mdiobus_unregister(aup->mii_bus);
-			mdiobus_free(aup->mii_bus);
-			for (j = 0; j < NUM_RX_DMA; j++)
-				if (aup->rx_db_inuse[j])
-					ReleaseDB(aup, aup->rx_db_inuse[j]);
-			for (j = 0; j < NUM_TX_DMA; j++)
-				if (aup->tx_db_inuse[j])
-					ReleaseDB(aup, aup->tx_db_inuse[j]);
- 			dma_free_noncoherent(NULL, MAX_BUF_SIZE *
- 					     (NUM_TX_BUFFS + NUM_RX_BUFFS),
- 					     (void *)aup->vaddr, aup->dma_addr);
- 			release_mem_region(dev->base_addr, MAC_IOSIZE);
- 			release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
-			free_netdev(dev);
-		}
-	}
-}
-
-static void update_tx_stats(struct net_device *dev, u32 status)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-	struct net_device_stats *ps = &dev->stats;
-
-	if (status & TX_FRAME_ABORTED) {
-		if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
-			if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
-				/* any other tx errors are only valid
-				 * in half duplex mode */
-				ps->tx_errors++;
-				ps->tx_aborted_errors++;
-			}
-		}
-		else {
-			ps->tx_errors++;
-			ps->tx_aborted_errors++;
-			if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
-				ps->tx_carrier_errors++;
-		}
-	}
-}
-
-
-/*
- * Called from the interrupt service routine to acknowledge
- * the TX DONE bits.  This is a must if the irq is setup as
- * edge triggered.
- */
-static void au1000_tx_ack(struct net_device *dev)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-	volatile tx_dma_t *ptxd;
-
-	ptxd = aup->tx_dma_ring[aup->tx_tail];
-
-	while (ptxd->buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status);
-		ptxd->buff_stat &= ~TX_T_DONE;
-		ptxd->len = 0;
-		au_sync();
-
-		aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
-		ptxd = aup->tx_dma_ring[aup->tx_tail];
-
-		if (aup->tx_full) {
-			aup->tx_full = 0;
-			netif_wake_queue(dev);
-		}
-	}
-}
-
-
 /*
  * Au1000 transmit routine.
  */
@@ -1142,123 +991,6 @@ static int au1000_tx(struct sk_buff *skb
 	return 0;
 }
 
-static inline void update_rx_stats(struct net_device *dev, u32 status)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-	struct net_device_stats *ps = &dev->stats;
-
-	ps->rx_packets++;
-	if (status & RX_MCAST_FRAME)
-		ps->multicast++;
-
-	if (status & RX_ERROR) {
-		ps->rx_errors++;
-		if (status & RX_MISSED_FRAME)
-			ps->rx_missed_errors++;
-		if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
-			ps->rx_length_errors++;
-		if (status & RX_CRC_ERROR)
-			ps->rx_crc_errors++;
-		if (status & RX_COLL)
-			ps->collisions++;
-	}
-	else
-		ps->rx_bytes += status & RX_FRAME_LEN_MASK;
-
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1000_rx(struct net_device *dev)
-{
-	struct au1000_private *aup = netdev_priv(dev);
-	struct sk_buff *skb;
-	volatile rx_dma_t *prxd;
-	u32 buff_stat, status;
-	db_dest_t *pDB;
-	u32	frmlen;
-
-	if (au1000_debug > 5)
-		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
-
-	prxd = aup->rx_dma_ring[aup->rx_head];
-	buff_stat = prxd->buff_stat;
-	while (buff_stat & RX_T_DONE)  {
-		status = prxd->status;
-		pDB = aup->rx_db_inuse[aup->rx_head];
-		update_rx_stats(dev, status);
-		if (!(status & RX_ERROR))  {
-
-			/* good frame */
-			frmlen = (status & RX_FRAME_LEN_MASK);
-			frmlen -= 4; /* Remove FCS */
-			skb = dev_alloc_skb(frmlen + 2);
-			if (skb == NULL) {
-				printk(KERN_ERR
-				       "%s: Memory squeeze, dropping packet.\n",
-				       dev->name);
-				dev->stats.rx_dropped++;
-				continue;
-			}
-			skb_reserve(skb, 2);	/* 16 byte IP header align */
-			skb_copy_to_linear_data(skb,
-				(unsigned char *)pDB->vaddr, frmlen);
-			skb_put(skb, frmlen);
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);	/* pass the packet to upper layers */
-		}
-		else {
-			if (au1000_debug > 4) {
-				if (status & RX_MISSED_FRAME)
-					printk("rx miss\n");
-				if (status & RX_WDOG_TIMER)
-					printk("rx wdog\n");
-				if (status & RX_RUNT)
-					printk("rx runt\n");
-				if (status & RX_OVERLEN)
-					printk("rx overlen\n");
-				if (status & RX_COLL)
-					printk("rx coll\n");
-				if (status & RX_MII_ERROR)
-					printk("rx mii error\n");
-				if (status & RX_CRC_ERROR)
-					printk("rx crc error\n");
-				if (status & RX_LEN_ERROR)
-					printk("rx len error\n");
-				if (status & RX_U_CNTRL_FRAME)
-					printk("rx u control frame\n");
-				if (status & RX_MISSED_FRAME)
-					printk("rx miss\n");
-			}
-		}
-		prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
-		aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
-		au_sync();
-
-		/* next descriptor */
-		prxd = aup->rx_dma_ring[aup->rx_head];
-		buff_stat = prxd->buff_stat;
-	}
-	return 0;
-}
-
-
-/*
- * Au1000 interrupt service routine.
- */
-static irqreturn_t au1000_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-
-	/* Handle RX interrupts first to minimize chance of overrun */
-
-	au1000_rx(dev);
-	au1000_tx_ack(dev);
-	return IRQ_RETVAL(1);
-}
-
-
 /*
  * The Tx ring has been full longer than the watchdog timeout
  * value. The transmitter must be hung?
@@ -1272,12 +1004,12 @@ static void au1000_tx_timeout(struct net
 	netif_wake_queue(dev);
 }
 
-static void set_rx_mode(struct net_device *dev)
+static void au1000_multicast_list(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
 	if (au1000_debug > 4)
-		printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
+		printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags);
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
@@ -1315,5 +1047,259 @@ static int au1000_ioctl(struct net_devic
 	return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
 }
 
+static const struct net_device_ops au1000_netdev_ops = {
+	.ndo_open		= au1000_open,
+	.ndo_stop		= au1000_close,
+	.ndo_start_xmit		= au1000_tx,
+	.ndo_set_multicast_list	= au1000_multicast_list,
+	.ndo_do_ioctl		= au1000_ioctl,
+	.ndo_tx_timeout		= au1000_tx_timeout,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
+static struct net_device * au1000_probe(int port_num)
+{
+	static unsigned version_printed = 0;
+	struct au1000_private *aup = NULL;
+	struct net_device *dev = NULL;
+	db_dest_t *pDB, *pDBfree;
+	char ethaddr[6];
+	int irq, i, err;
+	u32 base, macen;
+
+	if (port_num >= NUM_ETH_INTERFACES)
+		return NULL;
+
+	base  = CPHYSADDR(iflist[port_num].base_addr );
+	macen = CPHYSADDR(iflist[port_num].macen_addr);
+	irq = iflist[port_num].irq;
+
+	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
+	    !request_mem_region(macen, 4, "Au1x00 ENET"))
+		return NULL;
+
+	if (version_printed++ == 0)
+		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+	dev = alloc_etherdev(sizeof(struct au1000_private));
+	if (!dev) {
+		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
+		return NULL;
+	}
+
+	if ((err = register_netdev(dev)) != 0) {
+		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
+				DRV_NAME, err);
+		free_netdev(dev);
+		return NULL;
+	}
+
+	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
+		dev->name, base, irq);
+
+	aup = netdev_priv(dev);
+
+	spin_lock_init(&aup->lock);
+
+	/* Allocate the data buffers */
+	/* Snooping works fine with eth on all au1xxx */
+	aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
+						(NUM_TX_BUFFS + NUM_RX_BUFFS),
+						&aup->dma_addr,	0);
+	if (!aup->vaddr) {
+		free_netdev(dev);
+		release_mem_region( base, MAC_IOSIZE);
+		release_mem_region(macen, 4);
+		return NULL;
+	}
+
+	/* aup->mac is the base address of the MAC's registers */
+	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
+
+	/* Setup some variables for quick register address access */
+	aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
+	aup->mac_id = port_num;
+	au_macs[port_num] = aup;
+
+	if (port_num == 0) {
+		if (prom_get_ethernet_addr(ethaddr) == 0)
+			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+		else {
+			printk(KERN_INFO "%s: No MAC address found\n",
+					 dev->name);
+				/* Use the hard coded MAC addresses */
+		}
+
+		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+	} else if (port_num == 1)
+		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+
+	/*
+	 * Assign to the Ethernet ports two consecutive MAC addresses
+	 * to match those that are printed on their stickers
+	 */
+	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+	dev->dev_addr[5] += port_num;
+
+	*aup->enable = 0;
+	aup->mac_enabled = 0;
+
+	aup->mii_bus = mdiobus_alloc();
+	if (aup->mii_bus == NULL)
+		goto err_out;
+
+	aup->mii_bus->priv = dev;
+	aup->mii_bus->read = au1000_mdiobus_read;
+	aup->mii_bus->write = au1000_mdiobus_write;
+	aup->mii_bus->reset = au1000_mdiobus_reset;
+	aup->mii_bus->name = "au1000_eth_mii";
+	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
+	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+	for(i = 0; i < PHY_MAX_ADDR; ++i)
+		aup->mii_bus->irq[i] = PHY_POLL;
+
+	/* if known, set corresponding PHY IRQs */
+#if defined(AU1XXX_PHY_STATIC_CONFIG)
+# if defined(AU1XXX_PHY0_IRQ)
+	if (AU1XXX_PHY0_BUSID == aup->mac_id)
+		aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
+# endif
+# if defined(AU1XXX_PHY1_IRQ)
+	if (AU1XXX_PHY1_BUSID == aup->mac_id)
+		aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
+# endif
+#endif
+	mdiobus_register(aup->mii_bus);
+
+	if (mii_probe(dev) != 0) {
+		goto err_out;
+	}
+
+	pDBfree = NULL;
+	/* setup the data buffer descriptors and attach a buffer to each one */
+	pDB = aup->db;
+	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+		pDB->pnext = pDBfree;
+		pDBfree = pDB;
+		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
+		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+		pDB++;
+	}
+	aup->pDBfree = pDBfree;
+
+	for (i = 0; i < NUM_RX_DMA; i++) {
+		pDB = GetFreeDB(aup);
+		if (!pDB) {
+			goto err_out;
+		}
+		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+		aup->rx_db_inuse[i] = pDB;
+	}
+	for (i = 0; i < NUM_TX_DMA; i++) {
+		pDB = GetFreeDB(aup);
+		if (!pDB) {
+			goto err_out;
+		}
+		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+		aup->tx_dma_ring[i]->len = 0;
+		aup->tx_db_inuse[i] = pDB;
+	}
+
+	dev->base_addr = base;
+	dev->irq = irq;
+	dev->netdev_ops = &au1000_netdev_ops;
+	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+	dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+	/*
+	 * The boot code uses the ethernet controller, so reset it to start
+	 * fresh.  au1000_init() expects that the device is in reset state.
+	 */
+	reset_mac(dev);
+
+	return dev;
+
+err_out:
+	if (aup->mii_bus != NULL) {
+		mdiobus_unregister(aup->mii_bus);
+		mdiobus_free(aup->mii_bus);
+	}
+
+	/* here we should have a valid dev plus aup-> register addresses
+	 * so we can reset the mac properly.*/
+	reset_mac(dev);
+
+	for (i = 0; i < NUM_RX_DMA; i++) {
+		if (aup->rx_db_inuse[i])
+			ReleaseDB(aup, aup->rx_db_inuse[i]);
+	}
+	for (i = 0; i < NUM_TX_DMA; i++) {
+		if (aup->tx_db_inuse[i])
+			ReleaseDB(aup, aup->tx_db_inuse[i]);
+	}
+	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+			     (void *)aup->vaddr, aup->dma_addr);
+	unregister_netdev(dev);
+	free_netdev(dev);
+	release_mem_region( base, MAC_IOSIZE);
+	release_mem_region(macen, 4);
+	return NULL;
+}
+
+/*
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
+ * based on cpu type and whether the interface is enabled in sys_pinfunc
+ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+ */
+static int __init au1000_init_module(void)
+{
+	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+	struct net_device *dev;
+	int i, found_one = 0;
+
+	num_ifs = NUM_ETH_INTERFACES - ni;
+
+	for(i = 0; i < num_ifs; i++) {
+		dev = au1000_probe(i);
+		iflist[i].dev = dev;
+		if (dev)
+			found_one++;
+	}
+	if (!found_one)
+		return -ENODEV;
+	return 0;
+}
+
+static void __exit au1000_cleanup_module(void)
+{
+	int i, j;
+	struct net_device *dev;
+	struct au1000_private *aup;
+
+	for (i = 0; i < num_ifs; i++) {
+		dev = iflist[i].dev;
+		if (dev) {
+			aup = netdev_priv(dev);
+			unregister_netdev(dev);
+			mdiobus_unregister(aup->mii_bus);
+			mdiobus_free(aup->mii_bus);
+			for (j = 0; j < NUM_RX_DMA; j++)
+				if (aup->rx_db_inuse[j])
+					ReleaseDB(aup, aup->rx_db_inuse[j]);
+			for (j = 0; j < NUM_TX_DMA; j++)
+				if (aup->tx_db_inuse[j])
+					ReleaseDB(aup, aup->tx_db_inuse[j]);
+			dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+					     (NUM_TX_BUFFS + NUM_RX_BUFFS),
+					     (void *)aup->vaddr, aup->dma_addr);
+			release_mem_region(dev->base_addr, MAC_IOSIZE);
+			release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
+			free_netdev(dev);
+		}
+	}
+}
+
 module_init(au1000_init_module);
 module_exit(au1000_cleanup_module);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ax88796.c linux-libre-2.6.30-gnu1/drivers/net/ax88796.c
--- linux-libre-2.6.29-gnu1/drivers/net/ax88796.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ax88796.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,6 +93,7 @@ struct ax_device {
 
 	unsigned char		 running;
 	unsigned char		 resume_open;
+	unsigned int		 irqflags;
 
 	u32			 reg_offsets[0x20];
 };
@@ -474,7 +475,8 @@ static int ax_open(struct net_device *de
 
 	dev_dbg(&ax->dev->dev, "%s: open\n", dev->name);
 
-	ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+	ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+			  dev->name, dev);
 	if (ret)
 		return ret;
 
@@ -731,12 +733,19 @@ static int ax_init_dev(struct net_device
 	/* load the mac-address from the device if this is the
 	 * first time we've initialised */
 
-	if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
-		ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
-			ei_local->mem + E8390_CMD); /* 0x61 */
+	if (first_init) {
+		if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
+			ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+				ei_local->mem + E8390_CMD); /* 0x61 */
+			for (i = 0; i < ETHER_ADDR_LEN; i++)
+				dev->dev_addr[i] =
+					ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+		}
 
-		for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
-			dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+		if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
+		     ax->plat->mac_addr)
+			memcpy(dev->dev_addr, ax->plat->mac_addr,
+				ETHER_ADDR_LEN);
 	}
 
 	ax_reset_8390(dev);
@@ -829,7 +838,7 @@ static int ax_probe(struct platform_devi
 	struct ax_device  *ax;
 	struct resource   *res;
 	size_t size;
-	int ret;
+	int ret = 0;
 
 	dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
 	if (dev == NULL)
@@ -850,12 +859,14 @@ static int ax_probe(struct platform_devi
 
 	/* find the platform resources */
 
-	ret  = platform_get_irq(pdev, 0);
-	if (ret < 0) {
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res == NULL) {
 		dev_err(&pdev->dev, "no IRQ specified\n");
 		goto exit_mem;
 	}
-	dev->irq = ret;
+
+	dev->irq = res->start;
+	ax->irqflags = res->flags & IRQF_TRIGGER_MASK;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/b44.c linux-libre-2.6.30-gnu1/drivers/net/b44.c
--- linux-libre-2.6.29-gnu1/drivers/net/b44.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/b44.c	2009-06-09 23:05:27.000000000 -0400
@@ -660,7 +660,7 @@ static int b44_alloc_rx_skb(struct b44 *
 	/* Hardware bug work-around, the chip is unable to do PCI DMA
 	   to/from anything above 1GB :-( */
 	if (ssb_dma_mapping_error(bp->sdev, mapping) ||
-		mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+		mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
 		/* Sigh... */
 		if (!ssb_dma_mapping_error(bp->sdev, mapping))
 			ssb_dma_unmap_single(bp->sdev, mapping,
@@ -673,7 +673,7 @@ static int b44_alloc_rx_skb(struct b44 *
 					     RX_PKT_BUF_SZ,
 					     DMA_FROM_DEVICE);
 		if (ssb_dma_mapping_error(bp->sdev, mapping) ||
-			mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+			mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
 			if (!ssb_dma_mapping_error(bp->sdev, mapping))
 				ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
 			dev_kfree_skb_any(skb);
@@ -703,7 +703,7 @@ static int b44_alloc_rx_skb(struct b44 *
 
 	if (bp->flags & B44_FLAG_RX_RING_HACK)
 		b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
-			                    dest_idx * sizeof(dp),
+			                    dest_idx * sizeof(*dp),
 			                    DMA_BIDIRECTIONAL);
 
 	return RX_PKT_BUF_SZ;
@@ -731,7 +731,7 @@ static void b44_recycle_rx(struct b44 *b
 
 	if (bp->flags & B44_FLAG_RX_RING_HACK)
 		b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
-			                 src_idx * sizeof(src_desc),
+			                 src_idx * sizeof(*src_desc),
 			                 DMA_BIDIRECTIONAL);
 
 	ctrl = src_desc->ctrl;
@@ -747,10 +747,10 @@ static void b44_recycle_rx(struct b44 *b
 
 	if (bp->flags & B44_FLAG_RX_RING_HACK)
 		b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
-					     dest_idx * sizeof(dest_desc),
+					     dest_idx * sizeof(*dest_desc),
 					     DMA_BIDIRECTIONAL);
 
-	ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
+	ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping,
 				       RX_PKT_BUF_SZ,
 				       DMA_FROM_DEVICE);
 }
@@ -874,7 +874,7 @@ static int b44_poll(struct napi_struct *
 	}
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		b44_enable_ints(bp);
 	}
 
@@ -906,13 +906,13 @@ static irqreturn_t b44_interrupt(int irq
 			goto irq_ack;
 		}
 
-		if (netif_rx_schedule_prep(&bp->napi)) {
+		if (napi_schedule_prep(&bp->napi)) {
 			/* NOTE: These writes are posted by the readback of
 			 *       the ISTAT register below.
 			 */
 			bp->istat = istat;
 			__b44_disable_ints(bp);
-			__netif_rx_schedule(&bp->napi);
+			__napi_schedule(&bp->napi);
 		} else {
 			printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
 			       dev->name);
@@ -965,7 +965,7 @@ static int b44_start_xmit(struct sk_buff
 	}
 
 	mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
-	if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+	if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
 		struct sk_buff *bounce_skb;
 
 		/* Chip can't handle DMA to/from >1GB, use bounce buffer */
@@ -973,13 +973,13 @@ static int b44_start_xmit(struct sk_buff
 			ssb_dma_unmap_single(bp->sdev, mapping, len,
 					     DMA_TO_DEVICE);
 
-		bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
+		bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
 		if (!bounce_skb)
 			goto err_out;
 
 		mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
 					     len, DMA_TO_DEVICE);
-		if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+		if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
 			if (!ssb_dma_mapping_error(bp->sdev, mapping))
 				ssb_dma_unmap_single(bp->sdev, mapping,
 						     len, DMA_TO_DEVICE);
@@ -1204,7 +1204,7 @@ static int b44_alloc_consistent(struct b
 						 DMA_BIDIRECTIONAL);
 
 		if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
-			rx_ring_dma + size > DMA_30BIT_MASK) {
+			rx_ring_dma + size > DMA_BIT_MASK(30)) {
 			kfree(rx_ring);
 			goto out_err;
 		}
@@ -1231,7 +1231,7 @@ static int b44_alloc_consistent(struct b
 			                    DMA_TO_DEVICE);
 
 		if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
-			tx_ring_dma + size > DMA_30BIT_MASK) {
+			tx_ring_dma + size > DMA_BIT_MASK(30)) {
 			kfree(tx_ring);
 			goto out_err;
 		}
@@ -2180,7 +2180,7 @@ static int __devinit b44_init_one(struct
 			"Failed to powerup the bus\n");
 		goto err_out_free_dev;
 	}
-	err = ssb_dma_set_mask(sdev, DMA_30BIT_MASK);
+	err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30));
 	if (err) {
 		dev_err(sdev->dev,
 			"Required 30BIT DMA mask unsupported by the system.\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/benet/be_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/benet/be_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/benet/be_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/benet/be_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -319,7 +319,7 @@ be_get_pauseparam(struct net_device *net
 
 	be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause,
 		&ecmd->rx_pause);
-	ecmd->autoneg = AUTONEG_ENABLE;
+	ecmd->autoneg = 0;
 }
 
 static int
@@ -328,7 +328,7 @@ be_set_pauseparam(struct net_device *net
 	struct be_adapter *adapter = netdev_priv(netdev);
 	int status;
 
-	if (ecmd->autoneg != AUTONEG_ENABLE)
+	if (ecmd->autoneg != 0)
 		return -EINVAL;
 
 	status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/benet/be.h linux-libre-2.6.30-gnu1/drivers/net/benet/be.h
--- linux-libre-2.6.29-gnu1/drivers/net/benet/be.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/benet/be.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,8 +35,22 @@
 #define DRV_VER			"2.0.348"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
+#define OC_NAME			"Emulex OneConnect 10Gbps NIC"
 #define DRV_DESC		BE_NAME "Driver"
 
+#define BE_VENDOR_ID 		0x19a2
+#define BE_DEVICE_ID1		0x211
+#define OC_DEVICE_ID1		0x700
+#define OC_DEVICE_ID2		0x701
+
+static inline char *nic_name(struct pci_dev *pdev)
+{
+	if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2)
+		return OC_NAME;
+	else
+		return BE_NAME;
+}
+
 /* Number of bytes of an RX frame that are copied to skb->data */
 #define BE_HDR_LEN 		64
 #define BE_MAX_JUMBO_FRAME_SIZE	9018
@@ -100,9 +114,9 @@ struct be_drvr_stats {
 	u32 be_tx_wrbs;		/* number of tx WRBs used */
 	u32 be_tx_events;	/* number of tx completion events  */
 	u32 be_tx_compl;	/* number of tx completion entries processed */
-	u64 be_tx_jiffies;
-	ulong be_tx_bytes;
-	ulong be_tx_bytes_prev;
+	ulong be_tx_jiffies;
+	u64 be_tx_bytes;
+	u64 be_tx_bytes_prev;
 	u32 be_tx_rate;
 
 	u32 cache_barrier[16];
@@ -113,9 +127,9 @@ struct be_drvr_stats {
 	u32 be_rx_compl;	/* number of rx completion entries processed */
 	u32 be_lro_hgram_data[8];	/* histogram of LRO data packets */
 	u32 be_lro_hgram_ack[8];	/* histogram of LRO ACKs */
-	u64 be_rx_jiffies;
-	ulong be_rx_bytes;
-	ulong be_rx_bytes_prev;
+	ulong be_rx_jiffies;
+	u64 be_rx_bytes;
+	u64 be_rx_bytes_prev;
 	u32 be_rx_rate;
 	/* number of non ether type II frames dropped where
 	 * frame len > length field of Mac Hdr */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/benet/be_main.c linux-libre-2.6.30-gnu1/drivers/net/benet/be_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/benet/be_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/benet/be_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,6 +16,7 @@
  */
 
 #include "be.h"
+#include <asm/div64.h>
 
 MODULE_VERSION(DRV_VER);
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -27,10 +28,10 @@ static unsigned int rx_frag_size = 2048;
 module_param(rx_frag_size, uint, S_IRUGO);
 MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
 
-#define BE_VENDOR_ID 		0x19a2
-#define BE2_DEVICE_ID_1 	0x0211
 static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
-	{ PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) },
+	{ 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, be_dev_ids);
@@ -245,19 +246,29 @@ static void be_link_status_update(struct
 /* Update the EQ delay n BE based on the RX frags consumed / sec */
 static void be_rx_eqd_update(struct be_adapter *adapter)
 {
-	u32 eqd;
 	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+	ulong now = jiffies;
+	u32 eqd;
+
+	if (!rx_eq->enable_aic)
+		return;
+
+	/* Wrapped around */
+	if (time_before(now, stats->rx_fps_jiffies)) {
+		stats->rx_fps_jiffies = now;
+		return;
+	}
 
 	/* Update once a second */
-	if (((jiffies - stats->rx_fps_jiffies) < HZ) || rx_eq->enable_aic == 0)
+	if ((now - stats->rx_fps_jiffies) < HZ)
 		return;
 
 	stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) /
-			((jiffies - stats->rx_fps_jiffies) / HZ);
+			((now - stats->rx_fps_jiffies) / HZ);
 
-	stats->rx_fps_jiffies = jiffies;
+	stats->rx_fps_jiffies = now;
 	stats->be_prev_rx_frags = stats->be_rx_frags;
 	eqd = stats->be_rx_fps / 110000;
 	eqd = eqd << 3;
@@ -280,26 +291,47 @@ static struct net_device_stats *be_get_s
 	return &adapter->stats.net_stats;
 }
 
+static u32 be_calc_rate(u64 bytes, unsigned long ticks)
+{
+	u64 rate = bytes;
+
+	do_div(rate, ticks / HZ);
+	rate <<= 3;			/* bytes/sec -> bits/sec */
+	do_div(rate, 1000000ul);	/* MB/Sec */
+
+	return rate;
+}
+
+static void be_tx_rate_update(struct be_adapter *adapter)
+{
+	struct be_drvr_stats *stats = drvr_stats(adapter);
+	ulong now = jiffies;
+
+	/* Wrapped around? */
+	if (time_before(now, stats->be_tx_jiffies)) {
+		stats->be_tx_jiffies = now;
+		return;
+	}
+
+	/* Update tx rate once in two seconds */
+	if ((now - stats->be_tx_jiffies) > 2 * HZ) {
+		stats->be_tx_rate = be_calc_rate(stats->be_tx_bytes
+						  - stats->be_tx_bytes_prev,
+						 now - stats->be_tx_jiffies);
+		stats->be_tx_jiffies = now;
+		stats->be_tx_bytes_prev = stats->be_tx_bytes;
+	}
+}
+
 static void be_tx_stats_update(struct be_adapter *adapter,
 			u32 wrb_cnt, u32 copied, bool stopped)
 {
-	struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+	struct be_drvr_stats *stats = drvr_stats(adapter);
 	stats->be_tx_reqs++;
 	stats->be_tx_wrbs += wrb_cnt;
 	stats->be_tx_bytes += copied;
 	if (stopped)
 		stats->be_tx_stops++;
-
-	/* Update tx rate once in two seconds */
-	if ((jiffies - stats->be_tx_jiffies) > 2 * HZ) {
-		u32 r;
-		r = (stats->be_tx_bytes - stats->be_tx_bytes_prev) /
-			((u32) (jiffies - stats->be_tx_jiffies) / HZ);
-		r = (r / 1000000);			/* M bytes/s */
-		stats->be_tx_rate = (r * 8);	/* M bits/s */
-		stats->be_tx_jiffies = jiffies;
-		stats->be_tx_bytes_prev = stats->be_tx_bytes;
-	}
 }
 
 /* Determine number of WRB entries needed to xmit data in an skb */
@@ -573,28 +605,38 @@ static void be_set_multicast_list(struct
 	}
 }
 
-static void be_rx_rate_update(struct be_adapter *adapter, u32 pktsize,
-			u16 numfrags)
+static void be_rx_rate_update(struct be_adapter *adapter)
 {
-	struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
-	u32 rate;
+	struct be_drvr_stats *stats = drvr_stats(adapter);
+	ulong now = jiffies;
 
-	stats->be_rx_compl++;
-	stats->be_rx_frags += numfrags;
-	stats->be_rx_bytes += pktsize;
+	/* Wrapped around */
+	if (time_before(now, stats->be_rx_jiffies)) {
+		stats->be_rx_jiffies = now;
+		return;
+	}
 
 	/* Update the rate once in two seconds */
-	if ((jiffies - stats->be_rx_jiffies) < 2 * HZ)
+	if ((now - stats->be_rx_jiffies) < 2 * HZ)
 		return;
 
-	rate = (stats->be_rx_bytes - stats->be_rx_bytes_prev) /
-		((u32) (jiffies - stats->be_rx_jiffies) / HZ);
-	rate = (rate / 1000000);	/* MB/Sec */
-	stats->be_rx_rate = (rate * 8); 	/* Mega Bits/Sec */
-	stats->be_rx_jiffies = jiffies;
+	stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes
+					  - stats->be_rx_bytes_prev,
+					 now - stats->be_rx_jiffies);
+	stats->be_rx_jiffies = now;
 	stats->be_rx_bytes_prev = stats->be_rx_bytes;
 }
 
+static void be_rx_stats_update(struct be_adapter *adapter,
+		u32 pktsize, u16 numfrags)
+{
+	struct be_drvr_stats *stats = drvr_stats(adapter);
+
+	stats->be_rx_compl++;
+	stats->be_rx_frags += numfrags;
+	stats->be_rx_bytes += pktsize;
+}
+
 static struct be_rx_page_info *
 get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
 {
@@ -700,7 +742,7 @@ static void skb_fill_rx_data(struct be_a
 		memset(page_info, 0, sizeof(*page_info));
 	}
 
-	be_rx_rate_update(adapter, pktsize, num_rcvd);
+	be_rx_stats_update(adapter, pktsize, num_rcvd);
 	return;
 }
 
@@ -799,7 +841,7 @@ static void be_rx_compl_process_lro(stru
 			vid, NULL, 0);
 	}
 
-	be_rx_rate_update(adapter, pkt_size, num_rcvd);
+	be_rx_stats_update(adapter, pkt_size, num_rcvd);
 	return;
 }
 
@@ -841,7 +883,6 @@ static void be_post_rx_frags(struct be_a
 	u64 page_dmaaddr = 0, frag_dmaaddr;
 	u32 posted, page_offset = 0;
 
-
 	page_info = &page_info_tbl[rxq->head];
 	for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) {
 		if (!pagep) {
@@ -1305,6 +1346,9 @@ static void be_worker(struct work_struct
 	/* Set EQ delay */
 	be_rx_eqd_update(adapter);
 
+	be_tx_rate_update(adapter);
+	be_rx_rate_update(adapter);
+
 	if (adapter->rx_post_starved) {
 		adapter->rx_post_starved = false;
 		be_post_rx_frags(adapter);
@@ -1777,11 +1821,11 @@ static int __devinit be_probe(struct pci
 
 	be_msix_enable(adapter);
 
-	status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!status) {
 		netdev->features |= NETIF_F_HIGHDMA;
 	} else {
-		status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (status) {
 			dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
 			goto free_netdev;
@@ -1815,7 +1859,7 @@ static int __devinit be_probe(struct pci
 	if (status != 0)
 		goto stats_clean;
 
-	dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num);
+	dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
 	return 0;
 
 stats_clean:
@@ -1829,7 +1873,7 @@ rel_reg:
 disable_dev:
 	pci_disable_device(pdev);
 do_none:
-	dev_warn(&pdev->dev, BE_NAME " initialization failed\n");
+	dev_err(&pdev->dev, "%s initialization failed\n", nic_name(pdev));
 	return status;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bfin_mac.c linux-libre-2.6.30-gnu1/drivers/net/bfin_mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/bfin_mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bfin_mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *
 	}
 
 #if defined(CONFIG_BFIN_MAC_RMII)
-	phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
-			PHY_INTERFACE_MODE_RMII);
+	phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+			0, PHY_INTERFACE_MODE_RMII);
 #else
-	phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
-			PHY_INTERFACE_MODE_MII);
+	phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+			0, PHY_INTERFACE_MODE_MII);
 #endif
 
 	if (IS_ERR(phydev)) {
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *
 	printk(KERN_INFO "%s: attached PHY driver [%s] "
 	       "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
 	       "@sclk=%dMHz)\n",
-	       DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
+	       DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
 	       MDC_CLK, mdc_div, sclk/1000000);
 
 	return 0;
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
 	strcpy(info->fw_version, "N/A");
-	strcpy(info->bus_info, dev->dev.bus_id);
+	strcpy(info->bus_info, dev_name(&dev->dev));
 }
 
 static struct ethtool_ops bfin_mac_ethtool_ops = {
@@ -980,7 +980,6 @@ static int bfin_mac_open(struct net_devi
 }
 
 /*
- *
  * this makes the board clean up everything that it can
  * and not talk to the outside world.   Caused by
  * an 'ifconfig ethX down'
@@ -1005,6 +1004,20 @@ static int bfin_mac_close(struct net_dev
 	return 0;
 }
 
+static const struct net_device_ops bfin_mac_netdev_ops = {
+	.ndo_open		= bfin_mac_open,
+	.ndo_stop		= bfin_mac_close,
+	.ndo_start_xmit		= bfin_mac_hard_start_xmit,
+	.ndo_set_mac_address	= bfin_mac_set_mac_address,
+	.ndo_tx_timeout		= bfin_mac_timeout,
+	.ndo_set_multicast_list	= bfin_mac_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= bfin_mac_poll,
+#endif
+};
+
 static int __devinit bfin_mac_probe(struct platform_device *pdev)
 {
 	struct net_device *ndev;
@@ -1086,15 +1099,7 @@ static int __devinit bfin_mac_probe(stru
 	/* Fill in the fields of the device structure with ethernet values. */
 	ether_setup(ndev);
 
-	ndev->open = bfin_mac_open;
-	ndev->stop = bfin_mac_close;
-	ndev->hard_start_xmit = bfin_mac_hard_start_xmit;
-	ndev->set_mac_address = bfin_mac_set_mac_address;
-	ndev->tx_timeout = bfin_mac_timeout;
-	ndev->set_multicast_list = bfin_mac_set_multicast_list;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	ndev->poll_controller = bfin_mac_poll;
-#endif
+	ndev->netdev_ops = &bfin_mac_netdev_ops;
 	ndev->ethtool_ops = &bfin_mac_ethtool_ops;
 
 	spin_lock_init(&lp->lock);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bmac.c linux-libre-2.6.30-gnu1/drivers/net/bmac.c
--- linux-libre-2.6.29-gnu1/drivers/net/bmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -1062,7 +1062,6 @@ static int miscintcount;
 static irqreturn_t bmac_misc_intr(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct bmac_data *bp = netdev_priv(dev);
 	unsigned int status = bmread(dev, STATUS);
 	if (miscintcount++ < 10) {
 		XXDEBUG(("bmac_misc_intr\n"));
@@ -1240,7 +1239,7 @@ static void bmac_get_drvinfo(struct net_
 {
 	struct bmac_data *bp = netdev_priv(dev);
 	strcpy(info->driver, "bmac");
-	strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
+	strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
 }
 
 static const struct ethtool_ops bmac_ethtool_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2.c linux-libre-2.6.30-gnu1/drivers/net/bnx2.c
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2.c	2013-05-03 18:02:36.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2.c	2013-05-03 16:46:29.000000000 -0400
@@ -46,18 +46,20 @@
 #include <linux/crc32.h>
 #include <linux/prefetch.h>
 #include <linux/cache.h>
-#include <linux/zlib.h>
+#include <linux/firmware.h>
 #include <linux/log2.h>
 
 #include "bnx2.h"
-/*(DEBLOBBED)*/
-
-#define FW_BUF_SIZE		0x10000
+#include "bnx2_fw.h"
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.9.3"
-#define DRV_MODULE_RELDATE	"March 17, 2009"
+#define DRV_MODULE_VERSION	"2.0.1"
+#define DRV_MODULE_RELDATE	"May 6, 2009"
+#define FW_MIPS_FILE_06		"/*(DEBLOBBED)*/"
+#define FW_RV2P_FILE_06		"/*(DEBLOBBED)*/"
+#define FW_MIPS_FILE_09		"/*(DEBLOBBED)*/"
+#define FW_RV2P_FILE_09		"/*(DEBLOBBED)*/"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -71,6 +73,7 @@ MODULE_AUTHOR("Michael Chan <mchan@broad
 MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
+/*(DEBLOBBED)*/
 
 static int disable_msi = 0;
 
@@ -1496,6 +1499,8 @@ static int bnx2_fw_sync(struct bnx2 *, u
 
 static int
 bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
 {
 	u32 speed_arg = 0, pause_adv;
 
@@ -1553,6 +1558,8 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u
 
 static int
 bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
 {
 	u32 adv, bmcr;
 	u32 new_adv = 0;
@@ -1865,6 +1872,8 @@ bnx2_set_remote_link(struct bnx2 *bp)
 
 static int
 bnx2_setup_copper_phy(struct bnx2 *bp)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
 {
 	u32 bmcr;
 	u32 new_bmcr;
@@ -1962,6 +1971,8 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
 
 static int
 bnx2_setup_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
 {
 	if (bp->loopback == MAC_LOOPBACK)
 		return 0;
@@ -2175,6 +2186,8 @@ bnx2_init_copper_phy(struct bnx2 *bp, in
 
 static int
 bnx2_init_phy(struct bnx2 *bp, int reset_phy)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
 {
 	u32 val;
 	int rc = 0;
@@ -2584,6 +2597,7 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bn
 	/* Tell compiler that status block fields can change. */
 	barrier();
 	cons = *bnapi->hw_tx_cons_ptr;
+	barrier();
 	if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
 		cons++;
 	return cons;
@@ -2863,6 +2877,7 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bn
 	/* Tell compiler that status block fields can change. */
 	barrier();
 	cons = *bnapi->hw_rx_cons_ptr;
+	barrier();
 	if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
 		cons++;
 	return cons;
@@ -3004,6 +3019,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
 
+		skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
+
 #ifdef BCM_VLAN
 		if (hw_vlan)
 			vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
@@ -3060,7 +3077,7 @@ bnx2_msi(int irq, void *dev_instance)
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
 		return IRQ_HANDLED;
 
-	netif_rx_schedule(&bnapi->napi);
+	napi_schedule(&bnapi->napi);
 
 	return IRQ_HANDLED;
 }
@@ -3077,7 +3094,7 @@ bnx2_msi_1shot(int irq, void *dev_instan
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
 		return IRQ_HANDLED;
 
-	netif_rx_schedule(&bnapi->napi);
+	napi_schedule(&bnapi->napi);
 
 	return IRQ_HANDLED;
 }
@@ -3113,9 +3130,9 @@ bnx2_interrupt(int irq, void *dev_instan
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
 		return IRQ_HANDLED;
 
-	if (netif_rx_schedule_prep(&bnapi->napi)) {
+	if (napi_schedule_prep(&bnapi->napi)) {
 		bnapi->last_status_idx = sblk->status_idx;
-		__netif_rx_schedule(&bnapi->napi);
+		__napi_schedule(&bnapi->napi);
 	}
 
 	return IRQ_HANDLED;
@@ -3225,7 +3242,7 @@ static int bnx2_poll_msix(struct napi_st
 		rmb();
 		if (likely(!bnx2_has_fast_work(bnapi))) {
 
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
 			       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
 			       bnapi->last_status_idx);
@@ -3258,7 +3275,7 @@ static int bnx2_poll(struct napi_struct
 
 		rmb();
 		if (likely(!bnx2_has_work(bnapi))) {
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
 				REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 				       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -3378,14 +3395,165 @@ bnx2_set_rx_mode(struct net_device *dev)
 	spin_unlock_bh(&bp->phy_lock);
 }
 
-/*(DEBLOBBED)*/
+static int __devinit
+check_fw_section(const struct firmware *fw,
+		 const struct bnx2_fw_file_section *section,
+		 u32 alignment, bool non_empty)
+{
+	u32 offset = be32_to_cpu(section->offset);
+	u32 len = be32_to_cpu(section->len);
+
+	if ((offset == 0 && len != 0) || offset >= fw->size || offset & 3)
+		return -EINVAL;
+	if ((non_empty && len == 0) || len > fw->size - offset ||
+	    len & (alignment - 1))
+		return -EINVAL;
+	return 0;
+}
+
+static int __devinit
+check_mips_fw_entry(const struct firmware *fw,
+		    const struct bnx2_mips_fw_file_entry *entry)
+{
+	if (check_fw_section(fw, &entry->text, 4, true) ||
+	    check_fw_section(fw, &entry->data, 4, false) ||
+	    check_fw_section(fw, &entry->rodata, 4, false))
+		return -EINVAL;
+	return 0;
+}
+
+static int __devinit
+bnx2_reject_firmware(struct bnx2 *bp)
+{
+	const char *mips_fw_file, *rv2p_fw_file;
+	const struct bnx2_mips_fw_file *mips_fw;
+	const struct bnx2_rv2p_fw_file *rv2p_fw;
+	int rc;
+
+	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+		mips_fw_file = FW_MIPS_FILE_09;
+		rv2p_fw_file = FW_RV2P_FILE_09;
+	} else {
+		mips_fw_file = FW_MIPS_FILE_06;
+		rv2p_fw_file = FW_RV2P_FILE_06;
+	}
+
+	rc = reject_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
+	if (rc) {
+		printk(KERN_ERR PFX "Can't load firmware file \"%s\"\n",
+		       mips_fw_file);
+		return rc;
+	}
+
+	rc = reject_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
+	if (rc) {
+		printk(KERN_ERR PFX "Can't load firmware file \"%s\"\n",
+		       rv2p_fw_file);
+		return rc;
+	}
+	mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+	rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+	if (bp->mips_firmware->size < sizeof(*mips_fw) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->com) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->cp) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->rxp) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
+	    check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
+		printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
+		       mips_fw_file);
+		return -EINVAL;
+	}
+	if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
+	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
+	    check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
+		printk(KERN_ERR PFX "Firmware file \"%s\" is invalid\n",
+		       rv2p_fw_file);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32
+rv2p_fw_fixup(u32 rv2p_proc, int idx, u32 loc, u32 rv2p_code)
+{
+	switch (idx) {
+	case RV2P_P1_FIXUP_PAGE_SIZE_IDX:
+		rv2p_code &= ~RV2P_BD_PAGE_SIZE_MSK;
+		rv2p_code |= RV2P_BD_PAGE_SIZE;
+		break;
+	}
+	return rv2p_code;
+}
 
 static int
-load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
+load_rv2p_fw(struct bnx2 *bp, u32 rv2p_proc,
+	     const struct bnx2_rv2p_fw_file_entry *fw_entry)
+{
+	u32 rv2p_code_len, file_offset;
+	__be32 *rv2p_code;
+	int i;
+	u32 val, cmd, addr;
+
+	rv2p_code_len = be32_to_cpu(fw_entry->rv2p.len);
+	file_offset = be32_to_cpu(fw_entry->rv2p.offset);
+
+	rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
+
+	if (rv2p_proc == RV2P_PROC1) {
+		cmd = BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
+		addr = BNX2_RV2P_PROC1_ADDR_CMD;
+	} else {
+		cmd = BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
+		addr = BNX2_RV2P_PROC2_ADDR_CMD;
+	}
+
+	for (i = 0; i < rv2p_code_len; i += 8) {
+		REG_WR(bp, BNX2_RV2P_INSTR_HIGH, be32_to_cpu(*rv2p_code));
+		rv2p_code++;
+		REG_WR(bp, BNX2_RV2P_INSTR_LOW, be32_to_cpu(*rv2p_code));
+		rv2p_code++;
+
+		val = (i / 8) | cmd;
+		REG_WR(bp, addr, val);
+	}
+
+	rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
+	for (i = 0; i < 8; i++) {
+		u32 loc, code;
+
+		loc = be32_to_cpu(fw_entry->fixup[i]);
+		if (loc && ((loc * 4) < rv2p_code_len)) {
+			code = be32_to_cpu(*(rv2p_code + loc - 1));
+			REG_WR(bp, BNX2_RV2P_INSTR_HIGH, code);
+			code = be32_to_cpu(*(rv2p_code + loc));
+			code = rv2p_fw_fixup(rv2p_proc, i, loc, code);
+			REG_WR(bp, BNX2_RV2P_INSTR_LOW, code);
+
+			val = (loc / 2) | cmd;
+			REG_WR(bp, addr, val);
+		}
+	}
+
+	/* Reset the processor, un-stall is done later. */
+	if (rv2p_proc == RV2P_PROC1) {
+		REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
+	}
+	else {
+		REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
+	}
+
+	return 0;
+}
+
+static int
+load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg,
+	    const struct bnx2_mips_fw_file_entry *fw_entry)
 {
+	u32 addr, len, file_offset;
+	__be32 *data;
 	u32 offset;
 	u32 val;
-	int rc;
 
 	/* Halt the CPU. */
 	val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3394,64 +3562,52 @@ load_cpu_fw(struct bnx2 *bp, const struc
 	bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
 
 	/* Load the Text area. */
-	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
-	if (fw->gz_text) {
-		int j;
-
-		rc = zlib_inflate_blob(fw->text, FW_BUF_SIZE, fw->gz_text,
-				       fw->gz_text_len);
-		if (rc < 0)
-			return rc;
-
-		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
-			bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j]));
-	        }
-	}
+	addr = be32_to_cpu(fw_entry->text.addr);
+	len = be32_to_cpu(fw_entry->text.len);
+	file_offset = be32_to_cpu(fw_entry->text.offset);
+	data = (__be32 *)(bp->mips_firmware->data + file_offset);
 
-	/* Load the Data area. */
-	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
-	if (fw->data) {
+	offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+	if (len) {
 		int j;
 
-		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
-			bnx2_reg_wr_ind(bp, offset, fw->data[j]);
-		}
+		for (j = 0; j < (len / 4); j++, offset += 4)
+			bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
 	}
 
-	/* Load the SBSS area. */
-	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
-	if (fw->sbss_len) {
-		int j;
-
-		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
-			bnx2_reg_wr_ind(bp, offset, 0);
-		}
-	}
+	/* Load the Data area. */
+	addr = be32_to_cpu(fw_entry->data.addr);
+	len = be32_to_cpu(fw_entry->data.len);
+	file_offset = be32_to_cpu(fw_entry->data.offset);
+	data = (__be32 *)(bp->mips_firmware->data + file_offset);
 
-	/* Load the BSS area. */
-	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
-	if (fw->bss_len) {
+	offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+	if (len) {
 		int j;
 
-		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
-			bnx2_reg_wr_ind(bp, offset, 0);
-		}
+		for (j = 0; j < (len / 4); j++, offset += 4)
+			bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
 	}
 
 	/* Load the Read-Only area. */
-	offset = cpu_reg->spad_base +
-		(fw->rodata_addr - cpu_reg->mips_view_base);
-	if (fw->rodata) {
+	addr = be32_to_cpu(fw_entry->rodata.addr);
+	len = be32_to_cpu(fw_entry->rodata.len);
+	file_offset = be32_to_cpu(fw_entry->rodata.offset);
+	data = (__be32 *)(bp->mips_firmware->data + file_offset);
+
+	offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+	if (len) {
 		int j;
 
-		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
-			bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
-		}
+		for (j = 0; j < (len / 4); j++, offset += 4)
+			bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
 	}
 
 	/* Clear the pre-fetch instruction. */
 	bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
-	bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
+
+	val = be32_to_cpu(fw_entry->start_addr);
+	bnx2_reg_wr_ind(bp, cpu_reg->pc, val);
 
 	/* Start the CPU. */
 	val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3462,7 +3618,45 @@ load_cpu_fw(struct bnx2 *bp, const struc
 	return 0;
 }
 
-/*(DEBLOBBED)*/
+static int
+bnx2_init_cpus(struct bnx2 *bp)
+{
+	const struct bnx2_mips_fw_file *mips_fw =
+		(const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+	const struct bnx2_rv2p_fw_file *rv2p_fw =
+		(const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+	int rc;
+
+	/* Initialize the RV2P processor. */
+	load_rv2p_fw(bp, RV2P_PROC1, &rv2p_fw->proc1);
+	load_rv2p_fw(bp, RV2P_PROC2, &rv2p_fw->proc2);
+
+	/* Initialize the RX Processor. */
+	rc = load_cpu_fw(bp, &cpu_reg_rxp, &mips_fw->rxp);
+	if (rc)
+		goto init_cpu_err;
+
+	/* Initialize the TX Processor. */
+	rc = load_cpu_fw(bp, &cpu_reg_txp, &mips_fw->txp);
+	if (rc)
+		goto init_cpu_err;
+
+	/* Initialize the TX Patch-up Processor. */
+	rc = load_cpu_fw(bp, &cpu_reg_tpat, &mips_fw->tpat);
+	if (rc)
+		goto init_cpu_err;
+
+	/* Initialize the Completion Processor. */
+	rc = load_cpu_fw(bp, &cpu_reg_com, &mips_fw->com);
+	if (rc)
+		goto init_cpu_err;
+
+	/* Initialize the Command Processor. */
+	rc = load_cpu_fw(bp, &cpu_reg_cp, &mips_fw->cp);
+
+init_cpu_err:
+	return rc;
+}
 
 static int
 bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
@@ -4425,9 +4619,6 @@ bnx2_init_chip(struct bnx2 *bp)
 	} else
 		bnx2_init_context(bp);
 
-	printk (KERN_ERR "%s: Missing Free firmware\n", bp->dev->name);
-	return -EINVAL;
-#define bnx2_init_cpus(bp) (-EINVAL)
 	if ((rc = bnx2_init_cpus(bp)) != 0)
 		return rc;
 
@@ -7333,9 +7524,9 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	/* 5708 cannot support DMA addresses > 40-bit.  */
 	if (CHIP_NUM(bp) == CHIP_NUM_5708)
-		persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+		persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
 	else
-		persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+		persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
 
 	/* Configure DMA attributes. */
 	if (pci_set_dma_mask(pdev, dma_mask) == 0) {
@@ -7346,7 +7537,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 				"pci_set_consistent_dma_mask failed, aborting.\n");
 			goto err_out_unmap;
 		}
-	} else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+	} else if ((rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
 		dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
 		goto err_out_unmap;
 	}
@@ -7667,6 +7858,10 @@ bnx2_init_one(struct pci_dev *pdev, cons
 
 	pci_set_drvdata(pdev, dev);
 
+	rc = bnx2_reject_firmware(bp);
+	if (rc)
+		goto error;
+
 	memcpy(dev->dev_addr, bp->mac_addr, 6);
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
@@ -7683,13 +7878,7 @@ bnx2_init_one(struct pci_dev *pdev, cons
 
 	if ((rc = register_netdev(dev))) {
 		dev_err(&pdev->dev, "Cannot register net device\n");
-		if (bp->regview)
-			iounmap(bp->regview);
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
-		pci_set_drvdata(pdev, NULL);
-		free_netdev(dev);
-		return rc;
+		goto error;
 	}
 
 	printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
@@ -7703,6 +7892,20 @@ bnx2_init_one(struct pci_dev *pdev, cons
 		bp->pdev->irq, dev->dev_addr);
 
 	return 0;
+
+error:
+	if (bp->mips_firmware)
+		release_firmware(bp->mips_firmware);
+	if (bp->rv2p_firmware)
+		release_firmware(bp->rv2p_firmware);
+
+	if (bp->regview)
+		iounmap(bp->regview);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+	return rc;
 }
 
 static void __devexit
@@ -7715,6 +7918,11 @@ bnx2_remove_one(struct pci_dev *pdev)
 
 	unregister_netdev(dev);
 
+	if (bp->mips_firmware)
+		release_firmware(bp->mips_firmware);
+	if (bp->rv2p_firmware)
+		release_firmware(bp->rv2p_firmware);
+
 	if (bp->regview)
 		iounmap(bp->regview);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2_fw.h linux-libre-2.6.30-gnu1/drivers/net/bnx2_fw.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2_fw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2_fw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,88 @@
+/* bnx2_fw.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+/* Initialized Values for the Completion Processor. */
+static const struct cpu_reg cpu_reg_com = {
+	.mode = BNX2_COM_CPU_MODE,
+	.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT,
+	.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA,
+	.state = BNX2_COM_CPU_STATE,
+	.state_value_clear = 0xffffff,
+	.gpr0 = BNX2_COM_CPU_REG_FILE,
+	.evmask = BNX2_COM_CPU_EVENT_MASK,
+	.pc = BNX2_COM_CPU_PROGRAM_COUNTER,
+	.inst = BNX2_COM_CPU_INSTRUCTION,
+	.bp = BNX2_COM_CPU_HW_BREAKPOINT,
+	.spad_base = BNX2_COM_SCRATCH,
+	.mips_view_base = 0x8000000,
+};
+
+/* Initialized Values the Command Processor. */
+static const struct cpu_reg cpu_reg_cp = {
+	.mode = BNX2_CP_CPU_MODE,
+	.mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT,
+	.mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA,
+	.state = BNX2_CP_CPU_STATE,
+	.state_value_clear = 0xffffff,
+	.gpr0 = BNX2_CP_CPU_REG_FILE,
+	.evmask = BNX2_CP_CPU_EVENT_MASK,
+	.pc = BNX2_CP_CPU_PROGRAM_COUNTER,
+	.inst = BNX2_CP_CPU_INSTRUCTION,
+	.bp = BNX2_CP_CPU_HW_BREAKPOINT,
+	.spad_base = BNX2_CP_SCRATCH,
+	.mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the RX Processor. */
+static const struct cpu_reg cpu_reg_rxp = {
+	.mode = BNX2_RXP_CPU_MODE,
+	.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT,
+	.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA,
+	.state = BNX2_RXP_CPU_STATE,
+	.state_value_clear = 0xffffff,
+	.gpr0 = BNX2_RXP_CPU_REG_FILE,
+	.evmask = BNX2_RXP_CPU_EVENT_MASK,
+	.pc = BNX2_RXP_CPU_PROGRAM_COUNTER,
+	.inst = BNX2_RXP_CPU_INSTRUCTION,
+	.bp = BNX2_RXP_CPU_HW_BREAKPOINT,
+	.spad_base = BNX2_RXP_SCRATCH,
+	.mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the TX Patch-up Processor. */
+static const struct cpu_reg cpu_reg_tpat = {
+	.mode = BNX2_TPAT_CPU_MODE,
+	.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT,
+	.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA,
+	.state = BNX2_TPAT_CPU_STATE,
+	.state_value_clear = 0xffffff,
+	.gpr0 = BNX2_TPAT_CPU_REG_FILE,
+	.evmask = BNX2_TPAT_CPU_EVENT_MASK,
+	.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER,
+	.inst = BNX2_TPAT_CPU_INSTRUCTION,
+	.bp = BNX2_TPAT_CPU_HW_BREAKPOINT,
+	.spad_base = BNX2_TPAT_SCRATCH,
+	.mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the TX Processor. */
+static const struct cpu_reg cpu_reg_txp = {
+	.mode = BNX2_TXP_CPU_MODE,
+	.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT,
+	.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA,
+	.state = BNX2_TXP_CPU_STATE,
+	.state_value_clear = 0xffffff,
+	.gpr0 = BNX2_TXP_CPU_REG_FILE,
+	.evmask = BNX2_TXP_CPU_EVENT_MASK,
+	.pc = BNX2_TXP_CPU_PROGRAM_COUNTER,
+	.inst = BNX2_TXP_CPU_INSTRUCTION,
+	.bp = BNX2_TXP_CPU_HW_BREAKPOINT,
+	.spad_base = BNX2_TXP_SCRATCH,
+	.mips_view_base = 0x8000000,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2.h linux-libre-2.6.30-gnu1/drivers/net/bnx2.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2.h	2009-06-09 23:05:27.000000000 -0400
@@ -6885,6 +6885,8 @@ struct bnx2 {
 
 	u32			idle_chk_status_idx;
 
+	const struct firmware	*mips_firmware;
+	const struct firmware	*rv2p_firmware;
 };
 
 #define REG_RD(bp, offset)					\
@@ -6915,44 +6917,41 @@ struct cpu_reg {
 	u32 mips_view_base;
 };
 
-struct fw_info {
-	const u32 ver_major;
-	const u32 ver_minor;
-	const u32 ver_fix;
-
-	const u32 start_addr;
-
-	/* Text section. */
-	const u32 text_addr;
-	const u32 text_len;
-	const u32 text_index;
-	__le32 *text;
-	u8 *gz_text;
-	const u32 gz_text_len;
+struct bnx2_fw_file_section {
+	__be32 addr;
+	__be32 len;
+	__be32 offset;
+};
 
-	/* Data section. */
-	const u32 data_addr;
-	const u32 data_len;
-	const u32 data_index;
-	const u32 *data;
+struct bnx2_mips_fw_file_entry {
+	__be32 start_addr;
+	struct bnx2_fw_file_section text;
+	struct bnx2_fw_file_section data;
+	struct bnx2_fw_file_section rodata;
+};
 
-	/* SBSS section. */
-	const u32 sbss_addr;
-	const u32 sbss_len;
-	const u32 sbss_index;
+struct bnx2_rv2p_fw_file_entry {
+	struct bnx2_fw_file_section rv2p;
+	__be32 fixup[8];
+};
 
-	/* BSS section. */
-	const u32 bss_addr;
-	const u32 bss_len;
-	const u32 bss_index;
+struct bnx2_mips_fw_file {
+	struct bnx2_mips_fw_file_entry com;
+	struct bnx2_mips_fw_file_entry cp;
+	struct bnx2_mips_fw_file_entry rxp;
+	struct bnx2_mips_fw_file_entry tpat;
+	struct bnx2_mips_fw_file_entry txp;
+};
 
-	/* Read-only section. */
-	const u32 rodata_addr;
-	const u32 rodata_len;
-	const u32 rodata_index;
-	const u32 *rodata;
+struct bnx2_rv2p_fw_file {
+	struct bnx2_rv2p_fw_file_entry proc1;
+	struct bnx2_rv2p_fw_file_entry proc2;
 };
 
+#define RV2P_P1_FIXUP_PAGE_SIZE_IDX		0
+#define RV2P_BD_PAGE_SIZE_MSK			0xffff
+#define RV2P_BD_PAGE_SIZE			((BCM_PAGE_SIZE / 16) - 1)
+
 #define RV2P_PROC1                              0
 #define RV2P_PROC2                              1
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_dump.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_dump.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_dump.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_dump.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,526 @@
+/* bnx2x_dump.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+
+/* This struct holds a signature to ensure the dump returned from the driver
+ * match the meta data file inserted to grc_dump.tcl
+ * The signature is time stamp, diag version and grc_dump version
+ */
+
+struct dump_sign {
+	u32 time_stamp;
+	u32 diag_ver;
+	u32 grc_dump_ver;
+};
+
+#define TSTORM_WAITP_ADDR	0x1b8a80
+#define CSTORM_WAITP_ADDR	0x238a80
+#define XSTORM_WAITP_ADDR	0x2b8a80
+#define USTORM_WAITP_ADDR	0x338a80
+#define TSTORM_CAM_MODE		0x1b1440
+
+#define RI_E1			0x1
+#define RI_E1H			0x2
+#define RI_ONLINE		0x100
+
+#define RI_E1_OFFLINE		(RI_E1)
+#define RI_E1_ONLINE		(RI_E1 | RI_ONLINE)
+#define RI_E1H_OFFLINE		(RI_E1H)
+#define RI_E1H_ONLINE		(RI_E1H | RI_ONLINE)
+#define RI_ALL_OFFLINE		(RI_E1 | RI_E1H)
+#define RI_ALL_ONLINE		(RI_E1 | RI_E1H | RI_ONLINE)
+
+#define MAX_TIMER_PENDING	200
+#define TIMER_SCAN_DONT_CARE	0xFF
+
+
+struct dump_hdr {
+	u32		 hdr_size;	/* in dwords, excluding this field */
+	struct dump_sign dump_sign;
+	u32		 xstorm_waitp;
+	u32		 tstorm_waitp;
+	u32		 ustorm_waitp;
+	u32		 cstorm_waitp;
+	u16		 info;
+	u8		 idle_chk;
+	u8		 reserved;
+};
+
+struct reg_addr {
+	u32 addr;
+	u32 size;
+	u16 info;
+};
+
+struct wreg_addr {
+	u32 addr;
+	u32 size;
+	u32 read_regs_count;
+	const u32 *read_regs;
+	u16 info;
+};
+
+
+#define REGS_COUNT		558
+static const struct reg_addr reg_addrs[REGS_COUNT] = {
+	{ 0x2000, 341, RI_ALL_ONLINE}, { 0x2800, 103, RI_ALL_ONLINE},
+	{ 0x3000, 287, RI_ALL_ONLINE}, { 0x3800, 331, RI_ALL_ONLINE},
+	{ 0x8800, 6, RI_E1_ONLINE}, { 0xa000, 223, RI_ALL_ONLINE},
+	{ 0xa388, 1, RI_ALL_ONLINE}, { 0xa398, 1, RI_ALL_ONLINE},
+	{ 0xa39c, 7, RI_E1H_ONLINE}, { 0xa3c0, 3, RI_E1H_ONLINE},
+	{ 0xa3d0, 1, RI_E1H_ONLINE}, { 0xa3d8, 1, RI_E1H_ONLINE},
+	{ 0xa3e0, 1, RI_E1H_ONLINE}, { 0xa3e8, 1, RI_E1H_ONLINE},
+	{ 0xa3f0, 1, RI_E1H_ONLINE}, { 0xa3f8, 1, RI_E1H_ONLINE},
+	{ 0xa400, 69, RI_ALL_ONLINE}, { 0xa518, 1, RI_ALL_ONLINE},
+	{ 0xa520, 1, RI_ALL_ONLINE}, { 0xa528, 1, RI_ALL_ONLINE},
+	{ 0xa530, 1, RI_ALL_ONLINE}, { 0xa538, 1, RI_ALL_ONLINE},
+	{ 0xa540, 1, RI_ALL_ONLINE}, { 0xa548, 1, RI_ALL_ONLINE},
+	{ 0xa550, 1, RI_ALL_ONLINE}, { 0xa558, 1, RI_ALL_ONLINE},
+	{ 0xa560, 1, RI_ALL_ONLINE}, { 0xa568, 1, RI_ALL_ONLINE},
+	{ 0xa570, 1, RI_ALL_ONLINE}, { 0xa580, 1, RI_ALL_ONLINE},
+	{ 0xa590, 1, RI_ALL_ONLINE}, { 0xa5a0, 1, RI_ALL_ONLINE},
+	{ 0xa5c0, 1, RI_ALL_ONLINE}, { 0xa5e0, 1, RI_E1H_ONLINE},
+	{ 0xa5e8, 1, RI_E1H_ONLINE}, { 0xa5f0, 1, RI_E1H_ONLINE},
+	{ 0xa5f8, 10, RI_E1H_ONLINE}, { 0x10000, 236, RI_ALL_ONLINE},
+	{ 0x103bc, 1, RI_ALL_ONLINE}, { 0x103cc, 1, RI_ALL_ONLINE},
+	{ 0x103dc, 1, RI_ALL_ONLINE}, { 0x10400, 57, RI_ALL_ONLINE},
+	{ 0x104e8, 2, RI_ALL_ONLINE}, { 0x104f4, 2, RI_ALL_ONLINE},
+	{ 0x10500, 146, RI_ALL_ONLINE}, { 0x10750, 2, RI_ALL_ONLINE},
+	{ 0x10760, 2, RI_ALL_ONLINE}, { 0x10770, 2, RI_ALL_ONLINE},
+	{ 0x10780, 2, RI_ALL_ONLINE}, { 0x10790, 2, RI_ALL_ONLINE},
+	{ 0x107a0, 2, RI_ALL_ONLINE}, { 0x107b0, 2, RI_ALL_ONLINE},
+	{ 0x107c0, 2, RI_ALL_ONLINE}, { 0x107d0, 2, RI_ALL_ONLINE},
+	{ 0x107e0, 2, RI_ALL_ONLINE}, { 0x10880, 2, RI_ALL_ONLINE},
+	{ 0x10900, 2, RI_ALL_ONLINE}, { 0x12000, 1, RI_ALL_ONLINE},
+	{ 0x14000, 1, RI_ALL_ONLINE}, { 0x16000, 26, RI_E1H_ONLINE},
+	{ 0x16070, 18, RI_E1H_ONLINE}, { 0x160c0, 27, RI_E1H_ONLINE},
+	{ 0x16140, 1, RI_E1H_ONLINE}, { 0x16160, 1, RI_E1H_ONLINE},
+	{ 0x16180, 2, RI_E1H_ONLINE}, { 0x161c0, 2, RI_E1H_ONLINE},
+	{ 0x16204, 5, RI_E1H_ONLINE}, { 0x18000, 1, RI_E1H_ONLINE},
+	{ 0x18008, 1, RI_E1H_ONLINE}, { 0x20000, 24, RI_ALL_ONLINE},
+	{ 0x20060, 8, RI_ALL_ONLINE}, { 0x20080, 138, RI_ALL_ONLINE},
+	{ 0x202b4, 1, RI_ALL_ONLINE}, { 0x202c4, 1, RI_ALL_ONLINE},
+	{ 0x20400, 2, RI_ALL_ONLINE}, { 0x2040c, 8, RI_ALL_ONLINE},
+	{ 0x2042c, 18, RI_E1H_ONLINE}, { 0x20480, 1, RI_ALL_ONLINE},
+	{ 0x20500, 1, RI_ALL_ONLINE}, { 0x20600, 1, RI_ALL_ONLINE},
+	{ 0x28000, 1, RI_ALL_ONLINE}, { 0x28004, 8191, RI_ALL_OFFLINE},
+	{ 0x30000, 1, RI_ALL_ONLINE}, { 0x30004, 16383, RI_ALL_OFFLINE},
+	{ 0x40000, 98, RI_ALL_ONLINE}, { 0x40194, 1, RI_ALL_ONLINE},
+	{ 0x401a4, 1, RI_ALL_ONLINE}, { 0x401a8, 11, RI_E1H_ONLINE},
+	{ 0x40200, 4, RI_ALL_ONLINE}, { 0x40400, 43, RI_ALL_ONLINE},
+	{ 0x404b8, 1, RI_ALL_ONLINE}, { 0x404c8, 1, RI_ALL_ONLINE},
+	{ 0x404cc, 3, RI_E1H_ONLINE}, { 0x40500, 2, RI_ALL_ONLINE},
+	{ 0x40510, 2, RI_ALL_ONLINE}, { 0x40520, 2, RI_ALL_ONLINE},
+	{ 0x40530, 2, RI_ALL_ONLINE}, { 0x40540, 2, RI_ALL_ONLINE},
+	{ 0x42000, 164, RI_ALL_ONLINE}, { 0x4229c, 1, RI_ALL_ONLINE},
+	{ 0x422ac, 1, RI_ALL_ONLINE}, { 0x422bc, 1, RI_ALL_ONLINE},
+	{ 0x422d4, 5, RI_E1H_ONLINE}, { 0x42400, 49, RI_ALL_ONLINE},
+	{ 0x424c8, 38, RI_ALL_ONLINE}, { 0x42568, 2, RI_ALL_ONLINE},
+	{ 0x42800, 1, RI_ALL_ONLINE}, { 0x50000, 20, RI_ALL_ONLINE},
+	{ 0x50050, 8, RI_ALL_ONLINE}, { 0x50070, 88, RI_ALL_ONLINE},
+	{ 0x501dc, 1, RI_ALL_ONLINE}, { 0x501ec, 1, RI_ALL_ONLINE},
+	{ 0x501f0, 4, RI_E1H_ONLINE}, { 0x50200, 2, RI_ALL_ONLINE},
+	{ 0x5020c, 7, RI_ALL_ONLINE}, { 0x50228, 6, RI_E1H_ONLINE},
+	{ 0x50240, 1, RI_ALL_ONLINE}, { 0x50280, 1, RI_ALL_ONLINE},
+	{ 0x52000, 1, RI_ALL_ONLINE}, { 0x54000, 1, RI_ALL_ONLINE},
+	{ 0x54004, 3327, RI_ALL_OFFLINE}, { 0x58000, 1, RI_ALL_ONLINE},
+	{ 0x58004, 8191, RI_ALL_OFFLINE}, { 0x60000, 71, RI_ALL_ONLINE},
+	{ 0x60128, 1, RI_ALL_ONLINE}, { 0x60138, 1, RI_ALL_ONLINE},
+	{ 0x6013c, 24, RI_E1H_ONLINE}, { 0x60200, 1, RI_ALL_ONLINE},
+	{ 0x61000, 1, RI_ALL_ONLINE}, { 0x61004, 511, RI_ALL_OFFLINE},
+	{ 0x70000, 8, RI_ALL_ONLINE}, { 0x70020, 21496, RI_ALL_OFFLINE},
+	{ 0x85000, 3, RI_ALL_ONLINE}, { 0x8500c, 4, RI_ALL_OFFLINE},
+	{ 0x8501c, 7, RI_ALL_ONLINE}, { 0x85038, 4, RI_ALL_OFFLINE},
+	{ 0x85048, 1, RI_ALL_ONLINE}, { 0x8504c, 109, RI_ALL_OFFLINE},
+	{ 0x85200, 32, RI_ALL_ONLINE}, { 0x85280, 11104, RI_ALL_OFFLINE},
+	{ 0xa0000, 16384, RI_ALL_ONLINE}, { 0xb0000, 16384, RI_E1H_ONLINE},
+	{ 0xc1000, 7, RI_ALL_ONLINE}, { 0xc1028, 1, RI_ALL_ONLINE},
+	{ 0xc1038, 1, RI_ALL_ONLINE}, { 0xc1800, 2, RI_ALL_ONLINE},
+	{ 0xc2000, 164, RI_ALL_ONLINE}, { 0xc229c, 1, RI_ALL_ONLINE},
+	{ 0xc22ac, 1, RI_ALL_ONLINE}, { 0xc22bc, 1, RI_ALL_ONLINE},
+	{ 0xc2400, 49, RI_ALL_ONLINE}, { 0xc24c8, 38, RI_ALL_ONLINE},
+	{ 0xc2568, 2, RI_ALL_ONLINE}, { 0xc2600, 1, RI_ALL_ONLINE},
+	{ 0xc4000, 165, RI_ALL_ONLINE}, { 0xc42a0, 1, RI_ALL_ONLINE},
+	{ 0xc42b0, 1, RI_ALL_ONLINE}, { 0xc42c0, 1, RI_ALL_ONLINE},
+	{ 0xc42e0, 7, RI_E1H_ONLINE}, { 0xc4400, 51, RI_ALL_ONLINE},
+	{ 0xc44d0, 38, RI_ALL_ONLINE}, { 0xc4570, 2, RI_ALL_ONLINE},
+	{ 0xc4600, 1, RI_ALL_ONLINE}, { 0xd0000, 19, RI_ALL_ONLINE},
+	{ 0xd004c, 8, RI_ALL_ONLINE}, { 0xd006c, 91, RI_ALL_ONLINE},
+	{ 0xd01e4, 1, RI_ALL_ONLINE}, { 0xd01f4, 1, RI_ALL_ONLINE},
+	{ 0xd0200, 2, RI_ALL_ONLINE}, { 0xd020c, 7, RI_ALL_ONLINE},
+	{ 0xd0228, 18, RI_E1H_ONLINE}, { 0xd0280, 1, RI_ALL_ONLINE},
+	{ 0xd0300, 1, RI_ALL_ONLINE}, { 0xd0400, 1, RI_ALL_ONLINE},
+	{ 0xd4000, 1, RI_ALL_ONLINE}, { 0xd4004, 2559, RI_ALL_OFFLINE},
+	{ 0xd8000, 1, RI_ALL_ONLINE}, { 0xd8004, 8191, RI_ALL_OFFLINE},
+	{ 0xe0000, 21, RI_ALL_ONLINE}, { 0xe0054, 8, RI_ALL_ONLINE},
+	{ 0xe0074, 85, RI_ALL_ONLINE}, { 0xe01d4, 1, RI_ALL_ONLINE},
+	{ 0xe01e4, 1, RI_ALL_ONLINE}, { 0xe0200, 2, RI_ALL_ONLINE},
+	{ 0xe020c, 8, RI_ALL_ONLINE}, { 0xe022c, 18, RI_E1H_ONLINE},
+	{ 0xe0280, 1, RI_ALL_ONLINE}, { 0xe0300, 1, RI_ALL_ONLINE},
+	{ 0xe1000, 1, RI_ALL_ONLINE}, { 0xe2000, 1, RI_ALL_ONLINE},
+	{ 0xe2004, 2047, RI_ALL_OFFLINE}, { 0xf0000, 1, RI_ALL_ONLINE},
+	{ 0xf0004, 16383, RI_ALL_OFFLINE}, { 0x101000, 12, RI_ALL_ONLINE},
+	{ 0x10103c, 1, RI_ALL_ONLINE}, { 0x10104c, 1, RI_ALL_ONLINE},
+	{ 0x101050, 1, RI_E1H_ONLINE}, { 0x101100, 1, RI_ALL_ONLINE},
+	{ 0x101800, 8, RI_ALL_ONLINE}, { 0x102000, 18, RI_ALL_ONLINE},
+	{ 0x102054, 1, RI_ALL_ONLINE}, { 0x102064, 1, RI_ALL_ONLINE},
+	{ 0x102080, 17, RI_ALL_ONLINE}, { 0x1020c8, 8, RI_E1H_ONLINE},
+	{ 0x102400, 1, RI_ALL_ONLINE}, { 0x103000, 26, RI_ALL_ONLINE},
+	{ 0x103074, 1, RI_ALL_ONLINE}, { 0x103084, 1, RI_ALL_ONLINE},
+	{ 0x103094, 1, RI_ALL_ONLINE}, { 0x103098, 5, RI_E1H_ONLINE},
+	{ 0x103800, 8, RI_ALL_ONLINE}, { 0x104000, 63, RI_ALL_ONLINE},
+	{ 0x104108, 1, RI_ALL_ONLINE}, { 0x104118, 1, RI_ALL_ONLINE},
+	{ 0x104200, 17, RI_ALL_ONLINE}, { 0x104400, 64, RI_ALL_ONLINE},
+	{ 0x104500, 192, RI_ALL_OFFLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+	{ 0x104900, 192, RI_ALL_OFFLINE}, { 0x105000, 7, RI_ALL_ONLINE},
+	{ 0x10501c, 1, RI_ALL_OFFLINE}, { 0x105020, 3, RI_ALL_ONLINE},
+	{ 0x10502c, 1, RI_ALL_OFFLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+	{ 0x10503c, 1, RI_ALL_OFFLINE}, { 0x105040, 3, RI_ALL_ONLINE},
+	{ 0x10504c, 1, RI_ALL_OFFLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+	{ 0x10505c, 1, RI_ALL_OFFLINE}, { 0x105060, 3, RI_ALL_ONLINE},
+	{ 0x10506c, 1, RI_ALL_OFFLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+	{ 0x10507c, 1, RI_ALL_OFFLINE}, { 0x105080, 3, RI_ALL_ONLINE},
+	{ 0x10508c, 1, RI_ALL_OFFLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+	{ 0x10509c, 1, RI_ALL_OFFLINE}, { 0x1050a0, 3, RI_ALL_ONLINE},
+	{ 0x1050ac, 1, RI_ALL_OFFLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+	{ 0x1050bc, 1, RI_ALL_OFFLINE}, { 0x1050c0, 3, RI_ALL_ONLINE},
+	{ 0x1050cc, 1, RI_ALL_OFFLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+	{ 0x1050dc, 1, RI_ALL_OFFLINE}, { 0x1050e0, 3, RI_ALL_ONLINE},
+	{ 0x1050ec, 1, RI_ALL_OFFLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+	{ 0x1050fc, 1, RI_ALL_OFFLINE}, { 0x105100, 3, RI_ALL_ONLINE},
+	{ 0x10510c, 1, RI_ALL_OFFLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+	{ 0x10511c, 1, RI_ALL_OFFLINE}, { 0x105120, 3, RI_ALL_ONLINE},
+	{ 0x10512c, 1, RI_ALL_OFFLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+	{ 0x10513c, 1, RI_ALL_OFFLINE}, { 0x105140, 3, RI_ALL_ONLINE},
+	{ 0x10514c, 1, RI_ALL_OFFLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+	{ 0x10515c, 1, RI_ALL_OFFLINE}, { 0x105160, 3, RI_ALL_ONLINE},
+	{ 0x10516c, 1, RI_ALL_OFFLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+	{ 0x10517c, 1, RI_ALL_OFFLINE}, { 0x105180, 3, RI_ALL_ONLINE},
+	{ 0x10518c, 1, RI_ALL_OFFLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+	{ 0x10519c, 1, RI_ALL_OFFLINE}, { 0x1051a0, 3, RI_ALL_ONLINE},
+	{ 0x1051ac, 1, RI_ALL_OFFLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+	{ 0x1051bc, 1, RI_ALL_OFFLINE}, { 0x1051c0, 3, RI_ALL_ONLINE},
+	{ 0x1051cc, 1, RI_ALL_OFFLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+	{ 0x1051dc, 1, RI_ALL_OFFLINE}, { 0x1051e0, 3, RI_ALL_ONLINE},
+	{ 0x1051ec, 1, RI_ALL_OFFLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+	{ 0x1051fc, 1, RI_ALL_OFFLINE}, { 0x105200, 3, RI_ALL_ONLINE},
+	{ 0x10520c, 1, RI_ALL_OFFLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+	{ 0x10521c, 1, RI_ALL_OFFLINE}, { 0x105220, 3, RI_ALL_ONLINE},
+	{ 0x10522c, 1, RI_ALL_OFFLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+	{ 0x10523c, 1, RI_ALL_OFFLINE}, { 0x105240, 3, RI_ALL_ONLINE},
+	{ 0x10524c, 1, RI_ALL_OFFLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+	{ 0x10525c, 1, RI_ALL_OFFLINE}, { 0x105260, 3, RI_ALL_ONLINE},
+	{ 0x10526c, 1, RI_ALL_OFFLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+	{ 0x10527c, 1, RI_ALL_OFFLINE}, { 0x105280, 3, RI_ALL_ONLINE},
+	{ 0x10528c, 1, RI_ALL_OFFLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+	{ 0x10529c, 1, RI_ALL_OFFLINE}, { 0x1052a0, 3, RI_ALL_ONLINE},
+	{ 0x1052ac, 1, RI_ALL_OFFLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+	{ 0x1052bc, 1, RI_ALL_OFFLINE}, { 0x1052c0, 3, RI_ALL_ONLINE},
+	{ 0x1052cc, 1, RI_ALL_OFFLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+	{ 0x1052dc, 1, RI_ALL_OFFLINE}, { 0x1052e0, 3, RI_ALL_ONLINE},
+	{ 0x1052ec, 1, RI_ALL_OFFLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+	{ 0x1052fc, 1, RI_ALL_OFFLINE}, { 0x105300, 3, RI_ALL_ONLINE},
+	{ 0x10530c, 1, RI_ALL_OFFLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+	{ 0x10531c, 1, RI_ALL_OFFLINE}, { 0x105320, 3, RI_ALL_ONLINE},
+	{ 0x10532c, 1, RI_ALL_OFFLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+	{ 0x10533c, 1, RI_ALL_OFFLINE}, { 0x105340, 3, RI_ALL_ONLINE},
+	{ 0x10534c, 1, RI_ALL_OFFLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+	{ 0x10535c, 1, RI_ALL_OFFLINE}, { 0x105360, 3, RI_ALL_ONLINE},
+	{ 0x10536c, 1, RI_ALL_OFFLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+	{ 0x10537c, 1, RI_ALL_OFFLINE}, { 0x105380, 3, RI_ALL_ONLINE},
+	{ 0x10538c, 1, RI_ALL_OFFLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+	{ 0x10539c, 1, RI_ALL_OFFLINE}, { 0x1053a0, 3, RI_ALL_ONLINE},
+	{ 0x1053ac, 1, RI_ALL_OFFLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+	{ 0x1053bc, 1, RI_ALL_OFFLINE}, { 0x1053c0, 3, RI_ALL_ONLINE},
+	{ 0x1053cc, 1, RI_ALL_OFFLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+	{ 0x1053dc, 1, RI_ALL_OFFLINE}, { 0x1053e0, 3, RI_ALL_ONLINE},
+	{ 0x1053ec, 1, RI_ALL_OFFLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+	{ 0x1053fc, 769, RI_ALL_OFFLINE}, { 0x108000, 33, RI_ALL_ONLINE},
+	{ 0x108090, 1, RI_ALL_ONLINE}, { 0x1080a0, 1, RI_ALL_ONLINE},
+	{ 0x1080ac, 5, RI_E1H_ONLINE}, { 0x108100, 5, RI_ALL_ONLINE},
+	{ 0x108120, 5, RI_ALL_ONLINE}, { 0x108200, 74, RI_ALL_ONLINE},
+	{ 0x108400, 74, RI_ALL_ONLINE}, { 0x108800, 152, RI_ALL_ONLINE},
+	{ 0x109000, 1, RI_ALL_ONLINE}, { 0x120000, 347, RI_ALL_ONLINE},
+	{ 0x120578, 1, RI_ALL_ONLINE}, { 0x120588, 1, RI_ALL_ONLINE},
+	{ 0x120598, 1, RI_ALL_ONLINE}, { 0x12059c, 23, RI_E1H_ONLINE},
+	{ 0x120614, 1, RI_E1H_ONLINE}, { 0x12061c, 30, RI_E1H_ONLINE},
+	{ 0x12080c, 65, RI_ALL_ONLINE}, { 0x120a00, 2, RI_ALL_ONLINE},
+	{ 0x122000, 2, RI_ALL_ONLINE}, { 0x128000, 2, RI_E1H_ONLINE},
+	{ 0x140000, 114, RI_ALL_ONLINE}, { 0x1401d4, 1, RI_ALL_ONLINE},
+	{ 0x1401e4, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+	{ 0x144000, 4, RI_ALL_ONLINE}, { 0x148000, 4, RI_ALL_ONLINE},
+	{ 0x14c000, 4, RI_ALL_ONLINE}, { 0x150000, 4, RI_ALL_ONLINE},
+	{ 0x154000, 4, RI_ALL_ONLINE}, { 0x158000, 4, RI_ALL_ONLINE},
+	{ 0x15c000, 7, RI_E1H_ONLINE}, { 0x161000, 7, RI_ALL_ONLINE},
+	{ 0x161028, 1, RI_ALL_ONLINE}, { 0x161038, 1, RI_ALL_ONLINE},
+	{ 0x161800, 2, RI_ALL_ONLINE}, { 0x164000, 60, RI_ALL_ONLINE},
+	{ 0x1640fc, 1, RI_ALL_ONLINE}, { 0x16410c, 1, RI_ALL_ONLINE},
+	{ 0x164110, 2, RI_E1H_ONLINE}, { 0x164200, 1, RI_ALL_ONLINE},
+	{ 0x164208, 1, RI_ALL_ONLINE}, { 0x164210, 1, RI_ALL_ONLINE},
+	{ 0x164218, 1, RI_ALL_ONLINE}, { 0x164220, 1, RI_ALL_ONLINE},
+	{ 0x164228, 1, RI_ALL_ONLINE}, { 0x164230, 1, RI_ALL_ONLINE},
+	{ 0x164238, 1, RI_ALL_ONLINE}, { 0x164240, 1, RI_ALL_ONLINE},
+	{ 0x164248, 1, RI_ALL_ONLINE}, { 0x164250, 1, RI_ALL_ONLINE},
+	{ 0x164258, 1, RI_ALL_ONLINE}, { 0x164260, 1, RI_ALL_ONLINE},
+	{ 0x164270, 2, RI_ALL_ONLINE}, { 0x164280, 2, RI_ALL_ONLINE},
+	{ 0x164800, 2, RI_ALL_ONLINE}, { 0x165000, 2, RI_ALL_ONLINE},
+	{ 0x166000, 164, RI_ALL_ONLINE}, { 0x16629c, 1, RI_ALL_ONLINE},
+	{ 0x1662ac, 1, RI_ALL_ONLINE}, { 0x1662bc, 1, RI_ALL_ONLINE},
+	{ 0x166400, 49, RI_ALL_ONLINE}, { 0x1664c8, 38, RI_ALL_ONLINE},
+	{ 0x166568, 2, RI_ALL_ONLINE}, { 0x166800, 1, RI_ALL_ONLINE},
+	{ 0x168000, 270, RI_ALL_ONLINE}, { 0x168444, 1, RI_ALL_ONLINE},
+	{ 0x168454, 1, RI_ALL_ONLINE}, { 0x168800, 19, RI_ALL_ONLINE},
+	{ 0x168900, 1, RI_ALL_ONLINE}, { 0x168a00, 128, RI_ALL_ONLINE},
+	{ 0x16a000, 1, RI_ALL_ONLINE}, { 0x16a004, 1535, RI_ALL_OFFLINE},
+	{ 0x16c000, 1, RI_ALL_ONLINE}, { 0x16c004, 1535, RI_ALL_OFFLINE},
+	{ 0x16e000, 16, RI_E1H_ONLINE}, { 0x16e100, 1, RI_E1H_ONLINE},
+	{ 0x16e200, 2, RI_E1H_ONLINE}, { 0x16e400, 183, RI_E1H_ONLINE},
+	{ 0x170000, 93, RI_ALL_ONLINE}, { 0x170180, 1, RI_ALL_ONLINE},
+	{ 0x170190, 1, RI_ALL_ONLINE}, { 0x170200, 4, RI_ALL_ONLINE},
+	{ 0x170214, 1, RI_ALL_ONLINE}, { 0x178000, 1, RI_ALL_ONLINE},
+	{ 0x180000, 61, RI_ALL_ONLINE}, { 0x180100, 1, RI_ALL_ONLINE},
+	{ 0x180110, 1, RI_ALL_ONLINE}, { 0x180120, 1, RI_ALL_ONLINE},
+	{ 0x180130, 1, RI_ALL_ONLINE}, { 0x18013c, 2, RI_E1H_ONLINE},
+	{ 0x180200, 58, RI_ALL_ONLINE}, { 0x180340, 4, RI_ALL_ONLINE},
+	{ 0x180400, 1, RI_ALL_ONLINE}, { 0x180404, 255, RI_ALL_OFFLINE},
+	{ 0x181000, 4, RI_ALL_ONLINE}, { 0x181010, 1020, RI_ALL_OFFLINE},
+	{ 0x1a0000, 1, RI_ALL_ONLINE}, { 0x1a0004, 1023, RI_ALL_OFFLINE},
+	{ 0x1a1000, 1, RI_ALL_ONLINE}, { 0x1a1004, 4607, RI_ALL_OFFLINE},
+	{ 0x1a5800, 2560, RI_E1H_OFFLINE}, { 0x1a8000, 64, RI_ALL_OFFLINE},
+	{ 0x1a8100, 1984, RI_E1H_OFFLINE}, { 0x1aa000, 1, RI_E1H_ONLINE},
+	{ 0x1aa004, 6655, RI_E1H_OFFLINE}, { 0x1b1800, 128, RI_ALL_OFFLINE},
+	{ 0x1b1c00, 128, RI_ALL_OFFLINE}, { 0x1b2000, 1, RI_ALL_OFFLINE},
+	{ 0x1b2400, 64, RI_E1H_OFFLINE}, { 0x1b8200, 1, RI_ALL_ONLINE},
+	{ 0x1b8240, 1, RI_ALL_ONLINE}, { 0x1b8280, 1, RI_ALL_ONLINE},
+	{ 0x1b82c0, 1, RI_ALL_ONLINE}, { 0x1b8a00, 1, RI_ALL_ONLINE},
+	{ 0x1b8a80, 1, RI_ALL_ONLINE}, { 0x1c0000, 2, RI_ALL_ONLINE},
+	{ 0x200000, 65, RI_ALL_ONLINE}, { 0x200110, 1, RI_ALL_ONLINE},
+	{ 0x200120, 1, RI_ALL_ONLINE}, { 0x200130, 1, RI_ALL_ONLINE},
+	{ 0x200140, 1, RI_ALL_ONLINE}, { 0x20014c, 2, RI_E1H_ONLINE},
+	{ 0x200200, 58, RI_ALL_ONLINE}, { 0x200340, 4, RI_ALL_ONLINE},
+	{ 0x200400, 1, RI_ALL_ONLINE}, { 0x200404, 255, RI_ALL_OFFLINE},
+	{ 0x202000, 4, RI_ALL_ONLINE}, { 0x202010, 2044, RI_ALL_OFFLINE},
+	{ 0x220000, 1, RI_ALL_ONLINE}, { 0x220004, 1023, RI_ALL_OFFLINE},
+	{ 0x221000, 1, RI_ALL_ONLINE}, { 0x221004, 4607, RI_ALL_OFFLINE},
+	{ 0x225800, 1536, RI_E1H_OFFLINE}, { 0x227000, 1, RI_E1H_ONLINE},
+	{ 0x227004, 1023, RI_E1H_OFFLINE}, { 0x228000, 64, RI_ALL_OFFLINE},
+	{ 0x228100, 8640, RI_E1H_OFFLINE}, { 0x231800, 128, RI_ALL_OFFLINE},
+	{ 0x231c00, 128, RI_ALL_OFFLINE}, { 0x232000, 1, RI_ALL_OFFLINE},
+	{ 0x232400, 64, RI_E1H_OFFLINE}, { 0x238200, 1, RI_ALL_ONLINE},
+	{ 0x238240, 1, RI_ALL_ONLINE}, { 0x238280, 1, RI_ALL_ONLINE},
+	{ 0x2382c0, 1, RI_ALL_ONLINE}, { 0x238a00, 1, RI_ALL_ONLINE},
+	{ 0x238a80, 1, RI_ALL_ONLINE}, { 0x240000, 2, RI_ALL_ONLINE},
+	{ 0x280000, 65, RI_ALL_ONLINE}, { 0x280110, 1, RI_ALL_ONLINE},
+	{ 0x280120, 1, RI_ALL_ONLINE}, { 0x280130, 1, RI_ALL_ONLINE},
+	{ 0x280140, 1, RI_ALL_ONLINE}, { 0x28014c, 2, RI_E1H_ONLINE},
+	{ 0x280200, 58, RI_ALL_ONLINE}, { 0x280340, 4, RI_ALL_ONLINE},
+	{ 0x280400, 1, RI_ALL_ONLINE}, { 0x280404, 255, RI_ALL_OFFLINE},
+	{ 0x282000, 4, RI_ALL_ONLINE}, { 0x282010, 2044, RI_ALL_OFFLINE},
+	{ 0x2a0000, 1, RI_ALL_ONLINE}, { 0x2a0004, 1023, RI_ALL_OFFLINE},
+	{ 0x2a1000, 1, RI_ALL_ONLINE}, { 0x2a1004, 4607, RI_ALL_OFFLINE},
+	{ 0x2a5800, 2560, RI_E1H_OFFLINE}, { 0x2a8000, 64, RI_ALL_OFFLINE},
+	{ 0x2a8100, 960, RI_E1H_OFFLINE}, { 0x2a9000, 1, RI_E1H_ONLINE},
+	{ 0x2a9004, 7679, RI_E1H_OFFLINE}, { 0x2b1800, 128, RI_ALL_OFFLINE},
+	{ 0x2b1c00, 128, RI_ALL_OFFLINE}, { 0x2b2000, 1, RI_ALL_OFFLINE},
+	{ 0x2b2400, 64, RI_E1H_OFFLINE}, { 0x2b8200, 1, RI_ALL_ONLINE},
+	{ 0x2b8240, 1, RI_ALL_ONLINE}, { 0x2b8280, 1, RI_ALL_ONLINE},
+	{ 0x2b82c0, 1, RI_ALL_ONLINE}, { 0x2b8a00, 1, RI_ALL_ONLINE},
+	{ 0x2b8a80, 1, RI_ALL_ONLINE}, { 0x2c0000, 2, RI_ALL_ONLINE},
+	{ 0x300000, 65, RI_ALL_ONLINE}, { 0x300110, 1, RI_ALL_ONLINE},
+	{ 0x300120, 1, RI_ALL_ONLINE}, { 0x300130, 1, RI_ALL_ONLINE},
+	{ 0x300140, 1, RI_ALL_ONLINE}, { 0x30014c, 2, RI_E1H_ONLINE},
+	{ 0x300200, 58, RI_ALL_ONLINE}, { 0x300340, 4, RI_ALL_ONLINE},
+	{ 0x300400, 1, RI_ALL_ONLINE}, { 0x300404, 255, RI_ALL_OFFLINE},
+	{ 0x302000, 4, RI_ALL_ONLINE}, { 0x302010, 2044, RI_ALL_OFFLINE},
+	{ 0x320000, 1, RI_ALL_ONLINE}, { 0x320004, 1023, RI_ALL_OFFLINE},
+	{ 0x321000, 1, RI_ALL_ONLINE}, { 0x321004, 4607, RI_ALL_OFFLINE},
+	{ 0x325800, 2560, RI_E1H_OFFLINE}, { 0x328000, 64, RI_ALL_OFFLINE},
+	{ 0x328100, 536, RI_E1H_OFFLINE}, { 0x328960, 1, RI_E1H_ONLINE},
+	{ 0x328964, 8103, RI_E1H_OFFLINE}, { 0x331800, 128, RI_ALL_OFFLINE},
+	{ 0x331c00, 128, RI_ALL_OFFLINE}, { 0x332000, 1, RI_ALL_OFFLINE},
+	{ 0x332400, 64, RI_E1H_OFFLINE}, { 0x338200, 1, RI_ALL_ONLINE},
+	{ 0x338240, 1, RI_ALL_ONLINE}, { 0x338280, 1, RI_ALL_ONLINE},
+	{ 0x3382c0, 1, RI_ALL_ONLINE}, { 0x338a00, 1, RI_ALL_ONLINE},
+	{ 0x338a80, 1, RI_ALL_ONLINE}, { 0x340000, 2, RI_ALL_ONLINE}
+};
+
+
+#define IDLEREGS_COUNT		277
+static const struct reg_addr idle_addrs[IDLEREGS_COUNT] = {
+	{ 0x2114, 1, RI_ALL_ONLINE}, { 0x2120, 1, RI_ALL_ONLINE},
+	{ 0x212c, 4, RI_ALL_ONLINE}, { 0x2814, 1, RI_ALL_ONLINE},
+	{ 0x281c, 2, RI_ALL_ONLINE}, { 0xa38c, 1, RI_ALL_ONLINE},
+	{ 0xa408, 1, RI_ALL_ONLINE}, { 0xa42c, 12, RI_ALL_ONLINE},
+	{ 0xa600, 5, RI_E1H_ONLINE}, { 0xa618, 1, RI_E1H_ONLINE},
+	{ 0xc09c, 1, RI_ALL_ONLINE}, { 0x103b0, 1, RI_ALL_ONLINE},
+	{ 0x103c0, 1, RI_ALL_ONLINE}, { 0x103d0, 1, RI_E1H_ONLINE},
+	{ 0x2021c, 11, RI_ALL_ONLINE}, { 0x202a8, 1, RI_ALL_ONLINE},
+	{ 0x202b8, 1, RI_ALL_ONLINE}, { 0x20404, 1, RI_ALL_ONLINE},
+	{ 0x2040c, 2, RI_ALL_ONLINE}, { 0x2041c, 2, RI_ALL_ONLINE},
+	{ 0x40154, 14, RI_ALL_ONLINE}, { 0x40198, 1, RI_ALL_ONLINE},
+	{ 0x404ac, 1, RI_ALL_ONLINE}, { 0x404bc, 1, RI_ALL_ONLINE},
+	{ 0x42290, 1, RI_ALL_ONLINE}, { 0x422a0, 1, RI_ALL_ONLINE},
+	{ 0x422b0, 1, RI_ALL_ONLINE}, { 0x42548, 1, RI_ALL_ONLINE},
+	{ 0x42550, 1, RI_ALL_ONLINE}, { 0x42558, 1, RI_ALL_ONLINE},
+	{ 0x50160, 8, RI_ALL_ONLINE}, { 0x501d0, 1, RI_ALL_ONLINE},
+	{ 0x501e0, 1, RI_ALL_ONLINE}, { 0x50204, 1, RI_ALL_ONLINE},
+	{ 0x5020c, 2, RI_ALL_ONLINE}, { 0x5021c, 1, RI_ALL_ONLINE},
+	{ 0x60090, 1, RI_ALL_ONLINE}, { 0x6011c, 1, RI_ALL_ONLINE},
+	{ 0x6012c, 1, RI_ALL_ONLINE}, { 0xc101c, 1, RI_ALL_ONLINE},
+	{ 0xc102c, 1, RI_ALL_ONLINE}, { 0xc2290, 1, RI_ALL_ONLINE},
+	{ 0xc22a0, 1, RI_ALL_ONLINE}, { 0xc22b0, 1, RI_ALL_ONLINE},
+	{ 0xc2548, 1, RI_ALL_ONLINE}, { 0xc2550, 1, RI_ALL_ONLINE},
+	{ 0xc2558, 1, RI_ALL_ONLINE}, { 0xc4294, 1, RI_ALL_ONLINE},
+	{ 0xc42a4, 1, RI_ALL_ONLINE}, { 0xc42b4, 1, RI_ALL_ONLINE},
+	{ 0xc4550, 1, RI_ALL_ONLINE}, { 0xc4558, 1, RI_ALL_ONLINE},
+	{ 0xc4560, 1, RI_ALL_ONLINE}, { 0xd016c, 8, RI_ALL_ONLINE},
+	{ 0xd01d8, 1, RI_ALL_ONLINE}, { 0xd01e8, 1, RI_ALL_ONLINE},
+	{ 0xd0204, 1, RI_ALL_ONLINE}, { 0xd020c, 3, RI_ALL_ONLINE},
+	{ 0xe0154, 8, RI_ALL_ONLINE}, { 0xe01c8, 1, RI_ALL_ONLINE},
+	{ 0xe01d8, 1, RI_ALL_ONLINE}, { 0xe0204, 1, RI_ALL_ONLINE},
+	{ 0xe020c, 2, RI_ALL_ONLINE}, { 0xe021c, 2, RI_ALL_ONLINE},
+	{ 0x101014, 1, RI_ALL_ONLINE}, { 0x101030, 1, RI_ALL_ONLINE},
+	{ 0x101040, 1, RI_ALL_ONLINE}, { 0x102058, 1, RI_ALL_ONLINE},
+	{ 0x102080, 16, RI_ALL_ONLINE}, { 0x103004, 2, RI_ALL_ONLINE},
+	{ 0x103068, 1, RI_ALL_ONLINE}, { 0x103078, 1, RI_ALL_ONLINE},
+	{ 0x103088, 1, RI_ALL_ONLINE}, { 0x10309c, 2, RI_E1H_ONLINE},
+	{ 0x104004, 1, RI_ALL_ONLINE}, { 0x104018, 1, RI_ALL_ONLINE},
+	{ 0x104020, 1, RI_ALL_ONLINE}, { 0x10403c, 1, RI_ALL_ONLINE},
+	{ 0x1040fc, 1, RI_ALL_ONLINE}, { 0x10410c, 1, RI_ALL_ONLINE},
+	{ 0x104400, 64, RI_ALL_ONLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+	{ 0x105000, 3, RI_ALL_ONLINE}, { 0x105010, 3, RI_ALL_ONLINE},
+	{ 0x105020, 3, RI_ALL_ONLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+	{ 0x105040, 3, RI_ALL_ONLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+	{ 0x105060, 3, RI_ALL_ONLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+	{ 0x105080, 3, RI_ALL_ONLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+	{ 0x1050a0, 3, RI_ALL_ONLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+	{ 0x1050c0, 3, RI_ALL_ONLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+	{ 0x1050e0, 3, RI_ALL_ONLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+	{ 0x105100, 3, RI_ALL_ONLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+	{ 0x105120, 3, RI_ALL_ONLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+	{ 0x105140, 3, RI_ALL_ONLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+	{ 0x105160, 3, RI_ALL_ONLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+	{ 0x105180, 3, RI_ALL_ONLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+	{ 0x1051a0, 3, RI_ALL_ONLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+	{ 0x1051c0, 3, RI_ALL_ONLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+	{ 0x1051e0, 3, RI_ALL_ONLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+	{ 0x105200, 3, RI_ALL_ONLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+	{ 0x105220, 3, RI_ALL_ONLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+	{ 0x105240, 3, RI_ALL_ONLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+	{ 0x105260, 3, RI_ALL_ONLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+	{ 0x105280, 3, RI_ALL_ONLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+	{ 0x1052a0, 3, RI_ALL_ONLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+	{ 0x1052c0, 3, RI_ALL_ONLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+	{ 0x1052e0, 3, RI_ALL_ONLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+	{ 0x105300, 3, RI_ALL_ONLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+	{ 0x105320, 3, RI_ALL_ONLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+	{ 0x105340, 3, RI_ALL_ONLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+	{ 0x105360, 3, RI_ALL_ONLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+	{ 0x105380, 3, RI_ALL_ONLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+	{ 0x1053a0, 3, RI_ALL_ONLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+	{ 0x1053c0, 3, RI_ALL_ONLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+	{ 0x1053e0, 3, RI_ALL_ONLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+	{ 0x108094, 1, RI_ALL_ONLINE}, { 0x1201b0, 2, RI_ALL_ONLINE},
+	{ 0x12032c, 1, RI_ALL_ONLINE}, { 0x12036c, 3, RI_ALL_ONLINE},
+	{ 0x120408, 2, RI_ALL_ONLINE}, { 0x120414, 15, RI_ALL_ONLINE},
+	{ 0x120478, 2, RI_ALL_ONLINE}, { 0x12052c, 1, RI_ALL_ONLINE},
+	{ 0x120564, 3, RI_ALL_ONLINE}, { 0x12057c, 1, RI_ALL_ONLINE},
+	{ 0x12058c, 1, RI_ALL_ONLINE}, { 0x120608, 1, RI_E1H_ONLINE},
+	{ 0x120808, 1, RI_E1_ONLINE}, { 0x12080c, 2, RI_ALL_ONLINE},
+	{ 0x120818, 1, RI_ALL_ONLINE}, { 0x120820, 1, RI_ALL_ONLINE},
+	{ 0x120828, 1, RI_ALL_ONLINE}, { 0x120830, 1, RI_ALL_ONLINE},
+	{ 0x120838, 1, RI_ALL_ONLINE}, { 0x120840, 1, RI_ALL_ONLINE},
+	{ 0x120848, 1, RI_ALL_ONLINE}, { 0x120850, 1, RI_ALL_ONLINE},
+	{ 0x120858, 1, RI_ALL_ONLINE}, { 0x120860, 1, RI_ALL_ONLINE},
+	{ 0x120868, 1, RI_ALL_ONLINE}, { 0x120870, 1, RI_ALL_ONLINE},
+	{ 0x120878, 1, RI_ALL_ONLINE}, { 0x120880, 1, RI_ALL_ONLINE},
+	{ 0x120888, 1, RI_ALL_ONLINE}, { 0x120890, 1, RI_ALL_ONLINE},
+	{ 0x120898, 1, RI_ALL_ONLINE}, { 0x1208a0, 1, RI_ALL_ONLINE},
+	{ 0x1208a8, 1, RI_ALL_ONLINE}, { 0x1208b0, 1, RI_ALL_ONLINE},
+	{ 0x1208b8, 1, RI_ALL_ONLINE}, { 0x1208c0, 1, RI_ALL_ONLINE},
+	{ 0x1208c8, 1, RI_ALL_ONLINE}, { 0x1208d0, 1, RI_ALL_ONLINE},
+	{ 0x1208d8, 1, RI_ALL_ONLINE}, { 0x1208e0, 1, RI_ALL_ONLINE},
+	{ 0x1208e8, 1, RI_ALL_ONLINE}, { 0x1208f0, 1, RI_ALL_ONLINE},
+	{ 0x1208f8, 1, RI_ALL_ONLINE}, { 0x120900, 1, RI_ALL_ONLINE},
+	{ 0x120908, 1, RI_ALL_ONLINE}, { 0x14005c, 2, RI_ALL_ONLINE},
+	{ 0x1400d0, 2, RI_ALL_ONLINE}, { 0x1400e0, 1, RI_ALL_ONLINE},
+	{ 0x1401c8, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+	{ 0x16101c, 1, RI_ALL_ONLINE}, { 0x16102c, 1, RI_ALL_ONLINE},
+	{ 0x164014, 2, RI_ALL_ONLINE}, { 0x1640f0, 1, RI_ALL_ONLINE},
+	{ 0x166290, 1, RI_ALL_ONLINE}, { 0x1662a0, 1, RI_ALL_ONLINE},
+	{ 0x1662b0, 1, RI_ALL_ONLINE}, { 0x166548, 1, RI_ALL_ONLINE},
+	{ 0x166550, 1, RI_ALL_ONLINE}, { 0x166558, 1, RI_ALL_ONLINE},
+	{ 0x168000, 1, RI_ALL_ONLINE}, { 0x168008, 1, RI_ALL_ONLINE},
+	{ 0x168010, 1, RI_ALL_ONLINE}, { 0x168018, 1, RI_ALL_ONLINE},
+	{ 0x168028, 2, RI_ALL_ONLINE}, { 0x168058, 4, RI_ALL_ONLINE},
+	{ 0x168070, 1, RI_ALL_ONLINE}, { 0x168238, 1, RI_ALL_ONLINE},
+	{ 0x1682d0, 2, RI_ALL_ONLINE}, { 0x1682e0, 1, RI_ALL_ONLINE},
+	{ 0x168300, 67, RI_ALL_ONLINE}, { 0x168410, 2, RI_ALL_ONLINE},
+	{ 0x168438, 1, RI_ALL_ONLINE}, { 0x168448, 1, RI_ALL_ONLINE},
+	{ 0x168a00, 128, RI_ALL_ONLINE}, { 0x16e200, 128, RI_E1H_ONLINE},
+	{ 0x16e404, 2, RI_E1H_ONLINE}, { 0x16e584, 70, RI_E1H_ONLINE},
+	{ 0x1700a4, 1, RI_ALL_ONLINE}, { 0x1700ac, 2, RI_ALL_ONLINE},
+	{ 0x1700c0, 1, RI_ALL_ONLINE}, { 0x170174, 1, RI_ALL_ONLINE},
+	{ 0x170184, 1, RI_ALL_ONLINE}, { 0x1800f4, 1, RI_ALL_ONLINE},
+	{ 0x180104, 1, RI_ALL_ONLINE}, { 0x180114, 1, RI_ALL_ONLINE},
+	{ 0x180124, 1, RI_ALL_ONLINE}, { 0x18026c, 1, RI_ALL_ONLINE},
+	{ 0x1802a0, 1, RI_ALL_ONLINE}, { 0x1a1000, 1, RI_ALL_ONLINE},
+	{ 0x1aa000, 1, RI_E1H_ONLINE}, { 0x1b8000, 1, RI_ALL_ONLINE},
+	{ 0x1b8040, 1, RI_ALL_ONLINE}, { 0x1b8080, 1, RI_ALL_ONLINE},
+	{ 0x1b80c0, 1, RI_ALL_ONLINE}, { 0x200104, 1, RI_ALL_ONLINE},
+	{ 0x200114, 1, RI_ALL_ONLINE}, { 0x200124, 1, RI_ALL_ONLINE},
+	{ 0x200134, 1, RI_ALL_ONLINE}, { 0x20026c, 1, RI_ALL_ONLINE},
+	{ 0x2002a0, 1, RI_ALL_ONLINE}, { 0x221000, 1, RI_ALL_ONLINE},
+	{ 0x227000, 1, RI_E1H_ONLINE}, { 0x238000, 1, RI_ALL_ONLINE},
+	{ 0x238040, 1, RI_ALL_ONLINE}, { 0x238080, 1, RI_ALL_ONLINE},
+	{ 0x2380c0, 1, RI_ALL_ONLINE}, { 0x280104, 1, RI_ALL_ONLINE},
+	{ 0x280114, 1, RI_ALL_ONLINE}, { 0x280124, 1, RI_ALL_ONLINE},
+	{ 0x280134, 1, RI_ALL_ONLINE}, { 0x28026c, 1, RI_ALL_ONLINE},
+	{ 0x2802a0, 1, RI_ALL_ONLINE}, { 0x2a1000, 1, RI_ALL_ONLINE},
+	{ 0x2a9000, 1, RI_E1H_ONLINE}, { 0x2b8000, 1, RI_ALL_ONLINE},
+	{ 0x2b8040, 1, RI_ALL_ONLINE}, { 0x2b8080, 1, RI_ALL_ONLINE},
+	{ 0x2b80c0, 1, RI_ALL_ONLINE}, { 0x300104, 1, RI_ALL_ONLINE},
+	{ 0x300114, 1, RI_ALL_ONLINE}, { 0x300124, 1, RI_ALL_ONLINE},
+	{ 0x300134, 1, RI_ALL_ONLINE}, { 0x30026c, 1, RI_ALL_ONLINE},
+	{ 0x3002a0, 1, RI_ALL_ONLINE}, { 0x321000, 1, RI_ALL_ONLINE},
+	{ 0x328960, 1, RI_E1H_ONLINE}, { 0x338000, 1, RI_ALL_ONLINE},
+	{ 0x338040, 1, RI_ALL_ONLINE}, { 0x338080, 1, RI_ALL_ONLINE},
+	{ 0x3380c0, 1, RI_ALL_ONLINE}
+};
+
+static const u32 read_reg_e1_0[] = { 0x1b1000 };
+
+#define WREGS_COUNT_E1		1
+static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = {
+	{ 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE }
+};
+
+static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 };
+
+#define WREGS_COUNT_E1H		1
+static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
+	{ 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
+};
+
+
+static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
+
+
+#define TIMER_REGS_COUNT_E1	2
+static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] =
+	{ 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] =
+	{ 0x1640d0, 0x1640d4 };
+
+#define TIMER_REGS_COUNT_E1H	2
+static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] =
+	{ 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
+	{ 0x1640d0, 0x1640d4 };
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_fw_defs.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_fw_defs.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_fw_defs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_fw_defs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_fw_defs.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,8 +50,10 @@
 #define TSTORM_ASSERT_LIST_OFFSET(idx) \
 	(IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
-	(IS_E1H_OFFSET ? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) \
-	: (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
+	(IS_E1H_OFFSET ? (0x3350 + (port * 0x190) + (client_id * 0x10)) \
+	: (0x9c0 + (port * 0x130) + (client_id * 0x10)))
+#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \
+	(IS_E1H_OFFSET ? 0x1ad8 : 0xffffffff)
 #define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
 	(IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -81,43 +83,54 @@
 	(function * 0x38)))
 #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
 	(IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
-	0x50)) : (0x4000 + (port * 0x3f0) + (stats_counter_id * 0x38)))
-#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
-	(IS_E1H_OFFSET ? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) \
-	: (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
+	0x50)) : (0x4080 + (port * 0x5b0) + (stats_counter_id * 0x50)))
 #define TSTORM_STATS_FLAGS_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
 	(function * 0x8)))
-#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3b30 : 0x1c20)
+#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3680 : 0x1c20)
 #define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
 #define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
 #define USTORM_ASSERT_LIST_INDEX_OFFSET \
-	(IS_E1H_OFFSET ? 0x8000 : 0x1000)
+	(IS_E1H_OFFSET ? 0x8960 : 0x1000)
 #define USTORM_ASSERT_LIST_OFFSET(idx) \
-	(IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+	(IS_E1H_OFFSET ? (0x8980 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
-	(IS_E1H_OFFSET ? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
-	(0x5450 + (port * 0x1c8) + (clientId * 0x18)))
+	(IS_E1H_OFFSET ? (0x8018 + (port * 0x4b0) + (clientId * 0x30)) : \
+	(0x5330 + (port * 0x260) + (clientId * 0x20)))
 #define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
-	(IS_E1H_OFFSET ? (0x951a + ((function>>1) * 0x28) + \
-	((function&1) * 0xa0) + (index * 0x4)) : (0x191a + (function * \
-	0x28) + (index * 0x4)))
+	(IS_E1H_OFFSET ? (0x9522 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
+	0x40) + (index * 0x4)))
 #define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x28) + \
-	((function&1) * 0xa0)) : (0x1900 + (function * 0x28)))
+	(IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
 #define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x28) + \
-	((function&1) * 0xa0)) : (0x1908 + (function * 0x28)))
+	(IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
+#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \
+	(IS_E1H_OFFSET ? (0x8020 + (port * 0x4b0) + (clientId * 0x30)) : \
+	0xffffffff)
+#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1d98 + \
+	(function * 0x8)))
 #define USTORM_FUNCTION_MODE_OFFSET \
 	(IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
 #define USTORM_HC_BTR_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
+	(IS_E1H_OFFSET ? (0x9704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
 #define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
-	(IS_E1H_OFFSET ? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
-	(0x5448 + (port * 0x1c8) + (clientId * 0x18)))
+	(IS_E1H_OFFSET ? (0x8010 + (port * 0x4b0) + (clientId * 0x30)) : \
+	(0x5328 + (port * 0x260) + (clientId * 0x20)))
 #define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5408 + \
+	(IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5308 + \
 	(function * 0x8)))
+#define USTORM_PAUSE_ENABLED_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
+#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
+	(IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \
+	0x28)) : (0x4740 + (port * 0x2d0) + (stats_counter_id * 0x28)))
+#define USTORM_RX_PRODS_OFFSET(port, client_id) \
+	(IS_E1H_OFFSET ? (0x8000 + (port * 0x4b0) + (client_id * 0x30)) \
+	: (0x5318 + (port * 0x260) + (client_id * 0x20)))
 #define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
 	(IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
 	(index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
@@ -132,12 +145,15 @@
 #define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
 	(IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
 	(0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define USTORM_STATS_FLAGS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1d80 + \
+	(function * 0x8)))
 #define XSTORM_ASSERT_LIST_INDEX_OFFSET \
 	(IS_E1H_OFFSET ? 0x9000 : 0x1000)
 #define XSTORM_ASSERT_LIST_OFFSET(idx) \
 	(IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
+	(IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3ba0 + (port * 0x50)))
 #define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
 	(IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -149,23 +165,23 @@
 	(IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
 #define XSTORM_E1HOV_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2ab8 + (function * 0x2)) : 0xffffffff)
+	(IS_E1H_OFFSET ? (0x2c10 + (function * 0x2)) : 0xffffffff)
 #define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
 	(function * 0x8)))
 #define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2568 + (function * 0x70)) : (0x3c60 + \
-	(function * 0x70)))
+	(IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3c80 + \
+	(function * 0x90)))
 #define XSTORM_FUNCTION_MODE_OFFSET \
-	(IS_E1H_OFFSET ? 0x2ac8 : 0xffffffff)
+	(IS_E1H_OFFSET ? 0x2c20 : 0xffffffff)
 #define XSTORM_HC_BTR_OFFSET(port) \
 	(IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
 #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
 	(IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
 	0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
 #define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2528 + (function * 0x70)) : (0x3c20 + \
-	(function * 0x70)))
+	(IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3c40 + \
+	(function * 0x90)))
 #define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
 	(function * 0x10)))
@@ -178,7 +194,7 @@
 #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
 
 /**
-* This file defines HSI constatnts for the ETH flow
+* This file defines HSI constants for the ETH flow
 */
 #ifdef _EVEREST_MICROCODE
 #include "microcode_constants.h"
@@ -196,18 +212,18 @@
 #define IPV6_HASH_TYPE 3
 #define TCP_IPV6_HASH_TYPE 4
 
-/* Ethernet Ring parmaters */
+
+/* Ethernet Ring parameters */
 #define X_ETH_LOCAL_RING_SIZE 13
 #define FIRST_BD_IN_PKT 0
 #define PARSE_BD_INDEX 1
-#define NUM_OF_ETH_BDS_IN_PAGE \
-	((PAGE_SIZE) / (STRUCT_SIZE(eth_tx_bd)/8))
+#define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
 
 
 /* Rx ring params */
-#define U_ETH_LOCAL_BD_RING_SIZE (16)
-#define U_ETH_LOCAL_SGE_RING_SIZE (12)
-#define U_ETH_SGL_SIZE (8)
+#define U_ETH_LOCAL_BD_RING_SIZE 16
+#define U_ETH_LOCAL_SGE_RING_SIZE 12
+#define U_ETH_SGL_SIZE 8
 
 
 #define U_ETH_BDS_PER_PAGE_MASK \
@@ -229,15 +245,15 @@
 #define U_ETH_UNDEFINED_Q 0xFF
 
 /* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
-#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
-#define RAMROD_CMD_ID_ETH_UPDATE (100)
-#define RAMROD_CMD_ID_ETH_HALT (105)
-#define RAMROD_CMD_ID_ETH_SET_MAC (110)
-#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
-#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
+#define RAMROD_CMD_ID_ETH_PORT_SETUP 80
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85
+#define RAMROD_CMD_ID_ETH_STAT_QUERY 90
+#define RAMROD_CMD_ID_ETH_UPDATE 100
+#define RAMROD_CMD_ID_ETH_HALT 105
+#define RAMROD_CMD_ID_ETH_SET_MAC 110
+#define RAMROD_CMD_ID_ETH_CFC_DEL 115
+#define RAMROD_CMD_ID_ETH_PORT_DEL 120
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125
 
 
 /* command values for set mac command */
@@ -254,12 +270,16 @@
 #define ETH_MAX_RX_CLIENTS_E1H 25
 
 /* Maximal aggregation queues supported */
-#define ETH_MAX_AGGREGATION_QUEUES_E1 (32)
-#define ETH_MAX_AGGREGATION_QUEUES_E1H (64)
+#define ETH_MAX_AGGREGATION_QUEUES_E1 32
+#define ETH_MAX_AGGREGATION_QUEUES_E1H 64
+
+/* ETH RSS modes */
+#define ETH_RSS_MODE_DISABLED 0
+#define ETH_RSS_MODE_REGULAR 1
 
 
 /**
-* This file defines HSI constatnts common to all microcode flows
+* This file defines HSI constants common to all microcode flows
 */
 
 /* Connection types */
@@ -278,25 +298,22 @@
 #define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
 #define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
 #define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define ISCSI_STATE \
-	(ISCSI_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define FCOE_STATE (FCOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
 
 /* microcode fixed page page size 4K (chains and ring segments) */
-#define MC_PAGE_SIZE (4096)
+#define MC_PAGE_SIZE 4096
 
 
 /* Host coalescing constants */
 
 /* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 4
+#define HC_USTORM_DEF_SB_NUM_INDICES 8
 #define HC_CSTORM_DEF_SB_NUM_INDICES 8
 #define HC_XSTORM_DEF_SB_NUM_INDICES 4
 #define HC_TSTORM_DEF_SB_NUM_INDICES 4
 #define HC_USTORM_SB_NUM_INDICES 4
 #define HC_CSTORM_SB_NUM_INDICES 4
 
-/* index values - which counterto update */
+/* index values - which counter to update */
 
 #define HC_INDEX_U_TOE_RX_CQ_CONS 0
 #define HC_INDEX_U_ETH_RX_CQ_CONS 1
@@ -330,16 +347,16 @@
 #define ATTENTION_ID 4
 
 /* max number of slow path commands per port */
-#define MAX_RAMRODS_PER_PORT (8)
+#define MAX_RAMRODS_PER_PORT 8
 
 /* values for RX ETH CQE type field */
-#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
-#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
+#define RX_ETH_CQE_TYPE_ETH_FASTPATH 0
+#define RX_ETH_CQE_TYPE_ETH_RAMROD 1
 
 
 /**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define EMULATION_FREQUENCY_FACTOR (1600)
-#define FPGA_FREQUENCY_FACTOR (100)
+#define EMULATION_FREQUENCY_FACTOR 1600
+#define FPGA_FREQUENCY_FACTOR 100
 
 #define TIMERS_TICK_SIZE_CHIP (1e-3)
 #define TIMERS_TICK_SIZE_EMUL \
@@ -353,12 +370,9 @@
 #define TSEMI_CLK1_RESUL_FPGA \
  ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
 
-#define USEMI_CLK1_RESUL_CHIP \
- (TIMERS_TICK_SIZE_CHIP)
-#define USEMI_CLK1_RESUL_EMUL \
- (TIMERS_TICK_SIZE_EMUL)
-#define USEMI_CLK1_RESUL_FPGA \
- (TIMERS_TICK_SIZE_FPGA)
+#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP)
+#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL)
+#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA)
 
 #define XSEMI_CLK1_RESUL_CHIP (1e-3)
 #define XSEMI_CLK1_RESUL_EMUL \
@@ -383,12 +397,15 @@
 #define XSTORM_IP_ID_ROLL_HALF 0x8000
 #define XSTORM_IP_ID_ROLL_ALL 0
 
-#define FW_LOG_LIST_SIZE (50)
+#define FW_LOG_LIST_SIZE 50
 
 #define NUM_OF_PROTOCOLS 4
-#define MAX_COS_NUMBER 16
+#define NUM_OF_SAFC_BITS 16
+#define MAX_COS_NUMBER 4
 #define MAX_T_STAT_COUNTER_ID 18
 #define MAX_X_STAT_COUNTER_ID 18
+#define MAX_U_STAT_COUNTER_ID 18
+
 
 #define UNKNOWN_ADDRESS 0
 #define UNICAST_ADDRESS 1
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,16 @@
 #endif
 
 
+#define BNX2X_MULTI_QUEUE
+
+#define BNX2X_NEW_NAPI
+
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
+
 /* error/debug prints */
 
 #define DRV_MODULE_NAME		"bnx2x"
@@ -92,12 +102,10 @@
 
 #define REG_RD(bp, offset)		readl(REG_ADDR(bp, offset))
 #define REG_RD8(bp, offset)		readb(REG_ADDR(bp, offset))
-#define REG_RD64(bp, offset)		readq(REG_ADDR(bp, offset))
 
 #define REG_WR(bp, offset, val)		writel((u32)val, REG_ADDR(bp, offset))
 #define REG_WR8(bp, offset, val)	writeb((u8)val, REG_ADDR(bp, offset))
 #define REG_WR16(bp, offset, val)	writew((u16)val, REG_ADDR(bp, offset))
-#define REG_WR32(bp, offset, val)	REG_WR(bp, offset, val)
 
 #define REG_RD_IND(bp, offset)		bnx2x_reg_rd_ind(bp, offset)
 #define REG_WR_IND(bp, offset, val)	bnx2x_reg_wr_ind(bp, offset, val)
@@ -154,8 +162,6 @@ struct sw_rx_page {
 #define SGE_PAGE_SHIFT			PAGE_SHIFT
 #define SGE_PAGE_ALIGN(addr)		PAGE_ALIGN((typeof(PAGE_SIZE))addr)
 
-#define BCM_RX_ETH_PAYLOAD_ALIGN	64
-
 /* SGE ring related macros */
 #define NUM_RX_SGE_PAGES		2
 #define RX_SGE_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
@@ -187,6 +193,43 @@ struct sw_rx_page {
 #define NEXT_SGE_MASK_ELEM(el)		(((el) + 1) & RX_SGE_MASK_LEN_MASK)
 
 
+struct bnx2x_eth_q_stats {
+	u32 total_bytes_received_hi;
+	u32 total_bytes_received_lo;
+	u32 total_bytes_transmitted_hi;
+	u32 total_bytes_transmitted_lo;
+	u32 total_unicast_packets_received_hi;
+	u32 total_unicast_packets_received_lo;
+	u32 total_multicast_packets_received_hi;
+	u32 total_multicast_packets_received_lo;
+	u32 total_broadcast_packets_received_hi;
+	u32 total_broadcast_packets_received_lo;
+	u32 total_unicast_packets_transmitted_hi;
+	u32 total_unicast_packets_transmitted_lo;
+	u32 total_multicast_packets_transmitted_hi;
+	u32 total_multicast_packets_transmitted_lo;
+	u32 total_broadcast_packets_transmitted_hi;
+	u32 total_broadcast_packets_transmitted_lo;
+	u32 valid_bytes_received_hi;
+	u32 valid_bytes_received_lo;
+
+	u32 error_bytes_received_hi;
+	u32 error_bytes_received_lo;
+	u32 etherstatsoverrsizepkts_hi;
+	u32 etherstatsoverrsizepkts_lo;
+	u32 no_buff_discard_hi;
+	u32 no_buff_discard_lo;
+
+	u32 driver_xoff;
+	u32 rx_err_discard_pkt;
+	u32 rx_skb_alloc_failed;
+	u32 hw_csum_err;
+};
+
+#define BNX2X_NUM_Q_STATS		11
+#define Q_STATS_OFFSET32(stat_name) \
+			(offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
+
 struct bnx2x_fastpath {
 
 	struct napi_struct	napi;
@@ -228,20 +271,15 @@ struct bnx2x_fastpath {
 	u8			index;	/* number in fp array */
 	u8			cl_id;	/* eth client id */
 	u8			sb_id;	/* status block number in HW */
-#define FP_IDX(fp)			(fp->index)
-#define FP_CL_ID(fp)			(fp->cl_id)
-#define BP_CL_ID(bp)			(bp->fp[0].cl_id)
-#define FP_SB_ID(fp)			(fp->sb_id)
-#define CNIC_SB_ID			0
 
 	u16			tx_pkt_prod;
 	u16			tx_pkt_cons;
 	u16			tx_bd_prod;
 	u16			tx_bd_cons;
-	u16			*tx_cons_sb;
+	__le16			*tx_cons_sb;
 
-	u16			fp_c_idx;
-	u16			fp_u_idx;
+	__le16			fp_c_idx;
+	__le16			fp_u_idx;
 
 	u16			rx_bd_prod;
 	u16			rx_bd_cons;
@@ -250,8 +288,8 @@ struct bnx2x_fastpath {
 	u16			rx_sge_prod;
 	/* The last maximal completed SGE */
 	u16			last_max_sge;
-	u16			*rx_cons_sb;
-	u16			*rx_bd_cons_sb;
+	__le16			*rx_cons_sb;
+	__le16			*rx_bd_cons_sb;
 
 	unsigned long		tx_pkt,
 				rx_pkt,
@@ -266,6 +304,12 @@ struct bnx2x_fastpath {
 	u64			tpa_queue_used;
 #endif
 
+	struct tstorm_per_client_stats old_tclient;
+	struct ustorm_per_client_stats old_uclient;
+	struct xstorm_per_client_stats old_xclient;
+	struct bnx2x_eth_q_stats eth_q_stats;
+
+	char			name[IFNAMSIZ];
 	struct bnx2x		*bp; /* parent */
 };
 
@@ -401,10 +445,13 @@ struct bnx2x_fastpath {
 #define BNX2X_RX_CSUM_OK(cqe) \
 			(!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
 
+#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \
+				(((le16_to_cpu(flags) & \
+				   PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \
+				  PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT) \
+				 == PRS_FLAG_OVERETH_IPV4)
 #define BNX2X_RX_SUM_FIX(cqe) \
-			((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
-			  PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
-			 (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+	BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
 
 
 #define FP_USB_FUNC_OFF			(2 + 2*HC_USTORM_SB_NUM_INDICES)
@@ -478,11 +525,8 @@ struct bnx2x_common {
 	u32			shmem_base;
 
 	u32			hw_config;
-	u32			board;
 
 	u32			bc_ver;
-
-	char			*name;
 };
 
 
@@ -528,6 +572,7 @@ struct bnx2x_port {
 
 	/* used to synchronize phy accesses */
 	struct mutex		phy_mutex;
+	int			need_hw_lock;
 
 	u32			port_stx;
 
@@ -573,6 +618,10 @@ struct bnx2x_eth_stats {
 
 	u32 error_bytes_received_hi;
 	u32 error_bytes_received_lo;
+	u32 etherstatsoverrsizepkts_hi;
+	u32 etherstatsoverrsizepkts_lo;
+	u32 no_buff_discard_hi;
+	u32 no_buff_discard_lo;
 
 	u32 rx_stat_ifhcinbadoctets_hi;
 	u32 rx_stat_ifhcinbadoctets_lo;
@@ -651,19 +700,20 @@ struct bnx2x_eth_stats {
 	u32 tx_stat_bmac_ufl_hi;
 	u32 tx_stat_bmac_ufl_lo;
 
-	u32 brb_drop_hi;
-	u32 brb_drop_lo;
-	u32 brb_truncate_hi;
-	u32 brb_truncate_lo;
-
-	u32 jabber_packets_received;
+	u32 pause_frames_received_hi;
+	u32 pause_frames_received_lo;
+	u32 pause_frames_sent_hi;
+	u32 pause_frames_sent_lo;
 
 	u32 etherstatspkts1024octetsto1522octets_hi;
 	u32 etherstatspkts1024octetsto1522octets_lo;
 	u32 etherstatspktsover1522octets_hi;
 	u32 etherstatspktsover1522octets_lo;
 
-	u32 no_buff_discard;
+	u32 brb_drop_hi;
+	u32 brb_drop_lo;
+	u32 brb_truncate_hi;
+	u32 brb_truncate_lo;
 
 	u32 mac_filter_discard;
 	u32 xxoverflow_discard;
@@ -674,17 +724,16 @@ struct bnx2x_eth_stats {
 	u32 rx_err_discard_pkt;
 	u32 rx_skb_alloc_failed;
 	u32 hw_csum_err;
+
+	u32 nig_timer_max;
 };
 
+#define BNX2X_NUM_STATS			41
 #define STATS_OFFSET32(stat_name) \
 			(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
 
 
-#ifdef BNX2X_MULTI
 #define MAX_CONTEXT			16
-#else
-#define MAX_CONTEXT			1
-#endif
 
 union cdu_context {
 	struct eth_context eth;
@@ -739,6 +788,9 @@ struct bnx2x {
 
 	atomic_t		intr_sem;
 	struct msix_entry	msix_table[MAX_CONTEXT+1];
+#define INT_MODE_INTx			1
+#define INT_MODE_MSI			2
+#define INT_MODE_MSIX			3
 
 	int			tx_ring_size;
 
@@ -747,23 +799,26 @@ struct bnx2x {
 #endif
 
 	u32			rx_csum;
-	u32			rx_offset;
 	u32			rx_buf_size;
 #define ETH_OVREHEAD			(ETH_HLEN + 8)	/* 8 for CRC + VLAN */
 #define ETH_MIN_PACKET_SIZE		60
 #define ETH_MAX_PACKET_SIZE		1500
 #define ETH_MAX_JUMBO_PACKET_SIZE	9600
 
+	/* Max supported alignment is 256 (8 shift) */
+#define BNX2X_RX_ALIGN_SHIFT		((L1_CACHE_SHIFT < 8) ? \
+					 L1_CACHE_SHIFT : 8)
+#define BNX2X_RX_ALIGN			(1 << BNX2X_RX_ALIGN_SHIFT)
+
 	struct host_def_status_block *def_status_blk;
 #define DEF_SB_ID			16
-	u16			def_c_idx;
-	u16			def_u_idx;
-	u16			def_x_idx;
-	u16			def_t_idx;
-	u16			def_att_idx;
+	__le16			def_c_idx;
+	__le16			def_u_idx;
+	__le16			def_x_idx;
+	__le16			def_t_idx;
+	__le16			def_att_idx;
 	u32			attn_state;
 	struct attn_route	attn_group[MAX_DYNAMIC_ATTN_GRPS];
-	u32			nig_mask;
 
 	/* slow path ring */
 	struct eth_spe		*spq;
@@ -771,7 +826,7 @@ struct bnx2x {
 	u16			spq_prod_idx;
 	struct eth_spe		*spq_prod_bd;
 	struct eth_spe		*spq_last_bd;
-	u16			*dsb_sp_prod;
+	__le16			*dsb_sp_prod;
 	u16			spq_left; /* serialize spq */
 	/* used to synchronize spq accesses */
 	spinlock_t		spq_lock;
@@ -789,11 +844,11 @@ struct bnx2x {
 	u32			flags;
 #define PCIX_FLAG			1
 #define PCI_32BIT_FLAG			2
-#define ONE_TDMA_FLAG			4	/* no longer used */
+#define ONE_PORT_FLAG			4
 #define NO_WOL_FLAG			8
 #define USING_DAC_FLAG			0x10
 #define USING_MSIX_FLAG			0x20
-#define ASF_ENABLE_FLAG			0x40
+#define USING_MSI_FLAG			0x40
 #define TPA_ENABLE_FLAG			0x80
 #define NO_MCP_FLAG			0x100
 #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
@@ -808,12 +863,12 @@ struct bnx2x {
 
 	int			pm_cap;
 	int			pcie_cap;
+	int			mrrs;
 
 	struct delayed_work	sp_task;
 	struct work_struct	reset_task;
 
 	struct timer_list	timer;
-	int			timer_interval;
 	int			current_interval;
 
 	u16			fw_seq;
@@ -826,6 +881,9 @@ struct bnx2x {
 	struct bnx2x_common	common;
 	struct bnx2x_port	port;
 
+	struct cmng_struct_per_port cmng;
+	u32			vn_weight_sum;
+
 	u32			mf_config;
 	u16			e1hov;
 	u8			e1hmf;
@@ -848,7 +906,7 @@ struct bnx2x {
 	u32			lin_cnt;
 
 	int			state;
-#define BNX2X_STATE_CLOSED		0x0
+#define BNX2X_STATE_CLOSED		0
 #define BNX2X_STATE_OPENING_WAIT4_LOAD	0x1000
 #define BNX2X_STATE_OPENING_WAIT4_PORT	0x2000
 #define BNX2X_STATE_OPEN		0x3000
@@ -859,8 +917,9 @@ struct bnx2x {
 #define BNX2X_STATE_DIAG		0xe000
 #define BNX2X_STATE_ERROR		0xf000
 
-	int			num_queues;
-#define BP_MAX_QUEUES(bp)		(IS_E1HMF(bp) ? 4 : 16)
+	int			multi_mode;
+	int			num_rx_queues;
+	int			num_tx_queues;
 
 	u32			rx_mode;
 #define BNX2X_RX_MODE_NONE		0
@@ -898,8 +957,6 @@ struct bnx2x {
 	int			executer_idx;
 
 	u16			stats_counter;
-	struct tstorm_per_client_stats old_tclient;
-	struct xstorm_per_client_stats old_xclient;
 	struct bnx2x_eth_stats	eth_stats;
 
 	struct z_stream_s	*strm;
@@ -911,17 +968,27 @@ struct bnx2x {
 };
 
 
-#define for_each_queue(bp, var)	for (var = 0; var < bp->num_queues; var++)
+#define BNX2X_MAX_QUEUES(bp)	(IS_E1HMF(bp) ? (MAX_CONTEXT / E1HVN_MAX) : \
+						 MAX_CONTEXT)
+#define BNX2X_NUM_QUEUES(bp)	max(bp->num_rx_queues, bp->num_tx_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 = 0; var < bp->num_tx_queues; 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_queues; var++)
-#define is_multi(bp)		(bp->num_queues > 1)
+			for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
 
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
 void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 		      u32 len32);
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
 int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
 
 static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 			   int wait)
@@ -992,13 +1059,12 @@ static inline u32 reg_poll(struct bnx2x
 #define PCICFG_LINK_SPEED_SHIFT		16
 
 
-#define BNX2X_NUM_STATS			42
-#define BNX2X_NUM_TESTS			8
+#define BNX2X_NUM_TESTS			7
 
-#define BNX2X_MAC_LOOPBACK		0
-#define BNX2X_PHY_LOOPBACK		1
-#define BNX2X_MAC_LOOPBACK_FAILED	1
-#define BNX2X_PHY_LOOPBACK_FAILED	2
+#define BNX2X_PHY_LOOPBACK		0
+#define BNX2X_MAC_LOOPBACK		1
+#define BNX2X_PHY_LOOPBACK_FAILED	1
+#define BNX2X_MAC_LOOPBACK_FAILED	2
 #define BNX2X_LOOPBACK_FAILED		(BNX2X_MAC_LOOPBACK_FAILED | \
 					 BNX2X_PHY_LOOPBACK_FAILED)
 
@@ -1061,9 +1127,6 @@ static inline u32 reg_poll(struct bnx2x
 #define BNX2X_MCP_ASSERT \
 	GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
 
-#define BNX2X_DOORQ_ASSERT \
-	AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
-
 #define BNX2X_GRC_TIMEOUT	GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
 #define BNX2X_GRC_RSV		(GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
 				 GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
@@ -1120,12 +1183,13 @@ static inline u32 reg_poll(struct bnx2x
 				 AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
 
 
-#define MULTI_FLAGS \
+#define MULTI_FLAGS(bp) \
 		(TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
 		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
 		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
 		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
-		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
+		 (bp->multi_mode << \
+		  TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT))
 
 #define MULTI_MASK			0x7f
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_hsi.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_hsi.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 18:02:45.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_hsi.h	2013-05-03 16:46:37.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_hsi.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -119,35 +119,15 @@ struct shared_hw_cfg {					 /* NVRAM Off
 #define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000
 
 	u32 board;						/* 0x124 */
-#define SHARED_HW_CFG_BOARD_TYPE_MASK		    0x0000ffff
-#define SHARED_HW_CFG_BOARD_TYPE_SHIFT		    0
-#define SHARED_HW_CFG_BOARD_TYPE_NONE		    0x00000000
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000     0x00000001
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001     0x00000002
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G    0x00000003
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G    0x00000004
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G    0x00000005
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G    0x00000006
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G    0x00000007
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G    0x00000008
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G    0x00000009
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G    0x0000000a
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1023G    0x0000000b
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1033G    0x0000000c
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711T1101     0x0000000d
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711ET1201    0x0000000e
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711A1133G    0x0000000f
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711EA1233G   0x00000010
-
-#define SHARED_HW_CFG_BOARD_VER_MASK		    0xffff0000
-#define SHARED_HW_CFG_BOARD_VER_SHIFT		    16
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK	    0xf0000000
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT	    28
-#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK	    0x0f000000
-#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT	    24
-#define SHARED_HW_CFG_BOARD_REV_MASK		    0x00ff0000
+#define SHARED_HW_CFG_BOARD_REV_MASK		    0x00FF0000
 #define SHARED_HW_CFG_BOARD_REV_SHIFT		    16
 
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK	    0x0F000000
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT	    24
+
+#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK	    0xF0000000
+#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT	    28
+
 	u32 reserved;						/* 0x128 */
 
 };
@@ -198,36 +178,21 @@ struct port_hw_cfg {			    /* port 0: 0x
 	u32 rdma_mac_lower;
 
 	u32 serdes_config;
-	/* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT  16
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK	      0x0000FFFF
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT	      0
 
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK    0x0000ffff
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT   0
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK	      0xFFFF0000
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT	      16
 
-	u16 serdes_tx_driver_pre_emphasis[16];
-	u16 serdes_rx_driver_equalizer[16];
 
-	u32 xgxs_config_lane0;
-	u32 xgxs_config_lane1;
-	u32 xgxs_config_lane2;
-	u32 xgxs_config_lane3;
-	/* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK   0xffff0000
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT  16
+	u32 Reserved0[16];				    /* 0x158 */
 
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK	    0x0000ffff
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT     0
+	/*  for external PHY, or forced mode or during AN */
+	u16 xgxs_config_rx[4];				    /* 0x198 */
 
-	u16 xgxs_tx_driver_pre_emphasis_lane0[16];
-	u16 xgxs_tx_driver_pre_emphasis_lane1[16];
-	u16 xgxs_tx_driver_pre_emphasis_lane2[16];
-	u16 xgxs_tx_driver_pre_emphasis_lane3[16];
+	u16 xgxs_config_tx[4];				    /* 0x1A0 */
 
-	u16 xgxs_rx_driver_equalizer_lane0[16];
-	u16 xgxs_rx_driver_equalizer_lane1[16];
-	u16 xgxs_rx_driver_equalizer_lane2[16];
-	u16 xgxs_rx_driver_equalizer_lane3[16];
+	u32 Reserved1[64];				    /* 0x1A8 */
 
 	u32 lane_config;
 #define PORT_HW_CFG_LANE_SWAP_CFG_MASK		    0x0000ffff
@@ -265,7 +230,7 @@ struct port_hw_cfg {			    /* port 0: 0x
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073	    0x00000300
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705	    0x00000400
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706	    0x00000500
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276	    0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726	    0x00000600
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481	    0x00000700
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101	    0x00000800
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE	    0x0000fd00
@@ -319,6 +284,12 @@ struct shared_feat_cfg {				 /* NVRAM Of
 
 	u32 config;						/* 0x450 */
 #define SHARED_FEATURE_BMC_ECHO_MODE_EN 	    0x00000001
+
+	/*  Use the values from options 47 and 48 instead of the HW default
+	  values */
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED     0x00000000
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED      0x00000002
+
 #define SHARED_FEATURE_MF_MODE_DISABLED 	    0x00000100
 
 };
@@ -372,6 +343,11 @@ struct port_feat_cfg {			    /* port 0:
 #define PORT_FEATURE_MBA_ENABLED		    0x02000000
 #define PORT_FEATURE_MFW_ENABLED		    0x04000000
 
+	/*  Check the optic vendor via i2c before allowing it to be used by
+	  SW */
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 	      0x00000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED		      0x08000000
+
 	u32 wol_config;
 	/* Default is used when driver sets to "auto" mode */
 #define PORT_FEATURE_WOL_DEFAULT_MASK		    0x00000003
@@ -512,7 +488,7 @@ struct port_feat_cfg {			    /* port 0:
 /****************************************************************************
  * Device Information							    *
  ****************************************************************************/
-struct dev_info {						    /* size */
+struct shm_dev_info {						    /* size */
 
 	u32    bc_rev; /* 8 bits each: major, minor, build */	       /* 4 */
 
@@ -641,7 +617,10 @@ struct drv_port_mb {
 
 	u32 port_stx;
 
-	u32 reserved[2];
+	u32 stat_nig_timer;
+
+	/* MCP firmware does not use this field */
+	u32 ext_phy_fw_version;
 
 };
 
@@ -827,11 +806,7 @@ struct mf_cfg {
 
 	struct shared_mf_cfg	shared_mf_config;
 	struct port_mf_cfg	port_mf_config[PORT_MAX];
-#if defined(b710)
-	struct func_mf_cfg	func_mf_config[E1_FUNC_MAX];
-#else
 	struct func_mf_cfg	func_mf_config[E1H_FUNC_MAX];
-#endif
 
 };
 
@@ -862,7 +837,7 @@ struct shmem_region {			       /*   Shar
 #define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE	    0x000001c0
 #define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK	    0x000001c0
 
-	struct dev_info 	dev_info;		 /* 0x8     (0x438) */
+	struct shm_dev_info	dev_info;		 /* 0x8     (0x438) */
 
 	u8			reserved[52*PORT_MAX];
 
@@ -1218,18 +1193,12 @@ struct host_func_stats {
  * attention bits
  */
 struct atten_def_status_block {
-	u32 attn_bits;
-	u32 attn_bits_ack;
-#if defined(__BIG_ENDIAN)
-	u16 attn_bits_index;
-	u8 reserved0;
-	u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
+	__le32 attn_bits;
+	__le32 attn_bits_ack;
 	u8 status_block_id;
 	u8 reserved0;
-	u16 attn_bits_index;
-#endif
-	u32 reserved1;
+	__le16 attn_bits_index;
+	__le32 reserved1;
 };
 
 
@@ -1302,7 +1271,7 @@ struct igu_ack_register {
  * Parser parsing flags field
  */
 struct parsing_flags {
-	u16 flags;
+	__le16 flags;
 #define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
 #define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
 #define PARSING_FLAGS_VLAN (0x1<<1)
@@ -1333,8 +1302,8 @@ struct parsing_flags {
 
 
 struct regpair {
-	u32 lo;
-	u32 hi;
+	__le32 lo;
+	__le32 hi;
 };
 
 
@@ -1431,8 +1400,10 @@ struct ustorm_eth_st_context_config {
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
 	u8 status_block_id;
 	u8 clientId;
 	u8 sb_index_numbers;
@@ -1457,14 +1428,18 @@ struct ustorm_eth_st_context_config {
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
 #endif
 #if defined(__BIG_ENDIAN)
 	u16 bd_buff_size;
-	u16 mc_alignment_size;
+	u8 statistics_counter_id;
+	u8 mc_alignment_log_size;
 #elif defined(__LITTLE_ENDIAN)
-	u16 mc_alignment_size;
+	u8 mc_alignment_log_size;
+	u8 statistics_counter_id;
 	u16 bd_buff_size;
 #endif
 #if defined(__BIG_ENDIAN)
@@ -1476,13 +1451,7 @@ struct ustorm_eth_st_context_config {
 	u8 __local_bd_prod;
 	u8 __local_sge_prod;
 #endif
-#if defined(__BIG_ENDIAN)
-	u16 __bd_cons;
-	u16 __sge_cons;
-#elif defined(__LITTLE_ENDIAN)
-	u16 __sge_cons;
-	u16 __bd_cons;
-#endif
+	u32 reserved;
 	u32 bd_page_base_lo;
 	u32 bd_page_base_hi;
 	u32 sge_page_base_lo;
@@ -1493,16 +1462,16 @@ struct ustorm_eth_st_context_config {
  * The eth Rx Buffer Descriptor
  */
 struct eth_rx_bd {
-	u32 addr_lo;
-	u32 addr_hi;
+	__le32 addr_lo;
+	__le32 addr_hi;
 };
 
 /*
  * The eth Rx SGE Descriptor
  */
 struct eth_rx_sge {
-	u32 addr_lo;
-	u32 addr_hi;
+	__le32 addr_lo;
+	__le32 addr_hi;
 };
 
 /*
@@ -1694,7 +1663,7 @@ struct xstorm_eth_ag_context {
 };
 
 /*
- * The eth aggregative context section of Tstorm
+ * The eth extra aggregative context section of Tstorm
  */
 struct tstorm_eth_extra_ag_context_section {
 	u32 __agg_val1;
@@ -1905,11 +1874,11 @@ struct eth_tx_bd_flags {
  * The eth Tx Buffer Descriptor
  */
 struct eth_tx_bd {
-	u32 addr_lo;
-	u32 addr_hi;
-	u16 nbd;
-	u16 nbytes;
-	u16 vlan;
+	__le32 addr_lo;
+	__le32 addr_hi;
+	__le16 nbd;
+	__le16 nbytes;
+	__le16 vlan;
 	struct eth_tx_bd_flags bd_flags;
 	u8 general_data;
 #define ETH_TX_BD_HDR_NBDS (0x3F<<0)
@@ -1952,11 +1921,11 @@ struct eth_tx_parse_bd {
 #define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
 	u8 ip_hlen;
 	s8 cs_offset;
-	u16 total_hlen;
-	u16 lso_mss;
-	u16 tcp_pseudo_csum;
-	u16 ip_id;
-	u32 tcp_send_seq;
+	__le16 total_hlen;
+	__le16 lso_mss;
+	__le16 tcp_pseudo_csum;
+	__le16 ip_id;
+	__le32 tcp_send_seq;
 };
 
 /*
@@ -2072,44 +2041,44 @@ struct eth_tx_doorbell {
  * ustorm status block
  */
 struct ustorm_def_status_block {
-	u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
  * cstorm status block
  */
 struct cstorm_def_status_block {
-	u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
  * xstorm status block
  */
 struct xstorm_def_status_block {
-	u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
  * tstorm status block
  */
 struct tstorm_def_status_block {
-	u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
@@ -2128,22 +2097,22 @@ struct host_def_status_block {
  * ustorm status block
  */
 struct ustorm_status_block {
-	u16 index_values[HC_USTORM_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_USTORM_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
  * cstorm status block
  */
 struct cstorm_status_block {
-	u16 index_values[HC_CSTORM_SB_NUM_INDICES];
-	u16 status_block_index;
+	__le16 index_values[HC_CSTORM_SB_NUM_INDICES];
+	__le16 status_block_index;
 	u8 func;
 	u8 status_block_id;
-	u32 __flags;
+	__le32 __flags;
 };
 
 /*
@@ -2159,9 +2128,9 @@ struct host_status_block {
  * The data for RSS setup ramrod
  */
 struct eth_client_setup_ramrod_data {
-	u32 client_id_5b;
-	u8 is_rdma_1b;
-	u8 reserved0;
+	u32 client_id;
+	u8 is_rdma;
+	u8 is_fcoe;
 	u16 reserved1;
 };
 
@@ -2209,12 +2178,12 @@ struct eth_fast_path_rx_cqe {
 #define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
 	u8 placement_offset;
 	u8 queue_index;
-	u32 rss_hash_result;
-	u16 vlan_tag;
-	u16 pkt_len;
-	u16 len_on_bd;
+	__le32 rss_hash_result;
+	__le16 vlan_tag;
+	__le16 pkt_len;
+	__le16 len_on_bd;
 	struct parsing_flags pars_flags;
-	u16 sgl[8];
+	__le16 sgl[8];
 };
 
 
@@ -2222,7 +2191,7 @@ struct eth_fast_path_rx_cqe {
  * The data for RSS setup ramrod
  */
 struct eth_halt_ramrod_data {
-	u32 client_id_5b;
+	u32 client_id;
 	u32 reserved0;
 };
 
@@ -2233,11 +2202,11 @@ struct eth_halt_ramrod_data {
 struct eth_query_ramrod_data {
 #if defined(__BIG_ENDIAN)
 	u8 reserved0;
-	u8 collect_port_1b;
+	u8 collect_port;
 	u16 drv_counter;
 #elif defined(__LITTLE_ENDIAN)
 	u16 drv_counter;
-	u8 collect_port_1b;
+	u8 collect_port;
 	u8 reserved0;
 #endif
 	u32 ctr_id_vector;
@@ -2248,8 +2217,8 @@ struct eth_query_ramrod_data {
  * Place holder for ramrods protocol specific data
  */
 struct ramrod_data {
-	u32 data_lo;
-	u32 data_hi;
+	__le32 data_lo;
+	__le32 data_hi;
 };
 
 /*
@@ -2261,16 +2230,6 @@ union eth_ramrod_data {
 
 
 /*
- * Rx Last BD in page (in ETH)
- */
-struct eth_rx_bd_next_page {
-	u32 addr_lo;
-	u32 addr_hi;
-	u8 reserved[8];
-};
-
-
-/*
  * Eth Rx Cqe structure- general structure for ramrods
  */
 struct common_ramrod_eth_rx_cqe {
@@ -2279,24 +2238,24 @@ struct common_ramrod_eth_rx_cqe {
 #define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0
 #define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1)
 #define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1
-	u8 conn_type_3b;
-	u16 reserved1;
-	u32 conn_and_cmd_data;
+	u8 conn_type;
+	__le16 reserved1;
+	__le32 conn_and_cmd_data;
 #define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
 #define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
 #define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
 #define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
 	struct ramrod_data protocol_data;
-	u32 reserved2[4];
+	__le32 reserved2[4];
 };
 
 /*
  * Rx Last CQE in page (in ETH)
  */
 struct eth_rx_cqe_next_page {
-	u32 addr_lo;
-	u32 addr_hi;
-	u32 reserved[6];
+	__le32 addr_lo;
+	__le32 addr_hi;
+	__le32 reserved[6];
 };
 
 /*
@@ -2313,17 +2272,17 @@ union eth_rx_cqe {
  * common data for all protocols
  */
 struct spe_hdr {
-	u32 conn_and_cmd_data;
+	__le32 conn_and_cmd_data;
 #define SPE_HDR_CID (0xFFFFFF<<0)
 #define SPE_HDR_CID_SHIFT 0
 #define SPE_HDR_CMD_ID (0xFF<<24)
 #define SPE_HDR_CMD_ID_SHIFT 24
-	u16 type;
+	__le16 type;
 #define SPE_HDR_CONN_TYPE (0xFF<<0)
 #define SPE_HDR_CONN_TYPE_SHIFT 0
 #define SPE_HDR_COMMON_RAMROD (0xFF<<8)
 #define SPE_HDR_COMMON_RAMROD_SHIFT 8
-	u16 reserved;
+	__le16 reserved;
 };
 
 /*
@@ -2352,9 +2311,9 @@ struct eth_spe {
  * doorbell data in host memory
  */
 struct eth_tx_db_data {
-	u32 packets_prod;
-	u16 bds_prod;
-	u16 reserved;
+	__le32 packets_prod;
+	__le16 bds_prod;
+	__le16 reserved;
 };
 
 
@@ -2374,14 +2333,16 @@ struct tstorm_eth_function_common_config
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
 #elif defined(__LITTLE_ENDIAN)
 	u16 config_flags;
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2392,14 +2353,16 @@ struct tstorm_eth_function_common_config
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
 	u8 rss_result_mask;
 	u8 leading_client_id;
 #endif
@@ -2419,7 +2382,7 @@ struct eth_update_ramrod_data {
  * MAC filtering configuration command header
  */
 struct mac_configuration_hdr {
-	u8 length_6b;
+	u8 length;
 	u8 offset;
 	u16 client_id;
 	u32 reserved1;
@@ -2429,10 +2392,10 @@ struct mac_configuration_hdr {
  * MAC address in list for ramrod
  */
 struct tstorm_cam_entry {
-	u16 lsb_mac_addr;
-	u16 middle_mac_addr;
-	u16 msb_mac_addr;
-	u16 flags;
+	__le16 lsb_mac_addr;
+	__le16 middle_mac_addr;
+	__le16 msb_mac_addr;
+	__le16 flags;
 #define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
 #define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
 #define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
@@ -2481,11 +2444,11 @@ struct mac_configuration_cmd {
  * MAC address in list for ramrod
  */
 struct mac_configuration_entry_e1h {
-	u16 lsb_mac_addr;
-	u16 middle_mac_addr;
-	u16 msb_mac_addr;
-	u16 vlan_id;
-	u16 e1hov_id;
+	__le16 lsb_mac_addr;
+	__le16 middle_mac_addr;
+	__le16 msb_mac_addr;
+	__le16 vlan_id;
+	__le16 e1hov_id;
 	u8 client_id;
 	u8 flags;
 #define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
@@ -2541,24 +2504,28 @@ struct tstorm_eth_client_config {
 #define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
 #define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
 	u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
 #elif defined(__LITTLE_ENDIAN)
 	u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
 	u16 drop_flags;
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
@@ -2591,9 +2558,61 @@ struct tstorm_eth_mac_filter_config {
 
 
 /*
+ * common flag to indicate existance of TPA.
+ */
+struct tstorm_eth_tpa_exist {
+#if defined(__BIG_ENDIAN)
+	u16 reserved1;
+	u8 reserved0;
+	u8 tpa_exist;
+#elif defined(__LITTLE_ENDIAN)
+	u8 tpa_exist;
+	u8 reserved0;
+	u16 reserved1;
+#endif
+	u32 reserved2;
+};
+
+
+/*
+ * rx rings pause data for E1h only
+ */
+struct ustorm_eth_rx_pause_data_e1h {
+#if defined(__BIG_ENDIAN)
+	u16 bd_thr_low;
+	u16 cqe_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+	u16 cqe_thr_low;
+	u16 bd_thr_low;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 cos;
+	u16 sge_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+	u16 sge_thr_low;
+	u16 cos;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 bd_thr_high;
+	u16 cqe_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+	u16 cqe_thr_high;
+	u16 bd_thr_high;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 reserved0;
+	u16 sge_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+	u16 sge_thr_high;
+	u16 reserved0;
+#endif
+};
+
+
+/*
  * Three RX producers for ETH
  */
-struct tstorm_eth_rx_producers {
+struct ustorm_eth_rx_producers {
 #if defined(__BIG_ENDIAN)
 	u16 bd_prod;
 	u16 cqe_prod;
@@ -2612,38 +2631,23 @@ struct tstorm_eth_rx_producers {
 
 
 /*
- * common flag to indicate existence of TPA.
- */
-struct tstorm_eth_tpa_exist {
-#if defined(__BIG_ENDIAN)
-	u16 reserved1;
-	u8 reserved0;
-	u8 tpa_exist;
-#elif defined(__LITTLE_ENDIAN)
-	u8 tpa_exist;
-	u8 reserved0;
-	u16 reserved1;
-#endif
-	u32 reserved2;
-};
-
-
-/*
  * per-port SAFC demo variables
  */
 struct cmng_flags_per_port {
 	u8 con_number[NUM_OF_PROTOCOLS];
-#if defined(__BIG_ENDIAN)
-	u8 fairness_enable;
-	u8 rate_shaping_enable;
-	u8 cmng_protocol_enable;
-	u8 cmng_vn_enable;
-#elif defined(__LITTLE_ENDIAN)
-	u8 cmng_vn_enable;
-	u8 cmng_protocol_enable;
-	u8 rate_shaping_enable;
-	u8 fairness_enable;
-#endif
+	u32 cmng_enables;
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN (0x1<<0)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN_SHIFT 0
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN (0x1<<1)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN_SHIFT 1
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL (0x1<<2)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL_SHIFT 2
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL (0x1<<3)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4
+#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5)
+#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5
 };
 
 
@@ -2671,15 +2675,15 @@ struct fairness_vars_per_port {
  */
 struct safc_struct_per_port {
 #if defined(__BIG_ENDIAN)
-	u16 __reserved0;
-	u8 cur_cos_types;
+	u16 __reserved1;
+	u8 __reserved0;
 	u8 safc_timeout_usec;
 #elif defined(__LITTLE_ENDIAN)
 	u8 safc_timeout_usec;
-	u8 cur_cos_types;
-	u16 __reserved0;
+	u8 __reserved0;
+	u16 __reserved1;
 #endif
-	u8 cos_to_protocol[MAX_COS_NUMBER];
+	u16 cos_to_pause_mask[NUM_OF_SAFC_BITS];
 };
 
 
@@ -2699,16 +2703,16 @@ struct cmng_struct_per_port {
  */
 struct xstorm_per_client_stats {
 	struct regpair total_sent_bytes;
-	u32 total_sent_pkts;
-	u32 unicast_pkts_sent;
+	__le32 total_sent_pkts;
+	__le32 unicast_pkts_sent;
 	struct regpair unicast_bytes_sent;
 	struct regpair multicast_bytes_sent;
-	u32 multicast_pkts_sent;
-	u32 broadcast_pkts_sent;
+	__le32 multicast_pkts_sent;
+	__le32 broadcast_pkts_sent;
 	struct regpair broadcast_bytes_sent;
-	u16 stats_counter;
-	u16 reserved0;
-	u32 reserved1;
+	__le16 stats_counter;
+	__le16 reserved0;
+	__le32 reserved1;
 };
 
 
@@ -2724,10 +2728,10 @@ struct xstorm_common_stats {
  * Protocol-common statistics collected by the Tstorm (per port)
  */
 struct tstorm_per_port_stats {
-	u32 mac_filter_discard;
-	u32 xxoverflow_discard;
-	u32 brb_truncate_discard;
-	u32 mac_discard;
+	__le32 mac_filter_discard;
+	__le32 xxoverflow_discard;
+	__le32 brb_truncate_discard;
+	__le32 mac_discard;
 };
 
 
@@ -2740,17 +2744,17 @@ struct tstorm_per_client_stats {
 	struct regpair rcv_broadcast_bytes;
 	struct regpair rcv_multicast_bytes;
 	struct regpair rcv_error_bytes;
-	u32 checksum_discard;
-	u32 packets_too_big_discard;
-	u32 total_rcv_pkts;
-	u32 rcv_unicast_pkts;
-	u32 rcv_broadcast_pkts;
-	u32 rcv_multicast_pkts;
-	u32 no_buff_discard;
-	u32 ttl0_discard;
-	u16 stats_counter;
-	u16 reserved0;
-	u32 reserved1;
+	__le32 checksum_discard;
+	__le32 packets_too_big_discard;
+	__le32 total_rcv_pkts;
+	__le32 rcv_unicast_pkts;
+	__le32 rcv_broadcast_pkts;
+	__le32 rcv_multicast_pkts;
+	__le32 no_buff_discard;
+	__le32 ttl0_discard;
+	__le16 stats_counter;
+	__le16 reserved0;
+	__le32 reserved1;
 };
 
 /*
@@ -2762,11 +2766,33 @@ struct tstorm_common_stats {
 };
 
 /*
+ * Protocol-common statistics collected by the Ustorm (per client)
+ */
+struct ustorm_per_client_stats {
+	struct regpair ucast_no_buff_bytes;
+	struct regpair mcast_no_buff_bytes;
+	struct regpair bcast_no_buff_bytes;
+	__le32 ucast_no_buff_pkts;
+	__le32 mcast_no_buff_pkts;
+	__le32 bcast_no_buff_pkts;
+	__le16 stats_counter;
+	__le16 reserved0;
+};
+
+/*
+ * Protocol-common statistics collected by the Ustorm
+ */
+struct ustorm_common_stats {
+ struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID];
+};
+
+/*
  * Eth statistics query structure for the eth_stats_query ramrod
  */
 struct eth_stats_query {
 	struct xstorm_common_stats xstorm_common;
 	struct tstorm_common_stats tstorm_common;
+	struct ustorm_common_stats ustorm_common;
 };
 
 
@@ -2774,6 +2800,7 @@ struct eth_stats_query {
  * per-vnic fairness variables
  */
 struct fairness_vars_per_vn {
+	u32 cos_credit_delta[MAX_COS_NUMBER];
 	u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
 	u32 vn_credit_delta;
 	u32 __reserved0;
@@ -2785,13 +2812,15 @@ struct fairness_vars_per_vn {
  */
 struct fw_version {
 #if defined(__BIG_ENDIAN)
-	u16 patch;
-	u8 primary;
-	u8 client;
+	u8 engineering;
+	u8 revision;
+	u8 minor;
+	u8 major;
 #elif defined(__LITTLE_ENDIAN)
-	u8 client;
-	u8 primary;
-	u16 patch;
+	u8 major;
+	u8 minor;
+	u8 revision;
+	u8 engineering;
 #endif
 	u32 flags;
 #define FW_VERSION_OPTIMIZED (0x1<<0)
@@ -2809,9 +2838,10 @@ struct fw_version {
  * FW version stored in first line of pram
  */
 struct pram_fw_version {
-	u8 client;
-	u8 primary;
-	u16 patch;
+	u8 major;
+	u8 minor;
+	u8 revision;
+	u8 engineering;
 	u8 flags;
 #define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
 #define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_init.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_init.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_init.h	2013-05-03 18:02:42.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_init.h	2013-05-03 16:46:34.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_init.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,12 +22,15 @@
 #define INIT_ASIC			0x4
 #define INIT_HARDWARE			0x7
 
-#define STORM_INTMEM_SIZE_E1		(0x5800 / 4)
-#define STORM_INTMEM_SIZE_E1H		(0x10000 / 4)
-#define TSTORM_INTMEM_ADDR		0x1a0000
-#define CSTORM_INTMEM_ADDR		0x220000
-#define XSTORM_INTMEM_ADDR		0x2a0000
-#define USTORM_INTMEM_ADDR		0x320000
+#define TSTORM_INTMEM_ADDR		TSEM_REG_FAST_MEMORY
+#define CSTORM_INTMEM_ADDR		CSEM_REG_FAST_MEMORY
+#define XSTORM_INTMEM_ADDR		XSEM_REG_FAST_MEMORY
+#define USTORM_INTMEM_ADDR		USEM_REG_FAST_MEMORY
+/* RAM0 size in bytes */
+#define STORM_INTMEM_SIZE_E1		0x5800
+#define STORM_INTMEM_SIZE_E1H		0x10000
+#define STORM_INTMEM_SIZE(bp)	((CHIP_IS_E1H(bp) ? STORM_INTMEM_SIZE_E1H : \
+						    STORM_INTMEM_SIZE_E1) / 4)
 
 
 /* Init operation types and structures */
@@ -167,21 +170,24 @@ static void bnx2x_write_big_buf(struct b
 
 static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
 {
-	if ((len * 4) > FW_BUF_SIZE) {
-		BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x  len 0x%x\n",
-			  addr, len*4);
-		return;
-	}
-	memset(bp->gunzip_buf, fill, len * 4);
+	u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
+	u32 buf_len32 = buf_len / 4;
+	int i;
 
-	bnx2x_write_big_buf(bp, addr, len);
+	memset(bp->gunzip_buf, fill, buf_len);
+
+	for (i = 0; i < len; i += buf_len32) {
+		u32 cur_len = min(buf_len32, len - i);
+
+		bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+	}
 }
 
 static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
 			     u32 len64)
 {
-	u32 buf_len32 = FW_BUF_SIZE/4;
-	u32 len = len64*2;
+	u32 buf_len32 = FW_BUF_SIZE / 4;
+	u32 len = len64 * 2;
 	u64 data64 = 0;
 	int i;
 
@@ -245,57 +251,57 @@ struct arb_line {
 
 /* derived configuration for each read queue for each max request size */
 static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
-	{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
-	{{4 , 8 , 4},   {4 , 8 , 4},    {4 , 8 , 4},    {4 , 8 , 4} },
-	{{4 , 3 , 3},   {4 , 3 , 3},    {4 , 3 , 3},    {4 , 3 , 3} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {16 , 3 , 11},  {16 , 3 , 11} },
-	{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
-	{{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
+/* 1 */	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+	{ {4, 8,  4},  {4,  8,  4},  {4,  8,  4},  {4,  8,  4}  },
+	{ {4, 3,  3},  {4,  3,  3},  {4,  3,  3},  {4,  3,  3}  },
+	{ {8, 3,  6},  {16, 3,  11}, {16, 3,  11}, {16, 3,  11} },
+	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+/* 10 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+/* 20 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
 };
 
 /* derived configuration for each write queue for each max request size */
 static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
-	{{4 , 6 , 3},   {4 , 6 , 3},    {4 , 6 , 3} },
-	{{4 , 2 , 3},   {4 , 2 , 3},    {4 , 2 , 3} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
-	{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
-	{{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
-	{{8 , 9 , 6},   {16 , 9 , 11},  {32 , 9 , 21} },
-	{{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
-	{{8 , 9 , 6},   {16 , 9 , 11},  {16 , 9 , 11} },
-	{{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
+/* 1 */	{ {4, 6,  3},  {4,  6,  3},  {4,  6,  3} },
+	{ {4, 2,  3},  {4,  2,  3},  {4,  2,  3} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+/* 10 */{ {8, 9,  6},  {16, 9,  11}, {32, 9,  21} },
+	{ {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
+	{ {8, 9,  6},  {16, 9,  11}, {16, 9,  11} },
+	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
 };
 
 /* register addresses for read queues */
 static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
-	{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
+/* 1 */	{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
 		PXP2_REG_RQ_BW_RD_UBOUND0},
 	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
 		PXP2_REG_PSWRQ_BW_UB1},
@@ -313,7 +319,7 @@ static const struct arb_line read_arb_ad
 		PXP2_REG_PSWRQ_BW_UB7},
 	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
 		PXP2_REG_PSWRQ_BW_UB8},
-	{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
 		PXP2_REG_PSWRQ_BW_UB9},
 	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
 		PXP2_REG_PSWRQ_BW_UB10},
@@ -333,7 +339,7 @@ static const struct arb_line read_arb_ad
 		PXP2_REG_RQ_BW_RD_UBOUND17},
 	{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
 		PXP2_REG_RQ_BW_RD_UBOUND18},
-	{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
+/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
 		PXP2_REG_RQ_BW_RD_UBOUND19},
 	{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
 		PXP2_REG_RQ_BW_RD_UBOUND20},
@@ -355,7 +361,7 @@ static const struct arb_line read_arb_ad
 
 /* register addresses for write queues */
 static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
-	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+/* 1 */	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
 		PXP2_REG_PSWRQ_BW_UB1},
 	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
 		PXP2_REG_PSWRQ_BW_UB2},
@@ -373,7 +379,7 @@ static const struct arb_line write_arb_a
 		PXP2_REG_PSWRQ_BW_UB10},
 	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
 		PXP2_REG_PSWRQ_BW_UB11},
-	{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
 		PXP2_REG_PSWRQ_BW_UB28},
 	{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
 		PXP2_REG_RQ_BW_WR_UBOUND29},
@@ -391,7 +397,12 @@ static void bnx2x_init_pxp(struct bnx2x
 			     bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
 	DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
 	w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
-	r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+	if (bp->mrrs == -1)
+		r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+	else {
+		DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+		r_order = bp->mrrs;
+	}
 
 	if (r_order > MAX_RD_ORD) {
 		DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
@@ -466,17 +477,18 @@ static void bnx2x_init_pxp(struct bnx2x
 	REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
 
 	if (CHIP_IS_E1H(bp)) {
-		REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1);
-		REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1);
+		val = ((w_order == 0) ? 2 : 3);
+		REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
+		REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
 		REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
-		REG_WR(bp, PXP2_REG_WR_CDU_MPS, w_order+1);
+		REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_init_values.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_init_values.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_init_values.h	2013-05-03 18:02:40.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_init_values.h	2013-05-03 16:46:32.000000000 -0400
@@ -1,7 +1,23 @@
 #ifndef __BNX2X_INIT_VALUES_H__
 #define __BNX2X_INIT_VALUES_H__
 
-/* This array contains the list of operations needed to initialize the chip.
+/* bnx2x_init_values.h: Broadcom NX2 10G network driver.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, except as noted below.
+ *
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2007-2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ *
+ *
+ * This array contains the list of operations needed to initialize the chip.
  *
  * For each block in the chip there are three init stages:
  * common - HW used by both ports,
@@ -47,12 +63,16 @@ static const struct raw_op init_ops[] =
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
-	{OP_ZR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+	{OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+	{OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000},
+	{OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
 	{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
-	{OP_ZR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+	{OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+	{OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000},
+	{OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3},
 	{OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
 	{OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
 	{OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
@@ -71,15 +91,16 @@ static const struct raw_op init_ops[] =
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
-	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+	{OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+	{OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f},
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
 	{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END          47
-#define SRCH_COMMON_START       47
+#define PRS_COMMON_END          52
+#define SRCH_COMMON_START       52
 	{OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END         48
-#define TSDM_COMMON_START       48
+#define SRCH_COMMON_END         53
+#define TSDM_COMMON_START       53
 	{OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
 	{OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
 	{OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
@@ -92,10 +113,15 @@ static const struct raw_op init_ops[] =
 	{OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
 	{OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
 	{OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
-	{OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+	{OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+	{OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20},
+	{OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0},
 	{OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
 	{OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
-	{OP_ZR, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
+	{OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
+	{OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c},
+	{OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1},
+	{OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f},
 	{OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
 	{OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
 	{OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -118,8 +144,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
 	{OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
 	{OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END         86
-#define TCM_COMMON_START        86
+#define TSDM_COMMON_END         96
+#define TCM_COMMON_START        96
 	{OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
 	{OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
 	{OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
@@ -129,10 +155,16 @@ static const struct raw_op init_ops[] =
 	{OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
 	{OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
 	{OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
-	{OP_WR, TCM_REG_PRS_WEIGHT, 0x4},
-	{OP_WR, TCM_REG_PBF_WEIGHT, 0x5},
+	{OP_WR, TCM_REG_STORM_WEIGHT, 0x2},
+	{OP_WR, TCM_REG_PRS_WEIGHT, 0x5},
+	{OP_WR, TCM_REG_PBF_WEIGHT, 0x6},
+	{OP_WR, TCM_REG_USEM_WEIGHT, 0x2},
+	{OP_WR, TCM_REG_CSEM_WEIGHT, 0x2},
 	{OP_WR, TCM_REG_CP_WEIGHT, 0x0},
-	{OP_WR, TCM_REG_TSDM_WEIGHT, 0x4},
+	{OP_WR, TCM_REG_TSDM_WEIGHT, 0x5},
+	{OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2},
+	{OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2},
+	{OP_WR, TCM_REG_TM_WEIGHT, 0x2},
 	{OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
 	{OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
 	{OP_WR, TCM_REG_GR_LD0_PR, 0x1},
@@ -149,7 +181,9 @@ static const struct raw_op init_ops[] =
 	{OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
 	{OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
 	{OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
-	{OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4},
+	{OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4},
+	{OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1},
+	{OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3},
 	{OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
 	{OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
 	{OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
@@ -175,75 +209,75 @@ static const struct raw_op init_ops[] =
 	{OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
 	{OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
 	{OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END          141
-#define TCM_FUNC0_START         141
+#define TCM_COMMON_END          159
+#define TCM_FUNC0_START         159
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END           145
-#define TCM_FUNC1_START         145
+#define TCM_FUNC0_END           163
+#define TCM_FUNC1_START         163
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END           149
-#define TCM_FUNC2_START         149
+#define TCM_FUNC1_END           167
+#define TCM_FUNC2_START         167
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END           153
-#define TCM_FUNC3_START         153
+#define TCM_FUNC2_END           171
+#define TCM_FUNC3_START         171
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END           157
-#define TCM_FUNC4_START         157
+#define TCM_FUNC3_END           175
+#define TCM_FUNC4_START         175
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END           161
-#define TCM_FUNC5_START         161
+#define TCM_FUNC4_END           179
+#define TCM_FUNC5_START         179
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END           165
-#define TCM_FUNC6_START         165
+#define TCM_FUNC5_END           183
+#define TCM_FUNC6_START         183
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END           169
-#define TCM_FUNC7_START         169
+#define TCM_FUNC6_END           187
+#define TCM_FUNC7_START         187
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
 	{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END           173
-#define BRB1_COMMON_START       173
+#define TCM_FUNC7_END           191
+#define BRB1_COMMON_START       191
 	{OP_SW, BRB1_REG_LL_RAM, 0x2000020},
 	{OP_WR, BRB1_REG_SOFT_RESET, 0x1},
 	{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
 	{OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
 	{OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END         178
-#define BRB1_PORT0_START        178
+#define BRB1_COMMON_END         196
+#define BRB1_PORT0_START        196
 	{OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
 	{OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
 	{OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
 	{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END          182
-#define BRB1_PORT1_START        182
+#define BRB1_PORT0_END          200
+#define BRB1_PORT1_START        200
 	{OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
 	{OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
 	{OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
 	{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END          186
-#define TSEM_COMMON_START       186
+#define BRB1_PORT1_END          204
+#define TSEM_COMMON_START       204
 	{OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
 	{OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
 	{OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -303,143 +337,166 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2},
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3b28, 0x6},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2},
 	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
 	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
+	{OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
-	{OP_ZP_E1, TSEM_REG_INT_TABLE, 0x940000},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
 	{OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
+	{OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
-	{OP_ZP_E1, TSEM_REG_PRAM, 0x30b10000},
+	{OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
-	{OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33c50c2d},
+	{OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
-	{OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xbc6191f},
+	{OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
-	{OP_WR_64_E1, TSEM_REG_PRAM + 0x117f0, 0x5d020232},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x6140, 0x200224},
-	{OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x960000},
-	{OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x360, 0x140244},
-	{OP_ZP_E1H, TSEM_REG_PRAM, 0x30cc0000},
-	{OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x33df0c33},
-	{OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0xdce192b},
-	{OP_WR_64_E1H, TSEM_REG_PRAM + 0x11c70, 0x5c720246},
-#define TSEM_COMMON_END         276
-#define TSEM_PORT0_START        276
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224},
+	{OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000},
+	{OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244},
+	{OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000},
+	{OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98},
+	{OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe},
+	{OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246},
+#define TSEM_COMMON_END         297
+#define TSEM_PORT0_START        297
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0xfc},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
 	{OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0xfa},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
+	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0xbe},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
-	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20234},
+	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END          294
-#define TSEM_PORT1_START        294
+#define TSEM_PORT0_END          317
+#define TSEM_PORT1_START        317
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x43f0, 0xfc},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
 	{OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3738, 0xfa},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
+	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
-	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xcb8, 0xbe},
+	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
-	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20236},
+	{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
 	{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END          312
-#define TSEM_FUNC0_START        312
+#define TSEM_PORT1_END          337
+#define TSEM_FUNC0_START        337
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END          318
-#define TSEM_FUNC1_START        318
+#define TSEM_FUNC0_END          345
+#define TSEM_FUNC1_START        345
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END          324
-#define TSEM_FUNC2_START        324
+#define TSEM_FUNC1_END          353
+#define TSEM_FUNC2_START        353
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20248},
-#define TSEM_FUNC2_END          330
-#define TSEM_FUNC3_START        330
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257},
+#define TSEM_FUNC2_END          361
+#define TSEM_FUNC3_START        361
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2024a},
-#define TSEM_FUNC3_END          336
-#define TSEM_FUNC4_START        336
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e},
+#define TSEM_FUNC3_END          369
+#define TSEM_FUNC4_START        369
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x2024c},
-#define TSEM_FUNC4_END          342
-#define TSEM_FUNC5_START        342
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265},
+#define TSEM_FUNC4_END          377
+#define TSEM_FUNC5_START        377
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2024e},
-#define TSEM_FUNC5_END          348
-#define TSEM_FUNC6_START        348
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c},
+#define TSEM_FUNC5_END          385
+#define TSEM_FUNC6_START        385
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20250},
-#define TSEM_FUNC6_END          354
-#define TSEM_FUNC7_START        354
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273},
+#define TSEM_FUNC6_END          393
+#define TSEM_FUNC7_START        393
 	{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
-	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0xe},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2},
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275},
+	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
 	{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
-	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x20252},
-#define TSEM_FUNC7_END          360
-#define MISC_COMMON_START       360
+	{OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a},
+#define TSEM_FUNC7_END          401
+#define MISC_COMMON_START       401
 	{OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
 	{OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
 	{OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
@@ -447,39 +504,39 @@ static const struct raw_op init_ops[] =
 	{OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
 	{OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
 	{OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END         367
-#define MISC_FUNC0_START        367
+#define MISC_COMMON_END         408
+#define MISC_FUNC0_START        408
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END          368
-#define MISC_FUNC1_START        368
+#define MISC_FUNC0_END          409
+#define MISC_FUNC1_START        409
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END          369
-#define MISC_FUNC2_START        369
+#define MISC_FUNC1_END          410
+#define MISC_FUNC2_START        410
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END          370
-#define MISC_FUNC3_START        370
+#define MISC_FUNC2_END          411
+#define MISC_FUNC3_START        411
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END          371
-#define MISC_FUNC4_START        371
+#define MISC_FUNC3_END          412
+#define MISC_FUNC4_START        412
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END          372
-#define MISC_FUNC5_START        372
+#define MISC_FUNC4_END          413
+#define MISC_FUNC5_START        413
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END          373
-#define MISC_FUNC6_START        373
+#define MISC_FUNC5_END          414
+#define MISC_FUNC6_START        414
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END          374
-#define MISC_FUNC7_START        374
+#define MISC_FUNC6_END          415
+#define MISC_FUNC7_START        415
 	{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END          375
-#define NIG_COMMON_START        375
+#define MISC_FUNC7_END          416
+#define NIG_COMMON_START        416
 	{OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
 	{OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
 	{OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
 	{OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
 	{OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END          380
-#define NIG_PORT0_START         380
+#define NIG_COMMON_END          421
+#define NIG_PORT0_START         421
 	{OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
 	{OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
 	{OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
@@ -492,8 +549,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
 	{OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
 	{OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END           392
-#define NIG_PORT1_START         392
+#define NIG_PORT0_END           433
+#define NIG_PORT1_START         433
 	{OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
 	{OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
 	{OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
@@ -506,11 +563,11 @@ static const struct raw_op init_ops[] =
 	{OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
 	{OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
 	{OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END           404
-#define UPB_COMMON_START        404
+#define NIG_PORT1_END           445
+#define UPB_COMMON_START        445
 	{OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END          405
-#define CSDM_COMMON_START       405
+#define UPB_COMMON_END          446
+#define CSDM_COMMON_START       446
 	{OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
 	{OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
 	{OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
@@ -550,8 +607,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
 	{OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
 	{OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END         444
-#define USDM_COMMON_START       444
+#define CSDM_COMMON_END         485
+#define USDM_COMMON_START       485
 	{OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
 	{OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
 	{OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
@@ -568,9 +625,14 @@ static const struct raw_op init_ops[] =
 	{OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
 	{OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
 	{OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
-	{OP_ZR, USDM_REG_AGG_INT_EVENT_4, 0x5c},
+	{OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c},
+	{OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7},
+	{OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b},
 	{OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
-	{OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f},
+	{OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f},
+	{OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3},
+	{OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1},
+	{OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b},
 	{OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
 	{OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
 	{OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -594,18 +656,21 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
 	{OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
 	{OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END         486
-#define CCM_COMMON_START        486
+#define USDM_COMMON_END         532
+#define CCM_COMMON_START        532
 	{OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
 	{OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
 	{OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
 	{OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
 	{OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
+	{OP_WR, CCM_REG_STORM_WEIGHT, 0x2},
 	{OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
-	{OP_WR, CCM_REG_XSEM_WEIGHT, 0x4},
-	{OP_WR, CCM_REG_USEM_WEIGHT, 0x4},
+	{OP_WR, CCM_REG_XSEM_WEIGHT, 0x5},
+	{OP_WR, CCM_REG_USEM_WEIGHT, 0x5},
 	{OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
-	{OP_WR, CCM_REG_CQM_P_WEIGHT, 0x2},
+	{OP_WR, CCM_REG_CSDM_WEIGHT, 0x2},
+	{OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3},
+	{OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2},
 	{OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
 	{OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
 	{OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
@@ -620,8 +685,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
 	{OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
 	{OP_ZR, CCM_REG_XX_TABLE, 0x12},
-	{OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240238},
-	{OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x240254},
+	{OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242},
+	{OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c},
 	{OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
 	{OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
 	{OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
@@ -657,8 +722,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
 	{OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
 	{OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END          547
-#define CCM_FUNC0_START         547
+#define CCM_COMMON_END          596
+#define CCM_FUNC0_START         596
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
@@ -666,8 +731,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END           554
-#define CCM_FUNC1_START         554
+#define CCM_FUNC0_END           603
+#define CCM_FUNC1_START         603
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
@@ -675,8 +740,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END           561
-#define CCM_FUNC2_START         561
+#define CCM_FUNC1_END           610
+#define CCM_FUNC2_START         610
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
@@ -684,8 +749,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END           568
-#define CCM_FUNC3_START         568
+#define CCM_FUNC2_END           617
+#define CCM_FUNC3_START         617
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
@@ -693,8 +758,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END           575
-#define CCM_FUNC4_START         575
+#define CCM_FUNC3_END           624
+#define CCM_FUNC4_START         624
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
@@ -702,8 +767,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END           582
-#define CCM_FUNC5_START         582
+#define CCM_FUNC4_END           631
+#define CCM_FUNC5_START         631
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
@@ -711,8 +776,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END           589
-#define CCM_FUNC6_START         589
+#define CCM_FUNC5_END           638
+#define CCM_FUNC6_START         638
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
@@ -720,8 +785,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END           596
-#define CCM_FUNC7_START         596
+#define CCM_FUNC6_END           645
+#define CCM_FUNC7_START         645
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
 	{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
@@ -729,8 +794,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
 	{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END           603
-#define UCM_COMMON_START        603
+#define CCM_FUNC7_END           652
+#define UCM_COMMON_START        652
 	{OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
 	{OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
 	{OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
@@ -739,10 +804,16 @@ static const struct raw_op init_ops[] =
 	{OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
 	{OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
 	{OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
-	{OP_WR, UCM_REG_TSEM_WEIGHT, 0x3},
+	{OP_WR, UCM_REG_STORM_WEIGHT, 0x2},
+	{OP_WR, UCM_REG_TSEM_WEIGHT, 0x4},
 	{OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
+	{OP_WR, UCM_REG_XSEM_WEIGHT, 0x2},
+	{OP_WR, UCM_REG_DORQ_WEIGHT, 0x2},
 	{OP_WR, UCM_REG_CP_WEIGHT, 0x0},
-	{OP_WR, UCM_REG_UQM_P_WEIGHT, 0x6},
+	{OP_WR, UCM_REG_USDM_WEIGHT, 0x2},
+	{OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7},
+	{OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2},
+	{OP_WR, UCM_REG_TM_WEIGHT, 0x2},
 	{OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
 	{OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
 	{OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
@@ -756,14 +827,14 @@ static const struct raw_op init_ops[] =
 	{OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
 	{OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
 	{OP_ZR, UCM_REG_XX_TABLE, 0x12},
-	{OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b025c},
-	{OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b0278},
+	{OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266},
+	{OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0},
 	{OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
 	{OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
 	{OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
 	{OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
 	{OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
-	{OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xd},
+	{OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb},
 	{OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
 	{OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
 	{OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
@@ -787,56 +858,56 @@ static const struct raw_op init_ops[] =
 	{OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
 	{OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
 	{OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END          659
-#define UCM_FUNC0_START         659
+#define UCM_COMMON_END          714
+#define UCM_FUNC0_START         714
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END           663
-#define UCM_FUNC1_START         663
+#define UCM_FUNC0_END           718
+#define UCM_FUNC1_START         718
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END           667
-#define UCM_FUNC2_START         667
+#define UCM_FUNC1_END           722
+#define UCM_FUNC2_START         722
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END           671
-#define UCM_FUNC3_START         671
+#define UCM_FUNC2_END           726
+#define UCM_FUNC3_START         726
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END           675
-#define UCM_FUNC4_START         675
+#define UCM_FUNC3_END           730
+#define UCM_FUNC4_START         730
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END           679
-#define UCM_FUNC5_START         679
+#define UCM_FUNC4_END           734
+#define UCM_FUNC5_START         734
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END           683
-#define UCM_FUNC6_START         683
+#define UCM_FUNC5_END           738
+#define UCM_FUNC6_START         738
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END           687
-#define UCM_FUNC7_START         687
+#define UCM_FUNC6_END           742
+#define UCM_FUNC7_START         742
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
 	{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END           691
-#define USEM_COMMON_START       691
+#define UCM_FUNC7_END           746
+#define USEM_COMMON_START       746
 	{OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
 	{OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
 	{OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
@@ -887,69 +958,72 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
 	{OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
 	{OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2},
 	{OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
 	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
 	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
 	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57e8, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8020, 0xc8},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d0, 0x5},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x2},
-	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d0 + 0x14, 0x10277},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
-	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x20278},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4},
+	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb},
+	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
-	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027a},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf},
 	{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
-	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027c},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
+	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1},
 	{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
-	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028c},
-	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
-	{OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
-	{OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
-	{OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029c},
-	{OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
-	{OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
-	{OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
-	{OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x33450c47},
-	{OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
-	{OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
-	{OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
-	{OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x5004029e},
-	{OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
-	{OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
-#define USEM_COMMON_END         787
-#define USEM_PORT0_START        787
+	{OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294},
+	{OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1},
+	{OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000},
+	{OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000},
+	{OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4},
+	{OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1},
+	{OP_ZP_E1, USEM_REG_PRAM, 0x314c0000},
+	{OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000},
+	{OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53},
+	{OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e},
+	{OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf},
+	{OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02},
+	{OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754},
+	{OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9},
+	{OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6},
+	{OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3},
+#define USEM_COMMON_END         842
+#define USEM_PORT0_START        842
 	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x28},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9640, 0x34},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d00, 0x4},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4},
+	{OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d20, 0x20},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98},
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
@@ -966,23 +1040,26 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END          818
-#define USEM_PORT1_START        818
+#define USEM_PORT0_END          876
+#define USEM_PORT1_START        876
 	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x95a0, 0x28},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9710, 0x34},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d10, 0x4},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4},
+	{OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1da0, 0x20},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20},
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c},
+	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98},
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
-	{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
@@ -999,40 +1076,48 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END          849
-#define USEM_FUNC0_START        849
+#define USEM_PORT1_END          910
+#define USEM_FUNC0_START        910
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2},
-#define USEM_FUNC0_END          851
-#define USEM_FUNC1_START        851
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2},
+#define USEM_FUNC0_END          913
+#define USEM_FUNC1_START        913
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2},
-#define USEM_FUNC1_END          853
-#define USEM_FUNC2_START        853
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2},
+#define USEM_FUNC1_END          916
+#define USEM_FUNC2_START        916
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2},
-#define USEM_FUNC2_END          855
-#define USEM_FUNC3_START        855
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2},
+#define USEM_FUNC2_END          919
+#define USEM_FUNC3_START        919
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2},
-#define USEM_FUNC3_END          857
-#define USEM_FUNC4_START        857
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2},
+#define USEM_FUNC3_END          922
+#define USEM_FUNC4_START        922
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2},
-#define USEM_FUNC4_END          859
-#define USEM_FUNC5_START        859
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2},
+#define USEM_FUNC4_END          925
+#define USEM_FUNC5_START        925
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2},
-#define USEM_FUNC5_END          861
-#define USEM_FUNC6_START        861
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2},
+#define USEM_FUNC5_END          928
+#define USEM_FUNC6_START        928
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2},
-#define USEM_FUNC6_END          863
-#define USEM_FUNC7_START        863
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2},
+#define USEM_FUNC6_END          931
+#define USEM_FUNC7_START        931
+	{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0},
 	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
-	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2},
-#define USEM_FUNC7_END          865
-#define CSEM_COMMON_START       865
+	{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2},
+#define USEM_FUNC7_END          934
+#define CSEM_COMMON_START       934
 	{OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
 	{OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
 	{OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1091,29 +1176,30 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
-	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a0},
+	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
-	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240},
-	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100},
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400},
+	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5},
 	{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
-	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002a8},
-	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
+	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0},
+	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305},
 	{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
-	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002b8},
-	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
-	{OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
-	{OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
-	{OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002c8},
-	{OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
-	{OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
-	{OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
-	{OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
-	{OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
-	{OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402ca},
-	{OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
-#define CSEM_COMMON_END         944
-#define CSEM_PORT0_START        944
+	{OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0},
+	{OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315},
+	{OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000},
+	{OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000},
+	{OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0},
+	{OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325},
+	{OP_ZP_E1, CSEM_REG_PRAM, 0x32290000},
+	{OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000},
+	{OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b},
+	{OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a},
+	{OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2},
+	{OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327},
+#define CSEM_COMMON_END         1014
+#define CSEM_PORT0_START        1014
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
@@ -1123,11 +1209,10 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
-	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END          956
-#define CSEM_PORT1_START        956
+#define CSEM_PORT0_END          1025
+#define CSEM_PORT1_START        1025
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
@@ -1137,46 +1222,53 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
-	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
 	{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END          968
-#define CSEM_FUNC0_START        968
+#define CSEM_PORT1_END          1036
+#define CSEM_FUNC0_START        1036
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
-#define CSEM_FUNC0_END          970
-#define CSEM_FUNC1_START        970
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
+#define CSEM_FUNC0_END          1039
+#define CSEM_FUNC1_START        1039
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
-#define CSEM_FUNC1_END          972
-#define CSEM_FUNC2_START        972
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
+#define CSEM_FUNC1_END          1042
+#define CSEM_FUNC2_START        1042
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
-#define CSEM_FUNC2_END          974
-#define CSEM_FUNC3_START        974
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30},
+#define CSEM_FUNC2_END          1045
+#define CSEM_FUNC3_START        1045
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
-#define CSEM_FUNC3_END          976
-#define CSEM_FUNC4_START        976
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30},
+#define CSEM_FUNC3_END          1048
+#define CSEM_FUNC4_START        1048
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
-#define CSEM_FUNC4_END          978
-#define CSEM_FUNC5_START        978
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30},
+#define CSEM_FUNC4_END          1051
+#define CSEM_FUNC5_START        1051
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
-#define CSEM_FUNC5_END          980
-#define CSEM_FUNC6_START        980
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30},
+#define CSEM_FUNC5_END          1054
+#define CSEM_FUNC6_START        1054
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
-#define CSEM_FUNC6_END          982
-#define CSEM_FUNC7_START        982
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30},
+#define CSEM_FUNC6_END          1057
+#define CSEM_FUNC7_START        1057
 	{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
 	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
-#define CSEM_FUNC7_END          984
-#define XPB_COMMON_START        984
+	{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30},
+#define CSEM_FUNC7_END          1060
+#define XPB_COMMON_START        1060
 	{OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END          985
-#define DQ_COMMON_START         985
+#define XPB_COMMON_END          1061
+#define DQ_COMMON_START         1061
 	{OP_WR, DORQ_REG_MODE_ACT, 0x2},
 	{OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
 	{OP_WR, DORQ_REG_OUTST_REQ, 0x4},
@@ -1195,8 +1287,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
 	{OP_WR, DORQ_REG_REGN, 0x7c1004},
 	{OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END           1003
-#define TIMERS_COMMON_START     1003
+#define DQ_COMMON_END           1079
+#define TIMERS_COMMON_START     1079
 	{OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
 	{OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
 	{OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
@@ -1219,14 +1311,18 @@ static const struct raw_op init_ops[] =
 	{OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
 	{OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
 	{OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END       1025
-#define TIMERS_PORT0_START      1025
+#define TIMERS_COMMON_END       1101
+#define TIMERS_PORT0_START      1101
+	{OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0},
+	{OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0},
 	{OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END        1026
-#define TIMERS_PORT1_START      1026
+#define TIMERS_PORT0_END        1104
+#define TIMERS_PORT1_START      1104
+	{OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0},
+	{OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0},
 	{OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END        1027
-#define XSDM_COMMON_START       1027
+#define TIMERS_PORT1_END        1107
+#define XSDM_COMMON_START       1107
 	{OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
 	{OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
 	{OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
@@ -1249,7 +1345,9 @@ static const struct raw_op init_ops[] =
 	{OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
 	{OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
 	{OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
-	{OP_ZR, XSDM_REG_AGG_INT_EVENT_12, 0x54},
+	{OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c},
+	{OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d},
+	{OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52},
 	{OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
 	{OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
 	{OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
@@ -1274,8 +1372,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
 	{OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
 	{OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END         1074
-#define QM_COMMON_START         1074
+#define XSDM_COMMON_END         1156
+#define QM_COMMON_START         1156
 	{OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
 	{OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
 	{OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
@@ -1576,8 +1674,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
 	{OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
 	{OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END           1374
-#define PBF_COMMON_START        1374
+#define QM_COMMON_END           1456
+#define PBF_COMMON_START        1456
 	{OP_WR, PBF_REG_INIT, 0x1},
 	{OP_WR, PBF_REG_INIT_P4, 0x1},
 	{OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
@@ -1585,20 +1683,20 @@ static const struct raw_op init_ops[] =
 	{OP_WR, PBF_REG_INIT_P4, 0x0},
 	{OP_WR, PBF_REG_INIT, 0x0},
 	{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END          1381
-#define PBF_PORT0_START         1381
+#define PBF_COMMON_END          1463
+#define PBF_PORT0_START         1463
 	{OP_WR, PBF_REG_INIT_P0, 0x1},
 	{OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
 	{OP_WR, PBF_REG_INIT_P0, 0x0},
 	{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END           1385
-#define PBF_PORT1_START         1385
+#define PBF_PORT0_END           1467
+#define PBF_PORT1_START         1467
 	{OP_WR, PBF_REG_INIT_P1, 0x1},
 	{OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
 	{OP_WR, PBF_REG_INIT_P1, 0x0},
 	{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END           1389
-#define XCM_COMMON_START        1389
+#define PBF_PORT1_END           1471
+#define XCM_COMMON_START        1471
 	{OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
 	{OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
 	{OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
@@ -1607,15 +1705,18 @@ static const struct raw_op init_ops[] =
 	{OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
 	{OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
 	{OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
-	{OP_WR, XCM_REG_STORM_WEIGHT, 0x2},
-	{OP_WR, XCM_REG_TSEM_WEIGHT, 0x5},
-	{OP_WR, XCM_REG_CSEM_WEIGHT, 0x2},
-	{OP_WR, XCM_REG_USEM_WEIGHT, 0x2},
-	{OP_WR, XCM_REG_PBF_WEIGHT, 0x7},
-	{OP_WR, XCM_REG_NIG1_WEIGHT, 0x1},
+	{OP_WR, XCM_REG_STORM_WEIGHT, 0x3},
+	{OP_WR, XCM_REG_TSEM_WEIGHT, 0x6},
+	{OP_WR, XCM_REG_CSEM_WEIGHT, 0x3},
+	{OP_WR, XCM_REG_USEM_WEIGHT, 0x3},
+	{OP_WR, XCM_REG_DORQ_WEIGHT, 0x2},
+	{OP_WR, XCM_REG_PBF_WEIGHT, 0x0},
+	{OP_WR, XCM_REG_NIG0_WEIGHT, 0x2},
 	{OP_WR, XCM_REG_CP_WEIGHT, 0x0},
-	{OP_WR, XCM_REG_XSDM_WEIGHT, 0x5},
-	{OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3},
+	{OP_WR, XCM_REG_XSDM_WEIGHT, 0x6},
+	{OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4},
+	{OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2},
+	{OP_WR, XCM_REG_TM_WEIGHT, 0x2},
 	{OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
 	{OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
 	{OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
@@ -1633,14 +1734,14 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
 	{OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
 	{OP_ZR, XCM_REG_XX_TABLE, 0x12},
-	{OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02cc},
-	{OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
+	{OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4},
+	{OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329},
 	{OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
 	{OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
 	{OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
 	{OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
 	{OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
-	{OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xc},
+	{OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe},
 	{OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
 	{OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
 	{OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
@@ -1663,8 +1764,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
 	{OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
 	{OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END          1453
-#define XCM_PORT0_START         1453
+#define XCM_COMMON_END          1538
+#define XCM_PORT0_START         1538
 	{OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
 	{OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
 	{OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1673,8 +1774,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END           1461
-#define XCM_PORT1_START         1461
+#define XCM_PORT0_END           1546
+#define XCM_PORT1_START         1546
 	{OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
 	{OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
 	{OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1683,8 +1784,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
 	{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END           1469
-#define XCM_FUNC0_START         1469
+#define XCM_PORT1_END           1554
+#define XCM_FUNC0_START         1554
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1694,8 +1795,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END           1478
-#define XCM_FUNC1_START         1478
+#define XCM_FUNC0_END           1563
+#define XCM_FUNC1_START         1563
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1705,8 +1806,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END           1487
-#define XCM_FUNC2_START         1487
+#define XCM_FUNC1_END           1572
+#define XCM_FUNC2_START         1572
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1716,8 +1817,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END           1496
-#define XCM_FUNC3_START         1496
+#define XCM_FUNC2_END           1581
+#define XCM_FUNC3_START         1581
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1727,8 +1828,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END           1505
-#define XCM_FUNC4_START         1505
+#define XCM_FUNC3_END           1590
+#define XCM_FUNC4_START         1590
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1738,8 +1839,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END           1514
-#define XCM_FUNC5_START         1514
+#define XCM_FUNC4_END           1599
+#define XCM_FUNC5_START         1599
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1749,8 +1850,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END           1523
-#define XCM_FUNC6_START         1523
+#define XCM_FUNC5_END           1608
+#define XCM_FUNC6_START         1608
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1760,8 +1861,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END           1532
-#define XCM_FUNC7_START         1532
+#define XCM_FUNC6_END           1617
+#define XCM_FUNC7_START         1617
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
 	{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
 	{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1771,8 +1872,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
 	{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
 	{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END           1541
-#define XSEM_COMMON_START       1541
+#define XCM_FUNC7_END           1626
+#define XSEM_COMMON_START       1626
 	{OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
 	{OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
 	{OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1827,10 +1928,12 @@ static const struct raw_op init_ops[] =
 	{OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
 	{OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
 	{OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
-	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d00, 0x4},
+	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x4},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
@@ -1839,68 +1942,73 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202eb},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ed},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
+	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
-	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f1},
-	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0},
+	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f3},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362},
 	{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f5},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364},
 	{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80305},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374},
 	{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030d},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
-	{OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
-	{OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
-	{OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130315},
-	{OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
-	{OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
-	{OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
-	{OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38840d14},
-	{OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x38240d19},
-	{OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3e711b35},
-	{OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
-	{OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
-	{OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
-	{OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60317},
-	{OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
-#define XSEM_COMMON_END         1651
-#define XSEM_PORT0_START        1651
-	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c},
+	{OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000},
+	{OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000},
+	{OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321},
+	{OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384},
+	{OP_ZP_E1, XSEM_REG_PRAM, 0x33660000},
+	{OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000},
+	{OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda},
+	{OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02},
+	{OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07},
+	{OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8},
+	{OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4},
+	{OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9},
+	{OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323},
+	{OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3},
+	{OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386},
+#define XSEM_COMMON_END         1741
+#define XSEM_PORT0_START        1741
+	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
-	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x10},
+	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2528, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2608, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x100319},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
-	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
+	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
 	{OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
@@ -1910,31 +2018,33 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20329},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END          1683
-#define XSEM_PORT1_START        1683
-	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
+#define XSEM_PORT0_END          1775
+#define XSEM_PORT1_START        1775
+	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
-	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24e8, 0x10},
+	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2598, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2678, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
-	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032b},
+	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
-	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
+	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
 	{OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
@@ -1944,68 +2054,68 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e},
 	{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
-	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033b},
+	{OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
 	{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END          1715
-#define XSEM_FUNC0_START        1715
+#define XSEM_PORT1_END          1809
+#define XSEM_FUNC0_START        1809
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END          1718
-#define XSEM_FUNC1_START        1718
+#define XSEM_FUNC0_END          1812
+#define XSEM_FUNC1_START        1812
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END          1721
-#define XSEM_FUNC2_START        1721
+#define XSEM_FUNC1_END          1815
+#define XSEM_FUNC2_START        1815
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END          1724
-#define XSEM_FUNC3_START        1724
+#define XSEM_FUNC2_END          1818
+#define XSEM_FUNC3_START        1818
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END          1727
-#define XSEM_FUNC4_START        1727
+#define XSEM_FUNC3_END          1821
+#define XSEM_FUNC4_START        1821
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END          1730
-#define XSEM_FUNC5_START        1730
+#define XSEM_FUNC4_END          1824
+#define XSEM_FUNC5_START        1824
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END          1733
-#define XSEM_FUNC6_START        1733
+#define XSEM_FUNC5_END          1827
+#define XSEM_FUNC6_START        1827
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END          1736
-#define XSEM_FUNC7_START        1736
+#define XSEM_FUNC6_END          1830
+#define XSEM_FUNC7_START        1830
 	{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
-	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1},
+	{OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
 	{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END          1739
-#define CDU_COMMON_START        1739
+#define XSEM_FUNC7_END          1833
+#define CDU_COMMON_START        1833
 	{OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
 	{OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
 	{OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
 	{OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
-	{OP_WB_E1, CDU_REG_L1TT, 0x200033d},
-	{OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
-	{OP_WB_E1, CDU_REG_MATT, 0x20053d},
-	{OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
+	{OP_WB_E1, CDU_REG_L1TT, 0x200034d},
+	{OP_WB_E1H, CDU_REG_L1TT, 0x2000410},
+	{OP_WB_E1, CDU_REG_MATT, 0x20054d},
+	{OP_WB_E1H, CDU_REG_MATT, 0x280610},
 	{OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
-	{OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055d},
+	{OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
 	{OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END          1750
-#define DMAE_COMMON_START       1750
+#define CDU_COMMON_END          1844
+#define DMAE_COMMON_START       1844
 	{OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
 	{OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
 	{OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
@@ -2013,24 +2123,27 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
 	{OP_WR, DMAE_REG_PCI_IFEN, 0x1},
 	{OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END         1757
-#define PXP_COMMON_START        1757
-	{OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50563},
-	{OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
-	{OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50568},
-	{OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
-	{OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056d},
-#define PXP_COMMON_END          1762
-#define CFC_COMMON_START        1762
+#define DMAE_COMMON_END         1851
+#define PXP_COMMON_START        1851
+	{OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573},
+	{OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638},
+	{OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578},
+	{OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d},
+	{OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d},
+	{OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642},
+#define PXP_COMMON_END          1857
+#define CFC_COMMON_START        1857
 	{OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
 	{OP_WR, CFC_REG_CONTROL0, 0x10},
 	{OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
+	{OP_WR, CFC_REG_INTERFACES, 0x280000},
 	{OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
-#define CFC_COMMON_END          1766
-#define HC_COMMON_START         1766
+	{OP_WR, CFC_REG_INTERFACES, 0x0},
+#define CFC_COMMON_END          1863
+#define HC_COMMON_START         1863
 	{OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END           1767
-#define HC_PORT0_START          1767
+#define HC_COMMON_END           1864
+#define HC_PORT0_START          1864
 	{OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
 	{OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
 	{OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2049,8 +2162,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END            1785
-#define HC_PORT1_START          1785
+#define HC_PORT0_END            1882
+#define HC_PORT1_START          1882
 	{OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
 	{OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
 	{OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2069,8 +2182,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
 	{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END            1803
-#define HC_FUNC0_START          1803
+#define HC_PORT1_END            1900
+#define HC_FUNC0_START          1900
 	{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2086,8 +2199,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END            1818
-#define HC_FUNC1_START          1818
+#define HC_FUNC0_END            1915
+#define HC_FUNC1_START          1915
 	{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2103,8 +2216,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END            1833
-#define HC_FUNC2_START          1833
+#define HC_FUNC1_END            1930
+#define HC_FUNC2_START          1930
 	{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2120,8 +2233,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END            1848
-#define HC_FUNC3_START          1848
+#define HC_FUNC2_END            1945
+#define HC_FUNC3_START          1945
 	{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2137,8 +2250,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END            1863
-#define HC_FUNC4_START          1863
+#define HC_FUNC3_END            1960
+#define HC_FUNC4_START          1960
 	{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2154,8 +2267,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END            1878
-#define HC_FUNC5_START          1878
+#define HC_FUNC4_END            1975
+#define HC_FUNC5_START          1975
 	{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2171,8 +2284,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END            1893
-#define HC_FUNC6_START          1893
+#define HC_FUNC5_END            1990
+#define HC_FUNC6_START          1990
 	{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2188,8 +2301,8 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END            1908
-#define HC_FUNC7_START          1908
+#define HC_FUNC6_END            2005
+#define HC_FUNC7_START          2005
 	{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
 	{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
 	{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2205,10 +2318,10 @@ static const struct raw_op init_ops[] =
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
 	{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END            1923
-#define PXP2_COMMON_START       1923
-	{OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
+#define HC_FUNC7_END            2020
+#define PXP2_COMMON_START       2020
 	{OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
+	{OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340},
 	{OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
 	{OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
 	{OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
@@ -2220,7 +2333,7 @@ static const struct raw_op init_ops[] =
 	{OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
 	{OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
 	{OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
-	{OP_WR, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
+	{OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
 	{OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
 	{OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
 	{OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
@@ -2247,6 +2360,7 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
 	{OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
 	{OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
+	{OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000},
 	{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
 	{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
 	{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
@@ -2323,9 +2437,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
 	{OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
 	{OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
-	{OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
-#define PXP2_COMMON_END         2040
-#define MISC_AEU_COMMON_START   2040
+#define PXP2_COMMON_END         2137
+#define MISC_AEU_COMMON_START   2137
 	{OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
 	{OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
 	{OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
@@ -2345,8 +2458,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
 	{OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
 	{OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END     2059
-#define MISC_AEU_PORT0_START    2059
+#define MISC_AEU_COMMON_END     2156
+#define MISC_AEU_PORT0_START    2156
 	{OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
 	{OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
 	{OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
@@ -2379,8 +2492,8 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
 	{OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
 	{OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END      2091
-#define MISC_AEU_PORT1_START    2091
+#define MISC_AEU_PORT0_END      2188
+#define MISC_AEU_PORT1_START    2188
 	{OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
 	{OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
 	{OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
@@ -2413,7 +2526,7 @@ static const struct raw_op init_ops[] =
 	{OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
 	{OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
 	{OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END      2123
+#define MISC_AEU_PORT1_END      2220
 
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_link.c linux-libre-2.6.30-gnu1/drivers/net/bnx2x_link.c
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_link.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_link.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,14 +22,9 @@
 #include <linux/ethtool.h>
 #include <linux/mutex.h>
 
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
 #include "bnx2x.h"
 
 /********************************************************/
-#define SUPPORT_CL73 0 /* Currently no */
 #define ETH_HLEN			14
 #define ETH_OVREHEAD		(ETH_HLEN + 8)/* 8 for CRC + VLAN*/
 #define ETH_MIN_PACKET_SIZE		60
@@ -139,6 +134,26 @@
 #define PHY_SGMII_FLAG			0x2
 #define PHY_SERDES_FLAG			0x4
 
+/* */
+#define SFP_EEPROM_CON_TYPE_ADDR		0x2
+	#define SFP_EEPROM_CON_TYPE_VAL_LC 		0x7
+	#define SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
+
+#define SFP_EEPROM_FC_TX_TECH_ADDR		0x8
+	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
+	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE	 0x8
+#define SFP_EEPROM_VENDOR_NAME_ADDR		0x14
+#define SFP_EEPROM_VENDOR_NAME_SIZE 	16
+#define SFP_EEPROM_OPTIONS_ADDR 		0x40
+	#define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
+#define SFP_EEPROM_OPTIONS_SIZE 		2
+
+#define SFP_MODULE_TYPE_UNKNOWN 			0x0
+#define SFP_MODULE_TYPE_LC   			0x1
+#define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE		0x2
+#define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE	0x3
+
+#define SFP_LIMITING_MODE_VALUE 			0x0044
 /**********************************************************/
 /*                     INTERFACE                          */
 /**********************************************************/
@@ -154,13 +169,34 @@
 		(_bank + (_addr & 0xf)), \
 		_val)
 
-static void bnx2x_set_phy_mdio(struct link_params *params)
+static void bnx2x_set_serdes_access(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
-		   params->port*0x18, 0);
-	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
-		   DEFAULT_PHY_DEV_ADDR);
+	u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+	/* Set Clause 22 */
+	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
+	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
+	udelay(500);
+	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
+	udelay(500);
+	 /* Set Clause 45 */
+	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
+}
+static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
+{
+	struct bnx2x *bp = params->bp;
+	if (phy_flags & PHY_XGXS_FLAG) {
+		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+			   params->port*0x18, 0);
+		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
+			   DEFAULT_PHY_DEV_ADDR);
+	} else {
+		bnx2x_set_serdes_access(params);
+
+		REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
+			   params->port*0x10,
+			   DEFAULT_PHY_DEV_ADDR);
+	}
 }
 
 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
@@ -277,8 +313,10 @@ static u8 bnx2x_emac_enable(struct link_
 			   port*4, 0);
 	}
 
-	/* enable emac */
-	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+		    EMAC_RX_MODE_RESET);
+	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+		    EMAC_TX_MODE_RESET);
 
 	if (CHIP_REV_IS_SLOW(bp)) {
 		/* config GMII mode */
@@ -498,7 +536,7 @@ static void bnx2x_phy_deassert(struct li
 	udelay(500);
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
 		    val);
-	bnx2x_set_phy_mdio(params);
+	bnx2x_set_phy_mdio(params, phy_flags);
 }
 
 void bnx2x_link_status_update(struct link_params *params,
@@ -749,12 +787,17 @@ static u8 bnx2x_pbf_update(struct link_p
 	return 0;
 }
 
-static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
+static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
 {
 	u32 emac_base;
 	switch (ext_phy_type) {
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
-		emac_base = GRCBASE_EMAC0;
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		/* All MDC/MDIO is directed through single EMAC */
+		if (REG_RD(bp, NIG_REG_PORT_SWAP))
+			emac_base = GRCBASE_EMAC0;
+		else
+			emac_base = GRCBASE_EMAC1;
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
@@ -772,11 +815,12 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8
 {
 	u32 tmp, saved_mode;
 	u8 i, rc = 0;
-	u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+	u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
 
 	/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
 	 */
+
 	saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 	tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
 			     EMAC_MDIO_MODE_CLOCK_CNT);
@@ -841,10 +885,11 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8
 	u16 i;
 	u8 rc = 0;
 
-	u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+	u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
 	/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
 	 */
+
 	saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 	val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
 			     EMAC_MDIO_MODE_CLOCK_CNT));
@@ -967,6 +1012,8 @@ static u8 bnx2x_reset_unicore(struct lin
 			      (mii_control |
 			       MDIO_COMBO_IEEO_MII_CONTROL_RESET));
 
+	bnx2x_set_serdes_access(params);
+
 	/* wait for the reset to self clear */
 	for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
 		udelay(5);
@@ -1156,62 +1203,9 @@ static void bnx2x_set_autoneg(struct lin
 			      MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
 			      reg_val);
 
-	/* Enable Clause 73 Aneg */
-	if ((vars->line_speed == SPEED_AUTO_NEG) &&
-	    (SUPPORT_CL73)) {
-		/* Enable BAM Station Manager */
-
-		CL45_WR_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_CL73_USERB0,
-				      MDIO_CL73_USERB0_CL73_BAM_CTRL1,
-				   (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
-			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);
-
-		CL45_WR_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-			MDIO_REG_BANK_CL73_USERB0,
-			MDIO_CL73_USERB0_CL73_BAM_CTRL3,
-			(reg_val |
-			MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
-
-		/* Set the CL73 AN speed */
-
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_CL73_IEEEB1,
-				      MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
-		/* In the SerDes we support only the 1G.
-		   In the XGXS we support the 10G KX4
-		   but we currently do not support the KR */
-		if (vars->phy_flags & PHY_XGXS_FLAG) {
-			DP(NETIF_MSG_LINK, "XGXS\n");
-			/* 10G KX4 */
-			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
-		} else {
-			DP(NETIF_MSG_LINK, "SerDes\n");
-			/* 1000M KX */
-			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);
+	/* CL73 Autoneg Disabled */
+	reg_val = 0;
 
-		/* CL73 Autoneg Enabled */
-		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
-	} else {
-		/* CL73 Autoneg Disabled */
-		reg_val = 0;
-	}
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_CL73_IEEEB0,
@@ -1344,44 +1338,25 @@ static void bnx2x_set_ieee_aneg_advertis
 static void bnx2x_restart_autoneg(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
+	u16 mii_control;
 	DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
-	if (SUPPORT_CL73) {
-		/* enable and restart clause 73 aneg */
-		u16 an_ctrl;
-
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_CL73_IEEEB0,
-				      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
-				  &an_ctrl);
-		CL45_WR_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				MDIO_REG_BANK_CL73_IEEEB0,
-				MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
-				(an_ctrl |
-				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
-				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
-
-	} else {
-		/* Enable and restart BAM/CL37 aneg */
-		u16 mii_control;
+	/* Enable and restart BAM/CL37 aneg */
 
-		CL45_RD_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_COMBO_IEEE0,
-				      MDIO_COMBO_IEEE0_MII_CONTROL,
-				      &mii_control);
-		DP(NETIF_MSG_LINK,
-			 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
-			 mii_control);
-		CL45_WR_OVER_CL22(bp, params->port,
-				      params->phy_addr,
-				      MDIO_REG_BANK_COMBO_IEEE0,
-				      MDIO_COMBO_IEEE0_MII_CONTROL,
-				      (mii_control |
-				MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
-				MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
-	}
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_COMBO_IEEE0,
+			      MDIO_COMBO_IEEE0_MII_CONTROL,
+			      &mii_control);
+	DP(NETIF_MSG_LINK,
+		 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
+		 mii_control);
+	CL45_WR_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_COMBO_IEEE0,
+			      MDIO_COMBO_IEEE0_MII_CONTROL,
+			      (mii_control |
+			       MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+			       MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
 }
 
 static void bnx2x_initialize_sgmii_process(struct link_params *params,
@@ -1726,7 +1701,11 @@ static u8 bnx2x_link_settings_status(str
 		    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
-		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+		     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
 			vars->autoneg = AUTO_NEG_ENABLED;
 
 			if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1770,38 +1749,44 @@ static u8 bnx2x_link_settings_status(str
 	return rc;
 }
 
-static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
+static void bnx2x_set_gmii_tx_driver(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u16 lp_up2;
 	u16 tx_driver;
+	u16 bank;
 
 	/* read precomp */
-
 	CL45_RD_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_OVER_1G,
 			      MDIO_OVER_1G_LP_UP2, &lp_up2);
 
-	CL45_RD_OVER_CL22(bp, params->port,
-			      params->phy_addr,
-			      MDIO_REG_BANK_TX0,
-			      MDIO_TX0_TX_DRIVER, &tx_driver);
-
 	/* bits [10:7] at lp_up2, positioned at [15:12] */
 	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
 		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
 		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
 
-	if ((lp_up2 != 0) &&
-	    (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
-		/* replace tx_driver bits [15:12] */
-		tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
-		tx_driver |= lp_up2;
-		CL45_WR_OVER_CL22(bp, params->port,
+	if (lp_up2 == 0)
+		return;
+
+	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
+	      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
+		CL45_RD_OVER_CL22(bp, params->port,
 				      params->phy_addr,
-				      MDIO_REG_BANK_TX0,
-				      MDIO_TX0_TX_DRIVER, tx_driver);
+				      bank,
+				      MDIO_TX0_TX_DRIVER, &tx_driver);
+
+		/* replace tx_driver bits [15:12] */
+		if (lp_up2 !=
+		    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
+			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
+			tx_driver |= lp_up2;
+			CL45_WR_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      bank,
+					      MDIO_TX0_TX_DRIVER, tx_driver);
+		}
 	}
 }
 
@@ -1902,6 +1887,25 @@ static void bnx2x_ext_phy_reset(struct l
 				       MDIO_PMA_DEVAD,
 				       MDIO_PMA_REG_CTRL, 0xa040);
 			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+
+			/* Restore normal power mode*/
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+					  MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+					  params->port);
+
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+					  MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+					  params->port);
+
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_CTRL,
+				       1<<15);
+
+			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 			/* Unset Low Power Mode and SW reset */
 			/* Restore normal power mode*/
@@ -1919,9 +1923,6 @@ static void bnx2x_ext_phy_reset(struct l
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 			{
-			u16 emac_base;
-			emac_base = (params->port) ? GRCBASE_EMAC0 :
-					GRCBASE_EMAC1;
 
 			/* Restore normal power mode*/
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
@@ -1949,6 +1950,23 @@ static void bnx2x_ext_phy_reset(struct l
 
 			break;
 
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+
+			/* Restore normal power mode*/
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+					  params->port);
+
+			/* HW reset */
+			bnx2x_hw_reset(bp, params->port);
+
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_CTRL,
+				       1<<15);
+			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
 			DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
 			break;
@@ -1980,6 +1998,31 @@ static void bnx2x_ext_phy_reset(struct l
 	}
 }
 
+
+static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
+				    u32 shmem_base, u32 spirom_ver)
+{
+	DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
+		 (u16)(spirom_ver>>16), (u16)spirom_ver);
+	REG_WR(bp, shmem_base +
+		   offsetof(struct shmem_region,
+			    port_mb[port].ext_phy_fw_version),
+			spirom_ver);
+}
+
+static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
+				    u32 ext_phy_type, u8 ext_phy_addr,
+				    u32 shmem_base)
+{
+	u16 fw_ver1, fw_ver2;
+	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_ROM_VER2, &fw_ver2);
+	bnx2x_save_spirom_version(bp, port, shmem_base,
+				(u32)(fw_ver1<<16 | fw_ver2));
+}
+
 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
@@ -1988,7 +2031,6 @@ static void bnx2x_bcm8072_external_rom_b
 			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-	u16 fw_ver1, fw_ver2;
 
 	/* Need to wait 200ms after reset */
 	msleep(200);
@@ -2024,14 +2066,10 @@ static void bnx2x_bcm8072_external_rom_b
 	/* Wait 100ms */
 	msleep(100);
 
-	/* Print the PHY FW version */
-	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
-			    MDIO_PMA_DEVAD,
-			    MDIO_PMA_REG_ROM_VER1, &fw_ver1);
-	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
-			    MDIO_PMA_DEVAD,
-			    MDIO_PMA_REG_ROM_VER2, &fw_ver2);
-	DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+	bnx2x_save_bcm_spirom_ver(bp, port,
+				ext_phy_type,
+				ext_phy_addr,
+				params->shmem_base);
 }
 
 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
@@ -2049,7 +2087,7 @@ static u8 bnx2x_8073_is_snr_needed(struc
 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
-		      0xc801, &val);
+		      MDIO_PMA_REG_8073_CHIP_REV, &val);
 
 	if (val != 1) {
 		/* No need to workaround in 8073 A1 */
@@ -2081,7 +2119,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct l
 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
-		      0xc801, &val);
+		      MDIO_PMA_REG_8073_CHIP_REV, &val);
 
 	if (val > 0) {
 		/* No need to workaround in 8073 A1 */
@@ -2097,7 +2135,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct l
 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 			      ext_phy_addr,
 			      MDIO_PMA_DEVAD,
-			      0xc820, &val);
+			      MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+			      &val);
 		  /* If bit [14] = 0 or bit [13] = 0, continue on with
 		   system initialization (XAUI work-around not required,
 		    as these bits indicate 2.5G or 1G link up). */
@@ -2115,7 +2154,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct l
 					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 					ext_phy_addr,
 					MDIO_PMA_DEVAD,
-					0xc841, &val);
+					MDIO_PMA_REG_8073_XAUI_WA, &val);
 				if (val & (1<<15)) {
 					DP(NETIF_MSG_LINK,
 					  "XAUI workaround has completed\n");
@@ -2133,9 +2172,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct l
 }
 
 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
-					  u8 ext_phy_addr)
+					  u8 ext_phy_addr, u32 shmem_base)
 {
-	u16 fw_ver1, fw_ver2;
 	/* Boot port from external ROM  */
 	/* EDC grst */
 	bnx2x_cl45_write(bp, port,
@@ -2185,17 +2223,496 @@ static void bnx2x_bcm8073_external_rom_b
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
 
-	bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+	bnx2x_save_bcm_spirom_ver(bp, port,
+				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+				ext_phy_addr,
+				shmem_base);
+}
+
+static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u8 port = params->port;
+	u8 ext_phy_addr = ((params->ext_phy_config &
+			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+	/* 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);
+
+	/* Set soft reset */
+	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_MICRO_RESET);
+
+	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_GEN_CTRL2,
+		       0x73A0);
+
+	/* 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,
+		       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+	/* wait for 150ms for microcode load */
+	msleep(150);
+
+	/* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
+	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+
+	msleep(200);
+	bnx2x_save_bcm_spirom_ver(bp, port,
+				ext_phy_type,
+				ext_phy_addr,
+				params->shmem_base);
+}
+
+static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
+					u8 ext_phy_addr, u8 tx_en)
+{
+	u16 val;
+	DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
+		 tx_en, port);
+	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
+	bnx2x_cl45_read(bp, port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
-		      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+		      MDIO_PMA_REG_PHY_IDENTIFIER,
+		      &val);
+
+	if (tx_en)
+		val &= ~(1<<15);
+	else
+		val |= (1<<15);
+
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_PHY_IDENTIFIER,
+		       val);
+}
+
+
+static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+				     u8 byte_cnt, u8 *o_buf) {
+	struct bnx2x *bp = params->bp;
+	u16 val, i;
+	u8 port = params->port;
+	u8 ext_phy_addr = ((params->ext_phy_config &
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+	if (byte_cnt > 16) {
+		DP(NETIF_MSG_LINK, "Reading from eeprom is"
+			    " is limited to 0xf\n");
+		return -EINVAL;
+	}
+	/* Set the read command byte count */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
+		       (byte_cnt | 0xa000));
+
+	/* Set the read command address */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
+		       addr);
+
+	/* Activate read command */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
+		       0x2c0f);
+
+	/* Wait up to 500us for command complete status */
+	for (i = 0; i < 100; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
+			break;
+		udelay(5);
+	}
+
+	if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
+		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
+		DP(NETIF_MSG_LINK,
+			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
+			 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
+		return -EINVAL;
+	}
+
+	/* Read the buffer */
+	for (i = 0; i < byte_cnt; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
+		o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
+	}
+
+	for (i = 0; i < 100; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
+			return 0;;
+		msleep(1);
+	}
+	return -EINVAL;
+}
+
+
+static u8 bnx2x_get_sfp_module_type(struct link_params *params,
+				  u8 *module_type)
+{
+	struct bnx2x *bp = params->bp;
+	u8 val;
+	*module_type = SFP_MODULE_TYPE_UNKNOWN;
+
+	/* First check for copper cable */
+	if (bnx2x_read_sfp_module_eeprom(params,
+				       SFP_EEPROM_CON_TYPE_ADDR,
+				       1,
+				       &val) != 0) {
+		DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
+		return -EINVAL;
+	}
+
+	switch (val) {
+	case SFP_EEPROM_CON_TYPE_VAL_COPPER:
+	{
+		u8 copper_module_type;
+		/* Check if its active cable( includes SFP+ module)
+		of passive cable*/
+		if (bnx2x_read_sfp_module_eeprom(params,
+					       SFP_EEPROM_FC_TX_TECH_ADDR,
+					       1,
+					       &copper_module_type) !=
+		    0) {
+			DP(NETIF_MSG_LINK,
+				"Failed to read copper-cable-type"
+				" from SFP+ EEPROM\n");
+			return -EINVAL;
+		}
+
+		if (copper_module_type &
+		    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
+			DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
+			*module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
+		} else if (copper_module_type &
+			SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
+				DP(NETIF_MSG_LINK, "Passive Copper"
+					    " cable detected\n");
+				*module_type =
+				      SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
+		} else {
+			DP(NETIF_MSG_LINK, "Unknown copper-cable-"
+				     "type 0x%x !!!\n", copper_module_type);
+			return -EINVAL;
+		}
+		break;
+	}
+	case SFP_EEPROM_CON_TYPE_VAL_LC:
+		DP(NETIF_MSG_LINK, "Optic module detected\n");
+		*module_type = SFP_MODULE_TYPE_LC;
+		break;
+
+	default:
+		DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
+			 val);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+/* This function read the relevant field from the module ( SFP+ ),
+	and verify it is compliant with this board */
+static u8 bnx2x_verify_sfp_module(struct link_params *params,
+				u8 module_type)
+{
+	struct bnx2x *bp = params->bp;
+	u8 *str_p, *tmp_buf;
+	u16 i;
+
+#define COMPLIANCE_STR_CNT 6
+	u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
+		"FINISAR CORP.   ", "Amphenol"};
+	u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
+	/* Passive Copper cables are allowed to participate,
+	since the module is hardwired to the copper cable */
+
+	if (!(params->feature_config_flags &
+	     FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+		DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
+		return 0;
+	}
+
+	if (module_type != SFP_MODULE_TYPE_LC) {
+		DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
+		return 0;
+	}
+
+	/* In case of non copper cable or Active copper cable,
+		verify that the SFP+ module is compliant with this board*/
+	if (bnx2x_read_sfp_module_eeprom(params,
+				       SFP_EEPROM_VENDOR_NAME_ADDR,
+				       SFP_EEPROM_VENDOR_NAME_SIZE,
+				       buf) != 0) {
+		DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
+			    " module EEPROM\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
+		str_p = compliance_str[i];
+		tmp_buf = buf;
+		while (*str_p) {
+			if ((u8)(*tmp_buf) != (u8)(*str_p))
+				break;
+			str_p++;
+			tmp_buf++;
+		}
+
+		if (!(*str_p)) {
+			DP(NETIF_MSG_LINK, "SFP+ Module verified, "
+				     "index=%x\n", i);
+			return 0;
+		}
+	}
+	DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
+	return -EINVAL;
+}
+
+
+static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
+					u8 module_type)
+{
+	struct bnx2x *bp = params->bp;
+	u8 port = params->port;
+	u8 options[SFP_EEPROM_OPTIONS_SIZE];
+	u8 limiting_mode;
+	u8 ext_phy_addr = ((params->ext_phy_config &
+			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u16 cur_limiting_mode;
+	if (bnx2x_read_sfp_module_eeprom(params,
+				       SFP_EEPROM_OPTIONS_ADDR,
+				       SFP_EEPROM_OPTIONS_SIZE,
+				       options) != 0) {
+		DP(NETIF_MSG_LINK, "Failed to read Option field from"
+			    " module EEPROM\n");
+		return -EINVAL;
+	}
+	limiting_mode = !(options[0] &
+			  SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
+
 	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
-		      MDIO_PMA_REG_ROM_VER2, &fw_ver2);
-	DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+		      MDIO_PMA_REG_ROM_VER2,
+		      &cur_limiting_mode);
+	DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
+		 cur_limiting_mode);
+
+	if (limiting_mode &&
+	    (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
+		DP(NETIF_MSG_LINK,
+			 "Module options = 0x%x.Setting LIMITING MODE\n",
+			 options[0]);
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_ROM_VER2,
+			       SFP_LIMITING_MODE_VALUE);
+	} else { /* LRM mode ( default )*/
+
+		DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
+			 options[0]);
+
+		/* Changing to LRM mode takes quite few seconds.
+		So do it only if current mode is limiting
+		( default is LRM )*/
+		if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
+			return 0;
+
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_LRM_MODE,
+			       0);
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_ROM_VER2,
+			       0x128);
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_MISC_CTRL0,
+			       0x4008);
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_LRM_MODE,
+			       0xaaaa);
+	}
+	return 0;
+}
+
+static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
+{
+	u8 val;
+	struct bnx2x *bp = params->bp;
+	u16 timeout;
+	/* Initialization time after hot-plug may take up to 300ms for some
+	phys type ( e.g. JDSU ) */
+	for (timeout = 0; timeout < 60; timeout++) {
+		if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
+		    == 0) {
+			DP(NETIF_MSG_LINK, "SFP+ module initialization "
+				     "took %d ms\n", timeout * 5);
+			return 0;
+		}
+		msleep(5);
+	}
+	return -EINVAL;
+}
 
+static u8 bnx2x_sfp_module_detection(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u8 module_type;
+	u8 ext_phy_addr = ((params->ext_phy_config &
+				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+	if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+		DP(NETIF_MSG_LINK, "Module detection is not required "
+			    "for this phy\n");
+		return 0;
+	}
+
+	DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
+		 params->port);
+
+	if (bnx2x_get_sfp_module_type(params,
+				    &module_type) != 0) {
+		DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
+		if (!(params->feature_config_flags &
+		      FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+			/* In case module detection is disabled, it trys to
+			link up. The issue that can happen here is LRM /
+			LIMITING mode which set according to the module-type*/
+			DP(NETIF_MSG_LINK, "Unable to read module-type."
+				    "Probably due to Bit Stretching."
+				    " Proceeding...\n");
+		} else {
+			return -EINVAL;
+		}
+	} else if (bnx2x_verify_sfp_module(params, module_type) !=
+		   0) {
+		/* check SFP+ module compatibility */
+		DP(NETIF_MSG_LINK, "Module verification failed!!\n");
+		/* Turn on fault module-detected led */
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+				  MISC_REGISTERS_GPIO_HIGH,
+				  params->port);
+		return -EINVAL;
+	}
+
+	/* Turn off fault module-detected led */
+	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+			  MISC_REGISTERS_GPIO_LOW,
+			  params->port);
+
+	/* Check and set limiting mode / LRM mode */
+	bnx2x_bcm8726_set_limiting_mode(params, module_type);
+
+	/* Enable transmit for this module */
+	bnx2x_bcm8726_set_transmitter(bp, params->port,
+				    ext_phy_addr, 1);
+	return 0;
+}
+
+void bnx2x_handle_module_detect_int(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u32 gpio_val;
+	u8 port = params->port;
+	/* Set valid module led off */
+	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+			  MISC_REGISTERS_GPIO_HIGH,
+			  params->port);
+
+	/* Get current gpio val refelecting module plugged in / out*/
+	gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
+
+	/* Call the handling function in case module is detected */
+	if (gpio_val == 0) {
+
+		bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+				      MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
+				      port);
+
+		if (bnx2x_wait_for_sfp_module_initialized(params)
+		    == 0)
+			bnx2x_sfp_module_detection(params);
+		else
+			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
+	} else {
+		u8 ext_phy_addr = ((params->ext_phy_config &
+				    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+				   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+				      MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
+				      port);
+		/* Module was plugged out. */
+		/* Disable transmit for this module */
+		bnx2x_bcm8726_set_transmitter(bp, params->port,
+					    ext_phy_addr, 0);
+	}
 }
 
 static void bnx2x_bcm807x_force_10G(struct link_params *params)
@@ -2239,7 +2756,7 @@ static void bnx2x_bcm8073_set_xaui_low_p
 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
-		      0xc801, &val);
+		      MDIO_PMA_REG_8073_CHIP_REV, &val);
 
 	if (val == 0) {
 		/* Mustn't set low power mode in 8073 A0 */
@@ -2377,31 +2894,40 @@ static void bnx2x_ext_phy_set_pause(stru
 		       MDIO_AN_DEVAD,
 		       MDIO_AN_REG_ADV_PAUSE, val);
 }
+static void bnx2x_set_preemphasis(struct link_params *params)
+{
+	u16 bank, i = 0;
+	struct bnx2x *bp = params->bp;
+
+	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
+	      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
+			CL45_WR_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      bank,
+					      MDIO_RX0_RX_EQ_BOOST,
+					      params->xgxs_config_rx[i]);
+	}
 
+	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
+		      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
+			CL45_WR_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      bank,
+					      MDIO_TX0_TX_DRIVER,
+					      params->xgxs_config_tx[i]);
+	}
+}
 
 static void bnx2x_init_internal_phy(struct link_params *params,
 				struct link_vars *vars)
 {
 	struct bnx2x *bp = params->bp;
-	u8 port = params->port;
 	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
-		u16 bank, rx_eq;
-
-		rx_eq = ((params->serdes_config &
-			  PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
-			 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
-
-		DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
-		for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
-		      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
-			CL45_WR_OVER_CL22(bp, port,
-					      params->phy_addr,
-					      bank ,
-					      MDIO_RX0_RX_EQ_BOOST,
-					      ((rx_eq &
-				MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
-				MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
-		}
+		if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+		    (params->feature_config_flags &
+		     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
+			bnx2x_set_preemphasis(params);
 
 		/* forced speed requested? */
 		if (vars->line_speed != SPEED_AUTO_NEG) {
@@ -2506,12 +3032,53 @@ static u8 bnx2x_ext_phy_init(struct link
 				       ext_phy_addr,
 				       MDIO_WIS_DEVAD,
 				       MDIO_WIS_REG_LASI_CNTL, 0x1);
+
+			/* BCM8705 doesn't have microcode, hence the 0 */
+			bnx2x_save_spirom_version(bp, params->port,
+						params->shmem_base, 0);
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-			DP(NETIF_MSG_LINK, "XGXS 8706\n");
-
-			msleep(10);
+			/* Wait until fw is loaded */
+			for (cnt = 0; cnt < 100; cnt++) {
+				bnx2x_cl45_read(bp, params->port, ext_phy_type,
+					      ext_phy_addr, MDIO_PMA_DEVAD,
+					      MDIO_PMA_REG_ROM_VER1, &val);
+				if (val)
+					break;
+				msleep(10);
+			}
+			DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
+				"after %d ms\n", cnt);
+			if ((params->feature_config_flags &
+			     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+				u8 i;
+				u16 reg;
+				for (i = 0; i < 4; i++) {
+					reg = MDIO_XS_8706_REG_BANK_RX0 +
+						i*(MDIO_XS_8706_REG_BANK_RX1 -
+						   MDIO_XS_8706_REG_BANK_RX0);
+					bnx2x_cl45_read(bp, params->port,
+						      ext_phy_type,
+						      ext_phy_addr,
+						      MDIO_XS_DEVAD,
+						      reg, &val);
+					/* Clear first 3 bits of the control */
+					val &= ~0x7;
+					/* Set control bits according to
+					configuation */
+					val |= (params->xgxs_config_rx[i] &
+						0x7);
+					DP(NETIF_MSG_LINK, "Setting RX"
+						 "Equalizer to BCM8706 reg 0x%x"
+						 " <-- val 0x%x\n", reg, val);
+					bnx2x_cl45_write(bp, params->port,
+						       ext_phy_type,
+						       ext_phy_addr,
+						       MDIO_XS_DEVAD,
+						       reg, val);
+				}
+			}
 			/* Force speed */
 			/* First enable LASI */
 			bnx2x_cl45_write(bp, params->port,
@@ -2578,9 +3145,95 @@ static u8 bnx2x_ext_phy_init(struct link
 					       0x1200);
 
 			}
-
+			bnx2x_save_bcm_spirom_ver(bp, params->port,
+						ext_phy_type,
+						ext_phy_addr,
+						params->shmem_base);
 			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+			DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
+			bnx2x_bcm8726_external_rom_boot(params);
 
+			/* Need to call module detected on initialization since
+			the module detection triggered by actual module
+			insertion might occur before driver is loaded, and when
+			driver is loaded, it reset all registers, including the
+			transmitter */
+			bnx2x_sfp_module_detection(params);
+			if (params->req_line_speed == SPEED_1000) {
+				DP(NETIF_MSG_LINK, "Setting 1G force\n");
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_CTRL, 0x40);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_10G_CTRL2, 0xD);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_LASI_CTRL, 0x5);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_RX_ALARM_CTRL,
+					       0x400);
+			} else if ((params->req_line_speed ==
+				    SPEED_AUTO_NEG) &&
+				   ((params->speed_cap_mask &
+				     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
+				DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_ADV, 0x20);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CL37_CL73, 0x040c);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CL37_FC_LD, 0x0020);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CL37_AN, 0x1000);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CTRL, 0x1200);
+
+				/* Enable RX-ALARM control to receive
+				interrupt for 1G speed change */
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_LASI_CTRL, 0x4);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_RX_ALARM_CTRL,
+					       0x400);
+
+			} else { /* Default 10G. Set only LASI control */
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_LASI_CTRL, 1);
+			}
+
+			/* Set TX PreEmphasis if needed */
+			if ((params->feature_config_flags &
+			     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+				DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+					 "TX_CTRL2 0x%x\n",
+					 params->xgxs_config_tx[0],
+					 params->xgxs_config_tx[1]);
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_8726_TX_CTRL1,
+					       params->xgxs_config_tx[0]);
+
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_8726_TX_CTRL2,
+					       params->xgxs_config_tx[1]);
+			}
+			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 		{
@@ -2627,7 +3280,7 @@ static u8 bnx2x_ext_phy_init(struct link
 				      ext_phy_type,
 				      ext_phy_addr,
 				      MDIO_PMA_DEVAD,
-				      0xca13,
+				      MDIO_PMA_REG_M8051_MSGOUT_REG,
 				      &tmp1);
 
 			bnx2x_cl45_read(bp, params->port,
@@ -2694,7 +3347,7 @@ static u8 bnx2x_ext_phy_init(struct link
 					      ext_phy_type,
 					      ext_phy_addr,
 					      MDIO_AN_DEVAD,
-					      0x8329, &tmp1);
+					      MDIO_AN_REG_8073_2_5G, &tmp1);
 
 				if (((params->speed_cap_mask &
 				      PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
@@ -2708,7 +3361,7 @@ static u8 bnx2x_ext_phy_init(struct link
 					 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 					 ext_phy_addr,
 					 MDIO_PMA_DEVAD,
-					 0xc801, &phy_ver);
+					 MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
 					DP(NETIF_MSG_LINK, "Add 2.5G\n");
 					if (phy_ver > 0)
 						tmp1 |= 1;
@@ -2723,7 +3376,7 @@ static u8 bnx2x_ext_phy_init(struct link
 					       ext_phy_type,
 					       ext_phy_addr,
 					       MDIO_AN_DEVAD,
-					       0x8329, tmp1);
+					       MDIO_AN_REG_8073_2_5G, tmp1);
 			}
 
 			/* Add support for CL37 (passive mode) II */
@@ -2798,6 +3451,8 @@ static u8 bnx2x_ext_phy_init(struct link
 			break;
 		}
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+		{
+			u16 fw_ver1, fw_ver2;
 			DP(NETIF_MSG_LINK,
 				"Setting the SFX7101 LASI indication\n");
 
@@ -2827,6 +3482,50 @@ static u8 bnx2x_ext_phy_init(struct link
 				       ext_phy_addr,
 				       MDIO_AN_DEVAD,
 				       MDIO_AN_REG_CTRL, val);
+
+			/* Save spirom version */
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr, MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_7101_VER1, &fw_ver1);
+
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr, MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_7101_VER2, &fw_ver2);
+
+			bnx2x_save_spirom_version(params->bp, params->port,
+						params->shmem_base,
+						(u32)(fw_ver1<<16 | fw_ver2));
+
+			break;
+		}
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+			DP(NETIF_MSG_LINK,
+				"Setting the BCM8481 LASI control\n");
+
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_LASI_CTRL, 0x1);
+
+			/* Restart autoneg */
+			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);
+
+			bnx2x_save_bcm_spirom_ver(bp, params->port,
+						ext_phy_type,
+						ext_phy_addr,
+						params->shmem_base);
+
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
 			DP(NETIF_MSG_LINK,
@@ -2910,38 +3609,43 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-			DP(NETIF_MSG_LINK, "XGXS 8706\n");
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+			DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
+			/* Clear RX Alarm*/
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_PMA_DEVAD,
-				      MDIO_PMA_REG_LASI_STATUS, &val1);
-			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
+				      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+				      &val2);
+			/* clear LASI indication*/
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_PMA_DEVAD,
-				      MDIO_PMA_REG_LASI_STATUS, &val1);
-			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+				      MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+				      &val1);
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+				      &val2);
+			DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
+				     "0x%x\n", val1, val2);
 
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_PMA_DEVAD,
-				      MDIO_PMA_REG_RX_SD, &rx_sd);
+				      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+				      &rx_sd);
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_PCS_DEVAD,
-				      MDIO_PCS_REG_STATUS, &pcs_status);
-
+				      MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+				      &pcs_status);
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_AN_DEVAD,
-				      MDIO_AN_REG_LINK_STATUS, &val2);
+				      MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+				      &val2);
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_AN_DEVAD,
-				      MDIO_AN_REG_LINK_STATUS, &val2);
+				      MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+				      &val2);
 
-			DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
+			DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
 			   "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
 			   rx_sd, pcs_status, val2);
 			/* link is up if both bit 0 of pmd_rx_sd and
@@ -2951,19 +3655,31 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 			ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
 					   (val2 & (1<<1)));
 			if (ext_phy_link_up) {
+				if (ext_phy_type ==
+				     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+					/* If transmitter is disabled,
+					ignore false link up indication */
+					bnx2x_cl45_read(bp, params->port,
+						   ext_phy_type,
+						   ext_phy_addr,
+						   MDIO_PMA_DEVAD,
+						   MDIO_PMA_REG_PHY_IDENTIFIER,
+						   &val1);
+					if (val1 & (1<<15)) {
+						DP(NETIF_MSG_LINK, "Tx is "
+							    "disabled\n");
+						ext_phy_link_up = 0;
+						break;
+					}
+				}
+
 				if (val2 & (1<<1))
 					vars->line_speed = SPEED_1000;
 				else
 					vars->line_speed = SPEED_10000;
 			}
 
-			/* clear LASI indication*/
-			bnx2x_cl45_read(bp, params->port, ext_phy_type,
-				      ext_phy_addr,
-				      MDIO_PMA_DEVAD,
-				      MDIO_PMA_REG_RX_ALARM, &val2);
 			break;
-
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 		{
@@ -3018,7 +3734,7 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 				      ext_phy_type,
 				      ext_phy_addr,
 				      MDIO_PMA_DEVAD,
-				      0xca13,
+				      MDIO_PMA_REG_M8051_MSGOUT_REG,
 				      &val1);
 
 			/* Check the LASI */
@@ -3063,17 +3779,17 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 					}
 				}
 				bnx2x_cl45_read(bp, params->port,
-						      ext_phy_type,
-						      ext_phy_addr,
-						      MDIO_AN_DEVAD,
-						      0x8304,
-						      &an1000_status);
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_LINK_STATUS,
+					      &an1000_status);
 				bnx2x_cl45_read(bp, params->port,
-						      ext_phy_type,
-						      ext_phy_addr,
-						      MDIO_AN_DEVAD,
-						      0x8304,
-						      &an1000_status);
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_LINK_STATUS,
+					      &an1000_status);
 
 				/* Check the link status on 1.1.2 */
 				bnx2x_cl45_read(bp, params->port,
@@ -3090,7 +3806,7 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 					     "an_link_status=0x%x\n",
 					  val2, val1, an1000_status);
 
-					ext_phy_link_up = (((val1 & 4) == 4) ||
+				ext_phy_link_up = (((val1 & 4) == 4) ||
 						(an1000_status & (1<<1)));
 				if (ext_phy_link_up &&
 				    bnx2x_8073_is_snr_needed(params)) {
@@ -3118,11 +3834,11 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 
 				}
 				bnx2x_cl45_read(bp, params->port,
-						      ext_phy_type,
-						      ext_phy_addr,
-						      MDIO_PMA_DEVAD,
-						      0xc820,
-						      &link_status);
+					   ext_phy_type,
+					   ext_phy_addr,
+					   MDIO_PMA_DEVAD,
+					   MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+					   &link_status);
 
 				/* Bits 0..2 --> speed detected,
 				   bits 13..15--> link is down */
@@ -3156,17 +3872,17 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 			} else {
 				/* See if 1G link is up for the 8072 */
 				bnx2x_cl45_read(bp, params->port,
-						      ext_phy_type,
-						      ext_phy_addr,
-						      MDIO_AN_DEVAD,
-						      0x8304,
-						      &an1000_status);
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_LINK_STATUS,
+					      &an1000_status);
 				bnx2x_cl45_read(bp, params->port,
-						      ext_phy_type,
-						      ext_phy_addr,
-						      MDIO_AN_DEVAD,
-						      0x8304,
-						      &an1000_status);
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_LINK_STATUS,
+					      &an1000_status);
 				if (an1000_status & (1<<1)) {
 					ext_phy_link_up = 1;
 					vars->line_speed = SPEED_1000;
@@ -3226,7 +3942,53 @@ static u8 bnx2x_ext_phy_is_link_up(struc
 					 (val2 & (1<<14)));
 			}
 			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+			/* Clear LASI interrupt */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_LASI_STATUS, &val1);
+			DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
+				 val1);
+
+			/* Check 10G-BaseT link status */
+			/* Check Global PMD signal ok */
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+				      &rx_sd);
+			/* Check PCS block lock */
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+				      &pcs_status);
+			DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
+				 rx_sd, pcs_status);
+			if (rx_sd & pcs_status & 0x1) {
+				vars->line_speed = SPEED_10000;
+				ext_phy_link_up = 1;
+			} else {
+
+				/* Check 1000-BaseT link status */
+				bnx2x_cl45_read(bp, params->port, ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD, 0xFFE1,
+					      &val1);
+
+				bnx2x_cl45_read(bp, params->port, ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD, 0xFFE1,
+					      &val2);
+				DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
+					     "0x%x-->0x%x\n", val1, val2);
+				if (val2 & (1<<2)) {
+					vars->line_speed = SPEED_1000;
+					ext_phy_link_up = 1;
+				}
+			}
 
+			break;
 		default:
 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
 			   params->ext_phy_config);
@@ -3426,7 +4188,7 @@ static void bnx2x_turn_on_ef(struct bnx2
 			      ext_phy_addr,
 			      MDIO_PMA_DEVAD,
 			      MDIO_PMA_REG_CTRL,
-			       &ctrl);
+			      &ctrl);
 		if (!(ctrl & (1<<15))) {
 			DP(NETIF_MSG_LINK, "Reset completed\n\n");
 				break;
@@ -3452,91 +4214,39 @@ u8 bnx2x_get_ext_phy_fw_version(struct l
 {
 	struct bnx2x *bp = params->bp;
 	u32 ext_phy_type = 0;
-	u16 val = 0;
-	u8 ext_phy_addr = 0 ;
+	u32 spirom_ver = 0;
 	u8 status = 0 ;
-	u32 ver_num;
 
 	if (version == NULL || params == NULL)
 		return -EINVAL;
 
+	spirom_ver = REG_RD(bp, params->shmem_base +
+		   offsetof(struct shmem_region,
+			    port_mb[params->port].ext_phy_fw_version));
+
 	/* reset the returned value to zero */
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-	ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
 	switch (ext_phy_type) {
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 
 		if (len < 5)
 			return -EINVAL;
 
-		/* Take ext phy out of reset */
-		if (!driver_loaded)
-			bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
-				       ext_phy_type);
-
-		/*  wait for 1ms */
-		msleep(1);
-
-		bnx2x_cl45_read(bp, params->port,
-			      ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_7101_VER1, &val);
-		version[2] = (val & 0xFF);
-		version[3] = ((val & 0xFF00)>>8);
-
-		bnx2x_cl45_read(bp, params->port,
-			      ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
-			      &val);
-		version[0] = (val & 0xFF);
-		version[1] = ((val & 0xFF00)>>8);
+		version[0] = (spirom_ver & 0xFF);
+		version[1] = (spirom_ver & 0xFF00) >> 8;
+		version[2] = (spirom_ver & 0xFF0000) >> 16;
+		version[3] = (spirom_ver & 0xFF000000) >> 24;
 		version[4] = '\0';
 
-		if (!driver_loaded)
-			bnx2x_turn_off_sf(bp, params->port);
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
-	{
-		/* Take ext phy out of reset */
-		if (!driver_loaded)
-			bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
-				       ext_phy_type);
-
-		bnx2x_cl45_read(bp, params->port, ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_ROM_VER1, &val);
-		ver_num = val<<16;
-		bnx2x_cl45_read(bp, params->port, ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_ROM_VER2, &val);
-		ver_num |= val;
-		status = bnx2x_format_ver(ver_num, version, len);
-		break;
-	}
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-
-		bnx2x_cl45_read(bp, params->port, ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_ROM_VER1, &val);
-		ver_num = val<<16;
-		bnx2x_cl45_read(bp, params->port, ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_ROM_VER2, &val);
-		ver_num |= val;
-		status = bnx2x_format_ver(ver_num, version, len);
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+		status = bnx2x_format_ver(spirom_ver, version, len);
 		break;
-
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 		break;
 
@@ -3636,6 +4346,14 @@ static void bnx2x_ext_phy_loopback(struc
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 			DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
 			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+			DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
+			bnx2x_cl45_write(bp, params->port, ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_CTRL,
+				       0x0001);
+			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 			/* SFX7101_XGXS_TEST1 */
 			bnx2x_cl45_write(bp, params->port, ext_phy_type,
@@ -3906,11 +4624,13 @@ static u8 bnx2x_link_initialize(struct l
 
 	/* init ext phy and enable link state int */
 	non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
-		       (params->loopback_mode == LOOPBACK_XGXS_10) ||
-		       (params->loopback_mode == LOOPBACK_EXT_PHY));
+		       (params->loopback_mode == LOOPBACK_XGXS_10));
 
 	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_BCM8705) ||
+	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
+	    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
 		if (params->req_line_speed == SPEED_AUTO_NEG)
 			bnx2x_set_parallel_detection(params, vars->phy_flags);
 		bnx2x_init_internal_phy(params, vars);
@@ -4104,6 +4824,7 @@ u8 bnx2x_phy_init(struct link_params *pa
 			return -EINVAL;
 			break;
 		}
+		DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
 
 		bnx2x_link_initialize(params, vars);
 		msleep(30);
@@ -4112,7 +4833,23 @@ u8 bnx2x_phy_init(struct link_params *pa
 	return 0;
 }
 
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
+static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
+{
+	DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
+
+	/* Set serial boot control for external load */
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_GEN_CTRL, 0x0001);
+
+	/* Disable Transmitter */
+	bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
+
+}
+
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+		  u8 reset_ext_phy)
 {
 
 	struct bnx2x *bp = params->bp;
@@ -4150,28 +4887,37 @@ u8 bnx2x_link_reset(struct link_params *
 	 */
 	 /* clear link led */
 	bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
-	if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
-		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
-		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
+	if (reset_ext_phy) {
+		switch (ext_phy_type) {
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+			DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
+				 "low power mode\n",
+				 port);
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+					  MISC_REGISTERS_GPIO_OUTPUT_LOW,
+					  port);
+			break;
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		{
+			u8 ext_phy_addr = ((params->ext_phy_config &
+					 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+					 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+			/* Set soft reset */
+			bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
+			break;
+		}
+		default:
 			/* HW reset */
-
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
 					  MISC_REGISTERS_GPIO_OUTPUT_LOW,
 					  port);
-
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
 					  MISC_REGISTERS_GPIO_OUTPUT_LOW,
 					  port);
-
 			DP(NETIF_MSG_LINK, "reset external PHY\n");
-		} else if (ext_phy_type ==
-			   PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-				DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
-					 "low power mode\n",
-					 port);
-				bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
-					MISC_REGISTERS_GPIO_OUTPUT_LOW,
-						  port);
 		}
 	}
 	/* reset the SerDes/XGXS */
@@ -4248,7 +4994,7 @@ static u8 bnx2x_update_link_up(struct li
 		if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
 			if (!(vars->phy_flags &
 			      PHY_SGMII_FLAG))
-				bnx2x_set_sgmii_tx_driver(params);
+				bnx2x_set_gmii_tx_driver(params);
 		}
 	}
 
@@ -4337,6 +5083,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_BCM8726) &&
 	    (ext_phy_link_up && !vars->phy_link_up))
 		bnx2x_init_internal_phy(params, vars);
 
@@ -4398,7 +5145,7 @@ static u8 bnx2x_8073_common_init_phy(str
 		u16 fw_ver1;
 
 		bnx2x_bcm8073_external_rom_boot(bp, port,
-						      ext_phy_addr[port]);
+					      ext_phy_addr[port], shmem_base);
 
 		bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
 			      ext_phy_addr[port],
@@ -4434,7 +5181,7 @@ static u8 bnx2x_8073_common_init_phy(str
 
 	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
-		/* Phase2 of POWER_DOWN_RESET*/
+		/* Phase2 of POWER_DOWN_RESET */
 		/* Release bit 10 (Release Tx power down) */
 		bnx2x_cl45_read(bp, port,
 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
@@ -4469,12 +5216,51 @@ static u8 bnx2x_8073_common_init_phy(str
 
 }
 
+
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+{
+	u8 ext_phy_addr;
+	u32 val;
+	s8 port;
+	/* Use port1 because of the static port-swap */
+	/* Enable the module detection interrupt */
+	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
+	val |= ((1<<MISC_REGISTERS_GPIO_3)|
+		(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
+	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
+
+	bnx2x_hw_reset(bp, 1);
+	msleep(5);
+	for (port = 0; port < PORT_MAX; port++) {
+		/* Extract the ext phy address for the port */
+		u32 ext_phy_config = REG_RD(bp, shmem_base +
+					offsetof(struct shmem_region,
+			dev_info.port_hw_config[port].external_phy_config));
+
+		ext_phy_addr =
+			((ext_phy_config &
+			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
+			 ext_phy_addr);
+
+		bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
+
+		/* Set fault module detected LED on */
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+				  MISC_REGISTERS_GPIO_HIGH,
+				  port);
+	}
+
+	return 0;
+}
+
 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 {
 	u8 rc = 0;
 	u32 ext_phy_type;
 
-	DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
+	DP(NETIF_MSG_LINK, "Begin common phy init\n");
 
 	/* Read the ext_phy_type for arbitrary port(0) */
 	ext_phy_type = XGXS_EXT_PHY_TYPE(
@@ -4488,6 +5274,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *b
 		rc = bnx2x_8073_common_init_phy(bp, shmem_base);
 		break;
 	}
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		/* 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;
 	default:
 		DP(NETIF_MSG_LINK,
 			 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_link.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_link.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_link.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_link.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -66,8 +66,6 @@ struct link_params {
 	/* Device parameters */
 	u8 mac_addr[6];
 
-
-
 	/* shmem parameters */
 	u32 shmem_base;
 	u32 speed_cap_mask;
@@ -77,7 +75,6 @@ struct link_params {
 #define SWITCH_CFG_AUTO_DETECT	PORT_FEATURE_CON_SWITCH_AUTO_DETECT
 
 	u16 hw_led_mode; /* part of the hw_config read from the shmem */
-	u32 serdes_config;
 	u32 lane_config;
 	u32 ext_phy_config;
 #define XGXS_EXT_PHY_TYPE(ext_phy_config)	(ext_phy_config & \
@@ -89,6 +86,12 @@ struct link_params {
 
 	/* phy_addr populated by the CLC */
 	u8 phy_addr;
+	u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
+
+	u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
+	u32 feature_config_flags;
+#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
+#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED	(2<<0)
 	/* Device pointer passed to all callback functions */
 	struct bnx2x *bp;
 };
@@ -125,8 +128,11 @@ struct link_vars {
 /* Initialize the phy */
 u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
 
-/* Reset the link. Should be called when driver or interface goes down */
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars);
+/* Reset the link. Should be called when driver or interface goes down
+   Before calling phy firmware upgrade, the reset_ext_phy should be set
+   to 0 */
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+		  u8 reset_ext_phy);
 
 /* bnx2x_link_update should be called upon link interrupt */
 u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x
 
 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
 		      u8 driver_loaded, char data[], u32 size);
+/* bnx2x_handle_module_detect_int should be called upon module detection
+   interrupt */
+void bnx2x_handle_module_detect_int(struct link_params *params);
+
 /* Get the actual link status. In case it returns 0, link is up,
 	otherwise link is down*/
 u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
@@ -170,4 +180,5 @@ u8 bnx2x_test_link(struct link_params *i
 /* One-time initialization for external phy after power up */
 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
 
+
 #endif /* BNX2X_LINK_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_main.c linux-libre-2.6.30-gnu1/drivers/net/bnx2x_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_main.c	2013-05-03 18:02:42.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_main.c	2013-05-03 16:46:34.000000000 -0400
@@ -50,18 +50,16 @@
 #include <linux/zlib.h>
 #include <linux/io.h>
 
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
+
 #include "bnx2x.h"
 #include "bnx2x_init.h"
+#include "bnx2x_dump.h"
 #define bnx2x_init_block(bp, start, end) \
   return (printk(KERN_ERR PFX "%s: Missing Free firmware\n", bp->dev->name),\
 	  -EINVAL)
 
-#define DRV_MODULE_VERSION	"1.45.27"
-#define DRV_MODULE_RELDATE	"2009/01/26"
+#define DRV_MODULE_VERSION	"1.48.105"
+#define DRV_MODULE_RELDATE	"2009/03/02"
 #define BNX2X_BC_VER		0x040200
 
 /* Time in jiffies before concluding the transmitter is hung */
@@ -76,26 +74,32 @@ MODULE_DESCRIPTION("Broadcom NetXtreme I
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-static int disable_tpa;
-static int use_inta;
-static int poll;
-static int debug;
-static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-static int use_multi;
+static int multi_mode = 1;
+module_param(multi_mode, int, 0);
+MODULE_PARM_DESC(multi_mode, " Use per-CPU queues");
 
+static int disable_tpa;
 module_param(disable_tpa, int, 0);
-module_param(use_inta, int, 0);
+MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
+
+static int int_mode;
+module_param(int_mode, int, 0);
+MODULE_PARM_DESC(int_mode, " Force interrupt mode (1 INT#x; 2 MSI)");
+
+static int poll;
 module_param(poll, int, 0);
+MODULE_PARM_DESC(poll, " Use polling (for debug)");
+
+static int mrrs = -1;
+module_param(mrrs, int, 0);
+MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)");
+
+static int debug;
 module_param(debug, int, 0);
-MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
-MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
+MODULE_PARM_DESC(debug, " Default debug msglevel");
+
+static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
 
-#ifdef BNX2X_MULTI
-module_param(use_multi, int, 0);
-MODULE_PARM_DESC(use_multi, "use per-CPU queues");
-#endif
 static struct workqueue_struct *bnx2x_wq;
 
 enum bnx2x_board_type {
@@ -216,7 +220,7 @@ void bnx2x_write_dmae(struct bnx2x *bp,
 	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
 	dmae->comp_val = DMAE_COMP_VAL;
 
-	DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+	DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
 	   DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
 		    "dst_addr [%x:%08x (%08x)]\n"
 	   DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
@@ -237,7 +241,7 @@ void bnx2x_write_dmae(struct bnx2x *bp,
 		DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
 
 		if (!cnt) {
-			BNX2X_ERR("dmae timeout!\n");
+			BNX2X_ERR("DMAE timeout!\n");
 			break;
 		}
 		cnt--;
@@ -292,7 +296,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u
 	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
 	dmae->comp_val = DMAE_COMP_VAL;
 
-	DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+	DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
 	   DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
 		    "dst_addr [%x:%08x (%08x)]\n"
 	   DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
@@ -309,7 +313,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u
 	while (*wb_comp != DMAE_COMP_VAL) {
 
 		if (!cnt) {
-			BNX2X_ERR("dmae timeout!\n");
+			BNX2X_ERR("DMAE timeout!\n");
 			break;
 		}
 		cnt--;
@@ -471,7 +475,7 @@ static int bnx2x_mc_assert(struct bnx2x
 static void bnx2x_fw_dump(struct bnx2x *bp)
 {
 	u32 mark, offset;
-	u32 data[9];
+	__be32 data[9];
 	int word;
 
 	mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
@@ -505,82 +509,103 @@ static void bnx2x_panic_dump(struct bnx2
 
 	BNX2X_ERR("begin crash dump -----------------\n");
 
-	for_each_queue(bp, i) {
+	/* Indices */
+	/* Common */
+	BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_x_idx(%u)"
+		  "  def_t_idx(%u)  def_att_idx(%u)  attn_state(%u)"
+		  "  spq_prod_idx(%u)\n",
+		  bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
+		  bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+	/* Rx */
+	for_each_rx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
-		struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
 
-		BNX2X_ERR("queue[%d]: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
-			  "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)\n",
-			  i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
-			  fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
-		BNX2X_ERR("          rx_bd_prod(%x)  rx_bd_cons(%x)"
+		BNX2X_ERR("fp%d: rx_bd_prod(%x)  rx_bd_cons(%x)"
 			  "  *rx_bd_cons_sb(%x)  rx_comp_prod(%x)"
 			  "  rx_comp_cons(%x)  *rx_cons_sb(%x)\n",
-			  fp->rx_bd_prod, fp->rx_bd_cons,
+			  i, fp->rx_bd_prod, fp->rx_bd_cons,
 			  le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
 			  fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
-		BNX2X_ERR("          rx_sge_prod(%x)  last_max_sge(%x)"
-			  "  fp_c_idx(%x)  *sb_c_idx(%x)  fp_u_idx(%x)"
-			  "  *sb_u_idx(%x)  bd data(%x,%x)\n",
-			  fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
-			  fp->status_blk->c_status_block.status_block_index,
-			  fp->fp_u_idx,
-			  fp->status_blk->u_status_block.status_block_index,
-			  hw_prods->packets_prod, hw_prods->bds_prod);
-
-		start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
-		end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
-		for (j = start; j < end; j++) {
-			struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+		BNX2X_ERR("      rx_sge_prod(%x)  last_max_sge(%x)"
+			  "  fp_u_idx(%x) *sb_u_idx(%x)\n",
+			  fp->rx_sge_prod, fp->last_max_sge,
+			  le16_to_cpu(fp->fp_u_idx),
+			  fp->status_blk->u_status_block.status_block_index);
+	}
 
-			BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
-				  sw_bd->skb, sw_bd->first_bd);
-		}
+	/* Tx */
+	for_each_tx_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+		struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
 
-		start = TX_BD(fp->tx_bd_cons - 10);
-		end = TX_BD(fp->tx_bd_cons + 254);
-		for (j = start; j < end; j++) {
-			u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+		BNX2X_ERR("fp%d: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
+			  "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)\n",
+			  i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+			  fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+		BNX2X_ERR("      fp_c_idx(%x)  *sb_c_idx(%x)"
+			  "  bd data(%x,%x)\n", le16_to_cpu(fp->fp_c_idx),
+			  fp->status_blk->c_status_block.status_block_index,
+			  hw_prods->packets_prod, hw_prods->bds_prod);
+	}
 
-			BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
-				  j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
-		}
+	/* Rings */
+	/* Rx */
+	for_each_rx_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
 		end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
-		for (j = start; j < end; j++) {
+		for (j = start; j != end; j = RX_BD(j + 1)) {
 			u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
 			struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
 
-			BNX2X_ERR("rx_bd[%x]=[%x:%x]  sw_bd=[%p]\n",
-				  j, rx_bd[1], rx_bd[0], sw_bd->skb);
+			BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x]  sw_bd=[%p]\n",
+				  i, j, rx_bd[1], rx_bd[0], sw_bd->skb);
 		}
 
 		start = RX_SGE(fp->rx_sge_prod);
 		end = RX_SGE(fp->last_max_sge);
-		for (j = start; j < end; j++) {
+		for (j = start; j != end; j = RX_SGE(j + 1)) {
 			u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
 			struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
 
-			BNX2X_ERR("rx_sge[%x]=[%x:%x]  sw_page=[%p]\n",
-				  j, rx_sge[1], rx_sge[0], sw_page->page);
+			BNX2X_ERR("fp%d: rx_sge[%x]=[%x:%x]  sw_page=[%p]\n",
+				  i, j, rx_sge[1], rx_sge[0], sw_page->page);
 		}
 
 		start = RCQ_BD(fp->rx_comp_cons - 10);
 		end = RCQ_BD(fp->rx_comp_cons + 503);
-		for (j = start; j < end; j++) {
+		for (j = start; j != end; j = RCQ_BD(j + 1)) {
 			u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
 
-			BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
-				  j, cqe[0], cqe[1], cqe[2], cqe[3]);
+			BNX2X_ERR("fp%d: cqe[%x]=[%x:%x:%x:%x]\n",
+				  i, j, cqe[0], cqe[1], cqe[2], cqe[3]);
 		}
 	}
 
-	BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_x_idx(%u)"
-		  "  def_t_idx(%u)  def_att_idx(%u)  attn_state(%u)"
-		  "  spq_prod_idx(%u)\n",
-		  bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
-		  bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+	/* Tx */
+	for_each_tx_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+		end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+		for (j = start; j != end; j = TX_BD(j + 1)) {
+			struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+			BNX2X_ERR("fp%d: packet[%x]=[%p,%x]\n",
+				  i, j, sw_bd->skb, sw_bd->first_bd);
+		}
+
+		start = TX_BD(fp->tx_bd_cons - 10);
+		end = TX_BD(fp->tx_bd_cons + 254);
+		for (j = start; j != end; j = TX_BD(j + 1)) {
+			u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+			BNX2X_ERR("fp%d: tx_bd[%x]=[%x:%x:%x:%x]\n",
+				  i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+		}
+	}
 
 	bnx2x_fw_dump(bp);
 	bnx2x_mc_assert(bp);
@@ -593,37 +618,44 @@ static void bnx2x_int_enable(struct bnx2
 	u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
 	u32 val = REG_RD(bp, addr);
 	int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+	int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0;
 
 	if (msix) {
-		val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
+		val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+			 HC_CONFIG_0_REG_INT_LINE_EN_0);
 		val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
 			HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+	} else if (msi) {
+		val &= ~HC_CONFIG_0_REG_INT_LINE_EN_0;
+		val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+			HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+			HC_CONFIG_0_REG_ATTN_BIT_EN_0);
 	} else {
 		val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
 			HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
 			HC_CONFIG_0_REG_INT_LINE_EN_0 |
 			HC_CONFIG_0_REG_ATTN_BIT_EN_0);
 
-		DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  MSI-X %d\n",
-		   val, port, addr, msix);
+		DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+		   val, port, addr);
 
 		REG_WR(bp, addr, val);
 
 		val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
 	}
 
-	DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  MSI-X %d\n",
-	   val, port, addr, msix);
+	DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  mode %s\n",
+	   val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
 
 	REG_WR(bp, addr, val);
 
 	if (CHIP_IS_E1H(bp)) {
 		/* init leading/trailing edge */
 		if (IS_E1HMF(bp)) {
-			val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
+			val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
 			if (bp->port.pmf)
-				/* enable nig attention */
-				val |= 0x0100;
+				/* enable nig and gpio3 attention */
+				val |= 0x1100;
 		} else
 			val = 0xffff;
 
@@ -646,15 +678,19 @@ static void bnx2x_int_disable(struct bnx
 	DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
 	   val, port, addr);
 
+	/* flush all outstanding writes */
+	mmiowb();
+
 	REG_WR(bp, addr, val);
 	if (REG_RD(bp, addr) != val)
 		BNX2X_ERR("BUG! proper val not read from IGU!\n");
+
 }
 
 static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
 {
 	int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
-	int i;
+	int i, offset;
 
 	/* disable interrupt handling */
 	atomic_inc(&bp->intr_sem);
@@ -664,11 +700,10 @@ static void bnx2x_int_disable_sync(struc
 
 	/* make sure all ISRs are done */
 	if (msix) {
+		synchronize_irq(bp->msix_table[0].vector);
+		offset = 1;
 		for_each_queue(bp, i)
-			synchronize_irq(bp->msix_table[i].vector);
-
-		/* one more for the Slow Path IRQ */
-		synchronize_irq(bp->msix_table[i].vector);
+			synchronize_irq(bp->msix_table[i + offset].vector);
 	} else
 		synchronize_irq(bp->pdev->irq);
 
@@ -751,7 +786,6 @@ static inline int bnx2x_has_tx_work_unlo
 	/* Tell compiler that consumer and producer can change */
 	barrier();
 	return (fp->tx_pkt_prod != fp->tx_pkt_cons);
-
 }
 
 /* free skb in the packet ring at pos idx
@@ -845,9 +879,10 @@ static inline u16 bnx2x_tx_avail(struct
 	return (s16)(fp->bp->tx_ring_size) - used;
 }
 
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+static void 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;
 
@@ -856,6 +891,7 @@ static void bnx2x_tx_int(struct bnx2x_fa
 		return;
 #endif
 
+	txq = netdev_get_tx_queue(bp->dev, fp->index);
 	hw_cons = le16_to_cpu(*fp->tx_cons_sb);
 	sw_cons = fp->tx_pkt_cons;
 
@@ -877,32 +913,30 @@ static void bnx2x_tx_int(struct bnx2x_fa
 		bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
 		sw_cons++;
 		done++;
-
-		if (done == work)
-			break;
 	}
 
 	fp->tx_pkt_cons = sw_cons;
 	fp->tx_bd_cons = bd_cons;
 
-	/* Need to make the tx_cons update visible to start_xmit()
-	 * before checking for netif_queue_stopped().  Without the
-	 * memory barrier, there is a small possibility that start_xmit()
-	 * will miss it and cause the queue to be stopped forever.
-	 */
-	smp_mb();
-
 	/* TBD need a thresh? */
-	if (unlikely(netif_queue_stopped(bp->dev))) {
+	if (unlikely(netif_tx_queue_stopped(txq))) {
 
-		netif_tx_lock(bp->dev);
+		__netif_tx_lock(txq, smp_processor_id());
 
-		if (netif_queue_stopped(bp->dev) &&
+		/* Need to make the tx_bd_cons update visible to start_xmit()
+		 * before checking for netif_tx_queue_stopped().  Without the
+		 * memory barrier, there is a small possibility that
+		 * start_xmit() will miss it and cause the queue to be stopped
+		 * forever.
+		 */
+		smp_mb();
+
+		if ((netif_tx_queue_stopped(txq)) &&
 		    (bp->state == BNX2X_STATE_OPEN) &&
 		    (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
-			netif_wake_queue(bp->dev);
+			netif_tx_wake_queue(txq);
 
-		netif_tx_unlock(bp->dev);
+		__netif_tx_unlock(txq);
 	}
 }
 
@@ -916,12 +950,12 @@ static void bnx2x_sp_event(struct bnx2x_
 
 	DP(BNX2X_MSG_SP,
 	   "fp %d  cid %d  got ramrod #%d  state is %x  type is %d\n",
-	   FP_IDX(fp), cid, command, bp->state,
+	   fp->index, cid, command, bp->state,
 	   rr_cqe->ramrod_cqe.ramrod_type);
 
 	bp->spq_left++;
 
-	if (FP_IDX(fp)) {
+	if (fp->index) {
 		switch (command | fp->state) {
 		case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
 						BNX2X_FP_STATE_OPENING):
@@ -1081,8 +1115,7 @@ static void bnx2x_reuse_rx_skb(struct bn
 
 	pci_dma_sync_single_for_device(bp->pdev,
 				       pci_unmap_addr(cons_rx_buf, mapping),
-				       bp->rx_offset + RX_COPY_THRESH,
-				       PCI_DMA_FROMDEVICE);
+				       RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 
 	prod_rx_buf->skb = cons_rx_buf->skb;
 	pci_unmap_addr_set(prod_rx_buf, mapping,
@@ -1263,7 +1296,7 @@ static int bnx2x_fill_frag_skb(struct bn
 		   where we are and drop the whole packet */
 		err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
 		if (unlikely(err)) {
-			bp->eth_stats.rx_skb_alloc_failed++;
+			fp->eth_q_stats.rx_skb_alloc_failed++;
 			return err;
 		}
 
@@ -1368,7 +1401,7 @@ static void bnx2x_tpa_stop(struct bnx2x
 		/* else drop the packet and keep the buffer in the bin */
 		DP(NETIF_MSG_RX_STATUS,
 		   "Failed to allocate new skb - dropping packet!\n");
-		bp->eth_stats.rx_skb_alloc_failed++;
+		fp->eth_q_stats.rx_skb_alloc_failed++;
 	}
 
 	fp->tpa_state[queue] = BNX2X_TPA_STOP;
@@ -1379,7 +1412,7 @@ static inline void bnx2x_update_rx_prod(
 					u16 bd_prod, u16 rx_comp_prod,
 					u16 rx_sge_prod)
 {
-	struct tstorm_eth_rx_producers rx_prods = {0};
+	struct ustorm_eth_rx_producers rx_prods = {0};
 	int i;
 
 	/* Update producers */
@@ -1397,16 +1430,16 @@ static inline void bnx2x_update_rx_prod(
 	 */
 	wmb();
 
-	for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
-		REG_WR(bp, BAR_TSTRORM_INTMEM +
-		       TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+	for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++)
+		REG_WR(bp, BAR_USTRORM_INTMEM +
+		       USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4,
 		       ((u32 *)&rx_prods)[i]);
 
 	mmiowb(); /* keep prod updates ordered */
 
 	DP(NETIF_MSG_RX_STATUS,
-	   "Wrote: bd_prod %u  cqe_prod %u  sge_prod %u\n",
-	   bd_prod, rx_comp_prod, rx_sge_prod);
+	   "queue[%d]:  wrote  bd_prod %u  cqe_prod %u  sge_prod %u\n",
+	   fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
 }
 
 static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
@@ -1440,7 +1473,7 @@ static int bnx2x_rx_int(struct bnx2x_fas
 
 	DP(NETIF_MSG_RX_STATUS,
 	   "queue[%d]:  hw_comp_cons %u  sw_comp_cons %u\n",
-	   FP_IDX(fp), hw_comp_cons, sw_comp_cons);
+	   fp->index, hw_comp_cons, sw_comp_cons);
 
 	while (sw_comp_cons != hw_comp_cons) {
 		struct sw_rx_bd *rx_buf = NULL;
@@ -1530,7 +1563,7 @@ static int bnx2x_rx_int(struct bnx2x_fas
 				DP(NETIF_MSG_RX_ERR,
 				   "ERROR  flags %x  rx packet %u\n",
 				   cqe_fp_flags, sw_comp_cons);
-				bp->eth_stats.rx_err_discard_pkt++;
+				fp->eth_q_stats.rx_err_discard_pkt++;
 				goto reuse_rx;
 			}
 
@@ -1547,7 +1580,7 @@ static int bnx2x_rx_int(struct bnx2x_fas
 					DP(NETIF_MSG_RX_ERR,
 					   "ERROR  packet dropped "
 					   "because of alloc failure\n");
-					bp->eth_stats.rx_skb_alloc_failed++;
+					fp->eth_q_stats.rx_skb_alloc_failed++;
 					goto reuse_rx;
 				}
 
@@ -1573,7 +1606,7 @@ static int bnx2x_rx_int(struct bnx2x_fas
 				DP(NETIF_MSG_RX_ERR,
 				   "ERROR  packet dropped because "
 				   "of alloc failure\n");
-				bp->eth_stats.rx_skb_alloc_failed++;
+				fp->eth_q_stats.rx_skb_alloc_failed++;
 reuse_rx:
 				bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
 				goto next_rx;
@@ -1586,10 +1619,11 @@ reuse_rx:
 				if (likely(BNX2X_RX_CSUM_OK(cqe)))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
 				else
-					bp->eth_stats.hw_csum_err++;
+					fp->eth_q_stats.hw_csum_err++;
 			}
 		}
 
+		skb_record_rx_queue(skb, fp->index);
 #ifdef BCM_VLAN
 		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
 		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
@@ -1635,7 +1669,7 @@ static irqreturn_t bnx2x_msix_fp_int(int
 {
 	struct bnx2x_fastpath *fp = fp_cookie;
 	struct bnx2x *bp = fp->bp;
-	int index = FP_IDX(fp);
+	int index = fp->index;
 
 	/* Return here if interrupt is disabled */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1644,8 +1678,8 @@ static irqreturn_t bnx2x_msix_fp_int(int
 	}
 
 	DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
-	   index, FP_SB_ID(fp));
-	bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
+	   index, fp->sb_id);
+	bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
@@ -1657,15 +1691,14 @@ static irqreturn_t bnx2x_msix_fp_int(int
 	prefetch(&fp->status_blk->c_status_block.status_block_index);
 	prefetch(&fp->status_blk->u_status_block.status_block_index);
 
-	netif_rx_schedule(&bnx2x_fp(bp, index, napi));
+	napi_schedule(&bnx2x_fp(bp, index, napi));
 
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
 {
-	struct net_device *dev = dev_instance;
-	struct bnx2x *bp = netdev_priv(dev);
+	struct bnx2x *bp = netdev_priv(dev_instance);
 	u16 status = bnx2x_ack_int(bp);
 	u16 mask;
 
@@ -1674,7 +1707,7 @@ static irqreturn_t bnx2x_interrupt(int i
 		DP(NETIF_MSG_INTR, "not our interrupt!\n");
 		return IRQ_NONE;
 	}
-	DP(NETIF_MSG_INTR, "got an interrupt  status %u\n", status);
+	DP(NETIF_MSG_INTR, "got an interrupt  status 0x%x\n", status);
 
 	/* Return here if interrupt is disabled */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1696,7 +1729,7 @@ static irqreturn_t bnx2x_interrupt(int i
 		prefetch(&fp->status_blk->c_status_block.status_block_index);
 		prefetch(&fp->status_blk->u_status_block.status_block_index);
 
-		netif_rx_schedule(&bnx2x_fp(bp, 0, napi));
+		napi_schedule(&bnx2x_fp(bp, 0, napi));
 
 		status &= ~mask;
 	}
@@ -1809,26 +1842,50 @@ static int bnx2x_release_hw_lock(struct
 /* HW Lock for shared dual port PHYs */
 static void bnx2x_acquire_phy_lock(struct bnx2x *bp)
 {
-	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
 	mutex_lock(&bp->port.phy_mutex);
 
-	if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
-	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
-		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+	if (bp->port.need_hw_lock)
+		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
 }
 
 static void bnx2x_release_phy_lock(struct bnx2x *bp)
 {
-	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
-	if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
-	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
-		bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+	if (bp->port.need_hw_lock)
+		bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
 
 	mutex_unlock(&bp->port.phy_mutex);
 }
 
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port)
+{
+	/* The GPIO should be swapped if swap register is set and active */
+	int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+			 REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+	int gpio_shift = gpio_num +
+			(gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+	u32 gpio_mask = (1 << gpio_shift);
+	u32 gpio_reg;
+	int value;
+
+	if (gpio_num > MISC_REGISTERS_GPIO_3) {
+		BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+		return -EINVAL;
+	}
+
+	/* read GPIO value */
+	gpio_reg = REG_RD(bp, MISC_REG_GPIO);
+
+	/* get the requested pin value */
+	if ((gpio_reg & gpio_mask) == gpio_mask)
+		value = 1;
+	else
+		value = 0;
+
+	DP(NETIF_MSG_LINK, "pin %d  value 0x%x\n", gpio_num, value);
+
+	return value;
+}
+
 int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
 {
 	/* The GPIO should be swapped if swap register is set and active */
@@ -1882,6 +1939,52 @@ int bnx2x_set_gpio(struct bnx2x *bp, int
 	return 0;
 }
 
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
+{
+	/* The GPIO should be swapped if swap register is set and active */
+	int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+			 REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+	int gpio_shift = gpio_num +
+			(gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+	u32 gpio_mask = (1 << gpio_shift);
+	u32 gpio_reg;
+
+	if (gpio_num > MISC_REGISTERS_GPIO_3) {
+		BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+		return -EINVAL;
+	}
+
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+	/* read GPIO int */
+	gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT);
+
+	switch (mode) {
+	case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR:
+		DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> "
+				   "output low\n", gpio_num, gpio_shift);
+		/* clear SET and set CLR */
+		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+		gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+		break;
+
+	case MISC_REGISTERS_GPIO_INT_OUTPUT_SET:
+		DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> "
+				   "output high\n", gpio_num, gpio_shift);
+		/* clear CLR and set SET */
+		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+		gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+		break;
+
+	default:
+		break;
+	}
+
+	REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg);
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+
+	return 0;
+}
+
 static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
 {
 	u32 spio_mask = (1 << spio_num);
@@ -1936,13 +2039,16 @@ static void bnx2x_calc_fc_adv(struct bnx
 		bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
 					  ADVERTISED_Pause);
 		break;
+
 	case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
 		bp->port.advertising |= (ADVERTISED_Asym_Pause |
 					 ADVERTISED_Pause);
 		break;
+
 	case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
 		bp->port.advertising |= ADVERTISED_Asym_Pause;
 		break;
+
 	default:
 		bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
 					  ADVERTISED_Pause);
@@ -1967,7 +2073,8 @@ static void bnx2x_link_report(struct bnx
 		if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
 			if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
 				printk(", receive ");
-				if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+				if (bp->link_vars.flow_ctrl &
+				    BNX2X_FLOW_CTRL_TX)
 					printk("& transmit ");
 			} else {
 				printk(", transmit ");
@@ -1982,7 +2089,7 @@ static void bnx2x_link_report(struct bnx
 	}
 }
 
-static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
+static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
 {
 	if (!BP_NOMCP(bp)) {
 		u8 rc;
@@ -1998,18 +2105,24 @@ static u8 bnx2x_initial_phy_init(struct
 			bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
 
 		bnx2x_acquire_phy_lock(bp);
+
+		if (load_mode == LOAD_DIAG)
+			bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+
 		rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+
 		bnx2x_release_phy_lock(bp);
 
 		bnx2x_calc_fc_adv(bp);
 
-		if (bp->link_vars.link_up)
+		if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) {
+			bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
 			bnx2x_link_report(bp);
-
+		}
 
 		return rc;
 	}
-	BNX2X_ERR("Bootcode is missing -not initializing link\n");
+	BNX2X_ERR("Bootcode is missing - can not initialize link\n");
 	return -EINVAL;
 }
 
@@ -2022,17 +2135,17 @@ static void bnx2x_link_set(struct bnx2x
 
 		bnx2x_calc_fc_adv(bp);
 	} else
-		BNX2X_ERR("Bootcode is missing -not setting link\n");
+		BNX2X_ERR("Bootcode is missing - can not set link\n");
 }
 
 static void bnx2x__link_reset(struct bnx2x *bp)
 {
 	if (!BP_NOMCP(bp)) {
 		bnx2x_acquire_phy_lock(bp);
-		bnx2x_link_reset(&bp->link_params, &bp->link_vars);
+		bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
 		bnx2x_release_phy_lock(bp);
 	} else
-		BNX2X_ERR("Bootcode is missing -not resetting link\n");
+		BNX2X_ERR("Bootcode is missing - can not reset link\n");
 }
 
 static u8 bnx2x_link_test(struct bnx2x *bp)
@@ -2046,119 +2159,42 @@ static u8 bnx2x_link_test(struct bnx2x *
 	return rc;
 }
 
-/* Calculates the sum of vn_min_rates.
-   It's needed for further normalizing of the min_rates.
-
-   Returns:
-     sum of vn_min_rates
-       or
-     0 - if all the min_rates are 0.
-     In the later case fairness algorithm should be deactivated.
-     If not all min_rates are zero then those that are zeroes will
-     be set to 1.
- */
-static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
-{
-	int i, port = BP_PORT(bp);
-	u32 wsum = 0;
-	int all_zero = 1;
-
-	for (i = 0; i < E1HVN_MAX; i++) {
-		u32 vn_cfg =
-			SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
-		u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
-				     FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
-		if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
-			/* If min rate is zero - set it to 1 */
-			if (!vn_min_rate)
-				vn_min_rate = DEF_MIN_RATE;
-			else
-				all_zero = 0;
-
-			wsum += vn_min_rate;
-		}
-	}
-
-	/* ... only if all min rates are zeros - disable FAIRNESS */
-	if (all_zero)
-		return 0;
-
-	return wsum;
-}
-
-static void bnx2x_init_port_minmax(struct bnx2x *bp,
-				   int en_fness,
-				   u16 port_rate,
-				   struct cmng_struct_per_port *m_cmng_port)
+static void bnx2x_init_port_minmax(struct bnx2x *bp)
 {
-	u32 r_param = port_rate / 8;
-	int port = BP_PORT(bp);
-	int i;
-
-	memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
-
-	/* Enable minmax only if we are in e1hmf mode */
-	if (IS_E1HMF(bp)) {
-		u32 fair_periodic_timeout_usec;
-		u32 t_fair;
-
-		/* Enable rate shaping and fairness */
-		m_cmng_port->flags.cmng_vn_enable = 1;
-		m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
-		m_cmng_port->flags.rate_shaping_enable = 1;
+	u32 r_param = bp->link_vars.line_speed / 8;
+	u32 fair_periodic_timeout_usec;
+	u32 t_fair;
 
-		if (!en_fness)
-			DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
-			   "  fairness will be disabled\n");
+	memset(&(bp->cmng.rs_vars), 0,
+	       sizeof(struct rate_shaping_vars_per_port));
+	memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
 
-		/* 100 usec in SDM ticks = 25 since each tick is 4 usec */
-		m_cmng_port->rs_vars.rs_periodic_timeout =
-						RS_PERIODIC_TIMEOUT_USEC / 4;
+	/* 100 usec in SDM ticks = 25 since each tick is 4 usec */
+	bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
 
-		/* this is the threshold below which no timer arming will occur
-		   1.25 coefficient is for the threshold to be a little bigger
-		   than the real time, to compensate for timer in-accuracy */
-		m_cmng_port->rs_vars.rs_threshold =
+	/* this is the threshold below which no timer arming will occur
+	   1.25 coefficient is for the threshold to be a little bigger
+	   than the real time, to compensate for timer in-accuracy */
+	bp->cmng.rs_vars.rs_threshold =
 				(RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
 
-		/* resolution of fairness timer */
-		fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
-		/* for 10G it is 1000usec. for 1G it is 10000usec. */
-		t_fair = T_FAIR_COEF / port_rate;
-
-		/* this is the threshold below which we won't arm
-		   the timer anymore */
-		m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
-
-		/* we multiply by 1e3/8 to get bytes/msec.
-		   We don't want the credits to pass a credit
-		   of the T_FAIR*FAIR_MEM (algorithm resolution) */
-		m_cmng_port->fair_vars.upper_bound =
-						r_param * t_fair * FAIR_MEM;
-		/* since each tick is 4 usec */
-		m_cmng_port->fair_vars.fairness_timeout =
-						fair_periodic_timeout_usec / 4;
-
-	} else {
-		/* Disable rate shaping and fairness */
-		m_cmng_port->flags.cmng_vn_enable = 0;
-		m_cmng_port->flags.fairness_enable = 0;
-		m_cmng_port->flags.rate_shaping_enable = 0;
+	/* resolution of fairness timer */
+	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+	/* for 10G it is 1000usec. for 1G it is 10000usec. */
+	t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
 
-		DP(NETIF_MSG_IFUP,
-		   "Single function mode  minmax will be disabled\n");
-	}
+	/* this is the threshold below which we won't arm the timer anymore */
+	bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
 
-	/* Store it to internal memory */
-	for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
-		REG_WR(bp, BAR_XSTRORM_INTMEM +
-		       XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
-		       ((u32 *)(m_cmng_port))[i]);
+	/* we multiply by 1e3/8 to get bytes/msec.
+	   We don't want the credits to pass a credit
+	   of the t_fair*FAIR_MEM (algorithm resolution) */
+	bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
+	/* since each tick is 4 usec */
+	bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
 }
 
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
-				   u32 wsum, u16 port_rate,
-				 struct cmng_struct_per_port *m_cmng_port)
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
 {
 	struct rate_shaping_vars_per_vn m_rs_vn;
 	struct fairness_vars_per_vn m_fair_vn;
@@ -2174,17 +2210,18 @@ 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 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 ((vn_min_rate == 0) && wsum)
+		if (bp->vn_weight_sum && (vn_min_rate == 0))
 			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  "
-	   "wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
+	DP(NETIF_MSG_IFUP,
+	   "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));
 	memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
@@ -2196,55 +2233,20 @@ static void bnx2x_init_vn_minmax(struct
 	m_rs_vn.vn_counter.quota =
 				(vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
 
-#ifdef BNX2X_PER_PROT_QOS
-	/* per protocol counter */
-	for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
-		/* maximal Mbps for this protocol */
-		m_rs_vn.protocol_counters[protocol].rate =
-						protocol_max_rate[protocol];
-		/* the quota in each timer period -
-		   number of bytes transmitted in this period */
-		m_rs_vn.protocol_counters[protocol].quota =
-			(u32)(rs_periodic_timeout_usec *
-			  ((double)m_rs_vn.
-				   protocol_counters[protocol].rate/8));
-	}
-#endif
-
-	if (wsum) {
+	if (bp->vn_weight_sum) {
 		/* credit for each period of the fairness algorithm:
 		   number of bytes in T_FAIR (the vn share the port rate).
-		   wsum should not be larger than 10000, thus
-		   T_FAIR_COEF / (8 * wsum) will always be grater than zero */
+		   vn_weight_sum should not be larger than 10000, thus
+		   T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
+		   than zero */
 		m_fair_vn.vn_credit_delta =
-			max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
-			    (u64)(m_cmng_port->fair_vars.fair_threshold * 2));
+			max((u32)(vn_min_rate * (T_FAIR_COEF /
+						 (8 * bp->vn_weight_sum))),
+			    (u32)(bp->cmng.fair_vars.fair_threshold * 2));
 		DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
 		   m_fair_vn.vn_credit_delta);
 	}
 
-#ifdef BNX2X_PER_PROT_QOS
-	do {
-		u32 protocolWeightSum = 0;
-
-		for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
-			protocolWeightSum +=
-					drvInit.protocol_min_rate[protocol];
-		/* per protocol counter -
-		   NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
-		if (protocolWeightSum > 0) {
-			for (protocol = 0;
-			     protocol < NUM_OF_PROTOCOLS; protocol++)
-				/* credit for each period of the
-				   fairness algorithm - number of bytes in
-				   T_FAIR (the protocol share the vn rate) */
-				m_fair_vn.protocol_credit_delta[protocol] =
-					(u32)((vn_min_rate / 8) * t_fair *
-					protocol_min_rate / protocolWeightSum);
-		}
-	} while (0);
-#endif
-
 	/* Store it to internal memory */
 	for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
 		REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -2257,11 +2259,10 @@ static void bnx2x_init_vn_minmax(struct
 		       ((u32 *)(&m_fair_vn))[i]);
 }
 
+
 /* This function is called upon link interrupt */
 static void bnx2x_link_attn(struct bnx2x *bp)
 {
-	int vn;
-
 	/* Make sure that we are synced with the current statistics */
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
@@ -2269,6 +2270,19 @@ static void bnx2x_link_attn(struct bnx2x
 
 	if (bp->link_vars.link_up) {
 
+		/* dropless flow control */
+		if (CHIP_IS_E1H(bp)) {
+			int port = BP_PORT(bp);
+			u32 pause_enabled = 0;
+
+			if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+				pause_enabled = 1;
+
+			REG_WR(bp, BAR_USTRORM_INTMEM +
+			       USTORM_PAUSE_ENABLED_OFFSET(port),
+			       pause_enabled);
+		}
+
 		if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
 			struct host_port_stats *pstats;
 
@@ -2286,36 +2300,38 @@ static void bnx2x_link_attn(struct bnx2x
 	bnx2x_link_report(bp);
 
 	if (IS_E1HMF(bp)) {
+		int port = BP_PORT(bp);
 		int func;
+		int vn;
 
 		for (vn = VN_0; vn < E1HVN_MAX; vn++) {
 			if (vn == BP_E1HVN(bp))
 				continue;
 
-			func = ((vn << 1) | BP_PORT(bp));
+			func = ((vn << 1) | port);
 
 			/* Set the attention towards other drivers
 			   on the same port */
 			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
 			       (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
 		}
-	}
 
-	if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
-		struct cmng_struct_per_port m_cmng_port;
-		u32 wsum;
-		int port = BP_PORT(bp);
+		if (bp->link_vars.link_up) {
+			int i;
+
+			/* Init rate shaping and fairness contexts */
+			bnx2x_init_port_minmax(bp);
 
-		/* Init RATE SHAPING and FAIRNESS contexts */
-		wsum = bnx2x_calc_vn_wsum(bp);
-		bnx2x_init_port_minmax(bp, (int)wsum,
-					bp->link_vars.line_speed,
-					&m_cmng_port);
-		if (IS_E1HMF(bp))
 			for (vn = VN_0; vn < E1HVN_MAX; vn++)
-				bnx2x_init_vn_minmax(bp, 2*vn + port,
-					wsum, bp->link_vars.line_speed,
-						     &m_cmng_port);
+				bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+			/* Store it to internal memory */
+			for (i = 0;
+			     i < sizeof(struct cmng_struct_per_port) / 4; i++)
+				REG_WR(bp, BAR_XSTRORM_INTMEM +
+				  XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
+				       ((u32 *)(&bp->cmng))[i]);
+		}
 	}
 }
 
@@ -2492,6 +2508,7 @@ static void bnx2x_attn_int_asserted(stru
 	u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
 				       NIG_REG_MASK_INTERRUPT_PORT0;
 	u32 aeu_mask;
+	u32 nig_mask = 0;
 
 	if (bp->attn_state & asserted)
 		BNX2X_ERR("IGU ERROR\n");
@@ -2517,7 +2534,7 @@ static void bnx2x_attn_int_asserted(stru
 			bnx2x_acquire_phy_lock(bp);
 
 			/* save nig interrupt mask */
-			bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+			nig_mask = REG_RD(bp, nig_int_mask_addr);
 			REG_WR(bp, nig_int_mask_addr, 0);
 
 			bnx2x_link_attn(bp);
@@ -2572,7 +2589,7 @@ static void bnx2x_attn_int_asserted(stru
 
 	/* now set back the mask */
 	if (asserted & ATTN_NIG_FOR_FUNC) {
-		REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
+		REG_WR(bp, nig_int_mask_addr, nig_mask);
 		bnx2x_release_phy_lock(bp);
 	}
 }
@@ -2594,9 +2611,8 @@ static inline void bnx2x_attn_int_deasse
 
 		BNX2X_ERR("SPIO5 hw attention\n");
 
-		switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
-		case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
-		case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+		switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 			/* Fan failure attention */
 
 			/* The PHY reset is controlled by GPIO 1 */
@@ -2627,6 +2643,13 @@ static inline void bnx2x_attn_int_deasse
 		}
 	}
 
+	if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
+		    AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) {
+		bnx2x_acquire_phy_lock(bp);
+		bnx2x_handle_module_detect_int(&bp->link_params);
+		bnx2x_release_phy_lock(bp);
+	}
+
 	if (attn & HW_INTERRUT_ASSERT_SET_0) {
 
 		val = REG_RD(bp, reg_offset);
@@ -2643,7 +2666,7 @@ static inline void bnx2x_attn_int_deasse
 {
 	u32 val;
 
-	if (attn & BNX2X_DOORQ_ASSERT) {
+	if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) {
 
 		val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
 		BNX2X_ERR("DB hw attention 0x%x\n", val);
@@ -2889,10 +2912,6 @@ static void bnx2x_sp_task(struct work_st
 	if (status & 0x1)
 		bnx2x_attn_int(bp);
 
-	/* CStorm events: query_stats, port delete ramrod */
-	if (status & 0x2)
-		bp->stats_pending = 0;
-
 	bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx),
 		     IGU_INT_NOP, 1);
 	bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
@@ -2917,7 +2936,7 @@ static irqreturn_t bnx2x_msix_sp_int(int
 		return IRQ_HANDLED;
 	}
 
-	bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+	bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0);
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
@@ -3006,16 +3025,41 @@ static irqreturn_t bnx2x_msix_sp_int(int
 
 #define UPDATE_EXTEND_TSTAT(s, t) \
 	do { \
-		diff = le32_to_cpu(tclient->s) - old_tclient->s; \
-		old_tclient->s = le32_to_cpu(tclient->s); \
-		ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+		diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \
+		old_tclient->s = tclient->s; \
+		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+	} while (0)
+
+#define UPDATE_EXTEND_USTAT(s, t) \
+	do { \
+		diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+		old_uclient->s = uclient->s; \
+		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
 	} while (0)
 
 #define UPDATE_EXTEND_XSTAT(s, t) \
 	do { \
-		diff = le32_to_cpu(xclient->s) - old_xclient->s; \
-		old_xclient->s = le32_to_cpu(xclient->s); \
-		ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+		diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \
+		old_xclient->s = xclient->s; \
+		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+	} while (0)
+
+/* minuend -= subtrahend */
+#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
+	do { \
+		DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
+	} while (0)
+
+/* minuend[hi:lo] -= subtrahend */
+#define SUB_EXTEND_64(m_hi, m_lo, s) \
+	do { \
+		SUB_64(m_hi, 0, m_lo, s); \
+	} while (0)
+
+#define SUB_EXTEND_USTAT(s, t) \
+	do { \
+		diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+		SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
 	} while (0)
 
 /*
@@ -3042,11 +3086,12 @@ static void bnx2x_storm_stats_post(struc
 {
 	if (!bp->stats_pending) {
 		struct eth_query_ramrod_data ramrod_data = {0};
-		int rc;
+		int i, rc;
 
 		ramrod_data.drv_counter = bp->stats_counter++;
-		ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
-		ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
+		ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
+		for_each_queue(bp, i)
+			ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
 
 		rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
 				   ((u32 *)&ramrod_data)[1],
@@ -3062,7 +3107,9 @@ static void bnx2x_storm_stats_post(struc
 static void bnx2x_stats_init(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
+	int i;
 
+	bp->stats_pending = 0;
 	bp->executer_idx = 0;
 	bp->stats_counter = 0;
 
@@ -3084,9 +3131,19 @@ static void bnx2x_stats_init(struct bnx2
 		    &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
 
 	/* function stats */
+	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		memset(&fp->old_tclient, 0,
+		       sizeof(struct tstorm_per_client_stats));
+		memset(&fp->old_uclient, 0,
+		       sizeof(struct ustorm_per_client_stats));
+		memset(&fp->old_xclient, 0,
+		       sizeof(struct xstorm_per_client_stats));
+		memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
+	}
+
 	memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
-	memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
-	memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
 	memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
 
 	bp->stats_state = STATS_STATE_DISABLED;
@@ -3100,6 +3157,8 @@ static void bnx2x_hw_stats_post(struct b
 	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
 
 	*stats_comp = DMAE_COMP_VAL;
+	if (CHIP_REV_IS_SLOW(bp))
+		return;
 
 	/* loader */
 	if (bp->executer_idx) {
@@ -3489,7 +3548,11 @@ static void bnx2x_bmac_stats_update(stru
 {
 	struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
 	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
-	struct regpair diff;
+	struct bnx2x_eth_stats *estats = &bp->eth_stats;
+	struct {
+		u32 lo;
+		u32 hi;
+	} diff;
 
 	UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
 	UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
@@ -3499,7 +3562,7 @@ static void bnx2x_bmac_stats_update(stru
 	UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
 	UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
 	UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
-	UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
+	UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
 	UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
 	UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
 	UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
@@ -3520,12 +3583,23 @@ static void bnx2x_bmac_stats_update(stru
 	UPDATE_STAT64(tx_stat_gterr,
 				tx_stat_dot3statsinternalmactransmiterrors);
 	UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+
+	estats->pause_frames_received_hi =
+				pstats->mac_stx[1].rx_stat_bmac_xpf_hi;
+	estats->pause_frames_received_lo =
+				pstats->mac_stx[1].rx_stat_bmac_xpf_lo;
+
+	estats->pause_frames_sent_hi =
+				pstats->mac_stx[1].tx_stat_outxoffsent_hi;
+	estats->pause_frames_sent_lo =
+				pstats->mac_stx[1].tx_stat_outxoffsent_lo;
 }
 
 static void bnx2x_emac_stats_update(struct bnx2x *bp)
 {
 	struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
 	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+	struct bnx2x_eth_stats *estats = &bp->eth_stats;
 
 	UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
 	UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
@@ -3558,6 +3632,24 @@ static void bnx2x_emac_stats_update(stru
 	UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
 	UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
 	UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
+
+	estats->pause_frames_received_hi =
+			pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
+	estats->pause_frames_received_lo =
+			pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
+	ADD_64(estats->pause_frames_received_hi,
+	       pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
+	       estats->pause_frames_received_lo,
+	       pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
+
+	estats->pause_frames_sent_hi =
+			pstats->mac_stx[1].tx_stat_outxonsent_hi;
+	estats->pause_frames_sent_lo =
+			pstats->mac_stx[1].tx_stat_outxonsent_lo;
+	ADD_64(estats->pause_frames_sent_hi,
+	       pstats->mac_stx[1].tx_stat_outxoffsent_hi,
+	       estats->pause_frames_sent_lo,
+	       pstats->mac_stx[1].tx_stat_outxoffsent_lo);
 }
 
 static int bnx2x_hw_stats_update(struct bnx2x *bp)
@@ -3566,7 +3658,11 @@ static int bnx2x_hw_stats_update(struct
 	struct nig_stats *old = &(bp->port.old_nig_stats);
 	struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
-	struct regpair diff;
+	struct {
+		u32 lo;
+		u32 hi;
+	} diff;
+	u32 nig_timer_max;
 
 	if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
 		bnx2x_bmac_stats_update(bp);
@@ -3575,7 +3671,7 @@ static int bnx2x_hw_stats_update(struct
 		bnx2x_emac_stats_update(bp);
 
 	else { /* unreached */
-		BNX2X_ERR("stats updated by dmae but no MAC active\n");
+		BNX2X_ERR("stats updated by DMAE but no MAC active\n");
 		return -1;
 	}
 
@@ -3597,134 +3693,211 @@ static int bnx2x_hw_stats_update(struct
 
 	pstats->host_port_stats_start = ++pstats->host_port_stats_end;
 
+	nig_timer_max = SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
+	if (nig_timer_max != estats->nig_timer_max) {
+		estats->nig_timer_max = nig_timer_max;
+		BNX2X_ERR("NIG timer max (%u)\n", estats->nig_timer_max);
+	}
+
 	return 0;
 }
 
 static int bnx2x_storm_stats_update(struct bnx2x *bp)
 {
 	struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
-	int cl_id = BP_CL_ID(bp);
 	struct tstorm_per_port_stats *tport =
-				&stats->tstorm_common.port_statistics;
-	struct tstorm_per_client_stats *tclient =
-			&stats->tstorm_common.client_statistics[cl_id];
-	struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
-	struct xstorm_per_client_stats *xclient =
-			&stats->xstorm_common.client_statistics[cl_id];
-	struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
+					&stats->tstorm_common.port_statistics;
 	struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
-	u32 diff;
+	int i;
 
-	/* are storm stats valid? */
-	if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
+	memset(&(fstats->total_bytes_received_hi), 0,
+	       sizeof(struct host_func_stats) - 2*sizeof(u32));
+	estats->error_bytes_received_hi = 0;
+	estats->error_bytes_received_lo = 0;
+	estats->etherstatsoverrsizepkts_hi = 0;
+	estats->etherstatsoverrsizepkts_lo = 0;
+	estats->no_buff_discard_hi = 0;
+	estats->no_buff_discard_lo = 0;
+
+	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+		int cl_id = fp->cl_id;
+		struct tstorm_per_client_stats *tclient =
+				&stats->tstorm_common.client_statistics[cl_id];
+		struct tstorm_per_client_stats *old_tclient = &fp->old_tclient;
+		struct ustorm_per_client_stats *uclient =
+				&stats->ustorm_common.client_statistics[cl_id];
+		struct ustorm_per_client_stats *old_uclient = &fp->old_uclient;
+		struct xstorm_per_client_stats *xclient =
+				&stats->xstorm_common.client_statistics[cl_id];
+		struct xstorm_per_client_stats *old_xclient = &fp->old_xclient;
+		struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
+		u32 diff;
+
+		/* are storm stats valid? */
+		if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
 							bp->stats_counter) {
-		DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
-		   "  tstorm counter (%d) != stats_counter (%d)\n",
-		   tclient->stats_counter, bp->stats_counter);
-		return -1;
-	}
-	if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
+			DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
+			   "  xstorm counter (%d) != stats_counter (%d)\n",
+			   i, xclient->stats_counter, bp->stats_counter);
+			return -1;
+		}
+		if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
 							bp->stats_counter) {
-		DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
-		   "  xstorm counter (%d) != stats_counter (%d)\n",
-		   xclient->stats_counter, bp->stats_counter);
-		return -2;
-	}
+			DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
+			   "  tstorm counter (%d) != stats_counter (%d)\n",
+			   i, tclient->stats_counter, bp->stats_counter);
+			return -2;
+		}
+		if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) !=
+							bp->stats_counter) {
+			DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
+			   "  ustorm counter (%d) != stats_counter (%d)\n",
+			   i, uclient->stats_counter, bp->stats_counter);
+			return -4;
+		}
 
-	fstats->total_bytes_received_hi =
-	fstats->valid_bytes_received_hi =
+		qstats->total_bytes_received_hi =
+		qstats->valid_bytes_received_hi =
 				le32_to_cpu(tclient->total_rcv_bytes.hi);
-	fstats->total_bytes_received_lo =
-	fstats->valid_bytes_received_lo =
+		qstats->total_bytes_received_lo =
+		qstats->valid_bytes_received_lo =
 				le32_to_cpu(tclient->total_rcv_bytes.lo);
 
-	estats->error_bytes_received_hi =
+		qstats->error_bytes_received_hi =
 				le32_to_cpu(tclient->rcv_error_bytes.hi);
-	estats->error_bytes_received_lo =
+		qstats->error_bytes_received_lo =
 				le32_to_cpu(tclient->rcv_error_bytes.lo);
-	ADD_64(estats->error_bytes_received_hi,
-	       estats->rx_stat_ifhcinbadoctets_hi,
-	       estats->error_bytes_received_lo,
-	       estats->rx_stat_ifhcinbadoctets_lo);
 
-	ADD_64(fstats->total_bytes_received_hi,
-	       estats->error_bytes_received_hi,
-	       fstats->total_bytes_received_lo,
-	       estats->error_bytes_received_lo);
+		ADD_64(qstats->total_bytes_received_hi,
+		       qstats->error_bytes_received_hi,
+		       qstats->total_bytes_received_lo,
+		       qstats->error_bytes_received_lo);
 
-	UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
-	UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
-				total_multicast_packets_received);
-	UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
-				total_broadcast_packets_received);
+		UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
+					total_unicast_packets_received);
+		UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
+					total_multicast_packets_received);
+		UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
+					total_broadcast_packets_received);
+		UPDATE_EXTEND_TSTAT(packets_too_big_discard,
+					etherstatsoverrsizepkts);
+		UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard);
 
-	fstats->total_bytes_transmitted_hi =
+		SUB_EXTEND_USTAT(ucast_no_buff_pkts,
+					total_unicast_packets_received);
+		SUB_EXTEND_USTAT(mcast_no_buff_pkts,
+					total_multicast_packets_received);
+		SUB_EXTEND_USTAT(bcast_no_buff_pkts,
+					total_broadcast_packets_received);
+		UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard);
+		UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard);
+		UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
+
+		qstats->total_bytes_transmitted_hi =
 				le32_to_cpu(xclient->total_sent_bytes.hi);
-	fstats->total_bytes_transmitted_lo =
+		qstats->total_bytes_transmitted_lo =
 				le32_to_cpu(xclient->total_sent_bytes.lo);
 
-	UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
-				total_unicast_packets_transmitted);
-	UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
-				total_multicast_packets_transmitted);
-	UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
-				total_broadcast_packets_transmitted);
+		UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
+					total_unicast_packets_transmitted);
+		UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
+					total_multicast_packets_transmitted);
+		UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
+					total_broadcast_packets_transmitted);
 
-	memcpy(estats, &(fstats->total_bytes_received_hi),
-	       sizeof(struct host_func_stats) - 2*sizeof(u32));
+		old_tclient->checksum_discard = tclient->checksum_discard;
+		old_tclient->ttl0_discard = tclient->ttl0_discard;
 
-	estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
-	estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
-	estats->brb_truncate_discard =
-				le32_to_cpu(tport->brb_truncate_discard);
-	estats->mac_discard = le32_to_cpu(tport->mac_discard);
+		ADD_64(fstats->total_bytes_received_hi,
+		       qstats->total_bytes_received_hi,
+		       fstats->total_bytes_received_lo,
+		       qstats->total_bytes_received_lo);
+		ADD_64(fstats->total_bytes_transmitted_hi,
+		       qstats->total_bytes_transmitted_hi,
+		       fstats->total_bytes_transmitted_lo,
+		       qstats->total_bytes_transmitted_lo);
+		ADD_64(fstats->total_unicast_packets_received_hi,
+		       qstats->total_unicast_packets_received_hi,
+		       fstats->total_unicast_packets_received_lo,
+		       qstats->total_unicast_packets_received_lo);
+		ADD_64(fstats->total_multicast_packets_received_hi,
+		       qstats->total_multicast_packets_received_hi,
+		       fstats->total_multicast_packets_received_lo,
+		       qstats->total_multicast_packets_received_lo);
+		ADD_64(fstats->total_broadcast_packets_received_hi,
+		       qstats->total_broadcast_packets_received_hi,
+		       fstats->total_broadcast_packets_received_lo,
+		       qstats->total_broadcast_packets_received_lo);
+		ADD_64(fstats->total_unicast_packets_transmitted_hi,
+		       qstats->total_unicast_packets_transmitted_hi,
+		       fstats->total_unicast_packets_transmitted_lo,
+		       qstats->total_unicast_packets_transmitted_lo);
+		ADD_64(fstats->total_multicast_packets_transmitted_hi,
+		       qstats->total_multicast_packets_transmitted_hi,
+		       fstats->total_multicast_packets_transmitted_lo,
+		       qstats->total_multicast_packets_transmitted_lo);
+		ADD_64(fstats->total_broadcast_packets_transmitted_hi,
+		       qstats->total_broadcast_packets_transmitted_hi,
+		       fstats->total_broadcast_packets_transmitted_lo,
+		       qstats->total_broadcast_packets_transmitted_lo);
+		ADD_64(fstats->valid_bytes_received_hi,
+		       qstats->valid_bytes_received_hi,
+		       fstats->valid_bytes_received_lo,
+		       qstats->valid_bytes_received_lo);
 
-	old_tclient->rcv_unicast_bytes.hi =
-				le32_to_cpu(tclient->rcv_unicast_bytes.hi);
-	old_tclient->rcv_unicast_bytes.lo =
-				le32_to_cpu(tclient->rcv_unicast_bytes.lo);
-	old_tclient->rcv_broadcast_bytes.hi =
-				le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
-	old_tclient->rcv_broadcast_bytes.lo =
-				le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
-	old_tclient->rcv_multicast_bytes.hi =
-				le32_to_cpu(tclient->rcv_multicast_bytes.hi);
-	old_tclient->rcv_multicast_bytes.lo =
-				le32_to_cpu(tclient->rcv_multicast_bytes.lo);
-	old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
+		ADD_64(estats->error_bytes_received_hi,
+		       qstats->error_bytes_received_hi,
+		       estats->error_bytes_received_lo,
+		       qstats->error_bytes_received_lo);
+		ADD_64(estats->etherstatsoverrsizepkts_hi,
+		       qstats->etherstatsoverrsizepkts_hi,
+		       estats->etherstatsoverrsizepkts_lo,
+		       qstats->etherstatsoverrsizepkts_lo);
+		ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi,
+		       estats->no_buff_discard_lo, qstats->no_buff_discard_lo);
+	}
 
-	old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
-	old_tclient->packets_too_big_discard =
-				le32_to_cpu(tclient->packets_too_big_discard);
-	estats->no_buff_discard =
-	old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
-	old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
+	ADD_64(fstats->total_bytes_received_hi,
+	       estats->rx_stat_ifhcinbadoctets_hi,
+	       fstats->total_bytes_received_lo,
+	       estats->rx_stat_ifhcinbadoctets_lo);
 
-	old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
-	old_xclient->unicast_bytes_sent.hi =
-				le32_to_cpu(xclient->unicast_bytes_sent.hi);
-	old_xclient->unicast_bytes_sent.lo =
-				le32_to_cpu(xclient->unicast_bytes_sent.lo);
-	old_xclient->multicast_bytes_sent.hi =
-				le32_to_cpu(xclient->multicast_bytes_sent.hi);
-	old_xclient->multicast_bytes_sent.lo =
-				le32_to_cpu(xclient->multicast_bytes_sent.lo);
-	old_xclient->broadcast_bytes_sent.hi =
-				le32_to_cpu(xclient->broadcast_bytes_sent.hi);
-	old_xclient->broadcast_bytes_sent.lo =
-				le32_to_cpu(xclient->broadcast_bytes_sent.lo);
+	memcpy(estats, &(fstats->total_bytes_received_hi),
+	       sizeof(struct host_func_stats) - 2*sizeof(u32));
+
+	ADD_64(estats->etherstatsoverrsizepkts_hi,
+	       estats->rx_stat_dot3statsframestoolong_hi,
+	       estats->etherstatsoverrsizepkts_lo,
+	       estats->rx_stat_dot3statsframestoolong_lo);
+	ADD_64(estats->error_bytes_received_hi,
+	       estats->rx_stat_ifhcinbadoctets_hi,
+	       estats->error_bytes_received_lo,
+	       estats->rx_stat_ifhcinbadoctets_lo);
+
+	if (bp->port.pmf) {
+		estats->mac_filter_discard =
+				le32_to_cpu(tport->mac_filter_discard);
+		estats->xxoverflow_discard =
+				le32_to_cpu(tport->xxoverflow_discard);
+		estats->brb_truncate_discard =
+				le32_to_cpu(tport->brb_truncate_discard);
+		estats->mac_discard = le32_to_cpu(tport->mac_discard);
+	}
 
 	fstats->host_func_stats_start = ++fstats->host_func_stats_end;
 
+	bp->stats_pending = 0;
+
 	return 0;
 }
 
 static void bnx2x_net_stats_update(struct bnx2x *bp)
 {
-	struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
 	struct net_device_stats *nstats = &bp->dev->stats;
+	int i;
 
 	nstats->rx_packets =
 		bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
@@ -3736,34 +3909,33 @@ static void bnx2x_net_stats_update(struc
 		bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
 		bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
 
-	nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
+	nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
 
 	nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
 
-	nstats->rx_dropped = old_tclient->checksum_discard +
-			     estats->mac_discard;
+	nstats->rx_dropped = estats->mac_discard;
+	for_each_queue(bp, i)
+		nstats->rx_dropped +=
+			le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+
 	nstats->tx_dropped = 0;
 
 	nstats->multicast =
-		bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
+		bnx2x_hilo(&estats->total_multicast_packets_received_hi);
 
 	nstats->collisions =
-			estats->tx_stat_dot3statssinglecollisionframes_lo +
-			estats->tx_stat_dot3statsmultiplecollisionframes_lo +
-			estats->tx_stat_dot3statslatecollisions_lo +
-			estats->tx_stat_dot3statsexcessivecollisions_lo;
-
-	estats->jabber_packets_received =
-				old_tclient->packets_too_big_discard +
-				estats->rx_stat_dot3statsframestoolong_lo;
+		bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi);
 
 	nstats->rx_length_errors =
-				estats->rx_stat_etherstatsundersizepkts_lo +
-				estats->jabber_packets_received;
-	nstats->rx_over_errors = estats->brb_drop_lo + estats->brb_truncate_lo;
-	nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
-	nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
-	nstats->rx_fifo_errors = old_tclient->no_buff_discard;
+		bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
+		bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi);
+	nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) +
+				 bnx2x_hilo(&estats->brb_truncate_hi);
+	nstats->rx_crc_errors =
+		bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi);
+	nstats->rx_frame_errors =
+		bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi);
+	nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi);
 	nstats->rx_missed_errors = estats->xxoverflow_discard;
 
 	nstats->rx_errors = nstats->rx_length_errors +
@@ -3774,46 +3946,61 @@ static void bnx2x_net_stats_update(struc
 			    nstats->rx_missed_errors;
 
 	nstats->tx_aborted_errors =
-			estats->tx_stat_dot3statslatecollisions_lo +
-			estats->tx_stat_dot3statsexcessivecollisions_lo;
-	nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
+		bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
+		bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi);
+	nstats->tx_carrier_errors =
+		bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi);
 	nstats->tx_fifo_errors = 0;
 	nstats->tx_heartbeat_errors = 0;
 	nstats->tx_window_errors = 0;
 
 	nstats->tx_errors = nstats->tx_aborted_errors +
-			    nstats->tx_carrier_errors;
+			    nstats->tx_carrier_errors +
+	    bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi);
+}
+
+static void bnx2x_drv_stats_update(struct bnx2x *bp)
+{
+	struct bnx2x_eth_stats *estats = &bp->eth_stats;
+	int i;
+
+	estats->driver_xoff = 0;
+	estats->rx_err_discard_pkt = 0;
+	estats->rx_skb_alloc_failed = 0;
+	estats->hw_csum_err = 0;
+	for_each_queue(bp, i) {
+		struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
+
+		estats->driver_xoff += qstats->driver_xoff;
+		estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt;
+		estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed;
+		estats->hw_csum_err += qstats->hw_csum_err;
+	}
 }
 
 static void bnx2x_stats_update(struct bnx2x *bp)
 {
 	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-	int update = 0;
 
 	if (*stats_comp != DMAE_COMP_VAL)
 		return;
 
 	if (bp->port.pmf)
-		update = (bnx2x_hw_stats_update(bp) == 0);
-
-	update |= (bnx2x_storm_stats_update(bp) == 0);
-
-	if (update)
-		bnx2x_net_stats_update(bp);
+		bnx2x_hw_stats_update(bp);
 
-	else {
-		if (bp->stats_pending) {
-			bp->stats_pending++;
-			if (bp->stats_pending == 3) {
-				BNX2X_ERR("stats not updated for 3 times\n");
-				bnx2x_panic();
-				return;
-			}
-		}
+	if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) {
+		BNX2X_ERR("storm stats were not updated for 3 times\n");
+		bnx2x_panic();
+		return;
 	}
 
+	bnx2x_net_stats_update(bp);
+	bnx2x_drv_stats_update(bp);
+
 	if (bp->msglevel & NETIF_MSG_TIMER) {
-		struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+		struct tstorm_per_client_stats *old_tclient =
+							&bp->fp->old_tclient;
+		struct bnx2x_eth_q_stats *qstats = &bp->fp->eth_q_stats;
 		struct bnx2x_eth_stats *estats = &bp->eth_stats;
 		struct net_device_stats *nstats = &bp->dev->stats;
 		int i;
@@ -3828,20 +4015,22 @@ static void bnx2x_stats_update(struct bn
 		       (u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
 			     bp->fp->rx_comp_cons),
 		       le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
-		printk(KERN_DEBUG "  %s (Xoff events %u)  brb drops %u\n",
-		       netif_queue_stopped(bp->dev) ? "Xoff" : "Xon",
-		       estats->driver_xoff, estats->brb_drop_lo);
+		printk(KERN_DEBUG "  %s (Xoff events %u)  brb drops %u  "
+				  "brb truncate %u\n",
+		       (netif_queue_stopped(bp->dev) ? "Xoff" : "Xon"),
+		       qstats->driver_xoff,
+		       estats->brb_drop_lo, estats->brb_truncate_lo);
 		printk(KERN_DEBUG "tstats: checksum_discard %u  "
-			"packets_too_big_discard %u  no_buff_discard %u  "
+			"packets_too_big_discard %lu  no_buff_discard %lu  "
 			"mac_discard %u  mac_filter_discard %u  "
 			"xxovrflow_discard %u  brb_truncate_discard %u  "
 			"ttl0_discard %u\n",
-		       old_tclient->checksum_discard,
-		       old_tclient->packets_too_big_discard,
-		       old_tclient->no_buff_discard, estats->mac_discard,
-		       estats->mac_filter_discard, estats->xxoverflow_discard,
-		       estats->brb_truncate_discard,
-		       old_tclient->ttl0_discard);
+		       le32_to_cpu(old_tclient->checksum_discard),
+		       bnx2x_hilo(&qstats->etherstatsoverrsizepkts_hi),
+		       bnx2x_hilo(&qstats->no_buff_discard_hi),
+		       estats->mac_discard, estats->mac_filter_discard,
+		       estats->xxoverflow_discard, estats->brb_truncate_discard,
+		       le32_to_cpu(old_tclient->ttl0_discard));
 
 		for_each_queue(bp, i) {
 			printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
@@ -3990,7 +4179,7 @@ static void bnx2x_timer(unsigned long da
 		struct bnx2x_fastpath *fp = &bp->fp[0];
 		int rc;
 
-		bnx2x_tx_int(fp, 1000);
+		bnx2x_tx_int(fp);
 		rc = bnx2x_rx_int(fp, 1000);
 	}
 
@@ -4242,10 +4431,6 @@ static void bnx2x_update_coalesce(struct
 			 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
 						     U_SB_ETH_RX_CQ_INDEX),
 			 bp->rx_ticks ? 0 : 1);
-		REG_WR16(bp, BAR_USTRORM_INTMEM +
-			 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
-						     U_SB_ETH_RX_BD_INDEX),
-			 bp->rx_ticks ? 0 : 1);
 
 		/* HC_INDEX_C_ETH_TX_CQ_CONS */
 		REG_WR8(bp, BAR_CSTRORM_INTMEM +
@@ -4276,8 +4461,7 @@ static inline void bnx2x_free_tpa_pool(s
 		if (fp->tpa_state[i] == BNX2X_TPA_START)
 			pci_unmap_single(bp->pdev,
 					 pci_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_size,
-					 PCI_DMA_FROMDEVICE);
+					 bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
 		dev_kfree_skb(skb);
 		rx_buf->skb = NULL;
@@ -4292,16 +4476,13 @@ static void bnx2x_init_rx_rings(struct b
 	u16 ring_prod, cqe_ring_prod;
 	int i, j;
 
-	bp->rx_buf_size = bp->dev->mtu;
-	bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD +
-		BCM_RX_ETH_PAYLOAD_ALIGN;
+	bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN;
+	DP(NETIF_MSG_IFUP,
+	   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
 
 	if (bp->flags & TPA_ENABLE_FLAG) {
-		DP(NETIF_MSG_IFUP,
-		   "rx_buf_size %d  effective_mtu %d\n",
-		   bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD);
 
-		for_each_queue(bp, j) {
+		for_each_rx_queue(bp, j) {
 			struct bnx2x_fastpath *fp = &bp->fp[j];
 
 			for (i = 0; i < max_agg_queues; i++) {
@@ -4324,7 +4505,7 @@ static void bnx2x_init_rx_rings(struct b
 		}
 	}
 
-	for_each_queue(bp, j) {
+	for_each_rx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		fp->rx_bd_cons = 0;
@@ -4399,8 +4580,8 @@ static void bnx2x_init_rx_rings(struct b
 		for (i = 0; i < bp->rx_ring_size; i++) {
 			if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
 				BNX2X_ERR("was only able to allocate "
-					  "%d rx skbs\n", i);
-				bp->eth_stats.rx_skb_alloc_failed++;
+					  "%d rx skbs on queue[%d]\n", i, j);
+				fp->eth_q_stats.rx_skb_alloc_failed++;
 				break;
 			}
 			ring_prod = NEXT_RX_IDX(ring_prod);
@@ -4436,7 +4617,7 @@ static void bnx2x_init_tx_ring(struct bn
 {
 	int i, j;
 
-	for_each_queue(bp, j) {
+	for_each_tx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -4489,27 +4670,20 @@ static void bnx2x_init_context(struct bn
 	for_each_queue(bp, i) {
 		struct eth_context *context = bnx2x_sp(bp, context[i].eth);
 		struct bnx2x_fastpath *fp = &bp->fp[i];
-		u8 sb_id = FP_SB_ID(fp);
-
-		context->xstorm_st_context.tx_bd_page_base_hi =
-						U64_HI(fp->tx_desc_mapping);
-		context->xstorm_st_context.tx_bd_page_base_lo =
-						U64_LO(fp->tx_desc_mapping);
-		context->xstorm_st_context.db_data_addr_hi =
-						U64_HI(fp->tx_prods_mapping);
-		context->xstorm_st_context.db_data_addr_lo =
-						U64_LO(fp->tx_prods_mapping);
-		context->xstorm_st_context.statistics_data = (BP_CL_ID(bp) |
-				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+		u8 cl_id = fp->cl_id;
+		u8 sb_id = fp->sb_id;
 
 		context->ustorm_st_context.common.sb_index_numbers =
 						BNX2X_RX_SB_INDEX_NUM;
-		context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
+		context->ustorm_st_context.common.clientId = cl_id;
 		context->ustorm_st_context.common.status_block_id = sb_id;
 		context->ustorm_st_context.common.flags =
-			USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
-		context->ustorm_st_context.common.mc_alignment_size =
-			BCM_RX_ETH_PAYLOAD_ALIGN;
+			(USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
+			 USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS);
+		context->ustorm_st_context.common.statistics_counter_id =
+						cl_id;
+		context->ustorm_st_context.common.mc_alignment_log_size =
+						BNX2X_RX_ALIGN_SHIFT;
 		context->ustorm_st_context.common.bd_buff_size =
 						bp->rx_buf_size;
 		context->ustorm_st_context.common.bd_page_base_hi =
@@ -4529,6 +4703,21 @@ static void bnx2x_init_context(struct bn
 						U64_LO(fp->rx_sge_mapping);
 		}
 
+		context->ustorm_ag_context.cdu_usage =
+			CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+					       CDU_REGION_NUMBER_UCM_AG,
+					       ETH_CONNECTION_TYPE);
+
+		context->xstorm_st_context.tx_bd_page_base_hi =
+						U64_HI(fp->tx_desc_mapping);
+		context->xstorm_st_context.tx_bd_page_base_lo =
+						U64_LO(fp->tx_desc_mapping);
+		context->xstorm_st_context.db_data_addr_hi =
+						U64_HI(fp->tx_prods_mapping);
+		context->xstorm_st_context.db_data_addr_lo =
+						U64_LO(fp->tx_prods_mapping);
+		context->xstorm_st_context.statistics_data = (cl_id |
+				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
 		context->cstorm_st_context.sb_index_number =
 						C_SB_ETH_TX_CQ_INDEX;
 		context->cstorm_st_context.status_block_id = sb_id;
@@ -4537,10 +4726,6 @@ static void bnx2x_init_context(struct bn
 			CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
 					       CDU_REGION_NUMBER_XCM_AG,
 					       ETH_CONNECTION_TYPE);
-		context->ustorm_ag_context.cdu_usage =
-			CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
-					       CDU_REGION_NUMBER_UCM_AG,
-					       ETH_CONNECTION_TYPE);
 	}
 }
 
@@ -4549,14 +4734,15 @@ static void bnx2x_init_ind_table(struct
 	int func = BP_FUNC(bp);
 	int i;
 
-	if (!is_multi(bp))
+	if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
 		return;
 
-	DP(NETIF_MSG_IFUP, "Initializing indirection table\n");
+	DP(NETIF_MSG_IFUP,
+	   "Initializing indirection table  multi_mode %d\n", bp->multi_mode);
 	for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
 		REG_WR8(bp, BAR_TSTRORM_INTMEM +
 			TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
-			BP_CL_ID(bp) + (i % bp->num_queues));
+			bp->fp->cl_id + (i % bp->num_rx_queues));
 }
 
 static void bnx2x_set_client_config(struct bnx2x *bp)
@@ -4566,13 +4752,13 @@ static void bnx2x_set_client_config(stru
 	int i;
 
 	tstorm_client.mtu = bp->dev->mtu;
-	tstorm_client.statistics_counter_id = BP_CL_ID(bp);
 	tstorm_client.config_flags =
-				TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+				(TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE |
+				 TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE);
 #ifdef BCM_VLAN
 	if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) {
 		tstorm_client.config_flags |=
-				TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+				TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE;
 		DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
 	}
 #endif
@@ -4590,6 +4776,8 @@ static void bnx2x_set_client_config(stru
 	}
 
 	for_each_queue(bp, i) {
+		tstorm_client.statistics_counter_id = bp->fp[i].cl_id;
+
 		REG_WR(bp, BAR_TSTRORM_INTMEM +
 		       TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
 		       ((u32 *)&tstorm_client)[0]);
@@ -4618,18 +4806,22 @@ static void bnx2x_set_storm_rx_mode(stru
 		tstorm_mac_filter.mcast_drop_all = mask;
 		tstorm_mac_filter.bcast_drop_all = mask;
 		break;
+
 	case BNX2X_RX_MODE_NORMAL:
 		tstorm_mac_filter.bcast_accept_all = mask;
 		break;
+
 	case BNX2X_RX_MODE_ALLMULTI:
 		tstorm_mac_filter.mcast_accept_all = mask;
 		tstorm_mac_filter.bcast_accept_all = mask;
 		break;
+
 	case BNX2X_RX_MODE_PROMISC:
 		tstorm_mac_filter.ucast_accept_all = mask;
 		tstorm_mac_filter.mcast_accept_all = mask;
 		tstorm_mac_filter.bcast_accept_all = mask;
 		break;
+
 	default:
 		BNX2X_ERR("BAD rx mode (%d)\n", mode);
 		break;
@@ -4680,19 +4872,64 @@ static void bnx2x_init_internal_port(str
 	REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
 }
 
+/* Calculates the sum of vn_min_rates.
+   It's needed for further normalizing of the min_rates.
+   Returns:
+     sum of vn_min_rates.
+       or
+     0 - if all the min_rates are 0.
+     In the later case fainess algorithm should be deactivated.
+     If not all min_rates are zero then those that are zeroes will be set to 1.
+ */
+static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+{
+	int all_zero = 1;
+	int port = BP_PORT(bp);
+	int vn;
+
+	bp->vn_weight_sum = 0;
+	for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+		int func = 2*vn + port;
+		u32 vn_cfg =
+			SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+		u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+				   FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+
+		/* Skip hidden vns */
+		if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
+			continue;
+
+		/* If min rate is zero - set it to 1 */
+		if (!vn_min_rate)
+			vn_min_rate = DEF_MIN_RATE;
+		else
+			all_zero = 0;
+
+		bp->vn_weight_sum += vn_min_rate;
+	}
+
+	/* ... only if all min rates are zeros - disable fairness */
+	if (all_zero)
+		bp->vn_weight_sum = 0;
+}
+
 static void bnx2x_init_internal_func(struct bnx2x *bp)
 {
 	struct tstorm_eth_function_common_config tstorm_config = {0};
 	struct stats_indication_flags stats_flags = {0};
 	int port = BP_PORT(bp);
 	int func = BP_FUNC(bp);
-	int i;
+	int i, j;
+	u32 offset;
 	u16 max_agg_size;
 
 	if (is_multi(bp)) {
-		tstorm_config.config_flags = MULTI_FLAGS;
+		tstorm_config.config_flags = MULTI_FLAGS(bp);
 		tstorm_config.rss_result_mask = MULTI_MASK;
 	}
+	if (IS_E1HMF(bp))
+		tstorm_config.config_flags |=
+				TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM;
 
 	tstorm_config.leading_client_id = BP_L_ID(bp);
 
@@ -4703,17 +4940,29 @@ static void bnx2x_init_internal_func(str
 	bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
 	bnx2x_set_storm_rx_mode(bp);
 
-	/* reset xstorm per client statistics */
-	for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) {
-		REG_WR(bp, BAR_XSTRORM_INTMEM +
-		       XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
-		       i*4, 0);
-	}
-	/* reset tstorm per client statistics */
-	for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) {
-		REG_WR(bp, BAR_TSTRORM_INTMEM +
-		       TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
-		       i*4, 0);
+	for_each_queue(bp, i) {
+		u8 cl_id = bp->fp[i].cl_id;
+
+		/* reset xstorm per client statistics */
+		offset = BAR_XSTRORM_INTMEM +
+			 XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+		for (j = 0;
+		     j < sizeof(struct xstorm_per_client_stats) / 4; j++)
+			REG_WR(bp, offset + j*4, 0);
+
+		/* reset tstorm per client statistics */
+		offset = BAR_TSTRORM_INTMEM +
+			 TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+		for (j = 0;
+		     j < sizeof(struct tstorm_per_client_stats) / 4; j++)
+			REG_WR(bp, offset + j*4, 0);
+
+		/* reset ustorm per client statistics */
+		offset = BAR_USTRORM_INTMEM +
+			 USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+		for (j = 0;
+		     j < sizeof(struct ustorm_per_client_stats) / 4; j++)
+			REG_WR(bp, offset + j*4, 0);
 	}
 
 	/* Init statistics related context */
@@ -4729,6 +4978,11 @@ static void bnx2x_init_internal_func(str
 	REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
 	       ((u32 *)&stats_flags)[1]);
 
+	REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func),
+	       ((u32 *)&stats_flags)[0]);
+	REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4,
+	       ((u32 *)&stats_flags)[1]);
+
 	REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
 	       ((u32 *)&stats_flags)[0]);
 	REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
@@ -4748,6 +5002,13 @@ static void bnx2x_init_internal_func(str
 	       TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
 	       U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
 
+	REG_WR(bp, BAR_USTRORM_INTMEM +
+	       USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
+	       U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+	REG_WR(bp, BAR_USTRORM_INTMEM +
+	       USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
+	       U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+
 	if (CHIP_IS_E1H(bp)) {
 		REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
 			IS_E1HMF(bp));
@@ -4767,20 +5028,91 @@ 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_queue(bp, i) {
+	for_each_rx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		REG_WR(bp, BAR_USTRORM_INTMEM +
-		       USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
+		       USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id),
 		       U64_LO(fp->rx_comp_mapping));
 		REG_WR(bp, BAR_USTRORM_INTMEM +
-		       USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
+		       USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
 		       U64_HI(fp->rx_comp_mapping));
 
 		REG_WR16(bp, BAR_USTRORM_INTMEM +
-			 USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
+			 USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
 			 max_agg_size);
 	}
+
+	/* dropless flow control */
+	if (CHIP_IS_E1H(bp)) {
+		struct ustorm_eth_rx_pause_data_e1h rx_pause = {0};
+
+		rx_pause.bd_thr_low = 250;
+		rx_pause.cqe_thr_low = 250;
+		rx_pause.cos = 1;
+		rx_pause.sge_thr_low = 0;
+		rx_pause.bd_thr_high = 350;
+		rx_pause.cqe_thr_high = 350;
+		rx_pause.sge_thr_high = 0;
+
+		for_each_rx_queue(bp, i) {
+			struct bnx2x_fastpath *fp = &bp->fp[i];
+
+			if (!fp->disable_tpa) {
+				rx_pause.sge_thr_low = 150;
+				rx_pause.sge_thr_high = 250;
+			}
+
+
+			offset = BAR_USTRORM_INTMEM +
+				 USTORM_ETH_RING_PAUSE_DATA_OFFSET(port,
+								   fp->cl_id);
+			for (j = 0;
+			     j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4;
+			     j++)
+				REG_WR(bp, offset + j*4,
+				       ((u32 *)&rx_pause)[j]);
+		}
+	}
+
+	memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
+
+	/* Init rate shaping and fairness contexts */
+	if (IS_E1HMF(bp)) {
+		int vn;
+
+		/* During init there is no active link
+		   Until link is up, set link rate to 10Gbps */
+		bp->link_vars.line_speed = SPEED_10000;
+		bnx2x_init_port_minmax(bp);
+
+		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 =
+					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,
+		   "single function mode  minmax will be disabled\n");
+	}
+
+
+	/* Store it to internal memory */
+	if (bp->port.pmf)
+		for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+			REG_WR(bp, BAR_XSTRORM_INTMEM +
+			       XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
+			       ((u32 *)(&bp->cmng))[i]);
 }
 
 static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
@@ -4817,13 +5149,17 @@ static void bnx2x_nic_init(struct bnx2x
 		fp->cl_id = BP_L_ID(bp) + i;
 		fp->sb_id = fp->cl_id;
 		DP(NETIF_MSG_IFUP,
-		   "bnx2x_init_sb(%p,%p) index %d  cl_id %d  sb %d\n",
-		   bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
+		   "queue[%d]:  bnx2x_init_sb(%p,%p)  cl_id %d  sb %d\n",
+		   i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
 		bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
-			      FP_SB_ID(fp));
+			      fp->sb_id);
 		bnx2x_update_fpsb_idx(fp);
 	}
 
+	/* ensure status block indices were read */
+	rmb();
+
+
 	bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
 			  DEF_SB_ID);
 	bnx2x_update_dsb_idx(bp);
@@ -5201,6 +5537,8 @@ static int bnx2x_init_common(struct bnx2
 	REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
 	REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
 	REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
+	/* make sure this value is 0 */
+	REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
 
 /*	REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
 	REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
@@ -5269,14 +5607,6 @@ static int bnx2x_init_common(struct bnx2
 	}
 
 	bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
-	if (CHIP_REV_IS_SLOW(bp)) {
-		/* fix for emulation and FPGA for no pause */
-		REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
-		REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
-		REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
-		REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
-	}
-
 	bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
 	REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
 	/* set NIC mode */
@@ -5289,37 +5619,10 @@ static int bnx2x_init_common(struct bnx2
 	bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
 	bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
 
-	if (CHIP_IS_E1H(bp)) {
-		bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp,
-				TSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
-				0, STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp,
-				CSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
-				0, STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp,
-				XSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
-				0, STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1H/2);
-		bnx2x_init_fill(bp,
-				USTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
-				0, STORM_INTMEM_SIZE_E1H/2);
-	} else { /* E1 */
-		bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1);
-		bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1);
-		bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1);
-		bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
-				STORM_INTMEM_SIZE_E1);
-	}
+	bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
 
 	bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
 	bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
@@ -5341,8 +5644,7 @@ static int bnx2x_init_common(struct bnx2
 		REG_WR(bp, i, 0xc0cac01a);
 		/* TODO: replace with something meaningful */
 	}
-	if (CHIP_IS_E1H(bp))
-		bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+	bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
 	REG_WR(bp, SRC_REG_SOFT_RST, 0);
 
 	if (sizeof(union cdu_context) != 1024)
@@ -5361,6 +5663,11 @@ static int bnx2x_init_common(struct bnx2
 
 	bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
 	REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
+	/* enable context validation interrupt from CFC */
+	REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+
+	/* set the thresholds to prevent CFC/CDU race */
+	REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
 
 	bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
 	bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
@@ -5413,9 +5720,14 @@ static int bnx2x_init_common(struct bnx2
 		return -EBUSY;
 	}
 
-	switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
-	case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
-	case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+	switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		bp->port.need_hw_lock = 1;
+		break;
+
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 		/* Fan failure is indicated by SPIO 5 */
 		bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
 			       MISC_REGISTERS_SPIO_INPUT_HI_Z);
@@ -5454,6 +5766,7 @@ static int bnx2x_init_common(struct bnx2
 static int bnx2x_init_port(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
+	u32 low, high;
 	u32 val;
 
 	DP(BNX2X_MSG_MCP, "starting port init  port %x\n", port);
@@ -5488,6 +5801,8 @@ static int bnx2x_init_port(struct bnx2x
 	REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
 #endif
 	/* Port CMs come here */
+	bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
+			     (port ? XCM_PORT1_END : XCM_PORT0_END));
 
 	/* Port QM comes here */
 #ifdef BCM_ISCSI
@@ -5498,12 +5813,38 @@ static int bnx2x_init_port(struct bnx2x
 			     func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
 #endif
 	/* Port DQ comes here */
-	/* Port BRB1 comes here */
+
+	bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
+			     (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+	if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
+		/* no pause for emulation and FPGA */
+		low = 0;
+		high = 513;
+	} else {
+		if (IS_E1HMF(bp))
+			low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
+		else if (bp->dev->mtu > 4096) {
+			if (bp->flags & ONE_PORT_FLAG)
+				low = 160;
+			else {
+				val = bp->dev->mtu;
+				/* (24*1024 + val*4)/256 */
+				low = 96 + (val/64) + ((val % 64) ? 1 : 0);
+			}
+		} else
+			low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160);
+		high = low + 56;	/* 14*1024/256 */
+	}
+	REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low);
+	REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
+
+
 	/* Port PRS comes here */
 	/* Port TSDM comes here */
 	/* Port CSDM comes here */
 	/* Port USDM comes here */
 	/* Port XSDM comes here */
+
 	bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
 			     port ? TSEM_PORT1_END : TSEM_PORT0_END);
 	bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
@@ -5512,6 +5853,7 @@ static int bnx2x_init_port(struct bnx2x
 			     port ? CSEM_PORT1_END : CSEM_PORT0_END);
 	bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
 			     port ? XSEM_PORT1_END : XSEM_PORT0_END);
+
 	/* Port UPB comes here */
 	/* Port XPB comes here */
 
@@ -5570,36 +5912,63 @@ static int bnx2x_init_port(struct bnx2x
 	/* Port EMAC1 comes here */
 	/* Port DBU comes here */
 	/* Port DBG comes here */
+
 	bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
 			     port ? NIG_PORT1_END : NIG_PORT0_END);
 
 	REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
 
 	if (CHIP_IS_E1H(bp)) {
-		u32 wsum;
-		struct cmng_struct_per_port m_cmng_port;
-		int vn;
-
 		/* 0x2 disable e1hov, 0x1 enable */
 		REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
 		       (IS_E1HMF(bp) ? 0x1 : 0x2));
 
-		/* Init RATE SHAPING and FAIRNESS contexts.
-		   Initialize as if there is 10G link. */
-		wsum = bnx2x_calc_vn_wsum(bp);
-		bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
-		if (IS_E1HMF(bp))
-			for (vn = VN_0; vn < E1HVN_MAX; vn++)
-				bnx2x_init_vn_minmax(bp, 2*vn + port,
-					wsum, 10000, &m_cmng_port);
+		/* support pause requests from USDM, TSDM and BRB */
+		REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 + port*4, 0x7);
+
+		{
+			REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0);
+			REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0);
+			REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1);
+		}
 	}
 
 	/* Port MCP comes here */
 	/* Port DMAE comes here */
 
-	switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
-	case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
-	case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+	switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		{
+		u32 swap_val, swap_override, aeu_gpio_mask, offset;
+
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+			       MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
+
+		/* The GPIO should be swapped if the swap register is
+		   set and active */
+		swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+		swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+
+		/* Select function upon port-swap configuration */
+		if (port == 0) {
+			offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
+			aeu_gpio_mask = (swap_val && swap_override) ?
+				AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
+				AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
+		} else {
+			offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
+			aeu_gpio_mask = (swap_val && swap_override) ?
+				AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
+				AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
+		}
+		val = REG_RD(bp, offset);
+		/* add GPIO3 to group */
+		val |= aeu_gpio_mask;
+		REG_WR(bp, offset, val);
+		}
+		break;
+
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 		/* add SPIO 5 to group 0 */
 		val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
 		val |= AEU_INPUTS_ATTN_BITS_SPIO5;
@@ -5645,10 +6014,17 @@ static int bnx2x_init_func(struct bnx2x
 {
 	int port = BP_PORT(bp);
 	int func = BP_FUNC(bp);
+	u32 addr, val;
 	int i;
 
 	DP(BNX2X_MSG_MCP, "starting func init  func %x\n", func);
 
+	/* set MSI reconfigure capability */
+	addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0);
+	val = REG_RD(bp, addr);
+	val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0;
+	REG_WR(bp, addr, val);
+
 	i = FUNC_ILT_BASE(func);
 
 	bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
@@ -5678,9 +6054,6 @@ static int bnx2x_init_func(struct bnx2x
 	}
 	bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
 
-	if (CHIP_IS_E1H(bp))
-		REG_WR(bp, HC_REG_FUNC_NUM_P0 + port*4, func);
-
 	/* Reset PCIE errors for debug */
 	REG_WR(bp, 0x2114, 0xffffffff);
 	REG_WR(bp, 0x2120, 0xffffffff);
@@ -5809,20 +6182,19 @@ static void bnx2x_free_mem(struct bnx2x
 	int i;
 
 	/* fastpath */
+	/* Common */
 	for_each_queue(bp, i) {
 
-		/* Status blocks */
+		/* status blocks */
 		BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
 			       bnx2x_fp(bp, i, status_blk_mapping),
 			       sizeof(struct host_status_block) +
 			       sizeof(struct eth_tx_db_data));
+	}
+	/* Rx */
+	for_each_rx_queue(bp, i) {
 
-		/* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
-		BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
-		BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
-			       bnx2x_fp(bp, i, tx_desc_mapping),
-			       sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+		/* fastpath rx rings: rx_buf rx_desc rx_comp */
 		BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
 		BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
 			       bnx2x_fp(bp, i, rx_desc_mapping),
@@ -5839,6 +6211,15 @@ static void bnx2x_free_mem(struct bnx2x
 			       bnx2x_fp(bp, i, rx_sge_mapping),
 			       BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
 	}
+	/* Tx */
+	for_each_tx_queue(bp, i) {
+
+		/* fastpath tx rings: tx_buf tx_desc */
+		BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
+		BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
+			       bnx2x_fp(bp, i, tx_desc_mapping),
+			       sizeof(struct eth_tx_bd) * NUM_TX_BD);
+	}
 	/* end of fastpath */
 
 	BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -5881,29 +6262,20 @@ static int bnx2x_alloc_mem(struct bnx2x
 	int i;
 
 	/* fastpath */
+	/* Common */
 	for_each_queue(bp, i) {
 		bnx2x_fp(bp, i, bp) = bp;
 
-		/* Status blocks */
+		/* status blocks */
 		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
 				&bnx2x_fp(bp, i, status_blk_mapping),
 				sizeof(struct host_status_block) +
 				sizeof(struct eth_tx_db_data));
+	}
+	/* Rx */
+	for_each_rx_queue(bp, i) {
 
-		bnx2x_fp(bp, i, hw_tx_prods) =
-				(void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
-		bnx2x_fp(bp, i, tx_prods_mapping) =
-				bnx2x_fp(bp, i, status_blk_mapping) +
-				sizeof(struct host_status_block);
-
-		/* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
-		BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
-				sizeof(struct sw_tx_bd) * NUM_TX_BD);
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
-				&bnx2x_fp(bp, i, tx_desc_mapping),
-				sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+		/* fastpath rx rings: rx_buf rx_desc rx_comp */
 		BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
 				sizeof(struct sw_rx_bd) * NUM_RX_BD);
 		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
@@ -5922,6 +6294,23 @@ static int bnx2x_alloc_mem(struct bnx2x
 				&bnx2x_fp(bp, i, rx_sge_mapping),
 				BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
 	}
+	/* Tx */
+	for_each_tx_queue(bp, i) {
+
+		bnx2x_fp(bp, i, hw_tx_prods) =
+				(void *)(bnx2x_fp(bp, i, status_blk) + 1);
+
+		bnx2x_fp(bp, i, tx_prods_mapping) =
+				bnx2x_fp(bp, i, status_blk_mapping) +
+				sizeof(struct host_status_block);
+
+		/* fastpath tx rings: tx_buf tx_desc */
+		BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
+				sizeof(struct sw_tx_bd) * NUM_TX_BD);
+		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
+				&bnx2x_fp(bp, i, tx_desc_mapping),
+				sizeof(struct eth_tx_bd) * NUM_TX_BD);
+	}
 	/* end of fastpath */
 
 	BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
@@ -5975,7 +6364,7 @@ static void bnx2x_free_tx_skbs(struct bn
 {
 	int i;
 
-	for_each_queue(bp, i) {
+	for_each_tx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		u16 bd_cons = fp->tx_bd_cons;
@@ -5993,7 +6382,7 @@ static void bnx2x_free_rx_skbs(struct bn
 {
 	int i, j;
 
-	for_each_queue(bp, j) {
+	for_each_rx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		for (i = 0; i < NUM_RX_BD; i++) {
@@ -6005,8 +6394,7 @@ static void bnx2x_free_rx_skbs(struct bn
 
 			pci_unmap_single(bp->pdev,
 					 pci_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_size,
-					 PCI_DMA_FROMDEVICE);
+					 bp->rx_buf_size, PCI_DMA_FROMDEVICE);
 
 			rx_buf->skb = NULL;
 			dev_kfree_skb(skb);
@@ -6037,10 +6425,6 @@ static void bnx2x_free_msix_irqs(struct
 		   "state %x\n", i, bp->msix_table[i + offset].vector,
 		   bnx2x_fp(bp, i, state));
 
-		if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
-			BNX2X_ERR("IRQ of fp #%d being freed while "
-				  "state != closed\n", i);
-
 		free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]);
 	}
 }
@@ -6052,32 +6436,37 @@ static void bnx2x_free_irq(struct bnx2x
 		pci_disable_msix(bp->pdev);
 		bp->flags &= ~USING_MSIX_FLAG;
 
+	} else if (bp->flags & USING_MSI_FLAG) {
+		free_irq(bp->pdev->irq, bp->dev);
+		pci_disable_msi(bp->pdev);
+		bp->flags &= ~USING_MSI_FLAG;
+
 	} else
 		free_irq(bp->pdev->irq, bp->dev);
 }
 
 static int bnx2x_enable_msix(struct bnx2x *bp)
 {
-	int i, rc, offset;
+	int i, rc, offset = 1;
+	int igu_vec = 0;
 
-	bp->msix_table[0].entry = 0;
-	offset = 1;
-	DP(NETIF_MSG_IFUP, "msix_table[0].entry = 0 (slowpath)\n");
+	bp->msix_table[0].entry = igu_vec;
+	DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec);
 
 	for_each_queue(bp, i) {
-		int igu_vec = offset + i + BP_L_ID(bp);
-
+		igu_vec = BP_L_ID(bp) + offset + i;
 		bp->msix_table[i + offset].entry = igu_vec;
 		DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
 		   "(fastpath #%u)\n", i + offset, igu_vec, i);
 	}
 
 	rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
-			     bp->num_queues + offset);
+			     BNX2X_NUM_QUEUES(bp) + offset);
 	if (rc) {
-		DP(NETIF_MSG_IFUP, "MSI-X is not attainable\n");
-		return -1;
+		DP(NETIF_MSG_IFUP, "MSI-X is not attainable  rc %d\n", rc);
+		return rc;
 	}
+
 	bp->flags |= USING_MSIX_FLAG;
 
 	return 0;
@@ -6095,27 +6484,60 @@ static int bnx2x_req_msix_irqs(struct bn
 	}
 
 	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		sprintf(fp->name, "%s.fp%d", bp->dev->name, i);
 		rc = request_irq(bp->msix_table[i + offset].vector,
-				 bnx2x_msix_fp_int, 0,
-				 bp->dev->name, &bp->fp[i]);
+				 bnx2x_msix_fp_int, 0, fp->name, fp);
 		if (rc) {
-			BNX2X_ERR("request fp #%d irq failed  rc -%d\n",
-				  i + offset, -rc);
+			BNX2X_ERR("request fp #%d irq failed  rc %d\n", i, rc);
 			bnx2x_free_msix_irqs(bp);
 			return -EBUSY;
 		}
 
-		bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
+		fp->state = BNX2X_FP_STATE_IRQ;
 	}
 
+	i = BNX2X_NUM_QUEUES(bp);
+	if (is_multi(bp))
+		printk(KERN_INFO PFX
+		       "%s: using MSI-X  IRQs: sp %d  fp %d - %d\n",
+		       bp->dev->name, bp->msix_table[0].vector,
+		       bp->msix_table[offset].vector,
+		       bp->msix_table[offset + i - 1].vector);
+	else
+		printk(KERN_INFO PFX "%s: using MSI-X  IRQs: sp %d  fp %d\n",
+		       bp->dev->name, bp->msix_table[0].vector,
+		       bp->msix_table[offset + i - 1].vector);
+
+	return 0;
+}
+
+static int bnx2x_enable_msi(struct bnx2x *bp)
+{
+	int rc;
+
+	rc = pci_enable_msi(bp->pdev);
+	if (rc) {
+		DP(NETIF_MSG_IFUP, "MSI is not attainable\n");
+		return -1;
+	}
+	bp->flags |= USING_MSI_FLAG;
+
 	return 0;
 }
 
 static int bnx2x_req_irq(struct bnx2x *bp)
 {
+	unsigned long flags;
 	int rc;
 
-	rc = request_irq(bp->pdev->irq, bnx2x_interrupt, IRQF_SHARED,
+	if (bp->flags & USING_MSI_FLAG)
+		flags = 0;
+	else
+		flags = IRQF_SHARED;
+
+	rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags,
 			 bp->dev->name, bp->dev);
 	if (!rc)
 		bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
@@ -6127,7 +6549,7 @@ static void bnx2x_napi_enable(struct bnx
 {
 	int i;
 
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		napi_enable(&bnx2x_fp(bp, i, napi));
 }
 
@@ -6135,7 +6557,7 @@ static void bnx2x_napi_disable(struct bn
 {
 	int i;
 
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		napi_disable(&bnx2x_fp(bp, i, napi));
 }
 
@@ -6143,10 +6565,10 @@ static void bnx2x_netif_start(struct bnx
 {
 	if (atomic_dec_and_test(&bp->intr_sem)) {
 		if (netif_running(bp->dev)) {
-			if (bp->state == BNX2X_STATE_OPEN)
-				netif_wake_queue(bp->dev);
 			bnx2x_napi_enable(bp);
 			bnx2x_int_enable(bp);
+			if (bp->state == BNX2X_STATE_OPEN)
+				netif_tx_wake_all_queues(bp->dev);
 		}
 	}
 }
@@ -6155,10 +6577,8 @@ static void bnx2x_netif_stop(struct bnx2
 {
 	bnx2x_int_disable_sync(bp, disable_hw);
 	bnx2x_napi_disable(bp);
-	if (netif_running(bp->dev)) {
-		netif_tx_disable(bp->dev);
-		bp->dev->trans_start = jiffies;	/* prevent tx timeout */
-	}
+	netif_tx_disable(bp->dev);
+	bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 }
 
 /*
@@ -6174,9 +6594,9 @@ 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_6b = 2;
+	config->hdr.length = 2;
 	config->hdr.offset = port ? 32 : 0;
-	config->hdr.client_id = BP_CL_ID(bp);
+	config->hdr.client_id = bp->fp->cl_id;
 	config->hdr.reserved1 = 0;
 
 	/* primary MAC */
@@ -6201,9 +6621,9 @@ 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 = 0xffff;
-	config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
-	config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+	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 =
@@ -6232,9 +6652,9 @@ static void bnx2x_set_mac_addr_e1h(struc
 	 * unicasts: by func number
 	 * multicast: 20+FUNC*20, 20 each
 	 */
-	config->hdr.length_6b = 1;
+	config->hdr.length = 1;
 	config->hdr.offset = BP_FUNC(bp);
-	config->hdr.client_id = BP_CL_ID(bp);
+	config->hdr.client_id = bp->fp->cl_id;
 	config->hdr.reserved1 = 0;
 
 	/* primary MAC */
@@ -6268,7 +6688,7 @@ static int bnx2x_wait_ramrod(struct bnx2
 			     int *state_p, int poll)
 {
 	/* can take a while if any port is running */
-	int cnt = 500;
+	int cnt = 5000;
 
 	DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
 	   poll ? "polling" : "waiting", state, idx);
@@ -6286,8 +6706,12 @@ static int bnx2x_wait_ramrod(struct bnx2
 		}
 
 		mb(); /* state is changed by bnx2x_sp_event() */
-		if (*state_p == state)
+		if (*state_p == state) {
+#ifdef BNX2X_STOP_ON_ERROR
+			DP(NETIF_MSG_IFUP, "exit  (cnt %d)\n", 5000 - cnt);
+#endif
 			return 0;
+		}
 
 		msleep(1);
 	}
@@ -6320,19 +6744,68 @@ static int bnx2x_setup_leading(struct bn
 
 static int bnx2x_setup_multi(struct bnx2x *bp, int index)
 {
+	struct bnx2x_fastpath *fp = &bp->fp[index];
+
 	/* reset IGU state */
-	bnx2x_ack_sb(bp, bp->fp[index].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+	bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
 
 	/* SETUP ramrod */
-	bp->fp[index].state = BNX2X_FP_STATE_OPENING;
-	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
+	fp->state = BNX2X_FP_STATE_OPENING;
+	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0,
+		      fp->cl_id, 0);
 
 	/* Wait for completion */
 	return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
-				 &(bp->fp[index].state), 0);
+				 &(fp->state), 0);
 }
 
 static int bnx2x_poll(struct napi_struct *napi, int budget);
+
+static void bnx2x_set_int_mode(struct bnx2x *bp)
+{
+	int num_queues;
+
+	switch (int_mode) {
+	case INT_MODE_INTx:
+	case INT_MODE_MSI:
+		num_queues = 1;
+		bp->num_rx_queues = num_queues;
+		bp->num_tx_queues = num_queues;
+		DP(NETIF_MSG_IFUP,
+		   "set number of queues to %d\n", num_queues);
+		break;
+
+	case INT_MODE_MSIX:
+	default:
+		if (bp->multi_mode == ETH_RSS_MODE_REGULAR)
+			num_queues = min_t(u32, num_online_cpus(),
+					   BNX2X_MAX_QUEUES(bp));
+		else
+			num_queues = 1;
+		bp->num_rx_queues = num_queues;
+		bp->num_tx_queues = num_queues;
+		DP(NETIF_MSG_IFUP, "set number of rx queues to %d"
+		   "  number of tx queues to %d\n",
+		   bp->num_rx_queues, bp->num_tx_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
+		 */
+		if (bnx2x_enable_msix(bp)) {
+			/* failed to enable MSI-X */
+			num_queues = 1;
+			bp->num_rx_queues = num_queues;
+			bp->num_tx_queues = num_queues;
+			if (bp->multi_mode)
+				BNX2X_ERR("Multi requested but failed to "
+					  "enable MSI-X  set number of "
+					  "queues to %d\n", num_queues);
+		}
+		break;
+	}
+	bp->dev->real_num_tx_queues = bp->num_tx_queues;
+}
+
 static void bnx2x_set_rx_mode(struct net_device *dev);
 
 /* must be called with rtnl_lock */
@@ -6341,56 +6814,28 @@ static int bnx2x_nic_load(struct bnx2x *
 	u32 load_code;
 	int i, rc = 0;
 #ifdef BNX2X_STOP_ON_ERROR
+	DP(NETIF_MSG_IFUP, "enter  load_mode %d\n", load_mode);
 	if (unlikely(bp->panic))
 		return -EPERM;
 #endif
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
-	if (use_inta) {
-		bp->num_queues = 1;
-
-	} else {
-		if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
-			/* user requested number */
-			bp->num_queues = use_multi;
-
-		else if (use_multi)
-			bp->num_queues = min_t(u32, num_online_cpus(),
-					       BP_MAX_QUEUES(bp));
-		else
-			bp->num_queues = 1;
-
-		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) {
-			/* failed to enable MSI-X */
-			bp->num_queues = 1;
-			if (use_multi)
-				BNX2X_ERR("Multi requested but failed"
-					  " to enable MSI-X\n");
-		}
-	}
+	bnx2x_set_int_mode(bp);
 
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;
 
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		bnx2x_fp(bp, i, disable_tpa) =
 					((bp->flags & TPA_ENABLE_FLAG) == 0);
 
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
 			       bnx2x_poll, 128);
 
 #ifdef BNX2X_STOP_ON_ERROR
-	for_each_queue(bp, i) {
+	for_each_rx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		fp->poll_no_work = 0;
@@ -6408,14 +6853,22 @@ static int bnx2x_nic_load(struct bnx2x *
 			pci_disable_msix(bp->pdev);
 			goto load_error1;
 		}
-		printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
 	} else {
+		if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx))
+			bnx2x_enable_msi(bp);
 		bnx2x_ack_int(bp);
 		rc = bnx2x_req_irq(bp);
 		if (rc) {
 			BNX2X_ERR("IRQ request failed  rc %d, aborting\n", rc);
+			if (bp->flags & USING_MSI_FLAG)
+				pci_disable_msi(bp->pdev);
 			goto load_error1;
 		}
+		if (bp->flags & USING_MSI_FLAG) {
+			bp->dev->irq = bp->pdev->irq;
+			printk(KERN_INFO PFX "%s: using MSI  IRQ %d\n",
+			       bp->dev->name, bp->pdev->irq);
+		}
 	}
 
 	/* Send LOAD_REQUEST command to MCP
@@ -6438,11 +6891,11 @@ static int bnx2x_nic_load(struct bnx2x *
 	} else {
 		int port = BP_PORT(bp);
 
-		DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+		DP(NETIF_MSG_IFUP, "NO MCP - load counts      %d, %d, %d\n",
 		   load_count[0], load_count[1], load_count[2]);
 		load_count[0]++;
 		load_count[1 + port]++;
-		DP(NETIF_MSG_IFUP, "NO MCP new load counts       %d, %d, %d\n",
+		DP(NETIF_MSG_IFUP, "NO MCP - new load counts  %d, %d, %d\n",
 		   load_count[0], load_count[1], load_count[2]);
 		if (load_count[0] == 1)
 			load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
@@ -6489,7 +6942,7 @@ static int bnx2x_nic_load(struct bnx2x *
 
 	if (CHIP_IS_E1H(bp))
 		if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
-			BNX2X_ERR("!!!  mf_cfg function disabled\n");
+			DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
 			bp->state = BNX2X_STATE_DISABLED;
 		}
 
@@ -6506,19 +6959,19 @@ static int bnx2x_nic_load(struct bnx2x *
 		bnx2x_set_mac_addr_e1h(bp, 1);
 
 	if (bp->port.pmf)
-		bnx2x_initial_phy_init(bp);
+		bnx2x_initial_phy_init(bp, load_mode);
 
 	/* Start fast path */
 	switch (load_mode) {
 	case LOAD_NORMAL:
 		/* Tx queue should be only reenabled */
-		netif_wake_queue(bp->dev);
+		netif_tx_wake_all_queues(bp->dev);
 		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		break;
 
 	case LOAD_OPEN:
-		netif_start_queue(bp->dev);
+		netif_tx_start_all_queues(bp->dev);
 		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		break;
@@ -6551,33 +7004,32 @@ load_error3:
 	bp->port.pmf = 0;
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_queue(bp, i)
+	for_each_rx_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_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
-	/* TBD we really need to reset the chip
-	   if we want to recover from this */
 	return rc;
 }
 
 static int bnx2x_stop_multi(struct bnx2x *bp, int index)
 {
+	struct bnx2x_fastpath *fp = &bp->fp[index];
 	int rc;
 
 	/* halt the connection */
-	bp->fp[index].state = BNX2X_FP_STATE_HALTING;
-	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, index, 0);
+	fp->state = BNX2X_FP_STATE_HALTING;
+	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0);
 
 	/* Wait for completion */
 	rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
-			       &(bp->fp[index].state), 1);
+			       &(fp->state), 1);
 	if (rc) /* timeout */
 		return rc;
 
@@ -6586,13 +7038,13 @@ static int bnx2x_stop_multi(struct bnx2x
 
 	/* Wait for completion */
 	rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
-			       &(bp->fp[index].state), 1);
+			       &(fp->state), 1);
 	return rc;
 }
 
 static int bnx2x_stop_leading(struct bnx2x *bp)
 {
-	u16 dsb_sp_prod_idx;
+	__le16 dsb_sp_prod_idx;
 	/* if the other port is handling traffic,
 	   this can take a lot of time */
 	int cnt = 500;
@@ -6602,7 +7054,7 @@ static int bnx2x_stop_leading(struct bnx
 
 	/* Send HALT ramrod */
 	bp->fp[0].state = BNX2X_FP_STATE_HALTING;
-	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
+	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0);
 
 	/* Wait for completion */
 	rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
@@ -6626,9 +7078,8 @@ static int bnx2x_stop_leading(struct bnx
 			   *bp->dsb_sp_prod, dsb_sp_prod_idx);
 #ifdef BNX2X_STOP_ON_ERROR
 			bnx2x_panic();
-#else
-			rc = -EBUSY;
 #endif
+			rc = -EBUSY;
 			break;
 		}
 		cnt--;
@@ -6651,8 +7102,6 @@ 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);
 
-	REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
-
 	/* Clear ILT */
 	base = FUNC_ILT_BASE(func);
 	for (i = base; i < base + ILT_PER_FUNC; i++)
@@ -6734,15 +7183,14 @@ static int bnx2x_nic_unload(struct bnx2x
 	/* Release IRQs */
 	bnx2x_free_irq(bp);
 
-	/* Wait until tx fast path tasks complete */
-	for_each_queue(bp, i) {
+	/* Wait until tx fastpath tasks complete */
+	for_each_tx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
 		cnt = 1000;
-		smp_rmb();
 		while (bnx2x_has_tx_work_unload(fp)) {
 
-			bnx2x_tx_int(fp, 1000);
+			bnx2x_tx_int(fp);
 			if (!cnt) {
 				BNX2X_ERR("timeout waiting for queue[%d]\n",
 					  i);
@@ -6755,7 +7203,6 @@ static int bnx2x_nic_unload(struct bnx2x
 			}
 			cnt--;
 			msleep(1);
-			smp_rmb();
 		}
 	}
 	/* Give HW time to discard old tx messages */
@@ -6767,15 +7214,15 @@ static int bnx2x_nic_unload(struct bnx2x
 
 		bnx2x_set_mac_addr_e1(bp, 0);
 
-		for (i = 0; i < config->hdr.length_6b; i++)
+		for (i = 0; i < config->hdr.length; i++)
 			CAM_INVALIDATE(config->config_table[i]);
 
-		config->hdr.length_6b = i;
+		config->hdr.length = i;
 		if (CHIP_REV_IS_SLOW(bp))
 			config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
 		else
 			config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
-		config->hdr.client_id = BP_CL_ID(bp);
+		config->hdr.client_id = bp->fp->cl_id;
 		config->hdr.reserved1 = 0;
 
 		bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -6839,11 +7286,11 @@ unload_error:
 	if (!BP_NOMCP(bp))
 		reset_code = bnx2x_fw_command(bp, reset_code);
 	else {
-		DP(NETIF_MSG_IFDOWN, "NO MCP load counts      %d, %d, %d\n",
+		DP(NETIF_MSG_IFDOWN, "NO MCP - load counts      %d, %d, %d\n",
 		   load_count[0], load_count[1], load_count[2]);
 		load_count[0]--;
 		load_count[1 + port]--;
-		DP(NETIF_MSG_IFDOWN, "NO MCP new load counts  %d, %d, %d\n",
+		DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts  %d, %d, %d\n",
 		   load_count[0], load_count[1], load_count[2]);
 		if (load_count[0] == 0)
 			reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
@@ -6863,13 +7310,14 @@ unload_error:
 	/* Report UNLOAD_DONE to MCP */
 	if (!BP_NOMCP(bp))
 		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
 	bp->port.pmf = 0;
 
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
@@ -6911,6 +7359,64 @@ reset_task_exit:
  * Init service functions
  */
 
+static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func)
+{
+	switch (func) {
+	case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0;
+	case 1:	return PXP2_REG_PGL_PRETEND_FUNC_F1;
+	case 2:	return PXP2_REG_PGL_PRETEND_FUNC_F2;
+	case 3:	return PXP2_REG_PGL_PRETEND_FUNC_F3;
+	case 4:	return PXP2_REG_PGL_PRETEND_FUNC_F4;
+	case 5:	return PXP2_REG_PGL_PRETEND_FUNC_F5;
+	case 6:	return PXP2_REG_PGL_PRETEND_FUNC_F6;
+	case 7:	return PXP2_REG_PGL_PRETEND_FUNC_F7;
+	default:
+		BNX2X_ERR("Unsupported function index: %d\n", func);
+		return (u32)(-1);
+	}
+}
+
+static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func)
+{
+	u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val;
+
+	/* Flush all outstanding writes */
+	mmiowb();
+
+	/* Pretend to be function 0 */
+	REG_WR(bp, reg, 0);
+	/* Flush the GRC transaction (in the chip) */
+	new_val = REG_RD(bp, reg);
+	if (new_val != 0) {
+		BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n",
+			  new_val);
+		BUG();
+	}
+
+	/* From now we are in the "like-E1" mode */
+	bnx2x_int_disable(bp);
+
+	/* Flush all outstanding writes */
+	mmiowb();
+
+	/* Restore the original funtion settings */
+	REG_WR(bp, reg, orig_func);
+	new_val = REG_RD(bp, reg);
+	if (new_val != orig_func) {
+		BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n",
+			  orig_func, new_val);
+		BUG();
+	}
+}
+
+static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func)
+{
+	if (CHIP_IS_E1H(bp))
+		bnx2x_undi_int_disable_e1h(bp, func);
+	else
+		bnx2x_int_disable(bp);
+}
+
 static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 {
 	u32 val;
@@ -6961,8 +7467,7 @@ static void __devinit bnx2x_undi_unload(
 			/* now it's safe to release the lock */
 			bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
 
-			REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
-				    HC_REG_CONFIG_0), 0x1000);
+			bnx2x_undi_int_disable(bp, func);
 
 			/* close input traffic and wait for it */
 			/* Do not rcv packets to BRB */
@@ -7030,6 +7535,13 @@ static void __devinit bnx2x_get_common_h
 	bp->link_params.chip_id = bp->common.chip_id;
 	BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
 
+	val = (REG_RD(bp, 0x2874) & 0x55);
+	if ((bp->common.chip_id & 0x1) ||
+	    (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) {
+		bp->flags |= ONE_PORT_FLAG;
+		BNX2X_DEV_INFO("single port device\n");
+	}
+
 	val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
 	bp->common.flash_size = (NVRAM_1MB_SIZE <<
 				 (val & MCPR_NVM_CFG4_FLASH_SIZE));
@@ -7054,15 +7566,21 @@ static void __devinit bnx2x_get_common_h
 		BNX2X_ERR("BAD MCP validity signature\n");
 
 	bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
-	bp->common.board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
-
-	BNX2X_DEV_INFO("hw_config 0x%08x  board 0x%08x\n",
-		       bp->common.hw_config, bp->common.board);
+	BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config);
 
 	bp->link_params.hw_led_mode = ((bp->common.hw_config &
 					SHARED_HW_CFG_LED_MODE_MASK) >>
 				       SHARED_HW_CFG_LED_MODE_SHIFT);
 
+	bp->link_params.feature_config_flags = 0;
+	val = SHMEM_RD(bp, dev_info.shared_feature_config.config);
+	if (val & SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED)
+		bp->link_params.feature_config_flags |=
+				FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+	else
+		bp->link_params.feature_config_flags &=
+				~FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+
 	val = SHMEM_RD(bp, dev_info.bc_rev) >> 8;
 	bp->common.bc_ver = val;
 	BNX2X_DEV_INFO("bc_ver %X\n", val);
@@ -7081,7 +7599,7 @@ static void __devinit bnx2x_get_common_h
 		bp->flags |= NO_WOL_FLAG;
 	}
 	BNX2X_DEV_INFO("%sWoL capable\n",
-		       (bp->flags & NO_WOL_FLAG) ? "Not " : "");
+		       (bp->flags & NO_WOL_FLAG) ? "not " : "");
 
 	val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
 	val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
@@ -7174,48 +7692,60 @@ static void __devinit bnx2x_link_setting
 					       SUPPORTED_Asym_Pause);
 			break;
 
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
-			BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
 				       ext_phy_type);
 
 			bp->port.supported |= (SUPPORTED_10000baseT_Full |
+					       SUPPORTED_1000baseT_Full |
 					       SUPPORTED_FIBRE |
+					       SUPPORTED_Autoneg |
 					       SUPPORTED_Pause |
 					       SUPPORTED_Asym_Pause);
 			break;
 
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-			BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
 				       ext_phy_type);
 
 			bp->port.supported |= (SUPPORTED_10000baseT_Full |
+					       SUPPORTED_2500baseX_Full |
 					       SUPPORTED_1000baseT_Full |
 					       SUPPORTED_FIBRE |
+					       SUPPORTED_Autoneg |
 					       SUPPORTED_Pause |
 					       SUPPORTED_Asym_Pause);
 			break;
 
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
-			BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
 				       ext_phy_type);
 
 			bp->port.supported |= (SUPPORTED_10000baseT_Full |
-					       SUPPORTED_1000baseT_Full |
 					       SUPPORTED_FIBRE |
-					       SUPPORTED_Autoneg |
 					       SUPPORTED_Pause |
 					       SUPPORTED_Asym_Pause);
 			break;
 
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
-			BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
 				       ext_phy_type);
 
 			bp->port.supported |= (SUPPORTED_10000baseT_Full |
-					       SUPPORTED_2500baseX_Full |
 					       SUPPORTED_1000baseT_Full |
 					       SUPPORTED_FIBRE |
+					       SUPPORTED_Pause |
+					       SUPPORTED_Asym_Pause);
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
+				       ext_phy_type);
+
+			bp->port.supported |= (SUPPORTED_10000baseT_Full |
+					       SUPPORTED_1000baseT_Full |
 					       SUPPORTED_Autoneg |
+					       SUPPORTED_FIBRE |
 					       SUPPORTED_Pause |
 					       SUPPORTED_Asym_Pause);
 			break;
@@ -7231,6 +7761,22 @@ static void __devinit bnx2x_link_setting
 					       SUPPORTED_Asym_Pause);
 			break;
 
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n",
+				       ext_phy_type);
+
+			bp->port.supported |= (SUPPORTED_10baseT_Half |
+					       SUPPORTED_10baseT_Full |
+					       SUPPORTED_100baseT_Half |
+					       SUPPORTED_100baseT_Full |
+					       SUPPORTED_1000baseT_Full |
+					       SUPPORTED_10000baseT_Full |
+					       SUPPORTED_TP |
+					       SUPPORTED_Autoneg |
+					       SUPPORTED_Pause |
+					       SUPPORTED_Asym_Pause);
+			break;
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
 			BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
 				  bp->link_params.ext_phy_config);
@@ -7456,12 +8002,12 @@ static void __devinit bnx2x_get_port_hwi
 {
 	int port = BP_PORT(bp);
 	u32 val, val2;
+	u32 config;
+	u16 i;
 
 	bp->link_params.bp = bp;
 	bp->link_params.port = port;
 
-	bp->link_params.serdes_config =
-		SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
 	bp->link_params.lane_config =
 		SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
 	bp->link_params.ext_phy_config =
@@ -7474,10 +8020,35 @@ static void __devinit bnx2x_get_port_hwi
 	bp->port.link_config =
 		SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
 
-	BNX2X_DEV_INFO("serdes_config 0x%08x  lane_config 0x%08x\n"
-	     KERN_INFO "  ext_phy_config 0x%08x  speed_cap_mask 0x%08x"
-		       "  link_config 0x%08x\n",
-		       bp->link_params.serdes_config,
+	/* Get the 4 lanes xgxs config rx and tx */
+	for (i = 0; i < 2; i++) {
+		val = SHMEM_RD(bp,
+			   dev_info.port_hw_config[port].xgxs_config_rx[i<<1]);
+		bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff);
+		bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff);
+
+		val = SHMEM_RD(bp,
+			   dev_info.port_hw_config[port].xgxs_config_tx[i<<1]);
+		bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff);
+		bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
+	}
+
+	config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
+	if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
+		bp->link_params.feature_config_flags |=
+				FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+	else
+		bp->link_params.feature_config_flags &=
+				~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+
+	/* If the device is capable of WoL, set the default state according
+	 * to the HW
+	 */
+	bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
+		   (config & PORT_FEATURE_WOL_ENABLED));
+
+	BNX2X_DEV_INFO("lane_config 0x%08x  ext_phy_config 0x%08x"
+		       "  speed_cap_mask 0x%08x  link_config 0x%08x\n",
 		       bp->link_params.lane_config,
 		       bp->link_params.ext_phy_config,
 		       bp->link_params.speed_cap_mask, bp->port.link_config);
@@ -7524,7 +8095,7 @@ static int __devinit bnx2x_get_hwinfo(st
 				       "(0x%04x)\n",
 				       func, bp->e1hov, bp->e1hov);
 		} else {
-			BNX2X_DEV_INFO("Single function mode\n");
+			BNX2X_DEV_INFO("single function mode\n");
 			if (BP_E1HVN(bp)) {
 				BNX2X_ERR("!!!  No valid E1HOV for func %d,"
 					  "  aborting\n", func);
@@ -7574,6 +8145,7 @@ static int __devinit bnx2x_get_hwinfo(st
 static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 {
 	int func = BP_FUNC(bp);
+	int timer_interval;
 	int rc;
 
 	/* Disable interrupt handling until HW is initialized */
@@ -7597,6 +8169,16 @@ static int __devinit bnx2x_init_bp(struc
 		printk(KERN_ERR PFX
 		       "MCP disabled, must load devices in order!\n");
 
+	/* Set multi queue mode */
+	if ((multi_mode != ETH_RSS_MODE_DISABLED) &&
+	    ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) {
+		printk(KERN_ERR PFX
+		      "Multi disabled since int_mode requested is not MSI-X\n");
+		multi_mode = ETH_RSS_MODE_DISABLED;
+	}
+	bp->multi_mode = multi_mode;
+
+
 	/* Set TPA flags */
 	if (disable_tpa) {
 		bp->flags &= ~TPA_ENABLE_FLAG;
@@ -7606,18 +8188,18 @@ static int __devinit bnx2x_init_bp(struc
 		bp->dev->features |= NETIF_F_LRO;
 	}
 
+	bp->mrrs = mrrs;
 
 	bp->tx_ring_size = MAX_TX_AVAIL;
 	bp->rx_ring_size = MAX_RX_AVAIL;
 
 	bp->rx_csum = 1;
-	bp->rx_offset = 0;
 
 	bp->tx_ticks = 50;
 	bp->rx_ticks = 25;
 
-	bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
-	bp->current_interval = (poll ? poll : bp->timer_interval);
+	timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
+	bp->current_interval = (poll ? poll : timer_interval);
 
 	init_timer(&bp->timer);
 	bp->timer.expires = jiffies + bp->current_interval;
@@ -7662,14 +8244,16 @@ static int bnx2x_get_settings(struct net
 
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
-		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
 			cmd->port = PORT_FIBRE;
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
 			cmd->port = PORT_TP;
 			break;
 
@@ -7891,6 +8475,84 @@ static void bnx2x_get_drvinfo(struct net
 	info->regdump_len = 0;
 }
 
+#define IS_E1_ONLINE(info)	(((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
+#define IS_E1H_ONLINE(info)	(((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
+
+static int bnx2x_get_regs_len(struct net_device *dev)
+{
+	static u32 regdump_len;
+	struct bnx2x *bp = netdev_priv(dev);
+	int i;
+
+	if (regdump_len)
+		return regdump_len;
+
+	if (CHIP_IS_E1(bp)) {
+		for (i = 0; i < REGS_COUNT; i++)
+			if (IS_E1_ONLINE(reg_addrs[i].info))
+				regdump_len += reg_addrs[i].size;
+
+		for (i = 0; i < WREGS_COUNT_E1; i++)
+			if (IS_E1_ONLINE(wreg_addrs_e1[i].info))
+				regdump_len += wreg_addrs_e1[i].size *
+					(1 + wreg_addrs_e1[i].read_regs_count);
+
+	} else { /* E1H */
+		for (i = 0; i < REGS_COUNT; i++)
+			if (IS_E1H_ONLINE(reg_addrs[i].info))
+				regdump_len += reg_addrs[i].size;
+
+		for (i = 0; i < WREGS_COUNT_E1H; i++)
+			if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
+				regdump_len += wreg_addrs_e1h[i].size *
+					(1 + wreg_addrs_e1h[i].read_regs_count);
+	}
+	regdump_len *= 4;
+	regdump_len += sizeof(struct dump_hdr);
+
+	return regdump_len;
+}
+
+static void bnx2x_get_regs(struct net_device *dev,
+			   struct ethtool_regs *regs, void *_p)
+{
+	u32 *p = _p, i, j;
+	struct bnx2x *bp = netdev_priv(dev);
+	struct dump_hdr dump_hdr = {0};
+
+	regs->version = 0;
+	memset(p, 0, regs->len);
+
+	if (!netif_running(bp->dev))
+		return;
+
+	dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1;
+	dump_hdr.dump_sign = dump_sign_all;
+	dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR);
+	dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
+	dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
+	dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
+	dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
+
+	memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
+	p += dump_hdr.hdr_size + 1;
+
+	if (CHIP_IS_E1(bp)) {
+		for (i = 0; i < REGS_COUNT; i++)
+			if (IS_E1_ONLINE(reg_addrs[i].info))
+				for (j = 0; j < reg_addrs[i].size; j++)
+					*p++ = REG_RD(bp,
+						      reg_addrs[i].addr + j*4);
+
+	} else { /* E1H */
+		for (i = 0; i < REGS_COUNT; i++)
+			if (IS_E1H_ONLINE(reg_addrs[i].info))
+				for (j = 0; j < reg_addrs[i].size; j++)
+					*p++ = REG_RD(bp,
+						      reg_addrs[i].addr + j*4);
+	}
+}
+
 static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -8049,7 +8711,7 @@ static void bnx2x_disable_nvram_access(s
 			MCPR_NVM_ACCESS_ENABLE_WR_EN)));
 }
 
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
 				  u32 cmd_flags)
 {
 	int count, i, rc;
@@ -8085,8 +8747,7 @@ static int bnx2x_nvram_read_dword(struct
 			/* we read nvram data in cpu order
 			 * but ethtool sees it as an array of bytes
 			 * converting to big-endian will do the work */
-			val = cpu_to_be32(val);
-			*ret_val = val;
+			*ret_val = cpu_to_be32(val);
 			rc = 0;
 			break;
 		}
@@ -8100,7 +8761,7 @@ static int bnx2x_nvram_read(struct bnx2x
 {
 	int rc;
 	u32 cmd_flags;
-	u32 val;
+	__be32 val;
 
 	if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
 		DP(BNX2X_MSG_NVM,
@@ -8219,7 +8880,7 @@ static int bnx2x_nvram_write1(struct bnx
 	int rc;
 	u32 cmd_flags;
 	u32 align_offset;
-	u32 val;
+	__be32 val;
 
 	if (offset + buf_size > bp->common.flash_size) {
 		DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
@@ -8348,7 +9009,7 @@ static int bnx2x_set_eeprom(struct net_d
 			if ((bp->state == BNX2X_STATE_OPEN) ||
 			    (bp->state == BNX2X_STATE_DISABLED)) {
 				rc |= bnx2x_link_reset(&bp->link_params,
-						       &bp->link_vars);
+						       &bp->link_vars, 1);
 				rc |= bnx2x_phy_init(&bp->link_params,
 						     &bp->link_vars);
 			}
@@ -8438,7 +9099,8 @@ static void bnx2x_get_pauseparam(struct
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
-	epause->autoneg = (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
+	epause->autoneg = (bp->link_params.req_flow_ctrl ==
+			   BNX2X_FLOW_CTRL_AUTO) &&
 			  (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
 
 	epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
@@ -8570,8 +9232,7 @@ static const struct {
 	{ "nvram_test (online)" },
 	{ "interrupt_test (online)" },
 	{ "link_test (online)" },
-	{ "idle check (online)" },
-	{ "MC errors (online)" }
+	{ "idle check (online)" }
 };
 
 static int bnx2x_self_test_count(struct net_device *dev)
@@ -8759,23 +9420,23 @@ static int bnx2x_run_loopback(struct bnx
 	u16 len;
 	int rc = -ENODEV;
 
-	if (loopback_mode == BNX2X_MAC_LOOPBACK) {
+	/* check the loopback mode */
+	switch (loopback_mode) {
+	case BNX2X_PHY_LOOPBACK:
+		if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+			return -EINVAL;
+		break;
+	case BNX2X_MAC_LOOPBACK:
 		bp->link_params.loopback_mode = LOOPBACK_BMAC;
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-
-	} else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
-		u16 cnt = 1000;
-		bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
-		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-		/* wait until link state is restored */
-		if (link_up)
-			while (cnt-- && bnx2x_test_link(&bp->link_params,
-							&bp->link_vars))
-				msleep(10);
-	} else
+		break;
+	default:
 		return -EINVAL;
+	}
 
-	pkt_size = 1514;
+	/* prepare the loopback packet */
+	pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
+		     bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
 	skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
 	if (!skb) {
 		rc = -ENOMEM;
@@ -8787,6 +9448,7 @@ static int bnx2x_run_loopback(struct bnx
 	for (i = ETH_HLEN; i < pkt_size; i++)
 		packet[i] = (unsigned char) (i & 0xff);
 
+	/* send the loopback packet */
 	num_pkts = 0;
 	tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
 	rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
@@ -8811,12 +9473,10 @@ static int bnx2x_run_loopback(struct bnx
 
 	wmb();
 
-	fp->hw_tx_prods->bds_prod =
-		cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+	le16_add_cpu(&fp->hw_tx_prods->bds_prod, 1);
 	mb(); /* FW restriction: must not reorder writing nbd and packets */
-	fp->hw_tx_prods->packets_prod =
-		cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
-	DOORBELL(bp, FP_IDX(fp), 0);
+	le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+	DOORBELL(bp, fp->index, 0);
 
 	mmiowb();
 
@@ -8871,7 +9531,7 @@ test_loopback_exit:
 
 static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
 {
-	int rc = 0;
+	int rc = 0, res;
 
 	if (!netif_running(bp->dev))
 		return BNX2X_LOOPBACK_FAILED;
@@ -8879,14 +9539,16 @@ static int bnx2x_test_loopback(struct bn
 	bnx2x_netif_stop(bp, 1);
 	bnx2x_acquire_phy_lock(bp);
 
-	if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
-		DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
-		rc |= BNX2X_MAC_LOOPBACK_FAILED;
+	res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
+	if (res) {
+		DP(NETIF_MSG_PROBE, "  PHY loopback failed  (res %d)\n", res);
+		rc |= BNX2X_PHY_LOOPBACK_FAILED;
 	}
 
-	if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
-		DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
-		rc |= BNX2X_PHY_LOOPBACK_FAILED;
+	res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
+	if (res) {
+		DP(NETIF_MSG_PROBE, "  MAC loopback failed  (res %d)\n", res);
+		rc |= BNX2X_MAC_LOOPBACK_FAILED;
 	}
 
 	bnx2x_release_phy_lock(bp);
@@ -8913,14 +9575,14 @@ static int bnx2x_test_nvram(struct bnx2x
 		{ 0x778,  0x70 },
 		{     0,     0 }
 	};
-	u32 buf[0x350 / 4];
+	__be32 buf[0x350 / 4];
 	u8 *data = (u8 *)buf;
 	int i, rc;
 	u32 magic, csum;
 
 	rc = bnx2x_nvram_read(bp, 0, data, 4);
 	if (rc) {
-		DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
+		DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
 		goto test_nvram_exit;
 	}
 
@@ -8937,7 +9599,7 @@ static int bnx2x_test_nvram(struct bnx2x
 				      nvram_tbl[i].size);
 		if (rc) {
 			DP(NETIF_MSG_PROBE,
-			   "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
+			   "nvram_tbl[%d] read data (rc %d)\n", i, rc);
 			goto test_nvram_exit;
 		}
 
@@ -8962,12 +9624,12 @@ static int bnx2x_test_intr(struct bnx2x
 	if (!netif_running(bp->dev))
 		return -ENODEV;
 
-	config->hdr.length_6b = 0;
+	config->hdr.length = 0;
 	if (CHIP_IS_E1(bp))
 		config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
 	else
 		config->hdr.offset = BP_FUNC(bp);
-	config->hdr.client_id = BP_CL_ID(bp);
+	config->hdr.client_id = bp->fp->cl_id;
 	config->hdr.reserved1 = 0;
 
 	rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -9040,9 +9702,6 @@ static void bnx2x_self_test(struct net_d
 			buf[5] = 1;
 			etest->flags |= ETH_TEST_FL_FAILED;
 		}
-	buf[7] = bnx2x_mc_assert(bp);
-	if (buf[7] != 0)
-		etest->flags |= ETH_TEST_FL_FAILED;
 
 #ifdef BNX2X_EXTRA_DEBUG
 	bnx2x_panic_dump(bp);
@@ -9052,40 +9711,98 @@ static void bnx2x_self_test(struct net_d
 static const struct {
 	long offset;
 	int size;
+	u8 string[ETH_GSTRING_LEN];
+} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
+/* 1 */	{ Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
+	{ Q_STATS_OFFSET32(error_bytes_received_hi),
+						8, "[%d]: rx_error_bytes" },
+	{ Q_STATS_OFFSET32(total_unicast_packets_received_hi),
+						8, "[%d]: rx_ucast_packets" },
+	{ Q_STATS_OFFSET32(total_multicast_packets_received_hi),
+						8, "[%d]: rx_mcast_packets" },
+	{ Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
+						8, "[%d]: rx_bcast_packets" },
+	{ Q_STATS_OFFSET32(no_buff_discard_hi),	8, "[%d]: rx_discards" },
+	{ Q_STATS_OFFSET32(rx_err_discard_pkt),
+					 4, "[%d]: rx_phy_ip_err_discards"},
+	{ Q_STATS_OFFSET32(rx_skb_alloc_failed),
+					 4, "[%d]: rx_skb_alloc_discard" },
+	{ Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
+
+/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi),	8, "[%d]: tx_bytes" },
+	{ Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+							8, "[%d]: tx_packets" }
+};
+
+static const struct {
+	long offset;
+	int size;
 	u32 flags;
 #define STATS_FLAGS_PORT		1
 #define STATS_FLAGS_FUNC		2
+#define STATS_FLAGS_BOTH		(STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
 	u8 string[ETH_GSTRING_LEN];
 } bnx2x_stats_arr[BNX2X_NUM_STATS] = {
-/* 1 */	{ STATS_OFFSET32(valid_bytes_received_hi),
-				8, STATS_FLAGS_FUNC, "rx_bytes" },
+/* 1 */	{ STATS_OFFSET32(total_bytes_received_hi),
+				8, STATS_FLAGS_BOTH, "rx_bytes" },
 	{ STATS_OFFSET32(error_bytes_received_hi),
-				8, STATS_FLAGS_FUNC, "rx_error_bytes" },
-	{ STATS_OFFSET32(total_bytes_transmitted_hi),
-				8, STATS_FLAGS_FUNC, "tx_bytes" },
-	{ STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
-				8, STATS_FLAGS_PORT, "tx_error_bytes" },
+				8, STATS_FLAGS_BOTH, "rx_error_bytes" },
 	{ STATS_OFFSET32(total_unicast_packets_received_hi),
-				8, STATS_FLAGS_FUNC, "rx_ucast_packets" },
+				8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
 	{ STATS_OFFSET32(total_multicast_packets_received_hi),
-				8, STATS_FLAGS_FUNC, "rx_mcast_packets" },
+				8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
 	{ STATS_OFFSET32(total_broadcast_packets_received_hi),
-				8, STATS_FLAGS_FUNC, "rx_bcast_packets" },
-	{ STATS_OFFSET32(total_unicast_packets_transmitted_hi),
-				8, STATS_FLAGS_FUNC, "tx_packets" },
-	{ STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
-				8, STATS_FLAGS_PORT, "tx_mac_errors" },
-/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
-				8, STATS_FLAGS_PORT, "tx_carrier_errors" },
+				8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
 	{ STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
 				8, STATS_FLAGS_PORT, "rx_crc_errors" },
 	{ STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
 				8, STATS_FLAGS_PORT, "rx_align_errors" },
+	{ STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+				8, STATS_FLAGS_PORT, "rx_undersize_packets" },
+	{ STATS_OFFSET32(etherstatsoverrsizepkts_hi),
+				8, STATS_FLAGS_PORT, "rx_oversize_packets" },
+/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+				8, STATS_FLAGS_PORT, "rx_fragments" },
+	{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
+				8, STATS_FLAGS_PORT, "rx_jabbers" },
+	{ STATS_OFFSET32(no_buff_discard_hi),
+				8, STATS_FLAGS_BOTH, "rx_discards" },
+	{ STATS_OFFSET32(mac_filter_discard),
+				4, STATS_FLAGS_PORT, "rx_filtered_packets" },
+	{ STATS_OFFSET32(xxoverflow_discard),
+				4, STATS_FLAGS_PORT, "rx_fw_discards" },
+	{ STATS_OFFSET32(brb_drop_hi),
+				8, STATS_FLAGS_PORT, "rx_brb_discard" },
+	{ STATS_OFFSET32(brb_truncate_hi),
+				8, STATS_FLAGS_PORT, "rx_brb_truncate" },
+	{ STATS_OFFSET32(pause_frames_received_hi),
+				8, STATS_FLAGS_PORT, "rx_pause_frames" },
+	{ STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+				8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
+	{ STATS_OFFSET32(nig_timer_max),
+			4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
+/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
+				4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
+	{ STATS_OFFSET32(rx_skb_alloc_failed),
+				4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
+	{ STATS_OFFSET32(hw_csum_err),
+				4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
+
+	{ STATS_OFFSET32(total_bytes_transmitted_hi),
+				8, STATS_FLAGS_BOTH, "tx_bytes" },
+	{ STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
+				8, STATS_FLAGS_PORT, "tx_error_bytes" },
+	{ STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+				8, STATS_FLAGS_BOTH, "tx_packets" },
+	{ STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+				8, STATS_FLAGS_PORT, "tx_mac_errors" },
+	{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+				8, STATS_FLAGS_PORT, "tx_carrier_errors" },
 	{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
 				8, STATS_FLAGS_PORT, "tx_single_collisions" },
 	{ STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
 				8, STATS_FLAGS_PORT, "tx_multi_collisions" },
-	{ STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+/* 30 */{ STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
 				8, STATS_FLAGS_PORT, "tx_deferred" },
 	{ STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
 				8, STATS_FLAGS_PORT, "tx_excess_collisions" },
@@ -9093,14 +9810,6 @@ static const struct {
 				8, STATS_FLAGS_PORT, "tx_late_collisions" },
 	{ STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
 				8, STATS_FLAGS_PORT, "tx_total_collisions" },
-	{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
-				8, STATS_FLAGS_PORT, "rx_fragments" },
-/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
-				8, STATS_FLAGS_PORT, "rx_jabbers" },
-	{ STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
-				8, STATS_FLAGS_PORT, "rx_undersize_packets" },
-	{ STATS_OFFSET32(jabber_packets_received),
-				4, STATS_FLAGS_FUNC, "rx_oversize_packets" },
 	{ STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
 				8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
 	{ STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
@@ -9113,52 +9822,46 @@ static const struct {
 			8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
 	{ STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
 			8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
-	{ STATS_OFFSET32(etherstatspktsover1522octets_hi),
+/* 40 */{ STATS_OFFSET32(etherstatspktsover1522octets_hi),
 			8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
-/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
-				8, STATS_FLAGS_PORT, "rx_xon_frames" },
-	{ STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
-				8, STATS_FLAGS_PORT, "rx_xoff_frames" },
-	{ STATS_OFFSET32(tx_stat_outxonsent_hi),
-				8, STATS_FLAGS_PORT, "tx_xon_frames" },
-	{ STATS_OFFSET32(tx_stat_outxoffsent_hi),
-				8, STATS_FLAGS_PORT, "tx_xoff_frames" },
-	{ STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
-				8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
-	{ STATS_OFFSET32(mac_filter_discard),
-				4, STATS_FLAGS_PORT, "rx_filtered_packets" },
-	{ STATS_OFFSET32(no_buff_discard),
-				4, STATS_FLAGS_FUNC, "rx_discards" },
-	{ STATS_OFFSET32(xxoverflow_discard),
-				4, STATS_FLAGS_PORT, "rx_fw_discards" },
-	{ STATS_OFFSET32(brb_drop_hi),
-				8, STATS_FLAGS_PORT, "brb_discard" },
-	{ STATS_OFFSET32(brb_truncate_hi),
-				8, STATS_FLAGS_PORT, "brb_truncate" },
-/* 40 */{ STATS_OFFSET32(rx_err_discard_pkt),
-				4, STATS_FLAGS_FUNC, "rx_phy_ip_err_discards"},
-	{ STATS_OFFSET32(rx_skb_alloc_failed),
-				4, STATS_FLAGS_FUNC, "rx_skb_alloc_discard" },
-/* 42 */{ STATS_OFFSET32(hw_csum_err),
-				4, STATS_FLAGS_FUNC, "rx_csum_offload_errors" }
+	{ STATS_OFFSET32(pause_frames_sent_hi),
+				8, STATS_FLAGS_PORT, "tx_pause_frames" }
 };
 
-#define IS_NOT_E1HMF_STAT(bp, i) \
-		(IS_E1HMF(bp) && (bnx2x_stats_arr[i].flags & STATS_FLAGS_PORT))
+#define IS_PORT_STAT(i) \
+	((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
+#define IS_FUNC_STAT(i)		(bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
+#define IS_E1HMF_MODE_STAT(bp) \
+			(IS_E1HMF(bp) && !(bp->msglevel & BNX2X_MSG_STATS))
 
 static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int i, j;
+	int i, j, k;
 
 	switch (stringset) {
 	case ETH_SS_STATS:
-		for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
-			if (IS_NOT_E1HMF_STAT(bp, i))
-				continue;
-			strcpy(buf + j*ETH_GSTRING_LEN,
-			       bnx2x_stats_arr[i].string);
-			j++;
+		if (is_multi(bp)) {
+			k = 0;
+			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);
+				k += BNX2X_NUM_Q_STATS;
+			}
+			if (IS_E1HMF_MODE_STAT(bp))
+				break;
+			for (j = 0; j < BNX2X_NUM_STATS; j++)
+				strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+				       bnx2x_stats_arr[j].string);
+		} else {
+			for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+				if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+					continue;
+				strcpy(buf + j*ETH_GSTRING_LEN,
+				       bnx2x_stats_arr[i].string);
+				j++;
+			}
 		}
 		break;
 
@@ -9171,13 +9874,22 @@ 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 = 0;
+	int i, num_stats;
 
-	for (i = 0; i < BNX2X_NUM_STATS; i++) {
-		if (IS_NOT_E1HMF_STAT(bp, i))
-			continue;
-		num_stats++;
+	if (is_multi(bp)) {
+		num_stats = BNX2X_NUM_Q_STATS * BNX2X_NUM_QUEUES(bp);
+		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;
 }
 
@@ -9185,29 +9897,71 @@ static void bnx2x_get_ethtool_stats(stru
 				    struct ethtool_stats *stats, u64 *buf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	u32 *hw_stats = (u32 *)&bp->eth_stats;
-	int i, j;
-
-	for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
-		if (IS_NOT_E1HMF_STAT(bp, i))
-			continue;
+	u32 *hw_stats, *offset;
+	int i, j, k;
 
-		if (bnx2x_stats_arr[i].size == 0) {
-			/* skip this counter */
-			buf[j] = 0;
-			j++;
-			continue;
+	if (is_multi(bp)) {
+		k = 0;
+		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) {
+					/* skip this counter */
+					buf[k + j] = 0;
+					continue;
+				}
+				offset = (hw_stats +
+					  bnx2x_q_stats_arr[j].offset);
+				if (bnx2x_q_stats_arr[j].size == 4) {
+					/* 4-byte counter */
+					buf[k + j] = (u64) *offset;
+					continue;
+				}
+				/* 8-byte counter */
+				buf[k + j] = HILO_U64(*offset, *(offset + 1));
+			}
+			k += BNX2X_NUM_Q_STATS;
 		}
-		if (bnx2x_stats_arr[i].size == 4) {
-			/* 4-byte counter */
-			buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
+		if (IS_E1HMF_MODE_STAT(bp))
+			return;
+		hw_stats = (u32 *)&bp->eth_stats;
+		for (j = 0; j < BNX2X_NUM_STATS; j++) {
+			if (bnx2x_stats_arr[j].size == 0) {
+				/* skip this counter */
+				buf[k + j] = 0;
+				continue;
+			}
+			offset = (hw_stats + bnx2x_stats_arr[j].offset);
+			if (bnx2x_stats_arr[j].size == 4) {
+				/* 4-byte counter */
+				buf[k + j] = (u64) *offset;
+				continue;
+			}
+			/* 8-byte counter */
+			buf[k + j] = HILO_U64(*offset, *(offset + 1));
+		}
+	} else {
+		hw_stats = (u32 *)&bp->eth_stats;
+		for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+			if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+				continue;
+			if (bnx2x_stats_arr[i].size == 0) {
+				/* skip this counter */
+				buf[j] = 0;
+				j++;
+				continue;
+			}
+			offset = (hw_stats + bnx2x_stats_arr[i].offset);
+			if (bnx2x_stats_arr[i].size == 4) {
+				/* 4-byte counter */
+				buf[j] = (u64) *offset;
+				j++;
+				continue;
+			}
+			/* 8-byte counter */
+			buf[j] = HILO_U64(*offset, *(offset + 1));
 			j++;
-			continue;
 		}
-		/* 8-byte counter */
-		buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
-				  *(hw_stats + bnx2x_stats_arr[i].offset + 1));
-		j++;
 	}
 }
 
@@ -9254,6 +10008,8 @@ static struct ethtool_ops bnx2x_ethtool_
 	.get_settings		= bnx2x_get_settings,
 	.set_settings		= bnx2x_set_settings,
 	.get_drvinfo		= bnx2x_get_drvinfo,
+	.get_regs_len		= bnx2x_get_regs_len,
+	.get_regs		= bnx2x_get_regs,
 	.get_wol		= bnx2x_get_wol,
 	.set_wol		= bnx2x_set_wol,
 	.get_msglevel		= bnx2x_get_msglevel,
@@ -9366,25 +10122,41 @@ static int bnx2x_poll(struct napi_struct
 	bnx2x_update_fpsb_idx(fp);
 
 	if (bnx2x_has_tx_work(fp))
-		bnx2x_tx_int(fp, budget);
+		bnx2x_tx_int(fp);
 
-	if (bnx2x_has_rx_work(fp))
+	if (bnx2x_has_rx_work(fp)) {
 		work_done = bnx2x_rx_int(fp, budget);
-	rmb(); /* BNX2X_HAS_WORK() reads the status block */
 
-	/* must not complete if we consumed full budget */
-	if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
+		/* must not complete if we consumed full budget */
+		if (work_done >= budget)
+			goto poll_again;
+	}
+
+	/* BNX2X_HAS_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_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_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();
 
+	if (!BNX2X_HAS_WORK(fp)) {
 #ifdef BNX2X_STOP_ON_ERROR
 poll_panic:
 #endif
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
-		bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
+		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(fp), CSTORM_ID,
+		bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
 			     le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
 	}
+
+poll_again:
 	return work_done;
 }
 
@@ -9460,7 +10232,7 @@ static inline u32 bnx2x_xmit_type(struct
 		rc = XMIT_PLAIN;
 
 	else {
-		if (skb->protocol == ntohs(ETH_P_IPV6)) {
+		if (skb->protocol == htons(ETH_P_IPV6)) {
 			rc = XMIT_CSUM_V6;
 			if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
 				rc |= XMIT_CSUM_TCP;
@@ -9482,7 +10254,9 @@ static inline u32 bnx2x_xmit_type(struct
 }
 
 #if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
-/* check if packet requires linearization (packet is too fragmented) */
+/* check if packet requires linearization (packet is too fragmented)
+   no need to check fragmentation if page size > 8K (there will be no
+   violation to FW restrictions) */
 static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
 			     u32 xmit_type)
 {
@@ -9541,7 +10315,6 @@ static int bnx2x_pkt_req_lin(struct bnx2
 				wnd_sum -=
 					skb_shinfo(skb)->frags[wnd_idx].size;
 			}
-
 		} else {
 			/* in non-LSO too fragmented packet should always
 			   be linearized */
@@ -9569,6 +10342,7 @@ static int bnx2x_start_xmit(struct sk_bu
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	struct bnx2x_fastpath *fp;
+	struct netdev_queue *txq;
 	struct sw_tx_bd *tx_buf;
 	struct eth_tx_bd *tx_bd;
 	struct eth_tx_parse_bd *pbd = NULL;
@@ -9585,12 +10359,14 @@ static int bnx2x_start_xmit(struct sk_bu
 		return NETDEV_TX_BUSY;
 #endif
 
-	fp_index = (smp_processor_id() % bp->num_queues);
+	fp_index = skb_get_queue_mapping(skb);
+	txq = netdev_get_tx_queue(dev, fp_index);
+
 	fp = &bp->fp[fp_index];
 
 	if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
-		bp->eth_stats.driver_xoff++,
-		netif_stop_queue(dev);
+		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;
 	}
@@ -9601,8 +10377,9 @@ static int bnx2x_start_xmit(struct sk_bu
 	   ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
 
 #if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
-	/* First, check if we need to linearize the skb
-	   (due to FW restrictions) */
+	/* First, check if we need to linearize the skb (due to FW
+	   restrictions). No need to check fragmentation if page size > 8K
+	   (there will be no violation to FW restrictions) */
 	if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
 		/* Statistics of linearization */
 		bp->lin_cnt++;
@@ -9667,9 +10444,9 @@ static int bnx2x_start_xmit(struct sk_bu
 		hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
 
 		/* for now NS flag is not used in Linux */
-		pbd->global_data = (hlen |
-				    ((skb->protocol == ntohs(ETH_P_8021Q)) <<
-				     ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+		pbd->global_data =
+			(hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+				 ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
 
 		pbd->ip_hlen = (skb_transport_header(skb) -
 				skb_network_header(skb)) / 2;
@@ -9813,12 +10590,10 @@ static int bnx2x_start_xmit(struct sk_bu
 	 */
 	wmb();
 
-	fp->hw_tx_prods->bds_prod =
-		cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+	le16_add_cpu(&fp->hw_tx_prods->bds_prod, nbd);
 	mb(); /* FW restriction: must not reorder writing nbd and packets */
-	fp->hw_tx_prods->packets_prod =
-		cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
-	DOORBELL(bp, FP_IDX(fp), 0);
+	le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+	DOORBELL(bp, fp->index, 0);
 
 	mmiowb();
 
@@ -9829,10 +10604,10 @@ static int bnx2x_start_xmit(struct sk_bu
 		/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
 		   if we put Tx into XOFF state. */
 		smp_mb();
-		netif_stop_queue(dev);
-		bp->eth_stats.driver_xoff++;
+		netif_tx_stop_queue(txq);
+		fp->eth_q_stats.driver_xoff++;
 		if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
-			netif_wake_queue(dev);
+			netif_tx_wake_queue(txq);
 	}
 	fp->tx_pkt++;
 
@@ -9865,7 +10640,7 @@ static int bnx2x_close(struct net_device
 	return 0;
 }
 
-/* called with netif_tx_lock from set_multicast */
+/* called with netif_tx_lock from dev_mcast.c */
 static void bnx2x_set_rx_mode(struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -9924,7 +10699,7 @@ static void bnx2x_set_rx_mode(struct net
 				   config->config_table[i].
 						cam_entry.lsb_mac_addr);
 			}
-			old = config->hdr.length_6b;
+			old = config->hdr.length;
 			if (old > i) {
 				for (; i < old; i++) {
 					if (CAM_IS_INVALID(config->
@@ -9943,9 +10718,9 @@ static void bnx2x_set_rx_mode(struct net
 			else
 				offset = BNX2X_MAX_MULTICAST*(1 + port);
 
-			config->hdr.length_6b = i;
+			config->hdr.length = i;
 			config->hdr.offset = offset;
-			config->hdr.client_id = BP_CL_ID(bp);
+			config->hdr.client_id = bp->fp->cl_id;
 			config->hdr.reserved1 = 0;
 
 			bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -10131,7 +10906,7 @@ static const struct net_device_ops bnx2x
 	.ndo_open		= bnx2x_open,
 	.ndo_stop		= bnx2x_close,
 	.ndo_start_xmit		= bnx2x_start_xmit,
-	.ndo_set_multicast_list = bnx2x_set_rx_mode,
+	.ndo_set_multicast_list	= bnx2x_set_rx_mode,
 	.ndo_set_mac_address	= bnx2x_change_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= bnx2x_ioctl,
@@ -10145,7 +10920,6 @@ static const struct net_device_ops bnx2x
 #endif
 };
 
-
 static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 				    struct net_device *dev)
 {
@@ -10208,16 +10982,16 @@ static int __devinit bnx2x_init_dev(stru
 		goto err_out_release;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
 		bp->flags |= USING_DAC_FLAG;
-		if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
 			printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
 			       " failed, aborting\n");
 			rc = -EIO;
 			goto err_out_release;
 		}
 
-	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+	} else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
 		printk(KERN_ERR PFX "System does not support DMA,"
 		       " aborting\n");
 		rc = -EIO;
@@ -10324,7 +11098,7 @@ static int __devinit bnx2x_init_one(stru
 		printk(KERN_INFO "%s", version);
 
 	/* dev zeroed in init_etherdev */
-	dev = alloc_etherdev(sizeof(*bp));
+	dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
 	if (!dev) {
 		printk(KERN_ERR PFX "Cannot allocate net device\n");
 		return -ENOMEM;
@@ -10351,14 +11125,14 @@ static int __devinit bnx2x_init_one(stru
 		goto init_one_exit;
 	}
 
-	bp->common.name = board_info[ent->driver_data].name;
 	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
-	       " IRQ %d, ", dev->name, bp->common.name,
+	       " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
 	       (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
 	       bnx2x_get_pcie_width(bp),
 	       (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
 	       dev->base_addr, bp->pdev->irq);
 	printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
+
 	return 0;
 
 init_one_exit:
@@ -10490,15 +11264,15 @@ static int bnx2x_eeh_nic_unload(struct b
 		struct mac_configuration_cmd *config =
 						bnx2x_sp(bp, mcast_config);
 
-		for (i = 0; i < config->hdr.length_6b; i++)
+		for (i = 0; i < config->hdr.length; i++)
 			CAM_INVALIDATE(config->config_table[i]);
 	}
 
 	/* Free SKBs, SGEs, TPA pool and driver internals */
 	bnx2x_free_skbs(bp);
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
 	bnx2x_free_mem(bp);
 
@@ -10625,8 +11399,8 @@ static void bnx2x_io_resume(struct pci_d
 
 static struct pci_error_handlers bnx2x_err_handler = {
 	.error_detected = bnx2x_io_error_detected,
-	.slot_reset = bnx2x_io_slot_reset,
-	.resume = bnx2x_io_resume,
+	.slot_reset     = bnx2x_io_slot_reset,
+	.resume         = bnx2x_io_resume,
 };
 
 static struct pci_driver bnx2x_pci_driver = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bnx2x_reg.h linux-libre-2.6.30-gnu1/drivers/net/bnx2x_reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/bnx2x_reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bnx2x_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -30,8 +30,20 @@
    address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
    BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
 #define BRB1_REG_FREE_LIST_PRS_CRDT				 0x60200
+/* [RW 10] The number of free blocks above which the High_llfc signal to
+   interface #n is de-asserted. */
+#define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0			 0x6014c
+/* [RW 10] The number of free blocks below which the High_llfc signal to
+   interface #n is asserted. */
+#define BRB1_REG_HIGH_LLFC_LOW_THRESHOLD_0			 0x6013c
 /* [RW 23] LL RAM data. */
 #define BRB1_REG_LL_RAM 					 0x61000
+/* [RW 10] The number of free blocks above which the Low_llfc signal to
+   interface #n is de-asserted. */
+#define BRB1_REG_LOW_LLFC_HIGH_THRESHOLD_0			 0x6016c
+/* [RW 10] The number of free blocks below which the Low_llfc signal to
+   interface #n is asserted. */
+#define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0			 0x6015c
 /* [R 24] The number of full blocks. */
 #define BRB1_REG_NUM_OF_FULL_BLOCKS				 0x60090
 /* [ST 32] The number of cycles that the write_full signal towards MAC #0
@@ -125,6 +137,10 @@
    stands for weight 8 (the most prioritised); 1 stands for weight 1(least
    prioritised); 2 stands for weight 2; tc. */
 #define CCM_REG_CQM_P_WEIGHT					 0xd00b8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CQM_S_WEIGHT					 0xd00bc
 /* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
    acknowledge output is deasserted; all other signals are treated as usual;
    if 1 - normal activity. */
@@ -132,6 +148,10 @@
 /* [RC 1] Set when the message length mismatch (relative to last indication)
    at the SDM interface is detected. */
 #define CCM_REG_CSDM_LENGTH_MIS 				 0xd0170
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CSDM_WEIGHT					 0xd00b4
 /* [RW 28] The CM header for QM formatting in case of an error in the QM
    inputs. */
 #define CCM_REG_ERR_CCM_HDR					 0xd0094
@@ -211,6 +231,11 @@
 /* [RC 1] Set when the message length mismatch (relative to last indication)
    at the STORM interface is detected. */
 #define CCM_REG_STORM_LENGTH_MIS				 0xd016c
+/* [RW 3] The weight of the STORM input in the WRR (Weighted Round robin)
+   mechanism. 0 stands for weight 8 (the most prioritised); 1 stands for
+   weight 1(least prioritised); 2 stands for weight 2 (more prioritised);
+   tc. */
+#define CCM_REG_STORM_WEIGHT					 0xd009c
 /* [RW 1] Input tsem Interface enable. If 0 - the valid input is
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
@@ -323,7 +348,11 @@
    set one of these bits. the bit description can be found in CFC
    specifications */
 #define CFC_REG_ERROR_VECTOR					 0x10403c
+/* [WB 93] LCID info ram access */
+#define CFC_REG_INFO_RAM					 0x105000
+#define CFC_REG_INFO_RAM_SIZE					 1024
 #define CFC_REG_INIT_REG					 0x10404c
+#define CFC_REG_INTERFACES					 0x104058
 /* [RW 24] {weight_load_client7[2:0] to weight_load_client0[2:0]}. this
    field allows changing the priorities of the weighted-round-robin arbiter
    which selects which CFC load client should be served next */
@@ -337,8 +366,6 @@
 #define CFC_REG_NUM_LCIDS_ALLOC 				 0x104020
 /* [R 9] Number of Arriving LCIDs in Link List Block */
 #define CFC_REG_NUM_LCIDS_ARRIVING				 0x104004
-/* [R 9] Number of Inside LCIDs in Link List Block */
-#define CFC_REG_NUM_LCIDS_INSIDE				 0x104008
 /* [R 9] Number of Leaving LCIDs in Link List Block */
 #define CFC_REG_NUM_LCIDS_LEAVING				 0x104018
 /* [RW 8] The event id for aggregated interrupt 0 */
@@ -730,6 +757,7 @@
 #define DORQ_REG_SHRT_CMHEAD					 0x170054
 #define HC_CONFIG_0_REG_ATTN_BIT_EN_0				 (0x1<<4)
 #define HC_CONFIG_0_REG_INT_LINE_EN_0				 (0x1<<3)
+#define HC_CONFIG_0_REG_MSI_ATTN_EN_0				 (0x1<<7)
 #define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0			 (0x1<<2)
 #define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 			 (0x1<<1)
 #define HC_REG_AGG_INT_0					 0x108050
@@ -1410,6 +1438,29 @@
    This is the result value of the pin; not the drive value. Writing these
    bits will have not effect. */
 #define MISC_REG_GPIO						 0xa490
+/* [RW 8] These bits enable the GPIO_INTs to signals event to the
+   IGU/MCP.according to the following map: [0] p0_gpio_0; [1] p0_gpio_1; [2]
+   p0_gpio_2; [3] p0_gpio_3; [4] p1_gpio_0; [5] p1_gpio_1; [6] p1_gpio_2;
+   [7] p1_gpio_3; */
+#define MISC_REG_GPIO_EVENT_EN					 0xa2bc
+/* [RW 32] GPIO INT. [31-28] OLD_CLR port1; [27-24] OLD_CLR port0; Writing a
+   '1' to these bit clears the corresponding bit in the #OLD_VALUE register.
+   This will acknowledge an interrupt on the falling edge of corresponding
+   GPIO input (reset value 0). [23-16] OLD_SET [23-16] port1; OLD_SET port0;
+   Writing a '1' to these bit sets the corresponding bit in the #OLD_VALUE
+   register. This will acknowledge an interrupt on the rising edge of
+   corresponding SPIO input (reset value 0). [15-12] OLD_VALUE [11-8] port1;
+   OLD_VALUE port0; RO; These bits indicate the old value of the GPIO input
+   value. When the ~INT_STATE bit is set; this bit indicates the OLD value
+   of the pin such that if ~INT_STATE is set and this bit is '0'; then the
+   interrupt is due to a low to high edge. If ~INT_STATE is set and this bit
+   is '1'; then the interrupt is due to a high to low edge (reset value 0).
+   [7-4] INT_STATE port1; [3-0] INT_STATE RO port0; These bits indicate the
+   current GPIO interrupt state for each GPIO pin. This bit is cleared when
+   the appropriate #OLD_SET or #OLD_CLR command bit is written. This bit is
+   set when the GPIO input does not match the current value in #OLD_VALUE
+   (reset value 0). */
+#define MISC_REG_GPIO_INT					 0xa494
 /* [R 28] this field hold the last information that caused reserved
    attention. bits [19:0] - address; [22:20] function; [23] reserved;
    [27:24] the master that caused the attention - according to the following
@@ -1554,6 +1605,14 @@
    command bit is written. This bit is set when the SPIO input does not
    match the current value in #OLD_VALUE (reset value 0). */
 #define MISC_REG_SPIO_INT					 0xa500
+/* [RW 32] reload value for counter 4 if reload; the value will be reload if
+   the counter reached zero and the reload bit
+   (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */
+#define MISC_REG_SW_TIMER_RELOAD_VAL_4				 0xa2fc
+/* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses
+   in this register. addres 0 - timer 1; address - timer 2ï¿½address 7 -
+   timer 8 */
+#define MISC_REG_SW_TIMER_VAL					 0xa5c0
 /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
    loaded; 0-prepare; -unprepare */
 #define MISC_REG_UNPREPARED					 0xa424
@@ -1660,6 +1719,19 @@
 /* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3;
    9-11PHY7; 12 MAC4; 13-15 PHY10; */
 #define NIG_REG_LED_MODE_P0					 0x102f0
+/* [RW 3] for port0 enable for llfc ppp and pause. b0 - brb1 enable; b1-
+   tsdm enable; b2- usdm enable */
+#define NIG_REG_LLFC_EGRESS_SRC_ENABLE_0			 0x16070
+/* [RW 1] SAFC enable for port0. This register may get 1 only when
+   ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same
+   port */
+#define NIG_REG_LLFC_ENABLE_0					 0x16208
+/* [RW 16] classes are high-priority for port0 */
+#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0			 0x16058
+/* [RW 16] classes are low-priority for port0 */
+#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0			 0x16060
+/* [RW 1] Output enable of message to LLFC BMAC IF for port0 */
+#define NIG_REG_LLFC_OUT_EN_0					 0x160c8
 #define NIG_REG_LLH0_ACPI_PAT_0_CRC				 0x1015c
 #define NIG_REG_LLH0_ACPI_PAT_6_LEN				 0x10154
 #define NIG_REG_LLH0_BRB1_DRV_MASK				 0x10244
@@ -1730,6 +1802,10 @@
 #define NIG_REG_NIG_INT_STS_1					 0x103c0
 /* [R 32] Parity register #0 read */
 #define NIG_REG_NIG_PRTY_STS					 0x103d0
+/* [RW 1] Pause enable for port0. This register may get 1 only when
+   ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same
+   port */
+#define NIG_REG_PAUSE_ENABLE_0					 0x160c0
 /* [RW 1] Input enable for RX PBF LP IF */
 #define NIG_REG_PBF_LB_IN_EN					 0x100b4
 /* [RW 1] Value of this register will be transmitted to port swap when
@@ -1739,6 +1815,10 @@
 #define NIG_REG_PRS_EOP_OUT_EN					 0x10104
 /* [RW 1] Input enable for RX parser request IF */
 #define NIG_REG_PRS_REQ_IN_EN					 0x100b8
+/* [RW 5] control to serdes - CL45 DEVAD */
+#define NIG_REG_SERDES0_CTRL_MD_DEVAD				 0x10370
+/* [RW 1] control to serdes; 0 - clause 45; 1 - clause 22 */
+#define NIG_REG_SERDES0_CTRL_MD_ST				 0x1036c
 /* [RW 5] control to serdes - CL22 PHY_ADD and CL45 PRTAD */
 #define NIG_REG_SERDES0_CTRL_PHY_ADDR				 0x10374
 /* [R 1] status from serdes0 that inputs to interrupt logic of link status */
@@ -1885,6 +1965,7 @@
 #define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2			 0x400e4
 #define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3			 0x400e8
 #define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4			 0x400ec
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5			 0x400f0
 /* [RW 32] The CM header for flush message where 'load existed' bit in CFC
    load response is set and packet type is 0. Used in packet start message
    to TCM. */
@@ -1893,6 +1974,7 @@
 #define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2			 0x400c4
 #define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3			 0x400c8
 #define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4			 0x400cc
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5			 0x400d0
 /* [RW 32] The CM header for a match and packet type 1 for loopback port.
    Used in packet start message to TCM. */
 #define PRS_REG_CM_HDR_LOOPBACK_TYPE_1				 0x4009c
@@ -2035,6 +2117,19 @@
 #define PXP2_REG_PGL_INT_XSDM_5 				 0x1204e8
 #define PXP2_REG_PGL_INT_XSDM_6 				 0x1204ec
 #define PXP2_REG_PGL_INT_XSDM_7 				 0x1204f0
+/* [RW 3] this field allows one function to pretend being another function
+   when accessing any BAR mapped resource within the device. the value of
+   the field is the number of the function that will be accessed
+   effectively. after software write to this bit it must read it in order to
+   know that the new value is updated */
+#define PXP2_REG_PGL_PRETEND_FUNC_F0				 0x120674
+#define PXP2_REG_PGL_PRETEND_FUNC_F1				 0x120678
+#define PXP2_REG_PGL_PRETEND_FUNC_F2				 0x12067c
+#define PXP2_REG_PGL_PRETEND_FUNC_F3				 0x120680
+#define PXP2_REG_PGL_PRETEND_FUNC_F4				 0x120684
+#define PXP2_REG_PGL_PRETEND_FUNC_F5				 0x120688
+#define PXP2_REG_PGL_PRETEND_FUNC_F6				 0x12068c
+#define PXP2_REG_PGL_PRETEND_FUNC_F7				 0x120690
 /* [R 1] this bit indicates that a read request was blocked because of
    bus_master_en was deasserted */
 #define PXP2_REG_PGL_READ_BLOCKED				 0x120568
@@ -2498,6 +2593,11 @@
    considered zero so practically there are only 20 bits in this register;
    queues 63-0 */
 #define QM_REG_BASEADDR 					 0x168900
+/* [RW 32] The base logical address (in bytes) of each physical queue. The
+   index I represents the physical queue number. The 12 lsbs are ignore and
+   considered zero so practically there are only 20 bits in this register;
+   queues 127-64 */
+#define QM_REG_BASEADDR_EXT_A					 0x16e100
 /* [RW 16] The byte credit cost for each task. This value is for both ports */
 #define QM_REG_BYTECRDCOST					 0x168234
 /* [RW 16] The initial byte credit value for both ports. */
@@ -3438,6 +3538,16 @@
 #define SRC_REG_KEYRSS0_0					 0x40408
 #define SRC_REG_KEYRSS0_7					 0x40424
 #define SRC_REG_KEYRSS1_9					 0x40454
+#define SRC_REG_KEYSEARCH_0					 0x40458
+#define SRC_REG_KEYSEARCH_1					 0x4045c
+#define SRC_REG_KEYSEARCH_2					 0x40460
+#define SRC_REG_KEYSEARCH_3					 0x40464
+#define SRC_REG_KEYSEARCH_4					 0x40468
+#define SRC_REG_KEYSEARCH_5					 0x4046c
+#define SRC_REG_KEYSEARCH_6					 0x40470
+#define SRC_REG_KEYSEARCH_7					 0x40474
+#define SRC_REG_KEYSEARCH_8					 0x40478
+#define SRC_REG_KEYSEARCH_9					 0x4047c
 #define SRC_REG_LASTFREE0					 0x40530
 #define SRC_REG_NUMBER_HASH_BITS0				 0x40400
 /* [RW 1] Reset internal state machines. */
@@ -3481,6 +3591,10 @@
 /* [RC 1] Message length mismatch (relative to last indication) at the In#9
    interface. */
 #define TCM_REG_CSEM_LENGTH_MIS 				 0x50174
+/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_CSEM_WEIGHT					 0x500bc
 /* [RW 8] The Event ID in case of ErrorFlg is set in the input message. */
 #define TCM_REG_ERR_EVNT_ID					 0x500a0
 /* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -3524,6 +3638,7 @@
 #define TCM_REG_N_SM_CTX_LD_2					 0x50058
 #define TCM_REG_N_SM_CTX_LD_3					 0x5005c
 #define TCM_REG_N_SM_CTX_LD_4					 0x50060
+#define TCM_REG_N_SM_CTX_LD_5					 0x50064
 /* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
    acknowledge output is deasserted; all other signals are treated as usual;
    if 1 - normal activity. */
@@ -3563,6 +3678,10 @@
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
 #define TCM_REG_STORM_TCM_IFEN					 0x50010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_STORM_WEIGHT					 0x500ac
 /* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
    acknowledge output is deasserted; all other signals are treated as usual;
    if 1 - normal activity. */
@@ -3598,10 +3717,22 @@
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
 #define TCM_REG_TM_TCM_IFEN					 0x5001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TM_WEIGHT					 0x500d0
 /* [RW 6] QM output initial credit. Max credit available - 32.Write writes
    the initial credit value; read returns the current value of the credit
    counter. Must be initialized to 32 at start-up. */
 #define TCM_REG_TQM_INIT_CRD					 0x5021c
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_P_WEIGHT					 0x500c8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_S_WEIGHT					 0x500cc
 /* [RW 28] The CM header value for QM request (primary). */
 #define TCM_REG_TQM_TCM_HDR_P					 0x50090
 /* [RW 28] The CM header value for QM request (secondary). */
@@ -3628,6 +3759,10 @@
 /* [RC 1] Message length mismatch (relative to last indication) at the In#8
    interface. */
 #define TCM_REG_USEM_LENGTH_MIS 				 0x50170
+/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_USEM_WEIGHT					 0x500b8
 /* [RW 21] Indirect access to the descriptor table of the XX protection
    mechanism. The fields are: [5:0] - length of the message; 15:6] - message
    pointer; 20:16] - next pointer. */
@@ -3677,6 +3812,7 @@
 #define TM_REG_EN_CL1_INPUT					 0x16400c
 /* [RW 1] Enable client2 input. */
 #define TM_REG_EN_CL2_INPUT					 0x164010
+#define TM_REG_EN_LINEAR0_TIMER 				 0x164014
 /* [RW 1] Enable real time counter. */
 #define TM_REG_EN_REAL_TIME_CNT 				 0x1640d8
 /* [RW 1] Enable for Timers state machines. */
@@ -3684,14 +3820,22 @@
 /* [RW 4] Load value for expiration credit cnt. CFC max number of
    outstanding load requests for timers (expiration) context loading. */
 #define TM_REG_EXP_CRDCNT_VAL					 0x164238
+/* [RW 32] Linear0 logic address. */
+#define TM_REG_LIN0_LOGIC_ADDR					 0x164240
 /* [RW 18] Linear0 Max active cid (in banks of 32 entries). */
 #define TM_REG_LIN0_MAX_ACTIVE_CID				 0x164048
 /* [WB 64] Linear0 phy address. */
 #define TM_REG_LIN0_PHY_ADDR					 0x164270
+/* [RW 1] Linear0 physical address valid. */
+#define TM_REG_LIN0_PHY_ADDR_VALID				 0x164248
 /* [RW 24] Linear0 array scan timeout. */
 #define TM_REG_LIN0_SCAN_TIME					 0x16403c
+/* [RW 32] Linear1 logic address. */
+#define TM_REG_LIN1_LOGIC_ADDR					 0x164250
 /* [WB 64] Linear1 phy address. */
 #define TM_REG_LIN1_PHY_ADDR					 0x164280
+/* [RW 1] Linear1 physical address valid. */
+#define TM_REG_LIN1_PHY_ADDR_VALID				 0x164258
 /* [RW 6] Linear timer set_clear fifo threshold. */
 #define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR			 0x164070
 /* [RW 2] Load value for pci arbiter credit cnt. */
@@ -3708,6 +3852,17 @@
 #define TM_REG_TM_INT_STS					 0x1640f0
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define TSDM_REG_AGG_INT_EVENT_0				 0x42038
+#define TSDM_REG_AGG_INT_EVENT_1				 0x4203c
+#define TSDM_REG_AGG_INT_EVENT_10				 0x42060
+#define TSDM_REG_AGG_INT_EVENT_11				 0x42064
+#define TSDM_REG_AGG_INT_EVENT_12				 0x42068
+#define TSDM_REG_AGG_INT_EVENT_13				 0x4206c
+#define TSDM_REG_AGG_INT_EVENT_14				 0x42070
+#define TSDM_REG_AGG_INT_EVENT_15				 0x42074
+#define TSDM_REG_AGG_INT_EVENT_16				 0x42078
+#define TSDM_REG_AGG_INT_EVENT_17				 0x4207c
+#define TSDM_REG_AGG_INT_EVENT_18				 0x42080
+#define TSDM_REG_AGG_INT_EVENT_19				 0x42084
 #define TSDM_REG_AGG_INT_EVENT_2				 0x42040
 #define TSDM_REG_AGG_INT_EVENT_20				 0x42088
 #define TSDM_REG_AGG_INT_EVENT_21				 0x4208c
@@ -3723,6 +3878,19 @@
 #define TSDM_REG_AGG_INT_EVENT_30				 0x420b0
 #define TSDM_REG_AGG_INT_EVENT_31				 0x420b4
 #define TSDM_REG_AGG_INT_EVENT_4				 0x42048
+/* [RW 1] The T bit for aggregated interrupt 0 */
+#define TSDM_REG_AGG_INT_T_0					 0x420b8
+#define TSDM_REG_AGG_INT_T_1					 0x420bc
+#define TSDM_REG_AGG_INT_T_10					 0x420e0
+#define TSDM_REG_AGG_INT_T_11					 0x420e4
+#define TSDM_REG_AGG_INT_T_12					 0x420e8
+#define TSDM_REG_AGG_INT_T_13					 0x420ec
+#define TSDM_REG_AGG_INT_T_14					 0x420f0
+#define TSDM_REG_AGG_INT_T_15					 0x420f4
+#define TSDM_REG_AGG_INT_T_16					 0x420f8
+#define TSDM_REG_AGG_INT_T_17					 0x420fc
+#define TSDM_REG_AGG_INT_T_18					 0x42100
+#define TSDM_REG_AGG_INT_T_19					 0x42104
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define TSDM_REG_CFC_RSP_START_ADDR				 0x42008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -3967,6 +4135,10 @@
 /* [RC 1] Set when the message length mismatch (relative to last indication)
    at the dorq interface is detected. */
 #define UCM_REG_DORQ_LENGTH_MIS 				 0xe0168
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_DORQ_WEIGHT					 0xe00c0
 /* [RW 8] The Event ID in case ErrorFlg input message bit is set. */
 #define UCM_REG_ERR_EVNT_ID					 0xe00a4
 /* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4030,6 +4202,10 @@
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
 #define UCM_REG_STORM_UCM_IFEN					 0xe0010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_STORM_WEIGHT					 0xe00b0
 /* [RW 4] Timers output initial credit. Max credit available - 15.Write
    writes the initial credit value; read returns the current value of the
    credit counter. Must be initialized to 4 at start-up. */
@@ -4040,6 +4216,10 @@
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
 #define UCM_REG_TM_UCM_IFEN					 0xe001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_TM_WEIGHT					 0xe00d4
 /* [RW 1] Input tsem Interface enable. If 0 - the valid input is
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
@@ -4092,6 +4272,10 @@
    stands for weight 8 (the most prioritised); 1 stands for weight 1(least
    prioritised); 2 stands for weight 2; tc. */
 #define UCM_REG_UQM_P_WEIGHT					 0xe00cc
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_UQM_S_WEIGHT					 0xe00d0
 /* [RW 28] The CM header value for QM request (primary). */
 #define UCM_REG_UQM_UCM_HDR_P					 0xe0094
 /* [RW 28] The CM header value for QM request (secondary). */
@@ -4107,6 +4291,10 @@
 /* [RC 1] Set when the message length mismatch (relative to last indication)
    at the SDM interface is detected. */
 #define UCM_REG_USDM_LENGTH_MIS 				 0xe0158
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_USDM_WEIGHT					 0xe00c8
 /* [RW 1] Input xsem Interface enable. If 0 - the valid input is
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
@@ -4114,6 +4302,10 @@
 /* [RC 1] Set when the message length mismatch (relative to last indication)
    at the xsem interface isdetected. */
 #define UCM_REG_XSEM_LENGTH_MIS 				 0xe0164
+/* [RW 3] The weight of the input xsem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_XSEM_WEIGHT					 0xe00bc
 /* [RW 20] Indirect access to the descriptor table of the XX protection
    mechanism. The fields are:[5:0] - message length; 14:6] - message
    pointer; 19:15] - next pointer. */
@@ -4163,6 +4355,7 @@
 #define USDM_REG_AGG_INT_EVENT_30				 0xc40b0
 #define USDM_REG_AGG_INT_EVENT_31				 0xc40b4
 #define USDM_REG_AGG_INT_EVENT_4				 0xc4048
+#define USDM_REG_AGG_INT_EVENT_5				 0xc404c
 /* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
    or auto-mask-mode (1) */
 #define USDM_REG_AGG_INT_MODE_0 				 0xc41b8
@@ -4177,6 +4370,8 @@
 #define USDM_REG_AGG_INT_MODE_17				 0xc41fc
 #define USDM_REG_AGG_INT_MODE_18				 0xc4200
 #define USDM_REG_AGG_INT_MODE_19				 0xc4204
+#define USDM_REG_AGG_INT_MODE_4 				 0xc41c8
+#define USDM_REG_AGG_INT_MODE_5 				 0xc41cc
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define USDM_REG_CFC_RSP_START_ADDR				 0xc4008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -4427,6 +4622,10 @@
 /* [RC 1] Set at message length mismatch (relative to last indication) at
    the dorq interface. */
 #define XCM_REG_DORQ_LENGTH_MIS 				 0x20230
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_DORQ_WEIGHT					 0x200cc
 /* [RW 8] The Event ID in case the ErrorFlg input message bit is set. */
 #define XCM_REG_ERR_EVNT_ID					 0x200b0
 /* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4465,6 +4664,10 @@
 /* [RC 1] Set at message length mismatch (relative to last indication) at
    the nig0 interface. */
 #define XCM_REG_NIG0_LENGTH_MIS 				 0x20238
+/* [RW 3] The weight of the input nig0 in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_NIG0_WEIGHT					 0x200d4
 /* [RW 1] Input nig1 Interface enable. If 0 - the valid input is
    disregarded; acknowledge output is deasserted; all other signals are
    treated as usual; if 1 - normal activity. */
@@ -4523,6 +4726,10 @@
    writes the initial credit value; read returns the current value of the
    credit counter. Must be initialized to 4 at start-up. */
 #define XCM_REG_TM_INIT_CRD					 0x2041c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_TM_WEIGHT					 0x200ec
 /* [RW 28] The CM header for Timers expiration command. */
 #define XCM_REG_TM_XCM_HDR					 0x200a8
 /* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
@@ -4608,6 +4815,10 @@
    stands for weight 8 (the most prioritised); 1 stands for weight 1(least
    prioritised); 2 stands for weight 2; tc. */
 #define XCM_REG_XQM_P_WEIGHT					 0x200e4
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_XQM_S_WEIGHT					 0x200e8
 /* [RW 28] The CM header value for QM request (primary). */
 #define XCM_REG_XQM_XCM_HDR_P					 0x200a0
 /* [RW 28] The CM header value for QM request (secondary). */
@@ -4665,6 +4876,8 @@
 #define XSDM_REG_AGG_INT_EVENT_10				 0x166060
 #define XSDM_REG_AGG_INT_EVENT_11				 0x166064
 #define XSDM_REG_AGG_INT_EVENT_12				 0x166068
+#define XSDM_REG_AGG_INT_EVENT_13				 0x16606c
+#define XSDM_REG_AGG_INT_EVENT_14				 0x166070
 #define XSDM_REG_AGG_INT_EVENT_2				 0x166040
 #define XSDM_REG_AGG_INT_EVENT_20				 0x166088
 #define XSDM_REG_AGG_INT_EVENT_21				 0x16608c
@@ -4964,9 +5177,11 @@
 #define EMAC_RX_MODE_FLOW_EN					 (1L<<2)
 #define EMAC_RX_MODE_KEEP_VLAN_TAG				 (1L<<10)
 #define EMAC_RX_MODE_PROMISCUOUS				 (1L<<8)
+#define EMAC_RX_MODE_RESET					 (1L<<0)
 #define EMAC_RX_MTU_SIZE_JUMBO_ENA				 (1L<<31)
 #define EMAC_TX_MODE_EXT_PAUSE_EN				 (1L<<3)
 #define EMAC_TX_MODE_FLOW_EN					 (1L<<4)
+#define EMAC_TX_MODE_RESET					 (1L<<0)
 #define MISC_REGISTERS_GPIO_0					 0
 #define MISC_REGISTERS_GPIO_1					 1
 #define MISC_REGISTERS_GPIO_2					 2
@@ -4976,6 +5191,10 @@
 #define MISC_REGISTERS_GPIO_FLOAT_POS				 24
 #define MISC_REGISTERS_GPIO_HIGH				 1
 #define MISC_REGISTERS_GPIO_INPUT_HI_Z				 2
+#define MISC_REGISTERS_GPIO_INT_CLR_POS 			 24
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_CLR			 0
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_SET			 1
+#define MISC_REGISTERS_GPIO_INT_SET_POS 			 16
 #define MISC_REGISTERS_GPIO_LOW 				 0
 #define MISC_REGISTERS_GPIO_OUTPUT_HIGH 			 1
 #define MISC_REGISTERS_GPIO_OUTPUT_LOW				 0
@@ -5015,11 +5234,12 @@
 #define MISC_REGISTERS_SPIO_OUTPUT_LOW				 0
 #define MISC_REGISTERS_SPIO_SET_POS				 8
 #define HW_LOCK_MAX_RESOURCE_VALUE				 31
-#define HW_LOCK_RESOURCE_8072_MDIO				 0
 #define HW_LOCK_RESOURCE_GPIO					 1
+#define HW_LOCK_RESOURCE_MDIO					 0
 #define HW_LOCK_RESOURCE_PORT0_ATT_MASK 			 3
 #define HW_LOCK_RESOURCE_SPIO					 2
 #define HW_LOCK_RESOURCE_UNDI					 5
+#define PRS_FLAG_OVERETH_IPV4					 1
 #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR		      (1<<18)
 #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT		      (1<<31)
 #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT		      (1<<9)
@@ -5034,6 +5254,8 @@
 #define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT		      (1<<11)
 #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT	      (1<<13)
 #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR	      (1<<12)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0		      (1<<5)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1		      (1<<9)
 #define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR		      (1<<12)
 #define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT		      (1<<15)
 #define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR		      (1<<14)
@@ -5188,7 +5410,7 @@
 #define PCICFG_COMMAND_INT_DISABLE		(1<<10)
 #define PCICFG_COMMAND_RESERVED 		(0x1f<<11)
 #define PCICFG_STATUS_OFFSET				0x06
-#define PCICFG_REVESION_ID				0x08
+#define PCICFG_REVESION_ID_OFFSET			0x08
 #define PCICFG_CACHE_LINE_SIZE				0x0c
 #define PCICFG_LATENCY_TIMER				0x0d
 #define PCICFG_BAR_1_LOW				0x10
@@ -5216,9 +5438,28 @@
 #define PCICFG_PM_CSR_STATE			(0x3<<0)
 #define PCICFG_PM_CSR_PME_ENABLE		(1<<8)
 #define PCICFG_PM_CSR_PME_STATUS		(1<<15)
+#define PCICFG_MSI_CAP_ID_OFFSET			0x58
+#define PCICFG_MSI_CONTROL_ENABLE		(0x1<<16)
+#define PCICFG_MSI_CONTROL_MCAP 		(0x7<<17)
+#define PCICFG_MSI_CONTROL_MENA 		(0x7<<20)
+#define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP	(0x1<<23)
+#define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE	(0x1<<24)
 #define PCICFG_GRC_ADDRESS				0x78
 #define PCICFG_GRC_DATA 				0x80
+#define PCICFG_MSIX_CAP_ID_OFFSET			0xa0
+#define PCICFG_MSIX_CONTROL_TABLE_SIZE		(0x7ff<<16)
+#define PCICFG_MSIX_CONTROL_RESERVED		(0x7<<27)
+#define PCICFG_MSIX_CONTROL_FUNC_MASK		(0x1<<30)
+#define PCICFG_MSIX_CONTROL_MSIX_ENABLE 	(0x1<<31)
+
 #define PCICFG_DEVICE_CONTROL				0xb4
+#define PCICFG_DEVICE_STATUS				0xb6
+#define PCICFG_DEVICE_STATUS_CORR_ERR_DET	(1<<0)
+#define PCICFG_DEVICE_STATUS_NON_FATAL_ERR_DET	(1<<1)
+#define PCICFG_DEVICE_STATUS_FATAL_ERR_DET	(1<<2)
+#define PCICFG_DEVICE_STATUS_UNSUP_REQ_DET	(1<<3)
+#define PCICFG_DEVICE_STATUS_AUX_PWR_DET	(1<<4)
+#define PCICFG_DEVICE_STATUS_NO_PEND		(1<<5)
 #define PCICFG_LINK_CONTROL				0xbc
 
 
@@ -5363,6 +5604,42 @@
 #define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
 #define MDIO_TX0_TX_DRIVER_ICBUF1T			1
 
+#define MDIO_REG_BANK_TX1				0x8070
+#define MDIO_TX1_TX_DRIVER				0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 		0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T			1
+
+#define MDIO_REG_BANK_TX2				0x8080
+#define MDIO_TX2_TX_DRIVER				0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 		0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T			1
+
+#define MDIO_REG_BANK_TX3				0x8090
+#define MDIO_TX3_TX_DRIVER				0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK		0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT		12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 		0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT		8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK		0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT		4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK		0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT		1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T			1
+
 #define MDIO_REG_BANK_XGXS_BLOCK0			0x8000
 #define MDIO_BLOCK0_XGXS_CONTROL			0x10
 
@@ -5566,9 +5843,30 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_ROM_VER2		0xca1a
 #define MDIO_PMA_REG_EDC_FFE_MAIN	0xca1b
 #define MDIO_PMA_REG_PLL_BANDWIDTH	0xca1d
+#define MDIO_PMA_REG_GEN_CTRL2		0xca1e
+#define MDIO_PMA_REG_MISC_CTRL0 	0xca23
+#define MDIO_PMA_REG_LRM_MODE		0xca3f
 #define MDIO_PMA_REG_CDR_BANDWIDTH	0xca46
 #define MDIO_PMA_REG_MISC_CTRL1 	0xca85
 
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 	0x8000
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK	0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE		0x0000
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE	0x0004
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS	0x0008
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED	0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT	0x8002
+#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR	0x8003
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF	0xc820
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
+#define MDIO_PMA_REG_8726_TX_CTRL1		0xca01
+#define MDIO_PMA_REG_8726_TX_CTRL2		0xca05
+
+
+#define MDIO_PMA_REG_8073_CHIP_REV			0xc801
+#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
+#define MDIO_PMA_REG_8073_XAUI_WA			0xc841
+
 #define MDIO_PMA_REG_7101_RESET 	0xc000
 #define MDIO_PMA_REG_7107_LED_CNTL	0xc007
 #define MDIO_PMA_REG_7101_VER1		0xc026
@@ -5598,6 +5896,12 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_XS_PLL_SEQUENCER		0x8000
 #define MDIO_XS_SFX7101_XGXS_TEST1	0xc00a
 
+#define MDIO_XS_8706_REG_BANK_RX0	0x80bc
+#define MDIO_XS_8706_REG_BANK_RX1	0x80cc
+#define MDIO_XS_8706_REG_BANK_RX2	0x80dc
+#define MDIO_XS_8706_REG_BANK_RX3	0x80ec
+#define MDIO_XS_8706_REG_BANK_RXA	0x80fc
+
 #define MDIO_AN_DEVAD			0x7
 /*ieee*/
 #define MDIO_AN_REG_CTRL		0x0000
@@ -5619,6 +5923,8 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_AN_REG_CL37_FC_LD		0xffe4
 #define MDIO_AN_REG_CL37_FC_LP		0xffe5
 
+#define MDIO_AN_REG_8073_2_5G		0x8329
+
 
 #define IGU_FUNC_BASE			0x0400
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_3ad.c linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_3ad.c
--- linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_3ad.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_3ad.c	2009-06-09 23:05:27.000000000 -0400
@@ -1465,6 +1465,12 @@ static struct aggregator *ad_agg_selecti
 	return best;
 }
 
+static int agg_device_up(const struct aggregator *agg)
+{
+	return (netif_running(agg->slave->dev) &&
+		netif_carrier_ok(agg->slave->dev));
+}
+
 /**
  * ad_agg_selection_logic - select an aggregation group for a team
  * @aggregator: the aggregator we're looking at
@@ -1496,14 +1502,13 @@ static void ad_agg_selection_logic(struc
 	struct port *port;
 
 	origin = agg;
-
 	active = __get_active_agg(agg);
-	best = active;
+	best = (active && agg_device_up(active)) ? active : NULL;
 
 	do {
 		agg->is_active = 0;
 
-		if (agg->num_of_ports)
+		if (agg->num_of_ports && agg_device_up(agg))
 			best = ad_agg_selection_test(best, agg);
 
 	} while ((agg = __get_next_agg(agg)));
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_3ad.h linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_3ad.h
--- linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_3ad.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_3ad.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 
 // General definitions
 #define BOND_ETH_P_LACPDU       0x8809
-#define PKT_TYPE_LACPDU         __constant_htons(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU         cpu_to_be16(BOND_ETH_P_LACPDU)
 #define AD_TIMER_INTERVAL       100 /*msec*/
 
 #define MULTICAST_LACPDU_ADDR    {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_alb.c linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_alb.c
--- linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_alb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_alb.c	2009-06-09 23:05:27.000000000 -0400
@@ -370,8 +370,6 @@ static int rlb_arp_recv(struct sk_buff *
 
 	if (arp->op_code == htons(ARPOP_REPLY)) {
 		/* update rx hash table for this ARP */
-		printk("rar: update orig %s bond_dev %s\n", orig_dev->name,
-		       bond_dev->name);
 		bond = netdev_priv(bond_dev);
 		rlb_update_entry_from_arp(bond, arp);
 		pr_debug("Server received an ARP Reply from client\n");
@@ -822,7 +820,7 @@ static int rlb_initialize(struct bonding
 	_unlock_rx_hashtbl(bond);
 
 	/*initialize packet type*/
-	pk_type->type = __constant_htons(ETH_P_ARP);
+	pk_type->type = cpu_to_be16(ETH_P_ARP);
 	pk_type->dev = NULL;
 	pk_type->func = rlb_arp_recv;
 
@@ -892,7 +890,7 @@ static void alb_send_learning_packets(st
 	memset(&pkt, 0, size);
 	memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
 	memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
-	pkt.type = __constant_htons(ETH_P_LOOP);
+	pkt.type = cpu_to_be16(ETH_P_LOOP);
 
 	for (i = 0; i < MAX_LP_BURST; i++) {
 		struct sk_buff *skb;
@@ -1628,6 +1626,10 @@ void bond_alb_handle_link_change(struct
  * no other locks may be held.
  */
 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
+	__releases(&bond->curr_slave_lock)
+	__releases(&bond->lock)
+	__acquires(&bond->lock)
+	__acquires(&bond->curr_slave_lock)
 {
 	struct slave *swap_slave;
 	int i;
@@ -1704,6 +1706,8 @@ void bond_alb_handle_active_change(struc
  * Called with RTNL
  */
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+	__acquires(&bond->lock)
+	__releases(&bond->lock)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct sockaddr *sa = addr;
@@ -1739,9 +1743,6 @@ int bond_alb_set_mac_address(struct net_
 		}
 	}
 
-	write_unlock_bh(&bond->curr_slave_lock);
-	read_unlock(&bond->lock);
-
 	if (swap_slave) {
 		alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
 		alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
@@ -1749,16 +1750,15 @@ int bond_alb_set_mac_address(struct net_
 		alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
 				       bond->alb_info.rlb_enabled);
 
+		read_lock(&bond->lock);
 		alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
 		if (bond->alb_info.rlb_enabled) {
 			/* inform clients mac address has changed */
 			rlb_req_update_slave_clients(bond, bond->curr_active_slave);
 		}
+		read_unlock(&bond->lock);
 	}
 
-	read_lock(&bond->lock);
-	write_lock_bh(&bond->curr_slave_lock);
-
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_main.c linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1002,6 +1002,10 @@ static void bond_mc_swap(struct bonding
 static void bond_do_fail_over_mac(struct bonding *bond,
 				  struct slave *new_active,
 				  struct slave *old_active)
+	__releases(&bond->curr_slave_lock)
+	__releases(&bond->lock)
+	__acquires(&bond->lock)
+	__acquires(&bond->curr_slave_lock)
 {
 	u8 tmp_mac[ETH_ALEN];
 	struct sockaddr saddr;
@@ -1710,6 +1714,7 @@ int bond_enslave(struct net_device *bond
 	case BOND_MODE_ALB:
 		new_slave->state = BOND_STATE_ACTIVE;
 		bond_set_slave_inactive_flags(new_slave);
+		bond_select_active_slave(bond);
 		break;
 	default:
 		pr_debug("This slave is always active in trunk mode\n");
@@ -2208,33 +2213,24 @@ static int bond_slave_info_query(struct
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave;
-	int i, found = 0;
-
-	if (info->slave_id < 0) {
-		return -ENODEV;
-	}
+	int i, res = -ENODEV;
 
 	read_lock(&bond->lock);
 
 	bond_for_each_slave(bond, slave, i) {
 		if (i == (int)info->slave_id) {
-			found = 1;
+			res = 0;
+			strcpy(info->slave_name, slave->dev->name);
+			info->link = slave->link;
+			info->state = slave->state;
+			info->link_failure_count = slave->link_failure_count;
 			break;
 		}
 	}
 
 	read_unlock(&bond->lock);
 
-	if (found) {
-		strcpy(info->slave_name, slave->dev->name);
-		info->link = slave->link;
-		info->state = slave->state;
-		info->link_failure_count = slave->link_failure_count;
-	} else {
-		return -ENODEV;
-	}
-
-	return 0;
+	return res;
 }
 
 /*-------------------------------- Monitoring -------------------------------*/
@@ -2565,7 +2561,7 @@ static void bond_arp_send_all(struct bon
 
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
 		if (!targets[i])
-			continue;
+			break;
 		pr_debug("basa: target %x\n", targets[i]);
 		if (list_empty(&bond->vlan_list)) {
 			pr_debug("basa: empty vlan: arp_send\n");
@@ -2672,7 +2668,6 @@ static void bond_validate_arp(struct bon
 	int i;
 	__be32 *targets = bond->params.arp_targets;
 
-	targets = bond->params.arp_targets;
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
 		pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n",
 			&sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip));
@@ -3193,6 +3188,8 @@ out:
 #ifdef CONFIG_PROC_FS
 
 static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+	__acquires(&dev_base_lock)
+	__acquires(&bond->lock)
 {
 	struct bonding *bond = seq->private;
 	loff_t off = 0;
@@ -3232,6 +3229,8 @@ static void *bond_info_seq_next(struct s
 }
 
 static void bond_info_seq_stop(struct seq_file *seq, void *v)
+	__releases(&bond->lock)
+	__releases(&dev_base_lock)
 {
 	struct bonding *bond = seq->private;
 
@@ -3294,7 +3293,7 @@ static void bond_info_show_master(struct
 
 		for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
 			if (!bond->params.arp_targets[i])
-				continue;
+				break;
 			if (printed)
 				seq_printf(seq, ",");
 			seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
@@ -3369,7 +3368,7 @@ static int bond_info_seq_show(struct seq
 	return 0;
 }
 
-static struct seq_operations bond_info_seq_ops = {
+static const struct seq_operations bond_info_seq_ops = {
 	.start = bond_info_seq_start,
 	.next  = bond_info_seq_next,
 	.stop  = bond_info_seq_stop,
@@ -3435,25 +3434,12 @@ static void bond_remove_proc_entry(struc
  */
 static void bond_create_proc_dir(void)
 {
-	int len = strlen(DRV_NAME);
-
-	for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
-	     bond_proc_dir = bond_proc_dir->next) {
-		if ((bond_proc_dir->namelen == len) &&
-		    !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
-			break;
-		}
-	}
-
 	if (!bond_proc_dir) {
 		bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
-		if (bond_proc_dir) {
-			bond_proc_dir->owner = THIS_MODULE;
-		} else {
+		if (!bond_proc_dir)
 			printk(KERN_WARNING DRV_NAME
 				": Warning: cannot create /proc/net/%s\n",
 				DRV_NAME);
-		}
 	}
 }
 
@@ -3462,25 +3448,7 @@ static void bond_create_proc_dir(void)
  */
 static void bond_destroy_proc_dir(void)
 {
-	struct proc_dir_entry *de;
-
-	if (!bond_proc_dir) {
-		return;
-	}
-
-	/* verify that the /proc dir is empty */
-	for (de = bond_proc_dir->subdir; de; de = de->next) {
-		/* ignore . and .. */
-		if (*(de->name) != '.') {
-			break;
-		}
-	}
-
-	if (de) {
-		if (bond_proc_dir->owner == THIS_MODULE) {
-			bond_proc_dir->owner = NULL;
-		}
-	} else {
+	if (bond_proc_dir) {
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
 		bond_proc_dir = NULL;
 	}
@@ -4739,7 +4707,7 @@ static void bond_free_all(void)
  */
 int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
 {
-	int mode = -1, i, rv;
+	int modeint = -1, i, rv;
 	char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
 
 	for (p = (char *)buf; *p; p++)
@@ -4749,13 +4717,13 @@ int bond_parse_parm(const char *buf, con
 	if (*p)
 		rv = sscanf(buf, "%20s", modestr);
 	else
-		rv = sscanf(buf, "%d", &mode);
+		rv = sscanf(buf, "%d", &modeint);
 
 	if (!rv)
 		return -1;
 
 	for (i = 0; tbl[i].modename; i++) {
-		if (mode == tbl[i].mode)
+		if (modeint == tbl[i].mode)
 			return tbl[i].mode;
 		if (strcmp(modestr, tbl[i].modename) == 0)
 			return tbl[i].mode;
@@ -5190,16 +5158,15 @@ int bond_create(char *name, struct bond_
 	up_write(&bonding_rwsem);
 	rtnl_unlock(); /* allows sysfs registration of net device */
 	res = bond_create_sysfs_entry(netdev_priv(bond_dev));
-	if (res < 0) {
-		rtnl_lock();
-		down_write(&bonding_rwsem);
-		bond_deinit(bond_dev);
-		unregister_netdevice(bond_dev);
-		goto out_rtnl;
-	}
+	if (res < 0)
+		goto out_unreg;
 
 	return 0;
 
+out_unreg:
+	rtnl_lock();
+	down_write(&bonding_rwsem);
+	unregister_netdevice(bond_dev);
 out_bond:
 	bond_deinit(bond_dev);
 out_netdev:
@@ -5214,7 +5181,6 @@ static int __init bonding_init(void)
 {
 	int i;
 	int res;
-	struct bonding *bond;
 
 	printk(KERN_INFO "%s", version);
 
@@ -5245,13 +5211,6 @@ static int __init bonding_init(void)
 
 	goto out;
 err:
-	list_for_each_entry(bond, &bond_dev_list, bond_list) {
-		bond_work_cancel_all(bond);
-		destroy_workqueue(bond->wq);
-	}
-
-	bond_destroy_sysfs();
-
 	rtnl_lock();
 	bond_free_all();
 	rtnl_unlock();
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_sysfs.c linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/bonding/bond_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -684,17 +684,15 @@ static ssize_t bonding_store_arp_targets
 			goto out;
 		}
 		/* look for an empty slot to put the target in, and check for dupes */
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
 			if (targets[i] == newtarget) { /* duplicate */
 				printk(KERN_ERR DRV_NAME
 				       ": %s: ARP target %pI4 is already present\n",
 				       bond->dev->name, &newtarget);
-				if (done)
-					targets[i] = 0;
 				ret = -EINVAL;
 				goto out;
 			}
-			if (targets[i] == 0 && !done) {
+			if (targets[i] == 0) {
 				printk(KERN_INFO DRV_NAME
 				       ": %s: adding ARP target %pI4.\n",
 				       bond->dev->name, &newtarget);
@@ -720,12 +718,16 @@ static ssize_t bonding_store_arp_targets
 			goto out;
 		}
 
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
 			if (targets[i] == newtarget) {
+				int j;
 				printk(KERN_INFO DRV_NAME
 				       ": %s: removing ARP target %pI4.\n",
 				       bond->dev->name, &newtarget);
-				targets[i] = 0;
+				for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
+					targets[j] = targets[j+1];
+
+				targets[j] = 0;
 				done = 1;
 			}
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cassini.c linux-libre-2.6.30-gnu1/drivers/net/cassini.c
--- linux-libre-2.6.29-gnu1/drivers/net/cassini.c	2013-05-03 18:02:48.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cassini.c	2013-05-03 16:46:41.000000000 -0400
@@ -2506,7 +2506,7 @@ static irqreturn_t cas_interruptN(int ir
 	if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
 #ifdef USE_NAPI
 		cas_mask_intr(cp);
-		netif_rx_schedule(&cp->napi);
+		napi_schedule(&cp->napi);
 #else
 		cas_rx_ringN(cp, ring, 0);
 #endif
@@ -2557,7 +2557,7 @@ static irqreturn_t cas_interrupt1(int ir
 	if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
 #ifdef USE_NAPI
 		cas_mask_intr(cp);
-		netif_rx_schedule(&cp->napi);
+		napi_schedule(&cp->napi);
 #else
 		cas_rx_ringN(cp, 1, 0);
 #endif
@@ -2613,7 +2613,7 @@ static irqreturn_t cas_interrupt(int irq
 	if (status & INTR_RX_DONE) {
 #ifdef USE_NAPI
 		cas_mask_intr(cp);
-		netif_rx_schedule(&cp->napi);
+		napi_schedule(&cp->napi);
 #else
 		cas_rx_ringN(cp, 0, 0);
 #endif
@@ -2691,7 +2691,7 @@ rx_comp:
 #endif
 	spin_unlock_irqrestore(&cp->lock, flags);
 	if (enable_intr) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		cas_unmask_intr(cp);
 	}
 	return credits;
@@ -5074,10 +5074,10 @@ static int __devinit cas_init_one(struct
 
 
 	/* Configure DMA attributes. */
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 		err = pci_set_consistent_dma_mask(pdev,
-						  DMA_64BIT_MASK);
+						  DMA_BIT_MASK(64));
 		if (err < 0) {
 			dev_err(&pdev->dev, "Unable to obtain 64-bit DMA "
 			       "for consistent allocations\n");
@@ -5085,7 +5085,7 @@ static int __devinit cas_init_one(struct
 		}
 
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "No usable DMA configuration, "
 			       "aborting.\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/chelsio/cxgb2.c linux-libre-2.6.30-gnu1/drivers/net/chelsio/cxgb2.c
--- linux-libre-2.6.29-gnu1/drivers/net/chelsio/cxgb2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/chelsio/cxgb2.c	2009-06-09 23:05:27.000000000 -0400
@@ -1056,17 +1056,17 @@ static int __devinit init_one(struct pci
 		goto out_disable_pdev;
 	}
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 
-		if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
 			CH_ERR("%s: unable to obtain 64-bit DMA for "
 			       "consistent allocations\n", pci_name(pdev));
 			err = -ENODEV;
 			goto out_disable_pdev;
 		}
 
-	} else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+	} else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
 		CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
 		goto out_disable_pdev;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/chelsio/sge.c linux-libre-2.6.30-gnu1/drivers/net/chelsio/sge.c
--- linux-libre-2.6.29-gnu1/drivers/net/chelsio/sge.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/chelsio/sge.c	2009-06-09 23:05:27.000000000 -0400
@@ -1612,7 +1612,7 @@ int t1_poll(struct napi_struct *napi, in
 	int work_done = process_responses(adapter, budget);
 
 	if (likely(work_done < budget)) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		writel(adapter->sge->respQ.cidx,
 		       adapter->regs + A_SG_SLEEPING);
 	}
@@ -1630,7 +1630,7 @@ irqreturn_t t1_interrupt(int irq, void *
 
 		if (napi_schedule_prep(&adapter->napi)) {
 			if (process_pure_responses(adapter))
-				__netif_rx_schedule(&adapter->napi);
+				__napi_schedule(&adapter->napi);
 			else {
 				/* no data, no NAPI needed */
 				writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
@@ -1967,8 +1967,7 @@ void t1_sge_stop(struct sge *sge)
 		tx_sched_stop(sge);
 
 	for (i = 0; i < MAX_NPORTS; i++)
-		if (sge->espibug_skb[i])
-			kfree_skb(sge->espibug_skb[i]);
+		kfree_skb(sge->espibug_skb[i]);
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cpmac.c linux-libre-2.6.30-gnu1/drivers/net/cpmac.c
--- linux-libre-2.6.29-gnu1/drivers/net/cpmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cpmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -428,7 +428,7 @@ static int cpmac_poll(struct napi_struct
 			printk(KERN_WARNING "%s: rx: polling, but no queue\n",
 			       priv->dev->name);
 		spin_unlock(&priv->rx_lock);
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		return 0;
 	}
 
@@ -514,7 +514,7 @@ static int cpmac_poll(struct napi_struct
 	if (processed == 0) {
 		/* we ran out of packets to read,
 		 * revert to interrupt-driven mode */
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
 		return 0;
 	}
@@ -536,7 +536,7 @@ fatal_error:
 	}
 
 	spin_unlock(&priv->rx_lock);
-	netif_rx_complete(napi);
+	napi_complete(napi);
 	netif_tx_stop_all_queues(priv->dev);
 	napi_disable(&priv->napi);
 
@@ -802,9 +802,9 @@ static irqreturn_t cpmac_irq(int irq, vo
 
 	if (status & MAC_INT_RX) {
 		queue = (status >> 8) & 7;
-		if (netif_rx_schedule_prep(&priv->napi)) {
+		if (napi_schedule_prep(&priv->napi)) {
 			cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
-			__netif_rx_schedule(&priv->napi);
+			__napi_schedule(&priv->napi);
 		}
 	}
 
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct
 	priv->msg_enable = netif_msg_init(debug_level, 0xff);
 	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
 
-	priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
+	priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
 				&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
 	if (IS_ERR(priv->phy)) {
 		if (netif_msg_drv(priv))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cris/eth_v10.c linux-libre-2.6.30-gnu1/drivers/net/cris/eth_v10.c
--- linux-libre-2.6.29-gnu1/drivers/net/cris/eth_v10.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cris/eth_v10.c	2009-06-09 23:05:27.000000000 -0400
@@ -257,6 +257,23 @@ struct transceiver_ops transceivers[] =
 
 struct transceiver_ops* transceiver = &transceivers[0];
 
+static const struct net_device_ops e100_netdev_ops = {
+	.ndo_open		= e100_open,
+	.ndo_stop		= e100_close,
+	.ndo_start_xmit		= e100_send_packet,
+	.ndo_tx_timeout		= e100_tx_timeout,
+	.ndo_get_stats		= e100_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_do_ioctl		= e100_ioctl,
+	.ndo_set_mac_address	= e100_set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_config		= e100_set_config,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= e100_netpoll,
+#endif
+};
+
 #define tx_done(dev) (*R_DMA_CH0_CMD == 0)
 
 /*
@@ -300,19 +317,8 @@ etrax_ethernet_init(void)
 
 	/* fill in our handlers so the network layer can talk to us in the future */
 
-	dev->open               = e100_open;
-	dev->hard_start_xmit    = e100_send_packet;
-	dev->stop               = e100_close;
-	dev->get_stats          = e100_get_stats;
-	dev->set_multicast_list = set_multicast_list;
-	dev->set_mac_address    = e100_set_mac_address;
 	dev->ethtool_ops	= &e100_ethtool_ops;
-	dev->do_ioctl           = e100_ioctl;
-	dev->set_config		= e100_set_config;
-	dev->tx_timeout         = e100_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = e100_netpoll;
-#endif
+	dev->netdev_ops		= &e100_netdev_ops;
 
 	spin_lock_init(&np->lock);
 	spin_lock_init(&np->led_lock);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cs89x0.c linux-libre-2.6.30-gnu1/drivers/net/cs89x0.c
--- linux-libre-2.6.29-gnu1/drivers/net/cs89x0.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cs89x0.c	2009-06-09 23:05:27.000000000 -0400
@@ -501,6 +501,21 @@ static void net_poll_controller(struct n
 }
 #endif
 
+static const struct net_device_ops net_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_tx_timeout		= net_timeout,
+	.ndo_start_xmit 	= net_send_packet,
+	.ndo_get_stats		= net_get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_set_mac_address 	= set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= net_poll_controller,
+#endif
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* 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.
@@ -843,17 +858,8 @@ cs89x0_probe1(struct net_device *dev, in
 	/* print the ethernet address. */
 	printk(", MAC %pM", dev->dev_addr);
 
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->tx_timeout		= net_timeout;
-	dev->watchdog_timeo	= HZ;
-	dev->hard_start_xmit 	= net_send_packet;
-	dev->get_stats		= net_get_stats;
-	dev->set_multicast_list = set_multicast_list;
-	dev->set_mac_address 	= set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller	= net_poll_controller;
-#endif
+	dev->netdev_ops	= &net_ops;
+	dev->watchdog_timeo = HZ;
 
 	printk("\n");
 	if (net_debug)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/adapter.h linux-libre-2.6.30-gnu1/drivers/net/cxgb3/adapter.h
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/adapter.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/adapter.h	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,6 @@
 #include <linux/cache.h>
 #include <linux/mutex.h>
 #include <linux/bitops.h>
-#include <linux/inet_lro.h>
 #include "t3cdev.h"
 #include <asm/io.h>
 
@@ -69,6 +68,8 @@ struct port_info {
 	struct net_device_stats netstats;
 	int activity;
 	__be32 iscsi_ipv4addr;
+
+	int link_fault; /* link fault was detected */
 };
 
 enum {				/* adapter flags */
@@ -84,6 +85,8 @@ struct fl_pg_chunk {
 	struct page *page;
 	void *va;
 	unsigned int offset;
+	unsigned long *p_cnt;
+	dma_addr_t mapping;
 };
 
 struct rx_desc;
@@ -92,6 +95,7 @@ struct rx_sw_desc;
 struct sge_fl {                     /* SGE per free-buffer list state */
 	unsigned int buf_size;      /* size of each Rx buffer */
 	unsigned int credits;       /* # of available Rx buffers */
+	unsigned int pend_cred;     /* new buffers since last FL DB ring */
 	unsigned int size;          /* capacity of free list */
 	unsigned int cidx;          /* consumer index */
 	unsigned int pidx;          /* producer index */
@@ -99,6 +103,7 @@ struct sge_fl {                     /* S
 	struct fl_pg_chunk pg_chunk;/* page chunk cache */
 	unsigned int use_pages;     /* whether FL uses pages or sk_buffs */
 	unsigned int order;	    /* order of page allocations */
+	unsigned int alloc_size;    /* size of allocated buffer */
 	struct rx_desc *desc;       /* address of HW Rx descriptor ring */
 	struct rx_sw_desc *sdesc;   /* address of SW Rx descriptor ring */
 	dma_addr_t   phys_addr;     /* physical address of HW ring start */
@@ -178,15 +183,11 @@ enum {				/* per port SGE statistics */
 	SGE_PSTAT_TX_CSUM,	/* # of TX checksum offloads */
 	SGE_PSTAT_VLANEX,	/* # of VLAN tag extractions */
 	SGE_PSTAT_VLANINS,	/* # of VLAN tag insertions */
-	SGE_PSTAT_LRO_AGGR,	/* # of page chunks added to LRO sessions */
-	SGE_PSTAT_LRO_FLUSHED,	/* # of flushed LRO sessions */
-	SGE_PSTAT_LRO_NO_DESC,	/* # of overflown LRO sessions */
 
 	SGE_PSTAT_MAX		/* must be last */
 };
 
-#define T3_MAX_LRO_SES 8
-#define T3_MAX_LRO_MAX_PKTS 64
+struct napi_gro_fraginfo;
 
 struct sge_qset {		/* an SGE queue set */
 	struct adapter *adap;
@@ -194,17 +195,14 @@ struct sge_qset {		/* an SGE queue set *
 	struct sge_rspq rspq;
 	struct sge_fl fl[SGE_RXQ_PER_SET];
 	struct sge_txq txq[SGE_TXQ_PER_SET];
-	struct net_lro_mgr lro_mgr;
-	struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
-	struct skb_frag_struct *lro_frag_tbl;
-	int lro_nfrags;
+	struct napi_gro_fraginfo lro_frag_tbl;
 	int lro_enabled;
-	int lro_frag_len;
 	void *lro_va;
 	struct net_device *netdev;
 	struct netdev_queue *tx_q;	/* associated netdev TX queue */
 	unsigned long txq_stopped;	/* which Tx queues are stopped */
 	struct timer_list tx_reclaim_timer;	/* reclaims TX buffers */
+	struct timer_list rx_reclaim_timer;	/* reclaims RX buffers */
 	unsigned long port_stats[SGE_PSTAT_MAX];
 } ____cacheline_aligned;
 
@@ -230,6 +228,7 @@ struct adapter {
 	unsigned int slow_intr_mask;
 	unsigned long irq_stats[IRQ_NUM_STATS];
 
+	int msix_nvectors;
 	struct {
 		unsigned short vec;
 		char desc[22];
@@ -247,6 +246,7 @@ struct adapter {
 	struct delayed_work adap_check_task;
 	struct work_struct ext_intr_handler_task;
 	struct work_struct fatal_error_handler_task;
+	struct work_struct link_fault_handler_task;
 
 	struct dentry *debugfs_root;
 
@@ -289,9 +289,12 @@ void t3_os_ext_intr_handler(struct adapt
 void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
 			int speed, int duplex, int fc);
 void t3_os_phymod_changed(struct adapter *adap, int port_id);
+void t3_os_link_fault(struct adapter *adapter, int port_id, int state);
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id);
 
 void t3_sge_start(struct adapter *adap);
 void t3_sge_stop(struct adapter *adap);
+void t3_start_sge_timers(struct adapter *adap);
 void t3_stop_sge_timers(struct adapter *adap);
 void t3_free_sge_resources(struct adapter *adap);
 void t3_sge_err_intr_handler(struct adapter *adapter);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/ael1002.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/ael1002.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/ael1002.c	2013-05-03 18:02:53.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/ael1002.c	2013-05-03 16:46:46.000000000 -0400
@@ -366,7 +366,8 @@ static int ael2005_reset(struct cphy *ph
 		{ 0, 0, 0, 0 }
 	};
 
-	int err, lasi_ctrl;
+	int err;
+	unsigned int lasi_ctrl;
 
 	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
 	if (err)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/common.h linux-libre-2.6.30-gnu1/drivers/net/cxgb3/common.h
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/common.h	2009-06-09 23:05:27.000000000 -0400
@@ -191,7 +191,8 @@ struct mdio_ops {
 };
 
 struct adapter_info {
-	unsigned char nports;	/* # of ports */
+	unsigned char nports0;        /* # of ports on channel 0 */
+	unsigned char nports1;        /* # of ports on channel 1 */
 	unsigned char phy_base_addr;	/* MDIO PHY base address */
 	unsigned int gpio_out;	/* GPIO output settings */
 	unsigned char gpio_intr[MAX_NPORTS]; /* GPIO PHY IRQ pins */
@@ -280,6 +281,7 @@ struct mac_stats {
 	unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
 	unsigned long num_resets;  /* # times reset due to stuck TX */
 
+	unsigned long link_faults;  /* # detected link faults */
 };
 
 struct tp_mib_stats {
@@ -421,6 +423,7 @@ struct adapter_params {
 	unsigned short b_wnd[NCCTRL_WIN];
 
 	unsigned int nports;	/* # of ethernet ports */
+	unsigned int chan_map;  /* bitmap of in-use Tx channels */
 	unsigned int stats_update_period;	/* MAC stats accumulation period */
 	unsigned int linkpoll_period;	/* link poll period in 0.1s */
 	unsigned int rev;	/* chip revision */
@@ -701,6 +704,8 @@ int t3_phy_lasi_intr_handler(struct cphy
 void t3_intr_enable(struct adapter *adapter);
 void t3_intr_disable(struct adapter *adapter);
 void t3_intr_clear(struct adapter *adapter);
+void t3_xgm_intr_enable(struct adapter *adapter, int idx);
+void t3_xgm_intr_disable(struct adapter *adapter, int idx);
 void t3_port_intr_enable(struct adapter *adapter, int idx);
 void t3_port_intr_disable(struct adapter *adapter, int idx);
 void t3_port_intr_clear(struct adapter *adapter, int idx);
@@ -708,6 +713,7 @@ int t3_slow_intr_handler(struct adapter
 int t3_phy_intr_handler(struct adapter *adapter);
 
 void t3_link_changed(struct adapter *adapter, int port_id);
+void t3_link_fault(struct adapter *adapter, int port_id);
 int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
 const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
 int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
@@ -744,6 +750,8 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsi
 
 int t3_mac_reset(struct cmac *mac);
 void t3b_pcs_reset(struct cmac *mac);
+void t3_mac_disable_exact_filters(struct cmac *mac);
+void t3_mac_enable_exact_filters(struct cmac *mac);
 int t3_mac_enable(struct cmac *mac, int which);
 int t3_mac_disable(struct cmac *mac, int which);
 int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_main.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 18:02:51.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_main.c	2013-05-03 16:46:44.000000000 -0400
@@ -170,6 +170,40 @@ static void link_report(struct net_devic
 	}
 }
 
+void t3_os_link_fault(struct adapter *adap, int port_id, int state)
+{
+	struct net_device *dev = adap->port[port_id];
+	struct port_info *pi = netdev_priv(dev);
+
+	if (state == netif_carrier_ok(dev))
+		return;
+
+	if (state) {
+		struct cmac *mac = &pi->mac;
+
+		netif_carrier_on(dev);
+
+		/* Clear local faults */
+		t3_xgm_intr_disable(adap, pi->port_id);
+		t3_read_reg(adap, A_XGM_INT_STATUS +
+				    pi->mac.offset);
+		t3_write_reg(adap,
+			     A_XGM_INT_CAUSE + pi->mac.offset,
+			     F_XGM_INT);
+
+		t3_set_reg_field(adap,
+				 A_XGM_INT_ENABLE +
+				 pi->mac.offset,
+				 F_XGM_INT, F_XGM_INT);
+		t3_xgm_intr_enable(adap, pi->port_id);
+
+		t3_mac_enable(mac, MAC_DIRECTION_TX);
+	} else
+		netif_carrier_off(dev);
+
+	link_report(dev);
+}
+
 /**
  *	t3_os_link_changed - handle link status changes
  *	@adapter: the adapter associated with the link change
@@ -197,10 +231,34 @@ void t3_os_link_changed(struct adapter *
 	if (link_stat != netif_carrier_ok(dev)) {
 		if (link_stat) {
 			t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+			/* Clear local faults */
+			t3_xgm_intr_disable(adapter, pi->port_id);
+			t3_read_reg(adapter, A_XGM_INT_STATUS +
+				    pi->mac.offset);
+			t3_write_reg(adapter,
+				     A_XGM_INT_CAUSE + pi->mac.offset,
+				     F_XGM_INT);
+
+			t3_set_reg_field(adapter,
+					 A_XGM_INT_ENABLE + pi->mac.offset,
+					 F_XGM_INT, F_XGM_INT);
+			t3_xgm_intr_enable(adapter, pi->port_id);
+
 			netif_carrier_on(dev);
 		} else {
 			netif_carrier_off(dev);
-			pi->phy.ops->power_down(&pi->phy, 1);
+
+			t3_xgm_intr_disable(adapter, pi->port_id);
+			t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+			t3_set_reg_field(adapter,
+					 A_XGM_INT_ENABLE + pi->mac.offset,
+					 F_XGM_INT, 0);
+
+			if (is_10G(adapter))
+				pi->phy.ops->power_down(&pi->phy, 1);
+
+			t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
 			t3_mac_disable(mac, MAC_DIRECTION_RX);
 			t3_link_start(&pi->phy, mac, &pi->link_config);
 		}
@@ -339,7 +397,7 @@ static void free_irq_resources(struct ad
 
 		free_irq(adapter->msix_info[0].vec, adapter);
 		for_each_port(adapter, i)
-		    n += adap2pinfo(adapter, i)->nqsets;
+			n += adap2pinfo(adapter, i)->nqsets;
 
 		for (i = 0; i < n; ++i)
 			free_irq(adapter->msix_info[i + 1].vec,
@@ -509,19 +567,9 @@ static void set_qset_lro(struct net_devi
 {
 	struct port_info *pi = netdev_priv(dev);
 	struct adapter *adapter = pi->adapter;
-	int i, lro_on = 1;
 
 	adapter->params.sge.qset[qset_idx].lro = !!val;
 	adapter->sge.qs[qset_idx].lro_enabled = !!val;
-
-	/* let ethtool report LRO on only if all queues are LRO enabled */
-	for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; ++i)
-		lro_on &= adapter->params.sge.qset[i].lro;
-
-	if (lro_on)
-		dev->features |= NETIF_F_LRO;
-	else
-		dev->features &= ~NETIF_F_LRO;
 }
 
 /**
@@ -554,7 +602,6 @@ static int setup_sge_qsets(struct adapte
 				&adap->params.sge.qset[qset_idx], ntxq, dev,
 				netdev_get_tx_queue(dev, j));
 			if (err) {
-				t3_stop_sge_timers(adap);
 				t3_free_sge_resources(adap);
 				return err;
 			}
@@ -998,6 +1045,8 @@ static int cxgb_up(struct adapter *adap)
 		setup_rss(adap);
 		if (!(adap->flags & NAPI_INIT))
 			init_napi(adap);
+
+		t3_start_sge_timers(adap);
 		adap->flags |= FULL_INIT_DONE;
 	}
 
@@ -1068,8 +1117,8 @@ static void cxgb_down(struct adapter *ad
 	spin_unlock_irq(&adapter->work_lock);
 
 	free_irq_resources(adapter);
-	flush_workqueue(cxgb3_wq);	/* wait for external IRQ handler */
 	quiesce_rx(adapter);
+	flush_workqueue(cxgb3_wq);	/* wait for external IRQ handler */
 }
 
 static void schedule_chk_task(struct adapter *adap)
@@ -1138,6 +1187,9 @@ static int offload_close(struct t3cdev *
 
 	sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
 
+	/* Flush work scheduled while releasing TIDs */
+	flush_scheduled_work();
+
 	tdev->lldev = NULL;
 	cxgb3_set_dummy_ops(tdev);
 	t3_tp_set_offload_mode(adapter, 0);
@@ -1183,6 +1235,14 @@ static int cxgb_close(struct net_device
 	struct port_info *pi = netdev_priv(dev);
 	struct adapter *adapter = pi->adapter;
 
+	
+	if (!adapter->open_device_map)
+		return 0;
+
+	/* Stop link fault interrupts */
+	t3_xgm_intr_disable(adapter, pi->port_id);
+	t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+
 	t3_port_intr_disable(adapter, pi->port_id);
 	netif_tx_stop_all_queues(dev);
 	pi->phy.ops->power_down(&pi->phy, 1);
@@ -1194,8 +1254,7 @@ static int cxgb_close(struct net_device
 	spin_unlock_irq(&adapter->work_lock);
 
 	if (!(adapter->open_device_map & PORT_MASK))
-		cancel_rearming_delayed_workqueue(cxgb3_wq,
-						  &adapter->adap_check_task);
+		cancel_delayed_work_sync(&adapter->adap_check_task);
 
 	if (!adapter->open_device_map)
 		cxgb_down(adapter);
@@ -1309,6 +1368,7 @@ static char stats_strings[][ETH_GSTRING_
 	"CheckTXEnToggled   ",
 	"CheckResets        ",
 
+	"LinkFaults         ",
 };
 
 static int get_sset_count(struct net_device *dev, int sset)
@@ -1434,13 +1494,15 @@ static void get_stats(struct net_device
 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
-	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
+	*data++ = 0;
+	*data++ = 0;
+	*data++ = 0;
 	*data++ = s->rx_cong_drops;
 
 	*data++ = s->num_toggled;
 	*data++ = s->num_resets;
+
+	*data++ = s->link_faults;
 }
 
 static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -1576,7 +1638,6 @@ static int speed_duplex_to_caps(int spee
 
 static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	int cap;
 	struct port_info *p = netdev_priv(dev);
 	struct link_config *lc = &p->link_config;
 
@@ -1586,7 +1647,7 @@ static int set_settings(struct net_devic
 		 * being requested.
 		 */
 		if (cmd->autoneg == AUTONEG_DISABLE) {
-			cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+			int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
 			if (lc->supported & cap)
 				return 0;
 		}
@@ -1827,28 +1888,6 @@ static void get_wol(struct net_device *d
 	memset(&wol->sopass, 0, sizeof(wol->sopass));
 }
 
-static int cxgb3_set_flags(struct net_device *dev, u32 data)
-{
-	struct port_info *pi = netdev_priv(dev);
-	int i;
-
-	if (data & ETH_FLAG_LRO) {
-		if (!(pi->rx_offload & T3_RX_CSUM))
-			return -EINVAL;
-
-		pi->rx_offload |= T3_LRO;
-		for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
-			set_qset_lro(dev, i, 1);
-
-	} else {
-		pi->rx_offload &= ~T3_LRO;
-		for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
-			set_qset_lro(dev, i, 0);
-	}
-
-	return 0;
-}
-
 static const struct ethtool_ops cxgb_ethtool_ops = {
 	.get_settings = get_settings,
 	.set_settings = set_settings,
@@ -1878,8 +1917,6 @@ static const struct ethtool_ops cxgb_eth
 	.get_regs = get_regs,
 	.get_wol = get_wol,
 	.set_tso = ethtool_op_set_tso,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = cxgb3_set_flags,
 };
 
 static int in_range(int val, int lo, int hi)
@@ -2459,9 +2496,24 @@ static void check_link_status(struct ada
 	for_each_port(adapter, i) {
 		struct net_device *dev = adapter->port[i];
 		struct port_info *p = netdev_priv(dev);
+		int link_fault;
+
+		spin_lock_irq(&adapter->work_lock);
+		link_fault = p->link_fault;
+		spin_unlock_irq(&adapter->work_lock);
+
+		if (link_fault) {
+			t3_link_fault(adapter, i);
+			continue;
+		}
+
+		if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
+			t3_xgm_intr_disable(adapter, i);
+			t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
 
-		if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev))
 			t3_link_changed(adapter, i);
+			t3_xgm_intr_enable(adapter, i);
+		}
 	}
 }
 
@@ -2506,12 +2558,12 @@ static void t3_adap_check_task(struct wo
 	struct adapter *adapter = container_of(work, struct adapter,
 					       adap_check_task.work);
 	const struct adapter_params *p = &adapter->params;
+	int port;
+	unsigned int v, status, reset;
 
 	adapter->check_task_cnt++;
 
-	/* Check link status for PHYs without interrupts */
-	if (p->linkpoll_period)
-		check_link_status(adapter);
+	check_link_status(adapter);
 
 	/* Accumulate MAC stats if needed */
 	if (!p->linkpoll_period ||
@@ -2524,6 +2576,54 @@ static void t3_adap_check_task(struct wo
 	if (p->rev == T3_REV_B2)
 		check_t3b2_mac(adapter);
 
+	/*
+	 * Scan the XGMAC's to check for various conditions which we want to
+	 * monitor in a periodic polling manner rather than via an interrupt
+	 * condition.  This is used for conditions which would otherwise flood
+	 * the system with interrupts and we only really need to know that the
+	 * conditions are "happening" ...  For each condition we count the
+	 * detection of the condition and reset it for the next polling loop.
+	 */
+	for_each_port(adapter, port) {
+		struct cmac *mac =  &adap2pinfo(adapter, port)->mac;
+		u32 cause;
+
+		cause = t3_read_reg(adapter, A_XGM_INT_CAUSE + mac->offset);
+		reset = 0;
+		if (cause & F_RXFIFO_OVERFLOW) {
+			mac->stats.rx_fifo_ovfl++;
+			reset |= F_RXFIFO_OVERFLOW;
+		}
+
+		t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, reset);
+	}
+
+	/*
+	 * We do the same as above for FL_EMPTY interrupts.
+	 */
+	status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+	reset = 0;
+
+	if (status & F_FLEMPTY) {
+		struct sge_qset *qs = &adapter->sge.qs[0];
+		int i = 0;
+
+		reset |= F_FLEMPTY;
+
+		v = (t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS) >> S_FL0EMPTY) &
+		    0xffff;
+
+		while (v) {
+			qs->fl[i].empty += (v & 1);
+			if (i)
+				qs++;
+			i ^= 1;
+			v >>= 1;
+		}
+	}
+
+	t3_write_reg(adapter, A_SG_INT_CAUSE, reset);
+
 	/* Schedule the next check update if any port is active. */
 	spin_lock_irq(&adapter->work_lock);
 	if (adapter->open_device_map & PORT_MASK)
@@ -2538,9 +2638,23 @@ static void ext_intr_task(struct work_st
 {
 	struct adapter *adapter = container_of(work, struct adapter,
 					       ext_intr_handler_task);
+	int i;
+
+	/* Disable link fault interrupts */
+	for_each_port(adapter, i) {
+		struct net_device *dev = adapter->port[i];
+		struct port_info *p = netdev_priv(dev);
 
+		t3_xgm_intr_disable(adapter, i);
+		t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
+	}
+
+	/* Re-enable link fault interrupts */
 	t3_phy_intr_handler(adapter);
 
+	for_each_port(adapter, i)
+		t3_xgm_intr_enable(adapter, i);
+
 	/* Now reenable external interrupts */
 	spin_lock_irq(&adapter->work_lock);
 	if (adapter->slow_intr_mask) {
@@ -2573,10 +2687,26 @@ void t3_os_ext_intr_handler(struct adapt
 	spin_unlock(&adapter->work_lock);
 }
 
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
+{
+	struct net_device *netdev = adapter->port[port_id];
+	struct port_info *pi = netdev_priv(netdev);
+
+	spin_lock(&adapter->work_lock);
+	pi->link_fault = 1;
+	spin_unlock(&adapter->work_lock);
+}
+
 static int t3_adapter_error(struct adapter *adapter, int reset)
 {
 	int i, ret = 0;
 
+	if (is_offload(adapter) &&
+	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
+		cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
+		offload_close(&adapter->tdev);
+	}
+
 	/* Stop all ports */
 	for_each_port(adapter, i) {
 		struct net_device *netdev = adapter->port[i];
@@ -2585,10 +2715,6 @@ static int t3_adapter_error(struct adapt
 			cxgb_close(netdev);
 	}
 
-	if (is_offload(adapter) &&
-	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
-		offload_close(&adapter->tdev);
-
 	/* Stop SGE timers */
 	t3_stop_sge_timers(adapter);
 
@@ -2640,6 +2766,9 @@ static void t3_resume_ports(struct adapt
 			}
 		}
 	}
+
+	if (is_offload(adapter) && !ofld_disable)
+		cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
 }
 
 /*
@@ -2684,7 +2813,6 @@ void t3_fatal_err(struct adapter *adapte
 		CH_ALERT(adapter, "FW status: 0x%x, 0x%x, 0x%x, 0x%x\n",
 			 fw_status[0], fw_status[1],
 			 fw_status[2], fw_status[3]);
-
 }
 
 /**
@@ -2701,6 +2829,9 @@ static pci_ers_result_t t3_io_error_dete
 	struct adapter *adapter = pci_get_drvdata(pdev);
 	int ret;
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	ret = t3_adapter_error(adapter, 0);
 
 	/* Request a slot reset. */
@@ -2734,6 +2865,9 @@ static void t3_io_resume(struct pci_dev
 {
 	struct adapter *adapter = pci_get_drvdata(pdev);
 
+	CH_ALERT(adapter, "adapter recovering, PEX ERR 0x%x\n",
+		 t3_read_reg(adapter, A_PCIE_PEX_ERR));
+
 	t3_resume_ports(adapter);
 }
 
@@ -2753,7 +2887,7 @@ static void set_nqsets(struct adapter *a
 	int i, j = 0;
 	int num_cpus = num_online_cpus();
 	int hwports = adap->params.nports;
-	int nqsets = SGE_QSETS;
+	int nqsets = adap->msix_nvectors - 1;
 
 	if (adap->params.rev > 0 && adap->flags & USING_MSIX) {
 		if (hwports == 2 &&
@@ -2782,18 +2916,30 @@ static void set_nqsets(struct adapter *a
 static int __devinit cxgb_enable_msix(struct adapter *adap)
 {
 	struct msix_entry entries[SGE_QSETS + 1];
+	int vectors;
 	int i, err;
 
-	for (i = 0; i < ARRAY_SIZE(entries); ++i)
+	vectors = ARRAY_SIZE(entries);
+	for (i = 0; i < vectors; ++i)
 		entries[i].entry = i;
 
-	err = pci_enable_msix(adap->pdev, entries, ARRAY_SIZE(entries));
+	while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
+		vectors = err;
+
+	if (err < 0)
+		pci_disable_msix(adap->pdev);
+
+	if (!err && vectors < (adap->params.nports + 1)) {
+		pci_disable_msix(adap->pdev);
+		err = -1;
+	}
+
 	if (!err) {
-		for (i = 0; i < ARRAY_SIZE(entries); ++i)
+		for (i = 0; i < vectors; ++i)
 			adap->msix_info[i].vec = entries[i].vector;
-	} else if (err > 0)
-		dev_info(&adap->pdev->dev,
-		       "only %d MSI-X vectors left, not using MSI-X\n", err);
+		adap->msix_nvectors = vectors;
+	}
+
 	return err;
 }
 
@@ -2859,7 +3005,7 @@ static int __devinit init_one(struct pci
 	static int version_printed;
 
 	int i, err, pci_using_dac = 0;
-	unsigned long mmio_start, mmio_len;
+	resource_size_t mmio_start, mmio_len;
 	const struct adapter_info *ai;
 	struct adapter *adapter = NULL;
 	struct port_info *pi;
@@ -2891,15 +3037,15 @@ static int __devinit init_one(struct pci
 		goto out_release_regions;
 	}
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (err) {
 			dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
 			       "coherent allocations\n");
 			goto out_disable_device;
 		}
-	} else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+	} else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
 		dev_err(&pdev->dev, "no usable DMA configuration\n");
 		goto out_disable_device;
 	}
@@ -2938,7 +3084,7 @@ static int __devinit init_one(struct pci
 	INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
 	INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
 
-	for (i = 0; i < ai->nports; ++i) {
+	for (i = 0; i < ai->nports0 + ai->nports1; ++i) {
 		struct net_device *netdev;
 
 		netdev = alloc_etherdev_mq(sizeof(struct port_info), SGE_QSETS);
@@ -2961,7 +3107,7 @@ static int __devinit init_one(struct pci
 		netdev->mem_end = mmio_start + mmio_len - 1;
 		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 		netdev->features |= NETIF_F_LLTX;
-		netdev->features |= NETIF_F_LRO;
+		netdev->features |= NETIF_F_GRO;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
 
@@ -3028,7 +3174,7 @@ static int __devinit init_one(struct pci
 
 out_free_dev:
 	iounmap(adapter->regs);
-	for (i = ai->nports - 1; i >= 0; --i)
+	for (i = ai->nports0 + ai->nports1 - 1; i >= 0; --i)
 		if (adapter->port[i])
 			free_netdev(adapter->port[i]);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_offload.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_offload.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_offload.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_offload.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,18 @@ void cxgb3_remove_clients(struct t3cdev
 	mutex_unlock(&cxgb3_db_lock);
 }
 
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error)
+{
+	struct cxgb3_client *client;
+
+	mutex_lock(&cxgb3_db_lock);
+	list_for_each_entry(client, &client_list, client_list) {
+		if (client->err_handler)
+			client->err_handler(tdev, status, error);
+	}
+	mutex_unlock(&cxgb3_db_lock);
+}
+
 static struct net_device *get_iff_from_mac(struct adapter *adapter,
 					   const unsigned char *mac,
 					   unsigned int vlan)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_offload.h linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_offload.h
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/cxgb3_offload.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/cxgb3_offload.h	2009-06-09 23:05:27.000000000 -0400
@@ -64,10 +64,16 @@ void cxgb3_register_client(struct cxgb3_
 void cxgb3_unregister_client(struct cxgb3_client *client);
 void cxgb3_add_clients(struct t3cdev *tdev);
 void cxgb3_remove_clients(struct t3cdev *tdev);
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error);
 
 typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev,
 				      struct sk_buff *skb, void *ctx);
 
+enum {
+	OFFLOAD_STATUS_UP,
+	OFFLOAD_STATUS_DOWN
+};
+
 struct cxgb3_client {
 	char *name;
 	void (*add) (struct t3cdev *);
@@ -76,6 +82,7 @@ struct cxgb3_client {
 	int (*redirect)(void *ctx, struct dst_entry *old,
 			struct dst_entry *new, struct l2t_entry *l2t);
 	struct list_head client_list;
+	void (*err_handler)(struct t3cdev *tdev, u32 status, u32 error);
 };
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/regs.h linux-libre-2.6.30-gnu1/drivers/net/cxgb3/regs.h
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -170,6 +170,10 @@
 
 #define S_RSPQ0DISABLED    8
 
+#define S_FL0EMPTY    16
+#define V_FL0EMPTY(x) ((x) << S_FL0EMPTY)
+#define F_FL0EMPTY    V_FL0EMPTY(1U)
+
 #define A_SG_EGR_RCQ_DRB_THRSH 0x54
 
 #define S_HIRCQDRBTHRSH    16
@@ -258,6 +262,10 @@
 #define V_RSPQCREDITOVERFOW(x) ((x) << S_RSPQCREDITOVERFOW)
 #define F_RSPQCREDITOVERFOW    V_RSPQCREDITOVERFOW(1U)
 
+#define S_FLEMPTY    1
+#define V_FLEMPTY(x) ((x) << S_FLEMPTY)
+#define F_FLEMPTY    V_FLEMPTY(1U)
+
 #define A_SG_INT_ENABLE 0x60
 
 #define A_SG_CMDQ_CREDIT_TH 0x64
@@ -2207,6 +2215,15 @@
 
 #define A_XGM_RX_EXACT_MATCH_LOW_8 0x854
 
+#define A_XGM_INT_STATUS 0x86c
+
+#define S_LINKFAULTCHANGE    9
+#define V_LINKFAULTCHANGE(x) ((x) << S_LINKFAULTCHANGE)
+#define F_LINKFAULTCHANGE    V_LINKFAULTCHANGE(1U)
+
+#define A_XGM_XGM_INT_ENABLE 0x874
+#define A_XGM_XGM_INT_DISABLE 0x878
+
 #define A_XGM_STAT_CTRL 0x880
 
 #define S_CLRSTATS    2
@@ -2405,6 +2422,10 @@
 #define V_XAUIPCSALIGNCHANGE(x) ((x) << S_XAUIPCSALIGNCHANGE)
 #define F_XAUIPCSALIGNCHANGE    V_XAUIPCSALIGNCHANGE(1U)
 
+#define S_XGM_INT    0
+#define V_XGM_INT(x) ((x) << S_XGM_INT)
+#define F_XGM_INT    V_XGM_INT(1U)
+
 #define A_XGM_INT_CAUSE 0x8d8
 
 #define A_XGM_XAUI_ACT_CTRL 0x8dc
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/sge.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/sge.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/sge.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/sge.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,6 +50,7 @@
 #define SGE_RX_COPY_THRES  256
 #define SGE_RX_PULL_LEN    128
 
+#define SGE_PG_RSVD SMP_CACHE_BYTES
 /*
  * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
  * It must be a divisor of PAGE_SIZE.  If set to 0 FL0 will use sk_buffs
@@ -57,16 +58,25 @@
  */
 #define FL0_PG_CHUNK_SIZE  2048
 #define FL0_PG_ORDER 0
+#define FL0_PG_ALLOC_SIZE (PAGE_SIZE << FL0_PG_ORDER)
 #define FL1_PG_CHUNK_SIZE (PAGE_SIZE > 8192 ? 16384 : 8192)
 #define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
+#define FL1_PG_ALLOC_SIZE (PAGE_SIZE << FL1_PG_ORDER)
 
 #define SGE_RX_DROP_THRES 16
+#define RX_RECLAIM_PERIOD (HZ/4)
 
 /*
+ * Max number of Rx buffers we replenish at a time.
+ */
+#define MAX_RX_REFILL 16U
+/*
  * Period of the Tx buffer reclaim timer.  This timer does not need to run
  * frequently as Tx buffers are usually reclaimed by new Tx packets.
  */
 #define TX_RECLAIM_PERIOD (HZ / 4)
+#define TX_RECLAIM_TIMER_CHUNK 64U
+#define TX_RECLAIM_CHUNK 16U
 
 /* WR size in bytes */
 #define WR_LEN (WR_FLITS * 8)
@@ -304,21 +314,25 @@ static void free_tx_desc(struct adapter
  *	reclaim_completed_tx - reclaims completed Tx descriptors
  *	@adapter: the adapter
  *	@q: the Tx queue to reclaim completed descriptors from
+ *	@chunk: maximum number of descriptors to reclaim
  *
  *	Reclaims Tx descriptors that the SGE has indicated it has processed,
  *	and frees the associated buffers if possible.  Called with the Tx
  *	queue's lock held.
  */
-static inline void reclaim_completed_tx(struct adapter *adapter,
-					struct sge_txq *q)
+static inline unsigned int reclaim_completed_tx(struct adapter *adapter,
+						struct sge_txq *q,
+						unsigned int chunk)
 {
 	unsigned int reclaim = q->processed - q->cleaned;
 
+	reclaim = min(chunk, reclaim);
 	if (reclaim) {
 		free_tx_desc(adapter, q, reclaim);
 		q->cleaned += reclaim;
 		q->in_use -= reclaim;
 	}
+	return q->processed - q->cleaned;
 }
 
 /**
@@ -334,6 +348,26 @@ static inline int should_restart_tx(cons
 	return q->in_use - r < (q->size >> 1);
 }
 
+static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q,
+			  struct rx_sw_desc *d)
+{
+	if (q->use_pages && d->pg_chunk.page) {
+		(*d->pg_chunk.p_cnt)--;
+		if (!*d->pg_chunk.p_cnt)
+			pci_unmap_page(pdev,
+				       d->pg_chunk.mapping,
+				       q->alloc_size, PCI_DMA_FROMDEVICE);
+
+		put_page(d->pg_chunk.page);
+		d->pg_chunk.page = NULL;
+	} else {
+		pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
+				 q->buf_size, PCI_DMA_FROMDEVICE);
+		kfree_skb(d->skb);
+		d->skb = NULL;
+	}
+}
+
 /**
  *	free_rx_bufs - free the Rx buffers on an SGE free list
  *	@pdev: the PCI device associated with the adapter
@@ -349,16 +383,8 @@ static void free_rx_bufs(struct pci_dev
 	while (q->credits--) {
 		struct rx_sw_desc *d = &q->sdesc[cidx];
 
-		pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
-				 q->buf_size, PCI_DMA_FROMDEVICE);
-		if (q->use_pages) {
-			if (d->pg_chunk.page)
-				put_page(d->pg_chunk.page);
-			d->pg_chunk.page = NULL;
-		} else {
-			kfree_skb(d->skb);
-			d->skb = NULL;
-		}
+
+		clear_rx_desc(pdev, q, d);
 		if (++cidx == q->size)
 			cidx = 0;
 	}
@@ -401,18 +427,39 @@ static inline int add_one_rx_buf(void *v
 	return 0;
 }
 
-static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
+static inline int add_one_rx_chunk(dma_addr_t mapping, struct rx_desc *d,
+				   unsigned int gen)
+{
+	d->addr_lo = cpu_to_be32(mapping);
+	d->addr_hi = cpu_to_be32((u64) mapping >> 32);
+	wmb();
+	d->len_gen = cpu_to_be32(V_FLD_GEN1(gen));
+	d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
+	return 0;
+}
+
+static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q,
+			  struct rx_sw_desc *sd, gfp_t gfp,
 			  unsigned int order)
 {
 	if (!q->pg_chunk.page) {
+		dma_addr_t mapping;
+
 		q->pg_chunk.page = alloc_pages(gfp, order);
 		if (unlikely(!q->pg_chunk.page))
 			return -ENOMEM;
 		q->pg_chunk.va = page_address(q->pg_chunk.page);
+		q->pg_chunk.p_cnt = q->pg_chunk.va + (PAGE_SIZE << order) -
+				    SGE_PG_RSVD;
 		q->pg_chunk.offset = 0;
+		mapping = pci_map_page(adapter->pdev, q->pg_chunk.page,
+				       0, q->alloc_size, PCI_DMA_FROMDEVICE);
+		q->pg_chunk.mapping = mapping;
 	}
 	sd->pg_chunk = q->pg_chunk;
 
+	prefetch(sd->pg_chunk.p_cnt);
+
 	q->pg_chunk.offset += q->buf_size;
 	if (q->pg_chunk.offset == (PAGE_SIZE << order))
 		q->pg_chunk.page = NULL;
@@ -420,9 +467,23 @@ static int alloc_pg_chunk(struct sge_fl
 		q->pg_chunk.va += q->buf_size;
 		get_page(q->pg_chunk.page);
 	}
+
+	if (sd->pg_chunk.offset == 0)
+		*sd->pg_chunk.p_cnt = 1;
+	else
+		*sd->pg_chunk.p_cnt += 1;
+
 	return 0;
 }
 
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+	if (q->pend_cred >= q->credits / 4) {
+		q->pend_cred = 0;
+		t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+	}
+}
+
 /**
  *	refill_fl - refill an SGE free-buffer list
  *	@adapter: the adapter
@@ -436,38 +497,42 @@ static int alloc_pg_chunk(struct sge_fl
  */
 static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
 {
-	void *buf_start;
 	struct rx_sw_desc *sd = &q->sdesc[q->pidx];
 	struct rx_desc *d = &q->desc[q->pidx];
 	unsigned int count = 0;
 
 	while (n--) {
+		dma_addr_t mapping;
 		int err;
 
 		if (q->use_pages) {
-			if (unlikely(alloc_pg_chunk(q, sd, gfp, q->order))) {
+			if (unlikely(alloc_pg_chunk(adap, q, sd, gfp,
+						    q->order))) {
 nomem:				q->alloc_failed++;
 				break;
 			}
-			buf_start = sd->pg_chunk.va;
+			mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset;
+			pci_unmap_addr_set(sd, dma_addr, mapping);
+
+			add_one_rx_chunk(mapping, d, q->gen);
+			pci_dma_sync_single_for_device(adap->pdev, mapping,
+						q->buf_size - SGE_PG_RSVD,
+						PCI_DMA_FROMDEVICE);
 		} else {
-			struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
+			void *buf_start;
 
+			struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
 			if (!skb)
 				goto nomem;
 
 			sd->skb = skb;
 			buf_start = skb->data;
-		}
-
-		err = add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
-				     adap->pdev);
-		if (unlikely(err)) {
-			if (!q->use_pages) {
-				kfree_skb(sd->skb);
-				sd->skb = NULL;
+			err = add_one_rx_buf(buf_start, q->buf_size, d, sd,
+					     q->gen, adap->pdev);
+			if (unlikely(err)) {
+				clear_rx_desc(adap->pdev, q, sd);
+				break;
 			}
-			break;
 		}
 
 		d++;
@@ -478,19 +543,19 @@ nomem:				q->alloc_failed++;
 			sd = q->sdesc;
 			d = q->desc;
 		}
-		q->credits++;
 		count++;
 	}
-	wmb();
-	if (likely(count))
-		t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+	q->credits += count;
+	q->pend_cred += count;
+	ring_fl_db(adap, q);
 
 	return count;
 }
 
 static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
 {
-	refill_fl(adap, fl, min(16U, fl->size - fl->credits),
+	refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
 		  GFP_ATOMIC | __GFP_COMP);
 }
 
@@ -515,13 +580,15 @@ static void recycle_rx_buf(struct adapte
 	wmb();
 	to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
 	to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));
-	q->credits++;
 
 	if (++q->pidx == q->size) {
 		q->pidx = 0;
 		q->gen ^= 1;
 	}
-	t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+	q->credits++;
+	q->pend_cred++;
+	ring_fl_db(adap, q);
 }
 
 /**
@@ -585,8 +652,8 @@ static void t3_reset_qset(struct sge_qse
 	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
 	q->txq_stopped = 0;
 	q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
-	kfree(q->lro_frag_tbl);
-	q->lro_nfrags = q->lro_frag_len = 0;
+	q->rx_reclaim_timer.function = NULL;
+	q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
 }
 
 
@@ -733,7 +800,9 @@ recycle:
 		return skb;
 	}
 
-	if (unlikely(fl->credits < drop_thres))
+	if (unlikely(fl->credits < drop_thres) &&
+	    refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
+		      GFP_ATOMIC | __GFP_COMP) == 0)
 		goto recycle;
 
 use_orig_buf:
@@ -770,19 +839,19 @@ static struct sk_buff *get_packet_pg(str
 	struct sk_buff *newskb, *skb;
 	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
 
-	newskb = skb = q->pg_skb;
+	dma_addr_t dma_addr = pci_unmap_addr(sd, dma_addr);
 
+	newskb = skb = q->pg_skb;
 	if (!skb && (len <= SGE_RX_COPY_THRES)) {
 		newskb = alloc_skb(len, GFP_ATOMIC);
 		if (likely(newskb != NULL)) {
 			__skb_put(newskb, len);
-			pci_dma_sync_single_for_cpu(adap->pdev,
-					    pci_unmap_addr(sd, dma_addr), len,
+			pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
 					    PCI_DMA_FROMDEVICE);
 			memcpy(newskb->data, sd->pg_chunk.va, len);
-			pci_dma_sync_single_for_device(adap->pdev,
-					    pci_unmap_addr(sd, dma_addr), len,
-					    PCI_DMA_FROMDEVICE);
+			pci_dma_sync_single_for_device(adap->pdev, dma_addr,
+						       len,
+						       PCI_DMA_FROMDEVICE);
 		} else if (!drop_thres)
 			return NULL;
 recycle:
@@ -795,16 +864,25 @@ recycle:
 	if (unlikely(q->rx_recycle_buf || (!skb && fl->credits <= drop_thres)))
 		goto recycle;
 
+	prefetch(sd->pg_chunk.p_cnt);
+
 	if (!skb)
 		newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
+
 	if (unlikely(!newskb)) {
 		if (!drop_thres)
 			return NULL;
 		goto recycle;
 	}
 
-	pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
-			 fl->buf_size, PCI_DMA_FROMDEVICE);
+	pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
+				    PCI_DMA_FROMDEVICE);
+	(*sd->pg_chunk.p_cnt)--;
+	if (!*sd->pg_chunk.p_cnt)
+		pci_unmap_page(adap->pdev,
+			       sd->pg_chunk.mapping,
+			       fl->alloc_size,
+			       PCI_DMA_FROMDEVICE);
 	if (!skb) {
 		__skb_put(newskb, SGE_RX_PULL_LEN);
 		memcpy(newskb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
@@ -813,14 +891,15 @@ recycle:
 				   len - SGE_RX_PULL_LEN);
 		newskb->len = len;
 		newskb->data_len = len - SGE_RX_PULL_LEN;
+		newskb->truesize += newskb->data_len;
 	} else {
 		skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
 				   sd->pg_chunk.page,
 				   sd->pg_chunk.offset, len);
 		newskb->len += len;
 		newskb->data_len += len;
+		newskb->truesize += len;
 	}
-	newskb->truesize += newskb->data_len;
 
 	fl->credits--;
 	/*
@@ -1063,7 +1142,7 @@ static void write_tx_pkt_wr(struct adapt
 	struct tx_desc *d = &q->desc[pidx];
 	struct cpl_tx_pkt *cpl = (struct cpl_tx_pkt *)d;
 
-	cpl->len = htonl(skb->len | 0x80000000);
+	cpl->len = htonl(skb->len);
 	cntrl = V_TXPKT_INTF(pi->port_id);
 
 	if (vlan_tx_tag_present(skb) && pi->vlan_grp)
@@ -1161,7 +1240,7 @@ int t3_eth_xmit(struct sk_buff *skb, str
 	txq = netdev_get_tx_queue(dev, qidx);
 
 	spin_lock(&q->lock);
-	reclaim_completed_tx(adap, q);
+	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
 
 	credits = q->size - q->in_use;
 	ndesc = calc_tx_descs(skb);
@@ -1570,7 +1649,7 @@ static int ofld_xmit(struct adapter *ada
 	unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen;
 
 	spin_lock(&q->lock);
-      again:reclaim_completed_tx(adap, q);
+again:	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
 
 	ret = check_desc_avail(adap, q, skb, ndesc, TXQ_OFLD);
 	if (unlikely(ret)) {
@@ -1612,7 +1691,7 @@ static void restart_offloadq(unsigned lo
 	struct adapter *adap = pi->adapter;
 
 	spin_lock(&q->lock);
-      again:reclaim_completed_tx(adap, q);
+again:	reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
 
 	while ((skb = skb_peek(&q->sendq)) != NULL) {
 		unsigned int gen, pidx;
@@ -1932,12 +2011,13 @@ static void rx_eth(struct adapter *adap,
 	skb_pull(skb, sizeof(*p) + pad);
 	skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
 	pi = netdev_priv(skb->dev);
-	if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid && p->csum == htons(0xffff) &&
-	    !p->fragment) {
+	if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
+	    p->csum == htons(0xffff) && !p->fragment) {
 		qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else
 		skb->ip_summed = CHECKSUM_NONE;
+	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
 
 	if (unlikely(p->vlan_valid)) {
 		struct vlan_group *grp = pi->vlan_grp;
@@ -1945,10 +2025,8 @@ static void rx_eth(struct adapter *adap,
 		qs->port_stats[SGE_PSTAT_VLANEX]++;
 		if (likely(grp))
 			if (lro)
-				lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
-							     grp,
-							     ntohs(p->vlan),
-							     p);
+				vlan_gro_receive(&qs->napi, grp,
+						 ntohs(p->vlan), skb);
 			else {
 				if (unlikely(pi->iscsi_ipv4addr &&
 				    is_arp(skb))) {
@@ -1965,7 +2043,7 @@ static void rx_eth(struct adapter *adap,
 			dev_kfree_skb_any(skb);
 	} else if (rq->polling) {
 		if (lro)
-			lro_receive_skb(&qs->lro_mgr, skb, p);
+			napi_gro_receive(&qs->napi, skb);
 		else {
 			if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
 				cxgb3_arp_process(adap, skb);
@@ -1981,59 +2059,6 @@ static inline int is_eth_tcp(u32 rss)
 }
 
 /**
- *	lro_frame_ok - check if an ingress packet is eligible for LRO
- *	@p: the CPL header of the packet
- *
- *	Returns true if a received packet is eligible for LRO.
- *	The following conditions must be true:
- *	- packet is TCP/IP Ethernet II (checked elsewhere)
- *	- not an IP fragment
- *	- no IP options
- *	- TCP/IP checksums are correct
- *	- the packet is for this host
- */
-static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
-{
-	const struct ethhdr *eh = (struct ethhdr *)(p + 1);
-	const struct iphdr *ih = (struct iphdr *)(eh + 1);
-
-	return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
-		eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
-}
-
-static int t3_get_lro_header(void **eh,  void **iph, void **tcph,
-			     u64 *hdr_flags, void *priv)
-{
-	const struct cpl_rx_pkt *cpl = priv;
-
-	if (!lro_frame_ok(cpl))
-		return -1;
-
-	*eh = (struct ethhdr *)(cpl + 1);
-	*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
-	*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
-
-	*hdr_flags = LRO_IPV4 | LRO_TCP;
-	return 0;
-}
-
-static int t3_get_skb_header(struct sk_buff *skb,
-			      void **iph, void **tcph, u64 *hdr_flags,
-			      void *priv)
-{
-	void *eh;
-
-	return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
-}
-
-static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
-			      void **iph, void **tcph, u64 *hdr_flags,
-			      void *priv)
-{
-	return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
-}
-
-/**
  *	lro_add_page - add a page chunk to an LRO session
  *	@adap: the adapter
  *	@qs: the associated queue set
@@ -2049,8 +2074,9 @@ static void lro_add_page(struct adapter
 {
 	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
 	struct cpl_rx_pkt *cpl;
-	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
-	int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
+	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
+	int nr_frags = qs->lro_frag_tbl.nr_frags;
+	int frag_len = qs->lro_frag_tbl.len;
 	int offset = 0;
 
 	if (!nr_frags) {
@@ -2061,21 +2087,33 @@ static void lro_add_page(struct adapter
 	fl->credits--;
 
 	len -= offset;
-	pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
-			 fl->buf_size, PCI_DMA_FROMDEVICE);
+	pci_dma_sync_single_for_cpu(adap->pdev,
+				    pci_unmap_addr(sd, dma_addr),
+				    fl->buf_size - SGE_PG_RSVD,
+				    PCI_DMA_FROMDEVICE);
+
+	(*sd->pg_chunk.p_cnt)--;
+	if (!*sd->pg_chunk.p_cnt)
+		pci_unmap_page(adap->pdev,
+			       sd->pg_chunk.mapping,
+			       fl->alloc_size,
+			       PCI_DMA_FROMDEVICE);
+
+	prefetch(qs->lro_va);
 
 	rx_frag += nr_frags;
 	rx_frag->page = sd->pg_chunk.page;
 	rx_frag->page_offset = sd->pg_chunk.offset + offset;
 	rx_frag->size = len;
 	frag_len += len;
-	qs->lro_nfrags++;
-	qs->lro_frag_len = frag_len;
+	qs->lro_frag_tbl.nr_frags++;
+	qs->lro_frag_tbl.len = frag_len;
+
 
 	if (!complete)
 		return;
 
-	qs->lro_nfrags = qs->lro_frag_len = 0;
+	qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
 	cpl = qs->lro_va;
 
 	if (unlikely(cpl->vlan_valid)) {
@@ -2084,36 +2122,15 @@ static void lro_add_page(struct adapter
 		struct vlan_group *grp = pi->vlan_grp;
 
 		if (likely(grp != NULL)) {
-			lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
-						       qs->lro_frag_tbl,
-						       frag_len, frag_len,
-						       grp, ntohs(cpl->vlan),
-						       cpl, 0);
-			return;
+			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
+				       &qs->lro_frag_tbl);
+			goto out;
 		}
 	}
-	lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
-			  frag_len, frag_len, cpl, 0);
-}
+	napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
 
-/**
- *	init_lro_mgr - initialize a LRO manager object
- *	@lro_mgr: the LRO manager object
- */
-static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
-{
-	lro_mgr->dev = qs->netdev;
-	lro_mgr->features = LRO_F_NAPI;
-	lro_mgr->frag_align_pad = NET_IP_ALIGN;
-	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
-	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-	lro_mgr->max_desc = T3_MAX_LRO_SES;
-	lro_mgr->lro_arr = qs->lro_desc;
-	lro_mgr->get_frag_header = t3_get_frag_header;
-	lro_mgr->get_skb_header = t3_get_skb_header;
-	lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
-	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
-		lro_mgr->max_aggr = MAX_SKB_FRAGS;
+out:
+	qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
 }
 
 /**
@@ -2282,6 +2299,8 @@ no_mem:
 			if (fl->use_pages) {
 				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
 
+				prefetch(&qs->lro_frag_tbl);
+
 				prefetch(addr);
 #if L1_CACHE_BYTES < 128
 				prefetch(addr + L1_CACHE_BYTES);
@@ -2356,10 +2375,6 @@ next_fl:
 	}
 
 	deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
-	lro_flush_all(&qs->lro_mgr);
-	qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
-	qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
-	qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
 
 	if (sleeping)
 		check_ring_db(adap, qs, sleeping);
@@ -2775,7 +2790,8 @@ irq_handler_t t3_intr_handler(struct ada
  */
 void t3_sge_err_intr_handler(struct adapter *adapter)
 {
-	unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+	unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE) &
+				 ~F_FLEMPTY;
 
 	if (status & SGE_PARERR)
 		CH_ALERT(adapter, "SGE parity error (0x%x)\n",
@@ -2805,13 +2821,13 @@ void t3_sge_err_intr_handler(struct adap
 }
 
 /**
- *	sge_timer_cb - perform periodic maintenance of an SGE qset
+ *	sge_timer_tx - perform periodic maintenance of an SGE qset
  *	@data: the SGE queue set to maintain
  *
  *	Runs periodically from a timer to perform maintenance of an SGE queue
  *	set.  It performs two tasks:
  *
- *	a) Cleans up any completed Tx descriptors that may still be pending.
+ *	Cleans up any completed Tx descriptors that may still be pending.
  *	Normal descriptor cleanup happens when new packets are added to a Tx
  *	queue so this timer is relatively infrequent and does any cleanup only
  *	if the Tx queue has not seen any new packets in a while.  We make a
@@ -2821,51 +2837,87 @@ void t3_sge_err_intr_handler(struct adap
  *	up).  Since control queues use immediate data exclusively we don't
  *	bother cleaning them up here.
  *
- *	b) Replenishes Rx queues that have run out due to memory shortage.
- *	Normally new Rx buffers are added when existing ones are consumed but
- *	when out of memory a queue can become empty.  We try to add only a few
- *	buffers here, the queue will be replenished fully as these new buffers
- *	are used up if memory shortage has subsided.
  */
-static void sge_timer_cb(unsigned long data)
+static void sge_timer_tx(unsigned long data)
 {
-	spinlock_t *lock;
 	struct sge_qset *qs = (struct sge_qset *)data;
-	struct adapter *adap = qs->adap;
+	struct port_info *pi = netdev_priv(qs->netdev);
+	struct adapter *adap = pi->adapter;
+	unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
+	unsigned long next_period;
 
 	if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
-		reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
+		tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
+						    TX_RECLAIM_TIMER_CHUNK);
 		spin_unlock(&qs->txq[TXQ_ETH].lock);
 	}
 	if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
-		reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD]);
+		tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
+						     TX_RECLAIM_TIMER_CHUNK);
 		spin_unlock(&qs->txq[TXQ_OFLD].lock);
 	}
-	lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock :
-					    &adap->sge.qs[0].rspq.lock;
-	if (spin_trylock_irq(lock)) {
-		if (!napi_is_scheduled(&qs->napi)) {
-			u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
 
-			if (qs->fl[0].credits < qs->fl[0].size)
-				__refill_fl(adap, &qs->fl[0]);
-			if (qs->fl[1].credits < qs->fl[1].size)
-				__refill_fl(adap, &qs->fl[1]);
+	next_period = TX_RECLAIM_PERIOD >>
+		      (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
+		       TX_RECLAIM_TIMER_CHUNK);
+	mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
+}
 
-			if (status & (1 << qs->rspq.cntxt_id)) {
-				qs->rspq.starved++;
-				if (qs->rspq.credits) {
-					refill_rspq(adap, &qs->rspq, 1);
-					qs->rspq.credits--;
-					qs->rspq.restarted++;
-					t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
-						     1 << qs->rspq.cntxt_id);
-				}
+/*
+ *	sge_timer_rx - perform periodic maintenance of an SGE qset
+ *	@data: the SGE queue set to maintain
+ *
+ *	a) Replenishes Rx queues that have run out due to memory shortage.
+ *	Normally new Rx buffers are added when existing ones are consumed but
+ *	when out of memory a queue can become empty.  We try to add only a few
+ *	buffers here, the queue will be replenished fully as these new buffers
+ *	are used up if memory shortage has subsided.
+ *
+ *	b) Return coalesced response queue credits in case a response queue is
+ *	starved.
+ *
+ */
+static void sge_timer_rx(unsigned long data)
+{
+	spinlock_t *lock;
+	struct sge_qset *qs = (struct sge_qset *)data;
+	struct port_info *pi = netdev_priv(qs->netdev);
+	struct adapter *adap = pi->adapter;
+	u32 status;
+
+	lock = adap->params.rev > 0 ?
+	       &qs->rspq.lock : &adap->sge.qs[0].rspq.lock;
+
+	if (!spin_trylock_irq(lock))
+		goto out;
+
+	if (napi_is_scheduled(&qs->napi))
+		goto unlock;
+
+	if (adap->params.rev < 4) {
+		status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
+
+		if (status & (1 << qs->rspq.cntxt_id)) {
+			qs->rspq.starved++;
+			if (qs->rspq.credits) {
+				qs->rspq.credits--;
+				refill_rspq(adap, &qs->rspq, 1);
+				qs->rspq.restarted++;
+				t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
+					     1 << qs->rspq.cntxt_id);
 			}
 		}
-		spin_unlock_irq(lock);
 	}
-	mod_timer(&qs->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+
+	if (qs->fl[0].credits < qs->fl[0].size)
+		__refill_fl(adap, &qs->fl[0]);
+	if (qs->fl[1].credits < qs->fl[1].size)
+		__refill_fl(adap, &qs->fl[1]);
+
+unlock:
+	spin_unlock_irq(lock);
+out:
+	mod_timer(&qs->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
 }
 
 /**
@@ -2906,10 +2958,10 @@ int t3_sge_alloc_qset(struct adapter *ad
 {
 	int i, avail, ret = -ENOMEM;
 	struct sge_qset *q = &adapter->sge.qs[id];
-	struct net_lro_mgr *lro_mgr = &q->lro_mgr;
 
 	init_qset_cntxt(q, id);
-	setup_timer(&q->tx_reclaim_timer, sge_timer_cb, (unsigned long)q);
+	setup_timer(&q->tx_reclaim_timer, sge_timer_tx, (unsigned long)q);
+	setup_timer(&q->rx_reclaim_timer, sge_timer_rx, (unsigned long)q);
 
 	q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size,
 				   sizeof(struct rx_desc),
@@ -2985,25 +3037,23 @@ int t3_sge_alloc_qset(struct adapter *ad
 	q->fl[1].use_pages = FL1_PG_CHUNK_SIZE > 0;
 	q->fl[0].order = FL0_PG_ORDER;
 	q->fl[1].order = FL1_PG_ORDER;
+	q->fl[0].alloc_size = FL0_PG_ALLOC_SIZE;
+	q->fl[1].alloc_size = FL1_PG_ALLOC_SIZE;
 
-	q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
-				  sizeof(struct skb_frag_struct),
-				  GFP_KERNEL);
-	q->lro_nfrags = q->lro_frag_len = 0;
 	spin_lock_irq(&adapter->sge.reg_lock);
 
 	/* FL threshold comparison uses < */
 	ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx,
 				   q->rspq.phys_addr, q->rspq.size,
-				   q->fl[0].buf_size, 1, 0);
+				   q->fl[0].buf_size - SGE_PG_RSVD, 1, 0);
 	if (ret)
 		goto err_unlock;
 
 	for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
 		ret = t3_sge_init_flcntxt(adapter, q->fl[i].cntxt_id, 0,
 					  q->fl[i].phys_addr, q->fl[i].size,
-					  q->fl[i].buf_size, p->cong_thres, 1,
-					  0);
+					  q->fl[i].buf_size - SGE_PG_RSVD,
+					  p->cong_thres, 1, 0);
 		if (ret)
 			goto err_unlock;
 	}
@@ -3041,8 +3091,6 @@ int t3_sge_alloc_qset(struct adapter *ad
 	q->tx_q = netdevq;
 	t3_update_qset_coalesce(q, p);
 
-	init_lro_mgr(q, lro_mgr);
-
 	avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
 			  GFP_KERNEL | __GFP_COMP);
 	if (!avail) {
@@ -3063,7 +3111,6 @@ int t3_sge_alloc_qset(struct adapter *ad
 	t3_write_reg(adapter, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) |
 		     V_NEWTIMER(q->rspq.holdoff_tmr));
 
-	mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
 	return 0;
 
 err_unlock:
@@ -3074,6 +3121,27 @@ err:
 }
 
 /**
+ *      t3_start_sge_timers - start SGE timer call backs
+ *      @adap: the adapter
+ *
+ *      Starts each SGE queue set's timer call back
+ */
+void t3_start_sge_timers(struct adapter *adap)
+{
+	int i;
+
+	for (i = 0; i < SGE_QSETS; ++i) {
+		struct sge_qset *q = &adap->sge.qs[i];
+
+	if (q->tx_reclaim_timer.function)
+		mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+
+	if (q->rx_reclaim_timer.function)
+		mod_timer(&q->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
+	}
+}
+
+/**
  *	t3_stop_sge_timers - stop SGE timer call backs
  *	@adap: the adapter
  *
@@ -3088,6 +3156,8 @@ void t3_stop_sge_timers(struct adapter *
 
 		if (q->tx_reclaim_timer.function)
 			del_timer_sync(&q->tx_reclaim_timer);
+		if (q->rx_reclaim_timer.function)
+			del_timer_sync(&q->rx_reclaim_timer);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/t3_hw.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/t3_hw.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/t3_hw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/t3_hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -493,20 +493,20 @@ int t3_phy_lasi_intr_handler(struct cphy
 }
 
 static const struct adapter_info t3_adap_info[] = {
-	{2, 0,
+	{1, 1, 0,
 	 F_GPIO2_OEN | F_GPIO4_OEN |
 	 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
 	 &mi1_mdio_ops, "Chelsio PE9000"},
-	{2, 0,
+	{1, 1, 0,
 	 F_GPIO2_OEN | F_GPIO4_OEN |
 	 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
 	 &mi1_mdio_ops, "Chelsio T302"},
-	{1, 0,
+	{1, 0, 0,
 	 F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
 	 F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
 	 { 0 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
 	 &mi1_mdio_ext_ops, "Chelsio T310"},
-	{2, 0,
+	{1, 1, 0,
 	 F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
 	 F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
 	 F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
@@ -514,7 +514,7 @@ static const struct adapter_info t3_adap
 	 &mi1_mdio_ext_ops, "Chelsio T320"},
 	{},
 	{},
-	{1, 0,
+	{1, 0, 0,
 	 F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
 	 F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
 	 { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
@@ -1153,6 +1153,38 @@ int t3_cim_ctl_blk_read(struct adapter *
 	return ret;
 }
 
+static void t3_gate_rx_traffic(struct cmac *mac, u32 *rx_cfg,
+			       u32 *rx_hash_high, u32 *rx_hash_low)
+{
+	/* stop Rx unicast traffic */
+	t3_mac_disable_exact_filters(mac);
+
+	/* stop broadcast, multicast, promiscuous mode traffic */
+	*rx_cfg = t3_read_reg(mac->adapter, A_XGM_RX_CFG);
+	t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+			 F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+			 F_DISBCAST);
+
+	*rx_hash_high = t3_read_reg(mac->adapter, A_XGM_RX_HASH_HIGH);
+	t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, 0);
+
+	*rx_hash_low = t3_read_reg(mac->adapter, A_XGM_RX_HASH_LOW);
+	t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, 0);
+
+	/* Leave time to drain max RX fifo */
+	msleep(1);
+}
+
+static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg,
+			       u32 rx_hash_high, u32 rx_hash_low)
+{
+	t3_mac_enable_exact_filters(mac);
+	t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+			 F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+			 rx_cfg);
+	t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, rx_hash_high);
+	t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low);
+}
 
 /**
  *	t3_link_changed - handle interface link changes
@@ -1173,6 +1205,23 @@ void t3_link_changed(struct adapter *ada
 
 	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
+	if (!lc->link_ok && link_ok) {
+		u32 rx_cfg, rx_hash_high, rx_hash_low;
+		u32 status;
+
+		t3_xgm_intr_enable(adapter, port_id);
+		t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+		t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+		t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+		status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+		if (status & F_LINKFAULTCHANGE) {
+			mac->stats.link_faults++;
+			pi->link_fault = 1;
+		}
+		t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+	}
+
 	if (lc->requested_fc & PAUSE_AUTONEG)
 		fc &= lc->requested_fc;
 	else
@@ -1202,6 +1251,59 @@ void t3_link_changed(struct adapter *ada
 	t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
 }
 
+void t3_link_fault(struct adapter *adapter, int port_id)
+{
+	struct port_info *pi = adap2pinfo(adapter, port_id);
+	struct cmac *mac = &pi->mac;
+	struct cphy *phy = &pi->phy;
+	struct link_config *lc = &pi->link_config;
+	int link_ok, speed, duplex, fc, link_fault;
+	u32 rx_cfg, rx_hash_high, rx_hash_low;
+
+	t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+
+	if (adapter->params.rev > 0 && uses_xaui(adapter))
+		t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
+
+	t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+	t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+	t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+	link_fault = t3_read_reg(adapter,
+				 A_XGM_INT_STATUS + mac->offset);
+	link_fault &= F_LINKFAULTCHANGE;
+
+	link_ok = lc->link_ok;
+	speed = lc->speed;
+	duplex = lc->duplex;
+	fc = lc->fc;
+
+	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+
+	if (link_fault) {
+		lc->link_ok = 0;
+		lc->speed = SPEED_INVALID;
+		lc->duplex = DUPLEX_INVALID;
+
+		t3_os_link_fault(adapter, port_id, 0);
+
+		/* Account link faults only when the phy reports a link up */
+		if (link_ok)
+			mac->stats.link_faults++;
+	} else {
+		if (link_ok)
+			t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
+				     F_TXACTENABLE | F_RXEN);
+
+		pi->link_fault = 0;
+		lc->link_ok = (unsigned char)link_ok;
+		lc->speed = speed < 0 ? SPEED_INVALID : speed;
+		lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
+		t3_os_link_fault(adapter, port_id, link_ok);
+	}
+}
+
 /**
  *	t3_link_start - apply link configuration to MAC/PHY
  *	@phy: the PHY to setup
@@ -1323,7 +1425,7 @@ static int t3_handle_intr_status(struct
 #define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE))
 #define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
 		       V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \
-		       F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW)
+		       F_TXFIFO_UNDERRUN)
 #define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \
 			F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \
 			F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \
@@ -1360,11 +1462,11 @@ static int t3_handle_intr_status(struct
 		       V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \
 		       V_RXTPPARERRENB(M_RXTPPARERRENB) | \
 		       V_MCAPARERRENB(M_MCAPARERRENB))
+#define XGM_EXTRA_INTR_MASK (F_LINKFAULTCHANGE)
 #define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \
 		      F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \
 		      F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \
 		      F_MPS0 | F_CPL_SWITCH)
-
 /*
  * Interrupt handler for the PCIX1 module.
  */
@@ -1695,7 +1797,14 @@ static void mc7_intr_handler(struct mc7
 static int mac_intr_handler(struct adapter *adap, unsigned int idx)
 {
 	struct cmac *mac = &adap2pinfo(adap, idx)->mac;
-	u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
+	/*
+	 * We mask out interrupt causes for which we're not taking interrupts.
+	 * This allows us to use polling logic to monitor some of the other
+	 * conditions when taking interrupts would impose too much load on the
+	 * system.
+	 */
+	u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset) &
+		    ~F_RXFIFO_OVERFLOW;
 
 	if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
 		mac->stats.tx_fifo_parity_err++;
@@ -1715,10 +1824,20 @@ static int mac_intr_handler(struct adapt
 		mac->stats.xaui_pcs_ctc_err++;
 	if (cause & F_XAUIPCSALIGNCHANGE)
 		mac->stats.xaui_pcs_align_change++;
+	if (cause & F_XGM_INT) {
+		t3_set_reg_field(adap,
+				 A_XGM_INT_ENABLE + mac->offset,
+				 F_XGM_INT, 0);
+		mac->stats.link_faults++;
+
+		t3_os_link_fault_handler(adap, idx);
+	}
 
 	t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
+
 	if (cause & XGM_INTR_FATAL)
 		t3_fatal_err(adap);
+
 	return cause != 0;
 }
 
@@ -1924,6 +2043,22 @@ void t3_intr_clear(struct adapter *adapt
 	t3_read_reg(adapter, A_PL_INT_CAUSE0);	/* flush */
 }
 
+void t3_xgm_intr_enable(struct adapter *adapter, int idx)
+{
+	struct port_info *pi = adap2pinfo(adapter, idx);
+
+	t3_write_reg(adapter, A_XGM_XGM_INT_ENABLE + pi->mac.offset,
+		     XGM_EXTRA_INTR_MASK);
+}
+
+void t3_xgm_intr_disable(struct adapter *adapter, int idx)
+{
+	struct port_info *pi = adap2pinfo(adapter, idx);
+
+	t3_write_reg(adapter, A_XGM_XGM_INT_DISABLE + pi->mac.offset,
+		     0x7ff);
+}
+
 /**
  *	t3_port_intr_enable - enable port-specific interrupts
  *	@adapter: associated adapter
@@ -1989,16 +2124,40 @@ void t3_port_intr_clear(struct adapter *
 static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
 				unsigned int type)
 {
-	t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
-	t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
-	t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
-	t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+	if (type == F_RESPONSEQ) {
+		/*
+		 * Can't write the Response Queue Context bits for
+		 * Interrupt Armed or the Reserve bits after the chip
+		 * has been initialized out of reset.  Writing to these
+		 * bits can confuse the hardware.
+		 */
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0x17ffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+	} else {
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
+		t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+	}
 	t3_write_reg(adapter, A_SG_CONTEXT_CMD,
 		     V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
 	return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
 			       0, SG_CONTEXT_CMD_ATTEMPTS, 1);
 }
 
+/**
+ *	clear_sge_ctxt - completely clear an SGE context
+ *	@adapter: the adapter
+ *	@id: the context id
+ *	@type: the context type
+ *
+ *	Completely clear an SGE context.  Used predominantly at post-reset
+ *	initialization.  Note in particular that we don't skip writing to any
+ *	"sensitive bits" in the contexts the way that t3_sge_write_context()
+ *	does ...
+ */
 static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
 			  unsigned int type)
 {
@@ -2006,7 +2165,14 @@ static int clear_sge_ctxt(struct adapter
 	t3_write_reg(adap, A_SG_CONTEXT_DATA1, 0);
 	t3_write_reg(adap, A_SG_CONTEXT_DATA2, 0);
 	t3_write_reg(adap, A_SG_CONTEXT_DATA3, 0);
-	return t3_sge_write_context(adap, id, type);
+	t3_write_reg(adap, A_SG_CONTEXT_MASK0, 0xffffffff);
+	t3_write_reg(adap, A_SG_CONTEXT_MASK1, 0xffffffff);
+	t3_write_reg(adap, A_SG_CONTEXT_MASK2, 0xffffffff);
+	t3_write_reg(adap, A_SG_CONTEXT_MASK3, 0xffffffff);
+	t3_write_reg(adap, A_SG_CONTEXT_CMD,
+		     V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
+	return t3_wait_op_done(adap, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
+			       0, SG_CONTEXT_CMD_ATTEMPTS, 1);
 }
 
 /**
@@ -2590,10 +2756,10 @@ static void tp_config(struct adapter *ad
 		     F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
 	t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
 		     F_MTUENABLE | V_WINDOWSCALEMODE(1) |
-		     V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
+		     V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1));
 	t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
 		     V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
-		     V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
+		     V_BYTETHRESHOLD(26880) | V_MSSTHRESHOLD(2) |
 		     F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
 	t3_set_reg_field(adap, A_TP_IN_CONFIG, F_RXFBARBPRIO | F_TXFBARBPRIO,
 			 F_IPV6ENABLE | F_NICMODE);
@@ -3057,20 +3223,22 @@ int t3_mps_set_active_ports(struct adapt
 }
 
 /*
- * Perform the bits of HW initialization that are dependent on the number
- * of available ports.
+ * Perform the bits of HW initialization that are dependent on the Tx
+ * channels being used.
  */
-static void init_hw_for_avail_ports(struct adapter *adap, int nports)
+static void chan_init_hw(struct adapter *adap, unsigned int chan_map)
 {
 	int i;
 
-	if (nports == 1) {
+	if (chan_map != 3) {                                 /* one channel */
 		t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0);
 		t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
-		t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
-			     F_PORT0ACTIVE | F_ENFORCEPKT);
-		t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff);
-	} else {
+		t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_ENFORCEPKT |
+			     (chan_map == 1 ? F_TPTXPORT0EN | F_PORT0ACTIVE :
+					      F_TPTXPORT1EN | F_PORT1ACTIVE));
+		t3_write_reg(adap, A_PM1_TX_CFG,
+			     chan_map == 1 ? 0xffffffff : 0);
+	} else {                                             /* two channels */
 		t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
 		t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
 		t3_write_reg(adap, A_ULPTX_DMA_WEIGHT,
@@ -3378,7 +3546,7 @@ int t3_init_hw(struct adapter *adapter,
 	t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
 	t3_write_reg(adapter, A_PM1_RX_MODE, 0);
 	t3_write_reg(adapter, A_PM1_TX_MODE, 0);
-	init_hw_for_avail_ports(adapter, adapter->params.nports);
+	chan_init_hw(adapter, adapter->params.chan_map);
 	t3_sge_init(adapter, &adapter->params.sge);
 
 	t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
@@ -3615,9 +3783,18 @@ int t3_prep_adapter(struct adapter *adap
 	get_pci_mode(adapter, &adapter->params.pci);
 
 	adapter->params.info = ai;
-	adapter->params.nports = ai->nports;
+	adapter->params.nports = ai->nports0 + ai->nports1;
+	adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1);
 	adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
-	adapter->params.linkpoll_period = 0;
+	/*
+	 * We used to only run the "adapter check task" once a second if
+	 * we had PHYs which didn't support interrupts (we would check
+	 * their link status once a second).  Now we check other conditions
+	 * in that routine which could potentially impose a very high
+	 * interrupt load on the system.  As such, we now always scan the
+	 * adapter state once a second ...
+	 */
+	adapter->params.linkpoll_period = 10;
 	adapter->params.stats_update_period = is_10G(adapter) ?
 	    MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
 	adapter->params.pci.vpd_cap_addr =
@@ -3638,7 +3815,7 @@ int t3_prep_adapter(struct adapter *adap
 		mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX");
 		mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM");
 
-		p->nchan = ai->nports;
+		p->nchan = adapter->params.chan_map == 3 ? 2 : 1;
 		p->pmrx_size = t3_mc7_size(&adapter->pmrx);
 		p->pmtx_size = t3_mc7_size(&adapter->pmtx);
 		p->cm_size = t3_mc7_size(&adapter->cm);
@@ -3707,7 +3884,14 @@ int t3_prep_adapter(struct adapter *adap
 		       ETH_ALEN);
 		init_link_config(&p->link_config, p->phy.caps);
 		p->phy.ops->power_down(&p->phy, 1);
-		if (!(p->phy.caps & SUPPORTED_IRQ))
+
+		/*
+		 * If the PHY doesn't support interrupts for link status
+		 * changes, schedule a scan of the adapter links at least
+		 * once a second.
+		 */
+		if (!(p->phy.caps & SUPPORTED_IRQ) &&
+		    adapter->params.linkpoll_period > 10)
 			adapter->params.linkpoll_period = 10;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/version.h linux-libre-2.6.30-gnu1/drivers/net/cxgb3/version.h
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/version.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/version.h	2009-06-09 23:05:27.000000000 -0400
@@ -35,10 +35,10 @@
 #define DRV_DESC "Chelsio T3 Network Driver"
 #define DRV_NAME "cxgb3"
 /* Driver version */
-#define DRV_VERSION "1.1.1-ko"
+#define DRV_VERSION "1.1.2-ko"
 
 /* Firmware version */
 #define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 0
+#define FW_VERSION_MINOR 1
 #define FW_VERSION_MICRO 0
 #endif				/* __CHELSIO_VERSION_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/cxgb3/xgmac.c linux-libre-2.6.30-gnu1/drivers/net/cxgb3/xgmac.c
--- linux-libre-2.6.29-gnu1/drivers/net/cxgb3/xgmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/cxgb3/xgmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,7 +150,8 @@ int t3_mac_reset(struct cmac *mac)
 static int t3b2_mac_reset(struct cmac *mac)
 {
 	struct adapter *adap = mac->adapter;
-	unsigned int oft = mac->offset;
+	unsigned int oft = mac->offset, store;
+	int idx = macidx(mac);
 	u32 val;
 
 	if (!macidx(mac))
@@ -158,14 +159,28 @@ static int t3b2_mac_reset(struct cmac *m
 	else
 		t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
 
+	/* Stop NIC traffic to reduce the number of TXTOGGLES */
+	t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 0);
+	/* Ensure TX drains */
+	t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, 0);
+
 	t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
 	t3_read_reg(adap, A_XGM_RESET_CTRL + oft);    /* flush */
 
+	/* Store A_TP_TX_DROP_CFG_CH0 */
+	t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+	store = t3_read_reg(adap, A_TP_TX_DROP_CFG_CH0 + idx);
+
 	msleep(10);
 
+	/* Change DROP_CFG to 0xc0000011 */
+	t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+	t3_write_reg(adap, A_TP_PIO_DATA, 0xc0000011);
+
 	/* Check for xgm Rx fifo empty */
+	/* Increased loop count to 1000 from 5 cover 1G and 100Mbps case */
 	if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
-			    0x80000000, 1, 5, 2)) {
+			    0x80000000, 1, 1000, 2)) {
 		CH_ERR(adap, "MAC %d Rx fifo drain failed\n",
 		       macidx(mac));
 		return -1;
@@ -191,11 +206,21 @@ static int t3b2_mac_reset(struct cmac *m
 		     F_DISPAUSEFRAMES | F_EN1536BFRAMES |
 		     F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
 
-	if (!macidx(mac))
+	/* Restore the DROP_CFG */
+	t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+	t3_write_reg(adap, A_TP_PIO_DATA, store);
+
+	if (!idx)
 		t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
 	else
 		t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
 
+	/* re-enable nic traffic */
+	t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
+	/*  Set: re-enable NIC traffic */
+	t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
 	return 0;
 }
 
@@ -236,7 +261,7 @@ int t3_mac_set_num_ucast(struct cmac *ma
 	return 0;
 }
 
-static void disable_exact_filters(struct cmac *mac)
+void t3_mac_disable_exact_filters(struct cmac *mac)
 {
 	unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_LOW_1;
 
@@ -247,7 +272,7 @@ static void disable_exact_filters(struct
 	t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1);	/* flush */
 }
 
-static void enable_exact_filters(struct cmac *mac)
+void t3_mac_enable_exact_filters(struct cmac *mac)
 {
 	unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_HIGH_1;
 
@@ -332,18 +357,9 @@ int t3_mac_set_mtu(struct cmac *mac, uns
 		return -EINVAL;
 	t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
 
-	/*
-	 * Adjust the PAUSE frame watermarks.  We always set the LWM, and the
-	 * HWM only if flow-control is enabled.
-	 */
-	hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
-		    MAC_RXFIFO_SIZE * 38 / 100);
-	hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
-	lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
-
 	if (adap->params.rev >= T3_REV_B2 &&
 	    (t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
-		disable_exact_filters(mac);
+		t3_mac_disable_exact_filters(mac);
 		v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
 		t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
 				 F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
@@ -355,14 +371,14 @@ int t3_mac_set_mtu(struct cmac *mac, uns
 		if (t3_wait_op_done(adap, reg + mac->offset,
 				    F_RXFIFO_EMPTY, 1, 20, 5)) {
 			t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
-			enable_exact_filters(mac);
+			t3_mac_enable_exact_filters(mac);
 			return -EIO;
 		}
 		t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
 				 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
 				 V_RXMAXPKTSIZE(mtu));
 		t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
-		enable_exact_filters(mac);
+		t3_mac_enable_exact_filters(mac);
 	} else
 		t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
 				 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
@@ -452,9 +468,12 @@ int t3_mac_enable(struct cmac *mac, int
 
 	if (which & MAC_DIRECTION_TX) {
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
-		t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
+		t3_write_reg(adap, A_TP_PIO_DATA,
+			     adap->params.rev == T3_REV_C ?
+			     0xc4ffff01 : 0xc0ede401);
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
-		t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+		t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx,
+				 adap->params.rev == T3_REV_C ? 0 : 1 << idx);
 
 		t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
 
@@ -510,15 +529,12 @@ int t3b2_mac_watchdog_task(struct cmac *
 	struct adapter *adap = mac->adapter;
 	struct mac_stats *s = &mac->stats;
 	unsigned int tx_tcnt, tx_xcnt;
-	unsigned int tx_mcnt = s->tx_frames;
-	unsigned int rx_mcnt = s->rx_frames;
-	unsigned int rx_xcnt;
+	u64 tx_mcnt = s->tx_frames;
 	int status;
 
 	status = 0;
 	tx_xcnt = 1;		/* By default tx_xcnt is making progress */
 	tx_tcnt = mac->tx_tcnt;	/* If tx_mcnt is progressing ignore tx_tcnt */
-	rx_xcnt = 1;		/* By default rx_xcnt is making progress */
 	if (tx_mcnt == mac->tx_mcnt && mac->rx_pause == s->rx_pause) {
 		tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
 						A_XGM_TX_SPI4_SOP_EOP_CNT +
@@ -529,11 +545,11 @@ int t3b2_mac_watchdog_task(struct cmac *
 			tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
 						      A_TP_PIO_DATA)));
 		} else {
-			goto rxcheck;
+			goto out;
 		}
 	} else {
 		mac->toggle_cnt = 0;
-		goto rxcheck;
+		goto out;
 	}
 
 	if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
@@ -546,23 +562,6 @@ int t3b2_mac_watchdog_task(struct cmac *
 		}
 	} else {
 		mac->toggle_cnt = 0;
-		goto rxcheck;
-	}
-
-rxcheck:
-	if (rx_mcnt != mac->rx_mcnt) {
-		rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
-						A_XGM_RX_SPI4_SOP_EOP_CNT +
-						mac->offset))) +
-						(s->rx_fifo_ovfl -
-						 mac->rx_ocnt);
-		mac->rx_ocnt = s->rx_fifo_ovfl;
-	} else
-		goto out;
-
-	if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 &&
-	    mac->rx_xcnt == 0) {
-		status = 2;
 		goto out;
 	}
 
@@ -570,8 +569,6 @@ out:
 	mac->tx_tcnt = tx_tcnt;
 	mac->tx_xcnt = tx_xcnt;
 	mac->tx_mcnt = s->tx_frames;
-	mac->rx_xcnt = rx_xcnt;
-	mac->rx_mcnt = s->rx_frames;
 	mac->rx_pause = s->rx_pause;
 	if (status == 1) {
 		t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/declance.c linux-libre-2.6.30-gnu1/drivers/net/declance.c
--- linux-libre-2.6.29-gnu1/drivers/net/declance.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/declance.c	2009-06-09 23:05:27.000000000 -0400
@@ -1010,6 +1010,17 @@ static void lance_set_multicast_retry(un
 	lance_set_multicast(dev);
 }
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_set_multicast_list	= lance_set_multicast,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init dec_lance_probe(struct device *bdev, const int type)
 {
 	static unsigned version_printed;
@@ -1027,7 +1038,7 @@ static int __init dec_lance_probe(struct
 		printk(version);
 
 	if (bdev)
-		snprintf(name, sizeof(name), "%s", bdev->bus_id);
+		snprintf(name, sizeof(name), "%s", dev_name(bdev));
 	else {
 		i = 0;
 		dev = root_lance_dev;
@@ -1105,10 +1116,10 @@ static int __init dec_lance_probe(struct
 
 		start = to_tc_dev(bdev)->resource.start;
 		len = to_tc_dev(bdev)->resource.end - start + 1;
-		if (!request_mem_region(start, len, bdev->bus_id)) {
+		if (!request_mem_region(start, len, dev_name(bdev))) {
 			printk(KERN_ERR
 			       "%s: Unable to reserve MMIO resource\n",
-			       bdev->bus_id);
+			       dev_name(bdev));
 			ret = -EBUSY;
 			goto err_out_dev;
 		}
@@ -1223,12 +1234,8 @@ static int __init dec_lance_probe(struct
 
 	printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq);
 
-	dev->open = &lance_open;
-	dev->stop = &lance_close;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->tx_timeout = &lance_tx_timeout;
+	dev->netdev_ops = &lance_netdev_ops;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &lance_set_multicast;
 
 	/* lp->ll is the location of the registers for lance card */
 	lp->ll = ll;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/defxx.c linux-libre-2.6.30-gnu1/drivers/net/defxx.c
--- linux-libre-2.6.29-gnu1/drivers/net/defxx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/defxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -2937,7 +2937,7 @@ static int dfx_rcv_init(DFX_board_t *bp,
 	for (i = 0; i < (int)(bp->rcv_bufs_to_post); i++)
 		for (j = 0; (i + j) < (int)PI_RCV_DATA_K_NUM_ENTRIES; j += bp->rcv_bufs_to_post)
 		{
-			struct sk_buff *newskb = __dev_alloc_skb(NEW_SKB_SIZE, GFP_NOIO);
+			struct sk_buff *newskb = __netdev_alloc_skb(bp->dev, NEW_SKB_SIZE, GFP_NOIO);
 			if (!newskb)
 				return -ENOMEM;
 			bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP |
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/depca.c linux-libre-2.6.30-gnu1/drivers/net/depca.c
--- linux-libre-2.6.29-gnu1/drivers/net/depca.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/depca.c	2009-06-09 23:05:27.000000000 -0400
@@ -566,6 +566,18 @@ MODULE_LICENSE("GPL");
     outw(CSR0, DEPCA_ADDR);\
     outw(STOP, DEPCA_DATA)
 
+static const struct net_device_ops depca_netdev_ops = {
+	.ndo_open 		= depca_open,
+	.ndo_start_xmit 	= depca_start_xmit,
+	.ndo_stop 		= depca_close,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_do_ioctl 		= depca_ioctl,
+	.ndo_tx_timeout 	= depca_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init depca_hw_init (struct net_device *dev, struct device *device)
 {
 	struct depca_private *lp;
@@ -606,8 +618,8 @@ static int __init depca_hw_init (struct
 	if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
 		return -ENXIO;
 
-	printk ("%s: %s at 0x%04lx",
-	        device->bus_id, depca_signature[lp->adapter], ioaddr);
+	printk("%s: %s at 0x%04lx",
+	       dev_name(device), depca_signature[lp->adapter], ioaddr);
 
 	switch (lp->depca_bus) {
 #ifdef CONFIG_MCA
@@ -669,7 +681,7 @@ static int __init depca_hw_init (struct
 
 	spin_lock_init(&lp->lock);
 	sprintf(lp->adapter_name, "%s (%s)",
-		depca_signature[lp->adapter], device->bus_id);
+		depca_signature[lp->adapter], dev_name(device));
 	status = -EBUSY;
 
 	/* Initialisation Block */
@@ -793,12 +805,7 @@ static int __init depca_hw_init (struct
 	}
 
 	/* The DEPCA-specific entries in the device structure. */
-	dev->open = &depca_open;
-	dev->hard_start_xmit = &depca_start_xmit;
-	dev->stop = &depca_close;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->do_ioctl = &depca_ioctl;
-	dev->tx_timeout = depca_tx_timeout;
+	dev->netdev_ops = &depca_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	dev->mem_start = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/dl2k.c linux-libre-2.6.30-gnu1/drivers/net/dl2k.c
--- linux-libre-2.6.29-gnu1/drivers/net/dl2k.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/dl2k.c	2009-06-09 23:05:27.000000000 -0400
@@ -714,7 +714,7 @@ rio_interrupt (int irq, void *dev_instan
 
 static inline dma_addr_t desc_to_dma(struct netdev_desc *desc)
 {
-	return le64_to_cpu(desc->fraginfo) & DMA_48BIT_MASK;
+	return le64_to_cpu(desc->fraginfo) & DMA_BIT_MASK(48);
 }
 
 static void
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/dm9000.c linux-libre-2.6.30-gnu1/drivers/net/dm9000.c
--- linux-libre-2.6.29-gnu1/drivers/net/dm9000.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/dm9000.c	2009-06-09 23:05:27.000000000 -0400
@@ -559,7 +559,7 @@ static void dm9000_show_carrier(board_in
 static void
 dm9000_poll_work(struct work_struct *w)
 {
-	struct delayed_work *dw = container_of(w, struct delayed_work, work);
+	struct delayed_work *dw = to_delayed_work(w);
 	board_info_t *db = container_of(dw, board_info_t, phy_poll);
 	struct net_device *ndev = db->ndev;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/dnet.c linux-libre-2.6.30-gnu1/drivers/net/dnet.c
--- linux-libre-2.6.29-gnu1/drivers/net/dnet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/dnet.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/version.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -21,7 +21,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
-#include <linux/platform_device.h>
 
 #include "dnet.h"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000/e1000.h linux-libre-2.6.30-gnu1/drivers/net/e1000/e1000.h
--- linux-libre-2.6.29-gnu1/drivers/net/e1000/e1000.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000/e1000.h	2009-06-09 23:05:27.000000000 -0400
@@ -182,7 +182,6 @@ struct e1000_tx_ring {
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
 
-	spinlock_t tx_lock;
 	u16 tdh;
 	u16 tdt;
 	bool last_tx_tso;
@@ -238,7 +237,6 @@ struct e1000_adapter {
 	u16 link_speed;
 	u16 link_duplex;
 	spinlock_t stats_lock;
-	spinlock_t tx_queue_lock;
 	unsigned int total_tx_bytes;
 	unsigned int total_tx_packets;
 	unsigned int total_rx_bytes;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000/e1000_main.c linux-libre-2.6.30-gnu1/drivers/net/e1000/e1000_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000/e1000_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000/e1000_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -156,8 +156,8 @@ static void e1000_vlan_rx_add_vid(struct
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 static int e1000_resume(struct pci_dev *pdev);
 #endif
 static void e1000_shutdown(struct pci_dev *pdev);
@@ -577,12 +577,30 @@ out:
 
 void e1000_down(struct e1000_adapter *adapter)
 {
+	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
+	u32 rctl, tctl;
 
 	/* signal that we're down so the interrupt handler does not
 	 * reschedule our watchdog timer */
 	set_bit(__E1000_DOWN, &adapter->flags);
 
+	/* disable receives in the hardware */
+	rctl = er32(RCTL);
+	ew32(RCTL, rctl & ~E1000_RCTL_EN);
+	/* flush and sleep below */
+
+	/* can be netif_tx_disable when NETIF_F_LLTX is removed */
+	netif_stop_queue(netdev);
+
+	/* disable transmits in the hardware */
+	tctl = er32(TCTL);
+	tctl &= ~E1000_TCTL_EN;
+	ew32(TCTL, tctl);
+	/* flush both disables and wait for them to finish */
+	E1000_WRITE_FLUSH();
+	msleep(10);
+
 	napi_disable(&adapter->napi);
 
 	e1000_irq_disable(adapter);
@@ -595,7 +613,6 @@ void e1000_down(struct e1000_adapter *ad
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 	netif_carrier_off(netdev);
-	netif_stop_queue(netdev);
 
 	e1000_reset(adapter);
 	e1000_clean_all_tx_rings(adapter);
@@ -945,13 +962,13 @@ static int __devinit e1000_probe(struct
 	if (err)
 		return err;
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
-	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
-			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (err) {
 				E1000_ERR("No usable DMA configuration, "
 					  "aborting\n");
@@ -1048,8 +1065,6 @@ static int __devinit e1000_probe(struct
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->features |= NETIF_F_LLTX;
-
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_HW_CSUM;
@@ -1368,8 +1383,6 @@ static int __devinit e1000_sw_init(struc
 		return -ENOMEM;
 	}
 
-	spin_lock_init(&adapter->tx_queue_lock);
-
 	/* Explicitly disable IRQ since the NIC can be in any state. */
 	e1000_irq_disable(adapter);
 
@@ -1624,7 +1637,6 @@ setup_tx_desc_die:
 
 	txdr->next_to_use = 0;
 	txdr->next_to_clean = 0;
-	spin_lock_init(&txdr->tx_lock);
 
 	return 0;
 }
@@ -1882,8 +1894,6 @@ int e1000_setup_all_rx_resources(struct
  * e1000_setup_rctl - configure the receive control registers
  * @adapter: Board private structure
  **/
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
-			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
 static void e1000_setup_rctl(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
@@ -2056,17 +2066,14 @@ void e1000_free_all_tx_resources(struct
 static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
 					     struct e1000_buffer *buffer_info)
 {
-	if (buffer_info->dma) {
-		pci_unmap_page(adapter->pdev,
-				buffer_info->dma,
-				buffer_info->length,
-				PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
-	}
+	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 */
 }
 
@@ -2328,6 +2335,12 @@ static void e1000_set_rx_mode(struct net
 	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
 				E1000_NUM_MTA_REGISTERS_ICH8LAN :
 				E1000_NUM_MTA_REGISTERS;
+	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
+
+	if (!mcarray) {
+		DPRINTK(PROBE, ERR, "memory allocation failed\n");
+		return;
+	}
 
 	if (hw->mac_type == e1000_ich8lan)
 		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
@@ -2394,22 +2407,34 @@ static void e1000_set_rx_mode(struct net
 	}
 	WARN_ON(uc_ptr != NULL);
 
-	/* clear the old settings from the multicast hash table */
-
-	for (i = 0; i < mta_reg_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-		E1000_WRITE_FLUSH();
-	}
-
 	/* load any remaining addresses into the hash table */
 
 	for (; mc_ptr; mc_ptr = mc_ptr->next) {
+		u32 hash_reg, hash_bit, mta;
 		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
-		e1000_mta_set(hw, hash_value);
+		hash_reg = (hash_value >> 5) & 0x7F;
+		hash_bit = hash_value & 0x1F;
+		mta = (1 << hash_bit);
+		mcarray[hash_reg] |= mta;
 	}
 
+	/* write the hash table completely, write from bottom to avoid
+	 * both stupid write combining chipsets, and flushing each write */
+	for (i = mta_reg_count - 1; i >= 0 ; i--) {
+		/*
+		 * If we are on an 82544 has an errata where writing odd
+		 * offsets overwrites the previous even offset, but writing
+		 * backwards over the range solves the issue by always
+		 * writing the odd offset first
+		 */
+		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
+	}
+	E1000_WRITE_FLUSH();
+
 	if (hw->mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
+
+	kfree(mcarray);
 }
 
 /* Need to wait a few seconds after link up to get diagnostic information from
@@ -2865,11 +2890,11 @@ static bool e1000_tx_csum(struct e1000_a
 		return false;
 
 	switch (skb->protocol) {
-	case __constant_htons(ETH_P_IP):
+	case cpu_to_be16(ETH_P_IP):
 		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 			cmd_len |= E1000_TXD_CMD_TCP;
 		break;
-	case __constant_htons(ETH_P_IPV6):
+	case cpu_to_be16(ETH_P_IPV6):
 		/* XXX not handling all IPV6 headers */
 		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
 			cmd_len |= E1000_TXD_CMD_TCP;
@@ -2915,13 +2940,21 @@ static int e1000_tx_map(struct e1000_ada
 {
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_buffer *buffer_info;
-	unsigned int len = skb->len;
-	unsigned int offset = 0, size, count = 0, i;
+	unsigned int len = skb_headlen(skb);
+	unsigned int offset, size, count = 0, i;
 	unsigned int f;
-	len -= skb->data_len;
+	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);
@@ -2956,18 +2989,18 @@ static int e1000_tx_map(struct e1000_ada
 			size -= 4;
 
 		buffer_info->length = size;
-		buffer_info->dma =
-			pci_map_single(adapter->pdev,
-				skb->data + offset,
-				size,
-				PCI_DMA_TODEVICE);
+		buffer_info->dma = map[0] + offset;
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
 
 		len -= size;
 		offset += size;
 		count++;
-		if (unlikely(++i == tx_ring->count)) i = 0;
+		if (len) {
+			i++;
+			if (unlikely(i == tx_ring->count))
+				i = 0;
+		}
 	}
 
 	for (f = 0; f < nr_frags; f++) {
@@ -2975,9 +3008,13 @@ static int e1000_tx_map(struct e1000_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		offset = 0;
 
 		while (len) {
+			i++;
+			if (unlikely(i == tx_ring->count))
+				i = 0;
+
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, max_per_txd);
 			/* Workaround for premature desc write-backs
@@ -2993,23 +3030,16 @@ static int e1000_tx_map(struct e1000_ada
 				size -= 4;
 
 			buffer_info->length = size;
-			buffer_info->dma =
-				pci_map_page(adapter->pdev,
-					frag->page,
-					offset,
-					size,
-					PCI_DMA_TODEVICE);
+			buffer_info->dma = map[f + 1] + offset;
 			buffer_info->time_stamp = jiffies;
 			buffer_info->next_to_watch = i;
 
 			len -= size;
 			offset += size;
 			count++;
-			if (unlikely(++i == tx_ring->count)) i = 0;
 		}
 	}
 
-	i = (i == 0) ? tx_ring->count - 1 : i - 1;
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
@@ -3185,7 +3215,6 @@ static int e1000_xmit_frame(struct sk_bu
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
 	unsigned int len = skb->len - skb->data_len;
-	unsigned long flags;
 	unsigned int nr_frags;
 	unsigned int mss;
 	int count = 0;
@@ -3290,22 +3319,15 @@ static int e1000_xmit_frame(struct sk_bu
 	    (hw->mac_type == e1000_82573))
 		e1000_transfer_dhcp_info(adapter, skb);
 
-	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
-		/* Collision - tell upper layer to requeue */
-		return NETDEV_TX_LOCKED;
-
 	/* need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time */
-	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
-		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
 		return NETDEV_TX_BUSY;
-	}
 
 	if (unlikely(hw->mac_type == e1000_82547)) {
 		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
-			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 			return NETDEV_TX_BUSY;
 		}
 	}
@@ -3320,7 +3342,6 @@ static int e1000_xmit_frame(struct sk_bu
 	tso = e1000_tso(adapter, tx_ring, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 		return NETDEV_TX_OK;
 	}
 
@@ -3336,16 +3357,21 @@ static int e1000_xmit_frame(struct sk_bu
 	if (likely(skb->protocol == htons(ETH_P_IP)))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
-	e1000_tx_queue(adapter, tx_ring, tx_flags,
-	               e1000_tx_map(adapter, tx_ring, skb, first,
-	                            max_per_txd, nr_frags, mss));
+	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
+	                     nr_frags, mss);
 
-	netdev->trans_start = jiffies;
+	if (count) {
+		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
 
-	/* Make sure there is space in the ring for the next send. */
-	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
 
-	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
 
@@ -3687,12 +3713,12 @@ static irqreturn_t e1000_intr_msi(int ir
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+	if (likely(napi_schedule_prep(&adapter->napi))) {
 		adapter->total_tx_bytes = 0;
 		adapter->total_tx_packets = 0;
 		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	} else
 		e1000_irq_enable(adapter);
 
@@ -3712,7 +3738,7 @@ static irqreturn_t e1000_intr(int irq, v
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl, icr = er32(ICR);
 
-	if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
+	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
 		return IRQ_NONE;  /* Not our interrupt */
 
 	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
@@ -3747,16 +3773,18 @@ static irqreturn_t e1000_intr(int irq, v
 		ew32(IMC, ~0);
 		E1000_WRITE_FLUSH();
 	}
-	if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+	if (likely(napi_schedule_prep(&adapter->napi))) {
 		adapter->total_tx_bytes = 0;
 		adapter->total_tx_packets = 0;
 		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(&adapter->napi);
-	} else
+		__napi_schedule(&adapter->napi);
+	} else {
 		/* this really should not happen! if it does it is basically a
 		 * bug, but not a hard error, so enable ints and continue */
-		e1000_irq_enable(adapter);
+		if (!test_bit(__E1000_DOWN, &adapter->flags))
+			e1000_irq_enable(adapter);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -3773,28 +3801,21 @@ static int e1000_clean(struct napi_struc
 
 	adapter = netdev_priv(poll_dev);
 
-	/* e1000_clean is called per-cpu.  This lock protects
-	 * tx_ring[0] from being cleaned by multiple cpus
-	 * simultaneously.  A failure obtaining the lock means
-	 * tx_ring[0] is currently being cleaned anyway. */
-	if (spin_trylock(&adapter->tx_queue_lock)) {
-		tx_cleaned = e1000_clean_tx_irq(adapter,
-						&adapter->tx_ring[0]);
-		spin_unlock(&adapter->tx_queue_lock);
-	}
+	tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
 
 	adapter->clean_rx(adapter, &adapter->rx_ring[0],
 	                  &work_done, budget);
 
-	if (tx_cleaned)
+	if (!tx_cleaned)
 		work_done = budget;
 
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
 		if (likely(adapter->itr_setting & 3))
 			e1000_set_itr(adapter);
-		netif_rx_complete(napi);
-		e1000_irq_enable(adapter);
+		napi_complete(napi);
+		if (!test_bit(__E1000_DOWN, &adapter->flags))
+			e1000_irq_enable(adapter);
 	}
 
 	return work_done;
@@ -3813,15 +3834,16 @@ static bool e1000_clean_tx_irq(struct e1
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
 	unsigned int count = 0;
-	bool cleaned = false;
 	unsigned int total_tx_bytes=0, total_tx_packets=0;
 
 	i = tx_ring->next_to_clean;
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-		for (cleaned = false; !cleaned; ) {
+	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+	       (count < tx_ring->count)) {
+		bool cleaned = false;
+		for ( ; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
@@ -3844,16 +3866,12 @@ static bool e1000_clean_tx_irq(struct e1
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
-		/* weight of a sort for tx, to avoid endless transmit cleanup */
-		if (count++ == E1000_TX_WEIGHT)
-			break;
 	}
 
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+	if (unlikely(count && netif_carrier_ok(netdev) &&
 		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
@@ -3869,8 +3887,8 @@ static bool e1000_clean_tx_irq(struct e1
 		/* Detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = false;
-		if (tx_ring->buffer_info[eop].dma &&
-		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
+		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)) {
 
@@ -3892,7 +3910,7 @@ static bool e1000_clean_tx_irq(struct e1
 				readl(hw->hw_addr + tx_ring->tdt),
 				tx_ring->next_to_use,
 				tx_ring->next_to_clean,
-				tx_ring->buffer_info[eop].time_stamp,
+				tx_ring->buffer_info[i].time_stamp,
 				eop,
 				jiffies,
 				eop_desc->upper.fields.status);
@@ -3903,7 +3921,7 @@ static bool e1000_clean_tx_irq(struct e1
 	adapter->total_tx_packets += total_tx_packets;
 	adapter->net_stats.tx_bytes += total_tx_bytes;
 	adapter->net_stats.tx_packets += total_tx_packets;
-	return cleaned;
+	return (count < tx_ring->count);
 }
 
 /**
@@ -4009,8 +4027,9 @@ static bool e1000_clean_rx_irq(struct e1
 		                 PCI_DMA_FROMDEVICE);
 
 		length = le16_to_cpu(rx_desc->length);
-
-		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
+		/* !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))) {
 			/* All receives must fit into a single buffer */
 			E1000_DBG("%s: Receive packet consumed multiple"
 				  " buffers\n", netdev->name);
@@ -4583,7 +4602,7 @@ int e1000_set_spd_dplx(struct e1000_adap
 	return 0;
 }
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4646,22 +4665,18 @@ static int e1000_suspend(struct pci_dev
 
 		ew32(WUC, E1000_WUC_PME_EN);
 		ew32(WUFC, wufc);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
 	} else {
 		ew32(WUC, 0);
 		ew32(WUFC, 0);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
 	e1000_release_manageability(adapter);
 
+	*enable_wake = !!wufc;
+
 	/* make sure adapter isn't asleep if manageability is enabled */
-	if (adapter->en_mng_pt) {
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	}
+	if (adapter->en_mng_pt)
+		*enable_wake = true;
 
 	if (hw->phy_type == e1000_phy_igp_3)
 		e1000_phy_powerdown_workaround(hw);
@@ -4675,12 +4690,29 @@ static int e1000_suspend(struct pci_dev
 
 	pci_disable_device(pdev);
 
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
 	return 0;
 }
 
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __e1000_shutdown(pdev, &wake);
+	if (retval)
+		return retval;
+
+	if (wake) {
+		pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
+	return 0;
+}
+
 static int e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4735,7 +4767,14 @@ static int e1000_resume(struct pci_dev *
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-	e1000_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+
+	__e1000_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, wake);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/82571.c linux-libre-2.6.30-gnu1/drivers/net/e1000e/82571.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/82571.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/82571.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,7 @@
  * 82573E Gigabit Ethernet Controller (Copper)
  * 82573L Gigabit Ethernet Controller
  * 82574L Gigabit Network Connection
+ * 82583V Gigabit Network Connection
  */
 
 #include <linux/netdevice.h>
@@ -61,6 +62,7 @@
 static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
 static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
 static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw);
 static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
 				      u16 words, u16 *data);
 static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
@@ -99,6 +101,7 @@ static s32 e1000_init_phy_params_82571(s
 		phy->type		 = e1000_phy_m88;
 		break;
 	case e1000_82574:
+	case e1000_82583:
 		phy->type		 = e1000_phy_bm;
 		break;
 	default:
@@ -121,6 +124,7 @@ static s32 e1000_init_phy_params_82571(s
 			return -E1000_ERR_PHY;
 		break;
 	case e1000_82574:
+	case e1000_82583:
 		if (phy->id != BME1000_E_PHY_ID_R2)
 			return -E1000_ERR_PHY;
 		break;
@@ -164,6 +168,7 @@ static s32 e1000_init_nvm_params_82571(s
 	switch (hw->mac.type) {
 	case e1000_82573:
 	case e1000_82574:
+	case e1000_82583:
 		if (((eecd >> 15) & 0x3) == 0x3) {
 			nvm->type = e1000_nvm_flash_hw;
 			nvm->word_size = 2048;
@@ -250,7 +255,7 @@ static s32 e1000_init_mac_params_82571(s
 	case e1000_media_type_internal_serdes:
 		func->setup_physical_interface =
 			e1000_setup_fiber_serdes_link_82571;
-		func->check_for_link = e1000e_check_for_serdes_link;
+		func->check_for_link = e1000_check_for_serdes_link_82571;
 		func->get_link_up_info =
 			e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
@@ -261,6 +266,7 @@ static s32 e1000_init_mac_params_82571(s
 
 	switch (hw->mac.type) {
 	case e1000_82574:
+	case e1000_82583:
 		func->check_mng_mode = e1000_check_mng_mode_82574;
 		func->led_on = e1000_led_on_82574;
 		break;
@@ -374,6 +380,7 @@ static s32 e1000_get_phy_id_82571(struct
 		return e1000e_get_phy_id(hw);
 		break;
 	case e1000_82574:
+	case e1000_82583:
 		ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
 		if (ret_val)
 			return ret_val;
@@ -463,8 +470,15 @@ static s32 e1000_acquire_nvm_82571(struc
 	if (ret_val)
 		return ret_val;
 
-	if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
+		break;
+	default:
 		ret_val = e1000e_acquire_nvm(hw);
+		break;
+	}
 
 	if (ret_val)
 		e1000_put_hw_semaphore_82571(hw);
@@ -504,6 +518,7 @@ static s32 e1000_write_nvm_82571(struct
 	switch (hw->mac.type) {
 	case e1000_82573:
 	case e1000_82574:
+	case e1000_82583:
 		ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
 		break;
 	case e1000_82571:
@@ -778,7 +793,10 @@ static s32 e1000_reset_hw_82571(struct e
 	 * Must acquire the MDIO ownership before MAC reset.
 	 * Ownership defaults to firmware after a reset.
 	 */
-	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
 		extcnf_ctrl = er32(EXTCNF_CTRL);
 		extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
 
@@ -794,6 +812,9 @@ static s32 e1000_reset_hw_82571(struct e
 			msleep(2);
 			i++;
 		} while (i < MDIO_OWNERSHIP_TIMEOUT);
+		break;
+	default:
+		break;
 	}
 
 	ctrl = er32(CTRL);
@@ -819,8 +840,16 @@ static s32 e1000_reset_hw_82571(struct e
 	 * Need to wait for Phy configuration completion before accessing
 	 * NVM and Phy.
 	 */
-	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
+
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
 		msleep(25);
+		break;
+	default:
+		break;
+	}
 
 	/* Clear any pending interrupt events. */
 	ew32(IMC, 0xffffffff);
@@ -830,6 +859,10 @@ static s32 e1000_reset_hw_82571(struct e
 		hw->dev_spec.e82571.alt_mac_addr_is_present)
 			e1000e_set_laa_state_82571(hw, true);
 
+	/* Reinitialize the 82571 serdes link state machine */
+	if (hw->phy.media_type == e1000_media_type_internal_serdes)
+		hw->mac.serdes_link_state = e1000_serdes_link_down;
+
 	return 0;
 }
 
@@ -886,17 +919,22 @@ static s32 e1000_init_hw_82571(struct e1
 	ew32(TXDCTL(0), reg_data);
 
 	/* ...for both queues. */
-	if (mac->type != e1000_82573 && mac->type != e1000_82574) {
+	switch (mac->type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
+		e1000e_enable_tx_pkt_filtering(hw);
+		reg_data = er32(GCR);
+		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+		ew32(GCR, reg_data);
+		break;
+	default:
 		reg_data = er32(TXDCTL(1));
 		reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
 			   E1000_TXDCTL_FULL_TX_DESC_WB |
 			   E1000_TXDCTL_COUNT_DESC;
 		ew32(TXDCTL(1), reg_data);
-	} else {
-		e1000e_enable_tx_pkt_filtering(hw);
-		reg_data = er32(GCR);
-		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
-		ew32(GCR, reg_data);
+		break;
 	}
 
 	/*
@@ -961,18 +999,30 @@ static void e1000_initialize_hw_bits_825
 	}
 
 	/* Device Control */
-	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
 		reg = er32(CTRL);
 		reg &= ~(1 << 29);
 		ew32(CTRL, reg);
+		break;
+	default:
+		break;
 	}
 
 	/* Extended Device Control */
-	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
 		reg = er32(CTRL_EXT);
 		reg &= ~(1 << 23);
 		reg |= (1 << 22);
 		ew32(CTRL_EXT, reg);
+		break;
+	default:
+		break;
 	}
 
 	if (hw->mac.type == e1000_82571) {
@@ -980,9 +1030,23 @@ static void e1000_initialize_hw_bits_825
 		reg |= E1000_PBA_ECC_CORR_EN;
 		ew32(PBA_ECC, reg);
 	}
+	/*
+	 * Workaround for hardware errata.
+	 * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
+	 */
+
+        if ((hw->mac.type == e1000_82571) ||
+           (hw->mac.type == e1000_82572)) {
+                reg = er32(CTRL_EXT);
+                reg &= ~E1000_CTRL_EXT_DMA_DYN_CLK_EN;
+                ew32(CTRL_EXT, reg);
+        }
+
 
 	/* PCI-Ex Control Registers */
-	if (hw->mac.type == e1000_82574) {
+	switch (hw->mac.type) {
+	case e1000_82574:
+	case e1000_82583:
 		reg = er32(GCR);
 		reg |= (1 << 22);
 		ew32(GCR, reg);
@@ -990,6 +1054,9 @@ static void e1000_initialize_hw_bits_825
 		reg = er32(GCR2);
 		reg |= 1;
 		ew32(GCR2, reg);
+		break;
+	default:
+		break;
 	}
 
 	return;
@@ -1009,7 +1076,10 @@ void e1000e_clear_vfta(struct e1000_hw *
 	u32 vfta_offset = 0;
 	u32 vfta_bit_in_reg = 0;
 
-	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
 		if (hw->mng_cookie.vlan_id != 0) {
 			/*
 			 * The VFTA is a 4096b bit-field, each identifying
@@ -1024,6 +1094,9 @@ void e1000e_clear_vfta(struct e1000_hw *
 			vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
 					       E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
 		}
+		break;
+	default:
+		break;
 	}
 	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
 		/*
@@ -1122,9 +1195,16 @@ static s32 e1000_setup_link_82571(struct
 	 * the default flow control setting, so we explicitly
 	 * set it to full.
 	 */
-	if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
-	    hw->fc.requested_mode == e1000_fc_default)
-		hw->fc.requested_mode = e1000_fc_full;
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
+		if (hw->fc.requested_mode == e1000_fc_default)
+			hw->fc.requested_mode = e1000_fc_full;
+		break;
+	default:
+		break;
+	}
 
 	return e1000e_setup_link(hw);
 }
@@ -1203,6 +1283,131 @@ 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.
+ **/
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	u32 rxcw;
+	u32 ctrl;
+	u32 status;
+	s32 ret_val = 0;
+
+	ctrl = er32(CTRL);
+	status = er32(STATUS);
+	rxcw = er32(RXCW);
+
+	if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
+
+		/* Receiver is synchronized with no invalid bits.  */
+		switch (mac->serdes_link_state) {
+		case e1000_serdes_link_autoneg_complete:
+			if (!(status & E1000_STATUS_LU)) {
+				/*
+				 * We have lost link, retry autoneg before
+				 * reporting link failure
+				 */
+				mac->serdes_link_state =
+				    e1000_serdes_link_autoneg_progress;
+				hw_dbg(hw, "AN_UP     -> AN_PROG\n");
+			}
+		break;
+
+		case e1000_serdes_link_forced_up:
+			/*
+			 * If we are receiving /C/ ordered sets, re-enable
+			 * auto-negotiation in the TXCW register and disable
+			 * forced link in the Device Control register in an
+			 * attempt to auto-negotiate with our link partner.
+			 */
+			if (rxcw & E1000_RXCW_C) {
+				/* Enable autoneg, and unforce link up */
+				ew32(TXCW, mac->txcw);
+				ew32(CTRL,
+				    (ctrl & ~E1000_CTRL_SLU));
+				mac->serdes_link_state =
+				    e1000_serdes_link_autoneg_progress;
+				hw_dbg(hw, "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");
+			} else {
+				/*
+				 * Disable autoneg, force link up and
+				 * full duplex, and change state to forced
+				 */
+				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);
+				if (ret_val) {
+					hw_dbg(hw, "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;
+			break;
+
+		case e1000_serdes_link_down:
+		default:
+			/* The link was down but the receiver has now gained
+			 * valid sync, so lets see if we can bring the link
+			 * up. */
+			ew32(TXCW, mac->txcw);
+			ew32(CTRL,
+			    (ctrl & ~E1000_CTRL_SLU));
+			mac->serdes_link_state =
+			    e1000_serdes_link_autoneg_progress;
+			hw_dbg(hw, "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");
+		} else {
+			/*
+			 * 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");
+			}
+		}
+	}
+
+	return ret_val;
+}
+
+/**
  *  e1000_valid_led_default_82571 - Verify a valid default LED config
  *  @hw: pointer to the HW structure
  *  @data: pointer to the NVM (EEPROM)
@@ -1220,11 +1425,19 @@ static s32 e1000_valid_led_default_82571
 		return ret_val;
 	}
 
-	if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
-	    *data == ID_LED_RESERVED_F746)
-		*data = ID_LED_DEFAULT_82573;
-	else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
-		*data = ID_LED_DEFAULT;
+	switch (hw->mac.type) {
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_82583:
+		if (*data == ID_LED_RESERVED_F746)
+			*data = ID_LED_DEFAULT_82573;
+		break;
+	default:
+		if (*data == ID_LED_RESERVED_0000 ||
+		    *data == ID_LED_RESERVED_FFFF)
+			*data = ID_LED_DEFAULT;
+		break;
+	}
 
 	return 0;
 }
@@ -1507,6 +1720,22 @@ struct e1000_info e1000_82574_info = {
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
+				  | FLAG_HAS_SMART_POWER_DOWN
+				  | FLAG_HAS_AMT
+				  | FLAG_HAS_CTRLEXT_ON_LOAD,
+	.pba			= 20,
+	.get_variants		= e1000_get_variants_82571,
+	.mac_ops		= &e82571_mac_ops,
+	.phy_ops		= &e82_phy_ops_bm,
+	.nvm_ops		= &e82571_nvm_ops,
+};
+
+struct e1000_info e1000_82583_info = {
+	.mac			= e1000_82583,
+	.flags			= FLAG_HAS_HW_VLAN_FILTER
+				  | FLAG_HAS_WOL
+				  | FLAG_APME_IN_CTRL3
+				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/defines.h linux-libre-2.6.30-gnu1/drivers/net/e1000e/defines.h
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/defines.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/defines.h	2009-06-09 23:05:27.000000000 -0400
@@ -69,6 +69,7 @@
 #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
 #define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
 #define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */
+#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
 #define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES  0x00C00000
 #define E1000_CTRL_EXT_EIAME          0x01000000
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/e1000.h linux-libre-2.6.30-gnu1/drivers/net/e1000e/e1000.h
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/e1000.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/e1000.h	2009-06-09 23:05:27.000000000 -0400
@@ -101,6 +101,7 @@ enum e1000_boards {
 	board_82572,
 	board_82573,
 	board_82574,
+	board_82583,
 	board_80003es2lan,
 	board_ich8lan,
 	board_ich9lan,
@@ -195,8 +196,6 @@ struct e1000_adapter {
 	u16 link_duplex;
 	u16 eeprom_vers;
 
-	spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
-
 	/* track device up/down/testing state */
 	unsigned long state;
 
@@ -401,6 +400,7 @@ extern struct e1000_info e1000_82571_inf
 extern struct e1000_info e1000_82572_info;
 extern struct e1000_info e1000_82573_info;
 extern struct e1000_info e1000_82574_info;
+extern struct e1000_info e1000_82583_info;
 extern struct e1000_info e1000_ich8_info;
 extern struct e1000_info e1000_ich9_info;
 extern struct e1000_info e1000_ich10_info;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/ethtool.c linux-libre-2.6.30-gnu1/drivers/net/e1000e/ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -790,6 +790,7 @@ static int e1000_reg_test(struct e1000_a
 		break;
 	case e1000_82573:
 	case e1000_82574:
+	case e1000_82583:
 	case e1000_ich8lan:
 	case e1000_ich9lan:
 	case e1000_ich10lan:
@@ -1589,7 +1590,7 @@ static int e1000_link_test(struct e1000_
 	*data = 0;
 	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
-		hw->mac.serdes_has_link = 0;
+		hw->mac.serdes_has_link = false;
 
 		/*
 		 * On some blade server designs, link establishment
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/hw.h linux-libre-2.6.30-gnu1/drivers/net/e1000e/hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -339,6 +339,8 @@ enum e1e_registers {
 #define E1000_DEV_ID_82573E_IAMT		0x108C
 #define E1000_DEV_ID_82573L			0x109A
 #define E1000_DEV_ID_82574L			0x10D3
+#define E1000_DEV_ID_82574LA			0x10F6
+#define E1000_DEV_ID_82583V                     0x150C
 
 #define E1000_DEV_ID_80003ES2LAN_COPPER_DPT	0x1096
 #define E1000_DEV_ID_80003ES2LAN_SERDES_DPT	0x1098
@@ -376,6 +378,7 @@ enum e1000_mac_type {
 	e1000_82572,
 	e1000_82573,
 	e1000_82574,
+	e1000_82583,
 	e1000_80003es2lan,
 	e1000_ich8lan,
 	e1000_ich9lan,
@@ -459,6 +462,13 @@ enum e1000_smart_speed {
 	e1000_smart_speed_off
 };
 
+enum e1000_serdes_link_state {
+	e1000_serdes_link_down = 0,
+	e1000_serdes_link_autoneg_progress,
+	e1000_serdes_link_autoneg_complete,
+	e1000_serdes_link_forced_up
+};
+
 /* Receive Descriptor */
 struct e1000_rx_desc {
 	__le64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -787,6 +797,7 @@ struct e1000_mac_info {
 	bool in_ifs_mode;
 	bool serdes_has_link;
 	bool tx_pkt_filtering;
+	enum e1000_serdes_link_state serdes_link_state;
 };
 
 struct e1000_phy_info {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/ich8lan.c linux-libre-2.6.30-gnu1/drivers/net/e1000e/ich8lan.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/ich8lan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/ich8lan.c	2009-06-09 23:05:27.000000000 -0400
@@ -390,8 +390,6 @@ static s32 e1000_get_variants_ich8lan(st
 }
 
 static DEFINE_MUTEX(nvm_mutex);
-static pid_t nvm_owner_pid = -1;
-static char nvm_owner_name[TASK_COMM_LEN] = "";
 
 /**
  *  e1000_acquire_swflag_ich8lan - Acquire software control flag
@@ -408,16 +406,7 @@ static s32 e1000_acquire_swflag_ich8lan(
 
 	might_sleep();
 
-	if (!mutex_trylock(&nvm_mutex)) {
-		WARN(1, KERN_ERR "e1000e mutex contention. Owned by process "
-		     "%s (pid %d), required by process %s (pid %d)\n",
-		     nvm_owner_name, nvm_owner_pid,
-		     current->comm, current->pid);
-
-		mutex_lock(&nvm_mutex);
-	}
-	nvm_owner_pid = current->pid;
-	strncpy(nvm_owner_name, current->comm, TASK_COMM_LEN);
+	mutex_lock(&nvm_mutex);
 
 	while (timeout) {
 		extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -435,8 +424,6 @@ static s32 e1000_acquire_swflag_ich8lan(
 		hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
 		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
 		ew32(EXTCNF_CTRL, extcnf_ctrl);
-		nvm_owner_pid = -1;
-		strcpy(nvm_owner_name, "");
 		mutex_unlock(&nvm_mutex);
 		return -E1000_ERR_CONFIG;
 	}
@@ -460,8 +447,6 @@ static void e1000_release_swflag_ich8lan
 	extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
 	ew32(EXTCNF_CTRL, extcnf_ctrl);
 
-	nvm_owner_pid = -1;
-	strcpy(nvm_owner_name, "");
 	mutex_unlock(&nvm_mutex);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/lib.c linux-libre-2.6.30-gnu1/drivers/net/e1000e/lib.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/lib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/lib.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,41 +159,6 @@ void e1000e_rar_set(struct e1000_hw *hw,
 }
 
 /**
- *  e1000_mta_set - Set multicast filter table address
- *  @hw: pointer to the HW structure
- *  @hash_value: determines the MTA register and bit to set
- *
- *  The multicast table address is a register array of 32-bit registers.
- *  The hash_value is used to determine what register the bit is in, the
- *  current value is read, the new bit is OR'd in and the new value is
- *  written back into the register.
- **/
-static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
-	u32 hash_bit, hash_reg, mta;
-
-	/*
-	 * The MTA is a register array of 32-bit registers. It is
-	 * treated like an array of (32*mta_reg_count) bits.  We want to
-	 * set bit BitArray[hash_value]. So we figure out what register
-	 * the bit is in, read it, OR in the new bit, then write
-	 * back the new value.  The (hw->mac.mta_reg_count - 1) serves as a
-	 * mask to bits 31:5 of the hash value which gives us the
-	 * register we're modifying.  The hash bit within that register
-	 * is determined by the lower 5 bits of the hash value.
-	 */
-	hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
-	hash_bit = hash_value & 0x1F;
-
-	mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
-
-	mta |= (1 << hash_bit);
-
-	E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
-	e1e_flush();
-}
-
-/**
  *  e1000_hash_mc_addr - Generate a multicast hash value
  *  @hw: pointer to the HW structure
  *  @mc_addr: pointer to a multicast address
@@ -281,8 +246,13 @@ void e1000e_update_mc_addr_list_generic(
 					u8 *mc_addr_list, u32 mc_addr_count,
 					u32 rar_used_count, u32 rar_count)
 {
-	u32 hash_value;
 	u32 i;
+	u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
+
+	if (!mcarray) {
+		printk(KERN_ERR "multicast array memory allocation failed\n");
+		return;
+	}
 
 	/*
 	 * Load the first set of multicast addresses into the exact
@@ -302,20 +272,24 @@ void e1000e_update_mc_addr_list_generic(
 		}
 	}
 
-	/* Clear the old settings from the MTA */
-	hw_dbg(hw, "Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-		e1e_flush();
-	}
-
 	/* Load any remaining multicast addresses into the hash table. */
 	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);
-		e1000_mta_set(hw, hash_value);
+		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+		hash_bit = hash_value & 0x1F;
+		mta = (1 << hash_bit);
+		mcarray[hash_reg] |= mta;
 		mc_addr_list += ETH_ALEN;
 	}
+
+	/* write the hash table completely */
+	for (i = 0; i < hw->mac.mta_reg_count; i++)
+		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
+
+	e1e_flush();
+	kfree(mcarray);
 }
 
 /**
@@ -501,7 +475,7 @@ s32 e1000e_check_for_fiber_link(struct e
 		ew32(TXCW, mac->txcw);
 		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
-		mac->serdes_has_link = 1;
+		mac->serdes_has_link = true;
 	}
 
 	return 0;
@@ -566,7 +540,7 @@ s32 e1000e_check_for_serdes_link(struct
 		ew32(TXCW, mac->txcw);
 		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
-		mac->serdes_has_link = 1;
+		mac->serdes_has_link = true;
 	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
 		/*
 		 * If we force link for non-auto-negotiation switch, check
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e1000e/netdev.c linux-libre-2.6.30-gnu1/drivers/net/e1000e/netdev.c
--- linux-libre-2.6.29-gnu1/drivers/net/e1000e/netdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e1000e/netdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,10 +44,11 @@
 #include <linux/cpu.h>
 #include <linux/smp.h>
 #include <linux/pm_qos_params.h>
+#include <linux/aer.h>
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.3.3.3-k6"
+#define DRV_VERSION "0.3.3.4-k4"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -56,6 +57,7 @@ static const struct e1000_info *e1000_in
 	[board_82572]		= &e1000_82572_info,
 	[board_82573]		= &e1000_82573_info,
 	[board_82574]		= &e1000_82574_info,
+	[board_82583]		= &e1000_82583_info,
 	[board_80003es2lan]	= &e1000_es2_info,
 	[board_ich8lan]		= &e1000_ich8_info,
 	[board_ich9lan]		= &e1000_ich9_info,
@@ -99,8 +101,8 @@ static void e1000_receive_skb(struct e10
 	skb->protocol = eth_type_trans(skb, netdev);
 
 	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
-		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-					 le16_to_cpu(vlan));
+		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
+				 le16_to_cpu(vlan), skb);
 	else
 		napi_gro_receive(&adapter->napi, skb);
 }
@@ -565,15 +567,14 @@ next_desc:
 static void e1000_put_txbuf(struct e1000_adapter *adapter,
 			     struct e1000_buffer *buffer_info)
 {
-	if (buffer_info->dma) {
-		pci_unmap_page(adapter->pdev, buffer_info->dma,
-			       buffer_info->length, PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
-	}
+	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)
@@ -620,15 +621,16 @@ static bool e1000_clean_tx_irq(struct e1
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
 	unsigned int count = 0;
-	bool cleaned = 0;
 	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 
 	i = tx_ring->next_to_clean;
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-		for (cleaned = 0; !cleaned; ) {
+	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+	       (count < tx_ring->count)) {
+		bool cleaned = false;
+		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
@@ -654,17 +656,13 @@ static bool e1000_clean_tx_irq(struct e1
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
-		/* weight of a sort for tx, to avoid endless transmit cleanup */
-		if (count++ == E1000_TX_WEIGHT)
-			break;
 	}
 
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD 32
-	if (cleaned && netif_carrier_ok(netdev) &&
-		     e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+	if (count && netif_carrier_ok(netdev) &&
+	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
 		 */
@@ -678,13 +676,11 @@ 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[eop].dma &&
-		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
+		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);
@@ -695,7 +691,7 @@ static bool e1000_clean_tx_irq(struct e1
 	adapter->total_tx_packets += total_tx_packets;
 	adapter->net_stats.tx_bytes += total_tx_bytes;
 	adapter->net_stats.tx_packets += total_tx_packets;
-	return cleaned;
+	return (count < tx_ring->count);
 }
 
 /**
@@ -1152,7 +1148,7 @@ static irqreturn_t e1000_intr_msi(int ir
 	 * read ICR disables interrupts using IAM
 	 */
 
-	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+	if (icr & E1000_ICR_LSC) {
 		hw->mac.get_link_status = 1;
 		/*
 		 * ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1179,12 +1175,12 @@ static irqreturn_t e1000_intr_msi(int ir
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	if (netif_rx_schedule_prep(&adapter->napi)) {
+	if (napi_schedule_prep(&adapter->napi)) {
 		adapter->total_tx_bytes = 0;
 		adapter->total_tx_packets = 0;
 		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	}
 
 	return IRQ_HANDLED;
@@ -1218,7 +1214,7 @@ static irqreturn_t e1000_intr(int irq, v
 	 * IMC write
 	 */
 
-	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+	if (icr & E1000_ICR_LSC) {
 		hw->mac.get_link_status = 1;
 		/*
 		 * ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1246,12 +1242,12 @@ static irqreturn_t e1000_intr(int irq, v
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	if (netif_rx_schedule_prep(&adapter->napi)) {
+	if (napi_schedule_prep(&adapter->napi)) {
 		adapter->total_tx_bytes = 0;
 		adapter->total_tx_packets = 0;
 		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	}
 
 	return IRQ_HANDLED;
@@ -1265,7 +1261,8 @@ static irqreturn_t e1000_msix_other(int
 	u32 icr = er32(ICR);
 
 	if (!(icr & E1000_ICR_INT_ASSERTED)) {
-		ew32(IMS, E1000_IMS_OTHER);
+		if (!test_bit(__E1000_DOWN, &adapter->state))
+			ew32(IMS, E1000_IMS_OTHER);
 		return IRQ_NONE;
 	}
 
@@ -1282,7 +1279,8 @@ static irqreturn_t e1000_msix_other(int
 	}
 
 no_link_interrupt:
-	ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
+	if (!test_bit(__E1000_DOWN, &adapter->state))
+		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
 
 	return IRQ_HANDLED;
 }
@@ -1320,10 +1318,10 @@ static irqreturn_t e1000_intr_msix_rx(in
 		adapter->rx_ring->set_itr = 0;
 	}
 
-	if (netif_rx_schedule_prep(&adapter->napi)) {
+	if (napi_schedule_prep(&adapter->napi)) {
 		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	}
 	return IRQ_HANDLED;
 }
@@ -1698,7 +1696,6 @@ int e1000e_setup_tx_resources(struct e10
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
-	spin_lock_init(&adapter->tx_queue_lock);
 
 	return 0;
 err:
@@ -2007,32 +2004,25 @@ static int e1000_clean(struct napi_struc
 	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
 		goto clean_rx;
 
-	/*
-	 * e1000_clean is called per-cpu.  This lock protects
-	 * tx_ring from being cleaned by multiple cpus
-	 * simultaneously.  A failure obtaining the lock means
-	 * tx_ring is currently being cleaned anyway.
-	 */
-	if (spin_trylock(&adapter->tx_queue_lock)) {
-		tx_cleaned = e1000_clean_tx_irq(adapter);
-		spin_unlock(&adapter->tx_queue_lock);
-	}
+	tx_cleaned = e1000_clean_tx_irq(adapter);
 
 clean_rx:
 	adapter->clean_rx(adapter, &work_done, budget);
 
-	if (tx_cleaned)
+	if (!tx_cleaned)
 		work_done = budget;
 
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
 		if (adapter->itr_setting & 3)
 			e1000_set_itr(adapter);
-		netif_rx_complete(napi);
-		if (adapter->msix_entries)
-			ew32(IMS, adapter->rx_ring->ims_val);
-		else
-			e1000_irq_enable(adapter);
+		napi_complete(napi);
+		if (!test_bit(__E1000_DOWN, &adapter->state)) {
+			if (adapter->msix_entries)
+				ew32(IMS, adapter->rx_ring->ims_val);
+			else
+				e1000_irq_enable(adapter);
+		}
 	}
 
 	return work_done;
@@ -2213,7 +2203,7 @@ static void e1000_configure_tx(struct e1
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 	tdba = tx_ring->dma;
 	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
-	ew32(TDBAL, (tdba & DMA_32BIT_MASK));
+	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
 	ew32(TDBAH, (tdba >> 32));
 	ew32(TDLEN, tdlen);
 	ew32(TDH, 0);
@@ -2469,7 +2459,7 @@ static void e1000_configure_rx(struct e1
 	 * the Base and Length of the Rx Descriptor Ring
 	 */
 	rdba = rx_ring->dma;
-	ew32(RDBAL, (rdba & DMA_32BIT_MASK));
+	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
 	ew32(RDBAH, (rdba >> 32));
 	ew32(RDLEN, rdlen);
 	ew32(RDH, 0);
@@ -2922,8 +2912,6 @@ static int __devinit e1000_sw_init(struc
 	if (e1000_alloc_queues(adapter))
 		return -ENOMEM;
 
-	spin_lock_init(&adapter->tx_queue_lock);
-
 	/* Explicitly disable IRQ since the NIC can be in any state. */
 	e1000_irq_disable(adapter);
 
@@ -3320,7 +3308,7 @@ void e1000e_update_stats(struct e1000_ad
 
 	adapter->stats.algnerrc += er32(ALGNERRC);
 	adapter->stats.rxerrc += er32(RXERRC);
-	if (hw->mac.type != e1000_82574)
+	if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
 		adapter->stats.tncrs += er32(TNCRS);
 	adapter->stats.cexterr += er32(CEXTERR);
 	adapter->stats.tsctc += er32(TSCTC);
@@ -3777,23 +3765,30 @@ static bool e1000_tx_csum(struct e1000_a
 	unsigned int i;
 	u8 css;
 	u32 cmd_len = E1000_TXD_CMD_DEXT;
+	__be16 protocol;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
 		return 0;
 
-	switch (skb->protocol) {
-	case __constant_htons(ETH_P_IP):
+	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	else
+		protocol = skb->protocol;
+
+	switch (protocol) {
+	case cpu_to_be16(ETH_P_IP):
 		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 			cmd_len |= E1000_TXD_CMD_TCP;
 		break;
-	case __constant_htons(ETH_P_IPV6):
+	case cpu_to_be16(ETH_P_IPV6):
 		/* XXX not handling all IPV6 headers */
 		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
 			cmd_len |= E1000_TXD_CMD_TCP;
 		break;
 	default:
 		if (unlikely(net_ratelimit()))
-			e_warn("checksum_partial proto=%x!\n", skb->protocol);
+			e_warn("checksum_partial proto=%x!\n",
+			       be16_to_cpu(protocol));
 		break;
 	}
 
@@ -3832,42 +3827,40 @@ static int e1000_tx_map(struct e1000_ada
 {
 	struct e1000_ring *tx_ring = adapter->tx_ring;
 	struct e1000_buffer *buffer_info;
-	unsigned int len = skb->len - skb->data_len;
-	unsigned int offset = 0, size, count = 0, i;
+	unsigned int len = skb_headlen(skb);
+	unsigned int offset, 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);
 
-		/* Workaround for premature desc write-backs
-		 * in TSO mode.  Append 4-byte sentinel desc */
-		if (mss && !nr_frags && size == len && size > 8)
-			size -= 4;
-
 		buffer_info->length = size;
-		/* set time_stamp *before* dma to help avoid a possible race */
 		buffer_info->time_stamp = jiffies;
-		buffer_info->dma =
-			pci_map_single(adapter->pdev,
-				skb->data + offset,
-				size,
-				PCI_DMA_TODEVICE);
-		if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) {
-			dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-			adapter->tx_dma_failed++;
-			return -1;
-		}
 		buffer_info->next_to_watch = i;
+		buffer_info->dma = map[0] + offset;
+		count++;
 
 		len -= size;
 		offset += size;
-		count++;
-		i++;
-		if (i == tx_ring->count)
-			i = 0;
+
+		if (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
 	}
 
 	for (f = 0; f < nr_frags; f++) {
@@ -3875,49 +3868,27 @@ static int e1000_tx_map(struct e1000_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		offset = 0;
 
 		while (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, max_per_txd);
-			/* Workaround for premature desc write-backs
-			 * in TSO mode.  Append 4-byte sentinel desc */
-			if (mss && f == (nr_frags-1) && size == len && size > 8)
-				size -= 4;
 
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
-			buffer_info->dma =
-				pci_map_page(adapter->pdev,
-					frag->page,
-					offset,
-					size,
-					PCI_DMA_TODEVICE);
-			if (pci_dma_mapping_error(adapter->pdev,
-						  buffer_info->dma)) {
-				dev_err(&adapter->pdev->dev,
-					"TX DMA page map failed\n");
-				adapter->tx_dma_failed++;
-				return -1;
-			}
-
 			buffer_info->next_to_watch = i;
+			buffer_info->dma = map[f + 1] + offset;
 
 			len -= size;
 			offset += size;
 			count++;
-
-			i++;
-			if (i == tx_ring->count)
-				i = 0;
 		}
 	}
 
-	if (i == 0)
-		i = tx_ring->count - 1;
-	else
-		i--;
-
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
@@ -4069,7 +4040,6 @@ static int e1000_xmit_frame(struct sk_bu
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
 	unsigned int len = skb->len - skb->data_len;
-	unsigned long irq_flags;
 	unsigned int nr_frags;
 	unsigned int mss;
 	int count = 0;
@@ -4138,18 +4108,12 @@ static int e1000_xmit_frame(struct sk_bu
 	if (adapter->hw.mac.tx_pkt_filtering)
 		e1000_transfer_dhcp_info(adapter, skb);
 
-	if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags))
-		/* Collision - tell upper layer to requeue */
-		return NETDEV_TX_LOCKED;
-
 	/*
 	 * need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time
 	 */
-	if (e1000_maybe_stop_tx(netdev, count + 2)) {
-		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
+	if (e1000_maybe_stop_tx(netdev, count + 2))
 		return NETDEV_TX_BUSY;
-	}
 
 	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
@@ -4161,7 +4125,6 @@ static int e1000_xmit_frame(struct sk_bu
 	tso = e1000_tso(adapter, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
 		return NETDEV_TX_OK;
 	}
 
@@ -4178,22 +4141,20 @@ static int e1000_xmit_frame(struct sk_bu
 	if (skb->protocol == htons(ETH_P_IP))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
+	/* if count is 0 then mapping error has occured */
 	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
-	if (count < 0) {
-		/* handle pci_map_single() error in e1000_tx_map */
+	if (count) {
+		e1000_tx_queue(adapter, tx_flags, count);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
+
+	} else {
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
-		return NETDEV_TX_OK;
+		tx_ring->buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
 	}
 
-	e1000_tx_queue(adapter, tx_flags, count);
-
-	netdev->trans_start = jiffies;
-
-	/* Make sure there is space in the ring for the next send. */
-	e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
-
-	spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
 	return NETDEV_TX_OK;
 }
 
@@ -4385,7 +4346,7 @@ static int e1000_ioctl(struct net_device
 	}
 }
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4448,20 +4409,16 @@ static int e1000_suspend(struct pci_dev
 
 		ew32(WUC, E1000_WUC_PME_EN);
 		ew32(WUFC, wufc);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
 	} else {
 		ew32(WUC, 0);
 		ew32(WUFC, 0);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
 	}
 
+	*enable_wake = !!wufc;
+
 	/* make sure adapter isn't asleep if manageability is enabled */
-	if (adapter->flags & FLAG_MNG_PT_ENABLED) {
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	}
+	if (adapter->flags & FLAG_MNG_PT_ENABLED)
+		*enable_wake = true;
 
 	if (adapter->hw.phy.type == e1000_phy_igp_3)
 		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
@@ -4474,6 +4431,26 @@ static int e1000_suspend(struct pci_dev
 
 	pci_disable_device(pdev);
 
+	return 0;
+}
+
+static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
+{
+	if (sleep && wake) {
+		pci_prepare_to_sleep(pdev);
+		return;
+	}
+
+	pci_wake_from_d3(pdev, wake);
+	pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
+                                    bool wake)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+
 	/*
 	 * The pci-e switch on some quad port adapters will report a
 	 * correctable error when the MAC transitions from D0 to D3.  To
@@ -4489,14 +4466,12 @@ static int e1000_suspend(struct pci_dev
 		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
 		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
 
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		e1000_power_off(pdev, sleep, wake);
 
 		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
 	} else {
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		e1000_power_off(pdev, sleep, wake);
 	}
-
-	return 0;
 }
 
 static void e1000e_disable_l1aspm(struct pci_dev *pdev)
@@ -4525,6 +4500,18 @@ static void e1000e_disable_l1aspm(struct
 }
 
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __e1000_shutdown(pdev, &wake);
+	if (!retval)
+		e1000_complete_shutdown(pdev, true, wake);
+
+	return retval;
+}
+
 static int e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4543,6 +4530,14 @@ static int e1000_resume(struct pci_dev *
 		return err;
 	}
 
+	/* AER (Advanced Error Reporting) hooks */
+	err = pci_enable_pcie_error_reporting(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+		                    "0x%x\n", err);
+		/* non-fatal, continue */
+	}
+
 	pci_set_master(pdev);
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -4580,7 +4575,12 @@ static int e1000_resume(struct pci_dev *
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-	e1000_suspend(pdev, PMSG_SUSPEND);
+	bool wake = false;
+
+	__e1000_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF)
+		e1000_complete_shutdown(pdev, false, wake);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4637,24 +4637,29 @@ static pci_ers_result_t e1000_io_slot_re
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	int err;
+	pci_ers_result_t result;
 
 	e1000e_disable_l1aspm(pdev);
 	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
 			"Cannot re-enable PCI device after reset.\n");
-		return PCI_ERS_RESULT_DISCONNECT;
-	}
-	pci_set_master(pdev);
-	pci_restore_state(pdev);
+		result = PCI_ERS_RESULT_DISCONNECT;
+	} else {
+		pci_set_master(pdev);
+		pci_restore_state(pdev);
 
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+		pci_enable_wake(pdev, PCI_D3cold, 0);
 
-	e1000e_reset(adapter);
-	ew32(WUS, ~0);
+		e1000e_reset(adapter);
+		ew32(WUS, ~0);
+		result = PCI_ERS_RESULT_RECOVERED;
+	}
 
-	return PCI_ERS_RESULT_RECOVERED;
+	pci_cleanup_aer_uncorrect_error_status(pdev);
+
+	return result;
 }
 
 /**
@@ -4789,16 +4794,16 @@ static int __devinit e1000_probe(struct
 		return err;
 
 	pci_using_dac = 0;
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!err) {
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (!err)
 			pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			err = pci_set_consistent_dma_mask(pdev,
-							  DMA_32BIT_MASK);
+							  DMA_BIT_MASK(32));
 			if (err) {
 				dev_err(&pdev->dev, "No usable DMA "
 					"configuration, aborting\n");
@@ -4922,12 +4927,6 @@ static int __devinit e1000_probe(struct
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	/*
-	 * We should not be using LLTX anymore, but we are still Tx faster with
-	 * it.
-	 */
-	netdev->features |= NETIF_F_LLTX;
-
 	if (e1000e_enable_mng_pass_thru(&adapter->hw))
 		adapter->flags |= FLAG_MNG_PT_ENABLED;
 
@@ -5091,6 +5090,7 @@ static void __devexit e1000_remove(struc
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	int err;
 
 	/*
 	 * flush_scheduled work may reschedule our watchdog task, so
@@ -5125,6 +5125,12 @@ static void __devexit e1000_remove(struc
 
 	free_netdev(netdev);
 
+	/* AER disable */
+	err = pci_disable_pcie_error_reporting(pdev);
+	if (err)
+		dev_err(&pdev->dev,
+		        "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+
 	pci_disable_device(pdev);
 }
 
@@ -5156,6 +5162,8 @@ static struct pci_device_id e1000_pci_tb
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
 
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
 
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
 	  board_80003es2lan },
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e100.c linux-libre-2.6.30-gnu1/drivers/net/e100.c
--- linux-libre-2.6.29-gnu1/drivers/net/e100.c	2013-05-03 18:02:56.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e100.c	2013-05-03 16:46:49.000000000 -0400
@@ -167,7 +167,7 @@
 
 #define DRV_NAME		"e100"
 #define DRV_EXT			"-NAPI"
-#define DRV_VERSION		"3.5.23-k6"DRV_EXT
+#define DRV_VERSION		"3.5.24-k2"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2006 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -238,6 +238,7 @@ static struct pci_device_id e100_id_tabl
 	INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
 	INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
 	INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
+	INTEL_8255X_ETHERNET_DEVICE(0x10fe, 7),
 	INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
 	INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -273,6 +274,7 @@ enum phy {
 	phy_82562_em = 0x032002A8,
 	phy_82562_ek = 0x031002A8,
 	phy_82562_eh = 0x017002A8,
+	phy_82552_v  = 0xd061004d,
 	phy_unknown  = 0xFFFFFFFF,
 };
 
@@ -941,6 +943,22 @@ static int mdio_read(struct net_device *
 
 static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 {
+	struct nic *nic = netdev_priv(netdev);
+
+	if  ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
+	     (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
+		u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+		/*
+		 * Workaround Si issue where sometimes the part will not
+		 * autoneg to 100Mbps even when advertised.
+		 */
+		if (advert & ADVERTISE_100FULL)
+			data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+		else if (advert & ADVERTISE_100HALF)
+			data |= BMCR_SPEED100;
+	}
+
 	mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
 }
 
@@ -1275,16 +1293,12 @@ static int e100_phy_init(struct nic *nic
 	if (addr == 32)
 		return -EAGAIN;
 
-	/* Selected the phy and isolate the rest */
-	for (addr = 0; addr < 32; addr++) {
-		if (addr != nic->mii.phy_id) {
-			mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
-		} else {
-			bmcr = mdio_read(netdev, addr, MII_BMCR);
-			mdio_write(netdev, addr, MII_BMCR,
-				bmcr & ~BMCR_ISOLATE);
-		}
-	}
+	/* Isolate all the PHY ids */
+	for (addr = 0; addr < 32; addr++)
+		mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
+	/* Select the discovered PHY */
+	bmcr &= ~BMCR_ISOLATE;
+	mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
 
 	/* Get phy ID */
 	id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
@@ -1302,7 +1316,18 @@ static int e100_phy_init(struct nic *nic
 		mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
 	}
 
-	if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
+	if (nic->phy == phy_82552_v) {
+		u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+		/* Workaround Si not advertising flow-control during autoneg */
+		advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+		mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
+
+		/* Reset for the above changes to take effect */
+		bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
+		bmcr |= BMCR_RESET;
+		mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
+	} else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
 	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
 		!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
 		/* enable/disable MDI/MDI-X auto-switching. */
@@ -1943,9 +1968,9 @@ static irqreturn_t e100_intr(int irq, vo
 	if (stat_ack & stat_ack_rnr)
 		nic->ru_running = RU_SUSPENDED;
 
-	if (likely(netif_rx_schedule_prep(&nic->napi))) {
+	if (likely(napi_schedule_prep(&nic->napi))) {
 		e100_disable_irq(nic);
-		__netif_rx_schedule(&nic->napi);
+		__napi_schedule(&nic->napi);
 	}
 
 	return IRQ_HANDLED;
@@ -1961,7 +1986,7 @@ static int e100_poll(struct napi_struct
 
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		e100_enable_irq(nic);
 	}
 
@@ -2133,6 +2158,9 @@ err_clean_rx:
 }
 
 #define MII_LED_CONTROL	0x1B
+#define E100_82552_LED_OVERRIDE 0x19
+#define E100_82552_LED_ON       0x000F /* LEDTX and LED_RX both on */
+#define E100_82552_LED_OFF      0x000A /* LEDTX and LED_RX both off */
 static void e100_blink_led(unsigned long data)
 {
 	struct nic *nic = (struct nic *)data;
@@ -2142,10 +2170,19 @@ static void e100_blink_led(unsigned long
 		led_on_559 = 0x05,
 		led_on_557 = 0x07,
 	};
+	u16 led_reg = MII_LED_CONTROL;
 
-	nic->leds = (nic->leds & led_on) ? led_off :
-		(nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
-	mdio_write(nic->netdev, nic->mii.phy_id, MII_LED_CONTROL, nic->leds);
+	if (nic->phy == phy_82552_v) {
+		led_reg = E100_82552_LED_OVERRIDE;
+
+		nic->leds = (nic->leds == E100_82552_LED_ON) ?
+		            E100_82552_LED_OFF : E100_82552_LED_ON;
+	} else {
+		nic->leds = (nic->leds & led_on) ? led_off :
+		            (nic->mac < mac_82559_D101M) ? led_on_557 :
+		            led_on_559;
+	}
+	mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
 	mod_timer(&nic->blink_timer, jiffies + HZ / 4);
 }
 
@@ -2374,13 +2411,15 @@ static void e100_diag_test(struct net_de
 static int e100_phys_id(struct net_device *netdev, u32 data)
 {
 	struct nic *nic = netdev_priv(netdev);
+	u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
+	              MII_LED_CONTROL;
 
 	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 	mod_timer(&nic->blink_timer, jiffies);
 	msleep_interruptible(data * 1000);
 	del_timer_sync(&nic->blink_timer);
-	mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
+	mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
 
 	return 0;
 }
@@ -2564,7 +2603,7 @@ static int __devinit e100_probe(struct p
 		goto err_out_disable_pdev;
 	}
 
-	if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+	if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 		DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
 		goto err_out_free_res;
 	}
@@ -2685,7 +2724,10 @@ static void __devexit e100_remove(struct
 	}
 }
 
-static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
+#define E100_82552_SMARTSPEED   0x14   /* SmartSpeed Ctrl register */
+#define E100_82552_REV_ANEG     0x0200 /* Reverse auto-negotiation */
+#define E100_82552_ANEG_NOW     0x0400 /* Auto-negotiate now */
+static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
@@ -2697,19 +2739,41 @@ static int e100_suspend(struct pci_dev *
 	pci_save_state(pdev);
 
 	if ((nic->flags & wol_magic) | e100_asf(nic)) {
-		if (pci_enable_wake(pdev, PCI_D3cold, true))
-			pci_enable_wake(pdev, PCI_D3hot, true);
+		/* enable reverse auto-negotiation */
+		if (nic->phy == phy_82552_v) {
+			u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+			                           E100_82552_SMARTSPEED);
+
+			mdio_write(netdev, nic->mii.phy_id,
+			           E100_82552_SMARTSPEED, smartspeed |
+			           E100_82552_REV_ANEG | E100_82552_ANEG_NOW);
+		}
+		*enable_wake = true;
 	} else {
-		pci_enable_wake(pdev, PCI_D3hot, false);
+		*enable_wake = false;
 	}
 
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, PCI_D3hot);
+}
 
-	return 0;
+static int __e100_power_off(struct pci_dev *pdev, bool wake)
+{
+	if (wake) {
+		return pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		return pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 #ifdef CONFIG_PM
+static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	bool wake;
+	__e100_shutdown(pdev, &wake);
+	return __e100_power_off(pdev, wake);
+}
+
 static int e100_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2720,6 +2784,16 @@ static int e100_resume(struct pci_dev *p
 	/* ack any pending wake events, disable PME */
 	pci_enable_wake(pdev, 0, 0);
 
+	/* disbale reverse auto-negotiation */
+	if (nic->phy == phy_82552_v) {
+		u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+		                           E100_82552_SMARTSPEED);
+
+		mdio_write(netdev, nic->mii.phy_id,
+		           E100_82552_SMARTSPEED,
+		           smartspeed & ~(E100_82552_REV_ANEG));
+	}
+
 	netif_device_attach(netdev);
 	if (netif_running(netdev))
 		e100_up(nic);
@@ -2730,7 +2804,10 @@ static int e100_resume(struct pci_dev *p
 
 static void e100_shutdown(struct pci_dev *pdev)
 {
-	e100_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+	__e100_shutdown(pdev, &wake);
+	if (system_state == SYSTEM_POWER_OFF)
+		__e100_power_off(pdev, wake);
 }
 
 /* ------------------ PCI Error Recovery infrastructure  -------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/e2100.c linux-libre-2.6.30-gnu1/drivers/net/e2100.c
--- linux-libre-2.6.29-gnu1/drivers/net/e2100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/e2100.c	2009-06-09 23:05:27.000000000 -0400
@@ -216,13 +216,13 @@ static int __init e21_probe1(struct net_
 		printk(" %02X", station_addr[i]);
 
 	if (dev->irq < 2) {
-		int irqlist[] = {15,11,10,12,5,9,3,4}, i;
-		for (i = 0; i < 8; i++)
+		int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
+		for (i = 0; i < ARRAY_SIZE(irqlist); i++)
 			if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
 				dev->irq = irqlist[i];
 				break;
 			}
-		if (i >= 8) {
+		if (i >= ARRAY_SIZE(irqlist)) {
 			printk(" unable to get IRQ %d.\n", dev->irq);
 			retval = -EAGAIN;
 			goto out;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/eepro.c linux-libre-2.6.30-gnu1/drivers/net/eepro.c
--- linux-libre-2.6.29-gnu1/drivers/net/eepro.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/eepro.c	2009-06-09 23:05:27.000000000 -0400
@@ -739,6 +739,17 @@ static void __init eepro_print_info (str
 
 static const struct ethtool_ops eepro_ethtool_ops;
 
+static const struct net_device_ops eepro_netdev_ops = {
+ 	.ndo_open               = eepro_open,
+ 	.ndo_stop               = eepro_close,
+ 	.ndo_start_xmit    	= eepro_send_packet,
+ 	.ndo_set_multicast_list = set_multicast_list,
+ 	.ndo_tx_timeout		= eepro_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* This is the real probe routine.  Linux has a history of friendly device
    probes on the ISA bus.  A good device probe avoids doing writes, and
    verifies that the correct device exists and functions.  */
@@ -851,11 +862,7 @@ static int __init eepro_probe1(struct ne
  		}
  	}
 
- 	dev->open               = eepro_open;
- 	dev->stop               = eepro_close;
- 	dev->hard_start_xmit    = eepro_send_packet;
- 	dev->set_multicast_list = &set_multicast_list;
- 	dev->tx_timeout		= eepro_tx_timeout;
+	dev->netdev_ops		= &eepro_netdev_ops;
  	dev->watchdog_timeo	= TX_TIMEOUT;
 	dev->ethtool_ops	= &eepro_ethtool_ops;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/eexpress.c linux-libre-2.6.30-gnu1/drivers/net/eexpress.c
--- linux-libre-2.6.29-gnu1/drivers/net/eexpress.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/eexpress.c	2009-06-09 23:05:27.000000000 -0400
@@ -1043,6 +1043,17 @@ static void eexp_hw_tx_pio(struct net_de
 	lp->last_tx = jiffies;
 }
 
+static const struct net_device_ops eexp_netdev_ops = {
+	.ndo_open 		= eexp_open,
+	.ndo_stop 		= eexp_close,
+	.ndo_start_xmit		= eexp_xmit,
+	.ndo_set_multicast_list = eexp_set_multicast,
+	.ndo_tx_timeout		= eexp_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*
  * Sanity check the suspected EtherExpress card
  * Read hardware address, reset card, size memory and initialize buffer
@@ -1163,11 +1174,7 @@ static int __init eexp_hw_probe(struct n
 	lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
 	lp->width = buswidth;
 
-	dev->open = eexp_open;
-	dev->stop = eexp_close;
-	dev->hard_start_xmit = eexp_xmit;
-	dev->set_multicast_list = &eexp_set_multicast;
-	dev->tx_timeout = eexp_timeout;
+	dev->netdev_ops = &eexp_netdev_ops;
 	dev->watchdog_timeo = 2*HZ;
 
 	return register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea.h linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea.h
--- linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0096"
+#define DRV_VERSION	"EHEA_0101"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea_main.c linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -155,6 +155,8 @@ static void ehea_update_firmware_handles
 	int num_fw_handles, k, l;
 
 	/* Determine number of handles */
+	mutex_lock(&ehea_fw_handles.lock);
+
 	list_for_each_entry(adapter, &adapter_list, list) {
 		num_adapters++;
 
@@ -176,15 +178,19 @@ static void ehea_update_firmware_handles
 	if (num_fw_handles) {
 		arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
 		if (!arr)
-			return;  /* Keep the existing array */
+			goto out;  /* Keep the existing array */
 	} else
 		goto out_update;
 
 	list_for_each_entry(adapter, &adapter_list, list) {
+		if (num_adapters == 0)
+			break;
+
 		for (k = 0; k < EHEA_MAX_PORTS; k++) {
 			struct ehea_port *port = adapter->port[k];
 
-			if (!port || (port->state != EHEA_PORT_UP))
+			if (!port || (port->state != EHEA_PORT_UP)
+				|| (num_ports == 0))
 				continue;
 
 			for (l = 0;
@@ -207,6 +213,7 @@ static void ehea_update_firmware_handles
 			}
 			arr[i].adh = adapter->handle;
 			arr[i++].fwh = port->qp_eq->fw_handle;
+			num_ports--;
 		}
 
 		arr[i].adh = adapter->handle;
@@ -216,16 +223,20 @@ static void ehea_update_firmware_handles
 			arr[i].adh = adapter->handle;
 			arr[i++].fwh = adapter->mr.handle;
 		}
+		num_adapters--;
 	}
 
 out_update:
 	kfree(ehea_fw_handles.arr);
 	ehea_fw_handles.arr = arr;
 	ehea_fw_handles.num_entries = i;
+out:
+	mutex_unlock(&ehea_fw_handles.lock);
 }
 
 static void ehea_update_bcmc_registrations(void)
 {
+	unsigned long flags;
 	struct ehea_bcmc_reg_entry *arr = NULL;
 	struct ehea_adapter *adapter;
 	struct ehea_mc_list *mc_entry;
@@ -233,6 +244,8 @@ static void ehea_update_bcmc_registratio
 	int i = 0;
 	int k;
 
+	spin_lock_irqsave(&ehea_bcmc_regs.lock, flags);
+
 	/* Determine number of registrations */
 	list_for_each_entry(adapter, &adapter_list, list)
 		for (k = 0; k < EHEA_MAX_PORTS; k++) {
@@ -250,7 +263,7 @@ static void ehea_update_bcmc_registratio
 	if (num_registrations) {
 		arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
 		if (!arr)
-			return;  /* Keep the existing array */
+			goto out;  /* Keep the existing array */
 	} else
 		goto out_update;
 
@@ -261,6 +274,9 @@ static void ehea_update_bcmc_registratio
 			if (!port || (port->state != EHEA_PORT_UP))
 				continue;
 
+			if (num_registrations == 0)
+				goto out_update;
+
 			arr[i].adh = adapter->handle;
 			arr[i].port_id = port->logical_port_id;
 			arr[i].reg_type = EHEA_BCMC_BROADCAST |
@@ -272,9 +288,13 @@ static void ehea_update_bcmc_registratio
 			arr[i].reg_type = EHEA_BCMC_BROADCAST |
 					  EHEA_BCMC_VLANID_ALL;
 			arr[i++].macaddr = port->mac_addr;
+			num_registrations -= 2;
 
 			list_for_each_entry(mc_entry,
 					    &port->mc_list->list, list) {
+				if (num_registrations == 0)
+					goto out_update;
+
 				arr[i].adh = adapter->handle;
 				arr[i].port_id = port->logical_port_id;
 				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
@@ -288,6 +308,7 @@ static void ehea_update_bcmc_registratio
 						  EHEA_BCMC_MULTICAST |
 						  EHEA_BCMC_VLANID_ALL;
 				arr[i++].macaddr = mc_entry->macaddr;
+				num_registrations -= 2;
 			}
 		}
 	}
@@ -296,6 +317,8 @@ out_update:
 	kfree(ehea_bcmc_regs.arr);
 	ehea_bcmc_regs.arr = arr;
 	ehea_bcmc_regs.num_entries = i;
+out:
+	spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags);
 }
 
 static struct net_device_stats *ehea_get_stats(struct net_device *dev)
@@ -308,7 +331,7 @@ static struct net_device_stats *ehea_get
 
 	memset(stats, 0, sizeof(*stats));
 
-	cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+	cb2 = (void *)get_zeroed_page(GFP_ATOMIC);
 	if (!cb2) {
 		ehea_error("no mem for cb2");
 		goto out;
@@ -341,7 +364,7 @@ static struct net_device_stats *ehea_get
 	stats->rx_packets = rx_packets;
 
 out_herr:
-	kfree(cb2);
+	free_page((unsigned long)cb2);
 out:
 	return stats;
 }
@@ -370,8 +393,6 @@ static void ehea_refill_rq1(struct ehea_
 							      EHEA_L_PKT_SIZE);
 			if (!skb_arr_rq1[index]) {
 				pr->rq1_skba.os_skbs = fill_wqes - i;
-				ehea_error("%s: no mem for skb/%d wqes filled",
-					   dev->name, i);
 				break;
 			}
 		}
@@ -387,26 +408,19 @@ static void ehea_refill_rq1(struct ehea_
 	ehea_update_rq1a(pr->qp, adder);
 }
 
-static int ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
+static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
 {
-	int ret = 0;
 	struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr;
 	struct net_device *dev = pr->port->netdev;
 	int i;
 
 	for (i = 0; i < pr->rq1_skba.len; i++) {
 		skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
-		if (!skb_arr_rq1[i]) {
-			ehea_error("%s: no mem for skb/%d wqes filled",
-				   dev->name, i);
-			ret = -ENOMEM;
-			goto out;
-		}
+		if (!skb_arr_rq1[i])
+			break;
 	}
 	/* Ring doorbell */
 	ehea_update_rq1a(pr->qp, nr_rq1a);
-out:
-	return ret;
 }
 
 static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -435,10 +449,12 @@ static int ehea_refill_rq_def(struct ehe
 		u64 tmp_addr;
 		struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
 		if (!skb) {
-			ehea_error("%s: no mem for skb/%d wqes filled",
-				   pr->port->netdev->name, i);
 			q_skba->os_skbs = fill_wqes - i;
-			ret = -ENOMEM;
+			if (q_skba->os_skbs == q_skba->len - 2) {
+				ehea_info("%s: rq%i ran dry - no mem for skb",
+					  pr->port->netdev->name, rq_nr);
+				ret = -ENOMEM;
+			}
 			break;
 		}
 		skb_reserve(skb, NET_IP_ALIGN);
@@ -529,14 +545,17 @@ static inline struct sk_buff *get_skb_by
 	x &= (arr_len - 1);
 
 	pref = skb_array[x];
-	prefetchw(pref);
-	prefetchw(pref + EHEA_CACHE_LINE);
+	if (pref) {
+		prefetchw(pref);
+		prefetchw(pref + EHEA_CACHE_LINE);
+
+		pref = (skb_array[x]->data);
+		prefetch(pref);
+		prefetch(pref + EHEA_CACHE_LINE);
+		prefetch(pref + EHEA_CACHE_LINE * 2);
+		prefetch(pref + EHEA_CACHE_LINE * 3);
+	}
 
-	pref = (skb_array[x]->data);
-	prefetch(pref);
-	prefetch(pref + EHEA_CACHE_LINE);
-	prefetch(pref + EHEA_CACHE_LINE * 2);
-	prefetch(pref + EHEA_CACHE_LINE * 3);
 	skb = skb_array[skb_index];
 	skb_array[skb_index] = NULL;
 	return skb;
@@ -553,12 +572,14 @@ static inline struct sk_buff *get_skb_by
 	x &= (arr_len - 1);
 
 	pref = skb_array[x];
-	prefetchw(pref);
-	prefetchw(pref + EHEA_CACHE_LINE);
+	if (pref) {
+		prefetchw(pref);
+		prefetchw(pref + EHEA_CACHE_LINE);
 
-	pref = (skb_array[x]->data);
-	prefetchw(pref);
-	prefetchw(pref + EHEA_CACHE_LINE);
+		pref = (skb_array[x]->data);
+		prefetchw(pref);
+		prefetchw(pref + EHEA_CACHE_LINE);
+	}
 
 	skb = skb_array[wqe_index];
 	skb_array[wqe_index] = NULL;
@@ -830,7 +851,7 @@ static int ehea_poll(struct napi_struct
 	while ((rx != budget) || force_irq) {
 		pr->poll_counter = 0;
 		force_irq = 0;
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		ehea_reset_cq_ep(pr->recv_cq);
 		ehea_reset_cq_ep(pr->send_cq);
 		ehea_reset_cq_n1(pr->recv_cq);
@@ -841,7 +862,7 @@ static int ehea_poll(struct napi_struct
 		if (!cqe && !cqe_skb)
 			return rx;
 
-		if (!netif_rx_reschedule(napi))
+		if (!napi_reschedule(napi))
 			return rx;
 
 		cqe_skb = ehea_proc_cqes(pr, EHEA_POLL_MAX_CQES);
@@ -859,7 +880,7 @@ static void ehea_netpoll(struct net_devi
 	int i;
 
 	for (i = 0; i < port->num_def_qps; i++)
-		netif_rx_schedule(&port->port_res[i].napi);
+		napi_schedule(&port->port_res[i].napi);
 }
 #endif
 
@@ -867,7 +888,7 @@ static irqreturn_t ehea_recv_irq_handler
 {
 	struct ehea_port_res *pr = param;
 
-	netif_rx_schedule(&pr->napi);
+	napi_schedule(&pr->napi);
 
 	return IRQ_HANDLED;
 }
@@ -915,7 +936,7 @@ int ehea_sense_port_attr(struct ehea_por
 	struct hcp_ehea_port_cb0 *cb0;
 
 	/* may be called via ehea_neq_tasklet() */
-	cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+	cb0 = (void *)get_zeroed_page(GFP_ATOMIC);
 	if (!cb0) {
 		ehea_error("no mem for cb0");
 		ret = -ENOMEM;
@@ -996,7 +1017,7 @@ int ehea_sense_port_attr(struct ehea_por
 out_free:
 	if (ret || netif_msg_probe(port))
 		ehea_dump(cb0, sizeof(*cb0), "ehea_sense_port_attr");
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 out:
 	return ret;
 }
@@ -1007,7 +1028,7 @@ int ehea_set_portspeed(struct ehea_port
 	u64 hret;
 	int ret = 0;
 
-	cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb4 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb4) {
 		ehea_error("no mem for cb4");
 		ret = -ENOMEM;
@@ -1075,7 +1096,7 @@ int ehea_set_portspeed(struct ehea_port
 	if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
 		netif_carrier_on(port->netdev);
 
-	kfree(cb4);
+	free_page((unsigned long)cb4);
 out:
 	return ret;
 }
@@ -1201,11 +1222,11 @@ static int ehea_fill_port_res(struct ehe
 	int ret;
 	struct ehea_qp_init_attr *init_attr = &pr->qp->init_attr;
 
-	ret = ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
-				     - init_attr->act_nr_rwqes_rq2
-				     - init_attr->act_nr_rwqes_rq3 - 1);
+	ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
+			       - init_attr->act_nr_rwqes_rq2
+			       - init_attr->act_nr_rwqes_rq3 - 1);
 
-	ret |= ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
+	ret = ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
 
 	ret |= ehea_refill_rq3(pr, init_attr->act_nr_rwqes_rq3 - 1);
 
@@ -1302,7 +1323,7 @@ static int ehea_configure_port(struct eh
 	struct hcp_ehea_port_cb0 *cb0;
 
 	ret = -ENOMEM;
-	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb0 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb0)
 		goto out;
 
@@ -1338,7 +1359,7 @@ static int ehea_configure_port(struct eh
 	ret = 0;
 
 out_free:
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 out:
 	return ret;
 }
@@ -1748,7 +1769,7 @@ static int ehea_set_mac_addr(struct net_
 		goto out;
 	}
 
-	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb0 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb0) {
 		ehea_error("no mem for cb0");
 		ret = -ENOMEM;
@@ -1769,8 +1790,6 @@ static int ehea_set_mac_addr(struct net_
 
 	memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
 
-	spin_lock(&ehea_bcmc_regs.lock);
-
 	/* Deregister old MAC in pHYP */
 	if (port->state == EHEA_PORT_UP) {
 		ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1791,9 +1810,8 @@ static int ehea_set_mac_addr(struct net_
 
 out_upregs:
 	ehea_update_bcmc_registrations();
-	spin_unlock(&ehea_bcmc_regs.lock);
 out_free:
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 out:
 	return ret;
 }
@@ -1817,7 +1835,7 @@ static void ehea_promiscuous(struct net_
 	if ((enable && port->promisc) || (!enable && !port->promisc))
 		return;
 
-	cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+	cb7 = (void *)get_zeroed_page(GFP_ATOMIC);
 	if (!cb7) {
 		ehea_error("no mem for cb7");
 		goto out;
@@ -1836,7 +1854,7 @@ static void ehea_promiscuous(struct net_
 
 	port->promisc = enable;
 out:
-	kfree(cb7);
+	free_page((unsigned long)cb7);
 	return;
 }
 
@@ -1953,8 +1971,6 @@ static void ehea_set_multicast_list(stru
 	}
 	ehea_promiscuous(dev, 0);
 
-	spin_lock(&ehea_bcmc_regs.lock);
-
 	if (dev->flags & IFF_ALLMULTI) {
 		ehea_allmulti(dev, 1);
 		goto out;
@@ -1984,7 +2000,6 @@ static void ehea_set_multicast_list(stru
 	}
 out:
 	ehea_update_bcmc_registrations();
-	spin_unlock(&ehea_bcmc_regs.lock);
 	return;
 }
 
@@ -2217,7 +2232,7 @@ static void ehea_vlan_rx_register(struct
 
 	port->vgrp = grp;
 
-	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb1 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -2228,7 +2243,7 @@ static void ehea_vlan_rx_register(struct
 	if (hret != H_SUCCESS)
 		ehea_error("modify_ehea_port failed");
 
-	kfree(cb1);
+	free_page((unsigned long)cb1);
 out:
 	return;
 }
@@ -2241,7 +2256,7 @@ static void ehea_vlan_rx_add_vid(struct
 	int index;
 	u64 hret;
 
-	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb1 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -2262,7 +2277,7 @@ static void ehea_vlan_rx_add_vid(struct
 	if (hret != H_SUCCESS)
 		ehea_error("modify_ehea_port failed");
 out:
-	kfree(cb1);
+	free_page((unsigned long)cb1);
 	return;
 }
 
@@ -2276,7 +2291,7 @@ static void ehea_vlan_rx_kill_vid(struct
 
 	vlan_group_set_device(port->vgrp, vid, NULL);
 
-	cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb1 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb1) {
 		ehea_error("no mem for cb1");
 		goto out;
@@ -2297,7 +2312,7 @@ static void ehea_vlan_rx_kill_vid(struct
 	if (hret != H_SUCCESS)
 		ehea_error("modify_ehea_port failed");
 out:
-	kfree(cb1);
+	free_page((unsigned long)cb1);
 	return;
 }
 
@@ -2309,7 +2324,7 @@ int ehea_activate_qp(struct ehea_adapter
 	u64 dummy64 = 0;
 	struct hcp_modify_qp_cb0 *cb0;
 
-	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb0 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb0) {
 		ret = -ENOMEM;
 		goto out;
@@ -2372,7 +2387,7 @@ int ehea_activate_qp(struct ehea_adapter
 
 	ret = 0;
 out:
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 	return ret;
 }
 
@@ -2465,8 +2480,6 @@ static int ehea_up(struct net_device *de
 	if (port->state == EHEA_PORT_UP)
 		return 0;
 
-	mutex_lock(&ehea_fw_handles.lock);
-
 	ret = ehea_port_res_setup(port, port->num_def_qps,
 				  port->num_add_tx_qps);
 	if (ret) {
@@ -2503,8 +2516,6 @@ static int ehea_up(struct net_device *de
 		}
 	}
 
-	spin_lock(&ehea_bcmc_regs.lock);
-
 	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
 	if (ret) {
 		ret = -EIO;
@@ -2526,10 +2537,7 @@ out:
 		ehea_info("Failed starting %s. ret=%i", dev->name, ret);
 
 	ehea_update_bcmc_registrations();
-	spin_unlock(&ehea_bcmc_regs.lock);
-
 	ehea_update_firmware_handles();
-	mutex_unlock(&ehea_fw_handles.lock);
 
 	return ret;
 }
@@ -2579,9 +2587,6 @@ static int ehea_down(struct net_device *
 	if (port->state == EHEA_PORT_DOWN)
 		return 0;
 
-	mutex_lock(&ehea_fw_handles.lock);
-
-	spin_lock(&ehea_bcmc_regs.lock);
 	ehea_drop_multicast_list(dev);
 	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 
@@ -2590,7 +2595,6 @@ static int ehea_down(struct net_device *
 	port->state = EHEA_PORT_DOWN;
 
 	ehea_update_bcmc_registrations();
-	spin_unlock(&ehea_bcmc_regs.lock);
 
 	ret = ehea_clean_all_portres(port);
 	if (ret)
@@ -2598,7 +2602,6 @@ static int ehea_down(struct net_device *
 			  dev->name, ret);
 
 	ehea_update_firmware_handles();
-	mutex_unlock(&ehea_fw_handles.lock);
 
 	return ret;
 }
@@ -2664,7 +2667,7 @@ int ehea_stop_qps(struct net_device *dev
 	u64 dummy64 = 0;
 	u16 dummy16 = 0;
 
-	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb0 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb0) {
 		ret = -ENOMEM;
 		goto out;
@@ -2716,7 +2719,7 @@ int ehea_stop_qps(struct net_device *dev
 
 	ret = 0;
 out:
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 
 	return ret;
 }
@@ -2766,7 +2769,7 @@ int ehea_restart_qps(struct net_device *
 	u64 dummy64 = 0;
 	u16 dummy16 = 0;
 
-	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb0 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb0) {
 		ret = -ENOMEM;
 		goto out;
@@ -2819,7 +2822,7 @@ int ehea_restart_qps(struct net_device *
 		ehea_refill_rq3(pr, 0);
 	}
 out:
-	kfree(cb0);
+	free_page((unsigned long)cb0);
 
 	return ret;
 }
@@ -2950,7 +2953,7 @@ int ehea_sense_adapter_attr(struct ehea_
 	u64 hret;
 	int ret;
 
-	cb = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb) {
 		ret = -ENOMEM;
 		goto out;
@@ -2967,7 +2970,7 @@ int ehea_sense_adapter_attr(struct ehea_
 	ret = 0;
 
 out_herr:
-	kfree(cb);
+	free_page((unsigned long)cb);
 out:
 	return ret;
 }
@@ -2981,7 +2984,7 @@ int ehea_get_jumboframe_status(struct eh
 	*jumbo = 0;
 
 	/* (Try to) enable *jumbo frames */
-	cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	cb4 = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!cb4) {
 		ehea_error("no mem for cb4");
 		ret = -ENOMEM;
@@ -3009,7 +3012,7 @@ int ehea_get_jumboframe_status(struct eh
 		} else
 			ret = -EINVAL;
 
-		kfree(cb4);
+		free_page((unsigned long)cb4);
 	}
 out:
 	return ret;
@@ -3040,7 +3043,7 @@ static struct device *ehea_register_port
 	port->ofdev.dev.parent = &port->adapter->ofdev->dev;
 	port->ofdev.dev.bus = &ibmebus_bus_type;
 
-	sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
+	dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++);
 	port->ofdev.dev.release = logical_port_release;
 
 	ret = of_device_register(&port->ofdev);
@@ -3069,6 +3072,23 @@ static void ehea_unregister_port(struct
 	of_device_unregister(&port->ofdev);
 }
 
+static const struct net_device_ops ehea_netdev_ops = {
+	.ndo_open		= ehea_open,
+	.ndo_stop		= ehea_stop,
+	.ndo_start_xmit		= ehea_start_xmit,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ehea_netpoll,
+#endif
+	.ndo_get_stats		= ehea_get_stats,
+	.ndo_set_mac_address	= ehea_set_mac_addr,
+	.ndo_set_multicast_list	= ehea_set_multicast_list,
+	.ndo_change_mtu		= ehea_change_mtu,
+	.ndo_vlan_rx_register	= ehea_vlan_rx_register,
+	.ndo_vlan_rx_add_vid	= ehea_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= ehea_vlan_rx_kill_vid,
+	.ndo_tx_timeout		= ehea_tx_watchdog,
+};
+
 struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 					 u32 logical_port_id,
 					 struct device_node *dn)
@@ -3121,28 +3141,16 @@ struct ehea_port *ehea_setup_single_port
 	/* initialize net_device structure */
 	memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN);
 
-	dev->open = ehea_open;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = ehea_netpoll;
-#endif
-	dev->stop = ehea_stop;
-	dev->hard_start_xmit = ehea_start_xmit;
-	dev->get_stats = ehea_get_stats;
-	dev->set_multicast_list = ehea_set_multicast_list;
-	dev->set_mac_address = ehea_set_mac_addr;
-	dev->change_mtu = ehea_change_mtu;
-	dev->vlan_rx_register = ehea_vlan_rx_register;
-	dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid;
-	dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid;
+	dev->netdev_ops = &ehea_netdev_ops;
+	ehea_set_ethtool_ops(dev);
+
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
 		      | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
 		      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
 		      | NETIF_F_LLTX;
-	dev->tx_timeout = &ehea_tx_watchdog;
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
 	INIT_WORK(&port->reset_task, ehea_reset_port);
-	ehea_set_ethtool_ops(dev);
 
 	ret = register_netdev(dev);
 	if (ret) {
@@ -3370,7 +3378,6 @@ static int __devinit ehea_probe_adapter(
 		ehea_error("Invalid ibmebus device probed");
 		return -EINVAL;
 	}
-	mutex_lock(&ehea_fw_handles.lock);
 
 	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
 	if (!adapter) {
@@ -3450,11 +3457,12 @@ out_kill_eq:
 	ehea_destroy_eq(adapter->neq);
 
 out_free_ad:
+	list_del(&adapter->list);
 	kfree(adapter);
 
 out:
 	ehea_update_firmware_handles();
-	mutex_unlock(&ehea_fw_handles.lock);
+
 	return ret;
 }
 
@@ -3473,8 +3481,6 @@ static int __devexit ehea_remove(struct
 
 	flush_scheduled_work();
 
-	mutex_lock(&ehea_fw_handles.lock);
-
 	ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
 	tasklet_kill(&adapter->neq_tasklet);
 
@@ -3484,7 +3490,6 @@ static int __devexit ehea_remove(struct
 	kfree(adapter);
 
 	ehea_update_firmware_handles();
-	mutex_unlock(&ehea_fw_handles.lock);
 
 	return 0;
 }
@@ -3518,12 +3523,14 @@ static int ehea_mem_notifier(struct noti
 		/* Readd canceled memory block */
 	case MEM_ONLINE:
 		ehea_info("memory is going online");
+		set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
 		if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
 			return NOTIFY_BAD;
 		ehea_rereg_mrs(NULL);
 		break;
 	case MEM_GOING_OFFLINE:
 		ehea_info("memory is going offline");
+		set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
 		if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
 			return NOTIFY_BAD;
 		ehea_rereg_mrs(NULL);
@@ -3531,6 +3538,9 @@ static int ehea_mem_notifier(struct noti
 	default:
 		break;
 	}
+
+	ehea_update_firmware_handles();
+
 	return NOTIFY_OK;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea_qmr.c linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_qmr.c
--- linux-libre-2.6.29-gnu1/drivers/net/ehea/ehea_qmr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_qmr.c	2009-06-09 23:05:27.000000000 -0400
@@ -1005,7 +1005,7 @@ void ehea_error_data(struct ehea_adapter
 	unsigned long ret;
 	u64 *rblock;
 
-	rblock = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	rblock = (void *)get_zeroed_page(GFP_KERNEL);
 	if (!rblock) {
 		ehea_error("Cannot allocate rblock memory.");
 		return;
@@ -1022,5 +1022,5 @@ void ehea_error_data(struct ehea_adapter
 	else
 		ehea_error("Error data could not be fetched: %llX", res_handle);
 
-	kfree(rblock);
+	free_page((unsigned long)rblock);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/enic.h linux-libre-2.6.30-gnu1/drivers/net/enic/enic.h
--- linux-libre-2.6.29-gnu1/drivers/net/enic/enic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/enic.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco 10G Ethernet Driver"
-#define DRV_VERSION		"1.0.0.648"
+#define DRV_VERSION		"1.0.0.933"
 #define DRV_COPYRIGHT		"Copyright 2008 Cisco Systems, Inc"
 #define PFX			DRV_NAME ": "
 
@@ -97,6 +97,7 @@ struct enic {
 	____cacheline_aligned struct vnic_rq rq[1];
 	unsigned int rq_count;
 	int (*rq_alloc_buf)(struct vnic_rq *rq);
+	u64 rq_bad_fcs;
 	struct napi_struct napi;
 	struct net_lro_mgr lro_mgr;
 	struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC];
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/enic_main.c linux-libre-2.6.30-gnu1/drivers/net/enic/enic_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/enic/enic_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/enic_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -400,10 +400,13 @@ static irqreturn_t enic_isr_legacy(int i
 		return IRQ_NONE;	/* not our interrupt */
 	}
 
-	if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY))
+	if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) {
+		vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]);
 		enic_notify_check(enic);
+	}
 
 	if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) {
+		vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]);
 		enic_log_q_error(enic);
 		/* schedule recovery from WQ/RQ error */
 		schedule_work(&enic->reset);
@@ -411,8 +414,8 @@ static irqreturn_t enic_isr_legacy(int i
 	}
 
 	if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
-		if (netif_rx_schedule_prep(&enic->napi))
-			__netif_rx_schedule(&enic->napi);
+		if (napi_schedule_prep(&enic->napi))
+			__napi_schedule(&enic->napi);
 	} else {
 		vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
 	}
@@ -440,7 +443,7 @@ static irqreturn_t enic_isr_msi(int irq,
 	 * writes).
 	 */
 
-	netif_rx_schedule(&enic->napi);
+	napi_schedule(&enic->napi);
 
 	return IRQ_HANDLED;
 }
@@ -450,7 +453,7 @@ static irqreturn_t enic_isr_msix_rq(int
 	struct enic *enic = data;
 
 	/* schedule NAPI polling for RQ cleanup */
-	netif_rx_schedule(&enic->napi);
+	napi_schedule(&enic->napi);
 
 	return IRQ_HANDLED;
 }
@@ -476,6 +479,8 @@ static irqreturn_t enic_isr_msix_err(int
 {
 	struct enic *enic = data;
 
+	vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]);
+
 	enic_log_q_error(enic);
 
 	/* schedule recovery from WQ/RQ error */
@@ -488,8 +493,8 @@ static irqreturn_t enic_isr_msix_notify(
 {
 	struct enic *enic = data;
 
+	vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]);
 	enic_notify_check(enic);
-	vnic_intr_unmask(&enic->intr[ENIC_MSIX_NOTIFY]);
 
 	return IRQ_HANDLED;
 }
@@ -570,11 +575,11 @@ static inline void enic_queue_wq_skb_tso
 	 * to each TCP segment resulting from the TSO.
 	 */
 
-	if (skb->protocol == __constant_htons(ETH_P_IP)) {
+	if (skb->protocol == cpu_to_be16(ETH_P_IP)) {
 		ip_hdr(skb)->check = 0;
 		tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
 			ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
-	} else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+	} else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
 		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
 			&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
 	}
@@ -616,7 +621,7 @@ static inline void enic_queue_wq_skb(str
 			vlan_tag_insert, vlan_tag);
 }
 
-/* netif_tx_lock held, process context with BHs disabled */
+/* netif_tx_lock held, process context with BHs disabled, or BH */
 static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct enic *enic = netdev_priv(netdev);
@@ -683,7 +688,7 @@ static struct net_device_stats *enic_get
 	net_stats->rx_bytes = stats->rx.rx_bytes_ok;
 	net_stats->rx_errors = stats->rx.rx_errors;
 	net_stats->multicast = stats->rx.rx_multicast_frames_ok;
-	net_stats->rx_crc_errors = stats->rx.rx_crc_errors;
+	net_stats->rx_crc_errors = enic->rq_bad_fcs;
 	net_stats->rx_dropped = stats->rx.rx_no_bufs;
 
 	return net_stats;
@@ -928,12 +933,8 @@ static void enic_rq_indicate_buf(struct
 
 	if (packet_error) {
 
-		if (bytes_written > 0 && !fcs_ok) {
-			if (net_ratelimit())
-				printk(KERN_ERR PFX
-					"%s: packet error: bad FCS\n",
-					netdev->name);
-		}
+		if (bytes_written > 0 && !fcs_ok)
+			enic->rq_bad_fcs++;
 
 		dev_kfree_skb_any(skb);
 
@@ -1068,8 +1069,8 @@ static int enic_poll(struct napi_struct
 		if (netdev->features & NETIF_F_LRO)
 			lro_flush_all(&enic->lro_mgr);
 
-		netif_rx_complete(napi);
-		vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
+		napi_complete(napi);
+		vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
 	}
 
 	return rq_work_done;
@@ -1095,9 +1096,9 @@ static int enic_poll_msix(struct napi_st
 
 		vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
 
-		/* Accumulate intr event credits for this polling
+		/* Return intr event credits for this polling
 		 * cycle.  An intr event is the completion of a
-		 * a WQ or RQ packet.
+		 * RQ packet.
 		 */
 
 		vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
@@ -1112,7 +1113,7 @@ static int enic_poll_msix(struct napi_st
 		if (netdev->features & NETIF_F_LRO)
 			lro_flush_all(&enic->lro_mgr);
 
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
 	}
 
@@ -1461,6 +1462,26 @@ static int enic_dev_soft_reset(struct en
 	return err;
 }
 
+static int enic_set_niccfg(struct enic *enic)
+{
+	const u8 rss_default_cpu = 0;
+	const u8 rss_hash_type = 0;
+	const u8 rss_hash_bits = 0;
+	const u8 rss_base_cpu = 0;
+	const u8 rss_enable = 0;
+	const u8 tso_ipid_split_en = 0;
+	const u8 ig_vlan_strip_en = 1;
+
+	/* Enable VLAN tag stripping.  RSS not enabled (yet).
+	*/
+
+	return enic_set_nic_cfg(enic,
+		rss_default_cpu, rss_hash_type,
+		rss_hash_bits, rss_base_cpu,
+		rss_enable, tso_ipid_split_en,
+		ig_vlan_strip_en);
+}
+
 static void enic_reset(struct work_struct *work)
 {
 	struct enic *enic = container_of(work, struct enic, reset);
@@ -1476,8 +1497,10 @@ static void enic_reset(struct work_struc
 
 	enic_stop(enic->netdev);
 	enic_dev_soft_reset(enic);
+	vnic_dev_init(enic->vdev, 0);
 	enic_reset_mcaddrs(enic);
 	enic_init_vnic_resources(enic);
+	enic_set_niccfg(enic);
 	enic_open(enic->netdev);
 
 	rtnl_unlock();
@@ -1620,14 +1643,6 @@ static int __devinit enic_probe(struct p
 	unsigned int i;
 	int err;
 
-	const u8 rss_default_cpu = 0;
-	const u8 rss_hash_type = 0;
-	const u8 rss_hash_bits = 0;
-	const u8 rss_base_cpu = 0;
-	const u8 rss_enable = 0;
-	const u8 tso_ipid_split_en = 0;
-	const u8 ig_vlan_strip_en = 1;
-
 	/* Allocate net device structure and initialize.  Private
 	 * instance data is initialized to zero.
 	 */
@@ -1670,15 +1685,15 @@ static int __devinit enic_probe(struct p
 	 * fail to 32-bit.
 	 */
 
-	err = pci_set_dma_mask(pdev, DMA_40BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
 	if (err) {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			printk(KERN_ERR PFX
 				"No usable DMA configuration, aborting.\n");
 			goto err_out_release_regions;
 		}
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			printk(KERN_ERR PFX
 				"Unable to obtain 32-bit DMA "
@@ -1686,7 +1701,7 @@ static int __devinit enic_probe(struct p
 			goto err_out_release_regions;
 		}
 	} else {
-		err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
 		if (err) {
 			printk(KERN_ERR PFX
 				"Unable to obtain 40-bit DMA "
@@ -1793,14 +1808,7 @@ static int __devinit enic_probe(struct p
 
 	enic_init_vnic_resources(enic);
 
-	/* Enable VLAN tag stripping.  RSS not enabled (yet).
-	 */
-
-	err = enic_set_nic_cfg(enic,
-		rss_default_cpu, rss_hash_type,
-		rss_hash_bits, rss_base_cpu,
-		rss_enable, tso_ipid_split_en,
-		ig_vlan_strip_en);
+	err = enic_set_niccfg(enic);
 	if (err) {
 		printk(KERN_ERR PFX
 			"Failed to config nic, aborting.\n");
@@ -1858,7 +1866,6 @@ static int __devinit enic_probe(struct p
 	if (using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-
 	enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
 
 	enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR;
@@ -1870,7 +1877,6 @@ static int __devinit enic_probe(struct p
 	enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE;
 	enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
 
-
 	err = register_netdev(netdev);
 	if (err) {
 		printk(KERN_ERR PFX
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_dev.c linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_dev.c
--- linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_dev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_dev.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,6 +34,9 @@ struct vnic_res {
 	unsigned int count;
 };
 
+#define VNIC_DEV_CAP_INIT	0x0001
+#define VNIC_DEV_CAP_PERBI	0x0002
+
 struct vnic_dev {
 	void *priv;
 	struct pci_dev *pdev;
@@ -50,6 +53,7 @@ struct vnic_dev {
 	dma_addr_t stats_pa;
 	struct vnic_devcmd_fw_info *fw_info;
 	dma_addr_t fw_info_pa;
+	u32 cap_flags;
 };
 
 #define VNIC_MAX_RES_HDR_SIZE \
@@ -575,9 +579,9 @@ int vnic_dev_init(struct vnic_dev *vdev,
 {
 	u64 a0 = (u32)arg, a1 = 0;
 	int wait = 1000;
-        int r = 0;
+	int r = 0;
 
-	if (vnic_dev_capable(vdev, CMD_INIT))
+	if (vdev->cap_flags & VNIC_DEV_CAP_INIT)
 		r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
 	else {
 		vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
@@ -587,8 +591,8 @@ int vnic_dev_init(struct vnic_dev *vdev,
 			vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
 			vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
 		}
-        }
-        return r;
+	}
+	return r;
 }
 
 int vnic_dev_link_status(struct vnic_dev *vdev)
@@ -626,6 +630,22 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev)
 	return vdev->notify_copy.mtu;
 }
 
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)
+{
+	if (!vnic_dev_notify_ready(vdev))
+		return 0;
+
+	return vdev->notify_copy.link_down_cnt;
+}
+
+u32 vnic_dev_notify_status(struct vnic_dev *vdev)
+{
+	if (!vnic_dev_notify_ready(vdev))
+		return 0;
+
+	return vdev->notify_copy.status;
+}
+
 void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
 	enum vnic_dev_intr_mode intr_mode)
 {
@@ -682,6 +702,11 @@ struct vnic_dev *vnic_dev_register(struc
 	if (!vdev->devcmd)
 		goto err_out;
 
+	vdev->cap_flags = 0;
+
+	if (vnic_dev_capable(vdev, CMD_INIT))
+		vdev->cap_flags |= VNIC_DEV_CAP_INIT;
+
 	return vdev;
 
 err_out:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_devcmd.h linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_devcmd.h
--- linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_devcmd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_devcmd.h	2009-06-09 23:05:27.000000000 -0400
@@ -191,7 +191,7 @@ enum vnic_devcmd_cmd {
 	CMD_INIT_STATUS		= _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 31),
 
 	/* INT13 API: (u64)a0=paddr to vnic_int13_params struct
-	 *            (u8)a1=INT13_CMD_xxx */
+	 *            (u32)a1=INT13_CMD_xxx */
 	CMD_INT13               = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_FC, 32),
 
 	/* logical uplink enable/disable: (u64)a0: 0/1=disable/enable */
@@ -207,6 +207,11 @@ enum vnic_devcmd_cmd {
 	 * in:  (u32)a0=cmd
 	 * out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */
 	CMD_CAPABILITY		= _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36),
+
+	/* persistent binding info
+	 * in:  (u64)a0=paddr of arg
+	 *      (u32)a1=CMD_PERBI_XXX */
+	CMD_PERBI               = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
 };
 
 /* flags for CMD_OPEN */
@@ -259,6 +264,7 @@ struct vnic_devcmd_notify {
 	u32 status;		/* status bits (see VNIC_STF_*) */
 	u32 error;		/* error code (see ERR_*) for first ERR */
 	u32 link_down_cnt;	/* running count of link down transitions */
+	u32 perbi_rebuild_cnt;	/* running count of perbi rebuilds */
 };
 #define VNIC_STF_FATAL_ERR	0x0001	/* fatal fw error */
 #define VNIC_STF_STD_PAUSE	0x0002	/* standard link-level pause on */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_dev.h linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_dev.h
--- linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_dev.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_dev.h	2009-06-09 23:05:27.000000000 -0400
@@ -102,6 +102,8 @@ int vnic_dev_link_status(struct vnic_dev
 u32 vnic_dev_port_speed(struct vnic_dev *vdev);
 u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
 u32 vnic_dev_mtu(struct vnic_dev *vdev);
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev);
+u32 vnic_dev_notify_status(struct vnic_dev *vdev);
 int vnic_dev_close(struct vnic_dev *vdev);
 int vnic_dev_enable(struct vnic_dev *vdev);
 int vnic_dev_disable(struct vnic_dev *vdev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_intr.h linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_intr.h
--- linux-libre-2.6.29-gnu1/drivers/net/enic/vnic_intr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/enic/vnic_intr.h	2009-06-09 23:05:27.000000000 -0400
@@ -76,6 +76,20 @@ static inline void vnic_intr_return_cred
 	iowrite32(int_credit_return, &intr->ctrl->int_credit_return);
 }
 
+static inline unsigned int vnic_intr_credits(struct vnic_intr *intr)
+{
+	return ioread32(&intr->ctrl->int_credits);
+}
+
+static inline void vnic_intr_return_all_credits(struct vnic_intr *intr)
+{
+	unsigned int credits = vnic_intr_credits(intr);
+	int unmask = 1;
+	int reset_timer = 1;
+
+	vnic_intr_return_credits(intr, credits, unmask, reset_timer);
+}
+
 static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
 {
 	/* read PBA without clearing */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/epic100.c linux-libre-2.6.30-gnu1/drivers/net/epic100.c
--- linux-libre-2.6.29-gnu1/drivers/net/epic100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/epic100.c	2009-06-09 23:05:27.000000000 -0400
@@ -1114,9 +1114,9 @@ static irqreturn_t epic_interrupt(int ir
 
 	if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) {
 		spin_lock(&ep->napi_lock);
-		if (netif_rx_schedule_prep(&ep->napi)) {
+		if (napi_schedule_prep(&ep->napi)) {
 			epic_napi_irq_off(dev, ep);
-			__netif_rx_schedule(&ep->napi);
+			__napi_schedule(&ep->napi);
 		} else
 			ep->reschedule_in_poll++;
 		spin_unlock(&ep->napi_lock);
@@ -1293,7 +1293,7 @@ rx_action:
 
 		more = ep->reschedule_in_poll;
 		if (!more) {
-			__netif_rx_complete(napi);
+			__napi_complete(napi);
 			outl(EpicNapiEvent, ioaddr + INTSTAT);
 			epic_napi_irq_on(dev, ep);
 		} else
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/eql.c linux-libre-2.6.30-gnu1/drivers/net/eql.c
--- linux-libre-2.6.29-gnu1/drivers/net/eql.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/eql.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,7 +159,7 @@ static void eql_timer(unsigned long para
 	add_timer(&eql->timer);
 }
 
-static char version[] __initdata =
+static const char version[] __initconst =
 	"Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
 
 static const struct net_device_ops eql_netdev_ops = {
@@ -542,6 +542,8 @@ static int eql_s_slave_cfg(struct net_de
 	}
 	spin_unlock_bh(&eql->queue.lock);
 
+	dev_put(slave_dev);
+
 	return ret;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/eth16i.c linux-libre-2.6.30-gnu1/drivers/net/eth16i.c
--- linux-libre-2.6.29-gnu1/drivers/net/eth16i.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/eth16i.c	2009-06-09 23:05:27.000000000 -0400
@@ -475,6 +475,17 @@ out:
 }
 #endif
 
+static const struct net_device_ops eth16i_netdev_ops = {
+	.ndo_open               = eth16i_open,
+	.ndo_stop               = eth16i_close,
+	.ndo_start_xmit    	= eth16i_tx,
+	.ndo_set_multicast_list = eth16i_multicast,
+	.ndo_tx_timeout 	= eth16i_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
 {
 	struct eth16i_local *lp = netdev_priv(dev);
@@ -549,12 +560,7 @@ static int __init eth16i_probe1(struct n
 	BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
 
 	/* Initialize the device structure */
-	memset(lp, 0, sizeof(struct eth16i_local));
-	dev->open               = eth16i_open;
-	dev->stop               = eth16i_close;
-	dev->hard_start_xmit    = eth16i_tx;
-	dev->set_multicast_list = eth16i_multicast;
-	dev->tx_timeout 	= eth16i_timeout;
+	dev->netdev_ops         = &eth16i_netdev_ops;
 	dev->watchdog_timeo	= TX_TIMEOUT;
 	spin_lock_init(&lp->lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ethoc.c linux-libre-2.6.30-gnu1/drivers/net/ethoc.c
--- linux-libre-2.6.29-gnu1/drivers/net/ethoc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/ethoc.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1112 @@
+/*
+ * linux/drivers/net/ethoc.c
+ *
+ * Copyright (C) 2007-2008 Avionic Design Development GmbH
+ * Copyright (C) 2008-2009 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by Thierry Reding <thierry.reding@avionic-design.de>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/crc32.h>
+#include <linux/io.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <net/ethoc.h>
+
+/* register offsets */
+#define	MODER		0x00
+#define	INT_SOURCE	0x04
+#define	INT_MASK	0x08
+#define	IPGT		0x0c
+#define	IPGR1		0x10
+#define	IPGR2		0x14
+#define	PACKETLEN	0x18
+#define	COLLCONF	0x1c
+#define	TX_BD_NUM	0x20
+#define	CTRLMODER	0x24
+#define	MIIMODER	0x28
+#define	MIICOMMAND	0x2c
+#define	MIIADDRESS	0x30
+#define	MIITX_DATA	0x34
+#define	MIIRX_DATA	0x38
+#define	MIISTATUS	0x3c
+#define	MAC_ADDR0	0x40
+#define	MAC_ADDR1	0x44
+#define	ETH_HASH0	0x48
+#define	ETH_HASH1	0x4c
+#define	ETH_TXCTRL	0x50
+
+/* mode register */
+#define	MODER_RXEN	(1 <<  0) /* receive enable */
+#define	MODER_TXEN	(1 <<  1) /* transmit enable */
+#define	MODER_NOPRE	(1 <<  2) /* no preamble */
+#define	MODER_BRO	(1 <<  3) /* broadcast address */
+#define	MODER_IAM	(1 <<  4) /* individual address mode */
+#define	MODER_PRO	(1 <<  5) /* promiscuous mode */
+#define	MODER_IFG	(1 <<  6) /* interframe gap for incoming frames */
+#define	MODER_LOOP	(1 <<  7) /* loopback */
+#define	MODER_NBO	(1 <<  8) /* no back-off */
+#define	MODER_EDE	(1 <<  9) /* excess defer enable */
+#define	MODER_FULLD	(1 << 10) /* full duplex */
+#define	MODER_RESET	(1 << 11) /* FIXME: reset (undocumented) */
+#define	MODER_DCRC	(1 << 12) /* delayed CRC enable */
+#define	MODER_CRC	(1 << 13) /* CRC enable */
+#define	MODER_HUGE	(1 << 14) /* huge packets enable */
+#define	MODER_PAD	(1 << 15) /* padding enabled */
+#define	MODER_RSM	(1 << 16) /* receive small packets */
+
+/* interrupt source and mask registers */
+#define	INT_MASK_TXF	(1 << 0) /* transmit frame */
+#define	INT_MASK_TXE	(1 << 1) /* transmit error */
+#define	INT_MASK_RXF	(1 << 2) /* receive frame */
+#define	INT_MASK_RXE	(1 << 3) /* receive error */
+#define	INT_MASK_BUSY	(1 << 4)
+#define	INT_MASK_TXC	(1 << 5) /* transmit control frame */
+#define	INT_MASK_RXC	(1 << 6) /* receive control frame */
+
+#define	INT_MASK_TX	(INT_MASK_TXF | INT_MASK_TXE)
+#define	INT_MASK_RX	(INT_MASK_RXF | INT_MASK_RXE)
+
+#define	INT_MASK_ALL ( \
+		INT_MASK_TXF | INT_MASK_TXE | \
+		INT_MASK_RXF | INT_MASK_RXE | \
+		INT_MASK_TXC | INT_MASK_RXC | \
+		INT_MASK_BUSY \
+	)
+
+/* packet length register */
+#define	PACKETLEN_MIN(min)		(((min) & 0xffff) << 16)
+#define	PACKETLEN_MAX(max)		(((max) & 0xffff) <<  0)
+#define	PACKETLEN_MIN_MAX(min, max)	(PACKETLEN_MIN(min) | \
+					PACKETLEN_MAX(max))
+
+/* transmit buffer number register */
+#define	TX_BD_NUM_VAL(x)	(((x) <= 0x80) ? (x) : 0x80)
+
+/* control module mode register */
+#define	CTRLMODER_PASSALL	(1 << 0) /* pass all receive frames */
+#define	CTRLMODER_RXFLOW	(1 << 1) /* receive control flow */
+#define	CTRLMODER_TXFLOW	(1 << 2) /* transmit control flow */
+
+/* MII mode register */
+#define	MIIMODER_CLKDIV(x)	((x) & 0xfe) /* needs to be an even number */
+#define	MIIMODER_NOPRE		(1 << 8) /* no preamble */
+
+/* MII command register */
+#define	MIICOMMAND_SCAN		(1 << 0) /* scan status */
+#define	MIICOMMAND_READ		(1 << 1) /* read status */
+#define	MIICOMMAND_WRITE	(1 << 2) /* write control data */
+
+/* MII address register */
+#define	MIIADDRESS_FIAD(x)		(((x) & 0x1f) << 0)
+#define	MIIADDRESS_RGAD(x)		(((x) & 0x1f) << 8)
+#define	MIIADDRESS_ADDR(phy, reg)	(MIIADDRESS_FIAD(phy) | \
+					MIIADDRESS_RGAD(reg))
+
+/* MII transmit data register */
+#define	MIITX_DATA_VAL(x)	((x) & 0xffff)
+
+/* MII receive data register */
+#define	MIIRX_DATA_VAL(x)	((x) & 0xffff)
+
+/* MII status register */
+#define	MIISTATUS_LINKFAIL	(1 << 0)
+#define	MIISTATUS_BUSY		(1 << 1)
+#define	MIISTATUS_INVALID	(1 << 2)
+
+/* TX buffer descriptor */
+#define	TX_BD_CS		(1 <<  0) /* carrier sense lost */
+#define	TX_BD_DF		(1 <<  1) /* defer indication */
+#define	TX_BD_LC		(1 <<  2) /* late collision */
+#define	TX_BD_RL		(1 <<  3) /* retransmission limit */
+#define	TX_BD_RETRY_MASK	(0x00f0)
+#define	TX_BD_RETRY(x)		(((x) & 0x00f0) >>  4)
+#define	TX_BD_UR		(1 <<  8) /* transmitter underrun */
+#define	TX_BD_CRC		(1 << 11) /* TX CRC enable */
+#define	TX_BD_PAD		(1 << 12) /* pad enable for short packets */
+#define	TX_BD_WRAP		(1 << 13)
+#define	TX_BD_IRQ		(1 << 14) /* interrupt request enable */
+#define	TX_BD_READY		(1 << 15) /* TX buffer ready */
+#define	TX_BD_LEN(x)		(((x) & 0xffff) << 16)
+#define	TX_BD_LEN_MASK		(0xffff << 16)
+
+#define	TX_BD_STATS		(TX_BD_CS | TX_BD_DF | TX_BD_LC | \
+				TX_BD_RL | TX_BD_RETRY_MASK | TX_BD_UR)
+
+/* RX buffer descriptor */
+#define	RX_BD_LC	(1 <<  0) /* late collision */
+#define	RX_BD_CRC	(1 <<  1) /* RX CRC error */
+#define	RX_BD_SF	(1 <<  2) /* short frame */
+#define	RX_BD_TL	(1 <<  3) /* too long */
+#define	RX_BD_DN	(1 <<  4) /* dribble nibble */
+#define	RX_BD_IS	(1 <<  5) /* invalid symbol */
+#define	RX_BD_OR	(1 <<  6) /* receiver overrun */
+#define	RX_BD_MISS	(1 <<  7)
+#define	RX_BD_CF	(1 <<  8) /* control frame */
+#define	RX_BD_WRAP	(1 << 13)
+#define	RX_BD_IRQ	(1 << 14) /* interrupt request enable */
+#define	RX_BD_EMPTY	(1 << 15)
+#define	RX_BD_LEN(x)	(((x) & 0xffff) << 16)
+
+#define	RX_BD_STATS	(RX_BD_LC | RX_BD_CRC | RX_BD_SF | RX_BD_TL | \
+			RX_BD_DN | RX_BD_IS | RX_BD_OR | RX_BD_MISS)
+
+#define	ETHOC_BUFSIZ		1536
+#define	ETHOC_ZLEN		64
+#define	ETHOC_BD_BASE		0x400
+#define	ETHOC_TIMEOUT		(HZ / 2)
+#define	ETHOC_MII_TIMEOUT	(1 + (HZ / 5))
+
+/**
+ * struct ethoc - driver-private device structure
+ * @iobase:	pointer to I/O memory region
+ * @membase:	pointer to buffer memory region
+ * @num_tx:	number of send buffers
+ * @cur_tx:	last send buffer written
+ * @dty_tx:	last buffer actually sent
+ * @num_rx:	number of receive buffers
+ * @cur_rx:	current receive buffer
+ * @netdev:	pointer to network device structure
+ * @napi:	NAPI structure
+ * @stats:	network device statistics
+ * @msg_enable:	device state flags
+ * @rx_lock:	receive lock
+ * @lock:	device lock
+ * @phy:	attached PHY
+ * @mdio:	MDIO bus for PHY access
+ * @phy_id:	address of attached PHY
+ */
+struct ethoc {
+	void __iomem *iobase;
+	void __iomem *membase;
+
+	unsigned int num_tx;
+	unsigned int cur_tx;
+	unsigned int dty_tx;
+
+	unsigned int num_rx;
+	unsigned int cur_rx;
+
+	struct net_device *netdev;
+	struct napi_struct napi;
+	struct net_device_stats stats;
+	u32 msg_enable;
+
+	spinlock_t rx_lock;
+	spinlock_t lock;
+
+	struct phy_device *phy;
+	struct mii_bus *mdio;
+	s8 phy_id;
+};
+
+/**
+ * struct ethoc_bd - buffer descriptor
+ * @stat:	buffer statistics
+ * @addr:	physical memory address
+ */
+struct ethoc_bd {
+	u32 stat;
+	u32 addr;
+};
+
+static u32 ethoc_read(struct ethoc *dev, loff_t offset)
+{
+	return ioread32(dev->iobase + offset);
+}
+
+static void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
+{
+	iowrite32(data, dev->iobase + offset);
+}
+
+static void ethoc_read_bd(struct ethoc *dev, int index, struct ethoc_bd *bd)
+{
+	loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+	bd->stat = ethoc_read(dev, offset + 0);
+	bd->addr = ethoc_read(dev, offset + 4);
+}
+
+static void ethoc_write_bd(struct ethoc *dev, int index,
+		const struct ethoc_bd *bd)
+{
+	loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+	ethoc_write(dev, offset + 0, bd->stat);
+	ethoc_write(dev, offset + 4, bd->addr);
+}
+
+static void ethoc_enable_irq(struct ethoc *dev, u32 mask)
+{
+	u32 imask = ethoc_read(dev, INT_MASK);
+	imask |= mask;
+	ethoc_write(dev, INT_MASK, imask);
+}
+
+static void ethoc_disable_irq(struct ethoc *dev, u32 mask)
+{
+	u32 imask = ethoc_read(dev, INT_MASK);
+	imask &= ~mask;
+	ethoc_write(dev, INT_MASK, imask);
+}
+
+static void ethoc_ack_irq(struct ethoc *dev, u32 mask)
+{
+	ethoc_write(dev, INT_SOURCE, mask);
+}
+
+static void ethoc_enable_rx_and_tx(struct ethoc *dev)
+{
+	u32 mode = ethoc_read(dev, MODER);
+	mode |= MODER_RXEN | MODER_TXEN;
+	ethoc_write(dev, MODER, mode);
+}
+
+static void ethoc_disable_rx_and_tx(struct ethoc *dev)
+{
+	u32 mode = ethoc_read(dev, MODER);
+	mode &= ~(MODER_RXEN | MODER_TXEN);
+	ethoc_write(dev, MODER, mode);
+}
+
+static int ethoc_init_ring(struct ethoc *dev)
+{
+	struct ethoc_bd bd;
+	int i;
+
+	dev->cur_tx = 0;
+	dev->dty_tx = 0;
+	dev->cur_rx = 0;
+
+	/* setup transmission buffers */
+	bd.addr = 0;
+	bd.stat = TX_BD_IRQ | TX_BD_CRC;
+
+	for (i = 0; i < dev->num_tx; i++) {
+		if (i == dev->num_tx - 1)
+			bd.stat |= TX_BD_WRAP;
+
+		ethoc_write_bd(dev, i, &bd);
+		bd.addr += ETHOC_BUFSIZ;
+	}
+
+	bd.addr = dev->num_tx * ETHOC_BUFSIZ;
+	bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
+
+	for (i = 0; i < dev->num_rx; i++) {
+		if (i == dev->num_rx - 1)
+			bd.stat |= RX_BD_WRAP;
+
+		ethoc_write_bd(dev, dev->num_tx + i, &bd);
+		bd.addr += ETHOC_BUFSIZ;
+	}
+
+	return 0;
+}
+
+static int ethoc_reset(struct ethoc *dev)
+{
+	u32 mode;
+
+	/* TODO: reset controller? */
+
+	ethoc_disable_rx_and_tx(dev);
+
+	/* TODO: setup registers */
+
+	/* enable FCS generation and automatic padding */
+	mode = ethoc_read(dev, MODER);
+	mode |= MODER_CRC | MODER_PAD;
+	ethoc_write(dev, MODER, mode);
+
+	/* set full-duplex mode */
+	mode = ethoc_read(dev, MODER);
+	mode |= MODER_FULLD;
+	ethoc_write(dev, MODER, mode);
+	ethoc_write(dev, IPGT, 0x15);
+
+	ethoc_ack_irq(dev, INT_MASK_ALL);
+	ethoc_enable_irq(dev, INT_MASK_ALL);
+	ethoc_enable_rx_and_tx(dev);
+	return 0;
+}
+
+static unsigned int ethoc_update_rx_stats(struct ethoc *dev,
+		struct ethoc_bd *bd)
+{
+	struct net_device *netdev = dev->netdev;
+	unsigned int ret = 0;
+
+	if (bd->stat & RX_BD_TL) {
+		dev_err(&netdev->dev, "RX: frame too long\n");
+		dev->stats.rx_length_errors++;
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_SF) {
+		dev_err(&netdev->dev, "RX: frame too short\n");
+		dev->stats.rx_length_errors++;
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_DN) {
+		dev_err(&netdev->dev, "RX: dribble nibble\n");
+		dev->stats.rx_frame_errors++;
+	}
+
+	if (bd->stat & RX_BD_CRC) {
+		dev_err(&netdev->dev, "RX: wrong CRC\n");
+		dev->stats.rx_crc_errors++;
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_OR) {
+		dev_err(&netdev->dev, "RX: overrun\n");
+		dev->stats.rx_over_errors++;
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_MISS)
+		dev->stats.rx_missed_errors++;
+
+	if (bd->stat & RX_BD_LC) {
+		dev_err(&netdev->dev, "RX: late collision\n");
+		dev->stats.collisions++;
+		ret++;
+	}
+
+	return ret;
+}
+
+static int ethoc_rx(struct net_device *dev, int limit)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	int count;
+
+	for (count = 0; count < limit; ++count) {
+		unsigned int entry;
+		struct ethoc_bd bd;
+
+		entry = priv->num_tx + (priv->cur_rx % priv->num_rx);
+		ethoc_read_bd(priv, entry, &bd);
+		if (bd.stat & RX_BD_EMPTY)
+			break;
+
+		if (ethoc_update_rx_stats(priv, &bd) == 0) {
+			int size = bd.stat >> 16;
+			struct sk_buff *skb = netdev_alloc_skb(dev, size);
+			if (likely(skb)) {
+				void *src = priv->membase + bd.addr;
+				memcpy_fromio(skb_put(skb, size), src, size);
+				skb->protocol = eth_type_trans(skb, dev);
+				dev->last_rx = jiffies;
+				priv->stats.rx_packets++;
+				priv->stats.rx_bytes += size;
+				netif_receive_skb(skb);
+			} else {
+				if (net_ratelimit())
+					dev_warn(&dev->dev, "low on memory - "
+							"packet dropped\n");
+
+				priv->stats.rx_dropped++;
+				break;
+			}
+		}
+
+		/* clear the buffer descriptor so it can be reused */
+		bd.stat &= ~RX_BD_STATS;
+		bd.stat |=  RX_BD_EMPTY;
+		ethoc_write_bd(priv, entry, &bd);
+		priv->cur_rx++;
+	}
+
+	return count;
+}
+
+static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd)
+{
+	struct net_device *netdev = dev->netdev;
+
+	if (bd->stat & TX_BD_LC) {
+		dev_err(&netdev->dev, "TX: late collision\n");
+		dev->stats.tx_window_errors++;
+	}
+
+	if (bd->stat & TX_BD_RL) {
+		dev_err(&netdev->dev, "TX: retransmit limit\n");
+		dev->stats.tx_aborted_errors++;
+	}
+
+	if (bd->stat & TX_BD_UR) {
+		dev_err(&netdev->dev, "TX: underrun\n");
+		dev->stats.tx_fifo_errors++;
+	}
+
+	if (bd->stat & TX_BD_CS) {
+		dev_err(&netdev->dev, "TX: carrier sense lost\n");
+		dev->stats.tx_carrier_errors++;
+	}
+
+	if (bd->stat & TX_BD_STATS)
+		dev->stats.tx_errors++;
+
+	dev->stats.collisions += (bd->stat >> 4) & 0xf;
+	dev->stats.tx_bytes += bd->stat >> 16;
+	dev->stats.tx_packets++;
+	return 0;
+}
+
+static void ethoc_tx(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+
+	spin_lock(&priv->lock);
+
+	while (priv->dty_tx != priv->cur_tx) {
+		unsigned int entry = priv->dty_tx % priv->num_tx;
+		struct ethoc_bd bd;
+
+		ethoc_read_bd(priv, entry, &bd);
+		if (bd.stat & TX_BD_READY)
+			break;
+
+		entry = (++priv->dty_tx) % priv->num_tx;
+		(void)ethoc_update_tx_stats(priv, &bd);
+	}
+
+	if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2))
+		netif_wake_queue(dev);
+
+	ethoc_ack_irq(priv, INT_MASK_TX);
+	spin_unlock(&priv->lock);
+}
+
+static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct ethoc *priv = netdev_priv(dev);
+	u32 pending;
+
+	ethoc_disable_irq(priv, INT_MASK_ALL);
+	pending = ethoc_read(priv, INT_SOURCE);
+	if (unlikely(pending == 0)) {
+		ethoc_enable_irq(priv, INT_MASK_ALL);
+		return IRQ_NONE;
+	}
+
+	ethoc_ack_irq(priv, INT_MASK_ALL);
+
+	if (pending & INT_MASK_BUSY) {
+		dev_err(&dev->dev, "packet dropped\n");
+		priv->stats.rx_dropped++;
+	}
+
+	if (pending & INT_MASK_RX) {
+		if (napi_schedule_prep(&priv->napi))
+			__napi_schedule(&priv->napi);
+	} else {
+		ethoc_enable_irq(priv, INT_MASK_RX);
+	}
+
+	if (pending & INT_MASK_TX)
+		ethoc_tx(dev);
+
+	ethoc_enable_irq(priv, INT_MASK_ALL & ~INT_MASK_RX);
+	return IRQ_HANDLED;
+}
+
+static int ethoc_get_mac_address(struct net_device *dev, void *addr)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	u8 *mac = (u8 *)addr;
+	u32 reg;
+
+	reg = ethoc_read(priv, MAC_ADDR0);
+	mac[2] = (reg >> 24) & 0xff;
+	mac[3] = (reg >> 16) & 0xff;
+	mac[4] = (reg >>  8) & 0xff;
+	mac[5] = (reg >>  0) & 0xff;
+
+	reg = ethoc_read(priv, MAC_ADDR1);
+	mac[0] = (reg >>  8) & 0xff;
+	mac[1] = (reg >>  0) & 0xff;
+
+	return 0;
+}
+
+static int ethoc_poll(struct napi_struct *napi, int budget)
+{
+	struct ethoc *priv = container_of(napi, struct ethoc, napi);
+	int work_done = 0;
+
+	work_done = ethoc_rx(priv->netdev, budget);
+	if (work_done < budget) {
+		ethoc_enable_irq(priv, INT_MASK_RX);
+		napi_complete(napi);
+	}
+
+	return work_done;
+}
+
+static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+	unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
+	struct ethoc *priv = bus->priv;
+
+	ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
+	ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
+
+	while (time_before(jiffies, timeout)) {
+		u32 status = ethoc_read(priv, MIISTATUS);
+		if (!(status & MIISTATUS_BUSY)) {
+			u32 data = ethoc_read(priv, MIIRX_DATA);
+			/* reset MII command register */
+			ethoc_write(priv, MIICOMMAND, 0);
+			return data;
+		}
+
+		schedule();
+	}
+
+	return -EBUSY;
+}
+
+static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+	unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
+	struct ethoc *priv = bus->priv;
+
+	ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
+	ethoc_write(priv, MIITX_DATA, val);
+	ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
+
+	while (time_before(jiffies, timeout)) {
+		u32 stat = ethoc_read(priv, MIISTATUS);
+		if (!(stat & MIISTATUS_BUSY))
+			return 0;
+
+		schedule();
+	}
+
+	return -EBUSY;
+}
+
+static int ethoc_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+static void ethoc_mdio_poll(struct net_device *dev)
+{
+}
+
+static int ethoc_mdio_probe(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	struct phy_device *phy;
+	int i;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++) {
+		phy = priv->mdio->phy_map[i];
+		if (phy) {
+			if (priv->phy_id != -1) {
+				/* attach to specified PHY */
+				if (priv->phy_id == phy->addr)
+					break;
+			} else {
+				/* autoselect PHY if none was specified */
+				if (phy->addr != 0)
+					break;
+			}
+		}
+	}
+
+	if (!phy) {
+		dev_err(&dev->dev, "no PHY found\n");
+		return -ENXIO;
+	}
+
+	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");
+		return PTR_ERR(phy);
+	}
+
+	priv->phy = phy;
+	return 0;
+}
+
+static int ethoc_open(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	unsigned int min_tx = 2;
+	unsigned int num_bd;
+	int ret;
+
+	ret = request_irq(dev->irq, ethoc_interrupt, IRQF_SHARED,
+			dev->name, dev);
+	if (ret)
+		return ret;
+
+	/* calculate the number of TX/RX buffers */
+	num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ;
+	priv->num_tx = min(min_tx, num_bd / 4);
+	priv->num_rx = num_bd - priv->num_tx;
+	ethoc_write(priv, TX_BD_NUM, priv->num_tx);
+
+	ethoc_init_ring(priv);
+	ethoc_reset(priv);
+
+	if (netif_queue_stopped(dev)) {
+		dev_dbg(&dev->dev, " resuming queue\n");
+		netif_wake_queue(dev);
+	} else {
+		dev_dbg(&dev->dev, " starting queue\n");
+		netif_start_queue(dev);
+	}
+
+	phy_start(priv->phy);
+	napi_enable(&priv->napi);
+
+	if (netif_msg_ifup(priv)) {
+		dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
+				dev->base_addr, dev->mem_start, dev->mem_end);
+	}
+
+	return 0;
+}
+
+static int ethoc_stop(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+
+	napi_disable(&priv->napi);
+
+	if (priv->phy)
+		phy_stop(priv->phy);
+
+	ethoc_disable_rx_and_tx(priv);
+	free_irq(dev->irq, dev);
+
+	if (!netif_queue_stopped(dev))
+		netif_stop_queue(dev);
+
+	return 0;
+}
+
+static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	struct mii_ioctl_data *mdio = if_mii(ifr);
+	struct phy_device *phy = NULL;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	if (cmd != SIOCGMIIPHY) {
+		if (mdio->phy_id >= PHY_MAX_ADDR)
+			return -ERANGE;
+
+		phy = priv->mdio->phy_map[mdio->phy_id];
+		if (!phy)
+			return -ENODEV;
+	} else {
+		phy = priv->phy;
+	}
+
+	return phy_mii_ioctl(phy, mdio, cmd);
+}
+
+static int ethoc_config(struct net_device *dev, struct ifmap *map)
+{
+	return -ENOSYS;
+}
+
+static int ethoc_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	u8 *mac = (u8 *)addr;
+
+	ethoc_write(priv, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
+				     (mac[4] <<  8) | (mac[5] <<  0));
+	ethoc_write(priv, MAC_ADDR1, (mac[0] <<  8) | (mac[1] <<  0));
+
+	return 0;
+}
+
+static void ethoc_set_multicast_list(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	u32 mode = ethoc_read(priv, MODER);
+	struct dev_mc_list *mc = NULL;
+	u32 hash[2] = { 0, 0 };
+
+	/* set loopback mode if requested */
+	if (dev->flags & IFF_LOOPBACK)
+		mode |=  MODER_LOOP;
+	else
+		mode &= ~MODER_LOOP;
+
+	/* receive broadcast frames if requested */
+	if (dev->flags & IFF_BROADCAST)
+		mode &= ~MODER_BRO;
+	else
+		mode |=  MODER_BRO;
+
+	/* enable promiscuous mode if requested */
+	if (dev->flags & IFF_PROMISC)
+		mode |=  MODER_PRO;
+	else
+		mode &= ~MODER_PRO;
+
+	ethoc_write(priv, MODER, mode);
+
+	/* receive multicast frames */
+	if (dev->flags & IFF_ALLMULTI) {
+		hash[0] = 0xffffffff;
+		hash[1] = 0xffffffff;
+	} else {
+		for (mc = dev->mc_list; mc; mc = mc->next) {
+			u32 crc = ether_crc(mc->dmi_addrlen, mc->dmi_addr);
+			int bit = (crc >> 26) & 0x3f;
+			hash[bit >> 5] |= 1 << (bit & 0x1f);
+		}
+	}
+
+	ethoc_write(priv, ETH_HASH0, hash[0]);
+	ethoc_write(priv, ETH_HASH1, hash[1]);
+}
+
+static int ethoc_change_mtu(struct net_device *dev, int new_mtu)
+{
+	return -ENOSYS;
+}
+
+static void ethoc_tx_timeout(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	u32 pending = ethoc_read(priv, INT_SOURCE);
+	if (likely(pending))
+		ethoc_interrupt(dev->irq, dev);
+}
+
+static struct net_device_stats *ethoc_stats(struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	return &priv->stats;
+}
+
+static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ethoc *priv = netdev_priv(dev);
+	struct ethoc_bd bd;
+	unsigned int entry;
+	void *dest;
+
+	if (unlikely(skb->len > ETHOC_BUFSIZ)) {
+		priv->stats.tx_errors++;
+		return -EMSGSIZE;
+	}
+
+	entry = priv->cur_tx % priv->num_tx;
+	spin_lock_irq(&priv->lock);
+	priv->cur_tx++;
+
+	ethoc_read_bd(priv, entry, &bd);
+	if (unlikely(skb->len < ETHOC_ZLEN))
+		bd.stat |=  TX_BD_PAD;
+	else
+		bd.stat &= ~TX_BD_PAD;
+
+	dest = priv->membase + bd.addr;
+	memcpy_toio(dest, skb->data, skb->len);
+
+	bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
+	bd.stat |= TX_BD_LEN(skb->len);
+	ethoc_write_bd(priv, entry, &bd);
+
+	bd.stat |= TX_BD_READY;
+	ethoc_write_bd(priv, entry, &bd);
+
+	if (priv->cur_tx == (priv->dty_tx + priv->num_tx)) {
+		dev_dbg(&dev->dev, "stopping queue\n");
+		netif_stop_queue(dev);
+	}
+
+	dev->trans_start = jiffies;
+	dev_kfree_skb(skb);
+
+	spin_unlock_irq(&priv->lock);
+	return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ethoc_netdev_ops = {
+	.ndo_open = ethoc_open,
+	.ndo_stop = ethoc_stop,
+	.ndo_do_ioctl = ethoc_ioctl,
+	.ndo_set_config = ethoc_config,
+	.ndo_set_mac_address = ethoc_set_mac_address,
+	.ndo_set_multicast_list = ethoc_set_multicast_list,
+	.ndo_change_mtu = ethoc_change_mtu,
+	.ndo_tx_timeout = ethoc_tx_timeout,
+	.ndo_get_stats = ethoc_stats,
+	.ndo_start_xmit = ethoc_start_xmit,
+};
+
+/**
+ * ethoc_probe() - initialize OpenCores ethernet MAC
+ * pdev:	platform device
+ */
+static int ethoc_probe(struct platform_device *pdev)
+{
+	struct net_device *netdev = NULL;
+	struct resource *res = NULL;
+	struct resource *mmio = NULL;
+	struct resource *mem = NULL;
+	struct ethoc *priv = NULL;
+	unsigned int phy;
+	int ret = 0;
+
+	/* allocate networking device */
+	netdev = alloc_etherdev(sizeof(struct ethoc));
+	if (!netdev) {
+		dev_err(&pdev->dev, "cannot allocate network device\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+	platform_set_drvdata(pdev, netdev);
+
+	/* obtain I/O memory space */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot obtain I/O memory space\n");
+		ret = -ENXIO;
+		goto free;
+	}
+
+	mmio = devm_request_mem_region(&pdev->dev, res->start,
+			res->end - res->start + 1, res->name);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot request I/O memory space\n");
+		ret = -ENXIO;
+		goto free;
+	}
+
+	netdev->base_addr = mmio->start;
+
+	/* obtain buffer memory space */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot obtain memory space\n");
+		ret = -ENXIO;
+		goto free;
+	}
+
+	mem = devm_request_mem_region(&pdev->dev, res->start,
+			res->end - res->start + 1, res->name);
+	if (!mem) {
+		dev_err(&pdev->dev, "cannot request memory space\n");
+		ret = -ENXIO;
+		goto free;
+	}
+
+	netdev->mem_start = mem->start;
+	netdev->mem_end   = mem->end;
+
+	/* obtain device IRQ number */
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot obtain IRQ\n");
+		ret = -ENXIO;
+		goto free;
+	}
+
+	netdev->irq = res->start;
+
+	/* setup driver-private data */
+	priv = netdev_priv(netdev);
+	priv->netdev = netdev;
+
+	priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
+			mmio->end - mmio->start + 1);
+	if (!priv->iobase) {
+		dev_err(&pdev->dev, "cannot remap I/O memory space\n");
+		ret = -ENXIO;
+		goto error;
+	}
+
+	priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start,
+			mem->end - mem->start + 1);
+	if (!priv->membase) {
+		dev_err(&pdev->dev, "cannot remap memory space\n");
+		ret = -ENXIO;
+		goto error;
+	}
+
+	/* Allow the platform setup code to pass in a MAC address. */
+	if (pdev->dev.platform_data) {
+		struct ethoc_platform_data *pdata =
+			(struct ethoc_platform_data *)pdev->dev.platform_data;
+		memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN);
+		priv->phy_id = pdata->phy_id;
+	}
+
+	/* Check that the given MAC address is valid. If it isn't, read the
+	 * current MAC from the controller. */
+	if (!is_valid_ether_addr(netdev->dev_addr))
+		ethoc_get_mac_address(netdev, netdev->dev_addr);
+
+	/* Check the MAC again for validity, if it still isn't choose and
+	 * program a random one. */
+	if (!is_valid_ether_addr(netdev->dev_addr))
+		random_ether_addr(netdev->dev_addr);
+
+	ethoc_set_mac_address(netdev, netdev->dev_addr);
+
+	/* register MII bus */
+	priv->mdio = mdiobus_alloc();
+	if (!priv->mdio) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	priv->mdio->name = "ethoc-mdio";
+	snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%d",
+			priv->mdio->name, pdev->id);
+	priv->mdio->read = ethoc_mdio_read;
+	priv->mdio->write = ethoc_mdio_write;
+	priv->mdio->reset = ethoc_mdio_reset;
+	priv->mdio->priv = priv;
+
+	priv->mdio->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!priv->mdio->irq) {
+		ret = -ENOMEM;
+		goto free_mdio;
+	}
+
+	for (phy = 0; phy < PHY_MAX_ADDR; phy++)
+		priv->mdio->irq[phy] = PHY_POLL;
+
+	ret = mdiobus_register(priv->mdio);
+	if (ret) {
+		dev_err(&netdev->dev, "failed to register MDIO bus\n");
+		goto free_mdio;
+	}
+
+	ret = ethoc_mdio_probe(netdev);
+	if (ret) {
+		dev_err(&netdev->dev, "failed to probe MDIO bus\n");
+		goto error;
+	}
+
+	ether_setup(netdev);
+
+	/* setup the net_device structure */
+	netdev->netdev_ops = &ethoc_netdev_ops;
+	netdev->watchdog_timeo = ETHOC_TIMEOUT;
+	netdev->features |= 0;
+
+	/* setup NAPI */
+	memset(&priv->napi, 0, sizeof(priv->napi));
+	netif_napi_add(netdev, &priv->napi, ethoc_poll, 64);
+
+	spin_lock_init(&priv->rx_lock);
+	spin_lock_init(&priv->lock);
+
+	ret = register_netdev(netdev);
+	if (ret < 0) {
+		dev_err(&netdev->dev, "failed to register interface\n");
+		goto error;
+	}
+
+	goto out;
+
+error:
+	mdiobus_unregister(priv->mdio);
+free_mdio:
+	kfree(priv->mdio->irq);
+	mdiobus_free(priv->mdio);
+free:
+	free_netdev(netdev);
+out:
+	return ret;
+}
+
+/**
+ * ethoc_remove() - shutdown OpenCores ethernet MAC
+ * @pdev:	platform device
+ */
+static int ethoc_remove(struct platform_device *pdev)
+{
+	struct net_device *netdev = platform_get_drvdata(pdev);
+	struct ethoc *priv = netdev_priv(netdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (netdev) {
+		phy_disconnect(priv->phy);
+		priv->phy = NULL;
+
+		if (priv->mdio) {
+			mdiobus_unregister(priv->mdio);
+			kfree(priv->mdio->irq);
+			mdiobus_free(priv->mdio);
+		}
+
+		unregister_netdev(netdev);
+		free_netdev(netdev);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ethoc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	return -ENOSYS;
+}
+
+static int ethoc_resume(struct platform_device *pdev)
+{
+	return -ENOSYS;
+}
+#else
+# define ethoc_suspend NULL
+# define ethoc_resume  NULL
+#endif
+
+static struct platform_driver ethoc_driver = {
+	.probe   = ethoc_probe,
+	.remove  = ethoc_remove,
+	.suspend = ethoc_suspend,
+	.resume  = ethoc_resume,
+	.driver  = {
+		.name = "ethoc",
+	},
+};
+
+static int __init ethoc_init(void)
+{
+	return platform_driver_register(&ethoc_driver);
+}
+
+static void __exit ethoc_exit(void)
+{
+	platform_driver_unregister(&ethoc_driver);
+}
+
+module_init(ethoc_init);
+module_exit(ethoc_exit);
+
+MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
+MODULE_DESCRIPTION("OpenCores Ethernet MAC driver");
+MODULE_LICENSE("GPL v2");
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ewrk3.c linux-libre-2.6.30-gnu1/drivers/net/ewrk3.c
--- linux-libre-2.6.29-gnu1/drivers/net/ewrk3.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ewrk3.c	2009-06-09 23:05:27.000000000 -0400
@@ -388,6 +388,18 @@ static int __init ewrk3_probe1(struct ne
 	return err;
 }
 
+static const struct net_device_ops ewrk3_netdev_ops = {
+	.ndo_open		= ewrk3_open,
+	.ndo_start_xmit		= ewrk3_queue_pkt,
+	.ndo_stop		= ewrk3_close,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_do_ioctl		= ewrk3_ioctl,
+	.ndo_tx_timeout		= ewrk3_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init
 ewrk3_hw_init(struct net_device *dev, u_long iobase)
 {
@@ -603,16 +615,11 @@ ewrk3_hw_init(struct net_device *dev, u_
 		printk(version);
 	}
 	/* The EWRK3-specific entries in the device structure. */
-	dev->open = ewrk3_open;
-	dev->hard_start_xmit = ewrk3_queue_pkt;
-	dev->stop = ewrk3_close;
-	dev->set_multicast_list = set_multicast_list;
-	dev->do_ioctl = ewrk3_ioctl;
+	dev->netdev_ops = &ewrk3_netdev_ops;
 	if (lp->adapter_name[4] == '3')
 		SET_ETHTOOL_OPS(dev, &ethtool_ops_203);
 	else
 		SET_ETHTOOL_OPS(dev, &ethtool_ops);
-	dev->tx_timeout = ewrk3_timeout;
 	dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
 
 	dev->mem_start = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fealnx.c linux-libre-2.6.30-gnu1/drivers/net/fealnx.c
--- linux-libre-2.6.29-gnu1/drivers/net/fealnx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/fealnx.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,8 +93,8 @@ static int full_duplex[MAX_UNITS] = { -1
 #include <asm/byteorder.h>
 
 /* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
+static const char version[] __devinitconst =
+	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
 
 
 /* This driver was written to use PCI memory space, however some x86 systems
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fec.c linux-libre-2.6.30-gnu1/drivers/net/fec.c
--- linux-libre-2.6.29-gnu1/drivers/net/fec.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/fec.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,46 +36,32 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
 
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 
+#ifndef CONFIG_ARCH_MXC
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
+#endif
+
 #include "fec.h"
 
-#if defined(CONFIG_FEC2)
-#define	FEC_MAX_PORTS	2
+#ifdef CONFIG_ARCH_MXC
+#include <mach/hardware.h>
+#define FEC_ALIGNMENT	0xf
 #else
-#define	FEC_MAX_PORTS	1
-#endif
-
-#if defined(CONFIG_M5272)
-#define HAVE_mii_link_interrupt
+#define FEC_ALIGNMENT	0x3
 #endif
 
 /*
  * Define the fixed address of the FEC hardware.
  */
-static unsigned int fec_hw[] = {
 #if defined(CONFIG_M5272)
-	(MCF_MBAR + 0x840),
-#elif defined(CONFIG_M527x)
-	(MCF_MBAR + 0x1000),
-	(MCF_MBAR + 0x1800),
-#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
-	(MCF_MBAR + 0x1000),
-#elif defined(CONFIG_M520x)
-	(MCF_MBAR+0x30000),
-#elif defined(CONFIG_M532x)
-	(MCF_MBAR+0xfc030000),
-#else
-	&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
-#endif
-};
+#define HAVE_mii_link_interrupt
 
 static unsigned char	fec_mac_default[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -98,6 +84,7 @@ static unsigned char	fec_mac_default[] =
 #else
 #define	FEC_FLASHMAC	0
 #endif
+#endif /* CONFIG_M5272 */
 
 /* Forward declarations of some structures to support different PHYs
 */
@@ -162,7 +149,7 @@ typedef struct {
  * account when setting it.
  */
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -182,6 +169,8 @@ struct fec_enet_private {
 
 	struct net_device *netdev;
 
+	struct clk *clk;
+
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	unsigned char *tx_bounce[TX_RING_SIZE];
 	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -190,6 +179,7 @@ struct fec_enet_private {
 
 	/* CPM dual port RAM relative addresses.
 	*/
+	dma_addr_t	bd_dma;
 	cbd_t	*rx_bd_base;		/* Address of Rx and Tx buffers. */
 	cbd_t	*tx_bd_base;
 	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
@@ -342,10 +332,10 @@ fec_enet_start_xmit(struct sk_buff *skb,
 	 *	4-byte boundaries. Use bounce buffers to copy data
 	 *	and get it aligned. Ugh.
 	 */
-	if (bdp->cbd_bufaddr & 0x3) {
+	if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
 		unsigned int index;
 		index = bdp - fep->tx_bd_base;
-		memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
+		memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len);
 		bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
 	}
 
@@ -359,8 +349,8 @@ fec_enet_start_xmit(struct sk_buff *skb,
 	/* Push the data cache so the CPM does not get stale memory
 	 * data.
 	 */
-	flush_dcache_range((unsigned long)skb->data,
-			   (unsigned long)skb->data + skb->len);
+	dma_sync_single(NULL, bdp->cbd_bufaddr,
+			bdp->cbd_datlen, DMA_TO_DEVICE);
 
 	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
 	 * it's the last BD of the frame, and to put the CRC on the end.
@@ -633,6 +623,9 @@ while (!((status = bdp->cbd_sc) & BD_ENE
 	dev->stats.rx_bytes += pkt_len;
 	data = (__u8*)__va(bdp->cbd_bufaddr);
 
+	dma_sync_single(NULL, (unsigned long)__pa(data),
+			pkt_len - 4, DMA_FROM_DEVICE);
+
 	/* This does 16 byte alignment, exactly what we need.
 	 * The packet length includes FCS, but we don't want to
 	 * include that when passing upstream as it messes up
@@ -1114,7 +1107,7 @@ static phy_info_t const phy_info_am79c87
 /* register definitions for the 8721 */
 
 #define MII_KS8721BL_RXERCR	21
-#define MII_KS8721BL_ICSR	22
+#define MII_KS8721BL_ICSR	27
 #define	MII_KS8721BL_PHYCR	31
 
 static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
@@ -1223,93 +1216,14 @@ static phy_info_t const * const phy_info
 #ifdef HAVE_mii_link_interrupt
 static irqreturn_t
 mii_link_interrupt(int irq, void * dev_id);
-#endif
 
-#if defined(CONFIG_M5272)
 /*
- *	Code specific to Coldfire 5272 setup.
+ *	This is specific to the MII interrupt setup of the M5272EVB.
  */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
-	volatile unsigned long *icrp;
-	static const struct idesc {
-		char *name;
-		unsigned short irq;
-		irq_handler_t handler;
-	} *idp, id[] = {
-		{ "fec(RX)", 86, fec_enet_interrupt },
-		{ "fec(TX)", 87, fec_enet_interrupt },
-		{ "fec(OTHER)", 88, fec_enet_interrupt },
-		{ "fec(MII)", 66, mii_link_interrupt },
-		{ NULL },
-	};
-
-	/* Setup interrupt handlers. */
-	for (idp = id; idp->name; idp++) {
-		if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0)
-			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
-	}
-
-	/* Unmask interrupt at ColdFire 5272 SIM */
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
-	*icrp = 0x00000ddd;
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	*icrp = 0x0d000000;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-	fecp->fec_x_cntrl = 0x00;
-
-	/*
-	 * Set MII speed to 2.5 MHz
-	 * See 5272 manual section 11.5.8: MSCR
-	 */
-	fep->phy_speed = ((((MCF_CLK / 4) / (2500000 / 10)) + 5) / 10) * 2;
-	fecp->fec_mii_speed = fep->phy_speed;
-
-	fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
-	struct fec_enet_private *fep = netdev_priv(dev);
-	volatile fec_t *fecp;
-	unsigned char *iap, tmpaddr[ETH_ALEN];
-
-	fecp = fep->hwp;
-
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = (unsigned char *)FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
-		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
-		iap = &tmpaddr[0];
-	}
-
-	memcpy(dev->dev_addr, iap, ETH_ALEN);
-
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
+static void __inline__ fec_request_mii_intr(struct net_device *dev)
 {
+	if (request_irq(66, mii_link_interrupt, IRQF_DISABLED, "fec(MII)", dev) != 0)
+		printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
 }
 
 static void __inline__ fec_disable_phy_intr(void)
@@ -1326,384 +1240,9 @@ static void __inline__ fec_phy_ack_intr(
 	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
 	*icrp = 0x0d000000;
 }
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- *	Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-
-/*
- *	Code specific to Coldfire 5230/5231/5232/5234/5235,
- *	the 5270/5271/5274/5275 and 5280/5282 setups.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
-	struct fec_enet_private *fep;
-	int b;
-	static const struct idesc {
-		char *name;
-		unsigned short irq;
-	} *idp, id[] = {
-		{ "fec(TXF)", 23 },
-		{ "fec(RXF)", 27 },
-		{ "fec(MII)", 29 },
-		{ NULL },
-	};
-
-	fep = netdev_priv(dev);
-	b = (fep->index) ? 128 : 64;
-
-	/* Setup interrupt handlers. */
-	for (idp = id; idp->name; idp++) {
-		if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0)
-			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
-	}
-
-	/* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
-	{
-		volatile unsigned char  *icrp;
-		volatile unsigned long  *imrp;
-		int i, ilip;
-
-		b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0;
-		icrp = (volatile unsigned char *) (MCF_IPSBAR + b +
-			MCFINTC_ICR0);
-		for (i = 23, ilip = 0x28; (i < 36); i++)
-			icrp[i] = ilip--;
-
-		imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
-			MCFINTC_IMRH);
-		*imrp &= ~0x0000000f;
-		imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
-			MCFINTC_IMRL);
-		*imrp &= ~0xff800001;
-	}
-
-#if defined(CONFIG_M528x)
-	/* Set up gpio outputs for MII lines */
-	{
-		volatile u16 *gpio_paspar;
-		volatile u8 *gpio_pehlpar;
-
-		gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056);
-		gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058);
-		*gpio_paspar |= 0x0f00;
-		*gpio_pehlpar = 0xc0;
-	}
 #endif
 
-#if defined(CONFIG_M527x)
-	/* Set up gpio outputs for MII lines */
-	{
-		volatile u8 *gpio_par_fec;
-		volatile u16 *gpio_par_feci2c;
-
-		gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082);
-		/* Set up gpio outputs for FEC0 MII lines */
-		gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078);
-
-		*gpio_par_feci2c |= 0x0f00;
-		*gpio_par_fec |= 0xc0;
-
-#if defined(CONFIG_FEC2)
-		/* Set up gpio outputs for FEC1 MII lines */
-		gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079);
-
-		*gpio_par_feci2c |= 0x00a0;
-		*gpio_par_fec |= 0xc0;
-#endif /* CONFIG_FEC2 */
-	}
-#endif /* CONFIG_M527x */
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-	fecp->fec_x_cntrl = 0x00;
-
-	/*
-	 * Set MII speed to 2.5 MHz
-	 * See 5282 manual section 17.5.4.7: MSCR
-	 */
-	fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-	fecp->fec_mii_speed = fep->phy_speed;
-
-	fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
-	struct fec_enet_private *fep = netdev_priv(dev);
-	volatile fec_t *fecp;
-	unsigned char *iap, tmpaddr[ETH_ALEN];
-
-	fecp = fep->hwp;
-
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
-		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
-		iap = &tmpaddr[0];
-	}
-
-	memcpy(dev->dev_addr, iap, ETH_ALEN);
-
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- *	Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M520x)
-
-/*
- *	Code specific to Coldfire 520x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
-	struct fec_enet_private *fep;
-	int b;
-	static const struct idesc {
-		char *name;
-		unsigned short irq;
-	} *idp, id[] = {
-		{ "fec(TXF)", 23 },
-		{ "fec(RXF)", 27 },
-		{ "fec(MII)", 29 },
-		{ NULL },
-	};
-
-	fep = netdev_priv(dev);
-	b = 64 + 13;
-
-	/* Setup interrupt handlers. */
-	for (idp = id; idp->name; idp++) {
-		if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
-			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
-	}
-
-	/* Unmask interrupts at ColdFire interrupt controller */
-	{
-		volatile unsigned char  *icrp;
-		volatile unsigned long  *imrp;
-
-		icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
-			MCFINTC_ICR0);
-		for (b = 36; (b < 49); b++)
-			icrp[b] = 0x04;
-		imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
-			MCFINTC_IMRH);
-		*imrp &= ~0x0001FFF0;
-	}
-	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
-	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-	fecp->fec_x_cntrl = 0x00;
-
-	/*
-	 * Set MII speed to 2.5 MHz
-	 * See 5282 manual section 17.5.4.7: MSCR
-	 */
-	fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
-	fecp->fec_mii_speed = fep->phy_speed;
-
-	fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
-	struct fec_enet_private *fep = netdev_priv(dev);
-	volatile fec_t *fecp;
-	unsigned char *iap, tmpaddr[ETH_ALEN];
-
-	fecp = fep->hwp;
-
-	if (FEC_FLASHMAC) {
-		/*
-		 * Get MAC address from FLASH.
-		 * If it is all 1's or 0's, use the default.
-		 */
-		iap = FEC_FLASHMAC;
-		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
-		   (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
-			iap = fec_mac_default;
-		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
-		   (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
-			iap = fec_mac_default;
-	} else {
-		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
-		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
-		iap = &tmpaddr[0];
-	}
-
-	memcpy(dev->dev_addr, iap, ETH_ALEN);
-
-	/* Adjust MAC if using default MAC address */
-	if (iap == fec_mac_default)
-		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M532x)
-/*
- * Code specific for M532x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
-	struct fec_enet_private *fep;
-	int b;
-	static const struct idesc {
-		char *name;
-		unsigned short irq;
-	} *idp, id[] = {
-	    { "fec(TXF)", 36 },
-	    { "fec(RXF)", 40 },
-	    { "fec(MII)", 42 },
-	    { NULL },
-	};
-
-	fep = netdev_priv(dev);
-	b = (fep->index) ? 128 : 64;
-
-	/* Setup interrupt handlers. */
-	for (idp = id; idp->name; idp++) {
-		if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
-			printk("FEC: Could not allocate %s IRQ(%d)!\n",
-				idp->name, b+idp->irq);
-	}
-
-	/* Unmask interrupts */
-	MCF_INTC0_ICR36 = 0x2;
-	MCF_INTC0_ICR37 = 0x2;
-	MCF_INTC0_ICR38 = 0x2;
-	MCF_INTC0_ICR39 = 0x2;
-	MCF_INTC0_ICR40 = 0x2;
-	MCF_INTC0_ICR41 = 0x2;
-	MCF_INTC0_ICR42 = 0x2;
-	MCF_INTC0_ICR43 = 0x2;
-	MCF_INTC0_ICR44 = 0x2;
-	MCF_INTC0_ICR45 = 0x2;
-	MCF_INTC0_ICR46 = 0x2;
-	MCF_INTC0_ICR47 = 0x2;
-	MCF_INTC0_ICR48 = 0x2;
-
-	MCF_INTC0_IMRH &= ~(
-		MCF_INTC_IMRH_INT_MASK36 |
-		MCF_INTC_IMRH_INT_MASK37 |
-		MCF_INTC_IMRH_INT_MASK38 |
-		MCF_INTC_IMRH_INT_MASK39 |
-		MCF_INTC_IMRH_INT_MASK40 |
-		MCF_INTC_IMRH_INT_MASK41 |
-		MCF_INTC_IMRH_INT_MASK42 |
-		MCF_INTC_IMRH_INT_MASK43 |
-		MCF_INTC_IMRH_INT_MASK44 |
-		MCF_INTC_IMRH_INT_MASK45 |
-		MCF_INTC_IMRH_INT_MASK46 |
-		MCF_INTC_IMRH_INT_MASK47 |
-		MCF_INTC_IMRH_INT_MASK48 );
-
-	/* Set up gpio outputs for MII lines */
-	MCF_GPIO_PAR_FECI2C |= (0 |
-		MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
-		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
-	MCF_GPIO_PAR_FEC = (0 |
-		MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
-		MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-	fecp->fec_x_cntrl = 0x00;
-
-	/*
-	 * Set MII speed to 2.5 MHz
-	 */
-	fep->phy_speed = (MCF_CLK / 3) / (2500000 * 2 ) * 2;
-	fecp->fec_mii_speed = fep->phy_speed;
-
-	fec_restart(dev, 0);
-}
-
+#ifdef CONFIG_M5272
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
@@ -1717,7 +1256,7 @@ static void __inline__ fec_get_mac(struc
 		 * Get MAC address from FLASH.
 		 * If it is all 1's or 0's, use the default.
 		 */
-		iap = FEC_FLASHMAC;
+		iap = (unsigned char *)FEC_FLASHMAC;
 		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
 		    (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
 			iap = fec_mac_default;
@@ -1734,122 +1273,8 @@ static void __inline__ fec_get_mac(struc
 
 	/* Adjust MAC if using default MAC address */
 	if (iap == fec_mac_default)
-		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- *	Do not need to make region uncached on 532x.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-#else
-
-/*
- *	Code specific to the MPC860T setup.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
-	volatile immap_t *immap;
-
-	immap = (immap_t *)IMAP_ADDR;	/* pointer to internal registers */
-
-	if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
-		panic("Could not allocate FEC IRQ!");
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
-	bd_t *bd;
-
-	bd = (bd_t *)__res;
-	memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
-	extern uint _get_IMMR(void);
-	volatile immap_t *immap;
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	immap = (immap_t *)IMAP_ADDR;	/* pointer to internal registers */
-
-	/* Configure all of port D for MII.
-	*/
-	immap->im_ioport.iop_pdpar = 0x1fff;
-
-	/* Bits moved from Rev. D onward.
-	*/
-	if ((_get_IMMR() & 0xffff) < 0x0501)
-		immap->im_ioport.iop_pddir = 0x1c58;	/* Pre rev. D */
-	else
-		immap->im_ioport.iop_pddir = 0x1fff;	/* Rev. D and later */
-
-	/* Set MII speed to 2.5 MHz
-	*/
-	fecp->fec_mii_speed = fep->phy_speed =
-		((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-
-	/* Enable MII command finished interrupt
-	*/
-	fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-	volatile fec_t *fecp;
-
-	fecp = fep->hwp;
-	fecp->fec_r_hash = PKT_MAXBUF_SIZE;
-	/* Enable big endian and don't care about SDMA FC.
-	*/
-	fecp->fec_fun_code = 0x78000000;
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
-	pte_t *pte;
-	pte = va_to_pte(mem_addr);
-	pte_val(*pte) |= _PAGE_NO_CACHE;
-	flush_tlb_page(init_mm.mmap, mem_addr);
+		 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
 }
-
 #endif
 
 /* ------------------------------------------------------------------------- */
@@ -2055,7 +1480,9 @@ mii_discover_phy(uint mii_reg, struct ne
 		printk("FEC: No PHY device found.\n");
 		/* Disable external MII interface */
 		fecp->fec_mii_speed = fep->phy_speed = 0;
+#ifdef HAVE_mii_link_interrupt
 		fec_disable_phy_intr();
+#endif
 	}
 }
 
@@ -2237,12 +1664,12 @@ fec_set_mac_address(struct net_device *d
 
 }
 
-/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
- */
  /*
   * XXX:  We need to clean up on failure exits here.
+  *
+  * index is only used in legacy code
   */
-int __init fec_enet_init(struct net_device *dev)
+int __init fec_enet_init(struct net_device *dev, int index)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	unsigned long	mem_addr;
@@ -2250,15 +1677,11 @@ int __init fec_enet_init(struct net_devi
 	cbd_t		*cbd_base;
 	volatile fec_t	*fecp;
 	int 		i, j;
-	static int	index = 0;
-
-	/* Only allow us to be probed once. */
-	if (index >= FEC_MAX_PORTS)
-		return -ENXIO;
 
 	/* Allocate memory for buffer descriptors.
 	*/
-	mem_addr = __get_free_page(GFP_KERNEL);
+	mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
+			&fep->bd_dma, GFP_KERNEL);
 	if (mem_addr == 0) {
 		printk("FEC: allocate descriptor memory failed?\n");
 		return -ENOMEM;
@@ -2269,7 +1692,7 @@ int __init fec_enet_init(struct net_devi
 
 	/* Create an Ethernet device instance.
 	*/
-	fecp = (volatile fec_t *) fec_hw[index];
+	fecp = (volatile fec_t *)dev->base_addr;
 
 	fep->index = index;
 	fep->hwp = fecp;
@@ -2280,18 +1703,24 @@ int __init fec_enet_init(struct net_devi
 	fecp->fec_ecntrl = 1;
 	udelay(10);
 
-	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
-	 * this needs some work to get unique addresses.
-	 *
-	 * This is our default MAC address unless the user changes
-	 * it via eth_mac_addr (our dev->set_mac_addr handler).
-	 */
+	/* Set the Ethernet address */
+#ifdef CONFIG_M5272
 	fec_get_mac(dev);
+#else
+	{
+		unsigned long l;
+		l = fecp->fec_addr_low;
+		dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
+		dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
+		dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
+		dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
+		l = fecp->fec_addr_high;
+		dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
+		dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
+	}
+#endif
 
 	cbd_base = (cbd_t *)mem_addr;
-	/* XXX: missing check for allocation failure */
-
-	fec_uncache(mem_addr);
 
 	/* Set receive and transmit descriptor base.
 	*/
@@ -2313,8 +1742,6 @@ int __init fec_enet_init(struct net_devi
 		mem_addr = __get_free_page(GFP_KERNEL);
 		/* XXX: missing check for allocation failure */
 
-		fec_uncache(mem_addr);
-
 		/* Initialize the BD for every fragment in the page.
 		*/
 		for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
@@ -2357,13 +1784,13 @@ int __init fec_enet_init(struct net_devi
 
 	/* Set receive and transmit descriptor base.
 	*/
-	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
-	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+	fecp->fec_r_des_start = fep->bd_dma;
+	fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
+				* RX_RING_SIZE;
 
-	/* Install our interrupt handlers. This varies depending on
-	 * the architecture.
-	*/
-	fec_request_intrs(dev);
+#ifdef HAVE_mii_link_interrupt
+	fec_request_mii_intr(dev);
+#endif
 
 	fecp->fec_grp_hash_table_high = 0;
 	fecp->fec_grp_hash_table_low = 0;
@@ -2375,8 +1802,6 @@ int __init fec_enet_init(struct net_devi
 	fecp->fec_hash_table_low = 0;
 #endif
 
-	dev->base_addr = (unsigned long)fecp;
-
 	/* The FEC Ethernet specific entries in the device structure. */
 	dev->open = fec_enet_open;
 	dev->hard_start_xmit = fec_enet_start_xmit;
@@ -2390,7 +1815,16 @@ int __init fec_enet_init(struct net_devi
 	mii_free = mii_cmds;
 
 	/* setup MII interface */
-	fec_set_mii(dev, fep);
+	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/*
+	 * Set MII speed to 2.5 MHz
+	 */
+	fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
+					/ 2500000) / 2) & 0x3F) << 1;
+	fecp->fec_mii_speed = fep->phy_speed;
+	fec_restart(dev, 0);
 
 	/* Clear and enable interrupts */
 	fecp->fec_ievent = 0xffc00000;
@@ -2403,7 +1837,6 @@ int __init fec_enet_init(struct net_devi
 	fep->phy_addr = 0;
 	mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
 
-	index++;
 	return 0;
 }
 
@@ -2430,7 +1863,6 @@ fec_restart(struct net_device *dev, int
 	/* Clear any outstanding interrupt.
 	*/
 	fecp->fec_ievent = 0xffc00000;
-	fec_enable_phy_intr();
 
 	/* Set station address.
 	*/
@@ -2445,12 +1877,11 @@ fec_restart(struct net_device *dev, int
 	*/
 	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
 
-	fec_localhw_setup();
-
 	/* Set receive and transmit descriptor base.
 	*/
-	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
-	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+	fecp->fec_r_des_start = fep->bd_dma;
+	fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
+				* RX_RING_SIZE;
 
 	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
 	fep->cur_rx = fep->rx_bd_base;
@@ -2552,39 +1983,171 @@ fec_stop(struct net_device *dev)
 	/* Clear outstanding MII command interrupts.
 	*/
 	fecp->fec_ievent = FEC_ENET_MII;
-	fec_enable_phy_intr();
 
 	fecp->fec_imask = FEC_ENET_MII;
 	fecp->fec_mii_speed = fep->phy_speed;
 }
 
-static int __init fec_enet_module_init(void)
+static int __devinit
+fec_probe(struct platform_device *pdev)
 {
-	struct net_device *dev;
-	int i, err;
+	struct fec_enet_private *fep;
+	struct net_device *ndev;
+	int i, irq, ret = 0;
+	struct resource *r;
 
-	printk("FEC ENET Version 0.2\n");
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENXIO;
 
-	for (i = 0; (i < FEC_MAX_PORTS); i++) {
-		dev = alloc_etherdev(sizeof(struct fec_enet_private));
-		if (!dev)
-			return -ENOMEM;
-		err = fec_enet_init(dev);
-		if (err) {
-			free_netdev(dev);
-			continue;
+	r = request_mem_region(r->start, resource_size(r), pdev->name);
+	if (!r)
+		return -EBUSY;
+
+	/* Init network device */
+	ndev = alloc_etherdev(sizeof(struct fec_enet_private));
+	if (!ndev)
+		return -ENOMEM;
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	/* setup board info structure */
+	fep = netdev_priv(ndev);
+	memset(fep, 0, sizeof(*fep));
+
+	ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r));
+
+	if (!ndev->base_addr) {
+		ret = -ENOMEM;
+		goto failed_ioremap;
+	}
+
+	platform_set_drvdata(pdev, ndev);
+
+	/* This device has up to three irqs on some platforms */
+	for (i = 0; i < 3; i++) {
+		irq = platform_get_irq(pdev, i);
+		if (i && irq < 0)
+			break;
+		ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
+		if (ret) {
+			while (i >= 0) {
+				irq = platform_get_irq(pdev, i);
+				free_irq(irq, ndev);
+				i--;
+			}
+			goto failed_irq;
 		}
-		if (register_netdev(dev) != 0) {
-			/* XXX: missing cleanup here */
-			free_netdev(dev);
-			return -EIO;
+	}
+
+	fep->clk = clk_get(&pdev->dev, "fec_clk");
+	if (IS_ERR(fep->clk)) {
+		ret = PTR_ERR(fep->clk);
+		goto failed_clk;
+	}
+	clk_enable(fep->clk);
+
+	ret = fec_enet_init(ndev, 0);
+	if (ret)
+		goto failed_init;
+
+	ret = register_netdev(ndev);
+	if (ret)
+		goto failed_register;
+
+	return 0;
+
+failed_register:
+failed_init:
+	clk_disable(fep->clk);
+	clk_put(fep->clk);
+failed_clk:
+	for (i = 0; i < 3; i++) {
+		irq = platform_get_irq(pdev, i);
+		if (irq > 0)
+			free_irq(irq, ndev);
+	}
+failed_irq:
+	iounmap((void __iomem *)ndev->base_addr);
+failed_ioremap:
+	free_netdev(ndev);
+
+	return ret;
+}
+
+static int __devexit
+fec_drv_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	fec_stop(ndev);
+	clk_disable(fep->clk);
+	clk_put(fep->clk);
+	iounmap((void __iomem *)ndev->base_addr);
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+	return 0;
+}
+
+static int
+fec_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+	struct fec_enet_private *fep;
+
+	if (ndev) {
+		fep = netdev_priv(ndev);
+		if (netif_running(ndev)) {
+			netif_device_detach(ndev);
+			fec_stop(ndev);
 		}
+	}
+	return 0;
+}
 
-		printk("%s: ethernet %pM\n", dev->name, dev->dev_addr);
+static int
+fec_resume(struct platform_device *dev)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+
+	if (ndev) {
+		if (netif_running(ndev)) {
+			fec_enet_init(ndev, 0);
+			netif_device_attach(ndev);
+		}
 	}
 	return 0;
 }
 
+static struct platform_driver fec_driver = {
+	.driver	= {
+		.name    = "fec",
+		.owner	 = THIS_MODULE,
+	},
+	.probe   = fec_probe,
+	.remove  = __devexit_p(fec_drv_remove),
+	.suspend = fec_suspend,
+	.resume  = fec_resume,
+};
+
+static int __init
+fec_enet_module_init(void)
+{
+	printk(KERN_INFO "FEC Ethernet Driver\n");
+
+	return platform_driver_register(&fec_driver);
+}
+
+static void __exit
+fec_enet_cleanup(void)
+{
+	platform_driver_unregister(&fec_driver);
+}
+
+module_exit(fec_enet_cleanup);
 module_init(fec_enet_module_init);
 
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fec.h linux-libre-2.6.30-gnu1/drivers/net/fec.h
--- linux-libre-2.6.29-gnu1/drivers/net/fec.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/fec.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,7 +14,7 @@
 /****************************************************************************/
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -103,12 +103,19 @@ typedef struct fec {
 /*
  *	Define the buffer descriptor structure.
  */
+#ifdef CONFIG_ARCH_MXC
+typedef struct bufdesc {
+	unsigned short cbd_datlen;	/* Data length */
+	unsigned short cbd_sc;	/* Control and status info */
+	unsigned long cbd_bufaddr;	/* Buffer address */
+} cbd_t;
+#else
 typedef struct bufdesc {
 	unsigned short	cbd_sc;			/* Control and status info */
 	unsigned short	cbd_datlen;		/* Data length */
 	unsigned long	cbd_bufaddr;		/* Buffer address */
 } cbd_t;
-
+#endif
 
 /*
  *	The following definitions courtesy of commproc.h, which where
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fec_mpc52xx.c linux-libre-2.6.30-gnu1/drivers/net/fec_mpc52xx.c
--- linux-libre-2.6.29-gnu1/drivers/net/fec_mpc52xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/fec_mpc52xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,8 @@ static void mpc52xx_fec_free_rx_buffers(
 		struct sk_buff *skb;
 
 		skb = bcom_retrieve_buffer(s, NULL, (struct bcom_bd **)&bd);
-		dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_FROM_DEVICE);
+		dma_unmap_single(dev->dev.parent, bd->skb_pa, skb->len,
+				 DMA_FROM_DEVICE);
 		kfree_skb(skb);
 	}
 }
@@ -150,7 +151,7 @@ static int mpc52xx_fec_alloc_rx_buffers(
 		bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk);
 
 		bd->status = FEC_RX_BUFFER_SIZE;
-		bd->skb_pa = dma_map_single(&dev->dev, skb->data,
+		bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
 				FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
 
 		bcom_submit_next_buffer(rxtsk, skb);
@@ -270,15 +271,6 @@ static void mpc52xx_fec_phy_stop(struct
 	phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
 }
 
-static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
-		struct mii_ioctl_data *mii_data, int cmd)
-{
-	if (!priv->phydev)
-		return -ENOTSUPP;
-
-	return phy_mii_ioctl(priv->phydev, mii_data, cmd);
-}
-
 static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
 {
 	struct mpc52xx_fec __iomem *fec = priv->fec;
@@ -370,7 +362,7 @@ static int mpc52xx_fec_close(struct net_
  * invariant will hold if you make sure that the netif_*_queue()
  * calls are done at the proper times.
  */
-static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 	struct bcom_fec_bd *bd;
@@ -378,7 +370,7 @@ static int mpc52xx_fec_hard_start_xmit(s
 	if (bcom_queue_full(priv->tx_dmatsk)) {
 		if (net_ratelimit())
 			dev_err(&dev->dev, "transmit queue overrun\n");
-		return 1;
+		return NETDEV_TX_BUSY;
 	}
 
 	spin_lock_irq(&priv->lock);
@@ -388,7 +380,8 @@ static int mpc52xx_fec_hard_start_xmit(s
 		bcom_prepare_next_buffer(priv->tx_dmatsk);
 
 	bd->status = skb->len | BCOM_FEC_TX_BD_TFD | BCOM_FEC_TX_BD_TC;
-	bd->skb_pa = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+	bd->skb_pa = dma_map_single(dev->dev.parent, skb->data, skb->len,
+				    DMA_TO_DEVICE);
 
 	bcom_submit_next_buffer(priv->tx_dmatsk, skb);
 
@@ -398,7 +391,7 @@ static int mpc52xx_fec_hard_start_xmit(s
 
 	spin_unlock_irq(&priv->lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -430,7 +423,8 @@ static irqreturn_t mpc52xx_fec_tx_interr
 		struct bcom_fec_bd *bd;
 		skb = bcom_retrieve_buffer(priv->tx_dmatsk, NULL,
 				(struct bcom_bd **)&bd);
-		dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_TO_DEVICE);
+		dma_unmap_single(dev->dev.parent, bd->skb_pa, skb->len,
+				 DMA_TO_DEVICE);
 
 		dev_kfree_skb_irq(skb);
 	}
@@ -455,7 +449,8 @@ static irqreturn_t mpc52xx_fec_rx_interr
 
 		rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status,
 				(struct bcom_bd **)&bd);
-		dma_unmap_single(&dev->dev, bd->skb_pa, rskb->len, DMA_FROM_DEVICE);
+		dma_unmap_single(dev->dev.parent, bd->skb_pa, rskb->len,
+				 DMA_FROM_DEVICE);
 
 		/* Test for errors in received frame */
 		if (status & BCOM_FEC_RX_BD_ERRORS) {
@@ -464,7 +459,8 @@ static irqreturn_t mpc52xx_fec_rx_interr
 				bcom_prepare_next_buffer(priv->rx_dmatsk);
 
 			bd->status = FEC_RX_BUFFER_SIZE;
-			bd->skb_pa = dma_map_single(&dev->dev, rskb->data,
+			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);
@@ -499,7 +495,7 @@ static irqreturn_t mpc52xx_fec_rx_interr
 			bcom_prepare_next_buffer(priv->rx_dmatsk);
 
 		bd->status = FEC_RX_BUFFER_SIZE;
-		bd->skb_pa = dma_map_single(&dev->dev, skb->data,
+		bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
 				FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
 
 		bcom_submit_next_buffer(priv->rx_dmatsk, skb);
@@ -847,12 +843,20 @@ static void mpc52xx_fec_get_drvinfo(stru
 static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+	if (!priv->phydev)
+		return -ENODEV;
+
 	return phy_ethtool_gset(priv->phydev, cmd);
 }
 
 static int mpc52xx_fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+	if (!priv->phydev)
+		return -ENODEV;
+
 	return phy_ethtool_sset(priv->phydev, cmd);
 }
 
@@ -882,9 +886,28 @@ static int mpc52xx_fec_ioctl(struct net_
 {
 	struct mpc52xx_fec_priv *priv = netdev_priv(dev);
 
-	return mpc52xx_fec_phy_mii_ioctl(priv, if_mii(rq), cmd);
+	if (!priv->phydev)
+		return -ENOTSUPP;
+
+	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
 }
 
+static const struct net_device_ops mpc52xx_fec_netdev_ops = {
+	.ndo_open = mpc52xx_fec_open,
+	.ndo_stop = mpc52xx_fec_close,
+	.ndo_start_xmit = mpc52xx_fec_start_xmit,
+	.ndo_set_multicast_list = mpc52xx_fec_set_multicast_list,
+	.ndo_set_mac_address = mpc52xx_fec_set_mac_address,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_do_ioctl = mpc52xx_fec_ioctl,
+	.ndo_change_mtu = eth_change_mtu,
+	.ndo_tx_timeout = mpc52xx_fec_tx_timeout,
+	.ndo_get_stats = mpc52xx_fec_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = mpc52xx_fec_poll_controller,
+#endif
+};
+
 /* ======================================================================== */
 /* OF Driver                                                                */
 /* ======================================================================== */
@@ -929,22 +952,10 @@ mpc52xx_fec_probe(struct of_device *op,
 		return -EBUSY;
 
 	/* Init ether ndev with what we have */
-	ndev->open		= mpc52xx_fec_open;
-	ndev->stop		= mpc52xx_fec_close;
-	ndev->hard_start_xmit	= mpc52xx_fec_hard_start_xmit;
-	ndev->do_ioctl		= mpc52xx_fec_ioctl;
+	ndev->netdev_ops	= &mpc52xx_fec_netdev_ops;
 	ndev->ethtool_ops	= &mpc52xx_fec_ethtool_ops;
-	ndev->get_stats		= mpc52xx_fec_get_stats;
-	ndev->set_mac_address	= mpc52xx_fec_set_mac_address;
-	ndev->set_multicast_list = mpc52xx_fec_set_multicast_list;
-	ndev->tx_timeout	= mpc52xx_fec_tx_timeout;
 	ndev->watchdog_timeo	= FEC_WATCHDOG_TIMEOUT;
 	ndev->base_addr		= mem.start;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	ndev->poll_controller = mpc52xx_fec_poll_controller;
-#endif
-
-	priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
 
 	spin_lock_init(&priv->lock);
 
@@ -1123,9 +1134,9 @@ static int mpc52xx_fec_of_resume(struct
 #endif
 
 static struct of_device_id mpc52xx_fec_match[] = {
-	{ .type = "network", .compatible = "fsl,mpc5200b-fec", },
-	{ .type = "network", .compatible = "fsl,mpc5200-fec", },
-	{ .type = "network", .compatible = "mpc5200-fec", },
+	{ .compatible = "fsl,mpc5200b-fec", },
+	{ .compatible = "fsl,mpc5200-fec", },
+	{ .compatible = "mpc5200-fec", },
 	{ }
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/forcedeth.c linux-libre-2.6.30-gnu1/drivers/net/forcedeth.c
--- linux-libre-2.6.29-gnu1/drivers/net/forcedeth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/forcedeth.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.62"
+#define FORCEDETH_VERSION		"0.64"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -87,8 +87,8 @@
 #define DEV_HAS_MSI_X              0x000080  /* device supports MSI-X */
 #define DEV_HAS_POWER_CNTRL        0x000100  /* device supports power savings */
 #define DEV_HAS_STATISTICS_V1      0x000200  /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2      0x000400  /* device supports hw statistics version 2 */
-#define DEV_HAS_STATISTICS_V3      0x000800  /* device supports hw statistics version 3 */
+#define DEV_HAS_STATISTICS_V2      0x000600  /* device supports hw statistics version 2 */
+#define DEV_HAS_STATISTICS_V3      0x000e00  /* device supports hw statistics version 3 */
 #define DEV_HAS_TEST_EXTENDED      0x001000  /* device supports extended diagnostic test */
 #define DEV_HAS_MGMT_UNIT          0x002000  /* device supports management unit */
 #define DEV_HAS_CORRECT_MACADDR    0x004000  /* device supports correct mac address order */
@@ -102,7 +102,7 @@
 enum {
 	NvRegIrqStatus = 0x000,
 #define NVREG_IRQSTAT_MIIEVENT	0x040
-#define NVREG_IRQSTAT_MASK		0x81ff
+#define NVREG_IRQSTAT_MASK		0x83ff
 	NvRegIrqMask = 0x004,
 #define NVREG_IRQ_RX_ERROR		0x0001
 #define NVREG_IRQ_RX			0x0002
@@ -113,17 +113,13 @@ enum {
 #define NVREG_IRQ_LINK			0x0040
 #define NVREG_IRQ_RX_FORCED		0x0080
 #define NVREG_IRQ_TX_FORCED		0x0100
-#define NVREG_IRQ_RECOVER_ERROR		0x8000
+#define NVREG_IRQ_RECOVER_ERROR		0x8200
 #define NVREG_IRQMASK_THROUGHPUT	0x00df
 #define NVREG_IRQMASK_CPU		0x0060
 #define NVREG_IRQ_TX_ALL		(NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
 #define NVREG_IRQ_RX_ALL		(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
 #define NVREG_IRQ_OTHER			(NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
 
-#define NVREG_IRQ_UNKNOWN	(~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
-					NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED| \
-					NVREG_IRQ_TX_FORCED|NVREG_IRQ_RECOVER_ERROR))
-
 	NvRegUnknownSetupReg6 = 0x008,
 #define NVREG_UNKSETUP6_VAL		3
 
@@ -132,7 +128,7 @@ enum {
  * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
  */
 	NvRegPollingInterval = 0x00c,
-#define NVREG_POLL_DEFAULT_THROUGHPUT	970 /* backup tx cleanup if loop max reached */
+#define NVREG_POLL_DEFAULT_THROUGHPUT	65535 /* backup tx cleanup if loop max reached */
 #define NVREG_POLL_DEFAULT_CPU	13
 	NvRegMSIMap0 = 0x020,
 	NvRegMSIMap1 = 0x024,
@@ -157,6 +153,9 @@ enum {
 #define NVREG_XMITCTL_HOST_SEMA_ACQ	0x0000f000
 #define NVREG_XMITCTL_HOST_LOADED	0x00004000
 #define NVREG_XMITCTL_TX_PATH_EN	0x01000000
+#define NVREG_XMITCTL_DATA_START	0x00100000
+#define NVREG_XMITCTL_DATA_READY	0x00010000
+#define NVREG_XMITCTL_DATA_ERROR	0x00020000
 	NvRegTransmitterStatus = 0x088,
 #define NVREG_XMITSTAT_BUSY	0x01
 
@@ -289,8 +288,10 @@ enum {
 #define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE	0x04
 #define NVREG_WAKEUPFLAGS_ENABLE	0x1111
 
-	NvRegPatternCRC = 0x204,
-	NvRegPatternMask = 0x208,
+	NvRegMgmtUnitGetVersion = 0x204,
+#define NVREG_MGMTUNITGETVERSION     	0x01
+	NvRegMgmtUnitVersion = 0x208,
+#define NVREG_MGMTUNITVERSION		0x08
 	NvRegPowerCap = 0x268,
 #define NVREG_POWERCAP_D3SUPP	(1<<30)
 #define NVREG_POWERCAP_D2SUPP	(1<<26)
@@ -303,6 +304,8 @@ enum {
 #define NVREG_POWERSTATE_D1		0x0001
 #define NVREG_POWERSTATE_D2		0x0002
 #define NVREG_POWERSTATE_D3		0x0003
+	NvRegMgmtUnitControl = 0x278,
+#define NVREG_MGMTUNITCONTROL_INUSE	0x20000
 	NvRegTxCnt = 0x280,
 	NvRegTxZeroReXmt = 0x284,
 	NvRegTxOneReXmt = 0x288,
@@ -460,7 +463,7 @@ union ring_type {
 /* General driver defaults */
 #define NV_WATCHDOG_TIMEO	(5*HZ)
 
-#define RX_RING_DEFAULT		128
+#define RX_RING_DEFAULT		512
 #define TX_RING_DEFAULT		256
 #define RX_RING_MIN		128
 #define TX_RING_MIN		64
@@ -582,11 +585,17 @@ union ring_type {
 #define NV_MSI_X_VECTOR_TX    0x1
 #define NV_MSI_X_VECTOR_OTHER 0x2
 
+#define NV_MSI_PRIV_OFFSET 0x68
+#define NV_MSI_PRIV_VALUE  0xffffffff
+
 #define NV_RESTART_TX         0x1
 #define NV_RESTART_RX         0x2
 
 #define NV_TX_LIMIT_COUNT     16
 
+#define NV_DYNAMIC_THRESHOLD        4
+#define NV_DYNAMIC_MAX_QUIET_COUNT  2048
+
 /* statistics */
 struct nv_ethtool_str {
 	char name[ETH_GSTRING_LEN];
@@ -744,11 +753,13 @@ struct fe_priv {
 	u16 gigabit;
 	int intr_test;
 	int recover_error;
+	int quiet_count;
 
 	/* General data: RO fields */
 	dma_addr_t ring_addr;
 	struct pci_dev *pci_dev;
 	u32 orig_mac[2];
+	u32 events;
 	u32 irqmask;
 	u32 desc_ver;
 	u32 txrxctl_bits;
@@ -758,6 +769,8 @@ struct fe_priv {
 	u32 register_size;
 	int rx_csum;
 	u32 mac_in_use;
+	int mgmt_version;
+	int mgmt_sema;
 
 	void __iomem *base;
 
@@ -812,13 +825,18 @@ struct fe_priv {
 
 	/* power saved state */
 	u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
+
+	/* for different msi-x irq type */
+	char name_rx[IFNAMSIZ + 3];       /* -rx    */
+	char name_tx[IFNAMSIZ + 3];       /* -tx    */
+	char name_other[IFNAMSIZ + 6];    /* -other */
 };
 
 /*
  * Maximum number of loops until we assume that a bit in the irq mask
  * is stuck. Overridable with module param.
  */
-static int max_interrupt_work = 15;
+static int max_interrupt_work = 4;
 
 /*
  * Optimization can be either throuput mode or cpu mode
@@ -828,9 +846,10 @@ static int max_interrupt_work = 15;
  */
 enum {
 	NV_OPTIMIZATION_MODE_THROUGHPUT,
-	NV_OPTIMIZATION_MODE_CPU
+	NV_OPTIMIZATION_MODE_CPU,
+	NV_OPTIMIZATION_MODE_DYNAMIC
 };
-static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+static int optimization_mode = NV_OPTIMIZATION_MODE_DYNAMIC;
 
 /*
  * Poll interval for timer irq
@@ -857,7 +876,7 @@ enum {
 	NV_MSIX_INT_DISABLED,
 	NV_MSIX_INT_ENABLED
 };
-static int msix = NV_MSIX_INT_DISABLED;
+static int msix = NV_MSIX_INT_ENABLED;
 
 /*
  * DMA 64bit
@@ -878,6 +897,12 @@ enum {
 };
 static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED;
 
+/*
+ * Power down phy when interface is down (persists through reboot;
+ * older Linux and other OSes may not power it up again)
+ */
+static int phy_power_down = 0;
+
 static inline struct fe_priv *get_nvpriv(struct net_device *dev)
 {
 	return netdev_priv(dev);
@@ -923,7 +948,7 @@ static int reg_delay(struct net_device *
 		delaymax -= delay;
 		if (delaymax < 0) {
 			if (msg)
-				printk(msg);
+				printk("%s", msg);
 			return 1;
 		}
 	} while ((readl(base + offset) & mask) != target);
@@ -1052,6 +1077,24 @@ static void nv_disable_hw_interrupts(str
 	}
 }
 
+static void nv_napi_enable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+	struct fe_priv *np = get_nvpriv(dev);
+
+	napi_enable(&np->napi);
+#endif
+}
+
+static void nv_napi_disable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+	struct fe_priv *np = get_nvpriv(dev);
+
+	napi_disable(&np->napi);
+#endif
+}
+
 #define MII_READ	(-1)
 /* mii_rw: read/write a register on the PHY.
  *
@@ -1448,7 +1491,10 @@ static int phy_init(struct net_device *d
 
 	/* restart auto negotiation, power down phy */
 	mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
-	mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN);
+	mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+	if (phy_power_down) {
+		mii_control |= BMCR_PDOWN;
+	}
 	if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
 		return PHY_ERROR;
 	}
@@ -1760,7 +1806,7 @@ static void nv_do_rx_refill(unsigned lon
 	struct fe_priv *np = netdev_priv(dev);
 
 	/* Just reschedule NAPI rx processing */
-	netif_rx_schedule(&np->napi);
+	napi_schedule(&np->napi);
 }
 #else
 static void nv_do_rx_refill(unsigned long data)
@@ -1843,6 +1889,7 @@ static void nv_init_tx(struct net_device
 	np->tx_pkts_in_progress = 0;
 	np->tx_change_owner = NULL;
 	np->tx_end_flip = NULL;
+	np->tx_stop = 0;
 
 	for (i = 0; i < np->tx_ring_size; i++) {
 		if (!nv_optimized(np)) {
@@ -2365,14 +2412,16 @@ static inline void nv_tx_flip_ownership(
  *
  * Caller must own np->lock.
  */
-static void nv_tx_done(struct net_device *dev)
+static int nv_tx_done(struct net_device *dev, int limit)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u32 flags;
+	int tx_work = 0;
 	struct ring_desc* orig_get_tx = np->get_tx.orig;
 
 	while ((np->get_tx.orig != np->put_tx.orig) &&
-	       !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID)) {
+	       !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) &&
+	       (tx_work < limit)) {
 
 		dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n",
 					dev->name, flags);
@@ -2398,6 +2447,7 @@ static void nv_tx_done(struct net_device
 				}
 				dev_kfree_skb_any(np->get_tx_ctx->skb);
 				np->get_tx_ctx->skb = NULL;
+				tx_work++;
 			}
 		} else {
 			if (flags & NV_TX2_LASTPACKET) {
@@ -2415,6 +2465,7 @@ static void nv_tx_done(struct net_device
 				}
 				dev_kfree_skb_any(np->get_tx_ctx->skb);
 				np->get_tx_ctx->skb = NULL;
+				tx_work++;
 			}
 		}
 		if (unlikely(np->get_tx.orig++ == np->last_tx.orig))
@@ -2426,17 +2477,19 @@ static void nv_tx_done(struct net_device
 		np->tx_stop = 0;
 		netif_wake_queue(dev);
 	}
+	return tx_work;
 }
 
-static void nv_tx_done_optimized(struct net_device *dev, int limit)
+static int nv_tx_done_optimized(struct net_device *dev, int limit)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u32 flags;
+	int tx_work = 0;
 	struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
 
 	while ((np->get_tx.ex != np->put_tx.ex) &&
 	       !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) &&
-	       (limit-- > 0)) {
+	       (tx_work < limit)) {
 
 		dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
 					dev->name, flags);
@@ -2460,6 +2513,7 @@ static void nv_tx_done_optimized(struct
 
 			dev_kfree_skb_any(np->get_tx_ctx->skb);
 			np->get_tx_ctx->skb = NULL;
+			tx_work++;
 
 			if (np->tx_limit) {
 				nv_tx_flip_ownership(dev);
@@ -2474,6 +2528,7 @@ static void nv_tx_done_optimized(struct
 		np->tx_stop = 0;
 		netif_wake_queue(dev);
 	}
+	return tx_work;
 }
 
 /*
@@ -2485,6 +2540,8 @@ static void nv_tx_timeout(struct net_dev
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	u32 status;
+	union ring_type put_tx;
+	int saved_tx_limit;
 
 	if (np->msi_flags & NV_MSI_X_ENABLED)
 		status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
@@ -2544,24 +2601,32 @@ static void nv_tx_timeout(struct net_dev
 	/* 1) stop tx engine */
 	nv_stop_tx(dev);
 
-	/* 2) check that the packets were not sent already: */
+	/* 2) complete any outstanding tx and do not give HW any limited tx pkts */
+	saved_tx_limit = np->tx_limit;
+	np->tx_limit = 0; /* prevent giving HW any limited pkts */
+	np->tx_stop = 0;  /* prevent waking tx queue */
 	if (!nv_optimized(np))
-		nv_tx_done(dev);
+		nv_tx_done(dev, np->tx_ring_size);
 	else
 		nv_tx_done_optimized(dev, np->tx_ring_size);
 
-	/* 3) if there are dead entries: clear everything */
-	if (np->get_tx_ctx != np->put_tx_ctx) {
-		printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name);
-		nv_drain_tx(dev);
-		nv_init_tx(dev);
-		setup_hw_rings(dev, NV_SETUP_TX_RING);
-	}
+	/* save current HW postion */
+	if (np->tx_change_owner)
+		put_tx.ex = np->tx_change_owner->first_tx_desc;
+	else
+		put_tx = np->put_tx;
 
-	netif_wake_queue(dev);
+	/* 3) clear all tx state */
+	nv_drain_tx(dev);
+	nv_init_tx(dev);
 
-	/* 4) restart tx engine */
+	/* 4) restore state to current HW position */
+	np->get_tx = np->put_tx = put_tx;
+	np->tx_limit = saved_tx_limit;
+
+	/* 5) restart tx engine */
 	nv_start_tx(dev);
+	netif_wake_queue(dev);
 	spin_unlock_irq(&np->lock);
 }
 
@@ -2907,6 +2972,7 @@ static int nv_change_mtu(struct net_devi
 		 * Changing the MTU is a rare event, it shouldn't matter.
 		 */
 		nv_disable_irq(dev);
+		nv_napi_disable(dev);
 		netif_tx_lock_bh(dev);
 		netif_addr_lock(dev);
 		spin_lock(&np->lock);
@@ -2935,6 +3001,7 @@ static int nv_change_mtu(struct net_devi
 		spin_unlock(&np->lock);
 		netif_addr_unlock(dev);
 		netif_tx_unlock_bh(dev);
+		nv_napi_enable(dev);
 		nv_enable_irq(dev);
 	}
 	return 0;
@@ -3375,50 +3442,71 @@ static void nv_msi_workaround(struct fe_
 	}
 }
 
+static inline int nv_change_interrupt_mode(struct net_device *dev, int total_work)
+{
+	struct fe_priv *np = netdev_priv(dev);
+
+	if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC) {
+		if (total_work > NV_DYNAMIC_THRESHOLD) {
+			/* transition to poll based interrupts */
+			np->quiet_count = 0;
+			if (np->irqmask != NVREG_IRQMASK_CPU) {
+				np->irqmask = NVREG_IRQMASK_CPU;
+				return 1;
+			}
+		} else {
+			if (np->quiet_count < NV_DYNAMIC_MAX_QUIET_COUNT) {
+				np->quiet_count++;
+			} else {
+				/* reached a period of low activity, switch
+				   to per tx/rx packet interrupts */
+				if (np->irqmask != NVREG_IRQMASK_THROUGHPUT) {
+					np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+					return 1;
+				}
+			}
+		}
+	}
+	return 0;
+}
+
 static irqreturn_t nv_nic_irq(int foo, void *data)
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
-	u32 events;
-	int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+	int total_work = 0;
+	int loop_count = 0;
+#endif
 
 	dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name);
 
-	for (i=0; ; i++) {
-		if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
-			events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
-			writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
-		} else {
-			events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
-			writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
-		}
-		dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
-		if (!(events & np->irqmask))
-			break;
-
-		nv_msi_workaround(np);
+	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+		np->events = readl(base + NvRegIrqStatus);
+		writel(np->events, base + NvRegIrqStatus);
+	} else {
+		np->events = readl(base + NvRegMSIXIrqStatus);
+		writel(np->events, base + NvRegMSIXIrqStatus);
+	}
+	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+	if (!(np->events & np->irqmask))
+		return IRQ_NONE;
 
-		spin_lock(&np->lock);
-		nv_tx_done(dev);
-		spin_unlock(&np->lock);
+	nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-		if (events & NVREG_IRQ_RX_ALL) {
-			spin_lock(&np->lock);
-			netif_rx_schedule(&np->napi);
+	napi_schedule(&np->napi);
 
-			/* Disable furthur receive irq's */
-			np->irqmask &= ~NVREG_IRQ_RX_ALL;
+	/* Disable furthur irq's
+	   (msix not enabled with napi) */
+	writel(0, base + NvRegIrqMask);
 
-			if (np->msi_flags & NV_MSI_X_ENABLED)
-				writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			spin_unlock(&np->lock);
-		}
 #else
-		if (nv_rx_process(dev, RX_WORK_PER_LOOP)) {
+	do
+	{
+		int work = 0;
+		if ((work = nv_rx_process(dev, RX_WORK_PER_LOOP))) {
 			if (unlikely(nv_alloc_rx(dev))) {
 				spin_lock(&np->lock);
 				if (!np->in_shutdown)
@@ -3426,65 +3514,56 @@ static irqreturn_t nv_nic_irq(int foo, v
 				spin_unlock(&np->lock);
 			}
 		}
-#endif
-		if (unlikely(events & NVREG_IRQ_LINK)) {
-			spin_lock(&np->lock);
-			nv_link_irq(dev);
-			spin_unlock(&np->lock);
-		}
-		if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
-			spin_lock(&np->lock);
-			nv_linkchange(dev);
-			spin_unlock(&np->lock);
-			np->link_timeout = jiffies + LINK_TIMEOUT;
-		}
-		if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
-			dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
-						dev->name, events);
-		}
-		if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
-			printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
-						dev->name, events);
-		}
-		if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
-			spin_lock(&np->lock);
-			/* disable interrupts on the nic */
-			if (!(np->msi_flags & NV_MSI_X_ENABLED))
-				writel(0, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			pci_push(base);
 
-			if (!np->in_shutdown) {
-				np->nic_poll_irq = np->irqmask;
-				np->recover_error = 1;
-				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-			}
-			spin_unlock(&np->lock);
-			break;
-		}
-		if (unlikely(i > max_interrupt_work)) {
-			spin_lock(&np->lock);
-			/* disable interrupts on the nic */
-			if (!(np->msi_flags & NV_MSI_X_ENABLED))
-				writel(0, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			pci_push(base);
+		spin_lock(&np->lock);
+		work += nv_tx_done(dev, TX_WORK_PER_LOOP);
+		spin_unlock(&np->lock);
 
-			if (!np->in_shutdown) {
-				np->nic_poll_irq = np->irqmask;
-				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-			}
-			spin_unlock(&np->lock);
-			printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
+		if (!work)
 			break;
-		}
 
+		total_work += work;
+
+		loop_count++;
+	}
+	while (loop_count < max_interrupt_work);
+
+	if (nv_change_interrupt_mode(dev, total_work)) {
+		/* setup new irq mask */
+		writel(np->irqmask, base + NvRegIrqMask);
 	}
+
+	if (unlikely(np->events & NVREG_IRQ_LINK)) {
+		spin_lock(&np->lock);
+		nv_link_irq(dev);
+		spin_unlock(&np->lock);
+	}
+	if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+		spin_lock(&np->lock);
+		nv_linkchange(dev);
+		spin_unlock(&np->lock);
+		np->link_timeout = jiffies + LINK_TIMEOUT;
+	}
+	if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+		spin_lock(&np->lock);
+		/* disable interrupts on the nic */
+		if (!(np->msi_flags & NV_MSI_X_ENABLED))
+			writel(0, base + NvRegIrqMask);
+		else
+			writel(np->irqmask, base + NvRegIrqMask);
+		pci_push(base);
+
+		if (!np->in_shutdown) {
+			np->nic_poll_irq = np->irqmask;
+			np->recover_error = 1;
+			mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+		}
+		spin_unlock(&np->lock);
+	}
+#endif
 	dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name);
 
-	return IRQ_RETVAL(i);
+	return IRQ_HANDLED;
 }
 
 /**
@@ -3497,45 +3576,38 @@ static irqreturn_t nv_nic_irq_optimized(
 	struct net_device *dev = (struct net_device *) data;
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
-	u32 events;
-	int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+	int total_work = 0;
+	int loop_count = 0;
+#endif
 
 	dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name);
 
-	for (i=0; ; i++) {
-		if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
-			events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
-			writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
-		} else {
-			events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
-			writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
-		}
-		dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
-		if (!(events & np->irqmask))
-			break;
-
-		nv_msi_workaround(np);
+	if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+		np->events = readl(base + NvRegIrqStatus);
+		writel(np->events, base + NvRegIrqStatus);
+	} else {
+		np->events = readl(base + NvRegMSIXIrqStatus);
+		writel(np->events, base + NvRegMSIXIrqStatus);
+	}
+	dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+	if (!(np->events & np->irqmask))
+		return IRQ_NONE;
 
-		spin_lock(&np->lock);
-		nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
-		spin_unlock(&np->lock);
+	nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-		if (events & NVREG_IRQ_RX_ALL) {
-			spin_lock(&np->lock);
-			netif_rx_schedule(&np->napi);
+	napi_schedule(&np->napi);
 
-			/* Disable furthur receive irq's */
-			np->irqmask &= ~NVREG_IRQ_RX_ALL;
+	/* Disable furthur irq's
+	   (msix not enabled with napi) */
+	writel(0, base + NvRegIrqMask);
 
-			if (np->msi_flags & NV_MSI_X_ENABLED)
-				writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			spin_unlock(&np->lock);
-		}
 #else
-		if (nv_rx_process_optimized(dev, RX_WORK_PER_LOOP)) {
+	do
+	{
+		int work = 0;
+		if ((work = nv_rx_process_optimized(dev, RX_WORK_PER_LOOP))) {
 			if (unlikely(nv_alloc_rx_optimized(dev))) {
 				spin_lock(&np->lock);
 				if (!np->in_shutdown)
@@ -3543,66 +3615,57 @@ static irqreturn_t nv_nic_irq_optimized(
 				spin_unlock(&np->lock);
 			}
 		}
-#endif
-		if (unlikely(events & NVREG_IRQ_LINK)) {
-			spin_lock(&np->lock);
-			nv_link_irq(dev);
-			spin_unlock(&np->lock);
-		}
-		if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
-			spin_lock(&np->lock);
-			nv_linkchange(dev);
-			spin_unlock(&np->lock);
-			np->link_timeout = jiffies + LINK_TIMEOUT;
-		}
-		if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
-			dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
-						dev->name, events);
-		}
-		if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
-			printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
-						dev->name, events);
-		}
-		if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
-			spin_lock(&np->lock);
-			/* disable interrupts on the nic */
-			if (!(np->msi_flags & NV_MSI_X_ENABLED))
-				writel(0, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			pci_push(base);
 
-			if (!np->in_shutdown) {
-				np->nic_poll_irq = np->irqmask;
-				np->recover_error = 1;
-				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-			}
-			spin_unlock(&np->lock);
+		spin_lock(&np->lock);
+		work += nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
+		spin_unlock(&np->lock);
+
+		if (!work)
 			break;
-		}
 
-		if (unlikely(i > max_interrupt_work)) {
-			spin_lock(&np->lock);
-			/* disable interrupts on the nic */
-			if (!(np->msi_flags & NV_MSI_X_ENABLED))
-				writel(0, base + NvRegIrqMask);
-			else
-				writel(np->irqmask, base + NvRegIrqMask);
-			pci_push(base);
+		total_work += work;
 
-			if (!np->in_shutdown) {
-				np->nic_poll_irq = np->irqmask;
-				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-			}
-			spin_unlock(&np->lock);
-			printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
-			break;
-		}
+		loop_count++;
+	}
+	while (loop_count < max_interrupt_work);
 
+	if (nv_change_interrupt_mode(dev, total_work)) {
+		/* setup new irq mask */
+		writel(np->irqmask, base + NvRegIrqMask);
+	}
+
+	if (unlikely(np->events & NVREG_IRQ_LINK)) {
+		spin_lock(&np->lock);
+		nv_link_irq(dev);
+		spin_unlock(&np->lock);
+	}
+	if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+		spin_lock(&np->lock);
+		nv_linkchange(dev);
+		spin_unlock(&np->lock);
+		np->link_timeout = jiffies + LINK_TIMEOUT;
 	}
+	if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+		spin_lock(&np->lock);
+		/* disable interrupts on the nic */
+		if (!(np->msi_flags & NV_MSI_X_ENABLED))
+			writel(0, base + NvRegIrqMask);
+		else
+			writel(np->irqmask, base + NvRegIrqMask);
+		pci_push(base);
+
+		if (!np->in_shutdown) {
+			np->nic_poll_irq = np->irqmask;
+			np->recover_error = 1;
+			mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+		}
+		spin_unlock(&np->lock);
+	}
+
+#endif
 	dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name);
 
-	return IRQ_RETVAL(i);
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t nv_nic_irq_tx(int foo, void *data)
@@ -3627,10 +3690,6 @@ static irqreturn_t nv_nic_irq_tx(int foo
 		nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
 		spin_unlock_irqrestore(&np->lock, flags);
 
-		if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
-			dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
-						dev->name, events);
-		}
 		if (unlikely(i > max_interrupt_work)) {
 			spin_lock_irqsave(&np->lock, flags);
 			/* disable interrupts on the nic */
@@ -3659,13 +3718,22 @@ static int nv_napi_poll(struct napi_stru
 	struct net_device *dev = np->dev;
 	u8 __iomem *base = get_hwbase(dev);
 	unsigned long flags;
-	int pkts, retcode;
+	int retcode;
+	int tx_work, rx_work;
 
 	if (!nv_optimized(np)) {
-		pkts = nv_rx_process(dev, budget);
+		spin_lock_irqsave(&np->lock, flags);
+		tx_work = nv_tx_done(dev, np->tx_ring_size);
+		spin_unlock_irqrestore(&np->lock, flags);
+
+		rx_work = nv_rx_process(dev, budget);
 		retcode = nv_alloc_rx(dev);
 	} else {
-		pkts = nv_rx_process_optimized(dev, budget);
+		spin_lock_irqsave(&np->lock, flags);
+		tx_work = nv_tx_done_optimized(dev, np->tx_ring_size);
+		spin_unlock_irqrestore(&np->lock, flags);
+
+		rx_work = nv_rx_process_optimized(dev, budget);
 		retcode = nv_alloc_rx_optimized(dev);
 	}
 
@@ -3676,44 +3744,42 @@ static int nv_napi_poll(struct napi_stru
 		spin_unlock_irqrestore(&np->lock, flags);
 	}
 
-	if (pkts < budget) {
-		/* re-enable receive interrupts */
-		spin_lock_irqsave(&np->lock, flags);
-
-		__netif_rx_complete(napi);
-
-		np->irqmask |= NVREG_IRQ_RX_ALL;
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-		else
-			writel(np->irqmask, base + NvRegIrqMask);
+	nv_change_interrupt_mode(dev, tx_work + rx_work);
 
+	if (unlikely(np->events & NVREG_IRQ_LINK)) {
+		spin_lock_irqsave(&np->lock, flags);
+		nv_link_irq(dev);
 		spin_unlock_irqrestore(&np->lock, flags);
 	}
-	return pkts;
-}
-#endif
-
-#ifdef CONFIG_FORCEDETH_NAPI
-static irqreturn_t nv_nic_irq_rx(int foo, void *data)
-{
-	struct net_device *dev = (struct net_device *) data;
-	struct fe_priv *np = netdev_priv(dev);
-	u8 __iomem *base = get_hwbase(dev);
-	u32 events;
+	if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+		spin_lock_irqsave(&np->lock, flags);
+		nv_linkchange(dev);
+		spin_unlock_irqrestore(&np->lock, flags);
+		np->link_timeout = jiffies + LINK_TIMEOUT;
+	}
+	if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+		spin_lock_irqsave(&np->lock, flags);
+		if (!np->in_shutdown) {
+			np->nic_poll_irq = np->irqmask;
+			np->recover_error = 1;
+			mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+		}
+		spin_unlock_irqrestore(&np->lock, flags);
+		napi_complete(napi);
+		return rx_work;
+	}
 
-	events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
-	writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
+	if (rx_work < budget) {
+		/* re-enable interrupts
+		   (msix not enabled in napi) */
+		napi_complete(napi);
 
-	if (events) {
-		netif_rx_schedule(&np->napi);
-		/* disable receive interrupts on the nic */
-		writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-		pci_push(base);
+		writel(np->irqmask, base + NvRegIrqMask);
 	}
-	return IRQ_HANDLED;
+	return rx_work;
 }
-#else
+#endif
+
 static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 {
 	struct net_device *dev = (struct net_device *) data;
@@ -3760,7 +3826,6 @@ static irqreturn_t nv_nic_irq_rx(int foo
 
 	return IRQ_RETVAL(i);
 }
-#endif
 
 static irqreturn_t nv_nic_irq_other(int foo, void *data)
 {
@@ -3810,10 +3875,6 @@ static irqreturn_t nv_nic_irq_other(int
 			spin_unlock_irq(&np->lock);
 			break;
 		}
-		if (events & (NVREG_IRQ_UNKNOWN)) {
-			printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
-						dev->name, events);
-		}
 		if (unlikely(i > max_interrupt_work)) {
 			spin_lock_irqsave(&np->lock, flags);
 			/* disable interrupts on the nic */
@@ -3918,21 +3979,27 @@ static int nv_request_irq(struct net_dev
 			np->msi_flags |= NV_MSI_X_ENABLED;
 			if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) {
 				/* Request irq for rx handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, IRQF_SHARED, dev->name, dev) != 0) {
+				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) {
 					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;
 					goto out_err;
 				}
 				/* Request irq for tx handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, IRQF_SHARED, dev->name, dev) != 0) {
+				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) {
 					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;
 					goto out_free_rx;
 				}
 				/* Request irq for link and timer handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, IRQF_SHARED, dev->name, dev) != 0) {
+				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) {
 					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;
@@ -4046,19 +4113,19 @@ static void nv_do_nic_poll(unsigned long
 			mask |= NVREG_IRQ_OTHER;
 		}
 	}
-	np->nic_poll_irq = 0;
-
 	/* disable_irq() contains synchronize_irq, thus no irq handler can run now */
 
 	if (np->recover_error) {
 		np->recover_error = 0;
-		printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
+		printk(KERN_INFO "%s: MAC in recoverable error state\n", dev->name);
 		if (netif_running(dev)) {
 			netif_tx_lock_bh(dev);
 			netif_addr_lock(dev);
 			spin_lock(&np->lock);
 			/* stop engines */
 			nv_stop_rxtx(dev);
+			if (np->driver_data & DEV_HAS_POWER_CNTRL)
+				nv_mac_reset(dev);
 			nv_txrx_reset(dev);
 			/* drain rx queue */
 			nv_drain_rxtx(dev);
@@ -4076,6 +4143,11 @@ static void nv_do_nic_poll(unsigned long
 			pci_push(base);
 			writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
 			pci_push(base);
+			/* clear interrupts */
+			if (!(np->msi_flags & NV_MSI_X_ENABLED))
+				writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+			else
+				writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
 
 			/* restart rx engine */
 			nv_start_rxtx(dev);
@@ -4085,11 +4157,11 @@ static void nv_do_nic_poll(unsigned long
 		}
 	}
 
-
 	writel(mask, base + NvRegIrqMask);
 	pci_push(base);
 
 	if (!using_multi_irqs(dev)) {
+		np->nic_poll_irq = 0;
 		if (nv_optimized(np))
 			nv_nic_irq_optimized(0, dev);
 		else
@@ -4100,18 +4172,22 @@ static void nv_do_nic_poll(unsigned long
 			enable_irq_lockdep(np->pci_dev->irq);
 	} else {
 		if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
+			np->nic_poll_irq &= ~NVREG_IRQ_RX_ALL;
 			nv_nic_irq_rx(0, dev);
 			enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 		}
 		if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
+			np->nic_poll_irq &= ~NVREG_IRQ_TX_ALL;
 			nv_nic_irq_tx(0, dev);
 			enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
 		}
 		if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
+			np->nic_poll_irq &= ~NVREG_IRQ_OTHER;
 			nv_nic_irq_other(0, dev);
 			enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
 		}
 	}
+
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4560,6 +4636,7 @@ static int nv_set_ringparam(struct net_d
 
 	if (netif_running(dev)) {
 		nv_disable_irq(dev);
+		nv_napi_disable(dev);
 		netif_tx_lock_bh(dev);
 		netif_addr_lock(dev);
 		spin_lock(&np->lock);
@@ -4612,6 +4689,7 @@ static int nv_set_ringparam(struct net_d
 		spin_unlock(&np->lock);
 		netif_addr_unlock(dev);
 		netif_tx_unlock_bh(dev);
+		nv_napi_enable(dev);
 		nv_enable_irq(dev);
 	}
 	return 0;
@@ -4738,7 +4816,7 @@ static int nv_set_tx_csum(struct net_dev
 	struct fe_priv *np = netdev_priv(dev);
 
 	if (np->driver_data & DEV_HAS_CHECKSUM)
-		return ethtool_op_set_tx_hw_csum(dev, data);
+		return ethtool_op_set_tx_csum(dev, data);
 	else
 		return -EOPNOTSUPP;
 }
@@ -4764,12 +4842,12 @@ static int nv_get_sset_count(struct net_
 		else
 			return NV_TEST_COUNT_BASE;
 	case ETH_SS_STATS:
-		if (np->driver_data & DEV_HAS_STATISTICS_V1)
-			return NV_DEV_STATISTICS_V1_COUNT;
+		if (np->driver_data & DEV_HAS_STATISTICS_V3)
+			return NV_DEV_STATISTICS_V3_COUNT;
 		else if (np->driver_data & DEV_HAS_STATISTICS_V2)
 			return NV_DEV_STATISTICS_V2_COUNT;
-		else if (np->driver_data & DEV_HAS_STATISTICS_V3)
-			return NV_DEV_STATISTICS_V3_COUNT;
+		else if (np->driver_data & DEV_HAS_STATISTICS_V1)
+			return NV_DEV_STATISTICS_V1_COUNT;
 		else
 			return 0;
 	default:
@@ -5038,9 +5116,7 @@ static void nv_self_test(struct net_devi
 	if (test->flags & ETH_TEST_FL_OFFLINE) {
 		if (netif_running(dev)) {
 			netif_stop_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
-			napi_disable(&np->napi);
-#endif
+			nv_napi_disable(dev);
 			netif_tx_lock_bh(dev);
 			netif_addr_lock(dev);
 			spin_lock_irq(&np->lock);
@@ -5098,9 +5174,7 @@ static void nv_self_test(struct net_devi
 			/* restart rx engine */
 			nv_start_rxtx(dev);
 			netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
-			napi_enable(&np->napi);
-#endif
+			nv_napi_enable(dev);
 			nv_enable_hw_interrupts(dev, np->irqmask);
 		}
 	}
@@ -5169,6 +5243,7 @@ static void nv_vlan_rx_register(struct n
 /* The mgmt unit and driver use a semaphore to access the phy during init */
 static int nv_mgmt_acquire_sema(struct net_device *dev)
 {
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	int i;
 	u32 tx_ctrl, mgmt_sema;
@@ -5191,8 +5266,10 @@ static int nv_mgmt_acquire_sema(struct n
 		/* verify that semaphore was acquired */
 		tx_ctrl = readl(base + NvRegTransmitterControl);
 		if (((tx_ctrl & NVREG_XMITCTL_HOST_SEMA_MASK) == NVREG_XMITCTL_HOST_SEMA_ACQ) &&
-		    ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE))
+		    ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) {
+			np->mgmt_sema = 1;
 			return 1;
+		}
 		else
 			udelay(50);
 	}
@@ -5200,6 +5277,51 @@ static int nv_mgmt_acquire_sema(struct n
 	return 0;
 }
 
+static void nv_mgmt_release_sema(struct net_device *dev)
+{
+	struct fe_priv *np = netdev_priv(dev);
+	u8 __iomem *base = get_hwbase(dev);
+	u32 tx_ctrl;
+
+	if (np->driver_data & DEV_HAS_MGMT_UNIT) {
+		if (np->mgmt_sema) {
+			tx_ctrl = readl(base + NvRegTransmitterControl);
+			tx_ctrl &= ~NVREG_XMITCTL_HOST_SEMA_ACQ;
+			writel(tx_ctrl, base + NvRegTransmitterControl);
+		}
+	}
+}
+
+
+static int nv_mgmt_get_version(struct net_device *dev)
+{
+	struct fe_priv *np = netdev_priv(dev);
+	u8 __iomem *base = get_hwbase(dev);
+	u32 data_ready = readl(base + NvRegTransmitterControl);
+	u32 data_ready2 = 0;
+	unsigned long start;
+	int ready = 0;
+
+	writel(NVREG_MGMTUNITGETVERSION, base + NvRegMgmtUnitGetVersion);
+	writel(data_ready ^ NVREG_XMITCTL_DATA_START, base + NvRegTransmitterControl);
+	start = jiffies;
+	while (time_before(jiffies, start + 5*HZ)) {
+		data_ready2 = readl(base + NvRegTransmitterControl);
+		if ((data_ready & NVREG_XMITCTL_DATA_READY) != (data_ready2 & NVREG_XMITCTL_DATA_READY)) {
+			ready = 1;
+			break;
+		}
+		schedule_timeout_uninterruptible(1);
+	}
+
+	if (!ready || (data_ready2 & NVREG_XMITCTL_DATA_ERROR))
+		return 0;
+
+	np->mgmt_version = readl(base + NvRegMgmtUnitVersion) & NVREG_MGMTUNITVERSION;
+
+	return 1;
+}
+
 static int nv_open(struct net_device *dev)
 {
 	struct fe_priv *np = netdev_priv(dev);
@@ -5344,9 +5466,7 @@ static int nv_open(struct net_device *de
 	ret = nv_update_linkspeed(dev);
 	nv_start_rxtx(dev);
 	netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
-	napi_enable(&np->napi);
-#endif
+	nv_napi_enable(dev);
 
 	if (ret) {
 		netif_carrier_on(dev);
@@ -5378,9 +5498,7 @@ static int nv_close(struct net_device *d
 	spin_lock_irq(&np->lock);
 	np->in_shutdown = 1;
 	spin_unlock_irq(&np->lock);
-#ifdef CONFIG_FORCEDETH_NAPI
-	napi_disable(&np->napi);
-#endif
+	nv_napi_disable(dev);
 	synchronize_irq(np->pci_dev->irq);
 
 	del_timer_sync(&np->oom_kick);
@@ -5404,7 +5522,7 @@ static int nv_close(struct net_device *d
 
 	nv_drain_rxtx(dev);
 
-	if (np->wolenabled) {
+	if (np->wolenabled || !phy_power_down) {
 		writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
 		nv_start_rx(dev);
 	} else {
@@ -5534,12 +5652,12 @@ static int __devinit nv_probe(struct pci
 		np->desc_ver = DESC_VER_3;
 		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
 		if (dma_64bit) {
-			if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK))
+			if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(39)))
 				dev_printk(KERN_INFO, &pci_dev->dev,
 					"64-bit DMA failed, using 32-bit addressing\n");
 			else
 				dev->features |= NETIF_F_HIGHDMA;
-			if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) {
+			if (pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(39))) {
 				dev_printk(KERN_INFO, &pci_dev->dev,
 					"64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
 			}
@@ -5571,14 +5689,6 @@ static int __devinit nv_probe(struct pci
 		dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
 	}
 
-	np->msi_flags = 0;
-	if ((id->driver_data & DEV_HAS_MSI) && msi) {
-		np->msi_flags |= NV_MSI_CAPABLE;
-	}
-	if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
-		np->msi_flags |= NV_MSI_X_CAPABLE;
-	}
-
 	np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;
 	if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||
 	    (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) ||
@@ -5723,14 +5833,35 @@ static int __devinit nv_probe(struct pci
 	} else {
 		np->tx_flags = NV_TX2_VALID;
 	}
-	if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
-		np->irqmask = NVREG_IRQMASK_THROUGHPUT;
-		if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
-			np->msi_flags |= 0x0003;
-	} else {
+
+	np->msi_flags = 0;
+	if ((id->driver_data & DEV_HAS_MSI) && msi) {
+		np->msi_flags |= NV_MSI_CAPABLE;
+	}
+	if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
+		/* msix has had reported issues when modifying irqmask
+		   as in the case of napi, therefore, disable for now
+		*/
+#ifndef CONFIG_FORCEDETH_NAPI
+		np->msi_flags |= NV_MSI_X_CAPABLE;
+#endif
+	}
+
+	if (optimization_mode == NV_OPTIMIZATION_MODE_CPU) {
 		np->irqmask = NVREG_IRQMASK_CPU;
 		if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
 			np->msi_flags |= 0x0001;
+	} else if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC &&
+		   !(id->driver_data & DEV_NEED_TIMERIRQ)) {
+		/* start off in throughput mode */
+		np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+		/* remove support for msix mode */
+		np->msi_flags &= ~NV_MSI_X_CAPABLE;
+	} else {
+		optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+		np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+		if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
+			np->msi_flags |= 0x0003;
 	}
 
 	if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -5771,19 +5902,26 @@ static int __devinit nv_probe(struct pci
 
 	if (id->driver_data & DEV_HAS_MGMT_UNIT) {
 		/* management unit running on the mac? */
-		if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
-			np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
-			dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
-			if (nv_mgmt_acquire_sema(dev)) {
-				/* management unit setup the phy already? */
-				if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
-				    NVREG_XMITCTL_SYNC_PHY_INIT) {
-					/* phy is inited by mgmt unit */
-					phyinitialized = 1;
-					dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
-				} else {
-					/* we need to init the phy */
-				}
+		if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST) &&
+		    (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) &&
+		    nv_mgmt_acquire_sema(dev) &&
+		    nv_mgmt_get_version(dev)) {
+			np->mac_in_use = 1;
+			if (np->mgmt_version > 0) {
+				np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE;
+			}
+			dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n",
+				pci_name(pci_dev), np->mac_in_use);
+			/* management unit setup the phy already? */
+			if (np->mac_in_use &&
+			    ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
+			     NVREG_XMITCTL_SYNC_PHY_INIT)) {
+				/* phy is inited by mgmt unit */
+				phyinitialized = 1;
+				dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n",
+					pci_name(pci_dev));
+			} else {
+				/* we need to init the phy */
 			}
 		}
 	}
@@ -5945,6 +6083,8 @@ static void __devexit nv_remove(struct p
 	/* restore any phy related changes */
 	nv_restore_phy(dev);
 
+	nv_mgmt_release_sema(dev);
+
 	/* free all structures */
 	free_rings(dev);
 	iounmap(get_hwbase(dev));
@@ -5995,6 +6135,11 @@ static int nv_resume(struct pci_dev *pde
 	for (i = 0;i <= np->register_size/sizeof(u32); i++)
 		writel(np->saved_config_space[i], base+i*sizeof(u32));
 
+	pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
+
+	/* restore phy state, including autoneg */
+	phy_init(dev);
+
 	netif_device_attach(dev);
 	if (netif_running(dev)) {
 		rc = nv_open(dev);
@@ -6068,115 +6213,115 @@ static struct pci_device_id pci_tbl[] =
 	},
 	{	/* CK804 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
 	},
 	{	/* CK804 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
 	},
 	{	/* MCP04 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
 	},
 	{	/* MCP04 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
 	},
 	{	/* MCP51 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
 	},
 	{	/* MCP51 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
@@ -6184,15 +6329,15 @@ static struct pci_device_id pci_tbl[] =
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{0,},
 };
@@ -6220,7 +6365,7 @@ static void __exit exit_nic(void)
 module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
 module_param(optimization_mode, int, 0);
-MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
+MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer. In dynamic mode (2), the mode toggles between throughput and CPU mode based on network load.");
 module_param(poll_interval, int, 0);
 MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
 module_param(msi, int, 0);
@@ -6231,6 +6376,8 @@ module_param(dma_64bit, int, 0);
 MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0.");
 module_param(phy_cross, int, 0);
 MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
+module_param(phy_power_down, int, 0);
+MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0).");
 
 MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
 MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fs_enet/fs_enet-main.c linux-libre-2.6.30-gnu1/drivers/net/fs_enet/fs_enet-main.c
--- linux-libre-2.6.29-gnu1/drivers/net/fs_enet/fs_enet-main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/fs_enet/fs_enet-main.c	2009-06-09 23:05:27.000000000 -0400
@@ -209,7 +209,7 @@ static int fs_enet_rx_napi(struct napi_s
 
 	if (received < budget) {
 		/* done */
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		(*fep->ops->napi_enable_rx)(dev);
 	}
 	return received;
@@ -478,7 +478,7 @@ fs_enet_interrupt(int irq, void *dev_id)
 				/* NOTE: it is possible for FCCs in NAPI mode    */
 				/* to submit a spurious interrupt while in poll  */
 				if (napi_ok)
-					__netif_rx_schedule(&fep->napi);
+					__napi_schedule(&fep->napi);
 			}
 		}
 
@@ -1019,6 +1019,22 @@ out_put_phy:
 #define IS_FEC(match) 0
 #endif
 
+static const struct net_device_ops fs_enet_netdev_ops = {
+	.ndo_open		= fs_enet_open,
+	.ndo_stop		= fs_enet_close,
+	.ndo_get_stats		= fs_enet_get_stats,
+	.ndo_start_xmit		= fs_enet_start_xmit,
+	.ndo_tx_timeout		= fs_timeout,
+	.ndo_set_multicast_list	= fs_set_multicast_list,
+	.ndo_do_ioctl		= fs_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= fs_enet_netpoll,
+#endif
+};
+
 static int __devinit fs_enet_probe(struct of_device *ofdev,
                                    const struct of_device_id *match)
 {
@@ -1093,22 +1109,13 @@ static int __devinit fs_enet_probe(struc
 	fep->tx_ring = fpi->tx_ring;
 	fep->rx_ring = fpi->rx_ring;
 
-	ndev->open = fs_enet_open;
-	ndev->hard_start_xmit = fs_enet_start_xmit;
-	ndev->tx_timeout = fs_timeout;
+	ndev->netdev_ops = &fs_enet_netdev_ops;
 	ndev->watchdog_timeo = 2 * HZ;
-	ndev->stop = fs_enet_close;
-	ndev->get_stats = fs_enet_get_stats;
-	ndev->set_multicast_list = fs_set_multicast_list;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	ndev->poll_controller = fs_enet_netpoll;
-#endif
 	if (fpi->use_napi)
 		netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi,
 		               fpi->napi_weight);
 
 	ndev->ethtool_ops = &fs_ethtool_ops;
-	ndev->do_ioctl = fs_ioctl;
 
 	init_timer(&fep->phy_timer_list);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fsl_pq_mdio.c linux-libre-2.6.30-gnu1/drivers/net/fsl_pq_mdio.c
--- linux-libre-2.6.29-gnu1/drivers/net/fsl_pq_mdio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/fsl_pq_mdio.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,469 @@
+/*
+ * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
+ * Provides Bus interface for MIIM regs
+ *
+ * Author: Andy Fleming <afleming@freescale.com>
+ *
+ * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
+ *
+ * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/ucc.h>
+
+#include "gianfar.h"
+#include "fsl_pq_mdio.h"
+
+/*
+ * 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
+ * generic mdio bus (tied to a single interface), waiting until the write is
+ * done before returning. This is helpful in programming interfaces like
+ * the TBI which control interfaces like onchip SERDES and are always tied to
+ * the local mdio pins, which may not be the same as system mdio bus, used for
+ * controlling the external PHYs, for example.
+ */
+int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
+		int regnum, u16 value)
+{
+	/* Set the PHY address and the register address we want to write */
+	out_be32(&regs->miimadd, (mii_id << 8) | regnum);
+
+	/* Write out the value we want */
+	out_be32(&regs->miimcon, value);
+
+	/* Wait for the transaction to finish */
+	while (in_be32(&regs->miimind) & MIIMIND_BUSY)
+		cpu_relax();
+
+	return 0;
+}
+
+/*
+ * Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value.  Clears miimcom first.  All PHY operation
+ * done on the bus attached to the local interface,
+ * which may be different from the generic mdio bus
+ * This is helpful in programming interfaces like
+ * the TBI which, in turn, control interfaces like onchip SERDES
+ * and are always tied to the local mdio pins, which may not be the
+ * same as system mdio bus, used for controlling the external PHYs, for eg.
+ */
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
+		int mii_id, int regnum)
+{
+	u16 value;
+
+	/* Set the PHY address and the register address we want to read */
+	out_be32(&regs->miimadd, (mii_id << 8) | regnum);
+
+	/* Clear miimcom, and then initiate a read */
+	out_be32(&regs->miimcom, 0);
+	out_be32(&regs->miimcom, MII_READ_COMMAND);
+
+	/* Wait for the transaction to finish */
+	while (in_be32(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+		cpu_relax();
+
+	/* Grab the value of the register from miimstat */
+	value = in_be32(&regs->miimstat);
+
+	return value;
+}
+
+/*
+ * 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;
+
+	/* Write to the local MII regs */
+	return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value));
+}
+
+/*
+ * Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value.  Clears miimcom first.
+ */
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+	struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+
+	/* Read the local MII regs */
+	return(fsl_pq_local_mdio_read(regs, mii_id, regnum));
+}
+
+/* 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;
+	int timeout = PHY_INIT_TIMEOUT;
+
+	mutex_lock(&bus->mdio_lock);
+
+	/* Reset the management interface */
+	out_be32(&regs->miimcfg, MIIMCFG_RESET);
+
+	/* Setup the MII Mgmt clock speed */
+	out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+
+	/* Wait until the bus is free */
+	while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
+		cpu_relax();
+
+	mutex_unlock(&bus->mdio_lock);
+
+	if (timeout < 0) {
+		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
+				bus->name);
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+/* Allocate an array which provides irq #s for each PHY on the given bus */
+static int *create_irq_map(struct device_node *np)
+{
+	int *irqs;
+	int i;
+	struct device_node *child = NULL;
+
+	irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
+
+	if (!irqs)
+		return NULL;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		irqs[i] = PHY_POLL;
+
+	while ((child = of_get_next_child(np, child)) != NULL) {
+		int irq = irq_of_parse_and_map(child, 0);
+		const u32 *id;
+
+		if (irq == NO_IRQ)
+			continue;
+
+		id = of_get_property(child, "reg", NULL);
+
+		if (!id)
+			continue;
+
+		if (*id < PHY_MAX_ADDR && *id >= 0)
+			irqs[*id] = irq;
+		else
+			printk(KERN_WARNING "%s: "
+					"%d is not a valid PHY address\n",
+					np->full_name, *id);
+	}
+
+	return irqs;
+}
+
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
+{
+	const u32 *addr;
+	u64 taddr = OF_BAD_ADDR;
+
+	addr = of_get_address(np, 0, NULL, NULL);
+	if (addr)
+		taddr = of_translate_address(np, addr);
+
+	snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+		(unsigned long long)taddr);
+}
+EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name);
+
+/* Scan the bus in reverse, looking for an empty spot */
+static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
+{
+	int i;
+
+	for (i = PHY_MAX_ADDR; i > 0; i--) {
+		u32 phy_id;
+
+		if (get_phy_id(new_bus, i, &phy_id))
+			return -1;
+
+		if (phy_id == 0xffffffff)
+			break;
+	}
+
+	return i;
+}
+
+
+#ifdef CONFIG_GIANFAR
+static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs)
+{
+	struct gfar __iomem *enet_regs;
+
+	/*
+	 * 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;
+}
+#endif
+
+
+#ifdef CONFIG_UCC_GETH
+static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id)
+{
+	struct device_node *np = NULL;
+	int err = 0;
+
+	for_each_compatible_node(np, NULL, "ucc_geth") {
+		struct resource tempres;
+
+		err = of_address_to_resource(np, 0, &tempres);
+		if (err)
+			continue;
+
+		/* if our mdio regs fall within this UCC regs range */
+		if ((start >= tempres.start) && (end <= tempres.end)) {
+			/* Find the id of the UCC */
+			const u32 *id;
+
+			id = of_get_property(np, "cell-index", NULL);
+			if (!id) {
+				id = of_get_property(np, "device-id", NULL);
+				if (!id)
+					continue;
+			}
+
+			*ucc_id = *id;
+
+			return 0;
+		}
+	}
+
+	if (err)
+		return err;
+	else
+		return -EINVAL;
+}
+#endif
+
+
+static int fsl_pq_mdio_probe(struct of_device *ofdev,
+		const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct device_node *tbi;
+	struct fsl_pq_mdio __iomem *regs;
+	u32 __iomem *tbipa;
+	struct mii_bus *new_bus;
+	int tbiaddr = -1;
+	u64 addr, size;
+	int err = 0;
+
+	new_bus = mdiobus_alloc();
+	if (NULL == new_bus)
+		return -ENOMEM;
+
+	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,
+	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) {
+		err = -ENOMEM;
+		goto err_free_bus;
+	}
+
+	new_bus->priv = (void __force *)regs;
+
+	new_bus->irq = create_irq_map(np);
+
+	if (NULL == new_bus->irq) {
+		err = -ENOMEM;
+		goto err_unmap_regs;
+	}
+
+	new_bus->parent = &ofdev->dev;
+	dev_set_drvdata(&ofdev->dev, new_bus);
+
+	if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
+			of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+			of_device_is_compatible(np, "gianfar")) {
+#ifdef CONFIG_GIANFAR
+		tbipa = get_gfar_tbipa(regs);
+#else
+		err = -ENODEV;
+		goto err_free_irqs;
+#endif
+	} else if (of_device_is_compatible(np, "fsl,ucc-mdio") ||
+			of_device_is_compatible(np, "ucc_geth_phy")) {
+#ifdef CONFIG_UCC_GETH
+		u32 id;
+
+		tbipa = &regs->utbipar;
+
+		if ((err = get_ucc_id_for_range(addr, addr + size, &id)))
+			goto err_free_irqs;
+
+		ucc_set_qe_mux_mii_mng(id - 1);
+#else
+		err = -ENODEV;
+		goto err_free_irqs;
+#endif
+	} else {
+		err = -ENODEV;
+		goto err_free_irqs;
+	}
+
+	for_each_child_of_node(np, tbi) {
+		if (!strncmp(tbi->type, "tbi-phy", 8))
+			break;
+	}
+
+	if (tbi) {
+		const u32 *prop = of_get_property(tbi, "reg", NULL);
+
+		if (prop)
+			tbiaddr = *prop;
+	}
+
+	if (tbiaddr == -1) {
+		out_be32(tbipa, 0);
+
+		tbiaddr = fsl_pq_mdio_find_free(new_bus);
+	}
+
+	/*
+	 * We define TBIPA at 0 to be illegal, opting to fail for boards that
+	 * have PHYs at 1-31, rather than change tbipa and rescan.
+	 */
+	if (tbiaddr == 0) {
+		err = -EBUSY;
+
+		goto err_free_irqs;
+	}
+
+	out_be32(tbipa, tbiaddr);
+
+	/*
+	 * The TBIPHY-only buses will find PHYs at every address,
+	 * so we mask them all but the TBI
+	 */
+	if (of_device_is_compatible(np, "fsl,gianfar-tbi"))
+		new_bus->phy_mask = ~(1 << tbiaddr);
+
+	err = mdiobus_register(new_bus);
+
+	if (err) {
+		printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
+				new_bus->name);
+		goto err_free_irqs;
+	}
+
+	return 0;
+
+err_free_irqs:
+	kfree(new_bus->irq);
+err_unmap_regs:
+	iounmap(regs);
+err_free_bus:
+	kfree(new_bus);
+
+	return err;
+}
+
+
+static int fsl_pq_mdio_remove(struct of_device *ofdev)
+{
+	struct device *device = &ofdev->dev;
+	struct mii_bus *bus = dev_get_drvdata(device);
+
+	mdiobus_unregister(bus);
+
+	dev_set_drvdata(device, NULL);
+
+	iounmap((void __iomem *)bus->priv);
+	bus->priv = NULL;
+	mdiobus_free(bus);
+
+	return 0;
+}
+
+static struct of_device_id fsl_pq_mdio_match[] = {
+	{
+		.type = "mdio",
+		.compatible = "ucc_geth_phy",
+	},
+	{
+		.type = "mdio",
+		.compatible = "gianfar",
+	},
+	{
+		.compatible = "fsl,ucc-mdio",
+	},
+	{
+		.compatible = "fsl,gianfar-tbi",
+	},
+	{
+		.compatible = "fsl,gianfar-mdio",
+	},
+	{},
+};
+
+static struct of_platform_driver fsl_pq_mdio_driver = {
+	.name = "fsl-pq_mdio",
+	.probe = fsl_pq_mdio_probe,
+	.remove = fsl_pq_mdio_remove,
+	.match_table = fsl_pq_mdio_match,
+};
+
+int __init fsl_pq_mdio_init(void)
+{
+	return of_register_platform_driver(&fsl_pq_mdio_driver);
+}
+
+void fsl_pq_mdio_exit(void)
+{
+	of_unregister_platform_driver(&fsl_pq_mdio_driver);
+}
+subsys_initcall_sync(fsl_pq_mdio_init);
+module_exit(fsl_pq_mdio_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/fsl_pq_mdio.h linux-libre-2.6.30-gnu1/drivers/net/fsl_pq_mdio.h
--- linux-libre-2.6.29-gnu1/drivers/net/fsl_pq_mdio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/fsl_pq_mdio.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Freescale PowerQUICC MDIO Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller on Freescale PowerQUICC processors
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2002-2004,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 as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __FSL_PQ_MDIO_H
+#define __FSL_PQ_MDIO_H
+
+#define MIIMIND_BUSY            0x00000001
+#define MIIMIND_NOTVALID        0x00000004
+#define MIIMCFG_INIT_VALUE	0x00000007
+#define MIIMCFG_RESET           0x80000000
+
+#define MII_READ_COMMAND       0x00000001
+
+struct fsl_pq_mdio {
+	u32 miimcfg;		/* MII management configuration reg */
+	u32 miimcom;		/* MII management command reg */
+	u32 miimadd;		/* MII management address reg */
+	u32 miimcon;		/* MII management control reg */
+	u32 miimstat;		/* MII management status reg */
+	u32 miimind;		/* MII management indication reg */
+	u8 reserved[28];	/* Space holder */
+	u32 utbipar;		/* TBI phy address reg (only on UCC) */
+} __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,
+			  int regnum, u16 value);
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
+int __init fsl_pq_mdio_init(void);
+void fsl_pq_mdio_exit(void);
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
+#endif /* FSL_PQ_MDIO_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar.c linux-libre-2.6.30-gnu1/drivers/net/gianfar.c
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,7 +93,7 @@
 #include <linux/of.h>
 
 #include "gianfar.h"
-#include "gianfar_mii.h"
+#include "fsl_pq_mdio.h"
 
 #define TX_TIMEOUT      (1*HZ)
 #undef BRIEF_GFAR_ERRORS
@@ -140,13 +140,26 @@ static void gfar_halt_nodisable(struct n
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
-
-extern const struct ethtool_ops gfar_ethtool_ops;
+static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
+static const struct net_device_ops gfar_netdev_ops = {
+	.ndo_open = gfar_enet_open,
+	.ndo_start_xmit = gfar_start_xmit,
+	.ndo_stop = gfar_close,
+	.ndo_change_mtu = gfar_change_mtu,
+	.ndo_set_multicast_list = gfar_set_multi,
+	.ndo_tx_timeout = gfar_timeout,
+	.ndo_do_ioctl = gfar_ioctl,
+	.ndo_vlan_rx_register = gfar_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = gfar_netpoll,
+#endif
+};
+
 /* Returns 1 if incoming frames use an FCB */
 static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
@@ -166,6 +179,9 @@ static int gfar_of_init(struct net_devic
 	struct gfar_private *priv = netdev_priv(dev);
 	struct device_node *np = priv->node;
 	char bus_name[MII_BUS_ID_SIZE];
+	const u32 *stash;
+	const u32 *stash_len;
+	const u32 *stash_idx;
 
 	if (!np || !of_device_is_available(np))
 		return -ENODEV;
@@ -195,6 +211,26 @@ static int gfar_of_init(struct net_devic
 		}
 	}
 
+	stash = of_get_property(np, "bd-stash", NULL);
+
+	if(stash) {
+		priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING;
+		priv->bd_stash_en = 1;
+	}
+
+	stash_len = of_get_property(np, "rx-stash-len", NULL);
+
+	if (stash_len)
+		priv->rx_stash_size = *stash_len;
+
+	stash_idx = of_get_property(np, "rx-stash-idx", NULL);
+
+	if (stash_idx)
+		priv->rx_stash_index = *stash_idx;
+
+	if (stash_len || stash_idx)
+		priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+
 	mac_addr = of_get_mac_address(np);
 	if (mac_addr)
 		memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN);
@@ -253,9 +289,9 @@ static int gfar_of_init(struct net_devic
 		id = of_get_property(phy, "reg", NULL);
 
 		of_node_put(phy);
-		of_node_put(mdio);
 
-		gfar_mdio_bus_name(bus_name, mdio);
+		fsl_pq_mdio_bus_name(bus_name, mdio);
+		of_node_put(mdio);
 		snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
 				bus_name, *id);
 	}
@@ -329,8 +365,10 @@ static int gfar_probe(struct of_device *
 		return -ENOMEM;
 
 	priv = netdev_priv(dev);
-	priv->dev = dev;
+	priv->ndev = dev;
+	priv->ofdev = ofdev;
 	priv->node = ofdev->node;
+	SET_NETDEV_DEV(dev, &ofdev->dev);
 
 	err = gfar_of_init(dev);
 
@@ -369,21 +407,12 @@ static int gfar_probe(struct of_device *
 	SET_NETDEV_DEV(dev, &ofdev->dev);
 
 	/* Fill in the dev structure */
-	dev->open = gfar_enet_open;
-	dev->hard_start_xmit = gfar_start_xmit;
-	dev->tx_timeout = gfar_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = gfar_netpoll;
-#endif
-	dev->stop = gfar_close;
-	dev->change_mtu = gfar_change_mtu;
 	dev->mtu = 1500;
-	dev->set_multicast_list = gfar_set_multi;
 
+	dev->netdev_ops = &gfar_netdev_ops;
 	dev->ethtool_ops = &gfar_ethtool_ops;
-	dev->do_ioctl = gfar_ioctl;
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
 		priv->rx_csum_enable = 1;
@@ -393,11 +422,8 @@ static int gfar_probe(struct of_device *
 
 	priv->vlgrp = NULL;
 
-	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
-		dev->vlan_rx_register = gfar_vlan_rx_register;
-
+	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN)
 		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	}
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
 		priv->extended_hash = 1;
@@ -425,7 +451,7 @@ static int gfar_probe(struct of_device *
 		priv->hash_width = 8;
 
 		priv->hash_regs[0] = &priv->regs->gaddr0;
-                priv->hash_regs[1] = &priv->regs->gaddr1;
+		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;
@@ -466,6 +492,9 @@ static int gfar_probe(struct of_device *
 		goto register_fail;
 	}
 
+	device_init_wakeup(&dev->dev,
+		priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
 	/* fill out IRQ number and name fields */
 	len_devname = strlen(dev->name);
 	strncpy(&priv->int_name_tx[0], dev->name, len_devname);
@@ -511,7 +540,7 @@ static int gfar_remove(struct of_device
 	dev_set_drvdata(&ofdev->dev, NULL);
 
 	iounmap(priv->regs);
-	free_netdev(priv->dev);
+	free_netdev(priv->ndev);
 
 	return 0;
 }
@@ -520,7 +549,7 @@ static int gfar_remove(struct of_device
 static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
 {
 	struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-	struct net_device *dev = priv->dev;
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	u32 tempval;
 
@@ -569,7 +598,7 @@ static int gfar_suspend(struct of_device
 static int gfar_resume(struct of_device *ofdev)
 {
 	struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-	struct net_device *dev = priv->dev;
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	u32 tempval;
 	int magic_packet = priv->wol_en &&
@@ -838,12 +867,12 @@ void stop_gfar(struct net_device *dev)
 		free_irq(priv->interruptTransmit, dev);
 		free_irq(priv->interruptReceive, dev);
 	} else {
- 		free_irq(priv->interruptTransmit, dev);
+		free_irq(priv->interruptTransmit, dev);
 	}
 
 	free_skb_resources(priv);
 
-	dma_free_coherent(&dev->dev,
+	dma_free_coherent(&priv->ofdev->dev,
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
@@ -865,12 +894,12 @@ static void free_skb_resources(struct gf
 		if (!priv->tx_skbuff[i])
 			continue;
 
-		dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
+		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++) {
 			txbdp++;
-			dma_unmap_page(&priv->dev->dev, txbdp->bufPtr,
+			dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
 					txbdp->length, DMA_TO_DEVICE);
 		}
 		txbdp++;
@@ -887,7 +916,7 @@ static void free_skb_resources(struct gf
 	if(priv->rx_skbuff != NULL) {
 		for (i = 0; i < priv->rx_ring_size; i++) {
 			if (priv->rx_skbuff[i]) {
-				dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
+				dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
 						priv->rx_buffer_size,
 						DMA_FROM_DEVICE);
 
@@ -953,7 +982,7 @@ int startup_gfar(struct net_device *dev)
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
 	/* Allocate memory for the buffer descriptors */
-	vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
+	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);
@@ -1165,7 +1194,7 @@ err_rxalloc_fail:
 rx_skb_fail:
 	free_skb_resources(priv);
 tx_skb_fail:
-	dma_free_coherent(&dev->dev,
+	dma_free_coherent(&priv->ofdev->dev,
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
@@ -1183,6 +1212,8 @@ static int gfar_enet_open(struct net_dev
 
 	napi_enable(&priv->napi);
 
+	skb_queue_head_init(&priv->rx_recycle);
+
 	/* Initialize a bunch of registers */
 	init_registers(dev);
 
@@ -1203,13 +1234,14 @@ static int gfar_enet_open(struct net_dev
 
 	netif_start_queue(dev);
 
+	device_set_wakeup_enable(&dev->dev, priv->wol_en);
+
 	return err;
 }
 
 static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
 {
-	struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
-
+	struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
 	cacheable_memzero(fcb, GMAC_FCB_LEN);
 
 	return fcb;
@@ -1278,6 +1310,22 @@ static int gfar_start_xmit(struct sk_buf
 
 	base = priv->tx_bd_base;
 
+	/* make space for additional header when fcb is needed */
+	if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
+			(priv->vlgrp && vlan_tx_tag_present(skb))) &&
+			(skb_headroom(skb) < GMAC_FCB_LEN)) {
+		struct sk_buff *skb_new;
+
+		skb_new = skb_realloc_headroom(skb, GMAC_FCB_LEN);
+		if (!skb_new) {
+			dev->stats.tx_errors++;
+			kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+		kfree_skb(skb);
+		skb = skb_new;
+	}
+
 	/* total number of fragments in the SKB */
 	nr_frags = skb_shinfo(skb)->nr_frags;
 
@@ -1314,7 +1362,7 @@ static int gfar_start_xmit(struct sk_buf
 			if (i == nr_frags - 1)
 				lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
 
-			bufaddr = dma_map_page(&dev->dev,
+			bufaddr = dma_map_page(&priv->ofdev->dev,
 					skb_shinfo(skb)->frags[i].page,
 					skb_shinfo(skb)->frags[i].page_offset,
 					length,
@@ -1346,7 +1394,7 @@ 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;
-	txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data,
+	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);
@@ -1389,7 +1437,7 @@ static int gfar_start_xmit(struct sk_buf
 	/* Unlock priv */
 	spin_unlock_irqrestore(&priv->txlock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Stops the kernel queue, and halts the controller */
@@ -1399,6 +1447,7 @@ static int gfar_close(struct net_device
 
 	napi_disable(&priv->napi);
 
+	skb_queue_purge(&priv->rx_recycle);
 	cancel_work_sync(&priv->reset_task);
 	stop_gfar(dev);
 
@@ -1531,11 +1580,13 @@ static void gfar_reset_task(struct work_
 {
 	struct gfar_private *priv = container_of(work, struct gfar_private,
 			reset_task);
-	struct net_device *dev = priv->dev;
+	struct net_device *dev = priv->ndev;
 
 	if (dev->flags & IFF_UP) {
+		netif_stop_queue(dev);
 		stop_gfar(dev);
 		startup_gfar(dev);
+		netif_start_queue(dev);
 	}
 
 	netif_tx_schedule_all(dev);
@@ -1578,7 +1629,7 @@ static int gfar_clean_tx_ring(struct net
 				(lstatus & BD_LENGTH_MASK))
 			break;
 
-		dma_unmap_single(&dev->dev,
+		dma_unmap_single(&priv->ofdev->dev,
 				bdp->bufPtr,
 				bdp->length,
 				DMA_TO_DEVICE);
@@ -1587,7 +1638,7 @@ static int gfar_clean_tx_ring(struct net
 		bdp = next_txbd(bdp, base, tx_ring_size);
 
 		for (i = 0; i < frags; i++) {
-			dma_unmap_page(&dev->dev,
+			dma_unmap_page(&priv->ofdev->dev,
 					bdp->bufPtr,
 					bdp->length,
 					DMA_TO_DEVICE);
@@ -1595,7 +1646,17 @@ static int gfar_clean_tx_ring(struct net
 			bdp = next_txbd(bdp, base, tx_ring_size);
 		}
 
-		dev_kfree_skb_any(skb);
+		/*
+		 * 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 &&
+				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;
 
 		skb_dirtytx = (skb_dirtytx + 1) &
@@ -1626,9 +1687,9 @@ static void gfar_schedule_cleanup(struct
 	spin_lock_irqsave(&priv->txlock, flags);
 	spin_lock(&priv->rxlock);
 
-	if (netif_rx_schedule_prep(&priv->napi)) {
+	if (napi_schedule_prep(&priv->napi)) {
 		gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
-		__netif_rx_schedule(&priv->napi);
+		__napi_schedule(&priv->napi);
 	} else {
 		/*
 		 * Clear IEVENT, so interrupts aren't called again
@@ -1654,7 +1715,7 @@ static void gfar_new_rxbdp(struct net_de
 	struct gfar_private *priv = netdev_priv(dev);
 	u32 lstatus;
 
-	bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
+	bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
 			priv->rx_buffer_size, DMA_FROM_DEVICE);
 
 	lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
@@ -1674,8 +1735,10 @@ struct sk_buff * gfar_new_skb(struct net
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
 
-	/* We have to allocate the skb, so keep trying till we succeed */
-	skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
+	skb = __skb_dequeue(&priv->rx_recycle);
+	if (!skb)
+		skb = netdev_alloc_skb(dev,
+				priv->rx_buffer_size + RXBUF_ALIGNMENT);
 
 	if (!skb)
 		return NULL;
@@ -1812,7 +1875,7 @@ int gfar_clean_rx_ring(struct net_device
 
 		skb = priv->rx_skbuff[priv->skb_currx];
 
-		dma_unmap_single(&priv->dev->dev, bdp->bufPtr,
+		dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
 				priv->rx_buffer_size, DMA_FROM_DEVICE);
 
 		/* We drop the frame if we failed to allocate a new buffer */
@@ -1822,8 +1885,17 @@ int gfar_clean_rx_ring(struct net_device
 
 			if (unlikely(!newskb))
 				newskb = skb;
-			else if (skb)
-				dev_kfree_skb_any(skb);
+			else if (skb) {
+				/*
+				 * We need to reset ->data to what it
+				 * was before gfar_new_skb() re-aligned
+				 * it to an RXBUF_ALIGNMENT boundary
+				 * before we put the skb back on the
+				 * recycle list.
+				 */
+				skb->data = skb->head + NET_SKB_PAD;
+				__skb_queue_head(&priv->rx_recycle, skb);
+			}
 		} else {
 			/* Increment the number of packets */
 			dev->stats.rx_packets++;
@@ -1835,6 +1907,8 @@ int gfar_clean_rx_ring(struct net_device
 				skb_put(skb, pkt_len);
 				dev->stats.rx_bytes += pkt_len;
 
+				if (in_irq() || irqs_disabled())
+					printk("Interrupt problem!\n");
 				gfar_process_frame(dev, skb, amount_pull);
 
 			} else {
@@ -1870,7 +1944,7 @@ int gfar_clean_rx_ring(struct net_device
 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->dev;
+	struct net_device *dev = priv->ndev;
 	int tx_cleaned = 0;
 	int rx_cleaned = 0;
 	unsigned long flags;
@@ -1891,7 +1965,7 @@ static int gfar_poll(struct napi_struct
 		return budget;
 
 	if (rx_cleaned < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		/* Clear the halt bit in RSTAT */
 		gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
@@ -2308,23 +2382,12 @@ static struct of_platform_driver gfar_dr
 
 static int __init gfar_init(void)
 {
-	int err = gfar_mdio_init();
-
-	if (err)
-		return err;
-
-	err = of_register_platform_driver(&gfar_driver);
-
-	if (err)
-		gfar_mdio_exit();
-
-	return err;
+	return of_register_platform_driver(&gfar_driver);
 }
 
 static void __exit gfar_exit(void)
 {
 	of_unregister_platform_driver(&gfar_driver);
-	gfar_mdio_exit();
 }
 
 module_init(gfar_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/gianfar_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -600,6 +600,7 @@ static int gfar_set_wol(struct net_devic
 
 	spin_lock_irqsave(&priv->bflock, flags);
 	priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
+	device_set_wakeup_enable(&dev->dev, priv->wol_en);
 	spin_unlock_irqrestore(&priv->bflock, flags);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar.h linux-libre-2.6.30-gnu1/drivers/net/gianfar.h
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar.h	2009-06-09 23:05:27.000000000 -0400
@@ -45,8 +45,6 @@
 #include <linux/crc32.h>
 #include <linux/workqueue.h>
 #include <linux/ethtool.h>
-#include <linux/fsl_devices.h>
-#include "gianfar_mii.h"
 
 /* The maximum number of packets to be handled in one call of gfar_poll */
 #define GFAR_DEV_WEIGHT 64
@@ -126,9 +124,12 @@ extern const char gfar_driver_version[];
 #define DEFAULT_RX_COALESCE 0
 #define DEFAULT_RXCOUNT	0
 
-#define MIIMCFG_INIT_VALUE	0x00000007
-#define MIIMCFG_RESET           0x80000000
-#define MIIMIND_BUSY            0x00000001
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+		| SUPPORTED_10baseT_Full \
+		| SUPPORTED_100baseT_Half \
+		| SUPPORTED_100baseT_Full \
+		| SUPPORTED_Autoneg \
+		| SUPPORTED_MII)
 
 /* TBI register addresses */
 #define MII_TBICON		0x11
@@ -258,7 +259,7 @@ extern const char gfar_driver_version[];
 (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
  IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
  | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
- | IEVENT_MAG)
+ | IEVENT_MAG | IEVENT_BABR)
 
 #define IMASK_INIT_CLEAR	0x00000000
 #define IMASK_BABR              0x80000000
@@ -736,7 +737,8 @@ struct gfar_private {
 	spinlock_t rxlock;
 
 	struct device_node *node;
-	struct net_device *dev;
+	struct net_device *ndev;
+	struct of_device *ofdev;
 	struct napi_struct napi;
 
 	/* skb array and index */
@@ -756,6 +758,8 @@ struct gfar_private {
 	unsigned int rx_stash_size;
 	unsigned int rx_stash_index;
 
+	struct sk_buff_head rx_recycle;
+
 	struct vlan_group *vlgrp;
 
 	/* Unprotected fields */
@@ -826,8 +830,7 @@ extern void gfar_halt(struct net_device
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
 void gfar_init_sysfs(struct net_device *dev);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
-			  int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
+
+extern const struct ethtool_ops gfar_ethtool_ops;
 
 #endif /* __GIANFAR_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar_mii.c linux-libre-2.6.30-gnu1/drivers/net/gianfar_mii.c
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar_mii.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar_mii.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,379 +0,0 @@
-/*
- * drivers/net/gianfar_mii.c
- *
- * Gianfar Ethernet Driver -- MIIM bus implementation
- * Provides Bus interface for MIIM regs
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
- *
- * Copyright (c) 2002-2004 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/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
-#include "gianfar.h"
-#include "gianfar_mii.h"
-
-/*
- * 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
- * generic mdio bus (tied to a single interface), waiting until the write is
- * done before returning. This is helpful in programming interfaces like
- * the TBI which control interfaces like onchip SERDES and are always tied to
- * the local mdio pins, which may not be the same as system mdio bus, used for
- * controlling the external PHYs, for example.
- */
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
-			  int regnum, u16 value)
-{
-	/* Set the PHY address and the register address we want to write */
-	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
-
-	/* Write out the value we want */
-	gfar_write(&regs->miimcon, value);
-
-	/* Wait for the transaction to finish */
-	while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
-		cpu_relax();
-
-	return 0;
-}
-
-/*
- * Read the bus for PHY at addr mii_id, register regnum, and
- * return the value.  Clears miimcom first.  All PHY operation
- * done on the bus attached to the local interface,
- * which may be different from the generic mdio bus
- * This is helpful in programming interfaces like
- * the TBI which, inturn, control interfaces like onchip SERDES
- * and are always tied to the local mdio pins, which may not be the
- * same as system mdio bus, used for controlling the external PHYs, for eg.
- */
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
-{
-	u16 value;
-
-	/* Set the PHY address and the register address we want to read */
-	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
-
-	/* Clear miimcom, and then initiate a read */
-	gfar_write(&regs->miimcom, 0);
-	gfar_write(&regs->miimcom, MII_READ_COMMAND);
-
-	/* Wait for the transaction to finish */
-	while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
-		cpu_relax();
-
-	/* Grab the value of the register from miimstat */
-	value = gfar_read(&regs->miimstat);
-
-	return value;
-}
-
-/* Write value to the PHY at mii_id at register regnum,
- * on the bus, waiting until the write is done before returning.
- * All PHY configuration is done through the TSEC1 MIIM regs */
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
-{
-	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
-
-	/* Write to the local MII regs */
-	return(gfar_local_mdio_write(regs, mii_id, regnum, value));
-}
-
-/* Read the bus for PHY at addr mii_id, register regnum, and
- * return the value.  Clears miimcom first.  All PHY
- * configuration has to be done through the TSEC1 MIIM regs */
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
-	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
-
-	/* Read the local MII regs */
-	return(gfar_local_mdio_read(regs, mii_id, regnum));
-}
-
-/* Reset the MIIM registers, and wait for the bus to free */
-static int gfar_mdio_reset(struct mii_bus *bus)
-{
-	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
-	unsigned int timeout = PHY_INIT_TIMEOUT;
-
-	mutex_lock(&bus->mdio_lock);
-
-	/* Reset the management interface */
-	gfar_write(&regs->miimcfg, MIIMCFG_RESET);
-
-	/* Setup the MII Mgmt clock speed */
-	gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
-
-	/* Wait until the bus is free */
-	while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
-			--timeout)
-		cpu_relax();
-
-	mutex_unlock(&bus->mdio_lock);
-
-	if(timeout == 0) {
-		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
-				bus->name);
-		return -EBUSY;
-	}
-
-	return 0;
-}
-
-/* Allocate an array which provides irq #s for each PHY on the given bus */
-static int *create_irq_map(struct device_node *np)
-{
-	int *irqs;
-	int i;
-	struct device_node *child = NULL;
-
-	irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
-
-	if (!irqs)
-		return NULL;
-
-	for (i = 0; i < PHY_MAX_ADDR; i++)
-		irqs[i] = PHY_POLL;
-
-	while ((child = of_get_next_child(np, child)) != NULL) {
-		int irq = irq_of_parse_and_map(child, 0);
-		const u32 *id;
-
-		if (irq == NO_IRQ)
-			continue;
-
-		id = of_get_property(child, "reg", NULL);
-
-		if (!id)
-			continue;
-
-		if (*id < PHY_MAX_ADDR && *id >= 0)
-			irqs[*id] = irq;
-		else
-			printk(KERN_WARNING "%s: "
-					"%d is not a valid PHY address\n",
-					np->full_name, *id);
-	}
-
-	return irqs;
-}
-
-
-void gfar_mdio_bus_name(char *name, struct device_node *np)
-{
-	const u32 *reg;
-
-	reg = of_get_property(np, "reg", NULL);
-
-	snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
-}
-
-/* Scan the bus in reverse, looking for an empty spot */
-static int gfar_mdio_find_free(struct mii_bus *new_bus)
-{
-	int i;
-
-	for (i = PHY_MAX_ADDR; i > 0; i--) {
-		u32 phy_id;
-
-		if (get_phy_id(new_bus, i, &phy_id))
-			return -1;
-
-		if (phy_id == 0xffffffff)
-			break;
-	}
-
-	return i;
-}
-
-static int gfar_mdio_probe(struct of_device *ofdev,
-		const struct of_device_id *match)
-{
-	struct gfar_mii __iomem *regs;
-	struct gfar __iomem *enet_regs;
-	struct mii_bus *new_bus;
-	int err = 0;
-	u64 addr, size;
-	struct device_node *np = ofdev->node;
-	struct device_node *tbi;
-	int tbiaddr = -1;
-
-	new_bus = mdiobus_alloc();
-	if (NULL == new_bus)
-		return -ENOMEM;
-
-	device_init_wakeup(&ofdev->dev, 1);
-
-	new_bus->name = "Gianfar MII Bus",
-	new_bus->read = &gfar_mdio_read,
-	new_bus->write = &gfar_mdio_write,
-	new_bus->reset = &gfar_mdio_reset,
-	gfar_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) {
-		err = -ENOMEM;
-		goto err_free_bus;
-	}
-
-	new_bus->priv = (void __force *)regs;
-
-	new_bus->irq = create_irq_map(np);
-
-	if (new_bus->irq == NULL) {
-		err = -ENOMEM;
-		goto err_unmap_regs;
-	}
-
-	new_bus->parent = &ofdev->dev;
-	dev_set_drvdata(&ofdev->dev, new_bus);
-
-	/*
-	 * This is mildly evil, but so is our hardware for doing this.
-	 * Also, we have to cast back to struct gfar_mii because of
-	 * definition weirdness done in gianfar.h.
-	 */
-	enet_regs = (struct gfar __iomem *)
-		((char *)regs - offsetof(struct gfar, gfar_mii_regs));
-
-	for_each_child_of_node(np, tbi) {
-		if (!strncmp(tbi->type, "tbi-phy", 8))
-			break;
-	}
-
-	if (tbi) {
-		const u32 *prop = of_get_property(tbi, "reg", NULL);
-
-		if (prop)
-			tbiaddr = *prop;
-	}
-
-	if (tbiaddr == -1) {
-		gfar_write(&enet_regs->tbipa, 0);
-
-		tbiaddr = gfar_mdio_find_free(new_bus);
-	}
-
-	/*
-	 * We define TBIPA at 0 to be illegal, opting to fail for boards that
-	 * have PHYs at 1-31, rather than change tbipa and rescan.
-	 */
-	if (tbiaddr == 0) {
-		err = -EBUSY;
-
-		goto err_free_irqs;
-	}
-
-	gfar_write(&enet_regs->tbipa, tbiaddr);
-
-	/*
-	 * The TBIPHY-only buses will find PHYs at every address,
-	 * so we mask them all but the TBI
-	 */
-	if (!of_device_is_compatible(np, "fsl,gianfar-mdio"))
-		new_bus->phy_mask = ~(1 << tbiaddr);
-
-	err = mdiobus_register(new_bus);
-
-	if (err != 0) {
-		printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
-				new_bus->name);
-		goto err_free_irqs;
-	}
-
-	return 0;
-
-err_free_irqs:
-	kfree(new_bus->irq);
-err_unmap_regs:
-	iounmap(regs);
-err_free_bus:
-	mdiobus_free(new_bus);
-
-	return err;
-}
-
-
-static int gfar_mdio_remove(struct of_device *ofdev)
-{
-	struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
-
-	mdiobus_unregister(bus);
-
-	dev_set_drvdata(&ofdev->dev, NULL);
-
-	iounmap((void __iomem *)bus->priv);
-	bus->priv = NULL;
-	kfree(bus->irq);
-	mdiobus_free(bus);
-
-	return 0;
-}
-
-static struct of_device_id gfar_mdio_match[] =
-{
-	{
-		.compatible = "fsl,gianfar-mdio",
-	},
-	{
-		.compatible = "fsl,gianfar-tbi",
-	},
-	{
-		.type = "mdio",
-		.compatible = "gianfar",
-	},
-	{},
-};
-
-static struct of_platform_driver gianfar_mdio_driver = {
-	.name = "fsl-gianfar_mdio",
-	.match_table = gfar_mdio_match,
-
-	.probe = gfar_mdio_probe,
-	.remove = gfar_mdio_remove,
-};
-
-int __init gfar_mdio_init(void)
-{
-	return of_register_platform_driver(&gianfar_mdio_driver);
-}
-
-void gfar_mdio_exit(void)
-{
-	of_unregister_platform_driver(&gianfar_mdio_driver);
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar_mii.h linux-libre-2.6.30-gnu1/drivers/net/gianfar_mii.h
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar_mii.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar_mii.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- * drivers/net/gianfar_mii.h
- *
- * Gianfar Ethernet Driver -- MII Management Bus Implementation
- * Driver for the MDIO bus controller in the Gianfar register space
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
- *
- * Copyright (c) 2002-2004 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.
- *
- */
-#ifndef __GIANFAR_MII_H
-#define __GIANFAR_MII_H
-
-struct gfar_private; /* forward ref */
-
-#define MIIMIND_BUSY            0x00000001
-#define MIIMIND_NOTVALID        0x00000004
-
-#define MII_READ_COMMAND       0x00000001
-
-#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
-		| SUPPORTED_10baseT_Full \
-		| SUPPORTED_100baseT_Half \
-		| SUPPORTED_100baseT_Full \
-		| SUPPORTED_Autoneg \
-		| SUPPORTED_MII)
-
-struct gfar_mii {
-	u32	miimcfg;	/* 0x.520 - MII Management Config Register */
-	u32	miimcom;	/* 0x.524 - MII Management Command Register */
-	u32	miimadd;	/* 0x.528 - MII Management Address Register */
-	u32	miimcon;	/* 0x.52c - MII Management Control Register */
-	u32	miimstat;	/* 0x.530 - MII Management Status Register */
-	u32	miimind;	/* 0x.534 - MII Management Indicator Register */
-};
-
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
-			  int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
-struct mii_bus *gfar_get_miibus(const struct gfar_private *priv);
-int __init gfar_mdio_init(void);
-void gfar_mdio_exit(void);
-
-void gfar_mdio_bus_name(char *name, struct device_node *np);
-#endif /* GIANFAR_PHY_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/gianfar_sysfs.c linux-libre-2.6.30-gnu1/drivers/net/gianfar_sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/gianfar_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/gianfar_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,9 @@ static ssize_t gfar_set_bd_stash(struct
 	u32 temp;
 	unsigned long flags;
 
+	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;
@@ -81,7 +84,7 @@ static ssize_t gfar_set_bd_stash(struct
 	return count;
 }
 
-DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
+static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
 
 static ssize_t gfar_show_rx_stash_size(struct device *dev,
 				       struct device_attribute *attr, char *buf)
@@ -100,6 +103,9 @@ static ssize_t gfar_set_rx_stash_size(st
 	u32 temp;
 	unsigned long flags;
 
+	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+		return count;
+
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (length > priv->rx_buffer_size)
 		goto out;
@@ -130,8 +136,8 @@ out:
 	return count;
 }
 
-DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
-	    gfar_set_rx_stash_size);
+static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
+		   gfar_set_rx_stash_size);
 
 /* Stashing will only be enabled when rx_stash_size != 0 */
 static ssize_t gfar_show_rx_stash_index(struct device *dev,
@@ -152,6 +158,9 @@ static ssize_t gfar_set_rx_stash_index(s
 	u32 temp;
 	unsigned long flags;
 
+	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+		return count;
+
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (index > priv->rx_stash_size)
 		goto out;
@@ -172,8 +181,8 @@ out:
 	return count;
 }
 
-DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
-	    gfar_set_rx_stash_index);
+static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
+		   gfar_set_rx_stash_index);
 
 static ssize_t gfar_show_fifo_threshold(struct device *dev,
 					struct device_attribute *attr,
@@ -210,8 +219,8 @@ static ssize_t gfar_set_fifo_threshold(s
 	return count;
 }
 
-DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
-	    gfar_set_fifo_threshold);
+static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
+		   gfar_set_fifo_threshold);
 
 static ssize_t gfar_show_fifo_starve(struct device *dev,
 				     struct device_attribute *attr, char *buf)
@@ -247,7 +256,8 @@ static ssize_t gfar_set_fifo_starve(stru
 	return count;
 }
 
-DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve);
+static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
+		   gfar_set_fifo_starve);
 
 static ssize_t gfar_show_fifo_starve_off(struct device *dev,
 					 struct device_attribute *attr,
@@ -284,8 +294,8 @@ static ssize_t gfar_set_fifo_starve_off(
 	return count;
 }
 
-DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
-	    gfar_set_fifo_starve_off);
+static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
+		   gfar_set_fifo_starve_off);
 
 void gfar_init_sysfs(struct net_device *dev)
 {
@@ -293,12 +303,9 @@ void gfar_init_sysfs(struct net_device *
 	int rc;
 
 	/* Initialize the default values */
-	priv->rx_stash_size = DEFAULT_STASH_LENGTH;
-	priv->rx_stash_index = DEFAULT_STASH_INDEX;
 	priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
 	priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
 	priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
-	priv->bd_stash_en = DEFAULT_BD_STASH;
 
 	/* Create our sysfs files */
 	rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamachi.c linux-libre-2.6.30-gnu1/drivers/net/hamachi.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamachi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamachi.c	2009-06-09 23:05:27.000000000 -0400
@@ -171,7 +171,7 @@ static int tx_params[MAX_UNITS] = {-1, -
 #include <asm/unaligned.h>
 #include <asm/cache.h>
 
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
 KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Written by Donald Becker\n"
 KERN_INFO "   Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
 KERN_INFO "   Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
@@ -1244,7 +1244,7 @@ do { \
     csum_add(sum, (ih)->saddr & 0xffff); \
     csum_add(sum, (ih)->daddr >> 16); \
     csum_add(sum, (ih)->daddr & 0xffff); \
-    csum_add(sum, __constant_htons(IPPROTO_UDP)); \
+    csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
     csum_add(sum, (uh)->len); \
 } while (0)
 
@@ -1255,7 +1255,7 @@ do { \
     csum_add(sum, (ih)->saddr & 0xffff); \
     csum_add(sum, (ih)->daddr >> 16); \
     csum_add(sum, (ih)->daddr & 0xffff); \
-    csum_add(sum, __constant_htons(IPPROTO_TCP)); \
+    csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
     csum_add(sum, htons(len)); \
 } while (0)
 #endif
@@ -1296,7 +1296,7 @@ static int hamachi_start_xmit(struct sk_
 	    /* tack on checksum tag */
 	    u32 tagval = 0;
 	    struct ethhdr *eh = (struct ethhdr *)skb->data;
-	    if (eh->h_proto == __constant_htons(ETH_P_IP)) {
+	    if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
 		struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
 		if (ih->protocol == IPPROTO_UDP) {
 		    struct udphdr *uh
@@ -1605,7 +1605,7 @@ static int hamachi_rx(struct net_device
 				 */
 				if (ntohs(ih->tot_len) >= 46){
 					/* don't worry about frags */
-					if (!(ih->frag_off & __constant_htons(IP_MF|IP_OFFSET))) {
+					if (!(ih->frag_off & cpu_to_be16(IP_MF|IP_OFFSET))) {
 						u32 inv = *(u32 *) &buf_addr[data_size - 16];
 						u32 *p = (u32 *) &buf_addr[data_size - 20];
 						register u32 crc, p_r, p_r1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/6pack.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/6pack.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/6pack.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/6pack.c	2009-06-09 23:05:27.000000000 -0400
@@ -322,23 +322,25 @@ static const struct header_ops sp_header
 	.rebuild	= sp_rebuild_header,
 };
 
+static const struct net_device_ops sp_netdev_ops = {
+	.ndo_open		= sp_open_dev,
+	.ndo_stop		= sp_close,
+	.ndo_start_xmit		= sp_xmit,
+	.ndo_set_mac_address    = sp_set_mac_address,
+};
+
 static void sp_setup(struct net_device *dev)
 {
 	/* Finish setting up the DEVICE info. */
-	dev->mtu		= SIXP_MTU;
-	dev->hard_start_xmit	= sp_xmit;
-	dev->open		= sp_open_dev;
+	dev->netdev_ops		= &sp_netdev_ops;
 	dev->destructor		= free_netdev;
-	dev->stop		= sp_close;
-
-	dev->set_mac_address    = sp_set_mac_address;
+	dev->mtu		= SIXP_MTU;
 	dev->hard_header_len	= AX25_MAX_HEADER_LEN;
 	dev->header_ops 	= &sp_header_ops;
 
 	dev->addr_len		= AX25_ADDR_LEN;
 	dev->type		= ARPHRD_AX25;
 	dev->tx_queue_len	= 10;
-	dev->tx_timeout		= NULL;
 
 	/* Only activated in AX.25 mode */
 	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -788,9 +790,9 @@ static struct tty_ldisc_ops sp_ldisc = {
 
 /* Initialize 6pack control device -- register 6pack line discipline */
 
-static char msg_banner[]  __initdata = KERN_INFO \
+static const char msg_banner[]  __initdata = KERN_INFO \
 	"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static char msg_regfail[] __initdata = KERN_ERR  \
+static const char msg_regfail[] __initdata = KERN_ERR  \
 	"6pack: can't register line discipline (err = %d)\n";
 
 static int __init sixpack_init_driver(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/baycom_epp.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/baycom_epp.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/baycom_epp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/baycom_epp.c	2009-06-09 23:05:27.000000000 -0400
@@ -203,7 +203,6 @@ struct baycom_state {
 		unsigned char buf[TXBUFFER_SIZE];
         } hdlctx;
 
-        struct net_device_stats stats;
 	unsigned int ptt_keyed;
 	struct sk_buff *skb;  /* next transmit packet  */
 
@@ -423,7 +422,7 @@ static void encode_hdlc(struct baycom_st
 	bc->hdlctx.bufptr = bc->hdlctx.buf;
 	bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
 	dev_kfree_skb(skb);
-	bc->stats.tx_packets++;
+	bc->dev->stats.tx_packets++;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -547,7 +546,7 @@ static void do_rxpacket(struct net_devic
 	pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
 	if (!(skb = dev_alloc_skb(pktlen))) {
 		printk("%s: memory squeeze, dropping packet\n", dev->name);
-		bc->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	cp = skb_put(skb, pktlen);
@@ -555,7 +554,7 @@ static void do_rxpacket(struct net_devic
 	memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
 	skb->protocol = ax25_type_trans(skb, dev);
 	netif_rx(skb);
-	bc->stats.rx_packets++;
+	dev->stats.rx_packets++;
 }
 
 static int receive(struct net_device *dev, int cnt)
@@ -802,19 +801,6 @@ static int baycom_set_mac_address(struct
 
 /* --------------------------------------------------------------------- */
 
-static struct net_device_stats *baycom_get_stats(struct net_device *dev)
-{
-	struct baycom_state *bc = netdev_priv(dev);
-
-	/* 
-	 * Get the current statistics.  This may be called with the
-	 * card open or closed. 
-	 */
-	return &bc->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
 static void epp_wakeup(void *handle)
 {
         struct net_device *dev = (struct net_device *)handle;
@@ -1065,10 +1051,10 @@ static int baycom_ioctl(struct net_devic
 		hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);
 		hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);
 		hi.data.cs.ptt_keyed = bc->ptt_keyed;
-		hi.data.cs.tx_packets = bc->stats.tx_packets;
-		hi.data.cs.tx_errors = bc->stats.tx_errors;
-		hi.data.cs.rx_packets = bc->stats.rx_packets;
-		hi.data.cs.rx_errors = bc->stats.rx_errors;
+		hi.data.cs.tx_packets = dev->stats.tx_packets;
+		hi.data.cs.tx_errors = dev->stats.tx_errors;
+		hi.data.cs.rx_packets = dev->stats.rx_packets;
+		hi.data.cs.rx_errors = dev->stats.rx_errors;
 		break;		
 
 	case HDLCDRVCTL_OLDGETSTAT:
@@ -1116,6 +1102,14 @@ static int baycom_ioctl(struct net_devic
 
 /* --------------------------------------------------------------------- */
 
+static const struct net_device_ops baycom_netdev_ops = {
+	.ndo_open	     = epp_open,
+	.ndo_stop	     = epp_close,
+	.ndo_do_ioctl	     = baycom_ioctl,
+	.ndo_start_xmit      = baycom_send_packet,
+	.ndo_set_mac_address = baycom_set_mac_address,
+};
+
 /*
  * Check for a network adaptor of this type, and return '0' if one exists.
  * If dev->base_addr == 0, probe all likely locations.
@@ -1143,17 +1137,12 @@ static void baycom_probe(struct net_devi
 	/*
 	 * initialize the device struct
 	 */
-	dev->open = epp_open;
-	dev->stop = epp_close;
-	dev->do_ioctl = baycom_ioctl;
-	dev->hard_start_xmit = baycom_send_packet;
-	dev->get_stats = baycom_get_stats;
 
 	/* Fill in the fields of the device structure */
 	bc->skb = NULL;
 	
+	dev->netdev_ops = &baycom_netdev_ops;
 	dev->header_ops = &ax25_header_ops;
-	dev->set_mac_address = baycom_set_mac_address;
 	
 	dev->type = ARPHRD_AX25;           /* AF_AX25 device */
 	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/bpqether.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/bpqether.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/bpqether.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/bpqether.c	2009-06-09 23:05:27.000000000 -0400
@@ -87,7 +87,8 @@
 
 #include <linux/bpqether.h>
 
-static char banner[] __initdata = KERN_INFO "AX.25: bpqether driver version 004\n";
+static const char banner[] __initdata = KERN_INFO \
+	"AX.25: bpqether driver version 004\n";
 
 static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
 
@@ -96,8 +97,8 @@ static char bpq_eth_addr[6];
 static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
 static int bpq_device_event(struct notifier_block *, unsigned long, void *);
 
-static struct packet_type bpq_packet_type = {
-	.type	= __constant_htons(ETH_P_BPQ),
+static struct packet_type bpq_packet_type __read_mostly = {
+	.type	= cpu_to_be16(ETH_P_BPQ),
 	.func	= bpq_rcv,
 };
 
@@ -110,7 +111,6 @@ struct bpqdev {
 	struct list_head bpq_list;	/* list of bpq devices chain */
 	struct net_device *ethdev;	/* link to ethernet device */
 	struct net_device *axdev;	/* bpq device (bpq#) */
-	struct net_device_stats stats;	/* some statistics */
 	char   dest_addr[6];		/* ether destination address */
 	char   acpt_addr[6];		/* accept ether frames from this address only */
 };
@@ -222,8 +222,8 @@ static int bpq_rcv(struct sk_buff *skb,
 	skb_pull(skb, 2);	/* Remove the length bytes */
 	skb_trim(skb, len);	/* Set the length of the data */
 
-	bpq->stats.rx_packets++;
-	bpq->stats.rx_bytes += len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += len;
 
 	ptr = skb_push(skb, 1);
 	*ptr = 0;
@@ -292,7 +292,7 @@ static int bpq_xmit(struct sk_buff *skb,
 	bpq = netdev_priv(dev);
 
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
-		bpq->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		kfree_skb(skb);
 		return -ENODEV;
 	}
@@ -300,8 +300,8 @@ static int bpq_xmit(struct sk_buff *skb,
 	skb->protocol = ax25_type_trans(skb, dev);
 	skb_reset_network_header(skb);
 	dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
-	bpq->stats.tx_packets++;
-	bpq->stats.tx_bytes+=skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes+=skb->len;
   
 	dev_queue_xmit(skb);
 	netif_wake_queue(dev);
@@ -309,16 +309,6 @@ static int bpq_xmit(struct sk_buff *skb,
 }
 
 /*
- *	Statistics
- */
-static struct net_device_stats *bpq_get_stats(struct net_device *dev)
-{
-	struct bpqdev *bpq = netdev_priv(dev);
-
-	return &bpq->stats;
-}
-
-/*
  *	Set AX.25 callsign
  */
 static int bpq_set_mac_address(struct net_device *dev, void *addr)
@@ -396,6 +386,7 @@ static int bpq_close(struct net_device *
  *	Proc filesystem
  */
 static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
+	__acquires(RCU)
 {
 	int i = 1;
 	struct bpqdev *bpqdev;
@@ -428,6 +419,7 @@ static void *bpq_seq_next(struct seq_fil
 }
 
 static void bpq_seq_stop(struct seq_file *seq, void *v)
+	__releases(RCU)
 {
 	rcu_read_unlock();
 }
@@ -454,7 +446,7 @@ static int bpq_seq_show(struct seq_file
 	return 0;
 }
 
-static struct seq_operations bpq_seqops = {
+static const struct seq_operations bpq_seqops = {
 	.start = bpq_seq_start,
 	.next = bpq_seq_next,
 	.stop = bpq_seq_stop,
@@ -477,16 +469,17 @@ static const struct file_operations bpq_
 
 /* ------------------------------------------------------------------------ */
 
+static const struct net_device_ops bpq_netdev_ops = {
+	.ndo_open	     = bpq_open,
+	.ndo_stop	     = bpq_close,
+	.ndo_start_xmit	     = bpq_xmit,
+	.ndo_set_mac_address = bpq_set_mac_address,
+	.ndo_do_ioctl	     = bpq_ioctl,
+};
 
 static void bpq_setup(struct net_device *dev)
 {
-
-	dev->hard_start_xmit = bpq_xmit;
-	dev->open	     = bpq_open;
-	dev->stop	     = bpq_close;
-	dev->set_mac_address = bpq_set_mac_address;
-	dev->get_stats	     = bpq_get_stats;
-	dev->do_ioctl	     = bpq_ioctl;
+	dev->netdev_ops	     = &bpq_netdev_ops;
 	dev->destructor	     = free_netdev;
 
 	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/dmascc.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/dmascc.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/dmascc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/dmascc.c	2009-06-09 23:05:27.000000000 -0400
@@ -195,7 +195,7 @@ struct scc_priv {
 	int chip;
 	struct net_device *dev;
 	struct scc_info *info;
-	struct net_device_stats stats;
+
 	int channel;
 	int card_base, scc_cmd, scc_data;
 	int tmr_cnt, tmr_ctrl, tmr_mode;
@@ -239,7 +239,6 @@ static int scc_open(struct net_device *d
 static int scc_close(struct net_device *dev);
 static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static int scc_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *scc_get_stats(struct net_device *dev);
 static int scc_set_mac_address(struct net_device *dev, void *sa);
 
 static inline void tx_on(struct scc_priv *priv);
@@ -441,6 +440,14 @@ static void __init dev_setup(struct net_
 	memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
 }
 
+static const struct net_device_ops scc_netdev_ops = {
+	.ndo_open = scc_open,
+	.ndo_stop = scc_close,
+	.ndo_start_xmit = scc_send_packet,
+	.ndo_do_ioctl = scc_ioctl,
+	.ndo_set_mac_address = scc_set_mac_address,
+};
+
 static int __init setup_adapter(int card_base, int type, int n)
 {
 	int i, irq, chip;
@@ -576,13 +583,8 @@ static int __init setup_adapter(int card
 		sprintf(dev->name, "dmascc%i", 2 * n + i);
 		dev->base_addr = card_base;
 		dev->irq = irq;
-		dev->open = scc_open;
-		dev->stop = scc_close;
-		dev->do_ioctl = scc_ioctl;
-		dev->hard_start_xmit = scc_send_packet;
-		dev->get_stats = scc_get_stats;
+		dev->netdev_ops = &scc_netdev_ops;
 		dev->header_ops = &ax25_header_ops;
-		dev->set_mac_address = scc_set_mac_address;
 	}
 	if (register_netdev(info->dev[0])) {
 		printk(KERN_ERR "dmascc: could not register %s\n",
@@ -961,14 +963,6 @@ static int scc_send_packet(struct sk_buf
 }
 
 
-static struct net_device_stats *scc_get_stats(struct net_device *dev)
-{
-	struct scc_priv *priv = dev->ml_priv;
-
-	return &priv->stats;
-}
-
-
 static int scc_set_mac_address(struct net_device *dev, void *sa)
 {
 	memcpy(dev->dev_addr, ((struct sockaddr *) sa)->sa_data,
@@ -1216,17 +1210,17 @@ static void special_condition(struct scc
 		}
 		if (priv->rx_over) {
 			/* We had an overrun */
-			priv->stats.rx_errors++;
+			priv->dev->stats.rx_errors++;
 			if (priv->rx_over == 2)
-				priv->stats.rx_length_errors++;
+				priv->dev->stats.rx_length_errors++;
 			else
-				priv->stats.rx_fifo_errors++;
+				priv->dev->stats.rx_fifo_errors++;
 			priv->rx_over = 0;
 		} else if (rc & CRC_ERR) {
 			/* Count invalid CRC only if packet length >= minimum */
 			if (cb >= 15) {
-				priv->stats.rx_errors++;
-				priv->stats.rx_crc_errors++;
+				priv->dev->stats.rx_errors++;
+				priv->dev->stats.rx_crc_errors++;
 			}
 		} else {
 			if (cb >= 15) {
@@ -1239,8 +1233,8 @@ static void special_condition(struct scc
 					priv->rx_count++;
 					schedule_work(&priv->rx_work);
 				} else {
-					priv->stats.rx_errors++;
-					priv->stats.rx_over_errors++;
+					priv->dev->stats.rx_errors++;
+					priv->dev->stats.rx_over_errors++;
 				}
 			}
 		}
@@ -1275,7 +1269,7 @@ static void rx_bh(struct work_struct *ug
 		skb = dev_alloc_skb(cb + 1);
 		if (skb == NULL) {
 			/* Drop packet */
-			priv->stats.rx_dropped++;
+			priv->dev->stats.rx_dropped++;
 		} else {
 			/* Fill buffer */
 			data = skb_put(skb, cb + 1);
@@ -1283,8 +1277,8 @@ static void rx_bh(struct work_struct *ug
 			memcpy(&data[1], priv->rx_buf[i], cb);
 			skb->protocol = ax25_type_trans(skb, priv->dev);
 			netif_rx(skb);
-			priv->stats.rx_packets++;
-			priv->stats.rx_bytes += cb;
+			priv->dev->stats.rx_packets++;
+			priv->dev->stats.rx_bytes += cb;
 		}
 		spin_lock_irqsave(&priv->ring_lock, flags);
 		/* Move tail */
@@ -1351,15 +1345,15 @@ static void es_isr(struct scc_priv *priv
 			write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
 		if (res) {
 			/* Update packet statistics */
-			priv->stats.tx_errors++;
-			priv->stats.tx_fifo_errors++;
+			priv->dev->stats.tx_errors++;
+			priv->dev->stats.tx_fifo_errors++;
 			/* Other underrun interrupts may already be waiting */
 			write_scc(priv, R0, RES_EXT_INT);
 			write_scc(priv, R0, RES_EXT_INT);
 		} else {
 			/* Update packet statistics */
-			priv->stats.tx_packets++;
-			priv->stats.tx_bytes += priv->tx_len[i];
+			priv->dev->stats.tx_packets++;
+			priv->dev->stats.tx_bytes += priv->tx_len[i];
 			/* Remove frame from FIFO */
 			priv->tx_tail = (i + 1) % NUM_TX_BUF;
 			priv->tx_count--;
@@ -1425,7 +1419,7 @@ static void tm_isr(struct scc_priv *priv
 		write_scc(priv, R15, DCDIE);
 		priv->rr0 = read_scc(priv, R0);
 		if (priv->rr0 & DCD) {
-			priv->stats.collisions++;
+			priv->dev->stats.collisions++;
 			rx_on(priv);
 			priv->state = RX_ON;
 		} else {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/hdlcdrv.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/hdlcdrv.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/hdlcdrv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/hdlcdrv.c	2009-06-09 23:05:27.000000000 -0400
@@ -154,7 +154,7 @@ static void hdlc_rx_flag(struct net_devi
 	pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
 	if (!(skb = dev_alloc_skb(pkt_len))) {
 		printk("%s: memory squeeze, dropping packet\n", dev->name);
-		s->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	cp = skb_put(skb, pkt_len);
@@ -162,7 +162,7 @@ static void hdlc_rx_flag(struct net_devi
 	memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
 	skb->protocol = ax25_type_trans(skb, dev);
 	netif_rx(skb);
-	s->stats.rx_packets++;
+	dev->stats.rx_packets++;
 }
 
 void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
@@ -326,7 +326,7 @@ void hdlcdrv_transmitter(struct net_devi
 			s->hdlctx.len = pkt_len+2; /* the appended CRC */
 			s->hdlctx.tx_state = 2;
 			s->hdlctx.bitstream = 0;
-			s->stats.tx_packets++;
+			dev->stats.tx_packets++;
 			break;
 		case 2:
 			if (!s->hdlctx.len) {
@@ -427,19 +427,6 @@ static int hdlcdrv_set_mac_address(struc
 }
 
 /* --------------------------------------------------------------------- */
-
-static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
-{
-	struct hdlcdrv_state *sm = netdev_priv(dev);
-
-	/* 
-	 * Get the current statistics.  This may be called with the
-	 * card open or closed. 
-	 */
-	return &sm->stats;
-}
-
-/* --------------------------------------------------------------------- */
 /*
  * Open/initialize the board. This is called (in the current kernel)
  * sometime after booting when the 'ifconfig' program is run.
@@ -568,10 +555,10 @@ static int hdlcdrv_ioctl(struct net_devi
 		bi.data.cs.ptt = hdlcdrv_ptt(s);
 		bi.data.cs.dcd = s->hdlcrx.dcd;
 		bi.data.cs.ptt_keyed = s->ptt_keyed;
-		bi.data.cs.tx_packets = s->stats.tx_packets;
-		bi.data.cs.tx_errors = s->stats.tx_errors;
-		bi.data.cs.rx_packets = s->stats.rx_packets;
-		bi.data.cs.rx_errors = s->stats.rx_errors;
+		bi.data.cs.tx_packets = dev->stats.tx_packets;
+		bi.data.cs.tx_errors = dev->stats.tx_errors;
+		bi.data.cs.rx_packets = dev->stats.rx_packets;
+		bi.data.cs.rx_errors = dev->stats.rx_errors;
 		break;		
 
 	case HDLCDRVCTL_OLDGETSTAT:
@@ -630,6 +617,14 @@ static int hdlcdrv_ioctl(struct net_devi
 
 /* --------------------------------------------------------------------- */
 
+static const struct net_device_ops hdlcdrv_netdev = {
+	.ndo_open	= hdlcdrv_open,
+	.ndo_stop	= hdlcdrv_close,
+	.ndo_start_xmit = hdlcdrv_send_packet,
+	.ndo_do_ioctl	= hdlcdrv_ioctl,
+	.ndo_set_mac_address = hdlcdrv_set_mac_address,
+};
+
 /*
  * Initialize fields in hdlcdrv
  */
@@ -669,21 +664,13 @@ static void hdlcdrv_setup(struct net_dev
 	s->bitbuf_hdlc.shreg = 0x80;
 #endif /* HDLCDRV_DEBUG */
 
-	/*
-	 * initialize the device struct
-	 */
-	dev->open = hdlcdrv_open;
-	dev->stop = hdlcdrv_close;
-	dev->do_ioctl = hdlcdrv_ioctl;
-	dev->hard_start_xmit = hdlcdrv_send_packet;
-	dev->get_stats = hdlcdrv_get_stats;
 
 	/* Fill in the fields of the device structure */
 
 	s->skb = NULL;
 	
+	dev->netdev_ops = &hdlcdrv_netdev;
 	dev->header_ops = &ax25_header_ops;
-	dev->set_mac_address = hdlcdrv_set_mac_address;
 	
 	dev->type = ARPHRD_AX25;           /* AF_AX25 device */
 	dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/mkiss.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/mkiss.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/mkiss.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/mkiss.c	2009-06-09 23:05:27.000000000 -0400
@@ -59,8 +59,6 @@ struct mkiss {
 	unsigned char		*xhead;	/* pointer to next byte to XMIT */
 	int			xleft;	/* bytes left in XMIT queue     */
 
-	struct net_device_stats	stats;
-
 	/* Detailed SLIP statistics. */
 	int		mtu;		/* Our mtu (to spot changes!)   */
 	int		buffsize;	/* Max buffers sizes            */
@@ -253,7 +251,7 @@ static void ax_bump(struct mkiss *ax)
 	if (ax->rbuff[0] > 0x0f) {
 		if (ax->rbuff[0] & 0x80) {
 			if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
-				ax->stats.rx_errors++;
+				ax->dev->stats.rx_errors++;
 				spin_unlock_bh(&ax->buflock);
 
 				return;
@@ -268,7 +266,7 @@ static void ax_bump(struct mkiss *ax)
 			*ax->rbuff &= ~0x80;
 		} else if (ax->rbuff[0] & 0x20)  {
 			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
-				ax->stats.rx_errors++;
+				ax->dev->stats.rx_errors++;
 				spin_unlock_bh(&ax->buflock);
 				return;
 			}
@@ -295,7 +293,7 @@ static void ax_bump(struct mkiss *ax)
 	if ((skb = dev_alloc_skb(count)) == NULL) {
 		printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
 		       ax->dev->name);
-		ax->stats.rx_dropped++;
+		ax->dev->stats.rx_dropped++;
 		spin_unlock_bh(&ax->buflock);
 		return;
 	}
@@ -303,8 +301,8 @@ static void ax_bump(struct mkiss *ax)
 	memcpy(skb_put(skb,count), ax->rbuff, count);
 	skb->protocol = ax25_type_trans(skb, ax->dev);
 	netif_rx(skb);
-	ax->stats.rx_packets++;
-	ax->stats.rx_bytes += count;
+	ax->dev->stats.rx_packets++;
+	ax->dev->stats.rx_bytes += count;
 	spin_unlock_bh(&ax->buflock);
 }
 
@@ -344,7 +342,7 @@ static void kiss_unesc(struct mkiss *ax,
 			return;
 		}
 
-		ax->stats.rx_over_errors++;
+		ax->dev->stats.rx_over_errors++;
 		set_bit(AXF_ERROR, &ax->flags);
 	}
 	spin_unlock_bh(&ax->buflock);
@@ -406,7 +404,7 @@ static void ax_changedmtu(struct mkiss *
 			memcpy(ax->xbuff, ax->xhead, ax->xleft);
 		} else  {
 			ax->xleft = 0;
-			ax->stats.tx_dropped++;
+			dev->stats.tx_dropped++;
 		}
 	}
 
@@ -417,7 +415,7 @@ static void ax_changedmtu(struct mkiss *
 			memcpy(ax->rbuff, orbuff, ax->rcount);
 		} else  {
 			ax->rcount = 0;
-			ax->stats.rx_over_errors++;
+			dev->stats.rx_over_errors++;
 			set_bit(AXF_ERROR, &ax->flags);
 		}
 	}
@@ -444,7 +442,7 @@ static void ax_encaps(struct net_device
 	if (len > ax->mtu) {		/* Sigh, shouldn't occur BUT ... */
 		len = ax->mtu;
 		printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
-		ax->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		netif_start_queue(dev);
 		return;
 	}
@@ -518,8 +516,8 @@ static void ax_encaps(struct net_device
 
 	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
 	actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
-	ax->stats.tx_packets++;
-	ax->stats.tx_bytes += actual;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += actual;
 
 	ax->dev->trans_start = jiffies;
 	ax->xleft = count - actual;
@@ -664,32 +662,28 @@ static int ax_close(struct net_device *d
 	return 0;
 }
 
-static struct net_device_stats *ax_get_stats(struct net_device *dev)
-{
-	struct mkiss *ax = netdev_priv(dev);
-
-	return &ax->stats;
-}
-
 static const struct header_ops ax_header_ops = {
 	.create    = ax_header,
 	.rebuild   = ax_rebuild_header,
 };
 
+static const struct net_device_ops ax_netdev_ops = {
+	.ndo_open            = ax_open_dev,
+	.ndo_stop            = ax_close,
+	.ndo_start_xmit	     = ax_xmit,
+	.ndo_set_mac_address = ax_set_mac_address,
+};
+
 static void ax_setup(struct net_device *dev)
 {
 	/* Finish setting up the DEVICE info. */
 	dev->mtu             = AX_MTU;
-	dev->hard_start_xmit = ax_xmit;
-	dev->open            = ax_open_dev;
-	dev->stop            = ax_close;
-	dev->get_stats	     = ax_get_stats;
-	dev->set_mac_address = ax_set_mac_address;
 	dev->hard_header_len = 0;
 	dev->addr_len        = 0;
 	dev->type            = ARPHRD_AX25;
 	dev->tx_queue_len    = 10;
 	dev->header_ops      = &ax_header_ops;
+	dev->netdev_ops	     = &ax_netdev_ops;
 
 
 	memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -929,7 +923,7 @@ static void mkiss_receive_buf(struct tty
 	while (count--) {
 		if (fp != NULL && *fp++) {
 			if (!test_and_set_bit(AXF_ERROR, &ax->flags))
-				ax->stats.rx_errors++;
+				ax->dev->stats.rx_errors++;
 			cp++;
 			continue;
 		}
@@ -982,9 +976,9 @@ static struct tty_ldisc_ops ax_ldisc = {
 	.write_wakeup	= mkiss_write_wakeup
 };
 
-static char banner[] __initdata = KERN_INFO \
+static const char banner[] __initdata = KERN_INFO \
 	"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
 	"mkiss: can't register line discipline (err = %d)\n";
 
 static int __init mkiss_init_driver(void)
@@ -993,8 +987,9 @@ static int __init mkiss_init_driver(void
 
 	printk(banner);
 
-	if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
-		printk(msg_regfail);
+	status = tty_register_ldisc(N_AX25, &ax_ldisc);
+	if (status != 0)
+		printk(msg_regfail, status);
 
 	return status;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/scc.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/scc.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/scc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/scc.c	2009-06-09 23:05:27.000000000 -0400
@@ -184,7 +184,8 @@
 
 #include "z8530.h"
 
-static char banner[] __initdata = KERN_INFO "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
+static const char banner[] __initdata = KERN_INFO \
+	"AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
 
 static void t_dwait(unsigned long);
 static void t_txdelay(unsigned long);
@@ -1542,23 +1543,24 @@ static int scc_net_alloc(const char *nam
 /* *			    Network driver methods		      * */
 /* ******************************************************************** */
 
+static const struct net_device_ops scc_netdev_ops = {
+	.ndo_open            = scc_net_open,
+	.ndo_stop	     = scc_net_close,
+	.ndo_start_xmit	     = scc_net_tx,
+	.ndo_set_mac_address = scc_net_set_mac_address,
+	.ndo_get_stats       = scc_net_get_stats,
+	.ndo_do_ioctl        = scc_net_ioctl,
+};
+
 /* ----> Initialize device <----- */
 
 static void scc_net_setup(struct net_device *dev)
 {
 	dev->tx_queue_len    = 16;	/* should be enough... */
 
-	dev->open            = scc_net_open;
-	dev->stop	     = scc_net_close;
-
-	dev->hard_start_xmit = scc_net_tx;
+	dev->netdev_ops	     = &scc_netdev_ops;
 	dev->header_ops      = &ax25_header_ops;
 
-	dev->set_mac_address = scc_net_set_mac_address;
-	dev->get_stats       = scc_net_get_stats;
-	dev->do_ioctl        = scc_net_ioctl;
-	dev->tx_timeout      = NULL;
-
 	memcpy(dev->broadcast, &ax25_bcast,  AX25_ADDR_LEN);
 	memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN);
  
@@ -2073,7 +2075,7 @@ static int scc_net_seq_show(struct seq_f
         return 0;
 }
 
-static struct seq_operations scc_net_seq_ops = {
+static const struct seq_operations scc_net_seq_ops = {
 	.start  = scc_net_seq_start,
 	.next   = scc_net_seq_next,
 	.stop   = scc_net_seq_stop,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hamradio/yam.c linux-libre-2.6.30-gnu1/drivers/net/hamradio/yam.c
--- linux-libre-2.6.29-gnu1/drivers/net/hamradio/yam.c	2013-05-03 18:03:38.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hamradio/yam.c	2013-05-03 16:47:29.000000000 -0400
@@ -55,6 +55,8 @@
 #include <asm/system.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
 
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
@@ -71,15 +73,18 @@
 #include <linux/init.h>
 
 #include <linux/yam.h>
-/*(DEBLOBBED)*/
 
 /* --------------------------------------------------------------------- */
 
 static const char yam_drvname[] = "yam";
-static char yam_drvinfo[] __initdata = KERN_INFO "YAM driver version 0.8 by F1OAT/F6FBB\n";
+static const char yam_drvinfo[] __initdata = KERN_INFO \
+	"YAM driver version 0.8 by F1OAT/F6FBB\n";
 
 /* --------------------------------------------------------------------- */
 
+#define FIRMWARE_9600	"/*(DEBLOBBED)*/"
+#define FIRMWARE_1200	"/*(DEBLOBBED)*/"
+
 #define YAM_9600	1
 #define YAM_1200	2
 
@@ -114,10 +119,6 @@ struct yam_port {
 
 	struct net_device *dev;
 
-	/* Stats section */
-
-	struct net_device_stats stats;
-
 	int nb_rxint;
 	int nb_mdint;
 
@@ -344,9 +345,51 @@ static int fpga_write(int iobase, unsign
 	return 0;
 }
 
-static unsigned char *add_mcs(unsigned char *bits, int bitrate)
+/*
+ * predef should be 0 for loading user defined mcs
+ * predef should be YAM_1200 for loading predef 1200 mcs
+ * predef should be YAM_9600 for loading predef 9600 mcs
+ */
+static unsigned char *add_mcs(unsigned char *bits, int bitrate,
+			      unsigned int predef)
 {
+	const char *fw_name[2] = {FIRMWARE_9600, FIRMWARE_1200};
+	const struct firmware *fw;
+	struct platform_device *pdev;
 	struct yam_mcs *p;
+	int err;
+
+	switch (predef) {
+	case 0:
+		fw = NULL;
+		break;
+	case YAM_1200:
+	case YAM_9600:
+		predef--;
+		pdev = platform_device_register_simple("yam", 0, NULL, 0);
+		if (IS_ERR(pdev)) {
+			printk(KERN_ERR "yam: Failed to register firmware\n");
+			return NULL;
+		}
+		err = reject_firmware(&fw, fw_name[predef], &pdev->dev);
+		platform_device_unregister(pdev);
+		if (err) {
+			printk(KERN_ERR "Failed to load firmware \"%s\"\n",
+			       fw_name[predef]);
+			return NULL;
+		}
+		if (fw->size != YAM_FPGA_SIZE) {
+			printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n",
+			       fw->size, fw_name[predef]);
+			release_firmware(fw);
+			return NULL;
+		}
+		bits = (unsigned char *)fw->data;
+		break;
+	default:
+		printk(KERN_ERR "yam: Invalid predef number %u\n", predef);
+		return NULL;
+	}
 
 	/* If it already exists, replace the bit data */
 	p = yam_data;
@@ -361,6 +404,7 @@ static unsigned char *add_mcs(unsigned c
 	/* Allocate a new mcs */
 	if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) {
 		printk(KERN_WARNING "YAM: no memory to allocate mcs\n");
+		release_firmware(fw);
 		return NULL;
 	}
 	memcpy(p->bits, bits, YAM_FPGA_SIZE);
@@ -368,6 +412,7 @@ static unsigned char *add_mcs(unsigned c
 	p->next = yam_data;
 	yam_data = p;
 
+	release_firmware(fw);
 	return p->bits;
 }
 
@@ -385,11 +430,11 @@ static unsigned char *get_mcs(int bitrat
 	/* Load predefined mcs data */
 	switch (bitrate) {
 	case 1200:
-		printk(KERN_ERR "yam: Missing Free firmware\n");
-		return NULL;
+		/* setting predef as YAM_1200 for loading predef 1200 mcs */
+		return add_mcs(NULL, bitrate, YAM_1200);
 	default:
-		printk(KERN_ERR "yam: Missing Free firmware\n");
-		return NULL;
+		/* setting predef as YAM_9600 for loading predef 9600 mcs */
+		return add_mcs(NULL, bitrate, YAM_9600);
 	}
 }
 
@@ -508,7 +553,7 @@ static inline void yam_rx_flag(struct ne
 		} else {
 			if (!(skb = dev_alloc_skb(pkt_len))) {
 				printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
-				++yp->stats.rx_dropped;
+				++dev->stats.rx_dropped;
 			} else {
 				unsigned char *cp;
 				cp = skb_put(skb, pkt_len);
@@ -516,7 +561,7 @@ static inline void yam_rx_flag(struct ne
 				memcpy(cp, yp->rx_buf, pkt_len - 1);
 				skb->protocol = ax25_type_trans(skb, dev);
 				netif_rx(skb);
-				++yp->stats.rx_packets;
+				++dev->stats.rx_packets;
 			}
 		}
 	}
@@ -678,7 +723,7 @@ static void yam_tx_byte(struct net_devic
 			yp->tx_count = 1;
 			yp->tx_state = TX_HEAD;
 		}
-		++yp->stats.tx_packets;
+		++dev->stats.tx_packets;
 		break;
 	case TX_TAIL:
 		if (--yp->tx_count <= 0) {
@@ -717,7 +762,7 @@ static irqreturn_t yam_interrupt(int irq
 			handled = 1;
 
 			if (lsr & LSR_OE)
-				++yp->stats.rx_fifo_errors;
+				++dev->stats.rx_fifo_errors;
 
 			yp->dcd = (msr & RX_DCD) ? 1 : 0;
 
@@ -779,16 +824,16 @@ static int yam_seq_show(struct seq_file
 	seq_printf(seq, "  TxTail   %u\n", yp->txtail);
 	seq_printf(seq, "  SlotTime %u\n", yp->slot);
 	seq_printf(seq, "  Persist  %u\n", yp->pers);
-	seq_printf(seq, "  TxFrames %lu\n", yp->stats.tx_packets);
-	seq_printf(seq, "  RxFrames %lu\n", yp->stats.rx_packets);
+	seq_printf(seq, "  TxFrames %lu\n", dev->stats.tx_packets);
+	seq_printf(seq, "  RxFrames %lu\n", dev->stats.rx_packets);
 	seq_printf(seq, "  TxInt    %u\n", yp->nb_mdint);
 	seq_printf(seq, "  RxInt    %u\n", yp->nb_rxint);
-	seq_printf(seq, "  RxOver   %lu\n", yp->stats.rx_fifo_errors);
+	seq_printf(seq, "  RxOver   %lu\n", dev->stats.rx_fifo_errors);
 	seq_printf(seq, "\n");
 	return 0;
 }
 
-static struct seq_operations yam_seqops = {
+static const struct seq_operations yam_seqops = {
 	.start = yam_seq_start,
 	.next = yam_seq_next,
 	.stop = yam_seq_stop,
@@ -813,26 +858,6 @@ static const struct file_operations yam_
 
 /* --------------------------------------------------------------------- */
 
-static struct net_device_stats *yam_get_stats(struct net_device *dev)
-{
-	struct yam_port *yp;
-
-	if (!dev)
-		return NULL;
-
-	yp = netdev_priv(dev);
-	if (yp->magic != YAM_MAGIC)
-		return NULL;
-
-	/* 
-	 * Get the current statistics.  This may be called with the
-	 * card open or closed. 
-	 */
-	return &yp->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
 static int yam_open(struct net_device *dev)
 {
 	struct yam_port *yp = netdev_priv(dev);
@@ -878,10 +903,10 @@ static int yam_open(struct net_device *d
 
 	/* Reset overruns for all ports - FPGA programming makes overruns */
 	for (i = 0; i < NR_PORTS; i++) {
-		struct net_device *dev = yam_devs[i];
-		struct yam_port *yp = netdev_priv(dev);
-		inb(LSR(dev->base_addr));
-		yp->stats.rx_fifo_errors = 0;
+		struct net_device *yam_dev = yam_devs[i];
+
+		inb(LSR(yam_dev->base_addr));
+		yam_dev->stats.rx_fifo_errors = 0;
 	}
 
 	printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
@@ -960,7 +985,8 @@ static int yam_ioctl(struct net_device *
 			kfree(ym);
 			return -EINVAL;
 		}
-		add_mcs(ym->bits, ym->bitrate);
+		/* setting predef as 0 for loading userdefined mcs data */
+		add_mcs(ym->bits, ym->bitrate, 0);
 		kfree(ym);
 		break;
 
@@ -1069,6 +1095,14 @@ static int yam_set_mac_address(struct ne
 
 /* --------------------------------------------------------------------- */
 
+static const struct net_device_ops yam_netdev_ops = {
+	.ndo_open	     = yam_open,
+	.ndo_stop	     = yam_close,
+	.ndo_start_xmit      = yam_send_packet,
+	.ndo_do_ioctl 	     = yam_ioctl,
+	.ndo_set_mac_address = yam_set_mac_address,
+};
+
 static void yam_setup(struct net_device *dev)
 {
 	struct yam_port *yp = netdev_priv(dev);
@@ -1089,18 +1123,11 @@ static void yam_setup(struct net_device
 	dev->base_addr = yp->iobase;
 	dev->irq = yp->irq;
 
-	dev->open = yam_open;
-	dev->stop = yam_close;
-	dev->do_ioctl = yam_ioctl;
-	dev->hard_start_xmit = yam_send_packet;
-	dev->get_stats = yam_get_stats;
-
 	skb_queue_head_init(&yp->send_queue);
 
+	dev->netdev_ops = &yam_netdev_ops;
 	dev->header_ops = &ax25_header_ops;
 
-	dev->set_mac_address = yam_set_mac_address;
-
 	dev->type = ARPHRD_AX25;
 	dev->hard_header_len = AX25_MAX_HEADER_LEN;
 	dev->mtu = AX25_MTU;
@@ -1182,6 +1209,7 @@ static void __exit yam_cleanup_driver(vo
 MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
 MODULE_DESCRIPTION("Yam amateur radio modem driver");
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 
 module_init(yam_init_driver);
 module_exit(yam_cleanup_driver);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/hp100.c linux-libre-2.6.30-gnu1/drivers/net/hp100.c
--- linux-libre-2.6.29-gnu1/drivers/net/hp100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/hp100.c	2009-06-09 23:05:27.000000000 -0400
@@ -580,7 +580,7 @@ static int __devinit hp100_probe1(struct
 			 * Also, we can have EISA Busmaster cards (not tested),
 			 * so beware !!! - Jean II */
 			if((bus == HP100_BUS_PCI) &&
-			   (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK))) {
+			   (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)))) {
 				/* Gracefully fallback to shared memory */
 				goto busmasterfail;
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ibmlana.c linux-libre-2.6.30-gnu1/drivers/net/ibmlana.c
--- linux-libre-2.6.29-gnu1/drivers/net/ibmlana.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ibmlana.c	2009-06-09 23:05:27.000000000 -0400
@@ -905,6 +905,17 @@ static char *ibmlana_adapter_names[] __d
 	NULL
 };
 
+
+static const struct net_device_ops ibmlana_netdev_ops = {
+	.ndo_open 		= ibmlana_open,
+	.ndo_stop 		= ibmlana_close,
+	.ndo_start_xmit		= ibmlana_tx,
+	.ndo_set_multicast_list = ibmlana_set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __devinit ibmlana_init_one(struct device *kdev)
 {
 	struct mca_device *mdev = to_mca_device(kdev);
@@ -973,11 +984,7 @@ static int __devinit ibmlana_init_one(st
 	mca_device_set_claim(mdev, 1);
 
 	/* set methods */
-
-	dev->open = ibmlana_open;
-	dev->stop = ibmlana_close;
-	dev->hard_start_xmit = ibmlana_tx;
-	dev->set_multicast_list = ibmlana_set_multicast_list;
+	dev->netdev_ops = &ibmlana_netdev_ops;
 	dev->flags |= IFF_MULTICAST;
 
 	/* copy out MAC address */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ibm_newemac/core.c linux-libre-2.6.30-gnu1/drivers/net/ibm_newemac/core.c
--- linux-libre-2.6.29-gnu1/drivers/net/ibm_newemac/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ibm_newemac/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -134,7 +134,7 @@ static inline void emac_report_timeout_e
 				  EMAC_FTR_440EP_PHY_CLK_FIX))
 		DBG(dev, "%s" NL, error);
 	else if (net_ratelimit())
-		printk(KERN_ERR "%s: %s\n", dev->ndev->name, error);
+		printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error);
 }
 
 /* EMAC PHY clock workaround:
@@ -1229,7 +1229,7 @@ static int emac_link_differs(struct emac
 static void emac_link_timer(struct work_struct *work)
 {
 	struct emac_instance *dev =
-		container_of((struct delayed_work *)work,
+		container_of(to_delayed_work(work),
 			     struct emac_instance, link_work);
 	int link_poll_interval;
 
@@ -2686,6 +2686,32 @@ static int __devinit emac_init_config(st
 	return 0;
 }
 
+static const struct net_device_ops emac_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_close,
+	.ndo_get_stats		= emac_stats,
+	.ndo_set_multicast_list	= emac_set_multicast_list,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_tx_timeout		= emac_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_start_xmit		= emac_start_xmit,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
+static const struct net_device_ops emac_gige_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_close,
+	.ndo_get_stats		= emac_stats,
+	.ndo_set_multicast_list	= emac_set_multicast_list,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_tx_timeout		= emac_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_start_xmit		= emac_start_xmit_sg,
+	.ndo_change_mtu		= emac_change_mtu,
+};
+
 static int __devinit emac_probe(struct of_device *ofdev,
 				const struct of_device_id *match)
 {
@@ -2827,23 +2853,14 @@ static int __devinit emac_probe(struct o
 	if (err != 0)
 		goto err_detach_tah;
 
-	/* Fill in the driver function table */
-	ndev->open = &emac_open;
 	if (dev->tah_dev)
 		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-	ndev->tx_timeout = &emac_tx_timeout;
 	ndev->watchdog_timeo = 5 * HZ;
-	ndev->stop = &emac_close;
-	ndev->get_stats = &emac_stats;
-	ndev->set_multicast_list = &emac_set_multicast_list;
-	ndev->do_ioctl = &emac_ioctl;
 	if (emac_phy_supports_gige(dev->phy_mode)) {
-		ndev->hard_start_xmit = &emac_start_xmit_sg;
-		ndev->change_mtu = &emac_change_mtu;
+		ndev->netdev_ops = &emac_gige_netdev_ops;
 		dev->commac.ops = &emac_commac_sg_ops;
-	} else {
-		ndev->hard_start_xmit = &emac_start_xmit;
-	}
+	} else
+		ndev->netdev_ops = &emac_netdev_ops;
 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 
 	netif_carrier_off(ndev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ibmveth.c linux-libre-2.6.30-gnu1/drivers/net/ibmveth.c
--- linux-libre-2.6.29-gnu1/drivers/net/ibmveth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ibmveth.c	2009-06-09 23:05:27.000000000 -0400
@@ -1028,10 +1028,10 @@ static int ibmveth_poll(struct napi_stru
 
 		ibmveth_assert(lpar_rc == H_SUCCESS);
 
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		if (ibmveth_rxq_pending_buffer(adapter) &&
-		    netif_rx_reschedule(napi)) {
+		    napi_reschedule(napi)) {
 			lpar_rc = h_vio_signal(adapter->vdev->unit_address,
 					       VIO_IRQ_DISABLE);
 			goto restart_poll;
@@ -1047,11 +1047,11 @@ static irqreturn_t ibmveth_interrupt(int
 	struct ibmveth_adapter *adapter = netdev_priv(netdev);
 	unsigned long lpar_rc;
 
-	if (netif_rx_schedule_prep(&adapter->napi)) {
+	if (napi_schedule_prep(&adapter->napi)) {
 		lpar_rc = h_vio_signal(adapter->vdev->unit_address,
 				       VIO_IRQ_DISABLE);
 		ibmveth_assert(lpar_rc == H_SUCCESS);
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	}
 	return IRQ_HANDLED;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_82575.c linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_82575.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_82575.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_82575.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 - 2008 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -62,17 +62,12 @@ static bool igb_sgmii_active_82575(struc
 static s32  igb_reset_init_script_82575(struct e1000_hw *);
 static s32  igb_read_mac_addr_82575(struct e1000_hw *);
 
-
-struct e1000_dev_spec_82575 {
-	bool sgmii_active;
-};
-
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	struct e1000_nvm_info *nvm = &hw->nvm;
 	struct e1000_mac_info *mac = &hw->mac;
-	struct e1000_dev_spec_82575 *dev_spec;
+	struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
 	u32 eecd;
 	s32 ret_val;
 	u16 size;
@@ -85,8 +80,10 @@ static s32 igb_get_invariants_82575(stru
 		mac->type = e1000_82575;
 		break;
 	case E1000_DEV_ID_82576:
+	case E1000_DEV_ID_82576_NS:
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
+	case E1000_DEV_ID_82576_QUAD_COPPER:
 		mac->type = e1000_82576;
 		break;
 	default:
@@ -94,17 +91,6 @@ static s32 igb_get_invariants_82575(stru
 		break;
 	}
 
-	/* MAC initialization */
-	hw->dev_spec_size = sizeof(struct e1000_dev_spec_82575);
-
-	/* Device-specific structure allocation */
-	hw->dev_spec = kzalloc(hw->dev_spec_size, GFP_KERNEL);
-
-	if (!hw->dev_spec)
-		return -ENOMEM;
-
-	dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
 	/* Set media type */
 	/*
 	 * The 82575 uses bits 22:23 for link mode. The mode can be changed
@@ -195,13 +181,13 @@ static s32 igb_get_invariants_82575(stru
 
 	/* PHY function pointers */
 	if (igb_sgmii_active_82575(hw)) {
-		phy->ops.reset_phy          = igb_phy_hw_reset_sgmii_82575;
-		phy->ops.read_phy_reg       = igb_read_phy_reg_sgmii_82575;
-		phy->ops.write_phy_reg      = igb_write_phy_reg_sgmii_82575;
+		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 {
-		phy->ops.reset_phy          = igb_phy_hw_reset;
-		phy->ops.read_phy_reg       = igb_read_phy_reg_igp;
-		phy->ops.write_phy_reg      = igb_write_phy_reg_igp;
+		phy->ops.reset              = igb_phy_hw_reset;
+		phy->ops.read_reg           = igb_read_phy_reg_igp;
+		phy->ops.write_reg          = igb_write_phy_reg_igp;
 	}
 
 	/* Set phy->phy_addr and phy->id. */
@@ -229,6 +215,10 @@ static s32 igb_get_invariants_82575(stru
 		return -E1000_ERR_PHY;
 	}
 
+	/* if 82576 then initialize mailbox parameters */
+	if (mac->type == e1000_82576)
+		igb_init_mbx_params_pf(hw);
+
 	return 0;
 }
 
@@ -451,7 +441,7 @@ static s32 igb_phy_hw_reset_sgmii_82575(
 	 * SFP documentation requires the following to configure the SPF module
 	 * to work on SGMII.  No further documentation is given.
 	 */
-	ret_val = hw->phy.ops.write_phy_reg(hw, 0x1B, 0x8084);
+	ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
 	if (ret_val)
 		goto out;
 
@@ -480,28 +470,28 @@ static s32 igb_set_d0_lplu_state_82575(s
 	s32 ret_val;
 	u16 data;
 
-	ret_val = phy->ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
+	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
 	if (ret_val)
 		goto out;
 
 	if (active) {
 		data |= IGP02E1000_PM_D0_LPLU;
-		ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
 						 data);
 		if (ret_val)
 			goto out;
 
 		/* When LPLU is enabled, we should disable SmartSpeed */
-		ret_val = phy->ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
 						&data);
 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-		ret_val = phy->ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
 						 data);
 		if (ret_val)
 			goto out;
 	} else {
 		data &= ~IGP02E1000_PM_D0_LPLU;
-		ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
 						 data);
 		/*
 		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
@@ -510,24 +500,24 @@ static s32 igb_set_d0_lplu_state_82575(s
 		 * SmartSpeed, so performance is maintained.
 		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
-			ret_val = phy->ops.read_phy_reg(hw,
+			ret_val = phy->ops.read_reg(hw,
 					IGP01E1000_PHY_PORT_CONFIG, &data);
 			if (ret_val)
 				goto out;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = phy->ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 					IGP01E1000_PHY_PORT_CONFIG, data);
 			if (ret_val)
 				goto out;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
-			ret_val = phy->ops.read_phy_reg(hw,
+			ret_val = phy->ops.read_reg(hw,
 					IGP01E1000_PHY_PORT_CONFIG, &data);
 			if (ret_val)
 				goto out;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = phy->ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 					IGP01E1000_PHY_PORT_CONFIG, data);
 			if (ret_val)
 				goto out;
@@ -803,7 +793,7 @@ static void igb_init_rx_addrs_82575(stru
 }
 
 /**
- *  igb_update_mc_addr_list_82575 - Update Multicast addresses
+ *  igb_update_mc_addr_list - Update Multicast addresses
  *  @hw: pointer to the HW structure
  *  @mc_addr_list: array of multicast addresses to program
  *  @mc_addr_count: number of multicast addresses to program
@@ -815,9 +805,9 @@ static void igb_init_rx_addrs_82575(stru
  *  The parameter rar_count will usually be hw->mac.rar_entry_count
  *  unless there are workarounds that change this.
  **/
-void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
-                                   u8 *mc_addr_list, u32 mc_addr_count,
-                                   u32 rar_used_count, u32 rar_count)
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+                             u8 *mc_addr_list, u32 mc_addr_count,
+                             u32 rar_used_count, u32 rar_count)
 {
 	u32 hash_value;
 	u32 i;
@@ -1051,7 +1041,7 @@ static s32 igb_setup_copper_link_82575(s
 		 * depending on user settings.
 		 */
 		hw_dbg("Forcing Speed and Duplex\n");
-		ret_val = igb_phy_force_speed_duplex(hw);
+		ret_val = hw->phy.ops.force_speed_duplex(hw);
 		if (ret_val) {
 			hw_dbg("Error Forcing Speed and Duplex\n");
 			goto out;
@@ -1110,6 +1100,13 @@ static s32 igb_setup_fiber_serdes_link_8
 	       E1000_CTRL_SWDPIN1;
 	wr32(E1000_CTRL, reg);
 
+	/* Power on phy for 82576 fiber adapters */
+	if (hw->mac.type == e1000_82576) {
+		reg = rd32(E1000_CTRL_EXT);
+		reg &= ~E1000_CTRL_EXT_SDP7_DATA;
+		wr32(E1000_CTRL_EXT, reg);
+	}
+
 	/* Set switch control to serdes energy detect */
 	reg = rd32(E1000_CONNSW);
 	reg |= E1000_CONNSW_ENRGSRC;
@@ -1227,20 +1224,12 @@ out:
  **/
 static bool igb_sgmii_active_82575(struct e1000_hw *hw)
 {
-	struct e1000_dev_spec_82575 *dev_spec;
-	bool ret_val;
-
-	if (hw->mac.type != e1000_82575) {
-		ret_val = false;
-		goto out;
-	}
-
-	dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
 
-	ret_val = dev_spec->sgmii_active;
+	if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
+		return false;
 
-out:
-	return ret_val;
+	return dev_spec->sgmii_active;
 }
 
 /**
@@ -1430,6 +1419,44 @@ void igb_rx_fifo_flush_82575(struct e100
 	rd32(E1000_MPC);
 }
 
+/**
+ *  igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
+ *  @hw: pointer to the hardware struct
+ *  @enable: state to enter, either enabled or disabled
+ *
+ *  enables/disables L2 switch loopback functionality.
+ **/
+void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
+{
+	u32 dtxswc = rd32(E1000_DTXSWC);
+
+	if (enable)
+		dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+	else
+		dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+
+	wr32(E1000_DTXSWC, dtxswc);
+}
+
+/**
+ *  igb_vmdq_set_replication_pf - enable or disable vmdq replication
+ *  @hw: pointer to the hardware struct
+ *  @enable: state to enter, either enabled or disabled
+ *
+ *  enables/disables replication of packets across multiple pools.
+ **/
+void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
+{
+	u32 vt_ctl = rd32(E1000_VT_CTL);
+
+	if (enable)
+		vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
+	else
+		vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
+
+	wr32(E1000_VT_CTL, vt_ctl);
+}
+
 static struct e1000_mac_operations e1000_mac_ops_82575 = {
 	.reset_hw             = igb_reset_hw_82575,
 	.init_hw              = igb_init_hw_82575,
@@ -1440,16 +1467,16 @@ static struct e1000_mac_operations e1000
 };
 
 static struct e1000_phy_operations e1000_phy_ops_82575 = {
-	.acquire_phy          = igb_acquire_phy_82575,
+	.acquire              = igb_acquire_phy_82575,
 	.get_cfg_done         = igb_get_cfg_done_82575,
-	.release_phy          = igb_release_phy_82575,
+	.release              = igb_release_phy_82575,
 };
 
 static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
-	.acquire_nvm          = igb_acquire_nvm_82575,
-	.read_nvm             = igb_read_nvm_eerd,
-	.release_nvm          = igb_release_nvm_82575,
-	.write_nvm            = igb_write_nvm_spi,
+	.acquire              = igb_acquire_nvm_82575,
+	.read                 = igb_read_nvm_eerd,
+	.release              = igb_release_nvm_82575,
+	.write                = igb_write_nvm_spi,
 };
 
 const struct e1000_info e1000_82575_info = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_82575.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_82575.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_82575.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_82575.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 - 2008 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -28,7 +28,7 @@
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
 
-void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
+void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
 extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
@@ -40,8 +40,11 @@ extern void igb_rx_fifo_flush_82575(stru
 #define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */
 #define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000
 #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000
+#define E1000_SRRCTL_DROP_EN                            0x80000000
 
 #define E1000_MRQC_ENABLE_RSS_4Q            0x00000002
+#define E1000_MRQC_ENABLE_VMDQ              0x00000003
+#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q       0x00000005
 #define E1000_MRQC_RSS_FIELD_IPV4_UDP       0x00400000
 #define E1000_MRQC_RSS_FIELD_IPV6_UDP       0x00800000
 #define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX    0x01000000
@@ -58,9 +61,6 @@ extern void igb_rx_fifo_flush_82575(stru
     E1000_EICR_RX_QUEUE2 |    \
     E1000_EICR_RX_QUEUE3)
 
-#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
-#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
-
 /* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
 
 /* Receive Descriptor - Advanced */
@@ -95,12 +95,6 @@ union e1000_adv_rx_desc {
 #define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
 #define E1000_RXDADV_HDRBUFLEN_SHIFT     5
 
-/* RSS Hash results */
-
-/* RSS Packet Types as indicated in the receive descriptor */
-#define E1000_RXDADV_PKTTYPE_IPV4        0x00000010 /* IPV4 hdr present */
-#define E1000_RXDADV_PKTTYPE_TCP         0x00000100 /* TCP hdr present */
-
 /* Transmit Descriptor - Advanced */
 union e1000_adv_tx_desc {
 	struct {
@@ -116,6 +110,7 @@ union e1000_adv_tx_desc {
 };
 
 /* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_MAC_TSTAMP   0x00080000 /* IEEE1588 Timestamp packet */
 #define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */
 #define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */
 #define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */
@@ -149,11 +144,8 @@ struct e1000_adv_tx_context_desc {
 #define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */
 
 /* Direct Cache Access (DCA) definitions */
-#define E1000_DCA_CTRL_DCA_ENABLE  0x00000000 /* DCA Enable */
-#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
-
-#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
-#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
+#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
+#define E1000_DCA_CTRL_DCA_MODE_CB2     0x02 /* DCA Mode CB2 */
 
 #define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
 #define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
@@ -170,4 +162,44 @@ 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 */
 
+#define MAX_NUM_VFS                   8
+
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31)  /* global VF LB enable */
+
+/* Easy defines for setting default pool, would normally be left a zero */
+#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
+#define E1000_VT_CTL_DEFAULT_POOL_MASK  (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
+
+/* Other useful VMD_CTL register defines */
+#define E1000_VT_CTL_IGNORE_MAC         (1 << 28)
+#define E1000_VT_CTL_DISABLE_DEF_POOL   (1 << 29)
+#define E1000_VT_CTL_VM_REPL_EN         (1 << 30)
+
+/* Per VM Offload register setup */
+#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
+#define E1000_VMOLR_LPE        0x00010000 /* Accept Long packet */
+#define E1000_VMOLR_RSSE       0x00020000 /* Enable RSS */
+#define E1000_VMOLR_AUPE       0x01000000 /* Accept untagged packets */
+#define E1000_VMOLR_ROMPE      0x02000000 /* Accept overflow multicast */
+#define E1000_VMOLR_ROPE       0x04000000 /* Accept overflow unicast */
+#define E1000_VMOLR_BAM        0x08000000 /* Accept Broadcast packets */
+#define E1000_VMOLR_MPME       0x10000000 /* Multicast promiscuous mode */
+#define E1000_VMOLR_STRVLAN    0x40000000 /* Vlan stripping enable */
+#define E1000_VMOLR_STRCRC     0x80000000 /* CRC stripping enable */
+
+#define E1000_VLVF_ARRAY_SIZE     32
+#define E1000_VLVF_VLANID_MASK    0x00000FFF
+#define E1000_VLVF_POOLSEL_SHIFT  12
+#define E1000_VLVF_POOLSEL_MASK   (0xFF << E1000_VLVF_POOLSEL_SHIFT)
+#define E1000_VLVF_LVLAN          0x00100000
+#define E1000_VLVF_VLANID_ENABLE  0x80000000
+
+#define E1000_IOVCTL 0x05BBC
+#define E1000_IOVCTL_REUSE_VFQ 0x00000001
+
+#define ALL_QUEUES   0xFFFF
+
+void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
+void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_defines.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_defines.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_defines.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_defines.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 - 2008 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -42,33 +42,11 @@
 #define E1000_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
 #define E1000_WUFC_MC   0x00000008 /* Directed Multicast Wakeup Enable */
 #define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-
-/* Wake Up Packet Length */
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128
-
 
 /* Extended Device Control */
-#define E1000_CTRL_EXT_GPI1_EN   0x00000002 /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
 #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SDP4_DIR  0x00000100 /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
+/* Physical Func Reset Done Indication */
+#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_SGMII   0x00800000
@@ -103,13 +81,7 @@
 #define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
 #define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
 #define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
-#define E1000_RXD_STAT_DYNINT   0x800   /* Pkt caused INT via DYNINT */
-#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
-#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
-#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
-#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
-#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_STAT_TS       0x10000 /* Pkt was time stamped */
 
 #define E1000_RXDEXT_STATERR_CE    0x01000000
 #define E1000_RXDEXT_STATERR_SE    0x02000000
@@ -119,14 +91,6 @@
 #define E1000_RXDEXT_STATERR_IPE   0x40000000
 #define E1000_RXDEXT_STATERR_RXE   0x80000000
 
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
-    E1000_RXD_ERR_CE  |                \
-    E1000_RXD_ERR_SE  |                \
-    E1000_RXD_ERR_SEQ |                \
-    E1000_RXD_ERR_CXE |                \
-    E1000_RXD_ERR_RXE)
-
 /* Same mask, but for extended and packet split descriptors */
 #define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
     E1000_RXDEXT_STATERR_CE  |            \
@@ -145,16 +109,11 @@
 /* Management Control */
 #define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
 #define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
 /* Enable Neighbor Discovery Filtering */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
 #define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
 /* Enable MAC address filtering */
 #define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000
-/* Enable MNG packets to host memory */
-#define E1000_MANC_EN_MNG2HOST   0x00200000
-/* Enable IP address filtering */
-
 
 /* Receive Control */
 #define E1000_RCTL_EN             0x00000002    /* enable */
@@ -162,14 +121,11 @@
 #define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
 #define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
 #define E1000_RCTL_LPE            0x00000020    /* long packet enable */
-#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
 #define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
 #define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
 #define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
 #define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
 #define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
-#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
 #define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
 #define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
 #define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
@@ -226,11 +182,7 @@
 /* enable link status from external LINK_0 and LINK_1 pins */
 #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
 #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3  0x00200000  /* SWDPIN 3 value */
 #define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
 #define E1000_CTRL_RST      0x04000000  /* Global reset */
 #define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
 #define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
@@ -308,9 +260,7 @@
 #define AUTONEG_ADVERTISE_SPEED_DEFAULT   E1000_ALL_SPEED_DUPLEX
 
 /* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
 #define E1000_LEDCTL_LED0_MODE_SHIFT      0
-#define E1000_LEDCTL_LED0_IVRT            0x00000040
 #define E1000_LEDCTL_LED0_BLINK           0x00000080
 
 #define E1000_LEDCTL_MODE_LED_ON        0xE
@@ -357,12 +307,7 @@
 
 #define MAX_JUMBO_FRAME_SIZE    0x3F00
 
-/* Extended Configuration Control and Size */
-#define E1000_PHY_CTRL_GBE_DISABLE        0x00000040
-
 /* PBA constants */
-#define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
-#define E1000_PBA_24K 0x0018
 #define E1000_PBA_34K 0x0022
 #define E1000_PBA_64K 0x0040    /* 64KB */
 
@@ -378,41 +323,15 @@
 
 /* Interrupt Cause Read */
 #define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
 #define E1000_ICR_LSC           0x00000004 /* Link Status Change */
 #define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
 #define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO           0x00000040 /* rx overrun */
 #define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG         0x00000400 /* Rx /c/ ordered set */
-#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW       0x00008000
-#define E1000_ICR_SRPD          0x00010000
-#define E1000_ICR_ACK           0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG           0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK          0x00080000 /* Dock/Undock */
+#define E1000_ICR_VMMB          0x00000100 /* VM MB event */
 /* If this bit asserted, the driver should claim the interrupt */
 #define E1000_ICR_INT_ASSERTED  0x80000000
-/* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
-/* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
-/* host arb read buffer parity error */
-#define E1000_ICR_HOST_ARB_PAR  0x00400000
-#define E1000_ICR_PB_PAR        0x00800000 /* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
-/* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
-/* FW changed the status of DISSW bit in the FWSM */
-#define E1000_ICR_DSW           0x00000020
 /* LAN connected device generates an interrupt */
-#define E1000_ICR_PHYINT        0x00001000
-#define E1000_ICR_EPRST         0x00100000 /* ME handware reset occurs */
+#define E1000_ICR_DOUTSYNC      0x10000000 /* NIC DMA out of sync */
 
 /* Extended Interrupt Cause Read */
 #define E1000_EICR_RX_QUEUE0    0x00000001 /* Rx Queue 0 Interrupt */
@@ -423,7 +342,6 @@
 #define E1000_EICR_TX_QUEUE1    0x00000200 /* Tx Queue 1 Interrupt */
 #define E1000_EICR_TX_QUEUE2    0x00000400 /* Tx Queue 2 Interrupt */
 #define E1000_EICR_TX_QUEUE3    0x00000800 /* Tx Queue 3 Interrupt */
-#define E1000_EICR_TCP_TIMER    0x40000000 /* TCP Timer */
 #define E1000_EICR_OTHER        0x80000000 /* Interrupt Cause Active */
 /* TCP Timer */
 
@@ -441,17 +359,19 @@
     E1000_IMS_TXDW   |    \
     E1000_IMS_RXDMT0 |    \
     E1000_IMS_RXSEQ  |    \
-    E1000_IMS_LSC)
+    E1000_IMS_LSC    |    \
+    E1000_IMS_DOUTSYNC)
 
 /* Interrupt Mask Set */
 #define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
 #define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMS_VMMB      E1000_ICR_VMMB      /* Mail box activity */
 #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_DOUTSYNC  E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
 
 /* Extended Interrupt Mask Set */
-#define E1000_EIMS_TCP_TIMER    E1000_EICR_TCP_TIMER /* TCP Timer */
 #define E1000_EIMS_OTHER        E1000_EICR_OTHER   /* Interrupt Cause Active */
 
 /* Interrupt Cause Set */
@@ -481,6 +401,10 @@
  * manageability enabled, allowing us room for 15 multicast addresses.
  */
 #define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+#define E1000_RAL_MAC_ADDR_LEN 4
+#define E1000_RAH_MAC_ADDR_LEN 2
+#define E1000_RAH_POOL_MASK 0x03FC0000
+#define E1000_RAH_POOL_1 0x00040000
 
 /* Error Codes */
 #define E1000_ERR_NVM      1
@@ -490,10 +414,10 @@
 #define E1000_ERR_MAC_INIT 5
 #define E1000_ERR_RESET   9
 #define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
 #define E1000_BLK_PHY_RESET   12
 #define E1000_ERR_SWFW_SYNC 13
 #define E1000_NOT_IMPLEMENTED 14
+#define E1000_ERR_MBX      15
 
 /* Loop limit on how long we wait for auto-negotiation to complete */
 #define COPPER_LINK_UP_LIMIT              10
@@ -510,30 +434,9 @@
 /* Flow Control */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
-/* Transmit Configuration Word */
-#define E1000_TXCW_ANE        0x80000000        /* Auto-neg enable */
-
-/* Receive Configuration Word */
-
-/* PCI Express Control */
-#define E1000_GCR_RXD_NO_SNOOP          0x00000001
-#define E1000_GCR_RXDSCW_NO_SNOOP       0x00000002
-#define E1000_GCR_RXDSCR_NO_SNOOP       0x00000004
-#define E1000_GCR_TXD_NO_SNOOP          0x00000008
-#define E1000_GCR_TXDSCW_NO_SNOOP       0x00000010
-#define E1000_GCR_TXDSCR_NO_SNOOP       0x00000020
-
-#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP         | \
-			   E1000_GCR_RXDSCW_NO_SNOOP      | \
-			   E1000_GCR_RXDSCR_NO_SNOOP      | \
-			   E1000_GCR_TXD_NO_SNOOP         | \
-			   E1000_GCR_TXDSCW_NO_SNOOP      | \
-			   E1000_GCR_TXDSCR_NO_SNOOP)
-
 /* PHY Control Register */
 #define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
 #define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
-#define MII_CR_POWER_DOWN       0x0800  /* Power down */
 #define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
 #define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
 #define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
@@ -609,6 +512,7 @@
 #define NVM_ID_LED_SETTINGS        0x0004
 /* For SERDES output amplitude adjustment. */
 #define NVM_INIT_CONTROL2_REG      0x000F
+#define NVM_INIT_CONTROL3_PORT_B   0x0014
 #define NVM_INIT_CONTROL3_PORT_A   0x0024
 #define NVM_ALT_MAC_ADDR_PTR       0x0037
 #define NVM_CHECKSUM_REG           0x003F
@@ -663,10 +567,8 @@
 #define IGP_LED3_MODE           0x07000000
 
 /* PCI/PCI-X/PCI-EX Config space */
-#define PCI_HEADER_TYPE_REGISTER     0x0E
 #define PCIE_LINK_STATUS             0x12
 
-#define PCI_HEADER_TYPE_MULTIFUNC    0x80
 #define PCIE_LINK_WIDTH_MASK         0x3F0
 #define PCIE_LINK_WIDTH_SHIFT        4
 
@@ -763,4 +665,8 @@
 #define E1000_GEN_CTL_ADDRESS_SHIFT     8
 #define E1000_GEN_POLL_TIMEOUT          640
 
+#define E1000_VFTA_ENTRY_SHIFT               5
+#define E1000_VFTA_ENTRY_MASK                0x7F
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK      0x1F
+
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_hw.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -32,7 +32,6 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include "e1000_mac.h"
 #include "e1000_regs.h"
 #include "e1000_defines.h"
 
@@ -41,6 +40,8 @@ struct e1000_hw;
 #define E1000_DEV_ID_82576                    0x10C9
 #define E1000_DEV_ID_82576_FIBER              0x10E6
 #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_82575EB_COPPER           0x10A7
 #define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
 #define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
@@ -144,144 +145,6 @@ enum e1000_fc_type {
 	e1000_fc_default = 0xFF
 };
 
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
-	__le64 buffer_addr; /* Address of the descriptor's data buffer */
-	__le16 length;      /* Length of data DMAed into data buffer */
-	__le16 csum;        /* Packet checksum */
-	u8  status;      /* Descriptor status */
-	u8  errors;      /* Descriptor Errors */
-	__le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
-	struct {
-		__le64 buffer_addr;
-		__le64 reserved;
-	} read;
-	struct {
-		struct {
-			__le32 mrq;              /* Multiple Rx Queues */
-			union {
-				__le32 rss;            /* RSS Hash */
-				struct {
-					__le16 ip_id;  /* IP id */
-					__le16 csum;   /* Packet Checksum */
-				} csum_ip;
-			} hi_dword;
-		} lower;
-		struct {
-			__le32 status_error;     /* ext status/error */
-			__le16 length;
-			__le16 vlan;             /* VLAN tag */
-		} upper;
-	} wb;  /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
-	struct {
-		/* one buffer for protocol header(s), three data buffers */
-		__le64 buffer_addr[MAX_PS_BUFFERS];
-	} read;
-	struct {
-		struct {
-			__le32 mrq;              /* Multiple Rx Queues */
-			union {
-				__le32 rss;              /* RSS Hash */
-				struct {
-					__le16 ip_id;    /* IP id */
-					__le16 csum;     /* Packet Checksum */
-				} csum_ip;
-			} hi_dword;
-		} lower;
-		struct {
-			__le32 status_error;     /* ext status/error */
-			__le16 length0;          /* length of buffer 0 */
-			__le16 vlan;             /* VLAN tag */
-		} middle;
-		struct {
-			__le16 header_status;
-			__le16 length[3];        /* length of buffers 1-3 */
-		} upper;
-		__le64 reserved;
-	} wb; /* writeback */
-};
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
-	__le64 buffer_addr;      /* Address of the descriptor's data buffer */
-	union {
-		__le32 data;
-		struct {
-			__le16 length;    /* Data buffer length */
-			u8 cso;        /* Checksum offset */
-			u8 cmd;        /* Descriptor control */
-		} flags;
-	} lower;
-	union {
-		__le32 data;
-		struct {
-			u8 status;     /* Descriptor status */
-			u8 css;        /* Checksum start */
-			__le16 special;
-		} fields;
-	} upper;
-};
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
-	union {
-		__le32 ip_config;
-		struct {
-			u8 ipcss;      /* IP checksum start */
-			u8 ipcso;      /* IP checksum offset */
-			__le16 ipcse;     /* IP checksum end */
-		} ip_fields;
-	} lower_setup;
-	union {
-		__le32 tcp_config;
-		struct {
-			u8 tucss;      /* TCP checksum start */
-			u8 tucso;      /* TCP checksum offset */
-			__le16 tucse;     /* TCP checksum end */
-		} tcp_fields;
-	} upper_setup;
-	__le32 cmd_and_length;
-	union {
-		__le32 data;
-		struct {
-			u8 status;     /* Descriptor status */
-			u8 hdr_len;    /* Header length */
-			__le16 mss;       /* Maximum segment size */
-		} fields;
-	} tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
-	__le64 buffer_addr;   /* Address of the descriptor's buffer address */
-	union {
-		__le32 data;
-		struct {
-			__le16 length;    /* Data buffer length */
-			u8 typ_len_ext;
-			u8 cmd;
-		} flags;
-	} lower;
-	union {
-		__le32 data;
-		struct {
-			u8 status;     /* Descriptor status */
-			u8 popts;      /* Packet Options */
-			__le16 special;
-		} fields;
-	} upper;
-};
-
 /* Statistics counters collected by the MAC */
 struct e1000_hw_stats {
 	u64 crcerrs;
@@ -359,6 +222,7 @@ struct e1000_hw_stats {
 	u64 lenerrs;
 	u64 scvpc;
 	u64 hrmpc;
+	u64 doosync;
 };
 
 struct e1000_phy_stats {
@@ -409,6 +273,7 @@ struct e1000_host_mng_command_info {
 #include "e1000_mac.h"
 #include "e1000_phy.h"
 #include "e1000_nvm.h"
+#include "e1000_mbx.h"
 
 struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
@@ -422,25 +287,25 @@ struct e1000_mac_operations {
 };
 
 struct e1000_phy_operations {
-	s32  (*acquire_phy)(struct e1000_hw *);
+	s32  (*acquire)(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);
 	s32  (*get_cable_length)(struct e1000_hw *);
 	s32  (*get_phy_info)(struct e1000_hw *);
-	s32  (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
-	void (*release_phy)(struct e1000_hw *);
-	s32  (*reset_phy)(struct e1000_hw *);
+	s32  (*read_reg)(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_reg)(struct e1000_hw *, u32, u16);
 };
 
 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  (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+	s32  (*acquire)(struct e1000_hw *);
+	s32  (*read)(struct e1000_hw *, u16, u16, u16 *);
+	void (*release)(struct e1000_hw *);
+	s32  (*write)(struct e1000_hw *, u16, u16, u16 *);
 };
 
 struct e1000_info {
@@ -483,7 +348,6 @@ struct e1000_mac_info {
 	bool asf_firmware_present;
 	bool autoneg;
 	bool autoneg_failed;
-	bool disable_av;
 	bool disable_hw_init_bits;
 	bool get_link_status;
 	bool ifs_params_forced;
@@ -565,9 +429,40 @@ struct e1000_fc_info {
 	enum e1000_fc_type original_type;
 };
 
+struct e1000_mbx_operations {
+	s32 (*init_params)(struct e1000_hw *hw);
+	s32 (*read)(struct e1000_hw *, u32 *, u16,  u16);
+	s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
+	s32 (*read_posted)(struct e1000_hw *, u32 *, u16,  u16);
+	s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
+	s32 (*check_for_msg)(struct e1000_hw *, u16);
+	s32 (*check_for_ack)(struct e1000_hw *, u16);
+	s32 (*check_for_rst)(struct e1000_hw *, u16);
+};
+
+struct e1000_mbx_stats {
+	u32 msgs_tx;
+	u32 msgs_rx;
+
+	u32 acks;
+	u32 reqs;
+	u32 rsts;
+};
+
+struct e1000_mbx_info {
+	struct e1000_mbx_operations ops;
+	struct e1000_mbx_stats stats;
+	u32 timeout;
+	u32 usec_delay;
+	u16 size;
+};
+
+struct e1000_dev_spec_82575 {
+	bool sgmii_active;
+};
+
 struct e1000_hw {
 	void *back;
-	void *dev_spec;
 
 	u8 __iomem *hw_addr;
 	u8 __iomem *flash_address;
@@ -578,9 +473,12 @@ struct e1000_hw {
 	struct e1000_phy_info  phy;
 	struct e1000_nvm_info  nvm;
 	struct e1000_bus_info  bus;
+	struct e1000_mbx_info mbx;
 	struct e1000_host_mng_dhcp_cookie mng_cookie;
 
-	u32 dev_spec_size;
+	union {
+		struct e1000_dev_spec_82575	_82575;
+	} dev_spec;
 
 	u16 device_id;
 	u16 subsystem_vendor_id;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mac.c linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -37,19 +37,6 @@
 static s32 igb_set_default_fc(struct e1000_hw *hw);
 static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
 
-/**
- *  igb_remove_device - Free device specific structure
- *  @hw: pointer to the HW structure
- *
- *  If a device specific structure was allocated, this function will
- *  free it.
- **/
-void igb_remove_device(struct e1000_hw *hw)
-{
-	/* Freeing the dev_spec member of e1000_hw structure */
-	kfree(hw->dev_spec);
-}
-
 static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
 {
 	struct igb_adapter *adapter = hw->back;
@@ -124,13 +111,44 @@ void igb_clear_vfta(struct e1000_hw *hw)
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 {
 	array_wr32(E1000_VFTA, offset, value);
 	wrfl();
 }
 
 /**
+ *  igb_vfta_set - enable or disable vlan in VLAN filter table
+ *  @hw: pointer to the HW structure
+ *  @vid: VLAN id to add or remove
+ *  @add: if true add filter, if false remove
+ *
+ *  Sets or clears a bit in the VLAN filter table array based on VLAN id
+ *  and if we are adding or removing the filter
+ **/
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
+{
+	u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
+	u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
+	u32 vfta = array_rd32(E1000_VFTA, index);
+	s32 ret_val = 0;
+
+	/* bit was set/cleared before we started */
+	if ((!!(vfta & mask)) == add) {
+		ret_val = -E1000_ERR_CONFIG;
+	} else {
+		if (add)
+			vfta |= mask;
+		else
+			vfta &= ~mask;
+	}
+
+	igb_write_vfta(hw, index, vfta);
+
+	return ret_val;
+}
+
+/**
  *  igb_check_alt_mac_addr - Check for alternate MAC addr
  *  @hw: pointer to the HW structure
  *
@@ -148,7 +166,7 @@ s32 igb_check_alt_mac_addr(struct e1000_
 	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
 	u8 alt_mac_addr[ETH_ALEN];
 
-	ret_val = hw->nvm.ops.read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+	ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
 				 &nvm_alt_mac_addr_offset);
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
@@ -165,7 +183,7 @@ s32 igb_check_alt_mac_addr(struct e1000_
 
 	for (i = 0; i < ETH_ALEN; i += 2) {
 		offset = nvm_alt_mac_addr_offset + (i >> 1);
-		ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
+		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
 		if (ret_val) {
 			hw_dbg("NVM Read Error\n");
 			goto out;
@@ -213,7 +231,8 @@ void igb_rar_set(struct e1000_hw *hw, u8
 
 	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
 
-	if (!hw->mac.disable_av)
+	/* If MAC address zero, no need to set the AV bit */
+	if (rar_low || rar_high)
 		rar_high |= E1000_RAH_AV;
 
 	wr32(E1000_RAL(index), rar_low);
@@ -588,8 +607,7 @@ static s32 igb_set_default_fc(struct e10
 	 * control setting, then the variable hw->fc will
 	 * be initialized based on a value in the EEPROM.
 	 */
-	ret_val = hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL2_REG, 1,
-				       &nvm_data);
+	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
 
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
@@ -720,11 +738,11 @@ s32 igb_config_fc_after_link_up(struct e
 		 * has completed.  We read this twice because this reg has
 		 * some "sticky" (latched) bits.
 		 */
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
 						   &mii_status_reg);
 		if (ret_val)
 			goto out;
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
 						   &mii_status_reg);
 		if (ret_val)
 			goto out;
@@ -742,11 +760,11 @@ s32 igb_config_fc_after_link_up(struct e
 		 * Page Ability Register (Address 5) to determine how
 		 * flow control was negotiated.
 		 */
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
+		ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
 					    &mii_nway_adv_reg);
 		if (ret_val)
 			goto out;
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_LP_ABILITY,
+		ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
 					    &mii_nway_lp_ability_reg);
 		if (ret_val)
 			goto out;
@@ -1041,7 +1059,7 @@ static s32 igb_valid_led_default(struct
 {
 	s32 ret_val;
 
-	ret_val = hw->nvm.ops.read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
 		goto out;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mac.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mac.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mac.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mac.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -58,15 +58,14 @@ s32  igb_write_8bit_ctrl_reg(struct e100
 
 void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
 void igb_clear_vfta(struct e1000_hw *hw);
+s32  igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
 void igb_config_collision_dist(struct e1000_hw *hw);
 void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
 void igb_put_hw_semaphore(struct e1000_hw *hw);
 void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 s32  igb_check_alt_mac_addr(struct e1000_hw *hw);
-void igb_remove_device(struct e1000_hw *hw);
 void igb_reset_adaptive(struct e1000_hw *hw);
 void igb_update_adaptive(struct e1000_hw *hw);
-void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
 
 bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
 
@@ -83,13 +82,8 @@ enum e1000_mng_mode {
 #define E1000_FWSM_MODE_MASK  0xE
 #define E1000_FWSM_MODE_SHIFT 1
 
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT       10
 #define E1000_MNG_DHCP_COOKIE_STATUS_VLAN    0x2
 
-#define E1000_HICR_EN              0x01  /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define E1000_HICR_C               0x02
-
 extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
 extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mbx.c linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mbx.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mbx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mbx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,434 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007-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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "e1000_mbx.h"
+
+/**
+ *  igb_read_mbx - Reads a message from the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @mbx_id: id of mailbox to read
+ *
+ *  returns SUCCESS if it successfuly read message from buffer
+ **/
+s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	/* limit read to size of mailbox */
+	if (size > mbx->size)
+		size = mbx->size;
+
+	if (mbx->ops.read)
+		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  igb_write_mbx - Write a message to the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @mbx_id: id of mailbox to write
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer
+ **/
+s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = 0;
+
+	if (size > mbx->size)
+		ret_val = -E1000_ERR_MBX;
+
+	else if (mbx->ops.write)
+		ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_msg - checks to see if someone sent us mail
+ *  @hw: pointer to the HW structure
+ *  @mbx_id: id of mailbox to check
+ *
+ *  returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (mbx->ops.check_for_msg)
+		ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_ack - checks to see if someone sent us ACK
+ *  @hw: pointer to the HW structure
+ *  @mbx_id: id of mailbox to check
+ *
+ *  returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (mbx->ops.check_for_ack)
+		ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_rst - checks to see if other side has reset
+ *  @hw: pointer to the HW structure
+ *  @mbx_id: id of mailbox to check
+ *
+ *  returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (mbx->ops.check_for_rst)
+		ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+
+	return ret_val;
+}
+
+/**
+ *  igb_poll_for_msg - Wait for message notification
+ *  @hw: pointer to the HW structure
+ *  @mbx_id: id of mailbox to write
+ *
+ *  returns SUCCESS if it successfully received a message notification
+ **/
+static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_msg)
+		goto out;
+
+	while (mbx->ops.check_for_msg(hw, mbx_id)) {
+		if (!countdown)
+			break;
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+out:
+	return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ *  igb_poll_for_ack - Wait for message acknowledgement
+ *  @hw: pointer to the HW structure
+ *  @mbx_id: id of mailbox to write
+ *
+ *  returns SUCCESS if it successfully received a message acknowledgement
+ **/
+static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_ack)
+		goto out;
+
+	while (mbx->ops.check_for_ack(hw, mbx_id)) {
+		if (!countdown)
+			break;
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+out:
+	return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ *  igb_read_posted_mbx - Wait for message notification and receive message
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @mbx_id: id of mailbox to write
+ *
+ *  returns SUCCESS if it successfully received a message notification and
+ *  copied it into the receive buffer.
+ **/
+static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!mbx->ops.read)
+		goto out;
+
+	ret_val = igb_poll_for_msg(hw, mbx_id);
+
+	if (!ret_val)
+		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+out:
+	return ret_val;
+}
+
+/**
+ *  igb_write_posted_mbx - Write a message to the mailbox, wait for ack
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @mbx_id: id of mailbox to write
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer and
+ *  received an ack to that message within delay * timeout period
+ **/
+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;
+
+	if (!mbx->ops.write)
+		goto out;
+
+	/* send msg*/
+	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+	/* if msg sent wait until we receive an ack */
+	if (!ret_val)
+		ret_val = igb_poll_for_ack(hw, mbx_id);
+out:
+	return ret_val;
+}
+
+static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
+{
+	u32 mbvficr = rd32(E1000_MBVFICR);
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (mbvficr & mask) {
+		ret_val = 0;
+		wr32(E1000_MBVFICR, mask);
+	}
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_msg_pf - checks to see if the VF has sent mail
+ *  @hw: pointer to the HW structure
+ *  @vf_number: the VF index
+ *
+ *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
+		ret_val = 0;
+		hw->mbx.stats.reqs++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_ack_pf - checks to see if the VF has ACKed
+ *  @hw: pointer to the HW structure
+ *  @vf_number: the VF index
+ *
+ *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
+		ret_val = 0;
+		hw->mbx.stats.acks++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  igb_check_for_rst_pf - checks to see if the VF has reset
+ *  @hw: pointer to the HW structure
+ *  @vf_number: the VF index
+ *
+ *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
+{
+	u32 vflre = rd32(E1000_VFLRE);
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (vflre & (1 << vf_number)) {
+		ret_val = 0;
+		wr32(E1000_VFLRE, (1 << vf_number));
+		hw->mbx.stats.rsts++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  igb_write_mbx_pf - Places a message in the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @vf_number: the VF index
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+                              u16 vf_number)
+{
+	u32 p2v_mailbox;
+	s32 ret_val = 0;
+	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;
+		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);
+	igb_check_for_msg_pf(hw, vf_number);
+
+	/* copy the caller specified message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
+
+	/* Interrupt VF to tell it a message has been sent and release buffer*/
+	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
+
+	/* update stats */
+	hw->mbx.stats.msgs_tx++;
+
+out_no_write:
+	return ret_val;
+
+}
+
+/**
+ *  igb_read_mbx_pf - Read a message from the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *  @vf_number: the VF index
+ *
+ *  This function copies a message from the mailbox buffer to the caller's
+ *  memory buffer.  The presumption is that the caller knows that there was
+ *  a message due to a VF request so no polling for message is needed.
+ **/
+static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+                             u16 vf_number)
+{
+	u32 p2v_mailbox;
+	s32 ret_val = 0;
+	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;
+		goto out_no_read;
+	}
+
+	/* copy the message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
+
+	/* Acknowledge the message and release buffer */
+	wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+
+	/* update stats */
+	hw->mbx.stats.msgs_rx++;
+
+	ret_val = 0;
+
+out_no_read:
+	return ret_val;
+}
+
+/**
+ *  e1000_init_mbx_params_pf - set initial values for pf mailbox
+ *  @hw: pointer to the HW structure
+ *
+ *  Initializes the hw->mbx struct to correct values for pf mailbox
+ */
+s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+
+	if (hw->mac.type == e1000_82576) {
+		mbx->timeout = 0;
+		mbx->usec_delay = 0;
+
+		mbx->size = E1000_VFMAILBOX_SIZE;
+
+		mbx->ops.read = igb_read_mbx_pf;
+		mbx->ops.write = igb_write_mbx_pf;
+		mbx->ops.read_posted = igb_read_posted_mbx;
+		mbx->ops.write_posted = igb_write_posted_mbx;
+		mbx->ops.check_for_msg = igb_check_for_msg_pf;
+		mbx->ops.check_for_ack = igb_check_for_ack_pf;
+		mbx->ops.check_for_rst = igb_check_for_rst_pf;
+
+		mbx->stats.msgs_tx = 0;
+		mbx->stats.msgs_rx = 0;
+		mbx->stats.reqs = 0;
+		mbx->stats.acks = 0;
+		mbx->stats.rsts = 0;
+	}
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mbx.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mbx.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_mbx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_mbx.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007-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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "e1000_hw.h"
+
+#define E1000_P2VMAILBOX_STS   0x00000001 /* Initiate message send to VF */
+#define E1000_P2VMAILBOX_ACK   0x00000002 /* Ack message recv'd from VF */
+#define E1000_P2VMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_RVFU  0x00000010 /* Reset VFU - used when VF stuck */
+
+#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
+#define E1000_MBVFICR_VFREQ_VF1  0x00000001 /* bit for VF 1 message */
+#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
+#define E1000_MBVFICR_VFACK_VF1  0x00010000 /* bit for VF 1 ack */
+
+#define E1000_VFMAILBOX_SIZE   16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF.  The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
+                                               * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
+                                               * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
+                                                 clear to send requests */
+#define E1000_VT_MSGINFO_SHIFT    16
+/* bits 23:16 are used for exra info for certain messages */
+#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_PF_CONTROL_MSG      0x0100 /* PF control message */
+
+s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_check_for_msg(struct e1000_hw *, u16);
+s32 igb_check_for_ack(struct e1000_hw *, u16);
+s32 igb_check_for_rst(struct e1000_hw *, u16);
+s32 igb_init_mbx_params_pf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_nvm.c linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_nvm.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_nvm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_nvm.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -419,7 +419,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *h
 		goto out;
 	}
 
-	ret_val = hw->nvm.ops.acquire_nvm(hw);
+	ret_val = hw->nvm.ops.acquire(hw);
 	if (ret_val)
 		goto out;
 
@@ -468,7 +468,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *h
 
 	msleep(10);
 release:
-	hw->nvm.ops.release_nvm(hw);
+	hw->nvm.ops.release(hw);
 
 out:
 	return ret_val;
@@ -487,14 +487,14 @@ s32 igb_read_part_num(struct e1000_hw *h
 	s32  ret_val;
 	u16 nvm_data;
 
-	ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
 		goto out;
 	}
 	*part_num = (u32)(nvm_data << 16);
 
-	ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
 		goto out;
@@ -515,29 +515,23 @@ out:
  **/
 s32 igb_read_mac_addr(struct e1000_hw *hw)
 {
-	s32  ret_val = 0;
-	u16 offset, nvm_data, i;
+	u32 rar_high;
+	u32 rar_low;
+	u16 i;
 
-	for (i = 0; i < ETH_ALEN; i += 2) {
-		offset = i >> 1;
-		ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
-		if (ret_val) {
-			hw_dbg("NVM Read Error\n");
-			goto out;
-		}
-		hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
-		hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
-	}
+	rar_high = rd32(E1000_RAH(0));
+	rar_low = rd32(E1000_RAL(0));
 
-	/* Flip last bit of mac address if we're on second port */
-	if (hw->bus.func == E1000_FUNC_1)
-		hw->mac.perm_addr[5] ^= 1;
+	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
+
+	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
 
 	for (i = 0; i < ETH_ALEN; i++)
 		hw->mac.addr[i] = hw->mac.perm_addr[i];
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -554,7 +548,7 @@ s32 igb_validate_nvm_checksum(struct e10
 	u16 i, nvm_data;
 
 	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
-		ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
 		if (ret_val) {
 			hw_dbg("NVM Read Error\n");
 			goto out;
@@ -587,7 +581,7 @@ s32 igb_update_nvm_checksum(struct e1000
 	u16 i, nvm_data;
 
 	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
-		ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
 		if (ret_val) {
 			hw_dbg("NVM Read Error while updating checksum.\n");
 			goto out;
@@ -595,7 +589,7 @@ s32 igb_update_nvm_checksum(struct e1000
 		checksum += nvm_data;
 	}
 	checksum = (u16) NVM_SUM - checksum;
-	ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
+	ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
 	if (ret_val)
 		hw_dbg("NVM Write Error while updating checksum.\n");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_phy.c linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,10 +31,6 @@
 #include "e1000_mac.h"
 #include "e1000_phy.h"
 
-static s32  igb_get_phy_cfg_done(struct e1000_hw *hw);
-static void igb_release_phy(struct e1000_hw *hw);
-static s32  igb_acquire_phy(struct e1000_hw *hw);
-static s32  igb_phy_reset_dsp(struct e1000_hw *hw);
 static s32  igb_phy_setup_autoneg(struct e1000_hw *hw);
 static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
 					       u16 *phy_ctrl);
@@ -43,9 +39,6 @@ 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,
@@ -91,13 +84,13 @@ s32 igb_get_phy_id(struct e1000_hw *hw)
 	s32 ret_val = 0;
 	u16 phy_id;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID1, &phy_id);
+	ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
 	if (ret_val)
 		goto out;
 
 	phy->id = (u32)(phy_id << 16);
 	udelay(20);
-	ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID2, &phy_id);
+	ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
 	if (ret_val)
 		goto out;
 
@@ -118,11 +111,11 @@ static s32 igb_phy_reset_dsp(struct e100
 {
 	s32 ret_val;
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
+	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
 	if (ret_val)
 		goto out;
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
+	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
 
 out:
 	return ret_val;
@@ -257,9 +250,12 @@ out:
  **/
 s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
 {
-	s32 ret_val;
+	s32 ret_val = 0;
 
-	ret_val = igb_acquire_phy(hw);
+	if (!(hw->phy.ops.acquire))
+		goto out;
+
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		goto out;
 
@@ -268,16 +264,15 @@ s32 igb_read_phy_reg_igp(struct e1000_hw
 						   IGP01E1000_PHY_PAGE_SELECT,
 						   (u16)offset);
 		if (ret_val) {
-			igb_release_phy(hw);
+			hw->phy.ops.release(hw);
 			goto out;
 		}
 	}
 
-	ret_val = igb_read_phy_reg_mdic(hw,
-					  MAX_PHY_REG_ADDRESS & offset,
-					  data);
+	ret_val = igb_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					data);
 
-	igb_release_phy(hw);
+	hw->phy.ops.release(hw);
 
 out:
 	return ret_val;
@@ -294,9 +289,12 @@ out:
  **/
 s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
 {
-	s32 ret_val;
+	s32 ret_val = 0;
 
-	ret_val = igb_acquire_phy(hw);
+	if (!(hw->phy.ops.acquire))
+		goto out;
+
+	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
 		goto out;
 
@@ -305,16 +303,15 @@ s32 igb_write_phy_reg_igp(struct e1000_h
 						   IGP01E1000_PHY_PAGE_SELECT,
 						   (u16)offset);
 		if (ret_val) {
-			igb_release_phy(hw);
+			hw->phy.ops.release(hw);
 			goto out;
 		}
 	}
 
-	ret_val = igb_write_phy_reg_mdic(hw,
-					   MAX_PHY_REG_ADDRESS & offset,
+	ret_val = igb_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					   data);
 
-	igb_release_phy(hw);
+	hw->phy.ops.release(hw);
 
 out:
 	return ret_val;
@@ -339,8 +336,7 @@ s32 igb_copper_link_setup_m88(struct e10
 	}
 
 	/* Enable CRS on TX. This must be set for half-duplex operation. */
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
@@ -383,8 +379,7 @@ s32 igb_copper_link_setup_m88(struct e10
 	if (phy->disable_polarity_correction == 1)
 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					    phy_data);
+	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
 		goto out;
 
@@ -393,8 +388,7 @@ s32 igb_copper_link_setup_m88(struct e10
 		 * Force TX_CLK in the Extended PHY Specific Control Register
 		 * to 25MHz clock.
 		 */
-		ret_val = hw->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)
 			goto out;
@@ -413,8 +407,7 @@ s32 igb_copper_link_setup_m88(struct e10
 			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
 				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
 		}
-		ret_val = hw->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)
 			goto out;
@@ -449,14 +442,17 @@ s32 igb_copper_link_setup_igp(struct e10
 		goto out;
 	}
 
-	ret_val = hw->phy.ops.reset_phy(hw);
+	ret_val = phy->ops.reset(hw);
 	if (ret_val) {
 		hw_dbg("Error resetting the PHY.\n");
 		goto out;
 	}
 
-	/* Wait 15ms for MAC to configure PHY from NVM settings. */
-	msleep(15);
+	/*
+	 * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
+	 * timeout issues when LFS is enabled.
+	 */
+	msleep(100);
 
 	/*
 	 * The NVM settings will configure LPLU in D3 for
@@ -464,8 +460,8 @@ s32 igb_copper_link_setup_igp(struct e10
 	 */
 	if (phy->type == e1000_phy_igp) {
 		/* disable lplu d3 during driver init */
-		if (hw->phy.ops.set_d3_lplu_state)
-			ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
+		if (phy->ops.set_d3_lplu_state)
+			ret_val = phy->ops.set_d3_lplu_state(hw, false);
 		if (ret_val) {
 			hw_dbg("Error Disabling LPLU D3\n");
 			goto out;
@@ -473,13 +469,13 @@ s32 igb_copper_link_setup_igp(struct e10
 	}
 
 	/* disable lplu d0 during driver init */
-	ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
+	ret_val = phy->ops.set_d0_lplu_state(hw, false);
 	if (ret_val) {
 		hw_dbg("Error Disabling LPLU D0\n");
 		goto out;
 	}
 	/* Configure mdi-mdix settings */
-	ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
+	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
 	if (ret_val)
 		goto out;
 
@@ -497,7 +493,7 @@ s32 igb_copper_link_setup_igp(struct e10
 		data |= IGP01E1000_PSCR_AUTO_MDIX;
 		break;
 	}
-	ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
+	ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
 	if (ret_val)
 		goto out;
 
@@ -510,33 +506,31 @@ s32 igb_copper_link_setup_igp(struct e10
 		 */
 		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
 			/* Disable SmartSpeed */
-			ret_val = hw->phy.ops.read_phy_reg(hw,
-						     IGP01E1000_PHY_PORT_CONFIG,
-						     &data);
+			ret_val = phy->ops.read_reg(hw,
+						    IGP01E1000_PHY_PORT_CONFIG,
+						    &data);
 			if (ret_val)
 				goto out;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = hw->phy.ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 						     IGP01E1000_PHY_PORT_CONFIG,
 						     data);
 			if (ret_val)
 				goto out;
 
 			/* Set auto Master/Slave resolution process */
-			ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL,
-							   &data);
+			ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
 			if (ret_val)
 				goto out;
 
 			data &= ~CR_1000T_MS_ENABLE;
-			ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL,
-							    data);
+			ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
 			if (ret_val)
 				goto out;
 		}
 
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL, &data);
+		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
 		if (ret_val)
 			goto out;
 
@@ -560,7 +554,7 @@ s32 igb_copper_link_setup_igp(struct e10
 		default:
 			break;
 		}
-		ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL, data);
+		ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
 		if (ret_val)
 			goto out;
 	}
@@ -609,12 +603,12 @@ s32 igb_copper_link_autoneg(struct e1000
 	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
 	 * the Auto Neg Restart bit in the PHY control register.
 	 */
-	ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
 	if (ret_val)
 		goto out;
 
 	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-	ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
 	if (ret_val)
 		goto out;
 
@@ -656,15 +650,13 @@ static s32 igb_phy_setup_autoneg(struct
 	phy->autoneg_advertised &= phy->autoneg_mask;
 
 	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
-	ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
-					   &mii_autoneg_adv_reg);
+	ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
 	if (ret_val)
 		goto out;
 
 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
 		/* Read the MII 1000Base-T Control Register (Address 9). */
-		ret_val = hw->phy.ops.read_phy_reg(hw,
-					    PHY_1000T_CTRL,
+		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
 					    &mii_1000t_ctrl_reg);
 		if (ret_val)
 			goto out;
@@ -785,17 +777,16 @@ static s32 igb_phy_setup_autoneg(struct
 		goto out;
 	}
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, PHY_AUTONEG_ADV,
-					    mii_autoneg_adv_reg);
+	ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
 	if (ret_val)
 		goto out;
 
 	hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 
 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
-		ret_val = hw->phy.ops.write_phy_reg(hw,
-					      PHY_1000T_CTRL,
-					      mii_1000t_ctrl_reg);
+		ret_val = phy->ops.write_reg(hw,
+					     PHY_1000T_CTRL,
+					     mii_1000t_ctrl_reg);
 		if (ret_val)
 			goto out;
 	}
@@ -819,13 +810,13 @@ s32 igb_phy_force_speed_duplex_igp(struc
 	u16 phy_data;
 	bool link;
 
-	ret_val = hw->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;
 
 	igb_phy_force_speed_duplex_setup(hw, &phy_data);
 
-	ret_val = hw->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;
 
@@ -833,16 +824,14 @@ s32 igb_phy_force_speed_duplex_igp(struc
 	 * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
-	ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
 	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
 
-	ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-					    phy_data);
+	ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
 	if (ret_val)
 		goto out;
 
@@ -897,20 +886,18 @@ s32 igb_phy_force_speed_duplex_m88(struc
 	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					    phy_data);
+	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
 		goto out;
 
 	hw_dbg("M88E1000 PSCR: %X\n", phy_data);
 
-	ret_val = hw->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;
 
@@ -919,7 +906,7 @@ s32 igb_phy_force_speed_duplex_m88(struc
 	/* Reset the phy to commit changes. */
 	phy_data |= MII_CR_RESET;
 
-	ret_val = hw->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;
 
@@ -940,7 +927,7 @@ s32 igb_phy_force_speed_duplex_m88(struc
 			 * We didn't get link.
 			 * Reset the DSP and cross our fingers.
 			 */
-			ret_val = hw->phy.ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 						      M88E1000_PHY_PAGE_SELECT,
 						      0x001d);
 			if (ret_val)
@@ -957,8 +944,7 @@ s32 igb_phy_force_speed_duplex_m88(struc
 			goto out;
 	}
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
@@ -968,8 +954,7 @@ s32 igb_phy_force_speed_duplex_m88(struc
 	 * the reset value of 2.5MHz.
 	 */
 	phy_data |= M88E1000_EPSCR_TX_CLK_25;
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-					    phy_data);
+	ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
 		goto out;
 
@@ -977,14 +962,12 @@ s32 igb_phy_force_speed_duplex_m88(struc
 	 * In addition, we must re-enable CRS on Tx for both half and full
 	 * duplex.
 	 */
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-	ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					    phy_data);
+	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
 
 out:
 	return ret_val;
@@ -1071,15 +1054,13 @@ s32 igb_set_d3_lplu_state(struct e1000_h
 	s32 ret_val;
 	u16 data;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
-					   &data);
+	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
 	if (ret_val)
 		goto out;
 
 	if (!active) {
 		data &= ~IGP02E1000_PM_D3_LPLU;
-		ret_val = hw->phy.ops.write_phy_reg(hw,
-					     IGP02E1000_PHY_POWER_MGMT,
+		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
 					     data);
 		if (ret_val)
 			goto out;
@@ -1090,27 +1071,27 @@ s32 igb_set_d3_lplu_state(struct e1000_h
 		 * SmartSpeed, so performance is maintained.
 		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
-			ret_val = hw->phy.ops.read_phy_reg(hw,
+			ret_val = phy->ops.read_reg(hw,
 						    IGP01E1000_PHY_PORT_CONFIG,
 						    &data);
 			if (ret_val)
 				goto out;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = hw->phy.ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 						     IGP01E1000_PHY_PORT_CONFIG,
 						     data);
 			if (ret_val)
 				goto out;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
-			ret_val = hw->phy.ops.read_phy_reg(hw,
+			ret_val = phy->ops.read_reg(hw,
 						     IGP01E1000_PHY_PORT_CONFIG,
 						     &data);
 			if (ret_val)
 				goto out;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = hw->phy.ops.write_phy_reg(hw,
+			ret_val = phy->ops.write_reg(hw,
 						     IGP01E1000_PHY_PORT_CONFIG,
 						     data);
 			if (ret_val)
@@ -1120,22 +1101,19 @@ s32 igb_set_d3_lplu_state(struct e1000_h
 		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
 		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
 		data |= IGP02E1000_PM_D3_LPLU;
-		ret_val = hw->phy.ops.write_phy_reg(hw,
-					      IGP02E1000_PHY_POWER_MGMT,
+		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
 					      data);
 		if (ret_val)
 			goto out;
 
 		/* When LPLU is enabled, we should disable SmartSpeed */
-		ret_val = hw->phy.ops.read_phy_reg(hw,
-					     IGP01E1000_PHY_PORT_CONFIG,
+		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
 					     &data);
 		if (ret_val)
 			goto out;
 
 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-		ret_val = hw->phy.ops.write_phy_reg(hw,
-					      IGP01E1000_PHY_PORT_CONFIG,
+		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
 					      data);
 	}
 
@@ -1176,7 +1154,7 @@ s32 igb_check_downshift(struct e1000_hw
 		goto out;
 	}
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, offset, &phy_data);
+	ret_val = phy->ops.read_reg(hw, offset, &phy_data);
 
 	if (!ret_val)
 		phy->speed_downgraded = (phy_data & mask) ? true : false;
@@ -1199,7 +1177,7 @@ static s32 igb_check_polarity_m88(struct
 	s32 ret_val;
 	u16 data;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
 
 	if (!ret_val)
 		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
@@ -1228,8 +1206,7 @@ static s32 igb_check_polarity_igp(struct
 	 * Polarity is determined based on the speed of
 	 * our connection.
 	 */
-	ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-					   &data);
+	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
 	if (ret_val)
 		goto out;
 
@@ -1246,7 +1223,7 @@ static s32 igb_check_polarity_igp(struct
 		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
 	}
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, offset, &data);
+	ret_val = phy->ops.read_reg(hw, offset, &data);
 
 	if (!ret_val)
 		phy->cable_polarity = (data & mask)
@@ -1271,10 +1248,10 @@ static s32 igb_wait_autoneg(struct e1000
 
 	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
 	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
 		if (phy_status & MII_SR_AUTONEG_COMPLETE)
@@ -1310,10 +1287,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw
 		 * twice due to the link bit being sticky.  No harm doing
 		 * it across the board.
 		 */
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
 		if (ret_val)
 			break;
 		if (phy_status & MII_SR_LINK_STATUS)
@@ -1350,8 +1327,7 @@ s32 igb_get_cable_length_m88(struct e100
 	s32 ret_val;
 	u16 phy_data, index;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
 		goto out;
 
@@ -1372,8 +1348,8 @@ out:
  *
  *  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 reperesent the
- *  cobination of course and fine gain value, the value can be put
+ *  cable.  By reading the AGC registers, which represent the
+ *  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.
  **/
@@ -1392,14 +1368,13 @@ s32 igb_get_cable_length_igp_2(struct e1
 
 	/* Read the AGC registers for all channels */
 	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
-		ret_val = hw->phy.ops.read_phy_reg(hw, agc_reg_array[i],
-						   &phy_data);
+		ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
 		if (ret_val)
 			goto out;
 
 		/*
 		 * 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.
 		 */
@@ -1456,7 +1431,7 @@ s32 igb_get_phy_info_m88(struct e1000_hw
 	u16 phy_data;
 	bool link;
 
-	if (hw->phy.media_type != e1000_media_type_copper) {
+	if (phy->media_type != e1000_media_type_copper) {
 		hw_dbg("Phy info is only valid for copper media\n");
 		ret_val = -E1000_ERR_CONFIG;
 		goto out;
@@ -1472,33 +1447,29 @@ s32 igb_get_phy_info_m88(struct e1000_hw
 		goto out;
 	}
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
-				   ? true
-				   : false;
+				   ? true : false;
 
 	ret_val = igb_check_polarity_m88(hw);
 	if (ret_val)
 		goto out;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-					   &phy_data);
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
 		goto out;
 
 	phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
 
 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
-		ret_val = hw->phy.ops.get_cable_length(hw);
+		ret_val = phy->ops.get_cable_length(hw);
 		if (ret_val)
 			goto out;
 
-		ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
-						   &phy_data);
+		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
 		if (ret_val)
 			goto out;
 
@@ -1552,8 +1523,7 @@ s32 igb_get_phy_info_igp(struct e1000_hw
 	if (ret_val)
 		goto out;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-					   &data);
+	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
 	if (ret_val)
 		goto out;
 
@@ -1561,12 +1531,11 @@ s32 igb_get_phy_info_igp(struct e1000_hw
 
 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
-		ret_val = hw->phy.ops.get_cable_length(hw);
+		ret_val = phy->ops.get_cable_length(hw);
 		if (ret_val)
 			goto out;
 
-		ret_val = hw->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;
 
@@ -1599,12 +1568,12 @@ s32 igb_phy_sw_reset(struct e1000_hw *hw
 	s32 ret_val;
 	u16 phy_ctrl;
 
-	ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
 	if (ret_val)
 		goto out;
 
 	phy_ctrl |= MII_CR_RESET;
-	ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+	ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
 	if (ret_val)
 		goto out;
 
@@ -1635,7 +1604,7 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw
 		goto out;
 	}
 
-	ret_val = igb_acquire_phy(hw);
+	ret_val = phy->ops.acquire(hw);
 	if (ret_val)
 		goto out;
 
@@ -1650,74 +1619,14 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw
 
 	udelay(150);
 
-	igb_release_phy(hw);
+	phy->ops.release(hw);
 
-	ret_val = igb_get_phy_cfg_done(hw);
+	ret_val = phy->ops.get_cfg_done(hw);
 
 out:
 	return ret_val;
 }
 
-/* Internal function pointers */
-
-/**
- *  igb_get_phy_cfg_done - Generic PHY configuration done
- *  @hw: pointer to the HW structure
- *
- *  Return success if silicon family did not implement a family specific
- *  get_cfg_done function.
- **/
-static s32 igb_get_phy_cfg_done(struct e1000_hw *hw)
-{
-	if (hw->phy.ops.get_cfg_done)
-		return hw->phy.ops.get_cfg_done(hw);
-
-	return 0;
-}
-
-/**
- *  igb_release_phy - Generic release PHY
- *  @hw: pointer to the HW structure
- *
- *  Return if silicon family does not require a semaphore when accessing the
- *  PHY.
- **/
-static void igb_release_phy(struct e1000_hw *hw)
-{
-	if (hw->phy.ops.release_phy)
-		hw->phy.ops.release_phy(hw);
-}
-
-/**
- *  igb_acquire_phy - Generic acquire PHY
- *  @hw: pointer to the HW structure
- *
- *  Return success if silicon family does not require a semaphore when
- *  accessing the PHY.
- **/
-static s32 igb_acquire_phy(struct e1000_hw *hw)
-{
-	if (hw->phy.ops.acquire_phy)
-		return hw->phy.ops.acquire_phy(hw);
-
-	return 0;
-}
-
-/**
- *  igb_phy_force_speed_duplex - Generic force PHY speed/duplex
- *  @hw: pointer to the HW structure
- *
- *  When the silicon family has not implemented a forced speed/duplex
- *  function for the PHY, simply return 0.
- **/
-s32 igb_phy_force_speed_duplex(struct e1000_hw *hw)
-{
-	if (hw->phy.ops.force_speed_duplex)
-		return hw->phy.ops.force_speed_duplex(hw);
-
-	return 0;
-}
-
 /**
  *  igb_phy_init_script_igp3 - Inits the IGP3 PHY
  *  @hw: pointer to the HW structure
@@ -1730,75 +1639,75 @@ s32 igb_phy_init_script_igp3(struct e100
 
 	/* PHY init IGP 3 */
 	/* Enable rise/fall, 10-mode work in class-A */
-	hw->phy.ops.write_phy_reg(hw, 0x2F5B, 0x9018);
+	hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
 	/* Remove all caps from Replica path filter */
-	hw->phy.ops.write_phy_reg(hw, 0x2F52, 0x0000);
+	hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
 	/* Bias trimming for ADC, AFE and Driver (Default) */
-	hw->phy.ops.write_phy_reg(hw, 0x2FB1, 0x8B24);
+	hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
 	/* Increase Hybrid poly bias */
-	hw->phy.ops.write_phy_reg(hw, 0x2FB2, 0xF8F0);
+	hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
 	/* Add 4% to TX amplitude in Giga mode */
-	hw->phy.ops.write_phy_reg(hw, 0x2010, 0x10B0);
+	hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
 	/* Disable trimming (TTT) */
-	hw->phy.ops.write_phy_reg(hw, 0x2011, 0x0000);
+	hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
 	/* Poly DC correction to 94.6% + 2% for all channels */
-	hw->phy.ops.write_phy_reg(hw, 0x20DD, 0x249A);
+	hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
 	/* ABS DC correction to 95.9% */
-	hw->phy.ops.write_phy_reg(hw, 0x20DE, 0x00D3);
+	hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
 	/* BG temp curve trim */
-	hw->phy.ops.write_phy_reg(hw, 0x28B4, 0x04CE);
+	hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
 	/* Increasing ADC OPAMP stage 1 currents to max */
-	hw->phy.ops.write_phy_reg(hw, 0x2F70, 0x29E4);
+	hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
 	/* Force 1000 ( required for enabling PHY regs configuration) */
-	hw->phy.ops.write_phy_reg(hw, 0x0000, 0x0140);
+	hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
 	/* Set upd_freq to 6 */
-	hw->phy.ops.write_phy_reg(hw, 0x1F30, 0x1606);
+	hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
 	/* Disable NPDFE */
-	hw->phy.ops.write_phy_reg(hw, 0x1F31, 0xB814);
+	hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
 	/* Disable adaptive fixed FFE (Default) */
-	hw->phy.ops.write_phy_reg(hw, 0x1F35, 0x002A);
+	hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
 	/* Enable FFE hysteresis */
-	hw->phy.ops.write_phy_reg(hw, 0x1F3E, 0x0067);
+	hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
 	/* Fixed FFE for short cable lengths */
-	hw->phy.ops.write_phy_reg(hw, 0x1F54, 0x0065);
+	hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
 	/* Fixed FFE for medium cable lengths */
-	hw->phy.ops.write_phy_reg(hw, 0x1F55, 0x002A);
+	hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
 	/* Fixed FFE for long cable lengths */
-	hw->phy.ops.write_phy_reg(hw, 0x1F56, 0x002A);
+	hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
 	/* Enable Adaptive Clip Threshold */
-	hw->phy.ops.write_phy_reg(hw, 0x1F72, 0x3FB0);
+	hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
 	/* AHT reset limit to 1 */
-	hw->phy.ops.write_phy_reg(hw, 0x1F76, 0xC0FF);
+	hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
 	/* Set AHT master delay to 127 msec */
-	hw->phy.ops.write_phy_reg(hw, 0x1F77, 0x1DEC);
+	hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
 	/* Set scan bits for AHT */
-	hw->phy.ops.write_phy_reg(hw, 0x1F78, 0xF9EF);
+	hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
 	/* Set AHT Preset bits */
-	hw->phy.ops.write_phy_reg(hw, 0x1F79, 0x0210);
+	hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
 	/* Change integ_factor of channel A to 3 */
-	hw->phy.ops.write_phy_reg(hw, 0x1895, 0x0003);
+	hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
 	/* Change prop_factor of channels BCD to 8 */
-	hw->phy.ops.write_phy_reg(hw, 0x1796, 0x0008);
+	hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
 	/* Change cg_icount + enable integbp for channels BCD */
-	hw->phy.ops.write_phy_reg(hw, 0x1798, 0xD008);
+	hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
 	/*
 	 * Change cg_icount + enable integbp + change prop_factor_master
 	 * to 8 for channel A
 	 */
-	hw->phy.ops.write_phy_reg(hw, 0x1898, 0xD918);
+	hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
 	/* Disable AHT in Slave mode on channel A */
-	hw->phy.ops.write_phy_reg(hw, 0x187A, 0x0800);
+	hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
 	/*
 	 * Enable LPLU and disable AN to 1000 in non-D0a states,
 	 * Enable SPD+B2B
 	 */
-	hw->phy.ops.write_phy_reg(hw, 0x0019, 0x008D);
+	hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
 	/* Enable restart AN on an1000_dis change */
-	hw->phy.ops.write_phy_reg(hw, 0x001B, 0x2080);
+	hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
 	/* Enable wh_fifo read clock in 10/100 modes */
-	hw->phy.ops.write_phy_reg(hw, 0x0014, 0x0045);
+	hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
 	/* Restart AN, Speed selection is 1000 */
-	hw->phy.ops.write_phy_reg(hw, 0x0000, 0x1340);
+	hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_phy.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_phy.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_phy.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_phy.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,7 +44,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_phy_force_speed_duplex(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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_regs.h linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_regs.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/e1000_regs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/e1000_regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -73,8 +73,75 @@
 #define E1000_TCPTIMER 0x0104C  /* TCP Timer - RW */
 #define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
 #define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
-#define E1000_RDFPCQ(_n)  (0x02430 + (0x4 * (_n)))
 #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
+
+/* Filtering Registers */
+#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
+#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
+#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
+#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
+#define E1000_SAQF0 E1000_SAQF(0)
+#define E1000_DAQF0 E1000_DAQF(0)
+#define E1000_SPQF0 E1000_SPQF(0)
+#define E1000_FTQF0 E1000_FTQF(0)
+#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
+#define E1000_ETQF(_n)  (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+
 /* Split and Replication RX Control - RW */
 /*
  * Convenience macros
@@ -110,7 +177,6 @@
 				    : (0x0E018 + ((_n) * 0x40)))
 #define E1000_TXDCTL(_n)  ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
 				    : (0x0E028 + ((_n) * 0x40)))
-#define E1000_TARC(_n)    (0x03840 + (_n << 8))
 #define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
 #define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
 #define E1000_TDWBAL(_n)  ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
@@ -226,16 +292,14 @@
 #define E1000_RAH(_i)  (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
                                        (0x054E4 + ((_i - 16) * 8)))
 #define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
-#define E1000_VMD_CTL  0x0581C  /* VMDq Control - RW */
+#define E1000_VT_CTL   0x0581C  /* VMDq Control - RW */
 #define E1000_WUC      0x05800  /* Wakeup Control - RW */
 #define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
 #define E1000_WUS      0x05810  /* Wakeup Status - RO */
 #define E1000_MANC     0x05820  /* Management Control - RW */
 #define E1000_IPAV     0x05838  /* IP Address Valid - RW */
 #define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
-#define E1000_HOST_IF  0x08800  /* Host Interface */
 
-#define E1000_MANC2H      0x05860 /* Management Control To Host - RW */
 #define E1000_SW_FW_SYNC  0x05B5C /* Software-Firmware Synchronization - RW */
 #define E1000_CCMCTL      0x05B48 /* CCM Control Register */
 #define E1000_GIOCTL      0x05B44 /* GIO Analog Control Register */
@@ -243,9 +307,7 @@
 #define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
 #define E1000_SWSM      0x05B50 /* SW Semaphore */
 #define E1000_FWSM      0x05B54 /* FW Semaphore */
-#define E1000_DCA_ID    0x05B70 /* DCA Requester ID Information - RO */
 #define E1000_DCA_CTRL  0x05B74 /* DCA Control - RW */
-#define E1000_HICR      0x08F00 /* Host Inteface Control */
 
 /* RSS registers */
 #define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
@@ -254,18 +316,27 @@
 #define E1000_IMIRVP    0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
 /* MSI-X Allocation Register (_i) - RW */
 #define E1000_MSIXBM(_i)    (0x01600 + ((_i) * 4))
-/* MSI-X Table entry addr low reg 0 - RW */
-#define E1000_MSIXTADD(_i)  (0x0C000 + ((_i) * 0x10))
-/* MSI-X Table entry addr upper reg 0 - RW */
-#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
-/* MSI-X Table entry message reg 0 - RW */
-#define E1000_MSIXTMSG(_i)  (0x0C008 + ((_i) * 0x10))
-/* MSI-X Table entry vector ctrl reg 0 - RW */
-#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
 /* Redirection Table - RW Array */
 #define E1000_RETA(_i)  (0x05C00 + ((_i) * 4))
 #define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
 
+/* VT Registers */
+#define E1000_MBVFICR   0x00C80 /* Mailbox VF Cause - RWC */
+#define E1000_MBVFIMR   0x00C84 /* Mailbox VF int Mask - RW */
+#define E1000_VFLRE     0x00C88 /* VF Register Events - RWC */
+#define E1000_VFRE      0x00C8C /* VF Receive Enables */
+#define E1000_VFTE      0x00C90 /* VF Transmit Enables */
+#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_IOVTCL    0x05BBC /* IOV Control Register */
+/* These act per VF so an array friendly macro is used */
+#define E1000_P2VMAILBOX(_n)   (0x00C00 + (4 * (_n)))
+#define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n)))
+#define E1000_VMOLR(_n)        (0x05AD0 + (4 * (_n)))
+#define E1000_VLVF(_n)         (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
+                                                       * Filter - RW */
+
 #define wr32(reg, value) (writel(value, hw->hw_addr + reg))
 #define rd32(reg) (readl(hw->hw_addr + reg))
 #define wrfl() ((void)rd32(E1000_STATUS))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/igb_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/igb/igb_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/igb_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/igb_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -88,16 +88,11 @@ static const struct igb_stats igb_gstrin
 	{ "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) },
-	{ "rx_header_split", IGB_STAT(rx_hdr_split) },
+	{ "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) },
-#ifdef CONFIG_IGB_LRO
-	{ "lro_aggregated", IGB_STAT(lro_aggregated) },
-	{ "lro_flushed", IGB_STAT(lro_flushed) },
-	{ "lro_no_desc", IGB_STAT(lro_no_desc) },
-#endif
 };
 
 #define IGB_QUEUE_STATS_LEN \
@@ -293,15 +288,15 @@ static int igb_set_rx_csum(struct net_de
 
 static u32 igb_get_tx_csum(struct net_device *netdev)
 {
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
+	return (netdev->features & NETIF_F_IP_CSUM) != 0;
 }
 
 static int igb_set_tx_csum(struct net_device *netdev, u32 data)
 {
 	if (data)
-		netdev->features |= NETIF_F_HW_CSUM;
+		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 	else
-		netdev->features &= ~NETIF_F_HW_CSUM;
+		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 
 	return 0;
 }
@@ -310,15 +305,13 @@ static int igb_set_tso(struct net_device
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	if (data)
+	if (data) {
 		netdev->features |= NETIF_F_TSO;
-	else
-		netdev->features &= ~NETIF_F_TSO;
-
-	if (data)
 		netdev->features |= NETIF_F_TSO6;
-	else
+	} else {
+		netdev->features &= ~NETIF_F_TSO;
 		netdev->features &= ~NETIF_F_TSO6;
+	}
 
 	dev_info(&adapter->pdev->dev, "TSO is %s\n",
 		 data ? "Enabled" : "Disabled");
@@ -405,7 +398,7 @@ static void igb_get_regs(struct net_devi
 	regs_buff[34] = rd32(E1000_RLPML);
 	regs_buff[35] = rd32(E1000_RFCTL);
 	regs_buff[36] = rd32(E1000_MRQC);
-	regs_buff[37] = rd32(E1000_VMD_CTL);
+	regs_buff[37] = rd32(E1000_VT_CTL);
 
 	/* Transmit */
 	regs_buff[38] = rd32(E1000_TCTL);
@@ -598,12 +591,12 @@ static int igb_get_eeprom(struct net_dev
 		return -ENOMEM;
 
 	if (hw->nvm.type == e1000_nvm_eeprom_spi)
-		ret_val = hw->nvm.ops.read_nvm(hw, first_word,
+		ret_val = hw->nvm.ops.read(hw, first_word,
 					    last_word - first_word + 1,
 					    eeprom_buff);
 	else {
 		for (i = 0; i < last_word - first_word + 1; i++) {
-			ret_val = hw->nvm.ops.read_nvm(hw, first_word + i, 1,
+			ret_val = hw->nvm.ops.read(hw, first_word + i, 1,
 						    &eeprom_buff[i]);
 			if (ret_val)
 				break;
@@ -650,14 +643,14 @@ static int igb_set_eeprom(struct net_dev
 	if (eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
-		ret_val = hw->nvm.ops.read_nvm(hw, first_word, 1,
+		ret_val = hw->nvm.ops.read(hw, first_word, 1,
 					    &eeprom_buff[0]);
 		ptr++;
 	}
 	if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
-		ret_val = hw->nvm.ops.read_nvm(hw, last_word, 1,
+		ret_val = hw->nvm.ops.read(hw, last_word, 1,
 				   &eeprom_buff[last_word - first_word]);
 	}
 
@@ -670,7 +663,7 @@ static int igb_set_eeprom(struct net_dev
 	for (i = 0; i < last_word - first_word + 1; i++)
 		eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
 
-	ret_val = hw->nvm.ops.write_nvm(hw, first_word,
+	ret_val = hw->nvm.ops.write(hw, first_word,
 				     last_word - first_word + 1, eeprom_buff);
 
 	/* Update the checksum over the first part of the EEPROM if needed
@@ -694,7 +687,7 @@ static void igb_get_drvinfo(struct net_d
 
 	/* EEPROM image version # is reported as firmware version # for
 	 * 82575 controllers */
-	adapter->hw.nvm.ops.read_nvm(&adapter->hw, 5, 1, &eeprom_data);
+	adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data);
 	sprintf(firmware_version, "%d.%d-%d",
 		(eeprom_data & 0xF000) >> 12,
 		(eeprom_data & 0x0FF0) >> 4,
@@ -863,23 +856,26 @@ static struct igb_reg_test reg_test_8257
 	{ 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,  8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
-	{ E1000_RDBAH(4),  0x40,  8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
-	{ E1000_RDLEN(4),  0x40,  8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
-	/* Enable all four RX queues before testing. */
-	{ E1000_RXDCTL(0), 0x100, 1,  WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+	{ E1000_RDBAL(4),  0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_RDBAH(4),  0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_RDLEN(4),  0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	/* Enable all RX queues before testing. */
+	{ E1000_RXDCTL(0), 0x100, 4,  WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+	{ E1000_RXDCTL(4), 0x40, 12,  WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
 	/* RDH is read-only for 82576, only test RDT. */
 	{ E1000_RDT(0),	   0x100, 4,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+	{ E1000_RDT(4),	   0x40, 12,  PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
 	{ E1000_RXDCTL(0), 0x100, 4,  WRITE_NO_TEST, 0, 0 },
+	{ E1000_RXDCTL(4), 0x40, 12,  WRITE_NO_TEST, 0, 0 },
 	{ 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, 8,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
-	{ E1000_TDBAH(4),  0x40, 8,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
-	{ E1000_TDLEN(4),  0x40, 8,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+	{ E1000_TDBAL(4),  0x40, 12,  PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+	{ E1000_TDBAH(4),  0x40, 12,  PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+	{ E1000_TDLEN(4),  0x40, 12,  PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
 	{ 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 },
@@ -926,12 +922,13 @@ static struct igb_reg_test reg_test_8257
 static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
 			     int reg, u32 mask, u32 write)
 {
+	struct e1000_hw *hw = &adapter->hw;
 	u32 pat, val;
 	u32 _test[] =
 		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
 	for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
-		writel((_test[pat] & write), (adapter->hw.hw_addr + reg));
-		val = readl(adapter->hw.hw_addr + reg);
+		wr32(reg, (_test[pat] & write));
+		val = rd32(reg);
 		if (val != (_test[pat] & write & mask)) {
 			dev_err(&adapter->pdev->dev, "pattern test reg %04X "
 				"failed: got 0x%08X expected 0x%08X\n",
@@ -946,9 +943,10 @@ static bool reg_pattern_test(struct igb_
 static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
 			      int reg, u32 mask, u32 write)
 {
+	struct e1000_hw *hw = &adapter->hw;
 	u32 val;
-	writel((write & mask), (adapter->hw.hw_addr + reg));
-	val = readl(adapter->hw.hw_addr + reg);
+	wr32(reg, write & mask);
+	val = rd32(reg);
 	if ((write & mask) != (val & mask)) {
 		dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
 			" got 0x%08X expected 0x%08X\n", reg,
@@ -1014,12 +1012,14 @@ static int igb_reg_test(struct igb_adapt
 		for (i = 0; i < test->array_len; i++) {
 			switch (test->test_type) {
 			case PATTERN_TEST:
-				REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
+				REG_PATTERN_TEST(test->reg +
+						(i * test->reg_offset),
 						test->mask,
 						test->write);
 				break;
 			case SET_READ_TEST:
-				REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
+				REG_SET_AND_CHECK(test->reg +
+						(i * test->reg_offset),
 						test->mask,
 						test->write);
 				break;
@@ -1061,7 +1061,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_nvm(&adapter->hw, i, 1, &temp))
+		if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp))
 		    < 0) {
 			*data = 1;
 			break;
@@ -1091,16 +1091,17 @@ static int igb_intr_test(struct igb_adap
 {
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
-	u32 mask, i = 0, shared_int = true;
+	u32 mask, ics_mask, i = 0, shared_int = true;
 	u32 irq = adapter->pdev->irq;
 
 	*data = 0;
 
 	/* Hook up test interrupt handler just for this test */
-	if (adapter->msix_entries) {
+	if (adapter->msix_entries)
 		/* NOTE: we don't test MSI-X interrupts here, yet */
 		return 0;
-	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
+
+	if (adapter->flags & IGB_FLAG_HAS_MSI) {
 		shared_int = false;
 		if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
 			*data = 1;
@@ -1116,16 +1117,31 @@ static int igb_intr_test(struct igb_adap
 	}
 	dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
 		(shared_int ? "shared" : "unshared"));
-
 	/* Disable all the interrupts */
 	wr32(E1000_IMC, 0xFFFFFFFF);
 	msleep(10);
 
+	/* Define all writable bits for ICS */
+	switch(hw->mac.type) {
+	case e1000_82575:
+		ics_mask = 0x37F47EDD;
+		break;
+	case e1000_82576:
+		ics_mask = 0x77D4FBFD;
+		break;
+	default:
+		ics_mask = 0x7FFFFFFF;
+		break;
+	}
+
 	/* Test each interrupt */
-	for (; i < 10; i++) {
+	for (; i < 31; i++) {
 		/* Interrupt to test */
 		mask = 1 << i;
 
+		if (!(mask & ics_mask))
+			continue;
+
 		if (!shared_int) {
 			/* Disable the interrupt to be reported in
 			 * the cause register and then force the same
@@ -1134,8 +1150,12 @@ static int igb_intr_test(struct igb_adap
 			 * test failed.
 			 */
 			adapter->test_icr = 0;
-			wr32(E1000_IMC, ~mask & 0x00007FFF);
-			wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+			/* Flush any pending interrupts */
+			wr32(E1000_ICR, ~0);
+
+			wr32(E1000_IMC, mask);
+			wr32(E1000_ICS, mask);
 			msleep(10);
 
 			if (adapter->test_icr & mask) {
@@ -1151,6 +1171,10 @@ static int igb_intr_test(struct igb_adap
 		 * test failed.
 		 */
 		adapter->test_icr = 0;
+
+		/* Flush any pending interrupts */
+		wr32(E1000_ICR, ~0);
+
 		wr32(E1000_IMS, mask);
 		wr32(E1000_ICS, mask);
 		msleep(10);
@@ -1168,11 +1192,15 @@ static int igb_intr_test(struct igb_adap
 			 * test failed.
 			 */
 			adapter->test_icr = 0;
-			wr32(E1000_IMC, ~mask & 0x00007FFF);
-			wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+			/* Flush any pending interrupts */
+			wr32(E1000_ICR, ~0);
+
+			wr32(E1000_IMC, ~mask);
+			wr32(E1000_ICS, ~mask);
 			msleep(10);
 
-			if (adapter->test_icr) {
+			if (adapter->test_icr & mask) {
 				*data = 5;
 				break;
 			}
@@ -1180,7 +1208,7 @@ static int igb_intr_test(struct igb_adap
 	}
 
 	/* Disable all the interrupts */
-	wr32(E1000_IMC, 0xFFFFFFFF);
+	wr32(E1000_IMC, ~0);
 	msleep(10);
 
 	/* Unhook test interrupt handler */
@@ -1244,6 +1272,7 @@ static int igb_setup_desc_rings(struct i
 	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;
 
@@ -1260,7 +1289,7 @@ static int igb_setup_desc_rings(struct i
 		goto err_nomem;
 	}
 
-	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+	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);
@@ -1274,7 +1303,7 @@ static int igb_setup_desc_rings(struct i
 			((u64) tx_ring->dma & 0x00000000FFFFFFFF));
 	wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
 	wr32(E1000_TDLEN(0),
-			tx_ring->count * sizeof(struct e1000_tx_desc));
+			tx_ring->count * sizeof(union e1000_adv_tx_desc));
 	wr32(E1000_TDH(0), 0);
 	wr32(E1000_TDT(0), 0);
 	wr32(E1000_TCTL,
@@ -1283,27 +1312,31 @@ static int igb_setup_desc_rings(struct i
 			E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
 
 	for (i = 0; i < tx_ring->count; i++) {
-		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, 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);
-		tx_ring->buffer_info[i].skb = skb;
-		tx_ring->buffer_info[i].length = skb->len;
-		tx_ring->buffer_info[i].dma =
-			pci_map_single(pdev, skb->data, skb->len,
-				       PCI_DMA_TODEVICE);
-		tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma);
-		tx_desc->lower.data = cpu_to_le32(skb->len);
-		tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
-						   E1000_TXD_CMD_IFCS |
-						   E1000_TXD_CMD_RS);
-		tx_desc->upper.data = 0;
+		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);
 	}
 
 	/* Setup Rx descriptor ring and Rx buffers */
@@ -1319,7 +1352,7 @@ static int igb_setup_desc_rings(struct i
 		goto err_nomem;
 	}
 
-	rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
+	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) {
@@ -1338,16 +1371,17 @@ static int igb_setup_desc_rings(struct i
 	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_SZ_2048 |
-		E1000_RCTL_RDMTS_HALF |
+	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), 0);
+	wr32(E1000_SRRCTL(0), E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
 
 	for (i = 0; i < rx_ring->count; i++) {
-		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+		union e1000_adv_rx_desc *rx_desc;
 		struct sk_buff *skb;
 
+		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) {
@@ -1355,11 +1389,11 @@ static int igb_setup_desc_rings(struct i
 			goto err_nomem;
 		}
 		skb_reserve(skb, NET_IP_ALIGN);
-		rx_ring->buffer_info[i].skb = skb;
-		rx_ring->buffer_info[i].dma =
-			pci_map_single(pdev, skb->data, IGB_RXBUFFER_2048,
-				       PCI_DMA_FROMDEVICE);
-		rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
+		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);
 	}
 
@@ -1385,7 +1419,6 @@ static int igb_integrated_phy_loopback(s
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 ctrl_reg = 0;
-	u32 stat_reg = 0;
 
 	hw->mac.autoneg = false;
 
@@ -1409,18 +1442,11 @@ static int igb_integrated_phy_loopback(s
 	ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
 		     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
 		     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
-		     E1000_CTRL_FD);	 /* Force Duplex to FULL */
+		     E1000_CTRL_FD |	 /* Force Duplex to FULL */
+		     E1000_CTRL_SLU);	 /* Set link up enable bit */
 
-	if (hw->phy.media_type == e1000_media_type_copper &&
-	    hw->phy.type == e1000_phy_m88)
+	if (hw->phy.type == e1000_phy_m88)
 		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
-	else {
-		/* Set the ILOS bit on the fiber Nic if half duplex link is
-		 * detected. */
-		stat_reg = rd32(E1000_STATUS);
-		if ((stat_reg & E1000_STATUS_FD) == 0)
-			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
-	}
 
 	wr32(E1000_CTRL, ctrl_reg);
 
@@ -1458,7 +1484,7 @@ static int igb_setup_loopback_test(struc
 			 E1000_CTRL_TFCE |
 			 E1000_CTRL_LRST);
 		reg |= E1000_CTRL_SLU |
-		       E1000_CTRL_FD; 
+		       E1000_CTRL_FD;
 		wr32(E1000_CTRL, reg);
 
 		/* Unset switch control to serdes energy detect */
@@ -1745,6 +1771,15 @@ static int igb_wol_exclusion(struct igb_
 		/* return success for non excluded adapter ports */
 		retval = 0;
 		break;
+	case E1000_DEV_ID_82576_QUAD_COPPER:
+		/* quad port adapters only support WoL on port A */
+		if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
+			wol->supported = 0;
+			break;
+		}
+		/* return success for non excluded adapter ports */
+		retval = 0;
+		break;
 	default:
 		/* dual port cards only support WoL on port A from now on
 		 * unless it was enabled in the eeprom for port B
@@ -1827,9 +1862,6 @@ static int igb_set_wol(struct net_device
 	return 0;
 }
 
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define IGB_ID_INTERVAL		(HZ/4)
-
 /* bit defines for adapter->led_status */
 #define IGB_LED_ON		0
 
@@ -1921,18 +1953,6 @@ static void igb_get_ethtool_stats(struct
 	int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
 	int j;
 	int i;
-#ifdef CONFIG_IGB_LRO
-	int aggregated = 0, flushed = 0, no_desc = 0;
-
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
-		flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
-		no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
-	}
-	adapter->lro_aggregated = aggregated;
-	adapter->lro_flushed = flushed;
-	adapter->lro_no_desc = no_desc;
-#endif
 
 	igb_update_stats(adapter);
 	for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/igb.h linux-libre-2.6.30-gnu1/drivers/net/igb/igb.h
--- linux-libre-2.6.29-gnu1/drivers/net/igb/igb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/igb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -34,25 +34,15 @@
 #include "e1000_mac.h"
 #include "e1000_82575.h"
 
-struct igb_adapter;
-
-#ifdef CONFIG_IGB_LRO
-#include <linux/inet_lro.h>
-#define MAX_LRO_AGGR                      32
-#define MAX_LRO_DESCRIPTORS                8
-#endif
+#include <linux/clocksource.h>
+#include <linux/timecompare.h>
+#include <linux/net_tstamp.h>
 
-/* Interrupt defines */
-#define IGB_MIN_DYN_ITR 3000
-#define IGB_MAX_DYN_ITR 96000
+struct igb_adapter;
 
 /* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
 #define IGB_START_ITR 648
 
-#define IGB_DYN_ITR_PACKET_THRESHOLD 2
-#define IGB_DYN_ITR_LENGTH_LOW 200
-#define IGB_DYN_ITR_LENGTH_HIGH 1000
-
 /* TX/RX descriptor defines */
 #define IGB_DEFAULT_TXD                  256
 #define IGB_MIN_TXD                       80
@@ -67,8 +57,21 @@ struct igb_adapter;
 #define IGB_MIN_ITR_USECS                 10
 
 /* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES                  4
-#define IGB_MAX_TX_QUEUES                  4
+#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_VF_MC_ENTRIES              30
+#define IGB_MAX_VF_FUNCTIONS               8
+#define IGB_MAX_VFTA_ENTRIES               128
+
+struct vf_data_storage {
+	unsigned char vf_mac_addresses[ETH_ALEN];
+	u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
+	u16 num_vf_mc_hashes;
+	bool clear_to_send;
+};
 
 /* RX descriptor control thresholds.
  * PTHRESH - MAC will consider prefetch if it has fewer than this number of
@@ -94,12 +97,9 @@ struct igb_adapter;
 #define IGB_RXBUFFER_512   512
 #define IGB_RXBUFFER_1024  1024
 #define IGB_RXBUFFER_2048  2048
-#define IGB_RXBUFFER_4096  4096
-#define IGB_RXBUFFER_8192  8192
 #define IGB_RXBUFFER_16384 16384
 
-/* Packet Buffer allocations */
-
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
 
 /* How many Tx Descriptors do we need to call netif_wake_queue ? */
 #define IGB_TX_QUEUE_WAKE	16
@@ -176,29 +176,18 @@ struct igb_ring {
 			struct napi_struct napi;
 			int set_itr;
 			struct igb_ring *buddy;
-#ifdef CONFIG_IGB_LRO
-			struct net_lro_mgr lro_mgr;
-			bool lro_used;
-#endif
 		};
 	};
 
 	char name[IFNAMSIZ + 5];
 };
 
-#define IGB_DESC_UNUSED(R) \
-	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
-	(R)->next_to_clean - (R)->next_to_use - 1)
-
 #define E1000_RX_DESC_ADV(R, i)	    \
 	(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
 #define E1000_TX_DESC_ADV(R, i)	    \
 	(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
 #define E1000_TX_CTXTDESC_ADV(R, i)	    \
 	(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
-#define E1000_GET_DESC(R, i, type)	(&(((struct type *)((R).desc))[i]))
-#define E1000_TX_DESC(R, i)		E1000_GET_DESC(R, i, e1000_tx_desc)
-#define E1000_RX_DESC(R, i)		E1000_GET_DESC(R, i, e1000_rx_desc)
 
 /* board specific private data structure */
 
@@ -248,7 +237,6 @@ struct igb_adapter {
 
 	u64 hw_csum_err;
 	u64 hw_csum_good;
-	u64 rx_hdr_split;
 	u32 alloc_rx_buff_failed;
 	bool rx_csum;
 	u32 gorc;
@@ -262,6 +250,10 @@ struct igb_adapter {
 	struct napi_struct napi;
 	struct pci_dev *pdev;
 	struct net_device_stats net_stats;
+	struct cyclecounter cycles;
+	struct timecounter clock;
+	struct timecompare compare;
+	struct hwtstamp_config hwtstamp_config;
 
 	/* structs defined in e1000_hw.h */
 	struct e1000_hw hw;
@@ -283,27 +275,17 @@ struct igb_adapter {
 	unsigned int flags;
 	u32 eeprom_wol;
 
-	/* for ioport free */
-	int bars;
-	int need_ioport;
-
-	struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
-#ifdef CONFIG_IGB_LRO
-	unsigned int lro_max_aggr;
-	unsigned int lro_aggregated;
-	unsigned int lro_flushed;
-	unsigned int lro_no_desc;
-#endif
+	struct igb_ring *multi_tx_table[IGB_ABS_MAX_TX_QUEUES];
 	unsigned int tx_ring_count;
 	unsigned int rx_ring_count;
+	unsigned int vfs_allocated_count;
+	struct vf_data_storage *vf_data;
 };
 
 #define IGB_FLAG_HAS_MSI           (1 << 0)
-#define IGB_FLAG_MSI_ENABLE        (1 << 1)
-#define IGB_FLAG_DCA_ENABLED       (1 << 2)
-#define IGB_FLAG_IN_NETPOLL        (1 << 3)
-#define IGB_FLAG_QUAD_PORT_A       (1 << 4)
-#define IGB_FLAG_NEED_CTX_IDX      (1 << 5)
+#define IGB_FLAG_DCA_ENABLED       (1 << 1)
+#define IGB_FLAG_QUAD_PORT_A       (1 << 2)
+#define IGB_FLAG_NEED_CTX_IDX      (1 << 3)
 
 enum e1000_state_t {
 	__IGB_TESTING,
@@ -333,24 +315,24 @@ extern void igb_set_ethtool_ops(struct n
 
 static inline s32 igb_reset_phy(struct e1000_hw *hw)
 {
-	if (hw->phy.ops.reset_phy)
-		return hw->phy.ops.reset_phy(hw);
+	if (hw->phy.ops.reset)
+		return hw->phy.ops.reset(hw);
 
 	return 0;
 }
 
 static inline s32 igb_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
 {
-	if (hw->phy.ops.read_phy_reg)
-		return hw->phy.ops.read_phy_reg(hw, offset, data);
+	if (hw->phy.ops.read_reg)
+		return hw->phy.ops.read_reg(hw, offset, data);
 
 	return 0;
 }
 
 static inline s32 igb_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
 {
-	if (hw->phy.ops.write_phy_reg)
-		return hw->phy.ops.write_phy_reg(hw, offset, data);
+	if (hw->phy.ops.write_reg)
+		return hw->phy.ops.write_reg(hw, offset, data);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/igb_main.c linux-libre-2.6.30-gnu1/drivers/net/igb/igb_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/igb/igb_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/igb_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel(R) Gigabit Ethernet Linux driver
-  Copyright(c) 2007 Intel Corporation.
+  Copyright(c) 2007-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,
@@ -34,6 +34,7 @@
 #include <linux/ipv6.h>
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
+#include <linux/net_tstamp.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
@@ -48,12 +49,12 @@
 #endif
 #include "igb.h"
 
-#define DRV_VERSION "1.2.45-k2"
+#define DRV_VERSION "1.3.16-k2"
 char igb_driver_name[] = "igb";
 char igb_driver_version[] = DRV_VERSION;
 static const char igb_driver_string[] =
 				"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
+static const char igb_copyright[] = "Copyright (c) 2007-2009 Intel Corporation.";
 
 static const struct e1000_info *igb_info_tbl[] = {
 	[board_82575] = &e1000_82575_info,
@@ -61,8 +62,10 @@ static const struct e1000_info *igb_info
 
 static struct pci_device_id igb_pci_tbl[] = {
 	{ 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_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -105,7 +108,6 @@ static irqreturn_t igb_intr_msi(int irq,
 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 int igb_clean_rx_ring_msix(struct napi_struct *, int);
 #ifdef CONFIG_IGB_DCA
 static void igb_update_rx_dca(struct igb_ring *);
 static void igb_update_tx_dca(struct igb_ring *);
@@ -115,9 +117,6 @@ static bool igb_clean_tx_irq(struct igb_
 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);
-#ifdef CONFIG_IGB_LRO
-static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
-#endif
 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 *);
@@ -125,9 +124,19 @@ 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_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_set_mc_list_pools(struct igb_adapter *, int, u16);
+static void igb_vmm_control(struct igb_adapter *);
+static inline void igb_set_vmolr(struct e1000_hw *, int);
+static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int);
+static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
 
-static int igb_suspend(struct pci_dev *, pm_message_t);
 #ifdef CONFIG_PM
+static int igb_suspend(struct pci_dev *, pm_message_t);
 static int igb_resume(struct pci_dev *);
 #endif
 static void igb_shutdown(struct pci_dev *);
@@ -139,11 +148,16 @@ static struct notifier_block dca_notifie
 	.priority	= 0
 };
 #endif
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /* for netdump / net console */
 static void igb_netpoll(struct net_device *);
 #endif
+#ifdef CONFIG_PCI_IOV
+static unsigned int max_vfs = 0;
+module_param(max_vfs, uint, 0);
+MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
+                 "per physical function");
+#endif /* CONFIG_PCI_IOV */
 
 static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
 		     pci_channel_state_t);
@@ -178,6 +192,54 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Eth
 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)
+{
+	struct igb_adapter *adapter =
+		container_of(tc, struct igb_adapter, cycles);
+	struct e1000_hw *hw = &adapter->hw;
+	u64 stamp;
+
+	stamp =  rd32(E1000_SYSTIML);
+	stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL;
+
+	return stamp;
+}
+
 #ifdef DEBUG
 /**
  * igb_get_hw_dev_name - return device name string
@@ -188,9 +250,44 @@ char *igb_get_hw_dev_name(struct e1000_h
 	struct igb_adapter *adapter = hw->back;
 	return adapter->netdev->name;
 }
+
+/**
+ * igb_get_time_str - format current NIC and system time as string
+ */
+static char *igb_get_time_str(struct igb_adapter *adapter,
+			      char buffer[160])
+{
+	cycle_t hw = adapter->cycles.read(&adapter->cycles);
+	struct timespec nic = ns_to_timespec(timecounter_read(&adapter->clock));
+	struct timespec sys;
+	struct timespec delta;
+	getnstimeofday(&sys);
+
+	delta = timespec_sub(nic, sys);
+
+	sprintf(buffer,
+		"HW %llu, NIC %ld.%09lus, SYS %ld.%09lus, NIC-SYS %lds + %09luns",
+		hw,
+		(long)nic.tv_sec, nic.tv_nsec,
+		(long)sys.tv_sec, sys.tv_nsec,
+		(long)delta.tv_sec, delta.tv_nsec);
+
+	return buffer;
+}
 #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
@@ -243,6 +340,7 @@ 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;
 
 	switch (adapter->hw.mac.type) {
 	case e1000_82576:
@@ -252,9 +350,11 @@ static void igb_cache_ring_register(stru
 		 * and continue consuming queues in the same sequence
 		 */
 		for (i = 0; i < adapter->num_rx_queues; i++)
-			adapter->rx_ring[i].reg_idx = Q_IDX_82576(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 = Q_IDX_82576(i);
+			adapter->tx_ring[i].reg_idx = rbase_offset +
+			                              Q_IDX_82576(i);
 		break;
 	case e1000_82575:
 	default:
@@ -319,6 +419,9 @@ static void igb_free_queues(struct igb_a
 	for (i = 0; i < adapter->num_rx_queues; i++)
 		netif_napi_del(&adapter->rx_ring[i].napi);
 
+	adapter->num_rx_queues = 0;
+	adapter->num_tx_queues = 0;
+
 	kfree(adapter->tx_ring);
 	kfree(adapter->rx_ring);
 }
@@ -354,7 +457,7 @@ 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);
+			index = (rx_queue >> 1) + adapter->vfs_allocated_count;
 			ivar = array_rd32(E1000_IVAR0, index);
 			if (rx_queue & 0x1) {
 				/* vector goes into third byte of register */
@@ -369,7 +472,7 @@ static void igb_assign_vector(struct igb
 			array_wr32(E1000_IVAR0, index, ivar);
 		}
 		if (tx_queue > IGB_N0_QUEUE) {
-			index = (tx_queue >> 1);
+			index = (tx_queue >> 1) + adapter->vfs_allocated_count;
 			ivar = array_rd32(E1000_IVAR0, index);
 			if (tx_queue & 0x1) {
 				/* vector goes into high byte of register */
@@ -407,7 +510,7 @@ static void igb_configure_msix(struct ig
 		/* 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_PBA | E1000_GPIE_EIAME |
  				   E1000_GPIE_NSICR);
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
@@ -506,9 +609,6 @@ static int igb_request_msix(struct igb_a
 			goto out;
 		ring->itr_register = E1000_EITR(0) + (vector << 2);
 		ring->itr_val = adapter->itr;
-		/* overwrite the poll routine for MSIX, we've already done
-		 * netif_napi_add */
-		ring->napi.poll = &igb_clean_rx_ring_msix;
 		vector++;
 	}
 
@@ -546,6 +646,11 @@ static void igb_set_interrupt_capability
 	int err;
 	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());
+
 	numvecs = adapter->num_tx_queues + adapter->num_rx_queues + 1;
 	adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
 					GFP_KERNEL);
@@ -565,6 +670,21 @@ static void igb_set_interrupt_capability
 
 	/* If we can't do MSI-X, try MSI */
 msi_only:
+#ifdef CONFIG_PCI_IOV
+	/* disable SR-IOV for non MSI-X configurations */
+	if (adapter->vf_data) {
+		struct e1000_hw *hw = &adapter->hw;
+		/* disable iov and allow time for transactions to clear */
+		pci_disable_sriov(adapter->pdev);
+		msleep(500);
+
+		kfree(adapter->vf_data);
+		adapter->vf_data = NULL;
+		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+		msleep(100);
+		dev_info(&adapter->pdev->dev, "IOV Disabled\n");
+	}
+#endif
 	adapter->num_rx_queues = 1;
 	adapter->num_tx_queues = 1;
 	if (!pci_enable_msi(adapter->pdev))
@@ -687,7 +807,10 @@ static void igb_irq_enable(struct igb_ad
 		wr32(E1000_EIAC, adapter->eims_enable_mask);
 		wr32(E1000_EIAM, adapter->eims_enable_mask);
 		wr32(E1000_EIMS, adapter->eims_enable_mask);
-		wr32(E1000_IMS, E1000_IMS_LSC);
+		if (adapter->vfs_allocated_count)
+			wr32(E1000_MBVFIMR, 0xFF);
+		wr32(E1000_IMS, (E1000_IMS_LSC | E1000_IMS_VMMB |
+		                 E1000_IMS_DOUTSYNC));
 	} else {
 		wr32(E1000_IMS, IMS_ENABLE_MASK);
 		wr32(E1000_IAM, IMS_ENABLE_MASK);
@@ -778,12 +901,12 @@ static void igb_configure(struct igb_ada
 
 	igb_rx_fifo_flush_82575(&adapter->hw);
 
-	/* call IGB_DESC_UNUSED which always leaves
+	/* call igb_desc_unused which always leaves
 	 * at least 1 descriptor unused to make sure
 	 * next_to_use != next_to_clean */
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		struct igb_ring *ring = &adapter->rx_ring[i];
-		igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
+		igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
 	}
 
 
@@ -811,6 +934,10 @@ int igb_up(struct igb_adapter *adapter)
 	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);
+
 	/* Clear any pending interrupts. */
 	rd32(E1000_ICR);
 	igb_irq_enable(adapter);
@@ -856,6 +983,10 @@ void igb_down(struct igb_adapter *adapte
 
 	netdev->tx_queue_len = adapter->tx_queue_len;
 	netif_carrier_off(netdev);
+
+	/* record the stats before reset*/
+	igb_update_stats(adapter);
+
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 
@@ -886,11 +1017,14 @@ void igb_reset(struct igb_adapter *adapt
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
 	 */
-	if (mac->type != e1000_82576) {
-	pba = E1000_PBA_34K;
-	}
-	else {
+	switch (mac->type) {
+	case e1000_82576:
 		pba = E1000_PBA_64K;
+		break;
+	case e1000_82575:
+	default:
+		pba = E1000_PBA_34K;
+		break;
 	}
 
 	if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
@@ -912,7 +1046,7 @@ void igb_reset(struct igb_adapter *adapt
 		/* the tx fifo also stores 16 bytes of information about the tx
 		 * but don't include ethernet FCS because hardware appends it */
 		min_tx_space = (adapter->max_frame_size +
-				sizeof(struct e1000_tx_desc) -
+				sizeof(union e1000_adv_tx_desc) -
 				ETH_FCS_LEN) * 2;
 		min_tx_space = ALIGN(min_tx_space, 1024);
 		min_tx_space >>= 10;
@@ -956,6 +1090,20 @@ void igb_reset(struct igb_adapter *adapt
 	fc->send_xon = 1;
 	fc->type = fc->original_type;
 
+	/* disable receive for all VFs and wait one second */
+	if (adapter->vfs_allocated_count) {
+		int i;
+		for (i = 0 ; i < adapter->vfs_allocated_count; i++)
+			adapter->vf_data[i].clear_to_send = false;
+
+		/* ping all the active vfs to let them know we are going down */
+			igb_ping_all_vfs(adapter);
+
+		/* disable transmits and receives */
+		wr32(E1000_VFRE, 0);
+		wr32(E1000_VFTE, 0);
+	}
+
 	/* Allow time for pending master requests to run */
 	adapter->hw.mac.ops.reset_hw(&adapter->hw);
 	wr32(E1000_WUC, 0);
@@ -972,21 +1120,6 @@ void igb_reset(struct igb_adapter *adapt
 	igb_get_phy_info(&adapter->hw);
 }
 
-/**
- * igb_is_need_ioport - determine if an adapter needs ioport resources or not
- * @pdev: PCI device information struct
- *
- * Returns true if an adapter needs ioport resources
- **/
-static int igb_is_need_ioport(struct pci_dev *pdev)
-{
-	switch (pdev->device) {
-	/* Currently there are no adapters that need ioport resources */
-	default:
-		return false;
-	}
-}
-
 static const struct net_device_ops igb_netdev_ops = {
 	.ndo_open 		= igb_open,
 	.ndo_stop		= igb_close,
@@ -1025,34 +1158,25 @@ static int __devinit igb_probe(struct pc
 	struct e1000_hw *hw;
 	const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
 	unsigned long mmio_start, mmio_len;
-	int i, err, pci_using_dac;
+	int err, pci_using_dac;
 	u16 eeprom_data = 0;
 	u16 eeprom_apme_mask = IGB_EEPROM_APME;
 	u32 part_num;
-	int bars, need_ioport;
 
-	/* do not allocate ioport bars when not needed */
-	need_ioport = igb_is_need_ioport(pdev);
-	if (need_ioport) {
-		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
-		err = pci_enable_device(pdev);
-	} else {
-		bars = pci_select_bars(pdev, IORESOURCE_MEM);
-		err = pci_enable_device_mem(pdev);
-	}
+	err = pci_enable_device_mem(pdev);
 	if (err)
 		return err;
 
 	pci_using_dac = 0;
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!err) {
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (!err)
 			pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
-			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (err) {
 				dev_err(&pdev->dev, "No usable DMA "
 					"configuration, aborting\n");
@@ -1061,7 +1185,9 @@ static int __devinit igb_probe(struct pc
 		}
 	}
 
-	err = pci_request_selected_regions(pdev, bars, igb_driver_name);
+	err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+	                                   IORESOURCE_MEM),
+	                                   igb_driver_name);
 	if (err)
 		goto err_pci_reg;
 
@@ -1076,7 +1202,8 @@ static int __devinit igb_probe(struct pc
 	pci_save_state(pdev);
 
 	err = -ENOMEM;
-	netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
+	netdev = alloc_etherdev_mq(sizeof(struct igb_adapter),
+	                           IGB_ABS_MAX_TX_QUEUES);
 	if (!netdev)
 		goto err_alloc_etherdev;
 
@@ -1089,15 +1216,13 @@ static int __devinit igb_probe(struct pc
 	hw = &adapter->hw;
 	hw->back = adapter;
 	adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
-	adapter->bars = bars;
-	adapter->need_ioport = need_ioport;
 
 	mmio_start = pci_resource_start(pdev, 0);
 	mmio_len = pci_resource_len(pdev, 0);
 
 	err = -EIO;
-	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-	if (!adapter->hw.hw_addr)
+	hw->hw_addr = ioremap(mmio_start, mmio_len);
+	if (!hw->hw_addr)
 		goto err_ioremap;
 
 	netdev->netdev_ops = &igb_netdev_ops;
@@ -1125,8 +1250,49 @@ static int __devinit igb_probe(struct pc
 	/* Initialize skew-specific constants */
 	err = ei->get_invariants(hw);
 	if (err)
-		goto err_hw_init;
+		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)
 		goto err_sw_init;
@@ -1158,27 +1324,25 @@ static int __devinit igb_probe(struct pc
 			"PHY reset is blocked due to SOL/IDER session.\n");
 
 	netdev->features = NETIF_F_SG |
-			   NETIF_F_HW_CSUM |
+			   NETIF_F_IP_CSUM |
 			   NETIF_F_HW_VLAN_TX |
 			   NETIF_F_HW_VLAN_RX |
 			   NETIF_F_HW_VLAN_FILTER;
 
+	netdev->features |= NETIF_F_IPV6_CSUM;
 	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_TSO6;
 
-#ifdef CONFIG_IGB_LRO
-	netdev->features |= NETIF_F_LRO;
-#endif
+	netdev->features |= NETIF_F_GRO;
 
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
-	netdev->vlan_features |= NETIF_F_HW_CSUM;
+	netdev->vlan_features |= NETIF_F_IP_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->features |= NETIF_F_LLTX;
 	adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
 
 	/* before reading the NVM, reset the controller to put the device in a
@@ -1205,25 +1369,15 @@ static int __devinit igb_probe(struct pc
 		goto err_eeprom;
 	}
 
-	init_timer(&adapter->watchdog_timer);
-	adapter->watchdog_timer.function = &igb_watchdog;
-	adapter->watchdog_timer.data = (unsigned long) adapter;
-
-	init_timer(&adapter->phy_info_timer);
-	adapter->phy_info_timer.function = &igb_update_phy_info;
-	adapter->phy_info_timer.data = (unsigned long) adapter;
+	setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+	            (unsigned long) adapter);
+	setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+	            (unsigned long) adapter);
 
 	INIT_WORK(&adapter->reset_task, igb_reset_task);
 	INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
 
-	/* Initialize link & ring properties that are user-changeable */
-	adapter->tx_ring->count = 256;
-	for (i = 0; i < adapter->num_tx_queues; i++)
-		adapter->tx_ring[i].count = adapter->tx_ring->count;
-	adapter->rx_ring->count = 256;
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		adapter->rx_ring[i].count = adapter->rx_ring->count;
-
+	/* Initialize link properties that are user-changeable */
 	adapter->fc_autoneg = true;
 	hw->mac.autoneg = true;
 	hw->phy.autoneg_advertised = 0x2f;
@@ -1231,7 +1385,7 @@ static int __devinit igb_probe(struct pc
 	hw->fc.original_type = e1000_fc_default;
 	hw->fc.type = e1000_fc_default;
 
-	adapter->itr_setting = 3;
+	adapter->itr_setting = IGB_DEFAULT_ITR;
 	adapter->itr = IGB_START_ITR;
 
 	igb_validate_mdi_setting(hw);
@@ -1242,10 +1396,10 @@ static int __devinit igb_probe(struct pc
 	 * enable the ACPI Magic Packet filter
 	 */
 
-	if (hw->bus.func == 0 ||
-	    hw->device_id == E1000_DEV_ID_82575EB_COPPER)
-		hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL3_PORT_A, 1,
-				     &eeprom_data);
+	if (hw->bus.func == 0)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+	else if (hw->bus.func == 1)
+		hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 
 	if (eeprom_data & eeprom_apme_mask)
 		adapter->eeprom_wol |= E1000_WUFC_MAG;
@@ -1265,6 +1419,16 @@ static int __devinit igb_probe(struct pc
 		if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
 			adapter->eeprom_wol = 0;
 		break;
+	case E1000_DEV_ID_82576_QUAD_COPPER:
+		/* if quad port adapter, disable WoL on all but port A */
+		if (global_quad_port_a != 0)
+			adapter->eeprom_wol = 0;
+		else
+			adapter->flags |= IGB_FLAG_QUAD_PORT_A;
+		/* Reset for multiple quad port adapters */
+		if (++global_quad_port_a == 4)
+			global_quad_port_a = 0;
+		break;
 	}
 
 	/* initialize the wol settings based on the eeprom settings */
@@ -1293,20 +1457,73 @@ static int __devinit igb_probe(struct pc
 		dev_info(&pdev->dev, "DCA enabled\n");
 		/* Always use CB2 mode, difference is masked
 		 * in the CB driver. */
-		wr32(E1000_DCA_CTRL, 2);
+		wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
 		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.width == e1000_bus_width_pcie_x4)
-		  ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
-		  ? "Width x1" : "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" :
+		   "unknown"),
 		 netdev->dev_addr);
 
 	igb_read_part_num(hw, &part_num);
@@ -1330,15 +1547,14 @@ err_eeprom:
 	if (hw->flash_address)
 		iounmap(hw->flash_address);
 
-	igb_remove_device(hw);
 	igb_free_queues(adapter);
 err_sw_init:
-err_hw_init:
 	iounmap(hw->hw_addr);
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
-	pci_release_selected_regions(pdev, bars);
+	pci_release_selected_regions(pdev, pci_select_bars(pdev,
+	                             IORESOURCE_MEM));
 err_pci_reg:
 err_dma:
 	pci_disable_device(pdev);
@@ -1358,9 +1574,7 @@ static void __devexit igb_remove(struct
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_IGB_DCA
 	struct e1000_hw *hw = &adapter->hw;
-#endif
 	int err;
 
 	/* flush_scheduled work may reschedule our watchdog task, so
@@ -1376,7 +1590,7 @@ static void __devexit igb_remove(struct
 		dev_info(&pdev->dev, "DCA disabled\n");
 		dca_remove_requester(&pdev->dev);
 		adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
-		wr32(E1000_DCA_CTRL, 1);
+		wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
 	}
 #endif
 
@@ -1389,15 +1603,29 @@ static void __devexit igb_remove(struct
 	if (!igb_check_reset_block(&adapter->hw))
 		igb_reset_phy(&adapter->hw);
 
-	igb_remove_device(&adapter->hw);
 	igb_reset_interrupt_capability(adapter);
 
 	igb_free_queues(adapter);
 
-	iounmap(adapter->hw.hw_addr);
-	if (adapter->hw.flash_address)
-		iounmap(adapter->hw.flash_address);
-	pci_release_selected_regions(pdev, adapter->bars);
+#ifdef CONFIG_PCI_IOV
+	/* reclaim resources allocated to VFs */
+	if (adapter->vf_data) {
+		/* disable iov and allow time for transactions to clear */
+		pci_disable_sriov(pdev);
+		msleep(500);
+
+		kfree(adapter->vf_data);
+		adapter->vf_data = NULL;
+		wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+		msleep(100);
+		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));
 
 	free_netdev(netdev);
 
@@ -1432,11 +1660,6 @@ static int __devinit igb_sw_init(struct
 	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
-	/* 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());
-
 	/* This call may decrease the number of queues depending on
 	 * interrupt mode. */
 	igb_set_interrupt_capability(adapter);
@@ -1499,6 +1722,10 @@ static int igb_open(struct net_device *n
 	 * 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;
@@ -1574,7 +1801,6 @@ static int igb_close(struct net_device *
  *
  * Return 0 on success, negative on failure
  **/
-
 int igb_setup_tx_resources(struct igb_adapter *adapter,
 			   struct igb_ring *tx_ring)
 {
@@ -1588,7 +1814,7 @@ int igb_setup_tx_resources(struct igb_ad
 	memset(tx_ring->buffer_info, 0, size);
 
 	/* round up to nearest 4K */
-	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+	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,
@@ -1635,7 +1861,7 @@ static int igb_setup_all_tx_resources(st
 	for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
 		r_idx = i % adapter->num_tx_queues;
 		adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
-	}	
+	}
 	return err;
 }
 
@@ -1654,13 +1880,13 @@ static void igb_configure_tx(struct igb_
 	int i, j;
 
 	for (i = 0; i < adapter->num_tx_queues; i++) {
-		struct igb_ring *ring = &(adapter->tx_ring[i]);
+		struct igb_ring *ring = &adapter->tx_ring[i];
 		j = ring->reg_idx;
 		wr32(E1000_TDLEN(j),
-				ring->count * sizeof(struct e1000_tx_desc));
+		     ring->count * sizeof(union e1000_adv_tx_desc));
 		tdba = ring->dma;
 		wr32(E1000_TDBAL(j),
-				tdba & 0x00000000ffffffffULL);
+		     tdba & 0x00000000ffffffffULL);
 		wr32(E1000_TDBAH(j), tdba >> 32);
 
 		ring->head = E1000_TDH(j);
@@ -1680,12 +1906,11 @@ static void igb_configure_tx(struct igb_
 		wr32(E1000_DCA_TXCTRL(j), txctrl);
 	}
 
-
-
-	/* Use the default values for the Tx Inter Packet Gap (IPG) timer */
+	/* disable queue 0 to prevent tail bump w/o re-configuration */
+	if (adapter->vfs_allocated_count)
+		wr32(E1000_TXDCTL(0), 0);
 
 	/* Program the Transmit Control Register */
-
 	tctl = rd32(E1000_TCTL);
 	tctl &= ~E1000_TCTL_CT;
 	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
@@ -1709,21 +1934,12 @@ static void igb_configure_tx(struct igb_
  *
  * Returns 0 on success, negative on failure
  **/
-
 int igb_setup_rx_resources(struct igb_adapter *adapter,
 			   struct igb_ring *rx_ring)
 {
 	struct pci_dev *pdev = adapter->pdev;
 	int size, desc_len;
 
-#ifdef CONFIG_IGB_LRO
-	size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
-	rx_ring->lro_mgr.lro_arr = vmalloc(size);
-	if (!rx_ring->lro_mgr.lro_arr)
-		goto err;
-	memset(rx_ring->lro_mgr.lro_arr, 0, size);
-#endif
-
 	size = sizeof(struct igb_buffer) * rx_ring->count;
 	rx_ring->buffer_info = vmalloc(size);
 	if (!rx_ring->buffer_info)
@@ -1750,10 +1966,6 @@ int igb_setup_rx_resources(struct igb_ad
 	return 0;
 
 err:
-#ifdef CONFIG_IGB_LRO
-	vfree(rx_ring->lro_mgr.lro_arr);
-	rx_ring->lro_mgr.lro_arr = NULL;
-#endif
 	vfree(rx_ring->buffer_info);
 	dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
 		"the receive descriptor ring\n");
@@ -1794,7 +2006,7 @@ static void igb_setup_rctl(struct igb_ad
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl;
 	u32 srrctl = 0;
-	int i, j;
+	int i;
 
 	rctl = rd32(E1000_RCTL);
 
@@ -1802,13 +2014,13 @@ static void igb_setup_rctl(struct igb_ad
 	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);
+		(hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
 
 	/*
 	 * enable stripping of CRC. It's unlikely this will break BMC
 	 * redirection as it did with e1000. Newer features require
 	 * that the HW strips the CRC.
-	*/
+	 */
 	rctl |= E1000_RCTL_SECRC;
 
 	/*
@@ -1852,8 +2064,30 @@ static void igb_setup_rctl(struct igb_ad
 		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
 	}
 
+	/* 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);
+
+		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);
+	}
+
 	for (i = 0; i < adapter->num_rx_queues; i++) {
-		j = adapter->rx_ring[i].reg_idx;
+		int j = adapter->rx_ring[i].reg_idx;
 		wr32(E1000_SRRCTL(j), srrctl);
 	}
 
@@ -1861,6 +2095,54 @@ static void igb_setup_rctl(struct igb_ad
 }
 
 /**
+ * igb_rlpml_set - set maximum receive packet size
+ * @adapter: board private structure
+ *
+ * Configure maximum receivable packet size.
+ **/
+static void igb_rlpml_set(struct igb_adapter *adapter)
+{
+	u32 max_frame_size = adapter->max_frame_size;
+	struct e1000_hw *hw = &adapter->hw;
+	u16 pf_id = adapter->vfs_allocated_count;
+
+	if (adapter->vlgrp)
+		max_frame_size += VLAN_TAG_SIZE;
+
+	/* if vfs are enabled we set RLPML to the largest possible request
+	 * 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;
+	}
+
+	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)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u16 pf_id = adapter->vfs_allocated_count;
+	u32 vtctl;
+
+	/* not in sr-iov mode - do nothing */
+	if (!pf_id)
+		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);
+}
+
+/**
  * igb_configure_rx - Configure receive Unit after Reset
  * @adapter: board private structure
  *
@@ -1872,7 +2154,7 @@ static void igb_configure_rx(struct igb_
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl, rxcsum;
 	u32 rxdctl;
-	int i, j;
+	int i;
 
 	/* disable receives while setting up the descriptors */
 	rctl = rd32(E1000_RCTL);
@@ -1886,14 +2168,14 @@ static void igb_configure_rx(struct igb_
 	/* 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]);
-		j = ring->reg_idx;
+		struct igb_ring *ring = &adapter->rx_ring[i];
+		int j = ring->reg_idx;
 		rdba = ring->dma;
 		wr32(E1000_RDBAL(j),
-				rdba & 0x00000000ffffffffULL);
+		     rdba & 0x00000000ffffffffULL);
 		wr32(E1000_RDBAH(j), rdba >> 32);
 		wr32(E1000_RDLEN(j),
-			       ring->count * sizeof(union e1000_adv_rx_desc));
+		     ring->count * sizeof(union e1000_adv_rx_desc));
 
 		ring->head = E1000_RDH(j);
 		ring->tail = E1000_RDT(j);
@@ -1907,16 +2189,6 @@ static void igb_configure_rx(struct igb_
 		rxdctl |= IGB_RX_HTHRESH << 8;
 		rxdctl |= IGB_RX_WTHRESH << 16;
 		wr32(E1000_RXDCTL(j), rxdctl);
-#ifdef CONFIG_IGB_LRO
-		/* Intitial LRO Settings */
-		ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
-		ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
-		ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
-		ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
-		ring->lro_mgr.dev = adapter->netdev;
-		ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
-		ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-#endif
 	}
 
 	if (adapter->num_rx_queues > 1) {
@@ -1941,7 +2213,10 @@ static void igb_configure_rx(struct igb_
 				writel(reta.dword,
 				       hw->hw_addr + E1000_RETA(0) + (j & ~3));
 		}
-		mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+		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++)
@@ -1966,27 +2241,23 @@ static void igb_configure_rx(struct igb_
 		rxcsum |= E1000_RXCSUM_PCSD;
 		wr32(E1000_RXCSUM, rxcsum);
 	} else {
+		/* Enable multi-queue for sr-iov */
+		if (adapter->vfs_allocated_count)
+			wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
 		/* Enable Receive Checksum Offload for TCP and UDP */
 		rxcsum = rd32(E1000_RXCSUM);
-		if (adapter->rx_csum) {
-			rxcsum |= E1000_RXCSUM_TUOFL;
+		if (adapter->rx_csum)
+			rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
+		else
+			rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
 
-			/* Enable IPv4 payload checksum for UDP fragments
-			 * Must be used in conjunction with packet-split. */
-			if (adapter->rx_ps_hdr_size)
-				rxcsum |= E1000_RXCSUM_IPPCSE;
-		} else {
-			rxcsum &= ~E1000_RXCSUM_TUOFL;
-			/* don't need to clear IPPCSE as it defaults to 0 */
-		}
 		wr32(E1000_RXCSUM, rxcsum);
 	}
 
-	if (adapter->vlgrp)
-		wr32(E1000_RLPML,
-				adapter->max_frame_size + VLAN_TAG_SIZE);
-	else
-		wr32(E1000_RLPML, adapter->max_frame_size);
+	/* Set the default pool for the PF's first queue */
+	igb_configure_vt_default_pool(adapter);
+
+	igb_rlpml_set(adapter);
 
 	/* Enable Receives */
 	wr32(E1000_RCTL, rctl);
@@ -2029,14 +2300,10 @@ static void igb_free_all_tx_resources(st
 static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
 					   struct igb_buffer *buffer_info)
 {
-	if (buffer_info->dma) {
-		pci_unmap_page(adapter->pdev,
-				buffer_info->dma,
-				buffer_info->length,
-				PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
-	}
+	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;
 	}
@@ -2105,11 +2372,6 @@ void igb_free_rx_resources(struct igb_ri
 	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
 
-#ifdef CONFIG_IGB_LRO
-	vfree(rx_ring->lro_mgr.lro_arr);
-	rx_ring->lro_mgr.lro_arr = NULL;
-#endif 
-
 	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
 
 	rx_ring->desc = NULL;
@@ -2209,15 +2471,18 @@ static void igb_clean_all_rx_rings(struc
 static int igb_set_mac(struct net_device *netdev, void *p)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
 	struct sockaddr *addr = p;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
+	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+	igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
 
 	return 0;
 }
@@ -2237,7 +2502,7 @@ static void igb_set_multi(struct net_dev
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
 	struct dev_mc_list *mc_ptr;
-	u8  *mta_list;
+	u8  *mta_list = NULL;
 	u32 rctl;
 	int i;
 
@@ -2258,17 +2523,15 @@ static void igb_set_multi(struct net_dev
 	}
 	wr32(E1000_RCTL, rctl);
 
-	if (!netdev->mc_count) {
-		/* nothing to program, so clear mc list */
-		igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
-					  mac->rar_entry_count);
-		return;
+	if (netdev->mc_count) {
+		mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+		if (!mta_list) {
+			dev_err(&adapter->pdev->dev,
+			        "failed to allocate multicast filter list\n");
+			return;
+		}
 	}
 
-	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
-	if (!mta_list)
-		return;
-
 	/* The shared function expects a packed array of only addresses. */
 	mc_ptr = netdev->mc_list;
 
@@ -2278,8 +2541,13 @@ static void igb_set_multi(struct net_dev
 		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 		mc_ptr = mc_ptr->next;
 	}
-	igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
-	                              mac->rar_entry_count);
+	igb_update_mc_addr_list(hw, mta_list, i,
+	                        adapter->vfs_allocated_count + 1,
+	                        mac->rar_entry_count);
+
+	igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
+	igb_restore_vf_multicasts(adapter);
+
 	kfree(mta_list);
 }
 
@@ -2292,6 +2560,46 @@ static void igb_update_phy_info(unsigned
 }
 
 /**
+ * igb_has_link - check shared code for link and determine up/down
+ * @adapter: pointer to driver private info
+ **/
+static bool igb_has_link(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	bool link_active = false;
+	s32 ret_val = 0;
+
+	/* get_link_status is set on LSC (link status) interrupt or
+	 * rx sequence error interrupt.  get_link_status will stay
+	 * false until the e1000_check_for_link establishes link
+	 * for copper adapters ONLY
+	 */
+	switch (hw->phy.media_type) {
+	case e1000_media_type_copper:
+		if (hw->mac.get_link_status) {
+			ret_val = hw->mac.ops.check_for_link(hw);
+			link_active = !hw->mac.get_link_status;
+		} else {
+			link_active = true;
+		}
+		break;
+	case e1000_media_type_fiber:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
+		break;
+	case e1000_media_type_internal_serdes:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = hw->mac.serdes_has_link;
+		break;
+	default:
+	case e1000_media_type_unknown:
+		break;
+	}
+
+	return link_active;
+}
+
+/**
  * igb_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
  **/
@@ -2307,34 +2615,16 @@ static void igb_watchdog_task(struct wor
 	struct igb_adapter *adapter = container_of(work,
 					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;
-	struct e1000_mac_info *mac = &adapter->hw.mac;
 	u32 link;
 	u32 eics = 0;
-	s32 ret_val;
 	int i;
 
-	if ((netif_carrier_ok(netdev)) &&
-	    (rd32(E1000_STATUS) & E1000_STATUS_LU))
+	link = igb_has_link(adapter);
+	if ((netif_carrier_ok(netdev)) && link)
 		goto link_up;
 
-	ret_val = hw->mac.ops.check_for_link(&adapter->hw);
-	if ((ret_val == E1000_ERR_PHY) &&
-	    (hw->phy.type == e1000_phy_igp_3) &&
-	    (rd32(E1000_CTRL) &
-	     E1000_PHY_CTRL_GBE_DISABLE))
-		dev_info(&adapter->pdev->dev,
-			 "Gigabit has been disabled, downgrading speed\n");
-
-	if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
-	    !(rd32(E1000_TXCW) & E1000_TXCW_ANE))
-		link = mac->serdes_has_link;
-	else
-		link = rd32(E1000_STATUS) &
-				      E1000_STATUS_LU;
-
 	if (link) {
 		if (!netif_carrier_ok(netdev)) {
 			u32 ctrl;
@@ -2373,6 +2663,9 @@ static void igb_watchdog_task(struct wor
 			netif_carrier_on(netdev);
 			netif_tx_wake_all_queues(netdev);
 
+			igb_ping_all_vfs(adapter);
+
+			/* link state has changed, schedule phy info update */
 			if (!test_bit(__IGB_DOWN, &adapter->state))
 				mod_timer(&adapter->phy_info_timer,
 					  round_jiffies(jiffies + 2 * HZ));
@@ -2386,6 +2679,10 @@ static void igb_watchdog_task(struct wor
 			       netdev->name);
 			netif_carrier_off(netdev);
 			netif_tx_stop_all_queues(netdev);
+
+			igb_ping_all_vfs(adapter);
+
+			/* link state has changed, schedule phy info update */
 			if (!test_bit(__IGB_DOWN, &adapter->state))
 				mod_timer(&adapter->phy_info_timer,
 					  round_jiffies(jiffies + 2 * HZ));
@@ -2395,9 +2692,9 @@ static void igb_watchdog_task(struct wor
 link_up:
 	igb_update_stats(adapter);
 
-	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+	hw->mac.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
 	adapter->tpt_old = adapter->stats.tpt;
-	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
+	hw->mac.collision_delta = adapter->stats.colc - adapter->colc_old;
 	adapter->colc_old = adapter->stats.colc;
 
 	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
@@ -2408,7 +2705,7 @@ link_up:
 	igb_update_adaptive(&adapter->hw);
 
 	if (!netif_carrier_ok(netdev)) {
-		if (IGB_DESC_UNUSED(tx_ring) + 1 < tx_ring->count) {
+		if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
 			/* 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.
@@ -2554,7 +2851,7 @@ static unsigned int igb_update_itr(struc
 		if (bytes > 25000) {
 			if (packets > 35)
 				retval = low_latency;
-		} else if (bytes < 6000) {
+		} else if (bytes < 1500) {
 			retval = low_latency;
 		}
 		break;
@@ -2586,15 +2883,13 @@ static void igb_set_itr(struct igb_adapt
 					    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;
 	}
 
 	/* conservative mode (itr 3) eliminates the lowest_latency setting */
-	if (adapter->itr_setting == 3 &&
-	    current_itr == lowest_latency)
+	if (adapter->itr_setting == 3 && current_itr == lowest_latency)
 		current_itr = low_latency;
 
 	switch (current_itr) {
@@ -2646,6 +2941,7 @@ set_itr_now:
 #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
 
@@ -2711,7 +3007,7 @@ static inline int igb_tso_adv(struct igb
 	mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
 	mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
 
-	/* Context index must be unique per ring. */
+	/* 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;
 
@@ -2756,13 +3052,24 @@ static inline bool igb_tx_csum_adv(struc
 		tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
-			switch (skb->protocol) {
-			case __constant_htons(ETH_P_IP):
+			__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):
 				tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
 				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
 				break;
-			case __constant_htons(ETH_P_IPV6):
+			case cpu_to_be16(ETH_P_IPV6):
 				/* XXX what about other V6 headers?? */
 				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
 					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
@@ -2781,6 +3088,8 @@ static inline bool igb_tx_csum_adv(struc
 		if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
 			context_desc->mss_l4len_idx =
 				cpu_to_le32(tx_ring->queue_index << 4);
+		else
+			context_desc->mss_l4len_idx = 0;
 
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
@@ -2793,8 +3102,6 @@ static inline bool igb_tx_csum_adv(struc
 
 		return true;
 	}
-
-
 	return false;
 }
 
@@ -2809,25 +3116,33 @@ static inline int igb_tx_map_adv(struct
 	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 = pci_map_single(adapter->pdev, skb->data, len,
-					  PCI_DMA_TODEVICE);
+	buffer_info->dma = map[count];
 	count++;
-	i++;
-	if (i == tx_ring->count)
-		i = 0;
 
 	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
 
@@ -2836,19 +3151,10 @@ 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 = pci_map_page(adapter->pdev,
-						frag->page,
-						frag->page_offset,
-						len,
-						PCI_DMA_TODEVICE);
-
+		buffer_info->dma = map[count];
 		count++;
-		i++;
-		if (i == tx_ring->count)
-			i = 0;
 	}
 
-	i = ((i == 0) ? tx_ring->count - 1 : i - 1);
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
@@ -2871,6 +3177,9 @@ static inline void igb_tx_queue_adv(stru
 	if (tx_flags & IGB_TX_FLAGS_VLAN)
 		cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
 
+	if (tx_flags & IGB_TX_FLAGS_TSTAMP)
+		cmd_type_len |= E1000_ADVTXD_MAC_TSTAMP;
+
 	if (tx_flags & IGB_TX_FLAGS_TSO) {
 		cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
 
@@ -2933,7 +3242,7 @@ static int __igb_maybe_stop_tx(struct ne
 
 	/* We need to check again in a case another CPU has just
 	 * made room available. */
-	if (IGB_DESC_UNUSED(tx_ring) < size)
+	if (igb_desc_unused(tx_ring) < size)
 		return -EBUSY;
 
 	/* A reprieve! */
@@ -2945,13 +3254,11 @@ static int __igb_maybe_stop_tx(struct ne
 static int igb_maybe_stop_tx(struct net_device *netdev,
 			     struct igb_ring *tx_ring, int size)
 {
-	if (IGB_DESC_UNUSED(tx_ring) >= size)
+	if (igb_desc_unused(tx_ring) >= size)
 		return 0;
 	return __igb_maybe_stop_tx(netdev, tx_ring, size);
 }
 
-#define TXD_USE_COUNT(S) (((S) >> (IGB_MAX_TXD_PWR)) + 1)
-
 static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
 				   struct net_device *netdev,
 				   struct igb_ring *tx_ring)
@@ -2959,11 +3266,10 @@ static int igb_xmit_frame_ring_adv(struc
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	unsigned int first;
 	unsigned int tx_flags = 0;
-	unsigned int len;
 	u8 hdr_len = 0;
+	int count = 0;
 	int tso = 0;
-
-	len = skb_headlen(skb);
+	union skb_shared_tx *shtx;
 
 	if (test_bit(__IGB_DOWN, &adapter->state)) {
 		dev_kfree_skb_any(skb);
@@ -2984,7 +3290,21 @@ static int igb_xmit_frame_ring_adv(struc
 		/* this is a hard error */
 		return NETDEV_TX_BUSY;
 	}
-	skb_orphan(skb);
+
+	/*
+	 * 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)) {
 		tx_flags |= IGB_TX_FLAGS_VLAN;
@@ -2995,7 +3315,6 @@ static int igb_xmit_frame_ring_adv(struc
 		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;
 
@@ -3006,18 +3325,27 @@ static int igb_xmit_frame_ring_adv(struc
 
 	if (tso)
 		tx_flags |= IGB_TX_FLAGS_TSO;
-	else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags))
-			if (skb->ip_summed == CHECKSUM_PARTIAL)
-				tx_flags |= IGB_TX_FLAGS_CSUM;
-
-	igb_tx_queue_adv(adapter, tx_ring, tx_flags,
-			 igb_tx_map_adv(adapter, tx_ring, skb, first),
-			 skb->len, hdr_len);
+	else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags) &&
+	         (skb->ip_summed == CHECKSUM_PARTIAL))
+		tx_flags |= IGB_TX_FLAGS_CSUM;
 
-	netdev->trans_start = jiffies;
+	/*
+	 * count reflects descriptors mapped, if 0 then mapping error
+	 * has occured and we need to rewind the descriptor queue
+	 */
+	count = igb_tx_map_adv(adapter, tx_ring, skb, first);
 
-	/* Make sure there is space in the ring for the next send. */
-	igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
+	if (count) {
+		igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
+			         skb->len, hdr_len);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
 
 	return NETDEV_TX_OK;
 }
@@ -3028,7 +3356,7 @@ static int igb_xmit_frame_adv(struct sk_
 	struct igb_ring *tx_ring;
 
 	int r_idx = 0;
-	r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+	r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
 	tx_ring = adapter->multi_tx_table[r_idx];
 
 	/* This goes back to the question of how to logically map a tx queue
@@ -3050,8 +3378,8 @@ static void igb_tx_timeout(struct net_de
 	/* Do the reset outside of interrupt context */
 	adapter->tx_timeout_count++;
 	schedule_work(&adapter->reset_task);
-	wr32(E1000_EICS, adapter->eims_enable_mask &
-		~(E1000_EIMS_TCP_TIMER | E1000_EIMS_OTHER));
+	wr32(E1000_EICS,
+	     (adapter->eims_enable_mask & ~adapter->eims_other));
 }
 
 static void igb_reset_task(struct work_struct *work)
@@ -3069,8 +3397,7 @@ static void igb_reset_task(struct work_s
  * Returns the address of the device statistics structure.
  * The statistics are actually updated from the timer callback.
  **/
-static struct net_device_stats *
-igb_get_stats(struct net_device *netdev)
+static struct net_device_stats *igb_get_stats(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
@@ -3096,7 +3423,6 @@ static int igb_change_mtu(struct net_dev
 		return -EINVAL;
 	}
 
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
 	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
 		dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
 		return -EINVAL;
@@ -3104,6 +3430,7 @@ static int igb_change_mtu(struct net_dev
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
 		msleep(1);
+
 	/* igb_down has a dependency on max_frame_size */
 	adapter->max_frame_size = max_frame;
 	if (netif_running(netdev))
@@ -3129,6 +3456,12 @@ static int igb_change_mtu(struct net_dev
 #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;
+
 	/* 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))
@@ -3273,8 +3606,7 @@ void igb_update_stats(struct igb_adapter
 	/* Phy Stats */
 	if (hw->phy.media_type == e1000_media_type_copper) {
 		if ((adapter->link_speed == SPEED_1000) &&
-		   (!igb_read_phy_reg(hw, PHY_1000T_STATUS,
-					      &phy_tmp))) {
+		   (!igb_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
 			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
 			adapter->phy_stats.idle_errors += phy_tmp;
 		}
@@ -3286,7 +3618,6 @@ void igb_update_stats(struct igb_adapter
 	adapter->stats.mgpdc += rd32(E1000_MGTPDC);
 }
 
-
 static irqreturn_t igb_msix_other(int irq, void *data)
 {
 	struct net_device *netdev = data;
@@ -3295,15 +3626,24 @@ static irqreturn_t igb_msix_other(int ir
 	u32 icr = rd32(E1000_ICR);
 
 	/* reading ICR causes bit 31 of EICR to be cleared */
-	if (!(icr & E1000_ICR_LSC))
-		goto no_link_interrupt;
-	hw->mac.get_link_status = 1;
-	/* guard against interrupt when we're going down */
-	if (!test_bit(__IGB_DOWN, &adapter->state))
-		mod_timer(&adapter->watchdog_timer, jiffies + 1);
-	
-no_link_interrupt:
-	wr32(E1000_IMS, E1000_IMS_LSC);
+
+	if(icr & E1000_ICR_DOUTSYNC) {
+		/* HW is reporting DMA is out of sync */
+		adapter->stats.doosync++;
+	}
+
+	/* Check for a mailbox event */
+	if (icr & E1000_ICR_VMMB)
+		igb_msg_task(adapter);
+
+	if (icr & E1000_ICR_LSC) {
+		hw->mac.get_link_status = 1;
+		/* guard against interrupt when we're going down */
+		if (!test_bit(__IGB_DOWN, &adapter->state))
+			mod_timer(&adapter->watchdog_timer, jiffies + 1);
+	}
+
+	wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_VMMB);
 	wr32(E1000_EIMS, adapter->eims_other);
 
 	return IRQ_HANDLED;
@@ -3319,6 +3659,7 @@ static irqreturn_t igb_msix_tx(int irq,
 	if (adapter->flags & IGB_FLAG_DCA_ENABLED)
 		igb_update_tx_dca(tx_ring);
 #endif
+
 	tx_ring->total_bytes = 0;
 	tx_ring->total_packets = 0;
 
@@ -3339,13 +3680,11 @@ static void igb_write_itr(struct igb_rin
 	if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
 		switch (hw->mac.type) {
 		case e1000_82576:
-			wr32(ring->itr_register,
-			     ring->itr_val |
+			wr32(ring->itr_register, ring->itr_val |
 			     0x80000000);
 			break;
 		default:
-			wr32(ring->itr_register,
-			     ring->itr_val |
+			wr32(ring->itr_register, ring->itr_val |
 			     (ring->itr_val << 16));
 			break;
 		}
@@ -3363,8 +3702,8 @@ static irqreturn_t igb_msix_rx(int irq,
 
 	igb_write_itr(rx_ring);
 
-	if (netif_rx_schedule_prep(&rx_ring->napi))
-		__netif_rx_schedule(&rx_ring->napi);
+	if (napi_schedule_prep(&rx_ring->napi))
+		__napi_schedule(&rx_ring->napi);
 
 #ifdef CONFIG_IGB_DCA
 	if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
@@ -3386,11 +3725,11 @@ static void igb_update_rx_dca(struct igb
 		dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
 		if (hw->mac.type == e1000_82576) {
 			dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
-			dca_rxctrl |= dca_get_tag(cpu) <<
+			dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
 			              E1000_DCA_RXCTRL_CPUID_SHIFT;
 		} else {
 			dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
-			dca_rxctrl |= dca_get_tag(cpu);
+			dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		}
 		dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
 		dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
@@ -3413,11 +3752,11 @@ static void igb_update_tx_dca(struct igb
 		dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
 		if (hw->mac.type == e1000_82576) {
 			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
-			dca_txctrl |= dca_get_tag(cpu) <<
+			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
 			              E1000_DCA_TXCTRL_CPUID_SHIFT;
 		} else {
 			dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
-			dca_txctrl |= dca_get_tag(cpu);
+			dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		}
 		dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
 		wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
@@ -3457,7 +3796,7 @@ static int __igb_notify_dca(struct devic
 			break;
 		/* Always use CB2 mode, difference is masked
 		 * in the CB driver. */
-		wr32(E1000_DCA_CTRL, 2);
+		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");
@@ -3472,7 +3811,7 @@ static int __igb_notify_dca(struct devic
 			dca_remove_requester(dev);
 			dev_info(&adapter->pdev->dev, "DCA disabled\n");
 			adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
-			wr32(E1000_DCA_CTRL, 1);
+			wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
 		}
 		break;
 	}
@@ -3492,6 +3831,322 @@ static int igb_notify_dca(struct notifie
 }
 #endif /* CONFIG_IGB_DCA */
 
+static void igb_ping_all_vfs(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 ping;
+	int i;
+
+	for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
+		ping = E1000_PF_CONTROL_MSG;
+		if (adapter->vf_data[i].clear_to_send)
+			ping |= E1000_VT_MSGTYPE_CTS;
+		igb_write_mbx(hw, &ping, 1, i);
+	}
+}
+
+static int igb_set_vf_multicasts(struct igb_adapter *adapter,
+				  u32 *msgbuf, u32 vf)
+{
+	int n = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+	u16 *hash_list = (u16 *)&msgbuf[1];
+	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
+	 * 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 */
+	for (i = 0; i < n; i++)
+		vf_data->vf_mc_hashes[i] = hash_list[i];;
+
+	/* Flush and reset the mta with the new values */
+	igb_set_multi(adapter->netdev);
+
+	return 0;
+}
+
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct vf_data_storage *vf_data;
+	int i, j;
+
+	for (i = 0; i < adapter->vfs_allocated_count; i++) {
+		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]);
+	}
+}
+
+static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 pool_mask, reg, vid;
+	int i;
+
+	pool_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+	/* Find the vlan filter for this id */
+	for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+		reg = rd32(E1000_VLVF(i));
+
+		/* remove the vf from the pool */
+		reg &= ~pool_mask;
+
+		/* if pool is empty then remove entry from vfta */
+		if (!(reg & E1000_VLVF_POOLSEL_MASK) &&
+		    (reg & E1000_VLVF_VLANID_ENABLE)) {
+			reg = 0;
+			vid = reg & E1000_VLVF_VLANID_MASK;
+			igb_vfta_set(hw, vid, false);
+		}
+
+		wr32(E1000_VLVF(i), reg);
+	}
+}
+
+static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 reg, i;
+
+	/* It is an error to call this function when VFs are not enabled */
+	if (!adapter->vfs_allocated_count)
+		return -1;
+
+	/* Find the vlan filter for this id */
+	for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+		reg = rd32(E1000_VLVF(i));
+		if ((reg & E1000_VLVF_VLANID_ENABLE) &&
+		    vid == (reg & E1000_VLVF_VLANID_MASK))
+			break;
+	}
+
+	if (add) {
+		if (i == E1000_VLVF_ARRAY_SIZE) {
+			/* Did not find a matching VLAN ID entry that was
+			 * enabled.  Search for a free filter entry, i.e.
+			 * one without the enable bit set
+			 */
+			for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+				reg = rd32(E1000_VLVF(i));
+				if (!(reg & E1000_VLVF_VLANID_ENABLE))
+					break;
+			}
+		}
+		if (i < E1000_VLVF_ARRAY_SIZE) {
+			/* Found an enabled/available entry */
+			reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+			/* 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);
+				reg |= E1000_VLVF_VLANID_ENABLE;
+			}
+			reg &= ~E1000_VLVF_VLANID_MASK;
+			reg |= vid;
+
+			wr32(E1000_VLVF(i), reg);
+			return 0;
+		}
+	} else {
+		if (i < E1000_VLVF_ARRAY_SIZE) {
+			/* remove vf from the pool */
+			reg &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT + vf));
+			/* if pool is empty then remove entry from vfta */
+			if (!(reg & E1000_VLVF_POOLSEL_MASK)) {
+				reg = 0;
+				igb_vfta_set(hw, vid, false);
+			}
+			wr32(E1000_VLVF(i), reg);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+	int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+	int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
+
+	return igb_vlvf_set(adapter, vid, add, vf);
+}
+
+static inline void igb_vf_reset_event(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;
+
+	/* reset offloads to defaults */
+	igb_set_vmolr(hw, vf);
+
+	/* reset vlans for device */
+	igb_clear_vf_vfta(adapter, vf);
+
+	/* reset multicast table array for vf */
+	adapter->vf_data[vf].num_vf_mc_hashes = 0;
+
+	/* Flush and reset the mta with the new values */
+	igb_set_multi(adapter->netdev);
+}
+
+static inline 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;
+	u32 reg, msgbuf[3];
+	u8 *addr = (u8 *)(&msgbuf[1]);
+
+	/* process all the same items cleared in a function level reset */
+	igb_vf_reset_event(adapter, vf);
+
+	/* set vf mac address */
+	igb_rar_set(hw, vf_mac, vf + 1);
+	igb_set_rah_pool(hw, vf, vf + 1);
+
+	/* enable transmit and receive for vf */
+	reg = rd32(E1000_VFTE);
+	wr32(E1000_VFTE, reg | (1 << vf));
+	reg = rd32(E1000_VFRE);
+	wr32(E1000_VFRE, reg | (1 << vf));
+
+	/* enable mailbox functionality for vf */
+	adapter->vf_data[vf].clear_to_send = true;
+
+	/* reply to reset with ack and vf mac address */
+	msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
+	memcpy(addr, vf_mac, 6);
+	igb_write_mbx(hw, msgbuf, 3, vf);
+}
+
+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);
+
+		return err;
+
+}
+
+static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	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)
+		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);
+
+	}
+}
+
+static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+	u32 mbx_size = E1000_VFMAILBOX_SIZE;
+	u32 msgbuf[mbx_size];
+	struct e1000_hw *hw = &adapter->hw;
+	s32 retval;
+
+	retval = igb_read_mbx(hw, msgbuf, mbx_size, vf);
+
+	if (retval)
+		dev_err(&adapter->pdev->dev,
+		        "Error receiving message from VF\n");
+
+	/* this is a message we already processed, do nothing */
+	if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
+		return retval;
+
+	/*
+	 * until the vf completes a reset it should not be
+	 * allowed to start any configuration.
+	 */
+
+	if (msgbuf[0] == E1000_VF_RESET) {
+		igb_vf_reset_msg(adapter, vf);
+
+		return retval;
+	}
+
+	if (!adapter->vf_data[vf].clear_to_send) {
+		msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
+		igb_write_mbx(hw, msgbuf, 1, vf);
+		return retval;
+	}
+
+	switch ((msgbuf[0] & 0xFFFF)) {
+	case E1000_VF_SET_MAC_ADDR:
+		retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
+		break;
+	case E1000_VF_SET_MULTICAST:
+		retval = igb_set_vf_multicasts(adapter, msgbuf, vf);
+		break;
+	case E1000_VF_SET_LPE:
+		retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
+		break;
+	case E1000_VF_SET_VLAN:
+		retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+		break;
+	default:
+		dev_err(&adapter->pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
+		retval = -1;
+		break;
+	}
+
+	/* 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;
+}
+
 /**
  * igb_intr_msi - Interrupt Handler
  * @irq: interrupt number
@@ -3507,19 +4162,24 @@ static irqreturn_t igb_intr_msi(int irq,
 
 	igb_write_itr(adapter->rx_ring);
 
+	if(icr & E1000_ICR_DOUTSYNC) {
+		/* HW is reporting DMA is out of sync */
+		adapter->stats.doosync++;
+	}
+
 	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		hw->mac.get_link_status = 1;
 		if (!test_bit(__IGB_DOWN, &adapter->state))
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	netif_rx_schedule(&adapter->rx_ring[0].napi);
+	napi_schedule(&adapter->rx_ring[0].napi);
 
 	return IRQ_HANDLED;
 }
 
 /**
- * igb_intr - Interrupt Handler
+ * igb_intr - Legacy Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a network interface device structure
  **/
@@ -3531,7 +4191,6 @@ static irqreturn_t igb_intr(int irq, voi
 	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
 	 * need for the IMC write */
 	u32 icr = rd32(E1000_ICR);
-	u32 eicr = 0;
 	if (!icr)
 		return IRQ_NONE;  /* Not our interrupt */
 
@@ -3542,7 +4201,10 @@ static irqreturn_t igb_intr(int irq, voi
 	if (!(icr & E1000_ICR_INT_ASSERTED))
 		return IRQ_NONE;
 
-	eicr = rd32(E1000_EICR);
+	if(icr & E1000_ICR_DOUTSYNC) {
+		/* HW is reporting DMA is out of sync */
+		adapter->stats.doosync++;
+	}
 
 	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		hw->mac.get_link_status = 1;
@@ -3551,11 +4213,31 @@ static irqreturn_t igb_intr(int irq, voi
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	netif_rx_schedule(&adapter->rx_ring[0].napi);
+	napi_schedule(&adapter->rx_ring[0].napi);
 
 	return IRQ_HANDLED;
 }
 
+static inline void igb_rx_irq_enable(struct igb_ring *rx_ring)
+{
+	struct igb_adapter *adapter = rx_ring->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (adapter->itr_setting & 3) {
+		if (adapter->num_rx_queues == 1)
+			igb_set_itr(adapter);
+		else
+			igb_update_ring_itr(rx_ring);
+	}
+
+	if (!test_bit(__IGB_DOWN, &adapter->state)) {
+		if (adapter->msix_entries)
+			wr32(E1000_EIMS, rx_ring->eims_value);
+		else
+			igb_irq_enable(adapter);
+	}
+}
+
 /**
  * igb_poll - NAPI Rx polling callback
  * @napi: napi polling structure
@@ -3564,70 +4246,64 @@ static irqreturn_t igb_intr(int irq, voi
 static int igb_poll(struct napi_struct *napi, int budget)
 {
 	struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
-	struct igb_adapter *adapter = rx_ring->adapter;
-	struct net_device *netdev = adapter->netdev;
-	int tx_clean_complete, work_done = 0;
+	int work_done = 0;
 
-	/* this poll routine only supports one tx and one rx queue */
 #ifdef CONFIG_IGB_DCA
-	if (adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_tx_dca(&adapter->tx_ring[0]);
+	if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+		igb_update_rx_dca(rx_ring);
 #endif
-	tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
+	igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
 
+	if (rx_ring->buddy) {
 #ifdef CONFIG_IGB_DCA
-	if (adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_rx_dca(&adapter->rx_ring[0]);
+		if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+			igb_update_tx_dca(rx_ring->buddy);
 #endif
-	igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
+		if (!igb_clean_tx_irq(rx_ring->buddy))
+			work_done = budget;
+	}
 
-	/* If no Tx and not enough Rx work done, exit the polling mode */
-	if ((tx_clean_complete && (work_done < budget)) ||
-	    !netif_running(netdev)) {
-		if (adapter->itr_setting & 3)
-			igb_set_itr(adapter);
-		netif_rx_complete(napi);
-		if (!test_bit(__IGB_DOWN, &adapter->state))
-			igb_irq_enable(adapter);
-		return 0;
+	/* If not enough Rx work done, exit the polling mode */
+	if (work_done < budget) {
+		napi_complete(napi);
+		igb_rx_irq_enable(rx_ring);
 	}
 
-	return 1;
+	return work_done;
 }
 
-static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
+/**
+ * igb_hwtstamp - utility function which checks for TX time stamp
+ * @adapter: board private structure
+ * @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)
 {
-	struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
-	struct igb_adapter *adapter = rx_ring->adapter;
+	union skb_shared_tx *shtx = skb_tx(skb);
 	struct e1000_hw *hw = &adapter->hw;
-	struct net_device *netdev = adapter->netdev;
-	int work_done = 0;
-
-#ifdef CONFIG_IGB_DCA
-	if (adapter->flags & IGB_FLAG_DCA_ENABLED)
-		igb_update_rx_dca(rx_ring);
-#endif
-	igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
 
+	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 not enough Rx work done, exit the polling mode */
-	if ((work_done == 0) || !netif_running(netdev)) {
-		netif_rx_complete(napi);
-
-		if (adapter->itr_setting & 3) {
-			if (adapter->num_rx_queues == 1)
-				igb_set_itr(adapter);
-			else
-				igb_update_ring_itr(rx_ring);
+			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);
 		}
-
-		if (!test_bit(__IGB_DOWN, &adapter->state))
-			wr32(E1000_EIMS, rx_ring->eims_value);
-
-		return 0;
 	}
-
-	return 1;
 }
 
 /**
@@ -3668,6 +4344,8 @@ static bool igb_clean_tx_irq(struct igb_
 					    skb->len;
 				total_packets += segs;
 				total_bytes += bytecount;
+
+				igb_tx_hwtstamp(adapter, skb);
 			}
 
 			igb_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -3677,7 +4355,6 @@ static bool igb_clean_tx_irq(struct igb_
 			if (i == tx_ring->count)
 				i = 0;
 		}
-
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
 	}
@@ -3686,7 +4363,7 @@ static bool igb_clean_tx_irq(struct igb_
 
 	if (unlikely(count &&
 		     netif_carrier_ok(netdev) &&
-		     IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
+		     igb_desc_unused(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
 		/* Make sure that anybody stopping the queue after this
 		 * sees the new next_to_clean.
 		 */
@@ -3742,44 +4419,11 @@ static bool igb_clean_tx_irq(struct igb_
 	return (count < tx_ring->count);
 }
 
-#ifdef CONFIG_IGB_LRO
- /**
- * igb_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: pointer to the receive descriptor for the current sk_buff
- **/
-static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
-                           u64 *hdr_flags, void *priv)
-{
-	union e1000_adv_rx_desc *rx_desc = priv;
-	u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
-	               (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
-
-	/* Verify that this is a valid IPv4 TCP packet */
-	if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
-	                  E1000_RXDADV_PKTTYPE_TCP))
-		return -1;
-
-	/* Set network headers */
-	skb_reset_network_header(skb);
-	skb_set_transport_header(skb, ip_hdrlen(skb));
-	*iphdr = ip_hdr(skb);
-	*tcph = tcp_hdr(skb);
-	*hdr_flags = LRO_IPV4 | LRO_TCP;
-
-	return 0;
-
-}
-#endif /* CONFIG_IGB_LRO */
-
 /**
  * igb_receive_skb - helper function to handle rx indications
- * @ring: pointer to receive ring receving this packet 
+ * @ring: pointer to receive ring receving this packet
  * @status: descriptor status field as written by hardware
- * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @rx_desc: receive descriptor containing vlan and type information.
  * @skb: pointer to sk_buff to be indicated to stack
  **/
 static void igb_receive_skb(struct igb_ring *ring, u8 status,
@@ -3789,31 +4433,23 @@ static void igb_receive_skb(struct igb_r
 	struct igb_adapter * adapter = ring->adapter;
 	bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
 
-#ifdef CONFIG_IGB_LRO
-	if (adapter->netdev->features & NETIF_F_LRO &&
-	    skb->ip_summed == CHECKSUM_UNNECESSARY) {
+	skb_record_rx_queue(skb, ring->queue_index);
+	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		if (vlan_extracted)
-			lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
-			                   adapter->vlgrp,
-			                   le16_to_cpu(rx_desc->wb.upper.vlan),
-			                   rx_desc);
+			vlan_gro_receive(&ring->napi, adapter->vlgrp,
+			                 le16_to_cpu(rx_desc->wb.upper.vlan),
+			                 skb);
 		else
-			lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
-		ring->lro_used = 1;
+			napi_gro_receive(&ring->napi, skb);
 	} else {
-#endif
 		if (vlan_extracted)
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
 			                  le16_to_cpu(rx_desc->wb.upper.vlan));
 		else
-
 			netif_receive_skb(skb);
-#ifdef CONFIG_IGB_LRO
 	}
-#endif
 }
 
-
 static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
 				       u32 status_err, struct sk_buff *skb)
 {
@@ -3841,17 +4477,19 @@ static bool igb_clean_rx_irq_adv(struct
 {
 	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;
 	union e1000_adv_rx_desc *rx_desc , *next_rxd;
 	struct igb_buffer *buffer_info , *next_buffer;
 	struct sk_buff *skb;
-	unsigned int i;
-	u32 length, hlen, staterr;
 	bool cleaned = false;
 	int cleaned_count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int i;
+	u32 length, hlen, staterr;
 
 	i = rx_ring->next_to_clean;
+	buffer_info = &rx_ring->buffer_info[i];
 	rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
 	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 
@@ -3859,25 +4497,22 @@ static bool igb_clean_rx_irq_adv(struct
 		if (*work_done >= budget)
 			break;
 		(*work_done)++;
-		buffer_info = &rx_ring->buffer_info[i];
 
-		/* HW will not DMA in data larger than the given buffer, even
-		 * if it parses the (NFS, of course) header to be larger.  In
-		 * that case, it fills the header buffer and spills the rest
-		 * into the page.
-		 */
-		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;
+		skb = buffer_info->skb;
+		prefetch(skb->data - NET_IP_ALIGN);
+		buffer_info->skb = NULL;
+
+		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];
 
 		length = le16_to_cpu(rx_desc->wb.upper.length);
 		cleaned = true;
 		cleaned_count++;
 
-		skb = buffer_info->skb;
-		prefetch(skb->data - NET_IP_ALIGN);
-		buffer_info->skb = NULL;
 		if (!adapter->rx_ps_hdr_size) {
 			pci_unmap_single(pdev, buffer_info->dma,
 					 adapter->rx_buffer_len +
@@ -3887,10 +4522,19 @@ static bool igb_clean_rx_irq_adv(struct
 			goto send_up;
 		}
 
+		/* HW will not DMA in data larger than the given buffer, even
+		 * if it parses the (NFS, of course) header to be larger.  In
+		 * that case, it fills the header buffer and spills the rest
+		 * into the page.
+		 */
+		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 (!skb_shinfo(skb)->nr_frags) {
 			pci_unmap_single(pdev, buffer_info->dma,
-					 adapter->rx_ps_hdr_size +
-					   NET_IP_ALIGN,
+					 adapter->rx_ps_hdr_size + NET_IP_ALIGN,
 					 PCI_DMA_FROMDEVICE);
 			skb_put(skb, hlen);
 		}
@@ -3916,13 +4560,6 @@ static bool igb_clean_rx_irq_adv(struct
 
 			skb->truesize += length;
 		}
-send_up:
-		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];
 
 		if (!(staterr & E1000_RXD_STAT_EOP)) {
 			buffer_info->skb = next_buffer->skb;
@@ -3931,6 +4568,47 @@ send_up:
 			next_buffer->dma = 0;
 			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);
@@ -3958,19 +4636,11 @@ next_desc:
 		/* use prefetched values */
 		rx_desc = next_rxd;
 		buffer_info = next_buffer;
-
 		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 	}
 
 	rx_ring->next_to_clean = i;
-	cleaned_count = IGB_DESC_UNUSED(rx_ring);
-
-#ifdef CONFIG_IGB_LRO
-	if (rx_ring->lro_used) {
-		lro_flush_all(&rx_ring->lro_mgr);
-		rx_ring->lro_used = 0;
-	}
-#endif
+	cleaned_count = igb_desc_unused(rx_ring);
 
 	if (cleaned_count)
 		igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
@@ -3984,7 +4654,6 @@ next_desc:
 	return cleaned;
 }
 
-
 /**
  * igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
  * @adapter: address of board private structure
@@ -3999,10 +4668,17 @@ static void igb_alloc_rx_buffers_adv(str
 	struct igb_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
+	int bufsz;
 
 	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 += NET_IP_ALIGN;
+
 	while (cleaned_count--) {
 		rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
 
@@ -4018,23 +4694,14 @@ 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(pdev, buffer_info->page,
 					     buffer_info->page_offset,
 					     PAGE_SIZE / 2,
 					     PCI_DMA_FROMDEVICE);
 		}
 
 		if (!buffer_info->skb) {
-			int bufsz;
-
-			if (adapter->rx_ps_hdr_size)
-				bufsz = adapter->rx_ps_hdr_size;
-			else
-				bufsz = adapter->rx_buffer_len;
-			bufsz += NET_IP_ALIGN;
 			skb = netdev_alloc_skb(netdev, bufsz);
-
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
 				goto no_buffers;
@@ -4050,7 +4717,6 @@ static void igb_alloc_rx_buffers_adv(str
 			buffer_info->dma = pci_map_single(pdev, skb->data,
 							  bufsz,
 							  PCI_DMA_FROMDEVICE);
-
 		}
 		/* Refresh the desc even if buffer_addrs didn't change because
 		 * each write-back erases this info. */
@@ -4120,6 +4786,163 @@ static int igb_mii_ioctl(struct net_devi
 }
 
 /**
+ * igb_hwtstamp_ioctl - control hardware time stamping
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ *
+ * Outgoing time stamping can be enabled and disabled. Play nice and
+ * disable it when requested, although it shouldn't case any overhead
+ * when no packet needs it. At most one packet in the queue may be
+ * marked for time stamping, otherwise it would be impossible to tell
+ * for sure to which packet the hardware time stamp belongs.
+ *
+ * Incoming time stamping has to be configured via the hardware
+ * filters. Not all combinations are supported, in particular event
+ * type has to be specified. Matching the kind of event packet is
+ * not supported, with the exception of "all V2 events regardless of
+ * level 2 or 4".
+ *
+ **/
+static int igb_hwtstamp_ioctl(struct net_device *netdev,
+			      struct ifreq *ifr, int cmd)
+{
+	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_rx_cfg = 0;
+	int is_l4 = 0;
+	int is_l2 = 0;
+	short port = 319; /* PTP */
+	u32 regval;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	/* reserved for future extensions */
+	if (config.flags)
+		return -EINVAL;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		tsync_tx_ctl_bit = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		tsync_rx_ctl_bit = 0;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_ALL:
+		/*
+		 * register TSYNCRXCFG must be set, therefore it is not
+		 * 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;
+		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_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
+		is_l4 = 1;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+		tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
+		is_l4 = 1;
+		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_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
+		is_l2 = 1;
+		is_l4 = 1;
+		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_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
+		is_l2 = 1;
+		is_l4 = 1;
+		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;
+		config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+		is_l2 = 1;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	/* enable/disable TX */
+	regval = rd32(E1000_TSYNCTXCTL);
+	regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
+	wr32(E1000_TSYNCTXCTL, regval);
+
+	/* enable/disable RX, define which PTP packets are time stamped */
+	regval = rd32(E1000_TSYNCRXCTL);
+	regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
+	regval = (regval & ~0xE) | tsync_rx_ctl_type;
+	wr32(E1000_TSYNCRXCTL, regval);
+	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);
+
+	/* 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 */));
+
+	wrfl();
+
+	adapter->hwtstamp_config = config;
+
+	/* clear TX/RX time stamp registers, just to be sure */
+	regval = rd32(E1000_TXSTMPH);
+	regval = rd32(E1000_RXSTMPH);
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+		-EFAULT : 0;
+}
+
+/**
  * igb_ioctl -
  * @netdev:
  * @ifreq:
@@ -4132,6 +4955,8 @@ static int igb_ioctl(struct net_device *
 	case SIOCGMIIREG:
 	case SIOCSMIIREG:
 		return igb_mii_ioctl(netdev, ifr, cmd);
+	case SIOCSHWTSTAMP:
+		return igb_hwtstamp_ioctl(netdev, ifr, cmd);
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -4158,8 +4983,6 @@ static void igb_vlan_rx_register(struct
 		rctl &= ~E1000_RCTL_CFIEN;
 		wr32(E1000_RCTL, rctl);
 		igb_update_mng_vlan(adapter);
-		wr32(E1000_RLPML,
-				adapter->max_frame_size + VLAN_TAG_SIZE);
 	} else {
 		/* disable VLAN tag insert/strip */
 		ctrl = rd32(E1000_CTRL);
@@ -4170,10 +4993,10 @@ static void igb_vlan_rx_register(struct
 			igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 			adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
 		}
-		wr32(E1000_RLPML,
-				adapter->max_frame_size);
 	}
 
+	igb_rlpml_set(adapter);
+
 	if (!test_bit(__IGB_DOWN, &adapter->state))
 		igb_irq_enable(adapter);
 }
@@ -4182,24 +5005,25 @@ static void igb_vlan_rx_add_vid(struct n
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	u32 vfta, index;
+	int pf_id = adapter->vfs_allocated_count;
 
-	if ((adapter->hw.mng_cookie.status &
+	if ((hw->mng_cookie.status &
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	    (vid == adapter->mng_vlan_id))
 		return;
-	/* add VID to filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = array_rd32(E1000_VFTA, index);
-	vfta |= (1 << (vid & 0x1F));
-	igb_write_vfta(&adapter->hw, index, vfta);
+
+	/* 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);
+
 }
 
 static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	u32 vfta, index;
+	int pf_id = adapter->vfs_allocated_count;
 
 	igb_irq_disable(adapter);
 	vlan_group_set_device(adapter->vlgrp, vid, NULL);
@@ -4215,11 +5039,10 @@ static void igb_vlan_rx_kill_vid(struct
 		return;
 	}
 
-	/* remove VID from filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = array_rd32(E1000_VFTA, index);
-	vfta &= ~(1 << (vid & 0x1F));
-	igb_write_vfta(&adapter->hw, index, vfta);
+	/* 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))
+		igb_vfta_set(hw, vid, false);
 }
 
 static void igb_restore_vlan(struct igb_adapter *adapter)
@@ -4276,8 +5099,7 @@ int igb_set_spd_dplx(struct igb_adapter
 	return 0;
 }
 
-
-static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct igb_adapter *adapter = netdev_priv(netdev);
@@ -4336,15 +5158,9 @@ static int igb_suspend(struct pci_dev *p
 		wr32(E1000_WUFC, 0);
 	}
 
-	/* make sure adapter isn't asleep if manageability/wol is enabled */
-	if (wufc || adapter->en_mng_pt) {
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);
-	} else {
+	*enable_wake = wufc || adapter->en_mng_pt;
+	if (!*enable_wake)
 		igb_shutdown_fiber_serdes_link_82575(hw);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);
-	}
 
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant. */
@@ -4352,12 +5168,29 @@ static int igb_suspend(struct pci_dev *p
 
 	pci_disable_device(pdev);
 
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
 	return 0;
 }
 
 #ifdef CONFIG_PM
+static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __igb_shutdown(pdev, &wake);
+	if (retval)
+		return retval;
+
+	if (wake) {
+		pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
+	return 0;
+}
+
 static int igb_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4368,10 +5201,7 @@ static int igb_resume(struct pci_dev *pd
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	if (adapter->need_ioport)
-		err = pci_enable_device(pdev);
-	else
-		err = pci_enable_device_mem(pdev);
+	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
 			"igb: Cannot enable PCI device from suspend\n");
@@ -4392,6 +5222,11 @@ static int igb_resume(struct pci_dev *pd
 	/* e1000_power_up_phy(adapter); */
 
 	igb_reset(adapter);
+
+	/* let the f/w know that the h/w is now under the control of the
+	 * driver. */
+	igb_get_hw_control(adapter);
+
 	wr32(E1000_WUS, ~0);
 
 	if (netif_running(netdev)) {
@@ -4402,17 +5237,20 @@ static int igb_resume(struct pci_dev *pd
 
 	netif_device_attach(netdev);
 
-	/* let the f/w know that the h/w is now under the control of the
-	 * driver. */
-	igb_get_hw_control(adapter);
-
 	return 0;
 }
 #endif
 
 static void igb_shutdown(struct pci_dev *pdev)
 {
-	igb_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+
+	__igb_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, wake);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4424,22 +5262,27 @@ static void igb_shutdown(struct pci_dev
 static void igb_netpoll(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
 	int i;
-	int work_done = 0;
-
-	igb_irq_disable(adapter);
-	adapter->flags |= IGB_FLAG_IN_NETPOLL;
 
-	for (i = 0; i < adapter->num_tx_queues; i++)
-		igb_clean_tx_irq(&adapter->tx_ring[i]);
+	if (!adapter->msix_entries) {
+		igb_irq_disable(adapter);
+		napi_schedule(&adapter->rx_ring[0].napi);
+		return;
+	}
 
-	for (i = 0; i < adapter->num_rx_queues; i++)
-		igb_clean_rx_irq_adv(&adapter->rx_ring[i],
-				     &work_done,
-				     adapter->rx_ring[i].napi.weight);
+	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);
+	}
 
-	adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
-	igb_irq_enable(adapter);
+	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);
+	}
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
@@ -4482,12 +5325,7 @@ static pci_ers_result_t igb_io_slot_rese
 	pci_ers_result_t result;
 	int err;
 
-	if (adapter->need_ioport)
-		err = pci_enable_device(pdev);
-	else
-		err = pci_enable_device_mem(pdev);
-
-	if (err) {
+	if (pci_enable_device_mem(pdev)) {
 		dev_err(&pdev->dev,
 			"Cannot re-enable PCI device after reset.\n");
 		result = PCI_ERS_RESULT_DISCONNECT;
@@ -4540,4 +5378,87 @@ static void igb_io_resume(struct pci_dev
 	igb_get_hw_control(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;
+
+	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);
+}
+
+static void igb_set_mc_list_pools(struct igb_adapter *adapter,
+				  int entry_count, u16 total_rar_filters)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	int i = adapter->vfs_allocated_count + 1;
+
+	if ((i + entry_count) < total_rar_filters)
+		total_rar_filters = i + entry_count;
+
+	for (; i < total_rar_filters; i++)
+		igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
+}
+
+static int igb_set_vf_mac(struct igb_adapter *adapter,
+                          int vf, unsigned char *mac_addr)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	int rar_entry = vf + 1; /* VF MAC addresses start at entry 1 */
+
+	igb_rar_set(hw, mac_addr, rar_entry);
+
+	memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
+
+	igb_set_rah_pool(hw, vf, rar_entry);
+
+	return 0;
+}
+
+static void igb_vmm_control(struct igb_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 reg_data;
+
+	if (!adapter->vfs_allocated_count)
+		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);
+
+	igb_vmdq_set_loopback_pf(hw, true);
+	igb_vmdq_set_replication_pf(hw, true);
+}
+
 /* igb_main.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igb/Makefile linux-libre-2.6.30-gnu1/drivers/net/igb/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/igb/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/igb/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 82575 PCI-Express Ethernet Linux driver
-# Copyright(c) 1999 - 2007 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,
@@ -33,5 +33,5 @@
 obj-$(CONFIG_IGB) += igb.o
 
 igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
-	    e1000_mac.o e1000_nvm.o e1000_phy.o
+	    e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/defines.h linux-libre-2.6.30-gnu1/drivers/net/igbvf/defines.h
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/defines.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/defines.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_DEFINES_H_
+#define _E1000_DEFINES_H_
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* IVAR valid bit */
+#define E1000_IVAR_VALID        0x80
+
+/* Receive Descriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
+#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
+#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+
+#define E1000_RXDEXT_STATERR_CE    0x01000000
+#define E1000_RXDEXT_STATERR_SE    0x02000000
+#define E1000_RXDEXT_STATERR_SEQ   0x04000000
+#define E1000_RXDEXT_STATERR_CXE   0x10000000
+#define E1000_RXDEXT_STATERR_TCPE  0x20000000
+#define E1000_RXDEXT_STATERR_IPE   0x40000000
+#define E1000_RXDEXT_STATERR_RXE   0x80000000
+
+
+/* Same mask, but for extended and packet split descriptors */
+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
+    E1000_RXDEXT_STATERR_CE  |            \
+    E1000_RXDEXT_STATERR_SE  |            \
+    E1000_RXDEXT_STATERR_SEQ |            \
+    E1000_RXDEXT_STATERR_CXE |            \
+    E1000_RXDEXT_STATERR_RXE)
+
+/* Device Control */
+#define E1000_CTRL_RST      0x04000000  /* Global reset */
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
+#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
+
+#define MAX_JUMBO_FRAME_SIZE    0x3F00
+
+/* 802.1q VLAN Packet Size */
+#define VLAN_TAG_SIZE              4    /* 802.3ac tag (not DMA'd) */
+
+/* Error Codes */
+#define E1000_SUCCESS      0
+#define E1000_ERR_CONFIG   3
+#define E1000_ERR_MAC_INIT 5
+#define E1000_ERR_MBX      15
+
+#ifndef ETH_ADDR_LEN
+#define ETH_ADDR_LEN                 6
+#endif
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK                  0x00000F00
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000
+#define E1000_SRRCTL_DESCTYPE_MASK                      0x0E000000
+#define E1000_SRRCTL_DROP_EN                            0x80000000
+
+#define E1000_SRRCTL_BSIZEPKT_MASK      0x0000007F
+#define E1000_SRRCTL_BSIZEHDR_MASK      0x00003F00
+
+/* Additional Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */
+#define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */
+
+/* Direct Cache Access (DCA) definitions */
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+
+#define E1000_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
+
+#endif /* _E1000_DEFINES_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/ethtool.c linux-libre-2.6.30-gnu1/drivers/net/igbvf/ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/ethtool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,540 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* ethtool support for igbvf */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include "igbvf.h"
+#include <linux/if_vlan.h>
+
+
+struct igbvf_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+	int base_stat_offset;
+};
+
+#define IGBVF_STAT(current, base) \
+		sizeof(((struct igbvf_adapter *)0)->current), \
+		offsetof(struct igbvf_adapter, current), \
+		offsetof(struct igbvf_adapter, base)
+
+static const struct igbvf_stats igbvf_gstrings_stats[] = {
+	{ "rx_packets", IGBVF_STAT(stats.gprc, stats.base_gprc) },
+	{ "tx_packets", IGBVF_STAT(stats.gptc, stats.base_gptc) },
+	{ "rx_bytes", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+	{ "tx_bytes", IGBVF_STAT(stats.gotc, stats.base_gotc) },
+	{ "multicast", IGBVF_STAT(stats.mprc, stats.base_mprc) },
+	{ "lbrx_bytes", IGBVF_STAT(stats.gorlbc, stats.base_gorlbc) },
+	{ "lbrx_packets", IGBVF_STAT(stats.gprlbc, stats.base_gprlbc) },
+	{ "tx_restart_queue", IGBVF_STAT(restart_queue, zero_base) },
+	{ "rx_long_byte_count", IGBVF_STAT(stats.gorc, stats.base_gorc) },
+	{ "rx_csum_offload_good", IGBVF_STAT(hw_csum_good, zero_base) },
+	{ "rx_csum_offload_errors", IGBVF_STAT(hw_csum_err, zero_base) },
+	{ "rx_header_split", IGBVF_STAT(rx_hdr_split, zero_base) },
+	{ "alloc_rx_buff_failed", IGBVF_STAT(alloc_rx_buff_failed, zero_base) },
+};
+
+#define IGBVF_GLOBAL_STATS_LEN ARRAY_SIZE(igbvf_gstrings_stats)
+
+static const char igbvf_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Link test   (on/offline)"
+};
+
+#define IGBVF_TEST_LEN ARRAY_SIZE(igbvf_gstrings_test)
+
+static int igbvf_get_settings(struct net_device *netdev,
+                              struct ethtool_cmd *ecmd)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 status;
+
+	ecmd->supported   = SUPPORTED_1000baseT_Full;
+
+	ecmd->advertising = ADVERTISED_1000baseT_Full;
+
+	ecmd->port = -1;
+	ecmd->transceiver = XCVR_DUMMY1;
+
+	status = er32(STATUS);
+	if (status & E1000_STATUS_LU) {
+		if (status & E1000_STATUS_SPEED_1000)
+			ecmd->speed = 1000;
+		else if (status & E1000_STATUS_SPEED_100)
+			ecmd->speed = 100;
+		else
+			ecmd->speed = 10;
+
+		if (status & E1000_STATUS_FD)
+			ecmd->duplex = DUPLEX_FULL;
+		else
+			ecmd->duplex = DUPLEX_HALF;
+	} else {
+		ecmd->speed = -1;
+		ecmd->duplex = -1;
+	}
+
+	ecmd->autoneg = AUTONEG_DISABLE;
+
+	return 0;
+}
+
+static u32 igbvf_get_link(struct net_device *netdev)
+{
+	return netif_carrier_ok(netdev);
+}
+
+static int igbvf_set_settings(struct net_device *netdev,
+                              struct ethtool_cmd *ecmd)
+{
+	return -EOPNOTSUPP;
+}
+
+static void igbvf_get_pauseparam(struct net_device *netdev,
+                                 struct ethtool_pauseparam *pause)
+{
+	return;
+}
+
+static int igbvf_set_pauseparam(struct net_device *netdev,
+                                struct ethtool_pauseparam *pause)
+{
+	return -EOPNOTSUPP;
+}
+
+static u32 igbvf_get_tx_csum(struct net_device *netdev)
+{
+	return ((netdev->features & NETIF_F_IP_CSUM) != 0);
+}
+
+static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
+{
+	if (data)
+		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+	else
+		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+	return 0;
+}
+
+static int igbvf_set_tso(struct net_device *netdev, u32 data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int i;
+	struct net_device *v_netdev;
+
+	if (data) {
+		netdev->features |= NETIF_F_TSO;
+		netdev->features |= NETIF_F_TSO6;
+	} else {
+		netdev->features &= ~NETIF_F_TSO;
+		netdev->features &= ~NETIF_F_TSO6;
+		/* disable TSO on all VLANs if they're present */
+		if (!adapter->vlgrp)
+			goto tso_out;
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			v_netdev = vlan_group_get_device(adapter->vlgrp, i);
+			if (!v_netdev)
+				continue;
+
+			v_netdev->features &= ~NETIF_F_TSO;
+			v_netdev->features &= ~NETIF_F_TSO6;
+			vlan_group_set_device(adapter->vlgrp, i, v_netdev);
+		}
+	}
+
+tso_out:
+	dev_info(&adapter->pdev->dev, "TSO is %s\n",
+	         data ? "Enabled" : "Disabled");
+	adapter->flags |= FLAG_TSO_FORCE;
+	return 0;
+}
+
+static u32 igbvf_get_msglevel(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	return adapter->msg_enable;
+}
+
+static void igbvf_set_msglevel(struct net_device *netdev, u32 data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	adapter->msg_enable = data;
+}
+
+static int igbvf_get_regs_len(struct net_device *netdev)
+{
+#define IGBVF_REGS_LEN 8
+	return IGBVF_REGS_LEN * sizeof(u32);
+}
+
+static void igbvf_get_regs(struct net_device *netdev,
+                           struct ethtool_regs *regs, void *p)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 *regs_buff = p;
+	u8 revision_id;
+
+	memset(p, 0, IGBVF_REGS_LEN * sizeof(u32));
+
+	pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id);
+
+	regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device;
+
+	regs_buff[0] = er32(CTRL);
+	regs_buff[1] = er32(STATUS);
+
+	regs_buff[2] = er32(RDLEN(0));
+	regs_buff[3] = er32(RDH(0));
+	regs_buff[4] = er32(RDT(0));
+
+	regs_buff[5] = er32(TDLEN(0));
+	regs_buff[6] = er32(TDH(0));
+	regs_buff[7] = er32(TDT(0));
+}
+
+static int igbvf_get_eeprom_len(struct net_device *netdev)
+{
+	return 0;
+}
+
+static int igbvf_get_eeprom(struct net_device *netdev,
+                            struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	return -EOPNOTSUPP;
+}
+
+static int igbvf_set_eeprom(struct net_device *netdev,
+                            struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	return -EOPNOTSUPP;
+}
+
+static void igbvf_get_drvinfo(struct net_device *netdev,
+                              struct ethtool_drvinfo *drvinfo)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	char firmware_version[32] = "N/A";
+
+	strncpy(drvinfo->driver,  igbvf_driver_name, 32);
+	strncpy(drvinfo->version, igbvf_driver_version, 32);
+	strncpy(drvinfo->fw_version, firmware_version, 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->regdump_len = igbvf_get_regs_len(netdev);
+	drvinfo->eedump_len = igbvf_get_eeprom_len(netdev);
+}
+
+static void igbvf_get_ringparam(struct net_device *netdev,
+                                struct ethtool_ringparam *ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+
+	ring->rx_max_pending = IGBVF_MAX_RXD;
+	ring->tx_max_pending = IGBVF_MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rx_ring->count;
+	ring->tx_pending = tx_ring->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static int igbvf_set_ringparam(struct net_device *netdev,
+                               struct ethtool_ringparam *ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *temp_ring;
+	int err;
+	u32 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)IGBVF_MIN_RXD);
+	new_rx_count = min(new_rx_count, (u32)IGBVF_MAX_RXD);
+	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
+
+	new_tx_count = max(ring->tx_pending, (u32)IGBVF_MIN_TXD);
+	new_tx_count = min(new_tx_count, (u32)IGBVF_MAX_TXD);
+	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
+
+	if ((new_tx_count == adapter->tx_ring->count) &&
+	    (new_rx_count == adapter->rx_ring->count)) {
+		/* nothing to do */
+		return 0;
+	}
+
+	temp_ring = vmalloc(sizeof(struct igbvf_ring));
+	if (!temp_ring)
+		return -ENOMEM;
+
+	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+		msleep(1);
+
+	if (netif_running(adapter->netdev))
+		igbvf_down(adapter);
+
+	/*
+	 * We can't just free everything and then setup again,
+	 * because the ISRs in MSI-X mode get passed pointers
+	 * to the tx and rx ring structs.
+	 */
+	if (new_tx_count != adapter->tx_ring->count) {
+		memcpy(temp_ring, adapter->tx_ring, sizeof(struct igbvf_ring));
+
+		temp_ring->count = new_tx_count;
+		err = igbvf_setup_tx_resources(adapter, temp_ring);
+		if (err)
+			goto err_setup;
+
+		igbvf_free_tx_resources(adapter->tx_ring);
+
+		memcpy(adapter->tx_ring, temp_ring, sizeof(struct igbvf_ring));
+	}
+
+	if (new_rx_count != adapter->rx_ring->count) {
+		memcpy(temp_ring, adapter->rx_ring, sizeof(struct igbvf_ring));
+
+		temp_ring->count = new_rx_count;
+		err = igbvf_setup_rx_resources(adapter, temp_ring);
+		if (err)
+			goto err_setup;
+
+		igbvf_free_rx_resources(adapter->rx_ring);
+
+		memcpy(adapter->rx_ring, temp_ring,sizeof(struct igbvf_ring));
+	}
+
+	err = 0;
+err_setup:
+	if (netif_running(adapter->netdev))
+		igbvf_up(adapter);
+
+	clear_bit(__IGBVF_RESETTING, &adapter->state);
+	vfree(temp_ring);
+	return err;
+}
+
+static int igbvf_link_test(struct igbvf_adapter *adapter, u64 *data)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	*data = 0;
+
+	hw->mac.ops.check_for_link(hw);
+
+	if (!(er32(STATUS) & E1000_STATUS_LU))
+		*data = 1;
+
+	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)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	set_bit(__IGBVF_TESTING, &adapter->state);
+
+	/*
+	 * Link test performed before hardware reset so autoneg doesn't
+	 * interfere with test result
+	 */
+	if (igbvf_link_test(adapter, &data[0]))
+		eth_test->flags |= ETH_TEST_FL_FAILED;
+
+	clear_bit(__IGBVF_TESTING, &adapter->state);
+	msleep_interruptible(4 * 1000);
+}
+
+static void igbvf_get_wol(struct net_device *netdev,
+                          struct ethtool_wolinfo *wol)
+{
+	wol->supported = 0;
+	wol->wolopts = 0;
+
+	return;
+}
+
+static int igbvf_set_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
+{
+	return -EOPNOTSUPP;
+}
+
+static int igbvf_phys_id(struct net_device *netdev, u32 data)
+{
+	return 0;
+}
+
+static int igbvf_get_coalesce(struct net_device *netdev,
+                              struct ethtool_coalesce *ec)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->itr_setting <= 3)
+		ec->rx_coalesce_usecs = adapter->itr_setting;
+	else
+		ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
+
+	return 0;
+}
+
+static int igbvf_set_coalesce(struct net_device *netdev,
+                              struct ethtool_coalesce *ec)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) ||
+	    ((ec->rx_coalesce_usecs > 3) &&
+	     (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) ||
+	    (ec->rx_coalesce_usecs == 2))
+		return -EINVAL;
+
+	/* convert to rate of irq's per second */
+	if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
+		adapter->itr = IGBVF_START_ITR;
+		adapter->itr_setting = ec->rx_coalesce_usecs;
+	} else {
+		adapter->itr = ec->rx_coalesce_usecs << 2;
+		adapter->itr_setting = adapter->itr;
+	}
+
+	writel(adapter->itr,
+	       hw->hw_addr + adapter->rx_ring[0].itr_register);
+
+	return 0;
+}
+
+static int igbvf_nway_reset(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	if (netif_running(netdev))
+		igbvf_reinit_locked(adapter);
+	return 0;
+}
+
+
+static void igbvf_get_ethtool_stats(struct net_device *netdev,
+                                    struct ethtool_stats *stats,
+                                    u64 *data)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	igbvf_update_stats(adapter);
+	for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+		char *p = (char *)adapter +
+		          igbvf_gstrings_stats[i].stat_offset;
+		char *b = (char *)adapter +
+		          igbvf_gstrings_stats[i].base_stat_offset;
+		data[i] = ((igbvf_gstrings_stats[i].sizeof_stat ==
+		            sizeof(u64)) ? (*(u64 *)p - *(u64 *)b) :
+		            (*(u32 *)p - *(u32 *)b));
+	}
+
+}
+
+static void igbvf_get_strings(struct net_device *netdev, u32 stringset,
+                              u8 *data)
+{
+	u8 *p = data;
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_TEST:
+		memcpy(data, *igbvf_gstrings_test, sizeof(igbvf_gstrings_test));
+		break;
+	case ETH_SS_STATS:
+		for (i = 0; i < IGBVF_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, igbvf_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+static const struct ethtool_ops igbvf_ethtool_ops = {
+	.get_settings		= igbvf_get_settings,
+	.set_settings		= igbvf_set_settings,
+	.get_drvinfo		= igbvf_get_drvinfo,
+	.get_regs_len		= igbvf_get_regs_len,
+	.get_regs		= igbvf_get_regs,
+	.get_wol		= igbvf_get_wol,
+	.set_wol		= igbvf_set_wol,
+	.get_msglevel		= igbvf_get_msglevel,
+	.set_msglevel		= igbvf_set_msglevel,
+	.nway_reset		= igbvf_nway_reset,
+	.get_link		= igbvf_get_link,
+	.get_eeprom_len		= igbvf_get_eeprom_len,
+	.get_eeprom		= igbvf_get_eeprom,
+	.set_eeprom		= igbvf_set_eeprom,
+	.get_ringparam		= igbvf_get_ringparam,
+	.set_ringparam		= igbvf_set_ringparam,
+	.get_pauseparam		= igbvf_get_pauseparam,
+	.set_pauseparam		= igbvf_set_pauseparam,
+	.get_tx_csum		= igbvf_get_tx_csum,
+	.set_tx_csum		= igbvf_set_tx_csum,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
+	.get_tso		= ethtool_op_get_tso,
+	.set_tso		= igbvf_set_tso,
+	.self_test		= igbvf_diag_test,
+	.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,
+};
+
+void igbvf_set_ethtool_ops(struct net_device *netdev)
+{
+	/* have to "undeclare" const on this struct to remove warnings */
+	SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&igbvf_ethtool_ops);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/igbvf.h linux-libre-2.6.30-gnu1/drivers/net/igbvf/igbvf.h
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/igbvf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/igbvf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,332 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* Linux PRO/1000 Ethernet Driver main header file */
+
+#ifndef _IGBVF_H_
+#define _IGBVF_H_
+
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+
+
+#include "vf.h"
+
+/* Forward declarations */
+struct igbvf_info;
+struct igbvf_adapter;
+
+/* Interrupt defines */
+#define IGBVF_START_ITR                 648 /* ~6000 ints/sec */
+
+/* Interrupt modes, as used by the IntMode paramter */
+#define IGBVF_INT_MODE_LEGACY           0
+#define IGBVF_INT_MODE_MSI              1
+#define IGBVF_INT_MODE_MSIX             2
+
+/* Tx/Rx descriptor defines */
+#define IGBVF_DEFAULT_TXD               256
+#define IGBVF_MAX_TXD                   4096
+#define IGBVF_MIN_TXD                   80
+
+#define IGBVF_DEFAULT_RXD               256
+#define IGBVF_MAX_RXD                   4096
+#define IGBVF_MIN_RXD                   80
+
+#define IGBVF_MIN_ITR_USECS             10 /* 100000 irq/sec */
+#define IGBVF_MAX_ITR_USECS             10000 /* 100    irq/sec */
+
+/* RX descriptor control thresholds.
+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
+ *           descriptors available in its onboard memory.
+ *           Setting this to 0 disables RX descriptor prefetch.
+ * HTHRESH - MAC will only prefetch if there are at least this many descriptors
+ *           available in host memory.
+ *           If PTHRESH is 0, this should also be 0.
+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
+ *           descriptors until either it has this many to write back, or the
+ *           ITR timer expires.
+ */
+#define IGBVF_RX_PTHRESH                16
+#define IGBVF_RX_HTHRESH                8
+#define IGBVF_RX_WTHRESH                1
+
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE      1522
+
+#define IGBVF_FC_PAUSE_TIME             0x0680 /* 858 usec */
+
+/* How many Tx Descriptors do we need to call netif_wake_queue ? */
+#define IGBVF_TX_QUEUE_WAKE             32
+/* How many Rx Buffers do we bundle into one write to the hardware ? */
+#define IGBVF_RX_BUFFER_WRITE           16 /* Must be power of 2 */
+
+#define AUTO_ALL_MODES                  0
+#define IGBVF_EEPROM_APME               0x0400
+
+#define IGBVF_MNG_VLAN_NONE             (-1)
+
+/* Number of packet split data buffers (not including the header buffer) */
+#define PS_PAGE_BUFFERS                 (MAX_PS_BUFFERS - 1)
+
+enum igbvf_boards {
+	board_vf,
+};
+
+struct igbvf_queue_stats {
+	u64 packets;
+	u64 bytes;
+};
+
+/*
+ * wrappers around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct igbvf_buffer {
+	dma_addr_t dma;
+	struct sk_buff *skb;
+	union {
+		/* Tx */
+		struct {
+			unsigned long time_stamp;
+			u16 length;
+			u16 next_to_watch;
+		};
+		/* Rx */
+		struct {
+			struct page *page;
+			u64 page_dma;
+			unsigned int page_offset;
+		};
+	};
+	struct page *page;
+};
+
+union igbvf_desc {
+	union e1000_adv_rx_desc rx_desc;
+	union e1000_adv_tx_desc tx_desc;
+	struct e1000_adv_tx_context_desc tx_context_desc;
+};
+
+struct igbvf_ring {
+	struct igbvf_adapter *adapter;  /* backlink */
+	union igbvf_desc *desc;         /* pointer to ring memory  */
+	dma_addr_t dma;                 /* phys address of ring    */
+	unsigned int size;              /* length of ring in bytes */
+	unsigned int count;             /* number of desc. in ring */
+
+	u16 next_to_use;
+	u16 next_to_clean;
+
+	u16 head;
+	u16 tail;
+
+	/* array of buffer information structs */
+	struct igbvf_buffer *buffer_info;
+	struct napi_struct napi;
+
+	char name[IFNAMSIZ + 5];
+	u32 eims_value;
+	u32 itr_val;
+	u16 itr_register;
+	int set_itr;
+
+	struct sk_buff *rx_skb_top;
+
+	struct igbvf_queue_stats stats;
+};
+
+/* board specific private data structure */
+struct igbvf_adapter {
+	struct timer_list watchdog_timer;
+	struct timer_list blink_timer;
+
+	struct work_struct reset_task;
+	struct work_struct watchdog_task;
+
+	const struct igbvf_info *ei;
+
+	struct vlan_group *vlgrp;
+	u32 bd_number;
+	u32 rx_buffer_len;
+	u32 polling_interval;
+	u16 mng_vlan_id;
+	u16 link_speed;
+	u16 link_duplex;
+
+	spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
+
+	/* track device up/down/testing state */
+	unsigned long state;
+
+	/* Interrupt Throttle Rate */
+	u32 itr;
+	u32 itr_setting;
+	u16 tx_itr;
+	u16 rx_itr;
+
+	/*
+	 * Tx
+	 */
+	struct igbvf_ring *tx_ring /* One per active queue */
+	____cacheline_aligned_in_smp;
+
+	unsigned long tx_queue_len;
+	unsigned int restart_queue;
+	u32 txd_cmd;
+
+	bool detect_tx_hung;
+	u8 tx_timeout_factor;
+
+	u32 tx_int_delay;
+	u32 tx_abs_int_delay;
+
+	unsigned int total_tx_bytes;
+	unsigned int total_tx_packets;
+	unsigned int total_rx_bytes;
+	unsigned int total_rx_packets;
+
+	/* Tx stats */
+	u32 tx_timeout_count;
+	u32 tx_fifo_head;
+	u32 tx_head_addr;
+	u32 tx_fifo_size;
+	u32 tx_dma_failed;
+
+	/*
+	 * Rx
+	 */
+	struct igbvf_ring *rx_ring;
+
+	u32 rx_int_delay;
+	u32 rx_abs_int_delay;
+
+	/* Rx stats */
+	u64 hw_csum_err;
+	u64 hw_csum_good;
+	u64 rx_hdr_split;
+	u32 alloc_rx_buff_failed;
+	u32 rx_dma_failed;
+
+	unsigned int rx_ps_hdr_size;
+	u32 max_frame_size;
+	u32 min_frame_size;
+
+	/* OS defined structs */
+	struct net_device *netdev;
+	struct pci_dev *pdev;
+	struct net_device_stats net_stats;
+	spinlock_t stats_lock;      /* prevent concurrent stats updates */
+
+	/* structs defined in e1000_hw.h */
+	struct e1000_hw hw;
+
+	/* The VF counters don't clear on read so we have to get a base
+	 * count on driver start up and always subtract that base on
+	 * on the first update, thus the flag..
+	 */
+	struct e1000_vf_stats stats;
+	u64 zero_base;
+
+	struct igbvf_ring test_tx_ring;
+	struct igbvf_ring test_rx_ring;
+	u32 test_icr;
+
+	u32 msg_enable;
+	struct msix_entry *msix_entries;
+	int int_mode;
+	u32 eims_enable_mask;
+	u32 eims_other;
+	u32 int_counter0;
+	u32 int_counter1;
+
+	u32 eeprom_wol;
+	u32 wol;
+	u32 pba;
+
+	bool fc_autoneg;
+
+	unsigned long led_status;
+
+	unsigned int flags;
+};
+
+struct igbvf_info {
+	enum e1000_mac_type     mac;
+	unsigned int            flags;
+	u32                     pba;
+	void                    (*init_ops)(struct e1000_hw *);
+	s32                     (*get_variants)(struct igbvf_adapter *);
+};
+
+/* hardware capability, feature, and workaround flags */
+#define FLAG_HAS_HW_VLAN_FILTER           (1 << 0)
+#define FLAG_HAS_JUMBO_FRAMES             (1 << 1)
+#define FLAG_MSI_ENABLED                  (1 << 2)
+#define FLAG_RX_CSUM_ENABLED              (1 << 3)
+#define FLAG_TSO_FORCE                    (1 << 4)
+
+#define IGBVF_RX_DESC_ADV(R, i)     \
+	(&((((R).desc))[i].rx_desc))
+#define IGBVF_TX_DESC_ADV(R, i)     \
+	(&((((R).desc))[i].tx_desc))
+#define IGBVF_TX_CTXTDESC_ADV(R, i) \
+	(&((((R).desc))[i].tx_context_desc))
+
+enum igbvf_state_t {
+	__IGBVF_TESTING,
+	__IGBVF_RESETTING,
+	__IGBVF_DOWN
+};
+
+enum latency_range {
+	lowest_latency = 0,
+	low_latency = 1,
+	bulk_latency = 2,
+	latency_invalid = 255
+};
+
+extern char igbvf_driver_name[];
+extern const char igbvf_driver_version[];
+
+extern void igbvf_check_options(struct igbvf_adapter *);
+extern void igbvf_set_ethtool_ops(struct net_device *);
+
+extern int igbvf_up(struct igbvf_adapter *);
+extern void igbvf_down(struct igbvf_adapter *);
+extern void igbvf_reinit_locked(struct igbvf_adapter *);
+extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *);
+extern void igbvf_free_rx_resources(struct igbvf_ring *);
+extern void igbvf_free_tx_resources(struct igbvf_ring *);
+extern void igbvf_update_stats(struct igbvf_adapter *);
+
+extern unsigned int copybreak;
+
+#endif /* _IGBVF_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/Makefile linux-libre-2.6.30-gnu1/drivers/net/igbvf/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,38 @@
+################################################################################
+#
+# Intel(R) 82576 Virtual Function Linux driver
+# Copyright(c) 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,
+# 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.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+################################################################################
+
+#
+# Makefile for the Intel(R) 82576 VF ethernet driver
+#
+
+obj-$(CONFIG_IGBVF) += igbvf.o
+
+igbvf-objs := vf.o \
+              mbx.o \
+              ethtool.o \
+              netdev.o
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/mbx.c linux-libre-2.6.30-gnu1/drivers/net/igbvf/mbx.c
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/mbx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/mbx.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,350 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "mbx.h"
+
+/**
+ *  e1000_poll_for_msg - Wait for message notification
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if it successfully received a message notification
+ **/
+static s32 e1000_poll_for_msg(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_msg)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_msg(hw)) {
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ *  e1000_poll_for_ack - Wait for message acknowledgement
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if it successfully received a message acknowledgement
+ **/
+static s32 e1000_poll_for_ack(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	int countdown = mbx->timeout;
+
+	if (!mbx->ops.check_for_ack)
+		goto out;
+
+	while (countdown && mbx->ops.check_for_ack(hw)) {
+		countdown--;
+		udelay(mbx->usec_delay);
+	}
+
+	/* if we failed, all future posted messages fail until reset */
+	if (!countdown)
+		mbx->timeout = 0;
+out:
+	return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+}
+
+/**
+ *  e1000_read_posted_mbx - Wait for message notification and receive message
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully received a message notification and
+ *  copied it into the receive buffer.
+ **/
+static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!mbx->ops.read)
+		goto out;
+
+	ret_val = e1000_poll_for_msg(hw);
+
+	/* if ack received read message, otherwise we timed out */
+	if (!ret_val)
+		ret_val = mbx->ops.read(hw, msg, size);
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer and
+ *  received an ack to that message within delay * timeout period
+ **/
+static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	s32 ret_val = -E1000_ERR_MBX;
+
+	/* exit if we either can't write or there isn't a defined timeout */
+	if (!mbx->ops.write || !mbx->timeout)
+		goto out;
+
+	/* send msg*/
+	ret_val = mbx->ops.write(hw, msg, size);
+
+	/* if msg sent wait until we receive an ack */
+	if (!ret_val)
+		ret_val = e1000_poll_for_ack(hw);
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_read_v2p_mailbox - read v2p mailbox
+ *  @hw: pointer to the HW structure
+ *
+ *  This function is used to read the v2p mailbox without losing the read to
+ *  clear status bits.
+ **/
+static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
+{
+	u32 v2p_mailbox = er32(V2PMAILBOX(0));
+
+	v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
+	hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
+
+	return v2p_mailbox;
+}
+
+/**
+ *  e1000_check_for_bit_vf - Determine if a status bit was set
+ *  @hw: pointer to the HW structure
+ *  @mask: bitmask for bits to be tested and cleared
+ *
+ *  This function is used to check for the read to clear bits within
+ *  the V2P mailbox.
+ **/
+static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
+{
+	u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (v2p_mailbox & mask)
+		ret_val = E1000_SUCCESS;
+
+	hw->dev_spec.vf.v2p_mailbox &= ~mask;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_msg_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.reqs++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
+ *  @hw: pointer to the HW structure
+ *
+ *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
+ **/
+static s32 e1000_check_for_ack_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.acks++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_check_for_rst_vf - checks to see if the PF has reset
+ *  @hw: pointer to the HW structure
+ *
+ *  returns true if the PF has set the reset done bit or else false
+ **/
+static s32 e1000_check_for_rst_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
+	                                 E1000_V2PMAILBOX_RSTI))) {
+		ret_val = E1000_SUCCESS;
+		hw->mbx.stats.rsts++;
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
+ *  @hw: pointer to the HW structure
+ *
+ *  return SUCCESS if we obtained the mailbox lock
+ **/
+static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_MBX;
+
+	/* Take ownership of the buffer */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+
+	/* reserve mailbox for vf use */
+	if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
+		ret_val = E1000_SUCCESS;
+
+	return ret_val;
+}
+
+/**
+ *  e1000_write_mbx_vf - Write a message to the mailbox
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	s32 err;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	err = e1000_obtain_mbx_lock_vf(hw);
+	if (err)
+		goto out_no_write;
+
+	/* flush any ack or msg as we are going to overwrite mailbox */
+	e1000_check_for_ack_vf(hw);
+	e1000_check_for_msg_vf(hw);
+
+	/* copy the caller specified message to the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		array_ew32(VMBMEM(0), i, msg[i]);
+
+	/* update stats */
+	hw->mbx.stats.msgs_tx++;
+
+	/* Drop VFU and interrupt the PF to tell it a message has been sent */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
+
+out_no_write:
+	return err;
+}
+
+/**
+ *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
+ *  @hw: pointer to the HW structure
+ *  @msg: The message buffer
+ *  @size: Length of buffer
+ *
+ *  returns SUCCESS if it successfuly read message from buffer
+ **/
+static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+{
+	s32 err;
+	u16 i;
+
+	/* lock the mailbox to prevent pf/vf race condition */
+	err = e1000_obtain_mbx_lock_vf(hw);
+	if (err)
+		goto out_no_read;
+
+	/* copy the message from the mailbox memory buffer */
+	for (i = 0; i < size; i++)
+		msg[i] = array_er32(VMBMEM(0), i);
+
+	/* Acknowledge receipt and release mailbox, then we're done */
+	ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
+
+	/* update stats */
+	hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+	return err;
+}
+
+/**
+ *  e1000_init_mbx_params_vf - set initial values for vf mailbox
+ *  @hw: pointer to the HW structure
+ *
+ *  Initializes the hw->mbx struct to correct values for vf mailbox
+ */
+s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+
+	/* start mailbox as timed out and let the reset_hw call set the timeout
+	 * value to being communications */
+	mbx->timeout = 0;
+	mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
+
+	mbx->size = E1000_VFMAILBOX_SIZE;
+
+	mbx->ops.read = e1000_read_mbx_vf;
+	mbx->ops.write = e1000_write_mbx_vf;
+	mbx->ops.read_posted = e1000_read_posted_mbx;
+	mbx->ops.write_posted = e1000_write_posted_mbx;
+	mbx->ops.check_for_msg = e1000_check_for_msg_vf;
+	mbx->ops.check_for_ack = e1000_check_for_ack_vf;
+	mbx->ops.check_for_rst = e1000_check_for_rst_vf;
+
+	mbx->stats.msgs_tx = 0;
+	mbx->stats.msgs_rx = 0;
+	mbx->stats.reqs = 0;
+	mbx->stats.acks = 0;
+	mbx->stats.rsts = 0;
+
+	return E1000_SUCCESS;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/mbx.h linux-libre-2.6.30-gnu1/drivers/net/igbvf/mbx.h
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/mbx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/mbx.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "vf.h"
+
+#define E1000_V2PMAILBOX_REQ   0x00000001 /* Request for PF Ready bit */
+#define E1000_V2PMAILBOX_ACK   0x00000002 /* Ack PF message received */
+#define E1000_V2PMAILBOX_VFU   0x00000004 /* VF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFU   0x00000008 /* PF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
+#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
+#define E1000_V2PMAILBOX_RSTI  0x00000040 /* PF has reset indication */
+#define E1000_V2PMAILBOX_RSTD  0x00000080 /* PF has indicated reset done */
+#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
+
+#define E1000_VFMAILBOX_SIZE   16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF.  The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK      0x80000000  /* Messages below or'd with
+                                               * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK     0x40000000  /* Messages below or'd with
+                                               * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS      0x20000000  /* Indicates that VF is still
+                                                 clear to send requests */
+
+/* We have a total wait time of 1s for vf mailbox posted messages */
+#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mailbox timeout */
+#define E1000_VF_MBX_INIT_DELAY   500  /* usec delay between retries */
+
+#define E1000_VT_MSGINFO_SHIFT    16
+/* bits 23:16 are used for exra info for certain messages */
+#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_PF_CONTROL_MSG      0x0100 /* PF control message */
+
+void e1000_init_mbx_ops_generic(struct e1000_hw *hw);
+s32 e1000_init_mbx_params_vf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/netdev.c linux-libre-2.6.30-gnu1/drivers/net/igbvf/netdev.c
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/netdev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/netdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2922 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/pm_qos_params.h>
+
+#include "igbvf.h"
+
+#define DRV_VERSION "1.0.0-k0"
+char igbvf_driver_name[] = "igbvf";
+const char igbvf_driver_version[] = DRV_VERSION;
+static const char igbvf_driver_string[] =
+				"Intel(R) Virtual Function Network Driver";
+static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
+
+static int igbvf_poll(struct napi_struct *napi, int budget);
+static void igbvf_reset(struct igbvf_adapter *);
+static void igbvf_set_interrupt_capability(struct igbvf_adapter *);
+static void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
+
+static struct igbvf_info igbvf_vf_info = {
+	.mac                    = e1000_vfadapt,
+	.flags                  = FLAG_HAS_JUMBO_FRAMES
+	                          | FLAG_RX_CSUM_ENABLED,
+	.pba                    = 10,
+	.init_ops               = e1000_init_function_pointers_vf,
+};
+
+static const struct igbvf_info *igbvf_info_tbl[] = {
+	[board_vf]              = &igbvf_vf_info,
+};
+
+/**
+ * igbvf_desc_unused - calculate if we have unused descriptors
+ **/
+static int igbvf_desc_unused(struct igbvf_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;
+}
+
+/**
+ * igbvf_receive_skb - helper function to handle Rx indications
+ * @adapter: board private structure
+ * @status: descriptor status field as written by hardware
+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @skb: pointer to sk_buff to be indicated to stack
+ **/
+static void igbvf_receive_skb(struct igbvf_adapter *adapter,
+                              struct net_device *netdev,
+                              struct sk_buff *skb,
+                              u32 status, u16 vlan)
+{
+	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
+		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+		                         le16_to_cpu(vlan) &
+		                         E1000_RXD_SPC_VLAN_MASK);
+	else
+		netif_receive_skb(skb);
+
+	netdev->last_rx = jiffies;
+}
+
+static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
+                                         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))
+		return;
+	/* TCP/UDP checksum error bit is set */
+	if (status_err &
+	    (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+		/* let the stack verify checksum errors */
+		adapter->hw_csum_err++;
+		return;
+	}
+	/* It must be a TCP or UDP packet with a valid checksum */
+	if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	adapter->hw_csum_good++;
+}
+
+/**
+ * igbvf_alloc_rx_buffers - Replace used receive buffers; packet split
+ * @rx_ring: address of ring structure to repopulate
+ * @cleaned_count: number of buffers to repopulate
+ **/
+static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
+                                   int cleaned_count)
+{
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	union e1000_adv_rx_desc *rx_desc;
+	struct igbvf_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	int bufsz;
+
+	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 += NET_IP_ALIGN;
+
+	while (cleaned_count--) {
+		rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+
+		if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
+			if (!buffer_info->page) {
+				buffer_info->page = alloc_page(GFP_ATOMIC);
+				if (!buffer_info->page) {
+					adapter->alloc_rx_buff_failed++;
+					goto no_buffers;
+				}
+				buffer_info->page_offset = 0;
+			} else {
+				buffer_info->page_offset ^= PAGE_SIZE / 2;
+			}
+			buffer_info->page_dma =
+				pci_map_page(pdev, buffer_info->page,
+				             buffer_info->page_offset,
+				             PAGE_SIZE / 2,
+				             PCI_DMA_FROMDEVICE);
+		}
+
+		if (!buffer_info->skb) {
+			skb = netdev_alloc_skb(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,
+			                                  PCI_DMA_FROMDEVICE);
+		}
+		/* Refresh the desc even if buffer_addrs didn't change because
+		 * each write-back erases this info. */
+		if (adapter->rx_ps_hdr_size) {
+			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.hdr_addr = 0;
+		}
+
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+		buffer_info = &rx_ring->buffer_info[i];
+	}
+
+no_buffers:
+	if (rx_ring->next_to_use != i) {
+		rx_ring->next_to_use = i;
+		if (i == 0)
+			i = (rx_ring->count - 1);
+		else
+			i--;
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+	}
+}
+
+/**
+ * igbvf_clean_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ **/
+static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
+                               int *work_done, int work_to_do)
+{
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	union e1000_adv_rx_desc *rx_desc, *next_rxd;
+	struct igbvf_buffer *buffer_info, *next_buffer;
+	struct sk_buff *skb;
+	bool cleaned = false;
+	int cleaned_count = 0;
+	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int i;
+	u32 length, hlen, staterr;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
+	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+	while (staterr & E1000_RXD_STAT_DD) {
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		buffer_info = &rx_ring->buffer_info[i];
+
+		/* HW will not DMA in data larger than the given buffer, even
+		 * if it parses the (NFS, of course) header to be larger.  In
+		 * that case, it fills the header buffer and spills the rest
+		 * into the page.
+		 */
+		hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info) &
+		  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+		if (hlen > adapter->rx_ps_hdr_size)
+			hlen = adapter->rx_ps_hdr_size;
+
+		length = le16_to_cpu(rx_desc->wb.upper.length);
+		cleaned = true;
+		cleaned_count++;
+
+		skb = buffer_info->skb;
+		prefetch(skb->data - NET_IP_ALIGN);
+		buffer_info->skb = NULL;
+		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 (!skb_shinfo(skb)->nr_frags) {
+			pci_unmap_single(pdev, buffer_info->dma,
+			                 adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+			                 PCI_DMA_FROMDEVICE);
+			skb_put(skb, hlen);
+		}
+
+		if (length) {
+			pci_unmap_page(pdev, buffer_info->page_dma,
+			               PAGE_SIZE / 2,
+			               PCI_DMA_FROMDEVICE);
+			buffer_info->page_dma = 0;
+
+			skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+			                   buffer_info->page,
+			                   buffer_info->page_offset,
+			                   length);
+
+			if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+			    (page_count(buffer_info->page) != 1))
+				buffer_info->page = NULL;
+			else
+				get_page(buffer_info->page);
+
+			skb->len += length;
+			skb->data_len += length;
+			skb->truesize += length;
+		}
+send_up:
+		i++;
+		if (i == rx_ring->count)
+			i = 0;
+		next_rxd = IGBVF_RX_DESC_ADV(*rx_ring, i);
+		prefetch(next_rxd);
+		next_buffer = &rx_ring->buffer_info[i];
+
+		if (!(staterr & E1000_RXD_STAT_EOP)) {
+			buffer_info->skb = next_buffer->skb;
+			buffer_info->dma = next_buffer->dma;
+			next_buffer->skb = skb;
+			next_buffer->dma = 0;
+			goto next_desc;
+		}
+
+		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+			dev_kfree_skb_irq(skb);
+			goto next_desc;
+		}
+
+		total_bytes += skb->len;
+		total_packets++;
+
+		igbvf_rx_checksum_adv(adapter, staterr, skb);
+
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		igbvf_receive_skb(adapter, netdev, skb, staterr,
+		                  rx_desc->wb.upper.vlan);
+
+		netdev->last_rx = jiffies;
+
+next_desc:
+		rx_desc->wb.upper.status_error = 0;
+
+		/* return some buffers to hardware, one at a time is too slow */
+		if (cleaned_count >= IGBVF_RX_BUFFER_WRITE) {
+			igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+
+		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	}
+
+	rx_ring->next_to_clean = i;
+	cleaned_count = igbvf_desc_unused(rx_ring);
+
+	if (cleaned_count)
+		igbvf_alloc_rx_buffers(rx_ring, cleaned_count);
+
+	adapter->total_rx_packets += total_packets;
+	adapter->total_rx_bytes += total_bytes;
+	adapter->net_stats.rx_bytes += total_bytes;
+	adapter->net_stats.rx_packets += total_packets;
+	return cleaned;
+}
+
+static void igbvf_put_txbuf(struct igbvf_adapter *adapter,
+                            struct igbvf_buffer *buffer_info)
+{
+	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 igbvf_print_tx_hang(struct igbvf_adapter *adapter)
+{
+	struct igbvf_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;
+	union e1000_adv_tx_desc *eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+	/* detected Tx unit hang */
+	dev_err(&adapter->pdev->dev,
+	        "Detected Tx Unit Hang:\n"
+	        "  TDH                  <%x>\n"
+	        "  TDT                  <%x>\n"
+	        "  next_to_use          <%x>\n"
+	        "  next_to_clean        <%x>\n"
+	        "buffer_info[next_to_clean]:\n"
+	        "  time_stamp           <%lx>\n"
+	        "  next_to_watch        <%x>\n"
+	        "  jiffies              <%lx>\n"
+	        "  next_to_watch.status <%x>\n",
+	        readl(adapter->hw.hw_addr + tx_ring->head),
+	        readl(adapter->hw.hw_addr + tx_ring->tail),
+	        tx_ring->next_to_use,
+	        tx_ring->next_to_clean,
+	        tx_ring->buffer_info[eop].time_stamp,
+	        eop,
+	        jiffies,
+	        eop_desc->wb.status);
+}
+
+/**
+ * igbvf_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+int igbvf_setup_tx_resources(struct igbvf_adapter *adapter,
+                             struct igbvf_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size;
+
+	size = sizeof(struct igbvf_buffer) * tx_ring->count;
+	tx_ring->buffer_info = vmalloc(size);
+	if (!tx_ring->buffer_info)
+		goto err;
+	memset(tx_ring->buffer_info, 0, size);
+
+	/* round up to nearest 4K */
+	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)
+		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,
+	        "Unable to allocate memory for the transmit descriptor ring\n");
+	return -ENOMEM;
+}
+
+/**
+ * igbvf_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @adapter: board private structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+int igbvf_setup_rx_resources(struct igbvf_adapter *adapter,
+			     struct igbvf_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int size, desc_len;
+
+	size = sizeof(struct igbvf_buffer) * rx_ring->count;
+	rx_ring->buffer_info = vmalloc(size);
+	if (!rx_ring->buffer_info)
+		goto err;
+	memset(rx_ring->buffer_info, 0, size);
+
+	desc_len = sizeof(union e1000_adv_rx_desc);
+
+	/* Round up to nearest 4K */
+	rx_ring->size = rx_ring->count * desc_len;
+	rx_ring->size = ALIGN(rx_ring->size, 4096);
+
+	rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+	                                     &rx_ring->dma);
+
+	if (!rx_ring->desc)
+		goto err;
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	rx_ring->adapter = adapter;
+
+	return 0;
+
+err:
+	vfree(rx_ring->buffer_info);
+	rx_ring->buffer_info = NULL;
+	dev_err(&adapter->pdev->dev,
+	        "Unable to allocate memory for the receive descriptor ring\n");
+	return -ENOMEM;
+}
+
+/**
+ * igbvf_clean_tx_ring - Free Tx Buffers
+ * @tx_ring: ring to be cleaned
+ **/
+static void igbvf_clean_tx_ring(struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = tx_ring->adapter;
+	struct igbvf_buffer *buffer_info;
+	unsigned long size;
+	unsigned int i;
+
+	if (!tx_ring->buffer_info)
+		return;
+
+	/* Free all the Tx ring sk_buffs */
+	for (i = 0; i < tx_ring->count; i++) {
+		buffer_info = &tx_ring->buffer_info[i];
+		igbvf_put_txbuf(adapter, buffer_info);
+	}
+
+	size = sizeof(struct igbvf_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);
+}
+
+/**
+ * igbvf_free_tx_resources - Free Tx Resources per Queue
+ * @tx_ring: ring to free resources from
+ *
+ * Free all transmit software resources
+ **/
+void igbvf_free_tx_resources(struct igbvf_ring *tx_ring)
+{
+	struct pci_dev *pdev = tx_ring->adapter->pdev;
+
+	igbvf_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);
+
+	tx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_clean_rx_ring - Free Rx Buffers per Queue
+ * @adapter: board private structure
+ **/
+static void igbvf_clean_rx_ring(struct igbvf_ring *rx_ring)
+{
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct igbvf_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);
+			}
+			buffer_info->dma = 0;
+		}
+
+		if (buffer_info->skb) {
+			dev_kfree_skb(buffer_info->skb);
+			buffer_info->skb = NULL;
+		}
+
+		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;
+		}
+	}
+
+	size = sizeof(struct igbvf_buffer) * rx_ring->count;
+	memset(rx_ring->buffer_info, 0, size);
+
+	/* Zero out the descriptor ring */
+	memset(rx_ring->desc, 0, rx_ring->size);
+
+	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);
+}
+
+/**
+ * igbvf_free_rx_resources - Free Rx Resources
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+
+void igbvf_free_rx_resources(struct igbvf_ring *rx_ring)
+{
+	struct pci_dev *pdev = rx_ring->adapter->pdev;
+
+	igbvf_clean_rx_ring(rx_ring);
+
+	vfree(rx_ring->buffer_info);
+	rx_ring->buffer_info = NULL;
+
+	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
+	                  rx_ring->dma);
+	rx_ring->desc = NULL;
+}
+
+/**
+ * igbvf_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
+ *      Stores a new ITR value based on packets and byte
+ *      counts during the last interrupt.  The advantage of per interrupt
+ *      computation is faster updates and more accurate ITR for the current
+ *      traffic pattern.  Constants in this function were computed
+ *      based on theoretical maximum wire speed and thresholds were set based
+ *      on testing data as well as attempting to minimize response time
+ *      while increasing bulk throughput.  This functionality is controlled
+ *      by the InterruptThrottleRate module parameter.
+ **/
+static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
+                                     u16 itr_setting, int packets,
+                                     int bytes)
+{
+	unsigned int retval = itr_setting;
+
+	if (packets == 0)
+		goto update_itr_done;
+
+	switch (itr_setting) {
+	case lowest_latency:
+		/* handle TSO and jumbo frames */
+		if (bytes/packets > 8000)
+			retval = bulk_latency;
+		else if ((packets < 5) && (bytes > 512))
+			retval = low_latency;
+		break;
+	case low_latency:  /* 50 usec aka 20000 ints/s */
+		if (bytes > 10000) {
+			/* this if handles the TSO accounting */
+			if (bytes/packets > 8000)
+				retval = bulk_latency;
+			else if ((packets < 10) || ((bytes/packets) > 1200))
+				retval = bulk_latency;
+			else if ((packets > 35))
+				retval = lowest_latency;
+		} else if (bytes/packets > 2000) {
+			retval = bulk_latency;
+		} else if (packets <= 2 && bytes < 512) {
+			retval = lowest_latency;
+		}
+		break;
+	case bulk_latency: /* 250 usec aka 4000 ints/s */
+		if (bytes > 25000) {
+			if (packets > 35)
+				retval = low_latency;
+		} else if (bytes < 6000) {
+			retval = low_latency;
+		}
+		break;
+	}
+
+update_itr_done:
+	return retval;
+}
+
+static void igbvf_set_itr(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u16 current_itr;
+	u32 new_itr = adapter->itr;
+
+	adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr,
+	                                   adapter->total_tx_packets,
+	                                   adapter->total_tx_bytes);
+	/* conservative mode (itr 3) eliminates the lowest_latency setting */
+	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
+		adapter->tx_itr = low_latency;
+
+	adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr,
+	                                   adapter->total_rx_packets,
+	                                   adapter->total_rx_bytes);
+	/* conservative mode (itr 3) eliminates the lowest_latency setting */
+	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
+		adapter->rx_itr = low_latency;
+
+	current_itr = max(adapter->rx_itr, adapter->tx_itr);
+
+	switch (current_itr) {
+	/* counts and packets in update_itr are dependent on these numbers */
+	case lowest_latency:
+		new_itr = 70000;
+		break;
+	case low_latency:
+		new_itr = 20000; /* aka hwitr = ~200 */
+		break;
+	case bulk_latency:
+		new_itr = 4000;
+		break;
+	default:
+		break;
+	}
+
+	if (new_itr != adapter->itr) {
+		/*
+		 * this attempts to bias the interrupt rate towards Bulk
+		 * by adding intermediate steps when interrupt rate is
+		 * increasing
+		 */
+		new_itr = new_itr > adapter->itr ?
+		             min(adapter->itr + (new_itr >> 2), new_itr) :
+		             new_itr;
+		adapter->itr = new_itr;
+		adapter->rx_ring->itr_val = 1952;
+
+		if (adapter->msix_entries)
+			adapter->rx_ring->set_itr = 1;
+		else
+			ew32(ITR, 1952);
+	}
+}
+
+/**
+ * igbvf_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ * returns true if ring is completely cleaned
+ **/
+static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = tx_ring->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct igbvf_buffer *buffer_info;
+	struct sk_buff *skb;
+	union e1000_adv_tx_desc *tx_desc, *eop_desc;
+	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int i, eop, count = 0;
+	bool cleaned = false;
+
+	i = tx_ring->next_to_clean;
+	eop = tx_ring->buffer_info[i].next_to_watch;
+	eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+
+	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+	       (count < tx_ring->count)) {
+		for (cleaned = false; !cleaned; count++) {
+			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+			buffer_info = &tx_ring->buffer_info[i];
+			cleaned = (i == eop);
+			skb = buffer_info->skb;
+
+			if (skb) {
+				unsigned int segs, bytecount;
+
+				/* gso_segs is currently only valid for tcp */
+				segs = skb_shinfo(skb)->gso_segs ?: 1;
+				/* multiply data chunks by size of headers */
+				bytecount = ((segs - 1) * skb_headlen(skb)) +
+				            skb->len;
+				total_packets += segs;
+				total_bytes += bytecount;
+			}
+
+			igbvf_put_txbuf(adapter, buffer_info);
+			tx_desc->wb.status = 0;
+
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
+		eop = tx_ring->buffer_info[i].next_to_watch;
+		eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop);
+	}
+
+	tx_ring->next_to_clean = i;
+
+	if (unlikely(count &&
+	             netif_carrier_ok(netdev) &&
+	             igbvf_desc_unused(tx_ring) >= IGBVF_TX_QUEUE_WAKE)) {
+		/* Make sure that anybody stopping the queue after this
+		 * sees the new next_to_clean.
+		 */
+		smp_mb();
+		if (netif_queue_stopped(netdev) &&
+		    !(test_bit(__IGBVF_DOWN, &adapter->state))) {
+			netif_wake_queue(netdev);
+			++adapter->restart_queue;
+		}
+	}
+
+	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 */
+		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)) {
+
+			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
+			/* detected Tx unit hang */
+			igbvf_print_tx_hang(adapter);
+
+			netif_stop_queue(netdev);
+		}
+	}
+	adapter->net_stats.tx_bytes += total_bytes;
+	adapter->net_stats.tx_packets += total_packets;
+	return (count < tx_ring->count);
+}
+
+static irqreturn_t igbvf_msix_other(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	adapter->int_counter1++;
+
+	netif_carrier_off(netdev);
+	hw->mac.get_link_status = 1;
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+	ew32(EIMS, adapter->eims_other);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_tx(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+
+
+	adapter->total_tx_bytes = 0;
+	adapter->total_tx_packets = 0;
+
+	/* auto mask will automatically reenable the interrupt when we write
+	 * EICS */
+	if (!igbvf_clean_tx_irq(tx_ring))
+		/* Ring was not completely cleaned, so fire another interrupt */
+		ew32(EICS, tx_ring->eims_value);
+	else
+		ew32(EIMS, tx_ring->eims_value);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t igbvf_intr_msix_rx(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	adapter->int_counter0++;
+
+	/* Write the ITR value calculated at the end of the
+	 * previous interrupt.
+	 */
+	if (adapter->rx_ring->set_itr) {
+		writel(adapter->rx_ring->itr_val,
+		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
+		adapter->rx_ring->set_itr = 0;
+	}
+
+	if (napi_schedule_prep(&adapter->rx_ring->napi)) {
+		adapter->total_rx_bytes = 0;
+		adapter->total_rx_packets = 0;
+		__napi_schedule(&adapter->rx_ring->napi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+#define IGBVF_NO_QUEUE -1
+
+static void igbvf_assign_vector(struct igbvf_adapter *adapter, int rx_queue,
+                                int tx_queue, int msix_vector)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 ivar, index;
+
+	/* 82576 uses a table-based method for assigning vectors.
+	   Each queue has a single entry in the table to which we write
+	   a vector number along with a "valid" bit.  Sadly, the layout
+	   of the table is somewhat counterintuitive. */
+	if (rx_queue > IGBVF_NO_QUEUE) {
+		index = (rx_queue >> 1);
+		ivar = array_er32(IVAR0, index);
+		if (rx_queue & 0x1) {
+			/* vector goes into third byte of register */
+			ivar = ivar & 0xFF00FFFF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+		} else {
+			/* vector goes into low byte of register */
+			ivar = ivar & 0xFFFFFF00;
+			ivar |= msix_vector | E1000_IVAR_VALID;
+		}
+		adapter->rx_ring[rx_queue].eims_value = 1 << msix_vector;
+		array_ew32(IVAR0, index, ivar);
+	}
+	if (tx_queue > IGBVF_NO_QUEUE) {
+		index = (tx_queue >> 1);
+		ivar = array_er32(IVAR0, index);
+		if (tx_queue & 0x1) {
+			/* vector goes into high byte of register */
+			ivar = ivar & 0x00FFFFFF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+		} else {
+			/* vector goes into second byte of register */
+			ivar = ivar & 0xFFFF00FF;
+			ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+		}
+		adapter->tx_ring[tx_queue].eims_value = 1 << msix_vector;
+		array_ew32(IVAR0, index, ivar);
+	}
+}
+
+/**
+ * igbvf_configure_msix - Configure MSI-X hardware
+ *
+ * igbvf_configure_msix sets up the hardware to properly
+ * generate MSI-X interrupts.
+ **/
+static void igbvf_configure_msix(struct igbvf_adapter *adapter)
+{
+	u32 tmp;
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	int vector = 0;
+
+	adapter->eims_enable_mask = 0;
+
+	igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, 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(1952, hw->hw_addr + tx_ring->itr_register);
+
+	igbvf_assign_vector(adapter, 0, IGBVF_NO_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(1952, hw->hw_addr + rx_ring->itr_register);
+
+	/* set vector for other causes, i.e. link changes */
+
+	tmp = (vector++ | E1000_IVAR_VALID);
+
+	ew32(IVAR_MISC, tmp);
+
+	adapter->eims_enable_mask = (1 << (vector)) - 1;
+	adapter->eims_other = 1 << (vector - 1);
+	e1e_flush();
+}
+
+static void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter)
+{
+	if (adapter->msix_entries) {
+		pci_disable_msix(adapter->pdev);
+		kfree(adapter->msix_entries);
+		adapter->msix_entries = NULL;
+	}
+}
+
+/**
+ * igbvf_set_interrupt_capability - set MSI or MSI-X if supported
+ *
+ * Attempt to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter)
+{
+	int err = -ENOMEM;
+	int i;
+
+	/* we allocate 3 vectors, 1 for tx, 1 for rx, one for pf messages */
+	adapter->msix_entries = kcalloc(3, sizeof(struct msix_entry),
+	                                GFP_KERNEL);
+	if (adapter->msix_entries) {
+		for (i = 0; i < 3; i++)
+			adapter->msix_entries[i].entry = i;
+
+		err = pci_enable_msix(adapter->pdev,
+		                      adapter->msix_entries, 3);
+	}
+
+	if (err) {
+		/* MSI-X failed */
+		dev_err(&adapter->pdev->dev,
+		        "Failed to initialize MSI-X interrupts.\n");
+		igbvf_reset_interrupt_capability(adapter);
+	}
+}
+
+/**
+ * igbvf_request_msix - Initialize MSI-X interrupts
+ *
+ * igbvf_request_msix allocates MSI-X vectors and requests interrupts from the
+ * kernel.
+ **/
+static int igbvf_request_msix(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int err = 0, vector = 0;
+
+	if (strlen(netdev->name) < (IFNAMSIZ - 5)) {
+		sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
+		sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
+	} else {
+		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
+		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
+	}
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_intr_msix_tx, 0, adapter->tx_ring->name,
+	                  netdev);
+	if (err)
+		goto out;
+
+	adapter->tx_ring->itr_register = E1000_EITR(vector);
+	adapter->tx_ring->itr_val = 1952;
+	vector++;
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_intr_msix_rx, 0, adapter->rx_ring->name,
+	                  netdev);
+	if (err)
+		goto out;
+
+	adapter->rx_ring->itr_register = E1000_EITR(vector);
+	adapter->rx_ring->itr_val = 1952;
+	vector++;
+
+	err = request_irq(adapter->msix_entries[vector].vector,
+	                  &igbvf_msix_other, 0, netdev->name, netdev);
+	if (err)
+		goto out;
+
+	igbvf_configure_msix(adapter);
+	return 0;
+out:
+	return err;
+}
+
+/**
+ * igbvf_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ **/
+static int __devinit igbvf_alloc_queues(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	adapter->tx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+	if (!adapter->tx_ring)
+		return -ENOMEM;
+
+	adapter->rx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL);
+	if (!adapter->rx_ring) {
+		kfree(adapter->tx_ring);
+		return -ENOMEM;
+	}
+
+	netif_napi_add(netdev, &adapter->rx_ring->napi, igbvf_poll, 64);
+
+	return 0;
+}
+
+/**
+ * igbvf_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static int igbvf_request_irq(struct igbvf_adapter *adapter)
+{
+	int err = -1;
+
+	/* igbvf supports msi-x only */
+	if (adapter->msix_entries)
+		err = igbvf_request_msix(adapter);
+
+	if (!err)
+		return err;
+
+	dev_err(&adapter->pdev->dev,
+	        "Unable to allocate interrupt, Error: %d\n", err);
+
+	return err;
+}
+
+static void igbvf_free_irq(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int vector;
+
+	if (adapter->msix_entries) {
+		for (vector = 0; vector < 3; vector++)
+			free_irq(adapter->msix_entries[vector].vector, netdev);
+	}
+}
+
+/**
+ * igbvf_irq_disable - Mask off interrupt generation on the NIC
+ **/
+static void igbvf_irq_disable(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	ew32(EIMC, ~0);
+
+	if (adapter->msix_entries)
+		ew32(EIAC, 0);
+}
+
+/**
+ * igbvf_irq_enable - Enable default interrupt generation settings
+ **/
+static void igbvf_irq_enable(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	ew32(EIAC, adapter->eims_enable_mask);
+	ew32(EIAM, adapter->eims_enable_mask);
+	ew32(EIMS, adapter->eims_enable_mask);
+}
+
+/**
+ * igbvf_poll - NAPI Rx polling callback
+ * @napi: struct associated with this polling callback
+ * @budget: amount of packets driver is allowed to process this poll
+ **/
+static int igbvf_poll(struct napi_struct *napi, int budget)
+{
+	struct igbvf_ring *rx_ring = container_of(napi, struct igbvf_ring, napi);
+	struct igbvf_adapter *adapter = rx_ring->adapter;
+	struct e1000_hw *hw = &adapter->hw;
+	int work_done = 0;
+
+	igbvf_clean_rx_irq(adapter, &work_done, budget);
+
+	/* If not enough Rx work done, exit the polling mode */
+	if (work_done < budget) {
+		napi_complete(napi);
+
+		if (adapter->itr_setting & 3)
+			igbvf_set_itr(adapter);
+
+		if (!test_bit(__IGBVF_DOWN, &adapter->state))
+			ew32(EIMS, adapter->rx_ring->eims_value);
+	}
+
+	return work_done;
+}
+
+/**
+ * igbvf_set_rlpml - set receive large packet maximum length
+ * @adapter: board private structure
+ *
+ * Configure the maximum size of packets that will be received
+ */
+static void igbvf_set_rlpml(struct igbvf_adapter *adapter)
+{
+	int max_frame_size = adapter->max_frame_size;
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (adapter->vlgrp)
+		max_frame_size += VLAN_TAG_SIZE;
+
+	e1000_rlpml_set_vf(hw, max_frame_size);
+}
+
+static void igbvf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (hw->mac.ops.set_vfta(hw, vid, true))
+		dev_err(&adapter->pdev->dev, "Failed to add vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	igbvf_irq_disable(adapter);
+	vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		igbvf_irq_enable(adapter);
+
+	if (hw->mac.ops.set_vfta(hw, vid, false))
+		dev_err(&adapter->pdev->dev,
+		        "Failed to remove vlan id %d\n", vid);
+}
+
+static void igbvf_vlan_rx_register(struct net_device *netdev,
+                                   struct vlan_group *grp)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	adapter->vlgrp = grp;
+}
+
+static void igbvf_restore_vlan(struct igbvf_adapter *adapter)
+{
+	u16 vid;
+
+	if (!adapter->vlgrp)
+		return;
+
+	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		if (!vlan_group_get_device(adapter->vlgrp, vid))
+			continue;
+		igbvf_vlan_rx_add_vid(adapter->netdev, vid);
+	}
+
+	igbvf_set_rlpml(adapter);
+}
+
+/**
+ * igbvf_configure_tx - Configure Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_tx(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	u64 tdba;
+	u32 txdctl, dca_txctrl;
+
+	/* disable transmits */
+	txdctl = er32(TXDCTL(0));
+	ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+	msleep(10);
+
+	/* Setup the HW Tx Head and Tail descriptor pointers */
+	ew32(TDLEN(0), tx_ring->count * sizeof(union e1000_adv_tx_desc));
+	tdba = tx_ring->dma;
+	ew32(TDBAL(0), (tdba & DMA_32BIT_MASK));
+	ew32(TDBAH(0), (tdba >> 32));
+	ew32(TDH(0), 0);
+	ew32(TDT(0), 0);
+	tx_ring->head = E1000_TDH(0);
+	tx_ring->tail = E1000_TDT(0);
+
+	/* Turn off Relaxed Ordering on head write-backs.  The writebacks
+	 * MUST be delivered in order or it will completely screw up
+	 * our bookeeping.
+	 */
+	dca_txctrl = er32(DCA_TXCTRL(0));
+	dca_txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
+	ew32(DCA_TXCTRL(0), dca_txctrl);
+
+	/* enable transmits */
+	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+	ew32(TXDCTL(0), txdctl);
+
+	/* Setup Transmit Descriptor Settings for eop descriptor */
+	adapter->txd_cmd = E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_IFCS;
+
+	/* enable Report Status bit */
+	adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS;
+
+	adapter->tx_queue_len = adapter->netdev->tx_queue_len;
+}
+
+/**
+ * igbvf_setup_srrctl - configure the receive control registers
+ * @adapter: Board private structure
+ **/
+static void igbvf_setup_srrctl(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 srrctl = 0;
+
+	srrctl &= ~(E1000_SRRCTL_DESCTYPE_MASK |
+	            E1000_SRRCTL_BSIZEHDR_MASK |
+	            E1000_SRRCTL_BSIZEPKT_MASK);
+
+	/* Enable queue drop to avoid head of line blocking */
+	srrctl |= E1000_SRRCTL_DROP_EN;
+
+	/* Setup buffer sizes */
+	srrctl |= ALIGN(adapter->rx_buffer_len, 1024) >>
+	          E1000_SRRCTL_BSIZEPKT_SHIFT;
+
+	if (adapter->rx_buffer_len < 2048) {
+		adapter->rx_ps_hdr_size = 0;
+		srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+	} else {
+		adapter->rx_ps_hdr_size = 128;
+		srrctl |= adapter->rx_ps_hdr_size <<
+		          E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+		srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+	}
+
+	ew32(SRRCTL(0), srrctl);
+}
+
+/**
+ * igbvf_configure_rx - Configure Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igbvf_configure_rx(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct igbvf_ring *rx_ring = adapter->rx_ring;
+	u64 rdba;
+	u32 rdlen, rxdctl;
+
+	/* disable receives */
+	rxdctl = er32(RXDCTL(0));
+	ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+	msleep(10);
+
+	rdlen = rx_ring->count * sizeof(union e1000_adv_rx_desc);
+
+	/*
+	 * Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring
+	 */
+	rdba = rx_ring->dma;
+	ew32(RDBAL(0), (rdba & DMA_32BIT_MASK));
+	ew32(RDBAH(0), (rdba >> 32));
+	ew32(RDLEN(0), rx_ring->count * sizeof(union e1000_adv_rx_desc));
+	rx_ring->head = E1000_RDH(0);
+	rx_ring->tail = E1000_RDT(0);
+	ew32(RDH(0), 0);
+	ew32(RDT(0), 0);
+
+	rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+	rxdctl &= 0xFFF00000;
+	rxdctl |= IGBVF_RX_PTHRESH;
+	rxdctl |= IGBVF_RX_HTHRESH << 8;
+	rxdctl |= IGBVF_RX_WTHRESH << 16;
+
+	igbvf_set_rlpml(adapter);
+
+	/* enable receives */
+	ew32(RXDCTL(0), rxdctl);
+}
+
+/**
+ * igbvf_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igbvf_set_multi(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct dev_mc_list *mc_ptr;
+	u8  *mta_list = NULL;
+	int i;
+
+	if (netdev->mc_count) {
+		mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
+		if (!mta_list) {
+			dev_err(&adapter->pdev->dev,
+			        "failed to allocate multicast filter list\n");
+			return;
+		}
+	}
+
+	/* prepare 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;
+	}
+
+	hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 0, 0);
+	kfree(mta_list);
+}
+
+/**
+ * igbvf_configure - configure the hardware for Rx and Tx
+ * @adapter: private board structure
+ **/
+static void igbvf_configure(struct igbvf_adapter *adapter)
+{
+	igbvf_set_multi(adapter->netdev);
+
+	igbvf_restore_vlan(adapter);
+
+	igbvf_configure_tx(adapter);
+	igbvf_setup_srrctl(adapter);
+	igbvf_configure_rx(adapter);
+	igbvf_alloc_rx_buffers(adapter->rx_ring,
+	                       igbvf_desc_unused(adapter->rx_ring));
+}
+
+/* igbvf_reset - bring the hardware into a known good state
+ *
+ * This function boots the hardware and enables some settings that
+ * require a configuration cycle of the hardware - those cannot be
+ * set/changed during runtime. After reset the device needs to be
+ * properly configured for Rx, Tx etc.
+ */
+static void igbvf_reset(struct igbvf_adapter *adapter)
+{
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+
+	/* Allow time for pending master requests to run */
+	if (mac->ops.reset_hw(hw))
+		dev_err(&adapter->pdev->dev, "PF still resetting\n");
+
+	mac->ops.init_hw(hw);
+
+	if (is_valid_ether_addr(adapter->hw.mac.addr)) {
+		memcpy(netdev->dev_addr, adapter->hw.mac.addr,
+		       netdev->addr_len);
+		memcpy(netdev->perm_addr, adapter->hw.mac.addr,
+		       netdev->addr_len);
+	}
+}
+
+int igbvf_up(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	/* hardware has been reset, we need to reload some things */
+	igbvf_configure(adapter);
+
+	clear_bit(__IGBVF_DOWN, &adapter->state);
+
+	napi_enable(&adapter->rx_ring->napi);
+	if (adapter->msix_entries)
+		igbvf_configure_msix(adapter);
+
+	/* Clear any pending interrupts. */
+	er32(EICR);
+	igbvf_irq_enable(adapter);
+
+	/* start the watchdog */
+	hw->mac.get_link_status = 1;
+	mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+
+	return 0;
+}
+
+void igbvf_down(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 rxdctl, txdctl;
+
+	/*
+	 * signal that we're down so the interrupt handler does not
+	 * reschedule our watchdog timer
+	 */
+	set_bit(__IGBVF_DOWN, &adapter->state);
+
+	/* disable receives in the hardware */
+	rxdctl = er32(RXDCTL(0));
+	ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE);
+
+	netif_stop_queue(netdev);
+
+	/* disable transmits in the hardware */
+	txdctl = er32(TXDCTL(0));
+	ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE);
+
+	/* flush both disables and wait for them to finish */
+	e1e_flush();
+	msleep(10);
+
+	napi_disable(&adapter->rx_ring->napi);
+
+	igbvf_irq_disable(adapter);
+
+	del_timer_sync(&adapter->watchdog_timer);
+
+	netdev->tx_queue_len = adapter->tx_queue_len;
+	netif_carrier_off(netdev);
+
+	/* record the stats before reset*/
+	igbvf_update_stats(adapter);
+
+	adapter->link_speed = 0;
+	adapter->link_duplex = 0;
+
+	igbvf_reset(adapter);
+	igbvf_clean_tx_ring(adapter->tx_ring);
+	igbvf_clean_rx_ring(adapter->rx_ring);
+}
+
+void igbvf_reinit_locked(struct igbvf_adapter *adapter)
+{
+	might_sleep();
+	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+		msleep(1);
+	igbvf_down(adapter);
+	igbvf_up(adapter);
+	clear_bit(__IGBVF_RESETTING, &adapter->state);
+}
+
+/**
+ * igbvf_sw_init - Initialize general software structures (struct igbvf_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * igbvf_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	s32 rc;
+
+	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
+	adapter->rx_ps_hdr_size = 0;
+	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+	adapter->tx_int_delay = 8;
+	adapter->tx_abs_int_delay = 32;
+	adapter->rx_int_delay = 0;
+	adapter->rx_abs_int_delay = 8;
+	adapter->itr_setting = 3;
+	adapter->itr = 20000;
+
+	/* Set various function pointers */
+	adapter->ei->init_ops(&adapter->hw);
+
+	rc = adapter->hw.mac.ops.init_params(&adapter->hw);
+	if (rc)
+		return rc;
+
+	rc = adapter->hw.mbx.ops.init_params(&adapter->hw);
+	if (rc)
+		return rc;
+
+	igbvf_set_interrupt_capability(adapter);
+
+	if (igbvf_alloc_queues(adapter))
+		return -ENOMEM;
+
+	spin_lock_init(&adapter->tx_queue_lock);
+
+	/* Explicitly disable IRQ since the NIC can be in any state. */
+	igbvf_irq_disable(adapter);
+
+	spin_lock_init(&adapter->stats_lock);
+
+	set_bit(__IGBVF_DOWN, &adapter->state);
+	return 0;
+}
+
+static void igbvf_initialize_last_counter_stats(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	adapter->stats.last_gprc = er32(VFGPRC);
+	adapter->stats.last_gorc = er32(VFGORC);
+	adapter->stats.last_gptc = er32(VFGPTC);
+	adapter->stats.last_gotc = er32(VFGOTC);
+	adapter->stats.last_mprc = er32(VFMPRC);
+	adapter->stats.last_gotlbc = er32(VFGOTLBC);
+	adapter->stats.last_gptlbc = er32(VFGPTLBC);
+	adapter->stats.last_gorlbc = er32(VFGORLBC);
+	adapter->stats.last_gprlbc = er32(VFGPRLBC);
+
+	adapter->stats.base_gprc = er32(VFGPRC);
+	adapter->stats.base_gorc = er32(VFGORC);
+	adapter->stats.base_gptc = er32(VFGPTC);
+	adapter->stats.base_gotc = er32(VFGOTC);
+	adapter->stats.base_mprc = er32(VFMPRC);
+	adapter->stats.base_gotlbc = er32(VFGOTLBC);
+	adapter->stats.base_gptlbc = er32(VFGPTLBC);
+	adapter->stats.base_gorlbc = er32(VFGORLBC);
+	adapter->stats.base_gprlbc = er32(VFGPRLBC);
+}
+
+/**
+ * igbvf_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+static int igbvf_open(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	int err;
+
+	/* disallow open during test */
+	if (test_bit(__IGBVF_TESTING, &adapter->state))
+		return -EBUSY;
+
+	/* allocate transmit descriptors */
+	err = igbvf_setup_tx_resources(adapter, adapter->tx_ring);
+	if (err)
+		goto err_setup_tx;
+
+	/* allocate receive descriptors */
+	err = igbvf_setup_rx_resources(adapter, adapter->rx_ring);
+	if (err)
+		goto err_setup_rx;
+
+	/*
+	 * 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.
+	 */
+	igbvf_configure(adapter);
+
+	err = igbvf_request_irq(adapter);
+	if (err)
+		goto err_req_irq;
+
+	/* From here on the code is the same as igbvf_up() */
+	clear_bit(__IGBVF_DOWN, &adapter->state);
+
+	napi_enable(&adapter->rx_ring->napi);
+
+	/* clear any pending interrupts */
+	er32(EICR);
+
+	igbvf_irq_enable(adapter);
+
+	/* start the watchdog */
+	hw->mac.get_link_status = 1;
+	mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
+	return 0;
+
+err_req_irq:
+	igbvf_free_rx_resources(adapter->rx_ring);
+err_setup_rx:
+	igbvf_free_tx_resources(adapter->tx_ring);
+err_setup_tx:
+	igbvf_reset(adapter);
+
+	return err;
+}
+
+/**
+ * igbvf_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the drivers control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+static int igbvf_close(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+	igbvf_down(adapter);
+
+	igbvf_free_irq(adapter);
+
+	igbvf_free_tx_resources(adapter->tx_ring);
+	igbvf_free_rx_resources(adapter->rx_ring);
+
+	return 0;
+}
+/**
+ * igbvf_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_set_mac(struct net_device *netdev, void *p)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+	if (memcmp(addr->sa_data, hw->mac.addr, 6))
+		return -EADDRNOTAVAIL;
+
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+	return 0;
+}
+
+#define UPDATE_VF_COUNTER(reg, name)                                    \
+	{                                                               \
+		u32 current_counter = er32(reg);                        \
+		if (current_counter < adapter->stats.last_##name)       \
+			adapter->stats.name += 0x100000000LL;           \
+		adapter->stats.last_##name = current_counter;           \
+		adapter->stats.name &= 0xFFFFFFFF00000000LL;            \
+		adapter->stats.name |= current_counter;                 \
+	}
+
+/**
+ * igbvf_update_stats - Update the board statistics counters
+ * @adapter: board private structure
+**/
+void igbvf_update_stats(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct pci_dev *pdev = adapter->pdev;
+
+	/*
+	 * Prevent stats update while adapter is being reset, link is down
+	 * or if the pci connection is down.
+	 */
+	if (adapter->link_speed == 0)
+		return;
+
+	if (test_bit(__IGBVF_RESETTING, &adapter->state))
+		return;
+
+	if (pci_channel_offline(pdev))
+		return;
+
+	UPDATE_VF_COUNTER(VFGPRC, gprc);
+	UPDATE_VF_COUNTER(VFGORC, gorc);
+	UPDATE_VF_COUNTER(VFGPTC, gptc);
+	UPDATE_VF_COUNTER(VFGOTC, gotc);
+	UPDATE_VF_COUNTER(VFMPRC, mprc);
+	UPDATE_VF_COUNTER(VFGOTLBC, gotlbc);
+	UPDATE_VF_COUNTER(VFGPTLBC, gptlbc);
+	UPDATE_VF_COUNTER(VFGORLBC, gorlbc);
+	UPDATE_VF_COUNTER(VFGPRLBC, gprlbc);
+
+	/* Fill out the OS statistics structure */
+	adapter->net_stats.multicast = adapter->stats.mprc;
+}
+
+static void igbvf_print_link_info(struct igbvf_adapter *adapter)
+{
+	dev_info(&adapter->pdev->dev, "Link is Up %d Mbps %s\n",
+	         adapter->link_speed,
+	         ((adapter->link_duplex == FULL_DUPLEX) ?
+	          "Full Duplex" : "Half Duplex"));
+}
+
+static bool igbvf_has_link(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	s32 ret_val = E1000_SUCCESS;
+	bool link_active;
+
+	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)
+		schedule_work(&adapter->reset_task);
+
+	return link_active;
+}
+
+/**
+ * igbvf_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void igbvf_watchdog(unsigned long data)
+{
+	struct igbvf_adapter *adapter = (struct igbvf_adapter *) data;
+
+	/* Do the rest outside of interrupt context */
+	schedule_work(&adapter->watchdog_task);
+}
+
+static void igbvf_watchdog_task(struct work_struct *work)
+{
+	struct igbvf_adapter *adapter = container_of(work,
+	                                             struct igbvf_adapter,
+	                                             watchdog_task);
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_mac_info *mac = &adapter->hw.mac;
+	struct igbvf_ring *tx_ring = adapter->tx_ring;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 link;
+	int tx_pending = 0;
+
+	link = igbvf_has_link(adapter);
+
+	if (link) {
+		if (!netif_carrier_ok(netdev)) {
+			bool txb2b = 1;
+
+			mac->ops.get_link_up_info(&adapter->hw,
+			                          &adapter->link_speed,
+			                          &adapter->link_duplex);
+			igbvf_print_link_info(adapter);
+
+			/*
+			 * tweak tx_queue_len according to speed/duplex
+			 * and adjust the timeout factor
+			 */
+			netdev->tx_queue_len = adapter->tx_queue_len;
+			adapter->tx_timeout_factor = 1;
+			switch (adapter->link_speed) {
+			case SPEED_10:
+				txb2b = 0;
+				netdev->tx_queue_len = 10;
+				adapter->tx_timeout_factor = 16;
+				break;
+			case SPEED_100:
+				txb2b = 0;
+				netdev->tx_queue_len = 100;
+				/* maybe add some timeout factor ? */
+				break;
+			}
+
+			netif_carrier_on(netdev);
+			netif_wake_queue(netdev);
+		}
+	} else {
+		if (netif_carrier_ok(netdev)) {
+			adapter->link_speed = 0;
+			adapter->link_duplex = 0;
+			dev_info(&adapter->pdev->dev, "Link is Down\n");
+			netif_carrier_off(netdev);
+			netif_stop_queue(netdev);
+		}
+	}
+
+	if (netif_carrier_ok(netdev)) {
+		igbvf_update_stats(adapter);
+	} else {
+		tx_pending = (igbvf_desc_unused(tx_ring) + 1 <
+		              tx_ring->count);
+		if (tx_pending) {
+			/*
+			 * 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);
+		}
+	}
+
+	/* Cause software interrupt to ensure Rx ring is cleaned */
+	ew32(EICS, adapter->rx_ring->eims_value);
+
+	/* Force detection of hung controller every watchdog period */
+	adapter->detect_tx_hung = 1;
+
+	/* Reset the timer */
+	if (!test_bit(__IGBVF_DOWN, &adapter->state))
+		mod_timer(&adapter->watchdog_timer,
+			  round_jiffies(jiffies + (2 * HZ)));
+}
+
+#define IGBVF_TX_FLAGS_CSUM             0x00000001
+#define IGBVF_TX_FLAGS_VLAN             0x00000002
+#define IGBVF_TX_FLAGS_TSO              0x00000004
+#define IGBVF_TX_FLAGS_IPV4             0x00000008
+#define IGBVF_TX_FLAGS_VLAN_MASK        0xffff0000
+#define IGBVF_TX_FLAGS_VLAN_SHIFT       16
+
+static int igbvf_tso(struct igbvf_adapter *adapter,
+                     struct igbvf_ring *tx_ring,
+                     struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
+{
+	struct e1000_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	int err;
+	struct igbvf_buffer *buffer_info;
+	u32 info = 0, tu_cmd = 0;
+	u32 mss_l4len_idx, l4len;
+	*hdr_len = 0;
+
+	if (skb_header_cloned(skb)) {
+		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+		if (err) {
+			dev_err(&adapter->pdev->dev,
+			        "igbvf_tso returning an error\n");
+			return err;
+		}
+	}
+
+	l4len = tcp_hdrlen(skb);
+	*hdr_len += l4len;
+
+	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);
+	} 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);
+	}
+
+	i = tx_ring->next_to_use;
+
+	buffer_info = &tx_ring->buffer_info[i];
+	context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+	/* VLAN MACLEN IPLEN */
+	if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+		info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+	info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+	*hdr_len += skb_network_offset(skb);
+	info |= (skb_transport_header(skb) - skb_network_header(skb));
+	*hdr_len += (skb_transport_header(skb) - skb_network_header(skb));
+	context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+	/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
+	tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+	if (skb->protocol == htons(ETH_P_IP))
+		tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+	tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+
+	context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+
+	/* MSS L4LEN IDX */
+	mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
+	mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
+
+	context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+	context_desc->seqnum_seed = 0;
+
+	buffer_info->time_stamp = jiffies;
+	buffer_info->next_to_watch = i;
+	buffer_info->dma = 0;
+	i++;
+	if (i == tx_ring->count)
+		i = 0;
+
+	tx_ring->next_to_use = i;
+
+	return true;
+}
+
+static inline bool igbvf_tx_csum(struct igbvf_adapter *adapter,
+                                 struct igbvf_ring *tx_ring,
+                                 struct sk_buff *skb, u32 tx_flags)
+{
+	struct e1000_adv_tx_context_desc *context_desc;
+	unsigned int i;
+	struct igbvf_buffer *buffer_info;
+	u32 info = 0, tu_cmd = 0;
+
+	if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
+	    (tx_flags & IGBVF_TX_FLAGS_VLAN)) {
+		i = tx_ring->next_to_use;
+		buffer_info = &tx_ring->buffer_info[i];
+		context_desc = IGBVF_TX_CTXTDESC_ADV(*tx_ring, i);
+
+		if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+			info |= (tx_flags & IGBVF_TX_FLAGS_VLAN_MASK);
+
+		info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+		if (skb->ip_summed == CHECKSUM_PARTIAL)
+			info |= (skb_transport_header(skb) -
+			         skb_network_header(skb));
+
+
+		context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+		tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			switch (skb->protocol) {
+			case __constant_htons(ETH_P_IP):
+				tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+				break;
+			case __constant_htons(ETH_P_IPV6):
+				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+					tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+				break;
+			default:
+				break;
+			}
+		}
+
+		context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+		context_desc->seqnum_seed = 0;
+		context_desc->mss_l4len_idx = 0;
+
+		buffer_info->time_stamp = jiffies;
+		buffer_info->next_to_watch = i;
+		buffer_info->dma = 0;
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+		tx_ring->next_to_use = i;
+
+		return true;
+	}
+
+	return false;
+}
+
+static int igbvf_maybe_stop_tx(struct net_device *netdev, int size)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* there is enough descriptors then we don't need to worry  */
+	if (igbvf_desc_unused(adapter->tx_ring) >= size)
+		return 0;
+
+	netif_stop_queue(netdev);
+
+	smp_mb();
+
+	/* We need to check again just in case room has been made available */
+	if (igbvf_desc_unused(adapter->tx_ring) < size)
+		return -EBUSY;
+
+	netif_wake_queue(netdev);
+
+	++adapter->restart_queue;
+	return 0;
+}
+
+#define IGBVF_MAX_TXD_PWR       16
+#define IGBVF_MAX_DATA_PER_TXD  (1 << IGBVF_MAX_TXD_PWR)
+
+static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
+                                   struct igbvf_ring *tx_ring,
+                                   struct sk_buff *skb,
+                                   unsigned int first)
+{
+	struct igbvf_buffer *buffer_info;
+	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 = map[count];
+	count++;
+
+	for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+		struct skb_frag_struct *frag;
+
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+
+		frag = &skb_shinfo(skb)->frags[f];
+		len = frag->size;
+
+		buffer_info = &tx_ring->buffer_info[i];
+		BUG_ON(len >= IGBVF_MAX_DATA_PER_TXD);
+		buffer_info->length = len;
+		buffer_info->time_stamp = jiffies;
+		buffer_info->next_to_watch = i;
+		buffer_info->dma = map[count];
+		count++;
+	}
+
+	tx_ring->buffer_info[i].skb = skb;
+	tx_ring->buffer_info[first].next_to_watch = i;
+
+	return count;
+}
+
+static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
+                                      struct igbvf_ring *tx_ring,
+                                      int tx_flags, int count, u32 paylen,
+                                      u8 hdr_len)
+{
+	union e1000_adv_tx_desc *tx_desc = NULL;
+	struct igbvf_buffer *buffer_info;
+	u32 olinfo_status = 0, cmd_type_len;
+	unsigned int i;
+
+	cmd_type_len = (E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS |
+	                E1000_ADVTXD_DCMD_DEXT);
+
+	if (tx_flags & IGBVF_TX_FLAGS_VLAN)
+		cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+
+	if (tx_flags & IGBVF_TX_FLAGS_TSO) {
+		cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
+
+		/* insert tcp checksum */
+		olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+
+		/* insert ip checksum */
+		if (tx_flags & IGBVF_TX_FLAGS_IPV4)
+			olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
+
+	} else if (tx_flags & IGBVF_TX_FLAGS_CSUM) {
+		olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+	}
+
+	olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
+
+	i = tx_ring->next_to_use;
+	while (count--) {
+		buffer_info = &tx_ring->buffer_info[i];
+		tx_desc = IGBVF_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);
+		i++;
+		if (i == tx_ring->count)
+			i = 0;
+	}
+
+	tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+	/* Force memory writes to complete before letting h/w
+	 * know there are new descriptors to fetch.  (Only
+	 * applicable for weak-ordered memory model archs,
+	 * such as IA-64). */
+	wmb();
+
+	tx_ring->next_to_use = i;
+	writel(i, adapter->hw.hw_addr + 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 igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
+                                   struct net_device *netdev,
+                                   struct igbvf_ring *tx_ring)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	unsigned int first, tx_flags = 0;
+	u8 hdr_len = 0;
+	int count = 0;
+	int tso = 0;
+
+	if (test_bit(__IGBVF_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;
+	}
+
+	/*
+	 * need: count + 4 desc gap to keep tail from touching
+         *       + 2 desc gap to keep tail from touching head,
+         *       + 1 desc for skb->data,
+         *       + 1 desc for context descriptor,
+	 * head, otherwise try next time
+	 */
+	if (igbvf_maybe_stop_tx(netdev, skb_shinfo(skb)->nr_frags + 4)) {
+		/* this is a hard error */
+		return NETDEV_TX_BUSY;
+	}
+
+	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+		tx_flags |= IGBVF_TX_FLAGS_VLAN;
+		tx_flags |= (vlan_tx_tag_get(skb) << IGBVF_TX_FLAGS_VLAN_SHIFT);
+	}
+
+	if (skb->protocol == htons(ETH_P_IP))
+		tx_flags |= IGBVF_TX_FLAGS_IPV4;
+
+	first = tx_ring->next_to_use;
+
+	tso = skb_is_gso(skb) ?
+		igbvf_tso(adapter, tx_ring, skb, tx_flags, &hdr_len) : 0;
+	if (unlikely(tso < 0)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (tso)
+		tx_flags |= IGBVF_TX_FLAGS_TSO;
+	else if (igbvf_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+	         (skb->ip_summed == CHECKSUM_PARTIAL))
+		tx_flags |= IGBVF_TX_FLAGS_CSUM;
+
+	/*
+	 * count reflects descriptors mapped, if 0 then mapping error
+	 * has occured and we need to rewind the descriptor queue
+	 */
+	count = igbvf_tx_map_adv(adapter, tx_ring, skb, first);
+
+	if (count) {
+		igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count,
+		                   skb->len, hdr_len);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct igbvf_ring *tx_ring;
+	int retval;
+
+	if (test_bit(__IGBVF_DOWN, &adapter->state)) {
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+
+	tx_ring = &adapter->tx_ring[0];
+
+	retval = igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
+
+	return retval;
+}
+
+/**
+ * igbvf_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+static void igbvf_tx_timeout(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* Do the reset outside of interrupt context */
+	adapter->tx_timeout_count++;
+	schedule_work(&adapter->reset_task);
+}
+
+static void igbvf_reset_task(struct work_struct *work)
+{
+	struct igbvf_adapter *adapter;
+	adapter = container_of(work, struct igbvf_adapter, reset_task);
+
+	igbvf_reinit_locked(adapter);
+}
+
+/**
+ * igbvf_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 *igbvf_get_stats(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	/* only return the current stats */
+	return &adapter->net_stats;
+}
+
+/**
+ * igbvf_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+
+	if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+		dev_err(&adapter->pdev->dev, "Invalid MTU setting\n");
+		return -EINVAL;
+	}
+
+	/* Jumbo frame size limits */
+	if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+			dev_err(&adapter->pdev->dev,
+			        "Jumbo Frames not supported.\n");
+			return -EINVAL;
+		}
+	}
+
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
+	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+		dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
+		return -EINVAL;
+	}
+
+	while (test_and_set_bit(__IGBVF_RESETTING, &adapter->state))
+		msleep(1);
+	/* igbvf_down has a dependency on max_frame_size */
+	adapter->max_frame_size = max_frame;
+	if (netif_running(netdev))
+		igbvf_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
+	 * larger slab size.
+	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 * However with the new *_jumbo_rx* routines, jumbo receives will use
+	 * fragmented skbs
+	 */
+
+	if (max_frame <= 1024)
+		adapter->rx_buffer_len = 1024;
+	else if (max_frame <= 2048)
+		adapter->rx_buffer_len = 2048;
+	else
+#if (PAGE_SIZE / 2) > 16384
+		adapter->rx_buffer_len = 16384;
+#else
+		adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
+
+
+	/* adjust allocation if LPE protects us, and we aren't using SBP */
+	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
+	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
+		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN +
+		                         ETH_FCS_LEN;
+
+	dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
+	         netdev->mtu, new_mtu);
+	netdev->mtu = new_mtu;
+
+	if (netif_running(netdev))
+		igbvf_up(adapter);
+	else
+		igbvf_reset(adapter);
+
+	clear_bit(__IGBVF_RESETTING, &adapter->state);
+
+	return 0;
+}
+
+static int igbvf_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	switch (cmd) {
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int igbvf_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+	int retval = 0;
+#endif
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		WARN_ON(test_bit(__IGBVF_RESETTING, &adapter->state));
+		igbvf_down(adapter);
+		igbvf_free_irq(adapter);
+	}
+
+#ifdef CONFIG_PM
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+#endif
+
+	pci_disable_device(pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int igbvf_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	u32 err;
+
+	pci_restore_state(pdev);
+	err = pci_enable_device_mem(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
+		return err;
+	}
+
+	pci_set_master(pdev);
+
+	if (netif_running(netdev)) {
+		err = igbvf_request_irq(adapter);
+		if (err)
+			return err;
+	}
+
+	igbvf_reset(adapter);
+
+	if (netif_running(netdev))
+		igbvf_up(adapter);
+
+	netif_device_attach(netdev);
+
+	return 0;
+}
+#endif
+
+static void igbvf_shutdown(struct pci_dev *pdev)
+{
+	igbvf_suspend(pdev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void igbvf_netpoll(struct net_device *netdev)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	disable_irq(adapter->pdev->irq);
+
+	igbvf_clean_tx_irq(adapter->tx_ring);
+
+	enable_irq(adapter->pdev->irq);
+}
+#endif
+
+/**
+ * igbvf_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t igbvf_io_error_detected(struct pci_dev *pdev,
+                                                pci_channel_state_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		igbvf_down(adapter);
+	pci_disable_device(pdev);
+
+	/* Request a slot slot reset. */
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * igbvf_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the igbvf_resume routine.
+ */
+static pci_ers_result_t igbvf_io_slot_reset(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (pci_enable_device_mem(pdev)) {
+		dev_err(&pdev->dev,
+			"Cannot re-enable PCI device after reset.\n");
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+	pci_set_master(pdev);
+
+	igbvf_reset(adapter);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * igbvf_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the igbvf_resume routine.
+ */
+static void igbvf_io_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (netif_running(netdev)) {
+		if (igbvf_up(adapter)) {
+			dev_err(&pdev->dev,
+				"can't bring device back up after reset\n");
+			return;
+		}
+	}
+
+	netif_device_attach(netdev);
+}
+
+static void igbvf_print_device_info(struct igbvf_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	dev_info(&pdev->dev, "Intel(R) 82576 Virtual Function\n");
+	dev_info(&pdev->dev, "Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+	         /* MAC address */
+	         netdev->dev_addr[0], netdev->dev_addr[1],
+	         netdev->dev_addr[2], netdev->dev_addr[3],
+	         netdev->dev_addr[4], netdev->dev_addr[5]);
+	dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
+}
+
+static const struct net_device_ops igbvf_netdev_ops = {
+	.ndo_open                       = igbvf_open,
+	.ndo_stop                       = igbvf_close,
+	.ndo_start_xmit                 = igbvf_xmit_frame,
+	.ndo_get_stats                  = igbvf_get_stats,
+	.ndo_set_multicast_list         = igbvf_set_multi,
+	.ndo_set_mac_address            = igbvf_set_mac,
+	.ndo_change_mtu                 = igbvf_change_mtu,
+	.ndo_do_ioctl                   = igbvf_ioctl,
+	.ndo_tx_timeout                 = igbvf_tx_timeout,
+	.ndo_vlan_rx_register           = igbvf_vlan_rx_register,
+	.ndo_vlan_rx_add_vid            = igbvf_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid           = igbvf_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller            = igbvf_netpoll,
+#endif
+};
+
+/**
+ * igbvf_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in igbvf_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * igbvf_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+static int __devinit igbvf_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+	struct net_device *netdev;
+	struct igbvf_adapter *adapter;
+	struct e1000_hw *hw;
+	const struct igbvf_info *ei = igbvf_info_tbl[ent->driver_data];
+
+	static int cards_found;
+	int err, pci_using_dac;
+
+	err = pci_enable_device_mem(pdev);
+	if (err)
+		return err;
+
+	pci_using_dac = 0;
+	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	if (!err) {
+		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		if (!err)
+			pci_using_dac = 1;
+	} else {
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			if (err) {
+				dev_err(&pdev->dev, "No usable DMA "
+				        "configuration, aborting\n");
+				goto err_dma;
+			}
+		}
+	}
+
+	err = pci_request_regions(pdev, igbvf_driver_name);
+	if (err)
+		goto err_pci_reg;
+
+	pci_set_master(pdev);
+
+	err = -ENOMEM;
+	netdev = alloc_etherdev(sizeof(struct igbvf_adapter));
+	if (!netdev)
+		goto err_alloc_etherdev;
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	pci_set_drvdata(pdev, netdev);
+	adapter = netdev_priv(netdev);
+	hw = &adapter->hw;
+	adapter->netdev = netdev;
+	adapter->pdev = pdev;
+	adapter->ei = ei;
+	adapter->pba = ei->pba;
+	adapter->flags = ei->flags;
+	adapter->hw.back = adapter;
+	adapter->hw.mac.type = ei->mac;
+	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+
+	/* PCI config space info */
+
+	hw->vendor_id = pdev->vendor;
+	hw->device_id = pdev->device;
+	hw->subsystem_vendor_id = pdev->subsystem_vendor;
+	hw->subsystem_device_id = pdev->subsystem_device;
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+
+	err = -EIO;
+	adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0),
+	                              pci_resource_len(pdev, 0));
+
+	if (!adapter->hw.hw_addr)
+		goto err_ioremap;
+
+	if (ei->get_variants) {
+		err = ei->get_variants(adapter);
+		if (err)
+			goto err_ioremap;
+	}
+
+	/* setup adapter struct */
+	err = igbvf_sw_init(adapter);
+	if (err)
+		goto err_sw_init;
+
+	/* construct the net_device struct */
+	netdev->netdev_ops = &igbvf_netdev_ops;
+
+	igbvf_set_ethtool_ops(netdev);
+	netdev->watchdog_timeo = 5 * HZ;
+	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+	adapter->bd_number = cards_found++;
+
+	netdev->features = NETIF_F_SG |
+	                   NETIF_F_IP_CSUM |
+	                   NETIF_F_HW_VLAN_TX |
+	                   NETIF_F_HW_VLAN_RX |
+	                   NETIF_F_HW_VLAN_FILTER;
+
+	netdev->features |= NETIF_F_IPV6_CSUM;
+	netdev->features |= NETIF_F_TSO;
+	netdev->features |= NETIF_F_TSO6;
+
+	if (pci_using_dac)
+		netdev->features |= NETIF_F_HIGHDMA;
+
+	netdev->vlan_features |= NETIF_F_TSO;
+	netdev->vlan_features |= NETIF_F_TSO6;
+	netdev->vlan_features |= NETIF_F_IP_CSUM;
+	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
+	netdev->vlan_features |= NETIF_F_SG;
+
+	/*reset the controller to put the device in a known good state */
+	err = hw->mac.ops.reset_hw(hw);
+	if (err) {
+		dev_info(&pdev->dev,
+		         "PF still in reset state, assigning new address\n");
+		random_ether_addr(hw->mac.addr);
+	} else {
+		err = hw->mac.ops.read_mac_addr(hw);
+		if (err) {
+			dev_err(&pdev->dev, "Error reading MAC address\n");
+			goto err_hw_init;
+		}
+	}
+
+	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
+	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+
+	if (!is_valid_ether_addr(netdev->perm_addr)) {
+		dev_err(&pdev->dev, "Invalid MAC Address: "
+		        "%02x:%02x:%02x:%02x:%02x:%02x\n",
+		        netdev->dev_addr[0], netdev->dev_addr[1],
+		        netdev->dev_addr[2], netdev->dev_addr[3],
+		        netdev->dev_addr[4], netdev->dev_addr[5]);
+		err = -EIO;
+		goto err_hw_init;
+	}
+
+	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
+	            (unsigned long) adapter);
+
+	INIT_WORK(&adapter->reset_task, igbvf_reset_task);
+	INIT_WORK(&adapter->watchdog_task, igbvf_watchdog_task);
+
+	/* ring size defaults */
+	adapter->rx_ring->count = 1024;
+	adapter->tx_ring->count = 1024;
+
+	/* reset the hardware with the new settings */
+	igbvf_reset(adapter);
+
+	/* tell the stack to leave us alone until igbvf_open() is called */
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	strcpy(netdev->name, "eth%d");
+	err = register_netdev(netdev);
+	if (err)
+		goto err_hw_init;
+
+	igbvf_print_device_info(adapter);
+
+	igbvf_initialize_last_counter_stats(adapter);
+
+	return 0;
+
+err_hw_init:
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+err_sw_init:
+	igbvf_reset_interrupt_capability(adapter);
+	iounmap(adapter->hw.hw_addr);
+err_ioremap:
+	free_netdev(netdev);
+err_alloc_etherdev:
+	pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+	pci_disable_device(pdev);
+	return err;
+}
+
+/**
+ * igbvf_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * igbvf_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.  The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ **/
+static void __devexit igbvf_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	/*
+	 * flush_scheduled work may reschedule our watchdog task, so
+	 * explicitly disable watchdog tasks from being rescheduled
+	 */
+	set_bit(__IGBVF_DOWN, &adapter->state);
+	del_timer_sync(&adapter->watchdog_timer);
+
+	flush_scheduled_work();
+
+	unregister_netdev(netdev);
+
+	igbvf_reset_interrupt_capability(adapter);
+
+	/*
+	 * it is important to delete the napi struct prior to freeing the
+	 * rx ring so that you do not end up with null pointer refs
+	 */
+	netif_napi_del(&adapter->rx_ring->napi);
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+
+	iounmap(hw->hw_addr);
+	if (hw->flash_address)
+		iounmap(hw->flash_address);
+	pci_release_regions(pdev);
+
+	free_netdev(netdev);
+
+	pci_disable_device(pdev);
+}
+
+/* PCI Error Recovery (ERS) */
+static struct pci_error_handlers igbvf_err_handler = {
+	.error_detected = igbvf_io_error_detected,
+	.slot_reset = igbvf_io_slot_reset,
+	.resume = igbvf_io_resume,
+};
+
+static struct pci_device_id igbvf_pci_tbl[] = {
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_VF), board_vf },
+	{ } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, igbvf_pci_tbl);
+
+/* PCI Device API Driver */
+static struct pci_driver igbvf_driver = {
+	.name     = igbvf_driver_name,
+	.id_table = igbvf_pci_tbl,
+	.probe    = igbvf_probe,
+	.remove   = __devexit_p(igbvf_remove),
+#ifdef CONFIG_PM
+	/* Power Management Hooks */
+	.suspend  = igbvf_suspend,
+	.resume   = igbvf_resume,
+#endif
+	.shutdown = igbvf_shutdown,
+	.err_handler = &igbvf_err_handler
+};
+
+/**
+ * igbvf_init_module - Driver Registration Routine
+ *
+ * igbvf_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+static int __init igbvf_init_module(void)
+{
+	int ret;
+	printk(KERN_INFO "%s - version %s\n",
+	       igbvf_driver_string, igbvf_driver_version);
+	printk(KERN_INFO "%s\n", igbvf_copyright);
+
+	ret = pci_register_driver(&igbvf_driver);
+	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name,
+	                       PM_QOS_DEFAULT_VALUE);
+
+	return ret;
+}
+module_init(igbvf_init_module);
+
+/**
+ * igbvf_exit_module - Driver Exit Cleanup Routine
+ *
+ * igbvf_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+static void __exit igbvf_exit_module(void)
+{
+	pci_unregister_driver(&igbvf_driver);
+	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name);
+}
+module_exit(igbvf_exit_module);
+
+
+MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
+MODULE_DESCRIPTION("Intel(R) 82576 Virtual Function Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+/* netdev.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/regs.h linux-libre-2.6.30-gnu1/drivers/net/igbvf/regs.h
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/regs.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,108 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_REGS_H_
+#define _E1000_REGS_H_
+
+#define E1000_CTRL      0x00000 /* Device Control - RW */
+#define E1000_STATUS    0x00008 /* Device Status - RO */
+#define E1000_ITR       0x000C4 /* Interrupt Throttling Rate - RW */
+#define E1000_EICR      0x01580 /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n)  (0x01680 + (0x4 * (_n)))
+#define E1000_EICS      0x01520 /* Ext. Interrupt Cause Set - W0 */
+#define E1000_EIMS      0x01524 /* Ext. Interrupt Mask Set/Read - RW */
+#define E1000_EIMC      0x01528 /* Ext. Interrupt Mask Clear - WO */
+#define E1000_EIAC      0x0152C /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAM      0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_IVAR0     0x01700 /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
+/*
+ * Convenience macros
+ *
+ * Note: "_n" is the queue number of the register to be written to.
+ *
+ * Example usage:
+ * E1000_RDBAL_REG(current_rx_queue)
+ */
+#define E1000_RDBAL(_n)      ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : \
+                                         (0x0C000 + ((_n) * 0x40)))
+#define E1000_RDBAH(_n)      ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : \
+                                         (0x0C004 + ((_n) * 0x40)))
+#define E1000_RDLEN(_n)      ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : \
+                                         (0x0C008 + ((_n) * 0x40)))
+#define E1000_SRRCTL(_n)     ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
+                                         (0x0C00C + ((_n) * 0x40)))
+#define E1000_RDH(_n)        ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : \
+                                         (0x0C010 + ((_n) * 0x40)))
+#define E1000_RDT(_n)        ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : \
+                                         (0x0C018 + ((_n) * 0x40)))
+#define E1000_RXDCTL(_n)     ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
+                                         (0x0C028 + ((_n) * 0x40)))
+#define E1000_TDBAL(_n)      ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : \
+                                         (0x0E000 + ((_n) * 0x40)))
+#define E1000_TDBAH(_n)      ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : \
+                                         (0x0E004 + ((_n) * 0x40)))
+#define E1000_TDLEN(_n)      ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : \
+                                         (0x0E008 + ((_n) * 0x40)))
+#define E1000_TDH(_n)        ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : \
+                                         (0x0E010 + ((_n) * 0x40)))
+#define E1000_TDT(_n)        ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : \
+                                         (0x0E018 + ((_n) * 0x40)))
+#define E1000_TXDCTL(_n)     ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : \
+                                         (0x0E028 + ((_n) * 0x40)))
+#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
+#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#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)))
+
+/* Statistics registers */
+#define E1000_VFGPRC    0x00F10
+#define E1000_VFGORC    0x00F18
+#define E1000_VFMPRC    0x00F3C
+#define E1000_VFGPTC    0x00F14
+#define E1000_VFGOTC    0x00F34
+#define E1000_VFGOTLBC  0x00F50
+#define E1000_VFGPTLBC  0x00F44
+#define E1000_VFGORLBC  0x00F48
+#define E1000_VFGPRLBC  0x00F40
+
+/* These act per VF so an array friendly macro is used */
+#define E1000_V2PMAILBOX(_n)   (0x00C40 + (4 * (_n)))
+#define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n)))
+
+/* Define macros for handling registers */
+#define er32(reg) readl(hw->hw_addr + E1000_##reg)
+#define ew32(reg, val) writel((val), hw->hw_addr +  E1000_##reg)
+#define array_er32(reg, offset) \
+	readl(hw->hw_addr + E1000_##reg + (offset << 2))
+#define array_ew32(reg, offset, val) \
+	writel((val), hw->hw_addr +  E1000_##reg + (offset << 2))
+#define e1e_flush() er32(STATUS)
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/vf.c linux-libre-2.6.30-gnu1/drivers/net/igbvf/vf.c
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/vf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/vf.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,398 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+
+#include "vf.h"
+
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+                                     u16 *duplex);
+static s32 e1000_init_hw_vf(struct e1000_hw *hw);
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
+
+static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *,
+                                         u32, u32, u32);
+static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
+static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool);
+
+/**
+ *  e1000_init_mac_params_vf - Inits MAC params
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+
+	/* VF's have no MTA Registers - PF feature only */
+	mac->mta_reg_count = 128;
+	/* VF's have no access to RAR entries  */
+	mac->rar_entry_count = 1;
+
+	/* Function pointers */
+	/* reset */
+	mac->ops.reset_hw = e1000_reset_hw_vf;
+	/* hw initialization */
+	mac->ops.init_hw = e1000_init_hw_vf;
+	/* check for link */
+	mac->ops.check_for_link = e1000_check_for_link_vf;
+	/* link info */
+	mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
+	/* multicast address update */
+	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
+	/* set mac address */
+	mac->ops.rar_set = e1000_rar_set_vf;
+	/* read mac address */
+	mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
+	/* set vlan filter table array */
+	mac->ops.set_vfta = e1000_set_vfta_vf;
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_init_function_pointers_vf - Inits function pointers
+ *  @hw: pointer to the HW structure
+ **/
+void e1000_init_function_pointers_vf(struct e1000_hw *hw)
+{
+	hw->mac.ops.init_params = e1000_init_mac_params_vf;
+	hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
+}
+
+/**
+ *  e1000_get_link_up_info_vf - Gets link info.
+ *  @hw: pointer to the HW structure
+ *  @speed: pointer to 16 bit value to store link speed.
+ *  @duplex: pointer to 16 bit value to store duplex.
+ *
+ *  Since we cannot read the PHY and get accurate link info, we must rely upon
+ *  the status register's data which is often stale and inaccurate.
+ **/
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+                                     u16 *duplex)
+{
+	s32 status;
+
+	status = er32(STATUS);
+	if (status & E1000_STATUS_SPEED_1000)
+		*speed = SPEED_1000;
+	else if (status & E1000_STATUS_SPEED_100)
+		*speed = SPEED_100;
+	else
+		*speed = SPEED_10;
+
+	if (status & E1000_STATUS_FD)
+		*duplex = FULL_DUPLEX;
+	else
+		*duplex = HALF_DUPLEX;
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_reset_hw_vf - Resets the HW
+ *  @hw: pointer to the HW structure
+ *
+ *  VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
+ *  This is all the reset we can perform on a VF.
+ **/
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 timeout = E1000_VF_INIT_TIMEOUT;
+	u32 ret_val = -E1000_ERR_MAC_INIT;
+	u32 msgbuf[3];
+	u8 *addr = (u8 *)(&msgbuf[1]);
+	u32 ctrl;
+
+	/* assert vf queue/interrupt reset */
+	ctrl = er32(CTRL);
+	ew32(CTRL, ctrl | E1000_CTRL_RST);
+
+	/* we cannot initialize while the RSTI / RSTD bits are asserted */
+	while (!mbx->ops.check_for_rst(hw) && timeout) {
+		timeout--;
+		udelay(5);
+	}
+
+	if (timeout) {
+		/* mailbox timeout can now become active */
+		mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
+
+		/* notify pf of vf reset completion */
+		msgbuf[0] = E1000_VF_RESET;
+		mbx->ops.write_posted(hw, msgbuf, 1);
+
+		msleep(10);
+
+		/* set our "perm_addr" based on info provided by PF */
+		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+		if (!ret_val) {
+			if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK))
+				memcpy(hw->mac.perm_addr, addr, 6);
+			else
+				ret_val = -E1000_ERR_MAC_INIT;
+		}
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000_init_hw_vf - Inits the HW
+ *  @hw: pointer to the HW structure
+ *
+ *  Not much to do here except clear the PF Reset indication if there is one.
+ **/
+static s32 e1000_init_hw_vf(struct e1000_hw *hw)
+{
+	/* attempt to set and restore our mac address */
+	e1000_rar_set_vf(hw, hw->mac.addr, 0);
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_hash_mc_addr_vf - Generate a multicast hash value
+ *  @hw: pointer to the HW structure
+ *  @mc_addr: pointer to a multicast address
+ *
+ *  Generates a multicast address hash value which is used to determine
+ *  the multicast filter table array address and new table value.  See
+ *  e1000_mta_set_generic()
+ **/
+static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
+{
+	u32 hash_value, hash_mask;
+	u8 bit_shift = 0;
+
+	/* Register count multiplied by bits per register */
+	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
+
+	/*
+	 * The bit_shift is the number of left-shifts
+	 * where 0xFF would still fall within the hash mask.
+	 */
+	while (hash_mask >> bit_shift != 0xFF)
+		bit_shift++;
+
+	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
+	                          (((u16) mc_addr[5]) << bit_shift)));
+
+	return hash_value;
+}
+
+/**
+ *  e1000_update_mc_addr_list_vf - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *  @rar_used_count: the first RAR register free to program
+ *  @rar_count: total number of supported Receive Address Registers
+ *
+ *  Updates the Receive Address Registers and Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ *  The parameter rar_count will usually be hw->mac.rar_entry_count
+ *  unless there are workarounds that change this.
+ **/
+void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
+                                  u8 *mc_addr_list, u32 mc_addr_count,
+                                  u32 rar_used_count, u32 rar_count)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[E1000_VFMAILBOX_SIZE];
+	u16 *hash_list = (u16 *)&msgbuf[1];
+	u32 hash_value;
+	u32 cnt, i;
+
+	/* Each entry in the list uses 1 16 bit word.  We have 30
+	 * 16 bit words available in our HW msg buffer (minus 1 for the
+	 * msg type).  That's 30 hash values if we pack 'em right.  If
+	 * there are more than 30 MC addresses to add then punt the
+	 * extras for now and then add code to handle more than 30 later.
+	 * It would be unusual for a server to request that many multi-cast
+	 * addresses except for in large enterprise network environments.
+	 */
+
+	cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
+	msgbuf[0] = E1000_VF_SET_MULTICAST;
+	msgbuf[0] |= cnt << E1000_VT_MSGINFO_SHIFT;
+
+	for (i = 0; i < cnt; i++) {
+		hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
+		hash_list[i] = hash_value & 0x0FFFF;
+		mc_addr_list += ETH_ADDR_LEN;
+	}
+
+	mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE);
+}
+
+/**
+ *  e1000_set_vfta_vf - Set/Unset vlan filter table address
+ *  @hw: pointer to the HW structure
+ *  @vid: determines the vfta register and bit to set/unset
+ *  @set: if true then set bit, else clear bit
+ **/
+static s32 e1000_set_vfta_vf(struct e1000_hw *hw, u16 vid, bool set)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[2];
+	s32 err;
+
+	msgbuf[0] = E1000_VF_SET_VLAN;
+	msgbuf[1] = vid;
+	/* Setting the 8 bit field MSG INFO to true indicates "add" */
+	if (set)
+		msgbuf[0] |= 1 << E1000_VT_MSGINFO_SHIFT;
+
+	mbx->ops.write_posted(hw, msgbuf, 2);
+
+	err = mbx->ops.read_posted(hw, msgbuf, 2);
+
+	/* if nacked the vlan was rejected */
+	if (!err && (msgbuf[0] == (E1000_VF_SET_VLAN | E1000_VT_MSGTYPE_NACK)))
+		err = -E1000_ERR_MAC_INIT;
+
+	return err;
+}
+
+/** e1000_rlpml_set_vf - Set the maximum receive packet length
+ *  @hw: pointer to the HW structure
+ *  @max_size: value to assign to max frame size
+ **/
+void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[2];
+
+	msgbuf[0] = E1000_VF_SET_LPE;
+	msgbuf[1] = max_size;
+
+	mbx->ops.write_posted(hw, msgbuf, 2);
+}
+
+/**
+ *  e1000_rar_set_vf - set device MAC address
+ *  @hw: pointer to the HW structure
+ *  @addr: pointer to the receive address
+ *  @index receive address array register
+ **/
+static void e1000_rar_set_vf(struct e1000_hw *hw, u8 * addr, u32 index)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[3];
+	u8 *msg_addr = (u8 *)(&msgbuf[1]);
+	s32 ret_val;
+
+	memset(msgbuf, 0, 12);
+	msgbuf[0] = E1000_VF_SET_MAC_ADDR;
+	memcpy(msg_addr, addr, 6);
+	ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+	if (!ret_val)
+		ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+	/* if nacked the address was rejected, use "perm_addr" */
+	if (!ret_val &&
+	    (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
+		e1000_read_mac_addr_vf(hw);
+}
+
+/**
+ *  e1000_read_mac_addr_vf - Read device MAC address
+ *  @hw: pointer to the HW structure
+ **/
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
+{
+	int i;
+
+	for (i = 0; i < ETH_ADDR_LEN; i++)
+		hw->mac.addr[i] = hw->mac.perm_addr[i];
+
+	return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_check_for_link_vf - Check for link for a virtual interface
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks to see if the underlying PF is still talking to the VF and
+ *  if it is then it reports the link state to the hardware, otherwise
+ *  it reports link down and returns an error.
+ **/
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
+{
+	struct e1000_mbx_info *mbx = &hw->mbx;
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val = E1000_SUCCESS;
+	u32 in_msg = 0;
+
+	/*
+	 * We only want to run this if there has been a rst asserted.
+	 * in this case that could mean a link change, device reset,
+	 * or a virtual function reset
+	 */
+
+	/* If we were hit with a reset drop the link */
+	if (!mbx->ops.check_for_rst(hw))
+		mac->get_link_status = true;
+
+	if (!mac->get_link_status)
+		goto out;
+
+	/* if link status is down no point in checking to see if pf is up */
+	if (!(er32(STATUS) & E1000_STATUS_LU))
+		goto out;
+
+	/* if the read failed it could just be a mailbox collision, best wait
+	 * until we are called again and don't report an error */
+	if (mbx->ops.read(hw, &in_msg, 1))
+		goto out;
+
+	/* if incoming message isn't clear to send we are waiting on response */
+	if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
+		/* message is not CTS and is NACK we must have lost CTS status */
+		if (in_msg & E1000_VT_MSGTYPE_NACK)
+			ret_val = -E1000_ERR_MAC_INIT;
+		goto out;
+	}
+
+	/* the pf is talking, if we timed out in the past we reinit */
+	if (!mbx->timeout) {
+		ret_val = -E1000_ERR_MAC_INIT;
+		goto out;
+	}
+
+	/* if we passed all the tests above then the link is up and we no
+	 * longer need to check for link */
+	mac->get_link_status = false;
+
+out:
+	return ret_val;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/igbvf/vf.h linux-libre-2.6.30-gnu1/drivers/net/igbvf/vf.h
--- linux-libre-2.6.29-gnu1/drivers/net/igbvf/vf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/igbvf/vf.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,264 @@
+/*******************************************************************************
+
+  Intel(R) 82576 Virtual Function Linux driver
+  Copyright(c) 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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_VF_H_
+#define _E1000_VF_H_
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "regs.h"
+#include "defines.h"
+
+struct e1000_hw;
+
+#define E1000_DEV_ID_82576_VF                 0x10CA
+#define E1000_REVISION_0 0
+#define E1000_REVISION_1 1
+#define E1000_REVISION_2 2
+#define E1000_REVISION_3 3
+#define E1000_REVISION_4 4
+
+#define E1000_FUNC_0     0
+#define E1000_FUNC_1     1
+
+/*
+ * Receive Address Register Count
+ * Number of high/low register pairs in the RAR.  The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor.
+ * These entries are also used for MAC-based filtering.
+ */
+#define E1000_RAR_ENTRIES_VF      1
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+	struct {
+		u64 pkt_addr;             /* Packet buffer address */
+		u64 hdr_addr;             /* Header buffer address */
+	} read;
+	struct {
+		struct {
+			union {
+				u32 data;
+				struct {
+					u16 pkt_info; /* RSS/Packet type */
+					u16 hdr_info; /* Split Header,
+					               * hdr buffer length */
+				} hs_rss;
+			} lo_dword;
+			union {
+				u32 rss;          /* RSS Hash */
+				struct {
+					u16 ip_id;    /* IP id */
+					u16 csum;     /* Packet Checksum */
+				} csum_ip;
+			} hi_dword;
+		} lower;
+		struct {
+			u32 status_error;     /* ext status/error */
+			u16 length;           /* Packet length */
+			u16 vlan;             /* VLAN tag */
+		} upper;
+	} wb;  /* writeback */
+};
+
+#define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
+#define E1000_RXDADV_HDRBUFLEN_SHIFT     5
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+	struct {
+		u64 buffer_addr;    /* Address of descriptor's data buf */
+		u32 cmd_type_len;
+		u32 olinfo_status;
+	} read;
+	struct {
+		u64 rsvd;       /* Reserved */
+		u32 nxtseq_seed;
+		u32 status;
+	} wb;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_EOP     0x01000000 /* End of Packet */
+#define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_RS      0x08000000 /* Report Status */
+#define E1000_ADVTXD_DCMD_DEXT    0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE     0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE     0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+
+/* Context descriptors */
+struct e1000_adv_tx_context_desc {
+	u32 vlan_macip_lens;
+	u32 seqnum_seed;
+	u32 type_tucmd_mlhl;
+	u32 mss_l4len_idx;
+};
+
+#define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
+#define E1000_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */
+#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
+#define E1000_ADVTXD_MSS_SHIFT      16  /* Adv ctxt MSS shift */
+
+enum e1000_mac_type {
+	e1000_undefined = 0,
+	e1000_vfadapt,
+	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
+};
+
+struct e1000_vf_stats {
+	u64 base_gprc;
+	u64 base_gptc;
+	u64 base_gorc;
+	u64 base_gotc;
+	u64 base_mprc;
+	u64 base_gotlbc;
+	u64 base_gptlbc;
+	u64 base_gorlbc;
+	u64 base_gprlbc;
+
+	u32 last_gprc;
+	u32 last_gptc;
+	u32 last_gorc;
+	u32 last_gotc;
+	u32 last_mprc;
+	u32 last_gotlbc;
+	u32 last_gptlbc;
+	u32 last_gorlbc;
+	u32 last_gprlbc;
+
+	u64 gprc;
+	u64 gptc;
+	u64 gorc;
+	u64 gotc;
+	u64 mprc;
+	u64 gotlbc;
+	u64 gptlbc;
+	u64 gorlbc;
+	u64 gprlbc;
+};
+
+#include "mbx.h"
+
+struct e1000_mac_operations {
+	/* Function pointers for the MAC. */
+	s32  (*init_params)(struct e1000_hw *);
+	s32  (*check_for_link)(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 *);
+	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
+	s32  (*reset_hw)(struct e1000_hw *);
+	s32  (*init_hw)(struct e1000_hw *);
+	s32  (*setup_link)(struct e1000_hw *);
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
+	void (*mta_set)(struct e1000_hw *, u32);
+	void (*rar_set)(struct e1000_hw *, u8*, u32);
+	s32  (*read_mac_addr)(struct e1000_hw *);
+	s32  (*set_vfta)(struct e1000_hw *, u16, bool);
+};
+
+struct e1000_mac_info {
+	struct e1000_mac_operations ops;
+	u8 addr[6];
+	u8 perm_addr[6];
+
+	enum e1000_mac_type type;
+
+	u16 mta_reg_count;
+	u16 rar_entry_count;
+
+	bool get_link_status;
+};
+
+struct e1000_mbx_operations {
+	s32 (*init_params)(struct e1000_hw *hw);
+	s32 (*read)(struct e1000_hw *, u32 *, u16);
+	s32 (*write)(struct e1000_hw *, u32 *, u16);
+	s32 (*read_posted)(struct e1000_hw *, u32 *, u16);
+	s32 (*write_posted)(struct e1000_hw *, u32 *, u16);
+	s32 (*check_for_msg)(struct e1000_hw *);
+	s32 (*check_for_ack)(struct e1000_hw *);
+	s32 (*check_for_rst)(struct e1000_hw *);
+};
+
+struct e1000_mbx_stats {
+	u32 msgs_tx;
+	u32 msgs_rx;
+
+	u32 acks;
+	u32 reqs;
+	u32 rsts;
+};
+
+struct e1000_mbx_info {
+	struct e1000_mbx_operations ops;
+	struct e1000_mbx_stats stats;
+	u32 timeout;
+	u32 usec_delay;
+	u16 size;
+};
+
+struct e1000_dev_spec_vf {
+	u32 vf_number;
+	u32 v2p_mailbox;
+};
+
+struct e1000_hw {
+	void *back;
+
+	u8 __iomem *hw_addr;
+	u8 __iomem *flash_address;
+	unsigned long io_base;
+
+	struct e1000_mac_info  mac;
+	struct e1000_mbx_info mbx;
+
+	union {
+		struct e1000_dev_spec_vf vf;
+	} dev_spec;
+
+	u16 device_id;
+	u16 subsystem_vendor_id;
+	u16 subsystem_device_id;
+	u16 vendor_id;
+
+	u8  revision_id;
+};
+
+/* These functions must be implemented by drivers */
+void e1000_rlpml_set_vf(struct e1000_hw *, u16);
+void e1000_init_function_pointers_vf(struct e1000_hw *hw);
+
+
+#endif /* _E1000_VF_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ioc3-eth.c linux-libre-2.6.30-gnu1/drivers/net/ioc3-eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/ioc3-eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ioc3-eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -1214,6 +1214,19 @@ static void __devinit ioc3_serial_probe(
 }
 #endif
 
+static const struct net_device_ops ioc3_netdev_ops = {
+	.ndo_open		= ioc3_open,
+	.ndo_stop		= ioc3_close,
+	.ndo_start_xmit		= ioc3_start_xmit,
+	.ndo_tx_timeout		= ioc3_timeout,
+	.ndo_get_stats		= ioc3_get_stats,
+	.ndo_set_multicast_list	= ioc3_set_multicast_list,
+	.ndo_do_ioctl		= ioc3_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= ioc3_set_mac_address,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int __devinit ioc3_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -1226,17 +1239,17 @@ static int __devinit ioc3_probe(struct p
 	int err, pci_using_dac;
 
 	/* Configure DMA attributes. */
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (!err) {
 		pci_using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (err < 0) {
 			printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
 			       "for consistent allocations\n", pci_name(pdev));
 			goto out;
 		}
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			printk(KERN_ERR "%s: No usable DMA configuration, "
 			       "aborting.\n", pci_name(pdev));
@@ -1310,15 +1323,8 @@ static int __devinit ioc3_probe(struct p
 	ioc3_get_eaddr(ip);
 
 	/* The IOC3-specific entries in the device structure. */
-	dev->open		= ioc3_open;
-	dev->hard_start_xmit	= ioc3_start_xmit;
-	dev->tx_timeout		= ioc3_timeout;
 	dev->watchdog_timeo	= 5 * HZ;
-	dev->stop		= ioc3_close;
-	dev->get_stats		= ioc3_get_stats;
-	dev->do_ioctl		= ioc3_ioctl;
-	dev->set_multicast_list	= ioc3_set_multicast_list;
-	dev->set_mac_address	= ioc3_set_mac_address;
+	dev->netdev_ops		= &ioc3_netdev_ops;
 	dev->ethtool_ops	= &ioc3_ethtool_ops;
 	dev->features		= NETIF_F_IP_CSUM;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ipg.c linux-libre-2.6.30-gnu1/drivers/net/ipg.c
--- linux-libre-2.6.29-gnu1/drivers/net/ipg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ipg.c	2009-06-09 23:05:27.000000000 -0400
@@ -2240,9 +2240,9 @@ static int __devinit ipg_probe(struct pc
 
 	pci_set_master(pdev);
 
-	rc = pci_set_dma_mask(pdev, DMA_40BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
 	if (rc < 0) {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc < 0) {
 			printk(KERN_ERR "%s: DMA config failed.\n",
 			       pci_name(pdev));
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/ali-ircc.c linux-libre-2.6.30-gnu1/drivers/net/irda/ali-ircc.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/ali-ircc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/ali-ircc.c	2009-06-09 23:05:27.000000000 -0400
@@ -259,6 +259,20 @@ static void __exit ali_ircc_cleanup(void
 	IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__);
 }
 
+static const struct net_device_ops ali_ircc_sir_ops = {
+	.ndo_open       = ali_ircc_net_open,
+	.ndo_stop       = ali_ircc_net_close,
+	.ndo_start_xmit = ali_ircc_sir_hard_xmit,
+	.ndo_do_ioctl   = ali_ircc_net_ioctl,
+};
+
+static const struct net_device_ops ali_ircc_fir_ops = {
+	.ndo_open       = ali_ircc_net_open,
+	.ndo_stop       = ali_ircc_net_close,
+	.ndo_start_xmit = ali_ircc_fir_hard_xmit,
+	.ndo_do_ioctl   = ali_ircc_net_ioctl,
+};
+
 /*
  * Function ali_ircc_open (int i, chipio_t *inf)
  *
@@ -361,10 +375,7 @@ static int ali_ircc_open(int i, chipio_t
 	self->tx_fifo.tail = self->tx_buff.head;
 
 	/* Override the network functions we need to use */
-	dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
-	dev->open            = ali_ircc_net_open;
-	dev->stop            = ali_ircc_net_close;
-	dev->do_ioctl        = ali_ircc_net_ioctl;
+	dev->netdev_ops = &ali_ircc_sir_ops;
 
 	err = register_netdev(dev);
 	if (err) {
@@ -974,7 +985,7 @@ static void ali_ircc_change_speed(struct
 		ali_ircc_fir_change_speed(self, baud);			
 		
 		/* Install FIR xmit handler*/
-		dev->hard_start_xmit = ali_ircc_fir_hard_xmit;		
+		dev->netdev_ops = &ali_ircc_fir_ops;
 				
 		/* Enable Interuupt */
 		self->ier = IER_EOM; // benjamin 2000/11/20 07:24PM					
@@ -988,7 +999,7 @@ static void ali_ircc_change_speed(struct
 		ali_ircc_sir_change_speed(self, baud);
 				
 		/* Install SIR xmit handler*/
-		dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+		dev->netdev_ops = &ali_ircc_sir_ops;
 	}
 	
 		
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/donauboe.c linux-libre-2.6.30-gnu1/drivers/net/irda/donauboe.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/donauboe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/donauboe.c	2009-06-09 23:05:27.000000000 -0400
@@ -1524,6 +1524,13 @@ toshoboe_close (struct pci_dev *pci_dev)
   free_netdev(self->netdev);
 }
 
+static const struct net_device_ops toshoboe_netdev_ops = {
+	.ndo_open	= toshoboe_net_open,
+	.ndo_stop	= toshoboe_net_close,
+	.ndo_start_xmit	= toshoboe_hard_xmit,
+	.ndo_do_ioctl	= toshoboe_net_ioctl,
+};
+
 static int
 toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
 {
@@ -1657,10 +1664,7 @@ toshoboe_open (struct pci_dev *pci_dev,
 #endif
 
   SET_NETDEV_DEV(dev, &pci_dev->dev);
-  dev->hard_start_xmit = toshoboe_hard_xmit;
-  dev->open = toshoboe_net_open;
-  dev->stop = toshoboe_net_close;
-  dev->do_ioctl = toshoboe_net_ioctl;
+  dev->netdev_ops = &toshoboe_netdev_ops;
 
   err = register_netdev(dev);
   if (err)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/irda-usb.c linux-libre-2.6.30-gnu1/drivers/net/irda/irda-usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 18:03:40.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/irda-usb.c	2013-05-03 16:47:31.000000000 -0400
@@ -1398,6 +1398,14 @@ static inline void irda_usb_init_qos(str
 }
 
 /*------------------------------------------------------------------*/
+static const struct net_device_ops irda_usb_netdev_ops = {
+	.ndo_open       = irda_usb_net_open,
+	.ndo_stop       = irda_usb_net_close,
+	.ndo_do_ioctl   = irda_usb_net_ioctl,
+	.ndo_start_xmit = irda_usb_hard_xmit,
+	.ndo_tx_timeout	= irda_usb_net_timeout,
+};
+
 /*
  * Initialise the network side of the irda-usb instance
  * Called when a new USB instance is registered in irda_usb_probe()
@@ -1408,15 +1416,9 @@ static inline int irda_usb_open(struct i
 
 	IRDA_DEBUG(1, "%s()\n", __func__);
 
-	irda_usb_init_qos(self);
+	netdev->netdev_ops = &irda_usb_netdev_ops;
 
-	/* Override the network functions we need to use */
-	netdev->hard_start_xmit = irda_usb_hard_xmit;
-	netdev->tx_timeout	= irda_usb_net_timeout;
-	netdev->watchdog_timeo  = 250*HZ/1000;	/* 250 ms > USB timeout */
-	netdev->open            = irda_usb_net_open;
-	netdev->stop            = irda_usb_net_close;
-	netdev->do_ioctl        = irda_usb_net_ioctl;
+	irda_usb_init_qos(self);
 
 	return register_netdev(netdev);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/kingsun-sir.c linux-libre-2.6.30-gnu1/drivers/net/irda/kingsun-sir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/kingsun-sir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/kingsun-sir.c	2009-06-09 23:05:27.000000000 -0400
@@ -418,6 +418,12 @@ static int kingsun_net_ioctl(struct net_
 	return ret;
 }
 
+static const struct net_device_ops kingsun_ops = {
+	.ndo_start_xmit = kingsun_hard_xmit,
+	.ndo_open            = kingsun_net_open,
+	.ndo_stop            = kingsun_net_close,
+	.ndo_do_ioctl        = kingsun_net_ioctl,
+};
 
 /*
  * This routine is called by the USB subsystem for each new device
@@ -520,10 +526,7 @@ static int kingsun_probe(struct usb_inte
 	irda_qos_bits_to_value(&kingsun->qos);
 
 	/* Override the network functions we need to use */
-	net->hard_start_xmit = kingsun_hard_xmit;
-	net->open            = kingsun_net_open;
-	net->stop            = kingsun_net_close;
-	net->do_ioctl        = kingsun_net_ioctl;
+	net->netdev_ops = &kingsun_ops;
 
 	ret = register_netdev(net);
 	if (ret != 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/ks959-sir.c linux-libre-2.6.30-gnu1/drivers/net/irda/ks959-sir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/ks959-sir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/ks959-sir.c	2009-06-09 23:05:27.000000000 -0400
@@ -668,6 +668,12 @@ static int ks959_net_ioctl(struct net_de
 	return ret;
 }
 
+static const struct net_device_ops ks959_ops = {
+	.ndo_start_xmit	= ks959_hard_xmit,
+	.ndo_open	= ks959_net_open,
+	.ndo_stop	= ks959_net_close,
+	.ndo_do_ioctl	= ks959_net_ioctl,
+};
 /*
  * This routine is called by the USB subsystem for each new device
  * in the system. We need to check if the device is ours, and in
@@ -780,10 +786,7 @@ static int ks959_probe(struct usb_interf
 	irda_qos_bits_to_value(&kingsun->qos);
 
 	/* Override the network functions we need to use */
-	net->hard_start_xmit = ks959_hard_xmit;
-	net->open = ks959_net_open;
-	net->stop = ks959_net_close;
-	net->do_ioctl = ks959_net_ioctl;
+	net->netdev_ops = &ks959_ops;
 
 	ret = register_netdev(net);
 	if (ret != 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/ksdazzle-sir.c linux-libre-2.6.30-gnu1/drivers/net/irda/ksdazzle-sir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/ksdazzle-sir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/ksdazzle-sir.c	2009-06-09 23:05:27.000000000 -0400
@@ -562,6 +562,13 @@ static int ksdazzle_net_ioctl(struct net
 	return ret;
 }
 
+static const struct net_device_ops ksdazzle_ops = {
+	.ndo_start_xmit	= ksdazzle_hard_xmit,
+	.ndo_open	= ksdazzle_net_open,
+	.ndo_stop	= ksdazzle_net_close,
+	.ndo_do_ioctl	= ksdazzle_net_ioctl,
+};
+
 /*
  * This routine is called by the USB subsystem for each new device
  * in the system. We need to check if the device is ours, and in
@@ -684,10 +691,7 @@ static int ksdazzle_probe(struct usb_int
 	irda_qos_bits_to_value(&kingsun->qos);
 
 	/* Override the network functions we need to use */
-	net->hard_start_xmit = ksdazzle_hard_xmit;
-	net->open = ksdazzle_net_open;
-	net->stop = ksdazzle_net_close;
-	net->do_ioctl = ksdazzle_net_ioctl;
+	net->netdev_ops = &ksdazzle_ops;
 
 	ret = register_netdev(net);
 	if (ret != 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/mcs7780.c linux-libre-2.6.30-gnu1/drivers/net/irda/mcs7780.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/mcs7780.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/mcs7780.c	2009-06-09 23:05:27.000000000 -0400
@@ -873,6 +873,13 @@ static int mcs_hard_xmit(struct sk_buff
 	return ret;
 }
 
+static const struct net_device_ops mcs_netdev_ops = {
+	.ndo_open = mcs_net_open,
+	.ndo_stop = mcs_net_close,
+	.ndo_start_xmit = mcs_hard_xmit,
+	.ndo_do_ioctl = mcs_net_ioctl,
+};
+
 /*
  * This function is called by the USB subsystem for each new device in the
  * system.  Need to verify the device and if it is, then start handling it.
@@ -919,11 +926,7 @@ static int mcs_probe(struct usb_interfac
 	/* Speed change work initialisation*/
 	INIT_WORK(&mcs->work, mcs_speed_work);
 
-	/* Override the network functions we need to use */
-	ndev->hard_start_xmit = mcs_hard_xmit;
-	ndev->open = mcs_net_open;
-	ndev->stop = mcs_net_close;
-	ndev->do_ioctl = mcs_net_ioctl;
+	ndev->netdev_ops = &mcs_netdev_ops;
 
 	if (!intf->cur_altsetting)
 		goto error2;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/nsc-ircc.c linux-libre-2.6.30-gnu1/drivers/net/irda/nsc-ircc.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/nsc-ircc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/nsc-ircc.c	2009-06-09 23:05:27.000000000 -0400
@@ -331,6 +331,20 @@ static void __exit nsc_ircc_cleanup(void
 	pnp_registered = 0;
 }
 
+static const struct net_device_ops nsc_ircc_sir_ops = {
+	.ndo_open       = nsc_ircc_net_open,
+	.ndo_stop       = nsc_ircc_net_close,
+	.ndo_start_xmit = nsc_ircc_hard_xmit_sir,
+	.ndo_do_ioctl   = nsc_ircc_net_ioctl,
+};
+
+static const struct net_device_ops nsc_ircc_fir_ops = {
+	.ndo_open       = nsc_ircc_net_open,
+	.ndo_stop       = nsc_ircc_net_close,
+	.ndo_start_xmit = nsc_ircc_hard_xmit_fir,
+	.ndo_do_ioctl   = nsc_ircc_net_ioctl,
+};
+
 /*
  * Function nsc_ircc_open (iobase, irq)
  *
@@ -441,10 +455,7 @@ static int __init nsc_ircc_open(chipio_t
 	self->tx_fifo.tail = self->tx_buff.head;
 
 	/* Override the network functions we need to use */
-	dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
-	dev->open            = nsc_ircc_net_open;
-	dev->stop            = nsc_ircc_net_close;
-	dev->do_ioctl        = nsc_ircc_net_ioctl;
+	dev->netdev_ops = &nsc_ircc_sir_ops;
 
 	err = register_netdev(dev);
 	if (err) {
@@ -1320,12 +1331,12 @@ static __u8 nsc_ircc_change_speed(struct
 	switch_bank(iobase, BANK0); 
 	if (speed > 115200) {
 		/* Install FIR xmit handler */
-		dev->hard_start_xmit = nsc_ircc_hard_xmit_fir;
+		dev->netdev_ops = &nsc_ircc_fir_ops;
 		ier = IER_SFIF_IE;
 		nsc_ircc_dma_receive(self);
 	} else {
 		/* Install SIR xmit handler */
-		dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
+		dev->netdev_ops = &nsc_ircc_sir_ops;
 		ier = IER_RXHDL_IE;
 	}
 	/* Set our current interrupt mask */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/pxaficp_ir.c linux-libre-2.6.30-gnu1/drivers/net/irda/pxaficp_ir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/pxaficp_ir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/pxaficp_ir.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,9 +24,8 @@
 
 #include <mach/dma.h>
 #include <mach/irda.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/regs-uart.h>
+#include <mach/regs-ost.h>
 
 #define FICP		__REG(0x40800000)  /* Start of FICP area */
 #define ICCR0		__REG(0x40800000)  /* ICP Control Register 0 */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/sir_dev.c linux-libre-2.6.30-gnu1/drivers/net/irda/sir_dev.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/sir_dev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/sir_dev.c	2009-06-09 23:05:27.000000000 -0400
@@ -753,7 +753,8 @@ static int sirdev_alloc_buffers(struct s
 	dev->rx_buff.truesize = IRDA_SKB_MAX_MTU; 
 
 	/* Bootstrap ZeroCopy Rx */
-	dev->rx_buff.skb = __dev_alloc_skb(dev->rx_buff.truesize, GFP_KERNEL);
+	dev->rx_buff.skb = __netdev_alloc_skb(dev->netdev, dev->rx_buff.truesize,
+					      GFP_KERNEL);
 	if (dev->rx_buff.skb == NULL)
 		return -ENOMEM;
 	skb_reserve(dev->rx_buff.skb, 1);
@@ -779,8 +780,7 @@ static int sirdev_alloc_buffers(struct s
 
 static void sirdev_free_buffers(struct sir_dev *dev)
 {
-	if (dev->rx_buff.skb)
-		kfree_skb(dev->rx_buff.skb);
+	kfree_skb(dev->rx_buff.skb);
 	kfree(dev->tx_buff.head);
 	dev->rx_buff.head = dev->tx_buff.head = NULL;
 	dev->rx_buff.skb = NULL;
@@ -865,6 +865,12 @@ out:
 	return 0;
 }
 
+static const struct net_device_ops sirdev_ops = {
+	.ndo_start_xmit	= sirdev_hard_xmit,
+	.ndo_open	= sirdev_open,
+	.ndo_stop	= sirdev_close,
+	.ndo_do_ioctl	= sirdev_ioctl,
+};
 /* ----------------------------------------------------------------------------- */
 
 struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name)
@@ -908,10 +914,7 @@ struct sir_dev * sirdev_get_instance(con
 	dev->netdev = ndev;
 
 	/* Override the network functions we need to use */
-	ndev->hard_start_xmit = sirdev_hard_xmit;
-	ndev->open = sirdev_open;
-	ndev->stop = sirdev_close;
-	ndev->do_ioctl = sirdev_ioctl;
+	ndev->netdev_ops = &sirdev_ops;
 
 	if (register_netdev(ndev)) {
 		IRDA_ERROR("%s(), register_netdev() failed!\n", __func__);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/smsc-ircc2.c linux-libre-2.6.30-gnu1/drivers/net/irda/smsc-ircc2.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/smsc-ircc2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/smsc-ircc2.c	2009-06-09 23:05:27.000000000 -0400
@@ -486,6 +486,26 @@ static int __init smsc_ircc_init(void)
 	return ret;
 }
 
+static int smsc_ircc_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct smsc_ircc_cb *self = netdev_priv(dev);
+
+	if (self->io.speed > 115200)
+		return 	smsc_ircc_hard_xmit_fir(skb, dev);
+	else
+		return 	smsc_ircc_hard_xmit_sir(skb, dev);
+}
+
+static const struct net_device_ops smsc_ircc_netdev_ops = {
+	.ndo_open       = smsc_ircc_net_open,
+	.ndo_stop       = smsc_ircc_net_close,
+	.ndo_do_ioctl   = smsc_ircc_net_ioctl,
+	.ndo_start_xmit = smsc_ircc_net_xmit,
+#if SMSC_IRCC2_C_NET_TIMEOUT
+	.ndo_tx_timeout	= smsc_ircc_timeout,
+#endif
+};
+
 /*
  * Function smsc_ircc_open (firbase, sirbase, dma, irq)
  *
@@ -519,14 +539,10 @@ static int __init smsc_ircc_open(unsigne
 		goto err_out1;
 	}
 
-	dev->hard_start_xmit = smsc_ircc_hard_xmit_sir;
 #if SMSC_IRCC2_C_NET_TIMEOUT
-	dev->tx_timeout	     = smsc_ircc_timeout;
 	dev->watchdog_timeo  = HZ * 2;  /* Allow enough time for speed change */
 #endif
-	dev->open            = smsc_ircc_net_open;
-	dev->stop            = smsc_ircc_net_close;
-	dev->do_ioctl        = smsc_ircc_net_ioctl;
+	dev->netdev_ops = &smsc_ircc_netdev_ops;
 
 	self = netdev_priv(dev);
 	self->netdev = dev;
@@ -995,9 +1011,6 @@ static void smsc_ircc_fir_start(struct s
 
 	/* Reset everything */
 
-	/* Install FIR transmit handler */
-	dev->hard_start_xmit = smsc_ircc_hard_xmit_fir;
-
 	/* Clear FIFO */
 	outb(inb(fir_base + IRCC_LCR_A) | IRCC_LCR_A_FIFO_RESET, fir_base + IRCC_LCR_A);
 
@@ -1894,7 +1907,6 @@ static void smsc_ircc_sir_start(struct s
 	IRDA_ASSERT(self != NULL, return;);
 	dev = self->netdev;
 	IRDA_ASSERT(dev != NULL, return;);
-	dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir;
 
 	fir_base = self->io.fir_base;
 	sir_base = self->io.sir_base;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/stir4200.c linux-libre-2.6.30-gnu1/drivers/net/irda/stir4200.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/stir4200.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/stir4200.c	2009-06-09 23:05:27.000000000 -0400
@@ -1007,6 +1007,13 @@ static int stir_net_ioctl(struct net_dev
 	return ret;
 }
 
+static const struct net_device_ops stir_netdev_ops = {
+	.ndo_open       = stir_net_open,
+	.ndo_stop       = stir_net_close,
+	.ndo_start_xmit = stir_hard_xmit,
+	.ndo_do_ioctl   = stir_net_ioctl,
+};
+
 /*
  * This routine is called by the USB subsystem for each new device
  * in the system. We need to check if the device is ours, and in
@@ -1054,10 +1061,7 @@ static int stir_probe(struct usb_interfa
 	irda_qos_bits_to_value(&stir->qos);
 
 	/* Override the network functions we need to use */
-	net->hard_start_xmit = stir_hard_xmit;
-	net->open            = stir_net_open;
-	net->stop            = stir_net_close;
-	net->do_ioctl        = stir_net_ioctl;
+	net->netdev_ops = &stir_netdev_ops;
 
 	ret = register_netdev(net);
 	if (ret != 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/via-ircc.c linux-libre-2.6.30-gnu1/drivers/net/irda/via-ircc.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/via-ircc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/via-ircc.c	2009-06-09 23:05:27.000000000 -0400
@@ -310,6 +310,19 @@ static void __exit via_ircc_cleanup(void
 	pci_unregister_driver (&via_driver); 
 }
 
+static const struct net_device_ops via_ircc_sir_ops = {
+	.ndo_start_xmit = via_ircc_hard_xmit_sir,
+	.ndo_open = via_ircc_net_open,
+	.ndo_stop = via_ircc_net_close,
+	.ndo_do_ioctl = via_ircc_net_ioctl,
+};
+static const struct net_device_ops via_ircc_fir_ops = {
+	.ndo_start_xmit = via_ircc_hard_xmit_fir,
+	.ndo_open = via_ircc_net_open,
+	.ndo_stop = via_ircc_net_close,
+	.ndo_do_ioctl = via_ircc_net_ioctl,
+};
+
 /*
  * Function via_ircc_open (iobase, irq)
  *
@@ -428,10 +441,7 @@ static __devinit int via_ircc_open(int i
 	self->tx_fifo.tail = self->tx_buff.head;
 
 	/* Override the network functions we need to use */
-	dev->hard_start_xmit = via_ircc_hard_xmit_sir;
-	dev->open = via_ircc_net_open;
-	dev->stop = via_ircc_net_close;
-	dev->do_ioctl = via_ircc_net_ioctl;
+	dev->netdev_ops = &via_ircc_sir_ops;
 
 	err = register_netdev(dev);
 	if (err)
@@ -798,11 +808,11 @@ static void via_ircc_change_speed(struct
 
 	if (speed > 115200) {
 		/* Install FIR xmit handler */
-		dev->hard_start_xmit = via_ircc_hard_xmit_fir;
+		dev->netdev_ops = &via_ircc_fir_ops;
 		via_ircc_dma_receive(self);
 	} else {
 		/* Install SIR xmit handler */
-		dev->hard_start_xmit = via_ircc_hard_xmit_sir;
+		dev->netdev_ops = &via_ircc_sir_ops;
 	}
 	netif_wake_queue(dev);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/vlsi_ir.c linux-libre-2.6.30-gnu1/drivers/net/irda/vlsi_ir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/vlsi_ir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/vlsi_ir.c	2009-06-09 23:05:27.000000000 -0400
@@ -1573,6 +1573,14 @@ static int vlsi_close(struct net_device
 	return 0;
 }
 
+static const struct net_device_ops vlsi_netdev_ops = {
+	.ndo_open       = vlsi_open,
+	.ndo_stop       = vlsi_close,
+	.ndo_start_xmit = vlsi_hard_start_xmit,
+	.ndo_do_ioctl   = vlsi_ioctl,
+	.ndo_tx_timeout = vlsi_tx_timeout,
+};
+
 static int vlsi_irda_init(struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = netdev_priv(ndev);
@@ -1608,11 +1616,7 @@ static int vlsi_irda_init(struct net_dev
 	ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA;
 	ndev->if_port = IF_PORT_UNKNOWN;
  
-	ndev->open	      = vlsi_open;
-	ndev->stop	      = vlsi_close;
-	ndev->hard_start_xmit = vlsi_hard_start_xmit;
-	ndev->do_ioctl	      = vlsi_ioctl;
-	ndev->tx_timeout      = vlsi_tx_timeout;
+	ndev->netdev_ops = &vlsi_netdev_ops;
 	ndev->watchdog_timeo  = 500*HZ/1000;	/* max. allowed turn time for IrLAP */
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -1867,13 +1871,6 @@ static int __init vlsi_mod_init(void)
 	 * without procfs - it's not required for the driver to work.
 	 */
 	vlsi_proc_root = proc_mkdir(PROC_DIR, NULL);
-	if (vlsi_proc_root) {
-		/* protect registered procdir against module removal.
-		 * Because we are in the module init path there's no race
-		 * window after create_proc_entry (and no barrier needed).
-		 */
-		vlsi_proc_root->owner = THIS_MODULE;
-	}
 
 	ret = pci_register_driver(&vlsi_irda_driver);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/irda/w83977af_ir.c linux-libre-2.6.30-gnu1/drivers/net/irda/w83977af_ir.c
--- linux-libre-2.6.29-gnu1/drivers/net/irda/w83977af_ir.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/irda/w83977af_ir.c	2009-06-09 23:05:27.000000000 -0400
@@ -140,6 +140,13 @@ static void __exit w83977af_cleanup(void
 	}
 }
 
+static const struct net_device_ops w83977_netdev_ops = {
+	.ndo_open       = w83977af_net_open,
+	.ndo_stop       = w83977af_net_close,
+	.ndo_start_xmit = w83977af_hard_xmit,
+	.ndo_do_ioctl   = w83977af_net_ioctl,
+};
+
 /*
  * Function w83977af_open (iobase, irq)
  *
@@ -231,11 +238,7 @@ static int w83977af_open(int i, unsigned
 	self->rx_buff.data = self->rx_buff.head;
 	self->netdev = dev;
 
-	/* Override the network functions we need to use */
-	dev->hard_start_xmit = w83977af_hard_xmit;
-	dev->open            = w83977af_net_open;
-	dev->stop            = w83977af_net_close;
-	dev->do_ioctl        = w83977af_net_ioctl;
+	dev->netdev_ops	= &w83977_netdev_ops;
 
 	err = register_netdev(dev);
 	if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/isa-skeleton.c linux-libre-2.6.30-gnu1/drivers/net/isa-skeleton.c
--- linux-libre-2.6.29-gnu1/drivers/net/isa-skeleton.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/isa-skeleton.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,6 +181,18 @@ out:
 }
 #endif
 
+static const struct net_device_ops netcard_netdev_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_start_xmit		= net_send_packet,
+	.ndo_get_stats		= net_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_tx_timeout		= net_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /*
  * 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
@@ -303,13 +315,7 @@ static int __init netcard_probe1(struct
 	np = netdev_priv(dev);
 	spin_lock_init(&np->lock);
 
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit	= net_send_packet;
-	dev->get_stats		= net_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-
-        dev->tx_timeout		= &net_tx_timeout;
+        dev->netdev_ops		= &netcard_netdev_ops;
         dev->watchdog_timeo	= MY_TX_TIMEOUT;
 
 	err = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgb/ixgb_main.c linux-libre-2.6.30-gnu1/drivers/net/ixgb/ixgb_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgb/ixgb_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgb/ixgb_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -365,12 +365,12 @@ ixgb_probe(struct pci_dev *pdev, const s
 	if (err)
 		return err;
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
-	    !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
+	    !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
 		pci_using_dac = 1;
 	} else {
-		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
-		    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+		    (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 			printk(KERN_ERR
 			 "ixgb: No usable DMA configuration, aborting\n");
 			goto err_dma_mask;
@@ -887,19 +887,13 @@ static void
 ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
                                 struct ixgb_buffer *buffer_info)
 {
-	struct pci_dev *pdev = adapter->pdev;
-
-	if (buffer_info->dma)
-		pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
-		               PCI_DMA_TODEVICE);
-
-	/* okay to call kfree_skb here instead of kfree_skb_any because
-	 * this is never called in interrupt context */
-	if (buffer_info->skb)
-		dev_kfree_skb(buffer_info->skb);
-
-	buffer_info->skb = NULL;
 	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;
 	/* these fields must always be initialized in tx
 	 * buffer_info->length = 0;
@@ -1275,17 +1269,23 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_buffer *buffer_info;
-	int len = skb->len;
+	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;
-
-	len -= skb->data_len;
+	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);
@@ -1297,7 +1297,7 @@ 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 =
+		buffer_info->dma = map[0] + offset;
 			pci_map_single(adapter->pdev,
 				skb->data + offset,
 				size,
@@ -1307,7 +1307,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 		len -= size;
 		offset += size;
 		count++;
-		if (++i == tx_ring->count) i = 0;
+		if (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
 	}
 
 	for (f = 0; f < nr_frags; f++) {
@@ -1318,6 +1322,10 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 		offset = 0;
 
 		while (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, IXGB_MAX_DATA_PER_TXD);
 
@@ -1329,21 +1337,14 @@ ixgb_tx_map(struct ixgb_adapter *adapter
 
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
-			buffer_info->dma =
-				pci_map_page(adapter->pdev,
-					frag->page,
-					frag->page_offset + offset,
-					size,
-					PCI_DMA_TODEVICE);
+			buffer_info->dma = map[f + 1] + offset;
 			buffer_info->next_to_watch = 0;
 
 			len -= size;
 			offset += size;
 			count++;
-			if (++i == tx_ring->count) i = 0;
 		}
 	}
-	i = (i == 0) ? tx_ring->count - 1 : i - 1;
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
 
@@ -1445,6 +1446,7 @@ ixgb_xmit_frame(struct sk_buff *skb, str
 	unsigned int first;
 	unsigned int tx_flags = 0;
 	int vlan_id = 0;
+	int count = 0;
 	int tso;
 
 	if (test_bit(__IXGB_DOWN, &adapter->flags)) {
@@ -1479,13 +1481,19 @@ ixgb_xmit_frame(struct sk_buff *skb, str
 	else if (ixgb_tx_csum(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_CSUM;
 
-	ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
-			tx_flags);
+	count = ixgb_tx_map(adapter, skb, first);
 
-	netdev->trans_start = jiffies;
+	if (count) {
+		ixgb_tx_queue(adapter, count, vlan_id, tx_flags);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
 
-	/* Make sure there is space in the ring for the next send. */
-	ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
+	} else {
+		dev_kfree_skb_any(skb);
+		adapter->tx_ring.buffer_info[first].time_stamp = 0;
+		adapter->tx_ring.next_to_use = first;
+	}
 
 	return NETDEV_TX_OK;
 }
@@ -1721,14 +1729,14 @@ ixgb_intr(int irq, void *data)
 		if (!test_bit(__IXGB_DOWN, &adapter->flags))
 			mod_timer(&adapter->watchdog_timer, jiffies);
 
-	if (netif_rx_schedule_prep(&adapter->napi)) {
+	if (napi_schedule_prep(&adapter->napi)) {
 
 		/* Disable interrupts and register for poll. The flush
 		  of the posted write is intentionally left out.
 		*/
 
 		IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
-		__netif_rx_schedule(&adapter->napi);
+		__napi_schedule(&adapter->napi);
 	}
 	return IRQ_HANDLED;
 }
@@ -1749,7 +1757,7 @@ ixgb_clean(struct napi_struct *napi, int
 
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		if (!test_bit(__IXGB_DOWN, &adapter->flags))
 			ixgb_irq_enable(adapter);
 	}
@@ -1818,7 +1826,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *a
 		/* detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = false;
-		if (tx_ring->buffer_info[eop].dma &&
+		if (tx_ring->buffer_info[eop].time_stamp &&
 		   time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ)
 		   && !(IXGB_READ_REG(&adapter->hw, STATUS) &
 		        IXGB_STATUS_TXOFF)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_82598.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_82598.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_82598.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_82598.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -50,6 +50,27 @@ static s32 ixgbe_read_i2c_eeprom_82598(s
                                        u8 *eeprom_data);
 
 /**
+ *  ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
+ *  @hw: pointer to hardware structure
+ *
+ *  Read PCIe configuration space, and get the MSI-X vector count from
+ *  the capabilities table.
+ **/
+static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
+{
+	struct ixgbe_adapter *adapter = hw->back;
+	u16 msix_count;
+	pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82598_CAPS,
+	                     &msix_count);
+	msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+	/* MSI-X count is zero-based in HW, so increment to give proper value */
+	msix_count++;
+
+	return msix_count;
+}
+
+/**
  */
 static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 {
@@ -58,6 +79,9 @@ static s32 ixgbe_get_invariants_82598(st
 	s32 ret_val = 0;
 	u16 list_offset, data_offset;
 
+	/* Set the bus information prior to PHY identification */
+	mac->ops.get_bus_info(hw);
+
 	/* Call PHY identify routine to get the phy type */
 	ixgbe_identify_phy_generic(hw);
 
@@ -106,6 +130,7 @@ static s32 ixgbe_get_invariants_82598(st
 	mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
 	mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
 	mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
 
 out:
 	return ret_val;
@@ -124,18 +149,12 @@ static s32 ixgbe_get_link_capabilities_8
                                              bool *autoneg)
 {
 	s32 status = 0;
-	s32 autoc_reg;
 
-	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
-	if (hw->mac.link_settings_loaded) {
-		autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
-		autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
-		autoc_reg |= hw->mac.link_attach_type;
-		autoc_reg |= hw->mac.link_mode_select;
-	}
-
-	switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) {
+	/*
+	 * Determine link capabilities based on the stored value of AUTOC,
+	 * which represents EEPROM defaults.
+	 */
+	switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
 	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
 		*autoneg = false;
@@ -154,9 +173,9 @@ static s32 ixgbe_get_link_capabilities_8
 	case IXGBE_AUTOC_LMS_KX4_AN:
 	case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
 		*speed = IXGBE_LINK_SPEED_UNKNOWN;
-		if (autoc_reg & IXGBE_AUTOC_KX4_SUPP)
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
 			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
-		if (autoc_reg & IXGBE_AUTOC_KX_SUPP)
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
 			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
 		*autoneg = true;
 		break;
@@ -213,6 +232,10 @@ static enum ixgbe_media_type ixgbe_get_m
 
 	/* Media type for I82598 is based on device ID */
 	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82598:
+	case IXGBE_DEV_ID_82598_BX:
+		media_type = ixgbe_media_type_backplane;
+		break;
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 	case IXGBE_DEV_ID_82598EB_CX4:
@@ -235,104 +258,75 @@ static enum ixgbe_media_type ixgbe_get_m
 }
 
 /**
- *  ixgbe_setup_fc_82598 - Configure flow control settings
+ *  ixgbe_fc_enable_82598 - Enable flow control
  *  @hw: pointer to hardware structure
  *  @packetbuf_num: packet buffer number (0-7)
  *
- *  Configures the flow control settings based on SW configuration.  This
- *  function is used for 802.3x flow control configuration only.
+ *  Enable flow control according to the current settings.
  **/
-static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
-	u32 frctl_reg;
+	s32 ret_val = 0;
+	u32 fctrl_reg;
 	u32 rmcs_reg;
+	u32 reg;
 
-	if (packetbuf_num < 0 || packetbuf_num > 7) {
-		hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
-		          " 0-7\n", packetbuf_num);
-	}
-
-	frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-	frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
 
 	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
 	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
 
 	/*
-	 * 10 gig parts do not have a word in the EEPROM to determine the
-	 * default flow control setting, so we explicitly set it to full.
-	 */
-	if (hw->fc.type == ixgbe_fc_default)
-		hw->fc.type = ixgbe_fc_full;
-
-	/*
-	 * We want to save off the original Flow Control configuration just in
-	 * case we get disconnected and then reconnected into a different hub
-	 * or switch with different Flow Control capabilities.
-	 */
-	hw->fc.original_type = hw->fc.type;
-
-	/*
-	 * The possible values of the "flow_control" parameter are:
+	 * The possible values of fc.current_mode are:
 	 * 0: Flow control is completely disabled
-	 * 1: Rx flow control is enabled (we can receive pause frames but not
-	 *    send pause frames).
-	 * 2: Tx flow control is enabled (we can send pause frames but we do not
-	 *    support receiving pause frames)
+	 * 1: Rx flow control is enabled (we can receive pause frames,
+	 *    but not send pause frames).
+	 * 2:  Tx flow control is enabled (we can send pause frames but
+	 *     we do not support receiving pause frames).
 	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
 	 * other: Invalid.
 	 */
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case ixgbe_fc_none:
+		/* Flow control completely disabled by software override. */
 		break;
 	case ixgbe_fc_rx_pause:
 		/*
-		 * Rx Flow control is enabled,
-		 * and Tx Flow control is disabled.
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
 		 */
-		frctl_reg |= IXGBE_FCTRL_RFCE;
+		fctrl_reg |= IXGBE_FCTRL_RFCE;
 		break;
 	case ixgbe_fc_tx_pause:
 		/*
-		 * Tx Flow control is enabled, and Rx Flow control is disabled,
-		 * by a software over-ride.
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
 		 */
 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
 		break;
 	case ixgbe_fc_full:
-		/*
-		 * Flow control (both Rx and Tx) is enabled by a software
-		 * over-ride.
-		 */
-		frctl_reg |= IXGBE_FCTRL_RFCE;
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		fctrl_reg |= IXGBE_FCTRL_RFCE;
 		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
 		break;
 	default:
-		/* We should never get here.  The value should be 0-3. */
 		hw_dbg(hw, "Flow control param set incorrectly\n");
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
 		break;
 	}
 
 	/* Enable 802.3x based flow control settings. */
-	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
-	/*
-	 * Check for invalid software configuration, zeros are completely
-	 * invalid for all parameters used past this point, and if we enable
-	 * flow control with zero water marks, we blast flow control packets.
-	 */
-	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-		hw_dbg(hw, "Flow control structure initialized incorrectly\n");
-		return IXGBE_ERR_INVALID_LINK_SETTINGS;
-	}
-
-	/*
-	 * We need to set up the Receive Threshold high and low water
-	 * marks as well as (optionally) enabling the transmission of
-	 * XON frames.
-	 */
-	if (hw->fc.type & ixgbe_fc_tx_pause) {
+	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
+	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
 		if (hw->fc.send_xon) {
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
 			                (hw->fc.low_water | IXGBE_FCRTL_XONE));
@@ -340,14 +334,94 @@ static s32 ixgbe_setup_fc_82598(struct i
 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
 			                hw->fc.low_water);
 		}
+
 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
-		                (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+		                (hw->fc.high_water | IXGBE_FCRTH_FCEN));
 	}
 
-	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+	/* Configure pause time (2 TCs per register) */
+	reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+	if ((packetbuf_num & 1) == 0)
+		reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+	else
+		reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
 
-	return 0;
+out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_setup_fc_82598 - Configure flow control settings
+ *  @hw: pointer to hardware structure
+ *  @packetbuf_num: packet buffer number (0-7)
+ *
+ *  Configures the flow control settings based on SW configuration.  This
+ *  function is used for 802.3x flow control configuration only.
+ **/
+static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+	s32 ret_val = 0;
+	ixgbe_link_speed speed;
+	bool link_up;
+
+	/* Validate the packetbuf configuration */
+	if (packetbuf_num < 0 || packetbuf_num > 7) {
+		hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+		          " 0-7\n", packetbuf_num);
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the water mark configuration.  Zero water marks are invalid
+	 * because it causes the controller to just blast out fc packets.
+	 */
+	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+		hw_dbg(hw, "Invalid water mark configuration\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the requested mode.  Strict IEEE mode does not allow
+	 * ixgbe_fc_rx_pause because it will cause testing anomalies.
+	 */
+	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+		hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * 10gig parts do not have a word in the EEPROM to determine the
+	 * default flow control setting, so we explicitly set it to full.
+	 */
+	if (hw->fc.requested_mode == ixgbe_fc_default)
+		hw->fc.requested_mode = ixgbe_fc_full;
+
+	/*
+	 * Save off the requested flow control mode for use later.  Depending
+	 * on the link partner's capabilities, we may or may not use this mode.
+	 */
+
+	hw->fc.current_mode = hw->fc.requested_mode;
+
+	/* Decide whether to use autoneg or not. */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+	if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
+	    (speed == IXGBE_LINK_SPEED_1GB_FULL))
+		ret_val = ixgbe_fc_autoneg(hw);
+
+	if (ret_val)
+		goto out;
+
+	ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);
+
+out:
+	return ret_val;
 }
 
 /**
@@ -364,27 +438,17 @@ static s32 ixgbe_setup_mac_link_82598(st
 	u32 i;
 	s32 status = 0;
 
-	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
-	if (hw->mac.link_settings_loaded) {
-		autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
-		autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
-		autoc_reg |= hw->mac.link_attach_type;
-		autoc_reg |= hw->mac.link_mode_select;
-
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		IXGBE_WRITE_FLUSH(hw);
-		msleep(50);
-	}
-
 	/* Restart link */
+	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
 	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
 
 	/* Only poll for autoneg to complete if specified to do so */
 	if (hw->phy.autoneg_wait_to_complete) {
-		if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN ||
-		    hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		     IXGBE_AUTOC_LMS_KX4_AN ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		     IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
 			links_reg = 0; /* Just in case Autoneg time = 0 */
 			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
 				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
@@ -404,7 +468,6 @@ static s32 ixgbe_setup_mac_link_82598(st
 	 * case we get disconnected and then reconnected into a different hub
 	 * or switch with different Flow Control capabilities.
 	 */
-	hw->fc.original_type = hw->fc.type;
 	ixgbe_setup_fc_82598(hw, 0);
 
 	/* Add delay to filter out noises during initial link setup */
@@ -508,37 +571,43 @@ out:
  *  Set the link speed in the AUTOC register and restarts link.
  **/
 static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
-                                            ixgbe_link_speed speed, bool autoneg,
-                                            bool autoneg_wait_to_complete)
+                                           ixgbe_link_speed speed, bool autoneg,
+                                           bool autoneg_wait_to_complete)
 {
-	s32 status = 0;
+	s32              status            = 0;
+	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+	u32              curr_autoc        = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32              autoc             = curr_autoc;
+	u32              link_mode         = autoc & IXGBE_AUTOC_LMS_MASK;
 
-	/* If speed is 10G, then check for CX4 or XAUI. */
-	if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
-	    (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
-		hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
-	} else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
-		hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
-	} else if (autoneg) {
-		/* BX mode - Autonegotiate 1G */
-		if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
-			hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
-		else /* KX/KX4 mode */
-			hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN;
-	} else {
+	/* Check to see if speed passed in is supported. */
+	ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg);
+	speed &= link_capabilities;
+
+	if (speed == IXGBE_LINK_SPEED_UNKNOWN)
 		status = IXGBE_ERR_LINK_SETUP;
+
+	/* Set KX4/KX support according to speed requested */
+	else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
+	         link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+		autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
+		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+			autoc |= IXGBE_AUTOC_KX4_SUPP;
+		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+			autoc |= IXGBE_AUTOC_KX_SUPP;
+		if (autoc != curr_autoc)
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
 	}
 
 	if (status == 0) {
 		hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
 
-		hw->mac.link_settings_loaded = true;
 		/*
 		 * Setup and restart the link based on the new values in
 		 * ixgbe_hw This will write the AUTOC register based on the new
 		 * stored values
 		 */
-		ixgbe_setup_mac_link_82598(hw);
+		status = ixgbe_setup_mac_link_82598(hw);
 	}
 
 	return status;
@@ -561,10 +630,6 @@ static s32 ixgbe_setup_copper_link_82598
 	/* Restart autonegotiation on PHY */
 	status = hw->phy.ops.setup_link(hw);
 
-	/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
-	hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
-	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
 	/* Set up MAC */
 	ixgbe_setup_mac_link_82598(hw);
 
@@ -591,10 +656,6 @@ static s32 ixgbe_setup_copper_link_speed
 	status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
 	                                      autoneg_wait_to_complete);
 
-	/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
-	hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
-	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
 	/* Set up MAC */
 	ixgbe_setup_mac_link_82598(hw);
 
@@ -694,24 +755,16 @@ static s32 ixgbe_reset_hw_82598(struct i
 	IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
 
 	/*
-	 * AUTOC register which stores link settings gets cleared
-	 * and reloaded from EEPROM after reset. We need to restore
-	 * our stored value from init in case SW changed the attach
-	 * type or speed.  If this is the first time and link settings
-	 * have not been stored, store default settings from AUTOC.
+	 * Store the original AUTOC value if it has not been
+	 * stored off yet.  Otherwise restore the stored original
+	 * AUTOC value since the reset operation sets back to deaults.
 	 */
 	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	if (hw->mac.link_settings_loaded) {
-		autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
-		autoc &= ~(IXGBE_AUTOC_LMS_MASK);
-		autoc |= hw->mac.link_attach_type;
-		autoc |= hw->mac.link_mode_select;
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
-	} else {
-		hw->mac.link_attach_type =
-		                         (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
-		hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
-		hw->mac.link_settings_loaded = true;
+	if (hw->mac.orig_link_settings_stored == false) {
+		hw->mac.orig_autoc = autoc;
+		hw->mac.orig_link_settings_stored = true;
+	} else if (autoc != hw->mac.orig_autoc) {
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
 	}
 
 	/* Store the permanent mac address */
@@ -832,61 +885,6 @@ static s32 ixgbe_clear_vfta_82598(struct
 }
 
 /**
- *  ixgbe_blink_led_start_82598 - Blink LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to blink
- **/
-static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
-{
-	ixgbe_link_speed speed = 0;
-	bool link_up = 0;
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	/*
-	 * Link must be up to auto-blink the LEDs on the 82598EB MAC;
-	 * force it if link is down.
-	 */
-	hw->mac.ops.check_link(hw, &speed, &link_up, false);
-
-	if (!link_up) {
-		autoc_reg |= IXGBE_AUTOC_FLU;
-		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		msleep(10);
-	}
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg |= IXGBE_LED_BLINK(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
- *  ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
- *  @hw: pointer to hardware structure
- *  @index: led number to stop blinking
- **/
-static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
-{
-	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-
-	autoc_reg &= ~IXGBE_AUTOC_FLU;
-	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
-	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-
-	led_reg &= ~IXGBE_LED_MODE_MASK(index);
-	led_reg &= ~IXGBE_LED_BLINK(index);
-	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
-	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
-	IXGBE_WRITE_FLUSH(hw);
-
-	return 0;
-}
-
-/**
  *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
  *  @hw: pointer to hardware structure
  *  @reg: analog register to read
@@ -997,11 +995,18 @@ out:
  *
  *  Determines physical layer capabilities of the current configuration.
  **/
-static s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 {
-	s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 
 	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82598:
+		/* Default device ID is mezzanine card KX/KX4 */
+		physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+				  IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+		break;
+	case IXGBE_DEV_ID_82598_BX:
+		physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
 	case IXGBE_DEV_ID_82598EB_CX4:
 	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
 		physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
@@ -1055,8 +1060,11 @@ static struct ixgbe_mac_operations mac_o
 	.clear_hw_cntrs		= &ixgbe_clear_hw_cntrs_generic,
 	.get_media_type		= &ixgbe_get_media_type_82598,
 	.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+	.enable_rx_dma          = &ixgbe_enable_rx_dma_generic,
 	.get_mac_addr		= &ixgbe_get_mac_addr_generic,
 	.stop_adapter		= &ixgbe_stop_adapter_generic,
+	.get_bus_info           = &ixgbe_get_bus_info_generic,
+	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
 	.read_analog_reg8	= &ixgbe_read_analog_reg8_82598,
 	.write_analog_reg8	= &ixgbe_write_analog_reg8_82598,
 	.setup_link		= &ixgbe_setup_mac_link_82598,
@@ -1065,8 +1073,8 @@ static struct ixgbe_mac_operations mac_o
 	.get_link_capabilities	= &ixgbe_get_link_capabilities_82598,
 	.led_on			= &ixgbe_led_on_generic,
 	.led_off		= &ixgbe_led_off_generic,
-	.blink_led_start	= &ixgbe_blink_led_start_82598,
-	.blink_led_stop		= &ixgbe_blink_led_stop_82598,
+	.blink_led_start	= &ixgbe_blink_led_start_generic,
+	.blink_led_stop		= &ixgbe_blink_led_stop_generic,
 	.set_rar		= &ixgbe_set_rar_generic,
 	.clear_rar		= &ixgbe_clear_rar_generic,
 	.set_vmdq		= &ixgbe_set_vmdq_82598,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_82599.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_82599.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_82599.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_82599.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1256 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include "ixgbe.h"
+#include "ixgbe_phy.h"
+
+#define IXGBE_82599_MAX_TX_QUEUES 128
+#define IXGBE_82599_MAX_RX_QUEUES 128
+#define IXGBE_82599_RAR_ENTRIES   128
+#define IXGBE_82599_MC_TBL_SIZE   128
+#define IXGBE_82599_VFT_TBL_SIZE  128
+
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed,
+                                      bool *autoneg);
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed, bool autoneg,
+                                     bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw);
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
+                               ixgbe_link_speed *speed,
+                               bool *link_up, bool link_up_wait_to_complete);
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed,
+                                     bool autoneg,
+                                     bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+                                             ixgbe_link_speed *speed,
+                                             bool *autoneg);
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+                                               ixgbe_link_speed speed,
+                                               bool autoneg,
+                                               bool autoneg_wait_to_complete);
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
+                         u32 vind, bool vlan_on);
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_start_hw_rev_0_82599(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+
+void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	if (hw->phy.multispeed_fiber) {
+		/* Set up dual speed SFP+ support */
+		mac->ops.setup_link =
+		          &ixgbe_setup_mac_link_multispeed_fiber;
+		mac->ops.setup_link_speed =
+		          &ixgbe_setup_mac_link_speed_multispeed_fiber;
+	} else {
+		mac->ops.setup_link =
+		          &ixgbe_setup_mac_link_82599;
+		mac->ops.setup_link_speed =
+		          &ixgbe_setup_mac_link_speed_82599;
+	}
+}
+
+s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
+{
+	s32 ret_val = 0;
+	u16 list_offset, data_offset, data_value;
+
+	if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
+		ixgbe_init_mac_link_ops_82599(hw);
+		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
+		                                              &data_offset);
+
+		if (ret_val != 0)
+			goto setup_sfp_out;
+
+		hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+		while (data_value != 0xffff) {
+			IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
+			IXGBE_WRITE_FLUSH(hw);
+			hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+		}
+		/* Now restart DSP */
+		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
+		IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+
+setup_sfp_out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_get_pcie_msix_count_82599 - Gets MSI-X vector count
+ *  @hw: pointer to hardware structure
+ *
+ *  Read PCIe configuration space, and get the MSI-X vector count from
+ *  the capabilities table.
+ **/
+u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_adapter *adapter = hw->back;
+	u16 msix_count;
+	pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82599_CAPS,
+	                     &msix_count);
+	msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+	/* MSI-X count is zero-based in HW, so increment to give proper value */
+	msix_count++;
+
+	return msix_count;
+}
+
+static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	struct ixgbe_phy_info *phy = &hw->phy;
+	s32 ret_val;
+
+	/* Set the bus information prior to PHY identification */
+	mac->ops.get_bus_info(hw);
+
+	/* Call PHY identify routine to get the Cu or SFI phy type */
+	ret_val = phy->ops.identify(hw);
+
+	if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
+		goto get_invariants_out;
+
+	ixgbe_init_mac_link_ops_82599(hw);
+
+	/* Setup SFP module if there is one present. */
+	ret_val = mac->ops.setup_sfp(hw);
+
+	/* If copper media, overwrite with copper function pointers */
+	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+		mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
+		mac->ops.setup_link_speed =
+		                  &ixgbe_setup_copper_link_speed_82599;
+		mac->ops.get_link_capabilities =
+		                  &ixgbe_get_copper_link_capabilities_82599;
+	}
+
+	/* PHY Init */
+	switch (hw->phy.type) {
+	case ixgbe_phy_tn:
+		phy->ops.check_link = &ixgbe_check_phy_link_tnx;
+		phy->ops.get_firmware_version =
+		                  &ixgbe_get_phy_firmware_version_tnx;
+		break;
+	default:
+		break;
+	}
+
+	mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+	mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+	mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+	mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+	mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+	mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
+
+get_invariants_out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_get_link_capabilities_82599 - Determines link capabilities
+ *  @hw: pointer to hardware structure
+ *  @speed: pointer to link speed
+ *  @negotiation: true when autoneg or autotry is enabled
+ *
+ *  Determines the link capabilities by reading the AUTOC register.
+ **/
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed,
+                                      bool *negotiation)
+{
+	s32 status = 0;
+
+	switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+	case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_1G_AN:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_10G_SERIAL:
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+		*negotiation = false;
+		break;
+
+	case IXGBE_AUTOC_LMS_KX4_KX_KR:
+	case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+		*speed = IXGBE_LINK_SPEED_UNKNOWN;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
+		*speed = IXGBE_LINK_SPEED_100_FULL;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+			*speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+			*speed |= IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+		break;
+
+	case IXGBE_AUTOC_LMS_SGMII_1G_100M:
+		*speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
+		*negotiation = false;
+		break;
+
+	default:
+		status = IXGBE_ERR_LINK_SETUP;
+		goto out;
+		break;
+	}
+
+	if (hw->phy.multispeed_fiber) {
+		*speed |= IXGBE_LINK_SPEED_10GB_FULL |
+		          IXGBE_LINK_SPEED_1GB_FULL;
+		*negotiation = true;
+	}
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities
+ *  @hw: pointer to hardware structure
+ *  @speed: pointer to link speed
+ *  @autoneg: boolean auto-negotiation value
+ *
+ *  Determines the link capabilities by reading the AUTOC register.
+ **/
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+                                                    ixgbe_link_speed *speed,
+                                                    bool *autoneg)
+{
+	s32 status = IXGBE_ERR_LINK_SETUP;
+	u16 speed_ability;
+
+	*speed = 0;
+	*autoneg = true;
+
+	status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+	                              IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+	                              &speed_ability);
+
+	if (status == 0) {
+		if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+		    *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+		if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+		    *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_get_media_type_82599 - Get media type
+ *  @hw: pointer to hardware structure
+ *
+ *  Returns the media type (fiber, copper, backplane)
+ **/
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
+{
+	enum ixgbe_media_type media_type;
+
+	/* Detect if there is a copper PHY attached. */
+	if (hw->phy.type == ixgbe_phy_cu_unknown ||
+	    hw->phy.type == ixgbe_phy_tn) {
+		media_type = ixgbe_media_type_copper;
+		goto out;
+	}
+
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82599:
+	case IXGBE_DEV_ID_82599_KX4:
+		/* Default device ID is mezzanine card KX/KX4 */
+		media_type = ixgbe_media_type_backplane;
+		break;
+	case IXGBE_DEV_ID_82599_SFP:
+		media_type = ixgbe_media_type_fiber;
+		break;
+	default:
+		media_type = ixgbe_media_type_unknown;
+		break;
+	}
+out:
+	return media_type;
+}
+
+/**
+ *  ixgbe_setup_mac_link_82599 - Setup MAC link settings
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures link settings based on values in the ixgbe_hw struct.
+ *  Restarts the link.  Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
+{
+	u32 autoc_reg;
+	u32 links_reg;
+	u32 i;
+	s32 status = 0;
+
+	/* Restart link */
+	autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+	/* Only poll for autoneg to complete if specified to do so */
+	if (hw->phy.autoneg_wait_to_complete) {
+		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		     IXGBE_AUTOC_LMS_KX4_KX_KR ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		     IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+		     IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+			links_reg = 0; /* Just in case Autoneg time = 0 */
+			for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+				links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+				if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+					break;
+				msleep(100);
+			}
+			if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+				status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+				hw_dbg(hw, "Autoneg did not complete.\n");
+			}
+		}
+	}
+
+	/* Set up flow control */
+	status = ixgbe_setup_fc_generic(hw, 0);
+
+	/* Add delay to filter out noises during initial link setup */
+	msleep(50);
+
+	return status;
+}
+
+/**
+ *  ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures link settings based on values in the ixgbe_hw struct.
+ *  Restarts the link for multi-speed fiber at 1G speed, if link
+ *  fails at 10G.
+ *  Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
+{
+	s32 status = 0;
+	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG;
+	status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, link_speed,
+	                                                     true, true);
+	return status;
+}
+
+/**
+ *  ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed
+ *  @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
+ *
+ *  Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+                                                ixgbe_link_speed speed,
+                                                bool autoneg,
+                                                bool autoneg_wait_to_complete)
+{
+	s32 status = 0;
+	ixgbe_link_speed phy_link_speed;
+	ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+	u32 speedcnt = 0;
+	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+	bool link_up = false;
+	bool negotiation;
+
+	/* Mask off requested but non-supported speeds */
+	hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
+	speed &= phy_link_speed;
+
+	/*
+	 * Try each speed one by one, highest priority first.  We do this in
+	 * software because 10gb fiber doesn't support speed autonegotiation.
+	 */
+	if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+		speedcnt++;
+		highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+		/* Set hardware SDP's */
+		esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+		ixgbe_setup_mac_link_speed_82599(hw,
+		                                 IXGBE_LINK_SPEED_10GB_FULL,
+		                                 autoneg,
+		                                 autoneg_wait_to_complete);
+
+		msleep(50);
+
+		/* If we have link, just jump out */
+		hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+		if (link_up)
+			goto out;
+	}
+
+	if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+		speedcnt++;
+		if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+			highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+		/* Set hardware SDP's */
+		esdp_reg &= ~IXGBE_ESDP_SDP5;
+		esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+		ixgbe_setup_mac_link_speed_82599(
+			hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
+			autoneg_wait_to_complete);
+
+		msleep(50);
+
+		/* If we have link, just jump out */
+		hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+		if (link_up)
+			goto out;
+	}
+
+	/*
+	 * We didn't get link.  Configure back to the highest speed we tried,
+	 * (if there was more than one).  We call ourselves back with just the
+	 * single highest speed that the user requested.
+	 */
+	if (speedcnt > 1)
+		status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
+		                                     highest_link_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
+ *  @link_up: true when link is up
+ *  @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ *  Reads the links register to determine if link is up and the current speed
+ **/
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+                               bool *link_up, bool link_up_wait_to_complete)
+{
+	u32 links_reg;
+	u32 i;
+
+	links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+	if (link_up_wait_to_complete) {
+		for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+			if (links_reg & IXGBE_LINKS_UP) {
+				*link_up = true;
+				break;
+			} else {
+				*link_up = false;
+			}
+			msleep(100);
+			links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+		}
+	} else {
+		if (links_reg & IXGBE_LINKS_UP)
+			*link_up = true;
+		else
+			*link_up = false;
+	}
+
+	if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+	    IXGBE_LINKS_SPEED_10G_82599)
+		*speed = IXGBE_LINK_SPEED_10GB_FULL;
+	else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+	         IXGBE_LINKS_SPEED_1G_82599)
+		*speed = IXGBE_LINK_SPEED_1GB_FULL;
+	else
+		*speed = IXGBE_LINK_SPEED_100_FULL;
+
+
+	return 0;
+}
+
+/**
+ *  ixgbe_setup_mac_link_speed_82599 - Set MAC link speed
+ *  @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
+ *
+ *  Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed, bool autoneg,
+                                     bool autoneg_wait_to_complete)
+{
+	s32 status = 0;
+	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+	u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+	u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+	u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+	u32 links_reg;
+	u32 i;
+	ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+
+	/* Check to see if speed passed in is supported. */
+	hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
+	speed &= link_capabilities;
+
+	if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
+		status = IXGBE_ERR_LINK_SETUP;
+	} else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+	           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+	           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+		/* Set KX4/KX/KR support according to speed requested */
+		autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
+		if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+			if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+				autoc |= IXGBE_AUTOC_KX4_SUPP;
+			if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+				autoc |= IXGBE_AUTOC_KR_SUPP;
+		if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+			autoc |= IXGBE_AUTOC_KX_SUPP;
+	} else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
+	           (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
+	            link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
+		/* Switch from 1G SFI to 10G SFI if requested */
+		if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
+		    (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
+			autoc &= ~IXGBE_AUTOC_LMS_MASK;
+			autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
+		}
+	} else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
+	           (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
+		/* Switch from 10G SFI to 1G SFI if requested */
+		if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+		    (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
+			autoc &= ~IXGBE_AUTOC_LMS_MASK;
+			if (autoneg)
+				autoc |= IXGBE_AUTOC_LMS_1G_AN;
+			else
+				autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
+		}
+	}
+
+	if (status == 0) {
+		/* Restart link */
+		autoc |= IXGBE_AUTOC_AN_RESTART;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+
+		/* Only poll for autoneg to complete if specified to do so */
+		if (autoneg_wait_to_complete) {
+			if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+			    link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+				links_reg = 0; /*Just in case Autoneg time=0*/
+				for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+					links_reg =
+					       IXGBE_READ_REG(hw, IXGBE_LINKS);
+					if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+						break;
+					msleep(100);
+				}
+				if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+					status =
+					        IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+					hw_dbg(hw, "Autoneg did not "
+					       "complete.\n");
+				}
+			}
+		}
+
+		/* Set up flow control */
+		status = ixgbe_setup_fc_generic(hw, 0);
+
+		/* Add delay to filter out noises during initial link setup */
+		msleep(50);
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_setup_copper_link_82599 - Setup copper link settings
+ *  @hw: pointer to hardware structure
+ *
+ *  Restarts the link on PHY and then MAC. Performs autonegotiation if needed.
+ **/
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
+{
+	s32 status;
+
+	/* Restart autonegotiation on PHY */
+	status = hw->phy.ops.setup_link(hw);
+
+	/* Set up MAC */
+	ixgbe_setup_mac_link_82599(hw);
+
+	return status;
+}
+
+/**
+ *  ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field
+ *  @hw: pointer to hardware structure
+ *  @speed: new link speed
+ *  @autoneg: true if autonegotiation enabled
+ *  @autoneg_wait_to_complete: true if waiting is needed to complete
+ *
+ *  Restarts link on PHY and MAC based on settings passed in.
+ **/
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+                                               ixgbe_link_speed speed,
+                                               bool autoneg,
+                                               bool autoneg_wait_to_complete)
+{
+	s32 status;
+
+	/* Setup the PHY according to input speed */
+	status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+	                                      autoneg_wait_to_complete);
+	/* Set up MAC */
+	ixgbe_setup_mac_link_82599(hw);
+
+	return status;
+}
+
+/**
+ *  ixgbe_reset_hw_82599 - Perform hardware reset
+ *  @hw: pointer to hardware structure
+ *
+ *  Resets the hardware by resetting the transmit and receive units, masks
+ *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ *  reset.
+ **/
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
+{
+	s32 status = 0;
+	u32 ctrl, ctrl_ext;
+	u32 i;
+	u32 autoc;
+	u32 autoc2;
+
+	/* Call adapter stop to disable tx/rx and clear interrupts */
+	hw->mac.ops.stop_adapter(hw);
+
+	/* Reset PHY */
+	hw->phy.ops.reset(hw);
+
+	/*
+	 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+	 * access and verify no pending requests before reset
+	 */
+	if (ixgbe_disable_pcie_master(hw) != 0) {
+		status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+	}
+
+	/*
+	 * Issue global reset to the MAC.  This needs to be a SW reset.
+	 * If link reset is used, it might reset the MAC when mng is using it
+	 */
+	ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+	IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* Poll for reset bit to self-clear indicating reset is complete */
+	for (i = 0; i < 10; i++) {
+		udelay(1);
+		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+		if (!(ctrl & IXGBE_CTRL_RST))
+			break;
+	}
+	if (ctrl & IXGBE_CTRL_RST) {
+		status = IXGBE_ERR_RESET_FAILED;
+		hw_dbg(hw, "Reset polling failed to complete.\n");
+	}
+	/* Clear PF Reset Done bit so PF/VF Mail Ops can work */
+	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+	ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
+	IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+	msleep(50);
+
+
+
+	/*
+	 * Store the original AUTOC/AUTOC2 values if they have not been
+	 * stored off yet.  Otherwise restore the stored original
+	 * values since the reset operation sets back to defaults.
+	 */
+	autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+	if (hw->mac.orig_link_settings_stored == false) {
+		hw->mac.orig_autoc = autoc;
+		hw->mac.orig_autoc2 = autoc2;
+		hw->mac.orig_link_settings_stored = true;
+	} else {
+		if (autoc != hw->mac.orig_autoc)
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
+			                IXGBE_AUTOC_AN_RESTART));
+
+		if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
+		    (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
+			autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
+			autoc2 |= (hw->mac.orig_autoc2 &
+			           IXGBE_AUTOC2_UPPER_MASK);
+			IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+		}
+	}
+
+	/* Store the permanent mac address */
+	hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+	return status;
+}
+
+/**
+ *  ixgbe_clear_vmdq_82599 - Disassociate a VMDq pool index from a rx address
+ *  @hw: pointer to hardware struct
+ *  @rar: receive address register index to disassociate
+ *  @vmdq: VMDq pool index to remove from the rar
+ **/
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+	u32 mpsar_lo, mpsar_hi;
+	u32 rar_entries = hw->mac.num_rar_entries;
+
+	if (rar < rar_entries) {
+		mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+		mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+
+		if (!mpsar_lo && !mpsar_hi)
+			goto done;
+
+		if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
+			if (mpsar_lo) {
+				IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
+				mpsar_lo = 0;
+			}
+			if (mpsar_hi) {
+				IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
+				mpsar_hi = 0;
+			}
+		} else if (vmdq < 32) {
+			mpsar_lo &= ~(1 << vmdq);
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
+		} else {
+			mpsar_hi &= ~(1 << (vmdq - 32));
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
+		}
+
+		/* was that the last pool using this rar? */
+		if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
+			hw->mac.ops.clear_rar(hw, rar);
+	} else {
+		hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+	}
+
+done:
+	return 0;
+}
+
+/**
+ *  ixgbe_set_vmdq_82599 - Associate a VMDq pool index with a rx address
+ *  @hw: pointer to hardware struct
+ *  @rar: receive address register index to associate with a VMDq index
+ *  @vmdq: VMDq pool index
+ **/
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+	u32 mpsar;
+	u32 rar_entries = hw->mac.num_rar_entries;
+
+	if (rar < rar_entries) {
+		if (vmdq < 32) {
+			mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+			mpsar |= 1 << vmdq;
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
+		} else {
+			mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+			mpsar |= 1 << (vmdq - 32);
+			IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
+		}
+	} else {
+		hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+	}
+	return 0;
+}
+
+/**
+ *  ixgbe_set_vfta_82599 - Set VLAN filter table
+ *  @hw: pointer to hardware structure
+ *  @vlan: VLAN id to write to VLAN filter
+ *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
+ *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *
+ *  Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+                         bool vlan_on)
+{
+	u32 regindex;
+	u32 bitindex;
+	u32 bits;
+	u32 first_empty_slot;
+
+	if (vlan > 4095)
+		return IXGBE_ERR_PARAM;
+
+	/*
+	 * this is a 2 part operation - first the VFTA, then the
+	 * VLVF and VLVFB if vind is set
+	 */
+
+	/* Part 1
+	 * The VFTA is a bitstring made up of 128 32-bit registers
+	 * that enable the particular VLAN id, much like the MTA:
+	 *    bits[11-5]: which register
+	 *    bits[4-0]:  which bit in the register
+	 */
+	regindex = (vlan >> 5) & 0x7F;
+	bitindex = vlan & 0x1F;
+	bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+	if (vlan_on)
+		bits |= (1 << bitindex);
+	else
+		bits &= ~(1 << bitindex);
+	IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+
+	/* Part 2
+	 * If the vind is set
+	 *   Either vlan_on
+	 *     make sure the vlan is in VLVF
+	 *     set the vind bit in the matching VLVFB
+	 *   Or !vlan_on
+	 *     clear the pool bit and possibly the vind
+	 */
+	if (vind) {
+		/* find the vlanid or the first empty slot */
+		first_empty_slot = 0;
+
+		for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+			bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
+			if (!bits && !first_empty_slot)
+				first_empty_slot = regindex;
+			else if ((bits & 0x0FFF) == vlan)
+				break;
+		}
+
+		if (regindex >= IXGBE_VLVF_ENTRIES) {
+			if (first_empty_slot)
+				regindex = first_empty_slot;
+			else {
+				hw_dbg(hw, "No space in VLVF.\n");
+				goto out;
+			}
+		}
+
+		if (vlan_on) {
+			/* set the pool bit */
+			if (vind < 32) {
+				bits = IXGBE_READ_REG(hw,
+				                    IXGBE_VLVFB(regindex * 2));
+				bits |= (1 << vind);
+				IXGBE_WRITE_REG(hw,
+				              IXGBE_VLVFB(regindex * 2), bits);
+			} else {
+				bits = IXGBE_READ_REG(hw,
+				              IXGBE_VLVFB((regindex * 2) + 1));
+				bits |= (1 << vind);
+				IXGBE_WRITE_REG(hw,
+				        IXGBE_VLVFB((regindex * 2) + 1), bits);
+			}
+		} else {
+			/* clear the pool bit */
+			if (vind < 32) {
+				bits = IXGBE_READ_REG(hw,
+				     IXGBE_VLVFB(regindex * 2));
+			bits &= ~(1 << vind);
+				IXGBE_WRITE_REG(hw,
+				              IXGBE_VLVFB(regindex * 2), bits);
+				bits |= IXGBE_READ_REG(hw,
+				              IXGBE_VLVFB((regindex * 2) + 1));
+			} else {
+				bits = IXGBE_READ_REG(hw,
+				              IXGBE_VLVFB((regindex * 2) + 1));
+				bits &= ~(1 << vind);
+				IXGBE_WRITE_REG(hw,
+				        IXGBE_VLVFB((regindex * 2) + 1), bits);
+				bits |= IXGBE_READ_REG(hw,
+				                    IXGBE_VLVFB(regindex * 2));
+			}
+		}
+
+		if (bits)
+			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
+			                (IXGBE_VLVF_VIEN | vlan));
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+	}
+
+out:
+	return 0;
+}
+
+/**
+ *  ixgbe_clear_vfta_82599 - Clear VLAN filter table
+ *  @hw: pointer to hardware structure
+ *
+ *  Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < hw->mac.vft_size; offset++)
+		IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+	for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
+		IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
+	}
+
+	return 0;
+}
+
+/**
+ *  ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
+ *  @hw: pointer to hardware structure
+ **/
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
+{
+	int i;
+	hw_dbg(hw, " Clearing UTA\n");
+
+	for (i = 0; i < 128; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: analog register to read
+ *  @val: read value
+ *
+ *  Performs read operation to Omer analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+	u32  core_ctl;
+
+	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
+	                (reg << 8));
+	IXGBE_WRITE_FLUSH(hw);
+	udelay(10);
+	core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
+	*val = (u8)core_ctl;
+
+	return 0;
+}
+
+/**
+ *  ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: atlas register to write
+ *  @val: value to write
+ *
+ *  Performs write operation to Omer analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+	u32  core_ctl;
+
+	core_ctl = (reg << 8) | val;
+	IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
+	IXGBE_WRITE_FLUSH(hw);
+	udelay(10);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
+ *  @hw: pointer to hardware structure
+ *
+ *  Starts the hardware using the generic start_hw function.
+ *  Then performs device-specific:
+ *  Clears the rate limiter registers.
+ **/
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+{
+	u32 q_num;
+
+	ixgbe_start_hw_generic(hw);
+
+	/* Clear the rate limiters */
+	for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
+		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+	}
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_identify_phy_82599 - Get physical layer module
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines the physical layer module found on the current adapter.
+ **/
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+{
+	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+	status = ixgbe_identify_phy_generic(hw);
+	if (status != 0)
+		status = ixgbe_identify_sfp_module_generic(hw);
+	return status;
+}
+
+/**
+ *  ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+{
+	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+	u8 comp_codes_10g = 0;
+
+	switch (hw->device_id) {
+	case IXGBE_DEV_ID_82599:
+	case IXGBE_DEV_ID_82599_KX4:
+		/* Default device ID is mezzanine card KX/KX4 */
+		physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+		                  IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+		break;
+	case IXGBE_DEV_ID_82599_SFP:
+		hw->phy.ops.identify_sfp(hw);
+
+		switch (hw->phy.sfp_type) {
+		case ixgbe_sfp_type_da_cu:
+		case ixgbe_sfp_type_da_cu_core0:
+		case ixgbe_sfp_type_da_cu_core1:
+			physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+			break;
+		case ixgbe_sfp_type_sr:
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+			break;
+		case ixgbe_sfp_type_lr:
+			physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+			break;
+		case ixgbe_sfp_type_srlr_core0:
+		case ixgbe_sfp_type_srlr_core1:
+			hw->phy.ops.read_i2c_eeprom(hw,
+			                            IXGBE_SFF_10GBE_COMP_CODES,
+			                            &comp_codes_10g);
+			if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+				physical_layer =
+				                IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+				physical_layer =
+				                IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+			else
+				physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+		default:
+			physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+		break;
+	}
+
+	return physical_layer;
+}
+
+/**
+ *  ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
+ *  @hw: pointer to hardware structure
+ *  @regval: register value to write to RXCTRL
+ *
+ *  Enables the Rx DMA unit for 82599
+ **/
+s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+{
+#define IXGBE_MAX_SECRX_POLL 30
+	int i;
+	int secrxreg;
+
+	/*
+	 * Workaround for 82599 silicon errata when enabling the Rx datapath.
+	 * If traffic is incoming before we enable the Rx unit, it could hang
+	 * the Rx DMA unit.  Therefore, make sure the security engine is
+	 * completely disabled prior to enabling the Rx unit.
+	 */
+	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+	for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
+		secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
+		if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
+			break;
+		else
+			udelay(10);
+	}
+
+	/* For informational purposes only */
+	if (i >= IXGBE_MAX_SECRX_POLL)
+		hw_dbg(hw, "Rx unit being enabled before security "
+		       "path fully disabled.  Continuing with init.\n");
+
+	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+	secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+static struct ixgbe_mac_operations mac_ops_82599 = {
+	.init_hw                = &ixgbe_init_hw_generic,
+	.reset_hw               = &ixgbe_reset_hw_82599,
+	.start_hw               = &ixgbe_start_hw_82599,
+	.clear_hw_cntrs         = &ixgbe_clear_hw_cntrs_generic,
+	.get_media_type         = &ixgbe_get_media_type_82599,
+	.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
+	.enable_rx_dma          = &ixgbe_enable_rx_dma_82599,
+	.get_mac_addr           = &ixgbe_get_mac_addr_generic,
+	.stop_adapter           = &ixgbe_stop_adapter_generic,
+	.get_bus_info           = &ixgbe_get_bus_info_generic,
+	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
+	.read_analog_reg8       = &ixgbe_read_analog_reg8_82599,
+	.write_analog_reg8      = &ixgbe_write_analog_reg8_82599,
+	.setup_link             = &ixgbe_setup_mac_link_82599,
+	.setup_link_speed       = &ixgbe_setup_mac_link_speed_82599,
+	.check_link             = &ixgbe_check_mac_link_82599,
+	.get_link_capabilities  = &ixgbe_get_link_capabilities_82599,
+	.led_on                 = &ixgbe_led_on_generic,
+	.led_off                = &ixgbe_led_off_generic,
+	.blink_led_start        = &ixgbe_blink_led_start_generic,
+	.blink_led_stop         = &ixgbe_blink_led_stop_generic,
+	.set_rar                = &ixgbe_set_rar_generic,
+	.clear_rar              = &ixgbe_clear_rar_generic,
+	.set_vmdq               = &ixgbe_set_vmdq_82599,
+	.clear_vmdq             = &ixgbe_clear_vmdq_82599,
+	.init_rx_addrs          = &ixgbe_init_rx_addrs_generic,
+	.update_uc_addr_list    = &ixgbe_update_uc_addr_list_generic,
+	.update_mc_addr_list    = &ixgbe_update_mc_addr_list_generic,
+	.enable_mc              = &ixgbe_enable_mc_generic,
+	.disable_mc             = &ixgbe_disable_mc_generic,
+	.clear_vfta             = &ixgbe_clear_vfta_82599,
+	.set_vfta               = &ixgbe_set_vfta_82599,
+	.setup_fc               = &ixgbe_setup_fc_generic,
+	.init_uta_tables        = &ixgbe_init_uta_tables_82599,
+	.setup_sfp              = &ixgbe_setup_sfp_modules_82599,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
+	.init_params            = &ixgbe_init_eeprom_params_generic,
+	.read                   = &ixgbe_read_eeprom_generic,
+	.write                  = &ixgbe_write_eeprom_generic,
+	.validate_checksum      = &ixgbe_validate_eeprom_checksum_generic,
+	.update_checksum        = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82599 = {
+	.identify               = &ixgbe_identify_phy_82599,
+	.identify_sfp           = &ixgbe_identify_sfp_module_generic,
+	.reset                  = &ixgbe_reset_phy_generic,
+	.read_reg               = &ixgbe_read_phy_reg_generic,
+	.write_reg              = &ixgbe_write_phy_reg_generic,
+	.setup_link             = &ixgbe_setup_phy_link_generic,
+	.setup_link_speed       = &ixgbe_setup_phy_link_speed_generic,
+	.read_i2c_byte          = &ixgbe_read_i2c_byte_generic,
+	.write_i2c_byte         = &ixgbe_write_i2c_byte_generic,
+	.read_i2c_eeprom        = &ixgbe_read_i2c_eeprom_generic,
+	.write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic,
+};
+
+struct ixgbe_info ixgbe_82599_info = {
+	.mac                    = ixgbe_mac_82599EB,
+	.get_invariants         = &ixgbe_get_invariants_82599,
+	.mac_ops                = &mac_ops_82599,
+	.eeprom_ops             = &eeprom_ops_82599,
+	.phy_ops                = &phy_ops_82599,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_common.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_common.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 
+#include "ixgbe.h"
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
 
@@ -49,7 +50,6 @@ static u16 ixgbe_calc_eeprom_checksum(st
 static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
 static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
 static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
-static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
 static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
 
 /**
@@ -80,9 +80,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_
 	/* Clear the VLAN filter table */
 	hw->mac.ops.clear_vfta(hw);
 
-	/* Set up link */
-	hw->mac.ops.setup_link(hw);
-
 	/* Clear statistics registers */
 	hw->mac.ops.clear_hw_cntrs(hw);
 
@@ -254,6 +251,81 @@ s32 ixgbe_get_mac_addr_generic(struct ix
 }
 
 /**
+ *  ixgbe_get_bus_info_generic - Generic set PCI bus info
+ *  @hw: pointer to hardware structure
+ *
+ *  Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
+ **/
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
+{
+	struct ixgbe_adapter *adapter = hw->back;
+	struct ixgbe_mac_info *mac = &hw->mac;
+	u16 link_status;
+
+	hw->bus.type = ixgbe_bus_type_pci_express;
+
+	/* Get the negotiated link width and speed from PCI config space */
+	pci_read_config_word(adapter->pdev, IXGBE_PCI_LINK_STATUS,
+	                     &link_status);
+
+	switch (link_status & IXGBE_PCI_LINK_WIDTH) {
+	case IXGBE_PCI_LINK_WIDTH_1:
+		hw->bus.width = ixgbe_bus_width_pcie_x1;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_2:
+		hw->bus.width = ixgbe_bus_width_pcie_x2;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_4:
+		hw->bus.width = ixgbe_bus_width_pcie_x4;
+		break;
+	case IXGBE_PCI_LINK_WIDTH_8:
+		hw->bus.width = ixgbe_bus_width_pcie_x8;
+		break;
+	default:
+		hw->bus.width = ixgbe_bus_width_unknown;
+		break;
+	}
+
+	switch (link_status & IXGBE_PCI_LINK_SPEED) {
+	case IXGBE_PCI_LINK_SPEED_2500:
+		hw->bus.speed = ixgbe_bus_speed_2500;
+		break;
+	case IXGBE_PCI_LINK_SPEED_5000:
+		hw->bus.speed = ixgbe_bus_speed_5000;
+		break;
+	default:
+		hw->bus.speed = ixgbe_bus_speed_unknown;
+		break;
+	}
+
+	mac->ops.set_lan_id(hw);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines the LAN function id by reading memory-mapped registers
+ *  and swaps the port value if requested.
+ **/
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
+{
+	struct ixgbe_bus_info *bus = &hw->bus;
+	u32 reg;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
+	bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
+	bus->lan_id = bus->func;
+
+	/* check for a port swap */
+	reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+	if (reg & IXGBE_FACTPS_LFS)
+		bus->func ^= 0x1;
+}
+
+/**
  *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
  *  @hw: pointer to hardware structure
  *
@@ -393,6 +465,73 @@ s32 ixgbe_init_eeprom_params_generic(str
 }
 
 /**
+ *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be written to
+ *  @data: 16 bit word to be written to the EEPROM
+ *
+ *  If ixgbe_eeprom_update_checksum is not called after this function, the
+ *  EEPROM will most likely contain an invalid checksum.
+ **/
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+	s32 status;
+	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
+	hw->eeprom.ops.init_params(hw);
+
+	if (offset >= hw->eeprom.word_size) {
+		status = IXGBE_ERR_EEPROM;
+		goto out;
+	}
+
+	/* Prepare the EEPROM for writing  */
+	status = ixgbe_acquire_eeprom(hw);
+
+	if (status == 0) {
+		if (ixgbe_ready_eeprom(hw) != 0) {
+			ixgbe_release_eeprom(hw);
+			status = IXGBE_ERR_EEPROM;
+		}
+	}
+
+	if (status == 0) {
+		ixgbe_standby_eeprom(hw);
+
+		/*  Send the WRITE ENABLE command (8 bit opcode )  */
+		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
+		                            IXGBE_EEPROM_OPCODE_BITS);
+
+		ixgbe_standby_eeprom(hw);
+
+		/*
+		 * Some SPI eeproms use the 8th address bit embedded in the
+		 * opcode
+		 */
+		if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+			write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+		/* Send the Write command (8-bit opcode + addr) */
+		ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+		                            IXGBE_EEPROM_OPCODE_BITS);
+		ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+		                            hw->eeprom.address_bits);
+
+		/* Send the data */
+		data = (data >> 8) | (data << 8);
+		ixgbe_shift_out_eeprom_bits(hw, data, 16);
+		ixgbe_standby_eeprom(hw);
+
+		msleep(hw->eeprom.semaphore_delay);
+		/* Done with writing - release the EEPROM */
+		ixgbe_release_eeprom(hw);
+	}
+
+out:
+	return status;
+}
+
+/**
  *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
  *  @hw: pointer to hardware structure
  *  @offset: offset within the EEPROM to be read
@@ -521,7 +660,7 @@ static s32 ixgbe_poll_eeprom_eerd_done(s
 static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
 {
 	s32 status = 0;
-	u32 eec;
+	u32 eec = 0;
 	u32 i;
 
 	if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
@@ -1237,8 +1376,7 @@ s32 ixgbe_update_uc_addr_list_generic(st
 	 * Clear accounting of old secondary address list,
 	 * don't count RAR[0]
 	 */
-	uc_addr_in_use = hw->addr_ctrl.rar_used_count -
-	                 hw->addr_ctrl.mc_addr_in_rar_count - 1;
+	uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1;
 	hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
 	hw->addr_ctrl.overflow_promisc = 0;
 
@@ -1353,40 +1491,6 @@ static void ixgbe_set_mta(struct ixgbe_h
 }
 
 /**
- *  ixgbe_add_mc_addr - Adds a multicast address.
- *  @hw: pointer to hardware structure
- *  @mc_addr: new multicast address
- *
- *  Adds it to unused receive address register or to the multicast table.
- **/
-static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
-{
-	u32 rar_entries = hw->mac.num_rar_entries;
-	u32 rar;
-
-	hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
-	       mc_addr[0], mc_addr[1], mc_addr[2],
-	       mc_addr[3], mc_addr[4], mc_addr[5]);
-
-	/*
-	 * Place this multicast address in the RAR if there is room,
-	 * else put it in the MTA
-	 */
-	if (hw->addr_ctrl.rar_used_count < rar_entries) {
-		/* use RAR from the end up for multicast */
-		rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1;
-		hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV);
-		hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar);
-		hw->addr_ctrl.rar_used_count++;
-		hw->addr_ctrl.mc_addr_in_rar_count++;
-	} else {
-		ixgbe_set_mta(hw, mc_addr);
-	}
-
-	hw_dbg(hw, "ixgbe_add_mc_addr Complete\n");
-}
-
-/**
  *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
  *  @hw: pointer to hardware structure
  *  @mc_addr_list: the list of new multicast addresses
@@ -1402,7 +1506,6 @@ s32 ixgbe_update_mc_addr_list_generic(st
                                       u32 mc_addr_count, ixgbe_mc_addr_itr next)
 {
 	u32 i;
-	u32 rar_entries = hw->mac.num_rar_entries;
 	u32 vmdq;
 
 	/*
@@ -1410,18 +1513,8 @@ s32 ixgbe_update_mc_addr_list_generic(st
 	 * use.
 	 */
 	hw->addr_ctrl.num_mc_addrs = mc_addr_count;
-	hw->addr_ctrl.rar_used_count -= hw->addr_ctrl.mc_addr_in_rar_count;
-	hw->addr_ctrl.mc_addr_in_rar_count = 0;
 	hw->addr_ctrl.mta_in_use = 0;
 
-	/* Zero out the other receive addresses. */
-	hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count,
-	          rar_entries - 1);
-	for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) {
-		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
-	}
-
 	/* Clear the MTA */
 	hw_dbg(hw, " Clearing MTA\n");
 	for (i = 0; i < hw->mac.mcft_size; i++)
@@ -1430,7 +1523,7 @@ s32 ixgbe_update_mc_addr_list_generic(st
 	/* Add the new addresses */
 	for (i = 0; i < mc_addr_count; i++) {
 		hw_dbg(hw, " Adding the multicast addresses:\n");
-		ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq));
+		ixgbe_set_mta(hw, next(hw, &mc_addr_list, &vmdq));
 	}
 
 	/* Enable mta */
@@ -1490,6 +1583,327 @@ s32 ixgbe_disable_mc_generic(struct ixgb
 }
 
 /**
+ *  ixgbe_fc_enable - Enable flow control
+ *  @hw: pointer to hardware structure
+ *  @packetbuf_num: packet buffer number (0-7)
+ *
+ *  Enable flow control according to the current settings.
+ **/
+s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+	s32 ret_val = 0;
+	u32 mflcn_reg;
+	u32 fccfg_reg;
+	u32 reg;
+
+	mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+	mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
+
+	fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+	fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
+
+	/*
+	 * The possible values of fc.current_mode are:
+	 * 0: Flow control is completely disabled
+	 * 1: Rx flow control is enabled (we can receive pause frames,
+	 *    but not send pause frames).
+	 * 2: Tx flow control is enabled (we can send pause frames but
+	 *    we do not support receiving pause frames).
+	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
+	 * 4: Priority Flow Control is enabled.
+	 * other: Invalid.
+	 */
+	switch (hw->fc.current_mode) {
+	case ixgbe_fc_none:
+		/* Flow control completely disabled by software override. */
+		break;
+	case ixgbe_fc_rx_pause:
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
+		 */
+		mflcn_reg |= IXGBE_MFLCN_RFCE;
+		break;
+	case ixgbe_fc_tx_pause:
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
+		 */
+		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+		break;
+	case ixgbe_fc_full:
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		mflcn_reg |= IXGBE_MFLCN_RFCE;
+		fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+		break;
+#ifdef CONFIG_DCB
+	case ixgbe_fc_pfc:
+		goto out;
+		break;
+#endif
+	default:
+		hw_dbg(hw, "Flow control param set incorrectly\n");
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
+		break;
+	}
+
+	/* Enable 802.3x based flow control settings. */
+	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
+	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
+
+	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
+	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+		if (hw->fc.send_xon)
+			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+			                (hw->fc.low_water | IXGBE_FCRTL_XONE));
+		else
+			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+			                hw->fc.low_water);
+
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
+		                (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+	}
+
+	/* Configure pause time (2 TCs per register) */
+	reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+	if ((packetbuf_num & 1) == 0)
+		reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+	else
+		reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+	IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
+	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_fc_autoneg - Configure flow control
+ *  @hw: pointer to hardware structure
+ *
+ *  Negotiates flow control capabilities with link partner using autoneg and
+ *  applies the results.
+ **/
+s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
+{
+	s32 ret_val = 0;
+	u32 i, reg, pcs_anadv_reg, pcs_lpab_reg;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+
+	/*
+	 * The possible values of fc.current_mode are:
+	 * 0:  Flow control is completely disabled
+	 * 1:  Rx flow control is enabled (we can receive pause frames,
+	 *     but not send pause frames).
+	 * 2:  Tx flow control is enabled (we can send pause frames but
+	 *     we do not support receiving pause frames).
+	 * 3:  Both Rx and Tx flow control (symmetric) are enabled.
+	 * 4:  Priority Flow Control is enabled.
+	 * other: Invalid.
+	 */
+	switch (hw->fc.current_mode) {
+	case ixgbe_fc_none:
+		/* Flow control completely disabled by software override. */
+		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+	case ixgbe_fc_rx_pause:
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is
+		 * disabled by software override. Since there really
+		 * isn't a way to advertise that we are capable of RX
+		 * Pause ONLY, we will advertise that we support both
+		 * symmetric and asymmetric Rx PAUSE.  Later, we will
+		 * disable the adapter's ability to send PAUSE frames.
+		 */
+		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+	case ixgbe_fc_tx_pause:
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is
+		 * disabled by software override.
+		 */
+		reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
+		reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
+		break;
+	case ixgbe_fc_full:
+		/* Flow control (both Rx and Tx) is enabled by SW override. */
+		reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+		break;
+#ifdef CONFIG_DCB
+	case ixgbe_fc_pfc:
+		goto out;
+		break;
+#endif
+	default:
+		hw_dbg(hw, "Flow control param set incorrectly\n");
+		ret_val = -IXGBE_ERR_CONFIG;
+		goto out;
+		break;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+	reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+	/* Set PCS register for autoneg */
+	/* Enable and restart autoneg */
+	reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
+
+	/* Disable AN timeout */
+	if (hw->fc.strict_ieee)
+		reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+	hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
+	IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+
+	/* See if autonegotiation has succeeded */
+	hw->mac.autoneg_succeeded = 0;
+	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
+		msleep(10);
+		reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+		if ((reg & (IXGBE_PCS1GLSTA_LINK_OK |
+		     IXGBE_PCS1GLSTA_AN_COMPLETE)) ==
+		    (IXGBE_PCS1GLSTA_LINK_OK |
+		     IXGBE_PCS1GLSTA_AN_COMPLETE)) {
+			if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT))
+				hw->mac.autoneg_succeeded = 1;
+			break;
+		}
+	}
+
+	if (!hw->mac.autoneg_succeeded) {
+		/* Autoneg failed to achieve a link, so we turn fc off */
+		hw->fc.current_mode = ixgbe_fc_none;
+		hw_dbg(hw, "Flow Control = NONE.\n");
+		goto out;
+	}
+
+	/*
+	 * Read the AN advertisement and LP ability registers and resolve
+	 * local flow control settings accordingly
+	 */
+	pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+	pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+	if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+		(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+		/*
+		 * Now we need to check if the user selected Rx ONLY
+		 * of pause frames.  In this case, we had to advertise
+		 * FULL flow control because we could not advertise RX
+		 * ONLY. Hence, we must now check to see if we need to
+		 * turn OFF the TRANSMISSION of PAUSE frames.
+		 */
+		if (hw->fc.requested_mode == ixgbe_fc_full) {
+			hw->fc.current_mode = ixgbe_fc_full;
+			hw_dbg(hw, "Flow Control = FULL.\n");
+		} else {
+			hw->fc.current_mode = ixgbe_fc_rx_pause;
+			hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+		}
+	} else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+		   (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+		   (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+		   (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+		hw->fc.current_mode = ixgbe_fc_tx_pause;
+		hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+	} else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+		   (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+		   !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+		   (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+		hw->fc.current_mode = ixgbe_fc_rx_pause;
+		hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+	} else {
+		hw->fc.current_mode = ixgbe_fc_none;
+		hw_dbg(hw, "Flow Control = NONE.\n");
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  ixgbe_setup_fc_generic - Set up flow control
+ *  @hw: pointer to hardware structure
+ *
+ *  Sets up flow control.
+ **/
+s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+	s32 ret_val = 0;
+	ixgbe_link_speed speed;
+	bool link_up;
+
+#ifdef CONFIG_DCB
+	if (hw->fc.requested_mode == ixgbe_fc_pfc) {
+		hw->fc.current_mode = hw->fc.requested_mode;
+		goto out;
+	}
+
+#endif
+	/* Validate the packetbuf configuration */
+	if (packetbuf_num < 0 || packetbuf_num > 7) {
+		hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
+		       "is 0-7\n", packetbuf_num);
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the water mark configuration.  Zero water marks are invalid
+	 * because it causes the controller to just blast out fc packets.
+	 */
+	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+		hw_dbg(hw, "Invalid water mark configuration\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * Validate the requested mode.  Strict IEEE mode does not allow
+	 * ixgbe_fc_rx_pause because it will cause testing anomalies.
+	 */
+	if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+		hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict "
+		       "IEEE mode\n");
+		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+		goto out;
+	}
+
+	/*
+	 * 10gig parts do not have a word in the EEPROM to determine the
+	 * default flow control setting, so we explicitly set it to full.
+	 */
+	if (hw->fc.requested_mode == ixgbe_fc_default)
+		hw->fc.requested_mode = ixgbe_fc_full;
+
+	/*
+	 * Save off the requested flow control mode for use later.  Depending
+	 * on the link partner's capabilities, we may or may not use this mode.
+	 */
+	hw->fc.current_mode = hw->fc.requested_mode;
+
+	/* Decide whether to use autoneg or not. */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+	if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
+	    (speed == IXGBE_LINK_SPEED_1GB_FULL))
+		ret_val = ixgbe_fc_autoneg(hw);
+
+	if (ret_val)
+		goto out;
+
+	ret_val = ixgbe_fc_enable(hw, packetbuf_num);
+
+out:
+	return ret_val;
+}
+
+/**
  *  ixgbe_disable_pcie_master - Disable PCI-express master access
  *  @hw: pointer to hardware structure
  *
@@ -1597,3 +2011,71 @@ void ixgbe_release_swfw_sync(struct ixgb
 	ixgbe_release_eeprom_semaphore(hw);
 }
 
+/**
+ *  ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
+ *  @hw: pointer to hardware structure
+ *  @regval: register value to write to RXCTRL
+ *
+ *  Enables the Rx DMA unit
+ **/
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
+{
+	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_blink_led_start_generic - Blink LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to blink
+ **/
+s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
+{
+	ixgbe_link_speed speed = 0;
+	bool link_up = 0;
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	/*
+	 * Link must be up to auto-blink the LEDs;
+	 * Force it if link is down.
+	 */
+	hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+	if (!link_up) {
+		autoc_reg |= IXGBE_AUTOC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+		msleep(10);
+	}
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg |= IXGBE_LED_BLINK(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+/**
+ *  ixgbe_blink_led_stop_generic - Stop blinking LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to stop blinking
+ **/
+s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
+{
+	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+	autoc_reg &= ~IXGBE_AUTOC_FLU;
+	autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+	led_reg &= ~IXGBE_LED_MODE_MASK(index);
+	led_reg &= ~IXGBE_LED_BLINK(index);
+	led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_common.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_common.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_common.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -37,12 +37,14 @@ s32 ixgbe_clear_hw_cntrs_generic(struct
 s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
 s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
 s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
 s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
 
 s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
 
 s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
 s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
 s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
                                        u16 *data);
@@ -61,6 +63,10 @@ s32 ixgbe_update_uc_addr_list_generic(st
                                       u32 addr_count, ixgbe_mc_addr_itr func);
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
+s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
@@ -70,8 +76,18 @@ s32 ixgbe_disable_pcie_master(struct ixg
 s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
 
+s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
+
 #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
 
+#ifndef writeq
+#define writeq(val, addr) writel((u32) (val), addr); \
+    writel((u32) (val >> 32), (addr + 4));
+#endif
+
+#define IXGBE_WRITE_REG64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
+
 #define IXGBE_READ_REG(a, reg) readl((a)->hw_addr + (reg))
 
 #define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) (\
@@ -83,14 +99,11 @@ s32 ixgbe_write_analog_reg8_generic(stru
 #define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
 
 #ifdef DEBUG
+extern char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw);
 #define hw_dbg(hw, format, arg...) \
-printk(KERN_DEBUG, "%s: " format, ixgbe_get_hw_dev_name(hw), ##arg);
+	printk(KERN_DEBUG "%s: " format, ixgbe_get_hw_dev_name(hw), ##arg)
 #else
-static inline int __attribute__ ((format (printf, 2, 3)))
-hw_dbg(struct ixgbe_hw *hw, const char *format, ...)
-{
-	return 0;
-}
+#define hw_dbg(hw, format, arg...) do {} while (0)
 #endif
 
 #endif /* IXGBE_COMMON */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 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,
@@ -298,7 +298,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ix
 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
 	/* correct the reporting of our flow control status */
-	hw->fc.type = ixgbe_fc_none;
 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82598.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 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.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,473 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "ixgbe.h"
+#include "ixgbe_type.h"
+#include "ixgbe_dcb.h"
+#include "ixgbe_dcb_82599.h"
+
+/**
+ * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count:  Number of elements in bwg_array.
+ *
+ * This function returns the status data for each of the Traffic Classes in use.
+ */
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+                                 struct ixgbe_hw_stats *stats,
+                                 u8 tc_count)
+{
+	int tc;
+
+	if (tc_count > MAX_TRAFFIC_CLASS)
+		return DCB_ERR_PARAM;
+	/* Statistics pertaining to each traffic class */
+	for (tc = 0; tc < tc_count; tc++) {
+		/* Transmitted Packets */
+		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
+		/* Transmitted Bytes */
+		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
+		/* Received Packets */
+		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
+		/* Received Bytes */
+		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count:  Number of elements in bwg_array.
+ *
+ * This function returns the CBFC status data for each of the Traffic Classes.
+ */
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+                                  struct ixgbe_hw_stats *stats,
+                                  u8 tc_count)
+{
+	int tc;
+
+	if (tc_count > MAX_TRAFFIC_CLASS)
+		return DCB_ERR_PARAM;
+	for (tc = 0; tc < tc_count; tc++) {
+		/* Priority XOFF Transmitted */
+		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
+		/* Priority XOFF Received */
+		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure packet buffers for DCB mode.
+ */
+s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
+                                          struct ixgbe_dcb_config *dcb_config)
+{
+	s32 ret_val = 0;
+	u32 value = IXGBE_RXPBSIZE_64KB;
+	u8  i = 0;
+
+	/* Setup Rx packet buffer sizes */
+	switch (dcb_config->rx_pba_cfg) {
+	case pba_80_48:
+		/* Setup the first four at 80KB */
+		value = IXGBE_RXPBSIZE_80KB;
+		for (; i < 4; i++)
+			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+		/* Setup the last four at 48KB...don't re-init i */
+		value = IXGBE_RXPBSIZE_48KB;
+		/* Fall Through */
+	case pba_equal:
+	default:
+		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
+			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+
+		/* Setup Tx packet buffer sizes */
+		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+			IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
+			                IXGBE_TXPBSIZE_20KB);
+			IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
+			                IXGBE_TXPBTHRESH_DCB);
+		}
+		break;
+	}
+
+	return ret_val;
+}
+
+/**
+ * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Rx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+                                      struct ixgbe_dcb_config *dcb_config)
+{
+	struct tc_bw_alloc    *p;
+	u32    reg           = 0;
+	u32    credit_refill = 0;
+	u32    credit_max    = 0;
+	u8     i             = 0;
+
+	/* Disable the arbiter before changing parameters */
+	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, IXGBE_RTRPCS_ARBDIS);
+
+	/* Map all traffic classes to their UP, 1 to 1 */
+	reg = 0;
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+		reg |= (i << (i * IXGBE_RTRUP2TC_UP_SHIFT));
+	IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
+
+	/* Configure traffic class credits and priority */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
+
+		credit_refill = p->data_credits_refill;
+		credit_max    = p->data_credits_max;
+		reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
+
+		reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT;
+
+		if (p->prio_type == prio_link)
+			reg |= IXGBE_RTRPT4C_LSP;
+
+		IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
+	}
+
+	/*
+	 * Configure Rx packet plane (recycle mode; WSP) and
+	 * enable arbiter
+	 */
+	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
+	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Descriptor Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+                                           struct ixgbe_dcb_config *dcb_config)
+{
+	struct tc_bw_alloc *p;
+	u32    reg, max_credits;
+	u8     i;
+
+	/* Disable the arbiter before changing parameters */
+	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, IXGBE_RTTDCS_ARBDIS);
+
+	/* Clear the per-Tx queue credits; we use per-TC instead */
+	for (i = 0; i < 128; i++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
+	}
+
+	/* Configure traffic class credits and priority */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+		max_credits = dcb_config->tc_config[i].desc_credits_max;
+		reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
+		reg |= p->data_credits_refill;
+		reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT;
+
+		if (p->prio_type == prio_group)
+			reg |= IXGBE_RTTDT2C_GSP;
+
+		if (p->prio_type == prio_link)
+			reg |= IXGBE_RTTDT2C_LSP;
+
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
+	}
+
+	/*
+	 * Configure Tx descriptor plane (recycle mode; WSP) and
+	 * enable arbiter
+	 */
+	reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
+	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+                                           struct ixgbe_dcb_config *dcb_config)
+{
+	struct tc_bw_alloc *p;
+	u32 reg;
+	u8 i;
+
+	/* Disable the arbiter before changing parameters */
+	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, IXGBE_RTTPCS_ARBDIS);
+
+	/* Map all traffic classes to their UP, 1 to 1 */
+	reg = 0;
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+		reg |= (i << (i * IXGBE_RTTUP2TC_UP_SHIFT));
+	IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
+
+	/* Configure traffic class credits and priority */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+		reg = p->data_credits_refill;
+		reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT;
+		reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT;
+
+		if (p->prio_type == prio_group)
+			reg |= IXGBE_RTTPT2C_GSP;
+
+		if (p->prio_type == prio_link)
+			reg |= IXGBE_RTTPT2C_LSP;
+
+		IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
+	}
+
+	/*
+	 * Configure Tx packet plane (recycle mode; SP; arb delay) and
+	 * enable arbiter
+	 */
+	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
+	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
+	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Priority Flow Control (PFC) for each traffic class.
+ */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+                               struct ixgbe_dcb_config *dcb_config)
+{
+	u32 i, reg, rx_pba_size;
+
+	/* If PFC is disabled globally then fall back to LFC. */
+	if (!dcb_config->pfc_mode_enable) {
+		for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+			hw->mac.ops.setup_fc(hw, i);
+		goto out;
+	}
+
+	/* Configure PFC Tx thresholds per TC */
+	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+		if (dcb_config->rx_pba_cfg == pba_equal)
+			rx_pba_size = IXGBE_RXPBSIZE_64KB;
+		else
+			rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
+			                      : IXGBE_RXPBSIZE_48KB;
+
+		reg = ((rx_pba_size >> 5) & 0xFFE0);
+		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+			reg |= IXGBE_FCRTL_XONE;
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+
+		reg = ((rx_pba_size >> 2) & 0xFFE0);
+		if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+		    dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
+			reg |= IXGBE_FCRTH_FCEN;
+		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
+	}
+
+	/* Configure pause time (2 TCs per register) */
+	reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
+	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
+
+	/* Configure flow control refresh threshold value */
+	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
+
+	/* Enable Transmit PFC */
+	reg = IXGBE_FCCFG_TFCE_PRIORITY;
+	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
+
+	/*
+	 * Enable Receive PFC
+	 * We will always honor XOFF frames we receive when
+	 * we are in PFC mode.
+	 */
+	reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+	reg &= ~IXGBE_MFLCN_RFCE;
+	reg |= IXGBE_MFLCN_RPFCE;
+	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+out:
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
+ * @hw: pointer to hardware structure
+ *
+ * Configure queue statistics registers, all queues belonging to same traffic
+ * class uses a single set of queue statistics counters.
+ */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
+{
+	u32 reg = 0;
+	u8  i   = 0;
+
+	/*
+	 * Receive Queues stats setting
+	 * 32 RQSMR registers, each configuring 4 queues.
+	 * Set all 16 queues of each TC to the same stat
+	 * with TC 'n' going to stat 'n'.
+	 */
+	for (i = 0; i < 32; i++) {
+		reg = 0x01010101 * (i / 4);
+		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
+	}
+	/*
+	 * Transmit Queues stats setting
+	 * 32 TQSM registers, each controlling 4 queues.
+	 * Set all queues of each TC to the same stat
+	 * with TC 'n' going to stat 'n'.
+	 * Tx queues are allocated non-uniformly to TCs:
+	 * 32, 32, 16, 16, 8, 8, 8, 8.
+	 */
+	for (i = 0; i < 32; i++) {
+		if (i < 8)
+			reg = 0x00000000;
+		else if (i < 16)
+			reg = 0x01010101;
+		else if (i < 20)
+			reg = 0x02020202;
+		else if (i < 24)
+			reg = 0x03030303;
+		else if (i < 26)
+			reg = 0x04040404;
+		else if (i < 28)
+			reg = 0x05050505;
+		else if (i < 30)
+			reg = 0x06060606;
+		else
+			reg = 0x07070707;
+		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_config_82599 - Configure general DCB parameters
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure general DCB parameters.
+ */
+s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
+{
+	u32 reg;
+	u32 q;
+
+	/* Disable the Tx desc arbiter so that MTQC can be changed */
+	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+	reg |= IXGBE_RTTDCS_ARBDIS;
+	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+	/* Enable DCB for Rx with 8 TCs */
+	reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+	switch (reg & IXGBE_MRQC_MRQE_MASK) {
+	case 0:
+	case IXGBE_MRQC_RT4TCEN:
+		/* RSS disabled cases */
+		reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+		break;
+	case IXGBE_MRQC_RSSEN:
+	case IXGBE_MRQC_RTRSS4TCEN:
+		/* RSS enabled cases */
+		reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RTRSS8TCEN;
+		break;
+	default:
+		/* Unsupported value, assume stale data, overwrite no RSS */
+		reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+	}
+	IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
+
+	/* Enable DCB for Tx with 8 TCs */
+	reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
+	IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
+
+	/* Disable drop for all queues */
+	for (q = 0; q < 128; q++)
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, q << IXGBE_QDE_IDX_SHIFT);
+
+	/* Enable the Tx desc arbiter */
+	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+	reg &= ~IXGBE_RTTDCS_ARBDIS;
+	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+	return 0;
+}
+
+/**
+ * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure dcb settings and enable dcb mode.
+ */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+                              struct ixgbe_dcb_config *dcb_config)
+{
+	ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config);
+	ixgbe_dcb_config_82599(hw);
+	ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
+	ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
+	ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
+	ixgbe_dcb_config_pfc_82599(hw, dcb_config);
+	ixgbe_dcb_config_tc_stats_82599(hw);
+
+	return 0;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_82599.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,127 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  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,
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _DCB_82599_CONFIG_H_
+#define _DCB_82599_CONFIG_H_
+
+/* DCB register definitions */
+#define IXGBE_RTTDCS_TDPAC      0x00000001 /* 0 Round Robin,
+                                            * 1 WSP - Weighted Strict Priority
+                                            */
+#define IXGBE_RTTDCS_VMPAC      0x00000002 /* 0 Round Robin,
+                                            * 1 WRR - Weighted Round Robin
+                                            */
+#define IXGBE_RTTDCS_TDRM       0x00000010 /* Transmit Recycle Mode */
+#define IXGBE_RTTDCS_ARBDIS     0x00000040 /* DCB arbiter disable */
+#define IXGBE_RTTDCS_BDPM       0x00400000 /* Bypass Data Pipe - must clear! */
+#define IXGBE_RTTDCS_BPBFSM     0x00800000 /* Bypass PB Free Space - must
+                                             * clear!
+                                             */
+#define IXGBE_RTTDCS_SPEED_CHG  0x80000000 /* Link speed change */
+
+/* Receive UP2TC mapping */
+#define IXGBE_RTRUP2TC_UP_SHIFT 3
+/* Transmit UP2TC mapping */
+#define IXGBE_RTTUP2TC_UP_SHIFT 3
+
+#define IXGBE_RTRPT4C_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */
+#define IXGBE_RTRPT4C_BWG_SHIFT 9  /* Offset to BWG index */
+#define IXGBE_RTRPT4C_GSP       0x40000000 /* GSP enable bit */
+#define IXGBE_RTRPT4C_LSP       0x80000000 /* LSP enable bit */
+
+#define IXGBE_RDRXCTL_MPBEN     0x00000010 /* DMA config for multiple packet
+                                            * buffers enable
+                                            */
+#define IXGBE_RDRXCTL_MCEN      0x00000040 /* DMA config for multiple cores
+                                            * (RSS) enable
+                                            */
+
+/* RTRPCS Bit Masks */
+#define IXGBE_RTRPCS_RRM        0x00000002 /* Receive Recycle Mode enable */
+/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
+#define IXGBE_RTRPCS_RAC        0x00000004
+#define IXGBE_RTRPCS_ARBDIS     0x00000040 /* Arbitration disable bit */
+
+/* RTTDT2C Bit Masks */
+#define IXGBE_RTTDT2C_MCL_SHIFT 12
+#define IXGBE_RTTDT2C_BWG_SHIFT 9
+#define IXGBE_RTTDT2C_GSP       0x40000000
+#define IXGBE_RTTDT2C_LSP       0x80000000
+
+#define IXGBE_RTTPT2C_MCL_SHIFT 12
+#define IXGBE_RTTPT2C_BWG_SHIFT 9
+#define IXGBE_RTTPT2C_GSP       0x40000000
+#define IXGBE_RTTPT2C_LSP       0x80000000
+
+/* RTTPCS Bit Masks */
+#define IXGBE_RTTPCS_TPPAC      0x00000020 /* 0 Round Robin,
+                                            * 1 SP - Strict Priority
+                                            */
+#define IXGBE_RTTPCS_ARBDIS     0x00000040 /* Arbiter disable */
+#define IXGBE_RTTPCS_TPRM       0x00000100 /* Transmit Recycle Mode enable */
+#define IXGBE_RTTPCS_ARBD_SHIFT 22
+#define IXGBE_RTTPCS_ARBD_DCB   0x4        /* Arbitration delay in DCB mode */
+
+#define IXGBE_TXPBSIZE_20KB     0x00005000 /* 20KB Packet Buffer */
+#define IXGBE_TXPBSIZE_40KB     0x0000A000 /* 40KB Packet Buffer */
+#define IXGBE_RXPBSIZE_48KB     0x0000C000 /* 48KB Packet Buffer */
+#define IXGBE_RXPBSIZE_64KB     0x00010000 /* 64KB Packet Buffer */
+#define IXGBE_RXPBSIZE_80KB     0x00014000 /* 80KB Packet Buffer */
+#define IXGBE_RXPBSIZE_128KB    0x00020000 /* 128KB Packet Buffer */
+
+#define IXGBE_TXPBTHRESH_DCB    0xA        /* THRESH value for DCB mode */
+
+
+/* DCB hardware-specific driver APIs */
+
+/* DCB PFC functions */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+                               struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+                                  struct ixgbe_hw_stats *stats,
+                                  u8 tc_count);
+
+/* DCB traffic class stats */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw);
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+                                 struct ixgbe_hw_stats *stats,
+                                 u8 tc_count);
+
+/* DCB config arbiters */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+                                           struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+                                           struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+                                      struct ixgbe_dcb_config *dcb_config);
+
+
+/* DCB hw initialization */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+                              struct ixgbe_dcb_config *config);
+
+#endif /* _DCB_82599_CONFIG_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 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,6 +31,7 @@
 #include "ixgbe_type.h"
 #include "ixgbe_dcb.h"
 #include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
 
 /**
  * ixgbe_dcb_config - Struct containing DCB settings.
@@ -215,6 +216,8 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
 	return ret;
 }
 
@@ -232,6 +235,8 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
 	return ret;
 }
 
@@ -248,6 +253,8 @@ s32 ixgbe_dcb_config_rx_arbiter(struct i
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
 	return ret;
 }
 
@@ -264,6 +271,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter(str
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
 	return ret;
 }
 
@@ -280,6 +289,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter(str
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
 	return ret;
 }
 
@@ -296,6 +307,8 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config);
 	return ret;
 }
 
@@ -311,6 +324,8 @@ s32 ixgbe_dcb_config_tc_stats(struct ixg
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_config_tc_stats_82598(hw);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_config_tc_stats_82599(hw);
 	return ret;
 }
 
@@ -327,6 +342,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw
 	s32 ret = 0;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config);
 	return ret;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 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,
@@ -75,6 +75,26 @@ enum strict_prio_type {
 	prio_link
 };
 
+/* DCB capability definitions */
+#define IXGBE_DCB_PG_SUPPORT        0x00000001
+#define IXGBE_DCB_PFC_SUPPORT       0x00000002
+#define IXGBE_DCB_BCN_SUPPORT       0x00000004
+#define IXGBE_DCB_UP2TC_SUPPORT     0x00000008
+#define IXGBE_DCB_GSP_SUPPORT       0x00000010
+
+#define IXGBE_DCB_8_TC_SUPPORT      0x80
+
+struct dcb_support {
+	/* DCB capabilities */
+	u32 capabilities;
+
+	/* Each bit represents a number of TCs configurable in the hw.
+	 * If 8 traffic classes can be configured, the value is 0x80.
+	 */
+	u8  traffic_classes;
+	u8  pfc_traffic_classes;
+};
+
 /* Traffic class bandwidth allocation per direction */
 struct tc_bw_alloc {
 	u8 bwg_id;		  /* Bandwidth Group (BWG) ID */
@@ -108,38 +128,18 @@ enum dcb_rx_pba_cfg {
 	pba_80_48      /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */
 };
 
-/*
- * This structure contains many values encoded as fixed-point
- * numbers, meaning that some of bits are dedicated to the
- * magnitude and others to the fraction part. In the comments
- * this is shown as f=n, where n is the number of fraction bits.
- * These fraction bits are always the low-order bits. The size
- * of the magnitude is not specified.
- */
-struct bcn_config {
-	u32 rp_admin_mode[MAX_TRAFFIC_CLASS]; /* BCN enabled, per TC */
-	u32 bcna_option[2]; /* BCNA Port + MAC Addr */
-	u32 rp_w;        /* Derivative Weight, f=3 */
-	u32 rp_gi;       /* Increase Gain, f=12 */
-	u32 rp_gd;       /* Decrease Gain, f=12 */
-	u32 rp_ru;       /* Rate Unit */
-	u32 rp_alpha;    /* Max Decrease Factor, f=12 */
-	u32 rp_beta;     /* Max Increase Factor, f=12 */
-	u32 rp_ri;       /* Initial Rate */
-	u32 rp_td;       /* Drift Interval Timer */
-	u32 rp_rd;       /* Drift Increase */
-	u32 rp_tmax;     /* Severe Congestion Backoff Timer Range */
-	u32 rp_rmin;     /* Severe Congestion Restart Rate */
-	u32 rp_wrtt;     /* RTT Moving Average Weight */
+struct dcb_num_tcs {
+	u8 pg_tcs;
+	u8 pfc_tcs;
 };
 
 struct ixgbe_dcb_config {
-	struct bcn_config bcn;
-
+	struct dcb_support support;
+	struct dcb_num_tcs num_tcs;
 	struct tc_configuration tc_config[MAX_TRAFFIC_CLASS];
 	u8     bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */
-
-	bool  round_robin_enable;
+	bool   pfc_mode_enable;
+	bool   round_robin_enable;
 
 	enum dcb_rx_pba_cfg rx_pba_cfg;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_dcb_nl.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,6 +35,7 @@
 #define BIT_PG_RX	0x04
 #define BIT_PG_TX	0x08
 #define BIT_BCN         0x10
+#define BIT_LINKSPEED   0x80
 
 int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
                        struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
@@ -89,24 +90,7 @@ int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_
 			src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc;
 	}
 
-	for (i = DCB_BCN_ATTR_RP_0; i < DCB_BCN_ATTR_RP_ALL; i++) {
-		dst_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0] =
-			src_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0];
-	}
-	dst_dcb_cfg->bcn.bcna_option[0] = src_dcb_cfg->bcn.bcna_option[0];
-	dst_dcb_cfg->bcn.bcna_option[1] = src_dcb_cfg->bcn.bcna_option[1];
-	dst_dcb_cfg->bcn.rp_alpha = src_dcb_cfg->bcn.rp_alpha;
-	dst_dcb_cfg->bcn.rp_beta = src_dcb_cfg->bcn.rp_beta;
-	dst_dcb_cfg->bcn.rp_gd = src_dcb_cfg->bcn.rp_gd;
-	dst_dcb_cfg->bcn.rp_gi = src_dcb_cfg->bcn.rp_gi;
-	dst_dcb_cfg->bcn.rp_tmax = src_dcb_cfg->bcn.rp_tmax;
-	dst_dcb_cfg->bcn.rp_td = src_dcb_cfg->bcn.rp_td;
-	dst_dcb_cfg->bcn.rp_rmin = src_dcb_cfg->bcn.rp_rmin;
-	dst_dcb_cfg->bcn.rp_w = src_dcb_cfg->bcn.rp_w;
-	dst_dcb_cfg->bcn.rp_rd = src_dcb_cfg->bcn.rp_rd;
-	dst_dcb_cfg->bcn.rp_ru = src_dcb_cfg->bcn.rp_ru;
-	dst_dcb_cfg->bcn.rp_wrtt = src_dcb_cfg->bcn.rp_wrtt;
-	dst_dcb_cfg->bcn.rp_ri = src_dcb_cfg->bcn.rp_ri;
+	dst_dcb_cfg->pfc_mode_enable = src_dcb_cfg->pfc_mode_enable;
 
 	return 0;
 }
@@ -120,12 +104,6 @@ static u8 ixgbe_dcbnl_get_state(struct n
 	return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
 }
 
-static u16 ixgbe_dcb_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
-	/* All traffic should default to class 0 */
-	return 0;
-}
-
 static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
 	u8 err = 0;
@@ -153,8 +131,8 @@ static u8 ixgbe_dcbnl_set_state(struct n
 		kfree(adapter->rx_ring);
 		adapter->tx_ring = NULL;
 		adapter->rx_ring = NULL;
-		netdev->select_queue = &ixgbe_dcb_select_queue;
 
+		adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
 		adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
 		adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
 		ixgbe_init_interrupt_scheme(adapter);
@@ -163,6 +141,7 @@ static u8 ixgbe_dcbnl_set_state(struct n
 	} else {
 		/* Turn off DCB */
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+			adapter->hw.fc.requested_mode = ixgbe_fc_default;
 			if (netif_running(netdev))
 				netdev->netdev_ops->ndo_stop(netdev);
 			ixgbe_reset_interrupt_capability(adapter);
@@ -172,7 +151,6 @@ static u8 ixgbe_dcbnl_set_state(struct n
 			kfree(adapter->rx_ring);
 			adapter->tx_ring = NULL;
 			adapter->rx_ring = NULL;
-			netdev->select_queue = NULL;
 
 			adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
 			adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
@@ -322,8 +300,10 @@ static void ixgbe_dcbnl_set_pfc_cfg(stru
 
 	adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
 	if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
-	    adapter->dcb_cfg.tc_config[priority].dcb_pfc)
+	    adapter->dcb_cfg.tc_config[priority].dcb_pfc) {
 		adapter->dcb_set_bitmap |= BIT_PFC;
+		adapter->temp_dcb_cfg.pfc_mode_enable = true;
+	}
 }
 
 static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
@@ -444,175 +424,6 @@ static void ixgbe_dcbnl_setpfcstate(stru
 	return;
 }
 
-static void ixgbe_dcbnl_getbcnrp(struct net_device *netdev, int priority,
-				  u8 *setting)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	*setting = adapter->dcb_cfg.bcn.rp_admin_mode[priority];
-}
-
-
-static void ixgbe_dcbnl_getbcncfg(struct net_device *netdev, int enum_index,
-				  u32 *setting)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	switch (enum_index) {
-	case DCB_BCN_ATTR_BCNA_0:
-		*setting = adapter->dcb_cfg.bcn.bcna_option[0];
-		break;
-	case DCB_BCN_ATTR_BCNA_1:
-		*setting = adapter->dcb_cfg.bcn.bcna_option[1];
-		break;
-	case DCB_BCN_ATTR_ALPHA:
-		*setting = adapter->dcb_cfg.bcn.rp_alpha;
-		break;
-	case DCB_BCN_ATTR_BETA:
-		*setting = adapter->dcb_cfg.bcn.rp_beta;
-		break;
-	case DCB_BCN_ATTR_GD:
-		*setting = adapter->dcb_cfg.bcn.rp_gd;
-		break;
-	case DCB_BCN_ATTR_GI:
-		*setting = adapter->dcb_cfg.bcn.rp_gi;
-		break;
-	case DCB_BCN_ATTR_TMAX:
-		*setting = adapter->dcb_cfg.bcn.rp_tmax;
-		break;
-	case DCB_BCN_ATTR_TD:
-		*setting = adapter->dcb_cfg.bcn.rp_td;
-		break;
-	case DCB_BCN_ATTR_RMIN:
-		*setting = adapter->dcb_cfg.bcn.rp_rmin;
-		break;
-	case DCB_BCN_ATTR_W:
-		*setting = adapter->dcb_cfg.bcn.rp_w;
-		break;
-	case DCB_BCN_ATTR_RD:
-		*setting = adapter->dcb_cfg.bcn.rp_rd;
-		break;
-	case DCB_BCN_ATTR_RU:
-		*setting = adapter->dcb_cfg.bcn.rp_ru;
-		break;
-	case DCB_BCN_ATTR_WRTT:
-		*setting = adapter->dcb_cfg.bcn.rp_wrtt;
-		break;
-	case DCB_BCN_ATTR_RI:
-		*setting = adapter->dcb_cfg.bcn.rp_ri;
-		break;
-	default:
-		*setting = -1;
-	}
-}
-
-static void ixgbe_dcbnl_setbcnrp(struct net_device *netdev, int priority,
-				 u8 setting)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] = setting;
-
-	if (adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] !=
-	    adapter->dcb_cfg.bcn.rp_admin_mode[priority])
-		adapter->dcb_set_bitmap |= BIT_BCN;
-}
-
-static void ixgbe_dcbnl_setbcncfg(struct net_device *netdev, int enum_index,
-				 u32 setting)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	switch (enum_index) {
-	case DCB_BCN_ATTR_BCNA_0:
-		adapter->temp_dcb_cfg.bcn.bcna_option[0] = setting;
-		if (adapter->temp_dcb_cfg.bcn.bcna_option[0] !=
-			adapter->dcb_cfg.bcn.bcna_option[0])
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_BCNA_1:
-		adapter->temp_dcb_cfg.bcn.bcna_option[1] = setting;
-		if (adapter->temp_dcb_cfg.bcn.bcna_option[1] !=
-			adapter->dcb_cfg.bcn.bcna_option[1])
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_ALPHA:
-		adapter->temp_dcb_cfg.bcn.rp_alpha = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_alpha !=
-		    adapter->dcb_cfg.bcn.rp_alpha)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_BETA:
-		adapter->temp_dcb_cfg.bcn.rp_beta = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_beta !=
-		    adapter->dcb_cfg.bcn.rp_beta)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_GD:
-		adapter->temp_dcb_cfg.bcn.rp_gd = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_gd !=
-		    adapter->dcb_cfg.bcn.rp_gd)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_GI:
-		adapter->temp_dcb_cfg.bcn.rp_gi = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_gi !=
-		    adapter->dcb_cfg.bcn.rp_gi)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_TMAX:
-		adapter->temp_dcb_cfg.bcn.rp_tmax = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_tmax !=
-		    adapter->dcb_cfg.bcn.rp_tmax)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_TD:
-		adapter->temp_dcb_cfg.bcn.rp_td = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_td !=
-		    adapter->dcb_cfg.bcn.rp_td)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_RMIN:
-		adapter->temp_dcb_cfg.bcn.rp_rmin = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_rmin !=
-		    adapter->dcb_cfg.bcn.rp_rmin)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_W:
-		adapter->temp_dcb_cfg.bcn.rp_w = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_w !=
-		    adapter->dcb_cfg.bcn.rp_w)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_RD:
-		adapter->temp_dcb_cfg.bcn.rp_rd = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_rd !=
-		    adapter->dcb_cfg.bcn.rp_rd)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_RU:
-		adapter->temp_dcb_cfg.bcn.rp_ru = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_ru !=
-		    adapter->dcb_cfg.bcn.rp_ru)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_WRTT:
-		adapter->temp_dcb_cfg.bcn.rp_wrtt = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_wrtt !=
-		    adapter->dcb_cfg.bcn.rp_wrtt)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	case DCB_BCN_ATTR_RI:
-		adapter->temp_dcb_cfg.bcn.rp_ri = setting;
-		if (adapter->temp_dcb_cfg.bcn.rp_ri !=
-		    adapter->dcb_cfg.bcn.rp_ri)
-			adapter->dcb_set_bitmap |= BIT_BCN;
-		break;
-	default:
-		break;
-	}
-}
-
 struct dcbnl_rtnl_ops dcbnl_ops = {
 	.getstate	= ixgbe_dcbnl_get_state,
 	.setstate	= ixgbe_dcbnl_set_state,
@@ -633,9 +444,5 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
 	.setnumtcs	= ixgbe_dcbnl_setnumtcs,
 	.getpfcstate	= ixgbe_dcbnl_getpfcstate,
 	.setpfcstate	= ixgbe_dcbnl_setpfcstate,
-	.getbcncfg      = ixgbe_dcbnl_getbcncfg,
-	.getbcnrp       = ixgbe_dcbnl_getbcnrp,
-	.setbcncfg      = ixgbe_dcbnl_setbcncfg,
-	.setbcnrp       = ixgbe_dcbnl_setbcnrp
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -89,8 +89,7 @@ static struct ixgbe_stats ixgbe_gstrings
 	{"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)},
-	{"lro_aggregated", IXGBE_STAT(lro_aggregated)},
-	{"lro_flushed", IXGBE_STAT(lro_flushed)},
+	{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
 };
 
 #define IXGBE_QUEUE_STATS_LEN \
@@ -130,8 +129,37 @@ static int ixgbe_get_settings(struct net
 			ecmd->advertising |= ADVERTISED_10000baseT_Full;
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
 			ecmd->advertising |= ADVERTISED_1000baseT_Full;
+		/*
+		 * It's possible that phy.autoneg_advertised may not be
+		 * set yet.  If so display what the default would be -
+		 * both 1G and 10G supported.
+		 */
+		if (!(ecmd->advertising & (ADVERTISED_1000baseT_Full |
+					   ADVERTISED_10000baseT_Full)))
+			ecmd->advertising |= (ADVERTISED_10000baseT_Full |
+					      ADVERTISED_1000baseT_Full);
 
 		ecmd->port = PORT_TP;
+	} else if (hw->phy.media_type == ixgbe_media_type_backplane) {
+		/* Set as FIBRE until SERDES defined in kernel */
+		switch (hw->device_id) {
+		case IXGBE_DEV_ID_82598:
+			ecmd->supported |= (SUPPORTED_1000baseT_Full |
+				SUPPORTED_FIBRE);
+			ecmd->advertising = (ADVERTISED_10000baseT_Full |
+				ADVERTISED_1000baseT_Full |
+				ADVERTISED_FIBRE);
+			ecmd->port = PORT_FIBRE;
+			break;
+		case IXGBE_DEV_ID_82598_BX:
+			ecmd->supported = (SUPPORTED_1000baseT_Full |
+					   SUPPORTED_FIBRE);
+			ecmd->advertising = (ADVERTISED_1000baseT_Full |
+					     ADVERTISED_FIBRE);
+			ecmd->port = PORT_FIBRE;
+			ecmd->autoneg = AUTONEG_DISABLE;
+			break;
+		}
 	} else {
 		ecmd->supported |= SUPPORTED_FIBRE;
 		ecmd->advertising = (ADVERTISED_10000baseT_Full |
@@ -206,13 +234,22 @@ static void ixgbe_get_pauseparam(struct
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	pause->autoneg = (hw->fc.type == ixgbe_fc_full ? 1 : 0);
+	/*
+	 * Flow Control Autoneg isn't on if
+	 *  - we didn't ask for it OR
+	 *  - it failed, we know this by tx & rx being off
+	 */
+	if (hw->fc.disable_fc_autoneg ||
+	    (hw->fc.current_mode == ixgbe_fc_none))
+		pause->autoneg = 0;
+	else
+		pause->autoneg = 1;
 
-	if (hw->fc.type == ixgbe_fc_rx_pause) {
+	if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
 		pause->rx_pause = 1;
-	} else if (hw->fc.type == ixgbe_fc_tx_pause) {
+	} else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
 		pause->tx_pause = 1;
-	} else if (hw->fc.type == ixgbe_fc_full) {
+	} else if (hw->fc.current_mode == ixgbe_fc_full) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -224,24 +261,23 @@ static int ixgbe_set_pauseparam(struct n
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	if ((pause->autoneg == AUTONEG_ENABLE) ||
-	    (pause->rx_pause && pause->tx_pause))
-		hw->fc.type = ixgbe_fc_full;
+	if (pause->autoneg != AUTONEG_ENABLE)
+		hw->fc.disable_fc_autoneg = true;
+	else
+		hw->fc.disable_fc_autoneg = false;
+
+	if (pause->rx_pause && pause->tx_pause)
+		hw->fc.requested_mode = ixgbe_fc_full;
 	else if (pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = ixgbe_fc_rx_pause;
+		hw->fc.requested_mode = ixgbe_fc_rx_pause;
 	else if (!pause->rx_pause && pause->tx_pause)
-		hw->fc.type = ixgbe_fc_tx_pause;
+		hw->fc.requested_mode = ixgbe_fc_tx_pause;
 	else if (!pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = ixgbe_fc_none;
+		hw->fc.requested_mode = ixgbe_fc_none;
 	else
 		return -EINVAL;
 
-	hw->fc.original_type = hw->fc.type;
-
-	if (netif_running(netdev))
-		ixgbe_reinit_locked(adapter);
-	else
-		ixgbe_reset(adapter);
+	hw->mac.ops.setup_fc(hw, 0);
 
 	return 0;
 }
@@ -456,7 +492,7 @@ static void ixgbe_get_regs(struct net_de
 	regs_buff[825] = IXGBE_READ_REG(hw, IXGBE_IP6AT);
 	regs_buff[826] = IXGBE_READ_REG(hw, IXGBE_WUPL);
 	regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
-	regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
+	regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
 
 	regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
 	regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
@@ -661,10 +697,17 @@ static void ixgbe_get_drvinfo(struct net
                               struct ethtool_drvinfo *drvinfo)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	char firmware_version[32];
 
 	strncpy(drvinfo->driver, ixgbe_driver_name, 32);
 	strncpy(drvinfo->version, ixgbe_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
+
+	sprintf(firmware_version, "%d.%d-%d",
+	        (adapter->eeprom_version & 0xF000) >> 12,
+	        (adapter->eeprom_version & 0x0FF0) >> 4,
+	        adapter->eeprom_version & 0x000F);
+
+	strncpy(drvinfo->fw_version, firmware_version, 32);
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 	drvinfo->n_stats = IXGBE_STATS_LEN;
 	drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
@@ -691,9 +734,10 @@ static int ixgbe_set_ringparam(struct ne
                                struct ethtool_ringparam *ring)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_ring *temp_ring;
+	struct ixgbe_ring *temp_tx_ring, *temp_rx_ring;
 	int i, err;
 	u32 new_rx_count, new_tx_count;
+	bool need_update = false;
 
 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
@@ -712,80 +756,94 @@ static int ixgbe_set_ringparam(struct ne
 		return 0;
 	}
 
-	temp_ring = kcalloc(adapter->num_tx_queues,
-	                    sizeof(struct ixgbe_ring), GFP_KERNEL);
-	if (!temp_ring)
-		return -ENOMEM;
-
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 		msleep(1);
 
-	if (new_tx_count != adapter->tx_ring->count) {
+	temp_tx_ring = kcalloc(adapter->num_tx_queues,
+	                       sizeof(struct ixgbe_ring), GFP_KERNEL);
+	if (!temp_tx_ring) {
+		err = -ENOMEM;
+		goto err_setup;
+	}
+
+	if (new_tx_count != adapter->tx_ring_count) {
+		memcpy(temp_tx_ring, adapter->tx_ring,
+		       adapter->num_tx_queues * sizeof(struct ixgbe_ring));
 		for (i = 0; i < adapter->num_tx_queues; i++) {
-			temp_ring[i].count = new_tx_count;
-			err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
+			temp_tx_ring[i].count = new_tx_count;
+			err = ixgbe_setup_tx_resources(adapter,
+			                               &temp_tx_ring[i]);
 			if (err) {
 				while (i) {
 					i--;
 					ixgbe_free_tx_resources(adapter,
-					                        &temp_ring[i]);
+					                        &temp_tx_ring[i]);
 				}
 				goto err_setup;
 			}
-			temp_ring[i].v_idx = adapter->tx_ring[i].v_idx;
+			temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
 		}
-		if (netif_running(netdev))
-			netdev->netdev_ops->ndo_stop(netdev);
-		ixgbe_reset_interrupt_capability(adapter);
-		ixgbe_napi_del_all(adapter);
-		INIT_LIST_HEAD(&netdev->napi_list);
-		kfree(adapter->tx_ring);
-		adapter->tx_ring = temp_ring;
-		temp_ring = NULL;
-		adapter->tx_ring_count = new_tx_count;
+		need_update = true;
 	}
 
-	temp_ring = kcalloc(adapter->num_rx_queues,
-	                    sizeof(struct ixgbe_ring), GFP_KERNEL);
-	if (!temp_ring) {
-		if (netif_running(netdev))
-			netdev->netdev_ops->ndo_open(netdev);
-		return -ENOMEM;
+	temp_rx_ring = kcalloc(adapter->num_rx_queues,
+	                       sizeof(struct ixgbe_ring), GFP_KERNEL);
+	if ((!temp_rx_ring) && (need_update)) {
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			ixgbe_free_tx_resources(adapter, &temp_tx_ring[i]);
+		kfree(temp_tx_ring);
+		err = -ENOMEM;
+		goto err_setup;
 	}
 
-	if (new_rx_count != adapter->rx_ring->count) {
+	if (new_rx_count != adapter->rx_ring_count) {
+		memcpy(temp_rx_ring, adapter->rx_ring,
+		       adapter->num_rx_queues * sizeof(struct ixgbe_ring));
 		for (i = 0; i < adapter->num_rx_queues; i++) {
-			temp_ring[i].count = new_rx_count;
-			err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
+			temp_rx_ring[i].count = new_rx_count;
+			err = ixgbe_setup_rx_resources(adapter,
+			                               &temp_rx_ring[i]);
 			if (err) {
 				while (i) {
 					i--;
 					ixgbe_free_rx_resources(adapter,
-					                        &temp_ring[i]);
+					                      &temp_rx_ring[i]);
 				}
 				goto err_setup;
 			}
-			temp_ring[i].v_idx = adapter->rx_ring[i].v_idx;
+			temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
 		}
+		need_update = true;
+	}
+
+	/* if rings need to be updated, here's the place to do it in one shot */
+	if (need_update) {
 		if (netif_running(netdev))
-			netdev->netdev_ops->ndo_stop(netdev);
-		ixgbe_reset_interrupt_capability(adapter);
-		ixgbe_napi_del_all(adapter);
-		INIT_LIST_HEAD(&netdev->napi_list);
-		kfree(adapter->rx_ring);
-		adapter->rx_ring = temp_ring;
-		temp_ring = NULL;
+			ixgbe_down(adapter);
 
-		adapter->rx_ring_count = new_rx_count;
+		/* tx */
+		if (new_tx_count != adapter->tx_ring_count) {
+			kfree(adapter->tx_ring);
+			adapter->tx_ring = temp_tx_ring;
+			temp_tx_ring = NULL;
+			adapter->tx_ring_count = new_tx_count;
+		}
+
+		/* rx */
+		if (new_rx_count != adapter->rx_ring_count) {
+			kfree(adapter->rx_ring);
+			adapter->rx_ring = temp_rx_ring;
+			temp_rx_ring = NULL;
+			adapter->rx_ring_count = new_rx_count;
+		}
 	}
 
 	/* success! */
 	err = 0;
-err_setup:
-	ixgbe_init_interrupt_scheme(adapter);
 	if (netif_running(netdev))
-		netdev->netdev_ops->ndo_open(netdev);
+		ixgbe_up(adapter);
 
+err_setup:
 	clear_bit(__IXGBE_RESETTING, &adapter->state);
 	return err;
 }
@@ -808,15 +866,6 @@ static void ixgbe_get_ethtool_stats(stru
 	int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
 	int j, k;
 	int i;
-	u64 aggregated = 0, flushed = 0, no_desc = 0;
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
-		flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
-		no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
-	}
-	adapter->lro_aggregated = aggregated;
-	adapter->lro_flushed = flushed;
-	adapter->lro_no_desc = no_desc;
 
 	ixgbe_update_stats(adapter);
 	for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
@@ -894,15 +943,75 @@ static void ixgbe_get_strings(struct net
 }
 
 
+static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
+                               struct ethtool_wolinfo *wol)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	int retval = 1;
+
+	switch(hw->device_id) {
+	case IXGBE_DEV_ID_82599_KX4:
+		retval = 0;
+		break;
+	default:
+		wol->supported = 0;
+		retval = 0;
+	}
+
+	return retval;
+}
+
 static void ixgbe_get_wol(struct net_device *netdev,
                           struct ethtool_wolinfo *wol)
 {
-	wol->supported = 0;
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+	wol->supported = WAKE_UCAST | WAKE_MCAST |
+	                 WAKE_BCAST | WAKE_MAGIC;
 	wol->wolopts = 0;
 
+	if (ixgbe_wol_exclusion(adapter, wol) ||
+	    !device_can_wakeup(&adapter->pdev->dev))
+		return;
+
+	if (adapter->wol & IXGBE_WUFC_EX)
+		wol->wolopts |= WAKE_UCAST;
+	if (adapter->wol & IXGBE_WUFC_MC)
+		wol->wolopts |= WAKE_MCAST;
+	if (adapter->wol & IXGBE_WUFC_BC)
+		wol->wolopts |= WAKE_BCAST;
+	if (adapter->wol & IXGBE_WUFC_MAG)
+		wol->wolopts |= WAKE_MAGIC;
+
 	return;
 }
 
+static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+		return -EOPNOTSUPP;
+
+	if (ixgbe_wol_exclusion(adapter, wol))
+		return wol->wolopts ? -EOPNOTSUPP : 0;
+
+	adapter->wol = 0;
+
+	if (wol->wolopts & WAKE_UCAST)
+		adapter->wol |= IXGBE_WUFC_EX;
+	if (wol->wolopts & WAKE_MCAST)
+		adapter->wol |= IXGBE_WUFC_MC;
+	if (wol->wolopts & WAKE_BCAST)
+		adapter->wol |= IXGBE_WUFC_BC;
+	if (wol->wolopts & WAKE_MAGIC)
+		adapter->wol |= IXGBE_WUFC_MAG;
+
+	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+	return 0;
+}
+
 static int ixgbe_nway_reset(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -965,40 +1074,47 @@ static int ixgbe_set_coalesce(struct net
                               struct ethtool_coalesce *ec)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	struct ixgbe_hw *hw = &adapter->hw;
 	int i;
 
 	if (ec->tx_max_coalesced_frames_irq)
 		adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
 
 	if (ec->rx_coalesce_usecs > 1) {
+		/* check the limits */
+		if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
+		    (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
+			return -EINVAL;
+
 		/* store the value in ints/second */
 		adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
 
 		/* static value of interrupt rate */
 		adapter->itr_setting = adapter->eitr_param;
-		/* clear the lower bit */
+		/* clear the lower bit as its used for dynamic state */
 		adapter->itr_setting &= ~1;
 	} else if (ec->rx_coalesce_usecs == 1) {
 		/* 1 means dynamic mode */
 		adapter->eitr_param = 20000;
 		adapter->itr_setting = 1;
 	} else {
-		/* any other value means disable eitr, which is best
-		 * served by setting the interrupt rate very high */
-		adapter->eitr_param = 3000000;
+		/*
+		 * any other value means disable eitr, which is best
+		 * served by setting the interrupt rate very high
+		 */
+		adapter->eitr_param = IXGBE_MAX_INT_RATE;
 		adapter->itr_setting = 0;
 	}
 
 	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
 		struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
 		if (q_vector->txr_count && !q_vector->rxr_count)
+			/* tx vector gets half the rate */
 			q_vector->eitr = (adapter->eitr_param >> 1);
 		else
 			/* rx only or mixed */
 			q_vector->eitr = adapter->eitr_param;
-		IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
-		                EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+		ixgbe_write_eitr(adapter, i,
+		                 EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
 	}
 
 	return 0;
@@ -1012,6 +1128,7 @@ static const struct ethtool_ops ixgbe_et
 	.get_regs_len           = ixgbe_get_regs_len,
 	.get_regs               = ixgbe_get_regs,
 	.get_wol                = ixgbe_get_wol,
+	.set_wol                = ixgbe_set_wol,
 	.nway_reset             = ixgbe_nway_reset,
 	.get_link               = ethtool_op_get_link,
 	.get_eeprom_len         = ixgbe_get_eeprom_len,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,7 +31,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
-#include <linux/inet_lro.h>
 #include <linux/aer.h>
 
 #include "ixgbe_type.h"
@@ -72,6 +71,7 @@
 #define IXGBE_RXBUFFER_128   128    /* Used for packet split */
 #define IXGBE_RXBUFFER_256   256    /* Used for packet split */
 #define IXGBE_RXBUFFER_2048  2048
+#define IXGBE_MAX_RXBUFFER   16384  /* largest size for a single descriptor */
 
 #define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
 
@@ -88,9 +88,6 @@
 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK   0x0000e000
 #define IXGBE_TX_FLAGS_VLAN_SHIFT	16
 
-#define IXGBE_MAX_LRO_DESCRIPTORS       8
-#define IXGBE_MAX_LRO_AGGREGATE         32
-
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
 struct ixgbe_tx_buffer {
@@ -142,21 +139,25 @@ struct ixgbe_ring {
 	/* cpu for tx queue */
 	int cpu;
 #endif
-	struct net_lro_mgr lro_mgr;
-	bool lro_used;
 	struct ixgbe_queue_stats stats;
-	u16 v_idx; /* maps directly to the index for this ring in the hardware
-	           * vector array, can also be used for finding the bit in EICR
-	           * and friends that represents the vector for this ring */
+	u64 v_idx; /* maps directly to the index for this ring in the hardware
+	            * vector array, can also be used for finding the bit in EICR
+	            * and friends that represents the vector for this ring */
 
 
 	u16 work_limit;                /* max work per interrupt */
 	u16 rx_buf_len;
 };
 
-#define RING_F_DCB  0
-#define RING_F_VMDQ 1
-#define RING_F_RSS  2
+enum ixgbe_ring_f_enum {
+	RING_F_NONE = 0,
+	RING_F_DCB,
+	RING_F_VMDQ,
+	RING_F_RSS,
+
+	RING_F_ARRAY_SIZE      /* must be last in enum set */
+};
+
 #define IXGBE_MAX_DCB_INDICES   8
 #define IXGBE_MAX_RSS_INDICES  16
 #define IXGBE_MAX_VMDQ_INDICES 16
@@ -165,8 +166,8 @@ struct ixgbe_ring_feature {
 	int mask;
 };
 
-#define MAX_RX_QUEUES 64
-#define MAX_TX_QUEUES 32
+#define MAX_RX_QUEUES 128
+#define MAX_TX_QUEUES 128
 
 #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
                               ? 8 : 1)
@@ -188,10 +189,11 @@ struct ixgbe_q_vector {
 };
 
 /* Helper macros to switch between ints/sec and what the register uses.
- * And yes, it's the same math going both ways.
+ * And yes, it's the same math going both ways.  The lowest value
+ * supported by all of the ixgbe hardware is 8.
  */
 #define EITR_INTS_PER_SEC_TO_REG(_eitr) \
-	((_eitr) ? (1000000000 / ((_eitr) * 256)) : 0)
+	((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8)
 #define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG
 
 #define IXGBE_DESC_UNUSED(R) \
@@ -210,9 +212,15 @@ struct ixgbe_q_vector {
 #define OTHER_VECTOR 1
 #define NON_Q_VECTORS (OTHER_VECTOR)
 
-#define MAX_MSIX_Q_VECTORS 16
+#define MAX_MSIX_VECTORS_82599 64
+#define MAX_MSIX_Q_VECTORS_82599 64
+#define MAX_MSIX_VECTORS_82598 18
+#define MAX_MSIX_Q_VECTORS_82598 16
+
+#define MAX_MSIX_Q_VECTORS MAX_MSIX_Q_VECTORS_82599
+#define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599
+
 #define MIN_MSIX_Q_VECTORS 2
-#define MAX_MSIX_COUNT (MAX_MSIX_Q_VECTORS + NON_Q_VECTORS)
 #define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
 
 /* board specific private data structure */
@@ -222,7 +230,7 @@ struct ixgbe_adapter {
 	u16 bd_number;
 	struct work_struct reset_task;
 	struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
-	char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
+	char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
 	struct ixgbe_dcb_config dcb_cfg;
 	struct ixgbe_dcb_config temp_dcb_cfg;
 	u8 dcb_set_bitmap;
@@ -247,10 +255,12 @@ struct ixgbe_adapter {
 	struct ixgbe_ring *rx_ring;	/* 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;
-	struct ixgbe_ring_feature ring_feature[3];
+	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;
@@ -274,6 +284,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 11)
 #define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 12)
 #define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 14)
 #define IXGBE_FLAG_RSS_ENABLED                  (u32)(1 << 16)
 #define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
 #define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
@@ -281,7 +292,8 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_FAN_FAIL_CAPABLE             (u32)(1 << 20)
 #define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 22)
 #define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 23)
-#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_LINK_TASK             (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_MOD_TASK              (u32)(1 << 25)
 
 /* default to trying for four seconds */
 #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -301,9 +313,6 @@ struct ixgbe_adapter {
 
 	unsigned long state;
 	u64 tx_busy;
-	u64 lro_aggregated;
-	u64 lro_flushed;
-	u64 lro_no_desc;
 	unsigned int tx_ring_count;
 	unsigned int rx_ring_count;
 
@@ -314,6 +323,10 @@ struct ixgbe_adapter {
 	struct work_struct watchdog_task;
 	struct work_struct sfp_task;
 	struct timer_list sfp_timer;
+	struct work_struct multispeed_fiber_task;
+	struct work_struct sfp_config_module_task;
+	u32 wol;
+	u16 eeprom_version;
 };
 
 enum ixbge_state_t {
@@ -325,9 +338,11 @@ enum ixbge_state_t {
 
 enum ixgbe_boards {
 	board_82598,
+	board_82599,
 };
 
 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 int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
@@ -352,5 +367,6 @@ extern void ixgbe_reset_interrupt_capabi
 extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
 void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
 void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
+extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
 
 #endif /* _IXGBE_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_main.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -47,12 +47,13 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "1.3.30-k2"
+#define DRV_VERSION "2.0.8-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
-static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
 	[board_82598] = &ixgbe_82598_info,
+	[board_82599] = &ixgbe_82599_info,
 };
 
 /* ixgbe_pci_tbl - PCI Device ID Table
@@ -64,6 +65,8 @@ static const struct ixgbe_info *ixgbe_in
  *   Class, Class Mask, private data (not used) }
  */
 static struct pci_device_id ixgbe_pci_tbl[] = {
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598),
+	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
@@ -82,6 +85,12 @@ static struct pci_device_id ixgbe_pci_tb
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM),
 	 board_82598 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX),
+	 board_82598 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4),
+	 board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
+	 board_82599 },
 
 	/* required last entry */
 	{0, }
@@ -125,32 +134,67 @@ static void ixgbe_get_hw_control(struct
 	                ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
 }
 
-static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
-                           u8 msix_vector)
+/*
+ * ixgbe_set_ivar - set the IVAR registers, mapping interrupt causes to vectors
+ * @adapter: pointer to adapter struct
+ * @direction: 0 for Rx, 1 for Tx, -1 for other causes
+ * @queue: queue to map the corresponding interrupt to
+ * @msix_vector: the vector to map to the corresponding queue
+ *
+ */
+static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
+	                   u8 queue, u8 msix_vector)
 {
 	u32 ivar, index;
-
-	msix_vector |= IXGBE_IVAR_ALLOC_VAL;
-	index = (int_alloc_entry >> 2) & 0x1F;
-	ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR(index));
-	ivar &= ~(0xFF << (8 * (int_alloc_entry & 0x3)));
-	ivar |= (msix_vector << (8 * (int_alloc_entry & 0x3)));
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar);
+	struct ixgbe_hw *hw = &adapter->hw;
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB:
+		msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+		if (direction == -1)
+			direction = 0;
+		index = (((direction * 64) + queue) >> 2) & 0x1F;
+		ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+		ivar &= ~(0xFF << (8 * (queue & 0x3)));
+		ivar |= (msix_vector << (8 * (queue & 0x3)));
+		IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+		break;
+	case ixgbe_mac_82599EB:
+		if (direction == -1) {
+			/* other causes */
+			msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+			index = ((queue & 1) * 8);
+			ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR_MISC);
+			ivar &= ~(0xFF << index);
+			ivar |= (msix_vector << index);
+			IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR_MISC, ivar);
+			break;
+		} else {
+			/* tx or rx causes */
+			msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+			index = ((16 * (queue & 1)) + (8 * direction));
+			ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(queue >> 1));
+			ivar &= ~(0xFF << index);
+			ivar |= (msix_vector << index);
+			IXGBE_WRITE_REG(hw, IXGBE_IVAR(queue >> 1), ivar);
+			break;
+		}
+	default:
+		break;
+	}
 }
 
 static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
                                              struct ixgbe_tx_buffer
                                              *tx_buffer_info)
 {
-	if (tx_buffer_info->dma) {
-		pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
-		               tx_buffer_info->length, PCI_DMA_TODEVICE);
-		tx_buffer_info->dma = 0;
-	}
+	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;
 	}
+	tx_buffer_info->time_stamp = 0;
 	/* tx_buffer_info must be completely set up in the transmit path */
 }
 
@@ -159,15 +203,11 @@ static inline bool ixgbe_check_tx_hang(s
                                        unsigned int eop)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 head, tail;
 
 	/* Detect a transmit hang in hardware, this serializes the
 	 * check with the clearing of time_stamp and movement of eop */
-	head = IXGBE_READ_REG(hw, tx_ring->head);
-	tail = IXGBE_READ_REG(hw, tx_ring->tail);
 	adapter->detect_tx_hung = false;
-	if ((head != tail) &&
-	    tx_ring->tx_buffer_info[eop].time_stamp &&
+	if (tx_ring->tx_buffer_info[eop].time_stamp &&
 	    time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
 	    !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
 		/* detected Tx unit hang */
@@ -182,7 +222,8 @@ static inline bool ixgbe_check_tx_hang(s
 			"  time_stamp           <%lx>\n"
 			"  jiffies              <%lx>\n",
 			tx_ring->queue_index,
-			head, tail,
+			IXGBE_READ_REG(hw, tx_ring->head),
+			IXGBE_READ_REG(hw, tx_ring->tail),
 			tx_ring->next_to_use, eop,
 			tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
 		return true;
@@ -200,39 +241,39 @@ static inline bool ixgbe_check_tx_hang(s
 #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
 
-#define GET_TX_HEAD_FROM_RING(ring) (\
-	*(volatile u32 *) \
-	((union ixgbe_adv_tx_desc *)(ring)->desc + (ring)->count))
 static void ixgbe_tx_timeout(struct net_device *netdev);
 
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
  * @tx_ring: tx ring to clean
+ *
+ * returns true if transmit work is done
  **/
 static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
                                struct ixgbe_ring *tx_ring)
 {
-	union ixgbe_adv_tx_desc *tx_desc;
-	struct ixgbe_tx_buffer *tx_buffer_info;
 	struct net_device *netdev = adapter->netdev;
-	struct sk_buff *skb;
-	unsigned int i;
-	u32 head, oldhead;
-	unsigned int count = 0;
+	union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
+	struct ixgbe_tx_buffer *tx_buffer_info;
+	unsigned int i, eop, count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
 
-	rmb();
-	head = GET_TX_HEAD_FROM_RING(tx_ring);
-	head = le32_to_cpu(head);
 	i = tx_ring->next_to_clean;
-	while (1) {
-		while (i != head) {
+	eop = tx_ring->tx_buffer_info[i].next_to_watch;
+	eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+
+	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
+	       (count < tx_ring->work_limit)) {
+		bool cleaned = false;
+		for ( ; !cleaned; count++) {
+			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
 			tx_buffer_info = &tx_ring->tx_buffer_info[i];
+			cleaned = (i == eop);
 			skb = tx_buffer_info->skb;
 
-			if (skb) {
+			if (cleaned && skb) {
 				unsigned int segs, bytecount;
 
 				/* gso_segs is currently only valid for tcp */
@@ -247,23 +288,17 @@ static bool ixgbe_clean_tx_irq(struct ix
 			ixgbe_unmap_and_free_tx_resource(adapter,
 			                                 tx_buffer_info);
 
+			tx_desc->wb.status = 0;
+
 			i++;
 			if (i == tx_ring->count)
 				i = 0;
-
-			count++;
-			if (count == tx_ring->count)
-				goto done_cleaning;
 		}
-		oldhead = head;
-		rmb();
-		head = GET_TX_HEAD_FROM_RING(tx_ring);
-		head = le32_to_cpu(head);
-		if (head == oldhead)
-			goto done_cleaning;
-	} /* while (1) */
 
-done_cleaning:
+		eop = tx_ring->tx_buffer_info[i].next_to_watch;
+		eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+	}
+
 	tx_ring->next_to_clean = i;
 
 #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
@@ -291,17 +326,16 @@ done_cleaning:
 	}
 
 	/* re-arm the interrupt */
-	if ((total_packets >= tx_ring->work_limit) ||
-	    (count == tx_ring->count))
+	if (count >= tx_ring->work_limit)
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
 
 	tx_ring->total_bytes += total_bytes;
 	tx_ring->total_packets += total_packets;
-	tx_ring->stats.bytes += total_bytes;
 	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 (total_packets ? true : false);
+	return (count < tx_ring->work_limit);
 }
 
 #ifdef CONFIG_IXGBE_DCA
@@ -314,13 +348,19 @@ static void ixgbe_update_rx_dca(struct i
 
 	if (rx_ring->cpu != cpu) {
 		rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
-		rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
-		rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+		if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+			rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
+			rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+			rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
+			rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+			           IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+		}
 		rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 		rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
 		rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
 		rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
-			    IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+		            IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
 		rx_ring->cpu = cpu;
 	}
@@ -336,8 +376,14 @@ static void ixgbe_update_tx_dca(struct i
 
 	if (tx_ring->cpu != cpu) {
 		txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
-		txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
-		txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+		if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+			txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
+			txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+			txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
+			txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+			           IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+		}
 		txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
 		tx_ring->cpu = cpu;
@@ -403,23 +449,21 @@ static int __ixgbe_notify_dca(struct dev
  * @rx_ring: rx descriptor ring (for a specific queue) to setup
  * @rx_desc: rx descriptor
  **/
-static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
+static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
                               struct sk_buff *skb, u8 status,
-                              struct ixgbe_ring *ring,
                               union ixgbe_adv_rx_desc *rx_desc)
 {
+	struct ixgbe_adapter *adapter = q_vector->adapter;
+	struct napi_struct *napi = &q_vector->napi;
 	bool is_vlan = (status & IXGBE_RXD_STAT_VP);
 	u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
 
-	if (adapter->netdev->features & NETIF_F_LRO &&
-	    skb->ip_summed == CHECKSUM_UNNECESSARY) {
+	skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
+	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		if (adapter->vlgrp && is_vlan && (tag != 0))
-			lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
-			                             adapter->vlgrp, tag,
-			                             rx_desc);
+			vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
 		else
-			lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
-		ring->lro_used = true;
+			napi_gro_receive(napi, skb);
 	} else {
 		if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
 			if (adapter->vlgrp && is_vlan && (tag != 0))
@@ -470,6 +514,19 @@ static inline void ixgbe_rx_checksum(str
 	adapter->hw_csum_rx_good++;
 }
 
+static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
+                                         struct ixgbe_ring *rx_ring, u32 val)
+{
+	/*
+	 * Force memory writes to complete before letting h/w
+	 * know there are new descriptors to fetch.  (Only
+	 * applicable for weak-ordered memory model archs,
+	 * such as IA-64).
+	 */
+	wmb();
+	IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val);
+}
+
 /**
  * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
  * @adapter: address of board private structure
@@ -482,6 +539,7 @@ static void ixgbe_alloc_rx_buffers(struc
 	union ixgbe_adv_rx_desc *rx_desc;
 	struct ixgbe_rx_buffer *bi;
 	unsigned int i;
+	unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN;
 
 	i = rx_ring->next_to_use;
 	bi = &rx_ring->rx_buffer_info[i];
@@ -511,9 +569,7 @@ 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));
+			skb = netdev_alloc_skb(adapter->netdev, bufsz);
 
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
@@ -528,8 +584,7 @@ static void ixgbe_alloc_rx_buffers(struc
 			skb_reserve(skb, NET_IP_ALIGN);
 
 			bi->skb = skb;
-			bi->dma = pci_map_single(pdev, skb->data,
-			                         rx_ring->rx_buf_len,
+			bi->dma = pci_map_single(pdev, skb->data, bufsz,
 			                         PCI_DMA_FROMDEVICE);
 		}
 		/* Refresh the desc even if buffer_addrs didn't change because
@@ -553,14 +608,7 @@ no_buffers:
 		if (i-- == 0)
 			i = (rx_ring->count - 1);
 
-		/*
-		 * Force memory writes to complete before letting h/w
-		 * know there are new descriptors to fetch.  (Only
-		 * applicable for weak-ordered memory model archs,
-		 * such as IA-64).
-		 */
-		wmb();
-		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+		ixgbe_release_rx_desc(&adapter->hw, rx_ring, i);
 	}
 }
 
@@ -574,10 +622,11 @@ static inline u16 ixgbe_get_pkt_info(uni
 	return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
 }
 
-static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
+static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                                struct ixgbe_ring *rx_ring,
                                int *work_done, int work_to_do)
 {
+	struct ixgbe_adapter *adapter = q_vector->adapter;
 	struct pci_dev *pdev = adapter->pdev;
 	union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
 	struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -678,7 +727,7 @@ static bool ixgbe_clean_rx_irq(struct ix
 		total_rx_packets++;
 
 		skb->protocol = eth_type_trans(skb, adapter->netdev);
-		ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
+		ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
 
 next_desc:
 		rx_desc->wb.upper.status_error = 0;
@@ -696,11 +745,6 @@ next_desc:
 		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 	}
 
-	if (rx_ring->lro_used) {
-		lro_flush_all(&rx_ring->lro_mgr);
-		rx_ring->lro_used = false;
-	}
-
 	rx_ring->next_to_clean = i;
 	cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
 
@@ -731,7 +775,8 @@ static void ixgbe_configure_msix(struct
 
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
-	/* Populate the IVAR table and set the ITR values to the
+	/*
+	 * Populate the IVAR table and set the ITR values to the
 	 * corresponding register.
 	 */
 	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
@@ -742,7 +787,7 @@ static void ixgbe_configure_msix(struct
 
 		for (i = 0; i < q_vector->rxr_count; i++) {
 			j = adapter->rx_ring[r_idx].reg_idx;
-			ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
+			ixgbe_set_ivar(adapter, 0, j, v_idx);
 			r_idx = find_next_bit(q_vector->rxr_idx,
 			                      adapter->num_rx_queues,
 			                      r_idx + 1);
@@ -752,7 +797,7 @@ static void ixgbe_configure_msix(struct
 
 		for (i = 0; i < q_vector->txr_count; i++) {
 			j = adapter->tx_ring[r_idx].reg_idx;
-			ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
+			ixgbe_set_ivar(adapter, 1, j, v_idx);
 			r_idx = find_next_bit(q_vector->txr_idx,
 			                      adapter->num_tx_queues,
 			                      r_idx + 1);
@@ -761,15 +806,23 @@ static void ixgbe_configure_msix(struct
 		/* if this is a tx only vector halve the interrupt rate */
 		if (q_vector->txr_count && !q_vector->rxr_count)
 			q_vector->eitr = (adapter->eitr_param >> 1);
-		else
+		else if (q_vector->rxr_count)
 			/* rx only */
 			q_vector->eitr = adapter->eitr_param;
 
+		/*
+		 * since this is initial set up don't need to call
+		 * ixgbe_write_eitr helper
+		 */
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
 		                EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
 	}
 
-	ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
+	if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+		ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
+		               v_idx);
+	else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+		ixgbe_set_ivar(adapter, -1, 1, v_idx);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
 
 	/* set up to autoclear timer, and the vectors */
@@ -845,10 +898,35 @@ update_itr_done:
 	return retval;
 }
 
+/**
+ * ixgbe_write_eitr - write EITR register in hardware specific way
+ * @adapter: pointer to adapter struct
+ * @v_idx: vector index into q_vector array
+ * @itr_reg: new value to be written in *register* format, not ints/s
+ *
+ * This function is made to be called by ethtool and by the driver
+ * when it needs to update EITR registers at runtime.  Hardware
+ * specific quirks/differences are taken care of here.
+ */
+void ixgbe_write_eitr(struct ixgbe_adapter *adapter, int v_idx, u32 itr_reg)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+		/* must write high and low 16 bits to reset counter */
+		itr_reg |= (itr_reg << 16);
+	} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		/*
+		 * set the WDIS bit to not clear the timer bits and cause an
+		 * immediate assertion of the interrupt
+		 */
+		itr_reg |= IXGBE_EITR_CNT_WDIS;
+	}
+	IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg);
+}
+
 static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
 {
 	struct ixgbe_adapter *adapter = q_vector->adapter;
-	struct ixgbe_hw *hw = &adapter->hw;
 	u32 new_itr;
 	u8 current_itr, ret_itr;
 	int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
@@ -903,14 +981,13 @@ static void ixgbe_set_itr_msix(struct ix
 
 	if (new_itr != q_vector->eitr) {
 		u32 itr_reg;
+
+		/* save the algorithm value here, not the smoothed one */
+		q_vector->eitr = new_itr;
 		/* do an exponential smoothing */
 		new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
-		q_vector->eitr = new_itr;
 		itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
-		/* must write high and low 16 bits to reset counter */
-		DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
-		        itr_reg);
-		IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
+		ixgbe_write_eitr(adapter, v_idx, itr_reg);
 	}
 
 	return;
@@ -928,6 +1005,24 @@ static void ixgbe_check_fan_failure(stru
 	}
 }
 
+static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+	if (eicr & IXGBE_EICR_GPI_SDP1) {
+		/* Clear the interrupt */
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+		schedule_work(&adapter->multispeed_fiber_task);
+	} else if (eicr & IXGBE_EICR_GPI_SDP2) {
+		/* Clear the interrupt */
+		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+		schedule_work(&adapter->sfp_config_module_task);
+	} else {
+		/* Interrupt isn't for us... */
+		return;
+	}
+}
+
 static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -946,13 +1041,25 @@ static irqreturn_t ixgbe_msix_lsc(int ir
 	struct net_device *netdev = data;
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
+	u32 eicr;
+
+	/*
+	 * Workaround for Silicon errata.  Use clear-by-write instead
+	 * of clear-by-read.  Reading with EICS will return the
+	 * interrupt causes without clearing, which later be done
+	 * with the write to EICR.
+	 */
+	eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
+	IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
 
 	if (eicr & IXGBE_EICR_LSC)
 		ixgbe_check_lsc(adapter);
 
-	ixgbe_check_fan_failure(adapter, eicr);
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		ixgbe_check_fan_failure(adapter, eicr);
 
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		ixgbe_check_sfp_event(adapter, eicr);
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
 		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
 
@@ -1015,7 +1122,7 @@ static irqreturn_t ixgbe_msix_clean_rx(i
 	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* disable interrupts on this vector only */
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
-	netif_rx_schedule(&q_vector->napi);
+	napi_schedule(&q_vector->napi);
 
 	return IRQ_HANDLED;
 }
@@ -1052,12 +1159,12 @@ static int ixgbe_clean_rxonly(struct nap
 		ixgbe_update_rx_dca(adapter, rx_ring);
 #endif
 
-	ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+	ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
-		netif_rx_complete(napi);
-		if (adapter->itr_setting & 3)
+		napi_complete(napi);
+		if (adapter->itr_setting & 1)
 			ixgbe_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBE_DOWN, &adapter->state))
 			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
@@ -1095,7 +1202,7 @@ static int ixgbe_clean_rxonly_many(struc
 		if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
 			ixgbe_update_rx_dca(adapter, rx_ring);
 #endif
-		ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+		ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 		enable_mask |= rx_ring->v_idx;
 		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
 		                      r_idx + 1);
@@ -1105,8 +1212,8 @@ static int ixgbe_clean_rxonly_many(struc
 	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
-		netif_rx_complete(napi);
-		if (adapter->itr_setting & 3)
+		napi_complete(napi);
+		if (adapter->itr_setting & 1)
 			ixgbe_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBE_DOWN, &adapter->state))
 			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
@@ -1276,7 +1383,6 @@ out:
 
 static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
 	struct ixgbe_q_vector *q_vector = adapter->q_vector;
 	u8 current_itr;
 	u32 new_itr = q_vector->eitr;
@@ -1311,35 +1417,19 @@ static void ixgbe_set_itr(struct ixgbe_a
 
 	if (new_itr != q_vector->eitr) {
 		u32 itr_reg;
+
+		/* save the algorithm value here, not the smoothed one */
+		q_vector->eitr = new_itr;
 		/* do an exponential smoothing */
 		new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
-		q_vector->eitr = new_itr;
 		itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
-		/* must write high and low 16 bits to reset counter */
-		IXGBE_WRITE_REG(hw, IXGBE_EITR(0), itr_reg | (itr_reg)<<16);
+		ixgbe_write_eitr(adapter, 0, itr_reg);
 	}
 
 	return;
 }
 
 /**
- * ixgbe_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- **/
-static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
-{
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
-	IXGBE_WRITE_FLUSH(&adapter->hw);
-	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-		int i;
-		for (i = 0; i < adapter->num_msix_vectors; i++)
-			synchronize_irq(adapter->msix_entries[i].vector);
-	} else {
-		synchronize_irq(adapter->pdev->irq);
-	}
-}
-
-/**
  * ixgbe_irq_enable - Enable default interrupt generation settings
  * @adapter: board private structure
  **/
@@ -1349,7 +1439,21 @@ static inline void ixgbe_irq_enable(stru
 	mask = IXGBE_EIMS_ENABLE_MASK;
 	if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
 		mask |= IXGBE_EIMS_GPI_SDP1;
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		mask |= IXGBE_EIMS_ECC;
+		mask |= IXGBE_EIMS_GPI_SDP1;
+		mask |= IXGBE_EIMS_GPI_SDP2;
+	}
+
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		/* enable the rest of the queue vectors */
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1),
+		                (IXGBE_EIMS_RTX_QUEUE << 16));
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
+		                ((IXGBE_EIMS_RTX_QUEUE << 16) |
+		                  IXGBE_EIMS_RTX_QUEUE));
+	}
 	IXGBE_WRITE_FLUSH(&adapter->hw);
 }
 
@@ -1365,6 +1469,12 @@ static irqreturn_t ixgbe_intr(int irq, v
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 eicr;
 
+	/*
+	 * Workaround for silicon errata.  Mask the interrupts
+	 * before the read of EICR.
+	 */
+	IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
+
 	/* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
 	 * therefore no explict interrupt disable is necessary */
 	eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
@@ -1379,15 +1489,18 @@ static irqreturn_t ixgbe_intr(int irq, v
 	if (eicr & IXGBE_EICR_LSC)
 		ixgbe_check_lsc(adapter);
 
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		ixgbe_check_sfp_event(adapter, eicr);
+
 	ixgbe_check_fan_failure(adapter, eicr);
 
-	if (netif_rx_schedule_prep(&adapter->q_vector[0].napi)) {
+	if (napi_schedule_prep(&adapter->q_vector[0].napi)) {
 		adapter->tx_ring[0].total_packets = 0;
 		adapter->tx_ring[0].total_bytes = 0;
 		adapter->rx_ring[0].total_packets = 0;
 		adapter->rx_ring[0].total_bytes = 0;
 		/* would disable interrupts here but EIAM disabled it */
-		__netif_rx_schedule(&adapter->q_vector[0].napi);
+		__napi_schedule(&adapter->q_vector[0].napi);
 	}
 
 	return IRQ_HANDLED;
@@ -1459,6 +1572,39 @@ static void ixgbe_free_irq(struct ixgbe_
 }
 
 /**
+ * ixgbe_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
+{
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
+	}
+	IXGBE_WRITE_FLUSH(&adapter->hw);
+	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+		int i;
+		for (i = 0; i < adapter->num_msix_vectors; i++)
+			synchronize_irq(adapter->msix_entries[i].vector);
+	} else {
+		synchronize_irq(adapter->pdev->irq);
+	}
+}
+
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
+{
+	u32 mask = IXGBE_EIMS_RTX_QUEUE;
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
+		                (mask << 16 | mask));
+	}
+	/* skip the flush */
+}
+
+/**
  * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
  *
  **/
@@ -1469,8 +1615,8 @@ static void ixgbe_configure_msi_and_lega
 	IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
 	                EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
 
-	ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
-	ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
+	ixgbe_set_ivar(adapter, 0, 0, 0);
+	ixgbe_set_ivar(adapter, 1, 0, 0);
 
 	map_vector_to_rxq(adapter, 0, 0);
 	map_vector_to_txq(adapter, 0, 0);
@@ -1486,7 +1632,7 @@ static void ixgbe_configure_msi_and_lega
  **/
 static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
 {
-	u64 tdba, tdwba;
+	u64 tdba;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 i, j, tdlen, txctrl;
 
@@ -1497,13 +1643,8 @@ static void ixgbe_configure_tx(struct ix
 		tdba = ring->dma;
 		tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
 		IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
-		                (tdba & DMA_32BIT_MASK));
+		                (tdba & DMA_BIT_MASK(32)));
 		IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
-		tdwba = ring->dma +
-		        (ring->count * sizeof(union ixgbe_adv_tx_desc));
-		tdwba |= IXGBE_TDWBAL_HEAD_WB_ENABLE;
-		IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(j), tdwba & DMA_32BIT_MASK);
-		IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(j), (tdwba >> 32));
 		IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
 		IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
 		IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
@@ -1516,26 +1657,25 @@ static void ixgbe_configure_tx(struct ix
 		txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
 	}
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		/* We enable 8 traffic classes, DCB only */
+		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+			IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
+			                IXGBE_MTQC_8TC_8TQ));
+	}
 }
 
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT	2
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
 
 static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
 {
 	struct ixgbe_ring *rx_ring;
 	u32 srrctl;
-	int queue0;
+	int queue0 = 0;
 	unsigned long mask;
 
-	/* program one srrctl register per VMDq index */
-	if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
-		long shift, len;
-		mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
-		len = sizeof(adapter->ring_feature[RING_F_VMDQ].mask) * 8;
-		shift = find_first_bit(&mask, len);
-		queue0 = index & mask;
-		index = (index & mask) >> shift;
-	/* program one srrctl per RSS queue since RDRXCTL.MVMEN is enabled */
+	if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+		queue0 = index;
 	} else {
 		mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
 		queue0 = index & mask;
@@ -1550,7 +1690,14 @@ static void ixgbe_configure_srrctl(struc
 	srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
 
 	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-		srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+		u16 bufsz = IXGBE_RXBUFFER_2048;
+		/* grow the amount we can receive on large page machines */
+		if (bufsz < (PAGE_SIZE / 2))
+			bufsz = (PAGE_SIZE / 2);
+		/* cap the bufsz at our largest descriptor size */
+		bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
+
+		srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
 		srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
 		srrctl |= ((IXGBE_RX_HDR_SIZE <<
 		            IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
@@ -1565,39 +1712,10 @@ static void ixgbe_configure_srrctl(struc
 			srrctl |= rx_ring->rx_buf_len >>
 			          IXGBE_SRRCTL_BSIZEPKT_SHIFT;
 	}
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
-}
 
-/**
- * ixgbe_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: private data
- **/
-static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
-                             u64 *hdr_flags, void *priv)
-{
-	union ixgbe_adv_rx_desc *rx_desc = priv;
-
-	/* Verify that this is a valid IPv4 TCP packet */
-	if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) &&
-	     (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP)))
-		return -1;
-
-	/* Set network headers */
-	skb_reset_network_header(skb);
-	skb_set_transport_header(skb, ip_hdrlen(skb));
-	*iphdr = ip_hdr(skb);
-	*tcph = tcp_hdr(skb);
-	*hdr_flags = LRO_IPV4 | LRO_TCP;
-	return 0;
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
 }
 
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
-                           (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
-
 /**
  * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
  * @adapter: board private structure
@@ -1616,8 +1734,7 @@ static void ixgbe_configure_rx(struct ix
 	                  0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
 	                  0x6A3E67EA, 0x14364D17, 0x3BED200D};
 	u32 fctrl, hlreg0;
-	u32 pages;
-	u32 reta = 0, mrqc;
+	u32 reta = 0, mrqc = 0;
 	u32 rdrxctl;
 	int rx_buf_len;
 
@@ -1627,6 +1744,14 @@ static void ixgbe_configure_rx(struct ix
 	/* Set the RX buffer length according to the mode */
 	if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
 		rx_buf_len = IXGBE_RX_HDR_SIZE;
+		if (hw->mac.type == ixgbe_mac_82599EB) {
+			/* PSRTYPE must be initialized in 82599 */
+			u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+			              IXGBE_PSRTYPE_UDPHDR |
+			              IXGBE_PSRTYPE_IPV4HDR |
+			              IXGBE_PSRTYPE_IPV6HDR;
+			IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
+		}
 	} else {
 		if (netdev->mtu <= ETH_DATA_LEN)
 			rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
@@ -1637,6 +1762,7 @@ static void ixgbe_configure_rx(struct ix
 	fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
 	fctrl |= IXGBE_FCTRL_BAM;
 	fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
+	fctrl |= IXGBE_FCTRL_PMCF;
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
 
 	hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
@@ -1646,8 +1772,6 @@ static void ixgbe_configure_rx(struct ix
 		hlreg0 |= IXGBE_HLREG0_JUMBOEN;
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 
-	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-
 	rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
 	/* disable receives while setting up the descriptors */
 	rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1658,7 +1782,7 @@ static void ixgbe_configure_rx(struct ix
 	for (i = 0; i < adapter->num_rx_queues; i++) {
 		rdba = adapter->rx_ring[i].dma;
 		j = adapter->rx_ring[i].reg_idx;
-		IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_32BIT_MASK));
+		IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
 		IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
 		IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
 		IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
@@ -1666,37 +1790,44 @@ static void ixgbe_configure_rx(struct ix
 		adapter->rx_ring[i].head = IXGBE_RDH(j);
 		adapter->rx_ring[i].tail = IXGBE_RDT(j);
 		adapter->rx_ring[i].rx_buf_len = rx_buf_len;
-		/* Intitial LRO Settings */
-		adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
-		adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
-		adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
-		adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
-		if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
-			adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
-		adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
-		adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
-		adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
 
 		ixgbe_configure_srrctl(adapter, j);
 	}
 
-	/*
-	 * For VMDq support of different descriptor types or
-	 * buffer sizes through the use of multiple SRRCTL
-	 * registers, RDRXCTL.MVMEN must be set to 1
-	 *
-	 * also, the manual doesn't mention it clearly but DCA hints
-	 * will only use queue 0's tags unless this bit is set.  Side
-	 * effects of setting this bit are only that SRRCTL must be
-	 * fully programmed [0..15]
-	 */
-	if (adapter->flags &
-	    (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_VMDQ_ENABLED)) {
+	if (hw->mac.type == ixgbe_mac_82598EB) {
+		/*
+		 * For VMDq support of different descriptor types or
+		 * buffer sizes through the use of multiple SRRCTL
+		 * registers, RDRXCTL.MVMEN must be set to 1
+		 *
+		 * also, the manual doesn't mention it clearly but DCA hints
+		 * will only use queue 0's tags unless this bit is set.  Side
+		 * effects of setting this bit are only that SRRCTL must be
+		 * fully programmed [0..15]
+		 */
 		rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
 		rdrxctl |= IXGBE_RDRXCTL_MVMEN;
 		IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
 	}
 
+	/* Program MRQC for the distribution of queues */
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		int mask = adapter->flags & (
+				IXGBE_FLAG_RSS_ENABLED
+				| IXGBE_FLAG_DCB_ENABLED
+				);
+
+		switch (mask) {
+		case (IXGBE_FLAG_RSS_ENABLED):
+			mrqc = IXGBE_MRQC_RSSEN;
+			break;
+		case (IXGBE_FLAG_DCB_ENABLED):
+			mrqc = IXGBE_MRQC_RT8TCEN;
+			break;
+		default:
+			break;
+		}
+	}
 	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
 		/* Fill out redirection table */
 		for (i = 0, j = 0; i < 128; i++, j++) {
@@ -1713,19 +1844,17 @@ static void ixgbe_configure_rx(struct ix
 		for (i = 0; i < 10; i++)
 			IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
 
-		mrqc = IXGBE_MRQC_RSSEN
+		if (hw->mac.type == ixgbe_mac_82598EB)
+			mrqc |= IXGBE_MRQC_RSSEN;
 		    /* Perform hash on these packet types */
-		       | IXGBE_MRQC_RSS_FIELD_IPV4
-		       | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
-		       | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
-		       | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
-		       | IXGBE_MRQC_RSS_FIELD_IPV6_EX
-		       | IXGBE_MRQC_RSS_FIELD_IPV6
-		       | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
-		       | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
-		       | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
-		IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+		mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
+		      | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+		      | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
+		      | IXGBE_MRQC_RSS_FIELD_IPV6
+		      | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
+		      | IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
 	}
+	IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
 
 	rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
 
@@ -1742,6 +1871,12 @@ static void ixgbe_configure_rx(struct ix
 	}
 
 	IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
+
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+		rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+		IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+	}
 }
 
 static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -1775,6 +1910,7 @@ static void ixgbe_vlan_rx_register(struc
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	u32 ctrl;
+	int i, j;
 
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
 		ixgbe_irq_disable(adapter);
@@ -1786,18 +1922,24 @@ static void ixgbe_vlan_rx_register(struc
 	 * not in DCB mode.
 	 */
 	ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
-	ctrl |= IXGBE_VLNCTRL_VME;
-	ctrl &= ~IXGBE_VLNCTRL_CFIEN;
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
-	ixgbe_vlan_rx_add_vid(netdev, 0);
-
-	if (grp) {
+	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);
+	} 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_VME;
 		ctrl &= ~IXGBE_VLNCTRL_CFIEN;
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			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_vlan_rx_add_vid(netdev, 0);
 
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
 		ixgbe_irq_enable(adapter);
@@ -1960,9 +2102,21 @@ static void ixgbe_configure_dcb(struct i
 	}
 	/* Enable VLAN tag insert/strip */
 	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-	vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
-	vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
-	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+	if (hw->mac.type == ixgbe_mac_82598EB) {
+		vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+	} else if (hw->mac.type == ixgbe_mac_82599EB) {
+		vlnctrl |= IXGBE_VLNCTRL_VFE;
+		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+		for (i = 0; i < adapter->num_rx_queues; i++) {
+			j = adapter->rx_ring[i].reg_idx;
+			vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
+			vlnctrl |= IXGBE_RXDCTL_VME;
+			IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
+		}
+	}
 	hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
 }
 
@@ -1993,13 +2147,115 @@ static void ixgbe_configure(struct ixgbe
 		                       (adapter->rx_ring[i].count - 1));
 }
 
+static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
+{
+	switch (hw->phy.type) {
+	case ixgbe_phy_sfp_avago:
+	case ixgbe_phy_sfp_ftl:
+	case ixgbe_phy_sfp_intel:
+	case ixgbe_phy_sfp_unknown:
+	case ixgbe_phy_tw_tyco:
+	case ixgbe_phy_tw_unknown:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * ixgbe_sfp_link_config - set up SFP+ link
+ * @adapter: pointer to private adapter struct
+ **/
+static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+
+		if (hw->phy.multispeed_fiber) {
+			/*
+			 * In multispeed fiber setups, the device may not have
+			 * had a physical connection when the driver loaded.
+			 * If that's the case, the initial link configuration
+			 * couldn't get the MAC into 10G or 1G mode, so we'll
+			 * never have a link status change interrupt fire.
+			 * We need to try and force an autonegotiation
+			 * session, then bring up link.
+			 */
+			hw->mac.ops.setup_sfp(hw);
+			if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
+				schedule_work(&adapter->multispeed_fiber_task);
+		} else {
+			/*
+			 * Direct Attach Cu and non-multispeed fiber modules
+			 * still need to be configured properly prior to
+			 * attempting link.
+			 */
+			if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
+				schedule_work(&adapter->sfp_config_module_task);
+		}
+}
+
+/**
+ * ixgbe_non_sfp_link_config - set up non-SFP+ link
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
+{
+	u32 autoneg;
+	bool link_up = false;
+	u32 ret = IXGBE_ERR_LINK_SETUP;
+
+	if (hw->mac.ops.check_link)
+		ret = hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
+
+	if (ret)
+		goto link_cfg_out;
+
+	if (hw->mac.ops.get_link_capabilities)
+		ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
+		                                        &hw->mac.autoneg);
+	if (ret)
+		goto link_cfg_out;
+
+	if (hw->mac.ops.setup_link_speed)
+		ret = hw->mac.ops.setup_link_speed(hw, autoneg, true, link_up);
+link_cfg_out:
+	return ret;
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
+	                                      int rxr)
+{
+	int j = adapter->rx_ring[rxr].reg_idx;
+	int k;
+
+	for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
+		if (IXGBE_READ_REG(&adapter->hw,
+		                   IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+			break;
+		else
+			msleep(1);
+	}
+	if (k >= IXGBE_MAX_RX_DESC_POLL) {
+		DPRINTK(DRV, ERR, "RXDCTL.ENABLE on Rx queue %d "
+		        "not set within the polling period\n", rxr);
+	}
+	ixgbe_release_rx_desc(&adapter->hw, &adapter->rx_ring[rxr],
+	                      (adapter->rx_ring[rxr].count - 1));
+}
+
 static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i, j = 0;
+	int num_rx_rings = adapter->num_rx_queues;
+	int err;
 	int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 	u32 txdctl, rxdctl, mhadd;
+	u32 dmatxctl;
 	u32 gpie;
 
 	ixgbe_get_hw_control(adapter);
@@ -2031,6 +2287,13 @@ static int ixgbe_up_complete(struct ixgb
 		IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
 	}
 
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+		gpie |= IXGBE_SDP1_GPIEN;
+		gpie |= IXGBE_SDP2_GPIEN;
+		IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+	}
+
 	mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
 	if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
 		mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -2044,11 +2307,23 @@ static int ixgbe_up_complete(struct ixgb
 		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
 		/* enable WTHRESH=8 descriptors, to encourage burst writeback */
 		txdctl |= (8 << 16);
+		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
+	}
+
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		/* DMATXCTL.EN must be set after all Tx queue config is done */
+		dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+		dmatxctl |= IXGBE_DMATXCTL_TE;
+		IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
+	}
+	for (i = 0; i < adapter->num_tx_queues; i++) {
+		j = adapter->tx_ring[i].reg_idx;
+		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
 		txdctl |= IXGBE_TXDCTL_ENABLE;
 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
 	}
 
-	for (i = 0; i < adapter->num_rx_queues; i++) {
+	for (i = 0; i < num_rx_rings; i++) {
 		j = adapter->rx_ring[i].reg_idx;
 		rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
 		/* enable PTHRESH=32 descriptors (half the internal cache)
@@ -2057,19 +2332,22 @@ static int ixgbe_up_complete(struct ixgb
 		rxdctl |= 0x0020;
 		rxdctl |= IXGBE_RXDCTL_ENABLE;
 		IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
+		if (hw->mac.type == ixgbe_mac_82599EB)
+			ixgbe_rx_desc_queue_enable(adapter, i);
 	}
 	/* enable all receives */
 	rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
-	rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
-	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxdctl);
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
+	else
+		rxdctl |= IXGBE_RXCTRL_RXEN;
+	hw->mac.ops.enable_rx_dma(hw, rxdctl);
 
 	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
 		ixgbe_configure_msix(adapter);
 	else
 		ixgbe_configure_msi_and_legacy(adapter);
 
-	ixgbe_napi_add_all(adapter);
-
 	clear_bit(__IXGBE_DOWN, &adapter->state);
 	ixgbe_napi_enable_all(adapter);
 
@@ -2078,6 +2356,28 @@ static int ixgbe_up_complete(struct ixgb
 
 	ixgbe_irq_enable(adapter);
 
+	/*
+	 * For hot-pluggable SFP+ devices, a new SFP+ module may have
+	 * arrived before interrupts were enabled.  We need to kick off
+	 * the SFP+ module setup first, then try to bring up link.
+	 * If we're not hot-pluggable SFP+, we just need to configure link
+	 * and bring it up.
+	 */
+	err = hw->phy.ops.identify(hw);
+	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+		DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+		ixgbe_down(adapter);
+		return err;
+	}
+
+	if (ixgbe_is_sfp(hw)) {
+		ixgbe_sfp_link_config(adapter);
+	} else {
+		err = ixgbe_non_sfp_link_config(hw);
+		if (err)
+			DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err);
+	}
+
 	/* enable transmits */
 	netif_tx_start_all_queues(netdev);
 
@@ -2104,6 +2404,8 @@ int ixgbe_up(struct ixgbe_adapter *adapt
 	/* hardware has been reset, we need to reload some things */
 	ixgbe_configure(adapter);
 
+	ixgbe_napi_add_all(adapter);
+
 	return ixgbe_up_complete(adapter);
 }
 
@@ -2165,8 +2467,10 @@ static void ixgbe_clean_rx_ring(struct i
 	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);
+	if (rx_ring->head)
+		writel(0, adapter->hw.hw_addr + rx_ring->head);
+	if (rx_ring->tail)
+		writel(0, adapter->hw.hw_addr + rx_ring->tail);
 }
 
 /**
@@ -2197,8 +2501,10 @@ static void ixgbe_clean_tx_ring(struct i
 	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);
+	if (tx_ring->head)
+		writel(0, adapter->hw.hw_addr + tx_ring->head);
+	if (tx_ring->tail)
+		writel(0, adapter->hw.hw_addr + tx_ring->tail);
 }
 
 /**
@@ -2261,6 +2567,11 @@ void ixgbe_down(struct ixgbe_adapter *ad
 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
 		                (txdctl & ~IXGBE_TXDCTL_ENABLE));
 	}
+	/* Disable the Tx DMA engine on 82599 */
+	if (hw->mac.type == ixgbe_mac_82599EB)
+		IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
+		                (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
+		                 ~IXGBE_DMATXCTL_TE));
 
 	netif_carrier_off(netdev);
 
@@ -2297,10 +2608,10 @@ void ixgbe_down(struct ixgbe_adapter *ad
  **/
 static int ixgbe_poll(struct napi_struct *napi, int budget)
 {
-	struct ixgbe_q_vector *q_vector = container_of(napi,
-	                                          struct ixgbe_q_vector, napi);
+	struct ixgbe_q_vector *q_vector =
+	                        container_of(napi, struct ixgbe_q_vector, napi);
 	struct ixgbe_adapter *adapter = q_vector->adapter;
-	int tx_cleaned, work_done = 0;
+	int tx_clean_complete, work_done = 0;
 
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
@@ -2309,19 +2620,19 @@ static int ixgbe_poll(struct napi_struct
 	}
 #endif
 
-	tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
-	ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget);
+	tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+	ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
 
-	if (tx_cleaned)
+	if (!tx_clean_complete)
 		work_done = budget;
 
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
-		netif_rx_complete(napi);
-		if (adapter->itr_setting & 3)
+		napi_complete(napi);
+		if (adapter->itr_setting & 1)
 			ixgbe_set_itr(adapter);
 		if (!test_bit(__IXGBE_DOWN, &adapter->state))
-			ixgbe_irq_enable(adapter);
+			ixgbe_irq_enable_queues(adapter);
 	}
 	return work_done;
 }
@@ -2353,68 +2664,80 @@ static void ixgbe_reset_task(struct work
 	ixgbe_reinit_locked(adapter);
 }
 
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+#ifdef CONFIG_IXGBE_DCB
+static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
 {
-	int nrq = 1, ntq = 1;
-	int feature_mask = 0, rss_i, rss_m;
-	int dcb_i, dcb_m;
+	bool ret = false;
 
-	/* Number of supported queues */
-	switch (adapter->hw.mac.type) {
-	case ixgbe_mac_82598EB:
-		dcb_i = adapter->ring_feature[RING_F_DCB].indices;
-		dcb_m = 0;
-		rss_i = adapter->ring_feature[RING_F_RSS].indices;
-		rss_m = 0;
-		feature_mask |= IXGBE_FLAG_RSS_ENABLED;
-		feature_mask |= IXGBE_FLAG_DCB_ENABLED;
+	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+		adapter->ring_feature[RING_F_DCB].mask = 0x7 << 3;
+		adapter->num_rx_queues =
+		                      adapter->ring_feature[RING_F_DCB].indices;
+		adapter->num_tx_queues =
+		                      adapter->ring_feature[RING_F_DCB].indices;
+		ret = true;
+	} else {
+		ret = false;
+	}
 
-		switch (adapter->flags & feature_mask) {
-		case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
-			dcb_m = 0x7 << 3;
-			rss_i = min(8, rss_i);
-			rss_m = 0x7;
-			nrq = dcb_i * rss_i;
-			ntq = min(MAX_TX_QUEUES, dcb_i * rss_i);
-			break;
-		case (IXGBE_FLAG_DCB_ENABLED):
-			dcb_m = 0x7 << 3;
-			nrq = dcb_i;
-			ntq = dcb_i;
-			break;
-		case (IXGBE_FLAG_RSS_ENABLED):
-			rss_m = 0xF;
-			nrq = rss_i;
-			ntq = rss_i;
-			break;
-		case 0:
-		default:
-			dcb_i = 0;
-			dcb_m = 0;
-			rss_i = 0;
-			rss_m = 0;
-			nrq = 1;
-			ntq = 1;
-			break;
-		}
+	return ret;
+}
+#endif
 
-		/* Sanity check, we should never have zero queues */
-		nrq = (nrq ?:1);
-		ntq = (ntq ?:1);
+/**
+ * ixgbe_set_rss_queues: Allocate queues for RSS
+ * @adapter: board private structure to initialize
+ *
+ * This is our "base" multiqueue mode.  RSS (Receive Side Scaling) will try
+ * to allocate one Rx queue per CPU, and if available, one Tx queue per CPU.
+ *
+ **/
+static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
+{
+	bool ret = false;
 
-		adapter->ring_feature[RING_F_DCB].indices = dcb_i;
-		adapter->ring_feature[RING_F_DCB].mask = dcb_m;
-		adapter->ring_feature[RING_F_RSS].indices = rss_i;
-		adapter->ring_feature[RING_F_RSS].mask = rss_m;
-		break;
-	default:
-		nrq = 1;
-		ntq = 1;
-		break;
+	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+		adapter->ring_feature[RING_F_RSS].mask = 0xF;
+		adapter->num_rx_queues =
+		                      adapter->ring_feature[RING_F_RSS].indices;
+		adapter->num_tx_queues =
+		                      adapter->ring_feature[RING_F_RSS].indices;
+		ret = true;
+	} else {
+		ret = false;
 	}
 
-	adapter->num_rx_queues = nrq;
-	adapter->num_tx_queues = ntq;
+	return ret;
+}
+
+/*
+ * ixgbe_set_num_queues: Allocate queues for device, feature dependant
+ * @adapter: board private structure to initialize
+ *
+ * This is the top level queue allocation routine.  The order here is very
+ * important, starting with the "most" number of features turned on at once,
+ * and ending with the smallest set of features.  This way large combinations
+ * can be allocated if they're turned on, and smaller combinations are the
+ * fallthrough conditions.
+ *
+ **/
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+#ifdef CONFIG_IXGBE_DCB
+	if (ixgbe_set_dcb_queues(adapter))
+		goto done;
+
+#endif
+	if (ixgbe_set_rss_queues(adapter))
+		goto done;
+
+	/* fallback to base case */
+	adapter->num_rx_queues = 1;
+	adapter->num_tx_queues = 1;
+
+done:
+	/* Notify the stack of the (possibly) reduced Tx Queue count. */
+	adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
 }
 
 static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
@@ -2460,71 +2783,148 @@ static void ixgbe_acquire_msix_vectors(s
 		ixgbe_set_num_queues(adapter);
 	} else {
 		adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
-		adapter->num_msix_vectors = vectors;
+		/*
+		 * Adjust for only the vectors we'll use, which is minimum
+		 * of max_msix_q_vectors + NON_Q_VECTORS, or the number of
+		 * vectors we were allocated.
+		 */
+		adapter->num_msix_vectors = min(vectors,
+		                   adapter->max_msix_q_vectors + NON_Q_VECTORS);
 	}
 }
 
 /**
- * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS
  * @adapter: board private structure to initialize
  *
- * Once we know the feature-set enabled for the device, we'll cache
- * the register offset the descriptor ring is assigned to.
+ * Cache the descriptor ring offsets for RSS to the assigned rings.
+ *
  **/
-static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
 {
-	int feature_mask = 0, rss_i;
-	int i, txr_idx, rxr_idx;
-	int dcb_i;
+	int i;
+	bool ret = false;
 
-	/* Number of supported queues */
-	switch (adapter->hw.mac.type) {
-	case ixgbe_mac_82598EB:
-		dcb_i = adapter->ring_feature[RING_F_DCB].indices;
-		rss_i = adapter->ring_feature[RING_F_RSS].indices;
-		txr_idx = 0;
-		rxr_idx = 0;
-		feature_mask |= IXGBE_FLAG_DCB_ENABLED;
-		feature_mask |= IXGBE_FLAG_RSS_ENABLED;
-		switch (adapter->flags & feature_mask) {
-		case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
-			for (i = 0; i < dcb_i; i++) {
-				int j;
-				/* Rx first */
-				for (j = 0; j < adapter->num_rx_queues; j++) {
-					adapter->rx_ring[rxr_idx].reg_idx =
-						i << 3 | j;
-					rxr_idx++;
-				}
-				/* Tx now */
-				for (j = 0; j < adapter->num_tx_queues; j++) {
-					adapter->tx_ring[txr_idx].reg_idx =
-						i << 2 | (j >> 1);
-					if (j & 1)
-						txr_idx++;
-				}
-			}
-		case (IXGBE_FLAG_DCB_ENABLED):
+	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+		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;
+		ret = true;
+	} else {
+		ret = false;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_IXGBE_DCB
+/**
+ * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for DCB to the assigned rings.
+ *
+ **/
+static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
+{
+	int i;
+	bool ret = false;
+	int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+
+	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+		if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
 			/* the number of queues is assumed to be symmetric */
 			for (i = 0; i < dcb_i; i++) {
 				adapter->rx_ring[i].reg_idx = i << 3;
 				adapter->tx_ring[i].reg_idx = i << 2;
 			}
-			break;
-		case (IXGBE_FLAG_RSS_ENABLED):
-			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;
-			break;
-		case 0:
-		default:
-			break;
+			ret = true;
+		} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+			if (dcb_i == 8) {
+				/*
+				 * Tx TC0 starts at: descriptor queue 0
+				 * Tx TC1 starts at: descriptor queue 32
+				 * Tx TC2 starts at: descriptor queue 64
+				 * Tx TC3 starts at: descriptor queue 80
+				 * Tx TC4 starts at: descriptor queue 96
+				 * Tx TC5 starts at: descriptor queue 104
+				 * Tx TC6 starts at: descriptor queue 112
+				 * Tx TC7 starts at: descriptor queue 120
+				 *
+				 * Rx TC0-TC7 are offset by 16 queues each
+				 */
+				for (i = 0; i < 3; i++) {
+					adapter->tx_ring[i].reg_idx = i << 5;
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+				for ( ; i < 5; i++) {
+					adapter->tx_ring[i].reg_idx =
+					                         ((i + 2) << 4);
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+				for ( ; i < dcb_i; i++) {
+					adapter->tx_ring[i].reg_idx =
+					                         ((i + 8) << 3);
+					adapter->rx_ring[i].reg_idx = i << 4;
+				}
+
+				ret = true;
+			} else if (dcb_i == 4) {
+				/*
+				 * Tx TC0 starts at: descriptor queue 0
+				 * Tx TC1 starts at: descriptor queue 64
+				 * Tx TC2 starts at: descriptor queue 96
+				 * Tx TC3 starts at: descriptor queue 112
+				 *
+				 * Rx TC0-TC3 are offset by 32 queues each
+				 */
+				adapter->tx_ring[0].reg_idx = 0;
+				adapter->tx_ring[1].reg_idx = 64;
+				adapter->tx_ring[2].reg_idx = 96;
+				adapter->tx_ring[3].reg_idx = 112;
+				for (i = 0 ; i < dcb_i; i++)
+					adapter->rx_ring[i].reg_idx = i << 5;
+
+				ret = true;
+			} else {
+				ret = false;
+			}
+		} else {
+			ret = false;
 		}
-		break;
-	default:
-		break;
+	} else {
+		ret = false;
 	}
+
+	return ret;
+}
+#endif
+
+/**
+ * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * @adapter: board private structure to initialize
+ *
+ * Once we know the feature-set enabled for the device, we'll cache
+ * the register offset the descriptor ring is assigned to.
+ *
+ * Note, the order the various feature calls is important.  It must start with
+ * the "most" features enabled at the same time, then trickle down to the
+ * least amount of features turned on at once.
+ **/
+static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+{
+	/* start with default case */
+	adapter->rx_ring[0].reg_idx = 0;
+	adapter->tx_ring[0].reg_idx = 0;
+
+#ifdef CONFIG_IXGBE_DCB
+	if (ixgbe_cache_ring_dcb(adapter))
+		return;
+
+#endif
+	if (ixgbe_cache_ring_rss(adapter))
+		return;
 }
 
 /**
@@ -2532,7 +2932,8 @@ static void ixgbe_cache_ring_register(st
  * @adapter: board private structure to initialize
  *
  * We allocate one ring per queue at run-time since we don't know the
- * number of queues at compile-time.
+ * number of queues at compile-time.  The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
  **/
 static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
 {
@@ -2577,6 +2978,7 @@ err_tx_ring_allocation:
  **/
 static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_hw *hw = &adapter->hw;
 	int err = 0;
 	int vector, v_budget;
 
@@ -2591,12 +2993,12 @@ static int ixgbe_set_interrupt_capabilit
 
 	/*
 	 * At the same time, hardware can only support a maximum of
-	 * MAX_MSIX_COUNT vectors.  With features such as RSS and VMDq,
-	 * we can easily reach upwards of 64 Rx descriptor queues and
-	 * 32 Tx queues.  Thus, we cap it off in those rare cases where
-	 * the cpu count also exceeds our vector limit.
+	 * hw.mac->max_msix_vectors vectors.  With features
+	 * such as RSS and VMDq, we can easily surpass the number of Rx and Tx
+	 * descriptor queues supported by our device.  Thus, we cap it off in
+	 * those rare cases where the cpu count also exceeds our vector limit.
 	 */
-	v_budget = min(v_budget, MAX_MSIX_COUNT);
+	v_budget = min(v_budget, (int)hw->mac.max_msix_vectors);
 
 	/* A failure in MSI-X entry allocation isn't fatal, but it does
 	 * mean we disable MSI-X capabilities of the adapter. */
@@ -2638,9 +3040,6 @@ try_msi:
 	}
 
 out:
-	/* Notify the stack of the (possibly) reduced Tx Queue count. */
-	adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
-
 	return err;
 }
 
@@ -2711,7 +3110,8 @@ static void ixgbe_sfp_timer(unsigned lon
 {
 	struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
 
-	/* Do the sfp_timer outside of interrupt context due to the
+	/*
+	 * Do the sfp_timer outside of interrupt context due to the
 	 * delays that sfp+ detection requires
 	 */
 	schedule_work(&adapter->sfp_task);
@@ -2785,6 +3185,10 @@ static int __devinit ixgbe_sw_init(struc
 	adapter->ring_feature[RING_F_RSS].indices = rss;
 	adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
 	adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
+	else if (hw->mac.type == ixgbe_mac_82599EB)
+		adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
 
 #ifdef CONFIG_IXGBE_DCB
 	/* Configure DCB traffic classes */
@@ -2805,20 +3209,15 @@ static int __devinit ixgbe_sw_init(struc
 	                   adapter->ring_feature[RING_F_DCB].indices);
 
 #endif
-	if (hw->mac.ops.get_media_type &&
-	    (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper))
-		adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
 
 	/* default flow control settings */
-	hw->fc.original_type = ixgbe_fc_none;
-	hw->fc.type = ixgbe_fc_none;
+	hw->fc.requested_mode = ixgbe_fc_full;
+	hw->fc.current_mode = ixgbe_fc_full;	/* init for ethtool output */
 	hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
 	hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
 	hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
 	hw->fc.send_xon = true;
-
-	/* select 10G link by default */
-	hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
+	hw->fc.disable_fc_autoneg = false;
 
 	/* enable itr by default in dynamic mode */
 	adapter->itr_setting = 1;
@@ -2866,8 +3265,7 @@ int ixgbe_setup_tx_resources(struct ixgb
 	memset(tx_ring->tx_buffer_info, 0, size);
 
 	/* round up to nearest 4K */
-	tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc) +
-	                sizeof(u32);
+	tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
 	tx_ring->size = ALIGN(tx_ring->size, 4096);
 
 	tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -2926,12 +3324,6 @@ int ixgbe_setup_rx_resources(struct ixgb
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
-	size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
-	rx_ring->lro_mgr.lro_arr = vmalloc(size);
-	if (!rx_ring->lro_mgr.lro_arr)
-		return -ENOMEM;
-	memset(rx_ring->lro_mgr.lro_arr, 0, size);
-
 	size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
 	rx_ring->rx_buffer_info = vmalloc(size);
 	if (!rx_ring->rx_buffer_info) {
@@ -2960,8 +3352,6 @@ int ixgbe_setup_rx_resources(struct ixgb
 	return 0;
 
 alloc_failed:
-	vfree(rx_ring->lro_mgr.lro_arr);
-	rx_ring->lro_mgr.lro_arr = NULL;
 	return -ENOMEM;
 }
 
@@ -3024,7 +3414,8 @@ static void ixgbe_free_all_tx_resources(
 	int i;
 
 	for (i = 0; i < adapter->num_tx_queues; i++)
-		ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+		if (adapter->tx_ring[i].desc)
+			ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
 }
 
 /**
@@ -3039,9 +3430,6 @@ void ixgbe_free_rx_resources(struct ixgb
 {
 	struct pci_dev *pdev = adapter->pdev;
 
-	vfree(rx_ring->lro_mgr.lro_arr);
-	rx_ring->lro_mgr.lro_arr = NULL;
-
 	ixgbe_clean_rx_ring(adapter, rx_ring);
 
 	vfree(rx_ring->rx_buffer_info);
@@ -3063,7 +3451,8 @@ static void ixgbe_free_all_rx_resources(
 	int i;
 
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+		if (adapter->rx_ring[i].desc)
+			ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
 }
 
 /**
@@ -3126,6 +3515,8 @@ static int ixgbe_open(struct net_device
 
 	ixgbe_configure(adapter);
 
+	ixgbe_napi_add_all(adapter);
+
 	err = ixgbe_request_irq(adapter);
 	if (err)
 		goto err_req_irq;
@@ -3142,10 +3533,10 @@ err_up:
 	ixgbe_release_hw_control(adapter);
 	ixgbe_free_irq(adapter);
 err_req_irq:
-	ixgbe_free_all_rx_resources(adapter);
 err_setup_rx:
-	ixgbe_free_all_tx_resources(adapter);
+	ixgbe_free_all_rx_resources(adapter);
 err_setup_tx:
+	ixgbe_free_all_tx_resources(adapter);
 	ixgbe_reset(adapter);
 
 	return err;
@@ -3180,6 +3571,7 @@ static int ixgbe_close(struct net_device
 /**
  * ixgbe_napi_add_all - prep napi structs for use
  * @adapter: private struct
+ *
  * helper function to napi_add each possible q_vector->napi
  */
 void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
@@ -3252,9 +3644,10 @@ static int ixgbe_resume(struct pci_dev *
 		return err;
 	}
 
-	ixgbe_napi_add_all(adapter);
 	ixgbe_reset(adapter);
 
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
+
 	if (netif_running(netdev)) {
 		err = ixgbe_open(adapter->netdev);
 		if (err)
@@ -3265,12 +3658,15 @@ static int ixgbe_resume(struct pci_dev *
 
 	return 0;
 }
-
 #endif /* CONFIG_PM */
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+
+static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 ctrl, fctrl;
+	u32 wufc = adapter->wol;
 #ifdef CONFIG_PM
 	int retval = 0;
 #endif
@@ -3293,23 +3689,76 @@ static int ixgbe_suspend(struct pci_dev
 	retval = pci_save_state(pdev);
 	if (retval)
 		return retval;
+
 #endif
+	if (wufc) {
+		ixgbe_set_rx_mode(netdev);
 
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
+		/* turn on all-multi mode if wake on multicast is enabled */
+		if (wufc & IXGBE_WUFC_MC) {
+			fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+			fctrl |= IXGBE_FCTRL_MPE;
+			IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+		}
+
+		ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+		ctrl |= IXGBE_CTRL_GIO_DIS;
+		IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+
+		IXGBE_WRITE_REG(hw, IXGBE_WUFC, wufc);
+	} else {
+		IXGBE_WRITE_REG(hw, IXGBE_WUC, 0);
+		IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
+	}
+
+	if (wufc && hw->mac.type == ixgbe_mac_82599EB) {
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+	} else {
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+		pci_enable_wake(pdev, PCI_D3cold, 0);
+	}
+
+	*enable_wake = !!wufc;
 
 	ixgbe_release_hw_control(adapter);
 
 	pci_disable_device(pdev);
 
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+	bool wake;
+
+	retval = __ixgbe_shutdown(pdev, &wake);
+	if (retval)
+		return retval;
+
+	if (wake) {
+		pci_prepare_to_sleep(pdev);
+	} else {
+		pci_wake_from_d3(pdev, false);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 
 	return 0;
 }
+#endif /* CONFIG_PM */
 
 static void ixgbe_shutdown(struct pci_dev *pdev)
 {
-	ixgbe_suspend(pdev, PMSG_SUSPEND);
+	bool wake;
+
+	__ixgbe_shutdown(pdev, &wake);
+
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, wake);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
 }
 
 /**
@@ -3322,6 +3771,12 @@ void ixgbe_update_stats(struct ixgbe_ada
 	u64 total_mpc = 0;
 	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
 
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		for (i = 0; i < 16; i++)
+			adapter->hw_rx_no_dma_resources +=
+			                     IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+	}
+
 	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 */
@@ -3329,32 +3784,55 @@ void ixgbe_update_stats(struct ixgbe_ada
 		missed_rx += mpc;
 		adapter->stats.mpc[i] += mpc;
 		total_mpc += adapter->stats.mpc[i];
-		adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+		if (hw->mac.type == ixgbe_mac_82598EB)
+			adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
 		adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
 		adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
 		adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
 		adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
-		adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
-		                                            IXGBE_PXONRXC(i));
+		if (hw->mac.type == ixgbe_mac_82599EB) {
+			adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+			                                    IXGBE_PXONRXCNT(i));
+			adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+			                                   IXGBE_PXOFFRXCNT(i));
+			adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+		} else {
+			adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+			                                      IXGBE_PXONRXC(i));
+			adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+			                                     IXGBE_PXOFFRXC(i));
+		}
 		adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw,
 		                                            IXGBE_PXONTXC(i));
-		adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
-		                                            IXGBE_PXOFFRXC(i));
 		adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw,
-		                                            IXGBE_PXOFFTXC(i));
+		                                             IXGBE_PXOFFTXC(i));
 	}
 	adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
 	/* work around hardware counting issue */
 	adapter->stats.gprc -= missed_rx;
 
 	/* 82598 hardware only has a 32 bit counter in the high register */
-	adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
-	adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
-	adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+	if (hw->mac.type == ixgbe_mac_82599EB) {
+		adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
+		IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+		adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
+		IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+		adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
+		IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+		adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+		adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+	} else {
+		adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+		adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+		adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+		adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+		adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+	}
 	bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
 	adapter->stats.bprc += bprc;
 	adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
-	adapter->stats.mprc -= bprc;
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		adapter->stats.mprc -= bprc;
 	adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
 	adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
 	adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
@@ -3363,8 +3841,6 @@ void ixgbe_update_stats(struct ixgbe_ada
 	adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
 	adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
 	adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
-	adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
-	adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
 	lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
 	adapter->stats.lxontxc += lxon;
 	lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
@@ -3416,17 +3892,54 @@ static void ixgbe_watchdog(unsigned long
 	/* Do the watchdog outside of interrupt context due to the lovely
 	 * delays that some of the newer hardware requires */
 	if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+		u64 eics = 0;
+		int i;
+
+		for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
+			eics |= (1 << i);
+
 		/* Cause software interrupt to ensure rx rings are cleaned */
-		if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-			u32 eics =
-			 (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
-			IXGBE_WRITE_REG(hw, IXGBE_EICS, eics);
-		} else {
-			/* For legacy and MSI interrupts don't set any bits that
-			 * are enabled for EIAM, because this operation would
-			 * set *both* EIMS and EICS for any bit in EIAM */
-			IXGBE_WRITE_REG(hw, IXGBE_EICS,
-                                    (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+		switch (hw->mac.type) {
+		case ixgbe_mac_82598EB:
+			if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+				IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics);
+			} else {
+				/*
+				 * for legacy and MSI interrupts don't set any
+				 * bits that are enabled for EIAM, because this
+				 * operation would set *both* EIMS and EICS for
+				 * any bit in EIAM
+				 */
+				IXGBE_WRITE_REG(hw, IXGBE_EICS,
+				     (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+			}
+			break;
+		case ixgbe_mac_82599EB:
+			if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+				/*
+				 * EICS(0..15) first 0-15 q vectors
+				 * EICS[1] (16..31) q vectors 16-31
+				 * EICS[2] (0..31) q vectors 32-63
+				 */
+				IXGBE_WRITE_REG(hw, IXGBE_EICS,
+				                (u32)(eics & 0xFFFF));
+				IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
+				                (u32)(eics & 0xFFFF0000));
+				IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
+				                (u32)(eics >> 32));
+			} else {
+				/*
+				 * for legacy and MSI interrupts don't set any
+				 * bits that are enabled for EIAM, because this
+				 * operation would set *both* EIMS and EICS for
+				 * any bit in EIAM
+				 */
+				IXGBE_WRITE_REG(hw, IXGBE_EICS,
+				     (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+			}
+			break;
+		default:
+			break;
 		}
 		/* Reset the timer */
 		mod_timer(&adapter->watchdog_timer,
@@ -3437,6 +3950,55 @@ static void ixgbe_watchdog(unsigned long
 }
 
 /**
+ * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+{
+	struct ixgbe_adapter *adapter = container_of(work,
+	                                             struct ixgbe_adapter,
+	                                             multispeed_fiber_task);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 autoneg;
+
+	adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
+	if (hw->mac.ops.get_link_capabilities)
+		hw->mac.ops.get_link_capabilities(hw, &autoneg,
+		                                  &hw->mac.autoneg);
+	if (hw->mac.ops.setup_link_speed)
+		hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
+	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+	adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+}
+
+/**
+ * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_sfp_config_module_task(struct work_struct *work)
+{
+	struct ixgbe_adapter *adapter = container_of(work,
+	                                             struct ixgbe_adapter,
+	                                             sfp_config_module_task);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 err;
+
+	adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+	err = hw->phy.ops.identify_sfp(hw);
+	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+		DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+		ixgbe_down(adapter);
+		return;
+	}
+	hw->mac.ops.setup_sfp(hw);
+
+	if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
+		/* This will also work for DA Twinax connections */
+		schedule_work(&adapter->multispeed_fiber_task);
+	adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+}
+
+/**
  * ixgbe_watchdog_task - worker thread to bring link up
  * @work: pointer to work_struct containing our data
  **/
@@ -3466,10 +4028,20 @@ static void ixgbe_watchdog_task(struct w
 
 	if (link_up) {
 		if (!netif_carrier_ok(netdev)) {
-			u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-			u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-#define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
-#define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
+			bool flow_rx, flow_tx;
+
+			if (hw->mac.type == ixgbe_mac_82599EB) {
+				u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+				u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+				flow_rx = (mflcn & IXGBE_MFLCN_RFCE);
+				flow_tx = (fccfg & IXGBE_FCCFG_TFCE_802_3X);
+			} else {
+				u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+				u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+				flow_rx = (frctl & IXGBE_FCTRL_RFCE);
+				flow_tx = (rmcs & IXGBE_RMCS_TFCE_802_3X);
+			}
+
 			printk(KERN_INFO "ixgbe: %s NIC Link is Up %s, "
 			       "Flow Control: %s\n",
 			       netdev->name,
@@ -3477,9 +4049,9 @@ static void ixgbe_watchdog_task(struct w
 			        "10 Gbps" :
 			        (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
 			         "1 Gbps" : "unknown speed")),
-			       ((FLOW_RX && FLOW_TX) ? "RX/TX" :
-			        (FLOW_RX ? "RX" :
-			        (FLOW_TX ? "TX" : "None"))));
+			       ((flow_rx && flow_tx) ? "RX/TX" :
+			        (flow_rx ? "RX" :
+			        (flow_tx ? "TX" : "None"))));
 
 			netif_carrier_on(netdev);
 		} else {
@@ -3619,13 +4191,13 @@ static bool ixgbe_tx_csum(struct ixgbe_a
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
 			switch (skb->protocol) {
-			case __constant_htons(ETH_P_IP):
+			case cpu_to_be16(ETH_P_IP):
 				type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
 				if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 					type_tucmd_mlhl |=
 					        IXGBE_ADVTXD_TUCMD_L4T_TCP;
 				break;
-			case __constant_htons(ETH_P_IPV6):
+			case cpu_to_be16(ETH_P_IPV6):
 				/* XXX what about other V6 headers?? */
 				if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
 					type_tucmd_mlhl |=
@@ -3665,32 +4237,39 @@ static int ixgbe_tx_map(struct ixgbe_ada
                         struct sk_buff *skb, unsigned int first)
 {
 	struct ixgbe_tx_buffer *tx_buffer_info;
-	unsigned int len = skb->len;
+	unsigned int len = skb_headlen(skb);
 	unsigned int offset = 0, size, count = 0, i;
 	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
 	unsigned int f;
-
-	len -= skb->data_len;
+	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) {
 		tx_buffer_info = &tx_ring->tx_buffer_info[i];
 		size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 		tx_buffer_info->length = size;
-		tx_buffer_info->dma = pci_map_single(adapter->pdev,
-		                                     skb->data + offset,
-		                                     size, PCI_DMA_TODEVICE);
+		tx_buffer_info->dma = map[0] + offset;
 		tx_buffer_info->time_stamp = jiffies;
 		tx_buffer_info->next_to_watch = i;
 
 		len -= size;
 		offset += size;
 		count++;
-		i++;
-		if (i == tx_ring->count)
-			i = 0;
+
+		if (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
 	}
 
 	for (f = 0; f < nr_frags; f++) {
@@ -3698,33 +4277,27 @@ static int ixgbe_tx_map(struct ixgbe_ada
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		offset = 0;
 
 		while (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+
 			tx_buffer_info = &tx_ring->tx_buffer_info[i];
 			size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 			tx_buffer_info->length = size;
-			tx_buffer_info->dma = pci_map_page(adapter->pdev,
-			                                   frag->page,
-			                                   offset,
-			                                   size,
-			                                   PCI_DMA_TODEVICE);
+			tx_buffer_info->dma = map[f + 1] + offset;
 			tx_buffer_info->time_stamp = jiffies;
 			tx_buffer_info->next_to_watch = i;
 
 			len -= size;
 			offset += size;
 			count++;
-			i++;
-			if (i == tx_ring->count)
-				i = 0;
 		}
 	}
-	if (i == 0)
-		i = tx_ring->count - 1;
-	else
-		i = i - 1;
+
 	tx_ring->tx_buffer_info[i].skb = skb;
 	tx_ring->tx_buffer_info[first].next_to_watch = i;
 
@@ -3823,6 +4396,16 @@ static int ixgbe_maybe_stop_tx(struct ne
 	return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
 }
 
+static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+		return 0;  /* All traffic should default to class 0 */
+
+	return skb_tx_hash(dev, skb);
+}
+
 static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3834,7 +4417,7 @@ static int ixgbe_xmit_frame(struct sk_bu
 	int count = 0;
 	unsigned int f;
 
-	r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
+	r_idx = skb->queue_mapping;
 	tx_ring = &adapter->tx_ring[r_idx];
 
 	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
@@ -3880,13 +4463,19 @@ static int ixgbe_xmit_frame(struct sk_bu
 	         (skb->ip_summed == CHECKSUM_PARTIAL))
 		tx_flags |= IXGBE_TX_FLAGS_CSUM;
 
-	ixgbe_tx_queue(adapter, tx_ring, tx_flags,
-	               ixgbe_tx_map(adapter, tx_ring, skb, first),
-	               skb->len, hdr_len);
+	count = ixgbe_tx_map(adapter, tx_ring, skb, first);
 
-	netdev->trans_start = jiffies;
+	if (count) {
+		ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
+		               hdr_len);
+		netdev->trans_start = jiffies;
+		ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
 
-	ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->tx_buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
 
 	return NETDEV_TX_OK;
 }
@@ -3948,30 +4537,11 @@ static void ixgbe_netpoll(struct net_dev
 }
 #endif
 
-/**
- * ixgbe_link_config - set up initial link with default speed and duplex
- * @hw: pointer to private hardware struct
- *
- * Returns 0 on success, negative on failure
- **/
-static int ixgbe_link_config(struct ixgbe_hw *hw)
-{
-	u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
-
-	/* must always autoneg for both 1G and 10G link */
-	hw->mac.autoneg = true;
-
-	if ((hw->mac.type == ixgbe_mac_82598EB) &&
-	    (hw->phy.media_type == ixgbe_media_type_copper))
-		autoneg = IXGBE_LINK_SPEED_82598_AUTONEG;
-
-	return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
-}
-
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open 		= ixgbe_open,
 	.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,
@@ -4007,20 +4577,19 @@ static int __devinit ixgbe_probe(struct
 	const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
 	static int cards_found;
 	int i, err, pci_using_dac;
-	u16 link_status, link_speed, link_width;
 	u32 part_num, eec;
 
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
-	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
+	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
-			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 			if (err) {
 				dev_err(&pdev->dev, "No usable DMA "
 				        "configuration, aborting\n");
@@ -4106,6 +4675,13 @@ static int __devinit ixgbe_probe(struct
 
 	INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
 
+	/* multispeed fiber has its own tasklet, called from GPI SDP1 context */
+	INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
+
+	/* a new SFP+ module arrival, called from GPI SDP2 context */
+	INIT_WORK(&adapter->sfp_config_module_task,
+	          ixgbe_sfp_config_module_task);
+
 	err = ii->get_invariants(hw);
 	if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
 		/* start a kernel thread to watch for a module to arrive */
@@ -4142,7 +4718,7 @@ static int __devinit ixgbe_probe(struct
 	netdev->features |= NETIF_F_IPV6_CSUM;
 	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_TSO6;
-	netdev->features |= NETIF_F_LRO;
+	netdev->features |= NETIF_F_GRO;
 
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
@@ -4186,26 +4762,38 @@ static int __devinit ixgbe_probe(struct
 	if (err)
 		goto err_sw_init;
 
+	switch (pdev->device) {
+	case IXGBE_DEV_ID_82599_KX4:
+		adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
+		                IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+		break;
+	default:
+		adapter->wol = 0;
+		break;
+	}
+	device_init_wakeup(&adapter->pdev->dev, true);
+	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
 	/* print bus type/speed/width info */
-	pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status);
-	link_speed = link_status & IXGBE_PCI_LINK_SPEED;
-	link_width = link_status & IXGBE_PCI_LINK_WIDTH;
 	dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
-	        ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
-	         (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
-	         "Unknown"),
-	        ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
-	         (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
-	         (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
-	         (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+	        ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
+	         (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
+	        ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
+	         (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
+	         (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
 	         "Unknown"),
 	        netdev->dev_addr);
 	ixgbe_read_pba_num_generic(hw, &part_num);
-	dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
-	         hw->mac.type, hw->phy.type,
-	         (part_num >> 8), (part_num & 0xff));
+	if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
+		dev_info(&pdev->dev, "MAC: %d, PHY: %d, SFP+: %d, PBA No: %06x-%03x\n",
+		         hw->mac.type, hw->phy.type, hw->phy.sfp_type,
+		         (part_num >> 8), (part_num & 0xff));
+	else
+		dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
+		         hw->mac.type, hw->phy.type,
+		         (part_num >> 8), (part_num & 0xff));
 
-	if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
+	if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
 		dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
 		         "this card is not sufficient for optimal "
 		         "performance.\n");
@@ -4213,16 +4801,12 @@ static int __devinit ixgbe_probe(struct
 		         "PCI-Express slot is required.\n");
 	}
 
+	/* save off EEPROM version number */
+	hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
+
 	/* reset the hardware with the new settings */
 	hw->mac.ops.start_hw(hw);
 
-	/* link_config depends on start_hw being called at least once */
-	err = ixgbe_link_config(hw);
-	if (err) {
-		dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
-		goto err_register;
-	}
-
 	netif_carrier_off(netdev);
 
 	strcpy(netdev->name, "eth%d");
@@ -4253,6 +4837,8 @@ err_eeprom:
 	clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
 	del_timer_sync(&adapter->sfp_timer);
 	cancel_work_sync(&adapter->sfp_task);
+	cancel_work_sync(&adapter->multispeed_fiber_task);
+	cancel_work_sync(&adapter->sfp_config_module_task);
 	iounmap(hw->hw_addr);
 err_ioremap:
 	free_netdev(netdev);
@@ -4289,6 +4875,8 @@ static void __devexit ixgbe_remove(struc
 	del_timer_sync(&adapter->sfp_timer);
 	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->sfp_task);
+	cancel_work_sync(&adapter->multispeed_fiber_task);
+	cancel_work_sync(&adapter->sfp_config_module_task);
 	flush_scheduled_work();
 
 #ifdef CONFIG_IXGBE_DCA
@@ -4372,7 +4960,7 @@ static pci_ers_result_t ixgbe_io_slot_re
 		pci_enable_wake(pdev, PCI_D3cold, 0);
 
 		ixgbe_reset(adapter);
-
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
 		result = PCI_ERS_RESULT_RECOVERED;
 	}
 
@@ -4476,8 +5064,20 @@ static int ixgbe_notify_dca(struct notif
 
 	return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
 }
+
 #endif /* CONFIG_IXGBE_DCA */
+#ifdef DEBUG
+/**
+ * ixgbe_get_hw_dev_name - return device name string
+ * used by hardware layer to print debugging information
+ **/
+char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw)
+{
+	struct ixgbe_adapter *adapter = hw->back;
+	return adapter->netdev->name;
+}
 
+#endif
 module_exit(ixgbe_exit_module);
 
 /* ixgbe_main.c */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_phy.c linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -32,6 +32,18 @@
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
 
+static void ixgbe_i2c_start(struct ixgbe_hw *hw);
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
+static bool ixgbe_get_i2c_data(u32 *i2cctl);
+static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
 static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
 static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
 static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
@@ -543,8 +555,9 @@ s32 ixgbe_identify_sfp_module_generic(st
 	u8 identifier = 0;
 	u8 comp_codes_1g = 0;
 	u8 comp_codes_10g = 0;
-	u8 oui_bytes[4] = {0, 0, 0, 0};
+	u8 oui_bytes[3] = {0, 0, 0};
 	u8 transmission_media = 0;
+	u16 enforce_sfp = 0;
 
 	status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
 	                                     &identifier);
@@ -564,18 +577,48 @@ s32 ixgbe_identify_sfp_module_generic(st
 
 		/* ID Module
 		 * =========
-		 * 0	SFP_DA_CU
-		 * 1	SFP_SR
-		 * 2	SFP_LR
+		 * 0    SFP_DA_CU
+		 * 1    SFP_SR
+		 * 2    SFP_LR
+		 * 3    SFP_DA_CORE0 - 82599-specific
+		 * 4    SFP_DA_CORE1 - 82599-specific
+		 * 5    SFP_SR/LR_CORE0 - 82599-specific
+		 * 6    SFP_SR/LR_CORE1 - 82599-specific
 		 */
-		if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
-		else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_sr;
-		else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
-			hw->phy.sfp_type = ixgbe_sfp_type_lr;
-		else
-			hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		if (hw->mac.type == ixgbe_mac_82598EB) {
+			if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_sr;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+				hw->phy.sfp_type = ixgbe_sfp_type_lr;
+			else
+				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		} else if (hw->mac.type == ixgbe_mac_82599EB) {
+			if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					             ixgbe_sfp_type_da_cu_core0;
+				else
+					hw->phy.sfp_type =
+					             ixgbe_sfp_type_da_cu_core1;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					              ixgbe_sfp_type_srlr_core0;
+				else
+					hw->phy.sfp_type =
+					              ixgbe_sfp_type_srlr_core1;
+			else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+				if (hw->bus.lan_id == 0)
+					hw->phy.sfp_type =
+					              ixgbe_sfp_type_srlr_core0;
+				else
+					hw->phy.sfp_type =
+					              ixgbe_sfp_type_srlr_core1;
+			else
+				hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+		}
 
 		/* Determine PHY vendor */
 		if (hw->phy.type == ixgbe_phy_unknown) {
@@ -607,6 +650,9 @@ s32 ixgbe_identify_sfp_module_generic(st
 			case IXGBE_SFF_VENDOR_OUI_AVAGO:
 				hw->phy.type = ixgbe_phy_sfp_avago;
 				break;
+			case IXGBE_SFF_VENDOR_OUI_INTEL:
+				hw->phy.type = ixgbe_phy_sfp_intel;
+				break;
 			default:
 				if (transmission_media &
 				    IXGBE_SFF_TWIN_AX_CAPABLE)
@@ -616,7 +662,28 @@ s32 ixgbe_identify_sfp_module_generic(st
 				break;
 			}
 		}
-		status = 0;
+		if (hw->mac.type == ixgbe_mac_82598EB ||
+		    (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
+		     hw->phy.sfp_type != ixgbe_sfp_type_lr &&
+		     hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
+		     hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+			status = 0;
+			goto out;
+		}
+
+		hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
+		                    &enforce_sfp);
+		if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+			/* Make sure we're a supported PHY type */
+			if (hw->phy.type == ixgbe_phy_sfp_intel) {
+				status = 0;
+			} else {
+				hw_dbg(hw, "SFP+ module not supported\n");
+				status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+			}
+		} else {
+			status = 0;
+		}
 	}
 
 out:
@@ -651,7 +718,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(
 	hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
 
 	if ((!*list_offset) || (*list_offset == 0xFFFF))
-		return IXGBE_ERR_PHY;
+		return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
 
 	/* Shift offset to first ID word */
 	(*list_offset)++;
@@ -688,6 +755,501 @@ s32 ixgbe_get_sfp_init_sequence_offsets(
 }
 
 /**
+ *  ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: EEPROM byte offset to read
+ *  @eeprom_data: value read
+ *
+ *  Performs byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                  u8 *eeprom_data)
+{
+	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
+	                                 IXGBE_I2C_EEPROM_DEV_ADDR,
+	                                 eeprom_data);
+}
+
+/**
+ *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: EEPROM byte offset to write
+ *  @eeprom_data: value to write
+ *
+ *  Performs byte write operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                   u8 eeprom_data)
+{
+	return hw->phy.ops.write_i2c_byte(hw, byte_offset,
+	                                  IXGBE_I2C_EEPROM_DEV_ADDR,
+	                                  eeprom_data);
+}
+
+/**
+ *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to read
+ *  @data: value read
+ *
+ *  Performs byte read operation to SFP module's EEPROM over I2C interface at
+ *  a specified deivce address.
+ **/
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                u8 dev_addr, u8 *data)
+{
+	s32 status = 0;
+	u32 max_retry = 1;
+	u32 retry = 0;
+	bool nack = 1;
+
+	do {
+		ixgbe_i2c_start(hw);
+
+		/* Device Address and write indication */
+		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		ixgbe_i2c_start(hw);
+
+		/* Device Address and read indication */
+		status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_clock_in_i2c_byte(hw, data);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_bit(hw, nack);
+		if (status != 0)
+			goto fail;
+
+		ixgbe_i2c_stop(hw);
+		break;
+
+fail:
+		ixgbe_i2c_bus_clear(hw);
+		retry++;
+		if (retry < max_retry)
+			hw_dbg(hw, "I2C byte read error - Retrying.\n");
+		else
+			hw_dbg(hw, "I2C byte read error.\n");
+
+	} while (retry < max_retry);
+
+	return status;
+}
+
+/**
+ *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to write
+ *  @data: value to write
+ *
+ *  Performs byte write operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                 u8 dev_addr, u8 data)
+{
+	s32 status = 0;
+	u32 max_retry = 1;
+	u32 retry = 0;
+
+	do {
+		ixgbe_i2c_start(hw);
+
+		status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_clock_out_i2c_byte(hw, data);
+		if (status != 0)
+			goto fail;
+
+		status = ixgbe_get_i2c_ack(hw);
+		if (status != 0)
+			goto fail;
+
+		ixgbe_i2c_stop(hw);
+		break;
+
+fail:
+		ixgbe_i2c_bus_clear(hw);
+		retry++;
+		if (retry < max_retry)
+			hw_dbg(hw, "I2C byte write error - Retrying.\n");
+		else
+			hw_dbg(hw, "I2C byte write error.\n");
+	} while (retry < max_retry);
+
+	return status;
+}
+
+/**
+ *  ixgbe_i2c_start - Sets I2C start condition
+ *  @hw: pointer to hardware structure
+ *
+ *  Sets I2C start condition (High -> Low on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_start(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	/* Start condition must begin with data and clock high */
+	ixgbe_set_i2c_data(hw, &i2cctl, 1);
+	ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Setup time for start condition (4.7us) */
+	udelay(IXGBE_I2C_T_SU_STA);
+
+	ixgbe_set_i2c_data(hw, &i2cctl, 0);
+
+	/* Hold time for start condition (4us) */
+	udelay(IXGBE_I2C_T_HD_STA);
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	udelay(IXGBE_I2C_T_LOW);
+
+}
+
+/**
+ *  ixgbe_i2c_stop - Sets I2C stop condition
+ *  @hw: pointer to hardware structure
+ *
+ *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	/* Stop condition must begin with data low and clock high */
+	ixgbe_set_i2c_data(hw, &i2cctl, 0);
+	ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Setup time for stop condition (4us) */
+	udelay(IXGBE_I2C_T_SU_STO);
+
+	ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+	/* bus free time between stop and start (4.7us)*/
+	udelay(IXGBE_I2C_T_BUF);
+}
+
+/**
+ *  ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
+ *  @hw: pointer to hardware structure
+ *  @data: data byte to clock in
+ *
+ *  Clocks in one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
+{
+	s32 status = 0;
+	s32 i;
+	bool bit = 0;
+
+	for (i = 7; i >= 0; i--) {
+		status = ixgbe_clock_in_i2c_bit(hw, &bit);
+		*data |= bit << i;
+
+		if (status != 0)
+			break;
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
+ *  @hw: pointer to hardware structure
+ *  @data: data byte clocked out
+ *
+ *  Clocks out one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
+{
+	s32 status = 0;
+	s32 i;
+	u32 i2cctl;
+	bool bit = 0;
+
+	for (i = 7; i >= 0; i--) {
+		bit = (data >> i) & 0x1;
+		status = ixgbe_clock_out_i2c_bit(hw, bit);
+
+		if (status != 0)
+			break;
+	}
+
+	/* Release SDA line (set high) */
+	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	i2cctl |= IXGBE_I2C_DATA_OUT;
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
+
+	return status;
+}
+
+/**
+ *  ixgbe_get_i2c_ack - Polls for I2C ACK
+ *  @hw: pointer to hardware structure
+ *
+ *  Clocks in/out one bit via I2C data/clock
+ **/
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
+{
+	s32 status;
+	u32 i = 0;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	u32 timeout = 10;
+	bool ack = 1;
+
+	status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	if (status != 0)
+		goto out;
+
+	/* Minimum high period of clock is 4us */
+	udelay(IXGBE_I2C_T_HIGH);
+
+	/* Poll for ACK.  Note that ACK in I2C spec is
+	 * transition from 1 to 0 */
+	for (i = 0; i < timeout; i++) {
+		i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+		ack = ixgbe_get_i2c_data(&i2cctl);
+
+		udelay(1);
+		if (ack == 0)
+			break;
+	}
+
+	if (ack == 1) {
+		hw_dbg(hw, "I2C ack was not received.\n");
+		status = IXGBE_ERR_I2C;
+	}
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	udelay(IXGBE_I2C_T_LOW);
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
+ *  @hw: pointer to hardware structure
+ *  @data: read data value
+ *
+ *  Clocks in one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
+{
+	s32 status;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+	/* Minimum high period of clock is 4us */
+	udelay(IXGBE_I2C_T_HIGH);
+
+	i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	*data = ixgbe_get_i2c_data(&i2cctl);
+
+	ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+	/* Minimum low period of clock is 4.7 us */
+	udelay(IXGBE_I2C_T_LOW);
+
+	return status;
+}
+
+/**
+ *  ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
+ *  @hw: pointer to hardware structure
+ *  @data: data value to write
+ *
+ *  Clocks out one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
+{
+	s32 status;
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+	status = ixgbe_set_i2c_data(hw, &i2cctl, data);
+	if (status == 0) {
+		status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+		/* Minimum high period of clock is 4us */
+		udelay(IXGBE_I2C_T_HIGH);
+
+		ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+		/* Minimum low period of clock is 4.7 us.
+		 * This also takes care of the data hold time.
+		 */
+		udelay(IXGBE_I2C_T_LOW);
+	} else {
+		status = IXGBE_ERR_I2C;
+		hw_dbg(hw, "I2C data was not set to %X\n", data);
+	}
+
+	return status;
+}
+/**
+ *  ixgbe_raise_i2c_clk - Raises the I2C SCL clock
+ *  @hw: pointer to hardware structure
+ *  @i2cctl: Current value of I2CCTL register
+ *
+ *  Raises the I2C clock line '0'->'1'
+ **/
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+	s32 status = 0;
+
+	*i2cctl |= IXGBE_I2C_CLK_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* SCL rise time (1000ns) */
+	udelay(IXGBE_I2C_T_RISE);
+
+	return status;
+}
+
+/**
+ *  ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
+ *  @hw: pointer to hardware structure
+ *  @i2cctl: Current value of I2CCTL register
+ *
+ *  Lowers the I2C clock line '1'->'0'
+ **/
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+
+	*i2cctl &= ~IXGBE_I2C_CLK_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* SCL fall time (300ns) */
+	udelay(IXGBE_I2C_T_FALL);
+}
+
+/**
+ *  ixgbe_set_i2c_data - Sets the I2C data bit
+ *  @hw: pointer to hardware structure
+ *  @i2cctl: Current value of I2CCTL register
+ *  @data: I2C data value (0 or 1) to set
+ *
+ *  Sets the I2C data bit
+ **/
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
+{
+	s32 status = 0;
+
+	if (data)
+		*i2cctl |= IXGBE_I2C_DATA_OUT;
+	else
+		*i2cctl &= ~IXGBE_I2C_DATA_OUT;
+
+	IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+	/* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
+	udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
+
+	/* Verify data was set correctly */
+	*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	if (data != ixgbe_get_i2c_data(i2cctl)) {
+		status = IXGBE_ERR_I2C;
+		hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
+	}
+
+	return status;
+}
+
+/**
+ *  ixgbe_get_i2c_data - Reads the I2C SDA data bit
+ *  @hw: pointer to hardware structure
+ *  @i2cctl: Current value of I2CCTL register
+ *
+ *  Returns the I2C data bit value
+ **/
+static bool ixgbe_get_i2c_data(u32 *i2cctl)
+{
+	bool data;
+
+	if (*i2cctl & IXGBE_I2C_DATA_IN)
+		data = 1;
+	else
+		data = 0;
+
+	return data;
+}
+
+/**
+ *  ixgbe_i2c_bus_clear - Clears the I2C bus
+ *  @hw: pointer to hardware structure
+ *
+ *  Clears the I2C bus by sending nine clock pulses.
+ *  Used when data line is stuck low.
+ **/
+static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
+{
+	u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+	u32 i;
+
+	ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+	for (i = 0; i < 9; i++) {
+		ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+		/* Min high period of clock is 4us */
+		udelay(IXGBE_I2C_T_HIGH);
+
+		ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+		/* Min low period of clock is 4.7us*/
+		udelay(IXGBE_I2C_T_LOW);
+	}
+
+	/* Put the i2c bus back to default state */
+	ixgbe_i2c_stop(hw);
+}
+
+/**
  *  ixgbe_check_phy_link_tnx - Determine link and speed status
  *  @hw: pointer to hardware structure
  *
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_phy.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_phy.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_phy.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_phy.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,14 +54,15 @@
 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS  0x3
 
 /* Bit-shift macros */
-#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT    12
-#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT    8
-#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT    4
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT    24
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT    16
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT    8
 
 /* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
 #define IXGBE_SFF_VENDOR_OUI_TYCO     0x00407600
 #define IXGBE_SFF_VENDOR_OUI_FTL      0x00906500
 #define IXGBE_SFF_VENDOR_OUI_AVAGO    0x00176A00
+#define IXGBE_SFF_VENDOR_OUI_INTEL    0x001B2100
 
 /* I2C SDA and SCL timing parameters for standard mode */
 #define IXGBE_I2C_T_HD_STA  4
@@ -101,5 +102,12 @@ s32 ixgbe_identify_sfp_module_generic(st
 s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
                                         u16 *list_offset,
                                         u16 *data_offset);
-
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                u8 dev_addr, u8 *data);
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                 u8 dev_addr, u8 data);
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                  u8 *eeprom_data);
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                   u8 eeprom_data);
 #endif /* _IXGBE_PHY_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_type.h linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_type.h
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/ixgbe_type.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/ixgbe_type.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express 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,
@@ -34,6 +34,8 @@
 #define IXGBE_INTEL_VENDOR_ID   0x8086
 
 /* Device IDs */
+#define IXGBE_DEV_ID_82598               0x10B6
+#define IXGBE_DEV_ID_82598_BX            0x1508
 #define IXGBE_DEV_ID_82598AF_DUAL_PORT   0x10C6
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598EB_SFP_LOM     0x10DB
@@ -43,6 +45,9 @@
 #define IXGBE_DEV_ID_82598_DA_DUAL_PORT  0x10F1
 #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM      0x10E1
 #define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
+#define IXGBE_DEV_ID_82599               0x10D8
+#define IXGBE_DEV_ID_82599_KX4           0x10F7
+#define IXGBE_DEV_ID_82599_SFP           0x10FB
 
 /* General Registers */
 #define IXGBE_CTRL      0x00000
@@ -50,9 +55,12 @@
 #define IXGBE_CTRL_EXT  0x00018
 #define IXGBE_ESDP      0x00020
 #define IXGBE_EODSDP    0x00028
+#define IXGBE_I2CCTL    0x00028
 #define IXGBE_LEDCTL    0x00200
 #define IXGBE_FRTIMER   0x00048
 #define IXGBE_TCPTIMER  0x0004C
+#define IXGBE_CORESPARE 0x00600
+#define IXGBE_EXVET     0x05078
 
 /* NVM Registers */
 #define IXGBE_EEC       0x10010
@@ -66,6 +74,19 @@
 #define IXGBE_FLOP      0x1013C
 #define IXGBE_GRC       0x10200
 
+/* General Receive Control */
+#define IXGBE_GRC_MNG  0x00000001 /* Manageability Enable */
+#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */
+
+#define IXGBE_VPDDIAG0  0x10204
+#define IXGBE_VPDDIAG1  0x10208
+
+/* I2CCTL Bit Masks */
+#define IXGBE_I2C_CLK_IN    0x00000001
+#define IXGBE_I2C_CLK_OUT   0x00000002
+#define IXGBE_I2C_DATA_IN   0x00000004
+#define IXGBE_I2C_DATA_OUT  0x00000008
+
 /* Interrupt Registers */
 #define IXGBE_EICR      0x00800
 #define IXGBE_EICS      0x00808
@@ -73,28 +94,63 @@
 #define IXGBE_EIMC      0x00888
 #define IXGBE_EIAC      0x00810
 #define IXGBE_EIAM      0x00890
-#define IXGBE_EITR(_i)  (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_EICS_EX(_i)   (0x00A90 + (_i) * 4)
+#define IXGBE_EIMS_EX(_i)   (0x00AA0 + (_i) * 4)
+#define IXGBE_EIMC_EX(_i)   (0x00AB0 + (_i) * 4)
+#define IXGBE_EIAM_EX(_i)   (0x00AD0 + (_i) * 4)
+/*
+ * 82598 EITR is 16 bits but set the limits based on the max
+ * supported by all ixgbe hardware.  82599 EITR is only 12 bits,
+ * with the lower 3 always zero.
+ */
+#define IXGBE_MAX_INT_RATE 488281
+#define IXGBE_MIN_INT_RATE 956
+#define IXGBE_MAX_EITR     0x00000FF8
+#define IXGBE_MIN_EITR     8
+#define IXGBE_EITR(_i)  (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \
+                         (0x012300 + (((_i) - 24) * 4)))
+#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8
+#define IXGBE_EITR_LLI_MOD      0x00008000
+#define IXGBE_EITR_CNT_WDIS     0x80000000
 #define IXGBE_IVAR(_i)  (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */
+#define IXGBE_EITRSEL   0x00894
 #define IXGBE_MSIXT     0x00000 /* MSI-X Table. 0x0000 - 0x01C */
 #define IXGBE_MSIXPBA   0x02000 /* MSI-X Pending bit array */
 #define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
 #define IXGBE_GPIE      0x00898
 
 /* Flow Control Registers */
+#define IXGBE_FCADBUL   0x03210
+#define IXGBE_FCADBUH   0x03214
+#define IXGBE_FCAMACL   0x04328
+#define IXGBE_FCAMACH   0x0432C
+#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */
 #define IXGBE_PFCTOP    0x03008
 #define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */
 #define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */
 #define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */
 #define IXGBE_FCRTV     0x032A0
+#define IXGBE_FCCFG     0x03D00
 #define IXGBE_TFCS      0x0CE00
 
 /* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
-#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
-#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
-#define IXGBE_RDH(_i)   (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
-#define IXGBE_RDT(_i)   (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
-#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \
+                         (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \
+                         (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \
+                         (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i)   (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \
+                         (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i)   (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \
+                         (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
+                          (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDDCC      0x02F20
+#define IXGBE_RXMEMWRAP  0x03190
+#define IXGBE_STARCTRL   0x03024
 /*
  * Split and Replication Receive Control Registers
  * 00-15 : 0x02100 + n*4
@@ -127,10 +183,15 @@
 #define IXGBE_DRECCCTL_DISABLE 0
 /* Multicast Table Array - 128 entries */
 #define IXGBE_MTA(_i)   (0x05200 + ((_i) * 4))
-#define IXGBE_RAL(_i)   (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
-#define IXGBE_RAH(_i)   (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+#define IXGBE_RAL(_i)   (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
+                         (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i)   (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
+                         (0x0A204 + ((_i) * 8)))
+#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8))
+#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8))
 /* Packet split receive type */
-#define IXGBE_PSRTYPE(_i)    (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+#define IXGBE_PSRTYPE(_i)    (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \
+                              (0x0EA00 + ((_i) * 4)))
 /* array of 4096 1-bit vlan filters */
 #define IXGBE_VFTA(_i)  (0x0A000 + ((_i) * 4))
 /*array of 4096 4-bit vlan vmdq indices */
@@ -139,6 +200,28 @@
 #define IXGBE_VLNCTRL   0x05088
 #define IXGBE_MCSTCTRL  0x05090
 #define IXGBE_MRQC      0x05818
+#define IXGBE_SAQF(_i)  (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */
+#define IXGBE_DAQF(_i)  (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */
+#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */
+#define IXGBE_FTQF(_i)  (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */
+#define IXGBE_ETQF(_i)  (0x05128 + ((_i) * 4)) /* EType Queue Filter */
+#define IXGBE_ETQS(_i)  (0x0EC00 + ((_i) * 4)) /* EType Queue Select */
+#define IXGBE_SYNQF     0x0EC30 /* SYN Packet Queue Filter */
+#define IXGBE_RQTC      0x0EC70
+#define IXGBE_MTQC      0x08120
+#define IXGBE_VLVF(_i)  (0x0F100 + ((_i) * 4))  /* 64 of these (0-63) */
+#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4))  /* 128 of these (0-127) */
+#define IXGBE_VT_CTL    0x051B0
+#define IXGBE_VFRE(_i)  (0x051E0 + ((_i) * 4))
+#define IXGBE_VFTE(_i)  (0x08110 + ((_i) * 4))
+#define IXGBE_QDE       0x2F04
+#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
+#define IXGBE_UTA(_i)   (0x0F400 + ((_i) * 4))
+#define IXGBE_VMRCTL(_i)        (0x0F600 + ((_i) * 4))
+#define IXGBE_VMRVLAN(_i)       (0x0F610 + ((_i) * 4))
+#define IXGBE_VMRVM(_i)         (0x0F630 + ((_i) * 4))
+#define IXGBE_L34T_IMIR(_i)      (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_LLITHRESH 0x0EC90
 #define IXGBE_IMIR(_i)  (0x05A80 + ((_i) * 4))  /* 8 of these (0-7) */
 #define IXGBE_IMIREXT(_i)       (0x05AA0 + ((_i) * 4))  /* 8 of these (0-7) */
 #define IXGBE_IMIRVP    0x05AC0
@@ -146,7 +229,6 @@
 #define IXGBE_RETA(_i)  (0x05C00 + ((_i) * 4))  /* 32 of these (0-31) */
 #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4))  /* 10 of these (0-9) */
 
-
 /* Transmit DMA registers */
 #define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
 #define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
@@ -158,7 +240,20 @@
 #define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
 #define IXGBE_DTXCTL    0x07E00
 
+#define IXGBE_DMATXCTL  0x04A80
+#define IXGBE_DTXMXSZRQ     0x08100
+#define IXGBE_DTXTCPFLGL    0x04A88
+#define IXGBE_DTXTCPFLGH    0x04A8C
+#define IXGBE_LBDRPEN       0x0CA00
+#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */
+
+#define IXGBE_DMATXCTL_TE       0x1 /* Transmit Enable */
+#define IXGBE_DMATXCTL_NS       0x2 /* No Snoop LSO hdr buffer */
+#define IXGBE_DMATXCTL_GDV      0x8 /* Global Double VLAN */
+#define IXGBE_DMATXCTL_VT_SHIFT 16  /* VLAN EtherType */
 #define IXGBE_DCA_TXCTRL(_i)    (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
+/* Tx DCA Control register : 128 of these (0-127) */
+#define IXGBE_DCA_TXCTRL_82599(_i)  (0x0600C + ((_i) * 0x40))
 #define IXGBE_TIPG      0x0CB00
 #define IXGBE_TXPBSIZE(_i)      (0x0CC00 + ((_i) * 4)) /* 8 of these */
 #define IXGBE_MNGTXMAP  0x0CD10
@@ -175,9 +270,69 @@
 
 #define IXGBE_WUPL      0x05900
 #define IXGBE_WUPM      0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define IXGBE_FHFT      0x09000 /* Flex host filter table 9000-93FC */
+#define IXGBE_FHFT(_n)     (0x09000 + (_n * 0x100)) /* Flex host filter table */
+#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) /* Ext Flexible Host
+                                                     * Filter Table */
 
-/* Music registers */
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX         4
+#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX     2
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define IXGBE_FLEXIBLE_FILTER_SIZE_MAX  128
+#define IXGBE_FHFT_LENGTH_OFFSET        0xFC  /* Length byte in FHFT */
+#define IXGBE_FHFT_LENGTH_MASK          0x0FF /* Length in lower byte */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define IXGBE_WUC_PME_EN     0x00000002 /* PME Enable */
+#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */
+#define IXGBE_WUC_ADVD3WUC   0x00000010 /* D3Cold wake up cap. enable*/
+
+/* Wake Up Filter Control */
+#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define IXGBE_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define IXGBE_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define IXGBE_WUFC_MC   0x00000008 /* Directed Multicast Wakeup Enable */
+#define IXGBE_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+#define IXGBE_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define IXGBE_WUFC_MNG  0x00000100 /* Directed Mgmt Packet Wakeup Enable */
+
+#define IXGBE_WUFC_IGNORE_TCO   0x00008000 /* Ignore WakeOn TCO packets */
+#define IXGBE_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define IXGBE_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define IXGBE_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
+#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
+#define IXGBE_WUFC_FLX_FILTERS     0x000F0000 /* Mask for 4 flex filters */
+#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
+#define IXGBE_WUFC_ALL_FILTERS     0x003F00FF /* Mask for all 6 wakeup filters*/
+#define IXGBE_WUFC_FLX_OFFSET      16 /* Offset to the Flexible Filters bits */
+
+/* Wake Up Status */
+#define IXGBE_WUS_LNKC  IXGBE_WUFC_LNKC
+#define IXGBE_WUS_MAG   IXGBE_WUFC_MAG
+#define IXGBE_WUS_EX    IXGBE_WUFC_EX
+#define IXGBE_WUS_MC    IXGBE_WUFC_MC
+#define IXGBE_WUS_BC    IXGBE_WUFC_BC
+#define IXGBE_WUS_ARP   IXGBE_WUFC_ARP
+#define IXGBE_WUS_IPV4  IXGBE_WUFC_IPV4
+#define IXGBE_WUS_IPV6  IXGBE_WUFC_IPV6
+#define IXGBE_WUS_MNG   IXGBE_WUFC_MNG
+#define IXGBE_WUS_FLX0  IXGBE_WUFC_FLX0
+#define IXGBE_WUS_FLX1  IXGBE_WUFC_FLX1
+#define IXGBE_WUS_FLX2  IXGBE_WUFC_FLX2
+#define IXGBE_WUS_FLX3  IXGBE_WUFC_FLX3
+#define IXGBE_WUS_FLX4  IXGBE_WUFC_FLX4
+#define IXGBE_WUS_FLX5  IXGBE_WUFC_FLX5
+#define IXGBE_WUS_FLX_FILTERS  IXGBE_WUFC_FLX_FILTERS
+
+/* Wake Up Packet Length */
+#define IXGBE_WUPL_LENGTH_MASK 0xFFFF
+
+/* DCB registers */
 #define IXGBE_RMCS      0x03D00
 #define IXGBE_DPMCS     0x07F40
 #define IXGBE_PDPMCS    0x0CD00
@@ -190,6 +345,122 @@
 #define IXGBE_TDPT2TCSR(_i)     (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
 
 
+/* Security Control Registers */
+#define IXGBE_SECTXCTRL         0x08800
+#define IXGBE_SECTXSTAT         0x08804
+#define IXGBE_SECTXBUFFAF       0x08808
+#define IXGBE_SECTXMINIFG       0x08810
+#define IXGBE_SECTXSTAT         0x08804
+#define IXGBE_SECRXCTRL         0x08D00
+#define IXGBE_SECRXSTAT         0x08D04
+
+/* Security Bit Fields and Masks */
+#define IXGBE_SECTXCTRL_SECTX_DIS       0x00000001
+#define IXGBE_SECTXCTRL_TX_DIS          0x00000002
+#define IXGBE_SECTXCTRL_STORE_FORWARD   0x00000004
+
+#define IXGBE_SECTXSTAT_SECTX_RDY       0x00000001
+#define IXGBE_SECTXSTAT_ECC_TXERR       0x00000002
+
+#define IXGBE_SECRXCTRL_SECRX_DIS       0x00000001
+#define IXGBE_SECRXCTRL_RX_DIS          0x00000002
+
+#define IXGBE_SECRXSTAT_SECRX_RDY       0x00000001
+#define IXGBE_SECRXSTAT_ECC_RXERR       0x00000002
+
+/* LinkSec (MacSec) Registers */
+#define IXGBE_LSECTXCAP         0x08A00
+#define IXGBE_LSECRXCAP         0x08F00
+#define IXGBE_LSECTXCTRL        0x08A04
+#define IXGBE_LSECTXSCL         0x08A08 /* SCI Low */
+#define IXGBE_LSECTXSCH         0x08A0C /* SCI High */
+#define IXGBE_LSECTXSA          0x08A10
+#define IXGBE_LSECTXPN0         0x08A14
+#define IXGBE_LSECTXPN1         0x08A18
+#define IXGBE_LSECTXKEY0(_n)    (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECTXKEY1(_n)    (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECRXCTRL        0x08F04
+#define IXGBE_LSECRXSCL         0x08F08
+#define IXGBE_LSECRXSCH         0x08F0C
+#define IXGBE_LSECRXSA(_i)      (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXPN(_i)      (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m))))
+#define IXGBE_LSECTXUT          0x08A3C /* OutPktsUntagged */
+#define IXGBE_LSECTXPKTE        0x08A40 /* OutPktsEncrypted */
+#define IXGBE_LSECTXPKTP        0x08A44 /* OutPktsProtected */
+#define IXGBE_LSECTXOCTE        0x08A48 /* OutOctetsEncrypted */
+#define IXGBE_LSECTXOCTP        0x08A4C /* OutOctetsProtected */
+#define IXGBE_LSECRXUT          0x08F40 /* InPktsUntagged/InPktsNoTag */
+#define IXGBE_LSECRXOCTD        0x08F44 /* InOctetsDecrypted */
+#define IXGBE_LSECRXOCTV        0x08F48 /* InOctetsValidated */
+#define IXGBE_LSECRXBAD         0x08F4C /* InPktsBadTag */
+#define IXGBE_LSECRXNOSCI       0x08F50 /* InPktsNoSci */
+#define IXGBE_LSECRXUNSCI       0x08F54 /* InPktsUnknownSci */
+#define IXGBE_LSECRXUNCH        0x08F58 /* InPktsUnchecked */
+#define IXGBE_LSECRXDELAY       0x08F5C /* InPktsDelayed */
+#define IXGBE_LSECRXLATE        0x08F60 /* InPktsLate */
+#define IXGBE_LSECRXOK(_n)      (0x08F64 + (0x04 * (_n))) /* InPktsOk */
+#define IXGBE_LSECRXINV(_n)     (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */
+#define IXGBE_LSECRXNV(_n)      (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */
+#define IXGBE_LSECRXUNSA        0x08F7C /* InPktsUnusedSa */
+#define IXGBE_LSECRXNUSA        0x08F80 /* InPktsNotUsingSa */
+
+/* LinkSec (MacSec) Bit Fields and Masks */
+#define IXGBE_LSECTXCAP_SUM_MASK        0x00FF0000
+#define IXGBE_LSECTXCAP_SUM_SHIFT       16
+#define IXGBE_LSECRXCAP_SUM_MASK        0x00FF0000
+#define IXGBE_LSECRXCAP_SUM_SHIFT       16
+
+#define IXGBE_LSECTXCTRL_EN_MASK        0x00000003
+#define IXGBE_LSECTXCTRL_DISABLE        0x0
+#define IXGBE_LSECTXCTRL_AUTH           0x1
+#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT   0x2
+#define IXGBE_LSECTXCTRL_AISCI          0x00000020
+#define IXGBE_LSECTXCTRL_PNTHRSH_MASK   0xFFFFFF00
+#define IXGBE_LSECTXCTRL_RSV_MASK       0x000000D8
+
+#define IXGBE_LSECRXCTRL_EN_MASK        0x0000000C
+#define IXGBE_LSECRXCTRL_EN_SHIFT       2
+#define IXGBE_LSECRXCTRL_DISABLE        0x0
+#define IXGBE_LSECRXCTRL_CHECK          0x1
+#define IXGBE_LSECRXCTRL_STRICT         0x2
+#define IXGBE_LSECRXCTRL_DROP           0x3
+#define IXGBE_LSECRXCTRL_PLSH           0x00000040
+#define IXGBE_LSECRXCTRL_RP             0x00000080
+#define IXGBE_LSECRXCTRL_RSV_MASK       0xFFFFFF33
+
+/* IpSec Registers */
+#define IXGBE_IPSTXIDX          0x08900
+#define IXGBE_IPSTXSALT         0x08904
+#define IXGBE_IPSTXKEY(_i)      (0x08908 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXIDX          0x08E00
+#define IXGBE_IPSRXIPADDR(_i)   (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSPI          0x08E14
+#define IXGBE_IPSRXIPIDX        0x08E18
+#define IXGBE_IPSRXKEY(_i)      (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSALT         0x08E2C
+#define IXGBE_IPSRXMOD          0x08E30
+
+#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE    0x4
+
+/* DCB registers */
+#define IXGBE_RTRPCS      0x02430
+#define IXGBE_RTTDCS      0x04900
+#define IXGBE_RTTPCS      0x0CD00
+#define IXGBE_RTRUP2TC    0x03020
+#define IXGBE_RTTUP2TC    0x0C800
+#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDQSEL    0x04904
+#define IXGBE_RTTDT1C     0x04908
+#define IXGBE_RTTDT1S     0x0490C
+#define IXGBE_RTTDTECC    0x04990
+#define IXGBE_RTTDTECC_NO_BCN   0x00000100
+#define IXGBE_RTTBCNRC    0x04984
 
 /* Stats registers */
 #define IXGBE_CRCERRS   0x04000
@@ -204,6 +475,11 @@
 #define IXGBE_LXONRXC   0x0CF60
 #define IXGBE_LXOFFTXC  0x03F68
 #define IXGBE_LXOFFRXC  0x0CF68
+#define IXGBE_LXONRXCNT 0x041A4
+#define IXGBE_LXOFFRXCNT 0x041A8
+#define IXGBE_PXONRXCNT(_i)     (0x04140 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXOFFRXCNT(_i)    (0x04160 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXON2OFFCNT(_i)   (0x03240 + ((_i) * 4)) /* 8 of these */
 #define IXGBE_PXONTXC(_i)       (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/
 #define IXGBE_PXONRXC(_i)       (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/
 #define IXGBE_PXOFFTXC(_i)      (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/
@@ -243,14 +519,20 @@
 #define IXGBE_MPTC      0x040F0
 #define IXGBE_BPTC      0x040F4
 #define IXGBE_XEC       0x04120
+#define IXGBE_SSVPC     0x08780
 
-#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
+#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4))
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \
+                         (0x08600 + ((_i) * 4)))
+#define IXGBE_TQSM(_i)  (0x08600 + ((_i) * 4))
 
 #define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
+#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
+#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
+#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
 
 /* Management */
 #define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -263,6 +545,9 @@
 #define IXGBE_MMAL(_i)  (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */
 #define IXGBE_MMAH(_i)  (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */
 #define IXGBE_FTFT      0x09400 /* 0x9400-0x97FC */
+#define IXGBE_METF(_i)  (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */
+#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_LSWFW     0x15014
 
 /* ARC Subsystem registers */
 #define IXGBE_HICR      0x15F00
@@ -295,16 +580,65 @@
 #define IXGBE_DCA_ID    0x11070
 #define IXGBE_DCA_CTRL  0x11074
 
+/* PCIe registers 82599-specific */
+#define IXGBE_GCR_EXT           0x11050
+#define IXGBE_GSCL_5_82599      0x11030
+#define IXGBE_GSCL_6_82599      0x11034
+#define IXGBE_GSCL_7_82599      0x11038
+#define IXGBE_GSCL_8_82599      0x1103C
+#define IXGBE_PHYADR_82599      0x11040
+#define IXGBE_PHYDAT_82599      0x11044
+#define IXGBE_PHYCTL_82599      0x11048
+#define IXGBE_PBACLR_82599      0x11068
+#define IXGBE_CIAA_82599        0x11088
+#define IXGBE_CIAD_82599        0x1108C
+#define IXGBE_PCIE_DIAG_0_82599 0x11090
+#define IXGBE_PCIE_DIAG_1_82599 0x11094
+#define IXGBE_PCIE_DIAG_2_82599 0x11098
+#define IXGBE_PCIE_DIAG_3_82599 0x1109C
+#define IXGBE_PCIE_DIAG_4_82599 0x110A0
+#define IXGBE_PCIE_DIAG_5_82599 0x110A4
+#define IXGBE_PCIE_DIAG_6_82599 0x110A8
+#define IXGBE_PCIE_DIAG_7_82599 0x110C0
+#define IXGBE_INTRPT_CSR_82599  0x110B0
+#define IXGBE_INTRPT_MASK_82599 0x110B8
+#define IXGBE_CDQ_MBR_82599     0x110B4
+#define IXGBE_MISC_REG_82599    0x110F0
+#define IXGBE_ECC_CTRL_0_82599  0x11100
+#define IXGBE_ECC_CTRL_1_82599  0x11104
+#define IXGBE_ECC_STATUS_82599  0x110E0
+#define IXGBE_BAR_CTRL_82599    0x110F4
+
+/* Time Sync Registers */
+#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
+#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
+#define IXGBE_RXSTMPL    0x051E8 /* Rx timestamp Low - RO */
+#define IXGBE_RXSTMPH    0x051A4 /* Rx timestamp High - RO */
+#define IXGBE_RXSATRL    0x051A0 /* Rx timestamp attribute low - RO */
+#define IXGBE_RXSATRH    0x051A8 /* Rx timestamp attribute high - RO */
+#define IXGBE_RXMTRL     0x05120 /* RX message type register low - RW */
+#define IXGBE_TXSTMPL    0x08C04 /* Tx timestamp value Low - RO */
+#define IXGBE_TXSTMPH    0x08C08 /* Tx timestamp value High - RO */
+#define IXGBE_SYSTIML    0x08C0C /* System time register Low - RO */
+#define IXGBE_SYSTIMH    0x08C10 /* System time register High - RO */
+#define IXGBE_TIMINCA    0x08C14 /* Increment attributes register - RW */
+#define IXGBE_RXUDP      0x08C1C /* Time Sync Rx UDP Port - RW */
+
 /* Diagnostic Registers */
 #define IXGBE_RDSTATCTL   0x02C20
 #define IXGBE_RDSTAT(_i)  (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
 #define IXGBE_RDHMPN      0x02F08
 #define IXGBE_RIC_DW(_i)  (0x02F10 + ((_i) * 4))
 #define IXGBE_RDPROBE     0x02F20
+#define IXGBE_RDMAM       0x02F30
+#define IXGBE_RDMAD       0x02F34
 #define IXGBE_TDSTATCTL   0x07C20
 #define IXGBE_TDSTAT(_i)  (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
 #define IXGBE_TDHMPN      0x07F08
+#define IXGBE_TDHMPN2     0x082FC
+#define IXGBE_TXDESCIC    0x082CC
 #define IXGBE_TIC_DW(_i)  (0x07F10 + ((_i) * 4))
+#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4))
 #define IXGBE_TDPROBE     0x07F20
 #define IXGBE_TXBUFCTRL   0x0C600
 #define IXGBE_TXBUFDATA0  0x0C610
@@ -332,6 +666,8 @@
 #define IXGBE_TXDATARDPTR(_i)   (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
 #define IXGBE_TXDESCRDPTR(_i)   (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
 #define IXGBE_PCIEECCCTL 0x1106C
+#define IXGBE_PCIEECCCTL0 0x11100
+#define IXGBE_PCIEECCCTL1 0x11104
 #define IXGBE_PBTXECC   0x0C300
 #define IXGBE_PBRXECC   0x03300
 #define IXGBE_GHECCR    0x110B0
@@ -357,24 +693,61 @@
 #define IXGBE_MSRWD     0x04260
 #define IXGBE_MLADD     0x04264
 #define IXGBE_MHADD     0x04268
+#define IXGBE_MAXFRS    0x04268
 #define IXGBE_TREG      0x0426C
 #define IXGBE_PCSS1     0x04288
 #define IXGBE_PCSS2     0x0428C
 #define IXGBE_XPCSS     0x04290
+#define IXGBE_MFLCN     0x04294
 #define IXGBE_SERDESC   0x04298
 #define IXGBE_MACS      0x0429C
 #define IXGBE_AUTOC     0x042A0
 #define IXGBE_LINKS     0x042A4
+#define IXGBE_LINKS2    0x04324
 #define IXGBE_AUTOC2    0x042A8
 #define IXGBE_AUTOC3    0x042AC
 #define IXGBE_ANLP1     0x042B0
 #define IXGBE_ANLP2     0x042B4
 #define IXGBE_ATLASCTL  0x04800
+#define IXGBE_MMNGC     0x042D0
+#define IXGBE_ANLPNP1   0x042D4
+#define IXGBE_ANLPNP2   0x042D8
+#define IXGBE_KRPCSFC   0x042E0
+#define IXGBE_KRPCSS    0x042E4
+#define IXGBE_FECS1     0x042E8
+#define IXGBE_FECS2     0x042EC
+#define IXGBE_SMADARCTL 0x14F10
+#define IXGBE_MPVC      0x04318
+#define IXGBE_SGMIIC    0x04314
+
+/* Omer CORECTL */
+#define IXGBE_CORECTL           0x014F00
+/* BARCTRL */
+#define IXGBE_BARCTRL           0x110F4
+#define IXGBE_BARCTRL_FLSIZE    0x0700
+#define IXGBE_BARCTRL_CSRSIZE   0x2000
 
 /* RDRXCTL Bit Masks */
 #define IXGBE_RDRXCTL_RDMTS_1_2     0x00000000 /* Rx Desc Min Threshold Size */
+#define IXGBE_RDRXCTL_CRCSTRIP      0x00000002 /* CRC Strip */
 #define IXGBE_RDRXCTL_MVMEN         0x00000020
 #define IXGBE_RDRXCTL_DMAIDONE      0x00000008 /* DMA init cycle done */
+#define IXGBE_RDRXCTL_AGGDIS        0x00010000 /* Aggregation disable */
+
+/* RQTC Bit Masks and Shifts */
+#define IXGBE_RQTC_SHIFT_TC(_i)     ((_i) * 4)
+#define IXGBE_RQTC_TC0_MASK         (0x7 << 0)
+#define IXGBE_RQTC_TC1_MASK         (0x7 << 4)
+#define IXGBE_RQTC_TC2_MASK         (0x7 << 8)
+#define IXGBE_RQTC_TC3_MASK         (0x7 << 12)
+#define IXGBE_RQTC_TC4_MASK         (0x7 << 16)
+#define IXGBE_RQTC_TC5_MASK         (0x7 << 20)
+#define IXGBE_RQTC_TC6_MASK         (0x7 << 24)
+#define IXGBE_RQTC_TC7_MASK         (0x7 << 28)
+
+/* PSRTYPE.RQPL Bit masks and shift */
+#define IXGBE_PSRTYPE_RQPL_MASK     0x7
+#define IXGBE_PSRTYPE_RQPL_SHIFT    29
 
 /* CTRL Bit Masks */
 #define IXGBE_CTRL_GIO_DIS      0x00000004 /* Global IO Master Disable bit */
@@ -389,6 +762,7 @@
 #define IXGBE_MHADD_MFS_SHIFT   16
 
 /* Extended Device Control */
+#define IXGBE_CTRL_EXT_PFRSTD   0x00004000 /* Physical Function Reset Done */
 #define IXGBE_CTRL_EXT_NS_DIS   0x00010000 /* No Snoop disable */
 #define IXGBE_CTRL_EXT_RO_DIS   0x00020000 /* Relaxed Ordering disable */
 #define IXGBE_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
@@ -401,6 +775,8 @@
 #define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
 
 #define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599  0xFF000000 /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */
 #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
 #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
 #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
@@ -409,6 +785,8 @@
 #define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
 
 #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599  0xFF000000 /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */
 #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
 #define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
 #define IXGBE_DCA_MAX_QUEUES_82598   16 /* DCA regs only on 16 queues */
@@ -452,6 +830,8 @@
 #define IXGBE_ATLAS_PDN_TX_1G_QL_ALL    0xF0
 #define IXGBE_ATLAS_PDN_TX_AN_QL_ALL    0xF0
 
+/* Omer bit masks */
+#define IXGBE_CORECTL_WRITE_CMD         0x00010000
 
 /* Device Type definitions for new protocol MDIO commands */
 #define IXGBE_MDIO_PMA_PMD_DEV_TYPE               0x1
@@ -479,8 +859,11 @@
 #define IXGBE_MDIO_PHY_SPEED_ABILITY   0x4 /* Speed Ability Reg */
 #define IXGBE_MDIO_PHY_SPEED_10G       0x0001 /* 10G capable */
 #define IXGBE_MDIO_PHY_SPEED_1G        0x0010 /* 1G capable */
+#define IXGBE_MDIO_PHY_EXT_ABILITY        0xB /* Ext Ability Reg */
+#define IXGBE_MDIO_PHY_10GBASET_ABILITY   0x0004 /* 10GBaseT capable */
+#define IXGBE_MDIO_PHY_1000BASET_ABILITY  0x0020 /* 1000BaseT capable */
 
-#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR     0xC30A /* PHY_XS SDA/SCL Address Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR     0xC30A /* PHY_XS SDA/SCL Addr Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA     0xC30B /* PHY_XS SDA/SCL Data Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT     0xC30C /* PHY_XS SDA/SCL Status Reg */
 
@@ -495,7 +878,7 @@
 #define IXGBE_PHY_REVISION_MASK        0xFFFFFFF0
 #define IXGBE_MAX_PHY_ADDR             32
 
-/* PHY IDs */
+/* PHY IDs*/
 #define TN1010_PHY_ID    0x00A19410
 #define TNX_FW_REV       0xB
 #define QT2022_PHY_ID    0x0043A400
@@ -515,15 +898,22 @@
 #define IXGBE_CONTROL_NL         0x000F
 #define IXGBE_CONTROL_EOL_NL     0x0FFF
 #define IXGBE_CONTROL_SOL_NL     0x0000
+#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
+#define IXGBE_PHY_ALLOW_ANY_SFP            0x1
 
 /* General purpose Interrupt Enable */
 #define IXGBE_SDP0_GPIEN         0x00000001 /* SDP0 */
 #define IXGBE_SDP1_GPIEN         0x00000002 /* SDP1 */
+#define IXGBE_SDP2_GPIEN         0x00000004 /* SDP2 */
 #define IXGBE_GPIE_MSIX_MODE     0x00000010 /* MSI-X mode */
 #define IXGBE_GPIE_OCD           0x00000020 /* Other Clear Disable */
 #define IXGBE_GPIE_EIMEN         0x00000040 /* Immediate Interrupt Enable */
 #define IXGBE_GPIE_EIAME         0x40000000
 #define IXGBE_GPIE_PBA_SUPPORT   0x80000000
+#define IXGBE_GPIE_VTMODE_MASK   0x0000C000 /* VT Mode Mask */
+#define IXGBE_GPIE_VTMODE_16     0x00004000 /* 16 VFs 8 queues per VF */
+#define IXGBE_GPIE_VTMODE_32     0x00008000 /* 32 VFs 4 queues per VF */
+#define IXGBE_GPIE_VTMODE_64     0x0000C000 /* 64 VFs 2 queues per VF */
 
 /* Transmit Flow Control status */
 #define IXGBE_TFCS_TXOFF         0x00000001
@@ -564,6 +954,21 @@
 #define IXGBE_VMD_CTL_VMDQ_EN     0x00000001
 #define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002
 
+/* VT_CTL bitmasks */
+#define IXGBE_VT_CTL_DIS_DEFPL  0x20000000 /* disable default pool */
+#define IXGBE_VT_CTL_REPLEN     0x40000000 /* replication enabled */
+#define IXGBE_VT_CTL_VT_ENABLE  0x00000001  /* Enable VT Mode */
+
+/* VMOLR bitmasks */
+#define IXGBE_VMOLR_AUPE        0x01000000 /* accept untagged packets */
+#define IXGBE_VMOLR_ROMPE       0x02000000 /* accept packets in MTA tbl */
+#define IXGBE_VMOLR_ROPE        0x04000000 /* accept packets in UC tbl */
+#define IXGBE_VMOLR_BAM         0x08000000 /* accept broadcast packets */
+#define IXGBE_VMOLR_MPE         0x10000000 /* multicast promiscuous */
+
+/* VFRE bitmask */
+#define IXGBE_VFRE_ENABLE_ALL   0xFFFFFFFF
+
 /* RDHMPN and TDHMPN bitmasks */
 #define IXGBE_RDHMPN_RDICADDR       0x007FF800
 #define IXGBE_RDHMPN_RDICRDREQ      0x00800000
@@ -572,13 +977,39 @@
 #define IXGBE_TDHMPN_TDICRDREQ      0x00800000
 #define IXGBE_TDHMPN_TDICADDR_SHIFT 11
 
+#define IXGBE_RDMAM_MEM_SEL_SHIFT   13
+#define IXGBE_RDMAM_DWORD_SHIFT     9
+#define IXGBE_RDMAM_DESC_COMP_FIFO  1
+#define IXGBE_RDMAM_DFC_CMD_FIFO    2
+#define IXGBE_RDMAM_TCN_STATUS_RAM  4
+#define IXGBE_RDMAM_WB_COLL_FIFO    5
+#define IXGBE_RDMAM_QSC_CNT_RAM     6
+#define IXGBE_RDMAM_QSC_QUEUE_CNT   8
+#define IXGBE_RDMAM_QSC_QUEUE_RAM   0xA
+#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE     135
+#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT     4
+#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE      48
+#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT      7
+#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE    256
+#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT    9
+#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE      8
+#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT      4
+#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE       64
+#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT       4
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE     32
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT     4
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE     128
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT     8
+
+#define IXGBE_TXDESCIC_READY        0x80000000
+
 /* Receive Checksum Control */
 #define IXGBE_RXCSUM_IPPCSE     0x00001000   /* IP payload checksum enable */
 #define IXGBE_RXCSUM_PCSD       0x00002000   /* packet checksum disabled */
 
 /* FCRTL Bit Masks */
-#define IXGBE_FCRTL_XONE        0x80000000  /* bit 31, XON enable */
-#define IXGBE_FCRTH_FCEN        0x80000000  /* Rx Flow control enable */
+#define IXGBE_FCRTL_XONE        0x80000000  /* XON enable */
+#define IXGBE_FCRTH_FCEN        0x80000000  /* Packet buffer fc enable */
 
 /* PAP bit masks*/
 #define IXGBE_PAP_TXPAUSECNT_MASK   0x0000FFFF /* Pause counter mask */
@@ -588,19 +1019,29 @@
 /* Receive Arbitration Control: 0 Round Robin, 1 DFP */
 #define IXGBE_RMCS_RAC          0x00000004
 #define IXGBE_RMCS_DFP          IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
-#define IXGBE_RMCS_TFCE_802_3X  0x00000008 /* Tx Priority flow control ena */
-#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
+#define IXGBE_RMCS_TFCE_802_3X         0x00000008 /* Tx Priority FC ena */
+#define IXGBE_RMCS_TFCE_PRIORITY       0x00000010 /* Tx Priority FC ena */
 #define IXGBE_RMCS_ARBDIS       0x00000040 /* Arbitration disable bit */
 
+/* FCCFG Bit Masks */
+#define IXGBE_FCCFG_TFCE_802_3X         0x00000008 /* Tx link FC enable */
+#define IXGBE_FCCFG_TFCE_PRIORITY       0x00000010 /* Tx priority FC enable */
 
 /* Interrupt register bitmasks */
 
 /* Extended Interrupt Cause Read */
 #define IXGBE_EICR_RTX_QUEUE    0x0000FFFF /* RTx Queue Interrupt */
+#define IXGBE_EICR_FLOW_DIR     0x00010000 /* FDir Exception */
+#define IXGBE_EICR_RX_MISS      0x00020000 /* Packet Buffer Overrun */
+#define IXGBE_EICR_PCI          0x00040000 /* PCI Exception */
+#define IXGBE_EICR_MAILBOX      0x00080000 /* VF to PF Mailbox Interrupt */
 #define IXGBE_EICR_LSC          0x00100000 /* Link Status Change */
+#define IXGBE_EICR_LINKSEC      0x00200000 /* PN Threshold */
 #define IXGBE_EICR_MNG          0x00400000 /* Manageability Event Interrupt */
 #define IXGBE_EICR_GPI_SDP0     0x01000000 /* Gen Purpose Interrupt on SDP0 */
 #define IXGBE_EICR_GPI_SDP1     0x02000000 /* Gen Purpose Interrupt on SDP1 */
+#define IXGBE_EICR_GPI_SDP2     0x04000000 /* Gen Purpose Interrupt on SDP2 */
+#define IXGBE_EICR_ECC          0x10000000 /* ECC Error */
 #define IXGBE_EICR_PBUR         0x10000000 /* Packet Buffer Handler Error */
 #define IXGBE_EICR_DHER         0x20000000 /* Descriptor Handler Error */
 #define IXGBE_EICR_TCP_TIMER    0x40000000 /* TCP Timer */
@@ -608,10 +1049,16 @@
 
 /* Extended Interrupt Cause Set */
 #define IXGBE_EICS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EICS_FLOW_DIR     IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define IXGBE_EICS_RX_MISS      IXGBE_EICR_RX_MISS   /* Pkt Buffer Overrun */
+#define IXGBE_EICS_PCI          IXGBE_EICR_PCI       /* PCI Exception */
+#define IXGBE_EICS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
 #define IXGBE_EICS_LSC          IXGBE_EICR_LSC       /* Link Status Change */
 #define IXGBE_EICS_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
 #define IXGBE_EICS_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
 #define IXGBE_EICS_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP2     IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define IXGBE_EICS_ECC          IXGBE_EICR_ECC       /* ECC Error */
 #define IXGBE_EICS_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
 #define IXGBE_EICS_DHER         IXGBE_EICR_DHER      /* Desc Handler Error */
 #define IXGBE_EICS_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -619,10 +1066,16 @@
 
 /* Extended Interrupt Mask Set */
 #define IXGBE_EIMS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMS_FLOW_DIR     IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define IXGBE_EIMS_RX_MISS      IXGBE_EICR_RX_MISS   /* Packet Buffer Overrun */
+#define IXGBE_EIMS_PCI          IXGBE_EICR_PCI       /* PCI Exception */
+#define IXGBE_EIMS_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
 #define IXGBE_EIMS_LSC          IXGBE_EICR_LSC       /* Link Status Change */
 #define IXGBE_EIMS_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
 #define IXGBE_EIMS_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
 #define IXGBE_EIMS_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP2     IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMS_ECC          IXGBE_EICR_ECC       /* ECC Error */
 #define IXGBE_EIMS_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
 #define IXGBE_EIMS_DHER         IXGBE_EICR_DHER      /* Descr Handler Error */
 #define IXGBE_EIMS_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -630,10 +1083,16 @@
 
 /* Extended Interrupt Mask Clear */
 #define IXGBE_EIMC_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMC_FLOW_DIR     IXGBE_EICR_FLOW_DIR  /* FDir Exception */
+#define IXGBE_EIMC_RX_MISS      IXGBE_EICR_RX_MISS   /* Packet Buffer Overrun */
+#define IXGBE_EIMC_PCI          IXGBE_EICR_PCI       /* PCI Exception */
+#define IXGBE_EIMC_MAILBOX      IXGBE_EICR_MAILBOX   /* VF to PF Mailbox Int */
 #define IXGBE_EIMC_LSC          IXGBE_EICR_LSC       /* Link Status Change */
 #define IXGBE_EIMC_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
 #define IXGBE_EIMC_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
 #define IXGBE_EIMC_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP2     IXGBE_EICR_GPI_SDP2  /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMC_ECC          IXGBE_EICR_ECC       /* ECC Error */
 #define IXGBE_EIMC_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
 #define IXGBE_EIMC_DHER         IXGBE_EICR_DHER      /* Desc Handler Err */
 #define IXGBE_EIMC_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -656,6 +1115,33 @@
 #define IXGBE_IMIREXT_CTRL_SYN    0x00020000  /* Check SYN bit in header */
 #define IXGBE_IMIREXT_CTRL_FIN    0x00040000  /* Check FIN bit in header */
 #define IXGBE_IMIREXT_CTRL_BP     0x00080000  /* Bypass check of control bits */
+#define IXGBE_IMIR_SIZE_BP_82599  0x00001000 /* Packet size bypass */
+#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */
+#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */
+#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */
+#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */
+#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */
+#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */
+#define IXGBE_IMIR_CTRL_BP_82599  0x00080000 /* Bypass check of control bits */
+#define IXGBE_IMIR_LLI_EN_82599   0x00100000 /* Enables low latency Int */
+#define IXGBE_IMIR_RX_QUEUE_MASK_82599  0x0000007F /* Rx Queue Mask */
+#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */
+#define IXGBE_IMIRVP_PRIORITY_MASK      0x00000007 /* VLAN priority mask */
+#define IXGBE_IMIRVP_PRIORITY_EN        0x00000008 /* VLAN priority enable */
+
+#define IXGBE_MAX_FTQF_FILTERS          128
+#define IXGBE_FTQF_PROTOCOL_MASK        0x00000003
+#define IXGBE_FTQF_PROTOCOL_TCP         0x00000000
+#define IXGBE_FTQF_PROTOCOL_UDP         0x00000001
+#define IXGBE_FTQF_PROTOCOL_SCTP        2
+#define IXGBE_FTQF_PRIORITY_MASK        0x00000007
+#define IXGBE_FTQF_PRIORITY_SHIFT       2
+#define IXGBE_FTQF_POOL_MASK            0x0000003F
+#define IXGBE_FTQF_POOL_SHIFT           8
+#define IXGBE_FTQF_5TUPLE_MASK_MASK     0x0000001F
+#define IXGBE_FTQF_5TUPLE_MASK_SHIFT    25
+#define IXGBE_FTQF_POOL_MASK_EN         0x40000000
+#define IXGBE_FTQF_QUEUE_ENABLE         0x80000000
 
 /* Interrupt clear mask */
 #define IXGBE_IRQ_CLEAR_MASK    0xFFFFFFFF
@@ -675,6 +1161,31 @@
 
 #define IXGBE_IVAR_ALLOC_VAL    0x80 /* Interrupt Allocation valid */
 
+/* ETYPE Queue Filter/Select Bit Masks */
+#define IXGBE_MAX_ETQF_FILTERS  8
+#define IXGBE_ETQF_BCN          0x10000000 /* bit 28 */
+#define IXGBE_ETQF_1588         0x40000000 /* bit 30 */
+#define IXGBE_ETQF_FILTER_EN    0x80000000 /* bit 31 */
+#define IXGBE_ETQF_POOL_ENABLE   (1 << 26) /* bit 26 */
+
+#define IXGBE_ETQS_RX_QUEUE     0x007F0000 /* bits 22:16 */
+#define IXGBE_ETQS_RX_QUEUE_SHIFT       16
+#define IXGBE_ETQS_LLI          0x20000000 /* bit 29 */
+#define IXGBE_ETQS_QUEUE_EN     0x80000000 /* bit 31 */
+
+/*
+ * ETQF filter list: one static filter per filter consumer. This is
+ *                   to avoid filter collisions later. Add new filters
+ *                   here!!
+ *
+ * Current filters:
+ *    EAPOL 802.1x (0x888e): Filter 0
+ *    BCN (0x8904):          Filter 1
+ *    1588 (0x88f7):         Filter 3
+ */
+#define IXGBE_ETQF_FILTER_EAPOL          0
+#define IXGBE_ETQF_FILTER_BCN            1
+#define IXGBE_ETQF_FILTER_1588           3
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET       0x0000FFFF  /* bits 0-15 */
 #define IXGBE_VLNCTRL_CFI       0x10000000  /* bit 28 */
@@ -682,21 +1193,28 @@
 #define IXGBE_VLNCTRL_VFE       0x40000000  /* bit 30 */
 #define IXGBE_VLNCTRL_VME       0x80000000  /* bit 31 */
 
+/* VLAN pool filtering masks */
+#define IXGBE_VLVF_VIEN         0x80000000  /* filter is valid */
+#define IXGBE_VLVF_ENTRIES      64
 
 #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.1q protocol */
 
 /* STATUS Bit Masks */
-#define IXGBE_STATUS_LAN_ID     0x0000000C /* LAN ID */
-#define IXGBE_STATUS_GIO        0x00080000 /* GIO Master Enable Status */
+#define IXGBE_STATUS_LAN_ID         0x0000000C /* LAN ID */
+#define IXGBE_STATUS_LAN_ID_SHIFT   2          /* LAN ID Shift*/
+#define IXGBE_STATUS_GIO            0x00080000 /* GIO Master Enable Status */
 
 #define IXGBE_STATUS_LAN_ID_0   0x00000000 /* LAN ID 0 */
 #define IXGBE_STATUS_LAN_ID_1   0x00000004 /* LAN ID 1 */
 
 /* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP4 0x00000001 /* SDP4 Data Value */
-#define IXGBE_ESDP_SDP5 0x00000002 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP0 0x00000001
+#define IXGBE_ESDP_SDP1 0x00000002
+#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
+#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
 #define IXGBE_ESDP_SDP4_DIR     0x00000004 /* SDP4 IO direction */
-#define IXGBE_ESDP_SDP5_DIR     0x00000008 /* SDP5 IO direction */
+#define IXGBE_ESDP_SDP5_DIR     0x00002000 /* SDP5 IO direction */
 
 /* LEDCTL Bit Masks */
 #define IXGBE_LED_IVRT_BASE      0x00000040
@@ -719,6 +1237,7 @@
 #define IXGBE_LED_OFF           0xF
 
 /* AUTOC Bit Masks */
+#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000
 #define IXGBE_AUTOC_KX4_SUPP    0x80000000
 #define IXGBE_AUTOC_KX_SUPP     0x40000000
 #define IXGBE_AUTOC_PAUSE       0x30000000
@@ -727,9 +1246,17 @@
 #define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
 #define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000
 #define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000
+#define IXGBE_AUTOC_FECA        0x00040000
+#define IXGBE_AUTOC_FECR        0x00020000
+#define IXGBE_AUTOC_KR_SUPP     0x00010000
 #define IXGBE_AUTOC_AN_RESTART  0x00001000
 #define IXGBE_AUTOC_FLU         0x00000001
 #define IXGBE_AUTOC_LMS_SHIFT   13
+#define IXGBE_AUTOC_LMS_10G_SERIAL      (0x3 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR       (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_SGMII_1G_100M   (0x5 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT)
 #define IXGBE_AUTOC_LMS_MASK            (0x7 << IXGBE_AUTOC_LMS_SHIFT)
 #define IXGBE_AUTOC_LMS_1G_LINK_NO_AN   (0x0 << IXGBE_AUTOC_LMS_SHIFT)
 #define IXGBE_AUTOC_LMS_10G_LINK_NO_AN  (0x1 << IXGBE_AUTOC_LMS_SHIFT)
@@ -738,15 +1265,24 @@
 #define IXGBE_AUTOC_LMS_KX4_AN_1G_AN    (0x6 << IXGBE_AUTOC_LMS_SHIFT)
 #define IXGBE_AUTOC_LMS_ATTACH_TYPE     (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 
-#define IXGBE_AUTOC_1G_PMA_PMD         0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD        0x00000180
-#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
-#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
+#define IXGBE_AUTOC_1G_PMA_PMD_MASK    0x00000200
+#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT   9
+#define IXGBE_AUTOC_10G_PMA_PMD_MASK   0x00000180
+#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT  7
 #define IXGBE_AUTOC_10G_XAUI   (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 #define IXGBE_AUTOC_10G_KX4    (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 #define IXGBE_AUTOC_10G_CX4    (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 #define IXGBE_AUTOC_1G_BX      (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
 #define IXGBE_AUTOC_1G_KX      (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_SFI     (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_KX_BX   (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC2_UPPER_MASK  0xFFFF0000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK  0x00030000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16
+#define IXGBE_AUTOC2_10G_KR  (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
 
 /* LINKS Bit Masks */
 #define IXGBE_LINKS_KX_AN_COMP  0x80000000
@@ -756,6 +1292,7 @@
 #define IXGBE_LINKS_RX_MODE     0x06000000
 #define IXGBE_LINKS_TX_MODE     0x01800000
 #define IXGBE_LINKS_XGXS_EN     0x00400000
+#define IXGBE_LINKS_SGMII_EN    0x02000000
 #define IXGBE_LINKS_PCS_1G_EN   0x00200000
 #define IXGBE_LINKS_1G_AN_EN    0x00100000
 #define IXGBE_LINKS_KX_AN_IDLE  0x00080000
@@ -765,9 +1302,35 @@
 #define IXGBE_LINKS_TL_FAULT    0x00001000
 #define IXGBE_LINKS_SIGNAL      0x00000F00
 
+#define IXGBE_LINKS_SPEED_82599     0x30000000
+#define IXGBE_LINKS_SPEED_10G_82599 0x30000000
+#define IXGBE_LINKS_SPEED_1G_82599  0x20000000
+#define IXGBE_LINKS_SPEED_100_82599 0x10000000
 #define IXGBE_LINK_UP_TIME      90 /* 9.0 Seconds */
 #define IXGBE_AUTO_NEG_TIME     45 /* 4.5 Seconds */
 
+#define FIBER_LINK_UP_LIMIT     50
+
+/* PCS1GLSTA Bit Masks */
+#define IXGBE_PCS1GLSTA_LINK_OK         1
+#define IXGBE_PCS1GLSTA_SYNK_OK         0x10
+#define IXGBE_PCS1GLSTA_AN_COMPLETE     0x10000
+#define IXGBE_PCS1GLSTA_AN_PAGE_RX      0x20000
+#define IXGBE_PCS1GLSTA_AN_TIMED_OUT    0x40000
+#define IXGBE_PCS1GLSTA_AN_REMOTE_FAULT 0x80000
+#define IXGBE_PCS1GLSTA_AN_ERROR_RWS    0x100000
+
+#define IXGBE_PCS1GANA_SYM_PAUSE        0x80
+#define IXGBE_PCS1GANA_ASM_PAUSE        0x100
+
+/* PCS1GLCTL Bit Masks */
+#define IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN  0x00040000 /* PCS 1G autoneg to en */
+#define IXGBE_PCS1GLCTL_FLV_LINK_UP     1
+#define IXGBE_PCS1GLCTL_FORCE_LINK      0x20
+#define IXGBE_PCS1GLCTL_LOW_LINK_LATCH  0x40
+#define IXGBE_PCS1GLCTL_AN_ENABLE       0x10000
+#define IXGBE_PCS1GLCTL_AN_RESTART      0x20000
+
 /* SW Semaphore Register bitmasks */
 #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
 #define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
@@ -819,6 +1382,11 @@
 #define IXGBE_FW_PTR            0x0F
 #define IXGBE_PBANUM0_PTR       0x15
 #define IXGBE_PBANUM1_PTR       0x16
+#define IXGBE_PCIE_MSIX_82599_CAPS  0x72
+#define IXGBE_PCIE_MSIX_82598_CAPS  0x62
+
+/* MSI-X capability fields masks */
+#define IXGBE_PCIE_MSIX_TBL_SZ_MASK     0x7FF
 
 /* Legacy EEPROM word offsets */
 #define IXGBE_ISCSI_BOOT_CAPS           0x0033
@@ -867,6 +1435,8 @@
 #define IXGBE_PCI_LINK_SPEED      0xF
 #define IXGBE_PCI_LINK_SPEED_2500 0x1
 #define IXGBE_PCI_LINK_SPEED_5000 0x2
+#define IXGBE_PCI_HEADER_TYPE_REGISTER  0x0E
+#define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80
 
 /* Number of 100 microseconds we wait for PCI Express master disable */
 #define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
@@ -919,6 +1489,7 @@
 #define IXGBE_RXCTRL_RXEN       0x00000001  /* Enable Receiver */
 #define IXGBE_RXCTRL_DMBYPS     0x00000002  /* Descriptor Monitor Bypass */
 #define IXGBE_RXDCTL_ENABLE     0x02000000  /* Enable specific Rx Queue */
+#define IXGBE_RXDCTL_VME        0x40000000  /* VLAN mode enable */
 
 #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
 #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
@@ -929,9 +1500,23 @@
 /* Receive Priority Flow Control Enable */
 #define IXGBE_FCTRL_RPFCE 0x00004000
 #define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
+#define IXGBE_MFLCN_PMCF        0x00000001 /* Pass MAC Control Frames */
+#define IXGBE_MFLCN_DPF         0x00000002 /* Discard Pause Frame */
+#define IXGBE_MFLCN_RPFCE       0x00000004 /* Receive Priority FC Enable */
+#define IXGBE_MFLCN_RFCE        0x00000008 /* Receive FC Enable */
 
 /* Multiple Receive Queue Control */
 #define IXGBE_MRQC_RSSEN                 0x00000001  /* RSS Enable */
+#define IXGBE_MRQC_MRQE_MASK                    0xF /* Bits 3:0 */
+#define IXGBE_MRQC_RT8TCEN               0x00000002 /* 8 TC no RSS */
+#define IXGBE_MRQC_RT4TCEN               0x00000003 /* 4 TC no RSS */
+#define IXGBE_MRQC_RTRSS8TCEN            0x00000004 /* 8 TC w/ RSS */
+#define IXGBE_MRQC_RTRSS4TCEN            0x00000005 /* 4 TC w/ RSS */
+#define IXGBE_MRQC_VMDQEN                0x00000008 /* VMDq2 64 pools no RSS */
+#define IXGBE_MRQC_VMDQRSS32EN           0x0000000A /* VMDq2 32 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRSS64EN           0x0000000B /* VMDq2 64 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRT8TCEN           0x0000000C /* VMDq2/RT 16 pool 8 TC */
+#define IXGBE_MRQC_VMDQRT4TCEN           0x0000000D /* VMDq2/RT 32 pool 4 TC */
 #define IXGBE_MRQC_RSS_FIELD_MASK        0xFFFF0000
 #define IXGBE_MRQC_RSS_FIELD_IPV4_TCP    0x00010000
 #define IXGBE_MRQC_RSS_FIELD_IPV4        0x00020000
@@ -942,6 +1527,12 @@
 #define IXGBE_MRQC_RSS_FIELD_IPV4_UDP    0x00400000
 #define IXGBE_MRQC_RSS_FIELD_IPV6_UDP    0x00800000
 #define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
+#define IXGBE_MRQC_L3L4TXSWEN            0x00008000
+
+/* Queue Drop Enable */
+#define IXGBE_QDE_ENABLE     0x00000001
+#define IXGBE_QDE_IDX_MASK   0x00007F00
+#define IXGBE_QDE_IDX_SHIFT           8
 
 #define IXGBE_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
 #define IXGBE_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
@@ -953,10 +1544,25 @@
 #define IXGBE_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
 #define IXGBE_TXD_STAT_DD    0x00000001 /* Descriptor Done */
 
+#define IXGBE_RXDADV_IPSEC_STATUS_SECP                  0x00020000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL       0x08000000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH         0x10000000
+#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED            0x18000000
+#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK               0x18000000
+/* Multiple Transmit Queue Command Register */
+#define IXGBE_MTQC_RT_ENA       0x1 /* DCB Enable */
+#define IXGBE_MTQC_VT_ENA       0x2 /* VMDQ2 Enable */
+#define IXGBE_MTQC_64Q_1PB      0x0 /* 64 queues 1 pack buffer */
+#define IXGBE_MTQC_64VF         0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_8TC_8TQ      0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
+
 /* Receive Descriptor bit definitions */
 #define IXGBE_RXD_STAT_DD       0x01    /* Descriptor Done */
 #define IXGBE_RXD_STAT_EOP      0x02    /* End of Packet */
+#define IXGBE_RXD_STAT_FLM      0x04    /* FDir Match */
 #define IXGBE_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define IXGBE_RXDADV_NEXTP_MASK   0x000FFFF0 /* Next Descriptor Index */
+#define IXGBE_RXDADV_NEXTP_SHIFT  0x00000004
 #define IXGBE_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
 #define IXGBE_RXD_STAT_L4CS     0x20    /* L4 xsum calculated */
 #define IXGBE_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
@@ -965,6 +1571,10 @@
 #define IXGBE_RXD_STAT_VEXT     0x200   /* 1st VLAN found */
 #define IXGBE_RXD_STAT_UDPV     0x400   /* Valid UDP checksum */
 #define IXGBE_RXD_STAT_DYNINT   0x800   /* Pkt caused INT via DYNINT */
+#define IXGBE_RXD_STAT_LLINT    0x800   /* Pkt caused Low Latency Interrupt */
+#define IXGBE_RXD_STAT_TS       0x10000 /* Time Stamp */
+#define IXGBE_RXD_STAT_SECP     0x20000 /* Security Processing */
+#define IXGBE_RXD_STAT_LB       0x40000 /* Loopback Status */
 #define IXGBE_RXD_STAT_ACK      0x8000  /* ACK Packet indication */
 #define IXGBE_RXD_ERR_CE        0x01    /* CRC Error */
 #define IXGBE_RXD_ERR_LE        0x02    /* Length Error */
@@ -973,6 +1583,8 @@
 #define IXGBE_RXD_ERR_USE       0x20    /* Undersize Error */
 #define IXGBE_RXD_ERR_TCPE      0x40    /* TCP/UDP Checksum Error */
 #define IXGBE_RXD_ERR_IPE       0x80    /* IP Checksum Error */
+#define IXGBE_RXDADV_ERR_MASK           0xfff00000 /* RDESC.ERRORS mask */
+#define IXGBE_RXDADV_ERR_SHIFT          20         /* RDESC.ERRORS shift */
 #define IXGBE_RXDADV_ERR_HBO    0x00800000 /*Header Buffer Overflow */
 #define IXGBE_RXDADV_ERR_CE     0x01000000 /* CRC Error */
 #define IXGBE_RXDADV_ERR_LE     0x02000000 /* Length Error */
@@ -987,9 +1599,23 @@
 #define IXGBE_RXD_CFI_MASK      0x1000  /* CFI is bit 12 */
 #define IXGBE_RXD_CFI_SHIFT     12
 
+#define IXGBE_RXDADV_STAT_DD            IXGBE_RXD_STAT_DD  /* Done */
+#define IXGBE_RXDADV_STAT_EOP           IXGBE_RXD_STAT_EOP /* End of Packet */
+#define IXGBE_RXDADV_STAT_FLM           IXGBE_RXD_STAT_FLM /* FDir Match */
+#define IXGBE_RXDADV_STAT_VP            IXGBE_RXD_STAT_VP  /* IEEE VLAN Pkt */
+#define IXGBE_RXDADV_STAT_MASK          0x000fffff /* Stat/NEXTP: bit 0-19 */
+
+/* PSRTYPE bit definitions */
+#define IXGBE_PSRTYPE_TCPHDR    0x00000010
+#define IXGBE_PSRTYPE_UDPHDR    0x00000020
+#define IXGBE_PSRTYPE_IPV4HDR   0x00000100
+#define IXGBE_PSRTYPE_IPV6HDR   0x00000200
 
 /* SRRCTL bit definitions */
 #define IXGBE_SRRCTL_BSIZEPKT_SHIFT     10     /* so many KBs */
+#define IXGBE_SRRCTL_RDMTS_SHIFT        22
+#define IXGBE_SRRCTL_RDMTS_MASK         0x01C00000
+#define IXGBE_SRRCTL_DROP_EN            0x10000000
 #define IXGBE_SRRCTL_BSIZEPKT_MASK      0x0000007F
 #define IXGBE_SRRCTL_BSIZEHDR_MASK      0x00003F00
 #define IXGBE_SRRCTL_DESCTYPE_LEGACY    0x00000000
@@ -1004,6 +1630,7 @@
 
 #define IXGBE_RXDADV_RSSTYPE_MASK       0x0000000F
 #define IXGBE_RXDADV_PKTTYPE_MASK       0x0000FFF0
+#define IXGBE_RXDADV_PKTTYPE_MASK_EX    0x0001FFF0
 #define IXGBE_RXDADV_HDRBUFLEN_MASK     0x00007FE0
 #define IXGBE_RXDADV_HDRBUFLEN_SHIFT    5
 #define IXGBE_RXDADV_SPLITHEADER_EN     0x00001000
@@ -1031,6 +1658,20 @@
 #define IXGBE_RXDADV_PKTTYPE_UDP        0x00000200 /* UDP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_SCTP       0x00000400 /* SCTP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_NFS        0x00000800 /* NFS hdr present */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP  0x00001000 /* IPSec ESP */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH   0x00002000 /* IPSec AH */
+#define IXGBE_RXDADV_PKTTYPE_LINKSEC    0x00004000 /* LinkSec Encap */
+#define IXGBE_RXDADV_PKTTYPE_ETQF       0x00008000 /* PKTTYPE is ETQF index */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK  0x00000070 /* ETQF has 8 indices */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4          /* Right-shift 4 bits */
+
+/* Security Processing bit Indication */
+#define IXGBE_RXDADV_LNKSEC_STATUS_SECP         0x00020000
+#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH   0x08000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR  0x10000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK      0x18000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG       0x18000000
+
 /* Masks to determine if packets should be dropped due to frame errors */
 #define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
                                       IXGBE_RXD_ERR_CE | \
@@ -1060,6 +1701,14 @@
 #define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT  0x000D /* Priority in upper 3 of 16 */
 #define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT  IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
 
+/* Little Endian defines */
+#ifndef __le32
+#define __le32  u32
+#endif
+#ifndef __le64
+#define __le64  u64
+
+#endif
 
 /* Transmit Descriptor - Legacy */
 struct ixgbe_legacy_tx_desc {
@@ -1147,6 +1796,9 @@ struct ixgbe_adv_tx_context_desc {
 
 /* Adv Transmit Descriptor Config Masks */
 #define IXGBE_ADVTXD_DTALEN_MASK      0x0000FFFF /* Data buf length(bytes) */
+#define IXGBE_ADVTXD_MAC_LINKSEC      0x00040000 /* Insert LinkSec */
+#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK   0x000003FF /* IPSec SA index */
+#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK    0x000001FF /* IPSec ESP length */
 #define IXGBE_ADVTXD_DTYP_MASK  0x00F00000 /* DTYP mask */
 #define IXGBE_ADVTXD_DTYP_CTXT  0x00200000 /* Advanced Context Desc */
 #define IXGBE_ADVTXD_DTYP_DATA  0x00300000 /* Advanced Data Descriptor */
@@ -1181,6 +1833,9 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_TUCMD_L4T_TCP   0x00000800  /* L4 Packet TYPE of TCP */
 #define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */
 #define IXGBE_ADVTXD_TUCMD_MKRREQ    0x00002000 /*Req requires Markers and CRC*/
+#define IXGBE_ADVTXD_POPTS_IPSEC      0x00000400 /* IPSec offload request */
+#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
+#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
 #define IXGBE_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
 #define IXGBE_ADVTXD_MSS_SHIFT       16  /* Adv ctxt MSS shift */
 
@@ -1194,6 +1849,12 @@ typedef u32 ixgbe_link_speed;
 #define IXGBE_LINK_SPEED_10GB_FULL 0x0080
 #define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
                                         IXGBE_LINK_SPEED_10GB_FULL)
+#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \
+                                        IXGBE_LINK_SPEED_1GB_FULL | \
+                                        IXGBE_LINK_SPEED_10GB_FULL)
+
+#define IXGBE_PCIE_DEV_CTRL_2 0xC8
+#define PCIE_COMPL_TO_VALUE 0x05
 
 /* Physical layer type */
 typedef u32 ixgbe_physical_layer;
@@ -1210,7 +1871,6 @@ typedef u32 ixgbe_physical_layer;
 #define IXGBE_PHYSICAL_LAYER_1000BASE_KX  0x0200
 #define IXGBE_PHYSICAL_LAYER_1000BASE_BX  0x0400
 
-
 enum ixgbe_eeprom_type {
 	ixgbe_eeprom_uninitialized = 0,
 	ixgbe_eeprom_spi,
@@ -1220,12 +1880,14 @@ enum ixgbe_eeprom_type {
 enum ixgbe_mac_type {
 	ixgbe_mac_unknown = 0,
 	ixgbe_mac_82598EB,
+	ixgbe_mac_82599EB,
 	ixgbe_num_macs
 };
 
 enum ixgbe_phy_type {
 	ixgbe_phy_unknown = 0,
 	ixgbe_phy_tn,
+	ixgbe_phy_cu_unknown,
 	ixgbe_phy_qt,
 	ixgbe_phy_xaui,
 	ixgbe_phy_nl,
@@ -1234,22 +1896,31 @@ enum ixgbe_phy_type {
 	ixgbe_phy_sfp_avago,
 	ixgbe_phy_sfp_ftl,
 	ixgbe_phy_sfp_unknown,
+	ixgbe_phy_sfp_intel,
 	ixgbe_phy_generic
 };
 
 /*
  * SFP+ module type IDs:
  *
- * ID	Module Type
+ * ID   Module Type
  * =============
- * 0	SFP_DA_CU
- * 1	SFP_SR
- * 2	SFP_LR
+ * 0    SFP_DA_CU
+ * 1    SFP_SR
+ * 2    SFP_LR
+ * 3    SFP_DA_CU_CORE0 - 82599-specific
+ * 4    SFP_DA_CU_CORE1 - 82599-specific
+ * 5    SFP_SR/LR_CORE0 - 82599-specific
+ * 6    SFP_SR/LR_CORE1 - 82599-specific
  */
 enum ixgbe_sfp_type {
 	ixgbe_sfp_type_da_cu = 0,
 	ixgbe_sfp_type_sr = 1,
 	ixgbe_sfp_type_lr = 2,
+	ixgbe_sfp_type_da_cu_core0 = 3,
+	ixgbe_sfp_type_da_cu_core1 = 4,
+	ixgbe_sfp_type_srlr_core0 = 5,
+	ixgbe_sfp_type_srlr_core1 = 6,
 	ixgbe_sfp_type_not_present = 0xFFFE,
 	ixgbe_sfp_type_unknown = 0xFFFF
 };
@@ -1263,14 +1934,51 @@ enum ixgbe_media_type {
 };
 
 /* Flow Control Settings */
-enum ixgbe_fc_type {
+enum ixgbe_fc_mode {
 	ixgbe_fc_none = 0,
 	ixgbe_fc_rx_pause,
 	ixgbe_fc_tx_pause,
 	ixgbe_fc_full,
+#ifdef CONFIG_DCB
+	ixgbe_fc_pfc,
+#endif
 	ixgbe_fc_default
 };
 
+/* PCI bus types */
+enum ixgbe_bus_type {
+	ixgbe_bus_type_unknown = 0,
+	ixgbe_bus_type_pci,
+	ixgbe_bus_type_pcix,
+	ixgbe_bus_type_pci_express,
+	ixgbe_bus_type_reserved
+};
+
+/* PCI bus speeds */
+enum ixgbe_bus_speed {
+	ixgbe_bus_speed_unknown = 0,
+	ixgbe_bus_speed_33,
+	ixgbe_bus_speed_66,
+	ixgbe_bus_speed_100,
+	ixgbe_bus_speed_120,
+	ixgbe_bus_speed_133,
+	ixgbe_bus_speed_2500,
+	ixgbe_bus_speed_5000,
+	ixgbe_bus_speed_reserved
+};
+
+/* PCI bus widths */
+enum ixgbe_bus_width {
+	ixgbe_bus_width_unknown = 0,
+	ixgbe_bus_width_pcie_x1,
+	ixgbe_bus_width_pcie_x2,
+	ixgbe_bus_width_pcie_x4 = 4,
+	ixgbe_bus_width_pcie_x8 = 8,
+	ixgbe_bus_width_32,
+	ixgbe_bus_width_64,
+	ixgbe_bus_width_reserved
+};
+
 struct ixgbe_addr_filter_info {
 	u32 num_mc_addrs;
 	u32 rar_used_count;
@@ -1280,6 +1988,16 @@ struct ixgbe_addr_filter_info {
 	bool user_set_promisc;
 };
 
+/* Bus parameters */
+struct ixgbe_bus_info {
+	enum ixgbe_bus_speed speed;
+	enum ixgbe_bus_width width;
+	enum ixgbe_bus_type type;
+
+	u16 func;
+	u16 lan_id;
+};
+
 /* Flow control parameters */
 struct ixgbe_fc_info {
 	u32 high_water; /* Flow Control High-water */
@@ -1287,8 +2005,9 @@ struct ixgbe_fc_info {
 	u16 pause_time; /* Flow Control Pause timer */
 	bool send_xon; /* Flow control send XON */
 	bool strict_ieee; /* Strict IEEE mode */
-	enum ixgbe_fc_type type; /* Type of flow control */
-	enum ixgbe_fc_type original_type;
+	bool disable_fc_autoneg; /* Turn off autoneg FC mode */
+	enum ixgbe_fc_mode current_mode; /* FC mode in effect */
+	enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
 };
 
 /* Statistics counters collected by the MAC */
@@ -1348,6 +2067,14 @@ struct ixgbe_hw_stats {
 	u64 qptc[16];
 	u64 qbrc[16];
 	u64 qbtc[16];
+	u64 qprdc[16];
+	u64 pxon2offc[8];
+	u64 fdirustat_add;
+	u64 fdirustat_remove;
+	u64 fdirfstat_fadd;
+	u64 fdirfstat_fremove;
+	u64 fdirmatch;
+	u64 fdirmiss;
 };
 
 /* forward declaration */
@@ -1372,12 +2099,15 @@ struct ixgbe_mac_operations {
 	s32 (*start_hw)(struct ixgbe_hw *);
 	s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
 	enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
-	s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+	u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
 	s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
 	s32 (*stop_adapter)(struct ixgbe_hw *);
 	s32 (*get_bus_info)(struct ixgbe_hw *);
+	void (*set_lan_id)(struct ixgbe_hw *);
 	s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
 	s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+	s32 (*setup_sfp)(struct ixgbe_hw *);
+	s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
 	/* Link */
 	s32 (*setup_link)(struct ixgbe_hw *);
@@ -1433,7 +2163,7 @@ struct ixgbe_phy_operations {
 struct ixgbe_eeprom_info {
 	struct ixgbe_eeprom_operations  ops;
 	enum ixgbe_eeprom_type          type;
-	u32				semaphore_delay;
+	u32                             semaphore_delay;
 	u16                             word_size;
 	u16                             address_bits;
 };
@@ -1449,11 +2179,12 @@ struct ixgbe_mac_info {
 	u32                             num_rar_entries;
 	u32                             max_tx_queues;
 	u32                             max_rx_queues;
-	u32                             link_attach_type;
-	u32                             link_mode_select;
-	bool                            link_settings_loaded;
+	u32                             max_msix_vectors;
+	u32                             orig_autoc;
+	u32                             orig_autoc2;
+	bool                            orig_link_settings_stored;
 	bool                            autoneg;
-	bool                            autoneg_failed;
+	bool                            autoneg_succeeded;
 };
 
 struct ixgbe_phy_info {
@@ -1467,6 +2198,7 @@ struct ixgbe_phy_info {
 	bool                            reset_disable;
 	ixgbe_autoneg_advertised        autoneg_advertised;
 	bool                            autoneg_wait_to_complete;
+	bool                            multispeed_fiber;
 };
 
 struct ixgbe_hw {
@@ -1477,6 +2209,7 @@ struct ixgbe_hw {
 	struct ixgbe_fc_info		fc;
 	struct ixgbe_phy_info		phy;
 	struct ixgbe_eeprom_info	eeprom;
+	struct ixgbe_bus_info		bus;
 	u16				device_id;
 	u16				vendor_id;
 	u16				subsystem_device_id;
@@ -1515,6 +2248,7 @@ struct ixgbe_info {
 #define IXGBE_ERR_I2C                           -18
 #define IXGBE_ERR_SFP_NOT_SUPPORTED             -19
 #define IXGBE_ERR_SFP_NOT_PRESENT               -20
+#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT       -21
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 #endif /* _IXGBE_TYPE_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixgbe/Makefile linux-libre-2.6.30-gnu1/drivers/net/ixgbe/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/ixgbe/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixgbe/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2007 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,
@@ -33,6 +33,7 @@
 obj-$(CONFIG_IXGBE) += ixgbe.o
 
 ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
-              ixgbe_82598.o ixgbe_phy.o
+              ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o
 
-ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o ixgbe_dcb_nl.o
+ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
+                              ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ixp2000/ixpdev.c linux-libre-2.6.30-gnu1/drivers/net/ixp2000/ixpdev.c
--- linux-libre-2.6.29-gnu1/drivers/net/ixp2000/ixpdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ixp2000/ixpdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -141,7 +141,7 @@ static int ixpdev_poll(struct napi_struc
 			break;
 	} while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
 
-	netif_rx_complete(napi);
+	napi_complete(napi);
 	ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
 
 	return rx;
@@ -204,7 +204,7 @@ static irqreturn_t ixpdev_interrupt(int
 
 		ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
 		if (likely(napi_schedule_prep(&ip->napi))) {
-			__netif_rx_schedule(&ip->napi);
+			__napi_schedule(&ip->napi);
 		} else {
 			printk(KERN_CRIT "ixp2000: irq while polling!!\n");
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/jazzsonic.c linux-libre-2.6.30-gnu1/drivers/net/jazzsonic.c
--- linux-libre-2.6.29-gnu1/drivers/net/jazzsonic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/jazzsonic.c	2009-06-09 23:05:27.000000000 -0400
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct ne
 	if (sonic_debug  &&  version_printed++ == 0)
 		printk(version);
 
-	printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr);
+	printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
+	       dev_name(lp->device), dev->base_addr);
 
 	/*
 	 * Put the sonic into software reset, then
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct ne
 	if ((lp->descriptors = dma_alloc_coherent(lp->device,
 				SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
 				&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+		       dev_name(lp->device));
 		goto out;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/jme.c linux-libre-2.6.30-gnu1/drivers/net/jme.c
--- linux-libre-2.6.29-gnu1/drivers/net/jme.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/jme.c	2009-06-09 23:05:27.000000000 -0400
@@ -429,10 +429,9 @@ jme_check_link(struct net_device *netdev
 
 		jme->phylink = phylink;
 
-		ghc = jme->reg_ghc & ~(GHC_SPEED_10M |
-					GHC_SPEED_100M |
-					GHC_SPEED_1000M |
-					GHC_DPX);
+		ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX |
+				GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE |
+				GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY);
 		switch (phylink & PHY_LINK_SPEED_MASK) {
 		case PHY_LINK_SPEED_10M:
 			ghc |= GHC_SPEED_10M |
@@ -1834,7 +1833,7 @@ jme_tx_vlan(struct sk_buff *skb, __le16
 }
 
 static int
-jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
+jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
 {
 	struct jme_ring *txring = jme->txring;
 	struct txdesc *txdesc;
@@ -1864,6 +1863,7 @@ jme_fill_first_tx_desc(struct jme_adapte
 	if (jme_tx_tso(skb, &txdesc->desc1.mss, &flags))
 		jme_tx_csum(jme, skb, &flags);
 	jme_tx_vlan(skb, &txdesc->desc1.vlan, &flags);
+	jme_map_tx_skb(jme, skb, idx);
 	txdesc->desc1.flags = flags;
 	/*
 	 * Set tx buffer info after telling NIC to send
@@ -1933,8 +1933,7 @@ jme_start_xmit(struct sk_buff *skb, stru
 		return NETDEV_TX_BUSY;
 	}
 
-	jme_map_tx_skb(jme, skb, idx);
-	jme_fill_first_tx_desc(jme, skb, idx);
+	jme_fill_tx_desc(jme, skb, idx);
 
 	jwrite32(jme, JME_TXCS, jme->reg_txcs |
 				TXCS_SELECT_QUEUE0 |
@@ -2591,8 +2590,18 @@ static const struct ethtool_ops jme_etht
 static int
 jme_pci_dma64(struct pci_dev *pdev)
 {
-	if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
-		if (!pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
+	if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+		if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
+			return 1;
+
+	if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(40)))
+		if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)))
+			return 1;
+
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
+		if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
 			return 0;
 
 	return -1;
@@ -2857,7 +2866,11 @@ jme_init_one(struct pci_dev *pdev,
 		goto err_out_free_shadow;
 	}
 
-	msg_probe(jme, "JMC250 gigabit%s ver:%x rev:%x macaddr:%pM\n",
+	msg_probe(jme, "%s%s ver:%x rev:%x macaddr:%pM\n",
+		(jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ?
+			"JMC250 Gigabit Ethernet" :
+			(jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260) ?
+				"JMC260 Fast Ethernet" : "Unknown",
 		(jme->fpgaver != 0) ? " (FPGA)" : "",
 		(jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev,
 		jme->rev, netdev->dev_addr);
@@ -3003,7 +3016,7 @@ static struct pci_driver jme_driver = {
 static int __init
 jme_init_module(void)
 {
-	printk(KERN_INFO PFX "JMicron JMC250 gigabit ethernet "
+	printk(KERN_INFO PFX "JMicron JMC2XX ethernet "
 	       "driver version %s\n", DRV_VERSION);
 	return pci_register_driver(&jme_driver);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/jme.h linux-libre-2.6.30-gnu1/drivers/net/jme.h
--- linux-libre-2.6.29-gnu1/drivers/net/jme.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/jme.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,7 @@
 #define __JME_H_INCLUDED__
 
 #define DRV_NAME	"jme"
-#define DRV_VERSION	"1.0.3"
+#define DRV_VERSION	"1.0.4"
 #define PFX		DRV_NAME ": "
 
 #define PCI_DEVICE_ID_JMICRON_JMC250	0x0250
@@ -398,15 +398,15 @@ struct jme_ring {
 #define JME_NAPI_WEIGHT(w) int w
 #define JME_NAPI_WEIGHT_VAL(w) w
 #define JME_NAPI_WEIGHT_SET(w, r)
-#define JME_RX_COMPLETE(dev, napis) netif_rx_complete(napis)
+#define JME_RX_COMPLETE(dev, napis) napi_complete(napis)
 #define JME_NAPI_ENABLE(priv) napi_enable(&priv->napi);
 #define JME_NAPI_DISABLE(priv) \
 	if (!napi_disable_pending(&priv->napi)) \
 		napi_disable(&priv->napi);
 #define JME_RX_SCHEDULE_PREP(priv) \
-	netif_rx_schedule_prep(&priv->napi)
+	napi_schedule_prep(&priv->napi)
 #define JME_RX_SCHEDULE(priv) \
-	__netif_rx_schedule(&priv->napi);
+	__napi_schedule(&priv->napi);
 
 /*
  * Jmac Adapter Private data
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/Kconfig linux-libre-2.6.30-gnu1/drivers/net/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -26,6 +26,15 @@ menuconfig NETDEVICES
 # that for each of the symbols.
 if NETDEVICES
 
+config COMPAT_NET_DEV_OPS
+       default y
+       bool "Enable older network device API compatibility"
+       ---help---
+          This option enables kernel compatibility with older network devices
+          that do not use net_device_ops interface.
+
+	  If unsure, say Y.
+
 config IFB
 	tristate "Intermediate Functional Block support"
 	depends on NET_CLS_ACT
@@ -963,6 +972,16 @@ config ENC28J60_WRITEVERIFY
 	  Enable the verify after the buffer write useful for debugging purpose.
 	  If unsure, say N.
 
+config ETHOC
+	tristate "OpenCores 10/100 Mbps Ethernet MAC support"
+	depends on NET_ETHERNET && HAS_IOMEM
+	select MII
+	select PHYLIB
+	select CRC32
+	select BITREVERSE
+	help
+	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
+
 config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
@@ -1840,10 +1859,10 @@ config 68360_ENET
 
 config FEC
 	bool "FEC ethernet controller (of ColdFire CPUs)"
-	depends on M523x || M527x || M5272 || M528x || M520x || M532x
+	depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
-	  controller on some Motorola ColdFire processors.
+	  controller on some Motorola ColdFire and Freescale i.MX processors.
 
 config FEC2
 	bool "Second FEC ethernet controller (on some ColdFire CPUs)"
@@ -2030,15 +2049,6 @@ config IGB
          To compile this driver as a module, choose M here. The module
          will be called igb.
 
-config IGB_LRO 
-	bool "Use software LRO"
-	depends on IGB && INET
-	select INET_LRO
-	---help---
-	  Say Y here if you want to use large receive offload. 
-
-	  If in doubt, say N.
-
 config IGB_DCA
 	bool "Direct Cache Access (DCA) Support"
 	default y
@@ -2048,6 +2058,27 @@ config IGB_DCA
 	  driver.  DCA is a method for warming the CPU cache before data
 	  is used, with the intent of lessening the impact of cache misses.
 
+config IGBVF
+       tristate "Intel(R) 82576 Virtual Function Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) 82576 virtual functions.  For more
+         information on how to identify your adapter, go to the Adapter &
+         Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here. The module
+         will be called igbvf.
+
 source "drivers/net/ixp2000/Kconfig"
 
 config MYRI_SBUS
@@ -2226,7 +2257,7 @@ config BNX2
 	tristate "Broadcom NetXtremeII support"
 	depends on PCI
 	select CRC32
-	select ZLIB_INFLATE
+	select FW_LOADER
 	help
 	  This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
 
@@ -2284,9 +2315,17 @@ config GELIC_WIRELESS_OLD_PSK_INTERFACE
 
           If unsure, say N.
 
+config FSL_PQ_MDIO
+	tristate "Freescale PQ MDIO"
+	depends on FSL_SOC
+	select PHYLIB
+	help
+	  This driver supports the MDIO bus used by the gianfar and UCC drivers.
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on FSL_SOC
+	select FSL_PQ_MDIO
 	select PHYLIB
 	select CRC32
 	help
@@ -2296,6 +2335,7 @@ config GIANFAR
 config UCC_GETH
 	tristate "Freescale QE Gigabit Ethernet"
 	depends on QUICC_ENGINE
+	select FSL_PQ_MDIO
 	select PHYLIB
 	help
 	  This driver supports the Gigabit Ethernet mode of the QUICC Engine,
@@ -2312,6 +2352,7 @@ config UGETH_TX_ON_DEMAND
 config MV643XX_ETH
 	tristate "Marvell Discovery (643XX) and Orion ethernet support"
 	depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
+	select INET_LRO
 	select PHYLIB
 	help
 	  This driver supports the gigabit ethernet MACs in the
@@ -2430,7 +2471,6 @@ config CHELSIO_T3
 	tristate "Chelsio Communications T3 10Gb Ethernet support"
 	depends on CHELSIO_T3_DEPENDS
 	select FW_LOADER
-	select INET_LRO
 	help
 	  This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
 	  adapters.
@@ -2466,7 +2506,6 @@ config ENIC
 config IXGBE
 	tristate "Intel(R) 10GbE PCI Express adapters support"
 	depends on PCI && INET
-	select INET_LRO
 	---help---
 	  This driver supports Intel(R) 10GbE PCI Express family of
 	  adapters.  For more information on how to identify your adapter, go
@@ -2531,6 +2570,23 @@ config S2IO
 	  More specific information on configuring the driver is in 
 	  <file:Documentation/networking/s2io.txt>.
 
+config VXGE
+	tristate "Neterion X3100 Series 10GbE PCIe Server Adapter"
+	depends on PCI && INET
+	---help---
+	  This driver supports Neterion Inc's X3100 Series 10 GbE PCIe
+	  I/O Virtualized Server Adapter.
+	  More specific information on configuring the driver is in
+	  <file:Documentation/networking/vxge.txt>.
+
+config VXGE_DEBUG_TRACE_ALL
+	bool "Enabling All Debug trace statments in driver"
+	default n
+	depends on VXGE
+	---help---
+	  Say Y here if you want to enabling all the debug trace statements in
+	  driver. By  default only few debug trace statements are enabled.
+
 config MYRI10GE
 	tristate "Myricom Myri-10G Ethernet support"
 	depends on PCI && INET
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/korina.c linux-libre-2.6.30-gnu1/drivers/net/korina.c
--- linux-libre-2.6.29-gnu1/drivers/net/korina.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/korina.c	2009-06-09 23:05:27.000000000 -0400
@@ -334,7 +334,7 @@ static irqreturn_t korina_rx_dma_interru
 				DMA_STAT_HALT | DMA_STAT_ERR),
 				&lp->rx_dma_regs->dmasm);
 
-		netif_rx_schedule(&lp->napi);
+		napi_schedule(&lp->napi);
 
 		if (dmas & DMA_STAT_ERR)
 			printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
@@ -468,7 +468,7 @@ static int korina_poll(struct napi_struc
 
 	work_done = korina_rx(dev, budget);
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		writel(readl(&lp->rx_dma_regs->dmasm) &
 			~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/lance.c linux-libre-2.6.30-gnu1/drivers/net/lance.c
--- linux-libre-2.6.29-gnu1/drivers/net/lance.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/lance.c	2009-06-09 23:05:27.000000000 -0400
@@ -391,7 +391,8 @@ MODULE_LICENSE("GPL");
    */
 static int __init do_lance_probe(struct net_device *dev)
 {
-	int *port, result;
+	unsigned int *port;
+	int result;
 
 	if (high_memory <= phys_to_virt(16*1024*1024))
 		lance_need_isa_bounce_buffers = 0;
@@ -453,16 +454,28 @@ out:
 }
 #endif
 
+static const struct net_device_ops lance_netdev_ops = {
+	.ndo_open 		= lance_open,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_stop		= lance_close,
+	.ndo_get_stats		= lance_get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
 {
 	struct lance_private *lp;
-	long dma_channels;			/* Mark spuriously-busy DMA channels */
+	unsigned long dma_channels;	/* Mark spuriously-busy DMA channels */
 	int i, reset_val, lance_version;
 	const char *chipname;
 	/* Flags for specific chips or boards. */
-	unsigned char hpJ2405A = 0;		/* HP ISA adaptor */
-	int hp_builtin = 0;			/* HP on-board ethernet. */
-	static int did_version;			/* Already printed version info. */
+	unsigned char hpJ2405A = 0;	/* HP ISA adaptor */
+	int hp_builtin = 0;		/* HP on-board ethernet. */
+	static int did_version;		/* Already printed version info. */
 	unsigned long flags;
 	int err = -ENOMEM;
 	void __iomem *bios;
@@ -713,12 +726,7 @@ static int __init lance_probe1(struct ne
 		printk(version);
 
 	/* The LANCE-specific entries in the device structure. */
-	dev->open = lance_open;
-	dev->hard_start_xmit = lance_start_xmit;
-	dev->stop = lance_close;
-	dev->get_stats = lance_get_stats;
-	dev->set_multicast_list = set_multicast_list;
-	dev->tx_timeout = lance_tx_timeout;
+	dev->netdev_ops = &lance_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	err = register_netdev(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/lp486e.c linux-libre-2.6.30-gnu1/drivers/net/lp486e.c
--- linux-libre-2.6.29-gnu1/drivers/net/lp486e.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/lp486e.c	2009-06-09 23:05:27.000000000 -0400
@@ -952,6 +952,17 @@ static void print_eth(char *add)
 		(unsigned char) add[12], (unsigned char) add[13]);
 }
 
+static const struct net_device_ops i596_netdev_ops = {
+	.ndo_open		= i596_open,
+	.ndo_stop		= i596_close,
+	.ndo_start_xmit		= i596_start_xmit,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_tx_timeout		= i596_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init lp486e_probe(struct net_device *dev) {
 	struct i596_private *lp;
 	unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 };
@@ -1014,12 +1025,8 @@ static int __init lp486e_probe(struct ne
 	printk("\n");
 
 	/* The LP486E-specific entries in the device structure. */
-	dev->open = &i596_open;
-	dev->stop = &i596_close;
-	dev->hard_start_xmit = &i596_start_xmit;
-	dev->set_multicast_list = &set_multicast_list;
+	dev->netdev_ops = &i596_netdev_ops;
 	dev->watchdog_timeo = 5*HZ;
-	dev->tx_timeout = i596_tx_timeout;
 
 #if 0
 	/* selftest reports 0x320925ae - don't know what that means */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mac8390.c linux-libre-2.6.30-gnu1/drivers/net/mac8390.c
--- linux-libre-2.6.29-gnu1/drivers/net/mac8390.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mac8390.c	2009-06-09 23:05:27.000000000 -0400
@@ -304,7 +304,7 @@ struct net_device * __init mac8390_probe
 	if (!MACH_IS_MAC)
 		return ERR_PTR(-ENODEV);
 
-	dev = alloc_ei_netdev();
+	dev = ____alloc_ei_netdev(0);
 	if (!dev)
 		return ERR_PTR(-ENOMEM);
 
@@ -481,15 +481,15 @@ void cleanup_module(void)
 static const struct net_device_ops mac8390_netdev_ops = {
 	.ndo_open 		= mac8390_open,
 	.ndo_stop		= mac8390_close,
-	.ndo_start_xmit		= ei_start_xmit,
-	.ndo_tx_timeout		= ei_tx_timeout,
-	.ndo_get_stats		= ei_get_stats,
-	.ndo_set_multicast_list = ei_set_multicast_list,
+	.ndo_start_xmit		= __ei_start_xmit,
+	.ndo_tx_timeout		= __ei_tx_timeout,
+	.ndo_get_stats		= __ei_get_stats,
+	.ndo_set_multicast_list = __ei_set_multicast_list,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address 	= eth_mac_addr,
 	.ndo_change_mtu		= eth_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= ei_poll,
+	.ndo_poll_controller	= __ei_poll,
 #endif
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mac89x0.c linux-libre-2.6.30-gnu1/drivers/net/mac89x0.c
--- linux-libre-2.6.29-gnu1/drivers/net/mac89x0.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mac89x0.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,6 +168,17 @@ writereg(struct net_device *dev, int por
 	nubus_writew(swab16(value), dev->mem_start + portno);
 }
 
+static const struct net_device_ops mac89x0_netdev_ops = {
+	.ndo_open		= net_open,
+	.ndo_stop		= net_close,
+	.ndo_start_xmit		= net_send_packet,
+	.ndo_get_stats		= net_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_set_mac_address	= set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /* Probe for the CS8900 card in slot E.  We won't bother looking
    anywhere else until we have a really good reason to do so. */
 struct net_device * __init mac89x0_probe(int unit)
@@ -280,12 +291,7 @@ struct net_device * __init mac89x0_probe
 
 	printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
 
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit = net_send_packet;
-	dev->get_stats	= net_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = &set_mac_address;
+	dev->netdev_ops		= &mac89x0_netdev_ops;
 
 	err = register_netdev(dev);
 	if (err)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/macb.c linux-libre-2.6.30-gnu1/drivers/net/macb.c
--- linux-libre-2.6.29-gnu1/drivers/net/macb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/macb.c	2009-06-09 23:05:27.000000000 -0400
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_dev
 
 	/* attach the mac to the phy */
 	if (pdata && pdata->is_rmii) {
-		phydev = phy_connect(dev, phydev->dev.bus_id,
+		phydev = phy_connect(dev, dev_name(&phydev->dev),
 			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
 	} else {
-		phydev = phy_connect(dev, phydev->dev.bus_id,
+		phydev = phy_connect(dev, dev_name(&phydev->dev),
 			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
 	}
 
@@ -316,10 +316,11 @@ static void macb_tx(struct macb *bp)
 	dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
 		(unsigned long)status);
 
-	if (status & MACB_BIT(UND)) {
+	if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
 		int i;
-		printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
-			bp->dev->name);
+		printk(KERN_ERR "%s: TX %s, resetting buffers\n",
+			bp->dev->name, status & MACB_BIT(UND) ?
+			"underrun" : "retry limit exceeded");
 
 		/* Transfer ongoing, disable transmitter, to avoid confusion */
 		if (status & MACB_BIT(TGO))
@@ -513,7 +514,6 @@ static int macb_rx(struct macb *bp, int
 static int macb_poll(struct napi_struct *napi, int budget)
 {
 	struct macb *bp = container_of(napi, struct macb, napi);
-	struct net_device *dev = bp->dev;
 	int work_done;
 	u32 status;
 
@@ -521,36 +521,18 @@ static int macb_poll(struct napi_struct
 	macb_writel(bp, RSR, status);
 
 	work_done = 0;
-	if (!status) {
-		/*
-		 * This may happen if an interrupt was pending before
-		 * this function was called last time, and no packets
-		 * have been received since.
-		 */
-		netif_rx_complete(napi);
-		goto out;
-	}
 
 	dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
 		(unsigned long)status, budget);
 
-	if (!(status & MACB_BIT(REC))) {
-		dev_warn(&bp->pdev->dev,
-			 "No RX buffers complete, status = %02lx\n",
-			 (unsigned long)status);
-		netif_rx_complete(napi);
-		goto out;
-	}
-
 	work_done = macb_rx(bp, budget);
 	if (work_done < budget)
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 	/*
 	 * We've done what we can to clean the buffers. Make sure we
 	 * get notified when new packets arrive.
 	 */
-out:
 	macb_writel(bp, IER, MACB_RX_INT_FLAGS);
 
 	/* TODO: Handle errors */
@@ -579,7 +561,7 @@ static irqreturn_t macb_interrupt(int ir
 		}
 
 		if (status & MACB_RX_INT_FLAGS) {
-			if (netif_rx_schedule_prep(&bp->napi)) {
+			if (napi_schedule_prep(&bp->napi)) {
 				/*
 				 * There's no point taking any more interrupts
 				 * until we have processed the buffers
@@ -587,11 +569,12 @@ static irqreturn_t macb_interrupt(int ir
 				macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
 				dev_dbg(&bp->pdev->dev,
 					"scheduling RX softirq\n");
-				__netif_rx_schedule(&bp->napi);
+				__napi_schedule(&bp->napi);
 			}
 		}
 
-		if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND)))
+		if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
+			    MACB_BIT(ISR_RLE)))
 			macb_tx(bp);
 
 		/*
@@ -1077,7 +1060,7 @@ static void macb_get_drvinfo(struct net_
 
 	strcpy(info->driver, bp->pdev->dev.driver->name);
 	strcpy(info->version, "$Revision: 1.14 $");
-	strcpy(info->bus_info, bp->pdev->dev.bus_id);
+	strcpy(info->bus_info, dev_name(&bp->pdev->dev));
 }
 
 static struct ethtool_ops macb_ethtool_ops = {
@@ -1101,6 +1084,18 @@ static int macb_ioctl(struct net_device
 	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
 }
 
+static const struct net_device_ops macb_netdev_ops = {
+	.ndo_open		= macb_open,
+	.ndo_stop		= macb_close,
+	.ndo_start_xmit		= macb_start_xmit,
+	.ndo_set_multicast_list	= macb_set_rx_mode,
+	.ndo_get_stats		= macb_get_stats,
+	.ndo_do_ioctl		= macb_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init macb_probe(struct platform_device *pdev)
 {
 	struct eth_platform_data *pdata;
@@ -1176,12 +1171,7 @@ static int __init macb_probe(struct plat
 		goto err_out_iounmap;
 	}
 
-	dev->open = macb_open;
-	dev->stop = macb_close;
-	dev->hard_start_xmit = macb_start_xmit;
-	dev->get_stats = macb_get_stats;
-	dev->set_multicast_list = macb_set_rx_mode;
-	dev->do_ioctl = macb_ioctl;
+	dev->netdev_ops = &macb_netdev_ops;
 	netif_napi_add(dev, &bp->napi, macb_poll, 64);
 	dev->ethtool_ops = &macb_ethtool_ops;
 
@@ -1234,8 +1224,8 @@ static int __init macb_probe(struct plat
 
 	phydev = bp->phy_dev;
 	printk(KERN_INFO "%s: attached PHY driver [%s] "
-		"(mii_bus:phy_addr=%s, irq=%d)\n",
-		dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+		"(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+		phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/macsonic.c linux-libre-2.6.30-gnu1/drivers/net/macsonic.c
--- linux-libre-2.6.29-gnu1/drivers/net/macsonic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/macsonic.c	2009-06-09 23:05:27.000000000 -0400
@@ -167,6 +167,18 @@ static int macsonic_close(struct net_dev
 	return err;
 }
 
+static const struct net_device_ops macsonic_netdev_ops = {
+	.ndo_open		= macsonic_open,
+	.ndo_stop		= macsonic_close,
+	.ndo_start_xmit		= sonic_send_packet,
+	.ndo_set_multicast_list	= sonic_multicast_list,
+	.ndo_tx_timeout		= sonic_tx_timeout,
+	.ndo_get_stats		= sonic_get_stats,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init macsonic_init(struct net_device *dev)
 {
 	struct sonic_local* lp = netdev_priv(dev);
@@ -176,7 +188,8 @@ static int __init macsonic_init(struct n
 	if ((lp->descriptors = dma_alloc_coherent(lp->device,
 	            SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
 	            &lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
-		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+		       dev_name(lp->device));
 		return -ENOMEM;
 	}
 
@@ -197,12 +210,7 @@ static int __init macsonic_init(struct n
 	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-	dev->open = macsonic_open;
-	dev->stop = macsonic_close;
-	dev->hard_start_xmit = sonic_send_packet;
-	dev->get_stats = sonic_get_stats;
-	dev->set_multicast_list = &sonic_multicast_list;
-	dev->tx_timeout = sonic_tx_timeout;
+	dev->netdev_ops = &macsonic_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	/*
@@ -337,7 +345,7 @@ static int __init mac_onboard_sonic_prob
 		sonic_version_printed = 1;
 	}
 	printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
-	       lp->device->bus_id, dev->base_addr);
+	       dev_name(lp->device), dev->base_addr);
 
 	/* The PowerBook's SONIC is 16 bit always. */
 	if (macintosh_config->ident == MAC_MODEL_PB520) {
@@ -370,10 +378,10 @@ static int __init mac_onboard_sonic_prob
 	}
 	printk(KERN_INFO
 	       "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
-	       lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+	       dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);
 
 #if 0 /* This is sometimes useful to find out how MacOS configured the card. */
-	printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+	printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
 	       SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
 #endif
 
@@ -525,12 +533,12 @@ static int __init mac_nubus_sonic_probe(
 		sonic_version_printed = 1;
 	}
 	printk(KERN_INFO "%s: %s in slot %X\n",
-	       lp->device->bus_id, ndev->board->name, ndev->board->slot);
+	       dev_name(lp->device), ndev->board->name, ndev->board->slot);
 	printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
-	       lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
+	       dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
 
 #if 0 /* This is sometimes useful to find out how MacOS configured the card. */
-	printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+	printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
 	       SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/macvlan.c linux-libre-2.6.30-gnu1/drivers/net/macvlan.c
--- linux-libre-2.6.29-gnu1/drivers/net/macvlan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/macvlan.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,6 +60,47 @@ static struct macvlan_dev *macvlan_hash_
 	return NULL;
 }
 
+static void macvlan_hash_add(struct macvlan_dev *vlan)
+{
+	struct macvlan_port *port = vlan->port;
+	const unsigned char *addr = vlan->dev->dev_addr;
+
+	hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
+}
+
+static void macvlan_hash_del(struct macvlan_dev *vlan)
+{
+	hlist_del_rcu(&vlan->hlist);
+	synchronize_rcu();
+}
+
+static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
+					const unsigned char *addr)
+{
+	macvlan_hash_del(vlan);
+	/* Now that we are unhashed it is safe to change the device
+	 * address without confusing packet delivery.
+	 */
+	memcpy(vlan->dev->dev_addr, addr, ETH_ALEN);
+	macvlan_hash_add(vlan);
+}
+
+static int macvlan_addr_busy(const struct macvlan_port *port,
+				const unsigned char *addr)
+{
+	/* Test to see if the specified multicast address is
+	 * currently in use by the underlying device or
+	 * another macvlan.
+	 */
+	if (memcmp(port->dev->dev_addr, addr, ETH_ALEN) == 0)
+		return 1;
+
+	if (macvlan_hash_lookup(port, addr))
+		return 1;
+
+	return 0;
+}
+
 static void macvlan_broadcast(struct sk_buff *skb,
 			      const struct macvlan_port *port)
 {
@@ -184,10 +225,13 @@ static const struct header_ops macvlan_h
 static int macvlan_open(struct net_device *dev)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
-	struct macvlan_port *port = vlan->port;
 	struct net_device *lowerdev = vlan->lowerdev;
 	int err;
 
+	err = -EBUSY;
+	if (macvlan_addr_busy(vlan->port, dev->dev_addr))
+		goto out;
+
 	err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
 	if (err < 0)
 		goto out;
@@ -196,8 +240,7 @@ static int macvlan_open(struct net_devic
 		if (err < 0)
 			goto del_unicast;
 	}
-
-	hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[dev->dev_addr[5]]);
+	macvlan_hash_add(vlan);
 	return 0;
 
 del_unicast:
@@ -217,8 +260,7 @@ static int macvlan_stop(struct net_devic
 
 	dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
 
-	hlist_del_rcu(&vlan->hlist);
-	synchronize_rcu();
+	macvlan_hash_del(vlan);
 	return 0;
 }
 
@@ -232,16 +274,21 @@ static int macvlan_set_mac_address(struc
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	if (!(dev->flags & IFF_UP))
-		goto out;
+	if (!(dev->flags & IFF_UP)) {
+		/* Just copy in the new address */
+		memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	} else {
+		/* Rehash and update the device filters */
+		if (macvlan_addr_busy(vlan->port, addr->sa_data))
+			return -EBUSY;
 
-	err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN);
-	if (err < 0)
-		return err;
-	dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+		if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN)))
+			return err;
 
-out:
-	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+		dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+
+		macvlan_hash_change_addr(vlan, addr->sa_data);
+	}
 	return 0;
 }
 
@@ -329,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(s
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (lowerdev->ethtool_ops->get_rx_csum == NULL)
+	if (lowerdev->ethtool_ops == NULL ||
+	    lowerdev->ethtool_ops->get_rx_csum == NULL)
 		return 0;
 	return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
 }
@@ -340,7 +388,8 @@ static int macvlan_ethtool_get_settings(
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (!lowerdev->ethtool_ops->get_settings)
+	if (!lowerdev->ethtool_ops ||
+	    !lowerdev->ethtool_ops->get_settings)
 		return -EOPNOTSUPP;
 
 	return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
@@ -351,7 +400,8 @@ static u32 macvlan_ethtool_get_flags(str
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	struct net_device *lowerdev = vlan->lowerdev;
 
-	if (!lowerdev->ethtool_ops->get_flags)
+	if (!lowerdev->ethtool_ops ||
+	    !lowerdev->ethtool_ops->get_flags)
 		return 0;
 	return lowerdev->ethtool_ops->get_flags(lowerdev);
 }
@@ -461,12 +511,13 @@ static int macvlan_newlink(struct net_de
 	if (lowerdev == NULL)
 		return -ENODEV;
 
-	/* Don't allow macvlans on top of other macvlans - its not really
-	 * wrong, but lockdep can't handle it and its not useful for anything
-	 * you couldn't do directly on top of the real device.
+	/* When creating macvlans on top of other macvlans - use
+	 * the real device as the lowerdev.
 	 */
-	if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops)
-		return -ENODEV;
+	if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops) {
+		struct macvlan_dev *lowervlan = netdev_priv(lowerdev);
+		lowerdev = lowervlan->lowerdev;
+	}
 
 	if (!tb[IFLA_MTU])
 		dev->mtu = lowerdev->mtu;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/Makefile linux-libre-2.6.30-gnu1/drivers/net/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@ obj-$(CONFIG_E1000) += e1000/
 obj-$(CONFIG_E1000E) += e1000e/
 obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
 obj-$(CONFIG_IGB) += igb/
+obj-$(CONFIG_IGBVF) += igbvf/
 obj-$(CONFIG_IXGBE) += ixgbe/
 obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_IP1000) += ipg.o
@@ -26,11 +27,12 @@ obj-$(CONFIG_BE2NET) += benet/
 
 gianfar_driver-objs := gianfar.o \
 		gianfar_ethtool.o \
-		gianfar_mii.o \
 		gianfar_sysfs.o
 
 obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+
+obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
 
 #
 # link order important here
@@ -100,7 +102,7 @@ obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
+obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_HP100) += hp100.o
@@ -219,6 +221,7 @@ obj-$(CONFIG_R8169) += r8169.o
 obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
 obj-$(CONFIG_IBMVETH) += ibmveth.o
 obj-$(CONFIG_S2IO) += s2io.o
+obj-$(CONFIG_VXGE) += vxge/
 obj-$(CONFIG_MYRI10GE) += myri10ge/
 obj-$(CONFIG_SMC91X) += smc91x.o
 obj-$(CONFIG_SMC911X) += smc911x.o
@@ -229,6 +232,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_d
 pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
+obj-$(CONFIG_ETHOC) += ethoc.o
 
 obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/meth.c linux-libre-2.6.30-gnu1/drivers/net/meth.c
--- linux-libre-2.6.29-gnu1/drivers/net/meth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/meth.c	2009-06-09 23:05:27.000000000 -0400
@@ -127,11 +127,11 @@ static unsigned long mdio_read(struct me
 static int mdio_probe(struct meth_private *priv)
 {
 	int i;
-	unsigned long p2, p3;
+	unsigned long p2, p3, flags;
 	/* check if phy is detected already */
 	if(priv->phy_addr>=0&&priv->phy_addr<32)
 		return 0;
-	spin_lock(&priv->meth_lock);
+	spin_lock_irqsave(&priv->meth_lock, flags);
 	for (i=0;i<32;++i){
 		priv->phy_addr=i;
 		p2=mdio_read(priv,2);
@@ -157,7 +157,7 @@ static int mdio_probe(struct meth_privat
 			break;
 		}
 	}
-	spin_unlock(&priv->meth_lock);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 	if(priv->phy_addr<32) {
 		return 0;
 	}
@@ -373,14 +373,14 @@ static int meth_release(struct net_devic
 static void meth_rx(struct net_device* dev, unsigned long int_status)
 {
 	struct sk_buff *skb;
-	unsigned long status;
+	unsigned long status, flags;
 	struct meth_private *priv = netdev_priv(dev);
 	unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8;
 
-	spin_lock(&priv->meth_lock);
+	spin_lock_irqsave(&priv->meth_lock, flags);
 	priv->dma_ctrl &= ~METH_DMA_RX_INT_EN;
 	mace->eth.dma_ctrl = priv->dma_ctrl;
-	spin_unlock(&priv->meth_lock);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 
 	if (int_status & METH_INT_RX_UNDERFLOW) {
 		fifo_rptr = (fifo_rptr - 1) & 0x0f;
@@ -398,7 +398,7 @@ static void meth_rx(struct net_device* d
 			int len = (status & 0xffff) - 4; /* omit CRC */
 			/* length sanity check */
 			if (len < 60 || len > 1518) {
-				printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n",
+				printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2Lx.\n",
 				       dev->name, priv->rx_write,
 				       priv->rx_ring[priv->rx_write]->status.raw);
 				dev->stats.rx_errors++;
@@ -452,12 +452,12 @@ static void meth_rx(struct net_device* d
 		mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write];
 		ADVANCE_RX_PTR(priv->rx_write);
 	}
-	spin_lock(&priv->meth_lock);
+	spin_lock_irqsave(&priv->meth_lock, flags);
 	/* In case there was underflow, and Rx DMA was disabled */
 	priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN;
 	mace->eth.dma_ctrl = priv->dma_ctrl;
 	mace->eth.int_stat = METH_INT_RX_THRESHOLD;
-	spin_unlock(&priv->meth_lock);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 }
 
 static int meth_tx_full(struct net_device *dev)
@@ -470,11 +470,11 @@ static int meth_tx_full(struct net_devic
 static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
 {
 	struct meth_private *priv = netdev_priv(dev);
-	unsigned long status;
+	unsigned long status, flags;
 	struct sk_buff *skb;
 	unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16;
 
-	spin_lock(&priv->meth_lock);
+	spin_lock_irqsave(&priv->meth_lock, flags);
 
 	/* Stop DMA notification */
 	priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
@@ -527,12 +527,13 @@ static void meth_tx_cleanup(struct net_d
 	}
 
 	mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT;
-	spin_unlock(&priv->meth_lock);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 }
 
 static void meth_error(struct net_device* dev, unsigned status)
 {
 	struct meth_private *priv = netdev_priv(dev);
+	unsigned long flags;
 
 	printk(KERN_WARNING "meth: error status: 0x%08x\n",status);
 	/* check for errors too... */
@@ -547,7 +548,7 @@ static void meth_error(struct net_device
 		printk(KERN_WARNING "meth: Rx overflow\n");
 	if (status & (METH_INT_RX_UNDERFLOW)) {
 		printk(KERN_WARNING "meth: Rx underflow\n");
-		spin_lock(&priv->meth_lock);
+		spin_lock_irqsave(&priv->meth_lock, flags);
 		mace->eth.int_stat = METH_INT_RX_UNDERFLOW;
 		/* more underflow interrupts will be delivered,
 		 * effectively throwing us into an infinite loop.
@@ -555,7 +556,7 @@ static void meth_error(struct net_device
 		priv->dma_ctrl &= ~METH_DMA_RX_EN;
 		mace->eth.dma_ctrl = priv->dma_ctrl;
 		DPRINTK("Disabled meth Rx DMA temporarily\n");
-		spin_unlock(&priv->meth_lock);
+		spin_unlock_irqrestore(&priv->meth_lock, flags);
 	}
 	mace->eth.int_stat = METH_INT_ERROR;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mipsnet.c linux-libre-2.6.30-gnu1/drivers/net/mipsnet.c
--- linux-libre-2.6.29-gnu1/drivers/net/mipsnet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mipsnet.c	2009-06-09 23:05:27.000000000 -0400
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct ne
 {
 }
 
-static int __init mipsnet_probe(struct device *dev)
+static int __init mipsnet_probe(struct platform_device *dev)
 {
 	struct net_device *netdev;
 	int err;
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct d
 		goto out;
 	}
 
-	dev_set_drvdata(dev, netdev);
+	platform_set_drvdata(dev, netdev);
 
 	netdev->open			= mipsnet_open;
 	netdev->stop			= mipsnet_close;
@@ -293,23 +293,25 @@ out:
 	return err;
 }
 
-static int __devexit mipsnet_device_remove(struct device *device)
+static int __devexit mipsnet_device_remove(struct platform_device *device)
 {
-	struct net_device *dev = dev_get_drvdata(device);
+	struct net_device *dev = platform_get_drvdata(device);
 
 	unregister_netdev(dev);
 	release_region(dev->base_addr, sizeof(struct mipsnet_regs));
 	free_netdev(dev);
-	dev_set_drvdata(device, NULL);
+	platform_set_drvdata(device, NULL);
 
 	return 0;
 }
 
-static struct device_driver mipsnet_driver = {
-	.name	= mipsnet_string,
-	.bus	= &platform_bus_type,
-	.probe	= mipsnet_probe,
-	.remove	= __devexit_p(mipsnet_device_remove),
+static struct platform_driver mipsnet_driver = {
+	.driver = {
+		.name		= mipsnet_string,
+		.owner		= THIS_MODULE,
+	},
+	.probe		= mipsnet_probe,
+	.remove		= __devexit_p(mipsnet_device_remove),
 };
 
 static int __init mipsnet_init_module(void)
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(vo
 	printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
 	       "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
 
-	err = driver_register(&mipsnet_driver);
+	err = platform_driver_register(&mipsnet_driver);
 	if (err)
 		printk(KERN_ERR "Driver registration failed\n");
 
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(vo
 
 static void __exit mipsnet_exit_module(void)
 {
-	driver_unregister(&mipsnet_driver);
+	platform_driver_unregister(&mipsnet_driver);
 }
 
 module_init(mipsnet_init_module);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/catas.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/catas.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/catas.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/catas.c	2009-06-09 23:05:27.000000000 -0400
@@ -42,7 +42,6 @@ enum {
 static DEFINE_SPINLOCK(catas_lock);
 
 static LIST_HEAD(catas_list);
-static struct workqueue_struct *catas_wq;
 static struct work_struct catas_work;
 
 static int internal_err_reset = 1;
@@ -77,7 +76,7 @@ static void poll_catas(unsigned long dev
 			list_add(&priv->catas_err.list, &catas_list);
 			spin_unlock(&catas_lock);
 
-			queue_work(catas_wq, &catas_work);
+			queue_work(mlx4_wq, &catas_work);
 		}
 	} else
 		mod_timer(&priv->catas_err.timer,
@@ -146,18 +145,7 @@ void mlx4_stop_catas_poll(struct mlx4_de
 	spin_unlock_irq(&catas_lock);
 }
 
-int __init mlx4_catas_init(void)
+void  __init mlx4_catas_init(void)
 {
 	INIT_WORK(&catas_work, catas_reset);
-
-	catas_wq = create_singlethread_workqueue("mlx4_err");
-	if (!catas_wq)
-		return -ENOMEM;
-
-	return 0;
-}
-
-void mlx4_catas_cleanup(void)
-{
-	destroy_workqueue(catas_wq);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_cq.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_cq.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_cq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_cq.c	2009-06-09 23:05:27.000000000 -0400
@@ -125,8 +125,10 @@ void mlx4_en_deactivate_cq(struct mlx4_e
 
 	if (cq->is_tx)
 		del_timer(&cq->timer);
-	else
+	else {
 		napi_disable(&cq->napi);
+		netif_napi_del(&cq->napi);
+	}
 
 	mlx4_cq_free(mdev->dev, &cq->mcq);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_main.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -181,7 +181,7 @@ static void *mlx4_en_add(struct mlx4_dev
 	mdev->workqueue = create_singlethread_workqueue("mlx4_en");
 	if (!mdev->workqueue) {
 		err = -ENOMEM;
-		goto err_close_nic;
+		goto err_mr;
 	}
 
 	/* At this stage all non-port specific tasks are complete:
@@ -214,9 +214,8 @@ err_free_netdev:
 	flush_workqueue(mdev->workqueue);
 
 	/* Stop event queue before we drop down to release shared SW state */
-
-err_close_nic:
 	destroy_workqueue(mdev->workqueue);
+
 err_mr:
 	mlx4_mr_free(dev, &mdev->mr);
 err_uar:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_netdev.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_netdev.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_netdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_netdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -348,11 +348,9 @@ static void mlx4_en_tx_timeout(struct ne
 	if (netif_msg_timer(priv))
 		mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
 
-	if (netif_carrier_ok(dev)) {
-		priv->port_stats.tx_timeout++;
-		mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
-		queue_work(mdev->workqueue, &priv->watchdog_task);
-	}
+	priv->port_stats.tx_timeout++;
+	mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+	queue_work(mdev->workqueue, &priv->watchdog_task);
 }
 
 
@@ -505,7 +503,7 @@ out:
 
 static void mlx4_en_do_get_stats(struct work_struct *work)
 {
-	struct delayed_work *delay = container_of(work, struct delayed_work, work);
+	struct delayed_work *delay = to_delayed_work(work);
 	struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
 						 stats_task);
 	struct mlx4_en_dev *mdev = priv->mdev;
@@ -585,7 +583,7 @@ int mlx4_en_start_port(struct net_device
 		err = mlx4_en_activate_cq(priv, cq);
 		if (err) {
 			mlx4_err(mdev, "Failed activating Rx CQ\n");
-			goto rx_err;
+			goto cq_err;
 		}
 		for (j = 0; j < cq->size; j++)
 			cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK;
@@ -761,9 +759,14 @@ static void mlx4_en_restart(struct work_
 	struct net_device *dev = priv->dev;
 
 	mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
-	mlx4_en_stop_port(dev);
-	if (mlx4_en_start_port(dev))
-	    mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+
+	mutex_lock(&mdev->state_lock);
+	if (priv->port_up) {
+		mlx4_en_stop_port(dev);
+		if (mlx4_en_start_port(dev))
+			mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+	}
+	mutex_unlock(&mdev->state_lock);
 }
 
 
@@ -1054,7 +1057,7 @@ int mlx4_en_init_netdev(struct mlx4_en_d
 	 * Set driver features
 	 */
 	dev->features |= NETIF_F_SG;
-	dev->features |= NETIF_F_HW_CSUM;
+	dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	dev->features |= NETIF_F_HIGHDMA;
 	dev->features |= NETIF_F_HW_VLAN_TX |
 			 NETIF_F_HW_VLAN_RX |
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_port.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_port.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_port.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_port.c	2009-06-09 23:05:27.000000000 -0400
@@ -151,6 +151,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 	struct mlx4_cmd_mailbox *mailbox;
 	u64 in_mod = reset << 8 | port;
 	int err;
+	int i;
 
 	mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
 	if (IS_ERR(mailbox))
@@ -165,38 +166,18 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 
 	spin_lock_bh(&priv->stats_lock);
 
-	stats->rx_packets = be32_to_cpu(mlx4_en_stats->RTOTFRMS) -
-			    be32_to_cpu(mlx4_en_stats->RDROP);
-	stats->tx_packets = be64_to_cpu(mlx4_en_stats->TTOT_prio_0) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_1) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_2) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_3) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_4) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_5) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_6) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_prio_7) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_novlan) +
-			    be64_to_cpu(mlx4_en_stats->TTOT_loopbk);
-	stats->rx_bytes = be64_to_cpu(mlx4_en_stats->ROCT_prio_0) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_1) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_2) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_3) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_4) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_5) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_6) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_prio_7) +
-			  be64_to_cpu(mlx4_en_stats->ROCT_novlan);
-
-	stats->tx_bytes = be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_0) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_1) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_2) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_3) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_4) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_5) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_6) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_7) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_novlan) +
-			  be64_to_cpu(mlx4_en_stats->TTTLOCT_loopbk);
+	stats->rx_packets = 0;
+	stats->rx_bytes = 0;
+	for (i = 0; i < priv->rx_ring_num; i++) {
+		stats->rx_packets += priv->rx_ring[i].packets;
+		stats->rx_bytes += priv->rx_ring[i].bytes;
+	}
+	stats->tx_packets = 0;
+	stats->tx_bytes = 0;
+	for (i = 0; i <= priv->tx_ring_num; i++) {
+		stats->tx_packets += priv->tx_ring[i].packets;
+		stats->tx_bytes += priv->tx_ring[i].bytes;
+	}
 
 	stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) +
 			   be32_to_cpu(mlx4_en_stats->RdropLength) +
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_resources.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_resources.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_resources.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_resources.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,3 +94,9 @@ void mlx4_en_unmap_buffer(struct mlx4_bu
 
 	vunmap(buf->direct.buf);
 }
+
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
+{
+    return;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_rx.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -298,7 +298,7 @@ static void mlx4_en_free_rx_buf(struct m
 
 void mlx4_en_rx_refill(struct work_struct *work)
 {
-	struct delayed_work *delay = container_of(work, struct delayed_work, work);
+	struct delayed_work *delay = to_delayed_work(work);
 	struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
 						 refill_task);
 	struct mlx4_en_dev *mdev = priv->mdev;
@@ -436,8 +436,9 @@ int mlx4_en_activate_rx_rings(struct mlx
 		/* Initialize page allocators */
 		err = mlx4_en_init_allocator(priv, ring);
 		if (err) {
-			 mlx4_err(mdev, "Failed initializing ring allocator\n");
-			 goto err_allocator;
+			mlx4_err(mdev, "Failed initializing ring allocator\n");
+			ring_ind--;
+			goto err_allocator;
 		}
 
 		/* Fill Rx buffers */
@@ -467,6 +468,7 @@ int mlx4_en_activate_rx_rings(struct mlx
 				     ring->wqres.db.dma, &ring->srq);
 		if (err){
 			mlx4_err(mdev, "Failed to allocate srq\n");
+			ring_ind--;
 			goto err_srq;
 		}
 		ring->srq.event = mlx4_en_srq_event;
@@ -608,6 +610,10 @@ static struct sk_buff *mlx4_en_rx_skb(st
 		used_frags = mlx4_en_complete_rx_desc(priv, rx_desc, skb_frags,
 						      skb_shinfo(skb)->frags,
 						      page_alloc, length);
+		if (unlikely(!used_frags)) {
+			kfree_skb(skb);
+			return NULL;
+		}
 		skb_shinfo(skb)->nr_frags = used_frags;
 
 		/* Copy headers into the skb linear buffer */
@@ -768,6 +774,7 @@ int mlx4_en_process_rx_cq(struct net_dev
 
 		skb->ip_summed = ip_summed;
 		skb->protocol = eth_type_trans(skb, dev);
+		skb_record_rx_queue(skb, cq->ring);
 
 		/* Push it up the stack */
 		if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
@@ -814,7 +821,7 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
 	struct mlx4_en_priv *priv = netdev_priv(cq->dev);
 
 	if (priv->port_up)
-		netif_rx_schedule(&cq->napi);
+		napi_schedule(&cq->napi);
 	else
 		mlx4_en_arm_cq(priv, cq);
 }
@@ -834,7 +841,7 @@ int mlx4_en_poll_rx_cq(struct napi_struc
 		INC_PERF_COUNTER(priv->pstats.napi_quota);
 	else {
 		/* Done for now */
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		mlx4_en_arm_cq(priv, cq);
 	}
 	return done;
@@ -925,12 +932,6 @@ void mlx4_en_set_default_rss_map(struct
 	}
 }
 
-static void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event)
-{
-    return;
-}
-
-
 static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
 				 int qpn, int srqn, int cqn,
 				 enum mlx4_qp_state *state,
@@ -950,7 +951,6 @@ static int mlx4_en_config_rss_qp(struct
 	if (err) {
 		mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
 		goto out;
-		return err;
 	}
 	qp->event = mlx4_en_sqp_event;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_tx.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/en_tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/en_tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -112,6 +112,7 @@ int mlx4_en_create_tx_ring(struct mlx4_e
 		mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
 		goto err_reserve;
 	}
+	ring->qp.event = mlx4_en_sqp_event;
 
 	return 0;
 
@@ -425,7 +426,7 @@ void mlx4_en_poll_tx_cq(unsigned long da
 
 	INC_PERF_COUNTER(priv->pstats.tx_poll);
 
-	if (!spin_trylock(&ring->comp_lock)) {
+	if (!spin_trylock_irq(&ring->comp_lock)) {
 		mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
 		return;
 	}
@@ -438,7 +439,7 @@ void mlx4_en_poll_tx_cq(unsigned long da
 	if (inflight && priv->port_up)
 		mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
 
-	spin_unlock(&ring->comp_lock);
+	spin_unlock_irq(&ring->comp_lock);
 }
 
 static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
@@ -481,9 +482,9 @@ static inline void mlx4_en_xmit_poll(str
 
 	/* Poll the CQ every mlx4_en_TX_MODER_POLL packets */
 	if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0)
-		if (spin_trylock(&ring->comp_lock)) {
+		if (spin_trylock_irq(&ring->comp_lock)) {
 			mlx4_en_process_tx_cq(priv->dev, cq);
-			spin_unlock(&ring->comp_lock);
+			spin_unlock_irq(&ring->comp_lock);
 		}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/eq.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/eq.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/eq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/eq.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,6 +163,7 @@ static int mlx4_eq_int(struct mlx4_dev *
 	int cqn;
 	int eqes_found = 0;
 	int set_ci = 0;
+	int port;
 
 	while ((eqe = next_eqe_sw(eq))) {
 		/*
@@ -203,11 +204,16 @@ static int mlx4_eq_int(struct mlx4_dev *
 			break;
 
 		case MLX4_EVENT_TYPE_PORT_CHANGE:
-			mlx4_dispatch_event(dev,
-					    eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_ACTIVE ?
-					    MLX4_DEV_EVENT_PORT_UP :
-					    MLX4_DEV_EVENT_PORT_DOWN,
-					    be32_to_cpu(eqe->event.port_change.port) >> 28);
+			port = be32_to_cpu(eqe->event.port_change.port) >> 28;
+			if (eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN) {
+				mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_DOWN,
+						    port);
+				mlx4_priv(dev)->sense.do_sense_port[port] = 1;
+			} else {
+				mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_UP,
+						    port);
+				mlx4_priv(dev)->sense.do_sense_port[port] = 0;
+			}
 			break;
 
 		case MLX4_EVENT_TYPE_CQ_ERROR:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/main.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,6 +51,8 @@ MODULE_DESCRIPTION("Mellanox ConnectX HC
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 
+struct workqueue_struct *mlx4_wq;
+
 #ifdef CONFIG_MLX4_DEBUG
 
 int mlx4_debug_level = 0;
@@ -98,24 +100,23 @@ module_param_named(use_prio, use_prio, b
 MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
 		  "(0/1, default 0)");
 
-static int mlx4_check_port_params(struct mlx4_dev *dev,
-				  enum mlx4_port_type *port_type)
+int mlx4_check_port_params(struct mlx4_dev *dev,
+			   enum mlx4_port_type *port_type)
 {
 	int i;
 
 	for (i = 0; i < dev->caps.num_ports - 1; i++) {
-		if (port_type[i] != port_type[i+1] &&
-		    !(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
-			mlx4_err(dev, "Only same port types supported "
-				 "on this HCA, aborting.\n");
-			return -EINVAL;
+		if (port_type[i] != port_type[i + 1]) {
+			if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+				mlx4_err(dev, "Only same port types supported "
+					 "on this HCA, aborting.\n");
+				return -EINVAL;
+			}
+			if (port_type[i] == MLX4_PORT_TYPE_ETH &&
+			    port_type[i + 1] == MLX4_PORT_TYPE_IB)
+				return -EINVAL;
 		}
 	}
-	if ((port_type[0] == MLX4_PORT_TYPE_ETH) &&
-	    (port_type[1] == MLX4_PORT_TYPE_IB)) {
-		mlx4_err(dev, "eth-ib configuration is not supported.\n");
-		return -EINVAL;
-	}
 
 	for (i = 0; i < dev->caps.num_ports; i++) {
 		if (!(port_type[i] & dev->caps.supported_type[i+1])) {
@@ -225,6 +226,9 @@ static int mlx4_dev_cap(struct mlx4_dev
 			dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
 		else
 			dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
+		dev->caps.possible_type[i] = dev->caps.port_type[i];
+		mlx4_priv(dev)->sense.sense_allowed[i] =
+			dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO;
 
 		if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
 			dev->caps.log_num_macs = dev_cap->log_max_macs[i];
@@ -263,14 +267,16 @@ static int mlx4_dev_cap(struct mlx4_dev
  * Change the port configuration of the device.
  * Every user of this function must hold the port mutex.
  */
-static int mlx4_change_port_types(struct mlx4_dev *dev,
-				  enum mlx4_port_type *port_types)
+int mlx4_change_port_types(struct mlx4_dev *dev,
+			   enum mlx4_port_type *port_types)
 {
 	int err = 0;
 	int change = 0;
 	int port;
 
 	for (port = 0; port <  dev->caps.num_ports; port++) {
+		/* Change the port type only if the new type is different
+		 * from the current, and not set to Auto */
 		if (port_types[port] != dev->caps.port_type[port + 1]) {
 			change = 1;
 			dev->caps.port_type[port + 1] = port_types[port];
@@ -302,10 +308,17 @@ static ssize_t show_port_type(struct dev
 	struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
 						   port_attr);
 	struct mlx4_dev *mdev = info->dev;
+	char type[8];
 
-	return sprintf(buf, "%s\n",
-		       mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB ?
-		       "ib" : "eth");
+	sprintf(type, "%s",
+		(mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB) ?
+		"ib" : "eth");
+	if (mdev->caps.possible_type[info->port] == MLX4_PORT_TYPE_AUTO)
+		sprintf(buf, "auto (%s)\n", type);
+	else
+		sprintf(buf, "%s\n", type);
+
+	return strlen(buf);
 }
 
 static ssize_t set_port_type(struct device *dev,
@@ -317,6 +330,7 @@ static ssize_t set_port_type(struct devi
 	struct mlx4_dev *mdev = info->dev;
 	struct mlx4_priv *priv = mlx4_priv(mdev);
 	enum mlx4_port_type types[MLX4_MAX_PORTS];
+	enum mlx4_port_type new_types[MLX4_MAX_PORTS];
 	int i;
 	int err = 0;
 
@@ -324,26 +338,56 @@ static ssize_t set_port_type(struct devi
 		info->tmp_type = MLX4_PORT_TYPE_IB;
 	else if (!strcmp(buf, "eth\n"))
 		info->tmp_type = MLX4_PORT_TYPE_ETH;
+	else if (!strcmp(buf, "auto\n"))
+		info->tmp_type = MLX4_PORT_TYPE_AUTO;
 	else {
 		mlx4_err(mdev, "%s is not supported port type\n", buf);
 		return -EINVAL;
 	}
 
+	mlx4_stop_sense(mdev);
 	mutex_lock(&priv->port_mutex);
-	for (i = 0; i < mdev->caps.num_ports; i++)
+	/* Possible type is always the one that was delivered */
+	mdev->caps.possible_type[info->port] = info->tmp_type;
+
+	for (i = 0; i < mdev->caps.num_ports; i++) {
 		types[i] = priv->port[i+1].tmp_type ? priv->port[i+1].tmp_type :
-					mdev->caps.port_type[i+1];
+					mdev->caps.possible_type[i+1];
+		if (types[i] == MLX4_PORT_TYPE_AUTO)
+			types[i] = mdev->caps.port_type[i+1];
+	}
 
-	err = mlx4_check_port_params(mdev, types);
+	if (!(mdev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+		for (i = 1; i <= mdev->caps.num_ports; i++) {
+			if (mdev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+				mdev->caps.possible_type[i] = mdev->caps.port_type[i];
+				err = -EINVAL;
+			}
+		}
+	}
+	if (err) {
+		mlx4_err(mdev, "Auto sensing is not supported on this HCA. "
+			       "Set only 'eth' or 'ib' for both ports "
+			       "(should be the same)\n");
+		goto out;
+	}
+
+	mlx4_do_sense_ports(mdev, new_types, types);
+
+	err = mlx4_check_port_params(mdev, new_types);
 	if (err)
 		goto out;
 
-	for (i = 1; i <= mdev->caps.num_ports; i++)
-		priv->port[i].tmp_type = 0;
+	/* We are about to apply the changes after the configuration
+	 * was verified, no need to remember the temporary types
+	 * any more */
+	for (i = 0; i < mdev->caps.num_ports; i++)
+		priv->port[i + 1].tmp_type = 0;
 
-	err = mlx4_change_port_types(mdev, types);
+	err = mlx4_change_port_types(mdev, new_types);
 
 out:
+	mlx4_start_sense(mdev);
 	mutex_unlock(&priv->port_mutex);
 	return err ? err : count;
 }
@@ -932,7 +976,7 @@ static void mlx4_enable_msi_x(struct mlx
 				nreq = err;
 				goto retry;
 			}
-
+			kfree(entries);
 			goto no_msi;
 		}
 
@@ -1032,20 +1076,20 @@ static int __mlx4_init_one(struct pci_de
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err) {
 		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
 			goto err_release_bar2;
 		}
 	}
-	err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (err) {
 		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit "
 			 "consistent PCI DMA mask.\n");
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "Can't set consistent PCI DMA mask, "
 				"aborting.\n");
@@ -1117,6 +1161,9 @@ static int __mlx4_init_one(struct pci_de
 	if (err)
 		goto err_port;
 
+	mlx4_sense_init(dev);
+	mlx4_start_sense(dev);
+
 	pci_set_drvdata(pdev, dev);
 
 	return 0;
@@ -1182,6 +1229,7 @@ static void mlx4_remove_one(struct pci_d
 	int p;
 
 	if (dev) {
+		mlx4_stop_sense(dev);
 		mlx4_unregister_device(dev);
 
 		for (p = 1; p <= dev->caps.num_ports; p++) {
@@ -1230,6 +1278,8 @@ static struct pci_device_id mlx4_pci_tab
 	{ PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */
 	{ PCI_VDEVICE(MELLANOX, 0x6368) }, /* MT25408 "Hermon" EN 10GigE */
 	{ PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */
+	{ PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
+	{ PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
 	{ 0, }
 };
 
@@ -1264,9 +1314,11 @@ static int __init mlx4_init(void)
 	if (mlx4_verify_params())
 		return -EINVAL;
 
-	ret = mlx4_catas_init();
-	if (ret)
-		return ret;
+	mlx4_catas_init();
+
+	mlx4_wq = create_singlethread_workqueue("mlx4");
+	if (!mlx4_wq)
+		return -ENOMEM;
 
 	ret = pci_register_driver(&mlx4_driver);
 	return ret < 0 ? ret : 0;
@@ -1275,7 +1327,7 @@ static int __init mlx4_init(void)
 static void __exit mlx4_cleanup(void)
 {
 	pci_unregister_driver(&mlx4_driver);
-	mlx4_catas_cleanup();
+	destroy_workqueue(mlx4_wq);
 }
 
 module_init(mlx4_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/Makefile linux-libre-2.6.30-gnu1/drivers/net/mlx4/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 obj-$(CONFIG_MLX4_CORE)		+= mlx4_core.o
 
 mlx4_core-y :=	alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
-		mr.o pd.o port.o profile.o qp.o reset.o srq.o
+		mr.o pd.o port.o profile.o qp.o reset.o sense.o srq.o
 
 obj-$(CONFIG_MLX4_EN)               += mlx4_en.o
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/mlx4_en.h linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4_en.h
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/mlx4_en.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4_en.h	2009-06-09 23:05:27.000000000 -0400
@@ -538,6 +538,7 @@ int mlx4_en_poll_rx_cq(struct napi_struc
 void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 			     int is_tx, int rss, int qpn, int cqn, int srqn,
 			     struct mlx4_qp_context *context);
+void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
 int mlx4_en_map_buffer(struct mlx4_buf *buf);
 void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/mlx4.h linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4.h
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/mlx4.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/mutex.h>
 #include <linux/radix-tree.h>
 #include <linux/timer.h>
+#include <linux/workqueue.h>
 
 #include <linux/mlx4/device.h>
 #include <linux/mlx4/driver.h>
@@ -276,6 +277,13 @@ struct mlx4_port_info {
 	struct mlx4_vlan_table	vlan_table;
 };
 
+struct mlx4_sense {
+	struct mlx4_dev		*dev;
+	u8			do_sense_port[MLX4_MAX_PORTS + 1];
+	u8			sense_allowed[MLX4_MAX_PORTS + 1];
+	struct delayed_work	sense_poll;
+};
+
 struct mlx4_priv {
 	struct mlx4_dev		dev;
 
@@ -305,6 +313,7 @@ struct mlx4_priv {
 	struct mlx4_uar		driver_uar;
 	void __iomem	       *kar;
 	struct mlx4_port_info	port[MLX4_MAX_PORTS + 1];
+	struct mlx4_sense       sense;
 	struct mutex		port_mutex;
 };
 
@@ -313,6 +322,10 @@ static inline struct mlx4_priv *mlx4_pri
 	return container_of(dev, struct mlx4_priv, dev);
 }
 
+#define MLX4_SENSE_RANGE	(HZ * 3)
+
+extern struct workqueue_struct *mlx4_wq;
+
 u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
 void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
 u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
@@ -346,8 +359,7 @@ void mlx4_cleanup_mcg_table(struct mlx4_
 
 void mlx4_start_catas_poll(struct mlx4_dev *dev);
 void mlx4_stop_catas_poll(struct mlx4_dev *dev);
-int mlx4_catas_init(void);
-void mlx4_catas_cleanup(void);
+void mlx4_catas_init(void);
 int mlx4_restart_one(struct pci_dev *pdev);
 int mlx4_register_device(struct mlx4_dev *dev);
 void mlx4_unregister_device(struct mlx4_dev *dev);
@@ -379,6 +391,17 @@ void mlx4_srq_event(struct mlx4_dev *dev
 
 void mlx4_handle_catas_err(struct mlx4_dev *dev);
 
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+			 enum mlx4_port_type *stype,
+			 enum mlx4_port_type *defaults);
+void mlx4_start_sense(struct mlx4_dev *dev);
+void mlx4_stop_sense(struct mlx4_dev *dev);
+void mlx4_sense_init(struct mlx4_dev *dev);
+int mlx4_check_port_params(struct mlx4_dev *dev,
+			   enum mlx4_port_type *port_type);
+int mlx4_change_port_types(struct mlx4_dev *dev,
+			   enum mlx4_port_type *port_types);
+
 void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
 void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/port.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/port.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/port.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/port.c	2009-06-09 23:05:27.000000000 -0400
@@ -298,20 +298,18 @@ int mlx4_SET_PORT(struct mlx4_dev *dev,
 {
 	struct mlx4_cmd_mailbox *mailbox;
 	int err;
-	u8 is_eth = dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH;
+
+	if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
+		return 0;
 
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
 
 	memset(mailbox->buf, 0, 256);
-	if (is_eth) {
-		((u8 *) mailbox->buf)[3] = 6;
-		((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
-		((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
-	} else
-		((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
-	err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
+
+	((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
+	err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
 		       MLX4_CMD_TIME_CLASS_B);
 
 	mlx4_free_cmd_mailbox(dev, mailbox);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mlx4/sense.c linux-libre-2.6.30-gnu1/drivers/net/mlx4/sense.c
--- linux-libre-2.6.29-gnu1/drivers/net/mlx4/sense.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/mlx4/sense.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/if_ether.h>
+
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4.h"
+
+static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
+			   enum mlx4_port_type *type)
+{
+	u64 out_param;
+	int err = 0;
+
+	err = mlx4_cmd_imm(dev, 0, &out_param, port, 0,
+			   MLX4_CMD_SENSE_PORT, MLX4_CMD_TIME_CLASS_B);
+	if (err) {
+		mlx4_err(dev, "Sense command failed for port: %d\n", port);
+		return err;
+	}
+
+	if (out_param > 2) {
+		mlx4_err(dev, "Sense returned illegal value: 0x%llx\n", out_param);
+		return EINVAL;
+	}
+
+	*type = out_param;
+	return 0;
+}
+
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+			 enum mlx4_port_type *stype,
+			 enum mlx4_port_type *defaults)
+{
+	struct mlx4_sense *sense = &mlx4_priv(dev)->sense;
+	int err;
+	int i;
+
+	for (i = 1; i <= dev->caps.num_ports; i++) {
+		stype[i - 1] = 0;
+		if (sense->do_sense_port[i] && sense->sense_allowed[i] &&
+		    dev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+			err = mlx4_SENSE_PORT(dev, i, &stype[i - 1]);
+			if (err)
+				stype[i - 1] = defaults[i - 1];
+		} else
+			stype[i - 1] = defaults[i - 1];
+	}
+
+	/*
+	 * Adjust port configuration:
+	 * If port 1 sensed nothing and port 2 is IB, set both as IB
+	 * If port 2 sensed nothing and port 1 is Eth, set both as Eth
+	 */
+	if (stype[0] == MLX4_PORT_TYPE_ETH) {
+		for (i = 1; i < dev->caps.num_ports; i++)
+			stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH;
+	}
+	if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) {
+		for (i = 0; i < dev->caps.num_ports - 1; i++)
+			stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB;
+	}
+
+	/*
+	 * If sensed nothing, remain in current configuration.
+	 */
+	for (i = 0; i < dev->caps.num_ports; i++)
+		stype[i] = stype[i] ? stype[i] : defaults[i];
+
+}
+
+static void mlx4_sense_port(struct work_struct *work)
+{
+	struct delayed_work *delay = to_delayed_work(work);
+	struct mlx4_sense *sense = container_of(delay, struct mlx4_sense,
+						sense_poll);
+	struct mlx4_dev *dev = sense->dev;
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	enum mlx4_port_type stype[MLX4_MAX_PORTS];
+
+	mutex_lock(&priv->port_mutex);
+	mlx4_do_sense_ports(dev, stype, &dev->caps.port_type[1]);
+
+	if (mlx4_check_port_params(dev, stype))
+		goto sense_again;
+
+	if (mlx4_change_port_types(dev, stype))
+		mlx4_err(dev, "Failed to change port_types\n");
+
+sense_again:
+	mutex_unlock(&priv->port_mutex);
+	queue_delayed_work(mlx4_wq , &sense->sense_poll,
+			   round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_start_sense(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_sense *sense = &priv->sense;
+
+	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP))
+		return;
+
+	queue_delayed_work(mlx4_wq , &sense->sense_poll,
+			   round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_stop_sense(struct mlx4_dev *dev)
+{
+	cancel_delayed_work_sync(&mlx4_priv(dev)->sense.sense_poll);
+}
+
+void  mlx4_sense_init(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_sense *sense = &priv->sense;
+	int port;
+
+	sense->dev = dev;
+	for (port = 1; port <= dev->caps.num_ports; port++)
+		sense->do_sense_port[port] = 1;
+
+	INIT_DELAYED_WORK_DEFERRABLE(&sense->sense_poll, mlx4_sense_port);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/mv643xx_eth.c linux-libre-2.6.30-gnu1/drivers/net/mv643xx_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/mv643xx_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/mv643xx_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/io.h>
 #include <linux/types.h>
+#include <linux/inet_lro.h>
 #include <asm/system.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
@@ -227,6 +228,12 @@ struct tx_desc {
 #define RX_ENABLE_INTERRUPT		0x20000000
 #define RX_FIRST_DESC			0x08000000
 #define RX_LAST_DESC			0x04000000
+#define RX_IP_HDR_OK			0x02000000
+#define RX_PKT_IS_IPV4			0x01000000
+#define RX_PKT_IS_ETHERNETV2		0x00800000
+#define RX_PKT_LAYER4_TYPE_MASK		0x00600000
+#define RX_PKT_LAYER4_TYPE_TCP_IPV4	0x00000000
+#define RX_PKT_IS_VLAN_TAGGED		0x00080000
 
 /* TX descriptor command */
 #define TX_ENABLE_INTERRUPT		0x00800000
@@ -286,6 +293,9 @@ struct mv643xx_eth_shared_private {
 #define TX_BW_CONTROL_OLD_LAYOUT	1
 #define TX_BW_CONTROL_NEW_LAYOUT	2
 
+static int mv643xx_eth_open(struct net_device *dev);
+static int mv643xx_eth_stop(struct net_device *dev);
+
 
 /* per-port *****************************************************************/
 struct mib_counters {
@@ -321,6 +331,12 @@ struct mib_counters {
 	u32 late_collision;
 };
 
+struct lro_counters {
+	u32 lro_aggregated;
+	u32 lro_flushed;
+	u32 lro_no_desc;
+};
+
 struct rx_queue {
 	int index;
 
@@ -334,6 +350,9 @@ struct rx_queue {
 	dma_addr_t rx_desc_dma;
 	int rx_desc_area_size;
 	struct sk_buff **rx_skb;
+
+	struct net_lro_mgr lro_mgr;
+	struct net_lro_desc lro_arr[8];
 };
 
 struct tx_queue {
@@ -369,15 +388,17 @@ struct mv643xx_eth_private {
 	spinlock_t mib_counters_lock;
 	struct mib_counters mib_counters;
 
+	struct lro_counters lro_counters;
+
 	struct work_struct tx_timeout_task;
 
 	struct napi_struct napi;
+	u8 oom;
 	u8 work_link;
 	u8 work_tx;
 	u8 work_tx_end;
 	u8 work_rx;
 	u8 work_rx_refill;
-	u8 work_rx_oom;
 
 	int skb_size;
 	struct sk_buff_head rx_recycle;
@@ -385,7 +406,7 @@ struct mv643xx_eth_private {
 	/*
 	 * RX state.
 	 */
-	int default_rx_ring_size;
+	int rx_ring_size;
 	unsigned long rx_desc_sram_addr;
 	int rx_desc_sram_size;
 	int rxq_count;
@@ -395,7 +416,7 @@ struct mv643xx_eth_private {
 	/*
 	 * TX state.
 	 */
-	int default_tx_ring_size;
+	int tx_ring_size;
 	unsigned long tx_desc_sram_addr;
 	int tx_desc_sram_size;
 	int txq_count;
@@ -493,12 +514,40 @@ static void txq_maybe_wake(struct tx_que
 
 
 /* rx napi ******************************************************************/
+static int
+mv643xx_get_skb_header(struct sk_buff *skb, void **iphdr, void **tcph,
+		       u64 *hdr_flags, void *priv)
+{
+	unsigned long cmd_sts = (unsigned long)priv;
+
+	/*
+	 * Make sure that this packet is Ethernet II, is not VLAN
+	 * tagged, is IPv4, has a valid IP header, and is TCP.
+	 */
+	if ((cmd_sts & (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+		       RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_MASK |
+		       RX_PKT_IS_VLAN_TAGGED)) !=
+	    (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+	     RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_TCP_IPV4))
+		return -1;
+
+	skb_reset_network_header(skb);
+	skb_set_transport_header(skb, ip_hdrlen(skb));
+	*iphdr = ip_hdr(skb);
+	*tcph = tcp_hdr(skb);
+	*hdr_flags = LRO_IPV4 | LRO_TCP;
+
+	return 0;
+}
+
 static int rxq_process(struct rx_queue *rxq, int budget)
 {
 	struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
 	struct net_device_stats *stats = &mp->dev->stats;
+	int lro_flush_needed;
 	int rx;
 
+	lro_flush_needed = 0;
 	rx = 0;
 	while (rx < budget && rxq->rx_desc_count) {
 		struct rx_desc *rx_desc;
@@ -520,7 +569,7 @@ static int rxq_process(struct rx_queue *
 		if (rxq->rx_curr_desc == rxq->rx_ring_size)
 			rxq->rx_curr_desc = 0;
 
-		dma_unmap_single(NULL, rx_desc->buf_ptr,
+		dma_unmap_single(mp->dev->dev.parent, rx_desc->buf_ptr,
 				 rx_desc->buf_size, DMA_FROM_DEVICE);
 		rxq->rx_desc_count--;
 		rx++;
@@ -558,7 +607,13 @@ static int rxq_process(struct rx_queue *
 		if (cmd_sts & LAYER_4_CHECKSUM_OK)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		skb->protocol = eth_type_trans(skb, mp->dev);
-		netif_receive_skb(skb);
+
+		if (skb->dev->features & NETIF_F_LRO &&
+		    skb->ip_summed == CHECKSUM_UNNECESSARY) {
+			lro_receive_skb(&rxq->lro_mgr, skb, (void *)cmd_sts);
+			lro_flush_needed = 1;
+		} else
+			netif_receive_skb(skb);
 
 		continue;
 
@@ -579,6 +634,9 @@ err:
 		dev_kfree_skb(skb);
 	}
 
+	if (lro_flush_needed)
+		lro_flush_all(&rxq->lro_mgr);
+
 	if (rx < budget)
 		mp->work_rx &= ~(1 << rxq->index);
 
@@ -603,7 +661,7 @@ static int rxq_refill(struct rx_queue *r
 					    dma_get_cache_alignment() - 1);
 
 		if (skb == NULL) {
-			mp->work_rx_oom |= 1 << rxq->index;
+			mp->oom = 1;
 			goto oom;
 		}
 
@@ -620,8 +678,9 @@ static int rxq_refill(struct rx_queue *r
 
 		rx_desc = rxq->rx_desc_area + rx;
 
-		rx_desc->buf_ptr = dma_map_single(NULL, skb->data,
-					mp->skb_size, DMA_FROM_DEVICE);
+		rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
+						  skb->data, mp->skb_size,
+						  DMA_FROM_DEVICE);
 		rx_desc->buf_size = mp->skb_size;
 		rxq->rx_skb[rx] = skb;
 		wmb();
@@ -660,6 +719,7 @@ static inline unsigned int has_tiny_unal
 
 static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
 {
+	struct mv643xx_eth_private *mp = txq_to_mp(txq);
 	int nr_frags = skb_shinfo(skb)->nr_frags;
 	int frag;
 
@@ -688,10 +748,10 @@ static void txq_submit_frag_skb(struct t
 
 		desc->l4i_chk = 0;
 		desc->byte_cnt = this_frag->size;
-		desc->buf_ptr = dma_map_page(NULL, this_frag->page,
-						this_frag->page_offset,
-						this_frag->size,
-						DMA_TO_DEVICE);
+		desc->buf_ptr = dma_map_page(mp->dev->dev.parent,
+					     this_frag->page,
+					     this_frag->page_offset,
+					     this_frag->size, DMA_TO_DEVICE);
 	}
 }
 
@@ -768,7 +828,8 @@ no_csum:
 
 	desc->l4i_chk = l4i_chk;
 	desc->byte_cnt = length;
-	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+	desc->buf_ptr = dma_map_single(mp->dev->dev.parent, skb->data,
+				       length, DMA_TO_DEVICE);
 
 	__skb_queue_tail(&txq->tx_skb, skb);
 
@@ -898,16 +959,16 @@ static int txq_reclaim(struct tx_queue *
 		}
 
 		if (cmd_sts & TX_FIRST_DESC) {
-			dma_unmap_single(NULL, desc->buf_ptr,
+			dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr,
 					 desc->byte_cnt, DMA_TO_DEVICE);
 		} else {
-			dma_unmap_page(NULL, desc->buf_ptr,
+			dma_unmap_page(mp->dev->dev.parent, desc->buf_ptr,
 				       desc->byte_cnt, DMA_TO_DEVICE);
 		}
 
 		if (skb != NULL) {
 			if (skb_queue_len(&mp->rx_recycle) <
-					mp->default_rx_ring_size &&
+					mp->rx_ring_size &&
 			    skb_recycle_check(skb, mp->skb_size +
 					dma_get_cache_alignment() - 1))
 				__skb_queue_head(&mp->rx_recycle, skb);
@@ -1158,6 +1219,26 @@ static struct net_device_stats *mv643xx_
 	return stats;
 }
 
+static void mv643xx_eth_grab_lro_stats(struct mv643xx_eth_private *mp)
+{
+	u32 lro_aggregated = 0;
+	u32 lro_flushed = 0;
+	u32 lro_no_desc = 0;
+	int i;
+
+	for (i = 0; i < mp->rxq_count; i++) {
+		struct rx_queue *rxq = mp->rxq + i;
+
+		lro_aggregated += rxq->lro_mgr.stats.aggregated;
+		lro_flushed += rxq->lro_mgr.stats.flushed;
+		lro_no_desc += rxq->lro_mgr.stats.no_desc;
+	}
+
+	mp->lro_counters.lro_aggregated = lro_aggregated;
+	mp->lro_counters.lro_flushed = lro_flushed;
+	mp->lro_counters.lro_no_desc = lro_no_desc;
+}
+
 static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
 {
 	return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);
@@ -1177,7 +1258,6 @@ static void mib_counters_update(struct m
 
 	spin_lock_bh(&mp->mib_counters_lock);
 	p->good_octets_received += mib_read(mp, 0x00);
-	p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
 	p->bad_octets_received += mib_read(mp, 0x08);
 	p->internal_mac_transmit_err += mib_read(mp, 0x0c);
 	p->good_frames_received += mib_read(mp, 0x10);
@@ -1191,7 +1271,6 @@ static void mib_counters_update(struct m
 	p->frames_512_to_1023_octets += mib_read(mp, 0x30);
 	p->frames_1024_to_max_octets += mib_read(mp, 0x34);
 	p->good_octets_sent += mib_read(mp, 0x38);
-	p->good_octets_sent += (u64)mib_read(mp, 0x3c) << 32;
 	p->good_frames_sent += mib_read(mp, 0x40);
 	p->excessive_collision += mib_read(mp, 0x44);
 	p->multicast_frames_sent += mib_read(mp, 0x48);
@@ -1221,6 +1300,85 @@ static void mib_counters_timer_wrapper(u
 }
 
 
+/* interrupt coalescing *****************************************************/
+/*
+ * Hardware coalescing parameters are set in units of 64 t_clk
+ * cycles.  I.e.:
+ *
+ *	coal_delay_in_usec = 64000000 * register_value / t_clk_rate
+ *
+ *	register_value = coal_delay_in_usec * t_clk_rate / 64000000
+ *
+ * In the ->set*() methods, we round the computed register value
+ * to the nearest integer.
+ */
+static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
+{
+	u32 val = rdlp(mp, SDMA_CONFIG);
+	u64 temp;
+
+	if (mp->shared->extended_rx_coal_limit)
+		temp = ((val & 0x02000000) >> 10) | ((val & 0x003fff80) >> 7);
+	else
+		temp = (val & 0x003fff00) >> 8;
+
+	temp *= 64000000;
+	do_div(temp, mp->shared->t_clk);
+
+	return (unsigned int)temp;
+}
+
+static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+	u64 temp;
+	u32 val;
+
+	temp = (u64)usec * mp->shared->t_clk;
+	temp += 31999999;
+	do_div(temp, 64000000);
+
+	val = rdlp(mp, SDMA_CONFIG);
+	if (mp->shared->extended_rx_coal_limit) {
+		if (temp > 0xffff)
+			temp = 0xffff;
+		val &= ~0x023fff80;
+		val |= (temp & 0x8000) << 10;
+		val |= (temp & 0x7fff) << 7;
+	} else {
+		if (temp > 0x3fff)
+			temp = 0x3fff;
+		val &= ~0x003fff00;
+		val |= (temp & 0x3fff) << 8;
+	}
+	wrlp(mp, SDMA_CONFIG, val);
+}
+
+static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
+{
+	u64 temp;
+
+	temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
+	temp *= 64000000;
+	do_div(temp, mp->shared->t_clk);
+
+	return (unsigned int)temp;
+}
+
+static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+	u64 temp;
+
+	temp = (u64)usec * mp->shared->t_clk;
+	temp += 31999999;
+	do_div(temp, 64000000);
+
+	if (temp > 0x3fff)
+		temp = 0x3fff;
+
+	wrlp(mp, TX_FIFO_URGENT_THRESHOLD, temp << 4);
+}
+
+
 /* ethtool ******************************************************************/
 struct mv643xx_eth_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -1237,6 +1395,10 @@ struct mv643xx_eth_stats {
 	{ #m, FIELD_SIZEOF(struct mib_counters, m),		\
 	  -1, offsetof(struct mv643xx_eth_private, mib_counters.m) }
 
+#define LROSTAT(m)						\
+	{ #m, FIELD_SIZEOF(struct lro_counters, m),		\
+	  -1, offsetof(struct mv643xx_eth_private, lro_counters.m) }
+
 static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
 	SSTAT(rx_packets),
 	SSTAT(tx_packets),
@@ -1276,12 +1438,15 @@ static const struct mv643xx_eth_stats mv
 	MIBSTAT(bad_crc_event),
 	MIBSTAT(collision),
 	MIBSTAT(late_collision),
+	LROSTAT(lro_aggregated),
+	LROSTAT(lro_flushed),
+	LROSTAT(lro_no_desc),
 };
 
 static int
-mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+mv643xx_eth_get_settings_phy(struct mv643xx_eth_private *mp,
+			     struct ethtool_cmd *cmd)
 {
-	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	int err;
 
 	err = phy_read_status(mp->phy);
@@ -1298,10 +1463,9 @@ mv643xx_eth_get_settings(struct net_devi
 }
 
 static int
-mv643xx_eth_get_settings_phyless(struct net_device *dev,
+mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp,
 				 struct ethtool_cmd *cmd)
 {
-	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	u32 port_status;
 
 	port_status = rdlp(mp, PORT_STATUS);
@@ -1334,10 +1498,24 @@ mv643xx_eth_get_settings_phyless(struct
 }
 
 static int
+mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	if (mp->phy != NULL)
+		return mv643xx_eth_get_settings_phy(mp, cmd);
+	else
+		return mv643xx_eth_get_settings_phyless(mp, cmd);
+}
+
+static int
 mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 
+	if (mp->phy == NULL)
+		return -EINVAL;
+
 	/*
 	 * The MAC does not support 1000baseT_Half.
 	 */
@@ -1346,13 +1524,6 @@ mv643xx_eth_set_settings(struct net_devi
 	return phy_ethtool_sset(mp->phy, cmd);
 }
 
-static int
-mv643xx_eth_set_settings_phyless(struct net_device *dev,
-				 struct ethtool_cmd *cmd)
-{
-	return -EINVAL;
-}
-
 static void mv643xx_eth_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *drvinfo)
 {
@@ -1367,17 +1538,95 @@ static int mv643xx_eth_nway_reset(struct
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 
+	if (mp->phy == NULL)
+		return -EINVAL;
+
 	return genphy_restart_aneg(mp->phy);
 }
 
-static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
+static u32 mv643xx_eth_get_link(struct net_device *dev)
 {
-	return -EINVAL;
+	return !!netif_carrier_ok(dev);
 }
 
-static u32 mv643xx_eth_get_link(struct net_device *dev)
+static int
+mv643xx_eth_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
 {
-	return !!netif_carrier_ok(dev);
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	ec->rx_coalesce_usecs = get_rx_coal(mp);
+	ec->tx_coalesce_usecs = get_tx_coal(mp);
+
+	return 0;
+}
+
+static int
+mv643xx_eth_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	set_rx_coal(mp, ec->rx_coalesce_usecs);
+	set_tx_coal(mp, ec->tx_coalesce_usecs);
+
+	return 0;
+}
+
+static void
+mv643xx_eth_get_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	er->rx_max_pending = 4096;
+	er->tx_max_pending = 4096;
+	er->rx_mini_max_pending = 0;
+	er->rx_jumbo_max_pending = 0;
+
+	er->rx_pending = mp->rx_ring_size;
+	er->tx_pending = mp->tx_ring_size;
+	er->rx_mini_pending = 0;
+	er->rx_jumbo_pending = 0;
+}
+
+static int
+mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	if (er->rx_mini_pending || er->rx_jumbo_pending)
+		return -EINVAL;
+
+	mp->rx_ring_size = er->rx_pending < 4096 ? er->rx_pending : 4096;
+	mp->tx_ring_size = er->tx_pending < 4096 ? er->tx_pending : 4096;
+
+	if (netif_running(dev)) {
+		mv643xx_eth_stop(dev);
+		if (mv643xx_eth_open(dev)) {
+			dev_printk(KERN_ERR, &dev->dev,
+				   "fatal error on re-opening device after "
+				   "ring param change\n");
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+static u32
+mv643xx_eth_get_rx_csum(struct net_device *dev)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
+}
+
+static int
+mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+{
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+	wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
+
+	return 0;
 }
 
 static void mv643xx_eth_get_strings(struct net_device *dev,
@@ -1403,6 +1652,7 @@ static void mv643xx_eth_get_ethtool_stat
 
 	mv643xx_eth_get_stats(dev);
 	mib_counters_update(mp);
+	mv643xx_eth_grab_lro_stats(mp);
 
 	for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
 		const struct mv643xx_eth_stats *stat;
@@ -1434,21 +1684,18 @@ static const struct ethtool_ops mv643xx_
 	.get_drvinfo		= mv643xx_eth_get_drvinfo,
 	.nway_reset		= mv643xx_eth_nway_reset,
 	.get_link		= mv643xx_eth_get_link,
+	.get_coalesce		= mv643xx_eth_get_coalesce,
+	.set_coalesce		= mv643xx_eth_set_coalesce,
+	.get_ringparam		= mv643xx_eth_get_ringparam,
+	.set_ringparam		= mv643xx_eth_set_ringparam,
+	.get_rx_csum		= mv643xx_eth_get_rx_csum,
+	.set_rx_csum		= mv643xx_eth_set_rx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_csum,
 	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= mv643xx_eth_get_strings,
 	.get_ethtool_stats	= mv643xx_eth_get_ethtool_stats,
-	.get_sset_count		= mv643xx_eth_get_sset_count,
-};
-
-static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
-	.get_settings		= mv643xx_eth_get_settings_phyless,
-	.set_settings		= mv643xx_eth_set_settings_phyless,
-	.get_drvinfo		= mv643xx_eth_get_drvinfo,
-	.nway_reset		= mv643xx_eth_nway_reset_phyless,
-	.get_link		= mv643xx_eth_get_link,
-	.set_sg			= ethtool_op_set_sg,
-	.get_strings		= mv643xx_eth_get_strings,
-	.get_ethtool_stats	= mv643xx_eth_get_ethtool_stats,
+	.get_flags		= ethtool_op_get_flags,
+	.set_flags		= ethtool_op_set_flags,
 	.get_sset_count		= mv643xx_eth_get_sset_count,
 };
 
@@ -1637,7 +1884,7 @@ static int rxq_init(struct mv643xx_eth_p
 
 	rxq->index = index;
 
-	rxq->rx_ring_size = mp->default_rx_ring_size;
+	rxq->rx_ring_size = mp->rx_ring_size;
 
 	rxq->rx_desc_count = 0;
 	rxq->rx_curr_desc = 0;
@@ -1650,9 +1897,9 @@ static int rxq_init(struct mv643xx_eth_p
 						mp->rx_desc_sram_size);
 		rxq->rx_desc_dma = mp->rx_desc_sram_addr;
 	} else {
-		rxq->rx_desc_area = dma_alloc_coherent(NULL, size,
-							&rxq->rx_desc_dma,
-							GFP_KERNEL);
+		rxq->rx_desc_area = dma_alloc_coherent(mp->dev->dev.parent,
+						       size, &rxq->rx_desc_dma,
+						       GFP_KERNEL);
 	}
 
 	if (rxq->rx_desc_area == NULL) {
@@ -1683,6 +1930,19 @@ static int rxq_init(struct mv643xx_eth_p
 					nexti * sizeof(struct rx_desc);
 	}
 
+	rxq->lro_mgr.dev = mp->dev;
+	memset(&rxq->lro_mgr.stats, 0, sizeof(rxq->lro_mgr.stats));
+	rxq->lro_mgr.features = LRO_F_NAPI;
+	rxq->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+	rxq->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+	rxq->lro_mgr.max_desc = ARRAY_SIZE(rxq->lro_arr);
+	rxq->lro_mgr.max_aggr = 32;
+	rxq->lro_mgr.frag_align_pad = 0;
+	rxq->lro_mgr.lro_arr = rxq->lro_arr;
+	rxq->lro_mgr.get_skb_header = mv643xx_get_skb_header;
+
+	memset(&rxq->lro_arr, 0, sizeof(rxq->lro_arr));
+
 	return 0;
 
 
@@ -1690,7 +1950,7 @@ out_free:
 	if (index == 0 && size <= mp->rx_desc_sram_size)
 		iounmap(rxq->rx_desc_area);
 	else
-		dma_free_coherent(NULL, size,
+		dma_free_coherent(mp->dev->dev.parent, size,
 				  rxq->rx_desc_area,
 				  rxq->rx_desc_dma);
 
@@ -1722,7 +1982,7 @@ static void rxq_deinit(struct rx_queue *
 	    rxq->rx_desc_area_size <= mp->rx_desc_sram_size)
 		iounmap(rxq->rx_desc_area);
 	else
-		dma_free_coherent(NULL, rxq->rx_desc_area_size,
+		dma_free_coherent(mp->dev->dev.parent, rxq->rx_desc_area_size,
 				  rxq->rx_desc_area, rxq->rx_desc_dma);
 
 	kfree(rxq->rx_skb);
@@ -1737,7 +1997,7 @@ static int txq_init(struct mv643xx_eth_p
 
 	txq->index = index;
 
-	txq->tx_ring_size = mp->default_tx_ring_size;
+	txq->tx_ring_size = mp->tx_ring_size;
 
 	txq->tx_desc_count = 0;
 	txq->tx_curr_desc = 0;
@@ -1750,9 +2010,9 @@ static int txq_init(struct mv643xx_eth_p
 						mp->tx_desc_sram_size);
 		txq->tx_desc_dma = mp->tx_desc_sram_addr;
 	} else {
-		txq->tx_desc_area = dma_alloc_coherent(NULL, size,
-							&txq->tx_desc_dma,
-							GFP_KERNEL);
+		txq->tx_desc_area = dma_alloc_coherent(mp->dev->dev.parent,
+						       size, &txq->tx_desc_dma,
+						       GFP_KERNEL);
 	}
 
 	if (txq->tx_desc_area == NULL) {
@@ -1796,7 +2056,7 @@ static void txq_deinit(struct tx_queue *
 	    txq->tx_desc_area_size <= mp->tx_desc_sram_size)
 		iounmap(txq->tx_desc_area);
 	else
-		dma_free_coherent(NULL, txq->tx_desc_area_size,
+		dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size,
 				  txq->tx_desc_area, txq->tx_desc_dma);
 }
 
@@ -1908,8 +2168,10 @@ static int mv643xx_eth_poll(struct napi_
 
 	mp = container_of(napi, struct mv643xx_eth_private, napi);
 
-	mp->work_rx_refill |= mp->work_rx_oom;
-	mp->work_rx_oom = 0;
+	if (unlikely(mp->oom)) {
+		mp->oom = 0;
+		del_timer(&mp->rx_oom);
+	}
 
 	work_done = 0;
 	while (work_done < budget) {
@@ -1923,8 +2185,10 @@ static int mv643xx_eth_poll(struct napi_
 			continue;
 		}
 
-		queue_mask = mp->work_tx | mp->work_tx_end |
-				mp->work_rx | mp->work_rx_refill;
+		queue_mask = mp->work_tx | mp->work_tx_end | mp->work_rx;
+		if (likely(!mp->oom))
+			queue_mask |= mp->work_rx_refill;
+
 		if (!queue_mask) {
 			if (mv643xx_eth_collect_events(mp))
 				continue;
@@ -1945,7 +2209,7 @@ static int mv643xx_eth_poll(struct napi_
 			txq_maybe_wake(mp->txq + queue);
 		} else if (mp->work_rx & queue_mask) {
 			work_done += rxq_process(mp->rxq + queue, work_tbd);
-		} else if (mp->work_rx_refill & queue_mask) {
+		} else if (!mp->oom && (mp->work_rx_refill & queue_mask)) {
 			work_done += rxq_refill(mp->rxq + queue, work_tbd);
 		} else {
 			BUG();
@@ -1953,7 +2217,7 @@ static int mv643xx_eth_poll(struct napi_
 	}
 
 	if (work_done < budget) {
-		if (mp->work_rx_oom)
+		if (mp->oom)
 			mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
 		napi_complete(napi);
 		wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
@@ -2015,8 +2279,6 @@ static void port_start(struct mv643xx_et
 		pscr |= FORCE_LINK_PASS;
 	wrlp(mp, PORT_SERIAL_CONTROL, pscr);
 
-	wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
-
 	/*
 	 * Configure TX path and queues.
 	 */
@@ -2061,36 +2323,6 @@ static void port_start(struct mv643xx_et
 	}
 }
 
-static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
-	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
-	u32 val;
-
-	val = rdlp(mp, SDMA_CONFIG);
-	if (mp->shared->extended_rx_coal_limit) {
-		if (coal > 0xffff)
-			coal = 0xffff;
-		val &= ~0x023fff80;
-		val |= (coal & 0x8000) << 10;
-		val |= (coal & 0x7fff) << 7;
-	} else {
-		if (coal > 0x3fff)
-			coal = 0x3fff;
-		val &= ~0x003fff00;
-		val |= (coal & 0x3fff) << 8;
-	}
-	wrlp(mp, SDMA_CONFIG, val);
-}
-
-static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
-	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
-
-	if (coal > 0x3fff)
-		coal = 0x3fff;
-	wrlp(mp, TX_FIFO_URGENT_THRESHOLD, (coal & 0x3fff) << 4);
-}
-
 static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
 {
 	int skb_size;
@@ -2145,7 +2377,7 @@ static int mv643xx_eth_open(struct net_d
 		rxq_refill(mp->rxq + i, INT_MAX);
 	}
 
-	if (mp->work_rx_oom) {
+	if (mp->oom) {
 		mp->rx_oom.expires = jiffies + (HZ / 10);
 		add_timer(&mp->rx_oom);
 	}
@@ -2159,13 +2391,8 @@ static int mv643xx_eth_open(struct net_d
 		}
 	}
 
-	netif_carrier_off(dev);
-
 	port_start(mp);
 
-	set_rx_coal(mp, 0);
-	set_tx_coal(mp, 0);
-
 	wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
 	wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
 
@@ -2531,17 +2758,17 @@ static void set_params(struct mv643xx_et
 	else
 		uc_addr_get(mp, dev->dev_addr);
 
-	mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
+	mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
 	if (pd->rx_queue_size)
-		mp->default_rx_ring_size = pd->rx_queue_size;
+		mp->rx_ring_size = pd->rx_queue_size;
 	mp->rx_desc_sram_addr = pd->rx_sram_addr;
 	mp->rx_desc_sram_size = pd->rx_sram_size;
 
 	mp->rxq_count = pd->rx_queue_count ? : 1;
 
-	mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
+	mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
 	if (pd->tx_queue_size)
-		mp->default_tx_ring_size = pd->tx_queue_size;
+		mp->tx_ring_size = pd->tx_queue_size;
 	mp->tx_desc_sram_addr = pd->tx_sram_addr;
 	mp->tx_desc_sram_size = pd->tx_sram_size;
 
@@ -2588,7 +2815,7 @@ static void phy_init(struct mv643xx_eth_
 
 	phy_reset(mp);
 
-	phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+	phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII);
 
 	if (speed == 0) {
 		phy->autoneg = AUTONEG_ENABLE;
@@ -2632,6 +2859,21 @@ static void init_pscr(struct mv643xx_eth
 	wrlp(mp, PORT_SERIAL_CONTROL, pscr);
 }
 
+static const struct net_device_ops mv643xx_eth_netdev_ops = {
+	.ndo_open		= mv643xx_eth_open,
+	.ndo_stop		= mv643xx_eth_stop,
+	.ndo_start_xmit		= mv643xx_eth_xmit,
+	.ndo_set_rx_mode	= mv643xx_eth_set_rx_mode,
+	.ndo_set_mac_address	= mv643xx_eth_set_mac_address,
+	.ndo_do_ioctl		= mv643xx_eth_ioctl,
+	.ndo_change_mtu		= mv643xx_eth_change_mtu,
+	.ndo_tx_timeout		= mv643xx_eth_tx_timeout,
+	.ndo_get_stats		= mv643xx_eth_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= mv643xx_eth_netpoll,
+#endif
+};
+
 static int mv643xx_eth_probe(struct platform_device *pdev)
 {
 	struct mv643xx_eth_platform_data *pd;
@@ -2672,12 +2914,10 @@ static int mv643xx_eth_probe(struct plat
 	if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
 		mp->phy = phy_scan(mp, pd->phy_addr);
 
-	if (mp->phy != NULL) {
+	if (mp->phy != NULL)
 		phy_init(mp, pd->speed, pd->duplex);
-		SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
-	} else {
-		SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
-	}
+
+	SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
 
 	init_pscr(mp, pd->speed, pd->duplex);
 
@@ -2705,18 +2945,8 @@ static int mv643xx_eth_probe(struct plat
 	BUG_ON(!res);
 	dev->irq = res->start;
 
-	dev->get_stats = mv643xx_eth_get_stats;
-	dev->hard_start_xmit = mv643xx_eth_xmit;
-	dev->open = mv643xx_eth_open;
-	dev->stop = mv643xx_eth_stop;
-	dev->set_rx_mode = mv643xx_eth_set_rx_mode;
-	dev->set_mac_address = mv643xx_eth_set_mac_address;
-	dev->do_ioctl = mv643xx_eth_ioctl;
-	dev->change_mtu = mv643xx_eth_change_mtu;
-	dev->tx_timeout = mv643xx_eth_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = mv643xx_eth_netpoll;
-#endif
+	dev->netdev_ops = &mv643xx_eth_netdev_ops;
+
 	dev->watchdog_timeo = 2 * HZ;
 	dev->base_addr = 0;
 
@@ -2728,6 +2958,13 @@ static int mv643xx_eth_probe(struct plat
 	if (mp->shared->win_protect)
 		wrl(mp, WINDOW_PROTECT(mp->port_num), mp->shared->win_protect);
 
+	netif_carrier_off(dev);
+
+	wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
+
+	set_rx_coal(mp, 250);
+	set_tx_coal(mp, 0);
+
 	err = register_netdev(dev);
 	if (err)
 		goto out;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/myri10ge/myri10ge.c linux-libre-2.6.30-gnu1/drivers/net/myri10ge/myri10ge.c
--- linux-libre-2.6.29-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 18:03:02.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/myri10ge/myri10ge.c	2013-05-03 16:46:55.000000000 -0400
@@ -1130,7 +1130,7 @@ myri10ge_submit_8rx(struct mcp_kreq_ethe
 	__be32 low;
 
 	low = src->addr_low;
-	src->addr_low = htonl(DMA_32BIT_MASK);
+	src->addr_low = htonl(DMA_BIT_MASK(32));
 	myri10ge_pio_copy(dst, src, 4 * sizeof(*src));
 	mb();
 	myri10ge_pio_copy(dst + 4, src + 4, 4 * sizeof(*src));
@@ -1324,6 +1324,7 @@ myri10ge_rx_done(struct myri10ge_slice_s
 		skb_shinfo(skb)->nr_frags = 0;
 	}
 	skb->protocol = eth_type_trans(skb, dev);
+	skb_record_rx_queue(skb, ss - &mgp->ss[0]);
 
 	if (mgp->csum_flag) {
 		if ((skb->protocol == htons(ETH_P_IP)) ||
@@ -1514,7 +1515,7 @@ static int myri10ge_poll(struct napi_str
 	work_done = myri10ge_clean_rx_done(ss, budget);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		put_be32(htonl(3), ss->irq_claim);
 	}
 	return work_done;
@@ -1532,7 +1533,7 @@ static irqreturn_t myri10ge_intr(int irq
 	/* an interrupt on a non-zero receive-only slice is implicitly
 	 * valid  since MSI-X irqs are not shared */
 	if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
-		netif_rx_schedule(&ss->napi);
+		napi_schedule(&ss->napi);
 		return (IRQ_HANDLED);
 	}
 
@@ -1543,7 +1544,7 @@ static irqreturn_t myri10ge_intr(int irq
 	/* low bit indicates receives are present, so schedule
 	 * napi poll handler */
 	if (stats->valid & 1)
-		netif_rx_schedule(&ss->napi);
+		napi_schedule(&ss->napi);
 
 	if (!mgp->msi_enabled && !mgp->msix_enabled) {
 		put_be32(0, mgp->irq_deassert);
@@ -2446,6 +2447,7 @@ static int myri10ge_open(struct net_devi
 		lro_mgr->lro_arr = ss->rx_done.lro_desc;
 		lro_mgr->get_frag_header = myri10ge_get_frag_header;
 		lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+		lro_mgr->frag_align_pad = 2;
 		if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
 			lro_mgr->max_aggr = MAX_SKB_FRAGS;
 
@@ -3784,19 +3786,19 @@ static int myri10ge_probe(struct pci_dev
 
 	pci_set_master(pdev);
 	dac_enabled = 1;
-	status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+	status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
 	if (status != 0) {
 		dac_enabled = 0;
 		dev_err(&pdev->dev,
 			"64-bit pci address mask was refused, "
 			"trying 32-bit\n");
-		status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	}
 	if (status != 0) {
 		dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
 		goto abort_with_enabled;
 	}
-	(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+	(void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
 				      &mgp->cmd_bus, GFP_KERNEL);
 	if (mgp->cmd == NULL)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/myri10ge/myri10ge_mcp_gen_header.h linux-libre-2.6.30-gnu1/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
--- linux-libre-2.6.29-gnu1/drivers/net/myri10ge/myri10ge_mcp_gen_header.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/myri10ge/myri10ge_mcp_gen_header.h	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@
 #define MCP_TYPE_ETH 0x45544820	/* "ETH " */
 #define MCP_TYPE_MCP0 0x4d435030	/* "MCP0" */
 #define MCP_TYPE_DFLT 0x20202020	/* "    " */
+#define MCP_TYPE_ETHZ 0x4554485a	/* "ETHZ" */
 
 struct mcp_gen_header {
 	/* the first 4 fields are filled at compile time */
@@ -43,7 +44,15 @@ struct mcp_gen_header {
 	unsigned msix_table_addr;	/* start address of msix table in firmware */
 	unsigned bss_addr;	/* start of bss */
 	unsigned features;
+	unsigned ee_hdr_addr;
 	/* 8 */
 };
 
+struct zmcp_info {
+	unsigned info_len;
+	unsigned zmcp_addr;
+	unsigned zmcp_len;
+	unsigned mcp_edata;
+};
+
 #endif				/* __MYRI10GE_MCP_GEN_HEADER_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/myri_sbus.c linux-libre-2.6.30-gnu1/drivers/net/myri_sbus.c
--- linux-libre-2.6.29-gnu1/drivers/net/myri_sbus.c	2013-05-03 18:02:59.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/myri_sbus.c	2013-05-03 16:46:51.000000000 -0400
@@ -25,6 +25,7 @@ static char version[] =
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/firmware.h>
 
 #include <net/dst.h>
 #include <net/arp.h>
@@ -43,7 +44,6 @@ static char version[] =
 #include <asm/irq.h>
 
 #include "myri_sbus.h"
-/*(DEBLOBBED)*/
 
 /* #define DEBUG_DETECT */
 /* #define DEBUG_IRQ */
@@ -81,6 +81,9 @@ static char version[] =
 #define DHDR(x)
 #endif
 
+/* Firmware name */
+#define FWNAME		"/*(DEBLOBBED)*/"
+
 static void myri_reset_off(void __iomem *lp, void __iomem *cregs)
 {
 	/* Clear IRQ mask. */
@@ -171,10 +174,11 @@ static int myri_do_handshake(struct myri
 
 static int __devinit myri_load_lanai(struct myri_eth *mp)
 {
+	const struct firmware	*fw;
 	struct net_device	*dev = mp->dev;
 	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem		*rptr;
-	int 			i;
+	int 			i, lanai4_data_size;
 
 	myri_disable_irq(mp->lregs, mp->cregs);
 	myri_reset_on(mp->cregs);
@@ -186,7 +190,27 @@ static int __devinit myri_load_lanai(str
 	if (mp->eeprom.cpuvers >= CPUVERS_3_0)
 		sbus_writel(mp->eeprom.cval, mp->lregs + LANAI_CVAL);
 
-	/*(DEBLOBBED)*/
+	i = reject_firmware(&fw, FWNAME, &mp->myri_op->dev);
+	if (i) {
+		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+		       FWNAME, i);
+		return i;
+	}
+	if (fw->size < 2) {
+		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+		       fw->size, FWNAME);
+		release_firmware(fw);
+		return -EINVAL;
+	}
+	lanai4_data_size = fw->data[0] << 8 | fw->data[1];
+
+	/* Load executable code. */
+	for (i = 2; i < fw->size; i++)
+		sbus_writeb(fw->data[i], rptr++);
+
+	/* Load data segment. */
+	for (i = 0; i < lanai4_data_size; i++)
+		sbus_writeb(0, rptr++);
 
 	/* Set device address. */
 	sbus_writeb(0, &shmem->addr[0]);
@@ -222,6 +246,7 @@ static int __devinit myri_load_lanai(str
 	if (mp->eeprom.cpuvers == CPUVERS_4_0)
 		sbus_writel(0, mp->lregs + LANAI_VERS);
 
+	release_firmware(fw);
 	return i;
 }
 
@@ -742,7 +767,7 @@ static int myri_rebuild_header(struct sk
 	switch (eth->h_proto)
 	{
 #ifdef CONFIG_INET
-	case __constant_htons(ETH_P_IP):
+	case cpu_to_be16(ETH_P_IP):
  		return arp_find(eth->h_dest, skb);
 #endif
 
@@ -890,6 +915,17 @@ static const struct header_ops myri_head
 	.cache_update	= myri_header_cache_update,
 };
 
+static const struct net_device_ops myri_ops = {
+	.ndo_open		= myri_open,
+	.ndo_stop		= myri_close,
+	.ndo_start_xmit		= myri_start_xmit,
+	.ndo_set_multicast_list	= myri_set_multicast,
+	.ndo_tx_timeout		= myri_tx_timeout,
+	.ndo_change_mtu		= myri_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
 	struct device_node *dp = op->node;
@@ -1042,13 +1078,9 @@ static int __devinit myri_sbus_probe(str
 	sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL);
 
 	mp->dev = dev;
-	dev->open = &myri_open;
-	dev->stop = &myri_close;
-	dev->hard_start_xmit = &myri_start_xmit;
-	dev->tx_timeout = &myri_tx_timeout;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &myri_set_multicast;
 	dev->irq = op->irqs[0];
+	dev->netdev_ops = &myri_ops;
 
 	/* Register interrupt handler now. */
 	DET(("Requesting MYRIcom IRQ line.\n"));
@@ -1059,16 +1091,16 @@ static int __devinit myri_sbus_probe(str
 	}
 
 	dev->mtu		= MYRINET_MTU;
-	dev->change_mtu		= myri_change_mtu;
 	dev->header_ops		= &myri_header_ops;
 
 	dev->hard_header_len	= (ETH_HLEN + MYRI_PAD_LEN);
 
 	/* Load code onto the LANai. */
 	DET(("Loading LANAI firmware\n"));
-	printk(KERN_ERR "Missing Free firmware\n");
-	goto err_free_irq;
-	myri_load_lanai(mp);
+	if (myri_load_lanai(mp)) {
+		printk(KERN_ERR "MyriCOM: Cannot Load LANAI firmware.\n");
+		goto err_free_irq;
+	}
 
 	if (register_netdev(dev)) {
 		printk("MyriCOM: Cannot register device.\n");
@@ -1149,3 +1181,4 @@ module_init(myri_sbus_init);
 module_exit(myri_sbus_exit);
 
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/natsemi.c linux-libre-2.6.30-gnu1/drivers/net/natsemi.c
--- linux-libre-2.6.29-gnu1/drivers/net/natsemi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/natsemi.c	2009-06-09 23:05:27.000000000 -0400
@@ -127,7 +127,7 @@ static int full_duplex[MAX_UNITS];
 #define NATSEMI_RX_LIMIT	2046	/* maximum supported by hardware */
 
 /* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
   KERN_INFO DRV_NAME " dp8381x driver, version "
       DRV_VERSION ", " DRV_RELDATE "\n"
   KERN_INFO "  originally by Donald Becker <becker@scyld.com>\n"
@@ -2198,10 +2198,10 @@ static irqreturn_t intr_handler(int irq,
 
 	prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
 
-	if (netif_rx_schedule_prep(&np->napi)) {
+	if (napi_schedule_prep(&np->napi)) {
 		/* Disable interrupts and register for poll */
 		natsemi_irq_disable(dev);
-		__netif_rx_schedule(&np->napi);
+		__napi_schedule(&np->napi);
 	} else
 		printk(KERN_WARNING
 	       	       "%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
@@ -2253,7 +2253,7 @@ static int natsemi_poll(struct napi_stru
 		np->intr_status = readl(ioaddr + IntrStatus);
 	} while (np->intr_status);
 
-	netif_rx_complete(napi);
+	napi_complete(napi);
 
 	/* Reenable interrupts providing nothing is trying to shut
 	 * the chip down. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ne2k-pci.c linux-libre-2.6.30-gnu1/drivers/net/ne2k-pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/ne2k-pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ne2k-pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,8 +62,9 @@ static int options[MAX_UNITS];
 #include "8390.h"
 
 /* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n";
+static const char version[] __devinitconst =
+	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+	" D. Becker/P. Gortmaker\n";
 
 #if defined(__powerpc__)
 #define inl_le(addr)  le32_to_cpu(inl(addr))
@@ -373,18 +374,17 @@ static int __devinit ne2k_pci_init_one (
 	dev->ethtool_ops = &ne2k_pci_ethtool_ops;
 	NS8390_init(dev, 0);
 
+	memcpy(dev->dev_addr, SA_prom, 6);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
 	i = register_netdev(dev);
 	if (i)
 		goto err_out_free_netdev;
 
-	for(i = 0; i < 6; i++)
-		dev->dev_addr[i] = SA_prom[i];
 	printk("%s: %s found at %#lx, IRQ %d, %pM.\n",
 	       dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq,
 	       dev->dev_addr);
 
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
 	return 0;
 
 err_out_free_netdev:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ne3210.c linux-libre-2.6.30-gnu1/drivers/net/ne3210.c
--- linux-libre-2.6.29-gnu1/drivers/net/ne3210.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ne3210.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,7 +150,8 @@ static int __init ne3210_eisa_probe (str
 		if (phys_mem < virt_to_phys(high_memory)) {
 			printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n");
 			printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n");
-			printk(KERN_CRIT "ne3210.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
+			printk(KERN_CRIT "ne3210.c: or to an address above 0x%llx.\n",
+				(u64)virt_to_phys(high_memory));
 			printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n");
 			retval = -EINVAL;
 			goto out3;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netconsole.c linux-libre-2.6.30-gnu1/drivers/net/netconsole.c
--- linux-libre-2.6.29-gnu1/drivers/net/netconsole.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netconsole.c	2009-06-09 23:05:27.000000000 -0400
@@ -294,14 +294,12 @@ static ssize_t show_remote_port(struct n
 
 static ssize_t show_local_ip(struct netconsole_target *nt, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
-			HIPQUAD(nt->np.local_ip));
+	return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
 }
 
 static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
-			HIPQUAD(nt->np.remote_ip));
+	return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
 }
 
 static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
@@ -438,7 +436,7 @@ static ssize_t store_local_ip(struct net
 		return -EINVAL;
 	}
 
-	nt->np.local_ip = ntohl(in_aton(buf));
+	nt->np.local_ip = in_aton(buf);
 
 	return strnlen(buf, count);
 }
@@ -454,7 +452,7 @@ static ssize_t store_remote_ip(struct ne
 		return -EINVAL;
 	}
 
-	nt->np.remote_ip = ntohl(in_aton(buf));
+	nt->np.remote_ip = in_aton(buf);
 
 	return strnlen(buf, count);
 }
@@ -666,7 +664,7 @@ static int netconsole_netdev_event(struc
 	struct netconsole_target *nt;
 	struct net_device *dev = ptr;
 
-	if (!(event == NETDEV_CHANGENAME))
+	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER))
 		goto done;
 
 	spin_lock_irqsave(&target_list_lock, flags);
@@ -677,6 +675,15 @@ static int netconsole_netdev_event(struc
 			case NETDEV_CHANGENAME:
 				strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
 				break;
+			case NETDEV_UNREGISTER:
+				if (!nt->enabled)
+					break;
+				netpoll_cleanup(&nt->np);
+				nt->enabled = 0;
+				printk(KERN_INFO "netconsole: network logging stopped"
+					", interface %s unregistered\n",
+					dev->name);
+				break;
 			}
 		}
 		netconsole_target_put(nt);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/Makefile linux-libre-2.6.30-gnu1/drivers/net/netxen/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,4 +1,4 @@
-# Copyright (C) 2003 - 2006 NetXen, Inc.
+# Copyright (C) 2003 - 2009 NetXen, Inc.
 # All rights reserved.
 # 
 # This program is free software; you can redistribute it and/or
@@ -21,11 +21,10 @@
 # 
 # Contact Information:
 #    info@netxen.com
-# NetXen,
-# 3965 Freedom Circle, Fourth floor,
-# Santa Clara, CA 95054
+# NetXen Inc,
+# 18922 Forge Drive
+# Cupertino, CA 95014-0701
 #
-# Makefile for the NetXen NIC Driver
 #
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_ctx.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_ctx.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_ctx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_ctx.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2008 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,9 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -141,7 +141,7 @@ int
 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
 {
 	u32 rcode = NX_RCODE_SUCCESS;
-	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
 	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
 		rcode = netxen_issue_cmd(adapter,
@@ -169,6 +169,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_ad
 	nx_cardrsp_rds_ring_t *prsp_rds;
 	nx_cardrsp_sds_ring_t *prsp_sds;
 	struct nx_host_rds_ring *rds_ring;
+	struct nx_host_sds_ring *sds_ring;
 
 	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
 	u64 phys_addr;
@@ -179,11 +180,10 @@ nx_fw_cmd_create_rx_ctx(struct netxen_ad
 
 	int err;
 
-	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
-	/* only one sds ring for now */
 	nrds_rings = adapter->max_rds_rings;
-	nsds_rings = 1;
+	nsds_rings = adapter->max_sds_rings;
 
 	rq_size =
 		SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
@@ -231,7 +231,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_ad
 		rds_ring = &recv_ctx->rds_rings[i];
 
 		prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
-		prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
+		prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
 		prq_rds[i].ring_kind = cpu_to_le32(i);
 		prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
 	}
@@ -239,11 +239,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_ad
 	prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
 			le32_to_cpu(prq->sds_ring_offset));
 
-	prq_sds[0].host_phys_addr =
-		cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
-	prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
-	/* only one msix vector for now */
-	prq_sds[0].msi_index = cpu_to_le16(0);
+	for (i = 0; i < nsds_rings; i++) {
+
+		sds_ring = &recv_ctx->sds_rings[i];
+
+		prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
+		prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
+		prq_sds[i].msi_index = cpu_to_le16(i);
+	}
 
 	phys_addr = hostrq_phys_addr;
 	err = netxen_issue_cmd(adapter,
@@ -272,11 +275,16 @@ nx_fw_cmd_create_rx_ctx(struct netxen_ad
 
 	prsp_sds = ((nx_cardrsp_sds_ring_t *)
 			&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
-	reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
-	recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
 
-	reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
-	adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+	for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
+		sds_ring = &recv_ctx->sds_rings[i];
+
+		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
+		sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+
+		reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
+		sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+	}
 
 	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
 	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
@@ -292,7 +300,7 @@ out_free_rq:
 static void
 nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
 {
-	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
 	if (netxen_issue_cmd(adapter,
 			adapter->ahw.pci_func,
@@ -362,7 +370,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_ad
 	prq_cds->host_phys_addr =
 		cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
 
-	prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);
+	prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
 
 	phys_addr = rq_phys_addr;
 	err = netxen_issue_cmd(adapter,
@@ -488,30 +496,28 @@ netxen_init_old_ctx(struct netxen_adapte
 {
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
-	int ctx, ring;
+	struct nx_host_sds_ring *sds_ring;
+	int ring;
 	int func_id = adapter->portnum;
 
 	adapter->ctx_desc->cmd_ring_addr =
 		cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
 	adapter->ctx_desc->cmd_ring_size =
-		cpu_to_le32(adapter->max_tx_desc_count);
+		cpu_to_le32(adapter->num_txd);
 
-	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-		recv_ctx = &adapter->recv_ctx[ctx];
+	recv_ctx = &adapter->recv_ctx;
 
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			rds_ring = &recv_ctx->rds_rings[ring];
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
 
-			adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
-				cpu_to_le64(rds_ring->phys_addr);
-			adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
-				cpu_to_le32(rds_ring->max_rx_desc_count);
-		}
-		adapter->ctx_desc->sts_ring_addr =
-			cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
-		adapter->ctx_desc->sts_ring_size =
-			cpu_to_le32(adapter->max_rx_desc_count);
+		adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+			cpu_to_le64(rds_ring->phys_addr);
+		adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+			cpu_to_le32(rds_ring->num_desc);
 	}
+	sds_ring = &recv_ctx->sds_rings[0];
+	adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+	adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
 
 	adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
 			lower32(adapter->ctx_desc_phys_addr));
@@ -533,9 +539,13 @@ int netxen_alloc_hw_resources(struct net
 	u32 state = 0;
 	void *addr;
 	int err = 0;
-	int ctx, ring;
+	int ring;
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
+	struct nx_host_sds_ring *sds_ring;
+
+	struct pci_dev *pdev = adapter->pdev;
+	struct net_device *netdev = adapter->netdev;
 
 	err = netxen_receive_peg_ready(adapter);
 	if (err) {
@@ -544,12 +554,12 @@ int netxen_alloc_hw_resources(struct net
 		return err;
 	}
 
-	addr = pci_alloc_consistent(adapter->pdev,
+	addr = pci_alloc_consistent(pdev,
 			sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
 			&adapter->ctx_desc_phys_addr);
 
 	if (addr == NULL) {
-		DPRINTK(ERR, "failed to allocate hw context\n");
+		dev_err(&pdev->dev, "failed to allocate hw context\n");
 		return -ENOMEM;
 	}
 	memset(addr, 0, sizeof(struct netxen_ring_ctx));
@@ -562,61 +572,57 @@ int netxen_alloc_hw_resources(struct net
 		(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
 
 	/* cmd desc ring */
-	addr = pci_alloc_consistent(adapter->pdev,
-			sizeof(struct cmd_desc_type0) *
-			adapter->max_tx_desc_count,
+	addr = pci_alloc_consistent(pdev,
+			TX_DESC_RINGSIZE(adapter),
 			&hw->cmd_desc_phys_addr);
 
 	if (addr == NULL) {
-		printk(KERN_ERR "%s failed to allocate tx desc ring\n",
-				netxen_nic_driver_name);
+		dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
+				netdev->name);
 		return -ENOMEM;
 	}
 
 	hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
 
-	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-		recv_ctx = &adapter->recv_ctx[ctx];
-
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			/* rx desc ring */
-			rds_ring = &recv_ctx->rds_rings[ring];
-			addr = pci_alloc_consistent(adapter->pdev,
-					RCV_DESC_RINGSIZE,
-					&rds_ring->phys_addr);
-			if (addr == NULL) {
-				printk(KERN_ERR "%s failed to allocate rx "
-					"desc ring[%d]\n",
-					netxen_nic_driver_name, ring);
-				err = -ENOMEM;
-				goto err_out_free;
-			}
-			rds_ring->desc_head = (struct rcv_desc *)addr;
-
-			if (adapter->fw_major < 4)
-				rds_ring->crb_rcv_producer =
-					recv_crb_registers[adapter->portnum].
-					crb_rcv_producer[ring];
-		}
+	recv_ctx = &adapter->recv_ctx;
 
-		/* status desc ring */
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
 		addr = pci_alloc_consistent(adapter->pdev,
-				STATUS_DESC_RINGSIZE,
-				&recv_ctx->rcv_status_desc_phys_addr);
+				RCV_DESC_RINGSIZE(rds_ring),
+				&rds_ring->phys_addr);
 		if (addr == NULL) {
-			printk(KERN_ERR "%s failed to allocate sts desc ring\n",
-					netxen_nic_driver_name);
+			dev_err(&pdev->dev,
+				"%s: failed to allocate rds ring [%d]\n",
+				netdev->name, ring);
 			err = -ENOMEM;
 			goto err_out_free;
 		}
-		recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
+		rds_ring->desc_head = (struct rcv_desc *)addr;
 
 		if (adapter->fw_major < 4)
-			recv_ctx->crb_sts_consumer =
+			rds_ring->crb_rcv_producer =
 				recv_crb_registers[adapter->portnum].
-				crb_sts_consumer;
+				crb_rcv_producer[ring];
 	}
 
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+
+		addr = pci_alloc_consistent(adapter->pdev,
+				STATUS_DESC_RINGSIZE(sds_ring),
+				&sds_ring->phys_addr);
+		if (addr == NULL) {
+			dev_err(&pdev->dev,
+				"%s: failed to allocate sds ring [%d]\n",
+				netdev->name, ring);
+			err = -ENOMEM;
+			goto err_out_free;
+		}
+		sds_ring->desc_head = (struct status_desc *)addr;
+	}
+
+
 	if (adapter->fw_major >= 4) {
 		adapter->intr_scheme = INTR_SCHEME_PERPORT;
 		adapter->msi_mode = MSI_MODE_MULTIFUNC;
@@ -628,12 +634,16 @@ int netxen_alloc_hw_resources(struct net
 		if (err)
 			goto err_out_free;
 	} else {
+		sds_ring = &recv_ctx->sds_rings[0];
+		sds_ring->crb_sts_consumer =
+			recv_crb_registers[adapter->portnum].crb_sts_consumer;
 
 		adapter->intr_scheme = adapter->pci_read_normalize(adapter,
 				CRB_NIC_CAPABILITIES_FW);
 		adapter->msi_mode = adapter->pci_read_normalize(adapter,
 				CRB_NIC_MSI_MODE_FW);
-		adapter->crb_intr_mask = sw_int_mask[adapter->portnum];
+		recv_ctx->sds_rings[0].crb_intr_mask =
+				sw_int_mask[adapter->portnum];
 
 		err = netxen_init_old_ctx(adapter);
 		if (err) {
@@ -654,7 +664,8 @@ void netxen_free_hw_resources(struct net
 {
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
-	int ctx, ring;
+	struct nx_host_sds_ring *sds_ring;
+	int ring;
 
 	if (adapter->fw_major >= 4) {
 		nx_fw_cmd_destroy_tx_ctx(adapter);
@@ -673,32 +684,34 @@ void netxen_free_hw_resources(struct net
 	if (adapter->ahw.cmd_desc_head != NULL) {
 		pci_free_consistent(adapter->pdev,
 				sizeof(struct cmd_desc_type0) *
-				adapter->max_tx_desc_count,
+				adapter->num_txd,
 				adapter->ahw.cmd_desc_head,
 				adapter->ahw.cmd_desc_phys_addr);
 		adapter->ahw.cmd_desc_head = NULL;
 	}
 
-	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-		recv_ctx = &adapter->recv_ctx[ctx];
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			rds_ring = &recv_ctx->rds_rings[ring];
+	recv_ctx = &adapter->recv_ctx;
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
 
-			if (rds_ring->desc_head != NULL) {
-				pci_free_consistent(adapter->pdev,
-						RCV_DESC_RINGSIZE,
-						rds_ring->desc_head,
-						rds_ring->phys_addr);
-				rds_ring->desc_head = NULL;
-			}
+		if (rds_ring->desc_head != NULL) {
+			pci_free_consistent(adapter->pdev,
+					RCV_DESC_RINGSIZE(rds_ring),
+					rds_ring->desc_head,
+					rds_ring->phys_addr);
+			rds_ring->desc_head = NULL;
 		}
+	}
 
-		if (recv_ctx->rcv_status_desc_head != NULL) {
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+
+		if (sds_ring->desc_head != NULL) {
 			pci_free_consistent(adapter->pdev,
-					STATUS_DESC_RINGSIZE,
-					recv_ctx->rcv_status_desc_head,
-					recv_ctx->rcv_status_desc_phys_addr);
-			recv_ctx->rcv_status_desc_head = NULL;
+				STATUS_DESC_RINGSIZE(sds_ring),
+				sds_ring->desc_head,
+				sds_ring->phys_addr);
+			sds_ring->desc_head = NULL;
 		}
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * ethtool support for netxen nic
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -118,10 +115,9 @@ static int
 netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg;
 
 	/* read which mode */
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 				   SUPPORTED_10baseT_Full |
 				   SUPPORTED_100baseT_Half |
@@ -140,7 +136,7 @@ netxen_nic_get_settings(struct net_devic
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
-	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
 		u32 val;
 
 		adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
@@ -172,7 +168,7 @@ netxen_nic_get_settings(struct net_devic
 	ecmd->phy_address = adapter->physical_port;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	switch ((netxen_brdtype_t) boardinfo->board_type) {
+	switch ((netxen_brdtype_t)adapter->ahw.board_type) {
 	case NETXEN_BRDTYPE_P2_SB35_4G:
 	case NETXEN_BRDTYPE_P2_SB31_2G:
 	case NETXEN_BRDTYPE_P3_REF_QG:
@@ -188,7 +184,7 @@ netxen_nic_get_settings(struct net_devic
 		ecmd->supported |= SUPPORTED_TP;
 		ecmd->advertising |= ADVERTISED_TP;
 		ecmd->port = PORT_TP;
-		ecmd->autoneg = (boardinfo->board_type ==
+		ecmd->autoneg = (adapter->ahw.board_type ==
 				 NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
 		    (AUTONEG_DISABLE) : (adapter->link_autoneg);
 		break;
@@ -215,7 +211,7 @@ netxen_nic_get_settings(struct net_devic
 		ecmd->autoneg = AUTONEG_DISABLE;
 		break;
 	case NETXEN_BRDTYPE_P3_10G_TP:
-		if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+		if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
 			ecmd->autoneg = AUTONEG_DISABLE;
 			ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 			ecmd->advertising |=
@@ -231,7 +227,7 @@ netxen_nic_get_settings(struct net_devic
 		break;
 	default:
 		printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
-		       (netxen_brdtype_t) boardinfo->board_type);
+		       (netxen_brdtype_t)adapter->ahw.board_type);
 		return -EIO;
 	}
 
@@ -245,7 +241,7 @@ netxen_nic_set_settings(struct net_devic
 	__u32 status;
 
 	/* read which mode */
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		/* autonegotiation */
 		if (adapter->phy_write
 		    && adapter->phy_write(adapter,
@@ -433,7 +429,7 @@ static u32 netxen_nic_test_link(struct n
 	int val;
 
 	/* read which mode */
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		if (adapter->phy_read
 		    && adapter->phy_read(adapter,
 					 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
@@ -443,7 +439,7 @@ static u32 netxen_nic_test_link(struct n
 			val = netxen_get_phy_link(status);
 			return !val;
 		}
-	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
 		val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
 		return (val == XG_LINK_UP) ? 0 : 1;
 	}
@@ -473,95 +469,20 @@ netxen_nic_get_eeprom(struct net_device
 	return 0;
 }
 
-#if 0
-static int
-netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
-			u8 * bytes)
-{
-	struct netxen_adapter *adapter = netdev_priv(dev);
-	int offset = eeprom->offset;
-	static int flash_start;
-	static int ready_to_flash;
-	int ret;
-
-	if (flash_start == 0) {
-		netxen_halt_pegs(adapter);
-		ret = netxen_flash_unlock(adapter);
-		if (ret < 0) {
-			printk(KERN_ERR "%s: Flash unlock failed.\n",
-				netxen_nic_driver_name);
-			return ret;
-		}
-		printk(KERN_INFO "%s: flash unlocked. \n",
-			netxen_nic_driver_name);
-		ret = netxen_flash_erase_secondary(adapter);
-		if (ret != FLASH_SUCCESS) {
-			printk(KERN_ERR "%s: Flash erase failed.\n",
-				netxen_nic_driver_name);
-			return ret;
-		}
-		printk(KERN_INFO "%s: secondary flash erased successfully.\n",
-			netxen_nic_driver_name);
-		flash_start = 1;
-		return 0;
-	}
-
-	if (offset == NETXEN_BOOTLD_START) {
-		ret = netxen_flash_erase_primary(adapter);
-		if (ret != FLASH_SUCCESS) {
-			printk(KERN_ERR "%s: Flash erase failed.\n",
-				netxen_nic_driver_name);
-			return ret;
-		}
-
-		ret = netxen_rom_se(adapter, NETXEN_USER_START);
-		if (ret != FLASH_SUCCESS)
-			return ret;
-		ret = netxen_rom_se(adapter, NETXEN_FIXED_START);
-		if (ret != FLASH_SUCCESS)
-			return ret;
-
-		printk(KERN_INFO "%s: primary flash erased successfully\n",
-			netxen_nic_driver_name);
-
-		ret = netxen_backup_crbinit(adapter);
-		if (ret != FLASH_SUCCESS) {
-			printk(KERN_ERR "%s: CRBinit backup failed.\n",
-				netxen_nic_driver_name);
-			return ret;
-		}
-		printk(KERN_INFO "%s: CRBinit backup done.\n",
-			netxen_nic_driver_name);
-		ready_to_flash = 1;
-	}
-
-	if (!ready_to_flash) {
-		printk(KERN_ERR "%s: Invalid write sequence, returning...\n",
-			netxen_nic_driver_name);
-		return -EINVAL;
-	}
-
-	return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
-}
-#endif /* 0 */
-
 static void
 netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	int i;
 
 	ring->rx_pending = 0;
 	ring->rx_jumbo_pending = 0;
-	for (i = 0; i < MAX_RCV_CTX; ++i) {
-		ring->rx_pending += adapter->recv_ctx[i].
-		    rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
-		ring->rx_jumbo_pending += adapter->recv_ctx[i].
-		    rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
-	}
-	ring->tx_pending = adapter->max_tx_desc_count;
+	ring->rx_pending += adapter->recv_ctx.
+		rds_rings[RCV_RING_NORMAL].num_desc;
+	ring->rx_jumbo_pending += adapter->recv_ctx.
+		rds_rings[RCV_RING_JUMBO].num_desc;
+	ring->tx_pending = adapter->num_txd;
 
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE)
 		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
 	else
 		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
@@ -579,7 +500,7 @@ netxen_nic_get_pauseparam(struct net_dev
 	__u32 val;
 	int port = adapter->physical_port;
 
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
 			return;
 		/* get flow control settings */
@@ -602,7 +523,7 @@ netxen_nic_get_pauseparam(struct net_dev
 				pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
 				break;
 		}
-	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
 		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
 			return;
 		pause->rx_pause = 1;
@@ -613,7 +534,7 @@ netxen_nic_get_pauseparam(struct net_dev
 			pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
 	} else {
 		printk(KERN_ERR"%s: Unknown board type: %x\n",
-				netxen_nic_driver_name, adapter->ahw.board_type);
+				netxen_nic_driver_name, adapter->ahw.port_type);
 	}
 }
 
@@ -625,7 +546,7 @@ netxen_nic_set_pauseparam(struct net_dev
 	__u32 val;
 	int port = adapter->physical_port;
 	/* read mode */
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
 			return -EIO;
 		/* set flow control */
@@ -669,7 +590,7 @@ netxen_nic_set_pauseparam(struct net_dev
 				break;
 		}
 		netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
-	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+	} else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
 		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
 			return -EIO;
 		netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
@@ -688,7 +609,7 @@ netxen_nic_set_pauseparam(struct net_dev
 	} else {
 		printk(KERN_ERR "%s: Unknown board type: %x\n",
 				netxen_nic_driver_name,
-				adapter->ahw.board_type);
+				adapter->ahw.port_type);
 	}
 	return 0;
 }
@@ -810,6 +731,53 @@ static int netxen_nic_set_tso(struct net
 	return 0;
 }
 
+static void
+netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct netxen_adapter *adapter = netdev_priv(dev);
+	u32 wol_cfg = 0;
+
+	wol->supported = 0;
+	wol->wolopts = 0;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return;
+
+	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+	if (wol_cfg & (1UL << adapter->portnum))
+		wol->supported |= WAKE_MAGIC;
+
+	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+	if (wol_cfg & (1UL << adapter->portnum))
+		wol->wolopts |= WAKE_MAGIC;
+}
+
+static int
+netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct netxen_adapter *adapter = netdev_priv(dev);
+	u32 wol_cfg = 0;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return -EOPNOTSUPP;
+
+	if (wol->wolopts & ~WAKE_MAGIC)
+		return -EOPNOTSUPP;
+
+	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+	if (!(wol_cfg & (1 << adapter->portnum)))
+		return -EOPNOTSUPP;
+
+	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+	if (wol->wolopts & WAKE_MAGIC)
+		wol_cfg |= 1UL << adapter->portnum;
+	else
+		wol_cfg &= ~(1UL << adapter->portnum);
+	netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+
+	return 0;
+}
+
 /*
  * Set the coalescing parameters. Currently only normal is supported.
  * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
@@ -906,9 +874,6 @@ struct ethtool_ops netxen_nic_ethtool_op
 	.get_link = ethtool_op_get_link,
 	.get_eeprom_len = netxen_nic_get_eeprom_len,
 	.get_eeprom = netxen_nic_get_eeprom,
-#if 0
-	.set_eeprom = netxen_nic_set_eeprom,
-#endif
 	.get_ringparam = netxen_nic_get_ringparam,
 	.get_pauseparam = netxen_nic_get_pauseparam,
 	.set_pauseparam = netxen_nic_set_pauseparam,
@@ -916,6 +881,8 @@ struct ethtool_ops netxen_nic_ethtool_op
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = netxen_nic_get_tso,
 	.set_tso = netxen_nic_set_tso,
+	.get_wol = netxen_nic_get_wol,
+	.set_wol = netxen_nic_set_wol,
 	.self_test = netxen_nic_diag_test,
 	.get_strings = netxen_nic_get_strings,
 	.get_ethtool_stats = netxen_nic_get_ethtool_stats,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic.h linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic.h
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
  */
 
 #ifndef _NETXEN_NIC_H_
@@ -65,8 +66,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 11
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.11"
+#define _NETXEN_NIC_LINUX_SUBVERSION 30
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.30"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 16) + ((b) << 8) + (c))
 
@@ -77,19 +78,19 @@
 
 #define PHAN_VENDOR_ID 0x4040
 
-#define RCV_DESC_RINGSIZE	\
-	(sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
-#define STATUS_DESC_RINGSIZE	\
-	(sizeof(struct status_desc)* adapter->max_rx_desc_count)
-#define LRO_DESC_RINGSIZE	\
-	(sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
-#define TX_RINGSIZE	\
-	(sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
-#define RCV_BUFFSIZE	\
-	(sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count)
+#define RCV_DESC_RINGSIZE(rds_ring)	\
+	(sizeof(struct rcv_desc) * (rds_ring)->num_desc)
+#define RCV_BUFF_RINGSIZE(rds_ring)	\
+	(sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
+#define STATUS_DESC_RINGSIZE(sds_ring)	\
+	(sizeof(struct status_desc) * (sds_ring)->num_desc)
+#define TX_BUFF_RINGSIZE(adapter)	\
+	(sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
+#define TX_DESC_RINGSIZE(adapter)	\
+	(sizeof(struct cmd_desc_type0) * adapter->num_txd)
+
 #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
-#define NETXEN_NETDEV_STATUS		0x1
 #define NETXEN_RCV_PRODUCER_OFFSET	0
 #define NETXEN_RCV_PEG_DB_ID		2
 #define NETXEN_HOST_DUMMY_DMA_SIZE 1024
@@ -188,22 +189,12 @@
 /* Host writes the following to notify that it has done the init-handshake */
 #define PHAN_INITIALIZE_ACK	0xf00f
 
-#define NUM_RCV_DESC_RINGS	3	/* No of Rcv Descriptor contexts */
-
-/* descriptor types */
-#define RCV_DESC_NORMAL		0x01
-#define RCV_DESC_JUMBO		0x02
-#define RCV_DESC_LRO		0x04
-#define RCV_DESC_NORMAL_CTXID	0
-#define RCV_DESC_JUMBO_CTXID	1
-#define RCV_DESC_LRO_CTXID	2
+#define NUM_RCV_DESC_RINGS	3
+#define NUM_STS_DESC_RINGS	4
 
-#define RCV_DESC_TYPE(ID) \
-	((ID == RCV_DESC_JUMBO_CTXID)	\
-		? RCV_DESC_JUMBO	\
-		: ((ID == RCV_DESC_LRO_CTXID)	\
-			? RCV_DESC_LRO :	\
-			(RCV_DESC_NORMAL)))
+#define RCV_RING_NORMAL	0
+#define RCV_RING_JUMBO	1
+#define RCV_RING_LRO	2
 
 #define MAX_CMD_DESCRIPTORS		4096
 #define MAX_RCV_DESCRIPTORS		16384
@@ -357,10 +348,7 @@ struct cmd_desc_type0 {
 		__le64 addr_buffer1;
 	};
 
-	__le16 buffer1_length;
-	__le16 buffer2_length;
-	__le16 buffer3_length;
-	__le16 buffer4_length;
+	__le16 buffer_length[4];
 
 	union {
 		struct {
@@ -391,11 +379,8 @@ struct rcv_desc {
 #define STATUS_CKSUM_OK		(2)
 
 /* owner bits of status_desc */
-#define STATUS_OWNER_HOST	(0x1)
-#define STATUS_OWNER_PHANTOM	(0x2)
-
-#define NETXEN_PROT_IP		(1)
-#define NETXEN_PROT_UNKNOWN	(0)
+#define STATUS_OWNER_HOST	(0x1ULL << 56)
+#define STATUS_OWNER_PHANTOM	(0x2ULL << 56)
 
 /* Note: sizeof(status_desc) should always be a mutliple of 2 */
 
@@ -421,15 +406,6 @@ struct rcv_desc {
 #define netxen_get_sts_opcode(sts_data)	\
 	(((sts_data) >> 58) & 0x03F)
 
-#define netxen_get_sts_owner(status_desc)	\
-	((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03)
-#define netxen_set_sts_owner(status_desc, val)	{ \
-	(status_desc)->status_desc_data = \
-		((status_desc)->status_desc_data & \
-		~cpu_to_le64(0x3ULL << 56)) | \
-		cpu_to_le64((u64)((val) & 0x3) << 56); \
-}
-
 struct status_desc {
 	/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
 	   28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
@@ -712,6 +688,15 @@ typedef enum {
 	NETXEN_FIXED_START = 0x3F0000	/* backup of crbinit */
 } netxen_flash_map_t;
 
+#define NX_FW_VERSION_OFFSET	(NETXEN_USER_START+0x408)
+#define NX_FW_SIZE_OFFSET	(NETXEN_USER_START+0x40c)
+#define NX_BIOS_VERSION_OFFSET	(NETXEN_USER_START+0x83c)
+#define NX_FW_MAGIC_OFFSET	(NETXEN_BRDCFG_START+0x128)
+#define NX_FW_MIN_SIZE		(0x3fffff)
+#define NX_P2_MN_ROMIMAGE	0
+#define NX_P3_CT_ROMIMAGE	1
+#define NX_P3_MN_ROMIMAGE	2
+
 #define NETXEN_USER_START_OLD NETXEN_PXE_START	/* for backward compatibility */
 
 #define NETXEN_FLASH_START		(NETXEN_CRBINIT_START)
@@ -739,7 +724,7 @@ extern char netxen_nic_driver_name[];
 #endif
 
 /* Number of status descriptors to handle per interrupt */
-#define MAX_STATUS_HANDLE	(128)
+#define MAX_STATUS_HANDLE	(64)
 
 /*
  * netxen_skb_frag{} is to contain mapping info for each SG list. This
@@ -783,9 +768,6 @@ struct netxen_rx_buffer {
 	u64 dma;
 	u16 ref_handle;
 	u16 state;
-	u32 lro_expected_frags;
-	u32 lro_current_frags;
-	u32 lro_length;
 };
 
 /* Board types */
@@ -800,21 +782,19 @@ struct netxen_hardware_context {
 	void __iomem *pci_base0;
 	void __iomem *pci_base1;
 	void __iomem *pci_base2;
-	unsigned long first_page_group_end;
-	unsigned long first_page_group_start;
 	void __iomem *db_base;
 	unsigned long db_len;
 	unsigned long pci_len0;
 
-	u8 cut_through;
 	int qdr_sn_window;
 	int ddr_mn_window;
 	unsigned long mn_win_crb;
 	unsigned long ms_win_crb;
 
+	u8 cut_through;
 	u8 revision_id;
-	u16 board_type;
-	struct netxen_board_info boardcfg;
+	u16 port_type;
+	int board_type;
 	u32 linkup;
 	/* Address of cmd ring in Phantom */
 	struct cmd_desc_type0 *cmd_desc_head;
@@ -823,8 +803,6 @@ struct netxen_hardware_context {
 	int pci_func;
 };
 
-#define RCV_RING_LRO	RCV_DESC_LRO
-
 #define MINIMUM_ETHERNET_FRAME_SIZE	64	/* With FCS */
 #define ETHERNET_FCS_SIZE		4
 
@@ -850,16 +828,36 @@ struct netxen_adapter_stats {
  * be one Rcv Descriptor for normal packets, one for jumbo and may be others.
  */
 struct nx_host_rds_ring {
-	u32 flags;
 	u32 producer;
-	dma_addr_t phys_addr;
-	u32 crb_rcv_producer;	/* reg offset */
-	struct rcv_desc *desc_head;	/* address of rx ring in Phantom */
-	u32 max_rx_desc_count;
+	u32 crb_rcv_producer;
+	u32 num_desc;
 	u32 dma_size;
 	u32 skb_size;
-	struct netxen_rx_buffer *rx_buf_arr;	/* rx buffers for receive   */
+	u32 flags;
+	struct rcv_desc *desc_head;
+	struct netxen_rx_buffer *rx_buf_arr;
 	struct list_head free_list;
+	spinlock_t lock;
+	dma_addr_t phys_addr;
+};
+
+struct nx_host_sds_ring {
+	u32 consumer;
+	u32 crb_sts_consumer;
+	u32 crb_intr_mask;
+	u32 num_desc;
+
+	struct status_desc *desc_head;
+	struct netxen_adapter *adapter;
+	struct napi_struct napi;
+	struct list_head free_list[NUM_RCV_DESC_RINGS];
+
+	u16 clean_tx;
+	u16 post_rxd;
+	int irq;
+
+	dma_addr_t phys_addr;
+	char name[IFNAMSIZ+4];
 };
 
 /*
@@ -874,10 +872,7 @@ struct netxen_recv_context {
 	u16 virt_port;
 
 	struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
-	u32 status_rx_consumer;
-	u32 crb_sts_consumer;	/* reg offset */
-	dma_addr_t rcv_status_desc_phys_addr;
-	struct status_desc *rcv_status_desc_head;
+	struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
 };
 
 /* New HW context creation */
@@ -1203,13 +1198,13 @@ typedef struct {
 #define NETXEN_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
 
-#define MSIX_ENTRIES_PER_ADAPTER	1
+#define MSIX_ENTRIES_PER_ADAPTER	NUM_STS_DESC_RINGS
 #define NETXEN_MSIX_TBL_SPACE		8192
 #define NETXEN_PCI_REG_MSIX_TBL		0x44
 
 #define NETXEN_DB_MAPSIZE_BYTES    	0x1000
 
-#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_NETDEV_WEIGHT 128
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
@@ -1224,7 +1219,6 @@ struct netxen_adapter {
 	struct net_device *netdev;
 	struct pci_dev *pdev;
 	int pci_using_dac;
-	struct napi_struct napi;
 	struct net_device_stats net_stats;
 	int mtu;
 	int portnum;
@@ -1236,7 +1230,6 @@ struct netxen_adapter {
 	nx_mac_list_t	*mac_list;
 
 	struct netxen_legacy_intr_set legacy_intr;
-	u32	crb_intr_mask;
 
 	struct work_struct watchdog_task;
 	struct timer_list watchdog_timer;
@@ -1246,20 +1239,20 @@ struct netxen_adapter {
 	u32 crb_win;
 	rwlock_t adapter_lock;
 
-	uint64_t dma_mask;
-
 	u32 cmd_producer;
 	__le32 *cmd_consumer;
 	u32 last_cmd_consumer;
 	u32 crb_addr_cmd_producer;
 	u32 crb_addr_cmd_consumer;
+	spinlock_t tx_clean_lock;
 
-	u32 max_tx_desc_count;
-	u32 max_rx_desc_count;
-	u32 max_jumbo_rx_desc_count;
-	u32 max_lro_rx_desc_count;
+	u32 num_txd;
+	u32 num_rxd;
+	u32 num_jumbo_rxd;
+	u32 num_lro_rxd;
 
 	int max_rds_rings;
+	int max_sds_rings;
 
 	u32 flags;
 	u32 irq;
@@ -1267,9 +1260,9 @@ struct netxen_adapter {
 	u32 temp;
 
 	u32 fw_major;
+	u32 fw_version;
 
-	u8 msix_supported;
-	u8 max_possible_rss_rings;
+	int msix_supported;
 	struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
 
 	struct netxen_adapter_stats stats;
@@ -1279,7 +1272,6 @@ struct netxen_adapter {
 	u16 state;
 	u16 link_autoneg;
 	int rx_csum;
-	int status;
 
 	struct netxen_cmd_buffer *cmd_buf_arr;	/* Command buffers for xmit */
 
@@ -1287,7 +1279,7 @@ struct netxen_adapter {
 	 * Receive instances. These can be either one per port,
 	 * or one per peg, etc.
 	 */
-	struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
+	struct netxen_recv_context recv_ctx;
 
 	int is_up;
 	struct netxen_dummy_dma dummy_dma;
@@ -1398,6 +1390,8 @@ void netxen_nic_write_w1(struct netxen_a
 void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
+int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
 int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
 		ulong off, void *data, int len);
@@ -1471,15 +1465,16 @@ void netxen_initialize_adapter_ops(struc
 int netxen_init_firmware(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
-			    u32 ringid);
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+		struct nx_host_rds_ring *rds_ring);
 int netxen_process_cmd_ring(struct netxen_adapter *adapter);
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
+int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
 void netxen_p2_nic_set_multi(struct net_device *netdev);
 void netxen_p3_nic_set_multi(struct net_device *netdev);
 void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
+int netxen_config_rss(struct netxen_adapter *adapter, int enable);
 
 int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hdr.h linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hdr.h
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hdr.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
  */
 
 #ifndef __NETXEN_NIC_HDR_H_
@@ -362,12 +363,6 @@ enum {
 #define NETXEN_HW_CRB_HUB_AGT_ADR_LPC	\
 	((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR)
 
-/*
- * MAX_RCV_CTX : The number of receive contexts that are available on
- * the phantom.
- */
-#define MAX_RCV_CTX			1
-
 #define NETXEN_SRE_INT_STATUS		(NETXEN_CRB_SRE + 0x00034)
 #define NETXEN_SRE_PBI_ACTIVE_STATUS	(NETXEN_CRB_SRE + 0x01014)
 #define NETXEN_SRE_L1RE_CTL		(NETXEN_CRB_SRE + 0x03000)
@@ -858,6 +853,12 @@ enum {
 #define NETXEN_PORT_MODE_ADDR		(NETXEN_CAM_RAM(0x24))
 #define NETXEN_WOL_PORT_MODE		(NETXEN_CAM_RAM(0x198))
 
+#define NETXEN_WOL_CONFIG_NV		(NETXEN_CAM_RAM(0x184))
+#define NETXEN_WOL_CONFIG		(NETXEN_CAM_RAM(0x188))
+
+#define NX_PEG_TUNE_MN_PRESENT		0x1
+#define NX_PEG_TUNE_CAPABILITY		(NETXEN_CAM_RAM(0x02c))
+
 #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL		(0x14)
 
 #define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hw.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hw.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hw.c	2013-05-03 16:46:58.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to access the Phantom hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -35,7 +32,7 @@
 #include "netxen_nic_hw.h"
 #include "netxen_nic_phan_reg.h"
 
-
+#include <linux/firmware.h>
 #include <net/ip.h>
 
 #define MASK(n) ((1ULL<<(n))-1)
@@ -518,7 +515,7 @@ netxen_send_cmd_descs(struct netxen_adap
 			&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
 
 		producer = get_next_index(producer,
-				adapter->max_tx_desc_count);
+				adapter->num_txd);
 		i++;
 
 	} while (i != nr_elements);
@@ -673,6 +670,53 @@ int netxen_config_intr_coalesce(struct n
 	return rv;
 }
 
+#define RSS_HASHTYPE_IP_TCP	0x3
+
+int netxen_config_rss(struct netxen_adapter *adapter, int enable)
+{
+	nx_nic_req_t req;
+	u64 word;
+	int i, rv;
+
+	u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+			0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+			0x255b0ec26d5a56daULL };
+
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	/*
+	 * RSS request:
+	 * bits 3-0: hash_method
+	 *      5-4: hash_type_ipv4
+	 *	7-6: hash_type_ipv6
+	 *	  8: enable
+	 *        9: use indirection table
+	 *    47-10: reserved
+	 *    63-48: indirection table mask
+	 */
+	word =  ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
+		((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
+		((u64)(enable & 0x1) << 8) |
+		((0x7ULL) << 48);
+	req.words[0] = cpu_to_le64(word);
+	for (i = 0; i < 5; i++)
+		req.words[i+1] = cpu_to_le64(key[i]);
+
+
+	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0) {
+		printk(KERN_ERR "%s: could not configure RSS\n",
+				adapter->netdev->name);
+	}
+
+	return rv;
+}
+
 /*
  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
  * @returns 0 on success, negative on failure
@@ -709,9 +753,8 @@ int netxen_nic_change_mtu(struct net_dev
 static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
 				  int size, __le32 * buf)
 {
-	int i, addr;
+	int i, v, addr;
 	__le32 *ptr32;
-	u32 v;
 
 	addr = base;
 	ptr32 = buf;
@@ -914,13 +957,12 @@ netxen_nic_pci_set_crbwindow_2M(struct n
 	u32 win_read;
 
 	adapter->crb_win = CRB_HI(*off);
-	writel(adapter->crb_win, (void *)(CRB_WINDOW_2M +
-		adapter->ahw.pci_base0));
+	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((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0));
+	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",
@@ -930,24 +972,69 @@ netxen_nic_pci_set_crbwindow_2M(struct n
 		(ulong)adapter->ahw.pci_base0;
 }
 
-int netxen_load_firmware(struct netxen_adapter *adapter)
+static int
+netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
+		const struct firmware *fw)
 {
-	int i;
-	u32 data, size = 0;
-	u32 flashaddr = NETXEN_BOOTLD_START;
+	u64 *ptr64;
+	u32 i, flashaddr, size;
+	struct pci_dev *pdev = adapter->pdev;
 
-	size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4;
+	if (fw)
+		dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
+	else
+		dev_info(&pdev->dev, "loading firmware from flash\n");
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 		adapter->pci_write_normalize(adapter,
 				NETXEN_ROMUSB_GLB_CAS_RST, 1);
 
-	for (i = 0; i < size; i++) {
-		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
-			return -EIO;
+	if (fw) {
+		__le64 data;
 
-		adapter->pci_mem_write(adapter, flashaddr, &data, 4);
-		flashaddr += 4;
+		size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
+
+		ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+		flashaddr = NETXEN_BOOTLD_START;
+
+		for (i = 0; i < size; i++) {
+			data = cpu_to_le64(ptr64[i]);
+			adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+			flashaddr += 8;
+		}
+
+		size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
+		size = (__force u32)cpu_to_le32(size) / 8;
+
+		ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+		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))
+				return -EIO;
+
+			flashaddr += 8;
+		}
+	} else {
+		u32 data;
+
+		size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+		flashaddr = NETXEN_BOOTLD_START;
+
+		for (i = 0; i < size; i++) {
+			if (netxen_rom_fast_read(adapter,
+					flashaddr, (int *)&data) != 0)
+				return -EIO;
+
+			if (adapter->pci_mem_write(adapter,
+						flashaddr, &data, 4))
+				return -EIO;
+
+			flashaddr += 4;
+		}
 	}
 	msleep(1);
 
@@ -964,12 +1051,135 @@ int netxen_load_firmware(struct netxen_a
 	return 0;
 }
 
+static int
+netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
+		const struct firmware *fw)
+{
+	__le32 val;
+	u32 major, minor, build, ver, min_ver, bios;
+	struct pci_dev *pdev = adapter->pdev;
+
+	if (fw->size < NX_FW_MIN_SIZE)
+		return -EINVAL;
+
+	val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+	if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+		return -EINVAL;
+
+	val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+	major = (__force u32)val & 0xff;
+	minor = ((__force u32)val >> 8) & 0xff;
+	build = (__force u32)val >> 16;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		min_ver = NETXEN_VERSION_CODE(4, 0, 216);
+	else
+		min_ver = NETXEN_VERSION_CODE(3, 4, 216);
+
+	ver = NETXEN_VERSION_CODE(major, minor, build);
+
+	if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+		dev_err(&pdev->dev,
+				"%s: firmware version %d.%d.%d unsupported\n",
+				fwname, major, minor, build);
+		return -EINVAL;
+	}
+
+	val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+	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);
+		return -EINVAL;
+	}
+
+	/* check if flashed firmware is newer */
+	if (netxen_rom_fast_read(adapter,
+			NX_FW_VERSION_OFFSET, (int *)&val))
+		return -EIO;
+	major = (__force u32)val & 0xff;
+	minor = ((__force u32)val >> 8) & 0xff;
+	build = (__force u32)val >> 16;
+	if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+		return -EINVAL;
+
+	netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
+			NETXEN_BDINFO_MAGIC);
+	return 0;
+}
+
+static char *fw_name[] = { "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/" };
+
+int netxen_load_firmware(struct netxen_adapter *adapter)
+{
+	u32 capability, flashed_ver;
+	const struct firmware *fw;
+	int 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;
+	} else {
+		fw_type = NX_P3_CT_ROMIMAGE;
+		goto request_fw;
+	}
+
+request_mn:
+	capability = 0;
+
+	netxen_rom_fast_read(adapter,
+			NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+	if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+		adapter->hw_read_wx(adapter,
+				NX_PEG_TUNE_CAPABILITY, &capability, 4);
+		if (capability & NX_PEG_TUNE_MN_PRESENT) {
+			fw_type = NX_P3_MN_ROMIMAGE;
+			goto request_fw;
+		}
+	}
+
+request_fw:
+	rc = reject_firmware(&fw, fw_name[fw_type], &pdev->dev);
+	if (rc != 0) {
+		if (fw_type == NX_P3_CT_ROMIMAGE) {
+			msleep(1);
+			goto request_mn;
+		}
+
+		fw = NULL;
+		goto load_fw;
+	}
+
+	rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
+	if (rc != 0) {
+		release_firmware(fw);
+
+		if (fw_type == NX_P3_CT_ROMIMAGE) {
+			msleep(1);
+			goto request_mn;
+		}
+
+		fw = NULL;
+	}
+
+load_fw:
+	rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
+
+	if (fw)
+		release_firmware(fw);
+	return rc;
+}
+
 int
 netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
 		ulong off, void *data, int len)
 {
 	void __iomem *addr;
 
+	BUG_ON(len != 4);
+
 	if (ADDR_IN_WINDOW1(off)) {
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
 	} else {		/* Window 0 */
@@ -977,37 +1187,13 @@ netxen_nic_hw_write_wx_128M(struct netxe
 		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 	}
 
-	DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
-		" data %llx len %d\n",
-		pci_base(adapter, off), off, addr,
-		*(unsigned long long *)data, len);
 	if (!addr) {
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 		return 1;
 	}
 
-	switch (len) {
-	case 1:
-		writeb(*(u8 *) data, addr);
-		break;
-	case 2:
-		writew(*(u16 *) data, addr);
-		break;
-	case 4:
-		writel(*(u32 *) data, addr);
-		break;
-	case 8:
-		writeq(*(u64 *) data, addr);
-		break;
-	default:
-		DPRINTK(INFO,
-			"writing data %lx to offset %llx, num words=%d\n",
-			*(unsigned long *)data, off, (len >> 3));
+	writel(*(u32 *) data, addr);
 
-		netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
-					    (len >> 3));
-		break;
-	}
 	if (!ADDR_IN_WINDOW1(off))
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 
@@ -1020,6 +1206,8 @@ netxen_nic_hw_read_wx_128M(struct netxen
 {
 	void __iomem *addr;
 
+	BUG_ON(len != 4);
+
 	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
 	} else {		/* Window 0 */
@@ -1027,31 +1215,12 @@ netxen_nic_hw_read_wx_128M(struct netxen
 		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 	}
 
-	DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
-		pci_base(adapter, off), off, addr);
 	if (!addr) {
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 		return 1;
 	}
-	switch (len) {
-	case 1:
-		*(u8 *) data = readb(addr);
-		break;
-	case 2:
-		*(u16 *) data = readw(addr);
-		break;
-	case 4:
-		*(u32 *) data = readl(addr);
-		break;
-	case 8:
-		*(u64 *) data = readq(addr);
-		break;
-	default:
-		netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
-					   (len >> 3));
-		break;
-	}
-	DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
+
+	*(u32 *)data = readl(addr);
 
 	if (!ADDR_IN_WINDOW1(off))
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1066,6 +1235,8 @@ netxen_nic_hw_write_wx_2M(struct netxen_
 	unsigned long flags = 0;
 	int rv;
 
+	BUG_ON(len != 4);
+
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
 
 	if (rv == -1) {
@@ -1079,34 +1250,12 @@ netxen_nic_hw_write_wx_2M(struct netxen_
 		write_lock_irqsave(&adapter->adapter_lock, flags);
 		crb_win_lock(adapter);
 		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-	}
-
-	DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n",
-			*(unsigned long *)data, off, len);
-
-	switch (len) {
-	case 1:
-		writeb(*(uint8_t *)data, (void *)off);
-		break;
-	case 2:
-		writew(*(uint16_t *)data, (void *)off);
-		break;
-	case 4:
-		writel(*(uint32_t *)data, (void *)off);
-		break;
-	case 8:
-		writeq(*(uint64_t *)data, (void *)off);
-		break;
-	default:
-		DPRINTK(1, INFO,
-			"writing data %lx to offset %llx, num words=%d\n",
-			*(unsigned long *)data, off, (len>>3));
-		break;
-	}
-	if (rv == 1) {
+		writel(*(uint32_t *)data, (void __iomem *)off);
 		crb_win_unlock(adapter);
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	}
+	} else
+		writel(*(uint32_t *)data, (void __iomem *)off);
+
 
 	return 0;
 }
@@ -1118,6 +1267,8 @@ netxen_nic_hw_read_wx_2M(struct netxen_a
 	unsigned long flags = 0;
 	int rv;
 
+	BUG_ON(len != 4);
+
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
 
 	if (rv == -1) {
@@ -1131,33 +1282,11 @@ netxen_nic_hw_read_wx_2M(struct netxen_a
 		write_lock_irqsave(&adapter->adapter_lock, flags);
 		crb_win_lock(adapter);
 		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-	}
-
-	DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len);
-
-	switch (len) {
-	case 1:
-		*(uint8_t *)data = readb((void *)off);
-		break;
-	case 2:
-		*(uint16_t *)data = readw((void *)off);
-		break;
-	case 4:
-		*(uint32_t *)data = readl((void *)off);
-		break;
-	case 8:
-		*(uint64_t *)data = readq((void *)off);
-		break;
-	default:
-		break;
-	}
-
-	DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data);
-
-	if (rv == 1) {
+		*(uint32_t *)data = readl((void __iomem *)off);
 		crb_win_unlock(adapter);
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	}
+	} else
+		*(uint32_t *)data = readl((void __iomem *)off);
 
 	return 0;
 }
@@ -1419,10 +1548,9 @@ static int netxen_nic_pci_mem_read_direc
 			u64 off, void *data, int size)
 {
 	unsigned long flags;
-	void *addr;
+	void __iomem *addr, *mem_ptr = NULL;
 	int ret = 0;
 	u64 start;
-	uint8_t *mem_ptr = NULL;
 	unsigned long mem_base;
 	unsigned long mem_page;
 
@@ -1442,7 +1570,7 @@ static int netxen_nic_pci_mem_read_direc
 		return -1;
 	}
 
-	addr = (void *)(pci_base_offset(adapter, start));
+	addr = pci_base_offset(adapter, start);
 	if (!addr) {
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 		mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1481,7 +1609,6 @@ static int netxen_nic_pci_mem_read_direc
 		break;
 	}
 	write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
 
 	if (mem_ptr)
 		iounmap(mem_ptr);
@@ -1493,10 +1620,9 @@ netxen_nic_pci_mem_write_direct(struct n
 		void *data, int size)
 {
 	unsigned long flags;
-	void *addr;
+	void __iomem *addr, *mem_ptr = NULL;
 	int ret = 0;
 	u64 start;
-	uint8_t *mem_ptr = NULL;
 	unsigned long mem_base;
 	unsigned long mem_page;
 
@@ -1516,7 +1642,7 @@ netxen_nic_pci_mem_write_direct(struct n
 		return -1;
 	}
 
-	addr = (void *)(pci_base_offset(adapter, start));
+	addr = pci_base_offset(adapter, start);
 	if (!addr) {
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 		mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1553,8 +1679,6 @@ netxen_nic_pci_mem_write_direct(struct n
 		break;
 	}
 	write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	DPRINTK(1, INFO, "writing data %llx to offset %llx\n",
-			*(unsigned long long *)data, start);
 	if (mem_ptr)
 		iounmap(mem_ptr);
 	return ret;
@@ -1566,10 +1690,11 @@ int
 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
-	unsigned long   flags, mem_crb;
+	unsigned long   flags;
 	int	     i, j, ret = 0, loop, sz[2], off0;
 	uint32_t      temp;
 	uint64_t      off8, tmpw, word[2] = {0, 0};
+	void __iomem *mem_crb;
 
 	/*
 	 * If not MN, go check for MS or invalid.
@@ -1583,7 +1708,7 @@ netxen_nic_pci_mem_write_128M(struct net
 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
 	sz[1] = size - sz[0];
 	loop = ((off0 + size - 1) >> 3) + 1;
-	mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
 
 	if ((size != 8) || (off0 != 0))  {
 		for (i = 0; i < loop; i++) {
@@ -1621,28 +1746,29 @@ netxen_nic_pci_mem_write_128M(struct net
 
 	for (i = 0; i < loop; i++) {
 		writel((uint32_t)(off8 + (i << 3)),
-			(void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+			(mem_crb+MIU_TEST_AGT_ADDR_LO));
 		writel(0,
-			(void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+			(mem_crb+MIU_TEST_AGT_ADDR_HI));
 		writel(word[i] & 0xffffffff,
-			(void *)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
+			(mem_crb+MIU_TEST_AGT_WRDATA_LO));
 		writel((word[i] >> 32) & 0xffffffff,
-			(void *)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
+			(mem_crb+MIU_TEST_AGT_WRDATA_HI));
 		writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-			(void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			(mem_crb+MIU_TEST_AGT_CTRL));
 		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
-			(void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			(mem_crb+MIU_TEST_AGT_CTRL));
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
 			temp = readl(
-			     (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			     (mem_crb+MIU_TEST_AGT_CTRL));
 			if ((temp & MIU_TA_CTL_BUSY) == 0)
 				break;
 		}
 
 		if (j >= MAX_CTL_CHECK) {
-			printk("%s: %s Fail to write through agent\n",
-					__func__, netxen_nic_driver_name);
+			if (printk_ratelimit())
+				dev_err(&adapter->pdev->dev,
+					"failed to write through agent\n");
 			ret = -1;
 			break;
 		}
@@ -1657,10 +1783,11 @@ int
 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
-	unsigned long   flags, mem_crb;
+	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};
+	void __iomem *mem_crb;
 
 
 	/*
@@ -1675,31 +1802,32 @@ netxen_nic_pci_mem_read_128M(struct netx
 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
 	sz[1] = size - sz[0];
 	loop = ((off0[0] + size - 1) >> 3) + 1;
-	mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
 
 	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)),
-			(void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+			(mem_crb+MIU_TEST_AGT_ADDR_LO));
 		writel(0,
-			(void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+			(mem_crb+MIU_TEST_AGT_ADDR_HI));
 		writel(MIU_TA_CTL_ENABLE,
-			(void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			(mem_crb+MIU_TEST_AGT_CTRL));
 		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
-			(void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			(mem_crb+MIU_TEST_AGT_CTRL));
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
 			temp = readl(
-			      (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+			      (mem_crb+MIU_TEST_AGT_CTRL));
 			if ((temp & MIU_TA_CTL_BUSY) == 0)
 				break;
 		}
 
 		if (j >= MAX_CTL_CHECK) {
-			printk(KERN_ERR "%s: %s Fail to read through agent\n",
-					__func__, netxen_nic_driver_name);
+			if (printk_ratelimit())
+				dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
 			break;
 		}
 
@@ -1707,7 +1835,7 @@ netxen_nic_pci_mem_read_128M(struct netx
 		end   = (off0[i] + sz[i] - 1) >> 2;
 		for (k = start; k <= end; k++) {
 			word[i] |= ((uint64_t) readl(
-				    (void *)(mem_crb +
+				    (mem_crb +
 				    MIU_TEST_AGT_RDDATA(k))) << (32*k));
 		}
 	}
@@ -1739,7 +1867,6 @@ netxen_nic_pci_mem_read_128M(struct netx
 		*(uint64_t *)data = val;
 		break;
 	}
-	DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
 	return 0;
 }
 
@@ -1835,8 +1962,9 @@ netxen_nic_pci_mem_write_2M(struct netxe
 		}
 
 		if (j >= MAX_CTL_CHECK) {
-			printk(KERN_ERR "%s: Fail to write through agent\n",
-					netxen_nic_driver_name);
+			if (printk_ratelimit())
+				dev_err(&adapter->pdev->dev,
+					"failed to write through agent\n");
 			ret = -1;
 			break;
 		}
@@ -1905,8 +2033,9 @@ netxen_nic_pci_mem_read_2M(struct netxen
 		}
 
 		if (j >= MAX_CTL_CHECK) {
-			printk(KERN_ERR "%s: Fail to read through agent\n",
-					netxen_nic_driver_name);
+			if (printk_ratelimit())
+				dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
 			break;
 		}
 
@@ -1948,7 +2077,6 @@ netxen_nic_pci_mem_read_2M(struct netxen
 		*(uint64_t *)data = val;
 		break;
 	}
-	DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
 	return 0;
 }
 
@@ -1983,62 +2111,46 @@ u32 netxen_nic_pci_read_normalize_2M(str
 	return temp;
 }
 
-#if 0
-int
-netxen_nic_erase_pxe(struct netxen_adapter *adapter)
-{
-	if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
-		printk(KERN_ERR "%s: erase pxe failed\n",
-			netxen_nic_driver_name);
-		return -1;
-	}
-	return 0;
-}
-#endif  /*  0  */
-
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 {
-	int rv = 0;
-	int addr = NETXEN_BRDCFG_START;
-	struct netxen_board_info *boardinfo;
-	int index;
-	u32 *ptr32;
+	int offset, board_type, magic, header_version;
+	struct pci_dev *pdev = adapter->pdev;
 
-	boardinfo = &adapter->ahw.boardcfg;
-	ptr32 = (u32 *) boardinfo;
+	offset = NETXEN_BRDCFG_START +
+		offsetof(struct netxen_board_info, magic);
+	if (netxen_rom_fast_read(adapter, offset, &magic))
+		return -EIO;
 
-	for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
-	     index++) {
-		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
-			return -EIO;
-		}
-		ptr32++;
-		addr += sizeof(u32);
-	}
-	if (boardinfo->magic != NETXEN_BDINFO_MAGIC) {
-		printk("%s: ERROR reading %s board config."
-		       " Read %x, expected %x\n", netxen_nic_driver_name,
-		       netxen_nic_driver_name,
-		       boardinfo->magic, NETXEN_BDINFO_MAGIC);
-		rv = -1;
-	}
-	if (boardinfo->header_version != NETXEN_BDINFO_VERSION) {
-		printk("%s: Unknown board config version."
-		       " Read %x, expected %x\n", netxen_nic_driver_name,
-		       boardinfo->header_version, NETXEN_BDINFO_VERSION);
-		rv = -1;
+	offset = NETXEN_BRDCFG_START +
+		offsetof(struct netxen_board_info, header_version);
+	if (netxen_rom_fast_read(adapter, offset, &header_version))
+		return -EIO;
+
+	if (magic != NETXEN_BDINFO_MAGIC ||
+			header_version != NETXEN_BDINFO_VERSION) {
+		dev_err(&pdev->dev,
+			"invalid board config, magic=%08x, version=%08x\n",
+			magic, header_version);
+		return -EIO;
 	}
 
-	if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
+	offset = NETXEN_BRDCFG_START +
+		offsetof(struct netxen_board_info, board_type);
+	if (netxen_rom_fast_read(adapter, offset, &board_type))
+		return -EIO;
+
+	adapter->ahw.board_type = board_type;
+
+	if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
 		u32 gpio = netxen_nic_reg_read(adapter,
 				NETXEN_ROMUSB_GLB_PAD_GPIO_I);
 		if ((gpio & 0x8000) == 0)
-			boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP;
+			board_type = NETXEN_BRDTYPE_P3_10G_TP;
 	}
 
-	switch ((netxen_brdtype_t) boardinfo->board_type) {
+	switch ((netxen_brdtype_t)board_type) {
 	case NETXEN_BRDTYPE_P2_SB35_4G:
-		adapter->ahw.board_type = NETXEN_NIC_GBE;
+		adapter->ahw.port_type = NETXEN_NIC_GBE;
 		break;
 	case NETXEN_BRDTYPE_P2_SB31_10G:
 	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -2054,7 +2166,7 @@ int netxen_nic_get_board_info(struct net
 	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 	case NETXEN_BRDTYPE_P3_10000_BASE_T:
-		adapter->ahw.board_type = NETXEN_NIC_XGBE;
+		adapter->ahw.port_type = NETXEN_NIC_XGBE;
 		break;
 	case NETXEN_BRDTYPE_P1_BD:
 	case NETXEN_BRDTYPE_P1_SB:
@@ -2063,20 +2175,19 @@ int netxen_nic_get_board_info(struct net
 	case NETXEN_BRDTYPE_P3_REF_QG:
 	case NETXEN_BRDTYPE_P3_4_GB:
 	case NETXEN_BRDTYPE_P3_4_GB_MM:
-		adapter->ahw.board_type = NETXEN_NIC_GBE;
+		adapter->ahw.port_type = NETXEN_NIC_GBE;
 		break;
 	case NETXEN_BRDTYPE_P3_10G_TP:
-		adapter->ahw.board_type = (adapter->portnum < 2) ?
+		adapter->ahw.port_type = (adapter->portnum < 2) ?
 			NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
 		break;
 	default:
-		printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
-		       boardinfo->board_type);
-		rv = -ENODEV;
+		dev_err(&pdev->dev, "unknown board type %x\n", board_type);
+		adapter->ahw.port_type = NETXEN_NIC_XGBE;
 		break;
 	}
 
-	return rv;
+	return 0;
 }
 
 /* NIU access sections */
@@ -2122,7 +2233,7 @@ void netxen_nic_set_link_parameters(stru
 		return;
 	}
 
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		adapter->hw_read_wx(adapter,
 				NETXEN_PORT_MODE_ADDR, &port_mode, 4);
 		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -2177,32 +2288,27 @@ void netxen_nic_set_link_parameters(stru
 	}
 }
 
-void netxen_nic_flash_print(struct netxen_adapter *adapter)
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
 {
-	u32 fw_major = 0;
-	u32 fw_minor = 0;
-	u32 fw_build = 0;
+	u32 fw_major, fw_minor, fw_build;
 	char brd_name[NETXEN_MAX_SHORT_NAME];
 	char serial_num[32];
-	int i, addr;
-	__le32 *ptr32;
-
-	struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
+	int i, addr, val;
+	int *ptr32;
+	struct pci_dev *pdev = adapter->pdev;
 
 	adapter->driver_mismatch = 0;
 
-	ptr32 = (u32 *)&serial_num;
+	ptr32 = (int *)&serial_num;
 	addr = NETXEN_USER_START +
 	       offsetof(struct netxen_new_user_info, serial_num);
 	for (i = 0; i < 8; i++) {
-		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
-			printk("%s: ERROR reading %s board userarea.\n",
-			       netxen_nic_driver_name,
-			       netxen_nic_driver_name);
+		if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
+			dev_err(&pdev->dev, "error reading board info\n");
 			adapter->driver_mismatch = 1;
 			return;
 		}
-		ptr32++;
+		ptr32[i] = cpu_to_le32(val);
 		addr += sizeof(u32);
 	}
 
@@ -2211,23 +2317,48 @@ void netxen_nic_flash_print(struct netxe
 	adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
 
 	adapter->fw_major = fw_major;
+	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
 
 	if (adapter->portnum == 0) {
-		get_brd_name_by_type(board_info->board_type, brd_name);
+		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",
 				brd_name, serial_num, adapter->ahw.revision_id);
-		printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
-				fw_major, fw_minor, fw_build);
 	}
 
-	if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
-			NETXEN_VERSION_CODE(3, 4, 216)) {
+	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
 		adapter->driver_mismatch = 1;
-		printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n",
-				netxen_nic_driver_name,
+		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
 				fw_major, fw_minor, fw_build);
 		return;
 	}
+
+	dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
+			fw_major, fw_minor, fw_build);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		adapter->hw_read_wx(adapter,
+				NETXEN_MIU_MN_CONTROL, &i, 4);
+		adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
+		dev_info(&pdev->dev, "firmware running in %s mode\n",
+		adapter->ahw.cut_through ? "cut-through" : "legacy");
+	}
 }
 
+int
+netxen_nic_wol_supported(struct netxen_adapter *adapter)
+{
+	u32 wol_cfg;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 0;
+
+	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+	if (wol_cfg & (1UL << adapter->portnum)) {
+		wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+		if (wol_cfg & (1 << adapter->portnum))
+			return 1;
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hw.h linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Structures, enums, and macros for the MAC
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -54,37 +51,12 @@ static inline void writeq(u64 val, void
 }
 #endif
 
-static inline void netxen_nic_hw_block_write64(u64 __iomem * data_ptr,
-					       u64 __iomem * addr,
-					       int num_words)
-{
-	int num;
-	for (num = 0; num < num_words; num++) {
-		writeq(readq((void __iomem *)data_ptr), addr);
-		addr++;
-		data_ptr++;
-	}
-}
-
-static inline void netxen_nic_hw_block_read64(u64 __iomem * data_ptr,
-					      u64 __iomem * addr, int num_words)
-{
-	int num;
-	for (num = 0; num < num_words; num++) {
-		writeq(readq((void __iomem *)addr), data_ptr);
-		addr++;
-		data_ptr++;
-	}
-
-}
-
 struct netxen_adapter;
 
 #define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
 
 struct netxen_port;
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
-void netxen_nic_flash_print(struct netxen_adapter *adapter);
 
 typedef u8 netxen_ethernet_macaddr_t[6];
 
@@ -148,33 +120,6 @@ typedef enum {
 #define netxen_gb_get_soft_reset(config_word)	\
 		_netxen_crb_get_bit((config_word), 31)
 
-/*
- * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
- *
- *	Bit 0	    : duplex => 1:full duplex mode, 0:half duplex
- *	Bit 1	    : crc_enable => 1:append CRC to xmit frames, 0:dont append
- *	Bit 2	    : padshort => 1:pad short frames and add CRC, 0:dont pad
- *	Bit 4	    : checklength => 1:check framelen with actual,0:dont check
- *	Bit 5	    : hugeframes => 1:allow oversize xmit frames, 0:dont allow
- *	Bits 8-9    : intfmode => 01:nibble (10/100), 10:byte (1000)
- *	Bits 12-15  : preamblelen => preamble field length in bytes, default 7
- */
-
-#define netxen_gb_set_duplex(config_word)	\
-		((config_word) |= 1 << 0)
-#define netxen_gb_set_crc_enable(config_word)	\
-		((config_word) |= 1 << 1)
-#define netxen_gb_set_padshort(config_word)	\
-		((config_word) |= 1 << 2)
-#define netxen_gb_set_checklength(config_word)	\
-		((config_word) |= 1 << 4)
-#define netxen_gb_set_hugeframes(config_word)	\
-		((config_word) |= 1 << 5)
-#define netxen_gb_set_preamblelen(config_word, val)	\
-		((config_word) |= ((val) << 12) & 0xF000)
-#define netxen_gb_set_intfmode(config_word, val)		\
-		((config_word) |= ((val) << 8) & 0x300)
-
 #define netxen_gb_get_stationaddress_low(config_word) ((config_word) >> 16)
 
 #define netxen_gb_set_mii_mgmt_clockselect(config_word, val)	\
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_init.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_init.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_init.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_init.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to initialize the Phantom Hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -52,17 +49,9 @@ static unsigned int crb_addr_xform[NETXE
 
 #define NETXEN_NIC_XDMA_RESET 0x8000ff
 
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
-					uint32_t ctx, uint32_t ringid);
-
-#if 0
-static void netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
-					unsigned long off, int *data)
-{
-	void __iomem *addr = pci_base_offset(adapter, off);
-	writel(*data, addr);
-}
-#endif  /*  0  */
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+		struct nx_host_rds_ring *rds_ring);
 
 static void crb_addr_transform_setup(void)
 {
@@ -160,23 +149,21 @@ void netxen_release_rx_buffers(struct ne
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
 	struct netxen_rx_buffer *rx_buf;
-	int i, ctxid, ring;
+	int i, ring;
 
-	for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
-		recv_ctx = &adapter->recv_ctx[ctxid];
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			rds_ring = &recv_ctx->rds_rings[ring];
-			for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
-				rx_buf = &(rds_ring->rx_buf_arr[i]);
-				if (rx_buf->state == NETXEN_BUFFER_FREE)
-					continue;
-				pci_unmap_single(adapter->pdev,
-						rx_buf->dma,
-						rds_ring->dma_size,
-						PCI_DMA_FROMDEVICE);
-				if (rx_buf->skb != NULL)
-					dev_kfree_skb_any(rx_buf->skb);
-			}
+	recv_ctx = &adapter->recv_ctx;
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
+		for (i = 0; i < rds_ring->num_desc; ++i) {
+			rx_buf = &(rds_ring->rx_buf_arr[i]);
+			if (rx_buf->state == NETXEN_BUFFER_FREE)
+				continue;
+			pci_unmap_single(adapter->pdev,
+					rx_buf->dma,
+					rds_ring->dma_size,
+					PCI_DMA_FROMDEVICE);
+			if (rx_buf->skb != NULL)
+				dev_kfree_skb_any(rx_buf->skb);
 		}
 	}
 }
@@ -188,7 +175,7 @@ void netxen_release_tx_buffers(struct ne
 	int i, j;
 
 	cmd_buf = adapter->cmd_buf_arr;
-	for (i = 0; i < adapter->max_tx_desc_count; i++) {
+	for (i = 0; i < adapter->num_txd; i++) {
 		buffrag = cmd_buf->frag_array;
 		if (buffrag->dma) {
 			pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -204,7 +191,6 @@ void netxen_release_tx_buffers(struct ne
 				buffrag->dma = 0ULL;
 			}
 		}
-		/* Free the skb we received in netxen_nic_xmit_frame */
 		if (cmd_buf->skb) {
 			dev_kfree_skb_any(cmd_buf->skb);
 			cmd_buf->skb = NULL;
@@ -217,18 +203,17 @@ void netxen_free_sw_resources(struct net
 {
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
-	int ctx, ring;
+	int ring;
 
-	for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
-		recv_ctx = &adapter->recv_ctx[ctx];
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			rds_ring = &recv_ctx->rds_rings[ring];
-			if (rds_ring->rx_buf_arr) {
-				vfree(rds_ring->rx_buf_arr);
-				rds_ring->rx_buf_arr = NULL;
-			}
+	recv_ctx = &adapter->recv_ctx;
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
+		if (rds_ring->rx_buf_arr) {
+			vfree(rds_ring->rx_buf_arr);
+			rds_ring->rx_buf_arr = NULL;
 		}
 	}
+
 	if (adapter->cmd_buf_arr)
 		vfree(adapter->cmd_buf_arr);
 	return;
@@ -238,90 +223,97 @@ int netxen_alloc_sw_resources(struct net
 {
 	struct netxen_recv_context *recv_ctx;
 	struct nx_host_rds_ring *rds_ring;
+	struct nx_host_sds_ring *sds_ring;
 	struct netxen_rx_buffer *rx_buf;
-	int ctx, ring, i, num_rx_bufs;
+	int ring, i, num_rx_bufs;
 
 	struct netxen_cmd_buffer *cmd_buf_arr;
 	struct net_device *netdev = adapter->netdev;
 
-	cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+	cmd_buf_arr =
+		(struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
 	if (cmd_buf_arr == NULL) {
 		printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
 		       netdev->name);
 		return -ENOMEM;
 	}
-	memset(cmd_buf_arr, 0, TX_RINGSIZE);
+	memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
 	adapter->cmd_buf_arr = cmd_buf_arr;
 
-	for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
-		recv_ctx = &adapter->recv_ctx[ctx];
-		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
-			rds_ring = &recv_ctx->rds_rings[ring];
-			switch (RCV_DESC_TYPE(ring)) {
-			case RCV_DESC_NORMAL:
-				rds_ring->max_rx_desc_count =
-					adapter->max_rx_desc_count;
-				rds_ring->flags = RCV_DESC_NORMAL;
-				if (adapter->ahw.cut_through) {
-					rds_ring->dma_size =
-						NX_CT_DEFAULT_RX_BUF_LEN;
-					rds_ring->skb_size =
-						NX_CT_DEFAULT_RX_BUF_LEN;
-				} else {
-					rds_ring->dma_size = RX_DMA_MAP_LEN;
-					rds_ring->skb_size =
-						MAX_RX_BUFFER_LENGTH;
-				}
-				break;
-
-			case RCV_DESC_JUMBO:
-				rds_ring->max_rx_desc_count =
-					adapter->max_jumbo_rx_desc_count;
-				rds_ring->flags = RCV_DESC_JUMBO;
-				if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-					rds_ring->dma_size =
-						NX_P3_RX_JUMBO_BUF_MAX_LEN;
-				else
-					rds_ring->dma_size =
-						NX_P2_RX_JUMBO_BUF_MAX_LEN;
+	recv_ctx = &adapter->recv_ctx;
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &recv_ctx->rds_rings[ring];
+		switch (ring) {
+		case RCV_RING_NORMAL:
+			rds_ring->num_desc = adapter->num_rxd;
+			if (adapter->ahw.cut_through) {
+				rds_ring->dma_size =
+					NX_CT_DEFAULT_RX_BUF_LEN;
 				rds_ring->skb_size =
-					rds_ring->dma_size + NET_IP_ALIGN;
-				break;
+					NX_CT_DEFAULT_RX_BUF_LEN;
+			} else {
+				rds_ring->dma_size = RX_DMA_MAP_LEN;
+				rds_ring->skb_size =
+					MAX_RX_BUFFER_LENGTH;
+			}
+			break;
 
-			case RCV_RING_LRO:
-				rds_ring->max_rx_desc_count =
-					adapter->max_lro_rx_desc_count;
-				rds_ring->flags = RCV_DESC_LRO;
-				rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
-				rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
-				break;
+		case RCV_RING_JUMBO:
+			rds_ring->num_desc = adapter->num_jumbo_rxd;
+			if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+				rds_ring->dma_size =
+					NX_P3_RX_JUMBO_BUF_MAX_LEN;
+			else
+				rds_ring->dma_size =
+					NX_P2_RX_JUMBO_BUF_MAX_LEN;
+			rds_ring->skb_size =
+				rds_ring->dma_size + NET_IP_ALIGN;
+			break;
+
+		case RCV_RING_LRO:
+			rds_ring->num_desc = adapter->num_lro_rxd;
+			rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
+			rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+			break;
 
-			}
-			rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
-				vmalloc(RCV_BUFFSIZE);
-			if (rds_ring->rx_buf_arr == NULL) {
-				printk(KERN_ERR "%s: Failed to allocate "
-					"rx buffer ring %d\n",
-					netdev->name, ring);
-				/* free whatever was already allocated */
-				goto err_out;
-			}
-			memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
-			INIT_LIST_HEAD(&rds_ring->free_list);
-			/*
-			 * Now go through all of them, set reference handles
-			 * and put them in the queues.
-			 */
-			num_rx_bufs = rds_ring->max_rx_desc_count;
-			rx_buf = rds_ring->rx_buf_arr;
-			for (i = 0; i < num_rx_bufs; i++) {
-				list_add_tail(&rx_buf->list,
-						&rds_ring->free_list);
-				rx_buf->ref_handle = i;
-				rx_buf->state = NETXEN_BUFFER_FREE;
-				rx_buf++;
-			}
 		}
+		rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
+			vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+		if (rds_ring->rx_buf_arr == NULL) {
+			printk(KERN_ERR "%s: Failed to allocate "
+				"rx buffer ring %d\n",
+				netdev->name, ring);
+			/* free whatever was already allocated */
+			goto err_out;
+		}
+		memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
+		INIT_LIST_HEAD(&rds_ring->free_list);
+		/*
+		 * Now go through all of them, set reference handles
+		 * and put them in the queues.
+		 */
+		num_rx_bufs = rds_ring->num_desc;
+		rx_buf = rds_ring->rx_buf_arr;
+		for (i = 0; i < num_rx_bufs; i++) {
+			list_add_tail(&rx_buf->list,
+					&rds_ring->free_list);
+			rx_buf->ref_handle = i;
+			rx_buf->state = NETXEN_BUFFER_FREE;
+			rx_buf++;
+		}
+		spin_lock_init(&rds_ring->lock);
+	}
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		sds_ring->irq = adapter->msix_entries[ring].vector;
+		sds_ring->clean_tx = (ring == 0);
+		sds_ring->post_rxd = (ring == 0);
+		sds_ring->adapter = adapter;
+		sds_ring->num_desc = adapter->num_rxd;
+
+		for (i = 0; i < NUM_RCV_DESC_RINGS; i++)
+			INIT_LIST_HEAD(&sds_ring->free_list[i]);
 	}
 
 	return 0;
@@ -333,7 +325,7 @@ err_out:
 
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
 {
-	switch (adapter->ahw.board_type) {
+	switch (adapter->ahw.port_type) {
 	case NETXEN_NIC_GBE:
 		adapter->enable_phy_interrupts =
 		    netxen_niu_gbe_enable_phy_interrupts;
@@ -399,9 +391,6 @@ static u32 netxen_decode_crb_addr(u32 ad
 
 static long rom_max_timeout = 100;
 static long rom_lock_timeout = 10000;
-#if 0
-static long rom_write_timeout = 700;
-#endif
 
 static int rom_lock(struct netxen_adapter *adapter)
 {
@@ -452,38 +441,6 @@ static int netxen_wait_rom_done(struct n
 	return 0;
 }
 
-#if 0
-static int netxen_rom_wren(struct netxen_adapter *adapter)
-{
-	/* Set write enable latch in ROM status register */
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
-			     M25P_INSTR_WREN);
-	if (netxen_wait_rom_done(adapter)) {
-		return -1;
-	}
-	return 0;
-}
-
-static unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
-				    unsigned int addr)
-{
-	unsigned int data = 0xdeaddead;
-	data = netxen_nic_reg_read(adapter, addr);
-	return data;
-}
-
-static int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
-{
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
-			     M25P_INSTR_RDSR);
-	if (netxen_wait_rom_done(adapter)) {
-		return -1;
-	}
-	return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
-}
-#endif
-
 static void netxen_rom_unlock(struct netxen_adapter *adapter)
 {
 	u32 val;
@@ -493,44 +450,6 @@ static void netxen_rom_unlock(struct net
 
 }
 
-#if 0
-static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
-{
-	long timeout = 0;
-	long wip = 1;
-	int val;
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-	while (wip != 0) {
-		val = netxen_do_rom_rdsr(adapter);
-		wip = val & 1;
-		timeout++;
-		if (timeout > rom_max_timeout) {
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
-			     int data)
-{
-	if (netxen_rom_wren(adapter)) {
-		return -1;
-	}
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
-			     M25P_INSTR_PP);
-	if (netxen_wait_rom_done(adapter)) {
-		netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-		return -1;
-	}
-
-	return netxen_rom_wip_poll(adapter);
-}
-#endif
-
 static int do_rom_fast_read(struct netxen_adapter *adapter,
 			    int addr, int *valp)
 {
@@ -597,284 +516,6 @@ int netxen_rom_fast_read(struct netxen_a
 	return ret;
 }
 
-#if 0
-int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
-{
-	int ret = 0;
-
-	if (rom_lock(adapter) != 0) {
-		return -1;
-	}
-	ret = do_rom_fast_write(adapter, addr, data);
-	netxen_rom_unlock(adapter);
-	return ret;
-}
-
-static int do_rom_fast_write_words(struct netxen_adapter *adapter,
-				   int addr, u8 *bytes, size_t size)
-{
-	int addridx = addr;
-	int ret = 0;
-
-	while (addridx < (addr + size)) {
-		int last_attempt = 0;
-		int timeout = 0;
-		int data;
-
-		data = le32_to_cpu((*(__le32*)bytes));
-		ret = do_rom_fast_write(adapter, addridx, data);
-		if (ret < 0)
-			return ret;
-
-		while(1) {
-			int data1;
-
-			ret = do_rom_fast_read(adapter, addridx, &data1);
-			if (ret < 0)
-				return ret;
-
-			if (data1 == data)
-				break;
-
-			if (timeout++ >= rom_write_timeout) {
-				if (last_attempt++ < 4) {
-					ret = do_rom_fast_write(adapter,
-								addridx, data);
-					if (ret < 0)
-						return ret;
-				}
-				else {
-					printk(KERN_INFO "Data write did not "
-					   "succeed at address 0x%x\n", addridx);
-					break;
-				}
-			}
-		}
-
-		bytes += 4;
-		addridx += 4;
-	}
-
-	return ret;
-}
-
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
-					u8 *bytes, size_t size)
-{
-	int ret = 0;
-
-	ret = rom_lock(adapter);
-	if (ret < 0)
-		return ret;
-
-	ret = do_rom_fast_write_words(adapter, addr, bytes, size);
-	netxen_rom_unlock(adapter);
-
-	return ret;
-}
-
-static int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
-{
-	int ret;
-
-	ret = netxen_rom_wren(adapter);
-	if (ret < 0)
-		return ret;
-
-	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
-	netxen_crb_writelit_adapter(adapter,
-					NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
-
-	ret = netxen_wait_rom_done(adapter);
-	if (ret < 0)
-		return ret;
-
-	return netxen_rom_wip_poll(adapter);
-}
-
-static int netxen_rom_rdsr(struct netxen_adapter *adapter)
-{
-	int ret;
-
-	ret = rom_lock(adapter);
-	if (ret < 0)
-		return ret;
-
-	ret = netxen_do_rom_rdsr(adapter);
-	netxen_rom_unlock(adapter);
-	return ret;
-}
-
-int netxen_backup_crbinit(struct netxen_adapter *adapter)
-{
-	int ret = FLASH_SUCCESS;
-	int val;
-	char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
-
-	if (!buffer)
-		return -ENOMEM;
-	/* unlock sector 63 */
-	val = netxen_rom_rdsr(adapter);
-	val = val & 0xe3;
-	ret = netxen_rom_wrsr(adapter, val);
-	if (ret != FLASH_SUCCESS)
-		goto out_kfree;
-
-	ret = netxen_rom_wip_poll(adapter);
-	if (ret != FLASH_SUCCESS)
-		goto out_kfree;
-
-	/* copy  sector 0 to sector 63 */
-	ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
-					buffer, NETXEN_FLASH_SECTOR_SIZE);
-	if (ret != FLASH_SUCCESS)
-		goto out_kfree;
-
-	ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
-					buffer, NETXEN_FLASH_SECTOR_SIZE);
-	if (ret != FLASH_SUCCESS)
-		goto out_kfree;
-
-	/* lock sector 63 */
-	val = netxen_rom_rdsr(adapter);
-	if (!(val & 0x8)) {
-		val |= (0x1 << 2);
-		/* lock sector 63 */
-		if (netxen_rom_wrsr(adapter, val) == 0) {
-			ret = netxen_rom_wip_poll(adapter);
-			if (ret != FLASH_SUCCESS)
-				goto out_kfree;
-
-			/* lock SR writes */
-			ret = netxen_rom_wip_poll(adapter);
-			if (ret != FLASH_SUCCESS)
-				goto out_kfree;
-		}
-	}
-
-out_kfree:
-	kfree(buffer);
-	return ret;
-}
-
-static int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
-{
-	netxen_rom_wren(adapter);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
-			     M25P_INSTR_SE);
-	if (netxen_wait_rom_done(adapter)) {
-		netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-		return -1;
-	}
-	return netxen_rom_wip_poll(adapter);
-}
-
-static void check_erased_flash(struct netxen_adapter *adapter, int addr)
-{
-	int i;
-	int val;
-	int count = 0, erased_errors = 0;
-	int range;
-
-	range = (addr == NETXEN_USER_START) ?
-		NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
-
-	for (i = addr; i < range; i += 4) {
-		netxen_rom_fast_read(adapter, i, &val);
-		if (val != 0xffffffff)
-			erased_errors++;
-		count++;
-	}
-
-	if (erased_errors)
-		printk(KERN_INFO "0x%x out of 0x%x words fail to be erased "
-			"for sector address: %x\n", erased_errors, count, addr);
-}
-
-int netxen_rom_se(struct netxen_adapter *adapter, int addr)
-{
-	int ret = 0;
-	if (rom_lock(adapter) != 0) {
-		return -1;
-	}
-	ret = netxen_do_rom_se(adapter, addr);
-	netxen_rom_unlock(adapter);
-	msleep(30);
-	check_erased_flash(adapter, addr);
-
-	return ret;
-}
-
-static int netxen_flash_erase_sections(struct netxen_adapter *adapter,
-				       int start, int end)
-{
-	int ret = FLASH_SUCCESS;
-	int i;
-
-	for (i = start; i < end; i++) {
-		ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE);
-		if (ret)
-			break;
-		ret = netxen_rom_wip_poll(adapter);
-		if (ret < 0)
-			return ret;
-	}
-
-	return ret;
-}
-
-int
-netxen_flash_erase_secondary(struct netxen_adapter *adapter)
-{
-	int ret = FLASH_SUCCESS;
-	int start, end;
-
-	start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
-	end   = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE;
-	ret = netxen_flash_erase_sections(adapter, start, end);
-
-	return ret;
-}
-
-int
-netxen_flash_erase_primary(struct netxen_adapter *adapter)
-{
-	int ret = FLASH_SUCCESS;
-	int start, end;
-
-	start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE;
-	end   = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
-	ret = netxen_flash_erase_sections(adapter, start, end);
-
-	return ret;
-}
-
-void netxen_halt_pegs(struct netxen_adapter *adapter)
-{
-	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);
-	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);
-	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);
-	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);
-}
-
-int netxen_flash_unlock(struct netxen_adapter *adapter)
-{
-	int ret = 0;
-
-	ret = netxen_rom_wrsr(adapter, 0);
-	if (ret < 0)
-		return ret;
-
-	ret = netxen_rom_wren(adapter);
-	if (ret < 0)
-		return ret;
-
-	return ret;
-}
-#endif  /*  0  */
-
 #define NETXEN_BOARDTYPE		0x4008
 #define NETXEN_BOARDNUM 		0x400c
 #define NETXEN_CHIPNUM			0x4010
@@ -1168,6 +809,40 @@ int netxen_receive_peg_ready(struct netx
 	return 0;
 }
 
+static int
+netxen_alloc_rx_skb(struct netxen_adapter *adapter,
+		struct nx_host_rds_ring *rds_ring,
+		struct netxen_rx_buffer *buffer)
+{
+	struct sk_buff *skb;
+	dma_addr_t dma;
+	struct pci_dev *pdev = adapter->pdev;
+
+	buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+	if (!buffer->skb)
+		return 1;
+
+	skb = buffer->skb;
+
+	if (!adapter->ahw.cut_through)
+		skb_reserve(skb, 2);
+
+	dma = pci_map_single(pdev, skb->data,
+			rds_ring->dma_size, PCI_DMA_FROMDEVICE);
+
+	if (pci_dma_mapping_error(pdev, dma)) {
+		dev_kfree_skb_any(skb);
+		buffer->skb = NULL;
+		return 1;
+	}
+
+	buffer->skb = skb;
+	buffer->dma = dma;
+	buffer->state = NETXEN_BUFFER_BUSY;
+
+	return 0;
+}
+
 static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
 		struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
 {
@@ -1192,164 +867,121 @@ static struct sk_buff *netxen_process_rx
 	skb->dev = adapter->netdev;
 
 	buffer->skb = NULL;
-
 no_skb:
 	buffer->state = NETXEN_BUFFER_FREE;
-	buffer->lro_current_frags = 0;
-	buffer->lro_expected_frags = 0;
-	list_add_tail(&buffer->list, &rds_ring->free_list);
 	return skb;
 }
 
-/*
- * netxen_process_rcv() send the received packet to the protocol stack.
- * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
- * invoke the routine to send more rx buffers to the Phantom...
- */
-static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
-		struct status_desc *desc, struct status_desc *frag_desc)
+static struct netxen_rx_buffer *
+netxen_process_rcv(struct netxen_adapter *adapter,
+		int ring, int index, int length, int cksum, int pkt_offset)
 {
 	struct net_device *netdev = adapter->netdev;
-	u64 sts_data = le64_to_cpu(desc->status_desc_data);
-	int index = netxen_get_sts_refhandle(sts_data);
-	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 	struct netxen_rx_buffer *buffer;
 	struct sk_buff *skb;
-	u32 length = netxen_get_sts_totallength(sts_data);
-	u32 desc_ctx;
-	u16 pkt_offset = 0, cksum;
-	struct nx_host_rds_ring *rds_ring;
+	struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
 
-	desc_ctx = netxen_get_sts_type(sts_data);
-	if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
-		printk("%s: %s Bad Rcv descriptor ring\n",
-		       netxen_nic_driver_name, netdev->name);
-		return;
-	}
+	if (unlikely(index > rds_ring->num_desc))
+		return NULL;
 
-	rds_ring = &recv_ctx->rds_rings[desc_ctx];
-	if (unlikely(index > rds_ring->max_rx_desc_count)) {
-		DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
-			index, rds_ring->max_rx_desc_count);
-		return;
-	}
 	buffer = &rds_ring->rx_buf_arr[index];
-	if (desc_ctx == RCV_DESC_LRO_CTXID) {
-		buffer->lro_current_frags++;
-		if (netxen_get_sts_desc_lro_last_frag(desc)) {
-			buffer->lro_expected_frags =
-			    netxen_get_sts_desc_lro_cnt(desc);
-			buffer->lro_length = length;
-		}
-		if (buffer->lro_current_frags != buffer->lro_expected_frags) {
-			if (buffer->lro_expected_frags != 0) {
-				printk("LRO: (refhandle:%x) recv frag. "
-				       "wait for last. flags: %x expected:%d "
-				       "have:%d\n", index,
-				       netxen_get_sts_desc_lro_last_frag(desc),
-				       buffer->lro_expected_frags,
-				       buffer->lro_current_frags);
-			}
-			return;
-		}
-	}
-
-	cksum = netxen_get_sts_status(sts_data);
 
 	skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
 	if (!skb)
-		return;
+		return buffer;
 
-	if (desc_ctx == RCV_DESC_LRO_CTXID) {
-		/* True length was only available on the last pkt */
-		skb_put(skb, buffer->lro_length);
-	} else {
-		if (length > rds_ring->skb_size)
-			skb_put(skb, rds_ring->skb_size);
-		else
-			skb_put(skb, length);
+	if (length > rds_ring->skb_size)
+		skb_put(skb, rds_ring->skb_size);
+	else
+		skb_put(skb, length);
 
-		pkt_offset = netxen_get_sts_pkt_offset(sts_data);
-		if (pkt_offset)
-			skb_pull(skb, pkt_offset);
-	}
+
+	if (pkt_offset)
+		skb_pull(skb, pkt_offset);
 
 	skb->protocol = eth_type_trans(skb, netdev);
 
-	/*
-	 * rx buffer chaining is disabled, walk and free
-	 * any spurious rx buffer chain.
-	 */
-	if (frag_desc) {
-		u16 i, nr_frags = desc->nr_frags;
+	netif_receive_skb(skb);
 
-		dev_kfree_skb_any(skb);
-		for (i = 0; i < nr_frags; i++) {
-			index = le16_to_cpu(frag_desc->frag_handles[i]);
-			skb = netxen_process_rxbuf(adapter,
-					rds_ring, index, cksum);
-			if (skb)
-				dev_kfree_skb_any(skb);
-		}
-		adapter->stats.rxdropped++;
-	} else {
-		netif_receive_skb(skb);
+	adapter->stats.no_rcv++;
+	adapter->stats.rxbytes += length;
 
-		adapter->stats.no_rcv++;
-		adapter->stats.rxbytes += length;
-	}
+	return buffer;
 }
 
-/* Process Receive status ring */
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
+#define netxen_merge_rx_buffers(list, head) \
+	do { list_splice_tail_init(list, head); } while (0);
+
+int
+netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 {
-	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
-	struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
-	struct status_desc *desc, *frag_desc;
-	u32 consumer = recv_ctx->status_rx_consumer;
-	int count = 0, ring;
+	struct netxen_adapter *adapter = sds_ring->adapter;
+
+	struct list_head *cur;
+
+	struct status_desc *desc;
+	struct netxen_rx_buffer *rxbuf;
+
+	u32 consumer = sds_ring->consumer;
+
+	int count = 0;
 	u64 sts_data;
-	u16 opcode;
+	int opcode, ring, index, length, cksum, pkt_offset;
 
 	while (count < max) {
-		desc = &desc_head[consumer];
-		if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
-			DPRINTK(ERR, "desc %p ownedby %x\n", desc,
-				netxen_get_sts_owner(desc));
+		desc = &sds_ring->desc_head[consumer];
+		sts_data = le64_to_cpu(desc->status_desc_data);
+
+		if (!(sts_data & STATUS_OWNER_HOST))
 			break;
-		}
 
-		sts_data = le64_to_cpu(desc->status_desc_data);
+		ring   = netxen_get_sts_type(sts_data);
+		if (ring > RCV_RING_JUMBO)
+			continue;
+
 		opcode = netxen_get_sts_opcode(sts_data);
-		frag_desc = NULL;
-		if (opcode == NETXEN_NIC_RXPKT_DESC) {
-			if (desc->nr_frags) {
-				consumer = get_next_index(consumer,
-						adapter->max_rx_desc_count);
-				frag_desc = &desc_head[consumer];
-				netxen_set_sts_owner(frag_desc,
-						STATUS_OWNER_PHANTOM);
-			}
-		}
 
-		netxen_process_rcv(adapter, ctxid, desc, frag_desc);
+		index  = netxen_get_sts_refhandle(sts_data);
+		length = netxen_get_sts_totallength(sts_data);
+		cksum  = netxen_get_sts_status(sts_data);
+		pkt_offset = netxen_get_sts_pkt_offset(sts_data);
 
-		netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
+		rxbuf = netxen_process_rcv(adapter, ring, index,
+				length, cksum, pkt_offset);
 
-		consumer = get_next_index(consumer,
-				adapter->max_rx_desc_count);
+		if (rxbuf)
+			list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
+
+		desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
+
+		consumer = get_next_index(consumer, sds_ring->num_desc);
 		count++;
 	}
-	for (ring = 0; ring < adapter->max_rds_rings; ring++)
-		netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
 
-	/* update the consumer index in phantom */
-	if (count) {
-		recv_ctx->status_rx_consumer = consumer;
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		struct nx_host_rds_ring *rds_ring =
+			&adapter->recv_ctx.rds_rings[ring];
 
-		/* Window = 1 */
+		if (!list_empty(&sds_ring->free_list[ring])) {
+			list_for_each(cur, &sds_ring->free_list[ring]) {
+				rxbuf = list_entry(cur,
+						struct netxen_rx_buffer, list);
+				netxen_alloc_rx_skb(adapter, rds_ring, rxbuf);
+			}
+			spin_lock(&rds_ring->lock);
+			netxen_merge_rx_buffers(&sds_ring->free_list[ring],
+						&rds_ring->free_list);
+			spin_unlock(&rds_ring->lock);
+		}
+
+		netxen_post_rx_buffers_nodb(adapter, rds_ring);
+	}
+
+	if (count) {
+		sds_ring->consumer = consumer;
 		adapter->pci_write_normalize(adapter,
-				recv_ctx->crb_sts_consumer, consumer);
+				sds_ring->crb_sts_consumer, consumer);
 	}
 
 	return count;
@@ -1366,7 +998,11 @@ int netxen_process_cmd_ring(struct netxe
 	struct netxen_skb_frag *frag;
 	int done = 0;
 
+	if (!spin_trylock(&adapter->tx_clean_lock))
+		return 1;
+
 	last_consumer = adapter->last_cmd_consumer;
+	barrier(); /* cmd_consumer can change underneath */
 	consumer = le32_to_cpu(*(adapter->cmd_consumer));
 
 	while (last_consumer != consumer) {
@@ -1389,7 +1025,7 @@ int netxen_process_cmd_ring(struct netxe
 		}
 
 		last_consumer = get_next_index(last_consumer,
-					       adapter->max_tx_desc_count);
+					       adapter->num_txd);
 		if (++count >= MAX_STATUS_HANDLE)
 			break;
 	}
@@ -1417,75 +1053,55 @@ int netxen_process_cmd_ring(struct netxe
 	 * There is still a possible race condition and the host could miss an
 	 * interrupt. The card has to take care of this.
 	 */
+	barrier(); /* cmd_consumer can change underneath */
 	consumer = le32_to_cpu(*(adapter->cmd_consumer));
 	done = (last_consumer == consumer);
+	spin_unlock(&adapter->tx_clean_lock);
 
 	return (done);
 }
 
-/*
- * netxen_post_rx_buffers puts buffer in the Phantom memory
- */
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
+void
+netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+	struct nx_host_rds_ring *rds_ring)
 {
-	struct pci_dev *pdev = adapter->pdev;
-	struct sk_buff *skb;
-	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
-	struct nx_host_rds_ring *rds_ring = NULL;
-	uint producer;
 	struct rcv_desc *pdesc;
 	struct netxen_rx_buffer *buffer;
-	int count = 0;
+	int producer, count = 0;
 	netxen_ctx_msg msg = 0;
-	dma_addr_t dma;
 	struct list_head *head;
 
-	rds_ring = &recv_ctx->rds_rings[ringid];
-
 	producer = rds_ring->producer;
-	head = &rds_ring->free_list;
 
-	/* We can start writing rx descriptors into the phantom memory. */
+	spin_lock(&rds_ring->lock);
+	head = &rds_ring->free_list;
 	while (!list_empty(head)) {
 
-		skb = dev_alloc_skb(rds_ring->skb_size);
-		if (unlikely(!skb)) {
-			break;
-		}
-
-		if (!adapter->ahw.cut_through)
-			skb_reserve(skb, 2);
+		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 
-		dma = pci_map_single(pdev, skb->data,
-				rds_ring->dma_size, PCI_DMA_FROMDEVICE);
-		if (pci_dma_mapping_error(pdev, dma)) {
-			dev_kfree_skb_any(skb);
-			break;
+		if (!buffer->skb) {
+			if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+				break;
 		}
 
 		count++;
-		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 		list_del(&buffer->list);
 
-		buffer->skb = skb;
-		buffer->state = NETXEN_BUFFER_BUSY;
-		buffer->dma = dma;
-
 		/* make a rcv descriptor  */
 		pdesc = &rds_ring->desc_head[producer];
-		pdesc->addr_buffer = cpu_to_le64(dma);
+		pdesc->addr_buffer = cpu_to_le64(buffer->dma);
 		pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
 		pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
 
-		producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+		producer = get_next_index(producer, rds_ring->num_desc);
 	}
-	/* if we did allocate buffers, then write the count to Phantom */
+	spin_unlock(&rds_ring->lock);
+
 	if (count) {
 		rds_ring->producer = producer;
-			/* Window = 1 */
 		adapter->pci_write_normalize(adapter,
 				rds_ring->crb_rcv_producer,
-				(producer-1) & (rds_ring->max_rx_desc_count-1));
+				(producer-1) & (rds_ring->num_desc-1));
 
 		if (adapter->fw_major < 4) {
 			/*
@@ -1496,9 +1112,8 @@ void netxen_post_rx_buffers(struct netxe
 			netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
 			netxen_set_msg_privid(msg);
 			netxen_set_msg_count(msg,
-					     ((producer -
-					       1) & (rds_ring->
-						     max_rx_desc_count - 1)));
+					     ((producer - 1) &
+					      (rds_ring->num_desc - 1)));
 			netxen_set_msg_ctxid(msg, adapter->portnum);
 			netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
 			writel(msg,
@@ -1508,68 +1123,49 @@ void netxen_post_rx_buffers(struct netxe
 	}
 }
 
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
-					uint32_t ctx, uint32_t ringid)
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+		struct nx_host_rds_ring *rds_ring)
 {
-	struct pci_dev *pdev = adapter->pdev;
-	struct sk_buff *skb;
-	struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
-	struct nx_host_rds_ring *rds_ring = NULL;
-	u32 producer;
 	struct rcv_desc *pdesc;
 	struct netxen_rx_buffer *buffer;
-	int count = 0;
+	int producer, count = 0;
 	struct list_head *head;
-	dma_addr_t dma;
-
-	rds_ring = &recv_ctx->rds_rings[ringid];
 
 	producer = rds_ring->producer;
+	if (!spin_trylock(&rds_ring->lock))
+		return;
+
 	head = &rds_ring->free_list;
-	/* We can start writing rx descriptors into the phantom memory. */
 	while (!list_empty(head)) {
 
-		skb = dev_alloc_skb(rds_ring->skb_size);
-		if (unlikely(!skb)) {
-			break;
-		}
-
-		if (!adapter->ahw.cut_through)
-			skb_reserve(skb, 2);
+		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 
-		dma = pci_map_single(pdev, skb->data,
-				rds_ring->dma_size, PCI_DMA_FROMDEVICE);
-		if (pci_dma_mapping_error(pdev, dma)) {
-			dev_kfree_skb_any(skb);
-			break;
+		if (!buffer->skb) {
+			if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+				break;
 		}
 
 		count++;
-		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 		list_del(&buffer->list);
 
-		buffer->skb = skb;
-		buffer->state = NETXEN_BUFFER_BUSY;
-		buffer->dma = dma;
-
 		/* make a rcv descriptor  */
 		pdesc = &rds_ring->desc_head[producer];
 		pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
 		pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
 		pdesc->addr_buffer = cpu_to_le64(buffer->dma);
 
-		producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+		producer = get_next_index(producer, rds_ring->num_desc);
 	}
 
-	/* if we did allocate buffers, then write the count to Phantom */
 	if (count) {
 		rds_ring->producer = producer;
-			/* Window = 1 */
 		adapter->pci_write_normalize(adapter,
 			rds_ring->crb_rcv_producer,
-				(producer-1) & (rds_ring->max_rx_desc_count-1));
+				(producer - 1) & (rds_ring->num_desc - 1));
 			wmb();
 	}
+	spin_unlock(&rds_ring->lock);
 }
 
 void netxen_nic_clear_stats(struct netxen_adapter *adapter)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_main.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- *  Main source file for NetXen NIC Driver on Linux
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -97,20 +94,6 @@ static struct pci_device_id netxen_pci_t
 
 MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
 
-/*
- * In netxen_nic_down(), we must wait for any pending callback requests into
- * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be
- * reenabled right after it is deleted in netxen_nic_down().
- * FLUSH_SCHEDULED_WORK()  does this synchronization.
- *
- * Normally, schedule_work()/flush_scheduled_work() could have worked, but
- * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off()
- * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a
- * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause
- * linkwatch_event() to be executed which also attempts to acquire the rtnl
- * lock thus causing a deadlock.
- */
-
 static struct workqueue_struct *netxen_workq;
 #define SCHEDULE_WORK(tp)	queue_work(netxen_workq, tp)
 #define FLUSH_SCHEDULED_WORK()	flush_workqueue(netxen_workq)
@@ -152,130 +135,148 @@ static uint32_t msi_tgt_status[8] = {
 
 static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
 {
-	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
+	struct netxen_adapter *adapter = sds_ring->adapter;
+
+	adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
 }
 
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
 {
-	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
+	struct netxen_adapter *adapter = sds_ring->adapter;
+
+	adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
 
 	if (!NETXEN_IS_MSI_FAMILY(adapter))
 		adapter->pci_write_immediate(adapter,
 				adapter->legacy_intr.tgt_mask_reg, 0xfbff);
 }
 
+static void
+netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	int ring;
+	struct nx_host_sds_ring *sds_ring;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+		adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
+	else
+		adapter->max_sds_rings = 1;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		netif_napi_add(netdev, &sds_ring->napi,
+				netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+	}
+}
+
+static void
+netxen_napi_enable(struct netxen_adapter *adapter)
+{
+	int ring;
+	struct nx_host_sds_ring *sds_ring;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		napi_enable(&sds_ring->napi);
+		netxen_nic_enable_int(sds_ring);
+	}
+}
+
+static void
+netxen_napi_disable(struct netxen_adapter *adapter)
+{
+	int ring;
+	struct nx_host_sds_ring *sds_ring;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		netxen_nic_disable_int(sds_ring);
+		napi_disable(&sds_ring->napi);
+	}
+}
+
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
 {
 	struct pci_dev *pdev = adapter->pdev;
-	int err;
-	uint64_t mask;
+	uint64_t mask, cmask;
 
-#ifdef CONFIG_IA64
-	adapter->dma_mask = DMA_32BIT_MASK;
-#else
-	if (revision_id >= NX_P3_B0) {
-		/* should go to DMA_64BIT_MASK */
-		adapter->dma_mask = DMA_39BIT_MASK;
-		mask = DMA_39BIT_MASK;
-	} else if (revision_id == NX_P3_A2) {
-		adapter->dma_mask = DMA_39BIT_MASK;
-		mask = DMA_39BIT_MASK;
-	} else if (revision_id == NX_P2_C1) {
-		adapter->dma_mask = DMA_35BIT_MASK;
-		mask = DMA_35BIT_MASK;
-	} else {
-		adapter->dma_mask = DMA_32BIT_MASK;
-		mask = DMA_32BIT_MASK;
-		goto set_32_bit_mask;
-	}
+	adapter->pci_using_dac = 0;
 
+	mask = DMA_BIT_MASK(32);
 	/*
 	 * Consistent DMA mask is set to 32 bit because it cannot be set to
 	 * 35 bits. For P3 also leave it at 32 bits for now. Only the rings
 	 * come off this pool.
 	 */
+	cmask = DMA_BIT_MASK(32);
+
+#ifndef CONFIG_IA64
+	if (revision_id >= NX_P3_B0)
+		mask = DMA_BIT_MASK(39);
+	else if (revision_id == NX_P2_C1)
+		mask = DMA_BIT_MASK(35);
+#endif
 	if (pci_set_dma_mask(pdev, mask) == 0 &&
-		pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) {
+		pci_set_consistent_dma_mask(pdev, cmask) == 0) {
 		adapter->pci_using_dac = 1;
 		return 0;
 	}
-set_32_bit_mask:
-#endif /* CONFIG_IA64 */
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-	if (!err)
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-	if (err) {
-		DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err);
-		return err;
+	return -EIO;
+}
+
+/* Update addressable range if firmware supports it */
+static int
+nx_update_dma_mask(struct netxen_adapter *adapter)
+{
+	int change, shift, err;
+	uint64_t mask, old_mask;
+	struct pci_dev *pdev = adapter->pdev;
+
+	change = 0;
+
+	shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+	if (shift >= 32)
+		return 0;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9))
+		change = 1;
+	else if ((adapter->ahw.revision_id == NX_P2_C1) && (shift <= 4))
+		change = 1;
+
+	if (change) {
+		old_mask = pdev->dma_mask;
+		mask = (1ULL<<(32+shift)) - 1;
+
+		err = pci_set_dma_mask(pdev, mask);
+		if (err)
+			return pci_set_dma_mask(pdev, old_mask);
 	}
 
-	adapter->pci_using_dac = 0;
 	return 0;
 }
 
 static void netxen_check_options(struct netxen_adapter *adapter)
 {
-	switch (adapter->ahw.boardcfg.board_type) {
-	case NETXEN_BRDTYPE_P3_HMEZ:
-	case NETXEN_BRDTYPE_P3_XG_LOM:
-	case NETXEN_BRDTYPE_P3_10G_CX4:
-	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
-	case NETXEN_BRDTYPE_P3_IMEZ:
-	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
-	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
-	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
-	case NETXEN_BRDTYPE_P3_10G_XFP:
-	case NETXEN_BRDTYPE_P3_10000_BASE_T:
-		adapter->msix_supported = !!use_msi_x;
-		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
-		break;
-
-	case NETXEN_BRDTYPE_P2_SB31_10G:
-	case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
-	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
-	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
-		adapter->msix_supported = 0;
-		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
-		break;
-
-	case NETXEN_BRDTYPE_P3_REF_QG:
-	case NETXEN_BRDTYPE_P3_4_GB:
-	case NETXEN_BRDTYPE_P3_4_GB_MM:
-		adapter->msix_supported = !!use_msi_x;
-		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-		break;
-
-	case NETXEN_BRDTYPE_P2_SB35_4G:
-	case NETXEN_BRDTYPE_P2_SB31_2G:
-		adapter->msix_supported = 0;
-		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-		break;
+	if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+		adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
+	else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+		adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
 
-	case NETXEN_BRDTYPE_P3_10G_TP:
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		adapter->msix_supported = !!use_msi_x;
-		if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
-			adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
-		else
-			adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-		break;
-
-	default:
+	else
 		adapter->msix_supported = 0;
-		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-
-		printk(KERN_WARNING "Unknown board type(0x%x)\n",
-				adapter->ahw.boardcfg.board_type);
-		break;
-	}
 
-	adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
-	adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
-	adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
+	adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
+	adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
+	adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
 
-	adapter->max_possible_rss_rings = 1;
 	return;
 }
 
@@ -336,7 +337,7 @@ static void netxen_set_port_mode(struct
 {
 	u32 val, data;
 
-	val = adapter->ahw.boardcfg.board_type;
+	val = adapter->ahw.board_type;
 	if ((val == NETXEN_BRDTYPE_P3_HMEZ) ||
 		(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
 		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -454,91 +455,91 @@ static const struct net_device_ops netxe
 #endif
 };
 
-/*
- * netxen_nic_probe()
- *
- * The Linux system will invoke this after identifying the vendor ID and
- * device Id in the pci_tbl supported by this module.
- *
- * A quad port card has one operational PCI config space, (function 0),
- * which is used to access all four ports.
- *
- * This routine will initialize the adapter, and setup the global parameters
- * along with the port's specific structure.
- */
-static int __devinit
-netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void
+netxen_setup_intr(struct netxen_adapter *adapter)
 {
-	struct net_device *netdev = NULL;
-	struct netxen_adapter *adapter = NULL;
-	void __iomem *mem_ptr0 = NULL;
-	void __iomem *mem_ptr1 = NULL;
-	void __iomem *mem_ptr2 = NULL;
-	unsigned long first_page_group_end;
-	unsigned long first_page_group_start;
+	struct netxen_legacy_intr_set *legacy_intrp;
+	struct pci_dev *pdev = adapter->pdev;
 
+	adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+	adapter->intr_scheme = -1;
+	adapter->msi_mode = -1;
 
-	u8 __iomem *db_ptr = NULL;
-	unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
-	int i = 0, err;
-	int first_driver, first_boot;
-	u32 val;
-	int pci_func_id = PCI_FUNC(pdev->devfn);
-	struct netxen_legacy_intr_set *legacy_intrp;
-	uint8_t revision_id;
+	if (adapter->ahw.revision_id >= NX_P3_B0)
+		legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
+	else
+		legacy_intrp = &legacy_intr[0];
+	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
+	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
+	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
 
-	if (pci_func_id == 0)
-		printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+	netxen_set_msix_bit(pdev, 0);
 
-	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 (adapter->msix_supported) {
 
-	if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
-		printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
-				"will not be enabled.\n",
-				NX_P3_A0, NX_P3_B1);
-		return -ENODEV;
-	}
+		netxen_init_msix_entries(adapter);
+		if (pci_enable_msix(pdev, adapter->msix_entries,
+					MSIX_ENTRIES_PER_ADAPTER))
+			goto request_msi;
 
-	if ((err = pci_enable_device(pdev)))
-		return err;
+		adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+		netxen_set_msix_bit(pdev, 1);
+		dev_info(&pdev->dev, "using msi-x interrupts\n");
 
-	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		err = -ENODEV;
-		goto err_out_disable_pdev;
+	} else {
+request_msi:
+		if (use_msi && !pci_enable_msi(pdev)) {
+			adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+			dev_info(&pdev->dev, "using msi interrupts\n");
+		} else
+			dev_info(&pdev->dev, "using legacy interrupts\n");
+		adapter->msix_entries[0].vector = pdev->irq;
 	}
+}
 
-	if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
-		goto err_out_disable_pdev;
-
-	pci_set_master(pdev);
+static void
+netxen_teardown_intr(struct netxen_adapter *adapter)
+{
+	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+		pci_disable_msix(adapter->pdev);
+	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+		pci_disable_msi(adapter->pdev);
+}
 
-	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
-	if(!netdev) {
-		printk(KERN_ERR"%s: Failed to allocate memory for the "
-				"device block.Check system memory resource"
-				" usage.\n", netxen_nic_driver_name);
-		goto err_out_free_res;
-	}
+static void
+netxen_cleanup_pci_map(struct netxen_adapter *adapter)
+{
+	if (adapter->ahw.db_base != NULL)
+		iounmap(adapter->ahw.db_base);
+	if (adapter->ahw.pci_base0 != NULL)
+		iounmap(adapter->ahw.pci_base0);
+	if (adapter->ahw.pci_base1 != NULL)
+		iounmap(adapter->ahw.pci_base1);
+	if (adapter->ahw.pci_base2 != NULL)
+		iounmap(adapter->ahw.pci_base2);
+}
 
-	SET_NETDEV_DEV(netdev, &pdev->dev);
+static int
+netxen_setup_pci_map(struct netxen_adapter *adapter)
+{
+	void __iomem *mem_ptr0 = NULL;
+	void __iomem *mem_ptr1 = NULL;
+	void __iomem *mem_ptr2 = NULL;
+	void __iomem *db_ptr = NULL;
 
-	adapter = netdev_priv(netdev);
-	adapter->netdev  = netdev;
-	adapter->pdev    = pdev;
-	adapter->ahw.pci_func  = pci_func_id;
+	unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
 
-	revision_id = pdev->revision;
-	adapter->ahw.revision_id = revision_id;
+	struct pci_dev *pdev = adapter->pdev;
+	int pci_func = adapter->ahw.pci_func;
 
-	err = nx_set_dma_mask(adapter, revision_id);
-	if (err)
-		goto err_out_free_netdev;
+	int err = 0;
 
-	rwlock_init(&adapter->adapter_lock);
+	/*
+	 * 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;
 
@@ -564,14 +565,10 @@ netxen_nic_probe(struct pci_dev *pdev, c
 				SECOND_PAGE_GROUP_SIZE);
 		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
 				THIRD_PAGE_GROUP_SIZE);
-		first_page_group_start = FIRST_PAGE_GROUP_START;
-		first_page_group_end   = FIRST_PAGE_GROUP_END;
 	} 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 -
 			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
-		first_page_group_start = 0;
-		first_page_group_end   = 0;
 	} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
 		adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
 		adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
@@ -590,29 +587,33 @@ netxen_nic_probe(struct pci_dev *pdev, c
 			dev_err(&pdev->dev, "failed to map PCI bar 0\n");
 			return -EIO;
 		}
-
 		pci_len0 = mem_len;
-		first_page_group_start = 0;
-		first_page_group_end   = 0;
 
 		adapter->ahw.ddr_mn_window = 0;
 		adapter->ahw.qdr_sn_window = 0;
 
 		adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
-			(pci_func_id * 0x20);
+			(pci_func * 0x20);
 		adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
-		if (pci_func_id < 4)
-			adapter->ahw.ms_win_crb += (pci_func_id * 0x20);
+		if (pci_func < 4)
+			adapter->ahw.ms_win_crb += (pci_func * 0x20);
 		else
 			adapter->ahw.ms_win_crb +=
-					0xA0 + ((pci_func_id - 4) * 0x10);
+					0xA0 + ((pci_func - 4) * 0x10);
 	} else {
-		err = -EIO;
-		goto err_out_free_netdev;
+		return -EIO;
 	}
 
 	dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
+	adapter->ahw.pci_base0 = mem_ptr0;
+	adapter->ahw.pci_len0 = pci_len0;
+	adapter->ahw.pci_base1 = mem_ptr1;
+	adapter->ahw.pci_base2 = mem_ptr2;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		goto skip_doorbell;
+
 	db_base = pci_resource_start(pdev, 4);	/* doorbell is on bar 4 */
 	db_len = pci_resource_len(pdev, 4);
 
@@ -620,49 +621,349 @@ netxen_nic_probe(struct pci_dev *pdev, c
 		printk(KERN_ERR "%s: doorbell is disabled\n",
 				netxen_nic_driver_name);
 		err = -EIO;
-		goto err_out_iounmap;
+		goto err_out;
 	}
-	DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
-		db_len);
 
 	db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
 	if (!db_ptr) {
 		printk(KERN_ERR "%s: Failed to allocate doorbell map.",
 				netxen_nic_driver_name);
 		err = -EIO;
-		goto err_out_iounmap;
+		goto err_out;
 	}
-	DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
 
-	adapter->ahw.pci_base0 = mem_ptr0;
-	adapter->ahw.pci_len0 = pci_len0;
-	adapter->ahw.first_page_group_start = first_page_group_start;
-	adapter->ahw.first_page_group_end   = first_page_group_end;
-	adapter->ahw.pci_base1 = mem_ptr1;
-	adapter->ahw.pci_base2 = mem_ptr2;
+skip_doorbell:
 	adapter->ahw.db_base = db_ptr;
 	adapter->ahw.db_len = db_len;
+	return 0;
 
-	netif_napi_add(netdev, &adapter->napi,
-			netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+err_out:
+	netxen_cleanup_pci_map(adapter);
+	return err;
+}
 
-	if (revision_id >= NX_P3_B0)
-		legacy_intrp = &legacy_intr[pci_func_id];
+static int
+netxen_start_firmware(struct netxen_adapter *adapter)
+{
+	int val, err, first_boot;
+	struct pci_dev *pdev = adapter->pdev;
+
+	int first_driver = 0;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (adapter->ahw.pci_func == 0)
+			first_driver = 1;
+	} else {
+		if (adapter->portnum == 0)
+			first_driver = 1;
+	}
+
+	if (!first_driver)
+		return 0;
+
+	first_boot = adapter->pci_read_normalize(adapter,
+			NETXEN_CAM_RAM(0x1fc));
+
+	err = netxen_check_hw_init(adapter, first_boot);
+	if (err) {
+		dev_err(&pdev->dev, "error in init HW init sequence\n");
+		return err;
+	}
+
+	if (first_boot != 0x55555555) {
+		adapter->pci_write_normalize(adapter,
+					CRB_CMDPEG_STATE, 0);
+		netxen_pinit_from_rom(adapter, 0);
+		msleep(1);
+	}
+
+	netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		netxen_set_port_mode(adapter);
+
+	netxen_load_firmware(adapter);
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+
+		/* Initialize multicast addr pool owners */
+		val = 0x7654;
+		if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+			val |= 0x0f000000;
+		netxen_crb_writelit_adapter(adapter,
+				NETXEN_MAC_ADDR_CNTL_REG, val);
+
+	}
+
+	err = netxen_initialize_adapter_offload(adapter);
+	if (err)
+		return err;
+
+	/*
+	 * Tell the hardware our version number.
+	 */
+	val = (_NETXEN_NIC_LINUX_MAJOR << 16)
+		| ((_NETXEN_NIC_LINUX_MINOR << 8))
+		| (_NETXEN_NIC_LINUX_SUBVERSION);
+	adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+
+	/* Handshake with the card before we register the devices. */
+	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+	if (err) {
+		netxen_free_adapter_offload(adapter);
+		return err;
+	}
+
+	return 0;
+}
+
+static int
+netxen_nic_request_irq(struct netxen_adapter *adapter)
+{
+	irq_handler_t handler;
+	struct nx_host_sds_ring *sds_ring;
+	int err, ring;
+
+	unsigned long flags = IRQF_SAMPLE_RANDOM;
+	struct net_device *netdev = adapter->netdev;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
+		(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
+		printk(KERN_ERR "%s: Firmware interrupt scheme is "
+				"incompatible with driver\n",
+				netdev->name);
+		adapter->driver_mismatch = 1;
+		return -EINVAL;
+	}
+
+	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+		handler = netxen_msix_intr;
+	else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+		handler = netxen_msi_intr;
+	else {
+		flags |= IRQF_SHARED;
+		handler = netxen_intr;
+	}
+	adapter->irq = netdev->irq;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+		err = request_irq(sds_ring->irq, handler,
+				  flags, sds_ring->name, sds_ring);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static void
+netxen_nic_free_irq(struct netxen_adapter *adapter)
+{
+	int ring;
+	struct nx_host_sds_ring *sds_ring;
+
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+		sds_ring = &recv_ctx->sds_rings[ring];
+		free_irq(sds_ring->irq, sds_ring);
+	}
+}
+
+static int
+netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	int err;
+
+	err = adapter->init_port(adapter, adapter->physical_port);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to initialize port %d\n",
+				netxen_nic_driver_name, adapter->portnum);
+		return err;
+	}
+	adapter->macaddr_set(adapter, netdev->dev_addr);
+
+	netxen_nic_set_link_parameters(adapter);
+
+	netxen_set_multicast_list(netdev);
+	if (adapter->set_mtu)
+		adapter->set_mtu(adapter, netdev->mtu);
+
+	adapter->ahw.linkup = 0;
+	mod_timer(&adapter->watchdog_timer, jiffies);
+
+	netxen_napi_enable(adapter);
+
+	if (adapter->max_sds_rings > 1)
+		netxen_config_rss(adapter, 1);
+
+	return 0;
+}
+
+static void
+netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+	netxen_napi_disable(adapter);
+
+	if (adapter->stop_port)
+		adapter->stop_port(adapter);
+
+	netxen_release_tx_buffers(adapter);
+
+	FLUSH_SCHEDULED_WORK();
+	del_timer_sync(&adapter->watchdog_timer);
+}
+
+
+static int
+netxen_nic_attach(struct netxen_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	int err, ring;
+	struct nx_host_rds_ring *rds_ring;
+
+	err = netxen_init_firmware(adapter);
+	if (err != 0) {
+		printk(KERN_ERR "Failed to init firmware\n");
+		return -EIO;
+	}
+
+	if (adapter->fw_major < 4)
+		adapter->max_rds_rings = 3;
 	else
-		legacy_intrp = &legacy_intr[0];
+		adapter->max_rds_rings = 2;
 
-	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
-	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
-	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
-	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+	err = netxen_alloc_sw_resources(adapter);
+	if (err) {
+		printk(KERN_ERR "%s: Error in setting sw resources\n",
+				netdev->name);
+		return err;
+	}
 
-	/* this will be read from FW later */
-	adapter->intr_scheme = -1;
-	adapter->msi_mode = -1;
+	netxen_nic_clear_stats(adapter);
+
+	err = netxen_alloc_hw_resources(adapter);
+	if (err) {
+		printk(KERN_ERR "%s: Error in setting hw resources\n",
+				netdev->name);
+		goto err_out_free_sw;
+	}
+
+	if (adapter->fw_major < 4) {
+		adapter->crb_addr_cmd_producer =
+			crb_cmd_producer[adapter->portnum];
+		adapter->crb_addr_cmd_consumer =
+			crb_cmd_consumer[adapter->portnum];
+
+		netxen_nic_update_cmd_producer(adapter, 0);
+		netxen_nic_update_cmd_consumer(adapter, 0);
+	}
+
+	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+		rds_ring = &adapter->recv_ctx.rds_rings[ring];
+		netxen_post_rx_buffers(adapter, ring, rds_ring);
+	}
+
+	err = netxen_nic_request_irq(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "%s: failed to setup interrupt\n",
+				netdev->name);
+		goto err_out_free_rxbuf;
+	}
+
+	adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+	return 0;
+
+err_out_free_rxbuf:
+	netxen_release_rx_buffers(adapter);
+	netxen_free_hw_resources(adapter);
+err_out_free_sw:
+	netxen_free_sw_resources(adapter);
+	return err;
+}
+
+static void
+netxen_nic_detach(struct netxen_adapter *adapter)
+{
+	netxen_nic_free_irq(adapter);
+
+	netxen_release_rx_buffers(adapter);
+	netxen_free_hw_resources(adapter);
+	netxen_free_sw_resources(adapter);
+
+	adapter->is_up = 0;
+}
+
+static int __devinit
+netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct net_device *netdev = NULL;
+	struct netxen_adapter *adapter = NULL;
+	int i = 0, err;
+	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"
+				"will not be enabled.\n",
+				NX_P3_A0, NX_P3_B1);
+		return -ENODEV;
+	}
+
+	if ((err = pci_enable_device(pdev)))
+		return err;
+
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+		err = -ENODEV;
+		goto err_out_disable_pdev;
+	}
+
+	if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
+		goto err_out_disable_pdev;
+
+	pci_set_master(pdev);
+
+	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
+	if(!netdev) {
+		printk(KERN_ERR"%s: Failed to allocate memory for the "
+				"device block.Check system memory resource"
+				" usage.\n", netxen_nic_driver_name);
+		goto err_out_free_res;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	adapter = netdev_priv(netdev);
+	adapter->netdev  = netdev;
+	adapter->pdev    = pdev;
+	adapter->ahw.pci_func  = pci_func_id;
+
+	revision_id = pdev->revision;
+	adapter->ahw.revision_id = revision_id;
+
+	err = nx_set_dma_mask(adapter, revision_id);
+	if (err)
+		goto err_out_free_netdev;
+
+	rwlock_init(&adapter->adapter_lock);
+	spin_lock_init(&adapter->tx_clean_lock);
+
+	err = netxen_setup_pci_map(adapter);
+	if (err)
+		goto err_out_free_netdev;
 
 	/* This will be reset for mezz cards  */
 	adapter->portnum = pci_func_id;
-	adapter->status   &= ~NETXEN_NETDEV_STATUS;
 	adapter->rx_csum = 1;
 	adapter->mc_enabled = 0;
 	if (NX_IS_REVISION_P3(revision_id))
@@ -690,12 +991,6 @@ netxen_nic_probe(struct pci_dev *pdev, c
 		netdev->vlan_features |= NETIF_F_HIGHDMA;
 	}
 
-	/*
-	 * 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;
-
 	if (netxen_nic_get_board_info(adapter) != 0) {
 		printk("%s: Error getting board config info.\n",
 				netxen_nic_driver_name);
@@ -706,7 +1001,7 @@ netxen_nic_probe(struct pci_dev *pdev, c
 	netxen_initialize_adapter_ops(adapter);
 
 	/* Mezz cards have PCI function 0,2,3 enabled */
-	switch (adapter->ahw.boardcfg.board_type) {
+	switch (adapter->ahw.board_type) {
 	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
 	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
 		if (pci_func_id >= 2)
@@ -716,82 +1011,13 @@ netxen_nic_probe(struct pci_dev *pdev, c
 		break;
 	}
 
-	/*
-	 * This call will setup various max rx/tx counts.
-	 * It must be done before any buffer/ring allocations.
-	 */
-	netxen_check_options(adapter);
-
-	first_driver = 0;
-	if (NX_IS_REVISION_P3(revision_id)) {
-		if (adapter->ahw.pci_func == 0)
-			first_driver = 1;
-	} else {
-		if (adapter->portnum == 0)
-			first_driver = 1;
-	}
-
-	if (first_driver) {
-		first_boot = adapter->pci_read_normalize(adapter,
-				NETXEN_CAM_RAM(0x1fc));
-
-		err = netxen_check_hw_init(adapter, first_boot);
-		if (err) {
-			printk(KERN_ERR "%s: error in init HW init sequence\n",
-					netxen_nic_driver_name);
-			goto err_out_iounmap;
-		}
-
-		if (NX_IS_REVISION_P3(revision_id))
-			netxen_set_port_mode(adapter);
-
-		if (first_boot != 0x55555555) {
-			adapter->pci_write_normalize(adapter,
-						CRB_CMDPEG_STATE, 0);
-			netxen_pinit_from_rom(adapter, 0);
-			msleep(1);
-		}
-		netxen_load_firmware(adapter);
-
-		if (NX_IS_REVISION_P2(revision_id)) {
-
-			/* Initialize multicast addr pool owners */
-			val = 0x7654;
-			if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
-				val |= 0x0f000000;
-			netxen_crb_writelit_adapter(adapter,
-					NETXEN_MAC_ADDR_CNTL_REG, val);
-
-		}
-
-		err = netxen_initialize_adapter_offload(adapter);
-		if (err)
-			goto err_out_iounmap;
-
-		/*
-		 * Tell the hardware our version number.
-		 */
-		i = (_NETXEN_NIC_LINUX_MAJOR << 16)
-			| ((_NETXEN_NIC_LINUX_MINOR << 8))
-			| (_NETXEN_NIC_LINUX_SUBVERSION);
-		adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
-
-		/* Handshake with the card before we register the devices. */
-		err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
-		if (err)
-			goto err_out_free_offload;
-
-	}	/* first_driver */
+	err = netxen_start_firmware(adapter);
+	if (err)
+		goto err_out_iounmap;
 
-	netxen_nic_flash_print(adapter);
+	nx_update_dma_mask(adapter);
 
-	if (NX_IS_REVISION_P3(revision_id)) {
-		adapter->hw_read_wx(adapter,
-				NETXEN_MIU_MN_CONTROL, &val, 4);
-		adapter->ahw.cut_through = (val & 0x4) ? 1 : 0;
-		dev_info(&pdev->dev, "firmware running in %s mode\n",
-		adapter->ahw.cut_through ? "cut through" : "legacy");
-	}
+	netxen_nic_get_firmware_info(adapter);
 
 	/*
 	 * See if the firmware gave us a virtual-physical port mapping.
@@ -804,41 +1030,13 @@ netxen_nic_probe(struct pci_dev *pdev, c
 			adapter->physical_port = i;
 	}
 
-	adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
-
-	netxen_set_msix_bit(pdev, 0);
-
-	if (NX_IS_REVISION_P3(revision_id)) {
-		if ((mem_len != NETXEN_PCI_128MB_SIZE) &&
-			mem_len != NETXEN_PCI_2MB_SIZE)
-			adapter->msix_supported = 0;
-	}
-
-	if (adapter->msix_supported) {
-
-		netxen_init_msix_entries(adapter);
-
-		if (pci_enable_msix(pdev, adapter->msix_entries,
-					MSIX_ENTRIES_PER_ADAPTER))
-			goto request_msi;
+	netxen_check_options(adapter);
 
-		adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
-		netxen_set_msix_bit(pdev, 1);
-		dev_info(&pdev->dev, "using msi-x interrupts\n");
+	netxen_setup_intr(adapter);
 
-	} else {
-request_msi:
-		if (use_msi && !pci_enable_msi(pdev)) {
-			adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-			dev_info(&pdev->dev, "using msi interrupts\n");
-		} else
-			dev_info(&pdev->dev, "using legacy interrupts\n");
-	}
+	netdev->irq = adapter->msix_entries[0].vector;
 
-	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
-		netdev->irq = adapter->msix_entries[0].vector;
-	else
-		netdev->irq = pdev->irq;
+	netxen_napi_add(adapter, netdev);
 
 	err = netxen_receive_peg_ready(adapter);
 	if (err)
@@ -867,7 +1065,7 @@ request_msi:
 
 	pci_set_drvdata(pdev, adapter);
 
-	switch (adapter->ahw.board_type) {
+	switch (adapter->ahw.port_type) {
 	case NETXEN_NIC_GBE:
 		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
 				adapter->netdev->name);
@@ -881,25 +1079,12 @@ request_msi:
 	return 0;
 
 err_out_disable_msi:
-	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
-		pci_disable_msix(pdev);
-	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
-		pci_disable_msi(pdev);
+	netxen_teardown_intr(adapter);
 
-err_out_free_offload:
-	if (first_driver)
-		netxen_free_adapter_offload(adapter);
+	netxen_free_adapter_offload(adapter);
 
 err_out_iounmap:
-	if (db_ptr)
-		iounmap(db_ptr);
-
-	if (mem_ptr0)
-		iounmap(mem_ptr0);
-	if (mem_ptr1)
-		iounmap(mem_ptr1);
-	if (mem_ptr2)
-		iounmap(mem_ptr2);
+	netxen_cleanup_pci_map(adapter);
 
 err_out_free_netdev:
 	free_netdev(netdev);
@@ -927,9 +1112,7 @@ static void __devexit netxen_nic_remove(
 	unregister_netdev(netdev);
 
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-		netxen_free_hw_resources(adapter);
-		netxen_release_rx_buffers(adapter);
-		netxen_free_sw_resources(adapter);
+		netxen_nic_detach(adapter);
 
 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 			netxen_p3_free_mac_list(adapter);
@@ -938,20 +1121,9 @@ static void __devexit netxen_nic_remove(
 	if (adapter->portnum == 0)
 		netxen_free_adapter_offload(adapter);
 
-	if (adapter->irq)
-		free_irq(adapter->irq, adapter);
-
-	if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
-		pci_disable_msix(pdev);
-	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
-		pci_disable_msi(pdev);
+	netxen_teardown_intr(adapter);
 
-	iounmap(adapter->ahw.db_base);
-	iounmap(adapter->ahw.pci_base0);
-	if (adapter->ahw.pci_base1 != NULL)
-		iounmap(adapter->ahw.pci_base1);
-	if (adapter->ahw.pci_base2 != NULL)
-		iounmap(adapter->ahw.pci_base2);
+	netxen_cleanup_pci_map(adapter);
 
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -960,125 +1132,95 @@ static void __devexit netxen_nic_remove(
 	free_netdev(netdev);
 }
 
-/*
- * Called when a network interface is made active
- * @returns 0 on success, negative value on failure
- */
-static int netxen_nic_open(struct net_device *netdev)
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct netxen_adapter *adapter = netdev_priv(netdev);
-	int err = 0;
-	int ctx, ring;
-	irq_handler_t handler;
-	unsigned long flags = IRQF_SAMPLE_RANDOM;
 
-	if (adapter->driver_mismatch)
-		return -EIO;
+	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
 
-	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
-		err = netxen_init_firmware(adapter);
-		if (err != 0) {
-			printk(KERN_ERR "Failed to init firmware\n");
-			return -EIO;
-		}
+	netif_device_detach(netdev);
 
-		if (adapter->fw_major < 4)
-			adapter->max_rds_rings = 3;
-		else
-			adapter->max_rds_rings = 2;
+	if (netif_running(netdev))
+		netxen_nic_down(adapter, netdev);
 
-		err = netxen_alloc_sw_resources(adapter);
-		if (err) {
-			printk(KERN_ERR "%s: Error in setting sw resources\n",
-					netdev->name);
-			return err;
-		}
+	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+		netxen_nic_detach(adapter);
 
-		netxen_nic_clear_stats(adapter);
+	pci_save_state(pdev);
 
-		err = netxen_alloc_hw_resources(adapter);
-		if (err) {
-			printk(KERN_ERR "%s: Error in setting hw resources\n",
-					netdev->name);
-			goto err_out_free_sw;
-		}
+	if (netxen_nic_wol_supported(adapter)) {
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+	}
 
-		if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
-			(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
-			printk(KERN_ERR "%s: Firmware interrupt scheme is "
-					"incompatible with driver\n",
-					netdev->name);
-			adapter->driver_mismatch = 1;
-			goto err_out_free_hw;
-		}
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
-		if (adapter->fw_major < 4) {
-			adapter->crb_addr_cmd_producer =
-				crb_cmd_producer[adapter->portnum];
-			adapter->crb_addr_cmd_consumer =
-				crb_cmd_consumer[adapter->portnum];
+	return 0;
+}
 
-			netxen_nic_update_cmd_producer(adapter, 0);
-			netxen_nic_update_cmd_consumer(adapter, 0);
-		}
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int err;
 
-		for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-			for (ring = 0; ring < adapter->max_rds_rings; ring++)
-				netxen_post_rx_buffers(adapter, ctx, ring);
-		}
-		if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
-			handler = netxen_msix_intr;
-		else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
-			handler = netxen_msi_intr;
-		else {
-			flags |= IRQF_SHARED;
-			handler = netxen_intr;
-		}
-		adapter->irq = netdev->irq;
-		err = request_irq(adapter->irq, handler,
-				  flags, netdev->name, adapter);
-		if (err) {
-			printk(KERN_ERR "request_irq failed with: %d\n", err);
-			goto err_out_free_rxbuf;
-		}
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
 
-		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
-	}
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
 
-	/* Done here again so that even if phantom sw overwrote it,
-	 * we set it */
-	err = adapter->init_port(adapter, adapter->physical_port);
+	adapter->curr_window = 255;
+
+	err = netxen_start_firmware(adapter);
 	if (err) {
-		printk(KERN_ERR "%s: Failed to initialize port %d\n",
-				netxen_nic_driver_name, adapter->portnum);
-		goto err_out_free_irq;
+		dev_err(&pdev->dev, "failed to start firmware\n");
+		return err;
 	}
-	adapter->macaddr_set(adapter, netdev->dev_addr);
 
-	netxen_nic_set_link_parameters(adapter);
+	if (netif_running(netdev)) {
+		err = netxen_nic_attach(adapter);
+		if (err)
+			return err;
 
-	netxen_set_multicast_list(netdev);
-	if (adapter->set_mtu)
-		adapter->set_mtu(adapter, netdev->mtu);
+		err = netxen_nic_up(adapter, netdev);
+		if (err)
+			return err;
 
-	adapter->ahw.linkup = 0;
-	mod_timer(&adapter->watchdog_timer, jiffies);
+		netif_device_attach(netdev);
+	}
 
-	napi_enable(&adapter->napi);
-	netxen_nic_enable_int(adapter);
+	return 0;
+}
+
+static int netxen_nic_open(struct net_device *netdev)
+{
+	struct netxen_adapter *adapter = netdev_priv(netdev);
+	int err = 0;
+
+	if (adapter->driver_mismatch)
+		return -EIO;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
+		err = netxen_nic_attach(adapter);
+		if (err)
+			return err;
+	}
+
+	err = netxen_nic_up(adapter, netdev);
+	if (err)
+		goto err_out;
 
 	netif_start_queue(netdev);
 
 	return 0;
 
-err_out_free_irq:
-	free_irq(adapter->irq, adapter);
-err_out_free_rxbuf:
-	netxen_release_rx_buffers(adapter);
-err_out_free_hw:
-	netxen_free_hw_resources(adapter);
-err_out_free_sw:
-	netxen_free_sw_resources(adapter);
+err_out:
+	netxen_nic_detach(adapter);
 	return err;
 }
 
@@ -1089,20 +1231,7 @@ static int netxen_nic_close(struct net_d
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 
-	netif_carrier_off(netdev);
-	netif_stop_queue(netdev);
-	napi_disable(&adapter->napi);
-
-	if (adapter->stop_port)
-		adapter->stop_port(adapter);
-
-	netxen_nic_disable_int(adapter);
-
-	netxen_release_tx_buffers(adapter);
-
-	FLUSH_SCHEDULED_WORK();
-	del_timer_sync(&adapter->watchdog_timer);
-
+	netxen_nic_down(adapter, netdev);
 	return 0;
 }
 
@@ -1114,7 +1243,7 @@ static bool netxen_tso_check(struct net_
 	__be16 protocol = skb->protocol;
 	u16 flags = 0;
 
-	if (protocol == __constant_htons(ETH_P_8021Q)) {
+	if (protocol == cpu_to_be16(ETH_P_8021Q)) {
 		struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
 		protocol = vh->h_vlan_encapsulated_proto;
 		flags = FLAGS_VLAN_TAGGED;
@@ -1127,21 +1256,21 @@ static bool netxen_tso_check(struct net_
 		desc->total_hdr_length =
 			skb_transport_offset(skb) + tcp_hdrlen(skb);
 
-		opcode = (protocol == __constant_htons(ETH_P_IPV6)) ?
+		opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
 				TX_TCP_LSO6 : TX_TCP_LSO;
 		tso = true;
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 l4proto;
 
-		if (protocol == __constant_htons(ETH_P_IP)) {
+		if (protocol == cpu_to_be16(ETH_P_IP)) {
 			l4proto = ip_hdr(skb)->protocol;
 
 			if (l4proto == IPPROTO_TCP)
 				opcode = TX_TCP_PKT;
 			else if(l4proto == IPPROTO_UDP)
 				opcode = TX_UDP_PKT;
-		} else if (protocol == __constant_htons(ETH_P_IPV6)) {
+		} else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
 			l4proto = ipv6_hdr(skb)->nexthdr;
 
 			if (l4proto == IPPROTO_TCP)
@@ -1174,7 +1303,16 @@ netxen_clean_tx_dma_mapping(struct pci_d
 	}
 }
 
-static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static inline void
+netxen_clear_cmddesc(u64 *desc)
+{
+	int i;
+	for (i = 0; i < 8; i++)
+		desc[i] = 0ULL;
+}
+
+static int
+netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	struct netxen_hardware_context *hw = &adapter->ahw;
@@ -1188,7 +1326,7 @@ static int netxen_nic_xmit_frame(struct
 
 	u32 producer, consumer;
 	int frag_count, no_of_desc;
-	u32 num_txd = adapter->max_tx_desc_count;
+	u32 num_txd = adapter->num_txd;
 	bool is_tso = false;
 
 	frag_count = skb_shinfo(skb)->nr_frags + 1;
@@ -1207,7 +1345,7 @@ static int netxen_nic_xmit_frame(struct
 
 	/* Copy the descriptors into the hardware    */
 	hwdesc = &hw->cmd_desc_head[producer];
-	memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+	netxen_clear_cmddesc((u64 *)hwdesc);
 	/* Take skb->data itself */
 	pbuf = &adapter->cmd_buf_arr[producer];
 
@@ -1226,7 +1364,7 @@ static int netxen_nic_xmit_frame(struct
 	netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
 	netxen_set_tx_port(hwdesc, adapter->portnum);
 
-	hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
+	hwdesc->buffer_length[0] = cpu_to_le16(first_seg_len);
 	hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
 
 	for (i = 1, k = 1; i < frag_count; i++, k++) {
@@ -1239,7 +1377,7 @@ static int netxen_nic_xmit_frame(struct
 			k = 0;
 			producer = get_next_index(producer, num_txd);
 			hwdesc = &hw->cmd_desc_head[producer];
-			memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+			netxen_clear_cmddesc((u64 *)hwdesc);
 			pbuf = &adapter->cmd_buf_arr[producer];
 			pbuf->skb = NULL;
 		}
@@ -1259,21 +1397,18 @@ static int netxen_nic_xmit_frame(struct
 		buffrag->dma = temp_dma;
 		buffrag->length = temp_len;
 
+		hwdesc->buffer_length[k] = cpu_to_le16(temp_len);
 		switch (k) {
 		case 0:
-			hwdesc->buffer1_length = cpu_to_le16(temp_len);
 			hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
 			break;
 		case 1:
-			hwdesc->buffer2_length = cpu_to_le16(temp_len);
 			hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
 			break;
 		case 2:
-			hwdesc->buffer3_length = cpu_to_le16(temp_len);
 			hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
 			break;
 		case 3:
-			hwdesc->buffer4_length = cpu_to_le16(temp_len);
 			hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
 			break;
 		}
@@ -1388,7 +1523,7 @@ static void netxen_nic_handle_phy_intr(s
 		linkup = (val == XG_LINK_UP_P3);
 	} else {
 		val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
-		if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+		if (adapter->ahw.port_type == NETXEN_NIC_GBE)
 			linkup = (val >> port) & 1;
 		else {
 			val = (val >> port*8) & 0xff;
@@ -1455,13 +1590,11 @@ static void netxen_tx_timeout_task(struc
 	printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
 	       netxen_nic_driver_name, adapter->netdev->name);
 
-	netxen_nic_disable_int(adapter);
-	napi_disable(&adapter->napi);
+	netxen_napi_disable(adapter);
 
 	adapter->netdev->trans_start = jiffies;
 
-	napi_enable(&adapter->napi);
-	netxen_nic_enable_int(adapter);
+	netxen_napi_enable(adapter);
 	netif_wake_queue(adapter->netdev);
 }
 
@@ -1499,7 +1632,8 @@ struct net_device_stats *netxen_nic_get_
 
 static irqreturn_t netxen_intr(int irq, void *data)
 {
-	struct netxen_adapter *adapter = data;
+	struct nx_host_sds_ring *sds_ring = data;
+	struct netxen_adapter *adapter = sds_ring->adapter;
 	u32 status = 0;
 
 	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1530,7 +1664,7 @@ static irqreturn_t netxen_intr(int irq,
 
 	/* clear interrupt */
 	if (adapter->fw_major < 4)
-		netxen_nic_disable_int(adapter);
+		netxen_nic_disable_int(sds_ring);
 
 	adapter->pci_write_immediate(adapter,
 			adapter->legacy_intr.tgt_status_reg,
@@ -1539,61 +1673,49 @@ static irqreturn_t netxen_intr(int irq,
 	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
 	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
 
-	napi_schedule(&adapter->napi);
+	napi_schedule(&sds_ring->napi);
 
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t netxen_msi_intr(int irq, void *data)
 {
-	struct netxen_adapter *adapter = data;
+	struct nx_host_sds_ring *sds_ring = data;
+	struct netxen_adapter *adapter = sds_ring->adapter;
 
 	/* clear interrupt */
 	adapter->pci_write_immediate(adapter,
 			msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
 
-	napi_schedule(&adapter->napi);
+	napi_schedule(&sds_ring->napi);
 	return IRQ_HANDLED;
 }
 
 static irqreturn_t netxen_msix_intr(int irq, void *data)
 {
-	struct netxen_adapter *adapter = data;
+	struct nx_host_sds_ring *sds_ring = data;
 
-	napi_schedule(&adapter->napi);
+	napi_schedule(&sds_ring->napi);
 	return IRQ_HANDLED;
 }
 
 static int netxen_nic_poll(struct napi_struct *napi, int budget)
 {
-	struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
+	struct nx_host_sds_ring *sds_ring =
+		container_of(napi, struct nx_host_sds_ring, napi);
+
+	struct netxen_adapter *adapter = sds_ring->adapter;
+
 	int tx_complete;
-	int ctx;
 	int work_done;
 
 	tx_complete = netxen_process_cmd_ring(adapter);
 
-	work_done = 0;
-	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-		/*
-		 * Fairness issue. This will give undue weight to the
-		 * receive context 0.
-		 */
-
-		/*
-		 * To avoid starvation, we give each of our receivers,
-		 * a fraction of the quota. Sometimes, it might happen that we
-		 * have enough quota to process every packet, but since all the
-		 * packets are on one context, it gets only half of the quota,
-		 * and ends up not processing it.
-		 */
-		work_done += netxen_process_rcv_ring(adapter, ctx,
-						     budget / MAX_RCV_CTX);
-	}
+	work_done = netxen_process_rcv_ring(sds_ring, budget);
 
 	if ((work_done < budget) && tx_complete) {
-		netif_rx_complete(&adapter->napi);
-		netxen_nic_enable_int(adapter);
+		napi_complete(&sds_ring->napi);
+		netxen_nic_enable_int(sds_ring);
 	}
 
 	return work_done;
@@ -1613,13 +1735,17 @@ static struct pci_driver netxen_driver =
 	.name = netxen_nic_driver_name,
 	.id_table = netxen_pci_tbl,
 	.probe = netxen_nic_probe,
-	.remove = __devexit_p(netxen_nic_remove)
+	.remove = __devexit_p(netxen_nic_remove),
+	.suspend = netxen_nic_suspend,
+	.resume = netxen_nic_resume
 };
 
 /* Driver Registration on NetXen card    */
 
 static int __init netxen_init_module(void)
 {
+	printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+
 	if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
 		return -ENOMEM;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_niu.c linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_niu.c
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_niu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_niu.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Provides access to the Network Interface Unit h/w block.
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
  *
  */
 
@@ -299,14 +296,6 @@ int netxen_niu_gbe_disable_phy_interrupt
 	return result;
 }
 
-#if 0
-int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
-{
-	netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
-	return 0;
-}
-#endif  /*  0  */
-
 static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
 {
 	int result = 0;
@@ -467,104 +456,6 @@ int netxen_niu_xg_init_port(struct netxe
 	return 0;
 }
 
-#if 0
-/*
- * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
- * @param enable 0 means don't enable the port
- *		 1 means enable (or re-enable) the port
- */
-int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
-					int port, long enable)
-{
-	int result = 0;
-	__u32 int_src;
-
-	printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
-	       " (device enable = %d)\n", (int)port, (int)enable);
-
-	/*
-	 * The read of the PHY INT status will clear the pending
-	 * interrupt status
-	 */
-	if (netxen_niu_gbe_phy_read(adapter,
-				    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
-				    &int_src) != 0)
-		result = -EINVAL;
-	else {
-		printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
-		if (netxen_get_phy_int_jabber(int_src))
-			printk(KERN_INFO PFX "jabber Interrupt ");
-		if (netxen_get_phy_int_polarity_changed(int_src))
-			printk(KERN_INFO PFX "polarity changed ");
-		if (netxen_get_phy_int_energy_detect(int_src))
-			printk(KERN_INFO PFX "energy detect \n");
-		if (netxen_get_phy_int_downshift(int_src))
-			printk(KERN_INFO PFX "downshift \n");
-		if (netxen_get_phy_int_mdi_xover_changed(int_src))
-			printk(KERN_INFO PFX "mdi_xover_changed ");
-		if (netxen_get_phy_int_fifo_over_underflow(int_src))
-			printk(KERN_INFO PFX "fifo_over_underflow ");
-		if (netxen_get_phy_int_false_carrier(int_src))
-			printk(KERN_INFO PFX "false_carrier ");
-		if (netxen_get_phy_int_symbol_error(int_src))
-			printk(KERN_INFO PFX "symbol_error ");
-		if (netxen_get_phy_int_autoneg_completed(int_src))
-			printk(KERN_INFO PFX "autoneg_completed ");
-		if (netxen_get_phy_int_page_received(int_src))
-			printk(KERN_INFO PFX "page_received ");
-		if (netxen_get_phy_int_duplex_changed(int_src))
-			printk(KERN_INFO PFX "duplex_changed ");
-		if (netxen_get_phy_int_autoneg_error(int_src))
-			printk(KERN_INFO PFX "autoneg_error ");
-		if ((netxen_get_phy_int_speed_changed(int_src))
-		    || (netxen_get_phy_int_link_status_changed(int_src))) {
-			__u32 status;
-
-			printk(KERN_INFO PFX
-			       "speed_changed or link status changed");
-			if (netxen_niu_gbe_phy_read
-			    (adapter,
-			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-			     &status) == 0) {
-				if (netxen_get_phy_speed(status) == 2) {
-					printk
-					    (KERN_INFO PFX "Link speed changed"
-					     " to 1000 Mbps\n");
-					netxen_niu_gbe_set_gmii_mode(adapter,
-								     port,
-								     enable);
-				} else if (netxen_get_phy_speed(status) == 1) {
-					printk
-					    (KERN_INFO PFX "Link speed changed"
-					     " to 100 Mbps\n");
-					netxen_niu_gbe_set_mii_mode(adapter,
-								    port,
-								    enable);
-				} else if (netxen_get_phy_speed(status) == 0) {
-					printk
-					    (KERN_INFO PFX "Link speed changed"
-					     " to 10 Mbps\n");
-					netxen_niu_gbe_set_mii_mode(adapter,
-								    port,
-								    enable);
-				} else {
-					printk(KERN_ERR PFX "ERROR reading "
-					       "PHY status. Invalid speed.\n");
-					result = -1;
-				}
-			} else {
-				printk(KERN_ERR PFX
-				       "ERROR reading PHY status.\n");
-				result = -1;
-			}
-
-		}
-		printk(KERN_INFO "\n");
-	}
-	return result;
-}
-#endif  /*  0  */
-
 /*
  * Return the current station MAC address.
  * Note that the passed-in value must already be in network byte order.
@@ -641,86 +532,6 @@ int netxen_niu_macaddr_set(struct netxen
 	return 0;
 }
 
-#if 0
-/* Enable a GbE interface */
-int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
-			       int port, netxen_niu_gbe_ifmode_t mode)
-{
-	__u32 mac_cfg0;
-	__u32 mac_cfg1;
-	__u32 mii_cfg;
-
-	if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
-		return -EINVAL;
-
-	mac_cfg0 = 0;
-	netxen_gb_soft_reset(mac_cfg0);
-	if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-				   &mac_cfg0, 4))
-		return -EIO;
-	mac_cfg0 = 0;
-	netxen_gb_enable_tx(mac_cfg0);
-	netxen_gb_enable_rx(mac_cfg0);
-	netxen_gb_unset_rx_flowctl(mac_cfg0);
-	netxen_gb_tx_reset_pb(mac_cfg0);
-	netxen_gb_rx_reset_pb(mac_cfg0);
-	netxen_gb_tx_reset_mac(mac_cfg0);
-	netxen_gb_rx_reset_mac(mac_cfg0);
-
-	if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-				   &mac_cfg0, 4))
-		return -EIO;
-	mac_cfg1 = 0;
-	netxen_gb_set_preamblelen(mac_cfg1, 0xf);
-	netxen_gb_set_duplex(mac_cfg1);
-	netxen_gb_set_crc_enable(mac_cfg1);
-	netxen_gb_set_padshort(mac_cfg1);
-	netxen_gb_set_checklength(mac_cfg1);
-	netxen_gb_set_hugeframes(mac_cfg1);
-
-	if (mode == NETXEN_NIU_10_100_MB) {
-		netxen_gb_set_intfmode(mac_cfg1, 1);
-		if (adapter->hw_write_wx(adapter,
-					   NETXEN_NIU_GB_MAC_CONFIG_1(port),
-					   &mac_cfg1, 4))
-			return -EIO;
-
-		/* set mii mode */
-		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
-					    (port << 3), 0);
-		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
-					    (port << 3), 1);
-
-	} else if (mode == NETXEN_NIU_1000_MB) {
-		netxen_gb_set_intfmode(mac_cfg1, 2);
-		if (adapter->hw_write_wx(adapter,
-					   NETXEN_NIU_GB_MAC_CONFIG_1(port),
-					   &mac_cfg1, 4))
-			return -EIO;
-		/* set gmii mode */
-		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
-					    (port << 3), 0);
-		netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
-					    (port << 3), 1);
-	}
-	mii_cfg = 0;
-	netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
-	if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
-				   &mii_cfg, 4))
-		return -EIO;
-	mac_cfg0 = 0;
-	netxen_gb_enable_tx(mac_cfg0);
-	netxen_gb_enable_rx(mac_cfg0);
-	netxen_gb_unset_rx_flowctl(mac_cfg0);
-	netxen_gb_unset_tx_flowctl(mac_cfg0);
-
-	if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-				   &mac_cfg0, 4))
-		return -EIO;
-	return 0;
-}
-#endif  /*  0  */
-
 /* Disable a GbE interface */
 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
 {
@@ -869,39 +680,6 @@ int netxen_niu_xg_macaddr_set(struct net
 	return 0;
 }
 
-#if 0
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
-			      netxen_ethernet_macaddr_t * addr)
-{
-	int phy = adapter->physical_port;
-	u32 stationhigh;
-	u32 stationlow;
-	u8 val[8];
-
-	if (addr == NULL)
-		return -EINVAL;
-	if (phy != 0)
-		return -EINVAL;
-
-	if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
-				  &stationhigh, 4))
-		return -EIO;
-	if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
-				  &stationlow, 4))
-		return -EIO;
-	((__le32 *)val)[1] = cpu_to_le32(stationhigh);
-	((__le32 *)val)[0] = cpu_to_le32(stationlow);
-
-	memcpy(addr, val + 2, 6);
-
-	return 0;
-}
-#endif  /*  0  */
-
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
 		u32 mode)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_phan_reg.h linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_phan_reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/netxen/netxen_nic_phan_reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/netxen/netxen_nic_phan_reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
  *
  * Contact Information:
  *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
  */
 
 #ifndef __NIC_PHAN_REG_H_
@@ -90,6 +91,7 @@
 #define CRB_RX_LRO_START_NUM        NETXEN_NIC_REG(0xc0)
 #define CRB_MPORT_MODE              NETXEN_NIC_REG(0xc4)	/* Multiport Mode */
 #define CRB_CMD_RING_SIZE           NETXEN_NIC_REG(0xc8)
+#define CRB_DMA_SHIFT               NETXEN_NIC_REG(0xcc)
 #define CRB_INT_VECTOR              NETXEN_NIC_REG(0xd4)
 #define CRB_CTX_RESET               NETXEN_NIC_REG(0xd8)
 #define CRB_HOST_STS_PROD           NETXEN_NIC_REG(0xdc)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ni5010.c linux-libre-2.6.30-gnu1/drivers/net/ni5010.c
--- linux-libre-2.6.29-gnu1/drivers/net/ni5010.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ni5010.c	2009-06-09 23:05:27.000000000 -0400
@@ -189,6 +189,17 @@ static void __init trigger_irq(int ioadd
 		outb(MM_EN_XMT|MM_MUX, IE_MMODE); /* Start transmission */
 }
 
+static const struct net_device_ops ni5010_netdev_ops = {
+	.ndo_open		= ni5010_open,
+	.ndo_stop		= ni5010_close,
+	.ndo_start_xmit		= ni5010_send_packet,
+	.ndo_set_multicast_list	= ni5010_set_multicast_list,
+	.ndo_tx_timeout		= ni5010_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 /*
  *      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
@@ -328,13 +339,8 @@ static int __init ni5010_probe1(struct n
         	outb(0, IE_RBUF);	/* set buffer byte 0 to 0 again */
 	}
         printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
-	memset(netdev_priv(dev), 0, sizeof(struct ni5010_local));
 
-	dev->open		= ni5010_open;
-	dev->stop		= ni5010_close;
-	dev->hard_start_xmit	= ni5010_send_packet;
-	dev->set_multicast_list = ni5010_set_multicast_list;
-	dev->tx_timeout		= ni5010_timeout;
+	dev->netdev_ops		= &ni5010_netdev_ops;
 	dev->watchdog_timeo	= HZ/20;
 
 	dev->flags &= ~IFF_MULTICAST;	/* Multicast doesn't work */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ni52.c linux-libre-2.6.30-gnu1/drivers/net/ni52.c
--- linux-libre-2.6.29-gnu1/drivers/net/ni52.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ni52.c	2009-06-09 23:05:27.000000000 -0400
@@ -441,6 +441,18 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops ni52_netdev_ops = {
+	.ndo_open		= ni52_open,
+	.ndo_stop		= ni52_close,
+	.ndo_get_stats		= ni52_get_stats,
+	.ndo_tx_timeout 	= ni52_timeout,
+	.ndo_start_xmit 	= ni52_send_packet,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __init ni52_probe1(struct net_device *dev, int ioaddr)
 {
 	int i, size, retval;
@@ -561,15 +573,8 @@ static int __init ni52_probe1(struct net
 		printk("IRQ %d (assigned and not checked!).\n", dev->irq);
 	}
 
-	dev->open		= ni52_open;
-	dev->stop		= ni52_close;
-	dev->get_stats		= ni52_get_stats;
-	dev->tx_timeout 	= ni52_timeout;
+	dev->netdev_ops		= &ni52_netdev_ops;
 	dev->watchdog_timeo	= HZ/20;
-	dev->hard_start_xmit 	= ni52_send_packet;
-	dev->set_multicast_list = set_multicast_list;
-
-	dev->if_port 		= 0;
 
 	return 0;
 out:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ni65.c linux-libre-2.6.30-gnu1/drivers/net/ni65.c
--- linux-libre-2.6.29-gnu1/drivers/net/ni65.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ni65.c	2009-06-09 23:05:27.000000000 -0400
@@ -237,7 +237,7 @@ struct priv
 	void *tmdbounce[TMDNUM];
 	int tmdbouncenum;
 	int lock,xmit_queued;
-	struct net_device_stats stats;
+
 	void *self;
 	int cmdr_addr;
 	int cardno;
@@ -257,7 +257,6 @@ static void  ni65_timeout(struct net_dev
 static int  ni65_close(struct net_device *dev);
 static int  ni65_alloc_buffer(struct net_device *dev);
 static void ni65_free_buffer(struct priv *p);
-static struct net_device_stats *ni65_get_stats(struct net_device *);
 static void set_multicast_list(struct net_device *dev);
 
 static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */
@@ -401,6 +400,17 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops ni65_netdev_ops = {
+	.ndo_open		= ni65_open,
+	.ndo_stop		= ni65_close,
+	.ndo_start_xmit		= ni65_send_packet,
+	.ndo_tx_timeout		= ni65_timeout,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*
  * this is the real card probe ..
  */
@@ -481,8 +491,9 @@ static int __init ni65_probe1(struct net
 	else {
 		if(dev->dma == 0) {
 		/* 'stuck test' from lance.c */
-			long dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
-					    (inb(DMA2_STAT_REG) & 0xf0);
+			unsigned long dma_channels =
+				((inb(DMA1_STAT_REG) >> 4) & 0x0f)
+				| (inb(DMA2_STAT_REG) & 0xf0);
 			for(i=1;i<5;i++) {
 				int dma = dmatab[i];
 				if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
@@ -548,13 +559,9 @@ static int __init ni65_probe1(struct net
 	}
 
 	dev->base_addr = ioaddr;
-	dev->open		= ni65_open;
-	dev->stop		= ni65_close;
-	dev->hard_start_xmit	= ni65_send_packet;
-	dev->tx_timeout		= ni65_timeout;
+	dev->netdev_ops = &ni65_netdev_ops;
 	dev->watchdog_timeo	= HZ/2;
-	dev->get_stats		= ni65_get_stats;
-	dev->set_multicast_list = set_multicast_list;
+
 	return 0; /* everything is OK */
 }
 
@@ -897,17 +904,16 @@ static irqreturn_t ni65_interrupt(int ir
 
 		if(csr0 & CSR0_ERR)
 		{
-			struct priv *p = dev->ml_priv;
 			if(debuglevel > 1)
 				printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
 			if(csr0 & CSR0_BABL)
-				p->stats.tx_errors++;
+				dev->stats.tx_errors++;
 			if(csr0 & CSR0_MISS) {
 				int i;
 				for(i=0;i<RMDNUM;i++)
 					printk("%02x ",p->rmdhead[i].u.s.status);
 				printk("\n");
-				p->stats.rx_errors++;
+				dev->stats.rx_errors++;
 			}
 			if(csr0 & CSR0_MERR) {
 				if(debuglevel > 1)
@@ -922,8 +928,7 @@ static irqreturn_t ni65_interrupt(int ir
  int j;
  for(j=0;j<RMDNUM;j++)
  {
-	struct priv *p = dev->ml_priv;
-	int i,k,num1,num2;
+	int i, num2;
 	for(i=RMDNUM-1;i>0;i--) {
 		 num2 = (p->rmdnum + i) & (RMDNUM-1);
 		 if(!(p->rmdhead[num2].u.s.status & RCV_OWN))
@@ -931,6 +936,7 @@ static irqreturn_t ni65_interrupt(int ir
 	}
 
 	if(i) {
+		int k, num1;
 		for(k=0;k<RMDNUM;k++) {
 			num1 = (p->rmdnum + k) & (RMDNUM-1);
 			if(!(p->rmdhead[num1].u.s.status & RCV_OWN))
@@ -942,7 +948,6 @@ static irqreturn_t ni65_interrupt(int ir
 		if(debuglevel > 0)
 		{
 			char buf[256],*buf1;
-			int k;
 			buf1 = buf;
 			for(k=0;k<RMDNUM;k++) {
 				sprintf(buf1,"%02x ",(p->rmdhead[k].u.s.status)); /* & RCV_OWN) ); */
@@ -998,12 +1003,12 @@ static void ni65_xmit_intr(struct net_de
 #endif
 		 /* checking some errors */
 			if(tmdp->status2 & XMIT_RTRY)
-				p->stats.tx_aborted_errors++;
+				dev->stats.tx_aborted_errors++;
 			if(tmdp->status2 & XMIT_LCAR)
-				p->stats.tx_carrier_errors++;
+				dev->stats.tx_carrier_errors++;
 			if(tmdp->status2 & (XMIT_BUFF | XMIT_UFLO )) {
 		/* this stops the xmitter */
-				p->stats.tx_fifo_errors++;
+				dev->stats.tx_fifo_errors++;
 				if(debuglevel > 0)
 					printk(KERN_ERR "%s: Xmit FIFO/BUFF error\n",dev->name);
 				if(p->features & INIT_RING_BEFORE_START) {
@@ -1017,12 +1022,12 @@ static void ni65_xmit_intr(struct net_de
 			if(debuglevel > 2)
 				printk(KERN_ERR "%s: xmit-error: %04x %02x-%04x\n",dev->name,csr0,(int) tmdstat,(int) tmdp->status2);
 			if(!(csr0 & CSR0_BABL)) /* don't count errors twice */
-				p->stats.tx_errors++;
+				dev->stats.tx_errors++;
 			tmdp->status2 = 0;
 		}
 		else {
-			p->stats.tx_bytes -= (short)(tmdp->blen);
-			p->stats.tx_packets++;
+			dev->stats.tx_bytes -= (short)(tmdp->blen);
+			dev->stats.tx_packets++;
 		}
 
 #ifdef XMT_VIA_SKB
@@ -1058,7 +1063,7 @@ static void ni65_recv_intr(struct net_de
 			if(!(rmdstat & RCV_ERR)) {
 				if(rmdstat & RCV_START)
 				{
-					p->stats.rx_length_errors++;
+					dev->stats.rx_length_errors++;
 					printk(KERN_ERR "%s: recv, packet too long: %d\n",dev->name,rmdp->mlen & 0x0fff);
 				}
 			}
@@ -1067,16 +1072,16 @@ static void ni65_recv_intr(struct net_de
 					printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n",
 									dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) );
 				if(rmdstat & RCV_FRAM)
-					p->stats.rx_frame_errors++;
+					dev->stats.rx_frame_errors++;
 				if(rmdstat & RCV_OFLO)
-					p->stats.rx_over_errors++;
+					dev->stats.rx_over_errors++;
 				if(rmdstat & RCV_CRC)
-					p->stats.rx_crc_errors++;
+					dev->stats.rx_crc_errors++;
 				if(rmdstat & RCV_BUF_ERR)
-					p->stats.rx_fifo_errors++;
+					dev->stats.rx_fifo_errors++;
 			}
 			if(!(csr0 & CSR0_MISS)) /* don't count errors twice */
-				p->stats.rx_errors++;
+				dev->stats.rx_errors++;
 		}
 		else if( (len = (rmdp->mlen & 0x0fff) - 4) >= 60)
 		{
@@ -1107,20 +1112,20 @@ static void ni65_recv_intr(struct net_de
 				skb_put(skb,len);
 				skb_copy_to_linear_data(skb, (unsigned char *) p->recvbounce[p->rmdnum],len);
 #endif
-				p->stats.rx_packets++;
-				p->stats.rx_bytes += len;
+				dev->stats.rx_packets++;
+				dev->stats.rx_bytes += len;
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
 			}
 			else
 			{
 				printk(KERN_ERR "%s: can't alloc new sk_buff\n",dev->name);
-				p->stats.rx_dropped++;
+				dev->stats.rx_dropped++;
 			}
 		}
 		else {
 			printk(KERN_INFO "%s: received runt packet\n",dev->name);
-			p->stats.rx_errors++;
+			dev->stats.rx_errors++;
 		}
 		rmdp->blen = -(R_BUF_SIZE-8);
 		rmdp->mlen = 0;
@@ -1214,23 +1219,6 @@ static int ni65_send_packet(struct sk_bu
 	return 0;
 }
 
-static struct net_device_stats *ni65_get_stats(struct net_device *dev)
-{
-
-#if 0
-	int i;
-	struct priv *p = dev->ml_priv;
-	for(i=0;i<RMDNUM;i++)
-	{
-		struct rmd *rmdp = p->rmdhead + ((p->rmdnum + i) & (RMDNUM-1));
-		printk("%02x ",rmdp->u.s.status);
-	}
-	printk("\n");
-#endif
-
-	return &((struct priv *)dev->ml_priv)->stats;
-}
-
 static void set_multicast_list(struct net_device *dev)
 {
 	if(!ni65_lance_reinit(dev))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/niu.c linux-libre-2.6.30-gnu1/drivers/net/niu.c
--- linux-libre-2.6.29-gnu1/drivers/net/niu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/niu.c	2009-06-09 23:05:27.000000000 -0400
@@ -1115,6 +1115,130 @@ static int link_status_10g_serdes(struct
 	return 0;
 }
 
+static int link_status_mii(struct niu *np, int *link_up_p)
+{
+	struct niu_link_config *lp = &np->link_config;
+	int err;
+	int bmsr, advert, ctrl1000, stat1000, lpa, bmcr, estatus;
+	int supported, advertising, active_speed, active_duplex;
+
+	err = mii_read(np, np->phy_addr, MII_BMCR);
+	if (unlikely(err < 0))
+		return err;
+	bmcr = err;
+
+	err = mii_read(np, np->phy_addr, MII_BMSR);
+	if (unlikely(err < 0))
+		return err;
+	bmsr = err;
+
+	err = mii_read(np, np->phy_addr, MII_ADVERTISE);
+	if (unlikely(err < 0))
+		return err;
+	advert = err;
+
+	err = mii_read(np, np->phy_addr, MII_LPA);
+	if (unlikely(err < 0))
+		return err;
+	lpa = err;
+
+	if (likely(bmsr & BMSR_ESTATEN)) {
+		err = mii_read(np, np->phy_addr, MII_ESTATUS);
+		if (unlikely(err < 0))
+			return err;
+		estatus = err;
+
+		err = mii_read(np, np->phy_addr, MII_CTRL1000);
+		if (unlikely(err < 0))
+			return err;
+		ctrl1000 = err;
+
+		err = mii_read(np, np->phy_addr, MII_STAT1000);
+		if (unlikely(err < 0))
+			return err;
+		stat1000 = err;
+	} else
+		estatus = ctrl1000 = stat1000 = 0;
+
+	supported = 0;
+	if (bmsr & BMSR_ANEGCAPABLE)
+		supported |= SUPPORTED_Autoneg;
+	if (bmsr & BMSR_10HALF)
+		supported |= SUPPORTED_10baseT_Half;
+	if (bmsr & BMSR_10FULL)
+		supported |= SUPPORTED_10baseT_Full;
+	if (bmsr & BMSR_100HALF)
+		supported |= SUPPORTED_100baseT_Half;
+	if (bmsr & BMSR_100FULL)
+		supported |= SUPPORTED_100baseT_Full;
+	if (estatus & ESTATUS_1000_THALF)
+		supported |= SUPPORTED_1000baseT_Half;
+	if (estatus & ESTATUS_1000_TFULL)
+		supported |= SUPPORTED_1000baseT_Full;
+	lp->supported = supported;
+
+	advertising = 0;
+	if (advert & ADVERTISE_10HALF)
+		advertising |= ADVERTISED_10baseT_Half;
+	if (advert & ADVERTISE_10FULL)
+		advertising |= ADVERTISED_10baseT_Full;
+	if (advert & ADVERTISE_100HALF)
+		advertising |= ADVERTISED_100baseT_Half;
+	if (advert & ADVERTISE_100FULL)
+		advertising |= ADVERTISED_100baseT_Full;
+	if (ctrl1000 & ADVERTISE_1000HALF)
+		advertising |= ADVERTISED_1000baseT_Half;
+	if (ctrl1000 & ADVERTISE_1000FULL)
+		advertising |= ADVERTISED_1000baseT_Full;
+
+	if (bmcr & BMCR_ANENABLE) {
+		int neg, neg1000;
+
+		lp->active_autoneg = 1;
+		advertising |= ADVERTISED_Autoneg;
+
+		neg = advert & lpa;
+		neg1000 = (ctrl1000 << 2) & stat1000;
+
+		if (neg1000 & (LPA_1000FULL | LPA_1000HALF))
+			active_speed = SPEED_1000;
+		else if (neg & LPA_100)
+			active_speed = SPEED_100;
+		else if (neg & (LPA_10HALF | LPA_10FULL))
+			active_speed = SPEED_10;
+		else
+			active_speed = SPEED_INVALID;
+
+		if ((neg1000 & LPA_1000FULL) || (neg & LPA_DUPLEX))
+			active_duplex = DUPLEX_FULL;
+		else if (active_speed != SPEED_INVALID)
+			active_duplex = DUPLEX_HALF;
+		else
+			active_duplex = DUPLEX_INVALID;
+	} else {
+		lp->active_autoneg = 0;
+
+		if ((bmcr & BMCR_SPEED1000) && !(bmcr & BMCR_SPEED100))
+			active_speed = SPEED_1000;
+		else if (bmcr & BMCR_SPEED100)
+			active_speed = SPEED_100;
+		else
+			active_speed = SPEED_10;
+
+		if (bmcr & BMCR_FULLDPLX)
+			active_duplex = DUPLEX_FULL;
+		else
+			active_duplex = DUPLEX_HALF;
+	}
+
+	lp->active_advertising = advertising;
+	lp->active_speed = active_speed;
+	lp->active_duplex = active_duplex;
+	*link_up_p = !!(bmsr & BMSR_LSTATUS);
+
+	return 0;
+}
+
 static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
 {
 	struct niu_link_config *lp = &np->link_config;
@@ -1171,6 +1295,22 @@ out:
 	return err;
 }
 
+static int link_status_1g(struct niu *np, int *link_up_p)
+{
+	struct niu_link_config *lp = &np->link_config;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&np->lock, flags);
+
+	err = link_status_mii(np, link_up_p);
+	lp->supported |= SUPPORTED_TP;
+	lp->active_advertising |= ADVERTISED_TP;
+
+	spin_unlock_irqrestore(&np->lock, flags);
+	return err;
+}
+
 static int bcm8704_reset(struct niu *np)
 {
 	int err, limit;
@@ -1676,39 +1816,88 @@ static int mii_init_common(struct niu *n
 			return err;
 	}
 
-	/* XXX configurable XXX */
-	/* XXX for now don't advertise half-duplex or asym pause... XXX */
-	adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
-	if (bmsr & BMSR_10FULL)
-		adv |= ADVERTISE_10FULL;
-	if (bmsr & BMSR_100FULL)
-		adv |= ADVERTISE_100FULL;
-	err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
-	if (err)
-		return err;
-
-	if (bmsr & BMSR_ESTATEN) {
-		u16 ctrl1000 = 0;
+	if (lp->autoneg) {
+		u16 ctrl1000;
 
-		if (estat & ESTATUS_1000_TFULL)
-			ctrl1000 |= ADVERTISE_1000FULL;
-		err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000);
+		adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
+		if ((bmsr & BMSR_10HALF) &&
+			(lp->advertising & ADVERTISED_10baseT_Half))
+			adv |= ADVERTISE_10HALF;
+		if ((bmsr & BMSR_10FULL) &&
+			(lp->advertising & ADVERTISED_10baseT_Full))
+			adv |= ADVERTISE_10FULL;
+		if ((bmsr & BMSR_100HALF) &&
+			(lp->advertising & ADVERTISED_100baseT_Half))
+			adv |= ADVERTISE_100HALF;
+		if ((bmsr & BMSR_100FULL) &&
+			(lp->advertising & ADVERTISED_100baseT_Full))
+			adv |= ADVERTISE_100FULL;
+		err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
 		if (err)
 			return err;
+
+		if (likely(bmsr & BMSR_ESTATEN)) {
+			ctrl1000 = 0;
+			if ((estat & ESTATUS_1000_THALF) &&
+				(lp->advertising & ADVERTISED_1000baseT_Half))
+				ctrl1000 |= ADVERTISE_1000HALF;
+			if ((estat & ESTATUS_1000_TFULL) &&
+				(lp->advertising & ADVERTISED_1000baseT_Full))
+				ctrl1000 |= ADVERTISE_1000FULL;
+			err = mii_write(np, np->phy_addr,
+					MII_CTRL1000, ctrl1000);
+			if (err)
+				return err;
+		}
+
+		bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+	} else {
+		/* !lp->autoneg */
+		int fulldpx;
+
+		if (lp->duplex == DUPLEX_FULL) {
+			bmcr |= BMCR_FULLDPLX;
+			fulldpx = 1;
+		} else if (lp->duplex == DUPLEX_HALF)
+			fulldpx = 0;
+		else
+			return -EINVAL;
+
+		if (lp->speed == SPEED_1000) {
+			/* if X-full requested while not supported, or
+			   X-half requested while not supported... */
+			if ((fulldpx && !(estat & ESTATUS_1000_TFULL)) ||
+				(!fulldpx && !(estat & ESTATUS_1000_THALF)))
+				return -EINVAL;
+			bmcr |= BMCR_SPEED1000;
+		} else if (lp->speed == SPEED_100) {
+			if ((fulldpx && !(bmsr & BMSR_100FULL)) ||
+				(!fulldpx && !(bmsr & BMSR_100HALF)))
+				return -EINVAL;
+			bmcr |= BMCR_SPEED100;
+		} else if (lp->speed == SPEED_10) {
+			if ((fulldpx && !(bmsr & BMSR_10FULL)) ||
+				(!fulldpx && !(bmsr & BMSR_10HALF)))
+				return -EINVAL;
+		} else
+			return -EINVAL;
 	}
-	bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
 
 	err = mii_write(np, np->phy_addr, MII_BMCR, bmcr);
 	if (err)
 		return err;
 
+#if 0
 	err = mii_read(np, np->phy_addr, MII_BMCR);
 	if (err < 0)
 		return err;
+	bmcr = err;
+
 	err = mii_read(np, np->phy_addr, MII_BMSR);
 	if (err < 0)
 		return err;
-#if 0
+	bmsr = err;
+
 	pr_info(PFX "Port %u after MII init bmcr[%04x] bmsr[%04x]\n",
 		np->port, bmcr, bmsr);
 #endif
@@ -2054,87 +2243,6 @@ static int link_status_10g_hotplug(struc
 	return err;
 }
 
-static int link_status_1g(struct niu *np, int *link_up_p)
-{
-	struct niu_link_config *lp = &np->link_config;
-	u16 current_speed, bmsr;
-	unsigned long flags;
-	u8 current_duplex;
-	int err, link_up;
-
-	link_up = 0;
-	current_speed = SPEED_INVALID;
-	current_duplex = DUPLEX_INVALID;
-
-	spin_lock_irqsave(&np->lock, flags);
-
-	err = -EINVAL;
-	if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
-		goto out;
-
-	err = mii_read(np, np->phy_addr, MII_BMSR);
-	if (err < 0)
-		goto out;
-
-	bmsr = err;
-	if (bmsr & BMSR_LSTATUS) {
-		u16 adv, lpa, common, estat;
-
-		err = mii_read(np, np->phy_addr, MII_ADVERTISE);
-		if (err < 0)
-			goto out;
-		adv = err;
-
-		err = mii_read(np, np->phy_addr, MII_LPA);
-		if (err < 0)
-			goto out;
-		lpa = err;
-
-		common = adv & lpa;
-
-		err = mii_read(np, np->phy_addr, MII_ESTATUS);
-		if (err < 0)
-			goto out;
-		estat = err;
-
-		link_up = 1;
-		if (estat & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
-			current_speed = SPEED_1000;
-			if (estat & ESTATUS_1000_TFULL)
-				current_duplex = DUPLEX_FULL;
-			else
-				current_duplex = DUPLEX_HALF;
-		} else {
-			if (common & ADVERTISE_100BASE4) {
-				current_speed = SPEED_100;
-				current_duplex = DUPLEX_HALF;
-			} else if (common & ADVERTISE_100FULL) {
-				current_speed = SPEED_100;
-				current_duplex = DUPLEX_FULL;
-			} else if (common & ADVERTISE_100HALF) {
-				current_speed = SPEED_100;
-				current_duplex = DUPLEX_HALF;
-			} else if (common & ADVERTISE_10FULL) {
-				current_speed = SPEED_10;
-				current_duplex = DUPLEX_FULL;
-			} else if (common & ADVERTISE_10HALF) {
-				current_speed = SPEED_10;
-				current_duplex = DUPLEX_HALF;
-			} else
-				link_up = 0;
-		}
-	}
-	lp->active_speed = current_speed;
-	lp->active_duplex = current_duplex;
-	err = 0;
-
-out:
-	spin_unlock_irqrestore(&np->lock, flags);
-
-	*link_up_p = link_up;
-	return err;
-}
-
 static int niu_link_status(struct niu *np, int *link_up_p)
 {
 	const struct niu_phy_ops *ops = np->phy_ops;
@@ -2284,7 +2392,6 @@ static int serdes_init_10g_serdes(struct
 	struct niu_link_config *lp = &np->link_config;
 	unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
 	u64 ctrl_val, test_cfg_val, sig, mask, val;
-	int err;
 	u64 reset_val;
 
 	switch (np->port) {
@@ -2337,6 +2444,7 @@ static int serdes_init_10g_serdes(struct
 	/* Initialize all 4 lanes of the SERDES.  */
 	for (i = 0; i < 4; i++) {
 		u32 rxtx_ctrl, glue0;
+		int err;
 
 		err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl);
 		if (err)
@@ -2456,7 +2564,7 @@ static int niu_determine_phy_disposition
 
 		case NIU_FLAGS_10G:
 			/* 10G copper */
-			tp = &phy_template_1g_copper;
+			tp = &phy_template_10g_copper;
 			break;
 
 		case NIU_FLAGS_FIBER:
@@ -2873,7 +2981,6 @@ static int tcam_user_ip_class_enable(str
 	return 0;
 }
 
-#if 0
 static int tcam_user_ip_class_set(struct niu *np, unsigned long class,
 				  int ipv6, u64 protocol_id,
 				  u64 tos_mask, u64 tos_val)
@@ -2901,7 +3008,6 @@ static int tcam_user_ip_class_set(struct
 
 	return 0;
 }
-#endif
 
 static int tcam_early_init(struct niu *np)
 {
@@ -3168,6 +3274,27 @@ static int niu_set_tcam_key(struct niu *
 	return 0;
 }
 
+/* Entries for the ports are interleaved in the TCAM */
+static u16 tcam_get_index(struct niu *np, u16 idx)
+{
+	/* One entry reserved for IP fragment rule */
+	if (idx >= (np->clas.tcam_sz - 1))
+		idx = 0;
+	return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports));
+}
+
+static u16 tcam_get_size(struct niu *np)
+{
+	/* One entry reserved for IP fragment rule */
+	return np->clas.tcam_sz - 1;
+}
+
+static u16 tcam_get_valid_entry_cnt(struct niu *np)
+{
+	/* One entry reserved for IP fragment rule */
+	return np->clas.tcam_valid_entries - 1;
+}
+
 static void niu_rx_skb_append(struct sk_buff *skb, struct page *page,
 			      u32 offset, u32 size)
 {
@@ -3314,7 +3441,8 @@ static int niu_rx_pkt_ignore(struct niu
 	return num_rcr;
 }
 
-static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
+static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
+			      struct rx_ring_info *rp)
 {
 	unsigned int index = rp->rcr_index;
 	struct sk_buff *skb;
@@ -3390,7 +3518,8 @@ static int niu_process_rx_pkt(struct niu
 	rp->rx_bytes += skb->len;
 
 	skb->protocol = eth_type_trans(skb, np->dev);
-	netif_receive_skb(skb);
+	skb_record_rx_queue(skb, rp->rx_channel);
+	napi_gro_receive(napi, skb);
 
 	return num_rcr;
 }
@@ -3578,7 +3707,8 @@ static inline void niu_sync_rx_discard_s
 	}
 }
 
-static int niu_rx_work(struct niu *np, struct rx_ring_info *rp, int budget)
+static int niu_rx_work(struct napi_struct *napi, struct niu *np,
+		       struct rx_ring_info *rp, int budget)
 {
 	int qlen, rcr_done = 0, work_done = 0;
 	struct rxdma_mailbox *mbox = rp->mbox;
@@ -3600,7 +3730,7 @@ static int niu_rx_work(struct niu *np, s
 	rcr_done = work_done = 0;
 	qlen = min(qlen, budget);
 	while (work_done < qlen) {
-		rcr_done += niu_process_rx_pkt(np, rp);
+		rcr_done += niu_process_rx_pkt(napi, np, rp);
 		work_done++;
 	}
 
@@ -3648,7 +3778,7 @@ static int niu_poll_core(struct niu *np,
 		if (rx_vec & (1 << rp->rx_channel)) {
 			int this_work_done;
 
-			this_work_done = niu_rx_work(np, rp,
+			this_work_done = niu_rx_work(&lp->napi, np, rp,
 						     budget);
 
 			budget -= this_work_done;
@@ -3669,7 +3799,7 @@ static int niu_poll(struct napi_struct *
 	work_done = niu_poll_core(np, lp, budget);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		niu_ldg_rearm(np, lp, 1);
 	}
 	return work_done;
@@ -4088,12 +4218,12 @@ static void __niu_fastpath_interrupt(str
 static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
 			      u64 v0, u64 v1, u64 v2)
 {
-	if (likely(netif_rx_schedule_prep(&lp->napi))) {
+	if (likely(napi_schedule_prep(&lp->napi))) {
 		lp->v0 = v0;
 		lp->v1 = v1;
 		lp->v2 = v2;
 		__niu_fastpath_interrupt(np, lp->ldg_num, v0);
-		__netif_rx_schedule(&lp->napi);
+		__napi_schedule(&lp->napi);
 	}
 }
 
@@ -4704,6 +4834,7 @@ static int niu_compute_rbr_cfig_b(struct
 {
 	u64 val = 0;
 
+	*ret = 0;
 	switch (rp->rbr_block_size) {
 	case 4 * 1024:
 		val |= (RBR_BLKSIZE_4K << RBR_CFIG_B_BLKSIZE_SHIFT);
@@ -4890,8 +5021,7 @@ static int niu_set_ip_frag_rule(struct n
 	struct niu_tcam_entry *tp;
 	int index, err;
 
-	/* XXX fix this allocation scheme XXX */
-	index = cp->tcam_index;
+	index = cp->tcam_top;
 	tp = &parent->tcam[index];
 
 	/* Note that the noport bit is the same in both ipv4 and
@@ -4908,6 +5038,8 @@ static int niu_set_ip_frag_rule(struct n
 	err = tcam_assoc_write(np, index, tp->assoc_data);
 	if (err)
 		return err;
+	tp->valid = 1;
+	cp->tcam_valid_entries++;
 
 	return 0;
 }
@@ -5211,10 +5343,10 @@ static void niu_init_xif_xmac(struct niu
 	if (np->flags & NIU_FLAGS_10G) {
 		val |= XMAC_CONFIG_MODE_XGMII;
 	} else {
-		if (lp->active_speed == SPEED_100)
-			val |= XMAC_CONFIG_MODE_MII;
-		else
+		if (lp->active_speed == SPEED_1000)
 			val |= XMAC_CONFIG_MODE_GMII;
+		else
+			val |= XMAC_CONFIG_MODE_MII;
 	}
 
 	nw64_mac(XMAC_CONFIG, val);
@@ -6446,11 +6578,11 @@ static u64 niu_compute_tx_flags(struct s
 
 	ipv6 = ihl = 0;
 	switch (skb->protocol) {
-	case __constant_htons(ETH_P_IP):
+	case cpu_to_be16(ETH_P_IP):
 		ip_proto = ip_hdr(skb)->protocol;
 		ihl = ip_hdr(skb)->ihl;
 		break;
-	case __constant_htons(ETH_P_IPV6):
+	case cpu_to_be16(ETH_P_IPV6):
 		ip_proto = ipv6_hdr(skb)->nexthdr;
 		ihl = (40 >> 2);
 		ipv6 = 1;
@@ -6702,17 +6834,27 @@ static int niu_get_settings(struct net_d
 	memset(cmd, 0, sizeof(*cmd));
 	cmd->phy_address = np->phy_addr;
 	cmd->supported = lp->supported;
-	cmd->advertising = lp->advertising;
-	cmd->autoneg = lp->autoneg;
+	cmd->advertising = lp->active_advertising;
+	cmd->autoneg = lp->active_autoneg;
 	cmd->speed = lp->active_speed;
 	cmd->duplex = lp->active_duplex;
+	cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
+	cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
+		XCVR_EXTERNAL : XCVR_INTERNAL;
 
 	return 0;
 }
 
 static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	return -EINVAL;
+	struct niu *np = netdev_priv(dev);
+	struct niu_link_config *lp = &np->link_config;
+
+	lp->advertising = cmd->advertising;
+	lp->speed = cmd->speed;
+	lp->duplex = cmd->duplex;
+	lp->autoneg = cmd->autoneg;
+	return niu_init_link(np);
 }
 
 static u32 niu_get_msglevel(struct net_device *dev)
@@ -6727,6 +6869,16 @@ static void niu_set_msglevel(struct net_
 	np->msg_enable = value;
 }
 
+static int niu_nway_reset(struct net_device *dev)
+{
+	struct niu *np = netdev_priv(dev);
+
+	if (np->link_config.autoneg)
+		return niu_init_link(np);
+
+	return 0;
+}
+
 static int niu_get_eeprom_len(struct net_device *dev)
 {
 	struct niu *np = netdev_priv(dev);
@@ -6778,6 +6930,75 @@ static int niu_get_eeprom(struct net_dev
 	return 0;
 }
 
+static void niu_ethflow_to_l3proto(int flow_type, u8 *pid)
+{
+	switch (flow_type) {
+	case TCP_V4_FLOW:
+	case TCP_V6_FLOW:
+		*pid = IPPROTO_TCP;
+		break;
+	case UDP_V4_FLOW:
+	case UDP_V6_FLOW:
+		*pid = IPPROTO_UDP;
+		break;
+	case SCTP_V4_FLOW:
+	case SCTP_V6_FLOW:
+		*pid = IPPROTO_SCTP;
+		break;
+	case AH_V4_FLOW:
+	case AH_V6_FLOW:
+		*pid = IPPROTO_AH;
+		break;
+	case ESP_V4_FLOW:
+	case ESP_V6_FLOW:
+		*pid = IPPROTO_ESP;
+		break;
+	default:
+		*pid = 0;
+		break;
+	}
+}
+
+static int niu_class_to_ethflow(u64 class, int *flow_type)
+{
+	switch (class) {
+	case CLASS_CODE_TCP_IPV4:
+		*flow_type = TCP_V4_FLOW;
+		break;
+	case CLASS_CODE_UDP_IPV4:
+		*flow_type = UDP_V4_FLOW;
+		break;
+	case CLASS_CODE_AH_ESP_IPV4:
+		*flow_type = AH_V4_FLOW;
+		break;
+	case CLASS_CODE_SCTP_IPV4:
+		*flow_type = SCTP_V4_FLOW;
+		break;
+	case CLASS_CODE_TCP_IPV6:
+		*flow_type = TCP_V6_FLOW;
+		break;
+	case CLASS_CODE_UDP_IPV6:
+		*flow_type = UDP_V6_FLOW;
+		break;
+	case CLASS_CODE_AH_ESP_IPV6:
+		*flow_type = AH_V6_FLOW;
+		break;
+	case CLASS_CODE_SCTP_IPV6:
+		*flow_type = SCTP_V6_FLOW;
+		break;
+	case CLASS_CODE_USER_PROG1:
+	case CLASS_CODE_USER_PROG2:
+	case CLASS_CODE_USER_PROG3:
+	case CLASS_CODE_USER_PROG4:
+		*flow_type = IP_USER_FLOW;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
 static int niu_ethflow_to_class(int flow_type, u64 *class)
 {
 	switch (flow_type) {
@@ -6787,7 +7008,8 @@ static int niu_ethflow_to_class(int flow
 	case UDP_V4_FLOW:
 		*class = CLASS_CODE_UDP_IPV4;
 		break;
-	case AH_ESP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
 		*class = CLASS_CODE_AH_ESP_IPV4;
 		break;
 	case SCTP_V4_FLOW:
@@ -6799,7 +7021,8 @@ static int niu_ethflow_to_class(int flow
 	case UDP_V6_FLOW:
 		*class = CLASS_CODE_UDP_IPV6;
 		break;
-	case AH_ESP_V6_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
 		*class = CLASS_CODE_AH_ESP_IPV6;
 		break;
 	case SCTP_V6_FLOW:
@@ -6816,8 +7039,6 @@ static u64 niu_flowkey_to_ethflow(u64 fl
 {
 	u64 ethflow = 0;
 
-	if (flow_key & FLOW_KEY_PORT)
-		ethflow |= RXH_DEV_PORT;
 	if (flow_key & FLOW_KEY_L2DA)
 		ethflow |= RXH_L2DA;
 	if (flow_key & FLOW_KEY_VLAN)
@@ -6841,8 +7062,6 @@ static int niu_ethflow_to_flowkey(u64 et
 {
 	u64 key = 0;
 
-	if (ethflow & RXH_DEV_PORT)
-		key |= FLOW_KEY_PORT;
 	if (ethflow & RXH_L2DA)
 		key |= FLOW_KEY_L2DA;
 	if (ethflow & RXH_VLAN)
@@ -6864,41 +7083,279 @@ static int niu_ethflow_to_flowkey(u64 et
 
 }
 
-static int niu_get_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
 {
-	struct niu *np = netdev_priv(dev);
 	u64 class;
 
-	cmd->data = 0;
+	nfc->data = 0;
 
-	if (!niu_ethflow_to_class(cmd->flow_type, &class))
+	if (!niu_ethflow_to_class(nfc->flow_type, &class))
 		return -EINVAL;
 
 	if (np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] &
 	    TCAM_KEY_DISC)
-		cmd->data = RXH_DISCARD;
+		nfc->data = RXH_DISCARD;
 	else
-
-		cmd->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
+		nfc->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
 						      CLASS_CODE_USER_PROG1]);
 	return 0;
 }
 
-static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp,
+					struct ethtool_rx_flow_spec *fsp)
+{
+
+	fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >>
+		TCAM_V4KEY3_SADDR_SHIFT;
+	fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >>
+		TCAM_V4KEY3_DADDR_SHIFT;
+	fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >>
+		TCAM_V4KEY3_SADDR_SHIFT;
+	fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >>
+		TCAM_V4KEY3_DADDR_SHIFT;
+
+	fsp->h_u.tcp_ip4_spec.ip4src =
+		cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src);
+	fsp->m_u.tcp_ip4_spec.ip4src =
+		cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src);
+	fsp->h_u.tcp_ip4_spec.ip4dst =
+		cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst);
+	fsp->m_u.tcp_ip4_spec.ip4dst =
+		cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+	fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >>
+		TCAM_V4KEY2_TOS_SHIFT;
+	fsp->m_u.tcp_ip4_spec.tos = (tp->key_mask[2] & TCAM_V4KEY2_TOS) >>
+		TCAM_V4KEY2_TOS_SHIFT;
+
+	switch (fsp->flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+		fsp->h_u.tcp_ip4_spec.psrc =
+			((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+			 TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+		fsp->h_u.tcp_ip4_spec.pdst =
+			((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+			 TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+		fsp->m_u.tcp_ip4_spec.psrc =
+			((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+			 TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+		fsp->m_u.tcp_ip4_spec.pdst =
+			((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+			 TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+
+		fsp->h_u.tcp_ip4_spec.psrc =
+			cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc);
+		fsp->h_u.tcp_ip4_spec.pdst =
+			cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst);
+		fsp->m_u.tcp_ip4_spec.psrc =
+			cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc);
+		fsp->m_u.tcp_ip4_spec.pdst =
+			cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst);
+		break;
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+		fsp->h_u.ah_ip4_spec.spi =
+			(tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+			TCAM_V4KEY2_PORT_SPI_SHIFT;
+		fsp->m_u.ah_ip4_spec.spi =
+			(tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+			TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+		fsp->h_u.ah_ip4_spec.spi =
+			cpu_to_be32(fsp->h_u.ah_ip4_spec.spi);
+		fsp->m_u.ah_ip4_spec.spi =
+			cpu_to_be32(fsp->m_u.ah_ip4_spec.spi);
+		break;
+	case IP_USER_FLOW:
+		fsp->h_u.usr_ip4_spec.l4_4_bytes =
+			(tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+			TCAM_V4KEY2_PORT_SPI_SHIFT;
+		fsp->m_u.usr_ip4_spec.l4_4_bytes =
+			(tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+			TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+		fsp->h_u.usr_ip4_spec.l4_4_bytes =
+			cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+		fsp->m_u.usr_ip4_spec.l4_4_bytes =
+			cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+		fsp->h_u.usr_ip4_spec.proto =
+			(tp->key[2] & TCAM_V4KEY2_PROTO) >>
+			TCAM_V4KEY2_PROTO_SHIFT;
+		fsp->m_u.usr_ip4_spec.proto =
+			(tp->key_mask[2] & TCAM_V4KEY2_PROTO) >>
+			TCAM_V4KEY2_PROTO_SHIFT;
+
+		fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
+		break;
+	default:
+		break;
+	}
+}
+
+static int niu_get_ethtool_tcam_entry(struct niu *np,
+				      struct ethtool_rxnfc *nfc)
+{
+	struct niu_parent *parent = np->parent;
+	struct niu_tcam_entry *tp;
+	struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+	u16 idx;
+	u64 class;
+	int ret = 0;
+
+	idx = tcam_get_index(np, (u16)nfc->fs.location);
+
+	tp = &parent->tcam[idx];
+	if (!tp->valid) {
+		pr_info(PFX "niu%d: %s entry [%d] invalid for idx[%d]\n",
+		parent->index, np->dev->name, (u16)nfc->fs.location, idx);
+		return -EINVAL;
+	}
+
+	/* fill the flow spec entry */
+	class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+		TCAM_V4KEY0_CLASS_CODE_SHIFT;
+	ret = niu_class_to_ethflow(class, &fsp->flow_type);
+
+	if (ret < 0) {
+		pr_info(PFX "niu%d: %s niu_class_to_ethflow failed\n",
+		parent->index, np->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (fsp->flow_type == AH_V4_FLOW || fsp->flow_type == AH_V6_FLOW) {
+		u32 proto = (tp->key[2] & TCAM_V4KEY2_PROTO) >>
+			TCAM_V4KEY2_PROTO_SHIFT;
+		if (proto == IPPROTO_ESP) {
+			if (fsp->flow_type == AH_V4_FLOW)
+				fsp->flow_type = ESP_V4_FLOW;
+			else
+				fsp->flow_type = ESP_V6_FLOW;
+		}
+	}
+
+	switch (fsp->flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+		niu_get_ip4fs_from_tcam_key(tp, fsp);
+		break;
+	case TCP_V6_FLOW:
+	case UDP_V6_FLOW:
+	case SCTP_V6_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+		/* Not yet implemented */
+		ret = -EINVAL;
+		break;
+	case IP_USER_FLOW:
+		niu_get_ip4fs_from_tcam_key(tp, fsp);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret < 0)
+		goto out;
+
+	if (tp->assoc_data & TCAM_ASSOCDATA_DISC)
+		fsp->ring_cookie = RX_CLS_FLOW_DISC;
+	else
+		fsp->ring_cookie = (tp->assoc_data & TCAM_ASSOCDATA_OFFSET) >>
+			TCAM_ASSOCDATA_OFFSET_SHIFT;
+
+	/* put the tcam size here */
+	nfc->data = tcam_get_size(np);
+out:
+	return ret;
+}
+
+static int niu_get_ethtool_tcam_all(struct niu *np,
+				    struct ethtool_rxnfc *nfc,
+				    u32 *rule_locs)
+{
+	struct niu_parent *parent = np->parent;
+	struct niu_tcam_entry *tp;
+	int i, idx, cnt;
+	u16 n_entries;
+	unsigned long flags;
+
+
+	/* put the tcam size here */
+	nfc->data = tcam_get_size(np);
+
+	niu_lock_parent(np, flags);
+	n_entries = nfc->rule_cnt;
+	for (cnt = 0, i = 0; i < nfc->data; i++) {
+		idx = tcam_get_index(np, i);
+		tp = &parent->tcam[idx];
+		if (!tp->valid)
+			continue;
+		rule_locs[cnt] = i;
+		cnt++;
+	}
+	niu_unlock_parent(np, flags);
+
+	if (n_entries != cnt) {
+		/* print warning, this should not happen */
+		pr_info(PFX "niu%d: %s In niu_get_ethtool_tcam_all, "
+			"n_entries[%d] != cnt[%d]!!!\n\n",
+			np->parent->index, np->dev->name, n_entries, cnt);
+	}
+
+	return 0;
+}
+
+static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+		       void *rule_locs)
 {
 	struct niu *np = netdev_priv(dev);
+	int ret = 0;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_GRXFH:
+		ret = niu_get_hash_opts(np, cmd);
+		break;
+	case ETHTOOL_GRXRINGS:
+		cmd->data = np->num_rx_rings;
+		break;
+	case ETHTOOL_GRXCLSRLCNT:
+		cmd->rule_cnt = tcam_get_valid_entry_cnt(np);
+		break;
+	case ETHTOOL_GRXCLSRULE:
+		ret = niu_get_ethtool_tcam_entry(np, cmd);
+		break;
+	case ETHTOOL_GRXCLSRLALL:
+		ret = niu_get_ethtool_tcam_all(np, cmd, (u32 *)rule_locs);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int niu_set_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
+{
 	u64 class;
 	u64 flow_key = 0;
 	unsigned long flags;
 
-	if (!niu_ethflow_to_class(cmd->flow_type, &class))
+	if (!niu_ethflow_to_class(nfc->flow_type, &class))
 		return -EINVAL;
 
 	if (class < CLASS_CODE_USER_PROG1 ||
 	    class > CLASS_CODE_SCTP_IPV6)
 		return -EINVAL;
 
-	if (cmd->data & RXH_DISCARD) {
+	if (nfc->data & RXH_DISCARD) {
 		niu_lock_parent(np, flags);
 		flow_key = np->parent->tcam_key[class -
 					       CLASS_CODE_USER_PROG1];
@@ -6923,7 +7380,7 @@ static int niu_set_hash_opts(struct net_
 		}
 	}
 
-	if (!niu_ethflow_to_flowkey(cmd->data, &flow_key))
+	if (!niu_ethflow_to_flowkey(nfc->data, &flow_key))
 		return -EINVAL;
 
 	niu_lock_parent(np, flags);
@@ -6934,6 +7391,331 @@ static int niu_set_hash_opts(struct net_
 	return 0;
 }
 
+static void niu_get_tcamkey_from_ip4fs(struct ethtool_rx_flow_spec *fsp,
+				       struct niu_tcam_entry *tp,
+				       int l2_rdc_tab, u64 class)
+{
+	u8 pid = 0;
+	u32 sip, dip, sipm, dipm, spi, spim;
+	u16 sport, dport, spm, dpm;
+
+	sip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4src);
+	sipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4src);
+	dip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4dst);
+	dipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+	tp->key[0] = class << TCAM_V4KEY0_CLASS_CODE_SHIFT;
+	tp->key_mask[0] = TCAM_V4KEY0_CLASS_CODE;
+	tp->key[1] = (u64)l2_rdc_tab << TCAM_V4KEY1_L2RDCNUM_SHIFT;
+	tp->key_mask[1] = TCAM_V4KEY1_L2RDCNUM;
+
+	tp->key[3] = (u64)sip << TCAM_V4KEY3_SADDR_SHIFT;
+	tp->key[3] |= dip;
+
+	tp->key_mask[3] = (u64)sipm << TCAM_V4KEY3_SADDR_SHIFT;
+	tp->key_mask[3] |= dipm;
+
+	tp->key[2] |= ((u64)fsp->h_u.tcp_ip4_spec.tos <<
+		       TCAM_V4KEY2_TOS_SHIFT);
+	tp->key_mask[2] |= ((u64)fsp->m_u.tcp_ip4_spec.tos <<
+			    TCAM_V4KEY2_TOS_SHIFT);
+	switch (fsp->flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+		sport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.psrc);
+		spm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.psrc);
+		dport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.pdst);
+		dpm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.pdst);
+
+		tp->key[2] |= (((u64)sport << 16) | dport);
+		tp->key_mask[2] |= (((u64)spm << 16) | dpm);
+		niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+		break;
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+		spi = be32_to_cpu(fsp->h_u.ah_ip4_spec.spi);
+		spim = be32_to_cpu(fsp->m_u.ah_ip4_spec.spi);
+
+		tp->key[2] |= spi;
+		tp->key_mask[2] |= spim;
+		niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+		break;
+	case IP_USER_FLOW:
+		spi = be32_to_cpu(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+		spim = be32_to_cpu(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+		tp->key[2] |= spi;
+		tp->key_mask[2] |= spim;
+		pid = fsp->h_u.usr_ip4_spec.proto;
+		break;
+	default:
+		break;
+	}
+
+	tp->key[2] |= ((u64)pid << TCAM_V4KEY2_PROTO_SHIFT);
+	if (pid) {
+		tp->key_mask[2] |= TCAM_V4KEY2_PROTO;
+	}
+}
+
+static int niu_add_ethtool_tcam_entry(struct niu *np,
+				      struct ethtool_rxnfc *nfc)
+{
+	struct niu_parent *parent = np->parent;
+	struct niu_tcam_entry *tp;
+	struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+	struct niu_rdc_tables *rdc_table = &parent->rdc_group_cfg[np->port];
+	int l2_rdc_table = rdc_table->first_table_num;
+	u16 idx;
+	u64 class;
+	unsigned long flags;
+	int err, ret;
+
+	ret = 0;
+
+	idx = nfc->fs.location;
+	if (idx >= tcam_get_size(np))
+		return -EINVAL;
+
+	if (fsp->flow_type == IP_USER_FLOW) {
+		int i;
+		int add_usr_cls = 0;
+		int ipv6 = 0;
+		struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec;
+		struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec;
+
+		niu_lock_parent(np, flags);
+
+		for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+			if (parent->l3_cls[i]) {
+				if (uspec->proto == parent->l3_cls_pid[i]) {
+					class = parent->l3_cls[i];
+					parent->l3_cls_refcnt[i]++;
+					add_usr_cls = 1;
+					break;
+				}
+			} else {
+				/* Program new user IP class */
+				switch (i) {
+				case 0:
+					class = CLASS_CODE_USER_PROG1;
+					break;
+				case 1:
+					class = CLASS_CODE_USER_PROG2;
+					break;
+				case 2:
+					class = CLASS_CODE_USER_PROG3;
+					break;
+				case 3:
+					class = CLASS_CODE_USER_PROG4;
+					break;
+				default:
+					break;
+				}
+				if (uspec->ip_ver == ETH_RX_NFC_IP6)
+					ipv6 = 1;
+				ret = tcam_user_ip_class_set(np, class, ipv6,
+							     uspec->proto,
+							     uspec->tos,
+							     umask->tos);
+				if (ret)
+					goto out;
+
+				ret = tcam_user_ip_class_enable(np, class, 1);
+				if (ret)
+					goto out;
+				parent->l3_cls[i] = class;
+				parent->l3_cls_pid[i] = uspec->proto;
+				parent->l3_cls_refcnt[i]++;
+				add_usr_cls = 1;
+				break;
+			}
+		}
+		if (!add_usr_cls) {
+			pr_info(PFX "niu%d: %s niu_add_ethtool_tcam_entry: "
+				"Could not find/insert class for pid %d\n",
+				parent->index, np->dev->name, uspec->proto);
+			ret = -EINVAL;
+			goto out;
+		}
+		niu_unlock_parent(np, flags);
+	} else {
+		if (!niu_ethflow_to_class(fsp->flow_type, &class)) {
+			return -EINVAL;
+		}
+	}
+
+	niu_lock_parent(np, flags);
+
+	idx = tcam_get_index(np, idx);
+	tp = &parent->tcam[idx];
+
+	memset(tp, 0, sizeof(*tp));
+
+	/* fill in the tcam key and mask */
+	switch (fsp->flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+		niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class);
+		break;
+	case TCP_V6_FLOW:
+	case UDP_V6_FLOW:
+	case SCTP_V6_FLOW:
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+		/* Not yet implemented */
+		pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+			"flow %d for IPv6 not implemented\n\n",
+			parent->index, np->dev->name, fsp->flow_type);
+		ret = -EINVAL;
+		goto out;
+	case IP_USER_FLOW:
+		if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) {
+			niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table,
+						   class);
+		} else {
+			/* Not yet implemented */
+			pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+			"usr flow for IPv6 not implemented\n\n",
+			parent->index, np->dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+		break;
+	default:
+		pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+			"Unknown flow type %d\n\n",
+			parent->index, np->dev->name, fsp->flow_type);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* fill in the assoc data */
+	if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
+		tp->assoc_data = TCAM_ASSOCDATA_DISC;
+	} else {
+		if (fsp->ring_cookie >= np->num_rx_rings) {
+			pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+				"Invalid RX ring %lld\n\n",
+				parent->index, np->dev->name,
+				(long long) fsp->ring_cookie);
+			ret = -EINVAL;
+			goto out;
+		}
+		tp->assoc_data = (TCAM_ASSOCDATA_TRES_USE_OFFSET |
+				  (fsp->ring_cookie <<
+				   TCAM_ASSOCDATA_OFFSET_SHIFT));
+	}
+
+	err = tcam_write(np, idx, tp->key, tp->key_mask);
+	if (err) {
+		ret = -EINVAL;
+		goto out;
+	}
+	err = tcam_assoc_write(np, idx, tp->assoc_data);
+	if (err) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* validate the entry */
+	tp->valid = 1;
+	np->clas.tcam_valid_entries++;
+out:
+	niu_unlock_parent(np, flags);
+
+	return ret;
+}
+
+static int niu_del_ethtool_tcam_entry(struct niu *np, u32 loc)
+{
+	struct niu_parent *parent = np->parent;
+	struct niu_tcam_entry *tp;
+	u16 idx;
+	unsigned long flags;
+	u64 class;
+	int ret = 0;
+
+	if (loc >= tcam_get_size(np))
+		return -EINVAL;
+
+	niu_lock_parent(np, flags);
+
+	idx = tcam_get_index(np, loc);
+	tp = &parent->tcam[idx];
+
+	/* if the entry is of a user defined class, then update*/
+	class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+		TCAM_V4KEY0_CLASS_CODE_SHIFT;
+
+	if (class >= CLASS_CODE_USER_PROG1 && class <= CLASS_CODE_USER_PROG4) {
+		int i;
+		for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+			if (parent->l3_cls[i] == class) {
+				parent->l3_cls_refcnt[i]--;
+				if (!parent->l3_cls_refcnt[i]) {
+					/* disable class */
+					ret = tcam_user_ip_class_enable(np,
+									class,
+									0);
+					if (ret)
+						goto out;
+					parent->l3_cls[i] = 0;
+					parent->l3_cls_pid[i] = 0;
+				}
+				break;
+			}
+		}
+		if (i == NIU_L3_PROG_CLS) {
+			pr_info(PFX "niu%d: %s In niu_del_ethtool_tcam_entry,"
+				"Usr class 0x%llx not found \n",
+				parent->index, np->dev->name,
+				(unsigned long long) class);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+	ret = tcam_flush(np, idx);
+	if (ret)
+		goto out;
+
+	/* invalidate the entry */
+	tp->valid = 0;
+	np->clas.tcam_valid_entries--;
+out:
+	niu_unlock_parent(np, flags);
+
+	return ret;
+}
+
+static int niu_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+	struct niu *np = netdev_priv(dev);
+	int ret = 0;
+
+	switch (cmd->cmd) {
+	case ETHTOOL_SRXFH:
+		ret = niu_set_hash_opts(np, cmd);
+		break;
+	case ETHTOOL_SRXCLSRLINS:
+		ret = niu_add_ethtool_tcam_entry(np, cmd);
+		break;
+	case ETHTOOL_SRXCLSRLDEL:
+		ret = niu_del_ethtool_tcam_entry(np, cmd->fs.location);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 static const struct {
 	const char string[ETH_GSTRING_LEN];
 } niu_xmac_stat_keys[] = {
@@ -7158,6 +7940,7 @@ static const struct ethtool_ops niu_etht
 	.get_link		= ethtool_op_get_link,
 	.get_msglevel		= niu_get_msglevel,
 	.set_msglevel		= niu_set_msglevel,
+	.nway_reset		= niu_nway_reset,
 	.get_eeprom_len		= niu_get_eeprom_len,
 	.get_eeprom		= niu_get_eeprom,
 	.get_settings		= niu_get_settings,
@@ -7166,8 +7949,8 @@ static const struct ethtool_ops niu_etht
 	.get_stats_count	= niu_get_stats_count,
 	.get_ethtool_stats	= niu_get_ethtool_stats,
 	.phys_id		= niu_phys_id,
-	.get_rxhash		= niu_get_hash_opts,
-	.set_rxhash		= niu_set_hash_opts,
+	.get_rxnfc		= niu_get_nfc,
+	.set_rxnfc		= niu_set_nfc,
 };
 
 static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8237,7 +9020,8 @@ static int __devinit niu_classifier_swst
 	niudbg(PROBE, "niu_classifier_swstate_init: num_tcam(%d)\n",
 	       np->parent->tcam_num_entries);
 
-	cp->tcam_index = (u16) np->port;
+	cp->tcam_top = (u16) np->port;
+	cp->tcam_sz = np->parent->tcam_num_entries / np->parent->num_ports;
 	cp->h1_init = 0xffffffff;
 	cp->h2_init = 0xffff;
 
@@ -8257,7 +9041,9 @@ static void __devinit niu_link_config_in
 			   ADVERTISED_10000baseT_Full |
 			   ADVERTISED_Autoneg);
 	lp->speed = lp->active_speed = SPEED_INVALID;
-	lp->duplex = lp->active_duplex = DUPLEX_INVALID;
+	lp->duplex = DUPLEX_FULL;
+	lp->active_duplex = DUPLEX_INVALID;
+	lp->autoneg = 1;
 #if 0
 	lp->loopback_mode = LOOPBACK_MAC;
 	lp->active_speed = SPEED_10000;
@@ -8757,7 +9543,7 @@ static struct niu_parent * __devinit niu
 
 	plat_dev = platform_device_register_simple("niu", niu_parent_index,
 						   NULL, 0);
-	if (!plat_dev)
+	if (IS_ERR(plat_dev))
 		return NULL;
 
 	for (i = 0; attr_name(niu_parent_attributes[i]); i++) {
@@ -9104,8 +9890,8 @@ static int __devinit niu_pci_init_one(st
 			goto err_out_release_parent;
 		}
 	}
-	if (err || dma_mask == DMA_32BIT_MASK) {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (err || dma_mask == DMA_BIT_MASK(32)) {
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, PFX "No usable DMA configuration, "
 				"aborting.\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/niu.h linux-libre-2.6.30-gnu1/drivers/net/niu.h
--- linux-libre-2.6.29-gnu1/drivers/net/niu.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/niu.h	2009-06-09 23:05:27.000000000 -0400
@@ -3004,7 +3004,9 @@ struct niu_classifier {
 	struct niu_altmac_rdc	alt_mac_mappings[16];
 	struct niu_vlan_rdc	vlan_mappings[ENET_VLAN_TBL_NUM_ENTRIES];
 
-	u16			tcam_index;
+	u16			tcam_top;
+	u16			tcam_sz;
+	u16			tcam_valid_entries;
 	u16			num_alt_mac_mappings;
 
 	u32			h1_init;
@@ -3040,6 +3042,7 @@ struct phy_probe_info {
 };
 
 struct niu_tcam_entry {
+	u8			valid;
 	u64			key[4];
 	u64			key_mask[4];
 	u64			assoc_data;
@@ -3107,10 +3110,15 @@ struct niu_parent {
 	struct phy_probe_info	phy_probe_info;
 
 	struct niu_tcam_entry	tcam[NIU_TCAM_ENTRIES_MAX];
-	u64			l2_cls[2];
-	u64			l3_cls[4];
+
+#define	NIU_L2_PROG_CLS		2
+#define	NIU_L3_PROG_CLS		4
+	u64			l2_cls[NIU_L2_PROG_CLS];
+	u64			l3_cls[NIU_L3_PROG_CLS];
 	u64			tcam_key[12];
 	u64			flow_key[12];
+	u16			l3_cls_refcnt[NIU_L3_PROG_CLS];
+	u8			l3_cls_pid[NIU_L3_PROG_CLS];
 };
 
 struct niu_ops {
@@ -3131,16 +3139,19 @@ struct niu_ops {
 };
 
 struct niu_link_config {
+	u32				supported;
+
 	/* Describes what we're trying to get. */
 	u32				advertising;
-	u32				supported;
 	u16				speed;
 	u8				duplex;
 	u8				autoneg;
 
 	/* Describes what we actually have. */
+	u32				active_advertising;
 	u16				active_speed;
 	u8				active_duplex;
+	u8				active_autoneg;
 #define SPEED_INVALID		0xffff
 #define DUPLEX_INVALID		0xff
 #define AUTONEG_INVALID		0xff
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ns83820.c linux-libre-2.6.30-gnu1/drivers/net/ns83820.c
--- linux-libre-2.6.29-gnu1/drivers/net/ns83820.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ns83820.c	2009-06-09 23:05:27.000000000 -0400
@@ -409,7 +409,7 @@ static int lnksts = 0;		/* CFG_LNKSTS bi
 struct rx_info {
 	spinlock_t	lock;
 	int		up;
-	long		idle;
+	unsigned long	idle;
 
 	struct sk_buff	*skbs[NR_RX_DESC];
 
@@ -822,8 +822,7 @@ static void ns83820_cleanup_rx(struct ns
 		struct sk_buff *skb = dev->rx_info.skbs[i];
 		dev->rx_info.skbs[i] = NULL;
 		clear_rx_desc(dev, i);
-		if (skb)
-			kfree_skb(skb);
+		kfree_skb(skb);
 	}
 }
 
@@ -1974,9 +1973,9 @@ static int __devinit ns83820_init_one(st
 
 	/* See if we can set the dma mask early on; failure is fatal. */
 	if (sizeof(dma_addr_t) == 8 &&
-	 	!pci_set_dma_mask(pci_dev, DMA_64BIT_MASK)) {
+		!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) {
 		using_dac = 1;
-	} else if (!pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) {
+	} else if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) {
 		using_dac = 0;
 	} else {
 		dev_warn(&pci_dev->dev, "pci_set_dma_mask failed!\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pasemi_mac.c linux-libre-2.6.30-gnu1/drivers/net/pasemi_mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/pasemi_mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pasemi_mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -970,7 +970,7 @@ static irqreturn_t pasemi_mac_rx_intr(in
 	if (*chan->status & PAS_STATUS_ERROR)
 		reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
 
-	netif_rx_schedule(&mac->napi);
+	napi_schedule(&mac->napi);
 
 	write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
 
@@ -1010,7 +1010,7 @@ static irqreturn_t pasemi_mac_tx_intr(in
 
 	mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
 
-	netif_rx_schedule(&mac->napi);
+	napi_schedule(&mac->napi);
 
 	if (reg)
 		write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
@@ -1639,7 +1639,7 @@ static int pasemi_mac_poll(struct napi_s
 	pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
 	if (pkts < budget) {
 		/* all done, no more packets present */
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		pasemi_mac_restart_rx_intr(mac);
 		pasemi_mac_restart_tx_intr(mac);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/3c574_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/3c574_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/3c574_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/3c574_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -257,6 +257,18 @@ static void tc574_detach(struct pcmcia_d
 	local data structures for one device.  The device is registered
 	with Card Services.
 */
+static const struct net_device_ops el3_netdev_ops = {
+	.ndo_open 		= el3_open,
+	.ndo_stop 		= el3_close,
+	.ndo_start_xmit		= el3_start_xmit,
+	.ndo_tx_timeout 	= el3_tx_timeout,
+	.ndo_get_stats		= el3_get_stats,
+	.ndo_do_ioctl		= el3_ioctl,
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 static int tc574_probe(struct pcmcia_device *link)
 {
@@ -284,18 +296,9 @@ static int tc574_probe(struct pcmcia_dev
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.ConfigIndex = 1;
 
-	/* The EL3-specific entries in the device structure. */
-	dev->hard_start_xmit = &el3_start_xmit;
-	dev->get_stats = &el3_get_stats;
-	dev->do_ioctl = &el3_ioctl;
+	dev->netdev_ops = &el3_netdev_ops;
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-	dev->set_multicast_list = &set_rx_mode;
-	dev->open = &el3_open;
-	dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
-	dev->tx_timeout = el3_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
-#endif
 
 	return tc574_config(link);
 } /* tc574_attach */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/3c589_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/3c589_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/3c589_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/3c589_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -169,6 +169,19 @@ static void tc589_detach(struct pcmcia_d
 
 ======================================================================*/
 
+static const struct net_device_ops el3_netdev_ops = {
+	.ndo_open 		= el3_open,
+	.ndo_stop 		= el3_close,
+	.ndo_start_xmit		= el3_start_xmit,
+	.ndo_tx_timeout 	= el3_tx_timeout,
+	.ndo_set_config		= el3_config,
+	.ndo_get_stats		= el3_get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int tc589_probe(struct pcmcia_device *link)
 {
     struct el3_private *lp;
@@ -195,17 +208,9 @@ static int tc589_probe(struct pcmcia_dev
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
 
-    /* The EL3-specific entries in the device structure. */
-    dev->hard_start_xmit = &el3_start_xmit;
-    dev->set_config = &el3_config;
-    dev->get_stats = &el3_get_stats;
-    dev->set_multicast_list = &set_multicast_list;
-    dev->open = &el3_open;
-    dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = el3_tx_timeout;
+    dev->netdev_ops = &el3_netdev_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
     return tc589_config(link);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/axnet_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/axnet_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/axnet_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/axnet_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/crc32.h>
 #include "../8390.h"
 
@@ -91,6 +92,10 @@ static void axnet_release(struct pcmcia_
 static int axnet_open(struct net_device *dev);
 static int axnet_close(struct net_device *dev);
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void axnet_tx_timeout(struct net_device *dev);
 static const struct ethtool_ops netdev_ethtool_ops;
 static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
 static void ei_watchdog(u_long arg);
@@ -108,7 +113,6 @@ static void block_output(struct net_devi
 
 static void axnet_detach(struct pcmcia_device *p_dev);
 
-static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
 static int ax_open(struct net_device *dev);
 static int ax_close(struct net_device *dev);
@@ -134,6 +138,19 @@ static inline axnet_dev_t *PRIV(struct n
 	return p;
 }
 
+static const struct net_device_ops axnet_netdev_ops = {
+	.ndo_open 		= axnet_open,
+	.ndo_stop		= axnet_close,
+	.ndo_do_ioctl		= axnet_ioctl,
+	.ndo_start_xmit		= axnet_start_xmit,
+	.ndo_tx_timeout		= axnet_tx_timeout,
+	.ndo_get_stats		= get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*======================================================================
 
     axnet_attach() creates an "instance" of the driver, allocating
@@ -146,15 +163,17 @@ static int axnet_probe(struct pcmcia_dev
 {
     axnet_dev_t *info;
     struct net_device *dev;
+    struct ei_device *ei_local;
 
     DEBUG(0, "axnet_attach()\n");
 
-    dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
-			"eth%d", axdev_setup);
-
+    dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
     if (!dev)
 	return -ENOMEM;
 
+    ei_local = netdev_priv(dev);
+    spin_lock_init(&ei_local->page_lock);
+
     info = PRIV(dev);
     info->p_dev = link;
     link->priv = dev;
@@ -163,10 +182,10 @@ static int axnet_probe(struct pcmcia_dev
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    dev->open = &axnet_open;
-    dev->stop = &axnet_close;
-    dev->do_ioctl = &axnet_ioctl;
+    dev->netdev_ops = &axnet_netdev_ops;
+
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+    dev->watchdog_timeo = TX_TIMEOUT;
 
     return axnet_config(link);
 } /* axnet_attach */
@@ -320,7 +339,7 @@ static int axnet_config(struct pcmcia_de
 {
     struct net_device *dev = link->priv;
     axnet_dev_t *info = PRIV(dev);
-    int i, j, last_ret, last_fn;
+    int i, j, j2, last_ret, last_fn;
 
     DEBUG(0, "axnet_config(0x%p)\n", link);
 
@@ -369,6 +388,8 @@ static int axnet_config(struct pcmcia_de
 
     for (i = 0; i < 32; i++) {
 	j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+	j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+	if (j == j2) continue;
 	if ((j != 0) && (j != 0xffff)) break;
     }
 
@@ -379,6 +400,8 @@ static int axnet_config(struct pcmcia_de
  	pcmcia_access_configuration_register(link, &reg);
 	for (i = 0; i < 32; i++) {
 	    j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+	    j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+	    if (j == j2) continue;
 	    if ((j != 0) && (j != 0xffff)) break;
 	}
     }
@@ -861,7 +884,7 @@ module_exit(exit_axnet_cs);
 
   */
 
-static const char *version_8390 =
+static const char version_8390[] = KERN_INFO \
     "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
 
 #include <linux/bitops.h>
@@ -905,14 +928,12 @@ int ei_debug = 1;
 /* Index to functions. */
 static void ei_tx_intr(struct net_device *dev);
 static void ei_tx_err(struct net_device *dev);
-static void axnet_tx_timeout(struct net_device *dev);
 static void ei_receive(struct net_device *dev);
 static void ei_rx_overrun(struct net_device *dev);
 
 /* Routines generic to NS8390-based boards. */
 static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
 								int start_page);
-static void set_multicast_list(struct net_device *dev);
 static void do_set_multicast_list(struct net_device *dev);
 
 /*
@@ -954,15 +975,6 @@ static int ax_open(struct net_device *de
 	unsigned long flags;
 	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 
-#ifdef HAVE_TX_TIMEOUT
-	/* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
-	    wrapper that does e.g. media check & then calls axnet_tx_timeout. */
-	if (dev->tx_timeout == NULL)
-		 dev->tx_timeout = axnet_tx_timeout;
-	if (dev->watchdog_timeo <= 0)
-		 dev->watchdog_timeo = TX_TIMEOUT;
-#endif
-
 	/*
 	 *	Grab the page lock so we own the register set, then call
 	 *	the init function.
@@ -1701,30 +1713,6 @@ static void set_multicast_list(struct ne
 	spin_unlock_irqrestore(&dev_lock(dev), flags);
 }	
 
-/**
- * axdev_setup - init rest of 8390 device struct
- * @dev: network device structure to init
- *
- * Initialize the rest of the 8390 device structure.  Do NOT __init
- * this, as it is used by 8390 based modular drivers too.
- */
-
-static void axdev_setup(struct net_device *dev)
-{
-	struct ei_device *ei_local;
-	if (ei_debug > 1)
-		printk(version_8390);
-    
-	ei_local = (struct ei_device *)netdev_priv(dev);
-	spin_lock_init(&ei_local->page_lock);
-    
-	dev->hard_start_xmit = &axnet_start_xmit;
-	dev->get_stats	= get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-
-	ether_setup(dev);
-}
-
 /* This page of functions should be 8390 generic */
 /* Follow National Semi's recommendations for initializing the "NIC". */
 
@@ -1783,6 +1771,9 @@ static void AX88190_init(struct net_devi
 	ei_local->tx1 = ei_local->tx2 = 0;
 	ei_local->txing = 0;
 
+	if (info->flags & IS_AX88790)	/* select Internal PHY */
+		outb(0x10, e8390_base + AXNET_GPIO);
+
 	if (startp) 
 	{
 		outb_p(0xff,  e8390_base + EN0_ISR);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/fmvj18x_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/fmvj18x_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -100,7 +100,6 @@ static int fjn_start_xmit(struct sk_buff
 static irqreturn_t fjn_interrupt(int irq, void *dev_id);
 static void fjn_rx(struct net_device *dev);
 static void fjn_reset(struct net_device *dev);
-static struct net_device_stats *fjn_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 static void fjn_tx_timeout(struct net_device *dev);
 static const struct ethtool_ops netdev_ethtool_ops;
@@ -118,7 +117,6 @@ typedef enum { MBH10302, MBH10304, TDK,
 typedef struct local_info_t {
 	struct pcmcia_device	*p_dev;
     dev_node_t node;
-    struct net_device_stats stats;
     long open_time;
     uint tx_started:1;
     uint tx_queue;
@@ -229,6 +227,18 @@ typedef struct local_info_t {
 #define BANK_1U              0x24 /* bank 1 (CONFIG_1) */
 #define BANK_2U              0x28 /* bank 2 (CONFIG_1) */
 
+static const struct net_device_ops fjn_netdev_ops = {
+	.ndo_open 		= fjn_open,
+	.ndo_stop		= fjn_close,
+	.ndo_start_xmit 	= fjn_start_xmit,
+	.ndo_tx_timeout 	= fjn_tx_timeout,
+	.ndo_set_config 	= fjn_config,
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int fmvj18x_probe(struct pcmcia_device *link)
 {
     local_info_t *lp;
@@ -260,17 +270,9 @@ static int fmvj18x_probe(struct pcmcia_d
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* The FMVJ18x specific entries in the device structure. */
-    dev->hard_start_xmit = &fjn_start_xmit;
-    dev->set_config = &fjn_config;
-    dev->get_stats = &fjn_get_stats;
-    dev->set_multicast_list = &set_rx_mode;
-    dev->open = &fjn_open;
-    dev->stop = &fjn_close;
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = fjn_tx_timeout;
+    dev->netdev_ops = &fjn_netdev_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
     return fmvj18x_config(link);
@@ -793,7 +795,7 @@ static irqreturn_t fjn_interrupt(int dum
 	fjn_rx(dev);
     }
     if (tx_stat & F_TMT_RDY) {
-	lp->stats.tx_packets += lp->sent ;
+	dev->stats.tx_packets += lp->sent ;
         lp->sent = 0 ;
 	if (lp->tx_queue) {
 	    outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
@@ -840,7 +842,7 @@ static void fjn_tx_timeout(struct net_de
 	   htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
 	   htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
 	   htons(inw(ioaddr +14)));
-    lp->stats.tx_errors++;
+    dev->stats.tx_errors++;
     /* ToDo: We should try to restart the adaptor... */
     local_irq_disable();
     fjn_reset(dev);
@@ -880,7 +882,7 @@ static int fjn_start_xmit(struct sk_buff
 
 	DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
 	      dev->name, (unsigned long)skb->len);
-	lp->stats.tx_bytes += skb->len;
+	dev->stats.tx_bytes += skb->len;
 
 	/* Disable both interrupts. */
 	outw(0x0000, ioaddr + TX_INTR);
@@ -1008,7 +1010,6 @@ static void fjn_reset(struct net_device
 
 static void fjn_rx(struct net_device *dev)
 {
-    struct local_info_t *lp = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
     int boguscount = 10;	/* 5 -> 10: by agy 19940922 */
 
@@ -1027,11 +1028,11 @@ static void fjn_rx(struct net_device *de
 	}
 #endif
 	if ((status & 0xF0) != 0x20) {	/* There was an error. */
-	    lp->stats.rx_errors++;
-	    if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
-	    if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
-	    if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
-	    if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
+	    dev->stats.rx_errors++;
+	    if (status & F_LEN_ERR) dev->stats.rx_length_errors++;
+	    if (status & F_ALG_ERR) dev->stats.rx_frame_errors++;
+	    if (status & F_CRC_ERR) dev->stats.rx_crc_errors++;
+	    if (status & F_OVR_FLO) dev->stats.rx_over_errors++;
 	} else {
 	    u_short pkt_len = inw(ioaddr + DATAPORT);
 	    /* Malloc up new buffer. */
@@ -1041,7 +1042,7 @@ static void fjn_rx(struct net_device *de
 		printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
 		       "large packet, size %d.\n", dev->name, pkt_len);
 		outb(F_SKP_PKT, ioaddr + RX_SKIP);
-		lp->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		break;
 	    }
 	    skb = dev_alloc_skb(pkt_len+2);
@@ -1049,7 +1050,7 @@ static void fjn_rx(struct net_device *de
 		printk(KERN_NOTICE "%s: Memory squeeze, dropping "
 		       "packet (len %d).\n", dev->name, pkt_len);
 		outb(F_SKP_PKT, ioaddr + RX_SKIP);
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		break;
 	    }
 
@@ -1070,8 +1071,8 @@ static void fjn_rx(struct net_device *de
 #endif
 
 	    netif_rx(skb);
-	    lp->stats.rx_packets++;
-	    lp->stats.rx_bytes += pkt_len;
+	    dev->stats.rx_packets++;
+	    dev->stats.rx_bytes += pkt_len;
 	}
 	if (--boguscount <= 0)
 	    break;
@@ -1191,14 +1192,6 @@ static int fjn_close(struct net_device *
 
 /*====================================================================*/
 
-static struct net_device_stats *fjn_get_stats(struct net_device *dev)
-{
-    local_info_t *lp = netdev_priv(dev);
-    return &lp->stats;
-} /* fjn_get_stats */
-
-/*====================================================================*/
-
 /*
   Set the multicast/promiscuous mode for this adaptor.
 */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/nmclan_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/nmclan_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/nmclan_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/nmclan_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -436,6 +436,19 @@ static const struct ethtool_ops netdev_e
 
 static void nmclan_detach(struct pcmcia_device *p_dev);
 
+static const struct net_device_ops mace_netdev_ops = {
+	.ndo_open		= mace_open,
+	.ndo_stop		= mace_close,
+	.ndo_start_xmit		= mace_start_xmit,
+	.ndo_tx_timeout		= mace_tx_timeout,
+	.ndo_set_config		= mace_config,
+	.ndo_get_stats		= mace_get_stats,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* ----------------------------------------------------------------------------
 nmclan_attach
 	Creates an "instance" of the driver, allocating local data
@@ -474,17 +487,9 @@ static int nmclan_probe(struct pcmcia_de
 
     lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
 
-    dev->hard_start_xmit = &mace_start_xmit;
-    dev->set_config = &mace_config;
-    dev->get_stats = &mace_get_stats;
-    dev->set_multicast_list = &set_multicast_list;
+    dev->netdev_ops = &mace_netdev_ops;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    dev->open = &mace_open;
-    dev->stop = &mace_close;
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = mace_tx_timeout;
     dev->watchdog_timeo = TX_TIMEOUT;
-#endif
 
     return nmclan_config(link);
 } /* nmclan_attach */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/ositech.h linux-libre-2.6.30-gnu1/drivers/net/pcmcia/ositech.h
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/ositech.h	2013-05-03 18:03:42.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/ositech.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-/*
-    This file contains the firmware of Seven of Diamonds from OSITECH.
-    (Special thanks to Kevin MacPherson of OSITECH)
-
-    This software may be used and distributed according to the terms of
-    the GNU General Public License, incorporated herein by reference.
-*/
-
-    /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/pcnet_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/pcnet_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/pcnet_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/pcnet_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/log2.h>
+#include <linux/etherdevice.h>
 #include "../8390.h"
 
 #include <pcmcia/cs_types.h>
@@ -233,6 +234,23 @@ static inline pcnet_dev_t *PRIV(struct n
 	return (pcnet_dev_t *)(p + sizeof(struct ei_device));
 }
 
+static const struct net_device_ops pcnet_netdev_ops = {
+	.ndo_open		= pcnet_open,
+	.ndo_stop		= pcnet_close,
+	.ndo_set_config		= set_config,
+	.ndo_start_xmit 	= ei_start_xmit,
+	.ndo_get_stats		= ei_get_stats,
+	.ndo_do_ioctl 		= ei_ioctl,
+	.ndo_set_multicast_list = ei_set_multicast_list,
+	.ndo_tx_timeout 	= ei_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller 	= ei_poll,
+#endif
+};
+
 /*======================================================================
 
     pcnet_attach() creates an "instance" of the driver, allocating
@@ -260,9 +278,7 @@ static int pcnet_probe(struct pcmcia_dev
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    dev->open = &pcnet_open;
-    dev->stop = &pcnet_close;
-    dev->set_config = &set_config;
+    dev->netdev_ops = &pcnet_netdev_ops;
 
     return pcnet_config(link);
 } /* pcnet_attach */
@@ -640,18 +656,12 @@ static int pcnet_config(struct pcmcia_de
 
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    if (info->flags & (IS_DL10019|IS_DL10022)) {
-	dev->do_ioctl = &ei_ioctl;
+    if (info->flags & (IS_DL10019|IS_DL10022))
 	mii_phy_probe(dev);
-    }
 
     link->dev_node = &info->node;
     SET_NETDEV_DEV(dev, &handle_to_dev(link));
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-    dev->poll_controller = ei_poll;
-#endif
-
     if (register_netdev(dev) != 0) {
 	printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
 	link->dev_node = NULL;
@@ -1183,6 +1193,10 @@ static int ei_ioctl(struct net_device *d
     pcnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_ifru;
     unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
+
+    if (!(info->flags & (IS_DL10019|IS_DL10022)))
+	return -EINVAL;
+
     switch (cmd) {
     case SIOCGMIIPHY:
 	data[0] = info->phy_id;
@@ -1744,7 +1758,7 @@ static struct pcmcia_device_id pcnet_ids
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
-	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.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("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/smc91c92_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/smc91c92_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 18:03:45.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/smc91c92_cs.c	2013-05-03 16:47:34.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/jiffies.h>
+#include <linux/firmware.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -55,17 +56,18 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-/* Ositech Seven of Diamonds firmware */
-/*(DEBLOBBED)*/
-
 /*====================================================================*/
 
 static const char *if_names[] = { "auto", "10baseT", "10base2"};
 
+/* Firmware name */
+#define FIRMWARE_NAME		"/*(DEBLOBBED)*/"
+
 /* Module parameters */
 
 MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
@@ -108,7 +110,7 @@ struct smc_private {
     spinlock_t			lock;
     u_short			manfid;
     u_short			cardid;
-    struct net_device_stats	stats;
+
     dev_node_t			node;
     struct sk_buff		*saved_skb;
     int				packets_waiting;
@@ -289,7 +291,6 @@ static void smc_tx_timeout(struct net_de
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t smc_interrupt(int irq, void *dev_id);
 static void smc_rx(struct net_device *dev);
-static struct net_device_stats *smc_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 static int s9k_config(struct net_device *dev, struct ifmap *map);
 static void smc_set_xcvr(struct net_device *dev, int if_port);
@@ -301,6 +302,19 @@ static void mdio_write(struct net_device
 static int smc_link_ok(struct net_device *dev);
 static const struct ethtool_ops ethtool_ops;
 
+static const struct net_device_ops smc_netdev_ops = {
+	.ndo_open		= smc_open,
+	.ndo_stop		= smc_close,
+	.ndo_start_xmit		= smc_start_xmit,
+	.ndo_tx_timeout 	= smc_tx_timeout,
+	.ndo_set_config 	= s9k_config,
+	.ndo_set_multicast_list = set_rx_mode,
+	.ndo_do_ioctl		= &smc_ioctl,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*======================================================================
 
   smc91c92_attach() creates an "instance" of the driver, allocating
@@ -336,18 +350,9 @@ static int smc91c92_probe(struct pcmcia_
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     /* The SMC91c92-specific entries in the device structure. */
-    dev->hard_start_xmit = &smc_start_xmit;
-    dev->get_stats = &smc_get_stats;
-    dev->set_config = &s9k_config;
-    dev->set_multicast_list = &set_rx_mode;
-    dev->open = &smc_open;
-    dev->stop = &smc_close;
-    dev->do_ioctl = &smc_ioctl;
+    dev->netdev_ops = &smc_netdev_ops;
     SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = smc_tx_timeout;
     dev->watchdog_timeo = TX_TIMEOUT;
-#endif
 
     smc->mii_if.dev = dev;
     smc->mii_if.mdio_read = mdio_read;
@@ -768,6 +773,26 @@ static int osi_config(struct pcmcia_devi
     return i;
 }
 
+static int osi_load_firmware(struct pcmcia_device *link)
+{
+	const struct firmware *fw;
+	int i, err;
+
+	err = reject_firmware(&fw, FIRMWARE_NAME, &link->dev);
+	if (err) {
+		pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME);
+		return err;
+	}
+
+	/* Download the Seven of Diamonds firmware */
+	for (i = 0; i < fw->size; i++) {
+	    outb(fw->data[i], link->io.BasePort1 + 2);
+	    udelay(50);
+	}
+	release_firmware(fw);
+	return err;
+}
+
 static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
 {
     struct net_device *dev = link->priv;
@@ -808,10 +833,9 @@ static int osi_setup(struct pcmcia_devic
 	 (cardid == PRODID_OSITECH_SEVEN)) ||
 	((manfid == MANFID_PSION) &&
 	 (cardid == PRODID_PSION_NET100))) {
-	printk(KERN_ERR "%s: Missing Free firmware\n", dev->name);
-	rc = -EINVAL;
-	goto free_cfg_mem;
-	/*(DEBLOBBED)*/
+	rc = osi_load_firmware(link);
+	if (rc)
+		goto free_cfg_mem;
     } else if (manfid == MANFID_OSITECH) {
 	/* Make sure both functions are powered up */
 	set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -858,9 +882,11 @@ static int smc91c92_resume(struct pcmcia
 	     (smc->cardid == PRODID_OSITECH_SEVEN)) ||
 	    ((smc->manfid == MANFID_PSION) &&
 	     (smc->cardid == PRODID_PSION_NET100))) {
-		printk(KERN_ERR "%s: Missing Free firmware\n", dev->name);
-		return -EINVAL;
-		/*(DEBLOBBED)*/
+		i = osi_load_firmware(link);
+		if (i) {
+			pr_err("smc91c92_cs: Failed to load firmware\n");
+			return i;
+		}
 	}
 	if (link->open) {
 		smc_reset(dev);
@@ -1288,7 +1314,7 @@ static void smc_hardware_send_packet(str
 	return;
     }
 
-    smc->stats.tx_bytes += skb->len;
+    dev->stats.tx_bytes += skb->len;
     /* The card should use the just-allocated buffer. */
     outw(packet_no, ioaddr + PNR_ARR);
     /* point to the beginning of the packet */
@@ -1337,7 +1363,7 @@ static void smc_tx_timeout(struct net_de
     printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
 	   "Tx_status %2.2x status %4.4x.\n",
 	   dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
-    smc->stats.tx_errors++;
+    dev->stats.tx_errors++;
     smc_reset(dev);
     dev->trans_start = jiffies;
     smc->saved_skb = NULL;
@@ -1359,7 +1385,7 @@ static int smc_start_xmit(struct sk_buff
 
     if (smc->saved_skb) {
 	/* THIS SHOULD NEVER HAPPEN. */
-	smc->stats.tx_aborted_errors++;
+	dev->stats.tx_aborted_errors++;
 	printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
 	       dev->name);
 	return 1;
@@ -1372,7 +1398,7 @@ static int smc_start_xmit(struct sk_buff
 	printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
 	dev_kfree_skb (skb);
 	smc->saved_skb = NULL;
-	smc->stats.tx_dropped++;
+	dev->stats.tx_dropped++;
 	return 0;		/* Do not re-queue this packet. */
     }
     /* A packet is now waiting. */
@@ -1430,11 +1456,11 @@ static void smc_tx_err(struct net_device
 
     tx_status = inw(ioaddr + DATA_1);
 
-    smc->stats.tx_errors++;
-    if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++;
-    if (tx_status & TS_LATCOL)  smc->stats.tx_window_errors++;
+    dev->stats.tx_errors++;
+    if (tx_status & TS_LOSTCAR) dev->stats.tx_carrier_errors++;
+    if (tx_status & TS_LATCOL)  dev->stats.tx_window_errors++;
     if (tx_status & TS_16COL) {
-	smc->stats.tx_aborted_errors++;
+	dev->stats.tx_aborted_errors++;
 	smc->tx_err++;
     }
 
@@ -1471,10 +1497,10 @@ static void smc_eph_irq(struct net_devic
     /* Could be a counter roll-over warning: update stats. */
     card_stats = inw(ioaddr + COUNTER);
     /* single collisions */
-    smc->stats.collisions += card_stats & 0xF;
+    dev->stats.collisions += card_stats & 0xF;
     card_stats >>= 4;
     /* multiple collisions */
-    smc->stats.collisions += card_stats & 0xF;
+    dev->stats.collisions += card_stats & 0xF;
 #if 0 		/* These are for when linux supports these statistics */
     card_stats >>= 4;			/* deferred */
     card_stats >>= 4;			/* excess deferred */
@@ -1548,7 +1574,7 @@ static irqreturn_t smc_interrupt(int irq
 	if (status & IM_TX_EMPTY_INT) {
 	    outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT);
 	    mask &= ~IM_TX_EMPTY_INT;
-	    smc->stats.tx_packets += smc->packets_waiting;
+	    dev->stats.tx_packets += smc->packets_waiting;
 	    smc->packets_waiting = 0;
 	}
 	if (status & IM_ALLOC_INT) {
@@ -1564,8 +1590,8 @@ static irqreturn_t smc_interrupt(int irq
 	    netif_wake_queue(dev);
 	}
 	if (status & IM_RX_OVRN_INT) {
-	    smc->stats.rx_errors++;
-	    smc->stats.rx_fifo_errors++;
+	    dev->stats.rx_errors++;
+	    dev->stats.rx_fifo_errors++;
 	    if (smc->duplex)
 		smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */
 	    outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT);
@@ -1615,7 +1641,6 @@ irq_done:
 
 static void smc_rx(struct net_device *dev)
 {
-    struct smc_private *smc = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
     int rx_status;
     int packet_length;	/* Caution: not frame length, rather words
@@ -1646,7 +1671,7 @@ static void smc_rx(struct net_device *de
 	
 	if (skb == NULL) {
 	    DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
-	    smc->stats.rx_dropped++;
+	    dev->stats.rx_dropped++;
 	    outw(MC_RELEASE, ioaddr + MMU_CMD);
 	    return;
 	}
@@ -1659,18 +1684,18 @@ static void smc_rx(struct net_device *de
 	
 	netif_rx(skb);
 	dev->last_rx = jiffies;
-	smc->stats.rx_packets++;
-	smc->stats.rx_bytes += packet_length;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += packet_length;
 	if (rx_status & RS_MULTICAST)
-	    smc->stats.multicast++;
+	    dev->stats.multicast++;
     } else {
 	/* error ... */
-	smc->stats.rx_errors++;
+	dev->stats.rx_errors++;
 	
-	if (rx_status & RS_ALGNERR)  smc->stats.rx_frame_errors++;
+	if (rx_status & RS_ALGNERR)  dev->stats.rx_frame_errors++;
 	if (rx_status & (RS_TOOSHORT | RS_TOOLONG))
-	    smc->stats.rx_length_errors++;
-	if (rx_status & RS_BADCRC)	smc->stats.rx_crc_errors++;
+	    dev->stats.rx_length_errors++;
+	if (rx_status & RS_BADCRC)	dev->stats.rx_crc_errors++;
     }
     /* Let the MMU free the memory of this packet. */
     outw(MC_RELEASE, ioaddr + MMU_CMD);
@@ -1678,15 +1703,6 @@ static void smc_rx(struct net_device *de
     return;
 }
 
-/*====================================================================*/
-
-static struct net_device_stats *smc_get_stats(struct net_device *dev)
-{
-    struct smc_private *smc = netdev_priv(dev);
-    /* Nothing to update - the 91c92 is a pretty primative chip. */
-    return &smc->stats;
-}
-
 /*======================================================================
 
     Calculate values for the hardware multicast filter hash table.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcmcia/xirc2ps_cs.c linux-libre-2.6.30-gnu1/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcmcia/xirc2ps_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -335,7 +335,7 @@ typedef struct local_info_t {
 	struct net_device	*dev;
 	struct pcmcia_device	*p_dev;
     dev_node_t node;
-    struct net_device_stats stats;
+
     int card_type;
     int probe_port;
     int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */
@@ -355,7 +355,6 @@ typedef struct local_info_t {
 static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void xirc_tx_timeout(struct net_device *dev);
 static void xirc2ps_tx_timeout_task(struct work_struct *work);
-static struct net_device_stats *do_get_stats(struct net_device *dev);
 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);
@@ -546,6 +545,19 @@ mii_wr(unsigned int ioaddr, u_char phyad
 
 /*============= Main bulk of functions	=========================*/
 
+static const struct net_device_ops netdev_ops = {
+	.ndo_open		= do_open,
+	.ndo_stop		= do_stop,
+	.ndo_start_xmit		= do_start_xmit,
+	.ndo_tx_timeout 	= xirc_tx_timeout,
+	.ndo_set_config		= do_config,
+	.ndo_do_ioctl		= do_ioctl,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /****************
  * xirc2ps_attach() creates an "instance" of the driver, allocating
  * local data structures for one device.  The device is registered
@@ -581,19 +593,10 @@ xirc2ps_probe(struct pcmcia_device *link
     link->irq.Instance = dev;
 
     /* Fill in card specific entries */
-    dev->hard_start_xmit = &do_start_xmit;
-    dev->set_config = &do_config;
-    dev->get_stats = &do_get_stats;
-    dev->do_ioctl = &do_ioctl;
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    dev->set_multicast_list = &set_multicast_list;
-    dev->open = &do_open;
-    dev->stop = &do_stop;
-#ifdef HAVE_TX_TIMEOUT
-    dev->tx_timeout = xirc_tx_timeout;
+    dev->netdev_ops = &netdev_ops;
+    dev->ethtool_ops = &netdev_ethtool_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
     INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
-#endif
 
     return xirc2ps_config(link);
 } /* xirc2ps_attach */
@@ -1172,7 +1175,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	if (bytes_rcvd > maxrx_bytes && (rsr & PktRxOk)) {
 	    /* too many bytes received during this int, drop the rest of the
 	     * packets */
-	    lp->stats.rx_dropped++;
+	    dev->stats.rx_dropped++;
 	    DEBUG(2, "%s: RX drop, too much done\n", dev->name);
 	} else if (rsr & PktRxOk) {
 	    struct sk_buff *skb;
@@ -1186,7 +1189,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	    if (!skb) {
 		printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
 		       pktlen);
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 	    } else { /* okay get the packet */
 		skb_reserve(skb, 2);
 		if (lp->silicon == 0 ) { /* work around a hardware bug */
@@ -1242,24 +1245,24 @@ xirc2ps_interrupt(int irq, void *dev_id)
 		}
 		skb->protocol = eth_type_trans(skb, dev);
 		netif_rx(skb);
-		lp->stats.rx_packets++;
-		lp->stats.rx_bytes += pktlen;
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += pktlen;
 		if (!(rsr & PhyPkt))
-		    lp->stats.multicast++;
+		    dev->stats.multicast++;
 	    }
 	} else { /* bad packet */
 	    DEBUG(5, "rsr=%#02x\n", rsr);
 	}
 	if (rsr & PktTooLong) {
-	    lp->stats.rx_frame_errors++;
+	    dev->stats.rx_frame_errors++;
 	    DEBUG(3, "%s: Packet too long\n", dev->name);
 	}
 	if (rsr & CRCErr) {
-	    lp->stats.rx_crc_errors++;
+	    dev->stats.rx_crc_errors++;
 	    DEBUG(3, "%s: CRC error\n", dev->name);
 	}
 	if (rsr & AlignErr) {
-	    lp->stats.rx_fifo_errors++; /* okay ? */
+	    dev->stats.rx_fifo_errors++; /* okay ? */
 	    DEBUG(3, "%s: Alignment error\n", dev->name);
 	}
 
@@ -1270,7 +1273,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	eth_status = GetByte(XIRCREG_ESR);
     }
     if (rx_status & 0x10) { /* Receive overrun */
-	lp->stats.rx_over_errors++;
+	dev->stats.rx_over_errors++;
 	PutByte(XIRCREG_CR, ClearRxOvrun);
 	DEBUG(3, "receive overrun cleared\n");
     }
@@ -1283,11 +1286,11 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	nn = GetByte(XIRCREG0_PTR);
 	lp->last_ptr_value = nn;
 	if (nn < n) /* rollover */
-	    lp->stats.tx_packets += 256 - n;
+	    dev->stats.tx_packets += 256 - n;
 	else if (n == nn) { /* happens sometimes - don't know why */
 	    DEBUG(0, "PTR not changed?\n");
 	} else
-	    lp->stats.tx_packets += lp->last_ptr_value - n;
+	    dev->stats.tx_packets += lp->last_ptr_value - n;
 	netif_wake_queue(dev);
     }
     if (tx_status & 0x0002) {	/* Execessive collissions */
@@ -1295,7 +1298,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
 	PutByte(XIRCREG_CR, RestartTx);  /* restart transmitter process */
     }
     if (tx_status & 0x0040)
-	lp->stats.tx_aborted_errors++;
+	dev->stats.tx_aborted_errors++;
 
     /* recalculate our work chunk so that we limit the duration of this
      * ISR to about 1/10 of a second.
@@ -1353,7 +1356,7 @@ static void
 xirc_tx_timeout(struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
-    lp->stats.tx_errors++;
+    dev->stats.tx_errors++;
     printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
     schedule_work(&lp->tx_timeout_task);
 }
@@ -1409,20 +1412,11 @@ do_start_xmit(struct sk_buff *skb, struc
 
     dev_kfree_skb (skb);
     dev->trans_start = jiffies;
-    lp->stats.tx_bytes += pktlen;
+    dev->stats.tx_bytes += pktlen;
     netif_start_queue(dev);
     return 0;
 }
 
-static struct net_device_stats *
-do_get_stats(struct net_device *dev)
-{
-    local_info_t *lp = netdev_priv(dev);
-
-    /*	lp->stats.rx_missed_errors = GetByte(?) */
-    return &lp->stats;
-}
-
 /****************
  * Set all addresses: This first one is the individual address,
  * the next 9 addresses are taken from the multicast list and
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pcnet32.c linux-libre-2.6.30-gnu1/drivers/net/pcnet32.c
--- linux-libre-2.6.29-gnu1/drivers/net/pcnet32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pcnet32.c	2009-06-09 23:05:27.000000000 -0400
@@ -1397,7 +1397,7 @@ static int pcnet32_poll(struct napi_stru
 	if (work_done < budget) {
 		spin_lock_irqsave(&lp->lock, flags);
 
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 
 		/* clear interrupt masks */
 		val = lp->a.read_csr(ioaddr, CSR3);
@@ -2592,14 +2592,14 @@ pcnet32_interrupt(int irq, void *dev_id)
 				       dev->name, csr0);
 			/* unlike for the lance, there is no restart needed */
 		}
-		if (netif_rx_schedule_prep(&lp->napi)) {
+		if (napi_schedule_prep(&lp->napi)) {
 			u16 val;
 			/* set interrupt masks */
 			val = lp->a.read_csr(ioaddr, CSR3);
 			val |= 0x5f00;
 			lp->a.write_csr(ioaddr, CSR3, val);
 			mmiowb();
-			__netif_rx_schedule(&lp->napi);
+			__napi_schedule(&lp->napi);
 			break;
 		}
 		csr0 = lp->a.read_csr(ioaddr, CSR0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/fixed.c linux-libre-2.6.30-gnu1/drivers/net/phy/fixed.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/fixed.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/fixed.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/phy_fixed.h>
+#include <linux/err.h>
 
 #define MII_REGS_NUM 29
 
@@ -207,8 +208,8 @@ static int __init fixed_mdio_bus_init(vo
 	int ret;
 
 	pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
-	if (!pdev) {
-		ret = -ENOMEM;
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
 		goto err_pdev;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/marvell.c linux-libre-2.6.30-gnu1/drivers/net/phy/marvell.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/marvell.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/marvell.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,6 +69,11 @@
 #define MII_M1111_COPPER		0
 #define MII_M1111_FIBER			1
 
+#define MII_88E1121_PHY_LED_CTRL	16
+#define MII_88E1121_PHY_LED_PAGE	3
+#define MII_88E1121_PHY_LED_DEF		0x0030
+#define MII_88E1121_PHY_PAGE		22
+
 #define MII_M1011_PHY_STATUS		0x11
 #define MII_M1011_PHY_STATUS_1000	0x8000
 #define MII_M1011_PHY_STATUS_100	0x4000
@@ -154,6 +159,30 @@ static int marvell_config_aneg(struct ph
 	return err;
 }
 
+static int m88e1121_config_aneg(struct phy_device *phydev)
+{
+	int err, temp;
+
+	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, MII_M1011_PHY_SCR,
+			MII_M1011_PHY_SCR_AUTO_CROSS);
+	if (err < 0)
+		return err;
+
+	temp = phy_read(phydev, MII_88E1121_PHY_PAGE);
+
+	phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
+	phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
+	phy_write(phydev, MII_88E1121_PHY_PAGE, temp);
+
+	err = genphy_config_aneg(phydev);
+
+	return err;
+}
+
 static int m88e1111_config_init(struct phy_device *phydev)
 {
 	int err;
@@ -429,6 +458,18 @@ static int marvell_read_status(struct ph
 	return 0;
 }
 
+static int m88e1121_did_interrupt(struct phy_device *phydev)
+{
+	int imask;
+
+	imask = phy_read(phydev, MII_M1011_IEVENT);
+
+	if (imask & MII_M1011_IMASK_INIT)
+		return 1;
+
+	return 0;
+}
+
 static struct phy_driver marvell_drivers[] = {
 	{
 		.phy_id = 0x01410c60,
@@ -482,6 +523,19 @@ static struct phy_driver marvell_drivers
 		.driver = {.owner = THIS_MODULE,},
 	},
 	{
+		.phy_id = 0x01410cb0,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1121R",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_aneg = &m88e1121_config_aneg,
+		.read_status = &marvell_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.did_interrupt = &m88e1121_did_interrupt,
+		.driver = { .owner = THIS_MODULE },
+	},
+	{
 		.phy_id = 0x01410cd0,
 		.phy_id_mask = 0xfffffff0,
 		.name = "Marvell 88E1145",
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/mdio_bus.c linux-libre-2.6.30-gnu1/drivers/net/phy/mdio_bus.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/mdio_bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/mdio_bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -98,7 +99,7 @@ int mdiobus_register(struct mii_bus *bus
 	bus->dev.parent = bus->parent;
 	bus->dev.class = &mdio_bus_class;
 	bus->dev.groups = NULL;
-	dev_set_name(&bus->dev, bus->id);
+	dev_set_name(&bus->dev, "%s", bus->id);
 
 	err = device_register(&bus->dev);
 	if (err) {
@@ -286,33 +287,58 @@ static int mdio_bus_match(struct device
 		(phydev->phy_id & phydrv->phy_id_mask));
 }
 
+static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+{
+	struct device_driver *drv = phydev->dev.driver;
+	struct phy_driver *phydrv = to_phy_driver(drv);
+	struct net_device *netdev = phydev->attached_dev;
+
+	if (!drv || !phydrv->suspend)
+		return false;
+
+	/* PHY not attached? May suspend. */
+	if (!netdev)
+		return true;
+
+	/*
+	 * Don't suspend PHY if the attched netdev parent may wakeup.
+	 * The parent may point to a PCI device, as in tg3 driver.
+	 */
+	if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
+		return false;
+
+	/*
+	 * Also don't suspend PHY if the netdev itself may wakeup. This
+	 * is the case for devices w/o underlaying pwr. mgmt. aware bus,
+	 * e.g. SoC devices.
+	 */
+	if (device_may_wakeup(&netdev->dev))
+		return false;
+
+	return true;
+}
+
 /* Suspend and resume.  Copied from platform_suspend and
  * platform_resume
  */
 static int mdio_bus_suspend(struct device * dev, pm_message_t state)
 {
-	int ret = 0;
-	struct device_driver *drv = dev->driver;
-	struct phy_driver *phydrv = to_phy_driver(drv);
+	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
 
-	if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent))
-		ret = phydrv->suspend(phydev);
-
-	return ret;
+	if (!mdio_bus_phy_may_suspend(phydev))
+		return 0;
+	return phydrv->suspend(phydev);
 }
 
 static int mdio_bus_resume(struct device * dev)
 {
-	int ret = 0;
-	struct device_driver *drv = dev->driver;
-	struct phy_driver *phydrv = to_phy_driver(drv);
+	struct phy_driver *phydrv = to_phy_driver(dev->driver);
 	struct phy_device *phydev = to_phy_device(dev);
 
-	if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent))
-		ret = phydrv->resume(phydev);
-
-	return ret;
+	if (!mdio_bus_phy_may_suspend(phydev))
+		return 0;
+	return phydrv->resume(phydev);
 }
 
 struct bus_type mdio_bus_type = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/mdio-gpio.c linux-libre-2.6.30-gnu1/drivers/net/phy/mdio-gpio.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/mdio-gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/mdio-gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -202,16 +202,21 @@ static int __devinit mdio_ofgpio_probe(s
 {
 	struct device_node *np = NULL;
 	struct mdio_gpio_platform_data *pdata;
+	int ret;
 
 	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
 
-	pdata->mdc = of_get_gpio(ofdev->node, 0);
-	pdata->mdio = of_get_gpio(ofdev->node, 1);
-
-	if (pdata->mdc < 0 || pdata->mdio < 0)
+	ret = of_get_gpio(ofdev->node, 0);
+	if (ret < 0)
 		goto out_free;
+	pdata->mdc = ret;
+
+	ret = of_get_gpio(ofdev->node, 1);
+	if (ret < 0)
+                goto out_free;
+	pdata->mdio = ret;
 
 	while ((np = of_get_next_child(ofdev->node, np)))
 		if (!strcmp(np->type, "ethernet-phy"))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/phy.c linux-libre-2.6.30-gnu1/drivers/net/phy/phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -414,7 +414,6 @@ EXPORT_SYMBOL(phy_start_aneg);
 
 static void phy_change(struct work_struct *work);
 static void phy_state_machine(struct work_struct *work);
-static void phy_timer(unsigned long data);
 
 /**
  * phy_start_machine - start PHY state machine tracking
@@ -434,11 +433,8 @@ void phy_start_machine(struct phy_device
 {
 	phydev->adjust_state = handler;
 
-	INIT_WORK(&phydev->state_queue, phy_state_machine);
-	init_timer(&phydev->phy_timer);
-	phydev->phy_timer.function = &phy_timer;
-	phydev->phy_timer.data = (unsigned long) phydev;
-	mod_timer(&phydev->phy_timer, jiffies + HZ);
+	INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
+	schedule_delayed_work(&phydev->state_queue, HZ);
 }
 
 /**
@@ -451,8 +447,7 @@ void phy_start_machine(struct phy_device
  */
 void phy_stop_machine(struct phy_device *phydev)
 {
-	del_timer_sync(&phydev->phy_timer);
-	cancel_work_sync(&phydev->state_queue);
+	cancel_delayed_work_sync(&phydev->state_queue);
 
 	mutex_lock(&phydev->lock);
 	if (phydev->state > PHY_UP)
@@ -660,6 +655,10 @@ static void phy_change(struct work_struc
 	struct phy_device *phydev =
 		container_of(work, struct phy_device, phy_queue);
 
+	if (phydev->drv->did_interrupt &&
+	    !phydev->drv->did_interrupt(phydev))
+		goto ignore;
+
 	err = phy_disable_interrupts(phydev);
 
 	if (err)
@@ -680,12 +679,15 @@ static void phy_change(struct work_struc
 	if (err)
 		goto irq_enable_err;
 
-	/* Stop timer and run the state queue now.  The work function for
-	 * state_queue will start the timer up again.
-	 */
-	del_timer(&phydev->phy_timer);
-	schedule_work(&phydev->state_queue);
+	/* reschedule state queue work to run as soon as possible */
+	cancel_delayed_work_sync(&phydev->state_queue);
+	schedule_delayed_work(&phydev->state_queue, 0);
+
+	return;
 
+ignore:
+	atomic_dec(&phydev->irq_disable);
+	enable_irq(phydev->irq);
 	return;
 
 irq_enable_err:
@@ -761,14 +763,12 @@ EXPORT_SYMBOL(phy_start);
 /**
  * phy_state_machine - Handle the state machine
  * @work: work_struct that describes the work to be done
- *
- * Description: Scheduled by the state_queue workqueue each time
- *   phy_timer is triggered.
  */
 static void phy_state_machine(struct work_struct *work)
 {
+	struct delayed_work *dwork = to_delayed_work(work);
 	struct phy_device *phydev =
-			container_of(work, struct phy_device, state_queue);
+			container_of(dwork, struct phy_device, state_queue);
 	int needs_aneg = 0;
 	int err = 0;
 
@@ -946,17 +946,5 @@ static void phy_state_machine(struct wor
 	if (err < 0)
 		phy_error(phydev);
 
-	mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
-}
-
-/* PHY timer which schedules the state machine work */
-static void phy_timer(unsigned long data)
-{
-	struct phy_device *phydev = (struct phy_device *)data;
-
-	/*
-	 * PHY I/O operations can potentially sleep so we ensure that
-	 * it's done from a process context
-	 */
-	schedule_work(&phydev->state_queue);
+	schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/phy/smsc.c linux-libre-2.6.30-gnu1/drivers/net/phy/smsc.c
--- linux-libre-2.6.29-gnu1/drivers/net/phy/smsc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/phy/smsc.c	2009-06-09 23:05:27.000000000 -0400
@@ -159,6 +159,30 @@ static struct phy_driver lan911x_int_dri
 	.driver		= { .owner = THIS_MODULE, }
 };
 
+static struct phy_driver lan8710_driver = {
+	.phy_id		= 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "SMSC LAN8710/LAN8720",
+
+	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
+				| SUPPORTED_Asym_Pause),
+	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
+
+	/* basic functions */
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.config_init	= smsc_phy_config_init,
+
+	/* IRQ related */
+	.ack_interrupt	= smsc_phy_ack_interrupt,
+	.config_intr	= smsc_phy_config_intr,
+
+	.suspend	= genphy_suspend,
+	.resume		= genphy_resume,
+
+	.driver		= { .owner = THIS_MODULE, }
+};
+
 static int __init smsc_init(void)
 {
 	int ret;
@@ -179,8 +203,14 @@ static int __init smsc_init(void)
 	if (ret)
 		goto err4;
 
+	ret = phy_driver_register (&lan8710_driver);
+	if (ret)
+		goto err5;
+
 	return 0;
 
+err5:
+	phy_driver_unregister (&lan911x_int_driver);
 err4:
 	phy_driver_unregister (&lan8700_driver);
 err3:
@@ -193,6 +223,7 @@ err1:
 
 static void __exit smsc_exit(void)
 {
+	phy_driver_unregister (&lan8710_driver);
 	phy_driver_unregister (&lan911x_int_driver);
 	phy_driver_unregister (&lan8700_driver);
 	phy_driver_unregister (&lan8187_driver);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ppp_async.c linux-libre-2.6.30-gnu1/drivers/net/ppp_async.c
--- linux-libre-2.6.29-gnu1/drivers/net/ppp_async.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ppp_async.c	2009-06-09 23:05:27.000000000 -0400
@@ -157,6 +157,7 @@ ppp_asynctty_open(struct tty_struct *tty
 {
 	struct asyncppp *ap;
 	int err;
+	int speed;
 
 	if (tty->ops->write == NULL)
 		return -EOPNOTSUPP;
@@ -187,6 +188,8 @@ ppp_asynctty_open(struct tty_struct *tty
 	ap->chan.private = ap;
 	ap->chan.ops = &async_ops;
 	ap->chan.mtu = PPP_MRU;
+	speed = tty_get_baud_rate(tty);
+	ap->chan.speed = speed;
 	err = ppp_register_channel(&ap->chan);
 	if (err)
 		goto out_free;
@@ -233,11 +236,9 @@ ppp_asynctty_close(struct tty_struct *tt
 	tasklet_kill(&ap->tsk);
 
 	ppp_unregister_channel(&ap->chan);
-	if (ap->rpkt)
-		kfree_skb(ap->rpkt);
+	kfree_skb(ap->rpkt);
 	skb_queue_purge(&ap->rqueue);
-	if (ap->tpkt)
-		kfree_skb(ap->tpkt);
+	kfree_skb(ap->tpkt);
 	kfree(ap);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ppp_generic.c linux-libre-2.6.30-gnu1/drivers/net/ppp_generic.c
--- linux-libre-2.6.29-gnu1/drivers/net/ppp_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ppp_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,6 +49,10 @@
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
 #define PPP_VERSION	"2.4.2"
 
 /*
@@ -131,6 +135,7 @@ struct ppp {
 	struct sock_filter *active_filter;/* filter for pkts to reset idle */
 	unsigned pass_len, active_len;
 #endif /* CONFIG_PPP_FILTER */
+	struct net	*ppp_net;	/* the net we belong to */
 };
 
 /*
@@ -155,12 +160,14 @@ struct channel {
 	struct rw_semaphore chan_sem;	/* protects `chan' during chan ioctl */
 	spinlock_t	downl;		/* protects `chan', file.xq dequeue */
 	struct ppp	*ppp;		/* ppp unit we're connected to */
+	struct net	*chan_net;	/* the net channel belongs to */
 	struct list_head clist;		/* link in list of channels per unit */
 	rwlock_t	upl;		/* protects `ppp' */
 #ifdef CONFIG_PPP_MULTILINK
 	u8		avail;		/* flag used in multilink stuff */
 	u8		had_frag;	/* >= 1 fragments have been sent */
 	u32		lastseq;	/* MP: last sequence # received */
+	int     speed;		/* speed of the corresponding ppp channel*/
 #endif /* CONFIG_PPP_MULTILINK */
 };
 
@@ -173,26 +180,35 @@ struct channel {
  * channel.downl.
  */
 
-/*
- * all_ppp_mutex protects the all_ppp_units mapping.
- * It also ensures that finding a ppp unit in the all_ppp_units map
- * and updating its file.refcnt field is atomic.
- */
-static DEFINE_MUTEX(all_ppp_mutex);
 static atomic_t ppp_unit_count = ATOMIC_INIT(0);
-static DEFINE_IDR(ppp_units_idr);
-
-/*
- * all_channels_lock protects all_channels and last_channel_index,
- * and the atomicity of find a channel and updating its file.refcnt
- * field.
- */
-static DEFINE_SPINLOCK(all_channels_lock);
-static LIST_HEAD(all_channels);
-static LIST_HEAD(new_channels);
-static int last_channel_index;
 static atomic_t channel_count = ATOMIC_INIT(0);
 
+/* per-net private data for this module */
+static int ppp_net_id;
+struct ppp_net {
+	/* units to ppp mapping */
+	struct idr units_idr;
+
+	/*
+	 * all_ppp_mutex protects the units_idr mapping.
+	 * It also ensures that finding a ppp unit in the units_idr
+	 * map and updating its file.refcnt field is atomic.
+	 */
+	struct mutex all_ppp_mutex;
+
+	/* channels */
+	struct list_head all_channels;
+	struct list_head new_channels;
+	int last_channel_index;
+
+	/*
+	 * all_channels_lock protects all_channels and
+	 * last_channel_index, and the atomicity of find
+	 * a channel and updating its file.refcnt field.
+	 */
+	spinlock_t all_channels_lock;
+};
+
 /* Get the PPP protocol number from a skb */
 #define PPP_PROTO(skb)	(((skb)->data[0] << 8) + (skb)->data[1])
 
@@ -216,8 +232,8 @@ static atomic_t channel_count = ATOMIC_I
 #define seq_after(a, b)		((s32)((a) - (b)) > 0)
 
 /* Prototypes. */
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
-				unsigned int cmd, unsigned long arg);
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+			struct file *file, unsigned int cmd, unsigned long arg);
 static void ppp_xmit_process(struct ppp *ppp);
 static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
 static void ppp_push(struct ppp *ppp);
@@ -240,12 +256,12 @@ static void ppp_ccp_peek(struct ppp *ppp
 static void ppp_ccp_closed(struct ppp *ppp);
 static struct compressor *find_compressor(int type);
 static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
-static struct ppp *ppp_create_interface(int unit, int *retp);
+static struct ppp *ppp_create_interface(struct net *net, int unit, int *retp);
 static void init_ppp_file(struct ppp_file *pf, int kind);
 static void ppp_shutdown_interface(struct ppp *ppp);
 static void ppp_destroy_interface(struct ppp *ppp);
-static struct ppp *ppp_find_unit(int unit);
-static struct channel *ppp_find_channel(int unit);
+static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
+static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
 static int ppp_connect_channel(struct channel *pch, int unit);
 static int ppp_disconnect_channel(struct channel *pch);
 static void ppp_destroy_channel(struct channel *pch);
@@ -256,6 +272,14 @@ static void *unit_find(struct idr *p, in
 
 static struct class *ppp_class;
 
+/* per net-namespace data */
+static inline struct ppp_net *ppp_pernet(struct net *net)
+{
+	BUG_ON(!net);
+
+	return net_generic(net, ppp_net_id);
+}
+
 /* Translates a PPP protocol number to a NP index (NP == network protocol) */
 static inline int proto_to_npindex(int proto)
 {
@@ -544,7 +568,8 @@ static long ppp_ioctl(struct file *file,
 	int __user *p = argp;
 
 	if (!pf)
-		return ppp_unattached_ioctl(pf, file, cmd, arg);
+		return ppp_unattached_ioctl(current->nsproxy->net_ns,
+					pf, file, cmd, arg);
 
 	if (cmd == PPPIOCDETACH) {
 		/*
@@ -763,12 +788,13 @@ static long ppp_ioctl(struct file *file,
 	return err;
 }
 
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
-				unsigned int cmd, unsigned long arg)
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+			struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int unit, err = -EFAULT;
 	struct ppp *ppp;
 	struct channel *chan;
+	struct ppp_net *pn;
 	int __user *p = (int __user *)arg;
 
 	lock_kernel();
@@ -777,7 +803,7 @@ static int ppp_unattached_ioctl(struct p
 		/* Create a new ppp unit */
 		if (get_user(unit, p))
 			break;
-		ppp = ppp_create_interface(unit, &err);
+		ppp = ppp_create_interface(net, unit, &err);
 		if (!ppp)
 			break;
 		file->private_data = &ppp->file;
@@ -792,29 +818,31 @@ static int ppp_unattached_ioctl(struct p
 		/* Attach to an existing ppp unit */
 		if (get_user(unit, p))
 			break;
-		mutex_lock(&all_ppp_mutex);
 		err = -ENXIO;
-		ppp = ppp_find_unit(unit);
+		pn = ppp_pernet(net);
+		mutex_lock(&pn->all_ppp_mutex);
+		ppp = ppp_find_unit(pn, unit);
 		if (ppp) {
 			atomic_inc(&ppp->file.refcnt);
 			file->private_data = &ppp->file;
 			err = 0;
 		}
-		mutex_unlock(&all_ppp_mutex);
+		mutex_unlock(&pn->all_ppp_mutex);
 		break;
 
 	case PPPIOCATTCHAN:
 		if (get_user(unit, p))
 			break;
-		spin_lock_bh(&all_channels_lock);
 		err = -ENXIO;
-		chan = ppp_find_channel(unit);
+		pn = ppp_pernet(net);
+		spin_lock_bh(&pn->all_channels_lock);
+		chan = ppp_find_channel(pn, unit);
 		if (chan) {
 			atomic_inc(&chan->file.refcnt);
 			file->private_data = &chan->file;
 			err = 0;
 		}
-		spin_unlock_bh(&all_channels_lock);
+		spin_unlock_bh(&pn->all_channels_lock);
 		break;
 
 	default:
@@ -834,6 +862,51 @@ static const struct file_operations ppp_
 	.release	= ppp_release
 };
 
+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;
+
+	idr_init(&pn->units_idr);
+	mutex_init(&pn->all_ppp_mutex);
+
+	INIT_LIST_HEAD(&pn->all_channels);
+	INIT_LIST_HEAD(&pn->new_channels);
+
+	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;
+
+	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,
+};
+
 #define PPP_MAJOR	108
 
 /* Called at boot time if ppp is compiled into the kernel,
@@ -843,25 +916,36 @@ static int __init ppp_init(void)
 	int err;
 
 	printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
-	err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
-	if (!err) {
-		ppp_class = class_create(THIS_MODULE, "ppp");
-		if (IS_ERR(ppp_class)) {
-			err = PTR_ERR(ppp_class);
-			goto out_chrdev;
-		}
-		device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
-			      "ppp");
+
+	err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops);
+	if (err) {
+		printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err);
+		goto out;
 	}
 
-out:
-	if (err)
+	err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
+	if (err) {
 		printk(KERN_ERR "failed to register PPP device (%d)\n", err);
-	return err;
+		goto out_net;
+	}
+
+	ppp_class = class_create(THIS_MODULE, "ppp");
+	if (IS_ERR(ppp_class)) {
+		err = PTR_ERR(ppp_class);
+		goto out_chrdev;
+	}
+
+	/* not a big deal if we fail here :-) */
+	device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+
+	return 0;
 
 out_chrdev:
 	unregister_chrdev(PPP_MAJOR, "ppp");
-	goto out;
+out_net:
+	unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
+out:
+	return err;
 }
 
 /*
@@ -908,7 +992,7 @@ ppp_start_xmit(struct sk_buff *skb, stru
 
  outf:
 	kfree_skb(skb);
-	++ppp->dev->stats.tx_dropped;
+	++dev->stats.tx_dropped;
 	return 0;
 }
 
@@ -969,6 +1053,7 @@ static void ppp_setup(struct net_device
 	dev->tx_queue_len = 3;
 	dev->type = ARPHRD_PPP;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+	dev->features |= NETIF_F_NETNS_LOCAL;
 }
 
 /*
@@ -1161,8 +1246,7 @@ ppp_send_frame(struct ppp *ppp, struct s
 	return;
 
  drop:
-	if (skb)
-		kfree_skb(skb);
+	kfree_skb(skb);
 	++ppp->dev->stats.tx_errors;
 }
 
@@ -1224,138 +1308,181 @@ ppp_push(struct ppp *ppp)
  */
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 {
-	int len, fragsize;
-	int i, bits, hdrlen, mtu;
-	int flen;
-	int navail, nfree;
-	int nbigger;
+	int	len, totlen;
+	int	i, bits, hdrlen, mtu;
+	int	flen;
+	int	navail,	nfree, nzero;
+	int	nbigger;
+	int	totspeed;
+	int	totfree;
 	unsigned char *p, *q;
 	struct list_head *list;
 	struct channel *pch;
 	struct sk_buff *frag;
 	struct ppp_channel *chan;
 
-	nfree = 0;	/* # channels which have no packet already queued */
+	totspeed = 0; /*total bitrate of the bundle*/
+	nfree =	0;	/* # channels which	have no	packet already queued */
 	navail = 0;	/* total # of usable channels (not deregistered) */
+	nzero =	0; /* number of	channels with zero speed associated*/
+	totfree	= 0; /*total # of channels available and
+				  *having no queued packets before
+				  *starting the fragmentation*/
+
 	hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
-	i = 0;
-	list_for_each_entry(pch, &ppp->channels, clist) {
+	i =	0;
+	list_for_each_entry(pch, &ppp->channels, clist)	{
 		navail += pch->avail = (pch->chan != NULL);
-		if (pch->avail) {
+		pch->speed = pch->chan->speed;
+		if (pch->avail)	{
 			if (skb_queue_empty(&pch->file.xq) ||
-			    !pch->had_frag) {
-				pch->avail = 2;
-				++nfree;
-			}
-			if (!pch->had_frag && i < ppp->nxchan)
-				ppp->nxchan = i;
+				!pch->had_frag)	{
+					if (pch->speed == 0)
+						nzero++;
+					else
+						totspeed += pch->speed;
+
+					pch->avail = 2;
+					++nfree;
+					++totfree;
+				}
+			if (!pch->had_frag && i	< ppp->nxchan)
+				ppp->nxchan	= i;
 		}
 		++i;
 	}
-
 	/*
-	 * Don't start sending this packet unless at least half of
-	 * the channels are free.  This gives much better TCP
-	 * performance if we have a lot of channels.
+	 * Don't start sending this	packet unless at least half	of
+	 * the channels	are	free.  This	gives much better TCP
+	 * performance if we have a	lot	of channels.
 	 */
-	if (nfree == 0 || nfree < navail / 2)
-		return 0;	/* can't take now, leave it in xmit_pending */
+	if (nfree == 0 || nfree	< navail / 2)
+		return 0; /* can't take now, leave it in xmit_pending	*/
 
 	/* Do protocol field compression (XXX this should be optional) */
-	p = skb->data;
-	len = skb->len;
+	p =	skb->data;
+	len	= skb->len;
 	if (*p == 0) {
 		++p;
 		--len;
 	}
 
-	/*
-	 * Decide on fragment size.
-	 * We create a fragment for each free channel regardless of
-	 * how small they are (i.e. even 0 length) in order to minimize
-	 * the time that it will take to detect when a channel drops
-	 * a fragment.
-	 */
-	fragsize = len;
-	if (nfree > 1)
-		fragsize = DIV_ROUND_UP(fragsize, nfree);
-	/* nbigger channels get fragsize bytes, the rest get fragsize-1,
-	   except if nbigger==0, then they all get fragsize. */
-	nbigger = len % nfree;
+	totlen = len;
+	nbigger	= len %	nfree;
 
-	/* skip to the channel after the one we last used
-	   and start at that one */
+	/* skip	to the channel after the one we	last used
+	   and start at	that one */
 	list = &ppp->channels;
-	for (i = 0; i < ppp->nxchan; ++i) {
+	for	(i = 0;	i <	ppp->nxchan; ++i) {
 		list = list->next;
-		if (list == &ppp->channels) {
-			i = 0;
+		if (list ==	&ppp->channels)	{
+			i =	0;
 			break;
 		}
 	}
 
-	/* create a fragment for each channel */
+	/* create a	fragment for each channel */
 	bits = B;
-	while (nfree > 0 || len > 0) {
+	while (nfree > 0 &&	len	> 0) {
 		list = list->next;
-		if (list == &ppp->channels) {
-			i = 0;
+		if (list ==	&ppp->channels)	{
+			i =	0;
 			continue;
 		}
-		pch = list_entry(list, struct channel, clist);
+		pch	= list_entry(list, struct channel, clist);
 		++i;
 		if (!pch->avail)
 			continue;
 
 		/*
-		 * Skip this channel if it has a fragment pending already and
-		 * we haven't given a fragment to all of the free channels.
+		 * Skip	this channel if	it has a fragment pending already and
+		 * we haven't given	a fragment to all of the free channels.
 		 */
 		if (pch->avail == 1) {
-			if (nfree > 0)
+			if (nfree >	0)
 				continue;
 		} else {
-			--nfree;
 			pch->avail = 1;
 		}
 
 		/* check the channel's mtu and whether it is still attached. */
 		spin_lock_bh(&pch->downl);
 		if (pch->chan == NULL) {
-			/* can't use this channel, it's being deregistered */
+			/* can't use this channel, it's	being deregistered */
+			if (pch->speed == 0)
+				nzero--;
+			else
+				totspeed -=	pch->speed;
+
 			spin_unlock_bh(&pch->downl);
 			pch->avail = 0;
-			if (--navail == 0)
+			totlen = len;
+			totfree--;
+			nfree--;
+			if (--navail ==	0)
 				break;
 			continue;
 		}
 
 		/*
-		 * Create a fragment for this channel of
-		 * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
-		 * If mtu+2-hdrlen < 4, that is a ridiculously small
-		 * MTU, so we use mtu = 2 + hdrlen.
+		*if the channel speed is not set divide
+		*the packet	evenly among the free channels;
+		*otherwise divide it according to the speed
+		*of the channel we are going to transmit on
+		*/
+		if (pch->speed == 0) {
+			flen = totlen/nfree	;
+			if (nbigger > 0) {
+				flen++;
+				nbigger--;
+			}
+		} else {
+			flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+				((totspeed*totfree)/pch->speed)) - hdrlen;
+			if (nbigger > 0) {
+				flen += ((totfree - nzero)*pch->speed)/totspeed;
+				nbigger -= ((totfree - nzero)*pch->speed)/
+							totspeed;
+			}
+		}
+		nfree--;
+
+		/*
+		 *check	if we are on the last channel or
+		 *we exceded the lenght	of the data	to
+		 *fragment
 		 */
-		if (fragsize > len)
-			fragsize = len;
-		flen = fragsize;
-		mtu = pch->chan->mtu + 2 - hdrlen;
-		if (mtu < 4)
-			mtu = 4;
+		if ((nfree == 0) || (flen > len))
+			flen = len;
+		/*
+		 *it is not worth to tx on slow channels:
+		 *in that case from the resulting flen according to the
+		 *above formula will be equal or less than zero.
+		 *Skip the channel in this case
+		 */
+		if (flen <=	0) {
+			pch->avail = 2;
+			spin_unlock_bh(&pch->downl);
+			continue;
+		}
+
+		mtu	= pch->chan->mtu + 2 - hdrlen;
+		if (mtu	< 4)
+			mtu	= 4;
 		if (flen > mtu)
 			flen = mtu;
-		if (flen == len && nfree == 0)
-			bits |= E;
-		frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+		if (flen ==	len)
+			bits |=	E;
+		frag = alloc_skb(flen +	hdrlen + (flen == 0), GFP_ATOMIC);
 		if (!frag)
 			goto noskb;
-		q = skb_put(frag, flen + hdrlen);
+		q =	skb_put(frag, flen + hdrlen);
 
-		/* make the MP header */
+		/* make	the	MP header */
 		q[0] = PPP_MP >> 8;
 		q[1] = PPP_MP;
 		if (ppp->flags & SC_MP_XSHORTSEQ) {
-			q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+			q[2] = bits	+ ((ppp->nxseq >> 8) & 0xf);
 			q[3] = ppp->nxseq;
 		} else {
 			q[2] = bits;
@@ -1364,43 +1491,28 @@ static int ppp_mp_explode(struct ppp *pp
 			q[5] = ppp->nxseq;
 		}
 
-		/*
-		 * Copy the data in.
-		 * Unfortunately there is a bug in older versions of
-		 * the Linux PPP multilink reconstruction code where it
-		 * drops 0-length fragments.  Therefore we make sure the
-		 * fragment has at least one byte of data.  Any bytes
-		 * we add in this situation will end up as padding on the
-		 * end of the reconstructed packet.
-		 */
-		if (flen == 0)
-			*skb_put(frag, 1) = 0;
-		else
-			memcpy(q + hdrlen, p, flen);
+		memcpy(q + hdrlen, p, flen);
 
 		/* try to send it down the channel */
 		chan = pch->chan;
-		if (!skb_queue_empty(&pch->file.xq) ||
-		    !chan->ops->start_xmit(chan, frag))
+		if (!skb_queue_empty(&pch->file.xq)	||
+			!chan->ops->start_xmit(chan, frag))
 			skb_queue_tail(&pch->file.xq, frag);
-		pch->had_frag = 1;
+		pch->had_frag =	1;
 		p += flen;
-		len -= flen;
+		len	-= flen;
 		++ppp->nxseq;
 		bits = 0;
 		spin_unlock_bh(&pch->downl);
-
-		if (--nbigger == 0 && fragsize > 0)
-			--fragsize;
 	}
-	ppp->nxchan = i;
+	ppp->nxchan	= i;
 
 	return 1;
 
  noskb:
 	spin_unlock_bh(&pch->downl);
 	if (ppp->debug & 1)
-		printk(KERN_ERR "PPP: no memory (fragment)\n");
+		printk(KERN_ERR	"PPP: no memory	(fragment)\n");
 	++ppp->dev->stats.tx_errors;
 	++ppp->nxseq;
 	return 1;	/* abandon the frame */
@@ -1986,19 +2098,27 @@ ppp_mp_reconstruct(struct ppp *ppp)
  * Channel interface.
  */
 
-/*
- * Create a new, unattached ppp channel.
- */
-int
-ppp_register_channel(struct ppp_channel *chan)
+/* Create a new, unattached ppp channel. */
+int ppp_register_channel(struct ppp_channel *chan)
+{
+	return ppp_register_net_channel(current->nsproxy->net_ns, chan);
+}
+
+/* Create a new, unattached ppp channel for specified net. */
+int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
 {
 	struct channel *pch;
+	struct ppp_net *pn;
 
 	pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
 	if (!pch)
 		return -ENOMEM;
+
+	pn = ppp_pernet(net);
+
 	pch->ppp = NULL;
 	pch->chan = chan;
+	pch->chan_net = net;
 	chan->ppp = pch;
 	init_ppp_file(&pch->file, CHANNEL);
 	pch->file.hdrlen = chan->hdrlen;
@@ -2008,11 +2128,13 @@ ppp_register_channel(struct ppp_channel
 	init_rwsem(&pch->chan_sem);
 	spin_lock_init(&pch->downl);
 	rwlock_init(&pch->upl);
-	spin_lock_bh(&all_channels_lock);
-	pch->file.index = ++last_channel_index;
-	list_add(&pch->list, &new_channels);
+
+	spin_lock_bh(&pn->all_channels_lock);
+	pch->file.index = ++pn->last_channel_index;
+	list_add(&pch->list, &pn->new_channels);
 	atomic_inc(&channel_count);
-	spin_unlock_bh(&all_channels_lock);
+	spin_unlock_bh(&pn->all_channels_lock);
+
 	return 0;
 }
 
@@ -2053,9 +2175,11 @@ void
 ppp_unregister_channel(struct ppp_channel *chan)
 {
 	struct channel *pch = chan->ppp;
+	struct ppp_net *pn;
 
 	if (!pch)
 		return;		/* should never happen */
+
 	chan->ppp = NULL;
 
 	/*
@@ -2068,9 +2192,12 @@ ppp_unregister_channel(struct ppp_channe
 	spin_unlock_bh(&pch->downl);
 	up_write(&pch->chan_sem);
 	ppp_disconnect_channel(pch);
-	spin_lock_bh(&all_channels_lock);
+
+	pn = ppp_pernet(pch->chan_net);
+	spin_lock_bh(&pn->all_channels_lock);
 	list_del(&pch->list);
-	spin_unlock_bh(&all_channels_lock);
+	spin_unlock_bh(&pn->all_channels_lock);
+
 	pch->file.dead = 1;
 	wake_up_interruptible(&pch->file.rwait);
 	if (atomic_dec_and_test(&pch->file.refcnt))
@@ -2395,9 +2522,10 @@ ppp_get_stats(struct ppp *ppp, struct pp
  * unit == -1 means allocate a new number.
  */
 static struct ppp *
-ppp_create_interface(int unit, int *retp)
+ppp_create_interface(struct net *net, int unit, int *retp)
 {
 	struct ppp *ppp;
+	struct ppp_net *pn;
 	struct net_device *dev = NULL;
 	int ret = -ENOMEM;
 	int i;
@@ -2406,6 +2534,8 @@ ppp_create_interface(int unit, int *retp
 	if (!dev)
 		goto out1;
 
+	pn = ppp_pernet(net);
+
 	ppp = netdev_priv(dev);
 	ppp->dev = dev;
 	ppp->mru = PPP_MRU;
@@ -2421,17 +2551,23 @@ ppp_create_interface(int unit, int *retp
 	skb_queue_head_init(&ppp->mrq);
 #endif /* CONFIG_PPP_MULTILINK */
 
+	/*
+	 * drum roll: don't forget to set
+	 * the net device is belong to
+	 */
+	dev_net_set(dev, net);
+
 	ret = -EEXIST;
-	mutex_lock(&all_ppp_mutex);
+	mutex_lock(&pn->all_ppp_mutex);
 
 	if (unit < 0) {
-		unit = unit_get(&ppp_units_idr, ppp);
+		unit = unit_get(&pn->units_idr, ppp);
 		if (unit < 0) {
 			*retp = unit;
 			goto out2;
 		}
 	} else {
-		if (unit_find(&ppp_units_idr, unit))
+		if (unit_find(&pn->units_idr, unit))
 			goto out2; /* unit already exists */
 		/*
 		 * if caller need a specified unit number
@@ -2442,7 +2578,7 @@ ppp_create_interface(int unit, int *retp
 		 * fair but at least pppd will ask us to allocate
 		 * new unit in this case so user is happy :)
 		 */
-		unit = unit_set(&ppp_units_idr, ppp, unit);
+		unit = unit_set(&pn->units_idr, ppp, unit);
 		if (unit < 0)
 			goto out2;
 	}
@@ -2453,20 +2589,22 @@ ppp_create_interface(int unit, int *retp
 
 	ret = register_netdev(dev);
 	if (ret != 0) {
-		unit_put(&ppp_units_idr, unit);
+		unit_put(&pn->units_idr, unit);
 		printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
 		       dev->name, ret);
 		goto out2;
 	}
 
+	ppp->ppp_net = net;
+
 	atomic_inc(&ppp_unit_count);
-	mutex_unlock(&all_ppp_mutex);
+	mutex_unlock(&pn->all_ppp_mutex);
 
 	*retp = 0;
 	return ppp;
 
 out2:
-	mutex_unlock(&all_ppp_mutex);
+	mutex_unlock(&pn->all_ppp_mutex);
 	free_netdev(dev);
 out1:
 	*retp = ret;
@@ -2492,7 +2630,11 @@ init_ppp_file(struct ppp_file *pf, int k
  */
 static void ppp_shutdown_interface(struct ppp *ppp)
 {
-	mutex_lock(&all_ppp_mutex);
+	struct ppp_net *pn;
+
+	pn = ppp_pernet(ppp->ppp_net);
+	mutex_lock(&pn->all_ppp_mutex);
+
 	/* This will call dev_close() for us. */
 	ppp_lock(ppp);
 	if (!ppp->closing) {
@@ -2502,11 +2644,12 @@ static void ppp_shutdown_interface(struc
 	} else
 		ppp_unlock(ppp);
 
-	unit_put(&ppp_units_idr, ppp->file.index);
+	unit_put(&pn->units_idr, ppp->file.index);
 	ppp->file.dead = 1;
 	ppp->owner = NULL;
 	wake_up_interruptible(&ppp->file.rwait);
-	mutex_unlock(&all_ppp_mutex);
+
+	mutex_unlock(&pn->all_ppp_mutex);
 }
 
 /*
@@ -2543,8 +2686,7 @@ static void ppp_destroy_interface(struct
 	ppp->active_filter = NULL;
 #endif /* CONFIG_PPP_FILTER */
 
-	if (ppp->xmit_pending)
-		kfree_skb(ppp->xmit_pending);
+	kfree_skb(ppp->xmit_pending);
 
 	free_netdev(ppp->dev);
 }
@@ -2554,9 +2696,9 @@ static void ppp_destroy_interface(struct
  * The caller should have locked the all_ppp_mutex.
  */
 static struct ppp *
-ppp_find_unit(int unit)
+ppp_find_unit(struct ppp_net *pn, int unit)
 {
-	return unit_find(&ppp_units_idr, unit);
+	return unit_find(&pn->units_idr, unit);
 }
 
 /*
@@ -2568,20 +2710,22 @@ ppp_find_unit(int unit)
  * when we have a lot of channels in use.
  */
 static struct channel *
-ppp_find_channel(int unit)
+ppp_find_channel(struct ppp_net *pn, int unit)
 {
 	struct channel *pch;
 
-	list_for_each_entry(pch, &new_channels, list) {
+	list_for_each_entry(pch, &pn->new_channels, list) {
 		if (pch->file.index == unit) {
-			list_move(&pch->list, &all_channels);
+			list_move(&pch->list, &pn->all_channels);
 			return pch;
 		}
 	}
-	list_for_each_entry(pch, &all_channels, list) {
+
+	list_for_each_entry(pch, &pn->all_channels, list) {
 		if (pch->file.index == unit)
 			return pch;
 	}
+
 	return NULL;
 }
 
@@ -2592,11 +2736,14 @@ static int
 ppp_connect_channel(struct channel *pch, int unit)
 {
 	struct ppp *ppp;
+	struct ppp_net *pn;
 	int ret = -ENXIO;
 	int hdrlen;
 
-	mutex_lock(&all_ppp_mutex);
-	ppp = ppp_find_unit(unit);
+	pn = ppp_pernet(pch->chan_net);
+
+	mutex_lock(&pn->all_ppp_mutex);
+	ppp = ppp_find_unit(pn, unit);
 	if (!ppp)
 		goto out;
 	write_lock_bh(&pch->upl);
@@ -2620,7 +2767,7 @@ ppp_connect_channel(struct channel *pch,
  outl:
 	write_unlock_bh(&pch->upl);
  out:
-	mutex_unlock(&all_ppp_mutex);
+	mutex_unlock(&pn->all_ppp_mutex);
 	return ret;
 }
 
@@ -2677,7 +2824,7 @@ static void __exit ppp_cleanup(void)
 	unregister_chrdev(PPP_MAJOR, "ppp");
 	device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
 	class_destroy(ppp_class);
-	idr_destroy(&ppp_units_idr);
+	unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
 }
 
 /*
@@ -2743,6 +2890,7 @@ static void *unit_find(struct idr *p, in
 module_init(ppp_init);
 module_exit(ppp_cleanup);
 
+EXPORT_SYMBOL(ppp_register_net_channel);
 EXPORT_SYMBOL(ppp_register_channel);
 EXPORT_SYMBOL(ppp_unregister_channel);
 EXPORT_SYMBOL(ppp_channel_index);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pppoe.c linux-libre-2.6.30-gnu1/drivers/net/pppoe.c
--- linux-libre-2.6.29-gnu1/drivers/net/pppoe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pppoe.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,38 +78,73 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <linux/nsproxy.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
 
 #define PPPOE_HASH_BITS 4
-#define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS)
-
-static struct ppp_channel_ops pppoe_chan_ops;
+#define PPPOE_HASH_SIZE (1 << PPPOE_HASH_BITS)
+#define PPPOE_HASH_MASK	(PPPOE_HASH_SIZE - 1)
 
 static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
 static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
 
 static const struct proto_ops pppoe_ops;
-static DEFINE_RWLOCK(pppoe_hash_lock);
-
 static struct ppp_channel_ops pppoe_chan_ops;
 
+/* per-net private data for this module */
+static int pppoe_net_id;
+struct pppoe_net {
+	/*
+	 * we could use _single_ hash table for all
+	 * nets by injecting net id into the hash but
+	 * it would increase hash chains and add
+	 * a few additional math comparations messy
+	 * as well, moreover in case of SMP less locking
+	 * controversy here
+	 */
+	struct pppox_sock *hash_table[PPPOE_HASH_SIZE];
+	rwlock_t hash_lock;
+};
+
+/* to eliminate a race btw pppoe_flush_dev and pppoe_release */
+static DEFINE_SPINLOCK(flush_lock);
+
+/*
+ * PPPoE could be in the following stages:
+ * 1) Discovery stage (to obtain remote MAC and Session ID)
+ * 2) Session stage (MAC and SID are known)
+ *
+ * Ethernet frames have a special tag for this but
+ * we use simplier approach based on session id
+ */
+static inline bool stage_session(__be16 sid)
+{
+	return sid != 0;
+}
+
+static inline struct pppoe_net *pppoe_pernet(struct net *net)
+{
+	BUG_ON(!net);
+
+	return net_generic(net, pppoe_net_id);
+}
+
 static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b)
 {
-	return (a->sid == b->sid &&
-		(memcmp(a->remote, b->remote, ETH_ALEN) == 0));
+	return a->sid == b->sid && !memcmp(a->remote, b->remote, ETH_ALEN);
 }
 
 static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr)
 {
-	return (a->sid == sid &&
-		(memcmp(a->remote,addr,ETH_ALEN) == 0));
+	return a->sid == sid && !memcmp(a->remote, addr, ETH_ALEN);
 }
 
-#if 8%PPPOE_HASH_BITS
+#if 8 % PPPOE_HASH_BITS
 #error 8 must be a multiple of PPPOE_HASH_BITS
 #endif
 
@@ -118,69 +153,71 @@ static int hash_item(__be16 sid, unsigne
 	unsigned char hash = 0;
 	unsigned int i;
 
-	for (i = 0 ; i < ETH_ALEN ; i++) {
+	for (i = 0; i < ETH_ALEN; i++)
 		hash ^= addr[i];
-	}
-	for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){
-		hash ^= (__force __u32)sid>>i;
-	}
-	for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
-		hash ^= hash>>i;
-	}
+	for (i = 0; i < sizeof(sid_t) * 8; i += 8)
+		hash ^= (__force __u32)sid >> i;
+	for (i = 8; (i >>= 1) >= PPPOE_HASH_BITS;)
+		hash ^= hash >> i;
 
-	return hash & ( PPPOE_HASH_SIZE - 1 );
+	return hash & PPPOE_HASH_MASK;
 }
 
-/* zeroed because its in .bss */
-static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE];
-
 /**********************************************************************
  *
  *  Set/get/delete/rehash items  (internal versions)
  *
  **********************************************************************/
-static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifindex)
+static struct pppox_sock *__get_item(struct pppoe_net *pn, __be16 sid,
+				unsigned char *addr, int ifindex)
 {
 	int hash = hash_item(sid, addr);
 	struct pppox_sock *ret;
 
-	ret = item_hash_table[hash];
+	ret = pn->hash_table[hash];
+	while (ret) {
+		if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+		    ret->pppoe_ifindex == ifindex)
+			return ret;
 
-	while (ret && !(cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex))
 		ret = ret->next;
+	}
 
-	return ret;
+	return NULL;
 }
 
-static int __set_item(struct pppox_sock *po)
+static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
 {
 	int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
 	struct pppox_sock *ret;
 
-	ret = item_hash_table[hash];
+	ret = pn->hash_table[hash];
 	while (ret) {
-		if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && ret->pppoe_ifindex == po->pppoe_ifindex)
+		if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) &&
+		    ret->pppoe_ifindex == po->pppoe_ifindex)
 			return -EALREADY;
 
 		ret = ret->next;
 	}
 
-	po->next = item_hash_table[hash];
-	item_hash_table[hash] = po;
+	po->next = pn->hash_table[hash];
+	pn->hash_table[hash] = po;
 
 	return 0;
 }
 
-static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
+static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid,
+					char *addr, int ifindex)
 {
 	int hash = hash_item(sid, addr);
 	struct pppox_sock *ret, **src;
 
-	ret = item_hash_table[hash];
-	src = &item_hash_table[hash];
+	ret = pn->hash_table[hash];
+	src = &pn->hash_table[hash];
 
 	while (ret) {
-		if (cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex) {
+		if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+		    ret->pppoe_ifindex == ifindex) {
 			*src = ret->next;
 			break;
 		}
@@ -197,46 +234,54 @@ static struct pppox_sock *__delete_item(
  *  Set/get/delete/rehash items
  *
  **********************************************************************/
-static inline struct pppox_sock *get_item(__be16 sid,
-					 unsigned char *addr, int ifindex)
+static inline struct pppox_sock *get_item(struct pppoe_net *pn, __be16 sid,
+					unsigned char *addr, int ifindex)
 {
 	struct pppox_sock *po;
 
-	read_lock_bh(&pppoe_hash_lock);
-	po = __get_item(sid, addr, ifindex);
+	read_lock_bh(&pn->hash_lock);
+	po = __get_item(pn, sid, addr, ifindex);
 	if (po)
 		sock_hold(sk_pppox(po));
-	read_unlock_bh(&pppoe_hash_lock);
+	read_unlock_bh(&pn->hash_lock);
 
 	return po;
 }
 
-static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp)
+static inline struct pppox_sock *get_item_by_addr(struct net *net,
+						struct sockaddr_pppox *sp)
 {
 	struct net_device *dev;
+	struct pppoe_net *pn;
+	struct pppox_sock *pppox_sock;
+
 	int ifindex;
 
-	dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
-	if(!dev)
+	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,
+				sp->sa_addr.pppoe.remote, ifindex);
 	dev_put(dev);
-	return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex);
+
+	return pppox_sock;
 }
 
-static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex)
+static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid,
+					char *addr, int ifindex)
 {
 	struct pppox_sock *ret;
 
-	write_lock_bh(&pppoe_hash_lock);
-	ret = __delete_item(sid, addr, ifindex);
-	write_unlock_bh(&pppoe_hash_lock);
+	write_lock_bh(&pn->hash_lock);
+	ret = __delete_item(pn, sid, addr, ifindex);
+	write_unlock_bh(&pn->hash_lock);
 
 	return ret;
 }
 
-
-
 /***************************************************************************
  *
  *  Handler for device events.
@@ -246,25 +291,33 @@ static inline struct pppox_sock *delete_
 
 static void pppoe_flush_dev(struct net_device *dev)
 {
-	int hash;
+	struct pppoe_net *pn;
+	int i;
+
 	BUG_ON(dev == NULL);
 
-	write_lock_bh(&pppoe_hash_lock);
-	for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) {
-		struct pppox_sock *po = item_hash_table[hash];
+	pn = pppoe_pernet(dev_net(dev));
+	if (!pn) /* already freed */
+		return;
+
+	write_lock_bh(&pn->hash_lock);
+	for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+		struct pppox_sock *po = pn->hash_table[i];
 
 		while (po != NULL) {
-			struct sock *sk = sk_pppox(po);
+			struct sock *sk;
 			if (po->pppoe_dev != dev) {
 				po = po->next;
 				continue;
 			}
+			sk = sk_pppox(po);
+			spin_lock(&flush_lock);
 			po->pppoe_dev = NULL;
+			spin_unlock(&flush_lock);
 			dev_put(dev);
 
-
 			/* We always grab the socket lock, followed by the
-			 * pppoe_hash_lock, in that order.  Since we should
+			 * hash_lock, in that order.  Since we should
 			 * hold the sock lock while doing any unbinding,
 			 * we need to release the lock we're holding.
 			 * Hold a reference to the sock so it doesn't disappear
@@ -273,7 +326,7 @@ static void pppoe_flush_dev(struct net_d
 
 			sock_hold(sk);
 
-			write_unlock_bh(&pppoe_hash_lock);
+			write_unlock_bh(&pn->hash_lock);
 			lock_sock(sk);
 
 			if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -289,20 +342,17 @@ static void pppoe_flush_dev(struct net_d
 			 * While the lock was dropped the chain contents may
 			 * have changed.
 			 */
-			write_lock_bh(&pppoe_hash_lock);
-			po = item_hash_table[hash];
+			write_lock_bh(&pn->hash_lock);
+			po = pn->hash_table[i];
 		}
 	}
-	write_unlock_bh(&pppoe_hash_lock);
+	write_unlock_bh(&pn->hash_lock);
 }
 
 static int pppoe_device_event(struct notifier_block *this,
 			      unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *) ptr;
-
-	if (dev_net(dev) != &init_net)
-		return NOTIFY_DONE;
+	struct net_device *dev = (struct net_device *)ptr;
 
 	/* Only look at sockets that are using this specific device. */
 	switch (event) {
@@ -324,12 +374,10 @@ static int pppoe_device_event(struct not
 	return NOTIFY_DONE;
 }
 
-
 static struct notifier_block pppoe_notifier = {
 	.notifier_call = pppoe_device_event,
 };
 
-
 /************************************************************************
  *
  * Do the real work of receiving a PPPoE Session frame.
@@ -343,8 +391,8 @@ static int pppoe_rcv_core(struct sock *s
 	if (sk->sk_state & PPPOX_BOUND) {
 		ppp_input(&po->chan, skb);
 	} else if (sk->sk_state & PPPOX_RELAY) {
-		relay_po = get_item_by_addr(&po->pppoe_relay);
-
+		relay_po = get_item_by_addr(dev_net(po->pppoe_dev),
+						&po->pppoe_relay);
 		if (relay_po == NULL)
 			goto abort_kfree;
 
@@ -373,22 +421,18 @@ abort_kfree:
  * Receive wrapper called in BH context.
  *
  ***********************************************************************/
-static int pppoe_rcv(struct sk_buff *skb,
-		     struct net_device *dev,
-		     struct packet_type *pt,
-		     struct net_device *orig_dev)
-
+static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
+		     struct packet_type *pt, struct net_device *orig_dev)
 {
 	struct pppoe_hdr *ph;
 	struct pppox_sock *po;
+	struct pppoe_net *pn;
 	int len;
 
-	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
 		goto out;
 
-	if (dev_net(dev) != &init_net)
-		goto drop;
-
 	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
 		goto drop;
 
@@ -402,7 +446,8 @@ static int pppoe_rcv(struct sk_buff *skb
 	if (pskb_trim_rcsum(skb, len))
 		goto drop;
 
-	po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+	pn = pppoe_pernet(dev_net(dev));
+	po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
 	if (!po)
 		goto drop;
 
@@ -420,19 +465,16 @@ out:
  * This is solely for detection of PADT frames
  *
  ***********************************************************************/
-static int pppoe_disc_rcv(struct sk_buff *skb,
-			  struct net_device *dev,
-			  struct packet_type *pt,
-			  struct net_device *orig_dev)
+static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev,
+			  struct packet_type *pt, struct net_device *orig_dev)
 
 {
 	struct pppoe_hdr *ph;
 	struct pppox_sock *po;
+	struct pppoe_net *pn;
 
-	if (dev_net(dev) != &init_net)
-		goto abort;
-
-	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
 		goto out;
 
 	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
@@ -442,7 +484,8 @@ static int pppoe_disc_rcv(struct sk_buff
 	if (ph->code != PADT_CODE)
 		goto abort;
 
-	po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+	pn = pppoe_pernet(dev_net(dev));
+	po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
 	if (po) {
 		struct sock *sk = sk_pppox(po);
 
@@ -470,17 +513,17 @@ out:
 	return NET_RX_SUCCESS; /* Lies... :-) */
 }
 
-static struct packet_type pppoes_ptype = {
-	.type	= __constant_htons(ETH_P_PPP_SES),
+static struct packet_type pppoes_ptype __read_mostly = {
+	.type	= cpu_to_be16(ETH_P_PPP_SES),
 	.func	= pppoe_rcv,
 };
 
-static struct packet_type pppoed_ptype = {
-	.type	= __constant_htons(ETH_P_PPP_DISC),
+static struct packet_type pppoed_ptype __read_mostly = {
+	.type	= cpu_to_be16(ETH_P_PPP_DISC),
 	.func	= pppoe_disc_rcv,
 };
 
-static struct proto pppoe_sk_proto = {
+static struct proto pppoe_sk_proto __read_mostly = {
 	.name	  = "PPPOE",
 	.owner	  = THIS_MODULE,
 	.obj_size = sizeof(struct pppox_sock),
@@ -493,38 +536,37 @@ static struct proto pppoe_sk_proto = {
  **********************************************************************/
 static int pppoe_create(struct net *net, struct socket *sock)
 {
-	int error = -ENOMEM;
 	struct sock *sk;
 
 	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
 	if (!sk)
-		goto out;
+		return -ENOMEM;
 
 	sock_init_data(sock, sk);
 
-	sock->state = SS_UNCONNECTED;
-	sock->ops   = &pppoe_ops;
+	sock->state	= SS_UNCONNECTED;
+	sock->ops	= &pppoe_ops;
 
-	sk->sk_backlog_rcv = pppoe_rcv_core;
-	sk->sk_state	   = PPPOX_NONE;
-	sk->sk_type	   = SOCK_STREAM;
-	sk->sk_family	   = PF_PPPOX;
-	sk->sk_protocol	   = PX_PROTO_OE;
+	sk->sk_backlog_rcv	= pppoe_rcv_core;
+	sk->sk_state		= PPPOX_NONE;
+	sk->sk_type		= SOCK_STREAM;
+	sk->sk_family		= PF_PPPOX;
+	sk->sk_protocol		= PX_PROTO_OE;
 
-	error = 0;
-out:	return error;
+	return 0;
 }
 
 static int pppoe_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
 	struct pppox_sock *po;
+	struct pppoe_net *pn;
 
 	if (!sk)
 		return 0;
 
 	lock_sock(sk);
-	if (sock_flag(sk, SOCK_DEAD)){
+	if (sock_flag(sk, SOCK_DEAD)) {
 		release_sock(sk);
 		return -EBADF;
 	}
@@ -534,26 +576,39 @@ static int pppoe_release(struct socket *
 	/* Signal the death of the socket. */
 	sk->sk_state = PPPOX_DEAD;
 
+	/*
+	 * pppoe_flush_dev could lead to a race with
+	 * this routine so we use flush_lock to eliminate
+	 * such a case (we only need per-net specific data)
+	 */
+	spin_lock(&flush_lock);
+	po = pppox_sk(sk);
+	if (!po->pppoe_dev) {
+		spin_unlock(&flush_lock);
+		goto out;
+	}
+	pn = pppoe_pernet(dev_net(po->pppoe_dev));
+	spin_unlock(&flush_lock);
 
-	/* Write lock on hash lock protects the entire "po" struct from
-	 * concurrent updates via pppoe_flush_dev. The "po" struct should
-	 * be considered part of the hash table contents, thus protected
-	 * by the hash table lock */
-	write_lock_bh(&pppoe_hash_lock);
+	/*
+	 * protect "po" from concurrent updates
+	 * on pppoe_flush_dev
+	 */
+	write_lock_bh(&pn->hash_lock);
 
 	po = pppox_sk(sk);
-	if (po->pppoe_pa.sid) {
-		__delete_item(po->pppoe_pa.sid,
-			      po->pppoe_pa.remote, po->pppoe_ifindex);
-	}
+	if (stage_session(po->pppoe_pa.sid))
+		__delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
+				po->pppoe_ifindex);
 
 	if (po->pppoe_dev) {
 		dev_put(po->pppoe_dev);
 		po->pppoe_dev = NULL;
 	}
 
-	write_unlock_bh(&pppoe_hash_lock);
+	write_unlock_bh(&pn->hash_lock);
 
+out:
 	sock_orphan(sk);
 	sock->sk = NULL;
 
@@ -564,14 +619,14 @@ static int pppoe_release(struct socket *
 	return 0;
 }
 
-
 static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
 		  int sockaddr_len, int flags)
 {
 	struct sock *sk = sock->sk;
-	struct net_device *dev;
-	struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+	struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
 	struct pppox_sock *po = pppox_sk(sk);
+	struct net_device *dev;
+	struct pppoe_net *pn;
 	int error;
 
 	lock_sock(sk);
@@ -582,44 +637,45 @@ static int pppoe_connect(struct socket *
 
 	/* Check for already bound sockets */
 	error = -EBUSY;
-	if ((sk->sk_state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid)
+	if ((sk->sk_state & PPPOX_CONNECTED) &&
+	     stage_session(sp->sa_addr.pppoe.sid))
 		goto end;
 
 	/* Check for already disconnected sockets, on attempts to disconnect */
 	error = -EALREADY;
-	if ((sk->sk_state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid )
+	if ((sk->sk_state & PPPOX_DEAD) &&
+	     !stage_session(sp->sa_addr.pppoe.sid))
 		goto end;
 
 	error = 0;
-	if (po->pppoe_pa.sid) {
-		pppox_unbind_sock(sk);
-
-		/* Delete the old binding */
-		delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote,po->pppoe_ifindex);
 
-		if(po->pppoe_dev)
+	/* Delete the old binding */
+	if (stage_session(po->pppoe_pa.sid)) {
+		pppox_unbind_sock(sk);
+		if (po->pppoe_dev) {
+			pn = pppoe_pernet(dev_net(po->pppoe_dev));
+			delete_item(pn, po->pppoe_pa.sid,
+				po->pppoe_pa.remote, po->pppoe_ifindex);
 			dev_put(po->pppoe_dev);
-
+		}
 		memset(sk_pppox(po) + 1, 0,
 		       sizeof(struct pppox_sock) - sizeof(struct sock));
-
 		sk->sk_state = PPPOX_NONE;
 	}
 
-	/* Don't re-bind if sid==0 */
-	if (sp->sa_addr.pppoe.sid != 0) {
-		dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
-
+	/* Re-bind in session stage only */
+	if (stage_session(sp->sa_addr.pppoe.sid)) {
 		error = -ENODEV;
+		dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev);
 		if (!dev)
 			goto end;
 
 		po->pppoe_dev = dev;
 		po->pppoe_ifindex = dev->ifindex;
-
-		write_lock_bh(&pppoe_hash_lock);
-		if (!(dev->flags & IFF_UP)){
-			write_unlock_bh(&pppoe_hash_lock);
+		pn = pppoe_pernet(dev_net(dev));
+		write_lock_bh(&pn->hash_lock);
+		if (!(dev->flags & IFF_UP)) {
+			write_unlock_bh(&pn->hash_lock);
 			goto err_put;
 		}
 
@@ -627,8 +683,8 @@ static int pppoe_connect(struct socket *
 		       &sp->sa_addr.pppoe,
 		       sizeof(struct pppoe_addr));
 
-		error = __set_item(po);
-		write_unlock_bh(&pppoe_hash_lock);
+		error = __set_item(pn, po);
+		write_unlock_bh(&pn->hash_lock);
 		if (error < 0)
 			goto err_put;
 
@@ -639,7 +695,7 @@ static int pppoe_connect(struct socket *
 		po->chan.private = sk;
 		po->chan.ops = &pppoe_chan_ops;
 
-		error = ppp_register_channel(&po->chan);
+		error = ppp_register_net_channel(dev_net(dev), &po->chan);
 		if (error)
 			goto err_put;
 
@@ -648,7 +704,7 @@ static int pppoe_connect(struct socket *
 
 	po->num = sp->sa_addr.pppoe.sid;
 
- end:
+end:
 	release_sock(sk);
 	return error;
 err_put:
@@ -659,7 +715,6 @@ err_put:
 	goto end;
 }
 
-
 static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
 		  int *usockaddr_len, int peer)
 {
@@ -678,7 +733,6 @@ static int pppoe_getname(struct socket *
 	return 0;
 }
 
-
 static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
 		unsigned long arg)
 {
@@ -690,7 +744,6 @@ static int pppoe_ioctl(struct socket *so
 	switch (cmd) {
 	case PPPIOCGMRU:
 		err = -ENXIO;
-
 		if (!(sk->sk_state & PPPOX_CONNECTED))
 			break;
 
@@ -698,7 +751,7 @@ static int pppoe_ioctl(struct socket *so
 		if (put_user(po->pppoe_dev->mtu -
 			     sizeof(struct pppoe_hdr) -
 			     PPP_HDRLEN,
-			     (int __user *) arg))
+			     (int __user *)arg))
 			break;
 		err = 0;
 		break;
@@ -709,7 +762,7 @@ static int pppoe_ioctl(struct socket *so
 			break;
 
 		err = -EFAULT;
-		if (get_user(val,(int __user *) arg))
+		if (get_user(val, (int __user *)arg))
 			break;
 
 		if (val < (po->pppoe_dev->mtu
@@ -722,7 +775,7 @@ static int pppoe_ioctl(struct socket *so
 
 	case PPPIOCSFLAGS:
 		err = -EFAULT;
-		if (get_user(val, (int __user *) arg))
+		if (get_user(val, (int __user *)arg))
 			break;
 		err = 0;
 		break;
@@ -749,13 +802,12 @@ static int pppoe_ioctl(struct socket *so
 
 		err = -EINVAL;
 		if (po->pppoe_relay.sa_family != AF_PPPOX ||
-		    po->pppoe_relay.sa_protocol!= PX_PROTO_OE)
+		    po->pppoe_relay.sa_protocol != PX_PROTO_OE)
 			break;
 
 		/* Check that the socket referenced by the address
 		   actually exists. */
-		relay_po = get_item_by_addr(&po->pppoe_relay);
-
+		relay_po = get_item_by_addr(sock_net(sk), &po->pppoe_relay);
 		if (!relay_po)
 			break;
 
@@ -781,7 +833,6 @@ static int pppoe_ioctl(struct socket *so
 	return err;
 }
 
-
 static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
 		  struct msghdr *m, size_t total_len)
 {
@@ -808,7 +859,7 @@ static int pppoe_sendmsg(struct kiocb *i
 	dev = po->pppoe_dev;
 
 	error = -EMSGSIZE;
- 	if (total_len > (dev->mtu + dev->hard_header_len))
+	if (total_len > (dev->mtu + dev->hard_header_len))
 		goto end;
 
 
@@ -826,13 +877,12 @@ static int pppoe_sendmsg(struct kiocb *i
 	skb->dev = dev;
 
 	skb->priority = sk->sk_priority;
-	skb->protocol = __constant_htons(ETH_P_PPP_SES);
+	skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
 
-	ph = (struct pppoe_hdr *) skb_put(skb, total_len + sizeof(struct pppoe_hdr));
-	start = (char *) &ph->tag[0];
+	ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr));
+	start = (char *)&ph->tag[0];
 
 	error = memcpy_fromiovec(start, m->msg_iov, total_len);
-
 	if (error < 0) {
 		kfree_skb(skb);
 		goto end;
@@ -853,7 +903,6 @@ end:
 	return error;
 }
 
-
 /************************************************************************
  *
  * xmit function for internal use.
@@ -888,7 +937,7 @@ static int __pppoe_xmit(struct sock *sk,
 	ph->sid	= po->num;
 	ph->length = htons(data_len);
 
-	skb->protocol = __constant_htons(ETH_P_PPP_SES);
+	skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
 	skb->dev = dev;
 
 	dev_hard_header(skb, dev, ETH_P_PPP_SES,
@@ -903,7 +952,6 @@ abort:
 	return 1;
 }
 
-
 /************************************************************************
  *
  * xmit function called by generic PPP driver
@@ -912,11 +960,10 @@ abort:
  ***********************************************************************/
 static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
 {
-	struct sock *sk = (struct sock *) chan->private;
+	struct sock *sk = (struct sock *)chan->private;
 	return __pppoe_xmit(sk, skb);
 }
 
-
 static struct ppp_channel_ops pppoe_chan_ops = {
 	.start_xmit = pppoe_xmit,
 };
@@ -935,7 +982,6 @@ static int pppoe_recvmsg(struct kiocb *i
 
 	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
 				flags & MSG_DONTWAIT, &error);
-
 	if (error < 0)
 		goto end;
 
@@ -968,44 +1014,47 @@ static int pppoe_seq_show(struct seq_fil
 	dev_name = po->pppoe_pa.dev;
 
 	seq_printf(seq, "%08X %pM %8s\n",
-		   po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
+		po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
 out:
 	return 0;
 }
 
-static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos)
+static inline struct pppox_sock *pppoe_get_idx(struct pppoe_net *pn, loff_t pos)
 {
 	struct pppox_sock *po;
-	int i = 0;
+	int i;
 
-	for (; i < PPPOE_HASH_SIZE; i++) {
-		po = item_hash_table[i];
+	for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+		po = pn->hash_table[i];
 		while (po) {
 			if (!pos--)
 				goto out;
 			po = po->next;
 		}
 	}
+
 out:
 	return po;
 }
 
 static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
-	__acquires(pppoe_hash_lock)
+	__acquires(pn->hash_lock)
 {
+	struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
 	loff_t l = *pos;
 
-	read_lock_bh(&pppoe_hash_lock);
-	return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN;
+	read_lock_bh(&pn->hash_lock);
+	return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN;
 }
 
 static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+	struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
 	struct pppox_sock *po;
 
 	++*pos;
 	if (v == SEQ_START_TOKEN) {
-		po = pppoe_get_idx(0);
+		po = pppoe_get_idx(pn, 0);
 		goto out;
 	}
 	po = v;
@@ -1015,22 +1064,24 @@ static void *pppoe_seq_next(struct seq_f
 		int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
 
 		while (++hash < PPPOE_HASH_SIZE) {
-			po = item_hash_table[hash];
+			po = pn->hash_table[hash];
 			if (po)
 				break;
 		}
 	}
+
 out:
 	return po;
 }
 
 static void pppoe_seq_stop(struct seq_file *seq, void *v)
-	__releases(pppoe_hash_lock)
+	__releases(pn->hash_lock)
 {
-	read_unlock_bh(&pppoe_hash_lock);
+	struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
+	read_unlock_bh(&pn->hash_lock);
 }
 
-static struct seq_operations pppoe_seq_ops = {
+static const struct seq_operations pppoe_seq_ops = {
 	.start		= pppoe_seq_start,
 	.next		= pppoe_seq_next,
 	.stop		= pppoe_seq_stop,
@@ -1039,7 +1090,8 @@ static struct seq_operations pppoe_seq_o
 
 static int pppoe_seq_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &pppoe_seq_ops);
+	return seq_open_net(inode, file, &pppoe_seq_ops,
+			sizeof(struct seq_net_private));
 }
 
 static const struct file_operations pppoe_seq_fops = {
@@ -1047,74 +1099,115 @@ static const struct file_operations pppo
 	.open		= pppoe_seq_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= seq_release,
+	.release	= seq_release_net,
 };
 
-static int __init pppoe_proc_init(void)
-{
-	struct proc_dir_entry *p;
-
-	p = proc_net_fops_create(&init_net, "pppoe", S_IRUGO, &pppoe_seq_fops);
-	if (!p)
-		return -ENOMEM;
-	return 0;
-}
-#else /* CONFIG_PROC_FS */
-static inline int pppoe_proc_init(void) { return 0; }
 #endif /* CONFIG_PROC_FS */
 
 static const struct proto_ops pppoe_ops = {
-    .family		= AF_PPPOX,
-    .owner		= THIS_MODULE,
-    .release		= pppoe_release,
-    .bind		= sock_no_bind,
-    .connect		= pppoe_connect,
-    .socketpair		= sock_no_socketpair,
-    .accept		= sock_no_accept,
-    .getname		= pppoe_getname,
-    .poll		= datagram_poll,
-    .listen		= sock_no_listen,
-    .shutdown		= sock_no_shutdown,
-    .setsockopt		= sock_no_setsockopt,
-    .getsockopt		= sock_no_getsockopt,
-    .sendmsg		= pppoe_sendmsg,
-    .recvmsg		= pppoe_recvmsg,
-    .mmap		= sock_no_mmap,
-    .ioctl		= pppox_ioctl,
+	.family		= AF_PPPOX,
+	.owner		= THIS_MODULE,
+	.release	= pppoe_release,
+	.bind		= sock_no_bind,
+	.connect	= pppoe_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= sock_no_accept,
+	.getname	= pppoe_getname,
+	.poll		= datagram_poll,
+	.listen		= sock_no_listen,
+	.shutdown	= sock_no_shutdown,
+	.setsockopt	= sock_no_setsockopt,
+	.getsockopt	= sock_no_getsockopt,
+	.sendmsg	= pppoe_sendmsg,
+	.recvmsg	= pppoe_recvmsg,
+	.mmap		= sock_no_mmap,
+	.ioctl		= pppox_ioctl,
 };
 
 static struct pppox_proto pppoe_proto = {
-    .create	= pppoe_create,
-    .ioctl	= pppoe_ioctl,
-    .owner	= THIS_MODULE,
+	.create	= pppoe_create,
+	.ioctl	= pppoe_ioctl,
+	.owner	= THIS_MODULE,
 };
 
+static __net_init int pppoe_init_net(struct net *net)
+{
+	struct pppoe_net *pn;
+	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;
+	}
+#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,
+};
 
 static int __init pppoe_init(void)
 {
-	int err = proto_register(&pppoe_sk_proto, 0);
+	int err;
 
+	err = proto_register(&pppoe_sk_proto, 0);
 	if (err)
 		goto out;
 
- 	err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+	err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
 	if (err)
 		goto out_unregister_pppoe_proto;
 
-	err = pppoe_proc_init();
+	err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
 	if (err)
 		goto out_unregister_pppox_proto;
 
 	dev_add_pack(&pppoes_ptype);
 	dev_add_pack(&pppoed_ptype);
 	register_netdevice_notifier(&pppoe_notifier);
-out:
-	return err;
+
+	return 0;
+
 out_unregister_pppox_proto:
 	unregister_pppox_proto(PX_PROTO_OE);
 out_unregister_pppoe_proto:
 	proto_unregister(&pppoe_sk_proto);
-	goto out;
+out:
+	return err;
 }
 
 static void __exit pppoe_exit(void)
@@ -1123,7 +1216,7 @@ static void __exit pppoe_exit(void)
 	dev_remove_pack(&pppoes_ptype);
 	dev_remove_pack(&pppoed_ptype);
 	unregister_netdevice_notifier(&pppoe_notifier);
-	remove_proc_entry("pppoe", init_net.proc_net);
+	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
 	proto_unregister(&pppoe_sk_proto);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pppol2tp.c linux-libre-2.6.30-gnu1/drivers/net/pppol2tp.c
--- linux-libre-2.6.29-gnu1/drivers/net/pppol2tp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pppol2tp.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,7 +90,9 @@
 #include <linux/hash.h>
 #include <linux/sort.h>
 #include <linux/proc_fs.h>
+#include <linux/nsproxy.h>
 #include <net/net_namespace.h>
+#include <net/netns/generic.h>
 #include <net/dst.h>
 #include <net/ip.h>
 #include <net/udp.h>
@@ -204,6 +206,7 @@ struct pppol2tp_tunnel
 	struct sock		*sock;		/* Parent socket */
 	struct list_head	list;		/* Keep a list of all open
 						 * prepared sockets */
+	struct net		*pppol2tp_net;	/* the net we belong to */
 
 	atomic_t		ref_count;
 };
@@ -227,8 +230,20 @@ static atomic_t pppol2tp_tunnel_count;
 static atomic_t pppol2tp_session_count;
 static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
 static struct proto_ops pppol2tp_ops;
-static LIST_HEAD(pppol2tp_tunnel_list);
-static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* per-net private data for this module */
+static int pppol2tp_net_id;
+struct pppol2tp_net {
+	struct list_head pppol2tp_tunnel_list;
+	rwlock_t pppol2tp_tunnel_list_lock;
+};
+
+static inline struct pppol2tp_net *pppol2tp_pernet(struct net *net)
+{
+	BUG_ON(!net);
+
+	return net_generic(net, pppol2tp_net_id);
+}
 
 /* Helpers to obtain tunnel/session contexts from sockets.
  */
@@ -321,18 +336,19 @@ pppol2tp_session_find(struct pppol2tp_tu
 
 /* Lookup a tunnel by id
  */
-static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(struct net *net, u16 tunnel_id)
 {
-	struct pppol2tp_tunnel *tunnel = NULL;
+	struct pppol2tp_tunnel *tunnel;
+	struct pppol2tp_net *pn = pppol2tp_pernet(net);
 
-	read_lock_bh(&pppol2tp_tunnel_list_lock);
-	list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+	read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	list_for_each_entry(tunnel, &pn->pppol2tp_tunnel_list, list) {
 		if (tunnel->stats.tunnel_id == tunnel_id) {
-			read_unlock_bh(&pppol2tp_tunnel_list_lock);
+			read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 			return tunnel;
 		}
 	}
-	read_unlock_bh(&pppol2tp_tunnel_list_lock);
+	read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	return NULL;
 }
@@ -1287,10 +1303,12 @@ again:
  */
 static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
 {
+	struct pppol2tp_net *pn = pppol2tp_pernet(tunnel->pppol2tp_net);
+
 	/* Remove from socket list */
-	write_lock_bh(&pppol2tp_tunnel_list_lock);
+	write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
 	list_del_init(&tunnel->list);
-	write_unlock_bh(&pppol2tp_tunnel_list_lock);
+	write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	atomic_dec(&pppol2tp_tunnel_count);
 	kfree(tunnel);
@@ -1444,13 +1462,14 @@ error:
 /* Internal function to prepare a tunnel (UDP) socket to have PPPoX
  * sockets attached to it.
  */
-static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
-						   int *error)
+static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
+					int fd, u16 tunnel_id, int *error)
 {
 	int err;
 	struct socket *sock = NULL;
 	struct sock *sk;
 	struct pppol2tp_tunnel *tunnel;
+	struct pppol2tp_net *pn;
 	struct sock *ret = NULL;
 
 	/* Get the tunnel UDP socket from the fd, which was opened by
@@ -1524,11 +1543,15 @@ static struct sock *pppol2tp_prepare_tun
 	/* Misc init */
 	rwlock_init(&tunnel->hlist_lock);
 
+	/* The net we belong to */
+	tunnel->pppol2tp_net = net;
+	pn = pppol2tp_pernet(net);
+
 	/* Add tunnel to our list */
 	INIT_LIST_HEAD(&tunnel->list);
-	write_lock_bh(&pppol2tp_tunnel_list_lock);
-	list_add(&tunnel->list, &pppol2tp_tunnel_list);
-	write_unlock_bh(&pppol2tp_tunnel_list_lock);
+	write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	list_add(&tunnel->list, &pn->pppol2tp_tunnel_list);
+	write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 	atomic_inc(&pppol2tp_tunnel_count);
 
 	/* Bump the reference count. The tunnel context is deleted
@@ -1629,7 +1652,8 @@ static int pppol2tp_connect(struct socke
 	 * tunnel id.
 	 */
 	if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
-		tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+		tunnel_sock = pppol2tp_prepare_tunnel_socket(sock_net(sk),
+							     sp->pppol2tp.fd,
 							     sp->pppol2tp.s_tunnel,
 							     &error);
 		if (tunnel_sock == NULL)
@@ -1637,7 +1661,7 @@ static int pppol2tp_connect(struct socke
 
 		tunnel = tunnel_sock->sk_user_data;
 	} else {
-		tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+		tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
 
 		/* Error if we can't find the tunnel */
 		error = -ENOENT;
@@ -1725,7 +1749,7 @@ static int pppol2tp_connect(struct socke
 	po->chan.ops	 = &pppol2tp_chan_ops;
 	po->chan.mtu	 = session->mtu;
 
-	error = ppp_register_channel(&po->chan);
+	error = ppp_register_net_channel(sock_net(sk), &po->chan);
 	if (error)
 		goto end_put_tun;
 
@@ -2347,8 +2371,9 @@ end:
 #include <linux/seq_file.h>
 
 struct pppol2tp_seq_data {
-	struct pppol2tp_tunnel *tunnel; /* current tunnel */
-	struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+	struct seq_net_private p;
+	struct pppol2tp_tunnel *tunnel;		/* current tunnel */
+	struct pppol2tp_session *session;	/* NULL means get first session in tunnel */
 };
 
 static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
@@ -2384,17 +2409,18 @@ out:
 	return session;
 }
 
-static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_net *pn,
+					   struct pppol2tp_tunnel *curr)
 {
 	struct pppol2tp_tunnel *tunnel = NULL;
 
-	read_lock_bh(&pppol2tp_tunnel_list_lock);
-	if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+	read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+	if (list_is_last(&curr->list, &pn->pppol2tp_tunnel_list)) {
 		goto out;
 	}
 	tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
 out:
-	read_unlock_bh(&pppol2tp_tunnel_list_lock);
+	read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
 
 	return tunnel;
 }
@@ -2402,6 +2428,7 @@ out:
 static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
 {
 	struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+	struct pppol2tp_net *pn;
 	loff_t pos = *offs;
 
 	if (!pos)
@@ -2409,14 +2436,15 @@ static void *pppol2tp_seq_start(struct s
 
 	BUG_ON(m->private == NULL);
 	pd = m->private;
+	pn = pppol2tp_pernet(seq_file_net(m));
 
 	if (pd->tunnel == NULL) {
-		if (!list_empty(&pppol2tp_tunnel_list))
-			pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+		if (!list_empty(&pn->pppol2tp_tunnel_list))
+			pd->tunnel = list_entry(pn->pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
 	} else {
 		pd->session = next_session(pd->tunnel, pd->session);
 		if (pd->session == NULL) {
-			pd->tunnel = next_tunnel(pd->tunnel);
+			pd->tunnel = next_tunnel(pn, pd->tunnel);
 		}
 	}
 
@@ -2517,7 +2545,7 @@ out:
 	return 0;
 }
 
-static struct seq_operations pppol2tp_seq_ops = {
+static const struct seq_operations pppol2tp_seq_ops = {
 	.start		= pppol2tp_seq_start,
 	.next		= pppol2tp_seq_next,
 	.stop		= pppol2tp_seq_stop,
@@ -2530,51 +2558,18 @@ static struct seq_operations pppol2tp_se
  */
 static int pppol2tp_proc_open(struct inode *inode, struct file *file)
 {
-	struct seq_file *m;
-	struct pppol2tp_seq_data *pd;
-	int ret = 0;
-
-	ret = seq_open(file, &pppol2tp_seq_ops);
-	if (ret < 0)
-		goto out;
-
-	m = file->private_data;
-
-	/* Allocate and fill our proc_data for access later */
-	ret = -ENOMEM;
-	m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
-	if (m->private == NULL)
-		goto out;
-
-	pd = m->private;
-	ret = 0;
-
-out:
-	return ret;
-}
-
-/* Called when /proc file access completes.
- */
-static int pppol2tp_proc_release(struct inode *inode, struct file *file)
-{
-	struct seq_file *m = (struct seq_file *)file->private_data;
-
-	kfree(m->private);
-	m->private = NULL;
-
-	return seq_release(inode, file);
+	return seq_open_net(inode, file, &pppol2tp_seq_ops,
+			    sizeof(struct pppol2tp_seq_data));
 }
 
-static struct file_operations pppol2tp_proc_fops = {
+static const struct file_operations pppol2tp_proc_fops = {
 	.owner		= THIS_MODULE,
 	.open		= pppol2tp_proc_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
-	.release	= pppol2tp_proc_release,
+	.release	= seq_release_net,
 };
 
-static struct proc_dir_entry *pppol2tp_proc;
-
 #endif /* CONFIG_PROC_FS */
 
 /*****************************************************************************
@@ -2606,6 +2601,57 @@ static struct pppox_proto pppol2tp_proto
 	.ioctl		= pppol2tp_ioctl
 };
 
+static __net_init int pppol2tp_init_net(struct net *net)
+{
+	struct pppol2tp_net *pn;
+	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;
+	}
+#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,
+};
+
 static int __init pppol2tp_init(void)
 {
 	int err;
@@ -2617,23 +2663,17 @@ static int __init pppol2tp_init(void)
 	if (err)
 		goto out_unregister_pppol2tp_proto;
 
-#ifdef CONFIG_PROC_FS
-	pppol2tp_proc = proc_net_fops_create(&init_net, "pppol2tp", 0,
-					     &pppol2tp_proc_fops);
-	if (!pppol2tp_proc) {
-		err = -ENOMEM;
+	err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
+	if (err)
 		goto out_unregister_pppox_proto;
-	}
-#endif /* CONFIG_PROC_FS */
+
 	printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
 	       PPPOL2TP_DRV_VERSION);
 
 out:
 	return err;
-#ifdef CONFIG_PROC_FS
 out_unregister_pppox_proto:
 	unregister_pppox_proto(PX_PROTO_OL2TP);
-#endif
 out_unregister_pppol2tp_proto:
 	proto_unregister(&pppol2tp_sk_proto);
 	goto out;
@@ -2642,10 +2682,6 @@ out_unregister_pppol2tp_proto:
 static void __exit pppol2tp_exit(void)
 {
 	unregister_pppox_proto(PX_PROTO_OL2TP);
-
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry("pppol2tp", init_net.proc_net);
-#endif
 	proto_unregister(&pppol2tp_sk_proto);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/pppox.c linux-libre-2.6.30-gnu1/drivers/net/pppox.c
--- linux-libre-2.6.29-gnu1/drivers/net/pppox.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/pppox.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,9 +108,6 @@ static int pppox_create(struct net *net,
 {
 	int rc = -EPROTOTYPE;
 
-	if (net != &init_net)
-		return -EAFNOSUPPORT;
-
 	if (protocol < 0 || protocol > PX_MAX_PROTO)
 		goto out;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ppp_synctty.c linux-libre-2.6.30-gnu1/drivers/net/ppp_synctty.c
--- linux-libre-2.6.29-gnu1/drivers/net/ppp_synctty.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ppp_synctty.c	2009-06-09 23:05:27.000000000 -0400
@@ -206,6 +206,7 @@ ppp_sync_open(struct tty_struct *tty)
 {
 	struct syncppp *ap;
 	int err;
+	int speed;
 
 	if (tty->ops->write == NULL)
 		return -EOPNOTSUPP;
@@ -234,6 +235,8 @@ ppp_sync_open(struct tty_struct *tty)
 	ap->chan.ops = &sync_ops;
 	ap->chan.mtu = PPP_MRU;
 	ap->chan.hdrlen = 2;	/* for A/C bytes */
+	speed = tty_get_baud_rate(tty);
+	ap->chan.speed = speed;
 	err = ppp_register_channel(&ap->chan);
 	if (err)
 		goto out_free;
@@ -281,8 +284,7 @@ ppp_sync_close(struct tty_struct *tty)
 
 	ppp_unregister_channel(&ap->chan);
 	skb_queue_purge(&ap->rqueue);
-	if (ap->tpkt)
-		kfree_skb(ap->tpkt);
+	kfree_skb(ap->tpkt);
 	kfree(ap);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ps3_gelic_net.c linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_net.c
--- linux-libre-2.6.29-gnu1/drivers/net/ps3_gelic_net.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_net.c	2009-06-09 23:05:27.000000000 -0400
@@ -745,7 +745,7 @@ static inline struct sk_buff *gelic_put_
 	/* Move the mac addresses to the top of buffer */
 	memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
 
-	veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
+	veth->h_vlan_proto = cpu_to_be16(ETH_P_8021Q);
 	veth->h_vlan_TCI = htons(tag);
 
 	return skb;
@@ -1403,6 +1403,19 @@ void gelic_net_tx_timeout(struct net_dev
 		atomic_dec(&card->tx_timeout_task_counter);
 }
 
+static const struct net_device_ops gelic_netdevice_ops = {
+	.ndo_open = gelic_net_open,
+	.ndo_stop = gelic_net_stop,
+	.ndo_start_xmit = gelic_net_xmit,
+	.ndo_set_multicast_list = gelic_net_set_multi,
+	.ndo_change_mtu = gelic_net_change_mtu,
+	.ndo_tx_timeout = gelic_net_tx_timeout,
+	.ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
 /**
  * gelic_ether_setup_netdev_ops - initialization of net_device operations
  * @netdev: net_device structure
@@ -1412,21 +1425,12 @@ void gelic_net_tx_timeout(struct net_dev
 static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
 					 struct napi_struct *napi)
 {
-	netdev->open = &gelic_net_open;
-	netdev->stop = &gelic_net_stop;
-	netdev->hard_start_xmit = &gelic_net_xmit;
-	netdev->set_multicast_list = &gelic_net_set_multi;
-	netdev->change_mtu = &gelic_net_change_mtu;
-	/* tx watchdog */
-	netdev->tx_timeout = &gelic_net_tx_timeout;
 	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
 	/* NAPI */
 	netif_napi_add(netdev, napi,
 		       gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
 	netdev->ethtool_ops = &gelic_ether_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = gelic_net_poll_controller;
-#endif
+	netdev->netdev_ops = &gelic_netdevice_ops;
 }
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ps3_gelic_wireless.c linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_wireless.c
--- linux-libre-2.6.29-gnu1/drivers/net/ps3_gelic_wireless.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_wireless.c	2009-06-09 23:05:27.000000000 -0400
@@ -2101,6 +2101,9 @@ static int gelic_wl_associate_bss(struct
 	if (ret) {
 		pr_debug("%s: WEP/WPA setup failed %d\n", __func__,
 			 ret);
+		ret = -EPERM;
+		gelic_wl_send_iwap_event(wl, NULL);
+		goto out;
 	}
 
 	/* start association */
@@ -2697,6 +2700,19 @@ static int gelic_wl_stop(struct net_devi
 
 /* -- */
 
+static const struct net_device_ops gelic_wl_netdevice_ops = {
+	.ndo_open = gelic_wl_open,
+	.ndo_stop = gelic_wl_stop,
+	.ndo_start_xmit = gelic_net_xmit,
+	.ndo_set_multicast_list = gelic_net_set_multi,
+	.ndo_change_mtu = gelic_net_change_mtu,
+	.ndo_tx_timeout = gelic_net_tx_timeout,
+	.ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
 static struct ethtool_ops gelic_wl_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
 	.get_link	= gelic_wl_get_link,
@@ -2711,21 +2727,12 @@ static void gelic_wl_setup_netdev_ops(st
 	struct gelic_wl_info *wl;
 	wl = port_wl(netdev_priv(netdev));
 	BUG_ON(!wl);
-	netdev->open = &gelic_wl_open;
-	netdev->stop = &gelic_wl_stop;
-	netdev->hard_start_xmit = &gelic_net_xmit;
-	netdev->set_multicast_list = &gelic_net_set_multi;
-	netdev->change_mtu = &gelic_net_change_mtu;
-	netdev->wireless_data = &wl->wireless_data;
-	netdev->wireless_handlers = &gelic_wl_wext_handler_def;
-	/* tx watchdog */
-	netdev->tx_timeout = &gelic_net_tx_timeout;
 	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
 
 	netdev->ethtool_ops = &gelic_wl_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	netdev->poll_controller = gelic_net_poll_controller;
-#endif
+	netdev->netdev_ops = &gelic_wl_netdevice_ops;
+	netdev->wireless_data = &wl->wireless_data;
+	netdev->wireless_handlers = &gelic_wl_wext_handler_def;
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qla3xxx.c linux-libre-2.6.30-gnu1/drivers/net/qla3xxx.c
--- linux-libre-2.6.29-gnu1/drivers/net/qla3xxx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qla3xxx.c	2009-06-09 23:05:27.000000000 -0400
@@ -2292,7 +2292,7 @@ static int ql_poll(struct napi_struct *n
 
 	if (tx_cleaned + rx_cleaned != budget) {
 		spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		ql_update_small_bufq_prod_index(qdev);
 		ql_update_lrg_bufq_prod_index(qdev);
 		writel(qdev->rsp_consumer_index,
@@ -2351,8 +2351,8 @@ static irqreturn_t ql3xxx_isr(int irq, v
 		spin_unlock(&qdev->adapter_lock);
 	} else if (value & ISP_IMR_DISABLE_CMPL_INT) {
 		ql_disable_interrupts(qdev);
-		if (likely(netif_rx_schedule_prep(&qdev->napi))) {
-			__netif_rx_schedule(&qdev->napi);
+		if (likely(napi_schedule_prep(&qdev->napi))) {
+			__napi_schedule(&qdev->napi);
 		}
 	} else {
 		return IRQ_NONE;
@@ -3934,12 +3934,12 @@ static int __devinit ql3xxx_probe(struct
 
 	pci_set_master(pdev);
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-	} else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	} else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 		pci_using_dac = 0;
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	}
 
 	if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_dbg.c linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_dbg.c
--- linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_dbg.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_dbg.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,6 +83,10 @@ static void ql_dump_cam_entries(struct q
 {
 	int i;
 	u32 value[3];
+
+	i = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (i)
+		return;
 	for (i = 0; i < 4; i++) {
 		if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) {
 			printk(KERN_ERR PFX
@@ -111,12 +115,16 @@ static void ql_dump_cam_entries(struct q
 				       qdev->ndev->name, i, value[1], value[0]);
 		}
 	}
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
 
 void ql_dump_routing_entries(struct ql_adapter *qdev)
 {
 	int i;
 	u32 value;
+	i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+	if (i)
+		return;
 	for (i = 0; i < 16; i++) {
 		value = 0;
 		if (ql_get_routing_reg(qdev, i, &value)) {
@@ -131,6 +139,7 @@ void ql_dump_routing_entries(struct ql_a
 				       qdev->ndev->name, i, value);
 		}
 	}
+	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 }
 
 void ql_dump_regs(struct ql_adapter *qdev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 
-#include <linux/version.h>
 
 #include "qlge.h"
 
@@ -271,7 +270,8 @@ static int ql_get_settings(struct net_de
 	ecmd->advertising = ADVERTISED_10000baseT_Full;
 	ecmd->autoneg = AUTONEG_ENABLE;
 	ecmd->transceiver = XCVR_EXTERNAL;
-	if ((qdev->link_status & LINK_TYPE_MASK) == LINK_TYPE_10GBASET) {
+	if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
+				STS_LINK_TYPE_10GBASET) {
 		ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
 		ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
 		ecmd->port = PORT_TP;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge.h linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge.h
--- linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,8 +28,8 @@
        } while (0)
 
 #define QLGE_VENDOR_ID    0x1077
-#define QLGE_DEVICE_ID    0x8012
-
+#define QLGE_DEVICE_ID_8012	0x8012
+#define QLGE_DEVICE_ID_8000	0x8000
 #define MAX_CPUS 8
 #define MAX_TX_RINGS MAX_CPUS
 #define MAX_RX_RINGS ((MAX_CPUS * 2) + 1)
@@ -164,7 +164,7 @@ enum {
 	CSR_RP = (1 << 10),
 	CSR_CMD_PARM_SHIFT = 22,
 	CSR_CMD_NOP = 0x00000000,
-	CSR_CMD_SET_RST = 0x1000000,
+	CSR_CMD_SET_RST = 0x10000000,
 	CSR_CMD_CLR_RST = 0x20000000,
 	CSR_CMD_SET_PAUSE = 0x30000000,
 	CSR_CMD_CLR_PAUSE = 0x40000000,
@@ -424,7 +424,7 @@ enum {
 	RX_SYMBOL_ERR = 0x00000370,
 	RX_MAC_ERR = 0x00000378,
 	RX_CTL_PKTS = 0x00000380,
-	RX_PAUSE_PKTS = 0x00000384,
+	RX_PAUSE_PKTS = 0x00000388,
 	RX_64_PKTS = 0x00000390,
 	RX_65_TO_127_PKTS = 0x00000398,
 	RX_128_255_PKTS = 0x000003a0,
@@ -733,6 +733,11 @@ enum {
 	AEN_LINK_DOWN = 0x00008012,
 	AEN_IDC_CMPLT = 0x00008100,
 	AEN_IDC_REQ = 0x00008101,
+	AEN_IDC_EXT = 0x00008102,
+	AEN_DCBX_CHG = 0x00008110,
+	AEN_AEN_LOST = 0x00008120,
+	AEN_AEN_SFP_IN = 0x00008130,
+	AEN_AEN_SFP_OUT = 0x00008131,
 	AEN_FW_INIT_DONE = 0x00008400,
 	AEN_FW_INIT_FAIL = 0x00008401,
 
@@ -742,40 +747,48 @@ enum {
 	MB_CMD_MB_TEST = 0x00000006,
 	MB_CMD_CSUM_TEST = 0x00000007,	/* Verify Checksum */
 	MB_CMD_ABOUT_FW = 0x00000008,
+	MB_CMD_COPY_RISC_RAM = 0x0000000a,
 	MB_CMD_LOAD_RISC_RAM = 0x0000000b,
 	MB_CMD_DUMP_RISC_RAM = 0x0000000c,
 	MB_CMD_WRITE_RAM = 0x0000000d,
+	MB_CMD_INIT_RISC_RAM = 0x0000000e,
 	MB_CMD_READ_RAM = 0x0000000f,
 	MB_CMD_STOP_FW = 0x00000014,
 	MB_CMD_MAKE_SYS_ERR = 0x0000002a,
+	MB_CMD_WRITE_SFP = 0x00000030,
+	MB_CMD_READ_SFP = 0x00000031,
 	MB_CMD_INIT_FW = 0x00000060,
-	MB_CMD_GET_INIT_CB = 0x00000061,
+	MB_CMD_GET_IFCB = 0x00000061,
 	MB_CMD_GET_FW_STATE = 0x00000069,
 	MB_CMD_IDC_REQ = 0x00000100,	/* Inter-Driver Communication */
 	MB_CMD_IDC_ACK = 0x00000101,	/* Inter-Driver Communication */
 	MB_CMD_SET_WOL_MODE = 0x00000110,	/* Wake On Lan */
-	MB_WOL_DISABLE = 0x00000000,
-	MB_WOL_MAGIC_PKT = 0x00000001,
-	MB_WOL_FLTR = 0x00000002,
-	MB_WOL_UCAST = 0x00000004,
-	MB_WOL_MCAST = 0x00000008,
-	MB_WOL_BCAST = 0x00000010,
-	MB_WOL_LINK_UP = 0x00000020,
-	MB_WOL_LINK_DOWN = 0x00000040,
+	MB_WOL_DISABLE = 0,
+	MB_WOL_MAGIC_PKT = (1 << 1),
+	MB_WOL_FLTR = (1 << 2),
+	MB_WOL_UCAST = (1 << 3),
+	MB_WOL_MCAST = (1 << 4),
+	MB_WOL_BCAST = (1 << 5),
+	MB_WOL_LINK_UP = (1 << 6),
+	MB_WOL_LINK_DOWN = (1 << 7),
 	MB_CMD_SET_WOL_FLTR = 0x00000111,	/* Wake On Lan Filter */
-	MB_CMD_CLEAR_WOL_FLTR = 0x00000112,	/* 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 */
-	MB_CMD_CLEAR_WOL_MAGIC = 0x00000114,	/* Wake On Lan Magic Packet */
+	MB_CMD_CLEAR_WOL_MAGIC = 0x00000114,/* Wake On Lan Magic Packet */
+	MB_CMD_SET_WOL_IMMED = 0x00000115,
 	MB_CMD_PORT_RESET = 0x00000120,
 	MB_CMD_SET_PORT_CFG = 0x00000122,
 	MB_CMD_GET_PORT_CFG = 0x00000123,
-	MB_CMD_SET_ASIC_VOLTS = 0x00000130,
-	MB_CMD_GET_SNS_DATA = 0x00000131,	/* Temp and Volt Sense data. */
+	MB_CMD_GET_LINK_STS = 0x00000124,
 
 	/* Mailbox Command Status. */
 	MB_CMD_STS_GOOD = 0x00004000,	/* Success. */
 	MB_CMD_STS_INTRMDT = 0x00001000,	/* Intermediate Complete. */
-	MB_CMD_STS_ERR = 0x00004005,	/* Error. */
+	MB_CMD_STS_INVLD_CMD = 0x00004001,	/* Invalid. */
+	MB_CMD_STS_XFC_ERR = 0x00004002,	/* Interface Error. */
+	MB_CMD_STS_CSUM_ERR = 0x00004003,	/* Csum Error. */
+	MB_CMD_STS_ERR = 0x00004005,	/* System Error. */
+	MB_CMD_STS_PARAM_ERR = 0x00004006,	/* Parameter Error. */
 };
 
 struct mbox_params {
@@ -785,7 +798,7 @@ struct mbox_params {
 	int out_count;
 };
 
-struct flash_params {
+struct flash_params_8012 {
 	u8 dev_id_str[4];
 	__le16 size;
 	__le16 csum;
@@ -795,6 +808,43 @@ struct flash_params {
 	__le16 res;
 };
 
+/* 8000 device's flash is a different structure
+ * at a different offset in flash.
+ */
+#define FUNC0_FLASH_OFFSET 0x140200
+#define FUNC1_FLASH_OFFSET 0x140600
+
+/* Flash related data structures. */
+struct flash_params_8000 {
+	u8 dev_id_str[4];	/* "8000" */
+	__le16 ver;
+	__le16 size;
+	__le16 csum;
+	__le16 reserved0;
+	__le16 total_size;
+	__le16 entry_count;
+	u8 data_type0;
+	u8 data_size0;
+	u8 mac_addr[6];
+	u8 data_type1;
+	u8 data_size1;
+	u8 mac_addr1[6];
+	u8 data_type2;
+	u8 data_size2;
+	__le16 vlan_id;
+	u8 data_type3;
+	u8 data_size3;
+	__le16 last;
+	u8 reserved1[464];
+	__le16	subsys_ven_id;
+	__le16	subsys_dev_id;
+	u8 reserved2[4];
+};
+
+union flash_params {
+	struct flash_params_8012 flash_params_8012;
+	struct flash_params_8000 flash_params_8000;
+};
 
 /*
  * doorbell space for the rx ring context
@@ -968,6 +1018,7 @@ struct ib_mac_iocb_rsp {
 	__le16 vlan_id;		/* 12 bits */
 #define IB_MAC_IOCB_RSP_C	0x1000	/* VLAN CFI bit */
 #define IB_MAC_IOCB_RSP_COS_SHIFT	12	/* class of service value */
+#define IB_MAC_IOCB_RSP_VLAN_MASK	0x0ffff
 
 	__le16 reserved1;
 	__le32 reserved2[6];
@@ -1033,6 +1084,7 @@ struct wqicb {
 #define Q_LEN_CPP_16	0x0001
 #define Q_LEN_CPP_32	0x0002
 #define Q_LEN_CPP_64	0x0003
+#define Q_LEN_CPP_512	0x0006
 	__le16 flags;
 #define Q_PRI_SHIFT	1
 #define Q_FLAGS_LC	0x1000
@@ -1314,27 +1366,49 @@ enum {
 	QL_DMA64 = (1 << 5),
 	QL_PROMISCUOUS = (1 << 6),
 	QL_ALLMULTI = (1 << 7),
+	QL_PORT_CFG = (1 << 8),
+	QL_CAM_RT_SET = (1 << 9),
 };
 
 /* link_status bit definitions */
 enum {
-	LOOPBACK_MASK = 0x00000700,
-	LOOPBACK_PCS = 0x00000100,
-	LOOPBACK_HSS = 0x00000200,
-	LOOPBACK_EXT = 0x00000300,
-	PAUSE_MASK = 0x000000c0,
-	PAUSE_STD = 0x00000040,
-	PAUSE_PRI = 0x00000080,
-	SPEED_MASK = 0x00000038,
-	SPEED_100Mb = 0x00000000,
-	SPEED_1Gb = 0x00000008,
-	SPEED_10Gb = 0x00000010,
-	LINK_TYPE_MASK = 0x00000007,
-	LINK_TYPE_XFI = 0x00000001,
-	LINK_TYPE_XAUI = 0x00000002,
-	LINK_TYPE_XFI_BP = 0x00000003,
-	LINK_TYPE_XAUI_BP = 0x00000004,
-	LINK_TYPE_10GBASET = 0x00000005,
+	STS_LOOPBACK_MASK = 0x00000700,
+	STS_LOOPBACK_PCS = 0x00000100,
+	STS_LOOPBACK_HSS = 0x00000200,
+	STS_LOOPBACK_EXT = 0x00000300,
+	STS_PAUSE_MASK = 0x000000c0,
+	STS_PAUSE_STD = 0x00000040,
+	STS_PAUSE_PRI = 0x00000080,
+	STS_SPEED_MASK = 0x00000038,
+	STS_SPEED_100Mb = 0x00000000,
+	STS_SPEED_1Gb = 0x00000008,
+	STS_SPEED_10Gb = 0x00000010,
+	STS_LINK_TYPE_MASK = 0x00000007,
+	STS_LINK_TYPE_XFI = 0x00000001,
+	STS_LINK_TYPE_XAUI = 0x00000002,
+	STS_LINK_TYPE_XFI_BP = 0x00000003,
+	STS_LINK_TYPE_XAUI_BP = 0x00000004,
+	STS_LINK_TYPE_10GBASET = 0x00000005,
+};
+
+/* link_config bit definitions */
+enum {
+	CFG_JUMBO_FRAME_SIZE = 0x00010000,
+	CFG_PAUSE_MASK = 0x00000060,
+	CFG_PAUSE_STD = 0x00000020,
+	CFG_PAUSE_PRI = 0x00000040,
+	CFG_DCBX = 0x00000010,
+	CFG_LOOPBACK_MASK = 0x00000007,
+	CFG_LOOPBACK_PCS = 0x00000002,
+	CFG_LOOPBACK_HSS = 0x00000004,
+	CFG_LOOPBACK_EXT = 0x00000006,
+	CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
+};
+
+struct nic_operations {
+
+	int (*get_flash) (struct ql_adapter *);
+	int (*port_initialize) (struct ql_adapter *);
 };
 
 /*
@@ -1377,6 +1451,8 @@ struct ql_adapter {
 
 	u32 mailbox_in;
 	u32 mailbox_out;
+	struct mbox_params idc_mbc;
+	struct mutex	mpi_mutex;
 
 	int tx_ring_size;
 	int rx_ring_size;
@@ -1412,8 +1488,10 @@ struct ql_adapter {
 	u32 port_link_up;
 	u32 port_init;
 	u32 link_status;
+	u32 link_config;
+	u32 max_frame_size;
 
-	struct flash_params flash;
+	union flash_params flash;
 
 	struct net_device_stats stats;
 	struct workqueue_struct *q_workqueue;
@@ -1421,6 +1499,11 @@ struct ql_adapter {
 	struct delayed_work asic_reset_work;
 	struct delayed_work mpi_reset_work;
 	struct delayed_work mpi_work;
+	struct delayed_work mpi_port_cfg_work;
+	struct delayed_work mpi_idc_work;
+	struct completion ide_completion;
+	struct nic_operations *nic_ops;
+	u16 device_id;
 };
 
 /*
@@ -1493,6 +1576,10 @@ void ql_queue_asic_error(struct ql_adapt
 u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
 void ql_set_ethtool_ops(struct net_device *ndev);
 int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
+void ql_mpi_idc_work(struct work_struct *work);
+void ql_mpi_port_cfg_work(struct work_struct *work);
+int ql_mb_get_fw_state(struct ql_adapter *qdev);
+int ql_cam_route_initialize(struct ql_adapter *qdev);
 
 #if 1
 #define QL_ALL_DUMP
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_main.c linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -58,8 +58,8 @@ static const u32 default_msg =
     NETIF_MSG_IFUP |
     NETIF_MSG_RX_ERR |
     NETIF_MSG_TX_ERR |
-    NETIF_MSG_TX_QUEUED |
-    NETIF_MSG_INTR | NETIF_MSG_TX_DONE | NETIF_MSG_RX_STATUS |
+/*  NETIF_MSG_TX_QUEUED | */
+/*  NETIF_MSG_INTR | NETIF_MSG_TX_DONE | NETIF_MSG_RX_STATUS | */
 /* NETIF_MSG_PKTDATA | */
     NETIF_MSG_HW | NETIF_MSG_WOL | 0;
 
@@ -75,7 +75,8 @@ module_param(irq_type, int, MSIX_IRQ);
 MODULE_PARM_DESC(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)},
+	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
+	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)},
 	/* required last entry */
 	{0,}
 };
@@ -247,9 +248,6 @@ int ql_get_mac_addr_reg(struct ql_adapte
 	u32 offset = 0;
 	int status;
 
-	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
-	if (status)
-		return status;
 	switch (type) {
 	case MAC_ADDR_TYPE_MULTI_MAC:
 	case MAC_ADDR_TYPE_CAM_MAC:
@@ -308,7 +306,6 @@ int ql_get_mac_addr_reg(struct ql_adapte
 		status = -EPERM;
 	}
 exit:
-	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 	return status;
 }
 
@@ -321,9 +318,6 @@ static int ql_set_mac_addr_reg(struct ql
 	u32 offset = 0;
 	int status = 0;
 
-	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
-	if (status)
-		return status;
 	switch (type) {
 	case MAC_ADDR_TYPE_MULTI_MAC:
 	case MAC_ADDR_TYPE_CAM_MAC:
@@ -334,7 +328,7 @@ static int ql_set_mac_addr_reg(struct ql
 			    (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
 			    (addr[5]);
 
-			QPRINTK(qdev, IFUP, INFO,
+			QPRINTK(qdev, IFUP, DEBUG,
 				"Adding %s address %pM"
 				" at index %d in the CAM.\n",
 				((type ==
@@ -415,7 +409,6 @@ static int ql_set_mac_addr_reg(struct ql
 		status = -EPERM;
 	}
 exit:
-	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 	return status;
 }
 
@@ -426,10 +419,6 @@ int ql_get_routing_reg(struct ql_adapter
 {
 	int status = 0;
 
-	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
-	if (status)
-		goto exit;
-
 	status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0);
 	if (status)
 		goto exit;
@@ -441,7 +430,6 @@ int ql_get_routing_reg(struct ql_adapter
 		goto exit;
 	*value = ql_read32(qdev, RT_DATA);
 exit:
-	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 	return status;
 }
 
@@ -453,13 +441,9 @@ exit:
 static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
 			      int enable)
 {
-	int status;
+	int status = -EINVAL; /* Return error if no mask match. */
 	u32 value = 0;
 
-	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
-	if (status)
-		return status;
-
 	QPRINTK(qdev, IFUP, DEBUG,
 		"%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s mask %s the routing reg.\n",
 		(enable ? "Adding" : "Removing"),
@@ -555,7 +539,6 @@ static int ql_set_routing_reg(struct ql_
 		ql_write32(qdev, RT_DATA, enable ? mask : 0);
 	}
 exit:
-	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 	return status;
 }
 
@@ -604,7 +587,6 @@ u32 ql_enable_completion_interrupt(struc
 static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
 {
 	u32 var = 0;
-	unsigned long hw_flags;
 	struct intr_context *ctx;
 
 	/* HW disables for us if we're MSIX multi interrupts and
@@ -614,14 +596,14 @@ static u32 ql_disable_completion_interru
 		return 0;
 
 	ctx = qdev->intr_context + intr;
-	spin_lock_irqsave(&qdev->hw_lock, hw_flags);
+	spin_lock(&qdev->hw_lock);
 	if (!atomic_read(&ctx->irq_cnt)) {
 		ql_write32(qdev, INTR_EN,
 		ctx->intr_dis_mask);
 		var = ql_read32(qdev, STS);
 	}
 	atomic_inc(&ctx->irq_cnt);
-	spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+	spin_unlock(&qdev->hw_lock);
 	return var;
 }
 
@@ -641,6 +623,28 @@ static void ql_enable_all_completion_int
 
 }
 
+static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char *str)
+{
+	int status, i;
+	u16 csum = 0;
+	__le16 *flash = (__le16 *)&qdev->flash;
+
+	status = strncmp((char *)&qdev->flash, str, 4);
+	if (status) {
+		QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
+		return	status;
+	}
+
+	for (i = 0; i < size; i++)
+		csum += le16_to_cpu(*flash++);
+
+	if (csum)
+		QPRINTK(qdev, IFUP, ERR,
+			"Invalid flash checksum, csum = 0x%.04x.\n", csum);
+
+	return csum;
+}
+
 static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
 {
 	int status = 0;
@@ -665,23 +669,75 @@ exit:
 	return status;
 }
 
-static int ql_get_flash_params(struct ql_adapter *qdev)
+static int ql_get_8000_flash_params(struct ql_adapter *qdev)
+{
+	u32 i, size;
+	int status;
+	__le32 *p = (__le32 *)&qdev->flash;
+	u32 offset;
+
+	/* Get flash offset for function and adjust
+	 * for dword access.
+	 */
+	if (!qdev->func)
+		offset = FUNC0_FLASH_OFFSET / sizeof(u32);
+	else
+		offset = FUNC1_FLASH_OFFSET / sizeof(u32);
+
+	if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
+		return -ETIMEDOUT;
+
+	size = sizeof(struct flash_params_8000) / sizeof(u32);
+	for (i = 0; i < size; i++, p++) {
+		status = ql_read_flash_word(qdev, i+offset, p);
+		if (status) {
+			QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
+			goto exit;
+		}
+	}
+
+	status = ql_validate_flash(qdev,
+			sizeof(struct flash_params_8000) / sizeof(u16),
+			"8000");
+	if (status) {
+		QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+		status = -EINVAL;
+		goto exit;
+	}
+
+	if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) {
+		QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
+		status = -EINVAL;
+		goto exit;
+	}
+
+	memcpy(qdev->ndev->dev_addr,
+		qdev->flash.flash_params_8000.mac_addr,
+		qdev->ndev->addr_len);
+
+exit:
+	ql_sem_unlock(qdev, SEM_FLASH_MASK);
+	return status;
+}
+
+static int ql_get_8012_flash_params(struct ql_adapter *qdev)
 {
 	int i;
 	int status;
 	__le32 *p = (__le32 *)&qdev->flash;
 	u32 offset = 0;
+	u32 size = sizeof(struct flash_params_8012) / sizeof(u32);
 
 	/* Second function's parameters follow the first
 	 * function's.
 	 */
 	if (qdev->func)
-		offset = sizeof(qdev->flash) / sizeof(u32);
+		offset = size;
 
 	if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
 		return -ETIMEDOUT;
 
-	for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
+	for (i = 0; i < size; i++, p++) {
 		status = ql_read_flash_word(qdev, i+offset, p);
 		if (status) {
 			QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
@@ -689,6 +745,25 @@ static int ql_get_flash_params(struct ql
 		}
 
 	}
+
+	status = ql_validate_flash(qdev,
+			sizeof(struct flash_params_8012) / sizeof(u16),
+			"8012");
+	if (status) {
+		QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+		status = -EINVAL;
+		goto exit;
+	}
+
+	if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) {
+		status = -EINVAL;
+		goto exit;
+	}
+
+	memcpy(qdev->ndev->dev_addr,
+		qdev->flash.flash_params_8012.mac_addr,
+		qdev->ndev->addr_len);
+
 exit:
 	ql_sem_unlock(qdev, SEM_FLASH_MASK);
 	return status;
@@ -759,13 +834,25 @@ exit:
 	return status;
 }
 
+static int ql_8000_port_initialize(struct ql_adapter *qdev)
+{
+	int status;
+	status = ql_mb_get_fw_state(qdev);
+	if (status)
+		goto exit;
+	/* Wake up a worker to get/set the TX/RX frame sizes. */
+	queue_delayed_work(qdev->workqueue, &qdev->mpi_port_cfg_work, 0);
+exit:
+	return status;
+}
+
 /* Take the MAC Core out of reset.
  * Enable statistics counting.
  * Take the transmitter/receiver out of reset.
  * This functionality may be done in the MPI firmware at a
  * later date.
  */
-static int ql_port_initialize(struct ql_adapter *qdev)
+static int ql_8012_port_initialize(struct ql_adapter *qdev)
 {
 	int status = 0;
 	u32 data;
@@ -881,7 +968,8 @@ static void ql_write_cq_idx(struct rx_ri
 /* Process (refill) a large buffer queue. */
 static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
-	int clean_idx = rx_ring->lbq_clean_idx;
+	u32 clean_idx = rx_ring->lbq_clean_idx;
+	u32 start_idx = clean_idx;
 	struct bq_desc *lbq_desc;
 	u64 map;
 	int i;
@@ -928,19 +1016,23 @@ static void ql_update_lbq(struct ql_adap
 		rx_ring->lbq_prod_idx += 16;
 		if (rx_ring->lbq_prod_idx == rx_ring->lbq_len)
 			rx_ring->lbq_prod_idx = 0;
+		rx_ring->lbq_free_cnt -= 16;
+	}
+
+	if (start_idx != clean_idx) {
 		QPRINTK(qdev, RX_STATUS, DEBUG,
 			"lbq: updating prod idx = %d.\n",
 			rx_ring->lbq_prod_idx);
 		ql_write_db_reg(rx_ring->lbq_prod_idx,
 				rx_ring->lbq_prod_idx_db_reg);
-		rx_ring->lbq_free_cnt -= 16;
 	}
 }
 
 /* Process (refill) a small buffer queue. */
 static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
-	int clean_idx = rx_ring->sbq_clean_idx;
+	u32 clean_idx = rx_ring->sbq_clean_idx;
+	u32 start_idx = clean_idx;
 	struct bq_desc *sbq_desc;
 	u64 map;
 	int i;
@@ -990,13 +1082,15 @@ static void ql_update_sbq(struct ql_adap
 		rx_ring->sbq_prod_idx += 16;
 		if (rx_ring->sbq_prod_idx == rx_ring->sbq_len)
 			rx_ring->sbq_prod_idx = 0;
+		rx_ring->sbq_free_cnt -= 16;
+	}
+
+	if (start_idx != clean_idx) {
 		QPRINTK(qdev, RX_STATUS, DEBUG,
 			"sbq: updating prod idx = %d.\n",
 			rx_ring->sbq_prod_idx);
 		ql_write_db_reg(rx_ring->sbq_prod_idx,
 				rx_ring->sbq_prod_idx_db_reg);
-
-		rx_ring->sbq_free_cnt -= 16;
 	}
 }
 
@@ -1412,6 +1506,8 @@ static void ql_process_mac_rx_intr(struc
 {
 	struct net_device *ndev = qdev->ndev;
 	struct sk_buff *skb = NULL;
+	u16 vlan_id = (le16_to_cpu(ib_mac_rsp->vlan_id) &
+			IB_MAC_IOCB_RSP_VLAN_MASK)
 
 	QL_DUMP_IB_MAC_RSP(ib_mac_rsp);
 
@@ -1463,18 +1559,26 @@ static void ql_process_mac_rx_intr(struc
 			}
 		}
 	}
+
 	qdev->stats.rx_packets++;
 	qdev->stats.rx_bytes += skb->len;
-	skb->protocol = eth_type_trans(skb, ndev);
-	if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) {
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"Passing a VLAN packet upstream.\n");
-		vlan_hwaccel_receive_skb(skb, qdev->vlgrp,
-				le16_to_cpu(ib_mac_rsp->vlan_id));
+	skb_record_rx_queue(skb,
+		rx_ring->cq_id - qdev->rss_ring_first_cq_id);
+	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+		if (qdev->vlgrp &&
+			(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+			(vlan_id != 0))
+			vlan_gro_receive(&rx_ring->napi, qdev->vlgrp,
+				vlan_id, skb);
+		else
+			napi_gro_receive(&rx_ring->napi, skb);
 	} else {
-		QPRINTK(qdev, RX_STATUS, DEBUG,
-			"Passing a normal packet upstream.\n");
-		netif_receive_skb(skb);
+		if (qdev->vlgrp &&
+			(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+			(vlan_id != 0))
+			vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id);
+		else
+			netif_receive_skb(skb);
 	}
 }
 
@@ -1521,14 +1625,12 @@ static void ql_process_mac_tx_intr(struc
 /* Fire up a handler to reset the MPI processor. */
 void ql_queue_fw_error(struct ql_adapter *qdev)
 {
-	netif_stop_queue(qdev->ndev);
 	netif_carrier_off(qdev->ndev);
 	queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0);
 }
 
 void ql_queue_asic_error(struct ql_adapter *qdev)
 {
-	netif_stop_queue(qdev->ndev);
 	netif_carrier_off(qdev->ndev);
 	ql_disable_interrupts(qdev);
 	/* Clear adapter up bit to signal the recovery
@@ -1583,6 +1685,7 @@ static int ql_clean_outbound_rx_ring(str
 	struct ob_mac_iocb_rsp *net_rsp = NULL;
 	int count = 0;
 
+	struct tx_ring *tx_ring;
 	/* While there are entries in the completion queue. */
 	while (prod != rx_ring->cnsmr_idx) {
 
@@ -1608,15 +1711,16 @@ static int ql_clean_outbound_rx_ring(str
 		prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
 	}
 	ql_write_cq_idx(rx_ring);
-	if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) {
-		struct tx_ring *tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+	tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+	if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
+					net_rsp != NULL) {
 		if (atomic_read(&tx_ring->queue_stopped) &&
 		    (atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
 			/*
 			 * The queue got stopped because the tx_ring was full.
 			 * Wake it up, because it's now at least 25% empty.
 			 */
-			netif_wake_queue(qdev->ndev);
+			netif_wake_subqueue(qdev->ndev, tx_ring->wq_id);
 	}
 
 	return count;
@@ -1677,7 +1781,7 @@ static int ql_napi_poll_msix(struct napi
 		rx_ring->cq_id);
 
 	if (work_done < budget) {
-		__netif_rx_complete(napi);
+		napi_complete(napi);
 		ql_enable_completion_interrupt(qdev, rx_ring->irq);
 	}
 	return work_done;
@@ -1703,19 +1807,29 @@ static void ql_vlan_rx_add_vid(struct ne
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	u32 enable_bit = MAC_ADDR_E;
+	int status;
 
+	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status)
+		return;
 	spin_lock(&qdev->hw_lock);
 	if (ql_set_mac_addr_reg
 	    (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
 		QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
 	}
 	spin_unlock(&qdev->hw_lock);
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 }
 
 static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	u32 enable_bit = 0;
+	int status;
+
+	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status)
+		return;
 
 	spin_lock(&qdev->hw_lock);
 	if (ql_set_mac_addr_reg
@@ -1723,6 +1837,7 @@ static void ql_vlan_rx_kill_vid(struct n
 		QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
 	}
 	spin_unlock(&qdev->hw_lock);
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 
 }
 
@@ -1762,7 +1877,7 @@ static irqreturn_t qlge_msix_tx_isr(int
 static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
 {
 	struct rx_ring *rx_ring = dev_id;
-	netif_rx_schedule(&rx_ring->napi);
+	napi_schedule(&rx_ring->napi);
 	return IRQ_HANDLED;
 }
 
@@ -1848,7 +1963,7 @@ static irqreturn_t qlge_isr(int irq, voi
 							      &rx_ring->rx_work,
 							      0);
 				else
-					netif_rx_schedule(&rx_ring->napi);
+					napi_schedule(&rx_ring->napi);
 				work_done++;
 			}
 		}
@@ -1937,7 +2052,7 @@ static int qlge_send(struct sk_buff *skb
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	int tso;
 	struct tx_ring *tx_ring;
-	u32 tx_ring_idx = (u32) QL_TXQ_IDX(qdev, skb);
+	u32 tx_ring_idx = (u32) skb->queue_mapping;
 
 	tx_ring = &qdev->tx_ring[tx_ring_idx];
 
@@ -1948,7 +2063,7 @@ static int qlge_send(struct sk_buff *skb
 		QPRINTK(qdev, TX_QUEUED, INFO,
 			"%s: shutting down tx queue %d du to lack of resources.\n",
 			__func__, tx_ring_idx);
-		netif_stop_queue(ndev);
+		netif_stop_subqueue(ndev, tx_ring->wq_id);
 		atomic_inc(&tx_ring->queue_stopped);
 		return NETDEV_TX_BUSY;
 	}
@@ -2029,6 +2144,7 @@ static int ql_alloc_shadow_space(struct
 			"Allocation of RX shadow space failed.\n");
 		return -ENOMEM;
 	}
+	memset(qdev->rx_ring_shadow_reg_area, 0, PAGE_SIZE);
 	qdev->tx_ring_shadow_reg_area =
 	    pci_alloc_consistent(qdev->pdev, PAGE_SIZE,
 				 &qdev->tx_ring_shadow_reg_dma);
@@ -2037,6 +2153,7 @@ static int ql_alloc_shadow_space(struct
 			"Allocation of TX shadow space failed.\n");
 		goto err_wqp_sh_area;
 	}
+	memset(qdev->tx_ring_shadow_reg_area, 0, PAGE_SIZE);
 	return 0;
 
 err_wqp_sh_area:
@@ -2121,47 +2238,6 @@ static void ql_free_lbq_buffers(struct q
 	}
 }
 
-/*
- * Allocate and map a page for each element of the lbq.
- */
-static int ql_alloc_lbq_buffers(struct ql_adapter *qdev,
-				struct rx_ring *rx_ring)
-{
-	int i;
-	struct bq_desc *lbq_desc;
-	u64 map;
-	__le64 *bq = rx_ring->lbq_base;
-
-	for (i = 0; i < rx_ring->lbq_len; i++) {
-		lbq_desc = &rx_ring->lbq[i];
-		memset(lbq_desc, 0, sizeof(lbq_desc));
-		lbq_desc->addr = bq;
-		lbq_desc->index = i;
-		lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
-		if (unlikely(!lbq_desc->p.lbq_page)) {
-			QPRINTK(qdev, IFUP, ERR, "failed alloc_page().\n");
-			goto mem_error;
-		} else {
-			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)) {
-				QPRINTK(qdev, IFUP, ERR,
-					"PCI mapping failed.\n");
-				goto mem_error;
-			}
-			pci_unmap_addr_set(lbq_desc, mapaddr, map);
-			pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
-			*lbq_desc->addr = cpu_to_le64(map);
-		}
-		bq++;
-	}
-	return 0;
-mem_error:
-	ql_free_lbq_buffers(qdev, rx_ring);
-	return -ENOMEM;
-}
-
 static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
 	int i;
@@ -2184,63 +2260,72 @@ static void ql_free_sbq_buffers(struct q
 	}
 }
 
-/* Allocate and map an skb for each element of the sbq. */
-static int ql_alloc_sbq_buffers(struct ql_adapter *qdev,
+/* Free all large and small rx buffers associated
+ * with the completion queues for this device.
+ */
+static void ql_free_rx_buffers(struct ql_adapter *qdev)
+{
+	int i;
+	struct rx_ring *rx_ring;
+
+	for (i = 0; i < qdev->rx_ring_count; i++) {
+		rx_ring = &qdev->rx_ring[i];
+		if (rx_ring->lbq)
+			ql_free_lbq_buffers(qdev, rx_ring);
+		if (rx_ring->sbq)
+			ql_free_sbq_buffers(qdev, rx_ring);
+	}
+}
+
+static void ql_alloc_rx_buffers(struct ql_adapter *qdev)
+{
+	struct rx_ring *rx_ring;
+	int i;
+
+	for (i = 0; i < qdev->rx_ring_count; i++) {
+		rx_ring = &qdev->rx_ring[i];
+		if (rx_ring->type != TX_Q)
+			ql_update_buffer_queues(qdev, rx_ring);
+	}
+}
+
+static void ql_init_lbq_ring(struct ql_adapter *qdev,
+				struct rx_ring *rx_ring)
+{
+	int i;
+	struct bq_desc *lbq_desc;
+	__le64 *bq = rx_ring->lbq_base;
+
+	memset(rx_ring->lbq, 0, rx_ring->lbq_len * sizeof(struct bq_desc));
+	for (i = 0; i < rx_ring->lbq_len; i++) {
+		lbq_desc = &rx_ring->lbq[i];
+		memset(lbq_desc, 0, sizeof(*lbq_desc));
+		lbq_desc->index = i;
+		lbq_desc->addr = bq;
+		bq++;
+	}
+}
+
+static void ql_init_sbq_ring(struct ql_adapter *qdev,
 				struct rx_ring *rx_ring)
 {
 	int i;
 	struct bq_desc *sbq_desc;
-	struct sk_buff *skb;
-	u64 map;
 	__le64 *bq = rx_ring->sbq_base;
 
+	memset(rx_ring->sbq, 0, rx_ring->sbq_len * sizeof(struct bq_desc));
 	for (i = 0; i < rx_ring->sbq_len; i++) {
 		sbq_desc = &rx_ring->sbq[i];
-		memset(sbq_desc, 0, sizeof(sbq_desc));
+		memset(sbq_desc, 0, sizeof(*sbq_desc));
 		sbq_desc->index = i;
 		sbq_desc->addr = bq;
-		skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size);
-		if (unlikely(!skb)) {
-			/* Better luck next round */
-			QPRINTK(qdev, IFUP, ERR,
-				"small buff alloc failed for %d bytes at index %d.\n",
-				rx_ring->sbq_buf_size, i);
-			goto mem_err;
-		}
-		skb_reserve(skb, QLGE_SB_PAD);
-		sbq_desc->p.skb = skb;
-		/*
-		 * Map only half the buffer. Because the
-		 * other half may get some data copied to it
-		 * when the completion arrives.
-		 */
-		map = pci_map_single(qdev->pdev,
-				     skb->data,
-				     rx_ring->sbq_buf_size / 2,
-				     PCI_DMA_FROMDEVICE);
-		if (pci_dma_mapping_error(qdev->pdev, map)) {
-			QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
-			goto mem_err;
-		}
-		pci_unmap_addr_set(sbq_desc, mapaddr, map);
-		pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2);
-		*sbq_desc->addr = cpu_to_le64(map);
 		bq++;
 	}
-	return 0;
-mem_err:
-	ql_free_sbq_buffers(qdev, rx_ring);
-	return -ENOMEM;
 }
 
 static void ql_free_rx_resources(struct ql_adapter *qdev,
 				 struct rx_ring *rx_ring)
 {
-	if (rx_ring->sbq_len)
-		ql_free_sbq_buffers(qdev, rx_ring);
-	if (rx_ring->lbq_len)
-		ql_free_lbq_buffers(qdev, rx_ring);
-
 	/* Free the small buffer queue. */
 	if (rx_ring->sbq_base) {
 		pci_free_consistent(qdev->pdev,
@@ -2318,11 +2403,7 @@ static int ql_alloc_rx_resources(struct
 			goto err_mem;
 		}
 
-		if (ql_alloc_sbq_buffers(qdev, rx_ring)) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Small buffer allocation failed.\n");
-			goto err_mem;
-		}
+		ql_init_sbq_ring(qdev, rx_ring);
 	}
 
 	if (rx_ring->lbq_len) {
@@ -2350,14 +2431,7 @@ static int ql_alloc_rx_resources(struct
 			goto err_mem;
 		}
 
-		/*
-		 * Allocate the buffers.
-		 */
-		if (ql_alloc_lbq_buffers(qdev, rx_ring)) {
-			QPRINTK(qdev, IFUP, ERR,
-				"Large buffer allocation failed.\n");
-			goto err_mem;
-		}
+		ql_init_lbq_ring(qdev, rx_ring);
 	}
 
 	return 0;
@@ -2451,6 +2525,7 @@ static int ql_start_rx_ring(struct ql_ad
 	    qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
 	int err = 0;
 	u16 bq_len;
+	u64 tmp;
 
 	/* Set up the shadow registers for this ring. */
 	rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2496,7 +2571,8 @@ static int ql_start_rx_ring(struct ql_ad
 	    FLAGS_LI;		/* Load irq delay values */
 	if (rx_ring->lbq_len) {
 		cqicb->flags |= FLAGS_LL;	/* Load lbq values */
-		*((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma;
+		tmp = (u64)rx_ring->lbq_base_dma;;
+		*((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
 		cqicb->lbq_addr =
 		    cpu_to_le64(rx_ring->lbq_base_indirect_dma);
 		bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2505,25 +2581,26 @@ static int ql_start_rx_ring(struct ql_ad
 		bq_len = (rx_ring->lbq_len == 65536) ? 0 :
 			(u16) rx_ring->lbq_len;
 		cqicb->lbq_len = cpu_to_le16(bq_len);
-		rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16;
+		rx_ring->lbq_prod_idx = 0;
 		rx_ring->lbq_curr_idx = 0;
-		rx_ring->lbq_clean_idx = rx_ring->lbq_prod_idx;
-		rx_ring->lbq_free_cnt = 16;
+		rx_ring->lbq_clean_idx = 0;
+		rx_ring->lbq_free_cnt = rx_ring->lbq_len;
 	}
 	if (rx_ring->sbq_len) {
 		cqicb->flags |= FLAGS_LS;	/* Load sbq values */
-		*((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma;
+		tmp = (u64)rx_ring->sbq_base_dma;;
+		*((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
 		cqicb->sbq_addr =
 		    cpu_to_le64(rx_ring->sbq_base_indirect_dma);
 		cqicb->sbq_buf_size =
-		    cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8);
+		    cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
 		bq_len = (rx_ring->sbq_len == 65536) ? 0 :
 			(u16) rx_ring->sbq_len;
 		cqicb->sbq_len = cpu_to_le16(bq_len);
-		rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16;
+		rx_ring->sbq_prod_idx = 0;
 		rx_ring->sbq_curr_idx = 0;
-		rx_ring->sbq_clean_idx = rx_ring->sbq_prod_idx;
-		rx_ring->sbq_free_cnt = 16;
+		rx_ring->sbq_clean_idx = 0;
+		rx_ring->sbq_free_cnt = rx_ring->sbq_len;
 	}
 	switch (rx_ring->type) {
 	case TX_Q:
@@ -2569,24 +2646,13 @@ static int ql_start_rx_ring(struct ql_ad
 		QPRINTK(qdev, IFUP, DEBUG, "Invalid rx_ring->type = %d.\n",
 			rx_ring->type);
 	}
-	QPRINTK(qdev, IFUP, INFO, "Initializing rx work queue.\n");
+	QPRINTK(qdev, IFUP, DEBUG, "Initializing rx work queue.\n");
 	err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb),
 			   CFG_LCQ, rx_ring->cq_id);
 	if (err) {
 		QPRINTK(qdev, IFUP, ERR, "Failed to load CQICB.\n");
 		return err;
 	}
-	QPRINTK(qdev, IFUP, INFO, "Successfully loaded CQICB.\n");
-	/*
-	 * Advance the producer index for the buffer queues.
-	 */
-	wmb();
-	if (rx_ring->lbq_len)
-		ql_write_db_reg(rx_ring->lbq_prod_idx,
-				rx_ring->lbq_prod_idx_db_reg);
-	if (rx_ring->sbq_len)
-		ql_write_db_reg(rx_ring->sbq_prod_idx,
-				rx_ring->sbq_prod_idx_db_reg);
 	return err;
 }
 
@@ -2633,7 +2699,7 @@ static int ql_start_tx_ring(struct ql_ad
 		QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n");
 		return err;
 	}
-	QPRINTK(qdev, IFUP, INFO, "Successfully loaded WQICB.\n");
+	QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded WQICB.\n");
 	return err;
 }
 
@@ -2675,7 +2741,7 @@ static void ql_enable_msix(struct ql_ada
 		    (qdev->pdev, qdev->msi_x_entry, qdev->rx_ring_count)) {
 			set_bit(QL_MSIX_ENABLED, &qdev->flags);
 			qdev->intr_count = qdev->rx_ring_count;
-			QPRINTK(qdev, IFUP, INFO,
+			QPRINTK(qdev, IFUP, DEBUG,
 				"MSI-X Enabled, got %d vectors.\n",
 				qdev->intr_count);
 			return;
@@ -2802,11 +2868,11 @@ static void ql_free_irq(struct ql_adapte
 			if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
 				free_irq(qdev->msi_x_entry[i].vector,
 					 &qdev->rx_ring[i]);
-				QPRINTK(qdev, IFDOWN, ERR,
+				QPRINTK(qdev, IFDOWN, DEBUG,
 					"freeing msix interrupt %d.\n", i);
 			} else {
 				free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
-				QPRINTK(qdev, IFDOWN, ERR,
+				QPRINTK(qdev, IFDOWN, DEBUG,
 					"freeing msi interrupt %d.\n", i);
 			}
 		}
@@ -2837,7 +2903,7 @@ static int ql_request_irq(struct ql_adap
 					i);
 				goto err_irq;
 			} else {
-				QPRINTK(qdev, IFUP, INFO,
+				QPRINTK(qdev, IFUP, DEBUG,
 					"Hooked intr %d, queue type %s%s%s, with name %s.\n",
 					i,
 					qdev->rx_ring[i].type ==
@@ -2912,14 +2978,14 @@ static int ql_start_rss(struct ql_adapte
 	get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
 	get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
 
-	QPRINTK(qdev, IFUP, INFO, "Initializing RSS.\n");
+	QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
 
 	status = ql_write_cfg(qdev, ricb, sizeof(ricb), CFG_LR, 0);
 	if (status) {
 		QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n");
 		return status;
 	}
-	QPRINTK(qdev, IFUP, INFO, "Successfully loaded RICB.\n");
+	QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded RICB.\n");
 	return status;
 }
 
@@ -2929,13 +2995,17 @@ static int ql_route_initialize(struct ql
 	int status = 0;
 	int i;
 
+	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+	if (status)
+		return status;
+
 	/* Clear all the entries in the routing table. */
 	for (i = 0; i < 16; i++) {
 		status = ql_set_routing_reg(qdev, i, 0, 0);
 		if (status) {
 			QPRINTK(qdev, IFUP, ERR,
 				"Failed to init routing register for CAM packets.\n");
-			return status;
+			goto exit;
 		}
 	}
 
@@ -2943,13 +3013,13 @@ static int ql_route_initialize(struct ql
 	if (status) {
 		QPRINTK(qdev, IFUP, ERR,
 			"Failed to init routing register for error packets.\n");
-		return status;
+		goto exit;
 	}
 	status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
 	if (status) {
 		QPRINTK(qdev, IFUP, ERR,
 			"Failed to init routing register for broadcast packets.\n");
-		return status;
+		goto exit;
 	}
 	/* If we have more than one inbound queue, then turn on RSS in the
 	 * routing block.
@@ -2960,17 +3030,39 @@ static int ql_route_initialize(struct ql
 		if (status) {
 			QPRINTK(qdev, IFUP, ERR,
 				"Failed to init routing register for MATCH RSS packets.\n");
-			return status;
+			goto exit;
 		}
 	}
 
 	status = ql_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT,
 				    RT_IDX_CAM_HIT, 1);
-	if (status) {
+	if (status)
 		QPRINTK(qdev, IFUP, ERR,
 			"Failed to init routing register for CAM packets.\n");
+exit:
+	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+	return status;
+}
+
+int ql_cam_route_initialize(struct ql_adapter *qdev)
+{
+	int status;
+
+	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status)
+		return status;
+	status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
+			     MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status) {
+		QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
 		return status;
 	}
+
+	status = ql_route_initialize(qdev);
+	if (status)
+		QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+
 	return status;
 }
 
@@ -3038,28 +3130,24 @@ static int ql_adapter_initialize(struct
 		}
 	}
 
-	status = ql_port_initialize(qdev);
-	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
-		return status;
-	}
-
-	status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
-				     MAC_ADDR_TYPE_CAM_MAC, qdev->func);
-	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
-		return status;
-	}
+	/* 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;
+       }
 
-	status = ql_route_initialize(qdev);
+	/* Set up the MAC address and frame routing filter. */
+	status = ql_cam_route_initialize(qdev);
 	if (status) {
-		QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+		QPRINTK(qdev, IFUP, ERR,
+				"Failed to init CAM/Routing tables.\n");
 		return status;
 	}
 
 	/* Start NAPI for the RSS queues. */
 	for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) {
-		QPRINTK(qdev, IFUP, INFO, "Enabling NAPI for rx_ring[%d].\n",
+		QPRINTK(qdev, IFUP, DEBUG, "Enabling NAPI for rx_ring[%d].\n",
 			i);
 		napi_enable(&qdev->rx_ring[i].napi);
 	}
@@ -3071,36 +3159,23 @@ static int ql_adapter_initialize(struct
 static int ql_adapter_reset(struct ql_adapter *qdev)
 {
 	u32 value;
-	int max_wait_time;
 	int status = 0;
-	int resetCnt = 0;
+	unsigned long end_jiffies = jiffies +
+		max((unsigned long)1, usecs_to_jiffies(30));
 
-#define MAX_RESET_CNT   1
-issueReset:
-	resetCnt++;
-	QPRINTK(qdev, IFDOWN, DEBUG, "Issue soft reset to chip.\n");
 	ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
-	/* Wait for reset to complete. */
-	max_wait_time = 3;
-	QPRINTK(qdev, IFDOWN, DEBUG, "Wait %d seconds for reset to complete.\n",
-		max_wait_time);
+
 	do {
 		value = ql_read32(qdev, RST_FO);
 		if ((value & RST_FO_FR) == 0)
 			break;
+		cpu_relax();
+	} while (time_before(jiffies, end_jiffies));
 
-		ssleep(1);
-	} while ((--max_wait_time));
 	if (value & RST_FO_FR) {
 		QPRINTK(qdev, IFDOWN, ERR,
-			"Stuck in SoftReset:  FSC_SR:0x%08x\n", value);
-		if (resetCnt < MAX_RESET_CNT)
-			goto issueReset;
-	}
-	if (max_wait_time == 0) {
-		status = -ETIMEDOUT;
-		QPRINTK(qdev, IFDOWN, ERR,
 			"ETIMEOUT!!! errored out of resetting the chip!\n");
+		status = -ETIMEDOUT;
 	}
 
 	return status;
@@ -3123,12 +3198,10 @@ static void ql_display_dev_info(struct n
 
 static int ql_adapter_down(struct ql_adapter *qdev)
 {
-	struct net_device *ndev = qdev->ndev;
 	int i, status = 0;
 	struct rx_ring *rx_ring;
 
-	netif_stop_queue(ndev);
-	netif_carrier_off(ndev);
+	netif_carrier_off(qdev->ndev);
 
 	/* Don't kill the reset worker thread if we
 	 * are in the process of recovery.
@@ -3137,6 +3210,8 @@ static int ql_adapter_down(struct ql_ada
 		cancel_delayed_work_sync(&qdev->asic_reset_work);
 	cancel_delayed_work_sync(&qdev->mpi_reset_work);
 	cancel_delayed_work_sync(&qdev->mpi_work);
+	cancel_delayed_work_sync(&qdev->mpi_idc_work);
+	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 
 	/* The default queue at index 0 is always processed in
 	 * a workqueue.
@@ -3171,6 +3246,8 @@ static int ql_adapter_down(struct ql_ada
 	for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
 		netif_napi_del(&qdev->rx_ring[i].napi);
 
+	ql_free_rx_buffers(qdev);
+
 	spin_lock(&qdev->hw_lock);
 	status = ql_adapter_reset(qdev);
 	if (status)
@@ -3184,21 +3261,19 @@ static int ql_adapter_up(struct ql_adapt
 {
 	int err = 0;
 
-	spin_lock(&qdev->hw_lock);
 	err = ql_adapter_initialize(qdev);
 	if (err) {
 		QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
 		spin_unlock(&qdev->hw_lock);
 		goto err_init;
 	}
-	spin_unlock(&qdev->hw_lock);
 	set_bit(QL_ADAPTER_UP, &qdev->flags);
+	ql_alloc_rx_buffers(qdev);
+	if ((ql_read32(qdev, STS) & qdev->port_init))
+		netif_carrier_on(qdev->ndev);
 	ql_enable_interrupts(qdev);
 	ql_enable_all_completion_interrupts(qdev);
-	if ((ql_read32(qdev, STS) & qdev->port_init)) {
-		netif_carrier_on(qdev->ndev);
-		netif_start_queue(qdev->ndev);
-	}
+	netif_tx_start_all_queues(qdev->ndev);
 
 	return 0;
 err_init:
@@ -3206,28 +3281,6 @@ err_init:
 	return err;
 }
 
-static int ql_cycle_adapter(struct ql_adapter *qdev)
-{
-	int status;
-
-	status = ql_adapter_down(qdev);
-	if (status)
-		goto error;
-
-	status = ql_adapter_up(qdev);
-	if (status)
-		goto error;
-
-	return status;
-error:
-	QPRINTK(qdev, IFUP, ALERT,
-		"Driver up/down cycle failed, closing device\n");
-	rtnl_lock();
-	dev_close(qdev->ndev);
-	rtnl_unlock();
-	return status;
-}
-
 static void ql_release_adapter_resources(struct ql_adapter *qdev)
 {
 	ql_free_mem_resources(qdev);
@@ -3308,6 +3361,7 @@ static int ql_configure_rings(struct ql_
 	 * completion handler rx_rings.
 	 */
 	qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
+	netif_set_gso_max_size(qdev->ndev, 65536);
 
 	for (i = 0; i < qdev->tx_ring_count; i++) {
 		tx_ring = &qdev->tx_ring[i];
@@ -3414,6 +3468,8 @@ static int qlge_change_mtu(struct net_de
 
 	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) ||
@@ -3436,8 +3492,11 @@ static void qlge_set_multicast_list(stru
 {
 	struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
 	struct dev_mc_list *mc_ptr;
-	int i;
+	int i, status;
 
+	status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+	if (status)
+		return;
 	spin_lock(&qdev->hw_lock);
 	/*
 	 * Set or clear promiscuous mode if a
@@ -3493,14 +3552,19 @@ static void qlge_set_multicast_list(stru
 	}
 
 	if (ndev->mc_count) {
+		status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+		if (status)
+			goto exit;
 		for (i = 0, mc_ptr = ndev->mc_list; mc_ptr;
 		     i++, mc_ptr = mc_ptr->next)
 			if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr,
 						MAC_ADDR_TYPE_MULTI_MAC, i)) {
 				QPRINTK(qdev, HW, ERR,
 					"Failed to loadmulticast address.\n");
+				ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 				goto exit;
 			}
+		ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 		if (ql_set_routing_reg
 		    (qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) {
 			QPRINTK(qdev, HW, ERR,
@@ -3511,13 +3575,14 @@ static void qlge_set_multicast_list(stru
 	}
 exit:
 	spin_unlock(&qdev->hw_lock);
+	ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
 }
 
 static int qlge_set_mac_address(struct net_device *ndev, void *p)
 {
 	struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
 	struct sockaddr *addr = p;
-	int ret = 0;
+	int status;
 
 	if (netif_running(ndev))
 		return -EBUSY;
@@ -3526,15 +3591,17 @@ static int qlge_set_mac_address(struct n
 		return -EADDRNOTAVAIL;
 	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
 
+	status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+	if (status)
+		return status;
 	spin_lock(&qdev->hw_lock);
-	if (ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
-			MAC_ADDR_TYPE_CAM_MAC, qdev->func)) {/* Unicast */
-		QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
-		ret = -1;
-	}
+	status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
+			MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
 	spin_unlock(&qdev->hw_lock);
-
-	return ret;
+	if (status)
+		QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
+	ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+	return status;
 }
 
 static void qlge_tx_timeout(struct net_device *ndev)
@@ -3547,9 +3614,37 @@ static void ql_asic_reset_work(struct wo
 {
 	struct ql_adapter *qdev =
 	    container_of(work, struct ql_adapter, asic_reset_work.work);
-	ql_cycle_adapter(qdev);
+	int status;
+
+	status = ql_adapter_down(qdev);
+	if (status)
+		goto error;
+
+	status = ql_adapter_up(qdev);
+	if (status)
+		goto error;
+
+	return;
+error:
+	QPRINTK(qdev, IFUP, ALERT,
+		"Driver up/down cycle failed, closing device\n");
+	rtnl_lock();
+	set_bit(QL_ADAPTER_UP, &qdev->flags);
+	dev_close(qdev->ndev);
+	rtnl_unlock();
 }
 
+static struct nic_operations qla8012_nic_ops = {
+	.get_flash		= ql_get_8012_flash_params,
+	.port_initialize	= ql_8012_port_initialize,
+};
+
+static struct nic_operations qla8000_nic_ops = {
+	.get_flash		= ql_get_8000_flash_params,
+	.port_initialize	= ql_8000_port_initialize,
+};
+
+
 static void ql_get_board_info(struct ql_adapter *qdev)
 {
 	qdev->func =
@@ -3568,6 +3663,11 @@ static void ql_get_board_info(struct ql_
 		qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO;
 	}
 	qdev->chip_rev_id = ql_read32(qdev, REV_ID);
+	qdev->device_id = qdev->pdev->device;
+	if (qdev->device_id == QLGE_DEVICE_ID_8012)
+		qdev->nic_ops = &qla8012_nic_ops;
+	else if (qdev->device_id == QLGE_DEVICE_ID_8000)
+		qdev->nic_ops = &qla8000_nic_ops;
 }
 
 static void ql_release_all(struct pci_dev *pdev)
@@ -3626,13 +3726,13 @@ static int __devinit ql_init_device(stru
 	}
 
 	pci_set_master(pdev);
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		set_bit(QL_DMA64, &qdev->flags);
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (!err)
-		       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		       err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	}
 
 	if (err) {
@@ -3660,24 +3760,20 @@ static int __devinit ql_init_device(stru
 		goto err_out;
 	}
 
-	ql_get_board_info(qdev);
 	qdev->ndev = ndev;
 	qdev->pdev = pdev;
+	ql_get_board_info(qdev);
 	qdev->msg_enable = netif_msg_init(debug, default_msg);
 	spin_lock_init(&qdev->hw_lock);
 	spin_lock_init(&qdev->stats_lock);
 
 	/* make sure the EEPROM is good */
-	err = ql_get_flash_params(qdev);
+	err = qdev->nic_ops->get_flash(qdev);
 	if (err) {
 		dev_err(&pdev->dev, "Invalid FLASH.\n");
 		goto err_out;
 	}
 
-	if (!is_valid_ether_addr(qdev->flash.mac_addr))
-		goto err_out;
-
-	memcpy(ndev->dev_addr, qdev->flash.mac_addr, ndev->addr_len);
 	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
 
 	/* Set up the default ring sizes. */
@@ -3700,6 +3796,10 @@ static int __devinit ql_init_device(stru
 	INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
 	INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
 	INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
+	INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
+	INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
+	mutex_init(&qdev->mpi_mutex);
+	init_completion(&qdev->ide_completion);
 
 	if (!cards_found) {
 		dev_info(&pdev->dev, "%s\n", DRV_STRING);
@@ -3737,7 +3837,8 @@ static int __devinit qlge_probe(struct p
 	static int cards_found = 0;
 	int err = 0;
 
-	ndev = alloc_etherdev(sizeof(struct ql_adapter));
+	ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
+			min(MAX_CPUS, (int)num_online_cpus()));
 	if (!ndev)
 		return -ENOMEM;
 
@@ -3757,6 +3858,7 @@ static int __devinit qlge_probe(struct p
 			  | NETIF_F_TSO_ECN
 			  | NETIF_F_HW_VLAN_TX
 			  | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
+	ndev->features |= NETIF_F_GRO;
 
 	if (test_bit(QL_DMA64, &qdev->flags))
 		ndev->features |= NETIF_F_HIGHDMA;
@@ -3779,7 +3881,6 @@ static int __devinit qlge_probe(struct p
 		return err;
 	}
 	netif_carrier_off(ndev);
-	netif_stop_queue(ndev);
 	ql_display_dev_info(ndev);
 	cards_found++;
 	return 0;
@@ -3833,7 +3934,6 @@ static pci_ers_result_t qlge_io_slot_res
 	pci_set_master(pdev);
 
 	netif_carrier_off(ndev);
-	netif_stop_queue(ndev);
 	ql_adapter_reset(qdev);
 
 	/* Make sure the EEPROM is good */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_mpi.c linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_mpi.c
--- linux-libre-2.6.29-gnu1/drivers/net/qlge/qlge_mpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/qlge/qlge_mpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,26 @@
 #include "qlge.h"
 
-static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
+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;
 	/* wait for reg to come ready */
@@ -19,6 +39,32 @@ exit:
 	return status;
 }
 
+int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data)
+{
+	int status = 0;
+	/* wait for reg to come ready */
+	status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+	if (status)
+		goto exit;
+	/* write the data to the data reg */
+	ql_write32(qdev, PROC_DATA, data);
+	/* trigger the write */
+	ql_write32(qdev, PROC_ADDR, reg);
+	/* wait for reg to come ready */
+	status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+	if (status)
+		goto exit;
+exit:
+	return status;
+}
+
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+{
+	int status;
+	status = ql_write_mpi_reg(qdev, 0x00001010, 1);
+	return status;
+}
+
 static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
 	int i, status;
@@ -28,7 +74,7 @@ static int ql_get_mb_sts(struct ql_adapt
 		return -EBUSY;
 	for (i = 0; i < mbcp->out_count; i++) {
 		status =
-		    ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
+		    ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
 				     &mbcp->mbox_out[i]);
 		if (status) {
 			QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
@@ -39,102 +85,762 @@ static int ql_get_mb_sts(struct ql_adapt
 	return status;
 }
 
+/* Wait for a single mailbox command to complete.
+ * Returns zero on success.
+ */
+static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
+{
+	int count = 50;	/* TODO: arbitrary for now. */
+	u32 value;
+
+	do {
+		value = ql_read32(qdev, STS);
+		if (value & STS_PI)
+			return 0;
+		udelay(UDELAY_DELAY); /* 10us */
+	} while (--count);
+	return -ETIMEDOUT;
+}
+
+/* Execute a single mailbox command.
+ * Caller must hold PROC_ADDR semaphore.
+ */
+static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int i, status;
+
+	/*
+	 * Make sure there's nothing pending.
+	 * This shouldn't happen.
+	 */
+	if (ql_read32(qdev, CSR) & CSR_HRI)
+		return -EIO;
+
+	status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
+	if (status)
+		return status;
+
+	/*
+	 * Fill the outbound mailboxes.
+	 */
+	for (i = 0; i < mbcp->in_count; i++) {
+		status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i,
+						mbcp->mbox_in[i]);
+		if (status)
+			goto end;
+	}
+	/*
+	 * Wake up the MPI firmware.
+	 */
+	ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT);
+end:
+	ql_sem_unlock(qdev, SEM_PROC_REG_MASK);
+	return status;
+}
+
+/* We are being asked by firmware to accept
+ * a change to the port.  This is only
+ * a change to max frame sizes (Tx/Rx), pause
+ * paramters, or loopback mode. We wake up a worker
+ * to handler processing this since a mailbox command
+ * will need to be sent to ACK the request.
+ */
+static int ql_idc_req_aen(struct ql_adapter *qdev)
+{
+	int status;
+	struct mbox_params *mbcp = &qdev->idc_mbc;
+
+	QPRINTK(qdev, DRV, ERR, "Enter!\n");
+	/* Get the status data and start up a thread to
+	 * handle the request.
+	 */
+	mbcp = &qdev->idc_mbc;
+	mbcp->out_count = 4;
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"Could not read MPI, resetting ASIC!\n");
+		ql_queue_asic_error(qdev);
+	} else	{
+		/* Begin polled mode early so
+		 * we don't get another interrupt
+		 * when we leave mpi_worker.
+		 */
+		ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+		queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0);
+	}
+	return status;
+}
+
+/* Process an inter-device event completion.
+ * If good, signal the caller's completion.
+ */
+static int ql_idc_cmplt_aen(struct ql_adapter *qdev)
+{
+	int status;
+	struct mbox_params *mbcp = &qdev->idc_mbc;
+	mbcp->out_count = 4;
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"Could not read MPI, resetting RISC!\n");
+		ql_queue_fw_error(qdev);
+	} else
+		/* Wake up the sleeping mpi_idc_work thread that is
+		 * waiting for this event.
+		 */
+		complete(&qdev->ide_completion);
+
+	return status;
+}
+
 static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
+	int status;
 	mbcp->out_count = 2;
 
-	if (ql_get_mb_sts(qdev, mbcp))
-		goto exit;
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"%s: Could not get mailbox status.\n", __func__);
+		return;
+	}
 
 	qdev->link_status = mbcp->mbox_out[1];
 	QPRINTK(qdev, DRV, ERR, "Link Up.\n");
-	QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
-	if (!netif_carrier_ok(qdev->ndev)) {
-		QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
-		netif_carrier_on(qdev->ndev);
-		netif_wake_queue(qdev->ndev);
+
+	/* If we're coming back from an IDC event
+	 * then set up the CAM and frame routing.
+	 */
+	if (test_bit(QL_CAM_RT_SET, &qdev->flags)) {
+		status = ql_cam_route_initialize(qdev);
+		if (status) {
+			QPRINTK(qdev, IFUP, ERR,
+			"Failed to init CAM/Routing tables.\n");
+			return;
+		} else
+			clear_bit(QL_CAM_RT_SET, &qdev->flags);
 	}
-exit:
-	/* Clear the MPI firmware status. */
-	ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+	/* Queue up a worker to check the frame
+	 * size information, and fix it if it's not
+	 * to our liking.
+	 */
+	if (!test_bit(QL_PORT_CFG, &qdev->flags)) {
+		QPRINTK(qdev, DRV, ERR, "Queue Port Config Worker!\n");
+		set_bit(QL_PORT_CFG, &qdev->flags);
+		/* Begin polled mode early so
+		 * we don't get another interrupt
+		 * when we leave mpi_worker dpc.
+		 */
+		ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+		queue_delayed_work(qdev->workqueue,
+				&qdev->mpi_port_cfg_work, 0);
+	}
+
+	netif_carrier_on(qdev->ndev);
 }
 
 static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
+	int status;
+
 	mbcp->out_count = 3;
 
-	if (ql_get_mb_sts(qdev, mbcp)) {
-		QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
-		goto exit;
-	}
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status)
+		QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n");
+
+	netif_carrier_off(qdev->ndev);
+}
+
+static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int status;
+
+	mbcp->out_count = 5;
+
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status)
+		QPRINTK(qdev, DRV, ERR, "SFP in AEN broken!\n");
+	else
+		QPRINTK(qdev, DRV, ERR, "SFP insertion detected.\n");
+
+	return status;
+}
+
+static int ql_sfp_out(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int status;
+
+	mbcp->out_count = 1;
+
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status)
+		QPRINTK(qdev, DRV, ERR, "SFP out AEN broken!\n");
+	else
+		QPRINTK(qdev, DRV, ERR, "SFP removal detected.\n");
+
+	return status;
+}
+
+static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int status;
+
+	mbcp->out_count = 6;
+
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status)
+		QPRINTK(qdev, DRV, ERR, "Lost AEN broken!\n");
+	else {
+		int i;
+		QPRINTK(qdev, DRV, ERR, "Lost AEN detected.\n");
+		for (i = 0; i < mbcp->out_count; i++)
+			QPRINTK(qdev, DRV, ERR, "mbox_out[%d] = 0x%.08x.\n",
+					i, mbcp->mbox_out[i]);
 
-	if (netif_carrier_ok(qdev->ndev)) {
-		QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
-		netif_carrier_off(qdev->ndev);
-		netif_stop_queue(qdev->ndev);
 	}
-	QPRINTK(qdev, DRV, ERR, "Link Down.\n");
-	QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
-exit:
-	/* Clear the MPI firmware status. */
-	ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+	return status;
 }
 
 static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
 {
+	int status;
+
 	mbcp->out_count = 2;
 
-	if (ql_get_mb_sts(qdev, mbcp)) {
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status) {
 		QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
-		goto exit;
+	} else {
+		QPRINTK(qdev, DRV, ERR, "Firmware Revision  = 0x%.08x.\n",
+			mbcp->mbox_out[1]);
+		status = ql_cam_route_initialize(qdev);
+		if (status)
+			QPRINTK(qdev, IFUP, ERR,
+				"Failed to init CAM/Routing tables.\n");
 	}
-	QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
-	QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
-		mbcp->mbox_out[0]);
-	QPRINTK(qdev, DRV, ERR, "Firmware Revision  = 0x%.08x.\n",
-		mbcp->mbox_out[1]);
-exit:
-	/* Clear the MPI firmware status. */
+}
+
+/* Process an async event and clear it unless it's an
+ * error condition.
+ *  This can get called iteratively from the mpi_work thread
+ *  when events arrive via an interrupt.
+ *  It also gets called when a mailbox command is polling for
+ *  it's completion. */
+static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int status;
+	int orig_count = mbcp->out_count;
+
+	/* Just get mailbox zero for now. */
+	mbcp->out_count = 1;
+	status = ql_get_mb_sts(qdev, mbcp);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"Could not read MPI, resetting ASIC!\n");
+		ql_queue_asic_error(qdev);
+		goto end;
+	}
+
+	switch (mbcp->mbox_out[0]) {
+
+	/* This case is only active when we arrive here
+	 * as a result of issuing a mailbox command to
+	 * the firmware.
+	 */
+	case MB_CMD_STS_INTRMDT:
+	case MB_CMD_STS_GOOD:
+	case MB_CMD_STS_INVLD_CMD:
+	case MB_CMD_STS_XFC_ERR:
+	case MB_CMD_STS_CSUM_ERR:
+	case MB_CMD_STS_ERR:
+	case MB_CMD_STS_PARAM_ERR:
+		/* We can only get mailbox status if we're polling from an
+		 * unfinished command.  Get the rest of the status data and
+		 * return back to the caller.
+		 * We only end up here when we're polling for a mailbox
+		 * command completion.
+		 */
+		mbcp->out_count = orig_count;
+		status = ql_get_mb_sts(qdev, mbcp);
+		return status;
+
+	/* We are being asked by firmware to accept
+	 * a change to the port.  This is only
+	 * a change to max frame sizes (Tx/Rx), pause
+	 * paramters, or loopback mode.
+	 */
+	case AEN_IDC_REQ:
+		status = ql_idc_req_aen(qdev);
+		break;
+
+	/* Process and inbound IDC event.
+	 * This will happen when we're trying to
+	 * change tx/rx max frame size, change pause
+	 * paramters or loopback mode.
+	 */
+	case AEN_IDC_CMPLT:
+	case AEN_IDC_EXT:
+		status = ql_idc_cmplt_aen(qdev);
+		break;
+
+	case AEN_LINK_UP:
+		ql_link_up(qdev, mbcp);
+		break;
+
+	case AEN_LINK_DOWN:
+		ql_link_down(qdev, mbcp);
+		break;
+
+	case AEN_FW_INIT_DONE:
+		/* If we're in process on executing the firmware,
+		 * then convert the status to normal mailbox status.
+		 */
+		if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+			mbcp->out_count = orig_count;
+			status = ql_get_mb_sts(qdev, mbcp);
+			mbcp->mbox_out[0] = MB_CMD_STS_GOOD;
+			return status;
+		}
+		ql_init_fw_done(qdev, mbcp);
+		break;
+
+	case AEN_AEN_SFP_IN:
+		ql_sfp_in(qdev, mbcp);
+		break;
+
+	case AEN_AEN_SFP_OUT:
+		ql_sfp_out(qdev, mbcp);
+		break;
+
+	/* This event can arrive at boot time or after an
+	 * MPI reset if the firmware failed to initialize.
+	 */
+	case AEN_FW_INIT_FAIL:
+		/* If we're in process on executing the firmware,
+		 * then convert the status to normal mailbox status.
+		 */
+		if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+			mbcp->out_count = orig_count;
+			status = ql_get_mb_sts(qdev, mbcp);
+			mbcp->mbox_out[0] = MB_CMD_STS_ERR;
+			return status;
+		}
+		QPRINTK(qdev, DRV, ERR,
+			"Firmware initialization failed.\n");
+		status = -EIO;
+		ql_queue_fw_error(qdev);
+		break;
+
+	case AEN_SYS_ERR:
+		QPRINTK(qdev, DRV, ERR,
+			"System Error.\n");
+		ql_queue_fw_error(qdev);
+		status = -EIO;
+		break;
+
+	case AEN_AEN_LOST:
+		ql_aen_lost(qdev, mbcp);
+		break;
+
+	default:
+		QPRINTK(qdev, DRV, ERR,
+			"Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+		/* Clear the MPI firmware status. */
+	}
+end:
 	ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+	return status;
 }
 
-void ql_mpi_work(struct work_struct *work)
+/* Execute a single mailbox command.
+ * mbcp is a pointer to an array of u32.  Each
+ * element in the array contains the value for it's
+ * respective mailbox register.
+ */
+static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+	int status, count;
+
+	mutex_lock(&qdev->mpi_mutex);
+
+	/* Begin polled mode for MPI */
+	ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+
+	/* Load the mailbox registers and wake up MPI RISC. */
+	status = ql_exec_mb_cmd(qdev, mbcp);
+	if (status)
+		goto end;
+
+
+	/* If we're generating a system error, then there's nothing
+	 * to wait for.
+	 */
+	if (mbcp->mbox_in[0] == MB_CMD_MAKE_SYS_ERR)
+		goto end;
+
+	/* Wait for the command to complete. We loop
+	 * here because some AEN might arrive while
+	 * we're waiting for the mailbox command to
+	 * complete. If more than 5 arrive then we can
+	 * assume something is wrong. */
+	count = 5;
+	do {
+		/* Wait for the interrupt to come in. */
+		status = ql_wait_mbx_cmd_cmplt(qdev);
+		if (status)
+			goto end;
+
+		/* Process the event.  If it's an AEN, it
+		 * will be handled in-line or a worker
+		 * will be spawned. If it's our completion
+		 * we will catch it below.
+		 */
+		status = ql_mpi_handler(qdev, mbcp);
+		if (status)
+			goto end;
+
+		/* It's either the completion for our mailbox
+		 * command complete or an AEN.  If it's our
+		 * completion then get out.
+		 */
+		if (((mbcp->mbox_out[0] & 0x0000f000) ==
+					MB_CMD_STS_GOOD) ||
+			((mbcp->mbox_out[0] & 0x0000f000) ==
+					MB_CMD_STS_INTRMDT))
+			break;
+	} while (--count);
+
+	if (!count) {
+		QPRINTK(qdev, DRV, ERR,
+			"Timed out waiting for mailbox complete.\n");
+		status = -ETIMEDOUT;
+		goto end;
+	}
+
+	/* Now we can clear the interrupt condition
+	 * and look at our status.
+	 */
+	ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+	if (((mbcp->mbox_out[0] & 0x0000f000) !=
+					MB_CMD_STS_GOOD) &&
+		((mbcp->mbox_out[0] & 0x0000f000) !=
+					MB_CMD_STS_INTRMDT)) {
+		ql_display_mb_sts(qdev, mbcp);
+		status = -EIO;
+	}
+end:
+	mutex_unlock(&qdev->mpi_mutex);
+	/* End polled mode for MPI */
+	ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+	return status;
+}
+
+/* Get functional state for MPI firmware.
+ * Returns zero on success.
+ */
+int ql_mb_get_fw_state(struct ql_adapter *qdev)
 {
-	struct ql_adapter *qdev =
-	    container_of(work, struct ql_adapter, mpi_work.work);
 	struct mbox_params mbc;
 	struct mbox_params *mbcp = &mbc;
+	int status = 0;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 1;
+	mbcp->out_count = 2;
+
+	mbcp->mbox_in[0] = MB_CMD_GET_FW_STATE;
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed Get Firmware State.\n");
+		status = -EIO;
+	}
+
+	/* If bit zero is set in mbx 1 then the firmware is
+	 * running, but not initialized.  This should never
+	 * happen.
+	 */
+	if (mbcp->mbox_out[1] & 1) {
+		QPRINTK(qdev, DRV, ERR,
+			"Firmware waiting for initialization.\n");
+		status = -EIO;
+	}
+
+	return status;
+}
+
+/* Send and ACK mailbox command to the firmware to
+ * let it continue with the change.
+ */
+int ql_mb_idc_ack(struct ql_adapter *qdev)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status = 0;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 5;
 	mbcp->out_count = 1;
 
-	while (ql_read32(qdev, STS) & STS_PI) {
-		if (ql_get_mb_sts(qdev, mbcp)) {
-			QPRINTK(qdev, DRV, ERR,
-				"Could not read MPI, resetting ASIC!\n");
-			ql_queue_asic_error(qdev);
-		}
+	mbcp->mbox_in[0] = MB_CMD_IDC_ACK;
+	mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1];
+	mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2];
+	mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3];
+	mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4];
 
-		switch (mbcp->mbox_out[0]) {
-		case AEN_LINK_UP:
-			ql_link_up(qdev, mbcp);
-			break;
-		case AEN_LINK_DOWN:
-			ql_link_down(qdev, mbcp);
-			break;
-		case AEN_FW_INIT_DONE:
-			ql_init_fw_done(qdev, mbcp);
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed IDC ACK send.\n");
+		status = -EIO;
+	}
+	return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_set_port_cfg(struct ql_adapter *qdev)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status = 0;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 3;
+	mbcp->out_count = 1;
+
+	mbcp->mbox_in[0] = MB_CMD_SET_PORT_CFG;
+	mbcp->mbox_in[1] = qdev->link_config;
+	mbcp->mbox_in[2] = qdev->max_frame_size;
+
+
+	status = ql_mailbox_command(qdev, mbcp);
+	if (status)
+		return status;
+
+	if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) {
+		QPRINTK(qdev, DRV, ERR,
+			"Port Config sent, wait for IDC.\n");
+	} else	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+		QPRINTK(qdev, DRV, ERR,
+			"Failed Set Port Configuration.\n");
+		status = -EIO;
+	}
+	return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_get_port_cfg(struct ql_adapter *qdev)
+{
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+	int status = 0;
+
+	memset(mbcp, 0, sizeof(struct mbox_params));
+
+	mbcp->in_count = 1;
+	mbcp->out_count = 3;
+
+	mbcp->mbox_in[0] = MB_CMD_GET_PORT_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 Get Port Configuration.\n");
+		status = -EIO;
+	} else	{
+		QPRINTK(qdev, DRV, DEBUG,
+			"Passed Get Port Configuration.\n");
+		qdev->link_config = mbcp->mbox_out[1];
+		qdev->max_frame_size = mbcp->mbox_out[2];
+	}
+	return status;
+}
+
+/* IDC - Inter Device Communication...
+ * Some firmware commands require consent of adjacent FCOE
+ * function.  This function waits for the OK, or a
+ * counter-request for a little more time.i
+ * The firmware will complete the request if the other
+ * function doesn't respond.
+ */
+static int ql_idc_wait(struct ql_adapter *qdev)
+{
+	int status = -ETIMEDOUT;
+	long wait_time = 1 * HZ;
+	struct mbox_params *mbcp = &qdev->idc_mbc;
+	do {
+		/* Wait here for the command to complete
+		 * via the IDC process.
+		 */
+		wait_time =
+			wait_for_completion_timeout(&qdev->ide_completion,
+							wait_time);
+		if (!wait_time) {
+			QPRINTK(qdev, DRV, ERR,
+				"IDC Timeout.\n");
 			break;
-		case MB_CMD_STS_GOOD:
+		}
+		/* Now examine the response from the IDC process.
+		 * We might have a good completion or a request for
+		 * more wait time.
+		 */
+		if (mbcp->mbox_out[0] == AEN_IDC_EXT) {
+			QPRINTK(qdev, DRV, ERR,
+				"IDC Time Extension from function.\n");
+			wait_time += (mbcp->mbox_out[1] >> 8) & 0x0000000f;
+		} else if (mbcp->mbox_out[0] == AEN_IDC_CMPLT) {
+			QPRINTK(qdev, DRV, ERR,
+				"IDC Success.\n");
+			status = 0;
 			break;
-		case AEN_FW_INIT_FAIL:
-		case AEN_SYS_ERR:
-		case MB_CMD_STS_ERR:
-			ql_queue_fw_error(qdev);
-		default:
-			/* Clear the MPI firmware status. */
-			ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+		} else {
+			QPRINTK(qdev, DRV, ERR,
+				"IDC: Invalid State 0x%.04x.\n",
+				mbcp->mbox_out[0]);
+			status = -EIO;
 			break;
 		}
+	} while (wait_time);
+
+	return status;
+}
+
+/* API called in work thread context to set new TX/RX
+ * maximum frame size values to match MTU.
+ */
+static int ql_set_port_cfg(struct ql_adapter *qdev)
+{
+	int status;
+	status = ql_mb_set_port_cfg(qdev);
+	if (status)
+		return status;
+	status = ql_idc_wait(qdev);
+	return status;
+}
+
+/* The following routines are worker threads that process
+ * events that may sleep waiting for completion.
+ */
+
+/* This thread gets the maximum TX and RX frame size values
+ * from the firmware and, if necessary, changes them to match
+ * the MTU setting.
+ */
+void ql_mpi_port_cfg_work(struct work_struct *work)
+{
+	struct ql_adapter *qdev =
+	    container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
+	struct net_device *ndev = qdev->ndev;
+	int status;
+
+	status = ql_mb_get_port_cfg(qdev);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"Bug: Failed to get port config data.\n");
+		goto err;
+	}
+
+	if (ndev->mtu <= 2500)
+		goto end;
+	else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+			qdev->max_frame_size ==
+			CFG_DEFAULT_MAX_FRAME_SIZE)
+		goto end;
+
+	qdev->link_config |=	CFG_JUMBO_FRAME_SIZE;
+	qdev->max_frame_size = CFG_DEFAULT_MAX_FRAME_SIZE;
+	status = ql_set_port_cfg(qdev);
+	if (status) {
+		QPRINTK(qdev, DRV, ERR,
+			"Bug: Failed to set port config data.\n");
+		goto err;
+	}
+end:
+	clear_bit(QL_PORT_CFG, &qdev->flags);
+	return;
+err:
+	ql_queue_fw_error(qdev);
+	goto end;
+}
+
+/* Process an inter-device request.  This is issues by
+ * the firmware in response to another function requesting
+ * a change to the port. We set a flag to indicate a change
+ * has been made and then send a mailbox command ACKing
+ * the change request.
+ */
+void ql_mpi_idc_work(struct work_struct *work)
+{
+	struct ql_adapter *qdev =
+	    container_of(work, struct ql_adapter, mpi_idc_work.work);
+	int status;
+	struct mbox_params *mbcp = &qdev->idc_mbc;
+	u32 aen;
+
+	aen = mbcp->mbox_out[1] >> 16;
+
+	switch (aen) {
+	default:
+		QPRINTK(qdev, DRV, ERR,
+			"Bug: Unhandled IDC action.\n");
+		break;
+	case MB_CMD_PORT_RESET:
+	case MB_CMD_SET_PORT_CFG:
+	case MB_CMD_STOP_FW:
+		netif_carrier_off(qdev->ndev);
+		/* 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);
+		status = ql_mb_idc_ack(qdev);
+		if (status) {
+			QPRINTK(qdev, DRV, ERR,
+			"Bug: No pending IDC!\n");
+		}
+	}
+}
+
+void ql_mpi_work(struct work_struct *work)
+{
+	struct ql_adapter *qdev =
+	    container_of(work, struct ql_adapter, mpi_work.work);
+	struct mbox_params mbc;
+	struct mbox_params *mbcp = &mbc;
+
+	mutex_lock(&qdev->mpi_mutex);
+
+	while (ql_read32(qdev, STS) & STS_PI) {
+		memset(mbcp, 0, sizeof(struct mbox_params));
+		mbcp->out_count = 1;
+		ql_mpi_handler(qdev, mbcp);
 	}
+
+	mutex_unlock(&qdev->mpi_mutex);
 	ql_enable_completion_interrupt(qdev, 0);
 }
 
@@ -142,9 +848,8 @@ void ql_mpi_reset_work(struct work_struc
 {
 	struct ql_adapter *qdev =
 	    container_of(work, struct ql_adapter, mpi_reset_work.work);
-	QPRINTK(qdev, DRV, ERR,
-		"Enter, qdev = %p..\n", qdev);
-	ql_write32(qdev, CSR, CSR_CMD_SET_RST);
-	msleep(50);
-	ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
+	cancel_delayed_work_sync(&qdev->mpi_work);
+	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+	cancel_delayed_work_sync(&qdev->mpi_idc_work);
+	ql_soft_reset_mpi_risc(qdev);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/r6040.c linux-libre-2.6.30-gnu1/drivers/net/r6040.c
--- linux-libre-2.6.29-gnu1/drivers/net/r6040.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/r6040.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,12 +49,12 @@
 #include <asm/processor.h>
 
 #define DRV_NAME	"r6040"
-#define DRV_VERSION	"0.21"
-#define DRV_RELDATE	"09Jan2009"
+#define DRV_VERSION	"0.22"
+#define DRV_RELDATE	"25Mar2009"
 
 /* PHY CHIP Address */
 #define PHY1_ADDR	1	/* For MAC1 */
-#define PHY2_ADDR	2	/* For MAC2 */
+#define PHY2_ADDR	3	/* For MAC2 */
 #define PHY_MODE	0x3100	/* PHY CHIP Register 0 */
 #define PHY_CAP		0x01E1	/* PHY CHIP Register 4 */
 
@@ -160,6 +160,7 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.
 	"Florian Fainelli <florian@openwrt.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
+MODULE_VERSION(DRV_VERSION " " DRV_RELDATE);
 
 /* RX and TX interrupts that we handle */
 #define RX_INTS			(RX_FIFO_FULL | RX_NO_DESC | RX_FINISH)
@@ -484,12 +485,12 @@ static int r6040_close(struct net_device
 	/* Free Descriptor memory */
 	if (lp->rx_ring) {
 		pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
-		lp->rx_ring = 0;
+		lp->rx_ring = NULL;
 	}
 
 	if (lp->tx_ring) {
 		pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
-		lp->tx_ring = 0;
+		lp->tx_ring = NULL;
 	}
 
 	return 0;
@@ -676,7 +677,7 @@ static int r6040_poll(struct napi_struct
 	work_done = r6040_rx(dev, budget);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		/* Enable RX interrupt */
 		iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
 	}
@@ -713,7 +714,7 @@ static irqreturn_t r6040_interrupt(int i
 
 		/* Mask off RX interrupt */
 		misr &= ~RX_INTS;
-		netif_rx_schedule(&lp->napi);
+		napi_schedule(&lp->napi);
 	}
 
 	/* TX interrupt request */
@@ -1085,13 +1086,13 @@ static int __devinit r6040_init_one(stru
 		goto err_out;
 
 	/* this should always be supported */
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
 				"not supported by the card\n");
 		goto err_out;
 	}
-	err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses"
 				"not supported by the card\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/r8169.c linux-libre-2.6.30-gnu1/drivers/net/r8169.c
--- linux-libre-2.6.29-gnu1/drivers/net/r8169.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/r8169.c	2009-06-09 23:05:27.000000000 -0400
@@ -66,7 +66,6 @@ static const int multicast_filter_limit
 #define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
 #define EarlyTxThld	0x3F	/* 0x3F means NO early transmit */
-#define RxPacketMaxSize	0x3FE8	/* 16K - 1 - ETH_HLEN - VLAN - CRC... */
 #define SafeMtu		0x1c20	/* ... actually life sucks beyond ~7k */
 #define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
 
@@ -1148,7 +1147,7 @@ static void rtl8169_update_counters(stru
 		return;
 
 	RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
-	cmd = (u64)paddr & DMA_32BIT_MASK;
+	cmd = (u64)paddr & DMA_BIT_MASK(32);
 	RTL_W32(CounterAddrLow, cmd);
 	RTL_W32(CounterAddrLow, cmd | CounterDump);
 
@@ -2046,11 +2045,11 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	tp->cp_cmd = PCIMulRW | RxChkSum;
 
 	if ((sizeof(dma_addr_t) > 4) &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
 		tp->cp_cmd |= PCIDAC;
 		dev->features |= NETIF_F_HIGHDMA;
 	} else {
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc < 0) {
 			if (netif_msg_probe(tp)) {
 				dev_err(&pdev->dev,
@@ -2075,8 +2074,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	if (!tp->pcie_cap && netif_msg_probe(tp))
 		dev_info(&pdev->dev, "no PCI Express capability\n");
 
-	/* Unneeded ? Don't mess with Mrs. Murphy. */
-	rtl8169_irq_mask_and_ack(ioaddr);
+	RTL_W16(IntrMask, 0x0000);
 
 	/* Soft reset the chip. */
 	RTL_W8(ChipCmd, CmdReset);
@@ -2088,6 +2086,8 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		msleep_interruptible(1);
 	}
 
+	RTL_W16(IntrStatus, 0xffff);
+
 	/* Identify chip attached to board */
 	rtl8169_get_mac_version(tp, ioaddr);
 
@@ -2342,9 +2342,9 @@ static void rtl_set_rx_tx_desc_registers
 	 * Switching from MMIO to I/O access fixes the issue as well.
 	 */
 	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
-	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
+	RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
 	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
-	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
+	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
 }
 
 static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
@@ -2356,10 +2356,10 @@ static u16 rtl_rw_cpluscmd(void __iomem
 	return cmd;
 }
 
-static void rtl_set_rx_max_size(void __iomem *ioaddr)
+static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
 {
 	/* Low hurts. Let's disable the filtering. */
-	RTL_W16(RxMaxSize, 16383);
+	RTL_W16(RxMaxSize, rx_buf_sz);
 }
 
 static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@@ -2406,7 +2406,7 @@ static void rtl_hw_start_8169(struct net
 
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	rtl_set_rx_max_size(ioaddr);
+	rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
 
 	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
@@ -2667,7 +2667,7 @@ static void rtl_hw_start_8168(struct net
 
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	rtl_set_rx_max_size(ioaddr);
+	rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
 
 	tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
 
@@ -2845,7 +2845,7 @@ static void rtl_hw_start_8101(struct net
 
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
-	rtl_set_rx_max_size(ioaddr);
+	rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
 
 	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
@@ -3553,54 +3553,64 @@ static irqreturn_t rtl8169_interrupt(int
 	int handled = 0;
 	int status;
 
+	/* loop handling interrupts until we have no new ones or
+	 * we hit a invalid/hotplug case.
+	 */
 	status = RTL_R16(IntrStatus);
+	while (status && status != 0xffff) {
+		handled = 1;
 
-	/* hotplug/major error/no more work/shared irq */
-	if ((status == 0xffff) || !status)
-		goto out;
+		/* Handle all of the error cases first. These will reset
+		 * the chip, so just exit the loop.
+		 */
+		if (unlikely(!netif_running(dev))) {
+			rtl8169_asic_down(ioaddr);
+			break;
+		}
 
-	handled = 1;
+		/* Work around for rx fifo overflow */
+		if (unlikely(status & RxFIFOOver) &&
+		(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+			netif_stop_queue(dev);
+			rtl8169_tx_timeout(dev);
+			break;
+		}
 
-	if (unlikely(!netif_running(dev))) {
-		rtl8169_asic_down(ioaddr);
-		goto out;
-	}
+		if (unlikely(status & SYSErr)) {
+			rtl8169_pcierr_interrupt(dev);
+			break;
+		}
 
-	status &= tp->intr_mask;
-	RTL_W16(IntrStatus,
-		(status & RxFIFOOver) ? (status | RxOverflow) : status);
+		if (status & LinkChg)
+			rtl8169_check_link_status(dev, tp, ioaddr);
 
-	if (!(status & tp->intr_event))
-		goto out;
+		/* We need to see the lastest version of tp->intr_mask to
+		 * avoid ignoring an MSI interrupt and having to wait for
+		 * another event which may never come.
+		 */
+		smp_rmb();
+		if (status & tp->intr_mask & tp->napi_event) {
+			RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+			tp->intr_mask = ~tp->napi_event;
 
-	/* Work around for rx fifo overflow */
-	if (unlikely(status & RxFIFOOver) &&
-	    (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
-		netif_stop_queue(dev);
-		rtl8169_tx_timeout(dev);
-		goto out;
-	}
+			if (likely(napi_schedule_prep(&tp->napi)))
+				__napi_schedule(&tp->napi);
+			else if (netif_msg_intr(tp)) {
+				printk(KERN_INFO "%s: interrupt %04x in poll\n",
+				dev->name, status);
+			}
+		}
 
-	if (unlikely(status & SYSErr)) {
-		rtl8169_pcierr_interrupt(dev);
-		goto out;
+		/* We only get a new MSI interrupt when all active irq
+		 * sources on the chip have been acknowledged. So, ack
+		 * everything we've seen and check if new sources have become
+		 * active to avoid blocking all interrupts from the chip.
+		 */
+		RTL_W16(IntrStatus,
+			(status & RxFIFOOver) ? (status | RxOverflow) : status);
+		status = RTL_R16(IntrStatus);
 	}
 
-	if (status & LinkChg)
-		rtl8169_check_link_status(dev, tp, ioaddr);
-
-	if (status & tp->napi_event) {
-		RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-		tp->intr_mask = ~tp->napi_event;
-
-		if (likely(netif_rx_schedule_prep(&tp->napi)))
-			__netif_rx_schedule(&tp->napi);
-		else if (netif_msg_intr(tp)) {
-			printk(KERN_INFO "%s: interrupt %04x in poll\n",
-			       dev->name, status);
-		}
-	}
-out:
 	return IRQ_RETVAL(handled);
 }
 
@@ -3615,14 +3625,16 @@ static int rtl8169_poll(struct napi_stru
 	rtl8169_tx_interrupt(dev, tp, ioaddr);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
-		tp->intr_mask = 0xffff;
-		/*
-		 * 20040426: the barrier is not strictly required but the
-		 * behavior of the irq handler could be less predictable
-		 * without it. Btw, the lack of flush for the posted pci
-		 * write is safe - FR
+		napi_complete(napi);
+
+		/* We need for force the visibility of tp->intr_mask
+		 * for other CPUs, as we can loose an MSI interrupt
+		 * and potentially wait for a retransmit timeout if we don't.
+		 * The posted write to IntrMask is safe, as it will
+		 * eventually make it to the chip and we won't loose anything
+		 * until it does.
 		 */
+		tp->intr_mask = 0xffff;
 		smp_wmb();
 		RTL_W16(IntrMask, tp->intr_event);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/rionet.c linux-libre-2.6.30-gnu1/drivers/net/rionet.c
--- linux-libre-2.6.29-gnu1/drivers/net/rionet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/rionet.c	2009-06-09 23:05:27.000000000 -0400
@@ -362,8 +362,7 @@ static int rionet_close(struct net_devic
 	netif_carrier_off(ndev);
 
 	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
-		if (rnet->rx_skb[i])
-			kfree_skb(rnet->rx_skb[i]);
+		kfree_skb(rnet->rx_skb[i]);
 
 	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
 		if (rionet_active[peer->rdev->destid]) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/s2io.c linux-libre-2.6.30-gnu1/drivers/net/s2io.c
--- linux-libre-2.6.29-gnu1/drivers/net/s2io.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/s2io.c	2009-06-09 23:05:27.000000000 -0400
@@ -2852,7 +2852,7 @@ static int s2io_poll_msix(struct napi_st
 	s2io_chk_rx_buffers(nic, ring);
 
 	if (pkts_processed < budget_org) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		/*Re Enable MSI-Rx Vector*/
 		addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
 		addr += 7 - ring->ring_no;
@@ -2889,7 +2889,7 @@ static int s2io_poll_inta(struct napi_st
 			break;
 	}
 	if (pkts_processed < budget_org) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		/* Re enable the Rx interrupts for the ring */
 		writeq(0, &bar0->rx_traffic_mask);
 		readl(&bar0->rx_traffic_mask);
@@ -3862,7 +3862,7 @@ static int s2io_enable_msi_x(struct s2io
 	ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries);
 	/* We fail init if error or we get less vectors than min required */
 	if (ret) {
-		DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+		DBG_PRINT(ERR_DBG, "s2io: Enabling MSI-X failed\n");
 		kfree(nic->entries);
 		nic->mac_control.stats_info->sw_stat.mem_freed
 			+= (nic->num_entries * sizeof(struct msix_entry));
@@ -4342,7 +4342,7 @@ static irqreturn_t s2io_msix_ring_handle
 		val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
 		writeb(val8, addr);
 		val8 = readb(addr);
-		netif_rx_schedule(&ring->napi);
+		napi_schedule(&ring->napi);
 	} else {
 		rx_intr_handler(ring, 0);
 		s2io_chk_rx_buffers(sp, ring);
@@ -4789,7 +4789,7 @@ static irqreturn_t s2io_isr(int irq, voi
 
 		if (config->napi) {
 			if (reason & GEN_INTR_RXTRAFFIC) {
-				netif_rx_schedule(&sp->napi);
+				napi_schedule(&sp->napi);
 				writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
 				writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
 				readl(&bar0->rx_traffic_int);
@@ -7220,7 +7220,6 @@ static int s2io_card_up(struct s2io_nic
 
 	/* Initialise napi */
 	if (config->napi) {
-		int i;
 		if (config->intr_type ==  MSI_X) {
 			for (i = 0; i < sp->config.rx_ring_num; i++)
 				napi_enable(&sp->mac_control.rings[i].napi);
@@ -7542,6 +7541,7 @@ static int rx_osm_handler(struct ring_in
 
 	sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 send_up:
+	skb_record_rx_queue(skb, ring_no);
 	queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
 aggregate:
 	sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
@@ -7775,18 +7775,18 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		return ret;
 	}
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
 		dma_flag = TRUE;
 		if (pci_set_consistent_dma_mask
-		    (pdev, DMA_64BIT_MASK)) {
+		    (pdev, DMA_BIT_MASK(64))) {
 			DBG_PRINT(ERR_DBG,
 				  "Unable to obtain 64bit DMA for \
 					consistent allocations\n");
 			pci_disable_device(pdev);
 			return -ENOMEM;
 		}
-	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 32bit DMA\n");
 	} else {
 		pci_disable_device(pdev);
@@ -8009,8 +8009,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		if (ret) {
 
 			DBG_PRINT(ERR_DBG,
-			  "%s: MSI-X requested but failed to enable\n",
-			  dev->name);
+			  "s2io: MSI-X requested but failed to enable\n");
 			sp->config.intr_type = INTA;
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sb1250-mac.c linux-libre-2.6.30-gnu1/drivers/net/sb1250-mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/sb1250-mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sb1250-mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -2039,9 +2039,9 @@ static irqreturn_t sbmac_intr(int irq,vo
 		sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
 
 	if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
-		if (netif_rx_schedule_prep(&sc->napi)) {
+		if (napi_schedule_prep(&sc->napi)) {
 			__raw_writeq(0, sc->sbm_imr);
-			__netif_rx_schedule(&sc->napi);
+			__napi_schedule(&sc->napi);
 			/* Depend on the exit from poll to reenable intr */
 		}
 		else {
@@ -2299,7 +2299,7 @@ static int sbmac_init(struct platform_de
 	eaddr = sc->sbm_hwaddr;
 
 	/*
-	 * Read the ethernet address.  The firwmare left this programmed
+	 * Read the ethernet address.  The firmware left this programmed
 	 * for us in the ethernet address register for each mac.
 	 */
 
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_de
 		return -ENXIO;
 	}
 
-	phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+	phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0,
 			      PHY_INTERFACE_MODE_GMII);
 	if (IS_ERR(phy_dev)) {
 		printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_de
 
 	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
 		dev->name, phy_dev->drv->name,
-		phy_dev->dev.bus_id, phy_dev->irq);
+		dev_name(&phy_dev->dev), phy_dev->irq);
 
 	sc->phy_dev = phy_dev;
 
@@ -2667,7 +2667,7 @@ static int sbmac_poll(struct napi_struct
 	sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 #ifdef CONFIG_SBMAC_COALESCE
 		__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct pla
 	sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
 	if (!sbm_base) {
 		printk(KERN_ERR "%s: unable to map device registers\n",
-		       pldev->dev.bus_id);
+		       dev_name(&pldev->dev));
 		err = -ENOMEM;
 		goto out_out;
 	}
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct pla
 	 * If we find a zero, skip this MAC.
 	 */
 	sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
-	pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+	pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev),
 		 sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
 	if (sbmac_orig_hwaddr == 0) {
 		err = 0;
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct pla
 	dev = alloc_etherdev(sizeof(struct sbmac_softc));
 	if (!dev) {
 		printk(KERN_ERR "%s: unable to allocate etherdev\n",
-		       pldev->dev.bus_id);
+		       dev_name(&pldev->dev));
 		err = -ENOMEM;
 		goto out_unmap;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sc92031.c linux-libre-2.6.30-gnu1/drivers/net/sc92031.c
--- linux-libre-2.6.29-gnu1/drivers/net/sc92031.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sc92031.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,9 @@
  *  Both are almost identical and seem to be based on pci-skeleton.c
  *
  *  Rewritten for 2.6 by Cesar Eduardo Barros
+ *
+ *  A datasheet for this chip can be found at
+ *  http://www.silan.com.cn/english/products/pdf/SC92031AY.pdf
  */
 
 /* Note about set_mac_address: I don't know how to change the hardware
@@ -31,13 +34,7 @@
 
 #include <asm/irq.h>
 
-#define PCI_VENDOR_ID_SILAN		0x1904
-#define PCI_DEVICE_ID_SILAN_SC92031	0x2031
-#define PCI_DEVICE_ID_SILAN_8139D	0x8139
-
 #define SC92031_NAME "sc92031"
-#define SC92031_DESCRIPTION "Silan SC92031 PCI Fast Ethernet Adapter driver"
-#define SC92031_VERSION "2.0c"
 
 /* BAR 0 is MMIO, BAR 1 is PIO */
 #ifndef SC92031_USE_BAR
@@ -1264,7 +1261,6 @@ static void sc92031_ethtool_get_drvinfo(
 	struct pci_dev *pdev = priv->pdev;
 
 	strcpy(drvinfo->driver, SC92031_NAME);
-	strcpy(drvinfo->version, SC92031_VERSION);
 	strcpy(drvinfo->bus_info, pci_name(pdev));
 }
 
@@ -1423,6 +1419,7 @@ static int __devinit sc92031_probe(struc
 	struct net_device *dev;
 	struct sc92031_priv *priv;
 	u32 mac0, mac1;
+	unsigned long base_addr;
 
 	err = pci_enable_device(pdev);
 	if (unlikely(err < 0))
@@ -1430,11 +1427,11 @@ static int __devinit sc92031_probe(struc
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (unlikely(err < 0))
 		goto out_set_dma_mask;
 
-	err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (unlikely(err < 0))
 		goto out_set_dma_mask;
 
@@ -1497,6 +1494,14 @@ static int __devinit sc92031_probe(struc
 	if (err < 0)
 		goto out_register_netdev;
 
+#if SC92031_USE_BAR == 0
+	base_addr = dev->mem_start;
+#elif SC92031_USE_BAR == 1
+	base_addr = dev->base_addr;
+#endif
+	printk(KERN_INFO "%s: SC92031 at 0x%lx, %pM, IRQ %d\n", dev->name,
+			base_addr, dev->dev_addr, dev->irq);
+
 	return 0;
 
 out_register_netdev:
@@ -1586,8 +1591,8 @@ out:
 }
 
 static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_SC92031) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_8139D) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) },
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table);
@@ -1603,7 +1608,6 @@ static struct pci_driver sc92031_pci_dri
 
 static int __init sc92031_init(void)
 {
-	printk(KERN_INFO SC92031_DESCRIPTION " " SC92031_VERSION "\n");
 	return pci_register_driver(&sc92031_pci_driver);
 }
 
@@ -1617,5 +1621,4 @@ module_exit(sc92031_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Cesar Eduardo Barros <cesarb@cesarb.net>");
-MODULE_DESCRIPTION(SC92031_DESCRIPTION);
-MODULE_VERSION(SC92031_VERSION);
+MODULE_DESCRIPTION("Silan SC92031 PCI Fast Ethernet Adapter driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/seeq8005.c linux-libre-2.6.30-gnu1/drivers/net/seeq8005.c
--- linux-libre-2.6.29-gnu1/drivers/net/seeq8005.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/seeq8005.c	2009-06-09 23:05:27.000000000 -0400
@@ -143,6 +143,17 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops seeq8005_netdev_ops = {
+	.ndo_open		= seeq8005_open,
+	.ndo_stop		= seeq8005_close,
+	.ndo_start_xmit 	= seeq8005_send_packet,
+	.ndo_tx_timeout		= seeq8005_timeout,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* 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.  */
@@ -332,12 +343,8 @@ static int __init seeq8005_probe1(struct
 		 }
 	}
 #endif
-	dev->open		= seeq8005_open;
-	dev->stop		= seeq8005_close;
-	dev->hard_start_xmit 	= seeq8005_send_packet;
-	dev->tx_timeout		= seeq8005_timeout;
+	dev->netdev_ops = &seeq8005_netdev_ops;
 	dev->watchdog_timeo	= HZ/20;
-	dev->set_multicast_list = set_multicast_list;
 	dev->flags &= ~IFF_MULTICAST;
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/bitfield.h linux-libre-2.6.30-gnu1/drivers/net/sfc/bitfield.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/bitfield.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/bitfield.h	2009-06-09 23:05:27.000000000 -0400
@@ -543,7 +543,7 @@ typedef union efx_oword {
 
 /* Static initialiser */
 #define EFX_OWORD32(a, b, c, d)						\
-	{ .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \
-		   __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } }
+	{ .u32 = { cpu_to_le32(a), cpu_to_le32(b), \
+		   cpu_to_le32(c), cpu_to_le32(d) } }
 
 #endif /* EFX_BITFIELD_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/boards.c linux-libre-2.6.30-gnu1/drivers/net/sfc/boards.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/boards.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/boards.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,7 @@ static void blink_led_timer(unsigned lon
 {
 	struct efx_nic *efx = (struct efx_nic *)context;
 	struct efx_blinker *bl = &efx->board_info.blinker;
-	efx->board_info.set_fault_led(efx, bl->state);
+	efx->board_info.set_id_led(efx, bl->state);
 	bl->state = !bl->state;
 	if (bl->resubmit)
 		mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
@@ -48,7 +48,7 @@ static void board_blink(struct efx_nic *
 		blinker->resubmit = false;
 		if (blinker->timer.function)
 			del_timer_sync(&blinker->timer);
-		efx->board_info.set_fault_led(efx, false);
+		efx->board_info.init_leds(efx);
 	}
 }
 
@@ -185,7 +185,7 @@ static struct i2c_board_info sfe4002_hwm
 #define SFE4002_RX_LED    (0)	/* Green */
 #define SFE4002_TX_LED    (1)	/* Amber */
 
-static int sfe4002_init_leds(struct efx_nic *efx)
+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 */
@@ -194,11 +194,9 @@ static int sfe4002_init_leds(struct efx_
 	xfp_set_led(efx, SFE4002_RX_LED,
 		    QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
 	xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
-	efx->board_info.blinker.led_num = SFE4002_FAULT_LED;
-	return 0;
 }
 
-static void sfe4002_fault_led(struct efx_nic *efx, bool state)
+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);
@@ -222,7 +220,67 @@ static int sfe4002_init(struct efx_nic *
 		return rc;
 	efx->board_info.monitor = sfe4002_check_hw;
 	efx->board_info.init_leds = sfe4002_init_leds;
-	efx->board_info.set_fault_led = sfe4002_fault_led;
+	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,
+	.irq		= -1,
+};
+
+#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;
@@ -243,6 +301,8 @@ static struct efx_board_data board_data[
 	{ 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)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/boards.h linux-libre-2.6.30-gnu1/drivers/net/sfc/boards.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/boards.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/boards.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@ 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/efx.c linux-libre-2.6.30-gnu1/drivers/net/sfc/efx.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/efx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/efx.c	2009-06-09 23:05:27.000000000 -0400
@@ -133,6 +133,16 @@ static int phy_flash_cfg;
 module_param(phy_flash_cfg, int, 0644);
 MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially");
 
+static unsigned irq_adapt_low_thresh = 10000;
+module_param(irq_adapt_low_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_low_thresh,
+		 "Threshold score for reducing IRQ moderation");
+
+static unsigned irq_adapt_high_thresh = 20000;
+module_param(irq_adapt_high_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_high_thresh,
+		 "Threshold score for increasing IRQ moderation");
+
 /**************************************************************************
  *
  * Utility functions and prototypes
@@ -182,7 +192,6 @@ static int efx_process_channel(struct ef
 		channel->rx_pkt = NULL;
 	}
 
-	efx_flush_lro(channel);
 	efx_rx_strategy(channel);
 
 	efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
@@ -224,12 +233,41 @@ static int efx_poll(struct napi_struct *
 	rx_packets = efx_process_channel(channel, budget);
 
 	if (rx_packets < budget) {
+		struct efx_nic *efx = channel->efx;
+
+		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);
+			} 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 != old_irq_moderation)
+				falcon_set_int_moderation(channel);
+
+			channel->irq_count = 0;
+			channel->irq_mod_score = 0;
+		}
+
 		/* There is no race here; although napi_disable() will
-		 * only wait for netif_rx_complete(), this isn't a problem
+		 * only wait for napi_complete(), this isn't a problem
 		 * since efx_channel_processed() will have no effect if
 		 * interrupts have already been disabled.
 		 */
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		efx_channel_processed(channel);
 	}
 
@@ -424,10 +462,6 @@ static void efx_start_channel(struct efx
 
 	EFX_LOG(channel->efx, "starting chan %d\n", channel->channel);
 
-	if (!(channel->efx->net_dev->flags & IFF_UP))
-		netif_napi_add(channel->napi_dev, &channel->napi_str,
-			       efx_poll, napi_weight);
-
 	/* The interrupt handler for this channel may set work_pending
 	 * as soon as we enable it.  Make sure it's cleared before
 	 * then.  Similarly, make sure it sees the enabled flag set. */
@@ -558,6 +592,8 @@ static void efx_link_status_changed(stru
 
 }
 
+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)
@@ -593,8 +629,8 @@ void __efx_reconfigure_port(struct efx_n
 
 fail:
 	EFX_ERR(efx, "failed to reconfigure MAC\n");
-	efx->phy_op->fini(efx);
-	efx->port_initialized = false;
+	efx->port_enabled = false;
+	efx_fini_port(efx);
 }
 
 /* Reinitialise the MAC to pick up new PHY settings, even if the port is
@@ -854,20 +890,27 @@ static void efx_fini_io(struct efx_nic *
  * interrupts across them. */
 static int efx_wanted_rx_queues(void)
 {
-	cpumask_t core_mask;
+	cpumask_var_t core_mask;
 	int count;
 	int cpu;
 
-	cpus_clear(core_mask);
+	if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) {
+		printk(KERN_WARNING
+		       "efx.c: allocation failure, irq balancing hobbled\n");
+		return 1;
+	}
+
+	cpumask_clear(core_mask);
 	count = 0;
 	for_each_online_cpu(cpu) {
-		if (!cpu_isset(cpu, core_mask)) {
+		if (!cpumask_test_cpu(cpu, core_mask)) {
 			++count;
-			cpus_or(core_mask, core_mask,
-				topology_core_siblings(cpu));
+			cpumask_or(core_mask, core_mask,
+				   topology_core_cpumask(cpu));
 		}
 	}
 
+	free_cpumask_var(core_mask);
 	return count;
 }
 
@@ -990,7 +1033,7 @@ static int efx_probe_nic(struct efx_nic
 	efx_set_channels(efx);
 
 	/* Initialise the interrupt moderation settings */
-	efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec);
+	efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
 
 	return 0;
 }
@@ -1187,7 +1230,8 @@ void efx_flush_queues(struct efx_nic *ef
  **************************************************************************/
 
 /* Set interrupt moderation parameters */
-void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
+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;
@@ -1197,6 +1241,8 @@ void efx_init_irq_moderation(struct efx_
 	efx_for_each_tx_queue(tx_queue, efx)
 		tx_queue->channel->irq_moderation = tx_usecs;
 
+	efx->irq_rx_adaptive = rx_adaptive;
+	efx->irq_rx_moderation = rx_usecs;
 	efx_for_each_rx_queue(rx_queue, efx)
 		rx_queue->channel->irq_moderation = rx_usecs;
 }
@@ -1269,18 +1315,13 @@ static int efx_ioctl(struct net_device *
 static int efx_init_napi(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
-	int rc;
 
 	efx_for_each_channel(channel, efx) {
 		channel->napi_dev = efx->net_dev;
-		rc = efx_lro_init(&channel->lro_mgr, efx);
-		if (rc)
-			goto err;
+		netif_napi_add(channel->napi_dev, &channel->napi_str,
+			       efx_poll, napi_weight);
 	}
 	return 0;
- err:
-	efx_fini_napi(efx);
-	return rc;
 }
 
 static void efx_fini_napi(struct efx_nic *efx)
@@ -1288,7 +1329,8 @@ static void efx_fini_napi(struct efx_nic
 	struct efx_channel *channel;
 
 	efx_for_each_channel(channel, efx) {
-		efx_lro_fini(&channel->lro_mgr);
+		if (channel->napi_dev)
+			netif_napi_del(&channel->napi_str);
 		channel->napi_dev = NULL;
 	}
 }
@@ -1676,7 +1718,8 @@ int efx_reset_up(struct efx_nic *efx, en
 			rc = efx->phy_op->init(efx);
 			if (rc)
 				ok = false;
-		} else
+		}
+		if (!ok)
 			efx->port_initialized = false;
 	}
 
@@ -1857,8 +1900,8 @@ static struct efx_phy_operations efx_dum
 
 static struct efx_board efx_dummy_board_info = {
 	.init		= efx_port_dummy_op_int,
-	.init_leds	= efx_port_dummy_op_int,
-	.set_fault_led	= efx_port_dummy_op_blink,
+	.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,
@@ -2120,7 +2163,7 @@ static int __devinit efx_pci_probe(struc
 	net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
 			      NETIF_F_HIGHDMA | NETIF_F_TSO);
 	if (lro)
-		net_dev->features |= NETIF_F_LRO;
+		net_dev->features |= NETIF_F_GRO;
 	/* 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/efx.h linux-libre-2.6.30-gnu1/drivers/net/sfc/efx.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/efx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/efx.h	2009-06-09 23:05:27.000000000 -0400
@@ -52,7 +52,7 @@ extern void efx_schedule_reset(struct ef
 extern void efx_suspend(struct efx_nic *efx);
 extern void efx_resume(struct efx_nic *efx);
 extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
-				    int rx_usecs);
+				    int rx_usecs, bool rx_adaptive);
 extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
 extern void efx_hex_dump(const u8 *, unsigned int, const char *);
 
@@ -80,7 +80,7 @@ static inline void efx_schedule_channel(
 		  channel->channel, raw_smp_processor_id());
 	channel->work_pending = true;
 
-	netif_rx_schedule(&channel->napi_str);
+	napi_schedule(&channel->napi_str);
 }
 
 #endif /* EFX_EFX_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/ethtool.c linux-libre-2.6.30-gnu1/drivers/net/sfc/ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -529,7 +529,14 @@ static int efx_ethtool_nway_reset(struct
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
-	return mii_nway_restart(&efx->mii);
+	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
+		mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+				       MDIO_MMDREG_CTRL1,
+				       __ffs(BMCR_ANRESTART), true);
+		return 0;
+	}
+
+	return -EOPNOTSUPP;
 }
 
 static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -597,7 +604,6 @@ static int efx_ethtool_get_coalesce(stru
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_tx_queue *tx_queue;
-	struct efx_rx_queue *rx_queue;
 	struct efx_channel *channel;
 
 	memset(coalesce, 0, sizeof(*coalesce));
@@ -615,14 +621,8 @@ static int efx_ethtool_get_coalesce(stru
 		}
 	}
 
-	/* Find lowest IRQ moderation across all used RX queues */
-	coalesce->rx_coalesce_usecs_irq = ~((u32) 0);
-	efx_for_each_rx_queue(rx_queue, efx) {
-		channel = rx_queue->channel;
-		if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq)
-			coalesce->rx_coalesce_usecs_irq =
-				channel->irq_moderation;
-	}
+	coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
+	coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
 
 	return 0;
 }
@@ -636,10 +636,9 @@ static int efx_ethtool_set_coalesce(stru
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_channel *channel;
 	struct efx_tx_queue *tx_queue;
-	unsigned tx_usecs, rx_usecs;
+	unsigned tx_usecs, rx_usecs, adaptive;
 
-	if (coalesce->use_adaptive_rx_coalesce ||
-	    coalesce->use_adaptive_tx_coalesce)
+	if (coalesce->use_adaptive_tx_coalesce)
 		return -EOPNOTSUPP;
 
 	if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) {
@@ -650,6 +649,7 @@ static int efx_ethtool_set_coalesce(stru
 
 	rx_usecs = coalesce->rx_coalesce_usecs_irq;
 	tx_usecs = coalesce->tx_coalesce_usecs_irq;
+	adaptive = coalesce->use_adaptive_rx_coalesce;
 
 	/* If the channel is shared only allow RX parameters to be set */
 	efx_for_each_tx_queue(tx_queue, efx) {
@@ -661,7 +661,7 @@ static int efx_ethtool_set_coalesce(stru
 		}
 	}
 
-	efx_init_irq_moderation(efx, tx_usecs, rx_usecs);
+	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
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon.c linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,11 +39,16 @@
  * @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;
 };
 
 /**************************************************************************
@@ -119,8 +124,12 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "R
 #define FALCON_EVQ_SIZE 4096
 #define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1)
 
-/* Max number of internal errors. After this resets will not be performed */
-#define FALCON_MAX_INT_ERRORS 4
+/* 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
  */
@@ -146,13 +155,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "R
 /* Dummy SRAM size code */
 #define SRM_NB_BSZ_ONCHIP_ONLY (-1)
 
-/* Be nice if these (or equiv.) were in linux/pci_regs.h, but they're not. */
-#define PCI_EXP_DEVCAP_PWR_VAL_LBN	18
-#define PCI_EXP_DEVCAP_PWR_SCL_LBN	26
-#define PCI_EXP_DEVCTL_PAYLOAD_LBN	5
-#define PCI_EXP_LNKSTA_LNK_WID		0x3f0
-#define PCI_EXP_LNKSTA_LNK_WID_LBN	4
-
 #define FALCON_IS_DUAL_FUNC(efx)		\
 	(falcon_rev(efx) < FALCON_REV_B0)
 
@@ -338,10 +340,10 @@ static int falcon_alloc_special_buffer(s
 	nic_data->next_buffer_table += buffer->entries;
 
 	EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x "
-		"(virt %p phys %lx)\n", buffer->index,
+		"(virt %p phys %llx)\n", buffer->index,
 		buffer->index + buffer->entries - 1,
-		(unsigned long long)buffer->dma_addr, len,
-		buffer->addr, virt_to_phys(buffer->addr));
+		(u64)buffer->dma_addr, len,
+		buffer->addr, (u64)virt_to_phys(buffer->addr));
 
 	return 0;
 }
@@ -353,10 +355,10 @@ static void falcon_free_special_buffer(s
 		return;
 
 	EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x "
-		"(virt %p phys %lx)\n", buffer->index,
+		"(virt %p phys %llx)\n", buffer->index,
 		buffer->index + buffer->entries - 1,
-		(unsigned long long)buffer->dma_addr, buffer->len,
-		buffer->addr, virt_to_phys(buffer->addr));
+		(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);
@@ -727,6 +729,9 @@ static void falcon_handle_tx_event(struc
 		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 */
@@ -896,6 +901,8 @@ static void falcon_handle_rx_event(struc
 			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);
@@ -1073,14 +1080,15 @@ void falcon_set_int_moderation(struct ef
 		 * program is based at 0.  So actual interrupt moderation
 		 * achieved is ((x + 1) * res).
 		 */
-		unsigned int res = 5;
-		channel->irq_moderation -= (channel->irq_moderation % res);
-		if (channel->irq_moderation < res)
-			channel->irq_moderation = 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 / res) - 1);
+				     channel->irq_moderation /
+				     FALCON_IRQ_MOD_RESOLUTION - 1);
 	} else {
 		EFX_POPULATE_DWORD_2(timer_cmd,
 				     TIMER_MODE, TIMER_MODE_DIS,
@@ -1168,9 +1176,9 @@ void falcon_sim_phy_event(struct efx_nic
 
 	EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE);
 	if (EFX_IS10G(efx))
-		EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1);
+		EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1);
 	else
-		EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1);
+		EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1);
 
 	falcon_generate_event(&efx->channel[0], &phy_event);
 }
@@ -1187,31 +1195,29 @@ static void falcon_poll_flush_events(str
 	struct efx_channel *channel = &efx->channel[0];
 	struct efx_tx_queue *tx_queue;
 	struct efx_rx_queue *rx_queue;
-	unsigned int read_ptr, i;
+	unsigned int read_ptr = channel->eventq_read_ptr;
+	unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK;
 
-	read_ptr = channel->eventq_read_ptr;
-	for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+	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);
-		if (ev_code != DRIVER_EV_DECODE)
-			continue;
-
 		ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-		switch (ev_sub_code) {
-		case TX_DESCQ_FLS_DONE_EV_DECODE:
+		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;
 			}
-			break;
-		case RX_DESCQ_FLS_DONE_EV_DECODE:
+		} 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,
@@ -1225,11 +1231,10 @@ static void falcon_poll_flush_events(str
 				else
 					rx_queue->flushed = true;
 			}
-			break;
 		}
 
 		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
@@ -1377,7 +1382,6 @@ static irqreturn_t falcon_fatal_interrup
 	efx_oword_t *int_ker = efx->irq_status.addr;
 	efx_oword_t fatal_intr;
 	int error, mem_perr;
-	static int n_int_errors;
 
 	falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER);
 	error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR);
@@ -1404,7 +1408,14 @@ static irqreturn_t falcon_fatal_interrup
 		pci_clear_master(nic_data->pci_dev2);
 	falcon_disable_interrupts(efx);
 
-	if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
+	/* 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 {
@@ -1423,6 +1434,7 @@ static irqreturn_t falcon_legacy_interru
 {
 	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;
@@ -1437,23 +1449,24 @@ static irqreturn_t falcon_legacy_interru
 	if (unlikely(syserr))
 		return falcon_fatal_interrupt(efx);
 
-	if (queues == 0)
-		return IRQ_NONE;
-
-	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));
-
 	/* Schedule processing of any interrupting queues */
-	channel = &efx->channel[0];
-	while (queues) {
-		if (queues & 0x01)
+	efx_for_each_channel(channel, efx) {
+		if ((queues & 1) ||
+		    falcon_event_present(
+			    falcon_event(channel, channel->eventq_read_ptr))) {
 			efx_schedule_channel(channel);
-		channel++;
+			result = IRQ_HANDLED;
+		}
 		queues >>= 1;
 	}
 
-	return 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;
 }
 
 
@@ -2249,6 +2262,7 @@ static int falcon_probe_phy(struct efx_n
 		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:
@@ -2343,10 +2357,10 @@ int falcon_probe_port(struct efx_nic *ef
 				 FALCON_MAC_STATS_SIZE);
 	if (rc)
 		return rc;
-	EFX_LOG(efx, "stats buffer at %llx (virt %p phys %lx)\n",
-		(unsigned long long)efx->stats_buffer.dma_addr,
+	EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n",
+		(u64)efx->stats_buffer.dma_addr,
 		efx->stats_buffer.addr,
-		virt_to_phys(efx->stats_buffer.addr));
+		(u64)virt_to_phys(efx->stats_buffer.addr));
 
 	return 0;
 }
@@ -2921,9 +2935,9 @@ int falcon_probe_nic(struct efx_nic *efx
 		goto fail4;
 	BUG_ON(efx->irq_status.dma_addr & 0x0f);
 
-	EFX_LOG(efx, "INT_KER at %llx (virt %p phys %lx)\n",
-		(unsigned long long)efx->irq_status.dma_addr,
-		efx->irq_status.addr, virt_to_phys(efx->irq_status.addr));
+	EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n",
+		(u64)efx->irq_status.dma_addr,
+		efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr));
 
 	falcon_probe_spi_devices(efx);
 
@@ -3113,8 +3127,10 @@ void falcon_remove_nic(struct efx_nic *e
 	struct falcon_nic_data *nic_data = efx->nic_data;
 	int rc;
 
+	/* Remove I2C adapter and clear it in preparation for a retry */
 	rc = i2c_del_adapter(&efx->i2c_adap);
 	BUG_ON(rc);
+	memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
 
 	falcon_remove_spi_devices(efx);
 	falcon_free_buffer(efx, &efx->irq_status);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon.h linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon.h	2009-06-09 23:05:27.000000000 -0400
@@ -85,6 +85,8 @@ extern void falcon_set_int_moderation(st
 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon_io.h linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon_io.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/falcon_io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/falcon_io.h	2009-06-09 23:05:27.000000000 -0400
@@ -238,18 +238,21 @@ static inline void falcon_writel_page(st
 /* 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. Take out a lock so the BIU collector cannot be
- * confused. */
+ * 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;
+	unsigned long flags = 0;
 
-	spin_lock_irqsave(&efx->biu_lock, flags);
+	if (page == 0)
+		spin_lock_irqsave(&efx->biu_lock, flags);
 	falcon_writel(efx, value, FALCON_PAGED_REG(page, reg));
-	spin_unlock_irqrestore(&efx->biu_lock, flags);
+	if (page == 0)
+		spin_unlock_irqrestore(&efx->biu_lock, flags);
 }
 
 #endif /* EFX_FALCON_IO_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/Kconfig linux-libre-2.6.30-gnu1/drivers/net/sfc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,6 @@ config SFC
 	tristate "Solarflare Solarstorm SFC4000 support"
 	depends on PCI && INET
 	select MII
-	select INET_LRO
 	select CRC32
 	select I2C
 	select I2C_ALGOBIT
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/mdio_10g.c linux-libre-2.6.30-gnu1/drivers/net/sfc/mdio_10g.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/mdio_10g.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/mdio_10g.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,6 +17,21 @@
 #include "boards.h"
 #include "workarounds.h"
 
+unsigned mdio_id_oui(u32 id)
+{
+	unsigned oui = 0;
+	int i;
+
+	/* The bits of the OUI are designated a..x, with a=0 and b variable.
+	 * In the id register c is the MSB but the OUI is conventionally
+	 * written as bytes h..a, p..i, x..q.  Reorder the bits accordingly. */
+	for (i = 0; i < 22; ++i)
+		if (id & (1 << (i + 10)))
+			oui |= 1 << (i ^ 7);
+
+	return oui;
+}
+
 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
 {
@@ -125,24 +140,25 @@ int mdio_clause45_wait_reset_mmds(struct
 int mdio_clause45_check_mmds(struct efx_nic *efx,
 			     unsigned int mmd_mask, unsigned int fatal_mask)
 {
+	int mmd = 0, probe_mmd, devs0, devs1;
 	u32 devices;
-	int mmd = 0, probe_mmd;
 
 	/* Historically we have probed the PHYXS to find out what devices are
 	 * present,but that doesn't work so well if the PHYXS isn't expected
 	 * to exist, if so just find the first item in the list supplied. */
 	probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
 	    __ffs(mmd_mask);
-	devices = (mdio_clause45_read(efx, efx->mii.phy_id,
-				      probe_mmd, MDIO_MMDREG_DEVS0) |
-		   mdio_clause45_read(efx, efx->mii.phy_id,
-				      probe_mmd, MDIO_MMDREG_DEVS1) << 16);
 
 	/* Check all the expected MMDs are present */
-	if (devices < 0) {
+	devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
+				   probe_mmd, MDIO_MMDREG_DEVS0);
+	devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
+				   probe_mmd, MDIO_MMDREG_DEVS1);
+	if (devs0 < 0 || devs1 < 0) {
 		EFX_ERR(efx, "failed to read devices present\n");
 		return -EIO;
 	}
+	devices = devs0 | (devs1 << 16);
 	if ((devices & mmd_mask) != mmd_mask) {
 		EFX_ERR(efx, "required MMDs not present: got %x, "
 			"wanted %x\n", devices, mmd_mask);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/mdio_10g.h linux-libre-2.6.30-gnu1/drivers/net/sfc/mdio_10g.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/mdio_10g.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/mdio_10g.h	2009-06-09 23:05:27.000000000 -0400
@@ -70,10 +70,10 @@
 #define MDIO_MMDREG_STAT1_LPABLE_LBN	(1)
 #define MDIO_MMDREG_STAT1_LPABLE_WIDTH	(1)
 
-/* Bits in ID reg */
-#define MDIO_ID_REV(_id32)	(_id32 & 0xf)
-#define MDIO_ID_MODEL(_id32)	((_id32 >> 4) & 0x3f)
-#define MDIO_ID_OUI(_id32)	(_id32 >> 10)
+/* Bits in combined ID regs */
+static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned mdio_id_oui(u32 id);
 
 /* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
  * so the 'bit present' bit number of an MMD is the number of
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/mtd.c linux-libre-2.6.30-gnu1/drivers/net/sfc/mtd.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/mtd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/mtd.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,6 +15,7 @@
 #define EFX_DRIVER_NAME "sfc_mtd"
 #include "net_driver.h"
 #include "spi.h"
+#include "efx.h"
 
 #define EFX_SPI_VERIFY_BUF_LEN 16
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/net_driver.h linux-libre-2.6.30-gnu1/drivers/net/sfc/net_driver.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/net_driver.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/net_driver.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,15 +25,11 @@
 #include <linux/device.h>
 #include <linux/highmem.h>
 #include <linux/workqueue.h>
-#include <linux/inet_lro.h>
 #include <linux/i2c.h>
 
 #include "enum.h"
 #include "bitfield.h"
 
-#define EFX_MAX_LRO_DESCRIPTORS 8
-#define EFX_MAX_LRO_AGGR MAX_SKB_FRAGS
-
 /**************************************************************************
  *
  * Build definitions
@@ -340,13 +336,12 @@ enum efx_rx_alloc_method {
  * @eventq_read_ptr: Event queue read pointer
  * @last_eventq_read_ptr: Last event queue read pointer value.
  * @eventq_magic: Event queue magic value for driver-generated test events
- * @lro_mgr: LRO state
+ * @irq_count: Number of IRQs since last adaptive moderation decision
+ * @irq_mod_score: IRQ moderation score
  * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors
  *	and diagnostic counters
  * @rx_alloc_push_pages: RX allocation method currently in use for pushing
  *	descriptors
- * @rx_alloc_pop_pages: RX allocation method currently in use for popping
- *	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
@@ -371,10 +366,11 @@ struct efx_channel {
 	unsigned int last_eventq_read_ptr;
 	unsigned int eventq_magic;
 
-	struct net_lro_mgr lro_mgr;
+	unsigned int irq_count;
+	unsigned int irq_mod_score;
+
 	int rx_alloc_level;
 	int rx_alloc_push_pages;
-	int rx_alloc_pop_pages;
 
 	unsigned n_rx_tobe_disc;
 	unsigned n_rx_ip_frag_err;
@@ -394,13 +390,11 @@ struct efx_channel {
 
 /**
  * struct efx_blinker - S/W LED blinking context
- * @led_num: LED ID (board-specific meaning)
  * @state: Current state - on or off
  * @resubmit: Timer resubmission flag
  * @timer: Control timer for blinking
  */
 struct efx_blinker {
-	int led_num;
 	bool state;
 	bool resubmit;
 	struct timer_list timer;
@@ -413,8 +407,8 @@ struct efx_blinker {
  * @major: Major rev. ('A', 'B' ...)
  * @minor: Minor rev. (0, 1, ...)
  * @init: Initialisation function
- * @init_leds: Sets up board LEDs
- * @set_fault_led: Turns the fault LED on or off
+ * @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
@@ -430,9 +424,9 @@ struct efx_board {
 	/* As the LEDs are typically attached to the PHY, LEDs
 	 * have a separate init callback that happens later than
 	 * board init. */
-	int (*init_leds)(struct efx_nic *efx);
+	void (*init_leds)(struct efx_nic *efx);
+	void (*set_id_led) (struct efx_nic *efx, bool state);
 	int (*monitor) (struct efx_nic *nic);
-	void (*set_fault_led) (struct efx_nic *efx, bool state);
 	void (*blink) (struct efx_nic *efx, bool start);
 	void (*fini) (struct efx_nic *nic);
 	struct efx_blinker blinker;
@@ -459,6 +453,7 @@ enum phy_type {
 	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 */
 };
@@ -713,6 +708,8 @@ union efx_multicast_hash {
  * @membase: Memory BAR value
  * @biu_lock: BIU (bus interface unit) lock
  * @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.
@@ -794,6 +791,8 @@ struct efx_nic {
 	void __iomem *membase;
 	spinlock_t biu_lock;
 	enum efx_int_mode interrupt_mode;
+	bool irq_rx_adaptive;
+	unsigned int irq_rx_moderation;
 
 	struct i2c_adapter i2c_adap;
 	struct efx_board board_info;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/phy.h linux-libre-2.6.30-gnu1/drivers/net/sfc/phy.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/phy.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/phy.h	2009-06-09 23:05:27.000000000 -0400
@@ -18,12 +18,16 @@ extern struct efx_phy_operations falcon_
 
 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
 
+/* 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);
+
 /****************************************************************************
- * Exported functions from the driver for XFP optical PHYs
+ * AMCC/Quake QT20xx PHYs
  */
 extern struct efx_phy_operations falcon_xfp_phy_ops;
 
-/* The QUAKE XFP PHY provides various H/W control states for LEDs */
+/* These PHYs provide various H/W control states for LEDs */
 #define QUAKE_LED_LINK_INVAL	(0)
 #define QUAKE_LED_LINK_STAT	(1)
 #define QUAKE_LED_LINK_ACT	(2)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/rx.c linux-libre-2.6.30-gnu1/drivers/net/sfc/rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,109 +99,6 @@ static inline unsigned int efx_rx_buf_si
 }
 
 
-/**************************************************************************
- *
- * Linux generic LRO handling
- *
- **************************************************************************
- */
-
-static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr,
-			       void **tcpudp_hdr, u64 *hdr_flags, void *priv)
-{
-	struct efx_channel *channel = priv;
-	struct iphdr *iph;
-	struct tcphdr *th;
-
-	iph = (struct iphdr *)skb->data;
-	if (skb->protocol != htons(ETH_P_IP) || iph->protocol != IPPROTO_TCP)
-		goto fail;
-
-	th = (struct tcphdr *)(skb->data + iph->ihl * 4);
-
-	*tcpudp_hdr = th;
-	*ip_hdr = iph;
-	*hdr_flags = LRO_IPV4 | LRO_TCP;
-
-	channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
-	return 0;
-fail:
-	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
-	return -1;
-}
-
-static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr,
-			    void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags,
-			    void *priv)
-{
-	struct efx_channel *channel = priv;
-	struct ethhdr *eh;
-	struct iphdr *iph;
-
-	/* We support EtherII and VLAN encapsulated IPv4 */
-	eh = page_address(frag->page) + frag->page_offset;
-	*mac_hdr = eh;
-
-	if (eh->h_proto == htons(ETH_P_IP)) {
-		iph = (struct iphdr *)(eh + 1);
-	} else {
-		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)eh;
-		if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
-			goto fail;
-
-		iph = (struct iphdr *)(veh + 1);
-	}
-	*ip_hdr = iph;
-
-	/* We can only do LRO over TCP */
-	if (iph->protocol != IPPROTO_TCP)
-		goto fail;
-
-	*hdr_flags = LRO_IPV4 | LRO_TCP;
-	*tcpudp_hdr = (struct tcphdr *)((u8 *) iph + iph->ihl * 4);
-
-	channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
-	return 0;
- fail:
-	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
-	return -1;
-}
-
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx)
-{
-	size_t s = sizeof(struct net_lro_desc) * EFX_MAX_LRO_DESCRIPTORS;
-	struct net_lro_desc *lro_arr;
-
-	/* Allocate the LRO descriptors structure */
-	lro_arr = kzalloc(s, GFP_KERNEL);
-	if (lro_arr == NULL)
-		return -ENOMEM;
-
-	lro_mgr->lro_arr = lro_arr;
-	lro_mgr->max_desc = EFX_MAX_LRO_DESCRIPTORS;
-	lro_mgr->max_aggr = EFX_MAX_LRO_AGGR;
-	lro_mgr->frag_align_pad = EFX_PAGE_SKB_ALIGN;
-
-	lro_mgr->get_skb_header = efx_lro_get_skb_hdr;
-	lro_mgr->get_frag_header = efx_get_frag_hdr;
-	lro_mgr->dev = efx->net_dev;
-
-	lro_mgr->features = LRO_F_NAPI;
-
-	/* We can pass packets up with the checksum intact */
-	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
-
-	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
-	return 0;
-}
-
-void efx_lro_fini(struct net_lro_mgr *lro_mgr)
-{
-	kfree(lro_mgr->lro_arr);
-	lro_mgr->lro_arr = NULL;
-}
-
 /**
  * efx_init_rx_buffer_skb - create new RX buffer using skb-based allocation
  *
@@ -549,77 +446,31 @@ static void efx_rx_packet__check_len(str
 static void efx_rx_packet_lro(struct efx_channel *channel,
 			      struct efx_rx_buffer *rx_buf)
 {
-	struct net_lro_mgr *lro_mgr = &channel->lro_mgr;
-	void *priv = channel;
+	struct napi_struct *napi = &channel->napi_str;
 
 	/* Pass the skb/page into the LRO engine */
 	if (rx_buf->page) {
-		struct skb_frag_struct frags;
+		struct napi_gro_fraginfo info;
 
-		frags.page = rx_buf->page;
-		frags.page_offset = efx_rx_buf_offset(rx_buf);
-		frags.size = rx_buf->len;
+		info.frags[0].page = rx_buf->page;
+		info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
+		info.frags[0].size = rx_buf->len;
+		info.nr_frags = 1;
+		info.ip_summed = CHECKSUM_UNNECESSARY;
+		info.len = rx_buf->len;
 
-		lro_receive_frags(lro_mgr, &frags, rx_buf->len,
-				  rx_buf->len, priv, 0);
+		napi_gro_frags(napi, &info);
 
 		EFX_BUG_ON_PARANOID(rx_buf->skb);
 		rx_buf->page = NULL;
 	} else {
 		EFX_BUG_ON_PARANOID(!rx_buf->skb);
 
-		lro_receive_skb(lro_mgr, rx_buf->skb, priv);
+		napi_gro_receive(napi, rx_buf->skb);
 		rx_buf->skb = NULL;
 	}
 }
 
-/* Allocate and construct an SKB around a struct page.*/
-static struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
-				     struct efx_nic *efx,
-				     int hdr_len)
-{
-	struct sk_buff *skb;
-
-	/* Allocate an SKB to store the headers */
-	skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN);
-	if (unlikely(skb == NULL)) {
-		EFX_ERR_RL(efx, "RX out of memory for skb\n");
-		return NULL;
-	}
-
-	EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags);
-	EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len);
-
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
-	skb_reserve(skb, EFX_PAGE_SKB_ALIGN);
-
-	skb->len = rx_buf->len;
-	skb->truesize = rx_buf->len + sizeof(struct sk_buff);
-	memcpy(skb->data, rx_buf->data, hdr_len);
-	skb->tail += hdr_len;
-
-	/* Append the remaining page onto the frag list */
-	if (unlikely(rx_buf->len > hdr_len)) {
-		struct skb_frag_struct *frag = skb_shinfo(skb)->frags;
-		frag->page = rx_buf->page;
-		frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len;
-		frag->size = skb->len - hdr_len;
-		skb_shinfo(skb)->nr_frags = 1;
-		skb->data_len = frag->size;
-	} else {
-		__free_pages(rx_buf->page, efx->rx_buffer_order);
-		skb->data_len = 0;
-	}
-
-	/* Ownership has transferred from the rx_buf to skb */
-	rx_buf->page = NULL;
-
-	/* Move past the ethernet header */
-	skb->protocol = eth_type_trans(skb, efx->net_dev);
-
-	return skb;
-}
-
 void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 		   unsigned int len, bool checksummed, bool discard)
 {
@@ -687,7 +538,6 @@ void __efx_rx_packet(struct efx_channel
 {
 	struct efx_nic *efx = channel->efx;
 	struct sk_buff *skb;
-	bool lro = !!(efx->net_dev->features & NETIF_F_LRO);
 
 	/* If we're in loopback test, then pass the packet directly to the
 	 * loopback layer, and free the rx_buf here
@@ -709,41 +559,23 @@ void __efx_rx_packet(struct efx_channel
 						       efx->net_dev);
 	}
 
-	/* Both our generic-LRO and SFC-SSR support skb and page based
-	 * allocation, but neither support switching from one to the
-	 * other on the fly. If we spot that the allocation mode has
-	 * changed, then flush the LRO state.
-	 */
-	if (unlikely(channel->rx_alloc_pop_pages != (rx_buf->page != NULL))) {
-		efx_flush_lro(channel);
-		channel->rx_alloc_pop_pages = (rx_buf->page != NULL);
-	}
-	if (likely(checksummed && lro)) {
+	if (likely(checksummed || rx_buf->page)) {
 		efx_rx_packet_lro(channel, rx_buf);
 		goto done;
 	}
 
-	/* Form an skb if required */
-	if (rx_buf->page) {
-		int hdr_len = min(rx_buf->len, EFX_SKB_HEADERS);
-		skb = efx_rx_mk_skb(rx_buf, efx, hdr_len);
-		if (unlikely(skb == NULL)) {
-			efx_free_rx_buffer(efx, rx_buf);
-			goto done;
-		}
-	} else {
-		/* We now own the SKB */
-		skb = rx_buf->skb;
-		rx_buf->skb = NULL;
-	}
+	/* 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 */
-	if (unlikely(!checksummed || !efx->rx_checksum_enabled))
-		skb->ip_summed = CHECKSUM_NONE;
+	skb->ip_summed = CHECKSUM_NONE;
+
+	skb_record_rx_queue(skb, channel->channel);
 
 	/* Pass the packet up */
 	netif_receive_skb(skb);
@@ -760,7 +592,7 @@ void efx_rx_strategy(struct efx_channel
 	enum efx_rx_alloc_method method = rx_alloc_method;
 
 	/* Only makes sense to use page based allocation if LRO is enabled */
-	if (!(channel->efx->net_dev->features & NETIF_F_LRO)) {
+	if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
 		method = RX_ALLOC_METHOD_SKB;
 	} else if (method == RX_ALLOC_METHOD_AUTO) {
 		/* Constrain the rx_alloc_level */
@@ -865,11 +697,6 @@ void efx_remove_rx_queue(struct efx_rx_q
 	rx_queue->buffer = NULL;
 }
 
-void efx_flush_lro(struct efx_channel *channel)
-{
-	lro_flush_all(&channel->lro_mgr);
-}
-
 
 module_param(rx_alloc_method, int, 0644);
 MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/rx.h linux-libre-2.6.30-gnu1/drivers/net/sfc/rx.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/rx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/rx.h	2009-06-09 23:05:27.000000000 -0400
@@ -17,9 +17,6 @@ void efx_remove_rx_queue(struct efx_rx_q
 void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
 void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
 
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx);
-void efx_lro_fini(struct net_lro_mgr *lro_mgr);
-void efx_flush_lro(struct efx_channel *channel);
 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/sfe4001.c linux-libre-2.6.30-gnu1/drivers/net/sfc/sfe4001.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/sfe4001.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/sfe4001.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/rtnetlink.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "phy.h"
@@ -398,6 +399,7 @@ static struct i2c_board_info sfn4111t_r5
 
 int sfn4111t_init(struct efx_nic *efx)
 {
+	int i = 0;
 	int rc;
 
 	efx->board_info.hwmon_client =
@@ -416,13 +418,20 @@ int sfn4111t_init(struct efx_nic *efx)
 	if (rc)
 		goto fail_hwmon;
 
-	if (efx->phy_mode & PHY_MODE_SPECIAL) {
-		efx_stats_disable(efx);
-		sfn4111t_reset(efx);
-	}
-
-	return 0;
+	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.29-gnu1/drivers/net/sfc/tenxpress.c linux-libre-2.6.30-gnu1/drivers/net/sfc/tenxpress.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/tenxpress.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/tenxpress.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/rtnetlink.h>
 #include <linux/seq_file.h>
 #include "efx.h"
 #include "mdio_10g.h"
@@ -157,14 +158,16 @@
 #define PCS_10GBASET_BLKLK_WIDTH 1
 
 /* Boot status register */
-#define PCS_BOOT_STATUS_REG	53248
-#define PCS_BOOT_FATAL_ERR_LBN	(0)
-#define PCS_BOOT_PROGRESS_LBN	(1)
-#define PCS_BOOT_PROGRESS_WIDTH	(2)
-#define PCS_BOOT_COMPLETE_LBN	(3)
-
-#define PCS_BOOT_MAX_DELAY	(100)
-#define PCS_BOOT_POLL_DELAY	(10)
+#define PCS_BOOT_STATUS_REG		53248
+#define PCS_BOOT_FATAL_ERROR_LBN	0
+#define PCS_BOOT_PROGRESS_LBN		1
+#define PCS_BOOT_PROGRESS_WIDTH		2
+#define PCS_BOOT_PROGRESS_INIT		0
+#define PCS_BOOT_PROGRESS_WAIT_MDIO	1
+#define PCS_BOOT_PROGRESS_CHECKSUM	2
+#define PCS_BOOT_PROGRESS_JUMP		3
+#define PCS_BOOT_DOWNLOAD_WAIT_LBN	3
+#define PCS_BOOT_CODE_STARTED_LBN	4
 
 /* 100M/1G PHY registers */
 #define GPHY_XCONTROL_REG	49152
@@ -229,40 +232,62 @@ static ssize_t set_phy_short_reach(struc
 static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
 		   set_phy_short_reach);
 
-/* Check that the C166 has booted successfully */
-static int tenxpress_phy_check(struct efx_nic *efx)
+int sft9001_wait_boot(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
-	int count = PCS_BOOT_MAX_DELAY / PCS_BOOT_POLL_DELAY;
+	unsigned long timeout = jiffies + HZ + 1;
 	int boot_stat;
 
-	/* Wait for the boot to complete (or not) */
-	while (count) {
-		boot_stat = mdio_clause45_read(efx, phy_id,
+	for (;;) {
+		boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
 					       MDIO_MMD_PCS,
 					       PCS_BOOT_STATUS_REG);
-		if (boot_stat & (1 << PCS_BOOT_COMPLETE_LBN))
-			break;
-		count--;
-		udelay(PCS_BOOT_POLL_DELAY);
-	}
+		if (boot_stat >= 0) {
+			EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
+			switch (boot_stat &
+				((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+				 (3 << PCS_BOOT_PROGRESS_LBN) |
+				 (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+				 (1 << PCS_BOOT_CODE_STARTED_LBN))) {
+			case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+			      (PCS_BOOT_PROGRESS_CHECKSUM <<
+			       PCS_BOOT_PROGRESS_LBN)):
+			case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+			      (PCS_BOOT_PROGRESS_INIT <<
+			       PCS_BOOT_PROGRESS_LBN) |
+			      (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+				return -EINVAL;
+			case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
+			       PCS_BOOT_PROGRESS_LBN) |
+			      (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+				return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+					0 : -EIO;
+			case ((PCS_BOOT_PROGRESS_JUMP <<
+			       PCS_BOOT_PROGRESS_LBN) |
+			      (1 << PCS_BOOT_CODE_STARTED_LBN)):
+			case ((PCS_BOOT_PROGRESS_JUMP <<
+			       PCS_BOOT_PROGRESS_LBN) |
+			      (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+			      (1 << PCS_BOOT_CODE_STARTED_LBN)):
+				return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+					-EIO : 0;
+			default:
+				if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
+					return -EIO;
+				break;
+			}
+		}
 
-	if (!count) {
-		EFX_ERR(efx, "%s: PHY boot timed out. Last status "
-			"%x\n", __func__,
-			(boot_stat >> PCS_BOOT_PROGRESS_LBN) &
-			((1 << PCS_BOOT_PROGRESS_WIDTH) - 1));
-		return -ETIMEDOUT;
-	}
+		if (time_after_eq(jiffies, timeout))
+			return -ETIMEDOUT;
 
-	return 0;
+		msleep(50);
+	}
 }
 
 static int tenxpress_init(struct efx_nic *efx)
 {
 	int phy_id = efx->mii.phy_id;
 	int reg;
-	int rc;
 
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
 		/* Enable 312.5 MHz clock */
@@ -285,10 +310,6 @@ static int tenxpress_init(struct efx_nic
 				       false);
 	}
 
-	rc = tenxpress_phy_check(efx);
-	if (rc < 0)
-		return rc;
-
 	/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
 		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
@@ -299,7 +320,7 @@ static int tenxpress_init(struct efx_nic
 				    PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
 	}
 
-	return rc;
+	return 0;
 }
 
 static int tenxpress_phy_init(struct efx_nic *efx)
@@ -571,15 +592,14 @@ static void tenxpress_phy_reconfigure(st
 static void tenxpress_phy_poll(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data = efx->phy_data;
-	bool change = false, link_ok;
-	unsigned link_fc;
+	bool change = false;
 
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
-		link_ok = sfx7101_link_ok(efx);
+		bool link_ok = sfx7101_link_ok(efx);
 		if (link_ok != efx->link_up) {
 			change = true;
 		} else {
-			link_fc = mdio_clause45_get_pause(efx);
+			unsigned int link_fc = mdio_clause45_get_pause(efx);
 			if (link_fc != efx->link_fc)
 				change = true;
 		}
@@ -679,12 +699,10 @@ static int sft9001_run_tests(struct efx_
 {
 	struct ethtool_cmd ecmd;
 	int phy_id = efx->mii.phy_id;
-	int rc = 0, rc2, i, res_reg;
-
-	if (!(flags & ETH_TEST_FL_OFFLINE))
-		return 0;
+	int rc = 0, rc2, i, ctrl_reg, res_reg;
 
-	efx->phy_op->get_settings(efx, &ecmd);
+	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)
@@ -692,18 +710,22 @@ static int sft9001_run_tests(struct efx_
 
 	/* Run cable diagnostics; wait up to 5 seconds for them to complete.
 	 * A cable fault is not a self-test failure, but a timeout is. */
+	ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
+		    (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+	if (flags & ETH_TEST_FL_OFFLINE) {
+		/* Break the link in order to run full diagnostics.  We
+		 * must reset the PHY to resume normal service. */
+		ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
+	}
 	mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-			    PMA_PMD_CDIAG_CTRL_REG,
-			    (1 << CDIAG_CTRL_IMMED_LBN) |
-			    (1 << CDIAG_CTRL_BRK_LINK_LBN) |
-			    (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+			    PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
 	i = 0;
 	while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
 				  PMA_PMD_CDIAG_CTRL_REG) &
 	       (1 << CDIAG_CTRL_IN_PROG_LBN)) {
 		if (++i == 50) {
 			rc = -ETIMEDOUT;
-			goto reset;
+			goto out;
 		}
 		msleep(100);
 	}
@@ -728,17 +750,18 @@ static int sft9001_run_tests(struct efx_
 			results[5 + i] = len_reg;
 	}
 
-	/* We must reset to exit cable diagnostic mode.  The BIST will
-	 * also run when we do this. */
-reset:
-	rc2 = tenxpress_special_reset(efx);
-	results[0] = rc2 ? -1 : 1;
-	if (!rc)
-		rc = rc2;
+out:
+	if (flags & ETH_TEST_FL_OFFLINE) {
+		/* Reset, running the BIST and then resuming normal service. */
+		rc2 = tenxpress_special_reset(efx);
+		results[0] = rc2 ? -1 : 1;
+		if (!rc)
+			rc = rc2;
 
-	rc2 = efx->phy_op->set_settings(efx, &ecmd);
-	if (!rc)
-		rc = rc2;
+		rc2 = efx->phy_op->set_settings(efx, &ecmd);
+		if (!rc)
+			rc = rc2;
+	}
 
 	return rc;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/tx.c linux-libre-2.6.30-gnu1/drivers/net/sfc/tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -162,6 +162,14 @@ static int efx_enqueue_skb(struct efx_tx
 	/* Get size of the initial fragment */
 	len = skb_headlen(skb);
 
+	/* Pad if necessary */
+	if (EFX_WORKAROUND_15592(efx) && skb->len <= 32) {
+		EFX_BUG_ON_PARANOID(skb->data_len);
+		len = 32 + 1;
+		if (skb_pad(skb, len - skb->len))
+			return NETDEV_TX_OK;
+	}
+
 	fill_level = tx_queue->insert_count - tx_queue->old_read_count;
 	q_space = efx->type->txd_ring_mask - 1 - fill_level;
 
@@ -376,6 +384,9 @@ int efx_hard_start_xmit(struct sk_buff *
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_tx_queue *tx_queue;
 
+	if (unlikely(efx->port_inhibited))
+		return NETDEV_TX_BUSY;
+
 	if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
 		tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
 	else
@@ -397,7 +408,7 @@ void efx_xmit_done(struct efx_tx_queue *
 	 * separates the update of read_count from the test of
 	 * stopped. */
 	smp_mb();
-	if (unlikely(tx_queue->stopped)) {
+	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)) {
 			EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/workarounds.h linux-libre-2.6.30-gnu1/drivers/net/sfc/workarounds.h
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/workarounds.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/workarounds.h	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,8 @@
 #define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS
 /* Flush events can take a very long time to appear */
 #define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS
+/* Truncated IPv4 packets can confuse the TX packet parser */
+#define EFX_WORKAROUND_15592 EFX_WORKAROUND_ALWAYS
 
 /* Spurious parity errors in TSORT buffers */
 #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sfc/xfp_phy.c linux-libre-2.6.30-gnu1/drivers/net/sfc/xfp_phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/sfc/xfp_phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sfc/xfp_phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,8 +7,8 @@
  * by the Free Software Foundation, incorporated herein by reference.
  */
 /*
- * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32)
- * See www.amcc.com for details (search for qt2032)
+ * 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>
@@ -31,6 +31,21 @@
 /* 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;
@@ -45,7 +60,49 @@ struct xfp_phy_data {
 #define XFP_MAX_RESET_TIME 500
 #define XFP_RESET_WAIT 10
 
-/* Reset the PHYXS MMD. This is documented (for the Quake PHY) as doing
+static int qt2025c_wait_reset(struct efx_nic *efx)
+{
+	unsigned long timeout = jiffies + 10 * HZ;
+	int phy_id = efx->mii.phy_id;
+	int reg, old_counter = 0;
+
+	/* Wait for firmware heartbeat to start */
+	for (;;) {
+		int counter;
+		reg = mdio_clause45_read(efx, phy_id, 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 = mdio_clause45_read(efx, phy_id, 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;
+}
+
+/* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing
  * a complete soft reset.
  */
 static int xfp_reset_phy(struct efx_nic *efx)
@@ -58,6 +115,12 @@ static int xfp_reset_phy(struct efx_nic
 	if (rc < 0)
 		goto fail;
 
+	if (efx->phy_type == PHY_TYPE_QT2025C) {
+		rc = qt2025c_wait_reset(efx);
+		if (rc < 0)
+			goto fail;
+	}
+
 	/* Wait 250ms for the PHY to complete bootup */
 	msleep(250);
 
@@ -73,7 +136,7 @@ static int xfp_reset_phy(struct efx_nic
 	return rc;
 
  fail:
-	EFX_ERR(efx, "XFP: reset timed out!\n");
+	EFX_ERR(efx, "PHY reset timed out\n");
 	return rc;
 }
 
@@ -88,15 +151,15 @@ static int xfp_phy_init(struct efx_nic *
 		return -ENOMEM;
 	efx->phy_data = phy_data;
 
-	EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
-		 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
-		 MDIO_ID_REV(devid));
+	EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
+		 devid, mdio_id_oui(devid), mdio_id_model(devid),
+		 mdio_id_rev(devid));
 
 	phy_data->phy_mode = efx->phy_mode;
 
 	rc = xfp_reset_phy(efx);
 
-	EFX_INFO(efx, "XFP: PHY init %s.\n",
+	EFX_INFO(efx, "PHY init %s.\n",
 		 rc ? "failed" : "successful");
 	if (rc < 0)
 		goto fail;
@@ -131,12 +194,28 @@ static void xfp_phy_reconfigure(struct e
 {
 	struct xfp_phy_data *phy_data = efx->phy_data;
 
-	/* 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);
+	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_clause45_set_flag(
+			efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
+			PMA_PMD_FTX_CTRL2_REG, 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);
+
+		mdio_clause45_transmit_disable(efx);
+	}
 
-	mdio_clause45_transmit_disable(efx);
 	mdio_clause45_phy_reconfigure(efx);
 
 	phy_data->phy_mode = efx->phy_mode;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sh_eth.c linux-libre-2.6.30-gnu1/drivers/net/sh_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/sh_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sh_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -1188,6 +1188,19 @@ out:
 	return ret;
 }
 
+static const struct net_device_ops sh_eth_netdev_ops = {
+	.ndo_open		= sh_eth_open,
+	.ndo_stop		= sh_eth_close,
+	.ndo_start_xmit		= sh_eth_start_xmit,
+	.ndo_get_stats		= sh_eth_get_stats,
+	.ndo_set_multicast_list	= sh_eth_set_multicast_list,
+	.ndo_tx_timeout		= sh_eth_tx_timeout,
+	.ndo_do_ioctl		= sh_eth_do_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int sh_eth_drv_probe(struct platform_device *pdev)
 {
 	int ret, i, devno = 0;
@@ -1240,13 +1253,7 @@ static int sh_eth_drv_probe(struct platf
 	mdp->edmac_endian = pd->edmac_endian;
 
 	/* set function */
-	ndev->open = sh_eth_open;
-	ndev->hard_start_xmit = sh_eth_start_xmit;
-	ndev->stop = sh_eth_close;
-	ndev->get_stats = sh_eth_get_stats;
-	ndev->set_multicast_list = sh_eth_set_multicast_list;
-	ndev->do_ioctl = sh_eth_do_ioctl;
-	ndev->tx_timeout = sh_eth_tx_timeout;
+	ndev->netdev_ops = &sh_eth_netdev_ops;
 	ndev->watchdog_timeo = TX_TIMEOUT;
 
 	mdp->post_rx = POST_RX >> (devno << 1);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sis190.c linux-libre-2.6.30-gnu1/drivers/net/sis190.c
--- linux-libre-2.6.29-gnu1/drivers/net/sis190.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sis190.c	2009-06-09 23:05:27.000000000 -0400
@@ -1467,7 +1467,7 @@ static struct net_device * __devinit sis
 		goto err_pci_disable_2;
 	}
 
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc < 0) {
 		net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n",
 			  pci_name(pdev));
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sis900.c linux-libre-2.6.30-gnu1/drivers/net/sis900.c
--- linux-libre-2.6.29-gnu1/drivers/net/sis900.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sis900.c	2009-06-09 23:05:27.000000000 -0400
@@ -80,8 +80,8 @@
 #define SIS900_MODULE_NAME "sis900"
 #define SIS900_DRV_VERSION "v1.08.10 Apr. 2 2006"
 
-static char version[] __devinitdata =
-KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
+static const char version[] __devinitconst =
+	KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
 
 static int max_interrupt_work = 40;
 static int multicast_filter_limit = 128;
@@ -432,7 +432,7 @@ static int __devinit sis900_probe(struct
 	ret = pci_enable_device(pci_dev);
 	if(ret) return ret;
 
-	i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
+	i = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
 	if(i){
 		printk(KERN_ERR "sis900.c: architecture does not support "
 			"32bit PCI busmaster DMA\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/h/hwmtm.h linux-libre-2.6.30-gnu1/drivers/net/skfp/h/hwmtm.h
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/h/hwmtm.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/h/hwmtm.h	2009-06-09 23:05:27.000000000 -0400
@@ -145,7 +145,7 @@ struct hw_modul {
 	int	leave_isr ;		/* leave fddi_isr immedeately if set */
 	int	isr_flag ;		/* set, when HWM is entered from isr */
 	/*
-	 * varaibles for the current transmit frame
+	 * variables for the current transmit frame
 	 */
 	struct s_smt_tx_queue *tx_p ;	/* pointer to the transmit queue */
 	u_long	tx_descr ;		/* tx descriptor for FORMAC+ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/h/smc.h linux-libre-2.6.30-gnu1/drivers/net/skfp/h/smc.h
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/h/smc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/h/smc.h	2009-06-09 23:05:27.000000000 -0400
@@ -467,5 +467,22 @@ struct s_smc {
 #endif	/* DEBUG_BRD && DEBUG */
 } ;
 
+extern const struct fddi_addr fddi_broadcast;
+
+extern void all_selection_criteria(struct s_smc *smc);
+extern void card_stop(struct s_smc *smc);
+extern void init_board(struct s_smc *smc, u_char *mac_addr);
+extern int init_fplus(struct s_smc *smc);
+extern void init_plc(struct s_smc *smc);
+extern int init_smt(struct s_smc *smc, u_char * mac_addr);
+extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
+extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
+extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
+extern int pcm_status_twisted(struct s_smc *smc);
+extern void plc1_irq(struct s_smc *smc);
+extern void plc2_irq(struct s_smc *smc);
+extern void read_address(struct s_smc *smc, u_char * mac_addr);
+extern void timer_irq(struct s_smc *smc);
+
 #endif	/* _SCMECM_ */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/hwmtm.c linux-libre-2.6.30-gnu1/drivers/net/skfp/hwmtm.c
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/hwmtm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/hwmtm.c	2009-06-09 23:05:27.000000000 -0400
@@ -97,23 +97,15 @@ static void mac_drv_clear_txd(struct s_s
 
 extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);
 extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);
-extern void init_board(struct s_smc *smc, u_char *mac_addr);
 extern void mac_drv_fill_rxd(struct s_smc *smc);
-extern void plc1_irq(struct s_smc *smc);
 extern void mac_drv_tx_complete(struct s_smc *smc,
 				volatile struct s_smt_fp_txd *txd);
-extern void plc2_irq(struct s_smc *smc);
-extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
-extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
-extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
-extern void timer_irq(struct s_smc *smc);
 extern void mac_drv_rx_complete(struct s_smc *smc,
 				volatile struct s_smt_fp_rxd *rxd,
 				int frag_count, int len);
 extern void mac_drv_requeue_rxd(struct s_smc *smc, 
 				volatile struct s_smt_fp_rxd *rxd,
 				int frag_count);
-extern void init_plc(struct s_smc *smc);
 extern void mac_drv_clear_rxd(struct s_smc *smc,
 			      volatile struct s_smt_fp_rxd *rxd, int frag_count);
 
@@ -136,7 +128,6 @@ extern void dma_complete(struct s_smc *s
 			 int flag);
 #endif
 
-extern int init_fplus(struct s_smc *smc);
 extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
 			   int la_len);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/pcmplc.c linux-libre-2.6.30-gnu1/drivers/net/skfp/pcmplc.c
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/pcmplc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/pcmplc.c	2009-06-09 23:05:27.000000000 -0400
@@ -198,9 +198,6 @@ static int plc_imsk_na = PL_PCM_CODE | P
 static const int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
 			PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;
 
-/* external functions */
-void all_selection_criteria(struct s_smc *smc);
-
 /* internal functions */
 static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);
 static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/skfddi.c linux-libre-2.6.30-gnu1/drivers/net/skfp/skfddi.c
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/skfddi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/skfddi.c	2009-06-09 23:05:27.000000000 -0400
@@ -135,14 +135,11 @@ void dump_data(unsigned char *Data, int
 
 // External functions from the hardware module
 extern u_int mac_drv_check_space(void);
-extern void read_address(struct s_smc *smc, u_char * mac_addr);
-extern void card_stop(struct s_smc *smc);
 extern int mac_drv_init(struct s_smc *smc);
 extern void hwm_tx_frag(struct s_smc *smc, char far * virt, u_long phys,
 			int len, int frame_status);
 extern int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count,
 		       int frame_len, int frame_status);
-extern int init_smt(struct s_smc *smc, u_char * mac_addr);
 extern void fddi_isr(struct s_smc *smc);
 extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys,
 			int len, int frame_status);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skfp/smt.c linux-libre-2.6.30-gnu1/drivers/net/skfp/smt.c
--- linux-libre-2.6.29-gnu1/drivers/net/skfp/smt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skfp/smt.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,16 +55,6 @@ static const struct fddi_addr SMT_Unknow
 } ;
 
 /*
- * external variables
- */
-extern const struct fddi_addr fddi_broadcast ;
-
-/*
- * external functions
- */
-int pcm_status_twisted(struct s_smc *smc);
-
-/*
  * function prototypes
  */
 #ifdef	LITTLE_ENDIAN
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/skge.c linux-libre-2.6.30-gnu1/drivers/net/skge.c
--- linux-libre-2.6.29-gnu1/drivers/net/skge.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/skge.c	2009-06-09 23:05:27.000000000 -0400
@@ -2674,7 +2674,7 @@ static int skge_down(struct net_device *
 	if (netif_msg_ifdown(skge))
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
-	netif_stop_queue(dev);
+	netif_tx_disable(dev);
 
 	if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
 		del_timer_sync(&skge->link_timer);
@@ -2881,7 +2881,6 @@ static void skge_tx_clean(struct net_dev
 	}
 
 	skge->tx_ring.to_clean = e;
-	netif_wake_queue(dev);
 }
 
 static void skge_tx_timeout(struct net_device *dev)
@@ -2893,6 +2892,7 @@ static void skge_tx_timeout(struct net_d
 
 	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP);
 	skge_tx_clean(dev);
+	netif_wake_queue(dev);
 }
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
@@ -3214,7 +3214,7 @@ static int skge_poll(struct napi_struct
 		unsigned long flags;
 
 		spin_lock_irqsave(&hw->hw_lock, flags);
-		__netif_rx_complete(napi);
+		__napi_complete(napi);
 		hw->intr_mask |= napimask[skge->port];
 		skge_write32(hw, B0_IMSK, hw->intr_mask);
 		skge_read32(hw, B0_IMSK);
@@ -3377,7 +3377,7 @@ static irqreturn_t skge_intr(int irq, vo
 	if (status & (IS_XA1_F|IS_R1_F)) {
 		struct skge_port *skge = netdev_priv(hw->dev[0]);
 		hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
-		netif_rx_schedule(&skge->napi);
+		napi_schedule(&skge->napi);
 	}
 
 	if (status & IS_PA_TO_TX1)
@@ -3397,7 +3397,7 @@ static irqreturn_t skge_intr(int irq, vo
 
 		if (status & (IS_XA2_F|IS_R2_F)) {
 			hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
-			netif_rx_schedule(&skge->napi);
+			napi_schedule(&skge->napi);
 		}
 
 		if (status & IS_PA_TO_RX2) {
@@ -3912,12 +3912,12 @@ static int __devinit skge_probe(struct p
 
 	pci_set_master(pdev);
 
-	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-	} else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	} else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 		using_dac = 0;
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	}
 
 	if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sky2.c linux-libre-2.6.30-gnu1/drivers/net/sky2.c
--- linux-libre-2.6.29-gnu1/drivers/net/sky2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sky2.c	2009-06-09 23:05:27.000000000 -0400
@@ -1068,13 +1068,16 @@ static void sky2_rx_submit(struct sky2_p
 }
 
 
-static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
 			    unsigned size)
 {
 	struct sk_buff *skb = re->skb;
 	int i;
 
 	re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+	if (unlikely(pci_dma_mapping_error(pdev, re->data_addr)))
+		return -EIO;
+
 	pci_unmap_len_set(re, data_size, size);
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
@@ -1083,6 +1086,7 @@ static void sky2_rx_map_skb(struct pci_d
 						skb_shinfo(skb)->frags[i].page_offset,
 						skb_shinfo(skb)->frags[i].size,
 						PCI_DMA_FROMDEVICE);
+	return 0;
 }
 
 static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
@@ -1354,7 +1358,12 @@ static int sky2_rx_start(struct sky2_por
 		if (!re->skb)
 			goto nomem;
 
-		sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+		if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
+			dev_kfree_skb(re->skb);
+			re->skb = NULL;
+			goto nomem;
+		}
+
 		sky2_rx_submit(sky2, re);
 	}
 
@@ -1547,7 +1556,7 @@ static int sky2_xmit_frame(struct sk_buf
 	struct sky2_hw *hw = sky2->hw;
 	struct sky2_tx_le *le = NULL;
 	struct tx_ring_info *re;
-	unsigned i, len;
+	unsigned i, len, first_slot;
 	dma_addr_t mapping;
 	u16 mss;
 	u8 ctrl;
@@ -1555,13 +1564,17 @@ static int sky2_xmit_frame(struct sk_buf
  	if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
   		return NETDEV_TX_BUSY;
 
-	if (unlikely(netif_msg_tx_queued(sky2)))
-		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
-		       dev->name, sky2->tx_prod, skb->len);
-
 	len = skb_headlen(skb);
 	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
 
+	if (pci_dma_mapping_error(hw->pdev, mapping))
+		goto mapping_error;
+
+	first_slot = sky2->tx_prod;
+	if (unlikely(netif_msg_tx_queued(sky2)))
+		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+		       dev->name, first_slot, skb->len);
+
 	/* Send high bits if needed */
 	if (sizeof(dma_addr_t) > sizeof(u32)) {
 		le = get_tx_le(sky2);
@@ -1648,6 +1661,9 @@ static int sky2_xmit_frame(struct sk_buf
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
 
+		if (pci_dma_mapping_error(hw->pdev, mapping))
+			goto mapping_unwind;
+
 		if (sizeof(dma_addr_t) > sizeof(u32)) {
 			le = get_tx_le(sky2);
 			le->addr = cpu_to_le32(upper_32_bits(mapping));
@@ -1676,6 +1692,34 @@ static int sky2_xmit_frame(struct sk_buf
 
 	dev->trans_start = jiffies;
 	return NETDEV_TX_OK;
+
+mapping_unwind:
+	for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) {
+		le = sky2->tx_le + i;
+		re = sky2->tx_ring + i;
+
+		switch(le->opcode & ~HW_OWNER) {
+		case OP_LARGESEND:
+		case OP_PACKET:
+			pci_unmap_single(hw->pdev,
+					 pci_unmap_addr(re, mapaddr),
+					 pci_unmap_len(re, maplen),
+					 PCI_DMA_TODEVICE);
+			break;
+		case OP_BUFFER:
+			pci_unmap_page(hw->pdev, pci_unmap_addr(re, mapaddr),
+				       pci_unmap_len(re, maplen),
+				       PCI_DMA_TODEVICE);
+			break;
+		}
+	}
+
+	sky2->tx_prod = first_slot;
+mapping_error:
+	if (net_ratelimit())
+		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -2191,7 +2235,11 @@ static struct sk_buff *receive_new(struc
 
 	prefetch(skb->data);
 	re->skb = nskb;
-	sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+	if (sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space)) {
+		dev_kfree_skb(nskb);
+		re->skb = skb;
+		return NULL;
+	}
 
 	if (skb_shinfo(skb)->nr_frags)
 		skb_put_frags(skb, hdr_space, length);
@@ -2687,13 +2735,6 @@ static int sky2_poll(struct napi_struct
 			goto done;
 	}
 
-	/* Bug/Errata workaround?
-	 * Need to kick the TX irq moderation timer.
-	 */
-	if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
-		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
-		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
-	}
 	napi_complete(napi);
 	sky2_read32(hw, B0_Y2_SP_LISR);
 done:
@@ -3864,6 +3905,86 @@ static const struct ethtool_ops sky2_eth
 
 static struct dentry *sky2_debug;
 
+
+/*
+ * Read and parse the first part of Vital Product Data
+ */
+#define VPD_SIZE	128
+#define VPD_MAGIC	0x82
+
+static const struct vpd_tag {
+	char tag[2];
+	char *label;
+} vpd_tags[] = {
+	{ "PN",	"Part Number" },
+	{ "EC", "Engineering Level" },
+	{ "MN", "Manufacturer" },
+	{ "SN", "Serial Number" },
+	{ "YA", "Asset Tag" },
+	{ "VL", "First Error Log Message" },
+	{ "VF", "Second Error Log Message" },
+	{ "VB", "Boot Agent ROM Configuration" },
+	{ "VE", "EFI UNDI Configuration" },
+};
+
+static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
+{
+	size_t vpd_size;
+	loff_t offs;
+	u8 len;
+	unsigned char *buf;
+	u16 reg2;
+
+	reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+	vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+
+	seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
+	buf = kmalloc(vpd_size, GFP_KERNEL);
+	if (!buf) {
+		seq_puts(seq, "no memory!\n");
+		return;
+	}
+
+	if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
+		seq_puts(seq, "VPD read failed\n");
+		goto out;
+	}
+
+	if (buf[0] != VPD_MAGIC) {
+		seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
+		goto out;
+	}
+	len = buf[1];
+	if (len == 0 || len > vpd_size - 4) {
+		seq_printf(seq, "Invalid id length: %d\n", len);
+		goto out;
+	}
+
+	seq_printf(seq, "%.*s\n", len, buf + 3);
+	offs = len + 3;
+
+	while (offs < vpd_size - 4) {
+		int i;
+
+		if (!memcmp("RW", buf + offs, 2))	/* end marker */
+			break;
+		len = buf[offs + 2];
+		if (offs + len + 3 >= vpd_size)
+			break;
+
+		for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+			if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
+				seq_printf(seq, " %s: %.*s\n",
+					   vpd_tags[i].label, len, buf + offs + 3);
+				break;
+			}
+		}
+		offs += len + 3;
+	}
+out:
+	kfree(buf);
+}
+
 static int sky2_debug_show(struct seq_file *seq, void *v)
 {
 	struct net_device *dev = seq->private;
@@ -3873,14 +3994,18 @@ static int sky2_debug_show(struct seq_fi
 	unsigned idx, last;
 	int sop;
 
-	if (!netif_running(dev))
-		return -ENETDOWN;
+	sky2_show_vpd(seq, hw);
 
-	seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+	seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
 		   sky2_read32(hw, B0_ISRC),
 		   sky2_read32(hw, B0_IMSK),
 		   sky2_read32(hw, B0_Y2_SP_ICR));
 
+	if (!netif_running(dev)) {
+		seq_printf(seq, "network not running\n");
+		return 0;
+	}
+
 	napi_disable(&hw->napi);
 	last = sky2_read16(hw, STAT_PUT_IDX);
 
@@ -4204,69 +4329,6 @@ static int __devinit sky2_test_msi(struc
 	return err;
 }
 
-/*
- * Read and parse the first part of Vital Product Data
- */
-#define VPD_SIZE	128
-#define VPD_MAGIC	0x82
-
-static void __devinit sky2_vpd_info(struct sky2_hw *hw)
-{
-	int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD);
-	const u8 *p;
-	u8 *vpd_buf = NULL;
-	u16 len;
-	static struct vpd_tag {
-		char tag[2];
-		char *label;
-	} vpd_tags[] = {
-		{ "PN",	"Part Number" },
-		{ "EC", "Engineering Level" },
-		{ "MN", "Manufacturer" },
-	};
-
-	if (!cap)
-		goto out;
-
-	vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL);
-	if (!vpd_buf)
-		goto out;
-
-	if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE))
-		goto out;
-
-	if (vpd_buf[0] != VPD_MAGIC)
-		goto out;
-	len = vpd_buf[1];
-	if (len == 0 || len > VPD_SIZE - 4)
-		goto out;
-	p = vpd_buf + 3;
-	dev_info(&hw->pdev->dev, "%.*s\n", len, p);
-	p += len;
-
-	while (p < vpd_buf + VPD_SIZE - 4) {
-		int i;
-
-		if (!memcmp("RW", p, 2))	/* end marker */
-			break;
-
-		len = p[2];
-		if (len > (p - vpd_buf) - 4)
-			break;
-
-		for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
-			if (!memcmp(vpd_tags[i].tag, p, 2)) {
-				printk(KERN_DEBUG " %s: %.*s\n",
-				       vpd_tags[i].label, len, p + 3);
-				break;
-			}
-		}
-		p += len + 3;
-	}
-out:
-	kfree(vpd_buf);
-}
-
 /* This driver supports yukon2 chipset only */
 static const char *sky2_name(u8 chipid, char *buf, int sz)
 {
@@ -4294,6 +4356,7 @@ static int __devinit sky2_probe(struct p
 	struct net_device *dev;
 	struct sky2_hw *hw;
 	int err, using_dac = 0, wol_default;
+	u32 reg;
 	char buf1[16];
 
 	err = pci_enable_device(pdev);
@@ -4311,22 +4374,50 @@ static int __devinit sky2_probe(struct p
 	pci_set_master(pdev);
 
 	if (sizeof(dma_addr_t) > sizeof(u32) &&
-	    !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+	    !(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))) {
 		using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (err < 0) {
 			dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
 				"for consistent allocations\n");
 			goto err_out_free_regions;
 		}
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			dev_err(&pdev->dev, "no usable DMA configuration\n");
 			goto err_out_free_regions;
 		}
 	}
 
+	/* Get configuration information
+	 * Note: only regular PCI config access once to test for HW issues
+	 *       other PCI access through shared memory for speed and to
+	 *	 avoid MMCONFIG problems.
+	 */
+	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+	if (err) {
+		dev_err(&pdev->dev, "PCI read config failed\n");
+		goto err_out_free_regions;
+	}
+
+	/* size of available VPD, only impact sysfs */
+	err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
+	if (err)
+		dev_warn(&pdev->dev, "Can't set VPD size\n");
+
+#ifdef __BIG_ENDIAN
+	/* The sk98lin vendor driver uses hardware byte swapping but
+	 * this driver uses software swapping.
+	 */
+	reg &= ~PCI_REV_DESC;
+	err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg);
+	if (err) {
+		dev_err(&pdev->dev, "PCI write config failed\n");
+		goto err_out_free_regions;
+	}
+#endif
+
 	wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
 
 	err = -ENOMEM;
@@ -4344,18 +4435,6 @@ static int __devinit sky2_probe(struct p
 		goto err_out_free_hw;
 	}
 
-#ifdef __BIG_ENDIAN
-	/* The sk98lin vendor driver uses hardware byte swapping but
-	 * this driver uses software swapping.
-	 */
-	{
-		u32 reg;
-		reg = sky2_pci_read32(hw, PCI_DEV_REG2);
-		reg &= ~PCI_REV_DESC;
-		sky2_pci_write32(hw, PCI_DEV_REG2, reg);
-	}
-#endif
-
 	/* ring for status responses */
 	hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
 	if (!hw->st_le)
@@ -4370,8 +4449,6 @@ static int __devinit sky2_probe(struct p
 
 	sky2_reset(hw);
 
-	sky2_vpd_info(hw);
-
 	dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
 	if (!dev) {
 		err = -ENOMEM;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc911x.c linux-libre-2.6.30-gnu1/drivers/net/smc911x.c
--- linux-libre-2.6.29-gnu1/drivers/net/smc911x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc911x.c	2009-06-09 23:05:27.000000000 -0400
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_de
 {
 	strncpy(info->driver, CARDNAME, sizeof(info->driver));
 	strncpy(info->version, version, sizeof(info->version));
-	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+	strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
 }
 
 static int smc911x_ethtool_nwayreset(struct net_device *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc911x.h linux-libre-2.6.30-gnu1/drivers/net/smc911x.h
--- linux-libre-2.6.29-gnu1/drivers/net/smc911x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc911x.h	2009-06-09 23:05:27.000000000 -0400
@@ -236,8 +236,7 @@ static inline void SMC_outsl(struct smc9
  * Use a DMA for RX and TX packets.
  */
 #include <linux/dma-mapping.h>
-#include <asm/dma.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
 
 static dma_addr_t rx_dmabuf, tx_dmabuf;
 static int rx_dmalen, tx_dmalen;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc9194.c linux-libre-2.6.30-gnu1/drivers/net/smc9194.c
--- linux-libre-2.6.29-gnu1/drivers/net/smc9194.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc9194.c	2009-06-09 23:05:27.000000000 -0400
@@ -831,6 +831,17 @@ static int __init smc_findirq(int ioaddr
 #endif
 }
 
+static const struct net_device_ops smc_netdev_ops = {
+	.ndo_open		 = smc_open,
+	.ndo_stop		= smc_close,
+	.ndo_start_xmit    	= smc_wait_to_send_packet,
+	.ndo_tx_timeout	    	= smc_timeout,
+	.ndo_set_multicast_list	= smc_set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*----------------------------------------------------------------------
  . Function: smc_probe( int ioaddr )
  .
@@ -1044,12 +1055,8 @@ static int __init smc_probe(struct net_d
   	  	goto err_out;
       	}
 
-	dev->open		        = smc_open;
-	dev->stop		        = smc_close;
-	dev->hard_start_xmit    	= smc_wait_to_send_packet;
-	dev->tx_timeout		    	= smc_timeout;
+	dev->netdev_ops			= &smc_netdev_ops;
 	dev->watchdog_timeo		= HZ/20;
-	dev->set_multicast_list 	= smc_set_multicast_list;
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc91x.c linux-libre-2.6.30-gnu1/drivers/net/smc91x.c
--- linux-libre-2.6.29-gnu1/drivers/net/smc91x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc91x.c	2009-06-09 23:05:27.000000000 -0400
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device
 {
 	strncpy(info->driver, CARDNAME, sizeof(info->driver));
 	strncpy(info->version, version, sizeof(info->version));
-	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+	strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
 }
 
 static int smc_ethtool_nwayreset(struct net_device *dev)
@@ -1643,6 +1643,117 @@ static void smc_ethtool_setmsglevel(stru
 	lp->msg_enable = level;
 }
 
+static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word)
+{
+	u16 ctl;
+	struct smc_local *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	spin_lock_irq(&lp->lock);
+	/* load word into GP register */
+	SMC_SELECT_BANK(lp, 1);
+	SMC_SET_GP(lp, word);
+	/* set the address to put the data in EEPROM */
+	SMC_SELECT_BANK(lp, 2);
+	SMC_SET_PTR(lp, addr);
+	/* tell it to write */
+	SMC_SELECT_BANK(lp, 1);
+	ctl = SMC_GET_CTL(lp);
+	SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE));
+	/* wait for it to finish */
+	do {
+		udelay(1);
+	} while (SMC_GET_CTL(lp) & CTL_STORE);
+	/* clean up */
+	SMC_SET_CTL(lp, ctl);
+	SMC_SELECT_BANK(lp, 2);
+	spin_unlock_irq(&lp->lock);
+	return 0;
+}
+
+static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word)
+{
+	u16 ctl;
+	struct smc_local *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	spin_lock_irq(&lp->lock);
+	/* set the EEPROM address to get the data from */
+	SMC_SELECT_BANK(lp, 2);
+	SMC_SET_PTR(lp, addr | PTR_READ);
+	/* tell it to load */
+	SMC_SELECT_BANK(lp, 1);
+	SMC_SET_GP(lp, 0xffff);	/* init to known */
+	ctl = SMC_GET_CTL(lp);
+	SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD));
+	/* wait for it to finish */
+	do {
+		udelay(1);
+	} while (SMC_GET_CTL(lp) & CTL_RELOAD);
+	/* read word from GP register */
+	*word = SMC_GET_GP(lp);
+	/* clean up */
+	SMC_SET_CTL(lp, ctl);
+	SMC_SELECT_BANK(lp, 2);
+	spin_unlock_irq(&lp->lock);
+	return 0;
+}
+
+static int smc_ethtool_geteeprom_len(struct net_device *dev)
+{
+	return 0x23 * 2;
+}
+
+static int smc_ethtool_geteeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	int i;
+	int imax;
+
+	DBG(1, "Reading %d bytes at %d(0x%x)\n",
+		eeprom->len, eeprom->offset, eeprom->offset);
+	imax = smc_ethtool_geteeprom_len(dev);
+	for (i = 0; i < eeprom->len; i += 2) {
+		int ret;
+		u16 wbuf;
+		int offset = i + eeprom->offset;
+		if (offset > imax)
+			break;
+		ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf);
+		if (ret != 0)
+			return ret;
+		DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1);
+		data[i] = (wbuf >> 8) & 0xff;
+		data[i+1] = wbuf & 0xff;
+	}
+	return 0;
+}
+
+static int smc_ethtool_seteeprom(struct net_device *dev,
+		struct ethtool_eeprom *eeprom, u8 *data)
+{
+	int i;
+	int imax;
+
+	DBG(1, "Writing %d bytes to %d(0x%x)\n",
+			eeprom->len, eeprom->offset, eeprom->offset);
+	imax = smc_ethtool_geteeprom_len(dev);
+	for (i = 0; i < eeprom->len; i += 2) {
+		int ret;
+		u16 wbuf;
+		int offset = i + eeprom->offset;
+		if (offset > imax)
+			break;
+		wbuf = (data[i] << 8) | data[i + 1];
+		DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1);
+		ret = smc_write_eeprom_word(dev, offset >> 1, wbuf);
+		if (ret != 0)
+			return ret;
+	}
+	return 0;
+}
+
+
 static const struct ethtool_ops smc_ethtool_ops = {
 	.get_settings	= smc_ethtool_getsettings,
 	.set_settings	= smc_ethtool_setsettings,
@@ -1652,8 +1763,22 @@ static const struct ethtool_ops smc_etht
 	.set_msglevel	= smc_ethtool_setmsglevel,
 	.nway_reset	= smc_ethtool_nwayreset,
 	.get_link	= ethtool_op_get_link,
-//	.get_eeprom	= smc_ethtool_geteeprom,
-//	.set_eeprom	= smc_ethtool_seteeprom,
+	.get_eeprom_len = smc_ethtool_geteeprom_len,
+	.get_eeprom	= smc_ethtool_geteeprom,
+	.set_eeprom	= smc_ethtool_seteeprom,
+};
+
+static const struct net_device_ops smc_netdev_ops = {
+	.ndo_open		= smc_open,
+	.ndo_stop		= smc_close,
+	.ndo_start_xmit		= smc_hard_start_xmit,
+	.ndo_tx_timeout		= smc_timeout,
+	.ndo_set_multicast_list	= smc_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address 	= eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= smc_poll_controller,
+#endif
 };
 
 /*
@@ -1865,16 +1990,9 @@ static int __devinit smc_probe(struct ne
 	/* Fill in the fields of the device structure with ethernet values. */
 	ether_setup(dev);
 
-	dev->open = smc_open;
-	dev->stop = smc_close;
-	dev->hard_start_xmit = smc_hard_start_xmit;
-	dev->tx_timeout = smc_timeout;
 	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
-	dev->set_multicast_list = smc_set_multicast_list;
+	dev->netdev_ops = &smc_netdev_ops;
 	dev->ethtool_ops = &smc_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = smc_poll_controller;
-#endif
 
 	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
 	INIT_WORK(&lp->phy_configure, smc_phy_configure);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc91x.h linux-libre-2.6.30-gnu1/drivers/net/smc91x.h
--- linux-libre-2.6.29-gnu1/drivers/net/smc91x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc91x.h	2009-06-09 23:05:27.000000000 -0400
@@ -44,6 +44,7 @@
     defined(CONFIG_MACH_MAINSTONE) ||\
     defined(CONFIG_MACH_ZYLONITE) ||\
     defined(CONFIG_MACH_LITTLETON) ||\
+    defined(CONFIG_MACH_ZYLONITE2) ||\
     defined(CONFIG_ARCH_VIPER)
 
 #include <asm/mach-types.h>
@@ -345,38 +346,6 @@ static inline void LPD7_SMC_outsw (unsig
 #define RPC_LSA_DEFAULT		RPC_LED_TX_RX
 #define RPC_LSB_DEFAULT		RPC_LED_100_10
 
-#elif defined(CONFIG_SOC_AU1X00)
-
-#include <au1xxx.h>
-
-/* 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)		au_readw((unsigned long)((a) + (r)))
-#define SMC_insw(a, r, p, l)	\
-	do {	\
-		unsigned long _a = (unsigned long)((a) + (r)); \
-		int _l = (l); \
-		u16 *_p = (u16 *)(p); \
-		while (_l-- > 0) \
-			*_p++ = au_readw(_a); \
-	} while(0)
-#define SMC_outw(v, a, r)	au_writew(v, (unsigned long)((a) + (r)))
-#define SMC_outsw(a, r, p, l)	\
-	do {	\
-		unsigned long _a = (unsigned long)((a) + (r)); \
-		int _l = (l); \
-		const u16 *_p = (const u16 *)(p); \
-		while (_l-- > 0) \
-			au_writew(*_p++ , _a); \
-	} while(0)
-
-#define SMC_IRQ_FLAGS		(0)
-
 #elif	defined(CONFIG_ARCH_VERSATILE)
 
 #define SMC_CAN_USE_8BIT	1
@@ -400,7 +369,7 @@ static inline void LPD7_SMC_outsw (unsig
  * MN10300/AM33 configuration
  */
 
-#include <asm/unit/smc91111.h>
+#include <unit/smc91111.h>
 
 #else
 
@@ -494,8 +463,6 @@ struct smc_local {
  */
 #include <linux/dma-mapping.h>
 #include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 
 #ifdef SMC_insl
 #undef SMC_insl
@@ -1141,6 +1108,16 @@ static const char * chip_ids[ 16 ] =  {
 
 #define SMC_GET_MII(lp)		SMC_inw(ioaddr, MII_REG(lp))
 
+#define SMC_GET_GP(lp)		SMC_inw(ioaddr, GP_REG(lp))
+
+#define SMC_SET_GP(lp, x)						\
+	do {								\
+		if (SMC_MUST_ALIGN_WRITE(lp))				\
+			SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1));	\
+		else							\
+			SMC_outw(x, ioaddr, GP_REG(lp));		\
+	} while (0)
+
 #define SMC_SET_MII(lp, x)		SMC_outw(x, ioaddr, MII_REG(lp))
 
 #define SMC_GET_MIR(lp)		SMC_inw(ioaddr, MIR_REG(lp))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc-ultra32.c linux-libre-2.6.30-gnu1/drivers/net/smc-ultra32.c
--- linux-libre-2.6.29-gnu1/drivers/net/smc-ultra32.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc-ultra32.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,6 +153,22 @@ out:
 	return ERR_PTR(err);
 }
 
+
+static const struct net_device_ops ultra32_netdev_ops = {
+	.ndo_open 		= ultra32_open,
+	.ndo_stop 		= ultra32_close,
+	.ndo_start_xmit		= ei_start_xmit,
+	.ndo_tx_timeout		= ei_tx_timeout,
+	.ndo_get_stats		= ei_get_stats,
+	.ndo_set_multicast_list = ei_set_multicast_list,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ei_poll,
+#endif
+};
+
 static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
 {
 	int i, edge, media, retval;
@@ -273,11 +289,8 @@ static int __init ultra32_probe1(struct
 	ei_status.block_output = &ultra32_block_output;
 	ei_status.get_8390_hdr = &ultra32_get_8390_hdr;
 	ei_status.reset_8390 = &ultra32_reset_8390;
-	dev->open = &ultra32_open;
-	dev->stop = &ultra32_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = ei_poll;
-#endif
+
+	dev->netdev_ops = &ultra32_netdev_ops;
 	NS8390_init(dev, 0);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smc-ultra.c linux-libre-2.6.30-gnu1/drivers/net/smc-ultra.c
--- linux-libre-2.6.29-gnu1/drivers/net/smc-ultra.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smc-ultra.c	2009-06-09 23:05:27.000000000 -0400
@@ -142,9 +142,6 @@ static int __init do_ultra_probe(struct
 	int base_addr = dev->base_addr;
 	int irq = dev->irq;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = &ultra_poll;
-#endif
 	if (base_addr > 0x1ff)		/* Check a single specified location. */
 		return ultra_probe1(dev, base_addr);
 	else if (base_addr != 0)	/* Don't probe at all. */
@@ -199,7 +196,7 @@ static const struct net_device_ops ultra
 	.ndo_set_mac_address 	= eth_mac_addr,
 	.ndo_change_mtu		= eth_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller 	= ei_poll,
+	.ndo_poll_controller 	= ultra_poll,
 #endif
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smsc911x.c linux-libre-2.6.30-gnu1/drivers/net/smsc911x.c
--- linux-libre-2.6.29-gnu1/drivers/net/smsc911x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smsc911x.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,7 +43,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
-#include <linux/version.h>
 #include <linux/bug.h>
 #include <linux/bitops.h>
 #include <linux/irq.h>
@@ -318,7 +317,7 @@ static int smsc911x_mii_read(struct mii_
 			goto out;
 		}
 
-	SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+	SMSC_WARNING(HW, "Timed out waiting for MII read to finish");
 	reg = -EIO;
 
 out:
@@ -368,48 +367,53 @@ out:
 	return reg;
 }
 
-/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors.
- * If something goes wrong, returns -ENODEV to revert back to internal phy.
- * Performed at initialisation only, so interrupts are enabled */
-static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+/* Switch to external phy. Assumes tx and rx are stopped. */
+static void smsc911x_phy_enable_external(struct smsc911x_data *pdata)
 {
 	unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
 
-	/* External phy is requested, supported, and detected */
-	if (hwcfg & HW_CFG_EXT_PHY_DET_) {
-
-		/* Switch to external phy. Assuming tx and rx are stopped
-		 * because smsc911x_phy_initialise is called before
-		 * smsc911x_rx_initialise and tx_initialise. */
+	/* Disable phy clocks to the MAC */
+	hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+	hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
+	smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+	udelay(10);	/* Enough time for clocks to stop */
 
-		/* Disable phy clocks to the MAC */
-		hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
-		hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
-		smsc911x_reg_write(pdata, HW_CFG, hwcfg);
-		udelay(10);	/* Enough time for clocks to stop */
+	/* Switch to external phy */
+	hwcfg |= HW_CFG_EXT_PHY_EN_;
+	smsc911x_reg_write(pdata, HW_CFG, hwcfg);
 
-		/* Switch to external phy */
-		hwcfg |= HW_CFG_EXT_PHY_EN_;
-		smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+	/* Enable phy clocks to the MAC */
+	hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+	hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
+	smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+	udelay(10);	/* Enough time for clocks to restart */
 
-		/* Enable phy clocks to the MAC */
-		hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
-		hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
-		smsc911x_reg_write(pdata, HW_CFG, hwcfg);
-		udelay(10);	/* Enough time for clocks to restart */
+	hwcfg |= HW_CFG_SMI_SEL_;
+	smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+}
 
-		hwcfg |= HW_CFG_SMI_SEL_;
-		smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+/* Autodetects and enables external phy if present on supported chips.
+ * autodetection can be overridden by specifying SMSC911X_FORCE_INTERNAL_PHY
+ * or SMSC911X_FORCE_EXTERNAL_PHY in the platform_data flags. */
+static void smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+{
+	unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
 
-		SMSC_TRACE(HW, "Successfully switched to external PHY");
+	if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) {
+		SMSC_TRACE(HW, "Forcing internal PHY");
+		pdata->using_extphy = 0;
+	} else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) {
+		SMSC_TRACE(HW, "Forcing external PHY");
+		smsc911x_phy_enable_external(pdata);
+		pdata->using_extphy = 1;
+	} else if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+		SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY");
+		smsc911x_phy_enable_external(pdata);
 		pdata->using_extphy = 1;
 	} else {
-		SMSC_WARNING(HW, "No external PHY detected, "
-			"Using internal PHY instead.");
-		/* Use internal phy */
-		return -ENODEV;
+		SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY");
+		pdata->using_extphy = 0;
 	}
-	return 0;
 }
 
 /* Fetches a tx status out of the status fifo */
@@ -769,7 +773,7 @@ static int smsc911x_mii_probe(struct net
 		return -ENODEV;
 	}
 
-	phydev = phy_connect(dev, phydev->dev.bus_id,
+	phydev = phy_connect(dev, dev_name(&phydev->dev),
 		&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
 
 	if (IS_ERR(phydev)) {
@@ -778,7 +782,8 @@ static int smsc911x_mii_probe(struct net
 	}
 
 	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
-		dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+		dev->name, phydev->drv->name,
+		dev_name(&phydev->dev), phydev->irq);
 
 	/* mask with MAC supported features */
 	phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -824,22 +829,18 @@ static int __devinit smsc911x_mii_init(s
 
 	pdata->mii_bus->parent = &pdev->dev;
 
-	pdata->using_extphy = 0;
-
 	switch (pdata->idrev & 0xFFFF0000) {
 	case 0x01170000:
 	case 0x01150000:
 	case 0x117A0000:
 	case 0x115A0000:
 		/* External PHY supported, try to autodetect */
-		if (smsc911x_phy_initialise_external(pdata) < 0) {
-			SMSC_TRACE(HW, "No external PHY detected, "
-				"using internal PHY");
-		}
+		smsc911x_phy_initialise_external(pdata);
 		break;
 	default:
 		SMSC_TRACE(HW, "External PHY is not supported, "
 			"using internal PHY");
+		pdata->using_extphy = 0;
 		break;
 	}
 
@@ -893,22 +894,22 @@ static void smsc911x_tx_update_txcounter
 			SMSC_WARNING(HW,
 				"Packet tag reserved bit is high");
 		} else {
-			if (unlikely(tx_stat & 0x00008000)) {
+			if (unlikely(tx_stat & TX_STS_ES_)) {
 				dev->stats.tx_errors++;
 			} else {
 				dev->stats.tx_packets++;
 				dev->stats.tx_bytes += (tx_stat >> 16);
 			}
-			if (unlikely(tx_stat & 0x00000100)) {
+			if (unlikely(tx_stat & TX_STS_EXCESS_COL_)) {
 				dev->stats.collisions += 16;
 				dev->stats.tx_aborted_errors += 1;
 			} else {
 				dev->stats.collisions +=
 				    ((tx_stat >> 3) & 0xF);
 			}
-			if (unlikely(tx_stat & 0x00000800))
+			if (unlikely(tx_stat & TX_STS_LOST_CARRIER_))
 				dev->stats.tx_carrier_errors += 1;
-			if (unlikely(tx_stat & 0x00000200)) {
+			if (unlikely(tx_stat & TX_STS_LATE_COL_)) {
 				dev->stats.collisions++;
 				dev->stats.tx_aborted_errors++;
 			}
@@ -922,19 +923,17 @@ smsc911x_rx_counterrors(struct net_devic
 {
 	int crc_err = 0;
 
-	if (unlikely(rxstat & 0x00008000)) {
+	if (unlikely(rxstat & RX_STS_ES_)) {
 		dev->stats.rx_errors++;
-		if (unlikely(rxstat & 0x00000002)) {
+		if (unlikely(rxstat & RX_STS_CRC_ERR_)) {
 			dev->stats.rx_crc_errors++;
 			crc_err = 1;
 		}
 	}
 	if (likely(!crc_err)) {
-		if (unlikely((rxstat & 0x00001020) == 0x00001020)) {
-			/* Frame type indicates length,
-			 * and length error is set */
+		if (unlikely((rxstat & RX_STS_FRAME_TYPE_) &&
+			     (rxstat & RX_STS_LENGTH_ERR_)))
 			dev->stats.rx_length_errors++;
-		}
 		if (rxstat & RX_STS_MCAST_)
 			dev->stats.multicast++;
 	}
@@ -953,7 +952,7 @@ smsc911x_rx_fastforward(struct smsc911x_
 		do {
 			udelay(1);
 			val = smsc911x_reg_read(pdata, RX_DP_CTRL);
-		} while (--timeout && (val & RX_DP_CTRL_RX_FFWD_));
+		} while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout);
 
 		if (unlikely(timeout == 0))
 			SMSC_WARNING(HW, "Timed out waiting for "
@@ -984,7 +983,7 @@ static int smsc911x_poll(struct napi_str
 			/* We processed all packets available.  Tell NAPI it can
 			 * stop polling then re-enable rx interrupts */
 			smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_);
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			temp = smsc911x_reg_read(pdata, INT_EN);
 			temp |= INT_EN_RSFL_EN_;
 			smsc911x_reg_write(pdata, INT_EN, temp);
@@ -1119,7 +1118,7 @@ static int smsc911x_soft_reset(struct sm
 
 /* Sets the device MAC address to dev_addr, called with mac_lock held */
 static void
-smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
+smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
 {
 	u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
 	u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
@@ -1160,8 +1159,8 @@ static int smsc911x_open(struct net_devi
 
 	/* Make sure EEPROM has finished loading before setting GPIO_CFG */
 	timeout = 50;
-	while ((timeout--) &&
-	       (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
+	while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) &&
+	       --timeout) {
 		udelay(10);
 	}
 
@@ -1174,7 +1173,7 @@ static int smsc911x_open(struct net_devi
 	/* The soft reset above cleared the device's MAC address,
 	 * restore it from local copy (set in probe) */
 	spin_lock_irq(&pdata->mac_lock);
-	smsc911x_set_mac_address(pdata, dev->dev_addr);
+	smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 	spin_unlock_irq(&pdata->mac_lock);
 
 	/* Initialise irqs, but leave all sources disabled */
@@ -1250,7 +1249,7 @@ static int smsc911x_open(struct net_devi
 	napi_enable(&pdata->napi);
 
 	temp = smsc911x_reg_read(pdata, INT_EN);
-	temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_);
+	temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_ | INT_EN_RXSTOP_INT_EN_);
 	smsc911x_reg_write(pdata, INT_EN, temp);
 
 	spin_lock_irq(&pdata->mac_lock);
@@ -1422,11 +1421,6 @@ static void smsc911x_set_multicast_list(
 
 			/* Request the hardware to stop, then perform the
 			 * update when we get an RX_STOP interrupt */
-			smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
-			temp = smsc911x_reg_read(pdata, INT_EN);
-			temp |= INT_EN_RXSTOP_INT_EN_;
-			smsc911x_reg_write(pdata, INT_EN, temp);
-
 			temp = smsc911x_mac_read(pdata, MAC_CR);
 			temp &= ~(MAC_CR_RXEN_);
 			smsc911x_mac_write(pdata, MAC_CR, temp);
@@ -1465,11 +1459,9 @@ static irqreturn_t smsc911x_irqhandler(i
 		/* Called when there is a multicast update scheduled and
 		 * it is now safe to complete the update */
 		SMSC_TRACE(INTR, "RX Stop interrupt");
-		temp = smsc911x_reg_read(pdata, INT_EN);
-		temp &= (~INT_EN_RXSTOP_INT_EN_);
-		smsc911x_reg_write(pdata, INT_EN, temp);
 		smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
-		smsc911x_rx_multicast_update_workaround(pdata);
+		if (pdata->multicast_update_pending)
+			smsc911x_rx_multicast_update_workaround(pdata);
 		serviced = IRQ_HANDLED;
 	}
 
@@ -1489,16 +1481,16 @@ static irqreturn_t smsc911x_irqhandler(i
 	}
 
 	if (likely(intsts & inten & INT_STS_RSFL_)) {
-		if (likely(netif_rx_schedule_prep(&pdata->napi))) {
+		if (likely(napi_schedule_prep(&pdata->napi))) {
 			/* Disable Rx interrupts */
 			temp = smsc911x_reg_read(pdata, INT_EN);
 			temp &= (~INT_EN_RSFL_EN_);
 			smsc911x_reg_write(pdata, INT_EN, temp);
 			/* Schedule a NAPI poll */
-			__netif_rx_schedule(&pdata->napi);
+			__napi_schedule(&pdata->napi);
 		} else {
 			SMSC_WARNING(RX_ERR,
-				"netif_rx_schedule_prep failed");
+				"napi_schedule_prep failed");
 		}
 		serviced = IRQ_HANDLED;
 	}
@@ -1515,6 +1507,31 @@ static void smsc911x_poll_controller(str
 }
 #endif				/* CONFIG_NET_POLL_CONTROLLER */
 
+static int smsc911x_set_mac_address(struct net_device *dev, void *p)
+{
+	struct smsc911x_data *pdata = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	/* On older hardware revisions we cannot change the mac address
+	 * registers while receiving data.  Newer devices can safely change
+	 * this at any time. */
+	if (pdata->generation <= 1 && netif_running(dev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	spin_lock_irq(&pdata->mac_lock);
+	smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
+	spin_unlock_irq(&pdata->mac_lock);
+
+	dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+
+	return 0;
+}
+
 /* Standard ioctls for mii-tool */
 static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -1549,7 +1566,7 @@ static void smsc911x_ethtool_getdrvinfo(
 {
 	strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
 	strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, dev->dev.parent->bus_id,
+	strlcpy(info->bus_info, dev_name(dev->dev.parent),
 		sizeof(info->bus_info));
 }
 
@@ -1662,6 +1679,7 @@ static int smsc911x_eeprom_write_locatio
 					  u8 address, u8 data)
 {
 	u32 op = E2P_CMD_EPC_CMD_ERASE_ | address;
+	u32 temp;
 	int ret;
 
 	SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data);
@@ -1670,6 +1688,10 @@ static int smsc911x_eeprom_write_locatio
 	if (!ret) {
 		op = E2P_CMD_EPC_CMD_WRITE_ | address;
 		smsc911x_reg_write(pdata, E2P_DATA, (u32)data);
+
+		/* Workaround for hardware read-after-write restriction */
+		temp = smsc911x_reg_read(pdata, BYTE_TEST);
+
 		ret = smsc911x_eeprom_send_cmd(pdata, op);
 	}
 
@@ -1745,12 +1767,27 @@ static const struct net_device_ops smsc9
 	.ndo_set_multicast_list	= smsc911x_set_multicast_list,
 	.ndo_do_ioctl		= smsc911x_do_ioctl,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_mac_address 	= smsc911x_set_mac_address,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= smsc911x_poll_controller,
 #endif
 };
 
+/* copies the current mac address from hardware to dev->dev_addr */
+static void __devinit smsc911x_read_mac_address(struct net_device *dev)
+{
+	struct smsc911x_data *pdata = netdev_priv(dev);
+	u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
+	u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
+
+	dev->dev_addr[0] = (u8)(mac_low32);
+	dev->dev_addr[1] = (u8)(mac_low32 >> 8);
+	dev->dev_addr[2] = (u8)(mac_low32 >> 16);
+	dev->dev_addr[3] = (u8)(mac_low32 >> 24);
+	dev->dev_addr[4] = (u8)(mac_high16);
+	dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+}
+
 /* Initializing private device structures, only called from probe */
 static int __devinit smsc911x_init(struct net_device *dev)
 {
@@ -1838,6 +1875,12 @@ static int __devinit smsc911x_init(struc
 		SMSC_WARNING(PROBE,
 			"This driver is not intended for this chip revision");
 
+	/* workaround for platforms without an eeprom, where the mac address
+	 * is stored elsewhere and set by the bootloader.  This saves the
+	 * mac address before resetting the device */
+	if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
+		smsc911x_read_mac_address(dev);
+
 	/* Reset the LAN911x */
 	if (smsc911x_soft_reset(pdata))
 		return -ENODEV;
@@ -1896,11 +1939,10 @@ static int __devinit smsc911x_drv_probe(
 	struct net_device *dev;
 	struct smsc911x_data *pdata;
 	struct smsc911x_platform_config *config = pdev->dev.platform_data;
-	struct resource *res;
+	struct resource *res, *irq_res;
 	unsigned int intcfg = 0;
-	int res_size;
+	int res_size, irq_flags;
 	int retval;
-	DECLARE_MAC_BUF(mac);
 
 	pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
 
@@ -1923,6 +1965,14 @@ static int __devinit smsc911x_drv_probe(
 	}
 	res_size = res->end - res->start;
 
+	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!irq_res) {
+		pr_warning("%s: Could not allocate irq resource.\n",
+			SMSC_CHIPNAME);
+		retval = -ENODEV;
+		goto out_0;
+	}
+
 	if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) {
 		retval = -EBUSY;
 		goto out_0;
@@ -1939,7 +1989,8 @@ static int __devinit smsc911x_drv_probe(
 
 	pdata = netdev_priv(dev);
 
-	dev->irq = platform_get_irq(pdev, 0);
+	dev->irq = irq_res->start;
+	irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
 	pdata->ioaddr = ioremap_nocache(res->start, res_size);
 
 	/* copy config parameters across to pdata */
@@ -1972,8 +2023,8 @@ static int __devinit smsc911x_drv_probe(
 	smsc911x_reg_write(pdata, INT_EN, 0);
 	smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
 
-	retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED,
-			     dev->name, dev);
+	retval = request_irq(dev->irq, smsc911x_irqhandler,
+			     irq_flags | IRQF_SHARED, dev->name, dev);
 	if (retval) {
 		SMSC_WARNING(PROBE,
 			"Unable to claim requested irq: %d", dev->irq);
@@ -2004,19 +2055,12 @@ static int __devinit smsc911x_drv_probe(
 
 	/* Check if mac address has been specified when bringing interface up */
 	if (is_valid_ether_addr(dev->dev_addr)) {
-		smsc911x_set_mac_address(pdata, dev->dev_addr);
+		smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 		SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
 	} else {
 		/* Try reading mac address from device. if EEPROM is present
 		 * it will already have been set */
-		u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
-		u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
-		dev->dev_addr[0] = (u8)(mac_low32);
-		dev->dev_addr[1] = (u8)(mac_low32 >> 8);
-		dev->dev_addr[2] = (u8)(mac_low32 >> 16);
-		dev->dev_addr[3] = (u8)(mac_low32 >> 24);
-		dev->dev_addr[4] = (u8)(mac_high16);
-		dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+		smsc911x_read_mac_address(dev);
 
 		if (is_valid_ether_addr(dev->dev_addr)) {
 			/* eeprom values are valid  so use them */
@@ -2025,7 +2069,7 @@ static int __devinit smsc911x_drv_probe(
 		} else {
 			/* eeprom values are invalid, generate random MAC */
 			random_ether_addr(dev->dev_addr);
-			smsc911x_set_mac_address(pdata, dev->dev_addr);
+			smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 			SMSC_TRACE(PROBE,
 				"MAC Address is set to random_ether_addr");
 		}
@@ -2033,8 +2077,7 @@ static int __devinit smsc911x_drv_probe(
 
 	spin_unlock_irq(&pdata->mac_lock);
 
-	dev_info(&dev->dev, "MAC Address: %s\n",
-		 print_mac(mac, dev->dev_addr));
+	dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smsc911x.h linux-libre-2.6.30-gnu1/drivers/net/smsc911x.h
--- linux-libre-2.6.29-gnu1/drivers/net/smsc911x.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smsc911x.h	2009-06-09 23:05:27.000000000 -0400
@@ -81,12 +81,19 @@
 
 #define RX_STATUS_FIFO			0x40
 #define RX_STS_ES_			0x00008000
+#define RX_STS_LENGTH_ERR_		0x00001000
 #define RX_STS_MCAST_			0x00000400
+#define RX_STS_FRAME_TYPE_		0x00000020
+#define RX_STS_CRC_ERR_			0x00000002
 
 #define RX_STATUS_FIFO_PEEK		0x44
 
 #define TX_STATUS_FIFO			0x48
 #define TX_STS_ES_			0x00008000
+#define TX_STS_LOST_CARRIER_		0x00000800
+#define TX_STS_NO_CARRIER_		0x00000400
+#define TX_STS_LATE_COL_		0x00000200
+#define TX_STS_EXCESS_COL_		0x00000100
 
 #define TX_STATUS_FIFO_PEEK		0x4C
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/smsc9420.c linux-libre-2.6.30-gnu1/drivers/net/smsc9420.c
--- linux-libre-2.6.29-gnu1/drivers/net/smsc9420.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/smsc9420.c	2009-06-09 23:05:27.000000000 -0400
@@ -670,7 +670,7 @@ static irqreturn_t smsc9420_isr(int irq,
 			smsc9420_pci_flush_write(pd);
 
 			ints_to_clear |= (DMAC_STS_RX_ | DMAC_STS_NIS_);
-			netif_rx_schedule(&pd->napi);
+			napi_schedule(&pd->napi);
 		}
 
 		if (ints_to_clear)
@@ -807,7 +807,7 @@ static void smsc9420_rx_handoff(struct s
 	if (pd->rx_csum) {
 		u16 hw_csum = get_unaligned_le16(skb_tail_pointer(skb) +
 			NET_IP_ALIGN + packet_length + 4);
-		put_unaligned_le16(cpu_to_le16(hw_csum), &skb->csum);
+		put_unaligned_le16(hw_csum, &skb->csum);
 		skb->ip_summed = CHECKSUM_COMPLETE;
 	}
 
@@ -893,7 +893,7 @@ static int smsc9420_rx_poll(struct napi_
 	smsc9420_pci_flush_write(pd);
 
 	if (work_done < budget) {
-		netif_rx_complete(&pd->napi);
+		napi_complete(&pd->napi);
 
 		/* re-enable RX DMA interrupts */
 		dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
@@ -1160,7 +1160,7 @@ static int smsc9420_mii_probe(struct net
 	smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
 		phydev->phy_id);
 
-	phydev = phy_connect(dev, phydev->dev.bus_id,
+	phydev = phy_connect(dev, dev_name(&phydev->dev),
 		&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
 
 	if (IS_ERR(phydev)) {
@@ -1169,7 +1169,7 @@ static int smsc9420_mii_probe(struct net
 	}
 
 	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
-		dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+		dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 
 	/* mask with MAC supported features */
 	phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -1598,7 +1598,7 @@ smsc9420_probe(struct pci_dev *pdev, con
 		goto out_free_netdev_2;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR "No usable DMA configuration, aborting.\n");
 		goto out_free_regions_3;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/spider_net.c linux-libre-2.6.30-gnu1/drivers/net/spider_net.c
--- linux-libre-2.6.29-gnu1/drivers/net/spider_net.c	2013-05-03 18:03:15.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/spider_net.c	2013-05-03 16:47:02.000000000 -0400
@@ -1301,7 +1301,7 @@ static int spider_net_poll(struct napi_s
 	/* if all packets are in the stack, enable interrupts and return 0 */
 	/* if not, return 1 */
 	if (packets_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		spider_net_rx_irq_on(card);
 		card->ignore_rx_ramfull = 0;
 	}
@@ -1528,7 +1528,7 @@ spider_net_handle_error_irq(struct spide
 			spider_net_refill_rx_chain(card);
 			spider_net_enable_rxdmac(card);
 			card->num_rx_ints ++;
-			netif_rx_schedule(&card->napi);
+			napi_schedule(&card->napi);
 		}
 		show_error = 0;
 		break;
@@ -1548,7 +1548,7 @@ spider_net_handle_error_irq(struct spide
 		spider_net_refill_rx_chain(card);
 		spider_net_enable_rxdmac(card);
 		card->num_rx_ints ++;
-		netif_rx_schedule(&card->napi);
+		napi_schedule(&card->napi);
 		show_error = 0;
 		break;
 
@@ -1562,7 +1562,7 @@ spider_net_handle_error_irq(struct spide
 		spider_net_refill_rx_chain(card);
 		spider_net_enable_rxdmac(card);
 		card->num_rx_ints ++;
-		netif_rx_schedule(&card->napi);
+		napi_schedule(&card->napi);
 		show_error = 0;
 		break;
 
@@ -1656,11 +1656,11 @@ spider_net_interrupt(int irq, void *ptr)
 
 	if (status_reg & SPIDER_NET_RXINT ) {
 		spider_net_rx_irq_off(card);
-		netif_rx_schedule(&card->napi);
+		napi_schedule(&card->napi);
 		card->num_rx_ints ++;
 	}
 	if (status_reg & SPIDER_NET_TXINT)
-		netif_rx_schedule(&card->napi);
+		napi_schedule(&card->napi);
 
 	if (status_reg & SPIDER_NET_LINKINT)
 		spider_net_link_reset(netdev);
@@ -2259,6 +2259,23 @@ spider_net_tx_timeout(struct net_device
 	card->spider_stats.tx_timeouts++;
 }
 
+static const struct net_device_ops spider_net_ops = {
+	.ndo_open		= spider_net_open,
+	.ndo_stop		= spider_net_stop,
+	.ndo_start_xmit		= spider_net_xmit,
+	.ndo_set_multicast_list	= spider_net_set_multi,
+	.ndo_set_mac_address	= spider_net_set_mac,
+	.ndo_change_mtu		= spider_net_change_mtu,
+	.ndo_do_ioctl		= spider_net_do_ioctl,
+	.ndo_tx_timeout		= spider_net_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	/* HW VLAN */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	/* poll controller */
+	.ndo_poll_controller	= spider_net_poll_controller,
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+};
+
 /**
  * spider_net_setup_netdev_ops - initialization of net_device operations
  * @netdev: net_device structure
@@ -2268,21 +2285,8 @@ spider_net_tx_timeout(struct net_device
 static void
 spider_net_setup_netdev_ops(struct net_device *netdev)
 {
-	netdev->open = &spider_net_open;
-	netdev->stop = &spider_net_stop;
-	netdev->hard_start_xmit = &spider_net_xmit;
-	netdev->set_multicast_list = &spider_net_set_multi;
-	netdev->set_mac_address = &spider_net_set_mac;
-	netdev->change_mtu = &spider_net_change_mtu;
-	netdev->do_ioctl = &spider_net_do_ioctl;
-	/* tx watchdog */
-	netdev->tx_timeout = &spider_net_tx_timeout;
+	netdev->netdev_ops = &spider_net_ops;
 	netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT;
-	/* HW VLAN */
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	/* poll controller */
-	netdev->poll_controller = &spider_net_poll_controller;
-#endif /* CONFIG_NET_POLL_CONTROLLER */
 	/* ethtool ops */
 	netdev->ethtool_ops = &spider_net_ethtool_ops;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/starfire.c linux-libre-2.6.30-gnu1/drivers/net/starfire.c
--- linux-libre-2.6.29-gnu1/drivers/net/starfire.c	2013-05-03 18:02:32.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/starfire.c	2013-05-03 16:46:23.000000000 -0400
@@ -178,7 +178,7 @@ static int full_duplex[MAX_UNITS] = {0,
 #define FIRMWARE_TX	"/*(DEBLOBBED)*/"
 
 /* These identify the driver base version and may not be removed. */
-static char version[] =
+static const char version[] __devinitconst =
 KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"
 KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
@@ -1341,8 +1341,8 @@ static irqreturn_t intr_handler(int irq,
 		if (intr_status & (IntrRxDone | IntrRxEmpty)) {
 			u32 enable;
 
-			if (likely(netif_rx_schedule_prep(&np->napi))) {
-				__netif_rx_schedule(&np->napi);
+			if (likely(napi_schedule_prep(&np->napi))) {
+				__napi_schedule(&np->napi);
 				enable = readl(ioaddr + IntrEnable);
 				enable &= ~(IntrRxDone | IntrRxEmpty);
 				writel(enable, ioaddr + IntrEnable);
@@ -1586,7 +1586,7 @@ static int netdev_poll(struct napi_struc
 		intr_status = readl(ioaddr + IntrStatus);
 	} while (intr_status & (IntrRxDone | IntrRxEmpty));
 
-	netif_rx_complete(napi);
+	napi_complete(napi);
 	intr_status = readl(ioaddr + IntrEnable);
 	intr_status |= IntrRxDone | IntrRxEmpty;
 	writel(intr_status, ioaddr + IntrEnable);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sun3_82586.c linux-libre-2.6.30-gnu1/drivers/net/sun3_82586.c
--- linux-libre-2.6.29-gnu1/drivers/net/sun3_82586.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sun3_82586.c	2009-06-09 23:05:27.000000000 -0400
@@ -331,6 +331,18 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops sun3_82586_netdev_ops = {
+	.ndo_open		= sun3_82586_open,
+	.ndo_stop		= sun3_82586_close,
+	.ndo_start_xmit		= sun3_82586_send_packet,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_tx_timeout		= sun3_82586_timeout,
+	.ndo_get_stats		= sun3_82586_get_stats,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
 {
 	int i, size, retval;
@@ -381,13 +393,8 @@ static int __init sun3_82586_probe1(stru
 
 	printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
 
-	dev->open		= sun3_82586_open;
-	dev->stop		= sun3_82586_close;
-	dev->get_stats		= sun3_82586_get_stats;
-	dev->tx_timeout 	= sun3_82586_timeout;
+	dev->netdev_ops		= &sun3_82586_netdev_ops;
 	dev->watchdog_timeo	= HZ/20;
-	dev->hard_start_xmit 	= sun3_82586_send_packet;
-	dev->set_multicast_list = set_multicast_list;
 
 	dev->if_port 		= 0;
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sunbmac.c linux-libre-2.6.30-gnu1/drivers/net/sunbmac.c
--- linux-libre-2.6.29-gnu1/drivers/net/sunbmac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sunbmac.c	2009-06-09 23:05:27.000000000 -0400
@@ -1074,6 +1074,18 @@ static const struct ethtool_ops bigmac_e
 	.get_link		= bigmac_get_link,
 };
 
+static const struct net_device_ops bigmac_ops = {
+	.ndo_open		= bigmac_open,
+	.ndo_stop		= bigmac_close,
+	.ndo_start_xmit		= bigmac_start_xmit,
+	.ndo_get_stats		= bigmac_get_stats,
+	.ndo_set_multicast_list	= bigmac_set_multicast,
+	.ndo_tx_timeout		= bigmac_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __devinit bigmac_ether_init(struct of_device *op,
 				       struct of_device *qec_op)
 {
@@ -1187,16 +1199,8 @@ static int __devinit bigmac_ether_init(s
 	bp->dev = dev;
 
 	/* Set links to our BigMAC open and close routines. */
-	dev->open = &bigmac_open;
-	dev->stop = &bigmac_close;
-	dev->hard_start_xmit = &bigmac_start_xmit;
 	dev->ethtool_ops = &bigmac_ethtool_ops;
-
-	/* Set links to BigMAC statistic and multi-cast loading code. */
-	dev->get_stats = &bigmac_get_stats;
-	dev->set_multicast_list = &bigmac_set_multicast;
-
-	dev->tx_timeout = &bigmac_tx_timeout;
+	dev->netdev_ops = &bigmac_ops;
 	dev->watchdog_timeo = 5*HZ;
 
 	/* Finish net device registration. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sundance.c linux-libre-2.6.30-gnu1/drivers/net/sundance.c
--- linux-libre-2.6.29-gnu1/drivers/net/sundance.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sundance.c	2009-06-09 23:05:27.000000000 -0400
@@ -109,8 +109,9 @@ static char *media[MAX_UNITS];
 #endif
 
 /* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Written by Donald Becker\n";
+static const char version[] __devinitconst =
+	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+	" Written by Donald Becker\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sungem.c linux-libre-2.6.30-gnu1/drivers/net/sungem.c
--- linux-libre-2.6.29-gnu1/drivers/net/sungem.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sungem.c	2009-06-09 23:05:27.000000000 -0400
@@ -921,7 +921,7 @@ static int gem_poll(struct napi_struct *
 		gp->status = readl(gp->regs + GREG_STAT);
 	} while (gp->status & GREG_STAT_NAPI);
 
-	__netif_rx_complete(napi);
+	__napi_complete(napi);
 	gem_enable_ints(gp);
 
 	spin_unlock_irqrestore(&gp->lock, flags);
@@ -944,7 +944,7 @@ static irqreturn_t gem_interrupt(int irq
 
 	spin_lock_irqsave(&gp->lock, flags);
 
-	if (netif_rx_schedule_prep(&gp->napi)) {
+	if (napi_schedule_prep(&gp->napi)) {
 		u32 gem_status = readl(gp->regs + GREG_STAT);
 
 		if (gem_status == 0) {
@@ -954,7 +954,7 @@ static irqreturn_t gem_interrupt(int irq
 		}
 		gp->status = gem_status;
 		gem_disable_ints(gp);
-		__netif_rx_schedule(&gp->napi);
+		__napi_schedule(&gp->napi);
 	}
 
 	spin_unlock_irqrestore(&gp->lock, flags);
@@ -3042,10 +3042,10 @@ static int __devinit gem_init_one(struct
 	 */
 	if (pdev->vendor == PCI_VENDOR_ID_SUN &&
 	    pdev->device == PCI_DEVICE_ID_SUN_GEM &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
 		pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sunlance.c linux-libre-2.6.30-gnu1/drivers/net/sunlance.c
--- linux-libre-2.6.29-gnu1/drivers/net/sunlance.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sunlance.c	2009-06-09 23:05:27.000000000 -0400
@@ -1311,6 +1311,17 @@ static const struct ethtool_ops sparc_la
 	.get_link		= sparc_lance_get_link,
 };
 
+static const struct net_device_ops sparc_lance_ops = {
+	.ndo_open		= lance_open,
+	.ndo_stop		= lance_close,
+	.ndo_start_xmit		= lance_start_xmit,
+	.ndo_set_multicast_list	= lance_set_multicast,
+	.ndo_tx_timeout		= lance_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __devinit sparc_lance_probe_one(struct of_device *op,
 					   struct of_device *ledma,
 					   struct of_device *lebuffer)
@@ -1462,13 +1473,9 @@ no_link_test:
 
 	lp->dev = dev;
 	SET_NETDEV_DEV(dev, &op->dev);
-	dev->open = &lance_open;
-	dev->stop = &lance_close;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->tx_timeout = &lance_tx_timeout;
 	dev->watchdog_timeo = 5*HZ;
-	dev->set_multicast_list = &lance_set_multicast;
 	dev->ethtool_ops = &sparc_lance_ethtool_ops;
+	dev->netdev_ops = &sparc_lance_ops;
 
 	dev->irq = op->irqs[0];
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sunqe.c linux-libre-2.6.30-gnu1/drivers/net/sunqe.c
--- linux-libre-2.6.29-gnu1/drivers/net/sunqe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sunqe.c	2009-06-09 23:05:27.000000000 -0400
@@ -829,6 +829,17 @@ fail:
 	return NULL;
 }
 
+static const struct net_device_ops qec_ops = {
+	.ndo_open		= qe_open,
+	.ndo_stop		= qe_close,
+	.ndo_start_xmit		= qe_start_xmit,
+	.ndo_set_multicast_list	= qe_set_multicast,
+	.ndo_tx_timeout		= qe_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int __devinit qec_ether_init(struct of_device *op)
 {
 	static unsigned version_printed;
@@ -893,15 +904,11 @@ static int __devinit qec_ether_init(stru
 
 	SET_NETDEV_DEV(dev, &op->dev);
 
-	dev->open = qe_open;
-	dev->stop = qe_close;
-	dev->hard_start_xmit = qe_start_xmit;
-	dev->set_multicast_list = qe_set_multicast;
-	dev->tx_timeout = qe_tx_timeout;
 	dev->watchdog_timeo = 5*HZ;
 	dev->irq = op->irqs[0];
 	dev->dma = 0;
 	dev->ethtool_ops = &qe_ethtool_ops;
+	dev->netdev_ops = &qec_ops;
 
 	res = register_netdev(dev);
 	if (res)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/sunvnet.c linux-libre-2.6.30-gnu1/drivers/net/sunvnet.c
--- linux-libre-2.6.29-gnu1/drivers/net/sunvnet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/sunvnet.c	2009-06-09 23:05:27.000000000 -0400
@@ -1012,6 +1012,16 @@ err_out:
 static LIST_HEAD(vnet_list);
 static DEFINE_MUTEX(vnet_list_mutex);
 
+static const struct net_device_ops vnet_ops = {
+	.ndo_open		= vnet_open,
+	.ndo_stop		= vnet_close,
+	.ndo_set_multicast_list	= vnet_set_rx_mode,
+	.ndo_set_mac_address	= vnet_set_mac_addr,
+	.ndo_tx_timeout		= vnet_tx_timeout,
+	.ndo_change_mtu		= vnet_change_mtu,
+	.ndo_start_xmit		= vnet_start_xmit,
+};
+
 static struct vnet * __devinit vnet_new(const u64 *local_mac)
 {
 	struct net_device *dev;
@@ -1040,15 +1050,9 @@ static struct vnet * __devinit vnet_new(
 	INIT_LIST_HEAD(&vp->list);
 	vp->local_mac = *local_mac;
 
-	dev->open = vnet_open;
-	dev->stop = vnet_close;
-	dev->set_multicast_list = vnet_set_rx_mode;
-	dev->set_mac_address = vnet_set_mac_addr;
-	dev->tx_timeout = vnet_tx_timeout;
+	dev->netdev_ops = &vnet_ops;
 	dev->ethtool_ops = &vnet_ethtool_ops;
 	dev->watchdog_timeo = VNET_TX_TIMEOUT;
-	dev->change_mtu = vnet_change_mtu;
-	dev->hard_start_xmit = vnet_start_xmit;
 
 	err = register_netdev(dev);
 	if (err) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tc35815.c linux-libre-2.6.30-gnu1/drivers/net/tc35815.c
--- linux-libre-2.6.29-gnu1/drivers/net/tc35815.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tc35815.c	2009-06-09 23:05:27.000000000 -0400
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_devic
 	}
 
 	/* attach the mac to the phy */
-	phydev = phy_connect(dev, phydev->dev.bus_id,
+	phydev = phy_connect(dev, dev_name(&phydev->dev),
 			     &tc_handle_link_change, 0,
 			     lp->chiptype == TC35815_TX4939 ?
 			     PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_devic
 	}
 	printk(KERN_INFO "%s: attached PHY driver [%s] "
 		"(mii_bus:phy_addr=%s, id=%x)\n",
-		dev->name, phydev->drv->name, phydev->dev.bus_id,
+		dev->name, phydev->drv->name, dev_name(&phydev->dev),
 		phydev->phy_id);
 
 	/* mask with MAC supported features */
@@ -862,6 +862,22 @@ static int __devinit tc35815_init_dev_ad
 	return 0;
 }
 
+static const struct net_device_ops tc35815_netdev_ops = {
+	.ndo_open		= tc35815_open,
+	.ndo_stop		= tc35815_close,
+	.ndo_start_xmit		= tc35815_send_packet,
+	.ndo_get_stats		= tc35815_get_stats,
+	.ndo_set_multicast_list	= tc35815_set_multicast_list,
+	.ndo_tx_timeout		= tc35815_tx_timeout,
+	.ndo_do_ioctl		= tc35815_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= tc35815_poll_controller,
+#endif
+};
+
 static int __devinit tc35815_init_one(struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
@@ -904,21 +920,12 @@ static int __devinit tc35815_init_one(st
 	ioaddr = pcim_iomap_table(pdev)[1];
 
 	/* Initialize the device structure. */
-	dev->open = tc35815_open;
-	dev->hard_start_xmit = tc35815_send_packet;
-	dev->stop = tc35815_close;
-	dev->get_stats = tc35815_get_stats;
-	dev->set_multicast_list = tc35815_set_multicast_list;
-	dev->do_ioctl = tc35815_ioctl;
+	dev->netdev_ops = &tc35815_netdev_ops;
 	dev->ethtool_ops = &tc35815_ethtool_ops;
-	dev->tx_timeout = tc35815_tx_timeout;
 	dev->watchdog_timeo = TC35815_TX_TIMEOUT;
 #ifdef TC35815_NAPI
 	netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT);
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = tc35815_poll_controller;
-#endif
 
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long)ioaddr;
@@ -1609,8 +1616,8 @@ static irqreturn_t tc35815_interrupt(int
 	if (!(dmactl & DMA_IntMask)) {
 		/* disable interrupts */
 		tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
-		if (netif_rx_schedule_prep(&lp->napi))
-			__netif_rx_schedule(&lp->napi);
+		if (napi_schedule_prep(&lp->napi))
+			__napi_schedule(&lp->napi);
 		else {
 			printk(KERN_ERR "%s: interrupt taken in poll\n",
 			       dev->name);
@@ -1908,7 +1915,7 @@ static int tc35815_poll(struct napi_stru
 	do {
 		tc_writel(status, &tr->Int_Src);	/* write to clear */
 
-		handled = tc35815_do_interrupt(dev, status, limit);
+		handled = tc35815_do_interrupt(dev, status, budget - received);
 		if (handled >= 0) {
 			received += handled;
 			if (received >= budget)
@@ -1919,7 +1926,7 @@ static int tc35815_poll(struct napi_stru
 	spin_unlock(&lp->lock);
 
 	if (received < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		/* enable interrupts */
 		tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tehuti.c linux-libre-2.6.30-gnu1/drivers/net/tehuti.c
--- linux-libre-2.6.29-gnu1/drivers/net/tehuti.c	2013-05-03 18:03:25.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tehuti.c	2013-05-03 16:47:12.000000000 -0400
@@ -63,7 +63,6 @@
  */
 
 #include "tehuti.h"
-#include "tehuti_fw.h"
 
 static struct pci_device_id __devinitdata bdx_pci_tbl[] = {
 	{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -265,8 +264,8 @@ static irqreturn_t bdx_isr_napi(int irq,
 		bdx_isr_extra(priv, isr);
 
 	if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) {
-		if (likely(netif_rx_schedule_prep(&priv->napi))) {
-			__netif_rx_schedule(&priv->napi);
+		if (likely(napi_schedule_prep(&priv->napi))) {
+			__napi_schedule(&priv->napi);
 			RET(IRQ_HANDLED);
 		} else {
 			/* NOTE: we get here if intr has slipped into window
@@ -302,7 +301,7 @@ static int bdx_poll(struct napi_struct *
 		 * device lock and allow waiting tasks (eg rmmod) to advance) */
 		priv->napi_stop = 0;
 
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		bdx_enable_interrupts(priv);
 	}
 	return work_done;
@@ -318,30 +317,41 @@ static int bdx_poll(struct napi_struct *
 
 static int bdx_fw_load(struct bdx_priv *priv)
 {
+	const struct firmware *fw = NULL;
 	int master, i;
+	int rc;
 
 	ENTER;
 	master = READ_REG(priv, regINIT_SEMAPHORE);
 	if (!READ_REG(priv, regINIT_STATUS) && master) {
-		ERR("%s: Missing Free firmware\n", priv->ndev->name);
-		RET(-EINVAL);
-		/*(DEBLOBBED)*/
+		rc = reject_firmware(&fw, "/*(DEBLOBBED)*/", &priv->pdev->dev);
+		if (rc)
+			goto out;
+		bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
 		mdelay(100);
 	}
 	for (i = 0; i < 200; i++) {
-		if (READ_REG(priv, regINIT_STATUS))
-			break;
+		if (READ_REG(priv, regINIT_STATUS)) {
+			rc = 0;
+			goto out;
+		}
 		mdelay(2);
 	}
+	rc = -EIO;
+out:
 	if (master)
 		WRITE_REG(priv, regINIT_SEMAPHORE, 1);
+	if (fw)
+		release_firmware(fw);
 
-	if (i == 200) {
+	if (rc) {
 		ERR("%s: firmware loading failed\n", priv->ndev->name);
-		DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
-		    READ_REG(priv, regVPC),
-		    READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i);
-		RET(-EIO);
+		if (rc == -EIO)
+			DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
+			    READ_REG(priv, regVPC),
+			    READ_REG(priv, regVIC),
+			    READ_REG(priv, regINIT_STATUS), i);
+		RET(rc);
 	} else {
 		DBG("%s: firmware loading success\n", priv->ndev->name);
 		RET(0);
@@ -619,12 +629,6 @@ err:
 	RET(rc);
 }
 
-static void __init bdx_firmware_endianess(void)
-{
-	int i;
-	/*(DEBLOBBED)*/
-}
-
 static int bdx_range_check(struct bdx_priv *priv, u32 offset)
 {
 	return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
@@ -1937,12 +1941,12 @@ bdx_probe(struct pci_dev *pdev, const st
 	if ((err = pci_enable_device(pdev)))	/* it trigers interrupt, dunno why. */
 		goto err_pci;			/* it's not a problem though */
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
-	    !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
+	    !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
 		pci_using_dac = 1;
 	} else {
-		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
-		    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+		    (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 			printk(KERN_ERR "tehuti: No usable DMA configuration"
 					", aborting\n");
 			goto err_dma;
@@ -2502,7 +2506,6 @@ static void __init print_driver_id(void)
 static int __init bdx_module_init(void)
 {
 	ENTER;
-	bdx_firmware_endianess();
 	init_txd_sizes();
 	print_driver_id();
 	RET(pci_register_driver(&bdx_pci_driver));
@@ -2522,3 +2525,4 @@ module_exit(bdx_module_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(BDX_DRV_DESC);
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tehuti_fw.h linux-libre-2.6.30-gnu1/drivers/net/tehuti_fw.h
--- linux-libre-2.6.29-gnu1/drivers/net/tehuti_fw.h	2013-05-03 18:03:22.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tehuti_fw.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-/*
- * Tehuti Networks(R) Network Driver
- * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/* Loading Firmware */
-/* INT_MEM Ver */
-/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tehuti.h linux-libre-2.6.30-gnu1/drivers/net/tehuti.h
--- linux-libre-2.6.29-gnu1/drivers/net/tehuti.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tehuti.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,9 @@
 #include <linux/if_vlan.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
+#include <linux/firmware.h>
 #include <asm/byteorder.h>
+#include <linux/dma-mapping.h>
 
 /* Compile Time Switches */
 /* start */
@@ -97,14 +99,6 @@
 #define READ_REG(pp, reg)         readl(pp->pBdxRegs + reg)
 #define WRITE_REG(pp, reg, val)   writel(val, pp->pBdxRegs + reg)
 
-#ifndef DMA_64BIT_MASK
-#   define DMA_64BIT_MASK  0xffffffffffffffffULL
-#endif
-
-#ifndef DMA_32BIT_MASK
-#   define DMA_32BIT_MASK  0x00000000ffffffffULL
-#endif
-
 #ifndef NET_IP_ALIGN
 #   define NET_IP_ALIGN 2
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tg3.c linux-libre-2.6.30-gnu1/drivers/net/tg3.c
--- linux-libre-2.6.29-gnu1/drivers/net/tg3.c	2013-05-03 18:03:31.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tg3.c	2013-05-03 16:47:21.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-2007 Broadcom Corporation.
+ * Copyright (C) 2005-2009 Broadcom Corporation.
  *
 /*(DEBLOBBED)*/
 
@@ -61,8 +61,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.97"
-#define DRV_MODULE_RELDATE	"December 10, 2008"
+#define DRV_MODULE_VERSION	"3.98"
+#define DRV_MODULE_RELDATE	"February 25, 2009"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -851,7 +851,7 @@ static int tg3_bmcr_reset(struct tg3 *tp
 
 static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 {
-	struct tg3 *tp = (struct tg3 *)bp->priv;
+	struct tg3 *tp = bp->priv;
 	u32 val;
 
 	if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
@@ -865,7 +865,7 @@ static int tg3_mdio_read(struct mii_bus
 
 static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
 {
-	struct tg3 *tp = (struct tg3 *)bp->priv;
+	struct tg3 *tp = bp->priv;
 
 	if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
 		return -EAGAIN;
@@ -2041,8 +2041,6 @@ static int tg3_setup_phy(struct tg3 *, i
 
 static void tg3_write_sig_post_reset(struct tg3 *, int);
 static int tg3_halt_cpu(struct tg3 *, u32);
-static int tg3_nvram_lock(struct tg3 *);
-static void tg3_nvram_unlock(struct tg3 *);
 
 static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
@@ -2099,6 +2097,201 @@ static void tg3_power_down_phy(struct tg
 }
 
 /* tp->lock is held. */
+static int tg3_nvram_lock(struct tg3 *tp)
+{
+	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+		int i;
+
+		if (tp->nvram_lock_cnt == 0) {
+			tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+			for (i = 0; i < 8000; i++) {
+				if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+					break;
+				udelay(20);
+			}
+			if (i == 8000) {
+				tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+				return -ENODEV;
+			}
+		}
+		tp->nvram_lock_cnt++;
+	}
+	return 0;
+}
+
+/* tp->lock is held. */
+static void tg3_nvram_unlock(struct tg3 *tp)
+{
+	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+		if (tp->nvram_lock_cnt > 0)
+			tp->nvram_lock_cnt--;
+		if (tp->nvram_lock_cnt == 0)
+			tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+	}
+}
+
+/* tp->lock is held. */
+static void tg3_enable_nvram_access(struct tg3 *tp)
+{
+	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+		u32 nvaccess = tr32(NVRAM_ACCESS);
+
+		tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+	}
+}
+
+/* tp->lock is held. */
+static void tg3_disable_nvram_access(struct tg3 *tp)
+{
+	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+		u32 nvaccess = tr32(NVRAM_ACCESS);
+
+		tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+	}
+}
+
+static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
+					u32 offset, u32 *val)
+{
+	u32 tmp;
+	int i;
+
+	if (offset > EEPROM_ADDR_ADDR_MASK || (offset % 4) != 0)
+		return -EINVAL;
+
+	tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+					EEPROM_ADDR_DEVID_MASK |
+					EEPROM_ADDR_READ);
+	tw32(GRC_EEPROM_ADDR,
+	     tmp |
+	     (0 << EEPROM_ADDR_DEVID_SHIFT) |
+	     ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+	      EEPROM_ADDR_ADDR_MASK) |
+	     EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+	for (i = 0; i < 1000; i++) {
+		tmp = tr32(GRC_EEPROM_ADDR);
+
+		if (tmp & EEPROM_ADDR_COMPLETE)
+			break;
+		msleep(1);
+	}
+	if (!(tmp & EEPROM_ADDR_COMPLETE))
+		return -EBUSY;
+
+	tmp = tr32(GRC_EEPROM_DATA);
+
+	/*
+	 * The data will always be opposite the native endian
+	 * format.  Perform a blind byteswap to compensate.
+	 */
+	*val = swab32(tmp);
+
+	return 0;
+}
+
+#define NVRAM_CMD_TIMEOUT 10000
+
+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
+{
+	int i;
+
+	tw32(NVRAM_CMD, nvram_cmd);
+	for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
+		udelay(10);
+		if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
+			udelay(10);
+			break;
+		}
+	}
+
+	if (i == NVRAM_CMD_TIMEOUT)
+		return -EBUSY;
+
+	return 0;
+}
+
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+	    (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+		addr = ((addr / tp->nvram_pagesize) <<
+			ATMEL_AT45DB0X1B_PAGE_POS) +
+		       (addr % tp->nvram_pagesize);
+
+	return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+	    (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+		addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+			tp->nvram_pagesize) +
+		       (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+	return addr;
+}
+
+/* NOTE: Data read in from NVRAM is byteswapped according to
+ * the byteswapping settings for all other register accesses.
+ * tg3 devices are BE devices, so on a BE machine, the data
+ * returned will be exactly as it is seen in NVRAM.  On a LE
+ * machine, the 32-bit value will be byteswapped.
+ */
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+	int ret;
+
+	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+		return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+	offset = tg3_nvram_phys_addr(tp, offset);
+
+	if (offset > NVRAM_ADDR_MSK)
+		return -EINVAL;
+
+	ret = tg3_nvram_lock(tp);
+	if (ret)
+		return ret;
+
+	tg3_enable_nvram_access(tp);
+
+	tw32(NVRAM_ADDR, offset);
+	ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
+		NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+	if (ret == 0)
+		*val = tr32(NVRAM_RDDATA);
+
+	tg3_disable_nvram_access(tp);
+
+	tg3_nvram_unlock(tp);
+
+	return ret;
+}
+
+/* Ensures NVRAM data is in bytestream format. */
+static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
+{
+	u32 v;
+	int res = tg3_nvram_read(tp, offset, &v);
+	if (!res)
+		*val = cpu_to_be32(v);
+	return res;
+}
+
+/* tp->lock is held. */
 static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
 {
 	u32 addr_high, addr_low;
@@ -4197,7 +4390,7 @@ static void tg3_recycle_rx(struct tg3 *t
 #if TG3_VLAN_TAG_USED
 static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
 {
-	return vlan_hwaccel_receive_skb(skb, tp->vlgrp, vlan_tag);
+	return vlan_gro_receive(&tp->napi, tp->vlgrp, vlan_tag, skb);
 }
 #endif
 
@@ -4330,6 +4523,13 @@ static int tg3_rx(struct tg3 *tp, int bu
 			skb->ip_summed = CHECKSUM_NONE;
 
 		skb->protocol = eth_type_trans(skb, tp->dev);
+
+		if (len > (tp->dev->mtu + ETH_HLEN) &&
+		    skb->protocol != htons(ETH_P_8021Q)) {
+			dev_kfree_skb(skb);
+			goto next_pkt;
+		}
+
 #if TG3_VLAN_TAG_USED
 		if (tp->vlgrp != NULL &&
 		    desc->type_flags & RXD_FLAG_VLAN) {
@@ -4337,7 +4537,7 @@ static int tg3_rx(struct tg3 *tp, int bu
 				    desc->err_vlan & RXD_VLAN_MASK);
 		} else
 #endif
-			netif_receive_skb(skb);
+			napi_gro_receive(&tp->napi, skb);
 
 		received++;
 		budget--;
@@ -4452,7 +4652,7 @@ static int tg3_poll(struct napi_struct *
 			sblk->status &= ~SD_STATUS_UPDATED;
 
 		if (likely(!tg3_has_work(tp))) {
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			tg3_restart_ints(tp);
 			break;
 		}
@@ -4462,7 +4662,7 @@ static int tg3_poll(struct napi_struct *
 
 tx_recovery:
 	/* work_done is guaranteed to be less than budget. */
-	netif_rx_complete(napi);
+	napi_complete(napi);
 	schedule_work(&tp->reset_task);
 	return work_done;
 }
@@ -4511,7 +4711,7 @@ static irqreturn_t tg3_msi_1shot(int irq
 	prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
 
 	if (likely(!tg3_irq_sync(tp)))
-		netif_rx_schedule(&tp->napi);
+		napi_schedule(&tp->napi);
 
 	return IRQ_HANDLED;
 }
@@ -4536,7 +4736,7 @@ static irqreturn_t tg3_msi(int irq, void
 	 */
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
 	if (likely(!tg3_irq_sync(tp)))
-		netif_rx_schedule(&tp->napi);
+		napi_schedule(&tp->napi);
 
 	return IRQ_RETVAL(1);
 }
@@ -4578,7 +4778,7 @@ static irqreturn_t tg3_interrupt(int irq
 	sblk->status &= ~SD_STATUS_UPDATED;
 	if (likely(tg3_has_work(tp))) {
 		prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-		netif_rx_schedule(&tp->napi);
+		napi_schedule(&tp->napi);
 	} else {
 		/* No work, shared interrupt perhaps?  re-enable
 		 * interrupts, and flush that PCI write
@@ -4624,7 +4824,7 @@ static irqreturn_t tg3_interrupt_tagged(
 	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
 	if (tg3_irq_sync(tp))
 		goto out;
-	if (netif_rx_schedule_prep(&tp->napi)) {
+	if (napi_schedule_prep(&tp->napi)) {
 		prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
 		/* Update last_tag to mark that this status has been
 		 * seen. Because interrupt may be shared, we may be
@@ -4632,7 +4832,7 @@ static irqreturn_t tg3_interrupt_tagged(
 		 * if tg3_poll() is not scheduled.
 		 */
 		tp->last_tag = sblk->status_tag;
-		__netif_rx_schedule(&tp->napi);
+		__napi_schedule(&tp->napi);
 	}
 out:
 	return IRQ_RETVAL(handled);
@@ -4773,7 +4973,7 @@ static inline int tg3_40bit_overflow_tes
 {
 #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
 	if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
-		return (((u64) mapping + len) > DMA_40BIT_MASK);
+		return (((u64) mapping + len) > DMA_BIT_MASK(40));
 	return 0;
 #else
 	return 0;
@@ -5622,62 +5822,6 @@ static int tg3_abort_hw(struct tg3 *tp,
 	return err;
 }
 
-/* tp->lock is held. */
-static int tg3_nvram_lock(struct tg3 *tp)
-{
-	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
-		int i;
-
-		if (tp->nvram_lock_cnt == 0) {
-			tw32(NVRAM_SWARB, SWARB_REQ_SET1);
-			for (i = 0; i < 8000; i++) {
-				if (tr32(NVRAM_SWARB) & SWARB_GNT1)
-					break;
-				udelay(20);
-			}
-			if (i == 8000) {
-				tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
-				return -ENODEV;
-			}
-		}
-		tp->nvram_lock_cnt++;
-	}
-	return 0;
-}
-
-/* tp->lock is held. */
-static void tg3_nvram_unlock(struct tg3 *tp)
-{
-	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
-		if (tp->nvram_lock_cnt > 0)
-			tp->nvram_lock_cnt--;
-		if (tp->nvram_lock_cnt == 0)
-			tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
-	}
-}
-
-/* tp->lock is held. */
-static void tg3_enable_nvram_access(struct tg3 *tp)
-{
-	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
-		u32 nvaccess = tr32(NVRAM_ACCESS);
-
-		tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
-	}
-}
-
-/* tp->lock is held. */
-static void tg3_disable_nvram_access(struct tg3 *tp)
-{
-	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
-		u32 nvaccess = tr32(NVRAM_ACCESS);
-
-		tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
-	}
-}
-
 static void tg3_ape_send_event(struct tg3 *tp, u32 event)
 {
 	int i;
@@ -6815,7 +6959,8 @@ static int tg3_reset_hw(struct tg3 *tp,
 	__tg3_set_mac_addr(tp, 0);
 
 	/* MTU + ethernet header + FCS + optional VLAN tag */
-	tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+	tw32(MAC_RX_MTU_SIZE,
+	     tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
 
 	/* The slot time is changed by tg3_setup_phy if we
 	 * run at gigabit with half duplex.
@@ -8377,17 +8522,13 @@ static int tg3_get_eeprom_len(struct net
 	return tp->nvram_size;
 }
 
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val);
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
-
 static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct tg3 *tp = netdev_priv(dev);
 	int ret;
 	u8  *pd;
 	u32 i, offset, len, b_offset, b_count;
-	__le32 val;
+	__be32 val;
 
 	if (tp->link_config.phy_is_low_power)
 		return -EAGAIN;
@@ -8406,7 +8547,7 @@ static int tg3_get_eeprom(struct net_dev
 			/* i.e. offset=1 len=2 */
 			b_count = len;
 		}
-		ret = tg3_nvram_read_le(tp, offset-b_offset, &val);
+		ret = tg3_nvram_read_be32(tp, offset-b_offset, &val);
 		if (ret)
 			return ret;
 		memcpy(data, ((char*)&val) + b_offset, b_count);
@@ -8418,7 +8559,7 @@ static int tg3_get_eeprom(struct net_dev
 	/* read bytes upto the last 4 byte boundary */
 	pd = &data[eeprom->len];
 	for (i = 0; i < (len - (len & 3)); i += 4) {
-		ret = tg3_nvram_read_le(tp, offset + i, &val);
+		ret = tg3_nvram_read_be32(tp, offset + i, &val);
 		if (ret) {
 			eeprom->len += i;
 			return ret;
@@ -8432,7 +8573,7 @@ static int tg3_get_eeprom(struct net_dev
 		pd = &data[eeprom->len];
 		b_count = len & 3;
 		b_offset = offset + len - b_count;
-		ret = tg3_nvram_read_le(tp, b_offset, &val);
+		ret = tg3_nvram_read_be32(tp, b_offset, &val);
 		if (ret)
 			return ret;
 		memcpy(pd, &val, b_count);
@@ -8449,7 +8590,7 @@ static int tg3_set_eeprom(struct net_dev
 	int ret;
 	u32 offset, len, b_offset, odd_len;
 	u8 *buf;
-	__le32 start, end;
+	__be32 start, end;
 
 	if (tp->link_config.phy_is_low_power)
 		return -EAGAIN;
@@ -8462,7 +8603,7 @@ static int tg3_set_eeprom(struct net_dev
 
 	if ((b_offset = (offset & 3))) {
 		/* adjustments to start on required 4 byte boundary */
-		ret = tg3_nvram_read_le(tp, offset-b_offset, &start);
+		ret = tg3_nvram_read_be32(tp, offset-b_offset, &start);
 		if (ret)
 			return ret;
 		len += b_offset;
@@ -8476,7 +8617,7 @@ static int tg3_set_eeprom(struct net_dev
 		/* adjustments to end on required 4 byte boundary */
 		odd_len = 1;
 		len = (len + 3) & ~3;
-		ret = tg3_nvram_read_le(tp, offset+len-4, &end);
+		ret = tg3_nvram_read_be32(tp, offset+len-4, &end);
 		if (ret)
 			return ret;
 	}
@@ -8535,7 +8676,7 @@ static int tg3_get_settings(struct net_d
 		cmd->duplex = tp->link_config.active_duplex;
 	}
 	cmd->phy_address = PHY_ADDR;
-	cmd->transceiver = 0;
+	cmd->transceiver = XCVR_INTERNAL;
 	cmd->autoneg = tp->link_config.autoneg;
 	cmd->maxtxpkt = 0;
 	cmd->maxrxpkt = 0;
@@ -8552,26 +8693,58 @@ static int tg3_set_settings(struct net_d
 		return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
-		/* These are the only valid advertisement bits allowed.  */
-		if (cmd->autoneg == AUTONEG_ENABLE &&
-		    (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
-					  ADVERTISED_1000baseT_Full |
-					  ADVERTISED_Autoneg |
-					  ADVERTISED_FIBRE)))
-			return -EINVAL;
-		/* Fiber can only do SPEED_1000.  */
-		else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-			 (cmd->speed != SPEED_1000))
-			return -EINVAL;
-	/* Copper cannot force SPEED_1000.  */
-	} else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-		   (cmd->speed == SPEED_1000))
+	if (cmd->autoneg != AUTONEG_ENABLE &&
+	    cmd->autoneg != AUTONEG_DISABLE)
 		return -EINVAL;
-	else if ((cmd->speed == SPEED_1000) &&
-		 (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+
+	if (cmd->autoneg == AUTONEG_DISABLE &&
+	    cmd->duplex != DUPLEX_FULL &&
+	    cmd->duplex != DUPLEX_HALF)
 		return -EINVAL;
 
+	if (cmd->autoneg == AUTONEG_ENABLE) {
+		u32 mask = ADVERTISED_Autoneg |
+			   ADVERTISED_Pause |
+			   ADVERTISED_Asym_Pause;
+
+		if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+			mask |= ADVERTISED_1000baseT_Half |
+				ADVERTISED_1000baseT_Full;
+
+		if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+			mask |= ADVERTISED_100baseT_Half |
+				ADVERTISED_100baseT_Full |
+				ADVERTISED_10baseT_Half |
+				ADVERTISED_10baseT_Full |
+				ADVERTISED_TP;
+		else
+			mask |= ADVERTISED_FIBRE;
+
+		if (cmd->advertising & ~mask)
+			return -EINVAL;
+
+		mask &= (ADVERTISED_1000baseT_Half |
+			 ADVERTISED_1000baseT_Full |
+			 ADVERTISED_100baseT_Half |
+			 ADVERTISED_100baseT_Full |
+			 ADVERTISED_10baseT_Half |
+			 ADVERTISED_10baseT_Full);
+
+		cmd->advertising &= mask;
+	} else {
+		if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+			if (cmd->speed != SPEED_1000)
+				return -EINVAL;
+
+			if (cmd->duplex != DUPLEX_FULL)
+				return -EINVAL;
+		} else {
+			if (cmd->speed != SPEED_100 &&
+			    cmd->speed != SPEED_10)
+				return -EINVAL;
+		}
+	}
+
 	tg3_full_lock(tp, 0);
 
 	tp->link_config.autoneg = cmd->autoneg;
@@ -9016,10 +9189,10 @@ static void tg3_get_ethtool_stats (struc
 static int tg3_test_nvram(struct tg3 *tp)
 {
 	u32 csum, magic;
-	__le32 *buf;
+	__be32 *buf;
 	int i, j, k, err = 0, size;
 
-	if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+	if (tg3_nvram_read(tp, 0, &magic) != 0)
 		return -EIO;
 
 	if (magic == TG3_EEPROM_MAGIC)
@@ -9053,14 +9226,15 @@ static int tg3_test_nvram(struct tg3 *tp
 
 	err = -EIO;
 	for (i = 0, j = 0; i < size; i += 4, j++) {
-		if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0)
+		err = tg3_nvram_read_be32(tp, i, &buf[j]);
+		if (err)
 			break;
 	}
 	if (i < size)
 		goto out;
 
 	/* Selfboot format */
-	magic = swab32(le32_to_cpu(buf[0]));
+	magic = be32_to_cpu(buf[0]);
 	if ((magic & TG3_EEPROM_MAGIC_FW_MSK) ==
 	    TG3_EEPROM_MAGIC_FW) {
 		u8 *buf8 = (u8 *) buf, csum8 = 0;
@@ -9089,7 +9263,7 @@ static int tg3_test_nvram(struct tg3 *tp
 	if ((magic & TG3_EEPROM_MAGIC_HW_MSK) ==
 	    TG3_EEPROM_MAGIC_HW) {
 		u8 data[NVRAM_SELFBOOT_DATA_SIZE];
-	       	u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+		u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
 		u8 *buf8 = (u8 *) buf;
 
 		/* Separate the parity bits and the data bytes.  */
@@ -9132,13 +9306,13 @@ static int tg3_test_nvram(struct tg3 *tp
 
 	/* Bootstrap checksum at offset 0x10 */
 	csum = calc_crc((unsigned char *) buf, 0x10);
-	if(csum != le32_to_cpu(buf[0x10/4]))
+	if (csum != be32_to_cpu(buf[0x10/4]))
 		goto out;
 
 	/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
 	csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
-	if (csum != le32_to_cpu(buf[0xfc/4]))
-		 goto out;
+	if (csum != be32_to_cpu(buf[0xfc/4]))
+		goto out;
 
 	err = 0;
 
@@ -9847,8 +10021,12 @@ static void tg3_vlan_rx_register(struct
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	if (netif_running(dev))
-		tg3_netif_stop(tp);
+	if (!netif_running(dev)) {
+		tp->vlgrp = grp;
+		return;
+	}
+
+	tg3_netif_stop(tp);
 
 	tg3_full_lock(tp, 0);
 
@@ -9857,8 +10035,7 @@ static void tg3_vlan_rx_register(struct
 	/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
 	__tg3_set_rx_mode(dev);
 
-	if (netif_running(dev))
-		tg3_netif_start(tp);
+	tg3_netif_start(tp);
 
 	tg3_full_unlock(tp);
 }
@@ -9965,7 +10142,7 @@ static void __devinit tg3_get_eeprom_siz
 
 	tp->nvram_size = EEPROM_CHIP_SIZE;
 
-	if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+	if (tg3_nvram_read(tp, 0, &magic) != 0)
 		return;
 
 	if ((magic != TG3_EEPROM_MAGIC) &&
@@ -9981,7 +10158,7 @@ static void __devinit tg3_get_eeprom_siz
 	cursize = 0x10;
 
 	while (cursize < tp->nvram_size) {
-		if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
+		if (tg3_nvram_read(tp, cursize, &val) != 0)
 			return;
 
 		if (val == magic)
@@ -9997,7 +10174,7 @@ static void __devinit tg3_get_nvram_size
 {
 	u32 val;
 
-	if (tg3_nvram_read_swab(tp, 0, &val) != 0)
+	if (tg3_nvram_read(tp, 0, &val) != 0)
 		return;
 
 	/* Selfboot format */
@@ -10008,7 +10185,18 @@ static void __devinit tg3_get_nvram_size
 
 	if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
 		if (val != 0) {
-			tp->nvram_size = (val >> 16) * 1024;
+			/* This is confusing.  We want to operate on the
+			 * 16-bit value at offset 0xf2.  The tg3_nvram_read()
+			 * call will read from NVRAM and byteswap the data
+			 * according to the byteswapping settings for all
+			 * other register accesses.  This ensures the data we
+			 * want will always reside in the lower 16-bits.
+			 * However, the data in NVRAM is in LE format, which
+			 * means the data from the NVRAM read will always be
+			 * opposite the endianness of the CPU.  The 16-bit
+			 * byteswap then brings the data to CPU endianness.
+			 */
+			tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
 			return;
 		}
 	}
@@ -10459,141 +10647,6 @@ static void __devinit tg3_nvram_init(str
 	}
 }
 
-static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
-					u32 offset, u32 *val)
-{
-	u32 tmp;
-	int i;
-
-	if (offset > EEPROM_ADDR_ADDR_MASK ||
-	    (offset % 4) != 0)
-		return -EINVAL;
-
-	tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
-					EEPROM_ADDR_DEVID_MASK |
-					EEPROM_ADDR_READ);
-	tw32(GRC_EEPROM_ADDR,
-	     tmp |
-	     (0 << EEPROM_ADDR_DEVID_SHIFT) |
-	     ((offset << EEPROM_ADDR_ADDR_SHIFT) &
-	      EEPROM_ADDR_ADDR_MASK) |
-	     EEPROM_ADDR_READ | EEPROM_ADDR_START);
-
-	for (i = 0; i < 1000; i++) {
-		tmp = tr32(GRC_EEPROM_ADDR);
-
-		if (tmp & EEPROM_ADDR_COMPLETE)
-			break;
-		msleep(1);
-	}
-	if (!(tmp & EEPROM_ADDR_COMPLETE))
-		return -EBUSY;
-
-	*val = tr32(GRC_EEPROM_DATA);
-	return 0;
-}
-
-#define NVRAM_CMD_TIMEOUT 10000
-
-static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
-{
-	int i;
-
-	tw32(NVRAM_CMD, nvram_cmd);
-	for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
-		udelay(10);
-		if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
-			udelay(10);
-			break;
-		}
-	}
-	if (i == NVRAM_CMD_TIMEOUT) {
-		return -EBUSY;
-	}
-	return 0;
-}
-
-static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
-{
-	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
-	    (tp->nvram_jedecnum == JEDEC_ATMEL))
-
-		addr = ((addr / tp->nvram_pagesize) <<
-			ATMEL_AT45DB0X1B_PAGE_POS) +
-		       (addr % tp->nvram_pagesize);
-
-	return addr;
-}
-
-static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
-{
-	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
-	    (tp->nvram_jedecnum == JEDEC_ATMEL))
-
-		addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
-			tp->nvram_pagesize) +
-		       (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
-
-	return addr;
-}
-
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
-{
-	int ret;
-
-	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
-		return tg3_nvram_read_using_eeprom(tp, offset, val);
-
-	offset = tg3_nvram_phys_addr(tp, offset);
-
-	if (offset > NVRAM_ADDR_MSK)
-		return -EINVAL;
-
-	ret = tg3_nvram_lock(tp);
-	if (ret)
-		return ret;
-
-	tg3_enable_nvram_access(tp);
-
-	tw32(NVRAM_ADDR, offset);
-	ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
-		NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
-
-	if (ret == 0)
-		*val = swab32(tr32(NVRAM_RDDATA));
-
-	tg3_disable_nvram_access(tp);
-
-	tg3_nvram_unlock(tp);
-
-	return ret;
-}
-
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val)
-{
-	u32 v;
-	int res = tg3_nvram_read(tp, offset, &v);
-	if (!res)
-		*val = cpu_to_le32(v);
-	return res;
-}
-
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
-{
-	int err;
-	u32 tmp;
-
-	err = tg3_nvram_read(tp, offset, &tmp);
-	*val = swab32(tmp);
-	return err;
-}
-
 static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
 				    u32 offset, u32 len, u8 *buf)
 {
@@ -10602,13 +10655,19 @@ static int tg3_nvram_write_block_using_e
 
 	for (i = 0; i < len; i += 4) {
 		u32 addr;
-		__le32 data;
+		__be32 data;
 
 		addr = offset + i;
 
 		memcpy(&data, buf + i, 4);
 
-		tw32(GRC_EEPROM_DATA, le32_to_cpu(data));
+		/*
+		 * The SEEPROM interface expects the data to always be opposite
+		 * the native endian format.  We accomplish this by reversing
+		 * all the operations that would have been performed on the
+		 * data from a call to tg3_nvram_read_be32().
+		 */
+		tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
 
 		val = tr32(GRC_EEPROM_ADDR);
 		tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
@@ -10658,8 +10717,9 @@ static int tg3_nvram_write_block_unbuffe
 		phy_addr = offset & ~pagemask;
 
 		for (j = 0; j < pagesize; j += 4) {
-			if ((ret = tg3_nvram_read_le(tp, phy_addr + j,
-						(__le32 *) (tmp + j))))
+			ret = tg3_nvram_read_be32(tp, phy_addr + j,
+						  (__be32 *) (tmp + j));
+			if (ret)
 				break;
 		}
 		if (ret)
@@ -10706,7 +10766,7 @@ static int tg3_nvram_write_block_unbuffe
 			__be32 data;
 
 			data = *((__be32 *) (tmp + j));
-			/* swab32(le32_to_cpu(data)), actually */
+
 			tw32(NVRAM_WRDATA, be32_to_cpu(data));
 
 			tw32(NVRAM_ADDR, phy_addr + j);
@@ -11169,7 +11229,7 @@ static int __devinit tg3_phy_probe(struc
 		return tg3_phy_init(tp);
 
 	/* Reading the PHY ID register can conflict with ASF
-	 * firwmare access to the PHY hardware.
+	 * firmware access to the PHY hardware.
 	 */
 	err = 0;
 	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
@@ -11292,24 +11352,25 @@ skip_phy_reset:
 
 static void __devinit tg3_read_partno(struct tg3 *tp)
 {
-	unsigned char vpd_data[256];
+	unsigned char vpd_data[256];   /* in little-endian format */
 	unsigned int i;
 	u32 magic;
 
-	if (tg3_nvram_read_swab(tp, 0x0, &magic))
+	if (tg3_nvram_read(tp, 0x0, &magic))
 		goto out_not_found;
 
 	if (magic == TG3_EEPROM_MAGIC) {
 		for (i = 0; i < 256; i += 4) {
 			u32 tmp;
 
-			if (tg3_nvram_read(tp, 0x100 + i, &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))
 				goto out_not_found;
 
-			vpd_data[i + 0] = ((tmp >>  0) & 0xff);
-			vpd_data[i + 1] = ((tmp >>  8) & 0xff);
-			vpd_data[i + 2] = ((tmp >> 16) & 0xff);
-			vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+			memcpy(&vpd_data[i], &tmp, sizeof(tmp));
 		}
 	} else {
 		int vpd_cap;
@@ -11335,7 +11396,7 @@ static void __devinit tg3_read_partno(st
 			pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
 					      &tmp);
 			v = cpu_to_le32(tmp);
-			memcpy(&vpd_data[i], &v, 4);
+			memcpy(&vpd_data[i], &v, sizeof(v));
 		}
 	}
 
@@ -11395,15 +11456,79 @@ static int __devinit tg3_fw_img_is_valid
 {
 	u32 val;
 
-	if (tg3_nvram_read_swab(tp, offset, &val) ||
+	if (tg3_nvram_read(tp, offset, &val) ||
 	    (val & 0xfc000000) != 0x0c000000 ||
-	    tg3_nvram_read_swab(tp, offset + 4, &val) ||
+	    tg3_nvram_read(tp, offset + 4, &val) ||
 	    val != 0)
 		return 0;
 
 	return 1;
 }
 
+static void __devinit tg3_read_bc_ver(struct tg3 *tp)
+{
+	u32 val, offset, start, ver_offset;
+	int i;
+	bool newver = false;
+
+	if (tg3_nvram_read(tp, 0xc, &offset) ||
+	    tg3_nvram_read(tp, 0x4, &start))
+		return;
+
+	offset = tg3_nvram_logical_addr(tp, offset);
+
+	if (tg3_nvram_read(tp, offset, &val))
+		return;
+
+	if ((val & 0xfc000000) == 0x0c000000) {
+		if (tg3_nvram_read(tp, offset + 4, &val))
+			return;
+
+		if (val == 0)
+			newver = true;
+	}
+
+	if (newver) {
+		if (tg3_nvram_read(tp, offset + 8, &ver_offset))
+			return;
+
+		offset = offset + ver_offset - start;
+		for (i = 0; i < 16; i += 4) {
+			__be32 v;
+			if (tg3_nvram_read_be32(tp, offset + i, &v))
+				return;
+
+			memcpy(tp->fw_ver + i, &v, sizeof(v));
+		}
+	} else {
+		u32 major, minor;
+
+		if (tg3_nvram_read(tp, TG3_NVM_PTREV_BCVER, &ver_offset))
+			return;
+
+		major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
+			TG3_NVM_BCVER_MAJSFT;
+		minor = ver_offset & TG3_NVM_BCVER_MINMSK;
+		snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor);
+	}
+}
+
+static void __devinit tg3_read_hwsb_ver(struct tg3 *tp)
+{
+	u32 val, major, minor;
+
+	/* Use native endian representation */
+	if (tg3_nvram_read(tp, TG3_NVM_HWSB_CFG1, &val))
+		return;
+
+	major = (val & TG3_NVM_HWSB_CFG1_MAJMSK) >>
+		TG3_NVM_HWSB_CFG1_MAJSFT;
+	minor = (val & TG3_NVM_HWSB_CFG1_MINMSK) >>
+		TG3_NVM_HWSB_CFG1_MINSFT;
+
+	snprintf(&tp->fw_ver[0], 32, "sb v%d.%02d", major, minor);
+}
+
 static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
 {
 	u32 offset, major, minor, build;
@@ -11429,7 +11554,7 @@ static void __devinit tg3_read_sb_ver(st
 		return;
 	}
 
-	if (tg3_nvram_read_swab(tp, offset, &val))
+	if (tg3_nvram_read(tp, offset, &val))
 		return;
 
 	build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
@@ -11449,49 +11574,15 @@ static void __devinit tg3_read_sb_ver(st
 	}
 }
 
-static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp)
 {
 	u32 val, offset, start;
-	u32 ver_offset;
-	int i, bcnt;
-
-	if (tg3_nvram_read_swab(tp, 0, &val))
-		return;
-
-	if (val != TG3_EEPROM_MAGIC) {
-		if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
-			tg3_read_sb_ver(tp, val);
-
-		return;
-	}
-
-	if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
-	    tg3_nvram_read_swab(tp, 0x4, &start))
-		return;
-
-	offset = tg3_nvram_logical_addr(tp, offset);
-
-	if (!tg3_fw_img_is_valid(tp, offset) ||
-	    tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
-		return;
-
-	offset = offset + ver_offset - start;
-	for (i = 0; i < 16; i += 4) {
-		__le32 v;
-		if (tg3_nvram_read_le(tp, offset + i, &v))
-			return;
-
-		memcpy(tp->fw_ver + i, &v, 4);
-	}
-
-	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-	     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
-		return;
+	int i, vlen;
 
 	for (offset = TG3_NVM_DIR_START;
 	     offset < TG3_NVM_DIR_END;
 	     offset += TG3_NVM_DIRENT_SIZE) {
-		if (tg3_nvram_read_swab(tp, offset, &val))
+		if (tg3_nvram_read(tp, offset, &val))
 			return;
 
 		if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
@@ -11503,36 +11594,87 @@ static void __devinit tg3_read_fw_ver(st
 
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		start = 0x08000000;
-	else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+	else if (tg3_nvram_read(tp, offset - 4, &start))
 		return;
 
-	if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+	if (tg3_nvram_read(tp, offset + 4, &offset) ||
 	    !tg3_fw_img_is_valid(tp, offset) ||
-	    tg3_nvram_read_swab(tp, offset + 8, &val))
+	    tg3_nvram_read(tp, offset + 8, &val))
 		return;
 
 	offset += val - start;
 
-	bcnt = strlen(tp->fw_ver);
+	vlen = strlen(tp->fw_ver);
 
-	tp->fw_ver[bcnt++] = ',';
-	tp->fw_ver[bcnt++] = ' ';
+	tp->fw_ver[vlen++] = ',';
+	tp->fw_ver[vlen++] = ' ';
 
 	for (i = 0; i < 4; i++) {
-		__le32 v;
-		if (tg3_nvram_read_le(tp, offset, &v))
+		__be32 v;
+		if (tg3_nvram_read_be32(tp, offset, &v))
 			return;
 
 		offset += sizeof(v);
 
-		if (bcnt > TG3_VER_SIZE - sizeof(v)) {
-			memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt);
+		if (vlen > TG3_VER_SIZE - sizeof(v)) {
+			memcpy(&tp->fw_ver[vlen], &v, TG3_VER_SIZE - vlen);
 			break;
 		}
 
-		memcpy(&tp->fw_ver[bcnt], &v, sizeof(v));
-		bcnt += sizeof(v);
+		memcpy(&tp->fw_ver[vlen], &v, sizeof(v));
+		vlen += sizeof(v);
 	}
+}
+
+static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+{
+	int vlen;
+	u32 apedata;
+
+	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
+	    !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
+		return;
+
+	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+	if (apedata != APE_SEG_SIG_MAGIC)
+		return;
+
+	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+	if (!(apedata & APE_FW_STATUS_READY))
+		return;
+
+	apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
+
+	vlen = strlen(tp->fw_ver);
+
+	snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d",
+		 (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT,
+		 (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT,
+		 (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT,
+		 (apedata & APE_FW_VERSION_BLDMSK));
+}
+
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+	u32 val;
+
+	if (tg3_nvram_read(tp, 0, &val))
+		return;
+
+	if (val == TG3_EEPROM_MAGIC)
+		tg3_read_bc_ver(tp);
+	else if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+		tg3_read_sb_ver(tp, val);
+	else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+		tg3_read_hwsb_ver(tp);
+	else
+		return;
+
+	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+	     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+		return;
+
+	tg3_read_mgmtfw_ver(tp);
 
 	tp->fw_ver[TG3_VER_SIZE - 1] = 0;
 }
@@ -12303,14 +12445,10 @@ static int __devinit tg3_get_device_addr
 	}
 	if (!addr_ok) {
 		/* Next, try NVRAM. */
-		if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
-		    !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
-			dev->dev_addr[0] = ((hi >> 16) & 0xff);
-			dev->dev_addr[1] = ((hi >> 24) & 0xff);
-			dev->dev_addr[2] = ((lo >>  0) & 0xff);
-			dev->dev_addr[3] = ((lo >>  8) & 0xff);
-			dev->dev_addr[4] = ((lo >> 16) & 0xff);
-			dev->dev_addr[5] = ((lo >> 24) & 0xff);
+		if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+		    !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
+			memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
+			memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
 		}
 		/* Finally just fetch it out of the MAC control regs. */
 		else {
@@ -13094,17 +13232,17 @@ static int __devinit tg3_init_one(struct
 	 * do DMA address check in tg3_start_xmit().
 	 */
 	if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
-		persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+		persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
 	else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
-		persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+		persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
 #ifdef CONFIG_HIGHMEM
-		dma_mask = DMA_64BIT_MASK;
+		dma_mask = DMA_BIT_MASK(64);
 #endif
 	} else
-		persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+		persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
 
 	/* Configure DMA attributes. */
-	if (dma_mask > DMA_32BIT_MASK) {
+	if (dma_mask > DMA_BIT_MASK(32)) {
 		err = pci_set_dma_mask(pdev, dma_mask);
 		if (!err) {
 			dev->features |= NETIF_F_HIGHDMA;
@@ -13117,8 +13255,8 @@ static int __devinit tg3_init_one(struct
 			}
 		}
 	}
-	if (err || dma_mask == DMA_32BIT_MASK) {
-		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (err || dma_mask == DMA_BIT_MASK(32)) {
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
@@ -13191,6 +13329,9 @@ static int __devinit tg3_init_one(struct
 		}
 
 		tg3_ape_lock_init(tp);
+
+		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+			tg3_read_dash_ver(tp);
 	}
 
 	/*
@@ -13256,8 +13397,8 @@ static int __devinit tg3_init_one(struct
 	       (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
 	printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
 	       dev->name, tp->dma_rwctrl,
-	       (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
-	        (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
+	       (pdev->dma_mask == DMA_BIT_MASK(32)) ? 32 :
+	        (((u64) pdev->dma_mask == DMA_BIT_MASK(40)) ? 40 : 64));
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tg3.h linux-libre-2.6.30-gnu1/drivers/net/tg3.h
--- linux-libre-2.6.29-gnu1/drivers/net/tg3.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tg3.h	2009-06-09 23:05:27.000000000 -0400
@@ -1719,6 +1719,12 @@
 
 #define TG3_OTP_DEFAULT			0x286c1640
 
+/* Hardware Selfboot NVRAM layout */
+#define TG3_NVM_HWSB_CFG1		0x00000004
+#define  TG3_NVM_HWSB_CFG1_MAJMSK	0xf8000000
+#define  TG3_NVM_HWSB_CFG1_MAJSFT	27
+#define  TG3_NVM_HWSB_CFG1_MINMSK	0x07c00000
+#define  TG3_NVM_HWSB_CFG1_MINSFT	22
 
 #define TG3_EEPROM_MAGIC		0x669955aa
 #define TG3_EEPROM_MAGIC_FW		0xa5000000
@@ -1737,6 +1743,10 @@
 #define TG3_NVM_DIRENT_SIZE		0xc
 #define TG3_NVM_DIRTYPE_SHIFT		24
 #define TG3_NVM_DIRTYPE_ASFINI		1
+#define TG3_NVM_PTREV_BCVER		0x94
+#define TG3_NVM_BCVER_MAJMSK		0x0000ff00
+#define TG3_NVM_BCVER_MAJSFT		8
+#define TG3_NVM_BCVER_MINMSK		0x000000ff
 
 #define TG3_EEPROM_SB_F1R0_EDH_OFF	0x10
 #define TG3_EEPROM_SB_F1R2_EDH_OFF	0x14
@@ -1967,6 +1977,14 @@
 /* APE shared memory.  Accessible through BAR1 */
 #define TG3_APE_FW_STATUS		0x400c
 #define  APE_FW_STATUS_READY		 0x00000100
+#define TG3_APE_FW_VERSION		0x4018
+#define  APE_FW_VERSION_MAJMSK		 0xff000000
+#define  APE_FW_VERSION_MAJSFT		 24
+#define  APE_FW_VERSION_MINMSK		 0x00ff0000
+#define  APE_FW_VERSION_MINSFT		 16
+#define  APE_FW_VERSION_REVMSK		 0x0000ff00
+#define  APE_FW_VERSION_REVSFT		 8
+#define  APE_FW_VERSION_BLDMSK		 0x000000ff
 #define TG3_APE_HOST_SEG_SIG		0x4200
 #define  APE_HOST_SEG_SIG_MAGIC		 0x484f5354
 #define TG3_APE_HOST_SEG_LEN		0x4204
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tlan.c linux-libre-2.6.30-gnu1/drivers/net/tlan.c
--- linux-libre-2.6.29-gnu1/drivers/net/tlan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tlan.c	2009-06-09 23:05:27.000000000 -0400
@@ -570,7 +570,7 @@ static int __devinit TLan_probe1(struct
 
 		priv->adapter = &board_info[ent->driver_data];
 
-		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (rc) {
 			printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
 			goto err_out_free_dev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/3c359.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/3c359.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 18:03:47.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/3c359.c	2013-05-03 16:47:37.000000000 -0400
@@ -62,6 +62,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/firmware.h>
 
 #include <net/checksum.h>
 
@@ -73,8 +74,10 @@
 static char version[] __devinitdata  = 
 "3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; 
 
+#define FW_NAME		"/*(DEBLOBBED)*/"
 MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 
 MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
+/*(DEBLOBBED)*/
 
 /* Module paramters */
 
@@ -114,8 +117,6 @@ MODULE_PARM_DESC(message_level, "3c359:
  *	will be stuck with 1555 lines of hex #'s in the code.
  */
 
-/*(DEBLOBBED)*/ 
-
 static struct pci_device_id xl_pci_tbl[] =
 {
 	{PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
@@ -274,6 +275,15 @@ static void  xl_ee_write(struct net_devi
 	
 	return ; 
 }
+
+static const struct net_device_ops xl_netdev_ops = {
+	.ndo_open		= xl_open,
+	.ndo_stop		= xl_close,
+	.ndo_start_xmit		= xl_xmit,
+	.ndo_change_mtu		= xl_change_mtu,
+	.ndo_set_multicast_list = xl_set_rx_mode,
+	.ndo_set_mac_address	= xl_set_mac_address,
+};
  
 static int __devinit xl_probe(struct pci_dev *pdev,
 			      const struct pci_device_id *ent) 
@@ -337,13 +347,7 @@ static int __devinit xl_probe(struct pci
 		return i ; 
 	}				
 
-	dev->open=&xl_open;
-	dev->hard_start_xmit=&xl_xmit;
-	dev->change_mtu=&xl_change_mtu;
-	dev->stop=&xl_close;
-	dev->do_ioctl=NULL;
-	dev->set_multicast_list=&xl_set_rx_mode;
-	dev->set_mac_address=&xl_set_mac_address ; 
+	dev->netdev_ops = &xl_netdev_ops;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	pci_set_drvdata(pdev,dev) ; 
@@ -361,10 +365,30 @@ static int __devinit xl_probe(struct pci
 	return 0; 
 }
 
+static int xl_init_firmware(struct xl_private *xl_priv)
+{
+	int err;
+
+	err = reject_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev);
+	if (err) {
+		printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME);
+		return err;
+	}
+
+	if (xl_priv->fw->size < 16) {
+		printk(KERN_ERR "Bogus length %zu in \"%s\"\n",
+		       xl_priv->fw->size, FW_NAME);
+		release_firmware(xl_priv->fw);
+		err = -EINVAL;
+	}
+
+	return err;
+}
 
 static int __devinit xl_init(struct net_device *dev) 
 {
 	struct xl_private *xl_priv = netdev_priv(dev);
+	int err;
 
 	printk(KERN_INFO "%s \n", version);
 	printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
@@ -372,8 +396,11 @@ static int __devinit xl_init(struct net_
 
 	spin_lock_init(&xl_priv->xl_lock) ; 
 
-	return xl_hw_reset(dev) ; 
+	err = xl_init_firmware(xl_priv);
+	if (err == 0)
+		err = xl_hw_reset(dev);
 
+	return err;
 }
 
 
@@ -383,7 +410,7 @@ static int __devinit xl_init(struct net_
  */
 
 static int xl_hw_reset(struct net_device *dev) 
-{ 
+{
 	struct xl_private *xl_priv = netdev_priv(dev);
 	u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
 	unsigned long t ; 
@@ -393,6 +420,9 @@ static int xl_hw_reset(struct net_device
 	u16 start ; 
 	int j ;
 
+	if (xl_priv->fw == NULL)
+		return -EINVAL;
+
 	/*
 	 *  Reset the card.  If the card has got the microcode on board, we have 
          *  missed the initialization interrupt, so we must always do this.
@@ -455,13 +485,31 @@ static int xl_hw_reset(struct net_device
 
 		/* 
 		 * Now to write the microcode into the shared ram 
-	 	 * The microcode must finish at position 0xFFFF, so we must subtract
-		 * to get the start position for the code
+	 	 * The microcode must finish at position 0xFFFF,
+	 	 * so we must subtract to get the start position for the code
+	 	 *
+		 * Looks strange but ensures compiler only uses
+		 * 16 bit unsigned int
 		 */
+		start = (0xFFFF - (xl_priv->fw->size) + 1) ;
 
-		printk(KERN_ERR "%s: Missing Free firmware\n", dev->name);
-		return -EINVAL;
-		/*(DEBLOBBED)*/
+		printk(KERN_INFO "3C359: Uploading Microcode: "); 
+
+		for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) {
+			writel(MEM_BYTE_WRITE | 0XD0000 | i,
+			       xl_mmio + MMIO_MAC_ACCESS_CMD);
+			writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA);
+			if (j % 1024 == 0)
+				printk(".");
+		}
+		printk("\n") ; 
+
+		for (i = 0; i < 16; i++) {
+			writel((MEM_BYTE_WRITE | 0xDFFF0) + i,
+			       xl_mmio + MMIO_MAC_ACCESS_CMD);
+			writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i],
+			       xl_mmio + MMIO_MACDATA);
+		}
 
 		/*
 		 * Have to write the start address of the upload to FFF4, but
@@ -1766,6 +1814,7 @@ static void __devexit xl_remove_one (str
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct xl_private *xl_priv=netdev_priv(dev);
 	
+	release_firmware(xl_priv->fw);
 	unregister_netdev(dev);
 	iounmap(xl_priv->xl_mmio) ; 
 	pci_release_regions(pdev) ; 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/3c359.h linux-libre-2.6.30-gnu1/drivers/net/tokenring/3c359.h
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/3c359.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/3c359.h	2009-06-09 23:05:27.000000000 -0400
@@ -284,5 +284,8 @@ struct xl_private {
 	u8 xl_laa[6] ; 
 	u32 rx_ring_dma_addr ; 
 	u32 tx_ring_dma_addr ; 
+
+	/* firmware section */
+	const struct firmware *fw;
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/abyss.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/abyss.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/abyss.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/abyss.c	2009-06-09 23:05:27.000000000 -0400
@@ -92,6 +92,8 @@ static void abyss_sifwritew(struct net_d
 	outw(val, dev->base_addr + reg);
 }
 
+static struct net_device_ops abyss_netdev_ops;
+
 static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
 {	
 	static int versionprinted;
@@ -157,8 +159,7 @@ static int __devinit abyss_attach(struct
 
 	memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
 		
-	dev->open = abyss_open;
-	dev->stop = abyss_close;
+	dev->netdev_ops = &abyss_netdev_ops;
 
 	pci_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -450,6 +451,11 @@ static struct pci_driver abyss_driver =
 
 static int __init abyss_init (void)
 {
+	abyss_netdev_ops = tms380tr_netdev_ops;
+
+	abyss_netdev_ops.ndo_open = abyss_open;
+	abyss_netdev_ops.ndo_stop = abyss_close;
+
 	return pci_register_driver(&abyss_driver);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/ibmtr.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/ibmtr.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/ibmtr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/ibmtr.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,7 +200,6 @@ static void 	tr_rx(struct net_device *de
 static void	ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
 static void	tok_rerun(unsigned long dev_addr);
 static void	ibmtr_readlog(struct net_device *dev);
-static struct 	net_device_stats *tok_get_stats(struct net_device *dev);
 static int	ibmtr_change_mtu(struct net_device *dev, int mtu);
 static void	find_turbo_adapters(int *iolist);
 
@@ -816,18 +815,21 @@ static unsigned char __devinit get_sram_
 
 /*****************************************************************************/
 
+static const struct net_device_ops trdev_netdev_ops = {
+	.ndo_open		= tok_open,
+	.ndo_stop		= tok_close,
+	.ndo_start_xmit		= tok_send_packet,
+	.ndo_set_multicast_list = tok_set_multicast_list,
+	.ndo_change_mtu		= ibmtr_change_mtu,
+};
+
 static int __devinit trdev_init(struct net_device *dev)
 {
 	struct tok_info *ti = netdev_priv(dev);
 
 	SET_PAGE(ti->srb_page);
         ti->open_failure = NO    ;
-	dev->open = tok_open;
-	dev->stop = tok_close;
-	dev->hard_start_xmit = tok_send_packet;
-	dev->get_stats = tok_get_stats;
-	dev->set_multicast_list = tok_set_multicast_list;
-	dev->change_mtu = ibmtr_change_mtu;
+	dev->netdev_ops = &trdev_netdev_ops;
 
 	return 0;
 }
@@ -1460,7 +1462,7 @@ static irqreturn_t tok_interrupt(int irq
 					"%02X\n",
 					(int)retcode, (int)readb(ti->ssb + 6));
 			else
-				ti->tr_stats.tx_packets++;
+				dev->stats.tx_packets++;
 			break;
 		case XMIT_XID_CMD:
 			DPRINTK("xmit xid ret_code: %02X\n",
@@ -1646,7 +1648,7 @@ static void tr_tx(struct net_device *dev
 		break;
 	}
 	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-	ti->tr_stats.tx_bytes += ti->current_skb->len;
+	dev->stats.tx_bytes += ti->current_skb->len;
 	dev_kfree_skb_irq(ti->current_skb);
 	ti->current_skb = NULL;
 	netif_wake_queue(dev);
@@ -1722,7 +1724,7 @@ static void tr_rx(struct net_device *dev
 	if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
 		SET_PAGE(ti->asb_page);
 		writeb(DATA_LOST, ti->asb + RETCODE_OFST);
-		ti->tr_stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 		return;
 	}
@@ -1757,7 +1759,7 @@ static void tr_rx(struct net_device *dev
 
 	if (!(skb = dev_alloc_skb(skb_size))) {
 		DPRINTK("out of memory. frame dropped.\n");
-		ti->tr_stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		SET_PAGE(ti->asb_page);
 		writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
 		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
@@ -1813,8 +1815,8 @@ static void tr_rx(struct net_device *dev
 
 	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
-	ti->tr_stats.rx_bytes += skb->len;
-	ti->tr_stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_packets++;
 
 	skb->protocol = tr_type_trans(skb, dev);
 	if (IPv4_p) {
@@ -1875,21 +1877,6 @@ static void ibmtr_readlog(struct net_dev
 }
 
 /*****************************************************************************/
-
-/* tok_get_stats():  Basically a scaffold routine which will return
-   the address of the tr_statistics structure associated with
-   this device -- the tr.... structure is an ethnet look-alike
-   so at least for this iteration may suffice.   */
-
-static struct net_device_stats *tok_get_stats(struct net_device *dev)
-{
-
-	struct tok_info *toki;
-	toki = netdev_priv(dev);
-	return (struct net_device_stats *) &toki->tr_stats;
-}
-
-/*****************************************************************************/
 
 static int ibmtr_change_mtu(struct net_device *dev, int mtu)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/lanstreamer.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/lanstreamer.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/lanstreamer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/lanstreamer.c	2009-06-09 23:05:27.000000000 -0400
@@ -207,7 +207,6 @@ static int streamer_xmit(struct sk_buff
 static int streamer_close(struct net_device *dev);
 static void streamer_set_rx_mode(struct net_device *dev);
 static irqreturn_t streamer_interrupt(int irq, void *dev_id);
-static struct net_device_stats *streamer_get_stats(struct net_device *dev);
 static int streamer_set_mac_address(struct net_device *dev, void *addr);
 static void streamer_arb_cmd(struct net_device *dev);
 static int streamer_change_mtu(struct net_device *dev, int mtu);
@@ -222,6 +221,18 @@ struct streamer_private *dev_streamer=NU
 #endif
 #endif
 
+static const struct net_device_ops streamer_netdev_ops = {
+	.ndo_open		= streamer_open,
+	.ndo_stop		= streamer_close,
+	.ndo_start_xmit		= streamer_xmit,
+	.ndo_change_mtu		= streamer_change_mtu,
+#if STREAMER_IOCTL
+	.ndo_do_ioctl		= streamer_ioctl,
+#endif
+	.ndo_set_multicast_list = streamer_set_rx_mode,
+	.ndo_set_mac_address	= streamer_set_mac_address,
+};
+
 static int __devinit streamer_init_one(struct pci_dev *pdev,
 				       const struct pci_device_id *ent)
 {
@@ -256,7 +267,7 @@ static int __devinit streamer_init_one(s
 #endif
 #endif
 
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		printk(KERN_ERR "%s: No suitable PCI mapping available.\n",
 				dev->name);
@@ -321,18 +332,7 @@ static int __devinit streamer_init_one(s
 	init_waitqueue_head(&streamer_priv->srb_wait);
 	init_waitqueue_head(&streamer_priv->trb_wait);
 
-	dev->open = &streamer_open;
-	dev->hard_start_xmit = &streamer_xmit;
-	dev->change_mtu = &streamer_change_mtu;
-	dev->stop = &streamer_close;
-#if STREAMER_IOCTL
-	dev->do_ioctl = &streamer_ioctl;
-#else
-	dev->do_ioctl = NULL;
-#endif
-	dev->set_multicast_list = &streamer_set_rx_mode;
-	dev->get_stats = &streamer_get_stats;
-	dev->set_mac_address = &streamer_set_mac_address;
+	dev->netdev_ops = &streamer_netdev_ops;
 	dev->irq = pdev->irq;
 	dev->base_addr=pio_start;
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -616,8 +616,6 @@ static int streamer_open(struct net_devi
 	printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK));
 #endif
 	do {
-		int i;
-
 		for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
 			writew(0, streamer_mmio + LAPDINC);
 		}
@@ -937,7 +935,7 @@ static void streamer_rx(struct net_devic
 			if (skb == NULL) 
 			{
 				printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",	dev->name);
-				streamer_priv->streamer_stats.rx_dropped++;
+				dev->stats.rx_dropped++;
 			} else {	/* we allocated an skb OK */
 				if (buffer_cnt == 1) {
 					/* release the DMA mapping */
@@ -1009,8 +1007,8 @@ static void streamer_rx(struct net_devic
 					/* send up to the protocol */
 					netif_rx(skb);
 				}
-				streamer_priv->streamer_stats.rx_packets++;
-				streamer_priv->streamer_stats.rx_bytes += length;
+				dev->stats.rx_packets++;
+				dev->stats.rx_bytes += length;
 			}	/* if skb == null */
 		}		/* end received without errors */
 
@@ -1053,8 +1051,8 @@ static irqreturn_t streamer_interrupt(in
 				while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
 				streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
 				streamer_priv->free_tx_ring_entries++;
-				streamer_priv->streamer_stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
-				streamer_priv->streamer_stats.tx_packets++;
+				dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
+				dev->stats.tx_packets++;
 				dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]);
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef;
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
@@ -1484,13 +1482,6 @@ static void streamer_srb_bh(struct net_d
 	}			/* switch srb[0] */
 }
 
-static struct net_device_stats *streamer_get_stats(struct net_device *dev)
-{
-	struct streamer_private *streamer_priv;
-	streamer_priv = netdev_priv(dev);
-	return (struct net_device_stats *) &streamer_priv->streamer_stats;
-}
-
 static int streamer_set_mac_address(struct net_device *dev, void *addr)
 {
 	struct sockaddr *saddr = addr;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/lanstreamer.h linux-libre-2.6.30-gnu1/drivers/net/tokenring/lanstreamer.h
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/lanstreamer.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/lanstreamer.h	2009-06-09 23:05:27.000000000 -0400
@@ -299,7 +299,6 @@ struct streamer_private {
 	int tx_ring_free, tx_ring_last_status, rx_ring_last_received,
 	    free_tx_ring_entries;
 
-	struct net_device_stats streamer_stats;
 	__u16 streamer_lan_status;
 	__u8 streamer_ring_speed;
 	__u16 pkt_buf_sz;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/madgemc.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/madgemc.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/madgemc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/madgemc.c	2009-06-09 23:05:27.000000000 -0400
@@ -142,7 +142,7 @@ static void madgemc_sifwritew(struct net
 	return;
 }
 
-
+static struct net_device_ops madgemc_netdev_ops __read_mostly;
 
 static int __devinit madgemc_probe(struct device *device)
 {	
@@ -168,7 +168,7 @@ static int __devinit madgemc_probe(struc
 		goto getout;
 	}
 
-	dev->dma = 0;
+	dev->netdev_ops = &madgemc_netdev_ops;
 
 	card = kmalloc(sizeof(struct card_info), GFP_KERNEL);
 	if (card==NULL) {
@@ -348,9 +348,6 @@ static int __devinit madgemc_probe(struc
 
 	memcpy(tp->ProductID, "Madge MCA 16/4    ", PROD_ID_SIZE + 1);
 
-	dev->open = madgemc_open;
-	dev->stop = madgemc_close;
-
 	tp->tmspriv = card;
 	dev_set_drvdata(device, dev);
 
@@ -692,8 +689,6 @@ static int madgemc_mcaproc(char *buf, in
 	
 	len += sprintf(buf+len, "-------\n");
 	if (curcard) {
-		struct net_local *tp = netdev_priv(dev);
-		
 		len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev);
 		len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize);
 		len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45");
@@ -760,6 +755,10 @@ static struct mca_driver madgemc_driver
 
 static int __init madgemc_init (void)
 {
+	madgemc_netdev_ops = tms380tr_netdev_ops;
+	madgemc_netdev_ops.ndo_open = madgemc_open;
+	madgemc_netdev_ops.ndo_stop = madgemc_close;
+
 	return mca_register_driver (&madgemc_driver);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/olympic.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/olympic.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/olympic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/olympic.c	2009-06-09 23:05:27.000000000 -0400
@@ -187,7 +187,6 @@ static int olympic_close(struct net_devi
 static void olympic_set_rx_mode(struct net_device *dev);
 static void olympic_freemem(struct net_device *dev) ;  
 static irqreturn_t olympic_interrupt(int irq, void *dev_id);
-static struct net_device_stats * olympic_get_stats(struct net_device *dev);
 static int olympic_set_mac_address(struct net_device *dev, void *addr) ; 
 static void olympic_arb_cmd(struct net_device *dev);
 static int olympic_change_mtu(struct net_device *dev, int mtu);
@@ -195,6 +194,15 @@ static void olympic_srb_bh(struct net_de
 static void olympic_asb_bh(struct net_device *dev) ; 
 static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ; 
 
+static const struct net_device_ops olympic_netdev_ops = {
+	.ndo_open		= olympic_open,
+	.ndo_stop		= olympic_close,
+	.ndo_start_xmit		= olympic_xmit,
+	.ndo_change_mtu		= olympic_change_mtu,
+	.ndo_set_multicast_list	= olympic_set_rx_mode,
+	.ndo_set_mac_address	= olympic_set_mac_address,
+};
+
 static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev ; 
@@ -253,14 +261,7 @@ static int __devinit olympic_probe(struc
 		goto op_free_iomap;
 	}				
 
-	dev->open=&olympic_open;
-	dev->hard_start_xmit=&olympic_xmit;
-	dev->change_mtu=&olympic_change_mtu;
-	dev->stop=&olympic_close;
-	dev->do_ioctl=NULL;
-	dev->set_multicast_list=&olympic_set_rx_mode;
-	dev->get_stats=&olympic_get_stats ;
-	dev->set_mac_address=&olympic_set_mac_address ;  
+	dev->netdev_ops = &olympic_netdev_ops;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	pci_set_drvdata(pdev,dev) ; 
@@ -698,7 +699,6 @@ static int olympic_open(struct net_devic
 	if (olympic_priv->olympic_network_monitor) { 
 		u8 __iomem *oat;
 		u8 __iomem *opt;
-		int i;
 		u8 addr[6];
 		oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
 		opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
@@ -785,7 +785,7 @@ static void olympic_rx(struct net_device
 				} 
 				olympic_priv->rx_ring_last_received += i ; 
 				olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; 
-				olympic_priv->olympic_stats.rx_errors++;	 
+				dev->stats.rx_errors++;
 			} else {	
 			
 				if (buffer_cnt == 1) {
@@ -796,7 +796,7 @@ static void olympic_rx(struct net_device
 
 				if (skb == NULL) {
 					printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
-					olympic_priv->olympic_stats.rx_dropped++ ; 
+					dev->stats.rx_dropped++;
 					/* Update counters even though we don't transfer the frame */
 					olympic_priv->rx_ring_last_received += i ; 
 					olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;  
@@ -862,8 +862,8 @@ static void olympic_rx(struct net_device
 						skb->protocol = tr_type_trans(skb,dev);
 						netif_rx(skb) ; 
 					} 
-					olympic_priv->olympic_stats.rx_packets++ ; 
-					olympic_priv->olympic_stats.rx_bytes += length ; 
+					dev->stats.rx_packets++ ;
+					dev->stats.rx_bytes += length ;
 				} /* if skb == null */
 			} /* If status & 0x3b */
 
@@ -971,8 +971,8 @@ static irqreturn_t olympic_interrupt(int
 				olympic_priv->tx_ring_last_status++;
 				olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
 				olympic_priv->free_tx_ring_entries++;
-				olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
-				olympic_priv->olympic_stats.tx_packets++ ; 
+				dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
+				dev->stats.tx_packets++ ;
 				pci_unmap_single(olympic_priv->pdev, 
 					le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), 
 					olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
@@ -1344,13 +1344,6 @@ static void olympic_srb_bh(struct net_de
 
 } 
 
-static struct net_device_stats * olympic_get_stats(struct net_device *dev)
-{
-	struct olympic_private *olympic_priv ;
-	olympic_priv=netdev_priv(dev);
-	return (struct net_device_stats *) &olympic_priv->olympic_stats; 
-}
-
 static int olympic_set_mac_address (struct net_device *dev, void *addr) 
 {
 	struct sockaddr *saddr = addr ; 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/olympic.h linux-libre-2.6.30-gnu1/drivers/net/tokenring/olympic.h
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/olympic.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/olympic.h	2009-06-09 23:05:27.000000000 -0400
@@ -275,7 +275,6 @@ struct olympic_private {
 	struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE];	
 	int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
 
-	struct net_device_stats olympic_stats ;
 	u16 olympic_lan_status ;
 	u8 olympic_ring_speed ;
 	u16 pkt_buf_sz ; 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/proteon.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/proteon.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/proteon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/proteon.c	2009-06-09 23:05:27.000000000 -0400
@@ -116,6 +116,8 @@ nodev:
 	return -ENODEV;
 }
 
+static struct net_device_ops proteon_netdev_ops __read_mostly;
+
 static int __init setup_card(struct net_device *dev, struct device *pdev)
 {
 	struct net_local *tp;
@@ -167,8 +169,7 @@ static int __init setup_card(struct net_
 
 	tp->tmspriv = NULL;
 
-	dev->open = proteon_open;
-	dev->stop = tms380tr_close;
+	dev->netdev_ops = &proteon_netdev_ops;
 
 	if (dev->irq == 0)
 	{
@@ -352,6 +353,10 @@ static int __init proteon_init(void)
 	struct platform_device *pdev;
 	int i, num = 0, err = 0;
 
+	proteon_netdev_ops = tms380tr_netdev_ops;
+	proteon_netdev_ops.ndo_open = proteon_open;
+	proteon_netdev_ops.ndo_stop = tms380tr_close;
+
 	err = platform_driver_register(&proteon_driver);
 	if (err)
 		return err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/skisa.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/skisa.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/skisa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/skisa.c	2009-06-09 23:05:27.000000000 -0400
@@ -133,6 +133,8 @@ static int __init sk_isa_probe1(struct n
 	return 0;
 }
 
+static struct net_device_ops sk_isa_netdev_ops __read_mostly;
+
 static int __init setup_card(struct net_device *dev, struct device *pdev)
 {
 	struct net_local *tp;
@@ -184,8 +186,7 @@ static int __init setup_card(struct net_
 
 	tp->tmspriv = NULL;
 
-	dev->open = sk_isa_open;
-	dev->stop = tms380tr_close;
+	dev->netdev_ops = &sk_isa_netdev_ops;
 
 	if (dev->irq == 0)
 	{
@@ -362,6 +363,10 @@ static int __init sk_isa_init(void)
 	struct platform_device *pdev;
 	int i, num = 0, err = 0;
 
+	sk_isa_netdev_ops = tms380tr_netdev_ops;
+	sk_isa_netdev_ops.ndo_open = sk_isa_open;
+	sk_isa_netdev_ops.ndo_stop = tms380tr_close;
+
 	err = platform_driver_register(&sk_isa_driver);
 	if (err)
 		return err;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/smctr.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/smctr.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 18:03:52.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/smctr.c	2013-05-03 16:47:41.000000000 -0400
@@ -61,7 +61,8 @@
 
 #include "smctr.h"               /* Our Stuff */
 
-static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
+static const char version[] __initdata =
+	KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
 static const char cardname[] = "smctr";
 
 
@@ -123,7 +124,6 @@ static unsigned int smctr_get_num_rx_bdb
 static int smctr_get_physical_drop_number(struct net_device *dev);
 static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue);
 static int smctr_get_station_id(struct net_device *dev);
-static struct net_device_stats *smctr_get_stats(struct net_device *dev);
 static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
         __u16 bytes_count);
 static int smctr_get_upstream_neighbor_addr(struct net_device *dev);
@@ -3632,6 +3632,14 @@ out:
 	return ERR_PTR(err);
 }
 
+static const struct net_device_ops smctr_netdev_ops = {
+	.ndo_open          = smctr_open,
+	.ndo_stop          = smctr_close,
+	.ndo_start_xmit    = smctr_send_packet,
+	.ndo_tx_timeout	   = smctr_timeout,
+	.ndo_get_stats     = smctr_get_stats,
+	.ndo_set_multicast_list = smctr_set_multicast_list,
+};
 
 static int __init smctr_probe1(struct net_device *dev, int ioaddr)
 {
@@ -3682,13 +3690,8 @@ static int __init smctr_probe1(struct ne
                 (unsigned int)dev->base_addr,
                 dev->irq, tp->rom_base, tp->ram_base);
 
-        dev->open               = smctr_open;
-        dev->stop               = smctr_close;
-        dev->hard_start_xmit    = smctr_send_packet;
-        dev->tx_timeout		= smctr_timeout;
+	dev->netdev_ops = &smctr_netdev_ops;
         dev->watchdog_timeo	= HZ;
-        dev->get_stats          = smctr_get_stats;
-        dev->set_multicast_list = &smctr_set_multicast_list;
         return (0);
 
 out:
@@ -4392,52 +4395,42 @@ static int smctr_ring_status_chg(struct
         {
                 case RING_RECOVERY:
                         printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
-                        tp->current_ring_status |= RING_RECOVERY;
                         break;
 
                 case SINGLE_STATION:
                         printk(KERN_INFO "%s: Single Statinon\n", dev->name);
-                        tp->current_ring_status |= SINGLE_STATION;
                         break;
 
                 case COUNTER_OVERFLOW:
                         printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
-                        tp->current_ring_status |= COUNTER_OVERFLOW;
                         break;
 
                 case REMOVE_RECEIVED:
                         printk(KERN_INFO "%s: Remove Received\n", dev->name);
-                        tp->current_ring_status |= REMOVE_RECEIVED;
                         break;
 
                 case AUTO_REMOVAL_ERROR:
                         printk(KERN_INFO "%s: Auto Remove Error\n", dev->name);
-                        tp->current_ring_status |= AUTO_REMOVAL_ERROR;
                         break;
 
                 case LOBE_WIRE_FAULT:
                         printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name);
-                        tp->current_ring_status |= LOBE_WIRE_FAULT;
                         break;
 
                 case TRANSMIT_BEACON:
                         printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
-                        tp->current_ring_status |= TRANSMIT_BEACON;
                         break;
 
                 case SOFT_ERROR:
                         printk(KERN_INFO "%s: Soft Error\n", dev->name);
-                        tp->current_ring_status |= SOFT_ERROR;
                         break;
 
                 case HARD_ERROR:
                         printk(KERN_INFO "%s: Hard Error\n", dev->name);
-                        tp->current_ring_status |= HARD_ERROR;
                         break;
 
                 case SIGNAL_LOSS:
                         printk(KERN_INFO "%s: Signal Loss\n", dev->name);
-                        tp->current_ring_status |= SIGNAL_LOSS;
                         break;
 
                 default:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/smctr.h linux-libre-2.6.30-gnu1/drivers/net/tokenring/smctr.h
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/smctr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/smctr.h	2009-06-09 23:05:27.000000000 -0400
@@ -977,7 +977,6 @@ typedef struct net_local {
 	__u8		monitor_state_ready;
 	__u16		ring_status;
 	__u8		ring_status_flags;
-	__u8		current_ring_status;
 	__u8		state;
 
 	__u8		join_state;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/tms380tr.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/tms380tr.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 18:03:54.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/tms380tr.c	2013-05-03 16:47:44.000000000 -0400
@@ -2330,6 +2330,17 @@ void tmsdev_term(struct net_device *dev)
 		DMA_BIDIRECTIONAL);
 }
 
+const struct net_device_ops tms380tr_netdev_ops = {
+	.ndo_open		= tms380tr_open,
+	.ndo_stop		= tms380tr_close,
+	.ndo_start_xmit		= tms380tr_send_packet,
+	.ndo_tx_timeout		= tms380tr_timeout,
+	.ndo_get_stats		= tms380tr_get_stats,
+	.ndo_set_multicast_list = tms380tr_set_multicast_list,
+	.ndo_set_mac_address	= tms380tr_set_mac_address,
+};
+EXPORT_SYMBOL(tms380tr_netdev_ops);
+
 int tmsdev_init(struct net_device *dev, struct device *pdev)
 {
 	struct net_local *tms_local;
@@ -2353,16 +2364,8 @@ int tmsdev_init(struct net_device *dev,
 		return -ENOMEM;
 	}
 	
-	/* These can be overridden by the card driver if needed */
-	dev->open		= tms380tr_open;
-	dev->stop		= tms380tr_close;
-	dev->do_ioctl		= NULL; 
-	dev->hard_start_xmit	= tms380tr_send_packet;
-	dev->tx_timeout		= tms380tr_timeout;
+	dev->netdev_ops		= &tms380tr_netdev_ops;
 	dev->watchdog_timeo	= HZ;
-	dev->get_stats		= tms380tr_get_stats;
-	dev->set_multicast_list = &tms380tr_set_multicast_list;
-	dev->set_mac_address	= tms380tr_set_mac_address;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/tms380tr.h linux-libre-2.6.30-gnu1/drivers/net/tokenring/tms380tr.h
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/tms380tr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/tms380tr.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 
 /* module prototypes */
+extern const struct net_device_ops tms380tr_netdev_ops;
 int tms380tr_open(struct net_device *dev);
 int tms380tr_close(struct net_device *dev);
 irqreturn_t tms380tr_interrupt(int irq, void *dev_id);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tokenring/tmspci.c linux-libre-2.6.30-gnu1/drivers/net/tokenring/tmspci.c
--- linux-libre-2.6.29-gnu1/drivers/net/tokenring/tmspci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tokenring/tmspci.c	2009-06-09 23:05:27.000000000 -0400
@@ -152,13 +152,13 @@ static int __devinit tms_pci_attach(stru
 
 	tp->tmspriv = cardinfo;
 
+	dev->netdev_ops = &tms380tr_netdev_ops;
+
 	ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
 			  dev->name, dev);
 	if (ret)
 		goto err_out_tmsdev;
 
-	dev->open = tms380tr_open;
-	dev->stop = tms380tr_close;
 	pci_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tsi108_eth.c linux-libre-2.6.30-gnu1/drivers/net/tsi108_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/tsi108_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tsi108_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -888,7 +888,7 @@ static int tsi108_poll(struct napi_struc
 
 	if (num_received < budget) {
 		data->rxpending = 0;
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		TSI_WRITE(TSI108_EC_INTMASK,
 				     TSI_READ(TSI108_EC_INTMASK)
@@ -915,11 +915,11 @@ static void tsi108_rx_int(struct net_dev
 	 *
 	 * This can happen if this code races with tsi108_poll(), which masks
 	 * the interrupts after tsi108_irq_one() read the mask, but before
-	 * netif_rx_schedule is called.  It could also happen due to calls
+	 * napi_schedule is called.  It could also happen due to calls
 	 * from tsi108_check_rxring().
 	 */
 
-	if (netif_rx_schedule_prep(&data->napi)) {
+	if (napi_schedule_prep(&data->napi)) {
 		/* Mask, rather than ack, the receive interrupts.  The ack
 		 * will happen in tsi108_poll().
 		 */
@@ -930,7 +930,7 @@ static void tsi108_rx_int(struct net_dev
 				     | TSI108_INT_RXTHRESH |
 				     TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR |
 				     TSI108_INT_RXWAIT);
-		__netif_rx_schedule(&data->napi);
+		__napi_schedule(&data->napi);
 	} else {
 		if (!netif_running(dev)) {
 			/* This can happen if an interrupt occurs while the
@@ -1561,6 +1561,18 @@ static const struct ethtool_ops tsi108_e
 	.set_settings	= tsi108_set_settings,
 };
 
+static const struct net_device_ops tsi108_netdev_ops = {
+	.ndo_open		= tsi108_open,
+	.ndo_stop		= tsi108_close,
+	.ndo_start_xmit		= tsi108_send_packet,
+	.ndo_set_multicast_list	= tsi108_set_rx_mode,
+	.ndo_get_stats		= tsi108_get_stats,
+	.ndo_do_ioctl		= tsi108_do_ioctl,
+	.ndo_set_mac_address	= tsi108_set_mac,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
 static int
 tsi108_init_one(struct platform_device *pdev)
 {
@@ -1616,14 +1628,8 @@ tsi108_init_one(struct platform_device *
 	data->phy_type = einfo->phy_type;
 	data->irq_num = einfo->irq_num;
 	data->id = pdev->id;
-	dev->open = tsi108_open;
-	dev->stop = tsi108_close;
-	dev->hard_start_xmit = tsi108_send_packet;
-	dev->set_mac_address = tsi108_set_mac;
-	dev->set_multicast_list = tsi108_set_rx_mode;
-	dev->get_stats = tsi108_get_stats;
 	netif_napi_add(dev, &data->napi, tsi108_poll, 64);
-	dev->do_ioctl = tsi108_do_ioctl;
+	dev->netdev_ops = &tsi108_netdev_ops;
 	dev->ethtool_ops = &tsi108_ethtool_ops;
 
 	/* Apparently, the Linux networking code won't use scatter-gather
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/de4x5.c linux-libre-2.6.30-gnu1/drivers/net/tulip/de4x5.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/de4x5.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/de4x5.c	2009-06-09 23:05:27.000000000 -0400
@@ -479,7 +479,8 @@
 
 #include "de4x5.h"
 
-static char version[] __devinitdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+static const char version[] __devinitconst =
+	KERN_INFO "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
 
 #define c_char const char
 
@@ -3941,8 +3942,8 @@ PCI_signature(char *name, struct de4x5_p
 	strcpy(name, "DE434/5");
 	return status;
     } else {                           /* Search for a DEC name in the SROM */
-	int i = *((char *)&lp->srom + 19) * 3;
-	strncpy(name, (char *)&lp->srom + 26 + i, 8);
+	int tmp = *((char *)&lp->srom + 19) * 3;
+	strncpy(name, (char *)&lp->srom + 26 + tmp, 8);
     }
     name[8] = '\0';
     for (i=0; i<siglen; i++) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/dmfe.c linux-libre-2.6.30-gnu1/drivers/net/tulip/dmfe.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/dmfe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/dmfe.c	2009-06-09 23:05:27.000000000 -0400
@@ -288,7 +288,7 @@ enum dmfe_CR6_bits {
 
 /* Global variable declaration ----------------------------- */
 static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
 	KERN_INFO DRV_NAME ": Davicom DM9xxx net driver, version "
 	DRV_VERSION " (" DRV_RELDATE ")\n";
 
@@ -383,7 +383,7 @@ static int __devinit dmfe_init_one (stru
 		return -ENOMEM;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING DRV_NAME
 			": 32-bit PCI DMA not available.\n");
 		err = -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/interrupt.c linux-libre-2.6.30-gnu1/drivers/net/tulip/interrupt.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/interrupt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/interrupt.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ void oom_timer(unsigned long data)
 {
         struct net_device *dev = (struct net_device *)data;
 	struct tulip_private *tp = netdev_priv(dev);
-	netif_rx_schedule(&tp->napi);
+	napi_schedule(&tp->napi);
 }
 
 int tulip_poll(struct napi_struct *napi, int budget)
@@ -140,6 +140,7 @@ int tulip_poll(struct napi_struct *napi,
                /* If we own the next entry, it is a new packet. Send it up. */
                while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
                        s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+		       short pkt_len;
 
                        if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
                                break;
@@ -151,8 +152,28 @@ int tulip_poll(struct napi_struct *napi,
 		       if (++work_done >= budget)
                                goto not_done;
 
-                       if ((status & 0x38008300) != 0x0300) {
-                               if ((status & 0x38000300) != 0x0300) {
+		       /*
+			* Omit the four octet CRC from the length.
+			* (May not be considered valid until we have
+			* checked status for RxLengthOver2047 bits)
+			*/
+		       pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+		       /*
+			* Maximum pkt_len is 1518 (1514 + vlan header)
+			* Anything higher than this is always invalid
+			* regardless of RxLengthOver2047 bits
+			*/
+
+		       if ((status & (RxLengthOver2047 |
+				      RxDescCRCError |
+				      RxDescCollisionSeen |
+				      RxDescRunt |
+				      RxDescDescErr |
+				      RxWholePkt)) != RxWholePkt
+			   || pkt_len > 1518) {
+			       if ((status & (RxLengthOver2047 |
+					      RxWholePkt)) != RxWholePkt) {
                                 /* Ingore earlier buffers. */
                                        if ((status & 0xffff) != 0x7fff) {
                                                if (tulip_debug > 1)
@@ -161,30 +182,23 @@ int tulip_poll(struct napi_struct *napi,
                                                               dev->name, status);
                                                tp->stats.rx_length_errors++;
                                        }
-                               } else if (status & RxDescFatalErr) {
+			       } else {
                                 /* There was a fatal error. */
                                        if (tulip_debug > 2)
                                                printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
                                                       dev->name, status);
                                        tp->stats.rx_errors++; /* end of a packet.*/
-                                       if (status & 0x0890) tp->stats.rx_length_errors++;
+				       if (pkt_len > 1518 ||
+					   (status & RxDescRunt))
+					       tp->stats.rx_length_errors++;
+
                                        if (status & 0x0004) tp->stats.rx_frame_errors++;
                                        if (status & 0x0002) tp->stats.rx_crc_errors++;
                                        if (status & 0x0001) tp->stats.rx_fifo_errors++;
                                }
                        } else {
-                               /* Omit the four octet CRC from the length. */
-                               short pkt_len = ((status >> 16) & 0x7ff) - 4;
                                struct sk_buff *skb;
 
-#ifndef final_version
-                               if (pkt_len > 1518) {
-                                       printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-                                              dev->name, pkt_len, pkt_len);
-                                       pkt_len = 1518;
-                                       tp->stats.rx_length_errors++;
-                               }
-#endif
                                /* Check if the packet is long enough to accept without copying
                                   to a minimally-sized skbuff. */
                                if (pkt_len < tulip_rx_copybreak
@@ -300,7 +314,7 @@ int tulip_poll(struct napi_struct *napi,
 
          /* Remove us from polling list and enable RX intr. */
 
-         netif_rx_complete(napi);
+         napi_complete(napi);
          iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
 
          /* The last op happens after poll completion. Which means the following:
@@ -333,10 +347,10 @@ int tulip_poll(struct napi_struct *napi,
 
          /* Think: timer_pending() was an explicit signature of bug.
           * Timer can be pending now but fired and completed
-          * before we did netif_rx_complete(). See? We would lose it. */
+          * before we did napi_complete(). See? We would lose it. */
 
          /* remove ourselves from the polling list */
-         netif_rx_complete(napi);
+         napi_complete(napi);
 
          return work_done;
 }
@@ -356,14 +370,35 @@ static int tulip_rx(struct net_device *d
 	/* If we own the next entry, it is a new packet. Send it up. */
 	while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
 		s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+		short pkt_len;
 
 		if (tulip_debug > 5)
 			printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
 				   dev->name, entry, status);
 		if (--rx_work_limit < 0)
 			break;
-		if ((status & 0x38008300) != 0x0300) {
-			if ((status & 0x38000300) != 0x0300) {
+
+		/*
+		  Omit the four octet CRC from the length.
+		  (May not be considered valid until we have
+		  checked status for RxLengthOver2047 bits)
+		*/
+		pkt_len = ((status >> 16) & 0x7ff) - 4;
+		/*
+		  Maximum pkt_len is 1518 (1514 + vlan header)
+		  Anything higher than this is always invalid
+		  regardless of RxLengthOver2047 bits
+		*/
+
+		if ((status & (RxLengthOver2047 |
+			       RxDescCRCError |
+			       RxDescCollisionSeen |
+			       RxDescRunt |
+			       RxDescDescErr |
+			       RxWholePkt))        != RxWholePkt
+		     || pkt_len > 1518) {
+			if ((status & (RxLengthOver2047 |
+			     RxWholePkt))         != RxWholePkt) {
 				/* Ingore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
 					if (tulip_debug > 1)
@@ -372,31 +407,22 @@ static int tulip_rx(struct net_device *d
 							   dev->name, status);
 					tp->stats.rx_length_errors++;
 				}
-			} else if (status & RxDescFatalErr) {
+			} else {
 				/* There was a fatal error. */
 				if (tulip_debug > 2)
 					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
 						   dev->name, status);
 				tp->stats.rx_errors++; /* end of a packet.*/
-				if (status & 0x0890) tp->stats.rx_length_errors++;
+				if (pkt_len > 1518 ||
+				    (status & RxDescRunt))
+					tp->stats.rx_length_errors++;
 				if (status & 0x0004) tp->stats.rx_frame_errors++;
 				if (status & 0x0002) tp->stats.rx_crc_errors++;
 				if (status & 0x0001) tp->stats.rx_fifo_errors++;
 			}
 		} else {
-			/* Omit the four octet CRC from the length. */
-			short pkt_len = ((status >> 16) & 0x7ff) - 4;
 			struct sk_buff *skb;
 
-#ifndef final_version
-			if (pkt_len > 1518) {
-				printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
-					   dev->name, pkt_len, pkt_len);
-				pkt_len = 1518;
-				tp->stats.rx_length_errors++;
-			}
-#endif
-
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < tulip_rx_copybreak
@@ -519,7 +545,7 @@ irqreturn_t tulip_interrupt(int irq, voi
 			rxd++;
 			/* Mask RX intrs and add the device to poll list. */
 			iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
-			netif_rx_schedule(&tp->napi);
+			napi_schedule(&tp->napi);
 
 			if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
                                break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/media.c linux-libre-2.6.30-gnu1/drivers/net/tulip/media.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/media.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/media.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,11 +69,10 @@ int tulip_mdio_read(struct net_device *d
 
 	spin_lock_irqsave(&tp->mii_lock, flags);
 	if (tp->chip_id == LC82C168) {
-		int i = 1000;
 		iowrite32(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
 		ioread32(ioaddr + 0xA0);
 		ioread32(ioaddr + 0xA0);
-		while (--i > 0) {
+		for (i = 1000; i >= 0; --i) {
 			barrier();
 			if ( ! ((retval = ioread32(ioaddr + 0xA0)) & 0x80000000))
 				break;
@@ -131,13 +130,12 @@ void tulip_mdio_write(struct net_device
 
 	spin_lock_irqsave(&tp->mii_lock, flags);
 	if (tp->chip_id == LC82C168) {
-		int i = 1000;
 		iowrite32(cmd, ioaddr + 0xA0);
-		do {
+		for (i = 1000; i >= 0; --i) {
 			barrier();
 			if ( ! (ioread32(ioaddr + 0xA0) & 0x80000000))
 				break;
-		} while (--i > 0);
+		}
 		spin_unlock_irqrestore(&tp->mii_lock, flags);
 		return;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/tulip.h linux-libre-2.6.30-gnu1/drivers/net/tulip/tulip.h
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/tulip.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/tulip.h	2009-06-09 23:05:27.000000000 -0400
@@ -201,8 +201,38 @@ enum desc_status_bits {
 	DescStartPkt = 0x20000000,
 	DescEndRing  = 0x02000000,
 	DescUseLink  = 0x01000000,
-	RxDescFatalErr = 0x008000,
+
+	/*
+	 * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
+	 * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
+	 * within tulip chip.
+	 */
+	RxDescErrorSummary = 0x8000,
+	RxDescCRCError = 0x0002,
+	RxDescCollisionSeen = 0x0040,
+
+	/*
+	 * 'Frame Too Long' flag is set if packet length including CRC exceeds
+	 * 1518.  However, a full sized VLAN tagged frame is 1522 bytes
+	 * including CRC.
+	 *
+	 * The tulip chip does not block oversized frames, and if this flag is
+	 * set on a receive descriptor it does not indicate the frame has been
+	 * truncated.  The receive descriptor also includes the actual length.
+	 * Therefore we can safety ignore this flag and check the length
+	 * ourselves.
+	 */
+	RxDescFrameTooLong = 0x0080,
+	RxDescRunt = 0x0800,
+	RxDescDescErr = 0x4000,
 	RxWholePkt   = 0x00000300,
+	/*
+	 * Top three bits of 14 bit frame length (status bits 27-29) should
+	 * never be set as that would make frame over 2047 bytes. The Receive
+	 * Watchdog flag (bit 4) may indicate the length is over 2048 and the
+	 * length field is invalid.
+	 */
+	RxLengthOver2047 = 0x38000010
 };
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/uli526x.c linux-libre-2.6.30-gnu1/drivers/net/tulip/uli526x.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/uli526x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/uli526x.c	2009-06-09 23:05:27.000000000 -0400
@@ -200,7 +200,7 @@ enum uli526x_CR6_bits {
 
 /* Global variable declaration ----------------------------- */
 static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
 	KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
 	DRV_VERSION " (" DRV_RELDATE ")\n";
 
@@ -282,7 +282,7 @@ static int __devinit uli526x_init_one (s
 		return -ENOMEM;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n");
 		err = -ENODEV;
 		goto err_out_free;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tulip/winbond-840.c linux-libre-2.6.30-gnu1/drivers/net/tulip/winbond-840.c
--- linux-libre-2.6.29-gnu1/drivers/net/tulip/winbond-840.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tulip/winbond-840.c	2009-06-09 23:05:27.000000000 -0400
@@ -139,9 +139,10 @@ static int full_duplex[MAX_UNITS] = {-1,
 #define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer.*/
 
 /* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE "  Donald Becker <becker@scyld.com>\n"
-KERN_INFO "  http://www.scyld.com/network/drivers.html\n";
+static const char version[] __initconst =
+	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
+	DRV_RELDATE "  Donald Becker <becker@scyld.com>\n"
+	KERN_INFO "  http://www.scyld.com/network/drivers.html\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
@@ -374,7 +375,7 @@ static int __devinit w840_probe1 (struct
 
 	irq = pdev->irq;
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_WARNING "Winbond-840: Device %s disabled due to DMA limitations.\n",
 		       pci_name(pdev));
 		return -EIO;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/tun.c linux-libre-2.6.30-gnu1/drivers/net/tun.c
--- linux-libre-2.6.29-gnu1/drivers/net/tun.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/tun.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,6 +63,8 @@
 #include <linux/virtio_net.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -87,26 +89,124 @@ struct tap_filter {
 	unsigned char	addr[FLT_EXACT_COUNT][ETH_ALEN];
 };
 
+struct tun_file {
+	atomic_t count;
+	struct tun_struct *tun;
+	struct net *net;
+};
+
+struct tun_sock;
+
 struct tun_struct {
-	struct list_head        list;
+	struct tun_file		*tfile;
 	unsigned int 		flags;
-	int			attached;
 	uid_t			owner;
 	gid_t			group;
 
-	wait_queue_head_t	read_wait;
 	struct sk_buff_head	readq;
 
 	struct net_device	*dev;
 	struct fasync_struct	*fasync;
 
 	struct tap_filter       txflt;
+	struct sock		*sk;
+	struct socket		socket;
 
 #ifdef TUN_DEBUG
 	int debug;
 #endif
 };
 
+struct tun_sock {
+	struct sock		sk;
+	struct tun_struct	*tun;
+};
+
+static inline struct tun_sock *tun_sk(struct sock *sk)
+{
+	return container_of(sk, struct tun_sock, sk);
+}
+
+static int tun_attach(struct tun_struct *tun, struct file *file)
+{
+	struct tun_file *tfile = file->private_data;
+	const struct cred *cred = current_cred();
+	int err;
+
+	ASSERT_RTNL();
+
+	/* Check permissions */
+	if (((tun->owner != -1 && cred->euid != tun->owner) ||
+	     (tun->group != -1 && !in_egroup_p(tun->group))) &&
+		!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	netif_tx_lock_bh(tun->dev);
+
+	err = -EINVAL;
+	if (tfile->tun)
+		goto out;
+
+	err = -EBUSY;
+	if (tun->tfile)
+		goto out;
+
+	err = 0;
+	tfile->tun = tun;
+	tun->tfile = tfile;
+	dev_hold(tun->dev);
+	sock_hold(tun->sk);
+	atomic_inc(&tfile->count);
+
+out:
+	netif_tx_unlock_bh(tun->dev);
+	return err;
+}
+
+static void __tun_detach(struct tun_struct *tun)
+{
+	/* Detach from net device */
+	netif_tx_lock_bh(tun->dev);
+	tun->tfile = NULL;
+	netif_tx_unlock_bh(tun->dev);
+
+	/* Drop read queue */
+	skb_queue_purge(&tun->readq);
+
+	/* Drop the extra count on the net device */
+	dev_put(tun->dev);
+}
+
+static void tun_detach(struct tun_struct *tun)
+{
+	rtnl_lock();
+	__tun_detach(tun);
+	rtnl_unlock();
+}
+
+static struct tun_struct *__tun_get(struct tun_file *tfile)
+{
+	struct tun_struct *tun = NULL;
+
+	if (atomic_inc_not_zero(&tfile->count))
+		tun = tfile->tun;
+
+	return tun;
+}
+
+static struct tun_struct *tun_get(struct file *file)
+{
+	return __tun_get(file->private_data);
+}
+
+static void tun_put(struct tun_struct *tun)
+{
+	struct tun_file *tfile = tun->tfile;
+
+	if (atomic_dec_and_test(&tfile->count))
+		tun_detach(tfile->tun);
+}
+
 /* TAP filterting */
 static void addr_hash_set(u32 *mask, const u8 *addr)
 {
@@ -219,13 +319,30 @@ static int check_filter(struct tap_filte
 
 /* Network device part of the driver */
 
-static int tun_net_id;
-struct tun_net {
-	struct list_head dev_list;
-};
-
 static const struct ethtool_ops tun_ethtool_ops;
 
+/* Net device detach from fd. */
+static void tun_net_uninit(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	struct tun_file *tfile = tun->tfile;
+
+	/* Inform the methods they need to stop using the dev.
+	 */
+	if (tfile) {
+		wake_up_all(&tun->socket.wait);
+		if (atomic_dec_and_test(&tfile->count))
+			__tun_detach(tun);
+	}
+}
+
+static void tun_free_netdev(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	sock_put(tun->sk);
+}
+
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
 {
@@ -248,7 +365,7 @@ static int tun_net_xmit(struct sk_buff *
 	DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
 
 	/* Drop packet if interface is not attached */
-	if (!tun->attached)
+	if (!tun->tfile)
 		goto drop;
 
 	/* Drop if the filter does not like it.
@@ -280,7 +397,7 @@ static int tun_net_xmit(struct sk_buff *
 	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
 		kill_fasync(&tun->fasync, SIGIO, POLL_IN);
-	wake_up_interruptible(&tun->read_wait);
+	wake_up_interruptible(&tun->socket.wait);
 	return 0;
 
 drop:
@@ -312,6 +429,7 @@ tun_net_change_mtu(struct net_device *de
 }
 
 static const struct net_device_ops tun_netdev_ops = {
+	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
@@ -319,6 +437,7 @@ static const struct net_device_ops tun_n
 };
 
 static const struct net_device_ops tap_netdev_ops = {
+	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
@@ -365,86 +484,66 @@ static void tun_net_init(struct net_devi
 /* Poll */
 static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
 {
-	struct tun_struct *tun = file->private_data;
-	unsigned int mask = POLLOUT | POLLWRNORM;
+	struct tun_file *tfile = file->private_data;
+	struct tun_struct *tun = __tun_get(tfile);
+	struct sock *sk = tun->sk;
+	unsigned int mask = 0;
 
 	if (!tun)
-		return -EBADFD;
+		return POLLERR;
 
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
 
-	poll_wait(file, &tun->read_wait, wait);
+	poll_wait(file, &tun->socket.wait, wait);
 
 	if (!skb_queue_empty(&tun->readq))
 		mask |= POLLIN | POLLRDNORM;
 
+	if (sock_writeable(sk) ||
+	    (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+	     sock_writeable(sk)))
+		mask |= POLLOUT | POLLWRNORM;
+
+	if (tun->dev->reg_state != NETREG_REGISTERED)
+		mask = POLLERR;
+
+	tun_put(tun);
 	return mask;
 }
 
 /* prepad is the amount to reserve at front.  len is length after that.
  * linear is a hint as to how much to copy (usually headers). */
-static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
-				     gfp_t gfp)
+static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
+					    size_t prepad, size_t len,
+					    size_t linear, int noblock)
 {
+	struct sock *sk = tun->sk;
 	struct sk_buff *skb;
-	unsigned int i;
-
-	skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
-	if (skb) {
-		skb_reserve(skb, prepad);
-		skb_put(skb, len);
-		return skb;
-	}
+	int err;
 
 	/* Under a page?  Don't bother with paged skb. */
-	if (prepad + len < PAGE_SIZE)
-		return NULL;
+	if (prepad + len < PAGE_SIZE || !linear)
+		linear = len;
 
-	/* Start with a normal skb, and add pages. */
-	skb = alloc_skb(prepad + linear, gfp);
+	skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
+				   &err);
 	if (!skb)
-		return NULL;
+		return ERR_PTR(err);
 
 	skb_reserve(skb, prepad);
 	skb_put(skb, linear);
-
-	len -= linear;
-
-	for (i = 0; i < MAX_SKB_FRAGS; i++) {
-		skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-
-		f->page = alloc_page(gfp|__GFP_ZERO);
-		if (!f->page)
-			break;
-
-		f->page_offset = 0;
-		f->size = PAGE_SIZE;
-
-		skb->data_len += PAGE_SIZE;
-		skb->len += PAGE_SIZE;
-		skb->truesize += PAGE_SIZE;
-		skb_shinfo(skb)->nr_frags++;
-
-		if (len < PAGE_SIZE) {
-			len = 0;
-			break;
-		}
-		len -= PAGE_SIZE;
-	}
-
-	/* Too large, or alloc fail? */
-	if (unlikely(len)) {
-		kfree_skb(skb);
-		skb = NULL;
-	}
+	skb->data_len = len - linear;
+	skb->len += len - linear;
 
 	return skb;
 }
 
 /* Get packet from user space buffer */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
+				       struct iovec *iv, size_t count,
+				       int noblock)
 {
-	struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
+	struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
 	struct sk_buff *skb;
 	size_t len = count, align = 0;
 	struct virtio_net_hdr gso = { 0 };
@@ -470,13 +569,16 @@ static __inline__ ssize_t tun_get_user(s
 
 	if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
 		align = NET_IP_ALIGN;
-		if (unlikely(len < ETH_HLEN))
+		if (unlikely(len < ETH_HLEN ||
+			     (gso.hdr_len && gso.hdr_len < ETH_HLEN)))
 			return -EINVAL;
 	}
 
-	if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
-		tun->dev->stats.rx_dropped++;
-		return -ENOMEM;
+	skb = tun_alloc_skb(tun, align, len, gso.hdr_len, noblock);
+	if (IS_ERR(skb)) {
+		if (PTR_ERR(skb) != -EAGAIN)
+			tun->dev->stats.rx_dropped++;
+		return PTR_ERR(skb);
 	}
 
 	if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
@@ -562,14 +664,20 @@ static __inline__ ssize_t tun_get_user(s
 static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 			      unsigned long count, loff_t pos)
 {
-	struct tun_struct *tun = iocb->ki_filp->private_data;
+	struct file *file = iocb->ki_filp;
+	struct tun_struct *tun = tun_get(file);
+	ssize_t result;
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
 
-	return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
+	result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+			      file->f_flags & O_NONBLOCK);
+
+	tun_put(tun);
+	return result;
 }
 
 /* Put packet to the user space buffer */
@@ -642,7 +750,8 @@ static ssize_t tun_chr_aio_read(struct k
 			    unsigned long count, loff_t pos)
 {
 	struct file *file = iocb->ki_filp;
-	struct tun_struct *tun = file->private_data;
+	struct tun_file *tfile = file->private_data;
+	struct tun_struct *tun = __tun_get(tfile);
 	DECLARE_WAITQUEUE(wait, current);
 	struct sk_buff *skb;
 	ssize_t len, ret = 0;
@@ -653,10 +762,12 @@ static ssize_t tun_chr_aio_read(struct k
 	DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
 
 	len = iov_length(iv, count);
-	if (len < 0)
-		return -EINVAL;
+	if (len < 0) {
+		ret = -EINVAL;
+		goto out;
+	}
 
-	add_wait_queue(&tun->read_wait, &wait);
+	add_wait_queue(&tun->socket.wait, &wait);
 	while (len) {
 		current->state = TASK_INTERRUPTIBLE;
 
@@ -670,6 +781,10 @@ static ssize_t tun_chr_aio_read(struct k
 				ret = -ERESTARTSYS;
 				break;
 			}
+			if (tun->dev->reg_state != NETREG_REGISTERED) {
+				ret = -EIO;
+				break;
+			}
 
 			/* Nothing to read, let's sleep */
 			schedule();
@@ -683,8 +798,10 @@ static ssize_t tun_chr_aio_read(struct k
 	}
 
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&tun->read_wait, &wait);
+	remove_wait_queue(&tun->socket.wait, &wait);
 
+out:
+	tun_put(tun);
 	return ret;
 }
 
@@ -693,54 +810,77 @@ static void tun_setup(struct net_device
 	struct tun_struct *tun = netdev_priv(dev);
 
 	skb_queue_head_init(&tun->readq);
-	init_waitqueue_head(&tun->read_wait);
 
 	tun->owner = -1;
 	tun->group = -1;
 
 	dev->ethtool_ops = &tun_ethtool_ops;
-	dev->destructor = free_netdev;
-	dev->features |= NETIF_F_NETNS_LOCAL;
+	dev->destructor = tun_free_netdev;
 }
 
-static struct tun_struct *tun_get_by_name(struct tun_net *tn, const char *name)
+/* Trivial set of netlink ops to allow deleting tun or tap
+ * device with netlink.
+ */
+static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	return -EINVAL;
+}
+
+static struct rtnl_link_ops tun_link_ops __read_mostly = {
+	.kind		= DRV_NAME,
+	.priv_size	= sizeof(struct tun_struct),
+	.setup		= tun_setup,
+	.validate	= tun_validate,
+};
+
+static void tun_sock_write_space(struct sock *sk)
 {
 	struct tun_struct *tun;
 
-	ASSERT_RTNL();
-	list_for_each_entry(tun, &tn->dev_list, list) {
-		if (!strncmp(tun->dev->name, name, IFNAMSIZ))
-		    return tun;
-	}
+	if (!sock_writeable(sk))
+		return;
 
-	return NULL;
+	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+		wake_up_interruptible_sync(sk->sk_sleep);
+
+	if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+		return;
+
+	tun = container_of(sk, struct tun_sock, 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);
 }
 
+static struct proto tun_proto = {
+	.name		= "tun",
+	.owner		= THIS_MODULE,
+	.obj_size	= sizeof(struct tun_sock),
+};
+
 static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 {
-	struct tun_net *tn;
+	struct sock *sk;
 	struct tun_struct *tun;
 	struct net_device *dev;
-	const struct cred *cred = current_cred();
 	int err;
 
-	tn = net_generic(net, tun_net_id);
-	tun = tun_get_by_name(tn, ifr->ifr_name);
-	if (tun) {
-		if (tun->attached)
-			return -EBUSY;
+	dev = __dev_get_by_name(net, ifr->ifr_name);
+	if (dev) {
+		if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
+			tun = netdev_priv(dev);
+		else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
+			tun = netdev_priv(dev);
+		else
+			return -EINVAL;
 
-		/* Check permissions */
-		if (((tun->owner != -1 &&
-		      cred->euid != tun->owner) ||
-		     (tun->group != -1 &&
-		      cred->egid != tun->group)) &&
-		    !capable(CAP_NET_ADMIN)) {
-			return -EPERM;
-		}
+		err = tun_attach(tun, file);
+		if (err < 0)
+			return err;
 	}
-	else if (__dev_get_by_name(net, ifr->ifr_name))
-		return -EINVAL;
 	else {
 		char *name;
 		unsigned long flags = 0;
@@ -771,25 +911,44 @@ static int tun_set_iff(struct net *net,
 			return -ENOMEM;
 
 		dev_net_set(dev, net);
+		dev->rtnl_link_ops = &tun_link_ops;
 
 		tun = netdev_priv(dev);
 		tun->dev = dev;
 		tun->flags = flags;
 		tun->txflt.count = 0;
 
+		err = -ENOMEM;
+		sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
+		if (!sk)
+			goto err_free_dev;
+
+		init_waitqueue_head(&tun->socket.wait);
+		sock_init_data(&tun->socket, sk);
+		sk->sk_write_space = tun_sock_write_space;
+		sk->sk_sndbuf = INT_MAX;
+
+		tun->sk = sk;
+		container_of(sk, struct tun_sock, sk)->tun = tun;
+
 		tun_net_init(dev);
 
 		if (strchr(dev->name, '%')) {
 			err = dev_alloc_name(dev, dev->name);
 			if (err < 0)
-				goto err_free_dev;
+				goto err_free_sk;
 		}
 
+		err = -EINVAL;
 		err = register_netdevice(tun->dev);
 		if (err < 0)
-			goto err_free_dev;
+			goto err_free_sk;
 
-		list_add(&tun->list, &tn->dev_list);
+		sk->sk_destruct = tun_sock_destruct;
+
+		err = tun_attach(tun, file);
+		if (err < 0)
+			goto failed;
 	}
 
 	DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -809,10 +968,6 @@ static int tun_set_iff(struct net *net,
 	else
 		tun->flags &= ~TUN_VNET_HDR;
 
-	file->private_data = tun;
-	tun->attached = 1;
-	get_net(dev_net(tun->dev));
-
 	/* Make sure persistent devices do not get stuck in
 	 * xoff state.
 	 */
@@ -822,6 +977,8 @@ static int tun_set_iff(struct net *net,
 	strcpy(ifr->ifr_name, tun->dev->name);
 	return 0;
 
+ err_free_sk:
+	sock_put(sk);
  err_free_dev:
 	free_netdev(dev);
  failed:
@@ -830,7 +987,7 @@ static int tun_set_iff(struct net *net,
 
 static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
 {
-	struct tun_struct *tun = file->private_data;
+	struct tun_struct *tun = tun_get(file);
 
 	if (!tun)
 		return -EBADFD;
@@ -855,6 +1012,7 @@ static int tun_get_iff(struct net *net,
 	if (tun->flags & TUN_VNET_HDR)
 		ifr->ifr_flags |= IFF_VNET_HDR;
 
+	tun_put(tun);
 	return 0;
 }
 
@@ -901,22 +1059,34 @@ static int set_offload(struct net_device
 static int tun_chr_ioctl(struct inode *inode, struct file *file,
 			 unsigned int cmd, unsigned long arg)
 {
-	struct tun_struct *tun = file->private_data;
+	struct tun_file *tfile = file->private_data;
+	struct tun_struct *tun;
 	void __user* argp = (void __user*)arg;
 	struct ifreq ifr;
+	int sndbuf;
 	int ret;
 
 	if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
 		if (copy_from_user(&ifr, argp, sizeof ifr))
 			return -EFAULT;
 
+	if (cmd == TUNGETFEATURES) {
+		/* Currently this just means: "what IFF flags are valid?".
+		 * This is needed because we never checked for invalid flags on
+		 * TUNSETIFF. */
+		return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
+				IFF_VNET_HDR,
+				(unsigned int __user*)argp);
+	}
+
+	tun = __tun_get(tfile);
 	if (cmd == TUNSETIFF && !tun) {
 		int err;
 
 		ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
 		rtnl_lock();
-		err = tun_set_iff(current->nsproxy->net_ns, file, &ifr);
+		err = tun_set_iff(tfile->net, file, &ifr);
 		rtnl_unlock();
 
 		if (err)
@@ -927,28 +1097,21 @@ static int tun_chr_ioctl(struct inode *i
 		return 0;
 	}
 
-	if (cmd == TUNGETFEATURES) {
-		/* Currently this just means: "what IFF flags are valid?".
-		 * This is needed because we never checked for invalid flags on
-		 * TUNSETIFF. */
-		return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
-				IFF_VNET_HDR,
-				(unsigned int __user*)argp);
-	}
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
 
+	ret = 0;
 	switch (cmd) {
 	case TUNGETIFF:
 		ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
 		if (ret)
-			return ret;
+			break;
 
 		if (copy_to_user(argp, &ifr, sizeof(ifr)))
-			return -EFAULT;
+			ret = -EFAULT;
 		break;
 
 	case TUNSETNOCSUM:
@@ -1000,7 +1163,7 @@ static int tun_chr_ioctl(struct inode *i
 			ret = 0;
 		}
 		rtnl_unlock();
-		return ret;
+		break;
 
 #ifdef TUN_DEBUG
 	case TUNSETDEBUG:
@@ -1011,24 +1174,25 @@ static int tun_chr_ioctl(struct inode *i
 		rtnl_lock();
 		ret = set_offload(tun->dev, arg);
 		rtnl_unlock();
-		return ret;
+		break;
 
 	case TUNSETTXFILTER:
 		/* Can be set only for TAPs */
+		ret = -EINVAL;
 		if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
-			return -EINVAL;
+			break;
 		rtnl_lock();
 		ret = update_filter(&tun->txflt, (void __user *)arg);
 		rtnl_unlock();
-		return ret;
+		break;
 
 	case SIOCGIFHWADDR:
 		/* 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))
-			return -EFAULT;
-		return 0;
+			ret = -EFAULT;
+		break;
 
 	case SIOCSIFHWADDR:
 		/* Set hw address */
@@ -1038,18 +1202,35 @@ static int tun_chr_ioctl(struct inode *i
 		rtnl_lock();
 		ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
 		rtnl_unlock();
-		return ret;
+		break;
+
+	case TUNGETSNDBUF:
+		sndbuf = tun->sk->sk_sndbuf;
+		if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
+			ret = -EFAULT;
+		break;
+
+	case TUNSETSNDBUF:
+		if (copy_from_user(&sndbuf, argp, sizeof(sndbuf))) {
+			ret = -EFAULT;
+			break;
+		}
+
+		tun->sk->sk_sndbuf = sndbuf;
+		break;
 
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		break;
 	};
 
-	return 0;
+	tun_put(tun);
+	return ret;
 }
 
 static int tun_chr_fasync(int fd, struct file *file, int on)
 {
-	struct tun_struct *tun = file->private_data;
+	struct tun_struct *tun = tun_get(file);
 	int ret;
 
 	if (!tun)
@@ -1071,42 +1252,51 @@ static int tun_chr_fasync(int fd, struct
 	ret = 0;
 out:
 	unlock_kernel();
+	tun_put(tun);
 	return ret;
 }
 
 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");
-	file->private_data = NULL;
+
+	tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
+	if (!tfile)
+		return -ENOMEM;
+	atomic_set(&tfile->count, 0);
+	tfile->tun = NULL;
+	tfile->net = get_net(current->nsproxy->net_ns);
+	file->private_data = tfile;
 	return 0;
 }
 
 static int tun_chr_close(struct inode *inode, struct file *file)
 {
-	struct tun_struct *tun = file->private_data;
-
-	if (!tun)
-		return 0;
+	struct tun_file *tfile = file->private_data;
+	struct tun_struct *tun = __tun_get(tfile);
 
-	DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
 
-	rtnl_lock();
+	if (tun) {
+		DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
 
-	/* Detach from net device */
-	file->private_data = NULL;
-	tun->attached = 0;
-	put_net(dev_net(tun->dev));
+		rtnl_lock();
+		__tun_detach(tun);
 
-	/* Drop read queue */
-	skb_queue_purge(&tun->readq);
+		/* If desireable, unregister the netdevice. */
+		if (!(tun->flags & TUN_PERSIST))
+			unregister_netdevice(tun->dev);
 
-	if (!(tun->flags & TUN_PERSIST)) {
-		list_del(&tun->list);
-		unregister_netdevice(tun->dev);
+		rtnl_unlock();
 	}
 
-	rtnl_unlock();
+	tun = tfile->tun;
+	if (tun)
+		sock_put(tun->sk);
+
+	put_net(tfile->net);
+	kfree(tfile);
 
 	return 0;
 }
@@ -1187,7 +1377,7 @@ static void tun_set_msglevel(struct net_
 static u32 tun_get_link(struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
-	return tun->attached;
+	return !!tun->tfile;
 }
 
 static u32 tun_get_rx_csum(struct net_device *dev)
@@ -1216,45 +1406,6 @@ static const struct ethtool_ops tun_etht
 	.set_rx_csum	= tun_set_rx_csum
 };
 
-static int tun_init_net(struct net *net)
-{
-	struct tun_net *tn;
-
-	tn = kmalloc(sizeof(*tn), GFP_KERNEL);
-	if (tn == NULL)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&tn->dev_list);
-
-	if (net_assign_generic(net, tun_net_id, tn)) {
-		kfree(tn);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void tun_exit_net(struct net *net)
-{
-	struct tun_net *tn;
-	struct tun_struct *tun, *nxt;
-
-	tn = net_generic(net, tun_net_id);
-
-	rtnl_lock();
-	list_for_each_entry_safe(tun, nxt, &tn->dev_list, list) {
-		DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
-		unregister_netdevice(tun->dev);
-	}
-	rtnl_unlock();
-
-	kfree(tn);
-}
-
-static struct pernet_operations tun_net_ops = {
-	.init = tun_init_net,
-	.exit = tun_exit_net,
-};
 
 static int __init tun_init(void)
 {
@@ -1263,10 +1414,10 @@ static int __init tun_init(void)
 	printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 	printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
 
-	ret = register_pernet_gen_device(&tun_net_id, &tun_net_ops);
+	ret = rtnl_link_register(&tun_link_ops);
 	if (ret) {
-		printk(KERN_ERR "tun: Can't register pernet ops\n");
-		goto err_pernet;
+		printk(KERN_ERR "tun: Can't register link_ops\n");
+		goto err_linkops;
 	}
 
 	ret = misc_register(&tun_miscdev);
@@ -1274,18 +1425,17 @@ static int __init tun_init(void)
 		printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
 		goto err_misc;
 	}
-	return 0;
-
+	return  0;
 err_misc:
-	unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
-err_pernet:
+	rtnl_link_unregister(&tun_link_ops);
+err_linkops:
 	return ret;
 }
 
 static void tun_cleanup(void)
 {
 	misc_deregister(&tun_miscdev);
-	unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
+	rtnl_link_unregister(&tun_link_ops);
 }
 
 module_init(tun_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/typhoon.c linux-libre-2.6.30-gnu1/drivers/net/typhoon.c
--- linux-libre-2.6.29-gnu1/drivers/net/typhoon.c	2013-05-03 18:03:33.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/typhoon.c	2013-05-03 16:47:24.000000000 -0400
@@ -100,10 +100,11 @@ static const int multicast_filter_limit
 #define PKT_BUF_SZ		1536
 
 #define DRV_MODULE_NAME		"typhoon"
-#define DRV_MODULE_VERSION 	"1.5.8"
-#define DRV_MODULE_RELDATE	"06/11/09"
+#define DRV_MODULE_VERSION 	"1.5.9"
+#define DRV_MODULE_RELDATE	"Mar 2, 2009"
 #define PFX			DRV_MODULE_NAME ": "
 #define ERR_PFX			KERN_ERR PFX
+#define FIRMWARE_NAME		"/*(DEBLOBBED)*/"
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -129,9 +130,9 @@ static const int multicast_filter_limit
 #include <asm/uaccess.h>
 #include <linux/in6.h>
 #include <linux/dma-mapping.h>
+#include <linux/firmware.h>
 
 #include "typhoon.h"
-#include "typhoon-firmware.h"
 
 static char version[] __devinitdata =
     "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -139,6 +140,7 @@ static char version[] __devinitdata =
 MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
 MODULE_VERSION(DRV_MODULE_VERSION);
 MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
 MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
 MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
 			       "the buffer given back to the NIC. Default "
@@ -1344,14 +1346,74 @@ typhoon_init_rings(struct typhoon *tp)
 	tp->txHiRing.lastRead = 0;
 }
 
+static const struct firmware *typhoon_fw;
+
+static int
+typhoon_reject_firmware(struct typhoon *tp)
+{
+	const struct typhoon_file_header *fHdr;
+	const struct typhoon_section_header *sHdr;
+	const u8 *image_data;
+	u32 numSections;
+	u32 section_len;
+	u32 remaining;
+	int err;
+
+	if (typhoon_fw)
+		return 0;
+
+	err = reject_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+				tp->name, FIRMWARE_NAME);
+		return err;
+	}
+
+	image_data = (u8 *) typhoon_fw->data;
+	remaining = typhoon_fw->size;
+	if (remaining < sizeof(struct typhoon_file_header))
+		goto invalid_fw;
+
+	fHdr = (struct typhoon_file_header *) image_data;
+	if (memcmp(fHdr->tag, "TYPHOON", 8))
+		goto invalid_fw;
+
+	numSections = le32_to_cpu(fHdr->numSections);
+	image_data += sizeof(struct typhoon_file_header);
+	remaining -= sizeof(struct typhoon_file_header);
+
+	while (numSections--) {
+		if (remaining < sizeof(struct typhoon_section_header))
+			goto invalid_fw;
+
+		sHdr = (struct typhoon_section_header *) image_data;
+		image_data += sizeof(struct typhoon_section_header);
+		section_len = le32_to_cpu(sHdr->len);
+
+		if (remaining < section_len)
+			goto invalid_fw;
+
+		image_data += section_len;
+		remaining -= section_len;
+	}
+
+	return 0;
+
+invalid_fw:
+	printk(KERN_ERR "%s: Invalid firmware image\n", tp->name);
+	release_firmware(typhoon_fw);
+	typhoon_fw = NULL;
+	return -EINVAL;
+}
+
 static int
 typhoon_download_firmware(struct typhoon *tp)
 {
 	void __iomem *ioaddr = tp->ioaddr;
 	struct pci_dev *pdev = tp->pdev;
-	struct typhoon_file_header *fHdr;
-	struct typhoon_section_header *sHdr;
-	u8 *image_data;
+	const struct typhoon_file_header *fHdr;
+	const struct typhoon_section_header *sHdr;
+	const u8 *image_data;
 	void *dpage;
 	dma_addr_t dpage_dma;
 	__sum16 csum;
@@ -1365,22 +1427,12 @@ typhoon_download_firmware(struct typhoon
 	int i;
 	int err;
 
-	err = -EINVAL;
-	printk(KERN_ERR "%s: Missing Free firmware\n", tp->name);
-	err = -EINVAL;
-	goto err_out;
-	image_data = (u8 *) fHdr;
-
-	if(memcmp(fHdr->tag, "TYPHOON", 8)) {
-		printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
-		goto err_out;
-	}
+	image_data = (u8 *) typhoon_fw->data;
+	fHdr = (struct typhoon_file_header *) image_data;
 
 	/* Cannot just map the firmware image using pci_map_single() as
-	 * the firmware is part of the kernel/module image, so we allocate
-	 * some consistent memory to copy the sections into, as it is simpler,
-	 * and short-lived. If we ever split out and require a userland
-	 * firmware loader, then we can revisit this.
+	 * the firmware is vmalloc()'d and may not be physically contiguous,
+	 * so we allocate some consistent memory to copy the sections into.
 	 */
 	err = -ENOMEM;
 	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
@@ -1785,7 +1837,7 @@ typhoon_poll(struct napi_struct *napi, i
 	}
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		iowrite32(TYPHOON_INTR_NONE,
 				tp->ioaddr + TYPHOON_REG_INTR_MASK);
 		typhoon_post_pci_writes(tp->ioaddr);
@@ -1808,10 +1860,10 @@ typhoon_interrupt(int irq, void *dev_ins
 
 	iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
 
-	if (netif_rx_schedule_prep(&tp->napi)) {
+	if (napi_schedule_prep(&tp->napi)) {
 		iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
 		typhoon_post_pci_writes(ioaddr);
-		__netif_rx_schedule(&tp->napi);
+		__napi_schedule(&tp->napi);
 	} else {
 		printk(KERN_ERR "%s: Error, poll already scheduled\n",
                        dev->name);
@@ -1946,7 +1998,7 @@ typhoon_start_runtime(struct typhoon *tp
 		goto error_out;
 
 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
-	xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q);
+	xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q);
 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
 	if(err < 0)
 		goto error_out;
@@ -2088,6 +2140,10 @@ typhoon_open(struct net_device *dev)
 	struct typhoon *tp = netdev_priv(dev);
 	int err;
 
+	err = typhoon_reject_firmware(tp);
+	if (err)
+		goto out;
+
 	err = typhoon_wakeup(tp, WaitSleep);
 	if(err < 0) {
 		printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
@@ -2350,7 +2406,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 		goto error_out_disable;
 	}
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if(err < 0) {
 		printk(ERR_PFX "%s: No usable DMA configuration\n",
 		       pci_name(pdev));
@@ -2626,6 +2682,8 @@ typhoon_init(void)
 static void __exit
 typhoon_cleanup(void)
 {
+	if (typhoon_fw)
+		release_firmware(typhoon_fw);
 	pci_unregister_driver(&typhoon_driver);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/typhoon-firmware.h linux-libre-2.6.30-gnu1/drivers/net/typhoon-firmware.h
--- linux-libre-2.6.29-gnu1/drivers/net/typhoon-firmware.h	2013-05-03 18:03:33.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/typhoon-firmware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * Copyright 1999-2004 3Com Corporation.  All Rights Reserved.
- *
- * Redistribution and use in source and binary forms of the 3c990img.h
- * microcode software are permitted provided that the following conditions
- * are met:
- * 1. Redistribution of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistribution in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of 3Com may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY 3COM ``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.
- *
- * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h
- * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY
- * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS
- * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT)
- * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN
- * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE
- */
-
- /* ver 03.001.008 */
-/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/typhoon.h linux-libre-2.6.30-gnu1/drivers/net/typhoon.h
--- linux-libre-2.6.29-gnu1/drivers/net/typhoon.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/typhoon.h	2009-06-09 23:05:27.000000000 -0400
@@ -174,18 +174,18 @@ struct tx_desc {
 		u64 tx_addr;	/* opaque for hardware, for TX_DESC */
 	};
 	__le32 processFlags;
-#define TYPHOON_TX_PF_NO_CRC		__constant_cpu_to_le32(0x00000001)
-#define TYPHOON_TX_PF_IP_CHKSUM		__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_TX_PF_TCP_CHKSUM	__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_TX_PF_TCP_SEGMENT	__constant_cpu_to_le32(0x00000008)
-#define TYPHOON_TX_PF_INSERT_VLAN	__constant_cpu_to_le32(0x00000010)
-#define TYPHOON_TX_PF_IPSEC		__constant_cpu_to_le32(0x00000020)
-#define TYPHOON_TX_PF_VLAN_PRIORITY	__constant_cpu_to_le32(0x00000040)
-#define TYPHOON_TX_PF_UDP_CHKSUM	__constant_cpu_to_le32(0x00000080)
-#define TYPHOON_TX_PF_PAD_FRAME		__constant_cpu_to_le32(0x00000100)
-#define TYPHOON_TX_PF_RESERVED		__constant_cpu_to_le32(0x00000e00)
-#define TYPHOON_TX_PF_VLAN_MASK		__constant_cpu_to_le32(0x0ffff000)
-#define TYPHOON_TX_PF_INTERNAL		__constant_cpu_to_le32(0xf0000000)
+#define TYPHOON_TX_PF_NO_CRC		cpu_to_le32(0x00000001)
+#define TYPHOON_TX_PF_IP_CHKSUM		cpu_to_le32(0x00000002)
+#define TYPHOON_TX_PF_TCP_CHKSUM	cpu_to_le32(0x00000004)
+#define TYPHOON_TX_PF_TCP_SEGMENT	cpu_to_le32(0x00000008)
+#define TYPHOON_TX_PF_INSERT_VLAN	cpu_to_le32(0x00000010)
+#define TYPHOON_TX_PF_IPSEC		cpu_to_le32(0x00000020)
+#define TYPHOON_TX_PF_VLAN_PRIORITY	cpu_to_le32(0x00000040)
+#define TYPHOON_TX_PF_UDP_CHKSUM	cpu_to_le32(0x00000080)
+#define TYPHOON_TX_PF_PAD_FRAME		cpu_to_le32(0x00000100)
+#define TYPHOON_TX_PF_RESERVED		cpu_to_le32(0x00000e00)
+#define TYPHOON_TX_PF_VLAN_MASK		cpu_to_le32(0x0ffff000)
+#define TYPHOON_TX_PF_INTERNAL		cpu_to_le32(0xf0000000)
 #define TYPHOON_TX_PF_VLAN_TAG_SHIFT	12
 } __attribute__ ((packed));
 
@@ -203,8 +203,8 @@ struct tcpopt_desc {
 	u8  flags;
 	u8  numDesc;
 	__le16 mss_flags;
-#define TYPHOON_TSO_FIRST		__constant_cpu_to_le16(0x1000)
-#define TYPHOON_TSO_LAST		__constant_cpu_to_le16(0x2000)
+#define TYPHOON_TSO_FIRST		cpu_to_le16(0x1000)
+#define TYPHOON_TSO_LAST		cpu_to_le16(0x2000)
 	__le32 respAddrLo;
 	__le32 bytesTx;
 	__le32 status;
@@ -222,8 +222,8 @@ struct ipsec_desc {
 	u8  flags;
 	u8  numDesc;
 	__le16 ipsecFlags;
-#define TYPHOON_IPSEC_GEN_IV	__constant_cpu_to_le16(0x0000)
-#define TYPHOON_IPSEC_USE_IV	__constant_cpu_to_le16(0x0001)
+#define TYPHOON_IPSEC_GEN_IV	cpu_to_le16(0x0000)
+#define TYPHOON_IPSEC_USE_IV	cpu_to_le16(0x0001)
 	__le32 sa1;
 	__le32 sa2;
 	__le32 reserved;
@@ -248,41 +248,41 @@ struct rx_desc {
 	u32 addr;	/* opaque, comes from virtAddr */
 	u32 addrHi;	/* opaque, comes from virtAddrHi */
 	__le32 rxStatus;
-#define TYPHOON_RX_ERR_INTERNAL		__constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_ERR_FIFO_UNDERRUN	__constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_ERR_BAD_SSD		__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_ERR_RUNT		__constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_ERR_CRC		__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_ERR_OVERSIZE		__constant_cpu_to_le32(0x00000005)
-#define TYPHOON_RX_ERR_ALIGN		__constant_cpu_to_le32(0x00000006)
-#define TYPHOON_RX_ERR_DRIBBLE		__constant_cpu_to_le32(0x00000007)
-#define TYPHOON_RX_PROTO_MASK		__constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_PROTO_UNKNOWN	__constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_PROTO_IP		__constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_PROTO_IPX		__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_VLAN			__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_IP_FRAG		__constant_cpu_to_le32(0x00000008)
-#define TYPHOON_RX_IPSEC		__constant_cpu_to_le32(0x00000010)
-#define TYPHOON_RX_IP_CHK_FAIL		__constant_cpu_to_le32(0x00000020)
-#define TYPHOON_RX_TCP_CHK_FAIL		__constant_cpu_to_le32(0x00000040)
-#define TYPHOON_RX_UDP_CHK_FAIL		__constant_cpu_to_le32(0x00000080)
-#define TYPHOON_RX_IP_CHK_GOOD		__constant_cpu_to_le32(0x00000100)
-#define TYPHOON_RX_TCP_CHK_GOOD		__constant_cpu_to_le32(0x00000200)
-#define TYPHOON_RX_UDP_CHK_GOOD		__constant_cpu_to_le32(0x00000400)
+#define TYPHOON_RX_ERR_INTERNAL		cpu_to_le32(0x00000000)
+#define TYPHOON_RX_ERR_FIFO_UNDERRUN	cpu_to_le32(0x00000001)
+#define TYPHOON_RX_ERR_BAD_SSD		cpu_to_le32(0x00000002)
+#define TYPHOON_RX_ERR_RUNT		cpu_to_le32(0x00000003)
+#define TYPHOON_RX_ERR_CRC		cpu_to_le32(0x00000004)
+#define TYPHOON_RX_ERR_OVERSIZE		cpu_to_le32(0x00000005)
+#define TYPHOON_RX_ERR_ALIGN		cpu_to_le32(0x00000006)
+#define TYPHOON_RX_ERR_DRIBBLE		cpu_to_le32(0x00000007)
+#define TYPHOON_RX_PROTO_MASK		cpu_to_le32(0x00000003)
+#define TYPHOON_RX_PROTO_UNKNOWN	cpu_to_le32(0x00000000)
+#define TYPHOON_RX_PROTO_IP		cpu_to_le32(0x00000001)
+#define TYPHOON_RX_PROTO_IPX		cpu_to_le32(0x00000002)
+#define TYPHOON_RX_VLAN			cpu_to_le32(0x00000004)
+#define TYPHOON_RX_IP_FRAG		cpu_to_le32(0x00000008)
+#define TYPHOON_RX_IPSEC		cpu_to_le32(0x00000010)
+#define TYPHOON_RX_IP_CHK_FAIL		cpu_to_le32(0x00000020)
+#define TYPHOON_RX_TCP_CHK_FAIL		cpu_to_le32(0x00000040)
+#define TYPHOON_RX_UDP_CHK_FAIL		cpu_to_le32(0x00000080)
+#define TYPHOON_RX_IP_CHK_GOOD		cpu_to_le32(0x00000100)
+#define TYPHOON_RX_TCP_CHK_GOOD		cpu_to_le32(0x00000200)
+#define TYPHOON_RX_UDP_CHK_GOOD		cpu_to_le32(0x00000400)
 	__le16 filterResults;
-#define TYPHOON_RX_FILTER_MASK		__constant_cpu_to_le16(0x7fff)
-#define TYPHOON_RX_FILTERED		__constant_cpu_to_le16(0x8000)
+#define TYPHOON_RX_FILTER_MASK		cpu_to_le16(0x7fff)
+#define TYPHOON_RX_FILTERED		cpu_to_le16(0x8000)
 	__le16 ipsecResults;
-#define TYPHOON_RX_OUTER_AH_GOOD	__constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_OUTER_ESP_GOOD	__constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_INNER_AH_GOOD	__constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_INNER_ESP_GOOD	__constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_OUTER_AH_FAIL	__constant_cpu_to_le16(0x0010)
-#define TYPHOON_RX_OUTER_ESP_FAIL	__constant_cpu_to_le16(0x0020)
-#define TYPHOON_RX_INNER_AH_FAIL	__constant_cpu_to_le16(0x0040)
-#define TYPHOON_RX_INNER_ESP_FAIL	__constant_cpu_to_le16(0x0080)
-#define TYPHOON_RX_UNKNOWN_SA		__constant_cpu_to_le16(0x0100)
-#define TYPHOON_RX_ESP_FORMAT_ERR	__constant_cpu_to_le16(0x0200)
+#define TYPHOON_RX_OUTER_AH_GOOD	cpu_to_le16(0x0001)
+#define TYPHOON_RX_OUTER_ESP_GOOD	cpu_to_le16(0x0002)
+#define TYPHOON_RX_INNER_AH_GOOD	cpu_to_le16(0x0004)
+#define TYPHOON_RX_INNER_ESP_GOOD	cpu_to_le16(0x0008)
+#define TYPHOON_RX_OUTER_AH_FAIL	cpu_to_le16(0x0010)
+#define TYPHOON_RX_OUTER_ESP_FAIL	cpu_to_le16(0x0020)
+#define TYPHOON_RX_INNER_AH_FAIL	cpu_to_le16(0x0040)
+#define TYPHOON_RX_INNER_ESP_FAIL	cpu_to_le16(0x0080)
+#define TYPHOON_RX_UNKNOWN_SA		cpu_to_le16(0x0100)
+#define TYPHOON_RX_ESP_FORMAT_ERR	cpu_to_le16(0x0200)
 	__be32 vlanTag;
 } __attribute__ ((packed));
 
@@ -318,31 +318,31 @@ struct cmd_desc {
 	u8  flags;
 	u8  numDesc;
 	__le16 cmd;
-#define TYPHOON_CMD_TX_ENABLE		__constant_cpu_to_le16(0x0001)
-#define TYPHOON_CMD_TX_DISABLE		__constant_cpu_to_le16(0x0002)
-#define TYPHOON_CMD_RX_ENABLE		__constant_cpu_to_le16(0x0003)
-#define TYPHOON_CMD_RX_DISABLE		__constant_cpu_to_le16(0x0004)
-#define TYPHOON_CMD_SET_RX_FILTER	__constant_cpu_to_le16(0x0005)
-#define TYPHOON_CMD_READ_STATS		__constant_cpu_to_le16(0x0007)
-#define TYPHOON_CMD_XCVR_SELECT		__constant_cpu_to_le16(0x0013)
-#define TYPHOON_CMD_SET_MAX_PKT_SIZE	__constant_cpu_to_le16(0x001a)
-#define TYPHOON_CMD_READ_MEDIA_STATUS	__constant_cpu_to_le16(0x001b)
-#define TYPHOON_CMD_GOTO_SLEEP		__constant_cpu_to_le16(0x0023)
-#define TYPHOON_CMD_SET_MULTICAST_HASH	__constant_cpu_to_le16(0x0025)
-#define TYPHOON_CMD_SET_MAC_ADDRESS	__constant_cpu_to_le16(0x0026)
-#define TYPHOON_CMD_READ_MAC_ADDRESS	__constant_cpu_to_le16(0x0027)
-#define TYPHOON_CMD_VLAN_TYPE_WRITE	__constant_cpu_to_le16(0x002b)
-#define TYPHOON_CMD_CREATE_SA		__constant_cpu_to_le16(0x0034)
-#define TYPHOON_CMD_DELETE_SA		__constant_cpu_to_le16(0x0035)
-#define TYPHOON_CMD_READ_VERSIONS	__constant_cpu_to_le16(0x0043)
-#define TYPHOON_CMD_IRQ_COALESCE_CTRL	__constant_cpu_to_le16(0x0045)
-#define TYPHOON_CMD_ENABLE_WAKE_EVENTS	__constant_cpu_to_le16(0x0049)
-#define TYPHOON_CMD_SET_OFFLOAD_TASKS	__constant_cpu_to_le16(0x004f)
-#define TYPHOON_CMD_HELLO_RESP		__constant_cpu_to_le16(0x0057)
-#define TYPHOON_CMD_HALT		__constant_cpu_to_le16(0x005d)
-#define TYPHOON_CMD_READ_IPSEC_INFO	__constant_cpu_to_le16(0x005e)
-#define TYPHOON_CMD_GET_IPSEC_ENABLE	__constant_cpu_to_le16(0x0067)
-#define TYPHOON_CMD_GET_CMD_LVL		__constant_cpu_to_le16(0x0069)
+#define TYPHOON_CMD_TX_ENABLE		cpu_to_le16(0x0001)
+#define TYPHOON_CMD_TX_DISABLE		cpu_to_le16(0x0002)
+#define TYPHOON_CMD_RX_ENABLE		cpu_to_le16(0x0003)
+#define TYPHOON_CMD_RX_DISABLE		cpu_to_le16(0x0004)
+#define TYPHOON_CMD_SET_RX_FILTER	cpu_to_le16(0x0005)
+#define TYPHOON_CMD_READ_STATS		cpu_to_le16(0x0007)
+#define TYPHOON_CMD_XCVR_SELECT		cpu_to_le16(0x0013)
+#define TYPHOON_CMD_SET_MAX_PKT_SIZE	cpu_to_le16(0x001a)
+#define TYPHOON_CMD_READ_MEDIA_STATUS	cpu_to_le16(0x001b)
+#define TYPHOON_CMD_GOTO_SLEEP		cpu_to_le16(0x0023)
+#define TYPHOON_CMD_SET_MULTICAST_HASH	cpu_to_le16(0x0025)
+#define TYPHOON_CMD_SET_MAC_ADDRESS	cpu_to_le16(0x0026)
+#define TYPHOON_CMD_READ_MAC_ADDRESS	cpu_to_le16(0x0027)
+#define TYPHOON_CMD_VLAN_TYPE_WRITE	cpu_to_le16(0x002b)
+#define TYPHOON_CMD_CREATE_SA		cpu_to_le16(0x0034)
+#define TYPHOON_CMD_DELETE_SA		cpu_to_le16(0x0035)
+#define TYPHOON_CMD_READ_VERSIONS	cpu_to_le16(0x0043)
+#define TYPHOON_CMD_IRQ_COALESCE_CTRL	cpu_to_le16(0x0045)
+#define TYPHOON_CMD_ENABLE_WAKE_EVENTS	cpu_to_le16(0x0049)
+#define TYPHOON_CMD_SET_OFFLOAD_TASKS	cpu_to_le16(0x004f)
+#define TYPHOON_CMD_HELLO_RESP		cpu_to_le16(0x0057)
+#define TYPHOON_CMD_HALT		cpu_to_le16(0x005d)
+#define TYPHOON_CMD_READ_IPSEC_INFO	cpu_to_le16(0x005e)
+#define TYPHOON_CMD_GET_IPSEC_ENABLE	cpu_to_le16(0x0067)
+#define TYPHOON_CMD_GET_CMD_LVL		cpu_to_le16(0x0069)
 	u16 seqNo;
 	__le16 parm1;
 	__le32 parm2;
@@ -380,11 +380,11 @@ struct resp_desc {
 
 /* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1)
  */
-#define TYPHOON_RX_FILTER_DIRECTED	__constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_FILTER_ALL_MCAST	__constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_FILTER_BROADCAST	__constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_FILTER_PROMISCOUS	__constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_FILTER_MCAST_HASH	__constant_cpu_to_le16(0x0010)
+#define TYPHOON_RX_FILTER_DIRECTED	cpu_to_le16(0x0001)
+#define TYPHOON_RX_FILTER_ALL_MCAST	cpu_to_le16(0x0002)
+#define TYPHOON_RX_FILTER_BROADCAST	cpu_to_le16(0x0004)
+#define TYPHOON_RX_FILTER_PROMISCOUS	cpu_to_le16(0x0008)
+#define TYPHOON_RX_FILTER_MCAST_HASH	cpu_to_le16(0x0010)
 
 /* TYPHOON_CMD_READ_STATS response format
  */
@@ -416,40 +416,40 @@ struct stats_resp {
 	__le32 rxOverflow;
 	__le32 rxFiltered;
 	__le32 linkStatus;
-#define TYPHOON_LINK_STAT_MASK		__constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_GOOD		__constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_BAD		__constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_SPEED_MASK		__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_100MBPS		__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_10MBPS		__constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_DUPLEX_MASK	__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_FULL_DUPLEX	__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_HALF_DUPLEX	__constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_STAT_MASK		cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_GOOD		cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_BAD		cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_SPEED_MASK		cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_100MBPS		cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_10MBPS		cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_DUPLEX_MASK	cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_FULL_DUPLEX	cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_HALF_DUPLEX	cpu_to_le32(0x00000000)
 	__le32 unused2;
 	__le32 unused3;
 } __attribute__ ((packed));
 
 /* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1)
  */
-#define TYPHOON_XCVR_10HALF	__constant_cpu_to_le16(0x0000)
-#define TYPHOON_XCVR_10FULL	__constant_cpu_to_le16(0x0001)
-#define TYPHOON_XCVR_100HALF	__constant_cpu_to_le16(0x0002)
-#define TYPHOON_XCVR_100FULL	__constant_cpu_to_le16(0x0003)
-#define TYPHOON_XCVR_AUTONEG	__constant_cpu_to_le16(0x0004)
+#define TYPHOON_XCVR_10HALF	cpu_to_le16(0x0000)
+#define TYPHOON_XCVR_10FULL	cpu_to_le16(0x0001)
+#define TYPHOON_XCVR_100HALF	cpu_to_le16(0x0002)
+#define TYPHOON_XCVR_100FULL	cpu_to_le16(0x0003)
+#define TYPHOON_XCVR_AUTONEG	cpu_to_le16(0x0004)
 
 /* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1)
  */
-#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE	__constant_cpu_to_le16(0x0004)
-#define TYPHOON_MEDIA_STAT_COLLISION_DETECT	__constant_cpu_to_le16(0x0010)
-#define TYPHOON_MEDIA_STAT_CARRIER_SENSE	__constant_cpu_to_le16(0x0020)
-#define TYPHOON_MEDIA_STAT_POLARITY_REV		__constant_cpu_to_le16(0x0400)
-#define TYPHOON_MEDIA_STAT_NO_LINK		__constant_cpu_to_le16(0x0800)
+#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE	cpu_to_le16(0x0004)
+#define TYPHOON_MEDIA_STAT_COLLISION_DETECT	cpu_to_le16(0x0010)
+#define TYPHOON_MEDIA_STAT_CARRIER_SENSE	cpu_to_le16(0x0020)
+#define TYPHOON_MEDIA_STAT_POLARITY_REV		cpu_to_le16(0x0400)
+#define TYPHOON_MEDIA_STAT_NO_LINK		cpu_to_le16(0x0800)
 
 /* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1)
  */
-#define TYPHOON_MCAST_HASH_DISABLE	__constant_cpu_to_le16(0x0000)
-#define TYPHOON_MCAST_HASH_ENABLE	__constant_cpu_to_le16(0x0001)
-#define TYPHOON_MCAST_HASH_SET		__constant_cpu_to_le16(0x0002)
+#define TYPHOON_MCAST_HASH_DISABLE	cpu_to_le16(0x0000)
+#define TYPHOON_MCAST_HASH_ENABLE	cpu_to_le16(0x0001)
+#define TYPHOON_MCAST_HASH_SET		cpu_to_le16(0x0002)
 
 /* TYPHOON_CMD_CREATE_SA descriptor and settings
  */
@@ -459,9 +459,9 @@ struct sa_descriptor {
 	u16 cmd;
 	u16 seqNo;
 	u16 mode;
-#define TYPHOON_SA_MODE_NULL		__constant_cpu_to_le16(0x0000)
-#define TYPHOON_SA_MODE_AH		__constant_cpu_to_le16(0x0001)
-#define TYPHOON_SA_MODE_ESP		__constant_cpu_to_le16(0x0002)
+#define TYPHOON_SA_MODE_NULL		cpu_to_le16(0x0000)
+#define TYPHOON_SA_MODE_AH		cpu_to_le16(0x0001)
+#define TYPHOON_SA_MODE_ESP		cpu_to_le16(0x0002)
 	u8  hashFlags;
 #define TYPHOON_SA_HASH_ENABLE		0x01
 #define TYPHOON_SA_HASH_SHA1		0x02
@@ -493,22 +493,22 @@ struct sa_descriptor {
 /* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx))
  * This is all for IPv4.
  */
-#define TYPHOON_OFFLOAD_TCP_CHKSUM	__constant_cpu_to_le32(0x00000002)
-#define TYPHOON_OFFLOAD_UDP_CHKSUM	__constant_cpu_to_le32(0x00000004)
-#define TYPHOON_OFFLOAD_IP_CHKSUM	__constant_cpu_to_le32(0x00000008)
-#define TYPHOON_OFFLOAD_IPSEC		__constant_cpu_to_le32(0x00000010)
-#define TYPHOON_OFFLOAD_BCAST_THROTTLE	__constant_cpu_to_le32(0x00000020)
-#define TYPHOON_OFFLOAD_DHCP_PREVENT	__constant_cpu_to_le32(0x00000040)
-#define TYPHOON_OFFLOAD_VLAN		__constant_cpu_to_le32(0x00000080)
-#define TYPHOON_OFFLOAD_FILTERING	__constant_cpu_to_le32(0x00000100)
-#define TYPHOON_OFFLOAD_TCP_SEGMENT	__constant_cpu_to_le32(0x00000200)
+#define TYPHOON_OFFLOAD_TCP_CHKSUM	cpu_to_le32(0x00000002)
+#define TYPHOON_OFFLOAD_UDP_CHKSUM	cpu_to_le32(0x00000004)
+#define TYPHOON_OFFLOAD_IP_CHKSUM	cpu_to_le32(0x00000008)
+#define TYPHOON_OFFLOAD_IPSEC		cpu_to_le32(0x00000010)
+#define TYPHOON_OFFLOAD_BCAST_THROTTLE	cpu_to_le32(0x00000020)
+#define TYPHOON_OFFLOAD_DHCP_PREVENT	cpu_to_le32(0x00000040)
+#define TYPHOON_OFFLOAD_VLAN		cpu_to_le32(0x00000080)
+#define TYPHOON_OFFLOAD_FILTERING	cpu_to_le32(0x00000100)
+#define TYPHOON_OFFLOAD_TCP_SEGMENT	cpu_to_le32(0x00000200)
 
 /* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1)
  */
-#define TYPHOON_WAKE_MAGIC_PKT		__constant_cpu_to_le16(0x01)
-#define TYPHOON_WAKE_LINK_EVENT		__constant_cpu_to_le16(0x02)
-#define TYPHOON_WAKE_ICMP_ECHO		__constant_cpu_to_le16(0x04)
-#define TYPHOON_WAKE_ARP		__constant_cpu_to_le16(0x08)
+#define TYPHOON_WAKE_MAGIC_PKT		cpu_to_le16(0x01)
+#define TYPHOON_WAKE_LINK_EVENT		cpu_to_le16(0x02)
+#define TYPHOON_WAKE_ICMP_ECHO		cpu_to_le16(0x04)
+#define TYPHOON_WAKE_ARP		cpu_to_le16(0x08)
 
 /* These are used to load the firmware image on the NIC
  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ucc_geth.c linux-libre-2.6.30-gnu1/drivers/net/ucc_geth.c
--- linux-libre-2.6.29-gnu1/drivers/net/ucc_geth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ucc_geth.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/workqueue.h>
@@ -39,7 +38,7 @@
 #include <asm/ucc_fast.h>
 
 #include "ucc_geth.h"
-#include "ucc_geth_mii.h"
+#include "fsl_pq_mdio.h"
 
 #undef DEBUG
 
@@ -223,10 +222,10 @@ static struct sk_buff *get_new_skb(struc
 		    (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT -
 					      1)));
 
-	skb->dev = ugeth->dev;
+	skb->dev = ugeth->ndev;
 
 	out_be32(&((struct qe_bd __iomem *)bd)->buf,
-		      dma_map_single(&ugeth->dev->dev,
+		      dma_map_single(ugeth->dev,
 				     skb->data,
 				     ugeth->ug_info->uf_info.max_rx_buf_length +
 				     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
@@ -1395,7 +1394,8 @@ static int adjust_enet_interface(struct
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
 	    (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
-		upsmr |= UCC_GETH_UPSMR_RPM;
+		if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
+			upsmr |= UCC_GETH_UPSMR_RPM;
 		switch (ugeth->max_speed) {
 		case SPEED_10:
 			upsmr |= UCC_GETH_UPSMR_R10M;
@@ -1872,7 +1872,7 @@ static void ucc_geth_memclean(struct ucc
 			continue;
 		for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
 			if (ugeth->tx_skbuff[i][j]) {
-				dma_unmap_single(&ugeth->dev->dev,
+				dma_unmap_single(ugeth->dev,
 						 in_be32(&((struct qe_bd __iomem *)bd)->buf),
 						 (in_be32((u32 __iomem *)bd) &
 						  BD_LENGTH_MASK),
@@ -1900,7 +1900,7 @@ static void ucc_geth_memclean(struct ucc
 			bd = ugeth->p_rx_bd_ring[i];
 			for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
 				if (ugeth->rx_skbuff[i][j]) {
-					dma_unmap_single(&ugeth->dev->dev,
+					dma_unmap_single(ugeth->dev,
 						in_be32(&((struct qe_bd __iomem *)bd)->buf),
 						ugeth->ug_info->
 						uf_info.max_rx_buf_length +
@@ -2009,6 +2009,9 @@ static void ucc_geth_stop(struct ucc_get
 	/* Disable Rx and Tx */
 	clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
 
+	phy_disconnect(ugeth->phydev);
+	ugeth->phydev = NULL;
+
 	ucc_geth_memclean(ugeth);
 }
 
@@ -3068,7 +3071,7 @@ static int ucc_geth_start_xmit(struct sk
 
 	/* set up the buffer descriptor */
 	out_be32(&((struct qe_bd __iomem *)bd)->buf,
-		      dma_map_single(&ugeth->dev->dev, skb->data,
+		      dma_map_single(ugeth->dev, skb->data,
 			      skb->len, DMA_TO_DEVICE));
 
 	/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
@@ -3124,7 +3127,7 @@ static int ucc_geth_rx(struct ucc_geth_p
 
 	ugeth_vdbg("%s: IN", __func__);
 
-	dev = ugeth->dev;
+	dev = ugeth->ndev;
 
 	/* collect received buffers */
 	bd = ugeth->rxBd[rxQ];
@@ -3158,7 +3161,7 @@ static int ucc_geth_rx(struct ucc_geth_p
 			skb_put(skb, length);
 
 			/* Tell the skb what kind of packet this is */
-			skb->protocol = eth_type_trans(skb, ugeth->dev);
+			skb->protocol = eth_type_trans(skb, ugeth->ndev);
 
 			dev->stats.rx_bytes += length;
 			/* Send the packet up the stack */
@@ -3249,7 +3252,7 @@ static int ucc_geth_poll(struct napi_str
 		howmany += ucc_geth_rx(ugeth, i, budget - howmany);
 
 	if (howmany < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
 	}
 
@@ -3280,10 +3283,10 @@ static irqreturn_t ucc_geth_irq_handler(
 
 	/* check for receive events that require processing */
 	if (ucce & UCCE_RX_EVENTS) {
-		if (netif_rx_schedule_prep(&ugeth->napi)) {
+		if (napi_schedule_prep(&ugeth->napi)) {
 			uccm &= ~UCCE_RX_EVENTS;
 			out_be32(uccf->p_uccm, uccm);
-			__netif_rx_schedule(&ugeth->napi);
+			__napi_schedule(&ugeth->napi);
 		}
 	}
 
@@ -3345,6 +3348,14 @@ static int ucc_geth_open(struct net_devi
 		return -EINVAL;
 	}
 
+	err = init_phy(dev);
+	if (err) {
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot initialize PHY, aborting.",
+				  dev->name);
+		return err;
+	}
+
 	err = ucc_struct_init(ugeth);
 	if (err) {
 		if (netif_msg_ifup(ugeth))
@@ -3381,13 +3392,6 @@ static int ucc_geth_open(struct net_devi
 				   &ugeth->ug_regs->macstnaddr1,
 				   &ugeth->ug_regs->macstnaddr2);
 
-	err = init_phy(dev);
-	if (err) {
-		if (netif_msg_ifup(ugeth))
-			ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
-		goto out_err;
-	}
-
 	phy_start(ugeth->phydev);
 
 	err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
@@ -3428,10 +3432,7 @@ static int ucc_geth_close(struct net_dev
 
 	ucc_geth_stop(ugeth);
 
-	free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
-
-	phy_disconnect(ugeth->phydev);
-	ugeth->phydev = NULL;
+	free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
 
 	netif_stop_queue(dev);
 
@@ -3445,7 +3446,7 @@ static void ucc_geth_timeout_work(struct
 	struct net_device *dev;
 
 	ugeth = container_of(work, struct ucc_geth_private, timeout_work);
-	dev = ugeth->dev;
+	dev = ugeth->ndev;
 
 	ugeth_vdbg("%s: IN", __func__);
 
@@ -3501,6 +3502,20 @@ static phy_interface_t to_phy_interface(
 	return PHY_INTERFACE_MODE_MII;
 }
 
+static const struct net_device_ops ucc_geth_netdev_ops = {
+	.ndo_open		= ucc_geth_open,
+	.ndo_stop		= ucc_geth_close,
+	.ndo_start_xmit		= ucc_geth_start_xmit,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_multicast_list	= ucc_geth_set_multi,
+	.ndo_tx_timeout		= ucc_geth_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= ucc_netpoll,
+#endif
+};
+
 static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
 {
 	struct device *device = &ofdev->dev;
@@ -3633,15 +3648,16 @@ static int ucc_geth_probe(struct of_devi
 		mdio = of_get_parent(phy);
 
 		if (mdio == NULL)
-			return -1;
+			return -ENODEV;
 
 		err = of_address_to_resource(mdio, 0, &res);
-		of_node_put(mdio);
-
-		if (err)
-			return -1;
 
-		uec_mdio_bus_name(bus_name, mdio);
+		if (err) {
+			of_node_put(mdio);
+			return err;
+		}
+		fsl_pq_mdio_bus_name(bus_name, mdio);
+		of_node_put(mdio);
 		snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
 			"%s:%02x", bus_name, *prop);
 	}
@@ -3716,19 +3732,11 @@ static int ucc_geth_probe(struct of_devi
 
 	/* Fill in the dev structure */
 	uec_set_ethtool_ops(dev);
-	dev->open = ucc_geth_open;
-	dev->hard_start_xmit = ucc_geth_start_xmit;
-	dev->tx_timeout = ucc_geth_timeout;
+	dev->netdev_ops = &ucc_geth_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
 	netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	dev->poll_controller = ucc_netpoll;
-#endif
-	dev->stop = ucc_geth_close;
-//    dev->change_mtu = ucc_geth_change_mtu;
 	dev->mtu = 1500;
-	dev->set_multicast_list = ucc_geth_set_multi;
 
 	ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
 	ugeth->phy_interface = phy_interface;
@@ -3748,7 +3756,8 @@ static int ucc_geth_probe(struct of_devi
 		memcpy(dev->dev_addr, mac_addr, 6);
 
 	ugeth->ug_info = ug_info;
-	ugeth->dev = dev;
+	ugeth->dev = device;
+	ugeth->ndev = dev;
 	ugeth->node = np;
 
 	return 0;
@@ -3789,11 +3798,6 @@ static int __init ucc_geth_init(void)
 {
 	int i, ret;
 
-	ret = uec_mdio_init();
-
-	if (ret)
-		return ret;
-
 	if (netif_msg_drv(&debug))
 		printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
 	for (i = 0; i < 8; i++)
@@ -3802,16 +3806,12 @@ static int __init ucc_geth_init(void)
 
 	ret = of_register_platform_driver(&ucc_geth_driver);
 
-	if (ret)
-		uec_mdio_exit();
-
 	return ret;
 }
 
 static void __exit ucc_geth_exit(void)
 {
 	of_unregister_platform_driver(&ucc_geth_driver);
-	uec_mdio_exit();
 }
 
 module_init(ucc_geth_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_ethtool.c linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_ethtool.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
@@ -39,7 +38,6 @@
 #include <asm/types.h>
 
 #include "ucc_geth.h"
-#include "ucc_geth_mii.h"
 
 static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
 	"tx-64-frames",
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ucc_geth.h linux-libre-2.6.30-gnu1/drivers/net/ucc_geth.h
--- linux-libre-2.6.29-gnu1/drivers/net/ucc_geth.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ucc_geth.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,7 +20,6 @@
 
 #include <linux/kernel.h>
 #include <linux/list.h>
-#include <linux/fsl_devices.h>
 
 #include <asm/immap_qe.h>
 #include <asm/qe.h>
@@ -28,8 +27,6 @@
 #include <asm/ucc.h>
 #include <asm/ucc_fast.h>
 
-#include "ucc_geth_mii.h"
-
 #define DRV_DESC "QE UCC Gigabit Ethernet Controller"
 #define DRV_NAME "ucc_geth"
 #define DRV_VERSION "1.1"
@@ -184,6 +181,18 @@ struct ucc_geth {
 #define UCCE_RX_EVENTS  (UCCE_RXF | UCC_GETH_UCCE_BSY)
 #define UCCE_TX_EVENTS	(UCCE_TXB | UCC_GETH_UCCE_TXE)
 
+/* TBI defines */
+#define	ENET_TBI_MII_CR		0x00	/* Control */
+#define	ENET_TBI_MII_SR		0x01	/* Status */
+#define	ENET_TBI_MII_ANA	0x04	/* AN advertisement */
+#define	ENET_TBI_MII_ANLPBPA	0x05	/* AN link partner base page ability */
+#define	ENET_TBI_MII_ANEX	0x06	/* AN expansion */
+#define	ENET_TBI_MII_ANNPT	0x07	/* AN next page transmit */
+#define	ENET_TBI_MII_ANLPANP	0x08	/* AN link partner ability next page */
+#define	ENET_TBI_MII_EXST	0x0F	/* Extended status */
+#define	ENET_TBI_MII_JD		0x10	/* Jitter diagnostics */
+#define	ENET_TBI_MII_TBICON	0x11	/* TBI control */
+
 /* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
 #define MACCFG1_FLOW_RX                         0x00000020	/* Flow Control
 								   Rx */
@@ -1119,7 +1128,8 @@ struct ucc_geth_info {
 struct ucc_geth_private {
 	struct ucc_geth_info *ug_info;
 	struct ucc_fast_private *uccf;
-	struct net_device *dev;
+	struct device *dev;
+	struct net_device *ndev;
 	struct napi_struct napi;
 	struct work_struct timeout_work;
 	struct ucc_geth __iomem *ug_regs;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_mii.c linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_mii.c
--- linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_mii.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_mii.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,295 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.c
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- *	    Kim Phillips <kim.phillips@freescale.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/fsl_devices.h>
-#include <linux/of_platform.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/ucc.h>
-
-#include "ucc_geth_mii.h"
-#include "ucc_geth.h"
-
-#define DEBUG
-#ifdef DEBUG
-#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
-#else
-#define vdbg(format, arg...) do {} while(0)
-#endif
-
-#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
-#define MII_DRV_NAME "fsl-uec_mdio"
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns.  All PHY */
-/* configuration has to be done through the master UEC MIIM regs */
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
-{
-	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
-
-	/* Setting up the MII Mangement Address Register */
-	out_be32(&regs->miimadd,
-		 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
-	/* Setting up the MII Mangement Control Register with the value */
-	out_be32(&regs->miimcon, value);
-
-	/* Wait till MII management write is complete */
-	while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
-		cpu_relax();
-
-	return 0;
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value.  Clears miimcom first.  All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
-	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
-	u16 value;
-
-	/* Setting up the MII Mangement Address Register */
-	out_be32(&regs->miimadd,
-		 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
-	/* Clear miimcom, perform an MII management read cycle */
-	out_be32(&regs->miimcom, 0);
-	out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);
-
-	/* Wait till MII management write is complete */
-	while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
-		cpu_relax();
-
-	/* Read MII management status  */
-	value = in_be32(&regs->miimstat);
-
-	return value;
-}
-
-/* Reset the MIIM registers, and wait for the bus to free */
-static int uec_mdio_reset(struct mii_bus *bus)
-{
-	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
-	int timeout = PHY_INIT_TIMEOUT;
-
-	mutex_lock(&bus->mdio_lock);
-
-	/* Reset the management interface */
-	out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
-
-	/* Setup the MII Mgmt clock speed */
-	out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);
-
-	/* Wait until the bus is free */
-	while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
-		cpu_relax();
-
-	mutex_unlock(&bus->mdio_lock);
-
-	if (timeout < 0) {
-		printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
-		return -EBUSY;
-	}
-
-	return 0;
-}
-
-static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
-{
-	struct device *device = &ofdev->dev;
-	struct device_node *np = ofdev->node, *tempnp = NULL;
-	struct device_node *child = NULL;
-	struct ucc_mii_mng __iomem *regs;
-	struct mii_bus *new_bus;
-	struct resource res;
-	int k, err = 0;
-
-	new_bus = mdiobus_alloc();
-	if (NULL == new_bus)
-		return -ENOMEM;
-
-	new_bus->name = "UCC Ethernet Controller MII Bus";
-	new_bus->read = &uec_mdio_read;
-	new_bus->write = &uec_mdio_write;
-	new_bus->reset = &uec_mdio_reset;
-
-	memset(&res, 0, sizeof(res));
-
-	err = of_address_to_resource(np, 0, &res);
-	if (err)
-		goto reg_map_fail;
-
-	uec_mdio_bus_name(new_bus->id, np);
-
-	new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
-
-	if (NULL == new_bus->irq) {
-		err = -ENOMEM;
-		goto reg_map_fail;
-	}
-
-	for (k = 0; k < 32; k++)
-		new_bus->irq[k] = PHY_POLL;
-
-	while ((child = of_get_next_child(np, child)) != NULL) {
-		int irq = irq_of_parse_and_map(child, 0);
-		if (irq != NO_IRQ) {
-			const u32 *id = of_get_property(child, "reg", NULL);
-			new_bus->irq[*id] = irq;
-		}
-	}
-
-	/* Set the base address */
-	regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
-
-	if (NULL == regs) {
-		err = -ENOMEM;
-		goto ioremap_fail;
-	}
-
-	new_bus->priv = (void __force *)regs;
-
-	new_bus->parent = device;
-	dev_set_drvdata(device, new_bus);
-
-	/* Read MII management master from device tree */
-	while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
-	       != NULL) {
-		struct resource tempres;
-
-		err = of_address_to_resource(tempnp, 0, &tempres);
-		if (err)
-			goto bus_register_fail;
-
-		/* if our mdio regs fall within this UCC regs range */
-		if ((res.start >= tempres.start) &&
-		    (res.end <= tempres.end)) {
-			/* set this UCC to be the MII master */
-			const u32 *id;
-
-			id = of_get_property(tempnp, "cell-index", NULL);
-			if (!id) {
-				id = of_get_property(tempnp, "device-id", NULL);
-				if (!id)
-					goto bus_register_fail;
-			}
-
-			ucc_set_qe_mux_mii_mng(*id - 1);
-
-			/* assign the TBI an address which won't
-			 * conflict with the PHYs */
-			out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
-			break;
-		}
-	}
-
-	err = mdiobus_register(new_bus);
-	if (0 != err) {
-		printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
-		       new_bus->name);
-		goto bus_register_fail;
-	}
-
-	return 0;
-
-bus_register_fail:
-	iounmap(regs);
-ioremap_fail:
-	kfree(new_bus->irq);
-reg_map_fail:
-	mdiobus_free(new_bus);
-
-	return err;
-}
-
-static int uec_mdio_remove(struct of_device *ofdev)
-{
-	struct device *device = &ofdev->dev;
-	struct mii_bus *bus = dev_get_drvdata(device);
-
-	mdiobus_unregister(bus);
-
-	dev_set_drvdata(device, NULL);
-
-	iounmap((void __iomem *)bus->priv);
-	bus->priv = NULL;
-	mdiobus_free(bus);
-
-	return 0;
-}
-
-static struct of_device_id uec_mdio_match[] = {
-	{
-		.type = "mdio",
-		.compatible = "ucc_geth_phy",
-	},
-	{
-		.compatible = "fsl,ucc-mdio",
-	},
-	{},
-};
-
-static struct of_platform_driver uec_mdio_driver = {
-	.name	= MII_DRV_NAME,
-	.probe	= uec_mdio_probe,
-	.remove	= uec_mdio_remove,
-	.match_table	= uec_mdio_match,
-};
-
-int __init uec_mdio_init(void)
-{
-	return of_register_platform_driver(&uec_mdio_driver);
-}
-
-/* called from __init ucc_geth_init, therefore can not be __exit */
-void uec_mdio_exit(void)
-{
-	of_unregister_platform_driver(&uec_mdio_driver);
-}
-
-void uec_mdio_bus_name(char *name, struct device_node *np)
-{
-        const u32 *reg;
-
-        reg = of_get_property(np, "reg", NULL);
-
-        snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
-}
-
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_mii.h linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_mii.h
--- linux-libre-2.6.29-gnu1/drivers/net/ucc_geth_mii.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/ucc_geth_mii.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.h
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- *	    Kim Phillips <kim.phillips@freescale.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-#ifndef __UEC_MII_H
-#define __UEC_MII_H
-
-/* UCC GETH MIIMCFG (MII Management Configuration Register) */
-#define MIIMCFG_RESET_MANAGEMENT                0x80000000	/* Reset
-								   management */
-#define MIIMCFG_NO_PREAMBLE                     0x00000010	/* Preamble
-								   suppress */
-#define MIIMCFG_CLOCK_DIVIDE_SHIFT              (31 - 31)	/* clock divide
-								   << shift */
-#define MIIMCFG_CLOCK_DIVIDE_MAX                0xf	/* max clock divide */
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2    0x00000000
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4    0x00000001
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6    0x00000002
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8    0x00000003
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10   0x00000004
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14   0x00000005
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16   0x00000008
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20   0x00000006
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28   0x00000007
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32   0x00000009
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48   0x0000000a
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64   0x0000000b
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80   0x0000000c
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112  0x0000000d
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160  0x0000000e
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224  0x0000000f
-
-/* UCC GETH MIIMCOM (MII Management Command Register) */
-#define MIIMCOM_SCAN_CYCLE                      0x00000002	/* Scan cycle */
-#define MIIMCOM_READ_CYCLE                      0x00000001	/* Read cycle */
-
-/* UCC GETH MIIMADD (MII Management Address Register) */
-#define MIIMADD_PHY_ADDRESS_SHIFT               (31 - 23)	/* PHY Address
-								   << shift */
-#define MIIMADD_PHY_REGISTER_SHIFT              (31 - 31)	/* PHY Register
-								   << shift */
-
-/* UCC GETH MIIMCON (MII Management Control Register) */
-#define MIIMCON_PHY_CONTROL_SHIFT               (31 - 31)	/* PHY Control
-								   << shift */
-#define MIIMCON_PHY_STATUS_SHIFT                (31 - 31)	/* PHY Status
-								   << shift */
-
-/* UCC GETH MIIMIND (MII Management Indicator Register) */
-#define MIIMIND_NOT_VALID                       0x00000004	/* Not valid */
-#define MIIMIND_SCAN                            0x00000002	/* Scan in
-								   progress */
-#define MIIMIND_BUSY                            0x00000001
-
-/* Initial TBI Physical Address */
-#define UTBIPAR_INIT_TBIPA			0x1f
-
-struct ucc_mii_mng {
-	u32 miimcfg;		/* MII management configuration reg */
-	u32 miimcom;		/* MII management command reg */
-	u32 miimadd;		/* MII management address reg */
-	u32 miimcon;		/* MII management control reg */
-	u32 miimstat;		/* MII management status reg */
-	u32 miimind;		/* MII management indication reg */
-	u8 notcare[28];		/* Space holder */
-	u32 utbipar;		/* TBI phy address reg */
-} __attribute__ ((packed));
-
-/* TBI / MII Set Register */
-enum enet_tbi_mii_reg {
-	ENET_TBI_MII_CR = 0x00,	/* Control */
-	ENET_TBI_MII_SR = 0x01,	/* Status */
-	ENET_TBI_MII_ANA = 0x04,	/* AN advertisement */
-	ENET_TBI_MII_ANLPBPA = 0x05,	/* AN link partner base page ability */
-	ENET_TBI_MII_ANEX = 0x06,	/* AN expansion */
-	ENET_TBI_MII_ANNPT = 0x07,	/* AN next page transmit */
-	ENET_TBI_MII_ANLPANP = 0x08,	/* AN link partner ability next page */
-	ENET_TBI_MII_EXST = 0x0F,	/* Extended status */
-	ENET_TBI_MII_JD = 0x10,	/* Jitter diagnostics */
-	ENET_TBI_MII_TBICON = 0x11	/* TBI control */
-};
-
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int __init uec_mdio_init(void);
-void uec_mdio_exit(void);
-void uec_mdio_bus_name(char *name, struct device_node *np);
-#endif				/* __UEC_MII_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/asix.c linux-libre-2.6.30-gnu1/drivers/net/usb/asix.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/asix.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/asix.c	2009-06-09 23:05:27.000000000 -0400
@@ -807,6 +807,18 @@ static int ax88172_link_reset(struct usb
 	return 0;
 }
 
+static const struct net_device_ops ax88172_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= asix_ioctl,
+	.ndo_set_multicast_list = ax88172_set_multicast,
+};
+
 static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int ret = 0;
@@ -846,9 +858,8 @@ static int ax88172_bind(struct usbnet *d
 	dev->mii.phy_id_mask = 0x3f;
 	dev->mii.reg_num_mask = 0x1f;
 	dev->mii.phy_id = asix_get_phy_addr(dev);
-	dev->net->do_ioctl = asix_ioctl;
 
-	dev->net->set_multicast_list = ax88172_set_multicast;
+	dev->net->netdev_ops = &ax88172_netdev_ops;
 	dev->net->ethtool_ops = &ax88172_ethtool_ops;
 
 	asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -898,6 +909,18 @@ static int ax88772_link_reset(struct usb
 	return 0;
 }
 
+static const struct net_device_ops ax88772_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= asix_ioctl,
+	.ndo_set_multicast_list = asix_set_multicast,
+};
+
 static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int ret, embd_phy;
@@ -962,7 +985,6 @@ static int ax88772_bind(struct usbnet *d
 	dev->mii.mdio_write = asix_mdio_write;
 	dev->mii.phy_id_mask = 0x1f;
 	dev->mii.reg_num_mask = 0x1f;
-	dev->net->do_ioctl = asix_ioctl;
 	dev->mii.phy_id = asix_get_phy_addr(dev);
 
 	phyid = asix_get_phyid(dev);
@@ -978,7 +1000,7 @@ static int ax88772_bind(struct usbnet *d
 
 	msleep(150);
 
-	dev->net->set_multicast_list = asix_set_multicast;
+	dev->net->netdev_ops = &ax88772_netdev_ops;
 	dev->net->ethtool_ops = &ax88772_ethtool_ops;
 
 	asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -1181,6 +1203,18 @@ static int ax88178_change_mtu(struct net
 	return 0;
 }
 
+static const struct net_device_ops ax88178_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_multicast_list = asix_set_multicast,
+	.ndo_do_ioctl 		= asix_ioctl,
+	.ndo_change_mtu 	= ax88178_change_mtu,
+};
+
 static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	struct asix_data *data = (struct asix_data *)&dev->data;
@@ -1247,11 +1281,10 @@ static int ax88178_bind(struct usbnet *d
 	dev->mii.phy_id_mask = 0x1f;
 	dev->mii.reg_num_mask = 0xff;
 	dev->mii.supports_gmii = 1;
-	dev->net->do_ioctl = asix_ioctl;
 	dev->mii.phy_id = asix_get_phy_addr(dev);
-	dev->net->set_multicast_list = asix_set_multicast;
+
+	dev->net->netdev_ops = &ax88178_netdev_ops;
 	dev->net->ethtool_ops = &ax88178_ethtool_ops;
-	dev->net->change_mtu = &ax88178_change_mtu;
 
 	phyid = asix_get_phyid(dev);
 	dbg("PHYID=0x%08x", phyid);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/catc.c linux-libre-2.6.30-gnu1/drivers/net/usb/catc.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/catc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/catc.c	2009-06-09 23:05:27.000000000 -0400
@@ -163,7 +163,6 @@ struct catc {
 	struct net_device *netdev;
 	struct usb_device *usbdev;
 
-	struct net_device_stats stats;
 	unsigned long flags;
 
 	unsigned int tx_ptr, tx_idx;
@@ -245,8 +244,8 @@ static void catc_rx_done(struct urb *urb
 		if(!catc->is_f5u011) {
 			pkt_len = le16_to_cpup((__le16*)pkt_start);
 			if (pkt_len > urb->actual_length) {
-				catc->stats.rx_length_errors++;
-				catc->stats.rx_errors++;
+				catc->netdev->stats.rx_length_errors++;
+				catc->netdev->stats.rx_errors++;
 				break;
 			}
 		} else {
@@ -262,8 +261,8 @@ static void catc_rx_done(struct urb *urb
 		skb->protocol = eth_type_trans(skb, catc->netdev);
 		netif_rx(skb);
 
-		catc->stats.rx_packets++;
-		catc->stats.rx_bytes += pkt_len;
+		catc->netdev->stats.rx_packets++;
+		catc->netdev->stats.rx_bytes += pkt_len;
 
 		/* F5U011 only does one packet per RX */
 		if (catc->is_f5u011)
@@ -386,7 +385,7 @@ static void catc_tx_done(struct urb *urb
 		dbg("Tx Reset.");
 		urb->status = 0;
 		catc->netdev->trans_start = jiffies;
-		catc->stats.tx_errors++;
+		catc->netdev->stats.tx_errors++;
 		clear_bit(TX_RUNNING, &catc->flags);
 		netif_wake_queue(catc->netdev);
 		return;
@@ -412,7 +411,7 @@ static void catc_tx_done(struct urb *urb
 	spin_unlock_irqrestore(&catc->tx_lock, flags);
 }
 
-static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static int catc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct catc *catc = netdev_priv(netdev);
 	unsigned long flags;
@@ -443,8 +442,8 @@ static int catc_hard_start_xmit(struct s
 	spin_unlock_irqrestore(&catc->tx_lock, flags);
 
 	if (r >= 0) {
-		catc->stats.tx_bytes += skb->len;
-		catc->stats.tx_packets++;
+		catc->netdev->stats.tx_bytes += skb->len;
+		catc->netdev->stats.tx_packets++;
 	}
 
 	dev_kfree_skb(skb);
@@ -588,15 +587,15 @@ static void catc_stats_done(struct catc
 	switch (index) {
 		case TxSingleColl:
 		case TxMultiColl:
-			catc->stats.collisions += data - last;
+			catc->netdev->stats.collisions += data - last;
 			break;
 		case TxExcessColl:
-			catc->stats.tx_aborted_errors += data - last;
-			catc->stats.tx_errors += data - last;
+			catc->netdev->stats.tx_aborted_errors += data - last;
+			catc->netdev->stats.tx_errors += data - last;
 			break;
 		case RxFramErr:
-			catc->stats.rx_frame_errors += data - last;
-			catc->stats.rx_errors += data - last;
+			catc->netdev->stats.rx_frame_errors += data - last;
+			catc->netdev->stats.rx_errors += data - last;
 			break;
 	}
 
@@ -614,12 +613,6 @@ static void catc_stats_timer(unsigned lo
 	mod_timer(&catc->timer, jiffies + STATS_UPDATE);
 }
 
-static struct net_device_stats *catc_get_stats(struct net_device *netdev)
-{
-	struct catc *catc = netdev_priv(netdev);
-	return &catc->stats;
-}
-
 /*
  * Receive modes. Broadcast, Multicast, Promisc.
  */
@@ -750,6 +743,18 @@ static int catc_stop(struct net_device *
 	return 0;
 }
 
+static const struct net_device_ops catc_netdev_ops = {
+	.ndo_open		= catc_open,
+	.ndo_stop		= catc_stop,
+	.ndo_start_xmit		= catc_start_xmit,
+
+	.ndo_tx_timeout		= catc_tx_timeout,
+	.ndo_set_multicast_list = catc_set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /*
  * USB probe, disconnect.
  */
@@ -774,13 +779,8 @@ static int catc_probe(struct usb_interfa
 
 	catc = netdev_priv(netdev);
 
-	netdev->open = catc_open;
-	netdev->hard_start_xmit = catc_hard_start_xmit;
-	netdev->stop = catc_stop;
-	netdev->get_stats = catc_get_stats;
-	netdev->tx_timeout = catc_tx_timeout;
+	netdev->netdev_ops = &catc_netdev_ops;
 	netdev->watchdog_timeo = TX_TIMEOUT;
-	netdev->set_multicast_list = catc_set_multicast_list;
 	SET_ETHTOOL_OPS(netdev, &ops);
 
 	catc->usbdev = usbdev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/cdc_eem.c linux-libre-2.6.30-gnu1/drivers/net/usb/cdc_eem.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/cdc_eem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/cdc_eem.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,381 @@
+/*
+ * USB CDC EEM network interface driver
+ * Copyright (C) 2009 Oberthur Technologies
+ * by Omar Laazimani, Olivier Condemine
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+
+
+/*
+ * This driver is an implementation of the CDC "Ethernet Emulation
+ * Model" (EEM) specification, which encapsulates Ethernet frames
+ * for transport over USB using a simpler USB device model than the
+ * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet").
+ *
+ * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf
+ *
+ * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24,
+ * 2.6.27 and 2.6.30rc2 kernel.
+ * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel).
+ * build on 23-April-2009
+ */
+
+#define EEM_HEAD	2		/* 2 byte header */
+
+/*-------------------------------------------------------------------------*/
+
+static void eem_linkcmd_complete(struct urb *urb)
+{
+	dev_kfree_skb(urb->context);
+	usb_free_urb(urb);
+}
+
+static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct urb		*urb;
+	int			status;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb)
+		goto fail;
+
+	usb_fill_bulk_urb(urb, dev->udev, dev->out,
+			skb->data, skb->len, eem_linkcmd_complete, skb);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status) {
+		usb_free_urb(urb);
+fail:
+		dev_kfree_skb(skb);
+		devwarn(dev, "link cmd failure\n");
+		return;
+	}
+}
+
+static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status = 0;
+
+	status = usbnet_get_endpoints(dev, intf);
+	if (status < 0) {
+		usb_set_intfdata(intf, NULL);
+		usb_driver_release_interface(driver_of(intf), intf);
+		return status;
+	}
+
+	/* no jumbogram (16K) support for now */
+
+	dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN;
+
+	return 0;
+}
+
+/*
+ * EEM permits packing multiple Ethernet frames into USB transfers
+ * (a "bundle"), but for TX we don't try to do that.
+ */
+static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+				       gfp_t flags)
+{
+	struct sk_buff	*skb2 = NULL;
+	u16		len = skb->len;
+	u32		crc = 0;
+	int		padlen = 0;
+
+	/* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is
+	 * zero, stick two bytes of zero length EEM packet on the end.
+	 * Else the framework would add invalid single byte padding,
+	 * since it can't know whether ZLPs will be handled right by
+	 * all the relevant hardware and software.
+	 */
+	if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket))
+		padlen += 2;
+
+	if (!skb_cloned(skb)) {
+		int	headroom = skb_headroom(skb);
+		int	tailroom = skb_tailroom(skb);
+
+		if ((tailroom >= ETH_FCS_LEN + padlen)
+				&& (headroom >= EEM_HEAD))
+			goto done;
+
+		if ((headroom + tailroom)
+				> (EEM_HEAD + ETH_FCS_LEN + padlen)) {
+			skb->data = memmove(skb->head +
+					EEM_HEAD,
+					skb->data,
+					skb->len);
+			skb_set_tail_pointer(skb, len);
+			goto done;
+		}
+	}
+
+	skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags);
+	if (!skb2)
+		return NULL;
+
+	dev_kfree_skb_any(skb);
+	skb = skb2;
+
+done:
+	/* we don't use the "no Ethernet CRC" option */
+	crc = crc32_le(~0, skb->data, skb->len);
+	crc = ~crc;
+
+	put_unaligned_le32(crc, skb_put(skb, 4));
+
+	/* EEM packet header format:
+	 * b0..13:	length of ethernet frame
+	 * b14:		bmCRC (1 == valid Ethernet CRC)
+	 * b15:		bmType (0 == data)
+	 */
+	len = skb->len;
+	put_unaligned_le16(BIT(14) | len, skb_push(skb, 2));
+
+	/* Bundle a zero length EEM packet if needed */
+	if (padlen)
+		put_unaligned_le16(0, skb_put(skb, 2));
+
+	return skb;
+}
+
+static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	/*
+	 * Our task here is to strip off framing, leaving skb with one
+	 * data frame for the usbnet framework code to process.  But we
+	 * may have received multiple EEM payloads, or command payloads.
+	 * So we must process _everything_ as if it's a header, except
+	 * maybe the last data payload
+	 *
+	 * REVISIT the framework needs updating so that when we consume
+	 * all payloads (the last or only message was a command, or a
+	 * zero length EEM packet) that is not accounted as an rx_error.
+	 */
+	do {
+		struct sk_buff	*skb2 = NULL;
+		u16		header;
+		u16		len = 0;
+
+		/* incomplete EEM header? */
+		if (skb->len < EEM_HEAD)
+			return 0;
+
+		/*
+		 * EEM packet header format:
+		 * b0..14:	EEM type dependant (Data or Command)
+		 * b15:		bmType
+		 */
+		header = get_unaligned_le16(skb->data);
+		skb_pull(skb, EEM_HEAD);
+
+		/*
+		 * The bmType bit helps to denote when EEM
+		 * packet is data or command :
+		 *	bmType = 0	: EEM data payload
+		 *	bmType = 1	: EEM (link) command
+		 */
+		if (header & BIT(15)) {
+			u16	bmEEMCmd;
+
+			/*
+			 * EEM (link) command packet:
+			 * b0..10:	bmEEMCmdParam
+			 * b11..13:	bmEEMCmd
+			 * b14:		bmReserved (must be 0)
+			 * b15:		1 (EEM command)
+			 */
+			if (header & BIT(14)) {
+				devdbg(dev, "reserved command %04x\n", header);
+				continue;
+			}
+
+			bmEEMCmd = (header >> 11) & 0x7;
+			switch (bmEEMCmd) {
+
+			/* Responding to echo requests is mandatory. */
+			case 0:		/* Echo command */
+				len = header & 0x7FF;
+
+				/* bogus command? */
+				if (skb->len < len)
+					return 0;
+
+				skb2 = skb_clone(skb, GFP_ATOMIC);
+				if (unlikely(!skb2))
+					goto next;
+				skb_trim(skb2, len);
+				put_unaligned_le16(BIT(15) | (1 << 11) | len,
+						skb_push(skb2, 2));
+				eem_linkcmd(dev, skb2);
+				break;
+
+			/*
+			 * Host may choose to ignore hints.
+			 *  - suspend: peripheral ready to suspend
+			 *  - response: suggest N millisec polling
+			 *  - response complete: suggest N sec polling
+			 */
+			case 2:		/* Suspend hint */
+			case 3:		/* Response hint */
+			case 4:		/* Response complete hint */
+				continue;
+
+			/*
+			 * Hosts should never receive host-to-peripheral
+			 * or reserved command codes; or responses to an
+			 * echo command we didn't send.
+			 */
+			case 1:		/* Echo response */
+			case 5:		/* Tickle */
+			default:	/* reserved */
+				devwarn(dev, "unexpected link command %d\n",
+						bmEEMCmd);
+				continue;
+			}
+
+		} else {
+			u32	crc, crc2;
+			int	is_last;
+
+			/* zero length EEM packet? */
+			if (header == 0)
+				continue;
+
+			/*
+			 * EEM data packet header :
+			 * b0..13:	length of ethernet frame
+			 * b14:		bmCRC
+			 * b15:		0 (EEM data)
+			 */
+			len = header & 0x3FFF;
+
+			/* bogus EEM payload? */
+			if (skb->len < len)
+				return 0;
+
+			/* bogus ethernet frame? */
+			if (len < (ETH_HLEN + ETH_FCS_LEN))
+				goto next;
+
+			/*
+			 * Treat the last payload differently: framework
+			 * code expects our "fixup" to have stripped off
+			 * headers, so "skb" is a data packet (or error).
+			 * Else if it's not the last payload, keep "skb"
+			 * for further processing.
+			 */
+			is_last = (len == skb->len);
+			if (is_last)
+				skb2 = skb;
+			else {
+				skb2 = skb_clone(skb, GFP_ATOMIC);
+				if (unlikely(!skb2))
+					return 0;
+			}
+
+			crc = get_unaligned_le32(skb2->data
+					+ len - ETH_FCS_LEN);
+			skb_trim(skb2, len - ETH_FCS_LEN);
+
+			/*
+			 * The bmCRC helps to denote when the CRC field in
+			 * the Ethernet frame contains a calculated CRC:
+			 *	bmCRC = 1	: CRC is calculated
+			 *	bmCRC = 0	: CRC = 0xDEADBEEF
+			 */
+			if (header & BIT(14))
+				crc2 = ~crc32_le(~0, skb2->data, len);
+			else
+				crc2 = 0xdeadbeef;
+
+			if (is_last)
+				return crc == crc2;
+
+			if (unlikely(crc != crc2)) {
+				dev->stats.rx_errors++;
+				dev_kfree_skb_any(skb2);
+			} else
+				usbnet_skb_return(dev, skb2);
+		}
+
+next:
+		skb_pull(skb, len);
+	} while (skb->len);
+
+	return 1;
+}
+
+static const struct driver_info eem_info = {
+	.description =	"CDC EEM Device",
+	.flags =	FLAG_ETHER,
+	.bind =		eem_bind,
+	.rx_fixup =	eem_rx_fixup,
+	.tx_fixup =	eem_tx_fixup,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products[] = {
+{
+	USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM,
+			USB_CDC_PROTO_EEM),
+	.driver_info = (unsigned long) &eem_info,
+},
+{
+	/* EMPTY == end of list */
+},
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver eem_driver = {
+	.name =		"cdc_eem",
+	.id_table =	products,
+	.probe =	usbnet_probe,
+	.disconnect =	usbnet_disconnect,
+	.suspend =	usbnet_suspend,
+	.resume =	usbnet_resume,
+};
+
+
+static int __init eem_init(void)
+{
+	return usb_register(&eem_driver);
+}
+module_init(eem_init);
+
+static void __exit eem_exit(void)
+{
+	usb_deregister(&eem_driver);
+}
+module_exit(eem_exit);
+
+MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>");
+MODULE_DESCRIPTION("USB CDC EEM");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/dm9601.c linux-libre-2.6.30-gnu1/drivers/net/usb/dm9601.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/dm9601.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/dm9601.c	2009-06-09 23:05:27.000000000 -0400
@@ -419,6 +419,18 @@ static int dm9601_set_mac_address(struct
 	return 0;
 }
 
+static const struct net_device_ops dm9601_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl 		= dm9601_ioctl,
+	.ndo_set_multicast_list = dm9601_set_multicast,
+	.ndo_set_mac_address	= dm9601_set_mac_address,
+};
+
 static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int ret;
@@ -428,9 +440,7 @@ static int dm9601_bind(struct usbnet *de
 	if (ret)
 		goto out;
 
-	dev->net->do_ioctl = dm9601_ioctl;
-	dev->net->set_multicast_list = dm9601_set_multicast;
-	dev->net->set_mac_address = dm9601_set_mac_address;
+	dev->net->netdev_ops = &dm9601_netdev_ops;
 	dev->net->ethtool_ops = &dm9601_ethtool_ops;
 	dev->net->hard_header_len += DM_TX_OVERHEAD;
 	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/hso.c linux-libre-2.6.30-gnu1/drivers/net/usb/hso.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/hso.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/hso.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,7 @@
  *  Copyright (C) 2008 Option International
  *                     Filip Aben <f.aben@option.com>
  *                     Denis Joseph Barrow <d.barow@option.com>
+ *                     Jan Dumon <j.dumon@option.com>
  *  Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd)
  *  			<ajb@spheresystems.co.uk>
  *  Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
@@ -462,9 +463,16 @@ static const struct usb_device_id hso_id
 	{USB_DEVICE(0x0af0, 0x7701)},
 	{USB_DEVICE(0x0af0, 0x7801)},
 	{USB_DEVICE(0x0af0, 0x7901)},
-	{USB_DEVICE(0x0af0, 0x7361)},
-	{USB_DEVICE(0x0af0, 0xd057)},
+	{USB_DEVICE(0x0af0, 0x8200)},
+	{USB_DEVICE(0x0af0, 0x8201)},
+	{USB_DEVICE(0x0af0, 0xd035)},
 	{USB_DEVICE(0x0af0, 0xd055)},
+	{USB_DEVICE(0x0af0, 0xd155)},
+	{USB_DEVICE(0x0af0, 0xd255)},
+	{USB_DEVICE(0x0af0, 0xd057)},
+	{USB_DEVICE(0x0af0, 0xd157)},
+	{USB_DEVICE(0x0af0, 0xd257)},
+	{USB_DEVICE(0x0af0, 0xd357)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, hso_ids);
@@ -936,8 +944,7 @@ static void packetizeRx(struct hso_net *
 			if (!odev->rx_buf_missing) {
 				/* Packet is complete. Inject into stack. */
 				/* We have IP packet here */
-				odev->skb_rx_buf->protocol =
-						__constant_htons(ETH_P_IP);
+				odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
 				/* don't check it */
 				odev->skb_rx_buf->ip_summed =
 					CHECKSUM_UNNECESSARY;
@@ -1247,7 +1254,7 @@ static void hso_std_serial_read_bulk_cal
  * This needs to be a tasklet otherwise we will
  * end up recursively calling this function.
  */
-void hso_unthrottle_tasklet(struct hso_serial *serial)
+static void hso_unthrottle_tasklet(struct hso_serial *serial)
 {
 	unsigned long flags;
 
@@ -1266,7 +1273,7 @@ static	void hso_unthrottle(struct tty_st
 	tasklet_hi_schedule(&serial->unthrottle_tasklet);
 }
 
-void hso_unthrottle_workfunc(struct work_struct *work)
+static void hso_unthrottle_workfunc(struct work_struct *work)
 {
 	struct hso_serial *serial =
 	    container_of(work, struct hso_serial,
@@ -1465,9 +1472,9 @@ static int hso_serial_chars_in_buffer(st
 
 	return chars;
 }
-int tiocmget_submit_urb(struct hso_serial *serial,
-			struct hso_tiocmget  *tiocmget,
-			struct usb_device *usb)
+static int tiocmget_submit_urb(struct hso_serial *serial,
+			       struct hso_tiocmget *tiocmget,
+			       struct usb_device *usb)
 {
 	int result;
 
@@ -2364,12 +2371,6 @@ exit:
 	return -1;
 }
 
-/* Frees a general hso device */
-static void hso_free_device(struct hso_device *hso_dev)
-{
-	kfree(hso_dev);
-}
-
 /* Creates a general hso device */
 static struct hso_device *hso_create_device(struct usb_interface *intf,
 					    int port_spec)
@@ -2417,24 +2418,33 @@ static void hso_free_net_device(struct h
 	if (!hso_net)
 		return;
 
+	remove_net_device(hso_net->parent);
+
+	if (hso_net->net) {
+		unregister_netdev(hso_net->net);
+		free_netdev(hso_net->net);
+	}
+
 	/* start freeing */
 	for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
 		usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
 		kfree(hso_net->mux_bulk_rx_buf_pool[i]);
+		hso_net->mux_bulk_rx_buf_pool[i] = NULL;
 	}
 	usb_free_urb(hso_net->mux_bulk_tx_urb);
 	kfree(hso_net->mux_bulk_tx_buf);
+	hso_net->mux_bulk_tx_buf = NULL;
 
-	remove_net_device(hso_net->parent);
-
-	if (hso_net->net) {
-		unregister_netdev(hso_net->net);
-		free_netdev(hso_net->net);
-	}
-
-	hso_free_device(hso_dev);
+	kfree(hso_dev);
 }
 
+static const struct net_device_ops hso_netdev_ops = {
+	.ndo_open	= hso_net_open,
+	.ndo_stop	= hso_net_close,
+	.ndo_start_xmit = hso_net_start_xmit,
+	.ndo_tx_timeout = hso_net_tx_timeout,
+};
+
 /* initialize the network interface */
 static void hso_net_init(struct net_device *net)
 {
@@ -2443,10 +2453,7 @@ static void hso_net_init(struct net_devi
 	D1("sizeof hso_net is %d", (int)sizeof(*hso_net));
 
 	/* fill in the other fields */
-	net->open = hso_net_open;
-	net->stop = hso_net_close;
-	net->hard_start_xmit = hso_net_start_xmit;
-	net->tx_timeout = hso_net_tx_timeout;
+	net->netdev_ops = &hso_netdev_ops;
 	net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
 	net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
 	net->type = ARPHRD_NONE;
@@ -2529,14 +2536,15 @@ static void hso_create_rfkill(struct hso
 }
 
 /* Creates our network device */
-static struct hso_device *hso_create_net_device(struct usb_interface *interface)
+static struct hso_device *hso_create_net_device(struct usb_interface *interface,
+						int port_spec)
 {
 	int result, i;
 	struct net_device *net;
 	struct hso_net *hso_net;
 	struct hso_device *hso_dev;
 
-	hso_dev = hso_create_device(interface, HSO_INTF_MUX | HSO_PORT_NETWORK);
+	hso_dev = hso_create_device(interface, port_spec);
 	if (!hso_dev)
 		return NULL;
 
@@ -2616,12 +2624,12 @@ static void hso_free_tiomget(struct hso_
 {
 	struct hso_tiocmget *tiocmget = serial->tiocmget;
 	if (tiocmget) {
-		kfree(tiocmget);
 		if (tiocmget->urb) {
 			usb_free_urb(tiocmget->urb);
 			tiocmget->urb = NULL;
 		}
 		serial->tiocmget = NULL;
+		kfree(tiocmget);
 
 	}
 }
@@ -2646,7 +2654,7 @@ static void hso_free_serial_device(struc
 	}
 	hso_free_tiomget(serial);
 	kfree(serial);
-	hso_free_device(hso_dev);
+	kfree(hso_dev);
 }
 
 /* Creates a bulk AT channel */
@@ -2727,7 +2735,7 @@ exit2:
 exit:
 	hso_free_tiomget(serial);
 	kfree(serial);
-	hso_free_device(hso_dev);
+	kfree(hso_dev);
 	return NULL;
 }
 
@@ -2786,7 +2794,7 @@ exit:
 		kfree(serial);
 	}
 	if (hso_dev)
-		hso_free_device(hso_dev);
+		kfree(hso_dev);
 	return NULL;
 
 }
@@ -2936,7 +2944,8 @@ static int hso_probe(struct usb_interfac
 		if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
 			/* Create the network device */
 			if (!disable_net) {
-				hso_dev = hso_create_net_device(interface);
+				hso_dev = hso_create_net_device(interface,
+								port_spec);
 				if (!hso_dev)
 					goto exit;
 				tmp_dev = hso_dev;
@@ -2968,7 +2977,7 @@ static int hso_probe(struct usb_interfac
 		/* It's a regular bulk interface */
 		if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK)
 		    && !disable_net)
-			hso_dev = hso_create_net_device(interface);
+			hso_dev = hso_create_net_device(interface, port_spec);
 		else
 			hso_dev =
 			    hso_create_bulk_serial_device(interface, port_spec);
@@ -2979,8 +2988,6 @@ static int hso_probe(struct usb_interfac
 		goto exit;
 	}
 
-	usb_driver_claim_interface(&hso_driver, interface, hso_dev);
-
 	/* save our data pointer in this device */
 	usb_set_intfdata(interface, hso_dev);
 
@@ -2998,8 +3005,6 @@ static void hso_disconnect(struct usb_in
 
 	/* remove reference of our private data */
 	usb_set_intfdata(interface, NULL);
-
-	usb_driver_release_interface(&hso_driver, interface);
 }
 
 static void async_get_intf(struct work_struct *data)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/kaweth.c linux-libre-2.6.30-gnu1/drivers/net/usb/kaweth.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/kaweth.c	2013-05-03 18:03:57.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/kaweth.c	2013-05-03 16:47:46.000000000 -0400
@@ -36,7 +36,6 @@
  * Run test procedures
  * Fix bugs from previous two steps
  * Snoop other OSs for any tricks we're not doing
- * SMP locking
  * Reduce arbitrary timeouts
  * Smart multicast support
  * Temporary MAC change support
@@ -793,7 +792,7 @@ static int kaweth_start_xmit(struct sk_b
 
 	int res;
 
-	spin_lock(&kaweth->device_lock);
+	spin_lock_irq(&kaweth->device_lock);
 
 	kaweth_async_set_rx_mode(kaweth);
 	netif_stop_queue(net);
@@ -811,7 +810,7 @@ static int kaweth_start_xmit(struct sk_b
 		if (!copied_skb) {
 			kaweth->stats.tx_errors++;
 			netif_start_queue(net);
-			spin_unlock(&kaweth->device_lock);
+			spin_unlock_irq(&kaweth->device_lock);
 			return 0;
 		}
 	}
@@ -845,7 +844,7 @@ skip:
 		net->trans_start = jiffies;
 	}
 
-	spin_unlock(&kaweth->device_lock);
+	spin_unlock_irq(&kaweth->device_lock);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/Kconfig linux-libre-2.6.30-gnu1/drivers/net/usb/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/usb/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -180,6 +180,20 @@ config USB_NET_CDCETHER
 	  IEEE 802 "local assignment" bit is set in the address, a "usbX"
 	  name is used instead.
 
+config USB_NET_CDC_EEM
+	tristate "CDC EEM support"
+	depends on USB_USBNET && EXPERIMENTAL
+	help
+	  This option supports devices conforming to the Communication Device
+	  Class (CDC) Ethernet Emulation Model, a specification that's easy to
+	  implement in device firmware.  The CDC EEM specifications are available
+	  from <http://www.usb.org/>.
+
+	  This driver creates an interface named "ethX", where X depends on
+	  what other networking devices you have in use.  However, if the
+	  IEEE 802 "local assignment" bit is set in the address, a "usbX"
+	  name is used instead.
+
 config USB_NET_DM9601
 	tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
 	depends on USB_USBNET
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/Makefile linux-libre-2.6.30-gnu1/drivers/net/usb/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/usb/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
 obj-$(CONFIG_USB_HSO)		+= hso.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
+obj-$(CONFIG_USB_NET_CDC_EEM)	+= cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
 obj-$(CONFIG_USB_NET_SMSC95XX)	+= smsc95xx.o
 obj-$(CONFIG_USB_NET_GL620A)	+= gl620a.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/mcs7830.c linux-libre-2.6.30-gnu1/drivers/net/usb/mcs7830.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/mcs7830.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/mcs7830.c	2009-06-09 23:05:27.000000000 -0400
@@ -486,6 +486,18 @@ static int mcs7830_set_mac_address(struc
 	return 0;
 }
 
+static const struct net_device_ops mcs7830_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl 		= mcs7830_ioctl,
+	.ndo_set_multicast_list = mcs7830_set_multicast,
+	.ndo_set_mac_address	 = mcs7830_set_mac_address,
+};
+
 static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
 {
 	struct net_device *net = dev->net;
@@ -495,11 +507,9 @@ static int mcs7830_bind(struct usbnet *d
 	if (ret)
 		goto out;
 
-	net->do_ioctl = mcs7830_ioctl;
 	net->ethtool_ops = &mcs7830_ethtool_ops;
-	net->set_multicast_list = mcs7830_set_multicast;
+	net->netdev_ops = &mcs7830_netdev_ops;
 	mcs7830_set_multicast(net);
-	net->set_mac_address = mcs7830_set_mac_address;
 
 	/* reserve space for the status byte on rx */
 	dev->rx_urb_size = ETH_FRAME_LEN + 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/pegasus.c linux-libre-2.6.30-gnu1/drivers/net/usb/pegasus.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/pegasus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/pegasus.c	2009-06-09 23:05:27.000000000 -0400
@@ -899,6 +899,7 @@ static int pegasus_start_xmit(struct sk_
 			/* cleanup should already have been scheduled */
 			break;
 		case -ENODEV:		/* disconnect() upcoming */
+		case -EPERM:
 			netif_device_detach(pegasus->net);
 			break;
 		default:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/rndis_host.c linux-libre-2.6.30-gnu1/drivers/net/usb/rndis_host.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/rndis_host.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/rndis_host.c	2009-06-09 23:05:27.000000000 -0400
@@ -169,7 +169,7 @@ int rndis_command(struct usbnet *dev, st
 				struct rndis_keepalive_c *msg = (void *)buf;
 
 				msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
-				msg->msg_len = ccpu2(sizeof *msg);
+				msg->msg_len = cpu_to_le32(sizeof *msg);
 				msg->status = RNDIS_STATUS_SUCCESS;
 				retval = usb_control_msg(dev->udev,
 					usb_sndctrlpipe(dev->udev, 0),
@@ -237,7 +237,7 @@ static int rndis_query(struct usbnet *de
 	u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
 	u.get->oid = oid;
 	u.get->len = cpu_to_le32(in_len);
-	u.get->offset = ccpu2(20);
+	u.get->offset = cpu_to_le32(20);
 
 	retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
 	if (unlikely(retval < 0)) {
@@ -266,6 +266,16 @@ response_error:
 	return -EDOM;
 }
 
+/* same as usbnet_netdev_ops but MTU change not allowed */
+static const struct net_device_ops rndis_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 int
 generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
 {
@@ -297,9 +307,9 @@ generic_rndis_bind(struct usbnet *dev, s
 		goto fail;
 
 	u.init->msg_type = RNDIS_MSG_INIT;
-	u.init->msg_len = ccpu2(sizeof *u.init);
-	u.init->major_version = ccpu2(1);
-	u.init->minor_version = ccpu2(0);
+	u.init->msg_len = cpu_to_le32(sizeof *u.init);
+	u.init->major_version = cpu_to_le32(1);
+	u.init->minor_version = cpu_to_le32(0);
 
 	/* max transfer (in spec) is 0x4000 at full speed, but for
 	 * TX we'll stick to one Ethernet packet plus RNDIS framing.
@@ -327,7 +337,8 @@ generic_rndis_bind(struct usbnet *dev, s
 	dev->rx_urb_size &= ~(dev->maxpacket - 1);
 	u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
 
-	net->change_mtu = NULL;
+	net->netdev_ops = &rndis_netdev_ops;
+
 	retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
 	if (unlikely(retval < 0)) {
 		/* it might not even be an RNDIS device!! */
@@ -403,10 +414,10 @@ generic_rndis_bind(struct usbnet *dev, s
 	/* set a nonzero filter to enable data transfers */
 	memset(u.set, 0, sizeof *u.set);
 	u.set->msg_type = RNDIS_MSG_SET;
-	u.set->msg_len = ccpu2(4 + sizeof *u.set);
+	u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
 	u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
-	u.set->len = ccpu2(4);
-	u.set->offset = ccpu2((sizeof *u.set) - 8);
+	u.set->len = cpu_to_le32(4);
+	u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
 	*(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
 
 	retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
@@ -423,7 +434,7 @@ generic_rndis_bind(struct usbnet *dev, s
 halt_fail_and_release:
 	memset(u.halt, 0, sizeof *u.halt);
 	u.halt->msg_type = RNDIS_MSG_HALT;
-	u.halt->msg_len = ccpu2(sizeof *u.halt);
+	u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
 	(void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
 fail_and_release:
 	usb_set_intfdata(info->data, NULL);
@@ -448,7 +459,7 @@ void rndis_unbind(struct usbnet *dev, st
 	halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
 	if (halt) {
 		halt->msg_type = RNDIS_MSG_HALT;
-		halt->msg_len = ccpu2(sizeof *halt);
+		halt->msg_len = cpu_to_le32(sizeof *halt);
 		(void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
 		kfree(halt);
 	}
@@ -543,7 +554,7 @@ fill:
 	memset(hdr, 0, sizeof *hdr);
 	hdr->msg_type = RNDIS_MSG_PACKET;
 	hdr->msg_len = cpu_to_le32(skb->len);
-	hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
+	hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
 	hdr->data_len = cpu_to_le32(len);
 
 	/* FIXME make the last packet always be short ... */
@@ -562,9 +573,6 @@ static const struct driver_info	rndis_in
 	.tx_fixup =	rndis_tx_fixup,
 };
 
-#undef ccpu2
-
-
 /*-------------------------------------------------------------------------*/
 
 static const struct usb_device_id	products [] = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/rtl8150.c linux-libre-2.6.30-gnu1/drivers/net/usb/rtl8150.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/rtl8150.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/rtl8150.c	2009-06-09 23:05:27.000000000 -0400
@@ -155,7 +155,6 @@ struct rtl8150 {
 	unsigned long flags;
 	struct usb_device *udev;
 	struct tasklet_struct tl;
-	struct net_device_stats stats;
 	struct net_device *netdev;
 	struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
 	struct sk_buff *tx_skb, *rx_skb;
@@ -463,8 +462,8 @@ static void read_bulk_callback(struct ur
 	skb_put(dev->rx_skb, pkt_len);
 	dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev);
 	netif_rx(dev->rx_skb);
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += pkt_len;
+	netdev->stats.rx_packets++;
+	netdev->stats.rx_bytes += pkt_len;
 
 	spin_lock(&dev->rx_pool_lock);
 	skb = pull_skb(dev);
@@ -573,13 +572,13 @@ static void intr_callback(struct urb *ur
 
 	d = urb->transfer_buffer;
 	if (d[0] & TSR_ERRORS) {
-		dev->stats.tx_errors++;
+		dev->netdev->stats.tx_errors++;
 		if (d[INT_TSR] & (TSR_ECOL | TSR_JBR))
-			dev->stats.tx_aborted_errors++;
+			dev->netdev->stats.tx_aborted_errors++;
 		if (d[INT_TSR] & TSR_LCOL)
-			dev->stats.tx_window_errors++;
+			dev->netdev->stats.tx_window_errors++;
 		if (d[INT_TSR] & TSR_LOSS_CRS)
-			dev->stats.tx_carrier_errors++;
+			dev->netdev->stats.tx_carrier_errors++;
 	}
 	/* Report link status changes to the network stack */
 	if ((d[INT_MSR] & MSR_LINK) == 0) {
@@ -697,17 +696,12 @@ static void disable_net_traffic(rtl8150_
 	set_registers(dev, CR, 1, &cr);
 }
 
-static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
-{
-	return &((rtl8150_t *)netdev_priv(dev))->stats;
-}
-
 static void rtl8150_tx_timeout(struct net_device *netdev)
 {
 	rtl8150_t *dev = netdev_priv(netdev);
 	dev_warn(&netdev->dev, "Tx timeout.\n");
 	usb_unlink_urb(dev->tx_urb);
-	dev->stats.tx_errors++;
+	netdev->stats.tx_errors++;
 }
 
 static void rtl8150_set_multicast(struct net_device *netdev)
@@ -747,12 +741,12 @@ static int rtl8150_start_xmit(struct sk_
 			netif_device_detach(dev->netdev);
 		else {
 			dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
-			dev->stats.tx_errors++;
+			netdev->stats.tx_errors++;
 			netif_start_queue(netdev);
 		}
 	} else {
-		dev->stats.tx_packets++;
-		dev->stats.tx_bytes += skb->len;
+		netdev->stats.tx_packets++;
+		netdev->stats.tx_bytes += skb->len;
 		netdev->trans_start = jiffies;
 	}
 
@@ -897,6 +891,19 @@ static int rtl8150_ioctl(struct net_devi
 	return res;
 }
 
+static const struct net_device_ops rtl8150_netdev_ops = {
+	.ndo_open		= rtl8150_open,
+	.ndo_stop		= rtl8150_close,
+	.ndo_do_ioctl		= rtl8150_ioctl,
+	.ndo_start_xmit		= rtl8150_start_xmit,
+	.ndo_tx_timeout 	= rtl8150_tx_timeout,
+	.ndo_set_multicast_list = rtl8150_set_multicast,
+	.ndo_set_mac_address	= rtl8150_set_mac_address,
+
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int rtl8150_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
 {
@@ -923,15 +930,8 @@ static int rtl8150_probe(struct usb_inte
 	
 	dev->udev = udev;
 	dev->netdev = netdev;
-	netdev->open = rtl8150_open;
-	netdev->stop = rtl8150_close;
-	netdev->do_ioctl = rtl8150_ioctl;
+	netdev->netdev_ops = &rtl8150_netdev_ops;
 	netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
-	netdev->tx_timeout = rtl8150_tx_timeout;
-	netdev->hard_start_xmit = rtl8150_start_xmit;
-	netdev->set_multicast_list = rtl8150_set_multicast;
-	netdev->set_mac_address = rtl8150_set_mac_address;
-	netdev->get_stats = rtl8150_netdev_stats;
 	SET_ETHTOOL_OPS(netdev, &ops);
 	dev->intr_interval = 100;	/* 100ms */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/smsc95xx.c linux-libre-2.6.30-gnu1/drivers/net/usb/smsc95xx.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/smsc95xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/smsc95xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,11 +55,10 @@ struct smsc95xx_priv {
 
 struct usb_context {
 	struct usb_ctrlrequest req;
-	struct completion notify;
 	struct usbnet *dev;
 };
 
-int turbo_mode = true;
+static int turbo_mode = true;
 module_param(turbo_mode, bool, 0644);
 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
 
@@ -307,7 +306,7 @@ static int smsc95xx_write_eeprom(struct
 	return 0;
 }
 
-static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+static void smsc95xx_async_cmd_callback(struct urb *urb)
 {
 	struct usb_context *usb_context = urb->context;
 	struct usbnet *dev = usb_context->dev;
@@ -316,8 +315,6 @@ static void smsc95xx_async_cmd_callback(
 	if (status < 0)
 		devwarn(dev, "async callback failed with %d", status);
 
-	complete(&usb_context->notify);
-
 	kfree(usb_context);
 	usb_free_urb(urb);
 }
@@ -348,11 +345,10 @@ static int smsc95xx_write_reg_async(stru
 	usb_context->req.wValue = 00;
 	usb_context->req.wIndex = cpu_to_le16(index);
 	usb_context->req.wLength = cpu_to_le16(size);
-	init_completion(&usb_context->notify);
 
 	usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
 		(void *)&usb_context->req, data, size,
-		(usb_complete_t)smsc95xx_async_cmd_callback,
+		smsc95xx_async_cmd_callback,
 		(void *)usb_context);
 
 	status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -945,6 +941,16 @@ static int smsc95xx_reset(struct usbnet
 	if (netif_msg_ifup(dev))
 		devdbg(dev, "ID_REV = 0x%08x", read_buf);
 
+	/* Configure GPIO pins as LED outputs */
+	write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
+		LED_GPIO_CFG_FDX_LED;
+	ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
+	if (ret < 0) {
+		devwarn(dev, "Failed to write LED_GPIO_CFG register, ret=%d",
+			ret);
+		return ret;
+	}
+
 	/* Init Tx */
 	write_buf = 0;
 	ret = smsc95xx_write_reg(dev, FLOW, write_buf);
@@ -1012,6 +1018,18 @@ static int smsc95xx_reset(struct usbnet
 	return 0;
 }
 
+static const struct net_device_ops smsc95xx_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl 		= smsc95xx_ioctl,
+	.ndo_set_multicast_list = smsc95xx_set_multicast,
+};
+
 static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	struct smsc95xx_priv *pdata = NULL;
@@ -1042,9 +1060,8 @@ static int smsc95xx_bind(struct usbnet *
 	/* Init all registers */
 	ret = smsc95xx_reset(dev);
 
-	dev->net->do_ioctl = smsc95xx_ioctl;
+	dev->net->netdev_ops = &smsc95xx_netdev_ops;
 	dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
-	dev->net->set_multicast_list = smsc95xx_set_multicast;
 	dev->net->flags |= IFF_MULTICAST;
 	dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD;
 	return 0;
@@ -1224,6 +1241,11 @@ static const struct usb_device_id produc
 		USB_DEVICE(0x0424, 0x9500),
 		.driver_info = (unsigned long) &smsc95xx_info,
 	},
+	{
+		/* SMSC9512/9514 USB Hub & Ethernet Device */
+		USB_DEVICE(0x0424, 0xec00),
+		.driver_info = (unsigned long) &smsc95xx_info,
+	},
 	{ },		/* END */
 };
 MODULE_DEVICE_TABLE(usb, products);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/smsc95xx.h linux-libre-2.6.30-gnu1/drivers/net/usb/smsc95xx.h
--- linux-libre-2.6.29-gnu1/drivers/net/usb/smsc95xx.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/smsc95xx.h	2009-06-09 23:05:27.000000000 -0400
@@ -99,6 +99,9 @@
 #define PM_CTL_WUPS_MULTI_		(0x00000003)
 
 #define LED_GPIO_CFG			(0x24)
+#define LED_GPIO_CFG_SPD_LED		(0x01000000)
+#define LED_GPIO_CFG_LNK_LED		(0x00100000)
+#define LED_GPIO_CFG_FDX_LED		(0x00010000)
 
 #define GPIO_CFG			(0x28)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/usb/usbnet.c linux-libre-2.6.30-gnu1/drivers/net/usb/usbnet.c
--- linux-libre-2.6.29-gnu1/drivers/net/usb/usbnet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/usb/usbnet.c	2009-06-09 23:05:27.000000000 -0400
@@ -223,7 +223,7 @@ EXPORT_SYMBOL_GPL(usbnet_skb_return);
  *
  *-------------------------------------------------------------------------*/
 
-static int usbnet_change_mtu (struct net_device *net, int new_mtu)
+int usbnet_change_mtu (struct net_device *net, int new_mtu)
 {
 	struct usbnet	*dev = netdev_priv(net);
 	int		ll_mtu = new_mtu + net->hard_header_len;
@@ -246,14 +246,7 @@ static int usbnet_change_mtu (struct net
 
 	return 0;
 }
-
-/*-------------------------------------------------------------------------*/
-
-static struct net_device_stats *usbnet_get_stats (struct net_device *net)
-{
-	struct usbnet	*dev = netdev_priv(net);
-	return &dev->stats;
-}
+EXPORT_SYMBOL_GPL(usbnet_change_mtu);
 
 /*-------------------------------------------------------------------------*/
 
@@ -548,7 +541,7 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs)
 
 // precondition: never called in_interrupt
 
-static int usbnet_stop (struct net_device *net)
+int usbnet_stop (struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 	int			temp;
@@ -592,6 +585,7 @@ static int usbnet_stop (struct net_devic
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_stop);
 
 /*-------------------------------------------------------------------------*/
 
@@ -599,7 +593,7 @@ static int usbnet_stop (struct net_devic
 
 // precondition: never called in_interrupt
 
-static int usbnet_open (struct net_device *net)
+int usbnet_open (struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 	int			retval;
@@ -674,6 +668,7 @@ done:
 done_nopm:
 	return retval;
 }
+EXPORT_SYMBOL_GPL(usbnet_open);
 
 /*-------------------------------------------------------------------------*/
 
@@ -908,7 +903,7 @@ static void tx_complete (struct urb *urb
 
 /*-------------------------------------------------------------------------*/
 
-static void usbnet_tx_timeout (struct net_device *net)
+void usbnet_tx_timeout (struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 
@@ -917,10 +912,11 @@ static void usbnet_tx_timeout (struct ne
 
 	// FIXME: device recovery -- reset?
 }
+EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
 
 /*-------------------------------------------------------------------------*/
 
-static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
+int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 	int			length;
@@ -1003,7 +999,7 @@ drop:
 	}
 	return retval;
 }
-
+EXPORT_SYMBOL_GPL(usbnet_start_xmit);
 
 /*-------------------------------------------------------------------------*/
 
@@ -1110,6 +1106,15 @@ void usbnet_disconnect (struct usb_inter
 }
 EXPORT_SYMBOL_GPL(usbnet_disconnect);
 
+static const struct net_device_ops usbnet_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 /*-------------------------------------------------------------------------*/
 
@@ -1175,17 +1180,18 @@ usbnet_probe (struct usb_interface *udev
 #if 0
 // dma_supported() is deeply broken on almost all architectures
 	// possible with some EHCI controllers
-	if (dma_supported (&udev->dev, DMA_64BIT_MASK))
+	if (dma_supported (&udev->dev, DMA_BIT_MASK(64)))
 		net->features |= NETIF_F_HIGHDMA;
 #endif
 
-	net->change_mtu = usbnet_change_mtu;
-	net->get_stats = usbnet_get_stats;
+	net->netdev_ops = &usbnet_netdev_ops;
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
 	net->hard_start_xmit = usbnet_start_xmit;
 	net->open = usbnet_open;
 	net->stop = usbnet_stop;
-	net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
 	net->tx_timeout = usbnet_tx_timeout;
+#endif
+	net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
 	net->ethtool_ops = &usbnet_ethtool_ops;
 
 	// allow device-specific bind/init procedures
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/veth.c linux-libre-2.6.30-gnu1/drivers/net/veth.c
--- linux-libre-2.6.29-gnu1/drivers/net/veth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/veth.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,12 +19,17 @@
 #define DRV_NAME	"veth"
 #define DRV_VERSION	"1.0"
 
+#define MIN_MTU 68		/* Min L3 MTU */
+#define MAX_MTU 65535		/* Max L3 MTU (arbitrary) */
+#define MTU_PAD (ETH_HLEN + 4)  /* Max difference between L2 and L3 size MTU */
+
 struct veth_net_stats {
 	unsigned long	rx_packets;
 	unsigned long	tx_packets;
 	unsigned long	rx_bytes;
 	unsigned long	tx_bytes;
 	unsigned long	tx_dropped;
+	unsigned long	rx_dropped;
 };
 
 struct veth_priv {
@@ -147,7 +152,7 @@ static int veth_xmit(struct sk_buff *skb
 {
 	struct net_device *rcv = NULL;
 	struct veth_priv *priv, *rcv_priv;
-	struct veth_net_stats *stats;
+	struct veth_net_stats *stats, *rcv_stats;
 	int length, cpu;
 
 	skb_orphan(skb);
@@ -158,9 +163,13 @@ static int veth_xmit(struct sk_buff *skb
 
 	cpu = smp_processor_id();
 	stats = per_cpu_ptr(priv->stats, cpu);
+	rcv_stats = per_cpu_ptr(rcv_priv->stats, cpu);
 
 	if (!(rcv->flags & IFF_UP))
-		goto outf;
+		goto tx_drop;
+
+	if (skb->len > (rcv->mtu + MTU_PAD))
+		goto rx_drop;
 
 	skb->pkt_type = PACKET_HOST;
 	skb->protocol = eth_type_trans(skb, rcv);
@@ -178,17 +187,21 @@ static int veth_xmit(struct sk_buff *skb
 	stats->tx_bytes += length;
 	stats->tx_packets++;
 
-	stats = per_cpu_ptr(rcv_priv->stats, cpu);
-	stats->rx_bytes += length;
-	stats->rx_packets++;
+	rcv_stats->rx_bytes += length;
+	rcv_stats->rx_packets++;
 
 	netif_rx(skb);
 	return 0;
 
-outf:
+tx_drop:
 	kfree_skb(skb);
 	stats->tx_dropped++;
 	return 0;
+
+rx_drop:
+	kfree_skb(skb);
+	rcv_stats->rx_dropped++;
+	return 0;
 }
 
 /*
@@ -197,29 +210,29 @@ outf:
 
 static struct net_device_stats *veth_get_stats(struct net_device *dev)
 {
-	struct veth_priv *priv;
-	struct net_device_stats *dev_stats;
-	int cpu;
+	struct veth_priv *priv = netdev_priv(dev);
+	struct net_device_stats *dev_stats = &dev->stats;
+	unsigned int cpu;
 	struct veth_net_stats *stats;
 
-	priv = netdev_priv(dev);
-	dev_stats = &dev->stats;
-
 	dev_stats->rx_packets = 0;
 	dev_stats->tx_packets = 0;
 	dev_stats->rx_bytes = 0;
 	dev_stats->tx_bytes = 0;
 	dev_stats->tx_dropped = 0;
+	dev_stats->rx_dropped = 0;
 
-	for_each_online_cpu(cpu) {
-		stats = per_cpu_ptr(priv->stats, cpu);
+	if (priv->stats)
+		for_each_online_cpu(cpu) {
+			stats = per_cpu_ptr(priv->stats, cpu);
 
-		dev_stats->rx_packets += stats->rx_packets;
-		dev_stats->tx_packets += stats->tx_packets;
-		dev_stats->rx_bytes += stats->rx_bytes;
-		dev_stats->tx_bytes += stats->tx_bytes;
-		dev_stats->tx_dropped += stats->tx_dropped;
-	}
+			dev_stats->rx_packets += stats->rx_packets;
+			dev_stats->tx_packets += stats->tx_packets;
+			dev_stats->rx_bytes += stats->rx_bytes;
+			dev_stats->tx_bytes += stats->tx_bytes;
+			dev_stats->tx_dropped += stats->tx_dropped;
+			dev_stats->rx_dropped += stats->rx_dropped;
+		}
 
 	return dev_stats;
 }
@@ -246,6 +259,21 @@ static int veth_close(struct net_device
 	netif_carrier_off(dev);
 	netif_carrier_off(priv->peer);
 
+	free_percpu(priv->stats);
+	priv->stats = NULL;
+	return 0;
+}
+
+static int is_valid_veth_mtu(int new_mtu)
+{
+	return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU);
+}
+
+static int veth_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if (!is_valid_veth_mtu(new_mtu))
+		return -EINVAL;
+	dev->mtu = new_mtu;
 	return 0;
 }
 
@@ -263,20 +291,12 @@ static int veth_dev_init(struct net_devi
 	return 0;
 }
 
-static void veth_dev_free(struct net_device *dev)
-{
-	struct veth_priv *priv;
-
-	priv = netdev_priv(dev);
-	free_percpu(priv->stats);
-	free_netdev(dev);
-}
-
 static const struct net_device_ops veth_netdev_ops = {
 	.ndo_init            = veth_dev_init,
 	.ndo_open            = veth_open,
 	.ndo_stop            = veth_close,
 	.ndo_start_xmit      = veth_xmit,
+	.ndo_change_mtu      = veth_change_mtu,
 	.ndo_get_stats       = veth_get_stats,
 	.ndo_set_mac_address = eth_mac_addr,
 };
@@ -288,7 +308,7 @@ static void veth_setup(struct net_device
 	dev->netdev_ops = &veth_netdev_ops;
 	dev->ethtool_ops = &veth_ethtool_ops;
 	dev->features |= NETIF_F_LLTX;
-	dev->destructor = veth_dev_free;
+	dev->destructor = free_netdev;
 }
 
 /*
@@ -303,6 +323,10 @@ static int veth_validate(struct nlattr *
 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
 			return -EADDRNOTAVAIL;
 	}
+	if (tb[IFLA_MTU]) {
+		if (!is_valid_veth_mtu(nla_get_u32(tb[IFLA_MTU])))
+			return -EINVAL;
+	}
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/via-rhine.c linux-libre-2.6.30-gnu1/drivers/net/via-rhine.c
--- linux-libre-2.6.29-gnu1/drivers/net/via-rhine.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/via-rhine.c	2009-06-09 23:05:27.000000000 -0400
@@ -109,8 +109,9 @@ static const int multicast_filter_limit
 #include <linux/dmi.h>
 
 /* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+	KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
+	" Written by Donald Becker\n";
 
 /* This driver was written to use PCI memory space. Some early versions
    of the Rhine may only work correctly with I/O space accesses. */
@@ -589,7 +590,7 @@ static int rhine_napipoll(struct napi_st
 	work_done = rhine_rx(dev, budget);
 
 	if (work_done < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 
 		iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
 			  IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
@@ -685,7 +686,7 @@ static int __devinit rhine_init_one(stru
 		goto err_out;
 
 	/* this should always be supported */
-	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
 		printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
 		       "the card!?\n");
@@ -1319,7 +1320,7 @@ static irqreturn_t rhine_interrupt(int i
 				  IntrPCIErr | IntrStatsMax | IntrLinkChange,
 				  ioaddr + IntrEnable);
 
-			netif_rx_schedule(&rp->napi);
+			napi_schedule(&rp->napi);
 		}
 
 		if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/via-velocity.c linux-libre-2.6.30-gnu1/drivers/net/via-velocity.c
--- linux-libre-2.6.29-gnu1/drivers/net/via-velocity.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/via-velocity.c	2009-06-09 23:05:27.000000000 -0400
@@ -377,7 +377,7 @@ static void velocity_print_info(struct v
 static int velocity_open(struct net_device *dev);
 static int velocity_change_mtu(struct net_device *dev, int mtu);
 static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
-static int velocity_intr(int irq, void *dev_instance);
+static irqreturn_t velocity_intr(int irq, void *dev_instance);
 static void velocity_set_multi(struct net_device *dev);
 static struct net_device_stats *velocity_get_stats(struct net_device *dev);
 static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -2215,7 +2215,7 @@ out:
  *	efficiently as possible.
  */
 
-static int velocity_intr(int irq, void *dev_instance)
+static irqreturn_t velocity_intr(int irq, void *dev_instance)
 {
 	struct net_device *dev = dev_instance;
 	struct velocity_info *vptr = netdev_priv(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/via-velocity.h linux-libre-2.6.30-gnu1/drivers/net/via-velocity.h
--- linux-libre-2.6.29-gnu1/drivers/net/via-velocity.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/via-velocity.h	2009-06-09 23:05:27.000000000 -0400
@@ -183,7 +183,7 @@ struct rdesc1 {
 };
 
 enum {
-	RX_INTEN = __constant_cpu_to_le16(0x8000)
+	RX_INTEN = cpu_to_le16(0x8000)
 };
 
 struct rx_desc {
@@ -210,7 +210,7 @@ struct tdesc1 {
 } __attribute__ ((__packed__));
 
 enum {
-	TD_QUEUE = __constant_cpu_to_le16(0x8000)
+	TD_QUEUE = cpu_to_le16(0x8000)
 };
 
 struct td_buf {
@@ -242,7 +242,7 @@ struct velocity_td_info {
 
 enum  velocity_owner {
 	OWNED_BY_HOST = 0,
-	OWNED_BY_NIC = __constant_cpu_to_le16(0x8000)
+	OWNED_BY_NIC = cpu_to_le16(0x8000)
 };
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/virtio_net.c linux-libre-2.6.30-gnu1/drivers/net/virtio_net.c
--- linux-libre-2.6.29-gnu1/drivers/net/virtio_net.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/virtio_net.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,12 +37,15 @@ module_param(gso, bool, 0444);
 #define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
 #define GOOD_COPY_LEN	128
 
+#define VIRTNET_SEND_COMMAND_SG_MAX    2
+
 struct virtnet_info
 {
 	struct virtio_device *vdev;
-	struct virtqueue *rvq, *svq;
+	struct virtqueue *rvq, *svq, *cvq;
 	struct net_device *dev;
 	struct napi_struct napi;
+	unsigned int status;
 
 	/* The skb we couldn't send because buffers were full. */
 	struct sk_buff *last_xmit_skb;
@@ -375,9 +378,9 @@ static void skb_recv_done(struct virtque
 {
 	struct virtnet_info *vi = rvq->vdev->priv;
 	/* Schedule NAPI, Suppress further interrupts if successful. */
-	if (netif_rx_schedule_prep(&vi->napi)) {
+	if (napi_schedule_prep(&vi->napi)) {
 		rvq->vq_ops->disable_cb(rvq);
-		__netif_rx_schedule(&vi->napi);
+		__napi_schedule(&vi->napi);
 	}
 }
 
@@ -403,11 +406,11 @@ again:
 
 	/* Out of packets? */
 	if (received < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
 		    && napi_schedule_prep(napi)) {
 			vi->rvq->vq_ops->disable_cb(vi->rvq);
-			__netif_rx_schedule(napi);
+			__napi_schedule(napi);
 			goto again;
 		}
 	}
@@ -562,6 +565,23 @@ stop_queue:
 	goto done;
 }
 
+static int virtnet_set_mac_address(struct net_device *dev, void *p)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct virtio_device *vdev = vi->vdev;
+	int ret;
+
+	ret = eth_mac_addr(dev, p);
+	if (ret)
+		return ret;
+
+	if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
+		vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+		                  dev->dev_addr, dev->addr_len);
+
+	return 0;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void virtnet_netpoll(struct net_device *dev)
 {
@@ -581,13 +601,62 @@ static int virtnet_open(struct net_devic
 	 * won't get another interrupt, so process any outstanding packets
 	 * now.  virtnet_poll wants re-enable the queue, so we disable here.
 	 * We synchronize against interrupts via NAPI_STATE_SCHED */
-	if (netif_rx_schedule_prep(&vi->napi)) {
+	if (napi_schedule_prep(&vi->napi)) {
 		vi->rvq->vq_ops->disable_cb(vi->rvq);
-		__netif_rx_schedule(&vi->napi);
+		__napi_schedule(&vi->napi);
 	}
 	return 0;
 }
 
+/*
+ * Send command via the control virtqueue and check status.  Commands
+ * supported by the hypervisor, as indicated by feature bits, should
+ * never fail unless improperly formated.
+ */
+static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
+				 struct scatterlist *data, int out, int in)
+{
+	struct scatterlist *s, sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
+	struct virtio_net_ctrl_hdr ctrl;
+	virtio_net_ctrl_ack status = ~0;
+	unsigned int tmp;
+	int i;
+
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
+		BUG();  /* Caller should know better */
+		return false;
+	}
+
+	BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
+
+	out++; /* Add header */
+	in++; /* Add return status */
+
+	ctrl.class = class;
+	ctrl.cmd = cmd;
+
+	sg_init_table(sg, out + in);
+
+	sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
+	for_each_sg(data, s, out + in - 2, i)
+		sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
+	sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
+
+	if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
+		BUG();
+
+	vi->cvq->vq_ops->kick(vi->cvq);
+
+	/*
+	 * Spin for a response, the kick causes an ioport write, trapping
+	 * into the hypervisor, so the request should be handled immediately.
+	 */
+	while (!vi->cvq->vq_ops->get_buf(vi->cvq, &tmp))
+		cpu_relax();
+
+	return status == VIRTIO_NET_OK;
+}
+
 static int virtnet_close(struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
@@ -608,6 +677,101 @@ static int virtnet_set_tx_csum(struct ne
 	return ethtool_op_set_tx_hw_csum(dev, data);
 }
 
+static void virtnet_set_rx_mode(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct scatterlist sg[2];
+	u8 promisc, allmulti;
+	struct virtio_net_ctrl_mac *mac_data;
+	struct dev_addr_list *addr;
+	void *buf;
+	int i;
+
+	/* We can't dynamicaly set ndo_set_rx_mode, so return gracefully */
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
+		return;
+
+	promisc = ((dev->flags & IFF_PROMISC) != 0);
+	allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+
+	sg_init_one(sg, &promisc, sizeof(promisc));
+
+	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+				  VIRTIO_NET_CTRL_RX_PROMISC,
+				  sg, 1, 0))
+		dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
+			 promisc ? "en" : "dis");
+
+	sg_init_one(sg, &allmulti, sizeof(allmulti));
+
+	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+				  VIRTIO_NET_CTRL_RX_ALLMULTI,
+				  sg, 1, 0))
+		dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
+			 allmulti ? "en" : "dis");
+
+	/* MAC filter - use one buffer for both lists */
+	mac_data = buf = kzalloc(((dev->uc_count + dev->mc_count) * ETH_ALEN) +
+				 (2 * sizeof(mac_data->entries)), GFP_ATOMIC);
+	if (!buf) {
+		dev_warn(&dev->dev, "No memory for MAC address buffer\n");
+		return;
+	}
+
+	sg_init_table(sg, 2);
+
+	/* Store the unicast list and count in the front of the buffer */
+	mac_data->entries = dev->uc_count;
+	addr = dev->uc_list;
+	for (i = 0; i < dev->uc_count; i++, addr = addr->next)
+		memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+
+	sg_set_buf(&sg[0], mac_data,
+		   sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
+
+	/* multicast list and count fill the end */
+	mac_data = (void *)&mac_data->macs[dev->uc_count][0];
+
+	mac_data->entries = dev->mc_count;
+	addr = dev->mc_list;
+	for (i = 0; i < dev->mc_count; i++, addr = addr->next)
+		memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+
+	sg_set_buf(&sg[1], mac_data,
+		   sizeof(mac_data->entries) + (dev->mc_count * ETH_ALEN));
+
+	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
+				  VIRTIO_NET_CTRL_MAC_TABLE_SET,
+				  sg, 2, 0))
+		dev_warn(&dev->dev, "Failed to set MAC fitler table.\n");
+
+	kfree(buf);
+}
+
+static void virtnet_vlan_rx_add_vid(struct net_device *dev, u16 vid)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct scatterlist sg;
+
+	sg_init_one(&sg, &vid, sizeof(vid));
+
+	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+				  VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0))
+		dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
+}
+
+static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct scatterlist sg;
+
+	sg_init_one(&sg, &vid, sizeof(vid));
+
+	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+				  VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0))
+		dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid);
+}
+
 static struct ethtool_ops virtnet_ethtool_ops = {
 	.set_tx_csum = virtnet_set_tx_csum,
 	.set_sg = ethtool_op_set_sg,
@@ -631,13 +795,51 @@ static const struct net_device_ops virtn
 	.ndo_stop   	     = virtnet_close,
 	.ndo_start_xmit      = start_xmit,
 	.ndo_validate_addr   = eth_validate_addr,
-	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_set_mac_address = virtnet_set_mac_address,
+	.ndo_set_rx_mode     = virtnet_set_rx_mode,
 	.ndo_change_mtu	     = virtnet_change_mtu,
+	.ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = virtnet_netpoll,
 #endif
 };
 
+static void virtnet_update_status(struct virtnet_info *vi)
+{
+	u16 v;
+
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS))
+		return;
+
+	vi->vdev->config->get(vi->vdev,
+			      offsetof(struct virtio_net_config, status),
+			      &v, sizeof(v));
+
+	/* Ignore unknown (future) status bits */
+	v &= VIRTIO_NET_S_LINK_UP;
+
+	if (vi->status == v)
+		return;
+
+	vi->status = v;
+
+	if (vi->status & VIRTIO_NET_S_LINK_UP) {
+		netif_carrier_on(vi->dev);
+		netif_wake_queue(vi->dev);
+	} else {
+		netif_carrier_off(vi->dev);
+		netif_stop_queue(vi->dev);
+	}
+}
+
+static void virtnet_config_changed(struct virtio_device *vdev)
+{
+	struct virtnet_info *vi = vdev->priv;
+
+	virtnet_update_status(vi);
+}
+
 static int virtnet_probe(struct virtio_device *vdev)
 {
 	int err;
@@ -716,6 +918,17 @@ static int virtnet_probe(struct virtio_d
 		goto free_recv;
 	}
 
+	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
+		vi->cvq = vdev->config->find_vq(vdev, 2, NULL);
+		if (IS_ERR(vi->cvq)) {
+			err = PTR_ERR(vi->svq);
+			goto free_send;
+		}
+
+		if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
+			dev->features |= NETIF_F_HW_VLAN_FILTER;
+	}
+
 	/* Initialize our empty receive and send queues. */
 	skb_queue_head_init(&vi->recv);
 	skb_queue_head_init(&vi->send);
@@ -728,7 +941,7 @@ static int virtnet_probe(struct virtio_d
 	err = register_netdev(dev);
 	if (err) {
 		pr_debug("virtio_net: registering device failed\n");
-		goto free_send;
+		goto free_ctrl;
 	}
 
 	/* Last of all, set up some receive buffers. */
@@ -740,6 +953,8 @@ static int virtnet_probe(struct virtio_d
 		goto unregister;
 	}
 
+	vi->status = VIRTIO_NET_S_LINK_UP;
+	virtnet_update_status(vi);
 	netif_carrier_on(dev);
 
 	pr_debug("virtnet: registered device %s\n", dev->name);
@@ -747,6 +962,9 @@ static int virtnet_probe(struct virtio_d
 
 unregister:
 	unregister_netdev(dev);
+free_ctrl:
+	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+		vdev->config->del_vq(vi->cvq);
 free_send:
 	vdev->config->del_vq(vi->svq);
 free_recv:
@@ -778,6 +996,8 @@ static void virtnet_remove(struct virtio
 
 	vdev->config->del_vq(vi->svq);
 	vdev->config->del_vq(vi->rvq);
+	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+		vdev->config->del_vq(vi->cvq);
 	unregister_netdev(vi->dev);
 
 	while (vi->pages)
@@ -797,7 +1017,8 @@ static unsigned int features[] = {
 	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
 	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
 	VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
-	VIRTIO_NET_F_MRG_RXBUF,
+	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
+	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 	VIRTIO_F_NOTIFY_ON_EMPTY,
 };
 
@@ -809,6 +1030,7 @@ static struct virtio_driver virtio_net =
 	.id_table =	id_table,
 	.probe =	virtnet_probe,
 	.remove =	__devexit_p(virtnet_remove),
+	.config_changed = virtnet_config_changed,
 };
 
 static int __init init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/Makefile linux-libre-2.6.30-gnu1/drivers/net/vxge/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,7 @@
+#
+# Makefile for Neterion Inc's X3100 Series 10 GbE PCIe # I/O
+# Virtualized Server Adapter linux driver
+
+obj-$(CONFIG_VXGE) += vxge.o
+
+vxge-objs := vxge-config.o vxge-traffic.o vxge-ethtool.o vxge-main.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-config.c linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-config.c
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-config.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-config.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,5264 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-config.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include <linux/vmalloc.h>
+#include <linux/etherdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+
+/*
+ * __vxge_hw_channel_allocate - Allocate memory for channel
+ * This function allocates required memory for the channel and various arrays
+ * in the channel
+ */
+struct __vxge_hw_channel*
+__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
+			   enum __vxge_hw_channel_type type,
+	u32 length, u32 per_dtr_space, void *userdata)
+{
+	struct __vxge_hw_channel *channel;
+	struct __vxge_hw_device *hldev;
+	int size = 0;
+	u32 vp_id;
+
+	hldev = vph->vpath->hldev;
+	vp_id = vph->vpath->vp_id;
+
+	switch (type) {
+	case VXGE_HW_CHANNEL_TYPE_FIFO:
+		size = sizeof(struct __vxge_hw_fifo);
+		break;
+	case VXGE_HW_CHANNEL_TYPE_RING:
+		size = sizeof(struct __vxge_hw_ring);
+		break;
+	default:
+		break;
+	}
+
+	channel = kzalloc(size, GFP_KERNEL);
+	if (channel == NULL)
+		goto exit0;
+	INIT_LIST_HEAD(&channel->item);
+
+	channel->common_reg = hldev->common_reg;
+	channel->first_vp_id = hldev->first_vp_id;
+	channel->type = type;
+	channel->devh = hldev;
+	channel->vph = vph;
+	channel->userdata = userdata;
+	channel->per_dtr_space = per_dtr_space;
+	channel->length = length;
+	channel->vp_id = vp_id;
+
+	channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+	if (channel->work_arr == NULL)
+		goto exit1;
+
+	channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+	if (channel->free_arr == NULL)
+		goto exit1;
+	channel->free_ptr = length;
+
+	channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+	if (channel->reserve_arr == NULL)
+		goto exit1;
+	channel->reserve_ptr = length;
+	channel->reserve_top = 0;
+
+	channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+	if (channel->orig_arr == NULL)
+		goto exit1;
+
+	return channel;
+exit1:
+	__vxge_hw_channel_free(channel);
+
+exit0:
+	return NULL;
+}
+
+/*
+ * __vxge_hw_channel_free - Free memory allocated for channel
+ * This function deallocates memory from the channel and various arrays
+ * in the channel
+ */
+void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
+{
+	kfree(channel->work_arr);
+	kfree(channel->free_arr);
+	kfree(channel->reserve_arr);
+	kfree(channel->orig_arr);
+	kfree(channel);
+}
+
+/*
+ * __vxge_hw_channel_initialize - Initialize a channel
+ * This function initializes a channel by properly setting the
+ * various references
+ */
+enum vxge_hw_status
+__vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
+{
+	u32 i;
+	struct __vxge_hw_virtualpath *vpath;
+
+	vpath = channel->vph->vpath;
+
+	if ((channel->reserve_arr != NULL) && (channel->orig_arr != NULL)) {
+		for (i = 0; i < channel->length; i++)
+			channel->orig_arr[i] = channel->reserve_arr[i];
+	}
+
+	switch (channel->type) {
+	case VXGE_HW_CHANNEL_TYPE_FIFO:
+		vpath->fifoh = (struct __vxge_hw_fifo *)channel;
+		channel->stats = &((struct __vxge_hw_fifo *)
+				channel)->stats->common_stats;
+		break;
+	case VXGE_HW_CHANNEL_TYPE_RING:
+		vpath->ringh = (struct __vxge_hw_ring *)channel;
+		channel->stats = &((struct __vxge_hw_ring *)
+				channel)->stats->common_stats;
+		break;
+	default:
+		break;
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_channel_reset - Resets a channel
+ * This function resets a channel by properly setting the various references
+ */
+enum vxge_hw_status
+__vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
+{
+	u32 i;
+
+	for (i = 0; i < channel->length; i++) {
+		if (channel->reserve_arr != NULL)
+			channel->reserve_arr[i] = channel->orig_arr[i];
+		if (channel->free_arr != NULL)
+			channel->free_arr[i] = NULL;
+		if (channel->work_arr != NULL)
+			channel->work_arr[i] = NULL;
+	}
+	channel->free_ptr = channel->length;
+	channel->reserve_ptr = channel->length;
+	channel->reserve_top = 0;
+	channel->post_index = 0;
+	channel->compl_index = 0;
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_pci_e_init
+ * Initialize certain PCI/PCI-X configuration registers
+ * with recommended values. Save config space for future hw resets.
+ */
+void
+__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
+{
+	u16 cmd = 0;
+
+	/* Set the PErr Repconse bit and SERR in PCI command register. */
+	pci_read_config_word(hldev->pdev, PCI_COMMAND, &cmd);
+	cmd |= 0x140;
+	pci_write_config_word(hldev->pdev, PCI_COMMAND, cmd);
+
+	pci_save_state(hldev->pdev);
+
+	return;
+}
+
+/*
+ * __vxge_hw_device_register_poll
+ * Will poll certain register for specified amount of time.
+ * Will poll until masked bit is not cleared.
+ */
+enum vxge_hw_status
+__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
+{
+	u64 val64;
+	u32 i = 0;
+	enum vxge_hw_status ret = VXGE_HW_FAIL;
+
+	udelay(10);
+
+	do {
+		val64 = readq(reg);
+		if (!(val64 & mask))
+			return VXGE_HW_OK;
+		udelay(100);
+	} while (++i <= 9);
+
+	i = 0;
+	do {
+		val64 = readq(reg);
+		if (!(val64 & mask))
+			return VXGE_HW_OK;
+		mdelay(1);
+	} while (++i <= max_millis);
+
+	return ret;
+}
+
+ /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
+ * in progress
+ * This routine checks the vpath reset in progress register is turned zero
+ */
+enum vxge_hw_status
+__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
+{
+	enum vxge_hw_status status;
+	status = __vxge_hw_device_register_poll(vpath_rst_in_prog,
+			VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
+			VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+	return status;
+}
+
+/*
+ * __vxge_hw_device_toc_get
+ * This routine sets the swapper and reads the toc pointer and returns the
+ * memory mapped address of the toc
+ */
+struct vxge_hw_toc_reg __iomem *
+__vxge_hw_device_toc_get(void __iomem *bar0)
+{
+	u64 val64;
+	struct vxge_hw_toc_reg __iomem *toc = NULL;
+	enum vxge_hw_status status;
+
+	struct vxge_hw_legacy_reg __iomem *legacy_reg =
+		(struct vxge_hw_legacy_reg __iomem *)bar0;
+
+	status = __vxge_hw_legacy_swapper_set(legacy_reg);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 =	readq(&legacy_reg->toc_first_pointer);
+	toc = (struct vxge_hw_toc_reg __iomem *)(bar0+val64);
+exit:
+	return toc;
+}
+
+/*
+ * __vxge_hw_device_reg_addr_get
+ * This routine sets the swapper and reads the toc pointer and initializes the
+ * register location pointers in the device object. It waits until the ric is
+ * completed initializing registers.
+ */
+enum vxge_hw_status
+__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
+{
+	u64 val64;
+	u32 i;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	hldev->legacy_reg = (struct vxge_hw_legacy_reg __iomem *)hldev->bar0;
+
+	hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0);
+	if (hldev->toc_reg  == NULL) {
+		status = VXGE_HW_FAIL;
+		goto exit;
+	}
+
+	val64 = readq(&hldev->toc_reg->toc_common_pointer);
+	hldev->common_reg =
+	(struct vxge_hw_common_reg __iomem *)(hldev->bar0 + val64);
+
+	val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer);
+	hldev->mrpcim_reg =
+		(struct vxge_hw_mrpcim_reg __iomem *)(hldev->bar0 + val64);
+
+	for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) {
+		val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]);
+		hldev->srpcim_reg[i] =
+			(struct vxge_hw_srpcim_reg __iomem *)
+				(hldev->bar0 + val64);
+	}
+
+	for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) {
+		val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]);
+		hldev->vpmgmt_reg[i] =
+		(struct vxge_hw_vpmgmt_reg __iomem *)(hldev->bar0 + val64);
+	}
+
+	for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) {
+		val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]);
+		hldev->vpath_reg[i] =
+			(struct vxge_hw_vpath_reg __iomem *)
+				(hldev->bar0 + val64);
+	}
+
+	val64 = readq(&hldev->toc_reg->toc_kdfc);
+
+	switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) {
+	case 0:
+		hldev->kdfc = (u8 __iomem *)(hldev->bar0 +
+			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+		break;
+	case 2:
+		hldev->kdfc = (u8 __iomem *)(hldev->bar1 +
+			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+		break;
+	case 4:
+		hldev->kdfc = (u8 __iomem *)(hldev->bar2 +
+			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+		break;
+	default:
+		break;
+	}
+
+	status = __vxge_hw_device_vpath_reset_in_prog_check(
+			(u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_device_id_get
+ * This routine returns sets the device id and revision numbers into the device
+ * structure
+ */
+void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev)
+{
+	u64 val64;
+
+	val64 = readq(&hldev->common_reg->titan_asic_id);
+	hldev->device_id =
+		(u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64);
+
+	hldev->major_revision =
+		(u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64);
+
+	hldev->minor_revision =
+		(u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64);
+
+	return;
+}
+
+/*
+ * __vxge_hw_device_access_rights_get: Get Access Rights of the driver
+ * This routine returns the Access Rights of the driver
+ */
+static u32
+__vxge_hw_device_access_rights_get(u32 host_type, u32 func_id)
+{
+	u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH;
+
+	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;
+		}
+		break;
+	case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
+		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+				VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+		break;
+	case VXGE_HW_NO_MR_SR_VH0_FUNCTION0:
+		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+				VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+		break;
+	case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
+	case VXGE_HW_SR_VH_VIRTUAL_FUNCTION:
+	case VXGE_HW_MR_SR_VH0_INVALID_CONFIG:
+		break;
+	case VXGE_HW_SR_VH_FUNCTION0:
+	case VXGE_HW_VH_NORMAL_FUNCTION:
+		access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+		break;
+	}
+
+	return access_rights;
+}
+/*
+ * __vxge_hw_device_host_info_get
+ * This routine returns the host type assignments
+ */
+void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
+{
+	u64 val64;
+	u32 i;
+
+	val64 = readq(&hldev->common_reg->host_type_assignments);
+
+	hldev->host_type =
+	   (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
+
+	hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpath_assignments & vxge_mBIT(i)))
+			continue;
+
+		hldev->func_id =
+			__vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]);
+
+		hldev->access_rights = __vxge_hw_device_access_rights_get(
+			hldev->host_type, hldev->func_id);
+
+		hldev->first_vp_id = i;
+		break;
+	}
+
+	return;
+}
+
+/*
+ * __vxge_hw_verify_pci_e_info - Validate the pci-e link parameters such as
+ * link width and signalling rate.
+ */
+static enum vxge_hw_status
+__vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
+{
+	int exp_cap;
+	u16 lnk;
+
+	/* Get the negotiated link width and speed from PCI config space */
+	exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
+	pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+
+	if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
+		return VXGE_HW_ERR_INVALID_PCI_INFO;
+
+	switch ((lnk & PCI_EXP_LNKSTA_NLW) >> 4) {
+	case PCIE_LNK_WIDTH_RESRV:
+	case PCIE_LNK_X1:
+	case PCIE_LNK_X2:
+	case PCIE_LNK_X4:
+	case PCIE_LNK_X8:
+		break;
+	default:
+		return VXGE_HW_ERR_INVALID_PCI_INFO;
+	}
+
+	return VXGE_HW_OK;
+}
+
+static 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.
+ */
+enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	/* 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;
+}
+
+/**
+ * vxge_hw_device_hw_info_get - Get the hw information
+ * Returns the vpath mask that has the bits set for each vpath allocated
+ * for the driver, FW version information and the first mac addresse for
+ * each vpath
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_hw_info_get(void __iomem *bar0,
+			   struct vxge_hw_device_hw_info *hw_info)
+{
+	u32 i;
+	u64 val64;
+	struct vxge_hw_toc_reg __iomem *toc;
+	struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
+	struct vxge_hw_common_reg __iomem *common_reg;
+	struct vxge_hw_vpath_reg __iomem *vpath_reg;
+	struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
+	enum vxge_hw_status status;
+
+	memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
+
+	toc = __vxge_hw_device_toc_get(bar0);
+	if (toc == NULL) {
+		status = VXGE_HW_ERR_CRITICAL;
+		goto exit;
+	}
+
+	val64 = readq(&toc->toc_common_pointer);
+	common_reg = (struct vxge_hw_common_reg __iomem *)(bar0 + val64);
+
+	status = __vxge_hw_device_vpath_reset_in_prog_check(
+		(u64 __iomem *)&common_reg->vpath_rst_in_prog);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	hw_info->vpath_mask = readq(&common_reg->vpath_assignments);
+
+	val64 = readq(&common_reg->host_type_assignments);
+
+	hw_info->host_type =
+	   (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
+			continue;
+
+		val64 = readq(&toc->toc_vpmgmt_pointer[i]);
+
+		vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *)
+				(bar0 + val64);
+
+		hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg);
+		if (__vxge_hw_device_access_rights_get(hw_info->host_type,
+			hw_info->func_id) &
+			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
+
+			val64 = readq(&toc->toc_mrpcim_pointer);
+
+			mrpcim_reg = (struct vxge_hw_mrpcim_reg __iomem *)
+					(bar0 + val64);
+
+			writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask);
+			wmb();
+		}
+
+		val64 = readq(&toc->toc_vpath_pointer[i]);
+
+		vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+
+		hw_info->function_mode =
+			__vxge_hw_vpath_pci_func_mode_get(i, vpath_reg);
+
+		status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		break;
+	}
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
+			continue;
+
+		val64 = readq(&toc->toc_vpath_pointer[i]);
+		vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+
+		status =  __vxge_hw_vpath_addr_get(i, vpath_reg,
+				hw_info->mac_addrs[i],
+				hw_info->mac_addr_masks[i]);
+		if (status != VXGE_HW_OK)
+			goto exit;
+	}
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_initialize - Initialize Titan device.
+ * Initialize Titan device. Note that all the arguments of this public API
+ * are 'IN', including @hldev. Driver cooperates with
+ * OS to find new Titan device, locate its PCI and memory spaces.
+ *
+ * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW
+ * to enable the latter to perform Titan hardware initialization.
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_initialize(
+	struct __vxge_hw_device **devh,
+	struct vxge_hw_device_attr *attr,
+	struct vxge_hw_device_config *device_config)
+{
+	u32 i;
+	u32 nblocks = 0;
+	struct __vxge_hw_device *hldev = NULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	status = __vxge_hw_device_config_check(device_config);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	hldev = (struct __vxge_hw_device *)
+			vmalloc(sizeof(struct __vxge_hw_device));
+	if (hldev == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	memset(hldev, 0, sizeof(struct __vxge_hw_device));
+	hldev->magic = VXGE_HW_DEVICE_MAGIC;
+
+	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL);
+
+	/* apply config */
+	memcpy(&hldev->config, device_config,
+		sizeof(struct vxge_hw_device_config));
+
+	hldev->bar0 = attr->bar0;
+	hldev->bar1 = attr->bar1;
+	hldev->bar2 = attr->bar2;
+	hldev->pdev = attr->pdev;
+
+	hldev->uld_callbacks.link_up = attr->uld_callbacks.link_up;
+	hldev->uld_callbacks.link_down = attr->uld_callbacks.link_down;
+	hldev->uld_callbacks.crit_err = attr->uld_callbacks.crit_err;
+
+	__vxge_hw_device_pci_e_init(hldev);
+
+	status = __vxge_hw_device_reg_addr_get(hldev);
+	if (status != VXGE_HW_OK)
+		goto exit;
+	__vxge_hw_device_id_get(hldev);
+
+	__vxge_hw_device_host_info_get(hldev);
+
+	/* Incrementing for stats blocks */
+	nblocks++;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpath_assignments & vxge_mBIT(i)))
+			continue;
+
+		if (device_config->vp_config[i].ring.enable ==
+			VXGE_HW_RING_ENABLE)
+			nblocks += device_config->vp_config[i].ring.ring_blocks;
+
+		if (device_config->vp_config[i].fifo.enable ==
+			VXGE_HW_FIFO_ENABLE)
+			nblocks += device_config->vp_config[i].fifo.fifo_blocks;
+		nblocks++;
+	}
+
+	if (__vxge_hw_blockpool_create(hldev,
+		&hldev->block_pool,
+		device_config->dma_blockpool_initial + nblocks,
+		device_config->dma_blockpool_max + nblocks) != VXGE_HW_OK) {
+
+		vxge_hw_device_terminate(hldev);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	status = __vxge_hw_device_initialize(hldev);
+
+	if (status != VXGE_HW_OK) {
+		vxge_hw_device_terminate(hldev);
+		goto exit;
+	}
+
+	*devh = hldev;
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_terminate - Terminate Titan device.
+ * Terminate HW device.
+ */
+void
+vxge_hw_device_terminate(struct __vxge_hw_device *hldev)
+{
+	vxge_assert(hldev->magic == VXGE_HW_DEVICE_MAGIC);
+
+	hldev->magic = VXGE_HW_DEVICE_DEAD;
+	__vxge_hw_blockpool_destroy(&hldev->block_pool);
+	vfree(hldev);
+}
+
+/*
+ * vxge_hw_device_stats_get - Get the device hw statistics.
+ * Returns the vpath h/w stats for the device.
+ */
+enum vxge_hw_status
+vxge_hw_device_stats_get(struct __vxge_hw_device *hldev,
+			struct vxge_hw_device_stats_hw_info *hw_stats)
+{
+	u32 i;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpaths_deployed & vxge_mBIT(i)) ||
+			(hldev->virtual_paths[i].vp_open ==
+				VXGE_HW_VP_NOT_OPEN))
+			continue;
+
+		memcpy(hldev->virtual_paths[i].hw_stats_sav,
+				hldev->virtual_paths[i].hw_stats,
+				sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+		status = __vxge_hw_vpath_stats_get(
+			&hldev->virtual_paths[i],
+			hldev->virtual_paths[i].hw_stats);
+	}
+
+	memcpy(hw_stats, &hldev->stats.hw_dev_info_stats,
+			sizeof(struct vxge_hw_device_stats_hw_info));
+
+	return status;
+}
+
+/*
+ * vxge_hw_driver_stats_get - Get the device sw statistics.
+ * Returns the vpath s/w stats for the device.
+ */
+enum vxge_hw_status vxge_hw_driver_stats_get(
+			struct __vxge_hw_device *hldev,
+			struct vxge_hw_device_stats_sw_info *sw_stats)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	memcpy(sw_stats, &hldev->stats.sw_dev_info_stats,
+		sizeof(struct vxge_hw_device_stats_sw_info));
+
+	return status;
+}
+
+/*
+ * vxge_hw_mrpcim_stats_access - Access the statistics from the given location
+ *                           and offset and perform an operation
+ * Get the statistics from the given location and offset.
+ */
+enum vxge_hw_status
+vxge_hw_mrpcim_stats_access(struct __vxge_hw_device *hldev,
+			    u32 operation, u32 location, u32 offset, u64 *stat)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	status = __vxge_hw_device_is_privilaged(hldev);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = VXGE_HW_XMAC_STATS_SYS_CMD_OP(operation) |
+		VXGE_HW_XMAC_STATS_SYS_CMD_STROBE |
+		VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(location) |
+		VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(offset);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&hldev->mrpcim_reg->xmac_stats_sys_cmd,
+				VXGE_HW_XMAC_STATS_SYS_CMD_STROBE,
+				hldev->config.device_poll_millis);
+
+	if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
+		*stat = readq(&hldev->mrpcim_reg->xmac_stats_sys_data);
+	else
+		*stat = 0;
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_xmac_aggr_stats_get - Get the Statistics on aggregate port
+ * Get the Statistics on aggregate port
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *hldev, u32 port,
+				   struct vxge_hw_xmac_aggr_stats *aggr_stats)
+{
+	u64 *val64;
+	int i;
+	u32 offset = VXGE_HW_STATS_AGGRn_OFFSET;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = (u64 *)aggr_stats;
+
+	status = __vxge_hw_device_is_privilaged(hldev);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	for (i = 0; i < sizeof(struct vxge_hw_xmac_aggr_stats) / 8; i++) {
+		status = vxge_hw_mrpcim_stats_access(hldev,
+					VXGE_HW_STATS_OP_READ,
+					VXGE_HW_STATS_LOC_AGGR,
+					((offset + (104 * port)) >> 3), val64);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		offset += 8;
+		val64++;
+	}
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_xmac_port_stats_get - Get the Statistics on a port
+ * Get the Statistics on port
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *hldev, u32 port,
+				   struct vxge_hw_xmac_port_stats *port_stats)
+{
+	u64 *val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	int i;
+	u32 offset = 0x0;
+	val64 = (u64 *) port_stats;
+
+	status = __vxge_hw_device_is_privilaged(hldev);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	for (i = 0; i < sizeof(struct vxge_hw_xmac_port_stats) / 8; i++) {
+		status = vxge_hw_mrpcim_stats_access(hldev,
+					VXGE_HW_STATS_OP_READ,
+					VXGE_HW_STATS_LOC_AGGR,
+					((offset + (608 * port)) >> 3), val64);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		offset += 8;
+		val64++;
+	}
+
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_xmac_stats_get - Get the XMAC Statistics
+ * Get the XMAC Statistics
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev,
+			      struct vxge_hw_xmac_stats *xmac_stats)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	u32 i;
+
+	status = vxge_hw_device_xmac_aggr_stats_get(hldev,
+					0, &xmac_stats->aggr_stats[0]);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status = vxge_hw_device_xmac_aggr_stats_get(hldev,
+				1, &xmac_stats->aggr_stats[1]);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	for (i = 0; i <= VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
+
+		status = vxge_hw_device_xmac_port_stats_get(hldev,
+					i, &xmac_stats->port_stats[i]);
+		if (status != VXGE_HW_OK)
+			goto exit;
+	}
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+			continue;
+
+		status = __vxge_hw_vpath_xmac_tx_stats_get(
+					&hldev->virtual_paths[i],
+					&xmac_stats->vpath_tx_stats[i]);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		status = __vxge_hw_vpath_xmac_rx_stats_get(
+					&hldev->virtual_paths[i],
+					&xmac_stats->vpath_rx_stats[i]);
+		if (status != VXGE_HW_OK)
+			goto exit;
+	}
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_debug_set - Set the debug module, level and timestamp
+ * This routine is used to dynamically change the debug output
+ */
+void vxge_hw_device_debug_set(struct __vxge_hw_device *hldev,
+			      enum vxge_debug_level level, u32 mask)
+{
+	if (hldev == NULL)
+		return;
+
+#if defined(VXGE_DEBUG_TRACE_MASK) || \
+	defined(VXGE_DEBUG_ERR_MASK)
+	hldev->debug_module_mask = mask;
+	hldev->debug_level = level;
+#endif
+
+#if defined(VXGE_DEBUG_ERR_MASK)
+	hldev->level_err = level & VXGE_ERR;
+#endif
+
+#if defined(VXGE_DEBUG_TRACE_MASK)
+	hldev->level_trace = level & VXGE_TRACE;
+#endif
+}
+
+/*
+ * vxge_hw_device_error_level_get - Get the error level
+ * This routine returns the current error level set
+ */
+u32 vxge_hw_device_error_level_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_ERR_MASK)
+	if (hldev == NULL)
+		return VXGE_ERR;
+	else
+		return hldev->level_err;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * vxge_hw_device_trace_level_get - Get the trace level
+ * This routine returns the current trace level set
+ */
+u32 vxge_hw_device_trace_level_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_TRACE_MASK)
+	if (hldev == NULL)
+		return VXGE_TRACE;
+	else
+		return hldev->level_trace;
+#else
+	return 0;
+#endif
+}
+/*
+ * vxge_hw_device_debug_mask_get - Get the debug mask
+ * This routine returns the current debug mask set
+ */
+u32 vxge_hw_device_debug_mask_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_TRACE_MASK) || defined(VXGE_DEBUG_ERR_MASK)
+	if (hldev == NULL)
+		return 0;
+	return hldev->debug_module_mask;
+#else
+	return 0;
+#endif
+}
+
+/*
+ * vxge_hw_getpause_data -Pause frame frame generation and reception.
+ * Returns the Pause frame generation and reception capability of the NIC.
+ */
+enum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev,
+						 u32 port, u32 *tx, u32 *rx)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+		status = VXGE_HW_ERR_INVALID_DEVICE;
+		goto exit;
+	}
+
+	if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
+		status = VXGE_HW_ERR_INVALID_PORT;
+		goto exit;
+	}
+
+	if (!(hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+		status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+		goto exit;
+	}
+
+	val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+	if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN)
+		*tx = 1;
+	if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN)
+		*rx = 1;
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_device_setpause_data -  set/reset pause frame generation.
+ * It can be used to set or reset Pause frame generation or reception
+ * support of the NIC.
+ */
+
+enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
+						 u32 port, u32 tx, u32 rx)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+		status = VXGE_HW_ERR_INVALID_DEVICE;
+		goto exit;
+	}
+
+	if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
+		status = VXGE_HW_ERR_INVALID_PORT;
+		goto exit;
+	}
+
+	status = __vxge_hw_device_is_privilaged(hldev);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+	if (tx)
+		val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
+	else
+		val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
+	if (rx)
+		val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
+	else
+		val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
+
+	writeq(val64, &hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+exit:
+	return status;
+}
+
+u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
+{
+	int link_width, exp_cap;
+	u16 lnk;
+
+	exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
+	pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+	link_width = (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
+	return link_width;
+}
+
+/*
+ * __vxge_hw_ring_block_memblock_idx - Return the memblock index
+ * This function returns the index of memory block
+ */
+static inline u32
+__vxge_hw_ring_block_memblock_idx(u8 *block)
+{
+	return (u32)*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET));
+}
+
+/*
+ * __vxge_hw_ring_block_memblock_idx_set - Sets the memblock index
+ * This function sets index to a memory block
+ */
+static inline void
+__vxge_hw_ring_block_memblock_idx_set(u8 *block, u32 memblock_idx)
+{
+	*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)) = memblock_idx;
+}
+
+/*
+ * __vxge_hw_ring_block_next_pointer_set - Sets the next block pointer
+ * in RxD block
+ * Sets the next block pointer in RxD block
+ */
+static inline void
+__vxge_hw_ring_block_next_pointer_set(u8 *block, dma_addr_t dma_next)
+{
+	*((u64 *)(block + VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next;
+}
+
+/*
+ * __vxge_hw_ring_first_block_address_get - Returns the dma address of the
+ *             first block
+ * Returns the dma address of the first RxD block
+ */
+u64 __vxge_hw_ring_first_block_address_get(struct __vxge_hw_ring *ring)
+{
+	struct vxge_hw_mempool_dma *dma_object;
+
+	dma_object = ring->mempool->memblocks_dma_arr;
+	vxge_assert(dma_object != NULL);
+
+	return dma_object->addr;
+}
+
+/*
+ * __vxge_hw_ring_item_dma_addr - Return the dma address of an item
+ * This function returns the dma address of a given item
+ */
+static dma_addr_t __vxge_hw_ring_item_dma_addr(struct vxge_hw_mempool *mempoolh,
+					       void *item)
+{
+	u32 memblock_idx;
+	void *memblock;
+	struct vxge_hw_mempool_dma *memblock_dma_object;
+	ptrdiff_t dma_item_offset;
+
+	/* get owner memblock index */
+	memblock_idx = __vxge_hw_ring_block_memblock_idx(item);
+
+	/* get owner memblock by memblock index */
+	memblock = mempoolh->memblocks_arr[memblock_idx];
+
+	/* get memblock DMA object by memblock index */
+	memblock_dma_object = mempoolh->memblocks_dma_arr + memblock_idx;
+
+	/* calculate offset in the memblock of this item */
+	dma_item_offset = (u8 *)item - (u8 *)memblock;
+
+	return memblock_dma_object->addr + dma_item_offset;
+}
+
+/*
+ * __vxge_hw_ring_rxdblock_link - Link the RxD blocks
+ * This function returns the dma address of a given item
+ */
+static void __vxge_hw_ring_rxdblock_link(struct vxge_hw_mempool *mempoolh,
+					 struct __vxge_hw_ring *ring, u32 from,
+					 u32 to)
+{
+	u8 *to_item , *from_item;
+	dma_addr_t to_dma;
+
+	/* get "from" RxD block */
+	from_item = mempoolh->items_arr[from];
+	vxge_assert(from_item);
+
+	/* get "to" RxD block */
+	to_item = mempoolh->items_arr[to];
+	vxge_assert(to_item);
+
+	/* return address of the beginning of previous RxD block */
+	to_dma = __vxge_hw_ring_item_dma_addr(mempoolh, to_item);
+
+	/* set next pointer for this RxD block to point on
+	 * previous item's DMA start address */
+	__vxge_hw_ring_block_next_pointer_set(from_item, to_dma);
+}
+
+/*
+ * __vxge_hw_ring_mempool_item_alloc - Allocate List blocks for RxD
+ * block callback
+ * This function is callback passed to __vxge_hw_mempool_create to create memory
+ * pool for RxD block
+ */
+static void
+__vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh,
+				  u32 memblock_index,
+				  struct vxge_hw_mempool_dma *dma_object,
+				  u32 index, u32 is_last)
+{
+	u32 i;
+	void *item = mempoolh->items_arr[index];
+	struct __vxge_hw_ring *ring =
+		(struct __vxge_hw_ring *)mempoolh->userdata;
+
+	/* format rxds array */
+	for (i = 0; i < ring->rxds_per_block; i++) {
+		void *rxdblock_priv;
+		void *uld_priv;
+		struct vxge_hw_ring_rxd_1 *rxdp;
+
+		u32 reserve_index = ring->channel.reserve_ptr -
+				(index * ring->rxds_per_block + i + 1);
+		u32 memblock_item_idx;
+
+		ring->channel.reserve_arr[reserve_index] = ((u8 *)item) +
+						i * ring->rxd_size;
+
+		/* Note: memblock_item_idx is index of the item within
+		 *       the memblock. For instance, in case of three RxD-blocks
+		 *       per memblock this value can be 0, 1 or 2. */
+		rxdblock_priv = __vxge_hw_mempool_item_priv(mempoolh,
+					memblock_index, item,
+					&memblock_item_idx);
+
+		rxdp = (struct vxge_hw_ring_rxd_1 *)
+				ring->channel.reserve_arr[reserve_index];
+
+		uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i);
+
+		/* pre-format Host_Control */
+		rxdp->host_control = (u64)(size_t)uld_priv;
+	}
+
+	__vxge_hw_ring_block_memblock_idx_set(item, memblock_index);
+
+	if (is_last) {
+		/* link last one with first one */
+		__vxge_hw_ring_rxdblock_link(mempoolh, ring, index, 0);
+	}
+
+	if (index > 0) {
+		/* link this RxD block with previous one */
+		__vxge_hw_ring_rxdblock_link(mempoolh, ring, index - 1, index);
+	}
+
+	return;
+}
+
+/*
+ * __vxge_hw_ring_initial_replenish - Initial replenish of RxDs
+ * This function replenishes the RxDs from reserve array to work array
+ */
+enum vxge_hw_status
+vxge_hw_ring_replenish(struct __vxge_hw_ring *ring, u16 min_flag)
+{
+	void *rxd;
+	int i = 0;
+	struct __vxge_hw_channel *channel;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	channel = &ring->channel;
+
+	while (vxge_hw_channel_dtr_count(channel) > 0) {
+
+		status = vxge_hw_ring_rxd_reserve(ring, &rxd);
+
+		vxge_assert(status == VXGE_HW_OK);
+
+		if (ring->rxd_init) {
+			status = ring->rxd_init(rxd, channel->userdata);
+			if (status != VXGE_HW_OK) {
+				vxge_hw_ring_rxd_free(ring, rxd);
+				goto exit;
+			}
+		}
+
+		vxge_hw_ring_rxd_post(ring, rxd);
+		if (min_flag) {
+			i++;
+			if (i == VXGE_HW_RING_MIN_BUFF_ALLOCATION)
+				break;
+		}
+	}
+	status = VXGE_HW_OK;
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_ring_create - Create a Ring
+ * This function creates Ring and initializes it.
+ *
+ */
+enum vxge_hw_status
+__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
+		      struct vxge_hw_ring_attr *attr)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_ring *ring;
+	u32 ring_length;
+	struct vxge_hw_ring_config *config;
+	struct __vxge_hw_device *hldev;
+	u32 vp_id;
+	struct vxge_hw_mempool_cbs ring_mp_callback;
+
+	if ((vp == NULL) || (attr == NULL)) {
+		status = VXGE_HW_FAIL;
+		goto exit;
+	}
+
+	hldev = vp->vpath->hldev;
+	vp_id = vp->vpath->vp_id;
+
+	config = &hldev->config.vp_config[vp_id].ring;
+
+	ring_length = config->ring_blocks *
+			vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+
+	ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
+						VXGE_HW_CHANNEL_TYPE_RING,
+						ring_length,
+						attr->per_rxd_space,
+						attr->userdata);
+
+	if (ring == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	vp->vpath->ringh = ring;
+	ring->vp_id = vp_id;
+	ring->vp_reg = vp->vpath->vp_reg;
+	ring->common_reg = hldev->common_reg;
+	ring->stats = &vp->vpath->sw_stats->ring_stats;
+	ring->config = config;
+	ring->callback = attr->callback;
+	ring->rxd_init = attr->rxd_init;
+	ring->rxd_term = attr->rxd_term;
+	ring->buffer_mode = config->buffer_mode;
+	ring->rxds_limit = config->rxds_limit;
+
+	ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
+	ring->rxd_priv_size =
+		sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
+	ring->per_rxd_space = attr->per_rxd_space;
+
+	ring->rxd_priv_size =
+		((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
+		VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
+
+	/* how many RxDs can fit into one block. Depends on configured
+	 * buffer_mode. */
+	ring->rxds_per_block =
+		vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+
+	/* calculate actual RxD block private size */
+	ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
+	ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc;
+	ring->mempool = __vxge_hw_mempool_create(hldev,
+				VXGE_HW_BLOCK_SIZE,
+				VXGE_HW_BLOCK_SIZE,
+				ring->rxdblock_priv_size,
+				ring->config->ring_blocks,
+				ring->config->ring_blocks,
+				&ring_mp_callback,
+				ring);
+
+	if (ring->mempool == NULL) {
+		__vxge_hw_ring_delete(vp);
+		return VXGE_HW_ERR_OUT_OF_MEMORY;
+	}
+
+	status = __vxge_hw_channel_initialize(&ring->channel);
+	if (status != VXGE_HW_OK) {
+		__vxge_hw_ring_delete(vp);
+		goto exit;
+	}
+
+	/* Note:
+	 * Specifying rxd_init callback means two things:
+	 * 1) rxds need to be initialized by driver at channel-open time;
+	 * 2) rxds need to be posted at channel-open time
+	 *    (that's what the initial_replenish() below does)
+	 * Currently we don't have a case when the 1) is done without the 2).
+	 */
+	if (ring->rxd_init) {
+		status = vxge_hw_ring_replenish(ring, 1);
+		if (status != VXGE_HW_OK) {
+			__vxge_hw_ring_delete(vp);
+			goto exit;
+		}
+	}
+
+	/* initial replenish will increment the counter in its post() routine,
+	 * we have to reset it */
+	ring->stats->common_stats.usage_cnt = 0;
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_ring_abort - Returns the RxD
+ * This function terminates the RxDs of ring
+ */
+enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
+{
+	void *rxdh;
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	for (;;) {
+		vxge_hw_channel_dtr_try_complete(channel, &rxdh);
+
+		if (rxdh == NULL)
+			break;
+
+		vxge_hw_channel_dtr_complete(channel);
+
+		if (ring->rxd_term)
+			ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
+				channel->userdata);
+
+		vxge_hw_channel_dtr_free(channel, rxdh);
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_ring_reset - Resets the ring
+ * This function resets the ring during vpath reset operation
+ */
+enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	__vxge_hw_ring_abort(ring);
+
+	status = __vxge_hw_channel_reset(channel);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	if (ring->rxd_init) {
+		status = vxge_hw_ring_replenish(ring, 1);
+		if (status != VXGE_HW_OK)
+			goto exit;
+	}
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_ring_delete - Removes the ring
+ * This function freeup the memory pool and removes the ring
+ */
+enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_ring *ring = vp->vpath->ringh;
+
+	__vxge_hw_ring_abort(ring);
+
+	if (ring->mempool)
+		__vxge_hw_mempool_destroy(ring->mempool);
+
+	vp->vpath->ringh = NULL;
+	__vxge_hw_channel_free(&ring->channel);
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_mempool_grow
+ * Will resize mempool up to %num_allocate value.
+ */
+enum vxge_hw_status
+__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate,
+		       u32 *num_allocated)
+{
+	u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0;
+	u32 n_items = mempool->items_per_memblock;
+	u32 start_block_idx = mempool->memblocks_allocated;
+	u32 end_block_idx = mempool->memblocks_allocated + num_allocate;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	*num_allocated = 0;
+
+	if (end_block_idx > mempool->memblocks_max) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	for (i = start_block_idx; i < end_block_idx; i++) {
+		u32 j;
+		u32 is_last = ((end_block_idx - 1) == i);
+		struct vxge_hw_mempool_dma *dma_object =
+			mempool->memblocks_dma_arr + i;
+		void *the_memblock;
+
+		/* allocate memblock's private part. Each DMA memblock
+		 * has a space allocated for item's private usage upon
+		 * mempool's user request. Each time mempool grows, it will
+		 * allocate new memblock and its private part at once.
+		 * This helps to minimize memory usage a lot. */
+		mempool->memblocks_priv_arr[i] =
+				vmalloc(mempool->items_priv_size * n_items);
+		if (mempool->memblocks_priv_arr[i] == NULL) {
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto exit;
+		}
+
+		memset(mempool->memblocks_priv_arr[i], 0,
+			     mempool->items_priv_size * n_items);
+
+		/* allocate DMA-capable memblock */
+		mempool->memblocks_arr[i] =
+			__vxge_hw_blockpool_malloc(mempool->devh,
+				mempool->memblock_size, dma_object);
+		if (mempool->memblocks_arr[i] == NULL) {
+			vfree(mempool->memblocks_priv_arr[i]);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto exit;
+		}
+
+		(*num_allocated)++;
+		mempool->memblocks_allocated++;
+
+		memset(mempool->memblocks_arr[i], 0, mempool->memblock_size);
+
+		the_memblock = mempool->memblocks_arr[i];
+
+		/* fill the items hash array */
+		for (j = 0; j < n_items; j++) {
+			u32 index = i * n_items + j;
+
+			if (first_time && index >= mempool->items_initial)
+				break;
+
+			mempool->items_arr[index] =
+				((char *)the_memblock + j*mempool->item_size);
+
+			/* let caller to do more job on each item */
+			if (mempool->item_func_alloc != NULL)
+				mempool->item_func_alloc(mempool, i,
+					dma_object, index, is_last);
+
+			mempool->items_current = index + 1;
+		}
+
+		if (first_time && mempool->items_current ==
+					mempool->items_initial)
+			break;
+	}
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_mempool_create
+ * This function will create memory pool object. Pool may grow but will
+ * never shrink. Pool consists of number of dynamically allocated blocks
+ * with size enough to hold %items_initial number of items. Memory is
+ * DMA-able but client must map/unmap before interoperating with the device.
+ */
+struct vxge_hw_mempool*
+__vxge_hw_mempool_create(
+	struct __vxge_hw_device *devh,
+	u32 memblock_size,
+	u32 item_size,
+	u32 items_priv_size,
+	u32 items_initial,
+	u32 items_max,
+	struct vxge_hw_mempool_cbs *mp_callback,
+	void *userdata)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	u32 memblocks_to_allocate;
+	struct vxge_hw_mempool *mempool = NULL;
+	u32 allocated;
+
+	if (memblock_size < item_size) {
+		status = VXGE_HW_FAIL;
+		goto exit;
+	}
+
+	mempool = (struct vxge_hw_mempool *)
+			vmalloc(sizeof(struct vxge_hw_mempool));
+	if (mempool == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+	memset(mempool, 0, sizeof(struct vxge_hw_mempool));
+
+	mempool->devh			= devh;
+	mempool->memblock_size		= memblock_size;
+	mempool->items_max		= items_max;
+	mempool->items_initial		= items_initial;
+	mempool->item_size		= item_size;
+	mempool->items_priv_size	= items_priv_size;
+	mempool->item_func_alloc	= mp_callback->item_func_alloc;
+	mempool->userdata		= userdata;
+
+	mempool->memblocks_allocated = 0;
+
+	mempool->items_per_memblock = memblock_size / item_size;
+
+	mempool->memblocks_max = (items_max + mempool->items_per_memblock - 1) /
+					mempool->items_per_memblock;
+
+	/* allocate array of memblocks */
+	mempool->memblocks_arr =
+		(void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+	if (mempool->memblocks_arr == NULL) {
+		__vxge_hw_mempool_destroy(mempool);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		mempool = NULL;
+		goto exit;
+	}
+	memset(mempool->memblocks_arr, 0,
+		sizeof(void *) * mempool->memblocks_max);
+
+	/* allocate array of private parts of items per memblocks */
+	mempool->memblocks_priv_arr =
+		(void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+	if (mempool->memblocks_priv_arr == NULL) {
+		__vxge_hw_mempool_destroy(mempool);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		mempool = NULL;
+		goto exit;
+	}
+	memset(mempool->memblocks_priv_arr, 0,
+		    sizeof(void *) * mempool->memblocks_max);
+
+	/* allocate array of memblocks DMA objects */
+	mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *)
+		vmalloc(sizeof(struct vxge_hw_mempool_dma) *
+			mempool->memblocks_max);
+
+	if (mempool->memblocks_dma_arr == NULL) {
+		__vxge_hw_mempool_destroy(mempool);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		mempool = NULL;
+		goto exit;
+	}
+	memset(mempool->memblocks_dma_arr, 0,
+			sizeof(struct vxge_hw_mempool_dma) *
+			mempool->memblocks_max);
+
+	/* allocate hash array of items */
+	mempool->items_arr =
+		(void **) vmalloc(sizeof(void *) * mempool->items_max);
+	if (mempool->items_arr == NULL) {
+		__vxge_hw_mempool_destroy(mempool);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		mempool = NULL;
+		goto exit;
+	}
+	memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max);
+
+	/* calculate initial number of memblocks */
+	memblocks_to_allocate = (mempool->items_initial +
+				 mempool->items_per_memblock - 1) /
+						mempool->items_per_memblock;
+
+	/* pre-allocate the mempool */
+	status = __vxge_hw_mempool_grow(mempool, memblocks_to_allocate,
+					&allocated);
+	if (status != VXGE_HW_OK) {
+		__vxge_hw_mempool_destroy(mempool);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		mempool = NULL;
+		goto exit;
+	}
+
+exit:
+	return mempool;
+}
+
+/*
+ * vxge_hw_mempool_destroy
+ */
+void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
+{
+	u32 i, j;
+	struct __vxge_hw_device *devh = mempool->devh;
+
+	for (i = 0; i < mempool->memblocks_allocated; i++) {
+		struct vxge_hw_mempool_dma *dma_object;
+
+		vxge_assert(mempool->memblocks_arr[i]);
+		vxge_assert(mempool->memblocks_dma_arr + i);
+
+		dma_object = mempool->memblocks_dma_arr + i;
+
+		for (j = 0; j < mempool->items_per_memblock; j++) {
+			u32 index = i * mempool->items_per_memblock + j;
+
+			/* to skip last partially filled(if any) memblock */
+			if (index >= mempool->items_current)
+				break;
+		}
+
+		vfree(mempool->memblocks_priv_arr[i]);
+
+		__vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
+				mempool->memblock_size, dma_object);
+	}
+
+	if (mempool->items_arr)
+		vfree(mempool->items_arr);
+
+	if (mempool->memblocks_dma_arr)
+		vfree(mempool->memblocks_dma_arr);
+
+	if (mempool->memblocks_priv_arr)
+		vfree(mempool->memblocks_priv_arr);
+
+	if (mempool->memblocks_arr)
+		vfree(mempool->memblocks_arr);
+
+	vfree(mempool);
+}
+
+/*
+ * __vxge_hw_device_fifo_config_check - Check fifo configuration.
+ * Check the fifo configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
+{
+	if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
+	     (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
+		return VXGE_HW_BADCFG_FIFO_BLOCKS;
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_vpath_config_check - Check vpath configuration.
+ * Check the vpath configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
+{
+	enum vxge_hw_status status;
+
+	if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
+		(vp_config->min_bandwidth >
+					VXGE_HW_VPATH_BANDWIDTH_MAX))
+		return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
+
+	status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
+	if (status != VXGE_HW_OK)
+		return status;
+
+	if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
+		((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
+		(vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
+		return VXGE_HW_BADCFG_VPATH_MTU;
+
+	if ((vp_config->rpa_strip_vlan_tag !=
+		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
+		(vp_config->rpa_strip_vlan_tag !=
+		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
+		(vp_config->rpa_strip_vlan_tag !=
+		VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
+		return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_config_check - Check device configuration.
+ * Check the device configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
+{
+	u32 i;
+	enum vxge_hw_status status;
+
+	if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
+	   (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
+	   (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
+	   (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
+		return VXGE_HW_BADCFG_INTR_MODE;
+
+	if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
+	   (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
+		return VXGE_HW_BADCFG_RTS_MAC_EN;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		status = __vxge_hw_device_vpath_config_check(
+				&new_config->vp_config[i]);
+		if (status != VXGE_HW_OK)
+			return status;
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_device_config_default_get - Initialize device config with defaults.
+ * Initialize Titan device config with default values.
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
+{
+	u32 i;
+
+	device_config->dma_blockpool_initial =
+					VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
+	device_config->dma_blockpool_max = VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
+	device_config->intr_mode = VXGE_HW_INTR_MODE_DEF;
+	device_config->rth_en = VXGE_HW_RTH_DEFAULT;
+	device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_DEFAULT;
+	device_config->device_poll_millis =  VXGE_HW_DEF_DEVICE_POLL_MILLIS;
+	device_config->rts_mac_en =  VXGE_HW_RTS_MAC_DEFAULT;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		device_config->vp_config[i].vp_id = i;
+
+		device_config->vp_config[i].min_bandwidth =
+				VXGE_HW_VPATH_BANDWIDTH_DEFAULT;
+
+		device_config->vp_config[i].ring.enable = VXGE_HW_RING_DEFAULT;
+
+		device_config->vp_config[i].ring.ring_blocks =
+				VXGE_HW_DEF_RING_BLOCKS;
+
+		device_config->vp_config[i].ring.buffer_mode =
+				VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT;
+
+		device_config->vp_config[i].ring.scatter_mode =
+				VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].ring.rxds_limit =
+				VXGE_HW_DEF_RING_RXDS_LIMIT;
+
+		device_config->vp_config[i].fifo.enable = VXGE_HW_FIFO_ENABLE;
+
+		device_config->vp_config[i].fifo.fifo_blocks =
+				VXGE_HW_MIN_FIFO_BLOCKS;
+
+		device_config->vp_config[i].fifo.max_frags =
+				VXGE_HW_MAX_FIFO_FRAGS;
+
+		device_config->vp_config[i].fifo.memblock_size =
+				VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE;
+
+		device_config->vp_config[i].fifo.alignment_size =
+				VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE;
+
+		device_config->vp_config[i].fifo.intr =
+				VXGE_HW_FIFO_QUEUE_INTR_DEFAULT;
+
+		device_config->vp_config[i].fifo.no_snoop_bits =
+				VXGE_HW_FIFO_NO_SNOOP_DEFAULT;
+		device_config->vp_config[i].tti.intr_enable =
+				VXGE_HW_TIM_INTR_DEFAULT;
+
+		device_config->vp_config[i].tti.btimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.timer_ac_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.timer_ci_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.timer_ri_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.rtimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.util_sel =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.ltimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.urange_a =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.uec_a =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.urange_b =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.uec_b =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.urange_c =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.uec_c =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].tti.uec_d =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.intr_enable =
+				VXGE_HW_TIM_INTR_DEFAULT;
+
+		device_config->vp_config[i].rti.btimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.timer_ac_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.timer_ci_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.timer_ri_en =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.rtimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.util_sel =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.ltimer_val =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.urange_a =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.uec_a =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.urange_b =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.uec_b =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.urange_c =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.uec_c =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].rti.uec_d =
+				VXGE_HW_USE_FLASH_DEFAULT;
+
+		device_config->vp_config[i].mtu =
+				VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU;
+
+		device_config->vp_config[i].rpa_strip_vlan_tag =
+			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT;
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
+ * Set the swapper bits appropriately for the lagacy section.
+ */
+enum vxge_hw_status
+__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = readq(&legacy_reg->toc_swapper_fb);
+
+	wmb();
+
+	switch (val64) {
+
+	case VXGE_HW_SWAPPER_INITIAL_VALUE:
+		return status;
+
+	case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
+		writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+			&legacy_reg->pifm_rd_swap_en);
+		writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+			&legacy_reg->pifm_rd_flip_en);
+		writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+			&legacy_reg->pifm_wr_swap_en);
+		writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+			&legacy_reg->pifm_wr_flip_en);
+		break;
+
+	case VXGE_HW_SWAPPER_BYTE_SWAPPED:
+		writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+			&legacy_reg->pifm_rd_swap_en);
+		writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+			&legacy_reg->pifm_wr_swap_en);
+		break;
+
+	case VXGE_HW_SWAPPER_BIT_FLIPPED:
+		writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+			&legacy_reg->pifm_rd_flip_en);
+		writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+			&legacy_reg->pifm_wr_flip_en);
+		break;
+	}
+
+	wmb();
+
+	val64 = readq(&legacy_reg->toc_swapper_fb);
+
+	if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
+		status = VXGE_HW_ERR_SWAPPER_CTRL;
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
+ * Set the swapper bits appropriately for the vpath.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+#ifndef __BIG_ENDIAN
+	u64 val64;
+
+	val64 = readq(&vpath_reg->vpath_general_cfg1);
+	wmb();
+	val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN;
+	writeq(val64, &vpath_reg->vpath_general_cfg1);
+	wmb();
+#endif
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc.
+ * Set the swapper bits appropriately for the vpath.
+ */
+enum vxge_hw_status
+__vxge_hw_kdfc_swapper_set(
+	struct vxge_hw_legacy_reg __iomem *legacy_reg,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+	u64 val64;
+
+	val64 = readq(&legacy_reg->pifm_wr_swap_en);
+
+	if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) {
+		val64 = readq(&vpath_reg->kdfcctl_cfg0);
+		wmb();
+
+		val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0	|
+			VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1	|
+			VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2;
+
+		writeq(val64, &vpath_reg->kdfcctl_cfg0);
+		wmb();
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_mgmt_device_config - Retrieve device configuration.
+ * Get device configuration. Permits to retrieve at run-time configuration
+ * values that were used to initialize and configure the device.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_device_config(struct __vxge_hw_device *hldev,
+			   struct vxge_hw_device_config *dev_config, int size)
+{
+
+	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC))
+		return VXGE_HW_ERR_INVALID_DEVICE;
+
+	if (size != sizeof(struct vxge_hw_device_config))
+		return VXGE_HW_ERR_VERSION_CONFLICT;
+
+	memcpy(dev_config, &hldev->config,
+		sizeof(struct vxge_hw_device_config));
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_mgmt_reg_read - Read Titan register.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_reg_read(struct __vxge_hw_device *hldev,
+		      enum vxge_hw_mgmt_reg_type type,
+		      u32 index, u32 offset, u64 *value)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+		status = VXGE_HW_ERR_INVALID_DEVICE;
+		goto exit;
+	}
+
+	switch (type) {
+	case vxge_hw_mgmt_reg_type_legacy:
+		if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->legacy_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_toc:
+		if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->toc_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_common:
+		if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->common_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_mrpcim:
+		if (!(hldev->access_rights &
+			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->mrpcim_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_srpcim:
+		if (!(hldev->access_rights &
+			VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
+			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+			break;
+		}
+		if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->srpcim_reg[index] +
+				offset);
+		break;
+	case vxge_hw_mgmt_reg_type_vpmgmt:
+		if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
+			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->vpmgmt_reg[index] +
+				offset);
+		break;
+	case vxge_hw_mgmt_reg_type_vpath:
+		if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) ||
+			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		*value = readq((void __iomem *)hldev->vpath_reg[index] +
+				offset);
+		break;
+	default:
+		status = VXGE_HW_ERR_INVALID_TYPE;
+		break;
+	}
+
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_mgmt_reg_Write - Write Titan register.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_reg_write(struct __vxge_hw_device *hldev,
+		      enum vxge_hw_mgmt_reg_type type,
+		      u32 index, u32 offset, u64 value)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+		status = VXGE_HW_ERR_INVALID_DEVICE;
+		goto exit;
+	}
+
+	switch (type) {
+	case vxge_hw_mgmt_reg_type_legacy:
+		if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->legacy_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_toc:
+		if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->toc_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_common:
+		if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->common_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_mrpcim:
+		if (!(hldev->access_rights &
+			VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->mrpcim_reg + offset);
+		break;
+	case vxge_hw_mgmt_reg_type_srpcim:
+		if (!(hldev->access_rights &
+			VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
+			status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+			break;
+		}
+		if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->srpcim_reg[index] +
+			offset);
+
+		break;
+	case vxge_hw_mgmt_reg_type_vpmgmt:
+		if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
+			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->vpmgmt_reg[index] +
+			offset);
+		break;
+	case vxge_hw_mgmt_reg_type_vpath:
+		if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES-1) ||
+			(!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+			status = VXGE_HW_ERR_INVALID_INDEX;
+			break;
+		}
+		if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
+			status = VXGE_HW_ERR_INVALID_OFFSET;
+			break;
+		}
+		writeq(value, (void __iomem *)hldev->vpath_reg[index] +
+			offset);
+		break;
+	default:
+		status = VXGE_HW_ERR_INVALID_TYPE;
+		break;
+	}
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD
+ * list callback
+ * This function is callback passed to __vxge_hw_mempool_create to create memory
+ * pool for TxD list
+ */
+static void
+__vxge_hw_fifo_mempool_item_alloc(
+	struct vxge_hw_mempool *mempoolh,
+	u32 memblock_index, struct vxge_hw_mempool_dma *dma_object,
+	u32 index, u32 is_last)
+{
+	u32 memblock_item_idx;
+	struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+	struct vxge_hw_fifo_txd *txdp =
+		(struct vxge_hw_fifo_txd *)mempoolh->items_arr[index];
+	struct __vxge_hw_fifo *fifo =
+			(struct __vxge_hw_fifo *)mempoolh->userdata;
+	void *memblock = mempoolh->memblocks_arr[memblock_index];
+
+	vxge_assert(txdp);
+
+	txdp->host_control = (u64) (size_t)
+	__vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp,
+					&memblock_item_idx);
+
+	txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
+
+	vxge_assert(txdl_priv);
+
+	fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp;
+
+	/* pre-format HW's TxDL's private */
+	txdl_priv->dma_offset = (char *)txdp - (char *)memblock;
+	txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset;
+	txdl_priv->dma_handle = dma_object->handle;
+	txdl_priv->memblock   = memblock;
+	txdl_priv->first_txdp = txdp;
+	txdl_priv->next_txdl_priv = NULL;
+	txdl_priv->alloc_frags = 0;
+
+	return;
+}
+
+/*
+ * __vxge_hw_fifo_create - Create a FIFO
+ * This function creates FIFO and initializes it.
+ */
+enum vxge_hw_status
+__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp,
+		      struct vxge_hw_fifo_attr *attr)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_fifo *fifo;
+	struct vxge_hw_fifo_config *config;
+	u32 txdl_size, txdl_per_memblock;
+	struct vxge_hw_mempool_cbs fifo_mp_callback;
+	struct __vxge_hw_virtualpath *vpath;
+
+	if ((vp == NULL) || (attr == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+	vpath = vp->vpath;
+	config = &vpath->hldev->config.vp_config[vpath->vp_id].fifo;
+
+	txdl_size = config->max_frags * sizeof(struct vxge_hw_fifo_txd);
+
+	txdl_per_memblock = config->memblock_size / txdl_size;
+
+	fifo = (struct __vxge_hw_fifo *)__vxge_hw_channel_allocate(vp,
+					VXGE_HW_CHANNEL_TYPE_FIFO,
+					config->fifo_blocks * txdl_per_memblock,
+					attr->per_txdl_space, attr->userdata);
+
+	if (fifo == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	vpath->fifoh = fifo;
+	fifo->nofl_db = vpath->nofl_db;
+
+	fifo->vp_id = vpath->vp_id;
+	fifo->vp_reg = vpath->vp_reg;
+	fifo->stats = &vpath->sw_stats->fifo_stats;
+
+	fifo->config = config;
+
+	/* apply "interrupts per txdl" attribute */
+	fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ;
+
+	if (fifo->config->intr)
+		fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST;
+
+	fifo->no_snoop_bits = config->no_snoop_bits;
+
+	/*
+	 * FIFO memory management strategy:
+	 *
+	 * TxDL split into three independent parts:
+	 *	- set of TxD's
+	 *	- TxD HW private part
+	 *	- driver private part
+	 *
+	 * Adaptative memory allocation used. i.e. Memory allocated on
+	 * demand with the size which will fit into one memory block.
+	 * One memory block may contain more than one TxDL.
+	 *
+	 * During "reserve" operations more memory can be allocated on demand
+	 * for example due to FIFO full condition.
+	 *
+	 * Pool of memory memblocks never shrinks except in __vxge_hw_fifo_close
+	 * routine which will essentially stop the channel and free resources.
+	 */
+
+	/* TxDL common private size == TxDL private  +  driver private */
+	fifo->priv_size =
+		sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space;
+	fifo->priv_size = ((fifo->priv_size  +  VXGE_CACHE_LINE_SIZE - 1) /
+			VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
+
+	fifo->per_txdl_space = attr->per_txdl_space;
+
+	/* recompute txdl size to be cacheline aligned */
+	fifo->txdl_size = txdl_size;
+	fifo->txdl_per_memblock = txdl_per_memblock;
+
+	fifo->txdl_term = attr->txdl_term;
+	fifo->callback = attr->callback;
+
+	if (fifo->txdl_per_memblock == 0) {
+		__vxge_hw_fifo_delete(vp);
+		status = VXGE_HW_ERR_INVALID_BLOCK_SIZE;
+		goto exit;
+	}
+
+	fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc;
+
+	fifo->mempool =
+		__vxge_hw_mempool_create(vpath->hldev,
+			fifo->config->memblock_size,
+			fifo->txdl_size,
+			fifo->priv_size,
+			(fifo->config->fifo_blocks * fifo->txdl_per_memblock),
+			(fifo->config->fifo_blocks * fifo->txdl_per_memblock),
+			&fifo_mp_callback,
+			fifo);
+
+	if (fifo->mempool == NULL) {
+		__vxge_hw_fifo_delete(vp);
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto exit;
+	}
+
+	status = __vxge_hw_channel_initialize(&fifo->channel);
+	if (status != VXGE_HW_OK) {
+		__vxge_hw_fifo_delete(vp);
+		goto exit;
+	}
+
+	vxge_assert(fifo->channel.reserve_ptr);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_fifo_abort - Returns the TxD
+ * This function terminates the TxDs of fifo
+ */
+enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
+{
+	void *txdlh;
+
+	for (;;) {
+		vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
+
+		if (txdlh == NULL)
+			break;
+
+		vxge_hw_channel_dtr_complete(&fifo->channel);
+
+		if (fifo->txdl_term) {
+			fifo->txdl_term(txdlh,
+			VXGE_HW_TXDL_STATE_POSTED,
+			fifo->channel.userdata);
+		}
+
+		vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
+	}
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_fifo_reset - Resets the fifo
+ * This function resets the fifo during vpath reset operation
+ */
+enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	__vxge_hw_fifo_abort(fifo);
+	status = __vxge_hw_channel_reset(&fifo->channel);
+
+	return status;
+}
+
+/*
+ * __vxge_hw_fifo_delete - Removes the FIFO
+ * This function freeup the memory pool and removes the FIFO
+ */
+enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
+
+	__vxge_hw_fifo_abort(fifo);
+
+	if (fifo->mempool)
+		__vxge_hw_mempool_destroy(fifo->mempool);
+
+	vp->vpath->fifoh = NULL;
+
+	__vxge_hw_channel_free(&fifo->channel);
+
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_vpath_pci_read - Read the content of given address
+ *                          in pci config space.
+ * Read from the vpath pci config space.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath,
+			 u32 phy_func_0, u32 offset, u32 *val)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
+
+	val64 =	VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset);
+
+	if (phy_func_0)
+		val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0;
+
+	writeq(val64, &vp_reg->pci_config_access_cfg1);
+	wmb();
+	writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ,
+			&vp_reg->pci_config_access_cfg2);
+	wmb();
+
+	status = __vxge_hw_device_register_poll(
+			&vp_reg->pci_config_access_cfg2,
+			VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vp_reg->pci_config_access_status);
+
+	if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) {
+		status = VXGE_HW_FAIL;
+		*val = 0;
+	} else
+		*val = (u32)vxge_bVALn(val64, 32, 32);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
+ * Returns the function number of the vpath.
+ */
+u32
+__vxge_hw_vpath_func_id_get(u32 vp_id,
+	struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
+{
+	u64 val64;
+
+	val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
+
+	return
+	 (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
+}
+
+/*
+ * __vxge_hw_read_rts_ds - Program RTS steering critieria
+ */
+static inline void
+__vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg,
+		      u64 dta_struct_sel)
+{
+	writeq(0, &vpath_reg->rts_access_steer_ctrl);
+	wmb();
+	writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0);
+	writeq(0, &vpath_reg->rts_access_steer_data1);
+	wmb();
+	return;
+}
+
+
+/*
+ * __vxge_hw_vpath_card_info_get - Get the serial numbers,
+ * part number and product description.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_card_info_get(
+	u32 vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	struct vxge_hw_device_hw_info *hw_info)
+{
+	u32 i, j;
+	u64 val64;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	u8 *serial_number = hw_info->serial_number;
+	u8 *part_number = hw_info->part_number;
+	u8 *product_desc = hw_info->product_desc;
+
+	__vxge_hw_read_rts_ds(vpath_reg,
+		VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER);
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		return status;
+
+	val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+		data1 = readq(&vpath_reg->rts_access_steer_data0);
+		((u64 *)serial_number)[0] = be64_to_cpu(data1);
+
+		data2 = readq(&vpath_reg->rts_access_steer_data1);
+		((u64 *)serial_number)[1] = be64_to_cpu(data2);
+		status = VXGE_HW_OK;
+	} else
+		*serial_number = 0;
+
+	__vxge_hw_read_rts_ds(vpath_reg,
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER);
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		return status;
+
+	val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+		data1 = readq(&vpath_reg->rts_access_steer_data0);
+		((u64 *)part_number)[0] = be64_to_cpu(data1);
+
+		data2 = readq(&vpath_reg->rts_access_steer_data1);
+		((u64 *)part_number)[1] = be64_to_cpu(data2);
+
+		status = VXGE_HW_OK;
+
+	} else
+		*part_number = 0;
+
+	j = 0;
+
+	for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
+	     i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
+
+		__vxge_hw_read_rts_ds(vpath_reg, i);
+
+		val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+		status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+		if (status != VXGE_HW_OK)
+			return status;
+
+		val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+		if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+			data1 = readq(&vpath_reg->rts_access_steer_data0);
+			((u64 *)product_desc)[j++] = be64_to_cpu(data1);
+
+			data2 = readq(&vpath_reg->rts_access_steer_data1);
+			((u64 *)product_desc)[j++] = be64_to_cpu(data2);
+
+			status = VXGE_HW_OK;
+		} else
+			*product_desc = 0;
+	}
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_fw_ver_get - Get the fw version
+ * Returns FW Version
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_fw_ver_get(
+	u32 vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	struct vxge_hw_device_hw_info *hw_info)
+{
+	u64 val64;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
+	struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
+	struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
+	struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+		data1 = readq(&vpath_reg->rts_access_steer_data0);
+		data2 = readq(&vpath_reg->rts_access_steer_data1);
+
+		fw_date->day =
+			(u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(
+						data1);
+		fw_date->month =
+			(u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(
+						data1);
+		fw_date->year =
+			(u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(
+						data1);
+
+		snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
+			fw_date->month, fw_date->day, fw_date->year);
+
+		fw_version->major =
+		    (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1);
+		fw_version->minor =
+		    (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1);
+		fw_version->build =
+		    (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1);
+
+		snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+		    fw_version->major, fw_version->minor, fw_version->build);
+
+		flash_date->day =
+		  (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2);
+		flash_date->month =
+		 (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2);
+		flash_date->year =
+		 (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2);
+
+		snprintf(flash_date->date, VXGE_HW_FW_STRLEN,
+			"%2.2d/%2.2d/%4.4d",
+			flash_date->month, flash_date->day, flash_date->year);
+
+		flash_version->major =
+		 (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2);
+		flash_version->minor =
+		 (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2);
+		flash_version->build =
+		 (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2);
+
+		snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+			flash_version->major, flash_version->minor,
+			flash_version->build);
+
+		status = VXGE_HW_OK;
+
+	} else
+		status = VXGE_HW_FAIL;
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
+ * Returns pci function mode
+ */
+u64
+__vxge_hw_vpath_pci_func_mode_get(
+	u32  vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+	u64 val64;
+	u64 data1 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	__vxge_hw_read_rts_ds(vpath_reg,
+		VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE);
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+		data1 = readq(&vpath_reg->rts_access_steer_data0);
+		status = VXGE_HW_OK;
+	} else {
+		data1 = 0;
+		status = VXGE_HW_FAIL;
+	}
+exit:
+	return data1;
+}
+
+/**
+ * vxge_hw_device_flick_link_led - Flick (blink) link LED.
+ * @hldev: HW device.
+ * @on_off: TRUE if flickering to be on, FALSE to be off
+ *
+ * Flicker the link LED.
+ */
+enum vxge_hw_status
+vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev,
+			       u64 on_off)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	if (hldev == NULL) {
+		status = VXGE_HW_ERR_INVALID_DEVICE;
+		goto exit;
+	}
+
+	vp_reg = hldev->vpath_reg[hldev->first_vp_id];
+
+	writeq(0, &vp_reg->rts_access_steer_ctrl);
+	wmb();
+	writeq(on_off, &vp_reg->rts_access_steer_data0);
+	writeq(0, &vp_reg->rts_access_steer_data1);
+	wmb();
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vp_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_get(
+	struct __vxge_hw_vpath_handle *vp,
+	u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+	vp_reg = vpath->vp_reg;
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
+
+	if ((rts_table ==
+		VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
+	    (rts_table ==
+		VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
+	    (rts_table ==
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
+	    (rts_table ==
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
+		val64 = val64 |	VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
+	}
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vp_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				vpath->hldev->config.device_poll_millis);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vp_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+		*data1 = readq(&vp_reg->rts_access_steer_data0);
+
+		if ((rts_table ==
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
+		(rts_table ==
+		VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
+			*data2 = readq(&vp_reg->rts_access_steer_data1);
+		}
+		status = VXGE_HW_OK;
+	} else
+		status = VXGE_HW_FAIL;
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_set(
+	struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table,
+	u32 offset, u64 data1, u64 data2)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+	vp_reg = vpath->vp_reg;
+
+	writeq(data1, &vp_reg->rts_access_steer_data0);
+	wmb();
+
+	if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
+	    (rts_table ==
+		VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
+		writeq(data2, &vp_reg->rts_access_steer_data1);
+		wmb();
+	}
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vp_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				vpath->hldev->config.device_poll_millis);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vp_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS)
+		status = VXGE_HW_OK;
+	else
+		status = VXGE_HW_FAIL;
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
+ *               from MAC address table.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_addr_get(
+	u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN])
+{
+	u32 i;
+	u64 val64;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vpath_reg->rts_access_steer_ctrl,
+				VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+				VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+	if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+		data1 = readq(&vpath_reg->rts_access_steer_data0);
+		data2 = readq(&vpath_reg->rts_access_steer_data1);
+
+		data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+		data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
+							data2);
+
+		for (i = ETH_ALEN; i > 0; i--) {
+			macaddr[i-1] = (u8)(data1 & 0xFF);
+			data1 >>= 8;
+
+			macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+			data2 >>= 8;
+		}
+		status = VXGE_HW_OK;
+	} else
+		status = VXGE_HW_FAIL;
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_rts_rth_set - Set/configure RTS hashing.
+ */
+enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
+			struct __vxge_hw_vpath_handle *vp,
+			enum vxge_hw_rth_algoritms algorithm,
+			struct vxge_hw_rth_hash_types *hash_type,
+			u16 bucket_size)
+{
+	u64 data0, data1;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_get(vp,
+		     VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
+		     VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
+			0, &data0, &data1);
+
+	data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
+
+	data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN |
+	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(bucket_size) |
+	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(algorithm);
+
+	if (hash_type->hash_type_tcpipv4_en)
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN;
+
+	if (hash_type->hash_type_ipv4_en)
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN;
+
+	if (hash_type->hash_type_tcpipv6_en)
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN;
+
+	if (hash_type->hash_type_ipv6_en)
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN;
+
+	if (hash_type->hash_type_tcpipv6ex_en)
+		data0 |=
+		VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN;
+
+	if (hash_type->hash_type_ipv6ex_en)
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN;
+
+	if (VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(data0))
+		data0 &= ~VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
+	else
+		data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
+
+	status = __vxge_hw_vpath_rts_table_set(vp,
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY,
+		VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
+		0, data0, 0);
+exit:
+	return status;
+}
+
+static void
+vxge_hw_rts_rth_data0_data1_get(u32 j, u64 *data0, u64 *data1,
+				u16 flag, u8 *itable)
+{
+	switch (flag) {
+	case 1:
+		*data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(j)|
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN |
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(
+			itable[j]);
+	case 2:
+		*data0 |=
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(j)|
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN |
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(
+			itable[j]);
+	case 3:
+		*data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(j)|
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN |
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(
+			itable[j]);
+	case 4:
+		*data1 |=
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(j)|
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN |
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(
+			itable[j]);
+	default:
+		return;
+	}
+}
+/*
+ * vxge_hw_vpath_rts_rth_itable_set - Set/configure indirection table (IT).
+ */
+enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
+			struct __vxge_hw_vpath_handle **vpath_handles,
+			u32 vpath_count,
+			u8 *mtable,
+			u8 *itable,
+			u32 itable_size)
+{
+	u32 i, j, action, rts_table;
+	u64 data0;
+	u64 data1;
+	u32 max_entries;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_vpath_handle *vp = vpath_handles[0];
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	max_entries = (((u32)1) << itable_size);
+
+	if (vp->vpath->hldev->config.rth_it_type
+				== VXGE_HW_RTH_IT_TYPE_SOLO_IT) {
+		action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
+		rts_table =
+			VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT;
+
+		for (j = 0; j < max_entries; j++) {
+
+			data1 = 0;
+
+			data0 =
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
+				itable[j]);
+
+			status = __vxge_hw_vpath_rts_table_set(vpath_handles[0],
+				action, rts_table, j, data0, data1);
+
+			if (status != VXGE_HW_OK)
+				goto exit;
+		}
+
+		for (j = 0; j < max_entries; j++) {
+
+			data1 = 0;
+
+			data0 =
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN |
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
+				itable[j]);
+
+			status = __vxge_hw_vpath_rts_table_set(
+				vpath_handles[mtable[itable[j]]], action,
+				rts_table, j, data0, data1);
+
+			if (status != VXGE_HW_OK)
+				goto exit;
+		}
+	} else {
+		action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
+		rts_table =
+			VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT;
+		for (i = 0; i < vpath_count; i++) {
+
+			for (j = 0; j < max_entries;) {
+
+				data0 = 0;
+				data1 = 0;
+
+				while (j < max_entries) {
+					if (mtable[itable[j]] != i) {
+						j++;
+						continue;
+					}
+					vxge_hw_rts_rth_data0_data1_get(j,
+						&data0, &data1, 1, itable);
+					j++;
+					break;
+				}
+
+				while (j < max_entries) {
+					if (mtable[itable[j]] != i) {
+						j++;
+						continue;
+					}
+					vxge_hw_rts_rth_data0_data1_get(j,
+						&data0, &data1, 2, itable);
+					j++;
+					break;
+				}
+
+				while (j < max_entries) {
+					if (mtable[itable[j]] != i) {
+						j++;
+						continue;
+					}
+					vxge_hw_rts_rth_data0_data1_get(j,
+						&data0, &data1, 3, itable);
+					j++;
+					break;
+				}
+
+				while (j < max_entries) {
+					if (mtable[itable[j]] != i) {
+						j++;
+						continue;
+					}
+					vxge_hw_rts_rth_data0_data1_get(j,
+						&data0, &data1, 4, itable);
+					j++;
+					break;
+				}
+
+				if (data0 != 0) {
+					status = __vxge_hw_vpath_rts_table_set(
+							vpath_handles[i],
+							action, rts_table,
+							0, data0, data1);
+
+					if (status != VXGE_HW_OK)
+						goto exit;
+				}
+			}
+		}
+	}
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_check_leak - Check for memory leak
+ * @ringh: Handle to the ring object used for receive
+ *
+ * If PRC_RXD_DOORBELL_VPn.NEW_QW_CNT is larger or equal to
+ * PRC_CFG6_VPn.RXD_SPAT then a leak has occurred.
+ * Returns: VXGE_HW_FAIL, if leak has occurred.
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ring)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	u64 rxd_new_count, rxd_spat;
+
+	if (ring == NULL)
+		return status;
+
+	rxd_new_count = readl(&ring->vp_reg->prc_rxd_doorbell);
+	rxd_spat = readq(&ring->vp_reg->prc_cfg6);
+	rxd_spat = VXGE_HW_PRC_CFG6_RXD_SPAT(rxd_spat);
+
+	if (rxd_new_count >= rxd_spat)
+		status = VXGE_HW_FAIL;
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_mgmt_read
+ * This routine reads the vpath_mgmt registers
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_mgmt_read(
+	struct __vxge_hw_device *hldev,
+	struct __vxge_hw_virtualpath *vpath)
+{
+	u32 i, mtu = 0, max_pyld = 0;
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
+
+		val64 = readq(&vpath->vpmgmt_reg->
+				rxmac_cfg0_port_vpmgmt_clone[i]);
+		max_pyld =
+			(u32)
+			VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN
+			(val64);
+		if (mtu < max_pyld)
+			mtu = max_pyld;
+	}
+
+	vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+	val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp);
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (val64 & vxge_mBIT(i))
+			vpath->vsport_number = i;
+	}
+
+	val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone);
+
+	if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK)
+		VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP);
+	else
+		VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN);
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed
+ * This routine checks the vpath_rst_in_prog register to see if
+ * adapter completed the reset process for the vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath)
+{
+	enum vxge_hw_status status;
+
+	status = __vxge_hw_device_register_poll(
+			&vpath->hldev->common_reg->vpath_rst_in_prog,
+			VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(
+				1 << (16 - vpath->vp_id)),
+			vpath->hldev->config.device_poll_millis);
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_reset
+ * This routine resets the vpath on the device
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id));
+
+	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+				&hldev->common_reg->cmn_rsthdlr_cfg0);
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_sw_reset
+ * This routine resets the vpath structures
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+
+	vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id];
+
+	if (vpath->ringh) {
+		status = __vxge_hw_ring_reset(vpath->ringh);
+		if (status != VXGE_HW_OK)
+			goto exit;
+	}
+
+	if (vpath->fifoh)
+		status = __vxge_hw_fifo_reset(vpath->fifoh);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_prc_configure
+ * This routine configures the prc registers of virtual path using the config
+ * passed
+ */
+void
+__vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vp_config *vp_config;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	vpath = &hldev->virtual_paths[vp_id];
+	vp_reg = vpath->vp_reg;
+	vp_config = vpath->vp_config;
+
+	if (vp_config->ring.enable == VXGE_HW_RING_DISABLE)
+		return;
+
+	val64 = readq(&vp_reg->prc_cfg1);
+	val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE;
+	writeq(val64, &vp_reg->prc_cfg1);
+
+	val64 = readq(&vpath->vp_reg->prc_cfg6);
+	val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN;
+	writeq(val64, &vpath->vp_reg->prc_cfg6);
+
+	val64 = readq(&vp_reg->prc_cfg7);
+
+	if (vpath->vp_config->ring.scatter_mode !=
+		VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT) {
+
+		val64 &= ~VXGE_HW_PRC_CFG7_SCATTER_MODE(0x3);
+
+		switch (vpath->vp_config->ring.scatter_mode) {
+		case VXGE_HW_RING_SCATTER_MODE_A:
+			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+					VXGE_HW_PRC_CFG7_SCATTER_MODE_A);
+			break;
+		case VXGE_HW_RING_SCATTER_MODE_B:
+			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+					VXGE_HW_PRC_CFG7_SCATTER_MODE_B);
+			break;
+		case VXGE_HW_RING_SCATTER_MODE_C:
+			val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+					VXGE_HW_PRC_CFG7_SCATTER_MODE_C);
+			break;
+		}
+	}
+
+	writeq(val64, &vp_reg->prc_cfg7);
+
+	writeq(VXGE_HW_PRC_CFG5_RXD0_ADD(
+				__vxge_hw_ring_first_block_address_get(
+					vpath->ringh) >> 3), &vp_reg->prc_cfg5);
+
+	val64 = readq(&vp_reg->prc_cfg4);
+	val64 |= VXGE_HW_PRC_CFG4_IN_SVC;
+	val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3);
+
+	val64 |= VXGE_HW_PRC_CFG4_RING_MODE(
+			VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER);
+
+	if (hldev->config.rth_en == VXGE_HW_RTH_DISABLE)
+		val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE;
+	else
+		val64 &= ~VXGE_HW_PRC_CFG4_RTH_DISABLE;
+
+	writeq(val64, &vp_reg->prc_cfg4);
+	return;
+}
+
+/*
+ * __vxge_hw_vpath_kdfc_configure
+ * This routine configures the kdfc registers of virtual path using the
+ * config passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	u64 vpath_stride;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	vpath = &hldev->virtual_paths[vp_id];
+	vp_reg = vpath->vp_reg;
+	status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	val64 = readq(&vp_reg->kdfc_drbl_triplet_total);
+
+	vpath->max_kdfc_db =
+		(u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(
+			val64+1)/2;
+
+	if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+
+		vpath->max_nofl_db = vpath->max_kdfc_db;
+
+		if (vpath->max_nofl_db <
+			((vpath->vp_config->fifo.memblock_size /
+			(vpath->vp_config->fifo.max_frags *
+			sizeof(struct vxge_hw_fifo_txd))) *
+			vpath->vp_config->fifo.fifo_blocks)) {
+
+			return VXGE_HW_BADCFG_FIFO_BLOCKS;
+		}
+		val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(
+				(vpath->max_nofl_db*2)-1);
+	}
+
+	writeq(val64, &vp_reg->kdfc_fifo_trpl_partition);
+
+	writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE,
+		&vp_reg->kdfc_fifo_trpl_ctrl);
+
+	val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl);
+
+	val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) |
+		   VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF));
+
+	val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(
+		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) |
+#ifndef __BIG_ENDIAN
+		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN |
+#endif
+		 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0);
+
+	writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl);
+	writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address);
+	wmb();
+	vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride);
+
+	vpath->nofl_db =
+		(struct __vxge_hw_non_offload_db_wrapper __iomem *)
+		(hldev->kdfc + (vp_id *
+		VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(
+					vpath_stride)));
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_mac_configure
+ * This routine configures the mac of virtual path using the config passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vp_config *vp_config;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	vpath = &hldev->virtual_paths[vp_id];
+	vp_reg = vpath->vp_reg;
+	vp_config = vpath->vp_config;
+
+	writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(
+			vpath->vsport_number), &vp_reg->xmac_vsport_choice);
+
+	if (vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
+
+		val64 = readq(&vp_reg->xmac_rpa_vcfg);
+
+		if (vp_config->rpa_strip_vlan_tag !=
+			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) {
+			if (vp_config->rpa_strip_vlan_tag)
+				val64 |= VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
+			else
+				val64 &= ~VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
+		}
+
+		writeq(val64, &vp_reg->xmac_rpa_vcfg);
+		val64 = readq(&vp_reg->rxmac_vcfg0);
+
+		if (vp_config->mtu !=
+				VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) {
+			val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
+			if ((vp_config->mtu  +
+				VXGE_HW_MAC_HEADER_MAX_SIZE) < vpath->max_mtu)
+				val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
+					vp_config->mtu  +
+					VXGE_HW_MAC_HEADER_MAX_SIZE);
+			else
+				val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
+					vpath->max_mtu);
+		}
+
+		writeq(val64, &vp_reg->rxmac_vcfg0);
+
+		val64 = readq(&vp_reg->rxmac_vcfg1);
+
+		val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) |
+			VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE);
+
+		if (hldev->config.rth_it_type ==
+				VXGE_HW_RTH_IT_TYPE_MULTI_IT) {
+			val64 |= VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(
+				0x2) |
+				VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE;
+		}
+
+		writeq(val64, &vp_reg->rxmac_vcfg1);
+	}
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_tim_configure
+ * This routine configures the tim registers of virtual path using the config
+ * passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+	struct vxge_hw_vp_config *config;
+
+	vpath = &hldev->virtual_paths[vp_id];
+	vp_reg = vpath->vp_reg;
+	config = vpath->vp_config;
+
+	writeq((u64)0, &vp_reg->tim_dest_addr);
+	writeq((u64)0, &vp_reg->tim_vpath_map);
+	writeq((u64)0, &vp_reg->tim_bitmap);
+	writeq((u64)0, &vp_reg->tim_remap);
+
+	if (config->ring.enable == VXGE_HW_RING_ENABLE)
+		writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
+			(vp_id * VXGE_HW_MAX_INTR_PER_VP) +
+			VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn);
+
+	val64 = readq(&vp_reg->tim_pci_cfg);
+	val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD;
+	writeq(val64, &vp_reg->tim_pci_cfg);
+
+	if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+
+		val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+		if (config->tti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+				0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+					config->tti.btimer_val);
+		}
+
+		val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
+
+		if (config->tti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->tti.timer_ac_en)
+				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+		}
+
+		if (config->tti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->tti.timer_ci_en)
+				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+		}
+
+		if (config->tti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
+					config->tti.urange_a);
+		}
+
+		if (config->tti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
+					config->tti.urange_b);
+		}
+
+		if (config->tti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
+					config->tti.urange_c);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+		val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+		if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
+						config->tti.uec_a);
+		}
+
+		if (config->tti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
+						config->tti.uec_b);
+		}
+
+		if (config->tti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
+						config->tti.uec_c);
+		}
+
+		if (config->tti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
+						config->tti.uec_d);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
+		val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+		if (config->tti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->tti.timer_ri_en)
+				val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+		}
+
+		if (config->tti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+					0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+					config->tti.rtimer_val);
+		}
+
+		if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
+					config->tti.util_sel);
+		}
+
+		if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+					0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+					config->tti.ltimer_val);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
+	}
+
+	if (config->ring.enable == VXGE_HW_RING_ENABLE) {
+
+		val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+		if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+					0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+					config->rti.btimer_val);
+		}
+
+		val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
+
+		if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->rti.timer_ac_en)
+				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+		}
+
+		if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->rti.timer_ci_en)
+				val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+		}
+
+		if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
+					config->rti.urange_a);
+		}
+
+		if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
+					config->rti.urange_b);
+		}
+
+		if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
+			val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
+					config->rti.urange_c);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
+		val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+		if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
+						config->rti.uec_a);
+		}
+
+		if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
+						config->rti.uec_b);
+		}
+
+		if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
+						config->rti.uec_c);
+		}
+
+		if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
+			val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
+						config->rti.uec_d);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
+		val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+		if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
+			if (config->rti.timer_ri_en)
+				val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+			else
+				val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+		}
+
+		if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+					0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+					config->rti.rtimer_val);
+		}
+
+		if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
+					config->rti.util_sel);
+		}
+
+		if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+			val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+					0x3ffffff);
+			val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+					config->rti.ltimer_val);
+		}
+
+		writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
+	}
+
+	val64 = 0;
+	writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+	writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+	writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+	writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+	writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+	writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_initialize
+ * This routine is the final phase of init which initializes the
+ * registers of the vpath using the configuration passed.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	u64 val64;
+	u32 val32;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	vpath = &hldev->virtual_paths[vp_id];
+
+	if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
+		status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
+		goto exit;
+	}
+	vp_reg = vpath->vp_reg;
+
+	status =  __vxge_hw_vpath_swapper_set(vpath->vp_reg);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status =  __vxge_hw_vpath_mac_configure(hldev, vp_id);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status =  __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
+
+	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 */
+	status  = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
+
+	if (status == VXGE_HW_OK) {
+		val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
+		val64 &=
+		    ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7));
+		val64 |=
+		    VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32);
+
+		val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE;
+	}
+
+	val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7));
+	val64 |=
+	    VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(
+		    VXGE_HW_MAX_PAYLOAD_SIZE_512);
+
+	val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN;
+	writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl);
+
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vp_initialize - Initialize Virtual Path structure
+ * This routine is the initial phase of init which resets the vpath and
+ * initializes the software support structures.
+ */
+enum vxge_hw_status
+__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
+			struct vxge_hw_vp_config *config)
+{
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
+		status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
+		goto exit;
+	}
+
+	vpath = &hldev->virtual_paths[vp_id];
+
+	vpath->vp_id = vp_id;
+	vpath->vp_open = VXGE_HW_VP_OPEN;
+	vpath->hldev = hldev;
+	vpath->vp_config = config;
+	vpath->vp_reg = hldev->vpath_reg[vp_id];
+	vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id];
+
+	__vxge_hw_vpath_reset(hldev, vp_id);
+
+	status = __vxge_hw_vpath_reset_check(vpath);
+
+	if (status != VXGE_HW_OK) {
+		memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_mgmt_read(hldev, vpath);
+
+	if (status != VXGE_HW_OK) {
+		memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+		goto exit;
+	}
+
+	INIT_LIST_HEAD(&vpath->vpath_handles);
+
+	vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id];
+
+	VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0,
+		hldev->tim_int_mask1, vp_id);
+
+	status = __vxge_hw_vpath_initialize(hldev, vp_id);
+
+	if (status != VXGE_HW_OK)
+		__vxge_hw_vp_terminate(hldev, vp_id);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vp_terminate - Terminate Virtual Path structure
+ * This routine closes all channels it opened and freeup memory
+ */
+void
+__vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+	struct __vxge_hw_virtualpath *vpath;
+
+	vpath = &hldev->virtual_paths[vp_id];
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
+		goto exit;
+
+	VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
+		vpath->hldev->tim_int_mask1, vpath->vp_id);
+	hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
+
+	memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+exit:
+	return;
+}
+
+/*
+ * vxge_hw_vpath_mtu_set - Set MTU.
+ * Set new MTU value. Example, to use jumbo frames:
+ * vxge_hw_vpath_mtu_set(my_device, 9600);
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+	vpath = vp->vpath;
+
+	new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+	if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu))
+		status = VXGE_HW_ERR_INVALID_MTU_SIZE;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
+	val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu);
+
+	writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+
+	vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_open - Open a virtual path on a given adapter
+ * This function is used to open access to virtual path of an
+ * adapter for offload, GRO operations. This function returns
+ * synchronously.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_open(struct __vxge_hw_device *hldev,
+		   struct vxge_hw_vpath_attr *attr,
+		   struct __vxge_hw_vpath_handle **vpath_handle)
+{
+	struct __vxge_hw_virtualpath *vpath;
+	struct __vxge_hw_vpath_handle *vp;
+	enum vxge_hw_status status;
+
+	vpath = &hldev->virtual_paths[attr->vp_id];
+
+	if (vpath->vp_open == VXGE_HW_VP_OPEN) {
+		status = VXGE_HW_ERR_INVALID_STATE;
+		goto vpath_open_exit1;
+	}
+
+	status = __vxge_hw_vp_initialize(hldev, attr->vp_id,
+			&hldev->config.vp_config[attr->vp_id]);
+
+	if (status != VXGE_HW_OK)
+		goto vpath_open_exit1;
+
+	vp = (struct __vxge_hw_vpath_handle *)
+		vmalloc(sizeof(struct __vxge_hw_vpath_handle));
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto vpath_open_exit2;
+	}
+
+	memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle));
+
+	vp->vpath = vpath;
+
+	if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+		status = __vxge_hw_fifo_create(vp, &attr->fifo_attr);
+		if (status != VXGE_HW_OK)
+			goto vpath_open_exit6;
+	}
+
+	if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
+		status = __vxge_hw_ring_create(vp, &attr->ring_attr);
+		if (status != VXGE_HW_OK)
+			goto vpath_open_exit7;
+
+		__vxge_hw_vpath_prc_configure(hldev, attr->vp_id);
+	}
+
+	vpath->fifoh->tx_intr_num =
+		(attr->vp_id * VXGE_HW_MAX_INTR_PER_VP)  +
+			VXGE_HW_VPATH_INTR_TX;
+
+	vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev,
+				VXGE_HW_BLOCK_SIZE);
+
+	if (vpath->stats_block == NULL) {
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+		goto vpath_open_exit8;
+	}
+
+	vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath->
+			stats_block->memblock;
+	memset(vpath->hw_stats, 0,
+		sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+	hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] =
+						vpath->hw_stats;
+
+	vpath->hw_stats_sav =
+		&hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id];
+	memset(vpath->hw_stats_sav, 0,
+			sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+	writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg);
+
+	status = vxge_hw_vpath_stats_enable(vp);
+	if (status != VXGE_HW_OK)
+		goto vpath_open_exit8;
+
+	list_add(&vp->item, &vpath->vpath_handles);
+
+	hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id);
+
+	*vpath_handle = vp;
+
+	attr->fifo_attr.userdata = vpath->fifoh;
+	attr->ring_attr.userdata = vpath->ringh;
+
+	return VXGE_HW_OK;
+
+vpath_open_exit8:
+	if (vpath->ringh != NULL)
+		__vxge_hw_ring_delete(vp);
+vpath_open_exit7:
+	if (vpath->fifoh != NULL)
+		__vxge_hw_fifo_delete(vp);
+vpath_open_exit6:
+	vfree(vp);
+vpath_open_exit2:
+	__vxge_hw_vp_terminate(hldev, attr->vp_id);
+vpath_open_exit1:
+
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath
+ * (vpath) open
+ * @vp: Handle got from previous vpath open
+ *
+ * This function is used to close access to virtual path opened
+ * earlier.
+ */
+void
+vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_virtualpath *vpath = NULL;
+	u64 new_count, val64, val164;
+	struct __vxge_hw_ring *ring;
+
+	vpath = vp->vpath;
+	ring = vpath->ringh;
+
+	new_count = readq(&vpath->vp_reg->rxdmem_size);
+	new_count &= 0x1fff;
+	val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count));
+
+	writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164),
+		&vpath->vp_reg->prc_rxd_doorbell);
+	readl(&vpath->vp_reg->prc_rxd_doorbell);
+
+	val164 /= 2;
+	val64 = readq(&vpath->vp_reg->prc_cfg6);
+	val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64);
+	val64 &= 0x1ff;
+
+	/*
+	 * Each RxD is of 4 qwords
+	 */
+	new_count -= (val64 + 1);
+	val64 = min(val164, new_count) / 4;
+
+	ring->rxds_limit = min(ring->rxds_limit, val64);
+	if (ring->rxds_limit < 4)
+		ring->rxds_limit = 4;
+}
+
+/*
+ * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
+ * This function is used to close access to virtual path opened
+ * earlier.
+ */
+enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_virtualpath *vpath = NULL;
+	struct __vxge_hw_device *devh = NULL;
+	u32 vp_id = vp->vpath->vp_id;
+	u32 is_empty = TRUE;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	vpath = vp->vpath;
+	devh = vpath->hldev;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto vpath_close_exit;
+	}
+
+	list_del(&vp->item);
+
+	if (!list_empty(&vpath->vpath_handles)) {
+		list_add(&vp->item, &vpath->vpath_handles);
+		is_empty = FALSE;
+	}
+
+	if (!is_empty) {
+		status = VXGE_HW_FAIL;
+		goto vpath_close_exit;
+	}
+
+	devh->vpaths_deployed &= ~vxge_mBIT(vp_id);
+
+	if (vpath->ringh != NULL)
+		__vxge_hw_ring_delete(vp);
+
+	if (vpath->fifoh != NULL)
+		__vxge_hw_fifo_delete(vp);
+
+	if (vpath->stats_block != NULL)
+		__vxge_hw_blockpool_block_free(devh, vpath->stats_block);
+
+	vfree(vp);
+
+	__vxge_hw_vp_terminate(devh, vp_id);
+
+	vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
+
+vpath_close_exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_reset - Resets vpath
+ * This function is used to request a reset of vpath
+ */
+enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp)
+{
+	enum vxge_hw_status status;
+	u32 vp_id;
+	struct __vxge_hw_virtualpath *vpath = vp->vpath;
+
+	vp_id = vpath->vp_id;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_reset(vpath->hldev, vp_id);
+	if (status == VXGE_HW_OK)
+		vpath->sw_stats->soft_reset_cnt++;
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize.
+ * This function poll's for the vpath reset completion and re initializes
+ * the vpath.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_virtualpath *vpath = NULL;
+	enum vxge_hw_status status;
+	struct __vxge_hw_device *hldev;
+	u32 vp_id;
+
+	vp_id = vp->vpath->vp_id;
+	vpath = vp->vpath;
+	hldev = vpath->hldev;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_reset_check(vpath);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status = __vxge_hw_vpath_sw_reset(hldev, vp_id);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status = __vxge_hw_vpath_initialize(hldev, vp_id);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	if (vpath->ringh != NULL)
+		__vxge_hw_vpath_prc_configure(hldev, vp_id);
+
+	memset(vpath->hw_stats, 0,
+		sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+	memset(vpath->hw_stats_sav, 0,
+		sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+	writeq(vpath->stats_block->dma_addr,
+		&vpath->vp_reg->stats_cfg);
+
+	status = vxge_hw_vpath_stats_enable(vp);
+
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_enable - Enable vpath.
+ * This routine clears the vpath reset thereby enabling a vpath
+ * to start forwarding frames and generating interrupts.
+ */
+void
+vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp)
+{
+	struct __vxge_hw_device *hldev;
+	u64 val64;
+
+	hldev = vp->vpath->hldev;
+
+	val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(
+		1 << (16 - vp->vpath->vp_id));
+
+	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+		&hldev->common_reg->cmn_rsthdlr_cfg1);
+}
+
+/*
+ * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
+ * Enable the DMA vpath statistics. The function is to be called to re-enable
+ * the adapter to update stats into the host memory
+ */
+enum vxge_hw_status
+vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_virtualpath *vpath;
+
+	vpath = vp->vpath;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+
+	memcpy(vpath->hw_stats_sav, vpath->hw_stats,
+			sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+	status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_stats_access - Get the statistics from the given location
+ *                           and offset and perform an operation
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
+			     u32 operation, u32 offset, u64 *stat)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto vpath_stats_access_exit;
+	}
+
+	vp_reg = vpath->vp_reg;
+
+	val64 =  VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
+		 VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
+		 VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
+
+	status = __vxge_hw_pio_mem_write64(val64,
+				&vp_reg->xmac_stats_access_cmd,
+				VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
+				vpath->hldev->config.device_poll_millis);
+
+	if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
+		*stat = readq(&vp_reg->xmac_stats_access_data);
+	else
+		*stat = 0;
+
+vpath_stats_access_exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_tx_stats_get(
+	struct __vxge_hw_virtualpath *vpath,
+	struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
+{
+	u64 *val64;
+	int i;
+	u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	val64 = (u64 *) vpath_tx_stats;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+
+	for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
+		status = __vxge_hw_vpath_stats_access(vpath,
+					VXGE_HW_STATS_OP_READ,
+					offset, val64);
+		if (status != VXGE_HW_OK)
+			goto exit;
+		offset++;
+		val64++;
+	}
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
+			struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
+{
+	u64 *val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	int i;
+	u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
+	val64 = (u64 *) vpath_rx_stats;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+	for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
+		status = __vxge_hw_vpath_stats_access(vpath,
+					VXGE_HW_STATS_OP_READ,
+					offset >> 3, val64);
+		if (status != VXGE_HW_OK)
+			goto exit;
+
+		offset += 8;
+		val64++;
+	}
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
+ */
+enum vxge_hw_status __vxge_hw_vpath_stats_get(
+			struct __vxge_hw_virtualpath *vpath,
+			struct vxge_hw_vpath_stats_hw_info *hw_stats)
+{
+	u64 val64;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+	vp_reg = vpath->vp_reg;
+
+	val64 = readq(&vp_reg->vpath_debug_stats0);
+	hw_stats->ini_num_mwr_sent =
+		(u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats1);
+	hw_stats->ini_num_mrd_sent =
+		(u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats2);
+	hw_stats->ini_num_cpl_rcvd =
+		(u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats3);
+	hw_stats->ini_num_mwr_byte_sent =
+		VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats4);
+	hw_stats->ini_num_cpl_byte_rcvd =
+		VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats5);
+	hw_stats->wrcrdtarb_xoff =
+		(u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
+
+	val64 = readq(&vp_reg->vpath_debug_stats6);
+	hw_stats->rdcrdtarb_xoff =
+		(u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count01);
+	hw_stats->vpath_genstats_count0 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
+		val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count01);
+	hw_stats->vpath_genstats_count1 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
+		val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count23);
+	hw_stats->vpath_genstats_count2 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
+		val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count01);
+	hw_stats->vpath_genstats_count3 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
+		val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count4);
+	hw_stats->vpath_genstats_count4 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
+		val64);
+
+	val64 = readq(&vp_reg->vpath_genstats_count5);
+	hw_stats->vpath_genstats_count5 =
+	(u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
+		val64);
+
+	status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	VXGE_HW_VPATH_STATS_PIO_READ(
+		VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
+
+	hw_stats->prog_event_vnum0 =
+			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
+
+	hw_stats->prog_event_vnum1 =
+			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
+
+	VXGE_HW_VPATH_STATS_PIO_READ(
+		VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
+
+	hw_stats->prog_event_vnum2 =
+			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
+
+	hw_stats->prog_event_vnum3 =
+			(u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
+
+	val64 = readq(&vp_reg->rx_multi_cast_stats);
+	hw_stats->rx_multi_cast_frame_discard =
+		(u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
+
+	val64 = readq(&vp_reg->rx_frm_transferred);
+	hw_stats->rx_frm_transferred =
+		(u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
+
+	val64 = readq(&vp_reg->rxd_returned);
+	hw_stats->rxd_returned =
+		(u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
+
+	val64 = readq(&vp_reg->dbg_stats_rx_mpa);
+	hw_stats->rx_mpa_len_fail_frms =
+		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
+	hw_stats->rx_mpa_mrk_fail_frms =
+		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
+	hw_stats->rx_mpa_crc_fail_frms =
+		(u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
+
+	val64 = readq(&vp_reg->dbg_stats_rx_fau);
+	hw_stats->rx_permitted_frms =
+		(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
+	hw_stats->rx_vp_reset_discarded_frms =
+	(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
+	hw_stats->rx_wol_frms =
+		(u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
+
+	val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
+	hw_stats->tx_vp_reset_discarded_frms =
+	(u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
+		val64);
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_blockpool_create - Create block pool
+ */
+
+enum vxge_hw_status
+__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
+			   struct __vxge_hw_blockpool *blockpool,
+			   u32 pool_size,
+			   u32 pool_max)
+{
+	u32 i;
+	struct __vxge_hw_blockpool_entry *entry = NULL;
+	void *memblock;
+	dma_addr_t dma_addr;
+	struct pci_dev *dma_handle;
+	struct pci_dev *acc_handle;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (blockpool == NULL) {
+		status = VXGE_HW_FAIL;
+		goto blockpool_create_exit;
+	}
+
+	blockpool->hldev = hldev;
+	blockpool->block_size = VXGE_HW_BLOCK_SIZE;
+	blockpool->pool_size = 0;
+	blockpool->pool_max = pool_max;
+	blockpool->req_out = 0;
+
+	INIT_LIST_HEAD(&blockpool->free_block_list);
+	INIT_LIST_HEAD(&blockpool->free_entry_list);
+
+	for (i = 0; i < pool_size + pool_max; i++) {
+		entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+				GFP_KERNEL);
+		if (entry == NULL) {
+			__vxge_hw_blockpool_destroy(blockpool);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto blockpool_create_exit;
+		}
+		list_add(&entry->item, &blockpool->free_entry_list);
+	}
+
+	for (i = 0; i < pool_size; i++) {
+
+		memblock = vxge_os_dma_malloc(
+				hldev->pdev,
+				VXGE_HW_BLOCK_SIZE,
+				&dma_handle,
+				&acc_handle);
+
+		if (memblock == NULL) {
+			__vxge_hw_blockpool_destroy(blockpool);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto blockpool_create_exit;
+		}
+
+		dma_addr = pci_map_single(hldev->pdev, memblock,
+				VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
+
+		if (unlikely(pci_dma_mapping_error(hldev->pdev,
+				dma_addr))) {
+
+			vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
+			__vxge_hw_blockpool_destroy(blockpool);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto blockpool_create_exit;
+		}
+
+		if (!list_empty(&blockpool->free_entry_list))
+			entry = (struct __vxge_hw_blockpool_entry *)
+				list_first_entry(&blockpool->free_entry_list,
+					struct __vxge_hw_blockpool_entry,
+					item);
+
+		if (entry == NULL)
+			entry =
+			    kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+					GFP_KERNEL);
+		if (entry != NULL) {
+			list_del(&entry->item);
+			entry->length = VXGE_HW_BLOCK_SIZE;
+			entry->memblock = memblock;
+			entry->dma_addr = dma_addr;
+			entry->acc_handle = acc_handle;
+			entry->dma_handle = dma_handle;
+			list_add(&entry->item,
+					  &blockpool->free_block_list);
+			blockpool->pool_size++;
+		} else {
+			__vxge_hw_blockpool_destroy(blockpool);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto blockpool_create_exit;
+		}
+	}
+
+blockpool_create_exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_blockpool_destroy - Deallocates the block pool
+ */
+
+void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
+{
+
+	struct __vxge_hw_device *hldev;
+	struct list_head *p, *n;
+	u16 ret;
+
+	if (blockpool == NULL) {
+		ret = 1;
+		goto exit;
+	}
+
+	hldev = blockpool->hldev;
+
+	list_for_each_safe(p, n, &blockpool->free_block_list) {
+
+		pci_unmap_single(hldev->pdev,
+			((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+			((struct __vxge_hw_blockpool_entry *)p)->length,
+			PCI_DMA_BIDIRECTIONAL);
+
+		vxge_os_dma_free(hldev->pdev,
+			((struct __vxge_hw_blockpool_entry *)p)->memblock,
+			&((struct __vxge_hw_blockpool_entry *) p)->acc_handle);
+
+		list_del(
+			&((struct __vxge_hw_blockpool_entry *)p)->item);
+		kfree(p);
+		blockpool->pool_size--;
+	}
+
+	list_for_each_safe(p, n, &blockpool->free_entry_list) {
+		list_del(
+			&((struct __vxge_hw_blockpool_entry *)p)->item);
+		kfree((void *)p);
+	}
+	ret = 0;
+exit:
+	return;
+}
+
+/*
+ * __vxge_hw_blockpool_blocks_add - Request additional blocks
+ */
+static
+void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
+{
+	u32 nreq = 0, i;
+
+	if ((blockpool->pool_size  +  blockpool->req_out) <
+		VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
+		nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
+		blockpool->req_out += nreq;
+	}
+
+	for (i = 0; i < nreq; i++)
+		vxge_os_dma_malloc_async(
+			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+			blockpool->hldev, VXGE_HW_BLOCK_SIZE);
+}
+
+/*
+ * __vxge_hw_blockpool_blocks_remove - Free additional blocks
+ */
+static
+void __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &blockpool->free_block_list) {
+
+		if (blockpool->pool_size < blockpool->pool_max)
+			break;
+
+		pci_unmap_single(
+			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+			((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+			((struct __vxge_hw_blockpool_entry *)p)->length,
+			PCI_DMA_BIDIRECTIONAL);
+
+		vxge_os_dma_free(
+			((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+			((struct __vxge_hw_blockpool_entry *)p)->memblock,
+			&((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
+
+		list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
+
+		list_add(p, &blockpool->free_entry_list);
+
+		blockpool->pool_size--;
+
+	}
+}
+
+/*
+ * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
+ * Adds a block to block pool
+ */
+void vxge_hw_blockpool_block_add(
+			struct __vxge_hw_device *devh,
+			void *block_addr,
+			u32 length,
+			struct pci_dev *dma_h,
+			struct pci_dev *acc_handle)
+{
+	struct __vxge_hw_blockpool  *blockpool;
+	struct __vxge_hw_blockpool_entry  *entry = NULL;
+	dma_addr_t dma_addr;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	u32 req_out;
+
+	blockpool = &devh->block_pool;
+
+	if (block_addr == NULL) {
+		blockpool->req_out--;
+		status = VXGE_HW_FAIL;
+		goto exit;
+	}
+
+	dma_addr = pci_map_single(devh->pdev, block_addr, length,
+				PCI_DMA_BIDIRECTIONAL);
+
+	if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
+
+		vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
+		blockpool->req_out--;
+		status = VXGE_HW_FAIL;
+		goto exit;
+	}
+
+
+	if (!list_empty(&blockpool->free_entry_list))
+		entry = (struct __vxge_hw_blockpool_entry *)
+			list_first_entry(&blockpool->free_entry_list,
+				struct __vxge_hw_blockpool_entry,
+				item);
+
+	if (entry == NULL)
+		entry = (struct __vxge_hw_blockpool_entry *)
+			vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
+	else
+		list_del(&entry->item);
+
+	if (entry != NULL) {
+		entry->length = length;
+		entry->memblock = block_addr;
+		entry->dma_addr = dma_addr;
+		entry->acc_handle = acc_handle;
+		entry->dma_handle = dma_h;
+		list_add(&entry->item, &blockpool->free_block_list);
+		blockpool->pool_size++;
+		status = VXGE_HW_OK;
+	} else
+		status = VXGE_HW_ERR_OUT_OF_MEMORY;
+
+	blockpool->req_out--;
+
+	req_out = blockpool->req_out;
+exit:
+	return;
+}
+
+/*
+ * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
+ * Allocates a block of memory of given size, either from block pool
+ * or by calling vxge_os_dma_malloc()
+ */
+void *
+__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
+				struct vxge_hw_mempool_dma *dma_object)
+{
+	struct __vxge_hw_blockpool_entry *entry = NULL;
+	struct __vxge_hw_blockpool  *blockpool;
+	void *memblock = NULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	blockpool = &devh->block_pool;
+
+	if (size != blockpool->block_size) {
+
+		memblock = vxge_os_dma_malloc(devh->pdev, size,
+						&dma_object->handle,
+						&dma_object->acc_handle);
+
+		if (memblock == NULL) {
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto exit;
+		}
+
+		dma_object->addr = pci_map_single(devh->pdev, memblock, size,
+					PCI_DMA_BIDIRECTIONAL);
+
+		if (unlikely(pci_dma_mapping_error(devh->pdev,
+				dma_object->addr))) {
+			vxge_os_dma_free(devh->pdev, memblock,
+				&dma_object->acc_handle);
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+			goto exit;
+		}
+
+	} else {
+
+		if (!list_empty(&blockpool->free_block_list))
+			entry = (struct __vxge_hw_blockpool_entry *)
+				list_first_entry(&blockpool->free_block_list,
+					struct __vxge_hw_blockpool_entry,
+					item);
+
+		if (entry != NULL) {
+			list_del(&entry->item);
+			dma_object->addr = entry->dma_addr;
+			dma_object->handle = entry->dma_handle;
+			dma_object->acc_handle = entry->acc_handle;
+			memblock = entry->memblock;
+
+			list_add(&entry->item,
+				&blockpool->free_entry_list);
+			blockpool->pool_size--;
+		}
+
+		if (memblock != NULL)
+			__vxge_hw_blockpool_blocks_add(blockpool);
+	}
+exit:
+	return memblock;
+}
+
+/*
+ * __vxge_hw_blockpool_free - Frees the memory allcoated with
+				__vxge_hw_blockpool_malloc
+ */
+void
+__vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
+			void *memblock, u32 size,
+			struct vxge_hw_mempool_dma *dma_object)
+{
+	struct __vxge_hw_blockpool_entry *entry = NULL;
+	struct __vxge_hw_blockpool  *blockpool;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	blockpool = &devh->block_pool;
+
+	if (size != blockpool->block_size) {
+		pci_unmap_single(devh->pdev, dma_object->addr, size,
+			PCI_DMA_BIDIRECTIONAL);
+		vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
+	} else {
+
+		if (!list_empty(&blockpool->free_entry_list))
+			entry = (struct __vxge_hw_blockpool_entry *)
+				list_first_entry(&blockpool->free_entry_list,
+					struct __vxge_hw_blockpool_entry,
+					item);
+
+		if (entry == NULL)
+			entry = (struct __vxge_hw_blockpool_entry *)
+				vmalloc(sizeof(
+					struct __vxge_hw_blockpool_entry));
+		else
+			list_del(&entry->item);
+
+		if (entry != NULL) {
+			entry->length = size;
+			entry->memblock = memblock;
+			entry->dma_addr = dma_object->addr;
+			entry->acc_handle = dma_object->acc_handle;
+			entry->dma_handle = dma_object->handle;
+			list_add(&entry->item,
+					&blockpool->free_block_list);
+			blockpool->pool_size++;
+			status = VXGE_HW_OK;
+		} else
+			status = VXGE_HW_ERR_OUT_OF_MEMORY;
+
+		if (status == VXGE_HW_OK)
+			__vxge_hw_blockpool_blocks_remove(blockpool);
+	}
+
+	return;
+}
+
+/*
+ * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
+ * This function allocates a block from block pool or from the system
+ */
+struct __vxge_hw_blockpool_entry *
+__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
+{
+	struct __vxge_hw_blockpool_entry *entry = NULL;
+	struct __vxge_hw_blockpool  *blockpool;
+
+	blockpool = &devh->block_pool;
+
+	if (size == blockpool->block_size) {
+
+		if (!list_empty(&blockpool->free_block_list))
+			entry = (struct __vxge_hw_blockpool_entry *)
+				list_first_entry(&blockpool->free_block_list,
+					struct __vxge_hw_blockpool_entry,
+					item);
+
+		if (entry != NULL) {
+			list_del(&entry->item);
+			blockpool->pool_size--;
+		}
+	}
+
+	if (entry != NULL)
+		__vxge_hw_blockpool_blocks_add(blockpool);
+
+	return entry;
+}
+
+/*
+ * __vxge_hw_blockpool_block_free - Frees a block from block pool
+ * @devh: Hal device
+ * @entry: Entry of block to be freed
+ *
+ * This function frees a block from block pool
+ */
+void
+__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
+			struct __vxge_hw_blockpool_entry *entry)
+{
+	struct __vxge_hw_blockpool  *blockpool;
+
+	blockpool = &devh->block_pool;
+
+	if (entry->length == blockpool->block_size) {
+		list_add(&entry->item, &blockpool->free_block_list);
+		blockpool->pool_size++;
+	}
+
+	__vxge_hw_blockpool_blocks_remove(blockpool);
+
+	return;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-config.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-config.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-config.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-config.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2259 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-config.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_CONFIG_H
+#define VXGE_CONFIG_H
+#include <linux/list.h>
+
+#ifndef VXGE_CACHE_LINE_SIZE
+#define VXGE_CACHE_LINE_SIZE 128
+#endif
+
+#define vxge_os_vaprintf(level, mask, fmt, ...) { \
+	char buff[255]; \
+		snprintf(buff, 255, fmt, __VA_ARGS__); \
+		printk(buff); \
+		printk("\n"); \
+}
+
+#ifndef VXGE_ALIGN
+#define VXGE_ALIGN(adrs, size) \
+	(((size) - (((u64)adrs) & ((size)-1))) & ((size)-1))
+#endif
+
+#define VXGE_HW_MIN_MTU				68
+#define VXGE_HW_MAX_MTU				9600
+#define VXGE_HW_DEFAULT_MTU			1500
+
+#ifdef VXGE_DEBUG_ASSERT
+
+/**
+ * vxge_assert
+ * @test: C-condition to check
+ * @fmt: printf like format string
+ *
+ * This function implements traditional assert. By default assertions
+ * are enabled. It can be disabled by undefining VXGE_DEBUG_ASSERT macro in
+ * compilation
+ * time.
+ */
+#define vxge_assert(test) { \
+	if (!(test)) \
+		vxge_os_bug("bad cond: "#test" at %s:%d\n", \
+				__FILE__, __LINE__); }
+#else
+#define vxge_assert(test)
+#endif /* end of VXGE_DEBUG_ASSERT */
+
+/**
+ * enum enum vxge_debug_level
+ * @VXGE_NONE: debug disabled
+ * @VXGE_ERR: all errors going to be logged out
+ * @VXGE_TRACE: all errors plus all kind of verbose tracing print outs
+ *                 going to be logged out. Very noisy.
+ *
+ * This enumeration going to be used to switch between different
+ * debug levels during runtime if DEBUG macro defined during
+ * compilation. If DEBUG macro not defined than code will be
+ * compiled out.
+ */
+enum vxge_debug_level {
+	VXGE_NONE   = 0,
+	VXGE_TRACE  = 1,
+	VXGE_ERR    = 2
+};
+
+#define NULL_VPID					0xFFFFFFFF
+#ifdef CONFIG_VXGE_DEBUG_TRACE_ALL
+#define VXGE_DEBUG_MODULE_MASK  0xffffffff
+#define VXGE_DEBUG_TRACE_MASK   0xffffffff
+#define VXGE_DEBUG_ERR_MASK     0xffffffff
+#define VXGE_DEBUG_MASK         0x000001ff
+#else
+#define VXGE_DEBUG_MODULE_MASK  0x20000000
+#define VXGE_DEBUG_TRACE_MASK   0x20000000
+#define VXGE_DEBUG_ERR_MASK     0x20000000
+#define VXGE_DEBUG_MASK         0x00000001
+#endif
+
+/*
+ * @VXGE_COMPONENT_LL: do debug for vxge link layer module
+ * @VXGE_COMPONENT_ALL: activate debug for all modules with no exceptions
+ *
+ * This enumeration going to be used to distinguish modules
+ * or libraries during compilation and runtime.  Makefile must declare
+ * VXGE_DEBUG_MODULE_MASK macro and set it to proper value.
+ */
+#define	VXGE_COMPONENT_LL				0x20000000
+#define	VXGE_COMPONENT_ALL				0xffffffff
+
+#define VXGE_HW_BASE_INF	100
+#define VXGE_HW_BASE_ERR	200
+#define VXGE_HW_BASE_BADCFG	300
+
+enum vxge_hw_status {
+	VXGE_HW_OK				  = 0,
+	VXGE_HW_FAIL				  = 1,
+	VXGE_HW_PENDING				  = 2,
+	VXGE_HW_COMPLETIONS_REMAIN		  = 3,
+
+	VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS = VXGE_HW_BASE_INF + 1,
+	VXGE_HW_INF_OUT_OF_DESCRIPTORS		  = VXGE_HW_BASE_INF + 2,
+
+	VXGE_HW_ERR_INVALID_HANDLE		  = VXGE_HW_BASE_ERR + 1,
+	VXGE_HW_ERR_OUT_OF_MEMORY		  = VXGE_HW_BASE_ERR + 2,
+	VXGE_HW_ERR_VPATH_NOT_AVAILABLE	  	  = VXGE_HW_BASE_ERR + 3,
+	VXGE_HW_ERR_VPATH_NOT_OPEN		  = VXGE_HW_BASE_ERR + 4,
+	VXGE_HW_ERR_WRONG_IRQ			  = VXGE_HW_BASE_ERR + 5,
+	VXGE_HW_ERR_SWAPPER_CTRL		  = VXGE_HW_BASE_ERR + 6,
+	VXGE_HW_ERR_INVALID_MTU_SIZE		  = VXGE_HW_BASE_ERR + 7,
+	VXGE_HW_ERR_INVALID_INDEX		  = VXGE_HW_BASE_ERR + 8,
+	VXGE_HW_ERR_INVALID_TYPE		  = VXGE_HW_BASE_ERR + 9,
+	VXGE_HW_ERR_INVALID_OFFSET		  = VXGE_HW_BASE_ERR + 10,
+	VXGE_HW_ERR_INVALID_DEVICE		  = VXGE_HW_BASE_ERR + 11,
+	VXGE_HW_ERR_VERSION_CONFLICT		  = VXGE_HW_BASE_ERR + 12,
+	VXGE_HW_ERR_INVALID_PCI_INFO		  = VXGE_HW_BASE_ERR + 13,
+	VXGE_HW_ERR_INVALID_TCODE 		  = VXGE_HW_BASE_ERR + 14,
+	VXGE_HW_ERR_INVALID_BLOCK_SIZE		  = VXGE_HW_BASE_ERR + 15,
+	VXGE_HW_ERR_INVALID_STATE		  = VXGE_HW_BASE_ERR + 16,
+	VXGE_HW_ERR_PRIVILAGED_OPEARATION	  = VXGE_HW_BASE_ERR + 17,
+	VXGE_HW_ERR_INVALID_PORT 		  = VXGE_HW_BASE_ERR + 18,
+	VXGE_HW_ERR_FIFO		 	  = VXGE_HW_BASE_ERR + 19,
+	VXGE_HW_ERR_VPATH			  = VXGE_HW_BASE_ERR + 20,
+	VXGE_HW_ERR_CRITICAL			  = VXGE_HW_BASE_ERR + 21,
+	VXGE_HW_ERR_SLOT_FREEZE 		  = VXGE_HW_BASE_ERR + 22,
+
+	VXGE_HW_BADCFG_RING_INDICATE_MAX_PKTS	  = VXGE_HW_BASE_BADCFG + 1,
+	VXGE_HW_BADCFG_FIFO_BLOCKS		  = VXGE_HW_BASE_BADCFG + 2,
+	VXGE_HW_BADCFG_VPATH_MTU		  = VXGE_HW_BASE_BADCFG + 3,
+	VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG	  = VXGE_HW_BASE_BADCFG + 4,
+	VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH	  = VXGE_HW_BASE_BADCFG + 5,
+	VXGE_HW_BADCFG_INTR_MODE		  = VXGE_HW_BASE_BADCFG + 6,
+	VXGE_HW_BADCFG_RTS_MAC_EN		  = VXGE_HW_BASE_BADCFG + 7,
+
+	VXGE_HW_EOF_TRACE_BUF			  = -1
+};
+
+/**
+ * enum enum vxge_hw_device_link_state - Link state enumeration.
+ * @VXGE_HW_LINK_NONE: Invalid link state.
+ * @VXGE_HW_LINK_DOWN: Link is down.
+ * @VXGE_HW_LINK_UP: Link is up.
+ *
+ */
+enum vxge_hw_device_link_state {
+	VXGE_HW_LINK_NONE,
+	VXGE_HW_LINK_DOWN,
+	VXGE_HW_LINK_UP
+};
+
+/**
+ * struct vxge_hw_device_date - Date Format
+ * @day: Day
+ * @month: Month
+ * @year: Year
+ * @date: Date in string format
+ *
+ * Structure for returning date
+ */
+
+#define VXGE_HW_FW_STRLEN	32
+struct vxge_hw_device_date {
+	u32     day;
+	u32     month;
+	u32     year;
+	char    date[VXGE_HW_FW_STRLEN];
+};
+
+struct vxge_hw_device_version {
+	u32     major;
+	u32     minor;
+	u32     build;
+	char    version[VXGE_HW_FW_STRLEN];
+};
+
+u64
+__vxge_hw_vpath_pci_func_mode_get(
+	u32 vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+/**
+ * struct vxge_hw_fifo_config - Configuration of fifo.
+ * @enable: Is this fifo to be commissioned
+ * @fifo_blocks: Numbers of TxDL (that is, lists of Tx descriptors)
+ * 		blocks per queue.
+ * @max_frags: Max number of Tx buffers per TxDL (that is, per single
+ *             transmit operation).
+ *             No more than 256 transmit buffers can be specified.
+ * @memblock_size: Fifo descriptors are allocated in blocks of @mem_block_size
+ *             bytes. Setting @memblock_size to page size ensures
+ *             by-page allocation of descriptors. 128K bytes is the
+ *             maximum supported block size.
+ * @alignment_size: per Tx fragment DMA-able memory used to align transmit data
+ *             (e.g., to align on a cache line).
+ * @intr: Boolean. Use 1 to generate interrupt for each completed TxDL.
+ *             Use 0 otherwise.
+ * @no_snoop_bits: If non-zero, specifies no-snoop PCI operation,
+ *             which generally improves latency of the host bridge operation
+ *             (see PCI specification). For valid values please refer
+ *             to struct vxge_hw_fifo_config{} in the driver sources.
+ * Configuration of all Titan fifos.
+ * Note: Valid (min, max) range for each attribute is specified in the body of
+ * the struct vxge_hw_fifo_config{} structure.
+ */
+struct vxge_hw_fifo_config {
+	u32				enable;
+#define VXGE_HW_FIFO_ENABLE				1
+#define VXGE_HW_FIFO_DISABLE				0
+
+	u32				fifo_blocks;
+#define VXGE_HW_MIN_FIFO_BLOCKS				2
+#define VXGE_HW_MAX_FIFO_BLOCKS				128
+
+	u32				max_frags;
+#define VXGE_HW_MIN_FIFO_FRAGS				1
+#define VXGE_HW_MAX_FIFO_FRAGS				256
+
+	u32				memblock_size;
+#define VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE			VXGE_HW_BLOCK_SIZE
+#define VXGE_HW_MAX_FIFO_MEMBLOCK_SIZE			131072
+#define VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE			8096
+
+	u32		                alignment_size;
+#define VXGE_HW_MIN_FIFO_ALIGNMENT_SIZE		0
+#define VXGE_HW_MAX_FIFO_ALIGNMENT_SIZE		65536
+#define VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE		VXGE_CACHE_LINE_SIZE
+
+	u32		                intr;
+#define VXGE_HW_FIFO_QUEUE_INTR_ENABLE			1
+#define VXGE_HW_FIFO_QUEUE_INTR_DISABLE			0
+#define VXGE_HW_FIFO_QUEUE_INTR_DEFAULT			0
+
+	u32				no_snoop_bits;
+#define VXGE_HW_FIFO_NO_SNOOP_DISABLED			0
+#define VXGE_HW_FIFO_NO_SNOOP_TXD			1
+#define VXGE_HW_FIFO_NO_SNOOP_FRM			2
+#define VXGE_HW_FIFO_NO_SNOOP_ALL			3
+#define VXGE_HW_FIFO_NO_SNOOP_DEFAULT			0
+
+};
+/**
+ * struct vxge_hw_ring_config - Ring configurations.
+ * @enable: Is this ring to be commissioned
+ * @ring_blocks: Numbers of RxD blocks in the ring
+ * @buffer_mode: Receive buffer mode (1, 2, 3, or 5); for details please refer
+ *             to Titan User Guide.
+ * @scatter_mode: Titan supports two receive scatter modes: A and B.
+ *             For details please refer to Titan User Guide.
+ * @rx_timer_val: The number of 32ns periods that would be counted between two
+ *             timer interrupts.
+ * @greedy_return: If Set it forces the device to return absolutely all RxD
+ *             that are consumed and still on board when a timer interrupt
+ *             triggers. If Clear, then if the device has already returned
+ *             RxD before current timer interrupt trigerred and after the
+ *             previous timer interrupt triggered, then the device is not
+ *             forced to returned the rest of the consumed RxD that it has
+ *             on board which account for a byte count less than the one
+ *             programmed into PRC_CFG6.RXD_CRXDT field
+ * @rx_timer_ci: TBD
+ * @backoff_interval_us: Time (in microseconds), after which Titan
+ *             tries to download RxDs posted by the host.
+ *             Note that the "backoff" does not happen if host posts receive
+ *             descriptors in the timely fashion.
+ * Ring configuration.
+ */
+struct vxge_hw_ring_config {
+	u32				enable;
+#define VXGE_HW_RING_ENABLE					1
+#define VXGE_HW_RING_DISABLE					0
+#define VXGE_HW_RING_DEFAULT					1
+
+	u32				ring_blocks;
+#define VXGE_HW_MIN_RING_BLOCKS				1
+#define VXGE_HW_MAX_RING_BLOCKS				128
+#define VXGE_HW_DEF_RING_BLOCKS				2
+
+	u32				buffer_mode;
+#define VXGE_HW_RING_RXD_BUFFER_MODE_1				1
+#define VXGE_HW_RING_RXD_BUFFER_MODE_3				3
+#define VXGE_HW_RING_RXD_BUFFER_MODE_5				5
+#define VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT			1
+
+	u32				scatter_mode;
+#define VXGE_HW_RING_SCATTER_MODE_A				0
+#define VXGE_HW_RING_SCATTER_MODE_B				1
+#define VXGE_HW_RING_SCATTER_MODE_C				2
+#define VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT		0xffffffff
+
+	u64				rxds_limit;
+#define VXGE_HW_DEF_RING_RXDS_LIMIT				44
+};
+
+/**
+ * struct vxge_hw_vp_config - Configuration of virtual path
+ * @vp_id: Virtual Path Id
+ * @min_bandwidth: Minimum Guaranteed bandwidth
+ * @ring: See struct vxge_hw_ring_config{}.
+ * @fifo: See struct vxge_hw_fifo_config{}.
+ * @tti: Configuration of interrupt associated with Transmit.
+ *             see struct vxge_hw_tim_intr_config();
+ * @rti: Configuration of interrupt associated with Receive.
+ *              see struct vxge_hw_tim_intr_config();
+ * @mtu: mtu size used on this port.
+ * @rpa_strip_vlan_tag: Strip VLAN Tag enable/disable. Instructs the device to
+ *             remove the VLAN tag from all received tagged frames that are not
+ *             replicated at the internal L2 switch.
+ *             0 - Do not strip the VLAN tag.
+ *             1 - Strip the VLAN tag. Regardless of this setting, VLAN tags are
+ *                 always placed into the RxDMA descriptor.
+ *
+ * This structure is used by the driver to pass the configuration parameters to
+ * configure Virtual Path.
+ */
+struct vxge_hw_vp_config {
+	u32				vp_id;
+
+#define	VXGE_HW_VPATH_PRIORITY_MIN			0
+#define	VXGE_HW_VPATH_PRIORITY_MAX			16
+#define	VXGE_HW_VPATH_PRIORITY_DEFAULT			0
+
+	u32				min_bandwidth;
+#define	VXGE_HW_VPATH_BANDWIDTH_MIN			0
+#define	VXGE_HW_VPATH_BANDWIDTH_MAX			100
+#define	VXGE_HW_VPATH_BANDWIDTH_DEFAULT			0
+
+	struct vxge_hw_ring_config		ring;
+	struct vxge_hw_fifo_config		fifo;
+	struct vxge_hw_tim_intr_config	tti;
+	struct vxge_hw_tim_intr_config	rti;
+
+	u32				mtu;
+#define VXGE_HW_VPATH_MIN_INITIAL_MTU			VXGE_HW_MIN_MTU
+#define VXGE_HW_VPATH_MAX_INITIAL_MTU			VXGE_HW_MAX_MTU
+#define VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU	0xffffffff
+
+	u32				rpa_strip_vlan_tag;
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE			1
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE		0
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT	0xffffffff
+
+};
+/**
+ * struct vxge_hw_device_config - Device configuration.
+ * @dma_blockpool_initial: Initial size of DMA Pool
+ * @dma_blockpool_max: Maximum blocks in DMA pool
+ * @intr_mode: Line, or MSI-X interrupt.
+ *
+ * @rth_en: Enable Receive Traffic Hashing(RTH) using IT(Indirection Table).
+ * @rth_it_type: RTH IT table programming type
+ * @rts_mac_en: Enable Receive Traffic Steering using MAC destination address
+ * @vp_config: Configuration for virtual paths
+ * @device_poll_millis: Specify the interval (in mulliseconds)
+ * 			to wait for register reads
+ *
+ * Titan configuration.
+ * Contains per-device configuration parameters, including:
+ * - stats sampling interval, etc.
+ *
+ * In addition, struct vxge_hw_device_config{} includes "subordinate"
+ * configurations, including:
+ * - fifos and rings;
+ * - MAC (done at firmware level).
+ *
+ * See Titan User Guide for more details.
+ * Note: Valid (min, max) range for each attribute is specified in the body of
+ * the struct vxge_hw_device_config{} structure. Please refer to the
+ * corresponding include file.
+ * See also: struct vxge_hw_tim_intr_config{}.
+ */
+struct vxge_hw_device_config {
+	u32				dma_blockpool_initial;
+	u32				dma_blockpool_max;
+#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE			0
+#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE		0
+#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE		4
+#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE			4096
+
+#define        VXGE_HW_MAX_PAYLOAD_SIZE_512		2
+
+	u32				intr_mode;
+#define VXGE_HW_INTR_MODE_IRQLINE			0
+#define VXGE_HW_INTR_MODE_MSIX				1
+#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT			2
+
+#define VXGE_HW_INTR_MODE_DEF				0
+
+	u32				rth_en;
+#define VXGE_HW_RTH_DISABLE				0
+#define VXGE_HW_RTH_ENABLE				1
+#define VXGE_HW_RTH_DEFAULT				0
+
+	u32				rth_it_type;
+#define VXGE_HW_RTH_IT_TYPE_SOLO_IT			0
+#define VXGE_HW_RTH_IT_TYPE_MULTI_IT			1
+#define VXGE_HW_RTH_IT_TYPE_DEFAULT			0
+
+	u32				rts_mac_en;
+#define VXGE_HW_RTS_MAC_DISABLE			0
+#define VXGE_HW_RTS_MAC_ENABLE			1
+#define VXGE_HW_RTS_MAC_DEFAULT			0
+
+	struct vxge_hw_vp_config	vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
+
+	u32				device_poll_millis;
+#define VXGE_HW_MIN_DEVICE_POLL_MILLIS			1
+#define VXGE_HW_MAX_DEVICE_POLL_MILLIS			100000
+#define VXGE_HW_DEF_DEVICE_POLL_MILLIS			1000
+
+};
+
+/**
+ * function vxge_uld_link_up_f - Link-Up callback provided by driver.
+ * @devh: HW device handle.
+ * Link-up notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_down_f{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * function vxge_uld_link_down_f - Link-Down callback provided by
+ * driver.
+ * @devh: HW device handle.
+ *
+ * Link-Down notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_up_f{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * function vxge_uld_crit_err_f - Critical Error notification callback.
+ * @devh: HW device handle.
+ * (typically - at HW device iinitialization time).
+ * @type: Enumerated hw error, e.g.: double ECC.
+ * @serr_data: Titan status.
+ * @ext_data: Extended data. The contents depends on the @type.
+ *
+ * Link-Down notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, enum vxge_hw_event{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * struct vxge_hw_uld_cbs - driver "slow-path" callbacks.
+ * @link_up: See vxge_uld_link_up_f{}.
+ * @link_down: See vxge_uld_link_down_f{}.
+ * @crit_err: See vxge_uld_crit_err_f{}.
+ *
+ * Driver slow-path (per-driver) callbacks.
+ * Implemented by driver and provided to HW via
+ * vxge_hw_driver_initialize().
+ * Note that these callbacks are not mandatory: HW will not invoke
+ * a callback if NULL is specified.
+ *
+ * See also: vxge_hw_driver_initialize().
+ */
+struct vxge_hw_uld_cbs {
+
+	void (*link_up)(struct __vxge_hw_device *devh);
+	void (*link_down)(struct __vxge_hw_device *devh);
+	void (*crit_err)(struct __vxge_hw_device *devh,
+			enum vxge_hw_event type, u64 ext_data);
+};
+
+/*
+ * struct __vxge_hw_blockpool_entry - Block private data structure
+ * @item: List header used to link.
+ * @length: Length of the block
+ * @memblock: Virtual address block
+ * @dma_addr: DMA Address of the block.
+ * @dma_handle: DMA handle of the block.
+ * @acc_handle: DMA acc handle
+ *
+ * Block is allocated with a header to put the blocks into list.
+ *
+ */
+struct __vxge_hw_blockpool_entry {
+	struct list_head	item;
+	u32			length;
+	void			*memblock;
+	dma_addr_t		dma_addr;
+	struct pci_dev 		*dma_handle;
+	struct pci_dev 		*acc_handle;
+};
+
+/*
+ * struct __vxge_hw_blockpool - Block Pool
+ * @hldev: HW device
+ * @block_size: size of each block.
+ * @Pool_size: Number of blocks in the pool
+ * @pool_max: Maximum number of blocks above which to free additional blocks
+ * @req_out: Number of block requests with OS out standing
+ * @free_block_list: List of free blocks
+ *
+ * Block pool contains the DMA blocks preallocated.
+ *
+ */
+struct __vxge_hw_blockpool {
+	struct __vxge_hw_device *hldev;
+	u32				block_size;
+	u32				pool_size;
+	u32				pool_max;
+	u32				req_out;
+	struct list_head		free_block_list;
+	struct list_head		free_entry_list;
+};
+
+/*
+ * enum enum __vxge_hw_channel_type - Enumerated channel types.
+ * @VXGE_HW_CHANNEL_TYPE_UNKNOWN: Unknown channel.
+ * @VXGE_HW_CHANNEL_TYPE_FIFO: fifo.
+ * @VXGE_HW_CHANNEL_TYPE_RING: ring.
+ * @VXGE_HW_CHANNEL_TYPE_MAX: Maximum number of HW-supported
+ * (and recognized) channel types. Currently: 2.
+ *
+ * Enumerated channel types. Currently there are only two link-layer
+ * channels - Titan fifo and Titan ring. In the future the list will grow.
+ */
+enum __vxge_hw_channel_type {
+	VXGE_HW_CHANNEL_TYPE_UNKNOWN			= 0,
+	VXGE_HW_CHANNEL_TYPE_FIFO			= 1,
+	VXGE_HW_CHANNEL_TYPE_RING			= 2,
+	VXGE_HW_CHANNEL_TYPE_MAX			= 3
+};
+
+/*
+ * struct __vxge_hw_channel
+ * @item: List item; used to maintain a list of open channels.
+ * @type: Channel type. See enum vxge_hw_channel_type{}.
+ * @devh: Device handle. HW device object that contains _this_ channel.
+ * @vph: Virtual path handle. Virtual Path Object that contains _this_ channel.
+ * @length: Channel length. Currently allocated number of descriptors.
+ *          The channel length "grows" when more descriptors get allocated.
+ *          See _hw_mempool_grow.
+ * @reserve_arr: Reserve array. Contains descriptors that can be reserved
+ *               by driver for the subsequent send or receive operation.
+ *               See vxge_hw_fifo_txdl_reserve(),
+ *               vxge_hw_ring_rxd_reserve().
+ * @reserve_ptr: Current pointer in the resrve array
+ * @reserve_top: Reserve top gives the maximum number of dtrs available in
+ *          reserve array.
+ * @work_arr: Work array. Contains descriptors posted to the channel.
+ *            Note that at any point in time @work_arr contains 3 types of
+ *            descriptors:
+ *            1) posted but not yet consumed by Titan device;
+ *            2) consumed but not yet completed;
+ *            3) completed but not yet freed
+ *            (via vxge_hw_fifo_txdl_free() or vxge_hw_ring_rxd_free())
+ * @post_index: Post index. At any point in time points on the
+ *              position in the channel, which'll contain next to-be-posted
+ *              descriptor.
+ * @compl_index: Completion index. At any point in time points on the
+ *               position in the channel, which will contain next
+ *               to-be-completed descriptor.
+ * @free_arr: Free array. Contains completed descriptors that were freed
+ *            (i.e., handed over back to HW) by driver.
+ *            See vxge_hw_fifo_txdl_free(), vxge_hw_ring_rxd_free().
+ * @free_ptr: current pointer in free array
+ * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize
+ *                 to store per-operation control information.
+ * @stats: Pointer to common statistics
+ * @userdata: Per-channel opaque (void*) user-defined context, which may be
+ *            driver object, ULP connection, etc.
+ *            Once channel is open, @userdata is passed back to user via
+ *            vxge_hw_channel_callback_f.
+ *
+ * HW channel object.
+ *
+ * See also: enum vxge_hw_channel_type{}, enum vxge_hw_channel_flag
+ */
+struct __vxge_hw_channel {
+	struct list_head		item;
+	enum __vxge_hw_channel_type	type;
+	struct __vxge_hw_device 	*devh;
+	struct __vxge_hw_vpath_handle 	*vph;
+	u32			length;
+	u32			vp_id;
+	void		**reserve_arr;
+	u32			reserve_ptr;
+	u32			reserve_top;
+	void		**work_arr;
+	u32			post_index ____cacheline_aligned;
+	u32			compl_index ____cacheline_aligned;
+	void		**free_arr;
+	u32			free_ptr;
+	void		**orig_arr;
+	u32			per_dtr_space;
+	void		*userdata;
+	struct vxge_hw_common_reg	__iomem *common_reg;
+	u32			first_vp_id;
+	struct vxge_hw_vpath_stats_sw_common_info *stats;
+
+} ____cacheline_aligned;
+
+/*
+ * struct __vxge_hw_virtualpath - Virtual Path
+ *
+ * @vp_id: Virtual path id
+ * @vp_open: This flag specifies if vxge_hw_vp_open is called from LL Driver
+ * @hldev: Hal device
+ * @vp_config: Virtual Path Config
+ * @vp_reg: VPATH Register map address in BAR0
+ * @vpmgmt_reg: VPATH_MGMT register map address
+ * @max_mtu: Max mtu that can be supported
+ * @vsport_number: vsport attached to this vpath
+ * @max_kdfc_db: Maximum kernel mode doorbells
+ * @max_nofl_db: Maximum non offload doorbells
+ * @tx_intr_num: Interrupt Number associated with the TX
+
+ * @ringh: Ring Queue
+ * @fifoh: FIFO Queue
+ * @vpath_handles: Virtual Path handles list
+ * @stats_block: Memory for DMAing stats
+ * @stats: Vpath statistics
+ *
+ * Virtual path structure to encapsulate the data related to a virtual path.
+ * Virtual paths are allocated by the HW upon getting configuration from the
+ * driver and inserted into the list of virtual paths.
+ */
+struct __vxge_hw_virtualpath {
+	u32				vp_id;
+
+	u32				vp_open;
+#define VXGE_HW_VP_NOT_OPEN	0
+#define	VXGE_HW_VP_OPEN		1
+
+	struct __vxge_hw_device		*hldev;
+	struct vxge_hw_vp_config	*vp_config;
+	struct vxge_hw_vpath_reg	__iomem *vp_reg;
+	struct vxge_hw_vpmgmt_reg	__iomem *vpmgmt_reg;
+	struct __vxge_hw_non_offload_db_wrapper	__iomem *nofl_db;
+
+	u32				max_mtu;
+	u32				vsport_number;
+	u32				max_kdfc_db;
+	u32				max_nofl_db;
+
+	struct __vxge_hw_ring *____cacheline_aligned ringh;
+	struct __vxge_hw_fifo *____cacheline_aligned fifoh;
+	struct list_head		vpath_handles;
+	struct __vxge_hw_blockpool_entry		*stats_block;
+	struct vxge_hw_vpath_stats_hw_info	*hw_stats;
+	struct vxge_hw_vpath_stats_hw_info	*hw_stats_sav;
+	struct vxge_hw_vpath_stats_sw_info	*sw_stats;
+};
+
+/*
+ * struct __vxge_hw_vpath_handle - List item to store callback information
+ * @item: List head to keep the item in linked list
+ * @vpath: Virtual path to which this item belongs
+ *
+ * This structure is used to store the callback information.
+ */
+struct __vxge_hw_vpath_handle{
+	struct list_head	item;
+	struct __vxge_hw_virtualpath	*vpath;
+};
+
+/*
+ * struct __vxge_hw_device
+ *
+ * HW device object.
+ */
+/**
+ * struct __vxge_hw_device  - Hal device object
+ * @magic: Magic Number
+ * @device_id: PCI Device Id of the adapter
+ * @major_revision: PCI Device major revision
+ * @minor_revision: PCI Device minor revision
+ * @bar0: BAR0 virtual address.
+ * @bar1: BAR1 virtual address.
+ * @bar2: BAR2 virtual address.
+ * @pdev: Physical device handle
+ * @config: Confguration passed by the LL driver at initialization
+ * @link_state: Link state
+ *
+ * HW device object. Represents Titan adapter
+ */
+struct __vxge_hw_device {
+	u32				magic;
+#define VXGE_HW_DEVICE_MAGIC		0x12345678
+#define VXGE_HW_DEVICE_DEAD		0xDEADDEAD
+	u16				device_id;
+	u8				major_revision;
+	u8				minor_revision;
+	void __iomem			*bar0;
+	void __iomem			*bar1;
+	void __iomem			*bar2;
+	struct pci_dev			*pdev;
+	struct net_device		*ndev;
+	struct vxge_hw_device_config	config;
+	enum vxge_hw_device_link_state	link_state;
+
+	struct vxge_hw_uld_cbs		uld_callbacks;
+
+	u32				host_type;
+	u32				func_id;
+	u32				access_rights;
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH      0x1
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM     0x2
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM     0x4
+	struct vxge_hw_legacy_reg	__iomem *legacy_reg;
+	struct vxge_hw_toc_reg		__iomem *toc_reg;
+	struct vxge_hw_common_reg	__iomem *common_reg;
+	struct vxge_hw_mrpcim_reg	__iomem *mrpcim_reg;
+	struct vxge_hw_srpcim_reg	__iomem *srpcim_reg \
+					[VXGE_HW_TITAN_SRPCIM_REG_SPACES];
+	struct vxge_hw_vpmgmt_reg	__iomem *vpmgmt_reg \
+					[VXGE_HW_TITAN_VPMGMT_REG_SPACES];
+	struct vxge_hw_vpath_reg	__iomem *vpath_reg \
+					[VXGE_HW_TITAN_VPATH_REG_SPACES];
+	u8				__iomem *kdfc;
+	u8				__iomem *usdc;
+	struct __vxge_hw_virtualpath	virtual_paths \
+					[VXGE_HW_MAX_VIRTUAL_PATHS];
+	u64				vpath_assignments;
+	u64				vpaths_deployed;
+	u32				first_vp_id;
+	u64				tim_int_mask0[4];
+	u32				tim_int_mask1[4];
+
+	struct __vxge_hw_blockpool	block_pool;
+	struct vxge_hw_device_stats	stats;
+	u32				debug_module_mask;
+	u32				debug_level;
+	u32				level_err;
+	u32				level_trace;
+};
+
+#define VXGE_HW_INFO_LEN	64
+/**
+ * struct vxge_hw_device_hw_info - Device information
+ * @host_type: Host Type
+ * @func_id: Function Id
+ * @vpath_mask: vpath bit mask
+ * @fw_version: Firmware version
+ * @fw_date: Firmware Date
+ * @flash_version: Firmware version
+ * @flash_date: Firmware Date
+ * @mac_addrs: Mac addresses for each vpath
+ * @mac_addr_masks: Mac address masks for each vpath
+ *
+ * Returns the vpath mask that has the bits set for each vpath allocated
+ * for the driver and the first mac address for each vpath
+ */
+struct vxge_hw_device_hw_info {
+	u32		host_type;
+#define VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION			0
+#define VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION			1
+#define VXGE_HW_NO_MR_SR_VH0_FUNCTION0				2
+#define VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION			3
+#define VXGE_HW_MR_SR_VH0_INVALID_CONFIG			4
+#define VXGE_HW_SR_VH_FUNCTION0					5
+#define VXGE_HW_SR_VH_VIRTUAL_FUNCTION				6
+#define VXGE_HW_VH_NORMAL_FUNCTION				7
+	u64		function_mode;
+#define VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION			0
+#define VXGE_HW_FUNCTION_MODE_SINGLE_FUNCTION			1
+#define VXGE_HW_FUNCTION_MODE_SRIOV				2
+#define VXGE_HW_FUNCTION_MODE_MRIOV				3
+	u32		func_id;
+	u64		vpath_mask;
+	struct vxge_hw_device_version fw_version;
+	struct vxge_hw_device_date    fw_date;
+	struct vxge_hw_device_version flash_version;
+	struct vxge_hw_device_date    flash_date;
+	u8		serial_number[VXGE_HW_INFO_LEN];
+	u8		part_number[VXGE_HW_INFO_LEN];
+	u8		product_desc[VXGE_HW_INFO_LEN];
+	u8 (mac_addrs)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+	u8 (mac_addr_masks)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+};
+
+/**
+ * struct vxge_hw_device_attr - Device memory spaces.
+ * @bar0: BAR0 virtual address.
+ * @bar1: BAR1 virtual address.
+ * @bar2: BAR2 virtual address.
+ * @pdev: PCI device object.
+ *
+ * Device memory spaces. Includes configuration, BAR0, BAR1, etc. per device
+ * mapped memories. Also, includes a pointer to OS-specific PCI device object.
+ */
+struct vxge_hw_device_attr {
+	void __iomem		*bar0;
+	void __iomem		*bar1;
+	void __iomem		*bar2;
+	struct pci_dev 		*pdev;
+	struct vxge_hw_uld_cbs	uld_callbacks;
+};
+
+#define VXGE_HW_DEVICE_LINK_STATE_SET(hldev, ls)	(hldev->link_state = ls)
+
+#define VXGE_HW_DEVICE_TIM_INT_MASK_SET(m0, m1, i) {	\
+	if (i < 16) {				\
+		m0[0] |= vxge_vBIT(0x8, (i*4), 4);	\
+		m0[1] |= vxge_vBIT(0x4, (i*4), 4);	\
+	}			       		\
+	else {					\
+		m1[0] = 0x80000000;		\
+		m1[1] = 0x40000000;		\
+	}					\
+}
+
+#define VXGE_HW_DEVICE_TIM_INT_MASK_RESET(m0, m1, i) {	\
+	if (i < 16) {					\
+		m0[0] &= ~vxge_vBIT(0x8, (i*4), 4);		\
+		m0[1] &= ~vxge_vBIT(0x4, (i*4), 4);		\
+	}						\
+	else {						\
+		m1[0] = 0;				\
+		m1[1] = 0;				\
+	}						\
+}
+
+#define VXGE_HW_DEVICE_STATS_PIO_READ(loc, offset) {		\
+	status = vxge_hw_mrpcim_stats_access(hldev, \
+				VXGE_HW_STATS_OP_READ, \
+				loc, \
+				offset, \
+				&val64);			\
+								\
+	if (status != VXGE_HW_OK)				\
+		return status;						\
+}
+
+#define VXGE_HW_VPATH_STATS_PIO_READ(offset) {				\
+	status = __vxge_hw_vpath_stats_access(vpath, \
+			VXGE_HW_STATS_OP_READ, \
+			offset, \
+			&val64);					\
+	if (status != VXGE_HW_OK)					\
+		return status;						\
+}
+
+/*
+ * struct __vxge_hw_ring - Ring channel.
+ * @channel: Channel "base" of this ring, the common part of all HW
+ *           channels.
+ * @mempool: Memory pool, the pool from which descriptors get allocated.
+ *           (See vxge_hw_mm.h).
+ * @config: Ring configuration, part of device configuration
+ *          (see struct vxge_hw_device_config{}).
+ * @ring_length: Length of the ring
+ * @buffer_mode: 1, 3, or 5. The value specifies a receive buffer mode,
+ *          as per Titan User Guide.
+ * @rxd_size: RxD sizes for 1-, 3- or 5- buffer modes. As per Titan spec,
+ *            1-buffer mode descriptor is 32 byte long, etc.
+ * @rxd_priv_size: Per RxD size reserved (by HW) for driver to keep
+ *                 per-descriptor data (e.g., DMA handle for Solaris)
+ * @per_rxd_space: Per rxd space requested by driver
+ * @rxds_per_block: Number of descriptors per hardware-defined RxD
+ *                  block. Depends on the (1-, 3-, 5-) buffer mode.
+ * @rxdblock_priv_size: Reserved at the end of each RxD block. HW internal
+ *                      usage. Not to confuse with @rxd_priv_size.
+ * @cmpl_cnt: Completion counter. Is reset to zero upon entering the ISR.
+ * @callback: Channel completion callback. HW invokes the callback when there
+ *            are new completions on that channel. In many implementations
+ *            the @callback executes in the hw interrupt context.
+ * @rxd_init: Channel's descriptor-initialize callback.
+ *            See vxge_hw_ring_rxd_init_f{}.
+ *            If not NULL, HW invokes the callback when opening
+ *            the ring.
+ * @rxd_term: Channel's descriptor-terminate callback. If not NULL,
+ *          HW invokes the callback when closing the corresponding channel.
+ *          See also vxge_hw_channel_rxd_term_f{}.
+ * @stats: Statistics for ring
+ * Ring channel.
+ *
+ * Note: The structure is cache line aligned to better utilize
+ *       CPU cache performance.
+ */
+struct __vxge_hw_ring {
+	struct __vxge_hw_channel		channel;
+	struct vxge_hw_mempool			*mempool;
+	struct vxge_hw_vpath_reg		__iomem	*vp_reg;
+	struct vxge_hw_common_reg		__iomem	*common_reg;
+	u32					ring_length;
+	u32					buffer_mode;
+	u32					rxd_size;
+	u32					rxd_priv_size;
+	u32					per_rxd_space;
+	u32					rxds_per_block;
+	u32					rxdblock_priv_size;
+	u32					cmpl_cnt;
+	u32					vp_id;
+	u32					doorbell_cnt;
+	u32					total_db_cnt;
+	u64					rxds_limit;
+
+	enum vxge_hw_status (*callback)(
+			struct __vxge_hw_ring *ringh,
+			void *rxdh,
+			u8 t_code,
+			void *userdata);
+
+	enum vxge_hw_status (*rxd_init)(
+			void *rxdh,
+			void *userdata);
+
+	void (*rxd_term)(
+			void *rxdh,
+			enum vxge_hw_rxd_state state,
+			void *userdata);
+
+	struct vxge_hw_vpath_stats_sw_ring_info *stats	____cacheline_aligned;
+	struct vxge_hw_ring_config		*config;
+} ____cacheline_aligned;
+
+/**
+ * enum enum vxge_hw_txdl_state - Descriptor (TXDL) state.
+ * @VXGE_HW_TXDL_STATE_NONE: Invalid state.
+ * @VXGE_HW_TXDL_STATE_AVAIL: Descriptor is available for reservation.
+ * @VXGE_HW_TXDL_STATE_POSTED: Descriptor is posted for processing by the
+ * device.
+ * @VXGE_HW_TXDL_STATE_FREED: Descriptor is free and can be reused for
+ * filling-in and posting later.
+ *
+ * Titan/HW descriptor states.
+ *
+ */
+enum vxge_hw_txdl_state {
+	VXGE_HW_TXDL_STATE_NONE	= 0,
+	VXGE_HW_TXDL_STATE_AVAIL	= 1,
+	VXGE_HW_TXDL_STATE_POSTED	= 2,
+	VXGE_HW_TXDL_STATE_FREED	= 3
+};
+/*
+ * struct __vxge_hw_fifo - Fifo.
+ * @channel: Channel "base" of this fifo, the common part of all HW
+ *             channels.
+ * @mempool: Memory pool, from which descriptors get allocated.
+ * @config: Fifo configuration, part of device configuration
+ *             (see struct vxge_hw_device_config{}).
+ * @interrupt_type: Interrupt type to be used
+ * @no_snoop_bits: See struct vxge_hw_fifo_config{}.
+ * @txdl_per_memblock: Number of TxDLs (TxD lists) per memblock.
+ *             on TxDL please refer to Titan UG.
+ * @txdl_size: Configured TxDL size (i.e., number of TxDs in a list), plus
+ *             per-TxDL HW private space (struct __vxge_hw_fifo_txdl_priv).
+ * @priv_size: Per-Tx descriptor space reserved for driver
+ *             usage.
+ * @per_txdl_space: Per txdl private space for the driver
+ * @callback: Fifo completion callback. HW invokes the callback when there
+ *             are new completions on that fifo. In many implementations
+ *             the @callback executes in the hw interrupt context.
+ * @txdl_term: Fifo's descriptor-terminate callback. If not NULL,
+ *             HW invokes the callback when closing the corresponding fifo.
+ *             See also vxge_hw_fifo_txdl_term_f{}.
+ * @stats: Statistics of this fifo
+ *
+ * Fifo channel.
+ * Note: The structure is cache line aligned.
+ */
+struct __vxge_hw_fifo {
+	struct __vxge_hw_channel		channel;
+	struct vxge_hw_mempool			*mempool;
+	struct vxge_hw_fifo_config		*config;
+	struct vxge_hw_vpath_reg		__iomem *vp_reg;
+	struct __vxge_hw_non_offload_db_wrapper	__iomem *nofl_db;
+	u64					interrupt_type;
+	u32					no_snoop_bits;
+	u32					txdl_per_memblock;
+	u32					txdl_size;
+	u32					priv_size;
+	u32					per_txdl_space;
+	u32					vp_id;
+	u32					tx_intr_num;
+
+	enum vxge_hw_status (*callback)(
+			struct __vxge_hw_fifo *fifo_handle,
+			void *txdlh,
+			enum vxge_hw_fifo_tcode t_code,
+			void *userdata,
+			void **skb_ptr);
+
+	void (*txdl_term)(
+			void *txdlh,
+			enum vxge_hw_txdl_state state,
+			void *userdata);
+
+	struct vxge_hw_vpath_stats_sw_fifo_info *stats ____cacheline_aligned;
+} ____cacheline_aligned;
+
+/*
+ * struct __vxge_hw_fifo_txdl_priv - Transmit descriptor HW-private data.
+ * @dma_addr: DMA (mapped) address of _this_ descriptor.
+ * @dma_handle: DMA handle used to map the descriptor onto device.
+ * @dma_offset: Descriptor's offset in the memory block. HW allocates
+ *	 descriptors in memory blocks (see struct vxge_hw_fifo_config{})
+ *             Each memblock is a contiguous block of DMA-able memory.
+ * @frags: Total number of fragments (that is, contiguous data buffers)
+ * carried by this TxDL.
+ * @align_vaddr_start: Aligned virtual address start
+ * @align_vaddr: Virtual address of the per-TxDL area in memory used for
+ *             alignement. Used to place one or more mis-aligned fragments
+ * @align_dma_addr: DMA address translated from the @align_vaddr.
+ * @align_dma_handle: DMA handle that corresponds to @align_dma_addr.
+ * @align_dma_acch: DMA access handle corresponds to @align_dma_addr.
+ * @align_dma_offset: The current offset into the @align_vaddr area.
+ * Grows while filling the descriptor, gets reset.
+ * @align_used_frags: Number of fragments used.
+ * @alloc_frags: Total number of fragments allocated.
+ * @unused: TODO
+ * @next_txdl_priv: (TODO).
+ * @first_txdp: (TODO).
+ * @linked_txdl_priv: Pointer to any linked TxDL for creating contiguous
+ *             TxDL list.
+ * @txdlh: Corresponding txdlh to this TxDL.
+ * @memblock: Pointer to the TxDL memory block or memory page.
+ *             on the next send operation.
+ * @dma_object: DMA address and handle of the memory block that contains
+ *             the descriptor. This member is used only in the "checked"
+ *             version of the HW (to enforce certain assertions);
+ *             otherwise it gets compiled out.
+ * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage.
+ *
+ * Per-transmit decsriptor HW-private data. HW uses the space to keep DMA
+ * information associated with the descriptor. Note that driver can ask HW
+ * to allocate additional per-descriptor space for its own (driver-specific)
+ * purposes.
+ *
+ * See also: struct vxge_hw_ring_rxd_priv{}.
+ */
+struct __vxge_hw_fifo_txdl_priv {
+	dma_addr_t		dma_addr;
+	struct pci_dev	*dma_handle;
+	ptrdiff_t		dma_offset;
+	u32				frags;
+	u8				*align_vaddr_start;
+	u8				*align_vaddr;
+	dma_addr_t		align_dma_addr;
+	struct pci_dev 	*align_dma_handle;
+	struct pci_dev	*align_dma_acch;
+	ptrdiff_t		align_dma_offset;
+	u32				align_used_frags;
+	u32				alloc_frags;
+	u32				unused;
+	struct __vxge_hw_fifo_txdl_priv	*next_txdl_priv;
+	struct vxge_hw_fifo_txd		*first_txdp;
+	void			*memblock;
+};
+
+/*
+ * struct __vxge_hw_non_offload_db_wrapper - Non-offload Doorbell Wrapper
+ * @control_0: Bits 0 to 7 - Doorbell type.
+ *             Bits 8 to 31 - Reserved.
+ *             Bits 32 to 39 - The highest TxD in this TxDL.
+ *             Bits 40 to 47 - Reserved.
+	*	       Bits 48 to 55 - Reserved.
+ *             Bits 56 to 63 - No snoop flags.
+ * @txdl_ptr:  The starting location of the TxDL in host memory.
+ *
+ * Created by the host and written to the adapter via PIO to a Kernel Doorbell
+ * FIFO. All non-offload doorbell wrapper fields must be written by the host as
+ * part of a doorbell write. Consumed by the adapter but is not written by the
+ * adapter.
+ */
+struct __vxge_hw_non_offload_db_wrapper {
+	u64		control_0;
+#define	VXGE_HW_NODBW_GET_TYPE(ctrl0)			vxge_bVALn(ctrl0, 0, 8)
+#define VXGE_HW_NODBW_TYPE(val) vxge_vBIT(val, 0, 8)
+#define	VXGE_HW_NODBW_TYPE_NODBW				0
+
+#define	VXGE_HW_NODBW_GET_LAST_TXD_NUMBER(ctrl0)	vxge_bVALn(ctrl0, 32, 8)
+#define VXGE_HW_NODBW_LAST_TXD_NUMBER(val) vxge_vBIT(val, 32, 8)
+
+#define	VXGE_HW_NODBW_GET_NO_SNOOP(ctrl0)		vxge_bVALn(ctrl0, 56, 8)
+#define VXGE_HW_NODBW_LIST_NO_SNOOP(val) vxge_vBIT(val, 56, 8)
+#define	VXGE_HW_NODBW_LIST_NO_SNOOP_TXD_READ_TXD0_WRITE		0x2
+#define	VXGE_HW_NODBW_LIST_NO_SNOOP_TX_FRAME_DATA_READ		0x1
+
+	u64		txdl_ptr;
+};
+
+/*
+ * TX Descriptor
+ */
+
+/**
+ * struct vxge_hw_fifo_txd - Transmit Descriptor
+ * @control_0: Bits 0 to 6 - Reserved.
+ *             Bit 7 - List Ownership. This field should be initialized
+ *             to '1' by the driver before the transmit list pointer is
+ *             written to the adapter. This field will be set to '0' by the
+ *             adapter once it has completed transmitting the frame or frames in
+ *             the list. Note - This field is only valid in TxD0. Additionally,
+ *             for multi-list sequences, the driver should not release any
+ *             buffers until the ownership of the last list in the multi-list
+ *             sequence has been returned to the host.
+ *             Bits 8 to 11 - Reserved
+ *             Bits 12 to 15 - Transfer_Code. This field is only valid in
+ *             TxD0. It is used to describe the status of the transmit data
+ *             buffer transfer. This field is always overwritten by the
+ *             adapter, so this field may be initialized to any value.
+ *             Bits 16 to 17 - Host steering. This field allows the host to
+ *             override the selection of the physical transmit port.
+ *             Attention:
+ *             Normal sounds as if learned from the switch rather than from
+ *             the aggregation algorythms.
+ *             00: Normal. Use Destination/MAC Address
+ *             lookup to determine the transmit port.
+ *             01: Send on physical Port1.
+ *             10: Send on physical Port0.
+	*	       11: Send on both ports.
+ *             Bits 18 to 21 - Reserved
+ *             Bits 22 to 23 - Gather_Code. This field is set by the host and
+ *             is used to describe how individual buffers comprise a frame.
+ *             10: First descriptor of a frame.
+ *             00: Middle of a multi-descriptor frame.
+ *             01: Last descriptor of a frame.
+ *             11: First and last descriptor of a frame (the entire frame
+ *             resides in a single buffer).
+ *             For multi-descriptor frames, the only valid gather code sequence
+ *             is {10, [00], 01}. In other words, the descriptors must be placed
+ *             in the list in the correct order.
+ *             Bits 24 to 27 - Reserved
+ *             Bits 28 to 29 - LSO_Frm_Encap. LSO Frame Encapsulation
+ *             definition. Only valid in TxD0. This field allows the host to
+ *             indicate the Ethernet encapsulation of an outbound LSO packet.
+ *             00 - classic mode (best guess)
+ *             01 - LLC
+ *             10 - SNAP
+ *             11 - DIX
+ *             If "classic mode" is selected, the adapter will attempt to
+ *             decode the frame's Ethernet encapsulation by examining the L/T
+ *             field as follows:
+ *             <= 0x05DC LLC/SNAP encoding; must examine DSAP/SSAP to determine
+ *             if packet is IPv4 or IPv6.
+ *             0x8870 Jumbo-SNAP encoding.
+ *             0x0800 IPv4 DIX encoding
+ *             0x86DD IPv6 DIX encoding
+ *             others illegal encapsulation
+ *             Bits 30 - LSO_ Flag. Large Send Offload (LSO) flag.
+ *             Set to 1 to perform segmentation offload for TCP/UDP.
+ *             This field is valid only in TxD0.
+ *             Bits 31 to 33 - Reserved.
+ *             Bits 34 to 47 - LSO_MSS. TCP/UDP LSO Maximum Segment Size
+ *             This field is meaningful only when LSO_Control is non-zero.
+ *             When LSO_Control is set to TCP_LSO, the single (possibly large)
+ *             TCP segment described by this TxDL will be sent as a series of
+ *             TCP segments each of which contains no more than LSO_MSS
+ *             payload bytes.
+ *             When LSO_Control is set to UDP_LSO, the single (possibly large)
+ *             UDP datagram described by this TxDL will be sent as a series of
+ *             UDP datagrams each of which contains no more than LSO_MSS
+ *             payload bytes.
+ *             All outgoing frames from this TxDL will have LSO_MSS bytes of UDP
+ *             or TCP payload, with the exception of the last, which will have
+ *             <= LSO_MSS bytes of payload.
+ *             Bits 48 to 63 - Buffer_Size. Number of valid bytes in the
+ *             buffer to be read by the adapter. This field is written by the
+ *             host. A value of 0 is illegal.
+ *	       Bits 32 to 63 - This value is written by the adapter upon
+ *	       completion of a UDP or TCP LSO operation and indicates the number
+ *             of UDP or TCP payload bytes that were transmitted. 0x0000 will be
+ *             returned for any non-LSO operation.
+ * @control_1: Bits 0 to 4 - Reserved.
+ *             Bit 5 - Tx_CKO_IPv4 Set to a '1' to enable IPv4 header checksum
+ *             offload. This field is only valid in the first TxD of a frame.
+ *             Bit 6 - Tx_CKO_TCP Set to a '1' to enable TCP checksum offload.
+ *             This field is only valid in the first TxD of a frame (the TxD's
+ *             gather code must be 10 or 11). The driver should only set this
+ *             bit if it can guarantee that TCP is present.
+ *             Bit 7 - Tx_CKO_UDP Set to a '1' to enable UDP checksum offload.
+ *             This field is only valid in the first TxD of a frame (the TxD's
+ *             gather code must be 10 or 11). The driver should only set this
+ *             bit if it can guarantee that UDP is present.
+ *             Bits 8 to 14 - Reserved.
+ *             Bit 15 - Tx_VLAN_Enable VLAN tag insertion flag. Set to a '1' to
+ *             instruct the adapter to insert the VLAN tag specified by the
+ *             Tx_VLAN_Tag field. This field is only valid in the first TxD of
+ *             a frame.
+ *             Bits 16 to 31 - Tx_VLAN_Tag. Variable portion of the VLAN tag
+ *             to be inserted into the frame by the adapter (the first two bytes
+ *             of a VLAN tag are always 0x8100). This field is only valid if the
+ *             Tx_VLAN_Enable field is set to '1'.
+ *             Bits 32 to 33 - Reserved.
+ *             Bits 34 to 39 - Tx_Int_Number. Indicates which Tx interrupt
+ *             number the frame associated with. This field is written by the
+ *             host. It is only valid in the first TxD of a frame.
+ *             Bits 40 to 42 - Reserved.
+ *             Bit 43 - Set to 1 to exclude the frame from bandwidth metering
+ *             functions. This field is valid only in the first TxD
+ *             of a frame.
+ *             Bits 44 to 45 - Reserved.
+ *             Bit 46 - Tx_Int_Per_List Set to a '1' to instruct the adapter to
+ *             generate an interrupt as soon as all of the frames in the list
+ *             have been transmitted. In order to have per-frame interrupts,
+ *             the driver should place a maximum of one frame per list. This
+ *             field is only valid in the first TxD of a frame.
+ *             Bit 47 - Tx_Int_Utilization Set to a '1' to instruct the adapter
+ *             to count the frame toward the utilization interrupt specified in
+ *             the Tx_Int_Number field. This field is only valid in the first
+ *             TxD of a frame.
+ *             Bits 48 to 63 - Reserved.
+ * @buffer_pointer: Buffer start address.
+ * @host_control: Host_Control.Opaque 64bit data stored by driver inside the
+ *            Titan descriptor prior to posting the latter on the fifo
+ *            via vxge_hw_fifo_txdl_post().The %host_control is returned as is
+ *            to the driver with each completed descriptor.
+ *
+ * Transmit descriptor (TxD).Fifo descriptor contains configured number
+ * (list) of TxDs. * For more details please refer to Titan User Guide,
+ * Section 5.4.2 "Transmit Descriptor (TxD) Format".
+ */
+struct vxge_hw_fifo_txd {
+	u64 control_0;
+#define VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER		vxge_mBIT(7)
+
+#define VXGE_HW_FIFO_TXD_T_CODE_GET(ctrl0)		vxge_bVALn(ctrl0, 12, 4)
+#define VXGE_HW_FIFO_TXD_T_CODE(val) 			vxge_vBIT(val, 12, 4)
+#define VXGE_HW_FIFO_TXD_T_CODE_UNUSED		VXGE_HW_FIFO_T_CODE_UNUSED
+
+
+#define VXGE_HW_FIFO_TXD_GATHER_CODE(val) 		vxge_vBIT(val, 22, 2)
+#define VXGE_HW_FIFO_TXD_GATHER_CODE_FIRST	VXGE_HW_FIFO_GATHER_CODE_FIRST
+#define VXGE_HW_FIFO_TXD_GATHER_CODE_LAST	VXGE_HW_FIFO_GATHER_CODE_LAST
+
+
+#define VXGE_HW_FIFO_TXD_LSO_EN				vxge_mBIT(30)
+
+#define VXGE_HW_FIFO_TXD_LSO_MSS(val) 			vxge_vBIT(val, 34, 14)
+
+#define VXGE_HW_FIFO_TXD_BUFFER_SIZE(val) 		vxge_vBIT(val, 48, 16)
+
+	u64 control_1;
+#define VXGE_HW_FIFO_TXD_TX_CKO_IPV4_EN			vxge_mBIT(5)
+#define VXGE_HW_FIFO_TXD_TX_CKO_TCP_EN			vxge_mBIT(6)
+#define VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN			vxge_mBIT(7)
+#define VXGE_HW_FIFO_TXD_VLAN_ENABLE			vxge_mBIT(15)
+
+#define VXGE_HW_FIFO_TXD_VLAN_TAG(val) 			vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_FIFO_TXD_INT_NUMBER(val) 		vxge_vBIT(val, 34, 6)
+
+#define VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST		vxge_mBIT(46)
+#define VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ			vxge_mBIT(47)
+
+	u64 buffer_pointer;
+
+	u64 host_control;
+};
+
+/**
+ * struct vxge_hw_ring_rxd_1 - One buffer mode RxD for ring
+ * @host_control: This field is exclusively for host use and is "readonly"
+ *             from the adapter's perspective.
+ * @control_0:Bits 0 to 6 - RTH_Bucket get
+ *	      Bit 7 - Own Descriptor ownership bit. This bit is set to 1
+ *            by the host, and is set to 0 by the adapter.
+ *	      0 - Host owns RxD and buffer.
+ *	      1 - The adapter owns RxD and buffer.
+ *	      Bit 8 - Fast_Path_Eligible When set, indicates that the
+ *            received frame meets all of the criteria for fast path processing.
+ *            The required criteria are as follows:
+ *            !SYN &
+ *            (Transfer_Code == "Transfer OK") &
+ *            (!Is_IP_Fragment) &
+ *            ((Is_IPv4 & computed_L3_checksum == 0xFFFF) |
+ *            (Is_IPv6)) &
+ *            ((Is_TCP & computed_L4_checksum == 0xFFFF) |
+ *            (Is_UDP & (computed_L4_checksum == 0xFFFF |
+ *            computed _L4_checksum == 0x0000)))
+ *            (same meaning for all RxD buffer modes)
+ *	      Bit 9 - L3 Checksum Correct
+ *	      Bit 10 - L4 Checksum Correct
+ *	      Bit 11 - Reserved
+ *	      Bit 12 to 15 - This field is written by the adapter. It is
+ *            used to report the status of the frame transfer to the host.
+ *	      0x0 - Transfer OK
+ *	      0x4 - RDA Failure During Transfer
+ *	      0x5 - Unparseable Packet, such as unknown IPv6 header.
+ *	      0x6 - Frame integrity error (FCS or ECC).
+ *	      0x7 - Buffer Size Error. The provided buffer(s) were not
+ *                  appropriately sized and data loss occurred.
+ *	      0x8 - Internal ECC Error. RxD corrupted.
+ *	      0x9 - IPv4 Checksum error
+ *	      0xA - TCP/UDP Checksum error
+ *	      0xF - Unknown Error or Multiple Error. Indicates an
+ *               unknown problem or that more than one of transfer codes is set.
+ *	      Bit 16 - SYN The adapter sets this field to indicate that
+ *                the incoming frame contained a TCP segment with its SYN bit
+ *	          set and its ACK bit NOT set. (same meaning for all RxD buffer
+ *                modes)
+ *	      Bit 17 - Is ICMP
+ *	      Bit 18 - RTH_SPDM_HIT Set to 1 if there was a match in the
+ *                Socket Pair Direct Match Table and the frame was steered based
+ *                on SPDM.
+ *	      Bit 19 - RTH_IT_HIT Set to 1 if there was a match in the
+ *            Indirection Table and the frame was steered based on hash
+ *            indirection.
+ *	      Bit 20 to 23 - RTH_HASH_TYPE Indicates the function (hash
+ *	          type) that was used to calculate the hash.
+ *	      Bit 19 - IS_VLAN Set to '1' if the frame was/is VLAN
+ *	          tagged.
+ *	      Bit 25 to 26 - ETHER_ENCAP Reflects the Ethernet encapsulation
+ *                of the received frame.
+ *	      0x0 - Ethernet DIX
+ *	      0x1 - LLC
+ *	      0x2 - SNAP (includes Jumbo-SNAP)
+ *	      0x3 - IPX
+ *	      Bit 27 - IS_IPV4 Set to '1' if the frame contains an IPv4	packet.
+ *	      Bit 28 - IS_IPV6 Set to '1' if the frame contains an IPv6 packet.
+ *	      Bit 29 - IS_IP_FRAG Set to '1' if the frame contains a fragmented
+ *            IP packet.
+ *	      Bit 30 - IS_TCP Set to '1' if the frame contains a TCP segment.
+ *	      Bit 31 - IS_UDP Set to '1' if the frame contains a UDP message.
+ *	      Bit 32 to 47 - L3_Checksum[0:15] The IPv4 checksum value 	that
+ *            arrived with the frame. If the resulting computed IPv4 header
+ *            checksum for the frame did not produce the expected 0xFFFF value,
+ *            then the transfer code would be set to 0x9.
+ *	      Bit 48 to 63 - L4_Checksum[0:15] The TCP/UDP checksum value that
+ *            arrived with the frame. If the resulting computed TCP/UDP checksum
+ *            for the frame did not produce the expected 0xFFFF value, then the
+ *            transfer code would be set to 0xA.
+ * @control_1:Bits 0 to 1 - Reserved
+ *            Bits 2 to 15 - Buffer0_Size.This field is set by the host and
+ *            eventually overwritten by the adapter. The host writes the
+ *            available buffer size in bytes when it passes the descriptor to
+ *            the adapter. When a frame is delivered the host, the adapter
+ *            populates this field with the number of bytes written into the
+ *            buffer. The largest supported buffer is 16, 383 bytes.
+ *	      Bit 16 to 47 - RTH Hash Value 32-bit RTH hash value. Only valid if
+ *	      RTH_HASH_TYPE (Control_0, bits 20:23) is nonzero.
+ *	      Bit 48 to 63 - VLAN_Tag[0:15] The contents of the variable portion
+ *            of the VLAN tag, if one was detected by the adapter. This field is
+ *            populated even if VLAN-tag stripping is enabled.
+ * @buffer0_ptr: Pointer to buffer. This field is populated by the driver.
+ *
+ * One buffer mode RxD for ring structure
+ */
+struct vxge_hw_ring_rxd_1 {
+	u64 host_control;
+	u64 control_0;
+#define VXGE_HW_RING_RXD_RTH_BUCKET_GET(ctrl0)		vxge_bVALn(ctrl0, 0, 7)
+
+#define VXGE_HW_RING_RXD_LIST_OWN_ADAPTER		vxge_mBIT(7)
+
+#define VXGE_HW_RING_RXD_FAST_PATH_ELIGIBLE_GET(ctrl0)	vxge_bVALn(ctrl0, 8, 1)
+
+#define VXGE_HW_RING_RXD_L3_CKSUM_CORRECT_GET(ctrl0)	vxge_bVALn(ctrl0, 9, 1)
+
+#define VXGE_HW_RING_RXD_L4_CKSUM_CORRECT_GET(ctrl0)	vxge_bVALn(ctrl0, 10, 1)
+
+#define VXGE_HW_RING_RXD_T_CODE_GET(ctrl0)		vxge_bVALn(ctrl0, 12, 4)
+#define VXGE_HW_RING_RXD_T_CODE(val) 			vxge_vBIT(val, 12, 4)
+
+#define VXGE_HW_RING_RXD_T_CODE_UNUSED		VXGE_HW_RING_T_CODE_UNUSED
+
+#define VXGE_HW_RING_RXD_SYN_GET(ctrl0)		vxge_bVALn(ctrl0, 16, 1)
+
+#define VXGE_HW_RING_RXD_IS_ICMP_GET(ctrl0)		vxge_bVALn(ctrl0, 17, 1)
+
+#define VXGE_HW_RING_RXD_RTH_SPDM_HIT_GET(ctrl0)	vxge_bVALn(ctrl0, 18, 1)
+
+#define VXGE_HW_RING_RXD_RTH_IT_HIT_GET(ctrl0)		vxge_bVALn(ctrl0, 19, 1)
+
+#define VXGE_HW_RING_RXD_RTH_HASH_TYPE_GET(ctrl0)	vxge_bVALn(ctrl0, 20, 4)
+
+#define VXGE_HW_RING_RXD_IS_VLAN_GET(ctrl0)		vxge_bVALn(ctrl0, 24, 1)
+
+#define VXGE_HW_RING_RXD_ETHER_ENCAP_GET(ctrl0)		vxge_bVALn(ctrl0, 25, 2)
+
+#define VXGE_HW_RING_RXD_FRAME_PROTO_GET(ctrl0)		vxge_bVALn(ctrl0, 27, 5)
+
+#define VXGE_HW_RING_RXD_L3_CKSUM_GET(ctrl0)	vxge_bVALn(ctrl0, 32, 16)
+
+#define VXGE_HW_RING_RXD_L4_CKSUM_GET(ctrl0)	vxge_bVALn(ctrl0, 48, 16)
+
+	u64 control_1;
+
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE_GET(ctrl1)	vxge_bVALn(ctrl1, 2, 14)
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE(val) vxge_vBIT(val, 2, 14)
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE_MASK		vxge_vBIT(0x3FFF, 2, 14)
+
+#define VXGE_HW_RING_RXD_1_RTH_HASH_VAL_GET(ctrl1)    vxge_bVALn(ctrl1, 16, 32)
+
+#define VXGE_HW_RING_RXD_VLAN_TAG_GET(ctrl1)	vxge_bVALn(ctrl1, 48, 16)
+
+	u64 buffer0_ptr;
+};
+
+enum vxge_hw_rth_algoritms {
+	RTH_ALG_JENKINS = 0,
+	RTH_ALG_MS_RSS	= 1,
+	RTH_ALG_CRC32C	= 2
+};
+
+/**
+ * struct vxge_hw_rth_hash_types - RTH hash types.
+ * @hash_type_tcpipv4_en: Enables RTH field type HashTypeTcpIPv4
+ * @hash_type_ipv4_en: Enables RTH field type HashTypeIPv4
+ * @hash_type_tcpipv6_en: Enables RTH field type HashTypeTcpIPv6
+ * @hash_type_ipv6_en: Enables RTH field type HashTypeIPv6
+ * @hash_type_tcpipv6ex_en: Enables RTH field type HashTypeTcpIPv6Ex
+ * @hash_type_ipv6ex_en: Enables RTH field type HashTypeIPv6Ex
+ *
+ * Used to pass RTH hash types to rts_rts_set.
+ *
+ * See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
+ */
+struct vxge_hw_rth_hash_types {
+	u8 hash_type_tcpipv4_en;
+	u8 hash_type_ipv4_en;
+	u8 hash_type_tcpipv6_en;
+	u8 hash_type_ipv6_en;
+	u8 hash_type_tcpipv6ex_en;
+	u8 hash_type_ipv6ex_en;
+};
+
+u32
+vxge_hw_device_debug_mask_get(struct __vxge_hw_device *devh);
+
+void vxge_hw_device_debug_set(
+	struct __vxge_hw_device *devh,
+	enum vxge_debug_level level,
+	u32 mask);
+
+u32
+vxge_hw_device_error_level_get(struct __vxge_hw_device *devh);
+
+u32
+vxge_hw_device_trace_level_get(struct __vxge_hw_device *devh);
+
+u32
+vxge_hw_device_debug_mask_get(struct __vxge_hw_device *devh);
+
+/**
+ * vxge_hw_ring_rxd_size_get	- Get the size of ring descriptor.
+ * @buf_mode: Buffer mode (1, 3 or 5)
+ *
+ * This function returns the size of RxD for given buffer mode
+ */
+static inline u32 vxge_hw_ring_rxd_size_get(u32 buf_mode)
+{
+	return sizeof(struct vxge_hw_ring_rxd_1);
+}
+
+/**
+ * vxge_hw_ring_rxds_per_block_get - Get the number of rxds per block.
+ * @buf_mode: Buffer mode (1 buffer mode only)
+ *
+ * This function returns the number of RxD for RxD block for given buffer mode
+ */
+static inline u32 vxge_hw_ring_rxds_per_block_get(u32 buf_mode)
+{
+	return (u32)((VXGE_HW_BLOCK_SIZE-16) /
+		sizeof(struct vxge_hw_ring_rxd_1));
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_set - Prepare 1-buffer-mode descriptor.
+ * @rxdh: Descriptor handle.
+ * @dma_pointer: DMA address of	a single receive buffer	this descriptor
+ * should carry. Note that by the time vxge_hw_ring_rxd_1b_set is called,
+ * the receive buffer should be already mapped to the device
+ * @size: Size of the receive @dma_pointer buffer.
+ *
+ * Prepare 1-buffer-mode Rx	descriptor for posting
+ * (via	vxge_hw_ring_rxd_post()).
+ *
+ * This	inline helper-function does not	return any parameters and always
+ * succeeds.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_set(
+	void *rxdh,
+	dma_addr_t dma_pointer,
+	u32 size)
+{
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+	rxdp->buffer0_ptr = dma_pointer;
+	rxdp->control_1	&= ~VXGE_HW_RING_RXD_1_BUFFER0_SIZE_MASK;
+	rxdp->control_1	|= VXGE_HW_RING_RXD_1_BUFFER0_SIZE(size);
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_get - Get data from the completed 1-buf
+ * descriptor.
+ * @vpath_handle: Virtual Path handle.
+ * @rxdh: Descriptor handle.
+ * @dma_pointer: DMA address of	a single receive buffer	this descriptor
+ * carries. Returned by HW.
+ * @pkt_length:	Length (in bytes) of the data in the buffer pointed by
+ *
+ * Retrieve protocol data from the completed 1-buffer-mode Rx descriptor.
+ * This	inline helper-function uses completed descriptor to populate receive
+ * buffer pointer and other "out" parameters. The function always succeeds.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_get(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh,
+	u32 *pkt_length)
+{
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+
+	*pkt_length =
+		(u32)VXGE_HW_RING_RXD_1_BUFFER0_SIZE_GET(rxdp->control_1);
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_info_get - Get extended information associated with
+ * a completed receive descriptor for 1b mode.
+ * @vpath_handle: Virtual Path handle.
+ * @rxdh: Descriptor handle.
+ * @rxd_info: Descriptor information
+ *
+ * Retrieve extended information associated with a completed receive descriptor.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_info_get(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh,
+	struct vxge_hw_ring_rxd_info *rxd_info)
+{
+
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+	rxd_info->syn_flag =
+		(u32)VXGE_HW_RING_RXD_SYN_GET(rxdp->control_0);
+	rxd_info->is_icmp =
+		(u32)VXGE_HW_RING_RXD_IS_ICMP_GET(rxdp->control_0);
+	rxd_info->fast_path_eligible =
+		(u32)VXGE_HW_RING_RXD_FAST_PATH_ELIGIBLE_GET(rxdp->control_0);
+	rxd_info->l3_cksum_valid =
+		(u32)VXGE_HW_RING_RXD_L3_CKSUM_CORRECT_GET(rxdp->control_0);
+	rxd_info->l3_cksum =
+		(u32)VXGE_HW_RING_RXD_L3_CKSUM_GET(rxdp->control_0);
+	rxd_info->l4_cksum_valid =
+		(u32)VXGE_HW_RING_RXD_L4_CKSUM_CORRECT_GET(rxdp->control_0);
+	rxd_info->l4_cksum =
+		(u32)VXGE_HW_RING_RXD_L4_CKSUM_GET(rxdp->control_0);;
+	rxd_info->frame =
+		(u32)VXGE_HW_RING_RXD_ETHER_ENCAP_GET(rxdp->control_0);
+	rxd_info->proto =
+		(u32)VXGE_HW_RING_RXD_FRAME_PROTO_GET(rxdp->control_0);
+	rxd_info->is_vlan =
+		(u32)VXGE_HW_RING_RXD_IS_VLAN_GET(rxdp->control_0);
+	rxd_info->vlan =
+		(u32)VXGE_HW_RING_RXD_VLAN_TAG_GET(rxdp->control_1);
+	rxd_info->rth_bucket =
+		(u32)VXGE_HW_RING_RXD_RTH_BUCKET_GET(rxdp->control_0);
+	rxd_info->rth_it_hit =
+		(u32)VXGE_HW_RING_RXD_RTH_IT_HIT_GET(rxdp->control_0);
+	rxd_info->rth_spdm_hit =
+		(u32)VXGE_HW_RING_RXD_RTH_SPDM_HIT_GET(rxdp->control_0);
+	rxd_info->rth_hash_type =
+		(u32)VXGE_HW_RING_RXD_RTH_HASH_TYPE_GET(rxdp->control_0);
+	rxd_info->rth_value =
+		(u32)VXGE_HW_RING_RXD_1_RTH_HASH_VAL_GET(rxdp->control_1);
+}
+
+/**
+ * vxge_hw_ring_rxd_private_get - Get driver private per-descriptor data
+ *                      of 1b mode 3b mode ring.
+ * @rxdh: Descriptor handle.
+ *
+ * Returns: private driver	info associated	with the descriptor.
+ * driver requests	per-descriptor space via vxge_hw_ring_attr.
+ *
+ */
+static inline void *vxge_hw_ring_rxd_private_get(void *rxdh)
+{
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+	return (void *)(size_t)rxdp->host_control;
+}
+
+/**
+ * vxge_hw_fifo_txdl_cksum_set_bits - Offload checksum.
+ * @txdlh: Descriptor handle.
+ * @cksum_bits: Specifies which checksums are to be offloaded: IPv4,
+ *              and/or TCP and/or UDP.
+ *
+ * Ask Titan to calculate IPv4 & transport checksums for _this_ transmit
+ * descriptor.
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_mss_set(), vxge_hw_fifo_txdl_buffer_set_aligned(),
+ * and vxge_hw_fifo_txdl_buffer_set().
+ * All these APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+static inline void vxge_hw_fifo_txdl_cksum_set_bits(void *txdlh, u64 cksum_bits)
+{
+	struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+	txdp->control_1 |= cksum_bits;
+}
+
+/**
+ * vxge_hw_fifo_txdl_mss_set - Set MSS.
+ * @txdlh: Descriptor handle.
+ * @mss: MSS size for _this_ TCP connection. Passed by TCP stack down to the
+ *       driver, which in turn inserts the MSS into the @txdlh.
+ *
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_buffer_set(), vxge_hw_fifo_txdl_buffer_set_aligned(),
+ * and vxge_hw_fifo_txdl_cksum_set_bits().
+ * All these APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+static inline void vxge_hw_fifo_txdl_mss_set(void *txdlh, int mss)
+{
+	struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+
+	txdp->control_0 |= VXGE_HW_FIFO_TXD_LSO_EN;
+	txdp->control_0 |= VXGE_HW_FIFO_TXD_LSO_MSS(mss);
+}
+
+/**
+ * vxge_hw_fifo_txdl_vlan_set - Set VLAN tag.
+ * @txdlh: Descriptor handle.
+ * @vlan_tag: 16bit VLAN tag.
+ *
+ * Insert VLAN tag into specified transmit descriptor.
+ * The actual insertion of the tag into outgoing frame is done by the hardware.
+ */
+static inline void vxge_hw_fifo_txdl_vlan_set(void *txdlh, u16 vlan_tag)
+{
+	struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+
+	txdp->control_1 |= VXGE_HW_FIFO_TXD_VLAN_ENABLE;
+	txdp->control_1 |= VXGE_HW_FIFO_TXD_VLAN_TAG(vlan_tag);
+}
+
+/**
+ * vxge_hw_fifo_txdl_private_get - Retrieve per-descriptor private data.
+ * @txdlh: Descriptor handle.
+ *
+ * Retrieve per-descriptor private data.
+ * Note that driver requests per-descriptor space via
+ * struct vxge_hw_fifo_attr passed to
+ * vxge_hw_vpath_open().
+ *
+ * Returns: private driver data associated with the descriptor.
+ */
+static inline void *vxge_hw_fifo_txdl_private_get(void *txdlh)
+{
+	struct vxge_hw_fifo_txd *txdp  = (struct vxge_hw_fifo_txd *)txdlh;
+
+	return (void *)(size_t)txdp->host_control;
+}
+
+/**
+ * struct vxge_hw_ring_attr - Ring open "template".
+ * @callback: Ring completion callback. HW invokes the callback when there
+ *            are new completions on that ring. In many implementations
+ *            the @callback executes in the hw interrupt context.
+ * @rxd_init: Ring's descriptor-initialize callback.
+ *            See vxge_hw_ring_rxd_init_f{}.
+ *            If not NULL, HW invokes the callback when opening
+ *            the ring.
+ * @rxd_term: Ring's descriptor-terminate callback. If not NULL,
+ *          HW invokes the callback when closing the corresponding ring.
+ *          See also vxge_hw_ring_rxd_term_f{}.
+ * @userdata: User-defined "context" of _that_ ring. Passed back to the
+ *            user as one of the @callback, @rxd_init, and @rxd_term arguments.
+ * @per_rxd_space: If specified (i.e., greater than zero): extra space
+ *              reserved by HW per each receive descriptor.
+ *              Can be used to store
+ *              and retrieve on completion, information specific
+ *              to the driver.
+ *
+ * Ring open "template". User fills the structure with ring
+ * attributes and passes it to vxge_hw_vpath_open().
+ */
+struct vxge_hw_ring_attr {
+	enum vxge_hw_status (*callback)(
+			struct __vxge_hw_ring *ringh,
+			void *rxdh,
+			u8 t_code,
+			void *userdata);
+
+	enum vxge_hw_status (*rxd_init)(
+			void *rxdh,
+			void *userdata);
+
+	void (*rxd_term)(
+			void *rxdh,
+			enum vxge_hw_rxd_state state,
+			void *userdata);
+
+	void		*userdata;
+	u32		per_rxd_space;
+};
+
+/**
+ * function vxge_hw_fifo_callback_f - FIFO callback.
+ * @vpath_handle: Virtual path whose Fifo "containing" 1 or more completed
+ *             descriptors.
+ * @txdlh: First completed descriptor.
+ * @txdl_priv: Pointer to per txdl space allocated
+ * @t_code: Transfer code, as per Titan User Guide.
+ *          Returned by HW.
+ * @host_control: Opaque 64bit data stored by driver inside the Titan
+ *            descriptor prior to posting the latter on the fifo
+ *            via vxge_hw_fifo_txdl_post(). The @host_control is returned
+ *            as is to the driver with each completed descriptor.
+ * @userdata: Opaque per-fifo data specified at fifo open
+ *            time, via vxge_hw_vpath_open().
+ *
+ * Fifo completion callback (type declaration). A single per-fifo
+ * callback is specified at fifo open time, via
+ * vxge_hw_vpath_open(). Typically gets called as part of the processing
+ * of the Interrupt Service Routine.
+ *
+ * Fifo callback gets called by HW if, and only if, there is at least
+ * one new completion on a given fifo. Upon processing the first @txdlh driver
+ * is _supposed_ to continue consuming completions using:
+ *    - vxge_hw_fifo_txdl_next_completed()
+ *
+ * Note that failure to process new completions in a timely fashion
+ * leads to VXGE_HW_INF_OUT_OF_DESCRIPTORS condition.
+ *
+ * Non-zero @t_code means failure to process transmit descriptor.
+ *
+ * In the "transmit" case the failure could happen, for instance, when the
+ * link is down, in which case Titan completes the descriptor because it
+ * is not able to send the data out.
+ *
+ * For details please refer to Titan User Guide.
+ *
+ * See also: vxge_hw_fifo_txdl_next_completed(), vxge_hw_fifo_txdl_term_f{}.
+ */
+/**
+ * function vxge_hw_fifo_txdl_term_f - Terminate descriptor callback.
+ * @txdlh: First completed descriptor.
+ * @txdl_priv: Pointer to per txdl space allocated
+ * @state: One of the enum vxge_hw_txdl_state{} enumerated states.
+ * @userdata: Per-fifo user data (a.k.a. context) specified at
+ * fifo open time, via vxge_hw_vpath_open().
+ *
+ * Terminate descriptor callback. Unless NULL is specified in the
+ * struct vxge_hw_fifo_attr{} structure passed to vxge_hw_vpath_open()),
+ * HW invokes the callback as part of closing fifo, prior to
+ * de-allocating the ring and associated data structures
+ * (including descriptors).
+ * driver should utilize the callback to (for instance) unmap
+ * and free DMA data buffers associated with the posted (state =
+ * VXGE_HW_TXDL_STATE_POSTED) descriptors,
+ * as well as other relevant cleanup functions.
+ *
+ * See also: struct vxge_hw_fifo_attr{}
+ */
+/**
+ * struct vxge_hw_fifo_attr - Fifo open "template".
+ * @callback: Fifo completion callback. HW invokes the callback when there
+ *            are new completions on that fifo. In many implementations
+ *            the @callback executes in the hw interrupt context.
+ * @txdl_term: Fifo's descriptor-terminate callback. If not NULL,
+ *          HW invokes the callback when closing the corresponding fifo.
+ *          See also vxge_hw_fifo_txdl_term_f{}.
+ * @userdata: User-defined "context" of _that_ fifo. Passed back to the
+ *            user as one of the @callback, and @txdl_term arguments.
+ * @per_txdl_space: If specified (i.e., greater than zero): extra space
+ *              reserved by HW per each transmit descriptor. Can be used to
+ *              store, and retrieve on completion, information specific
+ *              to the driver.
+ *
+ * Fifo open "template". User fills the structure with fifo
+ * attributes and passes it to vxge_hw_vpath_open().
+ */
+struct vxge_hw_fifo_attr {
+
+	enum vxge_hw_status (*callback)(
+			struct __vxge_hw_fifo *fifo_handle,
+			void *txdlh,
+			enum vxge_hw_fifo_tcode t_code,
+			void *userdata,
+			void **skb_ptr);
+
+	void (*txdl_term)(
+			void *txdlh,
+			enum vxge_hw_txdl_state state,
+			void *userdata);
+
+	void		*userdata;
+	u32		per_txdl_space;
+};
+
+/**
+ * struct vxge_hw_vpath_attr - Attributes of virtual path
+ * @vp_id: Identifier of Virtual Path
+ * @ring_attr: Attributes of ring for non-offload receive
+ * @fifo_attr: Attributes of fifo for non-offload transmit
+ *
+ * Attributes of virtual path.  This structure is passed as parameter
+ * to the vxge_hw_vpath_open() routine to set the attributes of ring and fifo.
+ */
+struct vxge_hw_vpath_attr {
+	u32				vp_id;
+	struct vxge_hw_ring_attr	ring_attr;
+	struct vxge_hw_fifo_attr	fifo_attr;
+};
+
+enum vxge_hw_status
+__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
+			struct __vxge_hw_blockpool  *blockpool,
+			u32 pool_size,
+			u32 pool_max);
+
+void
+__vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool  *blockpool);
+
+struct __vxge_hw_blockpool_entry *
+__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *hldev,
+			u32 size);
+
+void
+__vxge_hw_blockpool_block_free(struct __vxge_hw_device *hldev,
+			struct __vxge_hw_blockpool_entry *entry);
+
+void *
+__vxge_hw_blockpool_malloc(struct __vxge_hw_device *hldev,
+			u32 size,
+			struct vxge_hw_mempool_dma *dma_object);
+
+void
+__vxge_hw_blockpool_free(struct __vxge_hw_device *hldev,
+			void *memblock,
+			u32 size,
+			struct vxge_hw_mempool_dma *dma_object);
+
+enum vxge_hw_status
+__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config);
+
+enum vxge_hw_status
+__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config);
+
+enum vxge_hw_status
+vxge_hw_mgmt_device_config(struct __vxge_hw_device *devh,
+		struct vxge_hw_device_config	*dev_config, int size);
+
+enum vxge_hw_status __devinit vxge_hw_device_hw_info_get(
+	void __iomem *bar0,
+	struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status
+__vxge_hw_vpath_fw_ver_get(
+	u32	vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status
+__vxge_hw_vpath_card_info_get(
+	u32 vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status __devinit vxge_hw_device_config_default_get(
+	struct vxge_hw_device_config *device_config);
+
+/**
+ * vxge_hw_device_link_state_get - Get link state.
+ * @devh: HW device handle.
+ *
+ * Get link state.
+ * Returns: link state.
+ */
+static inline
+enum vxge_hw_device_link_state vxge_hw_device_link_state_get(
+	struct __vxge_hw_device *devh)
+{
+	return devh->link_state;
+}
+
+void vxge_hw_device_terminate(struct __vxge_hw_device *devh);
+
+const u8 *
+vxge_hw_device_serial_number_get(struct __vxge_hw_device *devh);
+
+u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *devh);
+
+const u8 *
+vxge_hw_device_product_name_get(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status __devinit vxge_hw_device_initialize(
+	struct __vxge_hw_device **devh,
+	struct vxge_hw_device_attr *attr,
+	struct vxge_hw_device_config *device_config);
+
+enum vxge_hw_status vxge_hw_device_getpause_data(
+	 struct __vxge_hw_device *devh,
+	 u32 port,
+	 u32 *tx,
+	 u32 *rx);
+
+enum vxge_hw_status vxge_hw_device_setpause_data(
+	struct __vxge_hw_device *devh,
+	u32 port,
+	u32 tx,
+	u32 rx);
+
+static inline void *vxge_os_dma_malloc(struct pci_dev *pdev,
+			unsigned long size,
+			struct pci_dev **p_dmah,
+			struct pci_dev **p_dma_acch)
+{
+	gfp_t flags;
+	void *vaddr;
+	unsigned long misaligned = 0;
+	*p_dma_acch = *p_dmah = NULL;
+
+	if (in_interrupt())
+		flags = GFP_ATOMIC | GFP_DMA;
+	else
+		flags = GFP_KERNEL | GFP_DMA;
+
+	size += VXGE_CACHE_LINE_SIZE;
+
+	vaddr = kmalloc((size), flags);
+	if (vaddr == NULL)
+		return vaddr;
+	misaligned = (unsigned long)VXGE_ALIGN(*((u64 *)&vaddr),
+				VXGE_CACHE_LINE_SIZE);
+	*(unsigned long *)p_dma_acch = misaligned;
+	vaddr = (void *)((u8 *)vaddr + misaligned);
+	return vaddr;
+}
+
+extern void vxge_hw_blockpool_block_add(
+			struct __vxge_hw_device *devh,
+			void *block_addr,
+			u32 length,
+			struct pci_dev *dma_h,
+			struct pci_dev *acc_handle);
+
+static inline void vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh,
+					unsigned long size)
+{
+	gfp_t flags;
+	void *vaddr;
+
+	if (in_interrupt())
+		flags = GFP_ATOMIC | GFP_DMA;
+	else
+		flags = GFP_KERNEL | GFP_DMA;
+
+	vaddr = kmalloc((size), flags);
+
+	vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev);
+}
+
+static inline void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr,
+			struct pci_dev **p_dma_acch)
+{
+	unsigned long misaligned = *(unsigned long *)p_dma_acch;
+	u8 *tmp = (u8 *)vaddr;
+	tmp -= misaligned;
+	kfree((void *)tmp);
+}
+
+/*
+ * __vxge_hw_mempool_item_priv - will return pointer on per item private space
+ */
+static inline void*
+__vxge_hw_mempool_item_priv(
+	struct vxge_hw_mempool *mempool,
+	u32 memblock_idx,
+	void *item,
+	u32 *memblock_item_idx)
+{
+	ptrdiff_t offset;
+	void *memblock = mempool->memblocks_arr[memblock_idx];
+
+
+	offset = (u32)((u8 *)item - (u8 *)memblock);
+	vxge_assert(offset >= 0 && (u32)offset < mempool->memblock_size);
+
+	(*memblock_item_idx) = (u32) offset / mempool->item_size;
+	vxge_assert((*memblock_item_idx) < mempool->items_per_memblock);
+
+	return (u8 *)mempool->memblocks_priv_arr[memblock_idx] +
+			    (*memblock_item_idx) * mempool->items_priv_size;
+}
+
+enum vxge_hw_status
+__vxge_hw_mempool_grow(
+	struct vxge_hw_mempool *mempool,
+	u32 num_allocate,
+	u32 *num_allocated);
+
+struct vxge_hw_mempool*
+__vxge_hw_mempool_create(
+	struct __vxge_hw_device *devh,
+	u32 memblock_size,
+	u32 item_size,
+	u32 private_size,
+	u32 items_initial,
+	u32 items_max,
+	struct vxge_hw_mempool_cbs *mp_callback,
+	void *userdata);
+
+struct __vxge_hw_channel*
+__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
+			enum __vxge_hw_channel_type type, u32 length,
+			u32 per_dtr_space, void *userdata);
+
+void
+__vxge_hw_channel_free(
+	struct __vxge_hw_channel *channel);
+
+enum vxge_hw_status
+__vxge_hw_channel_initialize(
+	struct __vxge_hw_channel *channel);
+
+enum vxge_hw_status
+__vxge_hw_channel_reset(
+	struct __vxge_hw_channel *channel);
+
+/*
+ * __vxge_hw_fifo_txdl_priv - Return the max fragments allocated
+ * for the fifo.
+ * @fifo: Fifo
+ * @txdp: Poniter to a TxD
+ */
+static inline struct __vxge_hw_fifo_txdl_priv *
+__vxge_hw_fifo_txdl_priv(
+	struct __vxge_hw_fifo *fifo,
+	struct vxge_hw_fifo_txd *txdp)
+{
+	return (struct __vxge_hw_fifo_txdl_priv *)
+			(((char *)((ulong)txdp->host_control)) +
+				fifo->per_txdl_space);
+}
+
+enum vxge_hw_status vxge_hw_vpath_open(
+	struct __vxge_hw_device *devh,
+	struct vxge_hw_vpath_attr *attr,
+	struct __vxge_hw_vpath_handle **vpath_handle);
+
+enum vxge_hw_status
+__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog);
+
+enum vxge_hw_status vxge_hw_vpath_close(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+vxge_hw_vpath_reset(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+vxge_hw_vpath_recover_from_reset(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+void
+vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp);
+
+enum vxge_hw_status
+vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status vxge_hw_vpath_mtu_set(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u32 new_mtu);
+
+enum vxge_hw_status vxge_hw_vpath_stats_enable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+__vxge_hw_vpath_stats_access(
+	struct __vxge_hw_virtualpath	*vpath,
+	u32			operation,
+	u32			offset,
+	u64			*stat);
+
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_tx_stats_get(
+	struct __vxge_hw_virtualpath	*vpath,
+	struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats);
+
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_rx_stats_get(
+	struct __vxge_hw_virtualpath	*vpath,
+	struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats);
+
+enum vxge_hw_status
+__vxge_hw_vpath_stats_get(
+	struct __vxge_hw_virtualpath *vpath,
+	struct vxge_hw_vpath_stats_hw_info *hw_stats);
+
+void
+vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp);
+
+enum vxge_hw_status
+__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config);
+
+void
+__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg);
+
+enum vxge_hw_status
+__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+enum vxge_hw_status
+__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+enum vxge_hw_status
+__vxge_hw_device_register_poll(
+	void __iomem	*reg,
+	u64 mask, u32 max_millis);
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+	u64 ret = 0;
+	ret = readl(addr + 4);
+	ret <<= 32;
+	ret |= readl(addr);
+
+	return ret;
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+	writel((u32) (val), addr);
+	writel((u32) (val >> 32), (addr + 4));
+}
+#endif
+
+static inline void __vxge_hw_pio_mem_write32_upper(u32 val, void __iomem *addr)
+{
+	writel(val, addr + 4);
+}
+
+static inline void __vxge_hw_pio_mem_write32_lower(u32 val, void __iomem *addr)
+{
+	writel(val, addr);
+}
+
+static inline enum vxge_hw_status
+__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr,
+			  u64 mask, u32 max_millis)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	__vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr);
+	wmb();
+	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr);
+	wmb();
+
+	status = __vxge_hw_device_register_poll(addr, mask, max_millis);
+	return status;
+}
+
+struct vxge_hw_toc_reg __iomem *
+__vxge_hw_device_toc_get(void __iomem *bar0);
+
+enum vxge_hw_status
+__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev);
+
+void
+__vxge_hw_device_id_get(struct __vxge_hw_device *hldev);
+
+void
+__vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+vxge_hw_device_flick_link_led(struct __vxge_hw_device *devh, u64 on_off);
+
+enum vxge_hw_status
+__vxge_hw_device_initialize(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_vpath_pci_read(
+	struct __vxge_hw_virtualpath	*vpath,
+	u32			phy_func_0,
+	u32			offset,
+	u32			*val);
+
+enum vxge_hw_status
+__vxge_hw_vpath_addr_get(
+	u32 vp_id,
+	struct vxge_hw_vpath_reg __iomem *vpath_reg,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN]);
+
+u32
+__vxge_hw_vpath_func_id_get(
+	u32 vp_id, struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg);
+
+enum vxge_hw_status
+__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath);
+
+/**
+ * vxge_debug
+ * @level: level of debug verbosity.
+ * @mask: mask for the debug
+ * @buf: Circular buffer for tracing
+ * @fmt: printf like format string
+ *
+ * Provides logging facilities. Can be customized on per-module
+ * basis or/and with debug levels. Input parameters, except
+ * module and level, are the same as posix printf. This function
+ * may be compiled out if DEBUG macro was never defined.
+ * See also: enum vxge_debug_level{}.
+ */
+
+#define vxge_trace_aux(level, mask, fmt, ...) \
+{\
+		vxge_os_vaprintf(level, mask, fmt, __VA_ARGS__);\
+}
+
+#define vxge_debug(module, level, mask, fmt, ...) { \
+if ((level >= VXGE_TRACE && ((module & VXGE_DEBUG_TRACE_MASK) == module)) || \
+	(level >= VXGE_ERR && ((module & VXGE_DEBUG_ERR_MASK) == module))) {\
+	if ((mask & VXGE_DEBUG_MASK) == mask)\
+		vxge_trace_aux(level, mask, fmt, __VA_ARGS__); \
+} \
+}
+
+#if (VXGE_COMPONENT_LL & VXGE_DEBUG_MODULE_MASK)
+#define vxge_debug_ll(level, mask, fmt, ...) \
+{\
+	vxge_debug(VXGE_COMPONENT_LL, level, mask, fmt, __VA_ARGS__);\
+}
+
+#else
+#define vxge_debug_ll(level, mask, fmt, ...)
+#endif
+
+enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
+			struct __vxge_hw_vpath_handle **vpath_handles,
+			u32 vpath_count,
+			u8 *mtable,
+			u8 *itable,
+			u32 itable_size);
+
+enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	enum vxge_hw_rth_algoritms algorithm,
+	struct vxge_hw_rth_hash_types *hash_type,
+	u16 bucket_size);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-ethtool.c linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-ethtool.c
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-ethtool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-ethtool.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1148 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-ethtool.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                 Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include<linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+
+#include "vxge-ethtool.h"
+
+/**
+ * vxge_ethtool_sset - Sets different link parameters.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool to set
+ * link information.
+ *
+ * The function sets different link parameters provided by the user onto
+ * the NIC.
+ * Return value:
+ * 0 on success.
+ */
+
+static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
+{
+	/* We currently only support 10Gb/FULL */
+	if ((info->autoneg == AUTONEG_ENABLE) ||
+	    (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * vxge_ethtool_gset - Return link specific information.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool
+ * to return link information.
+ *
+ * Returns link specific information like speed, duplex etc.. to ethtool.
+ * Return value :
+ * return 0 on success.
+ */
+static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
+{
+	info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
+	info->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
+	info->port = PORT_FIBRE;
+
+	info->transceiver = XCVR_EXTERNAL;
+
+	if (netif_carrier_ok(dev)) {
+		info->speed = SPEED_10000;
+		info->duplex = DUPLEX_FULL;
+	} else {
+		info->speed = -1;
+		info->duplex = -1;
+	}
+
+	info->autoneg = AUTONEG_DISABLE;
+	return 0;
+}
+
+/**
+ * vxge_ethtool_gdrvinfo - Returns driver specific information.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool to
+ * return driver information.
+ *
+ * Returns driver specefic information like name, version etc.. to ethtool.
+ */
+static void vxge_ethtool_gdrvinfo(struct net_device *dev,
+			struct ethtool_drvinfo *info)
+{
+	struct vxgedev *vdev;
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME));
+	strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
+	strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN);
+	strlcpy(info->bus_info, pci_name(vdev->pdev), sizeof(info->bus_info));
+	info->regdump_len = sizeof(struct vxge_hw_vpath_reg)
+				* vdev->no_of_vpath;
+
+	info->n_stats = STAT_LEN;
+}
+
+/**
+ * vxge_ethtool_gregs - dumps the entire space of Titan into the buffer.
+ * @dev: device pointer.
+ * @regs: pointer to the structure with parameters given by ethtool for
+ * dumping the registers.
+ * @reg_space: The input argumnet into which all the registers are dumped.
+ *
+ * Dumps the vpath register space of Titan NIC into the user given
+ * buffer area.
+ */
+static void vxge_ethtool_gregs(struct net_device *dev,
+			struct ethtool_regs *regs, void *space)
+{
+	int index, offset;
+	enum vxge_hw_status status;
+	u64 reg;
+	u8 *reg_space = (u8 *) space;
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device *)
+					pci_get_drvdata(vdev->pdev);
+
+	regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
+	regs->version = vdev->pdev->subsystem_device;
+	for (index = 0; index < vdev->no_of_vpath; index++) {
+		for (offset = 0; offset < sizeof(struct vxge_hw_vpath_reg);
+				offset += 8) {
+			status = vxge_hw_mgmt_reg_read(hldev,
+					vxge_hw_mgmt_reg_type_vpath,
+					vdev->vpaths[index].device_id,
+					offset, &reg);
+			if (status != VXGE_HW_OK) {
+				vxge_debug_init(VXGE_ERR,
+					"%s:%d Getting reg dump Failed",
+						__func__, __LINE__);
+				return;
+			}
+
+			memcpy((reg_space + offset), &reg, 8);
+		}
+	}
+}
+
+/**
+ * vxge_ethtool_idnic - To physically identify the nic on the system.
+ * @dev : device pointer.
+ * @id : pointer to the structure with identification parameters given by
+ * ethtool.
+ *
+ * Used to physically identify the NIC on the system.
+ * The Link LED will blink for a time specified by the user.
+ * Return value:
+ * 0 on success
+ */
+static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device  *)
+			pci_get_drvdata(vdev->pdev);
+
+	vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
+	msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
+	vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+
+	return 0;
+}
+
+/**
+ * vxge_ethtool_getpause_data - Pause frame frame generation and reception.
+ * @dev : device pointer.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
+ * Description:
+ * Returns the Pause frame generation and reception capability of the NIC.
+ * Return value:
+ *  void
+ */
+static void vxge_ethtool_getpause_data(struct net_device *dev,
+					struct ethtool_pauseparam *ep)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device  *)
+			pci_get_drvdata(vdev->pdev);
+
+	vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause);
+}
+
+/**
+ * vxge_ethtool_setpause_data -  set/reset pause frame generation.
+ * @dev : device pointer.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
+ * Description:
+ * It can be used to set or reset Pause frame generation or reception
+ * support of the NIC.
+ * Return value:
+ * int, returns 0 on Success
+ */
+static int vxge_ethtool_setpause_data(struct net_device *dev,
+					struct ethtool_pauseparam *ep)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device  *)
+			pci_get_drvdata(vdev->pdev);
+
+	vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause);
+
+	vdev->config.tx_pause_enable = ep->tx_pause;
+	vdev->config.rx_pause_enable = ep->rx_pause;
+
+	return 0;
+}
+
+static void vxge_get_ethtool_stats(struct net_device *dev,
+				   struct ethtool_stats *estats, u64 *tmp_stats)
+{
+	int j, k;
+	enum vxge_hw_status status;
+	enum vxge_hw_status swstatus;
+	struct vxge_vpath *vpath = NULL;
+
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	struct __vxge_hw_device  *hldev = vdev->devh;
+	struct vxge_hw_xmac_stats *xmac_stats;
+	struct vxge_hw_device_stats_sw_info *sw_stats;
+	struct vxge_hw_device_stats_hw_info *hw_stats;
+
+	u64 *ptr = tmp_stats;
+
+	memset(tmp_stats, 0,
+		vxge_ethtool_get_sset_count(dev, ETH_SS_STATS) * sizeof(u64));
+
+	xmac_stats = kzalloc(sizeof(struct vxge_hw_xmac_stats), GFP_KERNEL);
+	if (xmac_stats == NULL) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : %d Memory Allocation failed for xmac_stats",
+				 __func__, __LINE__);
+		return;
+	}
+
+	sw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_sw_info),
+				GFP_KERNEL);
+	if (sw_stats == NULL) {
+		kfree(xmac_stats);
+		vxge_debug_init(VXGE_ERR,
+			"%s : %d Memory Allocation failed for sw_stats",
+			__func__, __LINE__);
+		return;
+	}
+
+	hw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_hw_info),
+				GFP_KERNEL);
+	if (hw_stats == NULL) {
+		kfree(xmac_stats);
+		kfree(sw_stats);
+		vxge_debug_init(VXGE_ERR,
+			"%s : %d Memory Allocation failed for hw_stats",
+			__func__, __LINE__);
+		return;
+	}
+
+	*ptr++ = 0;
+	status = vxge_hw_device_xmac_stats_get(hldev, xmac_stats);
+	if (status != VXGE_HW_OK) {
+		if (status != VXGE_HW_ERR_PRIVILAGED_OPEARATION) {
+			vxge_debug_init(VXGE_ERR,
+				"%s : %d Failure in getting xmac stats",
+				__func__, __LINE__);
+		}
+	}
+	swstatus = vxge_hw_driver_stats_get(hldev, sw_stats);
+	if (swstatus != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : %d Failure in getting sw stats",
+			__func__, __LINE__);
+	}
+
+	status = vxge_hw_device_stats_get(hldev, hw_stats);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : %d hw_stats_get error", __func__, __LINE__);
+	}
+
+	for (k = 0; k < vdev->no_of_vpath; k++) {
+		struct vxge_hw_vpath_stats_hw_info *vpath_info;
+
+		vpath = &vdev->vpaths[k];
+		j = vpath->device_id;
+		vpath_info = hw_stats->vpath_info[j];
+		if (!vpath_info) {
+			memset(ptr, 0, (VXGE_HW_VPATH_TX_STATS_LEN +
+				VXGE_HW_VPATH_RX_STATS_LEN) * sizeof(u64));
+			ptr += (VXGE_HW_VPATH_TX_STATS_LEN +
+				VXGE_HW_VPATH_RX_STATS_LEN);
+			continue;
+		}
+
+		*ptr++ = vpath_info->tx_stats.tx_ttl_eth_frms;
+		*ptr++ = vpath_info->tx_stats.tx_ttl_eth_octets;
+		*ptr++ = vpath_info->tx_stats.tx_data_octets;
+		*ptr++ = vpath_info->tx_stats.tx_mcast_frms;
+		*ptr++ = vpath_info->tx_stats.tx_bcast_frms;
+		*ptr++ = vpath_info->tx_stats.tx_ucast_frms;
+		*ptr++ = vpath_info->tx_stats.tx_tagged_frms;
+		*ptr++ = vpath_info->tx_stats.tx_vld_ip;
+		*ptr++ = vpath_info->tx_stats.tx_vld_ip_octets;
+		*ptr++ = vpath_info->tx_stats.tx_icmp;
+		*ptr++ = vpath_info->tx_stats.tx_tcp;
+		*ptr++ = vpath_info->tx_stats.tx_rst_tcp;
+		*ptr++ = vpath_info->tx_stats.tx_udp;
+		*ptr++ = vpath_info->tx_stats.tx_unknown_protocol;
+		*ptr++ = vpath_info->tx_stats.tx_lost_ip;
+		*ptr++ = vpath_info->tx_stats.tx_parse_error;
+		*ptr++ = vpath_info->tx_stats.tx_tcp_offload;
+		*ptr++ = vpath_info->tx_stats.tx_retx_tcp_offload;
+		*ptr++ = vpath_info->tx_stats.tx_lost_ip_offload;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_eth_frms;
+		*ptr++ = vpath_info->rx_stats.rx_vld_frms;
+		*ptr++ = vpath_info->rx_stats.rx_offload_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_eth_octets;
+		*ptr++ = vpath_info->rx_stats.rx_data_octets;
+		*ptr++ = vpath_info->rx_stats.rx_offload_octets;
+		*ptr++ = vpath_info->rx_stats.rx_vld_mcast_frms;
+		*ptr++ = vpath_info->rx_stats.rx_vld_bcast_frms;
+		*ptr++ = vpath_info->rx_stats.rx_accepted_ucast_frms;
+		*ptr++ = vpath_info->rx_stats.rx_accepted_nucast_frms;
+		*ptr++ = vpath_info->rx_stats.rx_tagged_frms;
+		*ptr++ = vpath_info->rx_stats.rx_long_frms;
+		*ptr++ = vpath_info->rx_stats.rx_usized_frms;
+		*ptr++ = vpath_info->rx_stats.rx_osized_frms;
+		*ptr++ = vpath_info->rx_stats.rx_frag_frms;
+		*ptr++ = vpath_info->rx_stats.rx_jabber_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_64_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_65_127_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_128_255_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_256_511_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_512_1023_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_1024_1518_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_1519_4095_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_4096_8191_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_8192_max_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ttl_gt_max_frms;
+		*ptr++ = vpath_info->rx_stats.rx_ip;
+		*ptr++ = vpath_info->rx_stats.rx_accepted_ip;
+		*ptr++ = vpath_info->rx_stats.rx_ip_octets;
+		*ptr++ = vpath_info->rx_stats.rx_err_ip;
+		*ptr++ = vpath_info->rx_stats.rx_icmp;
+		*ptr++ = vpath_info->rx_stats.rx_tcp;
+		*ptr++ = vpath_info->rx_stats.rx_udp;
+		*ptr++ = vpath_info->rx_stats.rx_err_tcp;
+		*ptr++ = vpath_info->rx_stats.rx_lost_frms;
+		*ptr++ = vpath_info->rx_stats.rx_lost_ip;
+		*ptr++ = vpath_info->rx_stats.rx_lost_ip_offload;
+		*ptr++ = vpath_info->rx_stats.rx_various_discard;
+		*ptr++ = vpath_info->rx_stats.rx_sleep_discard;
+		*ptr++ = vpath_info->rx_stats.rx_red_discard;
+		*ptr++ = vpath_info->rx_stats.rx_queue_full_discard;
+		*ptr++ = vpath_info->rx_stats.rx_mpa_ok_frms;
+	}
+	*ptr++ = 0;
+	for (k = 0; k < vdev->max_config_port; k++) {
+		*ptr++ = xmac_stats->aggr_stats[k].tx_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].tx_data_octets;
+		*ptr++ = xmac_stats->aggr_stats[k].tx_mcast_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].tx_bcast_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].tx_discarded_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].tx_errored_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_data_octets;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_mcast_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_bcast_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_discarded_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_errored_frms;
+		*ptr++ = xmac_stats->aggr_stats[k].rx_unknown_slow_proto_frms;
+	}
+	*ptr++ = 0;
+	for (k = 0; k < vdev->max_config_port; k++) {
+		*ptr++ = xmac_stats->port_stats[k].tx_ttl_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_ttl_octets;
+		*ptr++ = xmac_stats->port_stats[k].tx_data_octets;
+		*ptr++ = xmac_stats->port_stats[k].tx_mcast_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_bcast_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_ucast_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_tagged_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_vld_ip;
+		*ptr++ = xmac_stats->port_stats[k].tx_vld_ip_octets;
+		*ptr++ = xmac_stats->port_stats[k].tx_icmp;
+		*ptr++ = xmac_stats->port_stats[k].tx_tcp;
+		*ptr++ = xmac_stats->port_stats[k].tx_rst_tcp;
+		*ptr++ = xmac_stats->port_stats[k].tx_udp;
+		*ptr++ = xmac_stats->port_stats[k].tx_parse_error;
+		*ptr++ = xmac_stats->port_stats[k].tx_unknown_protocol;
+		*ptr++ = xmac_stats->port_stats[k].tx_pause_ctrl_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_marker_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_lacpdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_drop_ip;
+		*ptr++ = xmac_stats->port_stats[k].tx_marker_resp_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_char2_match;
+		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_char1_match;
+		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_column2_match;
+		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_column1_match;
+		*ptr++ = xmac_stats->port_stats[k].tx_any_err_frms;
+		*ptr++ = xmac_stats->port_stats[k].tx_drop_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_vld_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_offload_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_octets;
+		*ptr++ = xmac_stats->port_stats[k].rx_data_octets;
+		*ptr++ = xmac_stats->port_stats[k].rx_offload_octets;
+		*ptr++ = xmac_stats->port_stats[k].rx_vld_mcast_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_vld_bcast_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_accepted_ucast_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_accepted_nucast_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_tagged_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_long_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_usized_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_osized_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_frag_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_jabber_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_64_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_65_127_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_128_255_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_256_511_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_512_1023_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_1024_1518_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_1519_4095_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_4096_8191_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_8192_max_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ttl_gt_max_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_ip;
+		*ptr++ = xmac_stats->port_stats[k].rx_accepted_ip;
+		*ptr++ = xmac_stats->port_stats[k].rx_ip_octets;
+		*ptr++ = xmac_stats->port_stats[k].rx_err_ip;
+		*ptr++ = xmac_stats->port_stats[k].rx_icmp;
+		*ptr++ = xmac_stats->port_stats[k].rx_tcp;
+		*ptr++ = xmac_stats->port_stats[k].rx_udp;
+		*ptr++ = xmac_stats->port_stats[k].rx_err_tcp;
+		*ptr++ = xmac_stats->port_stats[k].rx_pause_count;
+		*ptr++ = xmac_stats->port_stats[k].rx_pause_ctrl_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_unsup_ctrl_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_fcs_err_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_in_rng_len_err_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_out_rng_len_err_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_drop_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_discarded_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_drop_ip;
+		*ptr++ = xmac_stats->port_stats[k].rx_drop_udp;
+		*ptr++ = xmac_stats->port_stats[k].rx_marker_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_lacpdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_unknown_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_marker_resp_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_fcs_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_illegal_pdu_frms;
+		*ptr++ = xmac_stats->port_stats[k].rx_switch_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_len_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_rpa_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_l2_mgmt_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_rts_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_trash_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_buff_full_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_red_discard;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_ctrl_err_cnt;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_data_err_cnt;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_char1_match;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_err_sym;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_column1_match;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_char2_match;
+		*ptr++ = xmac_stats->port_stats[k].rx_local_fault;
+		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_column2_match;
+		*ptr++ = xmac_stats->port_stats[k].rx_jettison;
+		*ptr++ = xmac_stats->port_stats[k].rx_remote_fault;
+	}
+
+	*ptr++ = 0;
+	for (k = 0; k < vdev->no_of_vpath; k++) {
+		struct vxge_hw_vpath_stats_sw_info *vpath_info;
+
+		vpath = &vdev->vpaths[k];
+		j = vpath->device_id;
+		vpath_info = (struct vxge_hw_vpath_stats_sw_info *)
+				&sw_stats->vpath_info[j];
+		*ptr++ = vpath_info->soft_reset_cnt;
+		*ptr++ = vpath_info->error_stats.unknown_alarms;
+		*ptr++ = vpath_info->error_stats.network_sustained_fault;
+		*ptr++ = vpath_info->error_stats.network_sustained_ok;
+		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_overwrite;
+		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_poison;
+		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_dma_error;
+		*ptr++ = vpath_info->error_stats.dblgen_fifo0_overflow;
+		*ptr++ = vpath_info->error_stats.statsb_pif_chain_error;
+		*ptr++ = vpath_info->error_stats.statsb_drop_timeout;
+		*ptr++ = vpath_info->error_stats.target_illegal_access;
+		*ptr++ = vpath_info->error_stats.ini_serr_det;
+		*ptr++ = vpath_info->error_stats.prc_ring_bumps;
+		*ptr++ = vpath_info->error_stats.prc_rxdcm_sc_err;
+		*ptr++ = vpath_info->error_stats.prc_rxdcm_sc_abort;
+		*ptr++ = vpath_info->error_stats.prc_quanta_size_err;
+		*ptr++ = vpath_info->ring_stats.common_stats.full_cnt;
+		*ptr++ = vpath_info->ring_stats.common_stats.usage_cnt;
+		*ptr++ = vpath_info->ring_stats.common_stats.usage_max;
+		*ptr++ = vpath_info->ring_stats.common_stats.
+					reserve_free_swaps_cnt;
+		*ptr++ = vpath_info->ring_stats.common_stats.total_compl_cnt;
+		for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+			*ptr++ = vpath_info->ring_stats.rxd_t_code_err_cnt[j];
+		*ptr++ = vpath_info->fifo_stats.common_stats.full_cnt;
+		*ptr++ = vpath_info->fifo_stats.common_stats.usage_cnt;
+		*ptr++ = vpath_info->fifo_stats.common_stats.usage_max;
+		*ptr++ = vpath_info->fifo_stats.common_stats.
+						reserve_free_swaps_cnt;
+		*ptr++ = vpath_info->fifo_stats.common_stats.total_compl_cnt;
+		*ptr++ = vpath_info->fifo_stats.total_posts;
+		*ptr++ = vpath_info->fifo_stats.total_buffers;
+		for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+			*ptr++ = vpath_info->fifo_stats.txd_t_code_err_cnt[j];
+	}
+
+	*ptr++ = 0;
+	for (k = 0; k < vdev->no_of_vpath; k++) {
+		struct vxge_hw_vpath_stats_hw_info *vpath_info;
+		vpath = &vdev->vpaths[k];
+		j = vpath->device_id;
+		vpath_info = hw_stats->vpath_info[j];
+		if (!vpath_info) {
+			memset(ptr, 0, VXGE_HW_VPATH_STATS_LEN * sizeof(u64));
+			ptr += VXGE_HW_VPATH_STATS_LEN;
+			continue;
+		}
+		*ptr++ = vpath_info->ini_num_mwr_sent;
+		*ptr++ = vpath_info->ini_num_mrd_sent;
+		*ptr++ = vpath_info->ini_num_cpl_rcvd;
+		*ptr++ = vpath_info->ini_num_mwr_byte_sent;
+		*ptr++ = vpath_info->ini_num_cpl_byte_rcvd;
+		*ptr++ = vpath_info->wrcrdtarb_xoff;
+		*ptr++ = vpath_info->rdcrdtarb_xoff;
+		*ptr++ = vpath_info->vpath_genstats_count0;
+		*ptr++ = vpath_info->vpath_genstats_count1;
+		*ptr++ = vpath_info->vpath_genstats_count2;
+		*ptr++ = vpath_info->vpath_genstats_count3;
+		*ptr++ = vpath_info->vpath_genstats_count4;
+		*ptr++ = vpath_info->vpath_genstats_count5;
+		*ptr++ = vpath_info->prog_event_vnum0;
+		*ptr++ = vpath_info->prog_event_vnum1;
+		*ptr++ = vpath_info->prog_event_vnum2;
+		*ptr++ = vpath_info->prog_event_vnum3;
+		*ptr++ = vpath_info->rx_multi_cast_frame_discard;
+		*ptr++ = vpath_info->rx_frm_transferred;
+		*ptr++ = vpath_info->rxd_returned;
+		*ptr++ = vpath_info->rx_mpa_len_fail_frms;
+		*ptr++ = vpath_info->rx_mpa_mrk_fail_frms;
+		*ptr++ = vpath_info->rx_mpa_crc_fail_frms;
+		*ptr++ = vpath_info->rx_permitted_frms;
+		*ptr++ = vpath_info->rx_vp_reset_discarded_frms;
+		*ptr++ = vpath_info->rx_wol_frms;
+		*ptr++ = vpath_info->tx_vp_reset_discarded_frms;
+	}
+
+	*ptr++ = 0;
+	*ptr++ = vdev->stats.vpaths_open;
+	*ptr++ = vdev->stats.vpath_open_fail;
+	*ptr++ = vdev->stats.link_up;
+	*ptr++ = vdev->stats.link_down;
+
+	for (k = 0; k < vdev->no_of_vpath; k++) {
+		*ptr += vdev->vpaths[k].fifo.stats.tx_frms;
+		*(ptr + 1) += vdev->vpaths[k].fifo.stats.tx_errors;
+		*(ptr + 2) += vdev->vpaths[k].fifo.stats.tx_bytes;
+		*(ptr + 3) += vdev->vpaths[k].fifo.stats.txd_not_free;
+		*(ptr + 4) += vdev->vpaths[k].fifo.stats.txd_out_of_desc;
+		*(ptr + 5) += vdev->vpaths[k].ring.stats.rx_frms;
+		*(ptr + 6) += vdev->vpaths[k].ring.stats.rx_errors;
+		*(ptr + 7) += vdev->vpaths[k].ring.stats.rx_bytes;
+		*(ptr + 8) += vdev->vpaths[k].ring.stats.rx_mcast;
+		*(ptr + 9) += vdev->vpaths[k].fifo.stats.pci_map_fail +
+				vdev->vpaths[k].ring.stats.pci_map_fail;
+		*(ptr + 10) += vdev->vpaths[k].ring.stats.skb_alloc_fail;
+	}
+
+	ptr += 12;
+
+	kfree(xmac_stats);
+	kfree(sw_stats);
+	kfree(hw_stats);
+}
+
+static void vxge_ethtool_get_strings(struct net_device *dev,
+			      u32 stringset, u8 *data)
+{
+	int stat_size = 0;
+	int i, j;
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	switch (stringset) {
+	case ETH_SS_STATS:
+		vxge_add_string("VPATH STATISTICS%s\t\t\t",
+			&stat_size, data, "");
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_add_string("tx_ttl_eth_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_ttl_eth_octects_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_data_octects_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_mcast_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_bcast_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_ucast_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_tagged_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_vld_ip_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_vld_ip_octects_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_icmp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_tcp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_rst_tcp_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_udp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_unknown_proto_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_lost_ip_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_parse_error_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_tcp_offload_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_retx_tcp_offload_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_lost_ip_offload_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_eth_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_vld_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_offload_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_eth_octects_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_data_octects_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_offload_octects_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_vld_mcast_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_vld_bcast_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_tagged_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_long_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_usized_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_osized_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_frag_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_jabber_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ip%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_accepted_ip_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_ip_octects_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_err_ip_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_icmp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_tcp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_udp_%d\t\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_err_tcp_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_lost_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_lost_ip_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_lost_ip_offload_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_various_discard_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_sleep_discard_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_red_discard_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_queue_full_discard_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_mpa_ok_frms_%d\t\t\t",
+					&stat_size, data, i);
+		}
+
+		vxge_add_string("\nAGGR STATISTICS%s\t\t\t\t",
+			&stat_size, data, "");
+		for (i = 0; i < vdev->max_config_port; i++) {
+			vxge_add_string("tx_frms_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_data_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_mcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_bcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_discarded_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_errored_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_frms_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_data_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_mcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_bcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_discarded_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_errored_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_unknown_slow_proto_frms_%d\t",
+				&stat_size, data, i);
+		}
+
+		vxge_add_string("\nPORT STATISTICS%s\t\t\t\t",
+			&stat_size, data, "");
+		for (i = 0; i < vdev->max_config_port; i++) {
+			vxge_add_string("tx_ttl_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_ttl_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_data_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_mcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_bcast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_ucast_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_tagged_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_vld_ip_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_vld_ip_octects_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_icmp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_tcp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_rst_tcp_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_udp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_parse_error_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_unknown_protocol_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_pause_ctrl_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_marker_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_lacpdu_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_drop_ip_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_marker_resp_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_xgmii_char2_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_xgmii_char1_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_xgmii_column2_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_xgmii_column1_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_any_err_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("tx_drop_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_vld_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_offload_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_data_octects_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_offload_octects_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_vld_mcast_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_vld_bcast_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_tagged_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_long_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_usized_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_osized_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_frag_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_jabber_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ip_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_accepted_ip_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_ip_octets_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_err_ip_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_icmp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_tcp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_udp_%d\t\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_err_tcp_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_pause_count_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_pause_ctrl_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_unsup_ctrl_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_fcs_err_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_in_rng_len_err_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_out_rng_len_err_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_drop_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_discard_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_drop_ip_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_drop_udp_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_marker_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_lacpdu_frms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_unknown_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_marker_resp_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_fcs_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_illegal_pdu_frms_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_switch_discard_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_len_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_rpa_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_l2_mgmt_discard_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_rts_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_trash_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_buff_full_discard_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_red_discard_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_ctrl_err_cnt_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_data_err_cnt_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_char1_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_err_sym_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_column1_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_char2_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_local_fault_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_xgmii_column2_match_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_jettison_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("rx_remote_fault_%d\t\t\t",
+				&stat_size, data, i);
+		}
+
+		vxge_add_string("\n SOFTWARE STATISTICS%s\t\t\t",
+			&stat_size, data, "");
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_add_string("soft_reset_cnt_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("unknown_alarms_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("network_sustained_fault_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("network_sustained_ok_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("kdfcctl_fifo0_overwrite_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("kdfcctl_fifo0_poison_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("kdfcctl_fifo0_dma_error_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("dblgen_fifo0_overflow_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("statsb_pif_chain_error_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("statsb_drop_timeout_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("target_illegal_access_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("ini_serr_det_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("prc_ring_bumps_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("prc_rxdcm_sc_err_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("prc_rxdcm_sc_abort_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("prc_quanta_size_err_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("ring_full_cnt_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("ring_usage_cnt_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("ring_usage_max_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("ring_reserve_free_swaps_cnt_%d\t",
+				&stat_size, data, i);
+			vxge_add_string("ring_total_compl_cnt_%d\t\t",
+				&stat_size, data, i);
+			for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+				vxge_add_string("rxd_t_code_err_cnt%d_%d\t\t",
+					&stat_size, data, j, i);
+			vxge_add_string("fifo_full_cnt_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_usage_cnt_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_usage_max_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_reserve_free_swaps_cnt_%d\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_total_compl_cnt_%d\t\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_total_posts_%d\t\t\t",
+				&stat_size, data, i);
+			vxge_add_string("fifo_total_buffers_%d\t\t",
+				&stat_size, data, i);
+			for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+				vxge_add_string("txd_t_code_err_cnt%d_%d\t\t",
+					&stat_size, data, j, i);
+		}
+
+		vxge_add_string("\n HARDWARE STATISTICS%s\t\t\t",
+				&stat_size, data, "");
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_add_string("ini_num_mwr_sent_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("ini_num_mrd_sent_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("ini_num_cpl_rcvd_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("ini_num_mwr_byte_sent_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("ini_num_cpl_byte_rcvd_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("wrcrdtarb_xoff_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rdcrdtarb_xoff_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count0_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count1_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count2_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count3_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count4_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("vpath_genstats_count5_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("prog_event_vnum0_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("prog_event_vnum1_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("prog_event_vnum2_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("prog_event_vnum3_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_multi_cast_frame_discard_%d\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_frm_transferred_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rxd_returned_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_mpa_len_fail_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_mpa_mrk_fail_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_mpa_crc_fail_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_permitted_frms_%d\t\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_vp_reset_discarded_frms_%d\t",
+					&stat_size, data, i);
+			vxge_add_string("rx_wol_frms_%d\t\t\t",
+					&stat_size, data, i);
+			vxge_add_string("tx_vp_reset_discarded_frms_%d\t",
+					&stat_size, data, i);
+		}
+
+		memcpy(data + stat_size, &ethtool_driver_stats_keys,
+			sizeof(ethtool_driver_stats_keys));
+	}
+}
+
+static int vxge_ethtool_get_regs_len(struct net_device *dev)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
+}
+
+static u32 vxge_get_rx_csum(struct net_device *dev)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	return vdev->rx_csum;
+}
+
+static int vxge_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	if (data)
+		vdev->rx_csum = 1;
+	else
+		vdev->rx_csum = 0;
+
+	return 0;
+}
+
+static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
+{
+	if (data)
+		dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
+	else
+		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+	return 0;
+}
+
+static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	switch (sset) {
+	case ETH_SS_STATS:
+		return VXGE_TITLE_LEN +
+			(vdev->no_of_vpath * VXGE_HW_VPATH_STATS_LEN) +
+			(vdev->max_config_port * VXGE_HW_AGGR_STATS_LEN) +
+			(vdev->max_config_port * VXGE_HW_PORT_STATS_LEN) +
+			(vdev->no_of_vpath * VXGE_HW_VPATH_TX_STATS_LEN) +
+			(vdev->no_of_vpath * VXGE_HW_VPATH_RX_STATS_LEN) +
+			(vdev->no_of_vpath * VXGE_SW_STATS_LEN) +
+			DRIVER_STAT_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static const struct ethtool_ops vxge_ethtool_ops = {
+	.get_settings		= vxge_ethtool_gset,
+	.set_settings		= vxge_ethtool_sset,
+	.get_drvinfo		= vxge_ethtool_gdrvinfo,
+	.get_regs_len		= vxge_ethtool_get_regs_len,
+	.get_regs		= vxge_ethtool_gregs,
+	.get_link		= ethtool_op_get_link,
+	.get_pauseparam		= vxge_ethtool_getpause_data,
+	.set_pauseparam		= vxge_ethtool_setpause_data,
+	.get_rx_csum		= vxge_get_rx_csum,
+	.set_rx_csum		= vxge_set_rx_csum,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
+	.get_tso		= ethtool_op_get_tso,
+	.set_tso		= vxge_ethtool_op_set_tso,
+	.get_strings		= vxge_ethtool_get_strings,
+	.phys_id		= vxge_ethtool_idnic,
+	.get_sset_count		= vxge_ethtool_get_sset_count,
+	.get_ethtool_stats	= vxge_get_ethtool_stats,
+};
+
+void initialize_ethtool_ops(struct net_device *ndev)
+{
+	SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-ethtool.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-ethtool.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-ethtool.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-ethtool.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-ethtool.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                 Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef _VXGE_ETHTOOL_H
+#define _VXGE_ETHTOOL_H
+
+#include "vxge-main.h"
+
+/* Ethtool related variables and Macros. */
+static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset);
+
+static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
+	{"\n DRIVER STATISTICS"},
+	{"vpaths_opened"},
+	{"vpath_open_fail_cnt"},
+	{"link_up_cnt"},
+	{"link_down_cnt"},
+	{"tx_frms"},
+	{"tx_errors"},
+	{"tx_bytes"},
+	{"txd_not_free"},
+	{"txd_out_of_desc"},
+	{"rx_frms"},
+	{"rx_errors"},
+	{"rx_bytes"},
+	{"rx_mcast"},
+	{"pci_map_fail_cnt"},
+	{"skb_alloc_fail_cnt"}
+};
+
+#define VXGE_TITLE_LEN			5
+#define VXGE_HW_VPATH_STATS_LEN 	27
+#define VXGE_HW_AGGR_STATS_LEN  	13
+#define VXGE_HW_PORT_STATS_LEN  	94
+#define VXGE_HW_VPATH_TX_STATS_LEN	19
+#define VXGE_HW_VPATH_RX_STATS_LEN	42
+#define VXGE_SW_STATS_LEN		60
+#define VXGE_HW_STATS_LEN	(VXGE_HW_VPATH_STATS_LEN +\
+				VXGE_HW_AGGR_STATS_LEN +\
+				VXGE_HW_PORT_STATS_LEN +\
+				VXGE_HW_VPATH_TX_STATS_LEN +\
+				VXGE_HW_VPATH_RX_STATS_LEN)
+
+#define DRIVER_STAT_LEN (sizeof(ethtool_driver_stats_keys)/ETH_GSTRING_LEN)
+#define STAT_LEN (VXGE_HW_STATS_LEN + DRIVER_STAT_LEN + VXGE_SW_STATS_LEN)
+
+/* Maximum flicker time of adapter LED */
+#define VXGE_MAX_FLICKER_TIME (60 * HZ) /* 60 seconds */
+#define VXGE_FLICKER_ON		1
+#define VXGE_FLICKER_OFF	0
+
+#define vxge_add_string(fmt, size, buf, ...) {\
+	snprintf(buf + *size, ETH_GSTRING_LEN, fmt, __VA_ARGS__); \
+	*size += ETH_GSTRING_LEN; \
+}
+
+#endif /*_VXGE_ETHTOOL_H*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-main.c linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-main.c
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-main.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4503 @@
+/******************************************************************************
+* This software may be used and distributed according to the terms of
+* the GNU General Public License (GPL), incorporated herein by reference.
+* Drivers based on or derived from this code fall under the GPL and must
+* retain the authorship, copyright and license notice.  This file is not
+* a complete program and may only be used when the entire operating
+* system is licensed under the GPL.
+* See the file COPYING in this distribution for more information.
+*
+* vxge-main.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+*              Virtualized Server Adapter.
+* Copyright(c) 2002-2009 Neterion Inc.
+*
+* The module loadable parameters that are supported by the driver and a brief
+* explanation of all the variables:
+* vlan_tag_strip:
+*	Strip VLAN Tag enable/disable. Instructs the device to remove
+*	the VLAN tag from all received tagged frames that are not
+*	replicated at the internal L2 switch.
+*		0 - Do not strip the VLAN tag.
+*		1 - Strip the VLAN tag.
+*
+* addr_learn_en:
+*	Enable learning the mac address of the guest OS interface in
+*	a virtualization environment.
+*		0 - DISABLE
+*		1 - ENABLE
+*
+* max_config_port:
+*	Maximum number of port to be supported.
+*		MIN -1 and MAX - 2
+*
+* max_config_vpath:
+*	This configures the maximum no of VPATH configures for each
+* 	device function.
+*		MIN - 1 and MAX - 17
+*
+* max_config_dev:
+*	This configures maximum no of Device function to be enabled.
+*		MIN - 1 and MAX - 17
+*
+******************************************************************************/
+
+#include <linux/if_vlan.h>
+#include <linux/pci.h>
+#include <linux/tcp.h>
+#include <net/ip.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include "vxge-main.h"
+#include "vxge-reg.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Neterion's X3100 Series 10GbE PCIe I/O"
+	"Virtualized Server Adapter");
+
+static struct pci_device_id vxge_id_table[] __devinitdata = {
+	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_TITAN_WIN, PCI_ANY_ID,
+	PCI_ANY_ID},
+	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_TITAN_UNI, PCI_ANY_ID,
+	PCI_ANY_ID},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, vxge_id_table);
+
+VXGE_MODULE_PARAM_INT(vlan_tag_strip, VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE);
+VXGE_MODULE_PARAM_INT(addr_learn_en, VXGE_HW_MAC_ADDR_LEARN_DEFAULT);
+VXGE_MODULE_PARAM_INT(max_config_port, VXGE_MAX_CONFIG_PORT);
+VXGE_MODULE_PARAM_INT(max_config_vpath, VXGE_USE_DEFAULT);
+VXGE_MODULE_PARAM_INT(max_mac_vpath, VXGE_MAX_MAC_ADDR_COUNT);
+VXGE_MODULE_PARAM_INT(max_config_dev, VXGE_MAX_CONFIG_DEV);
+
+static u16 vpath_selector[VXGE_HW_MAX_VIRTUAL_PATHS] =
+		{0, 1, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, 31};
+static unsigned int bw_percentage[VXGE_HW_MAX_VIRTUAL_PATHS] =
+	{[0 ...(VXGE_HW_MAX_VIRTUAL_PATHS - 1)] = 0xFF};
+module_param_array(bw_percentage, uint, NULL, 0);
+
+static struct vxge_drv_config *driver_config;
+
+static inline int is_vxge_card_up(struct vxgedev *vdev)
+{
+	return test_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+}
+
+static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
+{
+	unsigned long flags = 0;
+	struct sk_buff *skb_ptr = NULL;
+	struct sk_buff **temp, *head, *skb;
+
+	if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
+		vxge_hw_vpath_poll_tx(fifo->handle, (void **)&skb_ptr);
+		spin_unlock_irqrestore(&fifo->tx_lock, flags);
+	}
+	/* free SKBs */
+	head = skb_ptr;
+	while (head) {
+		skb = head;
+		temp = (struct sk_buff **)&skb->cb;
+		head = *temp;
+		*temp = NULL;
+		dev_kfree_skb_irq(skb);
+	}
+}
+
+static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev)
+{
+	int i;
+
+	/* Complete all transmits */
+	for (i = 0; i < vdev->no_of_vpath; i++)
+		VXGE_COMPLETE_VPATH_TX(&vdev->vpaths[i].fifo);
+}
+
+static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev)
+{
+	int i;
+	struct vxge_ring *ring;
+
+	/* Complete all receives*/
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		ring = &vdev->vpaths[i].ring;
+		vxge_hw_vpath_poll_rx(ring->handle);
+	}
+}
+
+/*
+ * MultiQ manipulation helper functions
+ */
+void vxge_stop_all_tx_queue(struct vxgedev *vdev)
+{
+	int i;
+	struct net_device *dev = vdev->ndev;
+
+	if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_STOP;
+	}
+	netif_tx_stop_all_queues(dev);
+}
+
+void vxge_stop_tx_queue(struct vxge_fifo *fifo)
+{
+	struct net_device *dev = fifo->ndev;
+
+	struct netdev_queue *txq = NULL;
+	if (fifo->tx_steering_type == TX_MULTIQ_STEERING)
+		txq = netdev_get_tx_queue(dev, fifo->driver_id);
+	else {
+		txq = netdev_get_tx_queue(dev, 0);
+		fifo->queue_state = VPATH_QUEUE_STOP;
+	}
+
+	netif_tx_stop_queue(txq);
+}
+
+void vxge_start_all_tx_queue(struct vxgedev *vdev)
+{
+	int i;
+	struct net_device *dev = vdev->ndev;
+
+	if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
+	}
+	netif_tx_start_all_queues(dev);
+}
+
+static void vxge_wake_all_tx_queue(struct vxgedev *vdev)
+{
+	int i;
+	struct net_device *dev = vdev->ndev;
+
+	if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
+	}
+	netif_tx_wake_all_queues(dev);
+}
+
+void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb)
+{
+	struct net_device *dev = fifo->ndev;
+
+	int vpath_no = fifo->driver_id;
+	struct netdev_queue *txq = NULL;
+	if (fifo->tx_steering_type == TX_MULTIQ_STEERING) {
+		txq = netdev_get_tx_queue(dev, vpath_no);
+		if (netif_tx_queue_stopped(txq))
+			netif_tx_wake_queue(txq);
+	} else {
+		txq = netdev_get_tx_queue(dev, 0);
+		if (fifo->queue_state == VPATH_QUEUE_STOP)
+			if (netif_tx_queue_stopped(txq)) {
+				fifo->queue_state = VPATH_QUEUE_START;
+				netif_tx_wake_queue(txq);
+			}
+	}
+}
+
+/*
+ * vxge_callback_link_up
+ *
+ * This function is called during interrupt context to notify link up state
+ * change.
+ */
+void
+vxge_callback_link_up(struct __vxge_hw_device *hldev)
+{
+	struct net_device *dev = hldev->ndev;
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		vdev->ndev->name, __func__, __LINE__);
+	printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
+	vdev->stats.link_up++;
+
+	netif_carrier_on(vdev->ndev);
+	vxge_wake_all_tx_queue(vdev);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_callback_link_down
+ *
+ * This function is called during interrupt context to notify link down state
+ * change.
+ */
+void
+vxge_callback_link_down(struct __vxge_hw_device *hldev)
+{
+	struct net_device *dev = hldev->ndev;
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+	printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
+
+	vdev->stats.link_down++;
+	netif_carrier_off(vdev->ndev);
+	vxge_stop_all_tx_queue(vdev);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_rx_alloc
+ *
+ * Allocate SKB.
+ */
+static struct sk_buff*
+vxge_rx_alloc(void *dtrh, struct vxge_ring *ring, const int skb_size)
+{
+	struct net_device    *dev;
+	struct sk_buff       *skb;
+	struct vxge_rx_priv *rx_priv;
+
+	dev = ring->ndev;
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		ring->ndev->name, __func__, __LINE__);
+
+	rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+
+	/* try to allocate skb first. this one may fail */
+	skb = netdev_alloc_skb(dev, skb_size +
+	VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+	if (skb == NULL) {
+		vxge_debug_mem(VXGE_ERR,
+			"%s: out of memory to allocate SKB", dev->name);
+		ring->stats.skb_alloc_fail++;
+		return NULL;
+	}
+
+	vxge_debug_mem(VXGE_TRACE,
+		"%s: %s:%d  Skb : 0x%p", ring->ndev->name,
+		__func__, __LINE__, skb);
+
+	skb_reserve(skb, VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+
+	rx_priv->skb = skb;
+	rx_priv->data_size = skb_size;
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+	return skb;
+}
+
+/*
+ * vxge_rx_map
+ */
+static int vxge_rx_map(void *dtrh, struct vxge_ring *ring)
+{
+	struct vxge_rx_priv *rx_priv;
+	dma_addr_t dma_addr;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		ring->ndev->name, __func__, __LINE__);
+	rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+
+	dma_addr = pci_map_single(ring->pdev, rx_priv->skb->data,
+				rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+	if (dma_addr == 0) {
+		ring->stats.pci_map_fail++;
+		return -EIO;
+	}
+	vxge_debug_mem(VXGE_TRACE,
+		"%s: %s:%d  1 buffer mode dma_addr = 0x%llx",
+		ring->ndev->name, __func__, __LINE__,
+		(unsigned long long)dma_addr);
+	vxge_hw_ring_rxd_1b_set(dtrh, dma_addr, rx_priv->data_size);
+
+	rx_priv->data_dma = dma_addr;
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+	return 0;
+}
+
+/*
+ * vxge_rx_initial_replenish
+ * Allocation of RxD as an initial replenish procedure.
+ */
+static enum vxge_hw_status
+vxge_rx_initial_replenish(void *dtrh, void *userdata)
+{
+	struct vxge_ring *ring = (struct vxge_ring *)userdata;
+	struct vxge_rx_priv *rx_priv;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		ring->ndev->name, __func__, __LINE__);
+	if (vxge_rx_alloc(dtrh, ring,
+			  VXGE_LL_MAX_FRAME_SIZE(ring->ndev)) == NULL)
+		return VXGE_HW_FAIL;
+
+	if (vxge_rx_map(dtrh, ring)) {
+		rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+		dev_kfree_skb(rx_priv->skb);
+
+		return VXGE_HW_FAIL;
+	}
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+	return VXGE_HW_OK;
+}
+
+static inline void
+vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
+		 int pkt_length, struct vxge_hw_ring_rxd_info *ext_info)
+{
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+			ring->ndev->name, __func__, __LINE__);
+	skb_record_rx_queue(skb, ring->driver_id);
+	skb->protocol = eth_type_trans(skb, ring->ndev);
+
+	ring->stats.rx_frms++;
+	ring->stats.rx_bytes += pkt_length;
+
+	if (skb->pkt_type == PACKET_MULTICAST)
+		ring->stats.rx_mcast++;
+
+	vxge_debug_rx(VXGE_TRACE,
+		"%s: %s:%d  skb protocol = %d",
+		ring->ndev->name, __func__, __LINE__, skb->protocol);
+
+	if (ring->gro_enable) {
+		if (ring->vlgrp && ext_info->vlan &&
+			(ring->vlan_tag_strip ==
+				VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+			vlan_gro_receive(&ring->napi, ring->vlgrp,
+					ext_info->vlan, skb);
+		else
+			napi_gro_receive(&ring->napi, skb);
+	} else {
+		if (ring->vlgrp && vlan &&
+			(ring->vlan_tag_strip ==
+				VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+			vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan);
+		else
+			netif_receive_skb(skb);
+	}
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+}
+
+static inline void vxge_re_pre_post(void *dtr, struct vxge_ring *ring,
+				    struct vxge_rx_priv *rx_priv)
+{
+	pci_dma_sync_single_for_device(ring->pdev,
+		rx_priv->data_dma, rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+	vxge_hw_ring_rxd_1b_set(dtr, rx_priv->data_dma, rx_priv->data_size);
+	vxge_hw_ring_rxd_pre_post(ring->handle, dtr);
+}
+
+static inline void vxge_post(int *dtr_cnt, void **first_dtr,
+			     void *post_dtr, struct __vxge_hw_ring *ringh)
+{
+	int dtr_count = *dtr_cnt;
+	if ((*dtr_cnt % VXGE_HW_RXSYNC_FREQ_CNT) == 0) {
+		if (*first_dtr)
+			vxge_hw_ring_rxd_post_post_wmb(ringh, *first_dtr);
+		*first_dtr = post_dtr;
+	} else
+		vxge_hw_ring_rxd_post_post(ringh, post_dtr);
+	dtr_count++;
+	*dtr_cnt = dtr_count;
+}
+
+/*
+ * vxge_rx_1b_compl
+ *
+ * If the interrupt is because of a received frame or if the receive ring
+ * contains fresh as yet un-processed frames, this function is called.
+ */
+enum vxge_hw_status
+vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
+		 u8 t_code, void *userdata)
+{
+	struct vxge_ring *ring = (struct vxge_ring *)userdata;
+	struct  net_device *dev = ring->ndev;
+	unsigned int dma_sizes;
+	void *first_dtr = NULL;
+	int dtr_cnt = 0;
+	int data_size;
+	dma_addr_t data_dma;
+	int pkt_length;
+	struct sk_buff *skb;
+	struct vxge_rx_priv *rx_priv;
+	struct vxge_hw_ring_rxd_info ext_info;
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		ring->ndev->name, __func__, __LINE__);
+	ring->pkts_processed = 0;
+
+	vxge_hw_ring_replenish(ringh, 0);
+
+	do {
+		rx_priv = vxge_hw_ring_rxd_private_get(dtr);
+		skb = rx_priv->skb;
+		data_size = rx_priv->data_size;
+		data_dma = rx_priv->data_dma;
+
+		vxge_debug_rx(VXGE_TRACE,
+			"%s: %s:%d  skb = 0x%p",
+			ring->ndev->name, __func__, __LINE__, skb);
+
+		vxge_hw_ring_rxd_1b_get(ringh, dtr, &dma_sizes);
+		pkt_length = dma_sizes;
+
+		vxge_debug_rx(VXGE_TRACE,
+			"%s: %s:%d  Packet Length = %d",
+			ring->ndev->name, __func__, __LINE__, pkt_length);
+
+		vxge_hw_ring_rxd_1b_info_get(ringh, dtr, &ext_info);
+
+		/* check skb validity */
+		vxge_assert(skb);
+
+		prefetch((char *)skb + L1_CACHE_BYTES);
+		if (unlikely(t_code)) {
+
+			if (vxge_hw_ring_handle_tcode(ringh, dtr, t_code) !=
+				VXGE_HW_OK) {
+
+				ring->stats.rx_errors++;
+				vxge_debug_rx(VXGE_TRACE,
+					"%s: %s :%d Rx T_code is %d",
+					ring->ndev->name, __func__,
+					__LINE__, t_code);
+
+				/* If the t_code is not supported and if the
+				 * t_code is other than 0x5 (unparseable packet
+				 * such as unknown UPV6 header), Drop it !!!
+				 */
+				vxge_re_pre_post(dtr, ring, rx_priv);
+
+				vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+				ring->stats.rx_dropped++;
+				continue;
+			}
+		}
+
+		if (pkt_length > VXGE_LL_RX_COPY_THRESHOLD) {
+
+			if (vxge_rx_alloc(dtr, ring, data_size) != NULL) {
+
+				if (!vxge_rx_map(dtr, ring)) {
+					skb_put(skb, pkt_length);
+
+					pci_unmap_single(ring->pdev, data_dma,
+						data_size, PCI_DMA_FROMDEVICE);
+
+					vxge_hw_ring_rxd_pre_post(ringh, dtr);
+					vxge_post(&dtr_cnt, &first_dtr, dtr,
+						ringh);
+				} else {
+					dev_kfree_skb(rx_priv->skb);
+					rx_priv->skb = skb;
+					rx_priv->data_size = data_size;
+					vxge_re_pre_post(dtr, ring, rx_priv);
+
+					vxge_post(&dtr_cnt, &first_dtr, dtr,
+						ringh);
+					ring->stats.rx_dropped++;
+					break;
+				}
+			} else {
+				vxge_re_pre_post(dtr, ring, rx_priv);
+
+				vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+				ring->stats.rx_dropped++;
+				break;
+			}
+		} else {
+			struct sk_buff *skb_up;
+
+			skb_up = netdev_alloc_skb(dev, pkt_length +
+				VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+			if (skb_up != NULL) {
+				skb_reserve(skb_up,
+				    VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+
+				pci_dma_sync_single_for_cpu(ring->pdev,
+					data_dma, data_size,
+					PCI_DMA_FROMDEVICE);
+
+				vxge_debug_mem(VXGE_TRACE,
+					"%s: %s:%d  skb_up = %p",
+					ring->ndev->name, __func__,
+					__LINE__, skb);
+				memcpy(skb_up->data, skb->data, pkt_length);
+
+				vxge_re_pre_post(dtr, ring, rx_priv);
+
+				vxge_post(&dtr_cnt, &first_dtr, dtr,
+					ringh);
+				/* will netif_rx small SKB instead */
+				skb = skb_up;
+				skb_put(skb, pkt_length);
+			} else {
+				vxge_re_pre_post(dtr, ring, rx_priv);
+
+				vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+				vxge_debug_rx(VXGE_ERR,
+					"%s: vxge_rx_1b_compl: out of "
+					"memory", dev->name);
+				ring->stats.skb_alloc_fail++;
+				break;
+			}
+		}
+
+		if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) &&
+		    !(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) &&
+		    ring->rx_csum && /* Offload Rx side CSUM */
+		    ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK &&
+		    ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
+
+		vxge_rx_complete(ring, skb, ext_info.vlan,
+			pkt_length, &ext_info);
+
+		ring->budget--;
+		ring->pkts_processed++;
+		if (!ring->budget)
+			break;
+
+	} while (vxge_hw_ring_rxd_next_completed(ringh, &dtr,
+		&t_code) == VXGE_HW_OK);
+
+	if (first_dtr)
+		vxge_hw_ring_rxd_post_post_wmb(ringh, first_dtr);
+
+	dev->last_rx = jiffies;
+
+	vxge_debug_entryexit(VXGE_TRACE,
+				"%s:%d  Exiting...",
+				__func__, __LINE__);
+	return VXGE_HW_OK;
+}
+
+/*
+ * vxge_xmit_compl
+ *
+ * If an interrupt was raised to indicate DMA complete of the Tx packet,
+ * this function is called. It identifies the last TxD whose buffer was
+ * freed and frees all skbs whose data have already DMA'ed into the NICs
+ * internal memory.
+ */
+enum vxge_hw_status
+vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
+		enum vxge_hw_fifo_tcode t_code, void *userdata,
+		void **skb_ptr)
+{
+	struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
+	struct sk_buff *skb, *head = NULL;
+	struct sk_buff **temp;
+	int pkt_cnt = 0;
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d Entered....", __func__, __LINE__);
+
+	do {
+		int frg_cnt;
+		skb_frag_t *frag;
+		int i = 0, j;
+		struct vxge_tx_priv *txd_priv =
+			vxge_hw_fifo_txdl_private_get(dtr);
+
+		skb = txd_priv->skb;
+		frg_cnt = skb_shinfo(skb)->nr_frags;
+		frag = &skb_shinfo(skb)->frags[0];
+
+		vxge_debug_tx(VXGE_TRACE,
+				"%s: %s:%d fifo_hw = %p dtr = %p "
+				"tcode = 0x%x", fifo->ndev->name, __func__,
+				__LINE__, fifo_hw, dtr, t_code);
+		/* check skb validity */
+		vxge_assert(skb);
+		vxge_debug_tx(VXGE_TRACE,
+			"%s: %s:%d skb = %p itxd_priv = %p frg_cnt = %d",
+			fifo->ndev->name, __func__, __LINE__,
+			skb, txd_priv, frg_cnt);
+		if (unlikely(t_code)) {
+			fifo->stats.tx_errors++;
+			vxge_debug_tx(VXGE_ERR,
+				"%s: tx: dtr %p completed due to "
+				"error t_code %01x", fifo->ndev->name,
+				dtr, t_code);
+			vxge_hw_fifo_handle_tcode(fifo_hw, dtr, t_code);
+		}
+
+		/*  for unfragmented skb */
+		pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
+				skb_headlen(skb), PCI_DMA_TODEVICE);
+
+		for (j = 0; j < frg_cnt; j++) {
+			pci_unmap_page(fifo->pdev,
+					txd_priv->dma_buffers[i++],
+					frag->size, PCI_DMA_TODEVICE);
+			frag += 1;
+		}
+
+		vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+
+		/* Updating the statistics block */
+		fifo->stats.tx_frms++;
+		fifo->stats.tx_bytes += skb->len;
+
+		temp = (struct sk_buff **)&skb->cb;
+		*temp = head;
+		head = skb;
+
+		pkt_cnt++;
+		if (pkt_cnt > fifo->indicate_max_pkts)
+			break;
+
+	} while (vxge_hw_fifo_txdl_next_completed(fifo_hw,
+				&dtr, &t_code) == VXGE_HW_OK);
+
+	vxge_wake_tx_queue(fifo, skb);
+
+	if (skb_ptr)
+		*skb_ptr = (void *) head;
+
+	vxge_debug_entryexit(VXGE_TRACE,
+				"%s: %s:%d  Exiting...",
+				fifo->ndev->name, __func__, __LINE__);
+	return VXGE_HW_OK;
+}
+
+/* select a vpath to trasmit the packet */
+static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
+	int *do_lock)
+{
+	u16 queue_len, counter = 0;
+	if (skb->protocol == htons(ETH_P_IP)) {
+		struct iphdr *ip;
+		struct tcphdr *th;
+
+		ip = ip_hdr(skb);
+
+		if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) {
+			th = (struct tcphdr *)(((unsigned char *)ip) +
+					ip->ihl*4);
+
+			queue_len = vdev->no_of_vpath;
+			counter = (ntohs(th->source) +
+				ntohs(th->dest)) &
+				vdev->vpath_selector[queue_len - 1];
+			if (counter >= queue_len)
+				counter = queue_len - 1;
+
+			if (ip->protocol == IPPROTO_UDP) {
+#ifdef NETIF_F_LLTX
+				*do_lock = 0;
+#endif
+			}
+		}
+	}
+	return counter;
+}
+
+static enum vxge_hw_status vxge_search_mac_addr_in_list(
+	struct vxge_vpath *vpath, u64 del_mac)
+{
+	struct list_head *entry, *next;
+	list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+		if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
+{
+	struct macInfo mac_info;
+	u8 *mac_address = NULL;
+	u64 mac_addr = 0, vpath_vector = 0;
+	int vpath_idx = 0;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_vpath *vpath = NULL;
+	struct __vxge_hw_device *hldev;
+
+	hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+
+	mac_address = (u8 *)&mac_addr;
+	memcpy(mac_address, mac_header, ETH_ALEN);
+
+	/* Is this mac address already in the list? */
+	for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+		vpath = &vdev->vpaths[vpath_idx];
+		if (vxge_search_mac_addr_in_list(vpath, mac_addr))
+			return vpath_idx;
+	}
+
+	memset(&mac_info, 0, sizeof(struct macInfo));
+	memcpy(mac_info.macaddr, mac_header, ETH_ALEN);
+
+	/* Any vpath has room to add mac address to its da table? */
+	for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+		vpath = &vdev->vpaths[vpath_idx];
+		if (vpath->mac_addr_cnt < vpath->max_mac_addr_cnt) {
+			/* Add this mac address to this vpath */
+			mac_info.vpath_no = vpath_idx;
+			mac_info.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+			status = vxge_add_mac_addr(vdev, &mac_info);
+			if (status != VXGE_HW_OK)
+				return -EPERM;
+			return vpath_idx;
+		}
+	}
+
+	mac_info.state = VXGE_LL_MAC_ADDR_IN_LIST;
+	vpath_idx = 0;
+	mac_info.vpath_no = vpath_idx;
+	/* Is the first vpath already selected as catch-basin ? */
+	vpath = &vdev->vpaths[vpath_idx];
+	if (vpath->mac_addr_cnt > vpath->max_mac_addr_cnt) {
+		/* Add this mac address to this vpath */
+		if (FALSE == vxge_mac_list_add(vpath, &mac_info))
+			return -EPERM;
+		return vpath_idx;
+	}
+
+	/* Select first vpath as catch-basin */
+	vpath_vector = vxge_mBIT(vpath->device_id);
+	status = vxge_hw_mgmt_reg_write(vpath->vdev->devh,
+				vxge_hw_mgmt_reg_type_mrpcim,
+				0,
+				(ulong)offsetof(
+					struct vxge_hw_mrpcim_reg,
+					rts_mgr_cbasin_cfg),
+				vpath_vector);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_tx(VXGE_ERR,
+			"%s: Unable to set the vpath-%d in catch-basin mode",
+			VXGE_DRIVER_NAME, vpath->device_id);
+		return -EPERM;
+	}
+
+	if (FALSE == vxge_mac_list_add(vpath, &mac_info))
+		return -EPERM;
+
+	return vpath_idx;
+}
+
+/**
+ * vxge_xmit
+ * @skb : the socket buffer containing the Tx data.
+ * @dev : device pointer.
+ *
+ * This function is the Tx entry point of the driver. Neterion NIC supports
+ * certain protocol assist features on Tx side, namely  CSO, S/G, LSO.
+ * NOTE: when device cant queue the pkt, just the trans_start variable will
+ * not be upadted.
+*/
+static int
+vxge_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct vxge_fifo *fifo = NULL;
+	void *dtr_priv;
+	void *dtr = NULL;
+	struct vxgedev *vdev = NULL;
+	enum vxge_hw_status status;
+	int frg_cnt, first_frg_len;
+	skb_frag_t *frag;
+	int i = 0, j = 0, avail;
+	u64 dma_pointer;
+	struct vxge_tx_priv *txdl_priv = NULL;
+	struct __vxge_hw_fifo *fifo_hw;
+	u32 max_mss = 0x0;
+	int offload_type;
+	unsigned long flags = 0;
+	int vpath_no = 0;
+	int do_spin_tx_lock = 1;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+			dev->name, __func__, __LINE__);
+
+	/* A buffer with no data will be dropped */
+	if (unlikely(skb->len <= 0)) {
+		vxge_debug_tx(VXGE_ERR,
+			"%s: Buffer has no data..", dev->name);
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+
+	if (unlikely(!is_vxge_card_up(vdev))) {
+		vxge_debug_tx(VXGE_ERR,
+			"%s: vdev not initialized", dev->name);
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	if (vdev->config.addr_learn_en) {
+		vpath_no = vxge_learn_mac(vdev, skb->data + ETH_ALEN);
+		if (vpath_no == -EPERM) {
+			vxge_debug_tx(VXGE_ERR,
+				"%s: Failed to store the mac address",
+				dev->name);
+			dev_kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+	}
+
+	if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
+		vpath_no = skb_get_queue_mapping(skb);
+	else if (vdev->config.tx_steering_type == TX_PORT_STEERING)
+		vpath_no = vxge_get_vpath_no(vdev, skb, &do_spin_tx_lock);
+
+	vxge_debug_tx(VXGE_TRACE, "%s: vpath_no= %d", dev->name, vpath_no);
+
+	if (vpath_no >= vdev->no_of_vpath)
+		vpath_no = 0;
+
+	fifo = &vdev->vpaths[vpath_no].fifo;
+	fifo_hw = fifo->handle;
+
+	if (do_spin_tx_lock)
+		spin_lock_irqsave(&fifo->tx_lock, flags);
+	else {
+		if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
+			return NETDEV_TX_LOCKED;
+	}
+
+	if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING) {
+		if (netif_subqueue_stopped(dev, skb)) {
+			spin_unlock_irqrestore(&fifo->tx_lock, flags);
+			return NETDEV_TX_BUSY;
+		}
+	} else if (unlikely(fifo->queue_state == VPATH_QUEUE_STOP)) {
+		if (netif_queue_stopped(dev)) {
+			spin_unlock_irqrestore(&fifo->tx_lock, flags);
+			return NETDEV_TX_BUSY;
+		}
+	}
+	avail = vxge_hw_fifo_free_txdl_count_get(fifo_hw);
+	if (avail == 0) {
+		vxge_debug_tx(VXGE_ERR,
+			"%s: No free TXDs available", dev->name);
+		fifo->stats.txd_not_free++;
+		vxge_stop_tx_queue(fifo);
+		goto _exit2;
+	}
+
+	status = vxge_hw_fifo_txdl_reserve(fifo_hw, &dtr, &dtr_priv);
+	if (unlikely(status != VXGE_HW_OK)) {
+		vxge_debug_tx(VXGE_ERR,
+		   "%s: Out of descriptors .", dev->name);
+		fifo->stats.txd_out_of_desc++;
+		vxge_stop_tx_queue(fifo);
+		goto _exit2;
+	}
+
+	vxge_debug_tx(VXGE_TRACE,
+		"%s: %s:%d fifo_hw = %p dtr = %p dtr_priv = %p",
+		dev->name, __func__, __LINE__,
+		fifo_hw, dtr, dtr_priv);
+
+	if (vdev->vlgrp && vlan_tx_tag_present(skb)) {
+		u16 vlan_tag = vlan_tx_tag_get(skb);
+		vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag);
+	}
+
+	first_frg_len = skb_headlen(skb);
+
+	dma_pointer = pci_map_single(fifo->pdev, skb->data, first_frg_len,
+				PCI_DMA_TODEVICE);
+
+	if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer))) {
+		vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+		vxge_stop_tx_queue(fifo);
+		fifo->stats.pci_map_fail++;
+		goto _exit2;
+	}
+
+	txdl_priv = vxge_hw_fifo_txdl_private_get(dtr);
+	txdl_priv->skb = skb;
+	txdl_priv->dma_buffers[j] = dma_pointer;
+
+	frg_cnt = skb_shinfo(skb)->nr_frags;
+	vxge_debug_tx(VXGE_TRACE,
+			"%s: %s:%d skb = %p txdl_priv = %p "
+			"frag_cnt = %d dma_pointer = 0x%llx", dev->name,
+			__func__, __LINE__, skb, txdl_priv,
+			frg_cnt, (unsigned long long)dma_pointer);
+
+	vxge_hw_fifo_txdl_buffer_set(fifo_hw, dtr, j++, dma_pointer,
+		first_frg_len);
+
+	frag = &skb_shinfo(skb)->frags[0];
+	for (i = 0; i < frg_cnt; i++) {
+		/* ignore 0 length fragment */
+		if (!frag->size)
+			continue;
+
+		dma_pointer =
+			(u64)pci_map_page(fifo->pdev, frag->page,
+				frag->page_offset, frag->size,
+				PCI_DMA_TODEVICE);
+
+		if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer)))
+			goto _exit0;
+		vxge_debug_tx(VXGE_TRACE,
+			"%s: %s:%d frag = %d dma_pointer = 0x%llx",
+				dev->name, __func__, __LINE__, i,
+				(unsigned long long)dma_pointer);
+
+		txdl_priv->dma_buffers[j] = dma_pointer;
+		vxge_hw_fifo_txdl_buffer_set(fifo_hw, dtr, j++, dma_pointer,
+					frag->size);
+		frag += 1;
+	}
+
+	offload_type = vxge_offload_type(skb);
+
+	if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+
+		int mss = vxge_tcp_mss(skb);
+		if (mss) {
+			max_mss = dev->mtu + ETH_HLEN -
+				VXGE_HW_TCPIP_HEADER_MAX_SIZE;
+			if (mss > max_mss)
+				mss = max_mss;
+			vxge_debug_tx(VXGE_TRACE,
+				"%s: %s:%d mss = %d",
+				dev->name, __func__, __LINE__, mss);
+			vxge_hw_fifo_txdl_mss_set(dtr, mss);
+		} else {
+			vxge_assert(skb->len <=
+				dev->mtu + VXGE_HW_MAC_HEADER_MAX_SIZE);
+			vxge_assert(0);
+			goto _exit1;
+		}
+	}
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		vxge_hw_fifo_txdl_cksum_set_bits(dtr,
+					VXGE_HW_FIFO_TXD_TX_CKO_IPV4_EN |
+					VXGE_HW_FIFO_TXD_TX_CKO_TCP_EN |
+					VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN);
+
+	vxge_hw_fifo_txdl_post(fifo_hw, dtr);
+	dev->trans_start = jiffies;
+	spin_unlock_irqrestore(&fifo->tx_lock, flags);
+
+	VXGE_COMPLETE_VPATH_TX(fifo);
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d  Exiting...",
+		dev->name, __func__, __LINE__);
+	return 0;
+
+_exit0:
+	vxge_debug_tx(VXGE_TRACE, "%s: pci_map_page failed", dev->name);
+
+_exit1:
+	j = 0;
+	frag = &skb_shinfo(skb)->frags[0];
+
+	pci_unmap_single(fifo->pdev, txdl_priv->dma_buffers[j++],
+			skb_headlen(skb), PCI_DMA_TODEVICE);
+
+	for (; j < i; j++) {
+		pci_unmap_page(fifo->pdev, txdl_priv->dma_buffers[j],
+			frag->size, PCI_DMA_TODEVICE);
+		frag += 1;
+	}
+
+	vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+_exit2:
+	dev_kfree_skb(skb);
+	spin_unlock_irqrestore(&fifo->tx_lock, flags);
+	VXGE_COMPLETE_VPATH_TX(fifo);
+
+	return 0;
+}
+
+/*
+ * vxge_rx_term
+ *
+ * Function will be called by hw function to abort all outstanding receive
+ * descriptors.
+ */
+static void
+vxge_rx_term(void *dtrh, enum vxge_hw_rxd_state state, void *userdata)
+{
+	struct vxge_ring *ring = (struct vxge_ring *)userdata;
+	struct vxge_rx_priv *rx_priv =
+		vxge_hw_ring_rxd_private_get(dtrh);
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+			ring->ndev->name, __func__, __LINE__);
+	if (state != VXGE_HW_RXD_STATE_POSTED)
+		return;
+
+	pci_unmap_single(ring->pdev, rx_priv->data_dma,
+		rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+	dev_kfree_skb(rx_priv->skb);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d  Exiting...",
+		ring->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_tx_term
+ *
+ * Function will be called to abort all outstanding tx descriptors
+ */
+static void
+vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata)
+{
+	struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
+	skb_frag_t *frag;
+	int i = 0, j, frg_cnt;
+	struct vxge_tx_priv *txd_priv = vxge_hw_fifo_txdl_private_get(dtrh);
+	struct sk_buff *skb = txd_priv->skb;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	if (state != VXGE_HW_TXDL_STATE_POSTED)
+		return;
+
+	/* check skb validity */
+	vxge_assert(skb);
+	frg_cnt = skb_shinfo(skb)->nr_frags;
+	frag = &skb_shinfo(skb)->frags[0];
+
+	/*  for unfragmented skb */
+	pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
+		skb_headlen(skb), PCI_DMA_TODEVICE);
+
+	for (j = 0; j < frg_cnt; j++) {
+		pci_unmap_page(fifo->pdev, txd_priv->dma_buffers[i++],
+			       frag->size, PCI_DMA_TODEVICE);
+		frag += 1;
+	}
+
+	dev_kfree_skb(skb);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_set_multicast
+ * @dev: pointer to the device structure
+ *
+ * Entry point for multicast address enable/disable
+ * This function is a driver entry point which gets called by the kernel
+ * whenever multicast addresses must be enabled/disabled. This also gets
+ * called to set/reset promiscuous mode. Depending on the deivce flag, we
+ * determine, if multicast address must be enabled or if promiscuous mode
+ * is to be disabled etc.
+ */
+static void vxge_set_multicast(struct net_device *dev)
+{
+	struct dev_mc_list *mclist;
+	struct vxgedev *vdev;
+	int i, mcast_cnt = 0;
+	struct __vxge_hw_device  *hldev;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct macInfo mac_info;
+	int vpath_idx = 0;
+	struct vxge_mac_addrs *mac_entry;
+	struct list_head *list_head;
+	struct list_head *entry, *next;
+	u8 *mac_address = NULL;
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d", __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	hldev = (struct __vxge_hw_device  *)vdev->devh;
+
+	if (unlikely(!is_vxge_card_up(vdev)))
+		return;
+
+	if ((dev->flags & IFF_ALLMULTI) && (!vdev->all_multi_flg)) {
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_assert(vdev->vpaths[i].is_open);
+			status = vxge_hw_vpath_mcast_enable(
+						vdev->vpaths[i].handle);
+			vdev->all_multi_flg = 1;
+		}
+	} else if ((dev->flags & IFF_ALLMULTI) && (vdev->all_multi_flg)) {
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_assert(vdev->vpaths[i].is_open);
+			status = vxge_hw_vpath_mcast_disable(
+						vdev->vpaths[i].handle);
+			vdev->all_multi_flg = 1;
+		}
+	}
+
+	if (status != VXGE_HW_OK)
+		vxge_debug_init(VXGE_ERR,
+			"failed to %s multicast, status %d",
+			dev->flags & IFF_ALLMULTI ?
+			"enable" : "disable", status);
+
+	if (!vdev->config.addr_learn_en) {
+		if (dev->flags & IFF_PROMISC) {
+			for (i = 0; i < vdev->no_of_vpath; i++) {
+				vxge_assert(vdev->vpaths[i].is_open);
+				status = vxge_hw_vpath_promisc_enable(
+						vdev->vpaths[i].handle);
+			}
+		} else {
+			for (i = 0; i < vdev->no_of_vpath; i++) {
+				vxge_assert(vdev->vpaths[i].is_open);
+				status = vxge_hw_vpath_promisc_disable(
+						vdev->vpaths[i].handle);
+			}
+		}
+	}
+
+	memset(&mac_info, 0, sizeof(struct macInfo));
+	/* Update individual M_CAST address list */
+	if ((!vdev->all_multi_flg) && dev->mc_count) {
+
+		mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
+		list_head = &vdev->vpaths[0].mac_addr_list;
+		if ((dev->mc_count +
+			(vdev->vpaths[0].mac_addr_cnt - mcast_cnt)) >
+				vdev->vpaths[0].max_mac_addr_cnt)
+			goto _set_all_mcast;
+
+		/* Delete previous MC's */
+		for (i = 0; i < mcast_cnt; i++) {
+			if (!list_empty(list_head))
+				mac_entry = (struct vxge_mac_addrs *)
+					list_first_entry(list_head,
+						struct vxge_mac_addrs,
+						item);
+
+			list_for_each_safe(entry, next, list_head) {
+
+				mac_entry = (struct vxge_mac_addrs *) entry;
+				/* Copy the mac address to delete */
+				mac_address = (u8 *)&mac_entry->macaddr;
+				memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+
+				/* Is this a multicast address */
+				if (0x01 & mac_info.macaddr[0]) {
+					for (vpath_idx = 0; vpath_idx <
+						vdev->no_of_vpath;
+						vpath_idx++) {
+						mac_info.vpath_no = vpath_idx;
+						status = vxge_del_mac_addr(
+								vdev,
+								&mac_info);
+					}
+				}
+			}
+		}
+
+		/* Add new ones */
+		for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+			i++, mclist = mclist->next) {
+
+			memcpy(mac_info.macaddr, mclist->dmi_addr, ETH_ALEN);
+			for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath;
+					vpath_idx++) {
+				mac_info.vpath_no = vpath_idx;
+				mac_info.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+				status = vxge_add_mac_addr(vdev, &mac_info);
+				if (status != VXGE_HW_OK) {
+					vxge_debug_init(VXGE_ERR,
+						"%s:%d Setting individual"
+						"multicast address failed",
+						__func__, __LINE__);
+					goto _set_all_mcast;
+				}
+			}
+		}
+
+		return;
+_set_all_mcast:
+		mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
+		/* Delete previous MC's */
+		for (i = 0; i < mcast_cnt; i++) {
+
+			list_for_each_safe(entry, next, list_head) {
+
+				mac_entry = (struct vxge_mac_addrs *) entry;
+				/* Copy the mac address to delete */
+				mac_address = (u8 *)&mac_entry->macaddr;
+				memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+
+				/* Is this a multicast address */
+				if (0x01 & mac_info.macaddr[0])
+					break;
+			}
+
+			for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath;
+					vpath_idx++) {
+				mac_info.vpath_no = vpath_idx;
+				status = vxge_del_mac_addr(vdev, &mac_info);
+			}
+		}
+
+		/* Enable all multicast */
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_assert(vdev->vpaths[i].is_open);
+			status = vxge_hw_vpath_mcast_enable(
+						vdev->vpaths[i].handle);
+			if (status != VXGE_HW_OK) {
+				vxge_debug_init(VXGE_ERR,
+					"%s:%d Enabling all multicasts failed",
+					 __func__, __LINE__);
+			}
+			vdev->all_multi_flg = 1;
+		}
+		dev->flags |= IFF_ALLMULTI;
+	}
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_set_mac_addr
+ * @dev: pointer to the device structure
+ *
+ * Update entry "0" (default MAC addr)
+ */
+static int vxge_set_mac_addr(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	struct vxgedev *vdev;
+	struct __vxge_hw_device  *hldev;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct macInfo mac_info_new, mac_info_old;
+	int vpath_idx = 0;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	hldev = vdev->devh;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	memset(&mac_info_new, 0, sizeof(struct macInfo));
+	memset(&mac_info_old, 0, sizeof(struct macInfo));
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d  Exiting...",
+		__func__, __LINE__);
+
+	/* Get the old address */
+	memcpy(mac_info_old.macaddr, dev->dev_addr, dev->addr_len);
+
+	/* Copy the new address */
+	memcpy(mac_info_new.macaddr, addr->sa_data, dev->addr_len);
+
+	/* First delete the old mac address from all the vpaths
+	as we can't specify the index while adding new mac address */
+	for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+		struct vxge_vpath *vpath = &vdev->vpaths[vpath_idx];
+		if (!vpath->is_open) {
+			/* This can happen when this interface is added/removed
+			to the bonding interface. Delete this station address
+			from the linked list */
+			vxge_mac_list_del(vpath, &mac_info_old);
+
+			/* Add this new address to the linked list
+			for later restoring */
+			vxge_mac_list_add(vpath, &mac_info_new);
+
+			continue;
+		}
+		/* Delete the station address */
+		mac_info_old.vpath_no = vpath_idx;
+		status = vxge_del_mac_addr(vdev, &mac_info_old);
+	}
+
+	if (unlikely(!is_vxge_card_up(vdev))) {
+		memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+		return VXGE_HW_OK;
+	}
+
+	/* Set this mac address to all the vpaths */
+	for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+		mac_info_new.vpath_no = vpath_idx;
+		mac_info_new.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+		status = vxge_add_mac_addr(vdev, &mac_info_new);
+		if (status != VXGE_HW_OK)
+			return -EINVAL;
+	}
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	return status;
+}
+
+/*
+ * vxge_vpath_intr_enable
+ * @vdev: pointer to vdev
+ * @vp_id: vpath for which to enable the interrupts
+ *
+ * Enables the interrupts for the vpath
+*/
+void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id)
+{
+	struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
+	int msix_id, alarm_msix_id;
+	int tim_msix_id[4] = {[0 ...3] = 0};
+
+	vxge_hw_vpath_intr_enable(vpath->handle);
+
+	if (vdev->config.intr_type == INTA)
+		vxge_hw_vpath_inta_unmask_tx_rx(vpath->handle);
+	else {
+		msix_id = vp_id * VXGE_HW_VPATH_MSIX_ACTIVE;
+		alarm_msix_id =
+			VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+
+		tim_msix_id[0] = msix_id;
+		tim_msix_id[1] = msix_id + 1;
+		vxge_hw_vpath_msix_set(vpath->handle, tim_msix_id,
+			alarm_msix_id);
+
+		vxge_hw_vpath_msix_unmask(vpath->handle, msix_id);
+		vxge_hw_vpath_msix_unmask(vpath->handle, msix_id + 1);
+
+		/* enable the alarm vector */
+		vxge_hw_vpath_msix_unmask(vpath->handle, alarm_msix_id);
+	}
+}
+
+/*
+ * vxge_vpath_intr_disable
+ * @vdev: pointer to vdev
+ * @vp_id: vpath for which to disable the interrupts
+ *
+ * Disables the interrupts for the vpath
+*/
+void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id)
+{
+	struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
+	int msix_id;
+
+	vxge_hw_vpath_intr_disable(vpath->handle);
+
+	if (vdev->config.intr_type == INTA)
+		vxge_hw_vpath_inta_mask_tx_rx(vpath->handle);
+	else {
+		msix_id = vp_id * VXGE_HW_VPATH_MSIX_ACTIVE;
+		vxge_hw_vpath_msix_mask(vpath->handle, msix_id);
+		vxge_hw_vpath_msix_mask(vpath->handle, msix_id + 1);
+
+		/* disable the alarm vector */
+		msix_id = VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+		vxge_hw_vpath_msix_mask(vpath->handle, msix_id);
+	}
+}
+
+/*
+ * vxge_reset_vpath
+ * @vdev: pointer to vdev
+ * @vp_id: vpath to reset
+ *
+ * Resets the vpath
+*/
+static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	int ret = 0;
+
+	/* check if device is down already */
+	if (unlikely(!is_vxge_card_up(vdev)))
+		return 0;
+
+	/* is device reset already scheduled */
+	if (test_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+		return 0;
+
+	if (vdev->vpaths[vp_id].handle) {
+		if (vxge_hw_vpath_reset(vdev->vpaths[vp_id].handle)
+				== VXGE_HW_OK) {
+			if (is_vxge_card_up(vdev) &&
+				vxge_hw_vpath_recover_from_reset(
+					vdev->vpaths[vp_id].handle)
+					!= VXGE_HW_OK) {
+				vxge_debug_init(VXGE_ERR,
+					"vxge_hw_vpath_recover_from_reset"
+					"failed for vpath:%d", vp_id);
+				return status;
+			}
+		} else {
+			vxge_debug_init(VXGE_ERR,
+				"vxge_hw_vpath_reset failed for"
+				"vpath:%d", vp_id);
+				return status;
+		}
+	} else
+		return VXGE_HW_FAIL;
+
+	vxge_restore_vpath_mac_addr(&vdev->vpaths[vp_id]);
+	vxge_restore_vpath_vid_table(&vdev->vpaths[vp_id]);
+
+	/* Enable all broadcast */
+	vxge_hw_vpath_bcast_enable(vdev->vpaths[vp_id].handle);
+
+	/* Enable the interrupts */
+	vxge_vpath_intr_enable(vdev, vp_id);
+
+	smp_wmb();
+
+	/* Enable the flow of traffic through the vpath */
+	vxge_hw_vpath_enable(vdev->vpaths[vp_id].handle);
+
+	smp_wmb();
+	vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[vp_id].handle);
+	vdev->vpaths[vp_id].ring.last_status = VXGE_HW_OK;
+
+	/* Vpath reset done */
+	clear_bit(vp_id, &vdev->vp_reset);
+
+	/* Start the vpath queue */
+	vxge_wake_tx_queue(&vdev->vpaths[vp_id].fifo, NULL);
+
+	return ret;
+}
+
+static int do_vxge_reset(struct vxgedev *vdev, int event)
+{
+	enum vxge_hw_status status;
+	int ret = 0, vp_id, i;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_START_RESET)) {
+		/* check if device is down already */
+		if (unlikely(!is_vxge_card_up(vdev)))
+			return 0;
+
+		/* is reset already scheduled */
+		if (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+			return 0;
+	}
+
+	if (event == VXGE_LL_FULL_RESET) {
+		/* wait for all the vpath reset to complete */
+		for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+			while (test_bit(vp_id, &vdev->vp_reset))
+				msleep(50);
+		}
+
+		/* if execution mode is set to debug, don't reset the adapter */
+		if (unlikely(vdev->exec_mode)) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: execution mode is debug, returning..",
+				vdev->ndev->name);
+		clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+		vxge_stop_all_tx_queue(vdev);
+		return 0;
+		}
+	}
+
+	if (event == VXGE_LL_FULL_RESET) {
+		vxge_hw_device_intr_disable(vdev->devh);
+
+		switch (vdev->cric_err_event) {
+		case VXGE_HW_EVENT_UNKNOWN:
+			vxge_stop_all_tx_queue(vdev);
+			vxge_debug_init(VXGE_ERR,
+				"fatal: %s: Disabling device due to"
+				"unknown error",
+				vdev->ndev->name);
+			ret = -EPERM;
+			goto out;
+		case VXGE_HW_EVENT_RESET_START:
+			break;
+		case VXGE_HW_EVENT_RESET_COMPLETE:
+		case VXGE_HW_EVENT_LINK_DOWN:
+		case VXGE_HW_EVENT_LINK_UP:
+		case VXGE_HW_EVENT_ALARM_CLEARED:
+		case VXGE_HW_EVENT_ECCERR:
+		case VXGE_HW_EVENT_MRPCIM_ECCERR:
+			ret = -EPERM;
+			goto out;
+		case VXGE_HW_EVENT_FIFO_ERR:
+		case VXGE_HW_EVENT_VPATH_ERR:
+			break;
+		case VXGE_HW_EVENT_CRITICAL_ERR:
+			vxge_stop_all_tx_queue(vdev);
+			vxge_debug_init(VXGE_ERR,
+				"fatal: %s: Disabling device due to"
+				"serious error",
+				vdev->ndev->name);
+			/* SOP or device reset required */
+			/* This event is not currently used */
+			ret = -EPERM;
+			goto out;
+		case VXGE_HW_EVENT_SERR:
+			vxge_stop_all_tx_queue(vdev);
+			vxge_debug_init(VXGE_ERR,
+				"fatal: %s: Disabling device due to"
+				"serious error",
+				vdev->ndev->name);
+			ret = -EPERM;
+			goto out;
+		case VXGE_HW_EVENT_SRPCIM_SERR:
+		case VXGE_HW_EVENT_MRPCIM_SERR:
+			ret = -EPERM;
+			goto out;
+		case VXGE_HW_EVENT_SLOT_FREEZE:
+			vxge_stop_all_tx_queue(vdev);
+			vxge_debug_init(VXGE_ERR,
+				"fatal: %s: Disabling device due to"
+				"slot freeze",
+				vdev->ndev->name);
+			ret = -EPERM;
+			goto out;
+		default:
+			break;
+
+		}
+	}
+
+	if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_START_RESET))
+		vxge_stop_all_tx_queue(vdev);
+
+	if (event == VXGE_LL_FULL_RESET) {
+		status = vxge_reset_all_vpaths(vdev);
+		if (status != VXGE_HW_OK) {
+			vxge_debug_init(VXGE_ERR,
+				"fatal: %s: can not reset vpaths",
+				vdev->ndev->name);
+			ret = -EPERM;
+			goto out;
+		}
+	}
+
+	if (event == VXGE_LL_COMPL_RESET) {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			if (vdev->vpaths[i].handle) {
+				if (vxge_hw_vpath_recover_from_reset(
+					vdev->vpaths[i].handle)
+						!= VXGE_HW_OK) {
+					vxge_debug_init(VXGE_ERR,
+						"vxge_hw_vpath_recover_"
+						"from_reset failed for vpath: "
+						"%d", i);
+					ret = -EPERM;
+					goto out;
+				}
+				} else {
+					vxge_debug_init(VXGE_ERR,
+					"vxge_hw_vpath_reset failed for "
+						"vpath:%d", i);
+					ret = -EPERM;
+					goto out;
+				}
+	}
+
+	if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_COMPL_RESET)) {
+		/* Reprogram the DA table with populated mac addresses */
+		for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+			vxge_restore_vpath_mac_addr(&vdev->vpaths[vp_id]);
+			vxge_restore_vpath_vid_table(&vdev->vpaths[vp_id]);
+		}
+
+		/* enable vpath interrupts */
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			vxge_vpath_intr_enable(vdev, i);
+
+		vxge_hw_device_intr_enable(vdev->devh);
+
+		smp_wmb();
+
+		/* Indicate card up */
+		set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+
+		/* Get the traffic to flow through the vpaths */
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			vxge_hw_vpath_enable(vdev->vpaths[i].handle);
+			smp_wmb();
+			vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
+		}
+
+		vxge_wake_all_tx_queue(vdev);
+	}
+
+out:
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+
+	/* Indicate reset done */
+	if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_COMPL_RESET))
+		clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state);
+	return ret;
+}
+
+/*
+ * vxge_reset
+ * @vdev: pointer to ll device
+ *
+ * driver may reset the chip on events of serr, eccerr, etc
+ */
+int vxge_reset(struct vxgedev *vdev)
+{
+	do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
+	return 0;
+}
+
+/**
+ * vxge_poll - Receive handler when Receive Polling is used.
+ * @dev: pointer to the device structure.
+ * @budget: Number of packets budgeted to be processed in this iteration.
+ *
+ * This function comes into picture only if Receive side is being handled
+ * through polling (called NAPI in linux). It mostly does what the normal
+ * Rx interrupt handler does in terms of descriptor and packet processing
+ * but not in an interrupt context. Also it will process a specified number
+ * of packets at most in one iteration. This value is passed down by the
+ * kernel as the function argument 'budget'.
+ */
+static int vxge_poll_msix(struct napi_struct *napi, int budget)
+{
+	struct vxge_ring *ring =
+		container_of(napi, struct vxge_ring, napi);
+	int budget_org = budget;
+	ring->budget = budget;
+
+	vxge_hw_vpath_poll_rx(ring->handle);
+
+	if (ring->pkts_processed < budget_org) {
+		napi_complete(napi);
+		/* Re enable the Rx interrupts for the vpath */
+		vxge_hw_channel_msix_unmask(
+				(struct __vxge_hw_channel *)ring->handle,
+				ring->rx_vector_no);
+	}
+
+	return ring->pkts_processed;
+}
+
+static int vxge_poll_inta(struct napi_struct *napi, int budget)
+{
+	struct vxgedev *vdev = container_of(napi, struct vxgedev, napi);
+	int pkts_processed = 0;
+	int i;
+	int budget_org = budget;
+	struct vxge_ring *ring;
+
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device *)
+		pci_get_drvdata(vdev->pdev);
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		ring = &vdev->vpaths[i].ring;
+		ring->budget = budget;
+		vxge_hw_vpath_poll_rx(ring->handle);
+		pkts_processed += ring->pkts_processed;
+		budget -= ring->pkts_processed;
+		if (budget <= 0)
+			break;
+	}
+
+	VXGE_COMPLETE_ALL_TX(vdev);
+
+	if (pkts_processed < budget_org) {
+		napi_complete(napi);
+		/* Re enable the Rx interrupts for the ring */
+		vxge_hw_device_unmask_all(hldev);
+		vxge_hw_device_flush_io(hldev);
+	}
+
+	return pkts_processed;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * vxge_netpoll - netpoll event handler entry point
+ * @dev : pointer to the device structure.
+ * Description:
+ *      This function will be called by upper layer to check for events on the
+ * interface in situations where interrupts are disabled. It is used for
+ * specific in-kernel networking tasks, such as remote consoles and kernel
+ * debugging over the network (example netdump in RedHat).
+ */
+static void vxge_netpoll(struct net_device *dev)
+{
+	struct __vxge_hw_device  *hldev;
+	struct vxgedev *vdev;
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	hldev = (struct __vxge_hw_device  *)pci_get_drvdata(vdev->pdev);
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	if (pci_channel_offline(vdev->pdev))
+		return;
+
+	disable_irq(dev->irq);
+	vxge_hw_device_clear_tx_rx(hldev);
+
+	vxge_hw_device_clear_tx_rx(hldev);
+	VXGE_COMPLETE_ALL_RX(vdev);
+	VXGE_COMPLETE_ALL_TX(vdev);
+
+	enable_irq(dev->irq);
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+	return;
+}
+#endif
+
+/* RTH configuration */
+static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_rth_hash_types hash_types;
+	u8 itable[256] = {0}; /* indirection table */
+	u8 mtable[256] = {0}; /* CPU to vpath mapping  */
+	int index;
+
+	/*
+	 * Filling
+	 * 	- itable with bucket numbers
+	 * 	- mtable with bucket-to-vpath mapping
+	 */
+	for (index = 0; index < (1 << vdev->config.rth_bkt_sz); index++) {
+		itable[index] = index;
+		mtable[index] = index % vdev->no_of_vpath;
+	}
+
+	/* Fill RTH hash types */
+	hash_types.hash_type_tcpipv4_en   = vdev->config.rth_hash_type_tcpipv4;
+	hash_types.hash_type_ipv4_en      = vdev->config.rth_hash_type_ipv4;
+	hash_types.hash_type_tcpipv6_en   = vdev->config.rth_hash_type_tcpipv6;
+	hash_types.hash_type_ipv6_en      = vdev->config.rth_hash_type_ipv6;
+	hash_types.hash_type_tcpipv6ex_en =
+					vdev->config.rth_hash_type_tcpipv6ex;
+	hash_types.hash_type_ipv6ex_en    = vdev->config.rth_hash_type_ipv6ex;
+
+	/* set indirection table, bucket-to-vpath mapping */
+	status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
+						vdev->no_of_vpath,
+						mtable, itable,
+						vdev->config.rth_bkt_sz);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"RTH indirection table configuration failed "
+			"for vpath:%d", vdev->vpaths[0].device_id);
+		return status;
+	}
+
+	/*
+	* Because the itable_set() method uses the active_table field
+	* for the target virtual path the RTH config should be updated
+	* for all VPATHs. The h/w only uses the lowest numbered VPATH
+	* when steering frames.
+	*/
+	 for (index = 0; index < vdev->no_of_vpath; index++) {
+		status = vxge_hw_vpath_rts_rth_set(
+				vdev->vpaths[index].handle,
+				vdev->config.rth_algorithm,
+				&hash_types,
+				vdev->config.rth_bkt_sz);
+
+		 if (status != VXGE_HW_OK) {
+			vxge_debug_init(VXGE_ERR,
+				"RTH configuration failed for vpath:%d",
+				vdev->vpaths[index].device_id);
+			return status;
+		 }
+	 }
+
+	return status;
+}
+
+int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+	struct vxge_mac_addrs *new_mac_entry;
+	u8 *mac_address = NULL;
+
+	if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT)
+		return TRUE;
+
+	new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC);
+	if (!new_mac_entry) {
+		vxge_debug_mem(VXGE_ERR,
+			"%s: memory allocation failed",
+			VXGE_DRIVER_NAME);
+		return FALSE;
+	}
+
+	list_add(&new_mac_entry->item, &vpath->mac_addr_list);
+
+	/* Copy the new mac address to the list */
+	mac_address = (u8 *)&new_mac_entry->macaddr;
+	memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+	new_mac_entry->state = mac->state;
+	vpath->mac_addr_cnt++;
+
+	/* Is this a multicast address */
+	if (0x01 & mac->macaddr[0])
+		vpath->mcast_addr_cnt++;
+
+	return TRUE;
+}
+
+/* Add a mac address to DA table */
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_vpath *vpath;
+	enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode;
+
+	if (0x01 & mac->macaddr[0]) /* multicast address */
+		duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE;
+	else
+		duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE;
+
+	vpath = &vdev->vpaths[mac->vpath_no];
+	status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr,
+						mac->macmask, duplicate_mode);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"DA config add entry failed for vpath:%d",
+			vpath->device_id);
+	} else
+		if (FALSE == vxge_mac_list_add(vpath, mac))
+			status = -EPERM;
+
+	return status;
+}
+
+int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+	struct list_head *entry, *next;
+	u64 del_mac = 0;
+	u8 *mac_address = (u8 *) (&del_mac);
+
+	/* Copy the mac address to delete from the list */
+	memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+	list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+		if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) {
+			list_del(entry);
+			kfree((struct vxge_mac_addrs *)entry);
+			vpath->mac_addr_cnt--;
+
+			/* Is this a multicast address */
+			if (0x01 & mac->macaddr[0])
+				vpath->mcast_addr_cnt--;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+/* delete a mac address from DA table */
+enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_vpath *vpath;
+
+	vpath = &vdev->vpaths[mac->vpath_no];
+	status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr,
+						mac->macmask);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"DA config delete entry failed for vpath:%d",
+			vpath->device_id);
+	} else
+		vxge_mac_list_del(vpath, mac);
+	return status;
+}
+
+/* list all mac addresses from DA table */
+enum vxge_hw_status
+static vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath,
+					struct macInfo *mac)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	unsigned char macmask[ETH_ALEN];
+	unsigned char macaddr[ETH_ALEN];
+
+	status = vxge_hw_vpath_mac_addr_get(vpath->handle,
+				macaddr, macmask);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"DA config list entry failed for vpath:%d",
+			vpath->device_id);
+		return status;
+	}
+
+	while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) {
+
+		status = vxge_hw_vpath_mac_addr_get_next(vpath->handle,
+				macaddr, macmask);
+		if (status != VXGE_HW_OK)
+			break;
+	}
+
+	return status;
+}
+
+/* Store all vlan ids from the list to the vid table */
+enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxgedev *vdev = vpath->vdev;
+	u16 vid;
+
+	if (vdev->vlgrp && vpath->is_open) {
+
+		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if (!vlan_group_get_device(vdev->vlgrp, vid))
+				continue;
+			/* Add these vlan to the vid table */
+			status = vxge_hw_vpath_vid_add(vpath->handle, vid);
+		}
+	}
+
+	return status;
+}
+
+/* Store all mac addresses from the list to the DA table */
+enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct macInfo mac_info;
+	u8 *mac_address = NULL;
+	struct list_head *entry, *next;
+
+	memset(&mac_info, 0, sizeof(struct macInfo));
+
+	if (vpath->is_open) {
+
+		list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+			mac_address =
+				(u8 *)&
+				((struct vxge_mac_addrs *)entry)->macaddr;
+			memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+			((struct vxge_mac_addrs *)entry)->state =
+				VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+			/* does this mac address already exist in da table? */
+			status = vxge_search_mac_addr_in_da_table(vpath,
+				&mac_info);
+			if (status != VXGE_HW_OK) {
+				/* Add this mac address to the DA table */
+				status = vxge_hw_vpath_mac_addr_add(
+					vpath->handle, mac_info.macaddr,
+					mac_info.macmask,
+				    VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE);
+				if (status != VXGE_HW_OK) {
+					vxge_debug_init(VXGE_ERR,
+					    "DA add entry failed for vpath:%d",
+					    vpath->device_id);
+					((struct vxge_mac_addrs *)entry)->state
+						= VXGE_LL_MAC_ADDR_IN_LIST;
+				}
+			}
+		}
+	}
+
+	return status;
+}
+
+/* reset vpaths */
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
+{
+	int i;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	for (i = 0; i < vdev->no_of_vpath; i++)
+		if (vdev->vpaths[i].handle) {
+			if (vxge_hw_vpath_reset(vdev->vpaths[i].handle)
+					== VXGE_HW_OK) {
+				if (is_vxge_card_up(vdev) &&
+					vxge_hw_vpath_recover_from_reset(
+						vdev->vpaths[i].handle)
+						!= VXGE_HW_OK) {
+					vxge_debug_init(VXGE_ERR,
+						"vxge_hw_vpath_recover_"
+						"from_reset failed for vpath: "
+						"%d", i);
+					return status;
+				}
+			} else {
+				vxge_debug_init(VXGE_ERR,
+					"vxge_hw_vpath_reset failed for "
+					"vpath:%d", i);
+					return status;
+			}
+		}
+	return status;
+}
+
+/* close vpaths */
+void vxge_close_vpaths(struct vxgedev *vdev, int index)
+{
+	int i;
+	for (i = index; i < vdev->no_of_vpath; i++) {
+		if (vdev->vpaths[i].handle && vdev->vpaths[i].is_open) {
+			vxge_hw_vpath_close(vdev->vpaths[i].handle);
+			vdev->stats.vpaths_open--;
+		}
+		vdev->vpaths[i].is_open = 0;
+		vdev->vpaths[i].handle  = NULL;
+	}
+}
+
+/* open vpaths */
+int vxge_open_vpaths(struct vxgedev *vdev)
+{
+	enum vxge_hw_status status;
+	int i;
+	u32 vp_id = 0;
+	struct vxge_hw_vpath_attr attr;
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		vxge_assert(vdev->vpaths[i].is_configured);
+		attr.vp_id = vdev->vpaths[i].device_id;
+		attr.fifo_attr.callback = vxge_xmit_compl;
+		attr.fifo_attr.txdl_term = vxge_tx_term;
+		attr.fifo_attr.per_txdl_space = sizeof(struct vxge_tx_priv);
+		attr.fifo_attr.userdata = (void *)&vdev->vpaths[i].fifo;
+
+		attr.ring_attr.callback = vxge_rx_1b_compl;
+		attr.ring_attr.rxd_init = vxge_rx_initial_replenish;
+		attr.ring_attr.rxd_term = vxge_rx_term;
+		attr.ring_attr.per_rxd_space = sizeof(struct vxge_rx_priv);
+		attr.ring_attr.userdata = (void *)&vdev->vpaths[i].ring;
+
+		vdev->vpaths[i].ring.ndev = vdev->ndev;
+		vdev->vpaths[i].ring.pdev = vdev->pdev;
+		status = vxge_hw_vpath_open(vdev->devh, &attr,
+				&(vdev->vpaths[i].handle));
+		if (status == VXGE_HW_OK) {
+			vdev->vpaths[i].fifo.handle =
+			    (struct __vxge_hw_fifo *)attr.fifo_attr.userdata;
+			vdev->vpaths[i].ring.handle =
+			    (struct __vxge_hw_ring *)attr.ring_attr.userdata;
+			vdev->vpaths[i].fifo.tx_steering_type =
+				vdev->config.tx_steering_type;
+			vdev->vpaths[i].fifo.ndev = vdev->ndev;
+			vdev->vpaths[i].fifo.pdev = vdev->pdev;
+			vdev->vpaths[i].fifo.indicate_max_pkts =
+				vdev->config.fifo_indicate_max_pkts;
+			vdev->vpaths[i].ring.rx_vector_no = 0;
+			vdev->vpaths[i].ring.rx_csum = vdev->rx_csum;
+			vdev->vpaths[i].is_open = 1;
+			vdev->vp_handles[i] = vdev->vpaths[i].handle;
+			vdev->vpaths[i].ring.gro_enable =
+						vdev->config.gro_enable;
+			vdev->vpaths[i].ring.vlan_tag_strip =
+						vdev->vlan_tag_strip;
+			vdev->stats.vpaths_open++;
+		} else {
+			vdev->stats.vpath_open_fail++;
+			vxge_debug_init(VXGE_ERR,
+				"%s: vpath: %d failed to open "
+				"with status: %d",
+			    vdev->ndev->name, vdev->vpaths[i].device_id,
+				status);
+			vxge_close_vpaths(vdev, 0);
+			return -EPERM;
+		}
+
+		vp_id =
+		  ((struct __vxge_hw_vpath_handle *)vdev->vpaths[i].handle)->
+		  vpath->vp_id;
+		vdev->vpaths_deployed |= vxge_mBIT(vp_id);
+	}
+	return VXGE_HW_OK;
+}
+
+/*
+ *  vxge_isr_napi
+ *  @irq: the irq of the device.
+ *  @dev_id: a void pointer to the hldev structure of the Titan device
+ *  @ptregs: pointer to the registers pushed on the stack.
+ *
+ *  This function is the ISR handler of the device when napi is enabled. It
+ *  identifies the reason for the interrupt and calls the relevant service
+ *  routines.
+ */
+static irqreturn_t vxge_isr_napi(int irq, void *dev_id)
+{
+	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device  *)dev_id;
+	struct vxgedev *vdev;
+	struct net_device *dev;
+	u64 reason;
+	enum vxge_hw_status status;
+
+	vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	dev = hldev->ndev;
+	vdev = netdev_priv(dev);
+
+	if (pci_channel_offline(vdev->pdev))
+		return IRQ_NONE;
+
+	if (unlikely(!is_vxge_card_up(vdev)))
+		return IRQ_NONE;
+
+	status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode,
+			&reason);
+	if (status == VXGE_HW_OK) {
+		vxge_hw_device_mask_all(hldev);
+
+		if (reason &
+			VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(
+			vdev->vpaths_deployed >>
+			(64 - VXGE_HW_MAX_VIRTUAL_PATHS))) {
+
+			vxge_hw_device_clear_tx_rx(hldev);
+			napi_schedule(&vdev->napi);
+			vxge_debug_intr(VXGE_TRACE,
+				"%s:%d  Exiting...", __func__, __LINE__);
+			return IRQ_HANDLED;
+		} else
+			vxge_hw_device_unmask_all(hldev);
+	} else if (unlikely((status == VXGE_HW_ERR_VPATH) ||
+		(status == VXGE_HW_ERR_CRITICAL) ||
+		(status == VXGE_HW_ERR_FIFO))) {
+		vxge_hw_device_mask_all(hldev);
+		vxge_hw_device_flush_io(hldev);
+		return IRQ_HANDLED;
+	} else if (unlikely(status == VXGE_HW_ERR_SLOT_FREEZE))
+		return IRQ_HANDLED;
+
+	vxge_debug_intr(VXGE_TRACE, "%s:%d  Exiting...", __func__, __LINE__);
+	return IRQ_NONE;
+}
+
+#ifdef CONFIG_PCI_MSI
+
+static irqreturn_t
+vxge_tx_msix_handle(int irq, void *dev_id)
+{
+	struct vxge_fifo *fifo = (struct vxge_fifo *)dev_id;
+
+	VXGE_COMPLETE_VPATH_TX(fifo);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+vxge_rx_msix_napi_handle(int irq, void *dev_id)
+{
+	struct vxge_ring *ring = (struct vxge_ring *)dev_id;
+
+	/* MSIX_IDX for Rx is 1 */
+	vxge_hw_channel_msix_mask((struct __vxge_hw_channel *)ring->handle,
+					ring->rx_vector_no);
+
+	napi_schedule(&ring->napi);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+vxge_alarm_msix_handle(int irq, void *dev_id)
+{
+	int i;
+	enum vxge_hw_status status;
+	struct vxge_vpath *vpath = (struct vxge_vpath *)dev_id;
+	struct vxgedev *vdev = vpath->vdev;
+	int alarm_msix_id =
+		VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		vxge_hw_vpath_msix_mask(vdev->vpaths[i].handle,
+			alarm_msix_id);
+
+		status = vxge_hw_vpath_alarm_process(vdev->vpaths[i].handle,
+			vdev->exec_mode);
+		if (status == VXGE_HW_OK) {
+
+			vxge_hw_vpath_msix_unmask(vdev->vpaths[i].handle,
+				alarm_msix_id);
+			continue;
+		}
+		vxge_debug_intr(VXGE_ERR,
+			"%s: vxge_hw_vpath_alarm_process failed %x ",
+			VXGE_DRIVER_NAME, status);
+	}
+	return IRQ_HANDLED;
+}
+
+static int vxge_alloc_msix(struct vxgedev *vdev)
+{
+	int j, i, ret = 0;
+	int intr_cnt = 0;
+	int alarm_msix_id = 0, msix_intr_vect = 0;
+	vdev->intr_cnt = 0;
+
+	/* Tx/Rx MSIX Vectors count */
+	vdev->intr_cnt = vdev->no_of_vpath * 2;
+
+	/* Alarm MSIX Vectors count */
+	vdev->intr_cnt++;
+
+	intr_cnt = (vdev->max_vpath_supported * 2) + 1;
+	vdev->entries = kzalloc(intr_cnt * sizeof(struct msix_entry),
+						GFP_KERNEL);
+	if (!vdev->entries) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: memory allocation failed",
+			VXGE_DRIVER_NAME);
+		return  -ENOMEM;
+	}
+
+	vdev->vxge_entries = kzalloc(intr_cnt * sizeof(struct vxge_msix_entry),
+							GFP_KERNEL);
+	if (!vdev->vxge_entries) {
+		vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
+			VXGE_DRIVER_NAME);
+		kfree(vdev->entries);
+		return -ENOMEM;
+	}
+
+	/* Last vector in the list is used for alarm */
+	alarm_msix_id = VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+	for (i = 0, j = 0; i < vdev->max_vpath_supported; i++) {
+
+		msix_intr_vect = i * VXGE_HW_VPATH_MSIX_ACTIVE;
+
+		/* Initialize the fifo vector */
+		vdev->entries[j].entry = msix_intr_vect;
+		vdev->vxge_entries[j].entry = msix_intr_vect;
+		vdev->vxge_entries[j].in_use = 0;
+		j++;
+
+		/* Initialize the ring vector */
+		vdev->entries[j].entry = msix_intr_vect + 1;
+		vdev->vxge_entries[j].entry = msix_intr_vect + 1;
+		vdev->vxge_entries[j].in_use = 0;
+		j++;
+	}
+
+	/* Initialize the alarm vector */
+	vdev->entries[j].entry = alarm_msix_id;
+	vdev->vxge_entries[j].entry = alarm_msix_id;
+	vdev->vxge_entries[j].in_use = 0;
+
+	ret = pci_enable_msix(vdev->pdev, vdev->entries, intr_cnt);
+	/* if driver request exceeeds available irq's, request with a small
+	 * number.
+	*/
+	if (ret > 0) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: MSI-X enable failed for %d vectors, available: %d",
+			VXGE_DRIVER_NAME, intr_cnt, ret);
+		vdev->max_vpath_supported = vdev->no_of_vpath;
+		intr_cnt = (vdev->max_vpath_supported * 2) + 1;
+
+		/* Reset the alarm vector setting */
+		vdev->entries[j].entry = 0;
+		vdev->vxge_entries[j].entry = 0;
+
+		/* Initialize the alarm vector with new setting */
+		vdev->entries[intr_cnt - 1].entry = alarm_msix_id;
+		vdev->vxge_entries[intr_cnt - 1].entry = alarm_msix_id;
+		vdev->vxge_entries[intr_cnt - 1].in_use = 0;
+
+		ret = pci_enable_msix(vdev->pdev, vdev->entries, intr_cnt);
+		if (!ret)
+			vxge_debug_init(VXGE_ERR,
+				"%s: MSI-X enabled for %d vectors",
+				VXGE_DRIVER_NAME, intr_cnt);
+	}
+
+	if (ret) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: MSI-X enable failed for %d vectors, ret: %d",
+			VXGE_DRIVER_NAME, intr_cnt, ret);
+		kfree(vdev->entries);
+		kfree(vdev->vxge_entries);
+		vdev->entries = NULL;
+		vdev->vxge_entries = NULL;
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int vxge_enable_msix(struct vxgedev *vdev)
+{
+
+	int i, ret = 0;
+	enum vxge_hw_status status;
+	/* 0 - Tx, 1 - Rx  */
+	int tim_msix_id[4];
+	int alarm_msix_id = 0, msix_intr_vect = 0;;
+	vdev->intr_cnt = 0;
+
+	/* allocate msix vectors */
+	ret = vxge_alloc_msix(vdev);
+	if (!ret) {
+		/* Last vector in the list is used for alarm */
+		alarm_msix_id =
+			VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+
+			/* If fifo or ring are not enabled
+			   the MSIX vector for that should be set to 0
+			   Hence initializeing this array to all 0s.
+			*/
+			memset(tim_msix_id, 0, sizeof(tim_msix_id));
+			msix_intr_vect = i * VXGE_HW_VPATH_MSIX_ACTIVE;
+			tim_msix_id[0] = msix_intr_vect;
+
+			tim_msix_id[1] = msix_intr_vect + 1;
+			vdev->vpaths[i].ring.rx_vector_no = tim_msix_id[1];
+
+			status = vxge_hw_vpath_msix_set(
+						vdev->vpaths[i].handle,
+						tim_msix_id, alarm_msix_id);
+			if (status != VXGE_HW_OK) {
+				vxge_debug_init(VXGE_ERR,
+					"vxge_hw_vpath_msix_set "
+					"failed with status : %x", status);
+				kfree(vdev->entries);
+				kfree(vdev->vxge_entries);
+				pci_disable_msix(vdev->pdev);
+				return -ENODEV;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static void vxge_rem_msix_isr(struct vxgedev *vdev)
+{
+	int intr_cnt;
+
+	for (intr_cnt = 0; intr_cnt < (vdev->max_vpath_supported * 2 + 1);
+		intr_cnt++) {
+		if (vdev->vxge_entries[intr_cnt].in_use) {
+			synchronize_irq(vdev->entries[intr_cnt].vector);
+			free_irq(vdev->entries[intr_cnt].vector,
+				vdev->vxge_entries[intr_cnt].arg);
+			vdev->vxge_entries[intr_cnt].in_use = 0;
+		}
+	}
+
+	kfree(vdev->entries);
+	kfree(vdev->vxge_entries);
+	vdev->entries = NULL;
+	vdev->vxge_entries = NULL;
+
+	if (vdev->config.intr_type == MSI_X)
+		pci_disable_msix(vdev->pdev);
+}
+#endif
+
+static void vxge_rem_isr(struct vxgedev *vdev)
+{
+	struct __vxge_hw_device  *hldev;
+	hldev = (struct __vxge_hw_device  *) pci_get_drvdata(vdev->pdev);
+
+#ifdef CONFIG_PCI_MSI
+	if (vdev->config.intr_type == MSI_X) {
+		vxge_rem_msix_isr(vdev);
+	} else
+#endif
+	if (vdev->config.intr_type == INTA) {
+			synchronize_irq(vdev->pdev->irq);
+			free_irq(vdev->pdev->irq, hldev);
+	}
+}
+
+static int vxge_add_isr(struct vxgedev *vdev)
+{
+	int ret = 0;
+	struct __vxge_hw_device  *hldev =
+		(struct __vxge_hw_device  *) pci_get_drvdata(vdev->pdev);
+#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)
+		ret = vxge_enable_msix(vdev);
+
+	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;
+		}
+	}
+
+	if (vdev->config.intr_type == MSI_X) {
+		for (intr_idx = 0;
+		     intr_idx < (vdev->no_of_vpath *
+			VXGE_HW_VPATH_MSIX_ACTIVE); intr_idx++) {
+
+			msix_idx = intr_idx % VXGE_HW_VPATH_MSIX_ACTIVE;
+			irq_req = 0;
+
+			switch (msix_idx) {
+			case 0:
+				snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+					"%s:vxge fn: %d vpath: %d Tx MSI-X: %d",
+					vdev->ndev->name, pci_fun, vp_idx,
+					vdev->entries[intr_cnt].entry);
+				ret = request_irq(
+				    vdev->entries[intr_cnt].vector,
+					vxge_tx_msix_handle, 0,
+					vdev->desc[intr_cnt],
+					&vdev->vpaths[vp_idx].fifo);
+					vdev->vxge_entries[intr_cnt].arg =
+						&vdev->vpaths[vp_idx].fifo;
+				irq_req = 1;
+				break;
+			case 1:
+				snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+					"%s:vxge fn: %d vpath: %d Rx MSI-X: %d",
+					vdev->ndev->name, pci_fun, vp_idx,
+					vdev->entries[intr_cnt].entry);
+				ret = request_irq(
+				    vdev->entries[intr_cnt].vector,
+					vxge_rx_msix_napi_handle,
+					0,
+					vdev->desc[intr_cnt],
+					&vdev->vpaths[vp_idx].ring);
+					vdev->vxge_entries[intr_cnt].arg =
+						&vdev->vpaths[vp_idx].ring;
+				irq_req = 1;
+				break;
+			}
+
+			if (ret) {
+				vxge_debug_init(VXGE_ERR,
+					"%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;
+					goto INTA_MODE;
+				}
+			}
+
+			if (irq_req) {
+				/* We requested for this msix interrupt */
+				vdev->vxge_entries[intr_cnt].in_use = 1;
+				vxge_hw_vpath_msix_unmask(
+					vdev->vpaths[vp_idx].handle,
+					intr_idx);
+				intr_cnt++;
+			}
+
+			/* Point to next vpath handler */
+			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;
+		snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+			"%s:vxge Alarm fn: %d MSI-X: %d",
+			vdev->ndev->name, pci_fun,
+			vdev->entries[intr_cnt].entry);
+		/* For Alarm interrupts */
+		ret = request_irq(vdev->entries[intr_cnt].vector,
+					vxge_alarm_msix_handle, 0,
+					vdev->desc[intr_cnt],
+					&vdev->vpaths[vp_idx]);
+		if (ret) {
+			vxge_debug_init(VXGE_ERR,
+				"%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;
+				goto INTA_MODE;
+			}
+		}
+
+		vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle,
+					intr_idx - 2);
+		vdev->vxge_entries[intr_cnt].in_use = 1;
+		vdev->vxge_entries[intr_cnt].arg = &vdev->vpaths[vp_idx];
+	}
+INTA_MODE:
+#endif
+	snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name);
+
+	if (vdev->config.intr_type == INTA) {
+		ret = request_irq((int) vdev->pdev->irq,
+			vxge_isr_napi,
+			IRQF_SHARED, vdev->desc[0], hldev);
+		if (ret) {
+			vxge_debug_init(VXGE_ERR,
+				"%s %s-%d: ISR registration failed",
+				VXGE_DRIVER_NAME, "IRQ", vdev->pdev->irq);
+			return -ENODEV;
+		}
+		vxge_debug_init(VXGE_TRACE,
+			"new %s-%d line allocated",
+			"IRQ", vdev->pdev->irq);
+	}
+
+	return VXGE_HW_OK;
+}
+
+static void vxge_poll_vp_reset(unsigned long data)
+{
+	struct vxgedev *vdev = (struct vxgedev *)data;
+	int i, j = 0;
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		if (test_bit(i, &vdev->vp_reset)) {
+			vxge_reset_vpath(vdev, i);
+			j++;
+		}
+	}
+	if (j && (vdev->config.intr_type != MSI_X)) {
+		vxge_hw_device_unmask_all(vdev->devh);
+		vxge_hw_device_flush_io(vdev->devh);
+	}
+
+	mod_timer(&vdev->vp_reset_timer, jiffies + HZ / 2);
+}
+
+static void vxge_poll_vp_lockup(unsigned long data)
+{
+	struct vxgedev *vdev = (struct vxgedev *)data;
+	int i;
+	struct vxge_ring *ring;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		ring = &vdev->vpaths[i].ring;
+		/* Did this vpath received any packets */
+		if (ring->stats.prev_rx_frms == ring->stats.rx_frms) {
+			status = vxge_hw_vpath_check_leak(ring->handle);
+
+			/* Did it received any packets last time */
+			if ((VXGE_HW_FAIL == status) &&
+				(VXGE_HW_FAIL == ring->last_status)) {
+
+				/* schedule vpath reset */
+				if (!test_and_set_bit(i, &vdev->vp_reset)) {
+
+					/* disable interrupts for this vpath */
+					vxge_vpath_intr_disable(vdev, i);
+
+					/* stop the queue for this vpath */
+					vxge_stop_tx_queue(&vdev->vpaths[i].
+								fifo);
+					continue;
+				}
+			}
+		}
+		ring->stats.prev_rx_frms = ring->stats.rx_frms;
+		ring->last_status = status;
+	}
+
+	/* Check every 1 milli second */
+	mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
+}
+
+/**
+ * vxge_open
+ * @dev: pointer to the device structure.
+ *
+ * This function is the open entry point of the driver. It mainly calls a
+ * function to allocate Rx buffers and inserts them into the buffer
+ * descriptors and then enables the Rx part of the NIC.
+ * Return value: '0' on success and an appropriate (-)ve integer as
+ * defined in errno.h file on failure.
+ */
+int
+vxge_open(struct net_device *dev)
+{
+	enum vxge_hw_status status;
+	struct vxgedev *vdev;
+	struct __vxge_hw_device *hldev;
+	int ret = 0;
+	int i;
+	u64 val64, function_mode;
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s: %s:%d", dev->name, __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+	function_mode = vdev->config.device_hw_info.function_mode;
+
+	/* make sure you have link off by default every time Nic is
+	 * 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) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: fatal: Vpath open failed", vdev->ndev->name);
+		ret = -EPERM;
+		goto out0;
+	}
+
+	vdev->mtu = dev->mtu;
+
+	status = vxge_add_isr(vdev);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: fatal: ISR add failed", dev->name);
+		ret = -EPERM;
+		goto out1;
+	}
+
+
+	if (vdev->config.intr_type != MSI_X) {
+		netif_napi_add(dev, &vdev->napi, vxge_poll_inta,
+			vdev->config.napi_weight);
+		napi_enable(&vdev->napi);
+	} else {
+		for (i = 0; i < vdev->no_of_vpath; i++) {
+			netif_napi_add(dev, &vdev->vpaths[i].ring.napi,
+			    vxge_poll_msix, vdev->config.napi_weight);
+			napi_enable(&vdev->vpaths[i].ring.napi);
+		}
+	}
+
+	/* configure RTH */
+	if (vdev->config.rth_steering) {
+		status = vxge_rth_configure(vdev);
+		if (status != VXGE_HW_OK) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: fatal: RTH configuration failed",
+				dev->name);
+			ret = -EPERM;
+			goto out2;
+		}
+	}
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		/* set initial mtu before enabling the device */
+		status = vxge_hw_vpath_mtu_set(vdev->vpaths[i].handle,
+						vdev->mtu);
+		if (status != VXGE_HW_OK) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: fatal: can not set new MTU", dev->name);
+			ret = -EPERM;
+			goto out2;
+		}
+	}
+
+	VXGE_DEVICE_DEBUG_LEVEL_SET(VXGE_TRACE, VXGE_COMPONENT_LL, vdev);
+	vxge_debug_init(vdev->level_trace,
+		"%s: MTU is %d", vdev->ndev->name, vdev->mtu);
+	VXGE_DEVICE_DEBUG_LEVEL_SET(VXGE_ERR, VXGE_COMPONENT_LL, vdev);
+
+	/* Reprogram the DA table with populated mac addresses */
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		vxge_restore_vpath_mac_addr(&vdev->vpaths[i]);
+		vxge_restore_vpath_vid_table(&vdev->vpaths[i]);
+	}
+
+	/* Enable vpath to sniff all unicast/multicast traffic that not
+	 * addressed to them. We allow promiscous mode for PF only
+	 */
+
+	val64 = 0;
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+		val64 |= VXGE_HW_RXMAC_AUTHORIZE_ALL_ADDR_VP(i);
+
+	vxge_hw_mgmt_reg_write(vdev->devh,
+		vxge_hw_mgmt_reg_type_mrpcim,
+		0,
+		(ulong)offsetof(struct vxge_hw_mrpcim_reg,
+			rxmac_authorize_all_addr),
+		val64);
+
+	vxge_hw_mgmt_reg_write(vdev->devh,
+		vxge_hw_mgmt_reg_type_mrpcim,
+		0,
+		(ulong)offsetof(struct vxge_hw_mrpcim_reg,
+			rxmac_authorize_all_vid),
+		val64);
+
+	vxge_set_multicast(dev);
+
+	/* Enabling Bcast and mcast for all vpath */
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		status = vxge_hw_vpath_bcast_enable(vdev->vpaths[i].handle);
+		if (status != VXGE_HW_OK)
+			vxge_debug_init(VXGE_ERR,
+				"%s : Can not enable bcast for vpath "
+				"id %d", dev->name, i);
+		if (vdev->config.addr_learn_en) {
+			status =
+			    vxge_hw_vpath_mcast_enable(vdev->vpaths[i].handle);
+			if (status != VXGE_HW_OK)
+				vxge_debug_init(VXGE_ERR,
+					"%s : Can not enable mcast for vpath "
+					"id %d", dev->name, i);
+		}
+	}
+
+	vxge_hw_device_setpause_data(vdev->devh, 0,
+		vdev->config.tx_pause_enable,
+		vdev->config.rx_pause_enable);
+
+	if (vdev->vp_reset_timer.function == NULL)
+		vxge_os_timer(vdev->vp_reset_timer,
+			vxge_poll_vp_reset, vdev, (HZ/2));
+
+	if (vdev->vp_lockup_timer.function == NULL)
+		vxge_os_timer(vdev->vp_lockup_timer,
+			vxge_poll_vp_lockup, vdev, (HZ/2));
+
+	set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+
+	smp_wmb();
+
+	if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) {
+		netif_carrier_on(vdev->ndev);
+		printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
+		vdev->stats.link_up++;
+	}
+
+	vxge_hw_device_intr_enable(vdev->devh);
+
+	smp_wmb();
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		vxge_hw_vpath_enable(vdev->vpaths[i].handle);
+		smp_wmb();
+		vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
+	}
+
+	vxge_start_all_tx_queue(vdev);
+	goto out0;
+
+out2:
+	vxge_rem_isr(vdev);
+
+	/* Disable napi */
+	if (vdev->config.intr_type != MSI_X)
+		napi_disable(&vdev->napi);
+	else {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			napi_disable(&vdev->vpaths[i].ring.napi);
+	}
+
+out1:
+	vxge_close_vpaths(vdev, 0);
+out0:
+	vxge_debug_entryexit(VXGE_TRACE,
+				"%s: %s:%d  Exiting...",
+				dev->name, __func__, __LINE__);
+	return ret;
+}
+
+/* Loop throught the mac address list and delete all the entries */
+void vxge_free_mac_add_list(struct vxge_vpath *vpath)
+{
+
+	struct list_head *entry, *next;
+	if (list_empty(&vpath->mac_addr_list))
+		return;
+
+	list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+		list_del(entry);
+		kfree((struct vxge_mac_addrs *)entry);
+	}
+}
+
+static void vxge_napi_del_all(struct vxgedev *vdev)
+{
+	int i;
+	if (vdev->config.intr_type != MSI_X)
+		netif_napi_del(&vdev->napi);
+	else {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			netif_napi_del(&vdev->vpaths[i].ring.napi);
+	}
+	return;
+}
+
+int do_vxge_close(struct net_device *dev, int do_io)
+{
+	enum vxge_hw_status status;
+	struct vxgedev *vdev;
+	struct __vxge_hw_device *hldev;
+	int i;
+	u64 val64, vpath_vector;
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+		dev->name, __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+	hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+
+	/* If vxge_handle_crit_err task is executing,
+	 * wait till it completes. */
+	while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+		msleep(50);
+
+	clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+	if (do_io) {
+		/* Put the vpath back in normal mode */
+		vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id);
+		status = vxge_hw_mgmt_reg_read(vdev->devh,
+				vxge_hw_mgmt_reg_type_mrpcim,
+				0,
+				(ulong)offsetof(
+					struct vxge_hw_mrpcim_reg,
+					rts_mgr_cbasin_cfg),
+				&val64);
+
+		if (status == VXGE_HW_OK) {
+			val64 &= ~vpath_vector;
+			status = vxge_hw_mgmt_reg_write(vdev->devh,
+					vxge_hw_mgmt_reg_type_mrpcim,
+					0,
+					(ulong)offsetof(
+						struct vxge_hw_mrpcim_reg,
+						rts_mgr_cbasin_cfg),
+					val64);
+		}
+
+		/* Remove the function 0 from promiscous mode */
+		vxge_hw_mgmt_reg_write(vdev->devh,
+			vxge_hw_mgmt_reg_type_mrpcim,
+			0,
+			(ulong)offsetof(struct vxge_hw_mrpcim_reg,
+				rxmac_authorize_all_addr),
+			0);
+
+		vxge_hw_mgmt_reg_write(vdev->devh,
+			vxge_hw_mgmt_reg_type_mrpcim,
+			0,
+			(ulong)offsetof(struct vxge_hw_mrpcim_reg,
+				rxmac_authorize_all_vid),
+			0);
+
+		smp_wmb();
+	}
+	del_timer_sync(&vdev->vp_lockup_timer);
+
+	del_timer_sync(&vdev->vp_reset_timer);
+
+	/* Disable napi */
+	if (vdev->config.intr_type != MSI_X)
+		napi_disable(&vdev->napi);
+	else {
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			napi_disable(&vdev->vpaths[i].ring.napi);
+	}
+
+	netif_carrier_off(vdev->ndev);
+	printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
+	vxge_stop_all_tx_queue(vdev);
+
+	/* Note that at this point xmit() is stopped by upper layer */
+	if (do_io)
+		vxge_hw_device_intr_disable(vdev->devh);
+
+	mdelay(1000);
+
+	vxge_rem_isr(vdev);
+
+	vxge_napi_del_all(vdev);
+
+	if (do_io)
+		vxge_reset_all_vpaths(vdev);
+
+	vxge_close_vpaths(vdev, 0);
+
+	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;
+}
+
+/**
+ * vxge_close
+ * @dev: device pointer.
+ *
+ * This is the stop entry point of the driver. It needs to undo exactly
+ * whatever was done by the open entry point, thus it's usually referred to
+ * as the close function.Among other things this function mainly stops the
+ * Rx side of the NIC and frees all the Rx buffers in the Rx rings.
+ * Return value: '0' on success and an appropriate (-)ve integer as
+ * defined in errno.h file on failure.
+ */
+int
+vxge_close(struct net_device *dev)
+{
+	do_vxge_close(dev, 1);
+	return 0;
+}
+
+/**
+ * vxge_change_mtu
+ * @dev: net device pointer.
+ * @new_mtu :the new MTU size for the device.
+ *
+ * A driver entry point to change MTU size for the device. Before changing
+ * the MTU the device must be stopped.
+ */
+static int vxge_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct vxgedev *vdev = netdev_priv(dev);
+
+	vxge_debug_entryexit(vdev->level_trace,
+		"%s:%d", __func__, __LINE__);
+	if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > VXGE_HW_MAX_MTU)) {
+		vxge_debug_init(vdev->level_err,
+			"%s: mtu size is invalid", dev->name);
+		return -EPERM;
+	}
+
+	/* check if device is down already */
+	if (unlikely(!is_vxge_card_up(vdev))) {
+		/* just store new value, will use later on open() */
+		dev->mtu = new_mtu;
+		vxge_debug_init(vdev->level_err,
+			"%s", "device is down on MTU change");
+		return 0;
+	}
+
+	vxge_debug_init(vdev->level_trace,
+		"trying to apply new MTU %d", new_mtu);
+
+	if (vxge_close(dev))
+		return -EIO;
+
+	dev->mtu = new_mtu;
+	vdev->mtu = new_mtu;
+
+	if (vxge_open(dev))
+		return -EIO;
+
+	vxge_debug_init(vdev->level_trace,
+		"%s: MTU changed to %d", vdev->ndev->name, new_mtu);
+
+	vxge_debug_entryexit(vdev->level_trace,
+		"%s:%d  Exiting...", __func__, __LINE__);
+
+	return 0;
+}
+
+/**
+ * vxge_get_stats
+ * @dev: pointer to the device structure
+ *
+ * Updates the device statistics structure. This function updates the device
+ * statistics structure in the net_device structure and returns a pointer
+ * to the same.
+ */
+static struct net_device_stats *
+vxge_get_stats(struct net_device *dev)
+{
+	struct vxgedev *vdev;
+	struct net_device_stats *net_stats;
+	int k;
+
+	vdev = netdev_priv(dev);
+
+	net_stats = &vdev->stats.net_stats;
+
+	memset(net_stats, 0, sizeof(struct net_device_stats));
+
+	for (k = 0; k < vdev->no_of_vpath; k++) {
+		net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms;
+		net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
+		net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors;
+		net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast;
+		net_stats->rx_dropped +=
+			vdev->vpaths[k].ring.stats.rx_dropped;
+
+		net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms;
+		net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes;
+		net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors;
+	}
+
+	return net_stats;
+}
+
+/**
+ * vxge_ioctl
+ * @dev: Device pointer.
+ * @ifr: An IOCTL specific structure, that can contain a pointer to
+ *       a proprietary structure used to pass information to the driver.
+ * @cmd: This is used to distinguish between the different commands that
+ *       can be passed to the IOCTL functions.
+ *
+ * Entry point for the Ioctl.
+ */
+static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * vxge_tx_watchdog
+ * @dev: pointer to net device structure
+ *
+ * Watchdog for transmit side.
+ * This function is triggered if the Tx Queue is stopped
+ * for a pre-defined amount of time when the Interface is still up.
+ */
+static void
+vxge_tx_watchdog(struct net_device *dev)
+{
+	struct vxgedev *vdev;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+
+	vdev->cric_err_event = VXGE_HW_EVENT_RESET_START;
+
+	vxge_reset(vdev);
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_vlan_rx_register
+ * @dev: net device pointer.
+ * @grp: vlan group
+ *
+ * Vlan group registration
+ */
+static void
+vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct vxgedev *vdev;
+	struct vxge_vpath *vpath;
+	int vp;
+	u64 vid;
+	enum vxge_hw_status status;
+	int i;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+
+	vpath = &vdev->vpaths[0];
+	if ((NULL == grp) && (vpath->is_open)) {
+		/* Get the first vlan */
+		status = vxge_hw_vpath_vid_get(vpath->handle, &vid);
+
+		while (status == VXGE_HW_OK) {
+
+			/* Delete this vlan from the vid table */
+			for (vp = 0; vp < vdev->no_of_vpath; vp++) {
+				vpath = &vdev->vpaths[vp];
+				if (!vpath->is_open)
+					continue;
+
+				vxge_hw_vpath_vid_delete(vpath->handle, vid);
+			}
+
+			/* Get the next vlan to be deleted */
+			vpath = &vdev->vpaths[0];
+			status = vxge_hw_vpath_vid_get(vpath->handle, &vid);
+		}
+	}
+
+	vdev->vlgrp = grp;
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		if (vdev->vpaths[i].is_configured)
+			vdev->vpaths[i].ring.vlgrp = grp;
+	}
+
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_vlan_rx_add_vid
+ * @dev: net device pointer.
+ * @vid: vid
+ *
+ * Add the vlan id to the devices vlan id table
+ */
+static void
+vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+	struct vxgedev *vdev;
+	struct vxge_vpath *vpath;
+	int vp_id;
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+
+	/* Add these vlan to the vid table */
+	for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+		vpath = &vdev->vpaths[vp_id];
+		if (!vpath->is_open)
+			continue;
+		vxge_hw_vpath_vid_add(vpath->handle, vid);
+	}
+}
+
+/**
+ * vxge_vlan_rx_add_vid
+ * @dev: net device pointer.
+ * @vid: vid
+ *
+ * Remove the vlan id from the device's vlan id table
+ */
+static void
+vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct vxgedev *vdev;
+	struct vxge_vpath *vpath;
+	int vp_id;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+	vdev = (struct vxgedev *)netdev_priv(dev);
+
+	vlan_group_set_device(vdev->vlgrp, vid, NULL);
+
+	/* Delete this vlan from the vid table */
+	for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+		vpath = &vdev->vpaths[vp_id];
+		if (!vpath->is_open)
+			continue;
+		vxge_hw_vpath_vid_delete(vpath->handle, vid);
+	}
+	vxge_debug_entryexit(VXGE_TRACE,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+static const struct net_device_ops vxge_netdev_ops = {
+	.ndo_open               = vxge_open,
+	.ndo_stop               = vxge_close,
+	.ndo_get_stats          = vxge_get_stats,
+	.ndo_start_xmit         = vxge_xmit,
+	.ndo_validate_addr      = eth_validate_addr,
+	.ndo_set_multicast_list = vxge_set_multicast,
+
+	.ndo_do_ioctl           = vxge_ioctl,
+
+	.ndo_set_mac_address    = vxge_set_mac_addr,
+	.ndo_change_mtu         = vxge_change_mtu,
+	.ndo_vlan_rx_register   = vxge_vlan_rx_register,
+	.ndo_vlan_rx_kill_vid   = vxge_vlan_rx_kill_vid,
+	.ndo_vlan_rx_add_vid	= vxge_vlan_rx_add_vid,
+
+	.ndo_tx_timeout         = vxge_tx_watchdog,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller    = vxge_netpoll,
+#endif
+};
+
+int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
+				   struct vxge_config *config,
+				   int high_dma, int no_of_vpath,
+				   struct vxgedev **vdev_out)
+{
+	struct net_device *ndev;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxgedev *vdev;
+	int i, ret = 0, no_of_queue = 1;
+	u64 stat;
+
+	*vdev_out = NULL;
+	if (config->tx_steering_type == TX_MULTIQ_STEERING)
+		no_of_queue = no_of_vpath;
+
+	ndev = alloc_etherdev_mq(sizeof(struct vxgedev),
+			no_of_queue);
+	if (ndev == NULL) {
+		vxge_debug_init(
+			vxge_hw_device_trace_level_get(hldev),
+		"%s : device allocation failed", __func__);
+		ret = -ENODEV;
+		goto _out0;
+	}
+
+	vxge_debug_entryexit(
+		vxge_hw_device_trace_level_get(hldev),
+		"%s: %s:%d  Entering...",
+		ndev->name, __func__, __LINE__);
+
+	vdev = netdev_priv(ndev);
+	memset(vdev, 0, sizeof(struct vxgedev));
+
+	vdev->ndev = ndev;
+	vdev->devh = hldev;
+	vdev->pdev = hldev->pdev;
+	memcpy(&vdev->config, config, sizeof(struct vxge_config));
+	vdev->rx_csum = 1;	/* Enable Rx CSUM by default. */
+
+	SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
+
+	ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+				NETIF_F_HW_VLAN_FILTER;
+	/*  Driver entry points */
+	ndev->irq = vdev->pdev->irq;
+	ndev->base_addr = (unsigned long) hldev->bar0;
+
+	ndev->netdev_ops = &vxge_netdev_ops;
+
+	ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT;
+
+	initialize_ethtool_ops(ndev);
+
+	/* Allocate memory for vpath */
+	vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
+				no_of_vpath, GFP_KERNEL);
+	if (!vdev->vpaths) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: vpath memory allocation failed",
+			vdev->ndev->name);
+		ret = -ENODEV;
+		goto _out1;
+	}
+
+	ndev->features |= NETIF_F_SG;
+
+	ndev->features |= NETIF_F_HW_CSUM;
+	vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+		"%s : checksuming enabled", __func__);
+
+	if (high_dma) {
+		ndev->features |= NETIF_F_HIGHDMA;
+		vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+			"%s : using High DMA", __func__);
+	}
+
+	ndev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+
+	if (vdev->config.gro_enable)
+		ndev->features |= NETIF_F_GRO;
+
+	if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
+		ndev->real_num_tx_queues = no_of_vpath;
+
+#ifdef NETIF_F_LLTX
+	ndev->features |= NETIF_F_LLTX;
+#endif
+
+	for (i = 0; i < no_of_vpath; i++)
+		spin_lock_init(&vdev->vpaths[i].fifo.tx_lock);
+
+	if (register_netdev(ndev)) {
+		vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+			"%s: %s : device registration failed!",
+			ndev->name, __func__);
+		ret = -ENODEV;
+		goto _out2;
+	}
+
+	/*  Set the factory defined MAC address initially */
+	ndev->addr_len = ETH_ALEN;
+
+	/* Make Link state as off at this point, when the Link change
+	 * interrupt comes the state will be automatically changed to
+	 * the right state.
+	 */
+	netif_carrier_off(ndev);
+
+	vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+		"%s: Ethernet device registered",
+		ndev->name);
+
+	*vdev_out = vdev;
+
+	/* Resetting the Device stats */
+	status = vxge_hw_mrpcim_stats_access(
+				hldev,
+				VXGE_HW_STATS_OP_CLEAR_ALL_STATS,
+				0,
+				0,
+				&stat);
+
+	if (status == VXGE_HW_ERR_PRIVILAGED_OPEARATION)
+		vxge_debug_init(
+			vxge_hw_device_trace_level_get(hldev),
+			"%s: device stats clear returns"
+			"VXGE_HW_ERR_PRIVILAGED_OPEARATION", ndev->name);
+
+	vxge_debug_entryexit(vxge_hw_device_trace_level_get(hldev),
+		"%s: %s:%d  Exiting...",
+		ndev->name, __func__, __LINE__);
+
+	return ret;
+_out2:
+	kfree(vdev->vpaths);
+_out1:
+	free_netdev(ndev);
+_out0:
+	return ret;
+}
+
+/*
+ * vxge_device_unregister
+ *
+ * This function will unregister and free network device
+ */
+void
+vxge_device_unregister(struct __vxge_hw_device *hldev)
+{
+	struct vxgedev *vdev;
+	struct net_device *dev;
+	char buf[IFNAMSIZ];
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+	(VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+	u32 level_trace;
+#endif
+
+	dev = hldev->ndev;
+	vdev = netdev_priv(dev);
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+	(VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+	level_trace = vdev->level_trace;
+#endif
+	vxge_debug_entryexit(level_trace,
+		"%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+
+	memcpy(buf, vdev->ndev->name, IFNAMSIZ);
+
+	/* in 2.6 will call stop() if device is up */
+	unregister_netdev(dev);
+
+	flush_scheduled_work();
+
+	vxge_debug_init(level_trace, "%s: ethernet device unregistered", buf);
+	vxge_debug_entryexit(level_trace,
+		"%s: %s:%d  Exiting...", buf, __func__, __LINE__);
+}
+
+/*
+ * vxge_callback_crit_err
+ *
+ * This function is called by the alarm handler in interrupt context.
+ * Driver must analyze it based on the event type.
+ */
+static void
+vxge_callback_crit_err(struct __vxge_hw_device *hldev,
+			enum vxge_hw_event type, u64 vp_id)
+{
+	struct net_device *dev = hldev->ndev;
+	struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+	int vpath_idx;
+
+	vxge_debug_entryexit(vdev->level_trace,
+		"%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+
+	/* Note: This event type should be used for device wide
+	 * indications only - Serious errors, Slot freeze and critical errors
+	 */
+	vdev->cric_err_event = type;
+
+	for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++)
+		if (vdev->vpaths[vpath_idx].device_id == vp_id)
+			break;
+
+	if (!test_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) {
+		if (type == VXGE_HW_EVENT_SLOT_FREEZE) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: Slot is frozen", vdev->ndev->name);
+		} else if (type == VXGE_HW_EVENT_SERR) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: Encountered Serious Error",
+				vdev->ndev->name);
+		} else if (type == VXGE_HW_EVENT_CRITICAL_ERR)
+			vxge_debug_init(VXGE_ERR,
+				"%s: Encountered Critical Error",
+				vdev->ndev->name);
+	}
+
+	if ((type == VXGE_HW_EVENT_SERR) ||
+		(type == VXGE_HW_EVENT_SLOT_FREEZE)) {
+		if (unlikely(vdev->exec_mode))
+			clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+	} else if (type == VXGE_HW_EVENT_CRITICAL_ERR) {
+		vxge_hw_device_mask_all(hldev);
+		if (unlikely(vdev->exec_mode))
+			clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+	} else if ((type == VXGE_HW_EVENT_FIFO_ERR) ||
+		  (type == VXGE_HW_EVENT_VPATH_ERR)) {
+
+		if (unlikely(vdev->exec_mode))
+			clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+		else {
+			/* check if this vpath is already set for reset */
+			if (!test_and_set_bit(vpath_idx, &vdev->vp_reset)) {
+
+				/* disable interrupts for this vpath */
+				vxge_vpath_intr_disable(vdev, vpath_idx);
+
+				/* stop the queue for this vpath */
+				vxge_stop_tx_queue(&vdev->vpaths[vpath_idx].
+							fifo);
+			}
+		}
+	}
+
+	vxge_debug_entryexit(vdev->level_trace,
+		"%s: %s:%d  Exiting...",
+		vdev->ndev->name, __func__, __LINE__);
+}
+
+static void verify_bandwidth(void)
+{
+	int i, band_width, total = 0, equal_priority = 0;
+
+	/* 1. If user enters 0 for some fifo, give equal priority to all */
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (bw_percentage[i] == 0) {
+			equal_priority = 1;
+			break;
+		}
+	}
+
+	if (!equal_priority) {
+		/* 2. If sum exceeds 100, give equal priority to all */
+		for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+			if (bw_percentage[i] == 0xFF)
+				break;
+
+			total += bw_percentage[i];
+			if (total > VXGE_HW_VPATH_BANDWIDTH_MAX) {
+				equal_priority = 1;
+				break;
+			}
+		}
+	}
+
+	if (!equal_priority) {
+		/* Is all the bandwidth consumed? */
+		if (total < VXGE_HW_VPATH_BANDWIDTH_MAX) {
+			if (i < VXGE_HW_MAX_VIRTUAL_PATHS) {
+				/* Split rest of bw equally among next VPs*/
+				band_width =
+				  (VXGE_HW_VPATH_BANDWIDTH_MAX  - total) /
+					(VXGE_HW_MAX_VIRTUAL_PATHS - i);
+				if (band_width < 2) /* min of 2% */
+					equal_priority = 1;
+				else {
+					for (; i < VXGE_HW_MAX_VIRTUAL_PATHS;
+						i++)
+						bw_percentage[i] =
+							band_width;
+				}
+			}
+		} else if (i < VXGE_HW_MAX_VIRTUAL_PATHS)
+			equal_priority = 1;
+	}
+
+	if (equal_priority) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: Assigning equal bandwidth to all the vpaths",
+			VXGE_DRIVER_NAME);
+		bw_percentage[0] = VXGE_HW_VPATH_BANDWIDTH_MAX /
+					VXGE_HW_MAX_VIRTUAL_PATHS;
+		for (i = 1; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+			bw_percentage[i] = bw_percentage[0];
+	}
+
+	return;
+}
+
+/*
+ * Vpath configuration
+ */
+static int __devinit vxge_config_vpaths(
+			struct vxge_hw_device_config *device_config,
+			u64 vpath_mask, struct vxge_config *config_param)
+{
+	int i, no_of_vpaths = 0, default_no_vpath = 0, temp;
+	u32 txdl_size, txdl_per_memblock;
+
+	temp = driver_config->vpath_per_dev;
+	if ((driver_config->vpath_per_dev == VXGE_USE_DEFAULT) &&
+		(max_config_dev == VXGE_MAX_CONFIG_DEV)) {
+		/* No more CPU. Return vpath number as zero.*/
+		if (driver_config->g_no_cpus == -1)
+			return 0;
+
+		if (!driver_config->g_no_cpus)
+			driver_config->g_no_cpus = num_online_cpus();
+
+		driver_config->vpath_per_dev = driver_config->g_no_cpus >> 1;
+		if (!driver_config->vpath_per_dev)
+			driver_config->vpath_per_dev = 1;
+
+		for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+			if (!vxge_bVALn(vpath_mask, i, 1))
+				continue;
+			else
+				default_no_vpath++;
+		if (default_no_vpath < driver_config->vpath_per_dev)
+			driver_config->vpath_per_dev = default_no_vpath;
+
+		driver_config->g_no_cpus = driver_config->g_no_cpus -
+				(driver_config->vpath_per_dev * 2);
+		if (driver_config->g_no_cpus <= 0)
+			driver_config->g_no_cpus = -1;
+	}
+
+	if (driver_config->vpath_per_dev == 1) {
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s: Disable tx and rx steering, "
+			"as single vpath is configured", VXGE_DRIVER_NAME);
+		config_param->rth_steering = NO_STEERING;
+		config_param->tx_steering_type = NO_STEERING;
+		device_config->rth_en = 0;
+	}
+
+	/* configure bandwidth */
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+		device_config->vp_config[i].min_bandwidth = bw_percentage[i];
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		device_config->vp_config[i].vp_id = i;
+		device_config->vp_config[i].mtu = VXGE_HW_DEFAULT_MTU;
+		if (no_of_vpaths < driver_config->vpath_per_dev) {
+			if (!vxge_bVALn(vpath_mask, i, 1)) {
+				vxge_debug_ll_config(VXGE_TRACE,
+					"%s: vpath: %d is not available",
+					VXGE_DRIVER_NAME, i);
+				continue;
+			} else {
+				vxge_debug_ll_config(VXGE_TRACE,
+					"%s: vpath: %d available",
+					VXGE_DRIVER_NAME, i);
+				no_of_vpaths++;
+			}
+		} else {
+			vxge_debug_ll_config(VXGE_TRACE,
+				"%s: vpath: %d is not configured, "
+				"max_config_vpath exceeded",
+				VXGE_DRIVER_NAME, i);
+			break;
+		}
+
+		/* Configure Tx fifo's */
+		device_config->vp_config[i].fifo.enable =
+						VXGE_HW_FIFO_ENABLE;
+		device_config->vp_config[i].fifo.max_frags =
+				MAX_SKB_FRAGS;
+		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_per_memblock = VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE / txdl_size;
+
+		device_config->vp_config[i].fifo.fifo_blocks =
+			((VXGE_DEF_FIFO_LENGTH - 1) / txdl_per_memblock) + 1;
+
+		device_config->vp_config[i].fifo.intr =
+				VXGE_HW_FIFO_QUEUE_INTR_DISABLE;
+
+		/* Configure tti properties */
+		device_config->vp_config[i].tti.intr_enable =
+					VXGE_HW_TIM_INTR_ENABLE;
+
+		device_config->vp_config[i].tti.btimer_val =
+			(VXGE_TTI_BTIMER_VAL * 1000) / 272;
+
+		device_config->vp_config[i].tti.timer_ac_en =
+				VXGE_HW_TIM_TIMER_AC_ENABLE;
+
+		/* For msi-x with napi (each vector
+		has a handler of its own) -
+		Set CI to OFF for all vpaths */
+		device_config->vp_config[i].tti.timer_ci_en =
+			VXGE_HW_TIM_TIMER_CI_DISABLE;
+
+		device_config->vp_config[i].tti.timer_ri_en =
+				VXGE_HW_TIM_TIMER_RI_DISABLE;
+
+		device_config->vp_config[i].tti.util_sel =
+			VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL;
+
+		device_config->vp_config[i].tti.ltimer_val =
+			(VXGE_TTI_LTIMER_VAL * 1000) / 272;
+
+		device_config->vp_config[i].tti.rtimer_val =
+			(VXGE_TTI_RTIMER_VAL * 1000) / 272;
+
+		device_config->vp_config[i].tti.urange_a = TTI_TX_URANGE_A;
+		device_config->vp_config[i].tti.urange_b = TTI_TX_URANGE_B;
+		device_config->vp_config[i].tti.urange_c = TTI_TX_URANGE_C;
+		device_config->vp_config[i].tti.uec_a = TTI_TX_UFC_A;
+		device_config->vp_config[i].tti.uec_b = TTI_TX_UFC_B;
+		device_config->vp_config[i].tti.uec_c = TTI_TX_UFC_C;
+		device_config->vp_config[i].tti.uec_d = TTI_TX_UFC_D;
+
+		/* Configure Rx rings */
+		device_config->vp_config[i].ring.enable  =
+						VXGE_HW_RING_ENABLE;
+
+		device_config->vp_config[i].ring.ring_blocks  =
+						VXGE_HW_DEF_RING_BLOCKS;
+		device_config->vp_config[i].ring.buffer_mode =
+			VXGE_HW_RING_RXD_BUFFER_MODE_1;
+		device_config->vp_config[i].ring.rxds_limit  =
+				VXGE_HW_DEF_RING_RXDS_LIMIT;
+		device_config->vp_config[i].ring.scatter_mode =
+					VXGE_HW_RING_SCATTER_MODE_A;
+
+		/* Configure rti properties */
+		device_config->vp_config[i].rti.intr_enable =
+					VXGE_HW_TIM_INTR_ENABLE;
+
+		device_config->vp_config[i].rti.btimer_val =
+			(VXGE_RTI_BTIMER_VAL * 1000)/272;
+
+		device_config->vp_config[i].rti.timer_ac_en =
+						VXGE_HW_TIM_TIMER_AC_ENABLE;
+
+		device_config->vp_config[i].rti.timer_ci_en =
+						VXGE_HW_TIM_TIMER_CI_DISABLE;
+
+		device_config->vp_config[i].rti.timer_ri_en =
+						VXGE_HW_TIM_TIMER_RI_DISABLE;
+
+		device_config->vp_config[i].rti.util_sel =
+				VXGE_HW_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL;
+
+		device_config->vp_config[i].rti.urange_a =
+						RTI_RX_URANGE_A;
+		device_config->vp_config[i].rti.urange_b =
+						RTI_RX_URANGE_B;
+		device_config->vp_config[i].rti.urange_c =
+						RTI_RX_URANGE_C;
+		device_config->vp_config[i].rti.uec_a = RTI_RX_UFC_A;
+		device_config->vp_config[i].rti.uec_b = RTI_RX_UFC_B;
+		device_config->vp_config[i].rti.uec_c = RTI_RX_UFC_C;
+		device_config->vp_config[i].rti.uec_d = RTI_RX_UFC_D;
+
+		device_config->vp_config[i].rti.rtimer_val =
+			(VXGE_RTI_RTIMER_VAL * 1000) / 272;
+
+		device_config->vp_config[i].rti.ltimer_val =
+			(VXGE_RTI_LTIMER_VAL * 1000) / 272;
+
+		device_config->vp_config[i].rpa_strip_vlan_tag =
+			vlan_tag_strip;
+	}
+
+	driver_config->vpath_per_dev = temp;
+	return no_of_vpaths;
+}
+
+/* initialize device configuratrions */
+static void __devinit vxge_device_config_init(
+				struct vxge_hw_device_config *device_config,
+				int *intr_type)
+{
+	/* Used for CQRQ/SRQ. */
+	device_config->dma_blockpool_initial =
+			VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
+
+	device_config->dma_blockpool_max =
+			VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
+
+	if (max_mac_vpath > VXGE_MAX_MAC_ADDR_COUNT)
+		max_mac_vpath = VXGE_MAX_MAC_ADDR_COUNT;
+
+#ifndef CONFIG_PCI_MSI
+	vxge_debug_init(VXGE_ERR,
+		"%s: This Kernel does not support "
+		"MSI-X. Defaulting to INTA", VXGE_DRIVER_NAME);
+	*intr_type = INTA;
+#endif
+
+	/* Configure whether MSI-X or IRQL. */
+	switch (*intr_type) {
+	case INTA:
+		device_config->intr_mode = VXGE_HW_INTR_MODE_IRQLINE;
+		break;
+
+	case MSI_X:
+		device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX;
+		break;
+	}
+	/* Timer period between device poll */
+	device_config->device_poll_millis = VXGE_TIMER_DELAY;
+
+	/* Configure mac based steering. */
+	device_config->rts_mac_en = addr_learn_en;
+
+	/* Configure Vpaths */
+	device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_MULTI_IT;
+
+	vxge_debug_ll_config(VXGE_TRACE, "%s : Device Config Params ",
+			__func__);
+	vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_initial : %d",
+			device_config->dma_blockpool_initial);
+	vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_max : %d",
+			device_config->dma_blockpool_max);
+	vxge_debug_ll_config(VXGE_TRACE, "intr_mode : %d",
+			device_config->intr_mode);
+	vxge_debug_ll_config(VXGE_TRACE, "device_poll_millis : %d",
+			device_config->device_poll_millis);
+	vxge_debug_ll_config(VXGE_TRACE, "rts_mac_en : %d",
+			device_config->rts_mac_en);
+	vxge_debug_ll_config(VXGE_TRACE, "rth_en : %d",
+			device_config->rth_en);
+	vxge_debug_ll_config(VXGE_TRACE, "rth_it_type : %d",
+			device_config->rth_it_type);
+}
+
+static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
+{
+	int i;
+
+	vxge_debug_init(VXGE_TRACE,
+		"%s: %d Vpath(s) opened",
+		vdev->ndev->name, vdev->no_of_vpath);
+
+	switch (vdev->config.intr_type) {
+	case INTA:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Interrupt type INTA", vdev->ndev->name);
+		break;
+
+	case MSI_X:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Interrupt type MSI-X", vdev->ndev->name);
+		break;
+	}
+
+	if (vdev->config.rth_steering) {
+		vxge_debug_init(VXGE_TRACE,
+			"%s: RTH steering enabled for TCP_IPV4",
+			vdev->ndev->name);
+	} else {
+		vxge_debug_init(VXGE_TRACE,
+			"%s: RTH steering disabled", vdev->ndev->name);
+	}
+
+	switch (vdev->config.tx_steering_type) {
+	case NO_STEERING:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx steering disabled", vdev->ndev->name);
+		break;
+	case TX_PRIORITY_STEERING:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Unsupported tx steering option",
+			vdev->ndev->name);
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx steering disabled", vdev->ndev->name);
+		vdev->config.tx_steering_type = 0;
+		break;
+	case TX_VLAN_STEERING:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Unsupported tx steering option",
+			vdev->ndev->name);
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx steering disabled", vdev->ndev->name);
+		vdev->config.tx_steering_type = 0;
+		break;
+	case TX_MULTIQ_STEERING:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx multiqueue steering enabled",
+			vdev->ndev->name);
+		break;
+	case TX_PORT_STEERING:
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx port steering enabled",
+			vdev->ndev->name);
+		break;
+	default:
+		vxge_debug_init(VXGE_ERR,
+			"%s: Unsupported tx steering type",
+			vdev->ndev->name);
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Tx steering disabled", vdev->ndev->name);
+		vdev->config.tx_steering_type = 0;
+	}
+
+	if (vdev->config.gro_enable) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: Generic receive offload enabled",
+			vdev->ndev->name);
+	} else
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Generic receive offload disabled",
+			vdev->ndev->name);
+
+	if (vdev->config.addr_learn_en)
+		vxge_debug_init(VXGE_TRACE,
+			"%s: MAC Address learning enabled", vdev->ndev->name);
+
+	vxge_debug_init(VXGE_TRACE,
+		"%s: Rx doorbell mode enabled", vdev->ndev->name);
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (!vxge_bVALn(vpath_mask, i, 1))
+			continue;
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s: MTU size - %d", vdev->ndev->name,
+			((struct __vxge_hw_device  *)(vdev->devh))->
+				config.vp_config[i].mtu);
+		vxge_debug_init(VXGE_TRACE,
+			"%s: VLAN tag stripping %s", vdev->ndev->name,
+			((struct __vxge_hw_device  *)(vdev->devh))->
+				config.vp_config[i].rpa_strip_vlan_tag
+			? "Enabled" : "Disabled");
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Ring blocks : %d", vdev->ndev->name,
+			((struct __vxge_hw_device  *)(vdev->devh))->
+				config.vp_config[i].ring.ring_blocks);
+		vxge_debug_init(VXGE_TRACE,
+			"%s: Fifo blocks : %d", vdev->ndev->name,
+			((struct __vxge_hw_device  *)(vdev->devh))->
+				config.vp_config[i].fifo.fifo_blocks);
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s: Max frags : %d", vdev->ndev->name,
+			((struct __vxge_hw_device  *)(vdev->devh))->
+				config.vp_config[i].fifo.max_frags);
+		break;
+	}
+}
+
+#ifdef CONFIG_PM
+/**
+ * vxge_pm_suspend - vxge power management suspend entry point
+ *
+ */
+static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	return -ENOSYS;
+}
+/**
+ * vxge_pm_resume - vxge power management resume entry point
+ *
+ */
+static int vxge_pm_resume(struct pci_dev *pdev)
+{
+	return -ENOSYS;
+}
+
+#endif
+
+/**
+ * vxge_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev,
+						pci_channel_state_t state)
+{
+	struct __vxge_hw_device  *hldev =
+		(struct __vxge_hw_device  *) pci_get_drvdata(pdev);
+	struct net_device *netdev = hldev->ndev;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev)) {
+		/* Bring down the card, while avoiding PCI I/O */
+		do_vxge_close(netdev, 0);
+	}
+
+	pci_disable_device(pdev);
+
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * vxge_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ * At this point, the card has exprienced a hard reset,
+ * followed by fixups by BIOS, and has its config space
+ * set up identically to what it was at cold boot.
+ */
+static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
+{
+	struct __vxge_hw_device  *hldev =
+		(struct __vxge_hw_device  *) pci_get_drvdata(pdev);
+	struct net_device *netdev = hldev->ndev;
+
+	struct vxgedev *vdev = netdev_priv(netdev);
+
+	if (pci_enable_device(pdev)) {
+		printk(KERN_ERR "%s: "
+			"Cannot re-enable device after reset\n",
+			VXGE_DRIVER_NAME);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	pci_set_master(pdev);
+	vxge_reset(vdev);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * vxge_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells
+ * us that its OK to resume normal operation.
+ */
+static void vxge_io_resume(struct pci_dev *pdev)
+{
+	struct __vxge_hw_device  *hldev =
+		(struct __vxge_hw_device  *) pci_get_drvdata(pdev);
+	struct net_device *netdev = hldev->ndev;
+
+	if (netif_running(netdev)) {
+		if (vxge_open(netdev)) {
+			printk(KERN_ERR "%s: "
+				"Can't bring device back up after reset\n",
+				VXGE_DRIVER_NAME);
+			return;
+		}
+	}
+
+	netif_device_attach(netdev);
+}
+
+/**
+ * vxge_probe
+ * @pdev : structure containing the PCI related information of the device.
+ * @pre: List of PCI devices supported by the driver listed in vxge_id_table.
+ * Description:
+ * This function is called when a new PCI device gets detected and initializes
+ * it.
+ * Return value:
+ * returns 0 on success and negative on failure.
+ *
+ */
+static int __devinit
+vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
+{
+	struct __vxge_hw_device  *hldev;
+	enum vxge_hw_status status;
+	int ret;
+	int high_dma = 0;
+	u64 vpath_mask = 0;
+	struct vxgedev *vdev;
+	struct vxge_config ll_config;
+	struct vxge_hw_device_config *device_config = NULL;
+	struct vxge_hw_device_attr attr;
+	int i, j, no_of_vpath = 0, max_vpath_supported = 0;
+	u8 *macaddr;
+	struct vxge_mac_addrs *entry;
+	static int bus = -1, device = -1;
+	u8 new_device = 0;
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+	attr.pdev = pdev;
+
+	if (bus != pdev->bus->number)
+		new_device = 1;
+	if (device != PCI_SLOT(pdev->devfn))
+		new_device = 1;
+
+	bus = pdev->bus->number;
+	device = PCI_SLOT(pdev->devfn);
+
+	if (new_device) {
+		if (driver_config->config_dev_cnt &&
+		   (driver_config->config_dev_cnt !=
+			driver_config->total_dev_cnt))
+			vxge_debug_init(VXGE_ERR,
+				"%s: Configured %d of %d devices",
+				VXGE_DRIVER_NAME,
+				driver_config->config_dev_cnt,
+				driver_config->total_dev_cnt);
+		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->total_dev_cnt++;
+	if (++driver_config->config_dev_cnt > max_config_dev) {
+		ret = 0;
+		goto _exit0;
+	}
+
+	device_config = kzalloc(sizeof(struct vxge_hw_device_config),
+		GFP_KERNEL);
+	if (!device_config) {
+		ret = -ENOMEM;
+		vxge_debug_init(VXGE_ERR,
+			"device_config : malloc failed %s %d",
+			__FILE__, __LINE__);
+		goto _exit0;
+	}
+
+	memset(&ll_config, 0, sizeof(struct vxge_config));
+	ll_config.tx_steering_type = TX_MULTIQ_STEERING;
+	ll_config.intr_type = MSI_X;
+	ll_config.napi_weight = NEW_NAPI_WEIGHT;
+	ll_config.rth_steering = RTH_STEERING;
+
+	/* get the default configuration parameters */
+	vxge_hw_device_config_default_get(device_config);
+
+	/* initialize configuration parameters */
+	vxge_device_config_init(device_config, &ll_config.intr_type);
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : can not enable PCI device", __func__);
+		goto _exit0;
+	}
+
+	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s : using 64bit DMA", __func__);
+
+		high_dma = 1;
+
+		if (pci_set_consistent_dma_mask(pdev,
+						0xffffffffffffffffULL)) {
+			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)) {
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s : using 32bit DMA", __func__);
+	} else {
+		ret = -ENOMEM;
+		goto _exit1;
+	}
+
+	if (pci_request_regions(pdev, VXGE_DRIVER_NAME)) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : request regions failed", __func__);
+		ret = -ENODEV;
+		goto _exit1;
+	}
+
+	pci_set_master(pdev);
+
+	attr.bar0 = pci_ioremap_bar(pdev, 0);
+	if (!attr.bar0) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : cannot remap io memory bar0", __func__);
+		ret = -ENODEV;
+		goto _exit2;
+	}
+	vxge_debug_ll_config(VXGE_TRACE,
+		"pci ioremap bar0: %p:0x%llx",
+		attr.bar0,
+		(unsigned long long)pci_resource_start(pdev, 0));
+
+	attr.bar1 = pci_ioremap_bar(pdev, 2);
+	if (!attr.bar1) {
+		vxge_debug_init(VXGE_ERR,
+			"%s : cannot remap io memory bar2", __func__);
+		ret = -ENODEV;
+		goto _exit3;
+	}
+	vxge_debug_ll_config(VXGE_TRACE,
+		"pci ioremap bar1: %p:0x%llx",
+		attr.bar1,
+		(unsigned long long)pci_resource_start(pdev, 2));
+
+	status = vxge_hw_device_hw_info_get(attr.bar0,
+			&ll_config.device_hw_info);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"%s: Reading of hardware info failed."
+			"Please try upgrading the firmware.", VXGE_DRIVER_NAME);
+		ret = -EINVAL;
+		goto _exit4;
+	}
+
+	if (ll_config.device_hw_info.fw_version.major !=
+		VXGE_DRIVER_VERSION_MAJOR) {
+		vxge_debug_init(VXGE_ERR,
+			"FW Ver.(maj): %d not driver's expected version: %d",
+			ll_config.device_hw_info.fw_version.major,
+			VXGE_DRIVER_VERSION_MAJOR);
+		ret = -EINVAL;
+		goto _exit4;
+	}
+
+	vpath_mask = ll_config.device_hw_info.vpath_mask;
+	if (vpath_mask == 0) {
+		vxge_debug_ll_config(VXGE_TRACE,
+			"%s: No vpaths available in device", VXGE_DRIVER_NAME);
+		ret = -EINVAL;
+		goto _exit4;
+	}
+
+	vxge_debug_ll_config(VXGE_TRACE,
+		"%s:%d  Vpath mask = %llx", __func__, __LINE__,
+		(unsigned long long)vpath_mask);
+
+	/* Check how many vpaths are available */
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (!((vpath_mask) & vxge_mBIT(i)))
+			continue;
+		max_vpath_supported++;
+	}
+
+	/*
+	 * Configure vpaths and get driver configured number of vpaths
+	 * which is less than or equal to the maximum vpaths per function.
+	 */
+	no_of_vpath = vxge_config_vpaths(device_config, vpath_mask, &ll_config);
+	if (!no_of_vpath) {
+		vxge_debug_ll_config(VXGE_ERR,
+			"%s: No more vpaths to configure", VXGE_DRIVER_NAME);
+		ret = 0;
+		goto _exit4;
+	}
+
+	/* Setting driver callbacks */
+	attr.uld_callbacks.link_up = vxge_callback_link_up;
+	attr.uld_callbacks.link_down = vxge_callback_link_down;
+	attr.uld_callbacks.crit_err = vxge_callback_crit_err;
+
+	status = vxge_hw_device_initialize(&hldev, &attr, device_config);
+	if (status != VXGE_HW_OK) {
+		vxge_debug_init(VXGE_ERR,
+			"Failed to initialize device (%d)", status);
+			ret = -EINVAL;
+			goto _exit4;
+	}
+
+	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
+
+	/* set private device info */
+	pci_set_drvdata(pdev, hldev);
+
+	ll_config.gro_enable = VXGE_GRO_ALWAYS_AGGREGATE;
+	ll_config.fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
+	ll_config.addr_learn_en = addr_learn_en;
+	ll_config.rth_algorithm = RTH_ALG_JENKINS;
+	ll_config.rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4;
+	ll_config.rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE;
+	ll_config.rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
+	ll_config.rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
+	ll_config.rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
+	ll_config.rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
+	ll_config.rth_bkt_sz = RTH_BUCKET_SIZE;
+	ll_config.tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
+	ll_config.rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
+
+	if (vxge_device_register(hldev, &ll_config, high_dma, no_of_vpath,
+		&vdev)) {
+		ret = -EINVAL;
+		goto _exit5;
+	}
+
+	vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL);
+	VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
+		vxge_hw_device_trace_level_get(hldev));
+
+	/* set private HW device info */
+	hldev->ndev = vdev->ndev;
+	vdev->mtu = VXGE_HW_DEFAULT_MTU;
+	vdev->bar0 = attr.bar0;
+	vdev->bar1 = attr.bar1;
+	vdev->max_vpath_supported = max_vpath_supported;
+	vdev->no_of_vpath = no_of_vpath;
+
+	/* Virtual Path count */
+	for (i = 0, j = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+		if (!vxge_bVALn(vpath_mask, i, 1))
+			continue;
+		if (j >= vdev->no_of_vpath)
+			break;
+
+		vdev->vpaths[j].is_configured = 1;
+		vdev->vpaths[j].device_id = i;
+		vdev->vpaths[j].fifo.driver_id = j;
+		vdev->vpaths[j].ring.driver_id = j;
+		vdev->vpaths[j].vdev = vdev;
+		vdev->vpaths[j].max_mac_addr_cnt = max_mac_vpath;
+		memcpy((u8 *)vdev->vpaths[j].macaddr,
+				(u8 *)ll_config.device_hw_info.mac_addrs[i],
+				ETH_ALEN);
+
+		/* Initialize the mac address list header */
+		INIT_LIST_HEAD(&vdev->vpaths[j].mac_addr_list);
+
+		vdev->vpaths[j].mac_addr_cnt = 0;
+		vdev->vpaths[j].mcast_addr_cnt = 0;
+		j++;
+	}
+	vdev->exec_mode = VXGE_EXEC_MODE_DISABLE;
+	vdev->max_config_port = max_config_port;
+
+	vdev->vlan_tag_strip = vlan_tag_strip;
+
+	/* map the hashing selector table to the configured vpaths */
+	for (i = 0; i < vdev->no_of_vpath; i++)
+		vdev->vpath_selector[i] = vpath_selector[i];
+
+	macaddr = (u8 *)vdev->vpaths[0].macaddr;
+
+	ll_config.device_hw_info.serial_number[VXGE_HW_INFO_LEN - 1] = '\0';
+	ll_config.device_hw_info.product_desc[VXGE_HW_INFO_LEN - 1] = '\0';
+	ll_config.device_hw_info.part_number[VXGE_HW_INFO_LEN - 1] = '\0';
+
+	vxge_debug_init(VXGE_TRACE, "%s: SERIAL NUMBER: %s",
+		vdev->ndev->name, ll_config.device_hw_info.serial_number);
+
+	vxge_debug_init(VXGE_TRACE, "%s: PART NUMBER: %s",
+		vdev->ndev->name, ll_config.device_hw_info.part_number);
+
+	vxge_debug_init(VXGE_TRACE, "%s: Neterion %s Server Adapter",
+		vdev->ndev->name, ll_config.device_hw_info.product_desc);
+
+	vxge_debug_init(VXGE_TRACE,
+		"%s: MAC ADDR: %02X:%02X:%02X:%02X:%02X:%02X",
+		vdev->ndev->name, macaddr[0], macaddr[1], macaddr[2],
+		macaddr[3], macaddr[4], macaddr[5]);
+
+	vxge_debug_init(VXGE_TRACE, "%s: Link Width x%d",
+		vdev->ndev->name, vxge_hw_device_link_width_get(hldev));
+
+	vxge_debug_init(VXGE_TRACE,
+		"%s: Firmware version : %s Date : %s", vdev->ndev->name,
+		ll_config.device_hw_info.fw_version.version,
+		ll_config.device_hw_info.fw_date.date);
+
+	vxge_print_parm(vdev, vpath_mask);
+
+	/* Store the fw version for ethttool option */
+	strcpy(vdev->fw_version, ll_config.device_hw_info.fw_version.version);
+	memcpy(vdev->ndev->dev_addr, (u8 *)vdev->vpaths[0].macaddr, ETH_ALEN);
+	memcpy(vdev->ndev->perm_addr, vdev->ndev->dev_addr, ETH_ALEN);
+
+	/* Copy the station mac address to the list */
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		entry =	(struct vxge_mac_addrs *)
+				kzalloc(sizeof(struct vxge_mac_addrs),
+					GFP_KERNEL);
+		if (NULL == entry) {
+			vxge_debug_init(VXGE_ERR,
+				"%s: mac_addr_list : memory allocation failed",
+				vdev->ndev->name);
+			ret = -EPERM;
+			goto _exit6;
+		}
+		macaddr = (u8 *)&entry->macaddr;
+		memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN);
+		list_add(&entry->item, &vdev->vpaths[i].mac_addr_list);
+		vdev->vpaths[i].mac_addr_cnt = 1;
+	}
+
+	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d  Exiting...",
+		vdev->ndev->name, __func__, __LINE__);
+
+	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
+	VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
+		vxge_hw_device_trace_level_get(hldev));
+
+	return 0;
+
+_exit6:
+	for (i = 0; i < vdev->no_of_vpath; i++)
+		vxge_free_mac_add_list(&vdev->vpaths[i]);
+
+	vxge_device_unregister(hldev);
+_exit5:
+	vxge_hw_device_terminate(hldev);
+_exit4:
+	iounmap(attr.bar1);
+_exit3:
+	iounmap(attr.bar0);
+_exit2:
+	pci_release_regions(pdev);
+_exit1:
+	pci_disable_device(pdev);
+_exit0:
+	kfree(device_config);
+	driver_config->config_dev_cnt--;
+	pci_set_drvdata(pdev, NULL);
+	return ret;
+}
+
+/**
+ * vxge_rem_nic - Free the PCI device
+ * @pdev: structure containing the PCI related information of the device.
+ * Description: This function is called by the Pci subsystem to release a
+ * PCI device and free up all resource held up by the device.
+ */
+static void __devexit
+vxge_remove(struct pci_dev *pdev)
+{
+	struct __vxge_hw_device  *hldev;
+	struct vxgedev *vdev = NULL;
+	struct net_device *dev;
+	int i = 0;
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+	(VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+	u32 level_trace;
+#endif
+
+	hldev = (struct __vxge_hw_device  *) pci_get_drvdata(pdev);
+
+	if (hldev == NULL)
+		return;
+	dev = hldev->ndev;
+	vdev = netdev_priv(dev);
+
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+	(VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+	level_trace = vdev->level_trace;
+#endif
+	vxge_debug_entryexit(level_trace,
+		"%s:%d", __func__, __LINE__);
+
+	vxge_debug_init(level_trace,
+		"%s : removing PCI device...", __func__);
+	vxge_device_unregister(hldev);
+
+	for (i = 0; i < vdev->no_of_vpath; i++) {
+		vxge_free_mac_add_list(&vdev->vpaths[i]);
+		vdev->vpaths[i].mcast_addr_cnt = 0;
+		vdev->vpaths[i].mac_addr_cnt = 0;
+	}
+
+	kfree(vdev->vpaths);
+
+	iounmap(vdev->bar0);
+	iounmap(vdev->bar1);
+
+	/* we are safe to free it now */
+	free_netdev(dev);
+
+	vxge_debug_init(level_trace,
+		"%s:%d  Device unregistered", __func__, __LINE__);
+
+	vxge_hw_device_terminate(hldev);
+
+	pci_disable_device(pdev);
+	pci_release_regions(pdev);
+	pci_set_drvdata(pdev, NULL);
+	vxge_debug_entryexit(level_trace,
+		"%s:%d  Exiting...", __func__, __LINE__);
+}
+
+static struct pci_error_handlers vxge_err_handler = {
+	.error_detected = vxge_io_error_detected,
+	.slot_reset = vxge_io_slot_reset,
+	.resume = vxge_io_resume,
+};
+
+static struct pci_driver vxge_driver = {
+	.name = VXGE_DRIVER_NAME,
+	.id_table = vxge_id_table,
+	.probe = vxge_probe,
+	.remove = __devexit_p(vxge_remove),
+#ifdef CONFIG_PM
+	.suspend = vxge_pm_suspend,
+	.resume = vxge_pm_resume,
+#endif
+	.err_handler = &vxge_err_handler,
+};
+
+static int __init
+vxge_starter(void)
+{
+	int ret = 0;
+	char version[32];
+	snprintf(version, 32, "%s", DRV_VERSION);
+
+	printk(KERN_CRIT "%s: Copyright(c) 2002-2009 Neterion Inc\n",
+		VXGE_DRIVER_NAME);
+	printk(KERN_CRIT "%s: Driver version: %s\n",
+			VXGE_DRIVER_NAME, version);
+
+	verify_bandwidth();
+
+	driver_config = kzalloc(sizeof(struct vxge_drv_config), GFP_KERNEL);
+	if (!driver_config)
+		return -ENOMEM;
+
+	ret = pci_register_driver(&vxge_driver);
+
+	if (driver_config->config_dev_cnt &&
+	   (driver_config->config_dev_cnt != driver_config->total_dev_cnt))
+		vxge_debug_init(VXGE_ERR,
+			"%s: Configured %d of %d devices",
+			VXGE_DRIVER_NAME, driver_config->config_dev_cnt,
+			driver_config->total_dev_cnt);
+
+	if (ret)
+		kfree(driver_config);
+
+	return ret;
+}
+
+static void __exit
+vxge_closer(void)
+{
+	pci_unregister_driver(&vxge_driver);
+	kfree(driver_config);
+}
+module_init(vxge_starter);
+module_exit(vxge_closer);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-main.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-main.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-main.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-main.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,557 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-main.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *              Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_MAIN_H
+#define VXGE_MAIN_H
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+#include "vxge-version.h"
+#include <linux/list.h>
+
+#define VXGE_DRIVER_NAME		"vxge"
+#define VXGE_DRIVER_VENDOR		"Neterion, Inc"
+#define VXGE_DRIVER_VERSION_MAJOR 0
+
+#define DRV_VERSION	VXGE_VERSION_MAJOR"."VXGE_VERSION_MINOR"."\
+	VXGE_VERSION_FIX"."VXGE_VERSION_BUILD"-"\
+	VXGE_VERSION_FOR
+
+#define PCI_DEVICE_ID_TITAN_WIN		0x5733
+#define PCI_DEVICE_ID_TITAN_UNI		0x5833
+#define	VXGE_USE_DEFAULT		0xffffffff
+#define VXGE_HW_VPATH_MSIX_ACTIVE	4
+#define VXGE_HW_RXSYNC_FREQ_CNT		4
+#define VXGE_LL_WATCH_DOG_TIMEOUT	(15 * HZ)
+#define VXGE_LL_RX_COPY_THRESHOLD	256
+#define VXGE_DEF_FIFO_LENGTH		84
+
+#define NO_STEERING		0
+#define PORT_STEERING		0x1
+#define RTH_STEERING		0x2
+#define RX_TOS_STEERING		0x3
+#define RX_VLAN_STEERING	0x4
+#define RTH_BUCKET_SIZE		4
+
+#define	TX_PRIORITY_STEERING	1
+#define	TX_VLAN_STEERING	2
+#define	TX_PORT_STEERING	3
+#define	TX_MULTIQ_STEERING	4
+
+#define VXGE_HW_MAC_ADDR_LEARN_DEFAULT VXGE_HW_RTS_MAC_DISABLE
+
+#define VXGE_TTI_BTIMER_VAL 250000
+
+#define VXGE_TTI_LTIMER_VAL 1000
+#define VXGE_TTI_RTIMER_VAL 0
+#define VXGE_RTI_BTIMER_VAL 250
+#define VXGE_RTI_LTIMER_VAL 100
+#define VXGE_RTI_RTIMER_VAL 0
+#define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH
+#define VXGE_ISR_POLLING_CNT 	8
+#define VXGE_MAX_CONFIG_DEV	0xFF
+#define VXGE_EXEC_MODE_DISABLE	0
+#define VXGE_EXEC_MODE_ENABLE	1
+#define VXGE_MAX_CONFIG_PORT	1
+#define VXGE_ALL_VID_DISABLE	0
+#define VXGE_ALL_VID_ENABLE	1
+#define VXGE_PAUSE_CTRL_DISABLE	0
+#define VXGE_PAUSE_CTRL_ENABLE	1
+
+#define TTI_TX_URANGE_A	5
+#define TTI_TX_URANGE_B	15
+#define TTI_TX_URANGE_C	40
+#define TTI_TX_UFC_A	5
+#define TTI_TX_UFC_B	40
+#define TTI_TX_UFC_C	60
+#define TTI_TX_UFC_D	100
+
+#define RTI_RX_URANGE_A	5
+#define RTI_RX_URANGE_B	15
+#define RTI_RX_URANGE_C	40
+#define RTI_RX_UFC_A	1
+#define RTI_RX_UFC_B	5
+#define RTI_RX_UFC_C	10
+#define RTI_RX_UFC_D	15
+
+/* Milli secs timer period */
+#define VXGE_TIMER_DELAY		10000
+
+#define VXGE_LL_MAX_FRAME_SIZE(dev) ((dev)->mtu + VXGE_HW_MAC_HEADER_MAX_SIZE)
+
+enum vxge_reset_event {
+	/* reset events */
+	VXGE_LL_VPATH_RESET	= 0,
+	VXGE_LL_DEVICE_RESET	= 1,
+	VXGE_LL_FULL_RESET	= 2,
+	VXGE_LL_START_RESET	= 3,
+	VXGE_LL_COMPL_RESET	= 4
+};
+/* These flags represent the devices temporary state */
+enum vxge_device_state_t {
+__VXGE_STATE_RESET_CARD = 0,
+__VXGE_STATE_CARD_UP
+};
+
+enum vxge_mac_addr_state {
+	/* mac address states */
+	VXGE_LL_MAC_ADDR_IN_LIST        = 0,
+	VXGE_LL_MAC_ADDR_IN_DA_TABLE    = 1
+};
+
+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;
+};
+
+struct macInfo {
+	unsigned char macaddr[ETH_ALEN];
+	unsigned char macmask[ETH_ALEN];
+	unsigned int vpath_no;
+	enum vxge_mac_addr_state state;
+};
+
+struct vxge_config {
+	int		tx_pause_enable;
+	int		rx_pause_enable;
+
+#define	NEW_NAPI_WEIGHT	64
+	int		napi_weight;
+#define VXGE_GRO_DONOT_AGGREGATE		0
+#define VXGE_GRO_ALWAYS_AGGREGATE		1
+	int		gro_enable;
+	int		intr_type;
+#define INTA	0
+#define MSI	1
+#define MSI_X	2
+
+	int		addr_learn_en;
+
+	int		rth_steering;
+	int		rth_algorithm;
+	int		rth_hash_type_tcpipv4;
+	int		rth_hash_type_ipv4;
+	int		rth_hash_type_tcpipv6;
+	int		rth_hash_type_ipv6;
+	int		rth_hash_type_tcpipv6ex;
+	int		rth_hash_type_ipv6ex;
+	int		rth_bkt_sz;
+	int		rth_jhash_golden_ratio;
+	int		tx_steering_type;
+	int 	fifo_indicate_max_pkts;
+	struct vxge_hw_device_hw_info device_hw_info;
+};
+
+struct vxge_msix_entry {
+	/* Mimicing the msix_entry struct of Kernel. */
+	u16 vector;
+	u16 entry;
+	u16 in_use;
+	void *arg;
+};
+
+/* Software Statistics */
+
+struct vxge_sw_stats {
+	/* Network Stats (interface stats) */
+	struct net_device_stats net_stats;
+
+	/* Tx */
+	u64 tx_frms;
+	u64 tx_errors;
+	u64 tx_bytes;
+	u64 txd_not_free;
+	u64 txd_out_of_desc;
+
+	/* Virtual Path */
+	u64 vpaths_open;
+	u64 vpath_open_fail;
+
+	/* Rx */
+	u64 rx_frms;
+	u64 rx_errors;
+	u64 rx_bytes;
+	u64 rx_mcast;
+
+	/* Misc. */
+	u64 link_up;
+	u64 link_down;
+	u64 pci_map_fail;
+	u64 skb_alloc_fail;
+};
+
+struct vxge_mac_addrs {
+	struct list_head item;
+	u64 macaddr;
+	u64 macmask;
+	enum vxge_mac_addr_state state;
+};
+
+struct vxgedev;
+
+struct vxge_fifo_stats {
+	u64 tx_frms;
+	u64 tx_errors;
+	u64 tx_bytes;
+	u64 txd_not_free;
+	u64 txd_out_of_desc;
+	u64 pci_map_fail;
+};
+
+struct vxge_fifo {
+	struct net_device	*ndev;
+	struct pci_dev		*pdev;
+	struct __vxge_hw_fifo *handle;
+
+	/* The vpath id maintained in the driver -
+	 * 0 to 'maximum_vpaths_in_function - 1'
+	 */
+	int driver_id;
+	int tx_steering_type;
+	int indicate_max_pkts;
+	spinlock_t tx_lock;
+	/* flag used to maintain queue state when MULTIQ is not enabled */
+#define VPATH_QUEUE_START       0
+#define VPATH_QUEUE_STOP        1
+	int queue_state;
+
+	/* Tx stats */
+	struct vxge_fifo_stats stats;
+} ____cacheline_aligned;
+
+struct vxge_ring_stats {
+	u64 prev_rx_frms;
+	u64 rx_frms;
+	u64 rx_errors;
+	u64 rx_dropped;
+	u64 rx_bytes;
+	u64 rx_mcast;
+	u64 pci_map_fail;
+	u64 skb_alloc_fail;
+};
+
+struct vxge_ring {
+	struct net_device	*ndev;
+	struct pci_dev		*pdev;
+	struct __vxge_hw_ring	*handle;
+	/* The vpath id maintained in the driver -
+	 * 0 to 'maximum_vpaths_in_function - 1'
+	 */
+	int driver_id;
+
+	 /* copy of the flag indicating whether rx_csum is to be used */
+	u32 rx_csum;
+
+	int pkts_processed;
+	int budget;
+	int gro_enable;
+
+	struct napi_struct napi;
+
+#define VXGE_MAX_MAC_ADDR_COUNT		30
+
+	int vlan_tag_strip;
+	struct vlan_group *vlgrp;
+	int rx_vector_no;
+	enum vxge_hw_status last_status;
+
+	/* Rx stats */
+	struct vxge_ring_stats stats;
+} ____cacheline_aligned;
+
+struct vxge_vpath {
+
+	struct vxge_fifo fifo;
+	struct vxge_ring ring;
+
+	struct __vxge_hw_vpath_handle *handle;
+
+	/* Actual vpath id for this vpath in the device - 0 to 16 */
+	int device_id;
+	int max_mac_addr_cnt;
+	int is_configured;
+	int is_open;
+	struct vxgedev *vdev;
+	u8 (macaddr)[ETH_ALEN];
+	u8 (macmask)[ETH_ALEN];
+
+#define VXGE_MAX_LEARN_MAC_ADDR_CNT	2048
+	/* mac addresses currently programmed into NIC */
+	u16 mac_addr_cnt;
+	u16 mcast_addr_cnt;
+	struct list_head mac_addr_list;
+
+	u32 level_err;
+	u32 level_trace;
+};
+#define VXGE_COPY_DEBUG_INFO_TO_LL(vdev, err, trace) {	\
+	for (i = 0; i < vdev->no_of_vpath; i++) {		\
+		vdev->vpaths[i].level_err = err;		\
+		vdev->vpaths[i].level_trace = trace;		\
+	}							\
+	vdev->level_err = err;					\
+	vdev->level_trace = trace;				\
+}
+
+struct vxgedev {
+	struct net_device	*ndev;
+	struct pci_dev		*pdev;
+	struct __vxge_hw_device *devh;
+	struct vlan_group	*vlgrp;
+	int vlan_tag_strip;
+	struct vxge_config	config;
+	unsigned long	state;
+
+	/* Indicates which vpath to reset */
+	unsigned long  vp_reset;
+
+	/* Timer used for polling vpath resets */
+	struct timer_list vp_reset_timer;
+
+	/* Timer used for polling vpath lockup */
+	struct timer_list vp_lockup_timer;
+
+	/*
+	 * Flags to track whether device is in All Multicast
+	 * or in promiscuous mode.
+	 */
+	u16		all_multi_flg;
+
+	 /* A flag indicating whether rx_csum is to be used or not. */
+	u32	rx_csum;
+
+	struct vxge_msix_entry *vxge_entries;
+	struct msix_entry *entries;
+	/*
+	 * 4 for each vpath * 17;
+	 * total is 68
+	 */
+#define	VXGE_MAX_REQUESTED_MSIX	68
+#define VXGE_INTR_STRLEN 80
+	char desc[VXGE_MAX_REQUESTED_MSIX][VXGE_INTR_STRLEN];
+
+	enum vxge_hw_event cric_err_event;
+
+	int max_vpath_supported;
+	int no_of_vpath;
+
+	struct napi_struct napi;
+	/* A debug option, when enabled and if error condition occurs,
+	 * the driver will do following steps:
+	 * - mask all interrupts
+	 * - Not clear the source of the alarm
+	 * - gracefully stop all I/O
+	 * A diagnostic dump of register and stats at this point
+	 * reveals very useful information.
+	 */
+	int exec_mode;
+	int max_config_port;
+	struct vxge_vpath	*vpaths;
+
+	struct __vxge_hw_vpath_handle *vp_handles[VXGE_HW_MAX_VIRTUAL_PATHS];
+	void __iomem *bar0;
+	void __iomem *bar1;
+	struct vxge_sw_stats	stats;
+	int		mtu;
+	/* Below variables are used for vpath selection to transmit a packet */
+	u8 		vpath_selector[VXGE_HW_MAX_VIRTUAL_PATHS];
+	u64		vpaths_deployed;
+
+	u32 		intr_cnt;
+	u32 		level_err;
+	u32 		level_trace;
+	char		fw_version[VXGE_HW_FW_STRLEN];
+};
+
+struct vxge_rx_priv {
+	struct sk_buff		*skb;
+	dma_addr_t		data_dma;
+	dma_addr_t		data_size;
+};
+
+struct vxge_tx_priv {
+	struct sk_buff		*skb;
+	dma_addr_t		dma_buffers[MAX_SKB_FRAGS+1];
+};
+
+#define VXGE_MODULE_PARAM_INT(p, val) \
+	static int p = val; \
+	module_param(p, int, 0)
+
+#define vxge_os_bug(fmt...)		{ printk(fmt); BUG(); }
+
+#define vxge_os_timer(timer, handle, arg, exp) do { \
+		init_timer(&timer); \
+		timer.function = handle; \
+		timer.data = (unsigned long) arg; \
+		mod_timer(&timer, (jiffies + exp)); \
+	} while (0);
+
+int __devinit vxge_device_register(struct __vxge_hw_device *devh,
+				    struct vxge_config *config,
+				    int high_dma, int no_of_vpath,
+				    struct vxgedev **vdev);
+
+void vxge_device_unregister(struct __vxge_hw_device *devh);
+
+void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id);
+
+void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id);
+
+void vxge_callback_link_up(struct __vxge_hw_device *devh);
+
+void vxge_callback_link_down(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
+	struct macInfo *mac);
+
+int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac);
+
+int vxge_reset(struct vxgedev *vdev);
+
+enum vxge_hw_status
+vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
+	u8 t_code, void *userdata);
+
+enum vxge_hw_status
+vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
+	enum vxge_hw_fifo_tcode t_code, void *userdata, void **skb_ptr);
+
+int vxge_close(struct net_device *dev);
+
+int vxge_open(struct net_device *dev);
+
+void vxge_close_vpaths(struct vxgedev *vdev, int index);
+
+int vxge_open_vpaths(struct vxgedev *vdev);
+
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
+
+void vxge_stop_all_tx_queue(struct vxgedev *vdev);
+
+void vxge_stop_tx_queue(struct vxge_fifo *fifo);
+
+void vxge_start_all_tx_queue(struct vxgedev *vdev);
+
+void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb);
+
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
+	struct macInfo *mac);
+
+enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev,
+	struct macInfo *mac);
+
+int vxge_mac_list_add(struct vxge_vpath *vpath,
+	struct macInfo *mac);
+
+void vxge_free_mac_add_list(struct vxge_vpath *vpath);
+
+enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath);
+
+enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath);
+
+int do_vxge_close(struct net_device *dev, int do_io);
+extern void initialize_ethtool_ops(struct net_device *ndev);
+/**
+ * #define VXGE_DEBUG_INIT: debug for initialization functions
+ * #define VXGE_DEBUG_TX	 : debug transmit related functions
+ * #define VXGE_DEBUG_RX  : debug recevice related functions
+ * #define VXGE_DEBUG_MEM : debug memory module
+ * #define VXGE_DEBUG_LOCK: debug locks
+ * #define VXGE_DEBUG_SEM : debug semaphore
+ * #define VXGE_DEBUG_ENTRYEXIT: debug functions by adding entry exit statements
+*/
+#define VXGE_DEBUG_INIT		0x00000001
+#define VXGE_DEBUG_TX		0x00000002
+#define VXGE_DEBUG_RX		0x00000004
+#define VXGE_DEBUG_MEM		0x00000008
+#define VXGE_DEBUG_LOCK		0x00000010
+#define VXGE_DEBUG_SEM		0x00000020
+#define VXGE_DEBUG_ENTRYEXIT	0x00000040
+#define VXGE_DEBUG_INTR		0x00000080
+#define VXGE_DEBUG_LL_CONFIG	0x00000100
+
+/* Debug tracing for VXGE driver */
+#ifndef VXGE_DEBUG_MASK
+#define VXGE_DEBUG_MASK	0x0
+#endif
+
+#if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK)
+#define vxge_debug_ll_config(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_ll_config(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK)
+#define vxge_debug_init(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_init(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK)
+#define vxge_debug_tx(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_tx(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK)
+#define vxge_debug_rx(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_rx(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK)
+#define vxge_debug_mem(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_mem(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)
+#define vxge_debug_entryexit(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_entryexit(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK)
+#define vxge_debug_intr(level, fmt, ...) \
+	vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_intr(level, fmt, ...)
+#endif
+
+#define VXGE_DEVICE_DEBUG_LEVEL_SET(level, mask, vdev) {\
+	vxge_hw_device_debug_set((struct __vxge_hw_device  *)vdev->devh, \
+		level, mask);\
+	VXGE_COPY_DEBUG_INFO_TO_LL(vdev, \
+		vxge_hw_device_error_level_get((struct __vxge_hw_device  *) \
+			vdev->devh), \
+		vxge_hw_device_trace_level_get((struct __vxge_hw_device  *) \
+			vdev->devh));\
+}
+
+#ifdef NETIF_F_GSO
+#define vxge_tcp_mss(skb) (skb_shinfo(skb)->gso_size)
+#define vxge_udp_mss(skb) (skb_shinfo(skb)->gso_size)
+#define vxge_offload_type(skb) (skb_shinfo(skb)->gso_type)
+#endif
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-reg.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,4608 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-reg.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O Virtualized
+ *             Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_REG_H
+#define VXGE_REG_H
+
+/*
+ * vxge_mBIT(loc) - set bit at offset
+ */
+#define vxge_mBIT(loc)		(0x8000000000000000ULL >> (loc))
+
+/*
+ * vxge_vBIT(val, loc, sz) - set bits at offset
+ */
+#define vxge_vBIT(val, loc, sz)	(((u64)(val)) << (64-(loc)-(sz)))
+#define vxge_vBIT32(val, loc, sz)	(((u32)(val)) << (32-(loc)-(sz)))
+
+/*
+ * vxge_bVALn(bits, loc, n) - Get the value of n bits at location
+ */
+#define vxge_bVALn(bits, loc, n) \
+	((((u64)bits) >> (64-(loc+n))) & ((0x1ULL << n) - 1))
+
+#define	VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(bits) \
+							vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(bits) \
+							vxge_bVALn(bits, 48, 8)
+#define	VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(bits) \
+							vxge_bVALn(bits, 56, 8)
+
+#define	VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(bits) \
+							vxge_bVALn(bits, 3, 5)
+#define	VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(bits) \
+							vxge_bVALn(bits, 5, 3)
+#define VXGE_HW_PF_SW_RESET_COMMAND				0xA5
+
+#define VXGE_HW_TITAN_PCICFGMGMT_REG_SPACES		17
+#define VXGE_HW_TITAN_SRPCIM_REG_SPACES			17
+#define VXGE_HW_TITAN_VPMGMT_REG_SPACES			17
+#define VXGE_HW_TITAN_VPATH_REG_SPACES			17
+
+#define VXGE_HW_ASIC_MODE_RESERVED				0
+#define VXGE_HW_ASIC_MODE_NO_IOV				1
+#define VXGE_HW_ASIC_MODE_SR_IOV				2
+#define VXGE_HW_ASIC_MODE_MR_IOV				3
+
+#define	VXGE_HW_TXMAC_GEN_CFG1_TMAC_PERMA_STOP_EN		vxge_mBIT(3)
+#define	VXGE_HW_TXMAC_GEN_CFG1_BLOCK_BCAST_TO_WIRE		vxge_mBIT(19)
+#define	VXGE_HW_TXMAC_GEN_CFG1_BLOCK_BCAST_TO_SWITCH	vxge_mBIT(23)
+#define	VXGE_HW_TXMAC_GEN_CFG1_HOST_APPEND_FCS			vxge_mBIT(31)
+
+#define	VXGE_HW_VPATH_IS_FIRST_GET_VPATH_IS_FIRST(bits)	vxge_bVALn(bits, 3, 1)
+
+#define	VXGE_HW_TIM_VPATH_ASSIGNMENT_GET_BMAP_ROOT(bits) \
+						vxge_bVALn(bits, 0, 32)
+
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN(bits) \
+							vxge_bVALn(bits, 50, 14)
+
+#define	VXGE_HW_XMAC_VSPORT_CHOICES_VP_GET_VSPORT_VECTOR(bits) \
+							vxge_bVALn(bits, 0, 17)
+
+#define	VXGE_HW_XMAC_VPATH_TO_VSPORT_VPMGMT_CLONE_GET_VSPORT_NUMBER(bits) \
+							vxge_bVALn(bits, 3, 5)
+
+#define	VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(bits) \
+							vxge_bVALn(bits, 17, 15)
+
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_LEGACY_MODE			0
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY		1
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_MULTI_OP_MODE		2
+
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE_MESSAGES_ONLY		0
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE_MULTI_OP_MODE		1
+
+#define	VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val) \
+				(val&~VXGE_HW_TOC_KDFC_INITIAL_BIR(7))
+#define	VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val) \
+				vxge_bVALn(val, 61, 3)
+#define	VXGE_HW_TOC_GET_USDC_INITIAL_OFFSET(val) \
+				(val&~VXGE_HW_TOC_USDC_INITIAL_BIR(7))
+#define	VXGE_HW_TOC_GET_USDC_INITIAL_BIR(val) \
+				vxge_bVALn(val, 61, 3)
+
+#define	VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(bits)	bits
+#define	VXGE_HW_TOC_KDFC_FIFO_STRIDE_GET_TOC_KDFC_FIFO_STRIDE(bits)	bits
+
+#define	VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR0(bits) \
+						vxge_bVALn(bits, 1, 15)
+#define	VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR1(bits) \
+						vxge_bVALn(bits, 17, 15)
+#define	VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR2(bits) \
+						vxge_bVALn(bits, 33, 15)
+
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_VAPTH_NUM(val) vxge_vBIT(val, 42, 5)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_FIFO_NUM(val) vxge_vBIT(val, 47, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_FIFO_OFFSET(val) \
+					vxge_vBIT(val, 49, 15)
+
+#define VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER			0
+#define VXGE_HW_PRC_CFG4_RING_MODE_THREE_BUFFER			1
+#define VXGE_HW_PRC_CFG4_RING_MODE_FIVE_BUFFER			2
+
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_A				0
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_B				2
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_C				1
+
+#define VXGE_HW_RTS_MGR_STEER_CTRL_WE_READ                             0
+#define VXGE_HW_RTS_MGR_STEER_CTRL_WE_WRITE                            1
+
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_DA                  0
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_VID                 1
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_ETYPE               2
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_PN                  3
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RANGE_PN            4
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG         5
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT         6
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG       7
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK            8
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY             9
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_QOS                 10
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_DS                  11
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT        12
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_FW_VERSION          13
+
+#define VXGE_HW_RTS_MGR_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
+							vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA0_DA_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_MASK(bits) \
+							vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_MASK(val) vxge_vBIT(val, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_ADD_PRIVILEGED_MODE \
+								vxge_mBIT(54)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_ADD_VPATH(bits) \
+							vxge_bVALn(bits, 55, 5)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_ADD_VPATH(val) \
+							vxge_vBIT(val, 55, 5)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_ADD_MODE(bits) \
+							vxge_bVALn(bits, 62, 2)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_MODE(val) vxge_vBIT(val, 62, 2)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY			0
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY		1
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY		2
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY		3
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY			0
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY		1
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY		3
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL		4
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ALL_CLEAR			172
+
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA		0
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID		1
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE		2
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN		3
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG	5
+#define	VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT	6
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG	7
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK		8
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY		9
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS		10
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS		11
+#define	VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT	12
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO		13
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
+							vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(bits) vxge_bVALn(bits, 0, 12)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(val) vxge_vBIT(val, 0, 12)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_ETYPE(bits)	vxge_bVALn(bits, 0, 11)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_ETYPE(val) vxge_vBIT(val, 0, 16)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_SRC_DEST_SEL(bits) \
+							vxge_bVALn(bits, 3, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_SRC_DEST_SEL		vxge_mBIT(3)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_TCP_UDP_SEL(bits) \
+							vxge_bVALn(bits, 7, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_TCP_UDP_SEL		vxge_mBIT(7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_PORT_NUM(bits) \
+							vxge_bVALn(bits, 8, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_PORT_NUM(val) vxge_vBIT(val, 8, 16)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_EN(bits) \
+							vxge_bVALn(bits, 3, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN		vxge_mBIT(3)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_BUCKET_SIZE(bits) \
+							vxge_bVALn(bits, 4, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(val) \
+							vxge_vBIT(val, 4, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ALG_SEL(bits) \
+							vxge_bVALn(bits, 10, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(val) \
+							vxge_vBIT(val, 10, 2)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_JENKINS	0
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_MS_RSS	1
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_CRC32C	2
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV4_EN(bits) \
+							vxge_bVALn(bits, 15, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN	vxge_mBIT(15)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV4_EN(bits) \
+							vxge_bVALn(bits, 19, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN	vxge_mBIT(19)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV6_EN(bits) \
+							vxge_bVALn(bits, 23, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN	vxge_mBIT(23)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV6_EN(bits) \
+							vxge_bVALn(bits, 27, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN	vxge_mBIT(27)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV6_EX_EN(bits) \
+							vxge_bVALn(bits, 31, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN vxge_mBIT(31)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV6_EX_EN(bits) \
+							vxge_bVALn(bits, 35, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN	vxge_mBIT(35)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(bits) \
+							vxge_bVALn(bits, 39, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE	vxge_mBIT(39)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_REPL_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 43, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_REPL_ENTRY_EN	vxge_mBIT(43)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_SOLO_IT_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 3, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN	vxge_mBIT(3)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_SOLO_IT_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(val) \
+							vxge_vBIT(val, 9, 7)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(val) \
+							vxge_vBIT(val, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 8, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN	vxge_mBIT(8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(val) \
+							vxge_vBIT(val, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(val) \
+							vxge_vBIT(val, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 24, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN	vxge_mBIT(24)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 25, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(val) \
+							vxge_vBIT(val, 25, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(val) \
+							vxge_vBIT(val, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 8, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN	vxge_mBIT(8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(val) \
+							vxge_vBIT(val, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(val) \
+							vxge_vBIT(val, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 24, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN	vxge_mBIT(24)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 25, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(val) \
+							vxge_vBIT(val, 25, 7)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_JHASH_CFG_GOLDEN_RATIO(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_JHASH_CFG_GOLDEN_RATIO(val) \
+							vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_JHASH_CFG_INIT_VALUE(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_JHASH_CFG_INIT_VALUE(val) \
+							vxge_vBIT(val, 32, 32)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV6_SA_MASK(bits) \
+							vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV6_SA_MASK(val) \
+							vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV6_DA_MASK(bits) \
+							vxge_bVALn(bits, 16, 16)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV6_DA_MASK(val) \
+							vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV4_SA_MASK(bits) \
+							vxge_bVALn(bits, 32, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV4_SA_MASK(val) \
+							vxge_vBIT(val, 32, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV4_DA_MASK(bits) \
+							vxge_bVALn(bits, 36, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV4_DA_MASK(val) \
+							vxge_vBIT(val, 36, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_L4SP_MASK(bits) \
+							vxge_bVALn(bits, 40, 2)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_L4SP_MASK(val) \
+							vxge_vBIT(val, 40, 2)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_L4DP_MASK(bits) \
+							vxge_bVALn(bits, 42, 2)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_L4DP_MASK(val) \
+							vxge_vBIT(val, 42, 2)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_KEY_KEY(bits) \
+							vxge_bVALn(bits, 0, 64)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_KEY_KEY vxge_vBIT(val, 0, 64)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_QOS_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 3, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_QOS_ENTRY_EN		vxge_mBIT(3)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DS_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 3, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_DS_ENTRY_EN		vxge_mBIT(3)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(bits) \
+							vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(val) \
+							vxge_vBIT(val, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MODE(val) \
+							vxge_vBIT(val, 62, 2)
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_BUCKET_NUM(val) \
+							vxge_vBIT(val, 0, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 8, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_ENTRY_EN	vxge_mBIT(8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_BUCKET_DATA(val) \
+							vxge_vBIT(val, 9, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_BUCKET_NUM(val) \
+							vxge_vBIT(val, 16, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 24, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_ENTRY_EN	vxge_mBIT(24)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 25, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_BUCKET_DATA(val) \
+							vxge_vBIT(val, 25, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 32, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_BUCKET_NUM(val) \
+							vxge_vBIT(val, 32, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 40, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_ENTRY_EN	vxge_mBIT(40)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 41, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_BUCKET_DATA(val) \
+							vxge_vBIT(val, 41, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_BUCKET_NUM(bits) \
+							vxge_bVALn(bits, 48, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_BUCKET_NUM(val) \
+							vxge_vBIT(val, 48, 8)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_ENTRY_EN(bits) \
+							vxge_bVALn(bits, 56, 1)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_ENTRY_EN	vxge_mBIT(56)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_BUCKET_DATA(bits) \
+							vxge_bVALn(bits, 57, 7)
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_BUCKET_DATA(val) \
+							vxge_vBIT(val, 57, 7)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER           0
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER         1
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_VERSION               2
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE              3
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0                4
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_1                5
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_2                6
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3                7
+
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_LED_CONTROL_ON			1
+#define	VXGE_HW_RTS_ACCESS_STEER_DATA0_LED_CONTROL_OFF			0
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_DAY(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(bits) \
+							vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MONTH(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(bits) \
+						vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_YEAR(val) \
+							vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(bits) \
+						vxge_bVALn(bits, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MAJOR vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(bits) \
+						vxge_bVALn(bits, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MINOR vxge_vBIT(val, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(bits) \
+						vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_BUILD vxge_vBIT(val, 48, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(bits) \
+						vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_DAY(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(bits) \
+							vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MONTH(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(bits) \
+							vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_YEAR(val) \
+							vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(bits) \
+							vxge_bVALn(bits, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MAJOR vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(bits) \
+							vxge_bVALn(bits, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MINOR vxge_vBIT(val, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \
+							vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16)
+
+#define	VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\
+							vxge_bVALn(bits, 0, 18)
+
+#define	VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(bits) \
+							vxge_bVALn(bits, 48, 16)
+#define	VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(bits)	vxge_bVALn(bits, 48, 16)
+#define	VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(bits)	(bits)
+#define	VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(bits)	(bits)
+#define	VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(bits\
+) vxge_bVALn(bits, 48, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(bits) vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(bits) \
+							vxge_bVALn(bits, 16, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(bits) \
+							vxge_bVALn(bits, 32, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(bits)	vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(bits) \
+							vxge_bVALn(bits, 16, 16)
+#define	VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(bits) \
+							vxge_bVALn(bits, 32, 16)
+
+#define	VXGE_HW_MRPCIM_DEBUG_STATS0_GET_INI_WR_DROP(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS0_GET_INI_RD_DROP(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS1_GET_VPLANE_WRCRDTARB_PH_CRDT_DEPLETED(bits\
+) vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS2_GET_VPLANE_WRCRDTARB_PD_CRDT_DEPLETED(bits\
+) vxge_bVALn(bits, 32, 32)
+#define \
+VXGE_HW_MRPCIM_DEBUG_STATS3_GET_VPLANE_RDCRDTARB_NPH_CRDT_DEPLETED(bits) \
+	vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS4_GET_INI_WR_VPIN_DROP(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS4_GET_INI_RD_VPIN_DROP(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_GENSTATS_COUNT01_GET_GENSTATS_COUNT1(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_GENSTATS_COUNT01_GET_GENSTATS_COUNT0(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_GENSTATS_COUNT23_GET_GENSTATS_COUNT3(bits) \
+							vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_GENSTATS_COUNT23_GET_GENSTATS_COUNT2(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_GENSTATS_COUNT4_GET_GENSTATS_COUNT4(bits) \
+							vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_GENSTATS_COUNT5_GET_GENSTATS_COUNT5(bits) \
+							vxge_bVALn(bits, 32, 32)
+
+#define	VXGE_HW_DEBUG_STATS0_GET_RSTDROP_MSG(bits)	vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_DEBUG_STATS0_GET_RSTDROP_CPL(bits)	vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_DEBUG_STATS1_GET_RSTDROP_CLIENT0(bits)	vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_DEBUG_STATS1_GET_RSTDROP_CLIENT1(bits)	vxge_bVALn(bits, 32, 32)
+#define	VXGE_HW_DEBUG_STATS2_GET_RSTDROP_CLIENT2(bits)	vxge_bVALn(bits, 0, 32)
+#define	VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_PH(bits)	vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_NPH(bits)	vxge_bVALn(bits, 16, 16)
+#define	VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_CPLH(bits)	vxge_bVALn(bits, 32, 16)
+#define	VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_PD(bits)	vxge_bVALn(bits, 0, 16)
+#define	VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_NPD(bits)	bVAL(bits, 16, 16)
+#define	VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_CPLD(bits)	vxge_bVALn(bits, 32, 16)
+
+#define	VXGE_HW_DBG_STATS_TPA_TX_PATH_GET_TX_PERMITTED_FRMS(bits) \
+							vxge_bVALn(bits, 32, 32)
+
+#define	VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT0_TX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define	VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT1_TX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 8, 8)
+#define	VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT2_TX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 16, 8)
+
+#define	VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT0_RX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 0, 8)
+#define	VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT1_RX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 8, 8)
+#define	VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT2_RX_ANY_FRMS(bits) \
+							vxge_bVALn(bits, 16, 8)
+
+#define VXGE_HW_CONFIG_PRIV_H
+
+#define VXGE_HW_SWAPPER_INITIAL_VALUE			0x0123456789abcdefULL
+#define VXGE_HW_SWAPPER_BYTE_SWAPPED			0xefcdab8967452301ULL
+#define VXGE_HW_SWAPPER_BIT_FLIPPED			0x80c4a2e691d5b3f7ULL
+#define VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED	0xf7b3d591e6a2c480ULL
+
+#define VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE		0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_READ_BYTE_SWAP_DISABLE		0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE		0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_READ_BIT_FLAP_DISABLE		0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE		0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_DISABLE		0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE		0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_WRITE_BIT_FLAP_DISABLE		0x0000000000000000ULL
+
+/*
+ * The registers are memory mapped and are native big-endian byte order. The
+ * little-endian hosts are handled by enabling hardware byte-swapping for
+ * register and dma operations.
+ */
+struct vxge_hw_legacy_reg {
+
+	u8	unused00010[0x00010];
+
+/*0x00010*/	u64	toc_swapper_fb;
+#define VXGE_HW_TOC_SWAPPER_FB_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00018*/	u64	pifm_rd_swap_en;
+#define VXGE_HW_PIFM_RD_SWAP_EN_PIFM_RD_SWAP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00020*/	u64	pifm_rd_flip_en;
+#define VXGE_HW_PIFM_RD_FLIP_EN_PIFM_RD_FLIP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00028*/	u64	pifm_wr_swap_en;
+#define VXGE_HW_PIFM_WR_SWAP_EN_PIFM_WR_SWAP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00030*/	u64	pifm_wr_flip_en;
+#define VXGE_HW_PIFM_WR_FLIP_EN_PIFM_WR_FLIP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00038*/	u64	toc_first_pointer;
+#define VXGE_HW_TOC_FIRST_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00040*/	u64	host_access_en;
+#define VXGE_HW_HOST_ACCESS_EN_HOST_ACCESS_EN(val) vxge_vBIT(val, 0, 64)
+
+} __packed;
+
+struct vxge_hw_toc_reg {
+
+	u8	unused00050[0x00050];
+
+/*0x00050*/	u64	toc_common_pointer;
+#define VXGE_HW_TOC_COMMON_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00058*/	u64	toc_memrepair_pointer;
+#define VXGE_HW_TOC_MEMREPAIR_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00060*/	u64	toc_pcicfgmgmt_pointer[17];
+#define VXGE_HW_TOC_PCICFGMGMT_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+	u8	unused001e0[0x001e0-0x000e8];
+
+/*0x001e0*/	u64	toc_mrpcim_pointer;
+#define VXGE_HW_TOC_MRPCIM_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x001e8*/	u64	toc_srpcim_pointer[17];
+#define VXGE_HW_TOC_SRPCIM_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+	u8	unused00278[0x00278-0x00270];
+
+/*0x00278*/	u64	toc_vpmgmt_pointer[17];
+#define VXGE_HW_TOC_VPMGMT_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+	u8	unused00390[0x00390-0x00300];
+
+/*0x00390*/	u64	toc_vpath_pointer[17];
+#define VXGE_HW_TOC_VPATH_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+	u8	unused004a0[0x004a0-0x00418];
+
+/*0x004a0*/	u64	toc_kdfc;
+#define VXGE_HW_TOC_KDFC_INITIAL_OFFSET(val) vxge_vBIT(val, 0, 61)
+#define VXGE_HW_TOC_KDFC_INITIAL_BIR(val) vxge_vBIT(val, 61, 3)
+/*0x004a8*/	u64	toc_usdc;
+#define VXGE_HW_TOC_USDC_INITIAL_OFFSET(val) vxge_vBIT(val, 0, 61)
+#define VXGE_HW_TOC_USDC_INITIAL_BIR(val) vxge_vBIT(val, 61, 3)
+/*0x004b0*/	u64	toc_kdfc_vpath_stride;
+#define	VXGE_HW_TOC_KDFC_VPATH_STRIDE_INITIAL_TOC_KDFC_VPATH_STRIDE(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x004b8*/	u64	toc_kdfc_fifo_stride;
+#define	VXGE_HW_TOC_KDFC_FIFO_STRIDE_INITIAL_TOC_KDFC_FIFO_STRIDE(val) \
+							vxge_vBIT(val, 0, 64)
+
+} __packed;
+
+struct vxge_hw_common_reg {
+
+	u8	unused00a00[0x00a00];
+
+/*0x00a00*/	u64	prc_status1;
+#define VXGE_HW_PRC_STATUS1_PRC_VP_QUIESCENT(n)	vxge_mBIT(n)
+/*0x00a08*/	u64	rxdcm_reset_in_progress;
+#define VXGE_HW_RXDCM_RESET_IN_PROGRESS_PRC_VP(n)	vxge_mBIT(n)
+/*0x00a10*/	u64	replicq_flush_in_progress;
+#define VXGE_HW_REPLICQ_FLUSH_IN_PROGRESS_NOA_VP(n)	vxge_mBIT(n)
+/*0x00a18*/	u64	rxpe_cmds_reset_in_progress;
+#define VXGE_HW_RXPE_CMDS_RESET_IN_PROGRESS_NOA_VP(n)	vxge_mBIT(n)
+/*0x00a20*/	u64	mxp_cmds_reset_in_progress;
+#define VXGE_HW_MXP_CMDS_RESET_IN_PROGRESS_NOA_VP(n)	vxge_mBIT(n)
+/*0x00a28*/	u64	noffload_reset_in_progress;
+#define VXGE_HW_NOFFLOAD_RESET_IN_PROGRESS_PRC_VP(n)	vxge_mBIT(n)
+/*0x00a30*/	u64	rd_req_in_progress;
+#define VXGE_HW_RD_REQ_IN_PROGRESS_VP(n)	vxge_mBIT(n)
+/*0x00a38*/	u64	rd_req_outstanding;
+#define VXGE_HW_RD_REQ_OUTSTANDING_VP(n)	vxge_mBIT(n)
+/*0x00a40*/	u64	kdfc_reset_in_progress;
+#define VXGE_HW_KDFC_RESET_IN_PROGRESS_NOA_VP(n)	vxge_mBIT(n)
+	u8	unused00b00[0x00b00-0x00a48];
+
+/*0x00b00*/	u64	one_cfg_vp;
+#define VXGE_HW_ONE_CFG_VP_RDY(n)	vxge_mBIT(n)
+/*0x00b08*/	u64	one_common;
+#define VXGE_HW_ONE_COMMON_PET_VPATH_RESET_IN_PROGRESS(n)	vxge_mBIT(n)
+	u8	unused00b80[0x00b80-0x00b10];
+
+/*0x00b80*/	u64	tim_int_en;
+#define VXGE_HW_TIM_INT_EN_TIM_VP(n)	vxge_mBIT(n)
+/*0x00b88*/	u64	tim_set_int_en;
+#define VXGE_HW_TIM_SET_INT_EN_VP(n)	vxge_mBIT(n)
+/*0x00b90*/	u64	tim_clr_int_en;
+#define VXGE_HW_TIM_CLR_INT_EN_VP(n)	vxge_mBIT(n)
+/*0x00b98*/	u64	tim_mask_int_during_reset;
+#define VXGE_HW_TIM_MASK_INT_DURING_RESET_VPATH(n)	vxge_mBIT(n)
+/*0x00ba0*/	u64	tim_reset_in_progress;
+#define VXGE_HW_TIM_RESET_IN_PROGRESS_TIM_VPATH(n)	vxge_mBIT(n)
+/*0x00ba8*/	u64	tim_outstanding_bmap;
+#define VXGE_HW_TIM_OUTSTANDING_BMAP_TIM_VPATH(n)	vxge_mBIT(n)
+	u8	unused00c00[0x00c00-0x00bb0];
+
+/*0x00c00*/	u64	msg_reset_in_progress;
+#define VXGE_HW_MSG_RESET_IN_PROGRESS_MSG_COMPOSITE(val) vxge_vBIT(val, 0, 17)
+/*0x00c08*/	u64	msg_mxp_mr_ready;
+#define VXGE_HW_MSG_MXP_MR_READY_MP_BOOTED(n)	vxge_mBIT(n)
+/*0x00c10*/	u64	msg_uxp_mr_ready;
+#define VXGE_HW_MSG_UXP_MR_READY_UP_BOOTED(n)	vxge_mBIT(n)
+/*0x00c18*/	u64	msg_dmq_noni_rtl_prefetch;
+#define VXGE_HW_MSG_DMQ_NONI_RTL_PREFETCH_BYPASS_ENABLE(n)	vxge_mBIT(n)
+/*0x00c20*/	u64	msg_umq_rtl_bwr;
+#define VXGE_HW_MSG_UMQ_RTL_BWR_PREFETCH_DISABLE(n)	vxge_mBIT(n)
+	u8	unused00d00[0x00d00-0x00c28];
+
+/*0x00d00*/	u64	cmn_rsthdlr_cfg0;
+#define VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(val) vxge_vBIT(val, 0, 17)
+/*0x00d08*/	u64	cmn_rsthdlr_cfg1;
+#define VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(val) vxge_vBIT(val, 0, 17)
+/*0x00d10*/	u64	cmn_rsthdlr_cfg2;
+#define VXGE_HW_CMN_RSTHDLR_CFG2_SW_RESET_FIFO0(val) vxge_vBIT(val, 0, 17)
+/*0x00d18*/	u64	cmn_rsthdlr_cfg3;
+#define VXGE_HW_CMN_RSTHDLR_CFG3_SW_RESET_FIFO1(val) vxge_vBIT(val, 0, 17)
+/*0x00d20*/	u64	cmn_rsthdlr_cfg4;
+#define VXGE_HW_CMN_RSTHDLR_CFG4_SW_RESET_FIFO2(val) vxge_vBIT(val, 0, 17)
+	u8	unused00d40[0x00d40-0x00d28];
+
+/*0x00d40*/	u64	cmn_rsthdlr_cfg8;
+#define VXGE_HW_CMN_RSTHDLR_CFG8_INCR_VPATH_INST_NUM(val) vxge_vBIT(val, 0, 17)
+/*0x00d48*/	u64	stats_cfg0;
+#define VXGE_HW_STATS_CFG0_STATS_ENABLE(val) vxge_vBIT(val, 0, 17)
+	u8	unused00da8[0x00da8-0x00d50];
+
+/*0x00da8*/	u64	clear_msix_mask_vect[4];
+#define VXGE_HW_CLEAR_MSIX_MASK_VECT_CLEAR_MSIX_MASK_VECT(val) \
+						vxge_vBIT(val, 0, 17)
+/*0x00dc8*/	u64	set_msix_mask_vect[4];
+#define VXGE_HW_SET_MSIX_MASK_VECT_SET_MSIX_MASK_VECT(val) vxge_vBIT(val, 0, 17)
+/*0x00de8*/	u64	clear_msix_mask_all_vect;
+#define	VXGE_HW_CLEAR_MSIX_MASK_ALL_VECT_CLEAR_MSIX_MASK_ALL_VECT(val)	\
+							vxge_vBIT(val, 0, 17)
+/*0x00df0*/	u64	set_msix_mask_all_vect;
+#define	VXGE_HW_SET_MSIX_MASK_ALL_VECT_SET_MSIX_MASK_ALL_VECT(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x00df8*/	u64	mask_vector[4];
+#define VXGE_HW_MASK_VECTOR_MASK_VECTOR(val) vxge_vBIT(val, 0, 17)
+/*0x00e18*/	u64	msix_pending_vector[4];
+#define VXGE_HW_MSIX_PENDING_VECTOR_MSIX_PENDING_VECTOR(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x00e38*/	u64	clr_msix_one_shot_vec[4];
+#define	VXGE_HW_CLR_MSIX_ONE_SHOT_VEC_CLR_MSIX_ONE_SHOT_VEC(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x00e58*/	u64	titan_asic_id;
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_DEVICE_ID(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_MAJOR_REVISION(val) vxge_vBIT(val, 48, 8)
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_MINOR_REVISION(val) vxge_vBIT(val, 56, 8)
+/*0x00e60*/	u64	titan_general_int_status;
+#define	VXGE_HW_TITAN_GENERAL_INT_STATUS_MRPCIM_ALARM_INT	vxge_mBIT(0)
+#define	VXGE_HW_TITAN_GENERAL_INT_STATUS_SRPCIM_ALARM_INT	vxge_mBIT(1)
+#define	VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT	vxge_mBIT(2)
+#define	VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(val) \
+							vxge_vBIT(val, 3, 17)
+	u8	unused00e70[0x00e70-0x00e68];
+
+/*0x00e70*/	u64	titan_mask_all_int;
+#define	VXGE_HW_TITAN_MASK_ALL_INT_ALARM	vxge_mBIT(7)
+#define	VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC	vxge_mBIT(15)
+	u8	unused00e80[0x00e80-0x00e78];
+
+/*0x00e80*/	u64	tim_int_status0;
+#define VXGE_HW_TIM_INT_STATUS0_TIM_INT_STATUS0(val) vxge_vBIT(val, 0, 64)
+/*0x00e88*/	u64	tim_int_mask0;
+#define VXGE_HW_TIM_INT_MASK0_TIM_INT_MASK0(val) vxge_vBIT(val, 0, 64)
+/*0x00e90*/	u64	tim_int_status1;
+#define VXGE_HW_TIM_INT_STATUS1_TIM_INT_STATUS1(val) vxge_vBIT(val, 0, 4)
+/*0x00e98*/	u64	tim_int_mask1;
+#define VXGE_HW_TIM_INT_MASK1_TIM_INT_MASK1(val) vxge_vBIT(val, 0, 4)
+/*0x00ea0*/	u64	rti_int_status;
+#define VXGE_HW_RTI_INT_STATUS_RTI_INT_STATUS(val) vxge_vBIT(val, 0, 17)
+/*0x00ea8*/	u64	rti_int_mask;
+#define VXGE_HW_RTI_INT_MASK_RTI_INT_MASK(val) vxge_vBIT(val, 0, 17)
+/*0x00eb0*/	u64	adapter_status;
+#define	VXGE_HW_ADAPTER_STATUS_RTDMA_RTDMA_READY	vxge_mBIT(0)
+#define	VXGE_HW_ADAPTER_STATUS_WRDMA_WRDMA_READY	vxge_mBIT(1)
+#define	VXGE_HW_ADAPTER_STATUS_KDFC_KDFC_READY	vxge_mBIT(2)
+#define	VXGE_HW_ADAPTER_STATUS_TPA_TMAC_BUF_EMPTY	vxge_mBIT(3)
+#define	VXGE_HW_ADAPTER_STATUS_RDCTL_PIC_QUIESCENT	vxge_mBIT(4)
+#define	VXGE_HW_ADAPTER_STATUS_XGMAC_NETWORK_FAULT	vxge_mBIT(5)
+#define	VXGE_HW_ADAPTER_STATUS_ROCRC_OFFLOAD_QUIESCENT	vxge_mBIT(6)
+#define	VXGE_HW_ADAPTER_STATUS_G3IF_FB_G3IF_FB_GDDR3_READY	vxge_mBIT(7)
+#define	VXGE_HW_ADAPTER_STATUS_G3IF_CM_G3IF_CM_GDDR3_READY	vxge_mBIT(8)
+#define	VXGE_HW_ADAPTER_STATUS_RIC_RIC_RUNNING	vxge_mBIT(9)
+#define	VXGE_HW_ADAPTER_STATUS_CMG_C_PLL_IN_LOCK	vxge_mBIT(10)
+#define	VXGE_HW_ADAPTER_STATUS_XGMAC_X_PLL_IN_LOCK	vxge_mBIT(11)
+#define	VXGE_HW_ADAPTER_STATUS_FBIF_M_PLL_IN_LOCK	vxge_mBIT(12)
+#define VXGE_HW_ADAPTER_STATUS_PCC_PCC_IDLE(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_ADAPTER_STATUS_ROCRC_RC_PRC_QUIESCENT(val) vxge_vBIT(val, 44, 8)
+/*0x00eb8*/	u64	gen_ctrl;
+#define	VXGE_HW_GEN_CTRL_SPI_MRPCIM_WR_DIS	vxge_mBIT(0)
+#define	VXGE_HW_GEN_CTRL_SPI_MRPCIM_RD_DIS	vxge_mBIT(1)
+#define	VXGE_HW_GEN_CTRL_SPI_SRPCIM_WR_DIS	vxge_mBIT(2)
+#define	VXGE_HW_GEN_CTRL_SPI_SRPCIM_RD_DIS	vxge_mBIT(3)
+#define	VXGE_HW_GEN_CTRL_SPI_DEBUG_DIS	vxge_mBIT(4)
+#define	VXGE_HW_GEN_CTRL_SPI_APP_LTSSM_TIMER_DIS	vxge_mBIT(5)
+#define VXGE_HW_GEN_CTRL_SPI_NOT_USED(val) vxge_vBIT(val, 6, 4)
+	u8	unused00ed0[0x00ed0-0x00ec0];
+
+/*0x00ed0*/	u64	adapter_ready;
+#define	VXGE_HW_ADAPTER_READY_ADAPTER_READY	vxge_mBIT(63)
+/*0x00ed8*/	u64	outstanding_read;
+#define VXGE_HW_OUTSTANDING_READ_OUTSTANDING_READ(val) vxge_vBIT(val, 0, 17)
+/*0x00ee0*/	u64	vpath_rst_in_prog;
+#define VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(val) vxge_vBIT(val, 0, 17)
+/*0x00ee8*/	u64	vpath_reg_modified;
+#define VXGE_HW_VPATH_REG_MODIFIED_VPATH_REG_MODIFIED(val) vxge_vBIT(val, 0, 17)
+	u8	unused00fc0[0x00fc0-0x00ef0];
+
+/*0x00fc0*/	u64	cp_reset_in_progress;
+#define VXGE_HW_CP_RESET_IN_PROGRESS_CP_VPATH(n)	vxge_mBIT(n)
+	u8	unused01080[0x01080-0x00fc8];
+
+/*0x01080*/	u64	xgmac_ready;
+#define VXGE_HW_XGMAC_READY_XMACJ_READY(val) vxge_vBIT(val, 0, 17)
+	u8	unused010c0[0x010c0-0x01088];
+
+/*0x010c0*/	u64	fbif_ready;
+#define VXGE_HW_FBIF_READY_FAU_READY(val) vxge_vBIT(val, 0, 17)
+	u8	unused01100[0x01100-0x010c8];
+
+/*0x01100*/	u64	vplane_assignments;
+#define VXGE_HW_VPLANE_ASSIGNMENTS_VPLANE_ASSIGNMENTS(val) vxge_vBIT(val, 3, 5)
+/*0x01108*/	u64	vpath_assignments;
+#define VXGE_HW_VPATH_ASSIGNMENTS_VPATH_ASSIGNMENTS(val) vxge_vBIT(val, 0, 17)
+/*0x01110*/	u64	resource_assignments;
+#define VXGE_HW_RESOURCE_ASSIGNMENTS_RESOURCE_ASSIGNMENTS(val) \
+						vxge_vBIT(val, 0, 17)
+/*0x01118*/	u64	host_type_assignments;
+#define	VXGE_HW_HOST_TYPE_ASSIGNMENTS_HOST_TYPE_ASSIGNMENTS(val) \
+							vxge_vBIT(val, 5, 3)
+	u8	unused01128[0x01128-0x01120];
+
+/*0x01128*/	u64	max_resource_assignments;
+#define VXGE_HW_MAX_RESOURCE_ASSIGNMENTS_PCI_MAX_VPLANE(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_MAX_RESOURCE_ASSIGNMENTS_PCI_MAX_VPATHS(val) \
+						vxge_vBIT(val, 11, 5)
+/*0x01130*/	u64	pf_vpath_assignments;
+#define VXGE_HW_PF_VPATH_ASSIGNMENTS_PF_VPATH_ASSIGNMENTS(val) \
+						vxge_vBIT(val, 0, 17)
+	u8	unused01200[0x01200-0x01138];
+
+/*0x01200*/	u64	rts_access_icmp;
+#define VXGE_HW_RTS_ACCESS_ICMP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01208*/	u64	rts_access_tcpsyn;
+#define VXGE_HW_RTS_ACCESS_TCPSYN_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01210*/	u64	rts_access_zl4pyld;
+#define VXGE_HW_RTS_ACCESS_ZL4PYLD_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01218*/	u64	rts_access_l4prtcl_tcp;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_TCP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01220*/	u64	rts_access_l4prtcl_udp;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_UDP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01228*/	u64	rts_access_l4prtcl_flex;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_FLEX_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01230*/	u64	rts_access_ipfrag;
+#define VXGE_HW_RTS_ACCESS_IPFRAG_EN(val) vxge_vBIT(val, 0, 17)
+
+} __packed;
+
+struct vxge_hw_memrepair_reg {
+	u64	unused1;
+	u64	unused2;
+} __packed;
+
+struct vxge_hw_pcicfgmgmt_reg {
+
+/*0x00000*/	u64	resource_no;
+#define	VXGE_HW_RESOURCE_NO_PFN_OR_VF	BIT(3)
+/*0x00008*/	u64	bargrp_pf_or_vf_bar0_mask;
+#define	VXGE_HW_BARGRP_PF_OR_VF_BAR0_MASK_BARGRP_PF_OR_VF_BAR0_MASK(val) \
+							vxge_vBIT(val, 2, 6)
+/*0x00010*/	u64	bargrp_pf_or_vf_bar1_mask;
+#define	VXGE_HW_BARGRP_PF_OR_VF_BAR1_MASK_BARGRP_PF_OR_VF_BAR1_MASK(val) \
+							vxge_vBIT(val, 2, 6)
+/*0x00018*/	u64	bargrp_pf_or_vf_bar2_mask;
+#define	VXGE_HW_BARGRP_PF_OR_VF_BAR2_MASK_BARGRP_PF_OR_VF_BAR2_MASK(val) \
+							vxge_vBIT(val, 2, 6)
+/*0x00020*/	u64	msixgrp_no;
+#define VXGE_HW_MSIXGRP_NO_TABLE_SIZE(val) vxge_vBIT(val, 5, 11)
+
+} __packed;
+
+struct vxge_hw_mrpcim_reg {
+/*0x00000*/	u64	g3fbct_int_status;
+#define	VXGE_HW_G3FBCT_INT_STATUS_ERR_G3IF_INT	vxge_mBIT(0)
+/*0x00008*/	u64	g3fbct_int_mask;
+/*0x00010*/	u64	g3fbct_err_reg;
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_SM_ERR	vxge_mBIT(4)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_DECC	vxge_mBIT(5)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_U_DECC	vxge_mBIT(6)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_CTRL_FIFO_DECC	vxge_mBIT(7)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_SECC	vxge_mBIT(29)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_U_SECC	vxge_mBIT(30)
+#define	VXGE_HW_G3FBCT_ERR_REG_G3IF_CTRL_FIFO_SECC	vxge_mBIT(31)
+/*0x00018*/	u64	g3fbct_err_mask;
+/*0x00020*/	u64	g3fbct_err_alarm;
+
+	u8	unused00a00[0x00a00-0x00028];
+
+/*0x00a00*/	u64	wrdma_int_status;
+#define	VXGE_HW_WRDMA_INT_STATUS_RC_ALARM_RC_INT	vxge_mBIT(0)
+#define	VXGE_HW_WRDMA_INT_STATUS_RXDRM_SM_ERR_RXDRM_INT	vxge_mBIT(1)
+#define	VXGE_HW_WRDMA_INT_STATUS_RXDCM_SM_ERR_RXDCM_SM_INT	vxge_mBIT(2)
+#define	VXGE_HW_WRDMA_INT_STATUS_RXDWM_SM_ERR_RXDWM_INT	vxge_mBIT(3)
+#define	VXGE_HW_WRDMA_INT_STATUS_RDA_ERR_RDA_INT	vxge_mBIT(6)
+#define	VXGE_HW_WRDMA_INT_STATUS_RDA_ECC_DB_RDA_ECC_DB_INT	vxge_mBIT(8)
+#define	VXGE_HW_WRDMA_INT_STATUS_RDA_ECC_SG_RDA_ECC_SG_INT	vxge_mBIT(9)
+#define	VXGE_HW_WRDMA_INT_STATUS_FRF_ALARM_FRF_INT	vxge_mBIT(12)
+#define	VXGE_HW_WRDMA_INT_STATUS_ROCRC_ALARM_ROCRC_INT	vxge_mBIT(13)
+#define	VXGE_HW_WRDMA_INT_STATUS_WDE0_ALARM_WDE0_INT	vxge_mBIT(14)
+#define	VXGE_HW_WRDMA_INT_STATUS_WDE1_ALARM_WDE1_INT	vxge_mBIT(15)
+#define	VXGE_HW_WRDMA_INT_STATUS_WDE2_ALARM_WDE2_INT	vxge_mBIT(16)
+#define	VXGE_HW_WRDMA_INT_STATUS_WDE3_ALARM_WDE3_INT	vxge_mBIT(17)
+/*0x00a08*/	u64	wrdma_int_mask;
+/*0x00a10*/	u64	rc_alarm_reg;
+#define	VXGE_HW_RC_ALARM_REG_FTC_SM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_RC_ALARM_REG_FTC_SM_PHASE_ERR	vxge_mBIT(1)
+#define	VXGE_HW_RC_ALARM_REG_BTDWM_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_RC_ALARM_REG_BTC_SM_ERR	vxge_mBIT(3)
+#define	VXGE_HW_RC_ALARM_REG_BTDCM_SM_ERR	vxge_mBIT(4)
+#define	VXGE_HW_RC_ALARM_REG_BTDRM_SM_ERR	vxge_mBIT(5)
+#define	VXGE_HW_RC_ALARM_REG_RMM_RXD_RC_ECC_DB_ERR	vxge_mBIT(6)
+#define	VXGE_HW_RC_ALARM_REG_RMM_RXD_RC_ECC_SG_ERR	vxge_mBIT(7)
+#define	VXGE_HW_RC_ALARM_REG_RHS_RXD_RHS_ECC_DB_ERR	vxge_mBIT(8)
+#define	VXGE_HW_RC_ALARM_REG_RHS_RXD_RHS_ECC_SG_ERR	vxge_mBIT(9)
+#define	VXGE_HW_RC_ALARM_REG_RMM_SM_ERR	vxge_mBIT(10)
+#define	VXGE_HW_RC_ALARM_REG_BTC_VPATH_MISMATCH_ERR	vxge_mBIT(12)
+/*0x00a18*/	u64	rc_alarm_mask;
+/*0x00a20*/	u64	rc_alarm_alarm;
+/*0x00a28*/	u64	rxdrm_sm_err_reg;
+#define VXGE_HW_RXDRM_SM_ERR_REG_PRC_VP(n)	vxge_mBIT(n)
+/*0x00a30*/	u64	rxdrm_sm_err_mask;
+/*0x00a38*/	u64	rxdrm_sm_err_alarm;
+/*0x00a40*/	u64	rxdcm_sm_err_reg;
+#define VXGE_HW_RXDCM_SM_ERR_REG_PRC_VP(n)	vxge_mBIT(n)
+/*0x00a48*/	u64	rxdcm_sm_err_mask;
+/*0x00a50*/	u64	rxdcm_sm_err_alarm;
+/*0x00a58*/	u64	rxdwm_sm_err_reg;
+#define VXGE_HW_RXDWM_SM_ERR_REG_PRC_VP(n)	vxge_mBIT(n)
+/*0x00a60*/	u64	rxdwm_sm_err_mask;
+/*0x00a68*/	u64	rxdwm_sm_err_alarm;
+/*0x00a70*/	u64	rda_err_reg;
+#define	VXGE_HW_RDA_ERR_REG_RDA_SM0_ERR_ALARM	vxge_mBIT(0)
+#define	VXGE_HW_RDA_ERR_REG_RDA_MISC_ERR	vxge_mBIT(1)
+#define	VXGE_HW_RDA_ERR_REG_RDA_PCIX_ERR	vxge_mBIT(2)
+#define	VXGE_HW_RDA_ERR_REG_RDA_RXD_ECC_DB_ERR	vxge_mBIT(3)
+#define	VXGE_HW_RDA_ERR_REG_RDA_FRM_ECC_DB_ERR	vxge_mBIT(4)
+#define	VXGE_HW_RDA_ERR_REG_RDA_UQM_ECC_DB_ERR	vxge_mBIT(5)
+#define	VXGE_HW_RDA_ERR_REG_RDA_IMM_ECC_DB_ERR	vxge_mBIT(6)
+#define	VXGE_HW_RDA_ERR_REG_RDA_TIM_ECC_DB_ERR	vxge_mBIT(7)
+/*0x00a78*/	u64	rda_err_mask;
+/*0x00a80*/	u64	rda_err_alarm;
+/*0x00a88*/	u64	rda_ecc_db_reg;
+#define VXGE_HW_RDA_ECC_DB_REG_RDA_RXD_ERR(n)	vxge_mBIT(n)
+/*0x00a90*/	u64	rda_ecc_db_mask;
+/*0x00a98*/	u64	rda_ecc_db_alarm;
+/*0x00aa0*/	u64	rda_ecc_sg_reg;
+#define VXGE_HW_RDA_ECC_SG_REG_RDA_RXD_ERR(n)	vxge_mBIT(n)
+/*0x00aa8*/	u64	rda_ecc_sg_mask;
+/*0x00ab0*/	u64	rda_ecc_sg_alarm;
+/*0x00ab8*/	u64	rqa_err_reg;
+#define	VXGE_HW_RQA_ERR_REG_RQA_SM_ERR_ALARM	vxge_mBIT(0)
+/*0x00ac0*/	u64	rqa_err_mask;
+/*0x00ac8*/	u64	rqa_err_alarm;
+/*0x00ad0*/	u64	frf_alarm_reg;
+#define VXGE_HW_FRF_ALARM_REG_PRC_VP_FRF_SM_ERR(n)	vxge_mBIT(n)
+/*0x00ad8*/	u64	frf_alarm_mask;
+/*0x00ae0*/	u64	frf_alarm_alarm;
+/*0x00ae8*/	u64	rocrc_alarm_reg;
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_QCC_BYP_ECC_DB	vxge_mBIT(0)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_QCC_BYP_ECC_SG	vxge_mBIT(1)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_NMA_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_IMMM_ECC_DB	vxge_mBIT(3)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_IMMM_ECC_SG	vxge_mBIT(4)
+#define	VXGE_HW_ROCRC_ALARM_REG_UDQ_UMQM_ECC_DB	vxge_mBIT(5)
+#define	VXGE_HW_ROCRC_ALARM_REG_UDQ_UMQM_ECC_SG	vxge_mBIT(6)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_RCBM_ECC_DB	vxge_mBIT(11)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_RCBM_ECC_SG	vxge_mBIT(12)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_EGB_RSVD_ERR	vxge_mBIT(13)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_EGB_OWN_ERR	vxge_mBIT(14)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_BYP_OWN_ERR	vxge_mBIT(15)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_OWN_NOT_ASSIGNED_ERR	vxge_mBIT(16)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_OWN_RSVD_SYNC_ERR	vxge_mBIT(17)
+#define	VXGE_HW_ROCRC_ALARM_REG_QCQ_LOST_EGB_ERR	vxge_mBIT(18)
+#define	VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ0_OVERFLOW	vxge_mBIT(19)
+#define	VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ1_OVERFLOW	vxge_mBIT(20)
+#define	VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ2_OVERFLOW	vxge_mBIT(21)
+#define	VXGE_HW_ROCRC_ALARM_REG_NOA_WCT_CMD_FIFO_ERR	vxge_mBIT(22)
+/*0x00af0*/	u64	rocrc_alarm_mask;
+/*0x00af8*/	u64	rocrc_alarm_alarm;
+/*0x00b00*/	u64	wde0_alarm_reg;
+#define	VXGE_HW_WDE0_ALARM_REG_WDE0_DCC_SM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_WDE0_ALARM_REG_WDE0_PRM_SM_ERR	vxge_mBIT(1)
+#define	VXGE_HW_WDE0_ALARM_REG_WDE0_CP_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_WDE0_ALARM_REG_WDE0_CP_CMD_ERR	vxge_mBIT(3)
+#define	VXGE_HW_WDE0_ALARM_REG_WDE0_PCR_SM_ERR	vxge_mBIT(4)
+/*0x00b08*/	u64	wde0_alarm_mask;
+/*0x00b10*/	u64	wde0_alarm_alarm;
+/*0x00b18*/	u64	wde1_alarm_reg;
+#define	VXGE_HW_WDE1_ALARM_REG_WDE1_DCC_SM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_WDE1_ALARM_REG_WDE1_PRM_SM_ERR	vxge_mBIT(1)
+#define	VXGE_HW_WDE1_ALARM_REG_WDE1_CP_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_WDE1_ALARM_REG_WDE1_CP_CMD_ERR	vxge_mBIT(3)
+#define	VXGE_HW_WDE1_ALARM_REG_WDE1_PCR_SM_ERR	vxge_mBIT(4)
+/*0x00b20*/	u64	wde1_alarm_mask;
+/*0x00b28*/	u64	wde1_alarm_alarm;
+/*0x00b30*/	u64	wde2_alarm_reg;
+#define	VXGE_HW_WDE2_ALARM_REG_WDE2_DCC_SM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_WDE2_ALARM_REG_WDE2_PRM_SM_ERR	vxge_mBIT(1)
+#define	VXGE_HW_WDE2_ALARM_REG_WDE2_CP_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_WDE2_ALARM_REG_WDE2_CP_CMD_ERR	vxge_mBIT(3)
+#define	VXGE_HW_WDE2_ALARM_REG_WDE2_PCR_SM_ERR	vxge_mBIT(4)
+/*0x00b38*/	u64	wde2_alarm_mask;
+/*0x00b40*/	u64	wde2_alarm_alarm;
+/*0x00b48*/	u64	wde3_alarm_reg;
+#define	VXGE_HW_WDE3_ALARM_REG_WDE3_DCC_SM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_WDE3_ALARM_REG_WDE3_PRM_SM_ERR	vxge_mBIT(1)
+#define	VXGE_HW_WDE3_ALARM_REG_WDE3_CP_SM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_WDE3_ALARM_REG_WDE3_CP_CMD_ERR	vxge_mBIT(3)
+#define	VXGE_HW_WDE3_ALARM_REG_WDE3_PCR_SM_ERR	vxge_mBIT(4)
+/*0x00b50*/	u64	wde3_alarm_mask;
+/*0x00b58*/	u64	wde3_alarm_alarm;
+
+	u8	unused00be8[0x00be8-0x00b60];
+
+/*0x00be8*/	u64	rx_w_round_robin_0;
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_7(val) vxge_vBIT(val, 59, 5)
+/*0x00bf0*/	u64	rx_w_round_robin_1;
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_8(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_9(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_10(val) \
+						vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_11(val) \
+						vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_12(val) \
+						vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_13(val) \
+						vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_14(val) \
+						vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_15(val) \
+						vxge_vBIT(val, 59, 5)
+/*0x00bf8*/	u64	rx_w_round_robin_2;
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_16(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_17(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_18(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_19(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_20(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_21(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_22(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_23(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c00*/	u64	rx_w_round_robin_3;
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_24(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_25(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_26(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_27(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_28(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_29(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_30(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_31(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c08*/	u64	rx_w_round_robin_4;
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_32(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_33(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_34(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_35(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_36(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_37(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_38(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_39(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c10*/	u64	rx_w_round_robin_5;
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_40(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_41(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_42(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_43(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_44(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_45(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_46(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_47(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c18*/	u64	rx_w_round_robin_6;
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_48(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_49(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_50(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_51(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_52(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_53(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_54(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_55(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c20*/	u64	rx_w_round_robin_7;
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_56(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_57(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_58(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_59(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_60(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_61(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_62(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_63(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c28*/	u64	rx_w_round_robin_8;
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_64(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_65(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_66(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_67(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_68(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_69(val) \
+						vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_70(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_71(val) \
+						vxge_vBIT(val, 59, 5)
+/*0x00c30*/	u64	rx_w_round_robin_9;
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_72(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_73(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_74(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_75(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_76(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_77(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_78(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_79(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c38*/	u64	rx_w_round_robin_10;
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_80(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_81(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_82(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_83(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_84(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_85(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_86(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_87(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c40*/	u64	rx_w_round_robin_11;
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_88(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_89(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_90(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_91(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_92(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_93(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_94(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_95(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c48*/	u64	rx_w_round_robin_12;
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_96(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_97(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_98(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_99(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_100(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_101(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_102(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_103(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c50*/	u64	rx_w_round_robin_13;
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_104(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_105(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_106(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_107(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_108(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_109(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_110(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_111(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c58*/	u64	rx_w_round_robin_14;
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_112(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_113(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_114(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_115(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_116(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_117(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_118(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_119(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c60*/	u64	rx_w_round_robin_15;
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_120(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_121(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_122(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_123(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_124(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_125(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_126(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_127(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c68*/	u64	rx_w_round_robin_16;
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_128(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_129(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_130(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_131(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_132(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_133(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_134(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_135(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c70*/	u64	rx_w_round_robin_17;
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_136(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_137(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_138(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_139(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_140(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_141(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_142(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_143(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c78*/	u64	rx_w_round_robin_18;
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_144(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_145(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_146(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_147(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_148(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_149(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_150(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_151(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c80*/	u64	rx_w_round_robin_19;
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_152(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_153(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_154(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_155(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_156(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_157(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_158(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_159(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c88*/	u64	rx_w_round_robin_20;
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_160(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_161(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_162(val) \
+							vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_163(val) \
+							vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_164(val) \
+							vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_165(val) \
+							vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_166(val) \
+							vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_167(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00c90*/	u64	rx_w_round_robin_21;
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_168(val) \
+							vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_169(val) \
+							vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_170(val) \
+							vxge_vBIT(val, 19, 5)
+
+#define VXGE_HW_WRR_RING_SERVICE_STATES			171
+#define VXGE_HW_WRR_RING_COUNT				22
+
+/*0x00c98*/	u64	rx_queue_priority_0;
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+/*0x00ca0*/	u64	rx_queue_priority_1;
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_8(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_9(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_10(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_11(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_12(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_13(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_14(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_15(val) vxge_vBIT(val, 59, 5)
+/*0x00ca8*/	u64	rx_queue_priority_2;
+#define VXGE_HW_RX_QUEUE_PRIORITY_2_RX_Q_NUMBER_16(val) vxge_vBIT(val, 3, 5)
+	u8	unused00cc8[0x00cc8-0x00cb0];
+
+/*0x00cc8*/	u64	replication_queue_priority;
+#define	VXGE_HW_REPLICATION_QUEUE_PRIORITY_REPLICATION_QUEUE_PRIORITY(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00cd0*/	u64	rx_queue_select;
+#define VXGE_HW_RX_QUEUE_SELECT_NUMBER(n)	vxge_mBIT(n)
+#define	VXGE_HW_RX_QUEUE_SELECT_ENABLE_CODE	vxge_mBIT(15)
+#define	VXGE_HW_RX_QUEUE_SELECT_ENABLE_HIERARCHICAL_PRTY	vxge_mBIT(23)
+/*0x00cd8*/	u64	rqa_vpbp_ctrl;
+#define	VXGE_HW_RQA_VPBP_CTRL_WR_XON_DIS	vxge_mBIT(15)
+#define	VXGE_HW_RQA_VPBP_CTRL_ROCRC_DIS	vxge_mBIT(23)
+#define	VXGE_HW_RQA_VPBP_CTRL_TXPE_DIS	vxge_mBIT(31)
+/*0x00ce0*/	u64	rx_multi_cast_ctrl;
+#define	VXGE_HW_RX_MULTI_CAST_CTRL_TIME_OUT_DIS	vxge_mBIT(0)
+#define	VXGE_HW_RX_MULTI_CAST_CTRL_FRM_DROP_DIS	vxge_mBIT(1)
+#define VXGE_HW_RX_MULTI_CAST_CTRL_NO_RXD_TIME_OUT_CNT(val) \
+							vxge_vBIT(val, 2, 30)
+#define VXGE_HW_RX_MULTI_CAST_CTRL_TIME_OUT_CNT(val) vxge_vBIT(val, 32, 32)
+/*0x00ce8*/	u64	wde_prm_ctrl;
+#define VXGE_HW_WDE_PRM_CTRL_SPAV_THRESHOLD(val) vxge_vBIT(val, 2, 10)
+#define VXGE_HW_WDE_PRM_CTRL_SPLIT_THRESHOLD(val) vxge_vBIT(val, 18, 14)
+#define	VXGE_HW_WDE_PRM_CTRL_SPLIT_ON_1ST_ROW	vxge_mBIT(32)
+#define	VXGE_HW_WDE_PRM_CTRL_SPLIT_ON_ROW_BNDRY	vxge_mBIT(33)
+#define VXGE_HW_WDE_PRM_CTRL_FB_ROW_SIZE(val) vxge_vBIT(val, 46, 2)
+/*0x00cf0*/	u64	noa_ctrl;
+#define VXGE_HW_NOA_CTRL_FRM_PRTY_QUOTA(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_NOA_CTRL_NON_FRM_PRTY_QUOTA(val) vxge_vBIT(val, 11, 5)
+#define	VXGE_HW_NOA_CTRL_IGNORE_KDFC_IF_STATUS	vxge_mBIT(16)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE0(val) vxge_vBIT(val, 37, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE1(val) vxge_vBIT(val, 45, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE2(val) vxge_vBIT(val, 53, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE3(val) vxge_vBIT(val, 60, 4)
+/*0x00cf8*/	u64	phase_cfg;
+#define	VXGE_HW_PHASE_CFG_QCC_WR_PHASE_EN	vxge_mBIT(0)
+#define	VXGE_HW_PHASE_CFG_QCC_RD_PHASE_EN	vxge_mBIT(3)
+#define	VXGE_HW_PHASE_CFG_IMMM_WR_PHASE_EN	vxge_mBIT(7)
+#define	VXGE_HW_PHASE_CFG_IMMM_RD_PHASE_EN	vxge_mBIT(11)
+#define	VXGE_HW_PHASE_CFG_UMQM_WR_PHASE_EN	vxge_mBIT(15)
+#define	VXGE_HW_PHASE_CFG_UMQM_RD_PHASE_EN	vxge_mBIT(19)
+#define	VXGE_HW_PHASE_CFG_RCBM_WR_PHASE_EN	vxge_mBIT(23)
+#define	VXGE_HW_PHASE_CFG_RCBM_RD_PHASE_EN	vxge_mBIT(27)
+#define	VXGE_HW_PHASE_CFG_RXD_RC_WR_PHASE_EN	vxge_mBIT(31)
+#define	VXGE_HW_PHASE_CFG_RXD_RC_RD_PHASE_EN	vxge_mBIT(35)
+#define	VXGE_HW_PHASE_CFG_RXD_RHS_WR_PHASE_EN	vxge_mBIT(39)
+#define	VXGE_HW_PHASE_CFG_RXD_RHS_RD_PHASE_EN	vxge_mBIT(43)
+/*0x00d00*/	u64	rcq_bypq_cfg;
+#define VXGE_HW_RCQ_BYPQ_CFG_OVERFLOW_THRESHOLD(val) vxge_vBIT(val, 10, 22)
+#define VXGE_HW_RCQ_BYPQ_CFG_BYP_ON_THRESHOLD(val) vxge_vBIT(val, 39, 9)
+#define VXGE_HW_RCQ_BYPQ_CFG_BYP_OFF_THRESHOLD(val) vxge_vBIT(val, 55, 9)
+	u8	unused00e00[0x00e00-0x00d08];
+
+/*0x00e00*/	u64	doorbell_int_status;
+#define	VXGE_HW_DOORBELL_INT_STATUS_KDFC_ERR_REG_TXDMA_KDFC_INT	vxge_mBIT(7)
+#define	VXGE_HW_DOORBELL_INT_STATUS_USDC_ERR_REG_TXDMA_USDC_INT	vxge_mBIT(15)
+/*0x00e08*/	u64	doorbell_int_mask;
+/*0x00e10*/	u64	kdfc_err_reg;
+#define	VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_ECC_SG_ERR	vxge_mBIT(7)
+#define	VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_ECC_DB_ERR	vxge_mBIT(15)
+#define	VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_SM_ERR_ALARM	vxge_mBIT(23)
+#define	VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_MISC_ERR_1	vxge_mBIT(32)
+#define	VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_PCIX_ERR	vxge_mBIT(39)
+/*0x00e18*/	u64	kdfc_err_mask;
+/*0x00e20*/	u64	kdfc_err_reg_alarm;
+#define	VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_ECC_SG_ERR	vxge_mBIT(7)
+#define	VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_ECC_DB_ERR	vxge_mBIT(15)
+#define	VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_SM_ERR_ALARM	vxge_mBIT(23)
+#define	VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_MISC_ERR_1	vxge_mBIT(32)
+#define	VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_PCIX_ERR	vxge_mBIT(39)
+	u8	unused00e40[0x00e40-0x00e28];
+/*0x00e40*/	u64	kdfc_vp_partition_0;
+#define	VXGE_HW_KDFC_VP_PARTITION_0_ENABLE	vxge_mBIT(0)
+#define VXGE_HW_KDFC_VP_PARTITION_0_NUMBER_0(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_0_LENGTH_0(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_0_NUMBER_1(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_0_LENGTH_1(val) vxge_vBIT(val, 49, 15)
+/*0x00e48*/	u64	kdfc_vp_partition_1;
+#define VXGE_HW_KDFC_VP_PARTITION_1_NUMBER_2(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_1_LENGTH_2(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_1_NUMBER_3(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_1_LENGTH_3(val) vxge_vBIT(val, 49, 15)
+/*0x00e50*/	u64	kdfc_vp_partition_2;
+#define VXGE_HW_KDFC_VP_PARTITION_2_NUMBER_4(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_2_LENGTH_4(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_2_NUMBER_5(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_2_LENGTH_5(val) vxge_vBIT(val, 49, 15)
+/*0x00e58*/	u64	kdfc_vp_partition_3;
+#define VXGE_HW_KDFC_VP_PARTITION_3_NUMBER_6(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_3_LENGTH_6(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_3_NUMBER_7(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_3_LENGTH_7(val) vxge_vBIT(val, 49, 15)
+/*0x00e60*/	u64	kdfc_vp_partition_4;
+#define VXGE_HW_KDFC_VP_PARTITION_4_LENGTH_8(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_4_LENGTH_9(val) vxge_vBIT(val, 49, 15)
+/*0x00e68*/	u64	kdfc_vp_partition_5;
+#define VXGE_HW_KDFC_VP_PARTITION_5_LENGTH_10(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_5_LENGTH_11(val) vxge_vBIT(val, 49, 15)
+/*0x00e70*/	u64	kdfc_vp_partition_6;
+#define VXGE_HW_KDFC_VP_PARTITION_6_LENGTH_12(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_6_LENGTH_13(val) vxge_vBIT(val, 49, 15)
+/*0x00e78*/	u64	kdfc_vp_partition_7;
+#define VXGE_HW_KDFC_VP_PARTITION_7_LENGTH_14(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_7_LENGTH_15(val) vxge_vBIT(val, 49, 15)
+/*0x00e80*/	u64	kdfc_vp_partition_8;
+#define VXGE_HW_KDFC_VP_PARTITION_8_LENGTH_16(val) vxge_vBIT(val, 17, 15)
+/*0x00e88*/	u64	kdfc_w_round_robin_0;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+	u8	unused0f28[0x0f28-0x0e90];
+
+/*0x00f28*/	u64	kdfc_w_round_robin_20;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+#define VXGE_HW_WRR_FIFO_COUNT				20
+
+	u8	unused0fc8[0x0fc8-0x0f30];
+
+/*0x00fc8*/	u64	kdfc_w_round_robin_40;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+	u8	unused1068[0x01068-0x0fd0];
+
+/*0x01068*/	u64	kdfc_entry_type_sel_0;
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_0(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_1(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_2(val) vxge_vBIT(val, 22, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_3(val) vxge_vBIT(val, 30, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_4(val) vxge_vBIT(val, 38, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_5(val) vxge_vBIT(val, 46, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_6(val) vxge_vBIT(val, 54, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_7(val) vxge_vBIT(val, 62, 2)
+/*0x01070*/	u64	kdfc_entry_type_sel_1;
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_1_NUMBER_8(val) vxge_vBIT(val, 6, 2)
+/*0x01078*/	u64	kdfc_fifo_0_ctrl;
+#define VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_WEIGHTED_RR_SERVICE_STATES		176
+#define VXGE_HW_WRR_FIFO_SERVICE_STATES			153
+
+	u8	unused1100[0x01100-0x1080];
+
+/*0x01100*/	u64	kdfc_fifo_17_ctrl;
+#define VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(val) vxge_vBIT(val, 3, 5)
+
+	u8	unused1600[0x01600-0x1108];
+
+/*0x01600*/	u64	rxmac_int_status;
+#define	VXGE_HW_RXMAC_INT_STATUS_RXMAC_GEN_ERR_RXMAC_GEN_INT	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_INT_STATUS_RXMAC_ECC_ERR_RXMAC_ECC_INT	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_INT_STATUS_RXMAC_VARIOUS_ERR_RXMAC_VARIOUS_INT \
+								vxge_mBIT(11)
+/*0x01608*/	u64	rxmac_int_mask;
+	u8	unused01618[0x01618-0x01610];
+
+/*0x01618*/	u64	rxmac_gen_err_reg;
+/*0x01620*/	u64	rxmac_gen_err_mask;
+/*0x01628*/	u64	rxmac_gen_err_alarm;
+/*0x01630*/	u64	rxmac_ecc_err_reg;
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT0_RMAC_RTS_PART_SG_ERR(val) \
+							vxge_vBIT(val, 0, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT0_RMAC_RTS_PART_DB_ERR(val) \
+							vxge_vBIT(val, 4, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT1_RMAC_RTS_PART_SG_ERR(val) \
+							vxge_vBIT(val, 8, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT1_RMAC_RTS_PART_DB_ERR(val) \
+							vxge_vBIT(val, 12, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT2_RMAC_RTS_PART_SG_ERR(val) \
+							vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT2_RMAC_RTS_PART_DB_ERR(val) \
+							vxge_vBIT(val, 20, 4)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT0_SG_ERR(val) \
+							vxge_vBIT(val, 24, 2)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT0_DB_ERR(val) \
+							vxge_vBIT(val, 26, 2)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT1_SG_ERR(val) \
+							vxge_vBIT(val, 28, 2)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT1_DB_ERR(val) \
+							vxge_vBIT(val, 30, 2)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_VID_LKP_SG_ERR	vxge_mBIT(32)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_VID_LKP_DB_ERR	vxge_mBIT(33)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT0_SG_ERR	vxge_mBIT(34)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT0_DB_ERR	vxge_mBIT(35)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT1_SG_ERR	vxge_mBIT(36)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT1_DB_ERR	vxge_mBIT(37)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT2_SG_ERR	vxge_mBIT(38)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT2_DB_ERR	vxge_mBIT(39)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_MASK_SG_ERR(val) \
+							vxge_vBIT(val, 40, 7)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_MASK_DB_ERR(val) \
+							vxge_vBIT(val, 47, 7)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_LKP_SG_ERR(val) \
+							vxge_vBIT(val, 54, 3)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_LKP_DB_ERR(val) \
+							vxge_vBIT(val, 57, 3)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DS_LKP_SG_ERR \
+							vxge_mBIT(60)
+#define	VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DS_LKP_DB_ERR \
+							vxge_mBIT(61)
+/*0x01638*/	u64	rxmac_ecc_err_mask;
+/*0x01640*/	u64	rxmac_ecc_err_alarm;
+/*0x01648*/	u64	rxmac_various_err_reg;
+#define	VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT0_FSM_ERR	vxge_mBIT(0)
+#define	VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT1_FSM_ERR	vxge_mBIT(1)
+#define	VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT2_FSM_ERR	vxge_mBIT(2)
+#define	VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMACJ_RMACJ_FSM_ERR	vxge_mBIT(3)
+/*0x01650*/	u64	rxmac_various_err_mask;
+/*0x01658*/	u64	rxmac_various_err_alarm;
+/*0x01660*/	u64	rxmac_gen_cfg;
+#define	VXGE_HW_RXMAC_GEN_CFG_SCALE_RMAC_UTIL	vxge_mBIT(11)
+/*0x01668*/	u64	rxmac_authorize_all_addr;
+#define VXGE_HW_RXMAC_AUTHORIZE_ALL_ADDR_VP(n)	vxge_mBIT(n)
+/*0x01670*/	u64	rxmac_authorize_all_vid;
+#define VXGE_HW_RXMAC_AUTHORIZE_ALL_VID_VP(n)	vxge_mBIT(n)
+	u8	unused016c0[0x016c0-0x01678];
+
+/*0x016c0*/	u64	rxmac_red_rate_repl_queue;
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR0(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR1(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR2(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR3(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR0(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR1(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR2(val) vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR3(val) vxge_vBIT(val, 28, 4)
+#define	VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_TRICKLE_EN	vxge_mBIT(35)
+	u8	unused016e0[0x016e0-0x016c8];
+
+/*0x016e0*/	u64	rxmac_cfg0_port[3];
+#define	VXGE_HW_RXMAC_CFG0_PORT_RMAC_EN	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_CFG0_PORT_STRIP_FCS	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_CFG0_PORT_DISCARD_PFRM	vxge_mBIT(11)
+#define	VXGE_HW_RXMAC_CFG0_PORT_IGNORE_FCS_ERR	vxge_mBIT(15)
+#define	VXGE_HW_RXMAC_CFG0_PORT_IGNORE_LONG_ERR	vxge_mBIT(19)
+#define	VXGE_HW_RXMAC_CFG0_PORT_IGNORE_USIZED_ERR	vxge_mBIT(23)
+#define	VXGE_HW_RXMAC_CFG0_PORT_IGNORE_LEN_MISMATCH	vxge_mBIT(27)
+#define VXGE_HW_RXMAC_CFG0_PORT_MAX_PYLD_LEN(val) vxge_vBIT(val, 50, 14)
+	u8	unused01710[0x01710-0x016f8];
+
+/*0x01710*/	u64	rxmac_cfg2_port[3];
+#define	VXGE_HW_RXMAC_CFG2_PORT_PROM_EN	vxge_mBIT(3)
+/*0x01728*/	u64	rxmac_pause_cfg_port[3];
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN	vxge_mBIT(7)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_ACCEL_SEND(val) vxge_vBIT(val, 9, 3)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_DUAL_THR	vxge_mBIT(15)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_HIGH_PTIME(val) vxge_vBIT(val, 20, 16)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_IGNORE_PF_FCS_ERR	vxge_mBIT(39)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_IGNORE_PF_LEN_ERR	vxge_mBIT(43)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_LIMITER_EN	vxge_mBIT(47)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_MAX_LIMIT(val) vxge_vBIT(val, 48, 8)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_PERMIT_RATEMGMT_CTRL	vxge_mBIT(59)
+	u8	unused01758[0x01758-0x01740];
+
+/*0x01758*/	u64	rxmac_red_cfg0_port[3];
+#define VXGE_HW_RXMAC_RED_CFG0_PORT_RED_EN_VP(n)	vxge_mBIT(n)
+/*0x01770*/	u64	rxmac_red_cfg1_port[3];
+#define	VXGE_HW_RXMAC_RED_CFG1_PORT_FINE_EN	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_RED_CFG1_PORT_RED_EN_REPL_QUEUE	vxge_mBIT(11)
+/*0x01788*/	u64	rxmac_red_cfg2_port[3];
+#define VXGE_HW_RXMAC_RED_CFG2_PORT_TRICKLE_EN_VP(n)	vxge_mBIT(n)
+/*0x017a0*/	u64	rxmac_link_util_port[3];
+#define	VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_UTILIZATION(val) \
+							vxge_vBIT(val, 1, 7)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_UTIL_CFG(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_FRAC_UTIL(val) \
+							vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_PKT_WEIGHT(val) vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_SCALE_FACTOR	vxge_mBIT(23)
+	u8	unused017d0[0x017d0-0x017b8];
+
+/*0x017d0*/	u64	rxmac_status_port[3];
+#define	VXGE_HW_RXMAC_STATUS_PORT_RMAC_RX_FRM_RCVD	vxge_mBIT(3)
+	u8	unused01800[0x01800-0x017e8];
+
+/*0x01800*/	u64	rxmac_rx_pa_cfg0;
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_IGNORE_FRAME_ERR	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_SUPPORT_SNAP_AB_N	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_SEARCH_FOR_HAO	vxge_mBIT(18)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_SUPPORT_MOBILE_IPV6_HDRS	vxge_mBIT(19)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_IPV6_STOP_SEARCHING	vxge_mBIT(23)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_NO_PS_IF_UNKNOWN	vxge_mBIT(27)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_SEARCH_FOR_ETYPE	vxge_mBIT(35)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_L3_CSUM_ERR	vxge_mBIT(39)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_L3_CSUM_ERR	vxge_mBIT(43)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_L4_CSUM_ERR	vxge_mBIT(47)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_L4_CSUM_ERR	vxge_mBIT(51)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_RPA_ERR	vxge_mBIT(55)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_RPA_ERR	vxge_mBIT(59)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_JUMBO_SNAP_EN	vxge_mBIT(63)
+/*0x01808*/	u64	rxmac_rx_pa_cfg1;
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV4_TCP_INCL_PH	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV6_TCP_INCL_PH	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV4_UDP_INCL_PH	vxge_mBIT(11)
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV6_UDP_INCL_PH	vxge_mBIT(15)
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_L4_INCL_CF	vxge_mBIT(19)
+#define	VXGE_HW_RXMAC_RX_PA_CFG1_REPL_STRIP_VLAN_TAG	vxge_mBIT(23)
+	u8	unused01828[0x01828-0x01810];
+
+/*0x01828*/	u64	rts_mgr_cfg0;
+#define	VXGE_HW_RTS_MGR_CFG0_RTS_DP_SP_PRIORITY	vxge_mBIT(3)
+#define VXGE_HW_RTS_MGR_CFG0_FLEX_L4PRTCL_VALUE(val) vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_RTS_MGR_CFG0_ICMP_TRASH	vxge_mBIT(35)
+#define	VXGE_HW_RTS_MGR_CFG0_TCPSYN_TRASH	vxge_mBIT(39)
+#define	VXGE_HW_RTS_MGR_CFG0_ZL4PYLD_TRASH	vxge_mBIT(43)
+#define	VXGE_HW_RTS_MGR_CFG0_L4PRTCL_TCP_TRASH	vxge_mBIT(47)
+#define	VXGE_HW_RTS_MGR_CFG0_L4PRTCL_UDP_TRASH	vxge_mBIT(51)
+#define	VXGE_HW_RTS_MGR_CFG0_L4PRTCL_FLEX_TRASH	vxge_mBIT(55)
+#define	VXGE_HW_RTS_MGR_CFG0_IPFRAG_TRASH	vxge_mBIT(59)
+/*0x01830*/	u64	rts_mgr_cfg1;
+#define	VXGE_HW_RTS_MGR_CFG1_DA_ACTIVE_TABLE	vxge_mBIT(3)
+#define	VXGE_HW_RTS_MGR_CFG1_PN_ACTIVE_TABLE	vxge_mBIT(7)
+/*0x01838*/	u64	rts_mgr_criteria_priority;
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ETYPE(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ICMP_TCPSYN(val) vxge_vBIT(val, 9, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_L4PN(val) vxge_vBIT(val, 13, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_RANGE_L4PN(val) vxge_vBIT(val, 17, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_RTH_IT(val) vxge_vBIT(val, 21, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_DS(val) vxge_vBIT(val, 25, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_QOS(val) vxge_vBIT(val, 29, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ZL4PYLD(val) vxge_vBIT(val, 33, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_L4PRTCL(val) vxge_vBIT(val, 37, 3)
+/*0x01840*/	u64	rts_mgr_da_pause_cfg;
+#define VXGE_HW_RTS_MGR_DA_PAUSE_CFG_VPATH_VECTOR(val) vxge_vBIT(val, 0, 17)
+/*0x01848*/	u64	rts_mgr_da_slow_proto_cfg;
+#define VXGE_HW_RTS_MGR_DA_SLOW_PROTO_CFG_VPATH_VECTOR(val) \
+							vxge_vBIT(val, 0, 17)
+	u8	unused01890[0x01890-0x01850];
+/*0x01890*/     u64     rts_mgr_cbasin_cfg;
+	u8	unused01968[0x01968-0x01898];
+
+/*0x01968*/	u64	dbg_stat_rx_any_frms;
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT0_RX_ANY_FRMS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT1_RX_ANY_FRMS(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT2_RX_ANY_FRMS(val) \
+							vxge_vBIT(val, 16, 8)
+	u8	unused01a00[0x01a00-0x01970];
+
+/*0x01a00*/	u64	rxmac_red_rate_vp[17];
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR0(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR1(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR2(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR3(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR0(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR1(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR2(val) vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR3(val) vxge_vBIT(val, 28, 4)
+	u8	unused01e00[0x01e00-0x01a88];
+
+/*0x01e00*/	u64	xgmac_int_status;
+#define	VXGE_HW_XGMAC_INT_STATUS_XMAC_GEN_ERR_XMAC_GEN_INT	vxge_mBIT(3)
+#define	VXGE_HW_XGMAC_INT_STATUS_XMAC_LINK_ERR_PORT0_XMAC_LINK_INT_PORT0 \
+								vxge_mBIT(7)
+#define	VXGE_HW_XGMAC_INT_STATUS_XMAC_LINK_ERR_PORT1_XMAC_LINK_INT_PORT1 \
+								vxge_mBIT(11)
+#define	VXGE_HW_XGMAC_INT_STATUS_XGXS_GEN_ERR_XGXS_GEN_INT	vxge_mBIT(15)
+#define	VXGE_HW_XGMAC_INT_STATUS_ASIC_NTWK_ERR_ASIC_NTWK_INT	vxge_mBIT(19)
+#define	VXGE_HW_XGMAC_INT_STATUS_ASIC_GPIO_ERR_ASIC_GPIO_INT	vxge_mBIT(23)
+/*0x01e08*/	u64	xgmac_int_mask;
+/*0x01e10*/	u64	xmac_gen_err_reg;
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_ACTOR_CHURN_DETECTED \
+								vxge_mBIT(7)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_PARTNER_CHURN_DETECTED \
+								vxge_mBIT(11)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_RECEIVED_LACPDU	vxge_mBIT(15)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_ACTOR_CHURN_DETECTED \
+								vxge_mBIT(19)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_PARTNER_CHURN_DETECTED \
+								vxge_mBIT(23)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_RECEIVED_LACPDU	vxge_mBIT(27)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XLCM_LAG_FAILOVER_DETECTED	vxge_mBIT(31)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE0_SG_ERR(val) \
+							vxge_vBIT(val, 40, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE0_DB_ERR(val) \
+							vxge_vBIT(val, 42, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE1_SG_ERR(val) \
+							vxge_vBIT(val, 44, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE1_DB_ERR(val) \
+							vxge_vBIT(val, 46, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE2_SG_ERR(val) \
+							vxge_vBIT(val, 48, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE2_DB_ERR(val) \
+							vxge_vBIT(val, 50, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE3_SG_ERR(val) \
+							vxge_vBIT(val, 52, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE3_DB_ERR(val) \
+							vxge_vBIT(val, 54, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE4_SG_ERR(val) \
+							vxge_vBIT(val, 56, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE4_DB_ERR(val) \
+							vxge_vBIT(val, 58, 2)
+#define	VXGE_HW_XMAC_GEN_ERR_REG_XMACJ_XMAC_FSM_ERR	vxge_mBIT(63)
+/*0x01e18*/	u64	xmac_gen_err_mask;
+/*0x01e20*/	u64	xmac_gen_err_alarm;
+/*0x01e28*/	u64	xmac_link_err_port_reg[2];
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_DOWN	vxge_mBIT(3)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_UP	vxge_mBIT(7)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_WENT_DOWN	vxge_mBIT(11)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_WENT_UP	vxge_mBIT(15)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_REAFFIRMED_FAULT \
+								vxge_mBIT(19)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_REAFFIRMED_OK	vxge_mBIT(23)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_LINK_DOWN	vxge_mBIT(27)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_LINK_UP	vxge_mBIT(31)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_RATEMGMT_RATE_CHANGE	vxge_mBIT(35)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_RATEMGMT_LASI_INV	vxge_mBIT(39)
+#define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMDIO_MDIO_MGR_ACCESS_COMPLETE \
+								vxge_mBIT(47)
+/*0x01e30*/	u64	xmac_link_err_port_mask[2];
+/*0x01e38*/	u64	xmac_link_err_port_alarm[2];
+/*0x01e58*/	u64	xgxs_gen_err_reg;
+#define	VXGE_HW_XGXS_GEN_ERR_REG_XGXS_XGXS_FSM_ERR	vxge_mBIT(63)
+/*0x01e60*/	u64	xgxs_gen_err_mask;
+/*0x01e68*/	u64	xgxs_gen_err_alarm;
+/*0x01e70*/	u64	asic_ntwk_err_reg;
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_DOWN	vxge_mBIT(3)
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_UP	vxge_mBIT(7)
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_WENT_DOWN	vxge_mBIT(11)
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_WENT_UP	vxge_mBIT(15)
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT	vxge_mBIT(19)
+#define	VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK	vxge_mBIT(23)
+/*0x01e78*/	u64	asic_ntwk_err_mask;
+/*0x01e80*/	u64	asic_ntwk_err_alarm;
+/*0x01e88*/	u64	asic_gpio_err_reg;
+#define VXGE_HW_ASIC_GPIO_ERR_REG_XMACJ_GPIO_INT(n)	vxge_mBIT(n)
+/*0x01e90*/	u64	asic_gpio_err_mask;
+/*0x01e98*/	u64	asic_gpio_err_alarm;
+/*0x01ea0*/	u64	xgmac_gen_status;
+#define	VXGE_HW_XGMAC_GEN_STATUS_XMACJ_NTWK_OK	vxge_mBIT(3)
+#define	VXGE_HW_XGMAC_GEN_STATUS_XMACJ_NTWK_DATA_RATE	vxge_mBIT(11)
+/*0x01ea8*/	u64	xgmac_gen_fw_memo_status;
+#define	VXGE_HW_XGMAC_GEN_FW_MEMO_STATUS_XMACJ_EVENTS_PENDING(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x01eb0*/	u64	xgmac_gen_fw_memo_mask;
+#define VXGE_HW_XGMAC_GEN_FW_MEMO_MASK_MASK(val) vxge_vBIT(val, 0, 64)
+/*0x01eb8*/	u64	xgmac_gen_fw_vpath_to_vsport_status;
+#define	VXGE_HW_XGMAC_GEN_FW_VPATH_TO_VSPORT_STATUS_XMACJ_EVENTS_PENDING(val) \
+						vxge_vBIT(val, 0, 17)
+/*0x01ec0*/	u64	xgmac_main_cfg_port[2];
+#define	VXGE_HW_XGMAC_MAIN_CFG_PORT_PORT_EN	vxge_mBIT(3)
+	u8	unused01f40[0x01f40-0x01ed0];
+
+/*0x01f40*/	u64	xmac_gen_cfg;
+#define VXGE_HW_XMAC_GEN_CFG_RATEMGMT_MAC_RATE_SEL(val) vxge_vBIT(val, 2, 2)
+#define	VXGE_HW_XMAC_GEN_CFG_TX_HEAD_DROP_WHEN_FAULT	vxge_mBIT(7)
+#define	VXGE_HW_XMAC_GEN_CFG_FAULT_BEHAVIOUR	vxge_mBIT(27)
+#define VXGE_HW_XMAC_GEN_CFG_PERIOD_NTWK_UP(val) vxge_vBIT(val, 28, 4)
+#define VXGE_HW_XMAC_GEN_CFG_PERIOD_NTWK_DOWN(val) vxge_vBIT(val, 32, 4)
+/*0x01f48*/	u64	xmac_timestamp;
+#define	VXGE_HW_XMAC_TIMESTAMP_EN	vxge_mBIT(3)
+#define VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_XMAC_TIMESTAMP_INTERVAL(val) vxge_vBIT(val, 12, 4)
+#define	VXGE_HW_XMAC_TIMESTAMP_TIMER_RESTART	vxge_mBIT(19)
+#define VXGE_HW_XMAC_TIMESTAMP_XMACJ_ROLLOVER_CNT(val) vxge_vBIT(val, 32, 16)
+/*0x01f50*/	u64	xmac_stats_gen_cfg;
+#define VXGE_HW_XMAC_STATS_GEN_CFG_PRTAGGR_CUM_TIMER(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VPATH_CUM_TIMER(val) vxge_vBIT(val, 8, 4)
+#define	VXGE_HW_XMAC_STATS_GEN_CFG_VLAN_HANDLING	vxge_mBIT(15)
+/*0x01f58*/	u64	xmac_stats_sys_cmd;
+#define VXGE_HW_XMAC_STATS_SYS_CMD_OP(val) vxge_vBIT(val, 5, 3)
+#define	VXGE_HW_XMAC_STATS_SYS_CMD_STROBE	vxge_mBIT(15)
+#define VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(val) vxge_vBIT(val, 32, 8)
+/*0x01f60*/	u64	xmac_stats_sys_data;
+#define VXGE_HW_XMAC_STATS_SYS_DATA_XSMGR_DATA(val) vxge_vBIT(val, 0, 64)
+	u8	unused01f80[0x01f80-0x01f68];
+
+/*0x01f80*/	u64	asic_ntwk_ctrl;
+#define	VXGE_HW_ASIC_NTWK_CTRL_REQ_TEST_NTWK	vxge_mBIT(3)
+#define	VXGE_HW_ASIC_NTWK_CTRL_PORT0_REQ_TEST_PORT	vxge_mBIT(11)
+#define	VXGE_HW_ASIC_NTWK_CTRL_PORT1_REQ_TEST_PORT	vxge_mBIT(15)
+/*0x01f88*/	u64	asic_ntwk_cfg_show_port_info;
+#define VXGE_HW_ASIC_NTWK_CFG_SHOW_PORT_INFO_VP(n)	vxge_mBIT(n)
+/*0x01f90*/	u64	asic_ntwk_cfg_port_num;
+#define VXGE_HW_ASIC_NTWK_CFG_PORT_NUM_VP(n)	vxge_mBIT(n)
+/*0x01f98*/	u64	xmac_cfg_port[3];
+#define	VXGE_HW_XMAC_CFG_PORT_XGMII_LOOPBACK	vxge_mBIT(3)
+#define	VXGE_HW_XMAC_CFG_PORT_XGMII_REVERSE_LOOPBACK	vxge_mBIT(7)
+#define	VXGE_HW_XMAC_CFG_PORT_XGMII_TX_BEHAV	vxge_mBIT(11)
+#define	VXGE_HW_XMAC_CFG_PORT_XGMII_RX_BEHAV	vxge_mBIT(15)
+/*0x01fb0*/	u64	xmac_station_addr_port[2];
+#define VXGE_HW_XMAC_STATION_ADDR_PORT_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+	u8	unused02020[0x02020-0x01fc0];
+
+/*0x02020*/	u64	lag_cfg;
+#define	VXGE_HW_LAG_CFG_EN	vxge_mBIT(3)
+#define VXGE_HW_LAG_CFG_MODE(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_LAG_CFG_TX_DISCARD_BEHAV	vxge_mBIT(11)
+#define	VXGE_HW_LAG_CFG_RX_DISCARD_BEHAV	vxge_mBIT(15)
+#define	VXGE_HW_LAG_CFG_PREF_INDIV_PORT_NUM	vxge_mBIT(19)
+/*0x02028*/	u64	lag_status;
+#define	VXGE_HW_LAG_STATUS_XLCM_WAITING_TO_FAILBACK	vxge_mBIT(3)
+#define VXGE_HW_LAG_STATUS_XLCM_TIMER_VAL_COLD_FAILOVER(val) \
+							vxge_vBIT(val, 8, 8)
+/*0x02030*/	u64	lag_active_passive_cfg;
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_HOT_STANDBY	vxge_mBIT(3)
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_LACP_DECIDES	vxge_mBIT(7)
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_PREF_ACTIVE_PORT_NUM	vxge_mBIT(11)
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_AUTO_FAILBACK	vxge_mBIT(15)
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_FAILBACK_EN	vxge_mBIT(19)
+#define	VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_COLD_FAILOVER_TIMEOUT(val) \
+							vxge_vBIT(val, 32, 16)
+	u8	unused02040[0x02040-0x02038];
+
+/*0x02040*/	u64	lag_lacp_cfg;
+#define	VXGE_HW_LAG_LACP_CFG_EN	vxge_mBIT(3)
+#define	VXGE_HW_LAG_LACP_CFG_LACP_BEGIN	vxge_mBIT(7)
+#define	VXGE_HW_LAG_LACP_CFG_DISCARD_LACP	vxge_mBIT(11)
+#define	VXGE_HW_LAG_LACP_CFG_LIBERAL_LEN_CHK	vxge_mBIT(15)
+/*0x02048*/	u64	lag_timer_cfg_1;
+#define VXGE_HW_LAG_TIMER_CFG_1_FAST_PER(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_SLOW_PER(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_SHORT_TIMEOUT(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_LONG_TIMEOUT(val) vxge_vBIT(val, 48, 16)
+/*0x02050*/	u64	lag_timer_cfg_2;
+#define VXGE_HW_LAG_TIMER_CFG_2_CHURN_DET(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_AGGR_WAIT(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_SHORT_TIMER_SCALE(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_LONG_TIMER_SCALE(val)  vxge_vBIT(val, 48, 16)
+/*0x02058*/	u64	lag_sys_id;
+#define VXGE_HW_LAG_SYS_ID_ADDR(val) vxge_vBIT(val, 0, 48)
+#define	VXGE_HW_LAG_SYS_ID_USE_PORT_ADDR	vxge_mBIT(51)
+#define	VXGE_HW_LAG_SYS_ID_ADDR_SEL	vxge_mBIT(55)
+/*0x02060*/	u64	lag_sys_cfg;
+#define VXGE_HW_LAG_SYS_CFG_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+	u8	unused02070[0x02070-0x02068];
+
+/*0x02070*/	u64	lag_aggr_addr_cfg[2];
+#define VXGE_HW_LAG_AGGR_ADDR_CFG_ADDR(val) vxge_vBIT(val, 0, 48)
+#define	VXGE_HW_LAG_AGGR_ADDR_CFG_USE_PORT_ADDR	vxge_mBIT(51)
+#define	VXGE_HW_LAG_AGGR_ADDR_CFG_ADDR_SEL	vxge_mBIT(55)
+/*0x02080*/	u64	lag_aggr_id_cfg[2];
+#define VXGE_HW_LAG_AGGR_ID_CFG_ID(val) vxge_vBIT(val, 0, 16)
+/*0x02090*/	u64	lag_aggr_admin_key[2];
+#define VXGE_HW_LAG_AGGR_ADMIN_KEY_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x020a0*/	u64	lag_aggr_alt_admin_key;
+#define VXGE_HW_LAG_AGGR_ALT_ADMIN_KEY_KEY(val) vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_LAG_AGGR_ALT_ADMIN_KEY_ALT_AGGR	vxge_mBIT(19)
+/*0x020a8*/	u64	lag_aggr_oper_key[2];
+#define VXGE_HW_LAG_AGGR_OPER_KEY_LAGC_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x020b8*/	u64	lag_aggr_partner_sys_id[2];
+#define VXGE_HW_LAG_AGGR_PARTNER_SYS_ID_LAGC_ADDR(val) vxge_vBIT(val, 0, 48)
+/*0x020c8*/	u64	lag_aggr_partner_info[2];
+#define VXGE_HW_LAG_AGGR_PARTNER_INFO_LAGC_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_LAG_AGGR_PARTNER_INFO_LAGC_OPER_KEY(val) \
+						vxge_vBIT(val, 16, 16)
+/*0x020d8*/	u64	lag_aggr_state[2];
+#define	VXGE_HW_LAG_AGGR_STATE_LAGC_TX	vxge_mBIT(3)
+#define	VXGE_HW_LAG_AGGR_STATE_LAGC_RX	vxge_mBIT(7)
+#define	VXGE_HW_LAG_AGGR_STATE_LAGC_READY	vxge_mBIT(11)
+#define	VXGE_HW_LAG_AGGR_STATE_LAGC_INDIVIDUAL	vxge_mBIT(15)
+	u8	unused020f0[0x020f0-0x020e8];
+
+/*0x020f0*/	u64	lag_port_cfg[2];
+#define	VXGE_HW_LAG_PORT_CFG_EN	vxge_mBIT(3)
+#define	VXGE_HW_LAG_PORT_CFG_DISCARD_SLOW_PROTO	vxge_mBIT(7)
+#define	VXGE_HW_LAG_PORT_CFG_HOST_CHOSEN_AGGR	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_CFG_DISCARD_UNKNOWN_SLOW_PROTO	vxge_mBIT(15)
+/*0x02100*/	u64	lag_port_actor_admin_cfg[2];
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_PORT_NUM(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_PORT_PRI(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_KEY_10G(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_KEY_1G(val) vxge_vBIT(val, 48, 16)
+/*0x02110*/	u64	lag_port_actor_admin_state[2];
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_LACP_ACTIVITY	vxge_mBIT(3)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_LACP_TIMEOUT	vxge_mBIT(7)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_AGGREGATION	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_SYNCHRONIZATION	vxge_mBIT(15)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_COLLECTING	vxge_mBIT(19)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_DISTRIBUTING	vxge_mBIT(23)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_DEFAULTED	vxge_mBIT(27)
+#define	VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_EXPIRED	vxge_mBIT(31)
+/*0x02120*/	u64	lag_port_partner_admin_sys_id[2];
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_SYS_ID_ADDR(val) vxge_vBIT(val, 0, 48)
+/*0x02130*/	u64	lag_port_partner_admin_cfg[2];
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_KEY(val) vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_PORT_NUM(val) \
+							vxge_vBIT(val, 32, 16)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_PORT_PRI(val) \
+							vxge_vBIT(val, 48, 16)
+/*0x02140*/	u64	lag_port_partner_admin_state[2];
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_LACP_ACTIVITY	vxge_mBIT(3)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_LACP_TIMEOUT	vxge_mBIT(7)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_AGGREGATION	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_SYNCHRONIZATION	vxge_mBIT(15)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_COLLECTING	vxge_mBIT(19)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_DISTRIBUTING	vxge_mBIT(23)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_DEFAULTED	vxge_mBIT(27)
+#define	VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_EXPIRED	vxge_mBIT(31)
+/*0x02150*/	u64	lag_port_to_aggr[2];
+#define VXGE_HW_LAG_PORT_TO_AGGR_LAGC_AGGR_ID(val) vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_LAG_PORT_TO_AGGR_LAGC_AGGR_VLD_ID	vxge_mBIT(19)
+/*0x02160*/	u64	lag_port_actor_oper_key[2];
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_KEY_LAGC_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x02170*/	u64	lag_port_actor_oper_state[2];
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_LACP_ACTIVITY	vxge_mBIT(3)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_LACP_TIMEOUT	vxge_mBIT(7)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_AGGREGATION	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_SYNCHRONIZATION	vxge_mBIT(15)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_COLLECTING	vxge_mBIT(19)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_DISTRIBUTING	vxge_mBIT(23)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_DEFAULTED	vxge_mBIT(27)
+#define	VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_EXPIRED	vxge_mBIT(31)
+/*0x02180*/	u64	lag_port_partner_oper_sys_id[2];
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_SYS_ID_LAGC_ADDR(val) \
+						vxge_vBIT(val, 0, 48)
+/*0x02190*/	u64	lag_port_partner_oper_info[2];
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_SYS_PRI(val) \
+						vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_KEY(val) \
+						vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_PORT_NUM(val) \
+						vxge_vBIT(val, 32, 16)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_PORT_PRI(val) \
+						vxge_vBIT(val, 48, 16)
+/*0x021a0*/	u64	lag_port_partner_oper_state[2];
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_LACP_ACTIVITY	vxge_mBIT(3)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_LACP_TIMEOUT	vxge_mBIT(7)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_AGGREGATION	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_SYNCHRONIZATION \
+								vxge_mBIT(15)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_COLLECTING	vxge_mBIT(19)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_DISTRIBUTING	vxge_mBIT(23)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_DEFAULTED	vxge_mBIT(27)
+#define	VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_EXPIRED	vxge_mBIT(31)
+/*0x021b0*/	u64	lag_port_state_vars[2];
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_READY	vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_SELECTED(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_AGGR_NUM	vxge_mBIT(11)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_MOVED	vxge_mBIT(15)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_ENABLED	vxge_mBIT(18)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_DISABLED	vxge_mBIT(19)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_NTT	vxge_mBIT(23)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN	vxge_mBIT(27)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN	vxge_mBIT(31)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_INFO_LEN_MISMATCH \
+								vxge_mBIT(32)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_INFO_LEN_MISMATCH \
+								vxge_mBIT(33)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_COLL_INFO_LEN_MISMATCH	vxge_mBIT(34)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_TERM_INFO_LEN_MISMATCH	vxge_mBIT(35)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_RX_FSM_STATE(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_MUX_FSM_STATE(val) \
+							vxge_vBIT(val, 41, 3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_MUX_REASON(val) vxge_vBIT(val, 44, 4)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN_STATE	vxge_mBIT(54)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN_STATE	vxge_mBIT(55)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN_COUNT(val) \
+							vxge_vBIT(val, 56, 4)
+#define	VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN_COUNT(val) \
+							vxge_vBIT(val, 60, 4)
+/*0x021c0*/	u64	lag_port_timer_cntr[2];
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_CURRENT_WHILE(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PERIODIC_WHILE(val) \
+							vxge_vBIT(val, 8, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_WAIT_WHILE(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_TX_LACP(val) vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_ACTOR_SYNC_TRANSITION_COUNT(val) \
+							vxge_vBIT(val, 32, 8)
+#define	VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PARTNER_SYNC_TRANSITION_COUNT(val) \
+							vxge_vBIT(val, 40, 8)
+#define	VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_ACTOR_CHANGE_COUNT(val) \
+							vxge_vBIT(val, 48, 8)
+#define	VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PARTNER_CHANGE_COUNT(val) \
+							vxge_vBIT(val, 56, 8)
+	u8	unused02208[0x02700-0x021d0];
+
+/*0x02700*/	u64	rtdma_int_status;
+#define	VXGE_HW_RTDMA_INT_STATUS_PDA_ALARM_PDA_INT	vxge_mBIT(1)
+#define	VXGE_HW_RTDMA_INT_STATUS_PCC_ERROR_PCC_INT	vxge_mBIT(2)
+#define	VXGE_HW_RTDMA_INT_STATUS_LSO_ERROR_LSO_INT	vxge_mBIT(4)
+#define	VXGE_HW_RTDMA_INT_STATUS_SM_ERROR_SM_INT	vxge_mBIT(5)
+/*0x02708*/	u64	rtdma_int_mask;
+/*0x02710*/	u64	pda_alarm_reg;
+#define	VXGE_HW_PDA_ALARM_REG_PDA_HSC_FIFO_ERR	vxge_mBIT(0)
+#define	VXGE_HW_PDA_ALARM_REG_PDA_SM_ERR	vxge_mBIT(1)
+/*0x02718*/	u64	pda_alarm_mask;
+/*0x02720*/	u64	pda_alarm_alarm;
+/*0x02728*/	u64	pcc_error_reg;
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FRM_BUF_SBE(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_TXDO_SBE(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FRM_BUF_DBE(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_TXDO_DBE(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FSM_ERR_ALARM(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_SERR(n)	vxge_mBIT(n)
+/*0x02730*/	u64	pcc_error_mask;
+/*0x02738*/	u64	pcc_error_alarm;
+/*0x02740*/	u64	lso_error_reg;
+#define VXGE_HW_LSO_ERROR_REG_PCC_LSO_ABORT(n)	vxge_mBIT(n)
+#define VXGE_HW_LSO_ERROR_REG_PCC_LSO_FSM_ERR_ALARM(n)	vxge_mBIT(n)
+/*0x02748*/	u64	lso_error_mask;
+/*0x02750*/	u64	lso_error_alarm;
+/*0x02758*/	u64	sm_error_reg;
+#define	VXGE_HW_SM_ERROR_REG_SM_FSM_ERR_ALARM	vxge_mBIT(15)
+/*0x02760*/	u64	sm_error_mask;
+/*0x02768*/	u64	sm_error_alarm;
+
+	u8	unused027a8[0x027a8-0x02770];
+
+/*0x027a8*/	u64	txd_ownership_ctrl;
+#define	VXGE_HW_TXD_OWNERSHIP_CTRL_KEEP_OWNERSHIP	vxge_mBIT(7)
+/*0x027b0*/	u64	pcc_cfg;
+#define VXGE_HW_PCC_CFG_PCC_ENABLE(n)	vxge_mBIT(n)
+#define VXGE_HW_PCC_CFG_PCC_ECC_ENABLE_N(n)	vxge_mBIT(n)
+/*0x027b8*/	u64	pcc_control;
+#define VXGE_HW_PCC_CONTROL_FE_ENABLE(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_PCC_CONTROL_EARLY_ASSIGN_EN	vxge_mBIT(15)
+#define	VXGE_HW_PCC_CONTROL_UNBLOCK_DB_ERR	vxge_mBIT(31)
+/*0x027c0*/	u64	pda_status1;
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_0_CTR(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_1_CTR(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_2_CTR(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_3_CTR(val) vxge_vBIT(val, 28, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_4_CTR(val) vxge_vBIT(val, 36, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_5_CTR(val) vxge_vBIT(val, 44, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_6_CTR(val) vxge_vBIT(val, 52, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_7_CTR(val) vxge_vBIT(val, 60, 4)
+/*0x027c8*/	u64	rtdma_bw_timer;
+#define VXGE_HW_RTDMA_BW_TIMER_TIMER_CTRL(val) vxge_vBIT(val, 12, 4)
+
+	u8	unused02900[0x02900-0x027d0];
+/*0x02900*/	u64	g3cmct_int_status;
+#define	VXGE_HW_G3CMCT_INT_STATUS_ERR_G3IF_INT	vxge_mBIT(0)
+/*0x02908*/	u64	g3cmct_int_mask;
+/*0x02910*/	u64	g3cmct_err_reg;
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_SM_ERR	vxge_mBIT(4)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_DECC	vxge_mBIT(5)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_U_DECC	vxge_mBIT(6)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_CTRL_FIFO_DECC	vxge_mBIT(7)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_SECC	vxge_mBIT(29)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_U_SECC	vxge_mBIT(30)
+#define	VXGE_HW_G3CMCT_ERR_REG_G3IF_CTRL_FIFO_SECC	vxge_mBIT(31)
+/*0x02918*/	u64	g3cmct_err_mask;
+/*0x02920*/	u64	g3cmct_err_alarm;
+	u8	unused03000[0x03000-0x02928];
+
+/*0x03000*/	u64	mc_int_status;
+#define	VXGE_HW_MC_INT_STATUS_MC_ERR_MC_INT	vxge_mBIT(3)
+#define	VXGE_HW_MC_INT_STATUS_GROCRC_ALARM_ROCRC_INT	vxge_mBIT(7)
+#define	VXGE_HW_MC_INT_STATUS_FAU_GEN_ERR_FAU_GEN_INT	vxge_mBIT(11)
+#define	VXGE_HW_MC_INT_STATUS_FAU_ECC_ERR_FAU_ECC_INT	vxge_mBIT(15)
+/*0x03008*/	u64	mc_int_mask;
+/*0x03010*/	u64	mc_err_reg;
+#define	VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_SG_ERR_A	vxge_mBIT(3)
+#define	VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_SG_ERR_B	vxge_mBIT(4)
+#define	VXGE_HW_MC_ERR_REG_MC_G3IF_RD_FIFO_ECC_SG_ERR	vxge_mBIT(5)
+#define	VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_SG_ERR_0	vxge_mBIT(6)
+#define	VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_SG_ERR_1	vxge_mBIT(7)
+#define	VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_DB_ERR_A	vxge_mBIT(10)
+#define	VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_DB_ERR_B	vxge_mBIT(11)
+#define	VXGE_HW_MC_ERR_REG_MC_G3IF_RD_FIFO_ECC_DB_ERR	vxge_mBIT(12)
+#define	VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_DB_ERR_0	vxge_mBIT(13)
+#define	VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_DB_ERR_1	vxge_mBIT(14)
+#define	VXGE_HW_MC_ERR_REG_MC_SM_ERR	vxge_mBIT(15)
+/*0x03018*/	u64	mc_err_mask;
+/*0x03020*/	u64	mc_err_alarm;
+/*0x03028*/	u64	grocrc_alarm_reg;
+#define	VXGE_HW_GROCRC_ALARM_REG_XFMD_WR_FIFO_ERR	vxge_mBIT(3)
+#define	VXGE_HW_GROCRC_ALARM_REG_WDE2MSR_RD_FIFO_ERR	vxge_mBIT(7)
+/*0x03030*/	u64	grocrc_alarm_mask;
+/*0x03038*/	u64	grocrc_alarm_alarm;
+	u8	unused03100[0x03100-0x03040];
+
+/*0x03100*/	u64	rx_thresh_cfg_repl;
+#define VXGE_HW_RX_THRESH_CFG_REPL_PAUSE_LOW_THR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_PAUSE_HIGH_THR(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_0(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_1(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_2(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_3(val) vxge_vBIT(val, 40, 8)
+#define	VXGE_HW_RX_THRESH_CFG_REPL_GLOBAL_WOL_EN	vxge_mBIT(62)
+#define	VXGE_HW_RX_THRESH_CFG_REPL_EXACT_VP_MATCH_REQ	vxge_mBIT(63)
+	u8	unused033b8[0x033b8-0x03108];
+
+/*0x033b8*/	u64	fbmc_ecc_cfg;
+#define VXGE_HW_FBMC_ECC_CFG_ENABLE(val) vxge_vBIT(val, 3, 5)
+	u8	unused03400[0x03400-0x033c0];
+
+/*0x03400*/	u64	pcipif_int_status;
+#define	VXGE_HW_PCIPIF_INT_STATUS_DBECC_ERR_DBECC_ERR_INT	vxge_mBIT(3)
+#define	VXGE_HW_PCIPIF_INT_STATUS_SBECC_ERR_SBECC_ERR_INT	vxge_mBIT(7)
+#define	VXGE_HW_PCIPIF_INT_STATUS_GENERAL_ERR_GENERAL_ERR_INT	vxge_mBIT(11)
+#define	VXGE_HW_PCIPIF_INT_STATUS_SRPCIM_MSG_SRPCIM_MSG_INT	vxge_mBIT(15)
+#define	VXGE_HW_PCIPIF_INT_STATUS_MRPCIM_SPARE_R1_MRPCIM_SPARE_R1_INT \
+								vxge_mBIT(19)
+/*0x03408*/	u64	pcipif_int_mask;
+/*0x03410*/	u64	dbecc_err_reg;
+#define	VXGE_HW_DBECC_ERR_REG_PCI_RETRY_BUF_DB_ERR	vxge_mBIT(3)
+#define	VXGE_HW_DBECC_ERR_REG_PCI_RETRY_SOT_DB_ERR	vxge_mBIT(7)
+#define	VXGE_HW_DBECC_ERR_REG_PCI_P_HDR_DB_ERR	vxge_mBIT(11)
+#define	VXGE_HW_DBECC_ERR_REG_PCI_P_DATA_DB_ERR	vxge_mBIT(15)
+#define	VXGE_HW_DBECC_ERR_REG_PCI_NP_HDR_DB_ERR	vxge_mBIT(19)
+#define	VXGE_HW_DBECC_ERR_REG_PCI_NP_DATA_DB_ERR	vxge_mBIT(23)
+/*0x03418*/	u64	dbecc_err_mask;
+/*0x03420*/	u64	dbecc_err_alarm;
+/*0x03428*/	u64	sbecc_err_reg;
+#define	VXGE_HW_SBECC_ERR_REG_PCI_RETRY_BUF_SG_ERR	vxge_mBIT(3)
+#define	VXGE_HW_SBECC_ERR_REG_PCI_RETRY_SOT_SG_ERR	vxge_mBIT(7)
+#define	VXGE_HW_SBECC_ERR_REG_PCI_P_HDR_SG_ERR	vxge_mBIT(11)
+#define	VXGE_HW_SBECC_ERR_REG_PCI_P_DATA_SG_ERR	vxge_mBIT(15)
+#define	VXGE_HW_SBECC_ERR_REG_PCI_NP_HDR_SG_ERR	vxge_mBIT(19)
+#define	VXGE_HW_SBECC_ERR_REG_PCI_NP_DATA_SG_ERR	vxge_mBIT(23)
+/*0x03430*/	u64	sbecc_err_mask;
+/*0x03438*/	u64	sbecc_err_alarm;
+/*0x03440*/	u64	general_err_reg;
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_DROPPED_ILLEGAL_CFG	vxge_mBIT(3)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_ILLEGAL_MEM_MAP_PROG	vxge_mBIT(7)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_LINK_RST_FSM_ERR	vxge_mBIT(11)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_RX_ILLEGAL_TLP_VPLANE	vxge_mBIT(15)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_TRAINING_RESET_DET	vxge_mBIT(19)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_PCI_LINK_DOWN_DET	vxge_mBIT(23)
+#define	VXGE_HW_GENERAL_ERR_REG_PCI_RESET_ACK_DLLP	vxge_mBIT(27)
+/*0x03448*/	u64	general_err_mask;
+/*0x03450*/	u64	general_err_alarm;
+/*0x03458*/	u64	srpcim_msg_reg;
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE0_RMSG_INT \
+								vxge_mBIT(0)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE1_RMSG_INT \
+								vxge_mBIT(1)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE2_RMSG_INT \
+								vxge_mBIT(2)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE3_RMSG_INT \
+								vxge_mBIT(3)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE4_RMSG_INT \
+								vxge_mBIT(4)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE5_RMSG_INT \
+								vxge_mBIT(5)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE6_RMSG_INT \
+								vxge_mBIT(6)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE7_RMSG_INT \
+								vxge_mBIT(7)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE8_RMSG_INT \
+								vxge_mBIT(8)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE9_RMSG_INT \
+								vxge_mBIT(9)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE10_RMSG_INT \
+								vxge_mBIT(10)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE11_RMSG_INT \
+								vxge_mBIT(11)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE12_RMSG_INT \
+								vxge_mBIT(12)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE13_RMSG_INT \
+								vxge_mBIT(13)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE14_RMSG_INT \
+								vxge_mBIT(14)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE15_RMSG_INT \
+								vxge_mBIT(15)
+#define	VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE16_RMSG_INT \
+								vxge_mBIT(16)
+/*0x03460*/	u64	srpcim_msg_mask;
+/*0x03468*/	u64	srpcim_msg_alarm;
+	u8	unused03600[0x03600-0x03470];
+
+/*0x03600*/	u64	gcmg1_int_status;
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSCC_ERR_GSSCC_INT	vxge_mBIT(0)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC0_ERR0_GSSC0_0_INT	vxge_mBIT(1)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC0_ERR1_GSSC0_1_INT	vxge_mBIT(2)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC1_ERR0_GSSC1_0_INT	vxge_mBIT(3)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC1_ERR1_GSSC1_1_INT	vxge_mBIT(4)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC2_ERR0_GSSC2_0_INT	vxge_mBIT(5)
+#define	VXGE_HW_GCMG1_INT_STATUS_GSSC2_ERR1_GSSC2_1_INT	vxge_mBIT(6)
+#define	VXGE_HW_GCMG1_INT_STATUS_UQM_ERR_UQM_INT	vxge_mBIT(7)
+#define	VXGE_HW_GCMG1_INT_STATUS_GQCC_ERR_GQCC_INT	vxge_mBIT(8)
+/*0x03608*/	u64	gcmg1_int_mask;
+	u8	unused03a00[0x03a00-0x03610];
+
+/*0x03a00*/	u64	pcmg1_int_status;
+#define	VXGE_HW_PCMG1_INT_STATUS_PSSCC_ERR_PSSCC_INT	vxge_mBIT(0)
+#define	VXGE_HW_PCMG1_INT_STATUS_PQCC_ERR_PQCC_INT	vxge_mBIT(1)
+#define	VXGE_HW_PCMG1_INT_STATUS_PQCC_CQM_ERR_PQCC_CQM_INT	vxge_mBIT(2)
+#define	VXGE_HW_PCMG1_INT_STATUS_PQCC_SQM_ERR_PQCC_SQM_INT	vxge_mBIT(3)
+/*0x03a08*/	u64	pcmg1_int_mask;
+	u8	unused04000[0x04000-0x03a10];
+
+/*0x04000*/	u64	one_int_status;
+#define	VXGE_HW_ONE_INT_STATUS_RXPE_ERR_RXPE_INT	vxge_mBIT(7)
+#define	VXGE_HW_ONE_INT_STATUS_TXPE_BCC_MEM_SG_ECC_ERR_TXPE_BCC_MEM_SG_ECC_INT \
+							vxge_mBIT(13)
+#define	VXGE_HW_ONE_INT_STATUS_TXPE_BCC_MEM_DB_ECC_ERR_TXPE_BCC_MEM_DB_ECC_INT \
+							vxge_mBIT(14)
+#define	VXGE_HW_ONE_INT_STATUS_TXPE_ERR_TXPE_INT	vxge_mBIT(15)
+#define	VXGE_HW_ONE_INT_STATUS_DLM_ERR_DLM_INT	vxge_mBIT(23)
+#define	VXGE_HW_ONE_INT_STATUS_PE_ERR_PE_INT	vxge_mBIT(31)
+#define	VXGE_HW_ONE_INT_STATUS_RPE_ERR_RPE_INT	vxge_mBIT(39)
+#define	VXGE_HW_ONE_INT_STATUS_RPE_FSM_ERR_RPE_FSM_INT	vxge_mBIT(47)
+#define	VXGE_HW_ONE_INT_STATUS_OES_ERR_OES_INT	vxge_mBIT(55)
+/*0x04008*/	u64	one_int_mask;
+	u8	unused04818[0x04818-0x04010];
+
+/*0x04818*/	u64	noa_wct_ctrl;
+#define	VXGE_HW_NOA_WCT_CTRL_VP_INT_NUM	vxge_mBIT(0)
+/*0x04820*/	u64	rc_cfg2;
+#define VXGE_HW_RC_CFG2_BUFF1_SIZE(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_RC_CFG2_BUFF2_SIZE(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_RC_CFG2_BUFF3_SIZE(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_RC_CFG2_BUFF4_SIZE(val) vxge_vBIT(val, 48, 16)
+/*0x04828*/	u64	rc_cfg3;
+#define VXGE_HW_RC_CFG3_BUFF5_SIZE(val) vxge_vBIT(val, 0, 16)
+/*0x04830*/	u64	rx_multi_cast_ctrl1;
+#define	VXGE_HW_RX_MULTI_CAST_CTRL1_ENABLE	vxge_mBIT(7)
+#define VXGE_HW_RX_MULTI_CAST_CTRL1_DELAY_COUNT(val) vxge_vBIT(val, 11, 5)
+/*0x04838*/	u64	rxdm_dbg_rd;
+#define VXGE_HW_RXDM_DBG_RD_ADDR(val) vxge_vBIT(val, 0, 12)
+#define	VXGE_HW_RXDM_DBG_RD_ENABLE	vxge_mBIT(31)
+/*0x04840*/	u64	rxdm_dbg_rd_data;
+#define VXGE_HW_RXDM_DBG_RD_DATA_RMC_RXDM_DBG_RD_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x04848*/	u64	rqa_top_prty_for_vh[17];
+#define VXGE_HW_RQA_TOP_PRTY_FOR_VH_RQA_TOP_PRTY_FOR_VH(val) \
+							vxge_vBIT(val, 59, 5)
+	u8	unused04900[0x04900-0x048d0];
+
+/*0x04900*/	u64	tim_status;
+#define	VXGE_HW_TIM_STATUS_TIM_RESET_IN_PROGRESS	vxge_mBIT(0)
+/*0x04908*/	u64	tim_ecc_enable;
+#define	VXGE_HW_TIM_ECC_ENABLE_VBLS_N	vxge_mBIT(7)
+#define	VXGE_HW_TIM_ECC_ENABLE_BMAP_N	vxge_mBIT(15)
+#define	VXGE_HW_TIM_ECC_ENABLE_BMAP_MSG_N	vxge_mBIT(23)
+/*0x04910*/	u64	tim_bp_ctrl;
+#define	VXGE_HW_TIM_BP_CTRL_RD_XON	vxge_mBIT(7)
+#define	VXGE_HW_TIM_BP_CTRL_WR_XON	vxge_mBIT(15)
+#define	VXGE_HW_TIM_BP_CTRL_ROCRC_BYP	vxge_mBIT(23)
+/*0x04918*/	u64	tim_resource_assignment_vh[17];
+#define VXGE_HW_TIM_RESOURCE_ASSIGNMENT_VH_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+/*0x049a0*/	u64	tim_bmap_mapping_vp_err[17];
+#define VXGE_HW_TIM_BMAP_MAPPING_VP_ERR_TIM_DEST_VPATH(val) vxge_vBIT(val, 3, 5)
+	u8	unused04b00[0x04b00-0x04a28];
+
+/*0x04b00*/	u64	gcmg2_int_status;
+#define	VXGE_HW_GCMG2_INT_STATUS_GXTMC_ERR_GXTMC_INT	vxge_mBIT(7)
+#define	VXGE_HW_GCMG2_INT_STATUS_GCP_ERR_GCP_INT	vxge_mBIT(15)
+#define	VXGE_HW_GCMG2_INT_STATUS_CMC_ERR_CMC_INT	vxge_mBIT(23)
+/*0x04b08*/	u64	gcmg2_int_mask;
+/*0x04b10*/	u64	gxtmc_err_reg;
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_MEM_DB_ERR(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_MEM_SG_ERR(val) vxge_vBIT(val, 4, 4)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMC_RD_DATA_DB_ERR	vxge_mBIT(8)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_REQ_FIFO_ERR	vxge_mBIT(9)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_REQ_DATA_FIFO_ERR	vxge_mBIT(10)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_WR_RSP_FIFO_ERR	vxge_mBIT(11)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_RD_RSP_FIFO_ERR	vxge_mBIT(12)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_WRP_FIFO_ERR	vxge_mBIT(13)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_WRP_ERR	vxge_mBIT(14)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_RRP_FIFO_ERR	vxge_mBIT(15)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_RRP_ERR	vxge_mBIT(16)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_DATA_SM_ERR	vxge_mBIT(17)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_CMC0_IF_ERR	vxge_mBIT(18)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_ARB_SM_ERR	vxge_mBIT(19)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_CFC_SM_ERR	vxge_mBIT(20)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_CREDIT_OVERFLOW \
+							vxge_mBIT(21)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_CREDIT_UNDERFLOW \
+							vxge_mBIT(22)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_SM_ERR	vxge_mBIT(23)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_CREDIT_OVERFLOW \
+							vxge_mBIT(24)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_CREDIT_UNDERFLOW \
+							vxge_mBIT(25)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_SM_ERR	vxge_mBIT(26)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WCOMPL_SM_ERR	vxge_mBIT(27)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WCOMPL_TAG_ERR	vxge_mBIT(28)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WREQ_SM_ERR	vxge_mBIT(29)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WREQ_FIFO_ERR	vxge_mBIT(30)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CP2BDT_RFIFO_POP_ERR	vxge_mBIT(31)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_CMI_OP_ERR	vxge_mBIT(32)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_DFETCH_OP_ERR	vxge_mBIT(33)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_DFIFO_ERR	vxge_mBIT(34)
+#define	VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_ARB_SM_ERR	vxge_mBIT(35)
+/*0x04b18*/	u64	gxtmc_err_mask;
+/*0x04b20*/	u64	gxtmc_err_alarm;
+/*0x04b28*/	u64	cmc_err_reg;
+#define	VXGE_HW_CMC_ERR_REG_CMC_CMC_SM_ERR	vxge_mBIT(0)
+/*0x04b30*/	u64	cmc_err_mask;
+/*0x04b38*/	u64	cmc_err_alarm;
+/*0x04b40*/	u64	gcp_err_reg;
+#define	VXGE_HW_GCP_ERR_REG_CP_H2L2CP_FIFO_ERR	vxge_mBIT(0)
+#define	VXGE_HW_GCP_ERR_REG_CP_STC2CP_FIFO_ERR	vxge_mBIT(1)
+#define	VXGE_HW_GCP_ERR_REG_CP_STE2CP_FIFO_ERR	vxge_mBIT(2)
+#define	VXGE_HW_GCP_ERR_REG_CP_TTE2CP_FIFO_ERR	vxge_mBIT(3)
+/*0x04b48*/	u64	gcp_err_mask;
+/*0x04b50*/	u64	gcp_err_alarm;
+	u8	unused04f00[0x04f00-0x04b58];
+
+/*0x04f00*/	u64	pcmg2_int_status;
+#define	VXGE_HW_PCMG2_INT_STATUS_PXTMC_ERR_PXTMC_INT	vxge_mBIT(7)
+#define	VXGE_HW_PCMG2_INT_STATUS_CP_EXC_CP_XT_EXC_INT	vxge_mBIT(15)
+#define	VXGE_HW_PCMG2_INT_STATUS_CP_ERR_CP_ERR_INT	vxge_mBIT(23)
+/*0x04f08*/	u64	pcmg2_int_mask;
+/*0x04f10*/	u64	pxtmc_err_reg;
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XT_PIF_SRAM_DB_ERR(val) vxge_vBIT(val, 0, 2)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_FIFO_ERR	vxge_mBIT(2)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_PRSP_FIFO_ERR	vxge_mBIT(3)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_WRSP_FIFO_ERR	vxge_mBIT(4)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_FIFO_ERR	vxge_mBIT(5)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_PRSP_FIFO_ERR	vxge_mBIT(6)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_WRSP_FIFO_ERR	vxge_mBIT(7)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_FIFO_ERR	vxge_mBIT(8)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_PRSP_FIFO_ERR	vxge_mBIT(9)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_WRSP_FIFO_ERR	vxge_mBIT(10)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_REQ_FIFO_ERR	vxge_mBIT(11)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_REQ_DATA_FIFO_ERR	vxge_mBIT(12)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_WR_RSP_FIFO_ERR	vxge_mBIT(13)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_RD_RSP_FIFO_ERR	vxge_mBIT(14)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_SHADOW_ERR	vxge_mBIT(15)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_RSP_SHADOW_ERR	vxge_mBIT(16)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_SHADOW_ERR	vxge_mBIT(17)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_RSP_SHADOW_ERR	vxge_mBIT(18)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_SHADOW_ERR	vxge_mBIT(19)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_RSP_SHADOW_ERR	vxge_mBIT(20)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_XIL_SHADOW_ERR	vxge_mBIT(21)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_ARB_SHADOW_ERR	vxge_mBIT(22)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_RAM_SHADOW_ERR	vxge_mBIT(23)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CMW_SHADOW_ERR	vxge_mBIT(24)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CMR_SHADOW_ERR	vxge_mBIT(25)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_FSM_ERR	vxge_mBIT(26)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_RSP_FSM_ERR	vxge_mBIT(27)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_FSM_ERR	vxge_mBIT(28)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_RSP_FSM_ERR	vxge_mBIT(29)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_FSM_ERR	vxge_mBIT(30)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_RSP_FSM_ERR	vxge_mBIT(31)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_XIL_FSM_ERR	vxge_mBIT(32)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_ARB_FSM_ERR	vxge_mBIT(33)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CMW_FSM_ERR	vxge_mBIT(34)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CMR_FSM_ERR	vxge_mBIT(35)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_RD_PROT_ERR	vxge_mBIT(36)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_RD_PROT_ERR	vxge_mBIT(37)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_RD_PROT_ERR	vxge_mBIT(38)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_WR_PROT_ERR	vxge_mBIT(39)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_WR_PROT_ERR	vxge_mBIT(40)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_WR_PROT_ERR	vxge_mBIT(41)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_INV_ADDR_ERR	vxge_mBIT(42)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_INV_ADDR_ERR	vxge_mBIT(43)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_INV_ADDR_ERR	vxge_mBIT(44)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_RD_PROT_INFO_ERR	vxge_mBIT(45)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_RD_PROT_INFO_ERR	vxge_mBIT(46)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_RD_PROT_INFO_ERR	vxge_mBIT(47)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_WR_PROT_INFO_ERR	vxge_mBIT(48)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_WR_PROT_INFO_ERR	vxge_mBIT(49)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_WR_PROT_INFO_ERR	vxge_mBIT(50)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_INV_ADDR_INFO_ERR	vxge_mBIT(51)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_INV_ADDR_INFO_ERR	vxge_mBIT(52)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_INV_ADDR_INFO_ERR	vxge_mBIT(53)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XT_PIF_SRAM_SG_ERR(val) vxge_vBIT(val, 54, 2)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CP2BDT_DFIFO_PUSH_ERR	vxge_mBIT(56)
+#define	VXGE_HW_PXTMC_ERR_REG_XTMC_CP2BDT_RFIFO_PUSH_ERR	vxge_mBIT(57)
+/*0x04f18*/	u64	pxtmc_err_mask;
+/*0x04f20*/	u64	pxtmc_err_alarm;
+/*0x04f28*/	u64	cp_err_reg;
+#define VXGE_HW_CP_ERR_REG_CP_CP_DCACHE_SG_ERR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ICACHE_SG_ERR(val) vxge_vBIT(val, 8, 2)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_DTAG_SG_ERR	vxge_mBIT(10)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_ITAG_SG_ERR	vxge_mBIT(11)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_TRACE_SG_ERR	vxge_mBIT(12)
+#define	VXGE_HW_CP_ERR_REG_CP_DMA2CP_SG_ERR	vxge_mBIT(13)
+#define	VXGE_HW_CP_ERR_REG_CP_MP2CP_SG_ERR	vxge_mBIT(14)
+#define	VXGE_HW_CP_ERR_REG_CP_QCC2CP_SG_ERR	vxge_mBIT(15)
+#define VXGE_HW_CP_ERR_REG_CP_STC2CP_SG_ERR(val) vxge_vBIT(val, 16, 2)
+#define VXGE_HW_CP_ERR_REG_CP_CP_DCACHE_DB_ERR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ICACHE_DB_ERR(val) vxge_vBIT(val, 32, 2)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_DTAG_DB_ERR	vxge_mBIT(34)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_ITAG_DB_ERR	vxge_mBIT(35)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_TRACE_DB_ERR	vxge_mBIT(36)
+#define	VXGE_HW_CP_ERR_REG_CP_DMA2CP_DB_ERR	vxge_mBIT(37)
+#define	VXGE_HW_CP_ERR_REG_CP_MP2CP_DB_ERR	vxge_mBIT(38)
+#define	VXGE_HW_CP_ERR_REG_CP_QCC2CP_DB_ERR	vxge_mBIT(39)
+#define VXGE_HW_CP_ERR_REG_CP_STC2CP_DB_ERR(val) vxge_vBIT(val, 40, 2)
+#define	VXGE_HW_CP_ERR_REG_CP_H2L2CP_FIFO_ERR	vxge_mBIT(48)
+#define	VXGE_HW_CP_ERR_REG_CP_STC2CP_FIFO_ERR	vxge_mBIT(49)
+#define	VXGE_HW_CP_ERR_REG_CP_STE2CP_FIFO_ERR	vxge_mBIT(50)
+#define	VXGE_HW_CP_ERR_REG_CP_TTE2CP_FIFO_ERR	vxge_mBIT(51)
+#define	VXGE_HW_CP_ERR_REG_CP_SWIF2CP_FIFO_ERR	vxge_mBIT(52)
+#define	VXGE_HW_CP_ERR_REG_CP_CP2DMA_FIFO_ERR	vxge_mBIT(53)
+#define	VXGE_HW_CP_ERR_REG_CP_DAM2CP_FIFO_ERR	vxge_mBIT(54)
+#define	VXGE_HW_CP_ERR_REG_CP_MP2CP_FIFO_ERR	vxge_mBIT(55)
+#define	VXGE_HW_CP_ERR_REG_CP_QCC2CP_FIFO_ERR	vxge_mBIT(56)
+#define	VXGE_HW_CP_ERR_REG_CP_DMA2CP_FIFO_ERR	vxge_mBIT(57)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_WAKE_FSM_INTEGRITY_ERR	vxge_mBIT(60)
+#define	VXGE_HW_CP_ERR_REG_CP_CP_PMON_FSM_INTEGRITY_ERR	vxge_mBIT(61)
+#define	VXGE_HW_CP_ERR_REG_CP_DMA_RD_SHADOW_ERR	vxge_mBIT(62)
+#define	VXGE_HW_CP_ERR_REG_CP_PIFT_CREDIT_ERR	vxge_mBIT(63)
+/*0x04f30*/	u64	cp_err_mask;
+/*0x04f38*/	u64	cp_err_alarm;
+	u8	unused04fe8[0x04f50-0x04f40];
+
+/*0x04f50*/	u64	cp_exc_reg;
+#define	VXGE_HW_CP_EXC_REG_CP_CP_CAUSE_INFO_INT	vxge_mBIT(47)
+#define	VXGE_HW_CP_EXC_REG_CP_CP_CAUSE_CRIT_INT	vxge_mBIT(55)
+#define	VXGE_HW_CP_EXC_REG_CP_CP_SERR	vxge_mBIT(63)
+/*0x04f58*/	u64	cp_exc_mask;
+/*0x04f60*/	u64	cp_exc_alarm;
+/*0x04f68*/	u64	cp_exc_cause;
+#define VXGE_HW_CP_EXC_CAUSE_CP_CP_CAUSE(val) vxge_vBIT(val, 32, 32)
+	u8	unused05200[0x05200-0x04f70];
+
+/*0x05200*/	u64	msg_int_status;
+#define	VXGE_HW_MSG_INT_STATUS_TIM_ERR_TIM_INT	vxge_mBIT(7)
+#define	VXGE_HW_MSG_INT_STATUS_MSG_EXC_MSG_XT_EXC_INT	vxge_mBIT(60)
+#define	VXGE_HW_MSG_INT_STATUS_MSG_ERR3_MSG_ERR3_INT	vxge_mBIT(61)
+#define	VXGE_HW_MSG_INT_STATUS_MSG_ERR2_MSG_ERR2_INT	vxge_mBIT(62)
+#define	VXGE_HW_MSG_INT_STATUS_MSG_ERR_MSG_ERR_INT	vxge_mBIT(63)
+/*0x05208*/	u64	msg_int_mask;
+/*0x05210*/	u64	tim_err_reg;
+#define	VXGE_HW_TIM_ERR_REG_TIM_VBLS_SG_ERR	vxge_mBIT(4)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_PA_SG_ERR	vxge_mBIT(5)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_PB_SG_ERR	vxge_mBIT(6)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_SG_ERR	vxge_mBIT(7)
+#define	VXGE_HW_TIM_ERR_REG_TIM_VBLS_DB_ERR	vxge_mBIT(12)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_PA_DB_ERR	vxge_mBIT(13)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_PB_DB_ERR	vxge_mBIT(14)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_DB_ERR	vxge_mBIT(15)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_MEM_CNTRL_SM_ERR	vxge_mBIT(18)
+#define	VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_MEM_CNTRL_SM_ERR	vxge_mBIT(19)
+#define	VXGE_HW_TIM_ERR_REG_TIM_MPIF_PCIWR_ERR	vxge_mBIT(20)
+#define	VXGE_HW_TIM_ERR_REG_TIM_ROCRC_BMAP_UPDT_FIFO_ERR	vxge_mBIT(22)
+#define	VXGE_HW_TIM_ERR_REG_TIM_CREATE_BMAPMSG_FIFO_ERR	vxge_mBIT(23)
+#define	VXGE_HW_TIM_ERR_REG_TIM_ROCRCIF_MISMATCH	vxge_mBIT(46)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MAPPING_VP_ERR(n)	vxge_mBIT(n)
+/*0x05218*/	u64	tim_err_mask;
+/*0x05220*/	u64	tim_err_alarm;
+/*0x05228*/	u64	msg_err_reg;
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_WAKE_FSM_INTEGRITY_ERR	vxge_mBIT(0)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_WAKE_FSM_INTEGRITY_ERR	vxge_mBIT(1)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_DMA_READ_CMD_FSM_INTEGRITY_ERR \
+								vxge_mBIT(2)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_DMA_RESP_FSM_INTEGRITY_ERR \
+								vxge_mBIT(3)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_OWN_FSM_INTEGRITY_ERR	vxge_mBIT(4)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_PDA_ACC_FSM_INTEGRITY_ERR	vxge_mBIT(5)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_PMON_FSM_INTEGRITY_ERR	vxge_mBIT(6)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_PMON_FSM_INTEGRITY_ERR	vxge_mBIT(7)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_DTAG_SG_ERR	vxge_mBIT(8)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_ITAG_SG_ERR	vxge_mBIT(10)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_DTAG_SG_ERR	vxge_mBIT(12)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_ITAG_SG_ERR	vxge_mBIT(14)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_TRACE_SG_ERR	vxge_mBIT(16)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_TRACE_SG_ERR	vxge_mBIT(17)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_CMG2MSG_SG_ERR	vxge_mBIT(18)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_TXPE2MSG_SG_ERR	vxge_mBIT(19)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_RXPE2MSG_SG_ERR	vxge_mBIT(20)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_RPE2MSG_SG_ERR	vxge_mBIT(21)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_SG_ERR	vxge_mBIT(26)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_PF_SG_ERR	vxge_mBIT(27)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_ECC_SG_ERR	vxge_mBIT(29)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_RESP_ECC_SG_ERR	vxge_mBIT(31)
+#define	VXGE_HW_MSG_ERR_REG_MSG_XFMDQRY_FSM_INTEGRITY_ERR	vxge_mBIT(33)
+#define	VXGE_HW_MSG_ERR_REG_MSG_FRMQRY_FSM_INTEGRITY_ERR	vxge_mBIT(34)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_WRITE_FSM_INTEGRITY_ERR	vxge_mBIT(35)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_BWR_PF_FSM_INTEGRITY_ERR \
+								vxge_mBIT(36)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_REG_RESP_FIFO_ERR	vxge_mBIT(38)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_DTAG_DB_ERR	vxge_mBIT(39)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_ITAG_DB_ERR	vxge_mBIT(41)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_DTAG_DB_ERR	vxge_mBIT(43)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_ITAG_DB_ERR	vxge_mBIT(45)
+#define	VXGE_HW_MSG_ERR_REG_UP_UXP_TRACE_DB_ERR	vxge_mBIT(47)
+#define	VXGE_HW_MSG_ERR_REG_MP_MXP_TRACE_DB_ERR	vxge_mBIT(48)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_CMG2MSG_DB_ERR	vxge_mBIT(49)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_TXPE2MSG_DB_ERR	vxge_mBIT(50)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_RXPE2MSG_DB_ERR	vxge_mBIT(51)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_RPE2MSG_DB_ERR	vxge_mBIT(52)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_REG_READ_FIFO_ERR	vxge_mBIT(53)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_MXP2UXP_FIFO_ERR	vxge_mBIT(54)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_KDFC_SIF_FIFO_ERR	vxge_mBIT(55)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_CXP2SWIF_FIFO_ERR	vxge_mBIT(56)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_DB_ERR	vxge_mBIT(57)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_PF_DB_ERR	vxge_mBIT(58)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_SIF_FIFO_ERR	vxge_mBIT(59)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_ECC_DB_ERR	vxge_mBIT(60)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_READ_FIFO_ERR	vxge_mBIT(61)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_RESP_ECC_DB_ERR	vxge_mBIT(62)
+#define	VXGE_HW_MSG_ERR_REG_MSG_QUE_UXP2MXP_FIFO_ERR	vxge_mBIT(63)
+/*0x05230*/	u64	msg_err_mask;
+/*0x05238*/	u64	msg_err_alarm;
+	u8	unused05340[0x05340-0x05240];
+
+/*0x05340*/	u64	msg_exc_reg;
+#define	VXGE_HW_MSG_EXC_REG_MP_MXP_CAUSE_INFO_INT	vxge_mBIT(50)
+#define	VXGE_HW_MSG_EXC_REG_MP_MXP_CAUSE_CRIT_INT	vxge_mBIT(51)
+#define	VXGE_HW_MSG_EXC_REG_UP_UXP_CAUSE_INFO_INT	vxge_mBIT(54)
+#define	VXGE_HW_MSG_EXC_REG_UP_UXP_CAUSE_CRIT_INT	vxge_mBIT(55)
+#define	VXGE_HW_MSG_EXC_REG_MP_MXP_SERR	vxge_mBIT(62)
+#define	VXGE_HW_MSG_EXC_REG_UP_UXP_SERR	vxge_mBIT(63)
+/*0x05348*/	u64	msg_exc_mask;
+/*0x05350*/	u64	msg_exc_alarm;
+/*0x05358*/	u64	msg_exc_cause;
+#define VXGE_HW_MSG_EXC_CAUSE_MP_MXP(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_MSG_EXC_CAUSE_UP_UXP(val) vxge_vBIT(val, 32, 32)
+	u8	unused05368[0x05380-0x05360];
+
+/*0x05380*/	u64	msg_err2_reg;
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_CMG2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+							vxge_mBIT(0)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_DMQ_DISPATCH_FSM_INTEGRITY_ERR \
+								vxge_mBIT(1)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIF_DISPATCH_FSM_INTEGRITY_ERR \
+								vxge_mBIT(2)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_PIC_WRITE_FSM_INTEGRITY_ERR \
+								vxge_mBIT(3)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIFREG_FSM_INTEGRITY_ERR	vxge_mBIT(4)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_TIM_WRITE_FSM_INTEGRITY_ERR \
+								vxge_mBIT(5)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_UMQ_TA_FSM_INTEGRITY_ERR	vxge_mBIT(6)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_TXPE_TA_FSM_INTEGRITY_ERR	vxge_mBIT(7)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_RXPE_TA_FSM_INTEGRITY_ERR	vxge_mBIT(8)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIF_TA_FSM_INTEGRITY_ERR	vxge_mBIT(9)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_DMA_TA_FSM_INTEGRITY_ERR	vxge_mBIT(10)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_CP_TA_FSM_INTEGRITY_ERR	vxge_mBIT(11)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA16_FSM_INTEGRITY_ERR \
+							vxge_mBIT(12)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA15_FSM_INTEGRITY_ERR \
+							vxge_mBIT(13)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA14_FSM_INTEGRITY_ERR \
+							vxge_mBIT(14)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA13_FSM_INTEGRITY_ERR \
+							vxge_mBIT(15)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA12_FSM_INTEGRITY_ERR \
+							vxge_mBIT(16)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA11_FSM_INTEGRITY_ERR \
+							vxge_mBIT(17)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA10_FSM_INTEGRITY_ERR \
+							vxge_mBIT(18)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA9_FSM_INTEGRITY_ERR \
+							vxge_mBIT(19)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA8_FSM_INTEGRITY_ERR \
+							vxge_mBIT(20)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA7_FSM_INTEGRITY_ERR \
+							vxge_mBIT(21)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA6_FSM_INTEGRITY_ERR \
+							vxge_mBIT(22)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA5_FSM_INTEGRITY_ERR \
+							vxge_mBIT(23)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA4_FSM_INTEGRITY_ERR \
+							vxge_mBIT(24)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA3_FSM_INTEGRITY_ERR \
+							vxge_mBIT(25)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA2_FSM_INTEGRITY_ERR \
+							vxge_mBIT(26)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA1_FSM_INTEGRITY_ERR \
+							vxge_mBIT(27)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA0_FSM_INTEGRITY_ERR \
+							vxge_mBIT(28)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_FBMC_OWN_FSM_INTEGRITY_ERR	vxge_mBIT(29)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_TXPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+							vxge_mBIT(30)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_RXPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+							vxge_mBIT(31)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_RPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+							vxge_mBIT(32)
+#define	VXGE_HW_MSG_ERR2_REG_MP_MP_PIFT_IF_CREDIT_CNT_ERR	vxge_mBIT(33)
+#define	VXGE_HW_MSG_ERR2_REG_UP_UP_PIFT_IF_CREDIT_CNT_ERR	vxge_mBIT(34)
+#define	VXGE_HW_MSG_ERR2_REG_MSG_QUE_UMQ2PIC_CMD_FIFO_ERR	vxge_mBIT(62)
+#define	VXGE_HW_MSG_ERR2_REG_TIM_TIM2MSG_CMD_FIFO_ERR	vxge_mBIT(63)
+/*0x05388*/	u64	msg_err2_mask;
+/*0x05390*/	u64	msg_err2_alarm;
+/*0x05398*/	u64	msg_err3_reg;
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR0	vxge_mBIT(0)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR1	vxge_mBIT(1)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR2	vxge_mBIT(2)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR3	vxge_mBIT(3)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR4	vxge_mBIT(4)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR5	vxge_mBIT(5)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR6	vxge_mBIT(6)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR7	vxge_mBIT(7)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_SG_ERR0	vxge_mBIT(8)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_SG_ERR1	vxge_mBIT(9)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR0	vxge_mBIT(16)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR1	vxge_mBIT(17)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR2	vxge_mBIT(18)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR3	vxge_mBIT(19)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR4	vxge_mBIT(20)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR5	vxge_mBIT(21)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR6	vxge_mBIT(22)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR7	vxge_mBIT(23)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_SG_ERR0	vxge_mBIT(24)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_SG_ERR1	vxge_mBIT(25)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR0	vxge_mBIT(32)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR1	vxge_mBIT(33)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR2	vxge_mBIT(34)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR3	vxge_mBIT(35)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR4	vxge_mBIT(36)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR5	vxge_mBIT(37)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR6	vxge_mBIT(38)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR7	vxge_mBIT(39)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_DB_ERR0	vxge_mBIT(40)
+#define	VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_DB_ERR1	vxge_mBIT(41)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR0	vxge_mBIT(48)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR1	vxge_mBIT(49)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR2	vxge_mBIT(50)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR3	vxge_mBIT(51)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR4	vxge_mBIT(52)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR5	vxge_mBIT(53)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR6	vxge_mBIT(54)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR7	vxge_mBIT(55)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_DB_ERR0	vxge_mBIT(56)
+#define	VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_DB_ERR1	vxge_mBIT(57)
+/*0x053a0*/	u64	msg_err3_mask;
+/*0x053a8*/	u64	msg_err3_alarm;
+	u8	unused05600[0x05600-0x053b0];
+
+/*0x05600*/	u64	fau_gen_err_reg;
+#define	VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT0_PERMANENT_STOP	vxge_mBIT(3)
+#define	VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT1_PERMANENT_STOP	vxge_mBIT(7)
+#define	VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT2_PERMANENT_STOP	vxge_mBIT(11)
+#define	VXGE_HW_FAU_GEN_ERR_REG_FALR_AUTO_LRO_NOTIFICATION	vxge_mBIT(15)
+/*0x05608*/	u64	fau_gen_err_mask;
+/*0x05610*/	u64	fau_gen_err_alarm;
+/*0x05618*/	u64	fau_ecc_err_reg;
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_N_SG_ERR	vxge_mBIT(0)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_N_DB_ERR	vxge_mBIT(1)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_W_SG_ERR(val) \
+							vxge_vBIT(val, 2, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_W_DB_ERR(val) \
+							vxge_vBIT(val, 4, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_N_SG_ERR	vxge_mBIT(6)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_N_DB_ERR	vxge_mBIT(7)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_W_SG_ERR(val) \
+							vxge_vBIT(val, 8, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_W_DB_ERR(val) \
+							vxge_vBIT(val, 10, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_N_SG_ERR	vxge_mBIT(12)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_N_DB_ERR	vxge_mBIT(13)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_W_SG_ERR(val) \
+							vxge_vBIT(val, 14, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_W_DB_ERR(val) \
+							vxge_vBIT(val, 16, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_FAU_XFMD_INS_SG_ERR(val) \
+							vxge_vBIT(val, 18, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_FAU_XFMD_INS_DB_ERR(val) \
+							vxge_vBIT(val, 20, 2)
+#define	VXGE_HW_FAU_ECC_ERR_REG_FAUJ_FAU_FSM_ERR	vxge_mBIT(31)
+/*0x05620*/	u64	fau_ecc_err_mask;
+/*0x05628*/	u64	fau_ecc_err_alarm;
+	u8	unused05658[0x05658-0x05630];
+/*0x05658*/	u64	fau_pa_cfg;
+#define	VXGE_HW_FAU_PA_CFG_REPL_L4_COMP_CSUM	vxge_mBIT(3)
+#define	VXGE_HW_FAU_PA_CFG_REPL_L3_INCL_CF	vxge_mBIT(7)
+#define	VXGE_HW_FAU_PA_CFG_REPL_L3_COMP_CSUM	vxge_mBIT(11)
+	u8	unused05668[0x05668-0x05660];
+
+/*0x05668*/	u64	dbg_stats_fau_rx_path;
+#define	VXGE_HW_DBG_STATS_FAU_RX_PATH_RX_PERMITTED_FRMS(val) \
+						vxge_vBIT(val, 32, 32)
+	u8	unused056c0[0x056c0-0x05670];
+
+/*0x056c0*/	u64	fau_lag_cfg;
+#define VXGE_HW_FAU_LAG_CFG_COLL_ALG(val) vxge_vBIT(val, 2, 2)
+#define	VXGE_HW_FAU_LAG_CFG_INCR_RX_AGGR_STATS	vxge_mBIT(7)
+	u8	unused05800[0x05800-0x056c8];
+
+/*0x05800*/	u64	tpa_int_status;
+#define	VXGE_HW_TPA_INT_STATUS_ORP_ERR_ORP_INT	vxge_mBIT(15)
+#define	VXGE_HW_TPA_INT_STATUS_PTM_ALARM_PTM_INT	vxge_mBIT(23)
+#define	VXGE_HW_TPA_INT_STATUS_TPA_ERROR_TPA_INT	vxge_mBIT(31)
+/*0x05808*/	u64	tpa_int_mask;
+/*0x05810*/	u64	orp_err_reg;
+#define	VXGE_HW_ORP_ERR_REG_ORP_FIFO_SG_ERR	vxge_mBIT(3)
+#define	VXGE_HW_ORP_ERR_REG_ORP_FIFO_DB_ERR	vxge_mBIT(7)
+#define	VXGE_HW_ORP_ERR_REG_ORP_XFMD_FIFO_UFLOW_ERR	vxge_mBIT(11)
+#define	VXGE_HW_ORP_ERR_REG_ORP_FRM_FIFO_UFLOW_ERR	vxge_mBIT(15)
+#define	VXGE_HW_ORP_ERR_REG_ORP_XFMD_RCV_FSM_ERR	vxge_mBIT(19)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OUTREAD_FSM_ERR	vxge_mBIT(23)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OUTQEM_FSM_ERR	vxge_mBIT(27)
+#define	VXGE_HW_ORP_ERR_REG_ORP_XFMD_RCV_SHADOW_ERR	vxge_mBIT(31)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OUTREAD_SHADOW_ERR	vxge_mBIT(35)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OUTQEM_SHADOW_ERR	vxge_mBIT(39)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OUTFRM_SHADOW_ERR	vxge_mBIT(43)
+#define	VXGE_HW_ORP_ERR_REG_ORP_OPTPRS_SHADOW_ERR	vxge_mBIT(47)
+/*0x05818*/	u64	orp_err_mask;
+/*0x05820*/	u64	orp_err_alarm;
+/*0x05828*/	u64	ptm_alarm_reg;
+#define	VXGE_HW_PTM_ALARM_REG_PTM_RDCTRL_SYNC_ERR	vxge_mBIT(3)
+#define	VXGE_HW_PTM_ALARM_REG_PTM_RDCTRL_FIFO_ERR	vxge_mBIT(7)
+#define	VXGE_HW_PTM_ALARM_REG_XFMD_RD_FIFO_ERR	vxge_mBIT(11)
+#define	VXGE_HW_PTM_ALARM_REG_WDE2MSR_WR_FIFO_ERR	vxge_mBIT(15)
+#define VXGE_HW_PTM_ALARM_REG_PTM_FRMM_ECC_DB_ERR(val) vxge_vBIT(val, 18, 2)
+#define VXGE_HW_PTM_ALARM_REG_PTM_FRMM_ECC_SG_ERR(val) vxge_vBIT(val, 22, 2)
+/*0x05830*/	u64	ptm_alarm_mask;
+/*0x05838*/	u64	ptm_alarm_alarm;
+/*0x05840*/	u64	tpa_error_reg;
+#define	VXGE_HW_TPA_ERROR_REG_TPA_FSM_ERR_ALARM	vxge_mBIT(3)
+#define	VXGE_HW_TPA_ERROR_REG_TPA_TPA_DA_LKUP_PRT0_DB_ERR	vxge_mBIT(7)
+#define	VXGE_HW_TPA_ERROR_REG_TPA_TPA_DA_LKUP_PRT0_SG_ERR	vxge_mBIT(11)
+/*0x05848*/	u64	tpa_error_mask;
+/*0x05850*/	u64	tpa_error_alarm;
+/*0x05858*/	u64	tpa_global_cfg;
+#define	VXGE_HW_TPA_GLOBAL_CFG_SUPPORT_SNAP_AB_N	vxge_mBIT(7)
+#define	VXGE_HW_TPA_GLOBAL_CFG_ECC_ENABLE_N	vxge_mBIT(35)
+	u8	unused05868[0x05870-0x05860];
+
+/*0x05870*/	u64	ptm_ecc_cfg;
+#define	VXGE_HW_PTM_ECC_CFG_PTM_FRMM_ECC_EN_N	vxge_mBIT(3)
+/*0x05878*/	u64	ptm_phase_cfg;
+#define	VXGE_HW_PTM_PHASE_CFG_FRMM_WR_PHASE_EN	vxge_mBIT(3)
+#define	VXGE_HW_PTM_PHASE_CFG_FRMM_RD_PHASE_EN	vxge_mBIT(7)
+	u8	unused05898[0x05898-0x05880];
+
+/*0x05898*/	u64	dbg_stats_tpa_tx_path;
+#define	VXGE_HW_DBG_STATS_TPA_TX_PATH_TX_PERMITTED_FRMS(val) \
+							vxge_vBIT(val, 32, 32)
+	u8	unused05900[0x05900-0x058a0];
+
+/*0x05900*/	u64	tmac_int_status;
+#define	VXGE_HW_TMAC_INT_STATUS_TXMAC_GEN_ERR_TXMAC_GEN_INT	vxge_mBIT(3)
+#define	VXGE_HW_TMAC_INT_STATUS_TXMAC_ECC_ERR_TXMAC_ECC_INT	vxge_mBIT(7)
+/*0x05908*/	u64	tmac_int_mask;
+/*0x05910*/	u64	txmac_gen_err_reg;
+#define	VXGE_HW_TXMAC_GEN_ERR_REG_TMACJ_PERMANENT_STOP	vxge_mBIT(3)
+#define	VXGE_HW_TXMAC_GEN_ERR_REG_TMACJ_NO_VALID_VSPORT	vxge_mBIT(7)
+/*0x05918*/	u64	txmac_gen_err_mask;
+/*0x05920*/	u64	txmac_gen_err_alarm;
+/*0x05928*/	u64	txmac_ecc_err_reg;
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2MAC_SG_ERR	vxge_mBIT(3)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2MAC_DB_ERR	vxge_mBIT(7)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_SB_SG_ERR	vxge_mBIT(11)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_SB_DB_ERR	vxge_mBIT(15)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_DA_SG_ERR	vxge_mBIT(19)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_DA_DB_ERR	vxge_mBIT(23)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT0_FSM_ERR	vxge_mBIT(27)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT1_FSM_ERR	vxge_mBIT(31)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT2_FSM_ERR	vxge_mBIT(35)
+#define	VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMACJ_FSM_ERR	vxge_mBIT(39)
+/*0x05930*/	u64	txmac_ecc_err_mask;
+/*0x05938*/	u64	txmac_ecc_err_alarm;
+	u8	unused05978[0x05978-0x05940];
+
+/*0x05978*/	u64	dbg_stat_tx_any_frms;
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT0_TX_ANY_FRMS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT1_TX_ANY_FRMS(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT2_TX_ANY_FRMS(val) \
+							vxge_vBIT(val, 16, 8)
+	u8	unused059a0[0x059a0-0x05980];
+
+/*0x059a0*/	u64	txmac_link_util_port[3];
+#define	VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_UTILIZATION(val) \
+							vxge_vBIT(val, 1, 7)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_UTIL_CFG(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_FRAC_UTIL(val) \
+							vxge_vBIT(val, 12, 4)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_PKT_WEIGHT(val) vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_SCALE_FACTOR	vxge_mBIT(23)
+/*0x059b8*/	u64	txmac_cfg0_port[3];
+#define	VXGE_HW_TXMAC_CFG0_PORT_TMAC_EN	vxge_mBIT(3)
+#define	VXGE_HW_TXMAC_CFG0_PORT_APPEND_PAD	vxge_mBIT(7)
+#define VXGE_HW_TXMAC_CFG0_PORT_PAD_BYTE(val) vxge_vBIT(val, 8, 8)
+/*0x059d0*/	u64	txmac_cfg1_port[3];
+#define VXGE_HW_TXMAC_CFG1_PORT_AVG_IPG(val) vxge_vBIT(val, 40, 8)
+/*0x059e8*/	u64	txmac_status_port[3];
+#define	VXGE_HW_TXMAC_STATUS_PORT_TMAC_TX_FRM_SENT	vxge_mBIT(3)
+	u8	unused05a20[0x05a20-0x05a00];
+
+/*0x05a20*/	u64	lag_distrib_dest;
+#define VXGE_HW_LAG_DISTRIB_DEST_MAP_VPATH(n)	vxge_mBIT(n)
+/*0x05a28*/	u64	lag_marker_cfg;
+#define	VXGE_HW_LAG_MARKER_CFG_GEN_RCVR_EN	vxge_mBIT(3)
+#define	VXGE_HW_LAG_MARKER_CFG_RESP_EN	vxge_mBIT(7)
+#define VXGE_HW_LAG_MARKER_CFG_RESP_TIMEOUT(val) vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_LAG_MARKER_CFG_SLOW_PROTO_MRKR_MIN_INTERVAL(val) \
+							vxge_vBIT(val, 32, 16)
+#define	VXGE_HW_LAG_MARKER_CFG_THROTTLE_MRKR_RESP	vxge_mBIT(51)
+/*0x05a30*/	u64	lag_tx_cfg;
+#define	VXGE_HW_LAG_TX_CFG_INCR_TX_AGGR_STATS	vxge_mBIT(3)
+#define VXGE_HW_LAG_TX_CFG_DISTRIB_ALG_SEL(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_LAG_TX_CFG_DISTRIB_REMAP_IF_FAIL	vxge_mBIT(11)
+#define VXGE_HW_LAG_TX_CFG_COLL_MAX_DELAY(val) vxge_vBIT(val, 16, 16)
+/*0x05a38*/	u64	lag_tx_status;
+#define VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_EMPTIED_LINK(val) \
+							vxge_vBIT(val, 0, 8)
+#define	VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_SLOW_PROTO_MRKR(val) \
+							vxge_vBIT(val, 8, 8)
+#define	VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_SLOW_PROTO_MRKRRESP(val) \
+							vxge_vBIT(val, 16, 8)
+	u8	unused05d48[0x05d48-0x05a40];
+
+/*0x05d48*/	u64	srpcim_to_mrpcim_vplane_rmsg[17];
+#define	\
+VXGE_HAL_SRPCIM_TO_MRPCIM_VPLANE_RMSG_SWIF_SRPCIM_TO_MRPCIM_VPLANE_RMSG(val)\
+ vxge_vBIT(val, 0, 64)
+		u8	unused06420[0x06420-0x05dd0];
+
+/*0x06420*/	u64	mrpcim_to_srpcim_vplane_wmsg[17];
+#define	VXGE_HW_MRPCIM_TO_SRPCIM_VPLANE_WMSG_MRPCIM_TO_SRPCIM_VPLANE_WMSG(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x064a8*/	u64	mrpcim_to_srpcim_vplane_wmsg_trig[17];
+
+/*0x06530*/	u64	debug_stats0;
+#define VXGE_HW_DEBUG_STATS0_RSTDROP_MSG(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_DEBUG_STATS0_RSTDROP_CPL(val) vxge_vBIT(val, 32, 32)
+/*0x06538*/	u64	debug_stats1;
+#define VXGE_HW_DEBUG_STATS1_RSTDROP_CLIENT0(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_DEBUG_STATS1_RSTDROP_CLIENT1(val) vxge_vBIT(val, 32, 32)
+/*0x06540*/	u64	debug_stats2;
+#define VXGE_HW_DEBUG_STATS2_RSTDROP_CLIENT2(val) vxge_vBIT(val, 0, 32)
+/*0x06548*/	u64	debug_stats3_vplane[17];
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_PH(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_NPH(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_CPLH(val) vxge_vBIT(val, 32, 16)
+/*0x065d0*/	u64	debug_stats4_vplane[17];
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_PD(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_NPD(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_CPLD(val) vxge_vBIT(val, 32, 16)
+
+	u8	unused07000[0x07000-0x06658];
+
+/*0x07000*/	u64	mrpcim_general_int_status;
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PIC_INT	vxge_mBIT(0)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCI_INT	vxge_mBIT(1)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_RTDMA_INT	vxge_mBIT(2)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_WRDMA_INT	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMCT_INT	vxge_mBIT(4)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG1_INT	vxge_mBIT(5)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG2_INT	vxge_mBIT(6)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG3_INT	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMIFL_INT	vxge_mBIT(8)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMIFU_INT	vxge_mBIT(9)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG1_INT	vxge_mBIT(10)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG2_INT	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG3_INT	vxge_mBIT(12)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_XMAC_INT	vxge_mBIT(13)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_RXMAC_INT	vxge_mBIT(14)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_TMAC_INT	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3FBIF_INT	vxge_mBIT(16)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_FBMC_INT	vxge_mBIT(17)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3FBCT_INT	vxge_mBIT(18)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_TPA_INT	vxge_mBIT(19)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_DRBELL_INT	vxge_mBIT(20)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_ONE_INT	vxge_mBIT(21)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_STATUS_MSG_INT	vxge_mBIT(22)
+/*0x07008*/	u64	mrpcim_general_int_mask;
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_PIC_INT	vxge_mBIT(0)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCI_INT	vxge_mBIT(1)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_RTDMA_INT	vxge_mBIT(2)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_WRDMA_INT	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMCT_INT	vxge_mBIT(4)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG1_INT	vxge_mBIT(5)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG2_INT	vxge_mBIT(6)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG3_INT	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMIFL_INT	vxge_mBIT(8)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMIFU_INT	vxge_mBIT(9)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG1_INT	vxge_mBIT(10)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG2_INT	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG3_INT	vxge_mBIT(12)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_XMAC_INT	vxge_mBIT(13)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_RXMAC_INT	vxge_mBIT(14)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_TMAC_INT	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3FBIF_INT	vxge_mBIT(16)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_FBMC_INT	vxge_mBIT(17)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3FBCT_INT	vxge_mBIT(18)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_TPA_INT	vxge_mBIT(19)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_DRBELL_INT	vxge_mBIT(20)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_ONE_INT	vxge_mBIT(21)
+#define	VXGE_HW_MRPCIM_GENERAL_INT_MASK_MSG_INT	vxge_mBIT(22)
+/*0x07010*/	u64	mrpcim_ppif_int_status;
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_INI_ERRORS_INI_INT	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_DMA_ERRORS_DMA_INT	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_TGT_ERRORS_TGT_INT	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CONFIG_ERRORS_CONFIG_INT	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_CRDT_INT	vxge_mBIT(19)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_PLL_ERRORS_PLL_INT	vxge_mBIT(27)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE0_CRD_INT_VPLANE0_INT\
+							vxge_mBIT(31)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE1_CRD_INT_VPLANE1_INT\
+							vxge_mBIT(32)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE2_CRD_INT_VPLANE2_INT\
+							vxge_mBIT(33)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE3_CRD_INT_VPLANE3_INT\
+							vxge_mBIT(34)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE4_CRD_INT_VPLANE4_INT\
+							vxge_mBIT(35)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE5_CRD_INT_VPLANE5_INT\
+							vxge_mBIT(36)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE6_CRD_INT_VPLANE6_INT\
+							vxge_mBIT(37)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE7_CRD_INT_VPLANE7_INT\
+							vxge_mBIT(38)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE8_CRD_INT_VPLANE8_INT\
+							vxge_mBIT(39)
+#define	VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE9_CRD_INT_VPLANE9_INT\
+							vxge_mBIT(40)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE10_CRD_INT_VPLANE10_INT \
+							vxge_mBIT(41)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE11_CRD_INT_VPLANE11_INT \
+							vxge_mBIT(42)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE12_CRD_INT_VPLANE12_INT \
+							vxge_mBIT(43)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE13_CRD_INT_VPLANE13_INT \
+							vxge_mBIT(44)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE14_CRD_INT_VPLANE14_INT \
+							vxge_mBIT(45)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE15_CRD_INT_VPLANE15_INT \
+							vxge_mBIT(46)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE16_CRD_INT_VPLANE16_INT \
+							vxge_mBIT(47)
+#define	\
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_VPATH_TO_MRPCIM_ALARM_VPATH_TO_MRPCIM_ALARM_INT \
+							vxge_mBIT(55)
+/*0x07018*/	u64	mrpcim_ppif_int_mask;
+	u8	unused07028[0x07028-0x07020];
+
+/*0x07028*/	u64	ini_errors_reg;
+#define	VXGE_HW_INI_ERRORS_REG_SCPL_CPL_TIMEOUT_UNUSED_TAG	vxge_mBIT(3)
+#define	VXGE_HW_INI_ERRORS_REG_SCPL_CPL_TIMEOUT	vxge_mBIT(7)
+#define	VXGE_HW_INI_ERRORS_REG_DCPL_FSM_ERR	vxge_mBIT(11)
+#define	VXGE_HW_INI_ERRORS_REG_DCPL_POISON	vxge_mBIT(12)
+#define	VXGE_HW_INI_ERRORS_REG_DCPL_UNSUPPORTED	vxge_mBIT(15)
+#define	VXGE_HW_INI_ERRORS_REG_DCPL_ABORT	vxge_mBIT(19)
+#define	VXGE_HW_INI_ERRORS_REG_INI_TLP_ABORT	vxge_mBIT(23)
+#define	VXGE_HW_INI_ERRORS_REG_INI_DLLP_ABORT	vxge_mBIT(27)
+#define	VXGE_HW_INI_ERRORS_REG_INI_ECRC_ERR	vxge_mBIT(31)
+#define	VXGE_HW_INI_ERRORS_REG_INI_BUF_DB_ERR	vxge_mBIT(35)
+#define	VXGE_HW_INI_ERRORS_REG_INI_BUF_SG_ERR	vxge_mBIT(39)
+#define	VXGE_HW_INI_ERRORS_REG_INI_DATA_OVERFLOW	vxge_mBIT(43)
+#define	VXGE_HW_INI_ERRORS_REG_INI_HDR_OVERFLOW	vxge_mBIT(47)
+#define	VXGE_HW_INI_ERRORS_REG_INI_MRD_SYS_DROP	vxge_mBIT(51)
+#define	VXGE_HW_INI_ERRORS_REG_INI_MWR_SYS_DROP	vxge_mBIT(55)
+#define	VXGE_HW_INI_ERRORS_REG_INI_MRD_CLIENT_DROP	vxge_mBIT(59)
+#define	VXGE_HW_INI_ERRORS_REG_INI_MWR_CLIENT_DROP	vxge_mBIT(63)
+/*0x07030*/	u64	ini_errors_mask;
+/*0x07038*/	u64	ini_errors_alarm;
+/*0x07040*/	u64	dma_errors_reg;
+#define	VXGE_HW_DMA_ERRORS_REG_RDARB_FSM_ERR	vxge_mBIT(3)
+#define	VXGE_HW_DMA_ERRORS_REG_WRARB_FSM_ERR	vxge_mBIT(7)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_HDR_OVERFLOW	vxge_mBIT(8)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_HDR_UNDERFLOW	vxge_mBIT(9)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_DATA_OVERFLOW	vxge_mBIT(10)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_DATA_UNDERFLOW	vxge_mBIT(11)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_HDR_OVERFLOW	vxge_mBIT(12)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_HDR_UNDERFLOW	vxge_mBIT(13)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_DATA_OVERFLOW	vxge_mBIT(14)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_DATA_UNDERFLOW	vxge_mBIT(15)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_HDR_OVERFLOW	vxge_mBIT(16)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_HDR_UNDERFLOW	vxge_mBIT(17)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_DATA_OVERFLOW	vxge_mBIT(18)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_DATA_UNDERFLOW	vxge_mBIT(19)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_HDR_OVERFLOW	vxge_mBIT(20)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_HDR_UNDERFLOW	vxge_mBIT(21)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_DATA_OVERFLOW	vxge_mBIT(22)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_DATA_UNDERFLOW	vxge_mBIT(23)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_RD_HDR_OVERFLOW	vxge_mBIT(24)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_RD_HDR_UNDERFLOW	vxge_mBIT(25)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_RD_HDR_OVERFLOW	vxge_mBIT(28)
+#define	VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_RD_HDR_UNDERFLOW	vxge_mBIT(29)
+#define	VXGE_HW_DMA_ERRORS_REG_DBLGEN_FSM_ERR	vxge_mBIT(32)
+#define	VXGE_HW_DMA_ERRORS_REG_DBLGEN_CREDIT_FSM_ERR	vxge_mBIT(33)
+#define	VXGE_HW_DMA_ERRORS_REG_DBLGEN_DMA_WRR_SM_ERR	vxge_mBIT(34)
+/*0x07048*/	u64	dma_errors_mask;
+/*0x07050*/	u64	dma_errors_alarm;
+/*0x07058*/	u64	tgt_errors_reg;
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_VENDOR_MSG	vxge_mBIT(0)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_MSG_UNLOCK	vxge_mBIT(1)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_ILLEGAL_TLP_BE	vxge_mBIT(2)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_BOOT_WRITE	vxge_mBIT(3)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_PIF_WR_CROSS_QWRANGE	vxge_mBIT(4)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_PIF_READ_CROSS_QWRANGE	vxge_mBIT(5)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_KDFC_READ	vxge_mBIT(6)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_USDC_READ	vxge_mBIT(7)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_USDC_WR_CROSS_QWRANGE	vxge_mBIT(8)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_MSIX_BEYOND_RANGE	vxge_mBIT(9)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_KDFC_POISON	vxge_mBIT(10)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_USDC_POISON	vxge_mBIT(11)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_PIF_POISON	vxge_mBIT(12)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_MSIX_POISON	vxge_mBIT(13)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_MRIOV_POISON	vxge_mBIT(14)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_NOT_MEM_TLP	vxge_mBIT(15)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_UNKNOWN_MEM_TLP	vxge_mBIT(16)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_REQ_FSM_ERR	vxge_mBIT(17)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_CPL_FSM_ERR	vxge_mBIT(18)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_KDFC_PROT_ERR	vxge_mBIT(19)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_SWIF_PROT_ERR	vxge_mBIT(20)
+#define	VXGE_HW_TGT_ERRORS_REG_TGT_MRIOV_MEM_MAP_CFG_ERR	vxge_mBIT(21)
+/*0x07060*/	u64	tgt_errors_mask;
+/*0x07068*/	u64	tgt_errors_alarm;
+/*0x07070*/	u64	config_errors_reg;
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_ILLEGAL_STOP_COND	vxge_mBIT(3)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_ILLEGAL_START_COND	vxge_mBIT(7)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_EXP_RD_CNT	vxge_mBIT(11)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_EXTRA_CYCLE	vxge_mBIT(15)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_MAIN_FSM_ERR	vxge_mBIT(19)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_REQ_COLLISION	vxge_mBIT(23)
+#define	VXGE_HW_CONFIG_ERRORS_REG_I2C_REG_FSM_ERR	vxge_mBIT(27)
+#define	VXGE_HW_CONFIG_ERRORS_REG_CFGM_I2C_TIMEOUT	vxge_mBIT(31)
+#define	VXGE_HW_CONFIG_ERRORS_REG_RIC_I2C_TIMEOUT	vxge_mBIT(35)
+#define	VXGE_HW_CONFIG_ERRORS_REG_CFGM_FSM_ERR	vxge_mBIT(39)
+#define	VXGE_HW_CONFIG_ERRORS_REG_RIC_FSM_ERR	vxge_mBIT(43)
+#define	VXGE_HW_CONFIG_ERRORS_REG_PIFM_ILLEGAL_ACCESS	vxge_mBIT(47)
+#define	VXGE_HW_CONFIG_ERRORS_REG_PIFM_TIMEOUT	vxge_mBIT(51)
+#define	VXGE_HW_CONFIG_ERRORS_REG_PIFM_FSM_ERR	vxge_mBIT(55)
+#define	VXGE_HW_CONFIG_ERRORS_REG_PIFM_TO_FSM_ERR	vxge_mBIT(59)
+#define	VXGE_HW_CONFIG_ERRORS_REG_RIC_RIC_RD_TIMEOUT	vxge_mBIT(63)
+/*0x07078*/	u64	config_errors_mask;
+/*0x07080*/	u64	config_errors_alarm;
+	u8	unused07090[0x07090-0x07088];
+
+/*0x07090*/	u64	crdt_errors_reg;
+#define	VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_FSM_ERR	vxge_mBIT(11)
+#define	VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_INTCTL_ILLEGAL_CRD_DEAL \
+							vxge_mBIT(15)
+#define	VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_PDA_ILLEGAL_CRD_DEAL	vxge_mBIT(19)
+#define	VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_PCI_MSG_ILLEGAL_CRD_DEAL \
+							vxge_mBIT(23)
+#define	VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_FSM_ERR	vxge_mBIT(35)
+#define	VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_RDA_ILLEGAL_CRD_DEAL	vxge_mBIT(39)
+#define	VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_PDA_ILLEGAL_CRD_DEAL	vxge_mBIT(43)
+#define	VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_DBLGEN_ILLEGAL_CRD_DEAL \
+							vxge_mBIT(47)
+/*0x07098*/	u64	crdt_errors_mask;
+/*0x070a0*/	u64	crdt_errors_alarm;
+	u8	unused070b0[0x070b0-0x070a8];
+
+/*0x070b0*/	u64	mrpcim_general_errors_reg;
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_STATSB_FSM_ERR	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_XGEN_FSM_ERR	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_XMEM_FSM_ERR	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_KDFCCTL_FSM_ERR	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_MRIOVCTL_FSM_ERR	vxge_mBIT(19)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_FLSH_ERR	vxge_mBIT(23)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_IIC_ACK_ERR	vxge_mBIT(27)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_IIC_CHKSUM_ERR	vxge_mBIT(31)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INI_SERR_DET	vxge_mBIT(35)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INTCTL_MSIX_FSM_ERR	vxge_mBIT(39)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INTCTL_MSI_OVERFLOW	vxge_mBIT(43)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_PPIF_PCI_NOT_FLUSH_DURING_SW_RESET \
+							vxge_mBIT(47)
+#define	VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_PPIF_SW_RESET_FSM_ERR	vxge_mBIT(51)
+/*0x070b8*/	u64	mrpcim_general_errors_mask;
+/*0x070c0*/	u64	mrpcim_general_errors_alarm;
+	u8	unused070d0[0x070d0-0x070c8];
+
+/*0x070d0*/	u64	pll_errors_reg;
+#define	VXGE_HW_PLL_ERRORS_REG_CORE_CMG_PLL_OOL	vxge_mBIT(3)
+#define	VXGE_HW_PLL_ERRORS_REG_CORE_FB_PLL_OOL	vxge_mBIT(7)
+#define	VXGE_HW_PLL_ERRORS_REG_CORE_X_PLL_OOL	vxge_mBIT(11)
+/*0x070d8*/	u64	pll_errors_mask;
+/*0x070e0*/	u64	pll_errors_alarm;
+/*0x070e8*/	u64	srpcim_to_mrpcim_alarm_reg;
+#define	VXGE_HW_SRPCIM_TO_MRPCIM_ALARM_REG_PPIF_SRPCIM_TO_MRPCIM_ALARM(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x070f0*/	u64	srpcim_to_mrpcim_alarm_mask;
+/*0x070f8*/	u64	srpcim_to_mrpcim_alarm_alarm;
+/*0x07100*/	u64	vpath_to_mrpcim_alarm_reg;
+#define	VXGE_HW_VPATH_TO_MRPCIM_ALARM_REG_PPIF_VPATH_TO_MRPCIM_ALARM(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x07108*/	u64	vpath_to_mrpcim_alarm_mask;
+/*0x07110*/	u64	vpath_to_mrpcim_alarm_alarm;
+	u8	unused07128[0x07128-0x07118];
+
+/*0x07128*/	u64	crdt_errors_vplane_reg[17];
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_H_CONSUME_CRDT_ERR \
+							vxge_mBIT(3)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_D_CONSUME_CRDT_ERR \
+							vxge_mBIT(7)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_H_RETURN_CRDT_ERR \
+							vxge_mBIT(11)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_D_RETURN_CRDT_ERR \
+							vxge_mBIT(15)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_NP_H_CONSUME_CRDT_ERR \
+							vxge_mBIT(19)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_NP_H_RETURN_CRDT_ERR \
+							vxge_mBIT(23)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_TAG_CONSUME_TAG_ERR \
+							vxge_mBIT(27)
+#define	VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_TAG_RETURN_TAG_ERR \
+							vxge_mBIT(31)
+/*0x07130*/	u64	crdt_errors_vplane_mask[17];
+/*0x07138*/	u64	crdt_errors_vplane_alarm[17];
+	u8	unused072f0[0x072f0-0x072c0];
+
+/*0x072f0*/	u64	mrpcim_rst_in_prog;
+#define	VXGE_HW_MRPCIM_RST_IN_PROG_MRPCIM_RST_IN_PROG	vxge_mBIT(7)
+/*0x072f8*/	u64	mrpcim_reg_modified;
+#define	VXGE_HW_MRPCIM_REG_MODIFIED_MRPCIM_REG_MODIFIED	vxge_mBIT(7)
+
+	u8	unused07378[0x07378-0x07300];
+
+/*0x07378*/	u64	write_arb_pending;
+#define	VXGE_HW_WRITE_ARB_PENDING_WRARB_WRDMA	vxge_mBIT(3)
+#define	VXGE_HW_WRITE_ARB_PENDING_WRARB_RTDMA	vxge_mBIT(7)
+#define	VXGE_HW_WRITE_ARB_PENDING_WRARB_MSG	vxge_mBIT(11)
+#define	VXGE_HW_WRITE_ARB_PENDING_WRARB_STATSB	vxge_mBIT(15)
+#define	VXGE_HW_WRITE_ARB_PENDING_WRARB_INTCTL	vxge_mBIT(19)
+/*0x07380*/	u64	read_arb_pending;
+#define	VXGE_HW_READ_ARB_PENDING_RDARB_WRDMA	vxge_mBIT(3)
+#define	VXGE_HW_READ_ARB_PENDING_RDARB_RTDMA	vxge_mBIT(7)
+#define	VXGE_HW_READ_ARB_PENDING_RDARB_DBLGEN	vxge_mBIT(11)
+/*0x07388*/	u64	dmaif_dmadbl_pending;
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_WRDMA_WR	vxge_mBIT(0)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_WRDMA_RD	vxge_mBIT(1)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_RTDMA_WR	vxge_mBIT(2)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_RTDMA_RD	vxge_mBIT(3)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_MSG_WR	vxge_mBIT(4)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_STATS_WR	vxge_mBIT(5)
+#define	VXGE_HW_DMAIF_DMADBL_PENDING_DBLGEN_IN_PROG(val) \
+							vxge_vBIT(val, 13, 51)
+/*0x07390*/	u64	wrcrdtarb_status0_vplane[17];
+#define	VXGE_HW_WRCRDTARB_STATUS0_VPLANE_WRCRDTARB_ABS_AVAIL_P_H(val) \
+							vxge_vBIT(val, 0, 8)
+/*0x07418*/	u64	wrcrdtarb_status1_vplane[17];
+#define	VXGE_HW_WRCRDTARB_STATUS1_VPLANE_WRCRDTARB_ABS_AVAIL_P_D(val) \
+							vxge_vBIT(val, 4, 12)
+	u8	unused07500[0x07500-0x074a0];
+
+/*0x07500*/	u64	mrpcim_general_cfg1;
+#define	VXGE_HW_MRPCIM_GENERAL_CFG1_CLEAR_SERR	vxge_mBIT(7)
+/*0x07508*/	u64	mrpcim_general_cfg2;
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_WR_TD	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_RD_TD	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_CPL_TD	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_INI_TIMEOUT_EN_MWR	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_INI_TIMEOUT_EN_MRD	vxge_mBIT(19)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_IGNORE_VPATH_RST_FOR_MSIX	vxge_mBIT(23)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_FLASH_READ_MSB	vxge_mBIT(27)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_DIS_HOST_PIPELINE_WR	vxge_mBIT(31)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_MRPCIM_STATS_ENABLE	vxge_mBIT(43)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_MRPCIM_STATS_MAP_TO_VPATH(val) \
+							vxge_vBIT(val, 47, 5)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_EN_BLOCK_MSIX_DUE_TO_SERR	vxge_mBIT(55)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_FORCE_SENDING_INTA	vxge_mBIT(59)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG2_DIS_SWIF_PROT_ON_RDS	vxge_mBIT(63)
+/*0x07510*/	u64	mrpcim_general_cfg3;
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_PROTECTION_CA_OR_UNSUPN	vxge_mBIT(0)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_ILLEGAL_RD_CA_OR_UNSUPN	vxge_mBIT(3)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_RD_BYTE_SWAPEN	vxge_mBIT(7)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_RD_BIT_FLIPEN	vxge_mBIT(11)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_WR_BYTE_SWAPEN	vxge_mBIT(15)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_WR_BIT_FLIPEN	vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_MR_MAX_MVFS(val) vxge_vBIT(val, 20, 16)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_MR_MVF_TBL_SIZE(val) \
+							vxge_vBIT(val, 36, 16)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_PF0_SW_RESET_EN	vxge_mBIT(55)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_REG_MODIFIED_CFG(val) vxge_vBIT(val, 56, 2)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_CPL_ECC_ENABLE_N	vxge_mBIT(59)
+#define	VXGE_HW_MRPCIM_GENERAL_CFG3_BYPASS_DAISY_CHAIN	vxge_mBIT(63)
+/*0x07518*/	u64	mrpcim_stats_start_host_addr;
+#define	VXGE_HW_MRPCIM_STATS_START_HOST_ADDR_MRPCIM_STATS_START_HOST_ADDR(val)\
+							vxge_vBIT(val, 0, 57)
+
+	u8	unused07950[0x07950-0x07520];
+
+/*0x07950*/	u64	rdcrdtarb_cfg0;
+#define VXGE_HW_RDCRDTARB_CFG0_RDA_MAX_OUTSTANDING_RDS(val) \
+						vxge_vBIT(val, 18, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_PDA_MAX_OUTSTANDING_RDS(val) \
+						vxge_vBIT(val, 26, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_DBLGEN_MAX_OUTSTANDING_RDS(val) \
+						vxge_vBIT(val, 34, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_WAIT_CNT(val) vxge_vBIT(val, 48, 4)
+#define VXGE_HW_RDCRDTARB_CFG0_MAX_OUTSTANDING_RDS(val) vxge_vBIT(val, 54, 6)
+#define	VXGE_HW_RDCRDTARB_CFG0_EN_XON	vxge_mBIT(63)
+	u8	unused07be8[0x07be8-0x07958];
+
+/*0x07be8*/	u64	bf_sw_reset;
+#define VXGE_HW_BF_SW_RESET_BF_SW_RESET(val) vxge_vBIT(val, 0, 8)
+/*0x07bf0*/	u64	sw_reset_status;
+#define	VXGE_HW_SW_RESET_STATUS_RESET_CMPLT	vxge_mBIT(7)
+#define	VXGE_HW_SW_RESET_STATUS_INIT_CMPLT	vxge_mBIT(15)
+	u8	unused07d30[0x07d30-0x07bf8];
+
+/*0x07d30*/	u64	mrpcim_debug_stats0;
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_INI_WR_DROP(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_INI_RD_DROP(val) vxge_vBIT(val, 32, 32)
+/*0x07d38*/	u64	mrpcim_debug_stats1_vplane[17];
+#define	VXGE_HW_MRPCIM_DEBUG_STATS1_VPLANE_WRCRDTARB_PH_CRDT_DEPLETED(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x07dc0*/	u64	mrpcim_debug_stats2_vplane[17];
+#define	VXGE_HW_MRPCIM_DEBUG_STATS2_VPLANE_WRCRDTARB_PD_CRDT_DEPLETED(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x07e48*/	u64	mrpcim_debug_stats3_vplane[17];
+#define	VXGE_HW_MRPCIM_DEBUG_STATS3_VPLANE_RDCRDTARB_NPH_CRDT_DEPLETED(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x07ed0*/	u64	mrpcim_debug_stats4;
+#define VXGE_HW_MRPCIM_DEBUG_STATS4_INI_WR_VPIN_DROP(val) vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_MRPCIM_DEBUG_STATS4_INI_RD_VPIN_DROP(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x07ed8*/	u64	genstats_count01;
+#define VXGE_HW_GENSTATS_COUNT01_GENSTATS_COUNT1(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT01_GENSTATS_COUNT0(val) vxge_vBIT(val, 32, 32)
+/*0x07ee0*/	u64	genstats_count23;
+#define VXGE_HW_GENSTATS_COUNT23_GENSTATS_COUNT3(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT23_GENSTATS_COUNT2(val) vxge_vBIT(val, 32, 32)
+/*0x07ee8*/	u64	genstats_count4;
+#define VXGE_HW_GENSTATS_COUNT4_GENSTATS_COUNT4(val) vxge_vBIT(val, 32, 32)
+/*0x07ef0*/	u64	genstats_count5;
+#define VXGE_HW_GENSTATS_COUNT5_GENSTATS_COUNT5(val) vxge_vBIT(val, 32, 32)
+
+	u8	unused07f08[0x07f08-0x07ef8];
+
+/*0x07f08*/	u64	genstats_cfg[6];
+#define VXGE_HW_GENSTATS_CFG_DTYPE_SEL(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_GENSTATS_CFG_CLIENT_NO_SEL(val) vxge_vBIT(val, 9, 3)
+#define VXGE_HW_GENSTATS_CFG_WR_RD_CPL_SEL(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_GENSTATS_CFG_VPATH_SEL(val) vxge_vBIT(val, 31, 17)
+/*0x07f38*/	u64	genstat_64bit_cfg;
+#define	VXGE_HW_GENSTAT_64BIT_CFG_EN_FOR_GENSTATS0	vxge_mBIT(3)
+#define	VXGE_HW_GENSTAT_64BIT_CFG_EN_FOR_GENSTATS2	vxge_mBIT(7)
+	u8	unused08000[0x08000-0x07f40];
+/*0x08000*/	u64	gcmg3_int_status;
+#define	VXGE_HW_GCMG3_INT_STATUS_GSTC_ERR0_GSTC0_INT	vxge_mBIT(0)
+#define	VXGE_HW_GCMG3_INT_STATUS_GSTC_ERR1_GSTC1_INT	vxge_mBIT(1)
+#define	VXGE_HW_GCMG3_INT_STATUS_GH2L_ERR0_GH2L0_INT	vxge_mBIT(2)
+#define	VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR_GH2L1_INT	vxge_mBIT(3)
+#define	VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR2_GH2L2_INT	vxge_mBIT(4)
+#define	VXGE_HW_GCMG3_INT_STATUS_GH2L_SMERR0_GH2L3_INT	vxge_mBIT(5)
+#define	VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR3_GH2L4_INT	vxge_mBIT(6)
+/*0x08008*/	u64	gcmg3_int_mask;
+	u8	unused09000[0x09000-0x8010];
+
+/*0x09000*/	u64	g3ifcmd_fb_int_status;
+#define	VXGE_HW_G3IFCMD_FB_INT_STATUS_ERR_G3IF_INT	vxge_mBIT(0)
+/*0x09008*/	u64	g3ifcmd_fb_int_mask;
+/*0x09010*/	u64	g3ifcmd_fb_err_reg;
+#define	VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_CK_DLL_LOCK	vxge_mBIT(6)
+#define	VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_SM_ERR	vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+						vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_IOCAL_FAULT	vxge_mBIT(55)
+/*0x09018*/	u64	g3ifcmd_fb_err_mask;
+/*0x09020*/	u64	g3ifcmd_fb_err_alarm;
+
+	u8	unused09400[0x09400-0x09028];
+
+/*0x09400*/	u64	g3ifcmd_cmu_int_status;
+#define	VXGE_HW_G3IFCMD_CMU_INT_STATUS_ERR_G3IF_INT	vxge_mBIT(0)
+/*0x09408*/	u64	g3ifcmd_cmu_int_mask;
+/*0x09410*/	u64	g3ifcmd_cmu_err_reg;
+#define	VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_CK_DLL_LOCK	vxge_mBIT(6)
+#define	VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_SM_ERR	vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+							vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_IOCAL_FAULT	vxge_mBIT(55)
+/*0x09418*/	u64	g3ifcmd_cmu_err_mask;
+/*0x09420*/	u64	g3ifcmd_cmu_err_alarm;
+
+	u8	unused09800[0x09800-0x09428];
+
+/*0x09800*/	u64	g3ifcmd_cml_int_status;
+#define	VXGE_HW_G3IFCMD_CML_INT_STATUS_ERR_G3IF_INT	vxge_mBIT(0)
+/*0x09808*/	u64	g3ifcmd_cml_int_mask;
+/*0x09810*/	u64	g3ifcmd_cml_err_reg;
+#define	VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_CK_DLL_LOCK	vxge_mBIT(6)
+#define	VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_SM_ERR	vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+						vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_IOCAL_FAULT	vxge_mBIT(55)
+/*0x09818*/	u64	g3ifcmd_cml_err_mask;
+/*0x09820*/	u64	g3ifcmd_cml_err_alarm;
+	u8	unused09b00[0x09b00-0x09828];
+
+/*0x09b00*/	u64	vpath_to_vplane_map[17];
+#define VXGE_HW_VPATH_TO_VPLANE_MAP_VPATH_TO_VPLANE_MAP(val) \
+							vxge_vBIT(val, 3, 5)
+	u8	unused09c30[0x09c30-0x09b88];
+
+/*0x09c30*/	u64	xgxs_cfg_port[2];
+#define VXGE_HW_XGXS_CFG_PORT_SIG_DETECT_FORCE_LOS(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_XGXS_CFG_PORT_SIG_DETECT_FORCE_VALID(val) vxge_vBIT(val, 20, 4)
+#define	VXGE_HW_XGXS_CFG_PORT_SEL_INFO_0	vxge_mBIT(27)
+#define VXGE_HW_XGXS_CFG_PORT_SEL_INFO_1(val) vxge_vBIT(val, 29, 3)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE0_SKEW(val) vxge_vBIT(val, 32, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE1_SKEW(val) vxge_vBIT(val, 36, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE2_SKEW(val) vxge_vBIT(val, 40, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE3_SKEW(val) vxge_vBIT(val, 44, 4)
+/*0x09c40*/	u64	xgxs_rxber_cfg_port[2];
+#define VXGE_HW_XGXS_RXBER_CFG_PORT_INTERVAL_DUR(val) vxge_vBIT(val, 0, 4)
+#define	VXGE_HW_XGXS_RXBER_CFG_PORT_RXGXS_INTERVAL_CNT(val) \
+							vxge_vBIT(val, 16, 48)
+/*0x09c50*/	u64	xgxs_rxber_status_port[2];
+#define	VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_A_ERR_CNT(val)	\
+							vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_B_ERR_CNT(val)	\
+							vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_C_ERR_CNT(val)	\
+							vxge_vBIT(val, 32, 16)
+#define	VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_D_ERR_CNT(val)	\
+							vxge_vBIT(val, 48, 16)
+/*0x09c60*/	u64	xgxs_status_port[2];
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_TX_ACTIVITY(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_RX_ACTIVITY(val) vxge_vBIT(val, 4, 4)
+#define	VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_CTC_FIFO_ERR	BIT(11)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_BYTE_SYNC_LOST(val) \
+							vxge_vBIT(val, 12, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_CTC_ERR(val) vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_ALIGNMENT_ERR	vxge_mBIT(23)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_DEC_ERR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_SKIP_INS_REQ(val) \
+							vxge_vBIT(val, 32, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_SKIP_DEL_REQ(val) \
+							vxge_vBIT(val, 36, 4)
+/*0x09c70*/	u64	xgxs_pma_reset_port[2];
+#define VXGE_HW_XGXS_PMA_RESET_PORT_SERDES_RESET(val) vxge_vBIT(val, 0, 8)
+	u8	unused09c90[0x09c90-0x09c80];
+
+/*0x09c90*/	u64	xgxs_static_cfg_port[2];
+#define	VXGE_HW_XGXS_STATIC_CFG_PORT_FW_CTRL_SERDES	vxge_mBIT(3)
+	u8	unused09d40[0x09d40-0x09ca0];
+
+/*0x09d40*/	u64	xgxs_info_port[2];
+#define VXGE_HW_XGXS_INFO_PORT_XMACJ_INFO_0(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_XGXS_INFO_PORT_XMACJ_INFO_1(val) vxge_vBIT(val, 32, 32)
+/*0x09d50*/	u64	ratemgmt_cfg_port[2];
+#define VXGE_HW_RATEMGMT_CFG_PORT_MODE(val) vxge_vBIT(val, 2, 2)
+#define	VXGE_HW_RATEMGMT_CFG_PORT_RATE	vxge_mBIT(7)
+#define	VXGE_HW_RATEMGMT_CFG_PORT_FIXED_USE_FSM	vxge_mBIT(11)
+#define	VXGE_HW_RATEMGMT_CFG_PORT_ANTP_USE_FSM	vxge_mBIT(15)
+#define	VXGE_HW_RATEMGMT_CFG_PORT_ANBE_USE_FSM	vxge_mBIT(19)
+/*0x09d60*/	u64	ratemgmt_status_port[2];
+#define	VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_COMPLETE	vxge_mBIT(3)
+#define	VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_RATE	vxge_mBIT(7)
+#define	VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_MAC_MATCHES_PHY	vxge_mBIT(11)
+	u8	unused09d80[0x09d80-0x09d70];
+
+/*0x09d80*/	u64	ratemgmt_fixed_cfg_port[2];
+#define	VXGE_HW_RATEMGMT_FIXED_CFG_PORT_RESTART	vxge_mBIT(7)
+/*0x09d90*/	u64	ratemgmt_antp_cfg_port[2];
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_RESTART	vxge_mBIT(7)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_USE_PREAMBLE_EXT_PHY	vxge_mBIT(11)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_USE_ACT_SEL	vxge_mBIT(15)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_RETRY_PHY_QUERY(val) \
+							vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_WAIT_MDIO_RESPONSE(val) \
+							vxge_vBIT(val, 20, 4)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_LDOWN_REAUTO_RESPONSE(val) \
+							vxge_vBIT(val, 24, 4)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_ADVERTISE_10G	vxge_mBIT(31)
+#define	VXGE_HW_RATEMGMT_ANTP_CFG_PORT_ADVERTISE_1G	vxge_mBIT(35)
+/*0x09da0*/	u64	ratemgmt_anbe_cfg_port[2];
+#define	VXGE_HW_RATEMGMT_ANBE_CFG_PORT_RESTART	vxge_mBIT(7)
+#define	VXGE_HW_RATEMGMT_ANBE_CFG_PORT_PARALLEL_DETECT_10G_KX4_ENABLE \
+								vxge_mBIT(11)
+#define	VXGE_HW_RATEMGMT_ANBE_CFG_PORT_PARALLEL_DETECT_1G_KX_ENABLE \
+								vxge_mBIT(15)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_SYNC_10G_KX4(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_SYNC_1G_KX(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_DME_EXCHANGE(val) vxge_vBIT(val, 24, 4)
+#define	VXGE_HW_RATEMGMT_ANBE_CFG_PORT_ADVERTISE_10G_KX4	vxge_mBIT(31)
+#define	VXGE_HW_RATEMGMT_ANBE_CFG_PORT_ADVERTISE_1G_KX	vxge_mBIT(35)
+/*0x09db0*/	u64	anbe_cfg_port[2];
+#define VXGE_HW_ANBE_CFG_PORT_RESET_CFG_REGS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_ANBE_CFG_PORT_ALIGN_10G_KX4_OVERRIDE(val) vxge_vBIT(val, 10, 2)
+#define VXGE_HW_ANBE_CFG_PORT_SYNC_1G_KX_OVERRIDE(val) vxge_vBIT(val, 14, 2)
+/*0x09dc0*/	u64	anbe_mgr_ctrl_port[2];
+#define	VXGE_HW_ANBE_MGR_CTRL_PORT_WE	vxge_mBIT(3)
+#define	VXGE_HW_ANBE_MGR_CTRL_PORT_STROBE	vxge_mBIT(7)
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_ADDR(val) vxge_vBIT(val, 15, 9)
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_DATA(val) vxge_vBIT(val, 32, 32)
+	u8	unused09de0[0x09de0-0x09dd0];
+
+/*0x09de0*/	u64	anbe_fw_mstr_port[2];
+#define	VXGE_HW_ANBE_FW_MSTR_PORT_CONNECT_BEAN_TO_SERDES	vxge_mBIT(3)
+#define	VXGE_HW_ANBE_FW_MSTR_PORT_TX_ZEROES_TO_SERDES	vxge_mBIT(7)
+/*0x09df0*/	u64	anbe_hwfsm_gen_status_port[2];
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G_KX4_USING_PD \
+							vxge_mBIT(3)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G_KX4_USING_DME \
+							vxge_mBIT(7)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G_KX_USING_PD \
+							vxge_mBIT(11)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G_KX_USING_DME \
+							vxge_mBIT(15)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_ANBEFSM_STATE(val)	\
+							vxge_vBIT(val, 18, 6)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_NEXT_PAGE_RECEIVED \
+							vxge_mBIT(27)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_BASE_PAGE_RECEIVED \
+							vxge_mBIT(35)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_AUTONEG_COMPLETE \
+							vxge_mBIT(39)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NP_BEFORE_BP \
+							vxge_mBIT(43)
+#define	\
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_AN_COMPLETE_BEFORE_BP \
+							vxge_mBIT(47)
+#define	\
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_AN_COMPLETE_BEFORE_NP \
+vxge_mBIT(51)
+#define	\
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_MODE_WHEN_AN_COMPLETE \
+							vxge_mBIT(55)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_COUNT_BP(val) \
+							vxge_vBIT(val, 56, 4)
+#define	VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_COUNT_NP(val) \
+							vxge_vBIT(val, 60, 4)
+/*0x09e00*/	u64	anbe_hwfsm_bp_status_port[2];
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_FEC_ENABLE \
+							vxge_mBIT(32)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_FEC_ABILITY \
+							vxge_mBIT(33)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_10G_KR_CAPABLE \
+							vxge_mBIT(40)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_10G_KX4_CAPABLE \
+							vxge_mBIT(41)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_1G_KX_CAPABLE \
+							vxge_mBIT(42)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_TX_NONCE(val)	\
+							vxge_vBIT(val, 43, 5)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_NP	vxge_mBIT(48)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ACK	vxge_mBIT(49)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_REMOTE_FAULT \
+							vxge_mBIT(50)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ASM_DIR	vxge_mBIT(51)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_PAUSE	vxge_mBIT(53)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ECHOED_NONCE(val) \
+							vxge_vBIT(val, 54, 5)
+#define	VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_SELECTOR_FIELD(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x09e10*/	u64	anbe_hwfsm_np_status_port[2];
+#define	VXGE_HW_ANBE_HWFSM_NP_STATUS_PORT_RATEMGMT_NP_BITS_47_TO_32(val) \
+							vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_ANBE_HWFSM_NP_STATUS_PORT_RATEMGMT_NP_BITS_31_TO_0(val) \
+							vxge_vBIT(val, 32, 32)
+	u8	unused09e30[0x09e30-0x09e20];
+
+/*0x09e30*/	u64	antp_gen_cfg_port[2];
+/*0x09e40*/	u64	antp_hwfsm_gen_status_port[2];
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G	vxge_mBIT(3)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G	vxge_mBIT(7)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_ANTPFSM_STATE(val)	\
+							vxge_vBIT(val, 10, 6)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_AUTONEG_COMPLETE \
+								vxge_mBIT(23)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NO_LP_XNP \
+							vxge_mBIT(27)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_GOT_LP_XNP	vxge_mBIT(31)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_MESSAGE_CODE \
+							vxge_mBIT(35)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NO_HCD \
+							vxge_mBIT(43)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_FOUND_HCD	vxge_mBIT(47)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_INVALID_RATE \
+							vxge_mBIT(51)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_VALID_RATE	vxge_mBIT(55)
+#define	VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_PERSISTENT_LDOWN \
+							vxge_mBIT(59)
+/*0x09e50*/	u64	antp_hwfsm_bp_status_port[2];
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_NP	vxge_mBIT(0)
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ACK	vxge_mBIT(1)
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_RF	vxge_mBIT(2)
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_XNP	vxge_mBIT(3)
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ABILITY_FIELD(val) \
+							vxge_vBIT(val, 4, 7)
+#define	VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_SELECTOR_FIELD(val) \
+							vxge_vBIT(val, 11, 5)
+/*0x09e60*/	u64	antp_hwfsm_xnp_status_port[2];
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_NP	vxge_mBIT(0)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_ACK	vxge_mBIT(1)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_MP	vxge_mBIT(2)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_ACK2	vxge_mBIT(3)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_TOGGLE	vxge_mBIT(4)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_MESSAGE_CODE(val) \
+							vxge_vBIT(val, 5, 11)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_UNF_CODE_FIELD1(val) \
+							vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_UNF_CODE_FIELD2(val) \
+							vxge_vBIT(val, 32, 16)
+/*0x09e70*/	u64	mdio_mgr_access_port[2];
+#define	VXGE_HW_MDIO_MGR_ACCESS_PORT_STROBE_ONE	BIT(3)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_OP_TYPE(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_DEVAD(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_ADDR(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_DATA(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_ST_PATTERN(val) vxge_vBIT(val, 49, 2)
+#define	VXGE_HW_MDIO_MGR_ACCESS_PORT_PREAMBLE	vxge_mBIT(51)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_PRTAD(val) vxge_vBIT(val, 55, 5)
+#define	VXGE_HW_MDIO_MGR_ACCESS_PORT_STROBE_TWO	vxge_mBIT(63)
+	u8	unused0a200[0x0a200-0x09e80];
+/*0x0a200*/	u64	xmac_vsport_choices_vh[17];
+#define VXGE_HW_XMAC_VSPORT_CHOICES_VH_VSPORT_VECTOR(val) vxge_vBIT(val, 0, 17)
+	u8	unused0a400[0x0a400-0x0a288];
+
+/*0x0a400*/	u64	rx_thresh_cfg_vp[17];
+#define VXGE_HW_RX_THRESH_CFG_VP_PAUSE_LOW_THR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_PAUSE_HIGH_THR(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_0(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_1(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_2(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_3(val) vxge_vBIT(val, 40, 8)
+	u8	unused0ac90[0x0ac90-0x0a488];
+} __packed;
+
+/*VXGE_HW_SRPCIM_REGS_H*/
+struct vxge_hw_srpcim_reg {
+
+/*0x00000*/	u64	tim_mr2sr_resource_assignment_vh;
+#define	VXGE_HW_TIM_MR2SR_RESOURCE_ASSIGNMENT_VH_BMAP_ROOT(val) \
+							vxge_vBIT(val, 0, 32)
+	u8	unused00100[0x00100-0x00008];
+
+/*0x00100*/	u64	srpcim_pcipif_int_status;
+#define	VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_MRPCIM_MSG_MRPCIM_MSG_INT	BIT(3)
+#define	VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_VPATH_MSG_VPATH_MSG_INT	BIT(7)
+#define	VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_SRPCIM_SPARE_R1_SRPCIM_SPARE_R1_INT \
+									BIT(11)
+/*0x00108*/	u64	srpcim_pcipif_int_mask;
+/*0x00110*/	u64	mrpcim_msg_reg;
+#define	VXGE_HW_MRPCIM_MSG_REG_SWIF_MRPCIM_TO_SRPCIM_RMSG_INT	BIT(3)
+/*0x00118*/	u64	mrpcim_msg_mask;
+/*0x00120*/	u64	mrpcim_msg_alarm;
+/*0x00128*/	u64	vpath_msg_reg;
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH0_TO_SRPCIM_RMSG_INT	BIT(0)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH1_TO_SRPCIM_RMSG_INT	BIT(1)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH2_TO_SRPCIM_RMSG_INT	BIT(2)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH3_TO_SRPCIM_RMSG_INT	BIT(3)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH4_TO_SRPCIM_RMSG_INT	BIT(4)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH5_TO_SRPCIM_RMSG_INT	BIT(5)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH6_TO_SRPCIM_RMSG_INT	BIT(6)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH7_TO_SRPCIM_RMSG_INT	BIT(7)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH8_TO_SRPCIM_RMSG_INT	BIT(8)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH9_TO_SRPCIM_RMSG_INT	BIT(9)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH10_TO_SRPCIM_RMSG_INT	BIT(10)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH11_TO_SRPCIM_RMSG_INT	BIT(11)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH12_TO_SRPCIM_RMSG_INT	BIT(12)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH13_TO_SRPCIM_RMSG_INT	BIT(13)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH14_TO_SRPCIM_RMSG_INT	BIT(14)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH15_TO_SRPCIM_RMSG_INT	BIT(15)
+#define	VXGE_HW_VPATH_MSG_REG_SWIF_VPATH16_TO_SRPCIM_RMSG_INT	BIT(16)
+/*0x00130*/	u64	vpath_msg_mask;
+/*0x00138*/	u64	vpath_msg_alarm;
+	u8	unused00160[0x00160-0x00140];
+
+/*0x00160*/	u64	srpcim_to_mrpcim_wmsg;
+#define	VXGE_HW_SRPCIM_TO_MRPCIM_WMSG_SRPCIM_TO_MRPCIM_WMSG(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x00168*/	u64	srpcim_to_mrpcim_wmsg_trig;
+#define	VXGE_HW_SRPCIM_TO_MRPCIM_WMSG_TRIG_SRPCIM_TO_MRPCIM_WMSG_TRIG	BIT(0)
+/*0x00170*/	u64	mrpcim_to_srpcim_rmsg;
+#define	VXGE_HW_MRPCIM_TO_SRPCIM_RMSG_SWIF_MRPCIM_TO_SRPCIM_RMSG(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x00178*/	u64	vpath_to_srpcim_rmsg_sel;
+#define	VXGE_HW_VPATH_TO_SRPCIM_RMSG_SEL_VPATH_TO_SRPCIM_RMSG_SEL(val) \
+							vxge_vBIT(val, 0, 5)
+/*0x00180*/	u64	vpath_to_srpcim_rmsg;
+#define	VXGE_HW_VPATH_TO_SRPCIM_RMSG_SWIF_VPATH_TO_SRPCIM_RMSG(val) \
+							vxge_vBIT(val, 0, 64)
+	u8	unused00200[0x00200-0x00188];
+
+/*0x00200*/	u64	srpcim_general_int_status;
+#define	VXGE_HW_SRPCIM_GENERAL_INT_STATUS_PIC_INT	BIT(0)
+#define	VXGE_HW_SRPCIM_GENERAL_INT_STATUS_PCI_INT	BIT(3)
+#define	VXGE_HW_SRPCIM_GENERAL_INT_STATUS_XMAC_INT	BIT(7)
+	u8	unused00210[0x00210-0x00208];
+
+/*0x00210*/	u64	srpcim_general_int_mask;
+#define	VXGE_HW_SRPCIM_GENERAL_INT_MASK_PIC_INT	BIT(0)
+#define	VXGE_HW_SRPCIM_GENERAL_INT_MASK_PCI_INT	BIT(3)
+#define	VXGE_HW_SRPCIM_GENERAL_INT_MASK_XMAC_INT	BIT(7)
+	u8	unused00220[0x00220-0x00218];
+
+/*0x00220*/	u64	srpcim_ppif_int_status;
+
+/*0x00228*/	u64	srpcim_ppif_int_mask;
+/*0x00230*/	u64	srpcim_gen_errors_reg;
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_STATUS_ERR	BIT(3)
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_UNCOR_ERR	BIT(7)
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_COR_ERR	BIT(11)
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_INTCTRL_SCHED_INT	BIT(15)
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_INI_SERR_DET	BIT(19)
+#define	VXGE_HW_SRPCIM_GEN_ERRORS_REG_TGT_PF_ILLEGAL_ACCESS	BIT(23)
+/*0x00238*/	u64	srpcim_gen_errors_mask;
+/*0x00240*/	u64	srpcim_gen_errors_alarm;
+/*0x00248*/	u64	mrpcim_to_srpcim_alarm_reg;
+#define	VXGE_HW_MRPCIM_TO_SRPCIM_ALARM_REG_PPIF_MRPCIM_TO_SRPCIM_ALARM	BIT(3)
+/*0x00250*/	u64	mrpcim_to_srpcim_alarm_mask;
+/*0x00258*/	u64	mrpcim_to_srpcim_alarm_alarm;
+/*0x00260*/	u64	vpath_to_srpcim_alarm_reg;
+
+/*0x00268*/	u64	vpath_to_srpcim_alarm_mask;
+/*0x00270*/	u64	vpath_to_srpcim_alarm_alarm;
+	u8	unused00280[0x00280-0x00278];
+
+/*0x00280*/	u64	pf_sw_reset;
+#define VXGE_HW_PF_SW_RESET_PF_SW_RESET(val) vxge_vBIT(val, 0, 8)
+/*0x00288*/	u64	srpcim_general_cfg1;
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_BOOT_BYTE_SWAPEN	BIT(19)
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_BOOT_BIT_FLIPEN	BIT(23)
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_ADDR_SWAPEN	BIT(27)
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_ADDR_FLIPEN	BIT(31)
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_DATA_SWAPEN	BIT(35)
+#define	VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_DATA_FLIPEN	BIT(39)
+/*0x00290*/	u64	srpcim_interrupt_cfg1;
+#define VXGE_HW_SRPCIM_INTERRUPT_CFG1_ALARM_MAP_TO_MSG(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_SRPCIM_INTERRUPT_CFG1_TRAFFIC_CLASS(val) vxge_vBIT(val, 9, 3)
+	u8	unused002a8[0x002a8-0x00298];
+
+/*0x002a8*/	u64	srpcim_clear_msix_mask;
+#define	VXGE_HW_SRPCIM_CLEAR_MSIX_MASK_SRPCIM_CLEAR_MSIX_MASK	BIT(0)
+/*0x002b0*/	u64	srpcim_set_msix_mask;
+#define	VXGE_HW_SRPCIM_SET_MSIX_MASK_SRPCIM_SET_MSIX_MASK	BIT(0)
+/*0x002b8*/	u64	srpcim_clr_msix_one_shot;
+#define	VXGE_HW_SRPCIM_CLR_MSIX_ONE_SHOT_SRPCIM_CLR_MSIX_ONE_SHOT	BIT(0)
+/*0x002c0*/	u64	srpcim_rst_in_prog;
+#define	VXGE_HW_SRPCIM_RST_IN_PROG_SRPCIM_RST_IN_PROG	BIT(7)
+/*0x002c8*/	u64	srpcim_reg_modified;
+#define	VXGE_HW_SRPCIM_REG_MODIFIED_SRPCIM_REG_MODIFIED	BIT(7)
+/*0x002d0*/	u64	tgt_pf_illegal_access;
+#define VXGE_HW_TGT_PF_ILLEGAL_ACCESS_SWIF_REGION(val) vxge_vBIT(val, 1, 7)
+/*0x002d8*/	u64	srpcim_msix_status;
+#define	VXGE_HW_SRPCIM_MSIX_STATUS_INTCTL_SRPCIM_MSIX_MASK	BIT(3)
+#define	VXGE_HW_SRPCIM_MSIX_STATUS_INTCTL_SRPCIM_MSIX_PENDING_VECTOR	BIT(7)
+	u8	unused00880[0x00880-0x002e0];
+
+/*0x00880*/	u64	xgmac_sr_int_status;
+#define	VXGE_HW_XGMAC_SR_INT_STATUS_ASIC_NTWK_SR_ERR_ASIC_NTWK_SR_INT	BIT(3)
+/*0x00888*/	u64	xgmac_sr_int_mask;
+/*0x00890*/	u64	asic_ntwk_sr_err_reg;
+#define	VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_FAULT	BIT(3)
+#define	VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_OK	BIT(7)
+#define	VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_FAULT_OCCURRED \
+									BIT(11)
+#define	VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_OK_OCCURRED	BIT(15)
+/*0x00898*/	u64	asic_ntwk_sr_err_mask;
+/*0x008a0*/	u64	asic_ntwk_sr_err_alarm;
+	u8	unused008c0[0x008c0-0x008a8];
+
+/*0x008c0*/	u64	xmac_vsport_choices_sr_clone;
+#define	VXGE_HW_XMAC_VSPORT_CHOICES_SR_CLONE_VSPORT_VECTOR(val) \
+							vxge_vBIT(val, 0, 17)
+	u8	unused00900[0x00900-0x008c8];
+
+/*0x00900*/	u64	mr_rqa_top_prty_for_vh;
+#define	VXGE_HW_MR_RQA_TOP_PRTY_FOR_VH_RQA_TOP_PRTY_FOR_VH(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00908*/	u64	umq_vh_data_list_empty;
+#define	VXGE_HW_UMQ_VH_DATA_LIST_EMPTY_ROCRC_UMQ_VH_DATA_LIST_EMPTY \
+							BIT(0)
+/*0x00910*/	u64	wde_cfg;
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_MWB_START	BIT(0)
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_MWB_END	BIT(1)
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_QB_START	BIT(2)
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_QB_END	BIT(3)
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_MPSB_START	BIT(4)
+#define	VXGE_HW_WDE_CFG_NS0_FORCE_MPSB_END	BIT(5)
+#define	VXGE_HW_WDE_CFG_NS0_MWB_OPT_EN	BIT(6)
+#define	VXGE_HW_WDE_CFG_NS0_QB_OPT_EN	BIT(7)
+#define	VXGE_HW_WDE_CFG_NS0_MPSB_OPT_EN	BIT(8)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_MWB_START	BIT(9)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_MWB_END	BIT(10)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_QB_START	BIT(11)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_QB_END	BIT(12)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_MPSB_START	BIT(13)
+#define	VXGE_HW_WDE_CFG_NS1_FORCE_MPSB_END	BIT(14)
+#define	VXGE_HW_WDE_CFG_NS1_MWB_OPT_EN	BIT(15)
+#define	VXGE_HW_WDE_CFG_NS1_QB_OPT_EN	BIT(16)
+#define	VXGE_HW_WDE_CFG_NS1_MPSB_OPT_EN	BIT(17)
+#define	VXGE_HW_WDE_CFG_DISABLE_QPAD_FOR_UNALIGNED_ADDR	BIT(19)
+#define VXGE_HW_WDE_CFG_ALIGNMENT_PREFERENCE(val) vxge_vBIT(val, 30, 2)
+#define VXGE_HW_WDE_CFG_MEM_WORD_SIZE(val) vxge_vBIT(val, 46, 2)
+
+} __packed;
+
+/*VXGE_HW_VPMGMT_REGS_H*/
+struct vxge_hw_vpmgmt_reg {
+
+	u8	unused00040[0x00040-0x00000];
+
+/*0x00040*/	u64	vpath_to_func_map_cfg1;
+#define	VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_VPATH_TO_FUNC_MAP_CFG1(val) \
+							vxge_vBIT(val, 3, 5)
+/*0x00048*/	u64	vpath_is_first;
+#define	VXGE_HW_VPATH_IS_FIRST_VPATH_IS_FIRST	vxge_mBIT(3)
+/*0x00050*/	u64	srpcim_to_vpath_wmsg;
+#define	VXGE_HW_SRPCIM_TO_VPATH_WMSG_SRPCIM_TO_VPATH_WMSG(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x00058*/	u64	srpcim_to_vpath_wmsg_trig;
+#define	VXGE_HW_SRPCIM_TO_VPATH_WMSG_TRIG_SRPCIM_TO_VPATH_WMSG_TRIG \
+								vxge_mBIT(0)
+	u8	unused00100[0x00100-0x00060];
+
+/*0x00100*/	u64	tim_vpath_assignment;
+#define VXGE_HW_TIM_VPATH_ASSIGNMENT_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+	u8	unused00140[0x00140-0x00108];
+
+/*0x00140*/	u64	rqa_top_prty_for_vp;
+#define VXGE_HW_RQA_TOP_PRTY_FOR_VP_RQA_TOP_PRTY_FOR_VP(val) \
+							vxge_vBIT(val, 59, 5)
+	u8	unused001c0[0x001c0-0x00148];
+
+/*0x001c0*/	u64	rxmac_rx_pa_cfg0_vpmgmt_clone;
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_IGNORE_FRAME_ERR	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SUPPORT_SNAP_AB_N	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SEARCH_FOR_HAO	vxge_mBIT(18)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SUPPORT_MOBILE_IPV6_HDRS \
+								vxge_mBIT(19)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_IPV6_STOP_SEARCHING \
+								vxge_mBIT(23)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_NO_PS_IF_UNKNOWN	vxge_mBIT(27)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SEARCH_FOR_ETYPE	vxge_mBIT(35)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_L3_CSUM_ERR \
+								vxge_mBIT(39)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_L3_CSUM_ERR \
+								vxge_mBIT(43)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_L4_CSUM_ERR \
+								vxge_mBIT(47)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_L4_CSUM_ERR \
+								vxge_mBIT(51)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_RPA_ERR \
+								vxge_mBIT(55)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_RPA_ERR \
+								vxge_mBIT(59)
+#define	VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_JUMBO_SNAP_EN	vxge_mBIT(63)
+/*0x001c8*/	u64	rts_mgr_cfg0_vpmgmt_clone;
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_RTS_DP_SP_PRIORITY	vxge_mBIT(3)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_FLEX_L4PRTCL_VALUE(val) \
+							vxge_vBIT(val, 24, 8)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_ICMP_TRASH	vxge_mBIT(35)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_TCPSYN_TRASH	vxge_mBIT(39)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_ZL4PYLD_TRASH	vxge_mBIT(43)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_TCP_TRASH	vxge_mBIT(47)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_UDP_TRASH	vxge_mBIT(51)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_FLEX_TRASH	vxge_mBIT(55)
+#define	VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_IPFRAG_TRASH	vxge_mBIT(59)
+/*0x001d0*/	u64	rts_mgr_criteria_priority_vpmgmt_clone;
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ETYPE(val) \
+							vxge_vBIT(val, 5, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ICMP_TCPSYN(val) \
+							vxge_vBIT(val, 9, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_L4PN(val) \
+							vxge_vBIT(val, 13, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_RANGE_L4PN(val) \
+							vxge_vBIT(val, 17, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_RTH_IT(val) \
+							vxge_vBIT(val, 21, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_DS(val) \
+							vxge_vBIT(val, 25, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_QOS(val) \
+							vxge_vBIT(val, 29, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ZL4PYLD(val) \
+							vxge_vBIT(val, 33, 3)
+#define	VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_L4PRTCL(val) \
+							vxge_vBIT(val, 37, 3)
+/*0x001d8*/	u64	rxmac_cfg0_port_vpmgmt_clone[3];
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_RMAC_EN	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_DISCARD_PFRM	vxge_mBIT(11)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_FCS_ERR	vxge_mBIT(15)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_LONG_ERR	vxge_mBIT(19)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_USIZED_ERR	vxge_mBIT(23)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_LEN_MISMATCH \
+								vxge_mBIT(27)
+#define	VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_MAX_PYLD_LEN(val) \
+							vxge_vBIT(val, 50, 14)
+/*0x001f0*/	u64	rxmac_pause_cfg_port_vpmgmt_clone[3];
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN	vxge_mBIT(3)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN	vxge_mBIT(7)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_ACCEL_SEND(val) \
+							vxge_vBIT(val, 9, 3)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_DUAL_THR	vxge_mBIT(15)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_HIGH_PTIME(val) \
+							vxge_vBIT(val, 20, 16)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_IGNORE_PF_FCS_ERR \
+								vxge_mBIT(39)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_IGNORE_PF_LEN_ERR \
+								vxge_mBIT(43)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_LIMITER_EN	vxge_mBIT(47)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_MAX_LIMIT(val) \
+							vxge_vBIT(val, 48, 8)
+#define	VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_PERMIT_RATEMGMT_CTRL \
+							vxge_mBIT(59)
+	u8	unused00240[0x00240-0x00208];
+
+/*0x00240*/	u64	xmac_vsport_choices_vp;
+#define VXGE_HW_XMAC_VSPORT_CHOICES_VP_VSPORT_VECTOR(val) vxge_vBIT(val, 0, 17)
+	u8	unused00260[0x00260-0x00248];
+
+/*0x00260*/	u64	xgmac_gen_status_vpmgmt_clone;
+#define	VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK	vxge_mBIT(3)
+#define	VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_DATA_RATE \
+								vxge_mBIT(11)
+/*0x00268*/	u64	xgmac_status_port_vpmgmt_clone[2];
+#define	VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_RMAC_REMOTE_FAULT \
+								vxge_mBIT(3)
+#define	VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_RMAC_LOCAL_FAULT	vxge_mBIT(7)
+#define	VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_XMACJ_MAC_PHY_LAYER_AVAIL \
+								vxge_mBIT(11)
+#define	VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_XMACJ_PORT_OK	vxge_mBIT(15)
+/*0x00278*/	u64	xmac_gen_cfg_vpmgmt_clone;
+#define	VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_RATEMGMT_MAC_RATE_SEL(val) \
+							vxge_vBIT(val, 2, 2)
+#define	VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_TX_HEAD_DROP_WHEN_FAULT \
+							vxge_mBIT(7)
+#define	VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_FAULT_BEHAVIOUR	vxge_mBIT(27)
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_PERIOD_NTWK_UP(val) \
+							vxge_vBIT(val, 28, 4)
+#define	VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_PERIOD_NTWK_DOWN(val) \
+							vxge_vBIT(val, 32, 4)
+/*0x00280*/	u64	xmac_timestamp_vpmgmt_clone;
+#define	VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_EN	vxge_mBIT(3)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_USE_LINK_ID(val) \
+							vxge_vBIT(val, 6, 2)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_INTERVAL(val) vxge_vBIT(val, 12, 4)
+#define	VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_TIMER_RESTART	vxge_mBIT(19)
+#define	VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_XMACJ_ROLLOVER_CNT(val) \
+							vxge_vBIT(val, 32, 16)
+/*0x00288*/	u64	xmac_stats_gen_cfg_vpmgmt_clone;
+#define	VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_PRTAGGR_CUM_TIMER(val) \
+							vxge_vBIT(val, 4, 4)
+#define	VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_VPATH_CUM_TIMER(val) \
+							vxge_vBIT(val, 8, 4)
+#define	VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_VLAN_HANDLING	vxge_mBIT(15)
+/*0x00290*/	u64	xmac_cfg_port_vpmgmt_clone[3];
+#define	VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_LOOPBACK	vxge_mBIT(3)
+#define	VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_REVERSE_LOOPBACK \
+								vxge_mBIT(7)
+#define	VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_TX_BEHAV	vxge_mBIT(11)
+#define	VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_RX_BEHAV	vxge_mBIT(15)
+	u8	unused002c0[0x002c0-0x002a8];
+
+/*0x002c0*/	u64	txmac_gen_cfg0_vpmgmt_clone;
+#define	VXGE_HW_TXMAC_GEN_CFG0_VPMGMT_CLONE_CHOSEN_TX_PORT	vxge_mBIT(7)
+/*0x002c8*/	u64	txmac_cfg0_port_vpmgmt_clone[3];
+#define	VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_TMAC_EN	vxge_mBIT(3)
+#define	VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_APPEND_PAD	vxge_mBIT(7)
+#define VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_PAD_BYTE(val) vxge_vBIT(val, 8, 8)
+	u8	unused00300[0x00300-0x002e0];
+
+/*0x00300*/	u64	wol_mp_crc;
+#define VXGE_HW_WOL_MP_CRC_CRC(val) vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_WOL_MP_CRC_RC_EN	vxge_mBIT(63)
+/*0x00308*/	u64	wol_mp_mask_a;
+#define VXGE_HW_WOL_MP_MASK_A_MASK(val) vxge_vBIT(val, 0, 64)
+/*0x00310*/	u64	wol_mp_mask_b;
+#define VXGE_HW_WOL_MP_MASK_B_MASK(val) vxge_vBIT(val, 0, 64)
+	u8	unused00360[0x00360-0x00318];
+
+/*0x00360*/	u64	fau_pa_cfg_vpmgmt_clone;
+#define	VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L4_COMP_CSUM	vxge_mBIT(3)
+#define	VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L3_INCL_CF	vxge_mBIT(7)
+#define	VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L3_COMP_CSUM	vxge_mBIT(11)
+/*0x00368*/	u64	rx_datapath_util_vp_clone;
+#define	VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_FAU_RX_UTILIZATION(val) \
+							vxge_vBIT(val, 7, 9)
+#define	VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_RX_UTIL_CFG(val) \
+							vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_FAU_RX_FRAC_UTIL(val) \
+							vxge_vBIT(val, 20, 4)
+#define	VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_RX_PKT_WEIGHT(val) \
+							vxge_vBIT(val, 24, 4)
+	u8	unused00380[0x00380-0x00370];
+
+/*0x00380*/	u64	tx_datapath_util_vp_clone;
+#define	VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TPA_TX_UTILIZATION(val) \
+							vxge_vBIT(val, 7, 9)
+#define	VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TX_UTIL_CFG(val) \
+							vxge_vBIT(val, 16, 4)
+#define	VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TPA_TX_FRAC_UTIL(val) \
+							vxge_vBIT(val, 20, 4)
+#define	VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TX_PKT_WEIGHT(val) \
+							vxge_vBIT(val, 24, 4)
+
+} __packed;
+
+struct vxge_hw_vpath_reg {
+
+	u8	unused00300[0x00300];
+
+/*0x00300*/	u64	usdc_vpath;
+#define VXGE_HW_USDC_VPATH_SGRP_ASSIGN(val) vxge_vBIT(val, 0, 32)
+	u8	unused00a00[0x00a00-0x00308];
+
+/*0x00a00*/	u64	wrdma_alarm_status;
+#define	VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT	vxge_mBIT(1)
+/*0x00a08*/	u64	wrdma_alarm_mask;
+	u8	unused00a30[0x00a30-0x00a10];
+
+/*0x00a30*/	u64	prc_alarm_reg;
+#define	VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP	vxge_mBIT(0)
+#define	VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR	vxge_mBIT(1)
+#define	VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT	vxge_mBIT(2)
+#define	VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR	vxge_mBIT(3)
+/*0x00a38*/	u64	prc_alarm_mask;
+/*0x00a40*/	u64	prc_alarm_alarm;
+/*0x00a48*/	u64	prc_cfg1;
+#define VXGE_HW_PRC_CFG1_RX_TIMER_VAL(val) vxge_vBIT(val, 3, 29)
+#define	VXGE_HW_PRC_CFG1_TIM_RING_BUMP_INT_ENABLE	vxge_mBIT(34)
+#define	VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE	vxge_mBIT(35)
+#define	VXGE_HW_PRC_CFG1_GREEDY_RETURN	vxge_mBIT(36)
+#define	VXGE_HW_PRC_CFG1_QUICK_SHOT	vxge_mBIT(37)
+#define	VXGE_HW_PRC_CFG1_RX_TIMER_CI	vxge_mBIT(39)
+#define VXGE_HW_PRC_CFG1_RESET_TIMER_ON_RXD_RET(val) vxge_vBIT(val, 40, 2)
+	u8	unused00a60[0x00a60-0x00a50];
+
+/*0x00a60*/	u64	prc_cfg4;
+#define	VXGE_HW_PRC_CFG4_IN_SVC	vxge_mBIT(7)
+#define VXGE_HW_PRC_CFG4_RING_MODE(val) vxge_vBIT(val, 14, 2)
+#define	VXGE_HW_PRC_CFG4_RXD_NO_SNOOP	vxge_mBIT(22)
+#define	VXGE_HW_PRC_CFG4_FRM_NO_SNOOP	vxge_mBIT(23)
+#define	VXGE_HW_PRC_CFG4_RTH_DISABLE	vxge_mBIT(31)
+#define	VXGE_HW_PRC_CFG4_IGNORE_OWNERSHIP	vxge_mBIT(32)
+#define	VXGE_HW_PRC_CFG4_SIGNAL_BENIGN_OVFLW	vxge_mBIT(36)
+#define	VXGE_HW_PRC_CFG4_BIMODAL_INTERRUPT	vxge_mBIT(37)
+#define VXGE_HW_PRC_CFG4_BACKOFF_INTERVAL(val) vxge_vBIT(val, 40, 24)
+/*0x00a68*/	u64	prc_cfg5;
+#define VXGE_HW_PRC_CFG5_RXD0_ADD(val) vxge_vBIT(val, 0, 61)
+/*0x00a70*/	u64	prc_cfg6;
+#define	VXGE_HW_PRC_CFG6_FRM_PAD_EN	vxge_mBIT(0)
+#define	VXGE_HW_PRC_CFG6_QSIZE_ALIGNED_RXD	vxge_mBIT(2)
+#define	VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN	vxge_mBIT(5)
+#define	VXGE_HW_PRC_CFG6_L3_CPC_TRSFR_CODE_EN	vxge_mBIT(8)
+#define	VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN	vxge_mBIT(9)
+#define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9)
+#define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9)
+/*0x00a78*/	u64	prc_cfg7;
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_PRC_CFG7_SMART_SCAT_EN	vxge_mBIT(11)
+#define	VXGE_HW_PRC_CFG7_RXD_NS_CHG_EN	vxge_mBIT(12)
+#define	VXGE_HW_PRC_CFG7_NO_HDR_SEPARATION	vxge_mBIT(14)
+#define VXGE_HW_PRC_CFG7_RXD_BUFF_SIZE_MASK(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_PRC_CFG7_BUFF_SIZE0_MASK(val) vxge_vBIT(val, 27, 5)
+/*0x00a80*/	u64	tim_dest_addr;
+#define VXGE_HW_TIM_DEST_ADDR_TIM_DEST_ADDR(val) vxge_vBIT(val, 0, 64)
+/*0x00a88*/	u64	prc_rxd_doorbell;
+#define VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val) vxge_vBIT(val, 48, 16)
+/*0x00a90*/	u64	rqa_prty_for_vp;
+#define VXGE_HW_RQA_PRTY_FOR_VP_RQA_PRTY_FOR_VP(val) vxge_vBIT(val, 59, 5)
+/*0x00a98*/	u64	rxdmem_size;
+#define VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(val) vxge_vBIT(val, 51, 13)
+/*0x00aa0*/	u64	frm_in_progress_cnt;
+#define	VXGE_HW_FRM_IN_PROGRESS_CNT_PRC_FRM_IN_PROGRESS_CNT(val) \
+							vxge_vBIT(val, 59, 5)
+/*0x00aa8*/	u64	rx_multi_cast_stats;
+#define VXGE_HW_RX_MULTI_CAST_STATS_FRAME_DISCARD(val) vxge_vBIT(val, 48, 16)
+/*0x00ab0*/	u64	rx_frm_transferred;
+#define	VXGE_HW_RX_FRM_TRANSFERRED_RX_FRM_TRANSFERRED(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x00ab8*/	u64	rxd_returned;
+#define VXGE_HW_RXD_RETURNED_RXD_RETURNED(val) vxge_vBIT(val, 48, 16)
+	u8	unused00c00[0x00c00-0x00ac0];
+
+/*0x00c00*/	u64	kdfc_fifo_trpl_partition;
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_1(val) vxge_vBIT(val, 33, 15)
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_2(val) vxge_vBIT(val, 49, 15)
+/*0x00c08*/	u64	kdfc_fifo_trpl_ctrl;
+#define	VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE	vxge_mBIT(7)
+/*0x00c10*/	u64	kdfc_trpl_fifo_0_ctrl;
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(val) vxge_vBIT(val, 14, 2)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_FLIP_EN	vxge_mBIT(22)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN	vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_CTRL_STRUC	vxge_mBIT(28)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_ADD_PAD	vxge_mBIT(29)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_NO_SNOOP	vxge_mBIT(30)
+#define	VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_RLX_ORD	vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c18*/	u64	kdfc_trpl_fifo_1_ctrl;
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE(val) vxge_vBIT(val, 14, 2)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_FLIP_EN	vxge_mBIT(22)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_SWAP_EN	vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_CTRL_STRUC	vxge_mBIT(28)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_ADD_PAD	vxge_mBIT(29)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_NO_SNOOP	vxge_mBIT(30)
+#define	VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_RLX_ORD	vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c20*/	u64	kdfc_trpl_fifo_2_ctrl;
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_FLIP_EN	vxge_mBIT(22)
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_SWAP_EN	vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_CTRL_STRUC	vxge_mBIT(28)
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_ADD_PAD	vxge_mBIT(29)
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_NO_SNOOP	vxge_mBIT(30)
+#define	VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_RLX_ORD	vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c28*/	u64	kdfc_trpl_fifo_0_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_0_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c30*/	u64	kdfc_trpl_fifo_1_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_1_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c38*/	u64	kdfc_trpl_fifo_2_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_2_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c40*/	u64	kdfc_trpl_fifo_offset;
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR0(val) vxge_vBIT(val, 1, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR1(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR2(val) vxge_vBIT(val, 33, 15)
+/*0x00c48*/	u64	kdfc_drbl_triplet_total;
+#define	VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_KDFC_MAX_SIZE(val) \
+							vxge_vBIT(val, 17, 15)
+	u8	unused00c60[0x00c60-0x00c50];
+
+/*0x00c60*/	u64	usdc_drbl_ctrl;
+#define	VXGE_HW_USDC_DRBL_CTRL_FLIP_EN	vxge_mBIT(22)
+#define	VXGE_HW_USDC_DRBL_CTRL_SWAP_EN	vxge_mBIT(23)
+/*0x00c68*/	u64	usdc_vp_ready;
+#define	VXGE_HW_USDC_VP_READY_USDC_HTN_READY	vxge_mBIT(7)
+#define	VXGE_HW_USDC_VP_READY_USDC_SRQ_READY	vxge_mBIT(15)
+#define	VXGE_HW_USDC_VP_READY_USDC_CQRQ_READY	vxge_mBIT(23)
+/*0x00c70*/	u64	kdfc_status;
+#define	VXGE_HW_KDFC_STATUS_KDFC_WRR_0_READY	vxge_mBIT(0)
+#define	VXGE_HW_KDFC_STATUS_KDFC_WRR_1_READY	vxge_mBIT(1)
+#define	VXGE_HW_KDFC_STATUS_KDFC_WRR_2_READY	vxge_mBIT(2)
+	u8	unused00c80[0x00c80-0x00c78];
+
+/*0x00c80*/	u64	xmac_rpa_vcfg;
+#define	VXGE_HW_XMAC_RPA_VCFG_IPV4_TCP_INCL_PH	vxge_mBIT(3)
+#define	VXGE_HW_XMAC_RPA_VCFG_IPV6_TCP_INCL_PH	vxge_mBIT(7)
+#define	VXGE_HW_XMAC_RPA_VCFG_IPV4_UDP_INCL_PH	vxge_mBIT(11)
+#define	VXGE_HW_XMAC_RPA_VCFG_IPV6_UDP_INCL_PH	vxge_mBIT(15)
+#define	VXGE_HW_XMAC_RPA_VCFG_L4_INCL_CF	vxge_mBIT(19)
+#define	VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG	vxge_mBIT(23)
+/*0x00c88*/	u64	rxmac_vcfg0;
+#define VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(val) vxge_vBIT(val, 2, 14)
+#define	VXGE_HW_RXMAC_VCFG0_RTS_USE_MIN_LEN	vxge_mBIT(19)
+#define VXGE_HW_RXMAC_VCFG0_RTS_MIN_FRM_LEN(val) vxge_vBIT(val, 26, 14)
+#define	VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN	vxge_mBIT(43)
+#define	VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN	vxge_mBIT(47)
+#define	VXGE_HW_RXMAC_VCFG0_BCAST_EN	vxge_mBIT(51)
+#define	VXGE_HW_RXMAC_VCFG0_ALL_VID_EN	vxge_mBIT(55)
+/*0x00c90*/	u64	rxmac_vcfg1;
+#define VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(val) vxge_vBIT(val, 42, 2)
+#define	VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE	vxge_mBIT(47)
+#define	VXGE_HW_RXMAC_VCFG1_CONTRIB_L2_FLOW	vxge_mBIT(51)
+/*0x00c98*/	u64	rts_access_steer_ctrl;
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(val) vxge_vBIT(val, 8, 4)
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE	vxge_mBIT(15)
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_BEHAV_TBL_SEL	vxge_mBIT(23)
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL	vxge_mBIT(27)
+#define	VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS	vxge_mBIT(0)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(val) vxge_vBIT(val, 40, 8)
+/*0x00ca0*/	u64	rts_access_steer_data0;
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x00ca8*/	u64	rts_access_steer_data1;
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DATA(val) vxge_vBIT(val, 0, 64)
+	u8	unused00d00[0x00d00-0x00cb0];
+
+/*0x00d00*/	u64	xmac_vsport_choice;
+#define VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(val) vxge_vBIT(val, 3, 5)
+/*0x00d08*/	u64	xmac_stats_cfg;
+/*0x00d10*/	u64	xmac_stats_access_cmd;
+#define VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(val) vxge_vBIT(val, 6, 2)
+#define	VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE	vxge_mBIT(15)
+#define VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(val) vxge_vBIT(val, 32, 8)
+/*0x00d18*/	u64	xmac_stats_access_data;
+#define VXGE_HW_XMAC_STATS_ACCESS_DATA_XSMGR_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x00d20*/	u64	asic_ntwk_vp_ctrl;
+#define	VXGE_HW_ASIC_NTWK_VP_CTRL_REQ_TEST_NTWK	vxge_mBIT(3)
+#define	VXGE_HW_ASIC_NTWK_VP_CTRL_XMACJ_SHOW_PORT_INFO	vxge_mBIT(55)
+#define	VXGE_HW_ASIC_NTWK_VP_CTRL_XMACJ_PORT_NUM	vxge_mBIT(63)
+	u8	unused00d30[0x00d30-0x00d28];
+
+/*0x00d30*/	u64	xgmac_vp_int_status;
+#define	VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT \
+								vxge_mBIT(3)
+/*0x00d38*/	u64	xgmac_vp_int_mask;
+/*0x00d40*/	u64	asic_ntwk_vp_err_reg;
+#define	VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT	vxge_mBIT(3)
+#define	VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK	vxge_mBIT(7)
+#define	VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR \
+								vxge_mBIT(11)
+#define	VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR \
+							vxge_mBIT(15)
+#define	VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT \
+							vxge_mBIT(19)
+#define	VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK	vxge_mBIT(23)
+/*0x00d48*/	u64	asic_ntwk_vp_err_mask;
+/*0x00d50*/	u64	asic_ntwk_vp_err_alarm;
+	u8	unused00d80[0x00d80-0x00d58];
+
+/*0x00d80*/	u64	rtdma_bw_ctrl;
+#define	VXGE_HW_RTDMA_BW_CTRL_BW_CTRL_EN	vxge_mBIT(39)
+#define VXGE_HW_RTDMA_BW_CTRL_DESIRED_BW(val) vxge_vBIT(val, 46, 18)
+/*0x00d88*/	u64	rtdma_rd_optimization_ctrl;
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_GEN_INT_AFTER_ABORT	vxge_mBIT(3)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_PAD_MODE(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_PAD_PATTERN(val) vxge_vBIT(val, 8, 8)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE	vxge_mBIT(19)
+#define VXGE_HW_PCI_EXP_DEVCTL_READRQ   0x7000  /* Max_Read_Request_Size */
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val) \
+							vxge_vBIT(val, 21, 3)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_PYLD_WMARK_EN	vxge_mBIT(28)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_PYLD_WMARK(val) \
+							vxge_vBIT(val, 29, 3)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN	vxge_mBIT(35)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(val) \
+							vxge_vBIT(val, 37, 3)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_WAIT_FOR_SPACE	vxge_mBIT(43)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_FILL_THRESH(val) \
+							vxge_vBIT(val, 51, 5)
+#define	VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_ADDR_BDRY_EN	vxge_mBIT(59)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_ADDR_BDRY(val) \
+							vxge_vBIT(val, 61, 3)
+/*0x00d90*/	u64	pda_pcc_job_monitor;
+#define	VXGE_HW_PDA_PCC_JOB_MONITOR_PDA_PCC_JOB_STATUS	vxge_mBIT(7)
+/*0x00d98*/	u64	tx_protocol_assist_cfg;
+#define	VXGE_HW_TX_PROTOCOL_ASSIST_CFG_LSOV2_EN	vxge_mBIT(6)
+#define	VXGE_HW_TX_PROTOCOL_ASSIST_CFG_IPV6_KEEP_SEARCHING	vxge_mBIT(7)
+	u8	unused01000[0x01000-0x00da0];
+
+/*0x01000*/	u64	tim_cfg1_int_num[4];
+#define VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(val) vxge_vBIT(val, 6, 26)
+#define	VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN	vxge_mBIT(35)
+#define	VXGE_HW_TIM_CFG1_INT_NUM_TXFRM_CNT_EN	vxge_mBIT(36)
+#define	VXGE_HW_TIM_CFG1_INT_NUM_TXD_CNT_EN	vxge_mBIT(37)
+#define	VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC	vxge_mBIT(38)
+#define	VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI	vxge_mBIT(39)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(val) vxge_vBIT(val, 49, 7)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(val) vxge_vBIT(val, 57, 7)
+/*0x01020*/	u64	tim_cfg2_int_num[4];
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(val) vxge_vBIT(val, 48, 16)
+/*0x01040*/	u64	tim_cfg3_int_num[4];
+#define	VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI	vxge_mBIT(0)
+#define VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_EVENT_SF(val) vxge_vBIT(val, 1, 4)
+#define VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(val) vxge_vBIT(val, 6, 26)
+#define VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(val) vxge_vBIT(val, 32, 6)
+#define VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(val) vxge_vBIT(val, 38, 26)
+/*0x01060*/	u64	tim_wrkld_clc;
+#define VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(val) vxge_vBIT(val, 35, 5)
+#define	VXGE_HW_TIM_WRKLD_CLC_CNT_FRM_BYTE	vxge_mBIT(40)
+#define VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(val) vxge_vBIT(val, 41, 2)
+#define	VXGE_HW_TIM_WRKLD_CLC_CNT_LNK_EN	vxge_mBIT(43)
+#define VXGE_HW_TIM_WRKLD_CLC_HOST_UTIL(val) vxge_vBIT(val, 57, 7)
+/*0x01068*/	u64	tim_bitmap;
+#define VXGE_HW_TIM_BITMAP_MASK(val) vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_TIM_BITMAP_LLROOT_RXD_EN	vxge_mBIT(32)
+#define	VXGE_HW_TIM_BITMAP_LLROOT_TXD_EN	vxge_mBIT(33)
+/*0x01070*/	u64	tim_ring_assn;
+#define VXGE_HW_TIM_RING_ASSN_INT_NUM(val) vxge_vBIT(val, 6, 2)
+/*0x01078*/	u64	tim_remap;
+#define	VXGE_HW_TIM_REMAP_TX_EN	vxge_mBIT(5)
+#define	VXGE_HW_TIM_REMAP_RX_EN	vxge_mBIT(6)
+#define	VXGE_HW_TIM_REMAP_OFFLOAD_EN	vxge_mBIT(7)
+#define VXGE_HW_TIM_REMAP_TO_VPATH_NUM(val) vxge_vBIT(val, 11, 5)
+/*0x01080*/	u64	tim_vpath_map;
+#define VXGE_HW_TIM_VPATH_MAP_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+/*0x01088*/	u64	tim_pci_cfg;
+#define	VXGE_HW_TIM_PCI_CFG_ADD_PAD	vxge_mBIT(7)
+#define	VXGE_HW_TIM_PCI_CFG_NO_SNOOP	vxge_mBIT(15)
+#define	VXGE_HW_TIM_PCI_CFG_RELAXED	vxge_mBIT(23)
+#define	VXGE_HW_TIM_PCI_CFG_CTL_STR	vxge_mBIT(31)
+	u8	unused01100[0x01100-0x01090];
+
+/*0x01100*/	u64	sgrp_assign;
+#define VXGE_HW_SGRP_ASSIGN_SGRP_ASSIGN(val) vxge_vBIT(val, 0, 64)
+/*0x01108*/	u64	sgrp_aoa_and_result;
+#define	VXGE_HW_SGRP_AOA_AND_RESULT_PET_SGRP_AOA_AND_RESULT(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x01110*/	u64	rpe_pci_cfg;
+#define	VXGE_HW_RPE_PCI_CFG_PAD_LRO_DATA_ENABLE	vxge_mBIT(7)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_LRO_HDR_ENABLE	vxge_mBIT(8)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_LRO_CQE_ENABLE	vxge_mBIT(9)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_NONLL_CQE_ENABLE	vxge_mBIT(10)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_BASE_LL_CQE_ENABLE	vxge_mBIT(11)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_LL_CQE_IDATA_ENABLE	vxge_mBIT(12)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_CQRQ_IR_ENABLE	vxge_mBIT(13)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_CQSQ_IR_ENABLE	vxge_mBIT(14)
+#define	VXGE_HW_RPE_PCI_CFG_PAD_CQRR_IR_ENABLE	vxge_mBIT(15)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_DATA	vxge_mBIT(18)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_NONLL_CQE	vxge_mBIT(19)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_LL_CQE	vxge_mBIT(20)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQRQ_IR	vxge_mBIT(21)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQSQ_IR	vxge_mBIT(22)
+#define	VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQRR_IR	vxge_mBIT(23)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_DATA	vxge_mBIT(26)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_NONLL_CQE	vxge_mBIT(27)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_LL_CQE	vxge_mBIT(28)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_CQRQ_IR	vxge_mBIT(29)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_CQSQ_IR	vxge_mBIT(30)
+#define	VXGE_HW_RPE_PCI_CFG_RELAXED_CQRR_IR	vxge_mBIT(31)
+/*0x01118*/	u64	rpe_lro_cfg;
+#define	VXGE_HW_RPE_LRO_CFG_SUPPRESS_LRO_ETH_TRLR	vxge_mBIT(7)
+#define	VXGE_HW_RPE_LRO_CFG_ALLOW_LRO_SNAP_SNAPJUMBO_MRG	vxge_mBIT(11)
+#define	VXGE_HW_RPE_LRO_CFG_ALLOW_LRO_LLC_LLCJUMBO_MRG	vxge_mBIT(15)
+#define	VXGE_HW_RPE_LRO_CFG_INCL_ACK_CNT_IN_CQE	vxge_mBIT(23)
+/*0x01120*/	u64	pe_mr2vp_ack_blk_limit;
+#define VXGE_HW_PE_MR2VP_ACK_BLK_LIMIT_BLK_LIMIT(val) vxge_vBIT(val, 32, 32)
+/*0x01128*/	u64	pe_mr2vp_rirr_lirr_blk_limit;
+#define	VXGE_HW_PE_MR2VP_RIRR_LIRR_BLK_LIMIT_RIRR_BLK_LIMIT(val) \
+							vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_PE_MR2VP_RIRR_LIRR_BLK_LIMIT_LIRR_BLK_LIMIT(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x01130*/	u64	txpe_pci_nce_cfg;
+#define VXGE_HW_TXPE_PCI_NCE_CFG_NCE_THRESH(val) vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_TXPE_PCI_NCE_CFG_PAD_TOWI_ENABLE	vxge_mBIT(55)
+#define	VXGE_HW_TXPE_PCI_NCE_CFG_NOSNOOP_TOWI	vxge_mBIT(63)
+	u8	unused01180[0x01180-0x01138];
+
+/*0x01180*/	u64	msg_qpad_en_cfg;
+#define	VXGE_HW_MSG_QPAD_EN_CFG_UMQ_BWR_READ	vxge_mBIT(3)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_DMQ_BWR_READ	vxge_mBIT(7)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_MXP_GENDMA_READ	vxge_mBIT(11)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_UXP_GENDMA_READ	vxge_mBIT(15)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_UMQ_MSG_WRITE	vxge_mBIT(19)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_UMQDMQ_IR_WRITE	vxge_mBIT(23)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_MXP_GENDMA_WRITE	vxge_mBIT(27)
+#define	VXGE_HW_MSG_QPAD_EN_CFG_UXP_GENDMA_WRITE	vxge_mBIT(31)
+/*0x01188*/	u64	msg_pci_cfg;
+#define	VXGE_HW_MSG_PCI_CFG_GENDMA_NO_SNOOP	vxge_mBIT(3)
+#define	VXGE_HW_MSG_PCI_CFG_UMQDMQ_IR_NO_SNOOP	vxge_mBIT(7)
+#define	VXGE_HW_MSG_PCI_CFG_UMQ_NO_SNOOP	vxge_mBIT(11)
+#define	VXGE_HW_MSG_PCI_CFG_DMQ_NO_SNOOP	vxge_mBIT(15)
+/*0x01190*/	u64	umqdmq_ir_init;
+#define VXGE_HW_UMQDMQ_IR_INIT_HOST_WRITE_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x01198*/	u64	dmq_ir_int;
+#define	VXGE_HW_DMQ_IR_INT_IMMED_ENABLE	vxge_mBIT(6)
+#define	VXGE_HW_DMQ_IR_INT_EVENT_ENABLE	vxge_mBIT(7)
+#define VXGE_HW_DMQ_IR_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_DMQ_IR_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
+/*0x011a0*/	u64	dmq_bwr_init_add;
+#define VXGE_HW_DMQ_BWR_INIT_ADD_HOST(val) vxge_vBIT(val, 0, 64)
+/*0x011a8*/	u64	dmq_bwr_init_byte;
+#define VXGE_HW_DMQ_BWR_INIT_BYTE_COUNT(val) vxge_vBIT(val, 0, 32)
+/*0x011b0*/	u64	dmq_ir;
+#define VXGE_HW_DMQ_IR_POLICY(val) vxge_vBIT(val, 0, 8)
+/*0x011b8*/	u64	umq_int;
+#define	VXGE_HW_UMQ_INT_IMMED_ENABLE	vxge_mBIT(6)
+#define	VXGE_HW_UMQ_INT_EVENT_ENABLE	vxge_mBIT(7)
+#define VXGE_HW_UMQ_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_UMQ_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
+/*0x011c0*/	u64	umq_mr2vp_bwr_pfch_init;
+#define VXGE_HW_UMQ_MR2VP_BWR_PFCH_INIT_NUMBER(val) vxge_vBIT(val, 0, 8)
+/*0x011c8*/	u64	umq_bwr_pfch_ctrl;
+#define	VXGE_HW_UMQ_BWR_PFCH_CTRL_POLL_EN	vxge_mBIT(3)
+/*0x011d0*/	u64	umq_mr2vp_bwr_eol;
+#define VXGE_HW_UMQ_MR2VP_BWR_EOL_POLL_LATENCY(val) vxge_vBIT(val, 32, 32)
+/*0x011d8*/	u64	umq_bwr_init_add;
+#define VXGE_HW_UMQ_BWR_INIT_ADD_HOST(val) vxge_vBIT(val, 0, 64)
+/*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;
+#define	VXGE_HW_DMQ_INIT_NOTIFY_PULSE	vxge_mBIT(3)
+/*0x01200*/	u64	umq_init_notify;
+#define	VXGE_HW_UMQ_INIT_NOTIFY_PULSE	vxge_mBIT(3)
+	u8	unused01380[0x01380-0x01208];
+
+/*0x01380*/	u64	tpa_cfg;
+#define	VXGE_HW_TPA_CFG_IGNORE_FRAME_ERR	vxge_mBIT(3)
+#define	VXGE_HW_TPA_CFG_IPV6_STOP_SEARCHING	vxge_mBIT(7)
+#define	VXGE_HW_TPA_CFG_L4_PSHDR_PRESENT	vxge_mBIT(11)
+#define	VXGE_HW_TPA_CFG_SUPPORT_MOBILE_IPV6_HDRS	vxge_mBIT(15)
+	u8	unused01400[0x01400-0x01388];
+
+/*0x01400*/	u64	tx_vp_reset_discarded_frms;
+#define	VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_TX_VP_RESET_DISCARDED_FRMS(val) \
+							vxge_vBIT(val, 48, 16)
+	u8	unused01480[0x01480-0x01408];
+
+/*0x01480*/	u64	fau_rpa_vcfg;
+#define	VXGE_HW_FAU_RPA_VCFG_L4_COMP_CSUM	vxge_mBIT(7)
+#define	VXGE_HW_FAU_RPA_VCFG_L3_INCL_CF	vxge_mBIT(11)
+#define	VXGE_HW_FAU_RPA_VCFG_L3_COMP_CSUM	vxge_mBIT(15)
+	u8	unused014d0[0x014d0-0x01488];
+
+/*0x014d0*/	u64	dbg_stats_rx_mpa;
+#define VXGE_HW_DBG_STATS_RX_MPA_CRC_FAIL_FRMS(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DBG_STATS_RX_MPA_MRK_FAIL_FRMS(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DBG_STATS_RX_MPA_LEN_FAIL_FRMS(val) vxge_vBIT(val, 32, 16)
+/*0x014d8*/	u64	dbg_stats_rx_fau;
+#define VXGE_HW_DBG_STATS_RX_FAU_RX_WOL_FRMS(val) vxge_vBIT(val, 0, 16)
+#define	VXGE_HW_DBG_STATS_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val) \
+							vxge_vBIT(val, 16, 16)
+#define	VXGE_HW_DBG_STATS_RX_FAU_RX_PERMITTED_FRMS(val) \
+							vxge_vBIT(val, 32, 32)
+	u8	unused014f0[0x014f0-0x014e0];
+
+/*0x014f0*/	u64	fbmc_vp_rdy;
+#define	VXGE_HW_FBMC_VP_RDY_QUEUE_SPAV_FM	vxge_mBIT(0)
+	u8	unused01e00[0x01e00-0x014f8];
+
+/*0x01e00*/	u64	vpath_pcipif_int_status;
+#define \
+VXGE_HW_VPATH_PCIPIF_INT_STATUS_SRPCIM_MSG_TO_VPATH_SRPCIM_MSG_TO_VPATH_INT \
+								vxge_mBIT(3)
+#define	VXGE_HW_VPATH_PCIPIF_INT_STATUS_VPATH_SPARE_R1_VPATH_SPARE_R1_INT \
+								vxge_mBIT(7)
+/*0x01e08*/	u64	vpath_pcipif_int_mask;
+	u8	unused01e20[0x01e20-0x01e10];
+
+/*0x01e20*/	u64	srpcim_msg_to_vpath_reg;
+#define	VXGE_HW_SRPCIM_MSG_TO_VPATH_REG_SWIF_SRPCIM_TO_VPATH_RMSG_INT \
+								vxge_mBIT(3)
+/*0x01e28*/	u64	srpcim_msg_to_vpath_mask;
+/*0x01e30*/	u64	srpcim_msg_to_vpath_alarm;
+	u8	unused01ea0[0x01ea0-0x01e38];
+
+/*0x01ea0*/	u64	vpath_to_srpcim_wmsg;
+#define VXGE_HW_VPATH_TO_SRPCIM_WMSG_VPATH_TO_SRPCIM_WMSG(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x01ea8*/	u64	vpath_to_srpcim_wmsg_trig;
+#define	VXGE_HW_VPATH_TO_SRPCIM_WMSG_TRIG_VPATH_TO_SRPCIM_WMSG_TRIG \
+							vxge_mBIT(0)
+	u8	unused02000[0x02000-0x01eb0];
+
+/*0x02000*/	u64	vpath_general_int_status;
+#define	VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT	vxge_mBIT(3)
+#define	VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT	vxge_mBIT(7)
+#define	VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT	vxge_mBIT(15)
+#define	VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT	vxge_mBIT(19)
+/*0x02008*/	u64	vpath_general_int_mask;
+#define	VXGE_HW_VPATH_GENERAL_INT_MASK_PIC_INT	vxge_mBIT(3)
+#define	VXGE_HW_VPATH_GENERAL_INT_MASK_PCI_INT	vxge_mBIT(7)
+#define	VXGE_HW_VPATH_GENERAL_INT_MASK_WRDMA_INT	vxge_mBIT(15)
+#define	VXGE_HW_VPATH_GENERAL_INT_MASK_XMAC_INT	vxge_mBIT(19)
+/*0x02010*/	u64	vpath_ppif_int_status;
+#define	VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT \
+							vxge_mBIT(3)
+#define	VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT \
+							vxge_mBIT(7)
+#define	VXGE_HW_VPATH_PPIF_INT_STATUS_PCI_CONFIG_ERRORS_PCI_CONFIG_INT \
+							vxge_mBIT(11)
+#define \
+VXGE_HW_VPATH_PPIF_INT_STATUS_MRPCIM_TO_VPATH_ALARM_MRPCIM_TO_VPATH_ALARM_INT \
+							vxge_mBIT(15)
+#define \
+VXGE_HW_VPATH_PPIF_INT_STATUS_SRPCIM_TO_VPATH_ALARM_SRPCIM_TO_VPATH_ALARM_INT \
+							vxge_mBIT(19)
+/*0x02018*/	u64	vpath_ppif_int_mask;
+/*0x02020*/	u64	kdfcctl_errors_reg;
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR	vxge_mBIT(3)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_OVRWR	vxge_mBIT(7)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_OVRWR	vxge_mBIT(11)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON	vxge_mBIT(15)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON	vxge_mBIT(19)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON	vxge_mBIT(23)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR	vxge_mBIT(31)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR	vxge_mBIT(35)
+#define	VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_DMA_ERR	vxge_mBIT(39)
+/*0x02028*/	u64	kdfcctl_errors_mask;
+/*0x02030*/	u64	kdfcctl_errors_alarm;
+	u8	unused02040[0x02040-0x02038];
+
+/*0x02040*/	u64	general_errors_reg;
+#define	VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW	vxge_mBIT(3)
+#define	VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO1_OVRFLOW	vxge_mBIT(7)
+#define	VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO2_OVRFLOW	vxge_mBIT(11)
+#define	VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR	vxge_mBIT(15)
+#define	VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ	vxge_mBIT(19)
+#define	VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS	vxge_mBIT(27)
+#define	VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET	vxge_mBIT(31)
+/*0x02048*/	u64	general_errors_mask;
+/*0x02050*/	u64	general_errors_alarm;
+/*0x02058*/	u64	pci_config_errors_reg;
+#define	VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_STATUS_ERR	vxge_mBIT(3)
+#define	VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_UNCOR_ERR	vxge_mBIT(7)
+#define	VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_COR_ERR	vxge_mBIT(11)
+/*0x02060*/	u64	pci_config_errors_mask;
+/*0x02068*/	u64	pci_config_errors_alarm;
+/*0x02070*/	u64	mrpcim_to_vpath_alarm_reg;
+#define	VXGE_HW_MRPCIM_TO_VPATH_ALARM_REG_PPIF_MRPCIM_TO_VPATH_ALARM \
+								vxge_mBIT(3)
+/*0x02078*/	u64	mrpcim_to_vpath_alarm_mask;
+/*0x02080*/	u64	mrpcim_to_vpath_alarm_alarm;
+/*0x02088*/	u64	srpcim_to_vpath_alarm_reg;
+#define	VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_PPIF_SRPCIM_TO_VPATH_ALARM(val) \
+							vxge_vBIT(val, 0, 17)
+/*0x02090*/	u64	srpcim_to_vpath_alarm_mask;
+/*0x02098*/	u64	srpcim_to_vpath_alarm_alarm;
+	u8	unused02108[0x02108-0x020a0];
+
+/*0x02108*/	u64	kdfcctl_status;
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO0_PRES(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO1_PRES(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO2_PRES(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO0_OVRWR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO1_OVRWR(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO2_OVRWR(val) vxge_vBIT(val, 40, 8)
+/*0x02110*/	u64	rsthdlr_status;
+#define	VXGE_HW_RSTHDLR_STATUS_RSTHDLR_CURRENT_RESET	vxge_mBIT(3)
+#define VXGE_HW_RSTHDLR_STATUS_RSTHDLR_CURRENT_VPIN(val) vxge_vBIT(val, 6, 2)
+/*0x02118*/	u64	fifo0_status;
+#define VXGE_HW_FIFO0_STATUS_DBLGEN_FIFO0_RDIDX(val) vxge_vBIT(val, 0, 12)
+/*0x02120*/	u64	fifo1_status;
+#define VXGE_HW_FIFO1_STATUS_DBLGEN_FIFO1_RDIDX(val) vxge_vBIT(val, 0, 12)
+/*0x02128*/	u64	fifo2_status;
+#define VXGE_HW_FIFO2_STATUS_DBLGEN_FIFO2_RDIDX(val) vxge_vBIT(val, 0, 12)
+	u8	unused02158[0x02158-0x02130];
+
+/*0x02158*/	u64	tgt_illegal_access;
+#define VXGE_HW_TGT_ILLEGAL_ACCESS_SWIF_REGION(val) vxge_vBIT(val, 1, 7)
+	u8	unused02200[0x02200-0x02160];
+
+/*0x02200*/	u64	vpath_general_cfg1;
+#define VXGE_HW_VPATH_GENERAL_CFG1_TC_VALUE(val) vxge_vBIT(val, 1, 3)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_DATA_BYTE_SWAPEN	vxge_mBIT(7)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_DATA_FLIPEN	vxge_mBIT(11)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN	vxge_mBIT(15)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_CTL_FLIPEN	vxge_mBIT(23)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_MSIX_ADDR_SWAPEN	vxge_mBIT(51)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_MSIX_ADDR_FLIPEN	vxge_mBIT(55)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_MSIX_DATA_SWAPEN	vxge_mBIT(59)
+#define	VXGE_HW_VPATH_GENERAL_CFG1_MSIX_DATA_FLIPEN	vxge_mBIT(63)
+/*0x02208*/	u64	vpath_general_cfg2;
+#define VXGE_HW_VPATH_GENERAL_CFG2_SIZE_QUANTUM(val) vxge_vBIT(val, 1, 3)
+/*0x02210*/	u64	vpath_general_cfg3;
+#define	VXGE_HW_VPATH_GENERAL_CFG3_IGNORE_VPATH_RST_FOR_INTA	vxge_mBIT(3)
+	u8	unused02220[0x02220-0x02218];
+
+/*0x02220*/	u64	kdfcctl_cfg0;
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0	vxge_mBIT(1)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1	vxge_mBIT(2)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2	vxge_mBIT(3)
+#define	VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO0	vxge_mBIT(5)
+#define	VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO1	vxge_mBIT(6)
+#define	VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO2	vxge_mBIT(7)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO0	vxge_mBIT(9)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO1	vxge_mBIT(10)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO2	vxge_mBIT(11)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO0	vxge_mBIT(13)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO1	vxge_mBIT(14)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO2	vxge_mBIT(15)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO0	vxge_mBIT(17)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO1	vxge_mBIT(18)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO2	vxge_mBIT(19)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO0	vxge_mBIT(21)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO1	vxge_mBIT(22)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO2	vxge_mBIT(23)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO0	vxge_mBIT(25)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO1	vxge_mBIT(26)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO2	vxge_mBIT(27)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO0	vxge_mBIT(29)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO1	vxge_mBIT(30)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO2	vxge_mBIT(31)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO0	vxge_mBIT(33)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO1	vxge_mBIT(34)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO2	vxge_mBIT(35)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO0	vxge_mBIT(37)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO1	vxge_mBIT(38)
+#define	VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO2	vxge_mBIT(39)
+
+	u8	unused02268[0x02268-0x02228];
+
+/*0x02268*/	u64	stats_cfg;
+#define VXGE_HW_STATS_CFG_START_HOST_ADDR(val) vxge_vBIT(val, 0, 57)
+/*0x02270*/	u64	interrupt_cfg0;
+#define VXGE_HW_INTERRUPT_CFG0_MSIX_FOR_RXTI(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP0_MSIX_FOR_TXTI(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP1_MSIX_FOR_TXTI(val) vxge_vBIT(val, 17, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP2_MSIX_FOR_TXTI(val) vxge_vBIT(val, 25, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP3_MSIX_FOR_TXTI(val) vxge_vBIT(val, 33, 7)
+	u8	unused02280[0x02280-0x02278];
+
+/*0x02280*/	u64	interrupt_cfg2;
+#define VXGE_HW_INTERRUPT_CFG2_ALARM_MAP_TO_MSG(val) vxge_vBIT(val, 1, 7)
+/*0x02288*/	u64	one_shot_vect0_en;
+#define	VXGE_HW_ONE_SHOT_VECT0_EN_ONE_SHOT_VECT0_EN	vxge_mBIT(3)
+/*0x02290*/	u64	one_shot_vect1_en;
+#define	VXGE_HW_ONE_SHOT_VECT1_EN_ONE_SHOT_VECT1_EN	vxge_mBIT(3)
+/*0x02298*/	u64	one_shot_vect2_en;
+#define	VXGE_HW_ONE_SHOT_VECT2_EN_ONE_SHOT_VECT2_EN	vxge_mBIT(3)
+/*0x022a0*/	u64	one_shot_vect3_en;
+#define	VXGE_HW_ONE_SHOT_VECT3_EN_ONE_SHOT_VECT3_EN	vxge_mBIT(3)
+	u8	unused022b0[0x022b0-0x022a8];
+
+/*0x022b0*/	u64	pci_config_access_cfg1;
+#define VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(val) vxge_vBIT(val, 0, 12)
+#define	VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0	vxge_mBIT(15)
+/*0x022b8*/	u64	pci_config_access_cfg2;
+#define	VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ	vxge_mBIT(0)
+/*0x022c0*/	u64	pci_config_access_status;
+#define	VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR	vxge_mBIT(0)
+#define VXGE_HW_PCI_CONFIG_ACCESS_STATUS_DATA(val) vxge_vBIT(val, 32, 32)
+	u8	unused02300[0x02300-0x022c8];
+
+/*0x02300*/	u64	vpath_debug_stats0;
+#define VXGE_HW_VPATH_DEBUG_STATS0_INI_NUM_MWR_SENT(val) vxge_vBIT(val, 0, 32)
+/*0x02308*/	u64	vpath_debug_stats1;
+#define VXGE_HW_VPATH_DEBUG_STATS1_INI_NUM_MRD_SENT(val) vxge_vBIT(val, 0, 32)
+/*0x02310*/	u64	vpath_debug_stats2;
+#define VXGE_HW_VPATH_DEBUG_STATS2_INI_NUM_CPL_RCVD(val) vxge_vBIT(val, 0, 32)
+/*0x02318*/	u64	vpath_debug_stats3;
+#define VXGE_HW_VPATH_DEBUG_STATS3_INI_NUM_MWR_BYTE_SENT(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x02320*/	u64	vpath_debug_stats4;
+#define VXGE_HW_VPATH_DEBUG_STATS4_INI_NUM_CPL_BYTE_RCVD(val) \
+							vxge_vBIT(val, 0, 64)
+/*0x02328*/	u64	vpath_debug_stats5;
+#define VXGE_HW_VPATH_DEBUG_STATS5_WRCRDTARB_XOFF(val) vxge_vBIT(val, 32, 32)
+/*0x02330*/	u64	vpath_debug_stats6;
+#define VXGE_HW_VPATH_DEBUG_STATS6_RDCRDTARB_XOFF(val) vxge_vBIT(val, 32, 32)
+/*0x02338*/	u64	vpath_genstats_count01;
+#define	VXGE_HW_VPATH_GENSTATS_COUNT01_PPIF_VPATH_GENSTATS_COUNT1(val) \
+							vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT01_PPIF_VPATH_GENSTATS_COUNT0(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x02340*/	u64	vpath_genstats_count23;
+#define	VXGE_HW_VPATH_GENSTATS_COUNT23_PPIF_VPATH_GENSTATS_COUNT3(val) \
+							vxge_vBIT(val, 0, 32)
+#define	VXGE_HW_VPATH_GENSTATS_COUNT23_PPIF_VPATH_GENSTATS_COUNT2(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x02348*/	u64	vpath_genstats_count4;
+#define	VXGE_HW_VPATH_GENSTATS_COUNT4_PPIF_VPATH_GENSTATS_COUNT4(val) \
+							vxge_vBIT(val, 32, 32)
+/*0x02350*/	u64	vpath_genstats_count5;
+#define	VXGE_HW_VPATH_GENSTATS_COUNT5_PPIF_VPATH_GENSTATS_COUNT5(val) \
+							vxge_vBIT(val, 32, 32)
+	u8	unused02648[0x02648-0x02358];
+} __packed;
+
+#define VXGE_HW_EEPROM_SIZE	(0x01 << 11)
+
+/* Capability lists */
+#define  VXGE_HW_PCI_EXP_LNKCAP_LNK_SPEED    0xf  /* Supported Link speeds */
+#define  VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH    0x3f0 /* Supported Link speeds. */
+#define  VXGE_HW_PCI_EXP_LNKCAP_LW_RES       0x0  /* Reserved. */
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-traffic.c linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-traffic.c
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-traffic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-traffic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2528 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-traffic.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                 Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include <linux/etherdevice.h>
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+#include "vxge-main.h"
+
+/*
+ * vxge_hw_vpath_intr_enable - Enable vpath interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Enable vpath interrupts. The function is to be executed the last in
+ * vpath initialization sequence.
+ *
+ * See also: vxge_hw_vpath_intr_disable()
+ */
+enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+
+	struct __vxge_hw_virtualpath *vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+
+	vp_reg = vpath->vp_reg;
+
+	writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->general_errors_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->pci_config_errors_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->mrpcim_to_vpath_alarm_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_to_vpath_alarm_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->vpath_ppif_int_status);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_msg_to_vpath_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->vpath_pcipif_int_status);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->prc_alarm_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->wrdma_alarm_status);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->asic_ntwk_vp_err_reg);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->xgmac_vp_int_status);
+
+	val64 = readq(&vp_reg->vpath_general_int_status);
+
+	/* Mask unwanted interrupts */
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->vpath_pcipif_int_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_msg_to_vpath_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_to_vpath_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->mrpcim_to_vpath_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->pci_config_errors_mask);
+
+	/* Unmask the individual interrupts */
+
+	writeq((u32)vxge_bVALn((VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO1_OVRFLOW|
+		VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO2_OVRFLOW|
+		VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ|
+		VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR), 0, 32),
+		&vp_reg->general_errors_mask);
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)vxge_bVALn((VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_OVRWR|
+		VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_OVRWR|
+		VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON|
+		VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON|
+		VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR|
+		VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_DMA_ERR), 0, 32),
+		&vp_reg->kdfcctl_errors_mask);
+
+	__vxge_hw_pio_mem_write32_upper(0, &vp_reg->vpath_ppif_int_mask);
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)vxge_bVALn(VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP, 0, 32),
+		&vp_reg->prc_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper(0, &vp_reg->wrdma_alarm_mask);
+	__vxge_hw_pio_mem_write32_upper(0, &vp_reg->xgmac_vp_int_mask);
+
+	if (vpath->hldev->first_vp_id != vpath->vp_id)
+		__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->asic_ntwk_vp_err_mask);
+	else
+		__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn((
+		VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT |
+		VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK), 0, 32),
+		&vp_reg->asic_ntwk_vp_err_mask);
+
+	__vxge_hw_pio_mem_write32_upper(0,
+		&vp_reg->vpath_general_int_mask);
+exit:
+	return status;
+
+}
+
+/*
+ * vxge_hw_vpath_intr_disable - Disable vpath interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Disable vpath interrupts. The function is to be executed the last in
+ * vpath initialization sequence.
+ *
+ * See also: vxge_hw_vpath_intr_enable()
+ */
+enum vxge_hw_status vxge_hw_vpath_intr_disable(
+			struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+		status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+		goto exit;
+	}
+	vp_reg = vpath->vp_reg;
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)VXGE_HW_INTR_MASK_ALL,
+		&vp_reg->vpath_general_int_mask);
+
+	val64 = VXGE_HW_TIM_CLR_INT_EN_VP(1 << (16 - vpath->vp_id));
+
+	writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->general_errors_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->pci_config_errors_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->mrpcim_to_vpath_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_to_vpath_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->vpath_ppif_int_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->srpcim_msg_to_vpath_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->vpath_pcipif_int_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->wrdma_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->prc_alarm_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->xgmac_vp_int_mask);
+
+	__vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+			&vp_reg->asic_ntwk_vp_err_mask);
+
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_channel_msix_mask - Mask MSIX Vector.
+ * @channeh: Channel for rx or tx handle
+ * @msix_id:  MSIX ID
+ *
+ * The function masks the msix interrupt for the given msix_id
+ *
+ * Returns: 0
+ */
+void vxge_hw_channel_msix_mask(struct __vxge_hw_channel *channel, int msix_id)
+{
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)vxge_bVALn(vxge_mBIT(channel->first_vp_id+(msix_id/4)),
+			0, 32),
+		&channel->common_reg->set_msix_mask_vect[msix_id%4]);
+
+	return;
+}
+
+/**
+ * vxge_hw_channel_msix_unmask - Unmask the MSIX Vector.
+ * @channeh: Channel for rx or tx handle
+ * @msix_id:  MSI ID
+ *
+ * The function unmasks the msix interrupt for the given msix_id
+ *
+ * Returns: 0
+ */
+void
+vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channel, int msix_id)
+{
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)vxge_bVALn(vxge_mBIT(channel->first_vp_id+(msix_id/4)),
+			0, 32),
+		&channel->common_reg->clear_msix_mask_vect[msix_id%4]);
+
+	return;
+}
+
+/**
+ * vxge_hw_device_set_intr_type - Updates the configuration
+ *		with new interrupt type.
+ * @hldev: HW device handle.
+ * @intr_mode: New interrupt type
+ */
+u32 vxge_hw_device_set_intr_type(struct __vxge_hw_device *hldev, u32 intr_mode)
+{
+
+	if ((intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
+	   (intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
+	   (intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
+	   (intr_mode != VXGE_HW_INTR_MODE_DEF))
+		intr_mode = VXGE_HW_INTR_MODE_IRQLINE;
+
+	hldev->config.intr_mode = intr_mode;
+	return intr_mode;
+}
+
+/**
+ * vxge_hw_device_intr_enable - Enable interrupts.
+ * @hldev: HW device handle.
+ * @op: One of the enum vxge_hw_device_intr enumerated values specifying
+ *      the type(s) of interrupts to enable.
+ *
+ * Enable Titan interrupts. The function is to be executed the last in
+ * Titan initialization sequence.
+ *
+ * See also: vxge_hw_device_intr_disable()
+ */
+void vxge_hw_device_intr_enable(struct __vxge_hw_device *hldev)
+{
+	u32 i;
+	u64 val64;
+	u32 val32;
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+			continue;
+
+		vxge_hw_vpath_intr_enable(
+			VXGE_HW_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
+	}
+
+	if (hldev->config.intr_mode == VXGE_HW_INTR_MODE_IRQLINE) {
+		val64 = hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+			hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX];
+
+		if (val64 != 0) {
+			writeq(val64, &hldev->common_reg->tim_int_status0);
+
+			writeq(~val64, &hldev->common_reg->tim_int_mask0);
+		}
+
+		val32 = hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+			hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX];
+
+		if (val32 != 0) {
+			__vxge_hw_pio_mem_write32_upper(val32,
+					&hldev->common_reg->tim_int_status1);
+
+			__vxge_hw_pio_mem_write32_upper(~val32,
+					&hldev->common_reg->tim_int_mask1);
+		}
+	}
+
+	val64 = readq(&hldev->common_reg->titan_general_int_status);
+
+	vxge_hw_device_unmask_all(hldev);
+
+	return;
+}
+
+/**
+ * vxge_hw_device_intr_disable - Disable Titan interrupts.
+ * @hldev: HW device handle.
+ * @op: One of the enum vxge_hw_device_intr enumerated values specifying
+ *      the type(s) of interrupts to disable.
+ *
+ * Disable Titan interrupts.
+ *
+ * See also: vxge_hw_device_intr_enable()
+ */
+void vxge_hw_device_intr_disable(struct __vxge_hw_device *hldev)
+{
+	u32 i;
+
+	vxge_hw_device_mask_all(hldev);
+
+	/* mask all the tim interrupts */
+	writeq(VXGE_HW_INTR_MASK_ALL, &hldev->common_reg->tim_int_mask0);
+	__vxge_hw_pio_mem_write32_upper(VXGE_HW_DEFAULT_32,
+		&hldev->common_reg->tim_int_mask1);
+
+	for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+		if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+			continue;
+
+		vxge_hw_vpath_intr_disable(
+			VXGE_HW_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
+	}
+
+	return;
+}
+
+/**
+ * vxge_hw_device_mask_all - Mask all device interrupts.
+ * @hldev: HW device handle.
+ *
+ * Mask	all device interrupts.
+ *
+ * See also: vxge_hw_device_unmask_all()
+ */
+void vxge_hw_device_mask_all(struct __vxge_hw_device *hldev)
+{
+	u64 val64;
+
+	val64 = VXGE_HW_TITAN_MASK_ALL_INT_ALARM |
+		VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC;
+
+	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+				&hldev->common_reg->titan_mask_all_int);
+
+	return;
+}
+
+/**
+ * vxge_hw_device_unmask_all - Unmask all device interrupts.
+ * @hldev: HW device handle.
+ *
+ * Unmask all device interrupts.
+ *
+ * See also: vxge_hw_device_mask_all()
+ */
+void vxge_hw_device_unmask_all(struct __vxge_hw_device *hldev)
+{
+	u64 val64 = 0;
+
+	if (hldev->config.intr_mode == VXGE_HW_INTR_MODE_IRQLINE)
+		val64 =  VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC;
+
+	__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+			&hldev->common_reg->titan_mask_all_int);
+
+	return;
+}
+
+/**
+ * vxge_hw_device_flush_io - Flush io writes.
+ * @hldev: HW device handle.
+ *
+ * The function	performs a read operation to flush io writes.
+ *
+ * Returns: void
+ */
+void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev)
+{
+	u32 val32;
+
+	val32 = readl(&hldev->common_reg->titan_general_int_status);
+}
+
+/**
+ * vxge_hw_device_begin_irq - Begin IRQ processing.
+ * @hldev: HW device handle.
+ * @skip_alarms: Do not clear the alarms
+ * @reason: "Reason" for the interrupt, the value of Titan's
+ *	general_int_status register.
+ *
+ * The function	performs two actions, It first checks whether (shared IRQ) the
+ * interrupt was raised	by the device. Next, it	masks the device interrupts.
+ *
+ * Note:
+ * vxge_hw_device_begin_irq() does not flush MMIO writes through the
+ * bridge. Therefore, two back-to-back interrupts are potentially possible.
+ *
+ * Returns: 0, if the interrupt	is not "ours" (note that in this case the
+ * device remain enabled).
+ * Otherwise, vxge_hw_device_begin_irq() returns 64bit general adapter
+ * status.
+ */
+enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev,
+					     u32 skip_alarms, u64 *reason)
+{
+	u32 i;
+	u64 val64;
+	u64 adapter_status;
+	u64 vpath_mask;
+	enum vxge_hw_status ret = VXGE_HW_OK;
+
+	val64 = readq(&hldev->common_reg->titan_general_int_status);
+
+	if (unlikely(!val64)) {
+		/* not Titan interrupt	*/
+		*reason	= 0;
+		ret = VXGE_HW_ERR_WRONG_IRQ;
+		goto exit;
+	}
+
+	if (unlikely(val64 == VXGE_HW_ALL_FOXES)) {
+
+		adapter_status = readq(&hldev->common_reg->adapter_status);
+
+		if (adapter_status == VXGE_HW_ALL_FOXES) {
+
+			__vxge_hw_device_handle_error(hldev,
+				NULL_VPID, VXGE_HW_EVENT_SLOT_FREEZE);
+			*reason	= 0;
+			ret = VXGE_HW_ERR_SLOT_FREEZE;
+			goto exit;
+		}
+	}
+
+	hldev->stats.sw_dev_info_stats.total_intr_cnt++;
+
+	*reason	= val64;
+
+	vpath_mask = hldev->vpaths_deployed >>
+				(64 - VXGE_HW_MAX_VIRTUAL_PATHS);
+
+	if (val64 &
+	    VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) {
+		hldev->stats.sw_dev_info_stats.traffic_intr_cnt++;
+
+		return VXGE_HW_OK;
+	}
+
+	hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt++;
+
+	if (unlikely(val64 &
+			VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) {
+
+		enum vxge_hw_status error_level = VXGE_HW_OK;
+
+		hldev->stats.sw_dev_err_stats.vpath_alarms++;
+
+		for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+			if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+				continue;
+
+			ret = __vxge_hw_vpath_alarm_process(
+				&hldev->virtual_paths[i], skip_alarms);
+
+			error_level = VXGE_HW_SET_LEVEL(ret, error_level);
+
+			if (unlikely((ret == VXGE_HW_ERR_CRITICAL) ||
+				(ret == VXGE_HW_ERR_SLOT_FREEZE)))
+				break;
+		}
+
+		ret = error_level;
+	}
+exit:
+	return ret;
+}
+
+/*
+ * __vxge_hw_device_handle_link_up_ind
+ * @hldev: HW device handle.
+ *
+ * Link up indication handler. The function is invoked by HW when
+ * Titan indicates that the link is up for programmable amount of time.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev)
+{
+	/*
+	 * If the previous link state is not down, return.
+	 */
+	if (hldev->link_state == VXGE_HW_LINK_UP)
+		goto exit;
+
+	hldev->link_state = VXGE_HW_LINK_UP;
+
+	/* notify driver */
+	if (hldev->uld_callbacks.link_up)
+		hldev->uld_callbacks.link_up(hldev);
+exit:
+	return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_handle_link_down_ind
+ * @hldev: HW device handle.
+ *
+ * Link down indication handler. The function is invoked by HW when
+ * Titan indicates that the link is down.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev)
+{
+	/*
+	 * If the previous link state is not down, return.
+	 */
+	if (hldev->link_state == VXGE_HW_LINK_DOWN)
+		goto exit;
+
+	hldev->link_state = VXGE_HW_LINK_DOWN;
+
+	/* notify driver */
+	if (hldev->uld_callbacks.link_down)
+		hldev->uld_callbacks.link_down(hldev);
+exit:
+	return VXGE_HW_OK;
+}
+
+/**
+ * __vxge_hw_device_handle_error - Handle error
+ * @hldev: HW device
+ * @vp_id: Vpath Id
+ * @type: Error type. Please see enum vxge_hw_event{}
+ *
+ * Handle error.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_error(
+		struct __vxge_hw_device *hldev,
+		u32 vp_id,
+		enum vxge_hw_event type)
+{
+	switch (type) {
+	case VXGE_HW_EVENT_UNKNOWN:
+		break;
+	case VXGE_HW_EVENT_RESET_START:
+	case VXGE_HW_EVENT_RESET_COMPLETE:
+	case VXGE_HW_EVENT_LINK_DOWN:
+	case VXGE_HW_EVENT_LINK_UP:
+		goto out;
+	case VXGE_HW_EVENT_ALARM_CLEARED:
+		goto out;
+	case VXGE_HW_EVENT_ECCERR:
+	case VXGE_HW_EVENT_MRPCIM_ECCERR:
+		goto out;
+	case VXGE_HW_EVENT_FIFO_ERR:
+	case VXGE_HW_EVENT_VPATH_ERR:
+	case VXGE_HW_EVENT_CRITICAL_ERR:
+	case VXGE_HW_EVENT_SERR:
+		break;
+	case VXGE_HW_EVENT_SRPCIM_SERR:
+	case VXGE_HW_EVENT_MRPCIM_SERR:
+		goto out;
+	case VXGE_HW_EVENT_SLOT_FREEZE:
+		break;
+	default:
+		vxge_assert(0);
+		goto out;
+	}
+
+	/* notify driver */
+	if (hldev->uld_callbacks.crit_err)
+		hldev->uld_callbacks.crit_err(
+			(struct __vxge_hw_device *)hldev,
+			type, vp_id);
+out:
+
+	return VXGE_HW_OK;
+}
+
+/**
+ * vxge_hw_device_clear_tx_rx - Acknowledge (that is, clear) the
+ * condition that has caused the Tx and RX interrupt.
+ * @hldev: HW device.
+ *
+ * Acknowledge (that is, clear) the condition that has caused
+ * the Tx and Rx interrupt.
+ * See also: vxge_hw_device_begin_irq(),
+ * vxge_hw_device_mask_tx_rx(), vxge_hw_device_unmask_tx_rx().
+ */
+void vxge_hw_device_clear_tx_rx(struct __vxge_hw_device *hldev)
+{
+
+	if ((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+	   (hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		writeq((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+				 hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX]),
+				&hldev->common_reg->tim_int_status0);
+	}
+
+	if ((hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+	   (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		__vxge_hw_pio_mem_write32_upper(
+				(hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+				 hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX]),
+				&hldev->common_reg->tim_int_status1);
+	}
+
+	return;
+}
+
+/*
+ * vxge_hw_channel_dtr_alloc - Allocate a dtr from the channel
+ * @channel: Channel
+ * @dtrh: Buffer to return the DTR pointer
+ *
+ * Allocates a dtr from the reserve array. If the reserve array is empty,
+ * it swaps the reserve and free arrays.
+ *
+ */
+enum vxge_hw_status
+vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh)
+{
+	void **tmp_arr;
+
+	if (channel->reserve_ptr - channel->reserve_top > 0) {
+_alloc_after_swap:
+		*dtrh =	channel->reserve_arr[--channel->reserve_ptr];
+
+		return VXGE_HW_OK;
+	}
+
+	/* switch between empty	and full arrays	*/
+
+	/* the idea behind such	a design is that by having free	and reserved
+	 * arrays separated we basically separated irq and non-irq parts.
+	 * i.e.	no additional lock need	to be done when	we free	a resource */
+
+	if (channel->length - channel->free_ptr > 0) {
+
+		tmp_arr	= channel->reserve_arr;
+		channel->reserve_arr = channel->free_arr;
+		channel->free_arr = tmp_arr;
+		channel->reserve_ptr = channel->length;
+		channel->reserve_top = channel->free_ptr;
+		channel->free_ptr = channel->length;
+
+		channel->stats->reserve_free_swaps_cnt++;
+
+		goto _alloc_after_swap;
+	}
+
+	channel->stats->full_cnt++;
+
+	*dtrh =	NULL;
+	return VXGE_HW_INF_OUT_OF_DESCRIPTORS;
+}
+
+/*
+ * vxge_hw_channel_dtr_post - Post a dtr to the channel
+ * @channelh: Channel
+ * @dtrh: DTR pointer
+ *
+ * Posts a dtr to work array.
+ *
+ */
+void vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh)
+{
+	vxge_assert(channel->work_arr[channel->post_index] == NULL);
+
+	channel->work_arr[channel->post_index++] = dtrh;
+
+	/* wrap-around */
+	if (channel->post_index	== channel->length)
+		channel->post_index = 0;
+}
+
+/*
+ * vxge_hw_channel_dtr_try_complete - Returns next completed dtr
+ * @channel: Channel
+ * @dtr: Buffer to return the next completed DTR pointer
+ *
+ * Returns the next completed dtr with out removing it from work array
+ *
+ */
+void
+vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel, void **dtrh)
+{
+	vxge_assert(channel->compl_index < channel->length);
+
+	*dtrh =	channel->work_arr[channel->compl_index];
+}
+
+/*
+ * vxge_hw_channel_dtr_complete - Removes next completed dtr from the work array
+ * @channel: Channel handle
+ *
+ * Removes the next completed dtr from work array
+ *
+ */
+void vxge_hw_channel_dtr_complete(struct __vxge_hw_channel *channel)
+{
+	channel->work_arr[channel->compl_index]	= NULL;
+
+	/* wrap-around */
+	if (++channel->compl_index == channel->length)
+		channel->compl_index = 0;
+
+	channel->stats->total_compl_cnt++;
+}
+
+/*
+ * vxge_hw_channel_dtr_free - Frees a dtr
+ * @channel: Channel handle
+ * @dtr:  DTR pointer
+ *
+ * Returns the dtr to free array
+ *
+ */
+void vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh)
+{
+	channel->free_arr[--channel->free_ptr] = dtrh;
+}
+
+/*
+ * vxge_hw_channel_dtr_count
+ * @channel: Channel handle. Obtained via vxge_hw_channel_open().
+ *
+ * Retreive number of DTRs available. This function can not be called
+ * from data path. ring_initial_replenishi() is the only user.
+ */
+int vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel)
+{
+	return (channel->reserve_ptr - channel->reserve_top) +
+		(channel->length - channel->free_ptr);
+}
+
+/**
+ * vxge_hw_ring_rxd_reserve	- Reserve ring descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Reserved descriptor. On success HW fills this "out" parameter
+ * with a valid handle.
+ *
+ * Reserve Rx descriptor for the subsequent filling-in driver
+ * and posting on the corresponding channel (@channelh)
+ * via vxge_hw_ring_rxd_post().
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_OUT_OF_DESCRIPTORS - Currently no descriptors available.
+ *
+ */
+enum vxge_hw_status vxge_hw_ring_rxd_reserve(struct __vxge_hw_ring *ring,
+	void **rxdh)
+{
+	enum vxge_hw_status status;
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	status = vxge_hw_channel_dtr_alloc(channel, rxdh);
+
+	if (status == VXGE_HW_OK) {
+		struct vxge_hw_ring_rxd_1 *rxdp =
+			(struct vxge_hw_ring_rxd_1 *)*rxdh;
+
+		rxdp->control_0	= rxdp->control_1 = 0;
+	}
+
+	return status;
+}
+
+/**
+ * vxge_hw_ring_rxd_free - Free descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Free	the reserved descriptor. This operation is "symmetrical" to
+ * vxge_hw_ring_rxd_reserve. The "free-ing" completes the descriptor's
+ * lifecycle.
+ *
+ * After free-ing (see vxge_hw_ring_rxd_free()) the descriptor again can
+ * be:
+ *
+ * - reserved (vxge_hw_ring_rxd_reserve);
+ *
+ * - posted	(vxge_hw_ring_rxd_post);
+ *
+ * - completed (vxge_hw_ring_rxd_next_completed);
+ *
+ * - and recycled again	(vxge_hw_ring_rxd_free).
+ *
+ * For alternative state transitions and more details please refer to
+ * the design doc.
+ *
+ */
+void vxge_hw_ring_rxd_free(struct __vxge_hw_ring *ring, void *rxdh)
+{
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	vxge_hw_channel_dtr_free(channel, rxdh);
+
+}
+
+/**
+ * vxge_hw_ring_rxd_pre_post - Prepare rxd and post
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * This routine prepares a rxd and posts
+ */
+void vxge_hw_ring_rxd_pre_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	vxge_hw_channel_dtr_post(channel, rxdh);
+}
+
+/**
+ * vxge_hw_ring_rxd_post_post - Process rxd after post.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Processes rxd after post
+ */
+void vxge_hw_ring_rxd_post_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	rxdp->control_0	|= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER;
+
+	if (ring->stats->common_stats.usage_cnt > 0)
+		ring->stats->common_stats.usage_cnt--;
+}
+
+/**
+ * vxge_hw_ring_rxd_post - Post descriptor on the ring.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor obtained via vxge_hw_ring_rxd_reserve().
+ *
+ * Post	descriptor on the ring.
+ * Prior to posting the	descriptor should be filled in accordance with
+ * Host/Titan interface specification for a given service (LL, etc.).
+ *
+ */
+void vxge_hw_ring_rxd_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+	struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	wmb();
+	rxdp->control_0	|= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER;
+
+	vxge_hw_channel_dtr_post(channel, rxdh);
+
+	if (ring->stats->common_stats.usage_cnt > 0)
+		ring->stats->common_stats.usage_cnt--;
+}
+
+/**
+ * vxge_hw_ring_rxd_post_post_wmb - Process rxd after post with memory barrier.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Processes rxd after post with memory barrier.
+ */
+void vxge_hw_ring_rxd_post_post_wmb(struct __vxge_hw_ring *ring, void *rxdh)
+{
+	struct __vxge_hw_channel *channel;
+
+	channel = &ring->channel;
+
+	wmb();
+	vxge_hw_ring_rxd_post_post(ring, rxdh);
+}
+
+/**
+ * vxge_hw_ring_rxd_next_completed - Get the _next_ completed descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle. Returned by HW.
+ * @t_code:	Transfer code, as per Titan User Guide,
+ *	 Receive Descriptor Format. Returned by HW.
+ *
+ * Retrieve the	_next_ completed descriptor.
+ * HW uses ring callback (*vxge_hw_ring_callback_f) to notifiy
+ * driver of new completed descriptors. After that
+ * the driver can use vxge_hw_ring_rxd_next_completed to retrieve the rest
+ * completions (the very first completion is passed by HW via
+ * vxge_hw_ring_callback_f).
+ *
+ * Implementation-wise, the driver is free to call
+ * vxge_hw_ring_rxd_next_completed either immediately from inside the
+ * ring callback, or in a deferred fashion and separate (from HW)
+ * context.
+ *
+ * Non-zero @t_code means failure to fill-in receive buffer(s)
+ * of the descriptor.
+ * For instance, parity	error detected during the data transfer.
+ * In this case	Titan will complete the descriptor and indicate
+ * for the host	that the received data is not to be used.
+ * For details please refer to Titan User Guide.
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed descriptors
+ * are currently available for processing.
+ *
+ * See also: vxge_hw_ring_callback_f{},
+ * vxge_hw_fifo_rxd_next_completed(), enum vxge_hw_status{}.
+ */
+enum vxge_hw_status vxge_hw_ring_rxd_next_completed(
+	struct __vxge_hw_ring *ring, void **rxdh, u8 *t_code)
+{
+	struct __vxge_hw_channel *channel;
+	struct vxge_hw_ring_rxd_1 *rxdp;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	channel = &ring->channel;
+
+	vxge_hw_channel_dtr_try_complete(channel, rxdh);
+
+	rxdp = (struct vxge_hw_ring_rxd_1 *)*rxdh;
+	if (rxdp == NULL) {
+		status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+		goto exit;
+	}
+
+	/* check whether it is not the end */
+	if (!(rxdp->control_0 &	VXGE_HW_RING_RXD_LIST_OWN_ADAPTER)) {
+
+		vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control !=
+				0);
+
+		++ring->cmpl_cnt;
+		vxge_hw_channel_dtr_complete(channel);
+
+		*t_code	= (u8)VXGE_HW_RING_RXD_T_CODE_GET(rxdp->control_0);
+
+		vxge_assert(*t_code != VXGE_HW_RING_RXD_T_CODE_UNUSED);
+
+		ring->stats->common_stats.usage_cnt++;
+		if (ring->stats->common_stats.usage_max <
+				ring->stats->common_stats.usage_cnt)
+			ring->stats->common_stats.usage_max =
+				ring->stats->common_stats.usage_cnt;
+
+		status = VXGE_HW_OK;
+		goto exit;
+	}
+
+	/* reset it. since we don't want to return
+	 * garbage to the driver */
+	*rxdh =	NULL;
+	status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_ring_handle_tcode - Handle transfer code.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ * @t_code: One of the enumerated (and documented in the Titan user guide)
+ * "transfer codes".
+ *
+ * Handle descriptor's transfer code. The latter comes with each completed
+ * descriptor.
+ *
+ * Returns: one of the enum vxge_hw_status{} enumerated types.
+ * VXGE_HW_OK			- for success.
+ * VXGE_HW_ERR_CRITICAL         - when encounters critical error.
+ */
+enum vxge_hw_status vxge_hw_ring_handle_tcode(
+	struct __vxge_hw_ring *ring, void *rxdh, u8 t_code)
+{
+	struct __vxge_hw_channel *channel;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	channel = &ring->channel;
+
+	/* If the t_code is not supported and if the
+	 * t_code is other than 0x5 (unparseable packet
+	 * such as unknown UPV6 header), Drop it !!!
+	 */
+
+	if (t_code == 0 || t_code == 5) {
+		status = VXGE_HW_OK;
+		goto exit;
+	}
+
+	if (t_code > 0xF) {
+		status = VXGE_HW_ERR_INVALID_TCODE;
+		goto exit;
+	}
+
+	ring->stats->rxd_t_code_err_cnt[t_code]++;
+exit:
+	return status;
+}
+
+/**
+ * __vxge_hw_non_offload_db_post - Post non offload doorbell
+ *
+ * @fifo: fifohandle
+ * @txdl_ptr: The starting location of the TxDL in host memory
+ * @num_txds: The highest TxD in this TxDL (0 to 255 means 1 to 256)
+ * @no_snoop: No snoop flags
+ *
+ * This function posts a non-offload doorbell to doorbell FIFO
+ *
+ */
+static void __vxge_hw_non_offload_db_post(struct __vxge_hw_fifo *fifo,
+	u64 txdl_ptr, u32 num_txds, u32 no_snoop)
+{
+	struct __vxge_hw_channel *channel;
+
+	channel = &fifo->channel;
+
+	writeq(VXGE_HW_NODBW_TYPE(VXGE_HW_NODBW_TYPE_NODBW) |
+		VXGE_HW_NODBW_LAST_TXD_NUMBER(num_txds) |
+		VXGE_HW_NODBW_GET_NO_SNOOP(no_snoop),
+		&fifo->nofl_db->control_0);
+
+	wmb();
+
+	writeq(txdl_ptr, &fifo->nofl_db->txdl_ptr);
+	wmb();
+
+}
+
+/**
+ * vxge_hw_fifo_free_txdl_count_get - returns the number of txdls available in
+ * the fifo
+ * @fifoh: Handle to the fifo object used for non offload send
+ */
+u32 vxge_hw_fifo_free_txdl_count_get(struct __vxge_hw_fifo *fifoh)
+{
+	return vxge_hw_channel_dtr_count(&fifoh->channel);
+}
+
+/**
+ * vxge_hw_fifo_txdl_reserve - Reserve fifo descriptor.
+ * @fifoh: Handle to the fifo object used for non offload send
+ * @txdlh: Reserved descriptor. On success HW fills this "out" parameter
+ *        with a valid handle.
+ * @txdl_priv: Buffer to return the pointer to per txdl space
+ *
+ * Reserve a single TxDL (that is, fifo descriptor)
+ * for the subsequent filling-in by driver)
+ * and posting on the corresponding channel (@channelh)
+ * via vxge_hw_fifo_txdl_post().
+ *
+ * Note: it is the responsibility of driver to reserve multiple descriptors
+ * for lengthy (e.g., LSO) transmit operation. A single fifo descriptor
+ * carries up to configured number (fifo.max_frags) of contiguous buffers.
+ *
+ * Returns: VXGE_HW_OK - success;
+ * VXGE_HW_INF_OUT_OF_DESCRIPTORS - Currently no descriptors available
+ *
+ */
+enum vxge_hw_status vxge_hw_fifo_txdl_reserve(
+	struct __vxge_hw_fifo *fifo,
+	void **txdlh, void **txdl_priv)
+{
+	struct __vxge_hw_channel *channel;
+	enum vxge_hw_status status;
+	int i;
+
+	channel = &fifo->channel;
+
+	status = vxge_hw_channel_dtr_alloc(channel, txdlh);
+
+	if (status == VXGE_HW_OK) {
+		struct vxge_hw_fifo_txd *txdp =
+			(struct vxge_hw_fifo_txd *)*txdlh;
+		struct __vxge_hw_fifo_txdl_priv *priv;
+
+		priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
+
+		/* reset the TxDL's private */
+		priv->align_dma_offset = 0;
+		priv->align_vaddr_start = priv->align_vaddr;
+		priv->align_used_frags = 0;
+		priv->frags = 0;
+		priv->alloc_frags = fifo->config->max_frags;
+		priv->next_txdl_priv = NULL;
+
+		*txdl_priv = (void *)(size_t)txdp->host_control;
+
+		for (i = 0; i < fifo->config->max_frags; i++) {
+			txdp = ((struct vxge_hw_fifo_txd *)*txdlh) + i;
+			txdp->control_0 = txdp->control_1 = 0;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * vxge_hw_fifo_txdl_buffer_set - Set transmit buffer pointer in the
+ * descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
+ *            (of buffers).
+ * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
+ * @size: Size of the data buffer (in bytes).
+ *
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_mss_set() and vxge_hw_fifo_txdl_cksum_set_bits().
+ * All three APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+void vxge_hw_fifo_txdl_buffer_set(struct __vxge_hw_fifo *fifo,
+				  void *txdlh, u32 frag_idx,
+				  dma_addr_t dma_pointer, u32 size)
+{
+	struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+	struct vxge_hw_fifo_txd *txdp, *txdp_last;
+	struct __vxge_hw_channel *channel;
+
+	channel = &fifo->channel;
+
+	txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdlh);
+	txdp = (struct vxge_hw_fifo_txd *)txdlh  +  txdl_priv->frags;
+
+	if (frag_idx != 0)
+		txdp->control_0 = txdp->control_1 = 0;
+	else {
+		txdp->control_0 |= VXGE_HW_FIFO_TXD_GATHER_CODE(
+			VXGE_HW_FIFO_TXD_GATHER_CODE_FIRST);
+		txdp->control_1 |= fifo->interrupt_type;
+		txdp->control_1 |= VXGE_HW_FIFO_TXD_INT_NUMBER(
+			fifo->tx_intr_num);
+		if (txdl_priv->frags) {
+			txdp_last = (struct vxge_hw_fifo_txd *)txdlh  +
+			(txdl_priv->frags - 1);
+			txdp_last->control_0 |= VXGE_HW_FIFO_TXD_GATHER_CODE(
+				VXGE_HW_FIFO_TXD_GATHER_CODE_LAST);
+		}
+	}
+
+	vxge_assert(frag_idx < txdl_priv->alloc_frags);
+
+	txdp->buffer_pointer = (u64)dma_pointer;
+	txdp->control_0 |= VXGE_HW_FIFO_TXD_BUFFER_SIZE(size);
+	fifo->stats->total_buffers++;
+	txdl_priv->frags++;
+}
+
+/**
+ * vxge_hw_fifo_txdl_post - Post descriptor on the fifo channel.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor obtained via vxge_hw_fifo_txdl_reserve()
+ * @frags: Number of contiguous buffers that are part of a single
+ *         transmit operation.
+ *
+ * Post descriptor on the 'fifo' type channel for transmission.
+ * Prior to posting the descriptor should be filled in accordance with
+ * Host/Titan interface specification for a given service (LL, etc.).
+ *
+ */
+void vxge_hw_fifo_txdl_post(struct __vxge_hw_fifo *fifo, void *txdlh)
+{
+	struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+	struct vxge_hw_fifo_txd *txdp_last;
+	struct vxge_hw_fifo_txd *txdp_first;
+	struct __vxge_hw_channel *channel;
+
+	channel = &fifo->channel;
+
+	txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdlh);
+	txdp_first = (struct vxge_hw_fifo_txd *)txdlh;
+
+	txdp_last = (struct vxge_hw_fifo_txd *)txdlh  +  (txdl_priv->frags - 1);
+	txdp_last->control_0 |=
+	      VXGE_HW_FIFO_TXD_GATHER_CODE(VXGE_HW_FIFO_TXD_GATHER_CODE_LAST);
+	txdp_first->control_0 |= VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER;
+
+	vxge_hw_channel_dtr_post(&fifo->channel, txdlh);
+
+	__vxge_hw_non_offload_db_post(fifo,
+		(u64)(size_t)txdl_priv->dma_addr,
+		txdl_priv->frags - 1,
+		fifo->no_snoop_bits);
+
+	fifo->stats->total_posts++;
+	fifo->stats->common_stats.usage_cnt++;
+	if (fifo->stats->common_stats.usage_max <
+		fifo->stats->common_stats.usage_cnt)
+		fifo->stats->common_stats.usage_max =
+			fifo->stats->common_stats.usage_cnt;
+}
+
+/**
+ * vxge_hw_fifo_txdl_next_completed - Retrieve next completed descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle. Returned by HW.
+ * @t_code: Transfer code, as per Titan User Guide,
+ *          Transmit Descriptor Format.
+ *          Returned by HW.
+ *
+ * Retrieve the _next_ completed descriptor.
+ * HW uses channel callback (*vxge_hw_channel_callback_f) to notifiy
+ * driver of new completed descriptors. After that
+ * the driver can use vxge_hw_fifo_txdl_next_completed to retrieve the rest
+ * completions (the very first completion is passed by HW via
+ * vxge_hw_channel_callback_f).
+ *
+ * Implementation-wise, the driver is free to call
+ * vxge_hw_fifo_txdl_next_completed either immediately from inside the
+ * channel callback, or in a deferred fashion and separate (from HW)
+ * context.
+ *
+ * Non-zero @t_code means failure to process the descriptor.
+ * The failure could happen, for instance, when the link is
+ * down, in which case Titan completes the descriptor because it
+ * is not able to send the data out.
+ *
+ * For details please refer to Titan User Guide.
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed descriptors
+ * are currently available for processing.
+ *
+ */
+enum vxge_hw_status vxge_hw_fifo_txdl_next_completed(
+	struct __vxge_hw_fifo *fifo, void **txdlh,
+	enum vxge_hw_fifo_tcode *t_code)
+{
+	struct __vxge_hw_channel *channel;
+	struct vxge_hw_fifo_txd *txdp;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	channel = &fifo->channel;
+
+	vxge_hw_channel_dtr_try_complete(channel, txdlh);
+
+	txdp = (struct vxge_hw_fifo_txd *)*txdlh;
+	if (txdp == NULL) {
+		status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+		goto exit;
+	}
+
+	/* check whether host owns it */
+	if (!(txdp->control_0 & VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER)) {
+
+		vxge_assert(txdp->host_control != 0);
+
+		vxge_hw_channel_dtr_complete(channel);
+
+		*t_code = (u8)VXGE_HW_FIFO_TXD_T_CODE_GET(txdp->control_0);
+
+		if (fifo->stats->common_stats.usage_cnt > 0)
+			fifo->stats->common_stats.usage_cnt--;
+
+		status = VXGE_HW_OK;
+		goto exit;
+	}
+
+	/* no more completions */
+	*txdlh = NULL;
+	status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_fifo_handle_tcode - Handle transfer code.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ * @t_code: One of the enumerated (and documented in the Titan user guide)
+ *          "transfer codes".
+ *
+ * Handle descriptor's transfer code. The latter comes with each completed
+ * descriptor.
+ *
+ * Returns: one of the enum vxge_hw_status{} enumerated types.
+ * VXGE_HW_OK - for success.
+ * VXGE_HW_ERR_CRITICAL - when encounters critical error.
+ */
+enum vxge_hw_status vxge_hw_fifo_handle_tcode(struct __vxge_hw_fifo *fifo,
+					      void *txdlh,
+					      enum vxge_hw_fifo_tcode t_code)
+{
+	struct __vxge_hw_channel *channel;
+
+	enum vxge_hw_status status = VXGE_HW_OK;
+	channel = &fifo->channel;
+
+	if (((t_code & 0x7) < 0) || ((t_code & 0x7) > 0x4)) {
+		status = VXGE_HW_ERR_INVALID_TCODE;
+		goto exit;
+	}
+
+	fifo->stats->txd_t_code_err_cnt[t_code]++;
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_fifo_txdl_free - Free descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ *
+ * Free the reserved descriptor. This operation is "symmetrical" to
+ * vxge_hw_fifo_txdl_reserve. The "free-ing" completes the descriptor's
+ * lifecycle.
+ *
+ * After free-ing (see vxge_hw_fifo_txdl_free()) the descriptor again can
+ * be:
+ *
+ * - reserved (vxge_hw_fifo_txdl_reserve);
+ *
+ * - posted (vxge_hw_fifo_txdl_post);
+ *
+ * - completed (vxge_hw_fifo_txdl_next_completed);
+ *
+ * - and recycled again (vxge_hw_fifo_txdl_free).
+ *
+ * For alternative state transitions and more details please refer to
+ * the design doc.
+ *
+ */
+void vxge_hw_fifo_txdl_free(struct __vxge_hw_fifo *fifo, void *txdlh)
+{
+	struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+	u32 max_frags;
+	struct __vxge_hw_channel *channel;
+
+	channel = &fifo->channel;
+
+	txdl_priv = __vxge_hw_fifo_txdl_priv(fifo,
+			(struct vxge_hw_fifo_txd *)txdlh);
+
+	max_frags = fifo->config->max_frags;
+
+	vxge_hw_channel_dtr_free(channel, txdlh);
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_add - Add the mac address entry for this vpath
+ *               to MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: MAC address to be added for this vpath into the list
+ * @macaddr_mask: MAC address mask for macaddr
+ * @duplicate_mode: Duplicate MAC address add mode. Please see
+ *             enum vxge_hw_vpath_mac_addr_add_mode{}
+ *
+ * Adds the given mac address and mac address mask into the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_delete, vxge_hw_vpath_mac_addr_get and
+ * vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_add(
+	struct __vxge_hw_vpath_handle *vp,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN],
+	enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode)
+{
+	u32 i;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		data1 <<= 8;
+		data1 |= (u8)macaddr[i];
+
+		data2 <<= 8;
+		data2 |= (u8)macaddr_mask[i];
+	}
+
+	switch (duplicate_mode) {
+	case VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE:
+		i = 0;
+		break;
+	case VXGE_HW_VPATH_MAC_ADDR_DISCARD_DUPLICATE:
+		i = 1;
+		break;
+	case VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE:
+		i = 2;
+		break;
+	default:
+		i = 0;
+		break;
+	}
+
+	status = __vxge_hw_vpath_rts_table_set(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+			0,
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1),
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2)|
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MODE(i));
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_get - Get the first mac address entry for this vpath
+ *               from MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: First MAC address entry for this vpath in the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Returns the first mac address and mac address mask in the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get(
+	struct __vxge_hw_vpath_handle *vp,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN])
+{
+	u32 i;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_get(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+			0, &data1, &data2);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+
+	data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2);
+
+	for (i = ETH_ALEN; i > 0; i--) {
+		macaddr[i-1] = (u8)(data1 & 0xFF);
+		data1 >>= 8;
+
+		macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+		data2 >>= 8;
+	}
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_get_next - Get the next mac address entry for this
+ * vpath
+ *               from MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: Next MAC address entry for this vpath in the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Returns the next mac address and mac address mask in the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_get
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get_next(
+	struct __vxge_hw_vpath_handle *vp,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN])
+{
+	u32 i;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_get(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+			0, &data1, &data2);
+
+	if (status != VXGE_HW_OK)
+		goto exit;
+
+	data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+
+	data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2);
+
+	for (i = ETH_ALEN; i > 0; i--) {
+		macaddr[i-1] = (u8)(data1 & 0xFF);
+		data1 >>= 8;
+
+		macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+		data2 >>= 8;
+	}
+
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_delete - Delete the mac address entry for this vpath
+ *               to MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: MAC address to be added for this vpath into the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Delete the given mac address and mac address mask into the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_add, vxge_hw_vpath_mac_addr_get and
+ * vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_delete(
+	struct __vxge_hw_vpath_handle *vp,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN])
+{
+	u32 i;
+	u64 data1 = 0ULL;
+	u64 data2 = 0ULL;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		data1 <<= 8;
+		data1 |= (u8)macaddr[i];
+
+		data2 <<= 8;
+		data2 |= (u8)macaddr_mask[i];
+	}
+
+	status = __vxge_hw_vpath_rts_table_set(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+			0,
+			VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1),
+			VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2));
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_add - Add the vlan id entry for this vpath
+ *               to vlan id table.
+ * @vp: Vpath handle.
+ * @vid: vlan id to be added for this vpath into the list
+ *
+ * Adds the given vlan id into the list for this  vpath.
+ * see also: vxge_hw_vpath_vid_delete, vxge_hw_vpath_vid_get and
+ * vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_add(struct __vxge_hw_vpath_handle *vp, u64 vid)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_set(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+			0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0);
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_get - Get the first vid entry for this vpath
+ *               from vlan id table.
+ * @vp: Vpath handle.
+ * @vid: Buffer to return vlan id
+ *
+ * Returns the first vlan id in the list for this vpath.
+ * see also: vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_get(struct __vxge_hw_vpath_handle *vp, u64 *vid)
+{
+	u64 data;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_get(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+			0, vid, &data);
+
+	*vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid);
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_get_next - Get the next vid entry for this vpath
+ *               from vlan id table.
+ * @vp: Vpath handle.
+ * @vid: Buffer to return vlan id
+ *
+ * Returns the next vlan id in the list for this vpath.
+ * see also: vxge_hw_vpath_vid_get
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_get_next(struct __vxge_hw_vpath_handle *vp, u64 *vid)
+{
+	u64 data;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_get(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+			0, vid, &data);
+
+	*vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid);
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_delete - Delete the vlan id entry for this vpath
+ *               to vlan id table.
+ * @vp: Vpath handle.
+ * @vid: vlan id to be added for this vpath into the list
+ *
+ * Adds the given vlan id into the list for this  vpath.
+ * see also: vxge_hw_vpath_vid_add, vxge_hw_vpath_vid_get and
+ * vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_delete(struct __vxge_hw_vpath_handle *vp, u64 vid)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_rts_table_set(vp,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY,
+			VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+			0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0);
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_promisc_enable - Enable promiscuous mode.
+ * @vp: Vpath handle.
+ *
+ * Enable promiscuous mode of Titan-e operation.
+ *
+ * See also: vxge_hw_vpath_promisc_disable().
+ */
+enum vxge_hw_status vxge_hw_vpath_promisc_enable(
+			struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	/* Enable promiscous mode for function 0 only */
+	if (!(vpath->hldev->access_rights &
+		VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM))
+		return VXGE_HW_OK;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	if (!(val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN)) {
+
+		val64 |= VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN |
+			 VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN |
+			 VXGE_HW_RXMAC_VCFG0_BCAST_EN |
+			 VXGE_HW_RXMAC_VCFG0_ALL_VID_EN;
+
+		writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+	}
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_promisc_disable - Disable promiscuous mode.
+ * @vp: Vpath handle.
+ *
+ * Disable promiscuous mode of Titan-e operation.
+ *
+ * See also: vxge_hw_vpath_promisc_enable().
+ */
+enum vxge_hw_status vxge_hw_vpath_promisc_disable(
+			struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	if (val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN) {
+
+		val64 &= ~(VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN |
+			   VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN |
+			   VXGE_HW_RXMAC_VCFG0_ALL_VID_EN);
+
+		writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+	}
+exit:
+	return status;
+}
+
+/*
+ * vxge_hw_vpath_bcast_enable - Enable broadcast
+ * @vp: Vpath handle.
+ *
+ * Enable receiving broadcasts.
+ */
+enum vxge_hw_status vxge_hw_vpath_bcast_enable(
+			struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	if (!(val64 & VXGE_HW_RXMAC_VCFG0_BCAST_EN)) {
+		val64 |= VXGE_HW_RXMAC_VCFG0_BCAST_EN;
+		writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+	}
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_mcast_enable - Enable multicast addresses.
+ * @vp: Vpath handle.
+ *
+ * Enable Titan-e multicast addresses.
+ * Returns: VXGE_HW_OK on success.
+ *
+ */
+enum vxge_hw_status vxge_hw_vpath_mcast_enable(
+			struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	if (!(val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN)) {
+		val64 |= VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN;
+		writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+	}
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_mcast_disable - Disable  multicast addresses.
+ * @vp: Vpath handle.
+ *
+ * Disable Titan-e multicast addresses.
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_ERR_INVALID_HANDLE - Invalid handle
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mcast_disable(struct __vxge_hw_vpath_handle *vp)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath;
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	vpath = vp->vpath;
+
+	val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+	if (val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN) {
+		val64 &= ~VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN;
+		writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+	}
+exit:
+	return status;
+}
+
+/*
+ * __vxge_hw_vpath_alarm_process - Process Alarms.
+ * @vpath: Virtual Path.
+ * @skip_alarms: Do not clear the alarms
+ *
+ * Process vpath alarms.
+ *
+ */
+enum vxge_hw_status __vxge_hw_vpath_alarm_process(
+			struct __vxge_hw_virtualpath *vpath,
+			u32 skip_alarms)
+{
+	u64 val64;
+	u64 alarm_status;
+	u64 pic_status;
+	struct __vxge_hw_device *hldev = NULL;
+	enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN;
+	u64 mask64;
+	struct vxge_hw_vpath_stats_sw_info *sw_stats;
+	struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+	if (vpath == NULL) {
+		alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+			alarm_event);
+		goto out;
+	}
+
+	hldev = vpath->hldev;
+	vp_reg = vpath->vp_reg;
+	alarm_status = readq(&vp_reg->vpath_general_int_status);
+
+	if (alarm_status == VXGE_HW_ALL_FOXES) {
+		alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE,
+			alarm_event);
+		goto out;
+	}
+
+	sw_stats = vpath->sw_stats;
+
+	if (alarm_status & ~(
+		VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT |
+		VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT |
+		VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT |
+		VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) {
+		sw_stats->error_stats.unknown_alarms++;
+
+		alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+			alarm_event);
+		goto out;
+	}
+
+	if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) {
+
+		val64 = readq(&vp_reg->xgmac_vp_int_status);
+
+		if (val64 &
+		VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) {
+
+			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_OK))) ||
+			    ((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(
+				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT,
+					&vp_reg->asic_ntwk_vp_err_mask);
+
+				__vxge_hw_device_handle_link_down_ind(hldev);
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_LINK_DOWN, alarm_event);
+			}
+
+			if (((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_FLT_OCCURR)
+			))) {
+
+				sw_stats->error_stats.network_sustained_ok++;
+
+				writeq(
+				VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK,
+					&vp_reg->asic_ntwk_vp_err_mask);
+
+				__vxge_hw_device_handle_link_up_ind(hldev);
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_LINK_UP, alarm_event);
+			}
+
+			writeq(VXGE_HW_INTR_MASK_ALL,
+				&vp_reg->asic_ntwk_vp_err_reg);
+
+			alarm_event = VXGE_HW_SET_LEVEL(
+				VXGE_HW_EVENT_ALARM_CLEARED, alarm_event);
+
+			if (skip_alarms)
+				return VXGE_HW_OK;
+		}
+	}
+
+	if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) {
+
+		pic_status = readq(&vp_reg->vpath_ppif_int_status);
+
+		if (pic_status &
+		    VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) {
+
+			val64 = readq(&vp_reg->general_errors_reg);
+			mask64 = readq(&vp_reg->general_errors_mask);
+
+			if ((val64 &
+				VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) &
+				~mask64) {
+				sw_stats->error_stats.ini_serr_det++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_SERR, alarm_event);
+			}
+
+			if ((val64 &
+			    VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) &
+				~mask64) {
+				sw_stats->error_stats.dblgen_fifo0_overflow++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_FIFO_ERR, alarm_event);
+			}
+
+			if ((val64 &
+			    VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) &
+				~mask64)
+				sw_stats->error_stats.statsb_pif_chain_error++;
+
+			if ((val64 &
+			   VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) &
+				~mask64)
+				sw_stats->error_stats.statsb_drop_timeout++;
+
+			if ((val64 &
+				VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) &
+				~mask64)
+				sw_stats->error_stats.target_illegal_access++;
+
+			if (!skip_alarms) {
+				writeq(VXGE_HW_INTR_MASK_ALL,
+					&vp_reg->general_errors_reg);
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_ALARM_CLEARED,
+					alarm_event);
+			}
+		}
+
+		if (pic_status &
+		    VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) {
+
+			val64 = readq(&vp_reg->kdfcctl_errors_reg);
+			mask64 = readq(&vp_reg->kdfcctl_errors_mask);
+
+			if ((val64 &
+			    VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) &
+				~mask64) {
+				sw_stats->error_stats.kdfcctl_fifo0_overwrite++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_FIFO_ERR,
+					alarm_event);
+			}
+
+			if ((val64 &
+			    VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) &
+				~mask64) {
+				sw_stats->error_stats.kdfcctl_fifo0_poison++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_FIFO_ERR,
+					alarm_event);
+			}
+
+			if ((val64 &
+			    VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) &
+				~mask64) {
+				sw_stats->error_stats.kdfcctl_fifo0_dma_error++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_FIFO_ERR,
+					alarm_event);
+			}
+
+			if (!skip_alarms) {
+				writeq(VXGE_HW_INTR_MASK_ALL,
+					&vp_reg->kdfcctl_errors_reg);
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_ALARM_CLEARED,
+					alarm_event);
+			}
+		}
+
+	}
+
+	if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) {
+
+		val64 = readq(&vp_reg->wrdma_alarm_status);
+
+		if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) {
+
+			val64 = readq(&vp_reg->prc_alarm_reg);
+			mask64 = readq(&vp_reg->prc_alarm_mask);
+
+			if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)&
+				~mask64)
+				sw_stats->error_stats.prc_ring_bumps++;
+
+			if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) &
+				~mask64) {
+				sw_stats->error_stats.prc_rxdcm_sc_err++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_VPATH_ERR,
+					alarm_event);
+			}
+
+			if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT)
+				& ~mask64) {
+				sw_stats->error_stats.prc_rxdcm_sc_abort++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+						VXGE_HW_EVENT_VPATH_ERR,
+						alarm_event);
+			}
+
+			if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR)
+				 & ~mask64) {
+				sw_stats->error_stats.prc_quanta_size_err++;
+
+				alarm_event = VXGE_HW_SET_LEVEL(
+					VXGE_HW_EVENT_VPATH_ERR,
+					alarm_event);
+			}
+
+			if (!skip_alarms) {
+				writeq(VXGE_HW_INTR_MASK_ALL,
+					&vp_reg->prc_alarm_reg);
+				alarm_event = VXGE_HW_SET_LEVEL(
+						VXGE_HW_EVENT_ALARM_CLEARED,
+						alarm_event);
+			}
+		}
+	}
+out:
+	hldev->stats.sw_dev_err_stats.vpath_alarms++;
+
+	if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
+		(alarm_event == VXGE_HW_EVENT_UNKNOWN))
+		return VXGE_HW_OK;
+
+	__vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event);
+
+	if (alarm_event == VXGE_HW_EVENT_SERR)
+		return VXGE_HW_ERR_CRITICAL;
+
+	return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ?
+		VXGE_HW_ERR_SLOT_FREEZE :
+		(alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO :
+		VXGE_HW_ERR_VPATH;
+}
+
+/*
+ * vxge_hw_vpath_alarm_process - Process Alarms.
+ * @vpath: Virtual Path.
+ * @skip_alarms: Do not clear the alarms
+ *
+ * Process vpath alarms.
+ *
+ */
+enum vxge_hw_status vxge_hw_vpath_alarm_process(
+			struct __vxge_hw_vpath_handle *vp,
+			u32 skip_alarms)
+{
+	enum vxge_hw_status status = VXGE_HW_OK;
+
+	if (vp == NULL) {
+		status = VXGE_HW_ERR_INVALID_HANDLE;
+		goto exit;
+	}
+
+	status = __vxge_hw_vpath_alarm_process(vp->vpath, skip_alarms);
+exit:
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_msix_set - Associate MSIX vectors with TIM interrupts and
+ *                            alrms
+ * @vp: Virtual Path handle.
+ * @tim_msix_id: MSIX vectors associated with VXGE_HW_MAX_INTR_PER_VP number of
+ *             interrupts(Can be repeated). If fifo or ring are not enabled
+ *             the MSIX vector for that should be set to 0
+ * @alarm_msix_id: MSIX vector for alarm.
+ *
+ * This API will associate a given MSIX vector numbers with the four TIM
+ * interrupts and alarm interrupt.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_msix_set(struct __vxge_hw_vpath_handle *vp, int *tim_msix_id,
+		       int alarm_msix_id)
+{
+	u64 val64;
+	struct __vxge_hw_virtualpath *vpath = vp->vpath;
+	struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
+	u32 first_vp_id = vpath->hldev->first_vp_id;
+
+	val64 =  VXGE_HW_INTERRUPT_CFG0_GROUP0_MSIX_FOR_TXTI(
+		  (first_vp_id * 4) + tim_msix_id[0]) |
+		 VXGE_HW_INTERRUPT_CFG0_GROUP1_MSIX_FOR_TXTI(
+		  (first_vp_id * 4) + tim_msix_id[1]) |
+		 VXGE_HW_INTERRUPT_CFG0_GROUP2_MSIX_FOR_TXTI(
+			(first_vp_id * 4) + tim_msix_id[2]);
+
+		val64 |= VXGE_HW_INTERRUPT_CFG0_GROUP3_MSIX_FOR_TXTI(
+			(first_vp_id * 4) + tim_msix_id[3]);
+
+	writeq(val64, &vp_reg->interrupt_cfg0);
+
+	writeq(VXGE_HW_INTERRUPT_CFG2_ALARM_MAP_TO_MSG(
+			(first_vp_id * 4) + alarm_msix_id),
+			&vp_reg->interrupt_cfg2);
+
+	if (vpath->hldev->config.intr_mode ==
+					VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+		__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+				VXGE_HW_ONE_SHOT_VECT1_EN_ONE_SHOT_VECT1_EN,
+				0, 32), &vp_reg->one_shot_vect1_en);
+	}
+
+	if (vpath->hldev->config.intr_mode ==
+		VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+		__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+				VXGE_HW_ONE_SHOT_VECT2_EN_ONE_SHOT_VECT2_EN,
+				0, 32), &vp_reg->one_shot_vect2_en);
+
+		__vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+				VXGE_HW_ONE_SHOT_VECT3_EN_ONE_SHOT_VECT3_EN,
+				0, 32), &vp_reg->one_shot_vect3_en);
+	}
+
+	return VXGE_HW_OK;
+}
+
+/**
+ * vxge_hw_vpath_msix_mask - Mask MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id:  MSIX ID
+ *
+ * The function masks the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+	struct __vxge_hw_device *hldev = vp->vpath->hldev;
+	__vxge_hw_pio_mem_write32_upper(
+		(u32) vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+			(msix_id  / 4)), 0, 32),
+		&hldev->common_reg->set_msix_mask_vect[msix_id % 4]);
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_msix_clear - Clear MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id:  MSI ID
+ *
+ * The function clears the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+	struct __vxge_hw_device *hldev = vp->vpath->hldev;
+	if (hldev->config.intr_mode ==
+			VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+		__vxge_hw_pio_mem_write32_upper(
+			(u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+				(msix_id/4)), 0, 32),
+				&hldev->common_reg->
+					clr_msix_one_shot_vec[msix_id%4]);
+	} else {
+		__vxge_hw_pio_mem_write32_upper(
+			(u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+				(msix_id/4)), 0, 32),
+				&hldev->common_reg->
+					clear_msix_mask_vect[msix_id%4]);
+	}
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_msix_unmask - Unmask the MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id:  MSI ID
+ *
+ * The function unmasks the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_unmask(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+	struct __vxge_hw_device *hldev = vp->vpath->hldev;
+	__vxge_hw_pio_mem_write32_upper(
+			(u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+			(msix_id/4)), 0, 32),
+			&hldev->common_reg->clear_msix_mask_vect[msix_id%4]);
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_msix_mask_all - Mask all MSIX vectors for the vpath.
+ * @vp: Virtual Path handle.
+ *
+ * The function masks all msix interrupt for the given vpath
+ *
+ */
+void
+vxge_hw_vpath_msix_mask_all(struct __vxge_hw_vpath_handle *vp)
+{
+
+	__vxge_hw_pio_mem_write32_upper(
+		(u32)vxge_bVALn(vxge_mBIT(vp->vpath->vp_id), 0, 32),
+		&vp->vpath->hldev->common_reg->set_msix_mask_all_vect);
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_inta_mask_tx_rx - Mask Tx and Rx interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Mask Tx and Rx vpath interrupts.
+ *
+ * See also: vxge_hw_vpath_inta_mask_tx_rx()
+ */
+void vxge_hw_vpath_inta_mask_tx_rx(struct __vxge_hw_vpath_handle *vp)
+{
+	u64	tim_int_mask0[4] = {[0 ...3] = 0};
+	u32	tim_int_mask1[4] = {[0 ...3] = 0};
+	u64	val64;
+	struct __vxge_hw_device *hldev = vp->vpath->hldev;
+
+	VXGE_HW_DEVICE_TIM_INT_MASK_SET(tim_int_mask0,
+		tim_int_mask1, vp->vpath->vp_id);
+
+	val64 = readq(&hldev->common_reg->tim_int_mask0);
+
+	if ((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+		(tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		writeq((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+			tim_int_mask0[VXGE_HW_VPATH_INTR_RX] | val64),
+			&hldev->common_reg->tim_int_mask0);
+	}
+
+	val64 = readl(&hldev->common_reg->tim_int_mask1);
+
+	if ((tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+		(tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		__vxge_hw_pio_mem_write32_upper(
+			(tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+			tim_int_mask1[VXGE_HW_VPATH_INTR_RX] | val64),
+			&hldev->common_reg->tim_int_mask1);
+	}
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_inta_unmask_tx_rx - Unmask Tx and Rx interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Unmask Tx and Rx vpath interrupts.
+ *
+ * See also: vxge_hw_vpath_inta_mask_tx_rx()
+ */
+void vxge_hw_vpath_inta_unmask_tx_rx(struct __vxge_hw_vpath_handle *vp)
+{
+	u64	tim_int_mask0[4] = {[0 ...3] = 0};
+	u32	tim_int_mask1[4] = {[0 ...3] = 0};
+	u64	val64;
+	struct __vxge_hw_device *hldev = vp->vpath->hldev;
+
+	VXGE_HW_DEVICE_TIM_INT_MASK_SET(tim_int_mask0,
+		tim_int_mask1, vp->vpath->vp_id);
+
+	val64 = readq(&hldev->common_reg->tim_int_mask0);
+
+	if ((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+	   (tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		writeq((~(tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+			tim_int_mask0[VXGE_HW_VPATH_INTR_RX])) & val64,
+			&hldev->common_reg->tim_int_mask0);
+	}
+
+	if ((tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+	   (tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+		__vxge_hw_pio_mem_write32_upper(
+			(~(tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+			  tim_int_mask1[VXGE_HW_VPATH_INTR_RX])) & val64,
+			&hldev->common_reg->tim_int_mask1);
+	}
+
+	return;
+}
+
+/**
+ * vxge_hw_vpath_poll_rx - Poll Rx Virtual Path for completed
+ * descriptors and process the same.
+ * @ring: Handle to the ring object used for receive
+ *
+ * The function	polls the Rx for the completed	descriptors and	calls
+ * the driver via supplied completion	callback.
+ *
+ * Returns: VXGE_HW_OK, if the polling is completed successful.
+ * VXGE_HW_COMPLETIONS_REMAIN: There are still more completed
+ * descriptors available which are yet to be processed.
+ *
+ * See also: vxge_hw_vpath_poll_rx()
+ */
+enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring)
+{
+	u8 t_code;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	void *first_rxdh;
+	u64 val64 = 0;
+	int new_count = 0;
+
+	ring->cmpl_cnt = 0;
+
+	status = vxge_hw_ring_rxd_next_completed(ring, &first_rxdh, &t_code);
+	if (status == VXGE_HW_OK)
+		ring->callback(ring, first_rxdh,
+			t_code, ring->channel.userdata);
+
+	if (ring->cmpl_cnt != 0) {
+		ring->doorbell_cnt += ring->cmpl_cnt;
+		if (ring->doorbell_cnt >= ring->rxds_limit) {
+			/*
+			 * Each RxD is of 4 qwords, update the number of
+			 * qwords replenished
+			 */
+			new_count = (ring->doorbell_cnt * 4);
+
+			/* For each block add 4 more qwords */
+			ring->total_db_cnt += ring->doorbell_cnt;
+			if (ring->total_db_cnt >= ring->rxds_per_block) {
+				new_count += 4;
+				/* Reset total count */
+				ring->total_db_cnt %= ring->rxds_per_block;
+			}
+			writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(new_count),
+				&ring->vp_reg->prc_rxd_doorbell);
+			val64 =
+			  readl(&ring->common_reg->titan_general_int_status);
+			ring->doorbell_cnt = 0;
+		}
+	}
+
+	return status;
+}
+
+/**
+ * vxge_hw_vpath_poll_tx - Poll Tx for completed descriptors and process
+ * the same.
+ * @fifo: Handle to the fifo object used for non offload send
+ *
+ * The function	polls the Tx for the completed	descriptors and	calls
+ * the driver via supplied completion callback.
+ *
+ * Returns: VXGE_HW_OK, if the polling is completed successful.
+ * VXGE_HW_COMPLETIONS_REMAIN: There are still more completed
+ * descriptors available which are yet to be processed.
+ *
+ * See also: vxge_hw_vpath_poll_tx().
+ */
+enum vxge_hw_status vxge_hw_vpath_poll_tx(struct __vxge_hw_fifo *fifo,
+					void **skb_ptr)
+{
+	enum vxge_hw_fifo_tcode t_code;
+	void *first_txdlh;
+	enum vxge_hw_status status = VXGE_HW_OK;
+	struct __vxge_hw_channel *channel;
+
+	channel = &fifo->channel;
+
+	status = vxge_hw_fifo_txdl_next_completed(fifo,
+				&first_txdlh, &t_code);
+	if (status == VXGE_HW_OK)
+		if (fifo->callback(fifo, first_txdlh,
+			t_code, channel->userdata, skb_ptr) != VXGE_HW_OK)
+			status = VXGE_HW_COMPLETIONS_REMAIN;
+
+	return status;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-traffic.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-traffic.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-traffic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-traffic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2409 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-traffic.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                 Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_TRAFFIC_H
+#define VXGE_TRAFFIC_H
+
+#include "vxge-reg.h"
+#include "vxge-version.h"
+
+#define VXGE_HW_DTR_MAX_T_CODE		16
+#define VXGE_HW_ALL_FOXES		0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_INTR_MASK_ALL		0xFFFFFFFFFFFFFFFFULL
+#define	VXGE_HW_MAX_VIRTUAL_PATHS	17
+
+#define VXGE_HW_MAC_MAX_MAC_PORT_ID	2
+
+#define VXGE_HW_DEFAULT_32		0xffffffff
+/* frames sizes */
+#define VXGE_HW_HEADER_802_2_SIZE	3
+#define VXGE_HW_HEADER_SNAP_SIZE	5
+#define VXGE_HW_HEADER_VLAN_SIZE	4
+#define VXGE_HW_MAC_HEADER_MAX_SIZE \
+			(ETH_HLEN + \
+			VXGE_HW_HEADER_802_2_SIZE + \
+			VXGE_HW_HEADER_VLAN_SIZE + \
+			VXGE_HW_HEADER_SNAP_SIZE)
+
+#define VXGE_HW_TCPIP_HEADER_MAX_SIZE	(64 + 64)
+
+/* 32bit alignments */
+#define VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN		2
+#define VXGE_HW_HEADER_802_2_SNAP_ALIGN			2
+#define VXGE_HW_HEADER_802_2_ALIGN			3
+#define VXGE_HW_HEADER_SNAP_ALIGN			1
+
+#define VXGE_HW_L3_CKSUM_OK				0xFFFF
+#define VXGE_HW_L4_CKSUM_OK				0xFFFF
+
+/* Forward declarations */
+struct __vxge_hw_device;
+struct __vxge_hw_vpath_handle;
+struct vxge_hw_vp_config;
+struct __vxge_hw_virtualpath;
+struct __vxge_hw_channel;
+struct __vxge_hw_fifo;
+struct __vxge_hw_ring;
+struct vxge_hw_ring_attr;
+struct vxge_hw_mempool;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*VXGE_HW_STATUS_H*/
+
+#define VXGE_HW_EVENT_BASE			0
+#define VXGE_LL_EVENT_BASE			100
+
+/**
+ * enum vxge_hw_event- Enumerates slow-path HW events.
+ * @VXGE_HW_EVENT_UNKNOWN: Unknown (and invalid) event.
+ * @VXGE_HW_EVENT_SERR: Serious vpath hardware error event.
+ * @VXGE_HW_EVENT_ECCERR: vpath ECC error event.
+ * @VXGE_HW_EVENT_VPATH_ERR: Error local to the respective vpath
+ * @VXGE_HW_EVENT_FIFO_ERR: FIFO Doorbell fifo error.
+ * @VXGE_HW_EVENT_SRPCIM_SERR: srpcim hardware error event.
+ * @VXGE_HW_EVENT_MRPCIM_SERR: mrpcim hardware error event.
+ * @VXGE_HW_EVENT_MRPCIM_ECCERR: mrpcim ecc error event.
+ * @VXGE_HW_EVENT_RESET_START: Privileged entity is starting device reset
+ * @VXGE_HW_EVENT_RESET_COMPLETE: Device reset has been completed
+ * @VXGE_HW_EVENT_SLOT_FREEZE: Slot-freeze event. Driver tries to distinguish
+ * slot-freeze from the rest critical events (e.g. ECC) when it is
+ * impossible to PIO read "through" the bus, i.e. when getting all-foxes.
+ *
+ * enum vxge_hw_event enumerates slow-path HW eventis.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_up_f{},
+ * vxge_uld_link_down_f{}.
+ */
+enum vxge_hw_event {
+	VXGE_HW_EVENT_UNKNOWN		= 0,
+	/* HW events */
+	VXGE_HW_EVENT_RESET_START	= VXGE_HW_EVENT_BASE + 1,
+	VXGE_HW_EVENT_RESET_COMPLETE	= VXGE_HW_EVENT_BASE + 2,
+	VXGE_HW_EVENT_LINK_DOWN		= VXGE_HW_EVENT_BASE + 3,
+	VXGE_HW_EVENT_LINK_UP		= VXGE_HW_EVENT_BASE + 4,
+	VXGE_HW_EVENT_ALARM_CLEARED	= VXGE_HW_EVENT_BASE + 5,
+	VXGE_HW_EVENT_ECCERR		= VXGE_HW_EVENT_BASE + 6,
+	VXGE_HW_EVENT_MRPCIM_ECCERR	= VXGE_HW_EVENT_BASE + 7,
+	VXGE_HW_EVENT_FIFO_ERR		= VXGE_HW_EVENT_BASE + 8,
+	VXGE_HW_EVENT_VPATH_ERR		= VXGE_HW_EVENT_BASE + 9,
+	VXGE_HW_EVENT_CRITICAL_ERR	= VXGE_HW_EVENT_BASE + 10,
+	VXGE_HW_EVENT_SERR		= VXGE_HW_EVENT_BASE + 11,
+	VXGE_HW_EVENT_SRPCIM_SERR	= VXGE_HW_EVENT_BASE + 12,
+	VXGE_HW_EVENT_MRPCIM_SERR	= VXGE_HW_EVENT_BASE + 13,
+	VXGE_HW_EVENT_SLOT_FREEZE	= VXGE_HW_EVENT_BASE + 14,
+};
+
+#define VXGE_HW_SET_LEVEL(a, b) (((a) > (b)) ? (a) : (b))
+
+/*
+ * struct vxge_hw_mempool_dma - Represents DMA objects passed to the
+	caller.
+ */
+struct vxge_hw_mempool_dma {
+	dma_addr_t			addr;
+	struct pci_dev *handle;
+	struct pci_dev *acc_handle;
+};
+
+/*
+ * vxge_hw_mempool_item_f  - Mempool item alloc/free callback
+ * @mempoolh: Memory pool handle.
+ * @memblock: Address of memory block
+ * @memblock_index: Index of memory block
+ * @item: Item that gets allocated or freed.
+ * @index: Item's index in the memory pool.
+ * @is_last: True, if this item is the last one in the pool; false - otherwise.
+ * userdata: Per-pool user context.
+ *
+ * Memory pool allocation/deallocation callback.
+ */
+
+/*
+ * struct vxge_hw_mempool - Memory pool.
+ */
+struct vxge_hw_mempool {
+
+	void (*item_func_alloc)(
+	struct vxge_hw_mempool *mempoolh,
+	u32			memblock_index,
+	struct vxge_hw_mempool_dma	*dma_object,
+	u32			index,
+	u32			is_last);
+
+	void		*userdata;
+	void		**memblocks_arr;
+	void		**memblocks_priv_arr;
+	struct vxge_hw_mempool_dma	*memblocks_dma_arr;
+	struct __vxge_hw_device *devh;
+	u32			memblock_size;
+	u32			memblocks_max;
+	u32			memblocks_allocated;
+	u32			item_size;
+	u32			items_max;
+	u32			items_initial;
+	u32			items_current;
+	u32			items_per_memblock;
+	void		**items_arr;
+	u32			items_priv_size;
+};
+
+#define	VXGE_HW_MAX_INTR_PER_VP				4
+#define	VXGE_HW_VPATH_INTR_TX				0
+#define	VXGE_HW_VPATH_INTR_RX				1
+#define	VXGE_HW_VPATH_INTR_EINTA			2
+#define	VXGE_HW_VPATH_INTR_BMAP				3
+
+#define VXGE_HW_BLOCK_SIZE				4096
+
+/**
+ * struct vxge_hw_tim_intr_config - Titan Tim interrupt configuration.
+ * @intr_enable: Set to 1, if interrupt is enabled.
+ * @btimer_val: Boundary Timer Initialization value in units of 272 ns.
+ * @timer_ac_en: Timer Automatic Cancel. 1 : Automatic Canceling Enable: when
+ *             asserted, other interrupt-generating entities will cancel the
+ *             scheduled timer interrupt.
+ * @timer_ci_en: Timer Continuous Interrupt. 1 : Continuous Interrupting Enable:
+ *             When asserted, an interrupt will be generated every time the
+ *             boundary timer expires, even if no traffic has been transmitted
+ *             on this interrupt.
+ * @timer_ri_en: Timer Consecutive (Re-) Interrupt 1 : Consecutive
+ *             (Re-) Interrupt Enable: When asserted, an interrupt will be
+ *             generated the next time the timer expires, even if no traffic has
+ *             been transmitted on this interrupt. (This will only happen once
+ *             each time that this value is written to the TIM.) This bit is
+ *             cleared by H/W at the end of the current-timer-interval when
+ *             the interrupt is triggered.
+ * @rtimer_val: Restriction Timer Initialization value in units of 272 ns.
+ * @util_sel: Utilization Selector. Selects which of the workload approximations
+ *             to use (e.g. legacy Tx utilization, Tx/Rx utilization, host
+ *             specified utilization etc.), selects one of
+ *             the 17 host configured values.
+ *             0-Virtual Path 0
+ *             1-Virtual Path 1
+ *             ...
+ *             16-Virtual Path 17
+ *             17-Legacy Tx network utilization, provided by TPA
+ *             18-Legacy Rx network utilization, provided by FAU
+ *             19-Average of legacy Rx and Tx utilization calculated from link
+ *                utilization values.
+ *             20-31-Invalid configurations
+ *             32-Host utilization for Virtual Path 0
+ *             33-Host utilization for Virtual Path 1
+ *             ...
+ *             48-Host utilization for Virtual Path 17
+ *             49-Legacy Tx network utilization, provided by TPA
+ *             50-Legacy Rx network utilization, provided by FAU
+ *             51-Average of legacy Rx and Tx utilization calculated from
+ *                link utilization values.
+ *             52-63-Invalid configurations
+ * @ltimer_val: Latency Timer Initialization Value in units of 272 ns.
+ * @txd_cnt_en: TxD Return Event Count Enable. This configuration bit when set
+ *             to 1 enables counting of TxD0 returns (signalled by PCC's),
+ *             towards utilization event count values.
+ * @urange_a: Defines the upper limit (in percent) for this utilization range
+ *             to be active. This range is considered active
+ *             if 0 = UTIL = URNG_A
+ *             and the UEC_A field (below) is non-zero.
+ * @uec_a: Utilization Event Count A. If this range is active, the adapter will
+ *             wait until UEC_A events have occurred on the interrupt before
+ *             generating an interrupt.
+ * @urange_b: Link utilization range B.
+ * @uec_b: Utilization Event Count B.
+ * @urange_c: Link utilization range C.
+ * @uec_c: Utilization Event Count C.
+ * @urange_d: Link utilization range D.
+ * @uec_d: Utilization Event Count D.
+ * Traffic Interrupt Controller Module interrupt configuration.
+ */
+struct vxge_hw_tim_intr_config {
+
+	u32				intr_enable;
+#define VXGE_HW_TIM_INTR_ENABLE				1
+#define VXGE_HW_TIM_INTR_DISABLE				0
+#define VXGE_HW_TIM_INTR_DEFAULT				0
+
+	u32				btimer_val;
+#define VXGE_HW_MIN_TIM_BTIMER_VAL				0
+#define VXGE_HW_MAX_TIM_BTIMER_VAL				67108864
+#define VXGE_HW_USE_FLASH_DEFAULT				0xffffffff
+
+	u32				timer_ac_en;
+#define VXGE_HW_TIM_TIMER_AC_ENABLE				1
+#define VXGE_HW_TIM_TIMER_AC_DISABLE				0
+
+	u32				timer_ci_en;
+#define VXGE_HW_TIM_TIMER_CI_ENABLE				1
+#define VXGE_HW_TIM_TIMER_CI_DISABLE				0
+
+	u32				timer_ri_en;
+#define VXGE_HW_TIM_TIMER_RI_ENABLE				1
+#define VXGE_HW_TIM_TIMER_RI_DISABLE				0
+
+	u32				rtimer_val;
+#define VXGE_HW_MIN_TIM_RTIMER_VAL				0
+#define VXGE_HW_MAX_TIM_RTIMER_VAL				67108864
+
+	u32				util_sel;
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL		17
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL		18
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_RX_AVE_NET_UTIL		19
+#define VXGE_HW_TIM_UTIL_SEL_PER_VPATH				63
+
+	u32				ltimer_val;
+#define VXGE_HW_MIN_TIM_LTIMER_VAL				0
+#define VXGE_HW_MAX_TIM_LTIMER_VAL				67108864
+
+	/* Line utilization interrupts */
+	u32				urange_a;
+#define VXGE_HW_MIN_TIM_URANGE_A				0
+#define VXGE_HW_MAX_TIM_URANGE_A				100
+
+	u32				uec_a;
+#define VXGE_HW_MIN_TIM_UEC_A					0
+#define VXGE_HW_MAX_TIM_UEC_A					65535
+
+	u32				urange_b;
+#define VXGE_HW_MIN_TIM_URANGE_B				0
+#define VXGE_HW_MAX_TIM_URANGE_B				100
+
+	u32				uec_b;
+#define VXGE_HW_MIN_TIM_UEC_B					0
+#define VXGE_HW_MAX_TIM_UEC_B					65535
+
+	u32				urange_c;
+#define VXGE_HW_MIN_TIM_URANGE_C				0
+#define VXGE_HW_MAX_TIM_URANGE_C				100
+
+	u32				uec_c;
+#define VXGE_HW_MIN_TIM_UEC_C					0
+#define VXGE_HW_MAX_TIM_UEC_C					65535
+
+	u32				uec_d;
+#define VXGE_HW_MIN_TIM_UEC_D					0
+#define VXGE_HW_MAX_TIM_UEC_D					65535
+};
+
+#define	VXGE_HW_STATS_OP_READ					0
+#define	VXGE_HW_STATS_OP_CLEAR_STAT				1
+#define	VXGE_HW_STATS_OP_CLEAR_ALL_VPATH_STATS			2
+#define	VXGE_HW_STATS_OP_CLEAR_ALL_STATS_OF_LOC			2
+#define	VXGE_HW_STATS_OP_CLEAR_ALL_STATS			3
+
+#define	VXGE_HW_STATS_LOC_AGGR					17
+#define VXGE_HW_STATS_AGGRn_OFFSET				0x00720
+
+#define VXGE_HW_STATS_VPATH_TX_OFFSET				0x0
+#define VXGE_HW_STATS_VPATH_RX_OFFSET				0x00090
+
+#define	VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET	   (0x001d0 >> 3)
+#define	VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(bits) \
+						vxge_bVALn(bits, 0, 32)
+
+#define	VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(bits) \
+						vxge_bVALn(bits, 32, 32)
+
+#define	VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET	   (0x001d8 >> 3)
+#define	VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(bits) \
+						vxge_bVALn(bits, 0, 32)
+
+#define	VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(bits) \
+						vxge_bVALn(bits, 32, 32)
+
+/**
+ * struct vxge_hw_xmac_aggr_stats - Per-Aggregator XMAC Statistics
+ *
+ * @tx_frms: Count of data frames transmitted on this Aggregator on all
+ *             its Aggregation ports. Does not include LACPDUs or Marker PDUs.
+ *             However, does include frames discarded by the Distribution
+ *             function.
+ * @tx_data_octets: Count of data and padding octets of frames transmitted
+ *             on this Aggregator on all its Aggregation ports. Does not include
+ *             octets of LACPDUs or Marker PDUs. However, does include octets of
+ *             frames discarded by the Distribution function.
+ * @tx_mcast_frms: Count of data frames transmitted (to a group destination
+ *             address other than the broadcast address) on this Aggregator on
+ *             all its Aggregation ports. Does not include LACPDUs or Marker
+ *             PDUs. However, does include frames discarded by the Distribution
+ *             function.
+ * @tx_bcast_frms: Count of broadcast data frames transmitted on this Aggregator
+ *             on all its Aggregation ports. Does not include LACPDUs or Marker
+ *             PDUs. However, does include frames discarded by the Distribution
+ *             function.
+ * @tx_discarded_frms: Count of data frames to be transmitted on this Aggregator
+ *             that are discarded by the Distribution function. This occurs when
+ *             conversation are allocated to different ports and have to be
+ *             flushed on old ports
+ * @tx_errored_frms: Count of data frames transmitted on this Aggregator that
+ *             experience transmission errors on its Aggregation ports.
+ * @rx_frms: Count of data frames received on this Aggregator on all its
+ *             Aggregation ports. Does not include LACPDUs or Marker PDUs.
+ *             Also, does not include frames discarded by the Collection
+ *             function.
+ * @rx_data_octets: Count of data and padding octets of frames received on this
+ *             Aggregator on all its Aggregation ports. Does not include octets
+ *             of LACPDUs or Marker PDUs. Also, does not include
+ *             octets of frames
+ *             discarded by the Collection function.
+ * @rx_mcast_frms: Count of data frames received (from a group destination
+ *             address other than the broadcast address) on this Aggregator on
+ *             all its Aggregation ports. Does not include LACPDUs or Marker
+ *             PDUs. Also, does not include frames discarded by the Collection
+ *             function.
+ * @rx_bcast_frms: Count of broadcast data frames received on this Aggregator on
+ *             all its Aggregation ports. Does not include LACPDUs or Marker
+ *             PDUs. Also, does not include frames discarded by the Collection
+ *             function.
+ * @rx_discarded_frms: Count of data frames received on this Aggregator that are
+ *             discarded by the Collection function because the Collection
+ *             function was disabled on the port which the frames are received.
+ * @rx_errored_frms: Count of data frames received on this Aggregator that are
+ *             discarded by its Aggregation ports, or are discarded by the
+ *             Collection function of the Aggregator, or that are discarded by
+ *             the Aggregator due to detection of an illegal Slow Protocols PDU.
+ * @rx_unknown_slow_proto_frms: Count of data frames received on this Aggregator
+ *             that are discarded by its Aggregation ports due to detection of
+ *             an unknown Slow Protocols PDU.
+ *
+ * Per aggregator XMAC RX statistics.
+ */
+struct vxge_hw_xmac_aggr_stats {
+/*0x000*/		u64	tx_frms;
+/*0x008*/		u64	tx_data_octets;
+/*0x010*/		u64	tx_mcast_frms;
+/*0x018*/		u64	tx_bcast_frms;
+/*0x020*/		u64	tx_discarded_frms;
+/*0x028*/		u64	tx_errored_frms;
+/*0x030*/		u64	rx_frms;
+/*0x038*/		u64	rx_data_octets;
+/*0x040*/		u64	rx_mcast_frms;
+/*0x048*/		u64	rx_bcast_frms;
+/*0x050*/		u64	rx_discarded_frms;
+/*0x058*/		u64	rx_errored_frms;
+/*0x060*/		u64	rx_unknown_slow_proto_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_port_stats - XMAC Port Statistics
+ *
+ * @tx_ttl_frms: Count of successfully transmitted MAC frames
+ * @tx_ttl_octets: Count of total octets of transmitted frames, not including
+ *            framing characters (i.e. less framing bits). To determine the
+ *            total octets of transmitted frames, including framing characters,
+ *            multiply PORTn_TX_TTL_FRMS by 8 and add it to this stat (unless
+ *            otherwise configured, this stat only counts frames that have
+ *            8 bytes of preamble for each frame). This stat can be configured
+ *            (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count everything
+ *            including the preamble octets.
+ * @tx_data_octets: Count of data and padding octets of successfully transmitted
+ *            frames.
+ * @tx_mcast_frms: Count of successfully transmitted frames to a group address
+ *            other than the broadcast address.
+ * @tx_bcast_frms: Count of successfully transmitted frames to the broadcast
+ *            group address.
+ * @tx_ucast_frms: Count of transmitted frames containing a unicast address.
+ *            Includes discarded frames that are not sent to the network.
+ * @tx_tagged_frms: Count of transmitted frames containing a VLAN tag.
+ * @tx_vld_ip: Count of transmitted IP datagrams that are passed to the network.
+ * @tx_vld_ip_octets: Count of total octets of transmitted IP datagrams that
+ *            are passed to the network.
+ * @tx_icmp: Count of transmitted ICMP messages. Includes messages not sent
+ *            due to problems within ICMP.
+ * @tx_tcp: Count of transmitted TCP segments. Does not include segments
+ *            containing retransmitted octets.
+ * @tx_rst_tcp: Count of transmitted TCP segments containing the RST flag.
+ * @tx_udp: Count of transmitted UDP datagrams.
+ * @tx_parse_error: Increments when the TPA is unable to parse a packet. This
+ *            generally occurs when a packet is corrupt somehow, including
+ *            packets that have IP version mismatches, invalid Layer 2 control
+ *            fields, etc. L3/L4 checksums are not offloaded, but the packet
+ *            is still be transmitted.
+ * @tx_unknown_protocol: Increments when the TPA encounters an unknown
+ *            protocol, such as a new IPv6 extension header, or an unsupported
+ *            Routing Type. The packet still has a checksum calculated but it
+ *            may be incorrect.
+ * @tx_pause_ctrl_frms: Count of MAC PAUSE control frames that are transmitted.
+ *            Since, the only control frames supported by this device are
+ *            PAUSE frames, this register is a count of all transmitted MAC
+ *            control frames.
+ * @tx_marker_pdu_frms: Count of Marker PDUs transmitted
+ * on this Aggregation port.
+ * @tx_lacpdu_frms: Count of LACPDUs transmitted on this Aggregation port.
+ * @tx_drop_ip: Count of transmitted IP datagrams that could not be passed to
+ *            the network. Increments because of:
+ *            1) An internal processing error
+ *            (such as an uncorrectable ECC error). 2) A frame parsing error
+ *            during IP checksum calculation.
+ * @tx_marker_resp_pdu_frms: Count of Marker Response PDUs transmitted on this
+ *            Aggregation port.
+ * @tx_xgmii_char2_match: Maintains a count of the number of transmitted XGMII
+ *            characters that match a pattern that is programmable through
+ *            register XMAC_STATS_TX_XGMII_CHAR_PORTn. By default, the pattern
+ *            is set to /T/ (i.e. the terminate character), thus the statistic
+ *            tracks the number of transmitted Terminate characters.
+ * @tx_xgmii_char1_match: Maintains a count of the number of transmitted XGMII
+ *            characters that match a pattern that is programmable through
+ *            register XMAC_STATS_TX_XGMII_CHAR_PORTn. By default, the pattern
+ *            is set to /S/ (i.e. the start character),
+ *            thus the statistic tracks
+ *            the number of transmitted Start characters.
+ * @tx_xgmii_column2_match: Maintains a count of the number of transmitted XGMII
+ *            columns that match a pattern that is programmable through register
+ *            XMAC_STATS_TX_XGMII_COLUMN2_PORTn. By default, the pattern is set
+ *            to 4 x /E/ (i.e. a column containing all error characters), thus
+ *            the statistic tracks the number of Error columns transmitted at
+ *            any time. If XMAC_STATS_TX_XGMII_BEHAV_COLUMN2_PORTn.NEAR_COL1 is
+ *            set to 1, then this stat increments when COLUMN2 is found within
+ *            'n' clocks after COLUMN1. Here, 'n' is defined by
+ *            XMAC_STATS_TX_XGMII_BEHAV_COLUMN2_PORTn.NUM_COL (if 'n' is set
+ *            to 0, then it means to search anywhere for COLUMN2).
+ * @tx_xgmii_column1_match: Maintains a count of the number of transmitted XGMII
+ *            columns that match a pattern that is programmable through register
+ *            XMAC_STATS_TX_XGMII_COLUMN1_PORTn. By default, the pattern is set
+ *            to 4 x /I/ (i.e. a column containing all idle characters),
+ *            thus the statistic tracks the number of transmitted Idle columns.
+ * @tx_any_err_frms: Count of transmitted frames containing any error that
+ *            prevents them from being passed to the network. Increments if
+ *            there is an ECC while reading the frame out of the transmit
+ *            buffer. Also increments if the transmit protocol assist (TPA)
+ *            block determines that the frame should not be sent.
+ * @tx_drop_frms: Count of frames that could not be sent for no other reason
+ *            than internal MAC processing. Increments once whenever the
+ *            transmit buffer is flushed (due to an ECC error on a memory
+ *            descriptor).
+ * @rx_ttl_frms: Count of total received MAC frames, including frames received
+ *            with frame-too-long, FCS, or length errors. This stat can be
+ *            configured (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count
+ *            everything, even "frames" as small one byte of preamble.
+ * @rx_vld_frms: Count of successfully received MAC frames. Does not include
+ *            frames received with frame-too-long, FCS, or length errors.
+ * @rx_offload_frms: Count of offloaded received frames that are passed to
+ *            the host.
+ * @rx_ttl_octets: Count of total octets of received frames, not including
+ *            framing characters (i.e. less framing bits). To determine the
+ *            total octets of received frames, including framing characters,
+ *            multiply PORTn_RX_TTL_FRMS by 8 and add it to this stat (unless
+ *            otherwise configured, this stat only counts frames that have 8
+ *            bytes of preamble for each frame). This stat can be configured
+ *            (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count everything,
+ *            even the preamble octets of "frames" as small one byte of preamble
+ * @rx_data_octets: Count of data and padding octets of successfully received
+ *            frames. Does not include frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_offload_octets: Count of total octets, not including framing
+ *            characters, of offloaded received frames that are passed
+ *            to the host.
+ * @rx_vld_mcast_frms: Count of successfully received MAC frames containing a
+ *	      nonbroadcast group address. Does not include frames received
+ *            with frame-too-long, FCS, or length errors.
+ * @rx_vld_bcast_frms: Count of successfully received MAC frames containing
+ *            the broadcast group address. Does not include frames received
+ *            with frame-too-long, FCS, or length errors.
+ * @rx_accepted_ucast_frms: Count of successfully received frames containing
+ *            a unicast address. Only includes frames that are passed to
+ *            the system.
+ * @rx_accepted_nucast_frms: Count of successfully received frames containing
+ *            a non-unicast (broadcast or multicast) address. Only includes
+ *            frames that are passed to the system. Could include, for instance,
+ *            non-unicast frames that contain FCS errors if the MAC_ERROR_CFG
+ *            register is set to pass FCS-errored frames to the host.
+ * @rx_tagged_frms: Count of received frames containing a VLAN tag.
+ * @rx_long_frms: Count of received frames that are longer than RX_MAX_PYLD_LEN
+ *            + 18 bytes (+ 22 bytes if VLAN-tagged).
+ * @rx_usized_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) less than 64 octets, that are otherwise well-formed.
+ *            In other words, counts runts.
+ * @rx_osized_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) more than 1518 octets, that are otherwise
+ *            well-formed. Note: If register XMAC_STATS_GLOBAL_CFG.VLAN_HANDLING
+ *            is set to 1, then "more than 1518 octets" becomes "more than 1518
+ *            (1522 if VLAN-tagged) octets".
+ * @rx_frag_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) less than 64 octets that had bad FCS. In other
+ *            words, counts fragments.
+ * @rx_jabber_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) more than 1518 octets that had bad FCS. In other
+ *            words, counts jabbers. Note: If register
+ *            XMAC_STATS_GLOBAL_CFG.VLAN_HANDLING is set to 1, then "more than
+ *            1518 octets" becomes "more than 1518 (1522 if VLAN-tagged)
+ *            octets".
+ * @rx_ttl_64_frms: Count of total received MAC frames with length (including
+ *            FCS, but not framing bits) of exactly 64 octets. Includes frames
+ *            received with frame-too-long, FCS, or length errors.
+ * @rx_ttl_65_127_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 65 and 127
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_128_255_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 128 and 255
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_256_511_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 256 and 511
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_512_1023_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 512 and 1023
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_1024_1518_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 1024 and 1518
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_1519_4095_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 1519 and 4095
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_4096_8191_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 4096 and 8191
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_8192_max_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 8192 and
+ *            RX_MAX_PYLD_LEN+18 octets inclusive. Includes frames received
+ *            with frame-too-long, FCS, or length errors.
+ * @rx_ttl_gt_max_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) exceeding
+ *            RX_MAX_PYLD_LEN+18 (+22 bytes if VLAN-tagged) octets inclusive.
+ *            Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ip: Count of received IP datagrams. Includes errored IP datagrams.
+ * @rx_accepted_ip: Count of received IP datagrams that
+ * 		are passed to the system.
+ * @rx_ip_octets: Count of number of octets in received IP datagrams. Includes
+ *            errored IP datagrams.
+ * @rx_err_ip: 	Count of received IP datagrams containing errors. For example,
+ *            bad IP checksum.
+ * @rx_icmp: Count of received ICMP messages. Includes errored ICMP messages.
+ * @rx_tcp: Count of received TCP segments. Includes errored TCP segments.
+ *            Note: This stat contains a count of all received TCP segments,
+ *            regardless of whether or not they pertain to an established
+ *            connection.
+ * @rx_udp: Count of received UDP datagrams.
+ * @rx_err_tcp: Count of received TCP segments containing errors. For example,
+ *            bad TCP checksum.
+ * @rx_pause_count: Count of number of pause quanta that the MAC has been in
+ *            the paused state. Recall, one pause quantum equates to 512
+ *            bit times.
+ * @rx_pause_ctrl_frms: Count of received MAC PAUSE control frames.
+ * @rx_unsup_ctrl_frms: Count of received MAC control frames that do not
+ *            contain the PAUSE opcode. The sum of RX_PAUSE_CTRL_FRMS and
+ *            this register is a count of all received MAC control frames.
+ *            Note: This stat may be configured to count all layer 2 errors
+ *            (i.e. length errors and FCS errors).
+ * @rx_fcs_err_frms: Count of received MAC frames that do not pass FCS. Does
+ *            not include frames received with frame-too-long or
+ *            frame-too-short error.
+ * @rx_in_rng_len_err_frms: Count of received frames with a length/type field
+ *            value between 46 (42 for VLAN-tagged frames) and 1500 (also 1500
+ *            for VLAN-tagged frames), inclusive, that does not match the
+ *            number of data octets (including pad) received. Also contains
+ *            a count of received frames with a length/type field less than
+ *            46 (42 for VLAN-tagged frames) and the number of data octets
+ *            (including pad) received is greater than 46 (42 for VLAN-tagged
+ *            frames).
+ * @rx_out_rng_len_err_frms:  Count of received frames with length/type field
+ *            between 1501 and 1535 decimal, inclusive.
+ * @rx_drop_frms: Count of received frames that could not be passed to the host.
+ *            See PORTn_RX_L2_MGMT_DISCARD, PORTn_RX_RPA_DISCARD,
+ *            PORTn_RX_TRASH_DISCARD, PORTn_RX_RTS_DISCARD, PORTn_RX_RED_DISCARD
+ *            for a list of reasons. Because the RMAC drops one frame at a time,
+ *            this stat also indicates the number of drop events.
+ * @rx_discarded_frms: Count of received frames containing
+ * 		any error that prevents
+ *            them from being passed to the system. See PORTn_RX_FCS_DISCARD,
+ *            PORTn_RX_LEN_DISCARD, and PORTn_RX_SWITCH_DISCARD for a list of
+ *            reasons.
+ * @rx_drop_ip: Count of received IP datagrams that could not be passed to the
+ *            host. See PORTn_RX_DROP_FRMS for a list of reasons.
+ * @rx_drop_udp: Count of received UDP datagrams that are not delivered to the
+ *            host. See PORTn_RX_DROP_FRMS for a list of reasons.
+ * @rx_marker_pdu_frms: Count of valid Marker PDUs received on this Aggregation
+ *            port.
+ * @rx_lacpdu_frms: Count of valid LACPDUs received on this Aggregation port.
+ * @rx_unknown_pdu_frms: Count of received frames (on this Aggregation port)
+ *            that carry the Slow Protocols EtherType, but contain an unknown
+ *            PDU. Or frames that contain the Slow Protocols group MAC address,
+ *            but do not carry the Slow Protocols EtherType.
+ * @rx_marker_resp_pdu_frms: Count of valid Marker Response PDUs received on
+ *            this Aggregation port.
+ * @rx_fcs_discard: Count of received frames that are discarded because the
+ *            FCS check failed.
+ * @rx_illegal_pdu_frms: Count of received frames (on this Aggregation port)
+ *            that carry the Slow Protocols EtherType, but contain a badly
+ *            formed PDU. Or frames that carry the Slow Protocols EtherType,
+ *            but contain an illegal value of Protocol Subtype.
+ * @rx_switch_discard: Count of received frames that are discarded by the
+ *            internal switch because they did not have an entry in the
+ *            Filtering Database. This includes frames that had an invalid
+ *            destination MAC address or VLAN ID. It also includes frames are
+ *            discarded because they did not satisfy the length requirements
+ *            of the target VPATH.
+ * @rx_len_discard: Count of received frames that are discarded because of an
+ *            invalid frame length (includes fragments, oversized frames and
+ *            mismatch between frame length and length/type field). This stat
+ *            can be configured
+ *            (see XMAC_STATS_GLOBAL_CFG.LEN_DISCARD_HANDLING).
+ * @rx_rpa_discard: Count of received frames that were discarded because the
+ *            receive protocol assist (RPA) discovered and error in the frame
+ *            or was unable to parse the frame.
+ * @rx_l2_mgmt_discard: Count of Layer 2 management frames (eg. pause frames,
+ *            Link Aggregation Control Protocol (LACP) frames, etc.) that are
+ *            discarded.
+ * @rx_rts_discard: Count of received frames that are discarded by the receive
+ *            traffic steering (RTS) logic. Includes those frame discarded
+ *            because the SSC response contradicted the switch table, because
+ *            the SSC timed out, or because the target queue could not fit the
+ *            frame.
+ * @rx_trash_discard: Count of received frames that are discarded because
+ *            receive traffic steering (RTS) steered the frame to the trash
+ *            queue.
+ * @rx_buff_full_discard: Count of received frames that are discarded because
+ *            internal buffers are full. Includes frames discarded because the
+ *            RTS logic is waiting for an SSC lookup that has no timeout bound.
+ *            Also, includes frames that are dropped because the MAC2FAU buffer
+ *            is nearly full -- this can happen if the external receive buffer
+ *            is full and the receive path is backing up.
+ * @rx_red_discard: Count of received frames that are discarded because of RED
+ *            (Random Early Discard).
+ * @rx_xgmii_ctrl_err_cnt: Maintains a count of unexpected or misplaced control
+ *            characters occuring between times of normal data transmission
+ *            (i.e. not included in RX_XGMII_DATA_ERR_CNT). This counter is
+ *            incremented when either -
+ *            1) The Reconciliation Sublayer (RS) is expecting one control
+ *               character and gets another (i.e. is expecting a Start
+ *               character, but gets another control character).
+ *            2) Start control character is not in lane 0
+ *            Only increments the count by one for each XGMII column.
+ * @rx_xgmii_data_err_cnt: Maintains a count of unexpected control characters
+ *            during normal data transmission. If the Reconciliation Sublayer
+ *            (RS) receives a control character, other than a terminate control
+ *            character, during receipt of data octets then this register is
+ *            incremented. Also increments if the start frame delimiter is not
+ *            found in the correct location. Only increments the count by one
+ *            for each XGMII column.
+ * @rx_xgmii_char1_match: Maintains a count of the number of XGMII characters
+ *            that match a pattern that is programmable through register
+ *            XMAC_STATS_RX_XGMII_CHAR_PORTn. By default, the pattern is set
+ *            to /E/ (i.e. the error character), thus the statistic tracks the
+ *            number of Error characters received at any time.
+ * @rx_xgmii_err_sym: Count of the number of symbol errors in the received
+ *            XGMII data (i.e. PHY indicates "Receive Error" on the XGMII).
+ *            Only includes symbol errors that are observed between the XGMII
+ *            Start Frame Delimiter and End Frame Delimiter, inclusive. And
+ *            only increments the count by one for each frame.
+ * @rx_xgmii_column1_match: Maintains a count of the number of XGMII columns
+ *            that match a pattern that is programmable through register
+ *            XMAC_STATS_RX_XGMII_COLUMN1_PORTn. By default, the pattern is set
+ *            to 4 x /E/ (i.e. a column containing all error characters), thus
+ *            the statistic tracks the number of Error columns received at any
+ *            time.
+ * @rx_xgmii_char2_match: Maintains a count of the number of XGMII characters
+ *            that match a pattern that is programmable through register
+ *            XMAC_STATS_RX_XGMII_CHAR_PORTn. By default, the pattern is set
+ *            to /E/ (i.e. the error character), thus the statistic tracks the
+ *            number of Error characters received at any time.
+ * @rx_local_fault: Maintains a count of the number of times that link
+ *            transitioned from "up" to "down" due to a local fault.
+ * @rx_xgmii_column2_match: Maintains a count of the number of XGMII columns
+ *            that match a pattern that is programmable through register
+ *            XMAC_STATS_RX_XGMII_COLUMN2_PORTn. By default, the pattern is set
+ *            to 4 x /E/ (i.e. a column containing all error characters), thus
+ *            the statistic tracks the number of Error columns received at any
+ *            time. If XMAC_STATS_RX_XGMII_BEHAV_COLUMN2_PORTn.NEAR_COL1 is set
+ *            to 1, then this stat increments when COLUMN2 is found within 'n'
+ *            clocks after COLUMN1. Here, 'n' is defined by
+ *            XMAC_STATS_RX_XGMII_BEHAV_COLUMN2_PORTn.NUM_COL (if 'n' is set to
+ *            0, then it means to search anywhere for COLUMN2).
+ * @rx_jettison: Count of received frames that are jettisoned because internal
+ *            buffers are full.
+ * @rx_remote_fault: Maintains a count of the number of times that link
+ *            transitioned from "up" to "down" due to a remote fault.
+ *
+ * XMAC Port Statistics.
+ */
+struct vxge_hw_xmac_port_stats {
+/*0x000*/		u64	tx_ttl_frms;
+/*0x008*/		u64	tx_ttl_octets;
+/*0x010*/		u64	tx_data_octets;
+/*0x018*/		u64	tx_mcast_frms;
+/*0x020*/		u64	tx_bcast_frms;
+/*0x028*/		u64	tx_ucast_frms;
+/*0x030*/		u64	tx_tagged_frms;
+/*0x038*/		u64	tx_vld_ip;
+/*0x040*/		u64	tx_vld_ip_octets;
+/*0x048*/		u64	tx_icmp;
+/*0x050*/		u64	tx_tcp;
+/*0x058*/		u64	tx_rst_tcp;
+/*0x060*/		u64	tx_udp;
+/*0x068*/		u32	tx_parse_error;
+/*0x06c*/		u32	tx_unknown_protocol;
+/*0x070*/		u64	tx_pause_ctrl_frms;
+/*0x078*/		u32	tx_marker_pdu_frms;
+/*0x07c*/		u32	tx_lacpdu_frms;
+/*0x080*/		u32	tx_drop_ip;
+/*0x084*/		u32	tx_marker_resp_pdu_frms;
+/*0x088*/		u32	tx_xgmii_char2_match;
+/*0x08c*/		u32	tx_xgmii_char1_match;
+/*0x090*/		u32	tx_xgmii_column2_match;
+/*0x094*/		u32	tx_xgmii_column1_match;
+/*0x098*/		u32	unused1;
+/*0x09c*/		u16	tx_any_err_frms;
+/*0x09e*/		u16	tx_drop_frms;
+/*0x0a0*/		u64	rx_ttl_frms;
+/*0x0a8*/		u64	rx_vld_frms;
+/*0x0b0*/		u64	rx_offload_frms;
+/*0x0b8*/		u64	rx_ttl_octets;
+/*0x0c0*/		u64	rx_data_octets;
+/*0x0c8*/		u64	rx_offload_octets;
+/*0x0d0*/		u64	rx_vld_mcast_frms;
+/*0x0d8*/		u64	rx_vld_bcast_frms;
+/*0x0e0*/		u64	rx_accepted_ucast_frms;
+/*0x0e8*/		u64	rx_accepted_nucast_frms;
+/*0x0f0*/		u64	rx_tagged_frms;
+/*0x0f8*/		u64	rx_long_frms;
+/*0x100*/		u64	rx_usized_frms;
+/*0x108*/		u64	rx_osized_frms;
+/*0x110*/		u64	rx_frag_frms;
+/*0x118*/		u64	rx_jabber_frms;
+/*0x120*/		u64	rx_ttl_64_frms;
+/*0x128*/		u64	rx_ttl_65_127_frms;
+/*0x130*/		u64	rx_ttl_128_255_frms;
+/*0x138*/		u64	rx_ttl_256_511_frms;
+/*0x140*/		u64	rx_ttl_512_1023_frms;
+/*0x148*/		u64	rx_ttl_1024_1518_frms;
+/*0x150*/		u64	rx_ttl_1519_4095_frms;
+/*0x158*/		u64	rx_ttl_4096_8191_frms;
+/*0x160*/		u64	rx_ttl_8192_max_frms;
+/*0x168*/		u64	rx_ttl_gt_max_frms;
+/*0x170*/		u64	rx_ip;
+/*0x178*/		u64	rx_accepted_ip;
+/*0x180*/		u64	rx_ip_octets;
+/*0x188*/		u64	rx_err_ip;
+/*0x190*/		u64	rx_icmp;
+/*0x198*/		u64	rx_tcp;
+/*0x1a0*/		u64	rx_udp;
+/*0x1a8*/		u64	rx_err_tcp;
+/*0x1b0*/		u64	rx_pause_count;
+/*0x1b8*/		u64	rx_pause_ctrl_frms;
+/*0x1c0*/		u64	rx_unsup_ctrl_frms;
+/*0x1c8*/		u64	rx_fcs_err_frms;
+/*0x1d0*/		u64	rx_in_rng_len_err_frms;
+/*0x1d8*/		u64	rx_out_rng_len_err_frms;
+/*0x1e0*/		u64	rx_drop_frms;
+/*0x1e8*/		u64	rx_discarded_frms;
+/*0x1f0*/		u64	rx_drop_ip;
+/*0x1f8*/		u64	rx_drop_udp;
+/*0x200*/		u32	rx_marker_pdu_frms;
+/*0x204*/		u32	rx_lacpdu_frms;
+/*0x208*/		u32	rx_unknown_pdu_frms;
+/*0x20c*/		u32	rx_marker_resp_pdu_frms;
+/*0x210*/		u32	rx_fcs_discard;
+/*0x214*/		u32	rx_illegal_pdu_frms;
+/*0x218*/		u32	rx_switch_discard;
+/*0x21c*/		u32	rx_len_discard;
+/*0x220*/		u32	rx_rpa_discard;
+/*0x224*/		u32	rx_l2_mgmt_discard;
+/*0x228*/		u32	rx_rts_discard;
+/*0x22c*/		u32	rx_trash_discard;
+/*0x230*/		u32	rx_buff_full_discard;
+/*0x234*/		u32	rx_red_discard;
+/*0x238*/		u32	rx_xgmii_ctrl_err_cnt;
+/*0x23c*/		u32	rx_xgmii_data_err_cnt;
+/*0x240*/		u32	rx_xgmii_char1_match;
+/*0x244*/		u32	rx_xgmii_err_sym;
+/*0x248*/		u32	rx_xgmii_column1_match;
+/*0x24c*/		u32	rx_xgmii_char2_match;
+/*0x250*/		u32	rx_local_fault;
+/*0x254*/		u32	rx_xgmii_column2_match;
+/*0x258*/		u32	rx_jettison;
+/*0x25c*/		u32	rx_remote_fault;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_vpath_tx_stats - XMAC Vpath Tx Statistics
+ *
+ * @tx_ttl_eth_frms: Count of successfully transmitted MAC frames.
+ * @tx_ttl_eth_octets: Count of total octets of transmitted frames,
+ *             not including framing characters (i.e. less framing bits).
+ *             To determine the total octets of transmitted frames, including
+ *             framing characters, multiply TX_TTL_ETH_FRMS by 8 and add it to
+ *             this stat (the device always prepends 8 bytes of preamble for
+ *             each frame)
+ * @tx_data_octets: Count of data and padding octets of successfully transmitted
+ *             frames.
+ * @tx_mcast_frms: Count of successfully transmitted frames to a group address
+ *             other than the broadcast address.
+ * @tx_bcast_frms: Count of successfully transmitted frames to the broadcast
+ *             group address.
+ * @tx_ucast_frms: Count of transmitted frames containing a unicast address.
+ *             Includes discarded frames that are not sent to the network.
+ * @tx_tagged_frms: Count of transmitted frames containing a VLAN tag.
+ * @tx_vld_ip: Count of transmitted IP datagrams that are passed to the network.
+ * @tx_vld_ip_octets: Count of total octets of transmitted IP datagrams that
+ *            are passed to the network.
+ * @tx_icmp: Count of transmitted ICMP messages. Includes messages not sent due
+ *            to problems within ICMP.
+ * @tx_tcp: Count of transmitted TCP segments. Does not include segments
+ *            containing retransmitted octets.
+ * @tx_rst_tcp: Count of transmitted TCP segments containing the RST flag.
+ * @tx_udp: Count of transmitted UDP datagrams.
+ * @tx_unknown_protocol: Increments when the TPA encounters an unknown protocol,
+ *            such as a new IPv6 extension header, or an unsupported Routing
+ *            Type. The packet still has a checksum calculated but it may be
+ *            incorrect.
+ * @tx_lost_ip: Count of transmitted IP datagrams that could not be passed
+ *            to the network. Increments because of: 1) An internal processing
+ *            error (such as an uncorrectable ECC error). 2) A frame parsing
+ *            error during IP checksum calculation.
+ * @tx_parse_error: Increments when the TPA is unable to parse a packet. This
+ *            generally occurs when a packet is corrupt somehow, including
+ *            packets that have IP version mismatches, invalid Layer 2 control
+ *            fields, etc. L3/L4 checksums are not offloaded, but the packet
+ *            is still be transmitted.
+ * @tx_tcp_offload: For frames belonging to offloaded sessions only, a count
+ *            of transmitted TCP segments. Does not include segments containing
+ *            retransmitted octets.
+ * @tx_retx_tcp_offload: For frames belonging to offloaded sessions only, the
+ *            total number of segments retransmitted. Retransmitted segments
+ *            that are sourced by the host are counted by the host.
+ * @tx_lost_ip_offload: For frames belonging to offloaded sessions only, a count
+ *            of transmitted IP datagrams that could not be passed to the
+ *            network.
+ *
+ * XMAC Vpath TX Statistics.
+ */
+struct vxge_hw_xmac_vpath_tx_stats {
+	u64	tx_ttl_eth_frms;
+	u64	tx_ttl_eth_octets;
+	u64	tx_data_octets;
+	u64	tx_mcast_frms;
+	u64	tx_bcast_frms;
+	u64	tx_ucast_frms;
+	u64	tx_tagged_frms;
+	u64	tx_vld_ip;
+	u64	tx_vld_ip_octets;
+	u64	tx_icmp;
+	u64	tx_tcp;
+	u64	tx_rst_tcp;
+	u64	tx_udp;
+	u32	tx_unknown_protocol;
+	u32	tx_lost_ip;
+	u32	unused1;
+	u32	tx_parse_error;
+	u64	tx_tcp_offload;
+	u64	tx_retx_tcp_offload;
+	u64	tx_lost_ip_offload;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_vpath_rx_stats - XMAC Vpath RX Statistics
+ *
+ * @rx_ttl_eth_frms: Count of successfully received MAC frames.
+ * @rx_vld_frms: Count of successfully received MAC frames. Does not include
+ *            frames received with frame-too-long, FCS, or length errors.
+ * @rx_offload_frms: Count of offloaded received frames that are passed to
+ *            the host.
+ * @rx_ttl_eth_octets: Count of total octets of received frames, not including
+ *            framing characters (i.e. less framing bits). Only counts octets
+ *            of frames that are at least 14 bytes (18 bytes for VLAN-tagged)
+ *            before FCS. To determine the total octets of received frames,
+ *            including framing characters, multiply RX_TTL_ETH_FRMS by 8 and
+ *            add it to this stat (the stat RX_TTL_ETH_FRMS only counts frames
+ *            that have the required 8 bytes of preamble).
+ * @rx_data_octets: Count of data and padding octets of successfully received
+ *            frames. Does not include frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_offload_octets: Count of total octets, not including framing characters,
+ *            of offloaded received frames that are passed to the host.
+ * @rx_vld_mcast_frms: Count of successfully received MAC frames containing a
+ *            nonbroadcast group address. Does not include frames received with
+ *            frame-too-long, FCS, or length errors.
+ * @rx_vld_bcast_frms: Count of successfully received MAC frames containing the
+ *            broadcast group address. Does not include frames received with
+ *            frame-too-long, FCS, or length errors.
+ * @rx_accepted_ucast_frms: Count of successfully received frames containing
+ *            a unicast address. Only includes frames that are passed to the
+ *            system.
+ * @rx_accepted_nucast_frms: Count of successfully received frames containing
+ *            a non-unicast (broadcast or multicast) address. Only includes
+ *            frames that are passed to the system. Could include, for instance,
+ *            non-unicast frames that contain FCS errors if the MAC_ERROR_CFG
+ *            register is set to pass FCS-errored frames to the host.
+ * @rx_tagged_frms: Count of received frames containing a VLAN tag.
+ * @rx_long_frms: Count of received frames that are longer than RX_MAX_PYLD_LEN
+ *            + 18 bytes (+ 22 bytes if VLAN-tagged).
+ * @rx_usized_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) less than 64 octets, that are otherwise well-formed.
+ *            In other words, counts runts.
+ * @rx_osized_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) more than 1518 octets, that are otherwise
+ *            well-formed.
+ * @rx_frag_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) less than 64 octets that had bad FCS.
+ *            In other words, counts fragments.
+ * @rx_jabber_frms: Count of received frames of length (including FCS, but not
+ *            framing bits) more than 1518 octets that had bad FCS. In other
+ *            words, counts jabbers.
+ * @rx_ttl_64_frms: Count of total received MAC frames with length (including
+ *            FCS, but not framing bits) of exactly 64 octets. Includes frames
+ *            received with frame-too-long, FCS, or length errors.
+ * @rx_ttl_65_127_frms: Count of total received MAC frames
+ * 		with length (including
+ *            FCS, but not framing bits) of between 65 and 127 octets inclusive.
+ *            Includes frames received with frame-too-long, FCS,
+ *            or length errors.
+ * @rx_ttl_128_255_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits)
+ *            of between 128 and 255 octets
+ *            inclusive. Includes frames received with frame-too-long, FCS,
+ *            or length errors.
+ * @rx_ttl_256_511_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits)
+ *            of between 256 and 511 octets
+ *            inclusive. Includes frames received with frame-too-long, FCS, or
+ *            length errors.
+ * @rx_ttl_512_1023_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 512 and 1023
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_1024_1518_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 1024 and 1518
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_1519_4095_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 1519 and 4095
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_4096_8191_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 4096 and 8191
+ *            octets inclusive. Includes frames received with frame-too-long,
+ *            FCS, or length errors.
+ * @rx_ttl_8192_max_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) of between 8192 and
+ *            RX_MAX_PYLD_LEN+18 octets inclusive. Includes frames received
+ *            with frame-too-long, FCS, or length errors.
+ * @rx_ttl_gt_max_frms: Count of total received MAC frames with length
+ *            (including FCS, but not framing bits) exceeding RX_MAX_PYLD_LEN+18
+ *            (+22 bytes if VLAN-tagged) octets inclusive. Includes frames
+ *            received with frame-too-long, FCS, or length errors.
+ * @rx_ip: Count of received IP datagrams. Includes errored IP datagrams.
+ * @rx_accepted_ip: Count of received IP datagrams that
+ * 		are passed to the system.
+ * @rx_ip_octets: Count of number of octets in received IP datagrams.
+ *            Includes errored IP datagrams.
+ * @rx_err_ip: Count of received IP datagrams containing errors. For example,
+ *            bad IP checksum.
+ * @rx_icmp: Count of received ICMP messages. Includes errored ICMP messages.
+ * @rx_tcp: Count of received TCP segments. Includes errored TCP segments.
+ *             Note: This stat contains a count of all received TCP segments,
+ *             regardless of whether or not they pertain to an established
+ *             connection.
+ * @rx_udp: Count of received UDP datagrams.
+ * @rx_err_tcp: Count of received TCP segments containing errors. For example,
+ *             bad TCP checksum.
+ * @rx_lost_frms: Count of received frames that could not be passed to the host.
+ *             See RX_QUEUE_FULL_DISCARD and RX_RED_DISCARD
+ *             for a list of reasons.
+ * @rx_lost_ip: Count of received IP datagrams that could not be passed to
+ *             the host. See RX_LOST_FRMS for a list of reasons.
+ * @rx_lost_ip_offload: For frames belonging to offloaded sessions only, a count
+ *             of received IP datagrams that could not be passed to the host.
+ *             See RX_LOST_FRMS for a list of reasons.
+ * @rx_various_discard: Count of received frames that are discarded because
+ *             the target receive queue is full.
+ * @rx_sleep_discard: Count of received frames that are discarded because the
+ *            target VPATH is asleep (a Wake-on-LAN magic packet can be used
+ *            to awaken the VPATH).
+ * @rx_red_discard: Count of received frames that are discarded because of RED
+ *            (Random Early Discard).
+ * @rx_queue_full_discard: Count of received frames that are discarded because
+ *             the target receive queue is full.
+ * @rx_mpa_ok_frms: Count of received frames that pass the MPA checks.
+ *
+ * XMAC Vpath RX Statistics.
+ */
+struct vxge_hw_xmac_vpath_rx_stats {
+	u64	rx_ttl_eth_frms;
+	u64	rx_vld_frms;
+	u64	rx_offload_frms;
+	u64	rx_ttl_eth_octets;
+	u64	rx_data_octets;
+	u64	rx_offload_octets;
+	u64	rx_vld_mcast_frms;
+	u64	rx_vld_bcast_frms;
+	u64	rx_accepted_ucast_frms;
+	u64	rx_accepted_nucast_frms;
+	u64	rx_tagged_frms;
+	u64	rx_long_frms;
+	u64	rx_usized_frms;
+	u64	rx_osized_frms;
+	u64	rx_frag_frms;
+	u64	rx_jabber_frms;
+	u64	rx_ttl_64_frms;
+	u64	rx_ttl_65_127_frms;
+	u64	rx_ttl_128_255_frms;
+	u64	rx_ttl_256_511_frms;
+	u64	rx_ttl_512_1023_frms;
+	u64	rx_ttl_1024_1518_frms;
+	u64	rx_ttl_1519_4095_frms;
+	u64	rx_ttl_4096_8191_frms;
+	u64	rx_ttl_8192_max_frms;
+	u64	rx_ttl_gt_max_frms;
+	u64	rx_ip;
+	u64	rx_accepted_ip;
+	u64	rx_ip_octets;
+	u64	rx_err_ip;
+	u64	rx_icmp;
+	u64	rx_tcp;
+	u64	rx_udp;
+	u64	rx_err_tcp;
+	u64	rx_lost_frms;
+	u64	rx_lost_ip;
+	u64	rx_lost_ip_offload;
+	u16	rx_various_discard;
+	u16	rx_sleep_discard;
+	u16	rx_red_discard;
+	u16	rx_queue_full_discard;
+	u64	rx_mpa_ok_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_stats - XMAC Statistics
+ *
+ * @aggr_stats: Statistics on aggregate port(port 0, port 1)
+ * @port_stats: Staticstics on ports(wire 0, wire 1, lag)
+ * @vpath_tx_stats: Per vpath XMAC TX stats
+ * @vpath_rx_stats: Per vpath XMAC RX stats
+ *
+ * XMAC Statistics.
+ */
+struct vxge_hw_xmac_stats {
+	struct vxge_hw_xmac_aggr_stats
+				aggr_stats[VXGE_HW_MAC_MAX_MAC_PORT_ID];
+	struct vxge_hw_xmac_port_stats
+				port_stats[VXGE_HW_MAC_MAX_MAC_PORT_ID+1];
+	struct vxge_hw_xmac_vpath_tx_stats
+				vpath_tx_stats[VXGE_HW_MAX_VIRTUAL_PATHS];
+	struct vxge_hw_xmac_vpath_rx_stats
+				vpath_rx_stats[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_hw_info - Titan vpath hardware statistics.
+ * @ini_num_mwr_sent: The number of PCI memory writes initiated by the PIC block
+ *             for the given VPATH
+ * @ini_num_mrd_sent: The number of PCI memory reads initiated by the PIC block
+ * @ini_num_cpl_rcvd: The number of PCI read completions received by the
+ *             PIC block
+ * @ini_num_mwr_byte_sent: The number of PCI memory write bytes sent by the PIC
+ *             block to the host
+ * @ini_num_cpl_byte_rcvd: The number of PCI read completion bytes received by
+ *             the PIC block
+ * @wrcrdtarb_xoff: TBD
+ * @rdcrdtarb_xoff: TBD
+ * @vpath_genstats_count0: TBD
+ * @vpath_genstats_count1: TBD
+ * @vpath_genstats_count2: TBD
+ * @vpath_genstats_count3: TBD
+ * @vpath_genstats_count4: TBD
+ * @vpath_gennstats_count5: TBD
+ * @tx_stats: Transmit stats
+ * @rx_stats: Receive stats
+ * @prog_event_vnum1: Programmable statistic. Increments when internal logic
+ *             detects a certain event. See register
+ *             XMAC_STATS_CFG.EVENT_VNUM1_CFG for more information.
+ * @prog_event_vnum0: Programmable statistic. Increments when internal logic
+ *             detects a certain event. See register
+ *             XMAC_STATS_CFG.EVENT_VNUM0_CFG for more information.
+ * @prog_event_vnum3: Programmable statistic. Increments when internal logic
+ *             detects a certain event. See register
+ *             XMAC_STATS_CFG.EVENT_VNUM3_CFG for more information.
+ * @prog_event_vnum2: Programmable statistic. Increments when internal logic
+ *             detects a certain event. See register
+ *             XMAC_STATS_CFG.EVENT_VNUM2_CFG for more information.
+ * @rx_multi_cast_frame_discard: TBD
+ * @rx_frm_transferred: TBD
+ * @rxd_returned: TBD
+ * @rx_mpa_len_fail_frms: Count of received frames
+ * 		that fail the MPA length check
+ * @rx_mpa_mrk_fail_frms: Count of received frames
+ * 		that fail the MPA marker check
+ * @rx_mpa_crc_fail_frms: Count of received frames that fail the MPA CRC check
+ * @rx_permitted_frms: Count of frames that pass through the FAU and on to the
+ *             frame buffer (and subsequently to the host).
+ * @rx_vp_reset_discarded_frms: Count of receive frames that are discarded
+ *             because the VPATH is in reset
+ * @rx_wol_frms: Count of received "magic packet" frames. Stat increments
+ *             whenever the received frame matches the VPATH's Wake-on-LAN
+ *             signature(s) CRC.
+ * @tx_vp_reset_discarded_frms: Count of transmit frames that are discarded
+ *             because the VPATH is in reset. Includes frames that are discarded
+ *             because the current VPIN does not match that VPIN of the frame
+ *
+ * Titan vpath hardware statistics.
+ */
+struct vxge_hw_vpath_stats_hw_info {
+/*0x000*/	u32 ini_num_mwr_sent;
+/*0x004*/	u32 unused1;
+/*0x008*/	u32 ini_num_mrd_sent;
+/*0x00c*/	u32 unused2;
+/*0x010*/	u32 ini_num_cpl_rcvd;
+/*0x014*/	u32 unused3;
+/*0x018*/	u64 ini_num_mwr_byte_sent;
+/*0x020*/	u64 ini_num_cpl_byte_rcvd;
+/*0x028*/	u32 wrcrdtarb_xoff;
+/*0x02c*/	u32 unused4;
+/*0x030*/	u32 rdcrdtarb_xoff;
+/*0x034*/	u32 unused5;
+/*0x038*/	u32 vpath_genstats_count0;
+/*0x03c*/	u32 vpath_genstats_count1;
+/*0x040*/	u32 vpath_genstats_count2;
+/*0x044*/	u32 vpath_genstats_count3;
+/*0x048*/	u32 vpath_genstats_count4;
+/*0x04c*/	u32 unused6;
+/*0x050*/	u32 vpath_genstats_count5;
+/*0x054*/	u32 unused7;
+/*0x058*/	struct vxge_hw_xmac_vpath_tx_stats tx_stats;
+/*0x0e8*/	struct vxge_hw_xmac_vpath_rx_stats rx_stats;
+/*0x220*/	u64 unused9;
+/*0x228*/	u32 prog_event_vnum1;
+/*0x22c*/	u32 prog_event_vnum0;
+/*0x230*/	u32 prog_event_vnum3;
+/*0x234*/	u32 prog_event_vnum2;
+/*0x238*/	u16 rx_multi_cast_frame_discard;
+/*0x23a*/	u8 unused10[6];
+/*0x240*/	u32 rx_frm_transferred;
+/*0x244*/	u32 unused11;
+/*0x248*/	u16 rxd_returned;
+/*0x24a*/	u8 unused12[6];
+/*0x252*/	u16 rx_mpa_len_fail_frms;
+/*0x254*/	u16 rx_mpa_mrk_fail_frms;
+/*0x256*/	u16 rx_mpa_crc_fail_frms;
+/*0x258*/	u16 rx_permitted_frms;
+/*0x25c*/	u64 rx_vp_reset_discarded_frms;
+/*0x25e*/	u64 rx_wol_frms;
+/*0x260*/	u64 tx_vp_reset_discarded_frms;
+} __packed;
+
+
+/**
+ * struct vxge_hw_device_stats_mrpcim_info - Titan mrpcim hardware statistics.
+ * @pic.ini_rd_drop  	 0x0000  	 4  	 Number of DMA reads initiated
+ *  by the adapter that were discarded because the VPATH is out of service
+ * @pic.ini_wr_drop 	0x0004 	4 	Number of DMA writes initiated by the
+ *  adapter that were discared because the VPATH is out of service
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane0] 	0x0008 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane1] 	0x0010 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane2] 	0x0018 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane3] 	0x0020 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane4] 	0x0028 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane5] 	0x0030 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane6] 	0x0038 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane7] 	0x0040 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane8] 	0x0048 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane9] 	0x0050 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane10] 	0x0058 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane11] 	0x0060 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane12] 	0x0068 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane13] 	0x0070 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane14] 	0x0078 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane15] 	0x0080 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane16] 	0x0088 	4 	Number of times
+ *  the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane0] 	0x0090 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane1] 	0x0098 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane2] 	0x00a0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane3] 	0x00a8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane4] 	0x00b0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane5] 	0x00b8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane6] 	0x00c0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane7] 	0x00c8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane8] 	0x00d0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane9] 	0x00d8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane10] 	0x00e0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane11] 	0x00e8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane12] 	0x00f0 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane13] 	0x00f8 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane14] 	0x0100 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane15] 	0x0108 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane16] 	0x0110 	4 	Number of times
+ *  the posted data credits for upstream PCI writes were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane0] 	0x0118 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane1] 	0x0120 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane2] 	0x0128 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane3] 	0x0130 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane4] 	0x0138 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane5] 	0x0140 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane6] 	0x0148 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane7] 	0x0150 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane8] 	0x0158 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane9] 	0x0160 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane10] 	0x0168 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane11] 	0x0170 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane12] 	0x0178 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane13] 	0x0180 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane14] 	0x0188 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane15] 	0x0190 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane16] 	0x0198 	4 	Number of times
+ *  the non-posted header credits for upstream PCI reads were depleted
+ * @pic.ini_rd_vpin_drop 	0x01a0 	4 	Number of DMA reads initiated by
+ *  the adapter that were discarded because the VPATH instance number does
+ *  not match
+ * @pic.ini_wr_vpin_drop 	0x01a4 	4 	Number of DMA writes initiated
+ *  by the adapter that were discarded because the VPATH instance number
+ *  does not match
+ * @pic.genstats_count0 	0x01a8 	4 	Configurable statistic #1. Refer
+ *  to the GENSTATS0_CFG for information on configuring this statistic
+ * @pic.genstats_count1 	0x01ac 	4 	Configurable statistic #2. Refer
+ *  to the GENSTATS1_CFG for information on configuring this statistic
+ * @pic.genstats_count2 	0x01b0 	4 	Configurable statistic #3. Refer
+ *  to the GENSTATS2_CFG for information on configuring this statistic
+ * @pic.genstats_count3 	0x01b4 	4 	Configurable statistic #4. Refer
+ *  to the GENSTATS3_CFG for information on configuring this statistic
+ * @pic.genstats_count4 	0x01b8 	4 	Configurable statistic #5. Refer
+ *  to the GENSTATS4_CFG for information on configuring this statistic
+ * @pic.genstats_count5 	0x01c0 	4 	Configurable statistic #6. Refer
+ *  to the GENSTATS5_CFG for information on configuring this statistic
+ * @pci.rstdrop_cpl 	0x01c8 	4
+ * @pci.rstdrop_msg 	0x01cc 	4
+ * @pci.rstdrop_client1 	0x01d0 	4
+ * @pci.rstdrop_client0 	0x01d4 	4
+ * @pci.rstdrop_client2 	0x01d8 	4
+ * @pci.depl_cplh[vplane0] 	0x01e2 	2 	Number of times completion
+ *  header credits were depleted
+ * @pci.depl_nph[vplane0] 	0x01e4 	2 	Number of times non posted
+ *  header credits were depleted
+ * @pci.depl_ph[vplane0] 	0x01e6 	2 	Number of times the posted
+ *  header credits were depleted
+ * @pci.depl_cplh[vplane1] 	0x01ea 	2
+ * @pci.depl_nph[vplane1] 	0x01ec 	2
+ * @pci.depl_ph[vplane1] 	0x01ee 	2
+ * @pci.depl_cplh[vplane2] 	0x01f2 	2
+ * @pci.depl_nph[vplane2] 	0x01f4 	2
+ * @pci.depl_ph[vplane2] 	0x01f6 	2
+ * @pci.depl_cplh[vplane3] 	0x01fa 	2
+ * @pci.depl_nph[vplane3] 	0x01fc 	2
+ * @pci.depl_ph[vplane3] 	0x01fe 	2
+ * @pci.depl_cplh[vplane4] 	0x0202 	2
+ * @pci.depl_nph[vplane4] 	0x0204 	2
+ * @pci.depl_ph[vplane4] 	0x0206 	2
+ * @pci.depl_cplh[vplane5] 	0x020a 	2
+ * @pci.depl_nph[vplane5] 	0x020c 	2
+ * @pci.depl_ph[vplane5] 	0x020e 	2
+ * @pci.depl_cplh[vplane6] 	0x0212 	2
+ * @pci.depl_nph[vplane6] 	0x0214 	2
+ * @pci.depl_ph[vplane6] 	0x0216 	2
+ * @pci.depl_cplh[vplane7] 	0x021a 	2
+ * @pci.depl_nph[vplane7] 	0x021c 	2
+ * @pci.depl_ph[vplane7] 	0x021e 	2
+ * @pci.depl_cplh[vplane8] 	0x0222 	2
+ * @pci.depl_nph[vplane8] 	0x0224 	2
+ * @pci.depl_ph[vplane8] 	0x0226 	2
+ * @pci.depl_cplh[vplane9] 	0x022a 	2
+ * @pci.depl_nph[vplane9] 	0x022c 	2
+ * @pci.depl_ph[vplane9] 	0x022e 	2
+ * @pci.depl_cplh[vplane10] 	0x0232 	2
+ * @pci.depl_nph[vplane10] 	0x0234 	2
+ * @pci.depl_ph[vplane10] 	0x0236 	2
+ * @pci.depl_cplh[vplane11] 	0x023a 	2
+ * @pci.depl_nph[vplane11] 	0x023c 	2
+ * @pci.depl_ph[vplane11] 	0x023e 	2
+ * @pci.depl_cplh[vplane12] 	0x0242 	2
+ * @pci.depl_nph[vplane12] 	0x0244 	2
+ * @pci.depl_ph[vplane12] 	0x0246 	2
+ * @pci.depl_cplh[vplane13] 	0x024a 	2
+ * @pci.depl_nph[vplane13] 	0x024c 	2
+ * @pci.depl_ph[vplane13] 	0x024e 	2
+ * @pci.depl_cplh[vplane14] 	0x0252 	2
+ * @pci.depl_nph[vplane14] 	0x0254 	2
+ * @pci.depl_ph[vplane14] 	0x0256 	2
+ * @pci.depl_cplh[vplane15] 	0x025a 	2
+ * @pci.depl_nph[vplane15] 	0x025c 	2
+ * @pci.depl_ph[vplane15] 	0x025e 	2
+ * @pci.depl_cplh[vplane16] 	0x0262 	2
+ * @pci.depl_nph[vplane16] 	0x0264 	2
+ * @pci.depl_ph[vplane16] 	0x0266 	2
+ * @pci.depl_cpld[vplane0] 	0x026a 	2 	Number of times completion data
+ *  credits were depleted
+ * @pci.depl_npd[vplane0] 	0x026c 	2 	Number of times non posted data
+ *  credits were depleted
+ * @pci.depl_pd[vplane0] 	0x026e 	2 	Number of times the posted data
+ *  credits were depleted
+ * @pci.depl_cpld[vplane1] 	0x0272 	2
+ * @pci.depl_npd[vplane1] 	0x0274 	2
+ * @pci.depl_pd[vplane1] 	0x0276 	2
+ * @pci.depl_cpld[vplane2] 	0x027a 	2
+ * @pci.depl_npd[vplane2] 	0x027c 	2
+ * @pci.depl_pd[vplane2] 	0x027e 	2
+ * @pci.depl_cpld[vplane3] 	0x0282 	2
+ * @pci.depl_npd[vplane3] 	0x0284 	2
+ * @pci.depl_pd[vplane3] 	0x0286 	2
+ * @pci.depl_cpld[vplane4] 	0x028a 	2
+ * @pci.depl_npd[vplane4] 	0x028c 	2
+ * @pci.depl_pd[vplane4] 	0x028e 	2
+ * @pci.depl_cpld[vplane5] 	0x0292 	2
+ * @pci.depl_npd[vplane5] 	0x0294 	2
+ * @pci.depl_pd[vplane5] 	0x0296 	2
+ * @pci.depl_cpld[vplane6] 	0x029a 	2
+ * @pci.depl_npd[vplane6] 	0x029c 	2
+ * @pci.depl_pd[vplane6] 	0x029e 	2
+ * @pci.depl_cpld[vplane7] 	0x02a2 	2
+ * @pci.depl_npd[vplane7] 	0x02a4 	2
+ * @pci.depl_pd[vplane7] 	0x02a6 	2
+ * @pci.depl_cpld[vplane8] 	0x02aa 	2
+ * @pci.depl_npd[vplane8] 	0x02ac 	2
+ * @pci.depl_pd[vplane8] 	0x02ae 	2
+ * @pci.depl_cpld[vplane9] 	0x02b2 	2
+ * @pci.depl_npd[vplane9] 	0x02b4 	2
+ * @pci.depl_pd[vplane9] 	0x02b6 	2
+ * @pci.depl_cpld[vplane10] 	0x02ba 	2
+ * @pci.depl_npd[vplane10] 	0x02bc 	2
+ * @pci.depl_pd[vplane10] 	0x02be 	2
+ * @pci.depl_cpld[vplane11] 	0x02c2 	2
+ * @pci.depl_npd[vplane11] 	0x02c4 	2
+ * @pci.depl_pd[vplane11] 	0x02c6 	2
+ * @pci.depl_cpld[vplane12] 	0x02ca 	2
+ * @pci.depl_npd[vplane12] 	0x02cc 	2
+ * @pci.depl_pd[vplane12] 	0x02ce 	2
+ * @pci.depl_cpld[vplane13] 	0x02d2 	2
+ * @pci.depl_npd[vplane13] 	0x02d4 	2
+ * @pci.depl_pd[vplane13] 	0x02d6 	2
+ * @pci.depl_cpld[vplane14] 	0x02da 	2
+ * @pci.depl_npd[vplane14] 	0x02dc 	2
+ * @pci.depl_pd[vplane14] 	0x02de 	2
+ * @pci.depl_cpld[vplane15] 	0x02e2 	2
+ * @pci.depl_npd[vplane15] 	0x02e4 	2
+ * @pci.depl_pd[vplane15] 	0x02e6 	2
+ * @pci.depl_cpld[vplane16] 	0x02ea 	2
+ * @pci.depl_npd[vplane16] 	0x02ec 	2
+ * @pci.depl_pd[vplane16] 	0x02ee 	2
+ * @xgmac_port[3];
+ * @xgmac_aggr[2];
+ * @xgmac.global_prog_event_gnum0 	0x0ae0 	8 	Programmable statistic.
+ *  Increments when internal logic detects a certain event. See register
+ *  XMAC_STATS_GLOBAL_CFG.EVENT_GNUM0_CFG for more information.
+ * @xgmac.global_prog_event_gnum1 	0x0ae8 	8 	Programmable statistic.
+ *  Increments when internal logic detects a certain event. See register
+ *  XMAC_STATS_GLOBAL_CFG.EVENT_GNUM1_CFG for more information.
+ * @xgmac.orp_lro_events 	0x0af8 	8
+ * @xgmac.orp_bs_events 	0x0b00 	8
+ * @xgmac.orp_iwarp_events 	0x0b08 	8
+ * @xgmac.tx_permitted_frms 	0x0b14 	4
+ * @xgmac.port2_tx_any_frms 	0x0b1d 	1
+ * @xgmac.port1_tx_any_frms 	0x0b1e 	1
+ * @xgmac.port0_tx_any_frms 	0x0b1f 	1
+ * @xgmac.port2_rx_any_frms 	0x0b25 	1
+ * @xgmac.port1_rx_any_frms 	0x0b26 	1
+ * @xgmac.port0_rx_any_frms 	0x0b27 	1
+ *
+ * Titan mrpcim hardware statistics.
+ */
+struct vxge_hw_device_stats_mrpcim_info {
+/*0x0000*/	u32	pic_ini_rd_drop;
+/*0x0004*/	u32	pic_ini_wr_drop;
+/*0x0008*/	struct {
+	/*0x0000*/	u32	pic_wrcrdtarb_ph_crdt_depleted;
+	/*0x0004*/	u32	unused1;
+		} pic_wrcrdtarb_ph_crdt_depleted_vplane[17];
+/*0x0090*/	struct {
+	/*0x0000*/	u32	pic_wrcrdtarb_pd_crdt_depleted;
+	/*0x0004*/	u32	unused2;
+		} pic_wrcrdtarb_pd_crdt_depleted_vplane[17];
+/*0x0118*/	struct {
+	/*0x0000*/	u32	pic_rdcrdtarb_nph_crdt_depleted;
+	/*0x0004*/	u32	unused3;
+		} pic_rdcrdtarb_nph_crdt_depleted_vplane[17];
+/*0x01a0*/	u32	pic_ini_rd_vpin_drop;
+/*0x01a4*/	u32	pic_ini_wr_vpin_drop;
+/*0x01a8*/	u32	pic_genstats_count0;
+/*0x01ac*/	u32	pic_genstats_count1;
+/*0x01b0*/	u32	pic_genstats_count2;
+/*0x01b4*/	u32	pic_genstats_count3;
+/*0x01b8*/	u32	pic_genstats_count4;
+/*0x01bc*/	u32	unused4;
+/*0x01c0*/	u32	pic_genstats_count5;
+/*0x01c4*/	u32	unused5;
+/*0x01c8*/	u32	pci_rstdrop_cpl;
+/*0x01cc*/	u32	pci_rstdrop_msg;
+/*0x01d0*/	u32	pci_rstdrop_client1;
+/*0x01d4*/	u32	pci_rstdrop_client0;
+/*0x01d8*/	u32	pci_rstdrop_client2;
+/*0x01dc*/	u32	unused6;
+/*0x01e0*/	struct {
+	/*0x0000*/	u16	unused7;
+	/*0x0002*/	u16	pci_depl_cplh;
+	/*0x0004*/	u16	pci_depl_nph;
+	/*0x0006*/	u16	pci_depl_ph;
+		} pci_depl_h_vplane[17];
+/*0x0268*/	struct {
+	/*0x0000*/	u16	unused8;
+	/*0x0002*/	u16	pci_depl_cpld;
+	/*0x0004*/	u16	pci_depl_npd;
+	/*0x0006*/	u16	pci_depl_pd;
+		} pci_depl_d_vplane[17];
+/*0x02f0*/	struct vxge_hw_xmac_port_stats xgmac_port[3];
+/*0x0a10*/	struct vxge_hw_xmac_aggr_stats xgmac_aggr[2];
+/*0x0ae0*/	u64	xgmac_global_prog_event_gnum0;
+/*0x0ae8*/	u64	xgmac_global_prog_event_gnum1;
+/*0x0af0*/	u64	unused7;
+/*0x0af8*/	u64	unused8;
+/*0x0b00*/	u64	unused9;
+/*0x0b08*/	u64	unused10;
+/*0x0b10*/	u32	unused11;
+/*0x0b14*/	u32	xgmac_tx_permitted_frms;
+/*0x0b18*/	u32	unused12;
+/*0x0b1c*/	u8	unused13;
+/*0x0b1d*/	u8	xgmac_port2_tx_any_frms;
+/*0x0b1e*/	u8	xgmac_port1_tx_any_frms;
+/*0x0b1f*/	u8	xgmac_port0_tx_any_frms;
+/*0x0b20*/	u32	unused14;
+/*0x0b24*/	u8	unused15;
+/*0x0b25*/	u8	xgmac_port2_rx_any_frms;
+/*0x0b26*/	u8	xgmac_port1_rx_any_frms;
+/*0x0b27*/	u8	xgmac_port0_rx_any_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_device_stats_hw_info - Titan hardware statistics.
+ * @vpath_info: VPath statistics
+ * @vpath_info_sav: Vpath statistics saved
+ *
+ * Titan hardware statistics.
+ */
+struct vxge_hw_device_stats_hw_info {
+	struct vxge_hw_vpath_stats_hw_info
+		*vpath_info[VXGE_HW_MAX_VIRTUAL_PATHS];
+	struct vxge_hw_vpath_stats_hw_info
+		vpath_info_sav[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_common_info - HW common
+ * statistics for queues.
+ * @full_cnt: Number of times the queue was full
+ * @usage_cnt: usage count.
+ * @usage_max: Maximum usage
+ * @reserve_free_swaps_cnt: Reserve/free swap counter. Internal usage.
+ * @total_compl_cnt: Total descriptor completion count.
+ *
+ * Hw queue counters
+ * See also: struct vxge_hw_vpath_stats_sw_fifo_info{},
+ * struct vxge_hw_vpath_stats_sw_ring_info{},
+ */
+struct vxge_hw_vpath_stats_sw_common_info {
+	u32	full_cnt;
+	u32	usage_cnt;
+	u32	usage_max;
+	u32	reserve_free_swaps_cnt;
+	u32 total_compl_cnt;
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_fifo_info - HW fifo statistics
+ * @common_stats: Common counters for all queues
+ * @total_posts: Total number of postings on the queue.
+ * @total_buffers: Total number of buffers posted.
+ * @txd_t_code_err_cnt: Array of transmit transfer codes. The position
+ * (index) in this array reflects the transfer code type, for instance
+ * 0xA - "loss of link".
+ * Value txd_t_code_err_cnt[i] reflects the
+ * number of times the corresponding transfer code was encountered.
+ *
+ * HW fifo counters
+ * See also: struct vxge_hw_vpath_stats_sw_common_info{},
+ * struct vxge_hw_vpath_stats_sw_ring_info{},
+ */
+struct vxge_hw_vpath_stats_sw_fifo_info {
+	struct vxge_hw_vpath_stats_sw_common_info common_stats;
+	u32 total_posts;
+	u32 total_buffers;
+	u32 txd_t_code_err_cnt[VXGE_HW_DTR_MAX_T_CODE];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_ring_info - HW ring statistics
+ * @common_stats: Common counters for all queues
+ * @rxd_t_code_err_cnt: Array of receive transfer codes. The position
+ *             (index) in this array reflects the transfer code type,
+ *             for instance
+ *             0x7 - for "invalid receive buffer size", or 0x8 - for ECC.
+ *             Value rxd_t_code_err_cnt[i] reflects the
+ *             number of times the corresponding transfer code was encountered.
+ *
+ * HW ring counters
+ * See also: struct vxge_hw_vpath_stats_sw_common_info{},
+ * struct vxge_hw_vpath_stats_sw_fifo_info{},
+ */
+struct vxge_hw_vpath_stats_sw_ring_info {
+	struct vxge_hw_vpath_stats_sw_common_info common_stats;
+	u32 rxd_t_code_err_cnt[VXGE_HW_DTR_MAX_T_CODE];
+
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_err - HW vpath error statistics
+ * @unknown_alarms:
+ * @network_sustained_fault:
+ * @network_sustained_ok:
+ * @kdfcctl_fifo0_overwrite:
+ * @kdfcctl_fifo0_poison:
+ * @kdfcctl_fifo0_dma_error:
+ * @dblgen_fifo0_overflow:
+ * @statsb_pif_chain_error:
+ * @statsb_drop_timeout:
+ * @target_illegal_access:
+ * @ini_serr_det:
+ * @prc_ring_bumps:
+ * @prc_rxdcm_sc_err:
+ * @prc_rxdcm_sc_abort:
+ * @prc_quanta_size_err:
+ *
+ * HW vpath error statistics
+ */
+struct vxge_hw_vpath_stats_sw_err {
+	u32	unknown_alarms;
+	u32	network_sustained_fault;
+	u32	network_sustained_ok;
+	u32	kdfcctl_fifo0_overwrite;
+	u32	kdfcctl_fifo0_poison;
+	u32	kdfcctl_fifo0_dma_error;
+	u32	dblgen_fifo0_overflow;
+	u32	statsb_pif_chain_error;
+	u32	statsb_drop_timeout;
+	u32	target_illegal_access;
+	u32	ini_serr_det;
+	u32	prc_ring_bumps;
+	u32	prc_rxdcm_sc_err;
+	u32	prc_rxdcm_sc_abort;
+	u32	prc_quanta_size_err;
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_info - HW vpath sw statistics
+ * @soft_reset_cnt: Number of times soft reset is done on this vpath.
+ * @error_stats: error counters for the vpath
+ * @ring_stats: counters for ring belonging to the vpath
+ * @fifo_stats: counters for fifo belonging to the vpath
+ *
+ * HW vpath sw statistics
+ * See also: struct vxge_hw_device_info{} }.
+ */
+struct vxge_hw_vpath_stats_sw_info {
+	u32    soft_reset_cnt;
+	struct vxge_hw_vpath_stats_sw_err	error_stats;
+	struct vxge_hw_vpath_stats_sw_ring_info	ring_stats;
+	struct vxge_hw_vpath_stats_sw_fifo_info	fifo_stats;
+};
+
+/**
+ * struct vxge_hw_device_stats_sw_info - HW own per-device statistics.
+ *
+ * @not_traffic_intr_cnt: Number of times the host was interrupted
+ *                        without new completions.
+ *                        "Non-traffic interrupt counter".
+ * @traffic_intr_cnt: Number of traffic interrupts for the device.
+ * @total_intr_cnt: Total number of traffic interrupts for the device.
+ *                  @total_intr_cnt == @traffic_intr_cnt +
+ *                              @not_traffic_intr_cnt
+ * @soft_reset_cnt: Number of times soft reset is done on this device.
+ * @vpath_info: please see struct vxge_hw_vpath_stats_sw_info{}
+ * HW per-device statistics.
+ */
+struct vxge_hw_device_stats_sw_info {
+	u32	not_traffic_intr_cnt;
+	u32	traffic_intr_cnt;
+	u32	total_intr_cnt;
+	u32	soft_reset_cnt;
+	struct vxge_hw_vpath_stats_sw_info
+		vpath_info[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_device_stats_sw_err - HW device error statistics.
+ * @vpath_alarms: Number of vpath alarms
+ *
+ * HW Device error stats
+ */
+struct vxge_hw_device_stats_sw_err {
+	u32     vpath_alarms;
+};
+
+/**
+ * struct vxge_hw_device_stats - Contains HW per-device statistics,
+ * including hw.
+ * @devh: HW device handle.
+ * @dma_addr: DMA addres of the %hw_info. Given to device to fill-in the stats.
+ * @hw_info_dmah: DMA handle used to map hw statistics onto the device memory
+ *                space.
+ * @hw_info_dma_acch: One more DMA handle used subsequently to free the
+ *                    DMA object. Note that this and the previous handle have
+ *                    physical meaning for Solaris; on Windows and Linux the
+ *                    corresponding value will be simply pointer to PCI device.
+ *
+ * @hw_dev_info_stats: Titan statistics maintained by the hardware.
+ * @sw_dev_info_stats: HW's "soft" device informational statistics, e.g. number
+ *                     of completions per interrupt.
+ * @sw_dev_err_stats: HW's "soft" device error statistics.
+ *
+ * Structure-container of HW per-device statistics. Note that per-channel
+ * statistics are kept in separate structures under HW's fifo and ring
+ * channels.
+ */
+struct vxge_hw_device_stats {
+	/* handles */
+	struct __vxge_hw_device *devh;
+
+	/* HW device hardware statistics */
+	struct vxge_hw_device_stats_hw_info	hw_dev_info_stats;
+
+	/* HW device "soft" stats */
+	struct vxge_hw_device_stats_sw_err   sw_dev_err_stats;
+	struct vxge_hw_device_stats_sw_info  sw_dev_info_stats;
+
+};
+
+enum vxge_hw_status vxge_hw_device_hw_stats_enable(
+			struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_device_stats_get(
+			struct __vxge_hw_device *devh,
+			struct vxge_hw_device_stats_hw_info *hw_stats);
+
+enum vxge_hw_status vxge_hw_driver_stats_get(
+			struct __vxge_hw_device *devh,
+			struct vxge_hw_device_stats_sw_info *sw_stats);
+
+enum vxge_hw_status vxge_hw_mrpcim_stats_enable(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_mrpcim_stats_disable(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status
+vxge_hw_mrpcim_stats_access(
+	struct __vxge_hw_device *devh,
+	u32 operation,
+	u32 location,
+	u32 offset,
+	u64 *stat);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *devh, u32 port,
+				   struct vxge_hw_xmac_aggr_stats *aggr_stats);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *devh, u32 port,
+				   struct vxge_hw_xmac_port_stats *port_stats);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *devh,
+			      struct vxge_hw_xmac_stats *xmac_stats);
+
+/**
+ * enum enum vxge_hw_mgmt_reg_type - Register types.
+ *
+ * @vxge_hw_mgmt_reg_type_legacy: Legacy registers
+ * @vxge_hw_mgmt_reg_type_toc: TOC Registers
+ * @vxge_hw_mgmt_reg_type_common: Common Registers
+ * @vxge_hw_mgmt_reg_type_mrpcim: mrpcim registers
+ * @vxge_hw_mgmt_reg_type_srpcim: srpcim registers
+ * @vxge_hw_mgmt_reg_type_vpmgmt: vpath management registers
+ * @vxge_hw_mgmt_reg_type_vpath: vpath registers
+ *
+ * Register type enumaration
+ */
+enum vxge_hw_mgmt_reg_type {
+	vxge_hw_mgmt_reg_type_legacy = 0,
+	vxge_hw_mgmt_reg_type_toc = 1,
+	vxge_hw_mgmt_reg_type_common = 2,
+	vxge_hw_mgmt_reg_type_mrpcim = 3,
+	vxge_hw_mgmt_reg_type_srpcim = 4,
+	vxge_hw_mgmt_reg_type_vpmgmt = 5,
+	vxge_hw_mgmt_reg_type_vpath = 6
+};
+
+enum vxge_hw_status
+vxge_hw_mgmt_reg_read(struct __vxge_hw_device *devh,
+		      enum vxge_hw_mgmt_reg_type type,
+		      u32 index,
+		      u32 offset,
+		      u64 *value);
+
+enum vxge_hw_status
+vxge_hw_mgmt_reg_write(struct __vxge_hw_device *devh,
+		      enum vxge_hw_mgmt_reg_type type,
+		      u32 index,
+		      u32 offset,
+		      u64 value);
+
+/**
+ * enum enum vxge_hw_rxd_state - Descriptor (RXD) state.
+ * @VXGE_HW_RXD_STATE_NONE: Invalid state.
+ * @VXGE_HW_RXD_STATE_AVAIL: Descriptor is available for reservation.
+ * @VXGE_HW_RXD_STATE_POSTED: Descriptor is posted for processing by the
+ * device.
+ * @VXGE_HW_RXD_STATE_FREED: Descriptor is free and can be reused for
+ * filling-in and posting later.
+ *
+ * Titan/HW descriptor states.
+ *
+ */
+enum vxge_hw_rxd_state {
+	VXGE_HW_RXD_STATE_NONE		= 0,
+	VXGE_HW_RXD_STATE_AVAIL		= 1,
+	VXGE_HW_RXD_STATE_POSTED	= 2,
+	VXGE_HW_RXD_STATE_FREED		= 3
+};
+
+/**
+ * struct vxge_hw_ring_rxd_info - Extended information associated with a
+ * completed ring descriptor.
+ * @syn_flag: SYN flag
+ * @is_icmp: Is ICMP
+ * @fast_path_eligible: Fast Path Eligible flag
+ * @l3_cksum: in L3 checksum is valid
+ * @l3_cksum: Result of IP checksum check (by Titan hardware).
+ *            This field containing VXGE_HW_L3_CKSUM_OK would mean that
+ *            the checksum is correct, otherwise - the datagram is
+ *            corrupted.
+ * @l4_cksum: in L4 checksum is valid
+ * @l4_cksum: Result of TCP/UDP checksum check (by Titan hardware).
+ *            This field containing VXGE_HW_L4_CKSUM_OK would mean that
+ *            the checksum is correct. Otherwise - the packet is
+ *            corrupted.
+ * @frame: Zero or more of enum vxge_hw_frame_type flags.
+ * 		See enum vxge_hw_frame_type{}.
+ * @proto: zero or more of enum vxge_hw_frame_proto flags.  Reporting bits for
+ *            various higher-layer protocols, including (but note restricted to)
+ *            TCP and UDP. See enum vxge_hw_frame_proto{}.
+ * @is_vlan: If vlan tag is valid
+ * @vlan: VLAN tag extracted from the received frame.
+ * @rth_bucket: RTH bucket
+ * @rth_it_hit: Set, If RTH hash value calculated by the Titan hardware
+ *             has a matching entry in the Indirection table.
+ * @rth_spdm_hit: Set, If RTH hash value calculated by the Titan hardware
+ *             has a matching entry in the Socket Pair Direct Match table.
+ * @rth_hash_type: RTH hash code of the function used to calculate the hash.
+ * @rth_value: Receive Traffic Hashing(RTH) hash value. Produced by Titan
+ *             hardware if RTH is enabled.
+ */
+struct vxge_hw_ring_rxd_info {
+	u32	syn_flag;
+	u32	is_icmp;
+	u32	fast_path_eligible;
+	u32	l3_cksum_valid;
+	u32	l3_cksum;
+	u32	l4_cksum_valid;
+	u32	l4_cksum;
+	u32	frame;
+	u32	proto;
+	u32	is_vlan;
+	u32	vlan;
+	u32	rth_bucket;
+	u32	rth_it_hit;
+	u32	rth_spdm_hit;
+	u32	rth_hash_type;
+	u32	rth_value;
+};
+
+/**
+ * enum enum vxge_hw_ring_hash_type - RTH hash types
+ * @VXGE_HW_RING_HASH_TYPE_NONE: No Hash
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4
+ * @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6
+ * @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension
+ * @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension
+ *
+ * RTH hash types
+ */
+enum vxge_hw_ring_hash_type {
+	VXGE_HW_RING_HASH_TYPE_NONE			= 0x0,
+	VXGE_HW_RING_HASH_TYPE_TCP_IPV4		= 0x1,
+	VXGE_HW_RING_HASH_TYPE_UDP_IPV4		= 0x2,
+	VXGE_HW_RING_HASH_TYPE_IPV4			= 0x3,
+	VXGE_HW_RING_HASH_TYPE_TCP_IPV6		= 0x4,
+	VXGE_HW_RING_HASH_TYPE_UDP_IPV6		= 0x5,
+	VXGE_HW_RING_HASH_TYPE_IPV6			= 0x6,
+	VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX	= 0x7,
+	VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX	= 0x8,
+	VXGE_HW_RING_HASH_TYPE_IPV6_EX		= 0x9
+};
+
+enum vxge_hw_status vxge_hw_ring_rxd_reserve(
+	struct __vxge_hw_ring *ring_handle,
+	void **rxdh);
+
+void
+vxge_hw_ring_rxd_pre_post(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh);
+
+void
+vxge_hw_ring_rxd_post_post(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh);
+
+enum vxge_hw_status
+vxge_hw_ring_replenish(struct __vxge_hw_ring *ring_handle, u16 min_flag);
+
+void
+vxge_hw_ring_rxd_post_post_wmb(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh);
+
+void vxge_hw_ring_rxd_post(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh);
+
+enum vxge_hw_status vxge_hw_ring_rxd_next_completed(
+	struct __vxge_hw_ring *ring_handle,
+	void **rxdh,
+	u8 *t_code);
+
+enum vxge_hw_status vxge_hw_ring_handle_tcode(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh,
+	u8 t_code);
+
+void vxge_hw_ring_rxd_free(
+	struct __vxge_hw_ring *ring_handle,
+	void *rxdh);
+
+/**
+ * enum enum vxge_hw_frame_proto - Higher-layer ethernet protocols.
+ * @VXGE_HW_FRAME_PROTO_VLAN_TAGGED: VLAN.
+ * @VXGE_HW_FRAME_PROTO_IPV4: IPv4.
+ * @VXGE_HW_FRAME_PROTO_IPV6: IPv6.
+ * @VXGE_HW_FRAME_PROTO_IP_FRAG: IP fragmented.
+ * @VXGE_HW_FRAME_PROTO_TCP: TCP.
+ * @VXGE_HW_FRAME_PROTO_UDP: UDP.
+ * @VXGE_HW_FRAME_PROTO_TCP_OR_UDP: TCP or UDP.
+ *
+ * Higher layer ethernet protocols and options.
+ */
+enum vxge_hw_frame_proto {
+	VXGE_HW_FRAME_PROTO_VLAN_TAGGED = 0x80,
+	VXGE_HW_FRAME_PROTO_IPV4		= 0x10,
+	VXGE_HW_FRAME_PROTO_IPV6		= 0x08,
+	VXGE_HW_FRAME_PROTO_IP_FRAG		= 0x04,
+	VXGE_HW_FRAME_PROTO_TCP			= 0x02,
+	VXGE_HW_FRAME_PROTO_UDP			= 0x01,
+	VXGE_HW_FRAME_PROTO_TCP_OR_UDP	= (VXGE_HW_FRAME_PROTO_TCP | \
+						   VXGE_HW_FRAME_PROTO_UDP)
+};
+
+/**
+ * enum enum vxge_hw_fifo_gather_code - Gather codes used in fifo TxD
+ * @VXGE_HW_FIFO_GATHER_CODE_FIRST: First TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_MIDDLE: Middle TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_LAST: Last TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_FIRST_LAST: First and Last TxDL.
+ *
+ * These gather codes are used to indicate the position of a TxD in a TxD list
+ */
+enum vxge_hw_fifo_gather_code {
+	VXGE_HW_FIFO_GATHER_CODE_FIRST		= 0x2,
+	VXGE_HW_FIFO_GATHER_CODE_MIDDLE		= 0x0,
+	VXGE_HW_FIFO_GATHER_CODE_LAST		= 0x1,
+	VXGE_HW_FIFO_GATHER_CODE_FIRST_LAST	= 0x3
+};
+
+/**
+ * enum enum vxge_hw_fifo_tcode - tcodes used in fifo
+ * @VXGE_HW_FIFO_T_CODE_OK: Transfer OK
+ * @VXGE_HW_FIFO_T_CODE_PCI_READ_CORRUPT: PCI read transaction (either TxD or
+ *             frame data) returned with corrupt data.
+ * @VXGE_HW_FIFO_T_CODE_PCI_READ_FAIL:PCI read transaction was returned
+ *             with no data.
+ * @VXGE_HW_FIFO_T_CODE_INVALID_MSS: The host attempted to send either a
+ *             frame or LSO MSS that was too long (>9800B).
+ * @VXGE_HW_FIFO_T_CODE_LSO_ERROR: Error detected during TCP/UDP Large Send
+	*	       Offload operation, due to improper header template,
+	*	       unsupported protocol, etc.
+ * @VXGE_HW_FIFO_T_CODE_UNUSED: Unused
+ * @VXGE_HW_FIFO_T_CODE_MULTI_ERROR: Set to 1 by the adapter if multiple
+ *             data buffer transfer errors are encountered (see below).
+ *             Otherwise it is set to 0.
+ *
+ * These tcodes are returned in various API for TxD status
+ */
+enum vxge_hw_fifo_tcode {
+	VXGE_HW_FIFO_T_CODE_OK			= 0x0,
+	VXGE_HW_FIFO_T_CODE_PCI_READ_CORRUPT	= 0x1,
+	VXGE_HW_FIFO_T_CODE_PCI_READ_FAIL	= 0x2,
+	VXGE_HW_FIFO_T_CODE_INVALID_MSS		= 0x3,
+	VXGE_HW_FIFO_T_CODE_LSO_ERROR		= 0x4,
+	VXGE_HW_FIFO_T_CODE_UNUSED		= 0x7,
+	VXGE_HW_FIFO_T_CODE_MULTI_ERROR		= 0x8
+};
+
+enum vxge_hw_status vxge_hw_fifo_txdl_reserve(
+	struct __vxge_hw_fifo *fifoh,
+	void **txdlh,
+	void **txdl_priv);
+
+void vxge_hw_fifo_txdl_buffer_set(
+			struct __vxge_hw_fifo *fifo_handle,
+			void *txdlh,
+			u32 frag_idx,
+			dma_addr_t dma_pointer,
+			u32 size);
+
+void vxge_hw_fifo_txdl_post(
+			struct __vxge_hw_fifo *fifo_handle,
+			void *txdlh);
+
+u32 vxge_hw_fifo_free_txdl_count_get(
+			struct __vxge_hw_fifo *fifo_handle);
+
+enum vxge_hw_status vxge_hw_fifo_txdl_next_completed(
+	struct __vxge_hw_fifo *fifoh,
+	void **txdlh,
+	enum vxge_hw_fifo_tcode *t_code);
+
+enum vxge_hw_status vxge_hw_fifo_handle_tcode(
+	struct __vxge_hw_fifo *fifoh,
+	void *txdlh,
+	enum vxge_hw_fifo_tcode t_code);
+
+void vxge_hw_fifo_txdl_free(
+	struct __vxge_hw_fifo *fifoh,
+	void *txdlh);
+
+/*
+ * Device
+ */
+
+#define VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET	(VXGE_HW_BLOCK_SIZE-8)
+#define VXGE_HW_RING_MEMBLOCK_IDX_OFFSET		(VXGE_HW_BLOCK_SIZE-16)
+#define VXGE_HW_RING_MIN_BUFF_ALLOCATION		64
+
+/*
+ * struct __vxge_hw_ring_rxd_priv - Receive descriptor HW-private data.
+ * @dma_addr: DMA (mapped) address of _this_ descriptor.
+ * @dma_handle: DMA handle used to map the descriptor onto device.
+ * @dma_offset: Descriptor's offset in the memory block. HW allocates
+ *              descriptors in memory blocks of %VXGE_HW_BLOCK_SIZE
+ *              bytes. Each memblock is contiguous DMA-able memory. Each
+ *              memblock contains 1 or more 4KB RxD blocks visible to the
+ *              Titan hardware.
+ * @dma_object: DMA address and handle of the memory block that contains
+ *              the descriptor. This member is used only in the "checked"
+ *              version of the HW (to enforce certain assertions);
+ *              otherwise it gets compiled out.
+ * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage.
+ *
+ * Per-receive decsriptor HW-private data. HW uses the space to keep DMA
+ * information associated with the descriptor. Note that driver can ask HW
+ * to allocate additional per-descriptor space for its own (driver-specific)
+ * purposes.
+ */
+struct __vxge_hw_ring_rxd_priv {
+	dma_addr_t	dma_addr;
+	struct pci_dev *dma_handle;
+	ptrdiff_t	dma_offset;
+#ifdef VXGE_DEBUG_ASSERT
+	struct vxge_hw_mempool_dma	*dma_object;
+#endif
+};
+
+/* ========================= RING PRIVATE API ============================= */
+u64
+__vxge_hw_ring_first_block_address_get(
+	struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_create(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	struct vxge_hw_ring_attr *attr);
+
+enum vxge_hw_status
+__vxge_hw_ring_abort(
+	struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_reset(
+	struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_delete(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+/* ========================= FIFO PRIVATE API ============================= */
+
+struct vxge_hw_fifo_attr;
+
+enum vxge_hw_status
+__vxge_hw_fifo_create(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	struct vxge_hw_fifo_attr *attr);
+
+enum vxge_hw_status
+__vxge_hw_fifo_abort(
+	struct __vxge_hw_fifo *fifoh);
+
+enum vxge_hw_status
+__vxge_hw_fifo_reset(
+	struct __vxge_hw_fifo *ringh);
+
+enum vxge_hw_status
+__vxge_hw_fifo_delete(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+struct vxge_hw_mempool_cbs {
+	void (*item_func_alloc)(
+			struct vxge_hw_mempool *mempoolh,
+			u32			memblock_index,
+			struct vxge_hw_mempool_dma	*dma_object,
+			u32			index,
+			u32			is_last);
+};
+
+void
+__vxge_hw_mempool_destroy(
+	struct vxge_hw_mempool *mempool);
+
+#define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath)				\
+		((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next)
+
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_get(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u32			action,
+	u32			rts_table,
+	u32			offset,
+	u64			*data1,
+	u64			*data2);
+
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_set(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u32			action,
+	u32			rts_table,
+	u32			offset,
+	u64			data1,
+	u64			data2);
+
+enum vxge_hw_status
+__vxge_hw_vpath_reset(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_sw_reset(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_enable(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+void
+__vxge_hw_vpath_prc_configure(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_kdfc_configure(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_mac_configure(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_tim_configure(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_initialize(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vp_initialize(
+	struct __vxge_hw_device *devh,
+	u32			vp_id,
+	struct vxge_hw_vp_config	*config);
+
+void
+__vxge_hw_vp_terminate(
+	struct __vxge_hw_device *devh,
+	u32			vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_alarm_process(
+	struct __vxge_hw_virtualpath	*vpath,
+	u32			skip_alarms);
+
+void vxge_hw_device_intr_enable(
+	struct __vxge_hw_device *devh);
+
+u32 vxge_hw_device_set_intr_type(struct __vxge_hw_device *devh, u32 intr_mode);
+
+void vxge_hw_device_intr_disable(
+	struct __vxge_hw_device *devh);
+
+void vxge_hw_device_mask_all(
+	struct __vxge_hw_device *devh);
+
+void vxge_hw_device_unmask_all(
+	struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_device_begin_irq(
+	struct __vxge_hw_device *devh,
+	u32 skip_alarms,
+	u64 *reason);
+
+void vxge_hw_device_clear_tx_rx(
+	struct __vxge_hw_device *devh);
+
+/*
+ *  Virtual Paths
+ */
+
+u32 vxge_hw_vpath_id(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_vpath_mac_addr_add_mode {
+	VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE = 0,
+	VXGE_HW_VPATH_MAC_ADDR_DISCARD_DUPLICATE = 1,
+	VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE = 2
+};
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_add(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN],
+	enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get_next(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_delete(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u8 (macaddr)[ETH_ALEN],
+	u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_add(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_get(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			*vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_get_next(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			*vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_delete(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_add(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_get(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			*etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_get_next(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			*etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_delete(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u64			etype);
+
+enum vxge_hw_status vxge_hw_vpath_promisc_enable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_promisc_disable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_bcast_enable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_mcast_enable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_mcast_disable(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_poll_rx(
+	struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status vxge_hw_vpath_poll_tx(
+	struct __vxge_hw_fifo *fifoh,
+	void **skb_ptr);
+
+enum vxge_hw_status vxge_hw_vpath_alarm_process(
+	struct __vxge_hw_vpath_handle *vpath_handle,
+	u32 skip_alarms);
+
+enum vxge_hw_status
+vxge_hw_vpath_msix_set(struct __vxge_hw_vpath_handle *vpath_handle,
+		       int *tim_msix_id, int alarm_msix_id);
+
+void
+vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vpath_handle,
+			int msix_id);
+
+void vxge_hw_device_flush_io(struct __vxge_hw_device *devh);
+
+void
+vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vpath_handle,
+			 int msix_id);
+
+void
+vxge_hw_vpath_msix_unmask(struct __vxge_hw_vpath_handle *vpath_handle,
+			  int msix_id);
+
+void
+vxge_hw_vpath_msix_mask_all(struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_intr_enable(
+				struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_intr_disable(
+				struct __vxge_hw_vpath_handle *vpath_handle);
+
+void vxge_hw_vpath_inta_mask_tx_rx(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+void vxge_hw_vpath_inta_unmask_tx_rx(
+	struct __vxge_hw_vpath_handle *vpath_handle);
+
+void
+vxge_hw_channel_msix_mask(struct __vxge_hw_channel *channelh, int msix_id);
+
+void
+vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channelh, int msix_id);
+
+enum vxge_hw_status
+vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh);
+
+void
+vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh);
+
+void
+vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel,
+				 void **dtrh);
+
+void
+vxge_hw_channel_dtr_complete(struct __vxge_hw_channel *channel);
+
+void
+vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh);
+
+int
+vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel);
+
+/* ========================== PRIVATE API ================================= */
+
+enum vxge_hw_status
+__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_device_handle_error(
+		struct __vxge_hw_device *hldev,
+		u32 vp_id,
+		enum vxge_hw_event type);
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-version.h linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-version.h
--- linux-libre-2.6.29-gnu1/drivers/net/vxge/vxge-version.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/vxge/vxge-version.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice.  This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-version.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ *                 Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_VERSION_H
+
+#define VXGE_VERSION_H
+
+#define VXGE_VERSION_MAJOR	"2"
+#define VXGE_VERSION_MINOR	"0"
+#define VXGE_VERSION_FIX	"1"
+#define VXGE_VERSION_BUILD	"17129"
+#define VXGE_VERSION_FOR	"k"
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/c101.c linux-libre-2.6.30-gnu1/drivers/net/wan/c101.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/c101.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/c101.c	2009-06-09 23:05:27.000000000 -0400
@@ -296,7 +296,13 @@ static void c101_destroy_card(card_t *ca
 	kfree(card);
 }
 
-
+static const struct net_device_ops c101_ops = {
+	.ndo_open       = c101_open,
+	.ndo_stop       = c101_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = c101_ioctl,
+};
 
 static int __init c101_run(unsigned long irq, unsigned long winbase)
 {
@@ -367,9 +373,7 @@ static int __init c101_run(unsigned long
 	dev->mem_start = winbase;
 	dev->mem_end = winbase + C101_MAPPED_RAM_SIZE - 1;
 	dev->tx_queue_len = 50;
-	dev->do_ioctl = c101_ioctl;
-	dev->open = c101_open;
-	dev->stop = c101_close;
+	dev->netdev_ops = &c101_ops;
 	hdlc->attach = sca_attach;
 	hdlc->xmit = sca_xmit;
 	card->settings.clock_type = CLOCK_EXT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/cosa.c linux-libre-2.6.30-gnu1/drivers/net/wan/cosa.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/cosa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/cosa.c	2009-06-09 23:05:27.000000000 -0400
@@ -427,6 +427,15 @@ static void __exit cosa_exit(void)
 }
 module_exit(cosa_exit);
 
+static const struct net_device_ops cosa_ops = {
+	.ndo_open       = cosa_net_open,
+	.ndo_stop       = cosa_net_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = cosa_net_ioctl,
+	.ndo_tx_timeout = cosa_net_timeout,
+};
+
 static int cosa_probe(int base, int irq, int dma)
 {
 	struct cosa_data *cosa = cosa_cards+nr_cards;
@@ -575,10 +584,7 @@ static int cosa_probe(int base, int irq,
 		}
 		dev_to_hdlc(chan->netdev)->attach = cosa_net_attach;
 		dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx;
-		chan->netdev->open = cosa_net_open;
-		chan->netdev->stop = cosa_net_close;
-		chan->netdev->do_ioctl = cosa_net_ioctl;
-		chan->netdev->tx_timeout = cosa_net_timeout;
+		chan->netdev->netdev_ops = &cosa_ops;
 		chan->netdev->watchdog_timeo = TX_TIMEOUT;
 		chan->netdev->base_addr = chan->cosa->datareg;
 		chan->netdev->irq = chan->cosa->irq;
@@ -725,8 +731,7 @@ static char *cosa_net_setup_rx(struct ch
 	 * We can safely fall back to non-dma-able memory, because we have
 	 * the cosa->bouncebuf pre-allocated.
 	 */
-	if (chan->rx_skb)
-		kfree_skb(chan->rx_skb);
+	kfree_skb(chan->rx_skb);
 	chan->rx_skb = dev_alloc_skb(size);
 	if (chan->rx_skb == NULL) {
 		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n",
@@ -993,8 +998,8 @@ static struct fasync_struct *fasync[256]
 static int cosa_fasync(struct inode *inode, struct file *file, int on)
 {
         int port = iminor(inode);
-        int rv = fasync_helper(inode, file, on, &fasync[port]);
-        return rv < 0 ? rv : 0;
+
+	return fasync_helper(inode, file, on, &fasync[port]);
 }
 #endif
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/cycx_x25.c linux-libre-2.6.30-gnu1/drivers/net/wan/cycx_x25.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/cycx_x25.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/cycx_x25.c	2009-06-09 23:05:27.000000000 -0400
@@ -355,12 +355,6 @@ static int cycx_wan_update(struct wan_de
 	return 0;
 }
 
-/* callback to initialize device */
-static void cycx_x25_chan_setup(struct net_device *dev)
-{
-	dev->init = cycx_netdevice_init;
-}
-
 /* Create new logical channel.
  * This routine is called by the router when ROUTER_IFNEW IOCTL is being
  * handled.
@@ -476,6 +470,27 @@ static const struct header_ops cycx_head
 	.rebuild = cycx_netdevice_rebuild_header,
 };
 
+static const struct net_device_ops cycx_netdev_ops = {
+	.ndo_init	= cycx_netdevice_init,
+	.ndo_open	= cycx_netdevice_open,
+	.ndo_stop	= cycx_netdevice_stop,
+	.ndo_start_xmit	= cycx_netdevice_hard_start_xmit,
+	.ndo_get_stats	= cycx_netdevice_get_stats,
+};
+
+static void cycx_x25_chan_setup(struct net_device *dev)
+{
+	/* Initialize device driver entry points */
+	dev->netdev_ops		= &cycx_netdev_ops;
+	dev->header_ops		= &cycx_header_ops;
+
+	/* Initialize media-specific parameters */
+	dev->mtu		= CYCX_X25_CHAN_MTU;
+	dev->type		= ARPHRD_HWX25;	/* ARP h/w type */
+	dev->hard_header_len	= 0;		/* media header length */
+	dev->addr_len		= 0;		/* hardware address length */
+}
+
 /* Initialize Linux network interface.
  *
  * This routine is called only once for each interface, during Linux network
@@ -487,20 +502,6 @@ static int cycx_netdevice_init(struct ne
 	struct cycx_device *card = chan->card;
 	struct wan_device *wandev = &card->wandev;
 
-	/* Initialize device driver entry points */
-	dev->open		= cycx_netdevice_open;
-	dev->stop		= cycx_netdevice_stop;
-	dev->header_ops		= &cycx_header_ops;
-
-	dev->hard_start_xmit	= cycx_netdevice_hard_start_xmit;
-	dev->get_stats		= cycx_netdevice_get_stats;
-
-	/* Initialize media-specific parameters */
-	dev->mtu		= CYCX_X25_CHAN_MTU;
-	dev->type		= ARPHRD_HWX25;	/* ARP h/w type */
-	dev->hard_header_len	= 0;		/* media header length */
-	dev->addr_len		= 0;		/* hardware address length */
-
 	if (!chan->svc)
 		*(__be16*)dev->dev_addr = htons(chan->lcn);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/dlci.c linux-libre-2.6.30-gnu1/drivers/net/wan/dlci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/dlci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/dlci.c	2009-06-09 23:05:27.000000000 -0400
@@ -114,7 +114,7 @@ static void dlci_receive(struct sk_buff
 	if (!pskb_may_pull(skb, sizeof(*hdr))) {
 		printk(KERN_NOTICE "%s: invalid data no header\n",
 		       dev->name);
-		dlp->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		kfree_skb(skb);
 		return;
 	}
@@ -127,7 +127,7 @@ static void dlci_receive(struct sk_buff
 	if (hdr->control != FRAD_I_UI)
 	{
 		printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
-		dlp->stats.rx_errors++;
+		dev->stats.rx_errors++;
 	}
 	else
 		switch(hdr->IP_NLPID)
@@ -136,14 +136,14 @@ static void dlci_receive(struct sk_buff
 				if (hdr->NLPID != FRAD_P_SNAP)
 				{
 					printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
-					dlp->stats.rx_errors++;
+					dev->stats.rx_errors++;
 					break;
 				}
 	 
 				if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
 				{
 					printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
-					dlp->stats.rx_errors++;
+					dev->stats.rx_errors++;
 					break;
 				}
 
@@ -164,12 +164,12 @@ static void dlci_receive(struct sk_buff
 			case FRAD_P_Q933:
 			case FRAD_P_CLNP:
 				printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
-				dlp->stats.rx_errors++;
+				dev->stats.rx_errors++;
 				break;
 
 			default:
 				printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
-				dlp->stats.rx_errors++;
+				dev->stats.rx_errors++;
 				break;				
 		}
 
@@ -178,9 +178,9 @@ static void dlci_receive(struct sk_buff
 		/* we've set up the protocol, so discard the header */
 		skb_reset_mac_header(skb);
 		skb_pull(skb, header);
-		dlp->stats.rx_bytes += skb->len;
+		dev->stats.rx_bytes += skb->len;
 		netif_rx(skb);
-		dlp->stats.rx_packets++;
+		dev->stats.rx_packets++;
 	}
 	else
 		dev_kfree_skb(skb);
@@ -200,19 +200,19 @@ static int dlci_transmit(struct sk_buff
 
 	netif_stop_queue(dev);
 	
-	ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+	ret = dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave);
 	switch (ret)
 	{
 		case DLCI_RET_OK:
-			dlp->stats.tx_packets++;
+			dev->stats.tx_packets++;
 			ret = 0;
 			break;
 			case DLCI_RET_ERR:
-			dlp->stats.tx_errors++;
+			dev->stats.tx_errors++;
 			ret = 0;
 			break;
 			case DLCI_RET_DROP:
-			dlp->stats.tx_dropped++;
+			dev->stats.tx_dropped++;
 			ret = 1;
 			break;
 	}
@@ -295,11 +295,9 @@ static int dlci_dev_ioctl(struct net_dev
 
 static int dlci_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct dlci_local *dlp;
-
-	dlp = netdev_priv(dev);
+	struct dlci_local *dlp = netdev_priv(dev);
 
-	return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+	return dev_set_mtu(dlp->slave, new_mtu);
 }
 
 static int dlci_open(struct net_device *dev)
@@ -342,15 +340,6 @@ static int dlci_close(struct net_device
 	return 0;
 }
 
-static struct net_device_stats *dlci_get_stats(struct net_device *dev)
-{
-	struct dlci_local *dlp;
-
-	dlp = netdev_priv(dev);
-
-	return(&dlp->stats);
-}
-
 static int dlci_add(struct dlci_add *dlci)
 {
 	struct net_device	*master, *slave;
@@ -488,18 +477,21 @@ static const struct header_ops dlci_head
 	.create	= dlci_header,
 };
 
+static const struct net_device_ops dlci_netdev_ops = {
+	.ndo_open	= dlci_open,
+	.ndo_stop	= dlci_close,
+	.ndo_do_ioctl	= dlci_dev_ioctl,
+	.ndo_start_xmit	= dlci_transmit,
+	.ndo_change_mtu	= dlci_change_mtu,
+};
+
 static void dlci_setup(struct net_device *dev)
 {
 	struct dlci_local *dlp = netdev_priv(dev);
 
 	dev->flags		= 0;
-	dev->open		= dlci_open;
-	dev->stop		= dlci_close;
-	dev->do_ioctl		= dlci_dev_ioctl;
-	dev->hard_start_xmit	= dlci_transmit;
 	dev->header_ops		= &dlci_header_ops;
-	dev->get_stats		= dlci_get_stats;
-	dev->change_mtu		= dlci_change_mtu;
+	dev->netdev_ops		= &dlci_netdev_ops;
 	dev->destructor		= free_netdev;
 
 	dlp->receive		= dlci_receive;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/dscc4.c linux-libre-2.6.30-gnu1/drivers/net/wan/dscc4.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/dscc4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/dscc4.c	2009-06-09 23:05:27.000000000 -0400
@@ -883,6 +883,15 @@ static inline int dscc4_set_quartz(struc
 	return ret;
 }
 
+static const struct net_device_ops dscc4_ops = {
+	.ndo_open       = dscc4_open,
+	.ndo_stop       = dscc4_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = dscc4_ioctl,
+	.ndo_tx_timeout = dscc4_tx_timeout,
+};
+
 static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
 {
 	struct dscc4_pci_priv *ppriv;
@@ -916,13 +925,8 @@ static int dscc4_found1(struct pci_dev *
 		hdlc_device *hdlc = dev_to_hdlc(d);
 
 	        d->base_addr = (unsigned long)ioaddr;
-		d->init = NULL;
 	        d->irq = pdev->irq;
-	        d->open = dscc4_open;
-	        d->stop = dscc4_close;
-		d->set_multicast_list = NULL;
-	        d->do_ioctl = dscc4_ioctl;
-		d->tx_timeout = dscc4_tx_timeout;
+		d->netdev_ops = &dscc4_ops;
 		d->watchdog_timeo = TX_TIMEOUT;
 		SET_NETDEV_DEV(d, &pdev->dev);
 
@@ -1048,7 +1052,7 @@ static int dscc4_open(struct net_device
 	struct dscc4_pci_priv *ppriv;
 	int ret = -EAGAIN;
 
-	if ((dscc4_loopback_check(dpriv) < 0) || !dev->hard_start_xmit)
+	if ((dscc4_loopback_check(dpriv) < 0))
 		goto err;
 
 	if ((ret = hdlc_open(dev)))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/farsync.c linux-libre-2.6.30-gnu1/drivers/net/wan/farsync.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/farsync.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/farsync.c	2009-06-09 23:05:27.000000000 -0400
@@ -69,7 +69,7 @@ MODULE_LICENSE("GPL");
 #endif
 
 /*
- * Modules parameters and associated varaibles
+ * Modules parameters and associated variables
  */
 static int fst_txq_low = FST_LOW_WATER_MARK;
 static int fst_txq_high = FST_HIGH_WATER_MARK;
@@ -2424,6 +2424,15 @@ fst_init_card(struct fst_card_info *card
 	       type_strings[card->type], card->irq, card->nports);
 }
 
+static const struct net_device_ops fst_ops = {
+	.ndo_open       = fst_open,
+	.ndo_stop       = fst_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = fst_ioctl,
+	.ndo_tx_timeout = fst_tx_timeout,
+};
+
 /*
  *      Initialise card when detected.
  *      Returns 0 to indicate success, or errno otherwise.
@@ -2565,12 +2574,9 @@ fst_add_one(struct pci_dev *pdev, const
                 dev->base_addr   = card->pci_conf;
                 dev->irq         = card->irq;
 
-                dev->tx_queue_len          = FST_TX_QUEUE_LEN;
-                dev->open                  = fst_open;
-                dev->stop                  = fst_close;
-                dev->do_ioctl              = fst_ioctl;
-                dev->watchdog_timeo        = FST_TX_TIMEOUT;
-                dev->tx_timeout            = fst_tx_timeout;
+		dev->netdev_ops = &fst_ops;
+		dev->tx_queue_len = FST_TX_QUEUE_LEN;
+		dev->watchdog_timeo = FST_TX_TIMEOUT;
                 hdlc->attach = fst_attach;
                 hdlc->xmit   = fst_start_xmit;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hd64572.c linux-libre-2.6.30-gnu1/drivers/net/wan/hd64572.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hd64572.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hd64572.c	2009-06-09 23:05:27.000000000 -0400
@@ -341,7 +341,7 @@ static int sca_poll(struct napi_struct *
 		received = sca_rx_done(port, budget);
 
 	if (received < budget) {
-		netif_rx_complete(napi);
+		napi_complete(napi);
 		enable_intr(port);
 	}
 
@@ -359,7 +359,7 @@ static irqreturn_t sca_intr(int irq, voi
 		if (port && (isr0 & (i ? 0x08002200 : 0x00080022))) {
 			handled = 1;
 			disable_intr(port);
-			netif_rx_schedule(&port->napi);
+			napi_schedule(&port->napi);
 		}
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,7 +44,7 @@ static const char* version = "HDLC suppo
 
 static struct hdlc_proto *first_proto;
 
-static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
+int hdlc_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
 		return -EINVAL;
@@ -52,15 +52,6 @@ static int hdlc_change_mtu(struct net_de
 	return 0;
 }
 
-
-
-static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
-{
-	return &dev->stats;
-}
-
-
-
 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
 		    struct packet_type *p, struct net_device *orig_dev)
 {
@@ -75,7 +66,15 @@ static int hdlc_rcv(struct sk_buff *skb,
 	return hdlc->proto->netif_rx(skb);
 }
 
+int hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	hdlc_device *hdlc = dev_to_hdlc(dev);
 
+	if (hdlc->proto->xmit)
+		return hdlc->proto->xmit(skb, dev);
+
+	return hdlc->xmit(skb, dev); /* call hardware driver directly */
+}
 
 static inline void hdlc_proto_start(struct net_device *dev)
 {
@@ -102,11 +101,11 @@ static int hdlc_device_event(struct noti
 	hdlc_device *hdlc;
 	unsigned long flags;
 	int on;
- 
+
 	if (dev_net(dev) != &init_net)
 		return NOTIFY_DONE;
 
-	if (dev->get_stats != hdlc_get_stats)
+	if (!(dev->priv_flags & IFF_WAN_HDLC))
 		return NOTIFY_DONE; /* not an HDLC device */
 
 	if (event != NETDEV_CHANGE)
@@ -233,15 +232,13 @@ static void hdlc_setup_dev(struct net_de
 	/* Re-init all variables changed by HDLC protocol drivers,
 	 * including ether_setup() called from hdlc_raw_eth.c.
 	 */
-	dev->get_stats		 = hdlc_get_stats;
 	dev->flags		 = IFF_POINTOPOINT | IFF_NOARP;
+	dev->priv_flags		 = IFF_WAN_HDLC;
 	dev->mtu		 = HDLC_MAX_MTU;
 	dev->type		 = ARPHRD_RAWHDLC;
 	dev->hard_header_len	 = 16;
 	dev->addr_len		 = 0;
 	dev->header_ops		 = &hdlc_null_ops;
-
-	dev->change_mtu		 = hdlc_change_mtu;
 }
 
 static void hdlc_setup(struct net_device *dev)
@@ -339,6 +336,8 @@ MODULE_AUTHOR("Krzysztof Halasa <khc@pm.
 MODULE_DESCRIPTION("HDLC support module");
 MODULE_LICENSE("GPL v2");
 
+EXPORT_SYMBOL(hdlc_change_mtu);
+EXPORT_SYMBOL(hdlc_start_xmit);
 EXPORT_SYMBOL(hdlc_open);
 EXPORT_SYMBOL(hdlc_close);
 EXPORT_SYMBOL(hdlc_ioctl);
@@ -349,8 +348,8 @@ EXPORT_SYMBOL(unregister_hdlc_protocol);
 EXPORT_SYMBOL(attach_hdlc_protocol);
 EXPORT_SYMBOL(detach_hdlc_protocol);
 
-static struct packet_type hdlc_packet_type = {
-	.type = __constant_htons(ETH_P_HDLC),
+static struct packet_type hdlc_packet_type __read_mostly = {
+	.type = cpu_to_be16(ETH_P_HDLC),
 	.func = hdlc_rcv,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_cisco.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_cisco.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_cisco.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_cisco.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,7 @@ static void cisco_keepalive_send(struct
 	data->type = htonl(type);
 	data->par1 = par1;
 	data->par2 = par2;
-	data->rel = __constant_htons(0xFFFF);
+	data->rel = cpu_to_be16(0xFFFF);
 	/* we will need do_div here if 1000 % HZ != 0 */
 	data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
 
@@ -136,20 +136,20 @@ static __be16 cisco_type_trans(struct sk
 	struct hdlc_header *data = (struct hdlc_header*)skb->data;
 
 	if (skb->len < sizeof(struct hdlc_header))
-		return __constant_htons(ETH_P_HDLC);
+		return cpu_to_be16(ETH_P_HDLC);
 
 	if (data->address != CISCO_MULTICAST &&
 	    data->address != CISCO_UNICAST)
-		return __constant_htons(ETH_P_HDLC);
+		return cpu_to_be16(ETH_P_HDLC);
 
 	switch(data->protocol) {
-	case __constant_htons(ETH_P_IP):
-	case __constant_htons(ETH_P_IPX):
-	case __constant_htons(ETH_P_IPV6):
+	case cpu_to_be16(ETH_P_IP):
+	case cpu_to_be16(ETH_P_IPX):
+	case cpu_to_be16(ETH_P_IPV6):
 		skb_pull(skb, sizeof(struct hdlc_header));
 		return data->protocol;
 	default:
-		return __constant_htons(ETH_P_HDLC);
+		return cpu_to_be16(ETH_P_HDLC);
 	}
 }
 
@@ -194,7 +194,7 @@ static int cisco_rx(struct sk_buff *skb)
 		case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
 			in_dev = dev->ip_ptr;
 			addr = 0;
-			mask = __constant_htonl(~0); /* is the mask correct? */
+			mask = ~cpu_to_be32(0); /* is the mask correct? */
 
 			if (in_dev != NULL) {
 				struct in_ifaddr **ifap = &in_dev->ifa_list;
@@ -382,7 +382,6 @@ static int cisco_ioctl(struct net_device
 
 		memcpy(&state(hdlc)->settings, &new_settings, size);
 		spin_lock_init(&state(hdlc)->lock);
-		dev->hard_start_xmit = hdlc->xmit;
 		dev->header_ops = &cisco_header_ops;
 		dev->type = ARPHRD_CISCO;
 		netif_dormant_on(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_fr.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_fr.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_fr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_fr.c	2009-06-09 23:05:27.000000000 -0400
@@ -278,31 +278,31 @@ static int fr_hard_header(struct sk_buff
 	struct sk_buff *skb = *skb_p;
 
 	switch (skb->protocol) {
-	case __constant_htons(NLPID_CCITT_ANSI_LMI):
+	case cpu_to_be16(NLPID_CCITT_ANSI_LMI):
 		head_len = 4;
 		skb_push(skb, head_len);
 		skb->data[3] = NLPID_CCITT_ANSI_LMI;
 		break;
 
-	case __constant_htons(NLPID_CISCO_LMI):
+	case cpu_to_be16(NLPID_CISCO_LMI):
 		head_len = 4;
 		skb_push(skb, head_len);
 		skb->data[3] = NLPID_CISCO_LMI;
 		break;
 
-	case __constant_htons(ETH_P_IP):
+	case cpu_to_be16(ETH_P_IP):
 		head_len = 4;
 		skb_push(skb, head_len);
 		skb->data[3] = NLPID_IP;
 		break;
 
-	case __constant_htons(ETH_P_IPV6):
+	case cpu_to_be16(ETH_P_IPV6):
 		head_len = 4;
 		skb_push(skb, head_len);
 		skb->data[3] = NLPID_IPV6;
 		break;
 
-	case __constant_htons(ETH_P_802_3):
+	case cpu_to_be16(ETH_P_802_3):
 		head_len = 10;
 		if (skb_headroom(skb) < head_len) {
 			struct sk_buff *skb2 = skb_realloc_headroom(skb,
@@ -426,7 +426,7 @@ static int pvc_xmit(struct sk_buff *skb,
 				skb_put(skb, pad);
 				memset(skb->data + len, 0, pad);
 			}
-			skb->protocol = __constant_htons(ETH_P_802_3);
+			skb->protocol = cpu_to_be16(ETH_P_802_3);
 		}
 		if (!fr_hard_header(&skb, pvc->dlci)) {
 			dev->stats.tx_bytes += skb->len;
@@ -444,18 +444,6 @@ static int pvc_xmit(struct sk_buff *skb,
 	return 0;
 }
 
-
-
-static int pvc_change_mtu(struct net_device *dev, int new_mtu)
-{
-	if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
-		return -EINVAL;
-	dev->mtu = new_mtu;
-	return 0;
-}
-
-
-
 static inline void fr_log_dlci_active(pvc_device *pvc)
 {
 	printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
@@ -508,10 +496,10 @@ static void fr_lmi_send(struct net_devic
 	memset(skb->data, 0, len);
 	skb_reserve(skb, 4);
 	if (lmi == LMI_CISCO) {
-		skb->protocol = __constant_htons(NLPID_CISCO_LMI);
+		skb->protocol = cpu_to_be16(NLPID_CISCO_LMI);
 		fr_hard_header(&skb, LMI_CISCO_DLCI);
 	} else {
-		skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
+		skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI);
 		fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
 	}
 	data = skb_tail_pointer(skb);
@@ -1068,6 +1056,14 @@ static void pvc_setup(struct net_device
 	dev->addr_len = 2;
 }
 
+static const struct net_device_ops pvc_ops = {
+	.ndo_open       = pvc_open,
+	.ndo_stop       = pvc_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = pvc_xmit,
+	.ndo_do_ioctl   = pvc_ioctl,
+};
+
 static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 {
 	hdlc_device *hdlc = dev_to_hdlc(frad);
@@ -1104,11 +1100,7 @@ static int fr_add_pvc(struct net_device
 		*(__be16*)dev->dev_addr = htons(dlci);
 		dlci_to_q922(dev->broadcast, dlci);
 	}
-	dev->hard_start_xmit = pvc_xmit;
-	dev->open = pvc_open;
-	dev->stop = pvc_close;
-	dev->do_ioctl = pvc_ioctl;
-	dev->change_mtu = pvc_change_mtu;
+	dev->netdev_ops = &pvc_ops;
 	dev->mtu = HDLC_MAX_MTU;
 	dev->tx_queue_len = 0;
 	dev->ml_priv = pvc;
@@ -1260,8 +1252,6 @@ static int fr_ioctl(struct net_device *d
 			state(hdlc)->dce_pvc_count = 0;
 		}
 		memcpy(&state(hdlc)->settings, &new_settings, size);
-
-		dev->hard_start_xmit = hdlc->xmit;
 		dev->type = ARPHRD_FRAD;
 		return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_ppp.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_ppp.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_ppp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_ppp.c	2009-06-09 23:05:27.000000000 -0400
@@ -150,11 +150,11 @@ static __be16 ppp_type_trans(struct sk_b
 		return htons(ETH_P_HDLC);
 
 	switch (data->protocol) {
-	case __constant_htons(PID_IP):
+	case cpu_to_be16(PID_IP):
 		skb_pull(skb, sizeof(struct hdlc_header));
 		return htons(ETH_P_IP);
 
-	case __constant_htons(PID_IPV6):
+	case cpu_to_be16(PID_IPV6):
 		skb_pull(skb, sizeof(struct hdlc_header));
 		return htons(ETH_P_IPV6);
 
@@ -558,7 +558,6 @@ out:
 	return NET_RX_DROP;
 }
 
-
 static void ppp_timer(unsigned long arg)
 {
 	struct proto *proto = (struct proto *)arg;
@@ -679,7 +678,6 @@ static int ppp_ioctl(struct net_device *
 		ppp->keepalive_interval = 10;
 		ppp->keepalive_timeout = 60;
 
-		dev->hard_start_xmit = hdlc->xmit;
 		dev->hard_header_len = sizeof(struct hdlc_header);
 		dev->header_ops = &ppp_header_ops;
 		dev->type = ARPHRD_PPP;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_raw.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_raw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_raw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_raw.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,11 +27,9 @@ static int raw_ioctl(struct net_device *
 
 static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-	return __constant_htons(ETH_P_IP);
+	return cpu_to_be16(ETH_P_IP);
 }
 
-
-
 static struct hdlc_proto proto = {
 	.type_trans	= raw_type_trans,
 	.ioctl		= raw_ioctl,
@@ -86,7 +84,6 @@ static int raw_ioctl(struct net_device *
 		if (result)
 			return result;
 		memcpy(hdlc->state, &new_settings, size);
-		dev->hard_start_xmit = hdlc->xmit;
 		dev->type = ARPHRD_RAWHDLC;
 		netif_dormant_off(dev);
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_raw_eth.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_raw_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_raw_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_raw_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -45,6 +45,7 @@ static int eth_tx(struct sk_buff *skb, s
 
 static struct hdlc_proto proto = {
 	.type_trans	= eth_type_trans,
+	.xmit		= eth_tx,
 	.ioctl		= raw_eth_ioctl,
 	.module		= THIS_MODULE,
 };
@@ -56,9 +57,7 @@ static int raw_eth_ioctl(struct net_devi
 	const size_t size = sizeof(raw_hdlc_proto);
 	raw_hdlc_proto new_settings;
 	hdlc_device *hdlc = dev_to_hdlc(dev);
-	int result;
-	int (*old_ch_mtu)(struct net_device *, int);
-	int old_qlen;
+	int result, old_qlen;
 
 	switch (ifr->ifr_settings.type) {
 	case IF_GET_PROTO:
@@ -99,11 +98,8 @@ static int raw_eth_ioctl(struct net_devi
 		if (result)
 			return result;
 		memcpy(hdlc->state, &new_settings, size);
-		dev->hard_start_xmit = eth_tx;
-		old_ch_mtu = dev->change_mtu;
 		old_qlen = dev->tx_queue_len;
 		ether_setup(dev);
-		dev->change_mtu = old_ch_mtu;
 		dev->tx_queue_len = old_qlen;
 		random_ether_addr(dev->dev_addr);
 		netif_dormant_off(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_x25.c linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_x25.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hdlc_x25.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hdlc_x25.c	2009-06-09 23:05:27.000000000 -0400
@@ -184,6 +184,7 @@ static struct hdlc_proto proto = {
 	.close		= x25_close,
 	.ioctl		= x25_ioctl,
 	.netif_rx	= x25_rx,
+	.xmit		= x25_xmit,
 	.module		= THIS_MODULE,
 };
 
@@ -213,7 +214,6 @@ static int x25_ioctl(struct net_device *
 
 		if ((result = attach_hdlc_protocol(dev, &proto, 0)))
 			return result;
-		dev->hard_start_xmit = x25_xmit;
 		dev->type = ARPHRD_X25;
 		netif_dormant_off(dev);
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/hostess_sv11.c linux-libre-2.6.30-gnu1/drivers/net/wan/hostess_sv11.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/hostess_sv11.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/hostess_sv11.c	2009-06-09 23:05:27.000000000 -0400
@@ -173,6 +173,14 @@ static int hostess_attach(struct net_dev
  *	Description block for a Comtrol Hostess SV11 card
  */
 
+static const struct net_device_ops hostess_ops = {
+	.ndo_open       = hostess_open,
+	.ndo_stop       = hostess_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hostess_ioctl,
+};
+
 static struct z8530_dev *sv11_init(int iobase, int irq)
 {
 	struct z8530_dev *sv;
@@ -267,9 +275,7 @@ static struct z8530_dev *sv11_init(int i
 
 	dev_to_hdlc(netdev)->attach = hostess_attach;
 	dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
-	netdev->open = hostess_open;
-	netdev->stop = hostess_close;
-	netdev->do_ioctl = hostess_ioctl;
+	netdev->netdev_ops = &hostess_ops;
 	netdev->base_addr = iobase;
 	netdev->irq = irq;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/ixp4xx_hss.c linux-libre-2.6.30-gnu1/drivers/net/wan/ixp4xx_hss.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/ixp4xx_hss.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/ixp4xx_hss.c	2009-06-09 23:05:27.000000000 -0400
@@ -622,7 +622,7 @@ static void hss_hdlc_rx_irq(void *pdev)
 	printk(KERN_DEBUG "%s: hss_hdlc_rx_irq\n", dev->name);
 #endif
 	qmgr_disable_irq(queue_ids[port->id].rx);
-	netif_rx_schedule(&port->napi);
+	napi_schedule(&port->napi);
 }
 
 static int hss_hdlc_poll(struct napi_struct *napi, int budget)
@@ -649,15 +649,15 @@ static int hss_hdlc_poll(struct napi_str
 		if ((n = queue_get_desc(rxq, port, 0)) < 0) {
 #if DEBUG_RX
 			printk(KERN_DEBUG "%s: hss_hdlc_poll"
-			       " netif_rx_complete\n", dev->name);
+			       " napi_complete\n", dev->name);
 #endif
-			netif_rx_complete(napi);
+			napi_complete(napi);
 			qmgr_enable_irq(rxq);
 			if (!qmgr_stat_empty(rxq) &&
-			    netif_rx_reschedule(napi)) {
+			    napi_reschedule(napi)) {
 #if DEBUG_RX
 				printk(KERN_DEBUG "%s: hss_hdlc_poll"
-				       " netif_rx_reschedule succeeded\n",
+				       " napi_reschedule succeeded\n",
 				       dev->name);
 #endif
 				qmgr_disable_irq(rxq);
@@ -1069,7 +1069,7 @@ static int hss_hdlc_open(struct net_devi
 	hss_start_hdlc(port);
 
 	/* we may already have RX data, enables IRQ */
-	netif_rx_schedule(&port->napi);
+	napi_schedule(&port->napi);
 	return 0;
 
 err_unlock:
@@ -1230,6 +1230,14 @@ static int hss_hdlc_ioctl(struct net_dev
  * initialization
  ****************************************************************************/
 
+static const struct net_device_ops hss_hdlc_ops = {
+	.ndo_open       = hss_hdlc_open,
+	.ndo_stop       = hss_hdlc_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = hss_hdlc_ioctl,
+};
+
 static int __devinit hss_init_one(struct platform_device *pdev)
 {
 	struct port *port;
@@ -1241,7 +1249,7 @@ static int __devinit hss_init_one(struct
 		return -ENOMEM;
 
 	if ((port->npe = npe_request(0)) == NULL) {
-		err = -ENOSYS;
+		err = -ENODEV;
 		goto err_free;
 	}
 
@@ -1254,9 +1262,7 @@ static int __devinit hss_init_one(struct
 	hdlc = dev_to_hdlc(dev);
 	hdlc->attach = hss_hdlc_attach;
 	hdlc->xmit = hss_hdlc_xmit;
-	dev->open = hss_hdlc_open;
-	dev->stop = hss_hdlc_close;
-	dev->do_ioctl = hss_hdlc_ioctl;
+	dev->netdev_ops = &hss_hdlc_ops;
 	dev->tx_queue_len = 100;
 	port->clock_type = CLOCK_EXT;
 	port->clock_rate = 2048000;
@@ -1305,7 +1311,7 @@ static int __init hss_init_module(void)
 	if ((ixp4xx_read_feature_bits() &
 	     (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
 	    (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS))
-		return -ENOSYS;
+		return -ENODEV;
 
 	spin_lock_init(&npe_lock);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/lapbether.c linux-libre-2.6.30-gnu1/drivers/net/wan/lapbether.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/lapbether.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/lapbether.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,7 +55,6 @@ struct lapbethdev {
 	struct list_head	node;
 	struct net_device	*ethdev;	/* link to ethernet device */
 	struct net_device	*axdev;		/* lapbeth device (lapb#) */
-	struct net_device_stats stats;		/* some statistics */
 };
 
 static LIST_HEAD(lapbeth_devices);
@@ -107,10 +106,9 @@ static int lapbeth_rcv(struct sk_buff *s
 	if (!netif_running(lapbeth->axdev))
 		goto drop_unlock;
 
-	lapbeth->stats.rx_packets++;
-
 	len = skb->data[0] + skb->data[1] * 256;
-	lapbeth->stats.rx_bytes += len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += len;
 
 	skb_pull(skb, 2);	/* Remove the length bytes */
 	skb_trim(skb, len);	/* Set the length of the data */
@@ -210,8 +208,8 @@ static void lapbeth_data_transmit(struct
 	*ptr++ = size % 256;
 	*ptr++ = size / 256;
 
-	lapbeth->stats.tx_packets++;
-	lapbeth->stats.tx_bytes += size;
+	ndev->stats.tx_packets++;
+	ndev->stats.tx_bytes += size;
 
 	skb->dev = dev = lapbeth->ethdev;
 
@@ -255,15 +253,6 @@ static void lapbeth_disconnected(struct
 }
 
 /*
- *	Statistics
- */
-static struct net_device_stats *lapbeth_get_stats(struct net_device *dev)
-{
-	struct lapbethdev *lapbeth = netdev_priv(dev);
-	return &lapbeth->stats;
-}
-
-/*
  *	Set AX.25 callsign
  */
 static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
@@ -314,14 +303,17 @@ static int lapbeth_close(struct net_devi
 
 /* ------------------------------------------------------------------------ */
 
+static const struct net_device_ops lapbeth_netdev_ops = {
+	.ndo_open	     = lapbeth_open,
+	.ndo_stop	     = lapbeth_close,
+	.ndo_start_xmit	     = lapbeth_xmit,
+	.ndo_set_mac_address = lapbeth_set_mac_address,
+};
+
 static void lapbeth_setup(struct net_device *dev)
 {
-	dev->hard_start_xmit = lapbeth_xmit;
-	dev->open	     = lapbeth_open;
-	dev->stop	     = lapbeth_close;
+	dev->netdev_ops	     = &lapbeth_netdev_ops;
 	dev->destructor	     = free_netdev;
-	dev->set_mac_address = lapbeth_set_mac_address;
-	dev->get_stats	     = lapbeth_get_stats;
 	dev->type            = ARPHRD_X25;
 	dev->hard_header_len = 3;
 	dev->mtu             = 1000;
@@ -421,8 +413,8 @@ static int lapbeth_device_event(struct n
 
 /* ------------------------------------------------------------------------ */
 
-static struct packet_type lapbeth_packet_type = {
-	.type = __constant_htons(ETH_P_DEC),
+static struct packet_type lapbeth_packet_type __read_mostly = {
+	.type = cpu_to_be16(ETH_P_DEC),
 	.func = lapbeth_rcv,
 };
 
@@ -430,7 +422,8 @@ static struct notifier_block lapbeth_dev
 	.notifier_call = lapbeth_device_event,
 };
 
-static char banner[] __initdata = KERN_INFO "LAPB Ethernet driver version 0.02\n";
+static const char banner[] __initconst =
+	KERN_INFO "LAPB Ethernet driver version 0.02\n";
 
 static int __init lapbeth_init_driver(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/lmc/lmc_main.c linux-libre-2.6.30-gnu1/drivers/net/wan/lmc/lmc_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/lmc/lmc_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/lmc/lmc_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -806,6 +806,16 @@ static int lmc_attach(struct net_device
 	return -EINVAL;
 }
 
+static const struct net_device_ops lmc_ops = {
+	.ndo_open       = lmc_open,
+	.ndo_stop       = lmc_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = lmc_ioctl,
+	.ndo_tx_timeout = lmc_driver_timeout,
+	.ndo_get_stats  = lmc_get_stats,
+};
+
 static int __devinit lmc_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -849,11 +859,7 @@ static int __devinit lmc_init_one(struct
 	dev->type = ARPHRD_HDLC;
 	dev_to_hdlc(dev)->xmit = lmc_start_xmit;
 	dev_to_hdlc(dev)->attach = lmc_attach;
-	dev->open = lmc_open;
-	dev->stop = lmc_close;
-	dev->get_stats = lmc_get_stats;
-	dev->do_ioctl = lmc_ioctl;
-	dev->tx_timeout = lmc_driver_timeout;
+	dev->netdev_ops = &lmc_ops;
 	dev->watchdog_timeo = HZ; /* 1 second */
 	dev->tx_queue_len = 100;
 	sc->lmc_device = dev;
@@ -1059,9 +1065,6 @@ static int lmc_open(struct net_device *d
     if ((err = lmc_proto_open(sc)) != 0)
 	    return err;
 
-    dev->do_ioctl = lmc_ioctl;
-
-
     netif_start_queue(dev);
     sc->extra_stats.tx_tbusy0++;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/lmc/lmc_proto.c linux-libre-2.6.30-gnu1/drivers/net/wan/lmc/lmc_proto.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/lmc/lmc_proto.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/lmc/lmc_proto.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,30 +51,15 @@
 void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
 {
     lmc_trace(sc->lmc_device, "lmc_proto_attach in");
-    switch(sc->if_type){
-    case LMC_PPP:
-        {
-            struct net_device *dev = sc->lmc_device;
-            dev->do_ioctl = lmc_ioctl;
-        }
-        break;
-    case LMC_NET:
-        {
+    if (sc->if_type == LMC_NET) {
             struct net_device *dev = sc->lmc_device;
             /*
 	     * They set a few basics because they don't use HDLC
              */
             dev->flags |= IFF_POINTOPOINT;
-
             dev->hard_header_len = 0;
             dev->addr_len = 0;
         }
-    case LMC_RAW: /* Setup the task queue, maybe we should notify someone? */
-        {
-        }
-    default:
-        break;
-    }
     lmc_trace(sc->lmc_device, "lmc_proto_attach out");
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/n2.c linux-libre-2.6.30-gnu1/drivers/net/wan/n2.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/n2.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/n2.c	2009-06-09 23:05:27.000000000 -0400
@@ -324,7 +324,13 @@ static void n2_destroy_card(card_t *card
 	kfree(card);
 }
 
-
+static const struct net_device_ops n2_ops = {
+	.ndo_open       = n2_open,
+	.ndo_stop       = n2_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = n2_ioctl,
+};
 
 static int __init n2_run(unsigned long io, unsigned long irq,
 			 unsigned long winbase, long valid0, long valid1)
@@ -460,9 +466,7 @@ static int __init n2_run(unsigned long i
 		dev->mem_start = winbase;
 		dev->mem_end = winbase + USE_WINDOWSIZE - 1;
 		dev->tx_queue_len = 50;
-		dev->do_ioctl = n2_ioctl;
-		dev->open = n2_open;
-		dev->stop = n2_close;
+		dev->netdev_ops = &n2_ops;
 		hdlc->attach = sca_attach;
 		hdlc->xmit = sca_xmit;
 		port->settings.clock_type = CLOCK_EXT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/pc300too.c linux-libre-2.6.30-gnu1/drivers/net/wan/pc300too.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/pc300too.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/pc300too.c	2009-06-09 23:05:27.000000000 -0400
@@ -287,7 +287,13 @@ static void pc300_pci_remove_one(struct
 	kfree(card);
 }
 
-
+static const struct net_device_ops pc300_ops = {
+	.ndo_open       = pc300_open,
+	.ndo_stop       = pc300_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = pc300_ioctl,
+};
 
 static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 					const struct pci_device_id *ent)
@@ -448,9 +454,7 @@ static int __devinit pc300_pci_init_one(
 		dev->mem_start = ramphys;
 		dev->mem_end = ramphys + ramsize - 1;
 		dev->tx_queue_len = 50;
-		dev->do_ioctl = pc300_ioctl;
-		dev->open = pc300_open;
-		dev->stop = pc300_close;
+		dev->netdev_ops = &pc300_ops;
 		hdlc->attach = sca_attach;
 		hdlc->xmit = sca_xmit;
 		port->settings.clock_type = CLOCK_EXT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/pci200syn.c linux-libre-2.6.30-gnu1/drivers/net/wan/pci200syn.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/pci200syn.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/pci200syn.c	2009-06-09 23:05:27.000000000 -0400
@@ -265,7 +265,13 @@ static void pci200_pci_remove_one(struct
 	kfree(card);
 }
 
-
+static const struct net_device_ops pci200_ops = {
+	.ndo_open       = pci200_open,
+	.ndo_stop       = pci200_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = pci200_ioctl,
+};
 
 static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 					 const struct pci_device_id *ent)
@@ -395,9 +401,7 @@ static int __devinit pci200_pci_init_one
 		dev->mem_start = ramphys;
 		dev->mem_end = ramphys + ramsize - 1;
 		dev->tx_queue_len = 50;
-		dev->do_ioctl = pci200_ioctl;
-		dev->open = pci200_open;
-		dev->stop = pci200_close;
+		dev->netdev_ops = &pci200_ops;
 		hdlc->attach = sca_attach;
 		hdlc->xmit = sca_xmit;
 		port->settings.clock_type = CLOCK_EXT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/sbni.c linux-libre-2.6.30-gnu1/drivers/net/wan/sbni.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/sbni.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/sbni.c	2009-06-09 23:05:27.000000000 -0400
@@ -68,7 +68,6 @@
 /* device private data */
 
 struct net_local {
-	struct net_device_stats	stats;
 	struct timer_list	watchdog;
 
 	spinlock_t	lock;
@@ -117,7 +116,6 @@ static int  sbni_open( struct net_device
 static int  sbni_close( struct net_device * );
 static int  sbni_start_xmit( struct sk_buff *, struct net_device * );
 static int  sbni_ioctl( struct net_device *, struct ifreq *, int );
-static struct net_device_stats  *sbni_get_stats( struct net_device * );
 static void  set_multicast_list( struct net_device * );
 
 static irqreturn_t sbni_interrupt( int, void * );
@@ -208,15 +206,21 @@ sbni_isa_probe( struct net_device  *dev
 	}
 }
 
+static const struct net_device_ops sbni_netdev_ops = {
+	.ndo_open		= sbni_open,
+	.ndo_stop		= sbni_close,
+	.ndo_start_xmit		= sbni_start_xmit,
+	.ndo_set_multicast_list	= set_multicast_list,
+	.ndo_do_ioctl		= sbni_ioctl,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static void __init sbni_devsetup(struct net_device *dev)
 {
 	ether_setup( dev );
-	dev->open		= &sbni_open;
-	dev->stop		= &sbni_close;
-	dev->hard_start_xmit	= &sbni_start_xmit;
-	dev->get_stats		= &sbni_get_stats;
-	dev->set_multicast_list	= &set_multicast_list;
-	dev->do_ioctl		= &sbni_ioctl;
+	dev->netdev_ops = &sbni_netdev_ops;
 }
 
 int __init sbni_probe(int unit)
@@ -229,6 +233,8 @@ int __init sbni_probe(int unit)
 	if (!dev)
 		return -ENOMEM;
 
+	dev->netdev_ops = &sbni_netdev_ops;
+
 	sprintf(dev->name, "sbni%d", unit);
 	netdev_boot_setup_check(dev);
 
@@ -723,13 +729,11 @@ upload_data( struct net_device  *dev,  u
 			nl->wait_frameno = 0,
 			nl->inppos = 0,
 #ifdef CONFIG_SBNI_MULTILINE
-			((struct net_local *)netdev_priv(nl->master))
-				->stats.rx_errors++,
-			((struct net_local *)netdev_priv(nl->master))
-				->stats.rx_missed_errors++;
+			nl->master->stats.rx_errors++,
+			nl->master->stats.rx_missed_errors++;
 #else
-			nl->stats.rx_errors++,
-			nl->stats.rx_missed_errors++;
+		        dev->stats.rx_errors++,
+			dev->stats.rx_missed_errors++;
 #endif
 			/* now skip all frames until is_first != 0 */
 	} else
@@ -742,13 +746,11 @@ upload_data( struct net_device  *dev,  u
 		 */
 		nl->wait_frameno = 0,
 #ifdef CONFIG_SBNI_MULTILINE
-		((struct net_local *)netdev_priv(nl->master))
-			->stats.rx_errors++,
-		((struct net_local *)netdev_priv(nl->master))
-			->stats.rx_crc_errors++;
+		nl->master->stats.rx_errors++,
+		nl->master->stats.rx_crc_errors++;
 #else
-		nl->stats.rx_errors++,
-		nl->stats.rx_crc_errors++;
+		dev->stats.rx_errors++,
+		dev->stats.rx_crc_errors++;
 #endif
 
 	return  frame_ok;
@@ -756,15 +758,16 @@ upload_data( struct net_device  *dev,  u
 
 
 static inline void
-send_complete( struct net_local  *nl )
+send_complete( struct net_device *dev )
 {
+	struct net_local  *nl = netdev_priv(dev);
+
 #ifdef CONFIG_SBNI_MULTILINE
-	((struct net_local *)netdev_priv(nl->master))->stats.tx_packets++;
-	((struct net_local *)netdev_priv(nl->master))->stats.tx_bytes
-		+= nl->tx_buf_p->len;
+	nl->master->stats.tx_packets++;
+	nl->master->stats.tx_bytes += nl->tx_buf_p->len;
 #else
-	nl->stats.tx_packets++;
-	nl->stats.tx_bytes += nl->tx_buf_p->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += nl->tx_buf_p->len;
 #endif
 	dev_kfree_skb_irq( nl->tx_buf_p );
 
@@ -792,7 +795,7 @@ interpret_ack( struct net_device  *dev,
 						   nl->maxframe,
 						   nl->tx_buf_p->len - nl->outpos);
 			else
-				send_complete( nl ),
+				send_complete( dev ),
 #ifdef CONFIG_SBNI_MULTILINE
 				netif_wake_queue( nl->master );
 #else
@@ -881,13 +884,11 @@ drop_xmit_queue( struct net_device  *dev
 		dev_kfree_skb_any( nl->tx_buf_p ),
 		nl->tx_buf_p = NULL,
 #ifdef CONFIG_SBNI_MULTILINE
-		((struct net_local *)netdev_priv(nl->master))
-			->stats.tx_errors++,
-		((struct net_local *)netdev_priv(nl->master))
-			->stats.tx_carrier_errors++;
+		nl->master->stats.tx_errors++,
+		nl->master->stats.tx_carrier_errors++;
 #else
-		nl->stats.tx_errors++,
-		nl->stats.tx_carrier_errors++;
+		dev->stats.tx_errors++,
+		dev->stats.tx_carrier_errors++;
 #endif
 
 	nl->tx_frameno	= 0;
@@ -1017,14 +1018,13 @@ indicate_pkt( struct net_device  *dev )
 #ifdef CONFIG_SBNI_MULTILINE
 	skb->protocol = eth_type_trans( skb, nl->master );
 	netif_rx( skb );
-	++((struct net_local *)netdev_priv(nl->master))->stats.rx_packets;
-	((struct net_local *)netdev_priv(nl->master))->stats.rx_bytes +=
-		nl->inppos;
+	++nl->master->stats.rx_packets;
+	nl->master->stats.rx_bytes += nl->inppos;
 #else
 	skb->protocol = eth_type_trans( skb, dev );
 	netif_rx( skb );
-	++nl->stats.rx_packets;
-	nl->stats.rx_bytes += nl->inppos;
+	++dev->stats.rx_packets;
+	dev->stats.rx_bytes += nl->inppos;
 #endif
 	nl->rx_buf_p = NULL;	/* protocol driver will clear this sk_buff */
 }
@@ -1197,7 +1197,7 @@ sbni_open( struct net_device  *dev )
 handler_attached:
 
 	spin_lock( &nl->lock );
-	memset( &nl->stats, 0, sizeof(struct net_device_stats) );
+	memset( &dev->stats, 0, sizeof(struct net_device_stats) );
 	memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
 
 	card_start( dev );
@@ -1413,7 +1413,7 @@ enslave( struct net_device  *dev,  struc
 
 	/* Summary statistics of MultiLine operation will be stored
 	   in master's counters */
-	memset( &snl->stats, 0, sizeof(struct net_device_stats) );
+	memset( &slave_dev->stats, 0, sizeof(struct net_device_stats) );
 	netif_stop_queue( slave_dev );
 	netif_wake_queue( dev );	/* Now we are able to transmit */
 
@@ -1464,14 +1464,6 @@ emancipate( struct net_device  *dev )
 
 #endif
 
-
-static struct net_device_stats *
-sbni_get_stats( struct net_device  *dev )
-{
-	return  &((struct net_local *)netdev_priv(dev))->stats;
-}
-
-
 static void
 set_multicast_list( struct net_device  *dev )
 {
@@ -1520,17 +1512,18 @@ int __init init_module( void )
 }
 
 void
-cleanup_module( void )
+cleanup_module(void)
 {
-	struct net_device  *dev;
-	int  num;
+	int i;
 
-	for( num = 0;  num < SBNI_MAX_NUM_CARDS;  ++num )
-		if( (dev = sbni_cards[ num ]) != NULL ) {
-			unregister_netdev( dev );
-			release_region( dev->base_addr, SBNI_IO_EXTENT );
-			free_netdev( dev );
+	for (i = 0;  i < SBNI_MAX_NUM_CARDS;  ++i) {
+		struct net_device *dev = sbni_cards[i];
+		if (dev != NULL) {
+			unregister_netdev(dev);
+			release_region(dev->base_addr, SBNI_IO_EXTENT);
+			free_netdev(dev);
 		}
+	}
 }
 
 #else	/* MODULE */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/sdla.c linux-libre-2.6.30-gnu1/drivers/net/wan/sdla.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/sdla.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/sdla.c	2009-06-09 23:05:27.000000000 -0400
@@ -714,19 +714,19 @@ static int sdla_transmit(struct sk_buff
 		switch (ret)
 		{
 			case SDLA_RET_OK:
-				flp->stats.tx_packets++;
+				dev->stats.tx_packets++;
 				ret = DLCI_RET_OK;
 				break;
 
 			case SDLA_RET_CIR_OVERFLOW:
 			case SDLA_RET_BUF_OVERSIZE:
 			case SDLA_RET_NO_BUFS:
-				flp->stats.tx_dropped++;
+				dev->stats.tx_dropped++;
 				ret = DLCI_RET_DROP;
 				break;
 
 			default:
-				flp->stats.tx_errors++;
+				dev->stats.tx_errors++;
 				ret = DLCI_RET_ERR;
 				break;
 		}
@@ -807,7 +807,7 @@ static void sdla_receive(struct net_devi
 		if (i == CONFIG_DLCI_MAX)
 		{
 			printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci);
-			flp->stats.rx_errors++;
+			dev->stats.rx_errors++;
 			success = 0;
 		}
 	}
@@ -819,7 +819,7 @@ static void sdla_receive(struct net_devi
 		if (skb == NULL) 
 		{
 			printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
-			flp->stats.rx_dropped++; 
+			dev->stats.rx_dropped++;
 			success = 0;
 		}
 		else
@@ -859,7 +859,7 @@ static void sdla_receive(struct net_devi
 
 	if (success)
 	{
-		flp->stats.rx_packets++;
+		dev->stats.rx_packets++;
 		dlp = netdev_priv(master);
 		(*dlp->receive)(skb, master);
 	}
@@ -1590,13 +1590,14 @@ fail:
 	return err;
 }
  
-static struct net_device_stats *sdla_stats(struct net_device *dev)
-{
-	struct frad_local *flp;
-	flp = netdev_priv(dev);
-
-	return(&flp->stats);
-}
+static const struct net_device_ops sdla_netdev_ops = {
+	.ndo_open	= sdla_open,
+	.ndo_stop	= sdla_close,
+	.ndo_do_ioctl	= sdla_ioctl,
+	.ndo_set_config	= sdla_set_config,
+	.ndo_start_xmit	= sdla_transmit,
+	.ndo_change_mtu	= sdla_change_mtu,
+};
 
 static void setup_sdla(struct net_device *dev)
 {
@@ -1604,20 +1605,13 @@ static void setup_sdla(struct net_device
 
 	netdev_boot_setup_check(dev);
 
+	dev->netdev_ops		= &sdla_netdev_ops;
 	dev->flags		= 0;
 	dev->type		= 0xFFFF;
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
 	dev->mtu		= SDLA_MAX_MTU;
 
-	dev->open		= sdla_open;
-	dev->stop		= sdla_close;
-	dev->do_ioctl		= sdla_ioctl;
-	dev->set_config		= sdla_set_config;
-	dev->get_stats		= sdla_stats;
-	dev->hard_start_xmit	= sdla_transmit;
-	dev->change_mtu		= sdla_change_mtu;
-
 	flp->activate		= sdla_activate;
 	flp->deactivate		= sdla_deactivate;
 	flp->assoc		= sdla_assoc;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/sealevel.c linux-libre-2.6.30-gnu1/drivers/net/wan/sealevel.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/sealevel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/sealevel.c	2009-06-09 23:05:27.000000000 -0400
@@ -169,6 +169,14 @@ static int sealevel_attach(struct net_de
 	return -EINVAL;
 }
 
+static const struct net_device_ops sealevel_ops = {
+	.ndo_open       = sealevel_open,
+	.ndo_stop       = sealevel_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = sealevel_ioctl,
+};
+
 static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
 {
 	struct net_device *dev = alloc_hdlcdev(sv);
@@ -177,9 +185,7 @@ static int slvl_setup(struct slvl_device
 
 	dev_to_hdlc(dev)->attach = sealevel_attach;
 	dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
-	dev->open = sealevel_open;
-	dev->stop = sealevel_close;
-	dev->do_ioctl = sealevel_ioctl;
+	dev->netdev_ops = &sealevel_ops;
 	dev->base_addr = iobase;
 	dev->irq = irq;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/wanxl.c linux-libre-2.6.30-gnu1/drivers/net/wan/wanxl.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/wanxl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/wanxl.c	2009-06-09 23:05:27.000000000 -0400
@@ -547,6 +547,15 @@ static void wanxl_pci_remove_one(struct
 
 #include "wanxlfw.inc"
 
+static const struct net_device_ops wanxl_ops = {
+	.ndo_open       = wanxl_open,
+	.ndo_stop       = wanxl_close,
+	.ndo_change_mtu = hdlc_change_mtu,
+	.ndo_start_xmit = hdlc_start_xmit,
+	.ndo_do_ioctl   = wanxl_ioctl,
+	.ndo_get_stats  = wanxl_get_stats,
+};
+
 static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 					const struct pci_device_id *ent)
 {
@@ -577,8 +586,8 @@ static int __devinit wanxl_pci_init_one(
 	   We set both dma_mask and consistent_dma_mask to 28 bits
 	   and pray pci_alloc_consistent() will use this info. It should
 	   work on most platforms */
-	if (pci_set_consistent_dma_mask(pdev, DMA_28BIT_MASK) ||
-	    pci_set_dma_mask(pdev, DMA_28BIT_MASK)) {
+	if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(28)) ||
+	    pci_set_dma_mask(pdev, DMA_BIT_MASK(28))) {
 		printk(KERN_ERR "wanXL: No usable DMA configuration\n");
 		return -EIO;
 	}
@@ -624,8 +633,8 @@ static int __devinit wanxl_pci_init_one(
 	/* FIXME when PCI/DMA subsystems are fixed.
 	   We set both dma_mask and consistent_dma_mask back to 32 bits
 	   to indicate the card can do 32-bit DMA addressing */
-	if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) ||
-	    pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+	    pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR "wanXL: No usable DMA configuration\n");
 		wanxl_pci_remove_one(pdev);
 		return -EIO;
@@ -777,12 +786,9 @@ static int __devinit wanxl_pci_init_one(
 		hdlc = dev_to_hdlc(dev);
 		spin_lock_init(&port->lock);
 		dev->tx_queue_len = 50;
-		dev->do_ioctl = wanxl_ioctl;
-		dev->open = wanxl_open;
-		dev->stop = wanxl_close;
+		dev->netdev_ops = &wanxl_ops;
 		hdlc->attach = wanxl_attach;
 		hdlc->xmit = wanxl_xmit;
-		dev->get_stats = wanxl_get_stats;
 		port->card = card;
 		port->node = i;
 		get_status(port)->clocking = CLOCK_EXT;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/x25_asy.c linux-libre-2.6.30-gnu1/drivers/net/wan/x25_asy.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/x25_asy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/x25_asy.c	2009-06-09 23:05:27.000000000 -0400
@@ -142,7 +142,7 @@ static int x25_asy_change_mtu(struct net
 			memcpy(sl->xbuff, sl->xhead, sl->xleft);
 		} else  {
 			sl->xleft = 0;
-			sl->stats.tx_dropped++;
+			dev->stats.tx_dropped++;
 		}
 	}
 	sl->xhead = sl->xbuff;
@@ -153,7 +153,7 @@ static int x25_asy_change_mtu(struct net
 			memcpy(sl->rbuff, rbuff, sl->rcount);
 		} else  {
 			sl->rcount = 0;
-			sl->stats.rx_over_errors++;
+			dev->stats.rx_over_errors++;
 			set_bit(SLF_ERROR, &sl->flags);
 		}
 	}
@@ -188,18 +188,19 @@ static inline void x25_asy_unlock(struct
 
 static void x25_asy_bump(struct x25_asy *sl)
 {
+	struct net_device *dev = sl->dev;
 	struct sk_buff *skb;
 	int count;
 	int err;
 
 	count = sl->rcount;
-	sl->stats.rx_bytes += count;
+	dev->stats.rx_bytes += count;
 
 	skb = dev_alloc_skb(count+1);
 	if (skb == NULL) {
 		printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
 			sl->dev->name);
-		sl->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	skb_push(skb, 1);	/* LAPB internal control */
@@ -211,7 +212,7 @@ static void x25_asy_bump(struct x25_asy
 		printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
 	} else {
 		netif_rx(skb);
-		sl->stats.rx_packets++;
+		dev->stats.rx_packets++;
 	}
 }
 
@@ -226,7 +227,7 @@ static void x25_asy_encaps(struct x25_as
 		len = mtu;
 		printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
 					sl->dev->name);
-		sl->stats.tx_dropped++;
+		sl->dev->stats.tx_dropped++;
 		x25_asy_unlock(sl);
 		return;
 	}
@@ -266,7 +267,7 @@ static void x25_asy_write_wakeup(struct
 	if (sl->xleft <= 0) {
 		/* Now serial buffer is almost free & we can start
 		 * transmission of another packet */
-		sl->stats.tx_packets++;
+		sl->dev->stats.tx_packets++;
 		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 		x25_asy_unlock(sl);
 		return;
@@ -383,7 +384,7 @@ static void x25_asy_data_transmit(struct
 	/* We were not busy, so we are now... :-) */
 	if (skb != NULL) {
 		x25_asy_lock(sl);
-		sl->stats.tx_bytes += skb->len;
+		dev->stats.tx_bytes += skb->len;
 		x25_asy_encaps(sl, skb->data, skb->len);
 		dev_kfree_skb(skb);
 	}
@@ -533,7 +534,7 @@ static void x25_asy_receive_buf(struct t
 	while (count--) {
 		if (fp && *fp++) {
 			if (!test_and_set_bit(SLF_ERROR, &sl->flags))
-				sl->stats.rx_errors++;
+				sl->dev->stats.rx_errors++;
 			cp++;
 			continue;
 		}
@@ -608,14 +609,6 @@ static void x25_asy_close_tty(struct tty
 	x25_asy_free(sl);
 }
 
-
-static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
-{
-	struct x25_asy *sl = netdev_priv(dev);
-	return &sl->stats;
-}
-
-
  /************************************************************************
   *			STANDARD X.25 ENCAPSULATION		  	 *
   ************************************************************************/
@@ -682,7 +675,7 @@ static void x25_asy_unesc(struct x25_asy
 			sl->rbuff[sl->rcount++] = s;
 			return;
 		}
-		sl->stats.rx_over_errors++;
+		sl->dev->stats.rx_over_errors++;
 		set_bit(SLF_ERROR, &sl->flags);
 	}
 }
@@ -719,6 +712,14 @@ static int x25_asy_open_dev(struct net_d
 	return 0;
 }
 
+static const struct net_device_ops x25_asy_netdev_ops = {
+	.ndo_open	= x25_asy_open_dev,
+	.ndo_stop	= x25_asy_close,
+	.ndo_start_xmit	= x25_asy_xmit,
+	.ndo_tx_timeout	= x25_asy_timeout,
+	.ndo_change_mtu	= x25_asy_change_mtu,
+};
+
 /* Initialise the X.25 driver.  Called by the device init code */
 static void x25_asy_setup(struct net_device *dev)
 {
@@ -734,13 +735,8 @@ static void x25_asy_setup(struct net_dev
 	 */
 
 	dev->mtu		= SL_MTU;
-	dev->hard_start_xmit	= x25_asy_xmit;
-	dev->tx_timeout		= x25_asy_timeout;
+	dev->netdev_ops		= &x25_asy_netdev_ops;
 	dev->watchdog_timeo	= HZ*20;
-	dev->open		= x25_asy_open_dev;
-	dev->stop		= x25_asy_close;
-	dev->get_stats	        = x25_asy_get_stats;
-	dev->change_mtu		= x25_asy_change_mtu;
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
 	dev->type		= ARPHRD_X25;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/x25_asy.h linux-libre-2.6.30-gnu1/drivers/net/wan/x25_asy.h
--- linux-libre-2.6.29-gnu1/drivers/net/wan/x25_asy.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/x25_asy.h	2009-06-09 23:05:27.000000000 -0400
@@ -28,10 +28,6 @@ struct x25_asy {
   unsigned char		*xbuff;		/* transmitter buffer		*/
   unsigned char         *xhead;         /* pointer to next byte to XMIT */
   int                   xleft;          /* bytes left in XMIT queue     */
-
-  /* X.25 interface statistics. */
-  struct net_device_stats stats;
-
   int                   buffsize;       /* Max buffers sizes            */
 
   unsigned long		flags;		/* Flag values/ mode etc	*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wan/z85230.c linux-libre-2.6.30-gnu1/drivers/net/wan/z85230.c
--- linux-libre-2.6.29-gnu1/drivers/net/wan/z85230.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wan/z85230.c	2009-06-09 23:05:27.000000000 -0400
@@ -1775,7 +1775,8 @@ EXPORT_SYMBOL(z8530_queue_xmit);
 /*
  *	Module support
  */
-static char banner[] __initdata = KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
+static const char banner[] __initdata =
+	KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
 
 static int __init z85230_init_driver(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/control.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/control.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/control.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/control.c	2009-06-09 23:05:27.000000000 -0400
@@ -52,7 +52,6 @@
  *
  * i2400m_dev_initalize()       Called by i2400m_dev_start()
  *   i2400m_set_init_config()
- *   i2400m_firmware_check()
  *   i2400m_cmd_get_state()
  * i2400m_dev_shutdown()        Called by i2400m_dev_stop()
  *   i2400m->bus_reset()
@@ -942,8 +941,8 @@ error_cmd_failed:
 /* Firmware interface versions we support */
 enum {
 	I2400M_HDIv_MAJOR = 9,
-	I2400M_HDIv_MAJOR_2 = 8,
 	I2400M_HDIv_MINOR = 1,
+	I2400M_HDIv_MINOR_2 = 2,
 };
 
 
@@ -959,6 +958,10 @@ enum {
  * Long function, but quite simple; first chunk launches the command
  * and double checks the reply for the right TLV. Then we process the
  * TLV (where the meat is).
+ *
+ * Once we process the TLV that gives us the firmware's interface
+ * version, we encode it and save it in i2400m->fw_version for future
+ * reference.
  */
 int i2400m_firmware_check(struct i2400m *i2400m)
 {
@@ -1009,22 +1012,20 @@ int i2400m_firmware_check(struct i2400m
 	minor = le16_to_cpu(l4mv->minor);
 	branch = le16_to_cpu(l4mv->branch);
 	result = -EINVAL;
-	if (major != I2400M_HDIv_MAJOR
-	    && major != I2400M_HDIv_MAJOR_2) {
-		dev_err(dev, "unsupported major fw interface version "
+	if (major != I2400M_HDIv_MAJOR) {
+		dev_err(dev, "unsupported major fw version "
 			"%u.%u.%u\n", major, minor, branch);
 		goto error_bad_major;
 	}
-	if (major == I2400M_HDIv_MAJOR_2)
-		dev_err(dev, "deprecated major fw interface version "
-			"%u.%u.%u\n", major, minor, branch);
 	result = 0;
-	if (minor != I2400M_HDIv_MINOR)
-		dev_warn(dev, "untested minor fw firmware version %u.%u.%u\n",
+	if (minor < I2400M_HDIv_MINOR_2 && minor > I2400M_HDIv_MINOR)
+		dev_warn(dev, "untested minor fw version %u.%u.%u\n",
 			 major, minor, branch);
-error_bad_major:
+	/* Yes, we ignore the branch -- we don't have to track it */
+	i2400m->fw_version = major << 16 | minor;
 	dev_info(dev, "firmware interface version %u.%u.%u\n",
 		 major, minor, branch);
+error_bad_major:
 error_no_tlv:
 error_cmd_failed:
 	kfree_skb(ack_skb);
@@ -1221,6 +1222,77 @@ EXPORT_SYMBOL_GPL(i2400m_set_init_config
 
 
 /**
+ * i2400m_set_idle_timeout - Set the device's idle mode timeout
+ *
+ * @i2400m: i2400m device descriptor
+ *
+ * @msecs: milliseconds for the timeout to enter idle mode. Between
+ *     100 to 300000 (5m); 0 to disable. In increments of 100.
+ *
+ * After this @msecs of the link being idle (no data being sent or
+ * received), the device will negotiate with the basestation entering
+ * idle mode for saving power. The connection is maintained, but
+ * getting out of it (done in tx.c) will require some negotiation,
+ * possible crypto re-handshake and a possible DHCP re-lease.
+ *
+ * Only available if fw_version >= 0x00090002.
+ *
+ * Returns: 0 if ok, < 0 errno code on error.
+ */
+int i2400m_set_idle_timeout(struct i2400m *i2400m, unsigned msecs)
+{
+	int result;
+	struct device *dev = i2400m_dev(i2400m);
+	struct sk_buff *ack_skb;
+	struct {
+		struct i2400m_l3l4_hdr hdr;
+		struct i2400m_tlv_config_idle_timeout cit;
+	} *cmd;
+	const struct i2400m_l3l4_hdr *ack;
+	size_t ack_len;
+	char strerr[32];
+
+	result = -ENOSYS;
+	if (i2400m_le_v1_3(i2400m))
+		goto error_alloc;
+	result = -ENOMEM;
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		goto error_alloc;
+	cmd->hdr.type = cpu_to_le16(I2400M_MT_GET_STATE);
+	cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr));
+	cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION);
+
+	cmd->cit.hdr.type =
+		cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+	cmd->cit.hdr.length = cpu_to_le16(sizeof(cmd->cit.timeout));
+	cmd->cit.timeout = cpu_to_le32(msecs);
+
+	ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd));
+	if (IS_ERR(ack_skb)) {
+		dev_err(dev, "Failed to issue 'set idle timeout' command: "
+			"%ld\n", PTR_ERR(ack_skb));
+		result = PTR_ERR(ack_skb);
+		goto error_msg_to_dev;
+	}
+	ack = wimax_msg_data_len(ack_skb, &ack_len);
+	result = i2400m_msg_check_status(ack, strerr, sizeof(strerr));
+	if (result < 0) {
+		dev_err(dev, "'set idle timeout' (0x%04x) command failed: "
+			"%d - %s\n", I2400M_MT_GET_STATE, result, strerr);
+		goto error_cmd_failed;
+	}
+	result = 0;
+	kfree_skb(ack_skb);
+error_cmd_failed:
+error_msg_to_dev:
+	kfree(cmd);
+error_alloc:
+	return result;
+}
+
+
+/**
  * i2400m_dev_initialize - Initialize the device once communications are ready
  *
  * @i2400m: device descriptor
@@ -1238,26 +1310,55 @@ int i2400m_dev_initialize(struct i2400m
 	int result;
 	struct device *dev = i2400m_dev(i2400m);
 	struct i2400m_tlv_config_idle_parameters idle_params;
+	struct i2400m_tlv_config_idle_timeout idle_timeout;
+	struct i2400m_tlv_config_d2h_data_format df;
+	struct i2400m_tlv_config_dl_host_reorder dlhr;
 	const struct i2400m_tlv_hdr *args[9];
 	unsigned argc = 0;
 
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
-	/* Useless for now...might change */
+	/* Disable idle mode? (enabled by default) */
 	if (i2400m_idle_mode_disabled) {
-		idle_params.hdr.type =
-			cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
-		idle_params.hdr.length = cpu_to_le16(
-			sizeof(idle_params) - sizeof(idle_params.hdr));
-		idle_params.idle_timeout = 0;
-		idle_params.idle_paging_interval = 0;
-		args[argc++] = &idle_params.hdr;
+		if (i2400m_le_v1_3(i2400m)) {
+			idle_params.hdr.type =
+				cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
+			idle_params.hdr.length = cpu_to_le16(
+				sizeof(idle_params) - sizeof(idle_params.hdr));
+			idle_params.idle_timeout = 0;
+			idle_params.idle_paging_interval = 0;
+			args[argc++] = &idle_params.hdr;
+		} else {
+			idle_timeout.hdr.type =
+				cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+			idle_timeout.hdr.length = cpu_to_le16(
+				sizeof(idle_timeout) - sizeof(idle_timeout.hdr));
+			idle_timeout.timeout = 0;
+			args[argc++] = &idle_timeout.hdr;
+		}
+	}
+	if (i2400m_ge_v1_4(i2400m)) {
+		/* Enable extended RX data format? */
+		df.hdr.type =
+			cpu_to_le16(I2400M_TLV_CONFIG_D2H_DATA_FORMAT);
+		df.hdr.length = cpu_to_le16(
+			sizeof(df) - sizeof(df.hdr));
+		df.format = 1;
+		args[argc++] = &df.hdr;
+
+		/* Enable RX data reordering?
+		 * (switch flipped in rx.c:i2400m_rx_setup() after fw upload) */
+		if (i2400m->rx_reorder) {
+			dlhr.hdr.type =
+				cpu_to_le16(I2400M_TLV_CONFIG_DL_HOST_REORDER);
+			dlhr.hdr.length = cpu_to_le16(
+				sizeof(dlhr) - sizeof(dlhr.hdr));
+			dlhr.reorder = 1;
+			args[argc++] = &dlhr.hdr;
+		}
 	}
 	result = i2400m_set_init_config(i2400m, args, argc);
 	if (result < 0)
 		goto error;
-	result = i2400m_firmware_check(i2400m);	/* fw versions ok? */
-	if (result < 0)
-		goto error;
 	/*
 	 * Update state: Here it just calls a get state; parsing the
 	 * result (System State TLV and RF Status TLV [done in the rx
@@ -1266,6 +1367,8 @@ int i2400m_dev_initialize(struct i2400m
 	 */
 	result = i2400m_cmd_get_state(i2400m);
 error:
+	if (result < 0)
+		dev_err(dev, "failed to initialize the device: %d\n", result);
 	d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
 	return result;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/debug-levels.h linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/debug-levels.h
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/debug-levels.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/debug-levels.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,6 +38,7 @@ enum d_module {
 	D_SUBMODULE_DECLARE(netdev),
 	D_SUBMODULE_DECLARE(rfkill),
 	D_SUBMODULE_DECLARE(rx),
+	D_SUBMODULE_DECLARE(sysfs),
 	D_SUBMODULE_DECLARE(tx),
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/driver.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/driver.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -48,6 +48,7 @@
  *       i2400m_dev_bootstrap()
  *       i2400m_tx_setup()
  *       i2400m->bus_dev_start()
+ *       i2400m_firmware_check()
  *       i2400m_check_mac_addr()
  *   wimax_dev_add()
  *
@@ -75,6 +76,11 @@ MODULE_PARM_DESC(idle_mode_disabled,
 		 "If true, the device will not enable idle mode negotiation "
 		 "with the base station (when connected) to save power.");
 
+int i2400m_rx_reorder_disabled;	/* 0 (rx reorder enabled) by default */
+module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
+MODULE_PARM_DESC(rx_reorder_disabled,
+		 "If true, RX reordering will be disabled.");
+
 /**
  * i2400m_queue_work - schedule work on a i2400m's queue
  *
@@ -395,6 +401,9 @@ retry:
 	result = i2400m_tx_setup(i2400m);
 	if (result < 0)
 		goto error_tx_setup;
+	result = i2400m_rx_setup(i2400m);
+	if (result < 0)
+		goto error_rx_setup;
 	result = i2400m->bus_dev_start(i2400m);
 	if (result < 0)
 		goto error_bus_dev_start;
@@ -404,6 +413,9 @@ retry:
 		dev_err(dev, "cannot create workqueue\n");
 		goto error_create_workqueue;
 	}
+	result = i2400m_firmware_check(i2400m);	/* fw versions ok? */
+	if (result < 0)
+		goto error_fw_check;
 	/* At this point is ok to send commands to the device */
 	result = i2400m_check_mac_addr(i2400m);
 	if (result < 0)
@@ -421,10 +433,13 @@ retry:
 
 error_dev_initialize:
 error_check_mac_addr:
+error_fw_check:
 	destroy_workqueue(i2400m->work_queue);
 error_create_workqueue:
 	i2400m->bus_dev_stop(i2400m);
 error_bus_dev_start:
+	i2400m_rx_release(i2400m);
+error_rx_setup:
 	i2400m_tx_release(i2400m);
 error_tx_setup:
 error_bootstrap:
@@ -472,6 +487,7 @@ void __i2400m_dev_stop(struct i2400m *i2
 	i2400m->ready = 0;
 	destroy_workqueue(i2400m->work_queue);
 	i2400m->bus_dev_stop(i2400m);
+	i2400m_rx_release(i2400m);
 	i2400m_tx_release(i2400m);
 	wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
 	d_fnend(3, dev, "(i2400m %p) = 0\n", i2400m);
@@ -613,7 +629,7 @@ int i2400m_setup(struct i2400m *i2400m,
 	d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
 
 	snprintf(wimax_dev->name, sizeof(wimax_dev->name),
-		 "i2400m-%s:%s", dev->bus->name, dev->bus_id);
+		 "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) {
@@ -657,6 +673,11 @@ int i2400m_setup(struct i2400m *i2400m,
 	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);
+	if (result < 0) {
+		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);
@@ -666,6 +687,9 @@ int i2400m_setup(struct i2400m *i2400m,
 	return result;
 
 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);
@@ -697,6 +721,8 @@ void i2400m_release(struct i2400m *i2400
 	netif_stop_queue(i2400m->wimax_dev.net_dev);
 
 	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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/fw.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/fw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 18:06:09.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/fw.c	2013-05-03 16:50:23.000000000 -0400
@@ -140,10 +140,10 @@
 
 
 static const __le32 i2400m_ACK_BARKER[4] = {
-	__constant_cpu_to_le32(I2400M_ACK_BARKER),
-	__constant_cpu_to_le32(I2400M_ACK_BARKER),
-	__constant_cpu_to_le32(I2400M_ACK_BARKER),
-	__constant_cpu_to_le32(I2400M_ACK_BARKER)
+	cpu_to_le32(I2400M_ACK_BARKER),
+	cpu_to_le32(I2400M_ACK_BARKER),
+	cpu_to_le32(I2400M_ACK_BARKER),
+	cpu_to_le32(I2400M_ACK_BARKER)
 };
 
 
@@ -483,7 +483,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m
 		if (offset + section_size > bcf_len) {
 			dev_err(dev, "fw %s: bad section #%zu, "
 				"end (@%zu) beyond EOF (@%zu)\n",
-				i2400m->bus_fw_name, section,
+				i2400m->fw_name, section,
 				offset + section_size,  bcf_len);
 			ret = -EINVAL;
 			goto error_section_beyond_eof;
@@ -493,7 +493,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m
 				    &ack, sizeof(ack), I2400M_BM_CMD_RAW);
 		if (ret < 0) {
 			dev_err(dev, "fw %s: section #%zu (@%zu %zu B) "
-				"failed %d\n", i2400m->bus_fw_name, section,
+				"failed %d\n", i2400m->fw_name, section,
 				offset, sizeof(*bh) + data_size, (int) ret);
 			goto error_send;
 		}
@@ -771,8 +771,8 @@ static
 int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
 {
 #define POKE(a, d) {					\
-	.address = __constant_cpu_to_le32(a),		\
-	.data = __constant_cpu_to_le32(d)		\
+	.address = cpu_to_le32(a),		\
+	.data = cpu_to_le32(d)		\
 }
 	static const struct {
 		__le32 address;
@@ -874,7 +874,7 @@ int i2400m_dnload_init(struct i2400m *i2
 		if (result < 0)
 			dev_err(dev, "fw %s: non-signed download "
 				"initialization failed: %d\n",
-				i2400m->bus_fw_name, result);
+				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 */
@@ -886,7 +886,7 @@ int i2400m_dnload_init(struct i2400m *i2
 		if (result < 0)
 			dev_err(dev, "fw %s: signed boot download "
 				"initialization failed: %d\n",
-				i2400m->bus_fw_name, result);
+				i2400m->fw_name, result);
 	}
 	return result;
 }
@@ -915,7 +915,7 @@ int i2400m_fw_check(struct i2400m *i2400
 	if (bcf_size < sizeof(*bcf)) {	/* big enough header? */
 		dev_err(dev, "firmware %s too short: "
 			"%zu B vs %zu (at least) expected\n",
-			i2400m->bus_fw_name, bcf_size, sizeof(*bcf));
+			i2400m->fw_name, bcf_size, sizeof(*bcf));
 		goto error;
 	}
 
@@ -931,7 +931,7 @@ int i2400m_fw_check(struct i2400m *i2400
 	if (bcf_size != size) {		/* annoyingly paranoid */
 		dev_err(dev, "firmware %s: bad size, got "
 			"%zu B vs %u expected\n",
-			i2400m->bus_fw_name, bcf_size, size);
+			i2400m->fw_name, bcf_size, size);
 		goto error;
 	}
 
@@ -943,7 +943,7 @@ int i2400m_fw_check(struct i2400m *i2400
 
 	if (module_type != 6) {		/* built for the right hardware? */
 		dev_err(dev, "bad fw %s: unexpected module type 0x%x; "
-			"aborting\n", i2400m->bus_fw_name, module_type);
+			"aborting\n", i2400m->fw_name, module_type);
 		goto error;
 	}
 
@@ -951,10 +951,10 @@ int i2400m_fw_check(struct i2400m *i2400
 	result = 0;
 	if (module_vendor != 0x8086)
 		dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n",
-			i2400m->bus_fw_name, module_vendor);
+			i2400m->fw_name, module_vendor);
 	if (date < 0x20080300)
 		dev_err(dev, "bad fw %s? build date too old %08x\n",
-			i2400m->bus_fw_name, date);
+			i2400m->fw_name, date);
 error:
 	return result;
 }
@@ -1016,7 +1016,7 @@ hw_reboot:
 		goto error_dev_rebooted;
 	if (ret < 0) {
 		dev_err(dev, "fw %s: download failed: %d\n",
-			i2400m->bus_fw_name, ret);
+			i2400m->fw_name, ret);
 		goto error_dnload_bcf;
 	}
 
@@ -1026,12 +1026,12 @@ hw_reboot:
 	if (ret < 0) {
 		dev_err(dev, "fw %s: "
 			"download finalization failed: %d\n",
-			i2400m->bus_fw_name, ret);
+			i2400m->fw_name, ret);
 		goto error_dnload_finalize;
 	}
 
 	d_printf(2, dev, "fw %s successfully uploaded\n",
-		 i2400m->bus_fw_name);
+		 i2400m->fw_name);
 	i2400m->boot_mode = 0;
 error_dnload_finalize:
 error_dnload_bcf:
@@ -1067,28 +1067,41 @@ error_dev_rebooted:
  */
 int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags)
 {
-	int ret = 0;
+	int ret = 0, itr = 0;
 	struct device *dev = i2400m_dev(i2400m);
 	const struct firmware *fw;
 	const struct i2400m_bcf_hdr *bcf;	/* Firmware data */
+	const char *fw_name;
 
 	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
+
 	/* Load firmware files to memory. */
-	ret = reject_firmware(&fw, i2400m->bus_fw_name, dev);
-	if (ret) {
-		dev_err(dev, "fw %s: request failed: %d\n",
-			i2400m->bus_fw_name, ret);
-		goto error_fw_req;
+	itr = 0;
+	while(1) {
+		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;
+		}
+		ret = reject_firmware(&fw, fw_name, dev);
+		if (ret == 0)
+			break;		/* got it */
+		if (ret < 0)
+			dev_err(dev, "fw %s: cannot load file: %d\n",
+				fw_name, ret);
+		itr++;
 	}
-	bcf = (void *) fw->data;
 
+	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_fw_req:
+error_no_fw:
 	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
 	return ret;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/i2400m.h linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/i2400m.h
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/i2400m.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/i2400m.h	2009-06-09 23:05:27.000000000 -0400
@@ -156,10 +156,6 @@ enum {
 };
 
 
-/* Firmware version we request when pulling the fw image file */
-#define I2400M_FW_VERSION "1.4"
-
-
 /**
  * i2400m_reset_type - methods to reset a device
  *
@@ -178,6 +174,7 @@ enum i2400m_reset_type {
 };
 
 struct i2400m_reset_ctx;
+struct i2400m_roq;
 
 /**
  * struct i2400m - descriptor for an Intel 2400m
@@ -242,10 +239,14 @@ struct i2400m_reset_ctx;
  *     The caller to this function will check if the response is a
  *     barker that indicates the device going into reset mode.
  *
- * @bus_fw_name: [fill] name of the firmware image (in most cases,
- *     they are all the same for a single release, except that they
- *     have the type of the bus embedded in the name (eg:
- *     i2400m-fw-X-VERSION.sbcf, where X is the bus name).
+ * @bus_fw_names: [fill] a NULL-terminated array with the names of the
+ *     firmware images to try loading. This is made a list so we can
+ *     support backward compatibility of firmware releases (eg: if we
+ *     can't find the default v1.4, we try v1.3). In general, the name
+ *     should be i2400m-fw-X-VERSION.sbcf, where X is the bus name.
+ *     The list is tried in order and the first one that loads is
+ *     used. The fw loader will set i2400m->fw_name to point to the
+ *     active firmware image.
  *
  * @bus_bm_mac_addr_impaired: [fill] Set to true if the device's MAC
  *     address provided in boot mode is kind of broken and needs to
@@ -257,6 +258,9 @@ struct i2400m_reset_ctx;
  *     force this to be the first field so that we can get from
  *     netdev_priv() the right pointer.
  *
+ * @rx_reorder: 1 if RX reordering is enabled; this can only be
+ *     set at probe time.
+ *
  * @state: device's state (as reported by it)
  *
  * @state_wq: waitqueue that is woken up whenever the state changes
@@ -313,6 +317,12 @@ struct i2400m_reset_ctx;
  *
  * @rx_size_max: buggest RX message received.
  *
+ * @rx_roq: RX ReOrder queues. (fw >= v1.4) When packets are received
+ *     out of order, the device will ask the driver to hold certain
+ *     packets until the ones that are received out of order can be
+ *     delivered. Then the driver can release them to the host. See
+ *     drivers/net/i2400m/rx.c for details.
+ *
  * @init_mutex: Mutex used for serializing the device bringup
  *     sequence; this way if the device reboots in the middle, we
  *     don't try to do a bringup again while we are tearing down the
@@ -364,6 +374,11 @@ struct i2400m_reset_ctx;
  *     These have to be in a separate directory, a child of
  *     (wimax_dev->debugfs_dentry) so they can be removed when the
  *     module unloads, as we don't keep each dentry.
+ *
+ * @fw_name: name of the firmware image that is currently being used.
+ *
+ * @fw_version: version of the firmware interface, Major.minor,
+ *     encoded in the high word and low word (major << 16 | minor).
  */
 struct i2400m {
 	struct wimax_dev wimax_dev;	/* FIRST! See doc */
@@ -372,6 +387,7 @@ struct i2400m {
 	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 rx_reorder:1;		/* RX reorder is enabled */
 	u8 trace_msg_from_user;		/* echo rx msgs to 'trace' pipe */
 					/* typed u8 so debugfs/u8 can tweak */
 	enum i2400m_system_state state;
@@ -388,7 +404,7 @@ struct i2400m {
 				   size_t, int flags);
 	ssize_t (*bus_bm_wait_for_ack)(struct i2400m *,
 				       struct i2400m_bootrom_header *, size_t);
-	const char *bus_fw_name;
+	const char **bus_fw_names;
 	unsigned bus_bm_mac_addr_impaired:1;
 
 	spinlock_t tx_lock;		/* protect TX state */
@@ -400,10 +416,11 @@ struct i2400m {
 	unsigned tx_pl_num, tx_pl_max, tx_pl_min,
 		tx_num, tx_size_acc, tx_size_min, tx_size_max;
 
-	/* RX stats */
+	/* RX stuff */
 	spinlock_t rx_lock;		/* protect RX state */
 	unsigned rx_pl_num, rx_pl_max, rx_pl_min,
 		rx_num, rx_size_acc, rx_size_min, rx_size_max;
+	struct i2400m_roq *rx_roq;	/* not under rx_lock! */
 
 	struct mutex msg_mutex;		/* serialize command execution */
 	struct completion msg_completion;
@@ -421,6 +438,8 @@ struct i2400m {
 	struct sk_buff *wake_tx_skb;
 
 	struct dentry *debugfs_dentry;
+	const char *fw_name;		/* name of the current firmware image */
+	unsigned long fw_version;	/* version of the firmware interface */
 };
 
 
@@ -435,6 +454,7 @@ 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);
@@ -578,12 +598,19 @@ unsigned i2400m_brh_get_signature(const
  * Driver / device setup and internal functions
  */
 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 *);
 extern int i2400m_tx_setup(struct i2400m *);
 extern void i2400m_wake_tx_work(struct work_struct *);
 extern void i2400m_tx_release(struct i2400m *);
 
+extern int i2400m_rx_setup(struct i2400m *);
+extern void i2400m_rx_release(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);
 enum i2400m_pt;
 extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
 
@@ -664,17 +691,17 @@ extern struct i2400m_msg_hdr *i2400m_tx_
 extern void i2400m_tx_msg_sent(struct i2400m *);
 
 static const __le32 i2400m_NBOOT_BARKER[4] = {
-	__constant_cpu_to_le32(I2400M_NBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_NBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_NBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_NBOOT_BARKER)
+	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] = {
-	__constant_cpu_to_le32(I2400M_SBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_SBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_SBOOT_BARKER),
-	__constant_cpu_to_le32(I2400M_SBOOT_BARKER)
+	cpu_to_le32(I2400M_SBOOT_BARKER),
+	cpu_to_le32(I2400M_SBOOT_BARKER),
+	cpu_to_le32(I2400M_SBOOT_BARKER),
+	cpu_to_le32(I2400M_SBOOT_BARKER)
 };
 
 
@@ -721,6 +748,7 @@ extern struct sk_buff *i2400m_get_device
 extern int i2400m_firmware_check(struct i2400m *);
 extern int i2400m_set_init_config(struct i2400m *,
 				  const struct i2400m_tlv_hdr **, size_t);
+extern int i2400m_set_idle_timeout(struct i2400m *, unsigned);
 
 static inline
 struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep)
@@ -733,6 +761,32 @@ extern int i2400m_op_rfkill_sw_toggle(st
 extern void i2400m_report_tlv_rf_switches_status(
 	struct i2400m *, const struct i2400m_tlv_rf_switches_status *);
 
+/*
+ * Helpers for firmware backwards compability
+ *
+ * As we aim to support at least the firmware version that was
+ * released with the previous kernel/driver release, some code will be
+ * conditionally executed depending on the firmware version. On each
+ * release, the code to support fw releases past the last two ones
+ * will be purged.
+ *
+ * By making it depend on this macros, it is easier to keep it a tab
+ * on what has to go and what not.
+ */
+static inline
+unsigned i2400m_le_v1_3(struct i2400m *i2400m)
+{
+	/* running fw is lower or v1.3 */
+	return i2400m->fw_version <= 0x00090001;
+}
+
+static inline
+unsigned i2400m_ge_v1_4(struct i2400m *i2400m)
+{
+	/* running fw is higher or v1.4 */
+	return i2400m->fw_version >= 0x00090002;
+}
+
 
 /*
  * Do a millisecond-sleep for allowing wireshark to dump all the data
@@ -750,6 +804,7 @@ void __i2400m_msleep(unsigned ms)
 /* Module parameters */
 
 extern int i2400m_idle_mode_disabled;
+extern int i2400m_rx_reorder_disabled;
 
 
 #endif /* #ifndef __I2400M_H__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/Makefile linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,7 @@ i2400m-y :=		\
 	driver.o	\
 	fw.o		\
 	op-rfkill.o	\
+	sysfs.o		\
 	netdev.o	\
 	tx.o		\
 	rx.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/netdev.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/netdev.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/netdev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/netdev.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,13 +28,12 @@
  * space and from the other side. The world is (sadly) configured to
  * take in only Ethernet devices...
  *
- * Because of this, currently there is an copy-each-rxed-packet
- * overhead on the RX path. Each IP packet has to be reallocated to
- * add an ethernet header (as there is no space in what we get from
- * the device). This is a known drawback and coming versions of the
- * device's firmware are being changed to add header space that can be
- * used to insert the ethernet header without having to reallocate and
- * copy.
+ * Because of this, when using firmwares <= v1.3, there is an
+ * copy-each-rxed-packet overhead on the RX path. Each IP packet has
+ * to be reallocated to add an ethernet header (as there is no space
+ * in what we get from the device). This is a known drawback and
+ * firmwares >= 1.4 add header space that can be used to insert the
+ * ethernet header without having to reallocate and copy.
  *
  * TX error handling is tricky; because we have to FIFO/queue the
  * buffers for transmission (as the hardware likes it aggregated), we
@@ -67,7 +66,9 @@
  * i2400m_tx_timeout      Called when the device times out
  *
  * i2400m_net_rx          Called by the RX code when a data frame is
- *                        available.
+ *                        available (firmware <= 1.3)
+ * i2400m_net_erx         Called by the RX code when a data frame is
+ *                        available (firmware >= 1.4).
  * i2400m_netdev_setup    Called to setup all the netdev stuff from
  *                        alloc_netdev.
  */
@@ -396,30 +397,18 @@ void i2400m_tx_timeout(struct net_device
  * Create a fake ethernet header
  *
  * For emulating an ethernet device, every received IP header has to
- * be prefixed with an ethernet header.
- *
- * What we receive has (potentially) many IP packets concatenated with
- * no ETH_HLEN bytes prefixed. Thus there is no space for an eth
- * header.
- *
- * We would have to reallocate or do ugly fragment tricks in order to
- * add it.
- *
- * But what we do is use the header space of the RX transaction
- * (*msg_hdr) as we don't need it anymore; then we'll point all the
- * data skbs there, as they share the same backing store.
- *
- * We only support IPv4 for v3 firmware.
+ * be prefixed with an ethernet header. Fake it with the given
+ * protocol.
  */
 static
 void i2400m_rx_fake_eth_header(struct net_device *net_dev,
-			       void *_eth_hdr)
+			       void *_eth_hdr, __be16 protocol)
 {
 	struct ethhdr *eth_hdr = _eth_hdr;
 
 	memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
 	memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest));
-	eth_hdr->h_proto = __constant_cpu_to_be16(ETH_P_IP);
+	eth_hdr->h_proto = protocol;
 }
 
 
@@ -432,6 +421,13 @@ void i2400m_rx_fake_eth_header(struct ne
  * @buf: pointer to the buffer containing the data
  * @len: buffer's length
  *
+ * This is only used now for the v1.3 firmware. It will be deprecated
+ * in >= 2.6.31.
+ *
+ * Note that due to firmware limitations, we don't have space to add
+ * an ethernet header, so we need to copy each packet. Firmware
+ * versions >= v1.4 fix this [see i2400m_net_erx()].
+ *
  * We just clone the skb and set it up so that it's skb->data pointer
  * points to "buf" and it's length.
  *
@@ -478,7 +474,8 @@ void i2400m_net_rx(struct i2400m *i2400m
 		memcpy(skb_put(skb, buf_len), buf, buf_len);
 	}
 	i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
-				  skb->data - ETH_HLEN);
+				  skb->data - ETH_HLEN,
+				  cpu_to_be16(ETH_P_IP));
 	skb_set_mac_header(skb, -ETH_HLEN);
 	skb->dev = i2400m->wimax_dev.net_dev;
 	skb->protocol = htons(ETH_P_IP);
@@ -494,6 +491,73 @@ error_skb_realloc:
 }
 
 
+/*
+ * i2400m_net_erx - pass a network packet to the stack (extended version)
+ *
+ * @i2400m: device descriptor
+ * @skb: the skb where the packet is - the skb should be set to point
+ *     at the IP packet; this function will add ethernet headers if
+ *     needed.
+ * @cs: packet type
+ *
+ * This is only used now for firmware >= v1.4. Note it is quite
+ * similar to i2400m_net_rx() (used only for v1.3 firmware).
+ *
+ * This function is normally run from a thread context. However, we
+ * still use netif_rx() instead of netif_receive_skb() as was
+ * recommended in the mailing list. Reason is in some stress tests
+ * when sending/receiving a lot of data we seem to hit a softlock in
+ * the kernel's TCP implementation [aroudn tcp_delay_timer()]. Using
+ * netif_rx() took care of the issue.
+ *
+ * This is, of course, still open to do more research on why running
+ * with netif_receive_skb() hits this softlock. FIXME.
+ */
+void i2400m_net_erx(struct i2400m *i2400m, struct sk_buff *skb,
+		    enum i2400m_cs cs)
+{
+	struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+	struct device *dev = i2400m_dev(i2400m);
+	int protocol;
+
+	d_fnstart(2, dev, "(i2400m %p skb %p [%u] cs %d)\n",
+		  i2400m, skb, skb->len, cs);
+	switch(cs) {
+	case I2400M_CS_IPV4_0:
+	case I2400M_CS_IPV4:
+		protocol = ETH_P_IP;
+		i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
+					  skb->data - ETH_HLEN,
+					  cpu_to_be16(ETH_P_IP));
+		skb_set_mac_header(skb, -ETH_HLEN);
+		skb->dev = i2400m->wimax_dev.net_dev;
+		skb->protocol = htons(ETH_P_IP);
+		net_dev->stats.rx_packets++;
+		net_dev->stats.rx_bytes += skb->len;
+		break;
+	default:
+		dev_err(dev, "ERX: BUG? CS type %u unsupported\n", cs);
+		goto error;
+
+	}
+	d_printf(3, dev, "ERX: receiving %d bytes to the network stack\n",
+		 skb->len);
+	d_dump(4, dev, skb->data, skb->len);
+	netif_rx_ni(skb);	/* see notes in function header */
+error:
+	d_fnend(2, dev, "(i2400m %p skb %p [%u] cs %d) = void\n",
+		i2400m, skb, skb->len, cs);
+}
+
+static const struct net_device_ops i2400m_netdev_ops = {
+	.ndo_open = i2400m_open,
+	.ndo_stop = i2400m_stop,
+	.ndo_start_xmit = i2400m_hard_start_xmit,
+	.ndo_tx_timeout = i2400m_tx_timeout,
+	.ndo_change_mtu = i2400m_change_mtu,
+};
+
+
 /**
  * i2400m_netdev_setup - Setup setup @net_dev's i2400m private data
  *
@@ -513,11 +577,7 @@ void i2400m_netdev_setup(struct net_devi
 		& (~IFF_BROADCAST	/* i2400m is P2P */
 		   & ~IFF_MULTICAST);
 	net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
-	net_dev->open = i2400m_open;
-	net_dev->stop = i2400m_stop;
-	net_dev->hard_start_xmit = i2400m_hard_start_xmit;
-	net_dev->change_mtu = i2400m_change_mtu;
-	net_dev->tx_timeout = i2400m_tx_timeout;
+	net_dev->netdev_ops = &i2400m_netdev_ops;
 	d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
 }
 EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/rx.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,7 +39,7 @@
  *  - Use skb_clone(), break up processing in chunks
  *  - Split transport/device specific
  *  - Make buffer size dynamic to exert less memory pressure
- *
+ *  - RX reorder support
  *
  * This handles the RX path.
  *
@@ -69,6 +69,50 @@
  * See tx.c for a deeper description on alignment requirements and
  * other fun facts of it.
  *
+ * DATA PACKETS
+ *
+ * In firmwares <= v1.3, data packets have no header for RX, but they
+ * do for TX (currently unused).
+ *
+ * In firmware >= 1.4, RX packets have an extended header (16
+ * bytes). This header conveys information for management of host
+ * reordering of packets (the device offloads storage of the packets
+ * for reordering to the host). Read below for more information.
+ *
+ * The header is used as dummy space to emulate an ethernet header and
+ * thus be able to act as an ethernet device without having to reallocate.
+ *
+ * DATA RX REORDERING
+ *
+ * Starting in firmware v1.4, the device can deliver packets for
+ * delivery with special reordering information; this allows it to
+ * more effectively do packet management when some frames were lost in
+ * the radio traffic.
+ *
+ * Thus, for RX packets that come out of order, the device gives the
+ * driver enough information to queue them properly and then at some
+ * point, the signal to deliver the whole (or part) of the queued
+ * packets to the networking stack. There are 16 such queues.
+ *
+ * This only happens when a packet comes in with the "need reorder"
+ * flag set in the RX header. When such bit is set, the following
+ * operations might be indicated:
+ *
+ *  - reset queue: send all queued packets to the OS
+ *
+ *  - queue: queue a packet
+ *
+ *  - update ws: update the queue's window start and deliver queued
+ *    packets that meet the criteria
+ *
+ *  - queue & update ws: queue a packet, update the window start and
+ *    deliver queued packets that meet the criteria
+ *
+ * (delivery criteria: the packet's [normalized] sequence number is
+ * lower than the new [normalized] window start).
+ *
+ * See the i2400m_roq_*() functions for details.
+ *
  * ROADMAP
  *
  * i2400m_rx
@@ -76,6 +120,19 @@
  *   i2400m_rx_pl_descr_check
  *   i2400m_rx_payload
  *     i2400m_net_rx
+ *     i2400m_rx_edata
+ *       i2400m_net_erx
+ *       i2400m_roq_reset
+ *         i2400m_net_erx
+ *       i2400m_roq_queue
+ *         __i2400m_roq_queue
+ *       i2400m_roq_update_ws
+ *         __i2400m_roq_update_ws
+ *           i2400m_net_erx
+ *       i2400m_roq_queue_update_ws
+ *         __i2400m_roq_queue
+ *         __i2400m_roq_update_ws
+ *           i2400m_net_erx
  *     i2400m_rx_ctl
  *       i2400m_msg_size_check
  *       i2400m_report_hook_work    [in a workqueue]
@@ -177,8 +234,7 @@ void i2400m_rx_ctl_ack(struct i2400m *i2
 	return;
 
 error_waiter_cancelled:
-	if (ack_skb)
-		kfree_skb(ack_skb);
+	kfree_skb(ack_skb);
 error_no_waiter:
 	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
 	return;
@@ -265,8 +321,6 @@ error_check:
 }
 
 
-
-
 /*
  * Receive and send up a trace
  *
@@ -317,30 +371,627 @@ error_check:
 
 
 /*
+ * Reorder queue data stored on skb->cb while the skb is queued in the
+ * reorder queues.
+ */
+struct i2400m_roq_data {
+	unsigned sn;		/* Serial number for the skb */
+	enum i2400m_cs cs;	/* packet type for the skb */
+};
+
+
+/*
+ * ReOrder Queue
+ *
+ * @ws: Window Start; sequence number where the current window start
+ *     is for this queue
+ * @queue: the skb queue itself
+ * @log: circular ring buffer used to log information about the
+ *     reorder process in this queue that can be displayed in case of
+ *     error to help diagnose it.
+ *
+ * This is the head for a list of skbs. In the skb->cb member of the
+ * skb when queued here contains a 'struct i2400m_roq_data' were we
+ * store the sequence number (sn) and the cs (packet type) coming from
+ * the RX payload header from the device.
+ */
+struct i2400m_roq
+{
+	unsigned ws;
+	struct sk_buff_head queue;
+	struct i2400m_roq_log *log;
+};
+
+
+static
+void __i2400m_roq_init(struct i2400m_roq *roq)
+{
+	roq->ws = 0;
+	skb_queue_head_init(&roq->queue);
+}
+
+
+static
+unsigned __i2400m_roq_index(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+	return ((unsigned long) roq - (unsigned long) i2400m->rx_roq)
+		/ sizeof(*roq);
+}
+
+
+/*
+ * Normalize a sequence number based on the queue's window start
+ *
+ * nsn = (sn - ws) % 2048
+ *
+ * Note that if @sn < @roq->ws, we still need a positive number; %'s
+ * sign is implementation specific, so we normalize it by adding 2048
+ * to bring it to be positive.
+ */
+static
+unsigned __i2400m_roq_nsn(struct i2400m_roq *roq, unsigned sn)
+{
+	int r;
+	r =  ((int) sn - (int) roq->ws) % 2048;
+	if (r < 0)
+		r += 2048;
+	return r;
+}
+
+
+/*
+ * Circular buffer to keep the last N reorder operations
+ *
+ * In case something fails, dumb then to try to come up with what
+ * happened.
+ */
+enum {
+	I2400M_ROQ_LOG_LENGTH = 32,
+};
+
+struct i2400m_roq_log {
+	struct i2400m_roq_log_entry {
+		enum i2400m_ro_type type;
+		unsigned ws, count, sn, nsn, new_ws;
+	} entry[I2400M_ROQ_LOG_LENGTH];
+	unsigned in, out;
+};
+
+
+/* Print a log entry */
+static
+void i2400m_roq_log_entry_print(struct i2400m *i2400m, unsigned index,
+				unsigned e_index,
+				struct i2400m_roq_log_entry *e)
+{
+	struct device *dev = i2400m_dev(i2400m);
+
+	switch(e->type) {
+	case I2400M_RO_TYPE_RESET:
+		dev_err(dev, "q#%d reset           ws %u cnt %u sn %u/%u"
+			" - new nws %u\n",
+			index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+		break;
+	case I2400M_RO_TYPE_PACKET:
+		dev_err(dev, "q#%d queue           ws %u cnt %u sn %u/%u\n",
+			index, e->ws, e->count, e->sn, e->nsn);
+		break;
+	case I2400M_RO_TYPE_WS:
+		dev_err(dev, "q#%d update_ws       ws %u cnt %u sn %u/%u"
+			" - new nws %u\n",
+			index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+		break;
+	case I2400M_RO_TYPE_PACKET_WS:
+		dev_err(dev, "q#%d queue_update_ws ws %u cnt %u sn %u/%u"
+			" - new nws %u\n",
+			index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+		break;
+	default:
+		dev_err(dev, "q#%d BUG? entry %u - unknown type %u\n",
+			index, e_index, e->type);
+		break;
+	}
+}
+
+
+static
+void i2400m_roq_log_add(struct i2400m *i2400m,
+			struct i2400m_roq *roq, enum i2400m_ro_type type,
+			unsigned ws, unsigned count, unsigned sn,
+			unsigned nsn, unsigned new_ws)
+{
+	struct i2400m_roq_log_entry *e;
+	unsigned cnt_idx;
+	int index = __i2400m_roq_index(i2400m, roq);
+
+	/* if we run out of space, we eat from the end */
+	if (roq->log->in - roq->log->out == I2400M_ROQ_LOG_LENGTH)
+		roq->log->out++;
+	cnt_idx = roq->log->in++ % I2400M_ROQ_LOG_LENGTH;
+	e = &roq->log->entry[cnt_idx];
+
+	e->type = type;
+	e->ws = ws;
+	e->count = count;
+	e->sn = sn;
+	e->nsn = nsn;
+	e->new_ws = new_ws;
+
+	if (d_test(1))
+		i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+}
+
+
+/* Dump all the entries in the FIFO and reinitialize it */
+static
+void i2400m_roq_log_dump(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+	unsigned cnt, cnt_idx;
+	struct i2400m_roq_log_entry *e;
+	int index = __i2400m_roq_index(i2400m, roq);
+
+	BUG_ON(roq->log->out > roq->log->in);
+	for (cnt = roq->log->out; cnt < roq->log->in; cnt++) {
+		cnt_idx = cnt % I2400M_ROQ_LOG_LENGTH;
+		e = &roq->log->entry[cnt_idx];
+		i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+		memset(e, 0, sizeof(*e));
+	}
+	roq->log->in = roq->log->out = 0;
+}
+
+
+/*
+ * Backbone for the queuing of an skb (by normalized sequence number)
+ *
+ * @i2400m: device descriptor
+ * @roq: reorder queue where to add
+ * @skb: the skb to add
+ * @sn: the sequence number of the skb
+ * @nsn: the normalized sequence number of the skb (pre-computed by the
+ *     caller from the @sn and @roq->ws).
+ *
+ * We try first a couple of quick cases:
+ *
+ *   - the queue is empty
+ *   - the skb would be appended to the queue
+ *
+ * These will be the most common operations.
+ *
+ * If these fail, then we have to do a sorted insertion in the queue,
+ * which is the slowest path.
+ *
+ * We don't have to acquire a reference count as we are going to own it.
+ */
+static
+void __i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+			struct sk_buff *skb, unsigned sn, unsigned nsn)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	struct sk_buff *skb_itr;
+	struct i2400m_roq_data *roq_data_itr, *roq_data;
+	unsigned nsn_itr;
+
+	d_fnstart(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %u)\n",
+		  i2400m, roq, skb, sn, nsn);
+
+	roq_data = (struct i2400m_roq_data *) &skb->cb;
+	BUILD_BUG_ON(sizeof(*roq_data) > sizeof(skb->cb));
+	roq_data->sn = sn;
+	d_printf(3, dev, "ERX: roq %p [ws %u] nsn %d sn %u\n",
+		 roq, roq->ws, nsn, roq_data->sn);
+
+	/* Queues will be empty on not-so-bad environments, so try
+	 * that first */
+	if (skb_queue_empty(&roq->queue)) {
+		d_printf(2, dev, "ERX: roq %p - first one\n", roq);
+		__skb_queue_head(&roq->queue, skb);
+		goto out;
+	}
+	/* Now try append, as most of the operations will be that */
+	skb_itr = skb_peek_tail(&roq->queue);
+	roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+	nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+	/* NSN bounds assumed correct (checked when it was queued) */
+	if (nsn >= nsn_itr) {
+		d_printf(2, dev, "ERX: roq %p - appended after %p (nsn %d sn %u)\n",
+			 roq, skb_itr, nsn_itr, roq_data_itr->sn);
+		__skb_queue_tail(&roq->queue, skb);
+		goto out;
+	}
+	/* None of the fast paths option worked. Iterate to find the
+	 * right spot where to insert the packet; we know the queue is
+	 * not empty, so we are not the first ones; we also know we
+	 * are not going to be the last ones. The list is sorted, so
+	 * we have to insert before the the first guy with an nsn_itr
+	 * greater that our nsn. */
+	skb_queue_walk(&roq->queue, skb_itr) {
+		roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+		nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+		/* NSN bounds assumed correct (checked when it was queued) */
+		if (nsn_itr > nsn) {
+			d_printf(2, dev, "ERX: roq %p - queued before %p "
+				 "(nsn %d sn %u)\n", roq, skb_itr, nsn_itr,
+				 roq_data_itr->sn);
+			__skb_queue_before(&roq->queue, skb_itr, skb);
+			goto out;
+		}
+	}
+	/* If we get here, that is VERY bad -- print info to help
+	 * diagnose and crash it */
+	dev_err(dev, "SW BUG? failed to insert packet\n");
+	dev_err(dev, "ERX: roq %p [ws %u] skb %p nsn %d sn %u\n",
+		roq, roq->ws, skb, nsn, roq_data->sn);
+	skb_queue_walk(&roq->queue, skb_itr) {
+		roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+		nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+		/* NSN bounds assumed correct (checked when it was queued) */
+		dev_err(dev, "ERX: roq %p skb_itr %p nsn %d sn %u\n",
+			roq, skb_itr, nsn_itr, roq_data_itr->sn);
+	}
+	BUG();
+out:
+	d_fnend(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %d) = void\n",
+		i2400m, roq, skb, sn, nsn);
+	return;
+}
+
+
+/*
+ * Backbone for the update window start operation
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ *
+ * Updates the window start of a queue; when doing so, it must deliver
+ * to the networking stack all the queued skb's whose normalized
+ * sequence number is lower than the new normalized window start.
+ */
+static
+unsigned __i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+				unsigned sn)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	struct sk_buff *skb_itr, *tmp_itr;
+	struct i2400m_roq_data *roq_data_itr;
+	unsigned new_nws, nsn_itr;
+
+	new_nws = __i2400m_roq_nsn(roq, sn);
+	if (unlikely(new_nws >= 1024) && d_test(1)) {
+		dev_err(dev, "SW BUG? __update_ws new_nws %u (sn %u ws %u)\n",
+			new_nws, sn, roq->ws);
+		WARN_ON(1);
+		i2400m_roq_log_dump(i2400m, roq);
+	}
+	skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+		roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+		nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+		/* NSN bounds assumed correct (checked when it was queued) */
+		if (nsn_itr < new_nws) {
+			d_printf(2, dev, "ERX: roq %p - release skb %p "
+				 "(nsn %u/%u new nws %u)\n",
+				 roq, skb_itr, nsn_itr, roq_data_itr->sn,
+				 new_nws);
+			__skb_unlink(skb_itr, &roq->queue);
+			i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+		}
+		else
+			break;	/* rest of packets all nsn_itr > nws */
+	}
+	roq->ws = sn;
+	return new_nws;
+}
+
+
+/*
+ * Reset a queue
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ *
+ * Deliver all the packets and reset the window-start to zero. Name is
+ * kind of misleading.
+ */
+static
+void i2400m_roq_reset(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	struct sk_buff *skb_itr, *tmp_itr;
+	struct i2400m_roq_data *roq_data_itr;
+
+	d_fnstart(2, dev, "(i2400m %p roq %p)\n", i2400m, roq);
+	i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_RESET,
+			     roq->ws, skb_queue_len(&roq->queue),
+			     ~0, ~0, 0);
+	skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+		roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+		d_printf(2, dev, "ERX: roq %p - release skb %p (sn %u)\n",
+			 roq, skb_itr, roq_data_itr->sn);
+		__skb_unlink(skb_itr, &roq->queue);
+		i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+	}
+	roq->ws = 0;
+	d_fnend(2, dev, "(i2400m %p roq %p) = void\n", i2400m, roq);
+	return;
+}
+
+
+/*
+ * Queue a packet
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @lbn: Last block number of the packet in @skb
+ *
+ * The hardware is asking the driver to queue a packet for later
+ * delivery to the networking stack.
+ */
+static
+void i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+		      struct sk_buff * skb, unsigned lbn)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	unsigned nsn, len;
+
+	d_fnstart(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+		  i2400m, roq, skb, lbn);
+	len = skb_queue_len(&roq->queue);
+	nsn = __i2400m_roq_nsn(roq, lbn);
+	if (unlikely(nsn >= 1024)) {
+		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);
+	} else {
+		__i2400m_roq_queue(i2400m, roq, skb, lbn, nsn);
+		i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET,
+				     roq->ws, len, lbn, nsn, ~0);
+	}
+	d_fnend(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+		i2400m, roq, skb, lbn);
+	return;
+}
+
+
+/*
+ * Update the window start in a reorder queue and deliver all skbs
+ * with a lower window start
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ */
+static
+void i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+			  unsigned sn)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	unsigned old_ws, nsn, len;
+
+	d_fnstart(2, dev, "(i2400m %p roq %p sn %u)\n", i2400m, roq, sn);
+	old_ws = roq->ws;
+	len = skb_queue_len(&roq->queue);
+	nsn = __i2400m_roq_update_ws(i2400m, roq, sn);
+	i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_WS,
+			     old_ws, len, sn, nsn, roq->ws);
+	d_fnstart(2, dev, "(i2400m %p roq %p sn %u) = void\n", i2400m, roq, sn);
+	return;
+}
+
+
+/*
+ * Queue a packet and update the window start
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @sn: Last block number of the packet in @skb
+ *
+ * Note that unlike i2400m_roq_update_ws(), which sets the new window
+ * start to @sn, in here we'll set it to @sn + 1.
+ */
+static
+void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+				struct sk_buff * skb, unsigned sn)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	unsigned nsn, old_ws, len;
+
+	d_fnstart(2, dev, "(i2400m %p roq %p skb %p sn %u)\n",
+		  i2400m, roq, skb, sn);
+	len = skb_queue_len(&roq->queue);
+	nsn = __i2400m_roq_nsn(roq, sn);
+	old_ws = roq->ws;
+	if (unlikely(nsn >= 1024)) {
+		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);
+	} else {
+		/* if the queue is empty, don't bother as we'd queue
+		 * it and inmediately unqueue it -- just deliver it */
+		if (len == 0) {
+			struct i2400m_roq_data *roq_data;
+			roq_data = (struct i2400m_roq_data *) &skb->cb;
+			i2400m_net_erx(i2400m, skb, roq_data->cs);
+		}
+		else
+			__i2400m_roq_queue(i2400m, roq, skb, sn, nsn);
+		__i2400m_roq_update_ws(i2400m, roq, sn + 1);
+		i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS,
+				   old_ws, len, sn, nsn, roq->ws);
+	}
+	d_fnend(2, dev, "(i2400m %p roq %p skb %p sn %u) = void\n",
+		i2400m, roq, skb, sn);
+	return;
+}
+
+
+/*
+ * Receive and send up an extended data packet
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ *     the skb.
+ * @payload: pointer to the packet's data inside the skb
+ * @size: size of the payload
+ *
+ * Starting in v1.4 of the i2400m's firmware, the device can send data
+ * packets to the host in an extended format that; this incudes a 16
+ * byte header (struct i2400m_pl_edata_hdr). Using this header's space
+ * we can fake ethernet headers for ethernet device emulation without
+ * having to copy packets around.
+ *
+ * This function handles said path.
+ *
+ *
+ * Receive and send up an extended data packet that requires no reordering
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ *     the skb.
+ * @payload: pointer to the packet's data (past the actual extended
+ *     data payload header).
+ * @size: size of the payload
+ *
+ * Pass over to the networking stack a data packet that might have
+ * reordering requirements.
+ *
+ * This needs to the decide if the skb in which the packet is
+ * contained can be reused or if it needs to be cloned. Then it has to
+ * be trimmed in the edges so that the beginning is the space for eth
+ * header and then pass it to i2400m_net_erx() for the stack
+ *
+ * Assumes the caller has verified the sanity of the payload (size,
+ * etc) already.
+ */
+static
+void i2400m_rx_edata(struct i2400m *i2400m, struct sk_buff *skb_rx,
+		     unsigned single_last, const void *payload, size_t size)
+{
+	struct device *dev = i2400m_dev(i2400m);
+	const struct i2400m_pl_edata_hdr *hdr = payload;
+	struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+	struct sk_buff *skb;
+	enum i2400m_cs cs;
+	u32 reorder;
+	unsigned ro_needed, ro_type, ro_cin, ro_sn;
+	struct i2400m_roq *roq;
+	struct i2400m_roq_data *roq_data;
+
+	BUILD_BUG_ON(ETH_HLEN > sizeof(*hdr));
+
+	d_fnstart(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+		  "size %zu)\n", i2400m, skb_rx, single_last, payload, size);
+	if (size < sizeof(*hdr)) {
+		dev_err(dev, "ERX: HW BUG? message with short header (%zu "
+			"vs %zu bytes expected)\n", size, sizeof(*hdr));
+		goto error;
+	}
+
+	if (single_last) {
+		skb = skb_get(skb_rx);
+		d_printf(3, dev, "ERX: skb %p reusing\n", skb);
+	} else {
+		skb = skb_clone(skb_rx, GFP_KERNEL);
+		if (skb == NULL) {
+			dev_err(dev, "ERX: no memory to clone skb\n");
+			net_dev->stats.rx_dropped++;
+			goto error_skb_clone;
+		}
+		d_printf(3, dev, "ERX: skb %p cloned from %p\n", skb, skb_rx);
+	}
+	/* now we have to pull and trim so that the skb points to the
+	 * beginning of the IP packet; the netdev part will add the
+	 * ethernet header as needed - we know there is enough space
+	 * because we checked in i2400m_rx_edata(). */
+	skb_pull(skb, payload + sizeof(*hdr) - (void *) skb->data);
+	skb_trim(skb, (void *) skb_end_pointer(skb) - payload - sizeof(*hdr));
+
+	reorder = le32_to_cpu(hdr->reorder);
+	ro_needed = reorder & I2400M_RO_NEEDED;
+	cs = hdr->cs;
+	if (ro_needed) {
+		ro_type = (reorder >> I2400M_RO_TYPE_SHIFT) & I2400M_RO_TYPE;
+		ro_cin = (reorder >> I2400M_RO_CIN_SHIFT) & I2400M_RO_CIN;
+		ro_sn = (reorder >> I2400M_RO_SN_SHIFT) & I2400M_RO_SN;
+
+		roq = &i2400m->rx_roq[ro_cin];
+		roq_data = (struct i2400m_roq_data *) &skb->cb;
+		roq_data->sn = ro_sn;
+		roq_data->cs = cs;
+		d_printf(2, dev, "ERX: reorder needed: "
+			 "type %u cin %u [ws %u] sn %u/%u len %zuB\n",
+			 ro_type, ro_cin, roq->ws, ro_sn,
+			 __i2400m_roq_nsn(roq, ro_sn), size);
+		d_dump(2, dev, payload, size);
+		switch(ro_type) {
+		case I2400M_RO_TYPE_RESET:
+			i2400m_roq_reset(i2400m, roq);
+			kfree_skb(skb);	/* no data here */
+			break;
+		case I2400M_RO_TYPE_PACKET:
+			i2400m_roq_queue(i2400m, roq, skb, ro_sn);
+			break;
+		case I2400M_RO_TYPE_WS:
+			i2400m_roq_update_ws(i2400m, roq, ro_sn);
+			kfree_skb(skb);	/* no data here */
+			break;
+		case I2400M_RO_TYPE_PACKET_WS:
+			i2400m_roq_queue_update_ws(i2400m, roq, skb, ro_sn);
+			break;
+		default:
+			dev_err(dev, "HW BUG? unknown reorder type %u\n", ro_type);
+		}
+	}
+	else
+		i2400m_net_erx(i2400m, skb, cs);
+error_skb_clone:
+error:
+	d_fnend(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+		"size %zu) = void\n", i2400m, skb_rx, single_last, payload, size);
+	return;
+}
+
+
+/*
  * Act on a received payload
  *
  * @i2400m: device instance
  * @skb_rx: skb where the transaction was received
- * @single: 1 if there is only one payload, 0 otherwise
+ * @single_last: 1 this is the only payload or the last one (so the
+ *     skb can be reused instead of cloned).
  * @pld: payload descriptor
  * @payload: payload data
  *
  * Upon reception of a payload, look at its guts in the payload
- * descriptor and decide what to do with it.
+ * descriptor and decide what to do with it. If it is a single payload
+ * skb or if the last skb is a data packet, the skb will be referenced
+ * and modified (so it doesn't have to be cloned).
  */
 static
 void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx,
-		       unsigned single, const struct i2400m_pld *pld,
+		       unsigned single_last, const struct i2400m_pld *pld,
 		       const void *payload)
 {
 	struct device *dev = i2400m_dev(i2400m);
 	size_t pl_size = i2400m_pld_size(pld);
 	enum i2400m_pt pl_type = i2400m_pld_type(pld);
 
+	d_printf(7, dev, "RX: received payload type %u, %zu bytes\n",
+		 pl_type, pl_size);
+	d_dump(8, dev, payload, pl_size);
+
 	switch (pl_type) {
 	case I2400M_PT_DATA:
 		d_printf(3, dev, "RX: data payload %zu bytes\n", pl_size);
-		i2400m_net_rx(i2400m, skb_rx, single, payload, pl_size);
+		i2400m_net_rx(i2400m, skb_rx, single_last, payload, pl_size);
 		break;
 	case I2400M_PT_CTRL:
 		i2400m_rx_ctl(i2400m, skb_rx, payload, pl_size);
@@ -348,6 +999,10 @@ void i2400m_rx_payload(struct i2400m *i2
 	case I2400M_PT_TRACE:
 		i2400m_rx_trace(i2400m, payload, pl_size);
 		break;
+	case I2400M_PT_EDATA:
+		d_printf(3, dev, "ERX: data payload %zu bytes\n", pl_size);
+		i2400m_rx_edata(i2400m, skb_rx, single_last, payload, pl_size);
+		break;
 	default:	/* Anything else shouldn't come to the host */
 		if (printk_ratelimit())
 			dev_err(dev, "RX: HW BUG? unexpected payload type %u\n",
@@ -475,7 +1130,7 @@ int i2400m_rx(struct i2400m *i2400m, str
 	const struct i2400m_msg_hdr *msg_hdr;
 	size_t pl_itr, pl_size, skb_len;
 	unsigned long flags;
-	unsigned num_pls;
+	unsigned num_pls, single_last;
 
 	skb_len = skb->len;
 	d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n",
@@ -504,7 +1159,8 @@ int i2400m_rx(struct i2400m *i2400m, str
 						  pl_itr, skb->len);
 		if (result < 0)
 			goto error_pl_descr_check;
-		i2400m_rx_payload(i2400m, skb, num_pls == 1, &msg_hdr->pld[i],
+		single_last = num_pls == 1 || i == num_pls - 1;
+		i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
 				  skb->data + pl_itr);
 		pl_itr += ALIGN(pl_size, I2400M_PL_PAD);
 		cond_resched();		/* Don't monopolize */
@@ -532,3 +1188,73 @@ error_msg_hdr_check:
 	return result;
 }
 EXPORT_SYMBOL_GPL(i2400m_rx);
+
+
+/*
+ * Initialize the RX queue and infrastructure
+ *
+ * This sets up all the RX reordering infrastructures, which will not
+ * be used if reordering is not enabled or if the firmware does not
+ * support it. The device is told to do reordering in
+ * i2400m_dev_initialize(), where it also looks at the value of the
+ * i2400m->rx_reorder switch before taking a decission.
+ *
+ * Note we allocate the roq queues in one chunk and the actual logging
+ * support for it (logging) in another one and then we setup the
+ * pointers from the first to the last.
+ */
+int i2400m_rx_setup(struct i2400m *i2400m)
+{
+	int result = 0;
+	struct device *dev = i2400m_dev(i2400m);
+
+	i2400m->rx_reorder = i2400m_rx_reorder_disabled? 0 : 1;
+	if (i2400m->rx_reorder) {
+		unsigned itr;
+		size_t size;
+		struct i2400m_roq_log *rd;
+
+		result = -ENOMEM;
+
+		size = sizeof(i2400m->rx_roq[0]) * (I2400M_RO_CIN + 1);
+		i2400m->rx_roq = kzalloc(size, GFP_KERNEL);
+		if (i2400m->rx_roq == NULL) {
+			dev_err(dev, "RX: cannot allocate %zu bytes for "
+				"reorder queues\n", size);
+			goto error_roq_alloc;
+		}
+
+		size = sizeof(*i2400m->rx_roq[0].log) * (I2400M_RO_CIN + 1);
+		rd = kzalloc(size, GFP_KERNEL);
+		if (rd == NULL) {
+			dev_err(dev, "RX: cannot allocate %zu bytes for "
+				"reorder queues log areas\n", size);
+			result = -ENOMEM;
+			goto error_roq_log_alloc;
+		}
+
+		for(itr = 0; itr < I2400M_RO_CIN + 1; itr++) {
+			__i2400m_roq_init(&i2400m->rx_roq[itr]);
+			i2400m->rx_roq[itr].log = &rd[itr];
+		}
+	}
+	return 0;
+
+error_roq_log_alloc:
+	kfree(i2400m->rx_roq);
+error_roq_alloc:
+	return result;
+}
+
+
+/* Tear down the RX queue and infrastructure */
+void i2400m_rx_release(struct i2400m *i2400m)
+{
+	if (i2400m->rx_reorder) {
+		unsigned itr;
+		for(itr = 0; itr < I2400M_RO_CIN + 1; itr++)
+			__skb_queue_purge(&i2400m->rx_roq[itr].queue);
+		kfree(i2400m->rx_roq[0].log);
+		kfree(i2400m->rx_roq);
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/sdio.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/sdio.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 18:06:11.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/sdio.c	2013-05-03 16:50:25.000000000 -0400
@@ -70,8 +70,13 @@
 static int ioe_timeout = 2;
 module_param(ioe_timeout, int, 0);
 
-/* Our firmware file name */
+/* Our firmware file name list */
+static const char *i2400ms_bus_fw_names[] = {
 #define I2400MS_FW_FILE_NAME "/*(DEBLOBBED)*/"
+	I2400MS_FW_FILE_NAME,
+	NULL
+};
+
 
 /*
  * Enable the SDIO function
@@ -255,16 +260,16 @@ int i2400ms_bus_reset(struct i2400m *i24
 		container_of(i2400m, struct i2400ms, i2400m);
 	struct device *dev = i2400m_dev(i2400m);
 	static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
 	};
 	static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
 	};
 
 	if (rt == I2400M_RT_WARM)
@@ -401,7 +406,7 @@ int i2400ms_probe(struct sdio_func *func
 	i2400m->bus_reset = i2400ms_bus_reset;
 	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_name = I2400MS_FW_FILE_NAME;
+	i2400m->bus_fw_names = i2400ms_bus_fw_names;
 	i2400m->bus_bm_mac_addr_impaired = 1;
 
 	result = i2400ms_enable_function(i2400ms->func);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/sysfs.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,80 @@
+/*
+ * Intel Wireless WiMAX Connection 2400m
+ * Sysfs interfaces to show driver and device information
+ *
+ *
+ * Copyright (C) 2007 Intel Corporation <linux-wimax@intel.com>
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include "i2400m.h"
+
+
+#define D_SUBMODULE sysfs
+#include "debug-levels.h"
+
+
+/*
+ * Set the idle timeout (msecs)
+ *
+ * FIXME: eventually this should be a common WiMAX stack method, but
+ * would like to wait to see how other devices manage it.
+ */
+static
+ssize_t i2400m_idle_timeout_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	ssize_t result;
+	struct i2400m *i2400m = net_dev_to_i2400m(to_net_dev(dev));
+	unsigned val;
+
+	result = -EINVAL;
+	if (sscanf(buf, "%u\n", &val) != 1)
+		goto error_no_unsigned;
+	if (val != 0 && (val < 100 || val > 300000 || val % 100 != 0)) {
+		dev_err(dev, "idle_timeout: %u: invalid msecs specification; "
+			"valid values are 0, 100-300000 in 100 increments\n",
+			val);
+		goto error_bad_value;
+	}
+	result = i2400m_set_idle_timeout(i2400m, val);
+	if (result >= 0)
+		result = size;
+error_no_unsigned:
+error_bad_value:
+	return result;
+}
+
+static
+DEVICE_ATTR(i2400m_idle_timeout, S_IWUSR,
+	    NULL, i2400m_idle_timeout_store);
+
+static
+struct attribute *i2400m_dev_attrs[] = {
+	&dev_attr_i2400m_idle_timeout.attr,
+	NULL,
+};
+
+struct attribute_group i2400m_dev_attr_group = {
+	.name = NULL,		/* we want them in the same directory */
+	.attrs = i2400m_dev_attrs,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/usb.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 18:06:13.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/usb.c	2013-05-03 16:50:27.000000000 -0400
@@ -73,7 +73,14 @@
 
 
 /* Our firmware file name */
-#define I2400MU_FW_FILE_NAME "/*(DEBLOBBED)*/"
+static const char *i2400mu_bus_fw_names[] = {
+#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
 int i2400mu_bus_dev_start(struct i2400m *i2400m)
@@ -211,16 +218,16 @@ int i2400mu_bus_reset(struct i2400m *i24
 		container_of(i2400m, struct i2400mu, i2400m);
 	struct device *dev = i2400m_dev(i2400m);
 	static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
+		cpu_to_le32(I2400M_WARM_RESET_BARKER),
 	};
 	static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
-		__constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
+		cpu_to_le32(I2400M_COLD_RESET_BARKER),
 	};
 
 	d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt);
@@ -394,7 +401,7 @@ int i2400mu_probe(struct usb_interface *
 	i2400m->bus_reset = i2400mu_bus_reset;
 	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_name = I2400MU_FW_FILE_NAME;
+	i2400m->bus_fw_names = i2400mu_bus_fw_names;
 	i2400m->bus_bm_mac_addr_impaired = 0;
 
 #ifdef CONFIG_PM
@@ -498,27 +505,52 @@ int i2400mu_suspend(struct usb_interface
 #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)
+		is_autosuspend = 1;
+#endif
+
 	d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event);
 	if (i2400m->updown == 0)
 		goto no_firmware;
-	d_printf(1, dev, "fw up, requesting standby\n");
+	if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) {
+		/* ugh -- the device is connected and this suspend
+		 * request is an autosuspend one (not a system standby
+		 * / hibernate).
+		 *
+		 * The only way the device can go to standby is if the
+		 * link with the base station is in IDLE mode; that
+		 * were the case, we'd be in status
+		 * I2400M_SS_CONNECTED_IDLE. But we are not.
+		 *
+		 * If we *tell* him to go power save now, it'll reset
+		 * as a precautionary measure, so if this is an
+		 * autosuspend thing, say no and it'll come back
+		 * later, when the link is IDLE
+		 */
+		result = -EBADF;
+		d_printf(1, dev, "fw up, link up, not-idle, autosuspend: "
+			 "not entering powersave\n");
+		goto error_not_now;
+	}
+	d_printf(1, dev, "fw up: entering powersave\n");
 	atomic_dec(&i2400mu->do_autopm);
 	result = i2400m_cmd_enter_powersave(i2400m);
 	atomic_inc(&i2400mu->do_autopm);
-#ifdef CONFIG_PM
-	if (result < 0 && usb_dev->auto_pm == 0) {
+	if (result < 0 && !is_autosuspend) {
 		/* System suspend, can't fail */
 		dev_err(dev, "failed to suspend, will reset on resume\n");
 		result = 0;
 	}
-#endif
 	if (result < 0)
 		goto error_enter_powersave;
 	i2400mu_notification_release(i2400mu);
-	d_printf(1, dev, "fw up, got standby\n");
+	d_printf(1, dev, "powersave requested\n");
 error_enter_powersave:
+error_not_now:
 no_firmware:
 	d_fnend(3, dev, "(iface %p pm_msg %u) = %d\n",
 		iface, pm_msg.event, result);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/usb-notif.c linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/usb-notif.c
--- linux-libre-2.6.29-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wimax/i2400m/usb-notif.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i24
 		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->bus_id);
+			 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);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/adm8211.c linux-libre-2.6.30-gnu1/drivers/net/wireless/adm8211.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/adm8211.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/adm8211.c	2009-06-09 23:05:27.000000000 -0400
@@ -1804,8 +1804,8 @@ static int __devinit adm8211_probe(struc
 		return err; /* someone else grabbed it? don't disable it */
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
-	    pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR "%s (adm8211): No suitable DMA available\n",
 		       pci_name(pdev));
 		goto err_free_reg;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/airo.c linux-libre-2.6.30-gnu1/drivers/net/wireless/airo.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/airo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/airo.c	2009-06-09 23:05:27.000000000 -0400
@@ -496,39 +496,41 @@ typedef struct {
  * so all rid access should use the read/writeXXXRid routines.
  */
 
-/* This is redundant for x86 archs, but it seems necessary for ARM */
-#pragma pack(1)
-
 /* This structure came from an email sent to me from an engineer at
    aironet for inclusion into this driver */
-typedef struct {
+typedef struct WepKeyRid WepKeyRid;
+struct WepKeyRid {
 	__le16 len;
 	__le16 kindex;
 	u8 mac[ETH_ALEN];
 	__le16 klen;
 	u8 key[16];
-} WepKeyRid;
+} __attribute__ ((packed));
 
 /* These structures are from the Aironet's PC4500 Developers Manual */
-typedef struct {
+typedef struct Ssid Ssid;
+struct Ssid {
 	__le16 len;
 	u8 ssid[32];
-} Ssid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct SsidRid SsidRid;
+struct SsidRid {
 	__le16 len;
 	Ssid ssids[3];
-} SsidRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct ModulationRid ModulationRid;
+struct ModulationRid {
         __le16 len;
         __le16 modulation;
 #define MOD_DEFAULT cpu_to_le16(0)
 #define MOD_CCK cpu_to_le16(1)
 #define MOD_MOK cpu_to_le16(2)
-} ModulationRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct ConfigRid ConfigRid;
+struct ConfigRid {
 	__le16 len; /* sizeof(ConfigRid) */
 	__le16 opmode; /* operating mode */
 #define MODE_STA_IBSS cpu_to_le16(0)
@@ -649,9 +651,10 @@ typedef struct {
 #define MAGIC_STAY_IN_CAM (1<<10)
 	u8 magicControl;
 	__le16 autoWake;
-} ConfigRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct StatusRid StatusRid;
+struct StatusRid {
 	__le16 len;
 	u8 mac[ETH_ALEN];
 	__le16 mode;
@@ -707,21 +710,23 @@ typedef struct {
 #define STAT_LEAPFAILED 91
 #define STAT_LEAPTIMEDOUT 92
 #define STAT_LEAPCOMPLETE 93
-} StatusRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct StatsRid StatsRid;
+struct StatsRid {
 	__le16 len;
 	__le16 spacer;
 	__le32 vals[100];
-} StatsRid;
-
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct APListRid APListRid;
+struct APListRid {
 	__le16 len;
 	u8 ap[4][ETH_ALEN];
-} APListRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct CapabilityRid CapabilityRid;
+struct CapabilityRid {
 	__le16 len;
 	char oui[3];
 	char zero;
@@ -748,17 +753,18 @@ typedef struct {
 	__le16 bootBlockVer;
 	__le16 requiredHard;
 	__le16 extSoftCap;
-} CapabilityRid;
-
+} __attribute__ ((packed));
 
 /* Only present on firmware >= 5.30.17 */
-typedef struct {
+typedef struct BSSListRidExtra BSSListRidExtra;
+struct BSSListRidExtra {
   __le16 unknown[4];
   u8 fixed[12]; /* WLAN management frame */
   u8 iep[624];
-} BSSListRidExtra;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct BSSListRid BSSListRid;
+struct BSSListRid {
   __le16 len;
   __le16 index; /* First is 0 and 0xffff means end of list */
 #define RADIO_FH 1 /* Frequency hopping radio type */
@@ -789,33 +795,37 @@ typedef struct {
 
   /* Only present on firmware >= 5.30.17 */
   BSSListRidExtra extra;
-} BSSListRid;
+} __attribute__ ((packed));
 
 typedef struct {
   BSSListRid bss;
   struct list_head list;
 } BSSListElement;
 
-typedef struct {
+typedef struct tdsRssiEntry tdsRssiEntry;
+struct tdsRssiEntry {
   u8 rssipct;
   u8 rssidBm;
-} tdsRssiEntry;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct tdsRssiRid tdsRssiRid;
+struct tdsRssiRid {
   u16 len;
   tdsRssiEntry x[256];
-} tdsRssiRid;
+} __attribute__ ((packed));
 
-typedef struct {
-	u16 len;
-	u16 state;
-	u16 multicastValid;
+typedef struct MICRid MICRid;
+struct MICRid {
+	__le16 len;
+	__le16 state;
+	__le16 multicastValid;
 	u8  multicast[16];
-	u16 unicastValid;
+	__le16 unicastValid;
 	u8  unicast[16];
-} MICRid;
+} __attribute__ ((packed));
 
-typedef struct {
+typedef struct MICBuffer MICBuffer;
+struct MICBuffer {
 	__be16 typelen;
 
 	union {
@@ -830,15 +840,13 @@ typedef struct {
 	} u;
 	__be32 mic;
 	__be32 seq;
-} MICBuffer;
+} __attribute__ ((packed));
 
 typedef struct {
 	u8 da[ETH_ALEN];
 	u8 sa[ETH_ALEN];
 } etherHead;
 
-#pragma pack()
-
 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
 #define TXCTL_TXEX (1<<2) /* report if tx fails */
 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
@@ -981,6 +989,14 @@ typedef struct {
 	dma_addr_t host_addr;
 } TxFid;
 
+struct rx_hdr {
+	__le16 status, len;
+	u8 rssi[2];
+	u8 rate;
+	u8 freq;
+	__le16 tmp[4];
+} __attribute__ ((packed));
+
 typedef struct {
 	unsigned int  ctl: 15;
 	unsigned int  rdy: 1;
@@ -1070,10 +1086,6 @@ static WifiCtlHdr wifictlhdr8023 = {
 	}
 };
 
-// Frequency list (map channels to frequencies)
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
-				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
 // A few details needed for WEP (Wireless Equivalent Privacy)
 #define MAX_KEY_SIZE 13			// 128 (?) bits
 #define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
@@ -1082,12 +1094,6 @@ typedef struct wep_key_t {
 	u8	key[16];	/* 40-bit and 104-bit keys */
 } wep_key_t;
 
-/* Backward compatibility */
-#ifndef IW_ENCODE_NOKEY
-#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
-#define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
-#endif /* IW_ENCODE_NOKEY */
-
 /* List of Wireless Handlers (new API) */
 static const struct iw_handler_def	airo_handler_def;
 
@@ -1155,7 +1161,7 @@ struct airo_info {
 	   use the high bit to mark whether it is in use. */
 #define MAX_FIDS 6
 #define MPI_MAX_FIDS 1
-	int                           fids[MAX_FIDS];
+	u32                           fids[MAX_FIDS];
 	ConfigRid config;
 	char keyindex; // Used with auto wep
 	char defindex; // Used with auto wep
@@ -1229,6 +1235,9 @@ struct airo_info {
 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
 	char			proc_name[IFNAMSIZ];
 
+	int			wep_capable;
+	int			max_wep_idx;
+
 	/* WPA-related stuff */
 	unsigned int bssListFirst;
 	unsigned int bssListNext;
@@ -1287,6 +1296,29 @@ static void emmh32_update(emmh32_context
 static void emmh32_final(emmh32_context *context, u8 digest[4]);
 static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
 
+static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
+			    struct crypto_cipher *tfm)
+{
+	/* If the current MIC context is valid and its key is the same as
+	 * the MIC register, there's nothing to do.
+	 */
+	if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
+		return;
+
+	/* Age current mic Context */
+	memcpy(old, cur, sizeof(*cur));
+
+	/* Initialize new context */
+	memcpy(cur->key, key, key_len);
+	cur->window  = 33; /* Window always points to the middle */
+	cur->rx      = 0;  /* Rx Sequence numbers */
+	cur->tx      = 0;  /* Tx sequence numbers */
+	cur->valid   = 1;  /* Key is now valid */
+
+	/* Give key to mic seed */
+	emmh32_setseed(&cur->seed, key, key_len, tfm);
+}
+
 /* micinit - Initialize mic seed */
 
 static void micinit(struct airo_info *ai)
@@ -1297,49 +1329,26 @@ static void micinit(struct airo_info *ai
 	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
 	up(&ai->sem);
 
-	ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
-
-	if (ai->micstats.enabled) {
-		/* Key must be valid and different */
-		if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
-		    (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
-			     sizeof(ai->mod[0].mCtx.key)) != 0))) {
-			/* Age current mic Context */
-			memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
-			/* Initialize new context */
-			memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
-			ai->mod[0].mCtx.window  = 33; //Window always points to the middle
-			ai->mod[0].mCtx.rx      = 0;  //Rx Sequence numbers
-			ai->mod[0].mCtx.tx      = 0;  //Tx sequence numbers
-			ai->mod[0].mCtx.valid   = 1;  //Key is now valid
-  
-			/* Give key to mic seed */
-			emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
-		}
-
-		/* Key must be valid and different */
-		if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid || 
-		    (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
-			    sizeof(ai->mod[0].uCtx.key)) != 0))) {
-			/* Age current mic Context */
-			memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
-			/* Initialize new context */
-			memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
-	
-			ai->mod[0].uCtx.window  = 33; //Window always points to the middle
-			ai->mod[0].uCtx.rx      = 0;  //Rx Sequence numbers
-			ai->mod[0].uCtx.tx      = 0;  //Tx sequence numbers
-			ai->mod[0].uCtx.valid   = 1;  //Key is now valid
-	
-			//Give key to mic seed
-			emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
-		}
-	} else {
-      /* So next time we have a valid key and mic is enabled, we will update
-       * the sequence number if the key is the same as before.
-       */
+	ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
+	if (!ai->micstats.enabled) {
+		/* So next time we have a valid key and mic is enabled, we will
+		 * update the sequence number if the key is the same as before.
+		 */
 		ai->mod[0].uCtx.valid = 0;
 		ai->mod[0].mCtx.valid = 0;
+		return;
+	}
+
+	if (mic_rid.multicastValid) {
+		age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
+		                mic_rid.multicast, sizeof(mic_rid.multicast),
+		                ai->tfm);
+	}
+
+	if (mic_rid.unicastValid) {
+		age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
+				mic_rid.unicast, sizeof(mic_rid.unicast),
+				ai->tfm);
 	}
 }
 
@@ -2637,17 +2646,21 @@ static const struct header_ops airo_head
 	.parse = wll_header_parse,
 };
 
+static const struct net_device_ops airo11_netdev_ops = {
+	.ndo_open 		= airo_open,
+	.ndo_stop 		= airo_close,
+	.ndo_start_xmit 	= airo_start_xmit11,
+	.ndo_get_stats 		= airo_get_stats,
+	.ndo_set_mac_address	= airo_set_mac_address,
+	.ndo_do_ioctl		= airo_ioctl,
+	.ndo_change_mtu		= airo_change_mtu,
+};
+
 static void wifi_setup(struct net_device *dev)
 {
+	dev->netdev_ops = &airo11_netdev_ops;
 	dev->header_ops = &airo_header_ops;
-	dev->hard_start_xmit = &airo_start_xmit11;
-	dev->get_stats = &airo_get_stats;
-	dev->set_mac_address = &airo_set_mac_address;
-	dev->do_ioctl = &airo_ioctl;
 	dev->wireless_handlers = &airo_handler_def;
-	dev->change_mtu = &airo_change_mtu;
-	dev->open = &airo_open;
-	dev->stop = &airo_close;
 
 	dev->type               = ARPHRD_IEEE80211;
 	dev->hard_header_len    = ETH_HLEN;
@@ -2730,27 +2743,30 @@ static void airo_networks_initialize(str
 			      &ai->network_free_list);
 }
 
-static int airo_test_wpa_capable(struct airo_info *ai)
-{
-	int status;
-	CapabilityRid cap_rid;
-
-	status = readCapabilityRid(ai, &cap_rid, 1);
-	if (status != SUCCESS) return 0;
+static const struct net_device_ops airo_netdev_ops = {
+	.ndo_open		= airo_open,
+	.ndo_stop		= airo_close,
+	.ndo_start_xmit		= airo_start_xmit,
+	.ndo_get_stats		= airo_get_stats,
+	.ndo_set_multicast_list	= airo_set_multicast_list,
+	.ndo_set_mac_address	= airo_set_mac_address,
+	.ndo_do_ioctl		= airo_ioctl,
+	.ndo_change_mtu		= airo_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
-	/* Only firmware versions 5.30.17 or better can do WPA */
-	if (le16_to_cpu(cap_rid.softVer) > 0x530
-	  || (le16_to_cpu(cap_rid.softVer) == 0x530
-	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
-		airo_print_info("", "WPA is supported.");
-		return 1;
-	}
+static const struct net_device_ops mpi_netdev_ops = {
+	.ndo_open		= airo_open,
+	.ndo_stop		= airo_close,
+	.ndo_start_xmit		= mpi_start_xmit,
+	.ndo_get_stats		= airo_get_stats,
+	.ndo_set_multicast_list	= airo_set_multicast_list,
+	.ndo_set_mac_address	= airo_set_mac_address,
+	.ndo_do_ioctl		= airo_ioctl,
+	.ndo_change_mtu		= airo_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
-	/* No WPA support */
-	airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
-		" and greater support WPA.  Detected %s)", cap_rid.prodVer);
-	return 0;
-}
 
 static struct net_device *_init_airo_card( unsigned short irq, int port,
 					   int is_pcmcia, struct pci_dev *pci,
@@ -2759,6 +2775,7 @@ static struct net_device *_init_airo_car
 	struct net_device *dev;
 	struct airo_info *ai;
 	int i, rc;
+	CapabilityRid cap_rid;
 
 	/* Create the network device object. */
 	dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2788,22 +2805,16 @@ static struct net_device *_init_airo_car
 		goto err_out_free;
 	airo_networks_initialize (ai);
 
+	skb_queue_head_init (&ai->txq);
+
 	/* The Airo-specific entries in the device structure. */
-	if (test_bit(FLAG_MPI,&ai->flags)) {
-		skb_queue_head_init (&ai->txq);
-		dev->hard_start_xmit = &mpi_start_xmit;
-	} else
-		dev->hard_start_xmit = &airo_start_xmit;
-	dev->get_stats = &airo_get_stats;
-	dev->set_multicast_list = &airo_set_multicast_list;
-	dev->set_mac_address = &airo_set_mac_address;
-	dev->do_ioctl = &airo_ioctl;
+	if (test_bit(FLAG_MPI,&ai->flags))
+		dev->netdev_ops = &mpi_netdev_ops;
+	else
+		dev->netdev_ops = &airo_netdev_ops;
 	dev->wireless_handlers = &airo_handler_def;
 	ai->wireless_data.spy_data = &ai->spy_data;
 	dev->wireless_data = &ai->wireless_data;
-	dev->change_mtu = &airo_change_mtu;
-	dev->open = &airo_open;
-	dev->stop = &airo_close;
 	dev->irq = irq;
 	dev->base_addr = port;
 
@@ -2828,7 +2839,7 @@ static struct net_device *_init_airo_car
 	}
 
 	if (probe) {
-		if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
+		if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
 			airo_print_err(dev->name, "MAC could not be enabled" );
 			rc = -EIO;
 			goto err_out_map;
@@ -2838,28 +2849,50 @@ static struct net_device *_init_airo_car
 		set_bit(FLAG_FLASHING, &ai->flags);
 	}
 
+	strcpy(dev->name, "eth%d");
+	rc = register_netdev(dev);
+	if (rc) {
+		airo_print_err(dev->name, "Couldn't register_netdev");
+		goto err_out_map;
+	}
+	ai->wifidev = init_wifidev(ai, dev);
+	if (!ai->wifidev)
+		goto err_out_reg;
+
+	rc = readCapabilityRid(ai, &cap_rid, 1);
+	if (rc != SUCCESS) {
+		rc = -EIO;
+		goto err_out_wifi;
+	}
+	/* WEP capability discovery */
+	ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
+	ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
+
+	airo_print_info(dev->name, "Firmware version %x.%x.%02x",
+	                ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
+	                (le16_to_cpu(cap_rid.softVer) & 0xFF),
+	                le16_to_cpu(cap_rid.softSubVer));
+
 	/* Test for WPA support */
-	if (airo_test_wpa_capable(ai)) {
+	/* Only firmware versions 5.30.17 or better can do WPA */
+	if (le16_to_cpu(cap_rid.softVer) > 0x530
+	 || (le16_to_cpu(cap_rid.softVer) == 0x530
+	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
+		airo_print_info(ai->dev->name, "WPA supported.");
+
 		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
 		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
 		ai->bssListNext = RID_WPA_BSSLISTNEXT;
 		ai->bssListRidLen = sizeof(BSSListRid);
 	} else {
+		airo_print_info(ai->dev->name, "WPA unsupported with firmware "
+			"versions older than 5.30.17.");
+
 		ai->bssListFirst = RID_BSSLISTFIRST;
 		ai->bssListNext = RID_BSSLISTNEXT;
 		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
 	}
 
-	strcpy(dev->name, "eth%d");
-	rc = register_netdev(dev);
-	if (rc) {
-		airo_print_err(dev->name, "Couldn't register_netdev");
-		goto err_out_map;
-	}
-	ai->wifidev = init_wifidev(ai, dev);
-	if (!ai->wifidev)
-		goto err_out_reg;
-
 	set_bit(FLAG_REGISTERED,&ai->flags);
 	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 
@@ -3127,314 +3160,354 @@ static int header_len(__le16 ctl)
 	return 24;
 }
 
-static irqreturn_t airo_interrupt(int irq, void *dev_id)
+static void airo_handle_cisco_mic(struct airo_info *ai)
 {
-	struct net_device *dev = dev_id;
+	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
+		set_bit(JOB_MIC, &ai->jobs);
+		wake_up_interruptible(&ai->thr_wait);
+	}
+}
+
+/* Airo Status codes */
+#define STAT_NOBEACON	0x8000 /* Loss of sync - missed beacons */
+#define STAT_MAXRETRIES	0x8001 /* Loss of sync - max retries */
+#define STAT_MAXARL	0x8002 /* Loss of sync - average retry level exceeded*/
+#define STAT_FORCELOSS	0x8003 /* Loss of sync - host request */
+#define STAT_TSFSYNC	0x8004 /* Loss of sync - TSF synchronization */
+#define STAT_DEAUTH	0x8100 /* low byte is 802.11 reason code */
+#define STAT_DISASSOC	0x8200 /* low byte is 802.11 reason code */
+#define STAT_ASSOC_FAIL	0x8400 /* low byte is 802.11 reason code */
+#define STAT_AUTH_FAIL	0x0300 /* low byte is 802.11 reason code */
+#define STAT_ASSOC	0x0400 /* Associated */
+#define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
+
+static void airo_print_status(const char *devname, u16 status)
+{
+	u8 reason = status & 0xFF;
+
+	switch (status) {
+	case STAT_NOBEACON:
+		airo_print_dbg(devname, "link lost (missed beacons)");
+		break;
+	case STAT_MAXRETRIES:
+	case STAT_MAXARL:
+		airo_print_dbg(devname, "link lost (max retries)");
+		break;
+	case STAT_FORCELOSS:
+		airo_print_dbg(devname, "link lost (local choice)");
+		break;
+	case STAT_TSFSYNC:
+		airo_print_dbg(devname, "link lost (TSF sync lost)");
+		break;
+	case STAT_DEAUTH:
+		airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
+		break;
+	case STAT_DISASSOC:
+		airo_print_dbg(devname, "disassociated (reason: %d)", reason);
+		break;
+	case STAT_ASSOC_FAIL:
+		airo_print_dbg(devname, "association failed (reason: %d)",
+			       reason);
+		break;
+	case STAT_AUTH_FAIL:
+		airo_print_dbg(devname, "authentication failed (reason: %d)",
+			       reason);
+		break;
+	default:
+		break;
+	}
+}
+
+static void airo_handle_link(struct airo_info *ai)
+{
+	union iwreq_data wrqu;
+	int scan_forceloss = 0;
 	u16 status;
-	u16 fid;
-	struct airo_info *apriv = dev->ml_priv;
-	u16 savedInterrupts = 0;
-	int handled = 0;
 
-	if (!netif_device_present(dev))
-		return IRQ_NONE;
+	/* Get new status and acknowledge the link change */
+	status = le16_to_cpu(IN4500(ai, LINKSTAT));
+	OUT4500(ai, EVACK, EV_LINK);
 
-	for (;;) {
-		status = IN4500( apriv, EVSTAT );
-		if ( !(status & STATUS_INTS) || status == 0xffff ) break;
+	if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
+		scan_forceloss = 1;
 
-		handled = 1;
+	airo_print_status(ai->dev->name, status);
 
-		if ( status & EV_AWAKE ) {
-			OUT4500( apriv, EVACK, EV_AWAKE );
-			OUT4500( apriv, EVACK, EV_AWAKE );
-		}
+	if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
+		if (auto_wep)
+			ai->expires = 0;
+		if (ai->list_bss_task)
+			wake_up_process(ai->list_bss_task);
+		set_bit(FLAG_UPDATE_UNI, &ai->flags);
+		set_bit(FLAG_UPDATE_MULTI, &ai->flags);
 
-		if (!savedInterrupts) {
-			savedInterrupts = IN4500( apriv, EVINTEN );
-			OUT4500( apriv, EVINTEN, 0 );
+		if (down_trylock(&ai->sem) != 0) {
+			set_bit(JOB_EVENT, &ai->jobs);
+			wake_up_interruptible(&ai->thr_wait);
+		} else
+			airo_send_event(ai->dev);
+	} else if (!scan_forceloss) {
+		if (auto_wep && !ai->expires) {
+			ai->expires = RUN_AT(3*HZ);
+			wake_up_interruptible(&ai->thr_wait);
 		}
 
-		if ( status & EV_MIC ) {
-			OUT4500( apriv, EVACK, EV_MIC );
-			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
-				set_bit(JOB_MIC, &apriv->jobs);
-				wake_up_interruptible(&apriv->thr_wait);
-			}
-		}
-		if ( status & EV_LINK ) {
-			union iwreq_data	wrqu;
-			int scan_forceloss = 0;
-			/* The link status has changed, if you want to put a
-			   monitor hook in, do it here.  (Remember that
-			   interrupts are still disabled!)
-			*/
-			u16 newStatus = IN4500(apriv, LINKSTAT);
-			OUT4500( apriv, EVACK, EV_LINK);
-			/* Here is what newStatus means: */
-#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
-#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
-#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
-#define FORCELOSS 0x8003 /* Loss of sync - host request */
-#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
-#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
-#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
-#define ASSFAIL 0x8400 /* Association failure (low byte is reason
-			  code) */
-#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
-			   code) */
-#define ASSOCIATED 0x0400 /* Associated */
-#define REASSOCIATED 0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
-#define RC_RESERVED 0 /* Reserved return code */
-#define RC_NOREASON 1 /* Unspecified reason */
-#define RC_AUTHINV 2 /* Previous authentication invalid */
-#define RC_DEAUTH 3 /* Deauthenticated because sending station is
-		       leaving */
-#define RC_NOACT 4 /* Disassociated due to inactivity */
-#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
-			all currently associated stations */
-#define RC_BADCLASS2 6 /* Class 2 frame received from
-			  non-Authenticated station */
-#define RC_BADCLASS3 7 /* Class 3 frame received from
-			  non-Associated station */
-#define RC_STATLEAVE 8 /* Disassociated because sending station is
-			  leaving BSS */
-#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
-		       Authenticated with the responding station */
-			if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
-				scan_forceloss = 1;
-			if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
-				if (auto_wep)
-					apriv->expires = 0;
-				if (apriv->list_bss_task)
-					wake_up_process(apriv->list_bss_task);
-				set_bit(FLAG_UPDATE_UNI, &apriv->flags);
-				set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
+		/* Send event to user space */
+		memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+		wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
+	}
+}
 
-				if (down_trylock(&apriv->sem) != 0) {
-					set_bit(JOB_EVENT, &apriv->jobs);
-					wake_up_interruptible(&apriv->thr_wait);
-				} else
-					airo_send_event(dev);
-			} else if (!scan_forceloss) {
-				if (auto_wep && !apriv->expires) {
-					apriv->expires = RUN_AT(3*HZ);
-					wake_up_interruptible(&apriv->thr_wait);
-				}
+static void airo_handle_rx(struct airo_info *ai)
+{
+	struct sk_buff *skb = NULL;
+	__le16 fc, v, *buffer, tmpbuf[4];
+	u16 len, hdrlen = 0, gap, fid;
+	struct rx_hdr hdr;
+	int success = 0;
 
-				/* Send event to user space */
-				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
-				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-				wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
-			}
-		}
+	if (test_bit(FLAG_MPI, &ai->flags)) {
+		if (test_bit(FLAG_802_11, &ai->flags))
+			mpi_receive_802_11(ai);
+		else
+			mpi_receive_802_3(ai);
+		OUT4500(ai, EVACK, EV_RX);
+		return;
+	}
 
-		/* Check to see if there is something to receive */
-		if ( status & EV_RX  ) {
-			struct sk_buff *skb = NULL;
-			__le16 fc, v;
-			u16 len, hdrlen = 0;
-#pragma pack(1)
-			struct {
-				__le16 status, len;
-				u8 rssi[2];
-				u8 rate;
-				u8 freq;
-				__le16 tmp[4];
-			} hdr;
-#pragma pack()
-			u16 gap;
-			__le16 tmpbuf[4];
-			__le16 *buffer;
+	fid = IN4500(ai, RXFID);
 
-			if (test_bit(FLAG_MPI,&apriv->flags)) {
-				if (test_bit(FLAG_802_11, &apriv->flags))
-					mpi_receive_802_11(apriv);
-				else
-					mpi_receive_802_3(apriv);
-				OUT4500(apriv, EVACK, EV_RX);
-				goto exitrx;
-			}
+	/* Get the packet length */
+	if (test_bit(FLAG_802_11, &ai->flags)) {
+		bap_setup (ai, fid, 4, BAP0);
+		bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
+		/* Bad CRC. Ignore packet */
+		if (le16_to_cpu(hdr.status) & 2)
+			hdr.len = 0;
+		if (ai->wifidev == NULL)
+			hdr.len = 0;
+	} else {
+		bap_setup(ai, fid, 0x36, BAP0);
+		bap_read(ai, &hdr.len, 2, BAP0);
+	}
+	len = le16_to_cpu(hdr.len);
 
-			fid = IN4500( apriv, RXFID );
+	if (len > AIRO_DEF_MTU) {
+		airo_print_err(ai->dev->name, "Bad size %d", len);
+		goto done;
+	}
+	if (len == 0)
+		goto done;
 
-			/* Get the packet length */
-			if (test_bit(FLAG_802_11, &apriv->flags)) {
-				bap_setup (apriv, fid, 4, BAP0);
-				bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
-				/* Bad CRC. Ignore packet */
-				if (le16_to_cpu(hdr.status) & 2)
-					hdr.len = 0;
-				if (apriv->wifidev == NULL)
-					hdr.len = 0;
-			} else {
-				bap_setup (apriv, fid, 0x36, BAP0);
-				bap_read (apriv, &hdr.len, 2, BAP0);
-			}
-			len = le16_to_cpu(hdr.len);
+	if (test_bit(FLAG_802_11, &ai->flags)) {
+		bap_read(ai, &fc, sizeof (fc), BAP0);
+		hdrlen = header_len(fc);
+	} else
+		hdrlen = ETH_ALEN * 2;
 
-			if (len > AIRO_DEF_MTU) {
-				airo_print_err(apriv->dev->name, "Bad size %d", len);
-				goto badrx;
-			}
-			if (len == 0)
-				goto badrx;
+	skb = dev_alloc_skb(len + hdrlen + 2 + 2);
+	if (!skb) {
+		ai->dev->stats.rx_dropped++;
+		goto done;
+	}
 
-			if (test_bit(FLAG_802_11, &apriv->flags)) {
-				bap_read (apriv, &fc, sizeof(fc), BAP0);
-				hdrlen = header_len(fc);
-			} else
-				hdrlen = ETH_ALEN * 2;
+	skb_reserve(skb, 2); /* This way the IP header is aligned */
+	buffer = (__le16 *) skb_put(skb, len + hdrlen);
+	if (test_bit(FLAG_802_11, &ai->flags)) {
+		buffer[0] = fc;
+		bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
+		if (hdrlen == 24)
+			bap_read(ai, tmpbuf, 6, BAP0);
 
-			skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
-			if ( !skb ) {
-				dev->stats.rx_dropped++;
-				goto badrx;
+		bap_read(ai, &v, sizeof(v), BAP0);
+		gap = le16_to_cpu(v);
+		if (gap) {
+			if (gap <= 8) {
+				bap_read(ai, tmpbuf, gap, BAP0);
+			} else {
+				airo_print_err(ai->dev->name, "gaplen too "
+					"big. Problems will follow...");
 			}
-			skb_reserve(skb, 2); /* This way the IP header is aligned */
-			buffer = (__le16*)skb_put (skb, len + hdrlen);
-			if (test_bit(FLAG_802_11, &apriv->flags)) {
-				buffer[0] = fc;
-				bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
-				if (hdrlen == 24)
-					bap_read (apriv, tmpbuf, 6, BAP0);
+		}
+		bap_read(ai, buffer + hdrlen/2, len, BAP0);
+	} else {
+		MICBuffer micbuf;
 
-				bap_read (apriv, &v, sizeof(v), BAP0);
-				gap = le16_to_cpu(v);
-				if (gap) {
-					if (gap <= 8) {
-						bap_read (apriv, tmpbuf, gap, BAP0);
-					} else {
-						airo_print_err(apriv->dev->name, "gaplen too "
-							"big. Problems will follow...");
-					}
+		bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
+		if (ai->micstats.enabled) {
+			bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
+			if (ntohs(micbuf.typelen) > 0x05DC)
+				bap_setup(ai, fid, 0x44, BAP0);
+			else {
+				if (len <= sizeof (micbuf)) {
+					dev_kfree_skb_irq(skb);
+					goto done;
 				}
-				bap_read (apriv, buffer + hdrlen/2, len, BAP0);
-			} else {
-				MICBuffer micbuf;
-				bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
-				if (apriv->micstats.enabled) {
-					bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
-					if (ntohs(micbuf.typelen) > 0x05DC)
-						bap_setup (apriv, fid, 0x44, BAP0);
-					else {
-						if (len <= sizeof(micbuf))
-							goto badmic;
 
-						len -= sizeof(micbuf);
-						skb_trim (skb, len + hdrlen);
-					}
-				}
-				bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
-				if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
-badmic:
-					dev_kfree_skb_irq (skb);
-badrx:
-					OUT4500( apriv, EVACK, EV_RX);
-					goto exitrx;
-				}
+				len -= sizeof(micbuf);
+				skb_trim(skb, len + hdrlen);
 			}
+		}
+
+		bap_read(ai, buffer + ETH_ALEN, len, BAP0);
+		if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
+			dev_kfree_skb_irq (skb);
+		else
+			success = 1;
+	}
+
 #ifdef WIRELESS_SPY
-			if (apriv->spy_data.spy_number > 0) {
-				char *sa;
-				struct iw_quality wstats;
-				/* Prepare spy data : addr + qual */
-				if (!test_bit(FLAG_802_11, &apriv->flags)) {
-					sa = (char*)buffer + 6;
-					bap_setup (apriv, fid, 8, BAP0);
-					bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
-				} else
-					sa = (char*)buffer + 10;
-				wstats.qual = hdr.rssi[0];
-				if (apriv->rssi)
-					wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
-				else
-					wstats.level = (hdr.rssi[1] + 321) / 2;
-				wstats.noise = apriv->wstats.qual.noise;
-				wstats.updated = IW_QUAL_LEVEL_UPDATED
-					| IW_QUAL_QUAL_UPDATED
-					| IW_QUAL_DBM;
-				/* Update spy records */
-				wireless_spy_update(dev, sa, &wstats);
-			}
+	if (success && (ai->spy_data.spy_number > 0)) {
+		char *sa;
+		struct iw_quality wstats;
+
+		/* Prepare spy data : addr + qual */
+		if (!test_bit(FLAG_802_11, &ai->flags)) {
+			sa = (char *) buffer + 6;
+			bap_setup(ai, fid, 8, BAP0);
+			bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
+		} else
+			sa = (char *) buffer + 10;
+		wstats.qual = hdr.rssi[0];
+		if (ai->rssi)
+			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
+		else
+			wstats.level = (hdr.rssi[1] + 321) / 2;
+		wstats.noise = ai->wstats.qual.noise;
+		wstats.updated =  IW_QUAL_LEVEL_UPDATED
+				| IW_QUAL_QUAL_UPDATED
+				| IW_QUAL_DBM;
+		/* Update spy records */
+		wireless_spy_update(ai->dev, sa, &wstats);
+	}
 #endif /* WIRELESS_SPY */
-			OUT4500( apriv, EVACK, EV_RX);
 
-			if (test_bit(FLAG_802_11, &apriv->flags)) {
-				skb_reset_mac_header(skb);
-				skb->pkt_type = PACKET_OTHERHOST;
-				skb->dev = apriv->wifidev;
-				skb->protocol = htons(ETH_P_802_2);
-			} else
-				skb->protocol = eth_type_trans(skb,dev);
-			skb->ip_summed = CHECKSUM_NONE;
+done:
+	OUT4500(ai, EVACK, EV_RX);
 
-			netif_rx( skb );
+	if (success) {
+		if (test_bit(FLAG_802_11, &ai->flags)) {
+			skb_reset_mac_header(skb);
+			skb->pkt_type = PACKET_OTHERHOST;
+			skb->dev = ai->wifidev;
+			skb->protocol = htons(ETH_P_802_2);
+		} else
+			skb->protocol = eth_type_trans(skb, ai->dev);
+		skb->ip_summed = CHECKSUM_NONE;
+
+		netif_rx(skb);
+	}
+}
+
+static void airo_handle_tx(struct airo_info *ai, u16 status)
+{
+	int i, len = 0, index = -1;
+	u16 fid;
+
+	if (test_bit(FLAG_MPI, &ai->flags)) {
+		unsigned long flags;
+
+		if (status & EV_TXEXC)
+			get_tx_error(ai, -1);
+
+		spin_lock_irqsave(&ai->aux_lock, flags);
+		if (!skb_queue_empty(&ai->txq)) {
+			spin_unlock_irqrestore(&ai->aux_lock,flags);
+			mpi_send_packet(ai->dev);
+		} else {
+			clear_bit(FLAG_PENDING_XMIT, &ai->flags);
+			spin_unlock_irqrestore(&ai->aux_lock,flags);
+			netif_wake_queue(ai->dev);
 		}
-exitrx:
+		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+		return;
+	}
 
-		/* Check to see if a packet has been transmitted */
-		if (  status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
-			int i;
-			int len = 0;
-			int index = -1;
+	fid = IN4500(ai, TXCOMPLFID);
 
-			if (test_bit(FLAG_MPI,&apriv->flags)) {
-				unsigned long flags;
+	for(i = 0; i < MAX_FIDS; i++) {
+		if ((ai->fids[i] & 0xffff) == fid) {
+			len = ai->fids[i] >> 16;
+			index = i;
+		}
+	}
 
-				if (status & EV_TXEXC)
-					get_tx_error(apriv, -1);
-				spin_lock_irqsave(&apriv->aux_lock, flags);
-				if (!skb_queue_empty(&apriv->txq)) {
-					spin_unlock_irqrestore(&apriv->aux_lock,flags);
-					mpi_send_packet (dev);
-				} else {
-					clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
-					spin_unlock_irqrestore(&apriv->aux_lock,flags);
-					netif_wake_queue (dev);
-				}
-				OUT4500( apriv, EVACK,
-					status & (EV_TX|EV_TXCPY|EV_TXEXC));
-				goto exittx;
-			}
+	if (index != -1) {
+		if (status & EV_TXEXC)
+			get_tx_error(ai, index);
 
-			fid = IN4500(apriv, TXCOMPLFID);
+		OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
 
-			for( i = 0; i < MAX_FIDS; i++ ) {
-				if ( ( apriv->fids[i] & 0xffff ) == fid ) {
-					len = apriv->fids[i] >> 16;
-					index = i;
-				}
-			}
-			if (index != -1) {
-				if (status & EV_TXEXC)
-					get_tx_error(apriv, index);
-				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
-				/* Set up to be used again */
-				apriv->fids[index] &= 0xffff;
-				if (index < MAX_FIDS / 2) {
-					if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
-						netif_wake_queue(dev);
-				} else {
-					if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
-						netif_wake_queue(apriv->wifidev);
-				}
-			} else {
-				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
-				airo_print_err(apriv->dev->name, "Unallocated FID was "
-					"used to xmit" );
-			}
+		/* Set up to be used again */
+		ai->fids[index] &= 0xffff;
+		if (index < MAX_FIDS / 2) {
+			if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
+				netif_wake_queue(ai->dev);
+		} else {
+			if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
+				netif_wake_queue(ai->wifidev);
 		}
-exittx:
-		if ( status & ~STATUS_INTS & ~IGNORE_INTS )
-			airo_print_warn(apriv->dev->name, "Got weird status %x",
+	} else {
+		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+		airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
+	}
+}
+
+static irqreturn_t airo_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	u16 status, savedInterrupts = 0;
+	struct airo_info *ai = dev->ml_priv;
+	int handled = 0;
+
+	if (!netif_device_present(dev))
+		return IRQ_NONE;
+
+	for (;;) {
+		status = IN4500(ai, EVSTAT);
+		if (!(status & STATUS_INTS) || (status == 0xffff))
+			break;
+
+		handled = 1;
+
+		if (status & EV_AWAKE) {
+			OUT4500(ai, EVACK, EV_AWAKE);
+			OUT4500(ai, EVACK, EV_AWAKE);
+		}
+
+		if (!savedInterrupts) {
+			savedInterrupts = IN4500(ai, EVINTEN);
+			OUT4500(ai, EVINTEN, 0);
+		}
+
+		if (status & EV_MIC) {
+			OUT4500(ai, EVACK, EV_MIC);
+			airo_handle_cisco_mic(ai);
+		}
+
+		if (status & EV_LINK) {
+			/* Link status changed */
+			airo_handle_link(ai);
+		}
+
+		/* Check to see if there is something to receive */
+		if (status & EV_RX)
+			airo_handle_rx(ai);
+
+		/* Check to see if a packet has been transmitted */
+		if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
+			airo_handle_tx(ai, status);
+
+		if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
+			airo_print_warn(ai->dev->name, "Got weird status %x",
 				status & ~STATUS_INTS & ~IGNORE_INTS );
+		}
 	}
 
 	if (savedInterrupts)
-		OUT4500( apriv, EVINTEN, savedInterrupts );
+		OUT4500(ai, EVINTEN, savedInterrupts);
 
-	/* done.. */
 	return IRQ_RETVAL(handled);
 }
 
@@ -3613,18 +3686,10 @@ static void mpi_receive_802_11(struct ai
 	struct sk_buff *skb = NULL;
 	u16 len, hdrlen = 0;
 	__le16 fc;
-#pragma pack(1)
-	struct {
-		__le16 status, len;
-		u8 rssi[2];
-		u8 rate;
-		u8 freq;
-		__le16 tmp[4];
-	} hdr;
-#pragma pack()
+	struct rx_hdr hdr;
 	u16 gap;
 	u16 *buffer;
-	char *ptr = ai->rxfids[0].virtual_host_addr+4;
+	char *ptr = ai->rxfids[0].virtual_host_addr + 4;
 
 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 	memcpy ((char *)&hdr, ptr, sizeof(hdr));
@@ -3691,6 +3756,7 @@ static void mpi_receive_802_11(struct ai
 	skb->protocol = htons(ETH_P_802_2);
 	skb->ip_summed = CHECKSUM_NONE;
 	netif_rx( skb );
+
 badrx:
 	if (rxd.valid == 0) {
 		rxd.valid = 1;
@@ -3705,7 +3771,6 @@ static u16 setup_card(struct airo_info *
 	Cmd cmd;
 	Resp rsp;
 	int status;
-	int i;
 	SsidRid mySsid;
 	__le16 lastindex;
 	WepKeyRid wkr;
@@ -3747,6 +3812,7 @@ static u16 setup_card(struct airo_info *
 	if (lock)
 		up(&ai->sem);
 	if (ai->config.len == 0) {
+		int i;
 		tdsRssiRid rssi_rid;
 		CapabilityRid cap_rid;
 
@@ -3794,14 +3860,12 @@ static u16 setup_card(struct airo_info *
 		/* Check to see if there are any insmod configured
 		   rates to add */
 		if ( rates[0] ) {
-			int i = 0;
 			memset(ai->config.rates,0,sizeof(ai->config.rates));
 			for( i = 0; i < 8 && rates[i]; i++ ) {
 				ai->config.rates[i] = rates[i];
 			}
 		}
 		if ( basic_rate > 0 ) {
-			int i;
 			for( i = 0; i < 8; i++ ) {
 				if ( ai->config.rates[i] == basic_rate ||
 				     !ai->config.rates ) {
@@ -4428,7 +4492,6 @@ static int setup_proc_entry( struct net_
 		goto fail;
 	apriv->proc_entry->uid = proc_uid;
 	apriv->proc_entry->gid = proc_gid;
-	apriv->proc_entry->owner = THIS_MODULE;
 
 	/* Setup the StatsDelta */
 	entry = proc_create_data("StatsDelta",
@@ -4686,7 +4749,7 @@ static int proc_stats_rid_open( struct i
 	StatsRid stats;
 	int i, j;
 	__le32 *vals = stats.vals;
-	int len = le16_to_cpu(stats.len);
+	int len;
 
 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
@@ -4697,6 +4760,7 @@ static int proc_stats_rid_open( struct i
 	}
 
 	readStatsRid(apriv, &stats, rid, 1);
+	len = le16_to_cpu(stats.len);
 
         j = 0;
 	for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
@@ -5131,55 +5195,98 @@ static int do_writerid( struct airo_info
 	return rc;
 }
 
-/* Returns the length of the key at the index.  If index == 0xffff
- * the index of the transmit key is returned.  If the key doesn't exist,
- * -1 will be returned.
+/* Returns the WEP key at the specified index, or -1 if that key does
+ * not exist.  The buffer is assumed to be at least 16 bytes in length.
  */
-static int get_wep_key(struct airo_info *ai, u16 index) {
+static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
+{
 	WepKeyRid wkr;
 	int rc;
 	__le16 lastindex;
 
 	rc = readWepKeyRid(ai, &wkr, 1, 1);
-	if (rc == SUCCESS) do {
+	if (rc != SUCCESS)
+		return -1;
+	do {
 		lastindex = wkr.kindex;
-		if (wkr.kindex == cpu_to_le16(index)) {
-			if (index == 0xffff) {
-				return wkr.mac[0];
-			}
-			return le16_to_cpu(wkr.klen);
+		if (le16_to_cpu(wkr.kindex) == index) {
+			int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
+			memcpy(buf, wkr.key, klen);
+			return klen;
 		}
-		readWepKeyRid(ai, &wkr, 0, 1);
+		rc = readWepKeyRid(ai, &wkr, 0, 1);
+		if (rc != SUCCESS)
+			return -1;
 	} while (lastindex != wkr.kindex);
 	return -1;
 }
 
-static int set_wep_key(struct airo_info *ai, u16 index,
-		       const char *key, u16 keylen, int perm, int lock )
+static int get_wep_tx_idx(struct airo_info *ai)
+{
+	WepKeyRid wkr;
+	int rc;
+	__le16 lastindex;
+
+	rc = readWepKeyRid(ai, &wkr, 1, 1);
+	if (rc != SUCCESS)
+		return -1;
+	do {
+		lastindex = wkr.kindex;
+		if (wkr.kindex == cpu_to_le16(0xffff))
+			return wkr.mac[0];
+		rc = readWepKeyRid(ai, &wkr, 0, 1);
+		if (rc != SUCCESS)
+			return -1;
+	} while (lastindex != wkr.kindex);
+	return -1;
+}
+
+static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
+		       u16 keylen, int perm, int lock)
 {
 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
 	WepKeyRid wkr;
+	int rc;
 
-	memset(&wkr, 0, sizeof(wkr));
 	if (keylen == 0) {
-// We are selecting which key to use
-		wkr.len = cpu_to_le16(sizeof(wkr));
-		wkr.kindex = cpu_to_le16(0xffff);
-		wkr.mac[0] = (char)index;
-		if (perm) ai->defindex = (char)index;
-	} else {
-// We are actually setting the key
-		wkr.len = cpu_to_le16(sizeof(wkr));
-		wkr.kindex = cpu_to_le16(index);
-		wkr.klen = cpu_to_le16(keylen);
-		memcpy( wkr.key, key, keylen );
-		memcpy( wkr.mac, macaddr, ETH_ALEN );
+		airo_print_err(ai->dev->name, "%s: key length to set was zero",
+			       __func__);
+		return -1;
 	}
 
+	memset(&wkr, 0, sizeof(wkr));
+	wkr.len = cpu_to_le16(sizeof(wkr));
+	wkr.kindex = cpu_to_le16(index);
+	wkr.klen = cpu_to_le16(keylen);
+	memcpy(wkr.key, key, keylen);
+	memcpy(wkr.mac, macaddr, ETH_ALEN);
+
 	if (perm) disable_MAC(ai, lock);
-	writeWepKeyRid(ai, &wkr, perm, lock);
+	rc = writeWepKeyRid(ai, &wkr, perm, lock);
 	if (perm) enable_MAC(ai, lock);
-	return 0;
+	return rc;
+}
+
+static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
+{
+	WepKeyRid wkr;
+	int rc;
+
+	memset(&wkr, 0, sizeof(wkr));
+	wkr.len = cpu_to_le16(sizeof(wkr));
+	wkr.kindex = cpu_to_le16(0xffff);
+	wkr.mac[0] = (char)index;
+
+	if (perm) {
+		ai->defindex = (char)index;
+		disable_MAC(ai, lock);
+	}
+
+	rc = writeWepKeyRid(ai, &wkr, perm, lock);
+
+	if (perm)
+		enable_MAC(ai, lock);
+	return rc;
 }
 
 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
@@ -5187,7 +5294,7 @@ static void proc_wepkey_on_close( struct
 	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = dev->ml_priv;
-	int i;
+	int i, rc;
 	char key[16];
 	u16 index = 0;
 	int j = 0;
@@ -5201,7 +5308,12 @@ static void proc_wepkey_on_close( struct
 	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
 		index = data->wbuffer[0] - '0';
 		if (data->wbuffer[1] == '\n') {
-			set_wep_key(ai, index, NULL, 0, 1, 1);
+			rc = set_wep_tx_idx(ai, index, 1, 1);
+			if (rc < 0) {
+				airo_print_err(ai->dev->name, "failed to set "
+				               "WEP transmit index to %d: %d.",
+				               index, rc);
+			}
 			return;
 		}
 		j = 2;
@@ -5220,7 +5332,12 @@ static void proc_wepkey_on_close( struct
 			break;
 		}
 	}
-	set_wep_key(ai, index, key, i/3, 1, 1);
+
+	rc = set_wep_key(ai, index, key, i/3, 1, 1);
+	if (rc < 0) {
+		airo_print_err(ai->dev->name, "failed to set WEP key at index "
+		               "%d: %d.", index, rc);
+	}
 }
 
 static int proc_wepkey_open( struct inode *inode, struct file *file )
@@ -5451,13 +5568,13 @@ static void timer_func( struct net_devic
 			break;
 		case AUTH_SHAREDKEY:
 			if (apriv->keyindex < auto_wep) {
-				set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
+				set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
 				apriv->config.authType = AUTH_SHAREDKEY;
 				apriv->keyindex++;
 			} else {
 			        /* Drop to ENCRYPT */
 				apriv->keyindex = 0;
-				set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
+				set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
 				apriv->config.authType = AUTH_ENCRYPT;
 			}
 			break;
@@ -5725,16 +5842,12 @@ static int airo_set_freq(struct net_devi
 	int rc = -EINPROGRESS;		/* Call commit handler */
 
 	/* If setting by frequency, convert to a channel */
-	if((fwrq->e == 1) &&
-	   (fwrq->m >= (int) 2.412e8) &&
-	   (fwrq->m <= (int) 2.487e8)) {
+	if(fwrq->e == 1) {
 		int f = fwrq->m / 100000;
-		int c = 0;
-		while((c < 14) && (f != frequency_list[c]))
-			c++;
+
 		/* Hack to fall through... */
 		fwrq->e = 0;
-		fwrq->m = c + 1;
+		fwrq->m = ieee80211_freq_to_dsss_chan(f);
 	}
 	/* Setting by channel number */
 	if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5778,7 +5891,7 @@ static int airo_get_freq(struct net_devi
 
 	ch = le16_to_cpu(status_rid.channel);
 	if((ch > 0) && (ch < 15)) {
-		fwrq->m = frequency_list[ch - 1] * 100000;
+		fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
 		fwrq->e = 1;
 	} else {
 		fwrq->m = ch;
@@ -6234,11 +6347,9 @@ static int airo_get_mode(struct net_devi
 	return 0;
 }
 
-static inline int valid_index(CapabilityRid *p, int index)
+static inline int valid_index(struct airo_info *ai, int index)
 {
-	if (index < 0)
-		return 0;
-	return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
+	return (index >= 0) && (index <= ai->max_wep_idx);
 }
 
 /*------------------------------------------------------------------*/
@@ -6251,16 +6362,13 @@ static int airo_set_encode(struct net_de
 			   char *extra)
 {
 	struct airo_info *local = dev->ml_priv;
-	CapabilityRid cap_rid;		/* Card capability info */
-	int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+	int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
 	__le16 currentAuthType = local->config.authType;
+	int rc = 0;
 
-	/* Is WEP supported ? */
-	readCapabilityRid(local, &cap_rid, 1);
-	/* Older firmware doesn't support this...
-	if(!(cap_rid.softCap & cpu_to_le16(2))) {
+	if (!local->wep_capable)
 		return -EOPNOTSUPP;
-	} */
+
 	readConfigRid(local, 1);
 
 	/* Basic checking: do we have a key to set ?
@@ -6272,14 +6380,21 @@ static int airo_set_encode(struct net_de
 	if (dwrq->length > 0) {
 		wep_key_t key;
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-		int current_index = get_wep_key(local, 0xffff);
+		int current_index;
+
 		/* Check the size of the key */
 		if (dwrq->length > MAX_KEY_SIZE) {
 			return -EINVAL;
 		}
+
+		current_index = get_wep_tx_idx(local);
+		if (current_index < 0)
+			current_index = 0;
+
 		/* Check the index (none -> use current) */
-		if (!valid_index(&cap_rid, index))
+		if (!valid_index(local, index))
 			index = current_index;
+
 		/* Set the length */
 		if (dwrq->length > MIN_KEY_SIZE)
 			key.len = MAX_KEY_SIZE;
@@ -6296,7 +6411,13 @@ static int airo_set_encode(struct net_de
 			/* Copy the key in the driver */
 			memcpy(key.key, extra, dwrq->length);
 			/* Send the key to the card */
-			set_wep_key(local, index, key.key, key.len, perm, 1);
+			rc = set_wep_key(local, index, key.key, key.len, perm, 1);
+			if (rc < 0) {
+				airo_print_err(local->dev->name, "failed to set"
+				               " WEP key at index %d: %d.",
+				               index, rc);
+				return rc;
+			}
 		}
 		/* WE specify that if a valid key is set, encryption
 		 * should be enabled (user may turn it off later)
@@ -6308,12 +6429,19 @@ static int airo_set_encode(struct net_de
 	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-		if (valid_index(&cap_rid, index)) {
-			set_wep_key(local, index, NULL, 0, perm, 1);
-		} else
+		if (valid_index(local, index)) {
+			rc = set_wep_tx_idx(local, index, perm, 1);
+			if (rc < 0) {
+				airo_print_err(local->dev->name, "failed to set"
+				               " WEP transmit index to %d: %d.",
+				               index, rc);
+				return rc;
+			}
+		} else {
 			/* Don't complain if only change the mode */
 			if (!(dwrq->flags & IW_ENCODE_MODE))
 				return -EINVAL;
+		}
 	}
 	/* Read the flags */
 	if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6339,14 +6467,14 @@ static int airo_get_encode(struct net_de
 {
 	struct airo_info *local = dev->ml_priv;
 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-	CapabilityRid cap_rid;		/* Card capability info */
+	int wep_key_len;
+	u8 buf[16];
 
-	/* Is it supported ? */
-	readCapabilityRid(local, &cap_rid, 1);
-	if(!(cap_rid.softCap & cpu_to_le16(2))) {
+	if (!local->wep_capable)
 		return -EOPNOTSUPP;
-	}
+
 	readConfigRid(local, 1);
+
 	/* Check encryption mode */
 	switch(local->config.authType)	{
 		case AUTH_ENCRYPT:
@@ -6365,14 +6493,22 @@ static int airo_get_encode(struct net_de
 	memset(extra, 0, 16);
 
 	/* Which key do we want ? -1 -> tx index */
-	if (!valid_index(&cap_rid, index))
-		index = get_wep_key(local, 0xffff);
+	if (!valid_index(local, index)) {
+		index = get_wep_tx_idx(local);
+		if (index < 0)
+			index = 0;
+	}
 	dwrq->flags |= index + 1;
+
 	/* Copy the key to the user buffer */
-	dwrq->length = get_wep_key(local, index);
-	if (dwrq->length > 16) {
-		dwrq->length=0;
+	wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
+	if (wep_key_len < 0) {
+		dwrq->length = 0;
+	} else {
+		dwrq->length = wep_key_len;
+		memcpy(extra, buf, dwrq->length);
 	}
+
 	return 0;
 }
 
@@ -6388,28 +6524,27 @@ static int airo_set_encodeext(struct net
 	struct airo_info *local = dev->ml_priv;
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	CapabilityRid cap_rid;		/* Card capability info */
 	int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
 	__le16 currentAuthType = local->config.authType;
-	int idx, key_len, alg = ext->alg, set_key = 1;
+	int idx, key_len, alg = ext->alg, set_key = 1, rc;
 	wep_key_t key;
 
-	/* Is WEP supported ? */
-	readCapabilityRid(local, &cap_rid, 1);
-	/* Older firmware doesn't support this...
-	if(!(cap_rid.softCap & cpu_to_le16(2))) {
+	if (!local->wep_capable)
 		return -EOPNOTSUPP;
-	} */
+
 	readConfigRid(local, 1);
 
 	/* Determine and validate the key index */
 	idx = encoding->flags & IW_ENCODE_INDEX;
 	if (idx) {
-		if (!valid_index(&cap_rid, idx - 1))
+		if (!valid_index(local, idx - 1))
 			return -EINVAL;
 		idx--;
-	} else
-		idx = get_wep_key(local, 0xffff);
+	} else {
+		idx = get_wep_tx_idx(local);
+		if (idx < 0)
+			idx = 0;
+	}
 
 	if (encoding->flags & IW_ENCODE_DISABLED)
 		alg = IW_ENCODE_ALG_NONE;
@@ -6418,7 +6553,13 @@ static int airo_set_encodeext(struct net
 		/* Only set transmit key index here, actual
 		 * key is set below if needed.
 		 */
-		set_wep_key(local, idx, NULL, 0, perm, 1);
+		rc = set_wep_tx_idx(local, idx, perm, 1);
+		if (rc < 0) {
+			airo_print_err(local->dev->name, "failed to set "
+			               "WEP transmit index to %d: %d.",
+			               idx, rc);
+			return rc;
+		}
 		set_key = ext->key_len > 0 ? 1 : 0;
 	}
 
@@ -6444,7 +6585,12 @@ static int airo_set_encodeext(struct net
 			return -EINVAL;
 		}
 		/* Send the key to the card */
-		set_wep_key(local, idx, key.key, key.len, perm, 1);
+		rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
+		if (rc < 0) {
+			airo_print_err(local->dev->name, "failed to set WEP key"
+			               " at index %d: %d.", idx, rc);
+			return rc;
+		}
 	}
 
 	/* Read the flags */
@@ -6474,14 +6620,12 @@ static int airo_get_encodeext(struct net
 	struct airo_info *local = dev->ml_priv;
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	CapabilityRid cap_rid;		/* Card capability info */
-	int idx, max_key_len;
+	int idx, max_key_len, wep_key_len;
+	u8 buf[16];
 
-	/* Is it supported ? */
-	readCapabilityRid(local, &cap_rid, 1);
-	if(!(cap_rid.softCap & cpu_to_le16(2))) {
+	if (!local->wep_capable)
 		return -EOPNOTSUPP;
-	}
+
 	readConfigRid(local, 1);
 
 	max_key_len = encoding->length - sizeof(*ext);
@@ -6490,11 +6634,14 @@ static int airo_get_encodeext(struct net
 
 	idx = encoding->flags & IW_ENCODE_INDEX;
 	if (idx) {
-		if (!valid_index(&cap_rid, idx - 1))
+		if (!valid_index(local, idx - 1))
 			return -EINVAL;
 		idx--;
-	} else
-		idx = get_wep_key(local, 0xffff);
+	} else {
+		idx = get_wep_tx_idx(local);
+		if (idx < 0)
+			idx = 0;
+	}
 
 	encoding->flags = idx + 1;
 	memset(ext, 0, sizeof(*ext));
@@ -6517,9 +6664,12 @@ static int airo_get_encodeext(struct net
 	memset(extra, 0, 16);
 	
 	/* Copy the key to the user buffer */
-	ext->key_len = get_wep_key(local, idx);
-	if (ext->key_len > 16) {
-		ext->key_len=0;
+	wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
+	if (wep_key_len < 0) {
+		ext->key_len = 0;
+	} else {
+		ext->key_len = wep_key_len;
+		memcpy(extra, buf, ext->key_len);
 	}
 
 	return 0;
@@ -6574,11 +6724,11 @@ static int airo_set_auth(struct net_devi
 				local->config.authType = AUTH_ENCRYPT;
 			} else
 				return -EINVAL;
-			break;
 
 			/* Commit the changes to flags if needed */
 			if (local->config.authType != currentAuthType)
 				set_bit (FLAG_COMMIT, &local->flags);
+			break;
 		}
 
 	case IW_AUTH_WPA_ENABLED:
@@ -6795,8 +6945,8 @@ static int airo_get_range(struct net_dev
 	k = 0;
 	for(i = 0; i < 14; i++) {
 		range->freq[k].i = i + 1; /* List index */
-		range->freq[k].m = frequency_list[i] * 100000;
-		range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
+		range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
+		range->freq[k++].e = 1;	/* Values in MHz -> * 10^5 * 10 */
 	}
 	range->num_frequency = k;
 
@@ -7031,11 +7181,15 @@ static int airo_get_aplist(struct net_de
 {
 	struct airo_info *local = dev->ml_priv;
 	struct sockaddr *address = (struct sockaddr *) extra;
-	struct iw_quality qual[IW_MAX_AP];
+	struct iw_quality *qual;
 	BSSListRid BSSList;
 	int i;
 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
 
+	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
+	if (!qual)
+		return -ENOMEM;
+
 	for (i = 0; i < IW_MAX_AP; i++) {
 		u16 dBm;
 		if (readBSSListRid(local, loseSync, &BSSList))
@@ -7090,6 +7244,7 @@ static int airo_get_aplist(struct net_de
 	}
 	dwrq->length = i;
 
+	kfree(qual);
 	return 0;
 }
 
@@ -7189,10 +7344,7 @@ static inline char *airo_translate_scan(
 	/* Add frequency */
 	iwe.cmd = SIOCGIWFREQ;
 	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
-	/* iwe.u.freq.m containt the channel (starting 1), our 
-	 * frequency_list array start at index 0...
-	 */
-	iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
+	iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
 	iwe.u.freq.e = 1;
 	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 					  &iwe, IW_EV_FREQ_LEN);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/airo_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/airo_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/airo_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/airo_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,8 +16,8 @@
     In addition this module was derived from dummy_cs.
     The initial developer of dummy_cs is David A. Hinds
     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.    
-    
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
 ======================================================================*/
 
 #ifdef __IN_PCMCIA_PACKAGE__
@@ -38,7 +38,7 @@
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/system.h>
 
 #include "airo.h"
@@ -54,7 +54,7 @@
 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);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
 #else
 #define DEBUG(n, args...)
 #endif
@@ -62,9 +62,9 @@ static char *version = "$Revision: 1.2 $
 /*====================================================================*/
 
 MODULE_AUTHOR("Benjamin Reed");
-MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
-                   cards.  This is the module that links the PCMCIA card \
-		   with the airo module.");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet "
+		   "cards.  This is the module that links the PCMCIA card "
+		   "with the airo module.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
 
@@ -76,7 +76,7 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4
    event is received.  The config() and release() entry points are
    used to configure or release a socket, in response to card
    insertion and ejection events.  They are invoked from the airo_cs
-   event handler. 
+   event handler.
 */
 
 static int airo_config(struct pcmcia_device *link);
@@ -103,8 +103,9 @@ static void airo_detach(struct pcmcia_de
    by one struct pcmcia_device structure (defined in ds.h).
 
    You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of struct pcmcia_device pointers, where minor
-   device numbers are used to derive the corresponding array index.
+   memory card driver uses an array of struct pcmcia_device pointers,
+   where minor device numbers are used to derive the corresponding
+   array index.
 */
 
 /*
@@ -122,22 +123,22 @@ static void airo_detach(struct pcmcia_de
    device IO routines can use a flag like this to throttle IO to a
    card that is not ready to accept it.
 */
-   
+
 typedef struct local_info_t {
 	dev_node_t	node;
 	struct net_device *eth_dev;
 } local_info_t;
 
 /*======================================================================
-  
+
   airo_attach() 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 airo_probe(struct pcmcia_device *p_dev)
@@ -150,7 +151,7 @@ static int airo_probe(struct pcmcia_devi
 	p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 	p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	p_dev->irq.Handler = NULL;
-	
+
 	/*
 	  General socket configuration defaults can go here.  In this
 	  client, we assume very little, and rely on the CIS for almost
@@ -160,7 +161,7 @@ static int airo_probe(struct pcmcia_devi
 	*/
 	p_dev->conf.Attributes = 0;
 	p_dev->conf.IntType = INT_MEMORY_AND_IO;
-	
+
 	/* Allocate space for private device-specific data */
 	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local) {
@@ -173,12 +174,12 @@ static int airo_probe(struct pcmcia_devi
 } /* airo_attach */
 
 /*======================================================================
-  
+
   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 airo_detach(struct pcmcia_device *link)
@@ -187,20 +188,20 @@ static void airo_detach(struct pcmcia_de
 
 	airo_release(link);
 
-	if ( ((local_info_t*)link->priv)->eth_dev ) {
-		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
+	if (((local_info_t *)link->priv)->eth_dev) {
+		stop_airo_card(((local_info_t *)link->priv)->eth_dev, 0);
 	}
-	((local_info_t*)link->priv)->eth_dev = NULL;
+	((local_info_t *)link->priv)->eth_dev = NULL;
 
 	kfree(link->priv);
 } /* airo_detach */
 
 /*======================================================================
-  
+
   airo_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) \
@@ -325,26 +326,28 @@ static int airo_config(struct pcmcia_dev
 	*/
 	if (link->conf.Attributes & CONF_ENABLE_IRQ)
 		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, and putting the
 	  card and host interface into "Memory and IO" mode.
 	*/
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
-	((local_info_t*)link->priv)->eth_dev = 
-		init_airo_card( link->irq.AssignedIRQ,
-				link->io.BasePort1, 1, &handle_to_dev(link) );
-	if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
-	
+	CS_CHECK(RequestConfiguration,
+		 pcmcia_request_configuration(link, &link->conf));
+	((local_info_t *)link->priv)->eth_dev =
+		init_airo_card(link->irq.AssignedIRQ,
+			       link->io.BasePort1, 1, &handle_to_dev(link));
+	if (!((local_info_t *)link->priv)->eth_dev)
+		goto cs_failed;
+
 	/*
 	  At this point, the dev_node_t structure(s) need to be
 	  initialized and arranged in a linked list at link->dev_node.
 	*/
-	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
+	strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name);
 	dev->node.major = dev->node.minor = 0;
 	link->dev_node = &dev->node;
-	
+
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x: ",
 	       dev->node.dev_name, link->conf.ConfigIndex);
@@ -374,11 +377,11 @@ static int airo_config(struct pcmcia_dev
 } /* airo_config */
 
 /*======================================================================
-  
+
   After a card is removed, airo_release() will unregister the
   device, and release the PCMCIA configuration.  If the device is
   still open, this will be postponed until it is closed.
-  
+
   ======================================================================*/
 
 static void airo_release(struct pcmcia_device *link)
@@ -475,7 +478,7 @@ static void airo_cs_cleanup(void)
     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.    
+    POSSIBILITY OF SUCH DAMAGE.
 */
 
 module_init(airo_cs_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/ar9170.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/ar9170.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/ar9170.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/ar9170.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_H
+#define __AR9170_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#ifdef CONFIG_AR9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_AR9170_LEDS */
+#include "eeprom.h"
+#include "hw.h"
+
+#define PAYLOAD_MAX	(AR9170_MAX_CMD_LEN/4 - 1)
+
+enum ar9170_bw {
+	AR9170_BW_20,
+	AR9170_BW_40_BELOW,
+	AR9170_BW_40_ABOVE,
+
+	__AR9170_NUM_BW,
+};
+
+enum ar9170_rf_init_mode {
+	AR9170_RFI_NONE,
+	AR9170_RFI_WARM,
+	AR9170_RFI_COLD,
+};
+
+#define AR9170_MAX_RX_BUFFER_SIZE		8192
+
+#ifdef CONFIG_AR9170_LEDS
+struct ar9170;
+
+struct ar9170_led {
+	struct ar9170 *ar;
+	struct led_classdev l;
+	char name[32];
+	unsigned int toggled;
+	bool registered;
+};
+
+#endif /* CONFIG_AR9170_LEDS */
+
+enum ar9170_device_state {
+	AR9170_UNKNOWN_STATE,
+	AR9170_STOPPED,
+	AR9170_IDLE,
+	AR9170_STARTED,
+	AR9170_ASSOCIATED,
+};
+
+struct ar9170 {
+	struct ieee80211_hw *hw;
+	struct mutex mutex;
+	enum ar9170_device_state state;
+
+	int (*open)(struct ar9170 *);
+	void (*stop)(struct ar9170 *);
+	int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
+	int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
+			void *, u32 , void *);
+	void (*callback_cmd)(struct ar9170 *, u32 , void *);
+
+	/* interface mode settings */
+	struct ieee80211_vif *vif;
+	u8 mac_addr[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+
+	/* beaconing */
+	struct sk_buff *beacon;
+	struct work_struct beacon_work;
+
+	/* cryptographic engine */
+	u64 usedkeys;
+	bool rx_software_decryption;
+	bool disable_offload;
+
+	/* filter settings */
+	struct work_struct filter_config_work;
+	u64 cur_mc_hash, want_mc_hash;
+	u32 cur_filter, want_filter;
+	unsigned int filter_changed;
+	bool sniffer_enabled;
+
+	/* PHY */
+	struct ieee80211_channel *channel;
+	int noise[4];
+
+	/* power calibration data */
+	u8 power_5G_leg[4];
+	u8 power_2G_cck[4];
+	u8 power_2G_ofdm[4];
+	u8 power_5G_ht20[8];
+	u8 power_5G_ht40[8];
+	u8 power_2G_ht20[8];
+	u8 power_2G_ht40[8];
+
+#ifdef CONFIG_AR9170_LEDS
+	struct delayed_work led_work;
+	struct ar9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_AR9170_LEDS */
+
+	/* qos queue settings */
+	spinlock_t tx_stats_lock;
+	struct ieee80211_tx_queue_stats tx_stats[5];
+	struct ieee80211_tx_queue_params edcf[5];
+
+	spinlock_t cmdlock;
+	__le32 cmdbuf[PAYLOAD_MAX + 1];
+
+	/* MAC statistics */
+	struct ieee80211_low_level_stats stats;
+
+	/* EEPROM */
+	struct ar9170_eeprom eeprom;
+
+	/* global tx status for unregistered Stations. */
+	struct sk_buff_head global_tx_status;
+	struct sk_buff_head global_tx_status_waste;
+	struct delayed_work tx_status_janitor;
+};
+
+struct ar9170_sta_info {
+	struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+};
+
+#define IS_STARTED(a)		(a->state >= AR9170_STARTED)
+#define IS_ACCEPTING_CMD(a)	(a->state >= AR9170_IDLE)
+
+#define AR9170_FILTER_CHANGED_PROMISC		BIT(0)
+#define AR9170_FILTER_CHANGED_MULTICAST		BIT(1)
+#define AR9170_FILTER_CHANGED_FRAMEFILTER	BIT(2)
+
+/* exported interface */
+void *ar9170_alloc(size_t priv_size);
+int ar9170_register(struct ar9170 *ar, struct device *pdev);
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_unregister(struct ar9170 *ar);
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+			     bool update_statistics, u16 tx_status);
+
+/* MAC */
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ar9170_init_mac(struct ar9170 *ar);
+int ar9170_set_qos(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar);
+int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_set_operating_mode(struct ar9170 *ar);
+int ar9170_set_beacon_timers(struct ar9170 *ar);
+int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
+int ar9170_update_beacon(struct ar9170 *ar);
+void ar9170_new_beacon(struct work_struct *work);
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+		      u8 keyidx, u8 *keydata, int keylen);
+int ar9170_disable_key(struct ar9170 *ar, u8 id);
+
+/* LEDs */
+#ifdef CONFIG_AR9170_LEDS
+int ar9170_register_leds(struct ar9170 *ar);
+void ar9170_unregister_leds(struct ar9170 *ar);
+#endif /* CONFIG_AR9170_LEDS */
+int ar9170_init_leds(struct ar9170 *ar);
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
+
+/* PHY / RF */
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
+int ar9170_init_rf(struct ar9170 *ar);
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+		       enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
+
+#endif /* __AR9170_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/cmd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/cmd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/cmd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/cmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
+{
+	int err;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return 0;
+
+	err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
+	if (err)
+		printk(KERN_DEBUG "%s: writing memory failed\n",
+		       wiphy_name(ar->hw->wiphy));
+	return err;
+}
+
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+	__le32 buf[2] = {
+		cpu_to_le32(reg),
+		cpu_to_le32(val),
+	};
+	int err;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return 0;
+
+	err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
+			   (u8 *) buf, 0, NULL);
+	if (err)
+		printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
+		       wiphy_name(ar->hw->wiphy), reg, val);
+	return err;
+}
+
+static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
+			    const u32 *regs, u32 *out)
+{
+	int i, err;
+	__le32 *offs, *res;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return 0;
+
+	/* abuse "out" for the register offsets, must be same length */
+	offs = (__le32 *)out;
+	for (i = 0; i < nregs; i++)
+		offs[i] = cpu_to_le32(regs[i]);
+
+	/* also use the same buffer for the input */
+	res = (__le32 *)out;
+
+	err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+			   4 * nregs, (u8 *)offs,
+			   4 * nregs, (u8 *)res);
+	if (err)
+		return err;
+
+	/* convert result to cpu endian */
+	for (i = 0; i < nregs; i++)
+		out[i] = le32_to_cpu(res[i]);
+
+	return 0;
+}
+
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+	return ar9170_read_mreg(ar, 1, &reg, val);
+}
+
+int ar9170_echo_test(struct ar9170 *ar, u32 v)
+{
+	__le32 echobuf = cpu_to_le32(v);
+	__le32 echores;
+	int err;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return -ENODEV;
+
+	err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
+			   4, (u8 *)&echobuf,
+			   4, (u8 *)&echores);
+	if (err)
+		return err;
+
+	if (echobuf != echores)
+		return -EINVAL;
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/cmd.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/cmd.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/cmd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/cmd.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __CMD_H
+#define __CMD_H
+
+#include "ar9170.h"
+
+/* basic HW access */
+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_echo_test(struct ar9170 *ar, u32 v);
+
+/*
+ * Macros to facilitate writing multiple registers in a single
+ * write-combining USB command. Note that when the first group
+ * fails the whole thing will fail without any others attempted,
+ * but you won't know which write in the group failed.
+ */
+#define ar9170_regwrite_begin(ar)					\
+do {									\
+	int __nreg = 0, __err = 0;					\
+	struct ar9170 *__ar = ar;
+
+#define ar9170_regwrite(r, v) do {					\
+	__ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);			\
+	__ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);			\
+	__nreg++;							\
+	if ((__nreg >= PAYLOAD_MAX/2)) {				\
+		if (IS_ACCEPTING_CMD(__ar))				\
+			__err = ar->exec_cmd(__ar, AR9170_CMD_WREG,	\
+					     8 * __nreg,		\
+					     (u8 *) &__ar->cmdbuf[1],	\
+					     0, NULL);			\
+		__nreg = 0;						\
+		if (__err)						\
+			goto __regwrite_out;				\
+	}								\
+} while (0)
+
+#define ar9170_regwrite_finish()					\
+__regwrite_out :							\
+	if (__nreg) {							\
+		if (IS_ACCEPTING_CMD(__ar))				\
+			__err = ar->exec_cmd(__ar, AR9170_CMD_WREG,	\
+					     8 * __nreg, 		\
+					     (u8 *) &__ar->cmdbuf[1],	\
+					     0, NULL);			\
+		__nreg = 0;						\
+	}
+
+#define ar9170_regwrite_result()					\
+	__err;								\
+} while (0);
+
+#endif /* __CMD_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/eeprom.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/eeprom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,179 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_EEPROM_H
+#define __AR9170_EEPROM_H
+
+#define AR5416_MAX_CHAINS		2
+#define AR5416_MODAL_SPURS		5
+
+struct ar9170_eeprom_modal {
+	__le32	antCtrlChain[AR5416_MAX_CHAINS];
+	__le32	antCtrlCommon;
+	s8	antennaGainCh[AR5416_MAX_CHAINS];
+	u8	switchSettling;
+	u8	txRxAttenCh[AR5416_MAX_CHAINS];
+	u8	rxTxMarginCh[AR5416_MAX_CHAINS];
+	s8	adcDesiredSize;
+	s8	pgaDesiredSize;
+	u8	xlnaGainCh[AR5416_MAX_CHAINS];
+	u8	txEndToXpaOff;
+	u8	txEndToRxOn;
+	u8	txFrameToXpaOn;
+	u8	thresh62;
+	s8	noiseFloorThreshCh[AR5416_MAX_CHAINS];
+	u8	xpdGain;
+	u8	xpd;
+	s8	iqCalICh[AR5416_MAX_CHAINS];
+	s8	iqCalQCh[AR5416_MAX_CHAINS];
+	u8	pdGainOverlap;
+	u8	ob;
+	u8	db;
+	u8	xpaBiasLvl;
+	u8	pwrDecreaseFor2Chain;
+	u8	pwrDecreaseFor3Chain;
+	u8	txFrameToDataStart;
+	u8	txFrameToPaOn;
+	u8	ht40PowerIncForPdadc;
+	u8	bswAtten[AR5416_MAX_CHAINS];
+	u8	bswMargin[AR5416_MAX_CHAINS];
+	u8	swSettleHt40;
+	u8	reserved[22];
+	struct spur_channel {
+		__le16 spurChan;
+		u8	spurRangeLow;
+		u8	spurRangeHigh;
+	} __packed spur_channels[AR5416_MODAL_SPURS];
+} __packed;
+
+#define AR5416_NUM_PD_GAINS		4
+#define AR5416_PD_GAIN_ICEPTS		5
+
+struct ar9170_calibration_data_per_freq {
+	u8	pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+	u8	vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+#define AR5416_NUM_5G_CAL_PIERS		8
+#define AR5416_NUM_2G_CAL_PIERS		4
+
+#define AR5416_NUM_5G_TARGET_PWRS	8
+#define AR5416_NUM_2G_CCK_TARGET_PWRS	3
+#define AR5416_NUM_2G_OFDM_TARGET_PWRS	4
+#define AR5416_MAX_NUM_TGT_PWRS		8
+
+struct ar9170_calibration_target_power_legacy {
+	u8	freq;
+	u8	power[4];
+} __packed;
+
+struct ar9170_calibration_target_power_ht {
+	u8	freq;
+	u8	power[8];
+} __packed;
+
+#define AR5416_NUM_CTLS			24
+
+struct ar9170_calctl_edges {
+	u8	channel;
+#define AR9170_CALCTL_EDGE_FLAGS	0xC0
+	u8	power_flags;
+} __packed;
+
+#define AR5416_NUM_BAND_EDGES		8
+
+struct ar9170_calctl_data {
+	struct ar9170_calctl_edges
+		control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+
+struct ar9170_eeprom {
+	__le16	length;
+	__le16	checksum;
+	__le16	version;
+	u8	operating_flags;
+#define AR9170_OPFLAG_5GHZ 		1
+#define AR9170_OPFLAG_2GHZ 		2
+	u8	misc;
+	__le16	reg_domain[2];
+	u8	mac_address[6];
+	u8	rx_mask;
+	u8	tx_mask;
+	__le16	rf_silent;
+	__le16	bluetooth_options;
+	__le16	device_capabilities;
+	__le32	build_number;
+	u8	deviceType;
+	u8	reserved[33];
+
+	u8	customer_data[64];
+
+	struct ar9170_eeprom_modal
+		modal_header[2];
+
+	u8	cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
+	u8	cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
+
+	struct ar9170_calibration_data_per_freq
+		cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
+		cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+
+	/* power calibration data */
+	struct ar9170_calibration_target_power_legacy
+		cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
+	struct ar9170_calibration_target_power_ht
+		cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
+		cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
+
+	struct ar9170_calibration_target_power_legacy
+		cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
+		cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+	struct ar9170_calibration_target_power_ht
+		cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
+		cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+
+	/* conformance testing limits */
+	u8	ctl_index[AR5416_NUM_CTLS];
+	struct ar9170_calctl_data
+		ctl_data[AR5416_NUM_CTLS];
+
+	u8	pad;
+	__le16	subsystem_id;
+} __packed;
+
+#endif /* __AR9170_EEPROM_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,417 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_HW_H
+#define __AR9170_HW_H
+
+#define AR9170_MAX_CMD_LEN	64
+
+enum ar9170_cmd {
+	AR9170_CMD_RREG		= 0x00,
+	AR9170_CMD_WREG		= 0x01,
+	AR9170_CMD_RMEM		= 0x02,
+	AR9170_CMD_WMEM		= 0x03,
+	AR9170_CMD_BITAND	= 0x04,
+	AR9170_CMD_BITOR	= 0x05,
+	AR9170_CMD_EKEY		= 0x28,
+	AR9170_CMD_DKEY		= 0x29,
+	AR9170_CMD_FREQUENCY	= 0x30,
+	AR9170_CMD_RF_INIT	= 0x31,
+	AR9170_CMD_SYNTH	= 0x32,
+	AR9170_CMD_FREQ_START	= 0x33,
+	AR9170_CMD_ECHO		= 0x80,
+	AR9170_CMD_TALLY	= 0x81,
+	AR9170_CMD_TALLY_APD	= 0x82,
+	AR9170_CMD_CONFIG	= 0x83,
+	AR9170_CMD_RESET	= 0x90,
+	AR9170_CMD_DKRESET	= 0x91,
+	AR9170_CMD_DKTX_STATUS	= 0x92,
+	AR9170_CMD_FDC		= 0xA0,
+	AR9170_CMD_WREEPROM	= 0xB0,
+	AR9170_CMD_WFLASH	= 0xB0,
+	AR9170_CMD_FLASH_ERASE	= 0xB1,
+	AR9170_CMD_FLASH_PROG	= 0xB2,
+	AR9170_CMD_FLASH_CHKSUM	= 0xB3,
+	AR9170_CMD_FLASH_READ	= 0xB4,
+	AR9170_CMD_FW_DL_INIT	= 0xB5,
+	AR9170_CMD_MEM_WREEPROM	= 0xBB,
+};
+
+/* endpoints */
+#define AR9170_EP_TX				1
+#define AR9170_EP_RX				2
+#define AR9170_EP_IRQ				3
+#define AR9170_EP_CMD				4
+
+#define AR9170_EEPROM_START			0x1600
+
+#define AR9170_GPIO_REG_BASE			0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE		AR9170_GPIO_REG_BASE
+#define AR9170_GPIO_REG_DATA			(AR9170_GPIO_REG_BASE + 4)
+#define AR9170_NUM_LEDS				2
+
+
+#define AR9170_USB_REG_BASE			0x1e1000
+#define AR9170_USB_REG_DMA_CTL			(AR9170_USB_REG_BASE + 0x108)
+#define		AR9170_DMA_CTL_ENABLE_TO_DEVICE		0x1
+#define		AR9170_DMA_CTL_ENABLE_FROM_DEVICE	0x2
+#define		AR9170_DMA_CTL_HIGH_SPEED		0x4
+#define		AR9170_DMA_CTL_PACKET_MODE		0x8
+
+#define AR9170_USB_REG_MAX_AGG_UPLOAD		(AR9170_USB_REG_BASE + 0x110)
+#define AR9170_USB_REG_UPLOAD_TIME_CTL		(AR9170_USB_REG_BASE + 0x114)
+
+
+
+#define AR9170_MAC_REG_BASE			0x1c3000
+
+#define AR9170_MAC_REG_TSF_L			(AR9170_MAC_REG_BASE + 0x514)
+#define AR9170_MAC_REG_TSF_H			(AR9170_MAC_REG_BASE + 0x518)
+
+#define AR9170_MAC_REG_ATIM_WINDOW		(AR9170_MAC_REG_BASE + 0x51C)
+#define AR9170_MAC_REG_BCN_PERIOD		(AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_REG_PRETBTT			(AR9170_MAC_REG_BASE + 0x524)
+
+#define AR9170_MAC_REG_MAC_ADDR_L		(AR9170_MAC_REG_BASE + 0x610)
+#define AR9170_MAC_REG_MAC_ADDR_H		(AR9170_MAC_REG_BASE + 0x614)
+#define AR9170_MAC_REG_BSSID_L			(AR9170_MAC_REG_BASE + 0x618)
+#define AR9170_MAC_REG_BSSID_H			(AR9170_MAC_REG_BASE + 0x61c)
+
+#define AR9170_MAC_REG_GROUP_HASH_TBL_L		(AR9170_MAC_REG_BASE + 0x624)
+#define AR9170_MAC_REG_GROUP_HASH_TBL_H		(AR9170_MAC_REG_BASE + 0x628)
+
+#define AR9170_MAC_REG_RX_TIMEOUT		(AR9170_MAC_REG_BASE + 0x62C)
+
+#define AR9170_MAC_REG_BASIC_RATE		(AR9170_MAC_REG_BASE + 0x630)
+#define AR9170_MAC_REG_MANDATORY_RATE		(AR9170_MAC_REG_BASE + 0x634)
+#define AR9170_MAC_REG_RTS_CTS_RATE		(AR9170_MAC_REG_BASE + 0x638)
+#define AR9170_MAC_REG_BACKOFF_PROTECT		(AR9170_MAC_REG_BASE + 0x63c)
+#define AR9170_MAC_REG_RX_THRESHOLD		(AR9170_MAC_REG_BASE + 0x640)
+#define AR9170_MAC_REG_RX_PE_DELAY		(AR9170_MAC_REG_BASE + 0x64C)
+
+#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK		(AR9170_MAC_REG_BASE + 0x658)
+#define AR9170_MAC_REG_SNIFFER			(AR9170_MAC_REG_BASE + 0x674)
+#define		AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC	BIT(0)
+#define		AR9170_MAC_REG_SNIFFER_DEFAULTS		0x02000000
+#define AR9170_MAC_REG_ENCRYPTION		(AR9170_MAC_REG_BASE + 0x678)
+#define		AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE	BIT(3)
+#define		AR9170_MAC_REG_ENCRYPTION_DEFAULTS	0x70
+
+#define AR9170_MAC_REG_MISC_680			(AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_TX_UNDERRUN		(AR9170_MAC_REG_BASE + 0x688)
+
+#define AR9170_MAC_REG_FRAMETYPE_FILTER		(AR9170_MAC_REG_BASE + 0x68c)
+#define		AR9170_MAC_REG_FTF_ASSOC_REQ		BIT(0)
+#define		AR9170_MAC_REG_FTF_ASSOC_RESP		BIT(1)
+#define		AR9170_MAC_REG_FTF_REASSOC_REQ		BIT(2)
+#define		AR9170_MAC_REG_FTF_REASSOC_RESP		BIT(3)
+#define		AR9170_MAC_REG_FTF_PRB_REQ		BIT(4)
+#define		AR9170_MAC_REG_FTF_PRB_RESP		BIT(5)
+#define		AR9170_MAC_REG_FTF_BIT6			BIT(6)
+#define		AR9170_MAC_REG_FTF_BIT7			BIT(7)
+#define		AR9170_MAC_REG_FTF_BEACON		BIT(8)
+#define		AR9170_MAC_REG_FTF_ATIM			BIT(9)
+#define		AR9170_MAC_REG_FTF_DEASSOC		BIT(10)
+#define		AR9170_MAC_REG_FTF_AUTH			BIT(11)
+#define		AR9170_MAC_REG_FTF_DEAUTH		BIT(12)
+#define		AR9170_MAC_REG_FTF_BIT13		BIT(13)
+#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_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_MONITOR		0xfd00ffff
+
+#define AR9170_MAC_REG_RX_TOTAL			(AR9170_MAC_REG_BASE + 0x6A0)
+#define AR9170_MAC_REG_RX_CRC32			(AR9170_MAC_REG_BASE + 0x6A4)
+#define AR9170_MAC_REG_RX_CRC16			(AR9170_MAC_REG_BASE + 0x6A8)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI	(AR9170_MAC_REG_BASE + 0x6AC)
+#define AR9170_MAC_REG_RX_OVERRUN		(AR9170_MAC_REG_BASE + 0x6B0)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL	(AR9170_MAC_REG_BASE + 0x6BC)
+#define AR9170_MAC_REG_TX_RETRY			(AR9170_MAC_REG_BASE + 0x6CC)
+#define AR9170_MAC_REG_TX_TOTAL			(AR9170_MAC_REG_BASE + 0x6F4)
+
+
+#define AR9170_MAC_REG_ACK_EXTENSION		(AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_EIFS_AND_SIFS		(AR9170_MAC_REG_BASE + 0x698)
+
+#define AR9170_MAC_REG_SLOT_TIME		(AR9170_MAC_REG_BASE + 0x6F0)
+
+#define AR9170_MAC_REG_POWERMANAGEMENT		(AR9170_MAC_REG_BASE + 0x700)
+#define		AR9170_MAC_REG_POWERMGT_IBSS		0xe0
+#define		AR9170_MAC_REG_POWERMGT_AP		0xa1
+#define		AR9170_MAC_REG_POWERMGT_STA		0x2
+#define		AR9170_MAC_REG_POWERMGT_AP_WDS		0x3
+#define		AR9170_MAC_REG_POWERMGT_DEFAULTS	(0xf << 24)
+
+#define AR9170_MAC_REG_ROLL_CALL_TBL_L		(AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_ROLL_CALL_TBL_H		(AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_AC0_CW			(AR9170_MAC_REG_BASE + 0xB00)
+#define AR9170_MAC_REG_AC1_CW			(AR9170_MAC_REG_BASE + 0xB04)
+#define AR9170_MAC_REG_AC2_CW			(AR9170_MAC_REG_BASE + 0xB08)
+#define AR9170_MAC_REG_AC3_CW			(AR9170_MAC_REG_BASE + 0xB0C)
+#define AR9170_MAC_REG_AC4_CW			(AR9170_MAC_REG_BASE + 0xB10)
+#define AR9170_MAC_REG_AC1_AC0_AIFS		(AR9170_MAC_REG_BASE + 0xB14)
+#define AR9170_MAC_REG_AC3_AC2_AIFS		(AR9170_MAC_REG_BASE + 0xB18)
+
+#define AR9170_MAC_REG_RETRY_MAX		(AR9170_MAC_REG_BASE + 0xB28)
+
+#define AR9170_MAC_REG_FCS_SELECT		(AR9170_MAC_REG_BASE + 0xBB0)
+#define		AR9170_MAC_FCS_SWFCS		0x1
+#define		AR9170_MAC_FCS_FIFO_PROT	0x4
+
+
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND	(AR9170_MAC_REG_BASE + 0xB30)
+
+#define AR9170_MAC_REG_AC1_AC0_TXOP		(AR9170_MAC_REG_BASE + 0xB44)
+#define AR9170_MAC_REG_AC3_AC2_TXOP		(AR9170_MAC_REG_BASE + 0xB48)
+
+#define AR9170_MAC_REG_ACK_TABLE		(AR9170_MAC_REG_BASE + 0xC00)
+#define AR9170_MAC_REG_AMPDU_RX_THRESH		(AR9170_MAC_REG_BASE + 0xC50)
+
+#define AR9170_MAC_REG_TXRX_MPI			(AR9170_MAC_REG_BASE + 0xD7C)
+#define		AR9170_MAC_TXRX_MPI_TX_MPI_MASK	0x0000000f
+#define		AR9170_MAC_TXRX_MPI_TX_TO_MASK	0x0000fff0
+#define		AR9170_MAC_TXRX_MPI_RX_MPI_MASK	0x000f0000
+#define		AR9170_MAC_TXRX_MPI_RX_TO_MASK	0xfff00000
+
+#define AR9170_MAC_REG_BCN_ADDR			(AR9170_MAC_REG_BASE + 0xD84)
+#define AR9170_MAC_REG_BCN_LENGTH		(AR9170_MAC_REG_BASE + 0xD88)
+#define AR9170_MAC_REG_BCN_PLCP			(AR9170_MAC_REG_BASE + 0xD90)
+#define AR9170_MAC_REG_BCN_CTRL			(AR9170_MAC_REG_BASE + 0xD94)
+#define AR9170_MAC_REG_BCN_HT1			(AR9170_MAC_REG_BASE + 0xDA0)
+#define AR9170_MAC_REG_BCN_HT2			(AR9170_MAC_REG_BASE + 0xDA4)
+
+
+#define AR9170_PWR_REG_BASE			0x1D4000
+
+#define AR9170_PWR_REG_CLOCK_SEL		(AR9170_PWR_REG_BASE + 0x008)
+#define		AR9170_PWR_CLK_AHB_40MHZ	0
+#define		AR9170_PWR_CLK_AHB_20_22MHZ	1
+#define		AR9170_PWR_CLK_AHB_40_44MHZ	2
+#define		AR9170_PWR_CLK_AHB_80_88MHZ	3
+#define		AR9170_PWR_CLK_DAC_160_INV_DLY	0x70
+
+
+/* put beacon here in memory */
+#define AR9170_BEACON_BUFFER_ADDRESS		0x117900
+
+
+struct ar9170_tx_control {
+	__le16 length;
+	__le16 mac_control;
+	__le32 phy_control;
+	u8 frame_data[0];
+} __packed;
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS			0x0001
+#define AR9170_TX_MAC_PROT_CTS			0x0002
+
+#define AR9170_TX_MAC_NO_ACK			0x0004
+/* if unset, MAC will only do SIFS space before frame */
+#define AR9170_TX_MAC_BACKOFF			0x0008
+#define AR9170_TX_MAC_BURST			0x0010
+#define AR9170_TX_MAC_AGGR			0x0020
+
+/* encryption is a two-bit field */
+#define AR9170_TX_MAC_ENCR_NONE			0x0000
+#define AR9170_TX_MAC_ENCR_RC4			0x0040
+#define AR9170_TX_MAC_ENCR_CENC			0x0080
+#define AR9170_TX_MAC_ENCR_AES			0x00c0
+
+#define AR9170_TX_MAC_MMIC			0x0100
+#define AR9170_TX_MAC_HW_DURATION		0x0200
+#define AR9170_TX_MAC_QOS_SHIFT			10
+#define AR9170_TX_MAC_QOS_MASK			(3 << AR9170_TX_MAC_QOS_SHIFT)
+#define AR9170_TX_MAC_AGGR_QOS_BIT1		0x0400
+#define AR9170_TX_MAC_AGGR_QOS_BIT2		0x0800
+#define AR9170_TX_MAC_DISABLE_TXOP		0x1000
+#define AR9170_TX_MAC_TXOP_RIFS			0x2000
+#define AR9170_TX_MAC_IMM_AMPDU			0x4000
+#define AR9170_TX_MAC_RATE_PROBE		0x8000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK			0x00000000
+#define AR9170_TX_PHY_MOD_OFDM			0x00000001
+#define AR9170_TX_PHY_MOD_HT			0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE		0x00000004
+#define AR9170_TX_PHY_GREENFIELD		0x00000004
+
+#define AR9170_TX_PHY_BW_SHIFT			3
+#define AR9170_TX_PHY_BW_MASK			(3 << AR9170_TX_PHY_BW_SHIFT)
+#define AR9170_TX_PHY_BW_20MHZ			0
+#define AR9170_TX_PHY_BW_40MHZ			2
+#define AR9170_TX_PHY_BW_40MHZ_DUP		3
+
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT	6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK	(7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
+
+#define AR9170_TX_PHY_TX_PWR_SHIFT		9
+#define AR9170_TX_PHY_TX_PWR_MASK		(0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
+
+/* not part of the hw-spec */
+#define AR9170_TX_PHY_QOS_SHIFT			25
+#define AR9170_TX_PHY_QOS_MASK			(3 << AR9170_TX_PHY_QOS_SHIFT)
+
+#define AR9170_TX_PHY_TXCHAIN_SHIFT		15
+#define AR9170_TX_PHY_TXCHAIN_MASK		(7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
+#define AR9170_TX_PHY_TXCHAIN_1			1
+/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
+#define AR9170_TX_PHY_TXCHAIN_2			5
+
+#define AR9170_TX_PHY_MCS_SHIFT			18
+#define AR9170_TX_PHY_MCS_MASK			(0x7f << AR9170_TX_PHY_MCS_SHIFT)
+
+#define AR9170_TX_PHY_SHORT_GI			0x80000000
+
+struct ar9170_rx_head {
+	u8 plcp[12];
+} __packed;
+
+struct ar9170_rx_tail {
+	union {
+		struct {
+			u8 rssi_ant0, rssi_ant1, rssi_ant2,
+			   rssi_ant0x, rssi_ant1x, rssi_ant2x,
+			   rssi_combined;
+		} __packed;
+		u8 rssi[7];
+	} __packed;
+
+	u8 evm_stream0[6], evm_stream1[6];
+	u8 phy_err;
+	u8 SAidx, DAidx;
+	u8 error;
+	u8 status;
+} __packed;
+
+#define AR9170_ENC_ALG_NONE			0x0
+#define AR9170_ENC_ALG_WEP64			0x1
+#define AR9170_ENC_ALG_TKIP			0x2
+#define AR9170_ENC_ALG_AESCCMP			0x4
+#define AR9170_ENC_ALG_WEP128			0x5
+#define AR9170_ENC_ALG_WEP256			0x6
+#define AR9170_ENC_ALG_CENC			0x7
+
+#define AR9170_RX_ENC_SOFTWARE			0x8
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
+{
+	return (t->SAidx & 0xc0) >> 4 |
+	       (t->DAidx & 0xc0) >> 6;
+}
+
+#define AR9170_RX_STATUS_MODULATION_MASK	0x03
+#define AR9170_RX_STATUS_MODULATION_CCK		0x00
+#define AR9170_RX_STATUS_MODULATION_OFDM	0x01
+#define AR9170_RX_STATUS_MODULATION_HT		0x02
+#define AR9170_RX_STATUS_MODULATION_DUPOFDM	0x03
+
+/* depends on modulation */
+#define AR9170_RX_STATUS_SHORT_PREAMBLE		0x08
+#define AR9170_RX_STATUS_GREENFIELD		0x08
+
+#define AR9170_RX_STATUS_MPDU_MASK		0x30
+#define AR9170_RX_STATUS_MPDU_SINGLE		0x00
+#define AR9170_RX_STATUS_MPDU_FIRST		0x10
+#define AR9170_RX_STATUS_MPDU_MIDDLE		0x20
+#define AR9170_RX_STATUS_MPDU_LAST		0x30
+
+
+#define AR9170_RX_ERROR_RXTO			0x01
+#define AR9170_RX_ERROR_OVERRUN			0x02
+#define AR9170_RX_ERROR_DECRYPT			0x04
+#define AR9170_RX_ERROR_FCS			0x08
+#define AR9170_RX_ERROR_WRONG_RA		0x10
+#define AR9170_RX_ERROR_PLCP			0x20
+#define AR9170_RX_ERROR_MMIC			0x40
+
+struct ar9170_cmd_tx_status {
+	__le16 unkn;
+	u8 dst[ETH_ALEN];
+	__le32 rate;
+	__le16 status;
+} __packed;
+
+#define AR9170_TX_STATUS_COMPLETE		0x00
+#define AR9170_TX_STATUS_RETRY			0x01
+#define AR9170_TX_STATUS_FAILED			0x02
+
+struct ar9170_cmd_ba_failed_count {
+	__le16 failed;
+	__le16 rate;
+} __packed;
+
+struct ar9170_cmd_response {
+	u8 flag;
+	u8 type;
+
+	union {
+		struct ar9170_cmd_tx_status		tx_status;
+		struct ar9170_cmd_ba_failed_count	ba_fail_cnt;
+		u8 data[0];
+	};
+} __packed;
+
+/* QoS */
+
+/* mac80211 queue to HW/FW map */
+static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
+
+/* HW/FW queue to mac80211 map */
+static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
+
+enum ar9170_txq {
+	AR9170_TXQ_BE,
+	AR9170_TXQ_BK,
+	AR9170_TXQ_VI,
+	AR9170_TXQ_VO,
+
+	__AR9170_NUM_TXQ,
+};
+
+#endif /* __AR9170_HW_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,17 @@
+config AR9170_USB
+	tristate "Atheros AR9170 802.11n USB support"
+	depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+	select FW_LOADER
+	help
+	  This is a driver for the Atheros "otus" 802.11n USB devices.
+
+	  These devices require additional firmware (2 files).
+	  For now, these files can be downloaded from here:
+	  http://wireless.kernel.org/en/users/Drivers/ar9170
+
+	  If you choose to build a module, it'll be called ar9170usb.
+
+config AR9170_LEDS
+	bool
+	depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
+	default y
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/led.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/led.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/led.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/led.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,171 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
+{
+	return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
+}
+
+int ar9170_init_leds(struct ar9170 *ar)
+{
+	int err;
+
+	/* disable LEDs */
+	/* GPIO [0/1 mode: output, 2/3: input] */
+	err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+	if (err)
+		goto out;
+
+	/* GPIO 0/1 value: off */
+	err = ar9170_set_leds_state(ar, 0);
+
+out:
+	return err;
+}
+
+#ifdef CONFIG_AR9170_LEDS
+static void ar9170_update_leds(struct work_struct *work)
+{
+	struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+	int i, tmp, blink_delay = 1000;
+	u32 led_val = 0;
+	bool rerun = false;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return ;
+
+	mutex_lock(&ar->mutex);
+	for (i = 0; i < AR9170_NUM_LEDS; i++)
+		if (ar->leds[i].toggled) {
+			led_val |= 1 << i;
+
+			tmp = 70 + 200 / (ar->leds[i].toggled);
+			if (tmp < blink_delay)
+				blink_delay = tmp;
+
+			if (ar->leds[i].toggled > 1)
+				ar->leds[i].toggled = 0;
+
+			rerun = true;
+		}
+
+	ar9170_set_leds_state(ar, led_val);
+	mutex_unlock(&ar->mutex);
+
+	if (rerun)
+		queue_delayed_work(ar->hw->workqueue, &ar->led_work,
+				   msecs_to_jiffies(blink_delay));
+}
+
+static void ar9170_led_brightness_set(struct led_classdev *led,
+				      enum led_brightness brightness)
+{
+	struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
+	struct ar9170 *ar = arl->ar;
+
+	arl->toggled++;
+
+	if (likely(IS_ACCEPTING_CMD(ar) && brightness))
+		queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+}
+
+static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
+			       char *trigger)
+{
+	int err;
+
+	snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+		 "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
+
+	ar->leds[i].ar = ar;
+	ar->leds[i].l.name = ar->leds[i].name;
+	ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
+	ar->leds[i].l.brightness = 0;
+	ar->leds[i].l.default_trigger = trigger;
+
+	err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
+				    &ar->leds[i].l);
+	if (err)
+		printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
+		       wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
+	else
+		ar->leds[i].registered = true;
+
+	return err;
+}
+
+void ar9170_unregister_leds(struct ar9170 *ar)
+{
+	int i;
+
+	cancel_delayed_work_sync(&ar->led_work);
+
+	for (i = 0; i < AR9170_NUM_LEDS; i++)
+		if (ar->leds[i].registered) {
+			led_classdev_unregister(&ar->leds[i].l);
+			ar->leds[i].registered = false;
+		}
+}
+
+int ar9170_register_leds(struct ar9170 *ar)
+{
+	int err;
+
+	INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
+
+	err = ar9170_register_led(ar, 0, "tx",
+				  ieee80211_get_tx_led_name(ar->hw));
+	if (err)
+		goto fail;
+
+	err = ar9170_register_led(ar, 1, "assoc",
+				 ieee80211_get_assoc_led_name(ar->hw));
+	if (err)
+		goto fail;
+
+	return 0;
+
+fail:
+	ar9170_unregister_leds(ar);
+	return err;
+}
+
+#endif /* CONFIG_AR9170_LEDS */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/mac.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/mac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,452 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * MAC programming
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_qos(struct ar9170 *ar)
+{
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+			(ar->edcf[0].cw_max << 16));
+	ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+			(ar->edcf[1].cw_max << 16));
+	ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+			(ar->edcf[2].cw_max << 16));
+	ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+			(ar->edcf[3].cw_max << 16));
+	ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+			(ar->edcf[4].cw_max << 16));
+
+	ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
+			((ar->edcf[0].aifs * 9 + 10)) |
+			((ar->edcf[1].aifs * 9 + 10) << 12) |
+			((ar->edcf[2].aifs * 9 + 10) << 24));
+	ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
+			((ar->edcf[2].aifs * 9 + 10) >> 8) |
+			((ar->edcf[3].aifs * 9 + 10) << 4) |
+			((ar->edcf[4].aifs * 9 + 10) << 16));
+
+	ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+			ar->edcf[0].txop | ar->edcf[1].txop << 16);
+	ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+			ar->edcf[1].txop | ar->edcf[3].txop << 16);
+
+	ar9170_regwrite_finish();
+
+	return ar9170_regwrite_result();
+}
+
+int ar9170_init_mac(struct ar9170 *ar)
+{
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+	ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
+
+	/* enable MMIC */
+	ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
+			AR9170_MAC_REG_SNIFFER_DEFAULTS);
+
+	ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+	ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+	ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+	ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+	/* CF-END mode */
+	ar9170_regwrite(0x1c3b2c, 0x19000000);
+
+	/* NAV protects ACK only (in TXOP) */
+	ar9170_regwrite(0x1c3b38, 0x201);
+
+	/* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+	/* OTUS set AM to 0x1 */
+	ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+	ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+	/* AGG test code*/
+	/* Aggregation MAX number and timeout */
+	ar9170_regwrite(0x1c3b9c, 0x10000a);
+
+	ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+			AR9170_MAC_REG_FTF_DEFAULTS);
+
+	/* Enable deaggregator, response in sniffer mode */
+	ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
+
+	/* rate sets */
+	ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+	ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+	ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
+
+	/* MIMO response control */
+	ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
+
+	/* switch MAC to OTUS interface */
+	ar9170_regwrite(0x1c3600, 0x3);
+
+	ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+	/* set PHY register read timeout (??) */
+	ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+	/* Disable Rx TimeOut, workaround for BB. */
+	ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+	/* Set CPU clock frequency to 88/80MHz */
+	ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
+			AR9170_PWR_CLK_AHB_80_88MHZ |
+			AR9170_PWR_CLK_DAC_160_INV_DLY);
+
+	/* Set WLAN DMA interrupt mode: generate int per packet */
+	ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+	ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+			AR9170_MAC_FCS_FIFO_PROT);
+
+	/* Disables the CF_END frame, undocumented register */
+	ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+			0x141E0F48);
+
+	ar9170_regwrite_finish();
+
+	return ar9170_regwrite_result();
+}
+
+static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
+{
+	static const u8 zero[ETH_ALEN] = { 0 };
+
+	if (!mac)
+		mac = zero;
+
+	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_finish();
+
+	return ar9170_regwrite_result();
+}
+
+int ar9170_update_multicast(struct ar9170 *ar)
+{
+	int err;
+
+	ar9170_regwrite_begin(ar);
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
+		ar->want_mc_hash >> 32);
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
+		ar->want_mc_hash);
+
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+
+	if (err)
+		return err;
+
+	ar->cur_mc_hash = ar->want_mc_hash;
+
+	return 0;
+}
+
+int ar9170_update_frame_filter(struct ar9170 *ar)
+{
+	int err;
+
+	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
+			       ar->want_filter);
+
+	if (err)
+		return err;
+
+	ar->cur_filter = ar->want_filter;
+
+	return 0;
+}
+
+static int ar9170_set_promiscouous(struct ar9170 *ar)
+{
+	u32 encr_mode, sniffer;
+	int err;
+
+	err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
+	if (err)
+		return err;
+
+	err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
+	if (err)
+		return err;
+
+	if (ar->sniffer_enabled) {
+		sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+		/*
+		 * Rx decryption works in place.
+		 *
+		 * If we don't disable it, the hardware will render all
+		 * encrypted frames which are encrypted with an unknown
+		 * key useless.
+		 */
+
+		encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+		ar->sniffer_enabled = true;
+	} else {
+		sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+		if (ar->rx_software_decryption)
+			encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+		else
+			encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+	}
+
+	ar9170_regwrite_begin(ar);
+	ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
+	ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+	ar9170_regwrite_finish();
+
+	return ar9170_regwrite_result();
+}
+
+int ar9170_set_operating_mode(struct ar9170 *ar)
+{
+	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;
+
+		switch (ar->vif->type) {
+		case NL80211_IFTYPE_MESH_POINT:
+		case NL80211_IFTYPE_ADHOC:
+			pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
+			break;
+/*		case NL80211_IFTYPE_AP:
+			pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
+			break;*/
+		case NL80211_IFTYPE_WDS:
+			pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
+			break;
+		case NL80211_IFTYPE_MONITOR:
+			ar->sniffer_enabled = true;
+			ar->rx_software_decryption = true;
+			break;
+		default:
+			pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
+			break;
+		}
+	} else {
+		mac_addr = NULL;
+		bssid = NULL;
+	}
+
+	err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+	if (err)
+		return err;
+
+	err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+	if (err)
+		return err;
+
+	err = ar9170_set_promiscouous(ar);
+	if (err)
+		return err;
+
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
+	ar9170_regwrite_finish();
+
+	return ar9170_regwrite_result();
+}
+
+int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
+{
+	u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+	return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int ar9170_set_beacon_timers(struct ar9170 *ar)
+{
+	u32 v = 0;
+	u32 pretbtt = 0;
+
+	v |= ar->hw->conf.beacon_int;
+
+	if (ar->vif) {
+		switch (ar->vif->type) {
+		case NL80211_IFTYPE_MESH_POINT:
+		case NL80211_IFTYPE_ADHOC:
+			v |= BIT(25);
+			break;
+		case NL80211_IFTYPE_AP:
+			v |= BIT(24);
+			pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
+			break;
+		default:
+			break;
+		}
+
+		v |= ar->vif->bss_conf.dtim_period << 16;
+	}
+
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+	ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+	ar9170_regwrite_finish();
+	return ar9170_regwrite_result();
+}
+
+int ar9170_update_beacon(struct ar9170 *ar)
+{
+	struct sk_buff *skb;
+	__le32 *data, *old = NULL;
+	u32 word;
+	int i;
+
+	skb = ieee80211_beacon_get(ar->hw, ar->vif);
+	if (!skb)
+		return -ENOMEM;
+
+	data = (__le32 *)skb->data;
+	if (ar->beacon)
+		old = (__le32 *)ar->beacon->data;
+
+	ar9170_regwrite_begin(ar);
+	for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+		/*
+		 * XXX: This accesses beyond skb data for up
+		 *	to the last 3 bytes!!
+		 */
+
+		if (old && (data[i] == old[i]))
+			continue;
+
+		word = le32_to_cpu(data[i]);
+		ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
+	}
+
+	/* XXX: use skb->cb info */
+	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+		ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+				((skb->len + 4) << (3+16)) + 0x0400);
+	else
+		ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+				((skb->len + 4) << (3+16)) + 0x0400);
+
+	ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
+	ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
+	ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
+
+	ar9170_regwrite_finish();
+
+	dev_kfree_skb(ar->beacon);
+	ar->beacon = skb;
+
+	return ar9170_regwrite_result();
+}
+
+void ar9170_new_beacon(struct work_struct *work)
+{
+	struct ar9170 *ar = container_of(work, struct ar9170,
+					 beacon_work);
+	struct sk_buff *skb;
+
+	if (unlikely(!IS_STARTED(ar)))
+		return ;
+
+	mutex_lock(&ar->mutex);
+
+	if (!ar->vif)
+		goto out;
+
+	ar9170_update_beacon(ar);
+
+	rcu_read_lock();
+	while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
+		ar9170_op_tx(ar->hw, skb);
+
+	rcu_read_unlock();
+
+ out:
+	mutex_unlock(&ar->mutex);
+}
+
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+		      u8 keyidx, u8 *keydata, int keylen)
+{
+	__le32 vals[7];
+	static const u8 bcast[ETH_ALEN] =
+		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	u8 dummy;
+
+	mac = mac ? : bcast;
+
+	vals[0] = cpu_to_le32((keyidx << 16) + id);
+	vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
+	vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
+			      mac[3] << 8 | mac[2]);
+	memset(&vals[3], 0, 16);
+	if (keydata)
+		memcpy(&vals[3], keydata, keylen);
+
+	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+			    sizeof(vals), (u8 *)vals,
+			    1, &dummy);
+}
+
+int ar9170_disable_key(struct ar9170 *ar, u8 id)
+{
+	__le32 val = cpu_to_le32(id);
+	u8 dummy;
+
+	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+			    sizeof(val), (u8 *)&val,
+			    1, &dummy);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1671 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {	\
+	.bitrate	= (_bitrate),			\
+	.flags		= (_flags),			\
+	.hw_value	= (_hw_rate) | (_txpidx) << 4,	\
+}
+
+static struct ieee80211_rate __ar9170_ratetable[] = {
+	RATE(10, 0, 0, 0),
+	RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
+	RATE(60, 0xb, 0, 0),
+	RATE(90, 0xf, 0, 0),
+	RATE(120, 0xa, 0, 0),
+	RATE(180, 0xe, 0, 0),
+	RATE(240, 0x9, 0, 0),
+	RATE(360, 0xd, 1, 0),
+	RATE(480, 0x8, 2, 0),
+	RATE(540, 0xc, 3, 0),
+};
+#undef RATE
+
+#define ar9170_g_ratetable	(__ar9170_ratetable + 0)
+#define ar9170_g_ratetable_size	12
+#define ar9170_a_ratetable	(__ar9170_ratetable + 4)
+#define ar9170_a_ratetable_size	8
+
+/*
+ * NB: The hw_value is used as an index into the ar9170_phy_freq_params
+ *     array in phy.c so that we don't have to do frequency lookups!
+ */
+#define CHAN(_freq, _idx) {		\
+	.center_freq	= (_freq),	\
+	.hw_value	= (_idx),	\
+	.max_power	= 18, /* XXX */	\
+}
+
+static struct ieee80211_channel ar9170_2ghz_chantable[] = {
+	CHAN(2412,  0),
+	CHAN(2417,  1),
+	CHAN(2422,  2),
+	CHAN(2427,  3),
+	CHAN(2432,  4),
+	CHAN(2437,  5),
+	CHAN(2442,  6),
+	CHAN(2447,  7),
+	CHAN(2452,  8),
+	CHAN(2457,  9),
+	CHAN(2462, 10),
+	CHAN(2467, 11),
+	CHAN(2472, 12),
+	CHAN(2484, 13),
+};
+
+static struct ieee80211_channel ar9170_5ghz_chantable[] = {
+	CHAN(4920, 14),
+	CHAN(4940, 15),
+	CHAN(4960, 16),
+	CHAN(4980, 17),
+	CHAN(5040, 18),
+	CHAN(5060, 19),
+	CHAN(5080, 20),
+	CHAN(5180, 21),
+	CHAN(5200, 22),
+	CHAN(5220, 23),
+	CHAN(5240, 24),
+	CHAN(5260, 25),
+	CHAN(5280, 26),
+	CHAN(5300, 27),
+	CHAN(5320, 28),
+	CHAN(5500, 29),
+	CHAN(5520, 30),
+	CHAN(5540, 31),
+	CHAN(5560, 32),
+	CHAN(5580, 33),
+	CHAN(5600, 34),
+	CHAN(5620, 35),
+	CHAN(5640, 36),
+	CHAN(5660, 37),
+	CHAN(5680, 38),
+	CHAN(5700, 39),
+	CHAN(5745, 40),
+	CHAN(5765, 41),
+	CHAN(5785, 42),
+	CHAN(5805, 43),
+	CHAN(5825, 44),
+	CHAN(5170, 45),
+	CHAN(5190, 46),
+	CHAN(5210, 47),
+	CHAN(5230, 48),
+};
+#undef CHAN
+
+static struct ieee80211_supported_band ar9170_band_2GHz = {
+	.channels	= ar9170_2ghz_chantable,
+	.n_channels	= ARRAY_SIZE(ar9170_2ghz_chantable),
+	.bitrates	= ar9170_g_ratetable,
+	.n_bitrates	= ar9170_g_ratetable_size,
+};
+
+#ifdef AR9170_QUEUE_DEBUG
+/*
+ * In case some wants works with AR9170's crazy tx_status queueing techniques.
+ * He might need this rather useful probing function.
+ *
+ * NOTE: caller must hold the queue's spinlock!
+ */
+
+static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ar9170_tx_control *txc = (void *) skb->data;
+	struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+	printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
+			  "mac_control:%04x, phy_control:%08x]\n",
+	       wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
+	       ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
+	       le32_to_cpu(txc->phy_control));
+}
+
+static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
+						struct sk_buff_head *queue)
+{
+	struct sk_buff *skb;
+	int i = 0;
+
+	printk(KERN_DEBUG "---[ cut here ]---\n");
+	printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
+	       wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
+
+	skb_queue_walk(queue, skb) {
+		struct ar9170_tx_control *txc = (void *) skb->data;
+		struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+		printk(KERN_DEBUG "index:%d => \n", i);
+		ar9170_print_txheader(ar, skb);
+	}
+	printk(KERN_DEBUG "---[ end ]---\n");
+}
+#endif /* AR9170_QUEUE_DEBUG */
+
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+	.channels	= ar9170_5ghz_chantable,
+	.n_channels	= ARRAY_SIZE(ar9170_5ghz_chantable),
+	.bitrates	= ar9170_a_ratetable,
+	.n_bitrates	= ar9170_a_ratetable_size,
+};
+
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+			     bool valid_status, u16 tx_status)
+{
+	struct ieee80211_tx_info *txinfo;
+	unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar->tx_stats_lock, flags);
+	ar->tx_stats[queue].len--;
+	if (ieee80211_queue_stopped(ar->hw, queue))
+		ieee80211_wake_queue(ar->hw, queue);
+	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+	txinfo = IEEE80211_SKB_CB(skb);
+	ieee80211_tx_info_clear_status(txinfo);
+
+	switch (tx_status) {
+	case AR9170_TX_STATUS_RETRY:
+		retries = 2;
+	case AR9170_TX_STATUS_COMPLETE:
+		txinfo->flags |= IEEE80211_TX_STAT_ACK;
+		break;
+
+	case AR9170_TX_STATUS_FAILED:
+		retries = ar->hw->conf.long_frame_max_tx_count;
+		break;
+
+	default:
+		printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
+		       wiphy_name(ar->hw->wiphy), tx_status);
+		break;
+	}
+
+	if (valid_status)
+		txinfo->status.rates[0].count = retries + 1;
+
+	skb_pull(skb, sizeof(struct ar9170_tx_control));
+	ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
+						const u8 *mac,
+						const u32 queue,
+						struct sk_buff_head *q)
+{
+	unsigned long flags;
+	struct sk_buff *skb;
+
+	spin_lock_irqsave(&q->lock, flags);
+	skb_queue_walk(q, skb) {
+		struct ar9170_tx_control *txc = (void *) skb->data;
+		struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+		u32 txc_queue = (le32_to_cpu(txc->phy_control) &
+				AR9170_TX_PHY_QOS_MASK) >>
+				AR9170_TX_PHY_QOS_SHIFT;
+
+		if  ((queue != txc_queue) ||
+		     (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
+			continue;
+
+		__skb_unlink(skb, q);
+		spin_unlock_irqrestore(&q->lock, flags);
+		return skb;
+	}
+	spin_unlock_irqrestore(&q->lock, flags);
+	return NULL;
+}
+
+static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
+					      const u32 queue)
+{
+	struct ieee80211_sta *sta;
+	struct sk_buff *skb;
+
+	/*
+	 * Unfortunately, the firmware does not tell to which (queued) frame
+	 * this transmission status report belongs to.
+	 *
+	 * So we have to make risky guesses - with the scarce information
+	 * the firmware provided (-> destination MAC, and phy_control) -
+	 * and hope that we picked the right one...
+	 */
+	rcu_read_lock();
+	sta = ieee80211_find_sta(ar->hw, mac);
+
+	if (likely(sta)) {
+		struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
+		skb = skb_dequeue(&sta_priv->tx_status[queue]);
+		rcu_read_unlock();
+		if (likely(skb))
+			return skb;
+	} else
+		rcu_read_unlock();
+
+	/* scan the waste queue for candidates */
+	skb = ar9170_find_skb_in_queue(ar, mac, queue,
+				       &ar->global_tx_status_waste);
+	if (!skb) {
+		/* so it still _must_ be in the global list. */
+		skb = ar9170_find_skb_in_queue(ar, mac, queue,
+					       &ar->global_tx_status);
+	}
+
+#ifdef AR9170_QUEUE_DEBUG
+	if (unlikely((!skb) && net_ratelimit())) {
+		printk(KERN_ERR "%s: ESS:[%pM] does not have any "
+				"outstanding frames in this queue (%d).\n",
+				wiphy_name(ar->hw->wiphy), mac, queue);
+	}
+#endif /* AR9170_QUEUE_DEBUG */
+	return skb;
+}
+
+/*
+ * This worker tries to keep the global tx_status queue empty.
+ * So we can guarantee that incoming tx_status reports for
+ * unregistered stations are always synced with the actual
+ * frame - which we think - belongs to.
+ */
+
+static void ar9170_tx_status_janitor(struct work_struct *work)
+{
+	struct ar9170 *ar = container_of(work, struct ar9170,
+					 tx_status_janitor.work);
+	struct sk_buff *skb;
+
+	if (unlikely(!IS_STARTED(ar)))
+		return ;
+
+	mutex_lock(&ar->mutex);
+	/* recycle the garbage back to mac80211... one by one. */
+	while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
+#ifdef AR9170_QUEUE_DEBUG
+		printk(KERN_DEBUG "%s: dispose queued frame =>\n",
+		       wiphy_name(ar->hw->wiphy));
+		ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+		ar9170_handle_tx_status(ar, skb, false,
+					AR9170_TX_STATUS_FAILED);
+	}
+
+	while ((skb = skb_dequeue(&ar->global_tx_status))) {
+#ifdef AR9170_QUEUE_DEBUG
+		printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
+		       wiphy_name(ar->hw->wiphy));
+
+		ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+		skb_queue_tail(&ar->global_tx_status_waste, skb);
+	}
+
+	/* recall the janitor in 100ms - if there's garbage in the can. */
+	if (skb_queue_len(&ar->global_tx_status_waste) > 0)
+		queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+				   msecs_to_jiffies(100));
+
+	mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_handle_command_response(struct ar9170 *ar,
+					   void *buf, u32 len)
+{
+	struct ar9170_cmd_response *cmd = (void *) buf;
+
+	if ((cmd->type & 0xc0) != 0xc0) {
+		ar->callback_cmd(ar, len, buf);
+		return;
+	}
+
+	/* hardware event handlers */
+	switch (cmd->type) {
+	case 0xc1: {
+		/*
+		 * TX status notification:
+		 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
+		 *
+		 * XX always 81
+		 * YY always 00
+		 * M1-M6 is the MAC address
+		 * R1-R4 is the transmit rate
+		 * S1-S2 is the transmit status
+		 */
+
+		struct sk_buff *skb;
+		u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
+			    AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
+
+		skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
+		if (unlikely(!skb))
+			return ;
+
+		ar9170_handle_tx_status(ar, skb, true,
+					le16_to_cpu(cmd->tx_status.status));
+		break;
+		}
+
+	case 0xc0:
+		/*
+		 * pre-TBTT event
+		 */
+		if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
+			queue_work(ar->hw->workqueue, &ar->beacon_work);
+		break;
+
+	case 0xc2:
+		/*
+		 * (IBSS) beacon send notification
+		 * bytes: 04 c2 XX YY B4 B3 B2 B1
+		 *
+		 * XX always 80
+		 * YY always 00
+		 * B1-B4 "should" be the number of send out beacons.
+		 */
+		break;
+
+	case 0xc3:
+		/* End of Atim Window */
+		break;
+
+	case 0xc4:
+	case 0xc5:
+		/* BlockACK events */
+		break;
+
+	case 0xc6:
+		/* Watchdog Interrupt */
+		break;
+
+	case 0xc9:
+		/* retransmission issue / SIFS/EIFS collision ?! */
+		break;
+
+	default:
+		printk(KERN_INFO "received unhandled event %x\n", cmd->type);
+		print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+		break;
+	}
+}
+
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we can
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+	struct sk_buff *skb;
+	struct ar9170_rx_head *head = (void *)buf;
+	struct ar9170_rx_tail *tail;
+	struct ieee80211_rx_status status;
+	int mpdu_len, i;
+	u8 error, antennas = 0, decrypt;
+	__le16 fc;
+	int reserved;
+
+	if (unlikely(!IS_STARTED(ar)))
+		return ;
+
+	/* Received MPDU */
+	mpdu_len = len;
+	mpdu_len -= sizeof(struct ar9170_rx_head);
+	mpdu_len -= sizeof(struct ar9170_rx_tail);
+	BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
+	BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
+
+	if (mpdu_len <= FCS_LEN)
+		return;
+
+	tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
+
+	for (i = 0; i < 3; i++)
+		if (tail->rssi[i] != 0x80)
+			antennas |= BIT(i);
+
+	/* post-process RSSI */
+	for (i = 0; i < 7; i++)
+		if (tail->rssi[i] & 0x80)
+			tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
+
+	memset(&status, 0, sizeof(status));
+
+	status.band = ar->channel->band;
+	status.freq = ar->channel->center_freq;
+	status.signal = ar->noise[0] + tail->rssi_combined;
+	status.noise = ar->noise[0];
+	status.antenna = antennas;
+
+	switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
+	case AR9170_RX_STATUS_MODULATION_CCK:
+		if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+			status.flag |= RX_FLAG_SHORTPRE;
+		switch (head->plcp[0]) {
+		case 0x0a:
+			status.rate_idx = 0;
+			break;
+		case 0x14:
+			status.rate_idx = 1;
+			break;
+		case 0x37:
+			status.rate_idx = 2;
+			break;
+		case 0x6e:
+			status.rate_idx = 3;
+			break;
+		default:
+			if ((!ar->sniffer_enabled) && (net_ratelimit()))
+				printk(KERN_ERR "%s: invalid plcp cck rate "
+				       "(%x).\n", wiphy_name(ar->hw->wiphy),
+				       head->plcp[0]);
+			return;
+		}
+		break;
+	case AR9170_RX_STATUS_MODULATION_OFDM:
+		switch (head->plcp[0] & 0xF) {
+		case 0xB:
+			status.rate_idx = 0;
+			break;
+		case 0xF:
+			status.rate_idx = 1;
+			break;
+		case 0xA:
+			status.rate_idx = 2;
+			break;
+		case 0xE:
+			status.rate_idx = 3;
+			break;
+		case 0x9:
+			status.rate_idx = 4;
+			break;
+		case 0xD:
+			status.rate_idx = 5;
+			break;
+		case 0x8:
+			status.rate_idx = 6;
+			break;
+		case 0xC:
+			status.rate_idx = 7;
+			break;
+		default:
+			if ((!ar->sniffer_enabled) && (net_ratelimit()))
+				printk(KERN_ERR "%s: invalid plcp ofdm rate "
+				       "(%x).\n", wiphy_name(ar->hw->wiphy),
+				       head->plcp[0]);
+			return;
+		}
+		if (status.band == IEEE80211_BAND_2GHZ)
+			status.rate_idx += 4;
+		break;
+	case AR9170_RX_STATUS_MODULATION_HT:
+	case AR9170_RX_STATUS_MODULATION_DUPOFDM:
+		/* XXX */
+
+		if (net_ratelimit())
+			printk(KERN_ERR "%s: invalid modulation\n",
+			       wiphy_name(ar->hw->wiphy));
+		return;
+	}
+
+	error = tail->error;
+
+	if (error & AR9170_RX_ERROR_MMIC) {
+		status.flag |= RX_FLAG_MMIC_ERROR;
+		error &= ~AR9170_RX_ERROR_MMIC;
+	}
+
+	if (error & AR9170_RX_ERROR_PLCP) {
+		status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+		error &= ~AR9170_RX_ERROR_PLCP;
+	}
+
+	if (error & AR9170_RX_ERROR_FCS) {
+		status.flag |= RX_FLAG_FAILED_FCS_CRC;
+		error &= ~AR9170_RX_ERROR_FCS;
+	}
+
+	decrypt = ar9170_get_decrypt_type(tail);
+	if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+	    decrypt != AR9170_ENC_ALG_NONE)
+		status.flag |= RX_FLAG_DECRYPTED;
+
+	/* ignore wrong RA errors */
+	error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+	if (error & AR9170_RX_ERROR_DECRYPT) {
+		error &= ~AR9170_RX_ERROR_DECRYPT;
+
+		/*
+		 * Rx decryption is done in place,
+		 * the original data is lost anyway.
+		 */
+		return ;
+	}
+
+	/* drop any other error frames */
+	if ((error) && (net_ratelimit())) {
+		printk(KERN_DEBUG "%s: errors: %#x\n",
+		       wiphy_name(ar->hw->wiphy), error);
+		return;
+	}
+
+	buf += sizeof(struct ar9170_rx_head);
+	fc = *(__le16 *)buf;
+
+	if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
+		reserved = 32 + 2;
+	else
+		reserved = 32;
+
+	skb = dev_alloc_skb(mpdu_len + reserved);
+	if (!skb)
+		return;
+
+	skb_reserve(skb, reserved);
+	memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
+	ieee80211_rx_irqsafe(ar->hw, skb, &status);
+}
+
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
+{
+	unsigned int i, tlen, resplen;
+	u8 *tbuf, *respbuf;
+
+	tbuf = skb->data;
+	tlen = skb->len;
+
+	while (tlen >= 4) {
+		int clen = tbuf[1] << 8 | tbuf[0];
+		int wlen = (clen + 3) & ~3;
+
+		/*
+		 * parse stream (if any)
+		 */
+		if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
+			printk(KERN_ERR "%s: missing tag!\n",
+			       wiphy_name(ar->hw->wiphy));
+			return ;
+		}
+		if (wlen > tlen - 4) {
+			printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
+			       wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
+			print_hex_dump(KERN_DEBUG, "data: ",
+				       DUMP_PREFIX_OFFSET,
+				       16, 1, tbuf, tlen, true);
+			return ;
+		}
+		resplen = clen;
+		respbuf = tbuf + 4;
+		tbuf += wlen + 4;
+		tlen -= wlen + 4;
+
+		i = 0;
+
+		/* weird thing, but this is the same in the original driver */
+		while (resplen > 2 && i < 12 &&
+		       respbuf[0] == 0xff && respbuf[1] == 0xff) {
+			i += 2;
+			resplen -= 2;
+			respbuf += 2;
+		}
+
+		if (resplen < 4)
+			continue;
+
+		/* found the 6 * 0xffff marker? */
+		if (i == 12)
+			ar9170_handle_command_response(ar, respbuf, resplen);
+		else
+			ar9170_handle_mpdu(ar, respbuf, resplen);
+	}
+
+	if (tlen)
+		printk(KERN_ERR "%s: buffer remains!\n",
+		       wiphy_name(ar->hw->wiphy));
+}
+
+#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)		\
+do {									\
+	queue.aifs = ai_fs;						\
+	queue.cw_min = cwmin;						\
+	queue.cw_max = cwmax;						\
+	queue.txop = _txop;						\
+} while (0)
+
+static int ar9170_op_start(struct ieee80211_hw *hw)
+{
+	struct ar9170 *ar = hw->priv;
+	int err, i;
+
+	mutex_lock(&ar->mutex);
+
+	/* reinitialize queues statistics */
+	memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+	for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
+		ar->tx_stats[i].limit = 8;
+
+	/* reset QoS defaults */
+	AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
+	AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
+	AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
+	AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
+	AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
+
+	err = ar->open(ar);
+	if (err)
+		goto out;
+
+	err = ar9170_init_mac(ar);
+	if (err)
+		goto out;
+
+	err = ar9170_set_qos(ar);
+	if (err)
+		goto out;
+
+	err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
+	if (err)
+		goto out;
+
+	err = ar9170_init_rf(ar);
+	if (err)
+		goto out;
+
+	/* start DMA */
+	err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
+	if (err)
+		goto out;
+
+	ar->state = AR9170_STARTED;
+
+out:
+	mutex_unlock(&ar->mutex);
+	return err;
+}
+
+static void ar9170_op_stop(struct ieee80211_hw *hw)
+{
+	struct ar9170 *ar = hw->priv;
+
+	if (IS_STARTED(ar))
+		ar->state = AR9170_IDLE;
+
+	mutex_lock(&ar->mutex);
+
+	cancel_delayed_work_sync(&ar->tx_status_janitor);
+	cancel_work_sync(&ar->filter_config_work);
+	cancel_work_sync(&ar->beacon_work);
+	skb_queue_purge(&ar->global_tx_status_waste);
+	skb_queue_purge(&ar->global_tx_status);
+
+	if (IS_ACCEPTING_CMD(ar)) {
+		ar9170_set_leds_state(ar, 0);
+
+		/* stop DMA */
+		ar9170_write_reg(ar, 0x1c3d30, 0);
+		ar->stop(ar);
+	}
+
+	mutex_unlock(&ar->mutex);
+}
+
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct ar9170 *ar = hw->priv;
+	struct ieee80211_hdr *hdr;
+	struct ar9170_tx_control *txc;
+	struct ieee80211_tx_info *info;
+	struct ieee80211_rate *rate = NULL;
+	struct ieee80211_tx_rate *txrate;
+	unsigned int queue = skb_get_queue_mapping(skb);
+	unsigned long flags = 0;
+	struct ar9170_sta_info *sta_info = NULL;
+	u32 power, chains;
+	u16 keytype = 0;
+	u16 len, icv = 0;
+	int err;
+	bool tx_status;
+
+	if (unlikely(!IS_STARTED(ar)))
+		goto err_free;
+
+	hdr = (void *)skb->data;
+	info = IEEE80211_SKB_CB(skb);
+	len = skb->len;
+
+	spin_lock_irqsave(&ar->tx_stats_lock, flags);
+	if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
+		spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+		return NETDEV_TX_OK;
+	}
+
+	ar->tx_stats[queue].len++;
+	ar->tx_stats[queue].count++;
+	if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
+		ieee80211_stop_queue(hw, queue);
+
+	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+	txc = (void *)skb_push(skb, sizeof(*txc));
+
+	tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
+		    ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
+
+	if (info->control.hw_key) {
+		icv = info->control.hw_key->icv_len;
+
+		switch (info->control.hw_key->alg) {
+		case ALG_WEP:
+			keytype = AR9170_TX_MAC_ENCR_RC4;
+			break;
+		case ALG_TKIP:
+			keytype = AR9170_TX_MAC_ENCR_RC4;
+			break;
+		case ALG_CCMP:
+			keytype = AR9170_TX_MAC_ENCR_AES;
+			break;
+		default:
+			WARN_ON(1);
+			goto err_dequeue;
+		}
+	}
+
+	/* Length */
+	txc->length = cpu_to_le16(len + icv + 4);
+
+	txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+				       AR9170_TX_MAC_BACKOFF);
+	txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
+					AR9170_TX_MAC_QOS_SHIFT);
+	txc->mac_control |= cpu_to_le16(keytype);
+	txc->phy_control = cpu_to_le32(0);
+
+	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+	if (info->flags & IEEE80211_TX_CTL_AMPDU)
+		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+
+	txrate = &info->control.rates[0];
+
+	if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+	else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+
+	if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+
+	if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+
+	if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
+	/* this works because 40 MHz is 2 and dup is 3 */
+	if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
+
+	if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+	if (txrate->flags & IEEE80211_TX_RC_MCS) {
+		u32 r = txrate->idx;
+		u8 *txpower;
+
+		r <<= AR9170_TX_PHY_MCS_SHIFT;
+		if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
+			goto err_dequeue;
+		txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
+		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+		if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+			if (info->band == IEEE80211_BAND_5GHZ)
+				txpower = ar->power_5G_ht40;
+			else
+				txpower = ar->power_2G_ht40;
+		} else {
+			if (info->band == IEEE80211_BAND_5GHZ)
+				txpower = ar->power_5G_ht20;
+			else
+				txpower = ar->power_2G_ht20;
+		}
+
+		power = txpower[(txrate->idx) & 7];
+	} else {
+		u8 *txpower;
+		u32 mod;
+		u32 phyrate;
+		u8 idx = txrate->idx;
+
+		if (info->band != IEEE80211_BAND_2GHZ) {
+			idx += 4;
+			txpower = ar->power_5G_leg;
+			mod = AR9170_TX_PHY_MOD_OFDM;
+		} else {
+			if (idx < 4) {
+				txpower = ar->power_2G_cck;
+				mod = AR9170_TX_PHY_MOD_CCK;
+			} else {
+				mod = AR9170_TX_PHY_MOD_OFDM;
+				txpower = ar->power_2G_ofdm;
+			}
+		}
+
+		rate = &__ar9170_ratetable[idx];
+
+		phyrate = rate->hw_value & 0xF;
+		power = txpower[(rate->hw_value & 0x30) >> 4];
+		phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
+
+		txc->phy_control |= cpu_to_le32(mod);
+		txc->phy_control |= cpu_to_le32(phyrate);
+	}
+
+	power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
+	power &= AR9170_TX_PHY_TX_PWR_MASK;
+	txc->phy_control |= cpu_to_le32(power);
+
+	/* set TX chains */
+	if (ar->eeprom.tx_mask == 1) {
+		chains = AR9170_TX_PHY_TXCHAIN_1;
+	} else {
+		chains = AR9170_TX_PHY_TXCHAIN_2;
+
+		/* >= 36M legacy OFDM - use only one chain */
+		if (rate && rate->bitrate >= 360)
+			chains = AR9170_TX_PHY_TXCHAIN_1;
+	}
+	txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
+
+	if (tx_status) {
+		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+		/*
+		 * WARNING:
+		 * Putting the QoS queue bits into an unexplored territory is
+		 * certainly not elegant.
+		 *
+		 * In my defense: This idea provides a reasonable way to
+		 * smuggle valuable information to the tx_status callback.
+		 * Also, the idea behind this bit-abuse came straight from
+		 * the original driver code.
+		 */
+
+		txc->phy_control |=
+			cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+
+		if (info->control.sta) {
+			sta_info = (void *) info->control.sta->drv_priv;
+			skb_queue_tail(&sta_info->tx_status[queue], skb);
+		} else {
+			skb_queue_tail(&ar->global_tx_status, skb);
+
+			queue_delayed_work(ar->hw->workqueue,
+					   &ar->tx_status_janitor,
+					   msecs_to_jiffies(100));
+		}
+	}
+
+	err = ar->tx(ar, skb, tx_status, 0);
+	if (unlikely(tx_status && err)) {
+		if (info->control.sta)
+			skb_unlink(skb, &sta_info->tx_status[queue]);
+		else
+			skb_unlink(skb, &ar->global_tx_status);
+	}
+
+	return NETDEV_TX_OK;
+
+err_dequeue:
+	spin_lock_irqsave(&ar->tx_stats_lock, flags);
+	ar->tx_stats[queue].len--;
+	ar->tx_stats[queue].count--;
+	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+err_free:
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static int ar9170_op_add_interface(struct ieee80211_hw *hw,
+				   struct ieee80211_if_init_conf *conf)
+{
+	struct ar9170 *ar = hw->priv;
+	int err = 0;
+
+	mutex_lock(&ar->mutex);
+
+	if (ar->vif) {
+		err = -EBUSY;
+		goto unlock;
+	}
+
+	ar->vif = conf->vif;
+	memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
+
+	if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
+		ar->rx_software_decryption = true;
+		ar->disable_offload = true;
+	}
+
+	ar->cur_filter = 0;
+	ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
+	err = ar9170_update_frame_filter(ar);
+	if (err)
+		goto unlock;
+
+	err = ar9170_set_operating_mode(ar);
+
+unlock:
+	mutex_unlock(&ar->mutex);
+	return err;
+}
+
+static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
+				       struct ieee80211_if_init_conf *conf)
+{
+	struct ar9170 *ar = hw->priv;
+
+	mutex_lock(&ar->mutex);
+	ar->vif = NULL;
+	ar->want_filter = 0;
+	ar9170_update_frame_filter(ar);
+	ar9170_set_beacon_timers(ar);
+	dev_kfree_skb(ar->beacon);
+	ar->beacon = NULL;
+	ar->sniffer_enabled = false;
+	ar->rx_software_decryption = false;
+	ar9170_set_operating_mode(ar);
+	mutex_unlock(&ar->mutex);
+}
+
+static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct ar9170 *ar = hw->priv;
+	int err = 0;
+
+	mutex_lock(&ar->mutex);
+
+	if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+		/* TODO */
+		err = 0;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+		/* TODO */
+		err = 0;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		/* TODO */
+		err = 0;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+		/* TODO */
+		err = 0;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+		/*
+		 * is it long_frame_max_tx_count or short_frame_max_tx_count?
+		 */
+
+		err = ar9170_set_hwretry_limit(ar,
+			ar->hw->conf.long_frame_max_tx_count);
+		if (err)
+			goto out;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
+		err = ar9170_set_beacon_timers(ar);
+		if (err)
+			goto out;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+		err = ar9170_set_channel(ar, hw->conf.channel,
+					 AR9170_RFI_NONE, AR9170_BW_20);
+		if (err)
+			goto out;
+		/* adjust slot time for 5 GHz */
+		if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+			err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
+					       9 << 10);
+	}
+
+out:
+	mutex_unlock(&ar->mutex);
+	return err;
+}
+
+static int ar9170_op_config_interface(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      struct ieee80211_if_conf *conf)
+{
+	struct ar9170 *ar = hw->priv;
+	int err = 0;
+
+	mutex_lock(&ar->mutex);
+
+	if (conf->changed & IEEE80211_IFCC_BSSID) {
+		memcpy(ar->bssid, conf->bssid, ETH_ALEN);
+		err = ar9170_set_operating_mode(ar);
+	}
+
+	if (conf->changed & IEEE80211_IFCC_BEACON) {
+		err = ar9170_update_beacon(ar);
+
+		if (err)
+			goto out;
+		err = ar9170_set_beacon_timers(ar);
+	}
+
+out:
+	mutex_unlock(&ar->mutex);
+	return err;
+}
+
+static void ar9170_set_filters(struct work_struct *work)
+{
+	struct ar9170 *ar = container_of(work, struct ar9170,
+					 filter_config_work);
+	int err;
+
+	mutex_lock(&ar->mutex);
+	if (unlikely(!IS_STARTED(ar)))
+		goto unlock;
+
+	if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
+		err = ar9170_set_operating_mode(ar);
+		if (err)
+			goto unlock;
+	}
+
+	if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
+		err = ar9170_update_multicast(ar);
+		if (err)
+			goto unlock;
+	}
+
+	if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
+		err = ar9170_update_frame_filter(ar);
+
+unlock:
+	mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
+				       unsigned int changed_flags,
+				       unsigned int *new_flags,
+				       int mc_count, struct dev_mc_list *mclist)
+{
+	struct ar9170 *ar = hw->priv;
+
+	/* mask supported flags */
+	*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
+		      FIF_PROMISC_IN_BSS;
+
+	/*
+	 * We can support more by setting the sniffer bit and
+	 * then checking the error flags, later.
+	 */
+
+	if (changed_flags & FIF_ALLMULTI) {
+		if (*new_flags & FIF_ALLMULTI) {
+			ar->want_mc_hash = ~0ULL;
+		} else {
+			u64 mchash;
+			int i;
+
+			/* always get broadcast frames */
+			mchash = 1ULL << (0xff>>2);
+
+			for (i = 0; i < mc_count; i++) {
+				if (WARN_ON(!mclist))
+					break;
+				mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+				mclist = mclist->next;
+			}
+		ar->want_mc_hash = mchash;
+		}
+		ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
+	}
+
+	if (changed_flags & FIF_CONTROL) {
+		u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
+			     AR9170_MAC_REG_FTF_RTS |
+			     AR9170_MAC_REG_FTF_CTS |
+			     AR9170_MAC_REG_FTF_ACK |
+			     AR9170_MAC_REG_FTF_CFE |
+			     AR9170_MAC_REG_FTF_CFE_ACK;
+
+		if (*new_flags & FIF_CONTROL)
+			ar->want_filter = ar->cur_filter | filter;
+		else
+			ar->want_filter = ar->cur_filter & ~filter;
+
+		ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
+	}
+
+	if (changed_flags & FIF_PROMISC_IN_BSS) {
+		ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
+		ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
+	}
+
+	if (likely(IS_STARTED(ar)))
+		queue_work(ar->hw->workqueue, &ar->filter_config_work);
+}
+
+static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u32 changed)
+{
+	struct ar9170 *ar = hw->priv;
+	int err = 0;
+
+	mutex_lock(&ar->mutex);
+
+	ar9170_regwrite_begin(ar);
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
+
+#ifndef CONFIG_AR9170_LEDS
+		/* enable assoc LED. */
+		err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
+#endif /* CONFIG_AR9170_LEDS */
+	}
+
+	if (changed & BSS_CHANGED_HT) {
+		/* TODO */
+		err = 0;
+	}
+
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		u32 slottime = 20;
+
+		if (bss_conf->use_short_slot)
+			slottime = 9;
+
+		ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+	}
+
+	if (changed & BSS_CHANGED_BASIC_RATES) {
+		u32 cck, ofdm;
+
+		if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
+			ofdm = bss_conf->basic_rates;
+			cck = 0;
+		} else {
+			/* four cck rates */
+			cck = bss_conf->basic_rates & 0xf;
+			ofdm = bss_conf->basic_rates >> 4;
+		}
+		ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
+				ofdm << 8 | cck);
+	}
+
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+	mutex_unlock(&ar->mutex);
+}
+
+static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+	struct ar9170 *ar = hw->priv;
+	int err;
+	u32 tsf_low;
+	u32 tsf_high;
+	u64 tsf;
+
+	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);
+	mutex_unlock(&ar->mutex);
+
+	if (WARN_ON(err))
+		return 0;
+
+	tsf = tsf_high;
+	tsf = (tsf << 32) | tsf_low;
+	return tsf;
+}
+
+static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key)
+{
+	struct ar9170 *ar = hw->priv;
+	int err = 0, i;
+	u8 ktype;
+
+	if ((!ar->vif) || (ar->disable_offload))
+		return -EOPNOTSUPP;
+
+	switch (key->alg) {
+	case ALG_WEP:
+		if (key->keylen == LEN_WEP40)
+			ktype = AR9170_ENC_ALG_WEP64;
+		else
+			ktype = AR9170_ENC_ALG_WEP128;
+		break;
+	case ALG_TKIP:
+		ktype = AR9170_ENC_ALG_TKIP;
+		break;
+	case ALG_CCMP:
+		ktype = AR9170_ENC_ALG_AESCCMP;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	mutex_lock(&ar->mutex);
+	if (cmd == SET_KEY) {
+		if (unlikely(!IS_STARTED(ar))) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+
+		/* group keys need all-zeroes address */
+		if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+			sta = NULL;
+
+		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+			for (i = 0; i < 64; i++)
+				if (!(ar->usedkeys & BIT(i)))
+					break;
+			if (i == 64) {
+				ar->rx_software_decryption = true;
+				ar9170_set_operating_mode(ar);
+				err = -ENOSPC;
+				goto out;
+			}
+		} else {
+			i = 64 + key->keyidx;
+		}
+
+		key->hw_key_idx = i;
+
+		err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
+					key->key, min_t(u8, 16, key->keylen));
+		if (err)
+			goto out;
+
+		if (key->alg == ALG_TKIP) {
+			err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
+						ktype, 1, key->key + 16, 16);
+			if (err)
+				goto out;
+
+			/*
+			 * hardware is not capable generating the MMIC
+			 * for fragmented frames!
+			 */
+			key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+		}
+
+		if (i < 64)
+			ar->usedkeys |= BIT(i);
+
+		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+	} else {
+		if (unlikely(!IS_STARTED(ar))) {
+			/* The device is gone... together with the key ;-) */
+			err = 0;
+			goto out;
+		}
+
+		err = ar9170_disable_key(ar, key->hw_key_idx);
+		if (err)
+			goto out;
+
+		if (key->hw_key_idx < 64) {
+			ar->usedkeys &= ~BIT(key->hw_key_idx);
+		} else {
+			err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
+						AR9170_ENC_ALG_NONE, 0,
+						NULL, 0);
+			if (err)
+				goto out;
+
+			if (key->alg == ALG_TKIP) {
+				err = ar9170_upload_key(ar, key->hw_key_idx,
+							NULL,
+							AR9170_ENC_ALG_NONE, 1,
+							NULL, 0);
+				if (err)
+					goto out;
+			}
+
+		}
+	}
+
+	ar9170_regwrite_begin(ar);
+	ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
+	ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+
+out:
+	mutex_unlock(&ar->mutex);
+
+	return err;
+}
+
+static void ar9170_sta_notify(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
+			      enum sta_notify_cmd cmd,
+			      struct ieee80211_sta *sta)
+{
+	struct ar9170 *ar = hw->priv;
+	struct ar9170_sta_info *info = (void *) sta->drv_priv;
+	struct sk_buff *skb;
+	unsigned int i;
+
+	switch (cmd) {
+	case STA_NOTIFY_ADD:
+		for (i = 0; i < ar->hw->queues; i++)
+			skb_queue_head_init(&info->tx_status[i]);
+		break;
+
+	case STA_NOTIFY_REMOVE:
+
+		/*
+		 * transfer all outstanding frames that need a tx_status
+		 * reports to the global tx_status queue
+		 */
+
+		for (i = 0; i < ar->hw->queues; i++) {
+			while ((skb = skb_dequeue(&info->tx_status[i]))) {
+#ifdef AR9170_QUEUE_DEBUG
+				printk(KERN_DEBUG "%s: queueing frame in "
+					  "global tx_status queue =>\n",
+				       wiphy_name(ar->hw->wiphy));
+
+				ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+				skb_queue_tail(&ar->global_tx_status, skb);
+			}
+		}
+		queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+				   msecs_to_jiffies(100));
+		break;
+
+	default:
+		break;
+	}
+}
+
+static int ar9170_get_stats(struct ieee80211_hw *hw,
+			    struct ieee80211_low_level_stats *stats)
+{
+	struct ar9170 *ar = hw->priv;
+	u32 val;
+	int err;
+
+	mutex_lock(&ar->mutex);
+	err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
+	ar->stats.dot11ACKFailureCount += val;
+
+	memcpy(stats, &ar->stats, sizeof(*stats));
+	mutex_unlock(&ar->mutex);
+
+	return 0;
+}
+
+static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
+			       struct ieee80211_tx_queue_stats *tx_stats)
+{
+	struct ar9170 *ar = hw->priv;
+
+	spin_lock_bh(&ar->tx_stats_lock);
+	memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
+	spin_unlock_bh(&ar->tx_stats_lock);
+
+	return 0;
+}
+
+static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
+			  const struct ieee80211_tx_queue_params *param)
+{
+	struct ar9170 *ar = hw->priv;
+	int ret;
+
+	mutex_lock(&ar->mutex);
+	if ((param) && !(queue > ar->hw->queues)) {
+		memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
+		       param, sizeof(*param));
+
+		ret = ar9170_set_qos(ar);
+	} else
+		ret = -EINVAL;
+
+	mutex_unlock(&ar->mutex);
+	return ret;
+}
+
+static const struct ieee80211_ops ar9170_ops = {
+	.start			= ar9170_op_start,
+	.stop			= ar9170_op_stop,
+	.tx			= ar9170_op_tx,
+	.add_interface		= ar9170_op_add_interface,
+	.remove_interface	= ar9170_op_remove_interface,
+	.config			= ar9170_op_config,
+	.config_interface	= ar9170_op_config_interface,
+	.configure_filter	= ar9170_op_configure_filter,
+	.conf_tx		= ar9170_conf_tx,
+	.bss_info_changed	= ar9170_op_bss_info_changed,
+	.get_tsf		= ar9170_op_get_tsf,
+	.set_key		= ar9170_set_key,
+	.sta_notify		= ar9170_sta_notify,
+	.get_stats		= ar9170_get_stats,
+	.get_tx_stats		= ar9170_get_tx_stats,
+};
+
+void *ar9170_alloc(size_t priv_size)
+{
+	struct ieee80211_hw *hw;
+	struct ar9170 *ar;
+	int i;
+
+	hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
+	if (!hw)
+		return ERR_PTR(-ENOMEM);
+
+	ar = hw->priv;
+	ar->hw = hw;
+
+	mutex_init(&ar->mutex);
+	spin_lock_init(&ar->cmdlock);
+	spin_lock_init(&ar->tx_stats_lock);
+	skb_queue_head_init(&ar->global_tx_status);
+	skb_queue_head_init(&ar->global_tx_status_waste);
+	INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
+	INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
+	INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
+
+	/* all hw supports 2.4 GHz, so set channel to 1 by default */
+	ar->channel = &ar9170_2ghz_chantable[0];
+
+	/* first part of wiphy init */
+	ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+					 BIT(NL80211_IFTYPE_WDS) |
+					 BIT(NL80211_IFTYPE_ADHOC);
+	ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+			 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+			 IEEE80211_HW_SIGNAL_DBM |
+			 IEEE80211_HW_NOISE_DBM;
+
+	ar->hw->queues = __AR9170_NUM_TXQ;
+	ar->hw->extra_tx_headroom = 8;
+	ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
+
+	ar->hw->max_rates = 1;
+	ar->hw->max_rate_tries = 3;
+
+	for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+		ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+	return ar;
+}
+
+static int ar9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW	8	/* number of words to read at once */
+#define RB	(sizeof(u32) * RW)
+	DECLARE_MAC_BUF(mbuf);
+	u8 *eeprom = (void *)&ar->eeprom;
+	u8 *addr = ar->eeprom.mac_address;
+	__le32 offsets[RW];
+	int i, j, err, bands = 0;
+
+	BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+	BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
+#ifndef __CHECKER__
+	/* don't want to handle trailing remains */
+	BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
+#endif
+
+	for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+		for (j = 0; j < RW; j++)
+			offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
+						 RB * i + 4 * j);
+
+		err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+				   RB, (u8 *) &offsets,
+				   RB, eeprom + RB * i);
+		if (err)
+			return err;
+	}
+
+#undef RW
+#undef RB
+
+	if (ar->eeprom.length == cpu_to_le16(0xFFFF))
+		return -ENODATA;
+
+	if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+		ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
+		bands++;
+	}
+	if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+		ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
+		bands++;
+	}
+	/*
+	 * I measured this, a bandswitch takes roughly
+	 * 135 ms and a frequency switch about 80.
+	 *
+	 * FIXME: measure these values again once EEPROM settings
+	 *	  are used, that will influence them!
+	 */
+	if (bands == 2)
+		ar->hw->channel_change_time = 135 * 1000;
+	else
+		ar->hw->channel_change_time = 80 * 1000;
+
+	/* second part of wiphy init */
+	SET_IEEE80211_PERM_ADDR(ar->hw, addr);
+
+	return bands ? 0 : -EINVAL;
+}
+
+int ar9170_register(struct ar9170 *ar, struct device *pdev)
+{
+	int err;
+
+	/* try to read EEPROM, init MAC addr */
+	err = ar9170_read_eeprom(ar);
+	if (err)
+		goto err_out;
+
+	err = ieee80211_register_hw(ar->hw);
+	if (err)
+		goto err_out;
+
+	err = ar9170_init_leds(ar);
+	if (err)
+		goto err_unreg;
+
+#ifdef CONFIG_AR9170_LEDS
+	err = ar9170_register_leds(ar);
+	if (err)
+		goto err_unreg;
+#endif /* CONFIG_AR9170_LEDS */
+
+	dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
+		 wiphy_name(ar->hw->wiphy));
+
+	return err;
+
+err_unreg:
+	ieee80211_unregister_hw(ar->hw);
+
+err_out:
+	return err;
+}
+
+void ar9170_unregister(struct ar9170 *ar)
+{
+#ifdef CONFIG_AR9170_LEDS
+	ar9170_unregister_leds(ar);
+#endif /* CONFIG_AR9170_LEDS */
+
+	ieee80211_unregister_hw(ar->hw);
+	mutex_destroy(&ar->mutex);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,3 @@
+ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
+
+obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/phy.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1240 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * PHY and RF code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 <linux/bitrev.h>
+#include "ar9170.h"
+#include "cmd.h"
+
+static int ar9170_init_power_cal(struct ar9170 *ar)
+{
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
+	ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
+	ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
+
+	ar9170_regwrite_finish();
+	return ar9170_regwrite_result();
+}
+
+struct ar9170_phy_init {
+	u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct ar9170_phy_init ar5416_phy_init[] = {
+	{ 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+	{ 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
+	{ 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
+	{ 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
+	{ 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
+	{ 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
+	{ 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
+	{ 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+	{ 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
+	{ 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+	{ 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+	{ 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+	{ 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
+	{ 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
+	{ 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
+	{ 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
+	{ 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
+	{ 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
+	{ 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+	{ 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+	{ 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
+	{ 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+	{ 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
+	{ 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
+	{ 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
+	{ 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
+	{ 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
+	{ 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
+	{ 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
+	{ 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+	{ 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+	{ 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
+	{ 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
+	{ 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
+	{ 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
+	{ 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
+	{ 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
+	{ 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+	{ 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
+	{ 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
+	{ 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+	{ 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+	{ 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
+	{ 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
+	{ 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
+	{ 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
+	{ 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+	{ 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+	{ 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
+	{ 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
+	{ 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
+	{ 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
+	{ 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
+	{ 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
+	{ 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
+	{ 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
+	{ 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
+	{ 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
+	{ 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
+	{ 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
+	{ 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
+	{ 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
+	{ 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
+	{ 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
+	{ 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
+	{ 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+	{ 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
+	{ 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
+	{ 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
+	{ 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
+	{ 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
+	{ 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
+	{ 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
+	{ 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
+	{ 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
+	{ 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
+	{ 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
+	{ 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
+	{ 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
+	{ 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
+	{ 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
+	{ 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
+	{ 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
+	{ 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
+	{ 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
+	{ 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
+	{ 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
+	{ 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
+	{ 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
+	{ 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
+	{ 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
+	{ 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
+	{ 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
+	{ 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
+	{ 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
+	{ 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+	{ 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+	{ 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
+	{ 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
+	{ 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+	{ 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
+	{ 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
+	{ 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
+	{ 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
+	{ 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
+	{ 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
+	{ 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
+	{ 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+	{ 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
+	{ 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
+	{ 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
+	{ 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
+	{ 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
+	{ 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
+	{ 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
+	{ 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+	{ 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
+	{ 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
+	{ 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
+	{ 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
+	{ 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
+	{ 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
+	{ 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
+	{ 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
+	{ 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
+	{ 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+	{ 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
+	{ 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
+	{ 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
+	{ 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
+	{ 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
+	{ 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
+	{ 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
+	{ 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
+	{ 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
+	{ 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
+	{ 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+	{ 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+	{ 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+	{ 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
+	{ 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
+	{ 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
+	{ 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+	{ 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
+	{ 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
+	{ 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
+	{ 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
+	{ 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
+	{ 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
+	{ 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
+	{ 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
+	{ 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
+	{ 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
+	{ 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
+	{ 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
+	{ 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+	{ 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+	{ 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
+	{ 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
+	{ 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
+	{ 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
+	{ 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+	{ 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
+	{ 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+	{ 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
+	{ 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
+	{ 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
+	{ 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
+	{ 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
+	{ 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
+	{ 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
+	{ 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
+	{ 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
+	{ 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
+	{ 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
+	{ 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
+	{ 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+	{ 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+	{ 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+	{ 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
+	{ 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
+	{ 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
+	{ 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+	{ 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
+	{ 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+	{ 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+	{ 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+	{ 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+	{ 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
+	{ 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+	{ 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+	{ 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+	{ 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+	{ 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+	{ 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+	{ 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+	{ 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+	{ 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+	{ 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+/*	{ 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
+	{ 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+	{ 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
+	{ 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
+	{ 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+	{ 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
+	{ 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
+	{ 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
+	{ 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
+	{ 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
+	{ 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
+	{ 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
+	{ 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
+	{ 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
+	{ 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
+	{ 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
+	{ 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
+};
+
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
+{
+	int i, err;
+	u32 val;
+	bool is_2ghz = band == IEEE80211_BAND_2GHZ;
+	bool is_40mhz = false; /* XXX: for now */
+
+	ar9170_regwrite_begin(ar);
+
+	for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+		if (is_40mhz) {
+			if (is_2ghz)
+				val = ar5416_phy_init[i]._2ghz_40;
+			else
+				val = ar5416_phy_init[i]._5ghz_40;
+		} else {
+			if (is_2ghz)
+				val = ar5416_phy_init[i]._2ghz_20;
+			else
+				val = ar5416_phy_init[i]._5ghz_20;
+		}
+
+		ar9170_regwrite(ar5416_phy_init[i].reg, val);
+	}
+
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+	if (err)
+		return err;
+
+	/* XXX: use EEPROM data here! */
+
+	err = ar9170_init_power_cal(ar);
+	if (err)
+		return err;
+
+	/* XXX: remove magic! */
+	if (is_2ghz)
+		err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
+	else
+		err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
+
+	return err;
+}
+
+struct ar9170_rf_init {
+	u32 reg, _5ghz, _2ghz;
+};
+
+static struct ar9170_rf_init ar9170_rf_init[] = {
+     /* bank 0 */
+     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
+     { 0x1c58e0,  0x02008020,  0x02008020},
+     /* bank 1 */
+     { 0x1c58b0,  0x02108421,  0x02108421},
+     { 0x1c58ec,  0x00000008,  0x00000008},
+     /* bank 2 */
+     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
+     { 0x1c58e0,  0x00000420,  0x00000420},
+     /* bank 3 */
+     { 0x1c58f0,  0x01400018,  0x01c00018},
+     /* bank 4 */
+     { 0x1c58b0,  0x000001a1,  0x000001a1},
+     { 0x1c58e8,  0x00000001,  0x00000001},
+     /* bank 5 */
+     { 0x1c58b0,  0x00000013,  0x00000013},
+     { 0x1c58e4,  0x00000002,  0x00000002},
+     /* bank 6 */
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00004800,  0x00004800},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006000,  0x00006000},
+     { 0x1c58b0,  0x00001000,  0x00001000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00087c00,  0x00087c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00005400,  0x00005400},
+     { 0x1c58b0,  0x00000c00,  0x00000c00},
+     { 0x1c58b0,  0x00001800,  0x00001800},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00003c00,  0x00003c00},
+     { 0x1c58b0,  0x00003800,  0x00003800},
+     { 0x1c58b0,  0x00001c00,  0x00001c00},
+     { 0x1c58b0,  0x00000800,  0x00000800},
+     { 0x1c58b0,  0x00000408,  0x00000408},
+     { 0x1c58b0,  0x00004c15,  0x00004c15},
+     { 0x1c58b0,  0x00004188,  0x00004188},
+     { 0x1c58b0,  0x0000201e,  0x0000201e},
+     { 0x1c58b0,  0x00010408,  0x00010408},
+     { 0x1c58b0,  0x00000801,  0x00000801},
+     { 0x1c58b0,  0x00000c08,  0x00000c08},
+     { 0x1c58b0,  0x0000181e,  0x0000181e},
+     { 0x1c58b0,  0x00001016,  0x00001016},
+     { 0x1c58b0,  0x00002800,  0x00002800},
+     { 0x1c58b0,  0x00004010,  0x00004010},
+     { 0x1c58b0,  0x0000081c,  0x0000081c},
+     { 0x1c58b0,  0x00000115,  0x00000115},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x00000066,  0x00000066},
+     { 0x1c58b0,  0x0000001c,  0x0000001c},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000004,  0x00000004},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x0000001f,  0x0000001f},
+     { 0x1c58e0,  0x00000000,  0x00000400},
+     /* bank 7 */
+     { 0x1c58b0,  0x000000a0,  0x000000a0},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000040,  0x00000040},
+     { 0x1c58f0,  0x0000001c,  0x0000001c},
+};
+
+static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+	int err, i;
+
+	ar9170_regwrite_begin(ar);
+
+	for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
+		ar9170_regwrite(ar9170_rf_init[i].reg,
+				band5ghz ? ar9170_rf_init[i]._5ghz
+					 : ar9170_rf_init[i]._2ghz);
+
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+	if (err)
+		printk(KERN_ERR "%s: rf init failed\n",
+		       wiphy_name(ar->hw->wiphy));
+	return err;
+}
+
+static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+				    u32 freq, enum ar9170_bw bw)
+{
+	int err;
+	u32 d0, d1, td0, td1, fd0, fd1;
+	u8 chansel;
+	u8 refsel0 = 1, refsel1 = 0;
+	u8 lf_synth = 0;
+
+	switch (bw) {
+	case AR9170_BW_40_ABOVE:
+		freq += 10;
+		break;
+	case AR9170_BW_40_BELOW:
+		freq -= 10;
+		break;
+	case AR9170_BW_20:
+		break;
+	case __AR9170_NUM_BW:
+		BUG();
+	}
+
+	if (band5ghz) {
+		if (freq % 10) {
+			chansel = (freq - 4800) / 5;
+		} else {
+			chansel = ((freq - 4800) / 10) * 2;
+			refsel0 = 0;
+			refsel1 = 1;
+		}
+		chansel = byte_rev_table[chansel];
+	} else {
+		if (freq == 2484) {
+			chansel = 10 + (freq - 2274) / 5;
+			lf_synth = 1;
+		} else
+			chansel = 16 + (freq - 2272) / 5;
+		chansel *= 4;
+		chansel = byte_rev_table[chansel];
+	}
+
+	d1 =	chansel;
+	d0 =	0x21 |
+		refsel0 << 3 |
+		refsel1 << 2 |
+		lf_synth << 1;
+	td0 =	d0 & 0x1f;
+	td1 =	d1 & 0x1f;
+	fd0 =	td1 << 5 | td0;
+
+	td0 =	(d0 >> 5) & 0x7;
+	td1 =	(d1 >> 5) & 0x7;
+	fd1 =	td1 << 5 | td0;
+
+	ar9170_regwrite_begin(ar);
+
+	ar9170_regwrite(0x1c58b0, fd0);
+	ar9170_regwrite(0x1c58e8, fd1);
+
+	ar9170_regwrite_finish();
+	err = ar9170_regwrite_result();
+	if (err)
+		return err;
+
+	msleep(10);
+
+	return 0;
+}
+
+struct ar9170_phy_freq_params {
+	u8 coeff_exp;
+	u16 coeff_man;
+	u8 coeff_exp_shgi;
+	u16 coeff_man_shgi;
+};
+
+struct ar9170_phy_freq_entry {
+	u16 freq;
+	struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
+/*
+ *	freq,
+ *		20MHz,
+ *		40MHz (below),
+ *		40Mhz (above),
+ */
+	{ 2412, {
+		{ 3, 21737, 3, 19563, },
+		{ 3, 21827, 3, 19644, },
+		{ 3, 21647, 3, 19482, },
+	} },
+	{ 2417, {
+		{ 3, 21692, 3, 19523, },
+		{ 3, 21782, 3, 19604, },
+		{ 3, 21602, 3, 19442, },
+	} },
+	{ 2422, {
+		{ 3, 21647, 3, 19482, },
+		{ 3, 21737, 3, 19563, },
+		{ 3, 21558, 3, 19402, },
+	} },
+	{ 2427, {
+		{ 3, 21602, 3, 19442, },
+		{ 3, 21692, 3, 19523, },
+		{ 3, 21514, 3, 19362, },
+	} },
+	{ 2432, {
+		{ 3, 21558, 3, 19402, },
+		{ 3, 21647, 3, 19482, },
+		{ 3, 21470, 3, 19323, },
+	} },
+	{ 2437, {
+		{ 3, 21514, 3, 19362, },
+		{ 3, 21602, 3, 19442, },
+		{ 3, 21426, 3, 19283, },
+	} },
+	{ 2442, {
+		{ 3, 21470, 3, 19323, },
+		{ 3, 21558, 3, 19402, },
+		{ 3, 21382, 3, 19244, },
+	} },
+	{ 2447, {
+		{ 3, 21426, 3, 19283, },
+		{ 3, 21514, 3, 19362, },
+		{ 3, 21339, 3, 19205, },
+	} },
+	{ 2452, {
+		{ 3, 21382, 3, 19244, },
+		{ 3, 21470, 3, 19323, },
+		{ 3, 21295, 3, 19166, },
+	} },
+	{ 2457, {
+		{ 3, 21339, 3, 19205, },
+		{ 3, 21426, 3, 19283, },
+		{ 3, 21252, 3, 19127, },
+	} },
+	{ 2462, {
+		{ 3, 21295, 3, 19166, },
+		{ 3, 21382, 3, 19244, },
+		{ 3, 21209, 3, 19088, },
+	} },
+	{ 2467, {
+		{ 3, 21252, 3, 19127, },
+		{ 3, 21339, 3, 19205, },
+		{ 3, 21166, 3, 19050, },
+	} },
+	{ 2472, {
+		{ 3, 21209, 3, 19088, },
+		{ 3, 21295, 3, 19166, },
+		{ 3, 21124, 3, 19011, },
+	} },
+	{ 2484, {
+		{ 3, 21107, 3, 18996, },
+		{ 3, 21192, 3, 19073, },
+		{ 3, 21022, 3, 18920, },
+	} },
+	{ 4920, {
+		{ 4, 21313, 4, 19181, },
+		{ 4, 21356, 4, 19220, },
+		{ 4, 21269, 4, 19142, },
+	} },
+	{ 4940, {
+		{ 4, 21226, 4, 19104, },
+		{ 4, 21269, 4, 19142, },
+		{ 4, 21183, 4, 19065, },
+	} },
+	{ 4960, {
+		{ 4, 21141, 4, 19027, },
+		{ 4, 21183, 4, 19065, },
+		{ 4, 21098, 4, 18988, },
+	} },
+	{ 4980, {
+		{ 4, 21056, 4, 18950, },
+		{ 4, 21098, 4, 18988, },
+		{ 4, 21014, 4, 18912, },
+	} },
+	{ 5040, {
+		{ 4, 20805, 4, 18725, },
+		{ 4, 20846, 4, 18762, },
+		{ 4, 20764, 4, 18687, },
+	} },
+	{ 5060, {
+		{ 4, 20723, 4, 18651, },
+		{ 4, 20764, 4, 18687, },
+		{ 4, 20682, 4, 18614, },
+	} },
+	{ 5080, {
+		{ 4, 20641, 4, 18577, },
+		{ 4, 20682, 4, 18614, },
+		{ 4, 20601, 4, 18541, },
+	} },
+	{ 5180, {
+		{ 4, 20243, 4, 18219, },
+		{ 4, 20282, 4, 18254, },
+		{ 4, 20204, 4, 18183, },
+	} },
+	{ 5200, {
+		{ 4, 20165, 4, 18148, },
+		{ 4, 20204, 4, 18183, },
+		{ 4, 20126, 4, 18114, },
+	} },
+	{ 5220, {
+		{ 4, 20088, 4, 18079, },
+		{ 4, 20126, 4, 18114, },
+		{ 4, 20049, 4, 18044, },
+	} },
+	{ 5240, {
+		{ 4, 20011, 4, 18010, },
+		{ 4, 20049, 4, 18044, },
+		{ 4, 19973, 4, 17976, },
+	} },
+	{ 5260, {
+		{ 4, 19935, 4, 17941, },
+		{ 4, 19973, 4, 17976, },
+		{ 4, 19897, 4, 17907, },
+	} },
+	{ 5280, {
+		{ 4, 19859, 4, 17873, },
+		{ 4, 19897, 4, 17907, },
+		{ 4, 19822, 4, 17840, },
+	} },
+	{ 5300, {
+		{ 4, 19784, 4, 17806, },
+		{ 4, 19822, 4, 17840, },
+		{ 4, 19747, 4, 17772, },
+	} },
+	{ 5320, {
+		{ 4, 19710, 4, 17739, },
+		{ 4, 19747, 4, 17772, },
+		{ 4, 19673, 4, 17706, },
+	} },
+	{ 5500, {
+		{ 4, 19065, 4, 17159, },
+		{ 4, 19100, 4, 17190, },
+		{ 4, 19030, 4, 17127, },
+	} },
+	{ 5520, {
+		{ 4, 18996, 4, 17096, },
+		{ 4, 19030, 4, 17127, },
+		{ 4, 18962, 4, 17065, },
+	} },
+	{ 5540, {
+		{ 4, 18927, 4, 17035, },
+		{ 4, 18962, 4, 17065, },
+		{ 4, 18893, 4, 17004, },
+	} },
+	{ 5560, {
+		{ 4, 18859, 4, 16973, },
+		{ 4, 18893, 4, 17004, },
+		{ 4, 18825, 4, 16943, },
+	} },
+	{ 5580, {
+		{ 4, 18792, 4, 16913, },
+		{ 4, 18825, 4, 16943, },
+		{ 4, 18758, 4, 16882, },
+	} },
+	{ 5600, {
+		{ 4, 18725, 4, 16852, },
+		{ 4, 18758, 4, 16882, },
+		{ 4, 18691, 4, 16822, },
+	} },
+	{ 5620, {
+		{ 4, 18658, 4, 16792, },
+		{ 4, 18691, 4, 16822, },
+		{ 4, 18625, 4, 16762, },
+	} },
+	{ 5640, {
+		{ 4, 18592, 4, 16733, },
+		{ 4, 18625, 4, 16762, },
+		{ 4, 18559, 4, 16703, },
+	} },
+	{ 5660, {
+		{ 4, 18526, 4, 16673, },
+		{ 4, 18559, 4, 16703, },
+		{ 4, 18493, 4, 16644, },
+	} },
+	{ 5680, {
+		{ 4, 18461, 4, 16615, },
+		{ 4, 18493, 4, 16644, },
+		{ 4, 18428, 4, 16586, },
+	} },
+	{ 5700, {
+		{ 4, 18396, 4, 16556, },
+		{ 4, 18428, 4, 16586, },
+		{ 4, 18364, 4, 16527, },
+	} },
+	{ 5745, {
+		{ 4, 18252, 4, 16427, },
+		{ 4, 18284, 4, 16455, },
+		{ 4, 18220, 4, 16398, },
+	} },
+	{ 5765, {
+		{ 4, 18189, 5, 32740, },
+		{ 4, 18220, 4, 16398, },
+		{ 4, 18157, 5, 32683, },
+	} },
+	{ 5785, {
+		{ 4, 18126, 5, 32626, },
+		{ 4, 18157, 5, 32683, },
+		{ 4, 18094, 5, 32570, },
+	} },
+	{ 5805, {
+		{ 4, 18063, 5, 32514, },
+		{ 4, 18094, 5, 32570, },
+		{ 4, 18032, 5, 32458, },
+	} },
+	{ 5825, {
+		{ 4, 18001, 5, 32402, },
+		{ 4, 18032, 5, 32458, },
+		{ 4, 17970, 5, 32347, },
+	} },
+	{ 5170, {
+		{ 4, 20282, 4, 18254, },
+		{ 4, 20321, 4, 18289, },
+		{ 4, 20243, 4, 18219, },
+	} },
+	{ 5190, {
+		{ 4, 20204, 4, 18183, },
+		{ 4, 20243, 4, 18219, },
+		{ 4, 20165, 4, 18148, },
+	} },
+	{ 5210, {
+		{ 4, 20126, 4, 18114, },
+		{ 4, 20165, 4, 18148, },
+		{ 4, 20088, 4, 18079, },
+	} },
+	{ 5230, {
+		{ 4, 20049, 4, 18044, },
+		{ 4, 20088, 4, 18079, },
+		{ 4, 20011, 4, 18010, },
+	} },
+};
+
+static const struct ar9170_phy_freq_params *
+ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+			 enum ar9170_bw bw)
+{
+	unsigned int chanidx = 0;
+	u16 freq = 2412;
+
+	if (channel) {
+		chanidx = channel->hw_value;
+		freq = channel->center_freq;
+	}
+
+	BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
+
+	BUILD_BUG_ON(__AR9170_NUM_BW != 3);
+
+	WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
+
+	return &ar9170_phy_freq_params[chanidx].params[bw];
+}
+
+
+int ar9170_init_rf(struct ar9170 *ar)
+{
+	const struct ar9170_phy_freq_params *freqpar;
+	__le32 cmd[7];
+	int err;
+
+	err = ar9170_init_rf_banks_0_7(ar, false);
+	if (err)
+		return err;
+
+	err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
+	if (err)
+		return err;
+
+	freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
+
+	cmd[0] = cpu_to_le32(2412 * 1000);
+	cmd[1] = cpu_to_le32(0);
+	cmd[2] = cpu_to_le32(1);
+	cmd[3] = cpu_to_le32(freqpar->coeff_exp);
+	cmd[4] = cpu_to_le32(freqpar->coeff_man);
+	cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+	cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+
+	/* RF_INIT echoes the command back to us */
+	err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
+			   sizeof(cmd), (u8 *)cmd,
+			   sizeof(cmd), (u8 *)cmd);
+	if (err)
+		return err;
+
+	msleep(1000);
+
+	return ar9170_echo_test(ar, 0xaabbccdd);
+}
+
+static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
+{
+	int idx = nfreqs - 2;
+
+	while (idx >= 0) {
+		if (f >= freqs[idx])
+			return idx;
+		idx--;
+	}
+
+	return 0;
+}
+
+static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
+{
+	/* nothing to interpolate, it's horizontal */
+	if (y2 == y1)
+		return y1;
+
+	/* check if we hit one of the edges */
+	if (x == x1)
+		return y1;
+	if (x == x2)
+		return y2;
+
+	/* x1 == x2 is bad, hopefully == x */
+	if (x2 == x1)
+		return y1;
+
+	return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
+}
+
+static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT		8
+	s32 y;
+
+	y = ar9170_interpolate_s32(x << SHIFT,
+				   x1 << SHIFT, y1 << SHIFT,
+				   x2 << SHIFT, y2 << SHIFT);
+
+	/*
+	 * XXX: unwrap this expression
+	 *	Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
+	 *	Can we rely on the compiler to optimise away the div?
+	 */
+	return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+#undef SHIFT
+}
+
+static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
+{
+	struct ar9170_calibration_target_power_legacy *ctpl;
+	struct ar9170_calibration_target_power_ht *ctph;
+	u8 *ctpres;
+	int ntargets;
+	int idx, i, n;
+	u8 ackpower, ackchains, f;
+	u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
+
+	if (freq < 3000)
+		f = freq - 2300;
+	else
+		f = (freq - 4800)/5;
+
+	/*
+	 * cycle through the various modes
+	 *
+	 * legacy modes first: 5G, 2G CCK, 2G OFDM
+	 */
+	for (i = 0; i < 3; i++) {
+		switch (i) {
+		case 0: /* 5 GHz legacy */
+			ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
+			ntargets = AR5416_NUM_5G_TARGET_PWRS;
+			ctpres = ar->power_5G_leg;
+			break;
+		case 1: /* 2.4 GHz CCK */
+			ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
+			ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
+			ctpres = ar->power_2G_cck;
+			break;
+		case 2: /* 2.4 GHz OFDM */
+			ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
+			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+			ctpres = ar->power_2G_ofdm;
+			break;
+		default:
+			BUG();
+		}
+
+		for (n = 0; n < ntargets; n++) {
+			if (ctpl[n].freq == 0xff)
+				break;
+			pwr_freqs[n] = ctpl[n].freq;
+		}
+		ntargets = n;
+		idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+		for (n = 0; n < 4; n++)
+			ctpres[n] = ar9170_interpolate_u8(
+					f,
+					ctpl[idx + 0].freq,
+					ctpl[idx + 0].power[n],
+					ctpl[idx + 1].freq,
+					ctpl[idx + 1].power[n]);
+	}
+
+	/*
+	 * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
+	 */
+	for (i = 0; i < 4; i++) {
+		switch (i) {
+		case 0: /* 5 GHz HT 20 */
+			ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
+			ntargets = AR5416_NUM_5G_TARGET_PWRS;
+			ctpres = ar->power_5G_ht20;
+			break;
+		case 1: /* 5 GHz HT 40 */
+			ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
+			ntargets = AR5416_NUM_5G_TARGET_PWRS;
+			ctpres = ar->power_5G_ht40;
+			break;
+		case 2: /* 2.4 GHz HT 20 */
+			ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
+			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+			ctpres = ar->power_2G_ht20;
+			break;
+		case 3: /* 2.4 GHz HT 40 */
+			ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
+			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+			ctpres = ar->power_2G_ht40;
+			break;
+		default:
+			BUG();
+		}
+
+		for (n = 0; n < ntargets; n++) {
+			if (ctph[n].freq == 0xff)
+				break;
+			pwr_freqs[n] = ctph[n].freq;
+		}
+		ntargets = n;
+		idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+		for (n = 0; n < 8; n++)
+			ctpres[n] = ar9170_interpolate_u8(
+					f,
+					ctph[idx + 0].freq,
+					ctph[idx + 0].power[n],
+					ctph[idx + 1].freq,
+					ctph[idx + 1].power[n]);
+	}
+
+	/* set ACK/CTS TX power */
+	ar9170_regwrite_begin(ar);
+
+	if (ar->eeprom.tx_mask != 1)
+		ackchains = AR9170_TX_PHY_TXCHAIN_2;
+	else
+		ackchains = AR9170_TX_PHY_TXCHAIN_1;
+
+	if (freq < 3000)
+		ackpower = ar->power_2G_ofdm[0] & 0x3f;
+	else
+		ackpower = ar->power_5G_leg[0] & 0x3f;
+
+	ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
+	ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
+				  ackpower << 21 | ackchains << 27);
+
+	ar9170_regwrite_finish();
+	return ar9170_regwrite_result();
+}
+
+static int ar9170_calc_noise_dbm(u32 raw_noise)
+{
+	if (raw_noise & 0x100)
+		return ~((raw_noise & 0x0ff) >> 1);
+	else
+		return (raw_noise & 0xff) >> 1;
+}
+
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+		       enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
+{
+	const struct ar9170_phy_freq_params *freqpar;
+	u32 cmd, tmp, offs;
+	__le32 vals[8];
+	int i, err;
+	bool bandswitch;
+
+	/* clear BB heavy clip enable */
+	err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
+	if (err)
+		return err;
+
+	/* may be NULL at first setup */
+	if (ar->channel)
+		bandswitch = ar->channel->band != channel->band;
+	else
+		bandswitch = true;
+
+	/* HW workaround */
+	if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+	    channel->center_freq <= 2417)
+		bandswitch = true;
+
+	err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+	if (err)
+		return err;
+
+	if (rfi != AR9170_RFI_NONE || bandswitch) {
+		u32 val = 0x400;
+
+		if (rfi == AR9170_RFI_COLD)
+			val = 0x800;
+
+		/* warm/cold reset BB/ADDA */
+		err = ar9170_write_reg(ar, 0x1d4004, val);
+		if (err)
+			return err;
+
+		err = ar9170_write_reg(ar, 0x1d4004, 0x0);
+		if (err)
+			return err;
+
+		err = ar9170_init_phy(ar, channel->band);
+		if (err)
+			return err;
+
+		err = ar9170_init_rf_banks_0_7(ar,
+			channel->band == IEEE80211_BAND_5GHZ);
+		if (err)
+			return err;
+
+		cmd = AR9170_CMD_RF_INIT;
+	} else {
+		cmd = AR9170_CMD_FREQUENCY;
+	}
+
+	err = ar9170_init_rf_bank4_pwr(ar,
+		channel->band == IEEE80211_BAND_5GHZ,
+		channel->center_freq, bw);
+	if (err)
+		return err;
+
+	switch (bw) {
+	case AR9170_BW_20:
+		tmp = 0x240;
+		offs = 0;
+		break;
+	case AR9170_BW_40_BELOW:
+		tmp = 0x2c4;
+		offs = 3;
+		break;
+	case AR9170_BW_40_ABOVE:
+		tmp = 0x2d4;
+		offs = 1;
+		break;
+	default:
+		BUG();
+		return -ENOSYS;
+	}
+
+	if (0 /* 2 streams capable */)
+		tmp |= 0x100;
+
+	err = ar9170_write_reg(ar, 0x1c5804, tmp);
+	if (err)
+		return err;
+
+	err = ar9170_set_power_cal(ar, channel->center_freq, bw);
+	if (err)
+		return err;
+
+	freqpar = ar9170_get_hw_dyn_params(channel, bw);
+
+	vals[0] = cpu_to_le32(channel->center_freq * 1000);
+	vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
+	vals[2] = cpu_to_le32(offs << 2 | 1);
+	vals[3] = cpu_to_le32(freqpar->coeff_exp);
+	vals[4] = cpu_to_le32(freqpar->coeff_man);
+	vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+	vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+	vals[7] = cpu_to_le32(1000);
+
+	err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
+			   sizeof(vals), (u8 *)vals);
+	if (err)
+		return err;
+
+	for (i = 0; i < 2; i++) {
+		ar->noise[i] = ar9170_calc_noise_dbm(
+				(le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
+
+		ar->noise[i + 2] = ar9170_calc_noise_dbm(
+				    (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
+	}
+
+	ar->channel = channel;
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/usb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,822 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 <linux/module.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "usb.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE("ar9170-1.fw");
+MODULE_FIRMWARE("ar9170-2.fw");
+
+static struct usb_device_id ar9170_usb_ids[] = {
+	/* Atheros 9170 */
+	{ USB_DEVICE(0x0cf3, 0x9170) },
+	/* Atheros TG121N */
+	{ USB_DEVICE(0x0cf3, 0x1001) },
+	/* Cace Airpcap NX */
+	{ USB_DEVICE(0xcace, 0x0300) },
+	/* D-Link DWA 160A */
+	{ USB_DEVICE(0x07d1, 0x3c10) },
+	/* Netgear WNDA3100 */
+	{ USB_DEVICE(0x0846, 0x9010) },
+	/* Netgear WN111 v2 */
+	{ USB_DEVICE(0x0846, 0x9001) },
+	/* Zydas ZD1221 */
+	{ USB_DEVICE(0x0ace, 0x1221) },
+	/* ZyXEL NWD271N */
+	{ USB_DEVICE(0x0586, 0x3417) },
+	/* Z-Com UB81 BG */
+	{ USB_DEVICE(0x0cde, 0x0023) },
+	/* Z-Com UB82 ABG */
+	{ USB_DEVICE(0x0cde, 0x0026) },
+	/* Arcadyan WN7512 */
+	{ USB_DEVICE(0x083a, 0xf522) },
+	/* Planex GWUS300 */
+	{ USB_DEVICE(0x2019, 0x5304) },
+	/* IO-Data WNGDNUS2 */
+	{ USB_DEVICE(0x04bb, 0x093f) },
+
+	/* terminate */
+	{}
+};
+MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
+
+static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct ar9170_usb *aru = (struct ar9170_usb *)
+	      usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+	if (!aru) {
+		dev_kfree_skb_irq(skb);
+		return ;
+	}
+
+	ar9170_handle_tx_status(&aru->common, skb, false,
+				AR9170_TX_STATUS_COMPLETE);
+}
+
+static void ar9170_usb_tx_urb_complete(struct urb *urb)
+{
+}
+
+static void ar9170_usb_irq_completed(struct urb *urb)
+{
+	struct ar9170_usb *aru = urb->context;
+
+	switch (urb->status) {
+	/* everything is fine */
+	case 0:
+		break;
+
+	/* disconnect */
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ENODEV:
+	case -ESHUTDOWN:
+		goto free;
+
+	default:
+		goto resubmit;
+	}
+
+	print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
+			     urb->transfer_buffer, urb->actual_length);
+
+resubmit:
+	usb_anchor_urb(urb, &aru->rx_submitted);
+	if (usb_submit_urb(urb, GFP_ATOMIC)) {
+		usb_unanchor_urb(urb);
+		goto free;
+	}
+
+	return;
+
+free:
+	usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
+}
+
+static void ar9170_usb_rx_completed(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct ar9170_usb *aru = (struct ar9170_usb *)
+		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+	int err;
+
+	if (!aru)
+		goto free;
+
+	switch (urb->status) {
+	/* everything is fine */
+	case 0:
+		break;
+
+	/* disconnect */
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ENODEV:
+	case -ESHUTDOWN:
+		goto free;
+
+	default:
+		goto resubmit;
+	}
+
+	skb_put(skb, urb->actual_length);
+	ar9170_rx(&aru->common, skb);
+
+resubmit:
+	skb_reset_tail_pointer(skb);
+	skb_trim(skb, 0);
+
+	usb_anchor_urb(urb, &aru->rx_submitted);
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err) {
+		usb_unanchor_urb(urb);
+		dev_kfree_skb_irq(skb);
+	}
+
+	return ;
+
+free:
+	dev_kfree_skb_irq(skb);
+	return;
+}
+
+static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
+				  struct urb *urb, gfp_t gfp)
+{
+	struct sk_buff *skb;
+
+	skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
+	if (!skb)
+		return -ENOMEM;
+
+	/* reserve some space for mac80211's radiotap */
+	skb_reserve(skb, 32);
+
+	usb_fill_bulk_urb(urb, aru->udev,
+			  usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
+			  skb->data, min(skb_tailroom(skb),
+			  AR9170_MAX_RX_BUFFER_SIZE),
+			  ar9170_usb_rx_completed, skb);
+
+	return 0;
+}
+
+static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
+{
+	struct urb *urb = NULL;
+	void *ibuf;
+	int err = -ENOMEM;
+
+	/* initialize interrupt endpoint */
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+		goto out;
+
+	ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
+	if (!ibuf)
+		goto out;
+
+	usb_fill_int_urb(urb, aru->udev,
+			 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
+			 64, ar9170_usb_irq_completed, aru, 1);
+	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	usb_anchor_urb(urb, &aru->rx_submitted);
+	err = usb_submit_urb(urb, GFP_KERNEL);
+	if (err) {
+		usb_unanchor_urb(urb);
+		usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
+				urb->transfer_dma);
+	}
+
+out:
+	usb_free_urb(urb);
+	return err;
+}
+
+static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
+{
+	struct urb *urb;
+	int i;
+	int err = -EINVAL;
+
+	for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
+		err = -ENOMEM;
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb)
+			goto err_out;
+
+		err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
+		if (err) {
+			usb_free_urb(urb);
+			goto err_out;
+		}
+
+		usb_anchor_urb(urb, &aru->rx_submitted);
+		err = usb_submit_urb(urb, GFP_KERNEL);
+		if (err) {
+			usb_unanchor_urb(urb);
+			dev_kfree_skb_any((void *) urb->transfer_buffer);
+			usb_free_urb(urb);
+			goto err_out;
+		}
+		usb_free_urb(urb);
+	}
+
+	/* the device now waiting for a firmware. */
+	aru->common.state = AR9170_IDLE;
+	return 0;
+
+err_out:
+
+	usb_kill_anchored_urbs(&aru->rx_submitted);
+	return err;
+}
+
+static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+{
+	int ret;
+
+	aru->common.state = AR9170_UNKNOWN_STATE;
+
+	usb_unlink_anchored_urbs(&aru->tx_submitted);
+
+	/* give the LED OFF command and the deauth frame a chance to air. */
+	ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+					    msecs_to_jiffies(100));
+	if (ret == 0)
+		dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+	usb_poison_anchored_urbs(&aru->tx_submitted);
+
+	usb_poison_anchored_urbs(&aru->rx_submitted);
+}
+
+static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
+			       unsigned int plen, void *payload,
+			       unsigned int outlen, void *out)
+{
+	struct ar9170_usb *aru = (void *) ar;
+	struct urb *urb = NULL;
+	unsigned long flags;
+	int err = -ENOMEM;
+
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return -EPERM;
+
+	if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
+		return -EINVAL;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (unlikely(!urb))
+		goto err_free;
+
+	ar->cmdbuf[0] = cpu_to_le32(plen);
+	ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
+	/* writing multiple regs fills this buffer already */
+	if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
+		memcpy(&ar->cmdbuf[1], payload, plen);
+
+	spin_lock_irqsave(&aru->common.cmdlock, flags);
+	aru->readbuf = (u8 *)out;
+	aru->readlen = outlen;
+	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+	usb_fill_int_urb(urb, aru->udev,
+			 usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+			 aru->common.cmdbuf, plen + 4,
+			 ar9170_usb_tx_urb_complete, NULL, 1);
+
+	usb_anchor_urb(urb, &aru->tx_submitted);
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err) {
+		usb_unanchor_urb(urb);
+		usb_free_urb(urb);
+		goto err_unbuf;
+	}
+	usb_free_urb(urb);
+
+	err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
+	if (err == 0) {
+		err = -ETIMEDOUT;
+		goto err_unbuf;
+	}
+
+	if (outlen >= 0 && aru->readlen != outlen) {
+		err = -EMSGSIZE;
+		goto err_unbuf;
+	}
+
+	return 0;
+
+err_unbuf:
+	/* Maybe the device was removed in the second we were waiting? */
+	if (IS_STARTED(ar)) {
+		dev_err(&aru->udev->dev, "no command feedback "
+					 "received (%d).\n", err);
+
+		/* provide some maybe useful debug information */
+		print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
+				     aru->common.cmdbuf, plen + 4);
+		dump_stack();
+	}
+
+	/* invalidate to avoid completing the next prematurely */
+	spin_lock_irqsave(&aru->common.cmdlock, flags);
+	aru->readbuf = NULL;
+	aru->readlen = 0;
+	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+err_free:
+
+	return err;
+}
+
+static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
+			 bool txstatus_needed, unsigned int extra_len)
+{
+	struct ar9170_usb *aru = (struct ar9170_usb *) ar;
+	struct urb *urb;
+	int err;
+
+	if (unlikely(!IS_STARTED(ar))) {
+		/* Seriously, what were you drink... err... thinking!? */
+		return -EPERM;
+	}
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (unlikely(!urb))
+		return -ENOMEM;
+
+	usb_fill_bulk_urb(urb, aru->udev,
+			  usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
+			  skb->data, skb->len + extra_len, (txstatus_needed ?
+			  ar9170_usb_tx_urb_complete :
+			  ar9170_usb_tx_urb_complete_free), skb);
+	urb->transfer_flags |= URB_ZERO_PACKET;
+
+	usb_anchor_urb(urb, &aru->tx_submitted);
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (unlikely(err))
+		usb_unanchor_urb(urb);
+
+	usb_free_urb(urb);
+	return err;
+}
+
+static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
+{
+	struct ar9170_usb *aru = (void *) ar;
+	unsigned long flags;
+	u32 in, out;
+
+	if (!buffer)
+		return ;
+
+	in = le32_to_cpup((__le32 *)buffer);
+	out = le32_to_cpu(ar->cmdbuf[0]);
+
+	/* mask off length byte */
+	out &= ~0xFF;
+
+	if (aru->readlen >= 0) {
+		/* add expected length */
+		out |= aru->readlen;
+	} else {
+		/* add obtained length */
+		out |= in & 0xFF;
+	}
+
+	/*
+	 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
+	 * length and we cannot predict the correct length in advance.
+	 * So we only check if we provided enough space for the data.
+	 */
+	if (unlikely(out < in)) {
+		dev_warn(&aru->udev->dev, "received invalid command response "
+					  "got %d bytes, instead of %d bytes "
+					  "and the resp length is %d bytes\n",
+			 in, out, len);
+		print_hex_dump_bytes("ar9170 invalid resp: ",
+				     DUMP_PREFIX_OFFSET, buffer, len);
+		/*
+		 * Do not complete, then the command times out,
+		 * and we get a stack trace from there.
+		 */
+		return ;
+	}
+
+	spin_lock_irqsave(&aru->common.cmdlock, flags);
+	if (aru->readbuf && len > 0) {
+		memcpy(aru->readbuf, buffer + 4, len - 4);
+		aru->readbuf = NULL;
+	}
+	complete(&aru->cmd_wait);
+	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+}
+
+static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
+			     size_t len, u32 addr, bool complete)
+{
+	int transfer, err;
+	u8 *buf = kmalloc(4096, GFP_KERNEL);
+
+	if (!buf)
+		return -ENOMEM;
+
+	while (len) {
+		transfer = min_t(int, len, 4096);
+		memcpy(buf, data, transfer);
+
+		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+				      0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+				      addr >> 8, 0, buf, transfer, 1000);
+
+		if (err < 0) {
+			kfree(buf);
+			return err;
+		}
+
+		len -= transfer;
+		data += transfer;
+		addr += transfer;
+	}
+	kfree(buf);
+
+	if (complete) {
+		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+				      0x31 /* FW DL COMPLETE */,
+				      0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
+	}
+
+	return 0;
+}
+
+static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
+{
+	int err = 0;
+
+	err = request_firmware(&aru->init_values, "ar9170-1.fw",
+			       &aru->udev->dev);
+	if (err) {
+		dev_err(&aru->udev->dev, "file with init values not found.\n");
+		return err;
+	}
+
+	err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
+	if (err) {
+		release_firmware(aru->init_values);
+		dev_err(&aru->udev->dev, "firmware file not found.\n");
+		return err;
+	}
+
+	return err;
+}
+
+static int ar9170_usb_reset(struct ar9170_usb *aru)
+{
+	int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
+
+	if (lock) {
+		ret = usb_lock_device_for_reset(aru->udev, aru->intf);
+		if (ret < 0) {
+			dev_err(&aru->udev->dev, "unable to lock device "
+				"for reset (%d).\n", ret);
+			return ret;
+		}
+	}
+
+	ret = usb_reset_device(aru->udev);
+	if (lock)
+		usb_unlock_device(aru->udev);
+
+	/* let it rest - for a second - */
+	msleep(1000);
+
+	return ret;
+}
+
+static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
+{
+	int err;
+
+	/* First, upload initial values to device RAM */
+	err = ar9170_usb_upload(aru, aru->init_values->data,
+				aru->init_values->size, 0x102800, false);
+	if (err) {
+		dev_err(&aru->udev->dev, "firmware part 1 "
+			"upload failed (%d).\n", err);
+		return err;
+	}
+
+	/* Then, upload the firmware itself and start it */
+	return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
+				0x200000, true);
+}
+
+static int ar9170_usb_init_transport(struct ar9170_usb *aru)
+{
+	struct ar9170 *ar = (void *) &aru->common;
+	int err;
+
+	ar9170_regwrite_begin(ar);
+
+	/* Set USB Rx stream mode MAX packet number to 2 */
+	ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
+
+	/* Set USB Rx stream mode timeout to 10us */
+	ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
+
+	ar9170_regwrite_finish();
+
+	err = ar9170_regwrite_result();
+	if (err)
+		dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
+
+	return err;
+}
+
+static void ar9170_usb_stop(struct ar9170 *ar)
+{
+	struct ar9170_usb *aru = (void *) ar;
+	int ret;
+
+	if (IS_ACCEPTING_CMD(ar))
+		aru->common.state = AR9170_STOPPED;
+
+	/* lets wait a while until the tx - queues are dried out */
+	ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+					    msecs_to_jiffies(1000));
+	if (ret == 0)
+		dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+
+	usb_poison_anchored_urbs(&aru->tx_submitted);
+
+	/*
+	 * Note:
+	 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
+	 * Else we would end up with a unresponsive device...
+	 */
+}
+
+static int ar9170_usb_open(struct ar9170 *ar)
+{
+	struct ar9170_usb *aru = (void *) ar;
+	int err;
+
+	usb_unpoison_anchored_urbs(&aru->tx_submitted);
+	err = ar9170_usb_init_transport(aru);
+	if (err) {
+		usb_poison_anchored_urbs(&aru->tx_submitted);
+		return err;
+	}
+
+	aru->common.state = AR9170_IDLE;
+	return 0;
+}
+
+static int ar9170_usb_init_device(struct ar9170_usb *aru)
+{
+	int err;
+
+	err = ar9170_usb_alloc_rx_irq_urb(aru);
+	if (err)
+		goto err_out;
+
+	err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_usb_upload_firmware(aru);
+	if (err) {
+		err = ar9170_echo_test(&aru->common, 0x60d43110);
+		if (err) {
+			/* force user invention, by disabling the device */
+			err = usb_driver_set_configuration(aru->udev, -1);
+			dev_err(&aru->udev->dev, "device is in a bad state. "
+						 "please reconnect it!\n");
+			goto err_unrx;
+		}
+	}
+
+	return 0;
+
+err_unrx:
+	ar9170_usb_cancel_urbs(aru);
+
+err_out:
+	return err;
+}
+
+static int ar9170_usb_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	struct ar9170_usb *aru;
+	struct ar9170 *ar;
+	struct usb_device *udev;
+	int err;
+
+	aru = ar9170_alloc(sizeof(*aru));
+	if (IS_ERR(aru)) {
+		err = PTR_ERR(aru);
+		goto out;
+	}
+
+	udev = interface_to_usbdev(intf);
+	usb_get_dev(udev);
+	aru->udev = udev;
+	aru->intf = intf;
+	ar = &aru->common;
+
+	usb_set_intfdata(intf, aru);
+	SET_IEEE80211_DEV(ar->hw, &udev->dev);
+
+	init_usb_anchor(&aru->rx_submitted);
+	init_usb_anchor(&aru->tx_submitted);
+	init_completion(&aru->cmd_wait);
+
+	aru->common.stop = ar9170_usb_stop;
+	aru->common.open = ar9170_usb_open;
+	aru->common.tx = ar9170_usb_tx;
+	aru->common.exec_cmd = ar9170_usb_exec_cmd;
+	aru->common.callback_cmd = ar9170_usb_callback_cmd;
+
+	err = ar9170_usb_reset(aru);
+	if (err)
+		goto err_freehw;
+
+	err = ar9170_usb_request_firmware(aru);
+	if (err)
+		goto err_freehw;
+
+	err = ar9170_usb_init_device(aru);
+	if (err)
+		goto err_freefw;
+
+	err = ar9170_usb_open(ar);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_register(ar, &udev->dev);
+
+	ar9170_usb_stop(ar);
+	if (err)
+		goto err_unrx;
+
+	return 0;
+
+err_unrx:
+	ar9170_usb_cancel_urbs(aru);
+
+err_freefw:
+	release_firmware(aru->init_values);
+	release_firmware(aru->firmware);
+
+err_freehw:
+	usb_set_intfdata(intf, NULL);
+	usb_put_dev(udev);
+	ieee80211_free_hw(ar->hw);
+out:
+	return err;
+}
+
+static void ar9170_usb_disconnect(struct usb_interface *intf)
+{
+	struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+	if (!aru)
+		return;
+
+	aru->common.state = AR9170_IDLE;
+	ar9170_unregister(&aru->common);
+	ar9170_usb_cancel_urbs(aru);
+
+	release_firmware(aru->init_values);
+	release_firmware(aru->firmware);
+
+	usb_put_dev(aru->udev);
+	usb_set_intfdata(intf, NULL);
+	ieee80211_free_hw(aru->common.hw);
+}
+
+#ifdef CONFIG_PM
+static int ar9170_suspend(struct usb_interface *intf,
+			  pm_message_t  message)
+{
+	struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+	if (!aru)
+		return -ENODEV;
+
+	aru->common.state = AR9170_IDLE;
+	ar9170_usb_cancel_urbs(aru);
+
+	return 0;
+}
+
+static int ar9170_resume(struct usb_interface *intf)
+{
+	struct ar9170_usb *aru = usb_get_intfdata(intf);
+	int err;
+
+	if (!aru)
+		return -ENODEV;
+
+	usb_unpoison_anchored_urbs(&aru->rx_submitted);
+	usb_unpoison_anchored_urbs(&aru->tx_submitted);
+
+	/*
+	 * FIXME: firmware upload will fail on resume.
+	 * but this is better than a hang!
+	 */
+
+	err = ar9170_usb_init_device(aru);
+	if (err)
+		goto err_unrx;
+
+	err = ar9170_usb_open(&aru->common);
+	if (err)
+		goto err_unrx;
+
+	return 0;
+
+err_unrx:
+	aru->common.state = AR9170_IDLE;
+	ar9170_usb_cancel_urbs(aru);
+
+	return err;
+}
+#endif /* CONFIG_PM */
+
+static struct usb_driver ar9170_driver = {
+	.name = "ar9170usb",
+	.probe = ar9170_usb_probe,
+	.disconnect = ar9170_usb_disconnect,
+	.id_table = ar9170_usb_ids,
+	.soft_unbind = 1,
+#ifdef CONFIG_PM
+	.suspend = ar9170_suspend,
+	.resume = ar9170_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init ar9170_init(void)
+{
+	return usb_register(&ar9170_driver);
+}
+
+static void __exit ar9170_exit(void)
+{
+	usb_deregister(&ar9170_driver);
+}
+
+module_init(ar9170_init);
+module_exit(ar9170_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ar9170/usb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * Atheros AR9170 USB driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __USB_H
+#define __USB_H
+
+#include <linux/usb.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/leds.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#include <linux/firmware.h>
+#include "eeprom.h"
+#include "hw.h"
+#include "ar9170.h"
+
+#define AR9170_NUM_RX_URBS			16
+
+struct firmware;
+
+struct ar9170_usb {
+	struct ar9170 common;
+	struct usb_device *udev;
+	struct usb_interface *intf;
+
+	struct usb_anchor rx_submitted;
+	struct usb_anchor tx_submitted;
+
+	spinlock_t cmdlock;
+	struct completion cmd_wait;
+	int readlen;
+	u8 *readbuf;
+
+	const struct firmware *init_values;
+	const struct firmware *firmware;
+};
+
+#endif /* __USB_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/arlan-main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/arlan-main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/arlan-main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/arlan-main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1030,7 +1030,17 @@ static int arlan_mac_addr(struct net_dev
 	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)
 {
@@ -1042,14 +1052,7 @@ static int __init arlan_setup_device(str
 	ap->conf = (struct arlan_shmem *)(ap+1);
 
 	dev->tx_queue_len = tx_queue_len;
-	dev->open = arlan_open;
-	dev->stop = arlan_close;
-	dev->hard_start_xmit = arlan_tx;
-	dev->get_stats = arlan_statistics;
-	dev->set_multicast_list = arlan_set_multicast;
-	dev->change_mtu = arlan_change_mtu;
-	dev->set_mac_address = arlan_mac_addr;
-	dev->tx_timeout = arlan_tx_timeout;
+	dev->netdev_ops = &arlan_netdev_ops;
 	dev->watchdog_timeo = 3*HZ;
 	
 	ap->irq_test_done = 0;
@@ -1082,8 +1085,8 @@ static int __init arlan_probe_here(struc
 	if (arlan_check_fingerprint(memaddr))
 		return -ENODEV;
 
-	printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, 
-	       (int) virt_to_phys((void*)memaddr));
+	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;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/at76c50x-usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/at76c50x-usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/at76c50x-usb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/at76c50x-usb.c	2013-05-03 16:47:52.000000000 -0400
@@ -0,0 +1,2503 @@
+/*
+ * at76c503/at76c505 USB driver
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth
+ * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
+ * Copyright (c) 2004 Nick Jones
+ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
+ * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
+ * Copyright (c) 2007 Kalle Valo <kalle.valo@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 file is part of the Berlios driver for WLAN USB devices based on the
+ * Atmel AT76C503A/505/505A.
+ *
+ * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
+ *
+ * TODO list is at the wiki:
+ *
+ * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/firmware.h>
+#include <linux/leds.h>
+#include <net/mac80211.h>
+
+#include "at76c50x-usb.h"
+
+/* Version information */
+#define DRIVER_NAME "at76c50x-usb"
+#define DRIVER_VERSION	"0.17"
+#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
+
+/* at76_debug bits */
+#define DBG_PROGRESS		0x00000001	/* authentication/accociation */
+#define DBG_BSS_TABLE		0x00000002	/* show BSS table after scans */
+#define DBG_IOCTL		0x00000004	/* ioctl calls / settings */
+#define DBG_MAC_STATE		0x00000008	/* MAC state transitions */
+#define DBG_TX_DATA		0x00000010	/* tx header */
+#define DBG_TX_DATA_CONTENT	0x00000020	/* tx content */
+#define DBG_TX_MGMT		0x00000040	/* tx management */
+#define DBG_RX_DATA		0x00000080	/* rx data header */
+#define DBG_RX_DATA_CONTENT	0x00000100	/* rx data content */
+#define DBG_RX_MGMT		0x00000200	/* rx mgmt frame headers */
+#define DBG_RX_BEACON		0x00000400	/* rx beacon */
+#define DBG_RX_CTRL		0x00000800	/* rx control */
+#define DBG_RX_MGMT_CONTENT	0x00001000	/* rx mgmt content */
+#define DBG_RX_FRAGS		0x00002000	/* rx data fragment handling */
+#define DBG_DEVSTART		0x00004000	/* fw download, device start */
+#define DBG_URB			0x00008000	/* rx urb status, ... */
+#define DBG_RX_ATMEL_HDR	0x00010000	/* Atmel-specific Rx headers */
+#define DBG_PROC_ENTRY		0x00020000	/* procedure entries/exits */
+#define DBG_PM			0x00040000	/* power management settings */
+#define DBG_BSS_MATCH		0x00080000	/* BSS match failures */
+#define DBG_PARAMS		0x00100000	/* show configured parameters */
+#define DBG_WAIT_COMPLETE	0x00200000	/* command completion */
+#define DBG_RX_FRAGS_SKB	0x00400000	/* skb header of Rx fragments */
+#define DBG_BSS_TABLE_RM	0x00800000	/* purging bss table entries */
+#define DBG_MONITOR_MODE	0x01000000	/* monitor mode */
+#define DBG_MIB			0x02000000	/* dump all MIBs on startup */
+#define DBG_MGMT_TIMER		0x04000000	/* dump mgmt_timer ops */
+#define DBG_WE_EVENTS		0x08000000	/* dump wireless events */
+#define DBG_FW			0x10000000	/* firmware download */
+#define DBG_DFU			0x20000000	/* device firmware upgrade */
+#define DBG_CMD			0x40000000
+#define DBG_MAC80211		0x80000000
+
+#define DBG_DEFAULTS		0
+
+/* Use our own dbg macro */
+#define at76_dbg(bits, format, arg...) \
+	do { \
+		if (at76_debug & (bits))				 \
+			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+			       ## arg);					 \
+	} while (0)
+
+#define at76_dbg_dump(bits, buf, len, format, arg...)	\
+	do { \
+		if (at76_debug & (bits)) { \
+			printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+			       ## arg);					 \
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,     \
+					     buf, len);			 \
+		}							 \
+	} while (0)
+
+static uint at76_debug = DBG_DEFAULTS;
+
+/* Protect against concurrent firmware loading and parsing */
+static struct mutex fw_mutex;
+
+static struct fwentry firmwares[] = {
+	[0] = { "" },
+	[BOARD_503_ISL3861] = { "/*(DEBLOBBED)*/" },
+	[BOARD_503_ISL3863] = { "/*(DEBLOBBED)*/" },
+	[BOARD_503] = { "/*(DEBLOBBED)*/" },
+	[BOARD_503_ACC] = { "/*(DEBLOBBED)*/" },
+	[BOARD_505] = { "/*(DEBLOBBED)*/" },
+	[BOARD_505_2958] = { "/*(DEBLOBBED)*/" },
+	[BOARD_505A] = { "/*(DEBLOBBED)*/" },
+	[BOARD_505AMX] = { "/*(DEBLOBBED)*/" },
+};
+
+#define USB_DEVICE_DATA(__ops)	.driver_info = (kernel_ulong_t)(__ops)
+
+static struct usb_device_id dev_table[] = {
+	/*
+	 * at76c503-i3861
+	 */
+	/* Generic AT76C503/3861 device */
+	{ USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Linksys WUSB11 v2.1/v2.6 */
+	{ USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Netgear MA101 rev. A */
+	{ USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Tekram U300C / Allnet ALL0193 */
+	{ USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* HP HN210W J7801A */
+	{ USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Sitecom/Z-Com/Zyxel M4Y-750 */
+	{ USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Dynalink/Askey WLL013 (intersil) */
+	{ USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
+	{ USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* BenQ AWL300 */
+	{ USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Addtron AWU-120, Compex WLU11 */
+	{ USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Intel AP310 AnyPoint II USB */
+	{ USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Dynalink L11U */
+	{ USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* Arescom WL-210, FCC id 07J-GL2411USB */
+	{ USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* I-O DATA WN-B11/USB */
+	{ USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/* BT Voyager 1010 */
+	{ USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+	/*
+	 * at76c503-i3863
+	 */
+	/* Generic AT76C503/3863 device */
+	{ USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+	/* Samsung SWL-2100U */
+	{ USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+	/*
+	 * at76c503-rfmd
+	 */
+	/* Generic AT76C503/RFMD device */
+	{ USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+	/* Dynalink/Askey WLL013 (rfmd) */
+	{ USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+	/* Linksys WUSB11 v2.6 */
+	{ USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+	/* Network Everywhere NWU11B */
+	{ USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+	/* Netgear MA101 rev. B */
+	{ USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+	/* D-Link DWL-120 rev. E */
+	{ USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+	/* Actiontec 802UAT1, HWU01150-01UK */
+	{ USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+	/* AirVast W-Buddie WN210 */
+	{ USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+	/* Dick Smith Electronics XH1153 802.11b USB adapter */
+	{ USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+	/* CNet CNUSB611 */
+	{ USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+	/* FiberLine FL-WL200U */
+	{ USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+	/* BenQ AWL400 USB stick */
+	{ USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+	/* 3Com 3CRSHEW696 */
+	{ USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+	/* Siemens Santis ADSL WLAN USB adapter WLL 013 */
+	{ USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+	/* Belkin F5D6050, version 2 */
+	{ USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+	/* iBlitzz, BWU613 (not *B or *SB) */
+	{ USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+	/* Gigabyte GN-WLBM101 */
+	{ USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+	/* Planex GW-US11S */
+	{ USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+	/* Internal WLAN adapter in h5[4,5]xx series iPAQs */
+	{ USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+	/* Corega Wireless LAN USB-11 mini */
+	{ USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+	/* Corega Wireless LAN USB-11 mini2 */
+	{ USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+	/* Uniden PCW100 */
+	{ USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+	/*
+	 * at76c503-rfmd-acc
+	 */
+	/* SMC2664W */
+	{ USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+	/* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
+	{ USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+	/*
+	 * at76c505-rfmd
+	 */
+	/* Generic AT76C505/RFMD */
+	{ USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+	/*
+	 * at76c505-rfmd2958
+	 */
+	/* Generic AT76C505/RFMD, OvisLink WL-1130USB */
+	{ USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* Fiberline FL-WL240U */
+	{ USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* CNet CNUSB-611G */
+	{ USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* Linksys WUSB11 v2.8 */
+	{ USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
+	{ USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* Corega WLAN USB Stick 11 */
+	{ USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+	/* Microstar MSI Box MS6978 */
+	{ USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+	/*
+	 * at76c505a-rfmd2958
+	 */
+	/* Generic AT76C505A device */
+	{ USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+	/* Generic AT76C505AS device */
+	{ USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+	/* Siemens Gigaset USB WLAN Adapter 11 */
+	{ USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+	/* OQO Model 01+ Internal Wi-Fi */
+	{ USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) },
+	/*
+	 * at76c505amx-rfmd
+	 */
+	/* Generic AT76C505AMX device */
+	{ USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, dev_table);
+
+/* Supported rates of this hardware, bit 7 marks basic rates */
+static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+
+static const char *const preambles[] = { "long", "short", "auto" };
+
+/* Firmware download */
+/* DFU states */
+#define STATE_IDLE			0x00
+#define STATE_DETACH			0x01
+#define STATE_DFU_IDLE			0x02
+#define STATE_DFU_DOWNLOAD_SYNC		0x03
+#define STATE_DFU_DOWNLOAD_BUSY		0x04
+#define STATE_DFU_DOWNLOAD_IDLE		0x05
+#define STATE_DFU_MANIFEST_SYNC		0x06
+#define STATE_DFU_MANIFEST		0x07
+#define STATE_DFU_MANIFEST_WAIT_RESET	0x08
+#define STATE_DFU_UPLOAD_IDLE		0x09
+#define STATE_DFU_ERROR			0x0a
+
+/* DFU commands */
+#define DFU_DETACH			0
+#define DFU_DNLOAD			1
+#define DFU_UPLOAD			2
+#define DFU_GETSTATUS			3
+#define DFU_CLRSTATUS			4
+#define DFU_GETSTATE			5
+#define DFU_ABORT			6
+
+#define FW_BLOCK_SIZE 1024
+
+struct dfu_status {
+	unsigned char status;
+	unsigned char poll_timeout[3];
+	unsigned char state;
+	unsigned char string;
+} __attribute__((packed));
+
+static inline int at76_is_intersil(enum board_type board)
+{
+	return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
+}
+
+static inline int at76_is_503rfmd(enum board_type board)
+{
+	return (board == BOARD_503 || board == BOARD_503_ACC);
+}
+
+static inline int at76_is_505a(enum board_type board)
+{
+	return (board == BOARD_505A || board == BOARD_505AMX);
+}
+
+/* Load a block of the first (internal) part of the firmware */
+static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
+				  void *block, int size)
+{
+	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
+			       USB_TYPE_CLASS | USB_DIR_OUT |
+			       USB_RECIP_INTERFACE, blockno, 0, block, size,
+			       USB_CTRL_GET_TIMEOUT);
+}
+
+static int at76_dfu_get_status(struct usb_device *udev,
+			       struct dfu_status *status)
+{
+	int ret;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
+			      USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+			      0, 0, status, sizeof(struct dfu_status),
+			      USB_CTRL_GET_TIMEOUT);
+	return ret;
+}
+
+static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
+{
+	int ret;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
+			      USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+			      0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
+	return ret;
+}
+
+/* Convert timeout from the DFU status to jiffies */
+static inline unsigned long at76_get_timeout(struct dfu_status *s)
+{
+	return msecs_to_jiffies((s->poll_timeout[2] << 16)
+				| (s->poll_timeout[1] << 8)
+				| (s->poll_timeout[0]));
+}
+
+/* Load internal firmware from the buffer.  If manifest_sync_timeout > 0, use
+ * its value in jiffies in the MANIFEST_SYNC state.  */
+static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
+				int manifest_sync_timeout)
+{
+	u8 *block;
+	struct dfu_status dfu_stat_buf;
+	int ret = 0;
+	int need_dfu_state = 1;
+	int is_done = 0;
+	u8 dfu_state = 0;
+	u32 dfu_timeout = 0;
+	int bsize = 0;
+	int blockno = 0;
+
+	at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
+		 manifest_sync_timeout);
+
+	if (!size) {
+		dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
+		return -EINVAL;
+	}
+
+	block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+	if (!block)
+		return -ENOMEM;
+
+	do {
+		if (need_dfu_state) {
+			ret = at76_dfu_get_state(udev, &dfu_state);
+			if (ret < 0) {
+				dev_printk(KERN_ERR, &udev->dev,
+					   "cannot get DFU state: %d\n", ret);
+				goto exit;
+			}
+			need_dfu_state = 0;
+		}
+
+		switch (dfu_state) {
+		case STATE_DFU_DOWNLOAD_SYNC:
+			at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
+			ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+			if (ret >= 0) {
+				dfu_state = dfu_stat_buf.state;
+				dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+				need_dfu_state = 0;
+			} else
+				dev_printk(KERN_ERR, &udev->dev,
+					   "at76_dfu_get_status returned %d\n",
+					   ret);
+			break;
+
+		case STATE_DFU_DOWNLOAD_BUSY:
+			at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
+			need_dfu_state = 1;
+
+			at76_dbg(DBG_DFU, "DFU: Resetting device");
+			schedule_timeout_interruptible(dfu_timeout);
+			break;
+
+		case STATE_DFU_DOWNLOAD_IDLE:
+			at76_dbg(DBG_DFU, "DOWNLOAD...");
+			/* fall through */
+		case STATE_DFU_IDLE:
+			at76_dbg(DBG_DFU, "DFU IDLE");
+
+			bsize = min_t(int, size, FW_BLOCK_SIZE);
+			memcpy(block, buf, bsize);
+			at76_dbg(DBG_DFU, "int fw, size left = %5d, "
+				 "bsize = %4d, blockno = %2d", size, bsize,
+				 blockno);
+			ret =
+			    at76_load_int_fw_block(udev, blockno, block, bsize);
+			buf += bsize;
+			size -= bsize;
+			blockno++;
+
+			if (ret != bsize)
+				dev_printk(KERN_ERR, &udev->dev,
+					   "at76_load_int_fw_block "
+					   "returned %d\n", ret);
+			need_dfu_state = 1;
+			break;
+
+		case STATE_DFU_MANIFEST_SYNC:
+			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
+
+			ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+			if (ret < 0)
+				break;
+
+			dfu_state = dfu_stat_buf.state;
+			dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+			need_dfu_state = 0;
+
+			/* override the timeout from the status response,
+			   needed for AT76C505A */
+			if (manifest_sync_timeout > 0)
+				dfu_timeout = manifest_sync_timeout;
+
+			at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
+			schedule_timeout_interruptible(dfu_timeout);
+			break;
+
+		case STATE_DFU_MANIFEST:
+			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
+			is_done = 1;
+			break;
+
+		case STATE_DFU_MANIFEST_WAIT_RESET:
+			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
+			is_done = 1;
+			break;
+
+		case STATE_DFU_UPLOAD_IDLE:
+			at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
+			break;
+
+		case STATE_DFU_ERROR:
+			at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
+			ret = -EPIPE;
+			break;
+
+		default:
+			at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
+			ret = -EINVAL;
+			break;
+		}
+	} while (!is_done && (ret >= 0));
+
+exit:
+	kfree(block);
+	if (ret >= 0)
+		ret = 0;
+
+	return ret;
+}
+
+#define HEX2STR_BUFFERS 4
+#define HEX2STR_MAX_LEN 64
+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
+
+/* Convert binary data into hex string */
+static char *hex2str(void *buf, int len)
+{
+	static atomic_t a = ATOMIC_INIT(0);
+	static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
+	char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
+	char *obuf = ret;
+	u8 *ibuf = buf;
+
+	if (len > HEX2STR_MAX_LEN)
+		len = HEX2STR_MAX_LEN;
+
+	if (len <= 0) {
+		ret[0] = '\0';
+		return ret;
+	}
+
+	while (len--) {
+		*obuf++ = BIN2HEX(*ibuf >> 4);
+		*obuf++ = BIN2HEX(*ibuf & 0xf);
+		*obuf++ = '-';
+		ibuf++;
+	}
+	*(--obuf) = '\0';
+
+	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);
+static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
+DEFINE_LED_TRIGGER(ledtrig_tx);
+
+static void at76_ledtrig_tx_timerfunc(unsigned long data)
+{
+	static int tx_lastactivity;
+
+	if (tx_lastactivity != tx_activity) {
+		tx_lastactivity = tx_activity;
+		led_trigger_event(ledtrig_tx, LED_FULL);
+		mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+	} else
+		led_trigger_event(ledtrig_tx, LED_OFF);
+}
+
+static void at76_ledtrig_tx_activity(void)
+{
+	tx_activity++;
+	if (!timer_pending(&ledtrig_tx_timer))
+		mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+}
+
+static int at76_remap(struct usb_device *udev)
+{
+	int ret;
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
+			      USB_TYPE_VENDOR | USB_DIR_OUT |
+			      USB_RECIP_INTERFACE, 0, 0, NULL, 0,
+			      USB_CTRL_GET_TIMEOUT);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int at76_get_op_mode(struct usb_device *udev)
+{
+	int ret;
+	u8 saved;
+	u8 *op_mode;
+
+	op_mode = kmalloc(1, GFP_NOIO);
+	if (!op_mode)
+		return -ENOMEM;
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+			      USB_TYPE_VENDOR | USB_DIR_IN |
+			      USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
+			      USB_CTRL_GET_TIMEOUT);
+	saved = *op_mode;
+	kfree(op_mode);
+
+	if (ret < 0)
+		return ret;
+	else if (ret < 1)
+		return -EIO;
+	else
+		return saved;
+}
+
+/* Load a block of the second ("external") part of the firmware */
+static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
+					 void *block, int size)
+{
+	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+			       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+			       0x0802, blockno, block, size,
+			       USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int at76_get_hw_cfg(struct usb_device *udev,
+				  union at76_hwcfg *buf, int buf_size)
+{
+	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+			       USB_TYPE_VENDOR | USB_DIR_IN |
+			       USB_RECIP_INTERFACE, 0x0a02, 0,
+			       buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Intersil boards use a different "value" for GetHWConfig requests */
+static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
+					   union at76_hwcfg *buf, int buf_size)
+{
+	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+			       USB_TYPE_VENDOR | USB_DIR_IN |
+			       USB_RECIP_INTERFACE, 0x0902, 0,
+			       buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Get the hardware configuration for the adapter and put it to the appropriate
+ * fields of 'priv' (the GetHWConfig request and interpretation of the result
+ * depends on the board type) */
+static int at76_get_hw_config(struct at76_priv *priv)
+{
+	int ret;
+	union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
+
+	if (!hwcfg)
+		return -ENOMEM;
+
+	if (at76_is_intersil(priv->board_type)) {
+		ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
+					       sizeof(hwcfg->i));
+		if (ret < 0)
+			goto exit;
+		memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
+		priv->regulatory_domain = hwcfg->i.regulatory_domain;
+	} else if (at76_is_503rfmd(priv->board_type)) {
+		ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
+		if (ret < 0)
+			goto exit;
+		memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
+		priv->regulatory_domain = hwcfg->r3.regulatory_domain;
+	} else {
+		ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
+		if (ret < 0)
+			goto exit;
+		memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
+		priv->regulatory_domain = hwcfg->r5.regulatory_domain;
+	}
+
+exit:
+	kfree(hwcfg);
+	if (ret < 0)
+		printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static struct reg_domain const *at76_get_reg_domain(u16 code)
+{
+	int i;
+	static struct reg_domain const fd_tab[] = {
+		{ 0x10, "FCC (USA)", 0x7ff },	/* ch 1-11 */
+		{ 0x20, "IC (Canada)", 0x7ff },	/* ch 1-11 */
+		{ 0x30, "ETSI (most of Europe)", 0x1fff },	/* ch 1-13 */
+		{ 0x31, "Spain", 0x600 },	/* ch 10-11 */
+		{ 0x32, "France", 0x1e00 },	/* ch 10-13 */
+		{ 0x40, "MKK (Japan)", 0x2000 },	/* ch 14 */
+		{ 0x41, "MKK1 (Japan)", 0x3fff },	/* ch 1-14 */
+		{ 0x50, "Israel", 0x3fc },	/* ch 3-9 */
+		{ 0x00, "<unknown>", 0xffffffff }	/* ch 1-32 */
+	};
+
+	/* Last entry is fallback for unknown domain code */
+	for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
+		if (code == fd_tab[i].code)
+			break;
+
+	return &fd_tab[i];
+}
+
+static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
+			       int buf_size)
+{
+	int ret;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+			      USB_TYPE_VENDOR | USB_DIR_IN |
+			      USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
+			      USB_CTRL_GET_TIMEOUT);
+	if (ret >= 0 && ret != buf_size)
+		return -EIO;
+	return ret;
+}
+
+/* Return positive number for status, negative for an error */
+static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
+{
+	u8 *stat_buf;
+	int ret;
+
+	stat_buf = kmalloc(40, GFP_NOIO);
+	if (!stat_buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
+			USB_TYPE_VENDOR | USB_DIR_IN |
+			USB_RECIP_INTERFACE, cmd, 0, stat_buf,
+			40, USB_CTRL_GET_TIMEOUT);
+	if (ret >= 0)
+		ret = stat_buf[5];
+	kfree(stat_buf);
+
+	return ret;
+}
+
+#define MAKE_CMD_CASE(c) case (c): return #c
+static const char *at76_get_cmd_string(u8 cmd_status)
+{
+	switch (cmd_status) {
+		MAKE_CMD_CASE(CMD_SET_MIB);
+		MAKE_CMD_CASE(CMD_GET_MIB);
+		MAKE_CMD_CASE(CMD_SCAN);
+		MAKE_CMD_CASE(CMD_JOIN);
+		MAKE_CMD_CASE(CMD_START_IBSS);
+		MAKE_CMD_CASE(CMD_RADIO_ON);
+		MAKE_CMD_CASE(CMD_RADIO_OFF);
+		MAKE_CMD_CASE(CMD_STARTUP);
+	}
+
+	return "UNKNOWN";
+}
+
+static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
+				 int buf_size)
+{
+	int ret;
+	struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
+					       buf_size, GFP_KERNEL);
+
+	if (!cmd_buf)
+		return -ENOMEM;
+
+	cmd_buf->cmd = cmd;
+	cmd_buf->reserved = 0;
+	cmd_buf->size = cpu_to_le16(buf_size);
+	memcpy(cmd_buf->data, buf, buf_size);
+
+	at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
+		      "issuing command %s (0x%02x)",
+		      at76_get_cmd_string(cmd), cmd);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+			      0, 0, cmd_buf,
+			      sizeof(struct at76_command) + buf_size,
+			      USB_CTRL_GET_TIMEOUT);
+	kfree(cmd_buf);
+	return ret;
+}
+
+#define MAKE_CMD_STATUS_CASE(c)	case (c): return #c
+static const char *at76_get_cmd_status_string(u8 cmd_status)
+{
+	switch (cmd_status) {
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
+		MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
+	}
+
+	return "UNKNOWN";
+}
+
+/* Wait until the command is completed */
+static int at76_wait_completion(struct at76_priv *priv, int cmd)
+{
+	int status = 0;
+	unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
+
+	do {
+		status = at76_get_cmd_status(priv->udev, cmd);
+		if (status < 0) {
+			printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
+			       wiphy_name(priv->hw->wiphy), status);
+			break;
+		}
+
+		at76_dbg(DBG_WAIT_COMPLETE,
+			 "%s: Waiting on cmd %d, status = %d (%s)",
+			 wiphy_name(priv->hw->wiphy), cmd, status,
+			 at76_get_cmd_status_string(status));
+
+		if (status != CMD_STATUS_IN_PROGRESS
+		    && status != CMD_STATUS_IDLE)
+			break;
+
+		schedule_timeout_interruptible(HZ / 10);	/* 100 ms */
+		if (time_after(jiffies, timeout)) {
+			printk(KERN_ERR
+			       "%s: completion timeout for command %d\n",
+			       wiphy_name(priv->hw->wiphy), cmd);
+			status = -ETIMEDOUT;
+			break;
+		}
+	} while (1);
+
+	return status;
+}
+
+static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
+{
+	int ret;
+
+	ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
+				    offsetof(struct set_mib_buffer,
+					     data) + buf->size);
+	if (ret < 0)
+		return ret;
+
+	ret = at76_wait_completion(priv, CMD_SET_MIB);
+	if (ret != CMD_STATUS_COMPLETE) {
+		printk(KERN_INFO
+		       "%s: set_mib: at76_wait_completion failed "
+		       "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
+/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
+static int at76_set_radio(struct at76_priv *priv, int enable)
+{
+	int ret;
+	int cmd;
+
+	if (priv->radio_on == enable)
+		return 0;
+
+	cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
+
+	ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
+	if (ret < 0)
+		printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), cmd, ret);
+	else
+		ret = 1;
+
+	priv->radio_on = enable;
+	return ret;
+}
+
+/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
+static int at76_set_pm_mode(struct at76_priv *priv)
+{
+	int ret = 0;
+
+	priv->mib_buf.type = MIB_MAC_MGMT;
+	priv->mib_buf.size = 1;
+	priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
+	priv->mib_buf.data.byte = priv->pm_mode;
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static int at76_set_preamble(struct at76_priv *priv, u8 type)
+{
+	int ret = 0;
+
+	priv->mib_buf.type = MIB_LOCAL;
+	priv->mib_buf.size = 1;
+	priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
+	priv->mib_buf.data.byte = type;
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static int at76_set_frag(struct at76_priv *priv, u16 size)
+{
+	int ret = 0;
+
+	priv->mib_buf.type = MIB_MAC;
+	priv->mib_buf.size = 2;
+	priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
+	priv->mib_buf.data.word = cpu_to_le16(size);
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static int at76_set_rts(struct at76_priv *priv, u16 size)
+{
+	int ret = 0;
+
+	priv->mib_buf.type = MIB_MAC;
+	priv->mib_buf.size = 2;
+	priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
+	priv->mib_buf.data.word = cpu_to_le16(size);
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
+{
+	int ret = 0;
+
+	priv->mib_buf.type = MIB_LOCAL;
+	priv->mib_buf.size = 1;
+	priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
+	priv->mib_buf.data.byte = onoff;
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	return ret;
+}
+
+static void at76_dump_mib_mac_addr(struct at76_priv *priv)
+{
+	int i;
+	int ret;
+	struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
+					 GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
+			   sizeof(struct mib_mac_addr));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
+		 wiphy_name(priv->hw->wiphy),
+		 mac2str(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, "
+			 "status %d", wiphy_name(priv->hw->wiphy), i,
+			 mac2str(m->group_addr[i]), m->group_addr_status[i]);
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_mac_wep(struct at76_priv *priv)
+{
+	int i;
+	int ret;
+	int key_len;
+	struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
+			   sizeof(struct mib_mac_wep));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
+		 "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
+		 "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+		 m->privacy_invoked, m->wep_default_key_id,
+		 m->wep_key_mapping_len, m->exclude_unencrypted,
+		 le32_to_cpu(m->wep_icv_error_count),
+		 le32_to_cpu(m->wep_excluded_count), m->encryption_level,
+		 m->wep_default_key_id);
+
+	key_len = (m->encryption_level == 1) ?
+	    WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+
+	for (i = 0; i < WEP_KEYS; i++)
+		at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
+			 wiphy_name(priv->hw->wiphy), i,
+			 hex2str(m->wep_default_keyvalue[i], key_len));
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
+{
+	int ret;
+	struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
+					 GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
+			   sizeof(struct mib_mac_mgmt));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	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 "
+		 "pm_mode %d ibss_change %d res %d "
+		 "multi_domain_capability_implemented %d "
+		 "international_roaming %d country_string %.3s",
+		 wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+		 le16_to_cpu(m->CFP_max_duration),
+		 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),
+		 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,
+		 m->multi_domain_capability_enabled, m->country_string);
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_mac(struct at76_priv *priv)
+{
+	int ret;
+	struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
+		 "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
+		 "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",
+		 wiphy_name(priv->hw->wiphy),
+		 le32_to_cpu(m->max_tx_msdu_lifetime),
+		 le32_to_cpu(m->max_rx_lifetime),
+		 le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
+		 le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
+		 m->short_retry_time, m->long_retry_time, m->scan_type,
+		 m->scan_channel, le16_to_cpu(m->probe_delay),
+		 le16_to_cpu(m->min_channel_time),
+		 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);
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_phy(struct at76_priv *priv)
+{
+	int ret;
+	struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
+		 "sifs_time %d preamble_length %d plcp_header_length %d "
+		 "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
+		 "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
+		 "phy_type %d current_reg_domain %d",
+		 wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+		 le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
+		 le16_to_cpu(m->preamble_length),
+		 le16_to_cpu(m->plcp_header_length),
+		 le16_to_cpu(m->mpdu_max_length),
+		 le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
+		 m->operation_rate_set[1], m->operation_rate_set[2],
+		 m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
+		 m->phy_type, m->current_reg_domain);
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_local(struct at76_priv *priv)
+{
+	int ret;
+	struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
+		 "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
+		 "preamble_type %d", wiphy_name(priv->hw->wiphy),
+		 m->beacon_enable,
+		 m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
+		 m->preamble_type);
+exit:
+	kfree(m);
+}
+
+static void at76_dump_mib_mdomain(struct at76_priv *priv)
+{
+	int ret;
+	struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
+
+	if (!m)
+		return;
+
+	ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
+			   sizeof(struct mib_mdomain));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
+		 wiphy_name(priv->hw->wiphy),
+		 hex2str(m->channel_list, sizeof(m->channel_list)));
+
+	at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
+		 wiphy_name(priv->hw->wiphy),
+		 hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
+exit:
+	kfree(m);
+}
+
+/* Enable monitor mode */
+static int at76_start_monitor(struct at76_priv *priv)
+{
+	struct at76_req_scan scan;
+	int ret;
+
+	memset(&scan, 0, sizeof(struct at76_req_scan));
+	memset(scan.bssid, 0xff, ETH_ALEN);
+
+	scan.channel = priv->channel;
+	scan.scan_type = SCAN_TYPE_PASSIVE;
+	scan.international_scan = 0;
+
+	ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+	if (ret >= 0)
+		ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+
+	return ret;
+}
+
+/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
+   likely to compensate a flaw in the AT76C503A USB part ... */
+static inline int at76_calc_padding(int wlen)
+{
+	/* add the USB TX header */
+	wlen += AT76_TX_HDRLEN;
+
+	wlen = wlen % 64;
+
+	if (wlen < 50)
+		return 50 - wlen;
+
+	if (wlen >= 61)
+		return 64 + 50 - wlen;
+
+	return 0;
+}
+
+static void at76_rx_callback(struct urb *urb)
+{
+	struct at76_priv *priv = urb->context;
+
+	priv->rx_tasklet.data = (unsigned long)urb;
+	tasklet_schedule(&priv->rx_tasklet);
+	return;
+}
+
+static int at76_submit_rx_urb(struct at76_priv *priv)
+{
+	int ret;
+	int size;
+	struct sk_buff *skb = priv->rx_skb;
+
+	if (!priv->rx_urb) {
+		printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
+		       wiphy_name(priv->hw->wiphy), __func__);
+		return -EFAULT;
+	}
+
+	if (!skb) {
+		skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
+		if (!skb) {
+			printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
+			       wiphy_name(priv->hw->wiphy));
+			ret = -ENOMEM;
+			goto exit;
+		}
+		priv->rx_skb = skb;
+	} else {
+		skb_push(skb, skb_headroom(skb));
+		skb_trim(skb, 0);
+	}
+
+	size = skb_tailroom(skb);
+	usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
+			  skb_put(skb, size), size, at76_rx_callback, priv);
+	ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
+	if (ret < 0) {
+		if (ret == -ENODEV)
+			at76_dbg(DBG_DEVSTART,
+				 "usb_submit_urb returned -ENODEV");
+		else
+			printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
+			       wiphy_name(priv->hw->wiphy), ret);
+	}
+
+exit:
+	if (ret < 0 && ret != -ENODEV)
+		printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
+		       "driver and/or power cycle the device\n",
+		       wiphy_name(priv->hw->wiphy));
+
+	return ret;
+}
+
+/* Download external firmware */
+static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+	int ret;
+	int op_mode;
+	int blockno = 0;
+	int bsize;
+	u8 *block;
+	u8 *buf = fwe->extfw;
+	int size = fwe->extfw_size;
+
+	if (!buf || !size)
+		return -ENOENT;
+
+	op_mode = at76_get_op_mode(udev);
+	at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+	if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+		dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
+			   op_mode);
+		return -EINVAL;
+	}
+
+	block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+	if (!block)
+		return -ENOMEM;
+
+	at76_dbg(DBG_DEVSTART, "downloading external firmware");
+
+	/* for fw >= 0.100, the device needs an extra empty block */
+	do {
+		bsize = min_t(int, size, FW_BLOCK_SIZE);
+		memcpy(block, buf, bsize);
+		at76_dbg(DBG_DEVSTART,
+			 "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
+			 size, bsize, blockno);
+		ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
+		if (ret != bsize) {
+			dev_printk(KERN_ERR, &udev->dev,
+				   "loading %dth firmware block failed: %d\n",
+				   blockno, ret);
+			goto exit;
+		}
+		buf += bsize;
+		size -= bsize;
+		blockno++;
+	} while (bsize > 0);
+
+	if (at76_is_505a(fwe->board_type)) {
+		at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
+		schedule_timeout_interruptible(HZ / 5 + 1);
+	}
+
+exit:
+	kfree(block);
+	if (ret < 0)
+		dev_printk(KERN_ERR, &udev->dev,
+			   "downloading external firmware failed: %d\n", ret);
+	return ret;
+}
+
+/* Download internal firmware */
+static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+	int ret;
+	int need_remap = !at76_is_505a(fwe->board_type);
+
+	ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
+				   need_remap ? 0 : 2 * HZ);
+
+	if (ret < 0) {
+		dev_printk(KERN_ERR, &udev->dev,
+			   "downloading internal fw failed with %d\n", ret);
+		goto exit;
+	}
+
+	at76_dbg(DBG_DEVSTART, "sending REMAP");
+
+	/* no REMAP for 505A (see SF driver) */
+	if (need_remap) {
+		ret = at76_remap(udev);
+		if (ret < 0) {
+			dev_printk(KERN_ERR, &udev->dev,
+				   "sending REMAP failed with %d\n", ret);
+			goto exit;
+		}
+	}
+
+	at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
+	schedule_timeout_interruptible(2 * HZ + 1);
+	usb_reset_device(udev);
+
+exit:
+	return ret;
+}
+
+static int at76_startup_device(struct at76_priv *priv)
+{
+	struct at76_card_config *ccfg = &priv->card_config;
+	int ret;
+
+	at76_dbg(DBG_PARAMS,
+		 "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
+		 "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
+		 priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+		 priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
+		 priv->channel, priv->wep_enabled ? "enabled" : "disabled",
+		 priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
+	at76_dbg(DBG_PARAMS,
+		 "%s param: preamble %s rts %d retry %d frag %d "
+		 "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+		 preambles[priv->preamble_type], priv->rts_threshold,
+		 priv->short_retry_limit, priv->frag_threshold,
+		 priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
+		 TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
+		 TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
+		 TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
+		 TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
+	at76_dbg(DBG_PARAMS,
+		 "%s param: pm_mode %d pm_period %d auth_mode %s "
+		 "scan_times %d %d scan_mode %s",
+		 wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+		 priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
+		 priv->scan_min_time, priv->scan_max_time,
+		 priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
+
+	memset(ccfg, 0, sizeof(struct at76_card_config));
+	ccfg->promiscuous_mode = 0;
+	ccfg->short_retry_limit = priv->short_retry_limit;
+
+	if (priv->wep_enabled) {
+		if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
+			ccfg->encryption_type = 2;
+		else
+			ccfg->encryption_type = 1;
+
+		/* jal: always exclude unencrypted if WEP is active */
+		ccfg->exclude_unencrypted = 1;
+	} else {
+		ccfg->exclude_unencrypted = 0;
+		ccfg->encryption_type = 0;
+	}
+
+	ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
+	ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
+
+	memcpy(ccfg->basic_rate_set, hw_rates, 4);
+	/* jal: really needed, we do a set_mib for autorate later ??? */
+	ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
+	ccfg->channel = priv->channel;
+	ccfg->privacy_invoked = priv->wep_enabled;
+	memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
+	ccfg->ssid_len = priv->essid_size;
+
+	ccfg->wep_default_key_id = priv->wep_key_id;
+	memcpy(ccfg->wep_default_key_value, priv->wep_keys,
+	       sizeof(priv->wep_keys));
+
+	ccfg->short_preamble = priv->preamble_type;
+	ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
+
+	ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
+				    sizeof(struct at76_card_config));
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		return ret;
+	}
+
+	at76_wait_completion(priv, CMD_STARTUP);
+
+	/* remove BSSID from previous run */
+	memset(priv->bssid, 0, ETH_ALEN);
+
+	if (at76_set_radio(priv, 1) == 1)
+		at76_wait_completion(priv, CMD_RADIO_ON);
+
+	ret = at76_set_preamble(priv, priv->preamble_type);
+	if (ret < 0)
+		return ret;
+
+	ret = at76_set_frag(priv, priv->frag_threshold);
+	if (ret < 0)
+		return ret;
+
+	ret = at76_set_rts(priv, priv->rts_threshold);
+	if (ret < 0)
+		return ret;
+
+	ret = at76_set_autorate_fallback(priv,
+					 priv->txrate == TX_RATE_AUTO ? 1 : 0);
+	if (ret < 0)
+		return ret;
+
+	ret = at76_set_pm_mode(priv);
+	if (ret < 0)
+		return ret;
+
+	if (at76_debug & DBG_MIB) {
+		at76_dump_mib_mac(priv);
+		at76_dump_mib_mac_addr(priv);
+		at76_dump_mib_mac_mgmt(priv);
+		at76_dump_mib_mac_wep(priv);
+		at76_dump_mib_mdomain(priv);
+		at76_dump_mib_phy(priv);
+		at76_dump_mib_local(priv);
+	}
+
+	return 0;
+}
+
+/* Enable or disable promiscuous mode */
+static void at76_work_set_promisc(struct work_struct *work)
+{
+	struct at76_priv *priv = container_of(work, struct at76_priv,
+					      work_set_promisc);
+	int ret = 0;
+
+	if (priv->device_unplugged)
+		return;
+
+	mutex_lock(&priv->mtx);
+
+	priv->mib_buf.type = MIB_LOCAL;
+	priv->mib_buf.size = 1;
+	priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
+	priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
+
+	ret = at76_set_mib(priv, &priv->mib_buf);
+	if (ret < 0)
+		printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+
+	mutex_unlock(&priv->mtx);
+}
+
+/* Submit Rx urb back to the device */
+static void at76_work_submit_rx(struct work_struct *work)
+{
+	struct at76_priv *priv = container_of(work, struct at76_priv,
+					      work_submit_rx);
+
+	mutex_lock(&priv->mtx);
+	at76_submit_rx_urb(priv);
+	mutex_unlock(&priv->mtx);
+}
+
+static void at76_rx_tasklet(unsigned long param)
+{
+	struct urb *urb = (struct urb *)param;
+	struct at76_priv *priv = urb->context;
+	struct at76_rx_buffer *buf;
+	struct ieee80211_rx_status rx_status = { 0 };
+
+	if (priv->device_unplugged) {
+		at76_dbg(DBG_DEVSTART, "device unplugged");
+		if (urb)
+			at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+		return;
+	}
+
+	if (!priv->rx_skb || !priv->rx_skb->data)
+		return;
+
+	buf = (struct at76_rx_buffer *)priv->rx_skb->data;
+
+	if (urb->status != 0) {
+		if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+			at76_dbg(DBG_URB,
+				 "%s %s: - nonzero Rx bulk status received: %d",
+				 __func__, wiphy_name(priv->hw->wiphy),
+				 urb->status);
+		return;
+	}
+
+	at76_dbg(DBG_RX_ATMEL_HDR,
+		 "%s: rx frame: rate %d rssi %d noise %d link %d",
+		 wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
+		 buf->noise_level, buf->link_quality);
+
+	skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
+	skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength));
+	at76_dbg_dump(DBG_RX_DATA, priv->rx_skb->data,
+		      priv->rx_skb->len, "RX: len=%d", priv->rx_skb->len);
+
+	rx_status.signal = buf->rssi;
+	rx_status.flag |= RX_FLAG_DECRYPTED;
+	rx_status.flag |= RX_FLAG_IV_STRIPPED;
+
+	at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
+		 priv->rx_skb->len, priv->rx_skb->data_len);
+	ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+
+	/* Use a new skb for the next receive */
+	priv->rx_skb = NULL;
+
+	at76_submit_rx_urb(priv);
+}
+
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+					  enum board_type board_type)
+{
+	int ret;
+	char *str;
+	struct at76_fw_header *fwh;
+	struct fwentry *fwe = &firmwares[board_type];
+
+	mutex_lock(&fw_mutex);
+
+	if (fwe->loaded) {
+		at76_dbg(DBG_FW, "re-using previously loaded fw");
+		goto exit;
+	}
+
+	at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+	ret = reject_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+	if (ret < 0) {
+		dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+			   fwe->fwname);
+		dev_printk(KERN_ERR, &udev->dev,
+			   "you may need to download the firmware from "
+			   "http://developer.berlios.de/projects/at76c503a/\n");
+		goto exit;
+	}
+
+	at76_dbg(DBG_FW, "got it.");
+	fwh = (struct at76_fw_header *)(fwe->fw->data);
+
+	if (fwe->fw->size <= sizeof(*fwh)) {
+		dev_printk(KERN_ERR, &udev->dev,
+			   "firmware is too short (0x%zx)\n", fwe->fw->size);
+		goto exit;
+	}
+
+	/* CRC currently not checked */
+	fwe->board_type = le32_to_cpu(fwh->board_type);
+	if (fwe->board_type != board_type) {
+		dev_printk(KERN_ERR, &udev->dev,
+			   "board type mismatch, requested %u, got %u\n",
+			   board_type, fwe->board_type);
+		goto exit;
+	}
+
+	fwe->fw_version.major = fwh->major;
+	fwe->fw_version.minor = fwh->minor;
+	fwe->fw_version.patch = fwh->patch;
+	fwe->fw_version.build = fwh->build;
+
+	str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+	fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+	fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+	fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+	fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+
+	fwe->loaded = 1;
+
+	dev_printk(KERN_DEBUG, &udev->dev,
+		   "using firmware %s (version %d.%d.%d-%d)\n",
+		   fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+
+	at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+		 le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+		 le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+	at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+
+exit:
+	mutex_unlock(&fw_mutex);
+
+	if (fwe->loaded)
+		return fwe;
+	else
+		return NULL;
+}
+
+static void at76_mac80211_tx_callback(struct urb *urb)
+{
+	struct at76_priv *priv = urb->context;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		info->flags |= IEEE80211_TX_STAT_ACK;
+		break;
+	case -ENOENT:
+	case -ECONNRESET:
+		/* fail, urb has been unlinked */
+		/* FIXME: add error message */
+		break;
+	default:
+		at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+			 __func__, urb->status);
+		break;
+	}
+
+	memset(&info->status, 0, sizeof(info->status));
+
+	ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+
+	priv->tx_skb = NULL;
+
+	ieee80211_wake_queues(priv->hw);
+}
+
+static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct at76_priv *priv = hw->priv;
+	struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	int padding, submit_len, ret;
+
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+	if (priv->tx_urb->status == -EINPROGRESS) {
+		printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+		       wiphy_name(priv->hw->wiphy), __func__);
+		return NETDEV_TX_BUSY;
+	}
+
+	ieee80211_stop_queues(hw);
+
+	at76_ledtrig_tx_activity();	/* tell ledtrigger we send a packet */
+
+	WARN_ON(priv->tx_skb != NULL);
+
+	priv->tx_skb = skb;
+	padding = at76_calc_padding(skb->len);
+	submit_len = AT76_TX_HDRLEN + skb->len + padding;
+
+	/* setup 'Atmel' header */
+	memset(tx_buffer, 0, sizeof(*tx_buffer));
+	tx_buffer->padding = padding;
+	tx_buffer->wlength = cpu_to_le16(skb->len);
+	tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
+	memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+	memcpy(tx_buffer->packet, skb->data, skb->len);
+
+	at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
+		 wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
+		 tx_buffer->padding, tx_buffer->tx_rate);
+
+	/* send stuff */
+	at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
+		      "%s(): tx_buffer %d bytes:", __func__, submit_len);
+	usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+			  submit_len, at76_mac80211_tx_callback, priv);
+	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+	if (ret) {
+		printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		if (ret == -EINVAL)
+			printk(KERN_ERR
+			       "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+			       wiphy_name(priv->hw->wiphy), priv->tx_urb,
+			       priv->tx_urb->hcpriv, priv->tx_urb->complete);
+	}
+
+	return 0;
+}
+
+static int at76_mac80211_start(struct ieee80211_hw *hw)
+{
+	struct at76_priv *priv = hw->priv;
+	int ret;
+
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+	mutex_lock(&priv->mtx);
+
+	ret = at76_submit_rx_urb(priv);
+	if (ret < 0) {
+		printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		goto error;
+	}
+
+	at76_startup_device(priv);
+
+	at76_start_monitor(priv);
+
+error:
+	mutex_unlock(&priv->mtx);
+
+	return 0;
+}
+
+static void at76_mac80211_stop(struct ieee80211_hw *hw)
+{
+	struct at76_priv *priv = hw->priv;
+
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+	mutex_lock(&priv->mtx);
+
+	if (!priv->device_unplugged) {
+		/* We are called by "ifconfig ethX down", not because the
+		 * device is not available anymore. */
+		at76_set_radio(priv, 0);
+
+		/* We unlink rx_urb because at76_open() re-submits it.
+		 * If unplugged, at76_delete_device() takes care of it. */
+		usb_kill_urb(priv->rx_urb);
+	}
+
+	mutex_unlock(&priv->mtx);
+}
+
+static int at76_add_interface(struct ieee80211_hw *hw,
+			      struct ieee80211_if_init_conf *conf)
+{
+	struct at76_priv *priv = hw->priv;
+	int ret = 0;
+
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+	mutex_lock(&priv->mtx);
+
+	switch (conf->type) {
+	case NL80211_IFTYPE_STATION:
+		priv->iw_mode = IW_MODE_INFRA;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		goto exit;
+	}
+
+exit:
+	mutex_unlock(&priv->mtx);
+
+	return ret;
+}
+
+static void at76_remove_interface(struct ieee80211_hw *hw,
+				  struct ieee80211_if_init_conf *conf)
+{
+	at76_dbg(DBG_MAC80211, "%s()", __func__);
+}
+
+static int at76_join(struct at76_priv *priv)
+{
+	struct at76_req_join join;
+	int ret;
+
+	memset(&join, 0, sizeof(struct at76_req_join));
+	memcpy(join.essid, priv->essid, priv->essid_size);
+	join.essid_size = priv->essid_size;
+	memcpy(join.bssid, priv->bssid, ETH_ALEN);
+	join.bss_type = INFRASTRUCTURE_MODE;
+	join.channel = priv->channel;
+	join.timeout = cpu_to_le16(2000);
+
+	at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
+	ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
+				    sizeof(struct at76_req_join));
+
+	if (ret < 0) {
+		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		return 0;
+	}
+
+	ret = at76_wait_completion(priv, CMD_JOIN);
+	at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
+	if (ret != CMD_STATUS_COMPLETE) {
+		printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
+		       wiphy_name(priv->hw->wiphy), ret);
+		return 0;
+	}
+
+	at76_set_pm_mode(priv);
+
+	return 0;
+}
+
+static void at76_dwork_hw_scan(struct work_struct *work)
+{
+	struct at76_priv *priv = container_of(work, struct at76_priv,
+					      dwork_hw_scan.work);
+	int ret;
+
+	if (priv->device_unplugged)
+		return;
+
+	mutex_lock(&priv->mtx);
+
+	ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+	at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+
+	/* FIXME: add maximum time for scan to complete */
+
+	if (ret != CMD_STATUS_COMPLETE) {
+		queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+				   SCAN_POLL_INTERVAL);
+		mutex_unlock(&priv->mtx);
+		return;
+	}
+
+	if (is_valid_ether_addr(priv->bssid))
+		at76_join(priv);
+
+	mutex_unlock(&priv->mtx);
+
+	ieee80211_scan_completed(priv->hw, false);
+
+	ieee80211_wake_queues(priv->hw);
+}
+
+static int at76_hw_scan(struct ieee80211_hw *hw,
+			struct cfg80211_scan_request *req)
+{
+	struct at76_priv *priv = hw->priv;
+	struct at76_req_scan scan;
+	u8 *ssid = NULL;
+	int ret, len = 0;
+
+	at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+	if (priv->device_unplugged)
+		return 0;
+
+	mutex_lock(&priv->mtx);
+
+	ieee80211_stop_queues(hw);
+
+	memset(&scan, 0, sizeof(struct at76_req_scan));
+	memset(scan.bssid, 0xFF, ETH_ALEN);
+
+	if (req->n_ssids) {
+		scan.scan_type = SCAN_TYPE_ACTIVE;
+		ssid = req->ssids[0].ssid;
+		len = req->ssids[0].ssid_len;
+	} else {
+		scan.scan_type = SCAN_TYPE_PASSIVE;
+	}
+
+	if (len) {
+		memcpy(scan.essid, ssid, len);
+		scan.essid_size = len;
+	}
+
+	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(priv->scan_min_time * 1000);
+	scan.international_scan = 0;
+
+	at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
+	ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+
+	if (ret < 0) {
+		err("CMD_SCAN failed: %d", ret);
+		goto exit;
+	}
+
+	queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+			   SCAN_POLL_INTERVAL);
+
+exit:
+	mutex_unlock(&priv->mtx);
+
+	return 0;
+}
+
+static int at76_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct at76_priv *priv = hw->priv;
+
+	at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
+		 __func__, hw->conf.channel->hw_value,
+		 hw->conf.radio_enabled);
+	at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+
+	mutex_lock(&priv->mtx);
+
+	priv->channel = hw->conf.channel->hw_value;
+
+	if (is_valid_ether_addr(priv->bssid))
+		at76_join(priv);
+	else
+		at76_start_monitor(priv);
+
+	mutex_unlock(&priv->mtx);
+
+	return 0;
+}
+
+static int at76_config_interface(struct ieee80211_hw *hw,
+				 struct ieee80211_vif *vif,
+				 struct ieee80211_if_conf *conf)
+{
+	struct at76_priv *priv = hw->priv;
+
+	at76_dbg(DBG_MAC80211, "%s():", __func__);
+	at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+
+	mutex_lock(&priv->mtx);
+
+	memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+
+	if (is_valid_ether_addr(priv->bssid))
+		/* mac80211 is joining a bss */
+		at76_join(priv);
+
+	mutex_unlock(&priv->mtx);
+
+	return 0;
+}
+
+/* must be atomic */
+static void at76_configure_filter(struct ieee80211_hw *hw,
+				  unsigned int changed_flags,
+				  unsigned int *total_flags, int mc_count,
+				  struct dev_addr_list *mc_list)
+{
+	struct at76_priv *priv = hw->priv;
+	int flags;
+
+	at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
+		 "total_flags=0x%08x mc_count=%d",
+		 __func__, changed_flags, *total_flags, mc_count);
+
+	flags = changed_flags & AT76_SUPPORTED_FILTERS;
+	*total_flags = AT76_SUPPORTED_FILTERS;
+
+	/* Bail out after updating flags to prevent a WARN_ON in mac80211. */
+	if (priv->device_unplugged)
+		return;
+
+	/* FIXME: access to priv->promisc should be protected with
+	 * priv->mtx, but it's impossible because this function needs to be
+	 * atomic */
+
+	if (flags && !priv->promisc) {
+		/* mac80211 wants us to enable promiscuous mode */
+		priv->promisc = 1;
+	} else if (!flags && priv->promisc) {
+		/* we need to disable promiscuous mode */
+		priv->promisc = 0;
+	} else
+		return;
+
+	queue_work(hw->workqueue, &priv->work_set_promisc);
+}
+
+static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			struct ieee80211_key_conf *key)
+{
+	struct at76_priv *priv = hw->priv;
+
+	int i;
+
+	at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
+		 "key->keylen %d",
+		 __func__, cmd, key->alg, key->keyidx, key->keylen);
+
+	if (key->alg != ALG_WEP)
+		return -EOPNOTSUPP;
+
+	key->hw_key_idx = key->keyidx;
+
+	mutex_lock(&priv->mtx);
+
+	switch (cmd) {
+	case SET_KEY:
+		memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
+		priv->wep_keys_len[key->keyidx] = key->keylen;
+
+		/* FIXME: find out how to do this properly */
+		priv->wep_key_id = key->keyidx;
+
+		break;
+	case DISABLE_KEY:
+	default:
+		priv->wep_keys_len[key->keyidx] = 0;
+		break;
+	}
+
+	priv->wep_enabled = 0;
+
+	for (i = 0; i < WEP_KEYS; i++) {
+		if (priv->wep_keys_len[i] != 0)
+			priv->wep_enabled = 1;
+	}
+
+	at76_startup_device(priv);
+
+	mutex_unlock(&priv->mtx);
+
+	return 0;
+}
+
+static const struct ieee80211_ops at76_ops = {
+	.tx = at76_mac80211_tx,
+	.add_interface = at76_add_interface,
+	.remove_interface = at76_remove_interface,
+	.config = at76_config,
+	.config_interface = at76_config_interface,
+	.configure_filter = at76_configure_filter,
+	.start = at76_mac80211_start,
+	.stop = at76_mac80211_stop,
+	.hw_scan = at76_hw_scan,
+	.set_key = at76_set_key,
+};
+
+/* Allocate network device and initialize private data */
+static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
+{
+	struct ieee80211_hw *hw;
+	struct at76_priv *priv;
+
+	hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
+	if (!hw) {
+		printk(KERN_ERR DRIVER_NAME ": could not register"
+		       " ieee80211_hw\n");
+		return NULL;
+	}
+
+	priv = hw->priv;
+	priv->hw = hw;
+
+	priv->udev = udev;
+
+	mutex_init(&priv->mtx);
+	INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
+	INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
+	INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+
+	tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
+
+	priv->pm_mode = AT76_PM_OFF;
+	priv->pm_period = 0;
+
+	/* unit us */
+	priv->hw->channel_change_time = 100000;
+
+	return priv;
+}
+
+static int at76_alloc_urbs(struct at76_priv *priv,
+			   struct usb_interface *interface)
+{
+	struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
+	int i;
+	int buffer_size;
+	struct usb_host_interface *iface_desc;
+
+	at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+	at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
+		 interface->altsetting[0].desc.bNumEndpoints);
+
+	ep_in = NULL;
+	ep_out = NULL;
+	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
+			 __func__, i, endpoint->bEndpointAddress,
+			 endpoint->bmAttributes);
+
+		if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
+			ep_in = endpoint;
+
+		if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
+			ep_out = endpoint;
+	}
+
+	if (!ep_in || !ep_out) {
+		dev_printk(KERN_ERR, &interface->dev,
+			   "bulk endpoints missing\n");
+		return -ENXIO;
+	}
+
+	priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
+	priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
+
+	priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!priv->rx_urb || !priv->tx_urb) {
+		dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
+		return -ENOMEM;
+	}
+
+	buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
+	priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!priv->bulk_out_buffer) {
+		dev_printk(KERN_ERR, &interface->dev,
+			   "cannot allocate output buffer\n");
+		return -ENOMEM;
+	}
+
+	at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+
+	return 0;
+}
+
+static struct ieee80211_rate at76_rates[] = {
+	{ .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
+	{ .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
+	{ .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
+	{ .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
+};
+
+static struct ieee80211_channel at76_channels[] = {
+	{ .center_freq = 2412, .hw_value = 1 },
+	{ .center_freq = 2417, .hw_value = 2 },
+	{ .center_freq = 2422, .hw_value = 3 },
+	{ .center_freq = 2427, .hw_value = 4 },
+	{ .center_freq = 2432, .hw_value = 5 },
+	{ .center_freq = 2437, .hw_value = 6 },
+	{ .center_freq = 2442, .hw_value = 7 },
+	{ .center_freq = 2447, .hw_value = 8 },
+	{ .center_freq = 2452, .hw_value = 9 },
+	{ .center_freq = 2457, .hw_value = 10 },
+	{ .center_freq = 2462, .hw_value = 11 },
+	{ .center_freq = 2467, .hw_value = 12 },
+	{ .center_freq = 2472, .hw_value = 13 },
+	{ .center_freq = 2484, .hw_value = 14 }
+};
+
+static struct ieee80211_supported_band at76_supported_band = {
+	.channels = at76_channels,
+	.n_channels = ARRAY_SIZE(at76_channels),
+	.bitrates = at76_rates,
+	.n_bitrates = ARRAY_SIZE(at76_rates),
+};
+
+/* Register network device and initialize the hardware */
+static int at76_init_new_device(struct at76_priv *priv,
+				struct usb_interface *interface)
+{
+	int ret;
+
+	/* set up the endpoint information */
+	/* check out the endpoints */
+
+	at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
+		 interface->cur_altsetting->desc.bNumEndpoints);
+
+	ret = at76_alloc_urbs(priv, interface);
+	if (ret < 0)
+		goto exit;
+
+	/* MAC address */
+	ret = at76_get_hw_config(priv);
+	if (ret < 0) {
+		dev_printk(KERN_ERR, &interface->dev,
+			   "cannot get MAC address\n");
+		goto exit;
+	}
+
+	priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+
+	priv->channel = DEF_CHANNEL;
+	priv->iw_mode = IW_MODE_INFRA;
+	priv->rts_threshold = DEF_RTS_THRESHOLD;
+	priv->frag_threshold = DEF_FRAG_THRESHOLD;
+	priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
+	priv->txrate = TX_RATE_AUTO;
+	priv->preamble_type = PREAMBLE_TYPE_LONG;
+	priv->beacon_period = 100;
+	priv->auth_mode = WLAN_AUTH_OPEN;
+	priv->scan_min_time = DEF_SCAN_MIN_TIME;
+	priv->scan_max_time = DEF_SCAN_MAX_TIME;
+	priv->scan_mode = SCAN_TYPE_ACTIVE;
+	priv->device_unplugged = 0;
+
+	/* mac80211 initialisation */
+	priv->hw->wiphy->max_scan_ssids = 1;
+	priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
+	priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+			  IEEE80211_HW_SIGNAL_UNSPEC;
+	priv->hw->max_signal = 100;
+
+	SET_IEEE80211_DEV(priv->hw, &interface->dev);
+	SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+
+	ret = ieee80211_register_hw(priv->hw);
+	if (ret) {
+		printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
+		       ret);
+		goto exit;
+	}
+
+	priv->mac80211_registered = 1;
+
+	printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+	       wiphy_name(priv->hw->wiphy),
+	       dev_name(&interface->dev), mac2str(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",
+	       wiphy_name(priv->hw->wiphy),
+	       priv->regulatory_domain, priv->domain->name);
+
+exit:
+	return ret;
+}
+
+static void at76_delete_device(struct at76_priv *priv)
+{
+	at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+	/* The device is gone, don't bother turning it off */
+	priv->device_unplugged = 1;
+
+	tasklet_kill(&priv->rx_tasklet);
+
+	if (priv->mac80211_registered) {
+		cancel_delayed_work(&priv->dwork_hw_scan);
+		flush_workqueue(priv->hw->workqueue);
+		ieee80211_unregister_hw(priv->hw);
+	}
+
+	if (priv->tx_urb) {
+		usb_kill_urb(priv->tx_urb);
+		usb_free_urb(priv->tx_urb);
+	}
+	if (priv->rx_urb) {
+		usb_kill_urb(priv->rx_urb);
+		usb_free_urb(priv->rx_urb);
+	}
+
+	at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
+
+	kfree(priv->bulk_out_buffer);
+
+	del_timer_sync(&ledtrig_tx_timer);
+
+	if (priv->rx_skb)
+		kfree_skb(priv->rx_skb);
+
+	usb_put_dev(priv->udev);
+
+	at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
+		 __func__);
+	ieee80211_free_hw(priv->hw);
+
+	at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+}
+
+static int at76_probe(struct usb_interface *interface,
+		      const struct usb_device_id *id)
+{
+	int ret;
+	struct at76_priv *priv;
+	struct fwentry *fwe;
+	struct usb_device *udev;
+	int op_mode;
+	int need_ext_fw = 0;
+	struct mib_fw_version fwv;
+	int board_type = (int)id->driver_info;
+
+	udev = usb_get_dev(interface_to_usbdev(interface));
+
+	/* Load firmware into kernel memory */
+	fwe = at76_load_firmware(udev, board_type);
+	if (!fwe) {
+		ret = -ENOENT;
+		goto error;
+	}
+
+	op_mode = at76_get_op_mode(udev);
+
+	at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+	/* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
+	   we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
+
+	if (op_mode == OPMODE_HW_CONFIG_MODE) {
+		dev_printk(KERN_ERR, &interface->dev,
+			   "cannot handle a device in HW_CONFIG_MODE\n");
+		ret = -EBUSY;
+		goto error;
+	}
+
+	if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+	    && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+		/* download internal firmware part */
+		dev_printk(KERN_DEBUG, &interface->dev,
+			   "downloading internal firmware\n");
+		ret = at76_load_internal_fw(udev, fwe);
+		if (ret < 0) {
+			dev_printk(KERN_ERR, &interface->dev,
+				   "error %d downloading internal firmware\n",
+				   ret);
+			goto error;
+		}
+		usb_put_dev(udev);
+		return ret;
+	}
+
+	/* Internal firmware already inside the device.  Get firmware
+	 * version to test if external firmware is loaded.
+	 * This works only for newer firmware, e.g. the Intersil 0.90.x
+	 * says "control timeout on ep0in" and subsequent
+	 * at76_get_op_mode() fail too :-( */
+
+	/* if version >= 0.100.x.y or device with built-in flash we can
+	 * query the device for the fw version */
+	if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
+	    || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
+		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+		if (ret < 0 || (fwv.major | fwv.minor) == 0)
+			need_ext_fw = 1;
+	} else
+		/* No way to check firmware version, reload to be sure */
+		need_ext_fw = 1;
+
+	if (need_ext_fw) {
+		dev_printk(KERN_DEBUG, &interface->dev,
+			   "downloading external firmware\n");
+
+		ret = at76_load_external_fw(udev, fwe);
+		if (ret)
+			goto error;
+
+		/* Re-check firmware version */
+		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+		if (ret < 0) {
+			dev_printk(KERN_ERR, &interface->dev,
+				   "error %d getting firmware version\n", ret);
+			goto error;
+		}
+	}
+
+	priv = at76_alloc_new_device(udev);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	usb_set_intfdata(interface, priv);
+
+	memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
+	priv->board_type = board_type;
+
+	ret = at76_init_new_device(priv, interface);
+	if (ret < 0)
+		at76_delete_device(priv);
+
+	return ret;
+
+error:
+	usb_put_dev(udev);
+	return ret;
+}
+
+static void at76_disconnect(struct usb_interface *interface)
+{
+	struct at76_priv *priv;
+
+	priv = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	/* Disconnect after loading internal firmware */
+	if (!priv)
+		return;
+
+	printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+	at76_delete_device(priv);
+	dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
+}
+
+/* Structure for registering this driver with the USB subsystem */
+static struct usb_driver at76_driver = {
+	.name = DRIVER_NAME,
+	.probe = at76_probe,
+	.disconnect = at76_disconnect,
+	.id_table = dev_table,
+};
+
+static int __init at76_mod_init(void)
+{
+	int result;
+
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
+
+	mutex_init(&fw_mutex);
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&at76_driver);
+	if (result < 0)
+		printk(KERN_ERR DRIVER_NAME
+		       ": usb_register failed (status %d)\n", result);
+
+	led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+	return result;
+}
+
+static void __exit at76_mod_exit(void)
+{
+	int i;
+
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
+	usb_deregister(&at76_driver);
+	for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
+		if (firmwares[i].fw)
+			release_firmware(firmwares[i].fw);
+	}
+	led_trigger_unregister_simple(ledtrig_tx);
+}
+
+module_param_named(debug, at76_debug, uint, 0600);
+MODULE_PARM_DESC(debug, "Debugging level");
+
+module_init(at76_mod_init);
+module_exit(at76_mod_exit);
+
+MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
+MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
+MODULE_AUTHOR("Alex <alex@foogod.com>");
+MODULE_AUTHOR("Nick Jones");
+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/at76c50x-usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/at76c50x-usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/at76c50x-usb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/at76c50x-usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2002,2003 Oliver Kurth
+ *	     (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
+ *	     (c) 2007 Guido Guenther <agx@sigxcpu.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 driver was based on information from the Sourceforge driver
+ * released and maintained by Atmel:
+ *
+ *  http://sourceforge.net/projects/atmelwlandriver/
+ *
+ * Although the code was completely re-written,
+ * it would have been impossible without Atmel's decision to
+ * release an Open Source driver (unfortunately the firmware was
+ * kept binary only). Thanks for that decision to Atmel!
+ */
+
+#ifndef _AT76_USB_H
+#define _AT76_USB_H
+
+/* Board types */
+enum board_type {
+	BOARD_503_ISL3861 = 1,
+	BOARD_503_ISL3863 = 2,
+	BOARD_503 = 3,
+	BOARD_503_ACC = 4,
+	BOARD_505 = 5,
+	BOARD_505_2958 = 6,
+	BOARD_505A = 7,
+	BOARD_505AMX = 8
+};
+
+#define CMD_STATUS_IDLE				0x00
+#define CMD_STATUS_COMPLETE			0x01
+#define CMD_STATUS_UNKNOWN			0x02
+#define CMD_STATUS_INVALID_PARAMETER		0x03
+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED	0x04
+#define CMD_STATUS_TIME_OUT			0x07
+#define CMD_STATUS_IN_PROGRESS			0x08
+#define CMD_STATUS_HOST_FAILURE			0xff
+#define CMD_STATUS_SCAN_FAILED			0xf0
+
+/* answers to get op mode */
+#define OPMODE_NONE				0x00
+#define OPMODE_NORMAL_NIC_WITH_FLASH		0x01
+#define OPMODE_HW_CONFIG_MODE			0x02
+#define OPMODE_DFU_MODE_WITH_FLASH		0x03
+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH		0x04
+
+#define CMD_SET_MIB		0x01
+#define CMD_GET_MIB		0x02
+#define CMD_SCAN		0x03
+#define CMD_JOIN		0x04
+#define CMD_START_IBSS		0x05
+#define CMD_RADIO_ON		0x06
+#define CMD_RADIO_OFF		0x07
+#define CMD_STARTUP		0x0B
+
+#define MIB_LOCAL		0x01
+#define MIB_MAC_ADDR		0x02
+#define MIB_MAC			0x03
+#define MIB_MAC_MGMT		0x05
+#define MIB_MAC_WEP		0x06
+#define MIB_PHY			0x07
+#define MIB_FW_VERSION		0x08
+#define MIB_MDOMAIN		0x09
+
+#define ADHOC_MODE		1
+#define INFRASTRUCTURE_MODE	2
+
+/* values for struct mib_local, field preamble_type */
+#define PREAMBLE_TYPE_LONG	0
+#define PREAMBLE_TYPE_SHORT	1
+#define PREAMBLE_TYPE_AUTO	2
+
+/* values for tx_rate */
+#define TX_RATE_1MBIT		0
+#define TX_RATE_2MBIT		1
+#define TX_RATE_5_5MBIT 	2
+#define TX_RATE_11MBIT		3
+#define TX_RATE_AUTO		4
+
+/* power management modes */
+#define AT76_PM_OFF		1
+#define AT76_PM_ON		2
+#define AT76_PM_SMART		3
+
+struct hwcfg_r505 {
+	u8 cr39_values[14];
+	u8 reserved1[14];
+	u8 bb_cr[14];
+	u8 pidvid[4];
+	u8 mac_addr[ETH_ALEN];
+	u8 regulatory_domain;
+	u8 reserved2[14];
+	u8 cr15_values[14];
+	u8 reserved3[3];
+} __attribute__((packed));
+
+struct hwcfg_rfmd {
+	u8 cr20_values[14];
+	u8 cr21_values[14];
+	u8 bb_cr[14];
+	u8 pidvid[4];
+	u8 mac_addr[ETH_ALEN];
+	u8 regulatory_domain;
+	u8 low_power_values[14];
+	u8 normal_power_values[14];
+	u8 reserved1[3];
+} __attribute__((packed));
+
+struct hwcfg_intersil {
+	u8 mac_addr[ETH_ALEN];
+	u8 cr31_values[14];
+	u8 cr58_values[14];
+	u8 pidvid[4];
+	u8 regulatory_domain;
+	u8 reserved[1];
+} __attribute__((packed));
+
+union at76_hwcfg {
+	struct hwcfg_intersil i;
+	struct hwcfg_rfmd r3;
+	struct hwcfg_r505 r5;
+};
+
+#define WEP_SMALL_KEY_LEN	(40 / 8)
+#define WEP_LARGE_KEY_LEN	(104 / 8)
+#define WEP_KEYS		(4)
+
+struct at76_card_config {
+	u8 exclude_unencrypted;
+	u8 promiscuous_mode;
+	u8 short_retry_limit;
+	u8 encryption_type;
+	__le16 rts_threshold;
+	__le16 fragmentation_threshold;	/* 256..2346 */
+	u8 basic_rate_set[4];
+	u8 auto_rate_fallback;	/* 0,1 */
+	u8 channel;
+	u8 privacy_invoked;
+	u8 wep_default_key_id;	/* 0..3 */
+	u8 current_ssid[32];
+	u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+	u8 ssid_len;
+	u8 short_preamble;
+	__le16 beacon_period;
+} __attribute__((packed));
+
+struct at76_command {
+	u8 cmd;
+	u8 reserved;
+	__le16 size;
+	u8 data[0];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Rx header before 802.11 frame */
+#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
+
+struct at76_rx_buffer {
+	__le16 wlength;
+	u8 rx_rate;
+	u8 newbss;
+	u8 fragmentation;
+	u8 rssi;
+	u8 link_quality;
+	u8 noise_level;
+	__le32 rx_time;
+	u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Tx header before 802.11 frame */
+#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
+
+struct at76_tx_buffer {
+	__le16 wlength;
+	u8 tx_rate;
+	u8 padding;
+	u8 reserved[4];
+	u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* defines for scan_type below */
+#define SCAN_TYPE_ACTIVE	0
+#define SCAN_TYPE_PASSIVE	1
+
+struct at76_req_scan {
+	u8 bssid[ETH_ALEN];
+	u8 essid[32];
+	u8 scan_type;
+	u8 channel;
+	__le16 probe_delay;
+	__le16 min_channel_time;
+	__le16 max_channel_time;
+	u8 essid_size;
+	u8 international_scan;
+} __attribute__((packed));
+
+struct at76_req_ibss {
+	u8 bssid[ETH_ALEN];
+	u8 essid[32];
+	u8 bss_type;
+	u8 channel;
+	u8 essid_size;
+	u8 reserved[3];
+} __attribute__((packed));
+
+struct at76_req_join {
+	u8 bssid[ETH_ALEN];
+	u8 essid[32];
+	u8 bss_type;
+	u8 channel;
+	__le16 timeout;
+	u8 essid_size;
+	u8 reserved;
+} __attribute__((packed));
+
+struct set_mib_buffer {
+	u8 type;
+	u8 size;
+	u8 index;
+	u8 reserved;
+	union {
+		u8 byte;
+		__le16 word;
+		u8 addr[ETH_ALEN];
+	} data;
+} __attribute__((packed));
+
+struct mib_local {
+	u16 reserved0;
+	u8 beacon_enable;
+	u8 txautorate_fallback;
+	u8 reserved1;
+	u8 ssid_size;
+	u8 promiscuous_mode;
+	u16 reserved2;
+	u8 preamble_type;
+	u16 reserved3;
+} __attribute__((packed));
+
+struct mib_mac_addr {
+	u8 mac_addr[ETH_ALEN];
+	u8 res[2];		/* ??? */
+	u8 group_addr[4][ETH_ALEN];
+	u8 group_addr_status[4];
+} __attribute__((packed));
+
+struct mib_mac {
+	__le32 max_tx_msdu_lifetime;
+	__le32 max_rx_lifetime;
+	__le16 frag_threshold;
+	__le16 rts_threshold;
+	__le16 cwmin;
+	__le16 cwmax;
+	u8 short_retry_time;
+	u8 long_retry_time;
+	u8 scan_type;		/* active or passive */
+	u8 scan_channel;
+	__le16 probe_delay;	/* delay before ProbeReq in active scan, RO */
+	__le16 min_channel_time;
+	__le16 max_channel_time;
+	__le16 listen_interval;
+	u8 desired_ssid[32];
+	u8 desired_bssid[ETH_ALEN];
+	u8 desired_bsstype;	/* ad-hoc or infrastructure */
+	u8 reserved2;
+} __attribute__((packed));
+
+struct mib_mac_mgmt {
+	__le16 beacon_period;
+	__le16 CFP_max_duration;
+	__le16 medium_occupancy_limit;
+	__le16 station_id;	/* assoc id */
+	__le16 ATIM_window;
+	u8 CFP_mode;
+	u8 privacy_option_implemented;
+	u8 DTIM_period;
+	u8 CFP_period;
+	u8 current_bssid[ETH_ALEN];
+	u8 current_essid[32];
+	u8 current_bss_type;
+	u8 power_mgmt_mode;
+	/* rfmd and 505 */
+	u8 ibss_change;
+	u8 res;
+	u8 multi_domain_capability_implemented;
+	u8 multi_domain_capability_enabled;
+	u8 country_string[3];
+	u8 reserved[3];
+} __attribute__((packed));
+
+struct mib_mac_wep {
+	u8 privacy_invoked;	/* 0 disable encr., 1 enable encr */
+	u8 wep_default_key_id;
+	u8 wep_key_mapping_len;
+	u8 exclude_unencrypted;
+	__le32 wep_icv_error_count;
+	__le32 wep_excluded_count;
+	u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+	u8 encryption_level;	/* 1 for 40bit, 2 for 104bit encryption */
+} __attribute__((packed));
+
+struct mib_phy {
+	__le32 ed_threshold;
+
+	__le16 slot_time;
+	__le16 sifs_time;
+	__le16 preamble_length;
+	__le16 plcp_header_length;
+	__le16 mpdu_max_length;
+	__le16 cca_mode_supported;
+
+	u8 operation_rate_set[4];
+	u8 channel_id;
+	u8 current_cca_mode;
+	u8 phy_type;
+	u8 current_reg_domain;
+} __attribute__((packed));
+
+struct mib_fw_version {
+	u8 major;
+	u8 minor;
+	u8 patch;
+	u8 build;
+} __attribute__((packed));
+
+struct mib_mdomain {
+	u8 tx_powerlevel[14];
+	u8 channel_list[14];	/* 0 for invalid channels */
+} __attribute__((packed));
+
+struct at76_fw_header {
+	__le32 crc;		/* CRC32 of the whole image */
+	__le32 board_type;	/* firmware compatibility code */
+	u8 build;		/* firmware build number */
+	u8 patch;		/* firmware patch level */
+	u8 minor;		/* firmware minor version */
+	u8 major;		/* firmware major version */
+	__le32 str_offset;	/* offset of the copyright string */
+	__le32 int_fw_offset;	/* internal firmware image offset */
+	__le32 int_fw_len;	/* internal firmware image length */
+	__le32 ext_fw_offset;	/* external firmware image offset */
+	__le32 ext_fw_len;	/* external firmware image length */
+} __attribute__((packed));
+
+/* a description of a regulatory domain and the allowed channels */
+struct reg_domain {
+	u16 code;
+	char const *name;
+	u32 channel_map;	/* if bit N is set, channel (N+1) is allowed */
+};
+
+/* Data for one loaded firmware file */
+struct fwentry {
+	const char *const fwname;
+	const struct firmware *fw;
+	int extfw_size;
+	int intfw_size;
+	/* pointer to loaded firmware, no need to free */
+	u8 *extfw;		/* external firmware, extfw_size bytes long */
+	u8 *intfw;		/* internal firmware, intfw_size bytes long */
+	enum board_type board_type;	/* board type */
+	struct mib_fw_version fw_version;
+	int loaded;		/* Loaded and parsed successfully */
+};
+
+struct at76_priv {
+	struct usb_device *udev;	/* USB device pointer */
+
+	struct sk_buff *rx_skb;	/* skbuff for receiving data */
+	struct sk_buff *tx_skb;	/* skbuff for transmitting data */
+	void *bulk_out_buffer;	/* buffer for sending data */
+
+	struct urb *tx_urb;	/* URB for sending data */
+	struct urb *rx_urb;	/* URB for receiving data */
+
+	unsigned int tx_pipe;	/* bulk out pipe */
+	unsigned int rx_pipe;	/* bulk in pipe */
+
+	struct mutex mtx;	/* locks this structure */
+
+	/* work queues */
+	struct work_struct work_set_promisc;
+	struct work_struct work_submit_rx;
+	struct delayed_work dwork_hw_scan;
+
+	struct tasklet_struct rx_tasklet;
+
+	/* the WEP stuff */
+	int wep_enabled;	/* 1 if WEP is enabled */
+	int wep_key_id;		/* key id to be used */
+	u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN];	/* WEP keys */
+	u8 wep_keys_len[WEP_KEYS];	/* length of WEP keys */
+
+	int channel;
+	int iw_mode;
+	u8 bssid[ETH_ALEN];
+	u8 essid[IW_ESSID_MAX_SIZE];
+	int essid_size;
+	int radio_on;
+	int promisc;
+
+	int preamble_type;	/* 0 - long, 1 - short, 2 - auto */
+	int auth_mode;		/* authentication type: 0 open, 1 shared key */
+	int txrate;		/* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
+	int frag_threshold;	/* threshold for fragmentation of tx packets */
+	int rts_threshold;	/* threshold for RTS mechanism */
+	int short_retry_limit;
+
+	int scan_min_time;	/* scan min channel time */
+	int scan_max_time;	/* scan max channel time */
+	int scan_mode;		/* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
+	int scan_need_any;	/* if set, need to scan for any ESSID */
+
+	u16 assoc_id;		/* current association ID, if associated */
+
+	u8 pm_mode;		/* power management mode */
+	u32 pm_period;		/* power management period in microseconds */
+
+	struct reg_domain const *domain;	/* reg domain description */
+
+	/* These fields contain HW config provided by the device (not all of
+	 * these fields are used by all board types) */
+	u8 mac_addr[ETH_ALEN];
+	u8 regulatory_domain;
+
+	struct at76_card_config card_config;
+
+	enum board_type board_type;
+	struct mib_fw_version fw_version;
+
+	unsigned int device_unplugged:1;
+	unsigned int netdev_registered:1;
+	struct set_mib_buffer mib_buf;	/* global buffer for set_mib calls */
+
+	int beacon_period;	/* period of mgmt beacons, Kus */
+
+	struct ieee80211_hw *hw;
+	int mac80211_registered;
+};
+
+#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+
+#define SCAN_POLL_INTERVAL	(HZ / 4)
+
+#define CMD_COMPLETION_TIMEOUT	(5 * HZ)
+
+#define DEF_RTS_THRESHOLD	1536
+#define DEF_FRAG_THRESHOLD	1536
+#define DEF_SHORT_RETRY_LIMIT	8
+#define DEF_CHANNEL		10
+#define DEF_SCAN_MIN_TIME	10
+#define DEF_SCAN_MAX_TIME	120
+
+/* the max padding size for tx in bytes (see calc_padding) */
+#define MAX_PADDING_SIZE	53
+
+#endif				/* _AT76_USB_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/ath5k.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/ath5k.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/ath5k.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/ath5k.h	2009-06-09 23:05:27.000000000 -0400
@@ -165,9 +165,6 @@
 #define AR5K_INI_VAL_XR			0
 #define AR5K_INI_VAL_MAX		5
 
-#define AR5K_RF5111_INI_RF_MAX_BANKS	AR5K_MAX_RF_BANKS
-#define AR5K_RF5112_INI_RF_MAX_BANKS	AR5K_MAX_RF_BANKS
-
 /* Used for BSSID etc manipulation */
 #define AR5K_LOW_ID(_a)(				\
 (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24	\
@@ -207,9 +204,9 @@
 #define AR5K_TUNE_CWMAX_11B			1023
 #define AR5K_TUNE_CWMAX_XR			7
 #define AR5K_TUNE_NOISE_FLOOR			-72
-#define AR5K_TUNE_MAX_TXPOWER			60
-#define AR5K_TUNE_DEFAULT_TXPOWER		30
-#define AR5K_TUNE_TPC_TXPOWER			true
+#define AR5K_TUNE_MAX_TXPOWER			63
+#define AR5K_TUNE_DEFAULT_TXPOWER		25
+#define AR5K_TUNE_TPC_TXPOWER			false
 #define AR5K_TUNE_ANT_DIVERSITY			true
 #define AR5K_TUNE_HWTXTRIES			4
 
@@ -225,6 +222,7 @@
 #endif
 
 /* Initial values */
+#define	AR5K_INIT_CYCRSSI_THR1			2
 #define AR5K_INIT_TX_LATENCY			502
 #define AR5K_INIT_USEC				39
 #define AR5K_INIT_USEC_TURBO			79
@@ -316,7 +314,7 @@ struct ath5k_srev_name {
 #define AR5K_SREV_AR5424	0x90 /* Condor */
 #define AR5K_SREV_AR5413	0xa4 /* Eagle lite */
 #define AR5K_SREV_AR5414	0xa0 /* Eagle */
-#define AR5K_SREV_AR2415	0xb0 /* Cobra */
+#define AR5K_SREV_AR2415	0xb0 /* Talon */
 #define AR5K_SREV_AR5416	0xc0 /* PCI-E */
 #define AR5K_SREV_AR5418	0xca /* PCI-E */
 #define AR5K_SREV_AR2425	0xe0 /* Swan */
@@ -334,7 +332,7 @@ struct ath5k_srev_name {
 #define	AR5K_SREV_RAD_2112B	0x46
 #define AR5K_SREV_RAD_2413	0x50
 #define AR5K_SREV_RAD_5413	0x60
-#define AR5K_SREV_RAD_2316	0x70
+#define AR5K_SREV_RAD_2316	0x70 /* Cobra SoC */
 #define AR5K_SREV_RAD_2317	0x80
 #define AR5K_SREV_RAD_5424	0xa0 /* Mostly same as 5413 */
 #define AR5K_SREV_RAD_2425	0xa2
@@ -342,7 +340,8 @@ struct ath5k_srev_name {
 
 #define AR5K_SREV_PHY_5211	0x30
 #define AR5K_SREV_PHY_5212	0x41
-#define AR5K_SREV_PHY_2112B	0x43
+#define	AR5K_SREV_PHY_5212A	0x42
+#define AR5K_SREV_PHY_5212B	0x43
 #define AR5K_SREV_PHY_2413	0x45
 #define AR5K_SREV_PHY_5413	0x61
 #define AR5K_SREV_PHY_2425	0x70
@@ -552,11 +551,11 @@ enum ath5k_pkt_type {
  */
 #define AR5K_TXPOWER_OFDM(_r, _v)	(			\
 	((0 & 1) << ((_v) + 6)) |				\
-	(((ah->ah_txpower.txp_rates[(_r)]) & 0x3f) << (_v))	\
+	(((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v))	\
 )
 
 #define AR5K_TXPOWER_CCK(_r, _v)	(			\
-	(ah->ah_txpower.txp_rates[(_r)] & 0x3f) << (_v)	\
+	(ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v)	\
 )
 
 /*
@@ -649,49 +648,21 @@ struct ath5k_beacon_state {
 
 enum ath5k_rfgain {
 	AR5K_RFGAIN_INACTIVE = 0,
+	AR5K_RFGAIN_ACTIVE,
 	AR5K_RFGAIN_READ_REQUESTED,
 	AR5K_RFGAIN_NEED_CHANGE,
 };
 
-#define AR5K_GAIN_CRN_FIX_BITS_5111		4
-#define AR5K_GAIN_CRN_FIX_BITS_5112		7
-#define AR5K_GAIN_CRN_MAX_FIX_BITS		AR5K_GAIN_CRN_FIX_BITS_5112
-#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN		15
-#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN		20
-#define AR5K_GAIN_CCK_PROBE_CORR		5
-#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA		15
-#define AR5K_GAIN_STEP_COUNT			10
-#define AR5K_GAIN_PARAM_TX_CLIP			0
-#define AR5K_GAIN_PARAM_PD_90			1
-#define AR5K_GAIN_PARAM_PD_84			2
-#define AR5K_GAIN_PARAM_GAIN_SEL		3
-#define AR5K_GAIN_PARAM_MIX_ORN			0
-#define AR5K_GAIN_PARAM_PD_138			1
-#define AR5K_GAIN_PARAM_PD_137			2
-#define AR5K_GAIN_PARAM_PD_136			3
-#define AR5K_GAIN_PARAM_PD_132			4
-#define AR5K_GAIN_PARAM_PD_131			5
-#define AR5K_GAIN_PARAM_PD_130			6
-#define AR5K_GAIN_CHECK_ADJUST(_g) 		\
-	((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
-
-struct ath5k_gain_opt_step {
-	s16				gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
-	s32				gos_gain;
-};
-
 struct ath5k_gain {
-	u32			g_step_idx;
-	u32			g_current;
-	u32			g_target;
-	u32			g_low;
-	u32			g_high;
-	u32			g_f_corr;
-	u32			g_active;
-	const struct ath5k_gain_opt_step	*g_step;
+	u8			g_step_idx;
+	u8			g_current;
+	u8			g_target;
+	u8			g_low;
+	u8			g_high;
+	u8			g_f_corr;
+	u8			g_state;
 };
 
-
 /********************\
   COMMON DEFINITIONS
 \********************/
@@ -1053,7 +1024,6 @@ struct ath5k_hw {
 	bool			ah_running;
 	bool			ah_single_chip;
 	bool			ah_combined_mic;
-	enum ath5k_rfgain	ah_rf_gain;
 
 	u32			ah_mac_srev;
 	u16			ah_mac_version;
@@ -1061,7 +1031,6 @@ struct ath5k_hw {
 	u16			ah_phy_revision;
 	u16			ah_radio_5ghz_revision;
 	u16			ah_radio_2ghz_revision;
-	u32			ah_phy_spending;
 
 	enum ath5k_version	ah_version;
 	enum ath5k_radio	ah_radio;
@@ -1112,16 +1081,29 @@ struct ath5k_hw {
 	u32			ah_txq_isr;
 	u32			*ah_rf_banks;
 	size_t			ah_rf_banks_size;
+	size_t			ah_rf_regs_count;
 	struct ath5k_gain	ah_gain;
-	u32			ah_offset[AR5K_MAX_RF_BANKS];
+	u8			ah_offset[AR5K_MAX_RF_BANKS];
+
 
 	struct {
-		u16		txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
-		u16		txp_rates[AR5K_MAX_RATES];
-		s16		txp_min;
-		s16		txp_max;
+		/* Temporary tables used for interpolation */
+		u8		tmpL[AR5K_EEPROM_N_PD_GAINS]
+					[AR5K_EEPROM_POWER_TABLE_SIZE];
+		u8		tmpR[AR5K_EEPROM_N_PD_GAINS]
+					[AR5K_EEPROM_POWER_TABLE_SIZE];
+		u8		txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
+		u16		txp_rates_power_table[AR5K_MAX_RATES];
+		u8		txp_min_idx;
 		bool		txp_tpc;
+		/* Values in 0.25dB units */
+		s16		txp_min_pwr;
+		s16		txp_max_pwr;
+		s16		txp_offset;
 		s16		txp_ofdm;
+		/* Values in dB units */
+		s16		txp_cck_ofdm_pwr_delta;
+		s16		txp_cck_ofdm_gainf_delta;
 	} ah_txpower;
 
 	struct {
@@ -1159,6 +1141,12 @@ struct ath5k_hw {
 extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
 extern void ath5k_hw_detach(struct ath5k_hw *ah);
 
+/* LED functions */
+extern int ath5k_init_leds(struct ath5k_softc *sc);
+extern void ath5k_led_enable(struct ath5k_softc *sc);
+extern void ath5k_led_off(struct ath5k_softc *sc);
+extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
 /* Reset Functions */
 extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
 extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
@@ -1185,7 +1173,9 @@ extern void ath5k_hw_update_mib_counters
 
 /* EEPROM access functions */
 extern int ath5k_eeprom_init(struct ath5k_hw *ah);
+extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
 extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
 
 /* Protocol Control Unit Functions */
 extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
@@ -1206,6 +1196,7 @@ extern void ath5k_hw_set_rx_filter(struc
 /* Beacon control functions */
 extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
 extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
+extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
 extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
 extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
 #if 0
@@ -1260,10 +1251,12 @@ extern int ath5k_hw_disable_pspoll(struc
 extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
 
 /* Initialize RF */
-extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
-extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
-extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
-extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
+extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+				struct ieee80211_channel *channel,
+				unsigned int mode);
+extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
+extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
 /* PHY/RF channel functions */
 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);
@@ -1276,8 +1269,8 @@ extern void ath5k_hw_set_def_antenna(str
 extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
 extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
 /* TX power setup */
-extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
+extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
 
 /*
  * Functions used internaly
@@ -1285,6 +1278,7 @@ extern int ath5k_hw_set_txpower_limit(st
 
 /*
  * Translate usec to hw clock units
+ * TODO: Half/quarter rate
  */
 static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
 {
@@ -1293,6 +1287,7 @@ static inline unsigned int ath5k_hw_htoc
 
 /*
  * Translate hw clock units to usec
+ * TODO: Half/quarter rate
  */
 static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/attach.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/attach.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/attach.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/attach.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,14 +34,14 @@
 static int ath5k_hw_post(struct ath5k_hw *ah)
 {
 
-	int i, c;
-	u16 cur_reg;
-	u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
-	u32 var_pattern;
-	u32 static_pattern[4] = {
+	static const u32 static_pattern[4] = {
 		0x55555555,	0xaaaaaaaa,
 		0x66666666,	0x99999999
 	};
+	static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
+	int i, c;
+	u16 cur_reg;
+	u32 var_pattern;
 	u32 init_val;
 	u32 cur_val;
 
@@ -106,7 +106,6 @@ struct ath5k_hw *ath5k_hw_attach(struct
 {
 	struct ath5k_hw *ah;
 	struct pci_dev *pdev = sc->pdev;
-	u8 mac[ETH_ALEN] = {};
 	int ret;
 	u32 srev;
 
@@ -169,7 +168,6 @@ struct ath5k_hw *ath5k_hw_attach(struct
 		ah->ah_single_chip = false;
 		ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
 							CHANNEL_2GHZ);
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
 		break;
 	case AR5K_SREV_RAD_5112:
 	case AR5K_SREV_RAD_2112:
@@ -177,38 +175,31 @@ struct ath5k_hw *ath5k_hw_attach(struct
 		ah->ah_single_chip = false;
 		ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
 							CHANNEL_2GHZ);
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
 		break;
 	case AR5K_SREV_RAD_2413:
 		ah->ah_radio = AR5K_RF2413;
 		ah->ah_single_chip = true;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
 		break;
 	case AR5K_SREV_RAD_5413:
 		ah->ah_radio = AR5K_RF5413;
 		ah->ah_single_chip = true;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
 		break;
 	case AR5K_SREV_RAD_2316:
 		ah->ah_radio = AR5K_RF2316;
 		ah->ah_single_chip = true;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
 		break;
 	case AR5K_SREV_RAD_2317:
 		ah->ah_radio = AR5K_RF2317;
 		ah->ah_single_chip = true;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
 		break;
 	case AR5K_SREV_RAD_5424:
 		if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
 		ah->ah_mac_version == AR5K_SREV_AR2417){
 			ah->ah_radio = AR5K_RF2425;
 			ah->ah_single_chip = true;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
 		} else {
 			ah->ah_radio = AR5K_RF5413;
 			ah->ah_single_chip = true;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
 		}
 		break;
 	default:
@@ -227,29 +218,25 @@ struct ath5k_hw *ath5k_hw_attach(struct
 			ah->ah_radio = AR5K_RF2425;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
 		} else if (srev == AR5K_SREV_AR5213A &&
-		ah->ah_phy_revision == AR5K_SREV_PHY_2112B) {
+		ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
 			ah->ah_radio = AR5K_RF5112;
 			ah->ah_single_chip = false;
-			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B;
+			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
 			ah->ah_radio = AR5K_RF2316;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
 		ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
 			ah->ah_radio = AR5K_RF5413;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
 		} else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
 		ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
 			ah->ah_radio = AR5K_RF2413;
 			ah->ah_single_chip = true;
 			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
 		} else {
 			ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
 			ret = -ENODEV;
@@ -324,14 +311,14 @@ struct ath5k_hw *ath5k_hw_attach(struct
 	}
 
 	/* MAC address is cleared until add_interface */
-	ath5k_hw_set_lladdr(ah, mac);
+	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);
 	ath5k_hw_set_opmode(ah);
 
-	ath5k_hw_set_rfgain_opt(ah);
+	ath5k_hw_rfgain_opt_init(ah);
 
 	return ah;
 err_free:
@@ -354,6 +341,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah
 	if (ah->ah_rf_banks != NULL)
 		kfree(ah->ah_rf_banks);
 
+	ath5k_eeprom_detach(ah);
+
 	/* assume interrupts are down */
 	kfree(ah);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/base.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.c	2009-06-09 23:05:27.000000000 -0400
@@ -79,7 +79,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
 
 
 /* Known PCI ids */
-static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
+static const struct pci_device_id ath5k_pci_id_table[] = {
 	{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
 	{ PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
 	{ PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
@@ -103,7 +103,7 @@ static struct pci_device_id ath5k_pci_id
 MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
 
 /* Known SREVs */
-static struct ath5k_srev_name srev_names[] = {
+static const struct ath5k_srev_name srev_names[] = {
 	{ "5210",	AR5K_VERSION_MAC,	AR5K_SREV_AR5210 },
 	{ "5311",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311 },
 	{ "5311A",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311A },
@@ -142,7 +142,7 @@ static struct ath5k_srev_name srev_names
 	{ "xxxxx",	AR5K_VERSION_RAD,	AR5K_SREV_UNKNOWN },
 };
 
-static struct ieee80211_rate ath5k_rates[] = {
+static const struct ieee80211_rate ath5k_rates[] = {
 	{ .bitrate = 10,
 	  .hw_value = ATH5K_RATE_CODE_1M, },
 	{ .bitrate = 20,
@@ -214,7 +214,7 @@ static struct pci_driver ath5k_pci_drive
  * Prototypes - MAC 802.11 stack related functions
  */
 static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
 static int ath5k_reset_wake(struct ath5k_softc *sc);
 static int ath5k_start(struct ieee80211_hw *hw);
 static void ath5k_stop(struct ieee80211_hw *hw);
@@ -232,13 +232,14 @@ static void ath5k_configure_filter(struc
 		int mc_count, struct dev_mc_list *mclist);
 static int ath5k_set_key(struct ieee80211_hw *hw,
 		enum set_key_cmd cmd,
-		const u8 *local_addr, const u8 *addr,
+		struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 		struct ieee80211_key_conf *key);
 static int ath5k_get_stats(struct ieee80211_hw *hw,
 		struct ieee80211_low_level_stats *stats);
 static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
 		struct ieee80211_tx_queue_stats *stats);
 static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
 static void ath5k_reset_tsf(struct ieee80211_hw *hw);
 static int ath5k_beacon_update(struct ath5k_softc *sc,
 		struct sk_buff *skb);
@@ -247,7 +248,7 @@ static void ath5k_bss_info_changed(struc
 		struct ieee80211_bss_conf *bss_conf,
 		u32 changes);
 
-static struct ieee80211_ops ath5k_hw_ops = {
+static const struct ieee80211_ops ath5k_hw_ops = {
 	.tx 		= ath5k_tx,
 	.start 		= ath5k_start,
 	.stop 		= ath5k_stop,
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops
 	.conf_tx 	= NULL,
 	.get_tx_stats 	= ath5k_get_tx_stats,
 	.get_tsf 	= ath5k_get_tsf,
+	.set_tsf 	= ath5k_set_tsf,
 	.reset_tsf 	= ath5k_reset_tsf,
 	.bss_info_changed = ath5k_bss_info_changed,
 };
@@ -308,6 +310,19 @@ static inline void ath5k_txbuf_free(stru
 	bf->skb = NULL;
 }
 
+static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
+				struct ath5k_buf *bf)
+{
+	BUG_ON(!bf);
+	if (!bf->skb)
+		return;
+	pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+			PCI_DMA_FROMDEVICE);
+	dev_kfree_skb_any(bf->skb);
+	bf->skb = NULL;
+}
+
+
 /* Queues setup */
 static struct 	ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
 				int qtype, int subtype);
@@ -335,6 +350,7 @@ static int 	ath5k_beacon_setup(struct at
 static void 	ath5k_beacon_send(struct ath5k_softc *sc);
 static void 	ath5k_beacon_config(struct ath5k_softc *sc);
 static void	ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+static void	ath5k_tasklet_beacon(unsigned long data);
 
 static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
 {
@@ -347,18 +363,13 @@ static inline u64 ath5k_extend_tsf(struc
 }
 
 /* Interrupt handling */
-static int 	ath5k_init(struct ath5k_softc *sc, bool is_resume);
+static int 	ath5k_init(struct ath5k_softc *sc);
 static int 	ath5k_stop_locked(struct ath5k_softc *sc);
-static int 	ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
+static int 	ath5k_stop_hw(struct ath5k_softc *sc);
 static irqreturn_t ath5k_intr(int irq, void *dev_id);
 static void 	ath5k_tasklet_reset(unsigned long data);
 
 static void 	ath5k_calibrate(unsigned long data);
-/* LED functions */
-static int	ath5k_init_leds(struct ath5k_softc *sc);
-static void	ath5k_led_enable(struct ath5k_softc *sc);
-static void	ath5k_led_off(struct ath5k_softc *sc);
-static void	ath5k_unregister_leds(struct ath5k_softc *sc);
 
 /*
  * Module init/exit functions
@@ -434,7 +445,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	}
 
 	/* XXX 32-bit addressing only */
-	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(&pdev->dev, "32-bit DMA not available\n");
 		goto err_dis;
@@ -653,8 +664,6 @@ ath5k_pci_suspend(struct pci_dev *pdev,
 
 	ath5k_led_off(sc);
 
-	ath5k_stop_hw(sc, true);
-
 	free_irq(pdev->irq, sc);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
@@ -676,27 +685,15 @@ ath5k_pci_resume(struct pci_dev *pdev)
 	if (err)
 		return err;
 
-	/*
-	 * Suspend/Resume resets the PCI configuration space, so we have to
-	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
-	 * PCI Tx retries from interfering with C3 CPU state
-	 */
-	pci_write_config_byte(pdev, 0x41, 0);
-
 	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
 	if (err) {
 		ATH5K_ERR(sc, "request_irq failed\n");
 		goto err_no_irq;
 	}
 
-	err = ath5k_init(sc, true);
-	if (err)
-		goto err_irq;
 	ath5k_led_enable(sc);
-
 	return 0;
-err_irq:
-	free_irq(pdev->irq, sc);
+
 err_no_irq:
 	pci_disable_device(pdev);
 	return err;
@@ -781,6 +778,7 @@ ath5k_attach(struct pci_dev *pdev, struc
 	tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
 	tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
 	tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+	tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
 	setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
 
 	ret = ath5k_eeprom_read_mac(ah, mac);
@@ -1040,16 +1038,13 @@ ath5k_chan_set(struct ath5k_softc *sc, s
 	if (chan->center_freq != sc->curchan->center_freq ||
 		chan->hw_value != sc->curchan->hw_value) {
 
-		sc->curchan = chan;
-		sc->curband = &sc->sbands[chan->band];
-
 		/*
 		 * To switch channels clear any pending DMA operations;
 		 * wait long enough for the RX fifo to drain, reset the
 		 * hardware at the new frequency, and then re-enable
 		 * the relevant bits of the h/w.
 		 */
-		return ath5k_reset(sc, true, true);
+		return ath5k_reset(sc, chan);
 	}
 
 	return 0;
@@ -1090,8 +1085,18 @@ ath5k_mode_setup(struct ath5k_softc *sc)
 static inline int
 ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
 {
-	WARN_ON(hw_rix < 0 || hw_rix > AR5K_MAX_RATES);
-	return sc->rate_idx[sc->curband->band][hw_rix];
+	int rix;
+
+	/* return base rate on errors */
+	if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+			"hw_rix out of bounds: %x\n", hw_rix))
+		return 0;
+
+	rix = sc->rate_idx[sc->curband->band][hw_rix];
+	if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
+		rix = 0;
+
+	return rix;
 }
 
 /***************\
@@ -1188,6 +1193,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc
 	struct ieee80211_rate *rate;
 	unsigned int mrr_rate[3], mrr_tries[3];
 	int i, ret;
+	u16 hw_rate;
+	u16 cts_rate = 0;
+	u16 duration = 0;
+	u8 rc_flags;
 
 	flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
 
@@ -1195,20 +1204,42 @@ ath5k_txbuf_setup(struct ath5k_softc *sc
 	bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
 			PCI_DMA_TODEVICE);
 
+	rate = ieee80211_get_tx_rate(sc->hw, info);
+
 	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
 		flags |= AR5K_TXDESC_NOACK;
 
+	rc_flags = info->control.rates[0].flags;
+	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+		rate->hw_value_short : rate->hw_value;
+
 	pktlen = skb->len;
 
+	/* FIXME: If we are in g mode and rate is a CCK rate
+	 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+	 * from tx power (value is in dB units already) */
 	if (info->control.hw_key) {
 		keyidx = info->control.hw_key->hw_key_idx;
 		pktlen += info->control.hw_key->icv_len;
 	}
+	if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+		flags |= AR5K_TXDESC_RTSENA;
+		cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+		duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+			sc->vif, pktlen, info));
+	}
+	if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+		flags |= AR5K_TXDESC_CTSENA;
+		cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+		duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+			sc->vif, pktlen, info));
+	}
 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
 		ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
 		(sc->power_level * 2),
-		ieee80211_get_tx_rate(sc->hw, info)->hw_value,
-		info->control.rates[0].count, keyidx, 0, flags, 0, 0);
+		hw_rate,
+		info->control.rates[0].count, keyidx, 0, flags,
+		cts_rate, duration);
 	if (ret)
 		goto err_unmap;
 
@@ -1324,7 +1355,7 @@ ath5k_desc_free(struct ath5k_softc *sc,
 	list_for_each_entry(bf, &sc->txbuf, list)
 		ath5k_txbuf_free(sc, bf);
 	list_for_each_entry(bf, &sc->rxbuf, list)
-		ath5k_txbuf_free(sc, bf);
+		ath5k_rxbuf_free(sc, bf);
 
 	/* Free memory associated with all descriptors */
 	pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -1668,6 +1699,34 @@ ath5k_check_ibss_tsf(struct ath5k_softc
 	}
 }
 
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+	struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+	/*
+	 * Software beacon alert--time to send a beacon.
+	 *
+	 * In IBSS mode we use this interrupt just to
+	 * keep track of the next TBTT (target beacon
+	 * transmission time) in order to detect wether
+	 * automatic TSF updates happened.
+	 */
+	if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+		/* XXX: only if VEOL suppported */
+		u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+		sc->nexttbtt += sc->bintval;
+		ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+				"SWBA nexttbtt: %x hw_tu: %x "
+				"TSF: %llx\n",
+				sc->nexttbtt,
+				TSF_TO_TU(tsf),
+				(unsigned long long) tsf);
+	} else {
+		spin_lock(&sc->block);
+		ath5k_beacon_send(sc);
+		spin_unlock(&sc->block);
+	}
+}
 
 static void
 ath5k_tasklet_rx(unsigned long data)
@@ -1987,6 +2046,9 @@ ath5k_beacon_setup(struct ath5k_softc *s
 			antenna = sc->bsent & 4 ? 2 : 1;
 	}
 
+	/* FIXME: If we are in g mode and rate is a CCK rate
+	 * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+	 * from tx power (value is in dB units already) */
 	ds->ds_data = bf->skbaddr;
 	ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
 			ieee80211_get_hdrlen_from_skb(skb),
@@ -2008,9 +2070,8 @@ err_unmap:
  * frame contents are done as needed and the slot time is
  * also adjusted based on current state.
  *
- * this is usually called from interrupt context (ath5k_intr())
- * but also from ath5k_beacon_config() in IBSS mode which in turn
- * can be called from a tasklet and user context
+ * This is called from software irq context (beacontq or restq
+ * tasklets) or user context from ath5k_beacon_config.
  */
 static void
 ath5k_beacon_send(struct ath5k_softc *sc)
@@ -2177,10 +2238,6 @@ ath5k_beacon_update_timers(struct ath5k_
  *
  * @sc: struct ath5k_softc pointer we are operating on
  *
- * When operating in station mode we want to receive a BMISS interrupt when we
- * stop seeing beacons from the AP we've associated with so we can look for
- * another AP to associate with.
- *
  * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
  * interrupts to detect TSF updates only.
  */
@@ -2188,14 +2245,13 @@ static void
 ath5k_beacon_config(struct ath5k_softc *sc)
 {
 	struct ath5k_hw *ah = sc->ah;
+	unsigned long flags;
 
 	ath5k_hw_set_imr(ah, 0);
 	sc->bmisscount = 0;
 	sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
-	if (sc->opmode == NL80211_IFTYPE_STATION) {
-		sc->imask |= AR5K_INT_BMISS;
-	} else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+	if (sc->opmode == NL80211_IFTYPE_ADHOC ||
 			sc->opmode == NL80211_IFTYPE_MESH_POINT ||
 			sc->opmode == NL80211_IFTYPE_AP) {
 		/*
@@ -2211,9 +2267,9 @@ ath5k_beacon_config(struct ath5k_softc *
 
 		if (sc->opmode == NL80211_IFTYPE_ADHOC) {
 			if (ath5k_hw_hasveol(ah)) {
-				spin_lock(&sc->block);
+				spin_lock_irqsave(&sc->block, flags);
 				ath5k_beacon_send(sc);
-				spin_unlock(&sc->block);
+				spin_unlock_irqrestore(&sc->block, flags);
 			}
 		} else
 			ath5k_beacon_update_timers(sc, -1);
@@ -2228,18 +2284,13 @@ ath5k_beacon_config(struct ath5k_softc *
 \********************/
 
 static int
-ath5k_init(struct ath5k_softc *sc, bool is_resume)
+ath5k_init(struct ath5k_softc *sc)
 {
 	struct ath5k_hw *ah = sc->ah;
 	int ret, i;
 
 	mutex_lock(&sc->lock);
 
-	if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
-		goto out_ok;
-
-	__clear_bit(ATH_STAT_STARTED, sc->status);
-
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
 
 	/*
@@ -2259,8 +2310,8 @@ ath5k_init(struct ath5k_softc *sc, bool
 	sc->curband = &sc->sbands[sc->curchan->band];
 	sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
 		AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
-		AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
-	ret = ath5k_reset(sc, false, false);
+		AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+	ret = ath5k_reset(sc, NULL);
 	if (ret)
 		goto done;
 
@@ -2271,15 +2322,12 @@ ath5k_init(struct ath5k_softc *sc, bool
 	for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
 		ath5k_hw_reset_key(ah, i);
 
-	__set_bit(ATH_STAT_STARTED, sc->status);
-
 	/* Set ack to be sent at low bit-rates */
 	ath5k_hw_set_ack_bitrate_high(ah, false);
 
 	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
 			msecs_to_jiffies(ath5k_calinterval * 1000)));
 
-out_ok:
 	ret = 0;
 done:
 	mmiowb();
@@ -2334,7 +2382,7 @@ ath5k_stop_locked(struct ath5k_softc *sc
  * stop is preempted).
  */
 static int
-ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
+ath5k_stop_hw(struct ath5k_softc *sc)
 {
 	int ret;
 
@@ -2365,8 +2413,6 @@ ath5k_stop_hw(struct ath5k_softc *sc, bo
 		}
 	}
 	ath5k_txbuf_free(sc, sc->bbuf);
-	if (!is_suspend)
-		__clear_bit(ATH_STAT_STARTED, sc->status);
 
 	mmiowb();
 	mutex_unlock(&sc->lock);
@@ -2375,6 +2421,7 @@ ath5k_stop_hw(struct ath5k_softc *sc, bo
 	tasklet_kill(&sc->rxtq);
 	tasklet_kill(&sc->txtq);
 	tasklet_kill(&sc->restq);
+	tasklet_kill(&sc->beacontq);
 
 	return ret;
 }
@@ -2392,16 +2439,9 @@ ath5k_intr(int irq, void *dev_id)
 		return IRQ_NONE;
 
 	do {
-		/*
-		 * Figure out the reason(s) for the interrupt.  Note
-		 * that get_isr returns a pseudo-ISR that may include
-		 * bits we haven't explicitly enabled so we mask the
-		 * value to insure we only process bits we requested.
-		 */
 		ath5k_hw_get_isr(ah, &status);		/* NB: clears IRQ too */
 		ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
 				status, sc->imask);
-		status &= sc->imask; /* discard unasked for bits */
 		if (unlikely(status & AR5K_INT_FATAL)) {
 			/*
 			 * Fatal errors are unrecoverable.
@@ -2412,32 +2452,7 @@ ath5k_intr(int irq, void *dev_id)
 			tasklet_schedule(&sc->restq);
 		} else {
 			if (status & AR5K_INT_SWBA) {
-				/*
-				* Software beacon alert--time to send a beacon.
-				* Handle beacon transmission directly; deferring
-				* this is too slow to meet timing constraints
-				* under load.
-				*
-				* In IBSS mode we use this interrupt just to
-				* keep track of the next TBTT (target beacon
-				* transmission time) in order to detect wether
-				* automatic TSF updates happened.
-				*/
-				if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-					 /* XXX: only if VEOL suppported */
-					u64 tsf = ath5k_hw_get_tsf64(ah);
-					sc->nexttbtt += sc->bintval;
-					ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-						  "SWBA nexttbtt: %x hw_tu: %x "
-						  "TSF: %llx\n",
-						  sc->nexttbtt,
-						  TSF_TO_TU(tsf),
-						  (unsigned long long) tsf);
-				} else {
-					spin_lock(&sc->block);
-					ath5k_beacon_send(sc);
-					spin_unlock(&sc->block);
-				}
+				tasklet_schedule(&sc->beacontq);
 			}
 			if (status & AR5K_INT_RXEOL) {
 				/*
@@ -2457,6 +2472,7 @@ ath5k_intr(int irq, void *dev_id)
 					| AR5K_INT_TXERR | AR5K_INT_TXEOL))
 				tasklet_schedule(&sc->txtq);
 			if (status & AR5K_INT_BMISS) {
+				/* TODO */
 			}
 			if (status & AR5K_INT_MIB) {
 				/*
@@ -2496,7 +2512,7 @@ ath5k_calibrate(unsigned long data)
 		ieee80211_frequency_to_channel(sc->curchan->center_freq),
 		sc->curchan->hw_value);
 
-	if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+	if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
 		/*
 		 * Rfgain is out of bounds, reset the chip
 		 * to load new gain values.
@@ -2514,130 +2530,6 @@ ath5k_calibrate(unsigned long data)
 }
 
 
-
-/***************\
-* LED functions *
-\***************/
-
-static void
-ath5k_led_enable(struct ath5k_softc *sc)
-{
-	if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
-		ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
-		ath5k_led_off(sc);
-	}
-}
-
-static void
-ath5k_led_on(struct ath5k_softc *sc)
-{
-	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-		return;
-	ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
-}
-
-static void
-ath5k_led_off(struct ath5k_softc *sc)
-{
-	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-		return;
-	ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
-}
-
-static void
-ath5k_led_brightness_set(struct led_classdev *led_dev,
-	enum led_brightness brightness)
-{
-	struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
-		led_dev);
-
-	if (brightness == LED_OFF)
-		ath5k_led_off(led->sc);
-	else
-		ath5k_led_on(led->sc);
-}
-
-static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
-		   const char *name, char *trigger)
-{
-	int err;
-
-	led->sc = sc;
-	strncpy(led->name, name, sizeof(led->name));
-	led->led_dev.name = led->name;
-	led->led_dev.default_trigger = trigger;
-	led->led_dev.brightness_set = ath5k_led_brightness_set;
-
-	err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
-	if (err) {
-		ATH5K_WARN(sc, "could not register LED %s\n", name);
-		led->sc = NULL;
-	}
-	return err;
-}
-
-static void
-ath5k_unregister_led(struct ath5k_led *led)
-{
-	if (!led->sc)
-		return;
-	led_classdev_unregister(&led->led_dev);
-	ath5k_led_off(led->sc);
-	led->sc = NULL;
-}
-
-static void
-ath5k_unregister_leds(struct ath5k_softc *sc)
-{
-	ath5k_unregister_led(&sc->rx_led);
-	ath5k_unregister_led(&sc->tx_led);
-}
-
-
-static int
-ath5k_init_leds(struct ath5k_softc *sc)
-{
-	int ret = 0;
-	struct ieee80211_hw *hw = sc->hw;
-	struct pci_dev *pdev = sc->pdev;
-	char name[ATH5K_LED_MAX_NAME_LEN + 1];
-
-	/*
-	 * Auto-enable soft led processing for IBM cards and for
-	 * 5211 minipci cards.
-	 */
-	if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
-	    pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
-		__set_bit(ATH_STAT_LEDSOFT, sc->status);
-		sc->led_pin = 0;
-		sc->led_on = 0;  /* active low */
-	}
-	/* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
-	if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
-		__set_bit(ATH_STAT_LEDSOFT, sc->status);
-		sc->led_pin = 1;
-		sc->led_on = 1;  /* active high */
-	}
-	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-		goto out;
-
-	ath5k_led_enable(sc);
-
-	snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
-	ret = ath5k_register_led(sc, &sc->rx_led, name,
-		ieee80211_get_rx_led_name(hw));
-	if (ret)
-		goto out;
-
-	snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
-	ret = ath5k_register_led(sc, &sc->tx_led, name,
-		ieee80211_get_tx_led_name(hw));
-out:
-	return ret;
-}
-
-
 /********************\
 * Mac80211 functions *
 \********************/
@@ -2667,7 +2559,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
 		if (skb_headroom(skb) < padsize) {
 			ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
 				  " headroom to pad %d\n", hdrlen, padsize);
-			return NETDEV_TX_BUSY;
+			goto drop_packet;
 		}
 		skb_push(skb, padsize);
 		memmove(skb->data, skb->data+padsize, hdrlen);
@@ -2678,7 +2570,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
 		ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
 		spin_unlock_irqrestore(&sc->txbuflock, flags);
 		ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
-		return NETDEV_TX_BUSY;
+		goto drop_packet;
 	}
 	bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
 	list_del(&bf->list);
@@ -2695,25 +2587,34 @@ ath5k_tx(struct ieee80211_hw *hw, struct
 		list_add_tail(&bf->list, &sc->txbuf);
 		sc->txbuf_len++;
 		spin_unlock_irqrestore(&sc->txbuflock, flags);
-		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
+		goto drop_packet;
 	}
+	return NETDEV_TX_OK;
 
+drop_packet:
+	dev_kfree_skb_any(skb);
 	return NETDEV_TX_OK;
 }
 
+/*
+ * Reset the hardware.  If chan is not NULL, then also pause rx/tx
+ * and change to the given channel.
+ */
 static int
-ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
 {
 	struct ath5k_hw *ah = sc->ah;
 	int ret;
 
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
 
-	if (stop) {
+	if (chan) {
 		ath5k_hw_set_imr(ah, 0);
 		ath5k_txq_cleanup(sc);
 		ath5k_rx_stop(sc);
+
+		sc->curchan = chan;
+		sc->curband = &sc->sbands[chan->band];
 	}
 	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
 	if (ret) {
@@ -2721,12 +2622,6 @@ ath5k_reset(struct ath5k_softc *sc, bool
 		goto err;
 	}
 
-	/*
-	 * This is needed only to setup initial state
-	 * but it's best done after a reset.
-	 */
-	ath5k_hw_set_txpower_limit(sc->ah, 0);
-
 	ret = ath5k_rx_start(sc);
 	if (ret) {
 		ATH5K_ERR(sc, "can't start recv logic\n");
@@ -2757,7 +2652,7 @@ ath5k_reset_wake(struct ath5k_softc *sc)
 {
 	int ret;
 
-	ret = ath5k_reset(sc, true, true);
+	ret = ath5k_reset(sc, sc->curchan);
 	if (!ret)
 		ieee80211_wake_queues(sc->hw);
 
@@ -2766,12 +2661,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)
 
 static int ath5k_start(struct ieee80211_hw *hw)
 {
-	return ath5k_init(hw->priv, false);
+	return ath5k_init(hw->priv);
 }
 
 static void ath5k_stop(struct ieee80211_hw *hw)
 {
-	ath5k_stop_hw(hw->priv, false);
+	ath5k_stop_hw(hw->priv);
 }
 
 static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2856,7 +2751,7 @@ ath5k_config_interface(struct ieee80211_
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
-	int ret;
+	int ret = 0;
 
 	mutex_lock(&sc->lock);
 	if (sc->vif != vif) {
@@ -2882,9 +2777,7 @@ ath5k_config_interface(struct ieee80211_
 		}
 		ath5k_beacon_update(sc, beacon);
 	}
-	mutex_unlock(&sc->lock);
 
-	return ath5k_reset_wake(sc);
 unlock:
 	mutex_unlock(&sc->lock);
 	return ret;
@@ -3020,8 +2913,8 @@ static void ath5k_configure_filter(struc
 
 static int
 ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-		const u8 *local_addr, const u8 *addr,
-		struct ieee80211_key_conf *key)
+	      struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+	      struct ieee80211_key_conf *key)
 {
 	struct ath5k_softc *sc = hw->priv;
 	int ret = 0;
@@ -3044,7 +2937,8 @@ ath5k_set_key(struct ieee80211_hw *hw, e
 
 	switch (cmd) {
 	case SET_KEY:
-		ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr);
+		ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
+				       sta ? sta->addr : NULL);
 		if (ret) {
 			ATH5K_ERR(sc, "can't set the key\n");
 			goto unlock;
@@ -3104,6 +2998,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw)
 }
 
 static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+	struct ath5k_softc *sc = hw->priv;
+
+	ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
 ath5k_reset_tsf(struct ieee80211_hw *hw)
 {
 	struct ath5k_softc *sc = hw->priv;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/base.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/base.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.h	2009-06-09 23:05:27.000000000 -0400
@@ -112,7 +112,7 @@ struct ath5k_softc {
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 	struct ieee80211_channel channels[ATH_CHAN_MAX];
 	struct ieee80211_rate	rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-	u8			rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+	s8			rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
 	enum nl80211_iftype	opmode;
 	struct ath5k_hw		*ah;		/* Atheros HW */
 
@@ -148,8 +148,7 @@ struct ath5k_softc {
 	u8			bssidmask[ETH_ALEN];
 
 	unsigned int		led_pin,	/* GPIO pin for driving LED */
-				led_on,		/* pin setting for LED on */
-				led_off;	/* off time for current blink */
+				led_on;		/* pin setting for LED on */
 
 	struct tasklet_struct	restq;		/* reset tasklet */
 
@@ -170,6 +169,7 @@ struct ath5k_softc {
 	struct ath5k_led	tx_led;		/* tx led */
 
 	spinlock_t		block;		/* protects beacon */
+	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
 	struct ath5k_buf	*bbuf;		/* beacon buffer */
 	unsigned int		bhalq,		/* SW q for outgoing beacons */
 				bmisscount,	/* missed beacon transmits */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/caps.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/caps.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/caps.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/caps.c	2009-06-09 23:05:27.000000000 -0400
@@ -85,7 +85,8 @@ int ath5k_hw_set_capabilities(struct ath
 		/* Enable  802.11b if a 2GHz capable radio (2111/5112) is
 		 * connected */
 		if (AR5K_EEPROM_HDR_11B(ee_header) ||
-				AR5K_EEPROM_HDR_11G(ee_header)) {
+		    (AR5K_EEPROM_HDR_11G(ee_header) &&
+		     ah->ah_version != AR5K_AR5211)) {
 			/* 2312 */
 			ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
 			ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
@@ -94,7 +95,8 @@ int ath5k_hw_set_capabilities(struct ath
 				__set_bit(AR5K_MODE_11B,
 						ah->ah_capabilities.cap_mode);
 
-			if (AR5K_EEPROM_HDR_11G(ee_header))
+			if (AR5K_EEPROM_HDR_11G(ee_header) &&
+			    ah->ah_version != AR5K_AR5211)
 				__set_bit(AR5K_MODE_11G,
 						ah->ah_capabilities.cap_mode);
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/debug.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/debug.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,14 +82,14 @@ static int ath5k_debugfs_open(struct ino
 /* debugfs: registers */
 
 struct reg {
-	char *name;
+	const char *name;
 	int addr;
 };
 
 #define REG_STRUCT_INIT(r) { #r, r }
 
 /* just a few random registers, might want to add more */
-static struct reg regs[] = {
+static const struct reg regs[] = {
 	REG_STRUCT_INIT(AR5K_CR),
 	REG_STRUCT_INIT(AR5K_RXDP),
 	REG_STRUCT_INIT(AR5K_CFG),
@@ -142,7 +142,7 @@ static struct reg regs[] = {
 
 static void *reg_start(struct seq_file *seq, loff_t *pos)
 {
-	return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+	return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
 }
 
 static void reg_stop(struct seq_file *seq, void *p)
@@ -153,7 +153,7 @@ static void reg_stop(struct seq_file *se
 static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
 {
 	++*pos;
-	return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+	return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
 }
 
 static int reg_show(struct seq_file *seq, void *p)
@@ -165,7 +165,7 @@ static int reg_show(struct seq_file *seq
 	return 0;
 }
 
-static struct seq_operations register_seq_ops = {
+static const struct seq_operations register_seq_ops = {
 	.start = reg_start,
 	.next  = reg_next,
 	.stop  = reg_stop,
@@ -193,43 +193,6 @@ static const struct file_operations fops
 };
 
 
-/* debugfs: TSF */
-
-static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
-				   size_t count, loff_t *ppos)
-{
-	struct ath5k_softc *sc = file->private_data;
-	char buf[100];
-	snprintf(buf, sizeof(buf), "0x%016llx\n",
-		 (unsigned long long)ath5k_hw_get_tsf64(sc->ah));
-	return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
-}
-
-static ssize_t write_file_tsf(struct file *file,
-				 const char __user *userbuf,
-				 size_t count, loff_t *ppos)
-{
-	struct ath5k_softc *sc = file->private_data;
-	char buf[20];
-
-	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
-		return -EFAULT;
-
-	if (strncmp(buf, "reset", 5) == 0) {
-		ath5k_hw_reset_tsf(sc->ah);
-		printk(KERN_INFO "debugfs reset TSF\n");
-	}
-	return count;
-}
-
-static const struct file_operations fops_tsf = {
-	.read = read_file_tsf,
-	.write = write_file_tsf,
-	.open = ath5k_debugfs_open,
-	.owner = THIS_MODULE,
-};
-
-
 /* debugfs: beacons */
 
 static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
@@ -327,7 +290,7 @@ static const struct file_operations fops
 
 /* debugfs: debug level */
 
-static struct {
+static const struct {
 	enum ath5k_debug_level level;
 	const char *name;
 	const char *desc;
@@ -423,9 +386,6 @@ ath5k_debug_init_device(struct ath5k_sof
 	sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
 				sc->debug.debugfs_phydir, sc, &fops_registers);
 
-	sc->debug.debugfs_tsf = debugfs_create_file("tsf", S_IWUSR | S_IRUGO,
-				sc->debug.debugfs_phydir, sc, &fops_tsf);
-
 	sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
 				sc->debug.debugfs_phydir, sc, &fops_beacon);
 
@@ -444,7 +404,6 @@ ath5k_debug_finish_device(struct ath5k_s
 {
 	debugfs_remove(sc->debug.debugfs_debug);
 	debugfs_remove(sc->debug.debugfs_registers);
-	debugfs_remove(sc->debug.debugfs_tsf);
 	debugfs_remove(sc->debug.debugfs_beacon);
 	debugfs_remove(sc->debug.debugfs_reset);
 	debugfs_remove(sc->debug.debugfs_phydir);
@@ -465,7 +424,7 @@ ath5k_debug_dump_bands(struct ath5k_soft
 
 	for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
 		struct ieee80211_supported_band *band = &sc->sbands[b];
-		char bname[5];
+		char bname[6];
 		switch (band->band) {
 		case IEEE80211_BAND_2GHZ:
 			strcpy(bname, "2 GHz");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/debug.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/debug.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/debug.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/debug.h	2009-06-09 23:05:27.000000000 -0400
@@ -72,7 +72,6 @@ struct ath5k_dbg_info {
 	struct dentry		*debugfs_phydir;
 	struct dentry		*debugfs_debug;
 	struct dentry		*debugfs_registers;
-	struct dentry		*debugfs_tsf;
 	struct dentry		*debugfs_beacon;
 	struct dentry		*debugfs_reset;
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/desc.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/desc.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/desc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/desc.c	2009-06-09 23:05:27.000000000 -0400
@@ -194,6 +194,10 @@ static int ath5k_hw_setup_4word_tx_desc(
 		return -EINVAL;
 	}
 
+	tx_power += ah->ah_txpower.txp_offset;
+	if (tx_power > AR5K_TUNE_MAX_TXPOWER)
+		tx_power = AR5K_TUNE_MAX_TXPOWER;
+
 	/* Clear descriptor */
 	memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/eeprom.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/eeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -98,11 +98,6 @@ ath5k_eeprom_init_header(struct ath5k_hw
 	int ret;
 	u16 val;
 
-	/* Initial TX thermal adjustment values */
-	ee->ee_tx_clip = 4;
-	ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
-	ee->ee_gain_select = 1;
-
 	/*
 	 * Read values from EEPROM and store them in the capability structure
 	 */
@@ -137,6 +132,18 @@ ath5k_eeprom_init_header(struct ath5k_hw
 	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
 		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
 		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+		/* XXX: Don't know which versions include these two */
+		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+		if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+		}
 	}
 
 	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
@@ -192,7 +199,7 @@ static int ath5k_eeprom_read_ants(struct
 
 	/* Get antenna modes */
 	ah->ah_antenna[mode][0] =
-	    (ee->ee_ant_control[mode][0] << 4) | 0x1;
+	    (ee->ee_ant_control[mode][0] << 4);
 	ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
 	     ee->ee_ant_control[mode][1] 	|
 	    (ee->ee_ant_control[mode][2] << 6) 	|
@@ -213,7 +220,8 @@ static int ath5k_eeprom_read_ants(struct
 }
 
 /*
- * Read supported modes from eeprom
+ * Read supported modes and some mode-specific calibration data
+ * from eeprom
  */
 static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 		unsigned int mode)
@@ -228,22 +236,22 @@ static int ath5k_eeprom_read_modes(struc
 	ee->ee_adc_desired_size[mode]	= (s8)((val >> 8) & 0xff);
 	switch(mode) {
 	case AR5K_EEPROM_MODE_11A:
-		ee->ee_ob[mode][3]		= (val >> 5) & 0x7;
-		ee->ee_db[mode][3]		= (val >> 2) & 0x7;
-		ee->ee_ob[mode][2]		= (val << 1) & 0x7;
+		ee->ee_ob[mode][3]	= (val >> 5) & 0x7;
+		ee->ee_db[mode][3]	= (val >> 2) & 0x7;
+		ee->ee_ob[mode][2]	= (val << 1) & 0x7;
 
 		AR5K_EEPROM_READ(o++, val);
-		ee->ee_ob[mode][2]		|= (val >> 15) & 0x1;
-		ee->ee_db[mode][2]		= (val >> 12) & 0x7;
-		ee->ee_ob[mode][1]		= (val >> 9) & 0x7;
-		ee->ee_db[mode][1]		= (val >> 6) & 0x7;
-		ee->ee_ob[mode][0]		= (val >> 3) & 0x7;
-		ee->ee_db[mode][0]		= val & 0x7;
+		ee->ee_ob[mode][2]	|= (val >> 15) & 0x1;
+		ee->ee_db[mode][2]	= (val >> 12) & 0x7;
+		ee->ee_ob[mode][1]	= (val >> 9) & 0x7;
+		ee->ee_db[mode][1]	= (val >> 6) & 0x7;
+		ee->ee_ob[mode][0]	= (val >> 3) & 0x7;
+		ee->ee_db[mode][0]	= val & 0x7;
 		break;
 	case AR5K_EEPROM_MODE_11G:
 	case AR5K_EEPROM_MODE_11B:
-		ee->ee_ob[mode][1]		= (val >> 4) & 0x7;
-		ee->ee_db[mode][1]		= val & 0x7;
+		ee->ee_ob[mode][1]	= (val >> 4) & 0x7;
+		ee->ee_db[mode][1]	= val & 0x7;
 		break;
 	}
 
@@ -315,6 +323,9 @@ static int ath5k_eeprom_read_modes(struc
 	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
 		goto done;
 
+	/* Note: >= v5 have bg freq piers on another location
+	 * so these freq piers are ignored for >= v5 (should be 0xff
+	 * anyway) */
 	switch(mode) {
 	case AR5K_EEPROM_MODE_11A:
 		if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
@@ -442,7 +453,7 @@ ath5k_eeprom_read_turbo_modes(struct ath
 	return 0;
 }
 
-
+/* Read mode-specific data (except power calibration data) */
 static int
 ath5k_eeprom_init_modes(struct ath5k_hw *ah)
 {
@@ -488,56 +499,47 @@ ath5k_eeprom_init_modes(struct ath5k_hw
 	return 0;
 }
 
-static inline void
-ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
-{
-	const static u16 intercepts3[] =
-		{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
-	const static u16 intercepts3_2[] =
-		{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
-	const u16 *ip;
-	int i;
-
-	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
-		ip = intercepts3_2;
-	else
-		ip = intercepts3;
-
-	for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
-		*vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100;
-}
-
+/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
+ * frequency mask) */
 static inline int
 ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
-                            struct ath5k_chan_pcal_info *pc, u8 *count)
+			struct ath5k_chan_pcal_info *pc, unsigned int mode)
 {
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	int o = *offset;
 	int i = 0;
-	u8 f1, f2;
+	u8 freq1, freq2;
 	int ret;
 	u16 val;
 
+	ee->ee_n_piers[mode] = 0;
 	while(i < max) {
 		AR5K_EEPROM_READ(o++, val);
 
-		f1 = (val >> 8) & 0xff;
-		f2 = val & 0xff;
-
-		if (f1)
-			pc[i++].freq = f1;
+		freq1 = val & 0xff;
+		if (!freq1)
+			break;
 
-		if (f2)
-			pc[i++].freq = f2;
+		pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+				freq1, mode);
+		ee->ee_n_piers[mode]++;
 
-		if (!f1 || !f2)
+		freq2 = (val >> 8) & 0xff;
+		if (!freq2)
 			break;
+
+		pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+				freq2, mode);
+		ee->ee_n_piers[mode]++;
 	}
+
+	/* return new offset */
 	*offset = o;
-	*count = i;
 
 	return 0;
 }
 
+/* Read frequency piers for 802.11a */
 static int
 ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
 {
@@ -550,7 +552,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct a
 	if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
 		ath5k_eeprom_read_freq_list(ah, &offset,
 			AR5K_EEPROM_N_5GHZ_CHAN, pcal,
-			&ee->ee_n_piers[AR5K_EEPROM_MODE_11A]);
+			AR5K_EEPROM_MODE_11A);
 	} else {
 		mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
 
@@ -577,23 +579,25 @@ ath5k_eeprom_init_11a_pcal_freq(struct a
 
 		AR5K_EEPROM_READ(offset++, val);
 		pcal[9].freq |= (val >> 10) & 0x3f;
+
+		/* Fixed number of piers */
 		ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
-	}
 
-	for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) {
-		pcal[i].freq = ath5k_eeprom_bin2freq(ee,
+		for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
+			pcal[i].freq = ath5k_eeprom_bin2freq(ee,
 				pcal[i].freq, AR5K_EEPROM_MODE_11A);
+		}
 	}
 
 	return 0;
 }
 
+/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
 static inline int
 ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_chan_pcal_info *pcal;
-	int i;
 
 	switch(mode) {
 	case AR5K_EEPROM_MODE_11B:
@@ -608,23 +612,134 @@ ath5k_eeprom_init_11bg_2413(struct ath5k
 
 	ath5k_eeprom_read_freq_list(ah, &offset,
 		AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
-		&ee->ee_n_piers[mode]);
-	for(i = 0; i < AR5K_EEPROM_N_2GHZ_CHAN_2413; i += 1) {
-		pcal[i].freq = ath5k_eeprom_bin2freq(ee,
-				pcal[i].freq, mode);
-	}
+		mode);
 
 	return 0;
 }
 
+/*
+ * Read power calibration for RF5111 chips
+ *
+ * For RF5111 we have an XPD -eXternal Power Detector- curve
+ * for each calibrated channel. Each curve has 0,5dB Power steps
+ * on x axis and PCDAC steps (offsets) on y axis and looks like an
+ * exponential function. To recreate the curve we read 11 points
+ * here and interpolate later.
+ */
+
+/* Used to match PCDAC steps with power values on RF5111 chips
+ * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
+ * steps that match with the power values we read from eeprom. On
+ * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
+ * these 11 steps are spaced in a different way. This function returns
+ * the pcdac steps based on eeprom version and curve min/max so that we
+ * can have pcdac/pwr points.
+ */
+static inline void
+ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
+{
+	const static u16 intercepts3[] =
+		{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
+	const static u16 intercepts3_2[] =
+		{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
+	const u16 *ip;
+	int i;
+
+	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
+		ip = intercepts3_2;
+	else
+		ip = intercepts3;
+
+	for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
+		vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
+}
 
+/* Convert RF5111 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
+				struct ath5k_chan_pcal_info *chinfo)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info_rf5111 *pcinfo;
+	struct ath5k_pdgain_info *pd;
+	u8 pier, point, idx;
+	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+
+	/* Fill raw data for each calibration pier */
+	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+		pcinfo = &chinfo[pier].rf5111_info;
+
+		/* Allocate pd_curves for this cal pier */
+		chinfo[pier].pd_curves =
+			kcalloc(AR5K_EEPROM_N_PD_CURVES,
+				sizeof(struct ath5k_pdgain_info),
+				GFP_KERNEL);
+
+		if (!chinfo[pier].pd_curves)
+			return -ENOMEM;
+
+		/* Only one curve for RF5111
+		 * find out which one and place
+		 * in in pd_curves.
+		 * Note: ee_x_gain is reversed here */
+		for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
+
+			if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
+				pdgain_idx[0] = idx;
+				break;
+			}
+		}
+
+		ee->ee_pd_gains[mode] = 1;
+
+		pd = &chinfo[pier].pd_curves[idx];
+
+		pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
+
+		/* Allocate pd points for this curve */
+		pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+					sizeof(u8), GFP_KERNEL);
+		if (!pd->pd_step)
+			return -ENOMEM;
+
+		pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+					sizeof(s16), GFP_KERNEL);
+		if (!pd->pd_pwr)
+			return -ENOMEM;
+
+		/* Fill raw dataset
+		 * (convert power to 0.25dB units
+		 * for RF5112 combatibility) */
+		for (point = 0; point < pd->pd_points; point++) {
+
+			/* Absolute values */
+			pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
+
+			/* Already sorted */
+			pd->pd_step[point] = pcinfo->pcdac[point];
+		}
+
+		/* Set min/max pwr */
+		chinfo[pier].min_pwr = pd->pd_pwr[0];
+		chinfo[pier].max_pwr = pd->pd_pwr[10];
+
+	}
+
+	return 0;
+}
+
+/* Parse EEPROM data */
 static int
 ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_chan_pcal_info *pcal;
 	int offset, ret;
-	int i, j;
+	int i;
 	u16 val;
 
 	offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
@@ -704,26 +819,167 @@ ath5k_eeprom_read_pcal_info_5111(struct
 
 		ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
 			cdata->pcdac_max, cdata->pcdac);
+	}
 
-		for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) {
-			cdata->pwr[j] = (u16)
-				(AR5K_EEPROM_POWER_STEP * cdata->pwr[j]);
+	return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
+}
+
+
+/*
+ * Read power calibration for RF5112 chips
+ *
+ * For RF5112 we have 4 XPD -eXternal Power Detector- curves
+ * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
+ * power steps on x axis and PCDAC steps on y axis and looks like a
+ * linear function. To recreate the curve and pass the power values
+ * on hw, we read 4 points for xpd 0 (lower gain -> max power)
+ * and 3 points for xpd 3 (higher gain -> lower power) here and
+ * interpolate later.
+ *
+ * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
+ */
+
+/* Convert RF5112 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
+				struct ath5k_chan_pcal_info *chinfo)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info_rf5112 *pcinfo;
+	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+	unsigned int pier, pdg, point;
+
+	/* Fill raw data for each calibration pier */
+	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+		pcinfo = &chinfo[pier].rf5112_info;
+
+		/* Allocate pd_curves for this cal pier */
+		chinfo[pier].pd_curves =
+				kcalloc(AR5K_EEPROM_N_PD_CURVES,
+					sizeof(struct ath5k_pdgain_info),
+					GFP_KERNEL);
+
+		if (!chinfo[pier].pd_curves)
+			return -ENOMEM;
+
+		/* Fill pd_curves */
+		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+			u8 idx = pdgain_idx[pdg];
+			struct ath5k_pdgain_info *pd =
+					&chinfo[pier].pd_curves[idx];
+
+			/* Lowest gain curve (max power) */
+			if (pdg == 0) {
+				/* One more point for better accuracy */
+				pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
+
+				/* Allocate pd points for this curve */
+				pd->pd_step = kcalloc(pd->pd_points,
+						sizeof(u8), GFP_KERNEL);
+
+				if (!pd->pd_step)
+					return -ENOMEM;
+
+				pd->pd_pwr = kcalloc(pd->pd_points,
+						sizeof(s16), GFP_KERNEL);
+
+				if (!pd->pd_pwr)
+					return -ENOMEM;
+
+
+				/* Fill raw dataset
+				 * (all power levels are in 0.25dB units) */
+				pd->pd_step[0] = pcinfo->pcdac_x0[0];
+				pd->pd_pwr[0] = pcinfo->pwr_x0[0];
+
+				for (point = 1; point < pd->pd_points;
+				point++) {
+					/* Absolute values */
+					pd->pd_pwr[point] =
+						pcinfo->pwr_x0[point];
+
+					/* Deltas */
+					pd->pd_step[point] =
+						pd->pd_step[point - 1] +
+						pcinfo->pcdac_x0[point];
+				}
+
+				/* Set min power for this frequency */
+				chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+			/* Highest gain curve (min power) */
+			} else if (pdg == 1) {
+
+				pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
+
+				/* Allocate pd points for this curve */
+				pd->pd_step = kcalloc(pd->pd_points,
+						sizeof(u8), GFP_KERNEL);
+
+				if (!pd->pd_step)
+					return -ENOMEM;
+
+				pd->pd_pwr = kcalloc(pd->pd_points,
+						sizeof(s16), GFP_KERNEL);
+
+				if (!pd->pd_pwr)
+					return -ENOMEM;
+
+				/* Fill raw dataset
+				 * (all power levels are in 0.25dB units) */
+				for (point = 0; point < pd->pd_points;
+				point++) {
+					/* Absolute values */
+					pd->pd_pwr[point] =
+						pcinfo->pwr_x3[point];
+
+					/* Fixed points */
+					pd->pd_step[point] =
+						pcinfo->pcdac_x3[point];
+				}
+
+				/* Since we have a higher gain curve
+				 * override min power */
+				chinfo[pier].min_pwr = pd->pd_pwr[0];
+			}
 		}
 	}
 
 	return 0;
 }
 
+/* Parse EEPROM data */
 static int
 ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
 	struct ath5k_chan_pcal_info *gen_chan_info;
+	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
 	u32 offset;
-	unsigned int i, c;
+	u8 i, c;
 	u16 val;
 	int ret;
+	u8 pd_gains = 0;
+
+	/* Count how many curves we have and
+	 * identify them (which one of the 4
+	 * available curves we have on each count).
+	 * Curves are stored from lower (x0) to
+	 * higher (x3) gain */
+	for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
+		/* ee_x_gain[mode] is x gain mask */
+		if ((ee->ee_x_gain[mode] >> i) & 0x1)
+			pdgain_idx[pd_gains++] = i;
+	}
+	ee->ee_pd_gains[mode] = pd_gains;
+
+	if (pd_gains == 0 || pd_gains > 2)
+		return -EINVAL;
 
 	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
@@ -761,13 +1017,13 @@ ath5k_eeprom_read_pcal_info_5112(struct
 	for (i = 0; i < ee->ee_n_piers[mode]; i++) {
 		chan_pcal_info = &gen_chan_info[i].rf5112_info;
 
-		/* Power values in dBm * 4
+		/* Power values in quarter dB
 		 * for the lower xpd gain curve
 		 * (0 dBm -> higher output power) */
 		for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr_x0[c] = (val & 0xff);
-			chan_pcal_info->pwr_x0[++c] = ((val >> 8) & 0xff);
+			chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
+			chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
 		}
 
 		/* PCDAC steps
@@ -778,42 +1034,61 @@ ath5k_eeprom_read_pcal_info_5112(struct
 		chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
 		chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
 
-		/* Power values in dBm * 4
+		/* Power values in quarter dB
 		 * for the higher xpd gain curve
 		 * (18 dBm -> lower output power) */
 		AR5K_EEPROM_READ(offset++, val);
-		chan_pcal_info->pwr_x3[0] = (val & 0xff);
-		chan_pcal_info->pwr_x3[1] = ((val >> 8) & 0xff);
+		chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
+		chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
 
 		AR5K_EEPROM_READ(offset++, val);
 		chan_pcal_info->pwr_x3[2] = (val & 0xff);
 
 		/* PCDAC steps
 		 * corresponding to the above power
-		 * measurements (static) */
+		 * measurements (fixed) */
 		chan_pcal_info->pcdac_x3[0] = 20;
 		chan_pcal_info->pcdac_x3[1] = 35;
 		chan_pcal_info->pcdac_x3[2] = 63;
 
 		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
-			chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0xff);
+			chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
 
 			/* Last xpd0 power level is also channel maximum */
 			gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
 		} else {
 			chan_pcal_info->pcdac_x0[0] = 1;
-			gen_chan_info[i].max_pwr = ((val >> 8) & 0xff);
+			gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
 		}
 
-		/* Recreate pcdac_x0 table for this channel using pcdac steps */
-		chan_pcal_info->pcdac_x0[1] += chan_pcal_info->pcdac_x0[0];
-		chan_pcal_info->pcdac_x0[2] += chan_pcal_info->pcdac_x0[1];
-		chan_pcal_info->pcdac_x0[3] += chan_pcal_info->pcdac_x0[2];
 	}
 
-	return 0;
+	return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
 }
 
+
+/*
+ * Read power calibration for RF2413 chips
+ *
+ * For RF2413 we have a Power to PDDAC table (Power Detector)
+ * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
+ * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
+ * axis and looks like an exponential function like the RF5111 curve.
+ *
+ * To recreate the curves we read here the points and interpolate
+ * later. Note that in most cases only 2 (higher and lower) curves are
+ * used (like RF5112) but vendors have the oportunity to include all
+ * 4 curves on eeprom. The final curve (higher power) has an extra
+ * point for better accuracy like RF5112.
+ */
+
+/* For RF2413 power calibration data doesn't start on a fixed location and
+ * if a mode is not supported, it's section is missing -not zeroed-.
+ * So we need to calculate the starting offset for each section by using
+ * these two functions */
+
+/* Return the size of each section based on the mode and the number of pd
+ * gains available (maximum 4). */
 static inline unsigned int
 ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
 {
@@ -826,6 +1101,8 @@ ath5k_pdgains_size_2413(struct ath5k_eep
 	return sz;
 }
 
+/* Return the starting offset for a section based on the modes supported
+ * and each section's size. */
 static unsigned int
 ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
 {
@@ -834,11 +1111,15 @@ ath5k_cal_data_offset_2413(struct ath5k_
 	switch(mode) {
 	case AR5K_EEPROM_MODE_11G:
 		if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-			offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 2;
+			offset += ath5k_pdgains_size_2413(ee,
+					AR5K_EEPROM_MODE_11B) +
+					AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
 		/* fall through */
 	case AR5K_EEPROM_MODE_11B:
 		if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-			offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 5;
+			offset += ath5k_pdgains_size_2413(ee,
+					AR5K_EEPROM_MODE_11A) +
+					AR5K_EEPROM_N_5GHZ_CHAN / 2;
 		/* fall through */
 	case AR5K_EEPROM_MODE_11A:
 		break;
@@ -849,24 +1130,117 @@ ath5k_cal_data_offset_2413(struct ath5k_
 	return offset;
 }
 
+/* Convert RF2413 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
+				struct ath5k_chan_pcal_info *chinfo)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+	unsigned int pier, pdg, point;
+
+	/* Fill raw data for each calibration pier */
+	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+		pcinfo = &chinfo[pier].rf2413_info;
+
+		/* Allocate pd_curves for this cal pier */
+		chinfo[pier].pd_curves =
+				kcalloc(AR5K_EEPROM_N_PD_CURVES,
+					sizeof(struct ath5k_pdgain_info),
+					GFP_KERNEL);
+
+		if (!chinfo[pier].pd_curves)
+			return -ENOMEM;
+
+		/* Fill pd_curves */
+		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+			u8 idx = pdgain_idx[pdg];
+			struct ath5k_pdgain_info *pd =
+					&chinfo[pier].pd_curves[idx];
+
+			/* One more point for the highest power
+			 * curve (lowest gain) */
+			if (pdg == ee->ee_pd_gains[mode] - 1)
+				pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
+			else
+				pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
+
+			/* Allocate pd points for this curve */
+			pd->pd_step = kcalloc(pd->pd_points,
+					sizeof(u8), GFP_KERNEL);
+
+			if (!pd->pd_step)
+				return -ENOMEM;
+
+			pd->pd_pwr = kcalloc(pd->pd_points,
+					sizeof(s16), GFP_KERNEL);
+
+			if (!pd->pd_pwr)
+				return -ENOMEM;
+
+			/* Fill raw dataset
+			 * convert all pwr levels to
+			 * quarter dB for RF5112 combatibility */
+			pd->pd_step[0] = pcinfo->pddac_i[pdg];
+			pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
+
+			for (point = 1; point < pd->pd_points; point++) {
+
+				pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
+					2 * pcinfo->pwr[pdg][point - 1];
+
+				pd->pd_step[point] = pd->pd_step[point - 1] +
+						pcinfo->pddac[pdg][point - 1];
+
+			}
+
+			/* Highest gain curve -> min power */
+			if (pdg == 0)
+				chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+			/* Lowest gain curve -> max power */
+			if (pdg == ee->ee_pd_gains[mode] - 1)
+				chinfo[pier].max_pwr =
+					pd->pd_pwr[pd->pd_points - 1];
+		}
+	}
+
+	return 0;
+}
+
+/* Parse EEPROM data */
 static int
 ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info;
-	struct ath5k_chan_pcal_info *gen_chan_info;
-	unsigned int i, c;
+	struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+	struct ath5k_chan_pcal_info *chinfo;
+	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
 	u32 offset;
-	int ret;
+	int idx, i, ret;
 	u16 val;
 	u8 pd_gains = 0;
 
-	if (ee->ee_x_gain[mode] & 0x1) pd_gains++;
-	if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++;
-	if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++;
-	if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++;
+	/* Count how many curves we have and
+	 * identify them (which one of the 4
+	 * available curves we have on each count).
+	 * Curves are stored from higher to
+	 * lower gain so we go backwards */
+	for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
+		/* ee_x_gain[mode] is x gain mask */
+		if ((ee->ee_x_gain[mode] >> idx) & 0x1)
+			pdgain_idx[pd_gains++] = idx;
+
+	}
 	ee->ee_pd_gains[mode] = pd_gains;
 
+	if (pd_gains == 0)
+		return -EINVAL;
+
 	offset = ath5k_cal_data_offset_2413(ee, mode);
 	switch (mode) {
 	case AR5K_EEPROM_MODE_11A:
@@ -875,7 +1249,7 @@ ath5k_eeprom_read_pcal_info_2413(struct
 
 		ath5k_eeprom_init_11a_pcal_freq(ah, offset);
 		offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
-		gen_chan_info = ee->ee_pwr_cal_a;
+		chinfo = ee->ee_pwr_cal_a;
 		break;
 	case AR5K_EEPROM_MODE_11B:
 		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
@@ -883,7 +1257,7 @@ ath5k_eeprom_read_pcal_info_2413(struct
 
 		ath5k_eeprom_init_11bg_2413(ah, mode, offset);
 		offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-		gen_chan_info = ee->ee_pwr_cal_b;
+		chinfo = ee->ee_pwr_cal_b;
 		break;
 	case AR5K_EEPROM_MODE_11G:
 		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
@@ -891,41 +1265,35 @@ ath5k_eeprom_read_pcal_info_2413(struct
 
 		ath5k_eeprom_init_11bg_2413(ah, mode, offset);
 		offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-		gen_chan_info = ee->ee_pwr_cal_g;
+		chinfo = ee->ee_pwr_cal_g;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	if (pd_gains == 0)
-		return 0;
-
 	for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-		chan_pcal_info = &gen_chan_info[i].rf2413_info;
+		pcinfo = &chinfo[i].rf2413_info;
 
 		/*
 		 * Read pwr_i, pddac_i and the first
 		 * 2 pd points (pwr, pddac)
 		 */
 		AR5K_EEPROM_READ(offset++, val);
-		chan_pcal_info->pwr_i[0] = val & 0x1f;
-		chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f;
-		chan_pcal_info->pwr[0][0] =
-					(val >> 12) & 0xf;
+		pcinfo->pwr_i[0] = val & 0x1f;
+		pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
+		pcinfo->pwr[0][0] = (val >> 12) & 0xf;
 
 		AR5K_EEPROM_READ(offset++, val);
-		chan_pcal_info->pddac[0][0] = val & 0x3f;
-		chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf;
-		chan_pcal_info->pddac[0][1] =
-					(val >> 10) & 0x3f;
+		pcinfo->pddac[0][0] = val & 0x3f;
+		pcinfo->pwr[0][1] = (val >> 6) & 0xf;
+		pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
 
 		AR5K_EEPROM_READ(offset++, val);
-		chan_pcal_info->pwr[0][2] = val & 0xf;
-		chan_pcal_info->pddac[0][2] =
-					(val >> 4) & 0x3f;
+		pcinfo->pwr[0][2] = val & 0xf;
+		pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
 
-		chan_pcal_info->pwr[0][3] = 0;
-		chan_pcal_info->pddac[0][3] = 0;
+		pcinfo->pwr[0][3] = 0;
+		pcinfo->pddac[0][3] = 0;
 
 		if (pd_gains > 1) {
 			/*
@@ -933,44 +1301,36 @@ ath5k_eeprom_read_pcal_info_2413(struct
 			 * so it only has 2 pd points.
 			 * Continue wih pd gain 1.
 			 */
-			chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
+			pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
 
-			chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1;
+			pcinfo->pddac_i[1] = (val >> 15) & 0x1;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1;
+			pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
 
-			chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf;
-			chan_pcal_info->pddac[1][0] =
-						(val >> 10) & 0x3f;
+			pcinfo->pwr[1][0] = (val >> 6) & 0xf;
+			pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
 
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr[1][1] = val & 0xf;
-			chan_pcal_info->pddac[1][1] =
-						(val >> 4) & 0x3f;
-			chan_pcal_info->pwr[1][2] =
-						(val >> 10) & 0xf;
+			pcinfo->pwr[1][1] = val & 0xf;
+			pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
+			pcinfo->pwr[1][2] = (val >> 10) & 0xf;
 
-			chan_pcal_info->pddac[1][2] =
-						(val >> 14) & 0x3;
+			pcinfo->pddac[1][2] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac[1][2] |=
-						(val & 0xF) << 2;
+			pcinfo->pddac[1][2] |= (val & 0xF) << 2;
 
-			chan_pcal_info->pwr[1][3] = 0;
-			chan_pcal_info->pddac[1][3] = 0;
+			pcinfo->pwr[1][3] = 0;
+			pcinfo->pddac[1][3] = 0;
 		} else if (pd_gains == 1) {
 			/*
 			 * Pd gain 0 is the last one so
 			 * read the extra point.
 			 */
-			chan_pcal_info->pwr[0][3] =
-						(val >> 10) & 0xf;
+			pcinfo->pwr[0][3] = (val >> 10) & 0xf;
 
-			chan_pcal_info->pddac[0][3] =
-						(val >> 14) & 0x3;
+			pcinfo->pddac[0][3] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac[0][3] |=
-						(val & 0xF) << 2;
+			pcinfo->pddac[0][3] |= (val & 0xF) << 2;
 		}
 
 		/*
@@ -978,105 +1338,65 @@ ath5k_eeprom_read_pcal_info_2413(struct
 		 * as above.
 		 */
 		if (pd_gains > 2) {
-			chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f;
-			chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f;
+			pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
+			pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
 
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr[2][0] =
-						(val >> 0) & 0xf;
-			chan_pcal_info->pddac[2][0] =
-						(val >> 4) & 0x3f;
-			chan_pcal_info->pwr[2][1] =
-						(val >> 10) & 0xf;
+			pcinfo->pwr[2][0] = (val >> 0) & 0xf;
+			pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
+			pcinfo->pwr[2][1] = (val >> 10) & 0xf;
 
-			chan_pcal_info->pddac[2][1] =
-						(val >> 14) & 0x3;
+			pcinfo->pddac[2][1] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac[2][1] |=
-						(val & 0xF) << 2;
+			pcinfo->pddac[2][1] |= (val & 0xF) << 2;
 
-			chan_pcal_info->pwr[2][2] =
-						(val >> 4) & 0xf;
-			chan_pcal_info->pddac[2][2] =
-						(val >> 8) & 0x3f;
+			pcinfo->pwr[2][2] = (val >> 4) & 0xf;
+			pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
 
-			chan_pcal_info->pwr[2][3] = 0;
-			chan_pcal_info->pddac[2][3] = 0;
+			pcinfo->pwr[2][3] = 0;
+			pcinfo->pddac[2][3] = 0;
 		} else if (pd_gains == 2) {
-			chan_pcal_info->pwr[1][3] =
-						(val >> 4) & 0xf;
-			chan_pcal_info->pddac[1][3] =
-						(val >> 8) & 0x3f;
+			pcinfo->pwr[1][3] = (val >> 4) & 0xf;
+			pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
 		}
 
 		if (pd_gains > 3) {
-			chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3;
+			pcinfo->pwr_i[3] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
+			pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
 
-			chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
-			chan_pcal_info->pwr[3][0] =
-						(val >> 10) & 0xf;
-			chan_pcal_info->pddac[3][0] =
-						(val >> 14) & 0x3;
+			pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
+			pcinfo->pwr[3][0] = (val >> 10) & 0xf;
+			pcinfo->pddac[3][0] = (val >> 14) & 0x3;
 
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac[3][0] |=
-						(val & 0xF) << 2;
-			chan_pcal_info->pwr[3][1] =
-						(val >> 4) & 0xf;
-			chan_pcal_info->pddac[3][1] =
-						(val >> 8) & 0x3f;
+			pcinfo->pddac[3][0] |= (val & 0xF) << 2;
+			pcinfo->pwr[3][1] = (val >> 4) & 0xf;
+			pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
 
-			chan_pcal_info->pwr[3][2] =
-						(val >> 14) & 0x3;
+			pcinfo->pwr[3][2] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr[3][2] |=
-						((val >> 0) & 0x3) << 2;
+			pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
 
-			chan_pcal_info->pddac[3][2] =
-						(val >> 2) & 0x3f;
-			chan_pcal_info->pwr[3][3] =
-						(val >> 8) & 0xf;
+			pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
+			pcinfo->pwr[3][3] = (val >> 8) & 0xf;
 
-			chan_pcal_info->pddac[3][3] =
-						(val >> 12) & 0xF;
+			pcinfo->pddac[3][3] = (val >> 12) & 0xF;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pddac[3][3] |=
-						((val >> 0) & 0x3) << 4;
+			pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
 		} else if (pd_gains == 3) {
-			chan_pcal_info->pwr[2][3] =
-						(val >> 14) & 0x3;
+			pcinfo->pwr[2][3] = (val >> 14) & 0x3;
 			AR5K_EEPROM_READ(offset++, val);
-			chan_pcal_info->pwr[2][3] |=
-						((val >> 0) & 0x3) << 2;
-
-			chan_pcal_info->pddac[2][3] =
-						(val >> 2) & 0x3f;
-		}
-
-		for (c = 0; c < pd_gains; c++) {
-			/* Recreate pwr table for this channel using pwr steps */
-			chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
-			chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
-			chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
-			chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
-			if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
-				chan_pcal_info->pwr[c][3] = 0;
+			pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
 
-			/* Recreate pddac table for this channel using pddac steps */
-			chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
-			chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
-			chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
-			chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
-			if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
-				chan_pcal_info->pddac[c][3] = 0;
+			pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
 		}
 	}
 
-	return 0;
+	return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
 }
 
+
 /*
  * Read per rate target power (this is the maximum tx power
  * supported by the card). This info is used when setting
@@ -1084,11 +1404,12 @@ ath5k_eeprom_read_pcal_info_2413(struct
  *
  * This also works for v5 EEPROMs.
  */
-static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
+static int
+ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
 {
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_rate_pcal_info *rate_pcal_info;
-	u16 *rate_target_pwr_num;
+	u8 *rate_target_pwr_num;
 	u32 offset;
 	u16 val;
 	int ret, i;
@@ -1163,6 +1484,20 @@ static int ath5k_eeprom_read_target_rate
 	return 0;
 }
 
+/*
+ * Read per channel calibration info from EEPROM
+ *
+ * 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
+ * it can use accurate power values when setting tx power (takes amplifier's
+ * performance on each channel into account).
+ *
+ * EEPROM provides us with the offsets for some pre-calibrated channels
+ * and we have to interpolate to create the full table for these channels and
+ * also the table for any channel.
+ */
 static int
 ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
 {
@@ -1180,7 +1515,9 @@ ath5k_eeprom_read_pcal_info(struct ath5k
 	else
 		read_pcal = ath5k_eeprom_read_pcal_info_5111;
 
-	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
+
+	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
+	mode++) {
 		err = read_pcal(ah, mode);
 		if (err)
 			return err;
@@ -1193,7 +1530,63 @@ ath5k_eeprom_read_pcal_info(struct ath5k
 	return 0;
 }
 
-/* Read conformance test limits */
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info *chinfo;
+	u8 pier, pdg;
+
+	switch (mode) {
+	case AR5K_EEPROM_MODE_11A:
+		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_a;
+		break;
+	case AR5K_EEPROM_MODE_11B:
+		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_b;
+		break;
+	case AR5K_EEPROM_MODE_11G:
+		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_g;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+		if (!chinfo[pier].pd_curves)
+			continue;
+
+		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+			struct ath5k_pdgain_info *pd =
+					&chinfo[pier].pd_curves[pdg];
+
+			if (pd != NULL) {
+				kfree(pd->pd_step);
+				kfree(pd->pd_pwr);
+			}
+		}
+
+		kfree(chinfo[pier].pd_curves);
+	}
+
+	return 0;
+}
+
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
+{
+	u8 mode;
+
+	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+		ath5k_eeprom_free_pcal_info(ah, mode);
+}
+
+/* Read conformance test limits used for regulatory control */
 static int
 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
 {
@@ -1328,19 +1721,17 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
 
 	return 0;
 }
+
 /*
  * Read the MAC address from eeprom
  */
 int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 {
-	u8 mac_d[ETH_ALEN];
+	u8 mac_d[ETH_ALEN] = {};
 	u32 total, offset;
 	u16 data;
 	int octet, ret;
 
-	memset(mac, 0, ETH_ALEN);
-	memset(mac_d, 0, ETH_ALEN);
-
 	ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
 	if (ret)
 		return ret;
@@ -1356,11 +1747,23 @@ int ath5k_eeprom_read_mac(struct ath5k_h
 		octet += 2;
 	}
 
-	memcpy(mac, mac_d, ETH_ALEN);
-
 	if (!total || total == 3 * 0xffff)
 		return -EINVAL;
 
+	memcpy(mac, mac_d, ETH_ALEN);
+
 	return 0;
 }
 
+bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
+{
+	u16 data;
+
+	ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
+
+	if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
+		return true;
+	else
+		return false;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/eeprom.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/eeprom.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,6 +25,7 @@
 #define AR5K_EEPROM_MAGIC_5211		0x0000145b /* 5211 */
 #define AR5K_EEPROM_MAGIC_5210		0x0000145a /* 5210 */
 
+#define	AR5K_EEPROM_IS_HB63		0x000b	/* Talon detect */
 #define AR5K_EEPROM_REG_DOMAIN		0x00bf	/* EEPROM regdom */
 #define AR5K_EEPROM_CHECKSUM		0x00c0	/* EEPROM checksum */
 #define AR5K_EEPROM_INFO_BASE		0x00c0	/* EEPROM header */
@@ -172,6 +173,7 @@
 #define AR5K_EEPROM_N_5GHZ_CHAN		10
 #define AR5K_EEPROM_N_2GHZ_CHAN		3
 #define AR5K_EEPROM_N_2GHZ_CHAN_2413	4
+#define	AR5K_EEPROM_N_2GHZ_CHAN_MAX	4
 #define AR5K_EEPROM_MAX_CHAN		10
 #define AR5K_EEPROM_N_PWR_POINTS_5111	11
 #define AR5K_EEPROM_N_PCDAC		11
@@ -192,7 +194,7 @@
 #define AR5K_EEPROM_SCALE_OC_DELTA(_x)	(((_x) * 2) / 10)
 #define AR5K_EEPROM_N_CTLS(_v)		AR5K_EEPROM_OFF(_v, 16, 32)
 #define AR5K_EEPROM_MAX_CTLS		32
-#define AR5K_EEPROM_N_XPD_PER_CHANNEL	4
+#define AR5K_EEPROM_N_PD_CURVES		4
 #define AR5K_EEPROM_N_XPD0_POINTS	4
 #define AR5K_EEPROM_N_XPD3_POINTS	3
 #define AR5K_EEPROM_N_PD_GAINS		4
@@ -231,7 +233,7 @@ enum ath5k_ctl_mode {
 	AR5K_CTL_11B = 1,
 	AR5K_CTL_11G = 2,
 	AR5K_CTL_TURBO = 3,
-	AR5K_CTL_108G = 4,
+	AR5K_CTL_TURBOG = 4,
 	AR5K_CTL_2GHT20 = 5,
 	AR5K_CTL_5GHT20 = 6,
 	AR5K_CTL_2GHT40 = 7,
@@ -239,65 +241,114 @@ enum ath5k_ctl_mode {
 	AR5K_CTL_MODE_M = 15,
 };
 
+/* Default CTL ids for the 3 main reg domains.
+ * Atheros only uses these by default but vendors
+ * can have up to 32 different CTLs for different
+ * scenarios. Note that theese values are ORed with
+ * the mode id (above) so we can have up to 24 CTL
+ * datasets out of these 3 main regdomains. That leaves
+ * 8 ids that can be used by vendors and since 0x20 is
+ * missing from HAL sources i guess this is the set of
+ * custom CTLs vendors can use. */
+#define	AR5K_CTL_FCC	0x10
+#define	AR5K_CTL_CUSTOM	0x20
+#define	AR5K_CTL_ETSI	0x30
+#define	AR5K_CTL_MKK	0x40
+
+/* Indicates a CTL with only mode set and
+ * no reg domain mapping, such CTLs are used
+ * for world roaming domains or simply when
+ * a reg domain is not set */
+#define	AR5K_CTL_NO_REGDOMAIN	0xf0
+
+/* Indicates an empty (invalid) CTL */
+#define AR5K_CTL_NO_CTL		0xff
+
 /* Per channel calibration data, used for power table setup */
 struct ath5k_chan_pcal_info_rf5111 {
 	/* Power levels in half dbm units
 	 * for one power curve. */
-	u8		pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
+	u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
 	/* PCDAC table steps
 	 * for the above values */
-	u8		pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
+	u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
 	/* Starting PCDAC step */
-	u8		pcdac_min;
+	u8 pcdac_min;
 	/* Final PCDAC step */
-	u8		pcdac_max;
+	u8 pcdac_max;
 };
 
 struct ath5k_chan_pcal_info_rf5112 {
 	/* Power levels in quarter dBm units
 	 * for lower (0) and higher (3)
-	 * level curves */
-	s8		pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
-	s8		pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
+	 * level curves in 0.25dB units */
+	s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
+	s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
 	/* PCDAC table steps
 	 * for the above values */
-	u8	pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
-	u8	pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
+	u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
+	u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
 };
 
 struct ath5k_chan_pcal_info_rf2413 {
 	/* Starting pwr/pddac values */
-	s8		pwr_i[AR5K_EEPROM_N_PD_GAINS];
-	u8	pddac_i[AR5K_EEPROM_N_PD_GAINS];
-	/* (pwr,pddac) points */
-	s8		pwr[AR5K_EEPROM_N_PD_GAINS]
-				[AR5K_EEPROM_N_PD_POINTS];
-	u8	pddac[AR5K_EEPROM_N_PD_GAINS]
-				[AR5K_EEPROM_N_PD_POINTS];
+	s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
+	u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
+	/* (pwr,pddac) points
+	 * power levels in 0.5dB units */
+	s8 pwr[AR5K_EEPROM_N_PD_GAINS]
+		[AR5K_EEPROM_N_PD_POINTS];
+	u8 pddac[AR5K_EEPROM_N_PD_GAINS]
+		[AR5K_EEPROM_N_PD_POINTS];
+};
+
+enum ath5k_powertable_type {
+	AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
+	AR5K_PWRTABLE_LINEAR_PCDAC = 1,
+	AR5K_PWRTABLE_PWR_TO_PDADC = 2,
+};
+
+struct ath5k_pdgain_info {
+	u8 pd_points;
+	u8 *pd_step;
+	/* Power values are in
+	 * 0.25dB units */
+	s16 *pd_pwr;
 };
 
 struct ath5k_chan_pcal_info {
 	/* Frequency */
 	u16	freq;
-	/* Max available power */
-	s8		max_pwr;
+	/* Tx power boundaries */
+	s16	max_pwr;
+	s16	min_pwr;
 	union {
 		struct ath5k_chan_pcal_info_rf5111 rf5111_info;
 		struct ath5k_chan_pcal_info_rf5112 rf5112_info;
 		struct ath5k_chan_pcal_info_rf2413 rf2413_info;
 	};
+	/* Raw values used by phy code
+	 * Curves are stored in order from lower
+	 * gain to higher gain (max txpower -> min txpower) */
+	struct ath5k_pdgain_info *pd_curves;
 };
 
-/* Per rate calibration data for each mode, used for power table setup */
+/* Per rate calibration data for each mode,
+ * used for rate power table setup.
+ * Note: Values in 0.5dB units */
 struct ath5k_rate_pcal_info {
 	u16	freq; /* Frequency */
-	/* Power level for 6-24Mbit/s rates */
+	/* Power level for 6-24Mbit/s rates or
+	 * 1Mb rate */
 	u16	target_power_6to24;
-	/* Power level for 36Mbit rate */
+	/* Power level for 36Mbit rate or
+	 * 2Mb rate */
 	u16	target_power_36;
-	/* Power level for 48Mbit rate */
+	/* Power level for 48Mbit rate or
+	 * 5.5Mbit rate */
 	u16	target_power_48;
-	/* Power level for 54Mbit rate */
+	/* Power level for 54Mbit rate or
+	 * 11Mbit rate */
 	u16	target_power_54;
 };
 
@@ -329,12 +380,6 @@ struct ath5k_eeprom_info {
 	u16	ee_cck_ofdm_power_delta;
 	u16	ee_scaled_cck_delta;
 
-	/* Used for tx thermal adjustment (eeprom_init, rfregs) */
-	u16	ee_tx_clip;
-	u16	ee_pwd_84;
-	u16	ee_pwd_90;
-	u16	ee_gain_select;
-
 	/* RF Calibration settings (reset, rfregs) */
 	u16	ee_i_cal[AR5K_EEPROM_N_MODES];
 	u16	ee_q_cal[AR5K_EEPROM_N_MODES];
@@ -362,23 +407,25 @@ struct ath5k_eeprom_info {
 	/* Power calibration data */
 	u16	ee_false_detect[AR5K_EEPROM_N_MODES];
 
-	/* Number of pd gain curves per mode (RF2413) */
-	u8 ee_pd_gains[AR5K_EEPROM_N_MODES];
+	/* Number of pd gain curves per mode */
+	u8	ee_pd_gains[AR5K_EEPROM_N_MODES];
+	/* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
+	u8	ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
 
-	u8 ee_n_piers[AR5K_EEPROM_N_MODES];
+	u8	ee_n_piers[AR5K_EEPROM_N_MODES];
 	struct ath5k_chan_pcal_info	ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
-	struct ath5k_chan_pcal_info	ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN];
-	struct ath5k_chan_pcal_info	ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN];
+	struct ath5k_chan_pcal_info	ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+	struct ath5k_chan_pcal_info	ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
 
 	/* Per rate target power levels */
-	u16	ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
+	u8	ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
 	struct ath5k_rate_pcal_info	ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
-	struct ath5k_rate_pcal_info	ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN];
-	struct ath5k_rate_pcal_info	ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN];
+	struct ath5k_rate_pcal_info	ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+	struct ath5k_rate_pcal_info	ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
 
 	/* Conformance test limits (Unused) */
-	u16	ee_ctls;
-	u16	ee_ctl[AR5K_EEPROM_MAX_CTLS];
+	u8	ee_ctls;
+	u8	ee_ctl[AR5K_EEPROM_MAX_CTLS];
 	struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
 
 	/* Noise Floor Calibration settings */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/gpio.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/gpio.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/gpio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/gpio.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,7 +83,7 @@ void ath5k_hw_set_ledstate(struct ath5k_
 int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	if (gpio > AR5K_NUM_GPIO)
+	if (gpio >= AR5K_NUM_GPIO)
 		return -EINVAL;
 
 	ath5k_hw_reg_write(ah,
@@ -99,7 +99,7 @@ int ath5k_hw_set_gpio_input(struct ath5k
 int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	if (gpio > AR5K_NUM_GPIO)
+	if (gpio >= AR5K_NUM_GPIO)
 		return -EINVAL;
 
 	ath5k_hw_reg_write(ah,
@@ -115,7 +115,7 @@ int ath5k_hw_set_gpio_output(struct ath5
 u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
 {
 	ATH5K_TRACE(ah->ah_sc);
-	if (gpio > AR5K_NUM_GPIO)
+	if (gpio >= AR5K_NUM_GPIO)
 		return 0xffffffff;
 
 	/* GPIO input magic */
@@ -131,7 +131,7 @@ int ath5k_hw_set_gpio(struct ath5k_hw *a
 	u32 data;
 	ATH5K_TRACE(ah->ah_sc);
 
-	if (gpio > AR5K_NUM_GPIO)
+	if (gpio >= AR5K_NUM_GPIO)
 		return -EINVAL;
 
 	/* GPIO output magic */
@@ -154,7 +154,7 @@ void ath5k_hw_set_gpio_intr(struct ath5k
 	u32 data;
 
 	ATH5K_TRACE(ah->ah_sc);
-	if (gpio > AR5K_NUM_GPIO)
+	if (gpio >= AR5K_NUM_GPIO)
 		return;
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/initvals.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/initvals.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/initvals.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/initvals.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  * Initial register settings functions
  *
  * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
  * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -340,7 +340,7 @@ static const struct ath5k_ini ar5211_ini
 	 * common on all cards/modes.
 	 * Note: Table is rewritten during
 	 * txpower setup later using calibration
-	 * data etc. so next write is non-common
+	 * data etc. so next write is non-common */
 	{ AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
 	{ AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
 	{ AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
@@ -371,7 +371,7 @@ static const struct ath5k_ini ar5211_ini
 	{ AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
 	{ AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
 	{ AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
-	{ AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },*/
+	{ AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
 	{ AR5K_PHY_CCKTXCTL, 0x00000000 },
 	{ AR5K_PHY(642), 0x503e4646 },
 	{ AR5K_PHY_GAIN_2GHZ, 0x6480416c },
@@ -386,85 +386,85 @@ static const struct ath5k_ini ar5211_ini
 };
 
 /* Initial mode-specific settings for AR5211
- * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ?
- * Maybe 5211 supports OFDM-only g but we need to test it !
+ * 5211 supports OFDM-only g (draft g) but we
+ * need to test it !
  */
 static const struct ath5k_ini_mode ar5211_ini_mode[] = {
 	{ AR5K_TXCFG,
-	/*	  a	      aTurbo	  b		*/
-		{ 0x00000015, 0x00000015, 0x0000001d } },
+	/*	  a	    aTurbo	  b	  g (OFDM)    */
+	   { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
 	{ AR5K_DCU_GBL_IFS_SLOT,
-		{ 0x00000168, 0x000001e0, 0x000001b8 } },
+	   { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
 	{ AR5K_DCU_GBL_IFS_SIFS,
-		{ 0x00000230, 0x000001e0, 0x000000b0 } },
+	   { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
 	{ AR5K_DCU_GBL_IFS_EIFS,
-		{ 0x00000d98, 0x00001180, 0x00001f48 } },
+	   { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
 	{ AR5K_DCU_GBL_IFS_MISC,
-		{ 0x0000a0e0, 0x00014068, 0x00005880 } },
+	   { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
 	{ AR5K_TIME_OUT,
-		{ 0x04000400, 0x08000800, 0x20003000 } },
+	   { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
 	{ AR5K_USEC_5211,
-		{ 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } },
+	   { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
 	{ AR5K_PHY_TURBO,
-		{ 0x00000000, 0x00000003, 0x00000000 } },
+	   { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
 	{ AR5K_PHY(8),
-		{ 0x02020200, 0x02020200, 0x02010200 } },
+	   { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
 	{ AR5K_PHY(9),
-		{ 0x00000e0e, 0x00000e0e, 0x00000707 } },
+	   { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
 	{ AR5K_PHY(10),
-		{ 0x0a020001, 0x0a020001, 0x05010000 } },
+	   { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
 	{ AR5K_PHY(13),
-		{ 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+	   { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
 	{ AR5K_PHY(14),
-		{ 0x00000007, 0x00000007, 0x0000000b } },
+	   { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
 	{ AR5K_PHY(17),
-		{ 0x1372169c, 0x137216a5, 0x137216a8 } },
+	   { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
 	{ AR5K_PHY(18),
-		{ 0x0018ba67, 0x0018ba67, 0x0018ba69 } },
+	   { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
 	{ AR5K_PHY(20),
-		{ 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+	   { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
 	{ AR5K_PHY_SIG,
-		{ 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } },
+	   { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x31375d5e, 0x31375d5e, 0x313a5d5e } },
+	   { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
 	{ AR5K_PHY_AGCCTL,
-		{ 0x0000bd10, 0x0000bd10, 0x0000bd38 } },
+	   { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
 	{ AR5K_PHY_NF,
-		{ 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+	   { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x00002710, 0x00002710, 0x0000157c } },
+	   { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
 	{ AR5K_PHY(70),
-		{ 0x00000190, 0x00000190, 0x00000084 } },
+	   { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0x6fe01020, 0x6fe01020, 0x6fe00920 } },
-	{ AR5K_PHY_PCDAC_TXPOWER_BASE_5211,
-		{ 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } },
+	   { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+	{ AR5K_PHY_PCDAC_TXPOWER_BASE,
+	   { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
 	{ AR5K_RF_BUFFER_CONTROL_4,
-		{ 0x00000010, 0x00000014, 0x00000010 } },
+	   { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
 };
 
 /* Initial register settings for AR5212 */
-static const struct ath5k_ini ar5212_ini[] = {
+static const struct ath5k_ini ar5212_ini_common_start[] = {
 	{ AR5K_RXDP,		0x00000000 },
 	{ AR5K_RXCFG,		0x00000005 },
 	{ AR5K_MIBC,		0x00000000 },
@@ -485,91 +485,83 @@ static const struct ath5k_ini ar5212_ini
 	{ AR5K_QUEUE_TXDP(9),	0x00000000 },
 	{ AR5K_DCU_FP,		0x00000000 },
 	{ AR5K_DCU_TXP,		0x00000000 },
-	{ AR5K_DCU_TX_FILTER_0_BASE,	0x00000000 },
-	/* Unknown table */
-	{ 0x1078, 0x00000000 },
-	{ 0x10b8, 0x00000000 },
-	{ 0x10f8, 0x00000000 },
-	{ 0x1138, 0x00000000 },
-	{ 0x1178, 0x00000000 },
-	{ 0x11b8, 0x00000000 },
-	{ 0x11f8, 0x00000000 },
-	{ 0x1238, 0x00000000 },
-	{ 0x1278, 0x00000000 },
-	{ 0x12b8, 0x00000000 },
-	{ 0x12f8, 0x00000000 },
-	{ 0x1338, 0x00000000 },
-	{ 0x1378, 0x00000000 },
-	{ 0x13b8, 0x00000000 },
-	{ 0x13f8, 0x00000000 },
-	{ 0x1438, 0x00000000 },
-	{ 0x1478, 0x00000000 },
-	{ 0x14b8, 0x00000000 },
-	{ 0x14f8, 0x00000000 },
-	{ 0x1538, 0x00000000 },
-	{ 0x1578, 0x00000000 },
-	{ 0x15b8, 0x00000000 },
-	{ 0x15f8, 0x00000000 },
-	{ 0x1638, 0x00000000 },
-	{ 0x1678, 0x00000000 },
-	{ 0x16b8, 0x00000000 },
-	{ 0x16f8, 0x00000000 },
-	{ 0x1738, 0x00000000 },
-	{ 0x1778, 0x00000000 },
-	{ 0x17b8, 0x00000000 },
-	{ 0x17f8, 0x00000000 },
-	{ 0x103c, 0x00000000 },
-	{ 0x107c, 0x00000000 },
-	{ 0x10bc, 0x00000000 },
-	{ 0x10fc, 0x00000000 },
-	{ 0x113c, 0x00000000 },
-	{ 0x117c, 0x00000000 },
-	{ 0x11bc, 0x00000000 },
-	{ 0x11fc, 0x00000000 },
-	{ 0x123c, 0x00000000 },
-	{ 0x127c, 0x00000000 },
-	{ 0x12bc, 0x00000000 },
-	{ 0x12fc, 0x00000000 },
-	{ 0x133c, 0x00000000 },
-	{ 0x137c, 0x00000000 },
-	{ 0x13bc, 0x00000000 },
-	{ 0x13fc, 0x00000000 },
-	{ 0x143c, 0x00000000 },
-	{ 0x147c, 0x00000000 },
+	/* Tx filter table 0 (32 entries) */
+	{ AR5K_DCU_TX_FILTER_0(0),  0x00000000 }, /* DCU 0 */
+	{ AR5K_DCU_TX_FILTER_0(1),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(2),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(3),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(4),  0x00000000 }, /* DCU 1 */
+	{ AR5K_DCU_TX_FILTER_0(5),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(6),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(7),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(8),  0x00000000 }, /* DCU 2 */
+	{ AR5K_DCU_TX_FILTER_0(9),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
+	{ AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
+	{ AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
+	{ AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
+	{ AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
+	{ AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
+	/* Tx filter table 1 (16 entries) */
+	{ AR5K_DCU_TX_FILTER_1(0),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(1),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(2),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(3),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(4),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(5),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(6),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(7),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(8),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(9),  0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+	{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
 	{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
 	{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
 	{ AR5K_STA_ID1,		0x00000000 },
 	{ AR5K_BSS_ID0,		0x00000000 },
 	{ AR5K_BSS_ID1,		0x00000000 },
-	/*{ AR5K_RSSI_THR,	0x00000000 },*/	/* Found on SuperAG cards */
-	{ AR5K_BEACON_5211,	0x00000000 },	/* Found on SuperAG cards */
-	{ AR5K_CFP_PERIOD_5211, 0x00000000 },	/* Found on SuperAG cards */
-	{ AR5K_TIMER0_5211,	0x00000030 },	/* Found on SuperAG cards */
-	{ AR5K_TIMER1_5211,	0x0007ffff },	/* Found on SuperAG cards */
-	{ AR5K_TIMER2_5211,	0x01ffffff },	/* Found on SuperAG cards */
-	{ AR5K_TIMER3_5211,	0x00000031 },	/* Found on SuperAG cards */
-	{ AR5K_CFP_DUR_5211,	0x00000000 },	/* Found on SuperAG cards */
+	{ AR5K_BEACON_5211,	0x00000000 },
+	{ AR5K_CFP_PERIOD_5211, 0x00000000 },
+	{ AR5K_TIMER0_5211,	0x00000030 },
+	{ AR5K_TIMER1_5211,	0x0007ffff },
+	{ AR5K_TIMER2_5211,	0x01ffffff },
+	{ AR5K_TIMER3_5211,	0x00000031 },
+	{ AR5K_CFP_DUR_5211,	0x00000000 },
 	{ AR5K_RX_FILTER_5211,	0x00000000 },
 	{ AR5K_DIAG_SW_5211,	0x00000000 },
 	{ AR5K_ADDAC_TEST,	0x00000000 },
 	{ AR5K_DEFAULT_ANTENNA,	0x00000000 },
-	{ 0x8080, 0x00000000 },
-	/*{ 0x805c, 0xffffc7ff },*/ /* Old value */
-	{ 0x805c, 0x000fc78f },
-	{ AR5K_NAV_5211,	0x00000000 },	/* Not found on recent */
-	{ AR5K_RTS_OK_5211,	0x00000000 },	/* dumps but it makes  */
-	{ AR5K_RTS_FAIL_5211,	0x00000000 },	/* sense to reset counters */
-	{ AR5K_ACK_FAIL_5211,	0x00000000 },	/* since pcu registers */
-	{ AR5K_FCS_FAIL_5211,	0x00000000 },	/* are skiped during chan*/
-	{ AR5K_BEACON_CNT_5211, 0x00000000 },	/* change */
+	{ AR5K_FRAME_CTL_QOSM, 	0x000fc78f },
 	{ AR5K_XRMODE,		0x2a82301a },
 	{ AR5K_XRDELAY,		0x05dc01e0 },
 	{ AR5K_XRTIMEOUT,	0x1f402710 },
 	{ AR5K_XRCHIRP,		0x01f40000 },
 	{ AR5K_XRSTOMP,		0x00001e1c },
-	{ AR5K_SLEEP0,		0x0002aaaa },	/* Found on SuperAG cards */
-	{ AR5K_SLEEP1,		0x02005555 },	/* Found on SuperAG cards */
-	{ AR5K_SLEEP2,		0x00000000 },	/* Found on SuperAG cards */
+	{ AR5K_SLEEP0,		0x0002aaaa },
+	{ AR5K_SLEEP1,		0x02005555 },
+	{ AR5K_SLEEP2,		0x00000000 },
 	{ AR5K_BSS_IDM0,	0xffffffff },
 	{ AR5K_BSS_IDM1,	0x0000ffff },
 	{ AR5K_TXPC,		0x00000000 },
@@ -577,7 +569,8 @@ static const struct ath5k_ini ar5212_ini
 	{ AR5K_PROFCNT_RX,	0x00000000 },
 	{ AR5K_PROFCNT_RXCLR,	0x00000000 },
 	{ AR5K_PROFCNT_CYCLE,	0x00000000 },
-	{ 0x80fc, 0x00000088 },
+	{ AR5K_QUIET_CTL1,	0x00000088 },
+	/* Initial rate duration table (32 entries )*/
 	{ AR5K_RATE_DUR(0),	0x00000000 },
 	{ AR5K_RATE_DUR(1),	0x0000008c },
 	{ AR5K_RATE_DUR(2),	0x000000e4 },
@@ -610,881 +603,625 @@ static const struct ath5k_ini ar5212_ini
 	{ AR5K_RATE_DUR(29),	0x0000007f },
 	{ AR5K_RATE_DUR(30),	0x000000a2 },
 	{ AR5K_RATE_DUR(31),	0x00000000 },
-	{ 0x8100, 0x00010002},
+	{ AR5K_QUIET_CTL2,	0x00010002 },
 	{ AR5K_TSF_PARM,	0x00000001 },
-	{ 0x8108, 0x000000c0 },
+	{ AR5K_QOS_NOACK,	0x000000c0 },
 	{ AR5K_PHY_ERR_FIL,	0x00000000 },
-	{ 0x8110, 0x00000168 },
-	{ 0x8114, 0x00000000 },
-	/* Some kind of table
-	 * also notice ...03<-02<-01<-00) */
-	{ 0x87c0, 0x03020100 },
-	{ 0x87c4, 0x07060504 },
-	{ 0x87c8, 0x0b0a0908 },
-	{ 0x87cc, 0x0f0e0d0c },
-	{ 0x87d0, 0x13121110 },
-	{ 0x87d4, 0x17161514 },
-	{ 0x87d8, 0x1b1a1918 },
-	{ 0x87dc, 0x1f1e1d1c },
-	/* loop ? */
-	{ 0x87e0, 0x03020100 },
-	{ 0x87e4, 0x07060504 },
-	{ 0x87e8, 0x0b0a0908 },
-	{ 0x87ec, 0x0f0e0d0c },
-	{ 0x87f0, 0x13121110 },
-	{ 0x87f4, 0x17161514 },
-	{ 0x87f8, 0x1b1a1918 },
-	{ 0x87fc, 0x1f1e1d1c },
-	/* PHY registers */
-	/*{ AR5K_PHY_AGC, 0x00000000 },*/
-	{ AR5K_PHY(3),	0xad848e19 },
-	{ AR5K_PHY(4),	0x7d28e000 },
-	{ AR5K_PHY_TIMING_3, 0x9c0a9f6b },
-	{ AR5K_PHY_ACT,	0x00000000 },
-	/*{ AR5K_PHY(11), 0x00022ffe },*/
-	/*{ AR5K_PHY(15), 0x00020100 },*/
-	{ AR5K_PHY(16),	0x206a017a },
-	/*{ AR5K_PHY(19), 0x1284613c },*/
-	{ AR5K_PHY(21),	0x00000859 },
-	{ AR5K_PHY(64),	0x00000000 },
-	{ AR5K_PHY(65),	0x00000000 },
-	{ AR5K_PHY(66),	0x00000000 },
-	{ AR5K_PHY(67),	0x00800000 },
-	{ AR5K_PHY(68),	0x00000001 },
+	{ AR5K_XRLAT_TX,	0x00000168 },
+	{ AR5K_ACKSIFS,		0x00000000 },
+	/* Rate -> db table
+	 * notice ...03<-02<-01<-00 ! */
+	{ AR5K_RATE2DB(0),	0x03020100 },
+	{ AR5K_RATE2DB(1),	0x07060504 },
+	{ AR5K_RATE2DB(2),	0x0b0a0908 },
+	{ AR5K_RATE2DB(3),	0x0f0e0d0c },
+	{ AR5K_RATE2DB(4),	0x13121110 },
+	{ AR5K_RATE2DB(5),	0x17161514 },
+	{ AR5K_RATE2DB(6),	0x1b1a1918 },
+	{ AR5K_RATE2DB(7),	0x1f1e1d1c },
+	/* Db -> Rate table */
+	{ AR5K_DB2RATE(0),	0x03020100 },
+	{ AR5K_DB2RATE(1),	0x07060504 },
+	{ AR5K_DB2RATE(2),	0x0b0a0908 },
+	{ AR5K_DB2RATE(3),	0x0f0e0d0c },
+	{ AR5K_DB2RATE(4),	0x13121110 },
+	{ AR5K_DB2RATE(5),	0x17161514 },
+	{ AR5K_DB2RATE(6),	0x1b1a1918 },
+	{ AR5K_DB2RATE(7),	0x1f1e1d1c },
+	/* PHY registers (Common settings
+	 * for all chips/modes) */
+	{ AR5K_PHY(3),		0xad848e19 },
+	{ AR5K_PHY(4),		0x7d28e000 },
+	{ AR5K_PHY_TIMING_3,	0x9c0a9f6b },
+	{ AR5K_PHY_ACT,		0x00000000 },
+	{ AR5K_PHY(16),		0x206a017a },
+	{ AR5K_PHY(21),		0x00000859 },
+	{ AR5K_PHY_BIN_MASK_1,	0x00000000 },
+	{ AR5K_PHY_BIN_MASK_2,	0x00000000 },
+	{ AR5K_PHY_BIN_MASK_3,	0x00000000 },
+	{ AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
+	{ AR5K_PHY_ANT_CTL,	0x00000001 },
 	/*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
-	{ AR5K_PHY(71),	0x00000c80 },
-	{ AR5K_PHY_IQ,	0x05100000 },
-	{ AR5K_PHY(74), 0x00000001 },
-	{ AR5K_PHY(75), 0x00000004 },
+	{ AR5K_PHY_MAX_RX_LEN,	0x00000c80 },
+	{ AR5K_PHY_IQ,		0x05100000 },
+	{ AR5K_PHY_WARM_RESET,	0x00000001 },
+	{ AR5K_PHY_CTL,		0x00000004 },
 	{ AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
 	{ AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
 	{ AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
-	/*{ AR5K_PHY(80), 0x00000004 },*/
-	{ AR5K_PHY(82), 0x9280b212 },
-	{ AR5K_PHY_RADAR, 0x5d50e188 },
+	{ AR5K_PHY(82),		0x9280b212 },
+	{ AR5K_PHY_RADAR,	0x5d50e188 },
 	/*{ AR5K_PHY(86), 0x000000ff },*/
-	{ AR5K_PHY(87), 0x004b6a8e },
-	{ AR5K_PHY(90),	0x000003ce },
-	{ AR5K_PHY(92),	0x192fb515 },
-	/*{ AR5K_PHY(93), 0x00000000 },*/
-	{ AR5K_PHY(94),	0x00000001 },
-	{ AR5K_PHY(95),	0x00000000 },
+	{ AR5K_PHY(87),		0x004b6a8e },
+	{ AR5K_PHY_NFTHRES,	0x000003ce },
+	{ AR5K_PHY_RESTART,	0x192fb515 },
+	{ AR5K_PHY(94),		0x00000001 },
+	{ AR5K_PHY_RFBUS_REQ,	0x00000000 },
 	/*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
 	/*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
-	{ AR5K_PHY(644), 0x00806333 },
-	{ AR5K_PHY(645), 0x00106c10 },
-	{ AR5K_PHY(646), 0x009c4060 },
-	{ AR5K_PHY(647), 0x1483800a },
-	/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
-	{ AR5K_PHY(648), 0x01831061 },
-	{ AR5K_PHY(649), 0x00000400 },
+	{ AR5K_PHY(644),	0x00806333 },
+	{ AR5K_PHY(645),	0x00106c10 },
+	{ AR5K_PHY(646),	0x009c4060 },
+	/* { AR5K_PHY(647), 0x1483800a }, */
+	/* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
+	{ AR5K_PHY(648),	0x018830c6 },
+	{ AR5K_PHY(649),	0x00000400 },
 	/*{ AR5K_PHY(650), 0x000001b5 },*/
-	{ AR5K_PHY(651), 0x00000000 },
+	{ AR5K_PHY(651),	0x00000000 },
 	{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
 	{ AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
 	/*{ AR5K_PHY(655), 0x13c889af },*/
-	{ AR5K_PHY(656), 0x38490a20 },
-	{ AR5K_PHY(657), 0x00007bb6 },
-	{ AR5K_PHY(658), 0x0fff3ffc },
-	/*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
+	{ AR5K_PHY(656),	0x38490a20 },
+	{ AR5K_PHY(657),	0x00007bb6 },
+	{ AR5K_PHY(658),	0x0fff3ffc },
 };
 
 /* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
 static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
-	{ AR5K_PHY(640),
-	/*	  a/XR	      aTurbo	  b	      g (DYN)	  gTurbo */
-		{ 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
-	{ AR5K_PHY(0),
-		{ 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
-		{ 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+	   { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
 	{ AR5K_DCU_GBL_IFS_SIFS,
-		{ 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+	   { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
 	{ AR5K_DCU_GBL_IFS_SLOT,
-		{ 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+	   { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
 	{ AR5K_DCU_GBL_IFS_EIFS,
-		{ 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+	   { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
 	{ AR5K_DCU_GBL_IFS_MISC,
-		{ 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+	   { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
 	{ AR5K_TIME_OUT,
-		{ 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+	   { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
 	{ AR5K_PHY_TURBO,
-		{ 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+	   { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
 	{ AR5K_PHY(8),
-		{ 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
-	{ AR5K_PHY(9),
-		{ 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
-	{ AR5K_PHY(17),
-		{ 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+	   { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+	{ AR5K_PHY_RF_CTL2,
+	   { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+	{ AR5K_PHY_SETTLING,
+	   { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
 	{ AR5K_PHY_AGCCTL,
-		{ 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+	   { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
 	{ AR5K_PHY_NF,
-		{ 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
-	{ AR5K_PHY(26),
-		{ 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+	   { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+	{ AR5K_PHY_WEAK_OFDM_HIGH_THR,
+	   { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
 	{ AR5K_PHY(70),
-		{ 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
-	{ AR5K_PHY(73),
-		{ 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+	   { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+	{ AR5K_PHY_OFDM_SELFCORR,
+	   { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
 	{ 0xa230,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+	   { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
 };
 
 /* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
-/* New dump pending */
-static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
-	{ AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
-	/*	  a/XR	      aTurbo	  b	      g (DYN)	  gTurbo */
-		{ 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
+static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
 	{ AR5K_TXCFG,
-		{ 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
 	{ AR5K_USEC_5211,
-		{ 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
-	{ AR5K_PHY(10),
-		{ 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
-	{ AR5K_PHY(13),
-		{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-	{ AR5K_PHY(14),
-		{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-	{ AR5K_PHY(18),
-		{ 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
-	{ AR5K_PHY(20),
-		{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+	   { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+	{ AR5K_PHY_RF_CTL3,
+	   { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+	{ AR5K_PHY_RF_CTL4,
+	   { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+	{ AR5K_PHY_PA_CTL,
+	   { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+	{ AR5K_PHY_GAIN,
+	   { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+	{ AR5K_PHY_DESIRED_SIZE,
+	   { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
 	{ AR5K_PHY_SIG,
-		{ 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+	   { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
-	{ AR5K_PHY(27),
-		{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+	   { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+	{ AR5K_PHY_WEAK_OFDM_LOW_THR,
+	   { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+	   { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+	   { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
 	{ AR5K_PHY_GAIN_2GHZ,
-		{ 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
-	{ 0xa21c,
-		{ 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-	{ AR5K_DCU_FP,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_AGC,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(11),
-		{ 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
-	{ AR5K_PHY(15),
-		{ 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
-	{ AR5K_PHY(19),
-		{ 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
-	{ AR5K_PHY_PAPD_PROBE,
-		{ 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } },
-	{ AR5K_PHY(80),
-		{ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
-	{ AR5K_PHY(86),
-		{ 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY(93),
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_SPENDING,
-		{ 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
-	{ AR5K_PHY_CCKTXCTL,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(642),
-		{ 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-	{ 0xa228,
-		{ 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
-	{ 0xa23c,
-		{ 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+	   { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+	{ AR5K_PHY_CCK_RX_CTL_4,
+	   { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5111_ini_common_end[] = {
+	{ AR5K_DCU_FP,		0x00000000 },
+	{ AR5K_PHY_AGC, 	0x00000000 },
+	{ AR5K_PHY_ADC_CTL, 	0x00022ffe },
+	{ 0x983c, 		0x00020100 },
+	{ AR5K_PHY_GAIN_OFFSET,	0x1284613c },
+	{ AR5K_PHY_PAPD_PROBE,	0x00004883 },
+	{ 0x9940,		0x00000004 },
+	{ 0x9958,		0x000000ff },
+	{ 0x9974,		0x00000000 },
+	{ AR5K_PHY_SPENDING,	0x00000018 },
+	{ AR5K_PHY_CCKTXCTL,	0x00000000 },
+	{ AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
+	{ AR5K_PHY_DAG_CCK_CTL,	0x000001b5 },
+	{ 0xa23c,		0x13c889af },
 };
 
 /* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */
-static const struct ath5k_ini_mode ar5212_rf5112_ini_mode_end[] = {
+static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
 	{ AR5K_TXCFG,
-	/*	  a/XR	      aTurbo	  b	      g (DYN)	  gTurbo */
-		{ 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
 	{ AR5K_USEC_5211,
-		{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-	{ AR5K_PHY(10),
-		{ 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-	{ AR5K_PHY(13),
-		{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-	{ AR5K_PHY(14),
-		{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-	{ AR5K_PHY(18),
-		{ 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
-	{ AR5K_PHY(20),
-		{ 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+	   { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+	{ AR5K_PHY_RF_CTL3,
+	   { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+	{ AR5K_PHY_RF_CTL4,
+	   { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+	{ AR5K_PHY_PA_CTL,
+	   { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+	{ AR5K_PHY_GAIN,
+	   { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+	{ AR5K_PHY_DESIRED_SIZE,
+	   { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
 	{ AR5K_PHY_SIG,
-		{ 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+	   { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
-	{ AR5K_PHY(27),
-		{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+	   { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+	{ AR5K_PHY_WEAK_OFDM_LOW_THR,
+	   { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+	   { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+	   { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
 	{ AR5K_PHY_CCKTXCTL,
-		{ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
-	{ AR5K_PHY(642),
-		{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+	   { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+	{ AR5K_PHY_CCK_CROSSCORR,
+	   { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
 	{ AR5K_PHY_GAIN_2GHZ,
-		{ 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
-	{ 0xa21c,
-		{ 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-	{ AR5K_DCU_FP,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_AGC,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(11),
-		{ 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
-	{ AR5K_PHY(15),
-		{ 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
-	{ AR5K_PHY(19),
-		{ 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
-	{ AR5K_PHY_PAPD_PROBE,
-		{ 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } },
-	{ AR5K_PHY(80),
-		{ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
-	{ AR5K_PHY(86),
-		{ 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY(93),
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa228,
-		{ 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
-	{ 0xa23c,
-		{ 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+	   { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+	{ AR5K_PHY_CCK_RX_CTL_4,
+	   { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5112_ini_common_end[] = {
+	{ AR5K_DCU_FP,		0x00000000 },
+	{ AR5K_PHY_AGC,		0x00000000 },
+	{ AR5K_PHY_ADC_CTL,	0x00022ffe },
+	{ 0x983c,		0x00020100 },
+	{ AR5K_PHY_GAIN_OFFSET,	0x1284613c },
+	{ AR5K_PHY_PAPD_PROBE,	0x00004882 },
+	{ 0x9940,		0x00000004 },
+	{ 0x9958,		0x000000ff },
+	{ 0x9974,		0x00000000 },
+	{ AR5K_PHY_DAG_CCK_CTL,	0x000001b5 },
+	{ 0xa23c,		0x13c889af },
 };
 
 /* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
 static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
 	{ AR5K_TXCFG,
-	/*	  a/XR	      aTurbo	  b	      g		  gTurbo */
-		{ 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
 	{ AR5K_USEC_5211,
-		{ 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-	{ AR5K_PHY(10),
-		{ 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-	{ AR5K_PHY(13),
-		{ 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-	{ AR5K_PHY(14),
-		{ 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-	{ AR5K_PHY(18),
-		{ 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
-	{ AR5K_PHY(20),
-		{ 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+	   { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+	{ AR5K_PHY_RF_CTL3,
+	   { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+	{ AR5K_PHY_RF_CTL4,
+	   { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+	{ AR5K_PHY_PA_CTL,
+	   { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+	{ AR5K_PHY_GAIN,
+	   { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+	{ AR5K_PHY_DESIRED_SIZE,
+	   { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
 	{ AR5K_PHY_SIG,
-		{ 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+	   { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
-	{ AR5K_PHY(27),
-		{ 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+	   { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+	{ AR5K_PHY_WEAK_OFDM_LOW_THR,
+	   { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+	   { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+	   { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
 	{ AR5K_PHY_CCKTXCTL,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(642),
-		{ 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+	   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ AR5K_PHY_CCK_CROSSCORR,
+	   { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
 	{ AR5K_PHY_GAIN_2GHZ,
-		{ 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
-	{ 0xa21c,
-		{ 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+	   { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+	{ AR5K_PHY_CCK_RX_CTL_4,
+	   { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
 	{ 0xa300,
-		{ 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+	   { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
 	{ 0xa304,
-		{ 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+	   { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
 	{ 0xa308,
-		{ 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+	   { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
 	{ 0xa30c,
-		{ 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+	   { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
 	{ 0xa310,
-		{ 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+	   { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
 	{ 0xa314,
-		{ 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+	   { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
 	{ 0xa318,
-		{ 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+	   { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
 	{ 0xa31c,
-		{ 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+	   { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
 	{ 0xa320,
-		{ 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+	   { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
 	{ 0xa324,
-		{ 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+	   { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
 	{ 0xa328,
-		{ 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+	   { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
 	{ 0xa32c,
-		{ 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+	   { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
 	{ 0xa330,
-		{ 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+	   { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
 	{ 0xa334,
-		{ 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
-	{ AR5K_DCU_FP,
-		{ 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } },
-	{ 0x4068,
-		{ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
-	{ 0x8060,
-		{ 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } },
-	{ 0x809c,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x80a0,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8118,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x811c,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8120,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8124,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8128,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x812c,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8130,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8134,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8138,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x813c,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8140,
-		{ 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } },
-	{ 0x8144,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_AGC,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(11),
-		{ 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
-	{ AR5K_PHY(15),
-		{ 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } },
-	{ AR5K_PHY(19),
-		{ 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } },
-	{ AR5K_PHY_SCR,
-		{ 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } },
-	{ AR5K_PHY_SLMT,
-		{ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-	{ AR5K_PHY_SCAL,
-		{ 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-	{ AR5K_PHY(86),
-		{ 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } },
-	{ AR5K_PHY(96),
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(97),
-		{ 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } },
-	{ AR5K_PHY(104),
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(120),
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(121),
-		{ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
-	{ AR5K_PHY(122),
-		{ 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } },
-	{ AR5K_PHY(123),
-		{ 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } },
-	{ AR5K_PHY_SCLOCK,
-		{ 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } },
-	{ AR5K_PHY_SDELAY,
-		{ 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY_SPENDING,
-		{ 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } },
-	{ 0xa228,
-		{ 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } },
-	{ 0xa23c,
-		{ 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
-	{ 0xa24c,
-		{ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-	{ 0xa250,
-		{ 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
-	{ 0xa254,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa258,
-		{ 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
-	{ 0xa25c,
-		{ 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
-	{ 0xa260,
-		{ 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
-	{ 0xa264,
-		{ 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
-	{ 0xa268,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa26c,
-		{ 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
-	{ 0xa270,
-		{ 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
-	{ 0xa274,
-		{ 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
-	{ 0xa278,
-		{ 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
-	{ 0xa27c,
-		{ 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
-	{ 0xa338,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa33c,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa340,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa344,
-		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa348,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa34c,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa350,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa354,
-		{ 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
-	{ 0xa358,
-		{ 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
-	{ 0xa35c,
-		{ 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
-	{ 0xa360,
-		{ 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
-	{ 0xa364,
-		{ 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
-	{ 0xa368,
-		{ 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
-	{ 0xa36c,
-		{ 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
-	{ 0xa370,
-		{ 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
-	{ 0xa374,
-		{ 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
-	{ 0xa378,
-		{ 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
-	{ 0xa37c,
-		{ 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
-	{ 0xa380,
-		{ 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
-	{ 0xa384,
-		{ 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+	   { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+};
+
+static const struct ath5k_ini rf5413_ini_common_end[] = {
+	{ AR5K_DCU_FP,		0x000003e0 },
+	{ AR5K_5414_CBCFG,	0x00000010 },
+	{ AR5K_SEQ_MASK,	0x0000000f },
+	{ 0x809c,		0x00000000 },
+	{ 0x80a0,		0x00000000 },
+	{ AR5K_MIC_QOS_CTL,	0x00000000 },
+	{ AR5K_MIC_QOS_SEL,	0x00000000 },
+	{ AR5K_MISC_MODE,	0x00000000 },
+	{ AR5K_OFDM_FIL_CNT,	0x00000000 },
+	{ AR5K_CCK_FIL_CNT,	0x00000000 },
+	{ AR5K_PHYERR_CNT1,	0x00000000 },
+	{ AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+	{ AR5K_PHYERR_CNT2,	0x00000000 },
+	{ AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+	{ AR5K_TSF_THRES,	0x00000000 },
+	{ 0x8140,		0x800003f9 },
+	{ 0x8144,		0x00000000 },
+	{ AR5K_PHY_AGC,		0x00000000 },
+	{ AR5K_PHY_ADC_CTL,	0x0000a000 },
+	{ 0x983c,		0x00200400 },
+	{ AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+	{ AR5K_PHY_SCR,		0x0000001f },
+	{ AR5K_PHY_SLMT,	0x00000080 },
+	{ AR5K_PHY_SCAL,	0x0000000e },
+	{ 0x9958,		0x00081fff },
+	{ AR5K_PHY_TIMING_7,	0x00000000 },
+	{ AR5K_PHY_TIMING_8,	0x02800000 },
+	{ AR5K_PHY_TIMING_11,	0x00000000 },
+	{ AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+	{ 0x99e4,		0xaaaaaaaa },
+	{ 0x99e8,		0x3c466478 },
+	{ 0x99ec,		0x000000aa },
+	{ AR5K_PHY_SCLOCK,	0x0000000c },
+	{ AR5K_PHY_SDELAY,	0x000000ff },
+	{ AR5K_PHY_SPENDING,	0x00000014 },
+	{ AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+	{ 0xa23c,		0x93c889af },
+	{ AR5K_PHY_FAST_ADC,	0x00000001 },
+	{ 0xa250,		0x0000a000 },
+	{ AR5K_PHY_BLUETOOTH,	0x00000000 },
+	{ AR5K_PHY_TPC_RG1,	0x0cc75380 },
+	{ 0xa25c,		0x0f0f0f01 },
+	{ 0xa260,		0x5f690f01 },
+	{ 0xa264,		0x00418a11 },
+	{ 0xa268,		0x00000000 },
+	{ AR5K_PHY_TPC_RG5,	0x0c30c16a },
+	{ 0xa270, 0x00820820 },
+	{ 0xa274, 0x081b7caa },
+	{ 0xa278, 0x1ce739ce },
+	{ 0xa27c, 0x051701ce },
+	{ 0xa338, 0x00000000 },
+	{ 0xa33c, 0x00000000 },
+	{ 0xa340, 0x00000000 },
+	{ 0xa344, 0x00000000 },
+	{ 0xa348, 0x3fffffff },
+	{ 0xa34c, 0x3fffffff },
+	{ 0xa350, 0x3fffffff },
+	{ 0xa354, 0x0003ffff },
+	{ 0xa358, 0x79a8aa1f },
+	{ 0xa35c, 0x066c420f },
+	{ 0xa360, 0x0f282207 },
+	{ 0xa364, 0x17601685 },
+	{ 0xa368, 0x1f801104 },
+	{ 0xa36c, 0x37a00c03 },
+	{ 0xa370, 0x3fc40883 },
+	{ 0xa374, 0x57c00803 },
+	{ 0xa378, 0x5fd80682 },
+	{ 0xa37c, 0x7fe00482 },
+	{ 0xa380, 0x7f3c7bba },
+	{ 0xa384, 0xf3307ff0 },
 };
 
 /* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
 static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
 	{ AR5K_TXCFG,
-	/*	      b		g	    gTurbo */
-		{ 0x00000015, 0x00000015, 0x00000015 } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
 	{ AR5K_USEC_5211,
-		{ 0x04e01395, 0x12e013ab, 0x098813cf } },
-	{ AR5K_PHY(10),
-		{ 0x05020000, 0x0a020001, 0x0a020001 } },
-	{ AR5K_PHY(13),
-		{ 0x00000e00, 0x00000e00, 0x00000e00 } },
-	{ AR5K_PHY(14),
-		{ 0x0000000a, 0x0000000a, 0x0000000a } },
-	{ AR5K_PHY(18),
-		{ 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
-	{ AR5K_PHY(20),
-		{ 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } },
+	   { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+	{ AR5K_PHY_RF_CTL3,
+	   { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+	{ AR5K_PHY_RF_CTL4,
+	   { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+	{ AR5K_PHY_PA_CTL,
+	   { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+	{ AR5K_PHY_GAIN,
+	   { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+	{ AR5K_PHY_DESIRED_SIZE,
+	   { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
 	{ AR5K_PHY_SIG,
-		{ 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+	   { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x3137665e, 0x3139605e, 0x3139605e } },
-	{ AR5K_PHY(27),
-		{ 0x050cb081, 0x050cb081, 0x050cb081 } },
+	   { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+	{ AR5K_PHY_WEAK_OFDM_LOW_THR,
+	   { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x0000044c, 0x00000898, 0x000007d0 } },
+	   { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+	   { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
 	{ AR5K_PHY_CCKTXCTL,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(642),
-		{ 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+	   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ AR5K_PHY_CCK_CROSSCORR,
+	   { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
 	{ AR5K_PHY_GAIN_2GHZ,
-		{ 0x0042c140, 0x0042c140, 0x0042c140 } },
-	{ 0xa21c,
-		{ 0x1863800a, 0x1883800a, 0x1883800a } },
-	{ AR5K_DCU_FP,
-		{ 0x000003e0, 0x000003e0, 0x000003e0 } },
-	{ 0x8060,
-		{ 0x0000000f, 0x0000000f, 0x0000000f } },
-	{ 0x8118,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x811c,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8120,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8124,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8128,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x812c,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8130,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8134,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8138,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x813c,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0x8140,
-		{ 0x800000a8, 0x800000a8, 0x800000a8 } },
-	{ 0x8144,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_AGC,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(11),
-		{ 0x0000a000, 0x0000a000, 0x0000a000 } },
-	{ AR5K_PHY(15),
-		{ 0x00200400, 0x00200400, 0x00200400 } },
-	{ AR5K_PHY(19),
-		{ 0x1284233c, 0x1284233c, 0x1284233c } },
-	{ AR5K_PHY_SCR,
-		{ 0x0000001f, 0x0000001f, 0x0000001f } },
-	{ AR5K_PHY_SLMT,
-		{ 0x00000080, 0x00000080, 0x00000080 } },
-	{ AR5K_PHY_SCAL,
-		{ 0x0000000e, 0x0000000e, 0x0000000e } },
-	{ AR5K_PHY(86),
-		{ 0x000000ff, 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY(96),
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(97),
-		{ 0x02800000, 0x02800000, 0x02800000 } },
-	{ AR5K_PHY(104),
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(120),
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(121),
-		{ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
-	{ AR5K_PHY(122),
-		{ 0x3c466478, 0x3c466478, 0x3c466478 } },
-	{ AR5K_PHY(123),
-		{ 0x000000aa, 0x000000aa, 0x000000aa } },
-	{ AR5K_PHY_SCLOCK,
-		{ 0x0000000c, 0x0000000c, 0x0000000c } },
-	{ AR5K_PHY_SDELAY,
-		{ 0x000000ff, 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY_SPENDING,
-		{ 0x00000014, 0x00000014, 0x00000014 } },
-	{ 0xa228,
-		{ 0x000009b5, 0x000009b5, 0x000009b5 } },
-	{ 0xa23c,
-		{ 0x93c889af, 0x93c889af, 0x93c889af } },
-	{ 0xa24c,
-		{ 0x00000001, 0x00000001, 0x00000001 } },
-	{ 0xa250,
-		{ 0x0000a000, 0x0000a000, 0x0000a000 } },
-	{ 0xa254,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa258,
-		{ 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
-	{ 0xa25c,
-		{ 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
-	{ 0xa260,
-		{ 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
-	{ 0xa264,
-		{ 0x00418a11, 0x00418a11, 0x00418a11 } },
-	{ 0xa268,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa26c,
-		{ 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
-	{ 0xa270,
-		{ 0x00820820, 0x00820820, 0x00820820 } },
-	{ 0xa274,
-		{ 0x001b7caa, 0x001b7caa, 0x001b7caa } },
-	{ 0xa278,
-		{ 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
-	{ 0xa27c,
-		{ 0x051701ce, 0x051701ce, 0x051701ce } },
-	{ 0xa300,
-		{ 0x18010000, 0x18010000, 0x18010000 } },
-	{ 0xa304,
-		{ 0x30032602, 0x30032602, 0x30032602 } },
-	{ 0xa308,
-		{ 0x48073e06, 0x48073e06, 0x48073e06 } },
-	{ 0xa30c,
-		{ 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
-	{ 0xa310,
-		{ 0x641a600f, 0x641a600f, 0x641a600f } },
-	{ 0xa314,
-		{ 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
-	{ 0xa318,
-		{ 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
-	{ 0xa31c,
-		{ 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
-	{ 0xa320,
-		{ 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
-	{ 0xa324,
-		{ 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
-	{ 0xa328,
-		{ 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
-	{ 0xa32c,
-		{ 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
-	{ 0xa330,
-		{ 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
-	{ 0xa334,
-		{ 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
-	{ 0xa338,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa33c,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa340,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa344,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0xa348,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa34c,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa350,
-		{ 0x3fffffff, 0x3fffffff, 0x3fffffff } },
-	{ 0xa354,
-		{ 0x0003ffff, 0x0003ffff, 0x0003ffff } },
-	{ 0xa358,
-		{ 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
-	{ 0xa35c,
-		{ 0x066c420f, 0x066c420f, 0x066c420f } },
-	{ 0xa360,
-		{ 0x0f282207, 0x0f282207, 0x0f282207 } },
-	{ 0xa364,
-		{ 0x17601685, 0x17601685, 0x17601685 } },
-	{ 0xa368,
-		{ 0x1f801104, 0x1f801104, 0x1f801104 } },
-	{ 0xa36c,
-		{ 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
-	{ 0xa370,
-		{ 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
-	{ 0xa374,
-		{ 0x57c00803, 0x57c00803, 0x57c00803 } },
-	{ 0xa378,
-		{ 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
-	{ 0xa37c,
-		{ 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
-	{ 0xa380,
-		{ 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
-	{ 0xa384,
-		{ 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+	   { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+	{ AR5K_PHY_CCK_RX_CTL_4,
+	   { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf2413_ini_common_end[] = {
+	{ AR5K_DCU_FP,		0x000003e0 },
+	{ AR5K_SEQ_MASK,	0x0000000f },
+	{ AR5K_MIC_QOS_CTL,	0x00000000 },
+	{ AR5K_MIC_QOS_SEL,	0x00000000 },
+	{ AR5K_MISC_MODE,	0x00000000 },
+	{ AR5K_OFDM_FIL_CNT,	0x00000000 },
+	{ AR5K_CCK_FIL_CNT,	0x00000000 },
+	{ AR5K_PHYERR_CNT1,	0x00000000 },
+	{ AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+	{ AR5K_PHYERR_CNT2,	0x00000000 },
+	{ AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+	{ AR5K_TSF_THRES,	0x00000000 },
+	{ 0x8140,		0x800000a8 },
+	{ 0x8144,		0x00000000 },
+	{ AR5K_PHY_AGC,		0x00000000 },
+	{ AR5K_PHY_ADC_CTL,	0x0000a000 },
+	{ 0x983c,		0x00200400 },
+	{ AR5K_PHY_GAIN_OFFSET,	0x1284233c },
+	{ AR5K_PHY_SCR,		0x0000001f },
+	{ AR5K_PHY_SLMT,	0x00000080 },
+	{ AR5K_PHY_SCAL,	0x0000000e },
+	{ 0x9958,		0x000000ff },
+	{ AR5K_PHY_TIMING_7,	0x00000000 },
+	{ AR5K_PHY_TIMING_8,	0x02800000 },
+	{ AR5K_PHY_TIMING_11,	0x00000000 },
+	{ AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+	{ 0x99e4,		0xaaaaaaaa },
+	{ 0x99e8,		0x3c466478 },
+	{ 0x99ec,		0x000000aa },
+	{ AR5K_PHY_SCLOCK,	0x0000000c },
+	{ AR5K_PHY_SDELAY,	0x000000ff },
+	{ AR5K_PHY_SPENDING,	0x00000014 },
+	{ AR5K_PHY_DAG_CCK_CTL,	0x000009b5 },
+	{ 0xa23c,		0x93c889af },
+	{ AR5K_PHY_FAST_ADC,	0x00000001 },
+	{ 0xa250,		0x0000a000 },
+	{ AR5K_PHY_BLUETOOTH,	0x00000000 },
+	{ AR5K_PHY_TPC_RG1,	0x0cc75380 },
+	{ 0xa25c,		0x0f0f0f01 },
+	{ 0xa260,		0x5f690f01 },
+	{ 0xa264,		0x00418a11 },
+	{ 0xa268,		0x00000000 },
+	{ AR5K_PHY_TPC_RG5,	0x0c30c16a },
+	{ 0xa270, 0x00820820 },
+	{ 0xa274, 0x001b7caa },
+	{ 0xa278, 0x1ce739ce },
+	{ 0xa27c, 0x051701ce },
+	{ 0xa300, 0x18010000 },
+	{ 0xa304, 0x30032602 },
+	{ 0xa308, 0x48073e06 },
+	{ 0xa30c, 0x560b4c0a },
+	{ 0xa310, 0x641a600f },
+	{ 0xa314, 0x784f6e1b },
+	{ 0xa318, 0x868f7c5a },
+	{ 0xa31c, 0x8ecf865b },
+	{ 0xa320, 0x9d4f970f },
+	{ 0xa324, 0xa5cfa18f },
+	{ 0xa328, 0xb55faf1f },
+	{ 0xa32c, 0xbddfb99f },
+	{ 0xa330, 0xcd7fc73f },
+	{ 0xa334, 0xd5ffd1bf },
+	{ 0xa338, 0x00000000 },
+	{ 0xa33c, 0x00000000 },
+	{ 0xa340, 0x00000000 },
+	{ 0xa344, 0x00000000 },
+	{ 0xa348, 0x3fffffff },
+	{ 0xa34c, 0x3fffffff },
+	{ 0xa350, 0x3fffffff },
+	{ 0xa354, 0x0003ffff },
+	{ 0xa358, 0x79a8aa1f },
+	{ 0xa35c, 0x066c420f },
+	{ 0xa360, 0x0f282207 },
+	{ 0xa364, 0x17601685 },
+	{ 0xa368, 0x1f801104 },
+	{ 0xa36c, 0x37a00c03 },
+	{ 0xa370, 0x3fc40883 },
+	{ 0xa374, 0x57c00803 },
+	{ 0xa378, 0x5fd80682 },
+	{ 0xa37c, 0x7fe00482 },
+	{ 0xa380, 0x7f3c7bba },
+	{ 0xa384, 0xf3307ff0 },
 };
 
 /* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
 static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
 	{ AR5K_TXCFG,
-	/*	       g	gTurbo */
-		{ 0x00000015, 0x00000015 } },
+	/*	a/XR	   aTurbo	  b	   g (DYN)     gTurbo     */
+	   { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
 	{ AR5K_USEC_5211,
-		{ 0x12e013ab, 0x098813cf } },
+	   { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
 	{ AR5K_PHY_TURBO,
-		{ 0x00000000, 0x00000003 } },
-	{ AR5K_PHY(10),
-		{ 0x0a020001, 0x0a020001 } },
-	{ AR5K_PHY(13),
-		{ 0x00000e0e, 0x00000e0e } },
-	{ AR5K_PHY(14),
-		{ 0x0000000b, 0x0000000b } },
-	{ AR5K_PHY(17),
-		{ 0x13721422, 0x13721422 } },
-	{ AR5K_PHY(18),
-		{ 0x00199a65, 0x00199a65 } },
-	{ AR5K_PHY(20),
-		{ 0x0c98b0da, 0x0c98b0da } },
+	   { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+	{ AR5K_PHY_RF_CTL3,
+	   { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+	{ AR5K_PHY_RF_CTL4,
+	   { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+	{ AR5K_PHY_PA_CTL,
+	   { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+	{ AR5K_PHY_SETTLING,
+	   { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+	{ AR5K_PHY_GAIN,
+	   { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+	{ AR5K_PHY_DESIRED_SIZE,
+	   { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
 	{ AR5K_PHY_SIG,
-		{ 0x7ec80d2e, 0x7ec80d2e } },
+	   { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
 	{ AR5K_PHY_AGCCOARSE,
-		{ 0x3139605e, 0x3139605e } },
-	{ AR5K_PHY(27),
-		{ 0x050cb081, 0x050cb081 } },
+	   { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+	{ AR5K_PHY_WEAK_OFDM_LOW_THR,
+	   { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
 	{ AR5K_PHY_RX_DELAY,
-		{ 0x00000898, 0x000007d0 } },
+	   { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
 	{ AR5K_PHY_FRAME_CTL_5211,
-		{ 0xf7b81000, 0xf7b81000 } },
+	   { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
 	{ AR5K_PHY_CCKTXCTL,
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(642),
-		{ 0xd03e6788, 0xd03e6788 } },
+	   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ AR5K_PHY_CCK_CROSSCORR,
+	   { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
 	{ AR5K_PHY_GAIN_2GHZ,
-		{ 0x0052c140, 0x0052c140 } },
-	{ 0xa21c,
-		{ 0x1883800a, 0x1883800a } },
+	   { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+	{ AR5K_PHY_CCK_RX_CTL_4,
+	   { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
 	{ 0xa324,
-		{ 0xa7cfa7cf, 0xa7cfa7cf } },
+	   { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
 	{ 0xa328,
-		{ 0xa7cfa7cf, 0xa7cfa7cf } },
+	   { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
 	{ 0xa32c,
-		{ 0xa7cfa7cf, 0xa7cfa7cf } },
+	   { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
 	{ 0xa330,
-		{ 0xa7cfa7cf, 0xa7cfa7cf } },
+	   { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
 	{ 0xa334,
-		{ 0xa7cfa7cf, 0xa7cfa7cf } },
-	{ AR5K_DCU_FP,
-		{ 0x000003e0, 0x000003e0 } },
-	{ 0x8060,
-		{ 0x0000000f, 0x0000000f } },
-	{ 0x809c,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x80a0,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8118,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x811c,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8120,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8124,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8128,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x812c,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8130,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8134,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8138,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x813c,
-		{ 0x00000000, 0x00000000 } },
-	{ 0x8140,
-		{ 0x800003f9, 0x800003f9 } },
-	{ 0x8144,
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY_AGC,
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(11),
-		{ 0x0000a000, 0x0000a000 } },
-	{ AR5K_PHY(15),
-		{ 0x00200400, 0x00200400 } },
-	{ AR5K_PHY(19),
-		{ 0x1284233c, 0x1284233c } },
-	{ AR5K_PHY_SCR,
-		{ 0x0000001f, 0x0000001f } },
-	{ AR5K_PHY_SLMT,
-		{ 0x00000080, 0x00000080 } },
-	{ AR5K_PHY_SCAL,
-		{ 0x0000000e, 0x0000000e } },
-	{ AR5K_PHY(86),
-		{ 0x00081fff, 0x00081fff } },
-	{ AR5K_PHY(96),
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(97),
-		{ 0x02800000, 0x02800000 } },
-	{ AR5K_PHY(104),
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(119),
-		{ 0xfebadbe8, 0xfebadbe8 } },
-	{ AR5K_PHY(120),
-		{ 0x00000000, 0x00000000 } },
-	{ AR5K_PHY(121),
-		{ 0xaaaaaaaa, 0xaaaaaaaa } },
-	{ AR5K_PHY(122),
-		{ 0x3c466478, 0x3c466478 } },
-	{ AR5K_PHY(123),
-		{ 0x000000aa, 0x000000aa } },
-	{ AR5K_PHY_SCLOCK,
-		{ 0x0000000c, 0x0000000c } },
-	{ AR5K_PHY_SDELAY,
-		{ 0x000000ff, 0x000000ff } },
-	{ AR5K_PHY_SPENDING,
-		{ 0x00000014, 0x00000014 } },
-	{ 0xa228,
-		{ 0x000009b5, 0x000009b5 } },
-	{ AR5K_PHY_TXPOWER_RATE3,
-		{ 0x20202020, 0x20202020 } },
-	{ AR5K_PHY_TXPOWER_RATE4,
-		{ 0x20202020, 0x20202020 } },
-	{ 0xa23c,
-		{ 0x93c889af, 0x93c889af } },
-	{ 0xa24c,
-		{ 0x00000001, 0x00000001 } },
-	{ 0xa250,
-		{ 0x0000a000, 0x0000a000 } },
-	{ 0xa254,
-		{ 0x00000000, 0x00000000 } },
-	{ 0xa258,
-		{ 0x0cc75380, 0x0cc75380 } },
-	{ 0xa25c,
-		{ 0x0f0f0f01, 0x0f0f0f01 } },
-	{ 0xa260,
-		{ 0x5f690f01, 0x5f690f01 } },
-	{ 0xa264,
-		{ 0x00418a11, 0x00418a11 } },
-	{ 0xa268,
-		{ 0x00000000, 0x00000000 } },
-	{ 0xa26c,
-		{ 0x0c30c166, 0x0c30c166 } },
-	{ 0xa270,
-		{ 0x00820820, 0x00820820 } },
-	{ 0xa274,
-		{ 0x081a3caa, 0x081a3caa } },
-	{ 0xa278,
-		{ 0x1ce739ce, 0x1ce739ce } },
-	{ 0xa27c,
-		{ 0x051701ce, 0x051701ce } },
-	{ 0xa300,
-		{ 0x16010000, 0x16010000 } },
-	{ 0xa304,
-		{ 0x2c032402, 0x2c032402 } },
-	{ 0xa308,
-		{ 0x48433e42, 0x48433e42 } },
-	{ 0xa30c,
-		{ 0x5a0f500b, 0x5a0f500b } },
-	{ 0xa310,
-		{ 0x6c4b624a, 0x6c4b624a } },
-	{ 0xa314,
-		{ 0x7e8b748a, 0x7e8b748a } },
-	{ 0xa318,
-		{ 0x96cf8ccb, 0x96cf8ccb } },
-	{ 0xa31c,
-		{ 0xa34f9d0f, 0xa34f9d0f } },
-	{ 0xa320,
-		{ 0xa7cfa58f, 0xa7cfa58f } },
-	{ 0xa348,
-		{ 0x3fffffff, 0x3fffffff } },
-	{ 0xa34c,
-		{ 0x3fffffff, 0x3fffffff } },
-	{ 0xa350,
-		{ 0x3fffffff, 0x3fffffff } },
-	{ 0xa354,
-		{ 0x0003ffff, 0x0003ffff } },
-	{ 0xa358,
-		{ 0x79a8aa1f, 0x79a8aa1f } },
-	{ 0xa35c,
-		{ 0x066c420f, 0x066c420f } },
-	{ 0xa360,
-		{ 0x0f282207, 0x0f282207 } },
-	{ 0xa364,
-		{ 0x17601685, 0x17601685 } },
-	{ 0xa368,
-		{ 0x1f801104, 0x1f801104 } },
-	{ 0xa36c,
-		{ 0x37a00c03, 0x37a00c03 } },
-	{ 0xa370,
-		{ 0x3fc40883, 0x3fc40883 } },
-	{ 0xa374,
-		{ 0x57c00803, 0x57c00803 } },
-	{ 0xa378,
-		{ 0x5fd80682, 0x5fd80682 } },
-	{ 0xa37c,
-		{ 0x7fe00482, 0x7fe00482 } },
-	{ 0xa380,
-		{ 0x7f3c7bba, 0x7f3c7bba } },
-	{ 0xa384,
-		{ 0xf3307ff0, 0xf3307ff0 } },
+	   { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+};
+
+static const struct ath5k_ini rf2425_ini_common_end[] = {
+	{ AR5K_DCU_FP,		0x000003e0 },
+	{ AR5K_SEQ_MASK,	0x0000000f },
+	{ 0x809c,		0x00000000 },
+	{ 0x80a0,		0x00000000 },
+	{ AR5K_MIC_QOS_CTL,	0x00000000 },
+	{ AR5K_MIC_QOS_SEL,	0x00000000 },
+	{ AR5K_MISC_MODE,	0x00000000 },
+	{ AR5K_OFDM_FIL_CNT,	0x00000000 },
+	{ AR5K_CCK_FIL_CNT,	0x00000000 },
+	{ AR5K_PHYERR_CNT1,	0x00000000 },
+	{ AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+	{ AR5K_PHYERR_CNT2,	0x00000000 },
+	{ AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+	{ AR5K_TSF_THRES,	0x00000000 },
+	{ 0x8140,		0x800003f9 },
+	{ 0x8144,		0x00000000 },
+	{ AR5K_PHY_AGC,		0x00000000 },
+	{ AR5K_PHY_ADC_CTL,	0x0000a000 },
+	{ 0x983c,		0x00200400 },
+	{ AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+	{ AR5K_PHY_SCR,		0x0000001f },
+	{ AR5K_PHY_SLMT,	0x00000080 },
+	{ AR5K_PHY_SCAL,	0x0000000e },
+	{ 0x9958,		0x00081fff },
+	{ AR5K_PHY_TIMING_7,	0x00000000 },
+	{ AR5K_PHY_TIMING_8,	0x02800000 },
+	{ AR5K_PHY_TIMING_11,	0x00000000 },
+	{ 0x99dc,		0xfebadbe8 },
+	{ AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+	{ 0x99e4,		0xaaaaaaaa },
+	{ 0x99e8,		0x3c466478 },
+	{ 0x99ec,		0x000000aa },
+	{ AR5K_PHY_SCLOCK,	0x0000000c },
+	{ AR5K_PHY_SDELAY,	0x000000ff },
+	{ AR5K_PHY_SPENDING,	0x00000014 },
+	{ AR5K_PHY_DAG_CCK_CTL,	0x000009b5 },
+	{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+	{ AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+	{ 0xa23c,		0x93c889af },
+	{ AR5K_PHY_FAST_ADC,	0x00000001 },
+	{ 0xa250,		0x0000a000 },
+	{ AR5K_PHY_BLUETOOTH,	0x00000000 },
+	{ AR5K_PHY_TPC_RG1,	0x0cc75380 },
+	{ 0xa25c,		0x0f0f0f01 },
+	{ 0xa260,		0x5f690f01 },
+	{ 0xa264,		0x00418a11 },
+	{ 0xa268,		0x00000000 },
+	{ AR5K_PHY_TPC_RG5,	0x0c30c166 },
+	{ 0xa270, 0x00820820 },
+	{ 0xa274, 0x081a3caa },
+	{ 0xa278, 0x1ce739ce },
+	{ 0xa27c, 0x051701ce },
+	{ 0xa300, 0x16010000 },
+	{ 0xa304, 0x2c032402 },
+	{ 0xa308, 0x48433e42 },
+	{ 0xa30c, 0x5a0f500b },
+	{ 0xa310, 0x6c4b624a },
+	{ 0xa314, 0x7e8b748a },
+	{ 0xa318, 0x96cf8ccb },
+	{ 0xa31c, 0xa34f9d0f },
+	{ 0xa320, 0xa7cfa58f },
+	{ 0xa348, 0x3fffffff },
+	{ 0xa34c, 0x3fffffff },
+	{ 0xa350, 0x3fffffff },
+	{ 0xa354, 0x0003ffff },
+	{ 0xa358, 0x79a8aa1f },
+	{ 0xa35c, 0x066c420f },
+	{ 0xa360, 0x0f282207 },
+	{ 0xa364, 0x17601685 },
+	{ 0xa368, 0x1f801104 },
+	{ 0xa36c, 0x37a00c03 },
+	{ 0xa370, 0x3fc40883 },
+	{ 0xa374, 0x57c00803 },
+	{ 0xa378, 0x5fd80682 },
+	{ 0xa37c, 0x7fe00482 },
+	{ 0xa380, 0x7f3c7bba },
+	{ 0xa384, 0xf3307ff0 },
 };
 
 /*
@@ -1560,7 +1297,7 @@ static const struct ath5k_ini rf5111_ini
 	{ AR5K_BB_GAIN(63), 0x00000016 },
 };
 
-/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414) */
+/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
 static const struct ath5k_ini rf5112_ini_bbgain[] = {
 	{ AR5K_BB_GAIN(0), 0x00000000 },
 	{ AR5K_BB_GAIN(1), 0x00000001 },
@@ -1691,87 +1428,97 @@ int ath5k_hw_write_initvals(struct ath5k
 		/*
 		 * Write initial settings common for all modes
 		 */
-		ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini),
-					ar5212_ini, change_channel);
+		ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
+				ar5212_ini_common_start, change_channel);
 
 		/* Second set of mode-specific settings */
-		if (ah->ah_radio == AR5K_RF5111) {
+		switch (ah->ah_radio) {
+		case AR5K_RF5111:
 
 			ath5k_hw_ini_mode_registers(ah,
-					ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
-					ar5212_rf5111_ini_mode_end, mode);
+					ARRAY_SIZE(rf5111_ini_mode_end),
+					rf5111_ini_mode_end, mode);
+
+			ath5k_hw_ini_registers(ah,
+					ARRAY_SIZE(rf5111_ini_common_end),
+					rf5111_ini_common_end, change_channel);
 
 			/* Baseband gain table */
 			ath5k_hw_ini_registers(ah,
 					ARRAY_SIZE(rf5111_ini_bbgain),
 					rf5111_ini_bbgain, change_channel);
 
-		} else if (ah->ah_radio == AR5K_RF5112) {
+			break;
+		case AR5K_RF5112:
 
 			ath5k_hw_ini_mode_registers(ah,
-					ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
-					ar5212_rf5112_ini_mode_end, mode);
+					ARRAY_SIZE(rf5112_ini_mode_end),
+					rf5112_ini_mode_end, mode);
+
+			ath5k_hw_ini_registers(ah,
+					ARRAY_SIZE(rf5112_ini_common_end),
+					rf5112_ini_common_end, change_channel);
 
 			ath5k_hw_ini_registers(ah,
 					ARRAY_SIZE(rf5112_ini_bbgain),
 					rf5112_ini_bbgain, change_channel);
 
-		} else if (ah->ah_radio == AR5K_RF5413) {
+			break;
+		case AR5K_RF5413:
 
 			ath5k_hw_ini_mode_registers(ah,
 					ARRAY_SIZE(rf5413_ini_mode_end),
 					rf5413_ini_mode_end, mode);
 
 			ath5k_hw_ini_registers(ah,
+					ARRAY_SIZE(rf5413_ini_common_end),
+					rf5413_ini_common_end, change_channel);
+
+			ath5k_hw_ini_registers(ah,
 					ARRAY_SIZE(rf5112_ini_bbgain),
 					rf5112_ini_bbgain, change_channel);
 
-		} else if (ah->ah_radio == AR5K_RF2413) {
-
-			if (mode < 2) {
-				ATH5K_ERR(ah->ah_sc,
-					"unsupported channel mode: %d\n", mode);
-				return -EINVAL;
-			}
-			mode = mode - 2;
-
-			/* Override a setting from ar5212_ini */
-			ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+			break;
+		case AR5K_RF2316:
+		case AR5K_RF2413:
 
 			ath5k_hw_ini_mode_registers(ah,
 					ARRAY_SIZE(rf2413_ini_mode_end),
 					rf2413_ini_mode_end, mode);
 
-			/* Baseband gain table */
 			ath5k_hw_ini_registers(ah,
-					ARRAY_SIZE(rf5112_ini_bbgain),
-					rf5112_ini_bbgain, change_channel);
-
-		} else if (ah->ah_radio == AR5K_RF2425) {
+					ARRAY_SIZE(rf2413_ini_common_end),
+					rf2413_ini_common_end, change_channel);
 
-			if (mode < 2) {
-				ATH5K_ERR(ah->ah_sc,
-					"unsupported channel mode: %d\n", mode);
-				return -EINVAL;
+			/* Override settings from rf2413_ini_common_end */
+			if (ah->ah_radio == AR5K_RF2316) {
+				ath5k_hw_reg_write(ah, 0x00004000,
+							AR5K_PHY_AGC);
+				ath5k_hw_reg_write(ah, 0x081b7caa,
+							0xa274);
 			}
 
-			/* Map b to g */
-			if (mode == 2)
-				mode = 0;
-			else
-				mode = mode - 3;
-
-			/* Override a setting from ar5212_ini */
-			ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+			ath5k_hw_ini_registers(ah,
+					ARRAY_SIZE(rf5112_ini_bbgain),
+					rf5112_ini_bbgain, change_channel);
+			break;
+		case AR5K_RF2317:
+		case AR5K_RF2425:
 
 			ath5k_hw_ini_mode_registers(ah,
 					ARRAY_SIZE(rf2425_ini_mode_end),
 					rf2425_ini_mode_end, mode);
 
-			/* Baseband gain table */
+			ath5k_hw_ini_registers(ah,
+					ARRAY_SIZE(rf2425_ini_common_end),
+					rf2425_ini_common_end, change_channel);
+
 			ath5k_hw_ini_registers(ah,
 					ARRAY_SIZE(rf5112_ini_bbgain),
 					rf5112_ini_bbgain, change_channel);
+			break;
+		default:
+			return -EINVAL;
 
 		}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/led.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/led.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/led.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/led.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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
+ *    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 NONINFRINGEMENT, 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/pci.h>
+#include "ath5k.h"
+#include "base.h"
+
+#define ATH_SDEVICE(subv,subd) \
+	.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+	.subvendor = (subv), .subdevice = (subd)
+
+#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_PIN(data) ((data) >> 8)
+#define ATH_POLARITY(data) ((data) & 0xff)
+
+/* Devices we match on for LED config info (typically laptops) */
+static const struct pci_device_id ath5k_led_devices[] = {
+	/* IBM-specific AR5212 */
+	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+	/* AR5211 */
+	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
+	/* HP Compaq nc6xx, nc4000, nx6000 */
+	{ 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 Ferrari 5000 (russ.dill@gmail.com) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
+	/* E-machines E510 (tuliom@gmail.com) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+	/* Acer Extensa 5620z (nekoreeve@gmail.com) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+	{ }
+};
+
+void ath5k_led_enable(struct ath5k_softc *sc)
+{
+	if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+		ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+		ath5k_led_off(sc);
+	}
+}
+
+void ath5k_led_on(struct ath5k_softc *sc)
+{
+	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+		return;
+	ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+}
+
+void ath5k_led_off(struct ath5k_softc *sc)
+{
+	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+		return;
+	ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+	enum led_brightness brightness)
+{
+	struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+		led_dev);
+
+	if (brightness == LED_OFF)
+		ath5k_led_off(led->sc);
+	else
+		ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+		   const char *name, char *trigger)
+{
+	int err;
+
+	led->sc = sc;
+	strncpy(led->name, name, sizeof(led->name));
+	led->led_dev.name = led->name;
+	led->led_dev.default_trigger = trigger;
+	led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+	err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+	if (err) {
+		ATH5K_WARN(sc, "could not register LED %s\n", name);
+		led->sc = NULL;
+	}
+	return err;
+}
+
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+	if (!led->sc)
+		return;
+	led_classdev_unregister(&led->led_dev);
+	ath5k_led_off(led->sc);
+	led->sc = NULL;
+}
+
+void ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+	ath5k_unregister_led(&sc->rx_led);
+	ath5k_unregister_led(&sc->tx_led);
+}
+
+int ath5k_init_leds(struct ath5k_softc *sc)
+{
+	int ret = 0;
+	struct ieee80211_hw *hw = sc->hw;
+	struct pci_dev *pdev = sc->pdev;
+	char name[ATH5K_LED_MAX_NAME_LEN + 1];
+	const struct pci_device_id *match;
+
+	match = pci_match_id(&ath5k_led_devices[0], pdev);
+	if (match) {
+		__set_bit(ATH_STAT_LEDSOFT, sc->status);
+		sc->led_pin = ATH_PIN(match->driver_data);
+		sc->led_on = ATH_POLARITY(match->driver_data);
+	}
+
+	if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+		goto out;
+
+	ath5k_led_enable(sc);
+
+	snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+	ret = ath5k_register_led(sc, &sc->rx_led, name,
+		ieee80211_get_rx_led_name(hw));
+	if (ret)
+		goto out;
+
+	snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+	ret = ath5k_register_led(sc, &sc->tx_led, name,
+		ieee80211_get_tx_led_name(hw));
+out:
+	return ret;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -10,5 +10,6 @@ ath5k-y				+= phy.o
 ath5k-y				+= reset.o
 ath5k-y				+= attach.o
 ath5k-y				+= base.o
+ath5k-y				+= led.o
 ath5k-$(CONFIG_ATH5K_DEBUG)	+= debug.o
 obj-$(CONFIG_ATH5K)		+= ath5k.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/pcu.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/pcu.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/pcu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/pcu.c	2009-06-09 23:05:27.000000000 -0400
@@ -646,6 +646,22 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *
 }
 
 /**
+ * ath5k_hw_set_tsf64 - Set a new 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ * @tsf64: The new 64bit TSF
+ *
+ * Sets the new TSF
+ */
+void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
+{
+	ATH5K_TRACE(ah->ah_sc);
+
+	ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
+	ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
+}
+
+/**
  * ath5k_hw_reset_tsf - Force a TSF reset
  *
  * @ah: The &struct ath5k_hw
@@ -1026,6 +1042,9 @@ int ath5k_keycache_type(const struct iee
 			return AR5K_KEYTABLE_TYPE_40;
 		else if (key->keylen == LEN_WEP104)
 			return AR5K_KEYTABLE_TYPE_104;
+		return -EINVAL;
+	default:
+		return -EINVAL;
 	}
 	return -EINVAL;
 }
@@ -1041,7 +1060,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah
 	__le32 key_v[5] = {};
 	__le32 key0 = 0, key1 = 0;
 	__le32 *rxmic, *txmic;
-	u32 keytype;
+	int keytype;
 	u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
 	bool is_tkip;
 	const u8 *key_ptr;
@@ -1139,7 +1158,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k
 
 	/* 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. */
-	if (unlikely(mac == NULL)) {
+	if (!mac) {
 		low_id = 0xffffffff;
 		high_id = 0xffff | AR5K_KEYTABLE_VALID;
 	} else {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/phy.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,8 +2,9 @@
  * PHY functions
  *
  * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
  * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -26,1138 +27,193 @@
 #include "ath5k.h"
 #include "reg.h"
 #include "base.h"
-
-/* Struct to hold initial RF register values (RF Banks) */
-struct ath5k_ini_rf {
-	u8	rf_bank;	/* check out ath5k_reg.h */
-	u16	rf_register;	/* register address */
-	u32	rf_value[5];	/* register value for different modes (above) */
-};
+#include "rfbuffer.h"
+#include "rfgain.h"
 
 /*
- * Mode-specific RF Gain table (64bytes) for RF5111/5112
- * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
- * RF Gain values are included in AR5K_AR5210_INI)
+ * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
  */
-struct ath5k_ini_rfgain {
-	u16	rfg_register;	/* RF Gain register address */
-	u32	rfg_value[2];	/* [freq (see below)] */
-};
-
-struct ath5k_gain_opt {
-	u32			go_default;
-	u32			go_steps_count;
-	const struct ath5k_gain_opt_step	go_step[AR5K_GAIN_STEP_COUNT];
-};
+static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
+					const struct ath5k_rf_reg *rf_regs,
+					u32 val, u8 reg_id, bool set)
+{
+	const struct ath5k_rf_reg *rfreg = NULL;
+	u8 offset, bank, num_bits, col, position;
+	u16 entry;
+	u32 mask, data, last_bit, bits_shifted, first_bit;
+	u32 *rfb;
+	s32 bits_left;
+	int i;
 
-/* RF5111 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5111[] = {
-	{ 0, 0x989c,
-	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 0, 0x989c,
-	    { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
-	{ 0, 0x989c,
-	    { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
-	{ 0, 0x98d4,
-	    { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
-	{ 1, 0x98d4,
-	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, 0x98d4,
-	    { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
-	{ 3, 0x98d8,
-	    { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-	{ 6, 0x989c,
-	    { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
-	{ 6, 0x989c,
-	    { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
-	{ 6, 0x989c,
-	    { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
-	{ 6, 0x989c,
-	    { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
-	{ 6, 0x989c,
-	    { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
-	{ 6, 0x98d4,
-	    { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
-	{ 7, 0x989c,
-	    { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
-	{ 7, 0x989c,
-	    { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
-	{ 7, 0x989c,
-	    { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-	{ 7, 0x989c,
-	    { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
-	{ 7, 0x989c,
-	    { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
-	{ 7, 0x989c,
-	    { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
-	{ 7, 0x989c,
-	    { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
-	{ 7, 0x98cc,
-	    { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
-};
+	data = 0;
+	rfb = ah->ah_rf_banks;
 
-/* Initial RF Gain settings for RF5111 */
-static const struct ath5k_ini_rfgain rfgain_5111[] = {
-	/*			      5Ghz	2Ghz	*/
-	{ AR5K_RF_GAIN(0),	{ 0x000001a9, 0x00000000 } },
-	{ AR5K_RF_GAIN(1),	{ 0x000001e9, 0x00000040 } },
-	{ AR5K_RF_GAIN(2),	{ 0x00000029, 0x00000080 } },
-	{ AR5K_RF_GAIN(3),	{ 0x00000069, 0x00000150 } },
-	{ AR5K_RF_GAIN(4),	{ 0x00000199, 0x00000190 } },
-	{ AR5K_RF_GAIN(5),	{ 0x000001d9, 0x000001d0 } },
-	{ AR5K_RF_GAIN(6),	{ 0x00000019, 0x00000010 } },
-	{ AR5K_RF_GAIN(7),	{ 0x00000059, 0x00000044 } },
-	{ AR5K_RF_GAIN(8),	{ 0x00000099, 0x00000084 } },
-	{ AR5K_RF_GAIN(9),	{ 0x000001a5, 0x00000148 } },
-	{ AR5K_RF_GAIN(10),	{ 0x000001e5, 0x00000188 } },
-	{ AR5K_RF_GAIN(11),	{ 0x00000025, 0x000001c8 } },
-	{ AR5K_RF_GAIN(12),	{ 0x000001c8, 0x00000014 } },
-	{ AR5K_RF_GAIN(13),	{ 0x00000008, 0x00000042 } },
-	{ AR5K_RF_GAIN(14),	{ 0x00000048, 0x00000082 } },
-	{ AR5K_RF_GAIN(15),	{ 0x00000088, 0x00000178 } },
-	{ AR5K_RF_GAIN(16),	{ 0x00000198, 0x000001b8 } },
-	{ AR5K_RF_GAIN(17),	{ 0x000001d8, 0x000001f8 } },
-	{ AR5K_RF_GAIN(18),	{ 0x00000018, 0x00000012 } },
-	{ AR5K_RF_GAIN(19),	{ 0x00000058, 0x00000052 } },
-	{ AR5K_RF_GAIN(20),	{ 0x00000098, 0x00000092 } },
-	{ AR5K_RF_GAIN(21),	{ 0x000001a4, 0x0000017c } },
-	{ AR5K_RF_GAIN(22),	{ 0x000001e4, 0x000001bc } },
-	{ AR5K_RF_GAIN(23),	{ 0x00000024, 0x000001fc } },
-	{ AR5K_RF_GAIN(24),	{ 0x00000064, 0x0000000a } },
-	{ AR5K_RF_GAIN(25),	{ 0x000000a4, 0x0000004a } },
-	{ AR5K_RF_GAIN(26),	{ 0x000000e4, 0x0000008a } },
-	{ AR5K_RF_GAIN(27),	{ 0x0000010a, 0x0000015a } },
-	{ AR5K_RF_GAIN(28),	{ 0x0000014a, 0x0000019a } },
-	{ AR5K_RF_GAIN(29),	{ 0x0000018a, 0x000001da } },
-	{ AR5K_RF_GAIN(30),	{ 0x000001ca, 0x0000000e } },
-	{ AR5K_RF_GAIN(31),	{ 0x0000000a, 0x0000004e } },
-	{ AR5K_RF_GAIN(32),	{ 0x0000004a, 0x0000008e } },
-	{ AR5K_RF_GAIN(33),	{ 0x0000008a, 0x0000015e } },
-	{ AR5K_RF_GAIN(34),	{ 0x000001ba, 0x0000019e } },
-	{ AR5K_RF_GAIN(35),	{ 0x000001fa, 0x000001de } },
-	{ AR5K_RF_GAIN(36),	{ 0x0000003a, 0x00000009 } },
-	{ AR5K_RF_GAIN(37),	{ 0x0000007a, 0x00000049 } },
-	{ AR5K_RF_GAIN(38),	{ 0x00000186, 0x00000089 } },
-	{ AR5K_RF_GAIN(39),	{ 0x000001c6, 0x00000179 } },
-	{ AR5K_RF_GAIN(40),	{ 0x00000006, 0x000001b9 } },
-	{ AR5K_RF_GAIN(41),	{ 0x00000046, 0x000001f9 } },
-	{ AR5K_RF_GAIN(42),	{ 0x00000086, 0x00000039 } },
-	{ AR5K_RF_GAIN(43),	{ 0x000000c6, 0x00000079 } },
-	{ AR5K_RF_GAIN(44),	{ 0x000000c6, 0x000000b9 } },
-	{ AR5K_RF_GAIN(45),	{ 0x000000c6, 0x000001bd } },
-	{ AR5K_RF_GAIN(46),	{ 0x000000c6, 0x000001fd } },
-	{ AR5K_RF_GAIN(47),	{ 0x000000c6, 0x0000003d } },
-	{ AR5K_RF_GAIN(48),	{ 0x000000c6, 0x0000007d } },
-	{ AR5K_RF_GAIN(49),	{ 0x000000c6, 0x000000bd } },
-	{ AR5K_RF_GAIN(50),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(51),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(52),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(53),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(54),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(55),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(56),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(57),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(58),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(59),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(60),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(61),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(62),	{ 0x000000c6, 0x000000fd } },
-	{ AR5K_RF_GAIN(63),	{ 0x000000c6, 0x000000fd } },
-};
+	for (i = 0; i < ah->ah_rf_regs_count; i++) {
+		if (rf_regs[i].index == reg_id) {
+			rfreg = &rf_regs[i];
+			break;
+		}
+	}
 
-static const struct ath5k_gain_opt rfgain_opt_5111 = {
-	4,
-	9,
-	{
-		{ { 4, 1, 1, 1 }, 6 },
-		{ { 4, 0, 1, 1 }, 4 },
-		{ { 3, 1, 1, 1 }, 3 },
-		{ { 4, 0, 0, 1 }, 1 },
-		{ { 4, 1, 1, 0 }, 0 },
-		{ { 4, 0, 1, 0 }, -2 },
-		{ { 3, 1, 1, 0 }, -3 },
-		{ { 4, 0, 0, 0 }, -4 },
-		{ { 2, 1, 1, 0 }, -6 }
+	if (rfb == NULL || rfreg == NULL) {
+		ATH5K_PRINTF("Rf register not found!\n");
+		/* should not happen */
+		return 0;
 	}
-};
 
-/* RF5112 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112[] = {
-	{ 1, 0x98d4,
-	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
-	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, 0x98d0,
-	    { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-	{ 3, 0x98dc,
-	    { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
-	{ 6, 0x989c,
-	    { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
-	{ 6, 0x989c,
-	    { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
-	{ 6, 0x989c,
-	    { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
-	{ 6, 0x989c,
-	    { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
-	{ 6, 0x989c,
-	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-	{ 6, 0x989c,
-	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-	{ 6, 0x989c,
-	    { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
-	{ 6, 0x989c,
-	    { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
-	{ 6, 0x989c,
-	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-	{ 6, 0x989c,
-	    { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-	{ 6, 0x989c,
-	    { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
-	{ 6, 0x989c,
-	    { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
-	{ 6, 0x989c,
-	    { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-	{ 6, 0x989c,
-	    { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
-	{ 6, 0x989c,
-	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-	{ 6, 0x989c,
-	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-	{ 6, 0x989c,
-	    { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
-	{ 6, 0x989c,
-	    { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
-	{ 6, 0x989c,
-	    { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-	{ 6, 0x989c,
-	    { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
-	{ 6, 0x989c,
-	    { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
-	{ 6, 0x989c,
-	    { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
-	{ 6, 0x989c,
-	    { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
-	{ 6, 0x989c,
-	    { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
-	{ 6, 0x989c,
-	    { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
-	{ 6, 0x989c,
-	    { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
-	{ 6, 0x989c,
-	    { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
-	{ 6, 0x989c,
-	    { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
-	{ 6, 0x989c,
-	    { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
-	{ 6, 0x98d0,
-	    { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
-	{ 7, 0x989c,
-	    { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-	{ 7, 0x989c,
-	    { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-	{ 7, 0x989c,
-	    { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
-	{ 7, 0x989c,
-	    { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-	{ 7, 0x989c,
-	    { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
-	{ 7, 0x989c,
-	    { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-	{ 7, 0x989c,
-	    { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-	{ 7, 0x989c,
-	    { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
-	{ 7, 0x989c,
-	    { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
-	{ 7, 0x989c,
-	    { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-	{ 7, 0x989c,
-	    { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-	{ 7, 0x989c,
-	    { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-	{ 7, 0x98c4,
-	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
+	bank = rfreg->bank;
+	num_bits = rfreg->field.len;
+	first_bit = rfreg->field.pos;
+	col = rfreg->field.col;
 
-/* RF5112A mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112a[] = {
-	{ 1, 0x98d4,
-	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
-	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, 0x98d0,
-	    { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-	{ 3, 0x98dc,
-	    { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
-	{ 6, 0x989c,
-	    { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
-	{ 6, 0x989c,
-	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-	{ 6, 0x989c,
-	    { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
-	{ 6, 0x989c,
-	    { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
-	{ 6, 0x989c,
-	    { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
-	{ 6, 0x989c,
-	    { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
-	{ 6, 0x989c,
-	    { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
-	{ 6, 0x989c,
-	    { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
-	{ 6, 0x989c,
-	    { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
-	{ 6, 0x989c,
-	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-	{ 6, 0x989c,
-	    { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
-	{ 6, 0x989c,
-	    { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-	{ 6, 0x989c,
-	    { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
-	{ 6, 0x989c,
-	    { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
-	{ 6, 0x989c,
-	    { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
-	{ 6, 0x989c,
-	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-	{ 6, 0x989c,
-	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-	{ 6, 0x989c,
-	    { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
-	{ 6, 0x989c,
-	    { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
-	{ 6, 0x989c,
-	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-	{ 6, 0x989c,
-	    { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
-	{ 6, 0x989c,
-	    { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
-	{ 6, 0x989c,
-	    { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
-	{ 6, 0x989c,
-	    { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
-	{ 6, 0x989c,
-	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
-	{ 6, 0x989c,
-	    { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
-	{ 6, 0x989c,
-	    { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
-	{ 6, 0x989c,
-	    { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
-	{ 6, 0x989c,
-	    { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
-	{ 6, 0x98d8,
-	    { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
-	{ 7, 0x989c,
-	    { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-	{ 7, 0x989c,
-	    { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-	{ 7, 0x989c,
-	    { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
-	{ 7, 0x989c,
-	    { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-	{ 7, 0x989c,
-	    { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
-	{ 7, 0x989c,
-	    { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-	{ 7, 0x989c,
-	    { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-	{ 7, 0x989c,
-	    { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
-	{ 7, 0x989c,
-	    { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
-	{ 7, 0x989c,
-	    { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-	{ 7, 0x989c,
-	    { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-	{ 7, 0x989c,
-	    { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-	{ 7, 0x98c4,
-	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
+	/* first_bit is an offset from bank's
+	 * start. Since we have all banks on
+	 * the same array, we use this offset
+	 * to mark each bank's start */
+	offset = ah->ah_offset[bank];
 
+	/* Boundary check */
+	if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
+		ATH5K_PRINTF("invalid values at offset %u\n", offset);
+		return 0;
+	}
 
-static const struct ath5k_ini_rf rfregs_2112a[] = {
-	{ 1, AR5K_RF_BUFFER_CONTROL_4,
-	/*	   mode b	mode g	  mode gTurbo */
-		{ 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, AR5K_RF_BUFFER_CONTROL_3,
-		{ 0x03060408, 0x03060408, 0x03070408 } },
-	{ 3, AR5K_RF_BUFFER_CONTROL_6,
-		{ 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x0a000000, 0x0a000000, 0x0a000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00800000, 0x00800000, 0x00800000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x002a0000, 0x002a0000, 0x002a0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00010000, 0x00010000, 0x00010000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00180000, 0x00180000, 0x00180000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x006e0000, 0x006e0000, 0x006e0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00c70000, 0x00c70000, 0x00c70000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x004b0000, 0x004b0000, 0x004b0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x04480000, 0x04480000, 0x04480000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x002a0000, 0x002a0000, 0x002a0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00e40000, 0x00e40000, 0x00e40000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x043f0000, 0x043f0000, 0x043f0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x02190000, 0x02190000, 0x02190000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00240000, 0x00240000, 0x00240000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00b40000, 0x00b40000, 0x00b40000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00990000, 0x00990000, 0x00990000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00500000, 0x00500000, 0x00500000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x002a0000, 0x002a0000, 0x002a0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00120000, 0x00120000, 0x00120000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0xc0320000, 0xc0320000, 0xc0320000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x01740000, 0x01740000, 0x01740000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00110000, 0x00110000, 0x00110000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x86280000, 0x86280000, 0x86280000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x31840000, 0x31840000, 0x31840000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00f20080, 0x00f20080, 0x00f20080 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00070019, 0x00070019, 0x00070019 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x000000b2, 0x000000b2, 0x000000b2 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00b02184, 0x00b02184, 0x00b02184 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x004125a4, 0x004125a4, 0x004125a4 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00119220, 0x00119220, 0x00119220 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x001a4800, 0x001a4800, 0x001a4800 } },
-	{ 6, AR5K_RF_BUFFER_CONTROL_5,
-		{ 0x000b0230, 0x000b0230, 0x000b0230 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000094, 0x00000094, 0x00000094 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000091, 0x00000091, 0x00000091 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000012, 0x00000012, 0x00000012 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000080, 0x00000080, 0x00000080 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x000000d9, 0x000000d9, 0x000000d9 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000060, 0x00000060, 0x00000060 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x000000f0, 0x000000f0, 0x000000f0 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x000000a2, 0x000000a2, 0x000000a2 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000052, 0x00000052, 0x00000052 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x000000d4, 0x000000d4, 0x000000d4 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x000014cc, 0x000014cc, 0x000014cc } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x0000048c, 0x0000048c, 0x0000048c } },
-	{ 7, AR5K_RF_BUFFER_CONTROL_1,
-		{ 0x00000003, 0x00000003, 0x00000003 } },
-};
+	entry = ((first_bit - 1) / 8) + offset;
+	position = (first_bit - 1) % 8;
 
-/* RF5413/5414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5413[] = {
-	{ 1, 0x98d4,
-	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
-	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, 0x98d0,
-	    { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-	{ 3, 0x98dc,
-	    { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
-	{ 6, 0x989c,
-	    { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
-	{ 6, 0x989c,
-	    { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
-	{ 6, 0x989c,
-	    { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
-	{ 6, 0x989c,
-	    { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-	{ 6, 0x989c,
-	    { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-	{ 6, 0x989c,
-	    { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-	{ 6, 0x989c,
-	    { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
-	{ 6, 0x989c,
-	    { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
-	{ 6, 0x989c,
-	    { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
-	{ 6, 0x989c,
-	    { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
-	{ 6, 0x989c,
-	    { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
-	{ 6, 0x989c,
-	    { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
-	{ 6, 0x989c,
-	    { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
-	{ 6, 0x989c,
-	    { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
-	{ 6, 0x989c,
-	    { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-	{ 6, 0x989c,
-	    { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
-	{ 6, 0x989c,
-	    { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
-	{ 6, 0x989c,
-	    { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
-	{ 6, 0x989c,
-	    { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
-	{ 6, 0x989c,
-	    { 0x00510040, 0x00510040, 0x005100a0, 0x005100a0, 0x005100a0 } },
-	{ 6, 0x989c,
-	    { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
-	{ 6, 0x989c,
-	    { 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
-	{ 6, 0x989c,
-	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, 0x989c,
-	    { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
-	{ 6, 0x989c,
-	    { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00003600 } },
-	{ 6, 0x98c8,
-	    { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
-	{ 7, 0x989c,
-	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-	{ 7, 0x989c,
-	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-	{ 7, 0x98cc,
-	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
+	if (set)
+		data = ath5k_hw_bitswap(val, num_bits);
 
-/* RF2413/2414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2413[] = {
-	{ 1, AR5K_RF_BUFFER_CONTROL_4,
-	/* 	   mode b      mode g     mode gTurbo */
-		{ 0x00000020, 0x00000020, 0x00000020 } },
-	{ 2, AR5K_RF_BUFFER_CONTROL_3,
-		{ 0x02001408, 0x02001408, 0x02001408 } },
-	{ 3, AR5K_RF_BUFFER_CONTROL_6,
-		{ 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0xf0000000, 0xf0000000, 0xf0000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x03000000, 0x03000000, 0x03000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x40400000, 0x40400000, 0x40400000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x65050000, 0x65050000, 0x65050000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00420000, 0x00420000, 0x00420000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00b50000, 0x00b50000, 0x00b50000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00030000, 0x00030000, 0x00030000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00f70000, 0x00f70000, 0x00f70000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x009d0000, 0x009d0000, 0x009d0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00220000, 0x00220000, 0x00220000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x04220000, 0x04220000, 0x04220000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00230018, 0x00230018, 0x00230018 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00280050, 0x00280050, 0x00280050 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x005000c3, 0x005000c3, 0x005000c3 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x0004007f, 0x0004007f, 0x0004007f } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000458, 0x00000458, 0x00000458 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x0000c000, 0x0000c000, 0x0000c000 } },
-	{ 6, AR5K_RF_BUFFER_CONTROL_5,
-		{ 0x00400230, 0x00400230, 0x00400230 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00006400, 0x00006400, 0x00006400 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000800, 0x00000800, 0x00000800 } },
-	{ 7, AR5K_RF_BUFFER_CONTROL_2,
-		{ 0x0000000e, 0x0000000e, 0x0000000e } },
-};
+	for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
+	position = 0, entry++) {
 
-/* RF2425 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2425[] = {
-	{ 1, AR5K_RF_BUFFER_CONTROL_4,
-	/* 	   mode g     mode gTurbo */
-		{ 0x00000020, 0x00000020 } },
-	{ 2, AR5K_RF_BUFFER_CONTROL_3,
-		{ 0x02001408, 0x02001408 } },
-	{ 3, AR5K_RF_BUFFER_CONTROL_6,
-		{ 0x00e020c0, 0x00e020c0 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x10000000, 0x10000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x002a0000, 0x002a0000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00100000, 0x00100000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00020000, 0x00020000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00730000, 0x00730000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00f80000, 0x00f80000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00e70000, 0x00e70000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00140000, 0x00140000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00910040, 0x00910040 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x0007001a, 0x0007001a } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00410000, 0x00410000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00810060, 0x00810060 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00020803, 0x00020803 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00000000, 0x00000000 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00001660, 0x00001660 } },
-	{ 6, AR5K_RF_BUFFER,
-		{ 0x00001688, 0x00001688 } },
-	{ 6, AR5K_RF_BUFFER_CONTROL_1,
-		{ 0x00000001, 0x00000001 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00006400, 0x00006400 } },
-	{ 7, AR5K_RF_BUFFER,
-		{ 0x00000800, 0x00000800 } },
-	{ 7, AR5K_RF_BUFFER_CONTROL_2,
-		{ 0x0000000e, 0x0000000e } },
-};
+		last_bit = (position + bits_left > 8) ? 8 :
+					position + bits_left;
 
-/* Initial RF Gain settings for RF5112 */
-static const struct ath5k_ini_rfgain rfgain_5112[] = {
-	/*			      5Ghz	2Ghz	*/
-	{ AR5K_RF_GAIN(0),	{ 0x00000007, 0x00000007 } },
-	{ AR5K_RF_GAIN(1),	{ 0x00000047, 0x00000047 } },
-	{ AR5K_RF_GAIN(2),	{ 0x00000087, 0x00000087 } },
-	{ AR5K_RF_GAIN(3),	{ 0x000001a0, 0x000001a0 } },
-	{ AR5K_RF_GAIN(4),	{ 0x000001e0, 0x000001e0 } },
-	{ AR5K_RF_GAIN(5),	{ 0x00000020, 0x00000020 } },
-	{ AR5K_RF_GAIN(6),	{ 0x00000060, 0x00000060 } },
-	{ AR5K_RF_GAIN(7),	{ 0x000001a1, 0x000001a1 } },
-	{ AR5K_RF_GAIN(8),	{ 0x000001e1, 0x000001e1 } },
-	{ AR5K_RF_GAIN(9),	{ 0x00000021, 0x00000021 } },
-	{ AR5K_RF_GAIN(10),	{ 0x00000061, 0x00000061 } },
-	{ AR5K_RF_GAIN(11),	{ 0x00000162, 0x00000162 } },
-	{ AR5K_RF_GAIN(12),	{ 0x000001a2, 0x000001a2 } },
-	{ AR5K_RF_GAIN(13),	{ 0x000001e2, 0x000001e2 } },
-	{ AR5K_RF_GAIN(14),	{ 0x00000022, 0x00000022 } },
-	{ AR5K_RF_GAIN(15),	{ 0x00000062, 0x00000062 } },
-	{ AR5K_RF_GAIN(16),	{ 0x00000163, 0x00000163 } },
-	{ AR5K_RF_GAIN(17),	{ 0x000001a3, 0x000001a3 } },
-	{ AR5K_RF_GAIN(18),	{ 0x000001e3, 0x000001e3 } },
-	{ AR5K_RF_GAIN(19),	{ 0x00000023, 0x00000023 } },
-	{ AR5K_RF_GAIN(20),	{ 0x00000063, 0x00000063 } },
-	{ AR5K_RF_GAIN(21),	{ 0x00000184, 0x00000184 } },
-	{ AR5K_RF_GAIN(22),	{ 0x000001c4, 0x000001c4 } },
-	{ AR5K_RF_GAIN(23),	{ 0x00000004, 0x00000004 } },
-	{ AR5K_RF_GAIN(24),	{ 0x000001ea, 0x0000000b } },
-	{ AR5K_RF_GAIN(25),	{ 0x0000002a, 0x0000004b } },
-	{ AR5K_RF_GAIN(26),	{ 0x0000006a, 0x0000008b } },
-	{ AR5K_RF_GAIN(27),	{ 0x000000aa, 0x000001ac } },
-	{ AR5K_RF_GAIN(28),	{ 0x000001ab, 0x000001ec } },
-	{ AR5K_RF_GAIN(29),	{ 0x000001eb, 0x0000002c } },
-	{ AR5K_RF_GAIN(30),	{ 0x0000002b, 0x00000012 } },
-	{ AR5K_RF_GAIN(31),	{ 0x0000006b, 0x00000052 } },
-	{ AR5K_RF_GAIN(32),	{ 0x000000ab, 0x00000092 } },
-	{ AR5K_RF_GAIN(33),	{ 0x000001ac, 0x00000193 } },
-	{ AR5K_RF_GAIN(34),	{ 0x000001ec, 0x000001d3 } },
-	{ AR5K_RF_GAIN(35),	{ 0x0000002c, 0x00000013 } },
-	{ AR5K_RF_GAIN(36),	{ 0x0000003a, 0x00000053 } },
-	{ AR5K_RF_GAIN(37),	{ 0x0000007a, 0x00000093 } },
-	{ AR5K_RF_GAIN(38),	{ 0x000000ba, 0x00000194 } },
-	{ AR5K_RF_GAIN(39),	{ 0x000001bb, 0x000001d4 } },
-	{ AR5K_RF_GAIN(40),	{ 0x000001fb, 0x00000014 } },
-	{ AR5K_RF_GAIN(41),	{ 0x0000003b, 0x0000003a } },
-	{ AR5K_RF_GAIN(42),	{ 0x0000007b, 0x0000007a } },
-	{ AR5K_RF_GAIN(43),	{ 0x000000bb, 0x000000ba } },
-	{ AR5K_RF_GAIN(44),	{ 0x000001bc, 0x000001bb } },
-	{ AR5K_RF_GAIN(45),	{ 0x000001fc, 0x000001fb } },
-	{ AR5K_RF_GAIN(46),	{ 0x0000003c, 0x0000003b } },
-	{ AR5K_RF_GAIN(47),	{ 0x0000007c, 0x0000007b } },
-	{ AR5K_RF_GAIN(48),	{ 0x000000bc, 0x000000bb } },
-	{ AR5K_RF_GAIN(49),	{ 0x000000fc, 0x000001bc } },
-	{ AR5K_RF_GAIN(50),	{ 0x000000fc, 0x000001fc } },
-	{ AR5K_RF_GAIN(51),	{ 0x000000fc, 0x0000003c } },
-	{ AR5K_RF_GAIN(52),	{ 0x000000fc, 0x0000007c } },
-	{ AR5K_RF_GAIN(53),	{ 0x000000fc, 0x000000bc } },
-	{ AR5K_RF_GAIN(54),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(55),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(56),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(57),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(58),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(59),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(60),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(61),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(62),	{ 0x000000fc, 0x000000fc } },
-	{ AR5K_RF_GAIN(63),	{ 0x000000fc, 0x000000fc } },
-};
+		mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
+								(col * 8);
 
-/* Initial RF Gain settings for RF5413 */
-static const struct ath5k_ini_rfgain rfgain_5413[] = {
-	/*			      5Ghz	2Ghz	*/
-	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
-	{ AR5K_RF_GAIN(1),	{ 0x00000040, 0x00000040 } },
-	{ AR5K_RF_GAIN(2),	{ 0x00000080, 0x00000080 } },
-	{ AR5K_RF_GAIN(3),	{ 0x000001a1, 0x00000161 } },
-	{ AR5K_RF_GAIN(4),	{ 0x000001e1, 0x000001a1 } },
-	{ AR5K_RF_GAIN(5),	{ 0x00000021, 0x000001e1 } },
-	{ AR5K_RF_GAIN(6),	{ 0x00000061, 0x00000021 } },
-	{ AR5K_RF_GAIN(7),	{ 0x00000188, 0x00000061 } },
-	{ AR5K_RF_GAIN(8),	{ 0x000001c8, 0x00000188 } },
-	{ AR5K_RF_GAIN(9),	{ 0x00000008, 0x000001c8 } },
-	{ AR5K_RF_GAIN(10),	{ 0x00000048, 0x00000008 } },
-	{ AR5K_RF_GAIN(11),	{ 0x00000088, 0x00000048 } },
-	{ AR5K_RF_GAIN(12),	{ 0x000001a9, 0x00000088 } },
-	{ AR5K_RF_GAIN(13),	{ 0x000001e9, 0x00000169 } },
-	{ AR5K_RF_GAIN(14),	{ 0x00000029, 0x000001a9 } },
-	{ AR5K_RF_GAIN(15),	{ 0x00000069, 0x000001e9 } },
-	{ AR5K_RF_GAIN(16),	{ 0x000001d0, 0x00000029 } },
-	{ AR5K_RF_GAIN(17),	{ 0x00000010, 0x00000069 } },
-	{ AR5K_RF_GAIN(18),	{ 0x00000050, 0x00000190 } },
-	{ AR5K_RF_GAIN(19),	{ 0x00000090, 0x000001d0 } },
-	{ AR5K_RF_GAIN(20),	{ 0x000001b1, 0x00000010 } },
-	{ AR5K_RF_GAIN(21),	{ 0x000001f1, 0x00000050 } },
-	{ AR5K_RF_GAIN(22),	{ 0x00000031, 0x00000090 } },
-	{ AR5K_RF_GAIN(23),	{ 0x00000071, 0x00000171 } },
-	{ AR5K_RF_GAIN(24),	{ 0x000001b8, 0x000001b1 } },
-	{ AR5K_RF_GAIN(25),	{ 0x000001f8, 0x000001f1 } },
-	{ AR5K_RF_GAIN(26),	{ 0x00000038, 0x00000031 } },
-	{ AR5K_RF_GAIN(27),	{ 0x00000078, 0x00000071 } },
-	{ AR5K_RF_GAIN(28),	{ 0x00000199, 0x00000198 } },
-	{ AR5K_RF_GAIN(29),	{ 0x000001d9, 0x000001d8 } },
-	{ AR5K_RF_GAIN(30),	{ 0x00000019, 0x00000018 } },
-	{ AR5K_RF_GAIN(31),	{ 0x00000059, 0x00000058 } },
-	{ AR5K_RF_GAIN(32),	{ 0x00000099, 0x00000098 } },
-	{ AR5K_RF_GAIN(33),	{ 0x000000d9, 0x00000179 } },
-	{ AR5K_RF_GAIN(34),	{ 0x000000f9, 0x000001b9 } },
-	{ AR5K_RF_GAIN(35),	{ 0x000000f9, 0x000001f9 } },
-	{ AR5K_RF_GAIN(36),	{ 0x000000f9, 0x00000039 } },
-	{ AR5K_RF_GAIN(37),	{ 0x000000f9, 0x00000079 } },
-	{ AR5K_RF_GAIN(38),	{ 0x000000f9, 0x000000b9 } },
-	{ AR5K_RF_GAIN(39),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(40),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(41),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(42),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(43),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(44),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(45),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(46),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(47),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(48),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(49),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(50),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(51),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(52),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(53),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(54),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(55),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(56),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(57),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(58),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(59),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(60),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(61),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(62),	{ 0x000000f9, 0x000000f9 } },
-	{ AR5K_RF_GAIN(63),	{ 0x000000f9, 0x000000f9 } },
-};
+		if (set) {
+			rfb[entry] &= ~mask;
+			rfb[entry] |= ((data << position) << (col * 8)) & mask;
+			data >>= (8 - position);
+		} else {
+			data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
+				<< bits_shifted;
+			bits_shifted += last_bit - position;
+		}
 
-/* Initial RF Gain settings for RF2413 */
-static const struct ath5k_ini_rfgain rfgain_2413[] = {
-	{ AR5K_RF_GAIN(0), { 0x00000000 } },
-	{ AR5K_RF_GAIN(1), { 0x00000040 } },
-	{ AR5K_RF_GAIN(2), { 0x00000080 } },
-	{ AR5K_RF_GAIN(3), { 0x00000181 } },
-	{ AR5K_RF_GAIN(4), { 0x000001c1 } },
-	{ AR5K_RF_GAIN(5), { 0x00000001 } },
-	{ AR5K_RF_GAIN(6), { 0x00000041 } },
-	{ AR5K_RF_GAIN(7), { 0x00000081 } },
-	{ AR5K_RF_GAIN(8), { 0x00000168 } },
-	{ AR5K_RF_GAIN(9), { 0x000001a8 } },
-	{ AR5K_RF_GAIN(10), { 0x000001e8 } },
-	{ AR5K_RF_GAIN(11), { 0x00000028 } },
-	{ AR5K_RF_GAIN(12), { 0x00000068 } },
-	{ AR5K_RF_GAIN(13), { 0x00000189 } },
-	{ AR5K_RF_GAIN(14), { 0x000001c9 } },
-	{ AR5K_RF_GAIN(15), { 0x00000009 } },
-	{ AR5K_RF_GAIN(16), { 0x00000049 } },
-	{ AR5K_RF_GAIN(17), { 0x00000089 } },
-	{ AR5K_RF_GAIN(18), { 0x00000190 } },
-	{ AR5K_RF_GAIN(19), { 0x000001d0 } },
-	{ AR5K_RF_GAIN(20), { 0x00000010 } },
-	{ AR5K_RF_GAIN(21), { 0x00000050 } },
-	{ AR5K_RF_GAIN(22), { 0x00000090 } },
-	{ AR5K_RF_GAIN(23), { 0x00000191 } },
-	{ AR5K_RF_GAIN(24), { 0x000001d1 } },
-	{ AR5K_RF_GAIN(25), { 0x00000011 } },
-	{ AR5K_RF_GAIN(26), { 0x00000051 } },
-	{ AR5K_RF_GAIN(27), { 0x00000091 } },
-	{ AR5K_RF_GAIN(28), { 0x00000178 } },
-	{ AR5K_RF_GAIN(29), { 0x000001b8 } },
-	{ AR5K_RF_GAIN(30), { 0x000001f8 } },
-	{ AR5K_RF_GAIN(31), { 0x00000038 } },
-	{ AR5K_RF_GAIN(32), { 0x00000078 } },
-	{ AR5K_RF_GAIN(33), { 0x00000199 } },
-	{ AR5K_RF_GAIN(34), { 0x000001d9 } },
-	{ AR5K_RF_GAIN(35), { 0x00000019 } },
-	{ AR5K_RF_GAIN(36), { 0x00000059 } },
-	{ AR5K_RF_GAIN(37), { 0x00000099 } },
-	{ AR5K_RF_GAIN(38), { 0x000000d9 } },
-	{ AR5K_RF_GAIN(39), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(40), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(41), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(42), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(43), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(44), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(45), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(46), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(47), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(48), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(49), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(50), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(51), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(52), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(53), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(54), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(55), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(56), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(57), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(58), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(59), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(60), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(61), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(62), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
+		bits_left -= 8 - position;
+	}
 
-/* Initial RF Gain settings for RF2425 */
-static const struct ath5k_ini_rfgain rfgain_2425[] = {
-	{ AR5K_RF_GAIN(0), { 0x00000000 } },
-	{ AR5K_RF_GAIN(1), { 0x00000040 } },
-	{ AR5K_RF_GAIN(2), { 0x00000080 } },
-	{ AR5K_RF_GAIN(3), { 0x00000181 } },
-	{ AR5K_RF_GAIN(4), { 0x000001c1 } },
-	{ AR5K_RF_GAIN(5), { 0x00000001 } },
-	{ AR5K_RF_GAIN(6), { 0x00000041 } },
-	{ AR5K_RF_GAIN(7), { 0x00000081 } },
-	{ AR5K_RF_GAIN(8), { 0x00000188 } },
-	{ AR5K_RF_GAIN(9), { 0x000001c8 } },
-	{ AR5K_RF_GAIN(10), { 0x00000008 } },
-	{ AR5K_RF_GAIN(11), { 0x00000048 } },
-	{ AR5K_RF_GAIN(12), { 0x00000088 } },
-	{ AR5K_RF_GAIN(13), { 0x00000189 } },
-	{ AR5K_RF_GAIN(14), { 0x000001c9 } },
-	{ AR5K_RF_GAIN(15), { 0x00000009 } },
-	{ AR5K_RF_GAIN(16), { 0x00000049 } },
-	{ AR5K_RF_GAIN(17), { 0x00000089 } },
-	{ AR5K_RF_GAIN(18), { 0x000001b0 } },
-	{ AR5K_RF_GAIN(19), { 0x000001f0 } },
-	{ AR5K_RF_GAIN(20), { 0x00000030 } },
-	{ AR5K_RF_GAIN(21), { 0x00000070 } },
-	{ AR5K_RF_GAIN(22), { 0x00000171 } },
-	{ AR5K_RF_GAIN(23), { 0x000001b1 } },
-	{ AR5K_RF_GAIN(24), { 0x000001f1 } },
-	{ AR5K_RF_GAIN(25), { 0x00000031 } },
-	{ AR5K_RF_GAIN(26), { 0x00000071 } },
-	{ AR5K_RF_GAIN(27), { 0x000001b8 } },
-	{ AR5K_RF_GAIN(28), { 0x000001f8 } },
-	{ AR5K_RF_GAIN(29), { 0x00000038 } },
-	{ AR5K_RF_GAIN(30), { 0x00000078 } },
-	{ AR5K_RF_GAIN(31), { 0x000000b8 } },
-	{ AR5K_RF_GAIN(32), { 0x000001b9 } },
-	{ AR5K_RF_GAIN(33), { 0x000001f9 } },
-	{ AR5K_RF_GAIN(34), { 0x00000039 } },
-	{ AR5K_RF_GAIN(35), { 0x00000079 } },
-	{ AR5K_RF_GAIN(36), { 0x000000b9 } },
-	{ AR5K_RF_GAIN(37), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(38), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(39), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(40), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(41), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(42), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(43), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(44), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(45), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(46), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(47), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(48), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(49), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(50), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(51), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(52), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(53), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(54), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(55), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(56), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(57), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(58), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(59), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(60), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(61), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(62), { 0x000000f9 } },
-	{ AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
+	data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
 
-static const struct ath5k_gain_opt rfgain_opt_5112 = {
-	1,
-	8,
-	{
-		{ { 3, 0, 0, 0, 0, 0, 0 }, 6 },
-		{ { 2, 0, 0, 0, 0, 0, 0 }, 0 },
-		{ { 1, 0, 0, 0, 0, 0, 0 }, -3 },
-		{ { 0, 0, 0, 0, 0, 0, 0 }, -6 },
-		{ { 0, 1, 1, 0, 0, 0, 0 }, -8 },
-		{ { 0, 1, 1, 0, 1, 1, 0 }, -10 },
-		{ { 0, 1, 0, 1, 1, 1, 0 }, -13 },
-		{ { 0, 1, 0, 1, 1, 0, 1 }, -16 },
-	}
-};
+	return data;
+}
+
+/**********************\
+* RF Gain optimization *
+\**********************/
 
 /*
- * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
+ * This code is used to optimize rf gain on different environments
+ * (temprature 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
+ * no gain optimization ladder-.
+ *
+ * For more infos check out this patent doc
+ * http://www.freepatentsonline.com/7400691.html
+ *
+ * This paper describes power drops as seen on the receiver due to
+ * probe packets
+ * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
+ * %20of%20Power%20Control.pdf
+ *
+ * And this is the MadWiFi bug entry related to the above
+ * http://madwifi-project.org/ticket/1659
+ * with various measurements and diagrams
+ *
+ * TODO: Deal with power drops due to probes by setting an apropriate
+ * tx power on the probe packets ! Make this part of the calibration process.
  */
-static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
-		u32 first, u32 col, bool set)
-{
-	u32 mask, entry, last, data, shift, position;
-	s32 left;
-	int i;
 
-	data = 0;
-
-	if (rf == NULL)
-		/* should not happen */
-		return 0;
-
-	if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
-		ATH5K_PRINTF("invalid values at offset %u\n", offset);
-		return 0;
+/* Initialize ah_gain durring attach */
+int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
+{
+	/* Initialize the gain optimization values */
+	switch (ah->ah_radio) {
+	case AR5K_RF5111:
+		ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
+		ah->ah_gain.g_low = 20;
+		ah->ah_gain.g_high = 35;
+		ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+		break;
+	case AR5K_RF5112:
+		ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+		ah->ah_gain.g_low = 20;
+		ah->ah_gain.g_high = 85;
+		ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	entry = ((first - 1) / 8) + offset;
-	position = (first - 1) % 8;
-
-	if (set)
-		data = ath5k_hw_bitswap(reg, bits);
+	return 0;
+}
 
-	for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
-		last = (position + left > 8) ? 8 : position + left;
-		mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
+/* Schedule a gain probe check on the next transmited packet.
+ * That means our next packet is going to be sent with lower
+ * tx power and a Peak to Average Power Detector (PAPD) will try
+ * to measure the gain.
+ *
+ * TODO: Use propper tx power setting for the probe packet so
+ * that we don't observe a serious power drop on the receiver
+ *
+ * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
+ * just after we enable the probe so that we don't mess with
+ * standard traffic ? Maybe it's time to use sw interrupts and
+ * a probe tasklet !!!
+ */
+static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
+{
 
-		if (set) {
-			rf[entry] &= ~mask;
-			rf[entry] |= ((data << position) << (col * 8)) & mask;
-			data >>= (8 - position);
-		} else {
-			data = (((rf[entry] & mask) >> (col * 8)) >> position)
-				<< shift;
-			shift += last - position;
-		}
+	/* Skip if gain calibration is inactive or
+	 * we already handle a probe request */
+	if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
+		return;
 
-		left -= 8 - position;
-	}
+	/* Send the packet with 2dB below max power as
+	 * patent doc suggest */
+	ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
+			AR5K_PHY_PAPD_PROBE_TXPOWER) |
+			AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
 
-	data = set ? 1 : ath5k_hw_bitswap(data, bits);
+	ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
 
-	return data;
 }
 
-static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
+/* Calculate gain_F measurement correction
+ * based on the current step for RF5112 rev. 2 */
+static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
 {
 	u32 mix, step;
 	u32 *rf;
+	const struct ath5k_gain_opt *go;
+	const struct ath5k_gain_opt_step *g_step;
+	const struct ath5k_rf_reg *rf_regs;
+
+	/* Only RF5112 Rev. 2 supports it */
+	if ((ah->ah_radio != AR5K_RF5112) ||
+	(ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
+		return 0;
+
+	go = &rfgain_opt_5112;
+	rf_regs = rf_regs_5112a;
+	ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+
+	g_step = &go->go_step[ah->ah_gain.g_step_idx];
 
 	if (ah->ah_rf_banks == NULL)
 		return 0;
@@ -1165,11 +221,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(st
 	rf = ah->ah_rf_banks;
 	ah->ah_gain.g_f_corr = 0;
 
-	if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
+	/* No VGA (Variable Gain Amplifier) override, skip */
+	if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
 		return 0;
 
-	step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
-	mix = ah->ah_gain.g_step->gos_param[0];
+	/* Mix gain stepping */
+	step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
+
+	/* Mix gain override */
+	mix = g_step->gos_param[0];
 
 	switch (mix) {
 	case 3:
@@ -1189,9 +249,14 @@ static u32 ath5k_hw_rfregs_gainf_corr(st
 	return ah->ah_gain.g_f_corr;
 }
 
-static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
+/* Check if current gain_F measurement is in the range of our
+ * power detector windows. If we get a measurement outside range
+ * we know it's not accurate (detectors can't measure anything outside
+ * their detection window) so we must ignore it */
+static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
 {
-	u32 step, mix, level[4];
+	const struct ath5k_rf_reg *rf_regs;
+	u32 step, mix_ovr, level[4];
 	u32 *rf;
 
 	if (ah->ah_rf_banks == NULL)
@@ -1200,23 +265,33 @@ static bool ath5k_hw_rfregs_gain_readbac
 	rf = ah->ah_rf_banks;
 
 	if (ah->ah_radio == AR5K_RF5111) {
-		step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
-				false);
+
+		rf_regs = rf_regs_5111;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+
+		step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
+			false);
+
 		level[0] = 0;
-		level[1] = (step == 0x3f) ? 0x32 : step + 4;
-		level[2] = (step != 0x3f) ? 0x40 : level[0];
-		level[3] = level[2] + 0x32;
+		level[1] = (step == 63) ? 50 : step + 4;
+		level[2] = (step != 63) ? 64 : level[0];
+		level[3] = level[2] + 50 ;
 
 		ah->ah_gain.g_high = level[3] -
-			(step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+			(step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
 		ah->ah_gain.g_low = level[0] +
-			(step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+			(step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
 	} else {
-		mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
-				false);
+
+		rf_regs = rf_regs_5112;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+
+		mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
+			false);
+
 		level[0] = level[2] = 0;
 
-		if (mix == 1) {
+		if (mix_ovr == 1) {
 			level[1] = level[3] = 83;
 		} else {
 			level[1] = level[3] = 107;
@@ -1230,9 +305,12 @@ static bool ath5k_hw_rfregs_gain_readbac
 			ah->ah_gain.g_current <= level[3]);
 }
 
-static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
+/* Perform gain_F adjustment by choosing the right set
+ * of parameters from rf gain optimization ladder */
+static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
 {
 	const struct ath5k_gain_opt *go;
+	const struct ath5k_gain_opt_step *g_step;
 	int ret = 0;
 
 	switch (ah->ah_radio) {
@@ -1246,35 +324,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(s
 		return 0;
 	}
 
-	ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
+	g_step = &go->go_step[ah->ah_gain.g_step_idx];
 
 	if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+
+		/* Reached maximum */
 		if (ah->ah_gain.g_step_idx == 0)
 			return -1;
+
 		for (ah->ah_gain.g_target = ah->ah_gain.g_current;
 				ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
 				ah->ah_gain.g_step_idx > 0;
-				ah->ah_gain.g_step =
-					&go->go_step[ah->ah_gain.g_step_idx])
+				g_step = &go->go_step[ah->ah_gain.g_step_idx])
 			ah->ah_gain.g_target -= 2 *
 			    (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
-			    ah->ah_gain.g_step->gos_gain);
+			    g_step->gos_gain);
 
 		ret = 1;
 		goto done;
 	}
 
 	if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+
+		/* Reached minimum */
 		if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
 			return -2;
+
 		for (ah->ah_gain.g_target = ah->ah_gain.g_current;
 				ah->ah_gain.g_target <= ah->ah_gain.g_low &&
 				ah->ah_gain.g_step_idx < go->go_steps_count-1;
-				ah->ah_gain.g_step =
-					&go->go_step[ah->ah_gain.g_step_idx])
+				g_step = &go->go_step[ah->ah_gain.g_step_idx])
 			ah->ah_gain.g_target -= 2 *
 			    (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
-			    ah->ah_gain.g_step->gos_gain);
+			    g_step->gos_gain);
 
 		ret = 2;
 		goto done;
@@ -1289,468 +371,449 @@ done:
 	return ret;
 }
 
-/*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
- */
-static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
-		struct ieee80211_channel *channel, unsigned int mode)
+/* Main callback for thermal rf gain calibration engine
+ * Check for a new gain reading and schedule an adjustment
+ * if needed.
+ *
+ * TODO: Use sw interrupt to schedule reset if gain_F needs
+ * adjustment */
+enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
 {
+	u32 data, type;
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	u32 *rf;
-	const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
-	unsigned int i;
-	int obdb = -1, bank = -1;
-	u32 ee_mode;
-
-	AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
 
-	rf = ah->ah_rf_banks;
-
-	/* Copy values to modify them */
-	for (i = 0; i < rf_size; i++) {
-		if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
-			ATH5K_ERR(ah->ah_sc, "invalid bank\n");
-			return -EINVAL;
-		}
-
-		if (bank != rfregs_5111[i].rf_bank) {
-			bank = rfregs_5111[i].rf_bank;
-			ah->ah_offset[bank] = i;
-		}
+	ATH5K_TRACE(ah->ah_sc);
 
-		rf[i] = rfregs_5111[i].rf_value[mode];
-	}
+	if (ah->ah_rf_banks == NULL ||
+	ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
+		return AR5K_RFGAIN_INACTIVE;
 
-	/* Modify bank 0 */
-	if (channel->hw_value & CHANNEL_2GHZ) {
-		if (channel->hw_value & CHANNEL_CCK)
-			ee_mode = AR5K_EEPROM_MODE_11B;
-		else
-			ee_mode = AR5K_EEPROM_MODE_11G;
-		obdb = 0;
+	/* No check requested, either engine is inactive
+	 * or an adjustment is already requested */
+	if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
+		goto done;
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
-				ee->ee_ob[ee_mode][obdb], 3, 119, 0, true))
-			return -EINVAL;
+	/* Read the PAPD (Peak to Average Power Detector)
+	 * register */
+	data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
-				ee->ee_ob[ee_mode][obdb], 3, 122, 0, true))
-			return -EINVAL;
+	/* No probe is scheduled, read gain_F measurement */
+	if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
+		ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
+		type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
 
-		obdb = 1;
-	/* Modify bank 6 */
-	} else {
-		/* For 11a, Turbo and XR */
-		ee_mode = AR5K_EEPROM_MODE_11A;
-		obdb =	 channel->center_freq >= 5725 ? 3 :
-			(channel->center_freq >= 5500 ? 2 :
-			(channel->center_freq >= 5260 ? 1 :
-			 (channel->center_freq > 4000 ? 0 : -1)));
+		/* If tx packet is CCK correct the gain_F measurement
+		 * by cck ofdm gain delta */
+		if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
+			if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+				ah->ah_gain.g_current +=
+					ee->ee_cck_ofdm_gain_delta;
+			else
+				ah->ah_gain.g_current +=
+					AR5K_GAIN_CCK_PROBE_CORR;
+		}
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_pwd_84, 1, 51, 3, true))
-			return -EINVAL;
+		/* Further correct gain_F measurement for
+		 * RF5112A radios */
+		if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+			ath5k_hw_rf_gainf_corr(ah);
+			ah->ah_gain.g_current =
+				ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
+				(ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+				0;
+		}
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_pwd_90, 1, 45, 3, true))
-			return -EINVAL;
+		/* Check if measurement is ok and if we need
+		 * to adjust gain, schedule a gain adjustment,
+		 * else switch back to the acive state */
+		if (ath5k_hw_rf_check_gainf_readback(ah) &&
+		AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+		ath5k_hw_rf_gainf_adjust(ah)) {
+			ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
+		} else {
+			ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+		}
 	}
 
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-			!ee->ee_xpd[ee_mode], 1, 95, 0, true))
-		return -EINVAL;
-
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-			ee->ee_x_gain[ee_mode], 4, 96, 0, true))
-		return -EINVAL;
-
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
-			ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
-		return -EINVAL;
+done:
+	return ah->ah_gain.g_state;
+}
 
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
-			ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true))
-		return -EINVAL;
+/* Write initial rf gain table to set the RF sensitivity
+ * this one works on all RF chips and has nothing to do
+ * with gain_F calibration */
+int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+{
+	const struct ath5k_ini_rfgain *ath5k_rfg;
+	unsigned int i, size;
 
-	/* Modify bank 7 */
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
-			ee->ee_i_gain[ee_mode], 6, 29, 0, true))
+	switch (ah->ah_radio) {
+	case AR5K_RF5111:
+		ath5k_rfg = rfgain_5111;
+		size = ARRAY_SIZE(rfgain_5111);
+		break;
+	case AR5K_RF5112:
+		ath5k_rfg = rfgain_5112;
+		size = ARRAY_SIZE(rfgain_5112);
+		break;
+	case AR5K_RF2413:
+		ath5k_rfg = rfgain_2413;
+		size = ARRAY_SIZE(rfgain_2413);
+		break;
+	case AR5K_RF2316:
+		ath5k_rfg = rfgain_2316;
+		size = ARRAY_SIZE(rfgain_2316);
+		break;
+	case AR5K_RF5413:
+		ath5k_rfg = rfgain_5413;
+		size = ARRAY_SIZE(rfgain_5413);
+		break;
+	case AR5K_RF2317:
+	case AR5K_RF2425:
+		ath5k_rfg = rfgain_2425;
+		size = ARRAY_SIZE(rfgain_2425);
+		break;
+	default:
 		return -EINVAL;
+	}
 
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
-			ee->ee_xpd[ee_mode], 1, 4, 0, true))
+	switch (freq) {
+	case AR5K_INI_RFGAIN_2GHZ:
+	case AR5K_INI_RFGAIN_5GHZ:
+		break;
+	default:
 		return -EINVAL;
+	}
 
-	/* Write RF values */
-	for (i = 0; i < rf_size; i++) {
+	for (i = 0; i < size; i++) {
 		AR5K_REG_WAIT(i);
-		ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register);
+		ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+			(u32)ath5k_rfg[i].rfg_register);
 	}
 
 	return 0;
 }
 
+
+
+/********************\
+* RF Registers setup *
+\********************/
+
+
 /*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
+ * Setup RF registers by writing rf buffer on hw
  */
-static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
-		struct ieee80211_channel *channel, unsigned int mode)
+int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+		unsigned int mode)
 {
-	const struct ath5k_ini_rf *rf_ini;
+	const struct ath5k_rf_reg *rf_regs;
+	const struct ath5k_ini_rfbuffer *ini_rfb;
+	const struct ath5k_gain_opt *go = NULL;
+	const struct ath5k_gain_opt_step *g_step;
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	u32 *rf;
-	unsigned int rf_size, i;
-	int obdb = -1, bank = -1;
-	u32 ee_mode;
-
-	AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
+	u8 ee_mode = 0;
+	u32 *rfb;
+	int i, obdb = -1, bank = -1;
 
-	rf = ah->ah_rf_banks;
+	switch (ah->ah_radio) {
+	case AR5K_RF5111:
+		rf_regs = rf_regs_5111;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+		ini_rfb = rfb_5111;
+		ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
+		go = &rfgain_opt_5111;
+		break;
+	case AR5K_RF5112:
+		if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+			rf_regs = rf_regs_5112a;
+			ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+			ini_rfb = rfb_5112a;
+			ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
+		} else {
+			rf_regs = rf_regs_5112;
+			ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+			ini_rfb = rfb_5112;
+			ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
+		}
+		go = &rfgain_opt_5112;
+		break;
+	case AR5K_RF2413:
+		rf_regs = rf_regs_2413;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
+		ini_rfb = rfb_2413;
+		ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
+		break;
+	case AR5K_RF2316:
+		rf_regs = rf_regs_2316;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
+		ini_rfb = rfb_2316;
+		ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
+		break;
+	case AR5K_RF5413:
+		rf_regs = rf_regs_5413;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
+		ini_rfb = rfb_5413;
+		ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
+		break;
+	case AR5K_RF2317:
+		rf_regs = rf_regs_2425;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+		ini_rfb = rfb_2317;
+		ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
+		break;
+	case AR5K_RF2425:
+		rf_regs = rf_regs_2425;
+		ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+		if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
+			ini_rfb = rfb_2425;
+			ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
+		} else {
+			ini_rfb = rfb_2417;
+			ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
 
-	if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
-		&& !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) {
-		rf_ini = rfregs_2112a;
-		rf_size = ARRAY_SIZE(rfregs_5112a);
-		if (mode < 2) {
-			ATH5K_ERR(ah->ah_sc, "invalid channel mode: %i\n",
-				  mode);
-			return -EINVAL;
+	/* If it's the first time we set rf buffer, allocate
+	 * ah->ah_rf_banks based on ah->ah_rf_banks_size
+	 * we set above */
+	if (ah->ah_rf_banks == NULL) {
+		ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
+								GFP_KERNEL);
+		if (ah->ah_rf_banks == NULL) {
+			ATH5K_ERR(ah->ah_sc, "out of memory\n");
+			return -ENOMEM;
 		}
-		mode = mode - 2; /*no a/turboa modes for 2112*/
-	} else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
-		rf_ini = rfregs_5112a;
-		rf_size = ARRAY_SIZE(rfregs_5112a);
-	} else {
-		rf_ini = rfregs_5112;
-		rf_size = ARRAY_SIZE(rfregs_5112);
 	}
 
 	/* Copy values to modify them */
-	for (i = 0; i < rf_size; i++) {
-		if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
+	rfb = ah->ah_rf_banks;
+
+	for (i = 0; i < ah->ah_rf_banks_size; i++) {
+		if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
 			ATH5K_ERR(ah->ah_sc, "invalid bank\n");
 			return -EINVAL;
 		}
 
-		if (bank != rf_ini[i].rf_bank) {
-			bank = rf_ini[i].rf_bank;
+		/* Bank changed, write down the offset */
+		if (bank != ini_rfb[i].rfb_bank) {
+			bank = ini_rfb[i].rfb_bank;
 			ah->ah_offset[bank] = i;
 		}
 
-		rf[i] = rf_ini[i].rf_value[mode];
+		rfb[i] = ini_rfb[i].rfb_mode_data[mode];
 	}
 
-	/* Modify bank 6 */
+	/* Set Output and Driver bias current (OB/DB) */
 	if (channel->hw_value & CHANNEL_2GHZ) {
-		if (channel->hw_value & CHANNEL_OFDM)
+
+		if (channel->hw_value & CHANNEL_CCK)
+			ee_mode = AR5K_EEPROM_MODE_11B;
+		else
 			ee_mode = AR5K_EEPROM_MODE_11G;
+
+		/* For RF511X/RF211X combination we
+		 * use b_OB and b_DB parameters stored
+		 * in eeprom on ee->ee_ob[ee_mode][0]
+		 *
+		 * For all other chips we use OB/DB for 2Ghz
+		 * stored in the b/g modal section just like
+		 * 802.11a on ee->ee_ob[ee_mode][1] */
+		if ((ah->ah_radio == AR5K_RF5111) ||
+		(ah->ah_radio == AR5K_RF5112))
+			obdb = 0;
 		else
-			ee_mode = AR5K_EEPROM_MODE_11B;
-		obdb = 0;
+			obdb = 1;
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_ob[ee_mode][obdb], 3, 287, 0, true))
-			return -EINVAL;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+						AR5K_RF_OB_2GHZ, true);
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_ob[ee_mode][obdb], 3, 290, 0, true))
-			return -EINVAL;
-	} else {
-		/* For 11a, Turbo and XR */
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+						AR5K_RF_DB_2GHZ, true);
+
+	/* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
+	} else if ((channel->hw_value & CHANNEL_5GHZ) ||
+			(ah->ah_radio == AR5K_RF5111)) {
+
+		/* For 11a, Turbo and XR we need to choose
+		 * OB/DB based on frequency range */
 		ee_mode = AR5K_EEPROM_MODE_11A;
-		obdb = channel->center_freq >= 5725 ? 3 :
-		    (channel->center_freq >= 5500 ? 2 :
+		obdb =	 channel->center_freq >= 5725 ? 3 :
+			(channel->center_freq >= 5500 ? 2 :
 			(channel->center_freq >= 5260 ? 1 :
-			    (channel->center_freq > 4000 ? 0 : -1)));
+			 (channel->center_freq > 4000 ? 0 : -1)));
 
-		if (obdb == -1)
+		if (obdb < 0)
 			return -EINVAL;
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
-			return -EINVAL;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+						AR5K_RF_OB_5GHZ, true);
 
-		if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-				ee->ee_ob[ee_mode][obdb], 3, 282, 0, true))
-			return -EINVAL;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+						AR5K_RF_DB_5GHZ, true);
 	}
 
-	ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-	    ee->ee_x_gain[ee_mode], 2, 270, 0, true);
-	ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-	    ee->ee_x_gain[ee_mode], 2, 257, 0, true);
-
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
-			ee->ee_xpd[ee_mode], 1, 302, 0, true))
-		return -EINVAL;
+	g_step = &go->go_step[ah->ah_gain.g_step_idx];
 
-	/* Modify bank 7 */
-	if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
-			ee->ee_i_gain[ee_mode], 6, 14, 0, true))
-		return -EINVAL;
+	/* Bank Modifications (chip-specific) */
+	if (ah->ah_radio == AR5K_RF5111) {
 
-	/* Write RF values */
-	for (i = 0; i < rf_size; i++)
-		ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+		/* Set gain_F settings according to current step */
+		if (channel->hw_value & CHANNEL_OFDM) {
 
-	return 0;
-}
+			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+					AR5K_PHY_FRAME_CTL_TX_CLIP,
+					g_step->gos_param[0]);
 
-/*
- * Initialize RF5413/5414 and future chips
- * (until we come up with a better solution)
- */
-static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
-		struct ieee80211_channel *channel, unsigned int mode)
-{
-	const struct ath5k_ini_rf *rf_ini;
-	u32 *rf;
-	unsigned int rf_size, i;
-	int bank = -1;
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+							AR5K_RF_PWD_90, true);
 
-	AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+							AR5K_RF_PWD_84, true);
 
-	rf = ah->ah_rf_banks;
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+						AR5K_RF_RFGAIN_SEL, true);
 
-	switch (ah->ah_radio) {
-	case AR5K_RF5413:
-		rf_ini = rfregs_5413;
-		rf_size = ARRAY_SIZE(rfregs_5413);
-		break;
-	case AR5K_RF2413:
-		rf_ini = rfregs_2413;
-		rf_size = ARRAY_SIZE(rfregs_2413);
+			/* We programmed gain_F parameters, switch back
+			 * to active state */
+			ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
 
-		if (mode < 2) {
-			ATH5K_ERR(ah->ah_sc,
-				"invalid channel mode: %i\n", mode);
-			return -EINVAL;
 		}
 
-		mode = mode - 2;
-		break;
-	case AR5K_RF2425:
-		rf_ini = rfregs_2425;
-		rf_size = ARRAY_SIZE(rfregs_2425);
+		/* Bank 6/7 setup */
 
-		if (mode < 2) {
-			ATH5K_ERR(ah->ah_sc,
-				"invalid channel mode: %i\n", mode);
-			return -EINVAL;
-		}
+		ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
+						AR5K_RF_PWD_XPD, true);
 
-		/* Map b to g */
-		if (mode == 2)
-			mode = 0;
-		else
-			mode = mode - 3;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
+						AR5K_RF_XPD_GAIN, true);
 
-		break;
-	default:
-		return -EINVAL;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+						AR5K_RF_GAIN_I, true);
+
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+						AR5K_RF_PLO_SEL, true);
+
+		/* TODO: Half/quarter channel support */
 	}
 
-	/* Copy values to modify them */
-	for (i = 0; i < rf_size; i++) {
-		if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
-			ATH5K_ERR(ah->ah_sc, "invalid bank\n");
-			return -EINVAL;
-		}
+	if (ah->ah_radio == AR5K_RF5112) {
 
-		if (bank != rf_ini[i].rf_bank) {
-			bank = rf_ini[i].rf_bank;
-			ah->ah_offset[bank] = i;
-		}
+		/* Set gain_F settings according to current step */
+		if (channel->hw_value & CHANNEL_OFDM) {
 
-		rf[i] = rf_ini[i].rf_value[mode];
-	}
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
+						AR5K_RF_MIXGAIN_OVR, true);
 
-	/*
-	 * After compairing dumps from different cards
-	 * we get the same RF_BUFFER settings (diff returns
-	 * 0 lines). It seems that RF_BUFFER settings are static
-	 * and are written unmodified (no EEPROM stuff
-	 * is used because calibration data would be
-	 * different between different cards and would result
-	 * different RF_BUFFER settings)
-	 */
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+						AR5K_RF_PWD_138, true);
 
-	/* Write RF values */
-	for (i = 0; i < rf_size; i++)
-		ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+						AR5K_RF_PWD_137, true);
 
-	return 0;
-}
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+						AR5K_RF_PWD_136, true);
 
-/*
- * Initialize RF
- */
-int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-		unsigned int mode)
-{
-	int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
-	int ret;
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
+						AR5K_RF_PWD_132, true);
 
-	switch (ah->ah_radio) {
-	case AR5K_RF5111:
-		ah->ah_rf_banks_size = sizeof(rfregs_5111);
-		func = ath5k_hw_rf5111_rfregs;
-		break;
-	case AR5K_RF5112:
-		if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
-			ah->ah_rf_banks_size = sizeof(rfregs_5112a);
-		else
-			ah->ah_rf_banks_size = sizeof(rfregs_5112);
-		func = ath5k_hw_rf5112_rfregs;
-		break;
-	case AR5K_RF5413:
-		ah->ah_rf_banks_size = sizeof(rfregs_5413);
-		func = ath5k_hw_rf5413_rfregs;
-		break;
-	case AR5K_RF2413:
-		ah->ah_rf_banks_size = sizeof(rfregs_2413);
-		func = ath5k_hw_rf5413_rfregs;
-		break;
-	case AR5K_RF2425:
-		ah->ah_rf_banks_size = sizeof(rfregs_2425);
-		func = ath5k_hw_rf5413_rfregs;
-		break;
-	default:
-		return -EINVAL;
-	}
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
+						AR5K_RF_PWD_131, true);
 
-	if (ah->ah_rf_banks == NULL) {
-		/* XXX do extra checks? */
-		ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
-		if (ah->ah_rf_banks == NULL) {
-			ATH5K_ERR(ah->ah_sc, "out of memory\n");
-			return -ENOMEM;
+			ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
+						AR5K_RF_PWD_130, true);
+
+			/* We programmed gain_F parameters, switch back
+			 * to active state */
+			ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
 		}
-	}
 
-	ret = func(ah, channel, mode);
-	if (!ret)
-		ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
+		/* Bank 6/7 setup */
 
-	return ret;
-}
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+						AR5K_RF_XPD_SEL, true);
 
-int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
-{
-	const struct ath5k_ini_rfgain *ath5k_rfg;
-	unsigned int i, size;
+		if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
+			/* Rev. 1 supports only one xpd */
+			ath5k_hw_rfb_op(ah, rf_regs,
+						ee->ee_x_gain[ee_mode],
+						AR5K_RF_XPD_GAIN, true);
 
-	switch (ah->ah_radio) {
-	case AR5K_RF5111:
-		ath5k_rfg = rfgain_5111;
-		size = ARRAY_SIZE(rfgain_5111);
-		break;
-	case AR5K_RF5112:
-		ath5k_rfg = rfgain_5112;
-		size = ARRAY_SIZE(rfgain_5112);
-		break;
-	case AR5K_RF5413:
-		ath5k_rfg = rfgain_5413;
-		size = ARRAY_SIZE(rfgain_5413);
-		break;
-	case AR5K_RF2413:
-		ath5k_rfg = rfgain_2413;
-		size = ARRAY_SIZE(rfgain_2413);
-		freq = 0; /* only 2Ghz */
-		break;
-	case AR5K_RF2425:
-		ath5k_rfg = rfgain_2425;
-		size = ARRAY_SIZE(rfgain_2425);
-		freq = 0; /* only 2Ghz */
-		break;
-	default:
-		return -EINVAL;
-	}
+		} else {
+			/* TODO: Set high and low gain bits */
+			ath5k_hw_rfb_op(ah, rf_regs,
+						ee->ee_x_gain[ee_mode],
+						AR5K_RF_PD_GAIN_LO, true);
+			ath5k_hw_rfb_op(ah, rf_regs,
+						ee->ee_x_gain[ee_mode],
+						AR5K_RF_PD_GAIN_HI, true);
 
-	switch (freq) {
-	case AR5K_INI_RFGAIN_2GHZ:
-	case AR5K_INI_RFGAIN_5GHZ:
-		break;
-	default:
-		return -EINVAL;
-	}
+			/* Lower synth voltage on Rev 2 */
+			ath5k_hw_rfb_op(ah, rf_regs, 2,
+					AR5K_RF_HIGH_VC_CP, true);
 
-	for (i = 0; i < size; i++) {
-		AR5K_REG_WAIT(i);
-		ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
-			(u32)ath5k_rfg[i].rfg_register);
-	}
+			ath5k_hw_rfb_op(ah, rf_regs, 2,
+					AR5K_RF_MID_VC_CP, true);
 
-	return 0;
-}
+			ath5k_hw_rfb_op(ah, rf_regs, 2,
+					AR5K_RF_LOW_VC_CP, true);
 
-enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
-{
-	u32 data, type;
+			ath5k_hw_rfb_op(ah, rf_regs, 2,
+					AR5K_RF_PUSH_UP, true);
 
-	ATH5K_TRACE(ah->ah_sc);
+			/* Decrease power consumption on 5213+ BaseBand */
+			if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+				ath5k_hw_rfb_op(ah, rf_regs, 1,
+						AR5K_RF_PAD2GND, true);
 
-	if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
-			ah->ah_version <= AR5K_AR5211)
-		return AR5K_RFGAIN_INACTIVE;
+				ath5k_hw_rfb_op(ah, rf_regs, 1,
+						AR5K_RF_XB2_LVL, true);
 
-	if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
-		goto done;
+				ath5k_hw_rfb_op(ah, rf_regs, 1,
+						AR5K_RF_XB5_LVL, true);
 
-	data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+				ath5k_hw_rfb_op(ah, rf_regs, 1,
+						AR5K_RF_PWD_167, true);
 
-	if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
-		ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
-		type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
+				ath5k_hw_rfb_op(ah, rf_regs, 1,
+						AR5K_RF_PWD_166, true);
+			}
+		}
 
-		if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
-			ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
+		ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+						AR5K_RF_GAIN_I, true);
 
-		if (ah->ah_radio >= AR5K_RF5112) {
-			ath5k_hw_rfregs_gainf_corr(ah);
-			ah->ah_gain.g_current =
-				ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
-				(ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
-				0;
-		}
+		/* TODO: Half/quarter channel support */
 
-		if (ath5k_hw_rfregs_gain_readback(ah) &&
-				AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
-				ath5k_hw_rfregs_gain_adjust(ah))
-			ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
 	}
 
-done:
-	return ah->ah_rf_gain;
-}
+	if (ah->ah_radio == AR5K_RF5413 &&
+	channel->hw_value & CHANNEL_2GHZ) {
 
-int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
-{
-	/* Initialize the gain optimization values */
-	switch (ah->ah_radio) {
-	case AR5K_RF5111:
-		ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
-		ah->ah_gain.g_step =
-		    &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
-		ah->ah_gain.g_low = 20;
-		ah->ah_gain.g_high = 35;
-		ah->ah_gain.g_active = 1;
-		break;
-	case AR5K_RF5112:
-		ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
-		ah->ah_gain.g_step =
-		    &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
-		ah->ah_gain.g_low = 20;
-		ah->ah_gain.g_high = 85;
-		ah->ah_gain.g_active = 1;
-		break;
-	default:
-		return -EINVAL;
+		ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
+									true);
+
+		/* Set optimum value for early revisions (on pci-e chips) */
+		if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+		ah->ah_mac_srev < AR5K_SREV_AR5413)
+			ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
+						AR5K_RF_PWD_ICLOBUF_2G, true);
+
+	}
+
+	/* Write RF banks on hw */
+	for (i = 0; i < ah->ah_rf_banks_size; i++) {
+		AR5K_REG_WAIT(i);
+		ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
 	}
 
 	return 0;
 }
 
+
 /**************************\
   PHY/RF channel functions
 \**************************/
@@ -2271,13 +1334,8 @@ done:
 	 * as often as I/Q calibration.*/
 	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 
-	/* Request RF gain */
-	if (channel->hw_value & CHANNEL_5GHZ) {
-		ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
-			AR5K_PHY_PAPD_PROBE_TXPOWER) |
-			AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
-		ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
-	}
+	/* Initiate a gain_F calibration */
+	ath5k_hw_request_rfgain_probe(ah);
 
 	return 0;
 }
@@ -2378,93 +1436,1127 @@ unsigned int ath5k_hw_get_def_antenna(st
 	return false; /*XXX: What do we return for 5210 ?*/
 }
 
+
+/****************\
+* TX power setup *
+\****************/
+
 /*
- * TX power setup
+ * Helper functions
  */
 
 /*
- * Initialize the tx power table (not fully implemented)
+ * Do linear interpolation between two given (x, y) points
  */
-static void ath5k_txpower_table(struct ath5k_hw *ah,
-		struct ieee80211_channel *channel, s16 max_power)
+static s16
+ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
+					s16 y_left, s16 y_right)
 {
-	unsigned int i, min, max, n;
-	u16 txpower, *rates;
+	s16 ratio, result;
 
-	rates = ah->ah_txpower.txp_rates;
+	/* Avoid divide by zero and skip interpolation
+	 * if we have the same point */
+	if ((x_left == x_right) || (y_left == y_right))
+		return y_left;
 
-	txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
-	if (max_power > txpower)
-		txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
-		    AR5K_TUNE_MAX_TXPOWER : max_power;
+	/*
+	 * Since we use ints and not fps, we need to scale up in
+	 * order to get a sane ratio value (or else we 'll eg. get
+	 * always 1 instead of 1.25, 1.75 etc). We scale up by 100
+	 * to have some accuracy both for 0.5 and 0.25 steps.
+	 */
+	ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
 
-	for (i = 0; i < AR5K_MAX_RATES; i++)
-		rates[i] = txpower;
+	/* Now scale down to be in range */
+	result = y_left + (ratio * (target - x_left) / 100);
 
-	/* XXX setup target powers by rate */
+	return result;
+}
 
-	ah->ah_txpower.txp_min = rates[7];
-	ah->ah_txpower.txp_max = rates[0];
-	ah->ah_txpower.txp_ofdm = rates[0];
+/*
+ * Find vertical boundary (min pwr) for the linear PCDAC curve.
+ *
+ * Since we have the top of the curve and we draw the line below
+ * until we reach 1 (1 pcdac step) we need to know which point
+ * (x value) that is so that we don't go below y axis and have negative
+ * pcdac values when creating the curve, or fill the table with zeroes.
+ */
+static s16
+ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
+				const s16 *pwrL, const s16 *pwrR)
+{
+	s8 tmp;
+	s16 min_pwrL, min_pwrR;
+	s16 pwr_i;
 
-	/* Calculate the power table */
-	n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac);
-	min = AR5K_EEPROM_PCDAC_START;
-	max = AR5K_EEPROM_PCDAC_STOP;
-	for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
-		ah->ah_txpower.txp_pcdac[i] =
-#ifdef notyet
-		min + ((i * (max - min)) / n);
-#else
-		min;
+	if (pwrL[0] == pwrL[1])
+		min_pwrL = pwrL[0];
+	else {
+		pwr_i = pwrL[0];
+		do {
+			pwr_i--;
+			tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+							pwrL[0], pwrL[1],
+							stepL[0], stepL[1]);
+		} while (tmp > 1);
+
+		min_pwrL = pwr_i;
+	}
+
+	if (pwrR[0] == pwrR[1])
+		min_pwrR = pwrR[0];
+	else {
+		pwr_i = pwrR[0];
+		do {
+			pwr_i--;
+			tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+							pwrR[0], pwrR[1],
+							stepR[0], stepR[1]);
+		} while (tmp > 1);
+
+		min_pwrR = pwr_i;
+	}
+
+	/* Keep the right boundary so that it works for both curves */
+	return max(min_pwrL, min_pwrR);
+}
+
+/*
+ * Interpolate (pwr,vpd) points to create a Power to PDADC or a
+ * Power to PCDAC curve.
+ *
+ * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
+ * steps (offsets) on y axis. Power can go up to 31.5dB and max
+ * PCDAC/PDADC step for each curve is 64 but we can write more than
+ * one curves on hw so we can go up to 128 (which is the max step we
+ * can write on the final table).
+ *
+ * We write y values (PCDAC/PDADC steps) on hw.
+ */
+static void
+ath5k_create_power_curve(s16 pmin, s16 pmax,
+			const s16 *pwr, const u8 *vpd,
+			u8 num_points,
+			u8 *vpd_table, u8 type)
+{
+	u8 idx[2] = { 0, 1 };
+	s16 pwr_i = 2*pmin;
+	int i;
+
+	if (num_points < 2)
+		return;
+
+	/* We want the whole line, so adjust boundaries
+	 * to cover the entire power range. Note that
+	 * power values are already 0.25dB so no need
+	 * to multiply pwr_i by 2 */
+	if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
+		pwr_i = pmin;
+		pmin = 0;
+		pmax = 63;
+	}
+
+	/* Find surrounding turning points (TPs)
+	 * and interpolate between them */
+	for (i = 0; (i <= (u16) (pmax - pmin)) &&
+	(i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+
+		/* We passed the right TP, move to the next set of TPs
+		 * if we pass the last TP, extrapolate above using the last
+		 * two TPs for ratio */
+		if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
+			idx[0]++;
+			idx[1]++;
+		}
+
+		vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
+						pwr[idx[0]], pwr[idx[1]],
+						vpd[idx[0]], vpd[idx[1]]);
+
+		/* Increase by 0.5dB
+		 * (0.25 dB units) */
+		pwr_i += 2;
+	}
+}
+
+/*
+ * Get the surrounding per-channel power calibration piers
+ * for a given frequency so that we can interpolate between
+ * them and come up with an apropriate dataset for our current
+ * channel.
+ */
+static void
+ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
+			struct ieee80211_channel *channel,
+			struct ath5k_chan_pcal_info **pcinfo_l,
+			struct ath5k_chan_pcal_info **pcinfo_r)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info *pcinfo;
+	u8 idx_l, idx_r;
+	u8 mode, max, i;
+	u32 target = channel->center_freq;
+
+	idx_l = 0;
+	idx_r = 0;
+
+	if (!(channel->hw_value & CHANNEL_OFDM)) {
+		pcinfo = ee->ee_pwr_cal_b;
+		mode = AR5K_EEPROM_MODE_11B;
+	} else if (channel->hw_value & CHANNEL_2GHZ) {
+		pcinfo = ee->ee_pwr_cal_g;
+		mode = AR5K_EEPROM_MODE_11G;
+	} else {
+		pcinfo = ee->ee_pwr_cal_a;
+		mode = AR5K_EEPROM_MODE_11A;
+	}
+	max = ee->ee_n_piers[mode] - 1;
+
+	/* Frequency is below our calibrated
+	 * range. Use the lowest power curve
+	 * we have */
+	if (target < pcinfo[0].freq) {
+		idx_l = idx_r = 0;
+		goto done;
+	}
+
+	/* Frequency is above our calibrated
+	 * range. Use the highest power curve
+	 * we have */
+	if (target > pcinfo[max].freq) {
+		idx_l = idx_r = max;
+		goto done;
+	}
+
+	/* Frequency is inside our calibrated
+	 * channel range. Pick the surrounding
+	 * calibration piers so that we can
+	 * interpolate */
+	for (i = 0; i <= max; i++) {
+
+		/* Frequency matches one of our calibration
+		 * piers, no need to interpolate, just use
+		 * that calibration pier */
+		if (pcinfo[i].freq == target) {
+			idx_l = idx_r = i;
+			goto done;
+		}
+
+		/* We found a calibration pier that's above
+		 * frequency, use this pier and the previous
+		 * one to interpolate */
+		if (target < pcinfo[i].freq) {
+			idx_r = i;
+			idx_l = idx_r - 1;
+			goto done;
+		}
+	}
+
+done:
+	*pcinfo_l = &pcinfo[idx_l];
+	*pcinfo_r = &pcinfo[idx_r];
+
+	return;
+}
+
+/*
+ * Get the surrounding per-rate power calibration data
+ * for a given frequency and interpolate between power
+ * values to set max target power supported by hw for
+ * each rate.
+ */
+static void
+ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
+			struct ieee80211_channel *channel,
+			struct ath5k_rate_pcal_info *rates)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_rate_pcal_info *rpinfo;
+	u8 idx_l, idx_r;
+	u8 mode, max, i;
+	u32 target = channel->center_freq;
+
+	idx_l = 0;
+	idx_r = 0;
+
+	if (!(channel->hw_value & CHANNEL_OFDM)) {
+		rpinfo = ee->ee_rate_tpwr_b;
+		mode = AR5K_EEPROM_MODE_11B;
+	} else if (channel->hw_value & CHANNEL_2GHZ) {
+		rpinfo = ee->ee_rate_tpwr_g;
+		mode = AR5K_EEPROM_MODE_11G;
+	} else {
+		rpinfo = ee->ee_rate_tpwr_a;
+		mode = AR5K_EEPROM_MODE_11A;
+	}
+	max = ee->ee_rate_target_pwr_num[mode] - 1;
+
+	/* Get the surrounding calibration
+	 * piers - same as above */
+	if (target < rpinfo[0].freq) {
+		idx_l = idx_r = 0;
+		goto done;
+	}
+
+	if (target > rpinfo[max].freq) {
+		idx_l = idx_r = max;
+		goto done;
+	}
+
+	for (i = 0; i <= max; i++) {
+
+		if (rpinfo[i].freq == target) {
+			idx_l = idx_r = i;
+			goto done;
+		}
+
+		if (target < rpinfo[i].freq) {
+			idx_r = i;
+			idx_l = idx_r - 1;
+			goto done;
+		}
+	}
+
+done:
+	/* Now interpolate power value, based on the frequency */
+	rates->freq = target;
+
+	rates->target_power_6to24 =
+		ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+					rpinfo[idx_r].freq,
+					rpinfo[idx_l].target_power_6to24,
+					rpinfo[idx_r].target_power_6to24);
+
+	rates->target_power_36 =
+		ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+					rpinfo[idx_r].freq,
+					rpinfo[idx_l].target_power_36,
+					rpinfo[idx_r].target_power_36);
+
+	rates->target_power_48 =
+		ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+					rpinfo[idx_r].freq,
+					rpinfo[idx_l].target_power_48,
+					rpinfo[idx_r].target_power_48);
+
+	rates->target_power_54 =
+		ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+					rpinfo[idx_r].freq,
+					rpinfo[idx_l].target_power_54,
+					rpinfo[idx_r].target_power_54);
+}
+
+/*
+ * Get the max edge power for this channel if
+ * we have such data from EEPROM's Conformance Test
+ * Limits (CTL), and limit max power if needed.
+ *
+ * FIXME: Only works for world regulatory domains
+ */
+static void
+ath5k_get_max_ctl_power(struct ath5k_hw *ah,
+			struct ieee80211_channel *channel)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
+	u8 *ctl_val = ee->ee_ctl;
+	s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
+	s16 edge_pwr = 0;
+	u8 rep_idx;
+	u8 i, ctl_mode;
+	u8 ctl_idx = 0xFF;
+	u32 target = channel->center_freq;
+
+	/* Find out a CTL for our mode that's not mapped
+	 * on a specific reg domain.
+	 *
+	 * TODO: Map our current reg domain to one of the 3 available
+	 * reg domain ids so that we can support more CTLs. */
+	switch (channel->hw_value & CHANNEL_MODES) {
+	case CHANNEL_A:
+		ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
+		break;
+	case CHANNEL_G:
+		ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
+		break;
+	case CHANNEL_B:
+		ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
+		break;
+	case CHANNEL_T:
+		ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
+		break;
+	case CHANNEL_TG:
+		ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
+		break;
+	case CHANNEL_XR:
+		/* Fall through */
+	default:
+		return;
+	}
+
+	for (i = 0; i < ee->ee_ctls; i++) {
+		if (ctl_val[i] == ctl_mode) {
+			ctl_idx = i;
+			break;
+		}
+	}
+
+	/* If we have a CTL dataset available grab it and find the
+	 * edge power for our frequency */
+	if (ctl_idx == 0xFF)
+		return;
+
+	/* Edge powers are sorted by frequency from lower
+	 * to higher. Each CTL corresponds to 8 edge power
+	 * measurements. */
+	rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
+
+	/* Don't do boundaries check because we
+	 * might have more that one bands defined
+	 * for this mode */
+
+	/* Get the edge power that's closer to our
+	 * frequency */
+	for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
+		rep_idx += i;
+		if (target <= rep[rep_idx].freq)
+			edge_pwr = (s16) rep[rep_idx].edge;
+	}
+
+	if (edge_pwr)
+		ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
+}
+
+
+/*
+ * Power to PCDAC table functions
+ */
+
+/*
+ * Fill Power to PCDAC table on RF5111
+ *
+ * No further processing is needed for RF5111, the only thing we have to
+ * do is fill the values below and above calibration range since eeprom data
+ * may not cover the entire PCDAC table.
+ */
+static void
+ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
+							s16 *table_max)
+{
+	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	u8	*pcdac_tmp = ah->ah_txpower.tmpL[0];
+	u8	pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
+	s16	min_pwr, max_pwr;
+
+	/* Get table boundaries */
+	min_pwr = table_min[0];
+	pcdac_0 = pcdac_tmp[0];
+
+	max_pwr = table_max[0];
+	pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
+
+	/* Extrapolate below minimum using pcdac_0 */
+	pcdac_i = 0;
+	for (i = 0; i < min_pwr; i++)
+		pcdac_out[pcdac_i++] = pcdac_0;
+
+	/* Copy values from pcdac_tmp */
+	pwr_idx = min_pwr;
+	for (i = 0 ; pwr_idx <= max_pwr &&
+	pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
+		pcdac_out[pcdac_i++] = pcdac_tmp[i];
+		pwr_idx++;
+	}
+
+	/* Extrapolate above maximum */
+	while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
+		pcdac_out[pcdac_i++] = pcdac_n;
+
+}
+
+/*
+ * Combine available XPD Curves and fill Linear Power to PCDAC table
+ * on RF5112
+ *
+ * RFX112 can have up to 2 curves (one for low txpower range and one for
+ * higher txpower range). We need to put them both on pcdac_out and place
+ * them in the correct location. In case we only have one curve available
+ * just fit it on pcdac_out (it's supposed to cover the entire range of
+ * available pwr levels since it's always the higher power curve). Extrapolate
+ * below and above final table if needed.
+ */
+static void
+ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
+						s16 *table_max, u8 pdcurves)
+{
+	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	u8	*pcdac_low_pwr;
+	u8	*pcdac_high_pwr;
+	u8	*pcdac_tmp;
+	u8	pwr;
+	s16	max_pwr_idx;
+	s16	min_pwr_idx;
+	s16	mid_pwr_idx = 0;
+	/* Edge flag turs on the 7nth bit on the PCDAC
+	 * to delcare the higher power curve (force values
+	 * to be greater than 64). If we only have one curve
+	 * we don't need to set this, if we have 2 curves and
+	 * fill the table backwards this can also be used to
+	 * switch from higher power curve to lower power curve */
+	u8	edge_flag;
+	int	i;
+
+	/* When we have only one curve available
+	 * that's the higher power curve. If we have
+	 * two curves the first is the high power curve
+	 * and the next is the low power curve. */
+	if (pdcurves > 1) {
+		pcdac_low_pwr = ah->ah_txpower.tmpL[1];
+		pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+		mid_pwr_idx = table_max[1] - table_min[1] - 1;
+		max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+
+		/* If table size goes beyond 31.5dB, keep the
+		 * upper 31.5dB range when setting tx power.
+		 * Note: 126 = 31.5 dB in quarter dB steps */
+		if (table_max[0] - table_min[1] > 126)
+			min_pwr_idx = table_max[0] - 126;
+		else
+			min_pwr_idx = table_min[1];
+
+		/* Since we fill table backwards
+		 * start from high power curve */
+		pcdac_tmp = pcdac_high_pwr;
+
+		edge_flag = 0x40;
+#if 0
+		/* If both min and max power limits are in lower
+		 * power curve's range, only use the low power curve.
+		 * TODO: min/max levels are related to target
+		 * power values requested from driver/user
+		 * XXX: Is this really needed ? */
+		if (min_pwr < table_max[1] &&
+		max_pwr < table_max[1]) {
+			edge_flag = 0;
+			pcdac_tmp = pcdac_low_pwr;
+			max_pwr_idx = (table_max[1] - table_min[1])/2;
+		}
 #endif
+	} else {
+		pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
+		pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+		min_pwr_idx = table_min[0];
+		max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+		pcdac_tmp = pcdac_high_pwr;
+		edge_flag = 0;
+	}
+
+	/* This is used when setting tx power*/
+	ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
+
+	/* Fill Power to PCDAC table backwards */
+	pwr = max_pwr_idx;
+	for (i = 63; i >= 0; i--) {
+		/* Entering lower power range, reset
+		 * edge flag and set pcdac_tmp to lower
+		 * power curve.*/
+		if (edge_flag == 0x40 &&
+		(2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
+			edge_flag = 0x00;
+			pcdac_tmp = pcdac_low_pwr;
+			pwr = mid_pwr_idx/2;
+		}
+
+		/* Don't go below 1, extrapolate below if we have
+		 * already swithced to the lower power curve -or
+		 * we only have one curve and edge_flag is zero
+		 * anyway */
+		if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
+			while (i >= 0) {
+				pcdac_out[i] = pcdac_out[i + 1];
+				i--;
+			}
+			break;
+		}
+
+		pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
+
+		/* Extrapolate above if pcdac is greater than
+		 * 126 -this can happen because we OR pcdac_out
+		 * value with edge_flag on high power curve */
+		if (pcdac_out[i] > 126)
+			pcdac_out[i] = 126;
+
+		/* Decrease by a 0.5dB step */
+		pwr--;
+	}
 }
 
+/* Write PCDAC values on hw */
+static void
+ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+{
+	u8 	*pcdac_out = ah->ah_txpower.txp_pd_table;
+	int	i;
+
+	/*
+	 * Write TX power values
+	 */
+	for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+		ath5k_hw_reg_write(ah,
+			(((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
+			(((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
+			AR5K_PHY_PCDAC_TXPOWER(i));
+	}
+}
+
+
 /*
- * Set transmition power
+ * Power to PDADC table functions
  */
-int /*O.K. - txpower_table is unimplemented so this doesn't work*/
-ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-		unsigned int txpower)
+
+/*
+ * Set the gain boundaries and create final Power to PDADC table
+ *
+ * We can have up to 4 pd curves, we need to do a simmilar process
+ * as we do for RF5112. This time we don't have an edge_flag but we
+ * set the gain boundaries on a separate register.
+ */
+static void
+ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
+			s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
 {
-	bool tpc = ah->ah_txpower.txp_tpc;
-	unsigned int i;
+	u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
+	u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+	u8 *pdadc_tmp;
+	s16 pdadc_0;
+	u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
+	u8 pd_gain_overlap;
 
-	ATH5K_TRACE(ah->ah_sc);
-	if (txpower > AR5K_TUNE_MAX_TXPOWER) {
-		ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
-		return -EINVAL;
+	/* Note: Register value is initialized on initvals
+	 * there is no feedback from hw.
+	 * XXX: What about pd_gain_overlap from EEPROM ? */
+	pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
+		AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
+
+	/* Create final PDADC table */
+	for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
+		pdadc_tmp = ah->ah_txpower.tmpL[pdg];
+
+		if (pdg == pdcurves - 1)
+			/* 2 dB boundary stretch for last
+			 * (higher power) curve */
+			gain_boundaries[pdg] = pwr_max[pdg] + 4;
+		else
+			/* Set gain boundary in the middle
+			 * between this curve and the next one */
+			gain_boundaries[pdg] =
+				(pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
+
+		/* Sanity check in case our 2 db stretch got out of
+		 * range. */
+		if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
+			gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
+
+		/* For the first curve (lower power)
+		 * start from 0 dB */
+		if (pdg == 0)
+			pdadc_0 = 0;
+		else
+			/* For the other curves use the gain overlap */
+			pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
+							pd_gain_overlap;
+
+		/* Force each power step to be at least 0.5 dB */
+		if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
+			pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
+		else
+			pwr_step = 1;
+
+		/* If pdadc_0 is negative, we need to extrapolate
+		 * below this pdgain by a number of pwr_steps */
+		while ((pdadc_0 < 0) && (pdadc_i < 128)) {
+			s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
+			pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
+			pdadc_0++;
+		}
+
+		/* Set last pwr level, using gain boundaries */
+		pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
+		/* Limit it to be inside pwr range */
+		table_size = pwr_max[pdg] - pwr_min[pdg];
+		max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
+
+		/* Fill pdadc_out table */
+		while (pdadc_0 < max_idx)
+			pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
+
+		/* Need to extrapolate above this pdgain? */
+		if (pdadc_n <= max_idx)
+			continue;
+
+		/* Force each power step to be at least 0.5 dB */
+		if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
+			pwr_step = pdadc_tmp[table_size - 1] -
+						pdadc_tmp[table_size - 2];
+		else
+			pwr_step = 1;
+
+		/* Extrapolate above */
+		while ((pdadc_0 < (s16) pdadc_n) &&
+		(pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
+			s16 tmp = pdadc_tmp[table_size - 1] +
+					(pdadc_0 - max_idx) * pwr_step;
+			pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
+			pdadc_0++;
+		}
 	}
 
+	while (pdg < AR5K_EEPROM_N_PD_GAINS) {
+		gain_boundaries[pdg] = gain_boundaries[pdg - 1];
+		pdg++;
+	}
+
+	while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
+		pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
+		pdadc_i++;
+	}
+
+	/* Set gain boundaries */
+	ath5k_hw_reg_write(ah,
+		AR5K_REG_SM(pd_gain_overlap,
+			AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
+		AR5K_REG_SM(gain_boundaries[0],
+			AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
+		AR5K_REG_SM(gain_boundaries[1],
+			AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
+		AR5K_REG_SM(gain_boundaries[2],
+			AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
+		AR5K_REG_SM(gain_boundaries[3],
+			AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
+		AR5K_PHY_TPC_RG5);
+
+	/* Used for setting rate power table */
+	ah->ah_txpower.txp_min_idx = pwr_min[0];
+
+}
+
+/* Write PDADC values on hw */
+static void
+ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
+			u8 pdcurves, u8 *pdg_to_idx)
+{
+	u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+	u32 reg;
+	u8 i;
+
+	/* Select the right pdgain curves */
+
+	/* Clear current settings */
+	reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
+	reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
+		AR5K_PHY_TPC_RG1_PDGAIN_2 |
+		AR5K_PHY_TPC_RG1_PDGAIN_3 |
+		AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
 	/*
-	 * RF2413 for some reason can't
-	 * transmit anything if we call
-	 * this funtion, so we skip it
-	 * until we fix txpower.
+	 * Use pd_gains curve from eeprom
 	 *
-	 * XXX: Assume same for RF2425
-	 * to be safe.
+	 * This overrides the default setting from initvals
+	 * in case some vendors (e.g. Zcomax) don't use the default
+	 * curves. If we don't honor their settings we 'll get a
+	 * 5dB (1 * gain overlap ?) drop.
 	 */
-	if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425))
-		return 0;
-
-	/* Reset TX power values */
-	memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
-	ah->ah_txpower.txp_tpc = tpc;
+	reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
 
-	/* Initialize TX power table */
-	ath5k_txpower_table(ah, channel, txpower);
+	switch (pdcurves) {
+	case 3:
+		reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
+		/* Fall through */
+	case 2:
+		reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
+		/* Fall through */
+	case 1:
+		reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
+		break;
+	}
+	ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
 
 	/*
 	 * Write TX power values
 	 */
 	for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
 		ath5k_hw_reg_write(ah,
-			((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) |
-			(((ah->ah_txpower.txp_pcdac[(i << 1)    ] << 8) | 0xff) & 0xffff),
-			AR5K_PHY_PCDAC_TXPOWER(i));
+			((pdadc_out[4*i + 0] & 0xff) << 0) |
+			((pdadc_out[4*i + 1] & 0xff) << 8) |
+			((pdadc_out[4*i + 2] & 0xff) << 16) |
+			((pdadc_out[4*i + 3] & 0xff) << 24),
+			AR5K_PHY_PDADC_TXPOWER(i));
+	}
+}
+
+
+/*
+ * Common code for PCDAC/PDADC tables
+ */
+
+/*
+ * This is the main function that uses all of the above
+ * to set PCDAC/PDADC table on hw for the current channel.
+ * This table is used for tx power calibration on the basband,
+ * without it we get weird tx power levels and in some cases
+ * distorted spectral mask
+ */
+static int
+ath5k_setup_channel_powertable(struct ath5k_hw *ah,
+			struct ieee80211_channel *channel,
+			u8 ee_mode, u8 type)
+{
+	struct ath5k_pdgain_info *pdg_L, *pdg_R;
+	struct ath5k_chan_pcal_info *pcinfo_L;
+	struct ath5k_chan_pcal_info *pcinfo_R;
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+	s16 table_min[AR5K_EEPROM_N_PD_GAINS];
+	s16 table_max[AR5K_EEPROM_N_PD_GAINS];
+	u8 *tmpL;
+	u8 *tmpR;
+	u32 target = channel->center_freq;
+	int pdg, i;
+
+	/* Get surounding freq piers for this channel */
+	ath5k_get_chan_pcal_surrounding_piers(ah, channel,
+						&pcinfo_L,
+						&pcinfo_R);
+
+	/* Loop over pd gain curves on
+	 * surounding freq piers by index */
+	for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
+
+		/* Fill curves in reverse order
+		 * from lower power (max gain)
+		 * to higher power. Use curve -> idx
+		 * backmaping we did on eeprom init */
+		u8 idx = pdg_curve_to_idx[pdg];
+
+		/* Grab the needed curves by index */
+		pdg_L = &pcinfo_L->pd_curves[idx];
+		pdg_R = &pcinfo_R->pd_curves[idx];
+
+		/* Initialize the temp tables */
+		tmpL = ah->ah_txpower.tmpL[pdg];
+		tmpR = ah->ah_txpower.tmpR[pdg];
+
+		/* Set curve's x boundaries and create
+		 * curves so that they cover the same
+		 * range (if we don't do that one table
+		 * will have values on some range and the
+		 * other one won't have any so interpolation
+		 * will fail) */
+		table_min[pdg] = min(pdg_L->pd_pwr[0],
+					pdg_R->pd_pwr[0]) / 2;
+
+		table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+				pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
+
+		/* Now create the curves on surrounding channels
+		 * and interpolate if needed to get the final
+		 * curve for this gain on this channel */
+		switch (type) {
+		case AR5K_PWRTABLE_LINEAR_PCDAC:
+			/* Override min/max so that we don't loose
+			 * accuracy (don't divide by 2) */
+			table_min[pdg] = min(pdg_L->pd_pwr[0],
+						pdg_R->pd_pwr[0]);
+
+			table_max[pdg] =
+				max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+					pdg_R->pd_pwr[pdg_R->pd_points - 1]);
+
+			/* Override minimum so that we don't get
+			 * out of bounds while extrapolating
+			 * below. Don't do this when we have 2
+			 * curves and we are on the high power curve
+			 * because table_min is ok in this case */
+			if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
+
+				table_min[pdg] =
+					ath5k_get_linear_pcdac_min(pdg_L->pd_step,
+								pdg_R->pd_step,
+								pdg_L->pd_pwr,
+								pdg_R->pd_pwr);
+
+				/* Don't go too low because we will
+				 * miss the upper part of the curve.
+				 * Note: 126 = 31.5dB (max power supported)
+				 * in 0.25dB units */
+				if (table_max[pdg] - table_min[pdg] > 126)
+					table_min[pdg] = table_max[pdg] - 126;
+			}
+
+			/* Fall through */
+		case AR5K_PWRTABLE_PWR_TO_PCDAC:
+		case AR5K_PWRTABLE_PWR_TO_PDADC:
+
+			ath5k_create_power_curve(table_min[pdg],
+						table_max[pdg],
+						pdg_L->pd_pwr,
+						pdg_L->pd_step,
+						pdg_L->pd_points, tmpL, type);
+
+			/* We are in a calibration
+			 * pier, no need to interpolate
+			 * between freq piers */
+			if (pcinfo_L == pcinfo_R)
+				continue;
+
+			ath5k_create_power_curve(table_min[pdg],
+						table_max[pdg],
+						pdg_R->pd_pwr,
+						pdg_R->pd_step,
+						pdg_R->pd_points, tmpR, type);
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		/* Interpolate between curves
+		 * of surounding freq piers to
+		 * get the final curve for this
+		 * pd gain. Re-use tmpL for interpolation
+		 * output */
+		for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
+		(i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+			tmpL[i] = (u8) ath5k_get_interpolated_value(target,
+							(s16) pcinfo_L->freq,
+							(s16) pcinfo_R->freq,
+							(s16) tmpL[i],
+							(s16) tmpR[i]);
+		}
+	}
+
+	/* 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).
+	 * 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. */
+
+	/* Fill min and max power levels for this
+	 * channel by interpolating the values on
+	 * surounding channels to complete the dataset */
+	ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
+					(s16) pcinfo_L->freq,
+					(s16) pcinfo_R->freq,
+					pcinfo_L->min_pwr, pcinfo_R->min_pwr);
+
+	ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
+					(s16) pcinfo_L->freq,
+					(s16) pcinfo_R->freq,
+					pcinfo_L->max_pwr, pcinfo_R->max_pwr);
+
+	/* We are ready to go, fill PCDAC/PDADC
+	 * table and write settings on hardware */
+	switch (type) {
+	case AR5K_PWRTABLE_LINEAR_PCDAC:
+		/* For RF5112 we can have one or two curves
+		 * and each curve covers a certain power lvl
+		 * range so we need to do some more processing */
+		ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
+						ee->ee_pd_gains[ee_mode]);
+
+		/* Set txp.offset so that we can
+		 * match max power value with max
+		 * table index */
+		ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
+
+		/* Write settings on hw */
+		ath5k_setup_pcdac_table(ah);
+		break;
+	case AR5K_PWRTABLE_PWR_TO_PCDAC:
+		/* We are done for RF5111 since it has only
+		 * one curve, just fit the curve on the table */
+		ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
+
+		/* No rate powertable adjustment for RF5111 */
+		ah->ah_txpower.txp_min_idx = 0;
+		ah->ah_txpower.txp_offset = 0;
+
+		/* Write settings on hw */
+		ath5k_setup_pcdac_table(ah);
+		break;
+	case AR5K_PWRTABLE_PWR_TO_PDADC:
+		/* Set PDADC boundaries and fill
+		 * final PDADC table */
+		ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
+						ee->ee_pd_gains[ee_mode]);
+
+		/* Write settings on hw */
+		ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
+
+		/* Set txp.offset, note that table_min
+		 * can be negative */
+		ah->ah_txpower.txp_offset = table_min[0];
+		break;
+	default:
+		return -EINVAL;
 	}
 
+	return 0;
+}
+
+
+/*
+ * Per-rate tx power setting
+ *
+ * This is the code that sets the desired tx power (below
+ * maximum) on hw for each rate (we also have TPC that sets
+ * power per packet). We do that by providing an index on the
+ * PCDAC/PDADC table we set up.
+ */
+
+/*
+ * Set rate power table
+ *
+ * For now we only limit txpower based on maximum tx power
+ * supported by hw (what's inside rate_info). We need to limit
+ * this even more, based on regulatory domain etc.
+ *
+ * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
+ * and is indexed as follows:
+ * rates[0] - rates[7] -> OFDM rates
+ * rates[8] - rates[14] -> CCK rates
+ * rates[15] -> XR rates (they all have the same power)
+ */
+static void
+ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
+			struct ath5k_rate_pcal_info *rate_info,
+			u8 ee_mode)
+{
+	unsigned int i;
+	u16 *rates;
+
+	/* max_pwr is power level we got from driver/user in 0.5dB
+	 * units, switch to 0.25dB units so we can compare */
+	max_pwr *= 2;
+	max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
+
+	/* apply rate limits */
+	rates = ah->ah_txpower.txp_rates_power_table;
+
+	/* OFDM rates 6 to 24Mb/s */
+	for (i = 0; i < 5; i++)
+		rates[i] = min(max_pwr, rate_info->target_power_6to24);
+
+	/* Rest OFDM rates */
+	rates[5] = min(rates[0], rate_info->target_power_36);
+	rates[6] = min(rates[0], rate_info->target_power_48);
+	rates[7] = min(rates[0], rate_info->target_power_54);
+
+	/* CCK rates */
+	/* 1L */
+	rates[8] = min(rates[0], rate_info->target_power_6to24);
+	/* 2L */
+	rates[9] = min(rates[0], rate_info->target_power_36);
+	/* 2S */
+	rates[10] = min(rates[0], rate_info->target_power_36);
+	/* 5L */
+	rates[11] = min(rates[0], rate_info->target_power_48);
+	/* 5S */
+	rates[12] = min(rates[0], rate_info->target_power_48);
+	/* 11L */
+	rates[13] = min(rates[0], rate_info->target_power_54);
+	/* 11S */
+	rates[14] = min(rates[0], rate_info->target_power_54);
+
+	/* XR rates */
+	rates[15] = min(rates[0], rate_info->target_power_6to24);
+
+	/* CCK rates have different peak to average ratio
+	 * so we have to tweak their power so that gainf
+	 * correction works ok. For this we use OFDM to
+	 * CCK delta from eeprom */
+	if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
+	(ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
+		for (i = 8; i <= 15; i++)
+			rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
+
+	ah->ah_txpower.txp_min_pwr = rates[7];
+	ah->ah_txpower.txp_max_pwr = rates[0];
+	ah->ah_txpower.txp_ofdm = rates[7];
+}
+
+
+/*
+ * Set transmition power
+ */
+int
+ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+		u8 ee_mode, u8 txpower)
+{
+	struct ath5k_rate_pcal_info rate_info;
+	u8 type;
+	int ret;
+
+	ATH5K_TRACE(ah->ah_sc);
+	if (txpower > AR5K_TUNE_MAX_TXPOWER) {
+		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));
+	ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+	ah->ah_txpower.txp_min_pwr = 0;
+	ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+
+	/* Initialize TX power table */
+	switch (ah->ah_radio) {
+	case AR5K_RF5111:
+		type = AR5K_PWRTABLE_PWR_TO_PCDAC;
+		break;
+	case AR5K_RF5112:
+		type = AR5K_PWRTABLE_LINEAR_PCDAC;
+		break;
+	case AR5K_RF2413:
+	case AR5K_RF5413:
+	case AR5K_RF2316:
+	case AR5K_RF2317:
+	case AR5K_RF2425:
+		type = AR5K_PWRTABLE_PWR_TO_PDADC;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* FIXME: Only on channel/mode change */
+	ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
+	if (ret)
+		return ret;
+
+	/* Limit max power if we have a CTL available */
+	ath5k_get_max_ctl_power(ah, channel);
+
+	/* FIXME: Tx power limit for this regdomain
+	 * XXX: Mac80211/CRDA will do that anyway ? */
+
+	/* FIXME: Antenna reduction stuff */
+
+	/* FIXME: Limit power on turbo modes */
+
+	/* FIXME: TPC scale reduction */
+
+	/* Get surounding channels for per-rate power table
+	 * calibration */
+	ath5k_get_rate_pcal_data(ah, channel, &rate_info);
+
+	/* Setup rate power table */
+	ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
+
+	/* Write rate power table on hw */
 	ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
 		AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
 		AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
@@ -2481,26 +2573,34 @@ ath5k_hw_txpower(struct ath5k_hw *ah, st
 		AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
 		AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
 
-	if (ah->ah_txpower.txp_tpc)
+	/* FIXME: TPC support */
+	if (ah->ah_txpower.txp_tpc) {
 		ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
 			AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
-	else
+
+		ath5k_hw_reg_write(ah,
+			AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
+			AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
+			AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+			AR5K_TPC);
+	} else {
 		ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
 			AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+	}
 
 	return 0;
 }
 
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power)
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
 {
 	/*Just a try M.F.*/
 	struct ieee80211_channel *channel = &ah->ah_current_channel;
 
 	ATH5K_TRACE(ah->ah_sc);
 	ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
-		"changing txpower to %d\n", power);
+		"changing txpower to %d\n", txpower);
 
-	return ath5k_hw_txpower(ah, channel, power);
+	return ath5k_hw_txpower(ah, channel, mode, txpower);
 }
 
 #undef _ATH5K_PHY
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/qcu.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/qcu.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/qcu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/qcu.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,6 +148,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k
  */
 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
 {
+	u32 pending;
 	ATH5K_TRACE(ah->ah_sc);
 	AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
 
@@ -159,7 +160,15 @@ u32 ath5k_hw_num_tx_pending(struct ath5k
 	if (ah->ah_version == AR5K_AR5210)
 		return false;
 
-	return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
+	pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+
+	/* It's possible to have no frames pending even if TXE
+	 * is set. To indicate that q has not stopped return
+	 * true */
+	if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+		return true;
+
+	return pending;
 }
 
 /*
@@ -324,8 +333,18 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 		/*
 		 * Set misc registers
 		 */
-		ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
-			AR5K_QUEUE_MISC(queue));
+		/* Enable DCU early termination for this queue */
+		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+					AR5K_QCU_MISC_DCU_EARLY);
+
+		/* Enable DCU to wait for next fragment from QCU */
+		AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+					AR5K_DCU_MISC_FRAG_WAIT);
+
+		/* On Maui and Spirit use the global seqnum on DCU */
+		if (ah->ah_mac_version < AR5K_SREV_AR5211)
+			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+						AR5K_DCU_MISC_SEQNUM_CTL);
 
 		if (tq->tqi_cbr_period) {
 			ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
@@ -341,7 +360,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 					AR5K_QCU_MISC_CBR_THRES_ENABLE);
 		}
 
-		if (tq->tqi_ready_time)
+		if (tq->tqi_ready_time &&
+		(tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
 			ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
 				AR5K_QCU_RDYTIMECFG_INTVAL) |
 				AR5K_QCU_RDYTIMECFG_ENABLE,
@@ -383,13 +403,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 				AR5K_DCU_MISC_ARBLOCK_CTL_S) |
 				AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
 				AR5K_DCU_MISC_BCN_ENABLE);
-
-			ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
-				(AR5K_TUNE_SW_BEACON_RESP -
-				AR5K_TUNE_DMA_BEACON_RESP) -
-				AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
-				AR5K_QCU_RDYTIMECFG_ENABLE,
-				AR5K_QUEUE_RDYTIMECFG(queue));
 			break;
 
 		case AR5K_TX_QUEUE_CAB:
@@ -398,6 +411,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 				AR5K_QCU_MISC_CBREXP_DIS |
 				AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
+			ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+				(AR5K_TUNE_SW_BEACON_RESP -
+				AR5K_TUNE_DMA_BEACON_RESP) -
+				AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+				AR5K_QCU_RDYTIMECFG_ENABLE,
+				AR5K_QUEUE_RDYTIMECFG(queue));
+
 			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
 				(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
 				AR5K_DCU_MISC_ARBLOCK_CTL_S));
@@ -413,6 +433,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 			break;
 		}
 
+		/* TODO: Handle frame compression */
+
 		/*
 		 * Enable interrupts for this tx queue
 		 * in the secondary interrupt mask registers
@@ -483,6 +505,9 @@ int ath5k_hw_reset_tx_queue(struct ath5k
 		 * by setting AR5K_TXNOFRM to zero */
 		if (ah->ah_txq_imr_nofrm == 0)
 			ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+		/* Set QCU mask for this DCU to save power */
+		AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
 	}
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/reg.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -187,6 +187,7 @@
 #define AR5K_TXCFG_FRMPAD_DIS		0x00002000	/* [5211+] */
 #define AR5K_TXCFG_RDY_CBR_DIS		0x00004000	/* Ready time CBR disable [5211+] */
 #define AR5K_TXCFG_JUMBO_FRM_MODE	0x00008000	/* Jumbo frame mode [5211+] */
+#define	AR5K_TXCFG_DCU_DBL_BUF_DIS	0x00008000	/* Disable double buffering on DCU */
 #define AR5K_TXCFG_DCU_CACHING_DIS	0x00010000	/* Disable DCU caching */
 
 /*
@@ -753,7 +754,7 @@
  */
 #define AR5K_DCU_SEQNUM_BASE		0x1140
 #define	AR5K_DCU_SEQNUM_M		0x00000fff
-#define	AR5K_QUEUE_DFS_SEQNUM(_q)	AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+#define	AR5K_QUEUE_DCU_SEQNUM(_q)	AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
 
 /*
  * DCU global IFS SIFS register
@@ -811,6 +812,8 @@
 
 /*
  * DCU transmit filter table 0 (32 entries)
+ * each entry contains a 32bit slice of the
+ * 128bit tx filter for each DCU (4 slices per DCU)
  */
 #define AR5K_DCU_TX_FILTER_0_BASE	0x1038
 #define	AR5K_DCU_TX_FILTER_0(_n)	(AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
@@ -819,7 +822,7 @@
  * DCU transmit filter table 1 (16 entries)
  */
 #define AR5K_DCU_TX_FILTER_1_BASE	0x103c
-#define	AR5K_DCU_TX_FILTER_1(_n)	(AR5K_DCU_TX_FILTER_1_BASE + ((_n - 32) * 64))
+#define	AR5K_DCU_TX_FILTER_1(_n)	(AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
 
 /*
  * DCU clear transmit filter register
@@ -1447,7 +1450,7 @@
 				AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
 
 /*
- * Last beacon timestamp register
+ * Last beacon timestamp register (Read Only)
  */
 #define AR5K_LAST_TSTP	0x8080
 
@@ -1465,7 +1468,7 @@
 #define AR5K_ADDAC_TEST_TRIG_PTY	0x00020000	/* Trigger polarity */
 #define AR5K_ADDAC_TEST_RXCONT		0x00040000	/* Continuous capture */
 #define AR5K_ADDAC_TEST_CAPTURE		0x00080000	/* Begin capture */
-#define AR5K_ADDAC_TEST_TST_ARM		0x00100000	/* Test ARM (Adaptive Radio Mode ?) */
+#define AR5K_ADDAC_TEST_TST_ARM		0x00100000	/* ARM rx buffer for capture */
 
 /*
  * Default antenna register [5211+]
@@ -1551,6 +1554,19 @@
 /*===5212 Specific PCU registers===*/
 
 /*
+ * Transmit power control register
+ */
+#define AR5K_TPC			0x80e8
+#define AR5K_TPC_ACK			0x0000003f	/* ack frames */
+#define AR5K_TPC_ACK_S			0
+#define AR5K_TPC_CTS			0x00003f00	/* cts frames */
+#define AR5K_TPC_CTS_S			8
+#define AR5K_TPC_CHIRP			0x003f0000	/* chirp frames */
+#define AR5K_TPC_CHIRP_S		16
+#define AR5K_TPC_DOPPLER		0x0f000000	/* doppler chirp span */
+#define AR5K_TPC_DOPPLER_S		24
+
+/*
  * XR (eXtended Range) mode register
  */
 #define AR5K_XRMODE			0x80c0			/* Register Address */
@@ -1677,7 +1693,7 @@
  * TSF parameter register
  */
 #define AR5K_TSF_PARM			0x8104			/* Register Address */
-#define AR5K_TSF_PARM_INC_M		0x000000ff	/* Mask for TSF increment */
+#define AR5K_TSF_PARM_INC		0x000000ff	/* Mask for TSF increment */
 #define AR5K_TSF_PARM_INC_S		0
 
 /*
@@ -1689,7 +1705,7 @@
 #define AR5K_QOS_NOACK_BIT_OFFSET	0x00000070	/* ??? */
 #define AR5K_QOS_NOACK_BIT_OFFSET_S	4
 #define AR5K_QOS_NOACK_BYTE_OFFSET	0x00000180	/* ??? */
-#define AR5K_QOS_NOACK_BYTE_OFFSET_S	8
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S	7
 
 /*
  * PHY error filter register
@@ -1848,15 +1864,14 @@
  * TST_2 (Misc config parameters)
  */
 #define	AR5K_PHY_TST2			0x9800			/* Register Address */
-#define AR5K_PHY_TST2_TRIG_SEL		0x00000001	/* Trigger select (?) (field ?) */
-#define AR5K_PHY_TST2_TRIG		0x00000010	/* Trigger (?) (field ?) */
-#define AR5K_PHY_TST2_CBUS_MODE		0x00000100	/* Cardbus mode (?) */
-/* bit reserved */
+#define AR5K_PHY_TST2_TRIG_SEL		0x00000007	/* Trigger select (?)*/
+#define AR5K_PHY_TST2_TRIG		0x00000010	/* Trigger (?) */
+#define AR5K_PHY_TST2_CBUS_MODE		0x00000060	/* Cardbus mode (?) */
 #define AR5K_PHY_TST2_CLK32		0x00000400	/* CLK_OUT is CLK32 (32Khz external) */
 #define AR5K_PHY_TST2_CHANCOR_DUMP_EN	0x00000800	/* Enable Chancor dump (?) */
 #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP	0x00001000	/* Even Chancor dump (?) */
 #define AR5K_PHY_TST2_RFSILENT_EN	0x00002000	/* Enable RFSILENT */
-#define AR5K_PHY_TST2_ALT_RFDATA	0x00004000	/* Alternate RFDATA (5-2GHz switch) */
+#define AR5K_PHY_TST2_ALT_RFDATA	0x00004000	/* Alternate RFDATA (5-2GHz switch ?) */
 #define AR5K_PHY_TST2_MINI_OBS_EN	0x00008000	/* Enable mini OBS (?) */
 #define AR5K_PHY_TST2_RX2_IS_RX5_INV	0x00010000	/* 2GHz rx path is the 5GHz path inverted (?) */
 #define AR5K_PHY_TST2_SLOW_CLK160	0x00020000	/* Slow CLK160 (?) */
@@ -1926,8 +1941,8 @@
 #define	AR5K_PHY_RF_CTL2_TXF2TXD_START_S	0
 
 #define AR5K_PHY_RF_CTL3		0x9828			/* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON	0x0000000f	/* TX end to XLNA on */
-#define	AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S	0
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON	0x0000ff00	/* TX end to XLNA on */
+#define	AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S	8
 
 #define	AR5K_PHY_ADC_CTL			0x982c
 #define	AR5K_PHY_ADC_CTL_INBUFGAIN_OFF		0x00000003
@@ -1961,7 +1976,7 @@
 #define	AR5K_PHY_SETTLING_AGC		0x0000007f	/* AGC settling time */
 #define	AR5K_PHY_SETTLING_AGC_S		0
 #define	AR5K_PHY_SETTLING_SWITCH	0x00003f80	/* Switch settlig time */
-#define	AR5K_PHY_SETTLINK_SWITCH_S	7
+#define	AR5K_PHY_SETTLING_SWITCH_S	7
 
 /*
  * PHY Gain registers
@@ -2067,14 +2082,14 @@
  * PHY sleep registers [5112+]
  */
 #define AR5K_PHY_SCR			0x9870
-#define AR5K_PHY_SCR_32MHZ		0x0000001f
 
 #define AR5K_PHY_SLMT			0x9874
 #define AR5K_PHY_SLMT_32MHZ		0x0000007f
 
 #define AR5K_PHY_SCAL			0x9878
 #define AR5K_PHY_SCAL_32MHZ		0x0000000e
-
+#define	AR5K_PHY_SCAL_32MHZ_2417	0x0000000a
+#define	AR5K_PHY_SCAL_32MHZ_HB63	0x00000032
 
 /*
  * PHY PLL (Phase Locked Loop) control register
@@ -2101,34 +2116,10 @@
 /*
  * RF Buffer register
  *
- * There are some special control registers on the RF chip
- * that hold various operation settings related mostly to
- * the analog parts (channel, gain adjustment etc).
- *
- * We don't write on those registers directly but
- * we send a data packet on the buffer register and
- * then write on another special register to notify hw
- * to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
- * are applied faster on the hw.
- *
- * We sent such data packets during rf initialization and channel change
- * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
- *
- * The data packets we send during initializadion are inside ath5k_ini_rf
- * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
- * We use *rfregs functions to modify them  acording to current operation
- * mode and eeprom values and pass them all together to the chip.
- *
  * It's obvious from the code that 0x989c is the buffer register but
  * for the other special registers that we write to after sending each
  * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
  * for now. It's interesting that they are also used for some other operations.
- *
- * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers):
- *
- * http://www.google.com/patents?id=qNURAAAAEBAJ
  */
 
 #define AR5K_RF_BUFFER			0x989c
@@ -2178,7 +2169,8 @@
 #define	AR5K_PHY_ANT_CTL_TXRX_EN	0x00000001	/* Enable TX/RX (?) */
 #define	AR5K_PHY_ANT_CTL_SECTORED_ANT	0x00000004	/* Sectored Antenna */
 #define	AR5K_PHY_ANT_CTL_HITUNE5	0x00000008	/* Hitune5 (?) */
-#define	AR5K_PHY_ANT_CTL_SWTABLE_IDLE	0x00000010	/* Switch table idle (?) */
+#define	AR5K_PHY_ANT_CTL_SWTABLE_IDLE	0x000003f0	/* Switch table idle (?) */
+#define	AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S	4
 
 /*
  * PHY receiver delay register [5111+]
@@ -2218,7 +2210,7 @@
 #define	AR5K_PHY_OFDM_SELFCORR			0x9924			/* Register Address */
 #define	AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN	0x00000001	/* Enable cyclic RSSI thr 1 */
 #define	AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1	0x000000fe	/* Mask for Cyclic RSSI threshold 1 */
-#define	AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S	0
+#define	AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S	1
 #define	AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3	0x00000100	/* Cyclic RSSI threshold 3 (field) (?) */
 #define	AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN	0x00008000	/* Enable 1A RSSI threshold (?) */
 #define	AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR	0x00010000	/* 1A RSSI threshold (field) (?) */
@@ -2243,9 +2235,7 @@
 #define	AR5K_PHY_CTL_LOW_FREQ_SLE_EN	0x00000080	/* Enable low freq sleep */
 
 /*
- * PHY PAPD probe register [5111+ (?)]
- * Is this only present in 5212 ?
- * Because it's always 0 in 5211 initialization code
+ * PHY PAPD probe register [5111+]
  */
 #define	AR5K_PHY_PAPD_PROBE		0x9930
 #define	AR5K_PHY_PAPD_PROBE_SH_HI_PAR	0x00000001
@@ -2303,6 +2293,15 @@
 			AR5K_PHY_FRAME_CTL_TIMING_ERR
 
 /*
+ * PHY Tx Power adjustment register [5212A+]
+ */
+#define	AR5K_PHY_TX_PWR_ADJ			0x994c
+#define	AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA	0x00000fc0
+#define	AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S	6
+#define	AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX	0x00fc0000
+#define	AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S	18
+
+/*
  * PHY radar detection register [5111+]
  */
 #define	AR5K_PHY_RADAR			0x9954
@@ -2355,7 +2354,7 @@
 #define AR5K_PHY_SIGMA_DELTA_FILT2_S	3
 #define AR5K_PHY_SIGMA_DELTA_FILT1	0x00001f00
 #define AR5K_PHY_SIGMA_DELTA_FILT1_S	8
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP	0x01ff3000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP	0x01ffe000
 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S	13
 
 /*
@@ -2387,21 +2386,21 @@
 #define AR5K_PHY_BIN_MASK2_4_MASK_4	0x00003fff
 #define AR5K_PHY_BIN_MASK2_4_MASK_4_S	0
 
-#define AR_PHY_TIMING_9			0x9998
-#define AR_PHY_TIMING_10		0x999c
-#define AR_PHY_TIMING_10_PILOT_MASK_2	0x000fffff
-#define AR_PHY_TIMING_10_PILOT_MASK_2_S	0
+#define AR5K_PHY_TIMING_9			0x9998
+#define AR5K_PHY_TIMING_10			0x999c
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2		0x000fffff
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S	0
 
 /*
  * Spur mitigation control
  */
-#define AR_PHY_TIMING_11			0x99a0		/* Register address */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE	0x000fffff	/* Spur delta phase */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S	0
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD		0x3ff00000	/* Freq sigma delta */
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S	20
-#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC	0x40000000	/* Spur filter in AGC detector */
-#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR	0x80000000	/* Spur filter in OFDM self correlator */
+#define AR5K_PHY_TIMING_11			0x99a0		/* Register address */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE	0x000fffff	/* Spur delta phase */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S	0
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD		0x3ff00000	/* Freq sigma delta */
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S	20
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC	0x40000000	/* Spur filter in AGC detector */
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR	0x80000000	/* Spur filter in OFDM self correlator */
 
 /*
  * Gain tables
@@ -2483,17 +2482,7 @@
 #define AR5K_PHY_SDELAY			0x99f4
 #define AR5K_PHY_SDELAY_32MHZ		0x000000ff
 #define AR5K_PHY_SPENDING		0x99f8
-#define AR5K_PHY_SPENDING_14		0x00000014
-#define AR5K_PHY_SPENDING_18		0x00000018
-#define AR5K_PHY_SPENDING_RF5111	0x00000018
-#define AR5K_PHY_SPENDING_RF5112	0x00000014
-/* #define AR5K_PHY_SPENDING_RF5112A	0x0000000e */
-/* #define AR5K_PHY_SPENDING_RF5424	0x00000012 */
-#define AR5K_PHY_SPENDING_RF5413	0x00000018
-#define AR5K_PHY_SPENDING_RF2413	0x00000018
-#define AR5K_PHY_SPENDING_RF2316	0x00000018
-#define AR5K_PHY_SPENDING_RF2317	0x00000018
-#define AR5K_PHY_SPENDING_RF2425	0x00000014
+
 
 /*
  * PHY PAPD I (power?) table (?)
@@ -2505,11 +2494,7 @@
 /*
  * PHY PCDAC TX power table
  */
-#define	AR5K_PHY_PCDAC_TXPOWER_BASE_5211	0xa180
-#define AR5K_PHY_PCDAC_TXPOWER_BASE_2413	0xa280
-#define AR5K_PHY_PCDAC_TXPOWER_BASE	(ah->ah_radio >= AR5K_RF2413 ? \
-					AR5K_PHY_PCDAC_TXPOWER_BASE_2413 :\
-					AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
+#define	AR5K_PHY_PCDAC_TXPOWER_BASE	0xa180
 #define	AR5K_PHY_PCDAC_TXPOWER(_n)	(AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
 
 /*
@@ -2578,6 +2563,12 @@
 #define	AR5K_PHY_TPC_RG1		0xa258
 #define	AR5K_PHY_TPC_RG1_NUM_PD_GAIN	0x0000c000
 #define	AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S	14
+#define AR5K_PHY_TPC_RG1_PDGAIN_1	0x00030000
+#define AR5K_PHY_TPC_RG1_PDGAIN_1_S	16
+#define AR5K_PHY_TPC_RG1_PDGAIN_2	0x000c0000
+#define AR5K_PHY_TPC_RG1_PDGAIN_2_S	18
+#define AR5K_PHY_TPC_RG1_PDGAIN_3	0x00300000
+#define AR5K_PHY_TPC_RG1_PDGAIN_3_S	20
 
 #define	AR5K_PHY_TPC_RG5			0xa26C
 #define	AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP	0x0000000F
@@ -2590,3 +2581,9 @@
 #define	AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S	16
 #define	AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4	0x0FC00000
 #define	AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S	22
+
+/*
+ * PHY PDADC Tx power table
+ */
+#define AR5K_PHY_PDADC_TXPOWER_BASE	0xa280
+#define	AR5K_PHY_PDADC_TXPOWER(_n)	(AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/reset.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/reset.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/reset.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/reset.c	2009-06-09 23:05:27.000000000 -0400
@@ -25,7 +25,8 @@
   Reset functions and helpers
 \*****************************/
 
-#include <linux/pci.h>
+#include <linux/pci.h> 		/* To determine if a card is pci-e */
+#include <linux/log2.h>
 #include "ath5k.h"
 #include "reg.h"
 #include "base.h"
@@ -37,10 +38,14 @@
  * @ah: the &struct ath5k_hw
  * @channel: the currently set channel upon reset
  *
- * Write the OFDM timings for the AR5212 upon reset. This is a helper for
- * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
- * depending on the bandwidth of the channel.
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
  *
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
  */
 static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
 	struct ieee80211_channel *channel)
@@ -53,23 +58,34 @@ static inline int ath5k_hw_write_ofdm_ti
 		!(channel->hw_value & CHANNEL_OFDM))
 		BUG();
 
-	/* Seems there are two PLLs, one for baseband sampling and one
-	 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
-	 * turbo. */
-	clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
-	coef_scaled = ((5 * (clock << 24)) / 2) /
-	channel->center_freq;
+	/* Get coefficient
+	 * ALGO: coef = (5 * clock * carrier_freq) / 2)
+	 * we scale coef by shifting clock value by 24 for
+	 * better precision since we use integers */
+	/* TODO: Half/quarter rate */
+	clock =  ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
 
-	for (coef_exp = 31; coef_exp > 0; coef_exp--)
-		if ((coef_scaled >> coef_exp) & 0x1)
-			break;
+	coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
 
-	if (!coef_exp)
+	/* Get exponent
+	 * ALGO: coef_exp = 14 - highest set bit position */
+	coef_exp = ilog2(coef_scaled);
+
+	/* Doesn't make sense if it's zero*/
+	if (!coef_scaled || !coef_exp)
 		return -EINVAL;
 
+	/* Note: we've shifted coef_scaled by 24 */
 	coef_exp = 14 - (coef_exp - 24);
+
+
+	/* Get mantissa (significant digits)
+	 * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
 	coef_man = coef_scaled +
 		(1 << (24 - coef_exp - 1));
+
+	/* Calculate delta slope coefficient exponent
+	 * and mantissa (remove scaling) and set them on hw */
 	ds_coef_man = coef_man >> (24 - coef_exp);
 	ds_coef_exp = coef_exp - 16;
 
@@ -86,20 +102,27 @@ static inline int ath5k_hw_write_ofdm_ti
  * index into rates for control rates, we can set it up like this because
  * this is only used for AR5212 and we know it supports G mode
  */
-static int control_rates[] =
+static const unsigned int control_rates[] =
 	{ 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
 
 /**
- * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
  *
  * @ah: the &struct ath5k_hw
  * @mode: one of enum ath5k_driver_mode
  *
- * Write the rate duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
- * the hardware for the current mode for each rate. The rates which are capable
- * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
- * register for the short preamble ACK timeout calculation.
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preample
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
+ * quarter rate mode, we need to use another set of bitrates (that's why we
+ * need the mode parameter) but we don't handle these proprietary modes yet.
  */
 static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
        unsigned int mode)
@@ -275,7 +298,8 @@ commit:
 }
 
 /*
- * Bring up MAC + PHY Chips
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
  */
 int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 {
@@ -333,7 +357,11 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw
 			}
 		} else if (flags & CHANNEL_5GHZ) {
 			mode |= AR5K_PHY_MODE_FREQ_5GHZ;
-			clock |= AR5K_PHY_PLL_40MHZ;
+
+			if (ah->ah_radio == AR5K_RF5413)
+				clock = AR5K_PHY_PLL_40MHZ_5413;
+			else
+				clock |= AR5K_PHY_PLL_40MHZ;
 
 			if (flags & CHANNEL_OFDM)
 				mode |= AR5K_PHY_MODE_MOD_OFDM;
@@ -391,10 +419,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw
 	}
 
 	if (ah->ah_version != AR5K_AR5210) {
-		/* ...set the PHY operating mode */
-		ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
-		udelay(300);
 
+		/* ...update PLL if needed */
+		if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
+			ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+			udelay(300);
+		}
+
+		/* ...set the PHY operating mode */
 		ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
 		ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
 	}
@@ -403,22 +435,399 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw
 }
 
 /*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ * 	123 - 127) require delay on access.
+ */
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	u32 scal, spending, usec32;
+
+	/* Only set 32KHz settings if we have an external
+	 * 32KHz crystal present */
+	if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+	AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+	enable) {
+
+		/* 1 usec/cycle */
+		AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+		/* Set up tsf increment on each cycle */
+		AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
+
+		/* Set baseband sleep control registers
+		 * and sleep control rate */
+		ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+		if ((ah->ah_radio == AR5K_RF5112) ||
+		(ah->ah_radio == AR5K_RF5413) ||
+		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+			spending = 0x14;
+		else
+			spending = 0x18;
+		ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+		if ((ah->ah_radio == AR5K_RF5112) ||
+		(ah->ah_radio == AR5K_RF5413) ||
+		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+			ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+			ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+			ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+			ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+			AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+		} else {
+			ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+			ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+			ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+			ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+			AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+		}
+
+		/* Enable sleep clock operation */
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+				AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+	} else {
+
+		/* Disable sleep clock operation and
+		 * restore default parameters */
+		AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+				AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+		AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+				AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+		ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+		ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+		if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+			scal = AR5K_PHY_SCAL_32MHZ_2417;
+		else if (ath5k_eeprom_is_hb63(ah))
+			scal = AR5K_PHY_SCAL_32MHZ_HB63;
+		else
+			scal = AR5K_PHY_SCAL_32MHZ;
+		ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+		ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+		ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+		if ((ah->ah_radio == AR5K_RF5112) ||
+		(ah->ah_radio == AR5K_RF5413) ||
+		(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+			spending = 0x14;
+		else
+			spending = 0x18;
+		ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+		if ((ah->ah_radio == AR5K_RF5112) ||
+		(ah->ah_radio == AR5K_RF5413))
+			usec32 = 39;
+		else
+			usec32 = 31;
+		AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
+
+		AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+	}
+	return;
+}
+
+static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+				struct ieee80211_channel *channel)
+{
+	u8 refclk_freq;
+
+	if ((ah->ah_radio == AR5K_RF5112) ||
+	(ah->ah_radio == AR5K_RF5413) ||
+	(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+		refclk_freq = 40;
+	else
+		refclk_freq = 32;
+
+	if ((channel->center_freq % refclk_freq != 0) &&
+	((channel->center_freq % refclk_freq < 10) ||
+	(channel->center_freq % refclk_freq > 22)))
+		return true;
+	else
+		return false;
+}
+
+/* TODO: Half/Quarter rate */
+static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
+				struct ieee80211_channel *channel)
+{
+	if (ah->ah_version == AR5K_AR5212 &&
+	    ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+
+		/* Setup ADC control */
+		ath5k_hw_reg_write(ah,
+				(AR5K_REG_SM(2,
+				AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
+				AR5K_REG_SM(2,
+				AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
+				AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
+				AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
+				AR5K_PHY_ADC_CTL);
+
+
+
+		/* Disable barker RSSI threshold */
+		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+				AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
+
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+			AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
+
+		/* Set the mute mask */
+		ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
+	}
+
+	/* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
+	if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
+		ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
+
+	/* Enable DCU double buffering */
+	if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
+		AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+				AR5K_TXCFG_DCU_DBL_BUF_DIS);
+
+	/* Set DAC/ADC delays */
+	if (ah->ah_version == AR5K_AR5212) {
+		u32 scal;
+		if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+			scal = AR5K_PHY_SCAL_32MHZ_2417;
+		else if (ath5k_eeprom_is_hb63(ah))
+			scal = AR5K_PHY_SCAL_32MHZ_HB63;
+		else
+			scal = AR5K_PHY_SCAL_32MHZ;
+		ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+	}
+
+	/* Set fast ADC */
+	if ((ah->ah_radio == AR5K_RF5413) ||
+	(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+		u32 fast_adc = true;
+
+		if (channel->center_freq == 2462 ||
+		channel->center_freq == 2467)
+			fast_adc = 0;
+
+		/* Only update if needed */
+		if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
+				ath5k_hw_reg_write(ah, fast_adc,
+						AR5K_PHY_FAST_ADC);
+	}
+
+	/* Fix for first revision of the RF5112 RF chipset */
+	if (ah->ah_radio == AR5K_RF5112 &&
+			ah->ah_radio_5ghz_revision <
+			AR5K_SREV_RAD_5112A) {
+		u32 data;
+		ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+				AR5K_PHY_CCKTXCTL);
+		if (channel->hw_value & CHANNEL_5GHZ)
+			data = 0xffb81020;
+		else
+			data = 0xffb80d20;
+		ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+	}
+
+	if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+		u32 usec_reg;
+		/* 5311 has different tx/rx latency masks
+		 * from 5211, since we deal 5311 the same
+		 * as 5211 when setting initvals, shift
+		 * values here to their proper locations */
+		usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+		ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
+				AR5K_USEC_32 |
+				AR5K_USEC_TX_LATENCY_5211 |
+				AR5K_REG_SM(29,
+				AR5K_USEC_RX_LATENCY_5210)),
+				AR5K_USEC_5211);
+		/* Clear QCU/DCU clock gating register */
+		ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
+		/* Set DAC/ADC delays */
+		ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+		/* Enable PCU FIFO corruption ECO */
+		AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+					AR5K_DIAG_SW_ECO_ENABLE);
+	}
+}
+
+static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
+		struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	s16 cck_ofdm_pwr_delta;
+
+	/* Adjust power delta for channel 14 */
+	if (channel->center_freq == 2484)
+		cck_ofdm_pwr_delta =
+			((ee->ee_cck_ofdm_power_delta -
+			ee->ee_scaled_cck_delta) * 2) / 10;
+	else
+		cck_ofdm_pwr_delta =
+			(ee->ee_cck_ofdm_power_delta * 2) / 10;
+
+	/* Set CCK to OFDM power delta on tx power
+	 * adjustment register */
+	if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+		if (channel->hw_value == CHANNEL_G)
+			ath5k_hw_reg_write(ah,
+			AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
+				AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
+			AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
+				AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
+				AR5K_PHY_TX_PWR_ADJ);
+		else
+			ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
+	} else {
+		/* For older revs we scale power on sw during tx power
+		 * setup */
+		ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
+		ah->ah_txpower.txp_cck_ofdm_gainf_delta =
+						ee->ee_cck_ofdm_gain_delta;
+	}
+
+	/* Set antenna idle switch table */
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
+			AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
+			(ah->ah_antenna[ee_mode][0] |
+			AR5K_PHY_ANT_CTL_TXRX_EN));
+
+	/* Set antenna switch table */
+	ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+		AR5K_PHY_ANT_SWITCH_TABLE_0);
+	ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+		AR5K_PHY_ANT_SWITCH_TABLE_1);
+
+	/* Noise floor threshold */
+	ath5k_hw_reg_write(ah,
+		AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+		AR5K_PHY_NFTHRES);
+
+	if ((channel->hw_value & CHANNEL_TURBO) &&
+	(ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
+		/* Switch settling time (Turbo) */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+				AR5K_PHY_SETTLING_SWITCH,
+				ee->ee_switch_settling_turbo[ee_mode]);
+
+		/* Tx/Rx attenuation (Turbo) */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+				AR5K_PHY_GAIN_TXRX_ATTEN,
+				ee->ee_atn_tx_rx_turbo[ee_mode]);
+
+		/* ADC/PGA desired size (Turbo) */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+				AR5K_PHY_DESIRED_SIZE_ADC,
+				ee->ee_adc_desired_size_turbo[ee_mode]);
+
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+				AR5K_PHY_DESIRED_SIZE_PGA,
+				ee->ee_pga_desired_size_turbo[ee_mode]);
+
+		/* Tx/Rx margin (Turbo) */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+				AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+				ee->ee_margin_tx_rx_turbo[ee_mode]);
+
+	} else {
+		/* Switch settling time */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+				AR5K_PHY_SETTLING_SWITCH,
+				ee->ee_switch_settling[ee_mode]);
+
+		/* Tx/Rx attenuation */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+				AR5K_PHY_GAIN_TXRX_ATTEN,
+				ee->ee_atn_tx_rx[ee_mode]);
+
+		/* ADC/PGA desired size */
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+				AR5K_PHY_DESIRED_SIZE_ADC,
+				ee->ee_adc_desired_size[ee_mode]);
+
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+				AR5K_PHY_DESIRED_SIZE_PGA,
+				ee->ee_pga_desired_size[ee_mode]);
+
+		/* Tx/Rx margin */
+		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+				AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+				ee->ee_margin_tx_rx[ee_mode]);
+	}
+
+	/* XPA delays */
+	ath5k_hw_reg_write(ah,
+		(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+		(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+		(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+		(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
+
+	/* XLNA delay */
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
+			AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
+			ee->ee_tx_end2xlna_enable[ee_mode]);
+
+	/* Thresh64 (ANI) */
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
+			AR5K_PHY_NF_THRESH62,
+			ee->ee_thr_62[ee_mode]);
+
+
+	/* False detect backoff for channels
+	 * that have spur noise. Write the new
+	 * cyclic power RSSI threshold. */
+	if (ath5k_hw_chan_has_spur_noise(ah, channel))
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+				AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+				AR5K_INIT_CYCRSSI_THR1 +
+				ee->ee_false_detect[ee_mode]);
+	else
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+				AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+				AR5K_INIT_CYCRSSI_THR1);
+
+	/* I/Q correction
+	 * TODO: Per channel i/q infos ? */
+	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+		AR5K_PHY_IQ_CORR_ENABLE |
+		(ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
+		ee->ee_q_cal[ee_mode]);
+
+	/* Heavy clipping -disable for now */
+	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
+		ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
+
+	return;
+}
+
+/*
  * Main reset function
  */
 int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	struct ieee80211_channel *channel, bool change_channel)
 {
-	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	struct pci_dev *pdev = ah->ah_sc->pdev;
-	u32 data, s_seq, s_ant, s_led[3], dma_size;
-	unsigned int i, mode, freq, ee_mode, ant[2];
-	int ret;
+	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];
+	int i, ret;
 
 	ATH5K_TRACE(ah->ah_sc);
 
-	s_seq = 0;
 	s_ant = 0;
 	ee_mode = 0;
+	staid1_flags = 0;
+	tsf_up = 0;
+	tsf_lo = 0;
 	freq = 0;
 	mode = 0;
 
@@ -427,48 +836,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	 */
 	/*DCU/Antenna selection not available on 5210*/
 	if (ah->ah_version != AR5K_AR5210) {
-		if (change_channel) {
-			/* Seq number for queue 0 -do this for all queues ? */
-			s_seq = ath5k_hw_reg_read(ah,
-					AR5K_QUEUE_DFS_SEQNUM(0));
-			/*Default antenna*/
-			s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
-		}
-	}
-
-	/*GPIOs*/
-	s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
-	s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
-	s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-	if (change_channel && ah->ah_rf_banks != NULL)
-		ath5k_hw_get_rf_gain(ah);
-
-
-	/*Wakeup the device*/
-	ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
-	if (ret)
-		return ret;
-
-	/*
-	 * Initialize operating mode
-	 */
-	ah->ah_op_mode = op_mode;
-
-	/*
-	 * 5111/5112 Settings
-	 * 5210 only comes with RF5110
-	 */
-	if (ah->ah_version != AR5K_AR5210) {
-		if (ah->ah_radio != AR5K_RF5111 &&
-			ah->ah_radio != AR5K_RF5112 &&
-			ah->ah_radio != AR5K_RF5413 &&
-			ah->ah_radio != AR5K_RF2413 &&
-			ah->ah_radio != AR5K_RF2425) {
-			ATH5K_ERR(ah->ah_sc,
-				"invalid phy radio: %u\n", ah->ah_radio);
-			return -EINVAL;
-		}
 
 		switch (channel->hw_value & CHANNEL_MODES) {
 		case CHANNEL_A:
@@ -491,8 +858,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			freq = AR5K_INI_RFGAIN_5GHZ;
 			ee_mode = AR5K_EEPROM_MODE_11A;
 			break;
-		/*Is this ok on 5211 too ?*/
 		case CHANNEL_TG:
+			if (ah->ah_version == AR5K_AR5211) {
+				ATH5K_ERR(ah->ah_sc,
+					"TurboG mode not available on 5211");
+				return -EINVAL;
+			}
 			mode = AR5K_MODE_11G_TURBO;
 			freq = AR5K_INI_RFGAIN_2GHZ;
 			ee_mode = AR5K_EEPROM_MODE_11G;
@@ -513,11 +884,93 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			return -EINVAL;
 		}
 
-		/* PHY access enable */
-		ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+		if (change_channel) {
+			/*
+			 * Save frame sequence count
+			 * For revs. after Oahu, only save
+			 * seq num for DCU 0 (Global seq num)
+			 */
+			if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+				for (i = 0; i < 10; i++)
+					s_seq[i] = ath5k_hw_reg_read(ah,
+						AR5K_QUEUE_DCU_SEQNUM(i));
+
+			} else {
+				s_seq[0] = ath5k_hw_reg_read(ah,
+						AR5K_QUEUE_DCU_SEQNUM(0));
+			}
+
+			/* TSF accelerates on AR5211 durring reset
+			 * As a workaround save it here and restore
+			 * it later so that it's back in time after
+			 * reset. This way it'll get re-synced on the
+			 * next beacon without breaking ad-hoc.
+			 *
+			 * On AR5212 TSF is almost preserved across a
+			 * reset so it stays back in time anyway and
+			 * we don't have to save/restore it.
+			 *
+			 * XXX: Since this breaks power saving we have
+			 * to disable power saving until we receive the
+			 * next beacon, so we can resync beacon timers */
+			if (ah->ah_version == AR5K_AR5211) {
+				tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+				tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+			}
+		}
+
+		/* Save default antenna */
+		s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
 
+		if (ah->ah_version == AR5K_AR5212) {
+			/* Restore normal 32/40MHz clock operation
+			 * to avoid register access delay on certain
+			 * PHY registers */
+			ath5k_hw_set_sleep_clock(ah, false);
+
+			/* Since we are going to write rf buffer
+			 * check if we have any pending gain_F
+			 * optimization settings */
+			if (change_channel && ah->ah_rf_banks != NULL)
+				ath5k_hw_gainf_calibrate(ah);
+		}
 	}
 
+	/*GPIOs*/
+	s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+					AR5K_PCICFG_LEDSTATE;
+	s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
+	s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+	/* AR5K_STA_ID1 flags, only preserve antenna
+	 * settings and ack/cts rate mode */
+	staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
+			(AR5K_STA_ID1_DEFAULT_ANTENNA |
+			AR5K_STA_ID1_DESC_ANTENNA |
+			AR5K_STA_ID1_RTS_DEF_ANTENNA |
+			AR5K_STA_ID1_ACKCTS_6MB |
+			AR5K_STA_ID1_BASE_RATE_11B |
+			AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+	/* Wakeup the device */
+	ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+	if (ret)
+		return ret;
+
+	/*
+	 * Initialize operating mode
+	 */
+	ah->ah_op_mode = op_mode;
+
+	/* PHY access enable */
+	if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
+		ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+	else
+		ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
+							AR5K_PHY(0));
+
+	/* Write initial settings */
 	ret = ath5k_hw_write_initvals(ah, mode, change_channel);
 	if (ret)
 		return ret;
@@ -526,69 +979,29 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	 * 5211/5212 Specific
 	 */
 	if (ah->ah_version != AR5K_AR5210) {
+
 		/*
 		 * Write initial RF gain settings
 		 * This should work for both 5111/5112
 		 */
-		ret = ath5k_hw_rfgain(ah, freq);
+		ret = ath5k_hw_rfgain_init(ah, freq);
 		if (ret)
 			return ret;
 
 		mdelay(1);
 
 		/*
-		 * Write some more initial register settings for revised chips
+		 * Tweak initval settings for revised
+		 * chipsets and add some more config
+		 * bits
 		 */
-		if (ah->ah_version == AR5K_AR5212 &&
-		    ah->ah_phy_revision > 0x41) {
-			ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
-
-			if (channel->hw_value == CHANNEL_G)
-				if (ah->ah_mac_srev < AR5K_SREV_AR2413)
-					ath5k_hw_reg_write(ah, 0x00f80d80,
-								0x994c);
-				else if (ah->ah_mac_srev < AR5K_SREV_AR5424)
-					ath5k_hw_reg_write(ah, 0x00380140,
-								0x994c);
-				else if (ah->ah_mac_srev < AR5K_SREV_AR2425)
-					ath5k_hw_reg_write(ah, 0x00fc0ec0,
-								0x994c);
-				else /* 2425 */
-					ath5k_hw_reg_write(ah, 0x00fc0fc0,
-								0x994c);
-			else
-				ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
-
-			/* Got this from legacy-hal */
-			AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
-
-			AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff);
-
-			/* Just write 0x9b5 ? */
-			/* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
-			ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
-			ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
-			ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
-		}
-
-		/* Fix for first revision of the RF5112 RF chipset */
-		if (ah->ah_radio >= AR5K_RF5112 &&
-				ah->ah_radio_5ghz_revision <
-				AR5K_SREV_RAD_5112A) {
-			ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
-					AR5K_PHY_CCKTXCTL);
-			if (channel->hw_value & CHANNEL_5GHZ)
-				data = 0xffb81020;
-			else
-				data = 0xffb80d20;
-			ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
-			data = 0;
-		}
+		ath5k_hw_tweak_initval_settings(ah, channel);
 
 		/*
 		 * Set TX power (FIXME)
 		 */
-		ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
+		ret = ath5k_hw_txpower(ah, channel, ee_mode,
+					AR5K_TUNE_DEFAULT_TXPOWER);
 		if (ret)
 			return ret;
 
@@ -601,15 +1014,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			ath5k_hw_write_rate_duration(ah, mode);
 
 		/*
-		 * Write RF registers
+		 * Write RF buffer
 		 */
-		ret = ath5k_hw_rfregs(ah, channel, mode);
+		ret = ath5k_hw_rfregs_init(ah, channel, mode);
 		if (ret)
 			return ret;
 
-		/*
-		 * Configure additional registers
-		 */
 
 		/* Write OFDM timings on 5212*/
 		if (ah->ah_version == AR5K_AR5212 &&
@@ -631,17 +1041,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 		}
 
 		/*
-		 * Set channel and calibrate the PHY
-		 */
-		ret = ath5k_hw_channel(ah, channel);
-		if (ret)
-			return ret;
-
-		/* Set antenna mode */
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
-			ah->ah_antenna[ee_mode][0], 0xfffffc06);
-
-		/*
 		 * In case a fixed antenna was set as default
 		 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
 		 * registers.
@@ -656,54 +1055,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			ant[1] = AR5K_ANT_FIXED_B;
 		}
 
-		ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
-			AR5K_PHY_ANT_SWITCH_TABLE_0);
-		ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
-			AR5K_PHY_ANT_SWITCH_TABLE_1);
-
 		/* Commit values from EEPROM */
-		if (ah->ah_radio == AR5K_RF5111)
-			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
-			    AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
-
-		ath5k_hw_reg_write(ah,
-			AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
-			AR5K_PHY_NFTHRES);
-
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
-			(ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
-			0xffffc07f);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
-			(ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000,
-			0xfffc0fff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-			(ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
-			((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
-			0xffff0000);
-
-		ath5k_hw_reg_write(ah,
-			(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
-			(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
-			(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
-			(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
-
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
-			ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
-			(ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
-
-		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-		    AR5K_PHY_IQ_CORR_ENABLE |
-		    (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
-		    ee->ee_q_cal[ee_mode]);
-
-		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-			AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
-				AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
-				ee->ee_margin_tx_rx[ee_mode]);
+		ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
 
 	} else {
+		/*
+		 * For 5210 we do all initialization using
+		 * initvals, so we don't have to modify
+		 * any settings (5210 also only supports
+		 * a/aturbo modes)
+		 */
 		mdelay(1);
 		/* Disable phy and wait */
 		ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
@@ -713,100 +1074,154 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	/*
 	 * Restore saved values
 	 */
+
 	/*DCU/Antenna selection not available on 5210*/
 	if (ah->ah_version != AR5K_AR5210) {
-		ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
+
+		if (change_channel) {
+			if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+				for (i = 0; i < 10; i++)
+					ath5k_hw_reg_write(ah, s_seq[i],
+						AR5K_QUEUE_DCU_SEQNUM(i));
+			} else {
+				ath5k_hw_reg_write(ah, s_seq[0],
+					AR5K_QUEUE_DCU_SEQNUM(0));
+			}
+
+
+			if (ah->ah_version == AR5K_AR5211) {
+				ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+				ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
+			}
+		}
+
 		ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
 	}
+
+	/* Ledstate */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+
+	/* Gpio settings */
 	ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
 	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);
+
+
 	/*
-	 * Misc
+	 * Configure PCU
 	 */
+
+	/* Restore bssid and bssid mask */
 	/* XXX: add ah->aid once mac80211 gives this to us */
 	ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
 
+	/* Set PCU config */
 	ath5k_hw_set_opmode(ah);
-	/*PISR/SISR Not available on 5210*/
-	if (ah->ah_version != AR5K_AR5210) {
+
+	/* Clear any pending interrupts
+	 * PISR/SISR Not available on 5210 */
+	if (ah->ah_version != AR5K_AR5210)
 		ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
-		/* If we later allow tuning for this, store into sc structure */
-		data = AR5K_TUNE_RSSI_THRES |
-			AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
-		ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
+
+	/* Set RSSI/BRSSI thresholds
+	 *
+	 * Note: If we decide to set this value
+	 * dynamicaly, have in mind that when AR5K_RSSI_THR
+	 * register is read it might return 0x40 if we haven't
+	 * wrote anything to it plus BMISS RSSI threshold is zeroed.
+	 * So doing a save/restore procedure here isn't the right
+	 * choice. Instead store it on ath5k_hw */
+	ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+				AR5K_TUNE_BMISS_THRES <<
+				AR5K_RSSI_THR_BMISS_S),
+				AR5K_RSSI_THR);
+
+	/* MIC QoS support */
+	if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+		ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+		ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
 	}
 
+	/* QoS NOACK Policy */
+	if (ah->ah_version == AR5K_AR5212) {
+		ath5k_hw_reg_write(ah,
+			AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+			AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
+			AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+			AR5K_QOS_NOACK);
+	}
+
+
 	/*
-	 * Set Rx/Tx DMA Configuration
-	 *
-	 * Set maximum DMA size (512) except for PCI-E cards since
-	 * it causes rx overruns and tx errors (tested on 5424 but since
-	 * rx overruns also occur on 5416/5418 with madwifi we set 128
-	 * for all PCI-E cards to be safe).
-	 *
-	 * In dumps this is 128 for allchips.
-	 *
-	 * XXX: need to check 5210 for this
-	 * TODO: Check out tx triger level, it's always 64 on dumps but I
-	 * guess we can tweak it and see how it goes ;-)
+	 * Configure PHY
 	 */
-	dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
-	if (ah->ah_version != AR5K_AR5210) {
-		AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-			AR5K_TXCFG_SDMAMR, dma_size);
-		AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
-			AR5K_RXCFG_SDMAMW, dma_size);
-	}
+
+	/* Set channel on PHY */
+	ret = ath5k_hw_channel(ah, channel);
+	if (ret)
+		return ret;
 
 	/*
 	 * Enable the PHY and wait until completion
+	 * This includes BaseBand and Synthesizer
+	 * activation.
 	 */
 	ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
 
 	/*
 	 * On 5211+ read activation -> rx delay
 	 * and use it.
+	 *
+	 * TODO: Half/quarter rate support
 	 */
 	if (ah->ah_version != AR5K_AR5210) {
-		data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+		u32 delay;
+		delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
 			AR5K_PHY_RX_DELAY_M;
-		data = (channel->hw_value & CHANNEL_CCK) ?
-			((data << 2) / 22) : (data / 10);
+		delay = (channel->hw_value & CHANNEL_CCK) ?
+			((delay << 2) / 22) : (delay / 10);
 
-		udelay(100 + (2 * data));
-		data = 0;
+		udelay(100 + (2 * delay));
 	} else {
 		mdelay(1);
 	}
 
 	/*
-	 * Perform ADC test (?)
+	 * Perform ADC test to see if baseband is ready
+	 * Set tx hold and check adc test register
 	 */
-	data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+	phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
 	ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
 	for (i = 0; i <= 20; i++) {
 		if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
 			break;
 		udelay(200);
 	}
-	ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
-	data = 0;
+	ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
 
 	/*
-	 * Start automatic gain calibration
+	 * Start automatic gain control calibration
 	 *
 	 * During AGC calibration RX path is re-routed to
-	 * a signal detector so we don't receive anything.
+	 * a power detector so we don't receive anything.
 	 *
 	 * This method is used to calibrate some static offsets
 	 * used together with on-the fly I/Q calibration (the
 	 * one performed via ath5k_hw_phy_calibrate), that doesn't
 	 * interrupt rx path.
 	 *
+	 * While rx path is re-routed to the power detector we also
+	 * start a noise floor calibration, to measure the
+	 * card's noise floor (the noise we measure when we are not
+	 * transmiting or receiving anything).
+	 *
 	 * If we are in a noisy environment AGC calibration may time
-	 * out.
+	 * out and/or noise floor calibration might timeout.
 	 */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
 				AR5K_PHY_AGCCTL_CAL);
@@ -828,30 +1243,37 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 			AR5K_PHY_AGCCTL_CAL, 0, false)) {
 		ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
 			channel->center_freq);
-		return -EAGAIN;
 	}
 
 	/*
-	 * Start noise floor calibration
-	 *
 	 * 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. I believe that's wrong because
-	 * during NF calibration, rx path is also routed to a detector, so if
-	 * it doesn't finish we won't have RX.
-	 *
-	 * XXX: Find an interval that's OK for all cards...
+	 * 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);
 
+
+	/*
+	 * Configure QCUs/DCUs
+	 */
+
+	/* TODO: HW Compression support for data queues */
+	/* TODO: Burst prefetch for data queues */
+
 	/*
 	 * Reset queues and start beacon timers at the end of the reset routine
+	 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+	 * Note: If we want we can assign multiple qcus on one dcu.
 	 */
 	for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
-		/*No QCU on 5210*/
-		if (ah->ah_version != AR5K_AR5210)
-			AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
-
 		ret = ath5k_hw_reset_tx_queue(ah, i);
 		if (ret) {
 			ATH5K_ERR(ah->ah_sc,
@@ -860,14 +1282,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 		}
 	}
 
+
+	/*
+	 * Configure DMA/Interrupts
+	 */
+
+	/*
+	 * Set Rx/Tx DMA Configuration
+	 *
+	 * Set standard DMA size (128). Note that
+	 * a DMA size of 512 causes rx overruns and tx errors
+	 * on pci-e cards (tested on 5424 but since rx overruns
+	 * also occur on 5416/5418 with madwifi we set 128
+	 * for all PCI-E cards to be safe).
+	 *
+	 * XXX: need to check 5210 for this
+	 * TODO: Check out tx triger level, it's always 64 on dumps but I
+	 * guess we can tweak it and see how it goes ;-)
+	 */
+	if (ah->ah_version != AR5K_AR5210) {
+		AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+			AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+		AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+			AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+	}
+
 	/* Pre-enable interrupts on 5211/5212*/
 	if (ah->ah_version != AR5K_AR5210)
 		ath5k_hw_set_imr(ah, ah->ah_imr);
 
 	/*
-	 * Set RF kill flags if supported by the device (read from the EEPROM)
-	 * Disable gpio_intr for now since it results system hang.
-	 * TODO: Handle this in ath5k_intr
+	 * Setup RFKill interrupt if rfkill flag is set on eeprom.
+	 * TODO: Use gpio pin and polarity infos from eeprom
+	 * TODO: Handle this in ath5k_intr because it'll result
+	 * 	 a nasty interrupt storm.
 	 */
 #if 0
 	if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
@@ -880,33 +1328,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
 	}
 #endif
 
-	/*
-	 * Set the 32MHz reference clock on 5212 phy clock sleep register
-	 *
-	 * TODO: Find out how to switch to external 32Khz clock to save power
-	 */
-	if (ah->ah_version == AR5K_AR5212) {
-		ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
-		ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
-		ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
-		ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
-		ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
-		ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
-
-		data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
-		data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
-						0x00000f80 : 0x00001380 ;
-		ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
-		data = 0;
-	}
-
-	if (ah->ah_version == AR5K_AR5212) {
-		ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
-		ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
-		ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
-		if (ah->ah_mac_srev >= AR5K_SREV_AR2413)
-			ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
-	}
+	/* Enable 32KHz clock function for AR5212+ chips
+	 * Set clocks to 32KHz operation and use an
+	 * external 32KHz crystal when sleeping if one
+	 * exists */
+	if (ah->ah_version == AR5K_AR5212)
+			ath5k_hw_set_sleep_clock(ah, true);
 
 	/*
 	 * Disable beacons and reset the register
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/rfbuffer.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/rfbuffer.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/rfbuffer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/rfbuffer.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1181 @@
+/*
+ * RF Buffer handling functions
+ *
+ * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+
+/*
+ * There are some special registers on the RF chip
+ * that control various operation settings related mostly to
+ * the analog parts (channel, gain adjustment etc).
+ *
+ * We don't write on those registers directly but
+ * we send a data packet on the chip, using a special register,
+ * that holds all the settings we need. After we 've sent the
+ * data packet, we write on another special register to notify hw
+ * to apply the settings. This is done so that control registers
+ * can be dynamicaly programmed during operation and the settings
+ * are applied faster on the hw.
+ *
+ * We call each data packet an "RF Bank" and all the data we write
+ * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
+ * data for the different RF chips, and various info to match RF
+ * Buffer offsets with specific RF registers so that we can access
+ * them. We tweak these settings on rfregs_init function.
+ *
+ * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+
+/*
+ * Struct to hold default mode specific RF
+ * register values (RF Banks)
+ */
+struct ath5k_ini_rfbuffer {
+	u8	rfb_bank;		/* RF Bank number */
+	u16	rfb_ctrl_register;	/* RF Buffer control register */
+	u32	rfb_mode_data[5];	/* RF Buffer data for each mode */
+};
+
+/*
+ * Struct to hold RF Buffer field
+ * infos used to access certain RF
+ * analog registers
+ */
+struct ath5k_rfb_field {
+	u8	len;	/* Field length */
+	u16	pos;	/* Offset on the raw packet */
+	u8	col;	/* Column -used for shifting */
+};
+
+/*
+ * RF analog register definition
+ */
+struct ath5k_rf_reg {
+	u8			bank;	/* RF Buffer Bank number */
+	u8			index;	/* Register's index on rf_regs_idx */
+	struct ath5k_rfb_field	field;	/* RF Buffer field for this register */
+};
+
+/* Map RF registers to indexes
+ * We do this to handle common bits and make our
+ * life easier by using an index for each register
+ * instead of a full rfb_field */
+enum ath5k_rf_regs_idx {
+	/* BANK 6 */
+	AR5K_RF_OB_2GHZ = 0,
+	AR5K_RF_OB_5GHZ,
+	AR5K_RF_DB_2GHZ,
+	AR5K_RF_DB_5GHZ,
+	AR5K_RF_FIXED_BIAS_A,
+	AR5K_RF_FIXED_BIAS_B,
+	AR5K_RF_PWD_XPD,
+	AR5K_RF_XPD_SEL,
+	AR5K_RF_XPD_GAIN,
+	AR5K_RF_PD_GAIN_LO,
+	AR5K_RF_PD_GAIN_HI,
+	AR5K_RF_HIGH_VC_CP,
+	AR5K_RF_MID_VC_CP,
+	AR5K_RF_LOW_VC_CP,
+	AR5K_RF_PUSH_UP,
+	AR5K_RF_PAD2GND,
+	AR5K_RF_XB2_LVL,
+	AR5K_RF_XB5_LVL,
+	AR5K_RF_PWD_ICLOBUF_2G,
+	AR5K_RF_PWD_84,
+	AR5K_RF_PWD_90,
+	AR5K_RF_PWD_130,
+	AR5K_RF_PWD_131,
+	AR5K_RF_PWD_132,
+	AR5K_RF_PWD_136,
+	AR5K_RF_PWD_137,
+	AR5K_RF_PWD_138,
+	AR5K_RF_PWD_166,
+	AR5K_RF_PWD_167,
+	AR5K_RF_DERBY_CHAN_SEL_MODE,
+	/* BANK 7 */
+	AR5K_RF_GAIN_I,
+	AR5K_RF_PLO_SEL,
+	AR5K_RF_RFGAIN_SEL,
+	AR5K_RF_RFGAIN_STEP,
+	AR5K_RF_WAIT_S,
+	AR5K_RF_WAIT_I,
+	AR5K_RF_MAX_TIME,
+	AR5K_RF_MIXVGA_OVR,
+	AR5K_RF_MIXGAIN_OVR,
+	AR5K_RF_MIXGAIN_STEP,
+	AR5K_RF_PD_DELAY_A,
+	AR5K_RF_PD_DELAY_B,
+	AR5K_RF_PD_DELAY_XR,
+	AR5K_RF_PD_PERIOD_A,
+	AR5K_RF_PD_PERIOD_B,
+	AR5K_RF_PD_PERIOD_XR,
+};
+
+
+/*******************\
+* RF5111 (Sombrero) *
+\*******************/
+
+/* BANK 6				len  pos col */
+#define	AR5K_RF5111_OB_2GHZ		{ 3, 119, 0 }
+#define	AR5K_RF5111_DB_2GHZ		{ 3, 122, 0 }
+
+#define	AR5K_RF5111_OB_5GHZ		{ 3, 104, 0 }
+#define	AR5K_RF5111_DB_5GHZ		{ 3, 107, 0 }
+
+#define	AR5K_RF5111_PWD_XPD		{ 1, 95,  0 }
+#define	AR5K_RF5111_XPD_GAIN		{ 4, 96,  0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5111_PWD(_n)		{ 1, (135 - _n), 3 }
+
+/* BANK 7				len  pos col */
+#define	AR5K_RF5111_GAIN_I		{ 6, 29,  0 }
+#define	AR5K_RF5111_PLO_SEL		{ 1, 4,   0 }
+#define	AR5K_RF5111_RFGAIN_SEL		{ 1, 36,  0 }
+#define AR5K_RF5111_RFGAIN_STEP		{ 6, 37,  0 }
+/* Only on AR5212 BaseBand and up */
+#define	AR5K_RF5111_WAIT_S		{ 5, 19,  0 }
+#define	AR5K_RF5111_WAIT_I		{ 5, 24,  0 }
+#define	AR5K_RF5111_MAX_TIME		{ 2, 49,  0 }
+
+static const struct ath5k_rf_reg rf_regs_5111[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF5111_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF5111_DB_2GHZ},
+	{6, AR5K_RF_OB_5GHZ,		AR5K_RF5111_OB_5GHZ},
+	{6, AR5K_RF_DB_5GHZ,		AR5K_RF5111_DB_5GHZ},
+	{6, AR5K_RF_PWD_XPD,		AR5K_RF5111_PWD_XPD},
+	{6, AR5K_RF_XPD_GAIN,		AR5K_RF5111_XPD_GAIN},
+	{6, AR5K_RF_PWD_84,		AR5K_RF5111_PWD(84)},
+	{6, AR5K_RF_PWD_90,		AR5K_RF5111_PWD(90)},
+	{7, AR5K_RF_GAIN_I,		AR5K_RF5111_GAIN_I},
+	{7, AR5K_RF_PLO_SEL,		AR5K_RF5111_PLO_SEL},
+	{7, AR5K_RF_RFGAIN_SEL,		AR5K_RF5111_RFGAIN_SEL},
+	{7, AR5K_RF_RFGAIN_STEP,	AR5K_RF5111_RFGAIN_STEP},
+	{7, AR5K_RF_WAIT_S,		AR5K_RF5111_WAIT_S},
+	{7, AR5K_RF_WAIT_I,		AR5K_RF5111_WAIT_I},
+	{7, AR5K_RF_MAX_TIME,		AR5K_RF5111_MAX_TIME}
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5111[] = {
+	{ 0, 0x989c,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+	{ 0, 0x989c,
+	    { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+	{ 0, 0x98d4,
+	    { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+	{ 1, 0x98d4,
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d4,
+	    { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+	{ 3, 0x98d8,
+	    { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+	{ 6, 0x989c,
+	    { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+	{ 6, 0x989c,
+	    { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+	{ 6, 0x989c,
+	    { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+	{ 6, 0x989c,
+	    { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+	{ 6, 0x989c,
+	    { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+	{ 6, 0x98d4,
+	    { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+	{ 7, 0x989c,
+	    { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
+	{ 7, 0x989c,
+	    { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+	{ 7, 0x989c,
+	    { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+	{ 7, 0x989c,
+	    { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
+	{ 7, 0x989c,
+	    { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
+	{ 7, 0x989c,
+	    { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
+	{ 7, 0x989c,
+	    { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***********************\
+* RF5112/RF2112 (Derby) *
+\***********************/
+
+/* BANK 7 (Common)			len  pos col */
+#define	AR5K_RF5112X_GAIN_I		{ 6, 14,  0 }
+#define	AR5K_RF5112X_MIXVGA_OVR		{ 1, 36,  0 }
+#define	AR5K_RF5112X_MIXGAIN_OVR	{ 2, 37,  0 }
+#define AR5K_RF5112X_MIXGAIN_STEP	{ 4, 32,  0 }
+#define	AR5K_RF5112X_PD_DELAY_A		{ 4, 58,  0 }
+#define	AR5K_RF5112X_PD_DELAY_B		{ 4, 62,  0 }
+#define	AR5K_RF5112X_PD_DELAY_XR	{ 4, 66,  0 }
+#define	AR5K_RF5112X_PD_PERIOD_A	{ 4, 70,  0 }
+#define	AR5K_RF5112X_PD_PERIOD_B	{ 4, 74,  0 }
+#define	AR5K_RF5112X_PD_PERIOD_XR	{ 4, 78,  0 }
+
+/* RFX112 (Derby 1) */
+
+/* BANK 6 				len  pos col */
+#define	AR5K_RF5112_OB_2GHZ		{ 3, 269, 0 }
+#define	AR5K_RF5112_DB_2GHZ		{ 3, 272, 0 }
+
+#define	AR5K_RF5112_OB_5GHZ		{ 3, 261, 0 }
+#define	AR5K_RF5112_DB_5GHZ		{ 3, 264, 0 }
+
+#define	AR5K_RF5112_FIXED_BIAS_A	{ 1, 260, 0 }
+#define	AR5K_RF5112_FIXED_BIAS_B	{ 1, 259, 0 }
+
+#define	AR5K_RF5112_XPD_SEL		{ 1, 284, 0 }
+#define	AR5K_RF5112_XPD_GAIN		{ 2, 252, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112_PWD(_n)		{ 1, (302 - _n), 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF5112_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF5112_DB_2GHZ},
+	{6, AR5K_RF_OB_5GHZ,		AR5K_RF5112_OB_5GHZ},
+	{6, AR5K_RF_DB_5GHZ,		AR5K_RF5112_DB_5GHZ},
+	{6, AR5K_RF_FIXED_BIAS_A,	AR5K_RF5112_FIXED_BIAS_A},
+	{6, AR5K_RF_FIXED_BIAS_B,	AR5K_RF5112_FIXED_BIAS_B},
+	{6, AR5K_RF_XPD_SEL,		AR5K_RF5112_XPD_SEL},
+	{6, AR5K_RF_XPD_GAIN,		AR5K_RF5112_XPD_GAIN},
+	{6, AR5K_RF_PWD_130,		AR5K_RF5112_PWD(130)},
+	{6, AR5K_RF_PWD_131,		AR5K_RF5112_PWD(131)},
+	{6, AR5K_RF_PWD_132,		AR5K_RF5112_PWD(132)},
+	{6, AR5K_RF_PWD_136,		AR5K_RF5112_PWD(136)},
+	{6, AR5K_RF_PWD_137,		AR5K_RF5112_PWD(137)},
+	{6, AR5K_RF_PWD_138,		AR5K_RF5112_PWD(138)},
+	{7, AR5K_RF_GAIN_I,		AR5K_RF5112X_GAIN_I},
+	{7, AR5K_RF_MIXVGA_OVR,		AR5K_RF5112X_MIXVGA_OVR},
+	{7, AR5K_RF_MIXGAIN_OVR,	AR5K_RF5112X_MIXGAIN_OVR},
+	{7, AR5K_RF_MIXGAIN_STEP,	AR5K_RF5112X_MIXGAIN_STEP},
+	{7, AR5K_RF_PD_DELAY_A,		AR5K_RF5112X_PD_DELAY_A},
+	{7, AR5K_RF_PD_DELAY_B,		AR5K_RF5112X_PD_DELAY_B},
+	{7, AR5K_RF_PD_DELAY_XR,	AR5K_RF5112X_PD_DELAY_XR},
+	{7, AR5K_RF_PD_PERIOD_A,	AR5K_RF5112X_PD_PERIOD_A},
+	{7, AR5K_RF_PD_PERIOD_B,	AR5K_RF5112X_PD_PERIOD_B},
+	{7, AR5K_RF_PD_PERIOD_XR,	AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+	{ 3, 0x98dc,
+	    { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+	{ 6, 0x989c,
+	    { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
+	{ 6, 0x989c,
+	    { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
+	{ 6, 0x989c,
+	    { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
+	{ 6, 0x989c,
+	    { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
+	{ 6, 0x989c,
+	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+	{ 6, 0x989c,
+	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+	{ 6, 0x989c,
+	    { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
+	{ 6, 0x989c,
+	    { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
+	{ 6, 0x989c,
+	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+	{ 6, 0x989c,
+	    { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+	{ 6, 0x989c,
+	    { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
+	{ 6, 0x989c,
+	    { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
+	{ 6, 0x989c,
+	    { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+	{ 6, 0x989c,
+	    { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
+	{ 6, 0x989c,
+	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+	{ 6, 0x989c,
+	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+	{ 6, 0x989c,
+	    { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
+	{ 6, 0x989c,
+	    { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
+	{ 6, 0x989c,
+	    { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+	{ 6, 0x989c,
+	    { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
+	{ 6, 0x989c,
+	    { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
+	{ 6, 0x989c,
+	    { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
+	{ 6, 0x989c,
+	    { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
+	{ 6, 0x989c,
+	    { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
+	{ 6, 0x989c,
+	    { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
+	{ 6, 0x989c,
+	    { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
+	{ 6, 0x989c,
+	    { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
+	{ 6, 0x989c,
+	    { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
+	{ 6, 0x989c,
+	    { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
+	{ 6, 0x98d0,
+	    { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
+	{ 7, 0x989c,
+	    { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+	{ 7, 0x989c,
+	    { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+	{ 7, 0x989c,
+	    { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
+	{ 7, 0x989c,
+	    { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+	{ 7, 0x989c,
+	    { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
+	{ 7, 0x989c,
+	    { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+	{ 7, 0x989c,
+	    { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+	{ 7, 0x989c,
+	    { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
+	{ 7, 0x989c,
+	    { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
+	{ 7, 0x989c,
+	    { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+	{ 7, 0x989c,
+	    { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+	{ 7, 0x989c,
+	    { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+	{ 7, 0x98c4,
+	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RFX112A (Derby 2) */
+
+/* BANK 6				len  pos col */
+#define	AR5K_RF5112A_OB_2GHZ		{ 3, 287, 0 }
+#define	AR5K_RF5112A_DB_2GHZ		{ 3, 290, 0 }
+
+#define	AR5K_RF5112A_OB_5GHZ		{ 3, 279, 0 }
+#define	AR5K_RF5112A_DB_5GHZ		{ 3, 282, 0 }
+
+#define	AR5K_RF5112A_FIXED_BIAS_A	{ 1, 278, 0 }
+#define	AR5K_RF5112A_FIXED_BIAS_B	{ 1, 277, 0 }
+
+#define	AR5K_RF5112A_XPD_SEL		{ 1, 302, 0 }
+#define	AR5K_RF5112A_PDGAINLO		{ 2, 270, 0 }
+#define	AR5K_RF5112A_PDGAINHI		{ 2, 257, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112A_PWD(_n)		{ 1, (306 - _n), 3 }
+
+/* Voltage regulators */
+#define	AR5K_RF5112A_HIGH_VC_CP		{ 2, 90,  2 }
+#define	AR5K_RF5112A_MID_VC_CP		{ 2, 92,  2 }
+#define	AR5K_RF5112A_LOW_VC_CP		{ 2, 94,  2 }
+#define	AR5K_RF5112A_PUSH_UP		{ 1, 254,  2 }
+
+/* Power consumption */
+#define	AR5K_RF5112A_PAD2GND		{ 1, 281, 1 }
+#define	AR5K_RF5112A_XB2_LVL		{ 2, 1,	  3 }
+#define	AR5K_RF5112A_XB5_LVL		{ 2, 3,	  3 }
+
+static const struct ath5k_rf_reg rf_regs_5112a[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF5112A_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF5112A_DB_2GHZ},
+	{6, AR5K_RF_OB_5GHZ,		AR5K_RF5112A_OB_5GHZ},
+	{6, AR5K_RF_DB_5GHZ,		AR5K_RF5112A_DB_5GHZ},
+	{6, AR5K_RF_FIXED_BIAS_A,	AR5K_RF5112A_FIXED_BIAS_A},
+	{6, AR5K_RF_FIXED_BIAS_B,	AR5K_RF5112A_FIXED_BIAS_B},
+	{6, AR5K_RF_XPD_SEL,		AR5K_RF5112A_XPD_SEL},
+	{6, AR5K_RF_PD_GAIN_LO,		AR5K_RF5112A_PDGAINLO},
+	{6, AR5K_RF_PD_GAIN_HI,		AR5K_RF5112A_PDGAINHI},
+	{6, AR5K_RF_PWD_130,		AR5K_RF5112A_PWD(130)},
+	{6, AR5K_RF_PWD_131,		AR5K_RF5112A_PWD(131)},
+	{6, AR5K_RF_PWD_132,		AR5K_RF5112A_PWD(132)},
+	{6, AR5K_RF_PWD_136,		AR5K_RF5112A_PWD(136)},
+	{6, AR5K_RF_PWD_137,		AR5K_RF5112A_PWD(137)},
+	{6, AR5K_RF_PWD_138,		AR5K_RF5112A_PWD(138)},
+	{6, AR5K_RF_PWD_166,		AR5K_RF5112A_PWD(166)},
+	{6, AR5K_RF_PWD_167,		AR5K_RF5112A_PWD(167)},
+	{6, AR5K_RF_HIGH_VC_CP,		AR5K_RF5112A_HIGH_VC_CP},
+	{6, AR5K_RF_MID_VC_CP,		AR5K_RF5112A_MID_VC_CP},
+	{6, AR5K_RF_LOW_VC_CP,		AR5K_RF5112A_LOW_VC_CP},
+	{6, AR5K_RF_PUSH_UP,		AR5K_RF5112A_PUSH_UP},
+	{6, AR5K_RF_PAD2GND,		AR5K_RF5112A_PAD2GND},
+	{6, AR5K_RF_XB2_LVL,		AR5K_RF5112A_XB2_LVL},
+	{6, AR5K_RF_XB5_LVL,		AR5K_RF5112A_XB5_LVL},
+	{7, AR5K_RF_GAIN_I,		AR5K_RF5112X_GAIN_I},
+	{7, AR5K_RF_MIXVGA_OVR,		AR5K_RF5112X_MIXVGA_OVR},
+	{7, AR5K_RF_MIXGAIN_OVR,	AR5K_RF5112X_MIXGAIN_OVR},
+	{7, AR5K_RF_MIXGAIN_STEP,	AR5K_RF5112X_MIXGAIN_STEP},
+	{7, AR5K_RF_PD_DELAY_A,		AR5K_RF5112X_PD_DELAY_A},
+	{7, AR5K_RF_PD_DELAY_B,		AR5K_RF5112X_PD_DELAY_B},
+	{7, AR5K_RF_PD_DELAY_XR,	AR5K_RF5112X_PD_DELAY_XR},
+	{7, AR5K_RF_PD_PERIOD_A,	AR5K_RF5112X_PD_PERIOD_A},
+	{7, AR5K_RF_PD_PERIOD_B,	AR5K_RF5112X_PD_PERIOD_B},
+	{7, AR5K_RF_PD_PERIOD_XR,	AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
+	{ 6, 0x989c,
+	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+	{ 6, 0x989c,
+	    { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
+	{ 6, 0x989c,
+	    { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
+	{ 6, 0x989c,
+	    { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
+	{ 6, 0x989c,
+	    { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
+	{ 6, 0x989c,
+	    { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
+	{ 6, 0x989c,
+	    { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
+	{ 6, 0x989c,
+	    { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
+	{ 6, 0x989c,
+	    { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+	{ 6, 0x989c,
+	    { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
+	{ 6, 0x989c,
+	    { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+	{ 6, 0x989c,
+	    { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
+	{ 6, 0x989c,
+	    { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
+	{ 6, 0x989c,
+	    { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
+	{ 6, 0x989c,
+	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+	{ 6, 0x989c,
+	    { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+	{ 6, 0x989c,
+	    { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
+	{ 6, 0x989c,
+	    { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
+	{ 6, 0x989c,
+	    { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+	{ 6, 0x989c,
+	    { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
+	{ 6, 0x989c,
+	    { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
+	{ 6, 0x989c,
+	    { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
+	{ 6, 0x989c,
+	    { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
+	{ 6, 0x989c,
+	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
+	{ 6, 0x989c,
+	    { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
+	{ 6, 0x989c,
+	    { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
+	{ 6, 0x989c,
+	    { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
+	{ 6, 0x989c,
+	    { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
+	{ 6, 0x98d8,
+	    { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
+	{ 7, 0x989c,
+	    { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+	{ 7, 0x989c,
+	    { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+	{ 7, 0x989c,
+	    { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
+	{ 7, 0x989c,
+	    { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+	{ 7, 0x989c,
+	    { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
+	{ 7, 0x989c,
+	    { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+	{ 7, 0x989c,
+	    { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+	{ 7, 0x989c,
+	    { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
+	{ 7, 0x989c,
+	    { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
+	{ 7, 0x989c,
+	    { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+	{ 7, 0x989c,
+	    { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+	{ 7, 0x989c,
+	    { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+	{ 7, 0x98c4,
+	    { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+
+
+/******************\
+* RF2413 (Griffin) *
+\******************/
+
+/* BANK 6 				len  pos col */
+#define	AR5K_RF2413_OB_2GHZ		{ 3, 168, 0 }
+#define	AR5K_RF2413_DB_2GHZ		{ 3, 165, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2413[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF2413_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF2413_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ???
+ */
+static const struct ath5k_ini_rfbuffer rfb_2413[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
+	{ 6, 0x989c,
+	    { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
+	{ 6, 0x989c,
+	    { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
+	{ 6, 0x989c,
+	    { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
+	{ 6, 0x989c,
+	    { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
+	{ 6, 0x989c,
+	    { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
+	{ 6, 0x989c,
+	    { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+	{ 6, 0x989c,
+	    { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
+	{ 6, 0x989c,
+	    { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
+	{ 6, 0x989c,
+	    { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
+	{ 6, 0x989c,
+	    { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
+	{ 6, 0x989c,
+	    { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
+	{ 6, 0x989c,
+	    { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
+	{ 6, 0x98d8,
+	    { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2315/RF2316 (Cobra SoC) *
+\***************************/
+
+/* BANK 6				len  pos col */
+#define	AR5K_RF2316_OB_2GHZ		{ 3, 178, 0 }
+#define	AR5K_RF2316_DB_2GHZ		{ 3, 175, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2316[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF2316_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF2316_DB_2GHZ},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_2316[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
+	{ 6, 0x989c,
+	    { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+	{ 6, 0x989c,
+	    { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
+	{ 6, 0x989c,
+	    { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
+	{ 6, 0x989c,
+	    { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
+	{ 6, 0x989c,
+	    { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
+	{ 6, 0x989c,
+	    { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+	{ 6, 0x989c,
+	    { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+	{ 6, 0x989c,
+	    { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
+	{ 6, 0x989c,
+	    { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
+	{ 6, 0x989c,
+	    { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
+	{ 6, 0x989c,
+	    { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
+	{ 6, 0x989c,
+	    { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
+	{ 6, 0x989c,
+	    { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
+	{ 6, 0x989c,
+	    { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+	{ 6, 0x989c,
+	    { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+	{ 6, 0x989c,
+	    { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
+	{ 6, 0x989c,
+	    { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
+	{ 6, 0x98c0,
+	    { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/******************************\
+* RF5413/RF5424 (Eagle/Condor) *
+\******************************/
+
+/* BANK 6				len  pos col */
+#define	AR5K_RF5413_OB_2GHZ		{ 3, 241, 0 }
+#define	AR5K_RF5413_DB_2GHZ		{ 3, 238, 0 }
+
+#define	AR5K_RF5413_OB_5GHZ		{ 3, 247, 0 }
+#define	AR5K_RF5413_DB_5GHZ		{ 3, 244, 0 }
+
+#define	AR5K_RF5413_PWD_ICLOBUF2G	{ 3, 131, 3 }
+#define	AR5K_RF5413_DERBY_CHAN_SEL_MODE	{ 1, 291, 2 }
+
+static const struct ath5k_rf_reg rf_regs_5413[] = {
+	{6, AR5K_RF_OB_2GHZ,		 AR5K_RF5413_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		 AR5K_RF5413_DB_2GHZ},
+	{6, AR5K_RF_OB_5GHZ,		 AR5K_RF5413_OB_5GHZ},
+	{6, AR5K_RF_DB_5GHZ,		 AR5K_RF5413_DB_5GHZ},
+	{6, AR5K_RF_PWD_ICLOBUF_2G,	 AR5K_RF5413_PWD_ICLOBUF2G},
+	{6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5413[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+	{ 3, 0x98dc,
+	    { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
+	{ 6, 0x989c,
+	    { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
+	{ 6, 0x989c,
+	    { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
+	{ 6, 0x989c,
+	    { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
+	{ 6, 0x989c,
+	    { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+	{ 6, 0x989c,
+	    { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+	{ 6, 0x989c,
+	    { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+	{ 6, 0x989c,
+	    { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
+	{ 6, 0x989c,
+	    { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
+	{ 6, 0x989c,
+	    { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+	{ 6, 0x989c,
+	    { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
+	{ 6, 0x989c,
+	    { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
+	{ 6, 0x989c,
+	    { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
+	{ 6, 0x989c,
+	    { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+	{ 6, 0x989c,
+	    { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
+	{ 6, 0x989c,
+	    { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+	{ 6, 0x989c,
+	    { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
+	{ 6, 0x989c,
+	    { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
+	{ 6, 0x989c,
+	    { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
+	{ 6, 0x989c,
+	    { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
+	{ 6, 0x989c,
+	    { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
+	{ 6, 0x989c,
+	    { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
+	{ 6, 0x989c,
+	    { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
+	{ 6, 0x98c8,
+	    { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2425/RF2417 (Swan/Nala) *
+* AR2317 (Spider SoC)       *
+\***************************/
+
+/* BANK 6				len  pos col */
+#define	AR5K_RF2425_OB_2GHZ		{ 3, 193, 0 }
+#define	AR5K_RF2425_DB_2GHZ		{ 3, 190, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2425[] = {
+	{6, AR5K_RF_OB_2GHZ,		AR5K_RF2425_OB_2GHZ},
+	{6, AR5K_RF_DB_2GHZ,		AR5K_RF2425_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2425[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+	{ 6, 0x989c,
+	    { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+	{ 6, 0x989c,
+	    { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+	{ 6, 0x989c,
+	    { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+	{ 6, 0x989c,
+	    { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+	{ 6, 0x989c,
+	    { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+	{ 6, 0x989c,
+	    { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+	{ 6, 0x989c,
+	    { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+	{ 6, 0x989c,
+	    { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+	{ 6, 0x989c,
+	    { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+	{ 6, 0x989c,
+	    { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+	{ 6, 0x989c,
+	    { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+	{ 6, 0x98c4,
+	    { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ */
+static const struct ath5k_ini_rfbuffer rfb_2317[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+	{ 6, 0x989c,
+	    { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+	{ 6, 0x989c,
+	    { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+	{ 6, 0x989c,
+	    { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+	{ 6, 0x989c,
+	    { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+	{ 6, 0x989c,
+	    { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
+	{ 6, 0x989c,
+	    { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+	{ 6, 0x989c,
+	    { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+	{ 6, 0x989c,
+	    { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+	{ 6, 0x989c,
+	    { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+	{ 6, 0x989c,
+	    { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+	{ 6, 0x989c,
+	    { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
+	{ 6, 0x98c4,
+	    { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2417[] = {
+	{ 1, 0x98d4,
+	/*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d0,
+	    { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+	{ 3, 0x98dc,
+	    { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+	{ 6, 0x989c,
+	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+	{ 6, 0x989c,
+	    { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+	{ 6, 0x989c,
+	    { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+	{ 6, 0x989c,
+	    { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+	{ 6, 0x989c,
+	    { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
+	{ 6, 0x989c,
+	    { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+	{ 6, 0x989c,
+	    { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+	{ 6, 0x989c,
+	    { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
+	{ 6, 0x989c,
+	    { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+	{ 6, 0x989c,
+	    { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+	{ 6, 0x989c,
+	    { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+	{ 6, 0x989c,
+	    { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+	{ 6, 0x98c4,
+	    { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+	{ 7, 0x989c,
+	    { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+	{ 7, 0x989c,
+	    { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+	{ 7, 0x98cc,
+	    { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/rfgain.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/rfgain.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath5k/rfgain.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/rfgain.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,516 @@
+/*
+ * RF Gain optimization
+ *
+ * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+	u16	rfg_register;	/* RF Gain register address */
+	u32	rfg_value[2];	/* [freq (see below)] */
+};
+
+/* Initial RF Gain settings for RF5111 */
+static const struct ath5k_ini_rfgain rfgain_5111[] = {
+	/*			      5Ghz	2Ghz	*/
+	{ AR5K_RF_GAIN(0),	{ 0x000001a9, 0x00000000 } },
+	{ AR5K_RF_GAIN(1),	{ 0x000001e9, 0x00000040 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000029, 0x00000080 } },
+	{ AR5K_RF_GAIN(3),	{ 0x00000069, 0x00000150 } },
+	{ AR5K_RF_GAIN(4),	{ 0x00000199, 0x00000190 } },
+	{ AR5K_RF_GAIN(5),	{ 0x000001d9, 0x000001d0 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000019, 0x00000010 } },
+	{ AR5K_RF_GAIN(7),	{ 0x00000059, 0x00000044 } },
+	{ AR5K_RF_GAIN(8),	{ 0x00000099, 0x00000084 } },
+	{ AR5K_RF_GAIN(9),	{ 0x000001a5, 0x00000148 } },
+	{ AR5K_RF_GAIN(10),	{ 0x000001e5, 0x00000188 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000025, 0x000001c8 } },
+	{ AR5K_RF_GAIN(12),	{ 0x000001c8, 0x00000014 } },
+	{ AR5K_RF_GAIN(13),	{ 0x00000008, 0x00000042 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000048, 0x00000082 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000088, 0x00000178 } },
+	{ AR5K_RF_GAIN(16),	{ 0x00000198, 0x000001b8 } },
+	{ AR5K_RF_GAIN(17),	{ 0x000001d8, 0x000001f8 } },
+	{ AR5K_RF_GAIN(18),	{ 0x00000018, 0x00000012 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000058, 0x00000052 } },
+	{ AR5K_RF_GAIN(20),	{ 0x00000098, 0x00000092 } },
+	{ AR5K_RF_GAIN(21),	{ 0x000001a4, 0x0000017c } },
+	{ AR5K_RF_GAIN(22),	{ 0x000001e4, 0x000001bc } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000024, 0x000001fc } },
+	{ AR5K_RF_GAIN(24),	{ 0x00000064, 0x0000000a } },
+	{ AR5K_RF_GAIN(25),	{ 0x000000a4, 0x0000004a } },
+	{ AR5K_RF_GAIN(26),	{ 0x000000e4, 0x0000008a } },
+	{ AR5K_RF_GAIN(27),	{ 0x0000010a, 0x0000015a } },
+	{ AR5K_RF_GAIN(28),	{ 0x0000014a, 0x0000019a } },
+	{ AR5K_RF_GAIN(29),	{ 0x0000018a, 0x000001da } },
+	{ AR5K_RF_GAIN(30),	{ 0x000001ca, 0x0000000e } },
+	{ AR5K_RF_GAIN(31),	{ 0x0000000a, 0x0000004e } },
+	{ AR5K_RF_GAIN(32),	{ 0x0000004a, 0x0000008e } },
+	{ AR5K_RF_GAIN(33),	{ 0x0000008a, 0x0000015e } },
+	{ AR5K_RF_GAIN(34),	{ 0x000001ba, 0x0000019e } },
+	{ AR5K_RF_GAIN(35),	{ 0x000001fa, 0x000001de } },
+	{ AR5K_RF_GAIN(36),	{ 0x0000003a, 0x00000009 } },
+	{ AR5K_RF_GAIN(37),	{ 0x0000007a, 0x00000049 } },
+	{ AR5K_RF_GAIN(38),	{ 0x00000186, 0x00000089 } },
+	{ AR5K_RF_GAIN(39),	{ 0x000001c6, 0x00000179 } },
+	{ AR5K_RF_GAIN(40),	{ 0x00000006, 0x000001b9 } },
+	{ AR5K_RF_GAIN(41),	{ 0x00000046, 0x000001f9 } },
+	{ AR5K_RF_GAIN(42),	{ 0x00000086, 0x00000039 } },
+	{ AR5K_RF_GAIN(43),	{ 0x000000c6, 0x00000079 } },
+	{ AR5K_RF_GAIN(44),	{ 0x000000c6, 0x000000b9 } },
+	{ AR5K_RF_GAIN(45),	{ 0x000000c6, 0x000001bd } },
+	{ AR5K_RF_GAIN(46),	{ 0x000000c6, 0x000001fd } },
+	{ AR5K_RF_GAIN(47),	{ 0x000000c6, 0x0000003d } },
+	{ AR5K_RF_GAIN(48),	{ 0x000000c6, 0x0000007d } },
+	{ AR5K_RF_GAIN(49),	{ 0x000000c6, 0x000000bd } },
+	{ AR5K_RF_GAIN(50),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(51),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(52),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(53),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(54),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(55),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(56),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(57),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(58),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(59),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(60),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(61),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(62),	{ 0x000000c6, 0x000000fd } },
+	{ AR5K_RF_GAIN(63),	{ 0x000000c6, 0x000000fd } },
+};
+
+/* Initial RF Gain settings for RF5112 */
+static const struct ath5k_ini_rfgain rfgain_5112[] = {
+	/*			      5Ghz	2Ghz	*/
+	{ AR5K_RF_GAIN(0),	{ 0x00000007, 0x00000007 } },
+	{ AR5K_RF_GAIN(1),	{ 0x00000047, 0x00000047 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000087, 0x00000087 } },
+	{ AR5K_RF_GAIN(3),	{ 0x000001a0, 0x000001a0 } },
+	{ AR5K_RF_GAIN(4),	{ 0x000001e0, 0x000001e0 } },
+	{ AR5K_RF_GAIN(5),	{ 0x00000020, 0x00000020 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000060, 0x00000060 } },
+	{ AR5K_RF_GAIN(7),	{ 0x000001a1, 0x000001a1 } },
+	{ AR5K_RF_GAIN(8),	{ 0x000001e1, 0x000001e1 } },
+	{ AR5K_RF_GAIN(9),	{ 0x00000021, 0x00000021 } },
+	{ AR5K_RF_GAIN(10),	{ 0x00000061, 0x00000061 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000162, 0x00000162 } },
+	{ AR5K_RF_GAIN(12),	{ 0x000001a2, 0x000001a2 } },
+	{ AR5K_RF_GAIN(13),	{ 0x000001e2, 0x000001e2 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000022, 0x00000022 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000062, 0x00000062 } },
+	{ AR5K_RF_GAIN(16),	{ 0x00000163, 0x00000163 } },
+	{ AR5K_RF_GAIN(17),	{ 0x000001a3, 0x000001a3 } },
+	{ AR5K_RF_GAIN(18),	{ 0x000001e3, 0x000001e3 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000023, 0x00000023 } },
+	{ AR5K_RF_GAIN(20),	{ 0x00000063, 0x00000063 } },
+	{ AR5K_RF_GAIN(21),	{ 0x00000184, 0x00000184 } },
+	{ AR5K_RF_GAIN(22),	{ 0x000001c4, 0x000001c4 } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000004, 0x00000004 } },
+	{ AR5K_RF_GAIN(24),	{ 0x000001ea, 0x0000000b } },
+	{ AR5K_RF_GAIN(25),	{ 0x0000002a, 0x0000004b } },
+	{ AR5K_RF_GAIN(26),	{ 0x0000006a, 0x0000008b } },
+	{ AR5K_RF_GAIN(27),	{ 0x000000aa, 0x000001ac } },
+	{ AR5K_RF_GAIN(28),	{ 0x000001ab, 0x000001ec } },
+	{ AR5K_RF_GAIN(29),	{ 0x000001eb, 0x0000002c } },
+	{ AR5K_RF_GAIN(30),	{ 0x0000002b, 0x00000012 } },
+	{ AR5K_RF_GAIN(31),	{ 0x0000006b, 0x00000052 } },
+	{ AR5K_RF_GAIN(32),	{ 0x000000ab, 0x00000092 } },
+	{ AR5K_RF_GAIN(33),	{ 0x000001ac, 0x00000193 } },
+	{ AR5K_RF_GAIN(34),	{ 0x000001ec, 0x000001d3 } },
+	{ AR5K_RF_GAIN(35),	{ 0x0000002c, 0x00000013 } },
+	{ AR5K_RF_GAIN(36),	{ 0x0000003a, 0x00000053 } },
+	{ AR5K_RF_GAIN(37),	{ 0x0000007a, 0x00000093 } },
+	{ AR5K_RF_GAIN(38),	{ 0x000000ba, 0x00000194 } },
+	{ AR5K_RF_GAIN(39),	{ 0x000001bb, 0x000001d4 } },
+	{ AR5K_RF_GAIN(40),	{ 0x000001fb, 0x00000014 } },
+	{ AR5K_RF_GAIN(41),	{ 0x0000003b, 0x0000003a } },
+	{ AR5K_RF_GAIN(42),	{ 0x0000007b, 0x0000007a } },
+	{ AR5K_RF_GAIN(43),	{ 0x000000bb, 0x000000ba } },
+	{ AR5K_RF_GAIN(44),	{ 0x000001bc, 0x000001bb } },
+	{ AR5K_RF_GAIN(45),	{ 0x000001fc, 0x000001fb } },
+	{ AR5K_RF_GAIN(46),	{ 0x0000003c, 0x0000003b } },
+	{ AR5K_RF_GAIN(47),	{ 0x0000007c, 0x0000007b } },
+	{ AR5K_RF_GAIN(48),	{ 0x000000bc, 0x000000bb } },
+	{ AR5K_RF_GAIN(49),	{ 0x000000fc, 0x000001bc } },
+	{ AR5K_RF_GAIN(50),	{ 0x000000fc, 0x000001fc } },
+	{ AR5K_RF_GAIN(51),	{ 0x000000fc, 0x0000003c } },
+	{ AR5K_RF_GAIN(52),	{ 0x000000fc, 0x0000007c } },
+	{ AR5K_RF_GAIN(53),	{ 0x000000fc, 0x000000bc } },
+	{ AR5K_RF_GAIN(54),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(55),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(56),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(57),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(58),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(59),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(60),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(61),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(62),	{ 0x000000fc, 0x000000fc } },
+	{ AR5K_RF_GAIN(63),	{ 0x000000fc, 0x000000fc } },
+};
+
+/* Initial RF Gain settings for RF2413 */
+static const struct ath5k_ini_rfgain rfgain_2413[] = {
+	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
+	{ AR5K_RF_GAIN(1),	{ 0x00000000, 0x00000040 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000000, 0x00000080 } },
+	{ AR5K_RF_GAIN(3),	{ 0x00000000, 0x00000181 } },
+	{ AR5K_RF_GAIN(4),	{ 0x00000000, 0x000001c1 } },
+	{ AR5K_RF_GAIN(5),	{ 0x00000000, 0x00000001 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000000, 0x00000041 } },
+	{ AR5K_RF_GAIN(7),	{ 0x00000000, 0x00000081 } },
+	{ AR5K_RF_GAIN(8),	{ 0x00000000, 0x00000168 } },
+	{ AR5K_RF_GAIN(9),	{ 0x00000000, 0x000001a8 } },
+	{ AR5K_RF_GAIN(10),	{ 0x00000000, 0x000001e8 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000000, 0x00000028 } },
+	{ AR5K_RF_GAIN(12),	{ 0x00000000, 0x00000068 } },
+	{ AR5K_RF_GAIN(13),	{ 0x00000000, 0x00000189 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000000, 0x000001c9 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000000, 0x00000009 } },
+	{ AR5K_RF_GAIN(16),	{ 0x00000000, 0x00000049 } },
+	{ AR5K_RF_GAIN(17),	{ 0x00000000, 0x00000089 } },
+	{ AR5K_RF_GAIN(18),	{ 0x00000000, 0x00000190 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000000, 0x000001d0 } },
+	{ AR5K_RF_GAIN(20),	{ 0x00000000, 0x00000010 } },
+	{ AR5K_RF_GAIN(21),	{ 0x00000000, 0x00000050 } },
+	{ AR5K_RF_GAIN(22),	{ 0x00000000, 0x00000090 } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000000, 0x00000191 } },
+	{ AR5K_RF_GAIN(24),	{ 0x00000000, 0x000001d1 } },
+	{ AR5K_RF_GAIN(25),	{ 0x00000000, 0x00000011 } },
+	{ AR5K_RF_GAIN(26),	{ 0x00000000, 0x00000051 } },
+	{ AR5K_RF_GAIN(27),	{ 0x00000000, 0x00000091 } },
+	{ AR5K_RF_GAIN(28),	{ 0x00000000, 0x00000178 } },
+	{ AR5K_RF_GAIN(29),	{ 0x00000000, 0x000001b8 } },
+	{ AR5K_RF_GAIN(30),	{ 0x00000000, 0x000001f8 } },
+	{ AR5K_RF_GAIN(31),	{ 0x00000000, 0x00000038 } },
+	{ AR5K_RF_GAIN(32),	{ 0x00000000, 0x00000078 } },
+	{ AR5K_RF_GAIN(33),	{ 0x00000000, 0x00000199 } },
+	{ AR5K_RF_GAIN(34),	{ 0x00000000, 0x000001d9 } },
+	{ AR5K_RF_GAIN(35),	{ 0x00000000, 0x00000019 } },
+	{ AR5K_RF_GAIN(36),	{ 0x00000000, 0x00000059 } },
+	{ AR5K_RF_GAIN(37),	{ 0x00000000, 0x00000099 } },
+	{ AR5K_RF_GAIN(38),	{ 0x00000000, 0x000000d9 } },
+	{ AR5K_RF_GAIN(39),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(40),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(41),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(42),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(43),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(44),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(45),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(46),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(47),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(48),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(49),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(50),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(51),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(52),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(53),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(54),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(55),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(56),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(57),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(58),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(59),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(60),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(61),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(62),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(63),	{ 0x00000000, 0x000000f9 } },
+};
+
+/* Initial RF Gain settings for AR2316 */
+static const struct ath5k_ini_rfgain rfgain_2316[] = {
+	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
+	{ AR5K_RF_GAIN(1),	{ 0x00000000, 0x00000040 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000000, 0x00000080 } },
+	{ AR5K_RF_GAIN(3),	{ 0x00000000, 0x000000c0 } },
+	{ AR5K_RF_GAIN(4),	{ 0x00000000, 0x000000e0 } },
+	{ AR5K_RF_GAIN(5),	{ 0x00000000, 0x000000e0 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000000, 0x00000128 } },
+	{ AR5K_RF_GAIN(7),	{ 0x00000000, 0x00000128 } },
+	{ AR5K_RF_GAIN(8),	{ 0x00000000, 0x00000128 } },
+	{ AR5K_RF_GAIN(9),	{ 0x00000000, 0x00000168 } },
+	{ AR5K_RF_GAIN(10),	{ 0x00000000, 0x000001a8 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000000, 0x000001e8 } },
+	{ AR5K_RF_GAIN(12),	{ 0x00000000, 0x00000028 } },
+	{ AR5K_RF_GAIN(13),	{ 0x00000000, 0x00000068 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000000, 0x000000a8 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000000, 0x000000e8 } },
+	{ AR5K_RF_GAIN(16),	{ 0x00000000, 0x000000e8 } },
+	{ AR5K_RF_GAIN(17),	{ 0x00000000, 0x00000130 } },
+	{ AR5K_RF_GAIN(18),	{ 0x00000000, 0x00000130 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000000, 0x00000170 } },
+	{ AR5K_RF_GAIN(20),	{ 0x00000000, 0x000001b0 } },
+	{ AR5K_RF_GAIN(21),	{ 0x00000000, 0x000001f0 } },
+	{ AR5K_RF_GAIN(22),	{ 0x00000000, 0x00000030 } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000000, 0x00000070 } },
+	{ AR5K_RF_GAIN(24),	{ 0x00000000, 0x000000b0 } },
+	{ AR5K_RF_GAIN(25),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(26),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(27),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(28),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(29),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(30),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(31),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(32),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(33),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(34),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(35),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(36),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(37),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(38),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(39),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(40),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(41),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(42),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(43),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(44),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(45),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(46),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(47),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(48),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(49),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(50),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(51),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(52),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(53),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(54),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(55),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(56),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(57),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(58),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(59),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(60),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(61),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(62),	{ 0x00000000, 0x000000f0 } },
+	{ AR5K_RF_GAIN(63),	{ 0x00000000, 0x000000f0 } },
+};
+
+
+/* Initial RF Gain settings for RF5413 */
+static const struct ath5k_ini_rfgain rfgain_5413[] = {
+	/*			      5Ghz	2Ghz	*/
+	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
+	{ AR5K_RF_GAIN(1),	{ 0x00000040, 0x00000040 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000080, 0x00000080 } },
+	{ AR5K_RF_GAIN(3),	{ 0x000001a1, 0x00000161 } },
+	{ AR5K_RF_GAIN(4),	{ 0x000001e1, 0x000001a1 } },
+	{ AR5K_RF_GAIN(5),	{ 0x00000021, 0x000001e1 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000061, 0x00000021 } },
+	{ AR5K_RF_GAIN(7),	{ 0x00000188, 0x00000061 } },
+	{ AR5K_RF_GAIN(8),	{ 0x000001c8, 0x00000188 } },
+	{ AR5K_RF_GAIN(9),	{ 0x00000008, 0x000001c8 } },
+	{ AR5K_RF_GAIN(10),	{ 0x00000048, 0x00000008 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000088, 0x00000048 } },
+	{ AR5K_RF_GAIN(12),	{ 0x000001a9, 0x00000088 } },
+	{ AR5K_RF_GAIN(13),	{ 0x000001e9, 0x00000169 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000029, 0x000001a9 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000069, 0x000001e9 } },
+	{ AR5K_RF_GAIN(16),	{ 0x000001d0, 0x00000029 } },
+	{ AR5K_RF_GAIN(17),	{ 0x00000010, 0x00000069 } },
+	{ AR5K_RF_GAIN(18),	{ 0x00000050, 0x00000190 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000090, 0x000001d0 } },
+	{ AR5K_RF_GAIN(20),	{ 0x000001b1, 0x00000010 } },
+	{ AR5K_RF_GAIN(21),	{ 0x000001f1, 0x00000050 } },
+	{ AR5K_RF_GAIN(22),	{ 0x00000031, 0x00000090 } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000071, 0x00000171 } },
+	{ AR5K_RF_GAIN(24),	{ 0x000001b8, 0x000001b1 } },
+	{ AR5K_RF_GAIN(25),	{ 0x000001f8, 0x000001f1 } },
+	{ AR5K_RF_GAIN(26),	{ 0x00000038, 0x00000031 } },
+	{ AR5K_RF_GAIN(27),	{ 0x00000078, 0x00000071 } },
+	{ AR5K_RF_GAIN(28),	{ 0x00000199, 0x00000198 } },
+	{ AR5K_RF_GAIN(29),	{ 0x000001d9, 0x000001d8 } },
+	{ AR5K_RF_GAIN(30),	{ 0x00000019, 0x00000018 } },
+	{ AR5K_RF_GAIN(31),	{ 0x00000059, 0x00000058 } },
+	{ AR5K_RF_GAIN(32),	{ 0x00000099, 0x00000098 } },
+	{ AR5K_RF_GAIN(33),	{ 0x000000d9, 0x00000179 } },
+	{ AR5K_RF_GAIN(34),	{ 0x000000f9, 0x000001b9 } },
+	{ AR5K_RF_GAIN(35),	{ 0x000000f9, 0x000001f9 } },
+	{ AR5K_RF_GAIN(36),	{ 0x000000f9, 0x00000039 } },
+	{ AR5K_RF_GAIN(37),	{ 0x000000f9, 0x00000079 } },
+	{ AR5K_RF_GAIN(38),	{ 0x000000f9, 0x000000b9 } },
+	{ AR5K_RF_GAIN(39),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(40),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(41),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(42),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(43),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(44),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(45),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(46),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(47),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(48),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(49),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(50),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(51),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(52),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(53),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(54),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(55),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(56),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(57),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(58),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(59),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(60),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(61),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(62),	{ 0x000000f9, 0x000000f9 } },
+	{ AR5K_RF_GAIN(63),	{ 0x000000f9, 0x000000f9 } },
+};
+
+
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+	{ AR5K_RF_GAIN(0),	{ 0x00000000, 0x00000000 } },
+	{ AR5K_RF_GAIN(1),	{ 0x00000000, 0x00000040 } },
+	{ AR5K_RF_GAIN(2),	{ 0x00000000, 0x00000080 } },
+	{ AR5K_RF_GAIN(3),	{ 0x00000000, 0x00000181 } },
+	{ AR5K_RF_GAIN(4),	{ 0x00000000, 0x000001c1 } },
+	{ AR5K_RF_GAIN(5),	{ 0x00000000, 0x00000001 } },
+	{ AR5K_RF_GAIN(6),	{ 0x00000000, 0x00000041 } },
+	{ AR5K_RF_GAIN(7),	{ 0x00000000, 0x00000081 } },
+	{ AR5K_RF_GAIN(8),	{ 0x00000000, 0x00000188 } },
+	{ AR5K_RF_GAIN(9),	{ 0x00000000, 0x000001c8 } },
+	{ AR5K_RF_GAIN(10),	{ 0x00000000, 0x00000008 } },
+	{ AR5K_RF_GAIN(11),	{ 0x00000000, 0x00000048 } },
+	{ AR5K_RF_GAIN(12),	{ 0x00000000, 0x00000088 } },
+	{ AR5K_RF_GAIN(13),	{ 0x00000000, 0x00000189 } },
+	{ AR5K_RF_GAIN(14),	{ 0x00000000, 0x000001c9 } },
+	{ AR5K_RF_GAIN(15),	{ 0x00000000, 0x00000009 } },
+	{ AR5K_RF_GAIN(16),	{ 0x00000000, 0x00000049 } },
+	{ AR5K_RF_GAIN(17),	{ 0x00000000, 0x00000089 } },
+	{ AR5K_RF_GAIN(18),	{ 0x00000000, 0x000001b0 } },
+	{ AR5K_RF_GAIN(19),	{ 0x00000000, 0x000001f0 } },
+	{ AR5K_RF_GAIN(20),	{ 0x00000000, 0x00000030 } },
+	{ AR5K_RF_GAIN(21),	{ 0x00000000, 0x00000070 } },
+	{ AR5K_RF_GAIN(22),	{ 0x00000000, 0x00000171 } },
+	{ AR5K_RF_GAIN(23),	{ 0x00000000, 0x000001b1 } },
+	{ AR5K_RF_GAIN(24),	{ 0x00000000, 0x000001f1 } },
+	{ AR5K_RF_GAIN(25),	{ 0x00000000, 0x00000031 } },
+	{ AR5K_RF_GAIN(26),	{ 0x00000000, 0x00000071 } },
+	{ AR5K_RF_GAIN(27),	{ 0x00000000, 0x000001b8 } },
+	{ AR5K_RF_GAIN(28),	{ 0x00000000, 0x000001f8 } },
+	{ AR5K_RF_GAIN(29),	{ 0x00000000, 0x00000038 } },
+	{ AR5K_RF_GAIN(30),	{ 0x00000000, 0x00000078 } },
+	{ AR5K_RF_GAIN(31),	{ 0x00000000, 0x000000b8 } },
+	{ AR5K_RF_GAIN(32),	{ 0x00000000, 0x000001b9 } },
+	{ AR5K_RF_GAIN(33),	{ 0x00000000, 0x000001f9 } },
+	{ AR5K_RF_GAIN(34),	{ 0x00000000, 0x00000039 } },
+	{ AR5K_RF_GAIN(35),	{ 0x00000000, 0x00000079 } },
+	{ AR5K_RF_GAIN(36),	{ 0x00000000, 0x000000b9 } },
+	{ AR5K_RF_GAIN(37),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(38),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(39),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(40),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(41),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(42),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(43),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(44),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(45),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(46),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(47),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(48),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(49),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(50),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(51),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(52),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(53),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(54),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(55),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(56),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(57),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(58),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(59),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(60),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(61),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(62),	{ 0x00000000, 0x000000f9 } },
+	{ AR5K_RF_GAIN(63),	{ 0x00000000, 0x000000f9 } },
+};
+
+#define AR5K_GAIN_CRN_FIX_BITS_5111		4
+#define AR5K_GAIN_CRN_FIX_BITS_5112		7
+#define AR5K_GAIN_CRN_MAX_FIX_BITS		AR5K_GAIN_CRN_FIX_BITS_5112
+#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN		15
+#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN		20
+#define AR5K_GAIN_CCK_PROBE_CORR		5
+#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA		15
+#define AR5K_GAIN_STEP_COUNT			10
+
+/* Check if our current measurement is inside our
+ * current variable attenuation window */
+#define AR5K_GAIN_CHECK_ADJUST(_g) 		\
+	((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+	s8				gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+	s8				gos_gain;
+};
+
+struct ath5k_gain_opt {
+	u8				go_default;
+	u8				go_steps_count;
+	const struct ath5k_gain_opt_step	go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Tx clip PHY register
+ * 2) PWD 90 RF register
+ * 3) PWD 84 RF register
+ * 4) RFGainSel RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5111 = {
+	4,
+	9,
+	{
+		{ { 4, 1, 1, 1 }, 6 },
+		{ { 4, 0, 1, 1 }, 4 },
+		{ { 3, 1, 1, 1 }, 3 },
+		{ { 4, 0, 0, 1 }, 1 },
+		{ { 4, 1, 1, 0 }, 0 },
+		{ { 4, 0, 1, 0 }, -2 },
+		{ { 3, 1, 1, 0 }, -3 },
+		{ { 4, 0, 0, 0 }, -4 },
+		{ { 2, 1, 1, 0 }, -6 }
+	}
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Mixgain ovr RF register
+ * 2) PWD 138 RF register
+ * 3) PWD 137 RF register
+ * 4) PWD 136 RF register
+ * 5) PWD 132 RF register
+ * 6) PWD 131 RF register
+ * 7) PWD 130 RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5112 = {
+	1,
+	8,
+	{
+		{ { 3, 0, 0, 0, 0, 0, 0 }, 6 },
+		{ { 2, 0, 0, 0, 0, 0, 0 }, 0 },
+		{ { 1, 0, 0, 0, 0, 0, 0 }, -3 },
+		{ { 0, 0, 0, 0, 0, 0, 0 }, -6 },
+		{ { 0, 1, 1, 0, 0, 0, 0 }, -8 },
+		{ { 0, 1, 1, 0, 1, 1, 0 }, -10 },
+		{ { 0, 1, 0, 1, 1, 1, 0 }, -13 },
+		{ { 0, 1, 0, 1, 1, 0, 1 }, -16 },
+	}
+};
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ahb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ahb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ahb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ahb.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+#include "ath9k.h"
+
+/* return bus cachesize in 4B word units */
+static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+{
+	*csz = L1_CACHE_BYTES >> 2;
+}
+
+static void ath_ahb_cleanup(struct ath_softc *sc)
+{
+	iounmap(sc->mem);
+}
+
+static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+	struct ath_softc *sc = ah->ah_sc;
+	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);
+		return false;
+	}
+
+	*data = pdata->eeprom_data[off];
+	return true;
+}
+
+static struct ath_bus_ops ath_ahb_bus_ops  = {
+	.read_cachesize = ath_ahb_read_cachesize,
+	.cleanup = ath_ahb_cleanup,
+
+	.eeprom_read = ath_ahb_eeprom_read,
+};
+
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+	void __iomem *mem;
+	struct ath_wiphy *aphy;
+	struct ath_softc *sc;
+	struct ieee80211_hw *hw;
+	struct resource *res;
+	int irq;
+	int ret = 0;
+	struct ath_hw *ah;
+
+	if (!pdev->dev.platform_data) {
+		dev_err(&pdev->dev, "no platform data specified\n");
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no memory resource found\n");
+		ret = -ENXIO;
+		goto err_out;
+	}
+
+	mem = ioremap_nocache(res->start, res->end - res->start + 1);
+	if (mem == NULL) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no IRQ resource found\n");
+		ret = -ENXIO;
+		goto err_iounmap;
+	}
+
+	irq = res->start;
+
+	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+				sizeof(struct ath_softc), &ath9k_ops);
+	if (hw == NULL) {
+		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+		ret = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	SET_IEEE80211_DEV(hw, &pdev->dev);
+	platform_set_drvdata(pdev, hw);
+
+	aphy = hw->priv;
+	sc = (struct ath_softc *) (aphy + 1);
+	aphy->sc = sc;
+	aphy->hw = hw;
+	sc->pri_wiphy = aphy;
+	sc->hw = hw;
+	sc->dev = &pdev->dev;
+	sc->mem = mem;
+	sc->bus_ops = &ath_ahb_bus_ops;
+	sc->irq = irq;
+
+	ret = ath_attach(AR5416_AR9100_DEVID, sc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+		ret = -ENODEV;
+		goto err_free_hw;
+	}
+
+	ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
+		ret = -EIO;
+		goto err_detach;
+	}
+
+	ah = sc->sc_ah;
+	printk(KERN_INFO
+	       "%s: Atheros AR%s MAC/BB Rev:%x, "
+	       "AR%s RF Rev:%x, 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,
+	       (unsigned long)mem, irq);
+
+	return 0;
+
+ err_detach:
+	ath_detach(sc);
+ err_free_hw:
+	ieee80211_free_hw(hw);
+	platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+	iounmap(mem);
+ err_out:
+	return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+	struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+
+	if (hw) {
+		struct ath_wiphy *aphy = hw->priv;
+		struct ath_softc *sc = aphy->sc;
+
+		ath_cleanup(sc);
+		platform_set_drvdata(pdev, NULL);
+	}
+
+	return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+	.probe      = ath_ahb_probe,
+	.remove     = ath_ahb_remove,
+	.driver		= {
+		.name	= "ath9k",
+		.owner	= THIS_MODULE,
+	},
+};
+
+int ath_ahb_init(void)
+{
+	return platform_driver_register(&ath_ahb_driver);
+}
+
+void ath_ahb_exit(void)
+{
+	platform_driver_unregister(&ath_ahb_driver);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ani.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ani.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ani.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ani.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,23 +14,19 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
 
-static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
+static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
 					struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
-		if (ahp->ah_ani[i].c.channel == chan->channel)
+	for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+		if (ah->ani[i].c &&
+		    ah->ani[i].c->channel == chan->channel)
 			return i;
-		if (ahp->ah_ani[i].c.channel == 0) {
-			ahp->ah_ani[i].c.channel = chan->channel;
-			ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
+		if (ah->ani[i].c == NULL) {
+			ah->ani[i].c = chan;
 			return i;
 		}
 	}
@@ -41,41 +37,40 @@ static int ath9k_hw_get_ani_channel_idx(
 	return 0;
 }
 
-static bool ath9k_hw_ani_control(struct ath_hal *ah,
+static bool ath9k_hw_ani_control(struct ath_hw *ah,
 				 enum ath9k_ani_cmd cmd, int param)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416AniState *aniState = ahp->ah_curani;
+	struct ar5416AniState *aniState = ah->curani;
 
-	switch (cmd & ahp->ah_ani_function) {
+	switch (cmd & ah->ani_function) {
 	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
 		u32 level = param;
 
-		if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
+		if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
 			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
 				"level out of range (%u > %u)\n",
 				level,
-				(unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired));
+				(unsigned)ARRAY_SIZE(ah->totalSizeDesired));
 			return false;
 		}
 
 		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
 			      AR_PHY_DESIRED_SZ_TOT_DES,
-			      ahp->ah_totalSizeDesired[level]);
+			      ah->totalSizeDesired[level]);
 		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
 			      AR_PHY_AGC_CTL1_COARSE_LOW,
-			      ahp->ah_coarseLow[level]);
+			      ah->coarse_low[level]);
 		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
 			      AR_PHY_AGC_CTL1_COARSE_HIGH,
-			      ahp->ah_coarseHigh[level]);
+			      ah->coarse_high[level]);
 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
 			      AR_PHY_FIND_SIG_FIRPWR,
-			      ahp->ah_firpwr[level]);
+			      ah->firpwr[level]);
 
 		if (level > aniState->noiseImmunityLevel)
-			ahp->ah_stats.ast_ani_niup++;
+			ah->stats.ast_ani_niup++;
 		else if (level < aniState->noiseImmunityLevel)
-			ahp->ah_stats.ast_ani_nidown++;
+			ah->stats.ast_ani_nidown++;
 		aniState->noiseImmunityLevel = level;
 		break;
 	}
@@ -129,9 +124,9 @@ static bool ath9k_hw_ani_control(struct
 
 		if (!on != aniState->ofdmWeakSigDetectOff) {
 			if (on)
-				ahp->ah_stats.ast_ani_ofdmon++;
+				ah->stats.ast_ani_ofdmon++;
 			else
-				ahp->ah_stats.ast_ani_ofdmoff++;
+				ah->stats.ast_ani_ofdmoff++;
 			aniState->ofdmWeakSigDetectOff = !on;
 		}
 		break;
@@ -145,9 +140,9 @@ static bool ath9k_hw_ani_control(struct
 			      weakSigThrCck[high]);
 		if (high != aniState->cckWeakSigThreshold) {
 			if (high)
-				ahp->ah_stats.ast_ani_cckhigh++;
+				ah->stats.ast_ani_cckhigh++;
 			else
-				ahp->ah_stats.ast_ani_ccklow++;
+				ah->stats.ast_ani_ccklow++;
 			aniState->cckWeakSigThreshold = high;
 		}
 		break;
@@ -167,9 +162,9 @@ static bool ath9k_hw_ani_control(struct
 			      AR_PHY_FIND_SIG_FIRSTEP,
 			      firstep[level]);
 		if (level > aniState->firstepLevel)
-			ahp->ah_stats.ast_ani_stepup++;
+			ah->stats.ast_ani_stepup++;
 		else if (level < aniState->firstepLevel)
-			ahp->ah_stats.ast_ani_stepdown++;
+			ah->stats.ast_ani_stepdown++;
 		aniState->firstepLevel = level;
 		break;
 	}
@@ -190,9 +185,9 @@ static bool ath9k_hw_ani_control(struct
 			      AR_PHY_TIMING5_CYCPWR_THR1,
 			      cycpwrThr1[level]);
 		if (level > aniState->spurImmunityLevel)
-			ahp->ah_stats.ast_ani_spurup++;
+			ah->stats.ast_ani_spurup++;
 		else if (level < aniState->spurImmunityLevel)
-			ahp->ah_stats.ast_ani_spurdown++;
+			ah->stats.ast_ani_spurdown++;
 		aniState->spurImmunityLevel = level;
 		break;
 	}
@@ -223,7 +218,7 @@ static bool ath9k_hw_ani_control(struct
 	return true;
 }
 
-static void ath9k_hw_update_mibstats(struct ath_hal *ah,
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
 				     struct ath9k_mib_stats *stats)
 {
 	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
@@ -233,18 +228,17 @@ static void ath9k_hw_update_mibstats(str
 	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
 }
 
-static void ath9k_ani_restart(struct ath_hal *ah)
+static void ath9k_ani_restart(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416AniState *aniState;
 
 	if (!DO_ANI(ah))
 		return;
 
-	aniState = ahp->ah_curani;
+	aniState = ah->curani;
 
 	aniState->listenTime = 0;
-	if (ahp->ah_hasHwPhyCounters) {
+	if (ah->has_hw_phycounters) {
 		if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
 			aniState->ofdmPhyErrBase = 0;
 			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -270,24 +264,22 @@ static void ath9k_ani_restart(struct ath
 		REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
 		REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 
-		ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+		ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 	}
 	aniState->ofdmPhyErrCount = 0;
 	aniState->cckPhyErrCount = 0;
 }
 
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
 	struct ar5416AniState *aniState;
-	enum wireless_mode mode;
 	int32_t rssi;
 
 	if (!DO_ANI(ah))
 		return;
 
-	aniState = ahp->ah_curani;
+	aniState = ah->curani;
 
 	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
 		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -303,14 +295,14 @@ static void ath9k_hw_ani_ofdm_err_trigge
 		}
 	}
 
-	if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+	if (ah->opmode == NL80211_IFTYPE_AP) {
 		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
 			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 					     aniState->firstepLevel + 1);
 		}
 		return;
 	}
-	rssi = BEACON_RSSI(ahp);
+	rssi = BEACON_RSSI(ah);
 	if (rssi > aniState->rssiThrHigh) {
 		if (!aniState->ofdmWeakSigDetectOff) {
 			if (ath9k_hw_ani_control(ah,
@@ -336,8 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigge
 					     aniState->firstepLevel + 1);
 		return;
 	} else {
-		mode = ath9k_hw_chan2wmode(ah, chan);
-		if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+		if (conf->channel->band == IEEE80211_BAND_2GHZ) {
 			if (!aniState->ofdmWeakSigDetectOff)
 				ath9k_hw_ani_control(ah,
 				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -350,39 +341,36 @@ static void ath9k_hw_ani_ofdm_err_trigge
 	}
 }
 
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
 	struct ar5416AniState *aniState;
-	enum wireless_mode mode;
 	int32_t rssi;
 
 	if (!DO_ANI(ah))
 		return;
 
-	aniState = ahp->ah_curani;
+	aniState = ah->curani;
 	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
 		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
 					 aniState->noiseImmunityLevel + 1)) {
 			return;
 		}
 	}
-	if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+	if (ah->opmode == NL80211_IFTYPE_AP) {
 		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
 			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 					     aniState->firstepLevel + 1);
 		}
 		return;
 	}
-	rssi = BEACON_RSSI(ahp);
+	rssi = BEACON_RSSI(ah);
 	if (rssi > aniState->rssiThrLow) {
 		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
 			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 					     aniState->firstepLevel + 1);
 	} else {
-		mode = ath9k_hw_chan2wmode(ah, chan);
-		if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+		if (conf->channel->band == IEEE80211_BAND_2GHZ) {
 			if (aniState->firstepLevel > 0)
 				ath9k_hw_ani_control(ah,
 					     ATH9K_ANI_FIRSTEP_LEVEL, 0);
@@ -390,22 +378,21 @@ static void ath9k_hw_ani_cck_err_trigger
 	}
 }
 
-static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416AniState *aniState;
 	int32_t rssi;
 
-	aniState = ahp->ah_curani;
+	aniState = ah->curani;
 
-	if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+	if (ah->opmode == NL80211_IFTYPE_AP) {
 		if (aniState->firstepLevel > 0) {
 			if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 						 aniState->firstepLevel - 1))
 				return;
 		}
 	} else {
-		rssi = BEACON_RSSI(ahp);
+		rssi = BEACON_RSSI(ah);
 		if (rssi > aniState->rssiThrHigh) {
 			/* XXX: Handle me */
 		} else if (rssi > aniState->rssiThrLow) {
@@ -444,9 +431,8 @@ static void ath9k_hw_ani_lower_immunity(
 	}
 }
 
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
+static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416AniState *aniState;
 	u32 txFrameCount, rxFrameCount, cycleCount;
 	int32_t listenTime;
@@ -455,11 +441,11 @@ static int32_t ath9k_hw_ani_get_listen_t
 	rxFrameCount = REG_READ(ah, AR_RFCNT);
 	cycleCount = REG_READ(ah, AR_CCCNT);
 
-	aniState = ahp->ah_curani;
+	aniState = ah->curani;
 	if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
 
 		listenTime = 0;
-		ahp->ah_stats.ast_ani_lzero++;
+		ah->stats.ast_ani_lzero++;
 	} else {
 		int32_t ccdelta = cycleCount - aniState->cycleCount;
 		int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
@@ -473,25 +459,24 @@ static int32_t ath9k_hw_ani_get_listen_t
 	return listenTime;
 }
 
-void ath9k_ani_reset(struct ath_hal *ah)
+void ath9k_ani_reset(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416AniState *aniState;
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ath9k_channel *chan = ah->curchan;
 	int index;
 
 	if (!DO_ANI(ah))
 		return;
 
 	index = ath9k_hw_get_ani_channel_idx(ah, chan);
-	aniState = &ahp->ah_ani[index];
-	ahp->ah_curani = aniState;
+	aniState = &ah->ani[index];
+	ah->curani = aniState;
 
-	if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION
-	    && ah->ah_opmode != NL80211_IFTYPE_ADHOC) {
+	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->ah_opmode);
-		ahp->ah_stats.ast_ani_reset++;
+			"Reset ANI state opmode %u\n", ah->opmode);
+		ah->stats.ast_ani_reset++;
 
 		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
 		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
@@ -504,15 +489,15 @@ void ath9k_ani_reset(struct ath_hal *ah)
 		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
 				     ATH9K_RX_FILTER_PHYERR);
 
-		if (ah->ah_opmode == NL80211_IFTYPE_AP) {
-			ahp->ah_curani->ofdmTrigHigh =
-				ah->ah_config.ofdm_trig_high;
-			ahp->ah_curani->ofdmTrigLow =
-				ah->ah_config.ofdm_trig_low;
-			ahp->ah_curani->cckTrigHigh =
-				ah->ah_config.cck_trig_high;
-			ahp->ah_curani->cckTrigLow =
-				ah->ah_config.cck_trig_low;
+		if (ah->opmode == NL80211_IFTYPE_AP) {
+			ah->curani->ofdmTrigHigh =
+				ah->config.ofdm_trig_high;
+			ah->curani->ofdmTrigLow =
+				ah->config.ofdm_trig_low;
+			ah->curani->cckTrigHigh =
+				ah->config.cck_trig_high;
+			ah->curani->cckTrigLow =
+				ah->config.cck_trig_low;
 		}
 		ath9k_ani_restart(ah);
 		return;
@@ -533,7 +518,7 @@ void ath9k_ani_reset(struct ath_hal *ah)
 	if (aniState->firstepLevel != 0)
 		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 				     aniState->firstepLevel);
-	if (ahp->ah_hasHwPhyCounters) {
+	if (ah->has_hw_phycounters) {
 		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
 				     ~ATH9K_RX_FILTER_PHYERR);
 		ath9k_ani_restart(ah);
@@ -547,31 +532,33 @@ void ath9k_ani_reset(struct ath_hal *ah)
 	}
 }
 
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
 			  const struct ath9k_node_stats *stats,
 			  struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416AniState *aniState;
 	int32_t listenTime;
 
-	aniState = ahp->ah_curani;
-	ahp->ah_stats.ast_nodestats = *stats;
+	if (!DO_ANI(ah))
+		return;
+
+	aniState = ah->curani;
+	ah->stats.ast_nodestats = *stats;
 
 	listenTime = ath9k_hw_ani_get_listen_time(ah);
 	if (listenTime < 0) {
-		ahp->ah_stats.ast_ani_lneg++;
+		ah->stats.ast_ani_lneg++;
 		ath9k_ani_restart(ah);
 		return;
 	}
 
 	aniState->listenTime += listenTime;
 
-	if (ahp->ah_hasHwPhyCounters) {
+	if (ah->has_hw_phycounters) {
 		u32 phyCnt1, phyCnt2;
 		u32 ofdmPhyErrCnt, cckPhyErrCnt;
 
-		ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+		ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
 		phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
 		phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
@@ -604,27 +591,24 @@ void ath9k_hw_ani_monitor(struct ath_hal
 		}
 
 		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-		ahp->ah_stats.ast_ani_ofdmerrs +=
+		ah->stats.ast_ani_ofdmerrs +=
 			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
 		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
 
 		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-		ahp->ah_stats.ast_ani_cckerrs +=
+		ah->stats.ast_ani_cckerrs +=
 			cckPhyErrCnt - aniState->cckPhyErrCount;
 		aniState->cckPhyErrCount = cckPhyErrCnt;
 	}
 
-	if (!DO_ANI(ah))
-		return;
-
-	if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
+	if (aniState->listenTime > 5 * ah->aniperiod) {
 		if (aniState->ofdmPhyErrCount <= aniState->listenTime *
 		    aniState->ofdmTrigLow / 1000 &&
 		    aniState->cckPhyErrCount <= aniState->listenTime *
 		    aniState->cckTrigLow / 1000)
 			ath9k_hw_ani_lower_immunity(ah);
 		ath9k_ani_restart(ah);
-	} else if (aniState->listenTime > ahp->ah_aniPeriod) {
+	} else if (aniState->listenTime > ah->aniperiod) {
 		if (aniState->ofdmPhyErrCount > aniState->listenTime *
 		    aniState->ofdmTrigHigh / 1000) {
 			ath9k_hw_ani_ofdm_err_trigger(ah);
@@ -638,20 +622,16 @@ void ath9k_hw_ani_monitor(struct ath_hal
 	}
 }
 
-bool ath9k_hw_phycounters(struct ath_hal *ah)
+bool ath9k_hw_phycounters(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	return ahp->ah_hasHwPhyCounters ? true : false;
+	return ah->has_hw_phycounters ? true : false;
 }
 
-void ath9k_enable_mib_counters(struct ath_hal *ah)
+void ath9k_enable_mib_counters(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
 
-	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
 	REG_WRITE(ah, AR_FILT_OFDM, 0);
 	REG_WRITE(ah, AR_FILT_CCK, 0);
@@ -662,21 +642,18 @@ void ath9k_enable_mib_counters(struct at
 	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 }
 
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
+/* Freeze the MIB counters, get the stats and then clear them */
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
-
-	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
-
-	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
+	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+	REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
 	REG_WRITE(ah, AR_FILT_OFDM, 0);
 	REG_WRITE(ah, AR_FILT_CCK, 0);
 }
 
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
 				  u32 *rxc_pcnt,
 				  u32 *rxf_pcnt,
 				  u32 *txf_pcnt)
@@ -721,10 +698,9 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct
  * any of the MIB counters overflow/trigger so don't assume we're
  * here because a PHY error counter triggered.
  */
-void ath9k_hw_procmibevent(struct ath_hal *ah,
+void ath9k_hw_procmibevent(struct ath_hw *ah,
 			   const struct ath9k_node_stats *stats)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 phyCnt1, phyCnt2;
 
 	/* Reset these counters regardless */
@@ -734,8 +710,8 @@ void ath9k_hw_procmibevent(struct ath_ha
 		REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
 
 	/* Clear the mib counters and save them in the stats */
-	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-	ahp->ah_stats.ast_nodestats = *stats;
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+	ah->stats.ast_nodestats = *stats;
 
 	if (!DO_ANI(ah))
 		return;
@@ -745,17 +721,17 @@ void ath9k_hw_procmibevent(struct ath_ha
 	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
 	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
 	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
-		struct ar5416AniState *aniState = ahp->ah_curani;
+		struct ar5416AniState *aniState = ah->curani;
 		u32 ofdmPhyErrCnt, cckPhyErrCnt;
 
 		/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
 		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-		ahp->ah_stats.ast_ani_ofdmerrs +=
+		ah->stats.ast_ani_ofdmerrs +=
 			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
 		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
 
 		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-		ahp->ah_stats.ast_ani_cckerrs +=
+		ah->stats.ast_ani_cckerrs +=
 			cckPhyErrCnt - aniState->cckPhyErrCount;
 		aniState->cckPhyErrCount = cckPhyErrCnt;
 
@@ -774,9 +750,8 @@ void ath9k_hw_procmibevent(struct ath_ha
 	}
 }
 
-void ath9k_hw_ani_setup(struct ath_hal *ah)
+void ath9k_hw_ani_setup(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
@@ -785,66 +760,63 @@ void ath9k_hw_ani_setup(struct ath_hal *
 	const int firpwr[] = { -78, -78, -78, -78, -80 };
 
 	for (i = 0; i < 5; i++) {
-		ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
-		ahp->ah_coarseHigh[i] = coarseHigh[i];
-		ahp->ah_coarseLow[i] = coarseLow[i];
-		ahp->ah_firpwr[i] = firpwr[i];
+		ah->totalSizeDesired[i] = totalSizeDesired[i];
+		ah->coarse_high[i] = coarseHigh[i];
+		ah->coarse_low[i] = coarseLow[i];
+		ah->firpwr[i] = firpwr[i];
 	}
 }
 
-void ath9k_hw_ani_attach(struct ath_hal *ah)
+void ath9k_hw_ani_attach(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
 
-	ahp->ah_hasHwPhyCounters = 1;
+	ah->has_hw_phycounters = 1;
 
-	memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
-	for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
-		ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
-		ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
-		ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
-		ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
-		ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
-		ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
-		ahp->ah_ani[i].ofdmWeakSigDetectOff =
+	memset(ah->ani, 0, sizeof(ah->ani));
+	for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+		ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+		ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+		ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+		ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+		ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+		ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+		ah->ani[i].ofdmWeakSigDetectOff =
 			!ATH9K_ANI_USE_OFDM_WEAK_SIG;
-		ahp->ah_ani[i].cckWeakSigThreshold =
+		ah->ani[i].cckWeakSigThreshold =
 			ATH9K_ANI_CCK_WEAK_SIG_THR;
-		ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-		ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-		if (ahp->ah_hasHwPhyCounters) {
-			ahp->ah_ani[i].ofdmPhyErrBase =
+		ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+		ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+		if (ah->has_hw_phycounters) {
+			ah->ani[i].ofdmPhyErrBase =
 				AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
-			ahp->ah_ani[i].cckPhyErrBase =
+			ah->ani[i].cckPhyErrBase =
 				AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
 		}
 	}
-	if (ahp->ah_hasHwPhyCounters) {
+	if (ah->has_hw_phycounters) {
 		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
 			"Setting OfdmErrBase = 0x%08x\n",
-			ahp->ah_ani[0].ofdmPhyErrBase);
+			ah->ani[0].ofdmPhyErrBase);
 		DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-			ahp->ah_ani[0].cckPhyErrBase);
+			ah->ani[0].cckPhyErrBase);
 
-		REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
-		REG_WRITE(ah, AR_PHY_ERR_2, ahp->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);
 		ath9k_enable_mib_counters(ah);
 	}
-	ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
-	if (ah->ah_config.enable_ani)
-		ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
+	ah->aniperiod = ATH9K_ANI_PERIOD;
+	if (ah->config.enable_ani)
+		ah->proc_phyerr |= HAL_PROCESS_ANI;
 }
 
-void ath9k_hw_ani_detach(struct ath_hal *ah)
+void ath9k_hw_ani_detach(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
 
-	if (ahp->ah_hasHwPhyCounters) {
+	if (ah->has_hw_phycounters) {
 		ath9k_hw_disable_mib_counters(ah);
 		REG_WRITE(ah, AR_PHY_ERR_1, 0);
 		REG_WRITE(ah, AR_PHY_ERR_2, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ani.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ani.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ani.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ani.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,138 @@
+/*
+ * 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 ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI           0x00000001
+#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+
+#define HAL_EP_RND(x, mul)						\
+	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define BEACON_RSSI(ahp)					\
+	HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,	\
+		   ATH9K_RSSI_EP_MULTIPLIER)
+
+#define ATH9K_ANI_OFDM_TRIG_HIGH          500
+#define ATH9K_ANI_OFDM_TRIG_LOW           200
+#define ATH9K_ANI_CCK_TRIG_HIGH           200
+#define ATH9K_ANI_CCK_TRIG_LOW            100
+#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
+#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
+#define ATH9K_ANI_SPUR_IMMUNE_LVL         7
+#define ATH9K_ANI_FIRSTEP_LVL             0
+#define ATH9K_ANI_RSSI_THR_HIGH           40
+#define ATH9K_ANI_RSSI_THR_LOW            7
+#define ATH9K_ANI_PERIOD                  100
+
+#define HAL_NOISE_IMMUNE_MAX              4
+#define HAL_SPUR_IMMUNE_MAX               7
+#define HAL_FIRST_STEP_MAX                2
+
+enum ath9k_ani_cmd {
+	ATH9K_ANI_PRESENT = 0x1,
+	ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+	ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+	ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+	ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+	ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+	ATH9K_ANI_MODE = 0x40,
+	ATH9K_ANI_PHYERR_RESET = 0x80,
+	ATH9K_ANI_ALL = 0xff
+};
+
+struct ath9k_mib_stats {
+	u32 ackrcv_bad;
+	u32 rts_bad;
+	u32 rts_good;
+	u32 fcs_bad;
+	u32 beacons;
+};
+
+struct ath9k_node_stats {
+	u32 ns_avgbrssi;
+	u32 ns_avgrssi;
+	u32 ns_avgtxrssi;
+	u32 ns_avgtxrate;
+};
+
+struct ar5416AniState {
+	struct ath9k_channel *c;
+	u8 noiseImmunityLevel;
+	u8 spurImmunityLevel;
+	u8 firstepLevel;
+	u8 ofdmWeakSigDetectOff;
+	u8 cckWeakSigThreshold;
+	u32 listenTime;
+	u32 ofdmTrigHigh;
+	u32 ofdmTrigLow;
+	int32_t cckTrigHigh;
+	int32_t cckTrigLow;
+	int32_t rssiThrLow;
+	int32_t rssiThrHigh;
+	u32 noiseFloor;
+	u32 txFrameCount;
+	u32 rxFrameCount;
+	u32 cycleCount;
+	u32 ofdmPhyErrCount;
+	u32 cckPhyErrCount;
+	u32 ofdmPhyErrBase;
+	u32 cckPhyErrBase;
+	int16_t pktRssi[2];
+	int16_t ofdmErrRssi[2];
+	int16_t cckErrRssi[2];
+};
+
+struct ar5416Stats {
+	u32 ast_ani_niup;
+	u32 ast_ani_nidown;
+	u32 ast_ani_spurup;
+	u32 ast_ani_spurdown;
+	u32 ast_ani_ofdmon;
+	u32 ast_ani_ofdmoff;
+	u32 ast_ani_cckhigh;
+	u32 ast_ani_ccklow;
+	u32 ast_ani_stepup;
+	u32 ast_ani_stepdown;
+	u32 ast_ani_ofdmerrs;
+	u32 ast_ani_cckerrs;
+	u32 ast_ani_reset;
+	u32 ast_ani_lzero;
+	u32 ast_ani_lneg;
+	struct ath9k_mib_stats ast_mibstats;
+	struct ath9k_node_stats ast_nodestats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_ani_reset(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+			  const struct ath9k_node_stats *stats,
+			  struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hw *ah);
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
+				  u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+			   const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_attach(struct ath_hw *ah);
+void ath9k_hw_ani_detach(struct ath_hw *ah);
+
+#endif /* ANI_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ath9k.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ath9k.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/ath9k.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/ath9k.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -17,1041 +17,741 @@
 #ifndef ATH9K_H
 #define ATH9K_H
 
-#include <linux/io.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	AR_SUBVENDOR_ID_NOG	0x0e11
-#define AR_SUBVENDOR_ID_NEW_A	0x7065
-
-#define ATH9K_TXERR_XRETRY         0x01
-#define ATH9K_TXERR_FILT           0x02
-#define ATH9K_TXERR_FIFO           0x04
-#define ATH9K_TXERR_XTXOP          0x08
-#define ATH9K_TXERR_TIMER_EXPIRED  0x10
-
-#define ATH9K_TX_BA                0x01
-#define ATH9K_TX_PWRMGMT           0x02
-#define ATH9K_TX_DESC_CFG_ERR      0x04
-#define ATH9K_TX_DATA_UNDERRUN     0x08
-#define ATH9K_TX_DELIM_UNDERRUN    0x10
-#define ATH9K_TX_SW_ABORTED        0x40
-#define ATH9K_TX_SW_FILTERED       0x80
-
-#define NBBY    8
-
-struct ath_tx_status {
-	u32 ts_tstamp;
-	u16 ts_seqnum;
-	u8 ts_status;
-	u8 ts_ratecode;
-	u8 ts_rateindex;
-	int8_t ts_rssi;
-	u8 ts_shortretry;
-	u8 ts_longretry;
-	u8 ts_virtcol;
-	u8 ts_antenna;
-	u8 ts_flags;
-	int8_t ts_rssi_ctl0;
-	int8_t ts_rssi_ctl1;
-	int8_t ts_rssi_ctl2;
-	int8_t ts_rssi_ext0;
-	int8_t ts_rssi_ext1;
-	int8_t ts_rssi_ext2;
-	u8 pad[3];
-	u32 ba_low;
-	u32 ba_high;
-	u32 evm0;
-	u32 evm1;
-	u32 evm2;
-};
-
-struct ath_rx_status {
-	u32 rs_tstamp;
-	u16 rs_datalen;
-	u8 rs_status;
-	u8 rs_phyerr;
-	int8_t rs_rssi;
-	u8 rs_keyix;
-	u8 rs_rate;
-	u8 rs_antenna;
-	u8 rs_more;
-	int8_t rs_rssi_ctl0;
-	int8_t rs_rssi_ctl1;
-	int8_t rs_rssi_ctl2;
-	int8_t rs_rssi_ext0;
-	int8_t rs_rssi_ext1;
-	int8_t rs_rssi_ext2;
-	u8 rs_isaggr;
-	u8 rs_moreaggr;
-	u8 rs_num_delims;
-	u8 rs_flags;
-	u32 evm0;
-	u32 evm1;
-	u32 evm2;
-};
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
 
-#define ATH9K_RXERR_CRC           0x01
-#define ATH9K_RXERR_PHY           0x02
-#define ATH9K_RXERR_FIFO          0x04
-#define ATH9K_RXERR_DECRYPT       0x08
-#define ATH9K_RXERR_MIC           0x10
+#include "hw.h"
+#include "rc.h"
+#include "debug.h"
 
-#define ATH9K_RX_MORE             0x01
-#define ATH9K_RX_MORE_AGGR        0x02
-#define ATH9K_RX_GI               0x04
-#define ATH9K_RX_2040             0x08
-#define ATH9K_RX_DELIM_CRC_PRE    0x10
-#define ATH9K_RX_DELIM_CRC_POST   0x20
-#define ATH9K_RX_DECRYPT_BUSY     0x40
+struct ath_node;
 
-#define ATH9K_RXKEYIX_INVALID	((u8)-1)
-#define ATH9K_TXKEYIX_INVALID	((u32)-1)
+/* Macro to expand scalars to 64-bit objects */
 
-struct ath_desc {
-	u32 ds_link;
-	u32 ds_data;
-	u32 ds_ctl0;
-	u32 ds_ctl1;
-	u32 ds_hw[20];
-	union {
-		struct ath_tx_status tx;
-		struct ath_rx_status rx;
-		void *stats;
-	} ds_us;
-	void *ds_vdata;
-} __packed;
+#define	ito64(x) (sizeof(x) == 8) ?			\
+	(((unsigned long long int)(x)) & (0xff)) :	\
+	(sizeof(x) == 16) ?				\
+	(((unsigned long long int)(x)) & 0xffff) :	\
+	((sizeof(x) == 32) ?				\
+	 (((unsigned long long int)(x)) & 0xffffffff) : \
+	 (unsigned long long int)(x))
 
-#define	ds_txstat	ds_us.tx
-#define	ds_rxstat	ds_us.rx
-#define ds_stat		ds_us.stats
+/* increment with wrap-around */
+#define INCR(_l, _sz)   do {			\
+		(_l)++;				\
+		(_l) &= ((_sz) - 1);		\
+	} while (0)
 
-#define ATH9K_TXDESC_CLRDMASK		0x0001
-#define ATH9K_TXDESC_NOACK		0x0002
-#define ATH9K_TXDESC_RTSENA		0x0004
-#define ATH9K_TXDESC_CTSENA		0x0008
-/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
- * the descriptor its marked on.  We take a tx interrupt to reap
- * descriptors when the h/w hits an EOL condition or
- * when the descriptor is specifically marked to generate
- * an interrupt with this flag. Descriptors should be
- * marked periodically to insure timely replenishing of the
- * supply needed for sending frames. Defering interrupts
- * reduces system load and potentially allows more concurrent
- * work to be done but if done to aggressively can cause
- * senders to backup. When the hardware queue is left too
- * large rate control information may also be too out of
- * date. An Alternative for this is TX interrupt mitigation
- * but this needs more testing. */
-#define ATH9K_TXDESC_INTREQ		0x0010
-#define ATH9K_TXDESC_VEOL		0x0020
-#define ATH9K_TXDESC_EXT_ONLY		0x0040
-#define ATH9K_TXDESC_EXT_AND_CTL	0x0080
-#define ATH9K_TXDESC_VMF		0x0100
-#define ATH9K_TXDESC_FRAG_IS_ON 	0x0200
-#define ATH9K_TXDESC_CAB		0x0400
+/* decrement with wrap-around */
+#define DECR(_l,  _sz)  do {			\
+		(_l)--;				\
+		(_l) &= ((_sz) - 1);		\
+	} while (0)
 
-#define ATH9K_RXDESC_INTREQ		0x0020
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
 
-enum wireless_mode {
-	ATH9K_MODE_11A = 0,
-	ATH9K_MODE_11B = 2,
-	ATH9K_MODE_11G = 3,
-	ATH9K_MODE_11NA_HT20 = 6,
-	ATH9K_MODE_11NG_HT20 = 7,
-	ATH9K_MODE_11NA_HT40PLUS = 8,
-	ATH9K_MODE_11NA_HT40MINUS = 9,
-	ATH9K_MODE_11NG_HT40PLUS = 10,
-	ATH9K_MODE_11NG_HT40MINUS = 11,
-	ATH9K_MODE_MAX
-};
+#define ASSERT(exp) do {			\
+		if (unlikely(!(exp))) {		\
+			BUG();			\
+		}				\
+	} while (0)
 
-enum ath9k_hw_caps {
-	ATH9K_HW_CAP_CHAN_SPREAD		= BIT(0),
-	ATH9K_HW_CAP_MIC_AESCCM                 = BIT(1),
-	ATH9K_HW_CAP_MIC_CKIP                   = BIT(2),
-	ATH9K_HW_CAP_MIC_TKIP                   = BIT(3),
-	ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(4),
-	ATH9K_HW_CAP_CIPHER_CKIP                = BIT(5),
-	ATH9K_HW_CAP_CIPHER_TKIP                = BIT(6),
-	ATH9K_HW_CAP_VEOL                       = BIT(7),
-	ATH9K_HW_CAP_BSSIDMASK                  = BIT(8),
-	ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(9),
-	ATH9K_HW_CAP_CHAN_HALFRATE              = BIT(10),
-	ATH9K_HW_CAP_CHAN_QUARTERRATE           = BIT(11),
-	ATH9K_HW_CAP_HT                         = BIT(12),
-	ATH9K_HW_CAP_GTT                        = BIT(13),
-	ATH9K_HW_CAP_FASTCC                     = BIT(14),
-	ATH9K_HW_CAP_RFSILENT                   = BIT(15),
-	ATH9K_HW_CAP_WOW                        = BIT(16),
-	ATH9K_HW_CAP_CST                        = BIT(17),
-	ATH9K_HW_CAP_ENHANCEDPM                 = BIT(18),
-	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(19),
-	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(20),
-	ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT     = BIT(21),
-};
+#define TSF_TO_TU(_h,_l) \
+	((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
-enum ath9k_capability_type {
-	ATH9K_CAP_CIPHER = 0,
-	ATH9K_CAP_TKIP_MIC,
-	ATH9K_CAP_TKIP_SPLIT,
-	ATH9K_CAP_PHYCOUNTERS,
-	ATH9K_CAP_DIVERSITY,
-	ATH9K_CAP_TXPOW,
-	ATH9K_CAP_PHYDIAG,
-	ATH9K_CAP_MCAST_KEYSRCH,
-	ATH9K_CAP_TSF_ADJUST,
-	ATH9K_CAP_WME_TKIPMIC,
-	ATH9K_CAP_RFSILENT,
-	ATH9K_CAP_ANT_CFG_2GHZ,
-	ATH9K_CAP_ANT_CFG_5GHZ
-};
+#define	ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
 
-struct ath9k_hw_capabilities {
-	u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-	DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
-	u16 total_queues;
-	u16 keycache_size;
-	u16 low_5ghz_chan, high_5ghz_chan;
-	u16 low_2ghz_chan, high_2ghz_chan;
-	u16 num_mr_retries;
-	u16 rts_aggr_limit;
-	u8 tx_chainmask;
-	u8 rx_chainmask;
-	u16 tx_triglevel_max;
-	u16 reg_cap;
-	u8 num_gpio_pins;
-	u8 num_antcfg_2ghz;
-	u8 num_antcfg_5ghz;
-};
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-struct ath9k_ops_config {
-	int dma_beacon_response_time;
-	int sw_beacon_response_time;
-	int additional_swba_backoff;
-	int ack_6mb;
-	int cwm_ignore_extcca;
-	u8 pcie_powersave_enable;
-	u8 pcie_l1skp_enable;
-	u8 pcie_clock_req;
-	u32 pcie_waen;
-	int pcie_power_reset;
-	u8 pcie_restore;
-	u8 analog_shiftreg;
-	u8 ht_enable;
-	u32 ofdm_trig_low;
-	u32 ofdm_trig_high;
-	u32 cck_trig_high;
-	u32 cck_trig_low;
-	u32 enable_ani;
-	u8 noise_immunity_level;
-	u32 ofdm_weaksignal_det;
-	u32 cck_weaksignal_thr;
-	u8 spur_immunity_level;
-	u8 firstep_level;
-	int8_t rssi_thr_high;
-	int8_t rssi_thr_low;
-	u16 diversity_control;
-	u16 antenna_switch_swap;
-	int serialize_regmode;
-	int intr_mitigation;
-#define SPUR_DISABLE        	0
-#define SPUR_ENABLE_IOCTL   	1
-#define SPUR_ENABLE_EEPROM  	2
-#define AR_EEPROM_MODAL_SPURS   5
-#define AR_SPUR_5413_1      	1640
-#define AR_SPUR_5413_2      	1200
-#define AR_NO_SPUR      	0x8000
-#define AR_BASE_FREQ_2GHZ   	2300
-#define AR_BASE_FREQ_5GHZ   	4900
-#define AR_SPUR_FEEQ_BOUND_HT40 19
-#define AR_SPUR_FEEQ_BOUND_HT20 10
-	int spurmode;
-	u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+struct ath_config {
+	u32 ath_aggr_prot;
+	u16 txpowlimit;
+	u8 cabqReadytime;
+	u8 swBeaconProcess;
 };
 
-enum ath9k_tx_queue {
-	ATH9K_TX_QUEUE_INACTIVE = 0,
-	ATH9K_TX_QUEUE_DATA,
-	ATH9K_TX_QUEUE_BEACON,
-	ATH9K_TX_QUEUE_CAB,
-	ATH9K_TX_QUEUE_UAPSD,
-	ATH9K_TX_QUEUE_PSPOLL
-};
+/*************************/
+/* Descriptor Management */
+/*************************/
 
-#define	ATH9K_NUM_TX_QUEUES 10
+#define ATH_TXBUF_RESET(_bf) do {				\
+		(_bf)->bf_status = 0;				\
+		(_bf)->bf_lastbf = NULL;			\
+		(_bf)->bf_next = NULL;				\
+		memset(&((_bf)->bf_state), 0,			\
+		       sizeof(struct ath_buf_state));		\
+	} while (0)
 
-enum ath9k_tx_queue_subtype {
-	ATH9K_WME_AC_BK = 0,
-	ATH9K_WME_AC_BE,
-	ATH9K_WME_AC_VI,
-	ATH9K_WME_AC_VO,
-	ATH9K_WME_UPSD
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_HT: Send this buffer using HT capabilities
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ *	(used in aggregation scheduling)
+ * @BUF_RETRY: Indicates whether the buffer is retried
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+	BUF_HT			= BIT(1),
+	BUF_AMPDU		= BIT(2),
+	BUF_AGGR		= BIT(3),
+	BUF_RETRY		= BIT(4),
+	BUF_XRETRY		= BIT(5),
 };
 
-enum ath9k_tx_queue_flags {
-	TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
-	TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
-	TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
-	TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
-	TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
-	TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
-	TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
-	TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
-	TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+struct ath_buf_state {
+	int bfs_nframes;
+	u16 bfs_al;
+	u16 bfs_frmlen;
+	int bfs_seqno;
+	int bfs_tidno;
+	int bfs_retries;
+	u32 bf_type;
+	u32 bfs_keyix;
+	enum ath9k_key_type bfs_keytype;
 };
 
-#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
-
-#define ATH9K_DECOMP_MASK_SIZE     128
-#define ATH9K_READY_TIME_LO_BOUND  50
-#define ATH9K_READY_TIME_HI_BOUND  96
+#define bf_nframes      	bf_state.bfs_nframes
+#define bf_al           	bf_state.bfs_al
+#define bf_frmlen       	bf_state.bfs_frmlen
+#define bf_retries      	bf_state.bfs_retries
+#define bf_seqno        	bf_state.bfs_seqno
+#define bf_tidno        	bf_state.bfs_tidno
+#define bf_keyix                bf_state.bfs_keyix
+#define bf_keytype      	bf_state.bfs_keytype
+#define bf_isht(bf)		(bf->bf_state.bf_type & BUF_HT)
+#define bf_isampdu(bf)		(bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf)		(bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
+#define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
 
-enum ath9k_pkt_type {
-	ATH9K_PKT_TYPE_NORMAL = 0,
-	ATH9K_PKT_TYPE_ATIM,
-	ATH9K_PKT_TYPE_PSPOLL,
-	ATH9K_PKT_TYPE_BEACON,
-	ATH9K_PKT_TYPE_PROBE_RESP,
-	ATH9K_PKT_TYPE_CHIRP,
-	ATH9K_PKT_TYPE_GRP_POLL,
+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 */
+	void *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 */
+	u32 bf_status;
+	u16 bf_flags;
+	struct ath_buf_state bf_state;
+	dma_addr_t bf_dmacontext;
 };
 
-struct ath9k_tx_queue_info {
-	u32 tqi_ver;
-	enum ath9k_tx_queue tqi_type;
-	enum ath9k_tx_queue_subtype tqi_subtype;
-	enum ath9k_tx_queue_flags tqi_qflags;
-	u32 tqi_priority;
-	u32 tqi_aifs;
-	u32 tqi_cwmin;
-	u32 tqi_cwmax;
-	u16 tqi_shretry;
-	u16 tqi_lgretry;
-	u32 tqi_cbrPeriod;
-	u32 tqi_cbrOverflowLimit;
-	u32 tqi_burstTime;
-	u32 tqi_readyTime;
-	u32 tqi_physCompBuf;
-	u32 tqi_intFlags;
-};
+#define ATH_RXBUF_RESET(_bf)    ((_bf)->bf_status = 0)
+#define ATH_BUFSTATUS_STALE     0x00000002
 
-enum ath9k_rx_filter {
-	ATH9K_RX_FILTER_UCAST = 0x00000001,
-	ATH9K_RX_FILTER_MCAST = 0x00000002,
-	ATH9K_RX_FILTER_BCAST = 0x00000004,
-	ATH9K_RX_FILTER_CONTROL = 0x00000008,
-	ATH9K_RX_FILTER_BEACON = 0x00000010,
-	ATH9K_RX_FILTER_PROM = 0x00000020,
-	ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
-	ATH9K_RX_FILTER_PSPOLL = 0x00004000,
-	ATH9K_RX_FILTER_PHYERR = 0x00000100,
-	ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+struct ath_descdma {
+	const char *dd_name;
+	struct ath_desc *dd_desc;
+	dma_addr_t dd_desc_paddr;
+	u32 dd_desc_len;
+	struct ath_buf *dd_bufptr;
+	dma_addr_t dd_dmacontext;
 };
 
-enum ath9k_int {
-	ATH9K_INT_RX = 0x00000001,
-	ATH9K_INT_RXDESC = 0x00000002,
-	ATH9K_INT_RXNOFRM = 0x00000008,
-	ATH9K_INT_RXEOL = 0x00000010,
-	ATH9K_INT_RXORN = 0x00000020,
-	ATH9K_INT_TX = 0x00000040,
-	ATH9K_INT_TXDESC = 0x00000080,
-	ATH9K_INT_TIM_TIMER = 0x00000100,
-	ATH9K_INT_TXURN = 0x00000800,
-	ATH9K_INT_MIB = 0x00001000,
-	ATH9K_INT_RXPHY = 0x00004000,
-	ATH9K_INT_RXKCM = 0x00008000,
-	ATH9K_INT_SWBA = 0x00010000,
-	ATH9K_INT_BMISS = 0x00040000,
-	ATH9K_INT_BNR = 0x00100000,
-	ATH9K_INT_TIM = 0x00200000,
-	ATH9K_INT_DTIM = 0x00400000,
-	ATH9K_INT_DTIMSYNC = 0x00800000,
-	ATH9K_INT_GPIO = 0x01000000,
-	ATH9K_INT_CABEND = 0x02000000,
-	ATH9K_INT_CST = 0x10000000,
-	ATH9K_INT_GTT = 0x20000000,
-	ATH9K_INT_FATAL = 0x40000000,
-	ATH9K_INT_GLOBAL = 0x80000000,
-	ATH9K_INT_BMISC = ATH9K_INT_TIM |
-		ATH9K_INT_DTIM |
-		ATH9K_INT_DTIMSYNC |
-		ATH9K_INT_CABEND,
-	ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
-		ATH9K_INT_RXDESC |
-		ATH9K_INT_RXEOL |
-		ATH9K_INT_RXORN |
-		ATH9K_INT_TXURN |
-		ATH9K_INT_TXDESC |
-		ATH9K_INT_MIB |
-		ATH9K_INT_RXPHY |
-		ATH9K_INT_RXKCM |
-		ATH9K_INT_SWBA |
-		ATH9K_INT_BMISS |
-		ATH9K_INT_GPIO,
-	ATH9K_INT_NOCARD = 0xffffffff
-};
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+		      struct list_head *head, const char *name,
+		      int nbuf, int ndesc);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+			 struct list_head *head);
 
-#define ATH9K_RATESERIES_RTS_CTS  0x0001
-#define ATH9K_RATESERIES_2040     0x0002
-#define ATH9K_RATESERIES_HALFGI   0x0004
+/***********/
+/* RX / TX */
+/***********/
 
-struct ath9k_11n_rate_series {
-	u32 Tries;
-	u32 Rate;
-	u32 PktDuration;
-	u32 ChSel;
-	u32 RateFlags;
-};
+#define ATH_MAX_ANTENNA         3
+#define ATH_RXBUF               512
+#define WME_NUM_TID             16
+#define ATH_TXBUF               512
+#define ATH_TXMAXTRY            13
+#define ATH_11N_TXMAXTRY        10
+#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 CHANNEL_CW_INT    0x00002
-#define CHANNEL_CCK       0x00020
-#define CHANNEL_OFDM      0x00040
-#define CHANNEL_2GHZ      0x00080
-#define CHANNEL_5GHZ      0x00100
-#define CHANNEL_PASSIVE   0x00200
-#define CHANNEL_DYN       0x00400
-#define CHANNEL_HALF      0x04000
-#define CHANNEL_QUARTER   0x08000
-#define CHANNEL_HT20      0x10000
-#define CHANNEL_HT40PLUS  0x20000
-#define CHANNEL_HT40MINUS 0x40000
+#define TID_TO_WME_AC(_tid)				\
+	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
+	 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK :	\
+	 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI :	\
+	 WME_AC_VO)
 
-#define CHANNEL_INTERFERENCE    0x01
-#define CHANNEL_DFS             0x02
-#define CHANNEL_4MS_LIMIT       0x04
-#define CHANNEL_DFS_CLEAR       0x08
-#define CHANNEL_DISALLOW_ADHOC  0x10
-#define CHANNEL_PER_11D_ADHOC   0x20
+#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 CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
-#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
-#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
-#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_ALL				\
-	(CHANNEL_OFDM|				\
-	 CHANNEL_CCK|				\
-	 CHANNEL_2GHZ |				\
-	 CHANNEL_5GHZ |				\
-	 CHANNEL_HT20 |				\
-	 CHANNEL_HT40PLUS |			\
-	 CHANNEL_HT40MINUS)
+#define ADDBA_EXCHANGE_ATTEMPTS    10
+#define ATH_AGGR_DELIM_SZ          4
+#define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM      10
+/* 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 ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
 
-struct ath9k_channel {
-	u16 channel;
-	u32 channelFlags;
-	u8 privFlags;
-	int8_t maxRegTxPower;
-	int8_t maxTxPower;
-	int8_t minTxPower;
-	u32 chanmode;
-	int32_t CalValid;
-	bool oneTimeCalsDone;
-	int8_t iCoff;
-	int8_t qCoff;
-	int16_t rawNoiseFloor;
-	int8_t antennaMax;
-	u32 regDmnFlags;
-	u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
-#ifdef ATH_NF_PER_CHAN
-	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-#endif
-};
+#define IEEE80211_SEQ_SEQ_SHIFT    4
+#define IEEE80211_SEQ_MAX          4096
+#define IEEE80211_MIN_AMPDU_BUF    0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+#define IEEE80211_WEP_IVLEN        3
+#define IEEE80211_WEP_KIDLEN       1
+#define IEEE80211_WEP_CRCLEN       4
+#define IEEE80211_MAX_MPDU_LEN     (3840 + FCS_LEN +		\
+				    (IEEE80211_WEP_IVLEN +	\
+				     IEEE80211_WEP_KIDLEN +	\
+				     IEEE80211_WEP_CRCLEN))
 
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
-       (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
-       (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
-       (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
-#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
-       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
-       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
-       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
-#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
-#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
-#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
-#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap  */
+#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&		\
+				((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
 
-/* These macros check chanmode and not channelFlags */
-#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
-#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||	\
-			  ((_c)->chanmode == CHANNEL_G_HT20))
-#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||	\
-			  ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||	\
-			  ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||	\
-			  ((_c)->chanmode == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
 
-#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
-#define IS_CHAN_A_5MHZ_SPACED(_c)			\
-	((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&	\
-	 (((_c)->channel % 20) != 0) &&			\
-	 (((_c)->channel % 10) != 0))
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len)					\
+	(((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?           \
+	  (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
 
-struct ath9k_keyval {
-	u8 kv_type;
-	u8 kv_pad;
-	u16 kv_len;
-	u8 kv_val[16];
-	u8 kv_mic[8];
-	u8 kv_txmic[8];
-};
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+	((((_seqno) - (_start)) & 4095) < (_bawsz))
 
-enum ath9k_key_type {
-	ATH9K_KEY_TYPE_CLEAR,
-	ATH9K_KEY_TYPE_WEP,
-	ATH9K_KEY_TYPE_AES,
-	ATH9K_KEY_TYPE_TKIP,
-};
+#define ATH_DS_BA_SEQ(_ds)         ((_ds)->ds_us.tx.ts_seqnum)
+#define ATH_DS_BA_BITMAP(_ds)      (&(_ds)->ds_us.tx.ba_low)
+#define ATH_DS_TX_BA(_ds)          ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
 
-enum ath9k_cipher {
-	ATH9K_CIPHER_WEP = 0,
-	ATH9K_CIPHER_AES_OCB = 1,
-	ATH9K_CIPHER_AES_CCM = 2,
-	ATH9K_CIPHER_CKIP = 3,
-	ATH9K_CIPHER_TKIP = 4,
-	ATH9K_CIPHER_CLR = 5,
-	ATH9K_CIPHER_MIC = 127
+enum ATH_AGGR_STATUS {
+	ATH_AGGR_DONE,
+	ATH_AGGR_BAW_CLOSED,
+	ATH_AGGR_LIMITED,
 };
 
-#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
-#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
-#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
-#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
-#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
-#define AR_EEPROM_EEPCAP_MAXQCU_S       4
-#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
-#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
-#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
-
-#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
-#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
-#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
-
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
-
-#define SD_NO_CTL               0xE0
-#define NO_CTL                  0xff
-#define CTL_MODE_M              7
-#define CTL_11A                 0
-#define CTL_11B                 1
-#define CTL_11G                 2
-#define CTL_2GHT20              5
-#define CTL_5GHT20              6
-#define CTL_2GHT40              7
-#define CTL_5GHT40              8
-
-#define AR_EEPROM_MAC(i)        (0x1d+(i))
-
-#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
-#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
-#define AR_EEPROM_RFSILENT_POLARITY     0x0002
-#define AR_EEPROM_RFSILENT_POLARITY_S   1
+struct ath_txq {
+	u32 axq_qnum;
+	u32 *axq_link;
+	struct list_head axq_q;
+	spinlock_t axq_lock;
+	u32 axq_depth;
+	u8 axq_aggr_depth;
+	u32 axq_totalqueued;
+	bool stopped;
+	struct ath_buf *axq_linkbuf;
 
-#define CTRY_DEBUG 0x1ff
-#define	CTRY_DEFAULT 0
+	/* first desc of the last descriptor that contains CTS */
+	struct ath_desc *axq_lastdsWithCTS;
 
-enum reg_ext_bitmap {
-	REG_EXT_JAPAN_MIDBAND = 1,
-	REG_EXT_FCC_DFS_HT40 = 2,
-	REG_EXT_JAPAN_NONDFS_HT40 = 3,
-	REG_EXT_JAPAN_DFS_HT40 = 4
-};
+	/* final desc of the gating desc that determines whether
+	   lastdsWithCTS has been DMA'ed or not */
+	struct ath_desc *axq_gatingds;
 
-struct ath9k_country_entry {
-	u16 countryCode;
-	u16 regDmnEnum;
-	u16 regDmn5G;
-	u16 regDmn2G;
-	u8 isMultidomain;
-	u8 iso[3];
+	struct list_head axq_acq;
 };
 
-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
-
-#define SM(_v, _f)  (((_v) << _f##_S) & _f)
-#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr)    \
-	REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
-#define REG_RMW_FIELD(_a, _r, _f, _v) \
-	REG_WRITE(_a, _r, \
-	(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
-#define REG_SET_BIT(_a, _r, _f) \
-	REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
-#define REG_CLR_BIT(_a, _r, _f) \
-	REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-
-#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS   0x00000001
-
-#define INIT_AIFS       2
-#define INIT_CWMIN      15
-#define INIT_CWMIN_11B  31
-#define INIT_CWMAX      1023
-#define INIT_SH_RETRY   10
-#define INIT_LG_RETRY   10
-#define INIT_SSH_RETRY  32
-#define INIT_SLG_RETRY  32
-
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
-
-#define ATH_AMPDU_LIMIT_MAX      (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT  ATH_AMPDU_LIMIT_MAX
-
-#define IEEE80211_WEP_IVLEN      3
-#define IEEE80211_WEP_KIDLEN     1
-#define IEEE80211_WEP_CRCLEN     4
-#define IEEE80211_MAX_MPDU_LEN  (3840 + FCS_LEN +		\
-				 (IEEE80211_WEP_IVLEN +		\
-				  IEEE80211_WEP_KIDLEN +	\
-				  IEEE80211_WEP_CRCLEN))
-#define MAX_RATE_POWER 63
-
-enum ath9k_power_mode {
-	ATH9K_PM_AWAKE = 0,
-	ATH9K_PM_FULL_SLEEP,
-	ATH9K_PM_NETWORK_SLEEP,
-	ATH9K_PM_UNDEFINED
-};
+#define AGGR_CLEANUP         BIT(1)
+#define AGGR_ADDBA_COMPLETE  BIT(2)
+#define AGGR_ADDBA_PROGRESS  BIT(3)
 
-struct ath9k_mib_stats {
-	u32 ackrcv_bad;
-	u32 rts_bad;
-	u32 rts_good;
-	u32 fcs_bad;
-	u32 beacons;
+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;
+	int addba_exchangeattempts;
 };
 
-enum ath9k_ant_setting {
-	ATH9K_ANT_VARIABLE = 0,
-	ATH9K_ANT_FIXED_A,
-	ATH9K_ANT_FIXED_B
+struct ath_atx_ac {
+	int sched;
+	int qnum;
+	struct list_head list;
+	struct list_head tid_q;
 };
 
-#define ATH9K_SLOT_TIME_6 6
-#define ATH9K_SLOT_TIME_9 9
-#define ATH9K_SLOT_TIME_20 20
-
-enum ath9k_ht_macmode {
-	ATH9K_HT_MACMODE_20 = 0,
-	ATH9K_HT_MACMODE_2040 = 1,
+struct ath_tx_control {
+	struct ath_txq *txq;
+	int if_id;
+	enum ath9k_internal_frame_type frame_type;
 };
 
-enum ath9k_ht_extprotspacing {
-	ATH9K_HT_EXTPROTSPACING_20 = 0,
-	ATH9K_HT_EXTPROTSPACING_25 = 1,
-};
+#define ATH_TX_ERROR        0x01
+#define ATH_TX_XRETRY       0x02
+#define ATH_TX_BAR          0x04
 
-struct ath9k_ht_cwm {
-	enum ath9k_ht_macmode ht_macmode;
-	enum ath9k_ht_extprotspacing ht_extprotspacing;
+/* All RSSI values are noise floor adjusted */
+struct ath_tx_stat {
+	int rssi;
+	int rssictl[ATH_MAX_ANTENNA];
+	int rssiextn[ATH_MAX_ANTENNA];
+	int rateieee;
+	int rateKbps;
+	int ratecode;
+	int flags;
+	u32 airtime;	/* time on air per final tx rate */
 };
 
-enum ath9k_ani_cmd {
-	ATH9K_ANI_PRESENT = 0x1,
-	ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
-	ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
-	ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
-	ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
-	ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
-	ATH9K_ANI_MODE = 0x40,
-	ATH9K_ANI_PHYERR_RESET = 0x80,
-	ATH9K_ANI_ALL = 0xff
+struct aggr_rifs_param {
+	int param_max_frames;
+	int param_max_len;
+	int param_rl;
+	int param_al;
+	struct ath_rc_series *param_rcs;
 };
 
-enum {
-	WLAN_RC_PHY_OFDM,
-	WLAN_RC_PHY_CCK,
-	WLAN_RC_PHY_HT_20_SS,
-	WLAN_RC_PHY_HT_20_DS,
-	WLAN_RC_PHY_HT_40_SS,
-	WLAN_RC_PHY_HT_40_DS,
-	WLAN_RC_PHY_HT_20_SS_HGI,
-	WLAN_RC_PHY_HT_20_DS_HGI,
-	WLAN_RC_PHY_HT_40_SS_HGI,
-	WLAN_RC_PHY_HT_40_DS_HGI,
-	WLAN_RC_PHY_MAX
+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;
 };
 
-enum ath9k_tp_scale {
-	ATH9K_TP_SCALE_MAX = 0,
-	ATH9K_TP_SCALE_50,
-	ATH9K_TP_SCALE_25,
-	ATH9K_TP_SCALE_12,
-	ATH9K_TP_SCALE_MIN
+struct ath_tx {
+	u16 seq_no;
+	u32 txqsetup;
+	int hwq_map[ATH9K_WME_AC_VO+1];
+	spinlock_t txbuflock;
+	struct list_head txbuf;
+	struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+	struct ath_descdma txdma;
 };
 
-enum ser_reg_mode {
-	SER_REG_MODE_OFF = 0,
-	SER_REG_MODE_ON = 1,
-	SER_REG_MODE_AUTO = 2,
+struct ath_rx {
+	u8 defant;
+	u8 rxotherant;
+	u32 *rxlink;
+	int bufsize;
+	unsigned int rxfilter;
+	spinlock_t rxflushlock;
+	spinlock_t rxbuflock;
+	struct list_head rxbuf;
+	struct ath_descdma rxdma;
 };
 
-#define AR_PHY_CCA_MAX_GOOD_VALUE      		-85
-#define AR_PHY_CCA_MAX_HIGH_VALUE      		-62
-#define AR_PHY_CCA_MIN_BAD_VALUE       		-121
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_setup(struct ath_softc *sc, int haltype);
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+		     struct ath_txq *txq, bool retry_tx);
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+int ath_tx_cleanup(struct ath_softc *sc);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+		   struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+		 struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+		      u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 
-#define ATH9K_NF_CAL_HIST_MAX           5
-#define NUM_NF_READINGS                 6
+/********/
+/* VIFs */
+/********/
 
-struct ath9k_nfcal_hist {
-	int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
-	u8 currIndex;
-	int16_t privNF;
-	u8 invalidNFcount;
+struct ath_vif {
+	int av_bslot;
+	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
+	enum nl80211_iftype av_opmode;
+	struct ath_buf *av_bcbuf;
+	struct ath_tx_control av_btxctl;
+	u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
 };
 
-struct ath9k_beacon_state {
-	u32 bs_nexttbtt;
-	u32 bs_nextdtim;
-	u32 bs_intval;
-#define ATH9K_BEACON_PERIOD       0x0000ffff
-#define ATH9K_BEACON_ENA          0x00800000
-#define ATH9K_BEACON_RESET_TSF    0x01000000
-	u32 bs_dtimperiod;
-	u16 bs_cfpperiod;
-	u16 bs_cfpmaxduration;
-	u32 bs_cfpnext;
-	u16 bs_timoffset;
-	u16 bs_bmissthreshold;
-	u32 bs_sleepduration;
-};
+/*******************/
+/* Beacon Handling */
+/*******************/
 
-struct ath9k_node_stats {
-	u32 ns_avgbrssi;
-	u32 ns_avgrssi;
-	u32 ns_avgtxrssi;
-	u32 ns_avgtxrate;
-};
+/*
+ * Regardless of the number of beacons we stagger, (i.e. regardless of the
+ * number of BSSIDs) if a given beacon does not go out even after waiting this
+ * number of beacon intervals, the game's up.
+ */
+#define BSTUCK_THRESH           	(9 * ATH_BCBUF)
+#define	ATH_BCBUF               	4
+#define ATH_DEFAULT_BINTVAL     	100 /* TU */
+#define ATH_DEFAULT_BMISS_LIMIT 	10
+#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
 
-#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
+struct ath_beacon_config {
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 dtim_period;
+	u16 bmiss_timeout;
+	u8 dtim_count;
+};
 
-#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
+struct ath_beacon {
+	enum {
+		OK,		/* no change needed */
+		UPDATE,		/* update pending */
+		COMMIT		/* beacon sent, commit change */
+	} updateslot;		/* slot time update fsm */
 
-enum {
-	ATH9K_RESET_POWER_ON,
-	ATH9K_RESET_WARM,
-	ATH9K_RESET_COLD,
+	u32 beaconq;
+	u32 bmisscnt;
+	u32 ast_be_xmit;
+	u64 bc_tstamp;
+	struct ieee80211_vif *bslot[ATH_BCBUF];
+	struct ath_wiphy *bslot_aphy[ATH_BCBUF];
+	int slottime;
+	int slotupdate;
+	struct ath9k_tx_queue_info beacon_qi;
+	struct ath_descdma bdma;
+	struct ath_txq *cabq;
+	struct list_head bbuf;
 };
 
-#define AH_USE_EEPROM   0x1
-
-struct ath_hal {
-	u32 ah_magic;
-	u16 ah_devid;
-	u16 ah_subvendorid;
-	u32 ah_macVersion;
-	u16 ah_macRev;
-	u16 ah_phyRev;
-	u16 ah_analog5GhzRev;
-	u16 ah_analog2GhzRev;
+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);
 
-	void __iomem *ah_sh;
-	struct ath_softc *ah_sc;
+/*******/
+/* ANI */
+/*******/
 
-	enum nl80211_iftype ah_opmode;
-	struct ath9k_ops_config ah_config;
-	struct ath9k_hw_capabilities ah_caps;
+#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
+#define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
+#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
 
-	u16 ah_countryCode;
-	u32 ah_flags;
-	int16_t ah_powerLimit;
-	u16 ah_maxPowerLevel;
-	u32 ah_tpScale;
-	u16 ah_currentRD;
-	u16 ah_currentRDExt;
-	u16 ah_currentRDInUse;
-	u16 ah_currentRD5G;
-	u16 ah_currentRD2G;
-	char ah_iso[4];
+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;
+};
 
-	struct ath9k_channel ah_channels[150];
-	struct ath9k_channel *ah_curchan;
-	u32 ah_nchan;
+/********************/
+/*   LED Control    */
+/********************/
 
-	bool ah_isPciExpress;
-	u16 ah_txTrigLevel;
-	u16 ah_rfsilent;
-	u32 ah_rfkill_gpio;
-	u32 ah_rfkill_polarity;
+#define ATH_LED_PIN	1
+#define ATH_LED_ON_DURATION_IDLE	350	/* in msecs */
+#define ATH_LED_OFF_DURATION_IDLE	250	/* in msecs */
 
-#ifndef ATH_NF_PER_CHAN
-	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-#endif
+enum ath_led_type {
+	ATH_LED_RADIO,
+	ATH_LED_ASSOC,
+	ATH_LED_TX,
+	ATH_LED_RX
 };
 
-struct chan_centers {
-	u16 synth_center;
-	u16 ctl_center;
-	u16 ext_center;
+struct ath_led {
+	struct ath_softc *sc;
+	struct led_classdev led_cdev;
+	enum ath_led_type led_type;
+	char name[32];
+	bool registered;
 };
 
-struct ath_rate_table;
-
-/* Helpers */
+/* Rfkill */
+#define ATH_RFKILL_POLL_INTERVAL	2000 /* msecs */
 
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
-			       const struct ath9k_channel *chan);
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hal *ah,
-			     u16 flags, u16 *low,
-			     u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
-			   struct ath_rate_table *rates,
-			   u32 frameLen, u16 rateix,
-			   bool shortPreamble);
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
-				  struct ath9k_channel *chan,
-				  struct chan_centers *centers);
+struct ath_rfkill {
+	struct rfkill *rfkill;
+	struct delayed_work rfkill_poll;
+	char rfkill_name[32];
+};
 
-/* Attach, Detach */
+/********************/
+/* Main driver core */
+/********************/
 
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hal *ah);
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
-				void __iomem *mem, int *error);
-void ath9k_hw_rfdetach(struct ath_hal *ah);
+/*
+ * Default cache line size, in bytes.
+ * 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 */
 
-/* HW Reset */
+#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
+#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RATE_DUMMY_MARKER   0
 
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
-		    enum ath9k_ht_macmode macmode,
-		    u8 txchainmask, u8 rxchainmask,
-		    enum ath9k_ht_extprotspacing extprotspacing,
-		    bool bChannelChange, int *status);
+#define SC_OP_INVALID           BIT(0)
+#define SC_OP_BEACONS           BIT(1)
+#define SC_OP_RXAGGR            BIT(2)
+#define SC_OP_TXAGGR            BIT(3)
+#define SC_OP_CHAINMASK_UPDATE  BIT(4)
+#define SC_OP_FULL_RESET        BIT(5)
+#define SC_OP_PREAMBLE_SHORT    BIT(6)
+#define SC_OP_PROTECT_ENABLE    BIT(7)
+#define SC_OP_RXFLUSH           BIT(8)
+#define SC_OP_LED_ASSOCIATED    BIT(9)
+#define SC_OP_RFKILL_REGISTERED BIT(10)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
+#define SC_OP_WAIT_FOR_BEACON   BIT(13)
+#define SC_OP_LED_ON            BIT(14)
+#define SC_OP_SCANNING          BIT(15)
+#define SC_OP_TSF_RESET         BIT(16)
 
-/* Key Cache Management */
+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);
+};
 
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
-				 const struct ath9k_keyval *k,
-				 const u8 *mac, int xorKey);
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
+struct ath_wiphy;
 
-/* Power Management */
+struct ath_softc {
+	struct ieee80211_hw *hw;
+	struct device *dev;
 
-bool ath9k_hw_setpower(struct ath_hal *ah,
-		       enum ath9k_power_mode mode);
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
+	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
+				       * have NULL entries */
+	int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+	int chan_idx;
+	int chan_is_ht;
+	struct ath_wiphy *next_wiphy;
+	struct work_struct chan_work;
+	int wiphy_select_failures;
+	unsigned long wiphy_select_first_fail;
+	struct delayed_work wiphy_work;
+	unsigned long wiphy_scheduler_int;
+	int wiphy_scheduler_index;
 
-/* Beacon timers */
+	struct tasklet_struct intr_tq;
+	struct tasklet_struct bcon_tasklet;
+	struct ath_hw *sc_ah;
+	void __iomem *mem;
+	int irq;
+	spinlock_t sc_resetlock;
+	spinlock_t sc_serial_rw;
+	struct mutex mutex;
 
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
-				    const struct ath9k_beacon_state *bs);
-/* HW Capabilities */
+	u8 curbssid[ETH_ALEN];
+	u8 bssidmask[ETH_ALEN];
+	u32 intrstatus;
+	u32 sc_flags; /* SC_OP_* */
+	u16 curtxpow;
+	u16 curaid;
+	u16 cachelsz;
+	u8 nbcnvifs;
+	u16 nvifs;
+	u8 tx_chainmask;
+	u8 rx_chainmask;
+	u32 keymax;
+	DECLARE_BITMAP(keymap, ATH_KEYMAX);
+	u8 splitmic;
+	atomic_t ps_usecount;
+	enum ath9k_int imask;
+	enum ath9k_ht_extprotspacing ht_extprotspacing;
+	enum ath9k_ht_macmode tx_chan_width;
 
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
-			    u32 capability, u32 *result);
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
-			    u32 capability, u32 setting, int *status);
+	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];
+	struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+	struct ath_rate_table *cur_rate_table;
+	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
-/* GPIO / RFKILL / Antennae */
+	struct ath_led radio_led;
+	struct ath_led assoc_led;
+	struct ath_led tx_led;
+	struct ath_led rx_led;
+	struct delayed_work ath_led_blink_work;
+	int led_on_duration;
+	int led_off_duration;
+	int led_on_cnt;
+	int led_off_cnt;
 
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
-			 u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah);
+	struct ath_rfkill rf_kill;
+	struct ath_ani ani;
+	struct ath9k_node_stats nodestats;
+#ifdef CONFIG_ATH9K_DEBUG
+	struct ath9k_debug debug;
 #endif
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg);
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
-			       enum ath9k_ant_setting settings,
-			       struct ath9k_channel *chan,
-			       u8 *tx_chainmask,
-			       u8 *rx_chainmask,
-			       u8 *antenna_cfgd);
+	struct ath_bus_ops *bus_ops;
+};
 
-/* General Operation */
+struct ath_wiphy {
+	struct ath_softc *sc; /* shared for all virtual wiphys */
+	struct ieee80211_hw *hw;
+	enum ath_wiphy_state {
+		ATH_WIPHY_INACTIVE,
+		ATH_WIPHY_ACTIVE,
+		ATH_WIPHY_PAUSING,
+		ATH_WIPHY_PAUSED,
+		ATH_WIPHY_SCAN,
+	} state;
+	int chan_idx;
+	int chan_is_ht;
+};
 
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
-bool ath9k_hw_phy_disable(struct ath_hal *ah);
-bool ath9k_hw_disable(struct ath_hal *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
-void ath9k_hw_setopmode(struct ath_hal *ah);
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1);
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask);
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId);
-u64 ath9k_hw_gettsf64(struct ath_hal *ah);
-void ath9k_hw_reset_tsf(struct ath_hal *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
+int ath_reset(struct ath_softc *sc, bool retry_tx);
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
+int ath_cabq_update(struct ath_softc *);
 
-/* Regulatory */
+static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+{
+	sc->bus_ops->read_cachesize(sc, csz);
+}
 
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
-struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah,
-			 const struct ath9k_channel *c);
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
-u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
-				   struct ath9k_channel *chan);
-bool ath9k_regd_init_channels(struct ath_hal *ah,
-			      u32 maxchans, u32 *nchans, u8 *regclassids,
-			      u32 maxregids, u32 *nregids, u16 cc,
-			      bool enableOutdoor, bool enableExtendedChannels);
+static inline void ath_bus_cleanup(struct ath_softc *sc)
+{
+	sc->bus_ops->cleanup(sc);
+}
 
-/* ANI */
+extern struct ieee80211_ops ath9k_ops;
 
-void ath9k_ani_reset(struct ath_hal *ah);
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
-			  const struct ath9k_node_stats *stats,
-			  struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hal *ah);
-void ath9k_enable_mib_counters(struct ath_hal *ah);
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
-				  u32 *rxc_pcnt,
-				  u32 *rxf_pcnt,
-				  u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hal *ah,
-			   const struct ath9k_node_stats *stats);
-void ath9k_hw_ani_setup(struct ath_hal *ah);
-void ath9k_hw_ani_attach(struct ath_hal *ah);
-void ath9k_hw_ani_detach(struct ath_hal *ah);
+irqreturn_t ath_isr(int irq, void *dev);
+void ath_cleanup(struct ath_softc *sc);
+int ath_attach(u16 devid, struct ath_softc *sc);
+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);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+			   struct ath9k_channel *ichan);
+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);
 
-/* Calibration */
+#ifdef CONFIG_PCI
+int ath_pci_init(void);
+void ath_pci_exit(void);
+#else
+static inline int ath_pci_init(void) { return 0; };
+static inline void ath_pci_exit(void) {};
+#endif
 
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
-			     bool *isCalDone);
-void ath9k_hw_start_nfcal(struct ath_hal *ah);
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
-		       struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
-			u8 rxchainmask, bool longcal,
-			bool *isCalDone);
-bool ath9k_hw_init_cal(struct ath_hal *ah,
-		       struct ath9k_channel *chan);
+#ifdef CONFIG_ATHEROS_AR71XX
+int ath_ahb_init(void);
+void ath_ahb_exit(void);
+#else
+static inline int ath_ahb_init(void) { return 0; };
+static inline void ath_ahb_exit(void) {};
+#endif
 
+static inline void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+	if (atomic_inc_return(&sc->ps_usecount) == 1)
+		if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
+			sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
+			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+		}
+}
 
-/* EEPROM */
+static inline void ath9k_ps_restore(struct ath_softc *sc)
+{
+	if (atomic_dec_and_test(&sc->ps_usecount))
+		if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
+		    !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
+			ath9k_hw_setpower(sc->sc_ah,
+					  sc->sc_ah->restore_mode);
+}
 
-int ath9k_hw_set_txpower(struct ath_hal *ah,
-			 struct ath9k_channel *chan,
-			 u16 cfgCtl,
-			 u8 twiceAntennaReduction,
-			 u8 twiceMaxRegulatoryPower,
-			 u8 powerLimit);
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
-				       struct ath9k_channel *chan,
-				       int16_t *ratesArray,
-				       u16 cfgCtl,
-				       u8 AntennaReduction,
-				       u8 twiceMaxRegulatoryPower,
-				       u8 powerLimit);
-bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
-				  struct ath9k_channel *chan,
-				  int16_t *pTxPowerIndexOffset);
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
-				      struct ath9k_channel *chan);
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
-				    struct ath9k_channel *chan,
-				    u8 index, u16 *config);
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
-			       enum ieee80211_band freq_band);
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz);
-int ath9k_hw_eeprom_attach(struct ath_hal *ah);
 
-/* Interrupt Handling */
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+				  struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
 
-bool ath9k_hw_intrpend(struct ath_hal *ah);
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
+/*
+ * 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.
+ */
 
-/* MAC (PCU/QCU) */
+static inline 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);
+}
 
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel);
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
-			 u32 segLen, bool firstSeg,
-			 bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
-			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-			    u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
-				  struct ath_desc *lastds,
-				  u32 durUpdateEn, u32 rtsctsRate,
-				  u32 rtsctsDuration,
-				  struct ath9k_11n_rate_series series[],
-				  u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
-				u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
-				 u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
-				   u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
-				     u32 vmf);
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
-			    const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
-			    struct ath9k_tx_queue_info *qinfo);
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
-			  const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
-			u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
-			  u32 size, u32 flags);
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hal *ah);
-void ath9k_hw_startpcureceive(struct ath_hal *ah);
-void ath9k_hw_stoppcurecv(struct ath_hal *ah);
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
+static inline 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;
+}
 
-#endif
+#endif /* ATH9K_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/beacon.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/beacon.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/beacon.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/beacon.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,7 +14,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
+#include "ath9k.h"
+
+#define FUDGE 2
 
 /*
  *  This function will modify certain transmit queue properties depending on
@@ -23,11 +25,11 @@
 */
 static int ath_beaconq_config(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath9k_tx_queue_info qi;
 
 	ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
+	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
 		/* Always burst out beacon and CAB traffic. */
 		qi.tqi_aifs = 1;
 		qi.tqi_cwmin = 0;
@@ -44,46 +46,33 @@ static int ath_beaconq_config(struct ath
 			"unable to update h/w beacon queue parameters\n");
 		return 0;
 	} else {
-		ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
+		ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
 		return 1;
 	}
 }
 
-static void ath_bstuck_process(struct ath_softc *sc)
-{
-	DPRINTF(sc, ATH_DBG_BEACON,
-		"stuck beacon; resetting (bmiss count %u)\n",
-		sc->beacon.bmisscnt);
-	ath_reset(sc, false);
-}
-
 /*
  *  Associates the beacon frame buffer with a transmit descriptor.  Will set
  *  up all required antenna switch parameters, rate codes, and channel flags.
  *  Beacons are always sent out at the lowest rate, and are not retried.
 */
-static void ath_beacon_setup(struct ath_softc *sc,
-			     struct ath_vap *avp, struct ath_buf *bf)
+static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+			     struct ath_buf *bf)
 {
 	struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_desc *ds;
 	struct ath9k_11n_rate_series series[4];
 	struct ath_rate_table *rt;
-	int flags, antenna;
-	u8 rix, rate;
-	int ctsrate = 0;
-	int ctsduration = 0;
-
-	DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len);
+	int flags, antenna, ctsrate = 0, ctsduration = 0;
+	u8 rate;
 
-	/* setup descriptors */
 	ds = bf->bf_desc;
-
 	flags = ATH9K_TXDESC_NOACK;
 
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
-	    (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+	if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+	     (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
+	    (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
 		ds->ds_link = bf->bf_daddr; /* self-linked */
 		flags |= ATH9K_TXDESC_VEOL;
 		/* Let hardware handle antenna switching. */
@@ -92,65 +81,53 @@ static void ath_beacon_setup(struct ath_
 		ds->ds_link = 0;
 		/*
 		 * Switch antenna every beacon.
-		 * Should only switch every beacon period, not for every
-		 * SWBA's
-		 * XXX assumes two antenna
+		 * Should only switch every beacon period, not for every SWBA
+		 * XXX assumes two antennae
 		 */
-		antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+		antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
 	}
 
 	ds->ds_data = bf->bf_buf_addr;
 
-	/*
-	 * Calculate rate code.
-	 * XXX everything at min xmit rate
-	 */
-	rix = 0;
 	rt = sc->cur_rate_table;
-	rate = rt->info[rix].ratecode;
+	rate = rt->info[0].ratecode;
 	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-		rate |= rt->info[rix].short_preamble;
+		rate |= rt->info[0].short_preamble;
 
-	ath9k_hw_set11n_txdesc(ah, ds,
-			       skb->len + FCS_LEN,     /* frame length */
-			       ATH9K_PKT_TYPE_BEACON,  /* Atheros packet type */
-			       MAX_RATE_POWER,         /* FIXME */
-			       ATH9K_TXKEYIX_INVALID,  /* no encryption */
-			       ATH9K_KEY_TYPE_CLEAR,   /* no encryption */
-			       flags                   /* no ack,
-							  veol for beacons */
-		);
+	ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
+			       ATH9K_PKT_TYPE_BEACON,
+			       MAX_RATE_POWER,
+			       ATH9K_TXKEYIX_INVALID,
+			       ATH9K_KEY_TYPE_CLEAR,
+			       flags);
 
 	/* NB: beacon's BufLen must be a multiple of 4 bytes */
-	ath9k_hw_filltxdesc(ah, ds,
-			    roundup(skb->len, 4), /* buffer length */
-			    true,                 /* first segment */
-			    true,                 /* last segment */
-			    ds                    /* first descriptor */
-		);
+	ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
+			    true, true, ds);
 
 	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
 	series[0].Tries = 1;
 	series[0].Rate = rate;
-	series[0].ChSel = sc->sc_tx_chainmask;
+	series[0].ChSel = sc->tx_chainmask;
 	series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
-	ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
-		ctsrate, ctsduration, series, 4, 0);
+	ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
+				     series, 4, 0);
 }
 
-/* Generate beacon frame and queue cab data for a vap */
-static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
+					   struct ieee80211_vif *vif)
 {
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	struct ath_buf *bf;
-	struct ath_vap *avp;
+	struct ath_vif *avp;
 	struct sk_buff *skb;
 	struct ath_txq *cabq;
-	struct ieee80211_vif *vif;
 	struct ieee80211_tx_info *info;
 	int cabq_depth;
 
-	vif = sc->sc_vaps[if_id];
-	ASSERT(vif);
+	if (aphy->state != ATH_WIPHY_ACTIVE)
+		return NULL;
 
 	avp = (void *)vif->drv_priv;
 	cabq = sc->beacon.cabq;
@@ -161,19 +138,24 @@ static struct ath_buf *ath_beacon_genera
 		return NULL;
 	}
 
+	/* Release the old beacon first */
+
 	bf = avp->av_bcbuf;
 	skb = (struct sk_buff *)bf->bf_mpdu;
 	if (skb) {
-		pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-				 skb->len,
-				 PCI_DMA_TODEVICE);
+		dma_unmap_single(sc->dev, bf->bf_dmacontext,
+				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 	}
 
-	skb = ieee80211_beacon_get(sc->hw, vif);
+	/* Get a new beacon from mac80211 */
+
+	skb = ieee80211_beacon_get(hw, vif);
 	bf->bf_mpdu = skb;
 	if (skb == NULL)
 		return NULL;
+	((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+		avp->tsf_adjust;
 
 	info = IEEE80211_SKB_CB(skb);
 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -188,54 +170,42 @@ static struct ath_buf *ath_beacon_genera
 	}
 
 	bf->bf_buf_addr = bf->bf_dmacontext =
-		pci_map_single(sc->pdev, skb->data,
-			       skb->len,
-			       PCI_DMA_TODEVICE);
-	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+		dma_map_single(sc->dev, skb->data,
+			       skb->len, DMA_TO_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_CONFIG,
-			"pci_dma_mapping_error() on beaconing\n");
+		DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
 		return NULL;
 	}
 
-	skb = ieee80211_get_buffered_bc(sc->hw, vif);
+	skb = ieee80211_get_buffered_bc(hw, vif);
 
 	/*
 	 * if the CABQ traffic from previous DTIM is pending and the current
 	 *  beacon is also a DTIM.
-	 *  1) if there is only one vap let the cab traffic continue.
-	 *  2) if there are more than one vap and we are using staggered
+	 *  1) if there is only one vif let the cab traffic continue.
+	 *  2) if there are more than one vif and we are using staggered
 	 *     beacons, then drain the cabq by dropping all the frames in
-	 *     the cabq so that the current vaps cab traffic can be scheduled.
+	 *     the cabq so that the current vifs cab traffic can be scheduled.
 	 */
 	spin_lock_bh(&cabq->axq_lock);
 	cabq_depth = cabq->axq_depth;
 	spin_unlock_bh(&cabq->axq_lock);
 
 	if (skb && cabq_depth) {
-		/*
-		 * Unlock the cabq lock as ath_tx_draintxq acquires
-		 * the lock again which is a common function and that
-		 * acquires txq lock inside.
-		 */
-		if (sc->sc_nvaps > 1) {
-			ath_tx_draintxq(sc, cabq, false);
+		if (sc->nvifs > 1) {
 			DPRINTF(sc, ATH_DBG_BEACON,
-				"flush previous cabq traffic\n");
+				"Flushing previous cabq traffic\n");
+			ath_draintxq(sc, cabq, false);
 		}
 	}
 
-	/* Construct tx descriptor. */
 	ath_beacon_setup(sc, avp, bf);
 
-	/*
-	 * Enable the CAB queue before the beacon queue to
-	 * insure cab frames are triggered by this beacon.
-	 */
 	while (skb) {
-		ath_tx_cabq(sc, skb);
-		skb = ieee80211_get_buffered_bc(sc->hw, vif);
+		ath_tx_cabq(hw, skb);
+		skb = ieee80211_get_buffered_bc(hw, vif);
 	}
 
 	return bf;
@@ -245,28 +215,22 @@ static struct ath_buf *ath_beacon_genera
  * Startup beacon transmission for adhoc mode when they are sent entirely
  * by the hardware using the self-linked descriptor + veol trick.
 */
-static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
+static void ath_beacon_start_adhoc(struct ath_softc *sc,
+				   struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_buf *bf;
-	struct ath_vap *avp;
+	struct ath_vif *avp;
 	struct sk_buff *skb;
 
-	vif = sc->sc_vaps[if_id];
-	ASSERT(vif);
-
 	avp = (void *)vif->drv_priv;
 
-	if (avp->av_bcbuf == NULL) {
-		DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
-			avp, avp != NULL ? avp->av_bcbuf : NULL);
+	if (avp->av_bcbuf == NULL)
 		return;
-	}
+
 	bf = avp->av_bcbuf;
 	skb = (struct sk_buff *) bf->bf_mpdu;
 
-	/* Construct tx descriptor. */
 	ath_beacon_setup(sc, avp, bf);
 
 	/* NB: caller is known to have already stopped tx dma */
@@ -276,7 +240,7 @@ static void ath_beacon_start_adhoc(struc
 		sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
 }
 
-int ath_beaconq_setup(struct ath_hal *ah)
+int ath_beaconq_setup(struct ath_hw *ah)
 {
 	struct ath9k_tx_queue_info qi;
 
@@ -288,18 +252,14 @@ int ath_beaconq_setup(struct ath_hal *ah
 	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 
-int ath_beacon_alloc(struct ath_softc *sc, int if_id)
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 {
-	struct ieee80211_vif *vif;
-	struct ath_vap *avp;
-	struct ieee80211_hdr *hdr;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_vif *avp;
 	struct ath_buf *bf;
 	struct sk_buff *skb;
 	__le64 tstamp;
 
-	vif = sc->sc_vaps[if_id];
-	ASSERT(vif);
-
 	avp = (void *)vif->drv_priv;
 
 	/* Allocate a beacon descriptor if we haven't done so. */
@@ -310,51 +270,46 @@ int ath_beacon_alloc(struct ath_softc *s
 						 struct ath_buf, list);
 		list_del(&avp->av_bcbuf->list);
 
-		if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
-		    !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+		if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+		    !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
 			int slot;
 			/*
-			 * Assign the vap to a beacon xmit slot. As
+			 * Assign the vif to a beacon xmit slot. As
 			 * above, this cannot fail to find one.
 			 */
 			avp->av_bslot = 0;
 			for (slot = 0; slot < ATH_BCBUF; slot++)
-				if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
+				if (sc->beacon.bslot[slot] == NULL) {
 					/*
 					 * XXX hack, space out slots to better
 					 * deal with misses
 					 */
 					if (slot+1 < ATH_BCBUF &&
-					    sc->beacon.bslot[slot+1] ==
-						ATH_IF_ID_ANY) {
+					    sc->beacon.bslot[slot+1] == NULL) {
 						avp->av_bslot = slot+1;
 						break;
 					}
 					avp->av_bslot = slot;
 					/* NB: keep looking for a double slot */
 				}
-			BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
-			sc->beacon.bslot[avp->av_bslot] = if_id;
-			sc->sc_nbcnvaps++;
+			BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
+			sc->beacon.bslot[avp->av_bslot] = vif;
+			sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
+			sc->nbcnvifs++;
 		}
 	}
 
-	/* release the previous beacon frame , if it already exists. */
+	/* release the previous beacon frame, if it already exists. */
 	bf = avp->av_bcbuf;
 	if (bf->bf_mpdu != NULL) {
 		skb = (struct sk_buff *)bf->bf_mpdu;
-		pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-				 skb->len,
-				 PCI_DMA_TODEVICE);
+		dma_unmap_single(sc->dev, bf->bf_dmacontext,
+				 skb->len, DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 		bf->bf_mpdu = NULL;
 	}
 
-	/*
-	 * NB: the beacon data buffer must be 32-bit aligned.
-	 * FIXME: Fill avp->av_btxctl.txpower and
-	 * avp->av_btxctl.shortPreamble
-	 */
+	/* 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");
@@ -363,75 +318,65 @@ int ath_beacon_alloc(struct ath_softc *s
 
 	tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
 	sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
-
-	/*
-	 * Calculate a TSF adjustment factor required for
-	 * staggered beacons.  Note that we assume the format
-	 * of the beacon frame leaves the tstamp field immediately
-	 * following the header.
-	 */
+	/* Calculate a TSF adjustment factor required for staggered beacons. */
 	if (avp->av_bslot > 0) {
 		u64 tsfadjust;
-		__le64 val;
 		int intval;
 
 		intval = sc->hw->conf.beacon_int ?
 			sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
 
 		/*
-		 * The beacon interval is in TU's; the TSF in usecs.
-		 * We figure out how many TU's to add to align the
-		 * timestamp then convert to TSF units and handle
-		 * byte swapping before writing it in the frame.
-		 * The hardware will then add this each time a beacon
-		 * frame is sent.  Note that we align vap's 1..N
-		 * and leave vap 0 untouched.  This means vap 0
-		 * has a timestamp in one beacon interval while the
-		 * others get a timestamp aligned to the next interval.
+		 * Calculate the TSF offset for this beacon slot, i.e., the
+		 * number of usecs that need to be added to the timestamp field
+		 * in Beacon and Probe Response frames. Beacon slot 0 is
+		 * processed at the correct offset, so it does not require TSF
+		 * adjustment. Other slots are adjusted to get the timestamp
+		 * close to the TBTT for the BSS.
 		 */
-		tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
-		val = cpu_to_le64(tsfadjust << 10);     /* TU->TSF */
+		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);
 
-		hdr = (struct ieee80211_hdr *)skb->data;
-		memcpy(&hdr[1], &val, sizeof(val));
-	}
+		((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+			avp->tsf_adjust;
+	} else
+		avp->tsf_adjust = cpu_to_le64(0);
 
 	bf->bf_mpdu = skb;
 	bf->bf_buf_addr = bf->bf_dmacontext =
-		pci_map_single(sc->pdev, skb->data,
-			       skb->len,
-			       PCI_DMA_TODEVICE);
-	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+		dma_map_single(sc->dev, skb->data,
+			       skb->len, DMA_TO_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_CONFIG,
-			"pci_dma_mapping_error() on beacon alloc\n");
+		DPRINTF(sc, ATH_DBG_FATAL,
+			"dma_mapping_error on beacon alloc\n");
 		return -ENOMEM;
 	}
 
 	return 0;
 }
 
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
 {
 	if (avp->av_bcbuf != NULL) {
 		struct ath_buf *bf;
 
 		if (avp->av_bslot != -1) {
-			sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
-			sc->sc_nbcnvaps--;
+			sc->beacon.bslot[avp->av_bslot] = NULL;
+			sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
+			sc->nbcnvifs--;
 		}
 
 		bf = avp->av_bcbuf;
 		if (bf->bf_mpdu != NULL) {
 			struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-			pci_unmap_single(sc->pdev, bf->bf_dmacontext,
-					 skb->len,
-					 PCI_DMA_TODEVICE);
+			dma_unmap_single(sc->dev, bf->bf_dmacontext,
+					 skb->len, DMA_TO_DEVICE);
 			dev_kfree_skb_any(skb);
 			bf->bf_mpdu = NULL;
 		}
@@ -441,92 +386,45 @@ void ath_beacon_return(struct ath_softc
 	}
 }
 
-void ath9k_beacon_tasklet(unsigned long data)
+void ath_beacon_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_buf *bf = NULL;
-	int slot, if_id;
-	u32 bfaddr;
-	u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
-	u32 show_cycles = 0;
-	u32 bc = 0; /* beacon count */
+	struct ieee80211_vif *vif;
+	struct ath_wiphy *aphy;
+	int slot;
+	u32 bfaddr, bc = 0, tsftu;
 	u64 tsf;
-	u32 tsftu;
 	u16 intval;
 
-	if (sc->sc_flags & SC_OP_NO_RESET) {
-		show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
-					    &rx_clear, &rx_frame, &tx_frame);
-	}
-
 	/*
 	 * Check if the previous beacon has gone out.  If
 	 * not don't try to post another, skip this period
 	 * and wait for the next.  Missed beacons indicate
 	 * a problem and should not occur.  If we miss too
 	 * many consecutive beacons reset the device.
-	 *
-	 * FIXME: Clean up this mess !!
 	 */
 	if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
 		sc->beacon.bmisscnt++;
-		/* XXX: doth needs the chanchange IE countdown decremented.
-		 *      We should consider adding a mac80211 call to indicate
-		 *      a beacon miss so appropriate action could be taken
-		 *      (in that layer).
-		 */
+
 		if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
-			if (sc->sc_flags & SC_OP_NO_RESET) {
-				DPRINTF(sc, ATH_DBG_BEACON,
-					"missed %u consecutive beacons\n",
-					sc->beacon.bmisscnt);
-				if (show_cycles) {
-					/*
-					 * Display cycle counter stats from HW
-					 * to aide in debug of stickiness.
-					 */
-					DPRINTF(sc, ATH_DBG_BEACON,
-						"busy times: rx_clear=%d, "
-						"rx_frame=%d, tx_frame=%d\n",
-						rx_clear, rx_frame,
-						tx_frame);
-				} else {
-					DPRINTF(sc, ATH_DBG_BEACON,
-						"unable to obtain "
-						"busy times\n");
-				}
-			} else {
-				DPRINTF(sc, ATH_DBG_BEACON,
-					"missed %u consecutive beacons\n",
-					sc->beacon.bmisscnt);
-			}
+			DPRINTF(sc, ATH_DBG_BEACON,
+				"missed %u consecutive beacons\n",
+				sc->beacon.bmisscnt);
 		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-			if (sc->sc_flags & SC_OP_NO_RESET) {
-				if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
-					DPRINTF(sc, ATH_DBG_BEACON,
-						"beacon is officially "
-						"stuck\n");
-				}
-			} else {
-				DPRINTF(sc, ATH_DBG_BEACON,
-					"beacon is officially stuck\n");
-				ath_bstuck_process(sc);
-			}
+			DPRINTF(sc, ATH_DBG_BEACON,
+				"beacon is officially stuck\n");
+			ath_reset(sc, false);
 		}
+
 		return;
 	}
 
 	if (sc->beacon.bmisscnt != 0) {
-		if (sc->sc_flags & SC_OP_NO_RESET) {
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"resume beacon xmit after %u misses\n",
-				sc->beacon.bmisscnt);
-		} else {
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"resume beacon xmit after %u misses\n",
-				sc->beacon.bmisscnt);
-		}
+		DPRINTF(sc, ATH_DBG_BEACON,
+			"resume beacon xmit after %u misses\n",
+			sc->beacon.bmisscnt);
 		sc->beacon.bmisscnt = 0;
 	}
 
@@ -542,21 +440,30 @@ void ath9k_beacon_tasklet(unsigned long
 	tsf = ath9k_hw_gettsf64(ah);
 	tsftu = TSF_TO_TU(tsf>>32, tsf);
 	slot = ((tsftu % intval) * ATH_BCBUF) / intval;
-	if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+	/*
+	 * Reverse the slot order to get slot 0 on the TBTT offset that does
+	 * not require TSF adjustment and other slots adding
+	 * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
+	 * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
+	 * and slot 0 is at correct offset to TBTT.
+	 */
+	slot = ATH_BCBUF - slot - 1;
+	vif = sc->beacon.bslot[slot];
+	aphy = sc->beacon.bslot_aphy[slot];
 
 	DPRINTF(sc, ATH_DBG_BEACON,
-		"slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
-		slot, (unsigned long long)tsf, tsftu,
-		intval, if_id);
+		"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+		slot, tsf, tsftu, intval, vif);
 
 	bfaddr = 0;
-	if (if_id != ATH_IF_ID_ANY) {
-		bf = ath_beacon_generate(sc, if_id);
+	if (vif) {
+		bf = ath_beacon_generate(aphy->hw, vif);
 		if (bf != NULL) {
 			bfaddr = bf->bf_daddr;
 			bc = 1;
 		}
 	}
+
 	/*
 	 * Handle slot time change when a non-ERP station joins/leaves
 	 * an 11g network.  The 802.11 layer notifies us via callback,
@@ -573,7 +480,6 @@ void ath9k_beacon_tasklet(unsigned long
 	 *     interval has passed.  When bursting slot is always left
 	 *     set to ATH_BCBUF so this check is a noop.
 	 */
-	/* XXX locking */
 	if (sc->beacon.updateslot == UPDATE) {
 		sc->beacon.updateslot = COMMIT; /* commit next beacon */
 		sc->beacon.slotupdate = slot;
@@ -590,265 +496,251 @@ void ath9k_beacon_tasklet(unsigned long
 		if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
 			DPRINTF(sc, ATH_DBG_FATAL,
 				"beacon queue %u did not stop?\n", sc->beacon.beaconq);
-			/* NB: the HAL still stops DMA, so proceed */
 		}
 
 		/* NB: cabq traffic should already be queued and primed */
 		ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
 		ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
-		sc->beacon.ast_be_xmit += bc;     /* XXX per-vap? */
+		sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
 	}
 }
 
 /*
- * Configure the beacon and sleep timers.
- *
- * When operating as an AP this resets the TSF and sets
- * up the hardware to notify us when we need to issue beacons.
- *
- * When operating in station mode this sets up the beacon
- * timers according to the timestamp of the last received
- * beacon and the current TSF, configures PCF and DTIM
- * handling, programs the sleep registers so the hardware
- * will wakeup in time to receive beacons, and configures
- * the beacon miss handling so we'll receive a BMISS
- * interrupt when we stop seeing beacons from the AP
- * we've associated with.
+ * 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
+ * slot. Slots that are not occupied will generate nothing.
  */
-void ath_beacon_config(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_ap(struct ath_softc *sc,
+				 struct ath_beacon_config *conf,
+				 struct ath_vif *avp)
 {
-	struct ieee80211_vif *vif;
-	struct ath_hal *ah = sc->sc_ah;
-	struct ath_beacon_config conf;
-	struct ath_vap *avp;
-	enum nl80211_iftype opmode;
 	u32 nexttbtt, intval;
 
-	if (if_id != ATH_IF_ID_ANY) {
-		vif = sc->sc_vaps[if_id];
-		ASSERT(vif);
-		avp = (void *)vif->drv_priv;
-		opmode = avp->av_opmode;
-	} else {
-		opmode = sc->sc_ah->ah_opmode;
-	}
+	/* Configure the timers only when the TSF has to be reset */
 
-	memset(&conf, 0, sizeof(struct ath_beacon_config));
+	if (!(sc->sc_flags & SC_OP_TSF_RESET))
+		return;
 
-	conf.beacon_interval = sc->hw->conf.beacon_int ?
-		sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-	conf.listen_interval = 1;
-	conf.dtim_period = conf.beacon_interval;
-	conf.dtim_count = 1;
-	conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+	/* NB: the beacon interval is kept internally in TU's */
+	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+	intval /= ATH_BCBUF;    /* for staggered beacons */
+	nexttbtt = intval;
+	intval |= ATH9K_BEACON_RESET_TSF;
 
-	/* extract tstamp from last beacon and convert to TU */
-	nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+	/*
+	 * In AP mode we enable the beacon timers and SWBA interrupts to
+	 * prepare beacon frames.
+	 */
+	intval |= ATH9K_BEACON_ENA;
+	sc->imask |= ATH9K_INT_SWBA;
+	ath_beaconq_config(sc);
 
-	/* XXX conditionalize multi-bss support? */
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
-		/*
-		 * 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 slot.
-		 * Slots that are not occupied will generate nothing.
-		 */
-		/* NB: the beacon interval is kept internally in TU's */
-		intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
-		intval /= ATH_BCBUF;    /* for staggered beacons */
-	} else {
-		intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
-	}
+	/* Set the computed AP beacon timers */
 
-	if (nexttbtt == 0)	/* e.g. for ap mode */
-		nexttbtt = intval;
-	else if (intval)	/* NB: can be 0 for monitor mode */
-		nexttbtt = roundup(nexttbtt, intval);
+	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	sc->beacon.bmisscnt = 0;
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
-	DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n",
-		nexttbtt, intval, conf.beacon_interval);
+	/* Clear the reset TSF flag, so that subsequent beacon updation
+	   will not reset the HW TSF. */
 
-	/* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) {
-		struct ath9k_beacon_state bs;
-		u64 tsf;
-		u32 tsftu;
-		int dtimperiod, dtimcount, sleepduration;
-		int cfpperiod, cfpcount;
+	sc->sc_flags &= ~SC_OP_TSF_RESET;
+}
 
-		/*
-		 * Setup dtim and cfp parameters according to
-		 * last beacon we received (which may be none).
-		 */
-		dtimperiod = conf.dtim_period;
-		if (dtimperiod <= 0)		/* NB: 0 if not known */
-			dtimperiod = 1;
-		dtimcount = conf.dtim_count;
-		if (dtimcount >= dtimperiod)	/* NB: sanity check */
-			dtimcount = 0;
-		cfpperiod = 1;			/* NB: no PCF support yet */
-		cfpcount = 0;
+/*
+ * This sets up the beacon timers according to the timestamp of the last
+ * received beacon and the current TSF, configures PCF and DTIM
+ * handling, programs the sleep registers so the hardware will wakeup in
+ * time to receive beacons, and configures the beacon miss handling so
+ * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
+ * we've associated with.
+ */
+static void ath_beacon_config_sta(struct ath_softc *sc,
+				  struct ath_beacon_config *conf,
+				  struct ath_vif *avp)
+{
+	struct ath9k_beacon_state bs;
+	int dtimperiod, dtimcount, sleepduration;
+	int cfpperiod, cfpcount;
+	u32 nexttbtt = 0, intval, tsftu;
+	u64 tsf;
 
-		sleepduration = conf.listen_interval * intval;
-		if (sleepduration <= 0)
-			sleepduration = intval;
+	memset(&bs, 0, sizeof(bs));
+	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
 
-#define FUDGE 2
-		/*
-		 * Pull nexttbtt forward to reflect the current
-		 * TSF and calculate dtim+cfp state for the result.
-		 */
-		tsf = ath9k_hw_gettsf64(ah);
-		tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
-		do {
-			nexttbtt += intval;
-			if (--dtimcount < 0) {
-				dtimcount = dtimperiod - 1;
-				if (--cfpcount < 0)
-					cfpcount = cfpperiod - 1;
-			}
-		} while (nexttbtt < tsftu);
-#undef FUDGE
-		memset(&bs, 0, sizeof(bs));
-		bs.bs_intval = intval;
-		bs.bs_nexttbtt = nexttbtt;
-		bs.bs_dtimperiod = dtimperiod*intval;
-		bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
-		bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
-		bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
-		bs.bs_cfpmaxduration = 0;
+	/*
+	 * Setup dtim and cfp parameters according to
+	 * last beacon we received (which may be none).
+	 */
+	dtimperiod = conf->dtim_period;
+	if (dtimperiod <= 0)		/* NB: 0 if not known */
+		dtimperiod = 1;
+	dtimcount = conf->dtim_count;
+	if (dtimcount >= dtimperiod)	/* NB: sanity check */
+		dtimcount = 0;
+	cfpperiod = 1;			/* NB: no PCF support yet */
+	cfpcount = 0;
 
-		/*
-		 * Calculate the number of consecutive beacons to miss
-		 * before taking a BMISS interrupt.  The configuration
-		 * is specified in TU so we only need calculate based
-		 * on the beacon interval.  Note that we clamp the
-		 * result to at most 15 beacons.
-		 */
-		if (sleepduration > intval) {
-			bs.bs_bmissthreshold = conf.listen_interval *
-				ATH_DEFAULT_BMISS_LIMIT / 2;
-		} else {
-			bs.bs_bmissthreshold =
-				DIV_ROUND_UP(conf.bmiss_timeout, intval);
-			if (bs.bs_bmissthreshold > 15)
-				bs.bs_bmissthreshold = 15;
-			else if (bs.bs_bmissthreshold <= 0)
-				bs.bs_bmissthreshold = 1;
+	sleepduration = conf->listen_interval * intval;
+	if (sleepduration <= 0)
+		sleepduration = intval;
+
+	/*
+	 * Pull nexttbtt forward to reflect the current
+	 * TSF and calculate dtim+cfp state for the result.
+	 */
+	tsf = ath9k_hw_gettsf64(sc->sc_ah);
+	tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
+	do {
+		nexttbtt += intval;
+		if (--dtimcount < 0) {
+			dtimcount = dtimperiod - 1;
+			if (--cfpcount < 0)
+				cfpcount = cfpperiod - 1;
 		}
+	} while (nexttbtt < tsftu);
 
-		/*
-		 * Calculate sleep duration.  The configuration is
-		 * given in ms.  We insure a multiple of the beacon
-		 * period is used.  Also, if the sleep duration is
-		 * greater than the DTIM period then it makes senses
-		 * to make it a multiple of that.
-		 *
-		 * XXX fixed at 100ms
-		 */
+	bs.bs_intval = intval;
+	bs.bs_nexttbtt = nexttbtt;
+	bs.bs_dtimperiod = dtimperiod*intval;
+	bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+	bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+	bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+	bs.bs_cfpmaxduration = 0;
 
-		bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100),
-					      sleepduration);
-		if (bs.bs_sleepduration > bs.bs_dtimperiod)
-			bs.bs_sleepduration = bs.bs_dtimperiod;
+	/*
+	 * Calculate the number of consecutive beacons to miss* before taking
+	 * a BMISS interrupt. The configuration is specified in TU so we only
+	 * need calculate based	on the beacon interval.  Note that we clamp the
+	 * result to at most 15 beacons.
+	 */
+	if (sleepduration > intval) {
+		bs.bs_bmissthreshold = conf->listen_interval *
+			ATH_DEFAULT_BMISS_LIMIT / 2;
+	} else {
+		bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
+		if (bs.bs_bmissthreshold > 15)
+			bs.bs_bmissthreshold = 15;
+		else if (bs.bs_bmissthreshold <= 0)
+			bs.bs_bmissthreshold = 1;
+	}
 
-		DPRINTF(sc, ATH_DBG_BEACON,
-			"tsf %llu "
-			"tsf:tu %u "
-			"intval %u "
-			"nexttbtt %u "
-			"dtim %u "
-			"nextdtim %u "
-			"bmiss %u "
-			"sleep %u "
-			"cfp:period %u "
-			"maxdur %u "
-			"next %u "
-			"timoffset %u\n",
-			(unsigned long long)tsf, tsftu,
-			bs.bs_intval,
-			bs.bs_nexttbtt,
-			bs.bs_dtimperiod,
-			bs.bs_nextdtim,
-			bs.bs_bmissthreshold,
-			bs.bs_sleepduration,
-			bs.bs_cfpperiod,
-			bs.bs_cfpmaxduration,
-			bs.bs_cfpnext,
-			bs.bs_timoffset
-			);
+	/*
+	 * Calculate sleep duration. The configuration is given in ms.
+	 * We ensure a multiple of the beacon period is used. Also, if the sleep
+	 * duration is greater than the DTIM period then it makes senses
+	 * to make it a multiple of that.
+	 *
+	 * XXX fixed at 100ms
+	 */
 
-		ath9k_hw_set_interrupts(ah, 0);
-		ath9k_hw_set_sta_beacon_timers(ah, &bs);
-		sc->sc_imask |= ATH9K_INT_BMISS;
-		ath9k_hw_set_interrupts(ah, sc->sc_imask);
-	} else {
-		u64 tsf;
-		u32 tsftu;
-		ath9k_hw_set_interrupts(ah, 0);
-		if (nexttbtt == intval)
-			intval |= ATH9K_BEACON_RESET_TSF;
-		if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
-			/*
-			 * Pull nexttbtt forward to reflect the current
-			 * TSF
-			 */
-#define FUDGE 2
-			if (!(intval & ATH9K_BEACON_RESET_TSF)) {
-				tsf = ath9k_hw_gettsf64(ah);
-				tsftu = TSF_TO_TU((u32)(tsf>>32),
-					(u32)tsf) + FUDGE;
-				do {
-					nexttbtt += intval;
-				} while (nexttbtt < tsftu);
-			}
-#undef FUDGE
-			DPRINTF(sc, ATH_DBG_BEACON,
-				"IBSS nexttbtt %u intval %u (%u)\n",
-				nexttbtt,
-				intval & ~ATH9K_BEACON_RESET_TSF,
-				conf.beacon_interval);
+	bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+	if (bs.bs_sleepduration > bs.bs_dtimperiod)
+		bs.bs_sleepduration = bs.bs_dtimperiod;
 
-			/*
-			 * In IBSS mode enable the beacon timers but only
-			 * enable SWBA interrupts if we need to manually
-			 * prepare beacon frames.  Otherwise we use a
-			 * self-linked tx descriptor and let the hardware
-			 * deal with things.
-			 */
-			intval |= ATH9K_BEACON_ENA;
-			if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
-				sc->sc_imask |= ATH9K_INT_SWBA;
-			ath_beaconq_config(sc);
-		} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
-			/*
-			 * In AP mode we enable the beacon timers and
-			 * SWBA interrupts to prepare beacon frames.
-			 */
-			intval |= ATH9K_BEACON_ENA;
-			sc->sc_imask |= ATH9K_INT_SWBA;   /* beacon prepare */
-			ath_beaconq_config(sc);
-		}
-		ath9k_hw_beaconinit(ah, nexttbtt, intval);
-		sc->beacon.bmisscnt = 0;
-		ath9k_hw_set_interrupts(ah, sc->sc_imask);
-		/*
-		 * When using a self-linked beacon descriptor in
-		 * ibss mode load it once here.
-		 */
-		if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
-		    (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
-			ath_beacon_start_adhoc(sc, 0);
-	}
+	/* 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);
+
+	/* Set the computed STA beacon timers */
+
+	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
+	sc->imask |= ATH9K_INT_BMISS;
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 }
 
-void ath_beacon_sync(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_adhoc(struct ath_softc *sc,
+				    struct ath_beacon_config *conf,
+				    struct ath_vif *avp,
+				    struct ieee80211_vif *vif)
 {
+	u64 tsf;
+	u32 tsftu, intval, nexttbtt;
+
+	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+	/* Pull nexttbtt forward to reflect the current TSF */
+
+	nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+	if (nexttbtt == 0)
+                nexttbtt = intval;
+        else if (intval)
+                nexttbtt = roundup(nexttbtt, intval);
+
+	tsf = ath9k_hw_gettsf64(sc->sc_ah);
+	tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
+	do {
+		nexttbtt += intval;
+	} while (nexttbtt < tsftu);
+
+	DPRINTF(sc, ATH_DBG_BEACON,
+		"IBSS nexttbtt %u intval %u (%u)\n",
+		nexttbtt, intval, conf->beacon_interval);
+
 	/*
-	 * Resync beacon timers using the tsf of the
-	 * beacon frame we just received.
+	 * In IBSS mode enable the beacon timers but only enable SWBA interrupts
+	 * if we need to manually prepare beacon frames.  Otherwise we use a
+	 * self-linked tx descriptor and let the hardware deal with things.
 	 */
-	ath_beacon_config(sc, if_id);
-	sc->sc_flags |= SC_OP_BEACONS;
+	intval |= ATH9K_BEACON_ENA;
+	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+		sc->imask |= ATH9K_INT_SWBA;
+
+	ath_beaconq_config(sc);
+
+	/* Set the computed ADHOC beacon timers */
+
+	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	sc->beacon.bmisscnt = 0;
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+		ath_beacon_start_adhoc(sc, vif);
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+	struct ath_beacon_config conf;
+
+	/* Setup the beacon configuration parameters */
+
+	memset(&conf, 0, sizeof(struct ath_beacon_config));
+	conf.beacon_interval = sc->hw->conf.beacon_int ?
+		sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+	conf.listen_interval = 1;
+	conf.dtim_period = conf.beacon_interval;
+	conf.dtim_count = 1;
+	conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+
+	if (vif) {
+		struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
+
+		switch(avp->av_opmode) {
+		case NL80211_IFTYPE_AP:
+			ath_beacon_config_ap(sc, &conf, avp);
+			break;
+		case NL80211_IFTYPE_ADHOC:
+		case NL80211_IFTYPE_MESH_POINT:
+			ath_beacon_config_adhoc(sc, &conf, avp, vif);
+			break;
+		case NL80211_IFTYPE_STATION:
+			ath_beacon_config_sta(sc, &conf, avp);
+			break;
+		default:
+			DPRINTF(sc, ATH_DBG_CONFIG,
+				"Unsupported beaconing mode\n");
+			return;
+		}
+
+		sc->sc_flags |= SC_OP_BEACONS;
+	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/calib.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/calib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,12 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
-
-static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
+#include "ath9k.h"
 
 /* We can tune this as we go by monitoring really low values */
 #define ATH9K_NF_TOO_LOW	-60
@@ -28,7 +23,7 @@ static const int16_t NOISE_FLOOR[] = { -
  * is incorrect and we should use the static NF value. Later we can try to
  * find out why they are reporting these values */
 
-static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+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,
@@ -91,7 +86,7 @@ static void ath9k_hw_update_nfcal_hist_b
 	return;
 }
 
-static void ath9k_hw_do_getnf(struct ath_hal *ah,
+static void ath9k_hw_do_getnf(struct ath_hw *ah,
 			      int16_t nfarray[NUM_NF_READINGS])
 {
 	int16_t nf;
@@ -107,27 +102,29 @@ static void ath9k_hw_do_getnf(struct ath
 		"NF calibrated [ctl] [chain 0] is %d\n", nf);
 	nfarray[0] = nf;
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-			AR9280_PHY_CH1_MINCCA_PWR);
-	else
-		nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-			AR_PHY_CH1_MINCCA_PWR);
-
-	if (nf & 0x100)
-		nf = 0 - ((nf ^ 0x1ff) + 1);
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-		"NF calibrated [ctl] [chain 1] is %d\n", nf);
-	nfarray[1] = nf;
+	if (!AR_SREV_9285(ah)) {
+		if (AR_SREV_9280_10_OR_LATER(ah))
+			nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+					AR9280_PHY_CH1_MINCCA_PWR);
+		else
+			nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+					AR_PHY_CH1_MINCCA_PWR);
 
-	if (!AR_SREV_9280(ah)) {
-		nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
-			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);
-		nfarray[2] = nf;
+				"NF calibrated [ctl] [chain 1] is %d\n", nf);
+		nfarray[1] = nf;
+
+		if (!AR_SREV_9280(ah)) {
+			nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+					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);
+			nfarray[2] = nf;
+		}
 	}
 
 	if (AR_SREV_9280_10_OR_LATER(ah))
@@ -143,58 +140,52 @@ static void ath9k_hw_do_getnf(struct ath
 		"NF calibrated [ext] [chain 0] is %d\n", nf);
 	nfarray[3] = nf;
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-			AR9280_PHY_CH1_EXT_MINCCA_PWR);
-	else
-		nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-			AR_PHY_CH1_EXT_MINCCA_PWR);
-
-	if (nf & 0x100)
-		nf = 0 - ((nf ^ 0x1ff) + 1);
-	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-		"NF calibrated [ext] [chain 1] is %d\n", nf);
-	nfarray[4] = nf;
+	if (!AR_SREV_9285(ah)) {
+		if (AR_SREV_9280_10_OR_LATER(ah))
+			nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+					AR9280_PHY_CH1_EXT_MINCCA_PWR);
+		else
+			nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+					AR_PHY_CH1_EXT_MINCCA_PWR);
 
-	if (!AR_SREV_9280(ah)) {
-		nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
-			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);
-		nfarray[5] = nf;
+				"NF calibrated [ext] [chain 1] is %d\n", nf);
+		nfarray[4] = nf;
+
+		if (!AR_SREV_9280(ah)) {
+			nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+					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);
+			nfarray[5] = nf;
+		}
 	}
 }
 
-static bool getNoiseFloorThresh(struct ath_hal *ah,
-				const struct ath9k_channel *chan,
+static bool getNoiseFloorThresh(struct ath_hw *ah,
+				enum ieee80211_band band,
 				int16_t *nft)
 {
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
+	switch (band) {
+	case IEEE80211_BAND_5GHZ:
+		*nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
 		break;
-	case CHANNEL_B:
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
+	case IEEE80211_BAND_2GHZ:
+		*nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
 		break;
 	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-			"invalid channel flags 0x%x\n", chan->channelFlags);
+		BUG_ON(1);
 		return false;
 	}
 
 	return true;
 }
 
-static void ath9k_hw_setup_calibration(struct ath_hal *ah,
+static void ath9k_hw_setup_calibration(struct ath_hw *ah,
 				       struct hal_cal_list *currCal)
 {
 	REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
@@ -228,10 +219,9 @@ static void ath9k_hw_setup_calibration(s
 		    AR_PHY_TIMING_CTRL4_DO_CAL);
 }
 
-static void ath9k_hw_reset_calibration(struct ath_hal *ah,
+static void ath9k_hw_reset_calibration(struct ath_hw *ah,
 				       struct hal_cal_list *currCal)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	ath9k_hw_setup_calibration(ah, currCal);
@@ -239,23 +229,21 @@ static void ath9k_hw_reset_calibration(s
 	currCal->calState = CAL_RUNNING;
 
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ahp->ah_Meas0.sign[i] = 0;
-		ahp->ah_Meas1.sign[i] = 0;
-		ahp->ah_Meas2.sign[i] = 0;
-		ahp->ah_Meas3.sign[i] = 0;
+		ah->meas0.sign[i] = 0;
+		ah->meas1.sign[i] = 0;
+		ah->meas2.sign[i] = 0;
+		ah->meas3.sign[i] = 0;
 	}
 
-	ahp->ah_CalSamples = 0;
+	ah->cal_samples = 0;
 }
 
-static void ath9k_hw_per_calibration(struct ath_hal *ah,
+static void ath9k_hw_per_calibration(struct ath_hw *ah,
 				     struct ath9k_channel *ichan,
 				     u8 rxchainmask,
 				     struct hal_cal_list *currCal,
 				     bool *isCalDone)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	*isCalDone = false;
 
 	if (currCal->calState == CAL_RUNNING) {
@@ -263,9 +251,9 @@ static void ath9k_hw_per_calibration(str
 		      AR_PHY_TIMING_CTRL4_DO_CAL)) {
 
 			currCal->calData->calCollect(ah);
-			ahp->ah_CalSamples++;
+			ah->cal_samples++;
 
-			if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) {
+			if (ah->cal_samples >= currCal->calData->calNumSamples) {
 				int i, numChains = 0;
 				for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 					if (rxchainmask & (1 << i))
@@ -285,113 +273,105 @@ static void ath9k_hw_per_calibration(str
 	}
 }
 
-static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
-				     struct ath9k_channel *chan,
+/* Assumes you are talking about the currently configured channel */
+static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
 				     enum hal_cal_types calType)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	bool retval = false;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
 
-	switch (calType & ahp->ah_suppCals) {
-	case IQ_MISMATCH_CAL:
-		if (!IS_CHAN_B(chan))
-			retval = true;
-		break;
+	switch (calType & ah->supp_cals) {
+	case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+		return true;
 	case ADC_GAIN_CAL:
 	case ADC_DC_CAL:
-		if (!IS_CHAN_B(chan)
-		    && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
-			retval = true;
+		if (conf->channel->band == IEEE80211_BAND_5GHZ &&
+		  conf_is_ht20(conf))
+			return true;
 		break;
 	}
-
-	return retval;
+	return false;
 }
 
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
+static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ahp->ah_totalPowerMeasI[i] +=
+		ah->totalPowerMeasI[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ahp->ah_totalPowerMeasQ[i] +=
+		ah->totalPowerMeasQ[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ahp->ah_totalIqCorrMeas[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",
-			ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
-			ahp->ah_totalPowerMeasQ[i],
-			ahp->ah_totalIqCorrMeas[i]);
+			ah->cal_samples, i, ah->totalPowerMeasI[i],
+			ah->totalPowerMeasQ[i],
+			ah->totalIqCorrMeas[i]);
 	}
 }
 
-static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ahp->ah_totalAdcIOddPhase[i] +=
+		ah->totalAdcIOddPhase[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ahp->ah_totalAdcIEvenPhase[i] +=
+		ah->totalAdcIEvenPhase[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ahp->ah_totalAdcQOddPhase[i] +=
+		ah->totalAdcQOddPhase[i] +=
 			REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ahp->ah_totalAdcQEvenPhase[i] +=
+		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",
-			ahp->ah_CalSamples, i,
-			ahp->ah_totalAdcIOddPhase[i],
-			ahp->ah_totalAdcIEvenPhase[i],
-			ahp->ah_totalAdcQOddPhase[i],
-			ahp->ah_totalAdcQEvenPhase[i]);
+			ah->cal_samples, i,
+			ah->totalAdcIOddPhase[i],
+			ah->totalAdcIEvenPhase[i],
+			ah->totalAdcQOddPhase[i],
+			ah->totalAdcQEvenPhase[i]);
 	}
 }
 
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int i;
 
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
+		ah->totalAdcDcOffsetIOddPhase[i] +=
 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
+		ah->totalAdcDcOffsetIEvenPhase[i] +=
 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
+		ah->totalAdcDcOffsetQOddPhase[i] +=
 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
+		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",
-			ahp->ah_CalSamples, i,
-			ahp->ah_totalAdcDcOffsetIOddPhase[i],
-			ahp->ah_totalAdcDcOffsetIEvenPhase[i],
-			ahp->ah_totalAdcDcOffsetQOddPhase[i],
-			ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
+			ah->cal_samples, i,
+			ah->totalAdcDcOffsetIOddPhase[i],
+			ah->totalAdcDcOffsetIEvenPhase[i],
+			ah->totalAdcDcOffsetQOddPhase[i],
+			ah->totalAdcDcOffsetQEvenPhase[i]);
 	}
 }
 
-static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 powerMeasQ, powerMeasI, iqCorrMeas;
 	u32 qCoffDenom, iCoffDenom;
 	int32_t qCoff, iCoff;
 	int iqCorrNeg, i;
 
 	for (i = 0; i < numChains; i++) {
-		powerMeasI = ahp->ah_totalPowerMeasI[i];
-		powerMeasQ = ahp->ah_totalPowerMeasQ[i];
-		iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+		powerMeasI = ah->totalPowerMeasI[i];
+		powerMeasQ = ah->totalPowerMeasQ[i];
+		iqCorrMeas = ah->totalIqCorrMeas[i];
 
 		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 			"Starting IQ Cal and Correction for Chain %d\n",
@@ -399,7 +379,7 @@ static void ath9k_hw_iqcalibrate(struct
 
 		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 			"Orignal: Chn %diq_corr_meas = 0x%08x\n",
-			i, ahp->ah_totalIqCorrMeas[i]);
+			i, ah->totalIqCorrMeas[i]);
 
 		iqCorrNeg = 0;
 
@@ -457,17 +437,16 @@ static void ath9k_hw_iqcalibrate(struct
 		    AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
 }
 
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
 	u32 qGainMismatch, iGainMismatch, val, i;
 
 	for (i = 0; i < numChains; i++) {
-		iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
-		iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
-		qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
-		qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
+		iOddMeasOffset = ah->totalAdcIOddPhase[i];
+		iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+		qOddMeasOffset = ah->totalAdcQOddPhase[i];
+		qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
 
 		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 			"Starting ADC Gain Cal for Chain %d\n", i);
@@ -515,21 +494,20 @@ static void ath9k_hw_adc_gaincal_calibra
 		  AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
 }
 
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 iOddMeasOffset, iEvenMeasOffset, val, i;
 	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
 	const struct hal_percal_data *calData =
-		ahp->ah_cal_list_curr->calData;
+		ah->cal_list_curr->calData;
 	u32 numSamples =
 		(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
 
 	for (i = 0; i < numChains; i++) {
-		iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
-		iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
-		qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
-		qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
+		iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+		iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+		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);
@@ -573,53 +551,42 @@ static void ath9k_hw_adc_dccal_calibrate
 		  AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
 }
 
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
-			     bool *isCalDone)
+/* This is done for the currently configured channel */
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_channel *ichan =
-		ath9k_regd_check_channel(ah, chan);
-	struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+	struct hal_cal_list *currCal = ah->cal_list_curr;
 
-	*isCalDone = true;
+	if (!ah->curchan)
+		return true;
 
 	if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
-		return;
+		return true;
 
 	if (currCal == NULL)
-		return;
-
-	if (ichan == NULL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"invalid channel %u/0x%x; no mapping\n",
-			chan->channel, chan->channelFlags);
-		return;
-	}
-
+		return true;
 
 	if (currCal->calState != CAL_DONE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 			"Calibration state incorrect, %d\n",
 			currCal->calState);
-		return;
+		return true;
 	}
 
-
-	if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
-		return;
+	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/0x%x\n",
-		currCal->calData->calType, chan->channel,
-		chan->channelFlags);
+		"Resetting Cal %d state for channel %u\n",
+		currCal->calData->calType, conf->channel->center_freq);
 
-	ichan->CalValid &= ~currCal->calData->calType;
+	ah->curchan->CalValid &= ~currCal->calData->calType;
 	currCal->calState = CAL_WAITING;
 
-	*isCalDone = false;
+	return false;
 }
 
-void ath9k_hw_start_nfcal(struct ath_hal *ah)
+void ath9k_hw_start_nfcal(struct ath_hw *ah)
 {
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
 		    AR_PHY_AGC_CONTROL_ENABLE_NF);
@@ -628,7 +595,7 @@ void ath9k_hw_start_nfcal(struct ath_hal
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 }
 
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	struct ath9k_nfcal_hist *h;
 	int i, j;
@@ -643,16 +610,14 @@ void ath9k_hw_loadnf(struct ath_hal *ah,
 	};
 	u8 chainmask;
 
-	if (AR_SREV_9280(ah))
+	if (AR_SREV_9285(ah))
+		chainmask = 0x9;
+	else if (AR_SREV_9280(ah))
 		chainmask = 0x1B;
 	else
 		chainmask = 0x3F;
 
-#ifdef ATH_NF_PER_CHAN
-	h = chan->nfCalHist;
-#else
 	h = ah->nfCalHist;
-#endif
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
@@ -686,18 +651,13 @@ void ath9k_hw_loadnf(struct ath_hal *ah,
 	}
 }
 
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
 		       struct ath9k_channel *chan)
 {
 	int16_t nf, nfThresh;
 	int16_t nfarray[NUM_NF_READINGS] = { 0 };
 	struct ath9k_nfcal_hist *h;
-	u8 chainmask;
-
-	if (AR_SREV_9280(ah))
-		chainmask = 0x1B;
-	else
-		chainmask = 0x3F;
+	struct ieee80211_channel *c = chan->chan;
 
 	chan->channelFlags &= (~CHANNEL_CW_INT);
 	if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
@@ -709,7 +669,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *a
 	} else {
 		ath9k_hw_do_getnf(ah, nfarray);
 		nf = nfarray[0];
-		if (getNoiseFloorThresh(ah, chan, &nfThresh)
+		if (getNoiseFloorThresh(ah, c->band, &nfThresh)
 		    && nf > nfThresh) {
 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 				"noise floor failed detected; "
@@ -719,11 +679,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *a
 		}
 	}
 
-#ifdef ATH_NF_PER_CHAN
-	h = chan->nfCalHist;
-#else
 	h = ah->nfCalHist;
-#endif
 
 	ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
 	chan->rawNoiseFloor = h[0].privNF;
@@ -731,7 +687,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *a
 	return chan->rawNoiseFloor;
 }
 
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
 {
 	int i, j;
 
@@ -745,26 +701,16 @@ void ath9k_init_nfcal_hist_buffer(struct
 				AR_PHY_CCA_MAX_GOOD_VALUE;
 		}
 	}
-	return;
 }
 
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
 {
-	struct ath9k_channel *ichan;
 	s16 nf;
 
-	ichan = ath9k_regd_check_channel(ah, chan);
-	if (ichan == NULL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"invalid channel %u/0x%x; no mapping\n",
-			chan->channel, chan->channelFlags);
-		return ATH_DEFAULT_NOISE_FLOOR;
-	}
-	if (ichan->rawNoiseFloor == 0) {
-		enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
-		nf = NOISE_FLOOR[mode];
-	} else
-		nf = ichan->rawNoiseFloor;
+	if (chan->rawNoiseFloor == 0)
+		nf = -96;
+	else
+		nf = chan->rawNoiseFloor;
 
 	if (!ath9k_hw_nf_in_range(ah, nf))
 		nf = ATH_DEFAULT_NOISE_FLOOR;
@@ -772,53 +718,34 @@ s16 ath9k_hw_getchan_noise(struct ath_ha
 	return nf;
 }
 
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
-			u8 rxchainmask, bool longcal,
-			bool *isCalDone)
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
-	struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
-
-	*isCalDone = true;
+	u32 rddata, i;
+	int delta, currPDADC, regval;
 
-	if (ichan == NULL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-			"invalid channel %u/0x%x; no mapping\n",
-			chan->channel, chan->channelFlags);
-		return false;
-	}
+	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
 
-	if (currCal &&
-	    (currCal->calState == CAL_RUNNING ||
-	     currCal->calState == CAL_WAITING)) {
-		ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
-					 isCalDone);
-		if (*isCalDone) {
-			ahp->ah_cal_list_curr = currCal = currCal->calNext;
+	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 
-			if (currCal->calState == CAL_WAITING) {
-				*isCalDone = false;
-				ath9k_hw_reset_calibration(ah, currCal);
-			}
-		}
-	}
+	if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+		delta = (currPDADC - ah->initPDADC + 4) / 8;
+	else
+		delta = (currPDADC - ah->initPDADC + 5) / 10;
 
-	if (longcal) {
-		ath9k_hw_getnf(ah, ichan);
-		ath9k_hw_loadnf(ah, ah->ah_curchan);
-		ath9k_hw_start_nfcal(ah);
+	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 ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
-			chan->channelFlags |= CHANNEL_CW_INT;
-			ichan->channelFlags &= ~CHANNEL_CW_INT;
+			REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+					AR_PHY_TX_GAIN, regval);
 		}
 	}
-
-	return true;
 }
 
-static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 {
 
 	u32 regVal;
@@ -913,59 +840,171 @@ static inline void ath9k_hw_9285_pa_cal(
 
 }
 
-bool ath9k_hw_init_cal(struct ath_hal *ah,
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+			u8 rxchainmask, bool longcal,
+			bool *isCalDone)
+{
+	struct hal_cal_list *currCal = ah->cal_list_curr;
+
+	*isCalDone = true;
+
+	if (currCal &&
+	    (currCal->calState == CAL_RUNNING ||
+	     currCal->calState == CAL_WAITING)) {
+		ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
+					 isCalDone);
+		if (*isCalDone) {
+			ah->cal_list_curr = currCal = currCal->calNext;
+
+			if (currCal->calState == CAL_WAITING) {
+				*isCalDone = false;
+				ath9k_hw_reset_calibration(ah, currCal);
+			}
+		}
+	}
+
+	if (longcal) {
+		if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+			ath9k_hw_9285_pa_cal(ah);
+
+		if (OLC_FOR_AR9280_20_LATER)
+			ath9k_olc_temp_compensation(ah);
+		ath9k_hw_getnf(ah, chan);
+		ath9k_hw_loadnf(ah, ah->curchan);
+		ath9k_hw_start_nfcal(ah);
+
+		if (chan->channelFlags & CHANNEL_CW_INT)
+			chan->channelFlags &= ~CHANNEL_CW_INT;
+	}
+
+	return true;
+}
+
+static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	if (chan->channelFlags & CHANNEL_HT20) {
+		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+			    AR_PHY_AGC_CONTROL_FLTR_CAL);
+		REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+		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");
+			return false;
+		}
+		REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	}
+	REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+	REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+	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");
+		return false;
+	}
+
+	REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+	REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+	return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hw *ah,
 		       struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+	if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+		if (!ar9285_clc(ah, chan))
+			return false;
+	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+
+		/* Kick off the cal */
+		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+				REG_READ(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 environment?\n");
+			return false;
+		}
 
+		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	}
+
+	/* Calibrate the AGC */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
-		  AR_PHY_AGC_CONTROL_CAL);
+			REG_READ(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)) {
+	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");
 		return false;
 	}
 
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+	}
+
+	/* Do PA Calibration */
 	if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
 		ath9k_hw_9285_pa_cal(ah);
 
+	/* Do NF Calibration */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
-		  AR_PHY_AGC_CONTROL_NF);
+			REG_READ(ah, AR_PHY_AGC_CONTROL) |
+			AR_PHY_AGC_CONTROL_NF);
 
-	ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
+	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
 
 	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-		if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
-			INIT_CAL(&ahp->ah_adcGainCalData);
-			INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
+		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");
+					"enabling ADC Gain Calibration.\n");
 		}
-		if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
-			INIT_CAL(&ahp->ah_adcDcCalData);
-			INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
+		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");
+					"enabling ADC DC Calibration.\n");
 		}
-		if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
-			INIT_CAL(&ahp->ah_iqCalData);
-			INSERT_CAL(ahp, &ahp->ah_iqCalData);
+		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");
+					"enabling IQ Calibration.\n");
 		}
 
-		ahp->ah_cal_list_curr = ahp->ah_cal_list;
+		ah->cal_list_curr = ah->cal_list;
 
-		if (ahp->ah_cal_list_curr)
-			ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
+		if (ah->cal_list_curr)
+			ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
 	}
 
-	ichan->CalValid = 0;
+	chan->CalValid = 0;
 
 	return true;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/calib.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/calib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * 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 CALIB_H
+#define CALIB_H
+
+extern const struct hal_percal_data iq_cal_multi_sample;
+extern const struct hal_percal_data iq_cal_single_sample;
+extern const struct hal_percal_data adc_gain_cal_multi_sample;
+extern const struct hal_percal_data adc_gain_cal_single_sample;
+extern const struct hal_percal_data adc_dc_cal_multi_sample;
+extern const struct hal_percal_data adc_dc_cal_single_sample;
+extern const struct hal_percal_data adc_init_dc_cal;
+
+#define AR_PHY_CCA_MAX_GOOD_VALUE      		-85
+#define AR_PHY_CCA_MAX_HIGH_VALUE      		-62
+#define AR_PHY_CCA_MIN_BAD_VALUE       		-140
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
+
+#define NUM_NF_READINGS       6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+	u32 *ia_array;
+	u32 ia_rows;
+	u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {	\
+		(iniarray)->ia_array = (u32 *)(array);		\
+		(iniarray)->ia_rows = (rows);			\
+		(iniarray)->ia_columns = (columns);		\
+	} while (0)
+
+#define INI_RA(iniarray, row, column) \
+	(((iniarray)->ia_array)[(row) *	((iniarray)->ia_columns) + (column)])
+
+#define INIT_CAL(_perCal) do {				\
+		(_perCal)->calState = CAL_WAITING;	\
+		(_perCal)->calNext = NULL;		\
+	} while (0)
+
+#define INSERT_CAL(_ahp, _perCal)					\
+	do {								\
+		if ((_ahp)->cal_list_last == NULL) {			\
+			(_ahp)->cal_list =				\
+				(_ahp)->cal_list_last = (_perCal);	\
+			((_ahp)->cal_list_last)->calNext = (_perCal); \
+		} else {						\
+			((_ahp)->cal_list_last)->calNext = (_perCal); \
+			(_ahp)->cal_list_last = (_perCal);		\
+			(_perCal)->calNext = (_ahp)->cal_list;	\
+		}							\
+	} while (0)
+
+enum hal_cal_types {
+	ADC_DC_INIT_CAL = 0x1,
+	ADC_GAIN_CAL = 0x2,
+	ADC_DC_CAL = 0x4,
+	IQ_MISMATCH_CAL = 0x8
+};
+
+enum hal_cal_state {
+	CAL_INACTIVE,
+	CAL_WAITING,
+	CAL_RUNNING,
+	CAL_DONE
+};
+
+#define MIN_CAL_SAMPLES     1
+#define MAX_CAL_SAMPLES    64
+#define INIT_LOG_COUNT      5
+#define PER_MIN_LOG_COUNT   2
+#define PER_MAX_LOG_COUNT  10
+
+struct hal_percal_data {
+	enum hal_cal_types calType;
+	u32 calNumSamples;
+	u32 calCountMax;
+	void (*calCollect) (struct ath_hw *);
+	void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct hal_cal_list {
+	const struct hal_percal_data *calData;
+	enum hal_cal_state calState;
+	struct hal_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+	int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+	u8 currIndex;
+	int16_t privNF;
+	u8 invalidNFcount;
+};
+
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+		       struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+			u8 rxchainmask, bool longcal,
+			bool *isCalDone);
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+		       struct ath9k_channel *chan);
+
+#endif /* CALIB_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/core.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/core.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,787 +0,0 @@
-/*
- * Copyright (c) 2008 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 CORE_H
-#define CORE_H
-
-#include <linux/etherdevice.h>
-#include <linux/pci.h>
-#include <net/mac80211.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-
-#include "ath9k.h"
-#include "rc.h"
-
-struct ath_node;
-
-/* Macro to expand scalars to 64-bit objects */
-
-#define	ito64(x) (sizeof(x) == 8) ?			\
-	(((unsigned long long int)(x)) & (0xff)) :	\
-	(sizeof(x) == 16) ?				\
-	(((unsigned long long int)(x)) & 0xffff) :	\
-	((sizeof(x) == 32) ?				\
-	 (((unsigned long long int)(x)) & 0xffffffff) : \
-	 (unsigned long long int)(x))
-
-/* increment with wrap-around */
-#define INCR(_l, _sz)   do {			\
-		(_l)++;				\
-		(_l) &= ((_sz) - 1);		\
-	} while (0)
-
-/* decrement with wrap-around */
-#define DECR(_l,  _sz)  do {			\
-		(_l)--;				\
-		(_l) &= ((_sz) - 1);		\
-	} while (0)
-
-#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define ASSERT(exp) do {			\
-		if (unlikely(!(exp))) {		\
-			BUG();			\
-		}				\
-	} while (0)
-
-#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};
-
-enum ATH_DEBUG {
-	ATH_DBG_RESET		= 0x00000001,
-	ATH_DBG_REG_IO		= 0x00000002,
-	ATH_DBG_QUEUE		= 0x00000004,
-	ATH_DBG_EEPROM		= 0x00000008,
-	ATH_DBG_CALIBRATE	= 0x00000010,
-	ATH_DBG_CHANNEL		= 0x00000020,
-	ATH_DBG_INTERRUPT	= 0x00000040,
-	ATH_DBG_REGULATORY	= 0x00000080,
-	ATH_DBG_ANI		= 0x00000100,
-	ATH_DBG_POWER_MGMT	= 0x00000200,
-	ATH_DBG_XMIT		= 0x00000400,
-	ATH_DBG_BEACON		= 0x00001000,
-	ATH_DBG_CONFIG		= 0x00002000,
-	ATH_DBG_KEYCACHE	= 0x00004000,
-	ATH_DBG_FATAL		= 0x00008000,
-	ATH_DBG_ANY		= 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH9K_DEBUG
-
-/**
- * struct ath_interrupt_stats - Contains statistics about interrupts
- * @total: Total no. of interrupts generated so far
- * @rxok: RX with no errors
- * @rxeol: RX with no more RXDESC available
- * @rxorn: RX FIFO overrun
- * @txok: TX completed at the requested rate
- * @txurn: TX FIFO underrun
- * @mib: MIB regs reaching its threshold
- * @rxphyerr: RX with phy errors
- * @rx_keycache_miss: RX with key cache misses
- * @swba: Software Beacon Alert
- * @bmiss: Beacon Miss
- * @bnr: Beacon Not Ready
- * @cst: Carrier Sense TImeout
- * @gtt: Global TX Timeout
- * @tim: RX beacon TIM occurrence
- * @cabend: RX End of CAB traffic
- * @dtimsync: DTIM sync lossage
- * @dtim: RX Beacon with DTIM
- */
-struct ath_interrupt_stats {
-	u32 total;
-	u32 rxok;
-	u32 rxeol;
-	u32 rxorn;
-	u32 txok;
-	u32 txeol;
-	u32 txurn;
-	u32 mib;
-	u32 rxphyerr;
-	u32 rx_keycache_miss;
-	u32 swba;
-	u32 bmiss;
-	u32 bnr;
-	u32 cst;
-	u32 gtt;
-	u32 tim;
-	u32 cabend;
-	u32 dtimsync;
-	u32 dtim;
-};
-
-struct ath_stats {
-	struct ath_interrupt_stats istats;
-};
-
-struct ath9k_debug {
-	int debug_mask;
-	struct dentry *debugfs_root;
-	struct dentry *debugfs_phy;
-	struct dentry *debugfs_dma;
-	struct dentry *debugfs_interrupt;
-	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);
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-
-#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)
-{
-	return 0;
-}
-
-static inline void ath9k_exit_debug(struct ath_softc *sc)
-{
-}
-
-static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
-					    enum ath9k_int status)
-{
-}
-
-#endif /* CONFIG_ATH9K_DEBUG */
-
-struct ath_config {
-	u32 ath_aggr_prot;
-	u16 txpowlimit;
-	u16 txpowlimit_override;
-	u8 cabqReadytime;
-	u8 swBeaconProcess;
-};
-
-/*************************/
-/* Descriptor Management */
-/*************************/
-
-#define ATH_TXBUF_RESET(_bf) do {				\
-		(_bf)->bf_status = 0;				\
-		(_bf)->bf_lastbf = NULL;			\
-		(_bf)->bf_lastfrm = NULL;			\
-		(_bf)->bf_next = NULL;				\
-		memset(&((_bf)->bf_state), 0,			\
-			    sizeof(struct ath_buf_state));	\
-	} while (0)
-
-enum buffer_type {
-	BUF_DATA		= BIT(0),
-	BUF_AGGR		= BIT(1),
-	BUF_AMPDU		= BIT(2),
-	BUF_HT			= BIT(3),
-	BUF_RETRY		= BIT(4),
-	BUF_XRETRY		= BIT(5),
-	BUF_SHORT_PREAMBLE	= BIT(6),
-	BUF_BAR			= BIT(7),
-	BUF_PSPOLL		= BIT(8),
-	BUF_AGGR_BURST		= BIT(9),
-	BUF_CALC_AIRTIME	= BIT(10),
-};
-
-struct ath_buf_state {
-	int bfs_nframes;		/* # frames in aggregate */
-	u16 bfs_al;			/* length of aggregate */
-	u16 bfs_frmlen;			/* length of frame */
-	int bfs_seqno;			/* sequence number */
-	int bfs_tidno;			/* tid of this frame */
-	int bfs_retries;		/* current retries */
-	u32 bf_type;			/* BUF_* (enum buffer_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
-#define bf_retries      	bf_state.bfs_retries
-#define bf_seqno        	bf_state.bfs_seqno
-#define bf_tidno        	bf_state.bfs_tidno
-#define bf_rcs          	bf_state.bfs_rcs
-#define bf_keyix                bf_state.bfs_keyix
-#define bf_keytype      	bf_state.bfs_keytype
-#define bf_isdata(bf)		(bf->bf_state.bf_type & BUF_DATA)
-#define bf_isaggr(bf)		(bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isampdu(bf)		(bf->bf_state.bf_type & BUF_AMPDU)
-#define bf_isht(bf)		(bf->bf_state.bf_type & BUF_HT)
-#define bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
-#define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
-#define bf_isshpreamble(bf)	(bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
-#define bf_isbar(bf)		(bf->bf_state.bf_type & BUF_BAR)
-#define bf_ispspoll(bf) 	(bf->bf_state.bf_type & BUF_PSPOLL)
-#define bf_isaggrburst(bf)	(bf->bf_state.bf_type & BUF_AGGR_BURST)
-
-/*
- * Abstraction of a contiguous buffer to transmit/receive.  There is only
- * a single hw descriptor encapsulated here.
- */
-struct ath_buf {
-	struct list_head list;
-	struct list_head *last;
-	struct ath_buf *bf_lastbf;	/* last buf of this unit (a frame or
-					   an aggregate) */
-	struct ath_buf *bf_lastfrm;	/* last buf of this frame */
-	struct ath_buf *bf_next;	/* next subframe in the aggregate */
-	void *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 */
-	u32 bf_status;
-	u16 bf_flags;			/* tx descriptor flags */
-	struct ath_buf_state bf_state;	/* buffer state */
-	dma_addr_t bf_dmacontext;
-};
-
-#define ATH_RXBUF_RESET(_bf)    ((_bf)->bf_status = 0)
-
-/* hw processing complete, desc processed by hal */
-#define ATH_BUFSTATUS_DONE      0x00000001
-/* hw processing complete, desc hold for hw */
-#define ATH_BUFSTATUS_STALE     0x00000002
-/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
-#define ATH_BUFSTATUS_FREE      0x00000004
-
-/* DMA state for tx/rx descriptors */
-
-struct ath_descdma {
-	const char *dd_name;
-	struct ath_desc *dd_desc;	/* descriptors  */
-	dma_addr_t dd_desc_paddr;	/* physical addr of dd_desc  */
-	u32 dd_desc_len;		/* size of dd_desc  */
-	struct ath_buf *dd_bufptr;	/* associated buffers */
-	dma_addr_t dd_dmacontext;
-};
-
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-		      struct list_head *head, const char *name,
-		      int nbuf, int ndesc);
-void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
-			 struct list_head *head);
-
-/***********/
-/* RX / TX */
-/***********/
-
-#define ATH_MAX_ANTENNA         3
-#define ATH_RXBUF               512
-#define WME_NUM_TID             16
-#define ATH_TXBUF               512
-#define ATH_TXMAXTRY            13
-#define ATH_11N_TXMAXTRY        10
-#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 :	\
-	 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK :	\
-	 (((_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 */
-/* number of delimiters for encryption padding */
-#define ATH_AGGR_ENCRYPTDELIM      10
-/* minimum h/w qdepth to be sustained to maximize aggregation */
-#define ATH_AGGR_MIN_QDEPTH        2
-#define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define IEEE80211_SEQ_SEQ_SHIFT    4
-#define IEEE80211_SEQ_MAX          4096
-#define IEEE80211_MIN_AMPDU_BUF    0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-
-/* return whether a bit at index _n in bitmap _bm is set
- * _sz is the size of the bitmap  */
-#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&		\
-				((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
-/* return block-ack bitmap index given sequence and starting sequence */
-#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
-
-/* returns delimiter padding required given the packet length */
-#define ATH_AGGR_GET_NDELIM(_len)					\
-	(((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?           \
-	  (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
-
-#define BAW_WITHIN(_start, _bawsz, _seqno) \
-	((((_seqno) - (_start)) & 4095) < (_bawsz))
-
-#define ATH_DS_BA_SEQ(_ds)         ((_ds)->ds_us.tx.ts_seqnum)
-#define ATH_DS_BA_BITMAP(_ds)      (&(_ds)->ds_us.tx.ba_low)
-#define ATH_DS_TX_BA(_ds)          ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
-#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
-	ATH_AGGR_DONE,
-	ATH_AGGR_BAW_CLOSED,
-	ATH_AGGR_LIMITED,
-	ATH_AGGR_SHORTPKT,
-	ATH_AGGR_8K_LIMITED,
-};
-
-struct ath_txq {
-	u32 axq_qnum;			/* hardware q number */
-	u32 *axq_link;			/* link ptr in last TX desc */
-	struct list_head axq_q;		/* transmit queue */
-	spinlock_t axq_lock;
-	unsigned long axq_lockflags;	/* intr state when must cli */
-	u32 axq_depth;			/* queue depth */
-	u8 axq_aggr_depth;		/* aggregates queued */
-	u32 axq_totalqueued;		/* total ever queued */
-	bool stopped;			/* Is mac80211 queue stopped ? */
-	struct ath_buf *axq_linkbuf;	/* virtual addr of last buffer*/
-
-	/* 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;
-};
-
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
-/* per TID aggregate tx state for a destination */
-struct ath_atx_tid {
-	struct list_head list;		/* round-robin tid entry */
-	struct list_head buf_q;		/* pending buffers */
-	struct ath_node *an;
-	struct ath_atx_ac *ac;
-	struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
-	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;
-	int addba_exchangeattempts;
-};
-
-/* per access-category aggregate tx state for a destination */
-struct ath_atx_ac {
-	int sched;			/* dest-ac is scheduled */
-	int qnum;			/* H/W queue number associated
-					   with this AC */
-	struct list_head list;		/* round-robin txq entry */
-	struct list_head tid_q;		/* queue of TIDs with buffers */
-};
-
-/* per-frame tx control block */
-struct ath_tx_control {
-	struct ath_txq *txq;
-	int if_id;
-};
-
-/* per frame tx status block */
-struct ath_xmit_status {
-	int retries;	/* number of retries to successufully
-			   transmit this frame */
-	int flags;	/* status of transmit */
-#define ATH_TX_ERROR        0x01
-#define ATH_TX_XRETRY       0x02
-#define ATH_TX_BAR          0x04
-};
-
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
-	int rssi;
-	int rssictl[ATH_MAX_ANTENNA];
-	int rssiextn[ATH_MAX_ANTENNA];
-	int rateieee;
-	int rateKbps;
-	int ratecode;
-	int flags;
-	u32 airtime;	/* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
-	int param_max_frames;
-	int param_max_len;
-	int param_rl;
-	int param_al;
-	struct ath_rc_series *param_rcs;
-};
-
-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;
-};
-
-struct ath_tx {
-	u16 seq_no;
-	u32 txqsetup;
-	int hwq_map[ATH9K_WME_AC_VO+1];
-	spinlock_t txbuflock;
-	struct list_head txbuf;
-	struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
-	struct ath_descdma txdma;
-};
-
-struct ath_rx {
-	u8 defant;
-	u8 rxotherant;
-	u32 *rxlink;
-	int bufsize;
-	unsigned int rxfilter;
-	spinlock_t rxflushlock;
-	spinlock_t rxbuflock;
-	struct list_head rxbuf;
-	struct ath_descdma rxdma;
-};
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_draintxq(struct ath_softc *sc, bool retry_tx);
-void ath_tx_draintxq(struct ath_softc *sc,
-		     struct ath_txq *txq, bool retry_tx);
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
-int ath_txq_update(struct ath_softc *sc, int qnum,
-		   struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
-		 struct ath_tx_control *txctl);
-void ath_tx_tasklet(struct ath_softc *sc);
-u32 ath_txq_depth(struct ath_softc *sc, int qnum);
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-void ath_tx_aggr_teardown(struct ath_softc *sc,	struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-		      u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-
-/********/
-/* VAPs */
-/********/
-
-/*
- * Define the scheme that we select MAC address for multiple
- * BSS on the same radio. The very first VAP will just use the MAC
- * address from the EEPROM. For the next 3 VAPs, we set the
- * U/L bit (bit 1) in MAC address, and use the next two bits as the
- * index of the VAP.
- */
-
-#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
-	((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
-
-struct ath_vap {
-	int av_bslot;
-	enum nl80211_iftype av_opmode;
-	struct ath_buf *av_bcbuf;
-	struct ath_tx_control av_btxctl;
-};
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-/*
- * Regardless of the number of beacons we stagger, (i.e. regardless of the
- * number of BSSIDs) if a given beacon does not go out even after waiting this
- * number of beacon intervals, the game's up.
- */
-#define BSTUCK_THRESH           	(9 * ATH_BCBUF)
-#define	ATH_BCBUF               	1
-#define ATH_DEFAULT_BINTVAL     	100 /* TU */
-#define ATH_DEFAULT_BMISS_LIMIT 	10
-#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
-
-struct ath_beacon_config {
-	u16 beacon_interval;
-	u16 listen_interval;
-	u16 dtim_period;
-	u16 bmiss_timeout;
-	u8 dtim_count;
-	u8 tim_offset;
-	union {
-		u64 last_tsf;
-		u8 last_tstamp[8];
-	} u; /* last received beacon/probe response timestamp of this BSS. */
-};
-
-struct ath_beacon {
-	enum {
-		OK,		/* no change needed */
-		UPDATE,		/* update pending */
-		COMMIT		/* beacon sent, commit change */
-	} updateslot;		/* slot time update fsm */
-
-	u32 beaconq;
-	u32 bmisscnt;
-	u32 ast_be_xmit;
-	u64 bc_tstamp;
-	int bslot[ATH_BCBUF];
-	int slottime;
-	int slotupdate;
-	struct ath9k_tx_queue_info beacon_qi;
-	struct ath_descdma bdma;
-	struct ath_txq *cabq;
-	struct list_head bbuf;
-};
-
-void ath9k_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, int if_id);
-int ath_beaconq_setup(struct ath_hal *ah);
-int ath_beacon_alloc(struct ath_softc *sc, int if_id);
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
-void ath_beacon_sync(struct ath_softc *sc, int if_id);
-
-/*******/
-/* ANI */
-/*******/
-
-/* ANI values for STA only.
-   FIXME: Add appropriate values for AP later */
-
-#define ATH_ANI_POLLINTERVAL    100     /* 100 milliseconds between ANI poll */
-#define ATH_SHORT_CALINTERVAL   1000    /* 1 second between calibrations */
-#define ATH_LONG_CALINTERVAL    30000   /* 30 seconds between calibrations */
-#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
-
-struct ath_ani {
-	bool sc_caldone;
-	int16_t sc_noise_floor;
-	unsigned int sc_longcal_timer;
-	unsigned int sc_shortcal_timer;
-	unsigned int sc_resetcal_timer;
-	unsigned int sc_checkani_timer;
-	struct timer_list timer;
-};
-
-/********************/
-/*   LED Control    */
-/********************/
-
-#define ATH_LED_PIN	1
-
-enum ath_led_type {
-	ATH_LED_RADIO,
-	ATH_LED_ASSOC,
-	ATH_LED_TX,
-	ATH_LED_RX
-};
-
-struct ath_led {
-	struct ath_softc *sc;
-	struct led_classdev led_cdev;
-	enum ath_led_type led_type;
-	char name[32];
-	bool registered;
-};
-
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL	2000 /* msecs */
-
-struct ath_rfkill {
-	struct rfkill *rfkill;
-	struct delayed_work rfkill_poll;
-	char rfkill_name[32];
-};
-
-/********************/
-/* Main driver core */
-/********************/
-
-/*
- * Default cache line size, in bytes.
- * 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 */
-#define IEEE80211_RATE_VAL      0x7f
-/*
- * 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_IF_ID_ANY   	0xff
-#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER   0x127
-#define ATH_RATE_DUMMY_MARKER   0
-
-enum PROT_MODE {
-	PROT_M_NONE = 0,
-	PROT_M_RTSCTS,
-	PROT_M_CTSONLY
-};
-
-#define SC_OP_INVALID		BIT(0)
-#define SC_OP_BEACONS		BIT(1)
-#define SC_OP_RXAGGR		BIT(2)
-#define SC_OP_TXAGGR		BIT(3)
-#define SC_OP_CHAINMASK_UPDATE	BIT(4)
-#define SC_OP_FULL_RESET	BIT(5)
-#define SC_OP_NO_RESET		BIT(6)
-#define SC_OP_PREAMBLE_SHORT	BIT(7)
-#define SC_OP_PROTECT_ENABLE	BIT(8)
-#define SC_OP_RXFLUSH		BIT(9)
-#define SC_OP_LED_ASSOCIATED	BIT(10)
-#define SC_OP_RFKILL_REGISTERED	BIT(11)
-#define SC_OP_RFKILL_SW_BLOCKED	BIT(12)
-#define SC_OP_RFKILL_HW_BLOCKED	BIT(13)
-
-struct ath_softc {
-	struct ieee80211_hw *hw;
-	struct pci_dev *pdev;
-	struct tasklet_struct intr_tq;
-	struct tasklet_struct bcon_tasklet;
-	struct ath_hal *sc_ah;
-	void __iomem *mem;
-	spinlock_t sc_resetlock;
-	spinlock_t sc_serial_rw;
-	struct mutex mutex;
-
-	u8 sc_curbssid[ETH_ALEN];
-	u8 sc_myaddr[ETH_ALEN];
-	u8 sc_bssidmask[ETH_ALEN];
-	u32 sc_intrstatus;
-	u32 sc_flags; /* SC_OP_* */
-	u16 sc_curtxpow;
-	u16 sc_curaid;
-	u16 sc_cachelsz;
-	u8 sc_nbcnvaps;
-	u16 sc_nvaps;
-	u8 sc_tx_chainmask;
-	u8 sc_rx_chainmask;
-	u32 sc_keymax;
-	DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
-	u8 sc_splitmic;
-	u8 sc_protrix;
-	enum ath9k_int sc_imask;
-	enum PROT_MODE sc_protmode;
-	enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
-	enum ath9k_ht_macmode tx_chan_width;
-
-	struct ath_config sc_config;
-	struct ath_rx rx;
-	struct ath_tx tx;
-	struct ath_beacon beacon;
-	struct ieee80211_vif *sc_vaps[ATH_BCBUF];
-	struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
-	struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
-	struct ath_rate_table *cur_rate_table;
-	struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
-	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-	struct ath_led radio_led;
-	struct ath_led assoc_led;
-	struct ath_led tx_led;
-	struct ath_led rx_led;
-	struct ath_rfkill rf_kill;
-	struct ath_ani sc_ani;
-	struct ath9k_node_stats sc_halstats;
-#ifdef CONFIG_ATH9K_DEBUG
-	struct ath9k_debug sc_debug;
-#endif
-};
-
-int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
-int ath_cabq_update(struct ath_softc *);
-
-/*
- * 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 inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val)
-{
-	if (ah->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);
-}
-
-static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset)
-{
-	u32 val;
-	if (ah->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;
-}
-
-#endif /* CORE_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/debug.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/debug.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,19 +14,21 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include <asm/unaligned.h>
+
+#include "ath9k.h"
 
 static unsigned int ath9k_debug = DBG_DEFAULT;
 module_param_named(debug, ath9k_debug, uint, 0);
 
+static struct dentry *ath9k_debugfs_root;
+
 void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
 {
 	if (!sc)
 		return;
 
-	if (sc->sc_debug.debug_mask & dbg_mask) {
+	if (sc->debug.debug_mask & dbg_mask) {
 		va_list args;
 
 		va_start(args, fmt);
@@ -46,7 +48,7 @@ static ssize_t read_file_dma(struct file
 			     size_t count, loff_t *ppos)
 {
 	struct ath_softc *sc = file->private_data;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	char buf[1024];
 	unsigned int len = 0;
 	u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
@@ -132,41 +134,41 @@ static const struct file_operations fops
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
 {
 	if (status)
-		sc->sc_debug.stats.istats.total++;
+		sc->debug.stats.istats.total++;
 	if (status & ATH9K_INT_RX)
-		sc->sc_debug.stats.istats.rxok++;
+		sc->debug.stats.istats.rxok++;
 	if (status & ATH9K_INT_RXEOL)
-		sc->sc_debug.stats.istats.rxeol++;
+		sc->debug.stats.istats.rxeol++;
 	if (status & ATH9K_INT_RXORN)
-		sc->sc_debug.stats.istats.rxorn++;
+		sc->debug.stats.istats.rxorn++;
 	if (status & ATH9K_INT_TX)
-		sc->sc_debug.stats.istats.txok++;
+		sc->debug.stats.istats.txok++;
 	if (status & ATH9K_INT_TXURN)
-		sc->sc_debug.stats.istats.txurn++;
+		sc->debug.stats.istats.txurn++;
 	if (status & ATH9K_INT_MIB)
-		sc->sc_debug.stats.istats.mib++;
+		sc->debug.stats.istats.mib++;
 	if (status & ATH9K_INT_RXPHY)
-		sc->sc_debug.stats.istats.rxphyerr++;
+		sc->debug.stats.istats.rxphyerr++;
 	if (status & ATH9K_INT_RXKCM)
-		sc->sc_debug.stats.istats.rx_keycache_miss++;
+		sc->debug.stats.istats.rx_keycache_miss++;
 	if (status & ATH9K_INT_SWBA)
-		sc->sc_debug.stats.istats.swba++;
+		sc->debug.stats.istats.swba++;
 	if (status & ATH9K_INT_BMISS)
-		sc->sc_debug.stats.istats.bmiss++;
+		sc->debug.stats.istats.bmiss++;
 	if (status & ATH9K_INT_BNR)
-		sc->sc_debug.stats.istats.bnr++;
+		sc->debug.stats.istats.bnr++;
 	if (status & ATH9K_INT_CST)
-		sc->sc_debug.stats.istats.cst++;
+		sc->debug.stats.istats.cst++;
 	if (status & ATH9K_INT_GTT)
-		sc->sc_debug.stats.istats.gtt++;
+		sc->debug.stats.istats.gtt++;
 	if (status & ATH9K_INT_TIM)
-		sc->sc_debug.stats.istats.tim++;
+		sc->debug.stats.istats.tim++;
 	if (status & ATH9K_INT_CABEND)
-		sc->sc_debug.stats.istats.cabend++;
+		sc->debug.stats.istats.cabend++;
 	if (status & ATH9K_INT_DTIMSYNC)
-		sc->sc_debug.stats.istats.dtimsync++;
+		sc->debug.stats.istats.dtimsync++;
 	if (status & ATH9K_INT_DTIM)
-		sc->sc_debug.stats.istats.dtim++;
+		sc->debug.stats.istats.dtim++;
 }
 
 static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -177,41 +179,41 @@ static ssize_t read_file_interrupt(struc
 	unsigned int len = 0;
 
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok);
+		"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol);
+		"%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn);
+		"%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok);
+		"%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn);
+		"%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib);
+		"%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr);
+		"%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss);
+		"%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba);
+		"%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss);
+		"%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr);
+		"%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst);
+		"%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt);
+		"%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim);
+		"%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend);
+		"%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync);
+		"%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim);
+		"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
 	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total);
+		"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
 
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
@@ -222,29 +224,308 @@ static const struct file_operations fops
 	.owner = THIS_MODULE
 };
 
-int ath9k_init_debug(struct ath_softc *sc)
+static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
 {
-	sc->sc_debug.debug_mask = ath9k_debug;
+	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;
 
-	sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-	if (!sc->sc_debug.debugfs_root)
-		goto err;
+	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+	final_ts_idx = tx_info_priv->tx.ts_rateindex;
+	idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
 
-	sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-						      sc->sc_debug.debugfs_root);
-	if (!sc->sc_debug.debugfs_phy)
+	sc->debug.stats.n_rcstats[idx].success++;
+}
+
+static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+	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;
+
+	tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+	final_ts_idx = tx_info_priv->tx.ts_rateindex;
+	idx = rates[final_ts_idx].idx;
+
+	sc->debug.stats.legacy_rcstats[idx].success++;
+}
+
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+	if (conf_is_ht(&sc->hw->conf))
+		ath_debug_stat_11n_rc(sc, skb);
+	else
+		ath_debug_stat_legacy_rc(sc, skb);
+}
+
+/* FIXME: legacy rates, later on .. */
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+			    int xretries, int retries, u8 per)
+{
+	if (conf_is_ht(&sc->hw->conf)) {
+		int idx = sc->cur_rate_table->info[rix].dot11rate;
+
+		sc->debug.stats.n_rcstats[idx].xretries += xretries;
+		sc->debug.stats.n_rcstats[idx].retries += retries;
+		sc->debug.stats.n_rcstats[idx].per = per;
+	}
+}
+
+static ssize_t ath_read_file_stat_11n_rc(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	char buf[1024];
+	unsigned int len = 0;
+	int i = 0;
+
+	len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
+		       "Retries", "XRetries", "PER");
+
+	for (i = 0; i <= 15; i++) {
+		len += snprintf(buf + len, sizeof(buf) - len,
+				"%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
+				sc->debug.stats.n_rcstats[i].success,
+				sc->debug.stats.n_rcstats[i].retries,
+				sc->debug.stats.n_rcstats[i].xretries,
+				sc->debug.stats.n_rcstats[i].per);
+	}
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
+					    char __user *user_buf,
+					    size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	char buf[512];
+	unsigned int len = 0;
+	int i = 0;
+
+	len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
+
+	for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
+		len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
+				sc->cur_rate_table->info[i].ratekbps / 1000,
+				sc->debug.stats.legacy_rcstats[i].success);
+	}
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+
+	if (sc->cur_rate_table == NULL)
+		return 0;
+
+	if (conf_is_ht(&sc->hw->conf))
+		return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
+	else
+		return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
+}
+
+static const struct file_operations fops_rcstat = {
+	.read = read_file_rcstat,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE
+};
+
+static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
+{
+	switch (state) {
+	case ATH_WIPHY_INACTIVE:
+		return "INACTIVE";
+	case ATH_WIPHY_ACTIVE:
+		return "ACTIVE";
+	case ATH_WIPHY_PAUSING:
+		return "PAUSING";
+	case ATH_WIPHY_PAUSED:
+		return "PAUSED";
+	case ATH_WIPHY_SCAN:
+		return "SCAN";
+	}
+	return "?";
+}
+
+static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	char buf[512];
+	unsigned int len = 0;
+	int i;
+	u8 addr[ETH_ALEN];
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"primary: %s (%s chan=%d ht=%d)\n",
+			wiphy_name(sc->pri_wiphy->hw->wiphy),
+			ath_wiphy_state_str(sc->pri_wiphy->state),
+			sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (aphy == NULL)
+			continue;
+		len += snprintf(buf + len, sizeof(buf) - len,
+				"secondary: %s (%s chan=%d ht=%d)\n",
+				wiphy_name(aphy->hw->wiphy),
+				ath_wiphy_state_str(aphy->state),
+				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);
+	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);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"addrmask: %pM\n", addr);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
+{
+	int i;
+	if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
+		return sc->pri_wiphy;
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
+			return aphy;
+	}
+	return NULL;
+}
+
+static int del_wiphy(struct ath_softc *sc, const char *name)
+{
+	struct ath_wiphy *aphy = get_wiphy(sc, name);
+	if (!aphy)
+		return -ENOENT;
+	return ath9k_wiphy_del(aphy);
+}
+
+static int pause_wiphy(struct ath_softc *sc, const char *name)
+{
+	struct ath_wiphy *aphy = get_wiphy(sc, name);
+	if (!aphy)
+		return -ENOENT;
+	return ath9k_wiphy_pause(aphy);
+}
+
+static int unpause_wiphy(struct ath_softc *sc, const char *name)
+{
+	struct ath_wiphy *aphy = get_wiphy(sc, name);
+	if (!aphy)
+		return -ENOENT;
+	return ath9k_wiphy_unpause(aphy);
+}
+
+static int select_wiphy(struct ath_softc *sc, const char *name)
+{
+	struct ath_wiphy *aphy = get_wiphy(sc, name);
+	if (!aphy)
+		return -ENOENT;
+	return ath9k_wiphy_select(aphy);
+}
+
+static int schedule_wiphy(struct ath_softc *sc, const char *msec)
+{
+	ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
+	return 0;
+}
+
+static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	char buf[50];
+	size_t len;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	if (len > 0 && buf[len - 1] == '\n')
+		buf[len - 1] = '\0';
+
+	if (strncmp(buf, "add", 3) == 0) {
+		int res = ath9k_wiphy_add(sc);
+		if (res < 0)
+			return res;
+	} else if (strncmp(buf, "del=", 4) == 0) {
+		int res = del_wiphy(sc, buf + 4);
+		if (res < 0)
+			return res;
+	} else if (strncmp(buf, "pause=", 6) == 0) {
+		int res = pause_wiphy(sc, buf + 6);
+		if (res < 0)
+			return res;
+	} else if (strncmp(buf, "unpause=", 8) == 0) {
+		int res = unpause_wiphy(sc, buf + 8);
+		if (res < 0)
+			return res;
+	} else if (strncmp(buf, "select=", 7) == 0) {
+		int res = select_wiphy(sc, buf + 7);
+		if (res < 0)
+			return res;
+	} else if (strncmp(buf, "schedule=", 9) == 0) {
+		int res = schedule_wiphy(sc, buf + 9);
+		if (res < 0)
+			return res;
+	} else
+		return -EOPNOTSUPP;
+
+	return count;
+}
+
+static const struct file_operations fops_wiphy = {
+	.read = read_file_wiphy,
+	.write = write_file_wiphy,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE
+};
+
+
+int ath9k_init_debug(struct ath_softc *sc)
+{
+	sc->debug.debug_mask = ath9k_debug;
+
+	sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+						      ath9k_debugfs_root);
+	if (!sc->debug.debugfs_phy)
 		goto err;
 
-	sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
-				       sc->sc_debug.debugfs_phy, sc, &fops_dma);
-	if (!sc->sc_debug.debugfs_dma)
+	sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+				       sc->debug.debugfs_phy, sc, &fops_dma);
+	if (!sc->debug.debugfs_dma)
 		goto err;
 
-	sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt",
+	sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
 						     S_IRUGO,
-						     sc->sc_debug.debugfs_phy,
+						     sc->debug.debugfs_phy,
 						     sc, &fops_interrupt);
-	if (!sc->sc_debug.debugfs_interrupt)
+	if (!sc->debug.debugfs_interrupt)
+		goto err;
+
+	sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
+						  S_IRUGO,
+						  sc->debug.debugfs_phy,
+						  sc, &fops_rcstat);
+	if (!sc->debug.debugfs_rcstat)
+		goto err;
+
+	sc->debug.debugfs_wiphy = debugfs_create_file(
+		"wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+		&fops_wiphy);
+	if (!sc->debug.debugfs_wiphy)
 		goto err;
 
 	return 0;
@@ -255,8 +536,24 @@ err:
 
 void ath9k_exit_debug(struct ath_softc *sc)
 {
-	debugfs_remove(sc->sc_debug.debugfs_interrupt);
-	debugfs_remove(sc->sc_debug.debugfs_dma);
-	debugfs_remove(sc->sc_debug.debugfs_phy);
-	debugfs_remove(sc->sc_debug.debugfs_root);
+	debugfs_remove(sc->debug.debugfs_wiphy);
+	debugfs_remove(sc->debug.debugfs_rcstat);
+	debugfs_remove(sc->debug.debugfs_interrupt);
+	debugfs_remove(sc->debug.debugfs_dma);
+	debugfs_remove(sc->debug.debugfs_phy);
+}
+
+int ath9k_debug_create_root(void)
+{
+	ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+	if (!ath9k_debugfs_root)
+		return -ENOENT;
+
+	return 0;
+}
+
+void ath9k_debug_remove_root(void)
+{
+	debugfs_remove(ath9k_debugfs_root);
+	ath9k_debugfs_root = NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/debug.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/debug.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/debug.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * 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 DEBUG_H
+#define DEBUG_H
+
+enum ATH_DEBUG {
+	ATH_DBG_RESET		= 0x00000001,
+	ATH_DBG_REG_IO		= 0x00000002,
+	ATH_DBG_QUEUE		= 0x00000004,
+	ATH_DBG_EEPROM		= 0x00000008,
+	ATH_DBG_CALIBRATE	= 0x00000010,
+	ATH_DBG_CHANNEL		= 0x00000020,
+	ATH_DBG_INTERRUPT	= 0x00000040,
+	ATH_DBG_REGULATORY	= 0x00000080,
+	ATH_DBG_ANI		= 0x00000100,
+	ATH_DBG_POWER_MGMT	= 0x00000200,
+	ATH_DBG_XMIT		= 0x00000400,
+	ATH_DBG_BEACON		= 0x00001000,
+	ATH_DBG_CONFIG		= 0x00002000,
+	ATH_DBG_KEYCACHE	= 0x00004000,
+	ATH_DBG_FATAL		= 0x00008000,
+	ATH_DBG_ANY		= 0xffffffff
+};
+
+#define DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH9K_DEBUG
+
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+	u32 total;
+	u32 rxok;
+	u32 rxeol;
+	u32 rxorn;
+	u32 txok;
+	u32 txeol;
+	u32 txurn;
+	u32 mib;
+	u32 rxphyerr;
+	u32 rx_keycache_miss;
+	u32 swba;
+	u32 bmiss;
+	u32 bnr;
+	u32 cst;
+	u32 gtt;
+	u32 tim;
+	u32 cabend;
+	u32 dtimsync;
+	u32 dtim;
+};
+
+struct ath_legacy_rc_stats {
+	u32 success;
+};
+
+struct ath_11n_rc_stats {
+	u32 success;
+	u32 retries;
+	u32 xretries;
+	u8 per;
+};
+
+struct ath_stats {
+	struct ath_interrupt_stats istats;
+	struct ath_legacy_rc_stats legacy_rcstats[12];	/* max(11a,11b,11g) */
+	struct ath_11n_rc_stats n_rcstats[16];		/* 0..15 MCS rates */
+};
+
+struct ath9k_debug {
+	int debug_mask;
+	struct dentry *debugfs_phy;
+	struct dentry *debugfs_dma;
+	struct dentry *debugfs_interrupt;
+	struct dentry *debugfs_rcstat;
+	struct dentry *debugfs_wiphy;
+	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_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_retries(struct ath_softc *sc, int rix,
+			    int xretries, int retries, u8 per);
+
+#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)
+{
+	return 0;
+}
+
+static inline void ath9k_exit_debug(struct ath_softc *sc)
+{
+}
+
+static inline int ath9k_debug_create_root(void)
+{
+	return 0;
+}
+
+static inline void ath9k_debug_remove_root(void)
+{
+}
+
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+					    enum ath9k_int status)
+{
+}
+
+static inline void ath_debug_stat_rc(struct ath_softc *sc,
+				     struct sk_buff *skb)
+{
+}
+
+static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+					  int xretries, int retries, u8 per)
+{
+}
+
+#endif /* CONFIG_ATH9K_DEBUG */
+
+#endif /* DEBUG_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/eeprom.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/eeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,12 +14,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
 
-static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
+static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
 				      u32 reg, u32 mask,
 				      u32 shift, u32 val)
 {
@@ -30,7 +27,7 @@ static void ath9k_hw_analog_shift_rmw(st
 
 	REG_WRITE(ah, reg, regVal);
 
-	if (ah->ah_config.analog_shiftreg)
+	if (ah->config.analog_shiftreg)
 		udelay(100);
 
 	return;
@@ -91,254 +88,288 @@ static inline bool ath9k_hw_get_lower_up
 	return false;
 }
 
-static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
 {
-	(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-
-	if (!ath9k_hw_wait(ah,
-			   AR_EEPROM_STATUS_DATA,
-			   AR_EEPROM_STATUS_DATA_BUSY |
-			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
-		return false;
-	}
-
-	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
-		   AR_EEPROM_STATUS_DATA_VAL);
+	struct ath_softc *sc = ah->ah_sc;
 
-	return true;
+	return sc->bus_ops->eeprom_read(ah, off, data);
 }
 
-static int ath9k_hw_flash_map(struct ath_hal *ah)
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+					   u8 *pVpdList, u16 numIntercepts,
+					   u8 *pRetVpdList)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
+	u16 i, k;
+	u8 currPwr = pwrMin;
+	u16 idxL = 0, idxR = 0;
 
-	if (!ahp->ah_cal_mem) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"cannot remap eeprom region \n");
-		return -EIO;
+	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+		ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+					       numIntercepts, &(idxL),
+					       &(idxR));
+		if (idxR < 1)
+			idxR = 1;
+		if (idxL == numIntercepts - 1)
+			idxL = (u16) (numIntercepts - 2);
+		if (pPwrList[idxL] == pPwrList[idxR])
+			k = pVpdList[idxL];
+		else
+			k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+				   (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+				  (pPwrList[idxR] - pPwrList[idxL]));
+		pRetVpdList[i] = (u8) k;
+		currPwr += 2;
 	}
 
-	return 0;
-}
-
-static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	*data = ioread16(ahp->ah_cal_mem + off);
-
 	return true;
 }
 
-static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
-{
-	if (ath9k_hw_use_flash(ah))
-		return ath9k_hw_flash_read(ah, off, data);
-	else
-		return ath9k_hw_eeprom_read(ah, off, data);
-}
-
-static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
+static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+				      struct ath9k_channel *chan,
+				      struct cal_target_power_leg *powInfo,
+				      u16 numChannels,
+				      struct cal_target_power_leg *pNewPower,
+				      u16 numRates, bool isExtTarget)
 {
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
-	u16 *eep_data;
-	int addr, eep_start_loc = 0;
+	struct chan_centers centers;
+	u16 clo, chi;
+	int i;
+	int matchIndex = -1, lowIndex = -1;
+	u16 freq;
 
-	eep_start_loc = 64;
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
 
-	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Reading from EEPROM, not flash\n");
+	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+				       IS_CHAN_2GHZ(chan))) {
+		matchIndex = 0;
+	} else {
+		for (i = 0; (i < numChannels) &&
+			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						       IS_CHAN_2GHZ(chan))) {
+				matchIndex = i;
+				break;
+			} else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						      IS_CHAN_2GHZ(chan))) &&
+				   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+						      IS_CHAN_2GHZ(chan)))) {
+				lowIndex = i - 1;
+				break;
+			}
+		}
+		if ((matchIndex == -1) && (lowIndex == -1))
+			matchIndex = i - 1;
 	}
 
-	eep_data = (u16 *)eep;
+	if (matchIndex != -1) {
+		*pNewPower = powInfo[matchIndex];
+	} else {
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+					 IS_CHAN_2GHZ(chan));
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+					 IS_CHAN_2GHZ(chan));
 
-	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");
-			return false;
+		for (i = 0; i < numRates; i++) {
+			pNewPower->tPow2x[i] =
+				(u8)ath9k_hw_interpolate(freq, clo, chi,
+						powInfo[lowIndex].tPow2x[i],
+						powInfo[lowIndex + 1].tPow2x[i]);
 		}
-		eep_data++;
 	}
-	return true;
-#undef SIZE_EEPROM_4K
 }
 
-static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+		struct ath9k_channel *chan,
+		struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+		u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
 {
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
-	u16 *eep_data;
-	int addr, ar5416_eep_start_loc = 0x100;
+	u8 pcdac, i = 0;
+	u16 idxL = 0, idxR = 0, numPiers;
+	bool match;
+	struct chan_centers centers;
 
-	eep_data = (u16 *)eep;
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
 
-	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
-		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
-					 eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"Unable to read eeprom region\n");
-			return false;
-		}
-		eep_data++;
-	}
-	return true;
-#undef SIZE_EEPROM_DEF
-}
+	for (numPiers = 0; numPiers < availPiers; numPiers++)
+		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
 
-static bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
-	ath9k_hw_fill_def_eeprom,
-	ath9k_hw_fill_4k_eeprom
-};
+	match = ath9k_hw_get_lower_upper_index(
+			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+			calChans, numPiers, &idxL, &idxR);
+	if (match) {
+		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+	} else {
+		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+	}
 
-static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	while (pcdac > ah->originalGain[i] &&
+			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+		i++;
 
-	return ath9k_fill_eeprom[ahp->ah_eep_map](ah);
+	*pcdacIdx = i;
+	return;
 }
 
-static int ath9k_hw_check_def_eeprom(struct ath_hal *ah)
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+				u32 initTxGain,
+				int txPower,
+				u8 *pPDADCValues)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep =
-		(struct ar5416_eeprom_def *) &ahp->ah_eeprom.def;
-	u16 *eepdata, temp, magic, magic2;
-	u32 sum = 0, el;
-	bool need_swap = false;
-	int i, addr, size;
+	u32 i;
+	u32 offset;
 
-	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
-				 &magic)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Reading Magic # failed\n");
-		return false;
-	}
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
 
-	if (!ath9k_hw_use_flash(ah)) {
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+			AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"Read Magic = 0x%04X\n", magic);
+	offset = txPower;
+	for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+		if (i < offset)
+			pPDADCValues[i] = 0x0;
+		else
+			pPDADCValues[i] = 0xFF;
+}
 
-		if (magic != AR5416_EEPROM_MAGIC) {
-			magic2 = swab16(magic);
 
-			if (magic2 == AR5416_EEPROM_MAGIC) {
-				size = sizeof(struct ar5416_eeprom_def);
-				need_swap = true;
-				eepdata = (u16 *) (&ahp->ah_eeprom);
 
-				for (addr = 0; addr < size / sizeof(u16); addr++) {
-					temp = swab16(*eepdata);
-					*eepdata = temp;
-					eepdata++;
 
-					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-						"0x%04X  ", *eepdata);
+static void ath9k_hw_get_target_powers(struct ath_hw *ah,
+				       struct ath9k_channel *chan,
+				       struct cal_target_power_ht *powInfo,
+				       u16 numChannels,
+				       struct cal_target_power_ht *pNewPower,
+				       u16 numRates, bool isHt40Target)
+{
+	struct chan_centers centers;
+	u16 clo, chi;
+	int i;
+	int matchIndex = -1, lowIndex = -1;
+	u16 freq;
 
-					if (((addr + 1) % 6) == 0)
-						DPRINTF(ah->ah_sc,
-							ATH_DBG_EEPROM, "\n");
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+		matchIndex = 0;
+	} else {
+		for (i = 0; (i < numChannels) &&
+			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						       IS_CHAN_2GHZ(chan))) {
+				matchIndex = i;
+				break;
+			} else
+				if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						       IS_CHAN_2GHZ(chan))) &&
+				    (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+						       IS_CHAN_2GHZ(chan)))) {
+					lowIndex = i - 1;
+					break;
 				}
-			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"Invalid EEPROM Magic. "
-					"endianness mismatch.\n");
-				return -EINVAL;
-			}
 		}
+		if ((matchIndex == -1) && (lowIndex == -1))
+			matchIndex = i - 1;
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-		need_swap ? "True" : "False");
-
-	if (need_swap)
-		el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
-	else
-		el = ahp->ah_eeprom.def.baseEepHeader.length;
-
-	if (el > sizeof(struct ar5416_eeprom_def))
-		el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
-	else
-		el = el / sizeof(u16);
-
-	eepdata = (u16 *)(&ahp->ah_eeprom);
-
-	for (i = 0; i < el; i++)
-		sum ^= *eepdata++;
-
-	if (need_swap) {
-		u32 integer, j;
-		u16 word;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing \n");
-
-		word = swab16(eep->baseEepHeader.length);
-		eep->baseEepHeader.length = word;
+	if (matchIndex != -1) {
+		*pNewPower = powInfo[matchIndex];
+	} else {
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+					 IS_CHAN_2GHZ(chan));
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+					 IS_CHAN_2GHZ(chan));
 
-		word = swab16(eep->baseEepHeader.checksum);
-		eep->baseEepHeader.checksum = word;
+		for (i = 0; i < numRates; i++) {
+			pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+						clo, chi,
+						powInfo[lowIndex].tPow2x[i],
+						powInfo[lowIndex + 1].tPow2x[i]);
+		}
+	}
+}
 
-		word = swab16(eep->baseEepHeader.version);
-		eep->baseEepHeader.version = word;
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+				       struct cal_ctl_edges *pRdEdgesPower,
+				       bool is2GHz, int num_band_edges)
+{
+	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	int i;
 
-		word = swab16(eep->baseEepHeader.regDmn[0]);
-		eep->baseEepHeader.regDmn[0] = word;
+	for (i = 0; (i < num_band_edges) &&
+		     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+			twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+			break;
+		} else if ((i > 0) &&
+			   (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+						      is2GHz))) {
+			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+					       is2GHz) < freq &&
+			    pRdEdgesPower[i - 1].flag) {
+				twiceMaxEdgePower =
+					pRdEdgesPower[i - 1].tPower;
+			}
+			break;
+		}
+	}
 
-		word = swab16(eep->baseEepHeader.regDmn[1]);
-		eep->baseEepHeader.regDmn[1] = word;
+	return twiceMaxEdgePower;
+}
 
-		word = swab16(eep->baseEepHeader.rfSilent);
-		eep->baseEepHeader.rfSilent = word;
+/****************************************/
+/* EEPROM Operations for 4K sized cards */
+/****************************************/
 
-		word = swab16(eep->baseEepHeader.blueToothOptions);
-		eep->baseEepHeader.blueToothOptions = word;
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+	return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
 
-		word = swab16(eep->baseEepHeader.deviceCap);
-		eep->baseEepHeader.deviceCap = word;
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+	return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
 
-		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
-			struct modal_eep_header *pModal =
-				&eep->modalHeader[j];
-			integer = swab32(pModal->antCtrlCommon);
-			pModal->antCtrlCommon = integer;
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+	int addr, eep_start_loc = 0;
 
-			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-				integer = swab32(pModal->antCtrlChain[i]);
-				pModal->antCtrlChain[i] = integer;
-			}
+	eep_start_loc = 64;
 
-			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-				word = swab16(pModal->spurChans[i].spurChan);
-				pModal->spurChans[i].spurChan = word;
-			}
-		}
+	if (!ath9k_hw_use_flash(ah)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Reading from EEPROM, not flash\n");
 	}
 
-	if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
-	    ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-			sum, ar5416_get_eep_ver(ahp));
-		return -EINVAL;
+	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");
+			return false;
+		}
+		eep_data++;
 	}
 
-	return 0;
+	return true;
+#undef SIZE_EEPROM_4K
 }
 
-static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
 {
 #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ar5416_eeprom_4k *eep =
-		(struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k;
+		(struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
 	u16 *eepdata, temp, magic, magic2;
 	u32 sum = 0, el;
 	bool need_swap = false;
@@ -346,38 +377,30 @@ static int ath9k_hw_check_4k_eeprom(stru
 
 
 	if (!ath9k_hw_use_flash(ah)) {
-
 		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
 					 &magic)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 				"Reading Magic # failed\n");
 			return false;
 		}
 
 		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"Read Magic = 0x%04X\n", magic);
+			"Read Magic = 0x%04X\n", magic);
 
 		if (magic != AR5416_EEPROM_MAGIC) {
 			magic2 = swab16(magic);
 
 			if (magic2 == AR5416_EEPROM_MAGIC) {
 				need_swap = true;
-				eepdata = (u16 *) (&ahp->ah_eeprom);
+				eepdata = (u16 *) (&ah->eeprom);
 
 				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
 					temp = swab16(*eepdata);
 					*eepdata = temp;
 					eepdata++;
-
-					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-						"0x%04X  ", *eepdata);
-
-					if (((addr + 1) % 6) == 0)
-						DPRINTF(ah->ah_sc,
-							ATH_DBG_EEPROM, "\n");
 				}
 			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 					"Invalid EEPROM Magic. "
 					"endianness mismatch.\n");
 				return -EINVAL;
@@ -389,16 +412,16 @@ static int ath9k_hw_check_4k_eeprom(stru
 		need_swap ? "True" : "False");
 
 	if (need_swap)
-		el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
+		el = swab16(ah->eeprom.map4k.baseEepHeader.length);
 	else
-		el = ahp->ah_eeprom.map4k.baseEepHeader.length;
+		el = ah->eeprom.map4k.baseEepHeader.length;
 
-	if (el > sizeof(struct ar5416_eeprom_def))
+	if (el > sizeof(struct ar5416_eeprom_4k))
 		el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
 	else
 		el = el / sizeof(u16);
 
-	eepdata = (u16 *)(&ahp->ah_eeprom);
+	eepdata = (u16 *)(&ah->eeprom);
 
 	for (i = 0; i < el; i++)
 		sum ^= *eepdata++;
@@ -408,7 +431,7 @@ static int ath9k_hw_check_4k_eeprom(stru
 		u16 word;
 
 		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing \n");
+			"EEPROM Endianness is not native.. Changing\n");
 
 		word = swab16(eep->baseEepHeader.length);
 		eep->baseEepHeader.length = word;
@@ -448,11 +471,11 @@ static int ath9k_hw_check_4k_eeprom(stru
 		}
 	}
 
-	if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
-	    ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+	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, ar5416_get_eep4k_ver(ahp));
+			sum, ah->eep_ops->get_eeprom_ver(ah));
 		return -EINVAL;
 	}
 
@@ -460,48 +483,50 @@ static int ath9k_hw_check_4k_eeprom(stru
 #undef EEPROM_4K_SIZE
 }
 
-static int (*ath9k_check_eeprom[]) (struct ath_hal *) = {
-	ath9k_hw_check_def_eeprom,
-	ath9k_hw_check_4k_eeprom
-};
-
-static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	return ath9k_check_eeprom[ahp->ah_eep_map](ah);
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
-					   u8 *pVpdList, u16 numIntercepts,
-					   u8 *pRetVpdList)
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+				  enum eeprom_param param)
 {
-	u16 i, k;
-	u8 currPwr = pwrMin;
-	u16 idxL = 0, idxR = 0;
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
 
-	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
-		ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
-					       numIntercepts, &(idxL),
-					       &(idxR));
-		if (idxR < 1)
-			idxR = 1;
-		if (idxL == numIntercepts - 1)
-			idxL = (u16) (numIntercepts - 2);
-		if (pPwrList[idxL] == pPwrList[idxR])
-			k = pVpdList[idxL];
-		else
-			k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
-				   (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
-				  (pPwrList[idxR] - pPwrList[idxL]));
-		pRetVpdList[i] = (u8) k;
-		currPwr += 2;
+	switch (param) {
+	case EEP_NFTHRESH_2:
+		return pModal->noiseFloorThreshCh[0];
+	case AR_EEPROM_MAC(0):
+		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+	case AR_EEPROM_MAC(1):
+		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+	case AR_EEPROM_MAC(2):
+		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_OB_2:
+		return pModal->ob_01;
+	case EEP_DB_2:
+		return pModal->db1_01;
+	case EEP_MINOR_REV:
+		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+	case EEP_TX_MASK:
+		return pBase->txMask;
+	case EEP_RX_MASK:
+		return pBase->rxMask;
+	case EEP_FRAC_N_5G:
+		return 0;
+	default:
+		return 0;
 	}
-
-	return true;
 }
 
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
 				struct ath9k_channel *chan,
 				struct cal_data_per_freq_4k *pRawDataSet,
 				u8 *bChans, u16 availPiers,
@@ -605,7 +630,7 @@ static void ath9k_hw_get_4k_gain_boundar
 		pPdGainBoundaries[i] =
 			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
 
-		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
 			minDelta = pPdGainBoundaries[0] - 23;
 			pPdGainBoundaries[0] = 23;
 		} else {
@@ -644,7 +669,7 @@ static void ath9k_hw_get_4k_gain_boundar
 				    vpdTableI[i][sizeCurrVpdTable - 2]);
 		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
 
-		if (tgtIndex > maxIndex) {
+		if (tgtIndex >= maxIndex) {
 			while ((ss <= tgtIndex) &&
 			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
 				tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
@@ -669,451 +694,20 @@ static void ath9k_hw_get_4k_gain_boundar
 #undef TMP_VAL_VPD_TABLE
 }
 
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
-				struct ath9k_channel *chan,
-				struct cal_data_per_freq *pRawDataSet,
-				u8 *bChans, u16 availPiers,
-				u16 tPdGainOverlap, int16_t *pMinCalPower,
-				u16 *pPdGainBoundaries, u8 *pPDADCValues,
-				u16 numXpdGains)
-{
-	int i, j, k;
-	int16_t ss;
-	u16 idxL = 0, idxR = 0, numPiers;
-	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-	u8 minPwrT4[AR5416_NUM_PD_GAINS];
-	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
-	int16_t vpdStep;
-	int16_t tmpVal;
-	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-	bool match;
-	int16_t minDelta = 0;
-	struct chan_centers centers;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	for (numPiers = 0; numPiers < availPiers; numPiers++) {
-		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-			break;
-	}
-
-	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
-							     IS_CHAN_2GHZ(chan)),
-					       bChans, numPiers, &idxL, &idxR);
-
-	if (match) {
-		for (i = 0; i < numXpdGains; i++) {
-			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-					pRawDataSet[idxL].pwrPdg[i],
-					pRawDataSet[idxL].vpdPdg[i],
-					AR5416_PD_GAIN_ICEPTS,
-					vpdTableI[i]);
-		}
-	} else {
-		for (i = 0; i < numXpdGains; i++) {
-			pVpdL = pRawDataSet[idxL].vpdPdg[i];
-			pPwrL = pRawDataSet[idxL].pwrPdg[i];
-			pVpdR = pRawDataSet[idxR].vpdPdg[i];
-			pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-			maxPwrT4[i] =
-				min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
-				    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrL, pVpdL,
-						AR5416_PD_GAIN_ICEPTS,
-						vpdTableL[i]);
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrR, pVpdR,
-						AR5416_PD_GAIN_ICEPTS,
-						vpdTableR[i]);
-
-			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-				vpdTableI[i][j] =
-					(u8)(ath9k_hw_interpolate((u16)
-					     FREQ2FBIN(centers.
-						       synth_center,
-						       IS_CHAN_2GHZ
-						       (chan)),
-					     bChans[idxL], bChans[idxR],
-					     vpdTableL[i][j], vpdTableR[i][j]));
-			}
-		}
-	}
-
-	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
-	k = 0;
-
-	for (i = 0; i < numXpdGains; i++) {
-		if (i == (numXpdGains - 1))
-			pPdGainBoundaries[i] =
-				(u16)(maxPwrT4[i] / 2);
-		else
-			pPdGainBoundaries[i] =
-				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-		pPdGainBoundaries[i] =
-			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
-			minDelta = pPdGainBoundaries[0] - 23;
-			pPdGainBoundaries[0] = 23;
-		} else {
-			minDelta = 0;
-		}
-
-		if (i == 0) {
-			if (AR_SREV_9280_10_OR_LATER(ah))
-				ss = (int16_t)(0 - (minPwrT4[i] / 2));
-			else
-				ss = 0;
-		} else {
-			ss = (int16_t)((pPdGainBoundaries[i - 1] -
-					(minPwrT4[i] / 2)) -
-				       tPdGainOverlap + 1 + minDelta);
-		}
-		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
-			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-			ss++;
-		}
-
-		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
-				(minPwrT4[i] / 2));
-		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
-			tgtIndex : sizeCurrVpdTable;
-
-		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-			pPDADCValues[k++] = vpdTableI[i][ss++];
-		}
-
-		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
-				    vpdTableI[i][sizeCurrVpdTable - 2]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		if (tgtIndex > maxIndex) {
-			while ((ss <= tgtIndex) &&
-			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
-						    (ss - maxIndex + 1) * vpdStep));
-				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
-							 255 : tmpVal);
-				ss++;
-			}
-		}
-	}
-
-	while (i < AR5416_PD_GAINS_IN_MASK) {
-		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
-		i++;
-	}
-
-	while (k < AR5416_NUM_PDADC_VALUES) {
-		pPDADCValues[k] = pPDADCValues[k - 1];
-		k++;
-	}
-
-	return;
-}
-
-static void ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
-				      struct ath9k_channel *chan,
-				      struct cal_target_power_leg *powInfo,
-				      u16 numChannels,
-				      struct cal_target_power_leg *pNewPower,
-				      u16 numRates, bool isExtTarget)
-{
-	struct chan_centers centers;
-	u16 clo, chi;
-	int i;
-	int matchIndex = -1, lowIndex = -1;
-	u16 freq;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
-
-	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
-				       IS_CHAN_2GHZ(chan))) {
-		matchIndex = 0;
-	} else {
-		for (i = 0; (i < numChannels) &&
-			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						       IS_CHAN_2GHZ(chan))) {
-				matchIndex = i;
-				break;
-			} else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						      IS_CHAN_2GHZ(chan))) &&
-				   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-						      IS_CHAN_2GHZ(chan)))) {
-				lowIndex = i - 1;
-				break;
-			}
-		}
-		if ((matchIndex == -1) && (lowIndex == -1))
-			matchIndex = i - 1;
-	}
-
-	if (matchIndex != -1) {
-		*pNewPower = powInfo[matchIndex];
-	} else {
-		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-					 IS_CHAN_2GHZ(chan));
-		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-					 IS_CHAN_2GHZ(chan));
-
-		for (i = 0; i < numRates; i++) {
-			pNewPower->tPow2x[i] =
-				(u8)ath9k_hw_interpolate(freq, clo, chi,
-						powInfo[lowIndex].tPow2x[i],
-						powInfo[lowIndex + 1].tPow2x[i]);
-		}
-	}
-}
-
-static void ath9k_hw_get_target_powers(struct ath_hal *ah,
-				       struct ath9k_channel *chan,
-				       struct cal_target_power_ht *powInfo,
-				       u16 numChannels,
-				       struct cal_target_power_ht *pNewPower,
-				       u16 numRates, bool isHt40Target)
-{
-	struct chan_centers centers;
-	u16 clo, chi;
-	int i;
-	int matchIndex = -1, lowIndex = -1;
-	u16 freq;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = isHt40Target ? centers.synth_center : centers.ctl_center;
-
-	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
-		matchIndex = 0;
-	} else {
-		for (i = 0; (i < numChannels) &&
-			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						       IS_CHAN_2GHZ(chan))) {
-				matchIndex = i;
-				break;
-			} else
-				if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						       IS_CHAN_2GHZ(chan))) &&
-				    (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-						       IS_CHAN_2GHZ(chan)))) {
-					lowIndex = i - 1;
-					break;
-				}
-		}
-		if ((matchIndex == -1) && (lowIndex == -1))
-			matchIndex = i - 1;
-	}
-
-	if (matchIndex != -1) {
-		*pNewPower = powInfo[matchIndex];
-	} else {
-		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-					 IS_CHAN_2GHZ(chan));
-		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-					 IS_CHAN_2GHZ(chan));
-
-		for (i = 0; i < numRates; i++) {
-			pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
-						clo, chi,
-						powInfo[lowIndex].tPow2x[i],
-						powInfo[lowIndex + 1].tPow2x[i]);
-		}
-	}
-}
-
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
-				       struct cal_ctl_edges *pRdEdgesPower,
-				       bool is2GHz, int num_band_edges)
-{
-	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-	int i;
-
-	for (i = 0; (i < num_band_edges) &&
-		     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
-			twiceMaxEdgePower = pRdEdgesPower[i].tPower;
-			break;
-		} else if ((i > 0) &&
-			   (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
-						      is2GHz))) {
-			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
-					       is2GHz) < freq &&
-			    pRdEdgesPower[i - 1].flag) {
-				twiceMaxEdgePower =
-					pRdEdgesPower[i - 1].tPower;
-			}
-			break;
-		}
-	}
-
-	return twiceMaxEdgePower;
-}
-
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
-				  struct ath9k_channel *chan,
-				  int16_t *pTxPowerIndexOffset)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
-	struct cal_data_per_freq *pRawDataset;
-	u8 *pCalBChans = NULL;
-	u16 pdGainOverlap_t2;
-	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
-	u16 numPiers, i, j;
-	int16_t tMinCalPower;
-	u16 numXpdGain, xpdMask;
-	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
-	u32 reg32, regOffset, regChainOffset;
-	int16_t modalIdx;
-
-	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
-	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		pdGainOverlap_t2 =
-			pEepData->modalHeader[modalIdx].pdGainOverlap;
-	} else {
-		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-	}
-
-	if (IS_CHAN_2GHZ(chan)) {
-		pCalBChans = pEepData->calFreqPier2G;
-		numPiers = AR5416_NUM_2G_CAL_PIERS;
-	} else {
-		pCalBChans = pEepData->calFreqPier5G;
-		numPiers = AR5416_NUM_5G_CAL_PIERS;
-	}
-
-	numXpdGain = 0;
-
-	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
-		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
-			if (numXpdGain >= AR5416_NUM_PD_GAINS)
-				break;
-			xpdGainValues[numXpdGain] =
-				(u16)(AR5416_PD_GAINS_IN_MASK - i);
-			numXpdGain++;
-		}
-	}
-
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-		      (numXpdGain - 1) & 0x3);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-		      xpdGainValues[0]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-		      xpdGainValues[1]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
-		      xpdGainValues[2]);
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		if (AR_SREV_5416_V20_OR_LATER(ah) &&
-		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
-		    (i != 0)) {
-			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-		} else
-			regChainOffset = i * 0x1000;
-
-		if (pEepData->baseEepHeader.txMask & (1 << i)) {
-			if (IS_CHAN_2GHZ(chan))
-				pRawDataset = pEepData->calPierData2G[i];
-			else
-				pRawDataset = pEepData->calPierData5G[i];
-
-			ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
-					    pRawDataset, pCalBChans,
-					    numPiers, pdGainOverlap_t2,
-					    &tMinCalPower, gainBoundaries,
-					    pdadcValues, numXpdGain);
-
-			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
-				REG_WRITE(ah,
-					  AR_PHY_TPCRG5 + regChainOffset,
-					  SM(pdGainOverlap_t2,
-					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
-					  | SM(gainBoundaries[0],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
-					  | SM(gainBoundaries[1],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
-					  | SM(gainBoundaries[2],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
-					  | SM(gainBoundaries[3],
-				       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
-			}
-
-			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
-			for (j = 0; j < 32; j++) {
-				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-					((pdadcValues[4 * j + 3] & 0xFF) << 24);
-				REG_WRITE(ah, regOffset, reg32);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-					"PDADC (%d,%4x): %4.4x %8.8x\n",
-					i, regChainOffset, regOffset,
-					reg32);
-				DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-					"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;
-			}
-		}
-	}
-
-	*pTxPowerIndexOffset = 0;
-
-	return true;
-}
-
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 				  struct ath9k_channel *chan,
 				  int16_t *pTxPowerIndexOffset)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
 	struct cal_data_per_freq_4k *pRawDataset;
 	u8 *pCalBChans = NULL;
 	u16 pdGainOverlap_t2;
 	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+	u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
 	u16 numPiers, i, j;
 	int16_t tMinCalPower;
 	u16 numXpdGain, xpdMask;
-	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+	u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
 	u32 reg32, regOffset, regChainOffset;
 
 	xpdMask = pEepData->modalHeader.xpdGain;
@@ -1128,16 +722,16 @@ static bool ath9k_hw_set_4k_power_cal_ta
 	}
 
 	pCalBChans = pEepData->calFreqPier2G;
-	numPiers = AR5416_NUM_2G_CAL_PIERS;
+	numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
 
 	numXpdGain = 0;
 
-	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
-		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
-			if (numXpdGain >= AR5416_NUM_PD_GAINS)
+	for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
 				break;
 			xpdGainValues[numXpdGain] =
-				(u16)(AR5416_PD_GAINS_IN_MASK - i);
+				(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
 			numXpdGain++;
 		}
 	}
@@ -1148,12 +742,11 @@ static bool ath9k_hw_set_4k_power_cal_ta
 		      xpdGainValues[0]);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
 		      xpdGainValues[1]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
-		      xpdGainValues[2]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
 
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		if (AR_SREV_5416_V20_OR_LATER(ah) &&
-		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
 		    (i != 0)) {
 			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
 		} else
@@ -1168,7 +761,7 @@ static bool ath9k_hw_set_4k_power_cal_ta
 					    &tMinCalPower, gainBoundaries,
 					    pdadcValues, numXpdGain);
 
-			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
 				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
 					  SM(pdGainOverlap_t2,
 					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
@@ -1216,298 +809,7 @@ static bool ath9k_hw_set_4k_power_cal_ta
 	return true;
 }
 
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
-						  struct ath9k_channel *chan,
-						  int16_t *ratesArray,
-						  u16 cfgCtl,
-						  u16 AntennaReduction,
-						  u16 twiceMaxRegulatoryPower,
-						  u16 powerLimit)
-{
-#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
-#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
-
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
-	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-	static const u16 tpScaleReductionTable[5] =
-		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-	int i;
-	int16_t twiceLargestAntenna;
-	struct cal_ctl_data *rep;
-	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-		0, { 0, 0, 0, 0}
-	};
-	struct cal_target_power_leg targetPowerOfdmExt = {
-		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-		0, { 0, 0, 0, 0 }
-	};
-	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-		0, {0, 0, 0, 0}
-	};
-	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-	u16 ctlModesFor11a[] =
-		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
-	u16 ctlModesFor11g[] =
-		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-		  CTL_2GHT40
-		};
-	u16 numCtlModes, *pCtlMode, ctlMode, freq;
-	struct chan_centers centers;
-	int tx_chainmask;
-	u16 twiceMinEdgePower;
-
-	tx_chainmask = ahp->ah_txchainmask;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	twiceLargestAntenna = max(
-		pEepData->modalHeader
-			[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
-		pEepData->modalHeader
-			[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
-	twiceLargestAntenna = max((u8)twiceLargestAntenna,
-				  pEepData->modalHeader
-				  [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
-	twiceLargestAntenna = (int16_t)min(AntennaReduction -
-					   twiceLargestAntenna, 0);
-
-	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
-		maxRegAllowedPower -=
-			(tpScaleReductionTable[(ah->ah_tpScale)] * 2);
-	}
-
-	scaledPower = min(powerLimit, maxRegAllowedPower);
-
-	switch (ar5416_get_ntxchains(tx_chainmask)) {
-	case 1:
-		break;
-	case 2:
-		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
-		break;
-	case 3:
-		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
-		break;
-	}
-
-	scaledPower = max((u16)0, scaledPower);
-
-	if (IS_CHAN_2GHZ(chan)) {
-		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
-			SUB_NUM_CTL_MODES_AT_2G_40;
-		pCtlMode = ctlModesFor11g;
-
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPowerCck,
-			AR5416_NUM_2G_CCK_TARGET_POWERS,
-			&targetPowerCck, 4, false);
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPower2G,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerOfdm, 4, false);
-		ath9k_hw_get_target_powers(ah, chan,
-			pEepData->calTargetPower2GHT20,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerHt20, 8, false);
-
-		if (IS_CHAN_HT40(chan)) {
-			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-			ath9k_hw_get_target_powers(ah, chan,
-				pEepData->calTargetPower2GHT40,
-				AR5416_NUM_2G_40_TARGET_POWERS,
-				&targetPowerHt40, 8, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPowerCck,
-				AR5416_NUM_2G_CCK_TARGET_POWERS,
-				&targetPowerCckExt, 4, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPower2G,
-				AR5416_NUM_2G_20_TARGET_POWERS,
-				&targetPowerOfdmExt, 4, true);
-		}
-	} else {
-		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
-			SUB_NUM_CTL_MODES_AT_5G_40;
-		pCtlMode = ctlModesFor11a;
-
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPower5G,
-			AR5416_NUM_5G_20_TARGET_POWERS,
-			&targetPowerOfdm, 4, false);
-		ath9k_hw_get_target_powers(ah, chan,
-			pEepData->calTargetPower5GHT20,
-			AR5416_NUM_5G_20_TARGET_POWERS,
-			&targetPowerHt20, 8, false);
-
-		if (IS_CHAN_HT40(chan)) {
-			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
-			ath9k_hw_get_target_powers(ah, chan,
-				pEepData->calTargetPower5GHT40,
-				AR5416_NUM_5G_40_TARGET_POWERS,
-				&targetPowerHt40, 8, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPower5G,
-				AR5416_NUM_5G_20_TARGET_POWERS,
-				&targetPowerOfdmExt, 4, true);
-		}
-	}
-
-	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
-			(pCtlMode[ctlMode] == CTL_2GHT40);
-		if (isHt40CtlMode)
-			freq = centers.synth_center;
-		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-			freq = centers.ext_center;
-		else
-			freq = centers.ctl_center;
-
-		if (ar5416_get_eep_ver(ahp) == 14 && ar5416_get_eep_rev(ahp) <= 2)
-			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-			"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-			"EXT_ADDITIVE %d\n",
-			ctlMode, numCtlModes, isHt40CtlMode,
-			(pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
-			DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-				"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-				"chan %d\n",
-				i, cfgCtl, pCtlMode[ctlMode],
-				pEepData->ctlIndex[i], chan->channel);
-
-			if ((((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     pEepData->ctlIndex[i]) ||
-			    (((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
-				rep = &(pEepData->ctlData[i]);
-
-				twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
-				rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
-				IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-					"    MATCH-EE_IDX %d: ch %d is2 %d "
-					"2xMinEdge %d chainmask %d chains %d\n",
-					i, freq, IS_CHAN_2GHZ(chan),
-					twiceMinEdgePower, tx_chainmask,
-					ar5416_get_ntxchains
-					(tx_chainmask));
-				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-					twiceMaxEdgePower = min(twiceMaxEdgePower,
-								twiceMinEdgePower);
-				} else {
-					twiceMaxEdgePower = twiceMinEdgePower;
-					break;
-				}
-			}
-		}
-
-		minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
-		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-			"    SEL-Min ctlMode %d pCtlMode %d "
-			"2xMaxEdge %d sP %d minCtlPwr %d\n",
-			ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-			scaledPower, minCtlPower);
-
-		switch (pCtlMode[ctlMode]) {
-		case CTL_11B:
-			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
-				targetPowerCck.tPow2x[i] =
-					min((u16)targetPowerCck.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11A:
-		case CTL_11G:
-			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
-				targetPowerOfdm.tPow2x[i] =
-					min((u16)targetPowerOfdm.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_5GHT20:
-		case CTL_2GHT20:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
-				targetPowerHt20.tPow2x[i] =
-					min((u16)targetPowerHt20.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11B_EXT:
-			targetPowerCckExt.tPow2x[0] = min((u16)
-					targetPowerCckExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_11A_EXT:
-		case CTL_11G_EXT:
-			targetPowerOfdmExt.tPow2x[0] = min((u16)
-					targetPowerOfdmExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_5GHT40:
-		case CTL_2GHT40:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-				targetPowerHt40.tPow2x[i] =
-					min((u16)targetPowerHt40.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-		ratesArray[rate18mb] = ratesArray[rate24mb] =
-		targetPowerOfdm.tPow2x[0];
-	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-	if (IS_CHAN_2GHZ(chan)) {
-		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-		ratesArray[rate2s] = ratesArray[rate2l] =
-			targetPowerCck.tPow2x[1];
-		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
-			targetPowerCck.tPow2x[2];
-		;
-		ratesArray[rate11s] = ratesArray[rate11l] =
-			targetPowerCck.tPow2x[3];
-		;
-	}
-	if (IS_CHAN_HT40(chan)) {
-		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-			ratesArray[rateHt40_0 + i] =
-				targetPowerHt40.tPow2x[i];
-		}
-		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-		if (IS_CHAN_2GHZ(chan)) {
-			ratesArray[rateExtCck] =
-				targetPowerCckExt.tPow2x[0];
-		}
-	}
-	return true;
-}
-
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
 						 struct ath9k_channel *chan,
 						 int16_t *ratesArray,
 						 u16 cfgCtl,
@@ -1515,8 +817,7 @@ static bool ath9k_hw_set_4k_power_per_ra
 						 u16 twiceMaxRegulatoryPower,
 						 u16 powerLimit)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
 	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
 	static const u16 tpScaleReductionTable[5] =
 		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
@@ -1544,7 +845,7 @@ static bool ath9k_hw_set_4k_power_per_ra
 	int tx_chainmask;
 	u16 twiceMinEdgePower;
 
-	tx_chainmask = ahp->ah_txchainmask;
+	tx_chainmask = ah->txchainmask;
 
 	ath9k_hw_get_channel_centers(ah, chan, &centers);
 
@@ -1555,9 +856,9 @@ static bool ath9k_hw_set_4k_power_per_ra
 
 	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
 
-	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+	if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
 		maxRegAllowedPower -=
-			(tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+			(tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
 	}
 
 	scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -1605,8 +906,8 @@ static bool ath9k_hw_set_4k_power_per_ra
 		else
 			freq = centers.ctl_center;
 
-		if (ar5416_get_eep_ver(ahp) == 14 &&
-				ar5416_get_eep_rev(ahp) <= 2)
+		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
 			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
 
 		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
@@ -1743,17 +1044,15 @@ static bool ath9k_hw_set_4k_power_per_ra
 	return true;
 }
 
-static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
-			 struct ath9k_channel *chan,
-			 u16 cfgCtl,
-			 u8 twiceAntennaReduction,
-			 u8 twiceMaxRegulatoryPower,
-			 u8 powerLimit)
+static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+				   struct ath9k_channel *chan,
+				   u16 cfgCtl,
+				   u8 twiceAntennaReduction,
+				   u8 twiceMaxRegulatoryPower,
+				   u8 powerLimit)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
-	struct modal_eep_header *pModal =
-		&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
 	int16_t ratesArray[Ar5416RateSize];
 	int16_t txPowerIndexOffset = 0;
 	u8 ht40PowerIncForPdadc = 2;
@@ -1766,7 +1065,7 @@ static int ath9k_hw_def_set_txpower(stru
 		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
 	}
 
-	if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+	if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
 					       &ratesArray[0], cfgCtl,
 					       twiceAntennaReduction,
 					       twiceMaxRegulatoryPower,
@@ -1777,7 +1076,7 @@ static int ath9k_hw_def_set_txpower(stru
 		return -EIO;
 	}
 
-	if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+	if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
 			 "ath9k_hw_set_txpower: unable to set power table\n");
 		return -EIO;
@@ -1856,10 +1155,6 @@ static int ath9k_hw_def_set_txpower(stru
 			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
 	}
 
-	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
-		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
-		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
 	i = rate6mb;
 
 	if (IS_CHAN_HT40(chan))
@@ -1868,272 +1163,572 @@ static int ath9k_hw_def_set_txpower(stru
 		i = rateHt20_0;
 
 	if (AR_SREV_9280_10_OR_LATER(ah))
-		ah->ah_maxPowerLevel =
+		ah->regulatory.max_power_level =
 			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
 	else
-		ah->ah_maxPowerLevel = ratesArray[i];
+		ah->regulatory.max_power_level = ratesArray[i];
 
 	return 0;
 }
 
-static int ath9k_hw_4k_set_txpower(struct ath_hal *ah,
-			 struct ath9k_channel *chan,
-			 u16 cfgCtl,
-			 u8 twiceAntennaReduction,
-			 u8 twiceMaxRegulatoryPower,
-			 u8 powerLimit)
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+				  struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
-	int16_t ratesArray[Ar5416RateSize];
-	int16_t txPowerIndexOffset = 0;
-	u8 ht40PowerIncForPdadc = 2;
-	int i;
+	struct modal_eep_4k_header *pModal;
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	u8 biaslevel;
 
-	memset(ratesArray, 0, sizeof(ratesArray));
+	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+		return;
 
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-	}
+	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+		return;
 
-	if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
-					       &ratesArray[0], cfgCtl,
-					       twiceAntennaReduction,
-					       twiceMaxRegulatoryPower,
-					       powerLimit)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"ath9k_hw_set_txpower: unable to set "
-			"tx power per rate table\n");
-		return -EIO;
-	}
+	pModal = &eep->modalHeader;
 
-	if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			 "ath9k_hw_set_txpower: unable to set power table\n");
-		return -EIO;
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+		INI_RA(&ah->iniAddac, 7, 1) =
+		  (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
 	}
+}
 
-	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
-		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-			ratesArray[i] = AR5416_MAX_RATE_POWER;
-	}
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+				 struct modal_eep_4k_header *pModal,
+				 struct ar5416_eeprom_4k *eep,
+				 u8 txRxAttenLocal, int regChainOffset)
+{
+	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+		  pModal->antCtrlChain[0]);
 
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		for (i = 0; i < Ar5416RateSize; i++)
-			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_3) {
+		txRxAttenLocal = pModal->txRxAttenCh[0];
+
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+			      pModal->xatten2Margin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
 	}
 
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
 
-	if (IS_CHAN_2GHZ(chan)) {
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-			  ATH9K_POW_SM(ratesArray[rate2s], 24)
-			  | ATH9K_POW_SM(ratesArray[rate2l], 16)
-			  | ATH9K_POW_SM(ratesArray[rateXr], 8)
-			  | ATH9K_POW_SM(ratesArray[rate1l], 0));
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-			  ATH9K_POW_SM(ratesArray[rate11s], 24)
-			  | ATH9K_POW_SM(ratesArray[rate11l], 16)
-			  | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-			  | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+}
+
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	struct modal_eep_4k_header *pModal;
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	u8 txRxAttenLocal;
+	u8 ob[5], db1[5], db2[5];
+	u8 ant_div_control1, ant_div_control2;
+	u32 regVal;
+
+	pModal = &eep->modalHeader;
+	txRxAttenLocal = 23;
+
+	REG_WRITE(ah, AR_PHY_SWITCH_COM,
+		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+	/* Single chain for 4K EEPROM*/
+	ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
+
+	/* Initialize Ant Diversity settings from EEPROM */
+	if (pModal->version == 3) {
+		ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+		ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+		regVal = REG_READ(ah, 0x99ac);
+		regVal &= (~(0x7f000000));
+		regVal |= ((ant_div_control1 & 0x1) << 24);
+		regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+		regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+		regVal |= ((ant_div_control2 & 0x3) << 25);
+		regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+		REG_WRITE(ah, 0x99ac, regVal);
+		regVal = REG_READ(ah, 0x99ac);
+		regVal = REG_READ(ah, 0xa208);
+		regVal &= (~(0x1 << 13));
+		regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+		REG_WRITE(ah, 0xa208, regVal);
+		regVal = REG_READ(ah, 0xa208);
 	}
 
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+	if (pModal->version >= 2) {
+		ob[0] = (pModal->ob_01 & 0xf);
+		ob[1] = (pModal->ob_01 >> 4) & 0xf;
+		ob[2] = (pModal->ob_234 & 0xf);
+		ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+		ob[4] = ((pModal->ob_234 >> 8) & 0xf);
 
-	if (IS_CHAN_HT40(chan)) {
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-					 ht40PowerIncForPdadc, 0));
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-					 ht40PowerIncForPdadc, 0));
+		db1[0] = (pModal->db1_01 & 0xf);
+		db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+		db1[2] = (pModal->db1_234 & 0xf);
+		db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+		db1[4] = ((pModal->db1_234 >> 8) & 0xf);
 
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-			  ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-			  | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+		db2[0] = (pModal->db2_01 & 0xf);
+		db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+		db2[2] = (pModal->db2_234 & 0xf);
+		db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+		db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+	} else if (pModal->version == 1) {
+		ob[0] = (pModal->ob_01 & 0xf);
+		ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+		db1[0] = (pModal->db1_01 & 0xf);
+		db1[1] = db1[2] = db1[3] =
+			db1[4] = ((pModal->db1_01 >> 4) & 0xf);
+		db2[0] = (pModal->db2_01 & 0xf);
+		db2[1] = db2[2] = db2[3] =
+			db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+	} else {
+		int i;
+		for (i = 0; i < 5; i++) {
+			ob[i] = pModal->ob_01;
+			db1[i] = pModal->db1_01;
+			db2[i] = pModal->db1_01;
+		}
 	}
 
-	i = rate6mb;
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
 
-	if (IS_CHAN_HT40(chan))
-		i = rateHt40_0;
-	else if (IS_CHAN_HT20(chan))
-		i = rateHt20_0;
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+			AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ah->ah_maxPowerLevel =
-			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-	else
-		ah->ah_maxPowerLevel = ratesArray[i];
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+			AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
 
-	return 0;
-}
 
-static int (*ath9k_set_txpower[]) (struct ath_hal *,
-				   struct ath9k_channel *,
-				   u16, u8, u8, u8) = {
-	ath9k_hw_def_set_txpower,
-	ath9k_hw_4k_set_txpower
-};
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
 
-int ath9k_hw_set_txpower(struct ath_hal *ah,
-			 struct ath9k_channel *chan,
-			 u16 cfgCtl,
-			 u8 twiceAntennaReduction,
-			 u8 twiceMaxRegulatoryPower,
-			 u8 powerLimit)
+	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+		      pModal->switchSettling);
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+		      pModal->adcDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	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,
+		      pModal->thresh62);
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+						AR5416_EEP_MINOR_VER_2) {
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+			      pModal->txFrameToDataStart);
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+			      pModal->txFrameToPaOn);
+	}
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+						AR5416_EEP_MINOR_VER_3) {
+		if (IS_CHAN_HT40(chan))
+			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+				      AR_PHY_SETTLING_SWITCH,
+				      pModal->swSettleHt40);
+	}
+}
+
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+					      struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
 
-	return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl,
-			twiceAntennaReduction, twiceMaxRegulatoryPower,
-			powerLimit);
+	return pModal->antCtrlCommon & 0xFFFF;
 }
 
-static void ath9k_hw_set_def_addac(struct ath_hal *ah,
-				   struct ath9k_channel *chan)
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+					 enum ieee80211_band freq_band)
 {
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
-	struct modal_eep_header *pModal;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
-	u8 biaslevel;
+	return 1;
+}
 
-	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
-		return;
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+	(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
 
-	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
-		return;
+	u16 spur_val = AR_NO_SPUR;
 
-	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Getting spur idx %d is2Ghz. %d val %x\n",
+		i, is2GHz, ah->config.spurchans[i][is2GHz]);
 
-	if (pModal->xpaBiasLvl != 0xff) {
-		biaslevel = pModal->xpaBiasLvl;
-	} else {
-		u16 resetFreqBin, freqBin, freqCount = 0;
-		struct chan_centers centers;
+	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);
+		break;
+	case SPUR_ENABLE_EEPROM:
+		spur_val = EEP_MAP4K_SPURCHAN;
+		break;
+	}
 
-		ath9k_hw_get_channel_centers(ah, chan, &centers);
+	return spur_val;
 
-		resetFreqBin = FREQ2FBIN(centers.synth_center,
-					 IS_CHAN_2GHZ(chan));
-		freqBin = XPA_LVL_FREQ(0) & 0xff;
-		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+#undef EEP_MAP4K_SPURCHAN
+}
 
-		freqCount++;
+static struct eeprom_ops eep_4k_ops = {
+	.check_eeprom		= ath9k_hw_4k_check_eeprom,
+	.get_eeprom		= ath9k_hw_4k_get_eeprom,
+	.fill_eeprom		= ath9k_hw_4k_fill_eeprom,
+	.get_eeprom_ver		= ath9k_hw_4k_get_eeprom_ver,
+	.get_eeprom_rev		= ath9k_hw_4k_get_eeprom_rev,
+	.get_num_ant_config	= ath9k_hw_4k_get_num_ant_config,
+	.get_eeprom_antenna_cfg	= ath9k_hw_4k_get_eeprom_antenna_cfg,
+	.set_board_values	= ath9k_hw_4k_set_board_values,
+	.set_addac		= ath9k_hw_4k_set_addac,
+	.set_txpower		= ath9k_hw_4k_set_txpower,
+	.get_spur_channel	= ath9k_hw_4k_get_spur_channel
+};
 
-		while (freqCount < 3) {
-			if (XPA_LVL_FREQ(freqCount) == 0x0)
-				break;
+/************************************************/
+/* EEPROM Operations for non-4K (Default) cards */
+/************************************************/
 
-			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
-			if (resetFreqBin >= freqBin)
-				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
-			else
-				break;
-			freqCount++;
-		}
-	}
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+	return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
 
-	if (IS_CHAN_2GHZ(chan)) {
-		INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac,
-					7, 1) & (~0x18)) | biaslevel << 3;
-	} else {
-		INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac,
-					6, 1) & (~0xc0)) | biaslevel << 6;
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+	return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+	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,
+					 eep_data)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+				"Unable to read eeprom region\n");
+			return false;
+		}
+		eep_data++;
 	}
-#undef XPA_LVL_FREQ
+	return true;
+#undef SIZE_EEPROM_DEF
 }
 
-static void ath9k_hw_set_4k_addac(struct ath_hal *ah,
-				  struct ath9k_channel *chan)
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
 {
-	struct modal_eep_4k_header *pModal;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
-	u8 biaslevel;
+	struct ar5416_eeprom_def *eep =
+		(struct ar5416_eeprom_def *) &ah->eeprom.def;
+	u16 *eepdata, temp, magic, magic2;
+	u32 sum = 0, el;
+	bool need_swap = false;
+	int i, addr, size;
 
-	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
-		return;
+	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+		return false;
+	}
 
-	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
-		return;
+	if (!ath9k_hw_use_flash(ah)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Read Magic = 0x%04X\n", magic);
 
-	pModal = &eep->modalHeader;
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
 
-	if (pModal->xpaBiasLvl != 0xff) {
-		biaslevel = pModal->xpaBiasLvl;
-		INI_RA(&ahp->ah_iniAddac, 7, 1) =
-		  (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				size = sizeof(struct ar5416_eeprom_def);
+				need_swap = true;
+				eepdata = (u16 *) (&ah->eeprom);
+
+				for (addr = 0; addr < size / sizeof(u16); addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+				}
+			} else {
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+					"Invalid EEPROM Magic. "
+					"Endianness mismatch.\n");
+				return -EINVAL;
+			}
+		}
 	}
-}
 
-static void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = {
-	ath9k_hw_set_def_addac,
-	ath9k_hw_set_4k_addac
-};
+	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+		need_swap ? "True" : "False");
 
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+	if (need_swap)
+		el = swab16(ah->eeprom.def.baseEepHeader.length);
+	else
+		el = ah->eeprom.def.baseEepHeader.length;
+
+	if (el > sizeof(struct ar5416_eeprom_def))
+		el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+	else
+		el = el / sizeof(u16);
+
+	eepdata = (u16 *)(&ah->eeprom);
+
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		u32 integer, j;
+		u16 word;
+
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"EEPROM Endianness is not native.. Changing.\n");
+
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+			struct modal_eep_header *pModal =
+				&eep->modalHeader[j];
+			integer = swab32(pModal->antCtrlCommon);
+			pModal->antCtrlCommon = integer;
+
+			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+				integer = swab32(pModal->antCtrlChain[i]);
+				pModal->antCtrlChain[i] = integer;
+			}
+
+			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+				word = swab16(pModal->spurChans[i].spurChan);
+				pModal->spurChans[i].spurChan = word;
+			}
+		}
+	}
+
+	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));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+				   enum eeprom_param param)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	struct modal_eep_header *pModal = eep->modalHeader;
+	struct base_eep_header *pBase = &eep->baseEepHeader;
 
-	ath9k_set_addac[ahp->ah_eep_map](ah, chan);
+	switch (param) {
+	case EEP_NFTHRESH_5:
+		return pModal[0].noiseFloorThreshCh[0];
+	case EEP_NFTHRESH_2:
+		return pModal[1].noiseFloorThreshCh[0];
+	case AR_EEPROM_MAC(0):
+		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+	case AR_EEPROM_MAC(1):
+		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+	case AR_EEPROM_MAC(2):
+		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_OB_5:
+		return pModal[0].ob;
+	case EEP_DB_5:
+		return pModal[0].db;
+	case EEP_OB_2:
+		return pModal[1].ob;
+	case EEP_DB_2:
+		return pModal[1].db;
+	case EEP_MINOR_REV:
+		return AR5416_VER_MASK;
+	case EEP_TX_MASK:
+		return pBase->txMask;
+	case EEP_RX_MASK:
+		return pBase->rxMask;
+	case EEP_RXGAIN_TYPE:
+		return pBase->rxGainType;
+	case EEP_TXGAIN_TYPE:
+		return pBase->txGainType;
+	case EEP_OL_PWRCTRL:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+			return pBase->openLoopPwrCntl ? true : false;
+		else
+			return false;
+	case EEP_RC_CHAIN_MASK:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+			return pBase->rcChainMask;
+		else
+			return 0;
+	case EEP_DAC_HPWR_5G:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+			return pBase->dacHiPwrMode_5G;
+		else
+			return 0;
+	case EEP_FRAC_N_5G:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+			return pBase->frac_n_5g;
+		else
+			return 0;
+	default:
+		return 0;
+	}
 }
 
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+				  struct modal_eep_header *pModal,
+				  struct ar5416_eeprom_def *eep,
+				  u8 txRxAttenLocal, int regChainOffset, int i)
+{
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+		txRxAttenLocal = pModal->txRxAttenCh[i];
+
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+			      pModal->bswMargin[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+			      pModal->bswAtten[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+			      pModal->xatten2Margin[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+			      pModal->xatten2Db[i]);
+		} else {
+			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+			  | SM(pModal-> bswMargin[i],
+			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+			  | SM(pModal->bswAtten[i],
+			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+		}
+	}
 
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_RMW_FIELD(ah,
+		      AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+		REG_RMW_FIELD(ah,
+		      AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
+	} else {
+		REG_WRITE(ah,
+			  AR_PHY_RXGAIN + regChainOffset,
+			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
+			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
+			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
+		REG_WRITE(ah,
+			  AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+	}
+}
 
-/* XXX: Clean me up, make me more legible */
-static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
-				      struct ath9k_channel *chan)
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+					  struct ath9k_channel *chan)
 {
 	struct modal_eep_header *pModal;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 	int i, regChainOffset;
 	u8 txRxAttenLocal;
-	u16 ant_config;
 
 	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
 	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
 
-	ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
-	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+	REG_WRITE(ah, AR_PHY_SWITCH_COM,
+		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
 
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 		if (AR_SREV_9280(ah)) {
@@ -2141,9 +1736,8 @@ static bool ath9k_hw_eeprom_set_def_boar
 				break;
 		}
 
-		if (AR_SREV_5416_V20_OR_LATER(ah) &&
-		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
-		    && (i != 0))
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
 			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
 		else
 			regChainOffset = i * 0x1000;
@@ -2152,9 +1746,7 @@ static bool ath9k_hw_eeprom_set_def_boar
 			  pModal->antCtrlChain[i]);
 
 		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-			  (REG_READ(ah,
-				    AR_PHY_TIMING_CTRL4(0) +
-				    regChainOffset) &
+			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
 			   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
 			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
 			  SM(pModal->iqCalICh[i],
@@ -2162,89 +1754,9 @@ static bool ath9k_hw_eeprom_set_def_boar
 			  SM(pModal->iqCalQCh[i],
 			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
 
-		if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
-			if ((eep->baseEepHeader.version &
-			     AR5416_EEP_VER_MINOR_MASK) >=
-			    AR5416_EEP_MINOR_VER_3) {
-				txRxAttenLocal = pModal->txRxAttenCh[i];
-				if (AR_SREV_9280_10_OR_LATER(ah)) {
-					REG_RMW_FIELD(ah,
-						AR_PHY_GAIN_2GHZ +
-						regChainOffset,
-						AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
-						pModal->
-						bswMargin[i]);
-					REG_RMW_FIELD(ah,
-						AR_PHY_GAIN_2GHZ +
-						regChainOffset,
-						AR_PHY_GAIN_2GHZ_XATTEN1_DB,
-						pModal->
-						bswAtten[i]);
-					REG_RMW_FIELD(ah,
-						AR_PHY_GAIN_2GHZ +
-						regChainOffset,
-						AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-						pModal->
-						xatten2Margin[i]);
-					REG_RMW_FIELD(ah,
-						AR_PHY_GAIN_2GHZ +
-						regChainOffset,
-						AR_PHY_GAIN_2GHZ_XATTEN2_DB,
-						pModal->
-						xatten2Db[i]);
-				} else {
-					REG_WRITE(ah,
-						  AR_PHY_GAIN_2GHZ +
-						  regChainOffset,
-						  (REG_READ(ah,
-							    AR_PHY_GAIN_2GHZ +
-							    regChainOffset) &
-						   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-						  | SM(pModal->
-						  bswMargin[i],
-						  AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-					REG_WRITE(ah,
-						  AR_PHY_GAIN_2GHZ +
-						  regChainOffset,
-						  (REG_READ(ah,
-							    AR_PHY_GAIN_2GHZ +
-							    regChainOffset) &
-						   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-						  | SM(pModal->bswAtten[i],
-						  AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-				}
-			}
-			if (AR_SREV_9280_10_OR_LATER(ah)) {
-				REG_RMW_FIELD(ah,
-					      AR_PHY_RXGAIN +
-					      regChainOffset,
-					      AR9280_PHY_RXGAIN_TXRX_ATTEN,
-					      txRxAttenLocal);
-				REG_RMW_FIELD(ah,
-					      AR_PHY_RXGAIN +
-					      regChainOffset,
-					      AR9280_PHY_RXGAIN_TXRX_MARGIN,
-					      pModal->rxTxMarginCh[i]);
-			} else {
-				REG_WRITE(ah,
-					  AR_PHY_RXGAIN + regChainOffset,
-					  (REG_READ(ah,
-						    AR_PHY_RXGAIN +
-						    regChainOffset) &
-					   ~AR_PHY_RXGAIN_TXRX_ATTEN) |
-					  SM(txRxAttenLocal,
-					     AR_PHY_RXGAIN_TXRX_ATTEN));
-				REG_WRITE(ah,
-					  AR_PHY_GAIN_2GHZ +
-					  regChainOffset,
-					  (REG_READ(ah,
-						    AR_PHY_GAIN_2GHZ +
-						    regChainOffset) &
-					   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-					  SM(pModal->rxTxMarginCh[i],
-					     AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
-			}
-		}
+		if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+			ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+					      regChainOffset, i);
 	}
 
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
@@ -2291,8 +1803,6 @@ static bool ath9k_hw_eeprom_set_def_boar
 					  AR_AN_TOP2_LOCALBIAS,
 					  AR_AN_TOP2_LOCALBIAS_S,
 					  pModal->local_bias);
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ForceXPAon: %d\n",
-			pModal->force_xpaon);
 		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
 			      pModal->force_xpaon);
 	}
@@ -2318,6 +1828,7 @@ static bool ath9k_hw_eeprom_set_def_boar
 
 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 		      pModal->txEndToRxOn);
+
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
 		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
 			      pModal->thresh62);
@@ -2332,8 +1843,7 @@ static bool ath9k_hw_eeprom_set_def_boar
 			      pModal->thresh62);
 	}
 
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
 		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
 			      AR_PHY_TX_END_DATA_START,
 			      pModal->txFrameToDataStart);
@@ -2341,296 +1851,880 @@ static bool ath9k_hw_eeprom_set_def_boar
 			      pModal->txFrameToPaOn);
 	}
 
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_3) {
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 		if (IS_CHAN_HT40(chan))
 			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
 				      AR_PHY_SETTLING_SWITCH,
 				      pModal->swSettleHt40);
 	}
 
-	return true;
+	if (AR_SREV_9280_20_OR_LATER(ah) &&
+	    AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+		REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+			      AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+			      pModal->miscBits);
+
+
+	if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+		if (IS_CHAN_2GHZ(chan))
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+					eep->baseEepHeader.dacLpMode);
+		else if (eep->baseEepHeader.dacHiPwrMode_5G)
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+		else
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+				      eep->baseEepHeader.dacLpMode);
+
+		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+			      pModal->miscBits >> 2);
+
+		REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+			      AR_PHY_TX_DESIRED_SCALE_CCK,
+			      eep->baseEepHeader.desiredScaleCCK);
+	}
 }
 
-static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
-				      struct ath9k_channel *chan)
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
 {
-	struct modal_eep_4k_header *pModal;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
-	int regChainOffset;
-	u8 txRxAttenLocal;
-	u16 ant_config = 0;
-	u8 ob[5], db1[5], db2[5];
-	u8 ant_div_control1, ant_div_control2;
-	u32 regVal;
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+	struct modal_eep_header *pModal;
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	u8 biaslevel;
 
+	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+		return;
 
-	pModal = &eep->modalHeader;
+	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+		return;
 
-	txRxAttenLocal = 23;
+	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 
-	ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
-	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+	} else {
+		u16 resetFreqBin, freqBin, freqCount = 0;
+		struct chan_centers centers;
 
-	regChainOffset = 0;
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-		  pModal->antCtrlChain[0]);
+		ath9k_hw_get_channel_centers(ah, chan, &centers);
 
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-		 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
-		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+		resetFreqBin = FREQ2FBIN(centers.synth_center,
+					 IS_CHAN_2GHZ(chan));
+		freqBin = XPA_LVL_FREQ(0) & 0xff;
+		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
 
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-			AR5416_EEP_MINOR_VER_3) {
-		txRxAttenLocal = pModal->txRxAttenCh[0];
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-			pModal->xatten2Margin[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
-	}
+		freqCount++;
 
-	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-			AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-			AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+		while (freqCount < 3) {
+			if (XPA_LVL_FREQ(freqCount) == 0x0)
+				break;
 
-	if (AR_SREV_9285_11(ah))
-		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+			if (resetFreqBin >= freqBin)
+				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+			else
+				break;
+			freqCount++;
+		}
+	}
 
-	/* Initialize Ant Diversity settings from EEPROM */
-	if (pModal->version == 3) {
-		ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
-		ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
-		regVal = REG_READ(ah, 0x99ac);
-		regVal &= (~(0x7f000000));
-		regVal |= ((ant_div_control1 & 0x1) << 24);
-		regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
-		regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
-		regVal |= ((ant_div_control2 & 0x3) << 25);
-		regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
-		REG_WRITE(ah, 0x99ac, regVal);
-		regVal = REG_READ(ah, 0x99ac);
-		regVal = REG_READ(ah, 0xa208);
-		regVal &= (~(0x1 << 13));
-		regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
-		REG_WRITE(ah, 0xa208, regVal);
-		regVal = REG_READ(ah, 0xa208);
+	if (IS_CHAN_2GHZ(chan)) {
+		INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+					7, 1) & (~0x18)) | biaslevel << 3;
+	} else {
+		INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+					6, 1) & (~0xc0)) | biaslevel << 6;
 	}
+#undef XPA_LVL_FREQ
+}
 
-	if (pModal->version >= 2) {
-		ob[0] = (pModal->ob_01 & 0xf);
-		ob[1] = (pModal->ob_01 >> 4) & 0xf;
-		ob[2] = (pModal->ob_234 & 0xf);
-		ob[3] = ((pModal->ob_234 >> 4) & 0xf);
-		ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				struct cal_data_per_freq *pRawDataSet,
+				u8 *bChans, u16 availPiers,
+				u16 tPdGainOverlap, int16_t *pMinCalPower,
+				u16 *pPdGainBoundaries, u8 *pPDADCValues,
+				u16 numXpdGains)
+{
+	int i, j, k;
+	int16_t ss;
+	u16 idxL = 0, idxR = 0, numPiers;
+	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
 
-		db1[0] = (pModal->db1_01 & 0xf);
-		db1[1] = ((pModal->db1_01 >> 4) & 0xf);
-		db1[2] = (pModal->db1_234 & 0xf);
-		db1[3] = ((pModal->db1_234 >> 4) & 0xf);
-		db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	u8 minPwrT4[AR5416_NUM_PD_GAINS];
+	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+	int16_t vpdStep;
+	int16_t tmpVal;
+	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+	bool match;
+	int16_t minDelta = 0;
+	struct chan_centers centers;
 
-		db2[0] = (pModal->db2_01 & 0xf);
-		db2[1] = ((pModal->db2_01 >> 4) & 0xf);
-		db2[2] = (pModal->db2_234 & 0xf);
-		db2[3] = ((pModal->db2_234 >> 4) & 0xf);
-		db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
 
-	} else if (pModal->version == 1) {
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+	}
 
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Model version is set to 1 \n");
-		ob[0] = (pModal->ob_01 & 0xf);
-		ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
-		db1[0] = (pModal->db1_01 & 0xf);
-		db1[1] = db1[2] = db1[3] =
-			db1[4] = ((pModal->db1_01 >> 4) & 0xf);
-		db2[0] = (pModal->db2_01 & 0xf);
-		db2[1] = db2[2] = db2[3] =
-			db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+							     IS_CHAN_2GHZ(chan)),
+					       bChans, numPiers, &idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pRawDataSet[idxL].pwrPdg[i],
+					pRawDataSet[idxL].vpdPdg[i],
+					AR5416_PD_GAIN_ICEPTS,
+					vpdTableI[i]);
+		}
 	} else {
-		int i;
-		for (i = 0; i < 5; i++) {
-			ob[i] = pModal->ob_01;
-			db1[i] = pModal->db1_01;
-			db2[i] = pModal->db1_01;
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+				min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+				    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrL, pVpdL,
+						AR5416_PD_GAIN_ICEPTS,
+						vpdTableL[i]);
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrR, pVpdR,
+						AR5416_PD_GAIN_ICEPTS,
+						vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+					(u8)(ath9k_hw_interpolate((u16)
+					     FREQ2FBIN(centers.
+						       synth_center,
+						       IS_CHAN_2GHZ
+						       (chan)),
+					     bChans[idxL], bChans[idxR],
+					     vpdTableL[i][j], vpdTableR[i][j]));
+			}
 		}
 	}
 
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
 
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+	k = 0;
 
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] =
+				(u16)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] =
+				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
 
+		pPdGainBoundaries[i] =
+			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
 
-	if (AR_SREV_9285_11(ah))
-		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else {
+			minDelta = 0;
+		}
 
-	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-		      pModal->switchSettling);
-	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-		      pModal->adcDesiredSize);
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else {
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
+					(minPwrT4[i] / 2)) -
+				       tPdGainOverlap + 1 + minDelta);
+		}
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
 
-	REG_WRITE(ah, AR_PHY_RF_CTL4,
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
 
-	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,
-		      pModal->thresh62);
+		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+				(minPwrT4[i] / 2));
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+			tgtIndex : sizeCurrVpdTable;
 
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-						AR5416_EEP_MINOR_VER_2) {
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
-			      pModal->txFrameToDataStart);
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-			      pModal->txFrameToPaOn);
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+		}
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+				    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		if (tgtIndex > maxIndex) {
+			while ((ss <= tgtIndex) &&
+			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+						    (ss - maxIndex + 1) * vpdStep));
+				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+							 255 : tmpVal);
+				ss++;
+			}
+		}
 	}
 
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-						AR5416_EEP_MINOR_VER_3) {
-		if (IS_CHAN_HT40(chan))
-			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-				      AR_PHY_SETTLING_SWITCH,
-				      pModal->swSettleHt40);
+	while (i < AR5416_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+		i++;
 	}
 
-	return true;
-}
+	while (k < AR5416_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k - 1];
+		k++;
+	}
 
-static bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *,
-					       struct ath9k_channel *) = {
-	ath9k_hw_eeprom_set_def_board_values,
-	ath9k_hw_eeprom_set_4k_board_values
-};
+	return;
+}
 
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
-				      struct ath9k_channel *chan)
+static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+				  struct ath9k_channel *chan,
+				  int16_t *pTxPowerIndexOffset)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
+#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)
 
-	return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan);
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	struct cal_data_per_freq *pRawDataset;
+	u8 *pCalBChans = NULL;
+	u16 pdGainOverlap_t2;
+	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+	u16 numPiers, i, j;
+	int16_t tMinCalPower;
+	u16 numXpdGain, xpdMask;
+	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+	u32 reg32, regOffset, regChainOffset;
+	int16_t modalIdx;
+
+	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		pdGainOverlap_t2 =
+			pEepData->modalHeader[modalIdx].pdGainOverlap;
+	} else {
+		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+	}
+
+	if (IS_CHAN_2GHZ(chan)) {
+		pCalBChans = pEepData->calFreqPier2G;
+		numPiers = AR5416_NUM_2G_CAL_PIERS;
+	} else {
+		pCalBChans = pEepData->calFreqPier5G;
+		numPiers = AR5416_NUM_5G_CAL_PIERS;
+	}
+
+	if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+		pRawDataset = pEepData->calPierData2G[0];
+		ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+				 pRawDataset)->vpdPdg[0][0];
+	}
+
+	numXpdGain = 0;
+
+	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+				(u16)(AR5416_PD_GAINS_IN_MASK - i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+		      (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+		      xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+		      xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+		      xpdGainValues[2]);
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+		    (i != 0)) {
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		} else
+			regChainOffset = i * 0x1000;
+
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			if (IS_CHAN_2GHZ(chan))
+				pRawDataset = pEepData->calPierData2G[i];
+			else
+				pRawDataset = pEepData->calPierData5G[i];
+
+
+			if (OLC_FOR_AR9280_20_LATER) {
+				u8 pcdacIdx;
+				u8 txPower;
+
+				ath9k_get_txgain_index(ah, chan,
+				(struct calDataPerFreqOpLoop *)pRawDataset,
+				pCalBChans, numPiers, &txPower, &pcdacIdx);
+				ath9k_olc_get_pdadcs(ah, pcdacIdx,
+						     txPower/2, pdadcValues);
+			} else {
+				ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+							chan, pRawDataset,
+							pCalBChans, numPiers,
+							pdGainOverlap_t2,
+							&tMinCalPower,
+							gainBoundaries,
+							pdadcValues,
+							numXpdGain);
+			}
+
+			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+				if (OLC_FOR_AR9280_20_LATER) {
+					REG_WRITE(ah,
+						AR_PHY_TPCRG5 + regChainOffset,
+						SM(0x6,
+						AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+						SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+						SM_PD_GAIN(3) | SM_PD_GAIN(4));
+				} else {
+					REG_WRITE(ah,
+						AR_PHY_TPCRG5 + regChainOffset,
+						SM(pdGainOverlap_t2,
+						AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+						SM_PDGAIN_B(0, 1) |
+						SM_PDGAIN_B(1, 2) |
+						SM_PDGAIN_B(2, 3) |
+						SM_PDGAIN_B(3, 4));
+				}
+			}
+
+			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+			for (j = 0; j < 32; j++) {
+				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+					((pdadcValues[4 * j + 3] & 0xFF) << 24);
+				REG_WRITE(ah, regOffset, reg32);
+
+				DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+					"PDADC (%d,%4x): %4.4x %8.8x\n",
+					i, regChainOffset, regOffset,
+					reg32);
+				DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+					"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;
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+
+	return true;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
 }
 
-static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
-				    struct ath9k_channel *chan,
-				    u8 index, u16 *config)
+static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+						  struct ath9k_channel *chan,
+						  int16_t *ratesArray,
+						  u16 cfgCtl,
+						  u16 AntennaReduction,
+						  u16 twiceMaxRegulatoryPower,
+						  u16 powerLimit)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
-	struct modal_eep_header *pModal =
-		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-	struct base_eep_header *pBase = &eep->baseEepHeader;
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
 
-	switch (index) {
-	case 0:
-		*config = pModal->antCtrlCommon & 0xFFFF;
-		return 0;
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	static const u16 tpScaleReductionTable[5] =
+		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+	int i;
+	int16_t twiceLargestAntenna;
+	struct cal_ctl_data *rep;
+	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+		0, { 0, 0, 0, 0}
+	};
+	struct cal_target_power_leg targetPowerOfdmExt = {
+		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+		0, { 0, 0, 0, 0 }
+	};
+	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+		0, {0, 0, 0, 0}
+	};
+	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	u16 ctlModesFor11a[] =
+		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+	u16 ctlModesFor11g[] =
+		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+		  CTL_2GHT40
+		};
+	u16 numCtlModes, *pCtlMode, ctlMode, freq;
+	struct chan_centers centers;
+	int tx_chainmask;
+	u16 twiceMinEdgePower;
+
+	tx_chainmask = ah->txchainmask;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = max(
+		pEepData->modalHeader
+			[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+		pEepData->modalHeader
+			[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+	twiceLargestAntenna = max((u8)twiceLargestAntenna,
+				  pEepData->modalHeader
+				  [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+	twiceLargestAntenna = (int16_t)min(AntennaReduction -
+					   twiceLargestAntenna, 0);
+
+	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+	if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+		maxRegAllowedPower -=
+			(tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+	}
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+
+	switch (ar5416_get_ntxchains(tx_chainmask)) {
 	case 1:
-		if (pBase->version >= 0x0E0D) {
-			if (pModal->useAnt1) {
-				*config =
-				((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
-				return 0;
-			}
-		}
 		break;
-	default:
+	case 2:
+		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		break;
+	case 3:
+		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
 		break;
 	}
 
-	return -EINVAL;
+	scaledPower = max((u16)0, scaledPower);
+
+	if (IS_CHAN_2GHZ(chan)) {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+			SUB_NUM_CTL_MODES_AT_2G_40;
+		pCtlMode = ctlModesFor11g;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPowerCck,
+			AR5416_NUM_2G_CCK_TARGET_POWERS,
+			&targetPowerCck, 4, false);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPower2G,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerOfdm, 4, false);
+		ath9k_hw_get_target_powers(ah, chan,
+			pEepData->calTargetPower2GHT20,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerHt20, 8, false);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+			ath9k_hw_get_target_powers(ah, chan,
+				pEepData->calTargetPower2GHT40,
+				AR5416_NUM_2G_40_TARGET_POWERS,
+				&targetPowerHt40, 8, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPowerCck,
+				AR5416_NUM_2G_CCK_TARGET_POWERS,
+				&targetPowerCckExt, 4, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPower2G,
+				AR5416_NUM_2G_20_TARGET_POWERS,
+				&targetPowerOfdmExt, 4, true);
+		}
+	} else {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+			SUB_NUM_CTL_MODES_AT_5G_40;
+		pCtlMode = ctlModesFor11a;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPower5G,
+			AR5416_NUM_5G_20_TARGET_POWERS,
+			&targetPowerOfdm, 4, false);
+		ath9k_hw_get_target_powers(ah, chan,
+			pEepData->calTargetPower5GHT20,
+			AR5416_NUM_5G_20_TARGET_POWERS,
+			&targetPowerHt20, 8, false);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+			ath9k_hw_get_target_powers(ah, chan,
+				pEepData->calTargetPower5GHT40,
+				AR5416_NUM_5G_40_TARGET_POWERS,
+				&targetPowerHt40, 8, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPower5G,
+				AR5416_NUM_5G_20_TARGET_POWERS,
+				&targetPowerOfdmExt, 4, true);
+		}
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+			(pCtlMode[ctlMode] == CTL_2GHT40);
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+			"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+			"EXT_ADDITIVE %d\n",
+			ctlMode, numCtlModes, isHt40CtlMode,
+			(pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+			DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+				"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+				"chan %d\n",
+				i, cfgCtl, pCtlMode[ctlMode],
+				pEepData->ctlIndex[i], chan->channel);
+
+			if ((((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     pEepData->ctlIndex[i]) ||
+			    (((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+				rep = &(pEepData->ctlData[i]);
+
+				twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+				rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+				IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+				DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+					"    MATCH-EE_IDX %d: ch %d is2 %d "
+					"2xMinEdge %d chainmask %d chains %d\n",
+					i, freq, IS_CHAN_2GHZ(chan),
+					twiceMinEdgePower, tx_chainmask,
+					ar5416_get_ntxchains
+					(tx_chainmask));
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+					twiceMaxEdgePower = min(twiceMaxEdgePower,
+								twiceMinEdgePower);
+				} else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+			"    SEL-Min ctlMode %d pCtlMode %d "
+			"2xMaxEdge %d sP %d minCtlPwr %d\n",
+			ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+			scaledPower, minCtlPower);
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+				targetPowerCck.tPow2x[i] =
+					min((u16)targetPowerCck.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11A:
+		case CTL_11G:
+			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+				targetPowerOfdm.tPow2x[i] =
+					min((u16)targetPowerOfdm.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_5GHT20:
+		case CTL_2GHT20:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+				targetPowerHt20.tPow2x[i] =
+					min((u16)targetPowerHt20.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] = min((u16)
+					targetPowerCckExt.tPow2x[0],
+					minCtlPower);
+			break;
+		case CTL_11A_EXT:
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] = min((u16)
+					targetPowerOfdmExt.tPow2x[0],
+					minCtlPower);
+			break;
+		case CTL_5GHT40:
+		case CTL_2GHT40:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+				targetPowerHt40.tPow2x[i] =
+					min((u16)targetPowerHt40.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+		ratesArray[rate18mb] = ratesArray[rate24mb] =
+		targetPowerOfdm.tPow2x[0];
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	if (IS_CHAN_2GHZ(chan)) {
+		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+		ratesArray[rate2s] = ratesArray[rate2l] =
+			targetPowerCck.tPow2x[1];
+		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+			targetPowerCck.tPow2x[2];
+		;
+		ratesArray[rate11s] = ratesArray[rate11l] =
+			targetPowerCck.tPow2x[3];
+		;
+	}
+	if (IS_CHAN_HT40(chan)) {
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+			ratesArray[rateHt40_0 + i] =
+				targetPowerHt40.tPow2x[i];
+		}
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		if (IS_CHAN_2GHZ(chan)) {
+			ratesArray[rateExtCck] =
+				targetPowerCckExt.tPow2x[0];
+		}
+	}
+	return true;
 }
 
-static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
+static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
 				    struct ath9k_channel *chan,
-				    u8 index, u16 *config)
+				    u16 cfgCtl,
+				    u8 twiceAntennaReduction,
+				    u8 twiceMaxRegulatoryPower,
+				    u8 powerLimit)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	struct modal_eep_header *pModal =
+		&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t txPowerIndexOffset = 0;
+	u8 ht40PowerIncForPdadc = 2;
+	int i, cck_ofdm_delta = 0;
 
-	switch (index) {
-	case 0:
-		*config = pModal->antCtrlCommon & 0xFFFF;
-		return 0;
-	default:
-		break;
+	memset(ratesArray, 0, sizeof(ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
 	}
 
-	return -EINVAL;
-}
+	if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+					       &ratesArray[0], cfgCtl,
+					       twiceAntennaReduction,
+					       twiceMaxRegulatoryPower,
+					       powerLimit)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"ath9k_hw_set_txpower: unable to set "
+			"tx power per rate table\n");
+		return -EIO;
+	}
 
-static int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *,
-					     struct ath9k_channel *,
-					     u8, u16 *) = {
-	ath9k_hw_get_def_eeprom_antenna_cfg,
-	ath9k_hw_get_4k_eeprom_antenna_cfg
-};
+	if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			 "ath9k_hw_set_txpower: unable to set power table\n");
+		return -EIO;
+	}
 
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
-				    struct ath9k_channel *chan,
-				    u8 index, u16 *config)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+			ratesArray[i] = AR5416_MAX_RATE_POWER;
+	}
 
-	return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan,
-							     index, config);
-}
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	}
 
-static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
-					 enum ieee80211_band freq_band)
-{
-	return 1;
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	if (IS_CHAN_2GHZ(chan)) {
+		if (OLC_FOR_AR9280_20_LATER) {
+			cck_ofdm_delta = 2;
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+				ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+				| ATH9K_POW_SM(ratesArray[rateXr], 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+				ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+		} else {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+				ATH9K_POW_SM(ratesArray[rate2s], 24)
+				| ATH9K_POW_SM(ratesArray[rate2l], 16)
+				| ATH9K_POW_SM(ratesArray[rateXr], 8)
+				| ATH9K_POW_SM(ratesArray[rate1l], 0));
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+				ATH9K_POW_SM(ratesArray[rate11s], 24)
+				| ATH9K_POW_SM(ratesArray[rate11l], 16)
+				| ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+				| ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	if (IS_CHAN_HT40(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+					 ht40PowerIncForPdadc, 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+					 ht40PowerIncForPdadc, 0));
+		if (OLC_FOR_AR9280_20_LATER) {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+		} else {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+				| ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+				| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+	i = rate6mb;
+
+	if (IS_CHAN_HT40(chan))
+		i = rateHt40_0;
+	else if (IS_CHAN_HT20(chan))
+		i = rateHt20_0;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ah->regulatory.max_power_level =
+			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+	else
+		ah->regulatory.max_power_level = ratesArray[i];
+
+	switch(ar5416_get_ntxchains(ah->txchainmask)) {
+	case 1:
+		break;
+	case 2:
+		ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+		break;
+	case 3:
+		ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+		break;
+	default:
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Invalid chainmask configuration\n");
+		break;
+	}
+
+	return 0;
 }
 
-static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
 					  enum ieee80211_band freq_band)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
 	struct modal_eep_header *pModal =
 		&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
 	struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -2645,180 +2739,75 @@ static u8 ath9k_hw_get_def_num_ant_confi
 	return num_ant_config;
 }
 
-static u8 (*ath9k_get_num_ant_config[])(struct ath_hal *,
-					enum ieee80211_band) = {
-	ath9k_hw_get_def_num_ant_config,
-	ath9k_hw_get_4k_num_ant_config
-};
-
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
-			       enum ieee80211_band freq_band)
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+					       struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	struct modal_eep_header *pModal =
+		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 
-	return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band);
+	return pModal->antCtrlCommon & 0xFFFF;
 }
 
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
 {
-#define EEP_MAP4K_SPURCHAN \
-	(ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
 #define EEP_DEF_SPURCHAN \
-	(ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	(ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
 	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->ah_config.spurchans[i][is2GHz]);
+		i, is2GHz, ah->config.spurchans[i][is2GHz]);
 
-	switch (ah->ah_config.spurmode) {
+	switch (ah->config.spurmode) {
 	case SPUR_DISABLE:
 		break;
 	case SPUR_ENABLE_IOCTL:
-		spur_val = ah->ah_config.spurchans[i][is2GHz];
+		spur_val = ah->config.spurchans[i][is2GHz];
 		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
 			"Getting spur val from new loc. %d\n", spur_val);
 		break;
 	case SPUR_ENABLE_EEPROM:
-		if (ahp->ah_eep_map == EEP_MAP_4KBITS)
-			spur_val = EEP_MAP4K_SPURCHAN;
-		else
-			spur_val = EEP_DEF_SPURCHAN;
+		spur_val = EEP_DEF_SPURCHAN;
 		break;
-
 	}
 
 	return spur_val;
-#undef EEP_DEF_SPURCHAN
-#undef EEP_MAP4K_SPURCHAN
-}
 
-static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
-				  enum eeprom_param param)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &eep->modalHeader;
-	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
-
-	switch (param) {
-	case EEP_NFTHRESH_2:
-		return pModal[1].noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
-		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
-		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
-		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-	case EEP_REG_0:
-		return pBase->regDmn[0];
-	case EEP_REG_1:
-		return pBase->regDmn[1];
-	case EEP_OP_CAP:
-		return pBase->deviceCap;
-	case EEP_OP_MODE:
-		return pBase->opCapFlags;
-	case EEP_RF_SILENT:
-		return pBase->rfSilent;
-	case EEP_OB_2:
-		return pModal->ob_01;
-	case EEP_DB_2:
-		return pModal->db1_01;
-	case EEP_MINOR_REV:
-		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
-	case EEP_TX_MASK:
-		return pBase->txMask;
-	case EEP_RX_MASK:
-		return pBase->rxMask;
-	default:
-		return 0;
-	}
-}
-
-static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah,
-				   enum eeprom_param param)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
-	struct modal_eep_header *pModal = eep->modalHeader;
-	struct base_eep_header *pBase = &eep->baseEepHeader;
-
-	switch (param) {
-	case EEP_NFTHRESH_5:
-		return pModal[0].noiseFloorThreshCh[0];
-	case EEP_NFTHRESH_2:
-		return pModal[1].noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
-		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
-		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
-		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-	case EEP_REG_0:
-		return pBase->regDmn[0];
-	case EEP_REG_1:
-		return pBase->regDmn[1];
-	case EEP_OP_CAP:
-		return pBase->deviceCap;
-	case EEP_OP_MODE:
-		return pBase->opCapFlags;
-	case EEP_RF_SILENT:
-		return pBase->rfSilent;
-	case EEP_OB_5:
-		return pModal[0].ob;
-	case EEP_DB_5:
-		return pModal[0].db;
-	case EEP_OB_2:
-		return pModal[1].ob;
-	case EEP_DB_2:
-		return pModal[1].db;
-	case EEP_MINOR_REV:
-		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
-	case EEP_TX_MASK:
-		return pBase->txMask;
-	case EEP_RX_MASK:
-		return pBase->rxMask;
-	case EEP_RXGAIN_TYPE:
-		return pBase->rxGainType;
-	case EEP_TXGAIN_TYPE:
-		return pBase->txGainType;
-
-	default:
-		return 0;
-	}
+#undef EEP_DEF_SPURCHAN
 }
 
-static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = {
-	ath9k_hw_get_eeprom_def,
-	ath9k_hw_get_eeprom_4k
+static struct eeprom_ops eep_def_ops = {
+	.check_eeprom		= ath9k_hw_def_check_eeprom,
+	.get_eeprom		= ath9k_hw_def_get_eeprom,
+	.fill_eeprom		= ath9k_hw_def_fill_eeprom,
+	.get_eeprom_ver		= ath9k_hw_def_get_eeprom_ver,
+	.get_eeprom_rev		= ath9k_hw_def_get_eeprom_rev,
+	.get_num_ant_config	= ath9k_hw_def_get_num_ant_config,
+	.get_eeprom_antenna_cfg	= ath9k_hw_def_get_eeprom_antenna_cfg,
+	.set_board_values	= ath9k_hw_def_set_board_values,
+	.set_addac		= ath9k_hw_def_set_addac,
+	.set_txpower		= ath9k_hw_def_set_txpower,
+	.get_spur_channel	= ath9k_hw_def_get_spur_channel
 };
 
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
-			enum eeprom_param param)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	return ath9k_get_eeprom[ahp->ah_eep_map](ah, param);
-}
-
-int ath9k_hw_eeprom_attach(struct ath_hal *ah)
+int ath9k_hw_eeprom_attach(struct ath_hw *ah)
 {
 	int status;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
-	if (ath9k_hw_use_flash(ah))
-		ath9k_hw_flash_map(ah);
-
-	if (AR_SREV_9285(ah))
-		ahp->ah_eep_map = EEP_MAP_4KBITS;
-	else
-		ahp->ah_eep_map = EEP_MAP_DEFAULT;
+	if (AR_SREV_9285(ah)) {
+		ah->eep_map = EEP_MAP_4KBITS;
+		ah->eep_ops = &eep_4k_ops;
+	} else {
+		ah->eep_map = EEP_MAP_DEFAULT;
+		ah->eep_ops = &eep_def_ops;
+	}
 
-	if (!ath9k_hw_fill_eeprom(ah))
+	if (!ah->eep_ops->fill_eeprom(ah))
 		return -EIO;
 
-	status = ath9k_hw_check_eeprom(ah);
+	status = ah->eep_ops->check_eeprom(ah);
 
 	return status;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/eeprom.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/eeprom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,507 @@
+/*
+ * 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 EEPROM_H
+#define EEPROM_H
+
+#define AH_USE_EEPROM   0x1
+
+#ifdef __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG   0x1ff
+#define	CTRY_DEFAULT 0
+
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
+#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
+#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
+#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
+#define AR_EEPROM_EEPCAP_MAXQCU_S       4
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
+#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
+
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
+#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
+
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
+
+#define AR5416_EEPROM_MAGIC_OFFSET  0x0
+#define AR5416_EEPROM_S             2
+#define AR5416_EEPROM_OFFSET        0x2000
+#define AR5416_EEPROM_MAX           0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+	(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#define SD_NO_CTL               0xE0
+#define NO_CTL                  0xff
+#define CTL_MODE_M              7
+#define CTL_11A                 0
+#define CTL_11B                 1
+#define CTL_11G                 2
+#define CTL_2GHT20              5
+#define CTL_5GHT20              6
+#define CTL_2GHT40              7
+#define CTL_5GHT40              8
+
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
+
+#define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT    0x1F
+
+#define AR_EEPROM_MAC(i)	(0x1d+(i))
+#define ATH9K_POW_SM(_r, _s)	(((_r) & 0x3f) << (_s))
+#define FREQ2FBIN(x, y)		((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define ath9k_hw_use_flash(_ah)	(!(_ah->ah_flags & AH_USE_EEPROM))
+
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+				 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
+#define AR_EEPROM_RFSILENT_POLARITY     0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S   1
+
+#define EEP_RFSILENT_ENABLED        0x0001
+#define EEP_RFSILENT_ENABLED_S      0
+#define EEP_RFSILENT_POLARITY       0x0002
+#define EEP_RFSILENT_POLARITY_S     1
+#define EEP_RFSILENT_GPIO_SEL       0x001c
+#define EEP_RFSILENT_GPIO_SEL_S     2
+
+#define AR5416_OPFLAGS_11A           0x01
+#define AR5416_OPFLAGS_11G           0x02
+#define AR5416_OPFLAGS_N_5G_HT40     0x04
+#define AR5416_OPFLAGS_N_2G_HT40     0x08
+#define AR5416_OPFLAGS_N_5G_HT20     0x10
+#define AR5416_OPFLAGS_N_2G_HT20     0x20
+
+#define AR5416_EEP_NO_BACK_VER       0x1
+#define AR5416_EEP_VER               0xE
+#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
+#define AR5416_EEP_MINOR_VER_2       0x2
+#define AR5416_EEP_MINOR_VER_3       0x3
+#define AR5416_EEP_MINOR_VER_7       0x7
+#define AR5416_EEP_MINOR_VER_9       0x9
+#define AR5416_EEP_MINOR_VER_16      0x10
+#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_22      0x16
+
+#define AR5416_NUM_5G_CAL_PIERS         8
+#define AR5416_NUM_2G_CAL_PIERS         4
+#define AR5416_NUM_5G_20_TARGET_POWERS  8
+#define AR5416_NUM_5G_40_TARGET_POWERS  8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS  4
+#define AR5416_NUM_2G_40_TARGET_POWERS  4
+#define AR5416_NUM_CTLS                 24
+#define AR5416_NUM_BAND_EDGES           8
+#define AR5416_NUM_PD_GAINS             4
+#define AR5416_PD_GAINS_IN_MASK         4
+#define AR5416_PD_GAIN_ICEPTS           5
+#define AR5416_EEPROM_MODAL_SPURS       5
+#define AR5416_MAX_RATE_POWER           63
+#define AR5416_NUM_PDADC_VALUES         128
+#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
+
+/* Rx gain type values */
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
+#define AR5416_EEP_RXGAIN_ORIG             2
+
+/* Tx gain type values */
+#define AR5416_EEP_TXGAIN_ORIGINAL         0
+#define AR5416_EEP_TXGAIN_HIGH_POWER       1
+
+#define AR5416_EEP4K_START_LOC                64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS         3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_CTLS                 12
+#define AR5416_EEP4K_NUM_BAND_EDGES           4
+#define AR5416_EEP4K_NUM_PD_GAINS             2
+#define AR5416_EEP4K_PD_GAINS_IN_MASK         4
+#define AR5416_EEP4K_PD_GAIN_ICEPTS           5
+#define AR5416_EEP4K_MAX_CHAINS               1
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+enum eeprom_param {
+	EEP_NFTHRESH_5,
+	EEP_NFTHRESH_2,
+	EEP_MAC_MSW,
+	EEP_MAC_MID,
+	EEP_MAC_LSW,
+	EEP_REG_0,
+	EEP_REG_1,
+	EEP_OP_CAP,
+	EEP_OP_MODE,
+	EEP_RF_SILENT,
+	EEP_OB_5,
+	EEP_DB_5,
+	EEP_OB_2,
+	EEP_DB_2,
+	EEP_MINOR_REV,
+	EEP_TX_MASK,
+	EEP_RX_MASK,
+	EEP_RXGAIN_TYPE,
+	EEP_TXGAIN_TYPE,
+	EEP_OL_PWRCTRL,
+	EEP_RC_CHAIN_MASK,
+	EEP_DAC_HPWR_5G,
+	EEP_FRAC_N_5G
+};
+
+enum ar5416_rates {
+	rate6mb, rate9mb, rate12mb, rate18mb,
+	rate24mb, rate36mb, rate48mb, rate54mb,
+	rate1l, rate2l, rate2s, rate5_5l,
+	rate5_5s, rate11l, rate11s, rateXr,
+	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+	Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+	ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+	ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+struct base_eep_header {
+	u16 length;
+	u16 checksum;
+	u16 version;
+	u8 opCapFlags;
+	u8 eepMisc;
+	u16 regDmn[2];
+	u8 macAddr[6];
+	u8 rxMask;
+	u8 txMask;
+	u16 rfSilent;
+	u16 blueToothOptions;
+	u16 deviceCap;
+	u32 binBuildNumber;
+	u8 deviceType;
+	u8 pwdclkind;
+	u8 futureBase_1[2];
+	u8 rxGainType;
+	u8 dacHiPwrMode_5G;
+	u8 openLoopPwrCntl;
+	u8 dacLpMode;
+	u8 txGainType;
+	u8 rcChainMask;
+	u8 desiredScaleCCK;
+	u8 power_table_offset;
+	u8 frac_n_5g;
+	u8 futureBase_3[21];
+} __packed;
+
+struct base_eep_header_4k {
+	u16 length;
+	u16 checksum;
+	u16 version;
+	u8 opCapFlags;
+	u8 eepMisc;
+	u16 regDmn[2];
+	u8 macAddr[6];
+	u8 rxMask;
+	u8 txMask;
+	u16 rfSilent;
+	u16 blueToothOptions;
+	u16 deviceCap;
+	u32 binBuildNumber;
+	u8 deviceType;
+	u8 txGainType;
+} __packed;
+
+
+struct spur_chan {
+	u16 spurChan;
+	u8 spurRangeLow;
+	u8 spurRangeHigh;
+} __packed;
+
+struct modal_eep_header {
+	u32 antCtrlChain[AR5416_MAX_CHAINS];
+	u32 antCtrlCommon;
+	u8 antennaGainCh[AR5416_MAX_CHAINS];
+	u8 switchSettling;
+	u8 txRxAttenCh[AR5416_MAX_CHAINS];
+	u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+	u8 adcDesiredSize;
+	u8 pgaDesiredSize;
+	u8 xlnaGainCh[AR5416_MAX_CHAINS];
+	u8 txEndToXpaOff;
+	u8 txEndToRxOn;
+	u8 txFrameToXpaOn;
+	u8 thresh62;
+	u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+	u8 xpdGain;
+	u8 xpd;
+	u8 iqCalICh[AR5416_MAX_CHAINS];
+	u8 iqCalQCh[AR5416_MAX_CHAINS];
+	u8 pdGainOverlap;
+	u8 ob;
+	u8 db;
+	u8 xpaBiasLvl;
+	u8 pwrDecreaseFor2Chain;
+	u8 pwrDecreaseFor3Chain;
+	u8 txFrameToDataStart;
+	u8 txFrameToPaOn;
+	u8 ht40PowerIncForPdadc;
+	u8 bswAtten[AR5416_MAX_CHAINS];
+	u8 bswMargin[AR5416_MAX_CHAINS];
+	u8 swSettleHt40;
+	u8 xatten2Db[AR5416_MAX_CHAINS];
+	u8 xatten2Margin[AR5416_MAX_CHAINS];
+	u8 ob_ch1;
+	u8 db_ch1;
+	u8 useAnt1:1,
+	    force_xpaon:1,
+	    local_bias:1,
+	    femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+	u8 miscBits;
+	u16 xpaBiasLvlFreq[3];
+	u8 futureModal[6];
+
+	struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct calDataPerFreqOpLoop {
+	u8 pwrPdg[2][5];
+	u8 vpdPdg[2][5];
+	u8 pcdac[2][5];
+	u8 empty[2][5];
+} __packed;
+
+struct modal_eep_4k_header {
+	u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+	u32  antCtrlCommon;
+	u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   switchSettling;
+	u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   adcDesiredSize;
+	u8   pgaDesiredSize;
+	u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   txEndToXpaOff;
+	u8   txEndToRxOn;
+	u8   txFrameToXpaOn;
+	u8   thresh62;
+	u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   xpdGain;
+	u8   xpd;
+	u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+	u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+	u8   pdGainOverlap;
+	u8   ob_01;
+	u8   db1_01;
+	u8   xpaBiasLvl;
+	u8   txFrameToDataStart;
+	u8   txFrameToPaOn;
+	u8   ht40PowerIncForPdadc;
+	u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
+	u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
+	u8   swSettleHt40;
+	u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+	u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+	u8   db2_01;
+	u8   version;
+	u16  ob_234;
+	u16  db1_234;
+	u16  db2_234;
+	u8   futureModal[4];
+
+	struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
+struct cal_data_per_freq {
+	u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+	u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_data_per_freq_4k {
+	u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+	u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_target_power_leg {
+	u8 bChannel;
+	u8 tPow2x[4];
+} __packed;
+
+struct cal_target_power_ht {
+	u8 bChannel;
+	u8 tPow2x[8];
+} __packed;
+
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+	u8 bChannel;
+	u8 flag:2, tPower:6;
+} __packed;
+#else
+struct cal_ctl_edges {
+	u8 bChannel;
+	u8 tPower:6, flag:2;
+} __packed;
+#endif
+
+struct cal_ctl_data {
+	struct cal_ctl_edges
+	ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+	struct cal_ctl_edges
+	ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom_def {
+	struct base_eep_header baseEepHeader;
+	u8 custData[64];
+	struct modal_eep_header modalHeader[2];
+	u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+	u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+	struct cal_data_per_freq
+	 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+	struct cal_data_per_freq
+	 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+	struct cal_target_power_leg
+	 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+	struct cal_target_power_leg
+	 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_target_power_leg
+	 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+	u8 ctlIndex[AR5416_NUM_CTLS];
+	struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+	u8 padding;
+} __packed;
+
+struct ar5416_eeprom_4k {
+	struct base_eep_header_4k baseEepHeader;
+	u8 custData[20];
+	struct modal_eep_4k_header modalHeader;
+	u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+	struct cal_data_per_freq_4k
+	calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+	struct cal_target_power_leg
+	calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_target_power_leg
+	calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+	u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+	struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+	u8 padding;
+} __packed;
+
+enum reg_ext_bitmap {
+	REG_EXT_JAPAN_MIDBAND = 1,
+	REG_EXT_FCC_DFS_HT40 = 2,
+	REG_EXT_JAPAN_NONDFS_HT40 = 3,
+	REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+	u16 countryCode;
+	u16 regDmnEnum;
+	u16 regDmn5G;
+	u16 regDmn2G;
+	u8 isMultidomain;
+	u8 iso[3];
+};
+
+enum ath9k_eep_map {
+	EEP_MAP_DEFAULT = 0x0,
+	EEP_MAP_4KBITS,
+	EEP_MAP_MAX
+};
+
+struct eeprom_ops {
+	int (*check_eeprom)(struct ath_hw *hw);
+	u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
+	bool (*fill_eeprom)(struct ath_hw *hw);
+	int (*get_eeprom_ver)(struct ath_hw *hw);
+	int (*get_eeprom_rev)(struct ath_hw *hw);
+	u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+	u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+				      struct ath9k_channel *chan);
+	void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+	void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+	int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+			   u16 cfgCtl, u8 twiceAntennaReduction,
+			   u8 twiceMaxRegulatoryPower, u8 powerLimit);
+	u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+};
+
+#define ar5416_get_ntxchains(_txchainmask)			\
+	(((_txchainmask >> 2) & 1) +                            \
+	 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+
+#endif /* EEPROM_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/hw.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/hw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/hw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -17,88 +17,80 @@
 #include <linux/io.h>
 #include <asm/unaligned.h>
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
 #include "initvals.h"
 
-static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
 
-extern struct hal_percal_data iq_cal_multi_sample;
-extern struct hal_percal_data iq_cal_single_sample;
-extern struct hal_percal_data adc_gain_cal_multi_sample;
-extern struct hal_percal_data adc_gain_cal_single_sample;
-extern struct hal_percal_data adc_dc_cal_multi_sample;
-extern struct hal_percal_data adc_dc_cal_single_sample;
-extern struct hal_percal_data adc_init_dc_cal;
+#define ATH9K_CLOCK_RATE_CCK		22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
 
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+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 u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+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_hal *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
+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);
 
 /********************/
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
 {
-	if (ah->ah_curchan != NULL)
-		return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
-	else
-		return clks / CLOCK_RATE[ATH9K_MODE_11B];
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+	if (!ah->curchan) /* should really check for CCK instead */
+		return clks / ATH9K_CLOCK_RATE_CCK;
+	if (conf->channel->band == IEEE80211_BAND_2GHZ)
+		return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+
+	return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
 }
 
-static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
 {
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
 
-	if (chan && IS_CHAN_HT40(chan))
+	if (conf_is_ht40(conf))
 		return ath9k_hw_mac_usec(ah, clks) / 2;
 	else
 		return ath9k_hw_mac_usec(ah, clks);
 }
 
-static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
 {
-	if (ah->ah_curchan != NULL)
-		return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
-			ah->ah_curchan)];
-	else
-		return usecs * CLOCK_RATE[ATH9K_MODE_11B];
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+	if (!ah->curchan) /* should really check for CCK instead */
+		return usecs *ATH9K_CLOCK_RATE_CCK;
+	if (conf->channel->band == IEEE80211_BAND_2GHZ)
+		return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+	return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
 }
 
-static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
 {
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
 
-	if (chan && IS_CHAN_HT40(chan))
+	if (conf_is_ht40(conf))
 		return ath9k_hw_mac_clks(ah, usecs) * 2;
 	else
 		return ath9k_hw_mac_clks(ah, usecs);
 }
 
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
-			       const struct ath9k_channel *chan)
-{
-	if (IS_CHAN_B(chan))
-		return ATH9K_MODE_11B;
-	if (IS_CHAN_G(chan))
-		return ATH9K_MODE_11G;
-
-	return ATH9K_MODE_11A;
-}
-
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
 {
 	int i;
 
-	for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
+	BUG_ON(timeout < AH_TIME_QUANTUM);
+
+	for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
 		if ((REG_READ(ah, reg) & mask) == val)
 			return true;
 
@@ -106,8 +98,8 @@ bool ath9k_hw_wait(struct ath_hal *ah, u
 	}
 
 	DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-		"timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
-		reg, REG_READ(ah, reg), mask, val);
+		"timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+		timeout, reg, REG_READ(ah, reg), mask, val);
 
 	return false;
 }
@@ -124,11 +116,11 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n
 	return retval;
 }
 
-bool ath9k_get_channel_edges(struct ath_hal *ah,
+bool ath9k_get_channel_edges(struct ath_hw *ah,
 			     u16 flags, u16 *low,
 			     u16 *high)
 {
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 	if (flags & CHANNEL_5GHZ) {
 		*low = pCap->low_5ghz_chan;
@@ -143,7 +135,7 @@ bool ath9k_get_channel_edges(struct ath_
 	return false;
 }
 
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
 			   struct ath_rate_table *rates,
 			   u32 frameLen, u16 rateix,
 			   bool shortPreamble)
@@ -165,15 +157,15 @@ u16 ath9k_hw_computetxtime(struct ath_ha
 		txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
 		break;
 	case WLAN_RC_PHY_OFDM:
-		if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
+		if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
 			bitsPerSymbol =	(kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
 			numBits = OFDM_PLCP_BITS + (frameLen << 3);
 			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
 			txTime = OFDM_SIFS_TIME_QUARTER
 				+ OFDM_PREAMBLE_TIME_QUARTER
 				+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
-		} else if (ah->ah_curchan &&
-			   IS_CHAN_HALF_RATE(ah->ah_curchan)) {
+		} else if (ah->curchan &&
+			   IS_CHAN_HALF_RATE(ah->curchan)) {
 			bitsPerSymbol =	(kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
 			numBits = OFDM_PLCP_BITS + (frameLen << 3);
 			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
@@ -199,52 +191,11 @@ u16 ath9k_hw_computetxtime(struct ath_ha
 	return txTime;
 }
 
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
-{
-	if (flags & CHANNEL_2GHZ) {
-		if (freq == 2484)
-			return 14;
-		if (freq < 2484)
-			return (freq - 2407) / 5;
-		else
-			return 15 + ((freq - 2512) / 20);
-	} else if (flags & CHANNEL_5GHZ) {
-		if (ath9k_regd_is_public_safety_sku(ah) &&
-		    IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
-			return ((freq * 10) +
-				(((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
-		} else if ((flags & CHANNEL_A) && (freq <= 5000)) {
-			return (freq - 4000) / 5;
-		} else {
-			return (freq - 5000) / 5;
-		}
-	} else {
-		if (freq == 2484)
-			return 14;
-		if (freq < 2484)
-			return (freq - 2407) / 5;
-		if (freq < 5000) {
-			if (ath9k_regd_is_public_safety_sku(ah)
-			    && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
-				return ((freq * 10) +
-					(((freq % 5) ==
-					  2) ? 5 : 0) - 49400) / 5;
-			} else if (freq > 4900) {
-				return (freq - 4000) / 5;
-			} else {
-				return 15 + ((freq - 2512) / 20);
-			}
-		}
-		return (freq - 5000) / 5;
-	}
-}
-
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
 				  struct ath9k_channel *chan,
 				  struct chan_centers *centers)
 {
 	int8_t extoff;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
 	if (!IS_CHAN_HT40(chan)) {
 		centers->ctl_center = centers->ext_center =
@@ -267,16 +218,15 @@ void ath9k_hw_get_channel_centers(struct
 		centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
 	centers->ext_center =
 		centers->synth_center + (extoff *
-			 ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+			 ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
 			  HT40_CHANNEL_CENTER_SHIFT : 15));
-
 }
 
 /******************/
 /* Chip Revisions */
 /******************/
 
-static void ath9k_hw_read_revisions(struct ath_hal *ah)
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
 {
 	u32 val;
 
@@ -284,21 +234,22 @@ static void ath9k_hw_read_revisions(stru
 
 	if (val == 0xFF) {
 		val = REG_READ(ah, AR_SREV);
-		ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
-		ah->ah_macRev = MS(val, AR_SREV_REVISION2);
-		ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+		ah->hw_version.macVersion =
+			(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+		ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
 	} else {
 		if (!AR_SREV_9100(ah))
-			ah->ah_macVersion = MS(val, AR_SREV_VERSION);
+			ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
 
-		ah->ah_macRev = val & AR_SREV_REVISION;
+		ah->hw_version.macRev = val & AR_SREV_REVISION;
 
-		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
-			ah->ah_isPciExpress = true;
+		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+			ah->is_pciexpress = true;
 	}
 }
 
-static int ath9k_hw_get_radiorev(struct ath_hal *ah)
+static int ath9k_hw_get_radiorev(struct ath_hw *ah)
 {
 	u32 val;
 	int i;
@@ -317,9 +268,9 @@ static int ath9k_hw_get_radiorev(struct
 /* HW Attach, Detach, Init Routines */
 /************************************/
 
-static void ath9k_hw_disablepcie(struct ath_hal *ah)
+static void ath9k_hw_disablepcie(struct ath_hw *ah)
 {
-	if (!AR_SREV_9100(ah))
+	if (AR_SREV_9100(ah))
 		return;
 
 	REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
@@ -335,7 +286,7 @@ static void ath9k_hw_disablepcie(struct
 	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
 }
 
-static bool ath9k_hw_chip_test(struct ath_hal *ah)
+static bool ath9k_hw_chip_test(struct ath_hw *ah)
 {
 	u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
 	u32 regHold[2];
@@ -377,6 +328,7 @@ static bool ath9k_hw_chip_test(struct at
 		REG_WRITE(ah, regAddr[i], regHold[i]);
 	}
 	udelay(100);
+
 	return true;
 }
 
@@ -389,6 +341,8 @@ static const char *ath9k_hw_devname(u16
 		return "Atheros 5418";
 	case AR9160_DEVID_PCI:
 		return "Atheros 9160";
+	case AR5416_AR9100_DEVID:
+		return "Atheros 9100";
 	case AR9280_DEVID_PCI:
 	case AR9280_DEVID_PCIE:
 		return "Atheros 9280";
@@ -399,44 +353,44 @@ static const char *ath9k_hw_devname(u16
 	return NULL;
 }
 
-static void ath9k_hw_set_defaults(struct ath_hal *ah)
+static void ath9k_hw_set_defaults(struct ath_hw *ah)
 {
 	int i;
 
-	ah->ah_config.dma_beacon_response_time = 2;
-	ah->ah_config.sw_beacon_response_time = 10;
-	ah->ah_config.additional_swba_backoff = 0;
-	ah->ah_config.ack_6mb = 0x0;
-	ah->ah_config.cwm_ignore_extcca = 0;
-	ah->ah_config.pcie_powersave_enable = 0;
-	ah->ah_config.pcie_l1skp_enable = 0;
-	ah->ah_config.pcie_clock_req = 0;
-	ah->ah_config.pcie_power_reset = 0x100;
-	ah->ah_config.pcie_restore = 0;
-	ah->ah_config.pcie_waen = 0;
-	ah->ah_config.analog_shiftreg = 1;
-	ah->ah_config.ht_enable = 1;
-	ah->ah_config.ofdm_trig_low = 200;
-	ah->ah_config.ofdm_trig_high = 500;
-	ah->ah_config.cck_trig_high = 200;
-	ah->ah_config.cck_trig_low = 100;
-	ah->ah_config.enable_ani = 1;
-	ah->ah_config.noise_immunity_level = 4;
-	ah->ah_config.ofdm_weaksignal_det = 1;
-	ah->ah_config.cck_weaksignal_thr = 0;
-	ah->ah_config.spur_immunity_level = 2;
-	ah->ah_config.firstep_level = 0;
-	ah->ah_config.rssi_thr_high = 40;
-	ah->ah_config.rssi_thr_low = 7;
-	ah->ah_config.diversity_control = 0;
-	ah->ah_config.antenna_switch_swap = 0;
+	ah->config.dma_beacon_response_time = 2;
+	ah->config.sw_beacon_response_time = 10;
+	ah->config.additional_swba_backoff = 0;
+	ah->config.ack_6mb = 0x0;
+	ah->config.cwm_ignore_extcca = 0;
+	ah->config.pcie_powersave_enable = 0;
+	ah->config.pcie_l1skp_enable = 0;
+	ah->config.pcie_clock_req = 0;
+	ah->config.pcie_power_reset = 0x100;
+	ah->config.pcie_restore = 0;
+	ah->config.pcie_waen = 0;
+	ah->config.analog_shiftreg = 1;
+	ah->config.ht_enable = 1;
+	ah->config.ofdm_trig_low = 200;
+	ah->config.ofdm_trig_high = 500;
+	ah->config.cck_trig_high = 200;
+	ah->config.cck_trig_low = 100;
+	ah->config.enable_ani = 1;
+	ah->config.noise_immunity_level = 4;
+	ah->config.ofdm_weaksignal_det = 1;
+	ah->config.cck_weaksignal_thr = 0;
+	ah->config.spur_immunity_level = 2;
+	ah->config.firstep_level = 0;
+	ah->config.rssi_thr_high = 40;
+	ah->config.rssi_thr_low = 7;
+	ah->config.diversity_control = 0;
+	ah->config.antenna_switch_swap = 0;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
-		ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
+		ah->config.spurchans[i][0] = AR_NO_SPUR;
+		ah->config.spurchans[i][1] = AR_NO_SPUR;
 	}
 
-	ah->ah_config.intr_mitigation = 1;
+	ah->config.intr_mitigation = 1;
 
 	/*
 	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -455,62 +409,54 @@ static void ath9k_hw_set_defaults(struct
 	 * devices (legacy, 802.11abg).
 	 */
 	if (num_possible_cpus() > 1)
-		ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO;
+		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
 }
 
-static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
-					      struct ath_softc *sc,
-					      void __iomem *mem,
-					      int *status)
+static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
+					int *status)
 {
-	static const u8 defbssidmask[ETH_ALEN] =
-		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-	struct ath_hal_5416 *ahp;
-	struct ath_hal *ah;
+	struct ath_hw *ah;
 
-	ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
-	if (ahp == NULL) {
+	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+	if (ah == NULL) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Cannot allocate memory for state block\n");
 		*status = -ENOMEM;
 		return NULL;
 	}
 
-	ah = &ahp->ah;
 	ah->ah_sc = sc;
-	ah->ah_sh = mem;
-	ah->ah_magic = AR5416_MAGIC;
-	ah->ah_countryCode = CTRY_DEFAULT;
-	ah->ah_devid = devid;
-	ah->ah_subvendorid = 0;
+	ah->hw_version.magic = AR5416_MAGIC;
+	ah->regulatory.country_code = CTRY_DEFAULT;
+	ah->hw_version.devid = devid;
+	ah->hw_version.subvendorid = 0;
 
 	ah->ah_flags = 0;
 	if ((devid == AR5416_AR9100_DEVID))
-		ah->ah_macVersion = AR_SREV_VERSION_9100;
+		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
 	if (!AR_SREV_9100(ah))
 		ah->ah_flags = AH_USE_EEPROM;
 
-	ah->ah_powerLimit = MAX_RATE_POWER;
-	ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
-	ahp->ah_atimWindow = 0;
-	ahp->ah_diversityControl = ah->ah_config.diversity_control;
-	ahp->ah_antennaSwitchSwap =
-		ah->ah_config.antenna_switch_swap;
-	ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
-	ahp->ah_beaconInterval = 100;
-	ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
-	ahp->ah_slottime = (u32) -1;
-	ahp->ah_acktimeout = (u32) -1;
-	ahp->ah_ctstimeout = (u32) -1;
-	ahp->ah_globaltxtimeout = (u32) -1;
-	memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
+	ah->regulatory.power_limit = MAX_RATE_POWER;
+	ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
+	ah->atim_window = 0;
+	ah->diversity_control = ah->config.diversity_control;
+	ah->antenna_switch_swap =
+		ah->config.antenna_switch_swap;
+	ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+	ah->beacon_interval = 100;
+	ah->enable_32kHz_clock = DONT_USE_32KHZ;
+	ah->slottime = (u32) -1;
+	ah->acktimeout = (u32) -1;
+	ah->ctstimeout = (u32) -1;
+	ah->globaltxtimeout = (u32) -1;
 
-	ahp->ah_gBeaconRate = 0;
+	ah->gbeacon_rate = 0;
 
-	return ahp;
+	return ah;
 }
 
-static int ath9k_hw_rfattach(struct ath_hal *ah)
+static int ath9k_hw_rfattach(struct ath_hw *ah)
 {
 	bool rfStatus = false;
 	int ecode = 0;
@@ -525,7 +471,7 @@ static int ath9k_hw_rfattach(struct ath_
 	return 0;
 }
 
-static int ath9k_hw_rf_claim(struct ath_hal *ah)
+static int ath9k_hw_rf_claim(struct ath_hw *ah)
 {
 	u32 val;
 
@@ -545,88 +491,87 @@ static int ath9k_hw_rf_claim(struct ath_
 		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
 			"5G Radio Chip Rev 0x%02X is not "
 			"supported by this driver\n",
-			ah->ah_analog5GhzRev);
+			ah->hw_version.analog5GhzRev);
 		return -EOPNOTSUPP;
 	}
 
-	ah->ah_analog5GhzRev = val;
+	ah->hw_version.analog5GhzRev = val;
 
 	return 0;
 }
 
-static int ath9k_hw_init_macaddr(struct ath_hal *ah)
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 {
 	u32 sum;
 	int i;
 	u16 eeval;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
 	sum = 0;
 	for (i = 0; i < 3; i++) {
-		eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i));
+		eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
 		sum += eeval;
-		ahp->ah_macaddr[2 * i] = eeval >> 8;
-		ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
+		ah->macaddr[2 * i] = eeval >> 8;
+		ah->macaddr[2 * i + 1] = eeval & 0xff;
 	}
 	if (sum == 0 || sum == 0xffff * 3) {
 		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
 			"mac address read failed: %pM\n",
-			ahp->ah_macaddr);
+			ah->macaddr);
 		return -EADDRNOTAVAIL;
 	}
 
 	return 0;
 }
 
-static void ath9k_hw_init_rxgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
 {
 	u32 rxgain_type;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
-	if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
-		rxgain_type = ath9k_hw_get_eeprom(ah, EEP_RXGAIN_TYPE);
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+		rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
 
 		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
-			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9280Modes_backoff_13db_rxgain_9280_2,
 			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
 		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
-			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9280Modes_backoff_23db_rxgain_9280_2,
 			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
 		else
-			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9280Modes_original_rxgain_9280_2,
 			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-	} else
-		INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+	} else {
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9280Modes_original_rxgain_9280_2,
 			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+	}
 }
 
-static void ath9k_hw_init_txgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
 {
 	u32 txgain_type;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
-	if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
-		txgain_type = ath9k_hw_get_eeprom(ah, EEP_TXGAIN_TYPE);
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+		txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
 
 		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
-			INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9280Modes_high_power_tx_gain_9280_2,
 			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
 		else
-			INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9280Modes_original_tx_gain_9280_2,
 			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-	} else
-		INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+	} else {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
 		ar9280Modes_original_tx_gain_9280_2,
 		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+	}
 }
 
-static int ath9k_hw_post_attach(struct ath_hal *ah)
+static int ath9k_hw_post_attach(struct ath_hw *ah)
 {
 	int ecode;
 
@@ -643,6 +588,10 @@ static int ath9k_hw_post_attach(struct a
 	ecode = ath9k_hw_eeprom_attach(ah);
 	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));
+
 	ecode = ath9k_hw_rfattach(ah);
 	if (ecode != 0)
 		return ecode;
@@ -655,238 +604,229 @@ static int ath9k_hw_post_attach(struct a
 	return 0;
 }
 
-static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
-					  void __iomem *mem, int *status)
+static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+					 int *status)
 {
-	struct ath_hal_5416 *ahp;
-	struct ath_hal *ah;
+	struct ath_hw *ah;
 	int ecode;
 	u32 i, j;
 
-	ahp = ath9k_hw_newstate(devid, sc, mem, status);
-	if (ahp == NULL)
+	ah = ath9k_hw_newstate(devid, sc, status);
+	if (ah == NULL)
 		return NULL;
 
-	ah = &ahp->ah;
-
 	ath9k_hw_set_defaults(ah);
 
-	if (ah->ah_config.intr_mitigation != 0)
-		ahp->ah_intrMitigation = true;
+	if (ah->config.intr_mitigation != 0)
+		ah->intr_mitigation = true;
 
 	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n");
+		DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
 		ecode = -EIO;
 		goto bad;
 	}
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
+		DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
 		ecode = -EIO;
 		goto bad;
 	}
 
-	if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
-		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI ||
-		    (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) {
-			ah->ah_config.serialize_regmode =
+	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+			ah->config.serialize_regmode =
 				SER_REG_MODE_ON;
 		} else {
-			ah->ah_config.serialize_regmode =
+			ah->config.serialize_regmode =
 				SER_REG_MODE_OFF;
 		}
 	}
 
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-		"serialize_regmode is %d\n",
-		ah->ah_config.serialize_regmode);
+	DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+		ah->config.serialize_regmode);
 
-	if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
-	    (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
-	    (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
+	if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
+	    (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
+	    (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
 	    (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+		DPRINTF(sc, ATH_DBG_RESET,
 			"Mac Chip Rev 0x%02x.%x is not supported by "
-			"this driver\n", ah->ah_macVersion, ah->ah_macRev);
+			"this driver\n", ah->hw_version.macVersion,
+			ah->hw_version.macRev);
 		ecode = -EOPNOTSUPP;
 		goto bad;
 	}
 
 	if (AR_SREV_9100(ah)) {
-		ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
-		ahp->ah_suppCals = IQ_MISMATCH_CAL;
-		ah->ah_isPciExpress = false;
+		ah->iq_caldata.calData = &iq_cal_multi_sample;
+		ah->supp_cals = IQ_MISMATCH_CAL;
+		ah->is_pciexpress = false;
 	}
-	ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
 
 	if (AR_SREV_9160_10_OR_LATER(ah)) {
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			ahp->ah_iqCalData.calData = &iq_cal_single_sample;
-			ahp->ah_adcGainCalData.calData =
+			ah->iq_caldata.calData = &iq_cal_single_sample;
+			ah->adcgain_caldata.calData =
 				&adc_gain_cal_single_sample;
-			ahp->ah_adcDcCalData.calData =
+			ah->adcdc_caldata.calData =
 				&adc_dc_cal_single_sample;
-			ahp->ah_adcDcCalInitData.calData =
+			ah->adcdc_calinitdata.calData =
 				&adc_init_dc_cal;
 		} else {
-			ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
-			ahp->ah_adcGainCalData.calData =
+			ah->iq_caldata.calData = &iq_cal_multi_sample;
+			ah->adcgain_caldata.calData =
 				&adc_gain_cal_multi_sample;
-			ahp->ah_adcDcCalData.calData =
+			ah->adcdc_caldata.calData =
 				&adc_dc_cal_multi_sample;
-			ahp->ah_adcDcCalInitData.calData =
+			ah->adcdc_calinitdata.calData =
 				&adc_init_dc_cal;
 		}
-		ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
 	}
 
-	if (AR_SREV_9160(ah)) {
-		ah->ah_config.enable_ani = 1;
-		ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
-					ATH9K_ANI_FIRSTEP_LEVEL);
-	} else {
-		ahp->ah_ani_function = ATH9K_ANI_ALL;
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			ahp->ah_ani_function &=	~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-		}
-	}
+	ah->ani_function = ATH9K_ANI_ALL;
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+	DPRINTF(sc, ATH_DBG_RESET,
 		"This Mac Chip Rev 0x%02x.%x is \n",
-		ah->ah_macVersion, ah->ah_macRev);
+		ah->hw_version.macVersion, ah->hw_version.macRev);
 
 	if (AR_SREV_9285_12_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
+
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
 			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
 			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);
 
-		if (ah->ah_config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			ar9285PciePhy_clkreq_off_L1_9285_1_2,
 			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
 		} else {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
 			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
 				  2);
 		}
 	} else if (AR_SREV_9285_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
 			       ARRAY_SIZE(ar9285Modes_9285), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
 			       ARRAY_SIZE(ar9285Common_9285), 2);
 
-		if (ah->ah_config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			ar9285PciePhy_clkreq_off_L1_9285,
 			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
 		} else {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			ar9285PciePhy_clkreq_always_on_L1_9285,
 			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
 		}
 	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
 			       ARRAY_SIZE(ar9280Modes_9280_2), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
 			       ARRAY_SIZE(ar9280Common_9280_2), 2);
 
-		if (ah->ah_config.pcie_clock_req) {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+		if (ah->config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			       ar9280PciePhy_clkreq_off_L1_9280,
 			       ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
 		} else {
-			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			       ar9280PciePhy_clkreq_always_on_L1_9280,
 			       ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
 		}
-		INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
 			       ar9280Modes_fast_clock_9280_2,
 			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
 	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
 			       ARRAY_SIZE(ar9280Modes_9280), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
 			       ARRAY_SIZE(ar9280Common_9280), 2);
 	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
 			       ARRAY_SIZE(ar5416Modes_9160), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
 			       ARRAY_SIZE(ar5416Common_9160), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
 			       ARRAY_SIZE(ar5416Bank0_9160), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
 			       ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
 			       ARRAY_SIZE(ar5416Bank1_9160), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
 			       ARRAY_SIZE(ar5416Bank2_9160), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
 			       ARRAY_SIZE(ar5416Bank3_9160), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
 			       ARRAY_SIZE(ar5416Bank6_9160), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
 			       ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
 			       ARRAY_SIZE(ar5416Bank7_9160), 2);
 		if (AR_SREV_9160_11(ah)) {
-			INIT_INI_ARRAY(&ahp->ah_iniAddac,
+			INIT_INI_ARRAY(&ah->iniAddac,
 				       ar5416Addac_91601_1,
 				       ARRAY_SIZE(ar5416Addac_91601_1), 2);
 		} else {
-			INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
+			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
 				       ARRAY_SIZE(ar5416Addac_9160), 2);
 		}
 	} else if (AR_SREV_9100_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
 			       ARRAY_SIZE(ar5416Modes_9100), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
 			       ARRAY_SIZE(ar5416Common_9100), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
 			       ARRAY_SIZE(ar5416Bank0_9100), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
 			       ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
 			       ARRAY_SIZE(ar5416Bank1_9100), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
 			       ARRAY_SIZE(ar5416Bank2_9100), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
 			       ARRAY_SIZE(ar5416Bank3_9100), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
 			       ARRAY_SIZE(ar5416Bank6_9100), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
 			       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
 			       ARRAY_SIZE(ar5416Bank7_9100), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
 			       ARRAY_SIZE(ar5416Addac_9100), 2);
 	} else {
-		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
 			       ARRAY_SIZE(ar5416Modes), 6);
-		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
 			       ARRAY_SIZE(ar5416Common), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
 			       ARRAY_SIZE(ar5416Bank0), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
 			       ARRAY_SIZE(ar5416BB_RfGain), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
 			       ARRAY_SIZE(ar5416Bank1), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
 			       ARRAY_SIZE(ar5416Bank2), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
 			       ARRAY_SIZE(ar5416Bank3), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
 			       ARRAY_SIZE(ar5416Bank6), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
 			       ARRAY_SIZE(ar5416Bank6TPC), 3);
-		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
 			       ARRAY_SIZE(ar5416Bank7), 2);
-		INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
 			       ARRAY_SIZE(ar5416Addac), 2);
 	}
 
-	if (ah->ah_isPciExpress)
+	if (ah->is_pciexpress)
 		ath9k_hw_configpcipowersave(ah, 0);
 	else
 		ath9k_hw_disablepcie(ah);
@@ -895,6 +835,22 @@ static struct ath_hal *ath9k_hw_do_attac
 	if (ecode != 0)
 		goto bad;
 
+	if (AR_SREV_9285_12_OR_LATER(ah)) {
+		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+		/* txgain table */
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9285Modes_high_power_tx_gain_9285_1_2,
+			ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+		} else {
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9285Modes_original_tx_gain_9285_1_2,
+			ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
+		}
+
+	}
+
 	/* rxgain table */
 	if (AR_SREV_9280_20(ah))
 		ath9k_hw_init_rxgain_ini(ah);
@@ -903,53 +859,55 @@ static struct ath_hal *ath9k_hw_do_attac
 	if (AR_SREV_9280_20(ah))
 		ath9k_hw_init_txgain_ini(ah);
 
-	if (ah->ah_devid == AR9280_DEVID_PCI) {
-		for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
-			u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
+	if (!ath9k_hw_fill_cap_info(ah)) {
+		DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
+		ecode = -EINVAL;
+		goto bad;
+	}
 
-			for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
-				u32 val = INI_RA(&ahp->ah_iniModes, i, j);
+	if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+	    test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
 
-				INI_RA(&ahp->ah_iniModes, i, j) =
+		/* EEPROM Fixup */
+		for (i = 0; i < ah->iniModes.ia_rows; i++) {
+			u32 reg = INI_RA(&ah->iniModes, i, 0);
+
+			for (j = 1; j < ah->iniModes.ia_columns; j++) {
+				u32 val = INI_RA(&ah->iniModes, i, j);
+
+				INI_RA(&ah->iniModes, i, j) =
 					ath9k_hw_ini_fixup(ah,
-							   &ahp->ah_eeprom.def,
+							   &ah->eeprom.def,
 							   reg, val);
 			}
 		}
 	}
 
-	if (!ath9k_hw_fill_cap_info(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-			"failed ath9k_hw_fill_cap_info\n");
-		ecode = -EINVAL;
-		goto bad;
-	}
-
 	ecode = ath9k_hw_init_macaddr(ah);
 	if (ecode != 0) {
-		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+		DPRINTF(sc, ATH_DBG_RESET,
 			"failed initializing mac address\n");
 		goto bad;
 	}
 
 	if (AR_SREV_9285(ah))
-		ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
+		ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
 	else
-		ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
+		ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
 
 	ath9k_init_nfcal_hist_buffer(ah);
 
 	return ah;
 bad:
-	if (ahp)
-		ath9k_hw_detach((struct ath_hal *) ahp);
+	if (ah)
+		ath9k_hw_detach(ah);
 	if (status)
 		*status = ecode;
 
 	return NULL;
 }
 
-static void ath9k_hw_init_bb(struct ath_hal *ah,
+static void ath9k_hw_init_bb(struct ath_hw *ah,
 			     struct ath9k_channel *chan)
 {
 	u32 synthDelay;
@@ -965,7 +923,7 @@ static void ath9k_hw_init_bb(struct ath_
 	udelay(synthDelay + BASE_ACTIVATE_DELAY);
 }
 
-static void ath9k_hw_init_qos(struct ath_hal *ah)
+static void ath9k_hw_init_qos(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
 	REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
@@ -982,7 +940,7 @@ static void ath9k_hw_init_qos(struct ath
 	REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
 }
 
-static void ath9k_hw_init_pll(struct ath_hal *ah,
+static void ath9k_hw_init_pll(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
 	u32 pll;
@@ -1043,27 +1001,26 @@ static void ath9k_hw_init_pll(struct ath
 				pll |= SM(0xb, AR_RTC_PLL_DIV);
 		}
 	}
-	REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
+	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
 	udelay(RTC_PLL_SETTLE_DELAY);
 
 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
 }
 
-static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
+static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int rx_chainmask, tx_chainmask;
 
-	rx_chainmask = ahp->ah_rxchainmask;
-	tx_chainmask = ahp->ah_txchainmask;
+	rx_chainmask = ah->rxchainmask;
+	tx_chainmask = ah->txchainmask;
 
 	switch (rx_chainmask) {
 	case 0x5:
 		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
 			    AR_PHY_SWAP_ALT_CHAIN);
 	case 0x3:
-		if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
+		if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
 			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
 			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
 			break;
@@ -1088,28 +1045,26 @@ static void ath9k_hw_init_chain_masks(st
 			  REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
 }
 
-static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
+static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 					  enum nl80211_iftype opmode)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	ahp->ah_maskReg = AR_IMR_TXERR |
+	ah->mask_reg = AR_IMR_TXERR |
 		AR_IMR_TXURN |
 		AR_IMR_RXERR |
 		AR_IMR_RXORN |
 		AR_IMR_BCNMISC;
 
-	if (ahp->ah_intrMitigation)
-		ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+	if (ah->intr_mitigation)
+		ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
 	else
-		ahp->ah_maskReg |= AR_IMR_RXOK;
+		ah->mask_reg |= AR_IMR_RXOK;
 
-	ahp->ah_maskReg |= AR_IMR_TXOK;
+	ah->mask_reg |= AR_IMR_TXOK;
 
 	if (opmode == NL80211_IFTYPE_AP)
-		ahp->ah_maskReg |= AR_IMR_MIB;
+		ah->mask_reg |= AR_IMR_MIB;
 
-	REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+	REG_WRITE(ah, AR_IMR, ah->mask_reg);
 	REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
 
 	if (!AR_SREV_9100(ah)) {
@@ -1119,72 +1074,64 @@ static void ath9k_hw_init_interrupt_mask
 	}
 }
 
-static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	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);
-		ahp->ah_acktimeout = (u32) -1;
+		ah->acktimeout = (u32) -1;
 		return false;
 	} else {
 		REG_RMW_FIELD(ah, AR_TIME_OUT,
 			      AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
-		ahp->ah_acktimeout = us;
+		ah->acktimeout = us;
 		return true;
 	}
 }
 
-static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	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);
-		ahp->ah_ctstimeout = (u32) -1;
+		ah->ctstimeout = (u32) -1;
 		return false;
 	} else {
 		REG_RMW_FIELD(ah, AR_TIME_OUT,
 			      AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
-		ahp->ah_ctstimeout = us;
+		ah->ctstimeout = us;
 		return true;
 	}
 }
 
-static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu)
+static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	if (tu > 0xFFFF) {
 		DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
 			"bad global tx timeout %u\n", tu);
-		ahp->ah_globaltxtimeout = (u32) -1;
+		ah->globaltxtimeout = (u32) -1;
 		return false;
 	} else {
 		REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
-		ahp->ah_globaltxtimeout = tu;
+		ah->globaltxtimeout = tu;
 		return true;
 	}
 }
 
-static void ath9k_hw_init_user_settings(struct ath_hal *ah)
+static void ath9k_hw_init_user_settings(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n",
-		ahp->ah_miscMode);
+	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+		ah->misc_mode);
 
-	if (ahp->ah_miscMode != 0)
+	if (ah->misc_mode != 0)
 		REG_WRITE(ah, AR_PCU_MISC,
-			  REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
-	if (ahp->ah_slottime != (u32) -1)
-		ath9k_hw_setslottime(ah, ahp->ah_slottime);
-	if (ahp->ah_acktimeout != (u32) -1)
-		ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
-	if (ahp->ah_ctstimeout != (u32) -1)
-		ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
-	if (ahp->ah_globaltxtimeout != (u32) -1)
-		ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
+			  REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+	if (ah->slottime != (u32) -1)
+		ath9k_hw_setslottime(ah, ah->slottime);
+	if (ah->acktimeout != (u32) -1)
+		ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+	if (ah->ctstimeout != (u32) -1)
+		ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+	if (ah->globaltxtimeout != (u32) -1)
+		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
 }
 
 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
@@ -1193,7 +1140,7 @@ const char *ath9k_hw_probe(u16 vendorid,
 		ath9k_hw_devname(devid) : NULL;
 }
 
-void ath9k_hw_detach(struct ath_hal *ah)
+void ath9k_hw_detach(struct ath_hw *ah)
 {
 	if (!AR_SREV_9100(ah))
 		ath9k_hw_ani_detach(ah);
@@ -1203,19 +1150,19 @@ void ath9k_hw_detach(struct ath_hal *ah)
 	kfree(ah);
 }
 
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
-				void __iomem *mem, int *error)
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
 {
-	struct ath_hal *ah = NULL;
+	struct ath_hw *ah = NULL;
 
 	switch (devid) {
 	case AR5416_DEVID_PCI:
 	case AR5416_DEVID_PCIE:
+	case AR5416_AR9100_DEVID:
 	case AR9160_DEVID_PCI:
 	case AR9280_DEVID_PCI:
 	case AR9280_DEVID_PCIE:
 	case AR9285_DEVID_PCIE:
-		ah = ath9k_hw_do_attach(devid, sc, mem, error);
+		ah = ath9k_hw_do_attach(devid, sc, error);
 		break;
 	default:
 		*error = -ENXIO;
@@ -1229,7 +1176,7 @@ struct ath_hal *ath9k_hw_attach(u16 devi
 /* INI */
 /*******/
 
-static void ath9k_hw_override_ini(struct ath_hal *ah,
+static void ath9k_hw_override_ini(struct ath_hw *ah,
 				  struct ath9k_channel *chan)
 {
 	/*
@@ -1240,20 +1187,20 @@ static void ath9k_hw_override_ini(struct
 	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
 
-	if (!AR_SREV_5416_V20_OR_LATER(ah) ||
+	if (!AR_SREV_5416_20_OR_LATER(ah) ||
 	    AR_SREV_9280_10_OR_LATER(ah))
 		return;
 
 	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
 }
 
-static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
 			      struct ar5416_eeprom_def *pEepData,
 			      u32 reg, u32 value)
 {
 	struct base_eep_header *pBase = &(pEepData->baseEepHeader);
 
-	switch (ah->ah_devid) {
+	switch (ah->hw_version.devid) {
 	case AR9280_DEVID_PCI:
 		if (reg == 0x7894) {
 			DPRINTF(ah->ah_sc, ATH_DBG_ANY,
@@ -1281,24 +1228,33 @@ static u32 ath9k_hw_def_ini_fixup(struct
 	return value;
 }
 
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
 			      struct ar5416_eeprom_def *pEepData,
 			      u32 reg, u32 value)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+	if (ah->eep_map == EEP_MAP_4KBITS)
 		return value;
 	else
 		return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
 }
 
-static int ath9k_hw_process_ini(struct ath_hal *ah,
+static void ath9k_olc_init(struct ath_hw *ah)
+{
+	u32 i;
+
+	for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+		ah->originalGain[i] =
+			MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+					AR_PHY_TX_GAIN);
+	ah->PDADCdelta = 0;
+}
+
+static int ath9k_hw_process_ini(struct ath_hw *ah,
 				struct ath9k_channel *chan,
 				enum ath9k_ht_macmode macmode)
 {
 	int i, regWrites = 0;
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ieee80211_channel *channel = chan->chan;
 	u32 modesIndex, freqIndex;
 	int status;
 
@@ -1330,40 +1286,38 @@ static int ath9k_hw_process_ini(struct a
 	}
 
 	REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
 	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+	ah->eep_ops->set_addac(ah, chan);
 
-	ath9k_hw_set_addac(ah, chan);
-
-	if (AR_SREV_5416_V22_OR_LATER(ah)) {
-		REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
+	if (AR_SREV_5416_22_OR_LATER(ah)) {
+		REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
 	} else {
 		struct ar5416IniArray temp;
 		u32 addacSize =
-			sizeof(u32) * ahp->ah_iniAddac.ia_rows *
-			ahp->ah_iniAddac.ia_columns;
+			sizeof(u32) * ah->iniAddac.ia_rows *
+			ah->iniAddac.ia_columns;
 
-		memcpy(ahp->ah_addac5416_21,
-		       ahp->ah_iniAddac.ia_array, addacSize);
+		memcpy(ah->addac5416_21,
+		       ah->iniAddac.ia_array, addacSize);
 
-		(ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
+		(ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
 
-		temp.ia_array = ahp->ah_addac5416_21;
-		temp.ia_columns = ahp->ah_iniAddac.ia_columns;
-		temp.ia_rows = ahp->ah_iniAddac.ia_rows;
+		temp.ia_array = ah->addac5416_21;
+		temp.ia_columns = ah->iniAddac.ia_columns;
+		temp.ia_rows = ah->iniAddac.ia_rows;
 		REG_WRITE_ARRAY(&temp, 1, regWrites);
 	}
 
 	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
 
-	for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
-		u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
-		u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
+	for (i = 0; i < ah->iniModes.ia_rows; i++) {
+		u32 reg = INI_RA(&ah->iniModes, i, 0);
+		u32 val = INI_RA(&ah->iniModes, i, modesIndex);
 
 		REG_WRITE(ah, reg, val);
 
 		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->ah_config.analog_shiftreg) {
+		    && ah->config.analog_shiftreg) {
 			udelay(100);
 		}
 
@@ -1371,19 +1325,20 @@ static int ath9k_hw_process_ini(struct a
 	}
 
 	if (AR_SREV_9280(ah))
-		REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites);
+		REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
 
-	if (AR_SREV_9280(ah))
-		REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
+	if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
+	    AR_SREV_9285_12_OR_LATER(ah)))
+		REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
 
-	for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
-		u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
-		u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
+	for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+		u32 reg = INI_RA(&ah->iniCommon, i, 0);
+		u32 val = INI_RA(&ah->iniCommon, i, 1);
 
 		REG_WRITE(ah, reg, val);
 
 		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->ah_config.analog_shiftreg) {
+		    && ah->config.analog_shiftreg) {
 			udelay(100);
 		}
 
@@ -1393,7 +1348,7 @@ static int ath9k_hw_process_ini(struct a
 	ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
 
 	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
-		REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
+		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
 				regWrites);
 	}
 
@@ -1401,13 +1356,15 @@ static int ath9k_hw_process_ini(struct a
 	ath9k_hw_set_regs(ah, chan, macmode);
 	ath9k_hw_init_chain_masks(ah);
 
-	status = ath9k_hw_set_txpower(ah, chan,
-				      ath9k_regd_get_ctl(ah, chan),
-				      ath9k_regd_get_antenna_allowed(ah,
-								     chan),
-				      chan->maxRegTxPower * 2,
-				      min((u32) MAX_RATE_POWER,
-					  (u32) ah->ah_powerLimit));
+	if (OLC_FOR_AR9280_20_LATER)
+		ath9k_olc_init(ah);
+
+	status = ah->eep_ops->set_txpower(ah, chan,
+				  ath9k_regd_get_ctl(ah, chan),
+				  channel->max_antenna_gain * 2,
+				  channel->max_power * 2,
+				  min((u32) MAX_RATE_POWER,
+				      (u32) ah->regulatory.power_limit));
 	if (status != 0) {
 		DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
 			"error init'ing transmit power\n");
@@ -1427,7 +1384,7 @@ static int ath9k_hw_process_ini(struct a
 /* Reset and Channel Switching Routines */
 /****************************************/
 
-static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u32 rfMode = 0;
 
@@ -1447,12 +1404,12 @@ static void ath9k_hw_set_rfmode(struct a
 	REG_WRITE(ah, AR_PHY_MODE, rfMode);
 }
 
-static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
+static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
 }
 
-static inline void ath9k_hw_set_dma(struct ath_hal *ah)
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
 	u32 regval;
 
@@ -1462,7 +1419,7 @@ static inline void ath9k_hw_set_dma(stru
 	regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
 	REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
 
-	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
 
 	regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
 	REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
@@ -1478,7 +1435,7 @@ static inline void ath9k_hw_set_dma(stru
 	}
 }
 
-static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
+static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 {
 	u32 val;
 
@@ -1491,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(
 		REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
 		break;
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
 		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
 			  | AR_STA_ID1_KSRCH_MODE);
 		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
@@ -1502,7 +1460,7 @@ static void ath9k_hw_set_operating_mode(
 	}
 }
 
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
 						 u32 coef_scaled,
 						 u32 *coef_mantissa,
 						 u32 *coef_exponent)
@@ -1521,7 +1479,7 @@ static inline void ath9k_hw_get_delta_sl
 	*coef_exponent = coef_exp - 16;
 }
 
-static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
+static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
 				     struct ath9k_channel *chan)
 {
 	u32 coef_scaled, ds_coef_exp, ds_coef_man;
@@ -1555,11 +1513,19 @@ static void ath9k_hw_set_delta_slope(str
 		      AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
 }
 
-static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
+static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
 {
 	u32 rst_flags;
 	u32 tmpReg;
 
+	if (AR_SREV_9100(ah)) {
+		u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
+		val &= ~AR_RTC_DERIVED_CLK_PERIOD;
+		val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
+		REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+		(void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+	}
+
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
 		  AR_RTC_FORCE_WAKE_ON_INT);
 
@@ -1582,11 +1548,11 @@ static bool ath9k_hw_set_reset(struct at
 			rst_flags |= AR_RTC_RC_MAC_COLD;
 	}
 
-	REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
+	REG_WRITE(ah, AR_RTC_RC, rst_flags);
 	udelay(50);
 
-	REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
-	if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+	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");
 		return false;
@@ -1603,18 +1569,20 @@ static bool ath9k_hw_set_reset(struct at
 	return true;
 }
 
-static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
 		  AR_RTC_FORCE_WAKE_ON_INT);
 
-	REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
-	REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+	REG_WRITE(ah, AR_RTC_RESET, 0);
+	udelay(2);
+	REG_WRITE(ah, AR_RTC_RESET, 1);
 
 	if (!ath9k_hw_wait(ah,
 			   AR_RTC_STATUS,
 			   AR_RTC_STATUS_M,
-			   AR_RTC_STATUS_ON)) {
+			   AR_RTC_STATUS_ON,
+			   AH_WAIT_TIMEOUT)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
 		return false;
 	}
@@ -1624,7 +1592,7 @@ static bool ath9k_hw_set_reset_power_on(
 	return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
 }
 
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
 {
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE,
 		  AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
@@ -1642,12 +1610,11 @@ static bool ath9k_hw_set_reset_reg(struc
 	}
 }
 
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 			      enum ath9k_ht_macmode macmode)
 {
 	u32 phymode;
 	u32 enableDacFifo = 0;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
 	if (AR_SREV_9285_10_OR_LATER(ah))
 		enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
@@ -1663,7 +1630,7 @@ static void ath9k_hw_set_regs(struct ath
 		    (chan->chanmode == CHANNEL_G_HT40PLUS))
 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
-		if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+		if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
 			phymode |= AR_PHY_FC_DYN2040_EXT_CH;
 	}
 	REG_WRITE(ah, AR_PHY_TURBO, phymode);
@@ -1674,54 +1641,30 @@ static void ath9k_hw_set_regs(struct ath
 	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
 }
 
-static bool ath9k_hw_chip_reset(struct ath_hal *ah,
+static bool ath9k_hw_chip_reset(struct ath_hw *ah,
 				struct ath9k_channel *chan)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+	if (OLC_FOR_AR9280_20_LATER) {
+		if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+			return false;
+	} else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
 		return false;
 
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return false;
 
-	ahp->ah_chipFullSleep = false;
-
+	ah->chip_fullsleep = false;
 	ath9k_hw_init_pll(ah, chan);
-
 	ath9k_hw_set_rfmode(ah, chan);
 
 	return true;
 }
 
-static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
-						 struct ath9k_channel *chan)
-{
-	if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-			"invalid channel %u/0x%x; not marked as "
-			"2GHz or 5GHz\n", chan->channel, chan->channelFlags);
-		return NULL;
-	}
-
-	if (!IS_CHAN_OFDM(chan) &&
-	    !IS_CHAN_B(chan) &&
-	    !IS_CHAN_HT20(chan) &&
-	    !IS_CHAN_HT40(chan)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-			"invalid channel %u/0x%x; not marked as "
-			"OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
-			chan->channel, chan->channelFlags);
-		return NULL;
-	}
-
-	return ath9k_regd_check_channel(ah, chan);
-}
-
-static bool ath9k_hw_channel_change(struct ath_hal *ah,
+static bool ath9k_hw_channel_change(struct ath_hw *ah,
 				    struct ath9k_channel *chan,
 				    enum ath9k_ht_macmode macmode)
 {
+	struct ieee80211_channel *channel = chan->chan;
 	u32 synthDelay, qnum;
 
 	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1734,7 +1677,7 @@ 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)) {
+			   AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
 			"Could not kill baseband RX\n");
 		return false;
@@ -1756,12 +1699,12 @@ static bool ath9k_hw_channel_change(stru
 		}
 	}
 
-	if (ath9k_hw_set_txpower(ah, chan,
-				 ath9k_regd_get_ctl(ah, chan),
-				 ath9k_regd_get_antenna_allowed(ah, chan),
-				 chan->maxRegTxPower * 2,
-				 min((u32) MAX_RATE_POWER,
-				     (u32) ah->ah_powerLimit)) != 0) {
+	if (ah->eep_ops->set_txpower(ah, chan,
+			     ath9k_regd_get_ctl(ah, chan),
+			     channel->max_antenna_gain * 2,
+			     channel->max_power * 2,
+			     min((u32) MAX_RATE_POWER,
+				 (u32) ah->regulatory.power_limit)) != 0) {
 		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
 			"error init'ing transmit power\n");
 		return false;
@@ -1791,7 +1734,7 @@ static bool ath9k_hw_channel_change(stru
 	return true;
 }
 
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	int bb_spur = AR_NO_SPUR;
 	int freq;
@@ -1825,9 +1768,9 @@ static void ath9k_hw_9280_spur_mitigate(
 	ath9k_hw_get_channel_centers(ah, chan, &centers);
 	freq = centers.synth_center;
 
-	ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
+	ah->config.spurmode = SPUR_ENABLE_EEPROM;
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+		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;
@@ -1938,9 +1881,9 @@ static void ath9k_hw_9280_spur_mitigate(
 		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
 
 			/* workaround for gcc bug #37014 */
-			volatile int tmp = abs(cur_vit_mask - bin);
+			volatile int tmp_v = abs(cur_vit_mask - bin);
 
-			if (tmp < 75)
+			if (tmp_v < 75)
 				mask_amt = 1;
 			else
 				mask_amt = 0;
@@ -2041,7 +1984,7 @@ static void ath9k_hw_9280_spur_mitigate(
 	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
 }
 
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	int bb_spur = AR_NO_SPUR;
 	int bin, cur_bin;
@@ -2070,7 +2013,7 @@ static void ath9k_hw_spur_mitigate(struc
 	memset(&mask_p, 0, sizeof(int8_t) * 123);
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+		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);
@@ -2139,9 +2082,9 @@ static void ath9k_hw_spur_mitigate(struc
 		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
 
 			/* workaround for gcc bug #37014 */
-			volatile int tmp = abs(cur_vit_mask - bin);
+			volatile int tmp_v = abs(cur_vit_mask - bin);
 
-			if (tmp < 75)
+			if (tmp_v < 75)
 				mask_amt = 1;
 			else
 				mask_amt = 0;
@@ -2242,58 +2185,47 @@ static void ath9k_hw_spur_mitigate(struc
 	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
 }
 
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
-		    enum ath9k_ht_macmode macmode,
-		    u8 txchainmask, u8 rxchainmask,
-		    enum ath9k_ht_extprotspacing extprotspacing,
-		    bool bChannelChange, int *status)
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+		    bool bChannelChange)
 {
 	u32 saveLedState;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_channel *curchan = ah->ah_curchan;
+	struct ath_softc *sc = ah->ah_sc;
+	struct ath9k_channel *curchan = ah->curchan;
 	u32 saveDefAntenna;
 	u32 macStaId1;
-	int ecode;
-	int i, rx_chainmask;
-
-	ahp->ah_extprotspacing = extprotspacing;
-	ahp->ah_txchainmask = txchainmask;
-	ahp->ah_rxchainmask = rxchainmask;
+	int i, rx_chainmask, r;
 
-	if (AR_SREV_9280(ah)) {
-		ahp->ah_txchainmask &= 0x3;
-		ahp->ah_rxchainmask &= 0x3;
-	}
+	ah->extprotspacing = sc->ht_extprotspacing;
+	ah->txchainmask = sc->tx_chainmask;
+	ah->rxchainmask = sc->rx_chainmask;
 
-	if (ath9k_hw_check_chan(ah, chan) == NULL) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-			"invalid channel %u/0x%x; no mapping\n",
-			chan->channel, chan->channelFlags);
-		ecode = -EINVAL;
-		goto bad;
+	if (AR_SREV_9285(ah)) {
+		ah->txchainmask &= 0x1;
+		ah->rxchainmask &= 0x1;
+	} else if (AR_SREV_9280(ah)) {
+		ah->txchainmask &= 0x3;
+		ah->rxchainmask &= 0x3;
 	}
 
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-		ecode = -EIO;
-		goto bad;
-	}
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+		return -EIO;
 
 	if (curchan)
 		ath9k_hw_getnf(ah, curchan);
 
 	if (bChannelChange &&
-	    (ahp->ah_chipFullSleep != true) &&
-	    (ah->ah_curchan != NULL) &&
-	    (chan->channel != ah->ah_curchan->channel) &&
+	    (ah->chip_fullsleep != true) &&
+	    (ah->curchan != NULL) &&
+	    (chan->channel != ah->curchan->channel) &&
 	    ((chan->channelFlags & CHANNEL_ALL) ==
-	     (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
+	     (ah->curchan->channelFlags & CHANNEL_ALL)) &&
 	    (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
-				   !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
+				   !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
 
-		if (ath9k_hw_channel_change(ah, chan, macmode)) {
-			ath9k_hw_loadnf(ah, ah->ah_curchan);
+		if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+			ath9k_hw_loadnf(ah, ah->curchan);
 			ath9k_hw_start_nfcal(ah);
-			return true;
+			return 0;
 		}
 	}
 
@@ -2311,28 +2243,32 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
 	if (!ath9k_hw_chip_reset(ah, chan)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
-		ecode = -EINVAL;
-		goto bad;
+		return -EINVAL;
 	}
 
-	if (AR_SREV_9280(ah)) {
-		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-			    AR_GPIO_JTAG_DISABLE);
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
-		if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
-			if (IS_CHAN_5GHZ(chan))
-				ath9k_hw_set_gpio(ah, 9, 0);
-			else
-				ath9k_hw_set_gpio(ah, 9, 1);
-		}
-		ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-	}
+	r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+	if (r)
+		return r;
 
-	ecode = ath9k_hw_process_ini(ah, chan, macmode);
-	if (ecode != 0) {
-		ecode = -EINVAL;
-		goto bad;
-	}
+	/* Setup MFP options for CCMP */
+	if (AR_SREV_9280_20_OR_LATER(ah)) {
+		/* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+		 * frames when constructing CCMP AAD. */
+		REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+			      0xc7ff);
+		ah->sw_mgmt_crypto = false;
+	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
+		/* Disable hardware crypto for management frames */
+		REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+			    AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+			    AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+		ah->sw_mgmt_crypto = true;
+	} else
+		ah->sw_mgmt_crypto = true;
 
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
@@ -2342,61 +2278,52 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 	else
 		ath9k_hw_spur_mitigate(ah, chan);
 
-	if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"error setting board options\n");
-		ecode = -EIO;
-		goto bad;
-	}
+	ah->eep_ops->set_board_values(ah, chan);
 
 	ath9k_hw_decrease_chain_power(ah, chan);
 
-	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
-	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
+	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
+	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
 		  | macStaId1
 		  | AR_STA_ID1_RTS_USE_DEF
-		  | (ah->ah_config.
+		  | (ah->config.
 		     ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
-		  | ahp->ah_staId1Defaults);
-	ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+		  | ah->sta_id1_defaults);
+	ath9k_hw_set_operating_mode(ah, ah->opmode);
 
-	REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
-	REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
+	REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+	REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
 
 	REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
 
-	REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
-	REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
-		  ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+	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));
 
 	REG_WRITE(ah, AR_ISR, ~0);
 
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
-			ecode = -EIO;
-			goto bad;
-		}
+		if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
+			return -EIO;
 	} else {
-		if (!(ath9k_hw_set_channel(ah, chan))) {
-			ecode = -EIO;
-			goto bad;
-		}
+		if (!(ath9k_hw_set_channel(ah, chan)))
+			return -EIO;
 	}
 
 	for (i = 0; i < AR_NUM_DCU; i++)
 		REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
 
-	ahp->ah_intrTxqs = 0;
-	for (i = 0; i < ah->ah_caps.total_queues; i++)
+	ah->intr_txqs = 0;
+	for (i = 0; i < ah->caps.total_queues; i++)
 		ath9k_hw_resettxqueue(ah, i);
 
-	ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
+	ath9k_hw_init_interrupt_masks(ah, ah->opmode);
 	ath9k_hw_init_qos(ah);
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		ath9k_enable_rfkill(ah);
 #endif
 	ath9k_hw_init_user_settings(ah);
@@ -2408,7 +2335,7 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
 	REG_WRITE(ah, AR_OBS, 8);
 
-	if (ahp->ah_intrMitigation) {
+	if (ah->intr_mitigation) {
 
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
@@ -2416,12 +2343,10 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
 	ath9k_hw_init_bb(ah, chan);
 
-	if (!ath9k_hw_init_cal(ah, chan)){
-		ecode = -EIO;;
-		goto bad;
-	}
+	if (!ath9k_hw_init_cal(ah, chan))
+		return -EIO;;
 
-	rx_chainmask = ahp->ah_rxchainmask;
+	rx_chainmask = ah->rxchainmask;
 	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
 		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
 		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
@@ -2448,22 +2373,18 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 #endif
 	}
 
-	return true;
-bad:
-	if (status)
-		*status = ecode;
-	return false;
+	return 0;
 }
 
 /************************/
 /* Key Cache Management */
 /************************/
 
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
 {
 	u32 keyType;
 
-	if (entry >= ah->ah_caps.keycache_size) {
+	if (entry >= ah->caps.keycache_size) {
 		DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
 			"entry %u out of range\n", entry);
 		return false;
@@ -2490,17 +2411,17 @@ bool ath9k_hw_keyreset(struct ath_hal *a
 
 	}
 
-	if (ah->ah_curchan == NULL)
+	if (ah->curchan == NULL)
 		return true;
 
 	return true;
 }
 
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
 {
 	u32 macHi, macLo;
 
-	if (entry >= ah->ah_caps.keycache_size) {
+	if (entry >= ah->caps.keycache_size) {
 		DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
 			"entry %u out of range\n", entry);
 		return false;
@@ -2524,17 +2445,13 @@ bool ath9k_hw_keysetmac(struct ath_hal *
 	return true;
 }
 
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
 				 const struct ath9k_keyval *k,
-				 const u8 *mac, int xorKey)
+				 const u8 *mac)
 {
-	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	const struct ath9k_hw_capabilities *pCap = &ah->caps;
 	u32 key0, key1, key2, key3, key4;
 	u32 keyType;
-	u32 xorMask = xorKey ?
-		(ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
-		 | ATH9K_KEY_XOR) : 0;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
 	if (entry >= pCap->keycache_size) {
 		DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
@@ -2550,7 +2467,7 @@ bool ath9k_hw_set_keycache_entry(struct
 		if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
 			DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
 				"AES-CCM not supported by mac rev 0x%x\n",
-				ah->ah_macRev);
+				ah->hw_version.macRev);
 			return false;
 		}
 		keyType = AR_KEYTABLE_TYPE_CCM;
@@ -2586,26 +2503,57 @@ bool ath9k_hw_set_keycache_entry(struct
 		return false;
 	}
 
-	key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
-	key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
-	key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
-	key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
-	key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
+	key0 = get_unaligned_le32(k->kv_val + 0);
+	key1 = get_unaligned_le16(k->kv_val + 4);
+	key2 = get_unaligned_le32(k->kv_val + 6);
+	key3 = get_unaligned_le16(k->kv_val + 10);
+	key4 = get_unaligned_le32(k->kv_val + 12);
 	if (k->kv_len <= LEN_WEP104)
 		key4 &= 0xff;
 
+	/*
+	 * Note: Key cache registers access special memory area that requires
+	 * two 32-bit writes to actually update the values in the internal
+	 * memory. Consequently, the exact order and pairs used here must be
+	 * maintained.
+	 */
+
 	if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
 		u16 micentry = entry + 64;
 
+		/*
+		 * Write inverted key[47:0] first to avoid Michael MIC errors
+		 * on frames that could be sent or received at the same time.
+		 * The correct key will be written in the end once everything
+		 * else is ready.
+		 */
 		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
 		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+		/* Write key[95:48] */
 		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
 		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+		/* Write key[127:96] and key type */
 		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
 		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+		/* Write MAC address for the entry */
 		(void) ath9k_hw_keysetmac(ah, entry, mac);
 
-		if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+		if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
+			/*
+			 * TKIP uses two key cache entries:
+			 * Michael MIC TX/RX keys in the same key cache entry
+			 * (idx = main index + 64):
+			 * key0 [31:0] = RX key [31:0]
+			 * key1 [15:0] = TX key [31:16]
+			 * key1 [31:16] = reserved
+			 * key2 [31:0] = RX key [63:32]
+			 * key3 [15:0] = TX key [15:0]
+			 * key3 [31:16] = reserved
+			 * key4 [31:0] = TX key [63:32]
+			 */
 			u32 mic0, mic1, mic2, mic3, mic4;
 
 			mic0 = get_unaligned_le32(k->kv_mic + 0);
@@ -2613,51 +2561,90 @@ bool ath9k_hw_set_keycache_entry(struct
 			mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
 			mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
 			mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+			/* Write RX[31:0] and TX[31:16] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
 			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+			/* Write RX[63:32] and TX[15:0] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
 			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+			/* Write TX[63:32] and keyType(reserved) */
 			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
 			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
 				  AR_KEYTABLE_TYPE_CLR);
 
 		} else {
+			/*
+			 * TKIP uses four key cache entries (two for group
+			 * keys):
+			 * Michael MIC TX/RX keys are in different key cache
+			 * entries (idx = main index + 64 for TX and
+			 * main index + 32 + 96 for RX):
+			 * key0 [31:0] = TX/RX MIC key [31:0]
+			 * key1 [31:0] = reserved
+			 * key2 [31:0] = TX/RX MIC key [63:32]
+			 * key3 [31:0] = reserved
+			 * key4 [31:0] = reserved
+			 *
+			 * Upper layer code will call this function separately
+			 * for TX and RX keys when these registers offsets are
+			 * used.
+			 */
 			u32 mic0, mic2;
 
 			mic0 = get_unaligned_le32(k->kv_mic + 0);
 			mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+			/* Write MIC key[31:0] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
 			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+			/* Write MIC key[63:32] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
 			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+			/* Write TX[63:32] and keyType(reserved) */
 			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
 			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
 				  AR_KEYTABLE_TYPE_CLR);
 		}
+
+		/* MAC address registers are reserved for the MIC entry */
 		REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
 		REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+		/*
+		 * Write the correct (un-inverted) key[47:0] last to enable
+		 * TKIP now that all other registers are set with correct
+		 * values.
+		 */
 		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
 		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
 	} else {
+		/* Write key[47:0] */
 		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
 		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+		/* Write key[95:48] */
 		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
 		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+		/* Write key[127:96] and key type */
 		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
 		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
 
+		/* Write MAC address for the entry */
 		(void) ath9k_hw_keysetmac(ah, entry, mac);
 	}
 
-	if (ah->ah_curchan == NULL)
-		return true;
-
 	return true;
 }
 
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
 {
-	if (entry < ah->ah_caps.keycache_size) {
+	if (entry < ah->caps.keycache_size) {
 		u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
 		if (val & AR_KEYTABLE_VALID)
 			return true;
@@ -2669,7 +2656,7 @@ bool ath9k_hw_keyisvalid(struct ath_hal
 /* Power Management (Chipset) */
 /******************************/
 
-static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
 {
 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
 	if (setChip) {
@@ -2678,16 +2665,16 @@ 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, (u16) (AR_RTC_RESET),
+		REG_CLR_BIT(ah, (AR_RTC_RESET),
 			    AR_RTC_RESET_EN);
 	}
 }
 
-static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
 {
 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
 	if (setChip) {
-		struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+		struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
 			REG_WRITE(ah, AR_RTC_FORCE_WAKE,
@@ -2699,8 +2686,7 @@ static void ath9k_set_power_network_slee
 	}
 }
 
-static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
-				     int setChip)
+static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 {
 	u32 val;
 	int i;
@@ -2741,20 +2727,18 @@ static bool ath9k_hw_set_power_awake(str
 	return true;
 }
 
-bool ath9k_hw_setpower(struct ath_hal *ah,
-		       enum ath9k_power_mode mode)
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
+	int status = true, setChip = true;
 	static const char *modes[] = {
 		"AWAKE",
 		"FULL-SLEEP",
 		"NETWORK SLEEP",
 		"UNDEFINED"
 	};
-	int status = true, setChip = true;
 
 	DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
-		modes[ahp->ah_powerMode], modes[mode],
+		modes[ah->power_mode], modes[mode],
 		setChip ? "set chip " : "");
 
 	switch (mode) {
@@ -2763,7 +2747,7 @@ bool ath9k_hw_setpower(struct ath_hal *a
 		break;
 	case ATH9K_PM_FULL_SLEEP:
 		ath9k_set_power_sleep(ah, setChip);
-		ahp->ah_chipFullSleep = true;
+		ah->chip_fullsleep = true;
 		break;
 	case ATH9K_PM_NETWORK_SLEEP:
 		ath9k_set_power_network_sleep(ah, setChip);
@@ -2773,41 +2757,57 @@ bool ath9k_hw_setpower(struct ath_hal *a
 			"Unknown power mode %u\n", mode);
 		return false;
 	}
-	ahp->ah_powerMode = mode;
+	ah->power_mode = mode;
 
 	return status;
 }
 
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u8 i;
 
-	if (ah->ah_isPciExpress != true)
+	if (ah->is_pciexpress != true)
 		return;
 
-	if (ah->ah_config.pcie_powersave_enable == 2)
+	/* Do not touch SerDes registers */
+	if (ah->config.pcie_powersave_enable == 2)
 		return;
 
+	/* Nothing to do on restore for 11N */
 	if (restore)
 		return;
 
 	if (AR_SREV_9280_20_OR_LATER(ah)) {
-		for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
-			REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
-				  INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
+		/*
+		 * AR9280 2.0 or later chips use SerDes values from the
+		 * initvals.h initialized depending on chipset during
+		 * ath9k_hw_do_attach()
+		 */
+		for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+			REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+				  INI_RA(&ah->iniPcieSerdes, i, 1));
 		}
-		udelay(1000);
 	} else if (AR_SREV_9280(ah) &&
-		   (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
+		   (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
 
+		/* RX shut off when elecidle is asserted */
 		REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
 
-		if (ah->ah_config.pcie_clock_req)
+		/* Shut off CLKREQ active in L1 */
+		if (ah->config.pcie_clock_req)
 			REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
 		else
 			REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
@@ -2816,42 +2816,59 @@ void ath9k_hw_configpcipowersave(struct
 		REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
 
+		/* Load the new settings */
 		REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
 
-		udelay(1000);
 	} else {
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+		/* RX shut off when elecidle is asserted */
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+		/*
+		 * Ignore ah->ah_config.pcie_clock_req setting for
+		 * pre-AR9280 11n
+		 */
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
 		REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+		/* Load the new settings */
 		REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
 	}
 
+	udelay(1000);
+
+	/* set bit 19 to allow forcing of pcie core into L1 state */
 	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
 
-	if (ah->ah_config.pcie_waen) {
-		REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+	/* Several PCIe massages to ensure proper behaviour */
+	if (ah->config.pcie_waen) {
+		REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
 	} else {
 		if (AR_SREV_9285(ah))
 			REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+		/*
+		 * On AR9280 chips bit 22 of 0x4004 needs to be set to
+		 * otherwise card may disappear.
+		 */
 		else if (AR_SREV_9280(ah))
 			REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
 		else
 			REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
 	}
-
 }
 
 /**********************/
 /* Interrupt Handling */
 /**********************/
 
-bool ath9k_hw_intrpend(struct ath_hal *ah)
+bool ath9k_hw_intrpend(struct ath_hw *ah)
 {
 	u32 host_isr;
 
@@ -2870,14 +2887,13 @@ bool ath9k_hw_intrpend(struct ath_hal *a
 	return false;
 }
 
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 {
 	u32 isr = 0;
 	u32 mask2 = 0;
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	u32 sync_cause = 0;
 	bool fatal_int = false;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
 	if (!AR_SREV_9100(ah)) {
 		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -2915,6 +2931,8 @@ bool ath9k_hw_getisr(struct ath_hal *ah,
 				mask2 |= ATH9K_INT_GTT;
 			if (isr2 & AR_ISR_S2_CST)
 				mask2 |= ATH9K_INT_CST;
+			if (isr2 & AR_ISR_S2_TSFOOR)
+				mask2 |= ATH9K_INT_TSFOOR;
 		}
 
 		isr = REG_READ(ah, AR_ISR_RAC);
@@ -2925,7 +2943,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah,
 
 		*masked = isr & ATH9K_INT_COMMON;
 
-		if (ahp->ah_intrMitigation) {
+		if (ah->intr_mitigation) {
 			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
 				*masked |= ATH9K_INT_RX;
 		}
@@ -2940,12 +2958,12 @@ bool ath9k_hw_getisr(struct ath_hal *ah,
 			*masked |= ATH9K_INT_TX;
 
 			s0_s = REG_READ(ah, AR_ISR_S0_S);
-			ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-			ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
 
 			s1_s = REG_READ(ah, AR_ISR_S1_S);
-			ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-			ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
 		}
 
 		if (isr & AR_ISR_RXORN) {
@@ -3002,17 +3020,16 @@ bool ath9k_hw_getisr(struct ath_hal *ah,
 	return true;
 }
 
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
 {
-	return AH5416(ah)->ah_maskReg;
+	return ah->mask_reg;
 }
 
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	u32 omask = ahp->ah_maskReg;
+	u32 omask = ah->mask_reg;
 	u32 mask, mask2;
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 	DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
 
@@ -3033,18 +3050,18 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 	mask2 = 0;
 
 	if (ints & ATH9K_INT_TX) {
-		if (ahp->ah_txOkInterruptMask)
+		if (ah->txok_interrupt_mask)
 			mask |= AR_IMR_TXOK;
-		if (ahp->ah_txDescInterruptMask)
+		if (ah->txdesc_interrupt_mask)
 			mask |= AR_IMR_TXDESC;
-		if (ahp->ah_txErrInterruptMask)
+		if (ah->txerr_interrupt_mask)
 			mask |= AR_IMR_TXERR;
-		if (ahp->ah_txEolInterruptMask)
+		if (ah->txeol_interrupt_mask)
 			mask |= AR_IMR_TXEOL;
 	}
 	if (ints & ATH9K_INT_RX) {
 		mask |= AR_IMR_RXERR;
-		if (ahp->ah_intrMitigation)
+		if (ah->intr_mitigation)
 			mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
 		else
 			mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3061,7 +3078,9 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 		if (ints & ATH9K_INT_DTIMSYNC)
 			mask2 |= AR_IMR_S2_DTIMSYNC;
 		if (ints & ATH9K_INT_CABEND)
-			mask2 |= (AR_IMR_S2_CABEND);
+			mask2 |= AR_IMR_S2_CABEND;
+		if (ints & ATH9K_INT_TSFOOR)
+			mask2 |= AR_IMR_S2_TSFOOR;
 	}
 
 	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
@@ -3082,7 +3101,7 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 					   AR_IMR_S2_TSFOOR |
 					   AR_IMR_S2_GTT | AR_IMR_S2_CST);
 	REG_WRITE(ah, AR_IMR_S2, mask | mask2);
-	ahp->ah_maskReg = ints;
+	ah->mask_reg = ints;
 
 	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
 		if (ints & ATH9K_INT_TIM_TIMER)
@@ -3116,14 +3135,13 @@ enum ath9k_int ath9k_hw_set_interrupts(s
 /* Beacon Handling */
 /*******************/
 
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	int flags = 0;
 
-	ahp->ah_beaconInterval = beacon_period;
+	ah->beacon_interval = beacon_period;
 
-	switch (ah->ah_opmode) {
+	switch (ah->opmode) {
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_MONITOR:
 		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
@@ -3132,22 +3150,23 @@ void ath9k_hw_beaconinit(struct ath_hal
 		flags |= AR_TBTT_TIMER_EN;
 		break;
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
 		REG_SET_BIT(ah, AR_TXCFG,
 			    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
 		REG_WRITE(ah, AR_NEXT_NDP_TIMER,
 			  TU_TO_USEC(next_beacon +
-				     (ahp->ah_atimWindow ? ahp->
-				      ah_atimWindow : 1)));
+				     (ah->atim_window ? ah->
+				      atim_window : 1)));
 		flags |= AR_NDP_TIMER_EN;
 	case NL80211_IFTYPE_AP:
 		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
 		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
 			  TU_TO_USEC(next_beacon -
-				     ah->ah_config.
+				     ah->config.
 				     dma_beacon_response_time));
 		REG_WRITE(ah, AR_NEXT_SWBA,
 			  TU_TO_USEC(next_beacon -
-				     ah->ah_config.
+				     ah->config.
 				     sw_beacon_response_time));
 		flags |=
 			AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
@@ -3155,7 +3174,7 @@ void ath9k_hw_beaconinit(struct ath_hal
 	default:
 		DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
 			"%s: unsupported opmode: %d\n",
-			__func__, ah->ah_opmode);
+			__func__, ah->opmode);
 		return;
 		break;
 	}
@@ -3174,11 +3193,11 @@ void ath9k_hw_beaconinit(struct ath_hal
 	REG_SET_BIT(ah, AR_TIMER_MODE, flags);
 }
 
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+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->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 	REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
 
@@ -3232,43 +3251,46 @@ void ath9k_hw_set_sta_beacon_timers(stru
 		    AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
 		    AR_DTIM_TIMER_EN);
 
+	/* TSF Out of Range Threshold */
+	REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
 }
 
 /*******************/
 /* HW Capabilities */
 /*******************/
 
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
+bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	u16 capField = 0, eeval;
 
-	eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
-
-	ah->ah_currentRD = eeval;
+	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+	ah->regulatory.current_rd = eeval;
 
-	eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
-	ah->ah_currentRDExt = eeval;
+	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		eeval |= AR9285_RDEXT_DEFAULT;
+	ah->regulatory.current_rd_ext = eeval;
 
-	capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
+	capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
 
-	if (ah->ah_opmode != NL80211_IFTYPE_AP &&
-	    ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
-		if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
-			ah->ah_currentRD += 5;
-		else if (ah->ah_currentRD == 0x41)
-			ah->ah_currentRD = 0x43;
+	if (ah->opmode != NL80211_IFTYPE_AP &&
+	    ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+		if (ah->regulatory.current_rd == 0x64 ||
+		    ah->regulatory.current_rd == 0x65)
+			ah->regulatory.current_rd += 5;
+		else if (ah->regulatory.current_rd == 0x41)
+			ah->regulatory.current_rd = 0x43;
 		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"regdomain mapped to 0x%x\n", ah->ah_currentRD);
+			"regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
 	}
 
-	eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
 	bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
 
 	if (eeval & AR5416_OPFLAGS_11A) {
 		set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-		if (ah->ah_config.ht_enable) {
+		if (ah->config.ht_enable) {
 			if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
 				set_bit(ATH9K_MODE_11NA_HT20,
 					pCap->wireless_modes);
@@ -3284,7 +3306,7 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 	if (eeval & AR5416_OPFLAGS_11G) {
 		set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
 		set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
-		if (ah->ah_config.ht_enable) {
+		if (ah->config.ht_enable) {
 			if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
 				set_bit(ATH9K_MODE_11NG_HT20,
 					pCap->wireless_modes);
@@ -3297,18 +3319,15 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 		}
 	}
 
-	pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK);
-	if ((ah->ah_isPciExpress)
-	    || (eeval & AR5416_OPFLAGS_11A)) {
-		pCap->rx_chainmask =
-			ath9k_hw_get_eeprom(ah, EEP_RX_MASK);
-	} else {
-		pCap->rx_chainmask =
-			(ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
-	}
+	pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+	if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+	    !(eeval & AR5416_OPFLAGS_11A))
+		pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+	else
+		pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
 
-	if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
-		ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
+	if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
+		ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
 
 	pCap->low_2ghz_chan = 2312;
 	pCap->high_2ghz_chan = 2732;
@@ -3326,7 +3345,7 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 
 	pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
 
-	if (ah->ah_config.ht_enable)
+	if (ah->config.ht_enable)
 		pCap->hw_caps |= ATH9K_HW_CAP_HT;
 	else
 		pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
@@ -3352,7 +3371,9 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 	pCap->num_mr_retries = 4;
 	pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		pCap->num_gpio_pins = AR9285_NUM_GPIO;
+	else if (AR_SREV_9280_10_OR_LATER(ah))
 		pCap->num_gpio_pins = AR928X_NUM_GPIO;
 	else
 		pCap->num_gpio_pins = AR_NUM_GPIO;
@@ -3375,22 +3396,22 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 	pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT);
-	if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
-		ah->ah_rfkill_gpio =
-			MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
-		ah->ah_rfkill_polarity =
-			MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
+	ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+	if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+		ah->rfkill_gpio =
+			MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+		ah->rfkill_polarity =
+			MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
 
 		pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
 	}
 #endif
 
-	if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
-	    (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
-	    (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
-	    (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
-	    (ah->ah_macVersion == AR_SREV_VERSION_9280))
+	if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
+	    (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
+	    (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
+	    (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
+	    (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
 		pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
 	else
 		pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3400,7 +3421,7 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 	else
 		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-	if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
+	if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
 		pCap->reg_cap =
 			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
 			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3415,19 +3436,22 @@ bool ath9k_hw_fill_cap_info(struct ath_h
 	pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
 
 	pCap->num_antcfg_5ghz =
-		ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
+		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
 	pCap->num_antcfg_2ghz =
-		ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+
+	if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+		pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+		ah->btactive_gpio = 6;
+		ah->wlanactive_gpio = 5;
+	}
 
 	return true;
 }
 
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 *result)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
 	switch (type) {
 	case ATH9K_CAP_CIPHER:
 		switch (capability) {
@@ -3446,23 +3470,17 @@ bool ath9k_hw_getcapability(struct ath_h
 		case 0:
 			return true;
 		case 1:
-			return (ahp->ah_staId1Defaults &
+			return (ah->sta_id1_defaults &
 				AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
 			false;
 		}
 	case ATH9K_CAP_TKIP_SPLIT:
-		return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
+		return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
 			false : true;
-	case ATH9K_CAP_WME_TKIPMIC:
-		return 0;
-	case ATH9K_CAP_PHYCOUNTERS:
-		return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
 	case ATH9K_CAP_DIVERSITY:
 		return (REG_READ(ah, AR_PHY_CCK_DETECT) &
 			AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
 			true : false;
-	case ATH9K_CAP_PHYDIAG:
-		return true;
 	case ATH9K_CAP_MCAST_KEYSRCH:
 		switch (capability) {
 		case 0:
@@ -3471,57 +3489,48 @@ bool ath9k_hw_getcapability(struct ath_h
 			if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
 				return false;
 			} else {
-				return (ahp->ah_staId1Defaults &
+				return (ah->sta_id1_defaults &
 					AR_STA_ID1_MCAST_KSRCH) ? true :
 					false;
 			}
 		}
 		return false;
-	case ATH9K_CAP_TSF_ADJUST:
-		return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
-			true : false;
-	case ATH9K_CAP_RFSILENT:
-		if (capability == 3)
-			return false;
-	case ATH9K_CAP_ANT_CFG_2GHZ:
-		*result = pCap->num_antcfg_2ghz;
-		return true;
-	case ATH9K_CAP_ANT_CFG_5GHZ:
-		*result = pCap->num_antcfg_5ghz;
-		return true;
 	case ATH9K_CAP_TXPOW:
 		switch (capability) {
 		case 0:
 			return 0;
 		case 1:
-			*result = ah->ah_powerLimit;
+			*result = ah->regulatory.power_limit;
 			return 0;
 		case 2:
-			*result = ah->ah_maxPowerLevel;
+			*result = ah->regulatory.max_power_level;
 			return 0;
 		case 3:
-			*result = ah->ah_tpScale;
+			*result = ah->regulatory.tp_scale;
 			return 0;
 		}
 		return false;
+	case ATH9K_CAP_DS:
+		return (AR_SREV_9280_20_OR_LATER(ah) &&
+			(ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
+			? false : true;
 	default:
 		return false;
 	}
 }
 
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 setting, int *status)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 v;
 
 	switch (type) {
 	case ATH9K_CAP_TKIP_MIC:
 		if (setting)
-			ahp->ah_staId1Defaults |=
+			ah->sta_id1_defaults |=
 				AR_STA_ID1_CRPT_MIC_ENABLE;
 		else
-			ahp->ah_staId1Defaults &=
+			ah->sta_id1_defaults &=
 				~AR_STA_ID1_CRPT_MIC_ENABLE;
 		return true;
 	case ATH9K_CAP_DIVERSITY:
@@ -3534,15 +3543,9 @@ bool ath9k_hw_setcapability(struct ath_h
 		return true;
 	case ATH9K_CAP_MCAST_KEYSRCH:
 		if (setting)
-			ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
-		else
-			ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
-		return true;
-	case ATH9K_CAP_TSF_ADJUST:
-		if (setting)
-			ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+			ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
 		else
-			ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+			ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
 		return true;
 	default:
 		return false;
@@ -3553,7 +3556,7 @@ bool ath9k_hw_setcapability(struct ath_h
 /* GPIO / RFKILL / Antennae */
 /****************************/
 
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
 					 u32 gpio, u32 type)
 {
 	int addr;
@@ -3581,11 +3584,11 @@ static void ath9k_hw_gpio_cfg_output_mux
 	}
 }
 
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
 {
 	u32 gpio_shift;
 
-	ASSERT(gpio < ah->ah_caps.num_gpio_pins);
+	ASSERT(gpio < ah->caps.num_gpio_pins);
 
 	gpio_shift = gpio << 1;
 
@@ -3595,22 +3598,23 @@ void ath9k_hw_cfg_gpio_input(struct ath_
 		(AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
 
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
 {
-	if (gpio >= ah->ah_caps.num_gpio_pins)
+#define MS_REG_READ(x, y) \
+	(MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+	if (gpio >= ah->caps.num_gpio_pins)
 		return 0xffffffff;
 
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		return (MS
-			(REG_READ(ah, AR_GPIO_IN_OUT),
-			 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
-	} else {
-		return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
-			AR_GPIO_BIT(gpio)) != 0;
-	}
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		return MS_REG_READ(AR9285, gpio) != 0;
+	else if (AR_SREV_9280_10_OR_LATER(ah))
+		return MS_REG_READ(AR928X, gpio) != 0;
+	else
+		return MS_REG_READ(AR, gpio) != 0;
 }
 
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
 			 u32 ah_signal_type)
 {
 	u32 gpio_shift;
@@ -3625,14 +3629,14 @@ void ath9k_hw_cfg_output(struct ath_hal
 		(AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
 
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
+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));
 }
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah)
+void ath9k_enable_rfkill(struct ath_hw *ah)
 {
 	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
 		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
@@ -3640,50 +3644,28 @@ void ath9k_enable_rfkill(struct ath_hal
 	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
 		    AR_GPIO_INPUT_MUX2_RFSILENT);
 
-	ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
+	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
 	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
 }
 #endif
 
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
-{
-	struct ath9k_channel *chan = ah->ah_curchan;
-	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-	u16 ant_config;
-	u32 halNumAntConfig;
-
-	halNumAntConfig = IS_CHAN_2GHZ(chan) ?
-		pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
-
-	if (cfg < halNumAntConfig) {
-		if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan,
-						     cfg, &ant_config)) {
-			REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
-			return 0;
-		}
-	}
-
-	return -EINVAL;
-}
-
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
 {
 	return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
 }
 
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
 {
 	REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
 }
 
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
+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)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	static u8 tx_chainmask_cfg, rx_chainmask_cfg;
 
 	if (AR_SREV_9280(ah)) {
@@ -3700,7 +3682,7 @@ bool ath9k_hw_setantennaswitch(struct at
 			*antenna_cfgd = true;
 			break;
 		case ATH9K_ANT_FIXED_B:
-			if (ah->ah_caps.tx_chainmask >
+			if (ah->caps.tx_chainmask >
 			    ATH9K_ANTENNA1_CHAINMASK) {
 				*tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
 			}
@@ -3716,7 +3698,7 @@ bool ath9k_hw_setantennaswitch(struct at
 			break;
 		}
 	} else {
-		ahp->ah_diversityControl = settings;
+		ah->diversity_control = settings;
 	}
 
 	return true;
@@ -3726,7 +3708,7 @@ bool ath9k_hw_setantennaswitch(struct at
 /* General Operation */
 /*********************/
 
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
 {
 	u32 bits = REG_READ(ah, AR_RX_FILTER);
 	u32 phybits = REG_READ(ah, AR_PHY_ERR);
@@ -3739,7 +3721,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hal
 	return bits;
 }
 
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
 {
 	u32 phybits;
 
@@ -3759,12 +3741,12 @@ void ath9k_hw_setrxfilter(struct ath_hal
 			  REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
 }
 
-bool ath9k_hw_phy_disable(struct ath_hal *ah)
+bool ath9k_hw_phy_disable(struct ath_hw *ah)
 {
 	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
 }
 
-bool ath9k_hw_disable(struct ath_hal *ah)
+bool ath9k_hw_disable(struct ath_hw *ah)
 {
 	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return false;
@@ -3772,82 +3754,54 @@ bool ath9k_hw_disable(struct ath_hal *ah
 	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
 }
 
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
 {
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ath9k_channel *chan = ah->curchan;
+	struct ieee80211_channel *channel = chan->chan;
 
-	ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
+	ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
 
-	if (ath9k_hw_set_txpower(ah, chan,
-				 ath9k_regd_get_ctl(ah, chan),
-				 ath9k_regd_get_antenna_allowed(ah, chan),
-				 chan->maxRegTxPower * 2,
-				 min((u32) MAX_RATE_POWER,
-				     (u32) ah->ah_powerLimit)) != 0)
+	if (ah->eep_ops->set_txpower(ah, chan,
+			     ath9k_regd_get_ctl(ah, chan),
+			     channel->max_antenna_gain * 2,
+			     channel->max_power * 2,
+			     min((u32) MAX_RATE_POWER,
+				 (u32) ah->regulatory.power_limit)) != 0)
 		return false;
 
 	return true;
 }
 
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
-}
-
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
-
-	return true;
+	memcpy(ah->macaddr, mac, ETH_ALEN);
 }
 
-void ath9k_hw_setopmode(struct ath_hal *ah)
+void ath9k_hw_setopmode(struct ath_hw *ah)
 {
-	ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+	ath9k_hw_set_operating_mode(ah, ah->opmode);
 }
 
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1)
+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);
 }
 
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
-{
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
-}
-
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
+void ath9k_hw_setbssidmask(struct ath_softc *sc)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
-
-	REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
-	REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
-
-	return true;
+	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));
 }
 
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId)
+void ath9k_hw_write_associd(struct ath_softc *sc)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
-	ahp->ah_assocId = assocId;
-
-	REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
-	REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
-		  ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+	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));
 }
 
-u64 ath9k_hw_gettsf64(struct ath_hal *ah)
+u64 ath9k_hw_gettsf64(struct ath_hw *ah)
 {
 	u64 tsf;
 
@@ -3857,7 +3811,13 @@ u64 ath9k_hw_gettsf64(struct ath_hal *ah
 	return tsf;
 }
 
-void ath9k_hw_reset_tsf(struct ath_hal *ah)
+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);
+}
+
+void ath9k_hw_reset_tsf(struct ath_hw *ah)
 {
 	int count;
 
@@ -3874,42 +3834,65 @@ void ath9k_hw_reset_tsf(struct ath_hal *
 	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
 }
 
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	if (setting)
-		ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+		ah->misc_mode |= AR_PCU_TX_ADD_TSF;
 	else
-		ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+		ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
 
 	return true;
 }
 
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	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);
-		ahp->ah_slottime = (u32) -1;
+		ah->slottime = (u32) -1;
 		return false;
 	} else {
 		REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-		ahp->ah_slottime = us;
+		ah->slottime = us;
 		return true;
 	}
 }
 
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
 {
 	u32 macmode;
 
 	if (mode == ATH9K_HT_MACMODE_2040 &&
-	    !ah->ah_config.cwm_ignore_extcca)
+	    !ah->config.cwm_ignore_extcca)
 		macmode = AR_2040_JOINED_RX_CLEAR;
 	else
 		macmode = 0;
 
 	REG_WRITE(ah, AR_2040_MODE, macmode);
 }
+
+/***************************/
+/*  Bluetooth Coexistence  */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+	/* 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));
+
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+			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,
+			ah->btactive_gpio);
+
+	/* Configure the desired gpio port for input */
+	ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+
+	/* Configure the desired GPIO port for TX_FRAME output */
+	ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -19,1062 +19,629 @@
 
 #include <linux/if_ether.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-struct ar5416_desc {
-	u32 ds_link;
-	u32 ds_data;
-	u32 ds_ctl0;
-	u32 ds_ctl1;
-	union {
-		struct {
-			u32 ctl2;
-			u32 ctl3;
-			u32 ctl4;
-			u32 ctl5;
-			u32 ctl6;
-			u32 ctl7;
-			u32 ctl8;
-			u32 ctl9;
-			u32 ctl10;
-			u32 ctl11;
-			u32 status0;
-			u32 status1;
-			u32 status2;
-			u32 status3;
-			u32 status4;
-			u32 status5;
-			u32 status6;
-			u32 status7;
-			u32 status8;
-			u32 status9;
-		} tx;
-		struct {
-			u32 status0;
-			u32 status1;
-			u32 status2;
-			u32 status3;
-			u32 status4;
-			u32 status5;
-			u32 status6;
-			u32 status7;
-			u32 status8;
-		} rx;
-	} u;
-} __packed;
-
-#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
-#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
-
-#define ds_ctl2     u.tx.ctl2
-#define ds_ctl3     u.tx.ctl3
-#define ds_ctl4     u.tx.ctl4
-#define ds_ctl5     u.tx.ctl5
-#define ds_ctl6     u.tx.ctl6
-#define ds_ctl7     u.tx.ctl7
-#define ds_ctl8     u.tx.ctl8
-#define ds_ctl9     u.tx.ctl9
-#define ds_ctl10    u.tx.ctl10
-#define ds_ctl11    u.tx.ctl11
-
-#define ds_txstatus0    u.tx.status0
-#define ds_txstatus1    u.tx.status1
-#define ds_txstatus2    u.tx.status2
-#define ds_txstatus3    u.tx.status3
-#define ds_txstatus4    u.tx.status4
-#define ds_txstatus5    u.tx.status5
-#define ds_txstatus6    u.tx.status6
-#define ds_txstatus7    u.tx.status7
-#define ds_txstatus8    u.tx.status8
-#define ds_txstatus9    u.tx.status9
-
-#define ds_rxstatus0    u.rx.status0
-#define ds_rxstatus1    u.rx.status1
-#define ds_rxstatus2    u.rx.status2
-#define ds_rxstatus3    u.rx.status3
-#define ds_rxstatus4    u.rx.status4
-#define ds_rxstatus5    u.rx.status5
-#define ds_rxstatus6    u.rx.status6
-#define ds_rxstatus7    u.rx.status7
-#define ds_rxstatus8    u.rx.status8
-
-#define AR_FrameLen         0x00000fff
-#define AR_VirtMoreFrag     0x00001000
-#define AR_TxCtlRsvd00      0x0000e000
-#define AR_XmitPower        0x003f0000
-#define AR_XmitPower_S      16
-#define AR_RTSEnable        0x00400000
-#define AR_VEOL             0x00800000
-#define AR_ClrDestMask      0x01000000
-#define AR_TxCtlRsvd01      0x1e000000
-#define AR_TxIntrReq        0x20000000
-#define AR_DestIdxValid     0x40000000
-#define AR_CTSEnable        0x80000000
-
-#define AR_BufLen           0x00000fff
-#define AR_TxMore           0x00001000
-#define AR_DestIdx          0x000fe000
-#define AR_DestIdx_S        13
-#define AR_FrameType        0x00f00000
-#define AR_FrameType_S      20
-#define AR_NoAck            0x01000000
-#define AR_InsertTS         0x02000000
-#define AR_CorruptFCS       0x04000000
-#define AR_ExtOnly          0x08000000
-#define AR_ExtAndCtl        0x10000000
-#define AR_MoreAggr         0x20000000
-#define AR_IsAggr           0x40000000
-
-#define AR_BurstDur         0x00007fff
-#define AR_BurstDur_S       0
-#define AR_DurUpdateEna     0x00008000
-#define AR_XmitDataTries0   0x000f0000
-#define AR_XmitDataTries0_S 16
-#define AR_XmitDataTries1   0x00f00000
-#define AR_XmitDataTries1_S 20
-#define AR_XmitDataTries2   0x0f000000
-#define AR_XmitDataTries2_S 24
-#define AR_XmitDataTries3   0xf0000000
-#define AR_XmitDataTries3_S 28
-
-#define AR_XmitRate0        0x000000ff
-#define AR_XmitRate0_S      0
-#define AR_XmitRate1        0x0000ff00
-#define AR_XmitRate1_S      8
-#define AR_XmitRate2        0x00ff0000
-#define AR_XmitRate2_S      16
-#define AR_XmitRate3        0xff000000
-#define AR_XmitRate3_S      24
-
-#define AR_PacketDur0       0x00007fff
-#define AR_PacketDur0_S     0
-#define AR_RTSCTSQual0      0x00008000
-#define AR_PacketDur1       0x7fff0000
-#define AR_PacketDur1_S     16
-#define AR_RTSCTSQual1      0x80000000
-
-#define AR_PacketDur2       0x00007fff
-#define AR_PacketDur2_S     0
-#define AR_RTSCTSQual2      0x00008000
-#define AR_PacketDur3       0x7fff0000
-#define AR_PacketDur3_S     16
-#define AR_RTSCTSQual3      0x80000000
-
-#define AR_AggrLen          0x0000ffff
-#define AR_AggrLen_S        0
-#define AR_TxCtlRsvd60      0x00030000
-#define AR_PadDelim         0x03fc0000
-#define AR_PadDelim_S       18
-#define AR_EncrType         0x0c000000
-#define AR_EncrType_S       26
-#define AR_TxCtlRsvd61      0xf0000000
-
-#define AR_2040_0           0x00000001
-#define AR_GI0              0x00000002
-#define AR_ChainSel0        0x0000001c
-#define AR_ChainSel0_S      2
-#define AR_2040_1           0x00000020
-#define AR_GI1              0x00000040
-#define AR_ChainSel1        0x00000380
-#define AR_ChainSel1_S      7
-#define AR_2040_2           0x00000400
-#define AR_GI2              0x00000800
-#define AR_ChainSel2        0x00007000
-#define AR_ChainSel2_S      12
-#define AR_2040_3           0x00008000
-#define AR_GI3              0x00010000
-#define AR_ChainSel3        0x000e0000
-#define AR_ChainSel3_S      17
-#define AR_RTSCTSRate       0x0ff00000
-#define AR_RTSCTSRate_S     20
-#define AR_TxCtlRsvd70      0xf0000000
-
-#define AR_TxRSSIAnt00      0x000000ff
-#define AR_TxRSSIAnt00_S    0
-#define AR_TxRSSIAnt01      0x0000ff00
-#define AR_TxRSSIAnt01_S    8
-#define AR_TxRSSIAnt02      0x00ff0000
-#define AR_TxRSSIAnt02_S    16
-#define AR_TxStatusRsvd00   0x3f000000
-#define AR_TxBaStatus       0x40000000
-#define AR_TxStatusRsvd01   0x80000000
-
-#define AR_FrmXmitOK            0x00000001
-#define AR_ExcessiveRetries     0x00000002
-#define AR_FIFOUnderrun         0x00000004
-#define AR_Filtered             0x00000008
-#define AR_RTSFailCnt           0x000000f0
-#define AR_RTSFailCnt_S         4
-#define AR_DataFailCnt          0x00000f00
-#define AR_DataFailCnt_S        8
-#define AR_VirtRetryCnt         0x0000f000
-#define AR_VirtRetryCnt_S       12
-#define AR_TxDelimUnderrun      0x00010000
-#define AR_TxDataUnderrun       0x00020000
-#define AR_DescCfgErr           0x00040000
-#define AR_TxTimerExpired       0x00080000
-#define AR_TxStatusRsvd10       0xfff00000
-
-#define AR_SendTimestamp    ds_txstatus2
-#define AR_BaBitmapLow      ds_txstatus3
-#define AR_BaBitmapHigh     ds_txstatus4
-
-#define AR_TxRSSIAnt10      0x000000ff
-#define AR_TxRSSIAnt10_S    0
-#define AR_TxRSSIAnt11      0x0000ff00
-#define AR_TxRSSIAnt11_S    8
-#define AR_TxRSSIAnt12      0x00ff0000
-#define AR_TxRSSIAnt12_S    16
-#define AR_TxRSSICombined   0xff000000
-#define AR_TxRSSICombined_S 24
-
-#define AR_TxEVM0           ds_txstatus5
-#define AR_TxEVM1           ds_txstatus6
-#define AR_TxEVM2           ds_txstatus7
-
-#define AR_TxDone           0x00000001
-#define AR_SeqNum           0x00001ffe
-#define AR_SeqNum_S         1
-#define AR_TxStatusRsvd80   0x0001e000
-#define AR_TxOpExceeded     0x00020000
-#define AR_TxStatusRsvd81   0x001c0000
-#define AR_FinalTxIdx       0x00600000
-#define AR_FinalTxIdx_S     21
-#define AR_TxStatusRsvd82   0x01800000
-#define AR_PowerMgmt        0x02000000
-#define AR_TxStatusRsvd83   0xfc000000
-
-#define AR_RxCTLRsvd00  0xffffffff
-
-#define AR_BufLen       0x00000fff
-#define AR_RxCtlRsvd00  0x00001000
-#define AR_RxIntrReq    0x00002000
-#define AR_RxCtlRsvd01  0xffffc000
-
-#define AR_RxRSSIAnt00      0x000000ff
-#define AR_RxRSSIAnt00_S    0
-#define AR_RxRSSIAnt01      0x0000ff00
-#define AR_RxRSSIAnt01_S    8
-#define AR_RxRSSIAnt02      0x00ff0000
-#define AR_RxRSSIAnt02_S    16
-#define AR_RxRate           0xff000000
-#define AR_RxRate_S         24
-#define AR_RxStatusRsvd00   0xff000000
-
-#define AR_DataLen          0x00000fff
-#define AR_RxMore           0x00001000
-#define AR_NumDelim         0x003fc000
-#define AR_NumDelim_S       14
-#define AR_RxStatusRsvd10   0xff800000
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "regd.h"
+#include "reg.h"
+#include "phy.h"
 
-#define AR_RcvTimestamp     ds_rxstatus2
+#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	AR_SUBVENDOR_ID_NOG	0x0e11
+#define AR_SUBVENDOR_ID_NEW_A	0x7065
+#define AR5416_MAGIC		0x19641014
 
-#define AR_GI               0x00000001
-#define AR_2040             0x00000002
-#define AR_Parallel40       0x00000004
-#define AR_Parallel40_S     2
-#define AR_RxStatusRsvd30   0x000000f8
-#define AR_RxAntenna	    0xffffff00
-#define AR_RxAntenna_S	    8
+/* 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 AR_RxRSSIAnt10            0x000000ff
-#define AR_RxRSSIAnt10_S          0
-#define AR_RxRSSIAnt11            0x0000ff00
-#define AR_RxRSSIAnt11_S          8
-#define AR_RxRSSIAnt12            0x00ff0000
-#define AR_RxRSSIAnt12_S          16
-#define AR_RxRSSICombined         0xff000000
-#define AR_RxRSSICombined_S       24
+#define SM(_v, _f)  (((_v) << _f##_S) & _f)
+#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
+#define REG_RMW(_a, _r, _set, _clr)    \
+	REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
+#define REG_RMW_FIELD(_a, _r, _f, _v) \
+	REG_WRITE(_a, _r, \
+	(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_SET_BIT(_a, _r, _f) \
+	REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
+#define REG_CLR_BIT(_a, _r, _f) \
+	REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
 
-#define AR_RxEVM0           ds_rxstatus4
-#define AR_RxEVM1           ds_rxstatus5
-#define AR_RxEVM2           ds_rxstatus6
+#define DO_DELAY(x) do {			\
+		if ((++(x) % 64) == 0)          \
+			udelay(1);		\
+	} while (0)
 
-#define AR_RxDone           0x00000001
-#define AR_RxFrameOK        0x00000002
-#define AR_CRCErr           0x00000004
-#define AR_DecryptCRCErr    0x00000008
-#define AR_PHYErr           0x00000010
-#define AR_MichaelErr       0x00000020
-#define AR_PreDelimCRCErr   0x00000040
-#define AR_RxStatusRsvd70   0x00000080
-#define AR_RxKeyIdxValid    0x00000100
-#define AR_KeyIdx           0x0000fe00
-#define AR_KeyIdx_S         9
-#define AR_PHYErrCode       0x0000ff00
-#define AR_PHYErrCode_S     8
-#define AR_RxMoreAggr       0x00010000
-#define AR_RxAggr           0x00020000
-#define AR_PostDelimCRCErr  0x00040000
-#define AR_RxStatusRsvd71   0x3ff80000
-#define AR_DecryptBusyErr   0x40000000
-#define AR_KeyMiss          0x80000000
+#define REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
+		int r;							\
+		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
+			REG_WRITE(ah, INI_RA((iniarray), (r), 0),	\
+				  INI_RA((iniarray), r, (column)));	\
+			DO_DELAY(regWr);				\
+		}							\
+	} while (0)
 
-#define AR5416_MAGIC        0x19641014
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
 
-#define RXSTATUS_RATE(ah, ads)  (AR_SREV_5416_V20_OR_LATER(ah) ?	\
-				 MS(ads->ds_rxstatus0, AR_RxRate) :	\
-				 (ads->ds_rxstatus3 >> 2) & 0xFF)
+#define AR_GPIOD_MASK               0x00001FFF
+#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
 
-#define set11nTries(_series, _index) \
-	(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+#define BASE_ACTIVATE_DELAY         100
+#define RTC_PLL_SETTLE_DELAY        1000
+#define COEF_SCALE_S                24
+#define HT40_CHANNEL_CENTER_SHIFT   10
 
-#define set11nRate(_series, _index) \
-	(SM((_series)[_index].Rate, AR_XmitRate##_index))
+#define ATH9K_ANTENNA0_CHAINMASK    0x1
+#define ATH9K_ANTENNA1_CHAINMASK    0x2
 
-#define set11nPktDurRTSCTS(_series, _index)				\
-	(SM((_series)[_index].PktDuration, AR_PacketDur##_index) |	\
-	((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?	\
-		AR_RTSCTSQual##_index : 0))
+#define ATH9K_NUM_DMA_DEBUG_REGS    8
+#define ATH9K_NUM_QUEUES            10
 
-#define set11nRateFlags(_series, _index)				\
-	(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?		\
-	  AR_2040_##_index : 0)						\
-	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?	\
-	   AR_GI##_index : 0)						\
-	 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+#define MAX_RATE_POWER              63
+#define AH_WAIT_TIMEOUT             100000 /* (us) */
+#define AH_TIME_QUANTUM             10
+#define AR_KEYTABLE_SIZE            128
+#define POWER_UP_TIME               200000
+#define SPUR_RSSI_THRESH            40
 
-#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
+#define CAB_TIMEOUT_VAL             10
+#define BEACON_TIMEOUT_VAL          10
+#define MIN_BEACON_TIMEOUT_VAL      1
+#define SLEEP_SLOP                  3
 
-#define INIT_CONFIG_STATUS  0x00000000
-#define INIT_RSSI_THR       0x00000700
-#define INIT_BCON_CNTRL_REG 0x00000000
+#define INIT_CONFIG_STATUS          0x00000000
+#define INIT_RSSI_THR               0x00000700
+#define INIT_BCON_CNTRL_REG         0x00000000
 
-#define MIN_TX_FIFO_THRESHOLD   0x1
-#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
+#define TU_TO_USEC(_tu)             ((_tu) << 10)
 
-struct ar5416AniState {
-	struct ath9k_channel c;
-	u8 noiseImmunityLevel;
-	u8 spurImmunityLevel;
-	u8 firstepLevel;
-	u8 ofdmWeakSigDetectOff;
-	u8 cckWeakSigThreshold;
-	u32 listenTime;
-	u32 ofdmTrigHigh;
-	u32 ofdmTrigLow;
-	int32_t cckTrigHigh;
-	int32_t cckTrigLow;
-	int32_t rssiThrLow;
-	int32_t rssiThrHigh;
-	u32 noiseFloor;
-	u32 txFrameCount;
-	u32 rxFrameCount;
-	u32 cycleCount;
-	u32 ofdmPhyErrCount;
-	u32 cckPhyErrCount;
-	u32 ofdmPhyErrBase;
-	u32 cckPhyErrBase;
-	int16_t pktRssi[2];
-	int16_t ofdmErrRssi[2];
-	int16_t cckErrRssi[2];
+enum wireless_mode {
+	ATH9K_MODE_11A = 0,
+	ATH9K_MODE_11B = 2,
+	ATH9K_MODE_11G = 3,
+	ATH9K_MODE_11NA_HT20 = 6,
+	ATH9K_MODE_11NG_HT20 = 7,
+	ATH9K_MODE_11NA_HT40PLUS = 8,
+	ATH9K_MODE_11NA_HT40MINUS = 9,
+	ATH9K_MODE_11NG_HT40PLUS = 10,
+	ATH9K_MODE_11NG_HT40MINUS = 11,
+	ATH9K_MODE_MAX
 };
 
-#define HAL_PROCESS_ANI     0x00000001
-#define DO_ANI(ah) \
-	((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
-
-struct ar5416Stats {
-	u32 ast_ani_niup;
-	u32 ast_ani_nidown;
-	u32 ast_ani_spurup;
-	u32 ast_ani_spurdown;
-	u32 ast_ani_ofdmon;
-	u32 ast_ani_ofdmoff;
-	u32 ast_ani_cckhigh;
-	u32 ast_ani_ccklow;
-	u32 ast_ani_stepup;
-	u32 ast_ani_stepdown;
-	u32 ast_ani_ofdmerrs;
-	u32 ast_ani_cckerrs;
-	u32 ast_ani_reset;
-	u32 ast_ani_lzero;
-	u32 ast_ani_lneg;
-	struct ath9k_mib_stats ast_mibstats;
-	struct ath9k_node_stats ast_nodestats;
+enum ath9k_hw_caps {
+	ATH9K_HW_CAP_CHAN_SPREAD		= BIT(0),
+	ATH9K_HW_CAP_MIC_AESCCM                 = BIT(1),
+	ATH9K_HW_CAP_MIC_CKIP                   = BIT(2),
+	ATH9K_HW_CAP_MIC_TKIP                   = BIT(3),
+	ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(4),
+	ATH9K_HW_CAP_CIPHER_CKIP                = BIT(5),
+	ATH9K_HW_CAP_CIPHER_TKIP                = BIT(6),
+	ATH9K_HW_CAP_VEOL                       = BIT(7),
+	ATH9K_HW_CAP_BSSIDMASK                  = BIT(8),
+	ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(9),
+	ATH9K_HW_CAP_CHAN_HALFRATE              = BIT(10),
+	ATH9K_HW_CAP_CHAN_QUARTERRATE           = BIT(11),
+	ATH9K_HW_CAP_HT                         = BIT(12),
+	ATH9K_HW_CAP_GTT                        = BIT(13),
+	ATH9K_HW_CAP_FASTCC                     = BIT(14),
+	ATH9K_HW_CAP_RFSILENT                   = BIT(15),
+	ATH9K_HW_CAP_WOW                        = BIT(16),
+	ATH9K_HW_CAP_CST                        = BIT(17),
+	ATH9K_HW_CAP_ENHANCEDPM                 = BIT(18),
+	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(19),
+	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(20),
+	ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT     = BIT(21),
+	ATH9K_HW_CAP_BT_COEX			= BIT(22)
 };
 
-#define AR5416_OPFLAGS_11A           0x01
-#define AR5416_OPFLAGS_11G           0x02
-#define AR5416_OPFLAGS_N_5G_HT40     0x04
-#define AR5416_OPFLAGS_N_2G_HT40     0x08
-#define AR5416_OPFLAGS_N_5G_HT20     0x10
-#define AR5416_OPFLAGS_N_2G_HT20     0x20
-
-#define EEP_RFSILENT_ENABLED        0x0001
-#define EEP_RFSILENT_ENABLED_S      0
-#define EEP_RFSILENT_POLARITY       0x0002
-#define EEP_RFSILENT_POLARITY_S     1
-#define EEP_RFSILENT_GPIO_SEL       0x001c
-#define EEP_RFSILENT_GPIO_SEL_S     2
-
-#define AR5416_EEP_NO_BACK_VER       0x1
-#define AR5416_EEP_VER               0xE
-#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
-#define AR5416_EEP_MINOR_VER_2       0x2
-#define AR5416_EEP_MINOR_VER_3       0x3
-#define AR5416_EEP_MINOR_VER_7       0x7
-#define AR5416_EEP_MINOR_VER_9       0x9
-#define AR5416_EEP_MINOR_VER_16      0x10
-#define AR5416_EEP_MINOR_VER_17      0x11
-#define AR5416_EEP_MINOR_VER_19      0x13
-
-#define AR5416_NUM_5G_CAL_PIERS         8
-#define AR5416_NUM_2G_CAL_PIERS         4
-#define AR5416_NUM_5G_20_TARGET_POWERS  8
-#define AR5416_NUM_5G_40_TARGET_POWERS  8
-#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_NUM_2G_20_TARGET_POWERS  4
-#define AR5416_NUM_2G_40_TARGET_POWERS  4
-#define AR5416_NUM_CTLS                 24
-#define AR5416_NUM_BAND_EDGES           8
-#define AR5416_NUM_PD_GAINS             4
-#define AR5416_PD_GAINS_IN_MASK         4
-#define AR5416_PD_GAIN_ICEPTS           5
-#define AR5416_EEPROM_MODAL_SPURS       5
-#define AR5416_MAX_RATE_POWER           63
-#define AR5416_NUM_PDADC_VALUES         128
-#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
-
-/* Rx gain type values */
-#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
-#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
-#define AR5416_EEP_RXGAIN_ORIG             2
-
-/* Tx gain type values */
-#define AR5416_EEP_TXGAIN_ORIGINAL         0
-#define AR5416_EEP_TXGAIN_HIGH_POWER       1
-
-#define AR5416_EEP4K_START_LOC         64
-#define AR5416_EEP4K_NUM_2G_CAL_PIERS      3
-#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
-#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
-#define AR5416_EEP4K_NUM_CTLS              12
-#define AR5416_EEP4K_NUM_BAND_EDGES        4
-#define AR5416_EEP4K_NUM_PD_GAINS          2
-#define AR5416_EEP4K_PD_GAINS_IN_MASK      4
-#define AR5416_EEP4K_PD_GAIN_ICEPTS        5
-#define AR5416_EEP4K_MAX_CHAINS            1
-
-enum eeprom_param {
-	EEP_NFTHRESH_5,
-	EEP_NFTHRESH_2,
-	EEP_MAC_MSW,
-	EEP_MAC_MID,
-	EEP_MAC_LSW,
-	EEP_REG_0,
-	EEP_REG_1,
-	EEP_OP_CAP,
-	EEP_OP_MODE,
-	EEP_RF_SILENT,
-	EEP_OB_5,
-	EEP_DB_5,
-	EEP_OB_2,
-	EEP_DB_2,
-	EEP_MINOR_REV,
-	EEP_TX_MASK,
-	EEP_RX_MASK,
-	EEP_RXGAIN_TYPE,
-	EEP_TXGAIN_TYPE,
+enum ath9k_capability_type {
+	ATH9K_CAP_CIPHER = 0,
+	ATH9K_CAP_TKIP_MIC,
+	ATH9K_CAP_TKIP_SPLIT,
+	ATH9K_CAP_DIVERSITY,
+	ATH9K_CAP_TXPOW,
+	ATH9K_CAP_MCAST_KEYSRCH,
+	ATH9K_CAP_DS
 };
 
-enum ar5416_rates {
-	rate6mb, rate9mb, rate12mb, rate18mb,
-	rate24mb, rate36mb, rate48mb, rate54mb,
-	rate1l, rate2l, rate2s, rate5_5l,
-	rate5_5s, rate11l, rate11s, rateXr,
-	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
-	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
-	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
-	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
-	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
-	Ar5416RateSize
+struct ath9k_hw_capabilities {
+	u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+	DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
+	u16 total_queues;
+	u16 keycache_size;
+	u16 low_5ghz_chan, high_5ghz_chan;
+	u16 low_2ghz_chan, high_2ghz_chan;
+	u16 num_mr_retries;
+	u16 rts_aggr_limit;
+	u8 tx_chainmask;
+	u8 rx_chainmask;
+	u16 tx_triglevel_max;
+	u16 reg_cap;
+	u8 num_gpio_pins;
+	u8 num_antcfg_2ghz;
+	u8 num_antcfg_5ghz;
 };
 
-enum ath9k_hal_freq_band {
-	ATH9K_HAL_FREQ_BAND_5GHZ = 0,
-	ATH9K_HAL_FREQ_BAND_2GHZ = 1
+struct ath9k_ops_config {
+	int dma_beacon_response_time;
+	int sw_beacon_response_time;
+	int additional_swba_backoff;
+	int ack_6mb;
+	int cwm_ignore_extcca;
+	u8 pcie_powersave_enable;
+	u8 pcie_l1skp_enable;
+	u8 pcie_clock_req;
+	u32 pcie_waen;
+	int pcie_power_reset;
+	u8 pcie_restore;
+	u8 analog_shiftreg;
+	u8 ht_enable;
+	u32 ofdm_trig_low;
+	u32 ofdm_trig_high;
+	u32 cck_trig_high;
+	u32 cck_trig_low;
+	u32 enable_ani;
+	u8 noise_immunity_level;
+	u32 ofdm_weaksignal_det;
+	u32 cck_weaksignal_thr;
+	u8 spur_immunity_level;
+	u8 firstep_level;
+	int8_t rssi_thr_high;
+	int8_t rssi_thr_low;
+	u16 diversity_control;
+	u16 antenna_switch_swap;
+	int serialize_regmode;
+	int intr_mitigation;
+#define SPUR_DISABLE        	0
+#define SPUR_ENABLE_IOCTL   	1
+#define SPUR_ENABLE_EEPROM  	2
+#define AR_EEPROM_MODAL_SPURS   5
+#define AR_SPUR_5413_1      	1640
+#define AR_SPUR_5413_2      	1200
+#define AR_NO_SPUR      	0x8000
+#define AR_BASE_FREQ_2GHZ   	2300
+#define AR_BASE_FREQ_5GHZ   	4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+	int spurmode;
+	u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
 };
 
-struct base_eep_header {
-	u16 length;
-	u16 checksum;
-	u16 version;
-	u8 opCapFlags;
-	u8 eepMisc;
-	u16 regDmn[2];
-	u8 macAddr[6];
-	u8 rxMask;
-	u8 txMask;
-	u16 rfSilent;
-	u16 blueToothOptions;
-	u16 deviceCap;
-	u32 binBuildNumber;
-	u8 deviceType;
-	u8 pwdclkind;
-	u8 futureBase_1[2];
-	u8 rxGainType;
-	u8 futureBase_2[3];
-	u8 txGainType;
-	u8 futureBase_3[25];
-} __packed;
-
-struct base_eep_header_4k {
-	u16 length;
-	u16 checksum;
-	u16 version;
-	u8 opCapFlags;
-	u8 eepMisc;
-	u16 regDmn[2];
-	u8 macAddr[6];
-	u8 rxMask;
-	u8 txMask;
-	u16 rfSilent;
-	u16 blueToothOptions;
-	u16 deviceCap;
-	u32 binBuildNumber;
-	u8 deviceType;
-	u8 futureBase[1];
-} __packed;
-
-
-struct spur_chan {
-	u16 spurChan;
-	u8 spurRangeLow;
-	u8 spurRangeHigh;
-} __packed;
-
-struct modal_eep_header {
-	u32 antCtrlChain[AR5416_MAX_CHAINS];
-	u32 antCtrlCommon;
-	u8 antennaGainCh[AR5416_MAX_CHAINS];
-	u8 switchSettling;
-	u8 txRxAttenCh[AR5416_MAX_CHAINS];
-	u8 rxTxMarginCh[AR5416_MAX_CHAINS];
-	u8 adcDesiredSize;
-	u8 pgaDesiredSize;
-	u8 xlnaGainCh[AR5416_MAX_CHAINS];
-	u8 txEndToXpaOff;
-	u8 txEndToRxOn;
-	u8 txFrameToXpaOn;
-	u8 thresh62;
-	u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
-	u8 xpdGain;
-	u8 xpd;
-	u8 iqCalICh[AR5416_MAX_CHAINS];
-	u8 iqCalQCh[AR5416_MAX_CHAINS];
-	u8 pdGainOverlap;
-	u8 ob;
-	u8 db;
-	u8 xpaBiasLvl;
-	u8 pwrDecreaseFor2Chain;
-	u8 pwrDecreaseFor3Chain;
-	u8 txFrameToDataStart;
-	u8 txFrameToPaOn;
-	u8 ht40PowerIncForPdadc;
-	u8 bswAtten[AR5416_MAX_CHAINS];
-	u8 bswMargin[AR5416_MAX_CHAINS];
-	u8 swSettleHt40;
-	u8 xatten2Db[AR5416_MAX_CHAINS];
-	u8 xatten2Margin[AR5416_MAX_CHAINS];
-	u8 ob_ch1;
-	u8 db_ch1;
-	u8 useAnt1:1,
-	    force_xpaon:1,
-	    local_bias:1,
-	    femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
-	u8 futureModalar9280;
-	u16 xpaBiasLvlFreq[3];
-	u8 futureModal[6];
-
-	struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-struct modal_eep_4k_header {
-    u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
-    u32  antCtrlCommon;
-    u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   switchSettling;
-    u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   adcDesiredSize;
-    u8   pgaDesiredSize;
-    u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   txEndToXpaOff;
-    u8   txEndToRxOn;
-    u8   txFrameToXpaOn;
-    u8   thresh62;
-    u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   xpdGain;
-    u8   xpd;
-    u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
-    u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
-    u8   pdGainOverlap;
-    u8   ob_01;
-    u8   db1_01;
-    u8   xpaBiasLvl;
-    u8   txFrameToDataStart;
-    u8   txFrameToPaOn;
-    u8   ht40PowerIncForPdadc;
-    u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
-    u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
-    u8   swSettleHt40;
-    u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
-    u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
-    u8   db2_01;
-    u8   version;
-    u16  ob_234;
-    u16  db1_234;
-    u16  db2_234;
-    u8   futureModal[4];
-
-    struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-
-struct cal_data_per_freq {
-	u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-	u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_data_per_freq_4k {
-	u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-	u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_target_power_leg {
-	u8 bChannel;
-	u8 tPow2x[4];
-} __packed;
-
-struct cal_target_power_ht {
-	u8 bChannel;
-	u8 tPow2x[8];
-} __packed;
-
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-	u8 bChannel;
-	u8 flag:2, tPower:6;
-} __packed;
-#else
-struct cal_ctl_edges {
-	u8 bChannel;
-	u8 tPower:6, flag:2;
-} __packed;
-#endif
-
-struct cal_ctl_data {
-	struct cal_ctl_edges
-	ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
+enum ath9k_int {
+	ATH9K_INT_RX = 0x00000001,
+	ATH9K_INT_RXDESC = 0x00000002,
+	ATH9K_INT_RXNOFRM = 0x00000008,
+	ATH9K_INT_RXEOL = 0x00000010,
+	ATH9K_INT_RXORN = 0x00000020,
+	ATH9K_INT_TX = 0x00000040,
+	ATH9K_INT_TXDESC = 0x00000080,
+	ATH9K_INT_TIM_TIMER = 0x00000100,
+	ATH9K_INT_TXURN = 0x00000800,
+	ATH9K_INT_MIB = 0x00001000,
+	ATH9K_INT_RXPHY = 0x00004000,
+	ATH9K_INT_RXKCM = 0x00008000,
+	ATH9K_INT_SWBA = 0x00010000,
+	ATH9K_INT_BMISS = 0x00040000,
+	ATH9K_INT_BNR = 0x00100000,
+	ATH9K_INT_TIM = 0x00200000,
+	ATH9K_INT_DTIM = 0x00400000,
+	ATH9K_INT_DTIMSYNC = 0x00800000,
+	ATH9K_INT_GPIO = 0x01000000,
+	ATH9K_INT_CABEND = 0x02000000,
+	ATH9K_INT_TSFOOR = 0x04000000,
+	ATH9K_INT_CST = 0x10000000,
+	ATH9K_INT_GTT = 0x20000000,
+	ATH9K_INT_FATAL = 0x40000000,
+	ATH9K_INT_GLOBAL = 0x80000000,
+	ATH9K_INT_BMISC = ATH9K_INT_TIM |
+		ATH9K_INT_DTIM |
+		ATH9K_INT_DTIMSYNC |
+		ATH9K_INT_TSFOOR |
+		ATH9K_INT_CABEND,
+	ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+		ATH9K_INT_RXDESC |
+		ATH9K_INT_RXEOL |
+		ATH9K_INT_RXORN |
+		ATH9K_INT_TXURN |
+		ATH9K_INT_TXDESC |
+		ATH9K_INT_MIB |
+		ATH9K_INT_RXPHY |
+		ATH9K_INT_RXKCM |
+		ATH9K_INT_SWBA |
+		ATH9K_INT_BMISS |
+		ATH9K_INT_GPIO,
+	ATH9K_INT_NOCARD = 0xffffffff
+};
 
-struct cal_ctl_data_4k {
-	struct cal_ctl_edges
-	ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
-} __packed;
+#define CHANNEL_CW_INT    0x00002
+#define CHANNEL_CCK       0x00020
+#define CHANNEL_OFDM      0x00040
+#define CHANNEL_2GHZ      0x00080
+#define CHANNEL_5GHZ      0x00100
+#define CHANNEL_PASSIVE   0x00200
+#define CHANNEL_DYN       0x00400
+#define CHANNEL_HALF      0x04000
+#define CHANNEL_QUARTER   0x08000
+#define CHANNEL_HT20      0x10000
+#define CHANNEL_HT40PLUS  0x20000
+#define CHANNEL_HT40MINUS 0x40000
 
-struct ar5416_eeprom_def {
-	struct base_eep_header baseEepHeader;
-	u8 custData[64];
-	struct modal_eep_header modalHeader[2];
-	u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
-	u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
-	struct cal_data_per_freq
-	 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
-	struct cal_data_per_freq
-	 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-	struct cal_target_power_leg
-	 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
-	struct cal_target_power_leg
-	 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
-	struct cal_target_power_leg
-	 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
-	u8 ctlIndex[AR5416_NUM_CTLS];
-	struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
-	u8 padding;
-} __packed;
+#define CHANNEL_INTERFERENCE    0x01
+#define CHANNEL_DFS             0x02
+#define CHANNEL_4MS_LIMIT       0x04
+#define CHANNEL_DFS_CLEAR       0x08
+#define CHANNEL_DISALLOW_ADHOC  0x10
+#define CHANNEL_PER_11D_ADHOC   0x20
 
-struct ar5416_eeprom_4k {
-	struct base_eep_header_4k baseEepHeader;
-	u8 custData[20];
-	struct modal_eep_4k_header modalHeader;
-	u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
-	struct cal_data_per_freq_4k
-	calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
-	struct cal_target_power_leg
-	calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
-	struct cal_target_power_leg
-	calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
-	struct cal_target_power_ht
-	calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
-	u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
-	struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
-	u8 padding;
-} __packed;
+#define CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
+#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
+#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
+#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_ALL				\
+	(CHANNEL_OFDM|				\
+	 CHANNEL_CCK|				\
+	 CHANNEL_2GHZ |				\
+	 CHANNEL_5GHZ |				\
+	 CHANNEL_HT20 |				\
+	 CHANNEL_HT40PLUS |			\
+	 CHANNEL_HT40MINUS)
 
-struct ar5416IniArray {
-	u32 *ia_array;
-	u32 ia_rows;
-	u32 ia_columns;
+struct ath9k_channel {
+	struct ieee80211_channel *chan;
+	u16 channel;
+	u32 channelFlags;
+	u32 chanmode;
+	int32_t CalValid;
+	bool oneTimeCalsDone;
+	int8_t iCoff;
+	int8_t qCoff;
+	int16_t rawNoiseFloor;
 };
 
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {	\
-		(iniarray)->ia_array = (u32 *)(array);		\
-		(iniarray)->ia_rows = (rows);			\
-		(iniarray)->ia_columns = (columns);		\
-	} while (0)
+#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
+       (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
+       (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
+       (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_A_5MHZ_SPACED(_c)			\
+	((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&	\
+	 (((_c)->channel % 20) != 0) &&			\
+	 (((_c)->channel % 10) != 0))
 
-#define INI_RA(iniarray, row, column) \
-	(((iniarray)->ia_array)[(row) *	((iniarray)->ia_columns) + (column)])
+/* These macros check chanmode and not channelFlags */
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||	\
+			  ((_c)->chanmode == CHANNEL_G_HT20))
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||	\
+			  ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||	\
+			  ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||	\
+			  ((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
 
-#define INIT_CAL(_perCal) do {				\
-		(_perCal)->calState = CAL_WAITING;	\
-		(_perCal)->calNext = NULL;		\
-	} while (0)
+enum ath9k_power_mode {
+	ATH9K_PM_AWAKE = 0,
+	ATH9K_PM_FULL_SLEEP,
+	ATH9K_PM_NETWORK_SLEEP,
+	ATH9K_PM_UNDEFINED
+};
 
-#define INSERT_CAL(_ahp, _perCal)					\
-	do {								\
-		if ((_ahp)->ah_cal_list_last == NULL) {			\
-			(_ahp)->ah_cal_list =				\
-				(_ahp)->ah_cal_list_last = (_perCal);	\
-			((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
-		} else {						\
-			((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
-			(_ahp)->ah_cal_list_last = (_perCal);		\
-			(_perCal)->calNext = (_ahp)->ah_cal_list;	\
-		}							\
-	} while (0)
+enum ath9k_ant_setting {
+	ATH9K_ANT_VARIABLE = 0,
+	ATH9K_ANT_FIXED_A,
+	ATH9K_ANT_FIXED_B
+};
 
-enum hal_cal_types {
-	ADC_DC_INIT_CAL = 0x1,
-	ADC_GAIN_CAL = 0x2,
-	ADC_DC_CAL = 0x4,
-	IQ_MISMATCH_CAL = 0x8
+enum ath9k_tp_scale {
+	ATH9K_TP_SCALE_MAX = 0,
+	ATH9K_TP_SCALE_50,
+	ATH9K_TP_SCALE_25,
+	ATH9K_TP_SCALE_12,
+	ATH9K_TP_SCALE_MIN
 };
 
-enum hal_cal_state {
-	CAL_INACTIVE,
-	CAL_WAITING,
-	CAL_RUNNING,
-	CAL_DONE
+enum ser_reg_mode {
+	SER_REG_MODE_OFF = 0,
+	SER_REG_MODE_ON = 1,
+	SER_REG_MODE_AUTO = 2,
 };
 
-#define MIN_CAL_SAMPLES     1
-#define MAX_CAL_SAMPLES    64
-#define INIT_LOG_COUNT      5
-#define PER_MIN_LOG_COUNT   2
-#define PER_MAX_LOG_COUNT  10
+struct ath9k_beacon_state {
+	u32 bs_nexttbtt;
+	u32 bs_nextdtim;
+	u32 bs_intval;
+#define ATH9K_BEACON_PERIOD       0x0000ffff
+#define ATH9K_BEACON_ENA          0x00800000
+#define ATH9K_BEACON_RESET_TSF    0x01000000
+#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
+	u32 bs_dtimperiod;
+	u16 bs_cfpperiod;
+	u16 bs_cfpmaxduration;
+	u32 bs_cfpnext;
+	u16 bs_timoffset;
+	u16 bs_bmissthreshold;
+	u32 bs_sleepduration;
+	u32 bs_tsfoor_threshold;
+};
 
-struct hal_percal_data {
-	enum hal_cal_types calType;
-	u32 calNumSamples;
-	u32 calCountMax;
-	void (*calCollect) (struct ath_hal *);
-	void (*calPostProc) (struct ath_hal *, u8);
+struct chan_centers {
+	u16 synth_center;
+	u16 ctl_center;
+	u16 ext_center;
 };
 
-struct hal_cal_list {
-	const struct hal_percal_data *calData;
-	enum hal_cal_state calState;
-	struct hal_cal_list *calNext;
+enum {
+	ATH9K_RESET_POWER_ON,
+	ATH9K_RESET_WARM,
+	ATH9K_RESET_COLD,
 };
 
-/*
- * Enum to indentify the eeprom mappings
- */
-enum hal_eep_map {
-	EEP_MAP_DEFAULT = 0x0,
-	EEP_MAP_4KBITS,
-	EEP_MAP_MAX
+struct ath9k_hw_version {
+	u32 magic;
+	u16 devid;
+	u16 subvendorid;
+	u32 macVersion;
+	u16 macRev;
+	u16 phyRev;
+	u16 analog5GhzRev;
+	u16 analog2GhzRev;
 };
 
+struct ath_hw {
+	struct ath_softc *ah_sc;
+	struct ath9k_hw_version hw_version;
+	struct ath9k_ops_config config;
+	struct ath9k_hw_capabilities caps;
+	struct ath9k_regulatory regulatory;
+	struct ath9k_channel channels[38];
+	struct ath9k_channel *curchan;
 
-struct ath_hal_5416 {
-	struct ath_hal ah;
 	union {
 		struct ar5416_eeprom_def def;
 		struct ar5416_eeprom_4k map4k;
-	} ah_eeprom;
-	struct ar5416Stats ah_stats;
-	struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
-	void __iomem *ah_cal_mem;
+	} eeprom;
+	const struct eeprom_ops *eep_ops;
+	enum ath9k_eep_map eep_map;
 
-	u8 ah_macaddr[ETH_ALEN];
-	u8 ah_bssid[ETH_ALEN];
-	u8 ah_bssidmask[ETH_ALEN];
-	u16 ah_assocId;
+	bool sw_mgmt_crypto;
+	bool is_pciexpress;
+	u8 macaddr[ETH_ALEN];
+	u16 tx_trig_level;
+	u16 rfsilent;
+	u32 rfkill_gpio;
+	u32 rfkill_polarity;
+	u32 btactive_gpio;
+	u32 wlanactive_gpio;
+	u32 ah_flags;
 
-	int16_t ah_curchanRadIndex;
-	u32 ah_maskReg;
-	u32 ah_txOkInterruptMask;
-	u32 ah_txErrInterruptMask;
-	u32 ah_txDescInterruptMask;
-	u32 ah_txEolInterruptMask;
-	u32 ah_txUrnInterruptMask;
-	bool ah_chipFullSleep;
-	u32 ah_atimWindow;
-	u16 ah_antennaSwitchSwap;
-	enum ath9k_power_mode ah_powerMode;
-	enum ath9k_ant_setting ah_diversityControl;
+	enum nl80211_iftype opmode;
+	enum ath9k_power_mode power_mode;
+	enum ath9k_power_mode restore_mode;
+
+	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+	struct ar5416Stats stats;
+	struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+	int16_t curchan_rad_index;
+	u32 mask_reg;
+	u32 txok_interrupt_mask;
+	u32 txerr_interrupt_mask;
+	u32 txdesc_interrupt_mask;
+	u32 txeol_interrupt_mask;
+	u32 txurn_interrupt_mask;
+	bool chip_fullsleep;
+	u32 atim_window;
+	u16 antenna_switch_swap;
+	enum ath9k_ant_setting diversity_control;
 
 	/* Calibration */
-	enum hal_cal_types ah_suppCals;
-	struct hal_cal_list ah_iqCalData;
-	struct hal_cal_list ah_adcGainCalData;
-	struct hal_cal_list ah_adcDcCalInitData;
-	struct hal_cal_list ah_adcDcCalData;
-	struct hal_cal_list *ah_cal_list;
-	struct hal_cal_list *ah_cal_list_last;
-	struct hal_cal_list *ah_cal_list_curr;
-#define ah_totalPowerMeasI ah_Meas0.unsign
-#define ah_totalPowerMeasQ ah_Meas1.unsign
-#define ah_totalIqCorrMeas ah_Meas2.sign
-#define ah_totalAdcIOddPhase  ah_Meas0.unsign
-#define ah_totalAdcIEvenPhase ah_Meas1.unsign
-#define ah_totalAdcQOddPhase  ah_Meas2.unsign
-#define ah_totalAdcQEvenPhase ah_Meas3.unsign
-#define ah_totalAdcDcOffsetIOddPhase  ah_Meas0.sign
-#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
-#define ah_totalAdcDcOffsetQOddPhase  ah_Meas2.sign
-#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
+	enum hal_cal_types supp_cals;
+	struct hal_cal_list iq_caldata;
+	struct hal_cal_list adcgain_caldata;
+	struct hal_cal_list adcdc_calinitdata;
+	struct hal_cal_list adcdc_caldata;
+	struct hal_cal_list *cal_list;
+	struct hal_cal_list *cal_list_last;
+	struct hal_cal_list *cal_list_curr;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase  meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase  meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase  meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase  meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
 	union {
 		u32 unsign[AR5416_MAX_CHAINS];
 		int32_t sign[AR5416_MAX_CHAINS];
-	} ah_Meas0;
+	} meas0;
 	union {
 		u32 unsign[AR5416_MAX_CHAINS];
 		int32_t sign[AR5416_MAX_CHAINS];
-	} ah_Meas1;
+	} meas1;
 	union {
 		u32 unsign[AR5416_MAX_CHAINS];
 		int32_t sign[AR5416_MAX_CHAINS];
-	} ah_Meas2;
+	} meas2;
 	union {
 		u32 unsign[AR5416_MAX_CHAINS];
 		int32_t sign[AR5416_MAX_CHAINS];
-	} ah_Meas3;
-	u16 ah_CalSamples;
+	} meas3;
+	u16 cal_samples;
 
-	u32 ah_staId1Defaults;
-	u32 ah_miscMode;
+	u32 sta_id1_defaults;
+	u32 misc_mode;
 	enum {
 		AUTO_32KHZ,
 		USE_32KHZ,
 		DONT_USE_32KHZ,
-	} ah_enable32kHzClock;
+	} enable_32kHz_clock;
 
 	/* RF */
-	u32 *ah_analogBank0Data;
-	u32 *ah_analogBank1Data;
-	u32 *ah_analogBank2Data;
-	u32 *ah_analogBank3Data;
-	u32 *ah_analogBank6Data;
-	u32 *ah_analogBank6TPCData;
-	u32 *ah_analogBank7Data;
-	u32 *ah_addac5416_21;
-	u32 *ah_bank6Temp;
+	u32 *analogBank0Data;
+	u32 *analogBank1Data;
+	u32 *analogBank2Data;
+	u32 *analogBank3Data;
+	u32 *analogBank6Data;
+	u32 *analogBank6TPCData;
+	u32 *analogBank7Data;
+	u32 *addac5416_21;
+	u32 *bank6Temp;
 
-	int16_t ah_txPowerIndexOffset;
-	u32 ah_beaconInterval;
-	u32 ah_slottime;
-	u32 ah_acktimeout;
-	u32 ah_ctstimeout;
-	u32 ah_globaltxtimeout;
-	u8 ah_gBeaconRate;
-	u32 ah_gpioSelect;
-	u32 ah_polarity;
-	u32 ah_gpioBit;
+	int16_t txpower_indexoffset;
+	u32 beacon_interval;
+	u32 slottime;
+	u32 acktimeout;
+	u32 ctstimeout;
+	u32 globaltxtimeout;
+	u8 gbeacon_rate;
 
 	/* ANI */
-	u32 ah_procPhyErr;
-	bool ah_hasHwPhyCounters;
-	u32 ah_aniPeriod;
-	struct ar5416AniState *ah_curani;
-	struct ar5416AniState ah_ani[255];
-	int ah_totalSizeDesired[5];
-	int ah_coarseHigh[5];
-	int ah_coarseLow[5];
-	int ah_firpwr[5];
-	enum ath9k_ani_cmd ah_ani_function;
-
-	u32 ah_intrTxqs;
-	bool ah_intrMitigation;
-	enum ath9k_ht_extprotspacing ah_extprotspacing;
-	u8 ah_txchainmask;
-	u8 ah_rxchainmask;
-
-	struct ar5416IniArray ah_iniModes;
-	struct ar5416IniArray ah_iniCommon;
-	struct ar5416IniArray ah_iniBank0;
-	struct ar5416IniArray ah_iniBB_RfGain;
-	struct ar5416IniArray ah_iniBank1;
-	struct ar5416IniArray ah_iniBank2;
-	struct ar5416IniArray ah_iniBank3;
-	struct ar5416IniArray ah_iniBank6;
-	struct ar5416IniArray ah_iniBank6TPC;
-	struct ar5416IniArray ah_iniBank7;
-	struct ar5416IniArray ah_iniAddac;
-	struct ar5416IniArray ah_iniPcieSerdes;
-	struct ar5416IniArray ah_iniModesAdditional;
-	struct ar5416IniArray ah_iniModesRxGain;
-	struct ar5416IniArray ah_iniModesTxGain;
-	/* To indicate EEPROM mapping used */
-	enum hal_eep_map ah_eep_map;
-};
-#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
-
-#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
-
-#define ar5416RfDetach(ah) do {					\
-		if (AH5416(ah)->ah_rfHal.rfDetach != NULL)	\
-			AH5416(ah)->ah_rfHal.rfDetach(ah);	\
-	} while (0)
-
-#define ath9k_hw_use_flash(_ah)			\
-	(!(_ah->ah_flags & AH_USE_EEPROM))
-
-
-#define DO_DELAY(x) do {			\
-		if ((++(x) % 64) == 0)          \
-			udelay(1);		\
-	} while (0)
-
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
-		int r;							\
-		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
-			REG_WRITE(ah, INI_RA((iniarray), (r), 0),	\
-				  INI_RA((iniarray), r, (column)));	\
-			DO_DELAY(regWr);				\
-		}							\
-	} while (0)
+	u32 proc_phyerr;
+	bool has_hw_phycounters;
+	u32 aniperiod;
+	struct ar5416AniState *curani;
+	struct ar5416AniState ani[255];
+	int totalSizeDesired[5];
+	int coarse_high[5];
+	int coarse_low[5];
+	int firpwr[5];
+	enum ath9k_ani_cmd ani_function;
 
-#define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        1000
-#define COEF_SCALE_S                24
-#define HT40_CHANNEL_CENTER_SHIFT   10
+	u32 intr_txqs;
+	bool intr_mitigation;
+	enum ath9k_ht_extprotspacing extprotspacing;
+	u8 txchainmask;
+	u8 rxchainmask;
 
-#define AR5416_EEPROM_MAGIC_OFFSET  0x0
+	u32 originalGain[22];
+	int initPDADC;
+	int PDADCdelta;
 
-#define AR5416_EEPROM_S             2
-#define AR5416_EEPROM_OFFSET        0x2000
-#define AR5416_EEPROM_START_ADDR \
-	(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
-#define AR5416_EEPROM_MAX           0xae0
-#define ar5416_get_eep_ver(_ahp) \
-	(((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep_rev(_ahp) \
-	(((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
-#define ar5416_get_ntxchains(_txchainmask) \
-	(((_txchainmask >> 2) & 1) + \
-		((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+	struct ar5416IniArray iniModes;
+	struct ar5416IniArray iniCommon;
+	struct ar5416IniArray iniBank0;
+	struct ar5416IniArray iniBB_RfGain;
+	struct ar5416IniArray iniBank1;
+	struct ar5416IniArray iniBank2;
+	struct ar5416IniArray iniBank3;
+	struct ar5416IniArray iniBank6;
+	struct ar5416IniArray iniBank6TPC;
+	struct ar5416IniArray iniBank7;
+	struct ar5416IniArray iniAddac;
+	struct ar5416IniArray iniPcieSerdes;
+	struct ar5416IniArray iniModesAdditional;
+	struct ar5416IniArray iniModesRxGain;
+	struct ar5416IniArray iniModesTxGain;
+};
 
-/* EEPROM 4K bit map definations */
-#define ar5416_get_eep4k_ver(_ahp)   \
-    (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep4k_rev(_ahp)   \
-    (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
+/* Attach, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hw *ah);
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
+void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+		   bool bChannelChange);
+bool 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,
+			    u32 capability, u32 setting, int *status);
 
+/* Key Cache Management */
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+				 const struct ath9k_keyval *k,
+				 const u8 *mac);
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
 
-#ifdef __BIG_ENDIAN
-#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
-#define AR5416_EEPROM_MAGIC 0xa55a
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+			 u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah);
 #endif
+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);
 
-#define ATH9K_POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
-
-#define ATH9K_ANTENNA0_CHAINMASK        0x1
-#define ATH9K_ANTENNA1_CHAINMASK        0x2
-
-#define ATH9K_NUM_DMA_DEBUG_REGS        8
-#define ATH9K_NUM_QUEUES                10
-
-#define HAL_NOISE_IMMUNE_MAX            4
-#define HAL_SPUR_IMMUNE_MAX             7
-#define HAL_FIRST_STEP_MAX              2
-
-#define ATH9K_ANI_OFDM_TRIG_HIGH          500
-#define ATH9K_ANI_OFDM_TRIG_LOW           200
-#define ATH9K_ANI_CCK_TRIG_HIGH           200
-#define ATH9K_ANI_CCK_TRIG_LOW            100
-#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
-#define ATH9K_ANI_SPUR_IMMUNE_LVL         7
-#define ATH9K_ANI_FIRSTEP_LVL             0
-#define ATH9K_ANI_RSSI_THR_HIGH           40
-#define ATH9K_ANI_RSSI_THR_LOW            7
-#define ATH9K_ANI_PERIOD                  100
-
-#define AR_GPIOD_MASK                   0x00001FFF
-#define AR_GPIO_BIT(_gpio)              (1 << (_gpio))
-
-#define HAL_EP_RND(x, mul) \
-	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp) \
-	HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
-		ATH9K_RSSI_EP_MULTIPLIER)
-
-#define ah_mibStats     ah_stats.ast_mibstats
-
-#define AH_TIMEOUT         100000
-#define AH_TIME_QUANTUM        10
-
-#define AR_KEYTABLE_SIZE 128
-#define POWER_UP_TIME    200000
-
-#define EXT_ADDITIVE (0x8000)
-#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
-#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
-#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
-
-#define SUB_NUM_CTL_MODES_AT_5G_40 2
-#define SUB_NUM_CTL_MODES_AT_2G_40 3
-#define SPUR_RSSI_THRESH 40
-
-#define TU_TO_USEC(_tu)         ((_tu) << 10)
-
-#define CAB_TIMEOUT_VAL         10
-#define BEACON_TIMEOUT_VAL      10
-#define MIN_BEACON_TIMEOUT_VAL   1
-#define SLEEP_SLOP               3
-
-#define CCK_SIFS_TIME        10
-#define CCK_PREAMBLE_BITS   144
-#define CCK_PLCP_BITS        48
-
-#define OFDM_SIFS_TIME        16
-#define OFDM_PREAMBLE_TIME    20
-#define OFDM_PLCP_BITS        22
-#define OFDM_SYMBOL_TIME      4
-
-#define OFDM_SIFS_TIME_HALF     32
-#define OFDM_PREAMBLE_TIME_HALF 40
-#define OFDM_PLCP_BITS_HALF     22
-#define OFDM_SYMBOL_TIME_HALF   8
+/* 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, struct ath_rate_table *rates,
+			   u32 frameLen, u16 rateix, bool shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+				  struct ath9k_channel *chan,
+				  struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hw *ah);
+bool ath9k_hw_disable(struct ath_hw *ah);
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+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);
+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);
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+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_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);
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
 
-#define OFDM_SIFS_TIME_QUARTER      64
-#define OFDM_PREAMBLE_TIME_QUARTER  80
-#define OFDM_PLCP_BITS_QUARTER      22
-#define OFDM_SYMBOL_TIME_QUARTER    16
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
 
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
-			enum eeprom_param param);
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/initvals.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/initvals.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/initvals.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/initvals.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,8 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* AR5416 to Fowl ar5146.ini */
-static const u32 ar5416Modes_9100[][6] = {
+static const u32 ar5416Modes[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -79,7 +78,7 @@ static const u32 ar5416Modes_9100[][6] =
     { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
 };
 
-static const u32 ar5416Common_9100[][2] = {
+static const u32 ar5416Common[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020015 },
     { 0x00000034, 0x00000005 },
@@ -457,12 +456,12 @@ static const u32 ar5416Common_9100[][2]
     { 0x0000a3e0, 0x000001ce },
 };
 
-static const u32 ar5416Bank0_9100[][2] = {
+static const u32 ar5416Bank0[][2] = {
     { 0x000098b0, 0x1e5795e5 },
     { 0x000098e0, 0x02008020 },
 };
 
-static const u32 ar5416BB_RfGain_9100[][3] = {
+static const u32 ar5416BB_RfGain[][3] = {
     { 0x00009a00, 0x00000000, 0x00000000 },
     { 0x00009a04, 0x00000040, 0x00000040 },
     { 0x00009a08, 0x00000080, 0x00000080 },
@@ -529,21 +528,21 @@ static const u32 ar5416BB_RfGain_9100[][
     { 0x00009afc, 0x000000f9, 0x000000f9 },
 };
 
-static const u32 ar5416Bank1_9100[][2] = {
+static const u32 ar5416Bank1[][2] = {
     { 0x000098b0, 0x02108421 },
     { 0x000098ec, 0x00000008 },
 };
 
-static const u32 ar5416Bank2_9100[][2] = {
+static const u32 ar5416Bank2[][2] = {
     { 0x000098b0, 0x0e73ff17 },
     { 0x000098e0, 0x00000420 },
 };
 
-static const u32 ar5416Bank3_9100[][3] = {
+static const u32 ar5416Bank3[][3] = {
     { 0x000098f0, 0x01400018, 0x01c00018 },
 };
 
-static const u32 ar5416Bank6_9100[][3] = {
+static const u32 ar5416Bank6[][3] = {
 
     { 0x0000989c, 0x00000000, 0x00000000 },
     { 0x0000989c, 0x00000000, 0x00000000 },
@@ -580,7 +579,7 @@ static const u32 ar5416Bank6_9100[][3] =
     { 0x000098d0, 0x0000000f, 0x0010000f },
 };
 
-static const u32 ar5416Bank6TPC_9100[][3] = {
+static const u32 ar5416Bank6TPC[][3] = {
     { 0x0000989c, 0x00000000, 0x00000000 },
     { 0x0000989c, 0x00000000, 0x00000000 },
     { 0x0000989c, 0x00000000, 0x00000000 },
@@ -616,13 +615,13 @@ static const u32 ar5416Bank6TPC_9100[][3
     { 0x000098d0, 0x0000000f, 0x0010000f },
 };
 
-static const u32 ar5416Bank7_9100[][2] = {
+static const u32 ar5416Bank7[][2] = {
     { 0x0000989c, 0x00000500 },
     { 0x0000989c, 0x00000800 },
     { 0x000098cc, 0x0000000e },
 };
 
-static const u32 ar5416Addac_9100[][2] = {
+static const u32 ar5416Addac[][2] = {
     {0x0000989c,  0x00000000 },
     {0x0000989c,  0x00000003 },
     {0x0000989c,  0x00000000 },
@@ -659,11 +658,10 @@ static const u32 ar5416Addac_9100[][2] =
     {0x0000989c,  0x00000000 },
     {0x0000989c,  0x00000000 },
     {0x0000989c,  0x00000000 },
-    {0x000098c4,  0x00000000 },
+    {0x000098cc,  0x00000000 },
 };
 
-/* ar5416 - howl ar5416_howl.ini */
-static const u32 ar5416Modes[][6] = {
+static const u32 ar5416Modes_9100[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -737,7 +735,7 @@ static const u32 ar5416Modes[][6] = {
     { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
 };
 
-static const u32 ar5416Common[][2] = {
+static const u32 ar5416Common_9100[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020015 },
     { 0x00000034, 0x00000005 },
@@ -1111,12 +1109,12 @@ static const u32 ar5416Common[][2] = {
     { 0x0000a3e0, 0x000001ce },
 };
 
-static const u32 ar5416Bank0[][2] = {
+static const u32 ar5416Bank0_9100[][2] = {
     { 0x000098b0, 0x1e5795e5 },
     { 0x000098e0, 0x02008020 },
 };
 
-static const u32 ar5416BB_RfGain[][3] = {
+static const u32 ar5416BB_RfGain_9100[][3] = {
     { 0x00009a00, 0x00000000, 0x00000000 },
     { 0x00009a04, 0x00000040, 0x00000040 },
     { 0x00009a08, 0x00000080, 0x00000080 },
@@ -1183,21 +1181,21 @@ static const u32 ar5416BB_RfGain[][3] =
     { 0x00009afc, 0x000000f9, 0x000000f9 },
 };
 
-static const u32 ar5416Bank1[][2] = {
+static const u32 ar5416Bank1_9100[][2] = {
     { 0x000098b0, 0x02108421},
     { 0x000098ec, 0x00000008},
 };
 
-static const u32 ar5416Bank2[][2] = {
+static const u32 ar5416Bank2_9100[][2] = {
     { 0x000098b0, 0x0e73ff17},
     { 0x000098e0, 0x00000420},
 };
 
-static const u32 ar5416Bank3[][3] = {
+static const u32 ar5416Bank3_9100[][3] = {
     { 0x000098f0, 0x01400018, 0x01c00018 },
 };
 
-static const u32 ar5416Bank6[][3] = {
+static const u32 ar5416Bank6_9100[][3] = {
 
     { 0x0000989c, 0x00000000, 0x00000000 },
     { 0x0000989c, 0x00000000, 0x00000000 },
@@ -1235,7 +1233,7 @@ static const u32 ar5416Bank6[][3] = {
 };
 
 
-static const u32 ar5416Bank6TPC[][3] = {
+static const u32 ar5416Bank6TPC_9100[][3] = {
 
     { 0x0000989c, 0x00000000, 0x00000000 },
     { 0x0000989c, 0x00000000, 0x00000000 },
@@ -1272,13 +1270,13 @@ static const u32 ar5416Bank6TPC[][3] = {
     { 0x000098d0, 0x0000000f, 0x0010000f },
 };
 
-static const u32 ar5416Bank7[][2] = {
+static const u32 ar5416Bank7_9100[][2] = {
     { 0x0000989c, 0x00000500 },
     { 0x0000989c, 0x00000800 },
     { 0x000098cc, 0x0000000e },
 };
 
-static const u32 ar5416Addac[][2] = {
+static const u32 ar5416Addac_9100[][2] = {
     {0x0000989c, 0x00000000 },
     {0x0000989c, 0x00000000 },
     {0x0000989c, 0x00000000 },
@@ -1313,7 +1311,6 @@ static const u32 ar5416Addac[][2] = {
     {0x000098cc, 0x00000000 },
 };
 
-/* AR5416 9160 Sowl ar5416_sowl.ini */
 static const u32 ar5416Modes_9160[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -2549,6 +2546,8 @@ static const u32 ar9280Modes_9280_2[][6]
     { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
     { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
     { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
     { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
@@ -2587,7 +2586,6 @@ static const u32 ar9280Modes_9280_2[][6]
     { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
     { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
     { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
-    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
     { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
@@ -2719,7 +2717,6 @@ static const u32 ar9280Common_9280_2[][2
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -2735,7 +2732,6 @@ static const u32 ar9280Common_9280_2[][2
     { 0x00008178, 0x00000100 },
     { 0x0000817c, 0x00000000 },
     { 0x000081c0, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
     { 0x000081ec, 0x00000000 },
     { 0x000081f0, 0x00000000 },
     { 0x000081f4, 0x00000000 },
@@ -2817,7 +2813,7 @@ static const u32 ar9280Common_9280_2[][2
     { 0x00009958, 0x2108ecff },
     { 0x00009940, 0x14750604 },
     { 0x0000c95c, 0x004b6a8e },
-    { 0x00009968, 0x000003ce },
+    { 0x0000c968, 0x000003ce },
     { 0x00009970, 0x190fb515 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
@@ -2909,16 +2905,12 @@ static const u32 ar9280Common_9280_2[][2
     { 0x0000780c, 0x21084210 },
     { 0x00007810, 0x6d801300 },
     { 0x00007818, 0x07e41000 },
-    { 0x0000781c, 0x00392000 },
-    { 0x00007820, 0x92592480 },
     { 0x00007824, 0x00040000 },
     { 0x00007828, 0xdb005012 },
     { 0x0000782c, 0x04924914 },
     { 0x00007830, 0x21084210 },
     { 0x00007834, 0x6d801300 },
     { 0x0000783c, 0x07e40000 },
-    { 0x00007840, 0x00392000 },
-    { 0x00007844, 0x92592480 },
     { 0x00007848, 0x00100000 },
     { 0x0000784c, 0x773f0567 },
     { 0x00007850, 0x54214514 },
@@ -2954,7 +2946,6 @@ static const u32 ar9280Modes_fast_clock_
     { 0x00009844, 0x03721821, 0x03721821 },
     { 0x00009914, 0x00000898, 0x00001130 },
     { 0x00009918, 0x0000000b, 0x00000016 },
-    { 0x00009944, 0xdfbc1210, 0xdfbc1210 },
 };
 
 static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
@@ -3366,21 +3357,26 @@ static const u32 ar9280Modes_high_power_
     { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a },
     { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 },
     { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
-    { 0x0000a324, 0x00020092, 0x00020092, 0x00022411, 0x00022411, 0x00022411 },
-    { 0x0000a328, 0x0002410a, 0x0002410a, 0x00025413, 0x00025413, 0x00025413 },
-    { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00029811, 0x00029811, 0x00029811 },
-    { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002c813, 0x0002c813, 0x0002c813 },
-    { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
-    { 0x0000a338, 0x000321ec, 0x000321ec, 0x00035a50, 0x00035a50, 0x00035a50 },
-    { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
-    { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
-    { 0x0000a344, 0x000321ec, 0x000321ec, 0x00042e92, 0x00042e92, 0x00042e92 },
-    { 0x0000a348, 0x000321ec, 0x000321ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
-    { 0x0000a34c, 0x000321ec, 0x000321ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
-    { 0x0000a350, 0x000321ec, 0x000321ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
-    { 0x0000a354, 0x000321ec, 0x000321ec, 0x00053fd5, 0x00053fd5, 0x00053fd5 },
+    { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
+    { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
+    { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
+    { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
+    { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
+    { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
+    { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
+    { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
+    { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
+    { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
+    { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
+    { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
+    { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
     { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
     { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+    { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+    { 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 },
 };
 
@@ -3409,6 +3405,11 @@ static const u32 ar9280Modes_original_tx
     { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
     { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
     { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
+    { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+    { 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 },
 };
 
@@ -4120,6 +4121,7 @@ static const u_int32_t ar9285PciePhy_clk
     {0x00004044,  0x00000000 },
 };
 
+/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
 static const u_int32_t ar9285Modes_9285_1_2[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4135,11 +4137,11 @@ static const u_int32_t ar9285Modes_9285_
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
     { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
-    { 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057, 0x00001059 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
     { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
     { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
     { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
     { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
@@ -4154,291 +4156,272 @@ static const u_int32_t ar9285Modes_9285_
     { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
-    { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
-    { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
-    { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
-    { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
-    { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
-    { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
-    { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
-    { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
-    { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
-    { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
-    { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
-    { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
-    { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
-    { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
-    { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
-    { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
-    { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
-    { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
-    { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
-    { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
-    { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
-    { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
-    { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
-    { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
-    { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
-    { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+    { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
     { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
     { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
     { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
     { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
     { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
     { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
-    { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
-    { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
-    { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
-    { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
-    { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
-    { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
-    { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
-    { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
-    { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
-    { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
-    { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
-    { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
-    { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
-    { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
-    { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
-    { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
-    { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
-    { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
-    { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
-    { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
-    { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
-    { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
-    { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
-    { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
-    { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
-    { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
-    { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
-    { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
-    { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
-    { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
-    { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
-    { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
-    { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
-    { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
-    { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
-    { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
-    { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
-    { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
-    { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
-    { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
-    { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
-    { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
-    { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
-    { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
-    { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
-    { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
-    { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
-    { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
-    { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
-    { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
-    { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
-    { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
-    { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
-    { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
-    { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
-    { 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
-    { 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
-    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
-    { 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
-    { 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
-    { 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
-    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
-    { 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
-    { 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
-    { 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
-    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
-    { 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
-    { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
-    { 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
-    { 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
-    { 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
-    { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
-    { 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
-    { 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
-    { 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
-    { 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
-    { 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
-    { 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
-    { 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
-    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
-    { 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
-    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
-    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
-    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
-    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
-    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
-    { 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
-    { 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
-    { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
-    { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
-    { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
-    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
-    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
-    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
-    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
-    { 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
-    { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
-    { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
-    { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
-    { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
-    { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
-    { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
-    { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
-    { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
-    { 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
-    { 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
-    { 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
-    { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
-    { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
-    { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
-    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
-    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
-    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
-    { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
-    { 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
-    { 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
-    { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
-    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
-    { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
-    { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
-    { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
-    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
-    { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
-    { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
-    { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
-    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
-    { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
-    { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
-    { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
-    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
-    { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
-    { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
-    { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
-    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
-    { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
-    { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
-    { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
-    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
-    { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
-    { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
-    { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
-    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
     { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
-    { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
     { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
     { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
     { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
-    { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de, 0x00000000 },
-    { 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e, 0x00000000 },
-    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e, 0x00000000 },
-    { 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
@@ -4568,7 +4551,7 @@ static const u_int32_t ar9285Common_9285
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
+    { 0x00008120, 0x08f04810 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -4584,7 +4567,7 @@ static const u_int32_t ar9285Common_9285
     { 0x00008178, 0x00000100 },
     { 0x0000817c, 0x00000000 },
     { 0x000081c0, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
+    { 0x000081d0, 0x0000320a },
     { 0x000081ec, 0x00000000 },
     { 0x000081f0, 0x00000000 },
     { 0x000081f4, 0x00000000 },
@@ -4679,7 +4662,7 @@ static const u_int32_t ar9285Common_9285
     { 0x000099a0, 0x00000000 },
     { 0x000099a4, 0x00000001 },
     { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x2def1000 },
+    { 0x000099ac, 0x2def0400 },
     { 0x000099b0, 0x03051000 },
     { 0x000099b4, 0x00000820 },
     { 0x000099dc, 0x00000000 },
@@ -4688,7 +4671,7 @@ static const u_int32_t ar9285Common_9285
     { 0x000099e8, 0x3c466478 },
     { 0x000099ec, 0x0cc80caa },
     { 0x000099f0, 0x00000000 },
-    { 0x0000a208, 0x803e6788 },
+    { 0x0000a208, 0x803e68c8 },
     { 0x0000a210, 0x4080a333 },
     { 0x0000a214, 0x00206c10 },
     { 0x0000a218, 0x009c4060 },
@@ -4708,8 +4691,6 @@ static const u_int32_t ar9285Common_9285
     { 0x0000a268, 0x00000000 },
     { 0x0000a26c, 0x0ebae9e6 },
     { 0x0000d270, 0x0d820820 },
-    { 0x0000a278, 0x318c6318 },
-    { 0x0000a27c, 0x050c0318 },
     { 0x0000d35c, 0x07ffffef },
     { 0x0000d360, 0x0fffffe7 },
     { 0x0000d364, 0x17ffffe5 },
@@ -4724,8 +4705,6 @@ static const u_int32_t ar9285Common_9285
     { 0x0000a388, 0x0c000000 },
     { 0x0000a38c, 0x20202020 },
     { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x318c6318 },
-    { 0x0000a398, 0x00000318 },
     { 0x0000a39c, 0x00000001 },
     { 0x0000a3a0, 0x00000000 },
     { 0x0000a3a4, 0x00000000 },
@@ -4740,8 +4719,6 @@ static const u_int32_t ar9285Common_9285
     { 0x0000a3cc, 0x20202020 },
     { 0x0000a3d0, 0x20202020 },
     { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x318c6318 },
-    { 0x0000a3e0, 0x00000318 },
     { 0x0000a3e4, 0x00000000 },
     { 0x0000a3e8, 0x18c43433 },
     { 0x0000a3ec, 0x00f70081 },
@@ -4752,13 +4729,11 @@ static const u_int32_t ar9285Common_9285
     { 0x00007810, 0x71c0d388 },
     { 0x00007814, 0x924934a8 },
     { 0x0000781c, 0x00000000 },
-    { 0x00007820, 0x00000c04 },
     { 0x00007824, 0x00d86fff },
     { 0x00007828, 0x26d2491b },
     { 0x0000782c, 0x6e36d97b },
     { 0x00007830, 0xedb6d96e },
     { 0x00007834, 0x71400087 },
-    { 0x00007838, 0xfac68801 },
     { 0x0000783c, 0x0001fffe },
     { 0x00007840, 0xffeb1a20 },
     { 0x00007844, 0x000c0db6 },
@@ -4771,10 +4746,81 @@ static const u_int32_t ar9285Common_9285
     { 0x00007860, 0x21084210 },
     { 0x00007864, 0xf7d7ffde },
     { 0x00007868, 0xc2034080 },
-    { 0x0000786c, 0x48609eb4 },
     { 0x00007870, 0x10142c00 },
 };
 
+static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
+    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
+    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+};
+
+static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
+    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
+    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
+    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
+    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+};
+
 static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
     {0x00004040,  0x9248fd00 },
     {0x00004040,  0x24924924 },
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/mac.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,45 +14,40 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
 
-static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
 					struct ath9k_tx_queue_info *qi)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
 		"tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
-		ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
-		ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
-		ahp->ah_txUrnInterruptMask);
+		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(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
-		  | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
+		  SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
+		  | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
 	REG_WRITE(ah, AR_IMR_S1,
-		  SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
-		  | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
+		  SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+		  | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
 	REG_RMW_FIELD(ah, AR_IMR_S2,
-		      AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
+		      AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
 }
 
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
 {
 	return REG_READ(ah, AR_QTXDP(q));
 }
 
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
 {
 	REG_WRITE(ah, AR_QTXDP(q), txdp);
 
 	return true;
 }
 
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
 {
 	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
 
@@ -61,7 +56,7 @@ bool ath9k_hw_txstart(struct ath_hal *ah
 	return true;
 }
 
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
 {
 	u32 npend;
 
@@ -75,16 +70,15 @@ u32 ath9k_hw_numtxpending(struct ath_hal
 	return npend;
 }
 
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 txcfg, curLevel, newLevel;
 	enum ath9k_int omask;
 
-	if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
+	if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
 		return false;
 
-	omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+	omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
 
 	txcfg = REG_READ(ah, AR_TXCFG);
 	curLevel = MS(txcfg, AR_FTRIG);
@@ -100,21 +94,38 @@ bool ath9k_hw_updatetxtriglevel(struct a
 
 	ath9k_hw_set_interrupts(ah, omask);
 
-	ah->ah_txTrigLevel = newLevel;
+	ah->tx_trig_level = newLevel;
 
 	return newLevel != curLevel;
 }
 
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+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 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, "invalid queue num %u\n", q);
+		return false;
+	}
+
+	qi = &ah->txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+		return false;
+	}
 
 	REG_WRITE(ah, AR_Q_TXD, 1 << q);
 
-	for (wait = 1000; wait != 0; wait--) {
+	for (wait = wait_time; wait != 0; wait--) {
 		if (ath9k_hw_numtxpending(ah, q) == 0)
 			break;
-		udelay(100);
+		udelay(ATH9K_TIME_QUANTUM);
 	}
 
 	if (ath9k_hw_numtxpending(ah, q)) {
@@ -144,8 +155,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *
 		udelay(200);
 		REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
 
-		wait = 1000;
-
+		wait = wait_time;
 		while (ath9k_hw_numtxpending(ah, q)) {
 			if ((--wait) == 0) {
 				DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
@@ -153,18 +163,20 @@ bool ath9k_hw_stoptxdma(struct ath_hal *
 					"msec after killing last frame\n");
 				break;
 			}
-			udelay(100);
+			udelay(ATH9K_TIME_QUANTUM);
 		}
 
 		REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
 	}
 
 	REG_WRITE(ah, AR_Q_TXD, 0);
-
 	return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
 }
 
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
 			 bool lastSeg, const struct ath_desc *ds0)
 {
@@ -192,7 +204,7 @@ bool ath9k_hw_filltxdesc(struct ath_hal
 	return true;
 }
 
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -203,7 +215,7 @@ void ath9k_hw_cleartxdesc(struct ath_hal
 	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 }
 
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -273,19 +285,18 @@ int ath9k_hw_txprocdesc(struct ath_hal *
 	ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
 	ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
 	ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-	ds->ds_txstat.ts_antenna = 1;
+	ds->ds_txstat.ts_antenna = 0;
 
 	return 0;
 }
 
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
 			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
 			    u32 keyIx, enum ath9k_key_type keyType, u32 flags)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
-	struct ath_hal_5416 *ahp = AH5416(ah);
 
-	txPower += ahp->ah_txPowerIndexOffset;
+	txPower += ah->txpower_indexoffset;
 	if (txPower > 63)
 		txPower = 63;
 
@@ -314,7 +325,7 @@ void ath9k_hw_set11n_txdesc(struct ath_h
 	}
 }
 
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
 				  struct ath_desc *lastds,
 				  u32 durUpdateEn, u32 rtsctsRate,
 				  u32 rtsctsDuration,
@@ -325,9 +336,6 @@ void ath9k_hw_set11n_ratescenario(struct
 	struct ar5416_desc *last_ads = AR5416DESC(lastds);
 	u32 ds_ctl0;
 
-	(void) nseries;
-	(void) rtsctsDuration;
-
 	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
 		ds_ctl0 = ads->ds_ctl0;
 
@@ -372,7 +380,7 @@ void ath9k_hw_set11n_ratescenario(struct
 	last_ads->ds_ctl3 = ads->ds_ctl3;
 }
 
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
 				u32 aggrLen)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
@@ -382,7 +390,7 @@ void ath9k_hw_set11n_aggr_first(struct a
 	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
 }
 
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
 				 u32 numDelims)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
@@ -396,7 +404,7 @@ void ath9k_hw_set11n_aggr_middle(struct
 	ads->ds_ctl6 = ctl6;
 }
 
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
@@ -405,14 +413,14 @@ void ath9k_hw_set11n_aggr_last(struct at
 	ads->ds_ctl6 &= ~AR_PadDelim;
 }
 
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
 
 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
 
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
 				   u32 burstDuration)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
@@ -421,7 +429,7 @@ void ath9k_hw_set11n_burstduration(struc
 	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
 }
 
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
 				     u32 vmf)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
@@ -432,20 +440,17 @@ void ath9k_hw_set11n_virtualmorefrag(str
 		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
 }
 
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	*txqs &= ahp->ah_intrTxqs;
-	ahp->ah_intrTxqs &= ~(*txqs);
+	*txqs &= ah->intr_txqs;
+	ah->intr_txqs &= ~(*txqs);
 }
 
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
 			    const struct ath9k_tx_queue_info *qinfo)
 {
 	u32 cw;
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
 	if (q >= pCap->total_queues) {
@@ -453,7 +458,7 @@ bool ath9k_hw_set_txq_props(struct ath_h
 		return false;
 	}
 
-	qi = &ahp->ah_txq[q];
+	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
 		return false;
@@ -509,11 +514,10 @@ bool ath9k_hw_set_txq_props(struct ath_h
 	return true;
 }
 
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
 			    struct ath9k_tx_queue_info *qinfo)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
 	if (q >= pCap->total_queues) {
@@ -521,7 +525,7 @@ bool ath9k_hw_get_txq_props(struct ath_h
 		return false;
 	}
 
-	qi = &ahp->ah_txq[q];
+	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
 		return false;
@@ -545,12 +549,11 @@ bool ath9k_hw_get_txq_props(struct ath_h
 	return true;
 }
 
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
 			  const struct ath9k_tx_queue_info *qinfo)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	struct ath9k_tx_queue_info *qi;
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	int q;
 
 	switch (type) {
@@ -568,7 +571,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal
 		break;
 	case ATH9K_TX_QUEUE_DATA:
 		for (q = 0; q < pCap->total_queues; q++)
-			if (ahp->ah_txq[q].tqi_type ==
+			if (ah->txq[q].tqi_type ==
 			    ATH9K_TX_QUEUE_INACTIVE)
 				break;
 		if (q == pCap->total_queues) {
@@ -584,7 +587,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal
 
 	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
 
-	qi = &ahp->ah_txq[q];
+	qi = &ah->txq[q];
 	if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 			"tx queue %u already active\n", q);
@@ -611,17 +614,16 @@ int ath9k_hw_setuptxqueue(struct ath_hal
 	return q;
 }
 
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	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, "invalid queue num %u\n", q);
 		return false;
 	}
-	qi = &ahp->ah_txq[q];
+	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
 		return false;
@@ -630,21 +632,20 @@ bool ath9k_hw_releasetxqueue(struct ath_
 	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
 
 	qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
-	ahp->ah_txOkInterruptMask &= ~(1 << q);
-	ahp->ah_txErrInterruptMask &= ~(1 << q);
-	ahp->ah_txDescInterruptMask &= ~(1 << q);
-	ahp->ah_txEolInterruptMask &= ~(1 << q);
-	ahp->ah_txUrnInterruptMask &= ~(1 << q);
+	ah->txok_interrupt_mask &= ~(1 << q);
+	ah->txerr_interrupt_mask &= ~(1 << q);
+	ah->txdesc_interrupt_mask &= ~(1 << q);
+	ah->txeol_interrupt_mask &= ~(1 << q);
+	ah->txurn_interrupt_mask &= ~(1 << q);
 	ath9k_hw_set_txq_interrupts(ah, qi);
 
 	return true;
 }
 
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath9k_channel *chan = ah->curchan;
 	struct ath9k_tx_queue_info *qi;
 	u32 cwMin, chanCwMin, value;
 
@@ -653,7 +654,7 @@ bool ath9k_hw_resettxqueue(struct ath_ha
 		return false;
 	}
 
-	qi = &ahp->ah_txq[q];
+	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
 		return true;
@@ -741,9 +742,9 @@ bool ath9k_hw_resettxqueue(struct ath_ha
 			  | AR_Q_MISC_CBR_INCR_DIS1
 			  | AR_Q_MISC_CBR_INCR_DIS0);
 		value = (qi->tqi_readyTime -
-			 (ah->ah_config.sw_beacon_response_time -
-			  ah->ah_config.dma_beacon_response_time) -
-			 ah->ah_config.additional_swba_backoff) * 1024;
+			 (ah->config.sw_beacon_response_time -
+			  ah->config.dma_beacon_response_time) -
+			 ah->config.additional_swba_backoff) * 1024;
 		REG_WRITE(ah, AR_QRDYTIMECFG(q),
 			  value | AR_Q_RDYTIMECFG_EN);
 		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
@@ -771,31 +772,31 @@ bool ath9k_hw_resettxqueue(struct ath_ha
 	}
 
 	if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
-		ahp->ah_txOkInterruptMask |= 1 << q;
+		ah->txok_interrupt_mask |= 1 << q;
 	else
-		ahp->ah_txOkInterruptMask &= ~(1 << q);
+		ah->txok_interrupt_mask &= ~(1 << q);
 	if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
-		ahp->ah_txErrInterruptMask |= 1 << q;
+		ah->txerr_interrupt_mask |= 1 << q;
 	else
-		ahp->ah_txErrInterruptMask &= ~(1 << q);
+		ah->txerr_interrupt_mask &= ~(1 << q);
 	if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
-		ahp->ah_txDescInterruptMask |= 1 << q;
+		ah->txdesc_interrupt_mask |= 1 << q;
 	else
-		ahp->ah_txDescInterruptMask &= ~(1 << q);
+		ah->txdesc_interrupt_mask &= ~(1 << q);
 	if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
-		ahp->ah_txEolInterruptMask |= 1 << q;
+		ah->txeol_interrupt_mask |= 1 << q;
 	else
-		ahp->ah_txEolInterruptMask &= ~(1 << q);
+		ah->txeol_interrupt_mask &= ~(1 << q);
 	if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
-		ahp->ah_txUrnInterruptMask |= 1 << q;
+		ah->txurn_interrupt_mask |= 1 << q;
 	else
-		ahp->ah_txUrnInterruptMask &= ~(1 << q);
+		ah->txurn_interrupt_mask &= ~(1 << q);
 	ath9k_hw_set_txq_interrupts(ah, qi);
 
 	return true;
 }
 
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 			u32 pa, struct ath_desc *nds, u64 tsf)
 {
 	struct ar5416_desc ads;
@@ -860,11 +861,11 @@ int ath9k_hw_rxprocdesc(struct ath_hal *
 	return 0;
 }
 
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
-	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 
 	ads->ds_ctl1 = size & AR_BufLen;
 	if (flags & ATH9K_RXDESC_INTREQ)
@@ -877,7 +878,7 @@ bool ath9k_hw_setuprxdesc(struct ath_hal
 	return true;
 }
 
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
 {
 	u32 reg;
 
@@ -885,7 +886,8 @@ bool ath9k_hw_setrxabort(struct ath_hal
 		REG_SET_BIT(ah, AR_DIAG_SW,
 			    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
-		if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
+		if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
+				   0, AH_WAIT_TIMEOUT)) {
 			REG_CLR_BIT(ah, AR_DIAG_SW,
 				    (AR_DIAG_RX_DIS |
 				     AR_DIAG_RX_ABORT));
@@ -904,17 +906,17 @@ bool ath9k_hw_setrxabort(struct ath_hal
 	return true;
 }
 
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
 {
 	REG_WRITE(ah, AR_RXDP, rxdp);
 }
 
-void ath9k_hw_rxena(struct ath_hal *ah)
+void ath9k_hw_rxena(struct ath_hw *ah)
 {
 	REG_WRITE(ah, AR_CR, AR_CR_RXE);
 }
 
-void ath9k_hw_startpcureceive(struct ath_hal *ah)
+void ath9k_hw_startpcureceive(struct ath_hw *ah)
 {
 	ath9k_enable_mib_counters(ah);
 
@@ -923,24 +925,41 @@ void ath9k_hw_startpcureceive(struct ath
 	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 }
 
-void ath9k_hw_stoppcurecv(struct ath_hal *ah)
+void ath9k_hw_stoppcurecv(struct ath_hw *ah)
 {
 	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
 
 	ath9k_hw_disable_mib_counters(ah);
 }
 
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
 {
+#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
+#define AH_RX_TIME_QUANTUM     100     /* usec */
+
+	int i;
+
 	REG_WRITE(ah, AR_CR, AR_CR_RXD);
 
-	if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+	/* Wait for rx enable bit to go low */
+	for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+		if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+			break;
+		udelay(AH_TIME_QUANTUM);
+	}
+
+	if (i == 0) {
 		DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-			"dma failed to stop in 10ms\n"
-			"AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
-			REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+			"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;
 	}
+
+#undef AH_RX_TIME_QUANTUM
+#undef AH_RX_STOP_DMA_TIMEOUT
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/mac.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/mac.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/mac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/mac.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,680 @@
+/*
+ * 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 MAC_H
+#define MAC_H
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ?		\
+				MS(ads->ds_rxstatus0, AR_RxRate) :	\
+				(ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define set11nTries(_series, _index) \
+	(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define set11nRate(_series, _index) \
+	(SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define set11nPktDurRTSCTS(_series, _index)				\
+	(SM((_series)[_index].PktDuration, AR_PacketDur##_index) |	\
+	 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?	\
+	  AR_RTSCTSQual##_index : 0))
+
+#define set11nRateFlags(_series, _index)				\
+	(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?		\
+	  AR_2040_##_index : 0)						\
+	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?	\
+	   AR_GI##_index : 0)						\
+	 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+
+#define CCK_SIFS_TIME        10
+#define CCK_PREAMBLE_BITS   144
+#define CCK_PLCP_BITS        48
+
+#define OFDM_SIFS_TIME        16
+#define OFDM_PREAMBLE_TIME    20
+#define OFDM_PLCP_BITS        22
+#define OFDM_SYMBOL_TIME      4
+
+#define OFDM_SIFS_TIME_HALF     32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF     22
+#define OFDM_SYMBOL_TIME_HALF   8
+
+#define OFDM_SIFS_TIME_QUARTER      64
+#define OFDM_PREAMBLE_TIME_QUARTER  80
+#define OFDM_PLCP_BITS_QUARTER      22
+#define OFDM_SYMBOL_TIME_QUARTER    16
+
+#define INIT_AIFS       2
+#define INIT_CWMIN      15
+#define INIT_CWMIN_11B  31
+#define INIT_CWMAX      1023
+#define INIT_SH_RETRY   10
+#define INIT_LG_RETRY   10
+#define INIT_SSH_RETRY  32
+#define INIT_SLG_RETRY  32
+
+#define ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#define ATH9K_TXERR_XRETRY         0x01
+#define ATH9K_TXERR_FILT           0x02
+#define ATH9K_TXERR_FIFO           0x04
+#define ATH9K_TXERR_XTXOP          0x08
+#define ATH9K_TXERR_TIMER_EXPIRED  0x10
+
+#define ATH9K_TX_BA                0x01
+#define ATH9K_TX_PWRMGMT           0x02
+#define ATH9K_TX_DESC_CFG_ERR      0x04
+#define ATH9K_TX_DATA_UNDERRUN     0x08
+#define ATH9K_TX_DELIM_UNDERRUN    0x10
+#define ATH9K_TX_SW_ABORTED        0x40
+#define ATH9K_TX_SW_FILTERED       0x80
+
+#define MIN_TX_FIFO_THRESHOLD   0x1
+#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
+#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
+
+struct ath_tx_status {
+	u32 ts_tstamp;
+	u16 ts_seqnum;
+	u8 ts_status;
+	u8 ts_ratecode;
+	u8 ts_rateindex;
+	int8_t ts_rssi;
+	u8 ts_shortretry;
+	u8 ts_longretry;
+	u8 ts_virtcol;
+	u8 ts_antenna;
+	u8 ts_flags;
+	int8_t ts_rssi_ctl0;
+	int8_t ts_rssi_ctl1;
+	int8_t ts_rssi_ctl2;
+	int8_t ts_rssi_ext0;
+	int8_t ts_rssi_ext1;
+	int8_t ts_rssi_ext2;
+	u8 pad[3];
+	u32 ba_low;
+	u32 ba_high;
+	u32 evm0;
+	u32 evm1;
+	u32 evm2;
+};
+
+struct ath_rx_status {
+	u32 rs_tstamp;
+	u16 rs_datalen;
+	u8 rs_status;
+	u8 rs_phyerr;
+	int8_t rs_rssi;
+	u8 rs_keyix;
+	u8 rs_rate;
+	u8 rs_antenna;
+	u8 rs_more;
+	int8_t rs_rssi_ctl0;
+	int8_t rs_rssi_ctl1;
+	int8_t rs_rssi_ctl2;
+	int8_t rs_rssi_ext0;
+	int8_t rs_rssi_ext1;
+	int8_t rs_rssi_ext2;
+	u8 rs_isaggr;
+	u8 rs_moreaggr;
+	u8 rs_num_delims;
+	u8 rs_flags;
+	u32 evm0;
+	u32 evm1;
+	u32 evm2;
+};
+
+#define ATH9K_RXERR_CRC           0x01
+#define ATH9K_RXERR_PHY           0x02
+#define ATH9K_RXERR_FIFO          0x04
+#define ATH9K_RXERR_DECRYPT       0x08
+#define ATH9K_RXERR_MIC           0x10
+
+#define ATH9K_RX_MORE             0x01
+#define ATH9K_RX_MORE_AGGR        0x02
+#define ATH9K_RX_GI               0x04
+#define ATH9K_RX_2040             0x08
+#define ATH9K_RX_DELIM_CRC_PRE    0x10
+#define ATH9K_RX_DELIM_CRC_POST   0x20
+#define ATH9K_RX_DECRYPT_BUSY     0x40
+
+#define ATH9K_RXKEYIX_INVALID	((u8)-1)
+#define ATH9K_TXKEYIX_INVALID	((u32)-1)
+
+struct ath_desc {
+	u32 ds_link;
+	u32 ds_data;
+	u32 ds_ctl0;
+	u32 ds_ctl1;
+	u32 ds_hw[20];
+	union {
+		struct ath_tx_status tx;
+		struct ath_rx_status rx;
+		void *stats;
+	} ds_us;
+	void *ds_vdata;
+} __packed;
+
+#define	ds_txstat	ds_us.tx
+#define	ds_rxstat	ds_us.rx
+#define ds_stat		ds_us.stats
+
+#define ATH9K_TXDESC_CLRDMASK		0x0001
+#define ATH9K_TXDESC_NOACK		0x0002
+#define ATH9K_TXDESC_RTSENA		0x0004
+#define ATH9K_TXDESC_CTSENA		0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on.  We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
+#define ATH9K_TXDESC_INTREQ		0x0010
+#define ATH9K_TXDESC_VEOL		0x0020
+#define ATH9K_TXDESC_EXT_ONLY		0x0040
+#define ATH9K_TXDESC_EXT_AND_CTL	0x0080
+#define ATH9K_TXDESC_VMF		0x0100
+#define ATH9K_TXDESC_FRAG_IS_ON 	0x0200
+#define ATH9K_TXDESC_CAB		0x0400
+
+#define ATH9K_RXDESC_INTREQ		0x0020
+
+struct ar5416_desc {
+	u32 ds_link;
+	u32 ds_data;
+	u32 ds_ctl0;
+	u32 ds_ctl1;
+	union {
+		struct {
+			u32 ctl2;
+			u32 ctl3;
+			u32 ctl4;
+			u32 ctl5;
+			u32 ctl6;
+			u32 ctl7;
+			u32 ctl8;
+			u32 ctl9;
+			u32 ctl10;
+			u32 ctl11;
+			u32 status0;
+			u32 status1;
+			u32 status2;
+			u32 status3;
+			u32 status4;
+			u32 status5;
+			u32 status6;
+			u32 status7;
+			u32 status8;
+			u32 status9;
+		} tx;
+		struct {
+			u32 status0;
+			u32 status1;
+			u32 status2;
+			u32 status3;
+			u32 status4;
+			u32 status5;
+			u32 status6;
+			u32 status7;
+			u32 status8;
+		} rx;
+	} u;
+} __packed;
+
+#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
+#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
+
+#define ds_ctl2     u.tx.ctl2
+#define ds_ctl3     u.tx.ctl3
+#define ds_ctl4     u.tx.ctl4
+#define ds_ctl5     u.tx.ctl5
+#define ds_ctl6     u.tx.ctl6
+#define ds_ctl7     u.tx.ctl7
+#define ds_ctl8     u.tx.ctl8
+#define ds_ctl9     u.tx.ctl9
+#define ds_ctl10    u.tx.ctl10
+#define ds_ctl11    u.tx.ctl11
+
+#define ds_txstatus0    u.tx.status0
+#define ds_txstatus1    u.tx.status1
+#define ds_txstatus2    u.tx.status2
+#define ds_txstatus3    u.tx.status3
+#define ds_txstatus4    u.tx.status4
+#define ds_txstatus5    u.tx.status5
+#define ds_txstatus6    u.tx.status6
+#define ds_txstatus7    u.tx.status7
+#define ds_txstatus8    u.tx.status8
+#define ds_txstatus9    u.tx.status9
+
+#define ds_rxstatus0    u.rx.status0
+#define ds_rxstatus1    u.rx.status1
+#define ds_rxstatus2    u.rx.status2
+#define ds_rxstatus3    u.rx.status3
+#define ds_rxstatus4    u.rx.status4
+#define ds_rxstatus5    u.rx.status5
+#define ds_rxstatus6    u.rx.status6
+#define ds_rxstatus7    u.rx.status7
+#define ds_rxstatus8    u.rx.status8
+
+#define AR_FrameLen         0x00000fff
+#define AR_VirtMoreFrag     0x00001000
+#define AR_TxCtlRsvd00      0x0000e000
+#define AR_XmitPower        0x003f0000
+#define AR_XmitPower_S      16
+#define AR_RTSEnable        0x00400000
+#define AR_VEOL             0x00800000
+#define AR_ClrDestMask      0x01000000
+#define AR_TxCtlRsvd01      0x1e000000
+#define AR_TxIntrReq        0x20000000
+#define AR_DestIdxValid     0x40000000
+#define AR_CTSEnable        0x80000000
+
+#define AR_BufLen           0x00000fff
+#define AR_TxMore           0x00001000
+#define AR_DestIdx          0x000fe000
+#define AR_DestIdx_S        13
+#define AR_FrameType        0x00f00000
+#define AR_FrameType_S      20
+#define AR_NoAck            0x01000000
+#define AR_InsertTS         0x02000000
+#define AR_CorruptFCS       0x04000000
+#define AR_ExtOnly          0x08000000
+#define AR_ExtAndCtl        0x10000000
+#define AR_MoreAggr         0x20000000
+#define AR_IsAggr           0x40000000
+
+#define AR_BurstDur         0x00007fff
+#define AR_BurstDur_S       0
+#define AR_DurUpdateEna     0x00008000
+#define AR_XmitDataTries0   0x000f0000
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1   0x00f00000
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2   0x0f000000
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3   0xf0000000
+#define AR_XmitDataTries3_S 28
+
+#define AR_XmitRate0        0x000000ff
+#define AR_XmitRate0_S      0
+#define AR_XmitRate1        0x0000ff00
+#define AR_XmitRate1_S      8
+#define AR_XmitRate2        0x00ff0000
+#define AR_XmitRate2_S      16
+#define AR_XmitRate3        0xff000000
+#define AR_XmitRate3_S      24
+
+#define AR_PacketDur0       0x00007fff
+#define AR_PacketDur0_S     0
+#define AR_RTSCTSQual0      0x00008000
+#define AR_PacketDur1       0x7fff0000
+#define AR_PacketDur1_S     16
+#define AR_RTSCTSQual1      0x80000000
+
+#define AR_PacketDur2       0x00007fff
+#define AR_PacketDur2_S     0
+#define AR_RTSCTSQual2      0x00008000
+#define AR_PacketDur3       0x7fff0000
+#define AR_PacketDur3_S     16
+#define AR_RTSCTSQual3      0x80000000
+
+#define AR_AggrLen          0x0000ffff
+#define AR_AggrLen_S        0
+#define AR_TxCtlRsvd60      0x00030000
+#define AR_PadDelim         0x03fc0000
+#define AR_PadDelim_S       18
+#define AR_EncrType         0x0c000000
+#define AR_EncrType_S       26
+#define AR_TxCtlRsvd61      0xf0000000
+
+#define AR_2040_0           0x00000001
+#define AR_GI0              0x00000002
+#define AR_ChainSel0        0x0000001c
+#define AR_ChainSel0_S      2
+#define AR_2040_1           0x00000020
+#define AR_GI1              0x00000040
+#define AR_ChainSel1        0x00000380
+#define AR_ChainSel1_S      7
+#define AR_2040_2           0x00000400
+#define AR_GI2              0x00000800
+#define AR_ChainSel2        0x00007000
+#define AR_ChainSel2_S      12
+#define AR_2040_3           0x00008000
+#define AR_GI3              0x00010000
+#define AR_ChainSel3        0x000e0000
+#define AR_ChainSel3_S      17
+#define AR_RTSCTSRate       0x0ff00000
+#define AR_RTSCTSRate_S     20
+#define AR_TxCtlRsvd70      0xf0000000
+
+#define AR_TxRSSIAnt00      0x000000ff
+#define AR_TxRSSIAnt00_S    0
+#define AR_TxRSSIAnt01      0x0000ff00
+#define AR_TxRSSIAnt01_S    8
+#define AR_TxRSSIAnt02      0x00ff0000
+#define AR_TxRSSIAnt02_S    16
+#define AR_TxStatusRsvd00   0x3f000000
+#define AR_TxBaStatus       0x40000000
+#define AR_TxStatusRsvd01   0x80000000
+
+#define AR_FrmXmitOK            0x00000001
+#define AR_ExcessiveRetries     0x00000002
+#define AR_FIFOUnderrun         0x00000004
+#define AR_Filtered             0x00000008
+#define AR_RTSFailCnt           0x000000f0
+#define AR_RTSFailCnt_S         4
+#define AR_DataFailCnt          0x00000f00
+#define AR_DataFailCnt_S        8
+#define AR_VirtRetryCnt         0x0000f000
+#define AR_VirtRetryCnt_S       12
+#define AR_TxDelimUnderrun      0x00010000
+#define AR_TxDataUnderrun       0x00020000
+#define AR_DescCfgErr           0x00040000
+#define AR_TxTimerExpired       0x00080000
+#define AR_TxStatusRsvd10       0xfff00000
+
+#define AR_SendTimestamp    ds_txstatus2
+#define AR_BaBitmapLow      ds_txstatus3
+#define AR_BaBitmapHigh     ds_txstatus4
+
+#define AR_TxRSSIAnt10      0x000000ff
+#define AR_TxRSSIAnt10_S    0
+#define AR_TxRSSIAnt11      0x0000ff00
+#define AR_TxRSSIAnt11_S    8
+#define AR_TxRSSIAnt12      0x00ff0000
+#define AR_TxRSSIAnt12_S    16
+#define AR_TxRSSICombined   0xff000000
+#define AR_TxRSSICombined_S 24
+
+#define AR_TxEVM0           ds_txstatus5
+#define AR_TxEVM1           ds_txstatus6
+#define AR_TxEVM2           ds_txstatus7
+
+#define AR_TxDone           0x00000001
+#define AR_SeqNum           0x00001ffe
+#define AR_SeqNum_S         1
+#define AR_TxStatusRsvd80   0x0001e000
+#define AR_TxOpExceeded     0x00020000
+#define AR_TxStatusRsvd81   0x001c0000
+#define AR_FinalTxIdx       0x00600000
+#define AR_FinalTxIdx_S     21
+#define AR_TxStatusRsvd82   0x01800000
+#define AR_PowerMgmt        0x02000000
+#define AR_TxStatusRsvd83   0xfc000000
+
+#define AR_RxCTLRsvd00  0xffffffff
+
+#define AR_BufLen       0x00000fff
+#define AR_RxCtlRsvd00  0x00001000
+#define AR_RxIntrReq    0x00002000
+#define AR_RxCtlRsvd01  0xffffc000
+
+#define AR_RxRSSIAnt00      0x000000ff
+#define AR_RxRSSIAnt00_S    0
+#define AR_RxRSSIAnt01      0x0000ff00
+#define AR_RxRSSIAnt01_S    8
+#define AR_RxRSSIAnt02      0x00ff0000
+#define AR_RxRSSIAnt02_S    16
+#define AR_RxRate           0xff000000
+#define AR_RxRate_S         24
+#define AR_RxStatusRsvd00   0xff000000
+
+#define AR_DataLen          0x00000fff
+#define AR_RxMore           0x00001000
+#define AR_NumDelim         0x003fc000
+#define AR_NumDelim_S       14
+#define AR_RxStatusRsvd10   0xff800000
+
+#define AR_RcvTimestamp     ds_rxstatus2
+
+#define AR_GI               0x00000001
+#define AR_2040             0x00000002
+#define AR_Parallel40       0x00000004
+#define AR_Parallel40_S     2
+#define AR_RxStatusRsvd30   0x000000f8
+#define AR_RxAntenna	    0xffffff00
+#define AR_RxAntenna_S	    8
+
+#define AR_RxRSSIAnt10            0x000000ff
+#define AR_RxRSSIAnt10_S          0
+#define AR_RxRSSIAnt11            0x0000ff00
+#define AR_RxRSSIAnt11_S          8
+#define AR_RxRSSIAnt12            0x00ff0000
+#define AR_RxRSSIAnt12_S          16
+#define AR_RxRSSICombined         0xff000000
+#define AR_RxRSSICombined_S       24
+
+#define AR_RxEVM0           ds_rxstatus4
+#define AR_RxEVM1           ds_rxstatus5
+#define AR_RxEVM2           ds_rxstatus6
+
+#define AR_RxDone           0x00000001
+#define AR_RxFrameOK        0x00000002
+#define AR_CRCErr           0x00000004
+#define AR_DecryptCRCErr    0x00000008
+#define AR_PHYErr           0x00000010
+#define AR_MichaelErr       0x00000020
+#define AR_PreDelimCRCErr   0x00000040
+#define AR_RxStatusRsvd70   0x00000080
+#define AR_RxKeyIdxValid    0x00000100
+#define AR_KeyIdx           0x0000fe00
+#define AR_KeyIdx_S         9
+#define AR_PHYErrCode       0x0000ff00
+#define AR_PHYErrCode_S     8
+#define AR_RxMoreAggr       0x00010000
+#define AR_RxAggr           0x00020000
+#define AR_PostDelimCRCErr  0x00040000
+#define AR_RxStatusRsvd71   0x3ff80000
+#define AR_DecryptBusyErr   0x40000000
+#define AR_KeyMiss          0x80000000
+
+enum ath9k_tx_queue {
+	ATH9K_TX_QUEUE_INACTIVE = 0,
+	ATH9K_TX_QUEUE_DATA,
+	ATH9K_TX_QUEUE_BEACON,
+	ATH9K_TX_QUEUE_CAB,
+	ATH9K_TX_QUEUE_UAPSD,
+	ATH9K_TX_QUEUE_PSPOLL
+};
+
+#define	ATH9K_NUM_TX_QUEUES 10
+
+enum ath9k_tx_queue_subtype {
+	ATH9K_WME_AC_BK = 0,
+	ATH9K_WME_AC_BE,
+	ATH9K_WME_AC_VI,
+	ATH9K_WME_AC_VO,
+	ATH9K_WME_UPSD
+};
+
+enum ath9k_tx_queue_flags {
+	TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+	TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+	TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+	TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+	TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+	TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+	TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+	TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+	TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#define ATH9K_DECOMP_MASK_SIZE     128
+#define ATH9K_READY_TIME_LO_BOUND  50
+#define ATH9K_READY_TIME_HI_BOUND  96
+
+enum ath9k_pkt_type {
+	ATH9K_PKT_TYPE_NORMAL = 0,
+	ATH9K_PKT_TYPE_ATIM,
+	ATH9K_PKT_TYPE_PSPOLL,
+	ATH9K_PKT_TYPE_BEACON,
+	ATH9K_PKT_TYPE_PROBE_RESP,
+	ATH9K_PKT_TYPE_CHIRP,
+	ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+	u32 tqi_ver;
+	enum ath9k_tx_queue tqi_type;
+	enum ath9k_tx_queue_subtype tqi_subtype;
+	enum ath9k_tx_queue_flags tqi_qflags;
+	u32 tqi_priority;
+	u32 tqi_aifs;
+	u32 tqi_cwmin;
+	u32 tqi_cwmax;
+	u16 tqi_shretry;
+	u16 tqi_lgretry;
+	u32 tqi_cbrPeriod;
+	u32 tqi_cbrOverflowLimit;
+	u32 tqi_burstTime;
+	u32 tqi_readyTime;
+	u32 tqi_physCompBuf;
+	u32 tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+	ATH9K_RX_FILTER_UCAST = 0x00000001,
+	ATH9K_RX_FILTER_MCAST = 0x00000002,
+	ATH9K_RX_FILTER_BCAST = 0x00000004,
+	ATH9K_RX_FILTER_CONTROL = 0x00000008,
+	ATH9K_RX_FILTER_BEACON = 0x00000010,
+	ATH9K_RX_FILTER_PROM = 0x00000020,
+	ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+	ATH9K_RX_FILTER_PHYERR = 0x00000100,
+	ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+	ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+	ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+	ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#define ATH9K_RATESERIES_RTS_CTS  0x0001
+#define ATH9K_RATESERIES_2040     0x0002
+#define ATH9K_RATESERIES_HALFGI   0x0004
+
+struct ath9k_11n_rate_series {
+	u32 Tries;
+	u32 Rate;
+	u32 PktDuration;
+	u32 ChSel;
+	u32 RateFlags;
+};
+
+struct ath9k_keyval {
+	u8 kv_type;
+	u8 kv_pad;
+	u16 kv_len;
+	u8 kv_val[16]; /* TK */
+	u8 kv_mic[8]; /* Michael MIC key */
+	u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+			 * supports both MIC keys in the same key cache entry;
+			 * in that case, kv_mic is the RX key) */
+};
+
+enum ath9k_key_type {
+	ATH9K_KEY_TYPE_CLEAR,
+	ATH9K_KEY_TYPE_WEP,
+	ATH9K_KEY_TYPE_AES,
+	ATH9K_KEY_TYPE_TKIP,
+};
+
+enum ath9k_cipher {
+	ATH9K_CIPHER_WEP = 0,
+	ATH9K_CIPHER_AES_OCB = 1,
+	ATH9K_CIPHER_AES_CCM = 2,
+	ATH9K_CIPHER_CKIP = 3,
+	ATH9K_CIPHER_TKIP = 4,
+	ATH9K_CIPHER_CLR = 5,
+	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);
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+			 u32 segLen, bool firstSeg,
+			 bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+			    u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+			    u32 keyIx, enum ath9k_key_type keyType, u32 flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+				  struct ath_desc *lastds,
+				  u32 durUpdateEn, u32 rtsctsRate,
+				  u32 rtsctsDuration,
+				  struct ath9k_11n_rate_series series[],
+				  u32 nseries, u32 flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+				u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+				 u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+				   u32 burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+				     u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+			    const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+			    struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+			  const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+			u32 pa, struct ath_desc *nds, u64 tsf);
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+			  u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+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);
+
+#endif /* MAC_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -15,9 +15,7 @@
  */
 
 #include <linux/nl80211.h>
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include "ath9k.h"
 
 #define ATH_PCI_VERSION "0.1"
 
@@ -28,84 +26,129 @@ MODULE_DESCRIPTION("Support for Atheros
 MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
 MODULE_LICENSE("Dual BSD/GPL");
 
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
-	{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
-	{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
-	{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
-	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
-	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
-	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
-	{ 0 }
-};
-
-static void ath_detach(struct ath_softc *sc);
-
-/* return bus cachesize in 4B word units */
-
-static void bus_read_cachesize(struct ath_softc *sc, int *csz)
-{
-	u8 u8tmp;
-
-	pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
-	*csz = (int)u8tmp;
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
 
-	/*
-	 * This check was put in to avoid "unplesant" consequences if
-	 * the bootrom has not fully initialized all PCI devices.
-	 * Sometimes the cache line size register is not set
-	 */
+/* We use the hw_value as an index into our private channel structure */
 
-	if (*csz == 0)
-		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
+#define CHAN2G(_freq, _idx)  { \
+	.center_freq = (_freq), \
+	.hw_value = (_idx), \
+	.max_power = 30, \
 }
 
-static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
-{
-	sc->cur_rate_table = sc->hw_rate_table[mode];
-	/*
-	 * All protection frames are transmited at 2Mb/s for
-	 * 11g, otherwise at 1Mb/s.
-	 * XXX select protection rate index from rate table.
-	 */
-	sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
+#define CHAN5G(_freq, _idx) { \
+	.band = IEEE80211_BAND_5GHZ, \
+	.center_freq = (_freq), \
+	.hw_value = (_idx), \
+	.max_power = 30, \
 }
 
-static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
-{
-	if (chan->chanmode == CHANNEL_A)
-		return ATH9K_MODE_11A;
-	else if (chan->chanmode == CHANNEL_G)
-		return ATH9K_MODE_11G;
-	else if (chan->chanmode == CHANNEL_B)
-		return ATH9K_MODE_11B;
-	else if (chan->chanmode == CHANNEL_A_HT20)
-		return ATH9K_MODE_11NA_HT20;
-	else if (chan->chanmode == CHANNEL_G_HT20)
-		return ATH9K_MODE_11NG_HT20;
-	else if (chan->chanmode == CHANNEL_A_HT40PLUS)
-		return ATH9K_MODE_11NA_HT40PLUS;
-	else if (chan->chanmode == CHANNEL_A_HT40MINUS)
-		return ATH9K_MODE_11NA_HT40MINUS;
-	else if (chan->chanmode == CHANNEL_G_HT40PLUS)
-		return ATH9K_MODE_11NG_HT40PLUS;
-	else if (chan->chanmode == CHANNEL_G_HT40MINUS)
-		return ATH9K_MODE_11NG_HT40MINUS;
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+	CHAN2G(2412, 0), /* Channel 1 */
+	CHAN2G(2417, 1), /* Channel 2 */
+	CHAN2G(2422, 2), /* Channel 3 */
+	CHAN2G(2427, 3), /* Channel 4 */
+	CHAN2G(2432, 4), /* Channel 5 */
+	CHAN2G(2437, 5), /* Channel 6 */
+	CHAN2G(2442, 6), /* Channel 7 */
+	CHAN2G(2447, 7), /* Channel 8 */
+	CHAN2G(2452, 8), /* Channel 9 */
+	CHAN2G(2457, 9), /* Channel 10 */
+	CHAN2G(2462, 10), /* Channel 11 */
+	CHAN2G(2467, 11), /* Channel 12 */
+	CHAN2G(2472, 12), /* Channel 13 */
+	CHAN2G(2484, 13), /* Channel 14 */
+};
 
-	WARN_ON(1); /* should not get here */
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+	/* _We_ call this UNII 1 */
+	CHAN5G(5180, 14), /* Channel 36 */
+	CHAN5G(5200, 15), /* Channel 40 */
+	CHAN5G(5220, 16), /* Channel 44 */
+	CHAN5G(5240, 17), /* Channel 48 */
+	/* _We_ call this UNII 2 */
+	CHAN5G(5260, 18), /* Channel 52 */
+	CHAN5G(5280, 19), /* Channel 56 */
+	CHAN5G(5300, 20), /* Channel 60 */
+	CHAN5G(5320, 21), /* Channel 64 */
+	/* _We_ call this "Middle band" */
+	CHAN5G(5500, 22), /* Channel 100 */
+	CHAN5G(5520, 23), /* Channel 104 */
+	CHAN5G(5540, 24), /* Channel 108 */
+	CHAN5G(5560, 25), /* Channel 112 */
+	CHAN5G(5580, 26), /* Channel 116 */
+	CHAN5G(5600, 27), /* Channel 120 */
+	CHAN5G(5620, 28), /* Channel 124 */
+	CHAN5G(5640, 29), /* Channel 128 */
+	CHAN5G(5660, 30), /* Channel 132 */
+	CHAN5G(5680, 31), /* Channel 136 */
+	CHAN5G(5700, 32), /* Channel 140 */
+	/* _We_ call this UNII 3 */
+	CHAN5G(5745, 33), /* Channel 149 */
+	CHAN5G(5765, 34), /* Channel 153 */
+	CHAN5G(5785, 35), /* Channel 157 */
+	CHAN5G(5805, 36), /* Channel 161 */
+	CHAN5G(5825, 37), /* Channel 165 */
+};
 
-	return ATH9K_MODE_11B;
+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];
+		else if (conf_is_ht40_minus(conf))
+			sc->cur_rate_table =
+			  sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+		else if (conf_is_ht40_plus(conf))
+			sc->cur_rate_table =
+			  sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+		else
+			sc->cur_rate_table =
+			  sc->hw_rate_table[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];
+		else if (conf_is_ht40_minus(conf))
+			sc->cur_rate_table =
+			  sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+		else if (conf_is_ht40_plus(conf))
+			sc->cur_rate_table =
+			  sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+		else
+			sc->cur_rate_table =
+			  sc->hw_rate_table[ATH9K_MODE_11A];
+		break;
+	default:
+		BUG_ON(1);
+		break;
+	}
 }
 
 static void ath_update_txpow(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	u32 txpow;
 
-	if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
-		ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
+	if (sc->curtxpow != sc->config.txpowlimit) {
+		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
 		/* read back in case value is clamped */
 		ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
-		sc->sc_curtxpow = txpow;
+		sc->curtxpow = txpow;
 	}
 }
 
@@ -176,150 +219,87 @@ static void ath_setup_rates(struct ath_s
 	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 int ath_setup_channels(struct ath_softc *sc)
-{
-	struct ath_hal *ah = sc->sc_ah;
-	int nchan, i, a = 0, b = 0;
-	u8 regclassids[ATH_REGCLASSIDS_MAX];
-	u32 nregclass = 0;
-	struct ieee80211_supported_band *band_2ghz;
-	struct ieee80211_supported_band *band_5ghz;
-	struct ieee80211_channel *chan_2ghz;
-	struct ieee80211_channel *chan_5ghz;
-	struct ath9k_channel *c;
-
-	/* Fill in ah->ah_channels */
-	if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan,
-				      regclassids, ATH_REGCLASSIDS_MAX,
-				      &nregclass, CTRY_DEFAULT, false, 1)) {
-		u32 rd = ah->ah_currentRD;
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to collect channel list; "
-			"regdomain likely %u country code %u\n",
-			rd, CTRY_DEFAULT);
-		return -EINVAL;
-	}
-
-	band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
-	band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
-	chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
-	chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
-
-	for (i = 0; i < nchan; i++) {
-		c = &ah->ah_channels[i];
-		if (IS_CHAN_2GHZ(c)) {
-			chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
-			chan_2ghz[a].center_freq = c->channel;
-			chan_2ghz[a].max_power = c->maxTxPower;
-
-			if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
-				chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
-			if (c->channelFlags & CHANNEL_PASSIVE)
-				chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
-			band_2ghz->n_channels = ++a;
-
-			DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, "
-				"channelFlags: 0x%x\n",
-				c->channel, c->channelFlags);
-		} else if (IS_CHAN_5GHZ(c)) {
-			chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
-			chan_5ghz[b].center_freq = c->channel;
-			chan_5ghz[b].max_power = c->maxTxPower;
-
-			if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
-				chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
-			if (c->channelFlags & CHANNEL_PASSIVE)
-				chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
-			band_5ghz->n_channels = ++b;
-
-			DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, "
-				"channelFlags: 0x%x\n",
-				c->channel, c->channelFlags);
-		}
-	}
-
-	return 0;
-}
-
 /*
  * 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
  * DMA, then restart stuff.
 */
-static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+		    struct ath9k_channel *hchan)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	bool fastcc = true, stopped;
+	struct ieee80211_channel *channel = hw->conf.channel;
+	int r;
 
 	if (sc->sc_flags & SC_OP_INVALID)
 		return -EIO;
 
-	if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
-	    hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
-	    (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
-	    (sc->sc_flags & SC_OP_FULL_RESET)) {
-		int status;
-		/*
-		 * This is only performed if the channel settings have
-		 * actually changed.
-		 *
-		 * To switch channels clear any pending DMA operations;
-		 * wait long enough for the RX fifo to drain, reset the
-		 * hardware at the new frequency, and then re-enable
-		 * the relevant bits of the h/w.
-		 */
-		ath9k_hw_set_interrupts(ah, 0);
-		ath_draintxq(sc, false);
-		stopped = ath_stoprecv(sc);
+	ath9k_ps_wakeup(sc);
 
-		/* XXX: do not flush receive queue here. We don't want
-		 * to flush data frames already in queue because of
-		 * changing channel. */
+	/*
+	 * This is only performed if the channel settings have
+	 * actually changed.
+	 *
+	 * To switch channels clear any pending DMA operations;
+	 * wait long enough for the RX fifo to drain, reset the
+	 * hardware at the new frequency, and then re-enable
+	 * the relevant bits of the h/w.
+	 */
+	ath9k_hw_set_interrupts(ah, 0);
+	ath_drain_all_txq(sc, false);
+	stopped = ath_stoprecv(sc);
 
-		if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
-			fastcc = false;
+	/* XXX: do not flush receive queue here. We don't want
+	 * to flush data frames already in queue because of
+	 * changing channel. */
 
-		DPRINTF(sc, ATH_DBG_CONFIG,
-			"(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n",
-			sc->sc_ah->ah_curchan->channel,
-			hchan->channel, hchan->channelFlags, sc->tx_chan_width);
+	if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+		fastcc = false;
 
-		spin_lock_bh(&sc->sc_resetlock);
-		if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
-				    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-				    sc->sc_ht_extprotspacing, fastcc, &status)) {
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to reset channel %u (%uMhz) "
-				"flags 0x%x hal status %u\n",
-				ath9k_hw_mhz2ieee(ah, hchan->channel,
-						  hchan->channelFlags),
-				hchan->channel, hchan->channelFlags, status);
-			spin_unlock_bh(&sc->sc_resetlock);
-			return -EIO;
-		}
-		spin_unlock_bh(&sc->sc_resetlock);
+	DPRINTF(sc, ATH_DBG_CONFIG,
+		"(%u MHz) -> (%u MHz), chanwidth: %d\n",
+		sc->sc_ah->curchan->channel,
+		channel->center_freq, sc->tx_chan_width);
 
-		sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
-		sc->sc_flags &= ~SC_OP_FULL_RESET;
+	spin_lock_bh(&sc->sc_resetlock);
 
-		if (ath_startrecv(sc) != 0) {
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to restart recv logic\n");
-			return -EIO;
-		}
+	r = ath9k_hw_reset(ah, hchan, fastcc);
+	if (r) {
+		DPRINTF(sc, ATH_DBG_FATAL,
+			"Unable to reset channel (%u Mhz) "
+			"reset status %u\n",
+			channel->center_freq, r);
+		spin_unlock_bh(&sc->sc_resetlock);
+		return r;
+	}
+	spin_unlock_bh(&sc->sc_resetlock);
 
-		ath_setcurmode(sc, ath_chan2mode(hchan));
-		ath_update_txpow(sc);
-		ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
+	sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+	if (ath_startrecv(sc) != 0) {
+		DPRINTF(sc, ATH_DBG_FATAL,
+			"Unable to restart recv logic\n");
+		return -EIO;
 	}
+
+	ath_cache_conf_rate(sc, &hw->conf);
+	ath_update_txpow(sc);
+	ath9k_hw_set_interrupts(ah, sc->imask);
+	ath9k_ps_restore(sc);
 	return 0;
 }
 
@@ -332,123 +312,122 @@ static int ath_set_channel(struct ath_so
  */
 static void ath_ani_calibrate(unsigned long data)
 {
-	struct ath_softc *sc;
-	struct ath_hal *ah;
+	struct ath_softc *sc = (struct ath_softc *)data;
+	struct ath_hw *ah = sc->sc_ah;
 	bool longcal = false;
 	bool shortcal = false;
 	bool aniflag = false;
 	unsigned int timestamp = jiffies_to_msecs(jiffies);
-	u32 cal_interval;
+	u32 cal_interval, short_cal_interval;
 
-	sc = (struct ath_softc *)data;
-	ah = sc->sc_ah;
+	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
 
 	/*
 	* don't calibrate when we're scanning.
 	* we are most likely not on our home channel.
 	*/
-	if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)
-		return;
+	if (sc->sc_flags & SC_OP_SCANNING)
+		goto set_timer;
 
 	/* Long calibration runs independently of short calibration. */
-	if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
+	if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
 		longcal = true;
 		DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
-		sc->sc_ani.sc_longcal_timer = timestamp;
+		sc->ani.longcal_timer = timestamp;
 	}
 
-	/* Short calibration applies only while sc_caldone is false */
-	if (!sc->sc_ani.sc_caldone) {
-		if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
-		    ATH_SHORT_CALINTERVAL) {
+	/* Short calibration applies only while caldone is false */
+	if (!sc->ani.caldone) {
+		if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
 			shortcal = true;
 			DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
-			sc->sc_ani.sc_shortcal_timer = timestamp;
-			sc->sc_ani.sc_resetcal_timer = timestamp;
+			sc->ani.shortcal_timer = timestamp;
+			sc->ani.resetcal_timer = timestamp;
 		}
 	} else {
-		if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
+		if ((timestamp - sc->ani.resetcal_timer) >=
 		    ATH_RESTART_CALINTERVAL) {
-			ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
-						&sc->sc_ani.sc_caldone);
-			if (sc->sc_ani.sc_caldone)
-				sc->sc_ani.sc_resetcal_timer = timestamp;
+			sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+			if (sc->ani.caldone)
+				sc->ani.resetcal_timer = timestamp;
 		}
 	}
 
 	/* Verify whether we must check ANI */
-	if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
-	   ATH_ANI_POLLINTERVAL) {
+	if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
 		aniflag = true;
-		sc->sc_ani.sc_checkani_timer = timestamp;
+		sc->ani.checkani_timer = timestamp;
 	}
 
 	/* Skip all processing if there's nothing to do. */
 	if (longcal || shortcal || aniflag) {
 		/* Call ANI routine if necessary */
 		if (aniflag)
-			ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
-					     ah->ah_curchan);
+			ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
 
 		/* Perform calibration if necessary */
 		if (longcal || shortcal) {
 			bool iscaldone = false;
 
-			if (ath9k_hw_calibrate(ah, ah->ah_curchan,
-					       sc->sc_rx_chainmask, longcal,
+			if (ath9k_hw_calibrate(ah, ah->curchan,
+					       sc->rx_chainmask, longcal,
 					       &iscaldone)) {
 				if (longcal)
-					sc->sc_ani.sc_noise_floor =
+					sc->ani.noise_floor =
 						ath9k_hw_getchan_noise(ah,
-							       ah->ah_curchan);
+							       ah->curchan);
 
 				DPRINTF(sc, ATH_DBG_ANI,
 					"calibrate chan %u/%x nf: %d\n",
-					ah->ah_curchan->channel,
-					ah->ah_curchan->channelFlags,
-					sc->sc_ani.sc_noise_floor);
+					ah->curchan->channel,
+					ah->curchan->channelFlags,
+					sc->ani.noise_floor);
 			} else {
 				DPRINTF(sc, ATH_DBG_ANY,
 					"calibrate chan %u/%x failed\n",
-					ah->ah_curchan->channel,
-					ah->ah_curchan->channelFlags);
+					ah->curchan->channel,
+					ah->curchan->channelFlags);
 			}
-			sc->sc_ani.sc_caldone = iscaldone;
+			sc->ani.caldone = iscaldone;
 		}
 	}
 
+set_timer:
 	/*
 	* Set timer interval based on previous results.
 	* The interval must be the shortest necessary to satisfy ANI,
 	* short calibration and long calibration.
 	*/
 	cal_interval = ATH_LONG_CALINTERVAL;
-	if (sc->sc_ah->ah_config.enable_ani)
+	if (sc->sc_ah->config.enable_ani)
 		cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
-	if (!sc->sc_ani.sc_caldone)
-		cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
+	if (!sc->ani.caldone)
+		cal_interval = min(cal_interval, (u32)short_cal_interval);
 
-	mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+	mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
 }
 
 /*
  * Update tx/rx chainmask. For legacy association,
  * hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration.
+ * the chainmask configuration, for bt coexistence, use
+ * the chainmask configuration even in legacy mode.
  */
-static void ath_update_chainmask(struct ath_softc *sc, int is_ht)
+void ath_update_chainmask(struct ath_softc *sc, int is_ht)
 {
 	sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
-	if (is_ht) {
-		sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
-		sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
+	if (is_ht ||
+	    (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+		sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+		sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
 	} else {
-		sc->sc_tx_chainmask = 1;
-		sc->sc_rx_chainmask = 1;
+		sc->tx_chainmask = 1;
+		sc->rx_chainmask = 1;
 	}
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
-		sc->sc_tx_chainmask, sc->sc_rx_chainmask);
+		sc->tx_chainmask, sc->rx_chainmask);
 }
 
 static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -476,7 +455,7 @@ static void ath_node_detach(struct ath_s
 static void ath9k_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
-	u32 status = sc->sc_intrstatus;
+	u32 status = sc->intrstatus;
 
 	if (status & ATH9K_INT_FATAL) {
 		/* need a chip reset */
@@ -496,13 +475,13 @@ static void ath9k_tasklet(unsigned long
 	}
 
 	/* re-enable hardware interrupt */
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 }
 
-static irqreturn_t ath_isr(int irq, void *dev)
+irqreturn_t ath_isr(int irq, void *dev)
 {
 	struct ath_softc *sc = dev;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	enum ath9k_int status;
 	bool sched = false;
 
@@ -527,7 +506,7 @@ static irqreturn_t ath_isr(int irq, void
 		 */
 		ath9k_hw_getisr(ah, &status);	/* NB: clears ISR too */
 
-		status &= sc->sc_imask;	/* discard unasked-for bits */
+		status &= sc->imask;	/* discard unasked-for bits */
 
 		/*
 		 * If there are no status bits set, then this interrupt was not
@@ -536,7 +515,8 @@ static irqreturn_t ath_isr(int irq, void
 		if (!status)
 			return IRQ_NONE;
 
-		sc->sc_intrstatus = status;
+		sc->intrstatus = status;
+		ath9k_ps_wakeup(sc);
 
 		if (status & ATH9K_INT_FATAL) {
 			/* need a chip reset */
@@ -583,45 +563,39 @@ static irqreturn_t ath_isr(int irq, void
 				 * it will clear whatever condition caused
 				 * the interrupt.
 				 */
-				ath9k_hw_procmibevent(ah, &sc->sc_halstats);
-				ath9k_hw_set_interrupts(ah, sc->sc_imask);
+				ath9k_hw_procmibevent(ah, &sc->nodestats);
+				ath9k_hw_set_interrupts(ah, sc->imask);
 			}
 			if (status & ATH9K_INT_TIM_TIMER) {
-				if (!(ah->ah_caps.hw_caps &
+				if (!(ah->caps.hw_caps &
 				      ATH9K_HW_CAP_AUTOSLEEP)) {
 					/* Clear RxAbort bit so that we can
 					 * receive frames */
+					ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
 					ath9k_hw_setrxabort(ah, 0);
 					sched = true;
+					sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
 				}
 			}
+			if (status & ATH9K_INT_TSFOOR) {
+				/* FIXME: Handle this interrupt for power save */
+				sched = true;
+			}
 		}
+		ath9k_ps_restore(sc);
 	} while (0);
 
 	ath_debug_stat_interrupt(sc, status);
 
 	if (sched) {
 		/* turn off every interrupt except SWBA */
-		ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
+		ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
 		tasklet_schedule(&sc->intr_tq);
 	}
 
 	return IRQ_HANDLED;
 }
 
-static int ath_get_channel(struct ath_softc *sc,
-			   struct ieee80211_channel *chan)
-{
-	int i;
-
-	for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
-		if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
-			return i;
-	}
-
-	return -1;
-}
-
 static u32 ath_get_extchanmode(struct ath_softc *sc,
 			       struct ieee80211_channel *chan,
 			       enum nl80211_channel_type channel_type)
@@ -664,20 +638,9 @@ static u32 ath_get_extchanmode(struct at
 	return chanmode;
 }
 
-static int ath_keyset(struct ath_softc *sc, u16 keyix,
-	       struct ath9k_keyval *hk, const u8 mac[ETH_ALEN])
-{
-	bool status;
-
-	status = ath9k_hw_set_keycache_entry(sc->sc_ah,
-		keyix, hk, mac, false);
-
-	return status != false;
-}
-
 static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
-			   struct ath9k_keyval *hk,
-			   const u8 *addr)
+			   struct ath9k_keyval *hk, const u8 *addr,
+			   bool authenticator)
 {
 	const u8 *key_rxmic;
 	const u8 *key_txmic;
@@ -686,26 +649,33 @@ static int ath_setkey_tkip(struct ath_so
 	key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
 
 	if (addr == NULL) {
-		/* Group key installation */
-		memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-		return ath_keyset(sc, keyix, hk, addr);
-	}
-	if (!sc->sc_splitmic) {
 		/*
-		 * data key goes at first index,
-		 * the hal handles the MIC keys at index+64.
+		 * Group key installation - only two key cache entries are used
+		 * regardless of splitmic capability since group key is only
+		 * used either for TX or RX.
 		 */
+		if (authenticator) {
+			memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+			memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+		} else {
+			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);
+	}
+	if (!sc->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 ath_keyset(sc, keyix, hk, addr);
+		return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
 	}
-	/*
-	 * TX key goes at first index, RX key at +32.
-	 * The hal handles the MIC keys at index+64.
-	 */
+
+	/* 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 (!ath_keyset(sc, keyix, hk, NULL)) {
-		/* Txmic entry failed. No need to proceed further */
+	if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+		/* TX MIC entry failed. No need to proceed further */
 		DPRINTF(sc, ATH_DBG_KEYCACHE,
 			"Setting TX MIC Key Failed\n");
 		return 0;
@@ -713,20 +683,20 @@ static int ath_setkey_tkip(struct ath_so
 
 	memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
 	/* XXX delete tx key on failure? */
-	return ath_keyset(sc, keyix + 32, hk, addr);
+	return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
 }
 
 static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
 {
 	int i;
 
-	for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
-		if (test_bit(i, sc->sc_keymap) ||
-		    test_bit(i + 64, sc->sc_keymap))
+	for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+		if (test_bit(i, sc->keymap) ||
+		    test_bit(i + 64, sc->keymap))
 			continue; /* At least one part of TKIP key allocated */
-		if (sc->sc_splitmic &&
-		    (test_bit(i + 32, sc->sc_keymap) ||
-		     test_bit(i + 64 + 32, sc->sc_keymap)))
+		if (sc->splitmic &&
+		    (test_bit(i + 32, sc->keymap) ||
+		     test_bit(i + 64 + 32, sc->keymap)))
 			continue; /* At least one part of TKIP key allocated */
 
 		/* Found a free slot for a TKIP key */
@@ -740,55 +710,55 @@ static int ath_reserve_key_cache_slot(st
 	int i;
 
 	/* First, try to find slots that would not be available for TKIP. */
-	if (sc->sc_splitmic) {
-		for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) {
-			if (!test_bit(i, sc->sc_keymap) &&
-			    (test_bit(i + 32, sc->sc_keymap) ||
-			     test_bit(i + 64, sc->sc_keymap) ||
-			     test_bit(i + 64 + 32, sc->sc_keymap)))
+	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)))
 				return i;
-			if (!test_bit(i + 32, sc->sc_keymap) &&
-			    (test_bit(i, sc->sc_keymap) ||
-			     test_bit(i + 64, sc->sc_keymap) ||
-			     test_bit(i + 64 + 32, sc->sc_keymap)))
+			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)))
 				return i + 32;
-			if (!test_bit(i + 64, sc->sc_keymap) &&
-			    (test_bit(i , sc->sc_keymap) ||
-			     test_bit(i + 32, sc->sc_keymap) ||
-			     test_bit(i + 64 + 32, sc->sc_keymap)))
+			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)))
 				return i + 64;
-			if (!test_bit(i + 64 + 32, sc->sc_keymap) &&
-			    (test_bit(i, sc->sc_keymap) ||
-			     test_bit(i + 32, sc->sc_keymap) ||
-			     test_bit(i + 64, sc->sc_keymap)))
+			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)))
 				return i + 64 + 32;
 		}
 	} else {
-		for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
-			if (!test_bit(i, sc->sc_keymap) &&
-			    test_bit(i + 64, sc->sc_keymap))
+		for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+			if (!test_bit(i, sc->keymap) &&
+			    test_bit(i + 64, sc->keymap))
 				return i;
-			if (test_bit(i, sc->sc_keymap) &&
-			    !test_bit(i + 64, sc->sc_keymap))
+			if (test_bit(i, sc->keymap) &&
+			    !test_bit(i + 64, sc->keymap))
 				return i + 64;
 		}
 	}
 
 	/* No partially used TKIP slots, pick any available slot */
-	for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) {
+	for (i = IEEE80211_WEP_NKID; i < sc->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->sc_splitmic) {
+		if (sc->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->sc_keymap))
+		if (!test_bit(i, sc->keymap))
 			return i; /* Found a free slot for a key */
 	}
 
@@ -797,7 +767,8 @@ static int ath_reserve_key_cache_slot(st
 }
 
 static int ath_key_config(struct ath_softc *sc,
-			  const u8 *addr,
+			  struct ieee80211_vif *vif,
+			  struct ieee80211_sta *sta,
 			  struct ieee80211_key_conf *key)
 {
 	struct ath9k_keyval hk;
@@ -818,7 +789,7 @@ static int ath_key_config(struct ath_sof
 		hk.kv_type = ATH9K_CIPHER_AES_CCM;
 		break;
 	default:
-		return -EINVAL;
+		return -EOPNOTSUPP;
 	}
 
 	hk.kv_len = key->keylen;
@@ -829,10 +800,10 @@ static int ath_key_config(struct ath_sof
 		 * need to change with virtual interfaces. */
 		idx = key->keyidx;
 	} else if (key->keyidx) {
-		struct ieee80211_vif *vif;
+		if (WARN_ON(!sta))
+			return -EOPNOTSUPP;
+		mac = sta->addr;
 
-		mac = addr;
-		vif = sc->sc_vaps[0];
 		if (vif->type != NL80211_IFTYPE_AP) {
 			/* Only keyidx 0 should be used with unicast key, but
 			 * allow this for client mode for now. */
@@ -840,29 +811,33 @@ static int ath_key_config(struct ath_sof
 		} else
 			return -EIO;
 	} else {
-		mac = addr;
+		if (WARN_ON(!sta))
+			return -EOPNOTSUPP;
+		mac = sta->addr;
+
 		if (key->alg == ALG_TKIP)
 			idx = ath_reserve_key_cache_slot_tkip(sc);
 		else
 			idx = ath_reserve_key_cache_slot(sc);
 		if (idx < 0)
-			return -EIO; /* no free key cache entries */
+			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(sc, idx, key->key, &hk, mac,
+				      vif->type == NL80211_IFTYPE_AP);
 	else
-		ret = ath_keyset(sc, idx, &hk, mac);
+		ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
 
 	if (!ret)
 		return -EIO;
 
-	set_bit(idx, sc->sc_keymap);
+	set_bit(idx, sc->keymap);
 	if (key->alg == ALG_TKIP) {
-		set_bit(idx + 64, sc->sc_keymap);
-		if (sc->sc_splitmic) {
-			set_bit(idx + 32, sc->sc_keymap);
-			set_bit(idx + 64 + 32, sc->sc_keymap);
+		set_bit(idx + 64, sc->keymap);
+		if (sc->splitmic) {
+			set_bit(idx + 32, sc->keymap);
+			set_bit(idx + 64 + 32, sc->keymap);
 		}
 	}
 
@@ -875,18 +850,19 @@ static void ath_key_delete(struct ath_so
 	if (key->hw_key_idx < IEEE80211_WEP_NKID)
 		return;
 
-	clear_bit(key->hw_key_idx, sc->sc_keymap);
+	clear_bit(key->hw_key_idx, sc->keymap);
 	if (key->alg != ALG_TKIP)
 		return;
 
-	clear_bit(key->hw_key_idx + 64, sc->sc_keymap);
-	if (sc->sc_splitmic) {
-		clear_bit(key->hw_key_idx + 32, sc->sc_keymap);
-		clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap);
+	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);
 	}
 }
 
-static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
+static void setup_ht_cap(struct ath_softc *sc,
+			 struct ieee80211_sta_ht_cap *ht_info)
 {
 #define	ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3	/* 2 ^ 16 */
 #define	ATH9K_HT_CAP_MPDUDENSITY_8 0x6		/* 8 usec */
@@ -899,10 +875,23 @@ static void setup_ht_cap(struct ieee8021
 
 	ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
 	ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+
 	/* set up supported mcs set */
 	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-	ht_info->mcs.rx_mask[0] = 0xff;
-	ht_info->mcs.rx_mask[1] = 0xff;
+
+	switch(sc->rx_chainmask) {
+	case 1:
+		ht_info->mcs.rx_mask[0] = 0xff;
+		break;
+	case 3:
+	case 5:
+	case 7:
+	default:
+		ht_info->mcs.rx_mask[0] = 0xff;
+		ht_info->mcs.rx_mask[1] = 0xff;
+		break;
+	}
+
 	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
 }
 
@@ -910,36 +899,33 @@ static void ath9k_bss_assoc_info(struct
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *bss_conf)
 {
-	struct ath_vap *avp = (void *)vif->drv_priv;
+	struct ath_vif *avp = (void *)vif->drv_priv;
 
 	if (bss_conf->assoc) {
 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
-			bss_conf->aid, sc->sc_curbssid);
+			bss_conf->aid, sc->curbssid);
 
 		/* New association, store aid */
 		if (avp->av_opmode == NL80211_IFTYPE_STATION) {
-			sc->sc_curaid = bss_conf->aid;
-			ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
-					       sc->sc_curaid);
+			sc->curaid = bss_conf->aid;
+			ath9k_hw_write_associd(sc);
 		}
 
 		/* Configure the beacon */
-		ath_beacon_config(sc, 0);
-		sc->sc_flags |= SC_OP_BEACONS;
+		ath_beacon_config(sc, vif);
 
 		/* Reset rssi stats */
-		sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+		sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+		sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+		sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+		sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
 
 		/* Start ANI */
-		mod_timer(&sc->sc_ani.timer,
-			jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-
+		mod_timer(&sc->ani.timer,
+			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
 	} else {
 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
-		sc->sc_curaid = 0;
+		sc->curaid = 0;
 	}
 }
 
@@ -947,6 +933,39 @@ static void ath9k_bss_assoc_info(struct
 /*	 LED functions		*/
 /********************************/
 
+static void ath_led_blink_work(struct work_struct *work)
+{
+	struct ath_softc *sc = container_of(work, struct ath_softc,
+					    ath_led_blink_work.work);
+
+	if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
+		return;
+
+	if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
+	    (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
+		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+	else
+		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+				  (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+	queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
+			   (sc->sc_flags & SC_OP_LED_ON) ?
+			   msecs_to_jiffies(sc->led_off_duration) :
+			   msecs_to_jiffies(sc->led_on_duration));
+
+	sc->led_on_duration = sc->led_on_cnt ?
+			max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
+			ATH_LED_ON_DURATION_IDLE;
+	sc->led_off_duration = sc->led_off_cnt ?
+			max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
+			ATH_LED_OFF_DURATION_IDLE;
+	sc->led_on_cnt = sc->led_off_cnt = 0;
+	if (sc->sc_flags & SC_OP_LED_ON)
+		sc->sc_flags &= ~SC_OP_LED_ON;
+	else
+		sc->sc_flags |= SC_OP_LED_ON;
+}
+
 static void ath_led_brightness(struct led_classdev *led_cdev,
 			       enum led_brightness brightness)
 {
@@ -956,16 +975,27 @@ static void ath_led_brightness(struct le
 	switch (brightness) {
 	case LED_OFF:
 		if (led->led_type == ATH_LED_ASSOC ||
-		    led->led_type == ATH_LED_RADIO)
+		    led->led_type == ATH_LED_RADIO) {
+			ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+				(led->led_type == ATH_LED_RADIO));
 			sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
-				(led->led_type == ATH_LED_RADIO) ? 1 :
-				!!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
+			if (led->led_type == ATH_LED_RADIO)
+				sc->sc_flags &= ~SC_OP_LED_ON;
+		} else {
+			sc->led_off_cnt++;
+		}
 		break;
 	case LED_FULL:
-		if (led->led_type == ATH_LED_ASSOC)
+		if (led->led_type == ATH_LED_ASSOC) {
 			sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+			queue_delayed_work(sc->hw->workqueue,
+					   &sc->ath_led_blink_work, 0);
+		} else if (led->led_type == ATH_LED_RADIO) {
+			ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+			sc->sc_flags |= SC_OP_LED_ON;
+		} else {
+			sc->led_on_cnt++;
+		}
 		break;
 	default:
 		break;
@@ -1001,6 +1031,7 @@ static void ath_unregister_led(struct at
 
 static void ath_deinit_leds(struct ath_softc *sc)
 {
+	cancel_delayed_work_sync(&sc->ath_led_blink_work);
 	ath_unregister_led(&sc->assoc_led);
 	sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
 	ath_unregister_led(&sc->tx_led);
@@ -1020,9 +1051,11 @@ static void ath_init_leds(struct ath_sof
 	/* LED off, active low */
 	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
 
+	INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+
 	trigger = ieee80211_get_radio_led_name(sc->hw);
 	snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
-		"ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
+		"ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
 	ret = ath_register_led(sc, &sc->radio_led, trigger);
 	sc->radio_led.led_type = ATH_LED_RADIO;
 	if (ret)
@@ -1030,7 +1063,7 @@ static void ath_init_leds(struct ath_sof
 
 	trigger = ieee80211_get_assoc_led_name(sc->hw);
 	snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
-		"ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
+		"ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
 	ret = ath_register_led(sc, &sc->assoc_led, trigger);
 	sc->assoc_led.led_type = ATH_LED_ASSOC;
 	if (ret)
@@ -1038,7 +1071,7 @@ static void ath_init_leds(struct ath_sof
 
 	trigger = ieee80211_get_tx_led_name(sc->hw);
 	snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
-		"ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
+		"ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
 	ret = ath_register_led(sc, &sc->tx_led, trigger);
 	sc->tx_led.led_type = ATH_LED_TX;
 	if (ret)
@@ -1046,7 +1079,7 @@ static void ath_init_leds(struct ath_sof
 
 	trigger = ieee80211_get_rx_led_name(sc->hw);
 	snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
-		"ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
+		"ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
 	ret = ath_register_led(sc, &sc->rx_led, trigger);
 	sc->rx_led.led_type = ATH_LED_RX;
 	if (ret)
@@ -1058,32 +1091,22 @@ fail:
 	ath_deinit_leds(sc);
 }
 
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-/*******************/
-/*	Rfkill	   */
-/*******************/
-
-static void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
-	int status;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	int r;
 
+	ath9k_ps_wakeup(sc);
 	spin_lock_bh(&sc->sc_resetlock);
-	if (!ath9k_hw_reset(ah, ah->ah_curchan,
-			    sc->tx_chan_width,
-			    sc->sc_tx_chainmask,
-			    sc->sc_rx_chainmask,
-			    sc->sc_ht_extprotspacing,
-			    false, &status)) {
+
+	r = ath9k_hw_reset(ah, ah->curchan, false);
+
+	if (r) {
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset channel %u (%uMhz) "
-			"flags 0x%x hal status %u\n",
-			ath9k_hw_mhz2ieee(ah,
-					  ah->ah_curchan->channel,
-					  ah->ah_curchan->channelFlags),
-			ah->ah_curchan->channel,
-			ah->ah_curchan->channelFlags, status);
+			"Unable to reset channel %u (%uMhz) ",
+			"reset status %u\n",
+			channel->center_freq, r);
 	}
 	spin_unlock_bh(&sc->sc_resetlock);
 
@@ -1095,10 +1118,10 @@ static void ath_radio_enable(struct ath_
 	}
 
 	if (sc->sc_flags & SC_OP_BEACONS)
-		ath_beacon_config(sc, ATH_IF_ID_ANY);	/* restart beacons */
+		ath_beacon_config(sc, NULL);	/* restart beacons */
 
 	/* Re-Enable  interrupts */
-	ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 
 	/* Enable LED */
 	ath9k_hw_cfg_output(ah, ATH_LED_PIN,
@@ -1106,14 +1129,16 @@ static void ath_radio_enable(struct ath_
 	ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
 
 	ieee80211_wake_queues(sc->hw);
+	ath9k_ps_restore(sc);
 }
 
-static void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
-	int status;
-
+	struct ath_hw *ah = sc->sc_ah;
+	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	int r;
 
+	ath9k_ps_wakeup(sc);
 	ieee80211_stop_queues(sc->hw);
 
 	/* Disable LED */
@@ -1123,38 +1148,37 @@ static void ath_radio_disable(struct ath
 	/* Disable interrupts */
 	ath9k_hw_set_interrupts(ah, 0);
 
-	ath_draintxq(sc, false);	/* clear pending tx frames */
+	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
 	ath_stoprecv(sc);		/* turn off frame recv */
 	ath_flushrecv(sc);		/* flush recv queue */
 
 	spin_lock_bh(&sc->sc_resetlock);
-	if (!ath9k_hw_reset(ah, ah->ah_curchan,
-			    sc->tx_chan_width,
-			    sc->sc_tx_chainmask,
-			    sc->sc_rx_chainmask,
-			    sc->sc_ht_extprotspacing,
-			    false, &status)) {
+	r = ath9k_hw_reset(ah, ah->curchan, false);
+	if (r) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to reset channel %u (%uMhz) "
-			"flags 0x%x hal status %u\n",
-			ath9k_hw_mhz2ieee(ah,
-				ah->ah_curchan->channel,
-				ah->ah_curchan->channelFlags),
-			ah->ah_curchan->channel,
-			ah->ah_curchan->channelFlags, status);
+			"reset status %u\n",
+			channel->center_freq, r);
 	}
 	spin_unlock_bh(&sc->sc_resetlock);
 
 	ath9k_hw_phy_disable(ah);
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_ps_restore(sc);
 }
 
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+
+/*******************/
+/*	Rfkill	   */
+/*******************/
+
 static bool ath_is_rfkill_set(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 
-	return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) ==
-				  ah->ah_rfkill_polarity;
+	return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+				  ah->rfkill_polarity;
 }
 
 /* h/w rfkill poll function */
@@ -1238,7 +1262,7 @@ static int ath_init_sw_rfkill(struct ath
 	}
 
 	snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
-		"ath9k-%s:rfkill", wiphy_name(sc->hw->wiphy));
+		"ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
 	sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
 	sc->rf_kill.rfkill->data = sc;
 	sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
@@ -1251,7 +1275,7 @@ static int ath_init_sw_rfkill(struct ath
 /* Deinitialize rfkill */
 static void ath_deinit_rfkill(struct ath_softc *sc)
 {
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
 
 	if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
@@ -1263,7 +1287,7 @@ static void ath_deinit_rfkill(struct ath
 
 static int ath_start_rfkill_poll(struct ath_softc *sc)
 {
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		queue_delayed_work(sc->hw->workqueue,
 				   &sc->rf_kill.rfkill_poll, 0);
 
@@ -1274,13 +1298,7 @@ static int ath_start_rfkill_poll(struct
 			rfkill_free(sc->rf_kill.rfkill);
 
 			/* Deinitialize the device */
-			ath_detach(sc);
-			if (sc->pdev->irq)
-				free_irq(sc->pdev->irq, sc);
-			pci_iounmap(sc->pdev, sc->mem);
-			pci_release_region(sc->pdev, 0);
-			pci_disable_device(sc->pdev);
-			ieee80211_free_hw(sc->hw);
+			ath_cleanup(sc);
 			return -EIO;
 		} else {
 			sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
@@ -1291,18 +1309,39 @@ static int ath_start_rfkill_poll(struct
 }
 #endif /* CONFIG_RFKILL */
 
-static void ath_detach(struct ath_softc *sc)
+void ath_cleanup(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);
+}
+
+void ath_detach(struct ath_softc *sc)
 {
 	struct ieee80211_hw *hw = sc->hw;
 	int i = 0;
 
+	ath9k_ps_wakeup(sc);
+
 	DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
 	ath_deinit_rfkill(sc);
 #endif
 	ath_deinit_leds(sc);
+	cancel_work_sync(&sc->chan_work);
+	cancel_delayed_work_sync(&sc->wiphy_work);
 
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (aphy == NULL)
+			continue;
+		sc->sec_wiphy[i] = NULL;
+		ieee80211_unregister_hw(aphy->hw);
+		ieee80211_free_hw(aphy->hw);
+	}
 	ieee80211_unregister_hw(hw);
 	ath_rx_cleanup(sc);
 	ath_tx_cleanup(sc);
@@ -1320,11 +1359,12 @@ static void ath_detach(struct ath_softc
 
 	ath9k_hw_detach(sc->sc_ah);
 	ath9k_exit_debug(sc);
+	ath9k_ps_restore(sc);
 }
 
 static int ath_init(u16 devid, struct ath_softc *sc)
 {
-	struct ath_hal *ah = NULL;
+	struct ath_hw *ah = NULL;
 	int status;
 	int error = 0, i;
 	int csz = 0;
@@ -1335,55 +1375,52 @@ static int ath_init(u16 devid, struct at
 	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);
 	mutex_init(&sc->mutex);
 	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
-	tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
+	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.
 	 */
-	bus_read_cachesize(sc, &csz);
+	ath_read_cachesize(sc, &csz);
 	/* XXX assert csz is non-zero */
-	sc->sc_cachelsz = csz << 2;	/* convert to bytes */
+	sc->cachelsz = csz << 2;	/* convert to bytes */
 
-	ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
+	ah = ath9k_hw_attach(devid, sc, &status);
 	if (ah == NULL) {
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to attach hardware; HAL status %u\n", status);
+			"Unable to attach hardware; HAL status %d\n", status);
 		error = -ENXIO;
 		goto bad;
 	}
 	sc->sc_ah = ah;
 
 	/* Get the hardware key cache size. */
-	sc->sc_keymax = ah->ah_caps.keycache_size;
-	if (sc->sc_keymax > ATH_KEYMAX) {
+	sc->keymax = ah->caps.keycache_size;
+	if (sc->keymax > ATH_KEYMAX) {
 		DPRINTF(sc, ATH_DBG_KEYCACHE,
 			"Warning, using only %u entries in %u key cache\n",
-			ATH_KEYMAX, sc->sc_keymax);
-		sc->sc_keymax = ATH_KEYMAX;
+			ATH_KEYMAX, sc->keymax);
+		sc->keymax = ATH_KEYMAX;
 	}
 
 	/*
 	 * Reset the key cache since some parts do not
 	 * reset the contents on initial power up.
 	 */
-	for (i = 0; i < sc->sc_keymax; i++)
+	for (i = 0; i < sc->keymax; i++)
 		ath9k_hw_keyreset(ah, (u16) i);
 
-	/* Collect the channel list using the default country code */
-
-	error = ath_setup_channels(sc);
-	if (error)
+	if (ath9k_regd_init(sc->sc_ah))
 		goto bad;
 
 	/* default to MONITOR mode */
-	sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR;
-
+	sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
 
 	/* Setup rate tables */
 
@@ -1412,7 +1449,7 @@ static int ath_init(u16 devid, struct at
 		goto bad2;
 	}
 
-	sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
+	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
 	ath_cabq_update(sc);
 
 	for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
@@ -1449,8 +1486,8 @@ static int ath_init(u16 devid, struct at
 	/* Initializes the noise floor to a reasonable default value.
 	 * Later on this will be updated during ANI processing. */
 
-	sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-	setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
+	sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+	setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
 
 	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
 				   ATH9K_CIPHER_TKIP, NULL)) {
@@ -1476,60 +1513,62 @@ static int ath_init(u16 devid, struct at
 				      ATH9K_CIPHER_MIC, NULL)
 	    && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
 				      0, NULL))
-		sc->sc_splitmic = 1;
+		sc->splitmic = 1;
 
 	/* turn on mcast key search if possible */
 	if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
 		(void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
 					     1, NULL);
 
-	sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
-	sc->sc_config.txpowlimit_override = 0;
+	sc->config.txpowlimit = ATH_TXPOWER_MAX;
 
 	/* 11n Capabilities */
-	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
 		sc->sc_flags |= SC_OP_TXAGGR;
 		sc->sc_flags |= SC_OP_RXAGGR;
 	}
 
-	sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
-	sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
+	sc->tx_chainmask = ah->caps.tx_chainmask;
+	sc->rx_chainmask = ah->caps.rx_chainmask;
 
 	ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
 	sc->rx.defant = ath9k_hw_getdefantenna(ah);
 
-	ath9k_hw_getmac(ah, sc->sc_myaddr);
-	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
-		ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
-		ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
-		ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
-	}
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+		memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
 
 	sc->beacon.slottime = ATH9K_SLOT_TIME_9;	/* default to short slot time */
 
 	/* initialize beacon slots */
-	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
-		sc->beacon.bslot[i] = ATH_IF_ID_ANY;
+	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+		sc->beacon.bslot[i] = NULL;
+		sc->beacon.bslot_aphy[i] = NULL;
+	}
 
 	/* save MISC configurations */
-	sc->sc_config.swBeaconProcess = 1;
+	sc->config.swBeaconProcess = 1;
 
 	/* setup channels and rates */
 
-	sc->sbands[IEEE80211_BAND_2GHZ].channels =
-		sc->channels[IEEE80211_BAND_2GHZ];
+	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_11A, sc->sc_ah->ah_caps.wireless_modes)) {
-		sc->sbands[IEEE80211_BAND_5GHZ].channels =
-			sc->channels[IEEE80211_BAND_5GHZ];
+	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);
 	}
 
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+		ath9k_hw_btcoex_enable(sc->sc_ah);
+
 	return 0;
 bad2:
 	/* cleanup tx queues */
@@ -1544,49 +1583,68 @@ bad:
 	return error;
 }
 
-static int ath_attach(u16 devid, struct ath_softc *sc)
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
-	struct ieee80211_hw *hw = sc->hw;
-	int error = 0, i;
-
-	DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
-
-	error = ath_init(devid, sc);
-	if (error != 0)
-		return error;
-
-	/* get mac address from hardware and set in mac80211 */
-
-	SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
-
 	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
 		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 		IEEE80211_HW_SIGNAL_DBM |
-		IEEE80211_HW_AMPDU_AGGREGATION;
+		IEEE80211_HW_AMPDU_AGGREGATION |
+		IEEE80211_HW_SUPPORTS_PS |
+		IEEE80211_HW_PS_NULLFUNC_STACK |
+		IEEE80211_HW_SPECTRUM_MGMT;
+
+	if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+		hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_AP) |
 		BIT(NL80211_IFTYPE_STATION) |
-		BIT(NL80211_IFTYPE_ADHOC);
+		BIT(NL80211_IFTYPE_ADHOC) |
+		BIT(NL80211_IFTYPE_MESH_POINT);
+
+	hw->wiphy->reg_notifier = ath9k_reg_notifier;
+	hw->wiphy->strict_regulatory = true;
 
 	hw->queues = 4;
 	hw->max_rates = 4;
+	hw->channel_change_time = 5000;
+	hw->max_listen_interval = 10;
 	hw->max_rate_tries = ATH_11N_TXMAXTRY;
 	hw->sta_data_size = sizeof(struct ath_node);
-	hw->vif_data_size = sizeof(struct ath_vap);
+	hw->vif_data_size = sizeof(struct ath_vif);
 
 	hw->rate_control_algorithm = "ath9k_rate_control";
 
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
-		setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-		if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
-			setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
-	}
-
-	hw->wiphy->bands[IEEE80211_BAND_2GHZ] =	&sc->sbands[IEEE80211_BAND_2GHZ];
-	if (test_bit(ATH9K_MODE_11A, sc->sc_ah->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];
+}
+
+int ath_attach(u16 devid, struct ath_softc *sc)
+{
+	struct ieee80211_hw *hw = sc->hw;
+	const struct ieee80211_regdomain *regd;
+	int error = 0, i;
+
+	DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+
+	error = ath_init(devid, sc);
+	if (error != 0)
+		return error;
+
+	/* get mac address from hardware and set in mac80211 */
+
+	SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+
+	ath_set_hw_capab(sc, hw);
+
+	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);
+	}
 
 	/* initialize tx/rx engine */
 	error = ath_tx_init(sc, ATH_TXBUF);
@@ -1599,7 +1657,7 @@ static int ath_attach(u16 devid, struct
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
 	/* Initialze h/w Rfkill */
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
 
 	/* Initialize s/w rfkill */
@@ -1608,11 +1666,39 @@ static int ath_attach(u16 devid, struct
 		goto error_attach;
 #endif
 
+	if (ath9k_is_world_regd(sc->sc_ah)) {
+		/* Anything applied here (prior to wiphy registration) gets
+		 * saved on the wiphy orig_* parameters */
+		regd = ath9k_world_regdomain(sc->sc_ah);
+		hw->wiphy->custom_regulatory = true;
+		hw->wiphy->strict_regulatory = false;
+	} else {
+		/* This gets applied in the case of the absense of CRDA,
+		 * it's our own custom world regulatory domain, similar to
+		 * cfg80211's but we enable passive scanning */
+		regd = ath9k_default_world_regdomain();
+	}
+	wiphy_apply_custom_regulatory(hw->wiphy, regd);
+	ath9k_reg_apply_radar_flags(hw->wiphy);
+	ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
+
+	INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
+	INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
+	sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+
 	error = ieee80211_register_hw(hw);
 
+	if (!ath9k_is_world_regd(sc->sc_ah)) {
+		error = regulatory_hint(hw->wiphy,
+			sc->sc_ah->regulatory.alpha2);
+		if (error)
+			goto error_attach;
+	}
+
 	/* Initialize LED control */
 	ath_init_leds(sc);
 
+
 	return 0;
 
 error_attach:
@@ -1629,24 +1715,20 @@ error_attach:
 
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 {
-	struct ath_hal *ah = sc->sc_ah;
-	int status;
-	int error = 0;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ieee80211_hw *hw = sc->hw;
+	int r;
 
 	ath9k_hw_set_interrupts(ah, 0);
-	ath_draintxq(sc, retry_tx);
+	ath_drain_all_txq(sc, retry_tx);
 	ath_stoprecv(sc);
 	ath_flushrecv(sc);
 
 	spin_lock_bh(&sc->sc_resetlock);
-	if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
-			    sc->tx_chan_width,
-			    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-			    sc->sc_ht_extprotspacing, false, &status)) {
+	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+	if (r)
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset hardware; hal status %u\n", status);
-		error = -EIO;
-	}
+			"Unable to reset hardware; reset status %u\n", r);
 	spin_unlock_bh(&sc->sc_resetlock);
 
 	if (ath_startrecv(sc) != 0)
@@ -1657,14 +1739,14 @@ int ath_reset(struct ath_softc *sc, bool
 	 * that changes the channel so update any state that
 	 * might change as a result.
 	 */
-	ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
+	ath_cache_conf_rate(sc, &hw->conf);
 
 	ath_update_txpow(sc);
 
 	if (sc->sc_flags & SC_OP_BEACONS)
-		ath_beacon_config(sc, ATH_IF_ID_ANY);	/* restart beacons */
+		ath_beacon_config(sc, NULL);	/* restart beacons */
 
-	ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	ath9k_hw_set_interrupts(ah, sc->imask);
 
 	if (retry_tx) {
 		int i;
@@ -1677,7 +1759,7 @@ int ath_reset(struct ath_softc *sc, bool
 		}
 	}
 
-	return error;
+	return r;
 }
 
 /*
@@ -1701,6 +1783,7 @@ int ath_descdma_setup(struct ath_softc *
 	DPRINTF(sc, 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");
@@ -1717,7 +1800,7 @@ int ath_descdma_setup(struct ath_softc *
 	 * descriptors that cross the 4K page boundary. Assume
 	 * one skipped descriptor per 4K page.
 	 */
-	if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
 		u32 ndesc_skipped =
 			ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
 		u32 dma_len;
@@ -1731,9 +1814,8 @@ int ath_descdma_setup(struct ath_softc *
 	}
 
 	/* allocate descriptors */
-	dd->dd_desc = pci_alloc_consistent(sc->pdev,
-			      dd->dd_desc_len,
-			      &dd->dd_desc_paddr);
+	dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+					 &dd->dd_desc_paddr, GFP_KERNEL);
 	if (dd->dd_desc == NULL) {
 		error = -ENOMEM;
 		goto fail;
@@ -1745,20 +1827,18 @@ int ath_descdma_setup(struct ath_softc *
 
 	/* allocate buffers */
 	bsize = sizeof(struct ath_buf) * nbuf;
-	bf = kmalloc(bsize, GFP_KERNEL);
+	bf = kzalloc(bsize, GFP_KERNEL);
 	if (bf == NULL) {
 		error = -ENOMEM;
 		goto fail2;
 	}
-	memset(bf, 0, bsize);
 	dd->dd_bufptr = bf;
 
-	INIT_LIST_HEAD(head);
 	for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
 		bf->bf_desc = ds;
 		bf->bf_daddr = DS2PHYS(dd, ds);
 
-		if (!(sc->sc_ah->ah_caps.hw_caps &
+		if (!(sc->sc_ah->caps.hw_caps &
 		      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
 			/*
 			 * Skip descriptor addresses which can cause 4KB
@@ -1779,8 +1859,8 @@ int ath_descdma_setup(struct ath_softc *
 	}
 	return 0;
 fail2:
-	pci_free_consistent(sc->pdev,
-		dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+			  dd->dd_desc_paddr);
 fail:
 	memset(dd, 0, sizeof(*dd));
 	return error;
@@ -1793,8 +1873,8 @@ void ath_descdma_cleanup(struct ath_soft
 			 struct ath_descdma *dd,
 			 struct list_head *head)
 {
-	pci_free_consistent(sc->pdev,
-		dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+	dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+			  dd->dd_desc_paddr);
 
 	INIT_LIST_HEAD(head);
 	kfree(dd->dd_bufptr);
@@ -1851,33 +1931,81 @@ int ath_get_mac80211_qnum(u32 queue, str
 	return qnum;
 }
 
+/* XXX: Remove me once we don't depend on ath9k_channel for all
+ * this redundant data */
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+			   struct ath9k_channel *ichan)
+{
+	struct ieee80211_channel *chan = hw->conf.channel;
+	struct ieee80211_conf *conf = &hw->conf;
+
+	ichan->channel = chan->center_freq;
+	ichan->chan = chan;
+
+	if (chan->band == IEEE80211_BAND_2GHZ) {
+		ichan->chanmode = CHANNEL_G;
+		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+	} else {
+		ichan->chanmode = CHANNEL_A;
+		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;
+
+		ichan->chanmode = ath_get_extchanmode(sc, chan,
+					    conf->channel_type);
+	}
+}
+
 /**********************/
 /* mac80211 callbacks */
 /**********************/
 
 static int ath9k_start(struct ieee80211_hw *hw)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	struct ieee80211_channel *curchan = hw->conf.channel;
 	struct ath9k_channel *init_channel;
-	int error = 0, pos, status;
+	int r, pos;
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
 		"initial channel: %d MHz\n", curchan->center_freq);
 
-	/* setup initial channel */
+	mutex_lock(&sc->mutex);
 
-	pos = ath_get_channel(sc, curchan);
-	if (pos == -1) {
-		DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
-		error = -EINVAL;
-		goto error;
+	if (ath9k_wiphy_started(sc)) {
+		if (sc->chan_idx == curchan->hw_value) {
+			/*
+			 * Already on the operational channel, the new wiphy
+			 * can be marked active.
+			 */
+			aphy->state = ATH_WIPHY_ACTIVE;
+			ieee80211_wake_queues(hw);
+		} else {
+			/*
+			 * Another wiphy is on another channel, start the new
+			 * wiphy in paused state.
+			 */
+			aphy->state = ATH_WIPHY_PAUSED;
+			ieee80211_stop_queues(hw);
+		}
+		mutex_unlock(&sc->mutex);
+		return 0;
 	}
+	aphy->state = ATH_WIPHY_ACTIVE;
 
-	sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-	sc->sc_ah->ah_channels[pos].chanmode =
-		(curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
-	init_channel = &sc->sc_ah->ah_channels[pos];
+	/* setup initial channel */
+
+	pos = curchan->hw_value;
+
+	sc->chan_idx = pos;
+	init_channel = &sc->sc_ah->channels[pos];
+	ath9k_update_ichannel(sc, hw, init_channel);
 
 	/* Reset SERDES registers */
 	ath9k_hw_configpcipowersave(sc->sc_ah, 0);
@@ -1890,17 +2018,14 @@ static int ath9k_start(struct ieee80211_
 	 * and then setup of the interrupt mask.
 	 */
 	spin_lock_bh(&sc->sc_resetlock);
-	if (!ath9k_hw_reset(sc->sc_ah, init_channel,
-			    sc->tx_chan_width,
-			    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-			    sc->sc_ht_extprotspacing, false, &status)) {
+	r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+	if (r) {
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to reset hardware; hal status %u "
-			"(freq %u flags 0x%x)\n", status,
-			init_channel->channel, init_channel->channelFlags);
-		error = -EIO;
+			"Unable to reset hardware; reset status %u "
+			"(freq %u MHz)\n", r,
+			curchan->center_freq);
 		spin_unlock_bh(&sc->sc_resetlock);
-		goto error;
+		goto mutex_unlock;
 	}
 	spin_unlock_bh(&sc->sc_resetlock);
 
@@ -1920,66 +2045,56 @@ static int ath9k_start(struct ieee80211_
 	if (ath_startrecv(sc) != 0) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to start recv logic\n");
-		error = -EIO;
-		goto error;
+		r = -EIO;
+		goto mutex_unlock;
 	}
 
 	/* Setup our intr mask. */
-	sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
+	sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
 		| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
 		| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
 
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT)
-		sc->sc_imask |= ATH9K_INT_GTT;
-
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
-		sc->sc_imask |= ATH9K_INT_CST;
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+		sc->imask |= ATH9K_INT_GTT;
 
-	/*
-	 * Enable MIB interrupts when there are hardware phy counters.
-	 * Note we only do this (at the moment) for station mode.
-	 */
-	if (ath9k_hw_phycounters(sc->sc_ah) &&
-	    ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
-	     (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)))
-		sc->sc_imask |= ATH9K_INT_MIB;
-	/*
-	 * Some hardware processes the TIM IE and fires an
-	 * interrupt when the TIM bit is set.  For hardware
-	 * that does, if not overridden by configuration,
-	 * enable the TIM interrupt when operating as station.
-	 */
-	if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
-	    (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) &&
-	    !sc->sc_config.swBeaconProcess)
-		sc->sc_imask |= ATH9K_INT_TIM;
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+		sc->imask |= ATH9K_INT_CST;
 
-	ath_setcurmode(sc, ath_chan2mode(init_channel));
+	ath_cache_conf_rate(sc, &hw->conf);
 
 	sc->sc_flags &= ~SC_OP_INVALID;
 
 	/* Disable BMISS interrupt when we're not associated */
-	sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+	sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
-	ieee80211_wake_queues(sc->hw);
+	ieee80211_wake_queues(hw);
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	error = ath_start_rfkill_poll(sc);
+	r = ath_start_rfkill_poll(sc);
 #endif
 
-error:
-	return error;
+mutex_unlock:
+	mutex_unlock(&sc->mutex);
+
+	return r;
 }
 
 static int ath9k_tx(struct ieee80211_hw *hw,
 		    struct sk_buff *skb)
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	struct ath_tx_control txctl;
 	int hdrlen, padsize;
 
+	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);
+		goto exit;
+	}
+
 	memset(&txctl, 0, sizeof(struct ath_tx_control));
 
 	/*
@@ -2013,7 +2128,7 @@ static int ath9k_tx(struct ieee80211_hw
 
 	DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
 
-	if (ath_tx_start(sc, skb, &txctl) != 0) {
+	if (ath_tx_start(hw, skb, &txctl) != 0) {
 		DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
 		goto exit;
 	}
@@ -2026,30 +2141,38 @@ exit:
 
 static void ath9k_stop(struct ieee80211_hw *hw)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	aphy->state = ATH_WIPHY_INACTIVE;
 
 	if (sc->sc_flags & SC_OP_INVALID) {
 		DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
 		return;
 	}
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n");
+	mutex_lock(&sc->mutex);
 
-	ieee80211_stop_queues(sc->hw);
+	ieee80211_stop_queues(hw);
+
+	if (ath9k_wiphy_started(sc)) {
+		mutex_unlock(&sc->mutex);
+		return; /* another wiphy still in use */
+	}
 
 	/* make sure h/w will not generate any interrupt
 	 * before setting the invalid flag. */
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
 
 	if (!(sc->sc_flags & SC_OP_INVALID)) {
-		ath_draintxq(sc, false);
+		ath_drain_all_txq(sc, false);
 		ath_stoprecv(sc);
 		ath9k_hw_phy_disable(sc->sc_ah);
 	} else
 		sc->rx.rxlink = NULL;
 
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
 #endif
 	/* disable HAL and put h/w to sleep */
@@ -2058,136 +2181,224 @@ static void ath9k_stop(struct ieee80211_
 
 	sc->sc_flags |= SC_OP_INVALID;
 
+	mutex_unlock(&sc->mutex);
+
 	DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
 }
 
 static int ath9k_add_interface(struct ieee80211_hw *hw,
 			       struct ieee80211_if_init_conf *conf)
 {
-	struct ath_softc *sc = hw->priv;
-	struct ath_vap *avp = (void *)conf->vif->drv_priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_vif *avp = (void *)conf->vif->drv_priv;
 	enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+	int ret = 0;
 
-	/* Support only vap for now */
+	mutex_lock(&sc->mutex);
 
-	if (sc->sc_nvaps)
-		return -ENOBUFS;
+	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
+	    sc->nvifs > 0) {
+		ret = -ENOBUFS;
+		goto out;
+	}
 
 	switch (conf->type) {
 	case NL80211_IFTYPE_STATION:
 		ic_opmode = NL80211_IFTYPE_STATION;
 		break;
 	case NL80211_IFTYPE_ADHOC:
-		ic_opmode = NL80211_IFTYPE_ADHOC;
-		break;
 	case NL80211_IFTYPE_AP:
-		ic_opmode = NL80211_IFTYPE_AP;
+	case NL80211_IFTYPE_MESH_POINT:
+		if (sc->nbcnvifs >= ATH_BCBUF) {
+			ret = -ENOBUFS;
+			goto out;
+		}
+		ic_opmode = conf->type;
 		break;
 	default:
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Interface type %d not yet supported\n", conf->type);
-		return -EOPNOTSUPP;
+		ret = -EOPNOTSUPP;
+		goto out;
 	}
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode);
+	DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
 
-	/* Set the VAP opmode */
+	/* Set the VIF opmode */
 	avp->av_opmode = ic_opmode;
 	avp->av_bslot = -1;
 
-	if (ic_opmode == NL80211_IFTYPE_AP)
-		ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+	sc->nvifs++;
 
-	sc->sc_vaps[0] = conf->vif;
-	sc->sc_nvaps++;
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+		ath9k_set_bssid_mask(hw);
+
+	if (sc->nvifs > 1)
+		goto out; /* skip global settings for secondary vif */
+
+	if (ic_opmode == NL80211_IFTYPE_AP) {
+		ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+		sc->sc_flags |= SC_OP_TSF_RESET;
+	}
 
 	/* Set the device opmode */
-	sc->sc_ah->ah_opmode = ic_opmode;
+	sc->sc_ah->opmode = ic_opmode;
+
+	/*
+	 * Enable MIB interrupts when there are hardware phy counters.
+	 * Note we only do this (at the moment) for station mode.
+	 */
+	if ((conf->type == NL80211_IFTYPE_STATION) ||
+	    (conf->type == NL80211_IFTYPE_ADHOC) ||
+	    (conf->type == NL80211_IFTYPE_MESH_POINT)) {
+		if (ath9k_hw_phycounters(sc->sc_ah))
+			sc->imask |= ATH9K_INT_MIB;
+		sc->imask |= ATH9K_INT_TSFOOR;
+	}
+
+	/*
+	 * Some hardware processes the TIM IE and fires an
+	 * interrupt when the TIM bit is set.  For hardware
+	 * that does, if not overridden by configuration,
+	 * enable the TIM interrupt when operating as station.
+	 */
+	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
+	    (conf->type == NL80211_IFTYPE_STATION) &&
+	    !sc->config.swBeaconProcess)
+		sc->imask |= ATH9K_INT_TIM;
+
+	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
 	if (conf->type == NL80211_IFTYPE_AP) {
 		/* TODO: is this a suitable place to start ANI for AP mode? */
 		/* Start ANI */
-		mod_timer(&sc->sc_ani.timer,
+		mod_timer(&sc->ani.timer,
 			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
 	}
 
-	return 0;
+out:
+	mutex_unlock(&sc->mutex);
+	return ret;
 }
 
 static void ath9k_remove_interface(struct ieee80211_hw *hw,
 				   struct ieee80211_if_init_conf *conf)
 {
-	struct ath_softc *sc = hw->priv;
-	struct ath_vap *avp = (void *)conf->vif->drv_priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_vif *avp = (void *)conf->vif->drv_priv;
+	int i;
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
 
+	mutex_lock(&sc->mutex);
+
 	/* Stop ANI */
-	del_timer_sync(&sc->sc_ani.timer);
+	del_timer_sync(&sc->ani.timer);
 
 	/* Reclaim beacon resources */
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
-	    sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+	    (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+	    (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
 		ath_beacon_return(sc, avp);
 	}
 
 	sc->sc_flags &= ~SC_OP_BEACONS;
 
-	sc->sc_vaps[0] = NULL;
-	sc->sc_nvaps--;
+	for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+		if (sc->beacon.bslot[i] == conf->vif) {
+			printk(KERN_DEBUG "%s: vif had allocated beacon "
+			       "slot\n", __func__);
+			sc->beacon.bslot[i] = NULL;
+			sc->beacon.bslot_aphy[i] = NULL;
+		}
+	}
+
+	sc->nvifs--;
+
+	mutex_unlock(&sc->mutex);
 }
 
 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	struct ieee80211_conf *conf = &hw->conf;
 
 	mutex_lock(&sc->mutex);
-	if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
-		       IEEE80211_CONF_CHANGE_HT)) {
-		struct ieee80211_channel *curchan = hw->conf.channel;
-		int pos;
 
-		DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
-			curchan->center_freq);
-
-		pos = ath_get_channel(sc, curchan);
-		if (pos == -1) {
-			DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n",
-				curchan->center_freq);
-			mutex_unlock(&sc->mutex);
-			return -EINVAL;
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		if (conf->flags & IEEE80211_CONF_PS) {
+			if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+				sc->imask |= ATH9K_INT_TIM_TIMER;
+				ath9k_hw_set_interrupts(sc->sc_ah,
+						sc->imask);
+			}
+			ath9k_hw_setrxabort(sc->sc_ah, 1);
+			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+		} else {
+			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+			ath9k_hw_setrxabort(sc->sc_ah, 0);
+			sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+			if (sc->imask & ATH9K_INT_TIM_TIMER) {
+				sc->imask &= ~ATH9K_INT_TIM_TIMER;
+				ath9k_hw_set_interrupts(sc->sc_ah,
+						sc->imask);
+			}
 		}
+	}
 
-		sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-		sc->sc_ah->ah_channels[pos].chanmode =
-			(curchan->band == IEEE80211_BAND_2GHZ) ?
-			CHANNEL_G : CHANNEL_A;
+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+		struct ieee80211_channel *curchan = hw->conf.channel;
+		int pos = curchan->hw_value;
 
-		if (conf->ht.enabled) {
-			if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS ||
-			    conf->ht.channel_type == NL80211_CHAN_HT40MINUS)
-				sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+		aphy->chan_idx = pos;
+		aphy->chan_is_ht = conf_is_ht(conf);
 
-			sc->sc_ah->ah_channels[pos].chanmode =
-				ath_get_extchanmode(sc, curchan,
-						    conf->ht.channel_type);
+		if (aphy->state == ATH_WIPHY_SCAN ||
+		    aphy->state == ATH_WIPHY_ACTIVE)
+			ath9k_wiphy_pause_all_forced(sc, aphy);
+		else {
+			/*
+			 * Do not change operational channel based on a paused
+			 * wiphy changes.
+			 */
+			goto skip_chan_change;
 		}
 
-		ath_update_chainmask(sc, conf->ht.enabled);
+		DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+			curchan->center_freq);
 
-		if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) {
+		/* XXX: remove me eventualy */
+		ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
+
+		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");
 			mutex_unlock(&sc->mutex);
 			return -EINVAL;
 		}
 	}
 
+skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
-		sc->sc_config.txpowlimit = 2 * conf->power_level;
+		sc->config.txpowlimit = 2 * conf->power_level;
+
+	/*
+	 * 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 & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
+		sc->sc_flags |= SC_OP_TSF_RESET;
 
 	mutex_unlock(&sc->mutex);
+
 	return 0;
 }
 
@@ -2195,19 +2406,24 @@ static int ath9k_config_interface(struct
 				  struct ieee80211_vif *vif,
 				  struct ieee80211_if_conf *conf)
 {
-	struct ath_softc *sc = hw->priv;
-	struct ath_hal *ah = sc->sc_ah;
-	struct ath_vap *avp = (void *)vif->drv_priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_vif *avp = (void *)vif->drv_priv;
 	u32 rfilt = 0;
 	int error, i;
 
+	mutex_lock(&sc->mutex);
+
 	/* TODO: Need to decide which hw opmode to use for multi-interface
 	 * cases */
 	if (vif->type == NL80211_IFTYPE_AP &&
-	    ah->ah_opmode != NL80211_IFTYPE_AP) {
-		ah->ah_opmode = NL80211_IFTYPE_STATION;
+	    ah->opmode != NL80211_IFTYPE_AP) {
+		ah->opmode = NL80211_IFTYPE_STATION;
 		ath9k_hw_setopmode(ah);
-		ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
+		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;
 	}
@@ -2217,18 +2433,19 @@ static int ath9k_config_interface(struct
 		switch (vif->type) {
 		case NL80211_IFTYPE_STATION:
 		case NL80211_IFTYPE_ADHOC:
+		case NL80211_IFTYPE_MESH_POINT:
 			/* Set BSSID */
-			memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
-			sc->sc_curaid = 0;
-			ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
-					       sc->sc_curaid);
+			memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
+			memcpy(avp->bssid, conf->bssid, ETH_ALEN);
+			sc->curaid = 0;
+			ath9k_hw_write_associd(sc);
 
 			/* Set aggregation protection mode parameters */
-			sc->sc_config.ath_aggr_prot = 0;
+			sc->config.ath_aggr_prot = 0;
 
 			DPRINTF(sc, ATH_DBG_CONFIG,
 				"RX filter 0x%x bssid %pM aid 0x%x\n",
-				rfilt, sc->sc_curbssid, sc->sc_curaid);
+				rfilt, sc->curbssid, sc->curaid);
 
 			/* need to reconfigure the beacon */
 			sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -2239,24 +2456,30 @@ static int ath9k_config_interface(struct
 		}
 	}
 
-	if ((conf->changed & IEEE80211_IFCC_BEACON) &&
-	    ((vif->type == NL80211_IFTYPE_ADHOC) ||
-	     (vif->type == NL80211_IFTYPE_AP))) {
-		/*
-		 * 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);
+	if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+	    (vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+		if ((conf->changed & IEEE80211_IFCC_BEACON) ||
+		    (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
+		     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);
 
-		error = ath_beacon_alloc(sc, 0);
-		if (error != 0)
-			return error;
+			error = ath_beacon_alloc(aphy, vif);
+			if (error != 0) {
+				mutex_unlock(&sc->mutex);
+				return error;
+			}
 
-		ath_beacon_sync(sc, 0);
+			ath_beacon_config(sc, vif);
+		}
 	}
 
 	/* Check for WLAN_CAPABILITY_PRIVACY ? */
@@ -2265,13 +2488,15 @@ static int ath9k_config_interface(struct
 			if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
 				ath9k_hw_keysetmac(sc->sc_ah,
 						   (u16)i,
-						   sc->sc_curbssid);
+						   sc->curbssid);
 	}
 
 	/* Only legacy IBSS for now */
 	if (vif->type == NL80211_IFTYPE_ADHOC)
 		ath_update_chainmask(sc, 0);
 
+	mutex_unlock(&sc->mutex);
+
 	return 0;
 }
 
@@ -2290,7 +2515,8 @@ static void ath9k_configure_filter(struc
 				   int mc_count,
 				   struct dev_mc_list *mclist)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	u32 rfilt;
 
 	changed_flags &= SUPPORTED_FILTERS;
@@ -2300,11 +2526,6 @@ static void ath9k_configure_filter(struc
 	rfilt = ath_calcrxfilter(sc);
 	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
 
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
-			ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
-	}
-
 	DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
 }
 
@@ -2313,7 +2534,8 @@ static void ath9k_sta_notify(struct ieee
 			     enum sta_notify_cmd cmd,
 			     struct ieee80211_sta *sta)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 
 	switch (cmd) {
 	case STA_NOTIFY_ADD:
@@ -2327,17 +2549,19 @@ static void ath9k_sta_notify(struct ieee
 	}
 }
 
-static int ath9k_conf_tx(struct ieee80211_hw *hw,
-			 u16 queue,
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			 const struct ieee80211_tx_queue_params *params)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	struct ath9k_tx_queue_info qi;
 	int ret = 0, qnum;
 
 	if (queue >= WME_NUM_AC)
 		return 0;
 
+	mutex_lock(&sc->mutex);
+
 	qi.tqi_aifs = params->aifs;
 	qi.tqi_cwmin = params->cw_min;
 	qi.tqi_cwmax = params->cw_max;
@@ -2354,29 +2578,39 @@ static int ath9k_conf_tx(struct ieee8021
 	if (ret)
 		DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
 
+	mutex_unlock(&sc->mutex);
+
 	return ret;
 }
 
 static int ath9k_set_key(struct ieee80211_hw *hw,
 			 enum set_key_cmd cmd,
-			 const u8 *local_addr,
-			 const u8 *addr,
+			 struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta,
 			 struct ieee80211_key_conf *key)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	int ret = 0;
 
+	if (modparam_nohwcrypt)
+		return -ENOSPC;
+
+	mutex_lock(&sc->mutex);
+	ath9k_ps_wakeup(sc);
 	DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
 
 	switch (cmd) {
 	case SET_KEY:
-		ret = ath_key_config(sc, addr, key);
+		ret = ath_key_config(sc, vif, sta, key);
 		if (ret >= 0) {
 			key->hw_key_idx = ret;
 			/* push IV and Michael MIC generation to stack */
 			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 			if (key->alg == ALG_TKIP)
 				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+			if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
 			ret = 0;
 		}
 		break;
@@ -2387,6 +2621,9 @@ static int ath9k_set_key(struct ieee8021
 		ret = -EINVAL;
 	}
 
+	ath9k_ps_restore(sc);
+	mutex_unlock(&sc->mutex);
+
 	return ret;
 }
 
@@ -2395,7 +2632,10 @@ static void ath9k_bss_info_changed(struc
 				   struct ieee80211_bss_conf *bss_conf,
 				   u32 changed)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	mutex_lock(&sc->mutex);
 
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
 		DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
@@ -2421,33 +2661,50 @@ static void ath9k_bss_info_changed(struc
 			bss_conf->assoc);
 		ath9k_bss_assoc_info(sc, vif, bss_conf);
 	}
+
+	mutex_unlock(&sc->mutex);
 }
 
 static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
 {
 	u64 tsf;
-	struct ath_softc *sc = hw->priv;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 
-	tsf = ath9k_hw_gettsf64(ah);
+	mutex_lock(&sc->mutex);
+	tsf = ath9k_hw_gettsf64(sc->sc_ah);
+	mutex_unlock(&sc->mutex);
 
 	return tsf;
 }
 
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	mutex_lock(&sc->mutex);
+	ath9k_hw_settsf64(sc->sc_ah, tsf);
+	mutex_unlock(&sc->mutex);
+}
+
 static void ath9k_reset_tsf(struct ieee80211_hw *hw)
 {
-	struct ath_softc *sc = hw->priv;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 
-	ath9k_hw_reset_tsf(ah);
+	mutex_lock(&sc->mutex);
+	ath9k_hw_reset_tsf(sc->sc_ah);
+	mutex_unlock(&sc->mutex);
 }
 
 static int ath9k_ampdu_action(struct ieee80211_hw *hw,
-		       enum ieee80211_ampdu_mlme_action action,
-		       struct ieee80211_sta *sta,
-		       u16 tid, u16 *ssn)
+			      enum ieee80211_ampdu_mlme_action action,
+			      struct ieee80211_sta *sta,
+			      u16 tid, u16 *ssn)
 {
-	struct ath_softc *sc = hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 	int ret = 0;
 
 	switch (action) {
@@ -2473,7 +2730,7 @@ static int ath9k_ampdu_action(struct iee
 
 		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
 		break;
-	case IEEE80211_AMPDU_TX_RESUME:
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
 		ath_tx_aggr_resume(sc, sta, tid);
 		break;
 	default:
@@ -2483,7 +2740,41 @@ static int ath9k_ampdu_action(struct iee
 	return ret;
 }
 
-static struct ieee80211_ops ath9k_ops = {
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	if (ath9k_wiphy_scanning(sc)) {
+		printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+		       "same time\n");
+		/*
+		 * Do not allow the concurrent scanning state for now. This
+		 * could be improved with scanning control moved into ath9k.
+		 */
+		return;
+	}
+
+	aphy->state = ATH_WIPHY_SCAN;
+	ath9k_wiphy_pause_all_forced(sc, aphy);
+
+	mutex_lock(&sc->mutex);
+	sc->sc_flags |= SC_OP_SCANNING;
+	mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	mutex_lock(&sc->mutex);
+	aphy->state = ATH_WIPHY_ACTIVE;
+	sc->sc_flags &= ~SC_OP_SCANNING;
+	mutex_unlock(&sc->mutex);
+}
+
+struct ieee80211_ops ath9k_ops = {
 	.tx 		    = ath9k_tx,
 	.start 		    = ath9k_start,
 	.stop 		    = ath9k_stop,
@@ -2497,8 +2788,11 @@ static struct ieee80211_ops ath9k_ops =
 	.bss_info_changed   = ath9k_bss_info_changed,
 	.set_key            = ath9k_set_key,
 	.get_tsf 	    = ath9k_get_tsf,
+	.set_tsf 	    = ath9k_set_tsf,
 	.reset_tsf 	    = ath9k_reset_tsf,
 	.ampdu_action       = ath9k_ampdu_action,
+	.sw_scan_start      = ath9k_sw_scan_start,
+	.sw_scan_complete   = ath9k_sw_scan_complete,
 };
 
 static struct {
@@ -2527,7 +2821,7 @@ static struct {
 /*
  * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
  */
-static const char *
+const char *
 ath_mac_bb_name(u32 mac_bb_version)
 {
 	int i;
@@ -2544,7 +2838,7 @@ ath_mac_bb_name(u32 mac_bb_version)
 /*
  * Return the RF name. "????" is returned if the RF is unknown.
  */
-static const char *
+const char *
 ath_rf_name(u16 rf_version)
 {
 	int i;
@@ -2558,254 +2852,62 @@ ath_rf_name(u16 rf_version)
 	return "????";
 }
 
-static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	void __iomem *mem;
-	struct ath_softc *sc;
-	struct ieee80211_hw *hw;
-	u8 csz;
-	u32 val;
-	int ret = 0;
-	struct ath_hal *ah;
-
-	if (pci_enable_device(pdev))
-		return -EIO;
-
-	ret =  pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-
-	if (ret) {
-		printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
-		goto bad;
-	}
-
-	ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-
-	if (ret) {
-		printk(KERN_ERR "ath9k: 32-bit DMA consistent "
-			"DMA enable failed\n");
-		goto bad;
-	}
-
-	/*
-	 * Cache line size is used to size and align various
-	 * structures used to communicate with the hardware.
-	 */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
-	if (csz == 0) {
-		/*
-		 * Linux 2.4.18 (at least) writes the cache line size
-		 * register as a 16-bit wide register which is wrong.
-		 * We must have this setup properly for rx buffer
-		 * DMA to work so force a reasonable value here if it
-		 * comes up zero.
-		 */
-		csz = L1_CACHE_BYTES / sizeof(u32);
-		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
-	}
-	/*
-	 * The default setting of latency timer yields poor results,
-	 * set it to the value used by other systems. It may be worth
-	 * tweaking this setting more.
-	 */
-	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
-	pci_set_master(pdev);
-
-	/*
-	 * Disable the RETRY_TIMEOUT register (0x41) to keep
-	 * PCI Tx retries from interfering with C3 CPU state.
-	 */
-	pci_read_config_dword(pdev, 0x40, &val);
-	if ((val & 0x0000ff00) != 0)
-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
-	ret = pci_request_region(pdev, 0, "ath9k");
-	if (ret) {
-		dev_err(&pdev->dev, "PCI memory region reserve error\n");
-		ret = -ENODEV;
-		goto bad;
-	}
-
-	mem = pci_iomap(pdev, 0, 0);
-	if (!mem) {
-		printk(KERN_ERR "PCI memory map error\n") ;
-		ret = -EIO;
-		goto bad1;
-	}
-
-	hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
-	if (hw == NULL) {
-		printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
-		goto bad2;
-	}
-
-	SET_IEEE80211_DEV(hw, &pdev->dev);
-	pci_set_drvdata(pdev, hw);
-
-	sc = hw->priv;
-	sc->hw = hw;
-	sc->pdev = pdev;
-	sc->mem = mem;
-
-	if (ath_attach(id->device, sc) != 0) {
-		ret = -ENODEV;
-		goto bad3;
-	}
-
-	/* setup interrupt service routine */
-
-	if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
-		printk(KERN_ERR "%s: request_irq failed\n",
-			wiphy_name(hw->wiphy));
-		ret = -EIO;
-		goto bad4;
-	}
-
-	ah = sc->sc_ah;
-	printk(KERN_INFO
-	       "%s: Atheros AR%s MAC/BB Rev:%x "
-	       "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
-	       wiphy_name(hw->wiphy),
-	       ath_mac_bb_name(ah->ah_macVersion),
-	       ah->ah_macRev,
-	       ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-	       ah->ah_phyRev,
-	       (unsigned long)mem, pdev->irq);
-
-	return 0;
-bad4:
-	ath_detach(sc);
-bad3:
-	ieee80211_free_hw(hw);
-bad2:
-	pci_iounmap(pdev, mem);
-bad1:
-	pci_release_region(pdev, 0);
-bad:
-	pci_disable_device(pdev);
-	return ret;
-}
-
-static void ath_pci_remove(struct pci_dev *pdev)
-{
-	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-	struct ath_softc *sc = hw->priv;
-
-	ath_detach(sc);
-	if (pdev->irq)
-		free_irq(pdev->irq, sc);
-	pci_iounmap(pdev, sc->mem);
-	pci_release_region(pdev, 0);
-	pci_disable_device(pdev);
-	ieee80211_free_hw(hw);
-}
-
-#ifdef CONFIG_PM
-
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-	struct ath_softc *sc = hw->priv;
-
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev, 3);
-
-	return 0;
-}
-
-static int ath_pci_resume(struct pci_dev *pdev)
-{
-	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-	struct ath_softc *sc = hw->priv;
-	u32 val;
-	int err;
-
-	err = pci_enable_device(pdev);
-	if (err)
-		return err;
-	pci_restore_state(pdev);
-	/*
-	 * Suspend/Resume resets the PCI configuration space, so we have to
-	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
-	 * PCI Tx retries from interfering with C3 CPU state
-	 */
-	pci_read_config_dword(pdev, 0x40, &val);
-	if ((val & 0x0000ff00) != 0)
-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
-	/* Enable LED */
-	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
-			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-	/*
-	 * check the h/w rfkill state on resume
-	 * and start the rfkill poll timer
-	 */
-	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-		queue_delayed_work(sc->hw->workqueue,
-				   &sc->rf_kill.rfkill_poll, 0);
-#endif
-
-	return 0;
-}
-
-#endif /* CONFIG_PM */
-
-MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
-
-static struct pci_driver ath_pci_driver = {
-	.name       = "ath9k",
-	.id_table   = ath_pci_id_table,
-	.probe      = ath_pci_probe,
-	.remove     = ath_pci_remove,
-#ifdef CONFIG_PM
-	.suspend    = ath_pci_suspend,
-	.resume     = ath_pci_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_ath_pci(void)
+static int __init ath9k_init(void)
 {
 	int error;
 
-	printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
-
 	/* Register rate control algorithm */
 	error = ath_rate_control_register();
 	if (error != 0) {
 		printk(KERN_ERR
-			"Unable to register rate control algorithm: %d\n",
+			"ath9k: Unable to register rate control "
+			"algorithm: %d\n",
 			error);
-		ath_rate_control_unregister();
-		return error;
+		goto err_out;
 	}
 
-	if (pci_register_driver(&ath_pci_driver) < 0) {
+	error = ath9k_debug_create_root();
+	if (error) {
 		printk(KERN_ERR
-			"ath_pci: No devices found, driver not installed.\n");
-		ath_rate_control_unregister();
-		pci_unregister_driver(&ath_pci_driver);
-		return -ENODEV;
+			"ath9k: Unable to create debugfs root: %d\n",
+			error);
+		goto err_rate_unregister;
+	}
+
+	error = ath_pci_init();
+	if (error < 0) {
+		printk(KERN_ERR
+			"ath9k: No PCI devices found, driver not installed.\n");
+		error = -ENODEV;
+		goto err_remove_root;
+	}
+
+	error = ath_ahb_init();
+	if (error < 0) {
+		error = -ENODEV;
+		goto err_pci_exit;
 	}
 
 	return 0;
+
+ err_pci_exit:
+	ath_pci_exit();
+
+ err_remove_root:
+	ath9k_debug_remove_root();
+ err_rate_unregister:
+	ath_rate_control_unregister();
+ err_out:
+	return error;
 }
-module_init(init_ath_pci);
+module_init(ath9k_init);
 
-static void __exit exit_ath_pci(void)
+static void __exit ath9k_exit(void)
 {
+	ath_ahb_exit();
+	ath_pci_exit();
+	ath9k_debug_remove_root();
 	ath_rate_control_unregister();
-	pci_unregister_driver(&ath_pci_driver);
 	printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
 }
-module_exit(exit_ath_pci);
+module_exit(ath9k_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -9,8 +9,11 @@ ath9k-y +=	hw.o \
 		main.o \
 		recv.o \
 		xmit.o \
+		virtual.o \
 		rc.o
 
+ath9k-$(CONFIG_PCI) += pci.o
+ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/pci.h>
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+	{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
+	{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+	{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
+	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+	{ 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+{
+	u8 u8tmp;
+
+	pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
+			     (u8 *)&u8tmp);
+	*csz = (int)u8tmp;
+
+	/*
+	 * This check was put in to avoid "unplesant" consequences if
+	 * the bootrom has not fully initialized all PCI devices.
+	 * Sometimes the cache line size register is not set
+	 */
+
+	if (*csz == 0)
+		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
+}
+
+static void ath_pci_cleanup(struct ath_softc *sc)
+{
+	struct pci_dev *pdev = to_pci_dev(sc->dev);
+
+	pci_iounmap(pdev, sc->mem);
+	pci_disable_device(pdev);
+	pci_release_region(pdev, 0);
+}
+
+static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+	(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+	if (!ath9k_hw_wait(ah,
+			   AR_EEPROM_STATUS_DATA,
+			   AR_EEPROM_STATUS_DATA_BUSY |
+			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+			   AH_WAIT_TIMEOUT)) {
+		return false;
+	}
+
+	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+		   AR_EEPROM_STATUS_DATA_VAL);
+
+	return true;
+}
+
+static struct ath_bus_ops ath_pci_bus_ops = {
+	.read_cachesize = ath_pci_read_cachesize,
+	.cleanup = ath_pci_cleanup,
+	.eeprom_read = ath_pci_eeprom_read,
+};
+
+static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	void __iomem *mem;
+	struct ath_wiphy *aphy;
+	struct ath_softc *sc;
+	struct ieee80211_hw *hw;
+	u8 csz;
+	int ret = 0;
+	struct ath_hw *ah;
+
+	if (pci_enable_device(pdev))
+		return -EIO;
+
+	ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	if (ret) {
+		printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
+		goto bad;
+	}
+
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	if (ret) {
+		printk(KERN_ERR "ath9k: 32-bit DMA consistent "
+			"DMA enable failed\n");
+		goto bad;
+	}
+
+	/*
+	 * Cache line size is used to size and align various
+	 * structures used to communicate with the hardware.
+	 */
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+	if (csz == 0) {
+		/*
+		 * Linux 2.4.18 (at least) writes the cache line size
+		 * register as a 16-bit wide register which is wrong.
+		 * We must have this setup properly for rx buffer
+		 * DMA to work so force a reasonable value here if it
+		 * comes up zero.
+		 */
+		csz = L1_CACHE_BYTES / sizeof(u32);
+		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+	}
+	/*
+	 * The default setting of latency timer yields poor results,
+	 * set it to the value used by other systems. It may be worth
+	 * tweaking this setting more.
+	 */
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+	pci_set_master(pdev);
+
+	ret = pci_request_region(pdev, 0, "ath9k");
+	if (ret) {
+		dev_err(&pdev->dev, "PCI memory region reserve error\n");
+		ret = -ENODEV;
+		goto bad;
+	}
+
+	mem = pci_iomap(pdev, 0, 0);
+	if (!mem) {
+		printk(KERN_ERR "PCI memory map error\n") ;
+		ret = -EIO;
+		goto bad1;
+	}
+
+	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+				sizeof(struct ath_softc), &ath9k_ops);
+	if (hw == NULL) {
+		printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+		goto bad2;
+	}
+
+	SET_IEEE80211_DEV(hw, &pdev->dev);
+	pci_set_drvdata(pdev, hw);
+
+	aphy = hw->priv;
+	sc = (struct ath_softc *) (aphy + 1);
+	aphy->sc = sc;
+	aphy->hw = hw;
+	sc->pri_wiphy = aphy;
+	sc->hw = hw;
+	sc->dev = &pdev->dev;
+	sc->mem = mem;
+	sc->bus_ops = &ath_pci_bus_ops;
+
+	if (ath_attach(id->device, sc) != 0) {
+		ret = -ENODEV;
+		goto bad3;
+	}
+
+	/* setup interrupt service routine */
+
+	if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
+		printk(KERN_ERR "%s: request_irq failed\n",
+			wiphy_name(hw->wiphy));
+		ret = -EIO;
+		goto bad4;
+	}
+
+	sc->irq = pdev->irq;
+
+	ah = sc->sc_ah;
+	printk(KERN_INFO
+	       "%s: Atheros AR%s MAC/BB Rev:%x "
+	       "AR%s RF Rev:%x: 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,
+	       (unsigned long)mem, pdev->irq);
+
+	return 0;
+bad4:
+	ath_detach(sc);
+bad3:
+	ieee80211_free_hw(hw);
+bad2:
+	pci_iounmap(pdev, mem);
+bad1:
+	pci_release_region(pdev, 0);
+bad:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+static void ath_pci_remove(struct pci_dev *pdev)
+{
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	ath_cleanup(sc);
+}
+
+#ifdef CONFIG_PM
+
+static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+
+	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+		cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	return 0;
+}
+
+static int ath_pci_resume(struct pci_dev *pdev)
+{
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	int err;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+	pci_restore_state(pdev);
+
+	/* Enable LED */
+	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+	/*
+	 * check the h/w rfkill state on resume
+	 * and start the rfkill poll timer
+	 */
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+		queue_delayed_work(sc->hw->workqueue,
+				   &sc->rf_kill.rfkill_poll, 0);
+#endif
+
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
+MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
+
+static struct pci_driver ath_pci_driver = {
+	.name       = "ath9k",
+	.id_table   = ath_pci_id_table,
+	.probe      = ath_pci_probe,
+	.remove     = ath_pci_remove,
+#ifdef CONFIG_PM
+	.suspend    = ath_pci_suspend,
+	.resume     = ath_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+int ath_pci_init(void)
+{
+	return pci_register_driver(&ath_pci_driver);
+}
+
+void ath_pci_exit(void)
+{
+	pci_unregister_driver(&ath_pci_driver);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/phy.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/phy.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/phy.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/phy.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,22 +14,17 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
 
 void
-ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
+ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
 		    int regWrites)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
+	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 }
 
 bool
-ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u32 channelSel = 0;
 	u32 bModeSynth = 0;
@@ -95,15 +90,14 @@ ath9k_hw_set_channel(struct ath_hal *ah,
 
 	REG_WRITE(ah, AR_PHY(0x37), reg32);
 
-	ah->ah_curchan = chan;
-
-	AH5416(ah)->ah_curchanRadIndex = -1;
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
 
 	return true;
 }
 
 bool
-ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 			    struct ath9k_channel *chan)
 {
 	u16 bMode, fracMode, aModeRefSel = 0;
@@ -138,20 +132,27 @@ ath9k_hw_ar9280_set_channel(struct ath_h
 		bMode = 0;
 		fracMode = 0;
 
-		if ((freq % 20) == 0) {
-			aModeRefSel = 3;
-		} else if ((freq % 10) == 0) {
-			aModeRefSel = 2;
-		} else {
+		switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+		case 0:
+			if ((freq % 20) == 0) {
+				aModeRefSel = 3;
+			} else if ((freq % 10) == 0) {
+				aModeRefSel = 2;
+			}
+			if (aModeRefSel)
+				break;
+		case 1:
+		default:
 			aModeRefSel = 0;
-
 			fracMode = 1;
 			refDivA = 1;
 			channelSel = (freq * 0x8000) / 15;
 
 			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
 				      AR_AN_SYNTH9_REFDIVA, refDivA);
+
 		}
+
 		if (!fracMode) {
 			ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
 			channelSel = ndiv & 0x1ff;
@@ -166,9 +167,8 @@ ath9k_hw_ar9280_set_channel(struct ath_h
 
 	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
 
-	ah->ah_curchan = chan;
-
-	AH5416(ah)->ah_curchanRadIndex = -1;
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
 
 	return true;
 }
@@ -201,11 +201,9 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u
 }
 
 bool
-ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 		     u16 modesIndex)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	u32 eepMinorRev;
 	u32 ob5GHz = 0, db5GHz = 0;
 	u32 ob2GHz = 0, db2GHz = 0;
@@ -214,161 +212,156 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah,
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		return true;
 
-	eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
+	eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
 
-	RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
+	RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
 
-	RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
+	RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
 
-	RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
+	RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
 
-	RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
+	RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
 		      modesIndex);
 	{
 		int i;
-		for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
-			ahp->ah_analogBank6Data[i] =
-			    INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
+		for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+			ah->analogBank6Data[i] =
+			    INI_RA(&ah->iniBank6TPC, i, modesIndex);
 		}
 	}
 
 	if (eepMinorRev >= 2) {
 		if (IS_CHAN_2GHZ(chan)) {
-			ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
-			db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
-			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+			db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
 						   ob2GHz, 3, 197, 0);
-			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
 						   db2GHz, 3, 194, 0);
 		} else {
-			ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
-			db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
-			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+			db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
 						   ob5GHz, 3, 203, 0);
-			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
 						   db5GHz, 3, 200, 0);
 		}
 	}
 
-	RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
+	RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
 
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
 			   regWrites);
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
 			   regWrites);
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
 			   regWrites);
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
 			   regWrites);
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
 			   regWrites);
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
+	REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
 			   regWrites);
 
 	return true;
 }
 
 void
-ath9k_hw_rfdetach(struct ath_hal *ah)
+ath9k_hw_rfdetach(struct ath_hw *ah)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
-	if (ahp->ah_analogBank0Data != NULL) {
-		kfree(ahp->ah_analogBank0Data);
-		ahp->ah_analogBank0Data = NULL;
+	if (ah->analogBank0Data != NULL) {
+		kfree(ah->analogBank0Data);
+		ah->analogBank0Data = NULL;
 	}
-	if (ahp->ah_analogBank1Data != NULL) {
-		kfree(ahp->ah_analogBank1Data);
-		ahp->ah_analogBank1Data = NULL;
+	if (ah->analogBank1Data != NULL) {
+		kfree(ah->analogBank1Data);
+		ah->analogBank1Data = NULL;
 	}
-	if (ahp->ah_analogBank2Data != NULL) {
-		kfree(ahp->ah_analogBank2Data);
-		ahp->ah_analogBank2Data = NULL;
+	if (ah->analogBank2Data != NULL) {
+		kfree(ah->analogBank2Data);
+		ah->analogBank2Data = NULL;
 	}
-	if (ahp->ah_analogBank3Data != NULL) {
-		kfree(ahp->ah_analogBank3Data);
-		ahp->ah_analogBank3Data = NULL;
+	if (ah->analogBank3Data != NULL) {
+		kfree(ah->analogBank3Data);
+		ah->analogBank3Data = NULL;
 	}
-	if (ahp->ah_analogBank6Data != NULL) {
-		kfree(ahp->ah_analogBank6Data);
-		ahp->ah_analogBank6Data = NULL;
+	if (ah->analogBank6Data != NULL) {
+		kfree(ah->analogBank6Data);
+		ah->analogBank6Data = NULL;
 	}
-	if (ahp->ah_analogBank6TPCData != NULL) {
-		kfree(ahp->ah_analogBank6TPCData);
-		ahp->ah_analogBank6TPCData = NULL;
+	if (ah->analogBank6TPCData != NULL) {
+		kfree(ah->analogBank6TPCData);
+		ah->analogBank6TPCData = NULL;
 	}
-	if (ahp->ah_analogBank7Data != NULL) {
-		kfree(ahp->ah_analogBank7Data);
-		ahp->ah_analogBank7Data = NULL;
+	if (ah->analogBank7Data != NULL) {
+		kfree(ah->analogBank7Data);
+		ah->analogBank7Data = NULL;
 	}
-	if (ahp->ah_addac5416_21 != NULL) {
-		kfree(ahp->ah_addac5416_21);
-		ahp->ah_addac5416_21 = NULL;
+	if (ah->addac5416_21 != NULL) {
+		kfree(ah->addac5416_21);
+		ah->addac5416_21 = NULL;
 	}
-	if (ahp->ah_bank6Temp != NULL) {
-		kfree(ahp->ah_bank6Temp);
-		ahp->ah_bank6Temp = NULL;
+	if (ah->bank6Temp != NULL) {
+		kfree(ah->bank6Temp);
+		ah->bank6Temp = NULL;
 	}
 }
 
-bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
+bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 {
-	struct ath_hal_5416 *ahp = AH5416(ah);
-
 	if (!AR_SREV_9280_10_OR_LATER(ah)) {
-
-		ahp->ah_analogBank0Data =
+		ah->analogBank0Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank1Data =
+			     ah->iniBank0.ia_rows), GFP_KERNEL);
+		ah->analogBank1Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank2Data =
+			     ah->iniBank1.ia_rows), GFP_KERNEL);
+		ah->analogBank2Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank3Data =
+			     ah->iniBank2.ia_rows), GFP_KERNEL);
+		ah->analogBank3Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank6Data =
+			     ah->iniBank3.ia_rows), GFP_KERNEL);
+		ah->analogBank6Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank6TPCData =
+			     ah->iniBank6.ia_rows), GFP_KERNEL);
+		ah->analogBank6TPCData =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
-		ahp->ah_analogBank7Data =
+			     ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+		ah->analogBank7Data =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
+			     ah->iniBank7.ia_rows), GFP_KERNEL);
 
-		if (ahp->ah_analogBank0Data == NULL
-		    || ahp->ah_analogBank1Data == NULL
-		    || ahp->ah_analogBank2Data == NULL
-		    || ahp->ah_analogBank3Data == NULL
-		    || ahp->ah_analogBank6Data == NULL
-		    || ahp->ah_analogBank6TPCData == NULL
-		    || ahp->ah_analogBank7Data == NULL) {
+		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;
 		}
 
-		ahp->ah_addac5416_21 =
+		ah->addac5416_21 =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniAddac.ia_rows *
-			     ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
-		if (ahp->ah_addac5416_21 == NULL) {
+			     ah->iniAddac.ia_rows *
+			     ah->iniAddac.ia_columns), GFP_KERNEL);
+		if (ah->addac5416_21 == NULL) {
 			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Cannot allocate ah_addac5416_21\n");
+				"Cannot allocate addac5416_21\n");
 			*status = -ENOMEM;
 			return false;
 		}
 
-		ahp->ah_bank6Temp =
+		ah->bank6Temp =
 		    kzalloc((sizeof(u32) *
-			     ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
-		if (ahp->ah_bank6Temp == NULL) {
+			     ah->iniBank6.ia_rows), GFP_KERNEL);
+		if (ah->bank6Temp == NULL) {
 			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Cannot allocate ah_bank6Temp\n");
+				"Cannot allocate bank6Temp\n");
 			*status = -ENOMEM;
 			return false;
 		}
@@ -378,24 +371,23 @@ bool ath9k_hw_init_rf(struct ath_hal *ah
 }
 
 void
-ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	int i, regWrites = 0;
-	struct ath_hal_5416 *ahp = AH5416(ah);
 	u32 bank6SelMask;
-	u32 *bank6Temp = ahp->ah_bank6Temp;
+	u32 *bank6Temp = ah->bank6Temp;
 
-	switch (ahp->ah_diversityControl) {
+	switch (ah->diversity_control) {
 	case ATH9K_ANT_FIXED_A:
 		bank6SelMask =
-		    (ahp->
-		     ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+		    (ah->
+		     antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
 		    REDUCE_CHAIN_1;
 		break;
 	case ATH9K_ANT_FIXED_B:
 		bank6SelMask =
-		    (ahp->
-		     ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+		    (ah->
+		     antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
 		    REDUCE_CHAIN_0;
 		break;
 	case ATH9K_ANT_VARIABLE:
@@ -406,8 +398,8 @@ ath9k_hw_decrease_chain_power(struct ath
 		break;
 	}
 
-	for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
-		bank6Temp[i] = ahp->ah_analogBank6Data[i];
+	for (i = 0; i < ah->iniBank6.ia_rows; i++)
+		bank6Temp[i] = ah->analogBank6Data[i];
 
 	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
 
@@ -421,7 +413,7 @@ ath9k_hw_decrease_chain_power(struct ath
 	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
 	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
 
-	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
+	REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
 
 	REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
 #ifdef ALTER_SWITCH
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/phy.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/phy.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/phy.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/phy.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -17,19 +17,19 @@
 #ifndef PHY_H
 #define PHY_H
 
-bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 				 struct ath9k_channel
 				 *chan);
-bool ath9k_hw_set_channel(struct ath_hal *ah,
+bool ath9k_hw_set_channel(struct ath_hw *ah,
 			  struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
 			 u32 freqIndex, int regWrites);
-bool ath9k_hw_set_rf_regs(struct ath_hal *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_hal *ah,
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
 				   struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hal *ah,
+bool ath9k_hw_init_rf(struct ath_hw *ah,
 		      int *status);
 
 #define AR_PHY_BASE     0x9800
@@ -387,6 +387,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah
 
 #define AR_PHY_CCK_TX_CTRL       0xA204
 #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
 
 #define AR_PHY_CCK_DETECT                           0xA208
 #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
@@ -444,6 +446,32 @@ bool ath9k_hw_init_rf(struct ath_hal *ah
 #define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
 #define AR_PHY_TPCRG1_PD_GAIN_3_S  20
 
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4       0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
+
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
+
+#define AR_PHY_TX_PWRCTRL7       0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+
+#define AR_PHY_TX_GAIN_TBL1      0xa300
+#define AR_PHY_TX_GAIN                     0x0007F000
+#define AR_PHY_TX_GAIN_S                   12
+
 #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
 #define AR_PHY_MASK2_M_31_45     0xa3a4
 #define AR_PHY_MASK2_M_16_30     0xa3a8
@@ -485,6 +513,11 @@ bool ath9k_hw_init_rf(struct ath_hal *ah
 #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
 #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
 
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+
 #define AR_PHY_POWER_TX_RATE5   0xA38C
 #define AR_PHY_POWER_TX_RATE6   0xA390
 
@@ -530,10 +563,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah
 		}							\
 	} while (0)
 
-#define ATH9K_KEY_XOR                 0xaa
-
 #define ATH9K_IS_MIC_ENABLED(ah)					\
-	(AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
+	((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
 
 #define ANTSWAP_AB 0x0001
 #define REDUCE_CHAIN_0 0x00000050
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/rc.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/rc.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/rc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/rc.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2004-2008 Atheros Communications, Inc.
+ * Copyright (c) 2004-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
@@ -15,16 +15,15 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
+#include "ath9k.h"
 
 static struct ath_rate_table ar5416_11na_ratetable = {
 	42,
-	{0},
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, 12,
 			0, 2, 1, 0, 0, 0, 0, 0 },
-		{ VALID,	VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800,  0x0f, 0x00, 18,
 			0, 3, 1, 1, 1, 1, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
@@ -158,7 +157,6 @@ static struct ath_rate_table ar5416_11na
 
 static struct ath_rate_table ar5416_11ng_ratetable = {
 	46,
-	{0},
 	{
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0x1b, 0x00, 2,
@@ -306,7 +304,6 @@ static struct ath_rate_table ar5416_11ng
 
 static struct ath_rate_table ar5416_11a_ratetable = {
 	8,
-	{0},
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, (0x80|12),
@@ -340,7 +337,6 @@ static struct ath_rate_table ar5416_11a_
 
 static struct ath_rate_table ar5416_11g_ratetable = {
 	12,
-	{0},
 	{
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0x1b, 0x00, 2,
@@ -386,7 +382,6 @@ static struct ath_rate_table ar5416_11g_
 
 static struct ath_rate_table ar5416_11b_ratetable = {
 	4,
-	{0},
 	{
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0x1b,  0x00, (0x80|2),
@@ -636,8 +631,7 @@ static u8 ath_rc_setvalid_htrates(struct
 static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
 			     struct ath_rate_priv *ath_rc_priv,
 			     struct ath_rate_table *rate_table,
-			     int probe_allowed, int *is_probing,
-			     int is_retry)
+			     int *is_probing)
 {
 	u32 dt, best_thruput, this_thruput, now_msec;
 	u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -719,13 +713,6 @@ static u8 ath_rc_ratefind_ht(struct ath_
 	}
 
 	rate = best_rate;
-
-	/* if we are retrying for more than half the number
-	 * of max retries, use the min rate for the next retry
-	 */
-	if (is_retry)
-		rate = ath_rc_priv->valid_rate_index[minindex];
-
 	ath_rc_priv->rssi_last_lookup = rssi_last;
 
 	/*
@@ -733,13 +720,12 @@ static u8 ath_rc_ratefind_ht(struct ath_
 	 * non-monoticity of 11g's rate table
 	 */
 
-	if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) {
+	if (rate >= ath_rc_priv->rate_max_phy) {
 		rate = ath_rc_priv->rate_max_phy;
 
 		/* Probe the next allowed phy state */
-		/* FIXME:XXXX Check to make sure ratMax is checked properly */
 		if (ath_rc_get_nextvalid_txrate(rate_table,
-						ath_rc_priv, rate, &next_rate) &&
+					ath_rc_priv, rate, &next_rate) &&
 		    (now_msec - ath_rc_priv->probe_time >
 		     rate_table->probe_interval) &&
 		    (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
@@ -761,14 +747,17 @@ static u8 ath_rc_ratefind_ht(struct ath_
 	return rate;
 }
 
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
+static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
 				   struct ieee80211_tx_rate *rate,
+				   struct ieee80211_tx_rate_control *txrc,
 				   u8 tries, u8 rix, int rtsctsenable)
 {
 	rate->count = tries;
 	rate->idx = rix;
 
-	if (rtsctsenable)
+	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;
@@ -778,6 +767,43 @@ static void ath_rc_rate_set_series(struc
 		rate->flags |= IEEE80211_TX_RC_MCS;
 }
 
+static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
+				   struct ath_rate_table *rate_table,
+				   struct ieee80211_tx_info *tx_info)
+{
+	struct ieee80211_tx_rate *rates = tx_info->control.rates;
+	int i = 0, rix = 0, cix, enable_g_protection = 0;
+
+	/* 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;
+			break;
+		}
+	}
+	cix = rate_table->info[rix].ctrl_rate;
+
+	/* All protection frames are transmited at 2Mb/s for 802.11g,
+	 * otherwise we transmit them at 1Mb/s */
+	if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+	    !conf_is_ht(&sc->hw->conf))
+		enable_g_protection = 1;
+
+	/*
+	 * If 802.11g protection is enabled, determine whether to use RTS/CTS or
+	 * just CTS.  Note that this is only done for OFDM/HT unicast frames.
+	 */
+	if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+	    !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+	    (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
+	     WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
+		rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
+		cix = rate_table->info[enable_g_protection].ctrl_rate;
+	}
+
+	tx_info->control.rts_cts_rate_idx = cix;
+}
+
 static u8 ath_rc_rate_getidx(struct ath_softc *sc,
 			     struct ath_rate_priv *ath_rc_priv,
 			     struct ath_rate_table *rate_table,
@@ -809,54 +835,58 @@ static u8 ath_rc_rate_getidx(struct ath_
 
 static void ath_rc_ratefind(struct ath_softc *sc,
 			    struct ath_rate_priv *ath_rc_priv,
-			    int num_tries, int num_rates,
-			    struct ieee80211_tx_info *tx_info, int *is_probe,
-			    int is_retry)
+			    struct ieee80211_tx_rate_control *txrc)
 {
-	u8 try_per_rate = 0, i = 0, rix, nrix;
 	struct ath_rate_table *rate_table;
+	struct sk_buff *skb = txrc->skb;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_rate *rates = tx_info->control.rates;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	__le16 fc = hdr->frame_control;
+	u8 try_per_rate = 0, i = 0, rix, nrix;
+	int is_probe = 0;
 
 	rate_table = sc->cur_rate_table;
-	rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
-				 is_probe, is_retry);
+	rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
 	nrix = rix;
 
-	if (*is_probe) {
+	if (is_probe) {
 		/* set one try for probe rates. For the
 		 * probes don't enable rts */
-		ath_rc_rate_set_series(rate_table,
-			&rates[i++], 1, nrix, 0);
+		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+				       1, nrix, 0);
 
-		try_per_rate = (num_tries/num_rates);
+		try_per_rate = (ATH_11N_TXMAXTRY/4);
 		/* Get the next tried/allowed rate. No RTS for the next series
 		 * after the probe rate
 		 */
-		nrix = ath_rc_rate_getidx(sc,
-			ath_rc_priv, rate_table, nrix, 1, 0);
-		ath_rc_rate_set_series(rate_table,
-			&rates[i++], try_per_rate, nrix, 0);
+		nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+					  rate_table, nrix, 1, 0);
+		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+				       try_per_rate, nrix, 0);
+
+		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
 	} else {
-		try_per_rate = (num_tries/num_rates);
+		try_per_rate = (ATH_11N_TXMAXTRY/4);
 		/* Set the choosen rate. No RTS for first series entry. */
-		ath_rc_rate_set_series(rate_table,
-			&rates[i++], try_per_rate, nrix, 0);
+		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+				       try_per_rate, nrix, 0);
 	}
 
 	/* Fill in the other rates for multirate retry */
-	for ( ; i < num_rates; i++) {
+	for ( ; i < 4; i++) {
 		u8 try_num;
 		u8 min_rate;
 
-		try_num = ((i + 1) == num_rates) ?
-			num_tries - (try_per_rate * i) : try_per_rate ;
-		min_rate = (((i + 1) == num_rates) && 0);
+		try_num = ((i + 1) == 4) ?
+			ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+		min_rate = (((i + 1) == 4) && 0);
 
 		nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
 					  rate_table, nrix, 1, min_rate);
 		/* All other rates in the series have RTS enabled */
-		ath_rc_rate_set_series(rate_table,
-				       &rates[i], try_num, nrix, 1);
+		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+				       try_num, nrix, 1);
 	}
 
 	/*
@@ -875,7 +905,7 @@ static void ath_rc_ratefind(struct ath_s
 	 * above conditions.
 	 */
 	if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
-	    (sc->hw->conf.ht.enabled)) {
+	    (conf_is_ht(&sc->hw->conf))) {
 		u8 dot11rate = rate_table->info[rix].dot11rate;
 		u8 phy = rate_table->info[rix].phy;
 		if (i == 4 &&
@@ -885,6 +915,24 @@ static void ath_rc_ratefind(struct ath_s
 			rates[3].flags = rates[2].flags;
 		}
 	}
+
+	/*
+	 * Force hardware to use computed duration for next
+	 * fragment by disabling multi-rate retry, which
+	 * updates duration based on the multi-rate duration table.
+	 *
+	 * FIXME: Fix duration
+	 */
+	if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+	    (ieee80211_has_morefrags(fc) ||
+	     (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+		rates[1].count = rates[2].count = rates[3].count = 0;
+		rates[1].idx = rates[2].idx = rates[3].idx = 0;
+		rates[0].count = ATH_TXMAXTRY;
+	}
+
+	/* Setup RTS/CTS */
+	ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
 }
 
 static bool ath_rc_update_per(struct ath_softc *sc,
@@ -1221,6 +1269,9 @@ static void ath_rc_update_ht(struct ath_
 		ath_rc_priv->per_down_time = now_msec;
 	}
 
+	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+			       ath_rc_priv->state[tx_rate].per);
+
 #undef CHK_RSSI
 }
 
@@ -1338,36 +1389,18 @@ static struct ath_rate_table *ath_choose
 static void ath_rc_init(struct ath_softc *sc,
 			struct ath_rate_priv *ath_rc_priv,
 			struct ieee80211_supported_band *sband,
-			struct ieee80211_sta *sta)
+			struct ieee80211_sta *sta,
+			struct ath_rate_table *rate_table)
 {
-	struct ath_rate_table *rate_table = NULL;
 	struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
 	u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
 	u8 i, j, k, hi = 0, hthi = 0;
 
-	/* FIXME: Adhoc */
-	if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
-	    (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) {
-		bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-		rate_table = ath_choose_rate_table(sc, sband->band,
-						   sta->ht_cap.ht_supported,
-						   is_cw_40);
-	} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
-		/* cur_rate_table would be set on init through config() */
-		rate_table = sc->cur_rate_table;
-	}
-
 	if (!rate_table) {
 		DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
 		return;
 	}
 
-	if (sta->ht_cap.ht_supported) {
-		ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG);
-		if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
-			ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
-	}
-
 	/* Initial rate table size. Will change depending
 	 * on the working rate set */
 	ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1387,7 +1420,7 @@ static void ath_rc_init(struct ath_softc
 			ath_rc_priv->valid_phy_rateidx[i][j] = 0;
 		ath_rc_priv->valid_phy_ratecnt[i] = 0;
 	}
-	ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
+	ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG;
 
 	/* Set stream capability */
 	ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
@@ -1395,16 +1428,16 @@ static void ath_rc_init(struct ath_softc
 	if (!rateset->rs_nrates) {
 		/* No working rate, just initialize valid rates */
 		hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
-						ath_rc_priv->ht_cap);
+					    ath_rc_priv->ht_cap);
 	} else {
 		/* Use intersection of working rates and valid rates */
 		hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
-					       rateset, ath_rc_priv->ht_cap);
+					   rateset, ath_rc_priv->ht_cap);
 		if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
 			hthi = ath_rc_setvalid_htrates(ath_rc_priv,
-							   rate_table,
-							   ht_mcs,
-							   ath_rc_priv->ht_cap);
+						       rate_table,
+						       ht_mcs,
+						       ath_rc_priv->ht_cap);
 		}
 		hi = A_MAX(hi, hthi);
 	}
@@ -1432,9 +1465,36 @@ static void ath_rc_init(struct ath_softc
 	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);
 }
 
-/* Rate Control callbacks */
+static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
+			       bool is_cw40, bool is_sgi40)
+{
+	u8 caps = 0;
+
+	if (sta->ht_cap.ht_supported) {
+		caps = WLAN_RC_HT_FLAG;
+		if (sc->sc_ah->caps.tx_chainmask != 1 &&
+		    ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
+			if (sta->ht_cap.mcs.rx_mask[1])
+				caps |= WLAN_RC_DS_FLAG;
+		}
+		if (is_cw40)
+			caps |= WLAN_RC_40_FLAG;
+		if (is_sgi40)
+			caps |= WLAN_RC_SGI_FLAG;
+	}
+
+	return caps;
+}
+
+/***********************************/
+/* mac80211 Rate Control callbacks */
+/***********************************/
+
 static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 			  struct ieee80211_sta *sta, void *priv_sta,
 			  struct sk_buff *skb)
@@ -1467,7 +1527,7 @@ static void ath_tx_status(void *priv, st
 	 */
 	if (tx_info_priv->tx.ts_flags &
 	    (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
-	    ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) {
+	    ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
 		tx_status = 1;
 		is_underrun = 1;
 	}
@@ -1480,6 +1540,23 @@ static void ath_tx_status(void *priv, st
 			 (is_underrun) ? ATH_11N_TXMAXTRY :
 			 tx_info_priv->tx.ts_longretry);
 
+	/* Check if aggregation has to be enabled for this tid */
+	if (conf_is_ht(&sc->hw->conf) &&
+	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+		if (ieee80211_is_data_qos(fc)) {
+			u8 *qc, tid;
+			struct ath_node *an;
+
+			qc = ieee80211_get_qos_ctl(hdr);
+			tid = qc[0] & 0xf;
+			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);
+		}
+	}
+
+	ath_debug_stat_rc(sc, skb);
 exit:
 	kfree(tx_info_priv);
 }
@@ -1490,11 +1567,9 @@ static void ath_get_rate(void *priv, str
 	struct ieee80211_supported_band *sband = txrc->sband;
 	struct sk_buff *skb = txrc->skb;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ath_softc *sc = priv;
-	struct ieee80211_hw *hw = sc->hw;
 	struct ath_rate_priv *ath_rc_priv = priv_sta;
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	int is_probe = 0;
 	__le16 fc = hdr->frame_control;
 
 	/* lowest rate for management and multicast/broadcast frames */
@@ -1507,23 +1582,7 @@ static void ath_get_rate(void *priv, str
 	}
 
 	/* Find tx rate for unicast frames */
-	ath_rc_ratefind(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4,
-			tx_info, &is_probe, false);
-
-	/* Check if aggregation has to be enabled for this tid */
-	if (hw->conf.ht.enabled) {
-		if (ieee80211_is_data_qos(fc)) {
-			u8 *qc, tid;
-			struct ath_node *an;
-
-			qc = ieee80211_get_qos_ctl(hdr);
-			tid = qc[0] & 0xf;
-			an = (struct ath_node *)sta->drv_priv;
-
-			if(ath_tx_aggr_check(sc, an, tid))
-				ieee80211_start_tx_ba_session(hw, hdr->addr1, tid);
-		}
-	}
+	ath_rc_ratefind(sc, ath_rc_priv, txrc);
 }
 
 static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1531,6 +1590,8 @@ static void ath_rate_init(void *priv, st
 {
 	struct ath_softc *sc = priv;
 	struct ath_rate_priv *ath_rc_priv = priv_sta;
+	struct ath_rate_table *rate_table = NULL;
+	bool is_cw40, is_sgi40;
 	int i, j = 0;
 
 	for (i = 0; i < sband->n_bitrates; i++) {
@@ -1552,12 +1613,71 @@ static void ath_rate_init(void *priv, st
 		ath_rc_priv->neg_ht_rates.rs_nrates = j;
 	}
 
-	ath_rc_init(sc, priv_sta, sband, sta);
+	is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+
+	/* Choose rate table first */
+
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+	    (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;
+	}
+
+	ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
+	ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+}
+
+static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
+			    struct ieee80211_sta *sta, void *priv_sta,
+			    u32 changed)
+{
+	struct ath_softc *sc = priv;
+	struct ath_rate_priv *ath_rc_priv = priv_sta;
+	struct ath_rate_table *rate_table = NULL;
+	bool oper_cw40 = false, oper_sgi40;
+	bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
+		true : false;
+	bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
+		true : false;
+
+	/* FIXME: Handle AP mode later when we support CWM */
+
+	if (changed & IEEE80211_RC_HT_CHANGED) {
+		if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+			return;
+
+		if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+		    sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+			oper_cw40 = true;
+
+		oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+			true : false;
+
+		if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+			rate_table = ath_choose_rate_table(sc, sband->band,
+						   sta->ht_cap.ht_supported,
+						   oper_cw40);
+			ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
+						   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);
+		}
+	}
 }
 
 static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
-	return hw->priv;
+	struct ath_wiphy *aphy = hw->priv;
+	return aphy->sc;
 }
 
 static void ath_rate_free(void *priv)
@@ -1578,7 +1698,7 @@ static void *ath_rate_alloc_sta(void *pr
 	}
 
 	rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
-	rate_priv->tx_triglevel_max = sc->sc_ah->ah_caps.tx_triglevel_max;
+	rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
 
 	return rate_priv;
 }
@@ -1596,41 +1716,13 @@ static struct rate_control_ops ath_rate_
 	.tx_status = ath_tx_status,
 	.get_rate = ath_get_rate,
 	.rate_init = ath_rate_init,
+	.rate_update = ath_rate_update,
 	.alloc = ath_rate_alloc,
 	.free = ath_rate_free,
 	.alloc_sta = ath_rate_alloc_sta,
 	.free_sta = ath_rate_free_sta,
 };
 
-static void ath_setup_rate_table(struct ath_softc *sc,
-				 struct ath_rate_table *rate_table)
-{
-	int i;
-
-	for (i = 0; i < 256; i++)
-		rate_table->rateCodeToIndex[i] = (u8)-1;
-
-	for (i = 0; i < rate_table->rate_cnt; i++) {
-		u8 code = rate_table->info[i].ratecode;
-		u8 cix = rate_table->info[i].ctrl_rate;
-		u8 sh = rate_table->info[i].short_preamble;
-
-		rate_table->rateCodeToIndex[code] = i;
-		rate_table->rateCodeToIndex[code | sh] = i;
-
-		rate_table->info[i].lpAckDuration =
-			ath9k_hw_computetxtime(sc->sc_ah, rate_table,
-					       WLAN_CTRL_FRAME_SIZE,
-					       cix,
-					       false);
-		rate_table->info[i].spAckDuration =
-			ath9k_hw_computetxtime(sc->sc_ah, rate_table,
-					       WLAN_CTRL_FRAME_SIZE,
-					       cix,
-					       true);
-	}
-}
-
 void ath_rate_attach(struct ath_softc *sc)
 {
 	sc->hw_rate_table[ATH9K_MODE_11B] =
@@ -1651,12 +1743,6 @@ void ath_rate_attach(struct ath_softc *s
 		&ar5416_11ng_ratetable;
 	sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
 		&ar5416_11ng_ratetable;
-
-	ath_setup_rate_table(sc, &ar5416_11b_ratetable);
-	ath_setup_rate_table(sc, &ar5416_11a_ratetable);
-	ath_setup_rate_table(sc, &ar5416_11g_ratetable);
-	ath_setup_rate_table(sc, &ar5416_11na_ratetable);
-	ath_setup_rate_table(sc, &ar5416_11ng_ratetable);
 }
 
 int ath_rate_control_register(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/rc.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/rc.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/rc.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/rc.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004 Sam Leffler, Errno Consulting
  * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -19,13 +19,12 @@
 #ifndef RC_H
 #define RC_H
 
-#include "ath9k.h"
-
 struct ath_softc;
 
 #define ATH_RATE_MAX     30
 #define RATE_TABLE_SIZE  64
 #define MAX_TX_RATE_PHY  48
+#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
 
 /* VALID_ALL - valid for 20/40/Legacy,
  * VALID - Legacy only,
@@ -39,6 +38,20 @@ struct ath_softc;
 #define VALID_2040 (VALID_20|VALID_40)
 #define VALID_ALL  (VALID_2040|VALID)
 
+enum {
+	WLAN_RC_PHY_OFDM,
+	WLAN_RC_PHY_CCK,
+	WLAN_RC_PHY_HT_20_SS,
+	WLAN_RC_PHY_HT_20_DS,
+	WLAN_RC_PHY_HT_40_SS,
+	WLAN_RC_PHY_HT_40_DS,
+	WLAN_RC_PHY_HT_20_SS_HGI,
+	WLAN_RC_PHY_HT_20_DS_HGI,
+	WLAN_RC_PHY_HT_40_SS_HGI,
+	WLAN_RC_PHY_HT_40_DS_HGI,
+	WLAN_RC_PHY_MAX
+};
+
 #define WLAN_RC_PHY_DS(_phy)   ((_phy == WLAN_RC_PHY_HT_20_DS)		\
 				|| (_phy == WLAN_RC_PHY_HT_40_DS)	\
 				|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI)	\
@@ -90,7 +103,6 @@ struct ath_softc;
  */
 struct ath_rate_table {
 	int rate_cnt;
-	u8 rateCodeToIndex[256];
 	struct {
 		int valid;
 		int valid_single_stream;
@@ -108,8 +120,6 @@ struct ath_rate_table {
 		u8 sgi_index;
 		u8 ht_index;
 		u32 max_4ms_framelen;
-		u16 lpAckDuration;
-		u16 spAckDuration;
 	} info[RATE_TABLE_SIZE];
 	u32 probe_interval;
 	u32 rssi_reduce_interval;
@@ -184,11 +194,19 @@ struct ath_rate_priv {
 	struct ath_rate_softc *asc;
 };
 
+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) \
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/recv.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/recv.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/recv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/recv.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,7 +14,28 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
+#include "ath9k.h"
+
+static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
+					     struct ieee80211_hdr *hdr)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (aphy == NULL)
+			continue;
+		if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
+		    == 0) {
+			hw = aphy->hw;
+			break;
+		}
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+	return hw;
+}
 
 /*
  * Setup and link descriptors.
@@ -26,7 +47,7 @@
  */
 static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_desc *ds;
 	struct sk_buff *skb;
 
@@ -79,7 +100,7 @@ static u64 ath_extend_tsf(struct ath_sof
 	return (tsf & ~0x7fff) | rstamp;
 }
 
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
+static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
 {
 	struct sk_buff *skb;
 	u32 off;
@@ -97,11 +118,11 @@ static struct sk_buff *ath_rxbuf_alloc(s
 	 * Unfortunately this means we may get 8 KB here from the
 	 * kernel... and that is actually what is observed on some
 	 * systems :( */
-	skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
+	skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
 	if (skb != NULL) {
-		off = ((unsigned long) skb->data) % sc->sc_cachelsz;
+		off = ((unsigned long) skb->data) % sc->cachelsz;
 		if (off != 0)
-			skb_reserve(skb, sc->sc_cachelsz - off);
+			skb_reserve(skb, sc->cachelsz - off);
 	} else {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"skbuff alloc of size %u failed\n", len);
@@ -123,10 +144,12 @@ static int ath_rx_prepare(struct sk_buff
 	struct ieee80211_hdr *hdr;
 	u8 ratecode;
 	__le16 fc;
+	struct ieee80211_hw *hw;
 
 	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) {
 		/*
@@ -135,7 +158,7 @@ static int ath_rx_prepare(struct sk_buff
 		 * discard the frame. Enable this if you want to see
 		 * error frames in Monitor mode.
 		 */
-		if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR)
+		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)
@@ -161,7 +184,7 @@ static int ath_rx_prepare(struct sk_buff
 		 * decryption and MIC failures. For monitor mode,
 		 * we also ignore the CRC error.
 		 */
-		if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) {
+		if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
 			if (ds->ds_rxstat.rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
 			      ATH9K_RXERR_CRC))
@@ -186,7 +209,6 @@ static int ath_rx_prepare(struct sk_buff
 		rx_status->rate_idx = ratecode & 0x7f;
 	} else {
 		int i = 0, cur_band, n_rates;
-		struct ieee80211_hw *hw = sc->hw;
 
 		cur_band = hw->conf.channel->band;
 		n_rates = sc->sbands[cur_band].n_bitrates;
@@ -208,9 +230,9 @@ static int ath_rx_prepare(struct sk_buff
 	}
 
 	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
-	rx_status->band = sc->hw->conf.channel->band;
-	rx_status->freq =  sc->hw->conf.channel->center_freq;
-	rx_status->noise = sc->sc_ani.sc_noise_floor;
+	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 = rx_status->noise + ds->ds_rxstat.rs_rssi;
 	rx_status->antenna = ds->ds_rxstat.rs_antenna;
 
@@ -233,7 +255,7 @@ rx_next:
 
 static void ath_opmode_init(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	u32 rfilt, mfilt[2];
 
 	/* configure rx filter */
@@ -241,14 +263,14 @@ static void ath_opmode_init(struct ath_s
 	ath9k_hw_setrxfilter(ah, rfilt);
 
 	/* configure bssid mask */
-	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-		ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+		ath9k_hw_setbssidmask(sc);
 
 	/* configure operational mode */
 	ath9k_hw_setopmode(ah);
 
 	/* Handle any link-level address change. */
-	ath9k_hw_setmac(ah, sc->sc_myaddr);
+	ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
 
 	/* calculate and install multicast filter */
 	mfilt[0] = mfilt[1] = ~0;
@@ -267,11 +289,11 @@ int ath_rx_init(struct ath_softc *sc, in
 		spin_lock_init(&sc->rx.rxbuflock);
 
 		sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-					   min(sc->sc_cachelsz,
+					   min(sc->cachelsz,
 					       (u16)64));
 
 		DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-			sc->sc_cachelsz, sc->rx.bufsize);
+			sc->cachelsz, sc->rx.bufsize);
 
 		/* Initialize rx descriptors */
 
@@ -284,22 +306,22 @@ int ath_rx_init(struct ath_softc *sc, in
 		}
 
 		list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-			skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+			skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
 			if (skb == NULL) {
 				error = -ENOMEM;
 				break;
 			}
 
 			bf->bf_mpdu = skb;
-			bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
+			bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
 							 sc->rx.bufsize,
-							 PCI_DMA_FROMDEVICE);
-			if (unlikely(pci_dma_mapping_error(sc->pdev,
+							 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_CONFIG,
-					"pci_dma_mapping_error() on RX init\n");
+					"dma_mapping_error() on RX init\n");
 				error = -ENOMEM;
 				break;
 			}
@@ -322,8 +344,13 @@ void ath_rx_cleanup(struct ath_softc *sc
 
 	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
 		skb = bf->bf_mpdu;
-		if (skb)
+		if (skb) {
+			dma_unmap_single(sc->dev,
+					 bf->bf_buf_addr,
+					 sc->rx.bufsize,
+					 DMA_FROM_DEVICE);
 			dev_kfree_skb(skb);
+		}
 	}
 
 	if (sc->rx.rxdma.dd_desc_len != 0)
@@ -360,26 +387,39 @@ u32 ath_calcrxfilter(struct ath_softc *s
 		| ATH9K_RX_FILTER_MCAST;
 
 	/* If not a STA, enable processing of Probe Requests */
-	if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION)
+	if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
 		rfilt |= ATH9K_RX_FILTER_PROBEREQ;
 
-	/* Can't set HOSTAP into promiscous mode */
-	if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
+	/*
+	 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
+	 * mode interface or when in monitor mode. AP mode does not need this
+	 * since it receives all in-BSS frames anyway.
+	 */
+	if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
 	     (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
-	    (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
+	    (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
 		rfilt |= ATH9K_RX_FILTER_PROM;
-		/* ??? To prevent from sending ACK */
-		rfilt &= ~ATH9K_RX_FILTER_UCAST;
-	}
 
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION ||
-	    sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)
+	if (sc->rx.rxfilter & FIF_CONTROL)
+		rfilt |= ATH9K_RX_FILTER_CONTROL;
+
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+	    !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+		rfilt |= ATH9K_RX_FILTER_MYBEACON;
+	else
 		rfilt |= ATH9K_RX_FILTER_BEACON;
 
-	/* If in HOSTAP mode, want to enable reception of PSPOLL frames
-	   & beacon frames */
-	if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP)
-		rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
+	/* If in HOSTAP mode, want to enable reception of PSPOLL frames */
+	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+		rfilt |= ATH9K_RX_FILTER_PSPOLL;
+
+	if (sc->sec_wiphy) {
+		/* TODO: only needed if more than one BSSID is in use in
+		 * station/adhoc mode */
+		/* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
+		 */
+		rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+	}
 
 	return rfilt;
 
@@ -388,7 +428,7 @@ u32 ath_calcrxfilter(struct ath_softc *s
 
 int ath_startrecv(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath_buf *bf, *tbf;
 
 	spin_lock_bh(&sc->rx.rxbuflock);
@@ -418,13 +458,12 @@ start_recv:
 
 bool ath_stoprecv(struct ath_softc *sc)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	bool stopped;
 
 	ath9k_hw_stoppcurecv(ah);
 	ath9k_hw_setrxfilter(ah, 0);
 	stopped = ath9k_hw_stopdmarecv(ah);
-	mdelay(3); /* 3ms is long enough for 1 frame */
 	sc->rx.rxlink = NULL;
 
 	return stopped;
@@ -449,11 +488,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
 	struct ath_desc *ds;
 	struct sk_buff *skb = NULL, *requeue_skb;
 	struct ieee80211_rx_status rx_status;
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ieee80211_hdr *hdr;
 	int hdrlen, padsize, retval;
 	bool decrypt_error = false;
 	u8 keyix;
+	__le16 fc;
 
 	spin_lock_bh(&sc->rx.rxbuflock);
 
@@ -524,9 +564,9 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		 * 1. accessing the frame
 		 * 2. requeueing the same buffer to h/w
 		 */
-		pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
+		dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
 				sc->rx.bufsize,
-				PCI_DMA_FROMDEVICE);
+				DMA_FROM_DEVICE);
 
 		/*
 		 * If we're asked to flush receive queue, directly
@@ -547,7 +587,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
 
 		/* Ensure we always have an skb to requeue once we are done
 		 * processing the current buffer's skb */
-		requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+		requeue_skb = ath_rxbuf_alloc(sc, sc->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
@@ -557,9 +597,9 @@ int ath_rx_tasklet(struct ath_softc *sc,
 			goto requeue;
 
 		/* Unmap the frame */
-		pci_unmap_single(sc->pdev, bf->bf_buf_addr,
+		dma_unmap_single(sc->dev, bf->bf_buf_addr,
 				 sc->rx.bufsize,
-				 PCI_DMA_FROMDEVICE);
+				 DMA_FROM_DEVICE);
 
 		skb_put(skb, ds->ds_rxstat.rs_datalen);
 		skb->protocol = cpu_to_be16(ETH_P_CONTROL);
@@ -567,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		/* 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
@@ -590,24 +631,52 @@ int ath_rx_tasklet(struct ath_softc *sc,
 			   && !decrypt_error && skb->len >= hdrlen + 4) {
 			keyix = skb->data[hdrlen + 3] >> 6;
 
-			if (test_bit(keyix, sc->sc_keymap))
+			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(hdr->frame_control)) {
+			/* Use software decrypt for management frames. */
+			rx_status.flag &= ~RX_FLAG_DECRYPTED;
+		}
 
 		/* Send the frame to mac80211 */
-		__ieee80211_rx(sc->hw, skb, &rx_status);
+		if (hdr->addr1[5] & 0x01) {
+			int i;
+			/*
+			 * Deliver broadcast/multicast frames to all suitable
+			 * virtual wiphys.
+			 */
+			/* TODO: filter based on channel configuration */
+			for (i = 0; i < sc->num_sec_wiphy; i++) {
+				struct ath_wiphy *aphy = sc->sec_wiphy[i];
+				struct sk_buff *nskb;
+				if (aphy == NULL)
+					continue;
+				nskb = skb_copy(skb, GFP_ATOMIC);
+				if (nskb)
+					__ieee80211_rx(aphy->hw, nskb,
+						       &rx_status);
+			}
+			__ieee80211_rx(sc->hw, skb, &rx_status);
+		} else {
+			/* Deliver unicast frames based on receiver address */
+			__ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
+				       &rx_status);
+		}
 
 		/* We will now give hardware our shiny new allocated skb */
 		bf->bf_mpdu = requeue_skb;
-		bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
+		bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
 					 sc->rx.bufsize,
-					 PCI_DMA_FROMDEVICE);
-		if (unlikely(pci_dma_mapping_error(sc->pdev,
+					 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_CONFIG,
-				"pci_dma_mapping_error() on RX\n");
+				"dma_mapping_error() on RX\n");
 			break;
 		}
 		bf->bf_dmacontext = bf->bf_buf_addr;
@@ -622,6 +691,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		} else {
 			sc->rx.rxotherant = 0;
 		}
+
+		if (ieee80211_is_beacon(fc) &&
+				(sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
+			sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+		}
 requeue:
 		list_move_tail(&bf->list, &sc->rx.rxbuf);
 		ath_rx_buf_link(sc, bf);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -16,998 +16,504 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include "core.h"
-#include "hw.h"
-#include "regd.h"
+#include "ath9k.h"
 #include "regd_common.h"
 
-static int ath9k_regd_chansort(const void *a, const void *b)
-{
-	const struct ath9k_channel *ca = a;
-	const struct ath9k_channel *cb = b;
+/*
+ * This is a set of common rules used by our world regulatory domains.
+ * We have 12 world regulatory domains. To save space we consolidate
+ * the regulatory domains in 5 structures by frequency and change
+ * the flags on our reg_notifier() on a case by case basis.
+ */
 
-	return (ca->channel == cb->channel) ?
-	    (ca->channelFlags & CHAN_FLAGS) -
-	    (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
-}
+/* Only these channels all allow active scan on all world regulatory domains */
+#define ATH9K_2GHZ_CH01_11	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
 
-static void
-ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
-{
-	u8 *aa = a;
-	u8 *ai, *t;
+/* We enable active scan on these a case by case basis by regulatory domain */
+#define ATH9K_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+					NL80211_RRF_PASSIVE_SCAN)
+#define ATH9K_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
 
-	for (ai = aa + size; --n >= 1; ai += size)
-		for (t = ai; t > aa; t -= size) {
-			u8 *u = t - size;
-			if (cmp(u, t) <= 0)
-				break;
-			swap_array(u, t, size);
-		}
-}
+/* We allow IBSS on these on a case by case basis by regulatory domain */
+#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 
-static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
-{
-	return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
-}
+#define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
+				ATH9K_2GHZ_CH12_13, \
+				ATH9K_2GHZ_CH14
 
-static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask)
-{
-	int i;
+#define ATH9K_5GHZ_ALL		ATH9K_5GHZ_5150_5350, \
+				ATH9K_5GHZ_5470_5850
+/* This one skips what we call "mid band" */
+#define ATH9K_5GHZ_NO_MIDBAND	ATH9K_5GHZ_5150_5350, \
+				ATH9K_5GHZ_5725_5850
 
-	for (i = 0; i < BMLEN; i++) {
-		if (bitmask[i] != 0)
-			return false;
+/* Can be used for:
+ * 0x60, 0x61, 0x62 */
+static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
+	.n_reg_rules = 5,
+	.alpha2 =  "99",
+	.reg_rules = {
+		ATH9K_2GHZ_ALL,
+		ATH9K_5GHZ_ALL,
 	}
-	return true;
-}
+};
 
-static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
-{
-	u16 rd = ath9k_regd_get_eepromRD(ah);
-	int i;
+/* Can be used by 0x63 and 0x65 */
+static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
+	.n_reg_rules = 4,
+	.alpha2 =  "99",
+	.reg_rules = {
+		ATH9K_2GHZ_CH01_11,
+		ATH9K_2GHZ_CH12_13,
+		ATH9K_5GHZ_NO_MIDBAND,
+	}
+};
 
-	if (rd & COUNTRY_ERD_FLAG) {
-		u16 cc = rd & ~COUNTRY_ERD_FLAG;
-		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
-			if (allCountries[i].countryCode == cc)
-				return true;
-	} else {
-		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
-			if (regDomainPairs[i].regDmnEnum == rd)
-				return true;
+/* Can be used by 0x64 only */
+static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
+	.n_reg_rules = 3,
+	.alpha2 =  "99",
+	.reg_rules = {
+		ATH9K_2GHZ_CH01_11,
+		ATH9K_5GHZ_NO_MIDBAND,
 	}
-	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-		 "invalid regulatory domain/country code 0x%x\n", rd);
-	return false;
-}
+};
 
-static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
-{
-	u32 regcap;
+/* Can be used by 0x66 and 0x69 */
+static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
+	.n_reg_rules = 3,
+	.alpha2 =  "99",
+	.reg_rules = {
+		ATH9K_2GHZ_CH01_11,
+		ATH9K_5GHZ_ALL,
+	}
+};
 
-	regcap = ah->ah_caps.reg_cap;
+/* Can be used by 0x67, 0x6A and 0x68 */
+static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
+	.n_reg_rules = 4,
+	.alpha2 =  "99",
+	.reg_rules = {
+		ATH9K_2GHZ_CH01_11,
+		ATH9K_2GHZ_CH12_13,
+		ATH9K_5GHZ_ALL,
+	}
+};
 
-	if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
-		return true;
-	else
-		return false;
+static inline bool is_wwr_sku(u16 regd)
+{
+	return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+		(regd == WORLD);
 }
 
-static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
-				      u16 cc)
+static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
 {
-	u16 rd;
-	int i;
-
-	if (cc == CTRY_DEFAULT)
-		return true;
-	if (cc == CTRY_DEBUG)
-		return true;
-
-	rd = ath9k_regd_get_eepromRD(ah);
-	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd);
-
-	if (rd & COUNTRY_ERD_FLAG) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"EEPROM setting is country code %u\n",
-			rd & ~COUNTRY_ERD_FLAG);
-		return cc == (rd & ~COUNTRY_ERD_FLAG);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
-		if (cc == allCountries[i].countryCode) {
-#ifdef AH_SUPPORT_11D
-			if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
-				return true;
-#endif
-			if (allCountries[i].regDmnEnum == rd ||
-			    rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
-				return true;
-		}
-	}
-	return false;
+	return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
 }
 
-static void
-ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
-			   struct country_code_to_enum_rd *country,
-			   struct regDomain *rd5GHz,
-			   unsigned long *modes_allowed)
+bool ath9k_is_world_regd(struct ath_hw *ah)
 {
-	bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX);
-
-	if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
-	    (!country->allow11g))
-		clear_bit(ATH9K_MODE_11G, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
-	    (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
-		clear_bit(ATH9K_MODE_11A, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes)
-	    && (!country->allow11ng20))
-		clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes)
-	    && (!country->allow11na20))
-		clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
-	    (!country->allow11ng40))
-		clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
-	    (!country->allow11ng40))
-		clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
-	    (!country->allow11na40))
-		clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
-
-	if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
-	    (!country->allow11na40))
-		clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
+	return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
 }
 
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
 {
-	u16 rd;
-
-	rd = ath9k_regd_get_eepromRD(ah);
-
-	switch (rd) {
-	case FCC4_FCCA:
-	case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
-		return true;
-	case DEBUG_REG_DMN:
-	case NO_ENUMRD:
-		if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
-			return true;
-		break;
-	}
-	return false;
+	/* this is the most restrictive */
+	return &ath9k_world_regdom_64;
 }
 
-static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
-		if (allCountries[i].countryCode == countryCode)
-			return &allCountries[i];
+	switch (ah->regulatory.regpair->regDmnEnum) {
+	case 0x60:
+	case 0x61:
+	case 0x62:
+		return &ath9k_world_regdom_60_61_62;
+	case 0x63:
+	case 0x65:
+		return &ath9k_world_regdom_63_65;
+	case 0x64:
+		return &ath9k_world_regdom_64;
+	case 0x66:
+	case 0x69:
+		return &ath9k_world_regdom_66_69;
+	case 0x67:
+	case 0x68:
+	case 0x6A:
+		return &ath9k_world_regdom_67_68_6A;
+	default:
+		WARN_ON(1);
+		return ath9k_default_world_regdomain();
 	}
-	return NULL;
 }
 
-static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
+/* Frequency is one where radar detection is required */
+static bool ath9k_is_radar_freq(u16 center_freq)
 {
-	u16 rd;
-	int i;
-
-	rd = ath9k_regd_get_eepromRD(ah);
-	if (rd & COUNTRY_ERD_FLAG) {
-		struct country_code_to_enum_rd *country = NULL;
-		u16 cc = rd & ~COUNTRY_ERD_FLAG;
-
-		country = ath9k_regd_find_country(cc);
-		if (country != NULL)
-			return cc;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
-		if (regDomainPairs[i].regDmnEnum == rd) {
-			if (regDomainPairs[i].singleCC != 0)
-				return regDomainPairs[i].singleCC;
-			else
-				i = ARRAY_SIZE(regDomainPairs);
-		}
-	return CTRY_DEFAULT;
+	return (center_freq >= 5260 && center_freq <= 5700);
 }
 
-static bool ath9k_regd_is_valid_reg_domain(int regDmn,
-					   struct regDomain *rd)
+/*
+ * N.B: These exception rules do not apply radar freqs.
+ *
+ * - We enable adhoc (or beaconing) if allowed by 11d
+ * - We enable active scan if the channel is allowed by 11d
+ * - If no country IE has been processed and a we determine we have
+ *   received a beacon on a channel we can enable active scan and
+ *   adhoc (or beaconing).
+ */
+static void ath9k_reg_apply_beaconing_flags(
+	struct wiphy *wiphy,
+	enum nl80211_reg_initiator initiator)
 {
-	int i;
+	enum ieee80211_band band;
+	struct ieee80211_supported_band *sband;
+	const struct ieee80211_reg_rule *reg_rule;
+	struct ieee80211_channel *ch;
+	unsigned int i;
+	u32 bandwidth = 0;
+	int r;
 
-	for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
-		if (regDomains[i].regDmnEnum == regDmn) {
-			if (rd != NULL) {
-				memcpy(rd, &regDomains[i],
-				       sizeof(struct regDomain));
-			}
-			return true;
-		}
-	}
-	return false;
-}
+	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 
-static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
-{
-	int i;
+		if (!wiphy->bands[band])
+			continue;
 
-	if (regDmnPair == NO_ENUMRD)
-		return false;
-	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
-		if (regDomainPairs[i].regDmnEnum == regDmnPair)
-			return true;
-	}
-	return false;
-}
+		sband = wiphy->bands[band];
 
-static bool
-ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
-			       u16 channelFlag, struct regDomain *rd)
-{
-	int i, found;
-	u64 flags = NO_REQ;
-	struct reg_dmn_pair_mapping *regPair = NULL;
-	int regOrg;
+		for (i = 0; i < sband->n_channels; i++) {
 
-	regOrg = regDmn;
-	if (regDmn == CTRY_DEFAULT) {
-		u16 rdnum;
-		rdnum = ath9k_regd_get_eepromRD(ah);
+			ch = &sband->channels[i];
 
-		if (!(rdnum & COUNTRY_ERD_FLAG)) {
-			if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
-			    ath9k_regd_is_valid_reg_domainPair(rdnum)) {
-				regDmn = rdnum;
-			}
-		}
-	}
+			if (ath9k_is_radar_freq(ch->center_freq) ||
+			    (ch->flags & IEEE80211_CHAN_RADAR))
+				continue;
 
-	if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
-		for (i = 0, found = 0;
-		     (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
-			if (regDomainPairs[i].regDmnEnum == regDmn) {
-				regPair = &regDomainPairs[i];
-				found = 1;
+			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+				r = freq_reg_info(wiphy, ch->center_freq,
+					&bandwidth, &reg_rule);
+				if (r)
+					continue;
+				/*
+				 * If 11d had a rule for this channel ensure
+				 * we enable adhoc/beaconing if it allows us to
+				 * use it. Note that we would have disabled it
+				 * by applying our static world regdomain by
+				 * default during init, prior to calling our
+				 * regulatory_hint().
+				 */
+				if (!(reg_rule->flags &
+				    NL80211_RRF_NO_IBSS))
+					ch->flags &=
+					  ~IEEE80211_CHAN_NO_IBSS;
+				if (!(reg_rule->flags &
+				    NL80211_RRF_PASSIVE_SCAN))
+					ch->flags &=
+					  ~IEEE80211_CHAN_PASSIVE_SCAN;
+			} else {
+				if (ch->beacon_found)
+					ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+					  IEEE80211_CHAN_PASSIVE_SCAN);
 			}
 		}
-		if (!found) {
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"Failed to find reg domain pair %u\n", regDmn);
-			return false;
-		}
-		if (!(channelFlag & CHANNEL_2GHZ)) {
-			regDmn = regPair->regDmn5GHz;
-			flags = regPair->flags5GHz;
-		}
-		if (channelFlag & CHANNEL_2GHZ) {
-			regDmn = regPair->regDmn2GHz;
-			flags = regPair->flags2GHz;
-		}
 	}
 
-	found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
-	if (!found) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Failed to find unitary reg domain %u\n", regDmn);
-		return false;
-	} else {
-		rd->pscan &= regPair->pscanMask;
-		if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
-		    (flags != NO_REQ)) {
-			rd->flags = flags;
-		}
-
-		rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
-		    REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
-		return true;
-	}
 }
 
-static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
+/* Allows active scan scan on Ch 12 and 13 */
+static void ath9k_reg_apply_active_scan_flags(
+	struct wiphy *wiphy,
+	enum nl80211_reg_initiator initiator)
 {
-	int byteOffset, bitnum;
-	u64 val;
-
-	byteOffset = bit / 64;
-	bitnum = bit - byteOffset * 64;
-	val = ((u64) 1) << bitnum;
-	if (bitmask[byteOffset] & val)
-		return true;
-	else
-		return false;
-}
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	const struct ieee80211_reg_rule *reg_rule;
+	u32 bandwidth = 0;
+	int r;
 
-static void
-ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
-			   u32 *nregids, u8 regclassid)
-{
-	int i;
+	sband = wiphy->bands[IEEE80211_BAND_2GHZ];
 
-	if (regclassid == 0)
+	/*
+	 * If no country IE has been received always enable active scan
+	 * on these channels. This is only done for specific regulatory SKUs
+	 */
+	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+		ch = &sband->channels[11]; /* CH 12 */
+		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+		ch = &sband->channels[12]; /* CH 13 */
+		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
 		return;
-
-	for (i = 0; i < maxregids; i++) {
-		if (regclassids[i] == regclassid)
-			return;
-		if (regclassids[i] == 0)
-			break;
 	}
 
-	if (i == maxregids)
-		return;
-	else {
-		regclassids[i] = regclassid;
-		*nregids += 1;
+	/*
+	 * If a country IE has been recieved check its rule for this
+	 * channel first before enabling active scan. The passive scan
+	 * would have been enforced by the initial processing of our
+	 * custom regulatory domain.
+	 */
+
+	ch = &sband->channels[11]; /* CH 12 */
+	r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+	if (!r) {
+		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
 	}
 
-	return;
+	ch = &sband->channels[12]; /* CH 13 */
+	r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+	if (!r) {
+		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+	}
 }
 
-static bool
-ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
-				   enum reg_ext_bitmap bit)
+/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
 {
-	return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
-}
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	unsigned int i;
 
-#ifdef ATH_NF_PER_CHAN
+	if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+		return;
 
-static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
-				      int nchans)
-{
-	int i, j, next;
+	sband = wiphy->bands[IEEE80211_BAND_5GHZ];
 
-	for (next = 0; next < nchans; next++) {
-		for (i = 0; i < NUM_NF_READINGS; i++) {
-			ichans[next].nfCalHist[i].currIndex = 0;
-			ichans[next].nfCalHist[i].privNF =
-			    AR_PHY_CCA_MAX_GOOD_VALUE;
-			ichans[next].nfCalHist[i].invalidNFcount =
-			    AR_PHY_CCA_FILTERWINDOW_LENGTH;
-			for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-				ichans[next].nfCalHist[i].nfCalBuffer[j] =
-				    AR_PHY_CCA_MAX_GOOD_VALUE;
-			}
-		}
+	for (i = 0; i < sband->n_channels; i++) {
+		ch = &sband->channels[i];
+		if (!ath9k_is_radar_freq(ch->center_freq))
+			continue;
+		/* We always enable radar detection/DFS on this
+		 * frequency range. Additionally we also apply on
+		 * this frequency range:
+		 * - If STA mode does not yet have DFS supports disable
+		 *   active scanning
+		 * - If adhoc mode does not support DFS yet then
+		 *   disable adhoc in the frequency.
+		 * - If AP mode does not yet support radar detection/DFS
+		 *   do not allow AP mode
+		 */
+		if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+			ch->flags |= IEEE80211_CHAN_RADAR |
+				     IEEE80211_CHAN_NO_IBSS |
+				     IEEE80211_CHAN_PASSIVE_SCAN;
 	}
 }
-#endif
 
-static int ath9k_regd_is_chan_present(struct ath_hal *ah,
-				      u16 c)
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+				 enum nl80211_reg_initiator initiator)
 {
-	int i;
+	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
 
-	for (i = 0; i < 150; i++) {
-		if (!ah->ah_channels[i].channel)
-			return -1;
-		else if (ah->ah_channels[i].channel == c)
-			return i;
+	switch (ah->regulatory.regpair->regDmnEnum) {
+	case 0x60:
+	case 0x63:
+	case 0x66:
+	case 0x67:
+		ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+		break;
+	case 0x68:
+		ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+		ath9k_reg_apply_active_scan_flags(wiphy, initiator);
+		break;
 	}
-
-	return -1;
+	return;
 }
 
-static bool
-ath9k_regd_add_channel(struct ath_hal *ah,
-		       u16 c,
-		       u16 c_lo,
-		       u16 c_hi,
-		       u16 maxChan,
-		       u8 ctl,
-		       int pos,
-		       struct regDomain rd5GHz,
-		       struct RegDmnFreqBand *fband,
-		       struct regDomain *rd,
-		       const struct cmode *cm,
-		       struct ath9k_channel *ichans,
-		       bool enableExtendedChannels)
+int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 {
-	struct ath9k_channel *chan;
-	int ret;
-	u32 channelFlags = 0;
-	u8 privFlags = 0;
-
-	if (!(c_lo <= c && c <= c_hi)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"c %u out of range [%u..%u]\n",
-			c, c_lo, c_hi);
-		return false;
-	}
-	if ((fband->channelBW == CHANNEL_HALF_BW) &&
-	    !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping %u half rate channel\n", c);
-		return false;
-	}
-
-	if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
-	    !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping %u quarter rate channel\n", c);
-		return false;
-	}
-
-	if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"c %u > maxChan %u\n", c, maxChan);
-		return false;
-	}
+	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
 
-	if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping ecm channel\n");
-		return false;
-	}
+	/* We always apply this */
+	ath9k_reg_apply_radar_flags(wiphy);
 
-	if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping HOSTAP channel\n");
-		return false;
+	switch (request->initiator) {
+	case NL80211_REGDOM_SET_BY_DRIVER:
+	case NL80211_REGDOM_SET_BY_CORE:
+	case NL80211_REGDOM_SET_BY_USER:
+		break;
+	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+		if (ath9k_is_world_regd(sc->sc_ah))
+			ath9k_reg_apply_world_flags(wiphy, request->initiator);
+		break;
 	}
 
-	if (IS_HT40_MODE(cm->mode) &&
-	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
-	    (fband->useDfs) &&
-	    (rd->conformanceTestLimit != MKK)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
-		return false;
-	}
+	return 0;
+}
 
-	if (IS_HT40_MODE(cm->mode) &&
-	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
-						 REG_EXT_JAPAN_NONDFS_HT40)) &&
-	    !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping HT40 channel (en_jap_ht40 = 0)\n");
-		return false;
-	}
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
+{
+	u16 rd = ath9k_regd_get_eepromRD(ah);
+	int i;
 
-	if (IS_HT40_MODE(cm->mode) &&
-	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
-	    (fband->useDfs) &&
-	    (rd->conformanceTestLimit == MKK)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
-		return false;
+	if (rd & COUNTRY_ERD_FLAG) {
+		/* EEPROM value is a country code */
+		u16 cc = rd & ~COUNTRY_ERD_FLAG;
+		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+			if (allCountries[i].countryCode == cc)
+				return true;
+	} else {
+		/* EEPROM value is a regpair value */
+		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+			if (regDomainPairs[i].regDmnEnum == rd)
+				return true;
 	}
+	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+		 "invalid regulatory domain/country code 0x%x\n", rd);
+	return false;
+}
 
-	/* Calculate channel flags */
-
-	channelFlags = cm->flags;
+/* EEPROM country code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country(u16 countryCode)
+{
+	int i;
 
-	switch (fband->channelBW) {
-	case CHANNEL_HALF_BW:
-		channelFlags |= CHANNEL_HALF;
-		break;
-	case CHANNEL_QUARTER_BW:
-		channelFlags |= CHANNEL_QUARTER;
-		break;
+	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+		if (allCountries[i].countryCode == countryCode)
+			return &allCountries[i];
 	}
+	return NULL;
+}
 
-	if (fband->usePassScan & rd->pscan)
-		channelFlags |= CHANNEL_PASSIVE;
-	else
-		channelFlags &= ~CHANNEL_PASSIVE;
-	if (fband->useDfs & rd->dfsMask)
-		privFlags = CHANNEL_DFS;
-	else
-		privFlags = 0;
-	if (rd->flags & LIMIT_FRAME_4MS)
-		privFlags |= CHANNEL_4MS_LIMIT;
-	if (privFlags & CHANNEL_DFS)
-		privFlags |= CHANNEL_DISALLOW_ADHOC;
-	if (rd->flags & ADHOC_PER_11D)
-		privFlags |= CHANNEL_PER_11D_ADHOC;
-
-	if (channelFlags & CHANNEL_PASSIVE) {
-		if ((c < 2412) || (c > 2462)) {
-			if (rd5GHz.regDmnEnum == MKK1 ||
-			    rd5GHz.regDmnEnum == MKK2) {
-				u32 regcap = ah->ah_caps.reg_cap;
-				if (!(regcap &
-				      (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
-				       AR_EEPROM_EEREGCAP_EN_KK_U2 |
-				       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
-				    isUNII1OddChan(c)) {
-					channelFlags &= ~CHANNEL_PASSIVE;
-				} else {
-					privFlags |= CHANNEL_DISALLOW_ADHOC;
-				}
-			} else {
-				privFlags |= CHANNEL_DISALLOW_ADHOC;
-			}
-		}
-	}
+/* EEPROM rd code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country_by_rd(int regdmn)
+{
+	int i;
 
-	if ((cm->mode == ATH9K_MODE_11A) ||
-	    (cm->mode == ATH9K_MODE_11NA_HT20) ||
-	    (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
-	    (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
-		if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
-			privFlags |= CHANNEL_DISALLOW_ADHOC;
+	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+		if (allCountries[i].regDmnEnum == regdmn)
+			return &allCountries[i];
 	}
+	return NULL;
+}
 
-	/* Fill in channel details */
+/* Returns the map of the EEPROM set RD to a country code */
+static u16 ath9k_regd_get_default_country(u16 rd)
+{
+	if (rd & COUNTRY_ERD_FLAG) {
+		struct country_code_to_enum_rd *country = NULL;
+		u16 cc = rd & ~COUNTRY_ERD_FLAG;
 
-	ret = ath9k_regd_is_chan_present(ah, c);
-	if (ret == -1) {
-		chan = &ah->ah_channels[pos];
-		chan->channel = c;
-		chan->maxRegTxPower = fband->powerDfs;
-		chan->antennaMax = fband->antennaMax;
-		chan->regDmnFlags = rd->flags;
-		chan->maxTxPower = AR5416_MAX_RATE_POWER;
-		chan->minTxPower = AR5416_MAX_RATE_POWER;
-		chan->channelFlags = channelFlags;
-		chan->privFlags = privFlags;
-	} else {
-		chan = &ah->ah_channels[ret];
-		chan->channelFlags |= channelFlags;
-		chan->privFlags |= privFlags;
+		country = ath9k_regd_find_country(cc);
+		if (country != NULL)
+			return cc;
 	}
 
-	/* Set CTLs */
-
-	if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
-		chan->conformanceTestLimit[0] = ctl;
-	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
-		chan->conformanceTestLimit[1] = ctl;
-	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
-		chan->conformanceTestLimit[2] = ctl;
-
-	return (ret == -1) ? true : false;
+	return CTRY_DEFAULT;
 }
 
-static bool ath9k_regd_japan_check(struct ath_hal *ah,
-				   int b,
-				   struct regDomain *rd5GHz)
+static struct reg_dmn_pair_mapping*
+ath9k_get_regpair(int regdmn)
 {
-	bool skipband = false;
 	int i;
-	u32 regcap;
 
-	for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
-		if (j_bandcheck[i].freqbandbit == b) {
-			regcap = ah->ah_caps.reg_cap;
-			if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
-				skipband = true;
-			} else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
-				  (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
-				rd5GHz->dfsMask |= DFS_MKK4;
-				rd5GHz->pscan |= PSCAN_MKK3;
-			}
-			break;
-		}
+	if (regdmn == NO_ENUMRD)
+		return NULL;
+	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+		if (regDomainPairs[i].regDmnEnum == regdmn)
+			return &regDomainPairs[i];
 	}
-
-	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-		"Skipping %d freq band\n", j_bandcheck[i].freqbandbit);
-
-	return skipband;
+	return NULL;
 }
 
-bool
-ath9k_regd_init_channels(struct ath_hal *ah,
-			 u32 maxchans,
-			 u32 *nchans, u8 *regclassids,
-			 u32 maxregids, u32 *nregids, u16 cc,
-			 bool enableOutdoor,
-			 bool enableExtendedChannels)
+int ath9k_regd_init(struct ath_hw *ah)
 {
-	u16 maxChan = 7000;
 	struct country_code_to_enum_rd *country = NULL;
-	struct regDomain rd5GHz, rd2GHz;
-	const struct cmode *cm;
-	struct ath9k_channel *ichans = &ah->ah_channels[0];
-	int next = 0, b;
-	u8 ctl;
-	int regdmn;
-	u16 chanSep;
-	unsigned long *modes_avail;
-	DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
-
-	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc,
-		 enableOutdoor ? "Enable outdoor" : "",
-		 enableExtendedChannels ? "Enable ecm" : "");
-
-	if (!ath9k_regd_is_ccode_valid(ah, cc)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Invalid country code %d\n", cc);
-		return false;
-	}
+	u16 regdmn;
 
 	if (!ath9k_regd_is_eeprom_valid(ah)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
 			"Invalid EEPROM contents\n");
-		return false;
+		return -EINVAL;
 	}
 
-	ah->ah_countryCode = ath9k_regd_get_default_country(ah);
+	regdmn = ath9k_regd_get_eepromRD(ah);
+	ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
 
-	if (ah->ah_countryCode == CTRY_DEFAULT) {
-		ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
-		if ((ah->ah_countryCode == CTRY_DEFAULT) &&
-		    (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
-			ah->ah_countryCode = CTRY_UNITED_STATES;
-		}
-	}
+	if (ah->regulatory.country_code == CTRY_DEFAULT &&
+	    regdmn == CTRY_DEFAULT)
+		ah->regulatory.country_code = CTRY_UNITED_STATES;
 
-#ifdef AH_SUPPORT_11D
-	if (ah->ah_countryCode == CTRY_DEFAULT) {
-		regdmn = ath9k_regd_get_eepromRD(ah);
+	if (ah->regulatory.country_code == CTRY_DEFAULT) {
 		country = NULL;
 	} else {
-#endif
-		country = ath9k_regd_find_country(ah->ah_countryCode);
+		country = ath9k_regd_find_country(ah->regulatory.country_code);
 		if (country == NULL) {
 			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
 				"Country is NULL!!!!, cc= %d\n",
-				ah->ah_countryCode);
-			return false;
-		} else {
+				ah->regulatory.country_code);
+			return -EINVAL;
+		} else
 			regdmn = country->regDmnEnum;
-#ifdef AH_SUPPORT_11D
-			if (((ath9k_regd_get_eepromRD(ah) &
-			      WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
-			    (cc == CTRY_UNITED_STATES)) {
-				if (!isWwrSKU_NoMidband(ah)
-				    && ath9k_regd_is_fcc_midband_supported(ah))
-					regdmn = FCC3_FCCA;
-				else
-					regdmn = FCC1_FCCA;
-			}
-#endif
-		}
-#ifdef AH_SUPPORT_11D
-	}
-#endif
-	if (!ath9k_regd_get_wmode_regdomain(ah,
-					    regdmn,
-					    ~CHANNEL_2GHZ,
-					    &rd5GHz)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Couldn't find unitary "
-			"5GHz reg domain for country %u\n",
-			ah->ah_countryCode);
-		return false;
-	}
-	if (!ath9k_regd_get_wmode_regdomain(ah,
-					    regdmn,
-					    CHANNEL_2GHZ,
-					    &rd2GHz)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"Couldn't find unitary 2GHz "
-			"reg domain for country %u\n",
-			ah->ah_countryCode);
-		return false;
-	}
-
-	if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
-			      (rd5GHz.regDmnEnum == FCC2))) {
-		if (ath9k_regd_is_fcc_midband_supported(ah)) {
-			if (!ath9k_regd_get_wmode_regdomain(ah,
-							    FCC3_FCCA,
-							    ~CHANNEL_2GHZ,
-							    &rd5GHz)) {
-				DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-					"Couldn't find unitary 5GHz "
-					"reg domain for country %u\n",
-					ah->ah_countryCode);
-				return false;
-			}
-		}
-	}
-
-	if (country == NULL) {
-		modes_avail = ah->ah_caps.wireless_modes;
-	} else {
-		ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
-		modes_avail = modes_allowed;
-
-		if (!enableOutdoor)
-			maxChan = country->outdoorChanStart;
 	}
 
-	next = 0;
-
-	if (maxchans > ARRAY_SIZE(ah->ah_channels))
-		maxchans = ARRAY_SIZE(ah->ah_channels);
-
-	for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
-		u16 c, c_hi, c_lo;
-		u64 *channelBM = NULL;
-		struct regDomain *rd = NULL;
-		struct RegDmnFreqBand *fband = NULL, *freqs;
-		int8_t low_adj = 0, hi_adj = 0;
-
-		if (!test_bit(cm->mode, modes_avail)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"!avail mode %d flags 0x%x\n",
-				cm->mode, cm->flags);
-			continue;
-		}
-		if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"channels 0x%x not supported "
-				"by hardware\n", cm->flags);
-			continue;
-		}
-
-		switch (cm->mode) {
-		case ATH9K_MODE_11A:
-		case ATH9K_MODE_11NA_HT20:
-		case ATH9K_MODE_11NA_HT40PLUS:
-		case ATH9K_MODE_11NA_HT40MINUS:
-			rd = &rd5GHz;
-			channelBM = rd->chan11a;
-			freqs = &regDmn5GhzFreq[0];
-			ctl = rd->conformanceTestLimit;
-			break;
-		case ATH9K_MODE_11B:
-			rd = &rd2GHz;
-			channelBM = rd->chan11b;
-			freqs = &regDmn2GhzFreq[0];
-			ctl = rd->conformanceTestLimit | CTL_11B;
-			break;
-		case ATH9K_MODE_11G:
-		case ATH9K_MODE_11NG_HT20:
-		case ATH9K_MODE_11NG_HT40PLUS:
-		case ATH9K_MODE_11NG_HT40MINUS:
-			rd = &rd2GHz;
-			channelBM = rd->chan11g;
-			freqs = &regDmn2Ghz11gFreq[0];
-			ctl = rd->conformanceTestLimit | CTL_11G;
-			break;
-		default:
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"Unknown HAL mode 0x%x\n", cm->mode);
-			continue;
-		}
-
-		if (ath9k_regd_is_chan_bm_zero(channelBM))
-			continue;
-
-		if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
-		    (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
-			hi_adj = -20;
-		}
-
-		if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
-		    (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
-			low_adj = 20;
-		}
-
-		/* XXX: Add a helper here instead */
-		for (b = 0; b < 64 * BMLEN; b++) {
-			if (ath9k_regd_is_bit_set(b, channelBM)) {
-				fband = &freqs[b];
-				if (rd5GHz.regDmnEnum == MKK1
-				    || rd5GHz.regDmnEnum == MKK2) {
-					if (ath9k_regd_japan_check(ah,
-								   b,
-								   &rd5GHz))
-						continue;
-				}
-
-				ath9k_regd_add_reg_classid(regclassids,
-							   maxregids,
-							   nregids,
-							   fband->
-							   regClassId);
-
-				if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
-					chanSep = 40;
-					if (fband->lowChannel == 5280)
-						low_adj += 20;
-
-					if (fband->lowChannel == 5170)
-						continue;
-				} else
-					chanSep = fband->channelSep;
-
-				for (c = fband->lowChannel + low_adj;
-				     ((c <= (fband->highChannel + hi_adj)) &&
-				      (c >= (fband->lowChannel + low_adj)));
-				     c += chanSep) {
-					if (next >= maxchans) {
-						DPRINTF(ah->ah_sc,
-							ATH_DBG_REGULATORY,
-							"too many channels "
-							"for channel table\n");
-						goto done;
-					}
-					if (ath9k_regd_add_channel(ah,
-						   c, c_lo, c_hi,
-						   maxChan, ctl,
-						   next,
-						   rd5GHz,
-						   fband, rd, cm,
-						   ichans,
-						   enableExtendedChannels))
-						next++;
-				}
-				if (IS_HT40_MODE(cm->mode) &&
-				    (fband->lowChannel == 5280)) {
-					low_adj -= 20;
-				}
-			}
-		}
-	}
-done:
-	if (next != 0) {
-		int i;
-
-		if (next > ARRAY_SIZE(ah->ah_channels)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"too many channels %u; truncating to %u\n",
-				next, (int) ARRAY_SIZE(ah->ah_channels));
-			next = ARRAY_SIZE(ah->ah_channels);
-		}
-#ifdef ATH_NF_PER_CHAN
-		ath9k_regd_init_rf_buffer(ichans, next);
-#endif
-		ath9k_regd_sort(ichans, next,
-				sizeof(struct ath9k_channel),
-				ath9k_regd_chansort);
-
-		ah->ah_nchan = next;
+	ah->regulatory.regpair = ath9k_get_regpair(regdmn);
 
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
-		for (i = 0; i < next; i++) {
-			DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-				"chan: %d flags: 0x%x\n",
-				ah->ah_channels[i].channel,
-				ah->ah_channels[i].channelFlags);
-		}
+	if (!ah->regulatory.regpair) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+			"No regulatory domain pair found, cannot continue\n");
+		return -EINVAL;
 	}
-	*nchans = next;
 
-	ah->ah_countryCode = ah->ah_countryCode;
+	if (!country)
+		country = ath9k_regd_find_country_by_rd(regdmn);
 
-	ah->ah_currentRDInUse = regdmn;
-	ah->ah_currentRD5G = rd5GHz.regDmnEnum;
-	ah->ah_currentRD2G = rd2GHz.regDmnEnum;
-	if (country == NULL) {
-		ah->ah_iso[0] = 0;
-		ah->ah_iso[1] = 0;
+	if (country) {
+		ah->regulatory.alpha2[0] = country->isoName[0];
+		ah->regulatory.alpha2[1] = country->isoName[1];
 	} else {
-		ah->ah_iso[0] = country->isoName[0];
-		ah->ah_iso[1] = country->isoName[1];
+		ah->regulatory.alpha2[0] = '0';
+		ah->regulatory.alpha2[1] = '0';
 	}
 
-	return next != 0;
-}
-
-struct ath9k_channel*
-ath9k_regd_check_channel(struct ath_hal *ah,
-			 const struct ath9k_channel *c)
-{
-	struct ath9k_channel *base, *cc;
-
-	int flags = c->channelFlags & CHAN_FLAGS;
-	int n, lim;
-
 	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-		"channel %u/0x%x (0x%x) requested\n",
-		c->channel, c->channelFlags, flags);
-
-	cc = ah->ah_curchan;
-	if (cc != NULL && cc->channel == c->channel &&
-	    (cc->channelFlags & CHAN_FLAGS) == flags) {
-		if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
-		    (cc->privFlags & CHANNEL_DFS))
-			return NULL;
-		else
-			return cc;
-	}
-
-	base = ah->ah_channels;
-	n = ah->ah_nchan;
-
-	for (lim = n; lim != 0; lim >>= 1) {
-		int d;
-		cc = &base[lim >> 1];
-		d = c->channel - cc->channel;
-		if (d == 0) {
-			if ((cc->channelFlags & CHAN_FLAGS) == flags) {
-				if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
-				    (cc->privFlags & CHANNEL_DFS))
-					return NULL;
-				else
-					return cc;
-			}
-			d = flags - (cc->channelFlags & CHAN_FLAGS);
-		}
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"channel %u/0x%x d %d\n",
-			cc->channel, cc->channelFlags, d);
-		if (d > 0) {
-			base = cc + 1;
-			lim--;
-		}
-	}
-	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n",
-		c->channel, c->channelFlags);
-	return NULL;
-}
-
-u32
-ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
-			       struct ath9k_channel *chan)
-{
-	struct ath9k_channel *ichan = NULL;
-
-	ichan = ath9k_regd_check_channel(ah, chan);
-	if (!ichan)
-		return 0;
+		"Country alpha2 being used: %c%c\n"
+		"Regulatory.Regpair detected: 0x%0x\n",
+		ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
+		ah->regulatory.regpair->regDmnEnum);
 
-	return ichan->antennaMax;
+	return 0;
 }
 
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u32 ctl = NO_CTL;
-	struct ath9k_channel *ichan;
 
-	if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
+	if (!ah->regulatory.regpair ||
+	    (ah->regulatory.country_code == CTRY_DEFAULT &&
+	     is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
 		if (IS_CHAN_B(chan))
 			ctl = SD_NO_CTL | CTL_11B;
 		else if (IS_CHAN_G(chan))
 			ctl = SD_NO_CTL | CTL_11G;
 		else
 			ctl = SD_NO_CTL | CTL_11A;
-	} else {
-		ichan = ath9k_regd_check_channel(ah, chan);
-		if (ichan != NULL) {
-			/* FIXME */
-			if (IS_CHAN_A(ichan))
-				ctl = ichan->conformanceTestLimit[0];
-			else if (IS_CHAN_B(ichan))
-				ctl = ichan->conformanceTestLimit[1];
-			else if (IS_CHAN_G(ichan))
-				ctl = ichan->conformanceTestLimit[2];
-
-			if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
-				ctl = (ctl & ~0xf) | CTL_11G;
-		}
+		return ctl;
 	}
-	return ctl;
-}
-
-void ath9k_regd_get_current_country(struct ath_hal *ah,
-				    struct ath9k_country_entry *ctry)
-{
-	u16 rd = ath9k_regd_get_eepromRD(ah);
 
-	ctry->isMultidomain = false;
-	if (rd == CTRY_DEFAULT)
-		ctry->isMultidomain = true;
-	else if (!(rd & COUNTRY_ERD_FLAG))
-		ctry->isMultidomain = isWwrSKU(ah);
+	if (IS_CHAN_B(chan))
+		ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
+	else if (IS_CHAN_G(chan))
+		ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
+	else
+		ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
 
-	ctry->countryCode = ah->ah_countryCode;
-	ctry->regDmnEnum = ah->ah_currentRD;
-	ctry->regDmn5G = ah->ah_currentRD5G;
-	ctry->regDmn2G = ah->ah_currentRD2G;
-	ctry->iso[0] = ah->ah_iso[0];
-	ctry->iso[1] = ah->ah_iso[1];
-	ctry->iso[2] = ah->ah_iso[2];
+	return ctl;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd_common.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd_common.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd_common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd_common.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -150,1766 +150,324 @@ enum EnumRd {
 	MKK9_MKKC = 0xFE,
 	MKK9_MKKA2 = 0xFF,
 
-	APL1 = 0x0150,
-	APL2 = 0x0250,
-	APL3 = 0x0350,
-	APL4 = 0x0450,
-	APL5 = 0x0550,
-	APL6 = 0x0650,
-	APL7 = 0x0750,
-	APL8 = 0x0850,
-	APL9 = 0x0950,
-	APL10 = 0x1050,
-
-	ETSI1 = 0x0130,
-	ETSI2 = 0x0230,
-	ETSI3 = 0x0330,
-	ETSI4 = 0x0430,
-	ETSI5 = 0x0530,
-	ETSI6 = 0x0630,
-	ETSIA = 0x0A30,
-	ETSIB = 0x0B30,
-	ETSIC = 0x0C30,
-
-	FCC1 = 0x0110,
-	FCC2 = 0x0120,
-	FCC3 = 0x0160,
-	FCC4 = 0x0165,
-	FCC5 = 0x0510,
-	FCC6 = 0x0610,
-	FCCA = 0x0A10,
-
-	APLD = 0x0D50,
-
-	MKK1 = 0x0140,
-	MKK2 = 0x0240,
-	MKK3 = 0x0340,
-	MKK4 = 0x0440,
-	MKK5 = 0x0540,
-	MKK6 = 0x0640,
-	MKK7 = 0x0740,
-	MKK8 = 0x0840,
-	MKK9 = 0x0940,
-	MKK10 = 0x0B40,
-	MKK11 = 0x1140,
-	MKK12 = 0x1240,
-	MKK13 = 0x0C40,
-	MKK14 = 0x1440,
-	MKK15 = 0x1540,
-	MKKA = 0x0A40,
-	MKKC = 0x0A50,
-
-	NULL1 = 0x0198,
 	WORLD = 0x0199,
 	DEBUG_REG_DMN = 0x01ff,
 };
 
-enum {
-	FCC = 0x10,
-	MKK = 0x40,
-	ETSI = 0x30,
-};
-
-enum {
-	NO_REQ = 0x00000000,
-	DISALLOW_ADHOC_11A = 0x00000001,
-	DISALLOW_ADHOC_11A_TURB = 0x00000002,
-	NEED_NFC = 0x00000004,
-
-	ADHOC_PER_11D = 0x00000008,
-	ADHOC_NO_11A = 0x00000010,
-
-	PUBLIC_SAFETY_DOMAIN = 0x00000020,
-	LIMIT_FRAME_4MS = 0x00000040,
-
-	NO_HOSTAP = 0x00000080,
-
-	REQ_MASK = 0x000000FF,
+enum ctl_group {
+	CTL_FCC = 0x10,
+	CTL_MKK = 0x40,
+	CTL_ETSI = 0x30,
 };
 
-#define REG_DOMAIN_2GHZ_MASK    (REQ_MASK & \
-	(~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
-#define REG_DOMAIN_5GHZ_MASK    REQ_MASK
-
+/* Regpair to CTL band mapping */
 static struct reg_dmn_pair_mapping regDomainPairs[] = {
-	{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
-	 PSCAN_DEFER, 0},
-	{NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
-	{FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC4_FCCA, FCC4, FCCA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
-	{ETSI1_WORLD, ETSI1, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{ETSI2_WORLD, ETSI2, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{ETSI3_WORLD, ETSI3, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{ETSI4_WORLD, ETSI4, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{ETSI5_WORLD, ETSI5, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{ETSI6_WORLD, ETSI6, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
+	/* regpair, 5 GHz CTL, 2 GHz CTL */
+	{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
+	{NULL1_WORLD, NO_CTL, CTL_ETSI},
+	{NULL1_ETSIB, NO_CTL, CTL_ETSI},
+	{NULL1_ETSIC, NO_CTL, CTL_ETSI},
 
-	{ETSI3_ETSIA, ETSI3, WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC2_FCCA, CTL_FCC, CTL_FCC},
+	{FCC2_WORLD, CTL_FCC, CTL_ETSI},
+	{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+	{FCC3_FCCA, CTL_FCC, CTL_FCC},
+	{FCC3_WORLD, CTL_FCC, CTL_ETSI},
+	{FCC4_FCCA, CTL_FCC, CTL_FCC},
+	{FCC5_FCCA, CTL_FCC, CTL_FCC},
+	{FCC6_FCCA, CTL_FCC, CTL_FCC},
+	{FCC6_WORLD, CTL_FCC, CTL_ETSI},
 
-	{FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
+	{ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
+	{ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
+	{ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
+	{ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
+	{ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
 
-	{APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,},
+	/* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
+	{ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
+	{FRANCE_RES, CTL_ETSI, CTL_ETSI},
 
-	{MKK1_MKKA, MKK1, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
-	{MKK1_MKKB, MKK1, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN1},
-	{MKK1_FCCA, MKK1, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1, CTRY_JAPAN2},
-	{MKK1_MKKA1, MKK1, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
-	{MKK1_MKKA2, MKK1, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
-	{MKK1_MKKC, MKK1, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1, CTRY_JAPAN6},
+	{FCC1_WORLD, CTL_FCC, CTL_ETSI},
+	{FCC1_FCCA, CTL_FCC, CTL_FCC},
+	{APL1_WORLD, CTL_FCC, CTL_ETSI},
+	{APL2_WORLD, CTL_FCC, CTL_ETSI},
+	{APL3_WORLD, CTL_FCC, CTL_ETSI},
+	{APL4_WORLD, CTL_FCC, CTL_ETSI},
+	{APL5_WORLD, CTL_FCC, CTL_ETSI},
+	{APL6_WORLD, CTL_ETSI, CTL_ETSI},
+	{APL8_WORLD, CTL_ETSI, CTL_ETSI},
+	{APL9_WORLD, CTL_ETSI, CTL_ETSI},
 
-	{MKK2_MKKA, MKK2, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN3},
+	{APL3_FCCA, CTL_FCC, CTL_FCC},
+	{APL1_ETSIC, CTL_FCC, CTL_ETSI},
+	{APL2_ETSIC, CTL_FCC, CTL_ETSI},
+	{APL2_APLD, CTL_FCC, NO_CTL},
 
-	{MKK3_MKKA, MKK3, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA, CTRY_JAPAN25},
-	{MKK3_MKKB, MKK3, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN7},
-	{MKK3_MKKA1, MKK3, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
-	{MKK3_MKKA2, MKK3, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
-	{MKK3_MKKC, MKK3, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN9},
-	{MKK3_FCCA, MKK3, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN27},
+	{MKK1_MKKA, CTL_MKK, CTL_MKK},
+	{MKK1_MKKB, CTL_MKK, CTL_MKK},
+	{MKK1_FCCA, CTL_MKK, CTL_FCC},
+	{MKK1_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK1_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK1_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK4_MKKA, MKK4, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN36},
-	{MKK4_MKKB, MKK4, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN10},
-	{MKK4_MKKA1, MKK4, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
-	{MKK4_MKKA2, MKK4, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
-	{MKK4_MKKC, MKK4, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN12},
-	{MKK4_FCCA, MKK4, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN29},
+	{MKK2_MKKA, CTL_MKK, CTL_MKK},
+	{MKK3_MKKA, CTL_MKK, CTL_MKK},
+	{MKK3_MKKB, CTL_MKK, CTL_MKK},
+	{MKK3_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK3_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK3_MKKC, CTL_MKK, CTL_MKK},
+	{MKK3_FCCA, CTL_MKK, CTL_FCC},
 
-	{MKK5_MKKB, MKK5, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN13},
-	{MKK5_MKKA2, MKK5, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
-	{MKK5_MKKC, MKK5, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN15},
+	{MKK4_MKKA, CTL_MKK, CTL_MKK},
+	{MKK4_MKKB, CTL_MKK, CTL_MKK},
+	{MKK4_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK4_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK4_MKKC, CTL_MKK, CTL_MKK},
+	{MKK4_FCCA, CTL_MKK, CTL_FCC},
 
-	{MKK6_MKKB, MKK6, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
-	{MKK6_MKKA1, MKK6, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
-	{MKK6_MKKA2, MKK6, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
-	{MKK6_MKKC, MKK6, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1, CTRY_JAPAN18},
-	{MKK6_FCCA, MKK6, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN31},
+	{MKK5_MKKB, CTL_MKK, CTL_MKK},
+	{MKK5_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK5_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK7_MKKB, MKK7, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN19},
-	{MKK7_MKKA1, MKK7, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
-	{MKK7_MKKA2, MKK7, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
-	 CTRY_JAPAN20},
-	{MKK7_MKKC, MKK7, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
-	{MKK7_FCCA, MKK7, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
+	{MKK6_MKKB, CTL_MKK, CTL_MKK},
+	{MKK6_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK6_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK6_MKKC, CTL_MKK, CTL_MKK},
+	{MKK6_FCCA, CTL_MKK, CTL_FCC},
 
-	{MKK8_MKKB, MKK8, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN22},
-	{MKK8_MKKA2, MKK8, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
-	 CTRY_JAPAN23},
-	{MKK8_MKKC, MKK8, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
+	{MKK7_MKKB, CTL_MKK, CTL_MKK},
+	{MKK7_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK7_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK7_MKKC, CTL_MKK, CTL_MKK},
+	{MKK7_FCCA, CTL_MKK, CTL_FCC},
 
-	{MKK9_MKKA, MKK9, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN34},
-	{MKK9_FCCA, MKK9, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN37},
-	{MKK9_MKKA1, MKK9, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
-	{MKK9_MKKA2, MKK9, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
-	{MKK9_MKKC, MKK9, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN39},
+	{MKK8_MKKB, CTL_MKK, CTL_MKK},
+	{MKK8_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK8_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK10_MKKA, MKK10, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
-	{MKK10_FCCA, MKK10, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN41},
-	{MKK10_MKKA1, MKK10, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
-	{MKK10_MKKA2, MKK10, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
-	{MKK10_MKKC, MKK10, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 NO_PSCAN, CTRY_JAPAN43},
+	{MKK9_MKKA, CTL_MKK, CTL_MKK},
+	{MKK9_FCCA, CTL_MKK, CTL_FCC},
+	{MKK9_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK9_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK9_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK11_MKKA, MKK11, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN45},
-	{MKK11_FCCA, MKK11, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN46},
-	{MKK11_MKKA1, MKK11, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
-	{MKK11_MKKA2, MKK11, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
-	{MKK11_MKKC, MKK11, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK3, CTRY_JAPAN48},
+	{MKK10_MKKA, CTL_MKK, CTL_MKK},
+	{MKK10_FCCA, CTL_MKK, CTL_FCC},
+	{MKK10_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK10_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK10_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK12_MKKA, MKK12, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
-	{MKK12_FCCA, MKK12, FCCA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
-	{MKK12_MKKA1, MKK12, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
-	 CTRY_JAPAN52},
-	{MKK12_MKKA2, MKK12, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
-	 CTRY_JAPAN54},
-	{MKK12_MKKC, MKK12, MKKC,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
+	{MKK11_MKKA, CTL_MKK, CTL_MKK},
+	{MKK11_FCCA, CTL_MKK, CTL_FCC},
+	{MKK11_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK11_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK11_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK13_MKKB, MKK13, MKKA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
-	 LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
-	 CTRY_JAPAN57},
+	{MKK12_MKKA, CTL_MKK, CTL_MKK},
+	{MKK12_FCCA, CTL_MKK, CTL_FCC},
+	{MKK12_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK12_MKKA2, CTL_MKK, CTL_MKK},
+	{MKK12_MKKC, CTL_MKK, CTL_MKK},
 
-	{MKK14_MKKA1, MKK14, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
-	{MKK15_MKKA1, MKK15, MKKA,
-	 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
-	 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
+	{MKK13_MKKB, CTL_MKK, CTL_MKK},
+	{MKK14_MKKA1, CTL_MKK, CTL_MKK},
+	{MKK15_MKKA1, CTL_MKK, CTL_MKK},
 
-	{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
-	 NO_REQ, PSCAN_DEFER, 0},
-	{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
-	 PSCAN_DEFER, 0},
-	{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
-	 PSCAN_DEFER, 0},
-	{EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-	{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WORA_WORLD, WORA_WORLD, WORA_WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
-	{WORB_WORLD, WORB_WORLD, WORB_WORLD,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
-	 0},
+	{WOR0_WORLD, NO_CTL, NO_CTL},
+	{WOR1_WORLD, NO_CTL, NO_CTL},
+	{WOR2_WORLD, NO_CTL, NO_CTL},
+	{WOR3_WORLD, NO_CTL, NO_CTL},
+	{WOR4_WORLD, NO_CTL, NO_CTL},
+	{WOR5_ETSIC, NO_CTL, NO_CTL},
+	{WOR01_WORLD, NO_CTL, NO_CTL},
+	{WOR02_WORLD, NO_CTL, NO_CTL},
+	{EU1_WORLD, NO_CTL, NO_CTL},
+	{WOR9_WORLD, NO_CTL, NO_CTL},
+	{WORA_WORLD, NO_CTL, NO_CTL},
+	{WORB_WORLD, NO_CTL, NO_CTL},
 };
 
-#define	NO_INTERSECT_REQ	0xFFFFFFFF
-#define	NO_UNION_REQ		0
-
 static struct country_code_to_enum_rd allCountries[] = {
-	{CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
-	 NO, NO, 7000},
-	{CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
-	 NO, NO, 7000},
-	{CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
-	 NO, YES, NO, 7000},
-	{CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
-	 YES, YES, YES, YES, NO, 7000},
-	{CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
-	 YES, NO, 7000},
-	{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
-	 YES, YES, YES, YES, YES, YES, YES, 7000},
-	{CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
-	 YES, YES, YES, NO, 7000},
-	{CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
-	 YES, YES, YES, YES, YES, YES, YES, 7000},
-	{CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
-	 YES, YES, YES, NO, 7000},
-	{CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
-	 YES, 7000},
-	{CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-
-	{CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
-	 YES, 7000},
-	{CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
-	 YES, YES, 7000},
-
-	{CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
-	 YES, YES, NO, NO, 7000},
-	{CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
-	 YES, NO, YES, NO, 7000},
-	{CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
-	 YES, NO, YES, NO, 7000},
-	{CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
-	 YES, NO, YES, NO, 7000},
-	{CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
-	 YES, YES, YES, YES, YES, 7000},
-	{CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
-	 YES, NO, 7000},
-	{CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
-	 "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
-	{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
-	 YES, YES, YES, NO, 7000},
-	{CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
-	 NO, 7000},
-	{CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
-	 YES, YES, YES, YES, YES, YES, 7000},
-	{CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
-	 NO, 7000},
-	{CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
-	 YES, YES, YES, NO, NO, 7000},
-	{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
-	 YES, NO, YES, YES, YES, YES, YES, 7000},
-	{CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
-	 YES, YES, YES, 7000},
-	{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
-	 YES, YES, YES, NO, 7000},
-	{CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
-	 YES, YES, 7000},
-	{CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
-	 YES, NO, YES, YES, YES, YES, NO, 7000},
-	{CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
-	 YES, YES, NO, NO, 7000},
-	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
-	 YES, YES, YES, YES, YES, 7000},
-	{CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
-	 YES, YES, YES, YES, YES, 5825},
-	{CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
-	 "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
-	 YES, 7000},
-	{CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
-	 YES, NO, 7000},
-	{CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
-	 YES, YES, YES, YES, 7000},
-	{CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
-	 YES, YES, NO, 7000},
-	{CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
-	 YES, NO, NO, 7000},
-	{CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
-	 NO, NO, 7000},
-	{CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
-	 YES, NO, NO, 7000}
-};
-
-enum {
-	NO_DFS = 0x0000000000000000ULL,
-	DFS_FCC3 = 0x0000000000000001ULL,
-	DFS_ETSI = 0x0000000000000002ULL,
-	DFS_MKK4 = 0x0000000000000004ULL,
-};
-
-enum {
-	F1_4915_4925,
-	F1_4935_4945,
-	F1_4920_4980,
-	F1_4942_4987,
-	F1_4945_4985,
-	F1_4950_4980,
-	F1_5035_5040,
-	F1_5040_5080,
-	F1_5055_5055,
-
-	F1_5120_5240,
-
-	F1_5170_5230,
-	F2_5170_5230,
-
-	F1_5180_5240,
-	F2_5180_5240,
-	F3_5180_5240,
-	F4_5180_5240,
-	F5_5180_5240,
-	F6_5180_5240,
-	F7_5180_5240,
-	F8_5180_5240,
-
-	F1_5180_5320,
-
-	F1_5240_5280,
-
-	F1_5260_5280,
-
-	F1_5260_5320,
-	F2_5260_5320,
-	F3_5260_5320,
-	F4_5260_5320,
-	F5_5260_5320,
-	F6_5260_5320,
-
-	F1_5260_5700,
-
-	F1_5280_5320,
-
-	F1_5500_5580,
-
-	F1_5500_5620,
-
-	F1_5500_5700,
-	F2_5500_5700,
-	F3_5500_5700,
-	F4_5500_5700,
-	F5_5500_5700,
-
-	F1_5660_5700,
-
-	F1_5745_5805,
-	F2_5745_5805,
-	F3_5745_5805,
-
-	F1_5745_5825,
-	F2_5745_5825,
-	F3_5745_5825,
-	F4_5745_5825,
-	F5_5745_5825,
-	F6_5745_5825,
-
-	W1_4920_4980,
-	W1_5040_5080,
-	W1_5170_5230,
-	W1_5180_5240,
-	W1_5260_5320,
-	W1_5745_5825,
-	W1_5500_5700,
-	A_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn5GhzFreq[] = {
-	{4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
-	{4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
-	{4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
-	{4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
-	{4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
-	{4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
-	{5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
-	{5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
-	{5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
-
-	{5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-	{5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
-	{5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
-
-	{5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
-	{5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
-	{5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
-	{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
-	{5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
-	{5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
-	{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
-	{5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-	{5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
-
-	{5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
-
-	{5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
-	 PSCAN_FCC | PSCAN_ETSI, 0},
-
-	{5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
-	 PSCAN_FCC | PSCAN_ETSI, 0},
-
-	{5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
-	 PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
-
-
-	{5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
-	 PSCAN_FCC | PSCAN_ETSI, 2},
-	{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
-	{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
-	{5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-	{5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
-
-	{5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
-
-	{5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
-	{5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
-	{5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
-	{5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
-	 PSCAN_FCC | PSCAN_ETSI, 0},
-	{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
-	 PSCAN_FCC | PSCAN_ETSI, 0},
-	{5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
-	 PSCAN_MKK3 | PSCAN_FCC, 0},
-	{5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
-	{5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
-	{5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
-	{5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-	{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
-	{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-
-	{4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
-	{5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
-	{5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
-	{5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
-	{5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
-	{5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
-	{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
-	{4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
-	T1_5130_5650,
-	T1_5150_5670,
-
-	T1_5200_5200,
-	T2_5200_5200,
-	T3_5200_5200,
-	T4_5200_5200,
-	T5_5200_5200,
-	T6_5200_5200,
-	T7_5200_5200,
-	T8_5200_5200,
-
-	T1_5200_5280,
-	T2_5200_5280,
-	T3_5200_5280,
-	T4_5200_5280,
-	T5_5200_5280,
-	T6_5200_5280,
-
-	T1_5200_5240,
-	T1_5210_5210,
-	T2_5210_5210,
-	T3_5210_5210,
-	T4_5210_5210,
-	T5_5210_5210,
-	T6_5210_5210,
-	T7_5210_5210,
-	T8_5210_5210,
-	T9_5210_5210,
-	T10_5210_5210,
-	T1_5240_5240,
-
-	T1_5210_5250,
-	T1_5210_5290,
-	T2_5210_5290,
-	T3_5210_5290,
-
-	T1_5280_5280,
-	T2_5280_5280,
-	T1_5290_5290,
-	T2_5290_5290,
-	T3_5290_5290,
-	T1_5250_5290,
-	T2_5250_5290,
-	T3_5250_5290,
-	T4_5250_5290,
-
-	T1_5540_5660,
-	T2_5540_5660,
-	T3_5540_5660,
-	T1_5760_5800,
-	T2_5760_5800,
-	T3_5760_5800,
-	T4_5760_5800,
-	T5_5760_5800,
-	T6_5760_5800,
-	T7_5760_5800,
-
-	T1_5765_5805,
-	T2_5765_5805,
-	T3_5765_5805,
-	T4_5765_5805,
-	T5_5765_5805,
-	T6_5765_5805,
-	T7_5765_5805,
-	T8_5765_5805,
-	T9_5765_5805,
-
-	WT1_5210_5250,
-	WT1_5290_5290,
-	WT1_5540_5660,
-	WT1_5760_5800,
-};
-
-enum {
-	F1_2312_2372,
-	F2_2312_2372,
-
-	F1_2412_2472,
-	F2_2412_2472,
-	F3_2412_2472,
-
-	F1_2412_2462,
-	F2_2412_2462,
-
-	F1_2432_2442,
-
-	F1_2457_2472,
-
-	F1_2467_2472,
-
-	F1_2484_2484,
-	F2_2484_2484,
-
-	F1_2512_2732,
-
-	W1_2312_2372,
-	W1_2412_2412,
-	W1_2417_2432,
-	W1_2437_2442,
-	W1_2447_2457,
-	W1_2462_2462,
-	W1_2467_2467,
-	W2_2467_2467,
-	W1_2472_2472,
-	W2_2472_2472,
-	W1_2484_2484,
-	W2_2484_2484,
-};
-
-static struct RegDmnFreqBand regDmn2GhzFreq[] = {
-	{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
-	{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
-
-	{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
-	{2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2484, 2484, 20, 0, 20, 5, NO_DFS,
-	 PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
-
-	{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
-	{2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-	{2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
-	{2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-	{2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
-	{2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-};
-
-enum {
-	G1_2312_2372,
-	G2_2312_2372,
-
-	G1_2412_2472,
-	G2_2412_2472,
-	G3_2412_2472,
-
-	G1_2412_2462,
-	G2_2412_2462,
-
-	G1_2432_2442,
-
-	G1_2457_2472,
-
-	G1_2512_2732,
-
-	G1_2467_2472,
-
-	WG1_2312_2372,
-	WG1_2412_2462,
-	WG1_2467_2472,
-	WG2_2467_2472,
-	G_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
-	{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
-	{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
-
-	{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
-	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
-	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
-	{2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-	{2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
-	T1_2312_2372,
-	T1_2437_2437,
-	T2_2437_2437,
-	T3_2437_2437,
-	T1_2512_2732
-};
-
-static struct regDomain regDomains[] = {
-
-	{DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
-	 BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1)},
-
-	{APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
-	 BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
-	 BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL8, ETSI, NO_DFS, NO_PSCAN,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
-	 BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
-	 BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
-	 BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
-	    F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-	{MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
-	    F2_5260_5320, F4_5500_5700, -1, -1),
-	 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
-	 BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
-	 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
-	 BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
-	 BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
-	 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
-	    -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
-	    F4_5500_5700, -1, -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
-	    F2_5260_5320, F4_5500_5700, -1, -1),
-	 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
-	    -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
-	 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
-	    F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
-	    F2_5260_5320, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO},
-
-
-	{APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BMZERO},
-
-	{ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
-	 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{MKKA, MKK, NO_DFS,
-	 PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
-	 PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-	    -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
-	 ADHOC_PER_11D,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
-	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
-	 ADHOC_PER_11D,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-	    -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
-	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-	    -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
-	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-	    -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
-	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
-	    -1, -1, -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
-	 BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
-	    -1, -1, -1, -1),
-	 BMZERO,
-	 BMZERO,
-	 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
-	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
-	 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-	    -1, -1),
-	 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
-	{NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO,
-	 BMZERO}
-};
+	{CTRY_DEBUG, NO_ENUMRD, "DB"},
+	{CTRY_DEFAULT, FCC1_FCCA, "CO"},
+	{CTRY_ALBANIA, NULL1_WORLD, "AL"},
+	{CTRY_ALGERIA, NULL1_WORLD, "DZ"},
+	{CTRY_ARGENTINA, APL3_WORLD, "AR"},
+	{CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+	{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_BELARUS, ETSI1_WORLD, "BY"},
+	{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
+	{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
+	{CTRY_BELIZE, APL1_ETSIC, "BZ"},
+	{CTRY_BOLIVIA, APL1_ETSIC, "BO"},
+	{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
+	{CTRY_BRAZIL, FCC3_WORLD, "BR"},
+	{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
+	{CTRY_BULGARIA, ETSI6_WORLD, "BG"},
+	{CTRY_CANADA, FCC2_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_CYPRUS, ETSI1_WORLD, "CY"},
+	{CTRY_CZECH, ETSI3_WORLD, "CZ"},
+	{CTRY_DENMARK, ETSI1_WORLD, "DK"},
+	{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
+	{CTRY_ECUADOR, FCC1_WORLD, "EC"},
+	{CTRY_EGYPT, ETSI3_WORLD, "EG"},
+	{CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
+	{CTRY_ESTONIA, ETSI1_WORLD, "EE"},
+	{CTRY_FINLAND, ETSI1_WORLD, "FI"},
+	{CTRY_FRANCE, ETSI1_WORLD, "FR"},
+	{CTRY_GEORGIA, ETSI4_WORLD, "GE"},
+	{CTRY_GERMANY, ETSI1_WORLD, "DE"},
+	{CTRY_GREECE, ETSI1_WORLD, "GR"},
+	{CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+	{CTRY_HONDURAS, NULL1_WORLD, "HN"},
+	{CTRY_HONG_KONG, FCC2_WORLD, "HK"},
+	{CTRY_HUNGARY, ETSI1_WORLD, "HU"},
+	{CTRY_ICELAND, ETSI1_WORLD, "IS"},
+	{CTRY_INDIA, APL6_WORLD, "IN"},
+	{CTRY_INDONESIA, APL1_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"},
 
-static const struct cmode modes[] = {
-	{ATH9K_MODE_11A, CHANNEL_A},
-	{ATH9K_MODE_11B, CHANNEL_B},
-	{ATH9K_MODE_11G, CHANNEL_G},
-	{ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
-	{ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
-	{ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
-	{ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
-	{ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
-	{ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
-};
+	{CTRY_JAPAN, MKK1_MKKA, "JP"},
+	{CTRY_JAPAN1, MKK1_MKKB, "JP"},
+	{CTRY_JAPAN2, MKK1_FCCA, "JP"},
+	{CTRY_JAPAN3, MKK2_MKKA, "JP"},
+	{CTRY_JAPAN4, MKK1_MKKA1, "JP"},
+	{CTRY_JAPAN5, MKK1_MKKA2, "JP"},
+	{CTRY_JAPAN6, MKK1_MKKC, "JP"},
+	{CTRY_JAPAN7, MKK3_MKKB, "JP"},
+	{CTRY_JAPAN8, MKK3_MKKA2, "JP"},
+	{CTRY_JAPAN9, MKK3_MKKC, "JP"},
+	{CTRY_JAPAN10, MKK4_MKKB, "JP"},
+	{CTRY_JAPAN11, MKK4_MKKA2, "JP"},
+	{CTRY_JAPAN12, MKK4_MKKC, "JP"},
+	{CTRY_JAPAN13, MKK5_MKKB, "JP"},
+	{CTRY_JAPAN14, MKK5_MKKA2, "JP"},
+	{CTRY_JAPAN15, MKK5_MKKC, "JP"},
+	{CTRY_JAPAN16, MKK6_MKKB, "JP"},
+	{CTRY_JAPAN17, MKK6_MKKA2, "JP"},
+	{CTRY_JAPAN18, MKK6_MKKC, "JP"},
+	{CTRY_JAPAN19, MKK7_MKKB, "JP"},
+	{CTRY_JAPAN20, MKK7_MKKA2, "JP"},
+	{CTRY_JAPAN21, MKK7_MKKC, "JP"},
+	{CTRY_JAPAN22, MKK8_MKKB, "JP"},
+	{CTRY_JAPAN23, MKK8_MKKA2, "JP"},
+	{CTRY_JAPAN24, MKK8_MKKC, "JP"},
+	{CTRY_JAPAN25, MKK3_MKKA, "JP"},
+	{CTRY_JAPAN26, MKK3_MKKA1, "JP"},
+	{CTRY_JAPAN27, MKK3_FCCA, "JP"},
+	{CTRY_JAPAN28, MKK4_MKKA1, "JP"},
+	{CTRY_JAPAN29, MKK4_FCCA, "JP"},
+	{CTRY_JAPAN30, MKK6_MKKA1, "JP"},
+	{CTRY_JAPAN31, MKK6_FCCA, "JP"},
+	{CTRY_JAPAN32, MKK7_MKKA1, "JP"},
+	{CTRY_JAPAN33, MKK7_FCCA, "JP"},
+	{CTRY_JAPAN34, MKK9_MKKA, "JP"},
+	{CTRY_JAPAN35, MKK10_MKKA, "JP"},
+	{CTRY_JAPAN36, MKK4_MKKA, "JP"},
+	{CTRY_JAPAN37, MKK9_FCCA, "JP"},
+	{CTRY_JAPAN38, MKK9_MKKA1, "JP"},
+	{CTRY_JAPAN39, MKK9_MKKC, "JP"},
+	{CTRY_JAPAN40, MKK9_MKKA2, "JP"},
+	{CTRY_JAPAN41, MKK10_FCCA, "JP"},
+	{CTRY_JAPAN42, MKK10_MKKA1, "JP"},
+	{CTRY_JAPAN43, MKK10_MKKC, "JP"},
+	{CTRY_JAPAN44, MKK10_MKKA2, "JP"},
+	{CTRY_JAPAN45, MKK11_MKKA, "JP"},
+	{CTRY_JAPAN46, MKK11_FCCA, "JP"},
+	{CTRY_JAPAN47, MKK11_MKKA1, "JP"},
+	{CTRY_JAPAN48, MKK11_MKKC, "JP"},
+	{CTRY_JAPAN49, MKK11_MKKA2, "JP"},
+	{CTRY_JAPAN50, MKK12_MKKA, "JP"},
+	{CTRY_JAPAN51, MKK12_FCCA, "JP"},
+	{CTRY_JAPAN52, MKK12_MKKA1, "JP"},
+	{CTRY_JAPAN53, MKK12_MKKC, "JP"},
+	{CTRY_JAPAN54, MKK12_MKKA2, "JP"},
+	{CTRY_JAPAN57, MKK13_MKKB, "JP"},
+	{CTRY_JAPAN58, MKK14_MKKA1, "JP"},
+	{CTRY_JAPAN59, MKK15_MKKA1, "JP"},
 
-static struct japan_bandcheck j_bandcheck[] = {
-	{F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
-	{F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
-	{F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
-	{F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
+	{CTRY_JORDAN, ETSI2_WORLD, "JO"},
+	{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
+	{CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
+	{CTRY_KOREA_ROC, APL9_WORLD, "KR"},
+	{CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
+	{CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
+	{CTRY_KUWAIT, NULL1_WORLD, "KW"},
+	{CTRY_LATVIA, ETSI1_WORLD, "LV"},
+	{CTRY_LEBANON, NULL1_WORLD, "LB"},
+	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
+	{CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
+	{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
+	{CTRY_MACAU, FCC2_WORLD, "MO"},
+	{CTRY_MACEDONIA, NULL1_WORLD, "MK"},
+	{CTRY_MALAYSIA, APL8_WORLD, "MY"},
+	{CTRY_MALTA, ETSI1_WORLD, "MT"},
+	{CTRY_MEXICO, FCC1_FCCA, "MX"},
+	{CTRY_MONACO, ETSI4_WORLD, "MC"},
+	{CTRY_MOROCCO, NULL1_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_PAKISTAN, NULL1_WORLD, "PK"},
+	{CTRY_PANAMA, FCC1_FCCA, "PA"},
+	{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
+	{CTRY_PERU, APL1_WORLD, "PE"},
+	{CTRY_PHILIPPINES, APL1_WORLD, "PH"},
+	{CTRY_POLAND, ETSI1_WORLD, "PL"},
+	{CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
+	{CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
+	{CTRY_QATAR, NULL1_WORLD, "QA"},
+	{CTRY_ROMANIA, NULL1_WORLD, "RO"},
+	{CTRY_RUSSIA, NULL1_WORLD, "RU"},
+	{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+	{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
+	{CTRY_SINGAPORE, APL6_WORLD, "SG"},
+	{CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
+	{CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
+	{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
+	{CTRY_SPAIN, ETSI1_WORLD, "ES"},
+	{CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
+	{CTRY_SWEDEN, ETSI1_WORLD, "SE"},
+	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
+	{CTRY_SYRIA, NULL1_WORLD, "SY"},
+	{CTRY_TAIWAN, APL3_FCCA, "TW"},
+	{CTRY_THAILAND, NULL1_WORLD, "TH"},
+	{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
+	{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
+	{CTRY_TURKEY, ETSI3_WORLD, "TR"},
+	{CTRY_UKRAINE, NULL1_WORLD, "UA"},
+	{CTRY_UAE, NULL1_WORLD, "AE"},
+	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+	{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+	/* This "PS" is for US public safety actually... to support this we
+	 * 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_UZBEKISTAN, FCC3_FCCA, "UZ"},
+	{CTRY_VENEZUELA, APL2_ETSIC, "VE"},
+	{CTRY_VIET_NAM, NULL1_WORLD, "VN"},
+	{CTRY_YEMEN, NULL1_WORLD, "YE"},
+	{CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
 };
 
-
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/regd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -17,127 +17,8 @@
 #ifndef REGD_H
 #define REGD_H
 
-#include "ath9k.h"
-
-#define BMLEN 2
-#define BMZERO {(u64) 0, (u64) 0}
-
-#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
-	{((((_fa >= 0) && (_fa < 64)) ? \
-		(((u64) 1) << _fa) : (u64) 0) | \
-	(((_fb >= 0) && (_fb < 64)) ? \
-		(((u64) 1) << _fb) : (u64) 0) | \
-	(((_fc >= 0) && (_fc < 64)) ? \
-		(((u64) 1) << _fc) : (u64) 0) | \
-	(((_fd >= 0) && (_fd < 64)) ? \
-		(((u64) 1) << _fd) : (u64) 0) | \
-	(((_fe >= 0) && (_fe < 64)) ? \
-		(((u64) 1) << _fe) : (u64) 0) | \
-	(((_ff >= 0) && (_ff < 64)) ? \
-		(((u64) 1) << _ff) : (u64) 0) | \
-	(((_fg >= 0) && (_fg < 64)) ? \
-		(((u64) 1) << _fg) : (u64) 0) | \
-	(((_fh >= 0) && (_fh < 64)) ? \
-		(((u64) 1) << _fh) : (u64) 0) | \
-	(((_fi >= 0) && (_fi < 64)) ? \
-		(((u64) 1) << _fi) : (u64) 0) | \
-	(((_fj >= 0) && (_fj < 64)) ? \
-		(((u64) 1) << _fj) : (u64) 0) | \
-	(((_fk >= 0) && (_fk < 64)) ? \
-		(((u64) 1) << _fk) : (u64) 0) | \
-	(((_fl >= 0) && (_fl < 64)) ? \
-		(((u64) 1) << _fl) : (u64) 0) | \
-			((((_fa > 63) && (_fa < 128)) ? \
-			(((u64) 1) << (_fa - 64)) : (u64) 0) | \
-	(((_fb > 63) && (_fb < 128)) ? \
-		(((u64) 1) << (_fb - 64)) : (u64) 0) | \
-	(((_fc > 63) && (_fc < 128)) ? \
-		(((u64) 1) << (_fc - 64)) : (u64) 0) | \
-	(((_fd > 63) && (_fd < 128)) ? \
-		(((u64) 1) << (_fd - 64)) : (u64) 0) | \
-	(((_fe > 63) && (_fe < 128)) ? \
-		(((u64) 1) << (_fe - 64)) : (u64) 0) | \
-	(((_ff > 63) && (_ff < 128)) ? \
-		(((u64) 1) << (_ff - 64)) : (u64) 0) | \
-	(((_fg > 63) && (_fg < 128)) ? \
-		(((u64) 1) << (_fg - 64)) : (u64) 0) | \
-	(((_fh > 63) && (_fh < 128)) ? \
-		(((u64) 1) << (_fh - 64)) : (u64) 0) | \
-	(((_fi > 63) && (_fi < 128)) ? \
-		(((u64) 1) << (_fi - 64)) : (u64) 0) | \
-	(((_fj > 63) && (_fj < 128)) ? \
-		(((u64) 1) << (_fj - 64)) : (u64) 0) | \
-	(((_fk > 63) && (_fk < 128)) ? \
-		(((u64) 1) << (_fk - 64)) : (u64) 0) | \
-	(((_fl > 63) && (_fl < 128)) ? \
-		(((u64) 1) << (_fl - 64)) : (u64) 0)))}
-
-#define DEF_REGDMN      FCC1_FCCA
-#define DEF_DMN_5       FCC1
-#define DEF_DMN_2       FCCA
 #define COUNTRY_ERD_FLAG        0x8000
 #define WORLDWIDE_ROAMING_FLAG  0x4000
-#define SUPER_DOMAIN_MASK   0x0fff
-#define COUNTRY_CODE_MASK   0x3fff
-#define CF_INTERFERENCE     (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
-#define CHANNEL_14      (2484)
-#define IS_11G_CH14(_ch,_cf) \
-    (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
-
-#define NO_PSCAN    0x0ULL
-#define PSCAN_FCC   0x0000000000000001ULL
-#define PSCAN_FCC_T 0x0000000000000002ULL
-#define PSCAN_ETSI  0x0000000000000004ULL
-#define PSCAN_MKK1  0x0000000000000008ULL
-#define PSCAN_MKK2  0x0000000000000010ULL
-#define PSCAN_MKKA  0x0000000000000020ULL
-#define PSCAN_MKKA_G    0x0000000000000040ULL
-#define PSCAN_ETSIA 0x0000000000000080ULL
-#define PSCAN_ETSIB 0x0000000000000100ULL
-#define PSCAN_ETSIC 0x0000000000000200ULL
-#define PSCAN_WWR   0x0000000000000400ULL
-#define PSCAN_MKKA1 0x0000000000000800ULL
-#define PSCAN_MKKA1_G   0x0000000000001000ULL
-#define PSCAN_MKKA2 0x0000000000002000ULL
-#define PSCAN_MKKA2_G   0x0000000000004000ULL
-#define PSCAN_MKK3  0x0000000000008000ULL
-#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
-#define IS_ECM_CHAN 0x8000000000000000ULL
-
-#define isWwrSKU(_ah) \
-	(((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
-		WORLD_SKU_PREFIX) || \
-		(ath9k_regd_get_eepromRD(_ah) == WORLD))
-
-#define isWwrSKU_NoMidband(_ah) \
-	((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
-	(ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
-	(ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
-
-#define isUNII1OddChan(ch) \
-	((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
-
-#define IS_HT40_MODE(_mode)					\
-	(((_mode == ATH9K_MODE_11NA_HT40PLUS  ||		\
-	   _mode == ATH9K_MODE_11NG_HT40PLUS    ||		\
-	   _mode == ATH9K_MODE_11NA_HT40MINUS   ||		\
-	   _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
-
-#define CHAN_FLAGS      (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
-
-#define swap_array(_a, _b, _size) {                   \
-	u8 *s = _b;                       \
-	int i = _size;                          \
-	do {                                    \
-		u8 tmp = *_a;             \
-		*_a++ = *s;                     \
-		*s++ = tmp;                     \
-	} while (--i);                          \
-	_a -= _size;                            \
-}
-
-
-#define HALF_MAXCHANBW          10
 
 #define MULTI_DOMAIN_MASK 0xFF00
 
@@ -147,81 +28,27 @@
 #define CHANNEL_HALF_BW         10
 #define CHANNEL_QUARTER_BW      5
 
-typedef int ath_hal_cmp_t(const void *, const void *);
-
 struct reg_dmn_pair_mapping {
 	u16 regDmnEnum;
-	u16 regDmn5GHz;
-	u16 regDmn2GHz;
-	u32 flags5GHz;
-	u32 flags2GHz;
-	u64 pscanMask;
-	u16 singleCC;
-};
-
-struct ccmap {
-	char isoName[3];
-	u16 countryCode;
+	u16 reg_5ghz_ctl;
+	u16 reg_2ghz_ctl;
 };
 
 struct country_code_to_enum_rd {
 	u16 countryCode;
 	u16 regDmnEnum;
 	const char *isoName;
-	const char *name;
-	bool allow11g;
-	bool allow11aTurbo;
-	bool allow11gTurbo;
-	bool allow11ng20;
-	bool allow11ng40;
-	bool allow11na20;
-	bool allow11na40;
-	u16 outdoorChanStart;
-};
-
-struct RegDmnFreqBand {
-	u16 lowChannel;
-	u16 highChannel;
-	u8 powerDfs;
-	u8 antennaMax;
-	u8 channelBW;
-	u8 channelSep;
-	u64 useDfs;
-	u64 usePassScan;
-	u8 regClassId;
 };
 
-struct regDomain {
-	u16 regDmnEnum;
-	u8 conformanceTestLimit;
-	u64 dfsMask;
-	u64 pscan;
-	u32 flags;
-	u64 chan11a[BMLEN];
-	u64 chan11a_turbo[BMLEN];
-	u64 chan11a_dyn_turbo[BMLEN];
-	u64 chan11b[BMLEN];
-	u64 chan11g[BMLEN];
-	u64 chan11g_turbo[BMLEN];
-};
-
-struct cmode {
-	u32 mode;
-	u32 flags;
-};
-
-#define YES true
-#define NO  false
-
-struct japan_bandcheck {
-	u16 freqbandbit;
-	u32 eepromflagtocheck;
-};
-
-struct common_mode_power {
-	u16 lchan;
-	u16 hchan;
-	u8 pwrlvl;
+struct ath9k_regulatory {
+	char alpha2[2];
+	u16 country_code;
+	u16 max_power_level;
+	u32 tp_scale;
+	u16 current_rd;
+	u16 current_rd_ext;
+	int16_t power_limit;
+	struct reg_dmn_pair_mapping *regpair;
 };
 
 enum CountryCode {
@@ -406,7 +233,15 @@ enum CountryCode {
 	CTRY_BELGIUM2 = 5002
 };
 
-void ath9k_regd_get_current_country(struct ath_hal *ah,
-				    struct ath9k_country_entry *ctry);
+bool ath9k_is_world_regd(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+				 enum nl80211_reg_initiator initiator);
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
+int ath9k_regd_init(struct ath_hw *ah);
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/reg.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -67,7 +67,7 @@
 #define AR_DMASIZE_512B      0x00000007
 
 #define AR_TXCFG             0x0030
-#define AR_TXCFG_DMASZ_MASK  0x00000003
+#define AR_TXCFG_DMASZ_MASK  0x00000007
 #define AR_TXCFG_DMASZ_4B    0
 #define AR_TXCFG_DMASZ_8B    1
 #define AR_TXCFG_DMASZ_16B   2
@@ -158,13 +158,6 @@
 #define AR_CST_TIMEOUT_LIMIT      0xFFFF0000
 #define AR_CST_TIMEOUT_LIMIT_S    16
 
-#define AR_SREV_VERSION_9100                  0x014
-
-#define AR_SREV_5416_V20_OR_LATER(_ah) \
-	(AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
-#define AR_SREV_5416_V22_OR_LATER(_ah) \
-	(AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
-
 #define AR_ISR               0x0080
 #define AR_ISR_RXOK          0x00000001
 #define AR_ISR_RXDESC        0x00000002
@@ -733,6 +726,7 @@
 #define AR_SREV_REVISION_5416_10               0
 #define AR_SREV_REVISION_5416_20               1
 #define AR_SREV_REVISION_5416_22               2
+#define AR_SREV_VERSION_9100                  0x14
 #define AR_SREV_VERSION_9160        	      0x40
 #define AR_SREV_REVISION_9160_10    	      0
 #define AR_SREV_REVISION_9160_11    	      1
@@ -745,45 +739,60 @@
 #define AR_SREV_REVISION_9285_11              1
 #define AR_SREV_REVISION_9285_12              2
 
-#define AR_SREV_9100_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+	 ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
 #define AR_SREV_5416_20_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
-		((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
+	(((AR_SREV_5416(_ah)) && \
+	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+	 ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
 #define AR_SREV_5416_22_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
-		((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
+	(((AR_SREV_5416(_ah)) && \
+	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+	 ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+	((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
 #define AR_SREV_9160(_ah) \
-	(((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
 #define AR_SREV_9160_10_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
 #define AR_SREV_9160_11(_ah) \
-	(AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
+	(AR_SREV_9160(_ah) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
 #define AR_SREV_9280(_ah) \
-	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
 #define AR_SREV_9280_10_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
 #define AR_SREV_9280_20(_ah) \
-	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
-		((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+		((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
 #define AR_SREV_9280_20_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
-	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
-	((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+	((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
 
-#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
 #define AR_SREV_9285_10_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
 #define AR_SREV_9285_11(_ah) \
-	(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
+	(AR_SREV_9285(ah) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
 #define AR_SREV_9285_11_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
-	 (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+	 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+			       AR_SREV_REVISION_9285_11)))
 #define AR_SREV_9285_12(_ah) \
-	(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
+	(AR_SREV_9285(ah) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
 #define AR_SREV_9285_12_OR_LATER(_ah) \
-	(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
-	 (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+	 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+			       AR_SREV_REVISION_9285_12)))
 
 #define AR_RADIO_SREV_MAJOR                   0xf0
 #define AR_RAD5133_SREV_MAJOR                 0xc0
@@ -875,12 +884,15 @@ enum {
 
 #define AR_NUM_GPIO                              14
 #define AR928X_NUM_GPIO                          10
+#define AR9285_NUM_GPIO                          12
 
 #define AR_GPIO_IN_OUT                           0x4048
 #define AR_GPIO_IN_VAL                           0x0FFFC000
 #define AR_GPIO_IN_VAL_S                         14
 #define AR928X_GPIO_IN_VAL                       0x000FFC00
 #define AR928X_GPIO_IN_VAL_S                     10
+#define AR9285_GPIO_IN_VAL                       0x00FFF000
+#define AR9285_GPIO_IN_VAL_S                     12
 
 #define AR_GPIO_OE_OUT                           0x404c
 #define AR_GPIO_OE_OUT_DRV                       0x3
@@ -894,14 +906,24 @@ enum {
 #define AR_GPIO_INTR_POL_VAL_S                   0
 
 #define AR_GPIO_INPUT_EN_VAL                     0x4054
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
+#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_ACTIVE_BB        0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
 #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
 #define AR_GPIO_JTAG_DISABLE                     0x00020000
 
 #define AR_GPIO_INPUT_MUX1                       0x4058
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
 
 #define AR_GPIO_INPUT_MUX2                       0x405c
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
@@ -940,7 +962,7 @@ enum {
 
 #define AR_RTC_BASE             0x00020000
 #define AR_RTC_RC \
-	(AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
 #define AR_RTC_RC_M		0x00000003
 #define AR_RTC_RC_MAC_WARM      0x00000001
 #define AR_RTC_RC_MAC_COLD      0x00000002
@@ -948,7 +970,7 @@ enum {
 #define AR_RTC_RC_WARM_RESET    0x00000008
 
 #define AR_RTC_PLL_CONTROL \
-	(AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
 
 #define AR_RTC_PLL_DIV          0x0000001f
 #define AR_RTC_PLL_DIV_S        0
@@ -957,8 +979,6 @@ enum {
 #define AR_RTC_PLL_CLKSEL       0x00000300
 #define AR_RTC_PLL_CLKSEL_S     8
 
-
-
 #define AR_RTC_RESET \
 	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
 #define AR_RTC_RESET_EN		(0x00000001)
@@ -995,6 +1015,12 @@ enum {
 #define AR_RTC_INTR_MASK \
 	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
 
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S  1
+
 #define	AR_SEQ_MASK	0x8060
 
 #define AR_AN_RF2G1_CH0         0x7810
@@ -1021,6 +1047,10 @@ enum {
 #define AR_AN_RF5G1_CH1_DB5     0x00380000
 #define AR_AN_RF5G1_CH1_DB5_S   19
 
+#define AR_AN_TOP1                  0x7890
+#define AR_AN_TOP1_DACIPMODE	    0x00040000
+#define AR_AN_TOP1_DACIPMODE_S	    18
+
 #define AR_AN_TOP2                  0x7894
 #define AR_AN_TOP2_XPABIAS_LVL      0xC0000000
 #define AR_AN_TOP2_XPABIAS_LVL_S    30
@@ -1181,18 +1211,7 @@ enum {
 #define AR_CFP_VAL          0x0000FFFF
 
 #define AR_RX_FILTER        0x803C
-#define AR_RX_FILTER_ALL    0x00000000
-#define AR_RX_UCAST         0x00000001
-#define AR_RX_MCAST         0x00000002
-#define AR_RX_BCAST         0x00000004
-#define AR_RX_CONTROL       0x00000008
-#define AR_RX_BEACON        0x00000010
-#define AR_RX_PROM          0x00000020
-#define AR_RX_PROBE_REQ     0x00000080
-#define AR_RX_MY_BEACON     0x00000200
 #define AR_RX_COMPR_BAR     0x00000400
-#define AR_RX_COMPR_BA      0x00000800
-#define AR_RX_UNCOM_BA_BAR  0x00001000
 
 #define AR_MCAST_FIL0       0x8040
 #define AR_MCAST_FIL1       0x8044
@@ -1236,6 +1255,8 @@ enum {
 
 #define AR_AES_MUTE_MASK1       0x8060
 #define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
 
 #define AR_GATED_CLKS       0x8064
 #define AR_GATED_CLKS_TX    0x00000002
@@ -1370,8 +1391,8 @@ enum {
 #define AR_PHY_COUNTMAX        (3 << 22)
 #define AR_MIBCNT_INTRMASK     (3 << 22)
 
-#define AR_TSF_THRESHOLD       0x813c
-#define AR_TSF_THRESHOLD_VAL   0x0000FFFF
+#define AR_TSFOOR_THRESHOLD       0x813c
+#define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
 
 #define AR_PHY_ERR_EIFS_MASK   8144
 
@@ -1460,6 +1481,10 @@ enum {
 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
 
+#define AR_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/virtual.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/virtual.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/virtual.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/virtual.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,662 @@
+/*
+ * 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.
+ */
+
+#include "ath9k.h"
+
+struct ath9k_vif_iter_data {
+	int count;
+	u8 *addr;
+};
+
+static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath9k_vif_iter_data *iter_data = data;
+	u8 *nbuf;
+
+	nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
+			GFP_ATOMIC);
+	if (nbuf == NULL)
+		return;
+
+	memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
+	iter_data->addr = nbuf;
+	iter_data->count++;
+}
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath9k_vif_iter_data iter_data;
+	int i, j;
+	u8 mask[ETH_ALEN];
+
+	/*
+	 * Add primary MAC address even if it is not in active use since it
+	 * will be configured to the hardware as the starting point and the
+	 * BSSID mask will need to be changed if another address is active.
+	 */
+	iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
+	if (iter_data.addr) {
+		memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+		iter_data.count = 1;
+	} else
+		iter_data.count = 0;
+
+	/* Get list of all active MAC addresses */
+	spin_lock_bh(&sc->wiphy_lock);
+	ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
+						   &iter_data);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] == NULL)
+			continue;
+		ieee80211_iterate_active_interfaces_atomic(
+			sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+
+	/* Generate an address mask to cover all active addresses */
+	memset(mask, 0, ETH_ALEN);
+	for (i = 0; i < iter_data.count; i++) {
+		u8 *a1 = iter_data.addr + i * ETH_ALEN;
+		for (j = i + 1; j < iter_data.count; j++) {
+			u8 *a2 = iter_data.addr + j * ETH_ALEN;
+			mask[0] |= a1[0] ^ a2[0];
+			mask[1] |= a1[1] ^ a2[1];
+			mask[2] |= a1[2] ^ a2[2];
+			mask[3] |= a1[3] ^ a2[3];
+			mask[4] |= a1[4] ^ a2[4];
+			mask[5] |= a1[5] ^ a2[5];
+		}
+	}
+
+	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];
+
+	ath9k_hw_setbssidmask(sc);
+}
+
+int ath9k_wiphy_add(struct ath_softc *sc)
+{
+	int i, error;
+	struct ath_wiphy *aphy;
+	struct ieee80211_hw *hw;
+	u8 addr[ETH_ALEN];
+
+	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
+	if (hw == NULL)
+		return -ENOMEM;
+
+	spin_lock_bh(&sc->wiphy_lock);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] == NULL)
+			break;
+	}
+
+	if (i == sc->num_sec_wiphy) {
+		/* No empty slot available; increase array length */
+		struct ath_wiphy **n;
+		n = krealloc(sc->sec_wiphy,
+			     (sc->num_sec_wiphy + 1) *
+			     sizeof(struct ath_wiphy *),
+			     GFP_ATOMIC);
+		if (n == NULL) {
+			spin_unlock_bh(&sc->wiphy_lock);
+			ieee80211_free_hw(hw);
+			return -ENOMEM;
+		}
+		n[i] = NULL;
+		sc->sec_wiphy = n;
+		sc->num_sec_wiphy++;
+	}
+
+	SET_IEEE80211_DEV(hw, sc->dev);
+
+	aphy = hw->priv;
+	aphy->sc = sc;
+	aphy->hw = hw;
+	sc->sec_wiphy[i] = aphy;
+	spin_unlock_bh(&sc->wiphy_lock);
+
+	memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+	addr[0] |= 0x02; /* Locally managed address */
+	/*
+	 * XOR virtual wiphy index into the least significant bits to generate
+	 * a different MAC address for each virtual wiphy.
+	 */
+	addr[5] ^= i & 0xff;
+	addr[4] ^= (i & 0xff00) >> 8;
+	addr[3] ^= (i & 0xff0000) >> 16;
+
+	SET_IEEE80211_PERM_ADDR(hw, addr);
+
+	ath_set_hw_capab(sc, hw);
+
+	error = ieee80211_register_hw(hw);
+
+	if (error == 0) {
+		/* Make sure wiphy scheduler is started (if enabled) */
+		ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
+	}
+
+	return error;
+}
+
+int ath9k_wiphy_del(struct ath_wiphy *aphy)
+{
+	struct ath_softc *sc = aphy->sc;
+	int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (aphy == sc->sec_wiphy[i]) {
+			sc->sec_wiphy[i] = NULL;
+			spin_unlock_bh(&sc->wiphy_lock);
+			ieee80211_unregister_hw(aphy->hw);
+			ieee80211_free_hw(aphy->hw);
+			return 0;
+		}
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+	return -ENOENT;
+}
+
+static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
+			       struct ieee80211_vif *vif, const u8 *bssid,
+			       int ps)
+{
+	struct ath_softc *sc = aphy->sc;
+	struct ath_tx_control txctl;
+	struct sk_buff *skb;
+	struct ieee80211_hdr *hdr;
+	__le16 fc;
+	struct ieee80211_tx_info *info;
+
+	skb = dev_alloc_skb(24);
+	if (skb == NULL)
+		return -ENOMEM;
+	hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
+	memset(hdr, 0, 24);
+	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+			 IEEE80211_FCTL_TODS);
+	if (ps)
+		fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+	hdr->frame_control = fc;
+	memcpy(hdr->addr1, bssid, ETH_ALEN);
+	memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
+	memcpy(hdr->addr3, bssid, ETH_ALEN);
+
+	info = IEEE80211_SKB_CB(skb);
+	memset(info, 0, sizeof(*info));
+	info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
+	info->control.vif = vif;
+	info->control.rates[0].idx = 0;
+	info->control.rates[0].count = 4;
+	info->control.rates[1].idx = -1;
+
+	memset(&txctl, 0, sizeof(struct ath_tx_control));
+	txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
+	txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
+
+	if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
+		goto exit;
+
+	return 0;
+exit:
+	dev_kfree_skb_any(skb);
+	return -1;
+}
+
+static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+	int i;
+	if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
+		return true;
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
+			return true;
+	}
+	return false;
+}
+
+static bool ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+	bool ret;
+	spin_lock_bh(&sc->wiphy_lock);
+	ret = __ath9k_wiphy_pausing(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+	return ret;
+}
+
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+	int i;
+	if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+		return true;
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+			return true;
+	}
+	return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+	bool ret;
+	spin_lock_bh(&sc->wiphy_lock);
+	ret = __ath9k_wiphy_scanning(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+	return ret;
+}
+
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
+{
+	if (aphy == NULL)
+		return;
+	if (aphy->chan_idx != aphy->sc->chan_idx)
+		return; /* wiphy not on the selected channel */
+	__ath9k_wiphy_unpause(aphy);
+}
+
+static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
+{
+	int i;
+	spin_lock_bh(&sc->wiphy_lock);
+	__ath9k_wiphy_unpause_ch(sc->pri_wiphy);
+	for (i = 0; i < sc->num_sec_wiphy; i++)
+		__ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_chan_work(struct work_struct *work)
+{
+	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+	struct ath_wiphy *aphy = sc->next_wiphy;
+
+	if (aphy == NULL)
+		return;
+
+	/*
+	 * All pending interfaces paused; ready to change
+	 * channels.
+	 */
+
+	/* Change channels */
+	mutex_lock(&sc->mutex);
+	/* XXX: remove me eventually */
+	ath9k_update_ichannel(sc, aphy->hw,
+			      &sc->sc_ah->channels[sc->chan_idx]);
+	ath_update_chainmask(sc, sc->chan_is_ht);
+	if (ath_set_channel(sc, aphy->hw,
+			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
+		printk(KERN_DEBUG "ath9k: Failed to set channel for new "
+		       "virtual wiphy\n");
+		mutex_unlock(&sc->mutex);
+		return;
+	}
+	mutex_unlock(&sc->mutex);
+
+	ath9k_wiphy_unpause_channel(sc);
+}
+
+/*
+ * ath9k version of ieee80211_tx_status() for TX frames that are generated
+ * internally in the driver.
+ */
+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 &&
+	    aphy->state == ATH_WIPHY_PAUSING) {
+		if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+			printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
+			       "frame\n", wiphy_name(hw->wiphy));
+			/*
+			 * The AP did not reply; ignore this to allow us to
+			 * continue.
+			 */
+		}
+		aphy->state = ATH_WIPHY_PAUSED;
+		if (!ath9k_wiphy_pausing(aphy->sc)) {
+			/*
+			 * Drop from tasklet to work to allow mutex for channel
+			 * change.
+			 */
+			queue_work(aphy->sc->hw->workqueue,
+				   &aphy->sc->chan_work);
+		}
+	}
+
+	kfree(tx_info_priv);
+	tx_info->rate_driver_data[0] = NULL;
+
+	dev_kfree_skb(skb);
+}
+
+static void ath9k_mark_paused(struct ath_wiphy *aphy)
+{
+	struct ath_softc *sc = aphy->sc;
+	aphy->state = ATH_WIPHY_PAUSED;
+	if (!__ath9k_wiphy_pausing(sc))
+		queue_work(sc->hw->workqueue, &sc->chan_work);
+}
+
+static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath_wiphy *aphy = data;
+	struct ath_vif *avp = (void *) vif->drv_priv;
+
+	switch (vif->type) {
+	case NL80211_IFTYPE_STATION:
+		if (!vif->bss_conf.assoc) {
+			ath9k_mark_paused(aphy);
+			break;
+		}
+		/* TODO: could avoid this if already in PS mode */
+		if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
+			printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
+			       __func__);
+			ath9k_mark_paused(aphy);
+		}
+		break;
+	case NL80211_IFTYPE_AP:
+		/* Beacon transmission is paused by aphy->state change */
+		ath9k_mark_paused(aphy);
+		break;
+	default:
+		break;
+	}
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+	ieee80211_stop_queues(aphy->hw);
+	aphy->state = ATH_WIPHY_PAUSING;
+	/*
+	 * TODO: handle PAUSING->PAUSED for the case where there are multiple
+	 * active vifs (now we do it on the first vif getting ready; should be
+	 * on the last)
+	 */
+	ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
+						   aphy);
+	return 0;
+}
+
+int ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+	int ret;
+	spin_lock_bh(&aphy->sc->wiphy_lock);
+	ret = __ath9k_wiphy_pause(aphy);
+	spin_unlock_bh(&aphy->sc->wiphy_lock);
+	return ret;
+}
+
+static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath_wiphy *aphy = data;
+	struct ath_vif *avp = (void *) vif->drv_priv;
+
+	switch (vif->type) {
+	case NL80211_IFTYPE_STATION:
+		if (!vif->bss_conf.assoc)
+			break;
+		ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
+		break;
+	case NL80211_IFTYPE_AP:
+		/* Beacon transmission is re-enabled by aphy->state change */
+		break;
+	default:
+		break;
+	}
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+	ieee80211_iterate_active_interfaces_atomic(aphy->hw,
+						   ath9k_unpause_iter, aphy);
+	aphy->state = ATH_WIPHY_ACTIVE;
+	ieee80211_wake_queues(aphy->hw);
+	return 0;
+}
+
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+	int ret;
+	spin_lock_bh(&aphy->sc->wiphy_lock);
+	ret = __ath9k_wiphy_unpause(aphy);
+	spin_unlock_bh(&aphy->sc->wiphy_lock);
+	return ret;
+}
+
+static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
+{
+	int i;
+	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
+		sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
+			sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
+	}
+}
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
+{
+	int i;
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+		__ath9k_wiphy_pause(sc->pri_wiphy);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+			__ath9k_wiphy_pause(sc->sec_wiphy[i]);
+	}
+}
+
+int ath9k_wiphy_select(struct ath_wiphy *aphy)
+{
+	struct ath_softc *sc = aphy->sc;
+	bool now;
+
+	spin_lock_bh(&sc->wiphy_lock);
+	if (__ath9k_wiphy_scanning(sc)) {
+		/*
+		 * For now, we are using mac80211 sw scan and it expects to
+		 * have full control over channel changes, so avoid wiphy
+		 * scheduling during a scan. This could be optimized if the
+		 * scanning control were moved into the driver.
+		 */
+		spin_unlock_bh(&sc->wiphy_lock);
+		return -EBUSY;
+	}
+	if (__ath9k_wiphy_pausing(sc)) {
+		if (sc->wiphy_select_failures == 0)
+			sc->wiphy_select_first_fail = jiffies;
+		sc->wiphy_select_failures++;
+		if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
+		{
+			printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
+			       "out; disable/enable hw to recover\n");
+			__ath9k_wiphy_mark_all_paused(sc);
+			/*
+			 * TODO: this workaround to fix hardware is unlikely to
+			 * be specific to virtual wiphy changes. It can happen
+			 * on normal channel change, too, and as such, this
+			 * should really be made more generic. For example,
+			 * tricker radio disable/enable on GTT interrupt burst
+			 * (say, 10 GTT interrupts received without any TX
+			 * frame being completed)
+			 */
+			spin_unlock_bh(&sc->wiphy_lock);
+			ath_radio_disable(sc);
+			ath_radio_enable(sc);
+			queue_work(aphy->sc->hw->workqueue,
+				   &aphy->sc->chan_work);
+			return -EBUSY; /* previous select still in progress */
+		}
+		spin_unlock_bh(&sc->wiphy_lock);
+		return -EBUSY; /* previous select still in progress */
+	}
+	sc->wiphy_select_failures = 0;
+
+	/* Store the new channel */
+	sc->chan_idx = aphy->chan_idx;
+	sc->chan_is_ht = aphy->chan_is_ht;
+	sc->next_wiphy = aphy;
+
+	__ath9k_wiphy_pause_all(sc);
+	now = !__ath9k_wiphy_pausing(aphy->sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+
+	if (now) {
+		/* Ready to request channel change immediately */
+		queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+	}
+
+	/*
+	 * wiphys will be unpaused in ath9k_tx_status() once channel has been
+	 * changed if any wiphy needs time to become paused.
+	 */
+
+	return 0;
+}
+
+bool ath9k_wiphy_started(struct ath_softc *sc)
+{
+	int i;
+	spin_lock_bh(&sc->wiphy_lock);
+	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+		spin_unlock_bh(&sc->wiphy_lock);
+		return true;
+	}
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
+			spin_unlock_bh(&sc->wiphy_lock);
+			return true;
+		}
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+	return false;
+}
+
+static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
+				   struct ath_wiphy *selected)
+{
+	if (selected->state == ATH_WIPHY_SCAN) {
+		if (aphy == selected)
+			return;
+		/*
+		 * Pause all other wiphys for the duration of the scan even if
+		 * they are on the current channel now.
+		 */
+	} else if (aphy->chan_idx == selected->chan_idx)
+		return;
+	aphy->state = ATH_WIPHY_PAUSED;
+	ieee80211_stop_queues(aphy->hw);
+}
+
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+				  struct ath_wiphy *selected)
+{
+	int i;
+	spin_lock_bh(&sc->wiphy_lock);
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+		ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i] &&
+		    sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+			ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_work(struct work_struct *work)
+{
+	struct ath_softc *sc = container_of(work, struct ath_softc,
+					    wiphy_work.work);
+	struct ath_wiphy *aphy = NULL;
+	bool first = true;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	if (sc->wiphy_scheduler_int == 0) {
+		/* wiphy scheduler is disabled */
+		spin_unlock_bh(&sc->wiphy_lock);
+		return;
+	}
+
+try_again:
+	sc->wiphy_scheduler_index++;
+	while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
+		aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
+		if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
+			break;
+
+		sc->wiphy_scheduler_index++;
+		aphy = NULL;
+	}
+	if (aphy == NULL) {
+		sc->wiphy_scheduler_index = 0;
+		if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
+			if (first) {
+				first = false;
+				goto try_again;
+			}
+			/* No wiphy is ready to be scheduled */
+		} else
+			aphy = sc->pri_wiphy;
+	}
+
+	spin_unlock_bh(&sc->wiphy_lock);
+
+	if (aphy &&
+	    aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
+	    ath9k_wiphy_select(aphy)) {
+		printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
+		       "change\n");
+	}
+
+	queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+			   sc->wiphy_scheduler_int);
+}
+
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
+{
+	cancel_delayed_work_sync(&sc->wiphy_work);
+	sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
+	if (sc->wiphy_scheduler_int)
+		queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+				   sc->wiphy_scheduler_int);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/xmit.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/xmit.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ath9k/xmit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/xmit.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * 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
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "core.h"
+#include "ath9k.h"
 
 #define BITS_PER_BYTE           8
 #define OFDM_PLCP_BITS          22
@@ -55,94 +55,23 @@ static u32 bits_per_symbol[][2] = {
 
 #define IS_HT_RATE(_rate)     ((_rate) & 0x80)
 
-/*
- * Insert a chain of ath_buf (descriptors) on a txq and
- * assume the descriptors are already chained together by caller.
- * NB: must be called with txq lock held
- */
-
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+				  struct ath_atx_tid *tid,
+				  struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+				struct list_head *bf_q,
+				int txok, int sendbar);
 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-			     struct list_head *head)
-{
-	struct ath_hal *ah = sc->sc_ah;
-	struct ath_buf *bf;
-
-	/*
-	 * Insert the frame on the outbound list and
-	 * pass it on to the hardware.
-	 */
-
-	if (list_empty(head))
-		return;
-
-	bf = list_first_entry(head, struct ath_buf, list);
-
-	list_splice_tail_init(head, &txq->axq_q);
-	txq->axq_depth++;
-	txq->axq_totalqueued++;
-	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);
-
-	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);
-	} 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);
-	}
-	txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
-	ath9k_hw_txstart(ah, txq->axq_qnum);
-}
-
-static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-			    struct ath_xmit_status *tx_status)
-{
-	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;
-
-	DPRINTF(sc, 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 (tx_status->flags & ATH_TX_BAR) {
-		tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-		tx_status->flags &= ~ATH_TX_BAR;
-	}
-
-	if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
-		/* Frame was ACKed */
-		tx_info->flags |= IEEE80211_TX_STAT_ACK;
-	}
-
-	tx_info->status.rates[0].count = tx_status->retries + 1;
-
-	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-	padsize = hdrlen & 3;
-	if (padsize && hdrlen >= 24) {
-		/*
-		 * Remove MAC header padding before giving the frame back to
-		 * mac80211.
-		 */
-		memmove(skb->data + padsize, skb->data, hdrlen);
-		skb_pull(skb, padsize);
-	}
-
-	ieee80211_tx_status(hw, skb);
-}
+			     struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+			      int txok);
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+			     int nbad, int txok, bool update_rc);
 
-/* Check if it's okay to send out aggregates */
+/*********************/
+/* Aggregation logic */
+/*********************/
 
 static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
 {
@@ -156,232 +85,19 @@ static int ath_aggr_query(struct ath_sof
 		return 0;
 }
 
-static void ath_get_beaconconfig(struct ath_softc *sc, int if_id,
-				 struct ath_beacon_config *conf)
-{
-	struct ieee80211_hw *hw = sc->hw;
-
-	/* fill in beacon config data */
-
-	conf->beacon_interval = hw->conf.beacon_int;
-	conf->listen_interval = 100;
-	conf->dtim_count = 1;
-	conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
-}
-
-/* Calculate Atheros packet type from IEEE80211 packet header */
-
-static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr;
-	enum ath9k_pkt_type htype;
-	__le16 fc;
-
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
-
-	if (ieee80211_is_beacon(fc))
-		htype = ATH9K_PKT_TYPE_BEACON;
-	else if (ieee80211_is_probe_resp(fc))
-		htype = ATH9K_PKT_TYPE_PROBE_RESP;
-	else if (ieee80211_is_atim(fc))
-		htype = ATH9K_PKT_TYPE_ATIM;
-	else if (ieee80211_is_pspoll(fc))
-		htype = ATH9K_PKT_TYPE_PSPOLL;
-	else
-		htype = ATH9K_PKT_TYPE_NORMAL;
-
-	return htype;
-}
-
-static bool is_pae(struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr;
-	__le16 fc;
-
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
-
-	if (ieee80211_is_data(fc)) {
-		if (ieee80211_is_nullfunc(fc) ||
-		    /* Port Access Entity (IEEE 802.1X) */
-		    (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-			return true;
-		}
-	}
-
-	return false;
-}
-
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
-	if (tx_info->control.hw_key) {
-		if (tx_info->control.hw_key->alg == ALG_WEP)
-			return ATH9K_KEY_TYPE_WEP;
-		else if (tx_info->control.hw_key->alg == ALG_TKIP)
-			return ATH9K_KEY_TYPE_TKIP;
-		else if (tx_info->control.hw_key->alg == ALG_CCMP)
-			return ATH9K_KEY_TYPE_AES;
-	}
-
-	return ATH9K_KEY_TYPE_CLEAR;
-}
-
-/* Called only when tx aggregation is enabled and HT is supported */
-
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
-				  struct ath_buf *bf)
-{
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_hdr *hdr;
-	struct ath_node *an;
-	struct ath_atx_tid *tid;
-	__le16 fc;
-	u8 *qc;
-
-	if (!tx_info->control.sta)
-		return;
-
-	an = (struct ath_node *)tx_info->control.sta->drv_priv;
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
-
-	/* Get tidno */
-
-	if (ieee80211_is_data_qos(fc)) {
-		qc = ieee80211_get_qos_ctl(hdr);
-		bf->bf_tidno = qc[0] & 0xf;
-	}
-
-	/* Get seqno */
-	/* 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);
-	bf->bf_seqno = tid->seq_next;
-	INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-}
-
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
-			  struct ath_txq *txq)
-{
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	int flags = 0;
-
-	flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
-	flags |= ATH9K_TXDESC_INTREQ;
-
-	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-		flags |= ATH9K_TXDESC_NOACK;
-	if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-		flags |= ATH9K_TXDESC_RTSENA;
-
-	return flags;
-}
-
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
-	struct ath_buf *bf = NULL;
-
-	spin_lock_bh(&sc->tx.txbuflock);
-
-	if (unlikely(list_empty(&sc->tx.txbuf))) {
-		spin_unlock_bh(&sc->tx.txbuflock);
-		return NULL;
-	}
-
-	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-	list_del(&bf->list);
-
-	spin_unlock_bh(&sc->tx.txbuflock);
-
-	return bf;
-}
-
-/* To complete a chain of buffers associated a frame */
-
-static void ath_tx_complete_buf(struct ath_softc *sc,
-				struct ath_buf *bf,
-				struct list_head *bf_q,
-				int txok, int sendbar)
-{
-	struct sk_buff *skb = bf->bf_mpdu;
-	struct ath_xmit_status tx_status;
-	unsigned long flags;
-
-	/*
-	 * Set retry information.
-	 * NB: Don't use the information in the descriptor, because the frame
-	 * could be software retried.
-	 */
-	tx_status.retries = bf->bf_retries;
-	tx_status.flags = 0;
-
-	if (sendbar)
-		tx_status.flags = ATH_TX_BAR;
-
-	if (!txok) {
-		tx_status.flags |= ATH_TX_ERROR;
-
-		if (bf_isxretried(bf))
-			tx_status.flags |= ATH_TX_XRETRY;
-	}
-
-	/* Unmap this frame */
-	pci_unmap_single(sc->pdev,
-			 bf->bf_dmacontext,
-			 skb->len,
-			 PCI_DMA_TODEVICE);
-	/* complete this frame */
-	ath_tx_complete(sc, skb, &tx_status);
-
-	/*
-	 * Return the list of ath_buf of this mpdu to free queue
-	 */
-	spin_lock_irqsave(&sc->tx.txbuflock, flags);
-	list_splice_tail_init(bf_q, &sc->tx.txbuf);
-	spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-}
-
-/*
- * queue up a dest/ac pair for tx scheduling
- * NB: must be called with txq lock held
- */
-
 static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
 {
 	struct ath_atx_ac *ac = tid->ac;
 
-	/*
-	 * if tid is paused, hold off
-	 */
 	if (tid->paused)
 		return;
 
-	/*
-	 * add tid to ac atmost once
-	 */
 	if (tid->sched)
 		return;
 
 	tid->sched = true;
 	list_add_tail(&tid->list, &ac->tid_q);
 
-	/*
-	 * add node ac to txq atmost once
-	 */
 	if (ac->sched)
 		return;
 
@@ -389,22 +105,16 @@ static void ath_tx_queue_tid(struct ath_
 	list_add_tail(&ac->list, &txq->axq_acq);
 }
 
-/* pause a tid */
-
 static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
 	struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
 
 	spin_lock_bh(&txq->axq_lock);
-
 	tid->paused++;
-
 	spin_unlock_bh(&txq->axq_lock);
 }
 
-/* resume a tid and schedule aggregate */
-
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
 	struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
 
@@ -419,63 +129,39 @@ void ath_tx_resume_tid(struct ath_softc
 	if (list_empty(&tid->buf_q))
 		goto unlock;
 
-	/*
-	 * Add this TID to scheduler and try to send out aggregates
-	 */
 	ath_tx_queue_tid(txq, tid);
 	ath_txq_schedule(sc, txq);
 unlock:
 	spin_unlock_bh(&txq->axq_lock);
 }
 
-/* Compute the number of bad frames */
-
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
-			      int txok)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
-	struct ath_buf *bf_last = bf->bf_lastbf;
-	struct ath_desc *ds = bf_last->bf_desc;
-	u16 seq_st = 0;
-	u32 ba[WME_BA_BMP_SIZE >> 5];
-	int ba_index;
-	int nbad = 0;
-	int isaggr = 0;
-
-	if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
-		return 0;
+	struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+	struct ath_buf *bf;
+	struct list_head bf_head;
+	INIT_LIST_HEAD(&bf_head);
 
-	isaggr = bf_isaggr(bf);
-	if (isaggr) {
-		seq_st = ATH_DS_BA_SEQ(ds);
-		memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
-	}
+	ASSERT(tid->paused > 0);
+	spin_lock_bh(&txq->axq_lock);
 
-	while (bf) {
-		ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
-		if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
-			nbad++;
+	tid->paused--;
 
-		bf = bf->bf_next;
+	if (tid->paused > 0) {
+		spin_unlock_bh(&txq->axq_lock);
+		return;
 	}
 
-	return nbad;
-}
-
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
-{
-	struct sk_buff *skb;
-	struct ieee80211_hdr *hdr;
-
-	bf->bf_state.bf_type |= BUF_RETRY;
-	bf->bf_retries++;
+	while (!list_empty(&tid->buf_q)) {
+		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+		ASSERT(!bf_isretried(bf));
+		list_move_tail(&bf->list, &bf_head);
+		ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+	}
 
-	skb = bf->bf_mpdu;
-	hdr = (struct ieee80211_hdr *)skb->data;
-	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+	spin_unlock_bh(&txq->axq_lock);
 }
 
-/* Update block ack window */
-
 static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
 			      int seqno)
 {
@@ -492,296 +178,150 @@ static void ath_tx_update_baw(struct ath
 	}
 }
 
-/*
- * ath_pkt_dur - compute packet duration (NB: not NAV)
- *
- * rix - rate index
- * pktlen - total bytes (delims + data + fcs + pads + pad delims)
- * width  - 0 for 20 MHz, 1 for 40 MHz
- * half_gi - to use 4us v/s 3.6 us for symbol time
- */
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
-			    int width, int half_gi, bool shortPreamble)
+static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+			     struct ath_buf *bf)
 {
-	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);
+	int index, cindex;
 
-	/* find number of symbols: PLCP + data */
-	nbits = (pktlen << 3) + OFDM_PLCP_BITS;
-	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
-	nsymbols = (nbits + nsymbits - 1) / nsymbits;
+	if (bf_isretried(bf))
+		return;
 
-	if (!half_gi)
-		duration = SYMBOL_TIME(nsymbols);
-	else
-		duration = SYMBOL_TIME_HALFGI(nsymbols);
+	index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+	cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
 
-	/* addup duration for legacy/ht training and signal fields */
-	streams = HT_RC_2_STREAMS(rc);
-	duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+	ASSERT(tid->tx_buf[cindex] == NULL);
+	tid->tx_buf[cindex] = bf;
 
-	return duration;
+	if (index >= ((tid->baw_tail - tid->baw_head) &
+		(ATH_TID_MAX_BUFS - 1))) {
+		tid->baw_tail = cindex;
+		INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
+	}
 }
 
-/* Rate module function to set rate related fields in tx descriptor */
+/*
+ * TODO: For frame(s) that are in the retry state, we will reuse the
+ * sequence number(s) without setting the retry bit. The
+ * alternative is to give up on these and BAR the receiver's window
+ * forward.
+ */
+static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
+			  struct ath_atx_tid *tid)
 
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ath_hal *ah = sc->sc_ah;
-	struct ath_rate_table *rt;
-	struct ath_desc *ds = bf->bf_desc;
-	struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
-	struct ath9k_11n_rate_series series[4];
-	struct sk_buff *skb;
-	struct ieee80211_tx_info *tx_info;
-	struct ieee80211_tx_rate *rates;
-	struct ieee80211_hdr *hdr;
-	int i, flags, rtsctsena = 0;
-	u32 ctsduration = 0;
-	u8 rix = 0, cix, ctsrate = 0;
-	__le16 fc;
-
-	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-
-	skb = (struct sk_buff *)bf->bf_mpdu;
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
-	tx_info = IEEE80211_SKB_CB(skb);
-	rates = tx_info->control.rates;
-
-	if (ieee80211_has_morefrags(fc) ||
-	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
-		rates[1].count = rates[2].count = rates[3].count = 0;
-		rates[1].idx = rates[2].idx = rates[3].idx = 0;
-		rates[0].count = ATH_TXMAXTRY;
-	}
+	struct ath_buf *bf;
+	struct list_head bf_head;
+	INIT_LIST_HEAD(&bf_head);
 
-	/* get the cix for the lowest valid rix */
-	rt = sc->cur_rate_table;
-	for (i = 3; i >= 0; i--) {
-		if (rates[i].count && (rates[i].idx >= 0)) {
-			rix = rates[i].idx;
+	for (;;) {
+		if (list_empty(&tid->buf_q))
 			break;
-		}
-	}
-
-	flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
-	cix = rt->info[rix].ctrl_rate;
-
-	/*
-	 * If 802.11g protection is enabled, determine whether to use RTS/CTS or
-	 * just CTS.  Note that this is only done for OFDM/HT unicast frames.
-	 */
-	if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK)
-	    && (rt->info[rix].phy == WLAN_RC_PHY_OFDM ||
-		WLAN_RC_PHY_HT(rt->info[rix].phy))) {
-		if (sc->sc_protmode == PROT_M_RTSCTS)
-			flags = ATH9K_TXDESC_RTSENA;
-		else if (sc->sc_protmode == PROT_M_CTSONLY)
-			flags = ATH9K_TXDESC_CTSENA;
-
-		cix = rt->info[sc->sc_protrix].ctrl_rate;
-		rtsctsena = 1;
-	}
-
-	/* For 11n, the default behavior is to enable RTS for hw retried frames.
-	 * We enable the global flag here and let rate series flags determine
-	 * which rates will actually use RTS.
-	 */
-	if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
-		/* 802.11g protection not needed, use our default behavior */
-		if (!rtsctsena)
-			flags = ATH9K_TXDESC_RTSENA;
-	}
-
-	/* Set protection if aggregate protection on */
-	if (sc->sc_config.ath_aggr_prot &&
-	    (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
-		flags = ATH9K_TXDESC_RTSENA;
-		cix = rt->info[sc->sc_protrix].ctrl_rate;
-		rtsctsena = 1;
-	}
 
-	/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
-	if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit))
-		flags &= ~(ATH9K_TXDESC_RTSENA);
-
-	/*
-	 * CTS transmit rate is derived from the transmit rate by looking in the
-	 * h/w rate table.  We must also factor in whether or not a short
-	 * preamble is to be used. NB: cix is set above where RTS/CTS is enabled
-	 */
-	ctsrate = rt->info[cix].ratecode |
-		(bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0);
-
-	for (i = 0; i < 4; i++) {
-		if (!rates[i].count || (rates[i].idx < 0))
-			continue;
-
-		rix = rates[i].idx;
-
-		series[i].Rate = rt->info[rix].ratecode |
-			(bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0);
-
-		series[i].Tries = rates[i].count;
-
-		series[i].RateFlags = (
-			(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ?
-				ATH9K_RATESERIES_RTS_CTS : 0) |
-			((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ?
-				ATH9K_RATESERIES_2040 : 0) |
-			((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ?
-				ATH9K_RATESERIES_HALFGI : 0);
-
-		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),
-			 bf_isshpreamble(bf));
+		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+		list_move_tail(&bf->list, &bf_head);
 
-		series[i].ChSel = sc->sc_tx_chainmask;
+		if (bf_isretried(bf))
+			ath_tx_update_baw(sc, tid, bf->bf_seqno);
 
-		if (rtsctsena)
-			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+		spin_unlock(&txq->axq_lock);
+		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+		spin_lock(&txq->axq_lock);
 	}
 
-	/* set dur_update_en for l-sig computation except for PS-Poll frames */
-	ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf),
-				     ctsrate, ctsduration,
-				     series, 4, flags);
-
-	if (sc->sc_config.ath_aggr_prot && flags)
-		ath9k_hw_set11n_burstduration(ah, ds, 8192);
+	tid->seq_next = tid->seq_start;
+	tid->baw_tail = tid->baw_head;
 }
 
-/*
- * Function to send a normal HT (non-AMPDU) frame
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_normal(struct ath_softc *sc,
-			      struct ath_txq *txq,
-			      struct ath_atx_tid *tid,
-			      struct list_head *bf_head)
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ath_buf *bf;
-
-	BUG_ON(list_empty(bf_head));
-
-	bf = list_first_entry(bf_head, struct ath_buf, list);
-	bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */
-
-	/* update starting sequence number for subsequent ADDBA request */
-	INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+	struct sk_buff *skb;
+	struct ieee80211_hdr *hdr;
 
-	/* Queue to h/w without aggregation */
-	bf->bf_nframes = 1;
-	bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
-	ath_buf_set_rate(sc, bf);
-	ath_tx_txqaddbuf(sc, txq, bf_head);
+	bf->bf_state.bf_type |= BUF_RETRY;
+	bf->bf_retries++;
 
-	return 0;
+	skb = bf->bf_mpdu;
+	hdr = (struct ieee80211_hdr *)skb->data;
+	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
 }
 
-/* flush tid's software queue and send frames as non-ampdu's */
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-	struct ath_buf *bf;
-	struct list_head bf_head;
-	INIT_LIST_HEAD(&bf_head);
-
-	ASSERT(tid->paused > 0);
-	spin_lock_bh(&txq->axq_lock);
+	struct ath_buf *tbf;
 
-	tid->paused--;
+	spin_lock_bh(&sc->tx.txbuflock);
+	ASSERT(!list_empty((&sc->tx.txbuf)));
+	tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+	list_del(&tbf->list);
+	spin_unlock_bh(&sc->tx.txbuflock);
 
-	if (tid->paused > 0) {
-		spin_unlock_bh(&txq->axq_lock);
-		return;
-	}
+	ATH_TXBUF_RESET(tbf);
 
-	while (!list_empty(&tid->buf_q)) {
-		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-		ASSERT(!bf_isretried(bf));
-		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
-		ath_tx_send_normal(sc, txq, tid, &bf_head);
-	}
+	tbf->bf_mpdu = bf->bf_mpdu;
+	tbf->bf_buf_addr = bf->bf_buf_addr;
+	*(tbf->bf_desc) = *(bf->bf_desc);
+	tbf->bf_state = bf->bf_state;
+	tbf->bf_dmacontext = bf->bf_dmacontext;
 
-	spin_unlock_bh(&txq->axq_lock);
+	return tbf;
 }
 
-/* Completion routine of an aggregate */
-
-static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
-				      struct ath_txq *txq,
-				      struct ath_buf *bf,
-				      struct list_head *bf_q,
-				      int txok)
+static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+				 struct ath_buf *bf, struct list_head *bf_q,
+				 int txok)
 {
 	struct ath_node *an = NULL;
 	struct sk_buff *skb;
-	struct ieee80211_tx_info *tx_info;
+	struct ieee80211_sta *sta;
+	struct ieee80211_hdr *hdr;
 	struct ath_atx_tid *tid = NULL;
-	struct ath_buf *bf_last = bf->bf_lastbf;
+	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
 	struct ath_desc *ds = bf_last->bf_desc;
-	struct ath_buf *bf_next, *bf_lastq = NULL;
 	struct list_head bf_head, bf_pending;
-	u16 seq_st = 0;
+	u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
 	u32 ba[WME_BA_BMP_SIZE >> 5];
-	int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
+	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+	bool rc_update = true;
 
 	skb = (struct sk_buff *)bf->bf_mpdu;
-	tx_info = IEEE80211_SKB_CB(skb);
+	hdr = (struct ieee80211_hdr *)skb->data;
 
-	if (tx_info->control.sta) {
-		an = (struct ath_node *)tx_info->control.sta->drv_priv;
-		tid = ATH_AN_2_TID(an, bf->bf_tidno);
+	rcu_read_lock();
+
+	sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+	if (!sta) {
+		rcu_read_unlock();
+		return;
 	}
 
+	an = (struct ath_node *)sta->drv_priv;
+	tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
 	isaggr = bf_isaggr(bf);
-	if (isaggr) {
-		if (txok) {
-			if (ATH_DS_TX_BA(ds)) {
-				/*
-				 * extract starting sequence and
-				 * block-ack bitmap
-				 */
-				seq_st = ATH_DS_BA_SEQ(ds);
-				memcpy(ba,
-					ATH_DS_BA_BITMAP(ds),
-					WME_BA_BMP_SIZE >> 3);
-			} else {
-				memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+	memset(ba, 0, WME_BA_BMP_SIZE >> 3);
 
-				/*
-				 * AR5416 can become deaf/mute when BA
-				 * issue happens. Chip needs to be reset.
-				 * But AP code may have sychronization issues
-				 * when perform internal reset in this routine.
-				 * Only enable reset in STA mode for now.
-				 */
-				if (sc->sc_ah->ah_opmode ==
-					    NL80211_IFTYPE_STATION)
-					needreset = 1;
-			}
+	if (isaggr && txok) {
+		if (ATH_DS_TX_BA(ds)) {
+			seq_st = ATH_DS_BA_SEQ(ds);
+			memcpy(ba, ATH_DS_BA_BITMAP(ds),
+			       WME_BA_BMP_SIZE >> 3);
 		} else {
-			memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+			/*
+			 * AR5416 can become deaf/mute when BA
+			 * issue happens. Chip needs to be reset.
+			 * But AP code may have sychronization issues
+			 * when perform internal reset in this routine.
+			 * Only enable reset in STA mode for now.
+			 */
+			if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
+				needreset = 1;
 		}
 	}
 
 	INIT_LIST_HEAD(&bf_pending);
 	INIT_LIST_HEAD(&bf_head);
 
+	nbad = ath_tx_num_badfrms(sc, bf, txok);
 	while (bf) {
 		txfail = txpending = 0;
 		bf_next = bf->bf_next;
@@ -789,10 +329,11 @@ static void ath_tx_complete_aggr_rifs(st
 		if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
 			/* transmit completion, subframe is
 			 * acked by block ack */
+			acked_cnt++;
 		} else if (!isaggr && txok) {
 			/* transmit completion */
+			acked_cnt++;
 		} else {
-
 			if (!(tid->state & AGGR_CLEANUP) &&
 			    ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
 				if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
@@ -802,6 +343,7 @@ static void ath_tx_complete_aggr_rifs(st
 					bf->bf_state.bf_type |= BUF_XRETRY;
 					txfail = 1;
 					sendbar = 1;
+					txfail_cnt++;
 				}
 			} else {
 				/*
@@ -811,37 +353,12 @@ static void ath_tx_complete_aggr_rifs(st
 				txfail = 1;
 			}
 		}
-		/*
-		 * Remove ath_buf's of this sub-frame from aggregate queue.
-		 */
-		if (bf_next == NULL) {  /* last subframe in the aggregate */
-			ASSERT(bf->bf_lastfrm == bf_last);
-
-			/*
-			 * The last descriptor of the last sub frame could be
-			 * a holding descriptor for h/w. If that's the case,
-			 * bf->bf_lastfrm won't be in the bf_q.
-			 * Make sure we handle bf_q properly here.
-			 */
 
-			if (!list_empty(bf_q)) {
-				bf_lastq = list_entry(bf_q->prev,
-					struct ath_buf, list);
-				list_cut_position(&bf_head,
-					bf_q, &bf_lastq->list);
-			} else {
-				/*
-				 * XXX: if the last subframe only has one
-				 * descriptor which is also being used as
-				 * a holding descriptor. Then the ath_buf
-				 * is not in the bf_q at all.
-				 */
-				INIT_LIST_HEAD(&bf_head);
-			}
+		if (bf_next == NULL) {
+			INIT_LIST_HEAD(&bf_head);
 		} else {
 			ASSERT(!list_empty(bf_q));
-			list_cut_position(&bf_head,
-				bf_q, &bf->bf_lastfrm->list);
+			list_move_tail(&bf->list, &bf_head);
 		}
 
 		if (!txpending) {
@@ -853,62 +370,29 @@ static void ath_tx_complete_aggr_rifs(st
 			ath_tx_update_baw(sc, tid, bf->bf_seqno);
 			spin_unlock_bh(&txq->axq_lock);
 
-			/* complete this sub-frame */
+			if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+				ath_tx_rc_status(bf, ds, nbad, txok, true);
+				rc_update = false;
+			} else {
+				ath_tx_rc_status(bf, ds, nbad, txok, false);
+			}
+
 			ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
 		} else {
-			/*
-			 * retry the un-acked ones
-			 */
-			/*
-			 * XXX: if the last descriptor is holding descriptor,
-			 * in order to requeue the frame to software queue, we
-			 * need to allocate a new descriptor and
-			 * copy the content of holding descriptor to it.
-			 */
+			/* retry the un-acked ones */
 			if (bf->bf_next == NULL &&
 			    bf_last->bf_status & ATH_BUFSTATUS_STALE) {
 				struct ath_buf *tbf;
 
-				/* allocate new descriptor */
-				spin_lock_bh(&sc->tx.txbuflock);
-				ASSERT(!list_empty((&sc->tx.txbuf)));
-				tbf = list_first_entry(&sc->tx.txbuf,
-						struct ath_buf, list);
-				list_del(&tbf->list);
-				spin_unlock_bh(&sc->tx.txbuflock);
-
-				ATH_TXBUF_RESET(tbf);
-
-				/* copy descriptor content */
-				tbf->bf_mpdu = bf_last->bf_mpdu;
-				tbf->bf_buf_addr = bf_last->bf_buf_addr;
-				*(tbf->bf_desc) = *(bf_last->bf_desc);
-
-				/* link it to the frame */
-				if (bf_lastq) {
-					bf_lastq->bf_desc->ds_link =
-						tbf->bf_daddr;
-					bf->bf_lastfrm = tbf;
-					ath9k_hw_cleartxdesc(sc->sc_ah,
-						bf->bf_lastfrm->bf_desc);
-				} else {
-					tbf->bf_state = bf_last->bf_state;
-					tbf->bf_lastfrm = tbf;
-					ath9k_hw_cleartxdesc(sc->sc_ah,
-						tbf->bf_lastfrm->bf_desc);
-
-					/* copy the DMA context */
-					tbf->bf_dmacontext =
-						bf_last->bf_dmacontext;
-				}
+				tbf = ath_clone_txbuf(sc, bf_last);
+				ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
 				list_add_tail(&tbf->list, &bf_head);
 			} else {
 				/*
 				 * Clear descriptor status words for
 				 * software retry
 				 */
-				ath9k_hw_cleartxdesc(sc->sc_ah,
-						     bf->bf_lastfrm->bf_desc);
+				ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
 			}
 
 			/*
@@ -922,332 +406,33 @@ static void ath_tx_complete_aggr_rifs(st
 	}
 
 	if (tid->state & AGGR_CLEANUP) {
-		/* check to see if we're done with cleaning the h/w queue */
-		spin_lock_bh(&txq->axq_lock);
-
 		if (tid->baw_head == tid->baw_tail) {
 			tid->state &= ~AGGR_ADDBA_COMPLETE;
 			tid->addba_exchangeattempts = 0;
-			spin_unlock_bh(&txq->axq_lock);
-
 			tid->state &= ~AGGR_CLEANUP;
 
 			/* send buffered frames as singles */
 			ath_tx_flush_tid(sc, tid);
-		} else
-			spin_unlock_bh(&txq->axq_lock);
-
+		}
+		rcu_read_unlock();
 		return;
 	}
 
-	/*
-	 * prepend un-acked frames to the beginning of the pending frame queue
-	 */
+	/* prepend un-acked frames to the beginning of the pending frame queue */
 	if (!list_empty(&bf_pending)) {
 		spin_lock_bh(&txq->axq_lock);
-		/* Note: we _prepend_, we _do_not_ at to
-		 * the end of the queue ! */
 		list_splice(&bf_pending, &tid->buf_q);
 		ath_tx_queue_tid(txq, tid);
 		spin_unlock_bh(&txq->axq_lock);
 	}
 
+	rcu_read_unlock();
+
 	if (needreset)
 		ath_reset(sc, false);
-
-	return;
-}
-
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
-{
-	struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-
-	tx_info_priv->update_rc = false;
-	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) {
-		if (bf_isdata(bf)) {
-			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;
-			tx_info_priv->update_rc = true;
-		}
-	}
-}
-
-/* Process completed xmit descriptors from the specified queue */
-
-static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
-{
-	struct ath_hal *ah = sc->sc_ah;
-	struct ath_buf *bf, *lastbf, *bf_held = NULL;
-	struct list_head bf_head;
-	struct ath_desc *ds;
-	int txok, nbad = 0;
-	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);
-
-	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;
-		}
-		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
-		/*
-		 * There is a race condition that a BH gets scheduled
-		 * after sw writes TxE and before hw re-load the last
-		 * descriptor to get the newly chained one.
-		 * Software must keep the last DONE descriptor as a
-		 * holding descriptor - software does so by marking
-		 * it with the STALE flag.
-		 */
-		bf_held = NULL;
-		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
-			bf_held = bf;
-			if (list_is_last(&bf_held->list, &txq->axq_q)) {
-				/* FIXME:
-				 * The holding descriptor is the last
-				 * descriptor in queue. It's safe to remove
-				 * the last holding descriptor in BH context.
-				 */
-				spin_unlock_bh(&txq->axq_lock);
-				break;
-			} else {
-				/* Lets work with the next buffer now */
-				bf = list_entry(bf_held->list.next,
-					struct ath_buf, list);
-			}
-		}
-
-		lastbf = bf->bf_lastbf;
-		ds = lastbf->bf_desc;    /* NB: last decriptor */
-
-		status = ath9k_hw_txprocdesc(ah, ds);
-		if (status == -EINPROGRESS) {
-			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;
-
-		/*
-		 * Remove ath_buf's of the same transmit unit from txq,
-		 * however leave the last descriptor back as the holding
-		 * descriptor for hw.
-		 */
-		lastbf->bf_status |= ATH_BUFSTATUS_STALE;
-		INIT_LIST_HEAD(&bf_head);
-
-		if (!list_is_singular(&lastbf->list))
-			list_cut_position(&bf_head,
-				&txq->axq_q, lastbf->list.prev);
-
-		txq->axq_depth--;
-
-		if (bf_isaggr(bf))
-			txq->axq_aggr_depth--;
-
-		txok = (ds->ds_txstat.ts_status == 0);
-
-		spin_unlock_bh(&txq->axq_lock);
-
-		if (bf_held) {
-			list_del(&bf_held->list);
-			spin_lock_bh(&sc->tx.txbuflock);
-			list_add_tail(&bf_held->list, &sc->tx.txbuf);
-			spin_unlock_bh(&sc->tx.txbuflock);
-		}
-
-		if (!bf_isampdu(bf)) {
-			/*
-			 * This frame is sent out as a single frame.
-			 * Use hardware retry status for this frame.
-			 */
-			bf->bf_retries = ds->ds_txstat.ts_longretry;
-			if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
-				bf->bf_state.bf_type |= BUF_XRETRY;
-			nbad = 0;
-		} else {
-			nbad = ath_tx_num_badfrms(sc, bf, txok);
-		}
-
-		ath_tx_rc_status(bf, ds, nbad);
-
-		/*
-		 * Complete this transmit unit
-		 */
-		if (bf_isampdu(bf))
-			ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
-		else
-			ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
-
-		/* Wake up mac80211 queue */
-
-		spin_lock_bh(&txq->axq_lock);
-		if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
-				(ATH_TXBUF - 20)) {
-			int qnum;
-			qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
-			if (qnum != -1) {
-				ieee80211_wake_queue(sc->hw, qnum);
-				txq->stopped = 0;
-			}
-
-		}
-
-		/*
-		 * schedule any pending packets if aggregation is enabled
-		 */
-		if (sc->sc_flags & SC_OP_TXAGGR)
-			ath_txq_schedule(sc, txq);
-		spin_unlock_bh(&txq->axq_lock);
-	}
-}
-
-static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
-{
-	struct ath_hal *ah = sc->sc_ah;
-
-	(void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
-	DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n",
-		txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum),
-		txq->axq_link);
-}
-
-/* Drain only the data queues */
-
-static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
-{
-	struct ath_hal *ah = sc->sc_ah;
-	int i, status, npend = 0;
-
-	if (!(sc->sc_flags & SC_OP_INVALID)) {
-		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-			if (ATH_TXQ_SETUP(sc, i)) {
-				ath_tx_stopdma(sc, &sc->tx.txq[i]);
-				/* The TxDMA may not really be stopped.
-				 * Double check the hal tx pending count */
-				npend += ath9k_hw_numtxpending(ah,
-						       sc->tx.txq[i].axq_qnum);
-			}
-		}
-	}
-
-	if (npend) {
-		/* TxDMA not stopped, reset the hal */
-		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
-
-		spin_lock_bh(&sc->sc_resetlock);
-		if (!ath9k_hw_reset(ah,
-				    sc->sc_ah->ah_curchan,
-				    sc->tx_chan_width,
-				    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
-				    sc->sc_ht_extprotspacing, true, &status)) {
-
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to reset hardware; hal status %u\n",
-				status);
-		}
-		spin_unlock_bh(&sc->sc_resetlock);
-	}
-
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-		if (ATH_TXQ_SETUP(sc, i))
-			ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
-	}
-}
-
-/* Add a sub-frame to block ack window */
-
-static void ath_tx_addto_baw(struct ath_softc *sc,
-			     struct ath_atx_tid *tid,
-			     struct ath_buf *bf)
-{
-	int index, cindex;
-
-	if (bf_isretried(bf))
-		return;
-
-	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);
-	tid->tx_buf[cindex] = bf;
-
-	if (index >= ((tid->baw_tail - tid->baw_head) &
-		(ATH_TID_MAX_BUFS - 1))) {
-		tid->baw_tail = cindex;
-		INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
-	}
-}
-
-/*
- * Function to send an A-MPDU
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_ampdu(struct ath_softc *sc,
-			     struct ath_atx_tid *tid,
-			     struct list_head *bf_head,
-			     struct ath_tx_control *txctl)
-{
-	struct ath_buf *bf;
-
-	BUG_ON(list_empty(bf_head));
-
-	bf = list_first_entry(bf_head, struct ath_buf, list);
-	bf->bf_state.bf_type |= BUF_AMPDU;
-
-	/*
-	 * Do not queue to h/w when any of the following conditions is true:
-	 * - there are pending frames in software queue
-	 * - the TID is currently paused for ADDBA/BAR request
-	 * - seqno is not within block-ack window
-	 * - h/w queue depth exceeds low water mark
-	 */
-	if (!list_empty(&tid->buf_q) || tid->paused ||
-	    !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
-	    txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
-		/*
-		 * Add this frame to software queue for scheduling later
-		 * for aggregation.
-		 */
-		list_splice_tail_init(bf_head, &tid->buf_q);
-		ath_tx_queue_tid(txctl->txq, tid);
-		return 0;
-	}
-
-	/* Add sub-frame to BAW */
-	ath_tx_addto_baw(sc, tid, bf);
-
-	/* Queue to h/w without aggregation */
-	bf->bf_nframes = 1;
-	bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
-	ath_buf_set_rate(sc, bf);
-	ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
-
-	return 0;
 }
 
-/*
- * looks up the rate
- * returns aggr limit based on lowest of the rates
- */
-static u32 ath_lookup_rate(struct ath_softc *sc,
-			   struct ath_buf *bf,
+static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 			   struct ath_atx_tid *tid)
 {
 	struct ath_rate_table *rate_table = sc->cur_rate_table;
@@ -1255,15 +440,14 @@ static u32 ath_lookup_rate(struct ath_so
 	struct ieee80211_tx_info *tx_info;
 	struct ieee80211_tx_rate *rates;
 	struct ath_tx_info_priv *tx_info_priv;
-	u32 max_4ms_framelen, frame_length;
+	u32 max_4ms_framelen, frmlen;
 	u16 aggr_limit, legacy = 0, maxampdu;
 	int i;
 
 	skb = (struct sk_buff *)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];
+	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
@@ -1279,9 +463,8 @@ static u32 ath_lookup_rate(struct ath_so
 				break;
 			}
 
-			frame_length =
-				rate_table->info[rates[i].idx].max_4ms_framelen;
-			max_4ms_framelen = min(max_4ms_framelen, frame_length);
+			frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+			max_4ms_framelen = min(max_4ms_framelen, frmlen);
 		}
 	}
 
@@ -1293,8 +476,7 @@ static u32 ath_lookup_rate(struct ath_so
 	if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
 		return 0;
 
-	aggr_limit = min(max_4ms_framelen,
-		(u32)ATH_AMPDU_LIMIT_DEFAULT);
+	aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
 
 	/*
 	 * h/w can accept aggregates upto 16 bit lengths (65535).
@@ -1309,14 +491,12 @@ static u32 ath_lookup_rate(struct ath_so
 }
 
 /*
- * returns the number of delimiters to be added to
+ * Returns the number of delimiters to be added to
  * meet the minimum required mpdudensity.
- * caller should make sure that the rate is  HT rate .
+ * caller should make sure that the rate is HT rate .
  */
-static int ath_compute_num_delims(struct ath_softc *sc,
-				  struct ath_atx_tid *tid,
-				  struct ath_buf *bf,
-				  u16 frmlen)
+static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
+				  struct ath_buf *bf, u16 frmlen)
 {
 	struct ath_rate_table *rt = sc->cur_rate_table;
 	struct sk_buff *skb = bf->bf_mpdu;
@@ -1370,9 +550,7 @@ static int ath_compute_num_delims(struct
 	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
 	minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
 
-	/* Is frame shorter than required minimum length? */
 	if (frmlen < minlen) {
-		/* Get the minimum number of delimiters required. */
 		mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
 		ndelim = max(mindelim, ndelim);
 	}
@@ -1380,37 +558,23 @@ static int ath_compute_num_delims(struct
 	return ndelim;
 }
 
-/*
- * For aggregation from software buffer queue.
- * NB: must be called with txq lock held
- */
 static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
-					struct ath_atx_tid *tid,
-					struct list_head *bf_q,
-					struct ath_buf **bf_last,
-					struct aggr_rifs_param *param,
-					int *prev_frames)
+					     struct ath_atx_tid *tid,
+					     struct list_head *bf_q)
 {
 #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
-	struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
-	struct list_head bf_head;
-	int rl = 0, nframes = 0, ndelim;
+	struct ath_buf *bf, *bf_first, *bf_prev = NULL;
+	int rl = 0, nframes = 0, ndelim, prev_al = 0;
 	u16 aggr_limit = 0, al = 0, bpad = 0,
 		al_delta, h_baw = tid->baw_size / 2;
 	enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
-	int prev_al = 0;
-	INIT_LIST_HEAD(&bf_head);
-
-	BUG_ON(list_empty(&tid->buf_q));
 
 	bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
 
 	do {
 		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
 
-		/*
-		 * do not step over block-ack window
-		 */
+		/* do not step over block-ack window */
 		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
 			status = ATH_AGGR_BAW_CLOSED;
 			break;
@@ -1421,29 +585,23 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 			rl = 1;
 		}
 
-		/*
-		 * do not exceed aggregation limit
-		 */
+		/* do not exceed aggregation limit */
 		al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
 
-		if (nframes && (aggr_limit <
-			(al + bpad + al_delta + prev_al))) {
+		if (nframes &&
+		    (aggr_limit < (al + bpad + al_delta + prev_al))) {
 			status = ATH_AGGR_LIMITED;
 			break;
 		}
 
-		/*
-		 * do not exceed subframe limit
-		 */
-		if ((nframes + *prev_frames) >=
-		    min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
+		/* do not exceed subframe limit */
+		if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
 			status = ATH_AGGR_LIMITED;
 			break;
 		}
+		nframes++;
 
-		/*
-		 * add padding for previous frame to aggregation length
-		 */
+		/* add padding for previous frame to aggregation length */
 		al += bpad + al_delta;
 
 		/*
@@ -1451,69 +609,35 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 		 * density for this node.
 		 */
 		ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
-
 		bpad = PADBYTES(al_delta) + (ndelim << 2);
 
 		bf->bf_next = NULL;
-		bf->bf_lastfrm->bf_desc->ds_link = 0;
+		bf->bf_desc->ds_link = 0;
 
-		/*
-		 * this packet is part of an aggregate
-		 * - remove all descriptors belonging to this frame from
-		 *   software queue
-		 * - add it to block ack window
-		 * - set up descriptors for aggregation
-		 */
-		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
+		/* link buffers of this frame to the aggregate */
 		ath_tx_addto_baw(sc, tid, bf);
-
-		list_for_each_entry(tbf, &bf_head, list) {
-			ath9k_hw_set11n_aggr_middle(sc->sc_ah,
-				tbf->bf_desc, ndelim);
-		}
-
-		/*
-		 * link buffers of this frame to the aggregate
-		 */
-		list_splice_tail_init(&bf_head, bf_q);
-		nframes++;
-
+		ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+		list_move_tail(&bf->list, bf_q);
 		if (bf_prev) {
 			bf_prev->bf_next = bf;
-			bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
+			bf_prev->bf_desc->ds_link = bf->bf_daddr;
 		}
 		bf_prev = bf;
-
-#ifdef AGGR_NOSHORT
-		/*
-		 * terminate aggregation on a small packet boundary
-		 */
-		if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
-			status = ATH_AGGR_SHORTPKT;
-			break;
-		}
-#endif
 	} while (!list_empty(&tid->buf_q));
 
 	bf_first->bf_al = al;
 	bf_first->bf_nframes = nframes;
-	*bf_last = bf_prev;
+
 	return status;
 #undef PADBYTES
 }
 
-/*
- * process pending frames possibly doing a-mpdu aggregation
- * NB: must be called with txq lock held
- */
-static void ath_tx_sched_aggr(struct ath_softc *sc,
-	struct ath_txq *txq, struct ath_atx_tid *tid)
+static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+			      struct ath_atx_tid *tid)
 {
-	struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
+	struct ath_buf *bf;
 	enum ATH_AGGR_STATUS status;
 	struct list_head bf_q;
-	struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
-	int prev_frames = 0;
 
 	do {
 		if (list_empty(&tid->buf_q))
@@ -1521,382 +645,169 @@ static void ath_tx_sched_aggr(struct ath
 
 		INIT_LIST_HEAD(&bf_q);
 
-		status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
-					  &prev_frames);
+		status = ath_tx_form_aggr(sc, tid, &bf_q);
 
 		/*
-		 * no frames picked up to be aggregated; block-ack
-		 * window is not open
+		 * no frames picked up to be aggregated;
+		 * block-ack window is not open.
 		 */
 		if (list_empty(&bf_q))
 			break;
 
 		bf = list_first_entry(&bf_q, struct ath_buf, list);
-		bf_last = list_entry(bf_q.prev, struct ath_buf, list);
-		bf->bf_lastbf = bf_last;
+		bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
 
-		/*
-		 * if only one frame, send as non-aggregate
-		 */
+		/* if only one frame, send as non-aggregate */
 		if (bf->bf_nframes == 1) {
-			ASSERT(bf->bf_lastfrm == bf_last);
-
 			bf->bf_state.bf_type &= ~BUF_AGGR;
-			/*
-			 * clear aggr bits for every descriptor
-			 * XXX TODO: is there a way to optimize it?
-			 */
-			list_for_each_entry(tbf, &bf_q, list) {
-				ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
-			}
-
+			ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
 			ath_buf_set_rate(sc, bf);
 			ath_tx_txqaddbuf(sc, txq, &bf_q);
 			continue;
 		}
 
-		/*
-		 * setup first desc with rate and aggr info
-		 */
+		/* setup first desc of aggregate */
 		bf->bf_state.bf_type |= BUF_AGGR;
 		ath_buf_set_rate(sc, bf);
 		ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
 
-		/*
-		 * anchor last frame of aggregate correctly
-		 */
-		ASSERT(bf_lastaggr);
-		ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
-		tbf = bf_lastaggr;
-		ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
-
-		/* XXX: We don't enter into this loop, consider removing this */
-		while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
-			tbf = list_entry(tbf->list.next, struct ath_buf, list);
-			ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
-		}
+		/* anchor last desc of aggregate */
+		ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
 
 		txq->axq_aggr_depth++;
-
-		/*
-		 * Normal aggregate, queue to hardware
-		 */
 		ath_tx_txqaddbuf(sc, txq, &bf_q);
 
 	} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
 		 status != ATH_AGGR_BAW_CLOSED);
 }
 
-/* Called with txq lock held */
-
-static void ath_tid_drain(struct ath_softc *sc,
-			  struct ath_txq *txq,
-			  struct ath_atx_tid *tid)
-
-{
-	struct ath_buf *bf;
-	struct list_head bf_head;
-	INIT_LIST_HEAD(&bf_head);
-
-	for (;;) {
-		if (list_empty(&tid->buf_q))
-			break;
-		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
-		list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
-
-		/* update baw for software retried frame */
-		if (bf_isretried(bf))
-			ath_tx_update_baw(sc, tid, bf->bf_seqno);
-
-		/*
-		 * do not indicate packets while holding txq spinlock.
-		 * unlock is intentional here
-		 */
-		spin_unlock(&txq->axq_lock);
-
-		/* complete this sub-frame */
-		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-
-		spin_lock(&txq->axq_lock);
-	}
-
-	/*
-	 * TODO: For frame(s) that are in the retry state, we will reuse the
-	 * sequence number(s) without setting the retry bit. The
-	 * alternative is to give up on these and BAR the receiver's window
-	 * forward.
-	 */
-	tid->seq_next = tid->seq_start;
-	tid->baw_tail = tid->baw_head;
-}
-
-/*
- * Drain all pending buffers
- * NB: must be called with txq lock held
- */
-static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
-					  struct ath_txq *txq)
-{
-	struct ath_atx_ac *ac, *ac_tmp;
-	struct ath_atx_tid *tid, *tid_tmp;
-
-	list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
-		list_del(&ac->list);
-		ac->sched = false;
-		list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
-			list_del(&tid->list);
-			tid->sched = false;
-			ath_tid_drain(sc, txq, tid);
-		}
-	}
-}
-
-static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
-				struct sk_buff *skb,
-				struct ath_tx_control *txctl)
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+		      u16 tid, u16 *ssn)
 {
-	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;
-
-	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;
-	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-	fc = hdr->frame_control;
-
-	ATH_TXBUF_RESET(bf);
-
-	/* Frame type */
-
-	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-
-	ieee80211_is_data(fc) ?
-		(bf->bf_state.bf_type |= BUF_DATA) :
-		(bf->bf_state.bf_type &= ~BUF_DATA);
-	ieee80211_is_back_req(fc) ?
-		(bf->bf_state.bf_type |= BUF_BAR) :
-		(bf->bf_state.bf_type &= ~BUF_BAR);
-	ieee80211_is_pspoll(fc) ?
-		(bf->bf_state.bf_type |= BUF_PSPOLL) :
-		(bf->bf_state.bf_type &= ~BUF_PSPOLL);
-	(sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
-		(bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
-		(bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);
-	(sc->hw->conf.ht.enabled && !is_pae(skb) &&
-	 (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ?
-		(bf->bf_state.bf_type |= BUF_HT) :
-		(bf->bf_state.bf_type &= ~BUF_HT);
-
-	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-
-	/* Crypto */
-
-	bf->bf_keytype = get_hw_crypto_keytype(skb);
-
-	if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
-		bf->bf_frmlen += tx_info->control.hw_key->icv_len;
-		bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
-	} else {
-		bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
-	}
-
-	/* Assign seqno, tidno */
-
-	if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
-		assign_aggr_tid_seqno(skb, bf);
+	struct ath_atx_tid *txtid;
+	struct ath_node *an;
 
-	/* DMA setup */
-	bf->bf_mpdu = skb;
+	an = (struct ath_node *)sta->drv_priv;
 
-	bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
-					   skb->len, PCI_DMA_TODEVICE);
-	if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) {
-		bf->bf_mpdu = NULL;
-		DPRINTF(sc, ATH_DBG_CONFIG,
-			"pci_dma_mapping_error() on TX\n");
-		return -ENOMEM;
+	if (sc->sc_flags & SC_OP_TXAGGR) {
+		txtid = ATH_AN_2_TID(an, tid);
+		txtid->state |= AGGR_ADDBA_PROGRESS;
+		ath_tx_pause_tid(sc, txtid);
+		*ssn = txtid->seq_start;
 	}
 
-	bf->bf_buf_addr = bf->bf_dmacontext;
 	return 0;
 }
 
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
-			     struct ath_tx_control *txctl)
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
-	struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-	struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
-	struct ath_node *an = NULL;
+	struct ath_node *an = (struct ath_node *)sta->drv_priv;
+	struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+	struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+	struct ath_buf *bf;
 	struct list_head bf_head;
-	struct ath_desc *ds;
-	struct ath_atx_tid *tid;
-	struct ath_hal *ah = sc->sc_ah;
-	int frm_type;
-
-	frm_type = get_hw_packet_type(skb);
-
 	INIT_LIST_HEAD(&bf_head);
-	list_add_tail(&bf->list, &bf_head);
-
-	/* setup descriptor */
-
-	ds = bf->bf_desc;
-	ds->ds_link = 0;
-	ds->ds_data = bf->bf_buf_addr;
 
-	/* Formulate first tx descriptor with tx controls */
-
-	ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
-			       bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-
-	ath9k_hw_filltxdesc(ah, ds,
-			    skb->len,	/* segment length */
-			    true,	/* first segment */
-			    true,	/* last segment */
-			    ds);	/* first descriptor */
-
-	bf->bf_lastfrm = bf;
+	if (txtid->state & AGGR_CLEANUP)
+		return 0;
 
-	spin_lock_bh(&txctl->txq->axq_lock);
+	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+		txtid->addba_exchangeattempts = 0;
+		return 0;
+	}
 
-	if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
-	    tx_info->control.sta) {
-		an = (struct ath_node *)tx_info->control.sta->drv_priv;
-		tid = ATH_AN_2_TID(an, bf->bf_tidno);
+	ath_tx_pause_tid(sc, txtid);
 
-		if (ath_aggr_query(sc, an, bf->bf_tidno)) {
-			/*
-			 * Try aggregation if it's a unicast data frame
-			 * and the destination is HT capable.
-			 */
-			ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
-		} else {
+	/* drop all software retried frames and mark this TID */
+	spin_lock_bh(&txq->axq_lock);
+	while (!list_empty(&txtid->buf_q)) {
+		bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
+		if (!bf_isretried(bf)) {
 			/*
-			 * Send this frame as regular when ADDBA
-			 * exchange is neither complete nor pending.
+			 * NB: it's based on the assumption that
+			 * software retried frame will always stay
+			 * at the head of software queue.
 			 */
-			ath_tx_send_normal(sc, txctl->txq,
-					   tid, &bf_head);
+			break;
 		}
-	} else {
-		bf->bf_lastbf = bf;
-		bf->bf_nframes = 1;
+		list_move_tail(&bf->list, &bf_head);
+		ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+	}
+	spin_unlock_bh(&txq->axq_lock);
 
-		ath_buf_set_rate(sc, bf);
-		ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
+	if (txtid->baw_head != txtid->baw_tail) {
+		txtid->state |= AGGR_CLEANUP;
+	} else {
+		txtid->state &= ~AGGR_ADDBA_COMPLETE;
+		txtid->addba_exchangeattempts = 0;
+		ath_tx_flush_tid(sc, txtid);
 	}
 
-	spin_unlock_bh(&txctl->txq->axq_lock);
+	return 0;
 }
 
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
-		 struct ath_tx_control *txctl)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
-	struct ath_buf *bf;
-	int r;
-
-	/* Check if a tx buffer is available */
-
-	bf = ath_tx_get_buffer(sc);
-	if (!bf) {
-		DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
-		return -1;
-	}
-
-	r = ath_tx_setup_buffer(sc, bf, skb, txctl);
-	if (unlikely(r)) {
-		struct ath_txq *txq = txctl->txq;
-
-		DPRINTF(sc, 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
-		 * we will at least have to run TX completionon one buffer
-		 * on the queue */
-		spin_lock_bh(&txq->axq_lock);
-		if (ath_txq_depth(sc, txq->axq_qnum) > 1) {
-			ieee80211_stop_queue(sc->hw,
-				skb_get_queue_mapping(skb));
-			txq->stopped = 1;
-		}
-		spin_unlock_bh(&txq->axq_lock);
+	struct ath_atx_tid *txtid;
+	struct ath_node *an;
 
-		spin_lock_bh(&sc->tx.txbuflock);
-		list_add_tail(&bf->list, &sc->tx.txbuf);
-		spin_unlock_bh(&sc->tx.txbuflock);
+	an = (struct ath_node *)sta->drv_priv;
 
-		return r;
+	if (sc->sc_flags & SC_OP_TXAGGR) {
+		txtid = ATH_AN_2_TID(an, tid);
+		txtid->baw_size =
+			IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+		txtid->state |= AGGR_ADDBA_COMPLETE;
+		txtid->state &= ~AGGR_ADDBA_PROGRESS;
+		ath_tx_resume_tid(sc, txtid);
 	}
-
-	ath_tx_start_dma(sc, bf, txctl);
-
-	return 0;
 }
 
-/* Initialize TX queue and h/w */
-
-int ath_tx_init(struct ath_softc *sc, int nbufs)
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
 {
-	int error = 0;
+	struct ath_atx_tid *txtid;
 
-	do {
-		spin_lock_init(&sc->tx.txbuflock);
+	if (!(sc->sc_flags & SC_OP_TXAGGR))
+		return false;
 
-		/* Setup tx descriptors */
-		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);
-			break;
-		}
+	txtid = ATH_AN_2_TID(an, tidno);
 
-		/* XXX allocate beacon state together with vap */
-		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);
-			break;
+	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+		if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
+		    (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
+			txtid->addba_exchangeattempts++;
+			return true;
 		}
+	}
 
-	} while (0);
-
-	if (error != 0)
-		ath_tx_cleanup(sc);
-
-	return error;
+	return false;
 }
 
-/* Reclaim all tx queue resources */
+/********************/
+/* Queue Management */
+/********************/
 
-int ath_tx_cleanup(struct ath_softc *sc)
+static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
+					  struct ath_txq *txq)
 {
-	/* cleanup beacon descriptors */
-	if (sc->beacon.bdma.dd_desc_len != 0)
-		ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
-
-	/* cleanup tx descriptors */
-	if (sc->tx.txdma.dd_desc_len != 0)
-		ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+	struct ath_atx_ac *ac, *ac_tmp;
+	struct ath_atx_tid *tid, *tid_tmp;
 
-	return 0;
+	list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+		list_del(&ac->list);
+		ac->sched = false;
+		list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
+			list_del(&tid->list);
+			tid->sched = false;
+			ath_tid_drain(sc, txq, tid);
+		}
+	}
 }
 
-/* Setup a h/w transmit queue */
-
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	struct ath9k_tx_queue_info qi;
 	int qnum;
 
@@ -1959,43 +870,7 @@ struct ath_txq *ath_txq_setup(struct ath
 	return &sc->tx.txq[qnum];
 }
 
-/* Reclaim resources for a setup queue */
-
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
-{
-	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
-	sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
-}
-
-/*
- * Setup a hardware data transmit queue for the specified
- * access control.  The hal may not support all requested
- * queues in which case it will return a reference to a
- * previously setup queue.  We record the mapping from ac's
- * to h/w queues for use by ath_tx_start and also track
- * the set of h/w queues being used to optimize work in the
- * transmit interrupt handler and related routines.
- */
-
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
-	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",
-			 haltype, ARRAY_SIZE(sc->tx.hwq_map));
-		return 0;
-	}
-	txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
-	if (txq != NULL) {
-		sc->tx.hwq_map[haltype] = txq->axq_qnum;
-		return 1;
-	} else
-		return 0;
-}
-
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
 {
 	int qnum;
 
@@ -2021,8 +896,6 @@ int ath_tx_get_qnum(struct ath_softc *sc
 	return qnum;
 }
 
-/* Get a transmit queue, if available */
-
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ath_txq *txq = NULL;
@@ -2033,9 +906,8 @@ struct ath_txq *ath_test_get_txq(struct
 
 	spin_lock_bh(&txq->axq_lock);
 
-	/* Try to avoid running out of descriptors */
 	if (txq->axq_depth >= (ATH_TXBUF - 20)) {
-		DPRINTF(sc, ATH_DBG_FATAL,
+		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));
@@ -2049,12 +921,10 @@ struct ath_txq *ath_test_get_txq(struct
 	return txq;
 }
 
-/* Update parameters for a transmit queue */
-
 int ath_txq_update(struct ath_softc *sc, int qnum,
 		   struct ath9k_tx_queue_info *qinfo)
 {
-	struct ath_hal *ah = sc->sc_ah;
+	struct ath_hw *ah = sc->sc_ah;
 	int error = 0;
 	struct ath9k_tx_queue_info qi;
 
@@ -2082,7 +952,7 @@ int ath_txq_update(struct ath_softc *sc,
 			"Unable to update hardware queue %u!\n", qnum);
 		error = -EIO;
 	} else {
-		ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
+		ath9k_hw_resettxqueue(ah, qnum);
 	}
 
 	return error;
@@ -2092,55 +962,36 @@ int ath_cabq_update(struct ath_softc *sc
 {
 	struct ath9k_tx_queue_info qi;
 	int qnum = sc->beacon.cabq->axq_qnum;
-	struct ath_beacon_config conf;
 
 	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
 	/*
 	 * Ensure the readytime % is within the bounds.
 	 */
-	if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
-		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
-	else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
-		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+	if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+		sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+	else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+		sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
 
-	ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
-	qi.tqi_readyTime =
-		(conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
+	qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+			    sc->config.cabqReadytime) / 100;
 	ath_txq_update(sc, qnum, &qi);
 
 	return 0;
 }
 
-/* Deferred processing of transmit interrupt */
-
-void ath_tx_tasklet(struct ath_softc *sc)
-{
-	int i;
-	u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
-	ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
-
-	/*
-	 * Process each active queue.
-	 */
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-		if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
-			ath_tx_processq(sc, &sc->tx.txq[i]);
-	}
-}
-
-void ath_tx_draintxq(struct ath_softc *sc,
-	struct ath_txq *txq, bool retry_tx)
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 {
 	struct ath_buf *bf, *lastbf;
 	struct list_head bf_head;
 
 	INIT_LIST_HEAD(&bf_head);
 
-	/*
-	 * NB: this assumes output has been stopped and
-	 *     we do not need to block ath_tx_tasklet
-	 */
 	for (;;) {
 		spin_lock_bh(&txq->axq_lock);
 
@@ -2175,7 +1026,7 @@ void ath_tx_draintxq(struct ath_softc *s
 		spin_unlock_bh(&txq->axq_lock);
 
 		if (bf_isampdu(bf))
-			ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
+			ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
 		else
 			ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
 	}
@@ -2190,44 +1041,285 @@ void ath_tx_draintxq(struct ath_softc *s
 	}
 }
 
-/* Drain the transmit queues and reclaim resources */
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_txq *txq;
+	int i, npend = 0;
 
-void ath_draintxq(struct ath_softc *sc, bool retry_tx)
+	if (sc->sc_flags & SC_OP_INVALID)
+		return;
+
+	/* Stop beacon queue */
+	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+	/* Stop data queues */
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ATH_TXQ_SETUP(sc, i)) {
+			txq = &sc->tx.txq[i];
+			ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+			npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+		}
+	}
+
+	if (npend) {
+		int r;
+
+		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+		spin_lock_bh(&sc->sc_resetlock);
+		r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+		if (r)
+			DPRINTF(sc, ATH_DBG_FATAL,
+				"Unable to reset hardware; reset status %u\n",
+				r);
+		spin_unlock_bh(&sc->sc_resetlock);
+	}
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ATH_TXQ_SETUP(sc, i))
+			ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
+	}
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
 {
-	/* stop beacon queue. The beacon will be freed when
-	 * we go to INIT state */
-	if (!(sc->sc_flags & SC_OP_INVALID)) {
-		(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-		DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
-			ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq));
+	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+	sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+{
+	struct ath_atx_ac *ac;
+	struct ath_atx_tid *tid;
+
+	if (list_empty(&txq->axq_acq))
+		return;
+
+	ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+	list_del(&ac->list);
+	ac->sched = false;
+
+	do {
+		if (list_empty(&ac->tid_q))
+			return;
+
+		tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+		list_del(&tid->list);
+		tid->sched = false;
+
+		if (tid->paused)
+			continue;
+
+		if ((txq->axq_depth % 2) == 0)
+			ath_tx_sched_aggr(sc, txq, tid);
+
+		/*
+		 * add tid to round-robin queue if more frames
+		 * are pending for the tid
+		 */
+		if (!list_empty(&tid->buf_q))
+			ath_tx_queue_tid(txq, tid);
+
+		break;
+	} while (!list_empty(&ac->tid_q));
+
+	if (!list_empty(&ac->tid_q)) {
+		if (!ac->sched) {
+			ac->sched = true;
+			list_add_tail(&ac->list, &txq->axq_acq);
+		}
 	}
+}
 
-	ath_drain_txdataq(sc, retry_tx);
+int ath_tx_setup(struct ath_softc *sc, int haltype)
+{
+	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",
+			 haltype, ARRAY_SIZE(sc->tx.hwq_map));
+		return 0;
+	}
+	txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+	if (txq != NULL) {
+		sc->tx.hwq_map[haltype] = txq->axq_qnum;
+		return 1;
+	} else
+		return 0;
 }
 
-u32 ath_txq_depth(struct ath_softc *sc, int qnum)
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+			     struct list_head *head)
 {
-	return sc->tx.txq[qnum].axq_depth;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_buf *bf;
+
+	/*
+	 * Insert the frame on the outbound list and
+	 * pass it on to the hardware.
+	 */
+
+	if (list_empty(head))
+		return;
+
+	bf = list_first_entry(head, struct ath_buf, list);
+
+	list_splice_tail_init(head, &txq->axq_q);
+	txq->axq_depth++;
+	txq->axq_totalqueued++;
+	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);
+
+	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);
+	} 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);
+	}
+	txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+	ath9k_hw_txstart(ah, txq->axq_qnum);
 }
 
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
 {
-	return sc->tx.txq[qnum].axq_aggr_depth;
+	struct ath_buf *bf = NULL;
+
+	spin_lock_bh(&sc->tx.txbuflock);
+
+	if (unlikely(list_empty(&sc->tx.txbuf))) {
+		spin_unlock_bh(&sc->tx.txbuflock);
+		return NULL;
+	}
+
+	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+	list_del(&bf->list);
+
+	spin_unlock_bh(&sc->tx.txbuflock);
+
+	return bf;
 }
 
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+			      struct list_head *bf_head,
+			      struct ath_tx_control *txctl)
 {
-	struct ath_atx_tid *txtid;
+	struct ath_buf *bf;
 
-	if (!(sc->sc_flags & SC_OP_TXAGGR))
-		return false;
+	bf = list_first_entry(bf_head, struct ath_buf, list);
+	bf->bf_state.bf_type |= BUF_AMPDU;
 
-	txtid = ATH_AN_2_TID(an, tidno);
+	/*
+	 * Do not queue to h/w when any of the following conditions is true:
+	 * - there are pending frames in software queue
+	 * - the TID is currently paused for ADDBA/BAR request
+	 * - seqno is not within block-ack window
+	 * - h/w queue depth exceeds low water mark
+	 */
+	if (!list_empty(&tid->buf_q) || tid->paused ||
+	    !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+	    txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+		/*
+		 * Add this frame to software queue for scheduling later
+		 * for aggregation.
+		 */
+		list_move_tail(&bf->list, &tid->buf_q);
+		ath_tx_queue_tid(txctl->txq, tid);
+		return;
+	}
 
-	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-		if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
-		    (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
-			txtid->addba_exchangeattempts++;
+	/* Add sub-frame to BAW */
+	ath_tx_addto_baw(sc, tid, bf);
+
+	/* Queue to h/w without aggregation */
+	bf->bf_nframes = 1;
+	bf->bf_lastbf = bf;
+	ath_buf_set_rate(sc, bf);
+	ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+}
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+				  struct ath_atx_tid *tid,
+				  struct list_head *bf_head)
+{
+	struct ath_buf *bf;
+
+	bf = list_first_entry(bf_head, struct ath_buf, list);
+	bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+	/* update starting sequence number for subsequent ADDBA request */
+	INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+	bf->bf_nframes = 1;
+	bf->bf_lastbf = bf;
+	ath_buf_set_rate(sc, bf);
+	ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+			       struct list_head *bf_head)
+{
+	struct ath_buf *bf;
+
+	bf = list_first_entry(bf_head, struct ath_buf, list);
+
+	bf->bf_lastbf = bf;
+	bf->bf_nframes = 1;
+	ath_buf_set_rate(sc, bf);
+	ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+	enum ath9k_pkt_type htype;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = hdr->frame_control;
+
+	if (ieee80211_is_beacon(fc))
+		htype = ATH9K_PKT_TYPE_BEACON;
+	else if (ieee80211_is_probe_resp(fc))
+		htype = ATH9K_PKT_TYPE_PROBE_RESP;
+	else if (ieee80211_is_atim(fc))
+		htype = ATH9K_PKT_TYPE_ATIM;
+	else if (ieee80211_is_pspoll(fc))
+		htype = ATH9K_PKT_TYPE_PSPOLL;
+	else
+		htype = ATH9K_PKT_TYPE_NORMAL;
+
+	return htype;
+}
+
+static bool is_pae(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = hdr->frame_control;
+
+	if (ieee80211_is_data(fc)) {
+		if (ieee80211_is_nullfunc(fc) ||
+		    /* Port Access Entity (IEEE 802.1X) */
+		    (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
 			return true;
 		}
 	}
@@ -2235,175 +1327,766 @@ bool ath_tx_aggr_check(struct ath_softc
 	return false;
 }
 
-/* Start TX aggregation */
+static int get_hw_crypto_keytype(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-		      u16 tid, u16 *ssn)
+	if (tx_info->control.hw_key) {
+		if (tx_info->control.hw_key->alg == ALG_WEP)
+			return ATH9K_KEY_TYPE_WEP;
+		else if (tx_info->control.hw_key->alg == ALG_TKIP)
+			return ATH9K_KEY_TYPE_TKIP;
+		else if (tx_info->control.hw_key->alg == ALG_CCMP)
+			return ATH9K_KEY_TYPE_AES;
+	}
+
+	return ATH9K_KEY_TYPE_CLEAR;
+}
+
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+				  struct ath_buf *bf)
 {
-	struct ath_atx_tid *txtid;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr;
 	struct ath_node *an;
+	struct ath_atx_tid *tid;
+	__le16 fc;
+	u8 *qc;
 
-	an = (struct ath_node *)sta->drv_priv;
+	if (!tx_info->control.sta)
+		return;
 
-	if (sc->sc_flags & SC_OP_TXAGGR) {
-		txtid = ATH_AN_2_TID(an, tid);
-		txtid->state |= AGGR_ADDBA_PROGRESS;
-		ath_tx_pause_tid(sc, txtid);
+	an = (struct ath_node *)tx_info->control.sta->drv_priv;
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = hdr->frame_control;
+
+	if (ieee80211_is_data_qos(fc)) {
+		qc = ieee80211_get_qos_ctl(hdr);
+		bf->bf_tidno = qc[0] & 0xf;
 	}
 
-	return 0;
+	/*
+	 * 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);
+	bf->bf_seqno = tid->seq_next;
+	INCR(tid->seq_next, IEEE80211_SEQ_MAX);
 }
 
-/* Stop tx aggregation */
-
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+			  struct ath_txq *txq)
 {
-	struct ath_node *an = (struct ath_node *)sta->drv_priv;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+	int flags = 0;
 
-	ath_tx_aggr_teardown(sc, an, tid);
-	return 0;
+	flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+	flags |= ATH9K_TXDESC_INTREQ;
+
+	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+		flags |= ATH9K_TXDESC_NOACK;
+
+	return flags;
 }
 
-/* Resume tx aggregation */
+/*
+ * rix - rate index
+ * pktlen - total bytes (delims + data + fcs + pads + pad delims)
+ * width  - 0 for 20 MHz, 1 for 40 MHz
+ * half_gi - to use 4us v/s 3.6 us for symbol time
+ */
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+			    int width, int half_gi, bool shortPreamble)
+{
+	struct ath_rate_table *rate_table = sc->cur_rate_table;
+	u32 nbits, nsymbits, duration, nsymbols;
+	u8 rc;
+	int streams, pktlen;
 
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+	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];
+	nsymbols = (nbits + nsymbits - 1) / nsymbits;
+
+	if (!half_gi)
+		duration = SYMBOL_TIME(nsymbols);
+	else
+		duration = SYMBOL_TIME_HALFGI(nsymbols);
+
+	/* addup duration for legacy/ht training and signal fields */
+	streams = HT_RC_2_STREAMS(rc);
+	duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
+	return duration;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
 {
-	struct ath_atx_tid *txtid;
-	struct ath_node *an;
+	struct ath_rate_table *rt = sc->cur_rate_table;
+	struct ath9k_11n_rate_series series[4];
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *tx_info;
+	struct ieee80211_tx_rate *rates;
+	struct ieee80211_hdr *hdr;
+	int i, flags = 0;
+	u8 rix = 0, ctsrate = 0;
+	bool is_pspoll;
 
-	an = (struct ath_node *)sta->drv_priv;
+	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
 
-	if (sc->sc_flags & SC_OP_TXAGGR) {
-		txtid = ATH_AN_2_TID(an, tid);
-		txtid->baw_size =
-			IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-		txtid->state |= AGGR_ADDBA_COMPLETE;
-		txtid->state &= ~AGGR_ADDBA_PROGRESS;
-		ath_tx_resume_tid(sc, txtid);
+	skb = (struct sk_buff *)bf->bf_mpdu;
+	tx_info = IEEE80211_SKB_CB(skb);
+	rates = tx_info->control.rates;
+	hdr = (struct ieee80211_hdr *)skb->data;
+	is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
+
+	/*
+	 * We check if Short Preamble is needed for the CTS rate by
+	 * checking the BSS's global flag.
+	 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+	 */
+	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;
+
+	/*
+	 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
+	 * Check the first rate in the series to decide whether RTS/CTS
+	 * or CTS-to-self has to be used.
+	 */
+	if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+		flags = ATH9K_TXDESC_CTSENA;
+	else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+		flags = ATH9K_TXDESC_RTSENA;
+
+	/* FIXME: Handle aggregation protection */
+	if (sc->config.ath_aggr_prot &&
+	    (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
+		flags = ATH9K_TXDESC_RTSENA;
 	}
+
+	/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+	if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+		flags &= ~(ATH9K_TXDESC_RTSENA);
+
+	for (i = 0; i < 4; i++) {
+		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;
+
+		if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+		if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+			series[i].RateFlags |= ATH9K_RATESERIES_2040;
+		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));
+	}
+
+	/* set dur_update_en for l-sig computation except for PS-Poll frames */
+	ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+				     bf->bf_lastbf->bf_desc,
+				     !is_pspoll, ctsrate,
+				     0, series, 4, flags);
+
+	if (sc->config.ath_aggr_prot && flags)
+		ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
 }
 
-/*
- * Performs transmit side cleanup when TID changes from aggregated to
- * unaggregated.
- * - Pause the TID and mark cleanup in progress
- * - Discard all retry frames from the s/w queue.
- */
+static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+				struct sk_buff *skb,
+				struct ath_tx_control *txctl)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	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;
 
-void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
+	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;
+	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+	fc = hdr->frame_control;
+
+	ATH_TXBUF_RESET(bf);
+
+	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+	if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+		bf->bf_state.bf_type |= BUF_HT;
+
+	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+	bf->bf_keytype = get_hw_crypto_keytype(skb);
+	if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+		bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+		bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+	} else {
+		bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+	}
+
+	if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+		assign_aggr_tid_seqno(skb, bf);
+
+	bf->bf_mpdu = skb;
+
+	bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
+					   skb->len, DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+		bf->bf_mpdu = NULL;
+		DPRINTF(sc, ATH_DBG_CONFIG,
+			"dma_mapping_error() on TX\n");
+		return -ENOMEM;
+	}
+
+	bf->bf_buf_addr = bf->bf_dmacontext;
+	return 0;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+			     struct ath_tx_control *txctl)
 {
-	struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
-	struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
-	struct ath_buf *bf;
+	struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+	struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ath_node *an = NULL;
 	struct list_head bf_head;
+	struct ath_desc *ds;
+	struct ath_atx_tid *tid;
+	struct ath_hw *ah = sc->sc_ah;
+	int frm_type;
+	__le16 fc;
+
+	frm_type = get_hw_packet_type(skb);
+	fc = hdr->frame_control;
+
 	INIT_LIST_HEAD(&bf_head);
+	list_add_tail(&bf->list, &bf_head);
 
-	if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */
-		return;
+	ds = bf->bf_desc;
+	ds->ds_link = 0;
+	ds->ds_data = bf->bf_buf_addr;
 
-	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-		txtid->addba_exchangeattempts = 0;
-		return;
-	}
+	ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+			       bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
 
-	/* TID must be paused first */
-	ath_tx_pause_tid(sc, txtid);
+	ath9k_hw_filltxdesc(ah, ds,
+			    skb->len,	/* segment length */
+			    true,	/* first segment */
+			    true,	/* last segment */
+			    ds);	/* first descriptor */
 
-	/* drop all software retried frames and mark this TID */
-	spin_lock_bh(&txq->axq_lock);
-	while (!list_empty(&txtid->buf_q)) {
-		bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
-		if (!bf_isretried(bf)) {
+	spin_lock_bh(&txctl->txq->axq_lock);
+
+	if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+	    tx_info->control.sta) {
+		an = (struct ath_node *)tx_info->control.sta->drv_priv;
+		tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+		if (!ieee80211_is_data_qos(fc)) {
+			ath_tx_send_normal(sc, txctl->txq, &bf_head);
+			goto tx_done;
+		}
+
+		if (ath_aggr_query(sc, an, bf->bf_tidno)) {
 			/*
-			 * NB: it's based on the assumption that
-			 * software retried frame will always stay
-			 * at the head of software queue.
+			 * Try aggregation if it's a unicast data frame
+			 * and the destination is HT capable.
 			 */
-			break;
+			ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
+		} else {
+			/*
+			 * Send this frame as regular when ADDBA
+			 * exchange is neither complete nor pending.
+			 */
+			ath_tx_send_ht_normal(sc, txctl->txq,
+					      tid, &bf_head);
 		}
-		list_cut_position(&bf_head,
-			&txtid->buf_q, &bf->bf_lastfrm->list);
-		ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+	} else {
+		ath_tx_send_normal(sc, txctl->txq, &bf_head);
+	}
 
-		/* complete this sub-frame */
-		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+tx_done:
+	spin_unlock_bh(&txctl->txq->axq_lock);
+}
+
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+		 struct ath_tx_control *txctl)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_buf *bf;
+	int r;
+
+	bf = ath_tx_get_buffer(sc);
+	if (!bf) {
+		DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+		return -1;
 	}
 
-	if (txtid->baw_head != txtid->baw_tail) {
-		spin_unlock_bh(&txq->axq_lock);
-		txtid->state |= AGGR_CLEANUP;
-	} else {
-		txtid->state &= ~AGGR_ADDBA_COMPLETE;
-		txtid->addba_exchangeattempts = 0;
+	r = ath_tx_setup_buffer(hw, bf, skb, txctl);
+	if (unlikely(r)) {
+		struct ath_txq *txq = txctl->txq;
+
+		DPRINTF(sc, 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
+		 * we will at least have to run TX completionon one buffer
+		 * 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));
+			txq->stopped = 1;
+		}
 		spin_unlock_bh(&txq->axq_lock);
-		ath_tx_flush_tid(sc, txtid);
+
+		spin_lock_bh(&sc->tx.txbuflock);
+		list_add_tail(&bf->list, &sc->tx.txbuf);
+		spin_unlock_bh(&sc->tx.txbuflock);
+
+		return r;
 	}
-}
 
-/*
- * Tx scheduling logic
- * NB: must be called with txq lock held
- */
+	ath_tx_start_dma(sc, bf, txctl);
 
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+	return 0;
+}
+
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-	struct ath_atx_ac *ac;
-	struct ath_atx_tid *tid;
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	int hdrlen, padsize;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ath_tx_control txctl;
 
-	/* nothing to schedule */
-	if (list_empty(&txq->axq_acq))
-		return;
-	/*
-	 * get the first node/ac pair on the queue
-	 */
-	ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
-	list_del(&ac->list);
-	ac->sched = false;
+	memset(&txctl, 0, sizeof(struct ath_tx_control));
 
 	/*
-	 * process a single tid per destination
+	 * As a temporary workaround, assign seq# here; this will likely need
+	 * to be cleaned up to work better with Beacon transmission and virtual
+	 * BSSes.
 	 */
-	do {
-		/* nothing to schedule */
-		if (list_empty(&ac->tid_q))
+	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);
+		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+	}
+
+	/* 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;
+		if (skb_headroom(skb) < padsize) {
+			DPRINTF(sc, 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);
+	}
 
-		tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
-		list_del(&tid->list);
-		tid->sched = false;
+	txctl.txq = sc->beacon.cabq;
 
-		if (tid->paused)    /* check next tid to keep h/w busy */
-			continue;
+	DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
 
-		if ((txq->axq_depth % 2) == 0)
-			ath_tx_sched_aggr(sc, txq, tid);
+	if (ath_tx_start(hw, skb, &txctl) != 0) {
+		DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+		goto exit;
+	}
+
+	return;
+exit:
+	dev_kfree_skb_any(skb);
+}
 
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
+			    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);
+
+	if (tx_info_priv) {
+		hw = tx_info_priv->aphy->hw;
+		frame_type = tx_info_priv->frame_type;
+	}
+
+	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 (tx_flags & ATH_TX_BAR)
+		tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+	if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
+		/* Frame was ACKed */
+		tx_info->flags |= IEEE80211_TX_STAT_ACK;
+	}
+
+	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+	padsize = hdrlen & 3;
+	if (padsize && hdrlen >= 24) {
 		/*
-		 * add tid to round-robin queue if more frames
-		 * are pending for the tid
+		 * Remove MAC header padding before giving the frame back to
+		 * mac80211.
 		 */
-		if (!list_empty(&tid->buf_q))
-			ath_tx_queue_tid(txq, tid);
+		memmove(skb->data + padsize, skb->data, hdrlen);
+		skb_pull(skb, padsize);
+	}
 
-		/* only schedule one TID at a time */
-		break;
-	} while (!list_empty(&ac->tid_q));
+	if (frame_type == ATH9K_NOT_INTERNAL)
+		ieee80211_tx_status(hw, skb);
+	else
+		ath9k_tx_status(hw, skb);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+				struct list_head *bf_q,
+				int txok, int sendbar)
+{
+	struct sk_buff *skb = bf->bf_mpdu;
+	unsigned long flags;
+	int tx_flags = 0;
+
+
+	if (sendbar)
+		tx_flags = ATH_TX_BAR;
+
+	if (!txok) {
+		tx_flags |= ATH_TX_ERROR;
+
+		if (bf_isxretried(bf))
+			tx_flags |= ATH_TX_XRETRY;
+	}
+
+	dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+	ath_tx_complete(sc, skb, tx_flags);
 
 	/*
-	 * schedule AC if more TIDs need processing
+	 * Return the list of ath_buf of this mpdu to free queue
 	 */
-	if (!list_empty(&ac->tid_q)) {
+	spin_lock_irqsave(&sc->tx.txbuflock, flags);
+	list_splice_tail_init(bf_q, &sc->tx.txbuf);
+	spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
+}
+
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+			      int txok)
+{
+	struct ath_buf *bf_last = bf->bf_lastbf;
+	struct ath_desc *ds = bf_last->bf_desc;
+	u16 seq_st = 0;
+	u32 ba[WME_BA_BMP_SIZE >> 5];
+	int ba_index;
+	int nbad = 0;
+	int isaggr = 0;
+
+	if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+		return 0;
+
+	isaggr = bf_isaggr(bf);
+	if (isaggr) {
+		seq_st = ATH_DS_BA_SEQ(ds);
+		memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
+	}
+
+	while (bf) {
+		ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
+		if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+			nbad++;
+
+		bf = bf->bf_next;
+	}
+
+	return nbad;
+}
+
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+			     int nbad, int txok, bool update_rc)
+{
+	struct sk_buff *skb = (struct sk_buff *)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;
+	u8 i, tx_rateindex;
+
+	if (txok)
+		tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
+
+	tx_rateindex = ds->ds_txstat.ts_rateindex;
+	WARN_ON(tx_rateindex >= hw->max_rates);
+
+	tx_info_priv->update_rc = 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;
+		}
+	}
+
+	for (i = tx_rateindex + 1; i < hw->max_rates; i++)
+		tx_info->status.rates[i].count = 0;
+
+	tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
+}
+
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+	int qnum;
+
+	spin_lock_bh(&txq->axq_lock);
+	if (txq->stopped &&
+	    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);
+			txq->stopped = 0;
+		}
+	}
+	spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+	struct ath_hw *ah = sc->sc_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);
+
+	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;
+		}
+		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
 		/*
-		 * add dest ac to txq if not already added
+		 * There is a race condition that a BH gets scheduled
+		 * after sw writes TxE and before hw re-load the last
+		 * descriptor to get the newly chained one.
+		 * Software must keep the last DONE descriptor as a
+		 * holding descriptor - software does so by marking
+		 * it with the STALE flag.
 		 */
-		if (!ac->sched) {
-			ac->sched = true;
-			list_add_tail(&ac->list, &txq->axq_acq);
+		bf_held = NULL;
+		if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+			bf_held = bf;
+			if (list_is_last(&bf_held->list, &txq->axq_q)) {
+				txq->axq_link = NULL;
+				txq->axq_linkbuf = NULL;
+				spin_unlock_bh(&txq->axq_lock);
+
+				/*
+				 * The holding descriptor is the last
+				 * descriptor in queue. It's safe to remove
+				 * the last holding descriptor in BH context.
+				 */
+				spin_lock_bh(&sc->tx.txbuflock);
+				list_move_tail(&bf_held->list, &sc->tx.txbuf);
+				spin_unlock_bh(&sc->tx.txbuflock);
+
+				break;
+			} else {
+				bf = list_entry(bf_held->list.next,
+						struct ath_buf, list);
+			}
 		}
+
+		lastbf = bf->bf_lastbf;
+		ds = lastbf->bf_desc;
+
+		status = ath9k_hw_txprocdesc(ah, ds);
+		if (status == -EINPROGRESS) {
+			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;
+
+		/*
+		 * Remove ath_buf's of the same transmit unit from txq,
+		 * however leave the last descriptor back as the holding
+		 * descriptor for hw.
+		 */
+		lastbf->bf_status |= ATH_BUFSTATUS_STALE;
+		INIT_LIST_HEAD(&bf_head);
+		if (!list_is_singular(&lastbf->list))
+			list_cut_position(&bf_head,
+				&txq->axq_q, lastbf->list.prev);
+
+		txq->axq_depth--;
+		if (bf_isaggr(bf))
+			txq->axq_aggr_depth--;
+
+		txok = (ds->ds_txstat.ts_status == 0);
+		spin_unlock_bh(&txq->axq_lock);
+
+		if (bf_held) {
+			spin_lock_bh(&sc->tx.txbuflock);
+			list_move_tail(&bf_held->list, &sc->tx.txbuf);
+			spin_unlock_bh(&sc->tx.txbuflock);
+		}
+
+		if (!bf_isampdu(bf)) {
+			/*
+			 * This frame is sent out as a single frame.
+			 * Use hardware retry status for this frame.
+			 */
+			bf->bf_retries = ds->ds_txstat.ts_longretry;
+			if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
+				bf->bf_state.bf_type |= BUF_XRETRY;
+			ath_tx_rc_status(bf, ds, 0, txok, true);
+		}
+
+		if (bf_isampdu(bf))
+			ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
+		else
+			ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+
+		ath_wake_mac80211_queue(sc, txq);
+
+		spin_lock_bh(&txq->axq_lock);
+		if (sc->sc_flags & SC_OP_TXAGGR)
+			ath_txq_schedule(sc, txq);
+		spin_unlock_bh(&txq->axq_lock);
 	}
 }
 
-/* Initialize per-node transmit state */
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+	int i;
+	u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+	ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+			ath_tx_processq(sc, &sc->tx.txq[i]);
+	}
+}
+
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+	int error = 0;
+
+	do {
+		spin_lock_init(&sc->tx.txbuflock);
+
+		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);
+			break;
+		}
+
+		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);
+			break;
+		}
+
+	} while (0);
+
+	if (error != 0)
+		ath_tx_cleanup(sc);
+
+	return error;
+}
+
+int ath_tx_cleanup(struct ath_softc *sc)
+{
+	if (sc->beacon.bdma.dd_desc_len != 0)
+		ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
+
+	if (sc->tx.txdma.dd_desc_len != 0)
+		ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+	return 0;
+}
 
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 {
@@ -2411,9 +2094,6 @@ void ath_tx_node_init(struct ath_softc *
 	struct ath_atx_ac *ac;
 	int tidno, acno;
 
-	/*
-	 * Init per tid tx state
-	 */
 	for (tidno = 0, tid = &an->tid[tidno];
 	     tidno < WME_NUM_TID;
 	     tidno++, tid++) {
@@ -2423,22 +2103,16 @@ void ath_tx_node_init(struct ath_softc *
 		tid->baw_size  = WME_MAX_BA;
 		tid->baw_head  = tid->baw_tail = 0;
 		tid->sched     = false;
-		tid->paused = false;
+		tid->paused    = false;
 		tid->state &= ~AGGR_CLEANUP;
 		INIT_LIST_HEAD(&tid->buf_q);
-
 		acno = TID_TO_WME_AC(tidno);
 		tid->ac = &an->ac[acno];
-
-		/* ADDBA state */
 		tid->state &= ~AGGR_ADDBA_COMPLETE;
 		tid->state &= ~AGGR_ADDBA_PROGRESS;
 		tid->addba_exchangeattempts = 0;
 	}
 
-	/*
-	 * Init per ac tx state
-	 */
 	for (acno = 0, ac = &an->ac[acno];
 	     acno < WME_NUM_AC; acno++, ac++) {
 		ac->sched    = false;
@@ -2465,14 +2139,13 @@ void ath_tx_node_init(struct ath_softc *
 	}
 }
 
-/* Cleanupthe pending buffers for the node. */
-
 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 {
 	int i;
 	struct ath_atx_ac *ac, *ac_tmp;
 	struct ath_atx_tid *tid, *tid_tmp;
 	struct ath_txq *txq;
+
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
 		if (ATH_TXQ_SETUP(sc, i)) {
 			txq = &sc->tx.txq[i];
@@ -2503,51 +2176,3 @@ void ath_tx_node_cleanup(struct ath_soft
 		}
 	}
 }
-
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
-{
-	int hdrlen, padsize;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ath_tx_control txctl;
-
-	memset(&txctl, 0, sizeof(struct ath_tx_control));
-
-	/*
-	 * As a temporary workaround, assign seq# here; this will likely need
-	 * to be cleaned up to work better with Beacon transmission and virtual
-	 * 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);
-		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-	}
-
-	/* 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;
-		if (skb_headroom(skb) < padsize) {
-			DPRINTF(sc, 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);
-	}
-
-	txctl.txq = sc->beacon.cabq;
-
-	DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
-	if (ath_tx_start(sc, skb, &txctl) != 0) {
-		DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
-		goto exit;
-	}
-
-	return;
-exit:
-	dev_kfree_skb_any(skb);
-}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/atmel.c linux-libre-2.6.30-gnu1/drivers/net/wireless/atmel.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/atmel.c	2013-05-03 18:04:00.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/atmel.c	2013-05-03 16:47:50.000000000 -0400
@@ -2,8 +2,8 @@
 
      Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
 
-        Copyright 2000-2001 ATMEL Corporation.
-        Copyright 2003-2004 Simon Kelley.
+	Copyright 2000-2001 ATMEL Corporation.
+	Copyright 2003-2004 Simon Kelley.
 
     This code was developed from version 2.1.1 of the Atmel drivers,
     released by Atmel corp. under the GPL in December 2002. It also
@@ -89,15 +89,15 @@ static struct {
 	const char *fw_file;
 	const char *fw_file_ext;
 } fw_table[] = {
-	{ ATMEL_FW_TYPE_502,      "/*(DEBLOBBED)*/",      "bin" },
-	{ ATMEL_FW_TYPE_502D,     "/*(DEBLOBBED)*/",     "bin" },
-	{ ATMEL_FW_TYPE_502E,     "/*(DEBLOBBED)*/",     "bin" },
-	{ ATMEL_FW_TYPE_502_3COM, "/*(DEBLOBBED)*/", "bin" },
-	{ ATMEL_FW_TYPE_504,      "/*(DEBLOBBED)*/",      "bin" },
-	{ ATMEL_FW_TYPE_504_2958, "/*(DEBLOBBED)*/", "bin" },
-	{ ATMEL_FW_TYPE_504A_2958,"/*(DEBLOBBED)*/","bin" },
-	{ ATMEL_FW_TYPE_506,      "/*(DEBLOBBED)*/",      "bin" },
-	{ ATMEL_FW_TYPE_NONE,      NULL,                  NULL }
+	{ ATMEL_FW_TYPE_502,		"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_502D,		"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_502E,		"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_502_3COM,	"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_504,		"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_504_2958,	"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_504A_2958,	"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_506,		"/*(DEBLOBBED)*/",	"bin" },
+	{ ATMEL_FW_TYPE_NONE,		NULL,			NULL }
 };
 
 #define MAX_SSID_LENGTH 32
@@ -106,60 +106,60 @@ static struct {
 #define MAX_BSS_ENTRIES	64
 
 /* registers */
-#define GCR  0x00    //      (SIR0)  General Configuration Register
-#define BSR  0x02    //      (SIR1)  Bank Switching Select Register
+#define GCR  0x00    /* (SIR0)  General Configuration Register */
+#define BSR  0x02    /* (SIR1)  Bank Switching Select Register */
 #define AR   0x04
 #define DR   0x08
-#define MR1  0x12    //      Mirror Register 1
-#define MR2  0x14    //      Mirror Register 2
-#define MR3  0x16    //      Mirror Register 3
-#define MR4  0x18    //      Mirror Register 4
+#define MR1  0x12    /* Mirror Register 1 */
+#define MR2  0x14    /* Mirror Register 2 */
+#define MR3  0x16    /* Mirror Register 3 */
+#define MR4  0x18    /* Mirror Register 4 */
 
 #define GPR1                            0x0c
 #define GPR2                            0x0e
 #define GPR3                            0x10
-//
-// Constants for the GCR register.
-//
-#define GCR_REMAP     0x0400          // Remap internal SRAM to 0
-#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset)
-#define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT     0x0002          // Enable Interrupts
-#define GCR_ACKINT    0x0008          // Acknowledge Interrupts
+/*
+ * Constants for the GCR register.
+ */
+#define GCR_REMAP     0x0400          /* Remap internal SRAM to 0 */
+#define GCR_SWRES     0x0080          /* BIU reset (ARM and PAI are NOT reset) */
+#define GCR_CORES     0x0060          /* Core Reset (ARM and PAI are reset) */
+#define GCR_ENINT     0x0002          /* Enable Interrupts */
+#define GCR_ACKINT    0x0008          /* Acknowledge Interrupts */
 
-#define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
-#define BSS_IRAM      0x0100          // AMBA module selection --> IRAM
-//
-// Constants for the MR registers.
-//
-#define MAC_INIT_COMPLETE       0x0001        // MAC init has been completed
-#define MAC_BOOT_COMPLETE       0x0010        // MAC boot has been completed
-#define MAC_INIT_OK             0x0002        // MAC boot has been completed
+#define BSS_SRAM      0x0200          /* AMBA module selection --> SRAM */
+#define BSS_IRAM      0x0100          /* AMBA module selection --> IRAM */
+/*
+ *Constants for the MR registers.
+ */
+#define MAC_INIT_COMPLETE       0x0001        /* MAC init has been completed */
+#define MAC_BOOT_COMPLETE       0x0010        /* MAC boot has been completed */
+#define MAC_INIT_OK             0x0002        /* MAC boot has been completed */
 
 #define MIB_MAX_DATA_BYTES    212
 #define MIB_HEADER_SIZE       4    /* first four fields */
 
 struct get_set_mib {
-        u8 type;
-        u8 size;
-        u8 index;
-        u8 reserved;
-        u8 data[MIB_MAX_DATA_BYTES];
+	u8 type;
+	u8 size;
+	u8 index;
+	u8 reserved;
+	u8 data[MIB_MAX_DATA_BYTES];
 };
 
 struct rx_desc {
-        u32          Next;
-        u16          MsduPos;
-        u16          MsduSize;
+	u32          Next;
+	u16          MsduPos;
+	u16          MsduSize;
 
-        u8           State;
-        u8           Status;
-        u8           Rate;
-        u8           Rssi;
-        u8           LinkQuality;
-        u8           PreambleType;
-        u16          Duration;
-        u32          RxTime;
+	u8           State;
+	u8           Status;
+	u8           Rate;
+	u8           Rssi;
+	u8           LinkQuality;
+	u8           PreambleType;
+	u16          Duration;
+	u32          RxTime;
 };
 
 #define RX_DESC_FLAG_VALID       0x80
@@ -192,7 +192,7 @@ struct tx_desc {
 	u8        KeyIndex;
 	u8        ChiperType;
 	u8        ChipreLength;
-        u8        Reserved1;
+	u8        Reserved1;
 
 	u8        Reserved;
 	u8        PacketType;
@@ -212,9 +212,9 @@ struct tx_desc {
 #define TX_DESC_PACKET_TYPE_OFFSET   17
 #define TX_DESC_HOST_LENGTH_OFFSET   18
 
-///////////////////////////////////////////////////////
-// Host-MAC interface
-///////////////////////////////////////////////////////
+/*
+ * Host-MAC interface
+ */
 
 #define TX_STATUS_SUCCESS       0x00
 
@@ -226,14 +226,14 @@ struct tx_desc {
 #define TX_PACKET_TYPE_DATA     0x01
 #define TX_PACKET_TYPE_MGMT     0x02
 
-#define ISR_EMPTY               0x00        // no bits set in ISR
-#define ISR_TxCOMPLETE          0x01        // packet transmitted
-#define ISR_RxCOMPLETE          0x02        // packet received
-#define ISR_RxFRAMELOST         0x04        // Rx Frame lost
-#define ISR_FATAL_ERROR         0x08        // Fatal error
-#define ISR_COMMAND_COMPLETE    0x10        // command completed
-#define ISR_OUT_OF_RANGE        0x20        // command completed
-#define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
+#define ISR_EMPTY               0x00        /* no bits set in ISR */
+#define ISR_TxCOMPLETE          0x01        /* packet transmitted */
+#define ISR_RxCOMPLETE          0x02        /* packet received */
+#define ISR_RxFRAMELOST         0x04        /* Rx Frame lost */
+#define ISR_FATAL_ERROR         0x08        /* Fatal error */
+#define ISR_COMMAND_COMPLETE    0x10        /* command completed */
+#define ISR_OUT_OF_RANGE        0x20        /* command completed */
+#define ISR_IBSS_MERGE          0x40        /* (4.1.2.30): IBSS merge */
 #define ISR_GENERIC_IRQ         0x80
 
 #define Local_Mib_Type          0x01
@@ -311,22 +311,22 @@ struct tx_desc {
 #define MAX_ENCRYPTION_KEYS 4
 #define MAX_ENCRYPTION_KEY_SIZE 40
 
-///////////////////////////////////////////////////////////////////////////
-// 802.11 related definitions
-///////////////////////////////////////////////////////////////////////////
+/*
+ * 802.11 related definitions
+ */
 
-//
-// Regulatory Domains
-//
+/*
+ * Regulatory Domains
+ */
 
-#define REG_DOMAIN_FCC		0x10	//Channels	1-11	USA
-#define REG_DOMAIN_DOC		0x20	//Channel	1-11	Canada
-#define REG_DOMAIN_ETSI		0x30	//Channel	1-13	Europe (ex Spain/France)
-#define REG_DOMAIN_SPAIN	0x31	//Channel	10-11	Spain
-#define REG_DOMAIN_FRANCE	0x32	//Channel	10-13	France
-#define REG_DOMAIN_MKK		0x40	//Channel	14	Japan
-#define REG_DOMAIN_MKK1		0x41	//Channel	1-14	Japan(MKK1)
-#define REG_DOMAIN_ISRAEL	0x50	//Channel	3-9	ISRAEL
+#define REG_DOMAIN_FCC		0x10	/* Channels	1-11	USA				*/
+#define REG_DOMAIN_DOC		0x20	/* Channel	1-11	Canada				*/
+#define REG_DOMAIN_ETSI		0x30	/* Channel	1-13	Europe (ex Spain/France)	*/
+#define REG_DOMAIN_SPAIN	0x31	/* Channel	10-11	Spain				*/
+#define REG_DOMAIN_FRANCE	0x32	/* Channel	10-13	France				*/
+#define REG_DOMAIN_MKK		0x40	/* Channel	14	Japan				*/
+#define REG_DOMAIN_MKK1		0x41	/* Channel	1-14	Japan(MKK1)			*/
+#define REG_DOMAIN_ISRAEL	0x50	/* Channel	3-9	ISRAEL				*/
 
 #define BSS_TYPE_AD_HOC		1
 #define BSS_TYPE_INFRASTRUCTURE 2
@@ -364,13 +364,13 @@ struct tx_desc {
 #define CIPHER_SUITE_CCX      4
 #define CIPHER_SUITE_WEP_128  5
 
-//
-// IFACE MACROS & definitions
-//
-//
+/*
+ * IFACE MACROS & definitions
+ */
 
-// FuncCtrl field:
-//
+/*
+ * FuncCtrl field:
+ */
 #define FUNC_CTRL_TxENABLE		0x10
 #define FUNC_CTRL_RxENABLE		0x20
 #define FUNC_CTRL_INIT_COMPLETE		0x01
@@ -378,48 +378,48 @@ struct tx_desc {
 /* A stub firmware image which reads the MAC address from NVRAM on the card.
    For copyright information and source see the end of this file. */
 static u8 mac_reader[] = {
-	0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
-	0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
-	0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
-	0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
-	0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
-	0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
-	0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
-	0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
-	0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
-	0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
-	0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
-	0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
-	0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
-	0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
-	0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
-	0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
-	0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
-	0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
-	0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
-	0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
-	0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
-	0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
-	0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
-	0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
-	0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
-	0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
-	0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
-	0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
-	0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
-	0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
-	0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
-	0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
-	0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
-	0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
-	0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
-	0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
-	0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
-	0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
-	0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
-	0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
-	0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
-	0x00,0x01,0x00,0x02
+	0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
+	0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
+	0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+	0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
+	0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
+	0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
+	0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
+	0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
+	0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
+	0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
+	0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+	0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+	0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+	0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+	0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
+	0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
+	0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
+	0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
+	0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
+	0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
+	0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
+	0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
+	0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
+	0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+	0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+	0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
+	0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
+	0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
+	0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
+	0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
+	0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
+	0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
+	0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
+	0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
+	0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
+	0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
+	0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
+	0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
+	0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
+	0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
+	0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
+	0x00, 0x01, 0x00, 0x02
 };
 
 struct atmel_private {
@@ -433,7 +433,7 @@ struct atmel_private {
 	struct net_device *dev;
 	struct device *sys_dev;
 	struct iw_statistics wstats;
-	spinlock_t irqlock, timerlock;	// spinlocks
+	spinlock_t irqlock, timerlock;	/* spinlocks */
 	enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
 	enum {
 		CARD_TYPE_PARALLEL_FLASH,
@@ -541,7 +541,7 @@ struct atmel_private {
 	u8 rx_buf[MAX_WIRELESS_BODY];
 };
 
-static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
+static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
 
 static const struct {
 	int reg_domain;
@@ -1283,17 +1283,17 @@ static struct iw_statistics *atmel_get_w
 
 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
 {
-        if ((new_mtu < 68) || (new_mtu > 2312))
-                return -EINVAL;
-        dev->mtu = new_mtu;
-        return 0;
+	if ((new_mtu < 68) || (new_mtu > 2312))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
 }
 
 static int atmel_set_mac_address(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
 
-        memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
+	memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
 	return atmel_open(dev);
 }
 
@@ -1420,10 +1420,17 @@ static int atmel_proc_output (char *buf,
 				     priv->firmware_id);
 
 		switch (priv->card_type) {
-		case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
-		case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
-		case CARD_TYPE_EEPROM: c = "EEPROM"; break;
-		default: c = "<unknown>";
+		case CARD_TYPE_PARALLEL_FLASH:
+			c = "Parallel flash";
+			break;
+		case CARD_TYPE_SPI_FLASH:
+			c = "SPI flash\n";
+			break;
+		case CARD_TYPE_EEPROM:
+			c = "EEPROM";
+			break;
+		default:
+			c = "<unknown>";
 		}
 
 		r = "<unknown>";
@@ -1439,16 +1446,33 @@ static int atmel_proc_output (char *buf,
 			     priv->use_wpa ? "Yes" : "No");
 	}
 
-	switch(priv->station_state) {
-	case STATION_STATE_SCANNING: s = "Scanning"; break;
-	case STATION_STATE_JOINNING: s = "Joining"; break;
-	case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
-	case STATION_STATE_ASSOCIATING: s = "Associating"; break;
-	case STATION_STATE_READY: s = "Ready"; break;
-	case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
-	case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
-	case STATION_STATE_DOWN: s = "Down"; break;
-	default: s = "<unknown>";
+	switch (priv->station_state) {
+	case STATION_STATE_SCANNING:
+		s = "Scanning";
+		break;
+	case STATION_STATE_JOINNING:
+		s = "Joining";
+		break;
+	case STATION_STATE_AUTHENTICATING:
+		s = "Authenticating";
+		break;
+	case STATION_STATE_ASSOCIATING:
+		s = "Associating";
+		break;
+	case STATION_STATE_READY:
+		s = "Ready";
+		break;
+	case STATION_STATE_REASSOCIATING:
+		s = "Reassociating";
+		break;
+	case STATION_STATE_MGMT_ERROR:
+		s = "Management error";
+		break;
+	case STATION_STATE_DOWN:
+		s = "Down";
+		break;
+	default:
+		s = "<unknown>";
 	}
 
 	p += sprintf(p, "Current state:\t\t%s\n", s);
@@ -1458,16 +1482,29 @@ static int atmel_proc_output (char *buf,
 static int atmel_read_proc(char *page, char **start, off_t off,
 			   int count, int *eof, void *data)
 {
-        struct atmel_private *priv = data;
+	struct atmel_private *priv = data;
 	int len = atmel_proc_output (page, priv);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) 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 const struct net_device_ops atmel_netdev_ops = {
+	.ndo_open 		= atmel_open,
+	.ndo_stop		= atmel_close,
+	.ndo_change_mtu 	= atmel_change_mtu,
+	.ndo_set_mac_address 	= atmel_set_mac_address,
+	.ndo_start_xmit 	= start_tx,
+	.ndo_do_ioctl 		= atmel_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
 				   const AtmelFWType fw_type,
 				   struct device *sys_dev,
@@ -1479,11 +1516,11 @@ struct net_device *init_atmel_card(unsig
 	int rc;
 
 	/* Create the network device object. */
-        dev = alloc_etherdev(sizeof(*priv));
-        if (!dev) {
+	dev = alloc_etherdev(sizeof(*priv));
+	if (!dev) {
 		printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
 		return NULL;
-        }
+	}
 	if (dev_alloc_name(dev, dev->name) < 0) {
 		printk(KERN_ERR "atmel: Couldn't get name!\n");
 		goto err_out_free;
@@ -1552,13 +1589,8 @@ struct net_device *init_atmel_card(unsig
 	priv->management_timer.function = atmel_management_timer;
 	priv->management_timer.data = (unsigned long) dev;
 
-	dev->open = atmel_open;
-	dev->stop = atmel_close;
-	dev->change_mtu = atmel_change_mtu;
-	dev->set_mac_address = atmel_set_mac_address;
-	dev->hard_start_xmit = start_tx;
-	dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
-	dev->do_ioctl = atmel_ioctl;
+	dev->netdev_ops = &atmel_netdev_ops;
+	dev->wireless_handlers = &atmel_handler_def;
 	dev->irq = irq;
 	dev->base_addr = port;
 
@@ -1577,7 +1609,7 @@ struct net_device *init_atmel_card(unsig
 	if (register_netdev(dev))
 		goto err_out_res;
 
-	if (!probe_atmel_card(dev)){
+	if (!probe_atmel_card(dev)) {
 		unregister_netdev(dev);
 		goto err_out_res;
 	}
@@ -1594,7 +1626,7 @@ struct net_device *init_atmel_card(unsig
 	return dev;
 
 err_out_res:
-	release_region( dev->base_addr, 32);
+	release_region(dev->base_addr, 32);
 err_out_irq:
 	free_irq(dev->irq, dev);
 err_out_free:
@@ -1632,7 +1664,7 @@ static int atmel_set_essid(struct net_de
 	struct atmel_private *priv = netdev_priv(dev);
 
 	/* Check if we asked for `any' */
-	if(dwrq->flags == 0) {
+	if (dwrq->flags == 0) {
 		priv->connect_to_any_BSS = 1;
 	} else {
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1768,7 +1800,7 @@ static int atmel_set_encode(struct net_d
 	}
 	if (dwrq->flags & IW_ENCODE_RESTRICTED)
 		priv->exclude_unencrypted = 1;
-	if(dwrq->flags & IW_ENCODE_OPEN)
+	if (dwrq->flags & IW_ENCODE_OPEN)
 		priv->exclude_unencrypted = 0;
 
 	return -EINPROGRESS;		/* Call commit handler */
@@ -1797,7 +1829,7 @@ static int atmel_get_encode(struct net_d
 	/* Copy the key to the user buffer */
 	dwrq->length = priv->wep_key_len[index];
 	if (dwrq->length > 16) {
-		dwrq->length=0;
+		dwrq->length = 0;
 	} else {
 		memset(extra, 0, 16);
 		memcpy(extra, priv->wep_keys[index], dwrq->length);
@@ -2013,11 +2045,20 @@ static int atmel_set_rate(struct net_dev
 		} else {
 		/* Setting by frequency value */
 			switch (vwrq->value) {
-			case  1000000: priv->tx_rate = 0; break;
-			case  2000000: priv->tx_rate = 1; break;
-			case  5500000: priv->tx_rate = 2; break;
-			case 11000000: priv->tx_rate = 3; break;
-			default: return -EINVAL;
+			case  1000000:
+				priv->tx_rate = 0;
+				break;
+			case  2000000:
+				priv->tx_rate = 1;
+				break;
+			case  5500000:
+				priv->tx_rate = 2;
+				break;
+			case 11000000:
+				priv->tx_rate = 3;
+				break;
+			default:
+				return -EINVAL;
 			}
 		}
 	}
@@ -2062,11 +2103,19 @@ static int atmel_get_rate(struct net_dev
 		vwrq->value = 11000000;
 	} else {
 		vwrq->fixed = 1;
-		switch(priv->tx_rate) {
-		case 0: vwrq->value =  1000000; break;
-		case 1: vwrq->value =  2000000; break;
-		case 2: vwrq->value =  5500000; break;
-		case 3: vwrq->value = 11000000; break;
+		switch (priv->tx_rate) {
+		case 0:
+			vwrq->value =  1000000;
+			break;
+		case 1:
+			vwrq->value =  2000000;
+			break;
+		case 2:
+			vwrq->value =  5500000;
+			break;
+		case 3:
+			vwrq->value = 11000000;
+			break;
 		}
 	}
 	return 0;
@@ -2204,9 +2253,6 @@ static int atmel_get_frag(struct net_dev
 	return 0;
 }
 
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
-				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
 static int atmel_set_freq(struct net_device *dev,
 			  struct iw_request_info *info,
 			  struct iw_freq *fwrq,
@@ -2216,16 +2262,12 @@ static int atmel_set_freq(struct net_dev
 	int rc = -EINPROGRESS;		/* Call commit handler */
 
 	/* If setting by frequency, convert to a channel */
-	if ((fwrq->e == 1) &&
-	    (fwrq->m >= (int) 241200000) &&
-	    (fwrq->m <= (int) 248700000)) {
+	if (fwrq->e == 1) {
 		int f = fwrq->m / 100000;
-		int c = 0;
-		while ((c < 14) && (f != frequency_list[c]))
-			c++;
+
 		/* Hack to fall through... */
 		fwrq->e = 0;
-		fwrq->m = c + 1;
+		fwrq->m = ieee80211_freq_to_dsss_chan(f);
 	}
 	/* Setting by channel number */
 	if ((fwrq->m > 1000) || (fwrq->e > 0))
@@ -2384,8 +2426,11 @@ static int atmel_get_range(struct net_de
 	if (range->num_channels != 0) {
 		for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
 			range->freq[k].i = i; /* List index */
-			range->freq[k].m = frequency_list[i - 1] * 100000;
-			range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
+
+			/* Values in MHz -> * 10^5 * 10 */
+			range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
+					    100000);
+			range->freq[k++].e = 1;
 		}
 		range->num_frequency = k;
 	}
@@ -2580,8 +2625,7 @@ static const struct iw_priv_args atmel_p
 	},
 };
 
-static const struct iw_handler_def atmel_handler_def =
-{
+static const struct iw_handler_def atmel_handler_def = {
 	.num_standard	= ARRAY_SIZE(atmel_handler),
 	.num_private	= ARRAY_SIZE(atmel_private_handler),
 	.num_private_args = ARRAY_SIZE(atmel_private_args),
@@ -2838,7 +2882,7 @@ static void send_authentication_request(
 
 	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
 		/* no WEP for authentication frames with TrSeqNo 1 */
-                header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+		header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 
 	auth.alg = cpu_to_le16(system);
 
@@ -2973,7 +3017,7 @@ static void store_bss_info(struct atmel_
 		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
 			index = i;
 
-        /* If we process a probe and an entry from this BSS exists
+	/* If we process a probe and an entry from this BSS exists
 	   we will update the BSS entry with the info from this BSS.
 	   If we process a beacon we will only update RSSI */
 
@@ -2999,7 +3043,7 @@ static void store_bss_info(struct atmel_
 	if (capability & WLAN_CAPABILITY_IBSS)
 		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
 	else if (capability & WLAN_CAPABILITY_ESS)
-		priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
+		priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
 
 	priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
 		SHORT_PREAMBLE : LONG_PREAMBLE;
@@ -3046,7 +3090,7 @@ static void authenticate(struct atmel_pr
 		}
 
 		if (should_associate) {
-			if(priv->station_was_associated) {
+			if (priv->station_was_associated) {
 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
 				send_association_request(priv, 1);
 				return;
@@ -3067,8 +3111,8 @@ static void authenticate(struct atmel_pr
 			priv->exclude_unencrypted = 1;
 			send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
 			return;
-		} else if (   system == WLAN_AUTH_SHARED_KEY
-		           && priv->wep_is_on) {
+		} else if (system == WLAN_AUTH_SHARED_KEY
+			   && priv->wep_is_on) {
 			priv->CurrentAuthentTransactionSeqNum = 0x001;
 			priv->exclude_unencrypted = 0;
 			send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
@@ -3256,11 +3300,11 @@ static void smooth_rssi(struct atmel_pri
 	u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
 
 	switch (priv->firmware_type) {
-		case ATMEL_FW_TYPE_502E:
-			max_rssi = 63; /* 502-rmfd-reve max by experiment */
-			break;
-		default:
-			break;
+	case ATMEL_FW_TYPE_502E:
+		max_rssi = 63; /* 502-rmfd-reve max by experiment */
+		break;
+	default:
+		break;
 	}
 
 	rssi = rssi * 100 / max_rssi;
@@ -3477,8 +3521,7 @@ static void atmel_command_irq(struct atm
 	    status == CMD_STATUS_IN_PROGRESS)
 		return;
 
-	switch (command){
-
+	switch (command) {
 	case CMD_Start:
 		if (status == CMD_STATUS_COMPLETE) {
 			priv->station_was_associated = priv->station_is_associated;
@@ -3713,7 +3756,7 @@ static int probe_atmel_card(struct net_d
 
 	if (rc) {
 		if (dev->dev_addr[0] == 0xFF) {
-			u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
+			u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
 			printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
 			memcpy(dev->dev_addr, default_mac, 6);
 		}
@@ -3807,7 +3850,7 @@ static void build_wpa_mib(struct atmel_p
 				} else {
 					mib.group_key = i;
 					priv->group_cipher_suite = priv->pairwise_cipher_suite;
-				        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
+					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
 				}
 			}
@@ -3917,7 +3960,7 @@ static int reset_atmel_card(struct net_d
 			len = fw_entry->size;
 		}
 
-	        if (len <= 0x6000) {
+		if (len <= 0x6000) {
 			atmel_write16(priv->dev, BSR, BSS_IRAM);
 			atmel_copy_to_card(priv->dev, 0, fw, len);
 			atmel_set_gcr(priv->dev, GCR_REMAP);
@@ -3946,7 +3989,7 @@ static int reset_atmel_card(struct net_d
 	priv->use_wpa = (priv->host_info.major_version == 4);
 	priv->radio_on_broken = (priv->host_info.major_version == 5);
 
-        /* unmask all irq sources */
+	/* unmask all irq sources */
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
 
 	/* int Tx system and enable Tx */
@@ -3979,7 +4022,7 @@ static int reset_atmel_card(struct net_d
 		    CMD_STATUS_REJECTED_RADIO_OFF) {
 			printk(KERN_INFO "%s: cannot turn the radio on.\n",
 			       dev->name);
-                        return -EIO;
+			return -EIO;
 		}
 	}
 
@@ -4003,8 +4046,7 @@ static int reset_atmel_card(struct net_d
 	else
 		build_wep_mib(priv);
 
-	if (old_state == STATION_STATE_READY)
-	{
+	if (old_state == STATION_STATE_READY) {
 		union iwreq_data wrqu;
 
 		wrqu.data.length = 0;
@@ -4281,24 +4323,24 @@ static void atmel_wmem32(struct atmel_pr
 	.set NVRAM_LENGTH, 0x0200
 	.set MAC_ADDRESS_MIB, SRAM_BASE
 	.set MAC_ADDRESS_LENGTH, 6
-        .set MAC_BOOT_FLAG, 0x10
+	.set MAC_BOOT_FLAG, 0x10
 	.set MR1, 0
 	.set MR2, 4
 	.set MR3, 8
 	.set MR4, 0xC
 RESET_VECTOR:
-        b RESET_HANDLER
+	b RESET_HANDLER
 UNDEF_VECTOR:
-        b HALT1
+	b HALT1
 SWI_VECTOR:
-        b HALT1
+	b HALT1
 IABORT_VECTOR:
-        b HALT1
+	b HALT1
 DABORT_VECTOR:
 RESERVED_VECTOR:
-        b HALT1
+	b HALT1
 IRQ_VECTOR:
-        b HALT1
+	b HALT1
 FIQ_VECTOR:
 	b HALT1
 HALT1:	b HALT1
@@ -4310,7 +4352,7 @@ RESET_HANDLER:
 	ldr	r0, =SPI_CGEN_BASE
 	mov	r1, #0
 	mov	r1, r1, lsl #3
-	orr	r1,r1, #0
+	orr	r1, r1, #0
 	str	r1, [r0]
 	ldr	r1, [r0, #28]
 	bic	r1, r1, #16
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/b43.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/b43.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/b43.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/b43.h	2009-06-09 23:05:27.000000000 -0400
@@ -120,6 +120,9 @@
 #define B43_MMIO_IFSCTL			0x688 /* Interframe space control */
 #define  B43_MMIO_IFSCTL_USE_EDCF	0x0004
 #define B43_MMIO_POWERUP_DELAY		0x6A8
+#define B43_MMIO_BTCOEX_CTL		0x6B4 /* Bluetooth Coexistence Control */
+#define B43_MMIO_BTCOEX_STAT		0x6B6 /* Bluetooth Coexistence Status */
+#define B43_MMIO_BTCOEX_TXCTL		0x6B8 /* Bluetooth Coexistence Transmit Control */
 
 /* SPROM boardflags_lo values */
 #define B43_BFL_BTCOEXIST		0x0001	/* implements Bluetooth coexistance */
@@ -547,9 +550,6 @@ struct b43_noise_calculation {
 
 struct b43_stats {
 	u8 link_noise;
-	/* Store the last TX/RX times here for updating the leds. */
-	unsigned long last_tx;
-	unsigned long last_rx;
 };
 
 struct b43_key {
@@ -655,10 +655,39 @@ struct b43_wl {
 	struct work_struct txpower_adjust_work;
 };
 
+/* The type of the firmware file. */
+enum b43_firmware_file_type {
+	B43_FWTYPE_PROPRIETARY,
+	B43_FWTYPE_OPENSOURCE,
+	B43_NR_FWTYPES,
+};
+
+/* Context data for fetching firmware. */
+struct b43_request_fw_context {
+	/* The device we are requesting the fw for. */
+	struct b43_wldev *dev;
+	/* The type of firmware to request. */
+	enum b43_firmware_file_type req_type;
+	/* Error messages for each firmware type. */
+	char errors[B43_NR_FWTYPES][128];
+	/* Temporary buffer for storing the firmware name. */
+	char fwname[64];
+	/* A fatal error occured while requesting. Firmware reqest
+	 * can not continue, as any other reqest will also fail. */
+	int fatal_failure;
+};
+
 /* In-memory representation of a cached microcode file. */
 struct b43_firmware_file {
 	const char *filename;
 	const struct firmware *data;
+	/* Type of the firmware file name. Note that this does only indicate
+	 * the type by the firmware name. NOT the file contents.
+	 * If you want to check for proprietary vs opensource, use (struct b43_firmware)->opensource
+	 * instead! The (struct b43_firmware)->opensource flag is derived from the actual firmware
+	 * binary code, not just the filename.
+	 */
+	enum b43_firmware_file_type type;
 };
 
 /* Pointers to the firmware data and meta information about it. */
@@ -677,7 +706,8 @@ struct b43_firmware {
 	/* Firmware patchlevel */
 	u16 patch;
 
-	/* Set to true, if we are using an opensource firmware. */
+	/* Set to true, if we are using an opensource firmware.
+	 * Use this to check for proprietary vs opensource. */
 	bool opensource;
 	/* Set to true, if the core needs a PCM firmware, but
 	 * we failed to load one. This is always false for
@@ -848,12 +878,9 @@ void b43err(struct b43_wl *wl, const cha
     __attribute__ ((format(printf, 2, 3)));
 void b43warn(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
-#if B43_DEBUG
 void b43dbg(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
-#else /* DEBUG */
-# define b43dbg(wl, fmt...) do { /* nothing */ } while (0)
-#endif /* DEBUG */
+
 
 /* A WARN_ON variant that vanishes when b43 debugging is disabled.
  * This _also_ evaluates the arg with debugging disabled. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/debugfs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/debugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -51,8 +51,8 @@ struct b43_debugfs_fops {
 };
 
 static inline
-struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
-				       const struct b43_debugfs_fops *dfops)
+struct b43_dfs_file *fops_to_dfs_file(struct b43_wldev *dev,
+				      const struct b43_debugfs_fops *dfops)
 {
 	void *p;
 
@@ -367,34 +367,6 @@ static int mmio32write__write_file(struc
 	return 0;
 }
 
-/* wl->irq_lock is locked */
-static ssize_t tsf_read_file(struct b43_wldev *dev,
-			     char *buf, size_t bufsize)
-{
-	ssize_t count = 0;
-	u64 tsf;
-
-	b43_tsf_read(dev, &tsf);
-	fappend("0x%08x%08x\n",
-		(unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
-		(unsigned int)(tsf & 0xFFFFFFFFULL));
-
-	return count;
-}
-
-/* wl->irq_lock is locked */
-static int tsf_write_file(struct b43_wldev *dev,
-			  const char *buf, size_t count)
-{
-	u64 tsf;
-
-	if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
-		return -EINVAL;
-	b43_tsf_write(dev, tsf);
-
-	return 0;
-}
-
 static ssize_t txstat_read_file(struct b43_wldev *dev,
 				char *buf, size_t bufsize)
 {
@@ -691,15 +663,23 @@ B43_DEBUGFS_FOPS(mmio16read, mmio16read_
 B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
 B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
 B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
 B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
 B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
 B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
 
 
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
 {
-	return !!(dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+	bool enabled;
+
+	enabled = (dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+	if (unlikely(enabled)) {
+		/* Force full debugging messages, if the user enabled
+		 * some dynamic debugging feature. */
+		b43_modparam_verbose = B43_VERBOSITY_MAX;
+	}
+
+	return enabled;
 }
 
 static void b43_remove_dynamic_debug(struct b43_wldev *dev)
@@ -805,7 +785,6 @@ void b43_debugfs_add_device(struct b43_w
 	ADD_FILE(mmio16write, 0200);
 	ADD_FILE(mmio32read, 0600);
 	ADD_FILE(mmio32write, 0200);
-	ADD_FILE(tsf, 0600);
 	ADD_FILE(txstat, 0400);
 	ADD_FILE(restart, 0200);
 	ADD_FILE(loctls, 0400);
@@ -834,7 +813,6 @@ void b43_debugfs_remove_device(struct b4
 	debugfs_remove(e->file_mmio16write.dentry);
 	debugfs_remove(e->file_mmio32read.dentry);
 	debugfs_remove(e->file_mmio32write.dentry);
-	debugfs_remove(e->file_tsf.dentry);
 	debugfs_remove(e->file_txstat.dentry);
 	debugfs_remove(e->file_restart.dentry);
 	debugfs_remove(e->file_loctls.dentry);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/debugfs.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/debugfs.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/debugfs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/debugfs.h	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,6 @@ struct b43_dfsentry {
 	struct b43_dfs_file file_mmio16write;
 	struct b43_dfs_file file_mmio32read;
 	struct b43_dfs_file file_mmio32write;
-	struct b43_dfs_file file_tsf;
 	struct b43_dfs_file file_txstat;
 	struct b43_dfs_file file_txpower_g;
 	struct b43_dfs_file file_restart;
@@ -72,7 +71,7 @@ struct b43_dfsentry {
 	struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG];
 };
 
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
 
 void b43_debugfs_init(void);
 void b43_debugfs_exit(void);
@@ -83,7 +82,7 @@ void b43_debugfs_log_txstat(struct b43_w
 
 #else /* CONFIG_B43_DEBUG */
 
-static inline int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
 {
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/dma.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/dma.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,12 @@
 #include <asm/div64.h>
 
 
+/* Required number of TX DMA slots per TX frame.
+ * This currently is 2, because we put the header and the ieee80211 frame
+ * into separate slots. */
+#define TX_SLOTS_PER_FRAME	2
+
+
 /* 32bit DMA ops. */
 static
 struct b43_dmadesc_generic *op32_idx2desc(struct b43_dmaring *ring,
@@ -74,8 +80,7 @@ static void op32_fill_descriptor(struct
 	addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
 	    >> SSB_DMA_TRANSLATION_SHIFT;
 	addr |= ssb_dma_translation(ring->dev->dev);
-	ctl = (bufsize - ring->frameoffset)
-	    & B43_DMA32_DCTL_BYTECNT;
+	ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
 	if (slot == ring->nr_slots - 1)
 		ctl |= B43_DMA32_DCTL_DTABLEEND;
 	if (start)
@@ -177,8 +182,7 @@ static void op64_fill_descriptor(struct
 		ctl0 |= B43_DMA64_DCTL0_FRAMEEND;
 	if (irq)
 		ctl0 |= B43_DMA64_DCTL0_IRQ;
-	ctl1 |= (bufsize - ring->frameoffset)
-	    & B43_DMA64_DCTL1_BYTECNT;
+	ctl1 |= bufsize & B43_DMA64_DCTL1_BYTECNT;
 	ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT)
 	    & B43_DMA64_DCTL1_ADDREXT_MASK;
 
@@ -551,11 +555,32 @@ address_error:
 	return 1;
 }
 
+static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+	unsigned char *f = skb->data + ring->frameoffset;
+
+	return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF);
+}
+
+static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb)
+{
+	struct b43_rxhdr_fw4 *rxhdr;
+	unsigned char *frame;
+
+	/* This poisons the RX buffer to detect DMA failures. */
+
+	rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
+	rxhdr->frame_len = 0;
+
+	B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2);
+	frame = skb->data + ring->frameoffset;
+	memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */);
+}
+
 static int setup_rx_descbuffer(struct b43_dmaring *ring,
 			       struct b43_dmadesc_generic *desc,
 			       struct b43_dmadesc_meta *meta, gfp_t gfp_flags)
 {
-	struct b43_rxhdr_fw4 *rxhdr;
 	dma_addr_t dmaaddr;
 	struct sk_buff *skb;
 
@@ -564,6 +589,7 @@ static int setup_rx_descbuffer(struct b4
 	skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
 	if (unlikely(!skb))
 		return -ENOMEM;
+	b43_poison_rx_buffer(ring, skb);
 	dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
 	if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
 		/* ugh. try to realloc in zone_dma */
@@ -574,14 +600,14 @@ static int setup_rx_descbuffer(struct b4
 		skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
 		if (unlikely(!skb))
 			return -ENOMEM;
+		b43_poison_rx_buffer(ring, skb);
 		dmaaddr = map_descbuffer(ring, skb->data,
 					 ring->rx_buffersize, 0);
-	}
-
-	if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
-		b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
-		dev_kfree_skb_any(skb);
-		return -EIO;
+		if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
+			b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
+			dev_kfree_skb_any(skb);
+			return -EIO;
+		}
 	}
 
 	meta->skb = skb;
@@ -589,9 +615,6 @@ static int setup_rx_descbuffer(struct b4
 	ring->ops->fill_descriptor(ring, desc, dmaaddr,
 				   ring->rx_buffersize, 0, 0, 0);
 
-	rxhdr = (struct b43_rxhdr_fw4 *)(skb->data);
-	rxhdr->frame_len = 0;
-
 	return 0;
 }
 
@@ -769,23 +792,23 @@ static u64 supported_dma_mask(struct b43
 
 	tmp = b43_read32(dev, SSB_TMSHIGH);
 	if (tmp & SSB_TMSHIGH_DMA64)
-		return DMA_64BIT_MASK;
+		return DMA_BIT_MASK(64);
 	mmio_base = b43_dmacontroller_base(0, 0);
 	b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK);
 	tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL);
 	if (tmp & B43_DMA32_TXADDREXT_MASK)
-		return DMA_32BIT_MASK;
+		return DMA_BIT_MASK(32);
 
-	return DMA_30BIT_MASK;
+	return DMA_BIT_MASK(30);
 }
 
 static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
 {
-	if (dmamask == DMA_30BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(30))
 		return B43_DMA_30BIT;
-	if (dmamask == DMA_32BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(32))
 		return B43_DMA_32BIT;
-	if (dmamask == DMA_64BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(64))
 		return B43_DMA_64BIT;
 	B43_WARN_ON(1);
 	return B43_DMA_30BIT;
@@ -830,9 +853,6 @@ struct b43_dmaring *b43_setup_dmaring(st
 		if (ring->index == 0) {
 			ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE;
 			ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET;
-		} else if (ring->index == 3) {
-			ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE;
-			ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET;
 		} else
 			B43_WARN_ON(1);
 	}
@@ -842,7 +862,10 @@ struct b43_dmaring *b43_setup_dmaring(st
 #endif
 
 	if (for_tx) {
-		ring->txhdr_cache = kcalloc(ring->nr_slots,
+		/* Assumption: B43_TXRING_SLOTS can be divided by TX_SLOTS_PER_FRAME */
+		BUILD_BUG_ON(B43_TXRING_SLOTS % TX_SLOTS_PER_FRAME != 0);
+
+		ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
 					    b43_txhdr_size(dev),
 					    GFP_KERNEL);
 		if (!ring->txhdr_cache)
@@ -858,7 +881,7 @@ struct b43_dmaring *b43_setup_dmaring(st
 					  b43_txhdr_size(dev), 1)) {
 			/* ugh realloc */
 			kfree(ring->txhdr_cache);
-			ring->txhdr_cache = kcalloc(ring->nr_slots,
+			ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
 						    b43_txhdr_size(dev),
 						    GFP_KERNEL | GFP_DMA);
 			if (!ring->txhdr_cache)
@@ -996,13 +1019,13 @@ static int b43_dma_set_mask(struct b43_w
 		err = ssb_dma_set_mask(dev->dev, mask);
 		if (!err)
 			break;
-		if (mask == DMA_64BIT_MASK) {
-			mask = DMA_32BIT_MASK;
+		if (mask == DMA_BIT_MASK(64)) {
+			mask = DMA_BIT_MASK(32);
 			fallback = 1;
 			continue;
 		}
-		if (mask == DMA_32BIT_MASK) {
-			mask = DMA_30BIT_MASK;
+		if (mask == DMA_BIT_MASK(32)) {
+			mask = DMA_BIT_MASK(30);
 			fallback = 1;
 			continue;
 		}
@@ -1149,7 +1172,10 @@ static int dma_tx_fragment(struct b43_dm
 	u16 cookie;
 	size_t hdrsize = b43_txhdr_size(ring->dev);
 
-#define SLOTS_PER_PACKET  2
+	/* Important note: If the number of used DMA slots per TX frame
+	 * is changed here, the TX_SLOTS_PER_FRAME definition at the top of
+	 * the file has to be updated, too!
+	 */
 
 	old_top_slot = ring->current_slot;
 	old_used_slots = ring->used_slots;
@@ -1159,7 +1185,7 @@ static int dma_tx_fragment(struct b43_dm
 	desc = ops->idx2desc(ring, slot, &meta_hdr);
 	memset(meta_hdr, 0, sizeof(*meta_hdr));
 
-	header = &(ring->txhdr_cache[slot * hdrsize]);
+	header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
 	cookie = generate_cookie(ring, slot);
 	err = b43_generate_txhdr(ring->dev, header,
 				 skb->data, skb->len, info, cookie);
@@ -1254,8 +1280,8 @@ static inline int should_inject_overflow
 }
 
 /* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
-static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
-						    u8 queue_prio)
+static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
+						   u8 queue_prio)
 {
 	struct b43_dmaring *ring;
 
@@ -1306,17 +1332,19 @@ int b43_dma_tx(struct b43_wldev *dev, st
 	}
 
 	spin_lock_irqsave(&ring->lock, flags);
+
 	B43_WARN_ON(!ring->tx);
-	if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
-		b43warn(dev->wl, "DMA queue overflow\n");
-		err = -ENOSPC;
-		goto out_unlock;
-	}
 	/* Check if the queue was stopped in mac80211,
 	 * but we got called nevertheless.
 	 * That would be a mac80211 bug. */
 	B43_WARN_ON(ring->stopped);
 
+	if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) {
+		b43warn(dev->wl, "DMA queue overflow\n");
+		err = -ENOSPC;
+		goto out_unlock;
+	}
+
 	/* Assign the queue number to the ring (if not already done before)
 	 * so TX status handling can use it. The queue to ring mapping is
 	 * static, so we don't need to store it per frame. */
@@ -1335,7 +1363,7 @@ int b43_dma_tx(struct b43_wldev *dev, st
 		goto out_unlock;
 	}
 	ring->nr_tx_packets++;
-	if ((free_slots(ring) < SLOTS_PER_PACKET) ||
+	if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
 	    should_inject_overflow(ring)) {
 		/* This TX ring is full. */
 		ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
@@ -1417,9 +1445,8 @@ void b43_dma_handle_txstatus(struct b43_
 			break;
 		slot = next_slot(ring, slot);
 	}
-	dev->stats.last_tx = jiffies;
 	if (ring->stopped) {
-		B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
+		B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
 		ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
 		ring->stopped = 0;
 		if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
@@ -1442,8 +1469,8 @@ void b43_dma_get_tx_stats(struct b43_wld
 		ring = select_ring_by_priority(dev, i);
 
 		spin_lock_irqsave(&ring->lock, flags);
-		stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
-		stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+		stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
+		stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
 		stats[i].count = ring->nr_tx_packets;
 		spin_unlock_irqrestore(&ring->lock, flags);
 	}
@@ -1476,12 +1503,17 @@ static void dma_rx(struct b43_dmaring *r
 			len = le16_to_cpu(rxhdr->frame_len);
 		} while (len == 0 && i++ < 5);
 		if (unlikely(len == 0)) {
-			/* recycle the descriptor buffer. */
-			sync_descbuffer_for_device(ring, meta->dmaaddr,
-						   ring->rx_buffersize);
-			goto drop;
+			dmaaddr = meta->dmaaddr;
+			goto drop_recycle_buffer;
 		}
 	}
+	if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) {
+		/* Something went wrong with the DMA.
+		 * The device did not touch the buffer and did not overwrite the poison. */
+		b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n");
+		dmaaddr = meta->dmaaddr;
+		goto drop_recycle_buffer;
+	}
 	if (unlikely(len > ring->rx_buffersize)) {
 		/* The data did not fit into one descriptor buffer
 		 * and is split over multiple buffers.
@@ -1494,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *r
 		while (1) {
 			desc = ops->idx2desc(ring, *slot, &meta);
 			/* recycle the descriptor buffer. */
+			b43_poison_rx_buffer(ring, meta->skb);
 			sync_descbuffer_for_device(ring, meta->dmaaddr,
 						   ring->rx_buffersize);
 			*slot = next_slot(ring, *slot);
@@ -1512,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *r
 	err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
 	if (unlikely(err)) {
 		b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
-		sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
-		goto drop;
+		goto drop_recycle_buffer;
 	}
 
 	unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
@@ -1523,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *r
 	b43_rx(ring->dev, skb, rxhdr);
 drop:
 	return;
+
+drop_recycle_buffer:
+	/* Poison and recycle the RX buffer. */
+	b43_poison_rx_buffer(ring, skb);
+	sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
 }
 
 void b43_dma_rx(struct b43_dmaring *ring)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/dma.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/dma.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/dma.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/dma.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,14 +1,12 @@
 #ifndef B43_DMA_H_
 #define B43_DMA_H_
 
-#include <linux/list.h>
+#include <linux/ieee80211.h>
 #include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/linkage.h>
-#include <asm/atomic.h>
 
 #include "b43.h"
 
+
 /* DMA-Interrupt reasons. */
 #define B43_DMAIRQ_FATALMASK	((1 << 10) | (1 << 11) | (1 << 12) \
 					 | (1 << 14) | (1 << 15))
@@ -161,14 +159,13 @@ struct b43_dmadesc_generic {
 
 /* Misc DMA constants */
 #define B43_DMA_RINGMEMSIZE		PAGE_SIZE
-#define B43_DMA0_RX_FRAMEOFFSET	30
-#define B43_DMA3_RX_FRAMEOFFSET	0
+#define B43_DMA0_RX_FRAMEOFFSET		30
 
 /* DMA engine tuning knobs */
-#define B43_TXRING_SLOTS		128
+#define B43_TXRING_SLOTS		256
 #define B43_RXRING_SLOTS		64
-#define B43_DMA0_RX_BUFFERSIZE	(2304 + 100)
-#define B43_DMA3_RX_BUFFERSIZE	16
+#define B43_DMA0_RX_BUFFERSIZE		IEEE80211_MAX_FRAME_LEN
+
 
 struct sk_buff;
 struct b43_private;
@@ -215,7 +212,7 @@ struct b43_dmaring {
 	void *descbase;
 	/* Meta data about all descriptors. */
 	struct b43_dmadesc_meta *meta;
-	/* Cache of TX headers for each slot.
+	/* Cache of TX headers for each TX frame.
 	 * This is to avoid an allocation on each TX.
 	 * This is NULL for an RX ring.
 	 */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -110,10 +110,18 @@ config B43_DEBUG
 	bool "Broadcom 43xx debugging"
 	depends on B43
 	---help---
-	  Broadcom 43xx debugging messages.
+	  Broadcom 43xx debugging.
 
-	  Say Y, if you want to find out why the driver does not
-	  work for you.
+	  This adds additional runtime sanity checks and statistics to the driver.
+	  These checks and statistics might me expensive and hurt runtime performance
+	  of your system.
+	  This also adds the b43 debugfs interface.
+
+	  Do not enable this, unless you are debugging the driver.
+
+	  Say N, if you are a distributor or user building a release kernel
+	  for production use.
+	  Only say Y, if you are debugging a problem in the b43 driver sourcecode.
 
 config B43_FORCE_PIO
 	bool "Force usage of PIO instead of DMA"
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/lo.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/lo.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/lo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/lo.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,8 +36,8 @@
 #include <linux/sched.h>
 
 
-static struct b43_lo_calib * b43_find_lo_calib(struct b43_txpower_lo_control *lo,
-					       const struct b43_bbatt *bbatt,
+static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
+					      const struct b43_bbatt *bbatt,
 					       const struct b43_rfatt *rfatt)
 {
 	struct b43_lo_calib *c;
@@ -138,7 +138,7 @@ static u16 lo_measure_feedthrough(struct
  * "pad_mix_gain" is the PAD Mixer Gain.
  */
 static u16 lo_txctl_register_table(struct b43_wldev *dev,
-				   u16 * value, u16 * pad_mix_gain)
+				   u16 *value, u16 *pad_mix_gain)
 {
 	struct b43_phy *phy = &dev->phy;
 	u16 reg, v, padmix;
@@ -225,14 +225,12 @@ static void lo_measure_txctl_values(stru
 				radio_pctl_reg = tmp;
 		}
 	}
-	b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
-				      & 0xFFF0) | radio_pctl_reg);
+	b43_radio_maskset(dev, 0x43, 0xFFF0, radio_pctl_reg);
 	b43_gphy_set_baseband_attenuation(dev, 2);
 
 	reg = lo_txctl_register_table(dev, &mask, NULL);
 	mask = ~mask;
-	b43_radio_write16(dev, reg, b43_radio_read16(dev, reg)
-			  & mask);
+	b43_radio_mask(dev, reg, mask);
 
 	if (has_tx_magnification(phy)) {
 		int i, j;
@@ -242,14 +240,10 @@ static void lo_measure_txctl_values(stru
 
 		for (i = 0; i < ARRAY_SIZE(tx_magn_values); i++) {
 			tx_magn = tx_magn_values[i];
-			b43_radio_write16(dev, 0x52,
-					  (b43_radio_read16(dev, 0x52)
-					   & 0xFF0F) | tx_magn);
+			b43_radio_maskset(dev, 0x52, 0xFF0F, tx_magn);
 			for (j = 0; j < ARRAY_SIZE(tx_bias_values); j++) {
 				tx_bias = tx_bias_values[j];
-				b43_radio_write16(dev, 0x52,
-						  (b43_radio_read16(dev, 0x52)
-						   & 0xFFF0) | tx_bias);
+				b43_radio_maskset(dev, 0x52, 0xFFF0, tx_bias);
 				feedthrough =
 				    lo_measure_feedthrough(dev, 0, pga,
 							   trsw_rx);
@@ -269,8 +263,7 @@ static void lo_measure_txctl_values(stru
 	} else {
 		lo->tx_magn = 0;
 		lo->tx_bias = 0;
-		b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52)
-				  & 0xFFF0);	/* TX bias == 0 */
+		b43_radio_mask(dev, 0x52, 0xFFF0);	/* TX bias == 0 */
 	}
 	lo->txctl_measured_time = jiffies;
 }
@@ -406,18 +399,10 @@ static void lo_measure_setup(struct b43_
 		sav->phy_cck_14 = b43_phy_read(dev, B43_PHY_CCK(0x14));
 		sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL);
 
-		b43_phy_write(dev, B43_PHY_HPWR_TSSICTL,
-			      b43_phy_read(dev, B43_PHY_HPWR_TSSICTL)
-			      | 0x100);
-		b43_phy_write(dev, B43_PHY_EXTG(0x01),
-			      b43_phy_read(dev, B43_PHY_EXTG(0x01))
-			      | 0x40);
-		b43_phy_write(dev, B43_PHY_DACCTL,
-			      b43_phy_read(dev, B43_PHY_DACCTL)
-			      | 0x40);
-		b43_phy_write(dev, B43_PHY_CCK(0x14),
-			      b43_phy_read(dev, B43_PHY_CCK(0x14))
-			      | 0x200);
+		b43_phy_set(dev, B43_PHY_HPWR_TSSICTL, 0x100);
+		b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x40);
+		b43_phy_set(dev, B43_PHY_DACCTL, 0x40);
+		b43_phy_set(dev, B43_PHY_CCK(0x14), 0x200);
 	}
 	if (phy->type == B43_PHYTYPE_B &&
 	    phy->radio_ver == 0x2050 && phy->radio_rev < 6) {
@@ -434,17 +419,10 @@ static void lo_measure_setup(struct b43_
 		sav->phy_cck_3E = b43_phy_read(dev, B43_PHY_CCK(0x3E));
 		sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
 
-		b43_phy_write(dev, B43_PHY_CLASSCTL,
-			      b43_phy_read(dev, B43_PHY_CLASSCTL)
-			      & 0xFFFC);
-		b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
-			      & 0x7FFF);
-		b43_phy_write(dev, B43_PHY_ANALOGOVER,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVER)
-			      | 0x0003);
-		b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
-			      & 0xFFFC);
+		b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
+		b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+		b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+		b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
 		if (phy->type == B43_PHYTYPE_G) {
 			if ((phy->rev >= 7) &&
 			    (sprom->boardflags_lo & B43_BFL_EXTLNA)) {
@@ -558,8 +536,7 @@ static void lo_measure_restore(struct b4
 	b43_radio_write16(dev, 0x7A, sav->radio_7A);
 	if (!has_tx_magnification(phy)) {
 		tmp = sav->radio_52;
-		b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
-					      & 0xFF0F) | tmp);
+		b43_radio_maskset(dev, 0x52, 0xFF0F, tmp);
 	}
 	b43_write16(dev, 0x3E2, sav->reg_3E2);
 	if (phy->type == B43_PHYTYPE_B &&
@@ -754,9 +731,9 @@ static void lo_probe_loctls_statemachine
 }
 
 static
-struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
-					       const struct b43_bbatt *bbatt,
-					       const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev,
+					      const struct b43_bbatt *bbatt,
+					      const struct b43_rfatt *rfatt)
 {
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_g *gphy = phy->g;
@@ -778,12 +755,8 @@ struct b43_lo_calib * b43_calibrate_lo_s
 
 	txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
 
-	b43_radio_write16(dev, 0x43,
-			  (b43_radio_read16(dev, 0x43) & 0xFFF0)
-			  | rfatt->att);
-	b43_radio_write16(dev, txctl_reg,
-			  (b43_radio_read16(dev, txctl_reg) & ~txctl_value)
-			  | (rfatt->with_padmix) ? txctl_value : 0);
+	b43_radio_maskset(dev, 0x43, 0xFFF0, rfatt->att);
+	b43_radio_maskset(dev, txctl_reg, ~txctl_value, (rfatt->with_padmix ? txctl_value :0));
 
 	max_rx_gain = rfatt->att * 2;
 	max_rx_gain += bbatt->att / 2;
@@ -824,9 +797,9 @@ struct b43_lo_calib * b43_calibrate_lo_s
 /* Get a calibrated LO setting for the given attenuation values.
  * Might return a NULL pointer under OOM! */
 static
-struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
-						const struct b43_bbatt *bbatt,
-						const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_get_calib_lo_settings(struct b43_wldev *dev,
+					       const struct b43_bbatt *bbatt,
+					       const struct b43_rfatt *rfatt)
 {
 	struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
 	struct b43_lo_calib *c;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 18:04:08.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/main.c	2013-05-03 16:48:00.000000000 -0400
@@ -4,7 +4,7 @@
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
   Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
-  Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
+  Copyright (c) 2005-2009 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
 
@@ -88,6 +88,10 @@ static int modparam_btcoex = 1;
 module_param_named(btcoex, modparam_btcoex, int, 0444);
 MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
 
+int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
+module_param_named(verbose, b43_modparam_verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
+
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -97,6 +101,8 @@ static const struct ssb_device_id b43_ss
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
 	SSB_DEVTABLE_END
 };
 
@@ -298,6 +304,8 @@ void b43info(struct b43_wl *wl, const ch
 {
 	va_list args;
 
+	if (b43_modparam_verbose < B43_VERBOSITY_INFO)
+		return;
 	if (!b43_ratelimit(wl))
 		return;
 	va_start(args, fmt);
@@ -311,6 +319,8 @@ void b43err(struct b43_wl *wl, const cha
 {
 	va_list args;
 
+	if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
+		return;
 	if (!b43_ratelimit(wl))
 		return;
 	va_start(args, fmt);
@@ -324,6 +334,8 @@ void b43warn(struct b43_wl *wl, const ch
 {
 	va_list args;
 
+	if (b43_modparam_verbose < B43_VERBOSITY_WARN)
+		return;
 	if (!b43_ratelimit(wl))
 		return;
 	va_start(args, fmt);
@@ -333,18 +345,18 @@ void b43warn(struct b43_wl *wl, const ch
 	va_end(args);
 }
 
-#if B43_DEBUG
 void b43dbg(struct b43_wl *wl, const char *fmt, ...)
 {
 	va_list args;
 
+	if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+		return;
 	va_start(args, fmt);
 	printk(KERN_DEBUG "b43-%s debug: ",
 	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
 	vprintk(fmt, args);
 	va_end(args);
 }
-#endif /* DEBUG */
 
 static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
 {
@@ -500,7 +512,7 @@ void b43_shm_write16(struct b43_wldev *d
 }
 
 /* Read HostFlags */
-u64 b43_hf_read(struct b43_wldev * dev)
+u64 b43_hf_read(struct b43_wldev *dev)
 {
 	u64 ret;
 
@@ -526,52 +538,20 @@ void b43_hf_write(struct b43_wldev *dev,
 	b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
 }
 
-void b43_tsf_read(struct b43_wldev *dev, u64 * tsf)
+void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
 {
-	/* We need to be careful. As we read the TSF from multiple
-	 * registers, we should take care of register overflows.
-	 * In theory, the whole tsf read process should be atomic.
-	 * We try to be atomic here, by restaring the read process,
-	 * if any of the high registers changed (overflew).
-	 */
-	if (dev->dev->id.revision >= 3) {
-		u32 low, high, high2;
-
-		do {
-			high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
-			low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
-			high2 = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
-		} while (unlikely(high != high2));
-
-		*tsf = high;
-		*tsf <<= 32;
-		*tsf |= low;
-	} else {
-		u64 tmp;
-		u16 v0, v1, v2, v3;
-		u16 test1, test2, test3;
+	u32 low, high;
 
-		do {
-			v3 = b43_read16(dev, B43_MMIO_TSF_3);
-			v2 = b43_read16(dev, B43_MMIO_TSF_2);
-			v1 = b43_read16(dev, B43_MMIO_TSF_1);
-			v0 = b43_read16(dev, B43_MMIO_TSF_0);
+	B43_WARN_ON(dev->dev->id.revision < 3);
 
-			test3 = b43_read16(dev, B43_MMIO_TSF_3);
-			test2 = b43_read16(dev, B43_MMIO_TSF_2);
-			test1 = b43_read16(dev, B43_MMIO_TSF_1);
-		} while (v3 != test3 || v2 != test2 || v1 != test1);
+	/* The hardware guarantees us an atomic read, if we
+	 * read the low register first. */
+	low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
+	high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
 
-		*tsf = v3;
-		*tsf <<= 48;
-		tmp = v2;
-		tmp <<= 32;
-		*tsf |= tmp;
-		tmp = v1;
-		tmp <<= 16;
-		*tsf |= tmp;
-		*tsf |= v0;
-	}
+	*tsf = high;
+	*tsf <<= 32;
+	*tsf |= low;
 }
 
 static void b43_time_lock(struct b43_wldev *dev)
@@ -598,35 +578,18 @@ static void b43_time_unlock(struct b43_w
 
 static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
 {
-	/* Be careful with the in-progress timer.
-	 * First zero out the low register, so we have a full
-	 * register-overflow duration to complete the operation.
-	 */
-	if (dev->dev->id.revision >= 3) {
-		u32 lo = (tsf & 0x00000000FFFFFFFFULL);
-		u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
+	u32 low, high;
 
-		b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, 0);
-		mmiowb();
-		b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, hi);
-		mmiowb();
-		b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, lo);
-	} else {
-		u16 v0 = (tsf & 0x000000000000FFFFULL);
-		u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
-		u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
-		u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
+	B43_WARN_ON(dev->dev->id.revision < 3);
 
-		b43_write16(dev, B43_MMIO_TSF_0, 0);
-		mmiowb();
-		b43_write16(dev, B43_MMIO_TSF_3, v3);
-		mmiowb();
-		b43_write16(dev, B43_MMIO_TSF_2, v2);
-		mmiowb();
-		b43_write16(dev, B43_MMIO_TSF_1, v1);
-		mmiowb();
-		b43_write16(dev, B43_MMIO_TSF_0, v0);
-	}
+	low = tsf;
+	high = (tsf >> 32);
+	/* The hardware guarantees us an atomic write, if we
+	 * write the low register first. */
+	b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low);
+	mmiowb();
+	b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high);
+	mmiowb();
 }
 
 void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
@@ -637,7 +600,7 @@ void b43_tsf_write(struct b43_wldev *dev
 }
 
 static
-void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 * mac)
+void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 *mac)
 {
 	static const u8 zero_addr[ETH_ALEN] = { 0 };
 	u16 data;
@@ -827,7 +790,7 @@ void b43_dummy_transmission(struct b43_w
 }
 
 static void key_write(struct b43_wldev *dev,
-		      u8 index, u8 algorithm, const u8 * key)
+		      u8 index, u8 algorithm, const u8 *key)
 {
 	unsigned int i;
 	u32 offset;
@@ -849,7 +812,7 @@ static void key_write(struct b43_wldev *
 	}
 }
 
-static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
+static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
 {
 	u32 addrtmp[2] = { 0, 0, };
 	u8 per_sta_keys_start = 8;
@@ -899,7 +862,7 @@ static void keymac_write(struct b43_wlde
 
 static void do_key_write(struct b43_wldev *dev,
 			 u8 index, u8 algorithm,
-			 const u8 * key, size_t key_len, const u8 * mac_addr)
+			 const u8 *key, size_t key_len, const u8 *mac_addr)
 {
 	u8 buf[B43_SEC_KEYSIZE] = { 0, };
 	u8 per_sta_keys_start = 8;
@@ -923,8 +886,8 @@ static void do_key_write(struct b43_wlde
 
 static int b43_key_write(struct b43_wldev *dev,
 			 int index, u8 algorithm,
-			 const u8 * key, size_t key_len,
-			 const u8 * mac_addr,
+			 const u8 *key, size_t key_len,
+			 const u8 *mac_addr,
 			 struct ieee80211_key_conf *keyconf)
 {
 	int i;
@@ -937,8 +900,7 @@ static int b43_key_write(struct b43_wlde
 		B43_WARN_ON(dev->key[i].keyconf == keyconf);
 	}
 	if (index < 0) {
-		/* Either pairwise key or address is 00:00:00:00:00:00
-		 * for transmit-only keys. Search the index. */
+		/* Pairwise key. Get an empty slot for the key. */
 		if (b43_new_kidx_api(dev))
 			sta_keys_start = 4;
 		else
@@ -951,7 +913,7 @@ static int b43_key_write(struct b43_wlde
 			}
 		}
 		if (index < 0) {
-			b43err(dev->wl, "Out of hardware key memory\n");
+			b43warn(dev->wl, "Out of hardware key memory\n");
 			return -ENOSPC;
 		}
 	} else
@@ -1324,7 +1286,7 @@ static void handle_irq_pmq(struct b43_wl
 }
 
 static void b43_write_template_common(struct b43_wldev *dev,
-				      const u8 * data, u16 size,
+				      const u8 *data, u16 size,
 				      u16 ram_offset,
 				      u16 shm_size_offset, u8 rate)
 {
@@ -1514,9 +1476,9 @@ static void b43_write_probe_resp_plcp(st
  * 2) Patching duration field
  * 3) Stripping TIM
  */
-static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
-					  u16 *dest_size,
-					  struct ieee80211_rate *rate)
+static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
+					 u16 *dest_size,
+					 struct ieee80211_rate *rate)
 {
 	const u8 *src_data;
 	u8 *dest_data;
@@ -1982,7 +1944,7 @@ static irqreturn_t b43_interrupt_handler
 	return ret;
 }
 
-static void do_release_fw(struct b43_firmware_file *fw)
+void b43_do_release_fw(struct b43_firmware_file *fw)
 {
 	release_firmware(fw->data);
 	fw->data = NULL;
@@ -1991,29 +1953,27 @@ static void do_release_fw(struct b43_fir
 
 static void b43_release_firmware(struct b43_wldev *dev)
 {
-	do_release_fw(&dev->fw.ucode);
-	do_release_fw(&dev->fw.pcm);
-	do_release_fw(&dev->fw.initvals);
-	do_release_fw(&dev->fw.initvals_band);
+	b43_do_release_fw(&dev->fw.ucode);
+	b43_do_release_fw(&dev->fw.pcm);
+	b43_do_release_fw(&dev->fw.initvals);
+	b43_do_release_fw(&dev->fw.initvals_band);
 }
 
 static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
 {
-	const char *text;
+	const char text[] =
+		"/*(DEBLOBBED)*/";
 
-	text = "/*(DEBLOBBED)*/";
 	if (error)
 		b43err(wl, text);
 	else
 		b43warn(wl, text);
 }
 
-static int do_request_fw(struct b43_wldev *dev,
-			 const char *name,
-			 struct b43_firmware_file *fw,
-			 bool silent)
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+		      const char *name,
+		      struct b43_firmware_file *fw)
 {
-	char path[sizeof(modparam_fwpostfix) + 32];
 	const struct firmware *blob;
 	struct b43_fw_header *hdr;
 	u32 size;
@@ -2021,29 +1981,49 @@ static int do_request_fw(struct b43_wlde
 
 	if (!name) {
 		/* Don't fetch anything. Free possibly cached firmware. */
-		do_release_fw(fw);
+		/* FIXME: We should probably keep it anyway, to save some headache
+		 * on suspend/resume with multiband devices. */
+		b43_do_release_fw(fw);
 		return 0;
 	}
 	if (fw->filename) {
-		if (strcmp(fw->filename, name) == 0)
+		if ((fw->type == ctx->req_type) &&
+		    (strcmp(fw->filename, name) == 0))
 			return 0; /* Already have this fw. */
 		/* Free the cached firmware first. */
-		do_release_fw(fw);
+		/* FIXME: We should probably do this later after we successfully
+		 * got the new fw. This could reduce headache with multiband devices.
+		 * We could also redesign this to cache the firmware for all possible
+		 * bands all the time. */
+		b43_do_release_fw(fw);
 	}
 
-	snprintf(path, ARRAY_SIZE(path),
-		 "/*(DEBLOBBED)*/",
-		 modparam_fwpostfix, name);
-	err = reject_firmware(&blob, path, dev->dev->dev);
+	switch (ctx->req_type) {
+	case B43_FWTYPE_PROPRIETARY:
+		snprintf(ctx->fwname, sizeof(ctx->fwname),
+			 "/*(DEBLOBBED)*/",
+			 modparam_fwpostfix, name);
+		break;
+	case B43_FWTYPE_OPENSOURCE:
+		snprintf(ctx->fwname, sizeof(ctx->fwname),
+			 "b43-open%s/%s.fw",
+			 modparam_fwpostfix, name);
+		break;
+	default:
+		B43_WARN_ON(1);
+		return -ENOSYS;
+	}
+	err = maybe_reject_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
 	if (err == -ENOENT) {
-		if (!silent) {
-			b43err(dev->wl, "Firmware file \"%s\" not found\n",
-			       path);
-		}
+		snprintf(ctx->errors[ctx->req_type],
+			 sizeof(ctx->errors[ctx->req_type]),
+			 "Firmware file \"%s\" not found\n", ctx->fwname);
 		return err;
 	} else if (err) {
-		b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
-		       path, err);
+		snprintf(ctx->errors[ctx->req_type],
+			 sizeof(ctx->errors[ctx->req_type]),
+			 "Firmware file \"%s\" request failed (err=%d)\n",
+			 ctx->fwname, err);
 		return err;
 	}
 	if (blob->size < sizeof(struct b43_fw_header))
@@ -2066,20 +2046,24 @@ static int do_request_fw(struct b43_wlde
 
 	fw->data = blob;
 	fw->filename = name;
+	fw->type = ctx->req_type;
 
 	return 0;
 
 err_format:
-	b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
+	snprintf(ctx->errors[ctx->req_type],
+		 sizeof(ctx->errors[ctx->req_type]),
+		 "Firmware file \"%s\" format error.\n", ctx->fwname);
 	release_firmware(blob);
 
 	return -EPROTO;
 }
 
-static int b43_reject_firmware(struct b43_wldev *dev)
+static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 {
-	struct b43_firmware *fw = &dev->fw;
-	const u8 rev = dev->dev->id.revision;
+	struct b43_wldev *dev = ctx->dev;
+	struct b43_firmware *fw = &ctx->dev->fw;
+	const u8 rev = ctx->dev->dev->id.revision;
 	const char *filename;
 	u32 tmshigh;
 	int err;
@@ -2094,7 +2078,7 @@ static int b43_reject_firmware(struct b4
 		filename = "ucode13";
 	else
 		goto err_no_ucode;
-	err = do_request_fw(dev, filename, &fw->ucode, 0);
+	err = b43_do_request_fw(ctx, filename, &fw->ucode);
 	if (err)
 		goto err_load;
 
@@ -2106,7 +2090,7 @@ static int b43_reject_firmware(struct b4
 	else
 		goto err_no_pcm;
 	fw->pcm_request_failed = 0;
-	err = do_request_fw(dev, filename, &fw->pcm, 1);
+	err = b43_do_request_fw(ctx, filename, &fw->pcm);
 	if (err == -ENOENT) {
 		/* We did not find a PCM file? Not fatal, but
 		 * core rev <= 10 must do without hwcrypto then. */
@@ -2142,7 +2126,7 @@ static int b43_reject_firmware(struct b4
 	default:
 		goto err_no_initvals;
 	}
-	err = do_request_fw(dev, filename, &fw->initvals, 0);
+	err = b43_do_request_fw(ctx, filename, &fw->initvals);
 	if (err)
 		goto err_load;
 
@@ -2176,30 +2160,34 @@ static int b43_reject_firmware(struct b4
 	default:
 		goto err_no_initvals;
 	}
-	err = do_request_fw(dev, filename, &fw->initvals_band, 0);
+	err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
 	if (err)
 		goto err_load;
 
 	return 0;
 
-err_load:
-	b43_print_fw_helptext(dev->wl, 1);
-	goto error;
-
 err_no_ucode:
-	err = -ENODEV;
-	b43err(dev->wl, "No microcode available for core rev %u\n", rev);
+	err = ctx->fatal_failure = -EOPNOTSUPP;
+	b43err(dev->wl, "The driver does not know which firmware (ucode) "
+	       "is required for your device (wl-core rev %u)\n", rev);
 	goto error;
 
 err_no_pcm:
-	err = -ENODEV;
-	b43err(dev->wl, "No PCM available for core rev %u\n", rev);
+	err = ctx->fatal_failure = -EOPNOTSUPP;
+	b43err(dev->wl, "The driver does not know which firmware (PCM) "
+	       "is required for your device (wl-core rev %u)\n", rev);
 	goto error;
 
 err_no_initvals:
-	err = -ENODEV;
-	b43err(dev->wl, "No Initial Values firmware file for PHY %u, "
-	       "core rev %u\n", dev->phy.type, rev);
+	err = ctx->fatal_failure = -EOPNOTSUPP;
+	b43err(dev->wl, "The driver does not know which firmware (initvals) "
+	       "is required for your device (wl-core rev %u)\n", rev);
+	goto error;
+
+err_load:
+	/* We failed to load this firmware image. The error message
+	 * already is in ctx->errors. Return and let our caller decide
+	 * what to do. */
 	goto error;
 
 error:
@@ -2207,6 +2195,48 @@ error:
 	return err;
 }
 
+static int b43_maybe_reject_firmware(struct b43_wldev *dev)
+{
+	struct b43_request_fw_context *ctx;
+	unsigned int i;
+	int err;
+	const char *errmsg;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+	ctx->dev = dev;
+
+	ctx->req_type = B43_FWTYPE_PROPRIETARY;
+	err = b43_try_request_fw(ctx);
+	if (!err)
+		goto out; /* Successfully loaded it. */
+	err = ctx->fatal_failure;
+	if (err)
+		goto out;
+
+	ctx->req_type = B43_FWTYPE_OPENSOURCE;
+	err = b43_try_request_fw(ctx);
+	if (!err)
+		goto out; /* Successfully loaded it. */
+	err = ctx->fatal_failure;
+	if (err)
+		goto out;
+
+	/* Could not find a usable firmware. Print the errors. */
+	for (i = 0; i < B43_NR_FWTYPES; i++) {
+		errmsg = ctx->errors[i];
+		if (strlen(errmsg))
+			b43err(dev->wl, errmsg);
+	}
+	b43_print_fw_helptext(dev->wl, 1);
+	err = -ENOENT;
+
+out:
+	kfree(ctx);
+	return err;
+}
+
 static int b43_upload_microcode(struct b43_wldev *dev)
 {
 	const size_t hdr_len = sizeof(struct b43_fw_header);
@@ -2297,6 +2327,11 @@ static int b43_upload_microcode(struct b
 	dev->fw.patch = fwpatch;
 	dev->fw.opensource = (fwdate == 0xFFFF);
 
+	if (!dev->fw.opensource) {
+		b43err(dev->wl, "Rejected non-Free firmware\n");
+		err = -EOPNOTSUPP;
+		goto error;
+	}
 	if (dev->fw.opensource) {
 		/* Patchlevel info is encoded in the "time" field. */
 		dev->fw.patch = fwtime;
@@ -2317,8 +2352,11 @@ static int b43_upload_microcode(struct b
 	}
 
 	if (b43_is_old_txhdr_format(dev)) {
+		/* We're over the deadline, but we keep support for old fw
+		 * until it turns out to be in major conflict with something new. */
 		b43warn(dev->wl, "You are using an old firmware image. "
-			"Support for old firmware will be removed in July 2008.\n");
+			"Support for old firmware will be removed soon "
+			"(official deadline was July 2008).\n");
 		b43_print_fw_helptext(dev->wl, 0);
 	}
 
@@ -2707,7 +2745,7 @@ static int b43_chip_init(struct b43_wlde
 	macctl |= B43_MACCTL_INFRA;
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
 
-	err = b43_reject_firmware(dev);
+	err = b43_maybe_reject_firmware(dev);
 	if (err)
 		goto out;
 	err = b43_upload_microcode(dev);
@@ -2944,7 +2982,7 @@ static void b43_security_init(struct b43
 	b43_clear_keys(dev);
 }
 
-static int b43_rng_read(struct hwrng *rng, u32 * data)
+static int b43_rng_read(struct hwrng *rng, u32 *data)
 {
 	struct b43_wl *wl = (struct b43_wl *)rng->priv;
 	unsigned long flags;
@@ -3219,6 +3257,43 @@ static int b43_op_get_stats(struct ieee8
 	return 0;
 }
 
+static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+	struct b43_wldev *dev;
+	u64 tsf;
+
+	mutex_lock(&wl->mutex);
+	spin_lock_irq(&wl->irq_lock);
+	dev = wl->current_dev;
+
+	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+		b43_tsf_read(dev, &tsf);
+	else
+		tsf = 0;
+
+	spin_unlock_irq(&wl->irq_lock);
+	mutex_unlock(&wl->mutex);
+
+	return tsf;
+}
+
+static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+	struct b43_wldev *dev;
+
+	mutex_lock(&wl->mutex);
+	spin_lock_irq(&wl->irq_lock);
+	dev = wl->current_dev;
+
+	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+		b43_tsf_write(dev, tsf);
+
+	spin_unlock_irq(&wl->irq_lock);
+	mutex_unlock(&wl->mutex);
+}
+
 static void b43_put_phy_into_reset(struct b43_wldev *dev)
 {
 	struct ssb_device *sdev = dev->dev;
@@ -3238,7 +3313,7 @@ static void b43_put_phy_into_reset(struc
 	msleep(1);
 }
 
-static const char * band_to_string(enum ieee80211_band band)
+static const char *band_to_string(enum ieee80211_band band)
 {
 	switch (band) {
 	case IEEE80211_BAND_5GHZ:
@@ -3440,7 +3515,7 @@ out_unlock_mutex:
 	return err;
 }
 
-static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
+static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates)
 {
 	struct ieee80211_supported_band *sband =
 		dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
@@ -3518,21 +3593,29 @@ out_unlock_mutex:
 }
 
 static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-			   const u8 *local_addr, const u8 *addr,
-			   struct ieee80211_key_conf *key)
+			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev;
-	unsigned long flags;
 	u8 algorithm;
 	u8 index;
 	int err;
+	static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
 	if (modparam_nohwcrypt)
 		return -ENOSPC; /* User disabled HW-crypto */
 
 	mutex_lock(&wl->mutex);
-	spin_lock_irqsave(&wl->irq_lock, flags);
+	spin_lock_irq(&wl->irq_lock);
+	write_lock(&wl->tx_lock);
+	/* Why do we need all this locking here?
+	 * mutex     -> Every config operation must take it.
+	 * irq_lock  -> We modify the dev->key array, which is accessed
+	 *              in the IRQ handlers.
+	 * tx_lock   -> We modify the dev->key array, which is accessed
+	 *              in the TX handler.
+	 */
 
 	dev = wl->current_dev;
 	err = -ENODEV;
@@ -3549,7 +3632,7 @@ static int b43_op_set_key(struct ieee802
 	err = -EINVAL;
 	switch (key->alg) {
 	case ALG_WEP:
-		if (key->keylen == 5)
+		if (key->keylen == LEN_WEP40)
 			algorithm = B43_SEC_ALGO_WEP40;
 		else
 			algorithm = B43_SEC_ALGO_WEP104;
@@ -3576,17 +3659,19 @@ static int b43_op_set_key(struct ieee802
 			goto out_unlock;
 		}
 
-		if (is_broadcast_ether_addr(addr)) {
-			/* addr is FF:FF:FF:FF:FF:FF for default keys */
+		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+			if (WARN_ON(!sta)) {
+				err = -EOPNOTSUPP;
+				goto out_unlock;
+			}
+			/* Pairwise key with an assigned MAC address. */
+			err = b43_key_write(dev, -1, algorithm,
+					    key->key, key->keylen,
+					    sta->addr, key);
+		} else {
+			/* Group key */
 			err = b43_key_write(dev, index, algorithm,
 					    key->key, key->keylen, NULL, key);
-		} else {
-			/*
-			 * either pairwise key or address is 00:00:00:00:00:00
-			 * for transmit-only keys
-			 */
-			err = b43_key_write(dev, -1, algorithm,
-					    key->key, key->keylen, addr, key);
 		}
 		if (err)
 			goto out_unlock;
@@ -3615,10 +3700,11 @@ out_unlock:
 		b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
 		       "mac: %pM\n",
 		       cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
-		       addr);
+		       sta ? sta->addr : bcast_addr);
 		b43_dump_keymemory(dev);
 	}
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
+	write_unlock(&wl->tx_lock);
+	spin_unlock_irq(&wl->irq_lock);
 	mutex_unlock(&wl->mutex);
 
 	return err;
@@ -3794,6 +3880,12 @@ static int b43_phy_versioning(struct b43
 		break;
 #ifdef CONFIG_B43_NPHY
 	case B43_PHYTYPE_N:
+		if (phy_rev > 4)
+			unsupported = 1;
+		break;
+#endif
+#ifdef CONFIG_B43_PHY_LP
+	case B43_PHYTYPE_LP:
 		if (phy_rev > 1)
 			unsupported = 1;
 		break;
@@ -3847,7 +3939,11 @@ static int b43_phy_versioning(struct b43
 			unsupported = 1;
 		break;
 	case B43_PHYTYPE_N:
-		if (radio_ver != 0x2055)
+		if (radio_ver != 0x2055 && radio_ver != 0x2056)
+			unsupported = 1;
+		break;
+	case B43_PHYTYPE_LP:
+		if (radio_ver != 0x2062)
 			unsupported = 1;
 		break;
 	default:
@@ -3880,6 +3976,11 @@ static void setup_struct_phy_for_init(st
 	phy->next_txpwr_check_time = jiffies;
 	/* PHY TX errors counter. */
 	atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+
+#if B43_DEBUG
+	phy->phy_locked = 0;
+	phy->radio_locked = 0;
+#endif
 }
 
 static void setup_struct_wldev_for_init(struct b43_wldev *dev)
@@ -3899,6 +4000,8 @@ static void setup_struct_wldev_for_init(
 	dev->irq_reason = 0;
 	memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
 	dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+	if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+		dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
 
 	dev->mac_suspended = 1;
 
@@ -4076,11 +4179,21 @@ static int b43_wireless_core_init(struct
 			hf |= B43_HF_GDCW;
 		if (sprom->boardflags_lo & B43_BFL_PACTRL)
 			hf |= B43_HF_OFDMPABOOST;
-	} else if (phy->type == B43_PHYTYPE_B) {
-		hf |= B43_HF_SYMW;
-		if (phy->rev >= 2 && phy->radio_ver == 0x2050)
-			hf &= ~B43_HF_GDCW;
 	}
+	if (phy->radio_ver == 0x2050) {
+		if (phy->radio_rev == 6)
+			hf |= B43_HF_4318TSSI;
+		if (phy->radio_rev < 6)
+			hf |= B43_HF_VCORECALC;
+	}
+	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
+		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+	if ((bus->bustype == SSB_BUSTYPE_PCI) &&
+	    (bus->pcicore.dev->id.revision <= 10))
+		hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
+#endif
+	hf &= ~B43_HF_SKCFPUP;
 	b43_hf_write(dev, hf);
 
 	b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
@@ -4119,7 +4232,7 @@ static int b43_wireless_core_init(struct
 	b43_set_synth_pu_delay(dev, 1);
 	b43_bluetooth_coext_enable(dev);
 
-	ssb_bus_powerup(bus, 1);	/* Enable dynamic PCTL */
+	ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
 	b43_upload_card_macaddress(dev);
 	b43_security_init(dev);
 	if (!dev->suspend_in_progress)
@@ -4303,6 +4416,34 @@ static void b43_op_sta_notify(struct iee
 	B43_WARN_ON(!vif || wl->vif != vif);
 }
 
+static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+	struct b43_wldev *dev;
+
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+		/* Disable CFP update during scan on other channels. */
+		b43_hf_write(dev, b43_hf_read(dev) | B43_HF_SKCFPUP);
+	}
+	mutex_unlock(&wl->mutex);
+}
+
+static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+	struct b43_wldev *dev;
+
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+		/* Re-enable CFP update. */
+		b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_SKCFPUP);
+	}
+	mutex_unlock(&wl->mutex);
+}
+
 static const struct ieee80211_ops b43_hw_ops = {
 	.tx			= b43_op_tx,
 	.conf_tx		= b43_op_conf_tx,
@@ -4315,10 +4456,14 @@ static const struct ieee80211_ops b43_hw
 	.set_key		= b43_op_set_key,
 	.get_stats		= b43_op_get_stats,
 	.get_tx_stats		= b43_op_get_tx_stats,
+	.get_tsf		= b43_op_get_tsf,
+	.set_tsf		= b43_op_set_tsf,
 	.start			= b43_op_start,
 	.stop			= b43_op_stop,
 	.set_tim		= b43_op_beacon_set_tim,
 	.sta_notify		= b43_op_sta_notify,
+	.sw_scan_start		= b43_op_sw_scan_start_notifier,
+	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
 };
 
 /* Hard-reset the chip. Do not call this directly.
@@ -4444,6 +4589,7 @@ static int b43_wireless_core_attach(stru
 			break;
 		case B43_PHYTYPE_G:
 		case B43_PHYTYPE_N:
+		case B43_PHYTYPE_LP:
 			have_2ghz_phy = 1;
 			break;
 		default:
@@ -4655,9 +4801,10 @@ static int b43_wireless_init(struct ssb_
 	INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
 
 	ssb_set_devtypedata(dev, wl);
-	b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
+		dev->bus->chip_id, dev->id.revision);
 	err = 0;
-      out:
+out:
 	return err;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/main.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/main.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/main.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/main.h	2009-06-09 23:05:27.000000000 -0400
@@ -40,6 +40,24 @@
 
 
 extern int b43_modparam_qos;
+extern int b43_modparam_verbose;
+
+/* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
+ * you add or remove levels. */
+enum b43_verbosity {
+	B43_VERBOSITY_ERROR,
+	B43_VERBOSITY_WARN,
+	B43_VERBOSITY_INFO,
+	B43_VERBOSITY_DEBUG,
+	__B43_VERBOSITY_AFTERLAST, /* keep last */
+
+	B43_VERBOSITY_MAX = __B43_VERBOSITY_AFTERLAST - 1,
+#if B43_DEBUG
+	B43_VERBOSITY_DEFAULT = B43_VERBOSITY_DEBUG,
+#else
+	B43_VERBOSITY_DEFAULT = B43_VERBOSITY_INFO,
+#endif
+};
 
 
 /* Lightweight function to convert a frequency (in Mhz) to a channel number. */
@@ -121,4 +139,11 @@ void b43_power_saving_ctl_bits(struct b4
 void b43_mac_suspend(struct b43_wldev *dev);
 void b43_mac_enable(struct b43_wldev *dev);
 
+
+struct b43_request_fw_context;
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+		      const char *name,
+		      struct b43_firmware_file *fw);
+void b43_do_release_fw(struct b43_firmware_file *fw);
+
 #endif /* B43_MAIN_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,7 @@ b43-y				+= phy_g.o
 b43-y				+= phy_a.o
 b43-$(CONFIG_B43_NPHY)		+= phy_n.o
 b43-$(CONFIG_B43_PHY_LP)	+= phy_lp.o
+b43-$(CONFIG_B43_PHY_LP)	+= tables_lpphy.o
 b43-y				+= sysfs.o
 b43-y				+= xmit.o
 b43-y				+= lo.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_a.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_a.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_a.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_a.c	2009-06-09 23:05:27.000000000 -0400
@@ -121,27 +121,18 @@ static void aphy_channel_switch(struct b
 	b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
 	b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
 	b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
-	b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
-					& 0x000F) | (r8 << 4));
+	b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
 	b43_radio_write16(dev, 0x002A, (r8 << 4));
 	b43_radio_write16(dev, 0x002B, (r8 << 4));
-	b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
-					& 0x00F0) | (r8 << 4));
-	b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
-					& 0xFF0F) | 0x00B0);
+	b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
+	b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
 	b43_radio_write16(dev, 0x0035, 0x00AA);
 	b43_radio_write16(dev, 0x0036, 0x0085);
-	b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
-					& 0xFF20) |
-			  freq_r3A_value(freq));
-	b43_radio_write16(dev, 0x003D,
-			  b43_radio_read16(dev, 0x003D) & 0x00FF);
-	b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
-					& 0xFF7F) | 0x0080);
-	b43_radio_write16(dev, 0x0035,
-			  b43_radio_read16(dev, 0x0035) & 0xFFEF);
-	b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
-					& 0xFFEF) | 0x0010);
+	b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
+	b43_radio_mask(dev, 0x003D, 0x00FF);
+	b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
+	b43_radio_mask(dev, 0x0035, 0xFFEF);
+	b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
 	b43_radio_set_tx_iq(dev);
 	//TODO: TSSI2dbm workaround
 //FIXME	b43_phy_xmitpower(dev);
@@ -160,23 +151,20 @@ static void b43_radio_init2060(struct b4
 	b43_radio_write16(dev, 0x0082, 0x0080);
 	b43_radio_write16(dev, 0x0080, 0x0000);
 	b43_radio_write16(dev, 0x003F, 0x00DA);
-	b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
-	b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
-	b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
-	b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
+	b43_radio_mask(dev, 0x0005, ~0x0008);
+	b43_radio_mask(dev, 0x0081, ~0x0010);
+	b43_radio_mask(dev, 0x0081, ~0x0020);
+	b43_radio_mask(dev, 0x0081, ~0x0020);
 	msleep(1);		/* delay 400usec */
 
-	b43_radio_write16(dev, 0x0081,
-			  (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
+	b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
 	msleep(1);		/* delay 400usec */
 
-	b43_radio_write16(dev, 0x0005,
-			  (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
-	b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
-	b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
-	b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
-	b43_radio_write16(dev, 0x0081,
-			  (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
+	b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
+	b43_radio_mask(dev, 0x0085, ~0x0010);
+	b43_radio_mask(dev, 0x0005, ~0x0008);
+	b43_radio_mask(dev, 0x0081, ~0x0040);
+	b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
 	b43_radio_write16(dev, 0x0005,
 			  (b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
 	b43_phy_write(dev, 0x0063, 0xDDC6);
@@ -224,22 +212,16 @@ static void b43_phy_ww(struct b43_wldev
 	u16 b, curr_s, best_s = 0xFFFF;
 	int i;
 
-	b43_phy_write(dev, B43_PHY_CRS0,
-		b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
-	b43_phy_write(dev, B43_PHY_OFDM(0x1B),
-		b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
-	b43_phy_write(dev, B43_PHY_OFDM(0x82),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
-	b43_radio_write16(dev, 0x0009,
-		b43_radio_read16(dev, 0x0009) | 0x0080);
-	b43_radio_write16(dev, 0x0012,
-		(b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+	b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
+	b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
+	b43_radio_set(dev, 0x0009, 0x0080);
+	b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
 	b43_wa_initgains(dev);
 	b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
 	b = b43_phy_read(dev, B43_PHY_PWRDOWN);
 	b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
-	b43_radio_write16(dev, 0x0004,
-		b43_radio_read16(dev, 0x0004) | 0x0004);
+	b43_radio_set(dev, 0x0004, 0x0004);
 	for (i = 0x10; i <= 0x20; i++) {
 		b43_radio_write16(dev, 0x0013, i);
 		curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
@@ -252,8 +234,7 @@ static void b43_phy_ww(struct b43_wldev
 			best_s = curr_s;
 	}
 	b43_phy_write(dev, B43_PHY_PWRDOWN, b);
-	b43_radio_write16(dev, 0x0004,
-		b43_radio_read16(dev, 0x0004) & 0xFFFB);
+	b43_radio_mask(dev, 0x0004, 0xFFFB);
 	b43_radio_write16(dev, 0x0013, best_s);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
 	b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
@@ -261,14 +242,10 @@ static void b43_phy_ww(struct b43_wldev
 	b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
 	b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
 	b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
-	b43_phy_write(dev, B43_PHY_OFDM(0xBB),
-		(b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
-	b43_phy_write(dev, B43_PHY_OFDM61,
-		(b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
-	b43_phy_write(dev, B43_PHY_OFDM(0x13),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
-	b43_phy_write(dev, B43_PHY_OFDM(0x14),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
+	b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
 	for (i = 0; i < 6; i++)
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
@@ -276,8 +253,7 @@ static void b43_phy_ww(struct b43_wldev
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
 	b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
-	b43_phy_write(dev, B43_PHY_CRS0,
-		b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+	b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
 }
 
 static void hardware_pctl_init_aphy(struct b43_wldev *dev)
@@ -300,26 +276,21 @@ void b43_phy_inita(struct b43_wldev *dev
 
 	if (phy->rev >= 6) {
 		if (phy->type == B43_PHYTYPE_A)
-			b43_phy_write(dev, B43_PHY_OFDM(0x1B),
-				b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
+			b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
 		if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
-			b43_phy_write(dev, B43_PHY_ENCORE,
-				b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
+			b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
 		else
-			b43_phy_write(dev, B43_PHY_ENCORE,
-				b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
+			b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
 	}
 
 	b43_wa_all(dev);
 
 	if (phy->type == B43_PHYTYPE_A) {
 		if (phy->gmode && (phy->rev < 3))
-			b43_phy_write(dev, 0x0034,
-				b43_phy_read(dev, 0x0034) | 0x0001);
+			b43_phy_set(dev, 0x0034, 0x0001);
 		b43_phy_rssiagc(dev, 0);
 
-		b43_phy_write(dev, B43_PHY_CRS0,
-			b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+		b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
 
 		b43_radio_init2060(dev);
 
@@ -339,9 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev
 
 	if ((phy->type == B43_PHYTYPE_G) &&
 	    (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
-		b43_phy_write(dev, B43_PHY_OFDM(0x6E),
-				  (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
-				   & 0xE000) | 0x3CF);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
 	}
 }
 
@@ -520,14 +489,14 @@ static void b43_aphy_op_software_rfkill(
 			return;
 		b43_radio_write16(dev, 0x0004, 0x00C0);
 		b43_radio_write16(dev, 0x0005, 0x0008);
-		b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
-		b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
+		b43_phy_mask(dev, 0x0010, 0xFFF7);
+		b43_phy_mask(dev, 0x0011, 0xFFF7);
 		b43_radio_init2060(dev);
 	} else {
 		b43_radio_write16(dev, 0x0004, 0x00FF);
 		b43_radio_write16(dev, 0x0005, 0x00FB);
-		b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
-		b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
+		b43_phy_set(dev, 0x0010, 0x0008);
+		b43_phy_set(dev, 0x0011, 0x0008);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_common.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_common.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -131,12 +131,16 @@ void b43_radio_lock(struct b43_wldev *de
 {
 	u32 macctl;
 
+#if B43_DEBUG
+	B43_WARN_ON(dev->phy.radio_locked);
+	dev->phy.radio_locked = 1;
+#endif
+
 	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
 	macctl |= B43_MACCTL_RADIOLOCK;
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
-	/* Commit the write and wait for the device
-	 * to exit any radio register access. */
+	/* Commit the write and wait for the firmware
+	 * to finish any radio register access. */
 	b43_read32(dev, B43_MMIO_MACCTL);
 	udelay(10);
 }
@@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *
 {
 	u32 macctl;
 
+#if B43_DEBUG
+	B43_WARN_ON(!dev->phy.radio_locked);
+	dev->phy.radio_locked = 0;
+#endif
+
 	/* Commit any write */
 	b43_read16(dev, B43_MMIO_PHY_VER);
 	/* unlock */
 	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
 	macctl &= ~B43_MACCTL_RADIOLOCK;
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_common.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_common.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_common.h	2009-06-09 23:05:27.000000000 -0400
@@ -245,8 +245,10 @@ struct b43_phy {
 	atomic_t txerr_cnt;
 
 #ifdef CONFIG_B43_DEBUG
-	/* PHY registers locked by b43_phy_lock()? */
+	/* PHY registers locked (w.r.t. firmware) */
 	bool phy_locked;
+	/* Radio registers locked (w.r.t. firmware) */
+	bool radio_locked;
 #endif /* B43_DEBUG */
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_g.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_g.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_g.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_g.c	2009-06-09 23:05:27.000000000 -0400
@@ -204,13 +204,9 @@ void b43_gphy_set_baseband_attenuation(s
 						 & 0xFFF0) |
 			    baseband_attenuation);
 	} else if (phy->analog > 1) {
-		b43_phy_write(dev, B43_PHY_DACCTL,
-			      (b43_phy_read(dev, B43_PHY_DACCTL)
-			       & 0xFFC3) | (baseband_attenuation << 2));
+		b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFFC3, (baseband_attenuation << 2));
 	} else {
-		b43_phy_write(dev, B43_PHY_DACCTL,
-			      (b43_phy_read(dev, B43_PHY_DACCTL)
-			       & 0xFF87) | (baseband_attenuation << 3));
+		b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFF87, (baseband_attenuation << 3));
 	}
 }
 
@@ -252,17 +248,13 @@ static void b43_set_txpower_g(struct b43
 		b43_radio_write16(dev, 0x43,
 				  (rf & 0x000F) | (tx_control & 0x0070));
 	} else {
-		b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
-					      & 0xFFF0) | (rf & 0x000F));
-		b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
-					      & ~0x0070) | (tx_control &
-							    0x0070));
+		b43_radio_maskset(dev, 0x43, 0xFFF0, (rf & 0x000F));
+		b43_radio_maskset(dev, 0x52, ~0x0070, (tx_control & 0x0070));
 	}
 	if (has_tx_magnification(phy)) {
 		b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
 	} else {
-		b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
-					      & 0xFFF0) | (tx_bias & 0x000F));
+		b43_radio_maskset(dev, 0x52, 0xFFF0, (tx_bias & 0x000F));
 	}
 	b43_lo_g_adjust(dev);
 }
@@ -337,12 +329,9 @@ static void b43_set_all_gains(struct b43
 
 	if (third != -1) {
 		tmp = ((u16) third << 14) | ((u16) third << 6);
-		b43_phy_write(dev, 0x04A0,
-			      (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
-		b43_phy_write(dev, 0x04A1,
-			      (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
-		b43_phy_write(dev, 0x04A2,
-			      (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
+		b43_phy_maskset(dev, 0x04A0, 0xBFBF, tmp);
+		b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
+		b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
 	}
 	b43_dummy_transmission(dev);
 }
@@ -373,12 +362,9 @@ static void b43_set_original_gains(struc
 	for (i = start; i < end; i++)
 		b43_ofdmtab_write16(dev, table, i, i - start);
 
-	b43_phy_write(dev, 0x04A0,
-		      (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
-	b43_phy_write(dev, 0x04A1,
-		      (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
-	b43_phy_write(dev, 0x04A2,
-		      (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
+	b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
+	b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
+	b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
 	b43_dummy_transmission(dev);
 }
 
@@ -454,13 +440,11 @@ static void b43_calc_nrssi_offset(struct
 	backup[10] = b43_radio_read16(dev, 0x007A);
 	backup[11] = b43_radio_read16(dev, 0x0043);
 
-	b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
-	b43_phy_write(dev, 0x0001,
-		      (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
-	b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
-	b43_phy_write(dev, 0x0812,
-		      (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
-	b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
+	b43_phy_mask(dev, 0x0429, 0x7FFF);
+	b43_phy_maskset(dev, 0x0001, 0x3FFF, 0x4000);
+	b43_phy_set(dev, 0x0811, 0x000C);
+	b43_phy_maskset(dev, 0x0812, 0xFFF3, 0x0004);
+	b43_phy_mask(dev, 0x0802, ~(0x1 | 0x2));
 	if (phy->rev >= 6) {
 		backup[12] = b43_phy_read(dev, 0x002E);
 		backup[13] = b43_phy_read(dev, 0x002F);
@@ -475,13 +459,13 @@ static void b43_calc_nrssi_offset(struct
 		b43_phy_write(dev, 0x002F, 0);
 		b43_phy_write(dev, 0x080F, 0);
 		b43_phy_write(dev, 0x0810, 0);
-		b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
-		b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
-		b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
-		b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
+		b43_phy_set(dev, 0x0478, 0x0100);
+		b43_phy_set(dev, 0x0801, 0x0040);
+		b43_phy_set(dev, 0x0060, 0x0040);
+		b43_phy_set(dev, 0x0014, 0x0200);
 	}
-	b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
-	b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
+	b43_radio_set(dev, 0x007A, 0x0070);
+	b43_radio_set(dev, 0x007A, 0x0080);
 	udelay(30);
 
 	v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
@@ -501,40 +485,31 @@ static void b43_calc_nrssi_offset(struct
 		if (saved == 0xFFFF)
 			saved = 4;
 	} else {
-		b43_radio_write16(dev, 0x007A,
-				  b43_radio_read16(dev, 0x007A) & 0x007F);
+		b43_radio_mask(dev, 0x007A, 0x007F);
 		if (phy->rev != 1) {	/* Not in specs, but needed to prevent PPC machine check */
-			b43_phy_write(dev, 0x0814,
-				      b43_phy_read(dev, 0x0814) | 0x0001);
-			b43_phy_write(dev, 0x0815,
-				      b43_phy_read(dev, 0x0815) & 0xFFFE);
+			b43_phy_set(dev, 0x0814, 0x0001);
+			b43_phy_mask(dev, 0x0815, 0xFFFE);
 		}
-		b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
-		b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
-		b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
-		b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
+		b43_phy_set(dev, 0x0811, 0x000C);
+		b43_phy_set(dev, 0x0812, 0x000C);
+		b43_phy_set(dev, 0x0811, 0x0030);
+		b43_phy_set(dev, 0x0812, 0x0030);
 		b43_phy_write(dev, 0x005A, 0x0480);
 		b43_phy_write(dev, 0x0059, 0x0810);
 		b43_phy_write(dev, 0x0058, 0x000D);
 		if (phy->rev == 0) {
 			b43_phy_write(dev, 0x0003, 0x0122);
 		} else {
-			b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
-				      | 0x2000);
+			b43_phy_set(dev, 0x000A, 0x2000);
 		}
 		if (phy->rev != 1) {	/* Not in specs, but needed to prevent PPC machine check */
-			b43_phy_write(dev, 0x0814,
-				      b43_phy_read(dev, 0x0814) | 0x0004);
-			b43_phy_write(dev, 0x0815,
-				      b43_phy_read(dev, 0x0815) & 0xFFFB);
+			b43_phy_set(dev, 0x0814, 0x0004);
+			b43_phy_mask(dev, 0x0815, 0xFFFB);
 		}
-		b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
-			      | 0x0040);
-		b43_radio_write16(dev, 0x007A,
-				  b43_radio_read16(dev, 0x007A) | 0x000F);
+		b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
+		b43_radio_set(dev, 0x007A, 0x000F);
 		b43_set_all_gains(dev, 3, 0, 1);
-		b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
-						& 0x00F0) | 0x000F);
+		b43_radio_maskset(dev, 0x0043, 0x00F0, 0x000F);
 		udelay(30);
 		v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
 		if (v47F >= 0x20)
@@ -576,7 +551,7 @@ static void b43_calc_nrssi_offset(struct
 	b43_radio_write16(dev, 0x0043, backup[11]);
 	b43_radio_write16(dev, 0x007A, backup[10]);
 	b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
-	b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
+	b43_phy_set(dev, 0x0429, 0x8000);
 	b43_set_original_gains(dev);
 	if (phy->rev >= 6) {
 		b43_phy_write(dev, 0x0801, backup[16]);
@@ -604,9 +579,8 @@ static void b43_calc_nrssi_slope(struct
 	if (phy->radio_rev == 8)
 		b43_calc_nrssi_offset(dev);
 
-	b43_phy_write(dev, B43_PHY_G_CRS,
-		      b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
-	b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
+	b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
+	b43_phy_mask(dev, 0x0802, 0xFFFC);
 	backup[7] = b43_read16(dev, 0x03E2);
 	b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
 	backup[0] = b43_radio_read16(dev, 0x007A);
@@ -633,66 +607,44 @@ static void b43_calc_nrssi_slope(struct
 		case 4:
 		case 6:
 		case 7:
-			b43_phy_write(dev, 0x0478,
-				      b43_phy_read(dev, 0x0478)
-				      | 0x0100);
-			b43_phy_write(dev, 0x0801,
-				      b43_phy_read(dev, 0x0801)
-				      | 0x0040);
+			b43_phy_set(dev, 0x0478, 0x0100);
+			b43_phy_set(dev, 0x0801, 0x0040);
 			break;
 		case 3:
 		case 5:
-			b43_phy_write(dev, 0x0801,
-				      b43_phy_read(dev, 0x0801)
-				      & 0xFFBF);
+			b43_phy_mask(dev, 0x0801, 0xFFBF);
 			break;
 		}
-		b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
-			      | 0x0040);
-		b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
-			      | 0x0200);
+		b43_phy_set(dev, 0x0060, 0x0040);
+		b43_phy_set(dev, 0x0014, 0x0200);
 	}
-	b43_radio_write16(dev, 0x007A,
-			  b43_radio_read16(dev, 0x007A) | 0x0070);
+	b43_radio_set(dev, 0x007A, 0x0070);
 	b43_set_all_gains(dev, 0, 8, 0);
-	b43_radio_write16(dev, 0x007A,
-			  b43_radio_read16(dev, 0x007A) & 0x00F7);
+	b43_radio_mask(dev, 0x007A, 0x00F7);
 	if (phy->rev >= 2) {
-		b43_phy_write(dev, 0x0811,
-			      (b43_phy_read(dev, 0x0811) & 0xFFCF) |
-			      0x0030);
-		b43_phy_write(dev, 0x0812,
-			      (b43_phy_read(dev, 0x0812) & 0xFFCF) |
-			      0x0010);
+		b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0030);
+		b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0010);
 	}
-	b43_radio_write16(dev, 0x007A,
-			  b43_radio_read16(dev, 0x007A) | 0x0080);
+	b43_radio_set(dev, 0x007A, 0x0080);
 	udelay(20);
 
 	nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
 	if (nrssi0 >= 0x0020)
 		nrssi0 -= 0x0040;
 
-	b43_radio_write16(dev, 0x007A,
-			  b43_radio_read16(dev, 0x007A) & 0x007F);
+	b43_radio_mask(dev, 0x007A, 0x007F);
 	if (phy->rev >= 2) {
-		b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
-					    & 0xFF9F) | 0x0040);
+		b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
 	}
 
 	b43_write16(dev, B43_MMIO_CHANNEL_EXT,
 		    b43_read16(dev, B43_MMIO_CHANNEL_EXT)
 		    | 0x2000);
-	b43_radio_write16(dev, 0x007A,
-			  b43_radio_read16(dev, 0x007A) | 0x000F);
+	b43_radio_set(dev, 0x007A, 0x000F);
 	b43_phy_write(dev, 0x0015, 0xF330);
 	if (phy->rev >= 2) {
-		b43_phy_write(dev, 0x0812,
-			      (b43_phy_read(dev, 0x0812) & 0xFFCF) |
-			      0x0020);
-		b43_phy_write(dev, 0x0811,
-			      (b43_phy_read(dev, 0x0811) & 0xFFCF) |
-			      0x0020);
+		b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0020);
+		b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0020);
 	}
 
 	b43_set_all_gains(dev, 3, 0, 1);
@@ -726,10 +678,8 @@ static void b43_calc_nrssi_slope(struct
 		b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
 	}
 	if (phy->rev >= 2) {
-		b43_phy_write(dev, 0x0812,
-			      b43_phy_read(dev, 0x0812) & 0xFFCF);
-		b43_phy_write(dev, 0x0811,
-			      b43_phy_read(dev, 0x0811) & 0xFFCF);
+		b43_phy_mask(dev, 0x0812, 0xFFCF);
+		b43_phy_mask(dev, 0x0811, 0xFFCF);
 	}
 
 	b43_radio_write16(dev, 0x007A, backup[0]);
@@ -743,11 +693,9 @@ static void b43_calc_nrssi_slope(struct
 	b43_phy_write(dev, 0x0059, backup[5]);
 	b43_phy_write(dev, 0x0058, backup[6]);
 	b43_synth_pu_workaround(dev, phy->channel);
-	b43_phy_write(dev, 0x0802,
-		      b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
+	b43_phy_set(dev, 0x0802, (0x0001 | 0x0002));
 	b43_set_original_gains(dev);
-	b43_phy_write(dev, B43_PHY_G_CRS,
-		      b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+	b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
 	if (phy->rev >= 3) {
 		b43_phy_write(dev, 0x0801, backup[14]);
 		b43_phy_write(dev, 0x0060, backup[15]);
@@ -774,13 +722,9 @@ static void b43_calc_nrssi_threshold(str
 		if (tmp16 >= 0x20)
 			tmp16 -= 0x40;
 		if (tmp16 < 3) {
-			b43_phy_write(dev, 0x048A,
-				      (b43_phy_read(dev, 0x048A)
-				       & 0xF000) | 0x09EB);
+			b43_phy_maskset(dev, 0x048A, 0xF000, 0x09EB);
 		} else {
-			b43_phy_write(dev, 0x048A,
-				      (b43_phy_read(dev, 0x048A)
-				       & 0xF000) | 0x0AED);
+			b43_phy_maskset(dev, 0x048A, 0xF000, 0x0AED);
 		}
 	} else {
 		if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
@@ -823,7 +767,7 @@ static void b43_calc_nrssi_threshold(str
  * interference mitigation code.
  * It is save to restore values in random order.
  */
-static void _stack_save(u32 * _stackptr, size_t * stackidx,
+static void _stack_save(u32 *_stackptr, size_t *stackidx,
 			u8 id, u16 offset, u16 value)
 {
 	u32 *stackptr = &(_stackptr[*stackidx]);
@@ -837,7 +781,7 @@ static void _stack_save(u32 * _stackptr,
 	B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
 }
 
-static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
+static u16 _stack_restore(u32 *stackptr, u8 id, u16 offset)
 {
 	size_t i;
 
@@ -901,11 +845,8 @@ b43_radio_interference_mitigation_enable
 	switch (mode) {
 	case B43_INTERFMODE_NONWLAN:
 		if (phy->rev != 1) {
-			b43_phy_write(dev, 0x042B,
-				      b43_phy_read(dev, 0x042B) | 0x0800);
-			b43_phy_write(dev, B43_PHY_G_CRS,
-				      b43_phy_read(dev,
-						   B43_PHY_G_CRS) & ~0x4000);
+			b43_phy_set(dev, 0x042B, 0x0800);
+			b43_phy_mask(dev, B43_PHY_G_CRS, ~0x4000);
 			break;
 		}
 		radio_stacksave(0x0078);
@@ -924,26 +865,19 @@ b43_radio_interference_mitigation_enable
 		phy_stacksave(0x0406);
 		b43_phy_write(dev, 0x0406, 0x7E28);
 
-		b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
-		b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
-			      b43_phy_read(dev,
-					   B43_PHY_RADIO_BITFIELD) | 0x1000);
+		b43_phy_set(dev, 0x042B, 0x0800);
+		b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, 0x1000);
 
 		phy_stacksave(0x04A0);
-		b43_phy_write(dev, 0x04A0,
-			      (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
+		b43_phy_maskset(dev, 0x04A0, 0xC0C0, 0x0008);
 		phy_stacksave(0x04A1);
-		b43_phy_write(dev, 0x04A1,
-			      (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
+		b43_phy_maskset(dev, 0x04A1, 0xC0C0, 0x0605);
 		phy_stacksave(0x04A2);
-		b43_phy_write(dev, 0x04A2,
-			      (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
+		b43_phy_maskset(dev, 0x04A2, 0xC0C0, 0x0204);
 		phy_stacksave(0x04A8);
-		b43_phy_write(dev, 0x04A8,
-			      (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
+		b43_phy_maskset(dev, 0x04A8, 0xC0C0, 0x0803);
 		phy_stacksave(0x04AB);
-		b43_phy_write(dev, 0x04AB,
-			      (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
+		b43_phy_maskset(dev, 0x04AB, 0xC0C0, 0x0605);
 
 		phy_stacksave(0x04A7);
 		b43_phy_write(dev, 0x04A7, 0x0002);
@@ -999,12 +933,8 @@ b43_radio_interference_mitigation_enable
 		phy_stacksave(0x042B);
 		phy_stacksave(0x048C);
 
-		b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
-			      b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
-			      & ~0x1000);
-		b43_phy_write(dev, B43_PHY_G_CRS,
-			      (b43_phy_read(dev, B43_PHY_G_CRS)
-			       & 0xFFFC) | 0x0002);
+		b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~0x1000);
+		b43_phy_maskset(dev, B43_PHY_G_CRS, 0xFFFC, 0x0002);
 
 		b43_phy_write(dev, 0x0033, 0x0800);
 		b43_phy_write(dev, 0x04A3, 0x2027);
@@ -1013,8 +943,7 @@ b43_radio_interference_mitigation_enable
 		b43_phy_write(dev, 0x04AA, 0x1CA8);
 		b43_phy_write(dev, 0x04AC, 0x287A);
 
-		b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
-					    & 0xFFC0) | 0x001A);
+		b43_phy_maskset(dev, 0x04A0, 0xFFC0, 0x001A);
 		b43_phy_write(dev, 0x04A7, 0x000D);
 
 		if (phy->rev < 2) {
@@ -1027,65 +956,41 @@ b43_radio_interference_mitigation_enable
 			b43_phy_write(dev, 0x04C1, 0x0059);
 		}
 
-		b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
-					    & 0xC0FF) | 0x1800);
-		b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
-					    & 0xFFC0) | 0x0015);
-		b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
-					    & 0xCFFF) | 0x1000);
-		b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
-					    & 0xF0FF) | 0x0A00);
-		b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
-					    & 0xCFFF) | 0x1000);
-		b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
-					    & 0xF0FF) | 0x0800);
-		b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
-					    & 0xFFCF) | 0x0010);
-		b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
-					    & 0xFFF0) | 0x0005);
-		b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
-					    & 0xFFCF) | 0x0010);
-		b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
-					    & 0xFFF0) | 0x0006);
-		b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
-					    & 0xF0FF) | 0x0800);
-		b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
-					    & 0xF0FF) | 0x0500);
-		b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
-					    & 0xFFF0) | 0x000B);
+		b43_phy_maskset(dev, 0x04A1, 0xC0FF, 0x1800);
+		b43_phy_maskset(dev, 0x04A1, 0xFFC0, 0x0015);
+		b43_phy_maskset(dev, 0x04A8, 0xCFFF, 0x1000);
+		b43_phy_maskset(dev, 0x04A8, 0xF0FF, 0x0A00);
+		b43_phy_maskset(dev, 0x04AB, 0xCFFF, 0x1000);
+		b43_phy_maskset(dev, 0x04AB, 0xF0FF, 0x0800);
+		b43_phy_maskset(dev, 0x04AB, 0xFFCF, 0x0010);
+		b43_phy_maskset(dev, 0x04AB, 0xFFF0, 0x0005);
+		b43_phy_maskset(dev, 0x04A8, 0xFFCF, 0x0010);
+		b43_phy_maskset(dev, 0x04A8, 0xFFF0, 0x0006);
+		b43_phy_maskset(dev, 0x04A2, 0xF0FF, 0x0800);
+		b43_phy_maskset(dev, 0x04A0, 0xF0FF, 0x0500);
+		b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B);
 
 		if (phy->rev >= 3) {
-			b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
-				      & ~0x8000);
-			b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
-						    & 0x8000) | 0x36D8);
-			b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
-						    & 0x8000) | 0x36D8);
-			b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
-						    & 0xFE00) | 0x016D);
+			b43_phy_mask(dev, 0x048A, (u16)~0x8000);
+			b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8);
+			b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8);
+			b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D);
 		} else {
-			b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
-				      | 0x1000);
-			b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
-						    & 0x9FFF) | 0x2000);
+			b43_phy_set(dev, 0x048A, 0x1000);
+			b43_phy_maskset(dev, 0x048A, 0x9FFF, 0x2000);
 			b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
 		}
 		if (phy->rev >= 2) {
-			b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
-				      | 0x0800);
+			b43_phy_set(dev, 0x042B, 0x0800);
 		}
-		b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
-					    & 0xF0FF) | 0x0200);
+		b43_phy_maskset(dev, 0x048C, 0xF0FF, 0x0200);
 		if (phy->rev == 2) {
-			b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
-						    & 0xFF00) | 0x007F);
-			b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
-						    & 0x00FF) | 0x1300);
+			b43_phy_maskset(dev, 0x04AE, 0xFF00, 0x007F);
+			b43_phy_maskset(dev, 0x04AD, 0x00FF, 0x1300);
 		} else if (phy->rev >= 6) {
 			b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
 			b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
-			b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
-				      & 0x00FF);
+			b43_phy_mask(dev, 0x04AD, 0x00FF);
 		}
 		b43_calc_nrssi_slope(dev);
 		break;
@@ -1104,24 +1009,18 @@ b43_radio_interference_mitigation_disabl
 	switch (mode) {
 	case B43_INTERFMODE_NONWLAN:
 		if (phy->rev != 1) {
-			b43_phy_write(dev, 0x042B,
-				      b43_phy_read(dev, 0x042B) & ~0x0800);
-			b43_phy_write(dev, B43_PHY_G_CRS,
-				      b43_phy_read(dev,
-						   B43_PHY_G_CRS) | 0x4000);
+			b43_phy_mask(dev, 0x042B, ~0x0800);
+			b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
 			break;
 		}
 		radio_stackrestore(0x0078);
 		b43_calc_nrssi_threshold(dev);
 		phy_stackrestore(0x0406);
-		b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
+		b43_phy_mask(dev, 0x042B, ~0x0800);
 		if (!dev->bad_frames_preempt) {
-			b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
-				      b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
-				      & ~(1 << 11));
+			b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~(1 << 11));
 		}
-		b43_phy_write(dev, B43_PHY_G_CRS,
-			      b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
+		b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
 		phy_stackrestore(0x04A0);
 		phy_stackrestore(0x04A1);
 		phy_stackrestore(0x04A2);
@@ -1389,17 +1288,10 @@ static u16 b43_radio_init2050(struct b43
 		sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
 		sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
 
-		b43_phy_write(dev, B43_PHY_ANALOGOVER,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVER)
-			      | 0x0003);
-		b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
-			      & 0xFFFC);
-		b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
-			      & 0x7FFF);
-		b43_phy_write(dev, B43_PHY_CLASSCTL,
-			      b43_phy_read(dev, B43_PHY_CLASSCTL)
-			      & 0xFFFC);
+		b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+		b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
+		b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+		b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
 		if (has_loopback_gain(phy)) {
 			sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
 			sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
@@ -1420,8 +1312,7 @@ static u16 b43_radio_init2050(struct b43
 	b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
 
 	sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
-	b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
-		      & 0xFF7F);
+	b43_phy_mask(dev, B43_PHY_SYNCCTL, 0xFF7F);
 	sav.reg_3E6 = b43_read16(dev, 0x3E6);
 	sav.reg_3F4 = b43_read16(dev, 0x3F4);
 
@@ -1429,9 +1320,7 @@ static u16 b43_radio_init2050(struct b43
 		b43_write16(dev, 0x03E6, 0x0122);
 	} else {
 		if (phy->analog >= 2) {
-			b43_phy_write(dev, B43_PHY_CCK(0x03),
-				      (b43_phy_read(dev, B43_PHY_CCK(0x03))
-				       & 0xFFBF) | 0x40);
+			b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFFBF, 0x40);
 		}
 		b43_write16(dev, B43_MMIO_CHANNEL_EXT,
 			    (b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
@@ -1454,14 +1343,12 @@ static u16 b43_radio_init2050(struct b43
 						   LPD(0, 0, 1)));
 	}
 	b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
-	b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
-			  | 0x0004);
+	b43_radio_set(dev, 0x51, 0x0004);
 	if (phy->radio_rev == 8) {
 		b43_radio_write16(dev, 0x43, 0x1F);
 	} else {
 		b43_radio_write16(dev, 0x52, 0);
-		b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
-					      & 0xFFF0) | 0x0009);
+		b43_radio_maskset(dev, 0x43, 0xFFF0, 0x0009);
 	}
 	b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
 
@@ -1610,8 +1497,7 @@ static void b43_phy_initb5(struct b43_wl
 	u8 old_channel;
 
 	if (phy->analog == 1) {
-		b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
-				  | 0x0050);
+		b43_radio_set(dev, 0x007A, 0x0050);
 	}
 	if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
 	    (bus->boardinfo.type != SSB_BOARD_BU4306)) {
@@ -1621,39 +1507,29 @@ static void b43_phy_initb5(struct b43_wl
 			value += 0x202;
 		}
 	}
-	b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
-		      | 0x0700);
+	b43_phy_maskset(dev, 0x0035, 0xF0FF, 0x0700);
 	if (phy->radio_ver == 0x2050)
 		b43_phy_write(dev, 0x0038, 0x0667);
 
 	if (phy->gmode || phy->rev >= 2) {
 		if (phy->radio_ver == 0x2050) {
-			b43_radio_write16(dev, 0x007A,
-					  b43_radio_read16(dev, 0x007A)
-					  | 0x0020);
-			b43_radio_write16(dev, 0x0051,
-					  b43_radio_read16(dev, 0x0051)
-					  | 0x0004);
+			b43_radio_set(dev, 0x007A, 0x0020);
+			b43_radio_set(dev, 0x0051, 0x0004);
 		}
 		b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
 
-		b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
-		b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+		b43_phy_set(dev, 0x0802, 0x0100);
+		b43_phy_set(dev, 0x042B, 0x2000);
 
 		b43_phy_write(dev, 0x001C, 0x186A);
 
-		b43_phy_write(dev, 0x0013,
-			      (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
-		b43_phy_write(dev, 0x0035,
-			      (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
-		b43_phy_write(dev, 0x005D,
-			      (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
+		b43_phy_maskset(dev, 0x0013, 0x00FF, 0x1900);
+		b43_phy_maskset(dev, 0x0035, 0xFFC0, 0x0064);
+		b43_phy_maskset(dev, 0x005D, 0xFF80, 0x000A);
 	}
 
 	if (dev->bad_frames_preempt) {
-		b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
-			      b43_phy_read(dev,
-					   B43_PHY_RADIO_BITFIELD) | (1 << 11));
+		b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, (1 << 11));
 	}
 
 	if (phy->analog == 1) {
@@ -1695,7 +1571,7 @@ static void b43_phy_initb5(struct b43_wl
 	b43_radio_write16(dev, 0x005B, 0x007B);
 	b43_radio_write16(dev, 0x005C, 0x00B0);
 
-	b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
+	b43_radio_set(dev, 0x007A, 0x0007);
 
 	b43_gphy_channel_switch(dev, old_channel, 0);
 
@@ -1771,12 +1647,10 @@ static void b43_phy_initb6(struct b43_wl
 		val += 0x0202;
 	}
 	if (phy->type == B43_PHYTYPE_G) {
-		b43_radio_write16(dev, 0x007A,
-				  b43_radio_read16(dev, 0x007A) | 0x0020);
-		b43_radio_write16(dev, 0x0051,
-				  b43_radio_read16(dev, 0x0051) | 0x0004);
-		b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
-		b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+		b43_radio_set(dev, 0x007A, 0x0020);
+		b43_radio_set(dev, 0x0051, 0x0004);
+		b43_phy_set(dev, 0x0802, 0x0100);
+		b43_phy_set(dev, 0x042B, 0x2000);
 		b43_phy_write(dev, 0x5B, 0);
 		b43_phy_write(dev, 0x5C, 0);
 	}
@@ -1801,8 +1675,7 @@ static void b43_phy_initb6(struct b43_wl
 		b43_radio_write16(dev, 0x5B, 0x7B);
 		b43_radio_write16(dev, 0x5C, 0xB0);
 	}
-	b43_radio_write16(dev, 0x007A,
-			  (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
+	b43_radio_maskset(dev, 0x007A, 0x00F8, 0x0007);
 
 	b43_gphy_channel_switch(dev, old_channel, 0);
 
@@ -1814,19 +1687,16 @@ static void b43_phy_initb6(struct b43_wl
 	b43_phy_write(dev, 0x0038, 0x0668);
 	b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
 	if (phy->radio_rev <= 5) {
-		b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
-					  & 0xFF80) | 0x0003);
+		b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
 	}
 	if (phy->radio_rev <= 2)
 		b43_radio_write16(dev, 0x005D, 0x000D);
 
 	if (phy->analog == 4) {
 		b43_write16(dev, 0x3E4, 9);
-		b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
-			      & 0x0FFF);
+		b43_phy_mask(dev, 0x61, 0x0FFF);
 	} else {
-		b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
-			      | 0x0004);
+		b43_phy_maskset(dev, 0x0002, 0xFFC0, 0x0004);
 	}
 	if (phy->type == B43_PHYTYPE_B)
 		B43_WARN_ON(1);
@@ -1868,63 +1738,39 @@ static void b43_calc_loopback_gain(struc
 	backup_radio[1] = b43_radio_read16(dev, 0x43);
 	backup_radio[2] = b43_radio_read16(dev, 0x7A);
 
-	b43_phy_write(dev, B43_PHY_CRS0,
-		      b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
-	b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
-		      b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
-	b43_phy_write(dev, B43_PHY_RFOVER,
-		      b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
-	b43_phy_write(dev, B43_PHY_RFOVERVAL,
-		      b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
-	b43_phy_write(dev, B43_PHY_RFOVER,
-		      b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
-	b43_phy_write(dev, B43_PHY_RFOVERVAL,
-		      b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
+	b43_phy_mask(dev, B43_PHY_CRS0, 0x3FFF);
+	b43_phy_set(dev, B43_PHY_CCKBBANDCFG, 0x8000);
+	b43_phy_set(dev, B43_PHY_RFOVER, 0x0002);
+	b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFD);
+	b43_phy_set(dev, B43_PHY_RFOVER, 0x0001);
+	b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFE);
 	if (phy->rev != 1) {	/* Not in specs, but needed to prevent PPC machine check */
-		b43_phy_write(dev, B43_PHY_ANALOGOVER,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
-		b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
-			      b43_phy_read(dev,
-					   B43_PHY_ANALOGOVERVAL) & 0xFFFE);
-		b43_phy_write(dev, B43_PHY_ANALOGOVER,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
-		b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
-			      b43_phy_read(dev,
-					   B43_PHY_ANALOGOVERVAL) & 0xFFFD);
+		b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0001);
+		b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFE);
+		b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0002);
+		b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFD);
 	}
-	b43_phy_write(dev, B43_PHY_RFOVER,
-		      b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
-	b43_phy_write(dev, B43_PHY_RFOVERVAL,
-		      b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
-	b43_phy_write(dev, B43_PHY_RFOVER,
-		      b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
-	b43_phy_write(dev, B43_PHY_RFOVERVAL,
-		      (b43_phy_read(dev, B43_PHY_RFOVERVAL)
-		       & 0xFFCF) | 0x10);
+	b43_phy_set(dev, B43_PHY_RFOVER, 0x000C);
+	b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x000C);
+	b43_phy_set(dev, B43_PHY_RFOVER, 0x0030);
+	b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xFFCF, 0x10);
 
 	b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
 	b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
 	b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
 
-	b43_phy_write(dev, B43_PHY_CCK(0x0A),
-		      b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
+	b43_phy_set(dev, B43_PHY_CCK(0x0A), 0x2000);
 	if (phy->rev != 1) {	/* Not in specs, but needed to prevent PPC machine check */
-		b43_phy_write(dev, B43_PHY_ANALOGOVER,
-			      b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
-		b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
-			      b43_phy_read(dev,
-					   B43_PHY_ANALOGOVERVAL) & 0xFFFB);
+		b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0004);
+		b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFB);
 	}
-	b43_phy_write(dev, B43_PHY_CCK(0x03),
-		      (b43_phy_read(dev, B43_PHY_CCK(0x03))
-		       & 0xFF9F) | 0x40);
+	b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFF9F, 0x40);
 
 	if (phy->radio_rev == 8) {
 		b43_radio_write16(dev, 0x43, 0x000F);
 	} else {
 		b43_radio_write16(dev, 0x52, 0);
-		b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
-					      & 0xFFF0) | 0x9);
+		b43_radio_maskset(dev, 0x43, 0xFFF0, 0x9);
 	}
 	b43_gphy_set_baseband_attenuation(dev, 11);
 
@@ -1934,45 +1780,28 @@ static void b43_calc_loopback_gain(struc
 		b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
 	b43_phy_write(dev, B43_PHY_LO_CTL, 0);
 
-	b43_phy_write(dev, B43_PHY_CCK(0x2B),
-		      (b43_phy_read(dev, B43_PHY_CCK(0x2B))
-		       & 0xFFC0) | 0x01);
-	b43_phy_write(dev, B43_PHY_CCK(0x2B),
-		      (b43_phy_read(dev, B43_PHY_CCK(0x2B))
-		       & 0xC0FF) | 0x800);
+	b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xFFC0, 0x01);
+	b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xC0FF, 0x800);
 
-	b43_phy_write(dev, B43_PHY_RFOVER,
-		      b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
-	b43_phy_write(dev, B43_PHY_RFOVERVAL,
-		      b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
+	b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
+	b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
 
 	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
 		if (phy->rev >= 7) {
-			b43_phy_write(dev, B43_PHY_RFOVER,
-				      b43_phy_read(dev, B43_PHY_RFOVER)
-				      | 0x0800);
-			b43_phy_write(dev, B43_PHY_RFOVERVAL,
-				      b43_phy_read(dev, B43_PHY_RFOVERVAL)
-				      | 0x8000);
+			b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
+			b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
 		}
 	}
-	b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
-			  & 0x00F7);
+	b43_radio_mask(dev, 0x7A, 0x00F7);
 
 	j = 0;
 	loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
 	for (i = 0; i < loop_i_max; i++) {
 		for (j = 0; j < 16; j++) {
 			b43_radio_write16(dev, 0x43, i);
-			b43_phy_write(dev, B43_PHY_RFOVERVAL,
-				      (b43_phy_read(dev, B43_PHY_RFOVERVAL)
-				       & 0xF0FF) | (j << 8));
-			b43_phy_write(dev, B43_PHY_PGACTL,
-				      (b43_phy_read(dev, B43_PHY_PGACTL)
-				       & 0x0FFF) | 0xA000);
-			b43_phy_write(dev, B43_PHY_PGACTL,
-				      b43_phy_read(dev, B43_PHY_PGACTL)
-				      | 0xF000);
+			b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+			b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+			b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
 			udelay(20);
 			if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
 				goto exit_loop1;
@@ -1982,20 +1811,12 @@ static void b43_calc_loopback_gain(struc
 	loop1_outer_done = i;
 	loop1_inner_done = j;
 	if (j >= 8) {
-		b43_phy_write(dev, B43_PHY_RFOVERVAL,
-			      b43_phy_read(dev, B43_PHY_RFOVERVAL)
-			      | 0x30);
+		b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x30);
 		trsw_rx = 0x1B;
 		for (j = j - 8; j < 16; j++) {
-			b43_phy_write(dev, B43_PHY_RFOVERVAL,
-				      (b43_phy_read(dev, B43_PHY_RFOVERVAL)
-				       & 0xF0FF) | (j << 8));
-			b43_phy_write(dev, B43_PHY_PGACTL,
-				      (b43_phy_read(dev, B43_PHY_PGACTL)
-				       & 0x0FFF) | 0xA000);
-			b43_phy_write(dev, B43_PHY_PGACTL,
-				      b43_phy_read(dev, B43_PHY_PGACTL)
-				      | 0xF000);
+			b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+			b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+			b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
 			udelay(20);
 			trsw_rx -= 3;
 			if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
@@ -2046,34 +1867,24 @@ static void b43_hardware_pctl_early_init
 		return;
 	}
 
-	b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
+	b43_phy_mask(dev, 0x0036, 0xFEFF);
 	b43_phy_write(dev, 0x002F, 0x0202);
-	b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
-	b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
+	b43_phy_set(dev, 0x047C, 0x0002);
+	b43_phy_set(dev, 0x047A, 0xF000);
 	if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
-		b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
-					    & 0xFF0F) | 0x0010);
-		b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
-			      | 0x8000);
-		b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
-					    & 0xFFC0) | 0x0010);
+		b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
+		b43_phy_set(dev, 0x005D, 0x8000);
+		b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
 		b43_phy_write(dev, 0x002E, 0xC07F);
-		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
-			      | 0x0400);
+		b43_phy_set(dev, 0x0036, 0x0400);
 	} else {
-		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
-			      | 0x0200);
-		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
-			      | 0x0400);
-		b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
-			      & 0x7FFF);
-		b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
-			      & 0xFFFE);
-		b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
-					    & 0xFFC0) | 0x0010);
+		b43_phy_set(dev, 0x0036, 0x0200);
+		b43_phy_set(dev, 0x0036, 0x0400);
+		b43_phy_mask(dev, 0x005D, 0x7FFF);
+		b43_phy_mask(dev, 0x004F, 0xFFFE);
+		b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
 		b43_phy_write(dev, 0x002E, 0xC07F);
-		b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
-					    & 0xFF0F) | 0x0010);
+		b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
 	}
 }
 
@@ -2089,22 +1900,17 @@ static void b43_hardware_pctl_init_gphy(
 		return;
 	}
 
-	b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
-		      | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
-	b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
-		      | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+	b43_phy_maskset(dev, 0x0036, 0xFFC0, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+	b43_phy_maskset(dev, 0x0478, 0xFF00, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
 	b43_gphy_tssi_power_lt_init(dev);
 	b43_gphy_gain_lt_init(dev);
-	b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
+	b43_phy_mask(dev, 0x0060, 0xFFBF);
 	b43_phy_write(dev, 0x0014, 0x0000);
 
 	B43_WARN_ON(phy->rev < 6);
-	b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
-		      | 0x0800);
-	b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
-		      & 0xFEFF);
-	b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
-		      & 0xFFBF);
+	b43_phy_set(dev, 0x0478, 0x0800);
+	b43_phy_mask(dev, 0x0478, 0xFEFF);
+	b43_phy_mask(dev, 0x0801, 0xFFBF);
 
 	b43_gphy_dc_lt_init(dev, 1);
 
@@ -2139,9 +1945,7 @@ static void b43_phy_init_pctl(struct b43
 	b43_hardware_pctl_early_init(dev);
 	if (gphy->cur_idle_tssi == 0) {
 		if (phy->radio_ver == 0x2050 && phy->analog == 0) {
-			b43_radio_write16(dev, 0x0076,
-					  (b43_radio_read16(dev, 0x0076)
-					   & 0x00F7) | 0x0084);
+			b43_radio_maskset(dev, 0x0076, 0x00F7, 0x0084);
 		} else {
 			struct b43_rfatt rfatt;
 			struct b43_bbatt bbatt;
@@ -2174,9 +1978,7 @@ static void b43_phy_init_pctl(struct b43
 			}
 		}
 		if (phy->radio_ver == 0x2050 && phy->analog == 0) {
-			b43_radio_write16(dev, 0x0076,
-					  b43_radio_read16(dev, 0x0076)
-					  & 0xFF7B);
+			b43_radio_mask(dev, 0x0076, 0xFF7B);
 		} else {
 			b43_set_txpower_g(dev, &old_bbatt,
 					  &old_rfatt, old_tx_control);
@@ -2220,20 +2022,14 @@ static void b43_phy_initg(struct b43_wld
 			b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
 		}
 		if (tmp == 5) {
-			b43_phy_write(dev, B43_PHY_OFDM(0xCC),
-				      (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
-				       & 0x00FF) | 0x1F00);
+			b43_phy_maskset(dev, B43_PHY_OFDM(0xCC), 0x00FF, 0x1F00);
 		}
 	}
 	if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
 		b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
 	if (phy->radio_rev == 8) {
-		b43_phy_write(dev, B43_PHY_EXTG(0x01),
-			      b43_phy_read(dev, B43_PHY_EXTG(0x01))
-			      | 0x80);
-		b43_phy_write(dev, B43_PHY_OFDM(0x3E),
-			      b43_phy_read(dev, B43_PHY_OFDM(0x3E))
-			      | 0x4);
+		b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x80);
+		b43_phy_set(dev, B43_PHY_OFDM(0x3E), 0x4);
 	}
 	if (has_loopback_gain(phy))
 		b43_calc_loopback_gain(dev);
@@ -2251,15 +2047,10 @@ static void b43_phy_initg(struct b43_wld
 				  | gphy->lo_control->tx_bias | gphy->
 				  lo_control->tx_magn);
 	} else {
-		b43_radio_write16(dev, 0x52,
-				  (b43_radio_read16(dev, 0x52) & 0xFFF0)
-				  | gphy->lo_control->tx_bias);
+		b43_radio_maskset(dev, 0x52, 0xFFF0, gphy->lo_control->tx_bias);
 	}
 	if (phy->rev >= 6) {
-		b43_phy_write(dev, B43_PHY_CCK(0x36),
-			      (b43_phy_read(dev, B43_PHY_CCK(0x36))
-			       & 0x0FFF) | (gphy->lo_control->
-					    tx_bias << 12));
+		b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
 	}
 	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
 		b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
@@ -2298,11 +2089,8 @@ static void b43_phy_initg(struct b43_wld
 	   but OFDM is legal everywhere */
 	if ((dev->dev->bus->chip_id == 0x4306
 	     && dev->dev->bus->chip_package == 2) || 0) {
-		b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
-			      & 0xBFFF);
-		b43_phy_write(dev, B43_PHY_OFDM(0xC3),
-			      b43_phy_read(dev, B43_PHY_OFDM(0xC3))
-			      & 0x7FFF);
+		b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
+		b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
 	}
 }
 
@@ -2504,9 +2292,8 @@ static u8 b43_gphy_aci_scan(struct b43_w
 
 	b43_phy_lock(dev);
 	b43_radio_lock(dev);
-	b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
-	b43_phy_write(dev, B43_PHY_G_CRS,
-		      b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
+	b43_phy_mask(dev, 0x0802, 0xFFFC);
+	b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
 	b43_set_all_gains(dev, 3, 8, 1);
 
 	start = (channel - 5 > 0) ? channel - 5 : 1;
@@ -2517,11 +2304,9 @@ static u8 b43_gphy_aci_scan(struct b43_w
 			ret[i - 1] = b43_gphy_aci_detect(dev, i);
 	}
 	b43_switch_channel(dev, channel);
-	b43_phy_write(dev, 0x0802,
-		      (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
-	b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
-	b43_phy_write(dev, B43_PHY_G_CRS,
-		      b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+	b43_phy_maskset(dev, 0x0802, 0xFFFC, 0x0003);
+	b43_phy_mask(dev, 0x0403, 0xFFF8);
+	b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
 	b43_set_original_gains(dev);
 	for (i = 0; i < 13; i++) {
 		if (!ret[i])
@@ -2565,8 +2350,8 @@ static s8 b43_tssi2dbm_entry(s8 entry[],
 	return 0;
 }
 
-u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
-				   s16 pab0, s16 pab1, s16 pab2)
+u8 *b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
+				  s16 pab0, s16 pab1, s16 pab2)
 {
 	unsigned int i;
 	u8 *tab;
@@ -3191,6 +2976,7 @@ static enum b43_txpwr_result b43_gphy_op
 	 * Baseband attennuation. Subtract it. */
 	bbatt_delta -= 4 * rfatt_delta;
 
+#if B43_DEBUG
 	if (b43_debug(dev, B43_DBG_XMITPOWER)) {
 		int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
 		b43dbg(dev->wl,
@@ -3199,6 +2985,8 @@ static enum b43_txpwr_result b43_gphy_op
 		       (pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
 		       bbatt_delta, rfatt_delta);
 	}
+#endif /* DEBUG */
+
 	/* So do we finally need to adjust something in hardware? */
 	if ((rfatt_delta == 0) && (bbatt_delta == 0))
 		goto no_adjustment_needed;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_lp.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_lp.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_lp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_lp.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
   Broadcom B43 wireless driver
   IEEE 802.11g LP-PHY driver
 
-  Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+  Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.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
@@ -23,8 +23,10 @@
 */
 
 #include "b43.h"
+#include "main.h"
 #include "phy_lp.h"
 #include "phy_common.h"
+#include "tables_lpphy.h"
 
 
 static int b43_lpphy_op_allocate(struct b43_wldev *dev)
@@ -57,9 +59,394 @@ static void b43_lpphy_op_free(struct b43
 	dev->phy.lp = NULL;
 }
 
-static int b43_lpphy_op_init(struct b43_wldev *dev)
+static void lpphy_table_init(struct b43_wldev *dev)
+{
+	//TODO
+}
+
+static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
+{
+	B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
+}
+
+static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0x8800);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
+	b43_phy_write(dev, B43_PHY_OFDM(0xF9), 0);
+	b43_phy_write(dev, B43_LPPHY_TR_LOOKUP_1, 0);
+	b43_phy_set(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x10);
+	b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x78);
+	b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xF8FF, 0x200);
+	b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xFF00, 0x7F);
+	b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFF0F, 0x40);
+	b43_phy_maskset(dev, B43_LPPHY_PREAMBLECONFIRMTO, 0xFF00, 0x2);
+	b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
+	b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
+	b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
+	b43_phy_write(dev, B43_LPPHY_CLIPTHRESH, 0x48);
+	b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0xFF00, 0x46);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xE4), 0xFF00, 0x10);
+	b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
+	b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
+	b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0);
+	b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
+	b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
+	if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+		b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
+		b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
+	} else {
+		b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x1E00);
+		b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xD);
+	}
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFFE0, 0x1F);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0xFF00, 0x19);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0x03FF, 0x3C00);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFC1F, 0x3E0);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0x00FF, 0x1900);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
+	b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
+
+	b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
+	b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x40);
+		b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0xB00);
+		b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
+		b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
+		b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
+	} else /* 5GHz */
+		b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
+
+	b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0xB3);
+	b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
+	b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset);
+	b43_phy_set(dev, B43_LPPHY_RESET_CTL, 0x44);
+	b43_phy_write(dev, B43_LPPHY_RESET_CTL, 0x80);
+	b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, 0xA954);
+	b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_1,
+		      0x2000 | ((u16)lpphy->rssi_gs << 10) |
+		      ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
+}
+
+static void lpphy_baseband_init(struct b43_wldev *dev)
+{
+	lpphy_table_init(dev);
+	if (dev->phy.rev >= 2)
+		lpphy_baseband_rev2plus_init(dev);
+	else
+		lpphy_baseband_rev0_1_init(dev);
+}
+
+struct b2062_freqdata {
+	u16 freq;
+	u8 data[6];
+};
+
+/* Initialize the 2062 radio. */
+static void lpphy_2062_init(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+	u32 crystalfreq, pdiv, tmp, ref;
+	unsigned int i;
+	const struct b2062_freqdata *fd = NULL;
+
+	static const struct b2062_freqdata freqdata_tab[] = {
+		{ .freq = 12000, .data[0] =  6, .data[1] =  6, .data[2] =  6,
+				 .data[3] =  6, .data[4] = 10, .data[5] =  6, },
+		{ .freq = 13000, .data[0] =  4, .data[1] =  4, .data[2] =  4,
+				 .data[3] =  4, .data[4] = 11, .data[5] =  7, },
+		{ .freq = 14400, .data[0] =  3, .data[1] =  3, .data[2] =  3,
+				 .data[3] =  3, .data[4] = 12, .data[5] =  7, },
+		{ .freq = 16200, .data[0] =  3, .data[1] =  3, .data[2] =  3,
+				 .data[3] =  3, .data[4] = 13, .data[5] =  8, },
+		{ .freq = 18000, .data[0] =  2, .data[1] =  2, .data[2] =  2,
+				 .data[3] =  2, .data[4] = 14, .data[5] =  8, },
+		{ .freq = 19200, .data[0] =  1, .data[1] =  1, .data[2] =  1,
+				 .data[3] =  1, .data[4] = 14, .data[5] =  9, },
+	};
+
+	b2062_upload_init_table(dev);
+
+	b43_radio_write(dev, B2062_N_TX_CTL3, 0);
+	b43_radio_write(dev, B2062_N_TX_CTL4, 0);
+	b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+	b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
+	b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
+	b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
+	b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
+	else
+		b43_radio_mask(dev, B2062_N_TSSI_CTL0, ~0x1);
+
+	/* Get the crystal freq, in Hz. */
+	crystalfreq = bus->chipco.pmu.crystalfreq * 1000;
+
+	B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
+	B43_WARN_ON(crystalfreq == 0);
+
+	if (crystalfreq >= 30000000) {
+		pdiv = 1;
+		b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
+	} else {
+		pdiv = 2;
+		b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
+	}
+
+	tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv);
+	tmp = (tmp - 1) & 0xFF;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
+
+	tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv);
+	tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
+
+	ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv);
+	ref &= 0xFFFF;
+	for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
+		if (ref < freqdata_tab[i].freq) {
+			fd = &freqdata_tab[i];
+			break;
+		}
+	}
+	if (!fd)
+		fd = &freqdata_tab[ARRAY_SIZE(freqdata_tab) - 1];
+	b43dbg(dev->wl, "b2062: Using crystal tab entry %u kHz.\n",
+	       fd->freq); /* FIXME: Keep this printk until the code is fully debugged. */
+
+	b43_radio_write(dev, B2062_S_RFPLL_CTL8,
+			((u16)(fd->data[1]) << 4) | fd->data[0]);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL9,
+			((u16)(fd->data[3]) << 4) | fd->data[2]);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL10, fd->data[4]);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL11, fd->data[5]);
+}
+
+/* Initialize the 2063 radio. */
+static void lpphy_2063_init(struct b43_wldev *dev)
 {
 	//TODO
+}
+
+static void lpphy_sync_stx(struct b43_wldev *dev)
+{
+	//TODO
+}
+
+static void lpphy_radio_init(struct b43_wldev *dev)
+{
+	/* The radio is attached through the 4wire bus. */
+	b43_phy_set(dev, B43_LPPHY_FOURWIRE_CTL, 0x2);
+	udelay(1);
+	b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
+	udelay(1);
+
+	if (dev->phy.rev < 2) {
+		lpphy_2062_init(dev);
+	} else {
+		lpphy_2063_init(dev);
+		lpphy_sync_stx(dev);
+		b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
+		b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
+		//TODO Do something on the backplane
+	}
+}
+
+/* Read the TX power control mode from hardware. */
+static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 ctl;
+
+	ctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD);
+	switch (ctl & B43_LPPHY_TX_PWR_CTL_CMD_MODE) {
+	case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF:
+		lpphy->txpctl_mode = B43_LPPHY_TXPCTL_OFF;
+		break;
+	case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW:
+		lpphy->txpctl_mode = B43_LPPHY_TXPCTL_SW;
+		break;
+	case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW:
+		lpphy->txpctl_mode = B43_LPPHY_TXPCTL_HW;
+		break;
+	default:
+		lpphy->txpctl_mode = B43_LPPHY_TXPCTL_UNKNOWN;
+		B43_WARN_ON(1);
+		break;
+	}
+}
+
+/* Set the TX power control mode in hardware. */
+static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 ctl;
+
+	switch (lpphy->txpctl_mode) {
+	case B43_LPPHY_TXPCTL_OFF:
+		ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF;
+		break;
+	case B43_LPPHY_TXPCTL_HW:
+		ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW;
+		break;
+	case B43_LPPHY_TXPCTL_SW:
+		ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW;
+		break;
+	default:
+		ctl = 0;
+		B43_WARN_ON(1);
+	}
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+			(u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl);
+}
+
+static void lpphy_set_tx_power_control(struct b43_wldev *dev,
+				       enum b43_lpphy_txpctl_mode mode)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	enum b43_lpphy_txpctl_mode oldmode;
+
+	oldmode = lpphy->txpctl_mode;
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
+	if (lpphy->txpctl_mode == mode)
+		return;
+	lpphy->txpctl_mode = mode;
+
+	if (oldmode == B43_LPPHY_TXPCTL_HW) {
+		//TODO Update TX Power NPT
+		//TODO Clear all TX Power offsets
+	} else {
+		if (mode == B43_LPPHY_TXPCTL_HW) {
+			//TODO Recalculate target TX power
+			b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+					0xFF80, lpphy->tssi_idx);
+			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->tx_pwr_idx_over = -1;
+		}
+	}
+	if (dev->phy.rev >= 2) {
+		if (mode == B43_LPPHY_TXPCTL_HW)
+			b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
+		else
+			b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
+	}
+	lpphy_write_tx_pctl_mode_to_hardware(dev);
+}
+
+static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	lpphy->tx_pwr_idx_over = index;
+	if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
+		lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
+
+	//TODO
+}
+
+static void lpphy_btcoex_override(struct b43_wldev *dev)
+{
+	b43_write16(dev, B43_MMIO_BTCOEX_CTL, 0x3);
+	b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
+}
+
+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);
+	}
+	//TODO
+
+	kfree(saved_tab);
+}
+
+static void lpphy_calibration(struct b43_wldev *dev)
+{
+	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
+
+	b43_mac_enable(dev);
+}
+
+/* Initialize TX power control */
+static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+{
+	if (0/*FIXME HWPCTL capable */) {
+		//TODO
+	} else { /* This device is only software TX power control capable. */
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			//TODO
+		} else {
+			//TODO
+		}
+		//TODO set BB multiplier to 0x0096
+	}
+}
+
+static int b43_lpphy_op_init(struct b43_wldev *dev)
+{
+	/* TODO: band SPROM */
+	lpphy_baseband_init(dev);
+	lpphy_radio_init(dev);
+	//TODO calibrate RC
+	//TODO set channel
+	lpphy_tx_pctl_init(dev);
+	//TODO full calib
 
 	return 0;
 }
@@ -115,7 +502,9 @@ static int b43_lpphy_op_switch_channel(s
 
 static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
 {
-	return 1; /* Default to channel 1 */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		return 1;
+	return 36;
 }
 
 static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_lp.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_lp.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/phy_lp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/phy_lp.h	2009-06-09 23:05:27.000000000 -0400
@@ -4,8 +4,285 @@
 /* Definitions for the LP-PHY */
 
 
+/* The CCK PHY register range. */
+#define B43_LPPHY_B_VERSION			B43_PHY_CCK(0x00) /* B PHY version */
+#define B43_LPPHY_B_BBCONFIG			B43_PHY_CCK(0x01) /* B PHY BBConfig */
+#define B43_LPPHY_B_RX_STAT0			B43_PHY_CCK(0x04) /* B PHY RX Status0 */
+#define B43_LPPHY_B_RX_STAT1			B43_PHY_CCK(0x05) /* B PHY RX Status1 */
+#define B43_LPPHY_B_CRS_THRESH			B43_PHY_CCK(0x06) /* B PHY CRS Thresh */
+#define B43_LPPHY_B_TXERROR			B43_PHY_CCK(0x07) /* B PHY TxError */
+#define B43_LPPHY_B_CHANNEL			B43_PHY_CCK(0x08) /* B PHY Channel */
+#define B43_LPPHY_B_WORKAROUND			B43_PHY_CCK(0x09) /* B PHY workaround */
+#define B43_LPPHY_B_TEST			B43_PHY_CCK(0x0A) /* B PHY Test */
+#define B43_LPPHY_B_FOURWIRE_ADDR		B43_PHY_CCK(0x0B) /* B PHY Fourwire Address */
+#define B43_LPPHY_B_FOURWIRE_DATA_HI		B43_PHY_CCK(0x0C) /* B PHY Fourwire Data Hi */
+#define B43_LPPHY_B_FOURWIRE_DATA_LO		B43_PHY_CCK(0x0D) /* B PHY Fourwire Data Lo */
+#define B43_LPPHY_B_BIST_STAT			B43_PHY_CCK(0x0E) /* B PHY Bist Status */
+#define B43_LPPHY_PA_RAMP_TX_TO			B43_PHY_CCK(0x10) /* PA Ramp TX Timeout */
+#define B43_LPPHY_RF_SYNTH_DC_TIMER		B43_PHY_CCK(0x11) /* RF Synth DC Timer */
+#define B43_LPPHY_PA_RAMP_TX_TIME_IN		B43_PHY_CCK(0x12) /* PA ramp TX Time in */
+#define B43_LPPHY_RX_FILTER_TIME_IN		B43_PHY_CCK(0x13) /* RX Filter Time in */
+#define B43_LPPHY_PLL_COEFF_S			B43_PHY_CCK(0x18) /* PLL Coefficient(s) */
+#define B43_LPPHY_PLL_OUT			B43_PHY_CCK(0x19) /* PLL Out */
+#define B43_LPPHY_RSSI_THRES			B43_PHY_CCK(0x20) /* RSSI Threshold */
+#define B43_LPPHY_IQ_THRES_HH			B43_PHY_CCK(0x21) /* IQ Threshold HH */
+#define B43_LPPHY_IQ_THRES_H			B43_PHY_CCK(0x22) /* IQ Threshold H */
+#define B43_LPPHY_IQ_THRES_L			B43_PHY_CCK(0x23) /* IQ Threshold L */
+#define B43_LPPHY_IQ_THRES_LL			B43_PHY_CCK(0x24) /* IQ Threshold LL */
+#define B43_LPPHY_AGC_GAIN			B43_PHY_CCK(0x25) /* AGC Gain */
+#define B43_LPPHY_LNA_GAIN_RANGE		B43_PHY_CCK(0x26) /* LNA Gain Range */
+#define B43_LPPHY_JSSI				B43_PHY_CCK(0x27) /* JSSI */
+#define B43_LPPHY_TSSI_CTL			B43_PHY_CCK(0x28) /* TSSI Control */
+#define B43_LPPHY_TSSI				B43_PHY_CCK(0x29) /* TSSI */
+#define B43_LPPHY_TR_LOSS			B43_PHY_CCK(0x2A) /* TR Loss */
+#define B43_LPPHY_LO_LEAKAGE			B43_PHY_CCK(0x2B) /* LO Leakage */
+#define B43_LPPHY_LO_RSSIACC			B43_PHY_CCK(0x2C) /* LO RSSIAcc */
+#define B43_LPPHY_LO_IQ_MAG_ACC			B43_PHY_CCK(0x2D) /* LO IQ Mag Acc */
+#define B43_LPPHY_TX_DCOFFSET1			B43_PHY_CCK(0x2E) /* TX DCOffset1 */
+#define B43_LPPHY_TX_DCOFFSET2			B43_PHY_CCK(0x2F) /* TX DCOffset2 */
+#define B43_LPPHY_SYNCPEAKCNT			B43_PHY_CCK(0x30) /* SyncPeakCnt */
+#define B43_LPPHY_SYNCFREQ			B43_PHY_CCK(0x31) /* SyncFreq */
+#define B43_LPPHY_SYNCDIVERSITYCTL		B43_PHY_CCK(0x32) /* SyncDiversityControl */
+#define B43_LPPHY_PEAKENERGYL			B43_PHY_CCK(0x33) /* PeakEnergyL */
+#define B43_LPPHY_PEAKENERGYH			B43_PHY_CCK(0x34) /* PeakEnergyH */
+#define B43_LPPHY_SYNCCTL			B43_PHY_CCK(0x35) /* SyncControl */
+#define B43_LPPHY_DSSSSTEP			B43_PHY_CCK(0x38) /* DsssStep */
+#define B43_LPPHY_DSSSWARMUP			B43_PHY_CCK(0x39) /* DsssWarmup */
+#define B43_LPPHY_DSSSSIGPOW			B43_PHY_CCK(0x3D) /* DsssSigPow */
+#define B43_LPPHY_SFDDETECTBLOCKTIME		B43_PHY_CCK(0x40) /* SfdDetectBlockTIme */
+#define B43_LPPHY_SFDTO				B43_PHY_CCK(0x41) /* SFDTimeOut */
+#define B43_LPPHY_SFDCTL			B43_PHY_CCK(0x42) /* SFDControl */
+#define B43_LPPHY_RXDBG				B43_PHY_CCK(0x43) /* rxDebug */
+#define B43_LPPHY_RX_DELAYCOMP			B43_PHY_CCK(0x44) /* RX DelayComp */
+#define B43_LPPHY_CRSDROPOUTTO			B43_PHY_CCK(0x45) /* CRSDropoutTimeout */
+#define B43_LPPHY_PSEUDOSHORTTO			B43_PHY_CCK(0x46) /* PseudoShortTimeout */
+#define B43_LPPHY_PR3931			B43_PHY_CCK(0x47) /* PR3931 */
+#define B43_LPPHY_DSSSCOEFF1			B43_PHY_CCK(0x48) /* DSSSCoeff1 */
+#define B43_LPPHY_DSSSCOEFF2			B43_PHY_CCK(0x49) /* DSSSCoeff2 */
+#define B43_LPPHY_CCKCOEFF1			B43_PHY_CCK(0x4A) /* CCKCoeff1 */
+#define B43_LPPHY_CCKCOEFF2			B43_PHY_CCK(0x4B) /* CCKCoeff2 */
+#define B43_LPPHY_TRCORR			B43_PHY_CCK(0x4C) /* TRCorr */
+#define B43_LPPHY_ANGLESCALE			B43_PHY_CCK(0x4D) /* AngleScale */
+#define B43_LPPHY_OPTIONALMODES2		B43_PHY_CCK(0x4F) /* OptionalModes2 */
+#define B43_LPPHY_CCKLMSSTEPSIZE		B43_PHY_CCK(0x50) /* CCKLMSStepSize */
+#define B43_LPPHY_DFEBYPASS			B43_PHY_CCK(0x51) /* DFEBypass */
+#define B43_LPPHY_CCKSTARTDELAYLONG		B43_PHY_CCK(0x52) /* CCKStartDelayLong */
+#define B43_LPPHY_CCKSTARTDELAYSHORT		B43_PHY_CCK(0x53) /* CCKStartDelayShort */
+#define B43_LPPHY_PPROCCHDELAY			B43_PHY_CCK(0x54) /* PprocChDelay */
+#define B43_LPPHY_PPROCONOFF			B43_PHY_CCK(0x55) /* PProcOnOff */
+#define B43_LPPHY_LNAGAINTWOBIT10		B43_PHY_CCK(0x5B) /* LNAGainTwoBit10 */
+#define B43_LPPHY_LNAGAINTWOBIT32		B43_PHY_CCK(0x5C) /* LNAGainTwoBit32 */
+#define B43_LPPHY_OPTIONALMODES			B43_PHY_CCK(0x5D) /* OptionalModes */
+#define B43_LPPHY_B_RX_STAT2			B43_PHY_CCK(0x5E) /* B PHY RX Status2 */
+#define B43_LPPHY_B_RX_STAT3			B43_PHY_CCK(0x5F) /* B PHY RX Status3 */
+#define B43_LPPHY_PWDNDACDELAY			B43_PHY_CCK(0x63) /* pwdnDacDelay */
+#define B43_LPPHY_FINEDIGIGAIN_CTL		B43_PHY_CCK(0x67) /* FineDigiGain Control */
+#define B43_LPPHY_LG2GAINTBLLNA8		B43_PHY_CCK(0x68) /* Lg2GainTblLNA8 */
+#define B43_LPPHY_LG2GAINTBLLNA28		B43_PHY_CCK(0x69) /* Lg2GainTblLNA28 */
+#define B43_LPPHY_GAINTBLLNATRSW		B43_PHY_CCK(0x6A) /* GainTblLNATrSw */
+#define B43_LPPHY_PEAKENERGY			B43_PHY_CCK(0x6B) /* PeakEnergy */
+#define B43_LPPHY_LG2INITGAIN			B43_PHY_CCK(0x6C) /* lg2InitGain */
+#define B43_LPPHY_BLANKCOUNTLNAPGA		B43_PHY_CCK(0x6D) /* BlankCountLnaPga */
+#define B43_LPPHY_LNAGAINTWOBIT54		B43_PHY_CCK(0x6E) /* LNAGainTwoBit54 */
+#define B43_LPPHY_LNAGAINTWOBIT76		B43_PHY_CCK(0x6F) /* LNAGainTwoBit76 */
+#define B43_LPPHY_JSSICTL			B43_PHY_CCK(0x70) /* JSSIControl */
+#define B43_LPPHY_LG2GAINTBLLNA44		B43_PHY_CCK(0x71) /* Lg2GainTblLNA44 */
+#define B43_LPPHY_LG2GAINTBLLNA62		B43_PHY_CCK(0x72) /* Lg2GainTblLNA62 */
+
+/* The OFDM PHY register range. */
+#define B43_LPPHY_VERSION			B43_PHY_OFDM(0x00) /* Version */
+#define B43_LPPHY_BBCONFIG			B43_PHY_OFDM(0x01) /* BBConfig */
+#define B43_LPPHY_RX_STAT0			B43_PHY_OFDM(0x04) /* RX Status0 */
+#define B43_LPPHY_RX_STAT1			B43_PHY_OFDM(0x05) /* RX Status1 */
+#define B43_LPPHY_TX_ERROR			B43_PHY_OFDM(0x07) /* TX Error */
+#define B43_LPPHY_CHANNEL			B43_PHY_OFDM(0x08) /* Channel */
+#define B43_LPPHY_WORKAROUND			B43_PHY_OFDM(0x09) /* workaround */
+#define B43_LPPHY_FOURWIRE_ADDR			B43_PHY_OFDM(0x0B) /* Fourwire Address */
+#define B43_LPPHY_FOURWIREDATAHI		B43_PHY_OFDM(0x0C) /* FourwireDataHi */
+#define B43_LPPHY_FOURWIREDATALO		B43_PHY_OFDM(0x0D) /* FourwireDataLo */
+#define B43_LPPHY_BISTSTAT0			B43_PHY_OFDM(0x0E) /* BistStatus0 */
+#define B43_LPPHY_BISTSTAT1			B43_PHY_OFDM(0x0F) /* BistStatus1 */
+#define B43_LPPHY_CRSGAIN_CTL			B43_PHY_OFDM(0x10) /* crsgain Control */
+#define B43_LPPHY_OFDMPWR_THRESH0		B43_PHY_OFDM(0x11) /* ofdmPower Thresh0 */
+#define B43_LPPHY_OFDMPWR_THRESH1		B43_PHY_OFDM(0x12) /* ofdmPower Thresh1 */
+#define B43_LPPHY_OFDMPWR_THRESH2		B43_PHY_OFDM(0x13) /* ofdmPower Thresh2 */
+#define B43_LPPHY_DSSSPWR_THRESH0		B43_PHY_OFDM(0x14) /* dsssPower Thresh0 */
+#define B43_LPPHY_DSSSPWR_THRESH1		B43_PHY_OFDM(0x15) /* dsssPower Thresh1 */
+#define B43_LPPHY_MINPWR_LEVEL			B43_PHY_OFDM(0x16) /* MinPower Level */
+#define B43_LPPHY_OFDMSYNCTHRESH0		B43_PHY_OFDM(0x17) /* ofdmSyncThresh0 */
+#define B43_LPPHY_OFDMSYNCTHRESH1		B43_PHY_OFDM(0x18) /* ofdmSyncThresh1 */
+#define B43_LPPHY_FINEFREQEST			B43_PHY_OFDM(0x19) /* FineFreqEst */
+#define B43_LPPHY_IDLEAFTERPKTRXTO		B43_PHY_OFDM(0x1A) /* IDLEafterPktRXTimeout */
+#define B43_LPPHY_LTRN_CTL			B43_PHY_OFDM(0x1B) /* LTRN Control */
+#define B43_LPPHY_DCOFFSETTRANSIENT		B43_PHY_OFDM(0x1C) /* DCOffsetTransient */
+#define B43_LPPHY_PREAMBLEINTO			B43_PHY_OFDM(0x1D) /* PreambleInTimeout */
+#define B43_LPPHY_PREAMBLECONFIRMTO		B43_PHY_OFDM(0x1E) /* PreambleConfirmTimeout */
+#define B43_LPPHY_CLIPTHRESH			B43_PHY_OFDM(0x1F) /* ClipThresh */
+#define B43_LPPHY_CLIPCTRTHRESH			B43_PHY_OFDM(0x20) /* ClipCtrThresh */
+#define B43_LPPHY_OFDMSYNCTIMER_CTL		B43_PHY_OFDM(0x21) /* ofdmSyncTimer Control */
+#define B43_LPPHY_WAITFORPHYSELTO		B43_PHY_OFDM(0x22) /* WaitforPHYSelTimeout */
+#define B43_LPPHY_HIGAINDB			B43_PHY_OFDM(0x23) /* HiGainDB */
+#define B43_LPPHY_LOWGAINDB			B43_PHY_OFDM(0x24) /* LowGainDB */
+#define B43_LPPHY_VERYLOWGAINDB			B43_PHY_OFDM(0x25) /* VeryLowGainDB */
+#define B43_LPPHY_GAINMISMATCH			B43_PHY_OFDM(0x26) /* gainMismatch */
+#define B43_LPPHY_GAINDIRECTMISMATCH		B43_PHY_OFDM(0x27) /* gaindirectMismatch */
+#define B43_LPPHY_PWR_THRESH0			B43_PHY_OFDM(0x28) /* Power Thresh0 */
+#define B43_LPPHY_PWR_THRESH1			B43_PHY_OFDM(0x29) /* Power Thresh1 */
+#define B43_LPPHY_DETECTOR_DELAY_ADJUST		B43_PHY_OFDM(0x2A) /* Detector Delay Adjust */
+#define B43_LPPHY_REDUCED_DETECTOR_DELAY	B43_PHY_OFDM(0x2B) /* Reduced Detector Delay */
+#define B43_LPPHY_DATA_TO			B43_PHY_OFDM(0x2C) /* data Timeout */
+#define B43_LPPHY_CORRELATOR_DIS_DELAY		B43_PHY_OFDM(0x2D) /* correlator Dis Delay */
+#define B43_LPPHY_DIVERSITY_GAINBACK		B43_PHY_OFDM(0x2E) /* Diversity GainBack */
+#define B43_LPPHY_DSSS_CONFIRM_CNT		B43_PHY_OFDM(0x2F) /* DSSS Confirm Cnt */
+#define B43_LPPHY_DC_BLANK_INT			B43_PHY_OFDM(0x30) /* DC Blank Interval */
+#define B43_LPPHY_GAIN_MISMATCH_LIMIT		B43_PHY_OFDM(0x31) /* gain Mismatch Limit */
+#define B43_LPPHY_CRS_ED_THRESH			B43_PHY_OFDM(0x32) /* crs ed thresh */
+#define B43_LPPHY_PHASE_SHIFT_CTL		B43_PHY_OFDM(0x33) /* phase shift Control */
+#define B43_LPPHY_INPUT_PWRDB			B43_PHY_OFDM(0x34) /* Input PowerDB */
+#define B43_LPPHY_OFDM_SYNC_CTL			B43_PHY_OFDM(0x35) /* ofdm sync Control */
+#define B43_LPPHY_AFE_ADC_CTL_0			B43_PHY_OFDM(0x36) /* Afe ADC Control 0 */
+#define B43_LPPHY_AFE_ADC_CTL_1			B43_PHY_OFDM(0x37) /* Afe ADC Control 1 */
+#define B43_LPPHY_AFE_ADC_CTL_2			B43_PHY_OFDM(0x38) /* Afe ADC Control 2 */
+#define B43_LPPHY_AFE_DAC_CTL			B43_PHY_OFDM(0x39) /* Afe DAC Control */
+#define B43_LPPHY_AFE_CTL			B43_PHY_OFDM(0x3A) /* Afe Control */
+#define B43_LPPHY_AFE_CTL_OVR			B43_PHY_OFDM(0x3B) /* Afe Control Ovr */
+#define B43_LPPHY_AFE_CTL_OVRVAL		B43_PHY_OFDM(0x3C) /* Afe Control OvrVal */
+#define B43_LPPHY_AFE_RSSI_CTL_0		B43_PHY_OFDM(0x3D) /* Afe RSSI Control 0 */
+#define B43_LPPHY_AFE_RSSI_CTL_1		B43_PHY_OFDM(0x3E) /* Afe RSSI Control 1 */
+#define B43_LPPHY_AFE_RSSI_SEL			B43_PHY_OFDM(0x3F) /* Afe RSSI Sel */
+#define B43_LPPHY_RADAR_THRESH			B43_PHY_OFDM(0x40) /* Radar Thresh */
+#define B43_LPPHY_RADAR_BLANK_INT		B43_PHY_OFDM(0x41) /* Radar blank Interval */
+#define B43_LPPHY_RADAR_MIN_FM_INT		B43_PHY_OFDM(0x42) /* Radar min fm Interval */
+#define B43_LPPHY_RADAR_GAIN_TO			B43_PHY_OFDM(0x43) /* Radar gain timeout */
+#define B43_LPPHY_RADAR_PULSE_TO		B43_PHY_OFDM(0x44) /* Radar pulse timeout */
+#define B43_LPPHY_RADAR_DETECT_FM_CTL		B43_PHY_OFDM(0x45) /* Radar detect FM Control */
+#define B43_LPPHY_RADAR_DETECT_EN		B43_PHY_OFDM(0x46) /* Radar detect En */
+#define B43_LPPHY_RADAR_RD_DATA_REG		B43_PHY_OFDM(0x47) /* Radar Rd Data Reg */
+#define B43_LPPHY_LP_PHY_CTL			B43_PHY_OFDM(0x48) /* LP PHY Control */
+#define B43_LPPHY_CLASSIFIER_CTL		B43_PHY_OFDM(0x49) /* classifier Control */
+#define B43_LPPHY_RESET_CTL			B43_PHY_OFDM(0x4A) /* reset Control */
+#define B43_LPPHY_CLKEN_CTL			B43_PHY_OFDM(0x4B) /* ClkEn Control */
+#define B43_LPPHY_RF_OVERRIDE_0			B43_PHY_OFDM(0x4C) /* RF Override 0 */
+#define B43_LPPHY_RF_OVERRIDE_VAL_0		B43_PHY_OFDM(0x4D) /* RF Override Val 0 */
+#define B43_LPPHY_TR_LOOKUP_1			B43_PHY_OFDM(0x4E) /* TR Lookup 1 */
+#define B43_LPPHY_TR_LOOKUP_2			B43_PHY_OFDM(0x4F) /* TR Lookup 2 */
+#define B43_LPPHY_RSSISELLOOKUP1		B43_PHY_OFDM(0x50) /* RssiSelLookup1 */
+#define B43_LPPHY_IQLO_CAL_CMD			B43_PHY_OFDM(0x51) /* iqlo Cal Cmd */
+#define B43_LPPHY_IQLO_CAL_CMD_N_NUM		B43_PHY_OFDM(0x52) /* iqlo Cal Cmd N num */
+#define B43_LPPHY_IQLO_CAL_CMD_G_CTL		B43_PHY_OFDM(0x53) /* iqlo Cal Cmd G control */
+#define B43_LPPHY_MACINT_DBG_REGISTER		B43_PHY_OFDM(0x54) /* macint Debug Register */
+#define B43_LPPHY_TABLE_ADDR			B43_PHY_OFDM(0x55) /* Table Address */
+#define B43_LPPHY_TABLEDATALO			B43_PHY_OFDM(0x56) /* TabledataLo */
+#define B43_LPPHY_TABLEDATAHI			B43_PHY_OFDM(0x57) /* TabledataHi */
+#define B43_LPPHY_PHY_CRS_ENABLE_ADDR		B43_PHY_OFDM(0x58) /* phy CRS Enable Address */
+#define B43_LPPHY_IDLETIME_CTL			B43_PHY_OFDM(0x59) /* Idletime Control */
+#define B43_LPPHY_IDLETIME_CRS_ON_LO		B43_PHY_OFDM(0x5A) /* Idletime CRS On Lo */
+#define B43_LPPHY_IDLETIME_CRS_ON_HI		B43_PHY_OFDM(0x5B) /* Idletime CRS On Hi */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_LO		B43_PHY_OFDM(0x5C) /* Idletime Meas Time Lo */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_HI		B43_PHY_OFDM(0x5D) /* Idletime Meas Time Hi */
+#define B43_LPPHY_RESET_LEN_OFDM_TX_ADDR	B43_PHY_OFDM(0x5E) /* Reset len Ofdm TX Address */
+#define B43_LPPHY_RESET_LEN_OFDM_RX_ADDR	B43_PHY_OFDM(0x5F) /* Reset len Ofdm RX Address */
+#define B43_LPPHY_REG_CRS_ENABLE		B43_PHY_OFDM(0x60) /* reg crs enable */
+#define B43_LPPHY_PLCP_TMT_STR0_CTR_MIN		B43_PHY_OFDM(0x61) /* PLCP Tmt Str0 Ctr Min */
+#define B43_LPPHY_PKT_FSM_RESET_LEN_VAL		B43_PHY_OFDM(0x62) /* Pkt fsm Reset Len Value */
+#define B43_LPPHY_READSYM2RESET_CTL		B43_PHY_OFDM(0x63) /* readsym2reset Control */
+#define B43_LPPHY_DC_FILTER_DELAY1		B43_PHY_OFDM(0x64) /* Dc filter delay1 */
+#define B43_LPPHY_PACKET_RX_ACTIVE_TO		B43_PHY_OFDM(0x65) /* packet rx Active timeout */
+#define B43_LPPHY_ED_TOVAL			B43_PHY_OFDM(0x66) /* ed timeoutValue */
+#define B43_LPPHY_HOLD_CRS_ON_VAL		B43_PHY_OFDM(0x67) /* hold CRS On Value */
+#define B43_LPPHY_OFDM_TX_PHY_CRS_DELAY_VAL	B43_PHY_OFDM(0x69) /* ofdm tx phy CRS Delay Value */
+#define B43_LPPHY_CCK_TX_PHY_CRS_DELAY_VAL	B43_PHY_OFDM(0x6A) /* cck tx phy CRS Delay Value */
+#define B43_LPPHY_ED_ON_CONFIRM_TIMER_VAL	B43_PHY_OFDM(0x6B) /* Ed on confirm Timer Value */
+#define B43_LPPHY_ED_OFFSET_CONFIRM_TIMER_VAL	B43_PHY_OFDM(0x6C) /* Ed offset confirm Timer Value */
+#define B43_LPPHY_PHY_CRS_OFFSET_TIMER_VAL	B43_PHY_OFDM(0x6D) /* phy CRS offset Timer Value */
+#define B43_LPPHY_ADC_COMPENSATION_CTL		B43_PHY_OFDM(0x70) /* ADC Compensation Control */
+#define B43_LPPHY_LOG2_RBPSK_ADDR		B43_PHY_OFDM(0x71) /* log2 RBPSK Address */
+#define B43_LPPHY_LOG2_RQPSK_ADDR		B43_PHY_OFDM(0x72) /* log2 RQPSK Address */
+#define B43_LPPHY_LOG2_R16QAM_ADDR		B43_PHY_OFDM(0x73) /* log2 R16QAM Address */
+#define B43_LPPHY_LOG2_R64QAM_ADDR		B43_PHY_OFDM(0x74) /* log2 R64QAM Address */
+#define B43_LPPHY_OFFSET_BPSK_ADDR		B43_PHY_OFDM(0x75) /* offset BPSK Address */
+#define B43_LPPHY_OFFSET_QPSK_ADDR		B43_PHY_OFDM(0x76) /* offset QPSK Address */
+#define B43_LPPHY_OFFSET_16QAM_ADDR		B43_PHY_OFDM(0x77) /* offset 16QAM Address */
+#define B43_LPPHY_OFFSET_64QAM_ADDR		B43_PHY_OFDM(0x78) /* offset 64QAM Address */
+#define B43_LPPHY_ALPHA1			B43_PHY_OFDM(0x79) /* Alpha1 */
+#define B43_LPPHY_ALPHA2			B43_PHY_OFDM(0x7A) /* Alpha2 */
+#define B43_LPPHY_BETA1				B43_PHY_OFDM(0x7B) /* Beta1 */
+#define B43_LPPHY_BETA2				B43_PHY_OFDM(0x7C) /* Beta2 */
+#define B43_LPPHY_LOOP_NUM_ADDR			B43_PHY_OFDM(0x7D) /* Loop Num Address */
+#define B43_LPPHY_STR_COLLMAX_SMPL_ADDR		B43_PHY_OFDM(0x7E) /* Str Collmax Sample Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_FINE_ADDR	B43_PHY_OFDM(0x7F) /* Max Sample Coarse/Fine Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_STR0CTR_ADDR	B43_PHY_OFDM(0x80) /* Max Sample Coarse/Str0Ctr Address */
+#define B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR	B43_PHY_OFDM(0x81) /* IQ Enable Wait Time Address */
+#define B43_LPPHY_IQ_NUM_SMPLS_ADDR		B43_PHY_OFDM(0x82) /* IQ Num Samples Address */
+#define B43_LPPHY_IQ_ACC_HI_ADDR		B43_PHY_OFDM(0x83) /* IQ Acc Hi Address */
+#define B43_LPPHY_IQ_ACC_LO_ADDR		B43_PHY_OFDM(0x84) /* IQ Acc Lo Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_HI_ADDR		B43_PHY_OFDM(0x85) /* IQ I PWR Acc Hi Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_LO_ADDR		B43_PHY_OFDM(0x86) /* IQ I PWR Acc Lo Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_HI_ADDR		B43_PHY_OFDM(0x87) /* IQ Q PWR Acc Hi Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_LO_ADDR		B43_PHY_OFDM(0x88) /* IQ Q PWR Acc Lo Address */
+#define B43_LPPHY_MAXNUMSTEPS			B43_PHY_OFDM(0x89) /* MaxNumsteps */
+#define B43_LPPHY_ROTORPHASE_ADDR		B43_PHY_OFDM(0x8A) /* RotorPhase Address */
+#define B43_LPPHY_ADVANCEDRETARDROTOR_ADDR	B43_PHY_OFDM(0x8B) /* AdvancedRetardRotor Address */
+#define B43_LPPHY_RSSIADCDELAY_CTL_ADDR		B43_PHY_OFDM(0x8D) /* rssiAdcdelay Control Address */
+#define B43_LPPHY_TSSISTAT_ADDR			B43_PHY_OFDM(0x8E) /* tssiStatus Address */
+#define B43_LPPHY_TEMPSENSESTAT_ADDR		B43_PHY_OFDM(0x8F) /* tempsenseStatus Address */
+#define B43_LPPHY_TEMPSENSE_CTL_ADDR		B43_PHY_OFDM(0x90) /* tempsense Control Address */
+#define B43_LPPHY_WRSSISTAT_ADDR		B43_PHY_OFDM(0x91) /* wrssistatus Address */
+#define B43_LPPHY_MUFACTORADDR			B43_PHY_OFDM(0x92) /* mufactoraddr */
+#define B43_LPPHY_SCRAMSTATE_ADDR		B43_PHY_OFDM(0x93) /* scramstate Address */
+#define B43_LPPHY_TXHOLDOFFADDR			B43_PHY_OFDM(0x94) /* txholdoffaddr */
+#define B43_LPPHY_PKTGAINVAL_ADDR		B43_PHY_OFDM(0x95) /* pktgainval Address */
+#define B43_LPPHY_COARSEESTIM_ADDR		B43_PHY_OFDM(0x96) /* Coarseestim Address */
+#define B43_LPPHY_STATE_TRANSITION_ADDR		B43_PHY_OFDM(0x97) /* state Transition Address */
+#define B43_LPPHY_TRN_OFFSET_ADDR		B43_PHY_OFDM(0x98) /* TRN offset Address */
+#define B43_LPPHY_NUM_ROTOR_ADDR		B43_PHY_OFDM(0x99) /* Num Rotor Address */
+#define B43_LPPHY_VITERBI_OFFSET_ADDR		B43_PHY_OFDM(0x9A) /* Viterbi Offset Address */
+#define B43_LPPHY_SMPL_COLLECT_WAIT_ADDR	B43_PHY_OFDM(0x9B) /* Sample collect wait Address */
+#define B43_LPPHY_A_PHY_CTL_ADDR		B43_PHY_OFDM(0x9C) /* A PHY Control Address */
+#define B43_LPPHY_NUM_PASS_THROUGH_ADDR		B43_PHY_OFDM(0x9D) /* Num Pass Through Address */
+#define B43_LPPHY_RX_COMP_COEFF_S		B43_PHY_OFDM(0x9E) /* RX Comp coefficient(s) */
+#define B43_LPPHY_CPAROTATEVAL			B43_PHY_OFDM(0x9F) /* cpaRotateValue */
+#define B43_LPPHY_SMPL_PLAY_COUNT		B43_PHY_OFDM(0xA0) /* Sample play count */
+#define B43_LPPHY_SMPL_PLAY_BUFFER_CTL		B43_PHY_OFDM(0xA1) /* Sample play Buffer Control */
+#define B43_LPPHY_FOURWIRE_CTL			B43_PHY_OFDM(0xA2) /* fourwire Control */
+#define B43_LPPHY_CPA_TAILCOUNT_VAL		B43_PHY_OFDM(0xA3) /* CPA TailCount Value */
+#define B43_LPPHY_TX_PWR_CTL_CMD		B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */
+#define  B43_LPPHY_TX_PWR_CTL_CMD_MODE		0xE000 /* TX power control mode mask */
+#define   B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF	0x0000 /* TX power control is OFF */
+#define   B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW	0x8000 /* TX power control is SOFTWARE */
+#define   B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW	0xE000 /* TX power control is HARDWARE */
+#define B43_LPPHY_TX_PWR_CTL_NNUM		B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */
+#define B43_LPPHY_TX_PWR_CTL_IDLETSSI		B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */
+#define B43_LPPHY_TX_PWR_CTL_TARGETPWR		B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */
+#define B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT	B43_PHY_OFDM(0xA8) /* TX Power Control DeltaPower Limit */
+#define B43_LPPHY_TX_PWR_CTL_BASEINDEX		B43_PHY_OFDM(0xA9) /* TX Power Control BaseIndex */
+#define B43_LPPHY_TX_PWR_CTL_PWR_INDEX		B43_PHY_OFDM(0xAA) /* TX Power Control Power Index */
+#define B43_LPPHY_TX_PWR_CTL_STAT		B43_PHY_OFDM(0xAB) /* TX Power Control Status */
+#define B43_LPPHY_LP_RF_SIGNAL_LUT		B43_PHY_OFDM(0xAC) /* LP RF signal LUT */
+#define B43_LPPHY_RX_RADIO_CTL_FILTER_STATE	B43_PHY_OFDM(0xAD) /* RX Radio Control Filter State */
+#define B43_LPPHY_RX_RADIO_CTL			B43_PHY_OFDM(0xAE) /* RX Radio Control */
+#define B43_LPPHY_NRSSI_STAT_ADDR		B43_PHY_OFDM(0xAF) /* NRSSI status Address */
+#define B43_LPPHY_RF_OVERRIDE_2			B43_PHY_OFDM(0xB0) /* RF override 2 */
+#define B43_LPPHY_RF_OVERRIDE_2_VAL		B43_PHY_OFDM(0xB1) /* RF override 2 val */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL0		B43_PHY_OFDM(0xB2) /* PS Control override val0 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL1		B43_PHY_OFDM(0xB3) /* PS Control override val1 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL2		B43_PHY_OFDM(0xB4) /* PS Control override val2 */
+#define B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL	B43_PHY_OFDM(0xB5) /* TX gain Control override val */
+#define B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL	B43_PHY_OFDM(0xB6) /* RX gain Control override val */
+#define B43_LPPHY_AFE_DDFS			B43_PHY_OFDM(0xB7) /* AFE DDFS */
+#define B43_LPPHY_AFE_DDFS_POINTER_INIT		B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
+#define B43_LPPHY_AFE_DDFS_INCR_INIT		B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
+#define B43_LPPHY_MRCNOISEREDUCTION		B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
+#define B43_LPPHY_TRLOOKUP3			B43_PHY_OFDM(0xBB) /* TRLookup3 */
+#define B43_LPPHY_TRLOOKUP4			B43_PHY_OFDM(0xBC) /* TRLookup4 */
+#define B43_LPPHY_RADAR_FIFO_STAT		B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
+#define B43_LPPHY_GPIO_OUTEN			B43_PHY_OFDM(0xBE) /* GPIO Out enable */
+#define B43_LPPHY_GPIO_SELECT			B43_PHY_OFDM(0xBF) /* GPIO Select */
+#define B43_LPPHY_GPIO_OUT			B43_PHY_OFDM(0xC0) /* GPIO Out */
+
 
 
+/* Radio register access decorators. */
 #define B43_LP_RADIO(radio_reg)			(radio_reg)
 #define B43_LP_NORTH(radio_reg)			B43_LP_RADIO(radio_reg)
 #define B43_LP_SOUTH(radio_reg)			B43_LP_RADIO((radio_reg) | 0x4000)
@@ -529,8 +806,58 @@
 
 
 
+enum b43_lpphy_txpctl_mode {
+	B43_LPPHY_TXPCTL_UNKNOWN = 0,
+	B43_LPPHY_TXPCTL_OFF,	/* TX power control is OFF */
+	B43_LPPHY_TXPCTL_SW,	/* TX power control is set to Software */
+	B43_LPPHY_TXPCTL_HW,	/* TX power control is set to Hardware */
+};
+
 struct b43_phy_lp {
-	//TODO
+	/* Current TX power control mode. */
+	enum b43_lpphy_txpctl_mode txpctl_mode;
+
+	/* Transmit isolation medium band */
+	u8 tx_isolation_med_band; /* FIXME initial value? */
+	/* Transmit isolation low band */
+	u8 tx_isolation_low_band; /* FIXME initial value? */
+	/* Transmit isolation high band */
+	u8 tx_isolation_hi_band; /* FIXME initial value? */
+
+	/* Receive power offset */
+	u8 rx_pwr_offset; /* FIXME initial value? */
+
+	/* TSSI transmit count */
+	u16 tssi_tx_count;
+	/* TSSI index */
+	u16 tssi_idx; /* FIXME initial value? */
+	/* TSSI npt */
+	u16 tssi_npt; /* FIXME initial value? */
+
+	/* Target TX frequency */
+	u16 tgt_tx_freq; /* FIXME initial value? */
+
+	/* Transmit power index override */
+	s8 tx_pwr_idx_over; /* FIXME initial value? */
+
+	/* RSSI vf */
+	u8 rssi_vf; /* FIXME initial value? */
+	/* RSSI vc */
+	u8 rssi_vc; /* FIXME initial value? */
+	/* RSSI gs */
+	u8 rssi_gs; /* FIXME initial value? */
+
+	/* RC cap */
+	u8 rc_cap; /* FIXME initial value? */
+	/* BX arch */
+	u8 bx_arch; /* FIXME initial value? */
+
+	/* Full calibration channel */
+	u8 full_calib_chan; /* FIXME initial value? */
+
+	/* Transmit iqlocal best coeffs */
+	bool tx_iqloc_best_coeffs_valid;
+	u8 tx_iqloc_best_coeffs[11];
 };
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/pio.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/pio.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/pio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/pio.c	2009-06-09 23:05:27.000000000 -0400
@@ -55,8 +55,8 @@ static u16 generate_cookie(struct b43_pi
 }
 
 static
-struct b43_pio_txqueue * parse_cookie(struct b43_wldev *dev,
-				      u16 cookie,
+struct b43_pio_txqueue *parse_cookie(struct b43_wldev *dev,
+				     u16 cookie,
 				      struct b43_pio_txpacket **pack)
 {
 	struct b43_pio *pio = &dev->pio;
@@ -134,8 +134,8 @@ static u16 pio_rxqueue_offset(struct b43
 	return 8;
 }
 
-static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
-						      unsigned int index)
+static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
+						     unsigned int index)
 {
 	struct b43_pio_txqueue *q;
 	struct b43_pio_txpacket *p;
@@ -171,8 +171,8 @@ static struct b43_pio_txqueue * b43_setu
 	return q;
 }
 
-static struct b43_pio_rxqueue * b43_setup_pioqueue_rx(struct b43_wldev *dev,
-						      unsigned int index)
+static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
+						     unsigned int index)
 {
 	struct b43_pio_rxqueue *q;
 
@@ -308,8 +308,8 @@ err_destroy_bk:
 }
 
 /* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
-static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev,
-							 u8 queue_prio)
+static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
+							u8 queue_prio)
 {
 	struct b43_pio_txqueue *q;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/rfkill.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/rfkill.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/rfkill.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/rfkill.c	2009-06-09 23:05:27.000000000 -0400
@@ -113,7 +113,7 @@ out_unlock:
 	return err;
 }
 
-char * b43_rfkill_led_name(struct b43_wldev *dev)
+char *b43_rfkill_led_name(struct b43_wldev *dev)
 {
 	struct b43_rfkill *rfk = &(dev->wl->rfkill);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/tables_lpphy.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/tables_lpphy.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/tables_lpphy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/tables_lpphy.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,394 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11g LP-PHY and radio device data tables
+
+  Copyright (c) 2009 Michael Buesch <mb@bu3sch.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; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_lpphy.h"
+#include "phy_common.h"
+#include "phy_lp.h"
+
+
+/* Entry of the 2062 radio init table */
+struct b2062_init_tab_entry {
+	u16 offset;
+	u16 value_a;
+	u16 value_g;
+	u8 flags;
+};
+#define B2062_FLAG_A	0x01 /* Flag: Init in A mode */
+#define B2062_FLAG_G	0x02 /* Flag: Init in G mode */
+
+static const struct b2062_init_tab_entry b2062_init_tab[] = {
+	/* { .offset = B2062_N_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = 0x0001, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_PDN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B2062_FLAG_G, },
+	/* { .offset = B2062_N_PDN_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+	{ .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_GEN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_IQ_CALIB, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	{ .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B2062_FLAG_A, },
+	/* { .offset = B2062_N_LGENA_LPF, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_BIAS0, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+	/* { .offset = B2062_N_LGNEA_BIAS1, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_CTL0, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_LGENA_TUNE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_LGENA_CTL4, .value_a = 0x001F, .value_g = 0x001F, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_CTL5, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+	/* { .offset = B2062_N_LGENA_CTL6, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+	{ .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_RXA_CTL0, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
+	{ .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_G, },
+	/* { .offset = B2062_N_RXA_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+	/* { .offset = B2062_N_RXA_CTL3, .value_a = 0x0027, .value_g = 0x0027, .flags = 0, }, */
+	/* { .offset = B2062_N_RXA_CTL4, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+	/* { .offset = B2062_N_RXA_CTL5, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+	/* { .offset = B2062_N_RXA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_RXA_CTL7, .value_a = 0x0008, .value_g = 0x0008, .flags = 0, }, */
+	{ .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_RXBB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_GAIN0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_RXBB_GAIN3, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI0, .value_a = 0x0043, .value_g = 0x0043, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_CALIB0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_CALIB1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_CALIB2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS1, .value_a = 0x002A, .value_g = 0x002A, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS2, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS3, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS4, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_BIAS5, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI2, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI3, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI4, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2062_N_RXBB_RSSI5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL0, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL2, .value_a = 0x0084, .value_g = 0x0084, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_TX_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL7, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL8, .value_a = 0x0082, .value_g = 0x0082, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_CTL_A, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_GC2G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_GC5G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+	{ .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_N_TX_PAD, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_PGA, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_PADAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2062_N_TX_PGAAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2062_N_TSSI_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TSSI_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TSSI_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_IQ_CALIB_CTL0, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2062_N_IQ_CALIB_CTL1, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_N_IQ_CALIB_CTL2, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_TS, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_CTL1, .value_a = 0x0015, .value_g = 0x0015, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_CTL2, .value_a = 0x000F, .value_g = 0x000F, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_DBG0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_DBG1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_DBG2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_CALIB_DBG3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_PSENSE_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_PSENSE_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_PSENSE_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_N_TEST_BUF0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RADIO_ID_CODE, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_PDS_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_PDS_CTL2, .value_a = 0x008E, .value_g = 0x008E, .flags = 0, }, */
+	/* { .offset = B2062_S_PDS_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_BG_CTL0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+	/* { .offset = B2062_S_BG_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_BG_CTL2, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+	{ .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_LGENG_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_LGENG_CTL3, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+	/* { .offset = B2062_S_LGENG_CTL4, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+	/* { .offset = B2062_S_LGENG_CTL5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2062_S_LGENG_CTL6, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+	/* { .offset = B2062_S_LGENG_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_LGENG_CTL9, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	{ .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_LGENG_CTL11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL2, .value_a = 0x00AF, .value_g = 0x00AF, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL3, .value_a = 0x0012, .value_g = 0x0012, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL4, .value_a = 0x000B, .value_g = 0x000B, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL5, .value_a = 0x005F, .value_g = 0x005F, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL7, .value_a = 0x0040, .value_g = 0x0040, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL8, .value_a = 0x0052, .value_g = 0x0052, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL9, .value_a = 0x0026, .value_g = 0x0026, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL10, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL11, .value_a = 0x0036, .value_g = 0x0036, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL12, .value_a = 0x0057, .value_g = 0x0057, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL13, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL14, .value_a = 0x0075, .value_g = 0x0075, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL15, .value_a = 0x00B4, .value_g = 0x00B4, .flags = 0, }, */
+	/* { .offset = B2062_S_REFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RFPLL_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RFPLL_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL17, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RFPLL_CTL20, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RFPLL_CTL26, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL27, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL28, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RFPLL_CTL29, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RFPLL_CTL32, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	/* { .offset = B2062_S_RXG_CNT0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT6, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	{ .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B2062_FLAG_A, },
+	/* { .offset = B2062_S_RXG_CNT9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT10, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT11, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT12, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT13, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT14, .value_a = 0x00A0, .value_g = 0x00A0, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT15, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2062_S_RXG_CNT17, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+};
+
+void b2062_upload_init_table(struct b43_wldev *dev)
+{
+	const struct b2062_init_tab_entry *e;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(b2062_init_tab); i++) {
+		e = &b2062_init_tab[i];
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			if (!(e->flags & B2062_FLAG_G))
+				continue;
+			b43_radio_write(dev, e->offset, e->value_g);
+		} else {
+			if (!(e->flags & B2062_FLAG_A))
+				continue;
+			b43_radio_write(dev, e->offset, e->value_a);
+		}
+	}
+}
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
+{
+	u32 type, value;
+
+	type = offset & B43_LPTAB_TYPEMASK;
+	offset &= ~B43_LPTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	switch (type) {
+	case B43_LPTAB_8BIT:
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO) & 0xFF;
+		break;
+	case B43_LPTAB_16BIT:
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+		break;
+	case B43_LPTAB_32BIT:
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		value = b43_phy_read(dev, B43_LPPHY_TABLEDATAHI);
+		value <<= 16;
+		value |= b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+		break;
+	default:
+		B43_WARN_ON(1);
+		value = 0;
+	}
+
+	return value;
+}
+
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+			 unsigned int nr_elements, void *_data)
+{
+	u32 type, value;
+	u8 *data = _data;
+	unsigned int i;
+
+	type = offset & B43_LPTAB_TYPEMASK;
+	for (i = 0; i < nr_elements; i++) {
+		value = b43_lptab_read(dev, offset);
+		switch (type) {
+		case B43_LPTAB_8BIT:
+			*data = value;
+			data++;
+			break;
+		case B43_LPTAB_16BIT:
+			*((u16 *)data) = value;
+			data += 2;
+			break;
+		case B43_LPTAB_32BIT:
+			*((u32 *)data) = value;
+			data += 4;
+			break;
+		default:
+			B43_WARN_ON(1);
+		}
+		offset++;
+	}
+}
+
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+	u32 type;
+
+	type = offset & B43_LPTAB_TYPEMASK;
+	offset &= ~B43_LPTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	switch (type) {
+	case B43_LPTAB_8BIT:
+		B43_WARN_ON(value & ~0xFF);
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+		break;
+	case B43_LPTAB_16BIT:
+		B43_WARN_ON(value & ~0xFFFF);
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+		break;
+	case B43_LPTAB_32BIT:
+		b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+		b43_phy_write(dev, B43_LPPHY_TABLEDATAHI, value >> 16);
+		b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+		break;
+	default:
+		B43_WARN_ON(1);
+	}
+}
+
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+			  unsigned int nr_elements, const void *_data)
+{
+	u32 type, value;
+	const u8 *data = _data;
+	unsigned int i;
+
+	type = offset & B43_LPTAB_TYPEMASK;
+	for (i = 0; i < nr_elements; i++) {
+		switch (type) {
+		case B43_LPTAB_8BIT:
+			value = *data;
+			data++;
+			break;
+		case B43_LPTAB_16BIT:
+			value = *((u16 *)data);
+			data += 2;
+			break;
+		case B43_LPTAB_32BIT:
+			value = *((u32 *)data);
+			data += 4;
+			break;
+		default:
+			B43_WARN_ON(1);
+			value = 0;
+		}
+		b43_lptab_write(dev, offset, value);
+		offset++;
+	}
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/tables_lpphy.h linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/tables_lpphy.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/tables_lpphy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/tables_lpphy.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,31 @@
+#ifndef B43_TABLES_LPPHY_H_
+#define B43_TABLES_LPPHY_H_
+
+
+#define B43_LPTAB_TYPEMASK		0xF0000000
+#define B43_LPTAB_8BIT			0x10000000
+#define B43_LPTAB_16BIT			0x20000000
+#define B43_LPTAB_32BIT			0x30000000
+#define B43_LPTAB8(table, offset)	(((table) << 10) | (offset) | B43_LPTAB_8BIT)
+#define B43_LPTAB16(table, offset)	(((table) << 10) | (offset) | B43_LPTAB_16BIT)
+#define B43_LPTAB32(table, offset)	(((table) << 10) | (offset) | B43_LPTAB_32BIT)
+
+/* Table definitions */
+#define B43_LPTAB_TXPWR_R2PLUS		B43_LPTAB32(0x07, 0) /* TX power lookup table (rev >= 2) */
+#define B43_LPTAB_TXPWR_R0_1		B43_LPTAB32(0xA0, 0) /* TX power lookup table (rev < 2) */
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset);
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value);
+
+/* Bulk table access. Note that these functions return the bulk data in
+ * host endianness! The returned data is _not_ a bytearray, but an array
+ * consisting of nr_elements of the data type. */
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+			 unsigned int nr_elements, void *data);
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+			  unsigned int nr_elements, const void *data);
+
+void b2062_upload_init_table(struct b43_wldev *dev);
+
+
+#endif /* B43_TABLES_LPPHY_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/wa.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/wa.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/wa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/wa.c	2009-06-09 23:05:27.000000000 -0400
@@ -62,8 +62,7 @@ void b43_wa_initgains(struct b43_wldev *
 	struct b43_phy *phy = &dev->phy;
 
 	b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
-	b43_phy_write(dev, B43_PHY_LPFGAINCTL,
-		b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F);
+	b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
 	if (phy->rev <= 2)
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
 	b43_radio_write16(dev, 0x0002, 0x1FBF);
@@ -73,11 +72,9 @@ void b43_wa_initgains(struct b43_wldev *
 	b43_phy_write(dev, 0x001D, 0x0F40);
 	b43_phy_write(dev, 0x001F, 0x1C00);
 	if (phy->rev <= 3)
-		b43_phy_write(dev, 0x002A,
-			(b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+		b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
 	else if (phy->rev == 5) {
-		b43_phy_write(dev, 0x002A,
-			(b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+		b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
 		b43_phy_write(dev, 0x00CC, 0x2121);
 	}
 	if (phy->rev >= 3)
@@ -86,7 +83,7 @@ void b43_wa_initgains(struct b43_wldev *
 
 static void b43_wa_divider(struct b43_wldev *dev)
 {
-	b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100);
+	b43_phy_mask(dev, 0x002B, ~0x0100);
 	b43_phy_write(dev, 0x008E, 0x58C1);
 }
 
@@ -272,8 +269,7 @@ static void b43_wa_2060txlna_gain(struct
 
 static void b43_wa_lms(struct b43_wldev *dev)
 {
-	b43_phy_write(dev, 0x0055,
-		(b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+	b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
 }
 
 static void b43_wa_mixedsignal(struct b43_wldev *dev)
@@ -318,23 +314,18 @@ static void b43_wa_crs_ed(struct b43_wld
 	} else if (phy->rev == 2) {
 		b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
 		b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
-		b43_phy_write(dev, B43_PHY_ANTDWELL,
-				  b43_phy_read(dev, B43_PHY_ANTDWELL)
-				  | 0x0800);
+		b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
 	} else {
 		b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
 		b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
 		b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
-		b43_phy_write(dev, B43_PHY_ANTDWELL,
-				  b43_phy_read(dev, B43_PHY_ANTDWELL)
-				  | 0x0800);
+		b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
 	}
 }
 
 static void b43_wa_crs_thr(struct b43_wldev *dev)
 {
-	b43_phy_write(dev, B43_PHY_CRS0,
-			(b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000);
+	b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
 }
 
 static void b43_wa_crs_blank(struct b43_wldev *dev)
@@ -391,72 +382,45 @@ static void b43_wa_altagc(struct b43_wld
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
 	}
 
-	b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA,
-		(b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700);
-	b43_phy_write(dev, B43_PHY_OFDM(0x1A),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F);
-	b43_phy_write(dev, B43_PHY_OFDM(0x1A),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80);
-	b43_phy_write(dev, B43_PHY_ANTWRSETT,
-		(b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300);
-	b43_radio_write16(dev, 0x7A,
-		b43_radio_read16(dev, 0x7A) | 0x0008);
-	b43_phy_write(dev, B43_PHY_N1P1GAIN,
-		(b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008);
-	b43_phy_write(dev, B43_PHY_P1P2GAIN,
-		(b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600);
-	b43_phy_write(dev, B43_PHY_N1N2GAIN,
-		(b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700);
-	b43_phy_write(dev, B43_PHY_N1P1GAIN,
-		(b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100);
+	b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
+	b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
+	b43_radio_set(dev, 0x7A, 0x0008);
+	b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
+	b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
+	b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
+	b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
 	if (phy->rev == 1) {
-		b43_phy_write(dev, B43_PHY_N1N2GAIN,
-				  (b43_phy_read(dev, B43_PHY_N1N2GAIN)
-				   & ~0x000F) | 0x0007);
+		b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
 	}
-	b43_phy_write(dev, B43_PHY_OFDM(0x88),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C);
-	b43_phy_write(dev, B43_PHY_OFDM(0x88),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200);
-	b43_phy_write(dev, B43_PHY_OFDM(0x96),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C);
-	b43_phy_write(dev, B43_PHY_OFDM(0x89),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020);
-	b43_phy_write(dev, B43_PHY_OFDM(0x89),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200);
-	b43_phy_write(dev, B43_PHY_OFDM(0x82),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E);
-	b43_phy_write(dev, B43_PHY_OFDM(0x96),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00);
-	b43_phy_write(dev, B43_PHY_OFDM(0x81),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028);
-	b43_phy_write(dev, B43_PHY_OFDM(0x81),
-		(b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
+	b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00);
 	if (phy->rev == 1) {
 		b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
-		b43_phy_write(dev, B43_PHY_OFDM(0x1B),
-			(b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
 	} else {
-		b43_phy_write(dev, B43_PHY_OFDM(0x1B),
-			b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E);
+		b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
 		b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
-		b43_phy_write(dev, B43_PHY_LPFGAINCTL,
-			(b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004);
+		b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
 		if (phy->rev >= 6) {
 			b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
-			b43_phy_write(dev, B43_PHY_LPFGAINCTL,
-				(b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000);
+			b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000);
 		}
 	}
-	b43_phy_write(dev, B43_PHY_DIVSRCHIDX,
-		(b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x8080) | 0x7874);
+	b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
 	b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
 	if (phy->rev == 1) {
-		b43_phy_write(dev, B43_PHY_DIVP1P2GAIN,
-			(b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600);
+		b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
 		b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
-		b43_phy_write(dev, B43_PHY_ANTWRSETT,
-			(b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E);
+		b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
 		b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
@@ -469,10 +433,8 @@ static void b43_wa_altagc(struct b43_wld
 		b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
 	}
 	if (phy->rev >= 6) {
-		b43_phy_write(dev, B43_PHY_OFDM(0x26),
-			b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003);
-		b43_phy_write(dev, B43_PHY_OFDM(0x26),
-			b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000);
+		b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
+		b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
 	}
 	b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
 }
@@ -538,8 +500,7 @@ static void b43_wa_boards_g(struct b43_w
 			b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
 			if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
 			    (phy->rev >= 7)) {
-				b43_phy_write(dev, B43_PHY_EXTG(0x11),
-					b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF);
+				b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
 				b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
 				b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
 				b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/xmit.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/xmit.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43/xmit.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43/xmit.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@ static int b43_plcp_get_bitrate_idx_cck(
 }
 
 /* Extract the bitrate index out of an OFDM PLCP header. */
-static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
+static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
 {
 	int base = aphy ? 0 : 4;
 
@@ -538,8 +538,14 @@ void b43_rx(struct b43_wldev *dev, struc
 	chanstat = le16_to_cpu(rxhdr->channel);
 	phytype = chanstat & B43_RX_CHAN_PHYTYPE;
 
-	if (macstat & B43_RX_MAC_FCSERR)
+	if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
 		dev->wl->ieee_stats.dot11FCSErrorCount++;
+		status.flag |= RX_FLAG_FAILED_FCS_CRC;
+	}
+	if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
+		status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+	if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
+		status.flag |= RX_FLAG_SHORTPRE;
 	if (macstat & B43_RX_MAC_DECERR) {
 		/* Decryption with the given key failed.
 		 * Drop the packet. We also won't be able to decrypt it with
@@ -606,8 +612,12 @@ void b43_rx(struct b43_wldev *dev, struc
 						phytype == B43_PHYTYPE_A);
 	else
 		status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
-	if (unlikely(status.rate_idx == -1))
-		goto drop;
+	if (unlikely(status.rate_idx == -1)) {
+		/* PLCP seems to be corrupted.
+		 * Drop the frame, if we are not interested in corrupted frames. */
+		if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
+			goto drop;
+	}
 	status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
 
 	/*
@@ -661,7 +671,6 @@ void b43_rx(struct b43_wldev *dev, struc
 		goto drop;
 	}
 
-	dev->stats.last_rx = jiffies;
 	ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
 
 	return;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/dma.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/dma.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -846,7 +846,7 @@ static u64 supported_dma_mask(struct b43
 
 	tmp = b43legacy_read32(dev, SSB_TMSHIGH);
 	if (tmp & SSB_TMSHIGH_DMA64)
-		return DMA_64BIT_MASK;
+		return DMA_BIT_MASK(64);
 	mmio_base = b43legacy_dmacontroller_base(0, 0);
 	b43legacy_write32(dev,
 			mmio_base + B43legacy_DMA32_TXCTL,
@@ -854,18 +854,18 @@ static u64 supported_dma_mask(struct b43
 	tmp = b43legacy_read32(dev, mmio_base +
 			       B43legacy_DMA32_TXCTL);
 	if (tmp & B43legacy_DMA32_TXADDREXT_MASK)
-		return DMA_32BIT_MASK;
+		return DMA_BIT_MASK(32);
 
-	return DMA_30BIT_MASK;
+	return DMA_BIT_MASK(30);
 }
 
 static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
 {
-	if (dmamask == DMA_30BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(30))
 		return B43legacy_DMA_30BIT;
-	if (dmamask == DMA_32BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(32))
 		return B43legacy_DMA_32BIT;
-	if (dmamask == DMA_64BIT_MASK)
+	if (dmamask == DMA_BIT_MASK(64))
 		return B43legacy_DMA_64BIT;
 	B43legacy_WARN_ON(1);
 	return B43legacy_DMA_30BIT;
@@ -1042,13 +1042,13 @@ static int b43legacy_dma_set_mask(struct
 		err = ssb_dma_set_mask(dev->dev, mask);
 		if (!err)
 			break;
-		if (mask == DMA_64BIT_MASK) {
-			mask = DMA_32BIT_MASK;
+		if (mask == DMA_BIT_MASK(64)) {
+			mask = DMA_BIT_MASK(32);
 			fallback = 1;
 			continue;
 		}
-		if (mask == DMA_32BIT_MASK) {
-			mask = DMA_30BIT_MASK;
+		if (mask == DMA_BIT_MASK(32)) {
+			mask = DMA_BIT_MASK(30);
 			fallback = 1;
 			continue;
 		}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/leds.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/leds.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/leds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/leds.c	2009-06-09 23:05:27.000000000 -0400
@@ -146,12 +146,12 @@ static void b43legacy_map_led(struct b43
 	case B43legacy_LED_TRANSFER:
 	case B43legacy_LED_APTRANSFER:
 		snprintf(name, sizeof(name),
-			 "b43legacy-%s:tx", wiphy_name(hw->wiphy));
+			 "b43legacy-%s::tx", wiphy_name(hw->wiphy));
 		b43legacy_register_led(dev, &dev->led_tx, name,
 				 ieee80211_get_tx_led_name(hw),
 				 led_index, activelow);
 		snprintf(name, sizeof(name),
-			 "b43legacy-%s:rx", wiphy_name(hw->wiphy));
+			 "b43legacy-%s::rx", wiphy_name(hw->wiphy));
 		b43legacy_register_led(dev, &dev->led_rx, name,
 				 ieee80211_get_rx_led_name(hw),
 				 led_index, activelow);
@@ -161,7 +161,7 @@ static void b43legacy_map_led(struct b43
 	case B43legacy_LED_RADIO_B:
 	case B43legacy_LED_MODE_BG:
 		snprintf(name, sizeof(name),
-			 "b43legacy-%s:radio", wiphy_name(hw->wiphy));
+			 "b43legacy-%s::radio", wiphy_name(hw->wiphy));
 		b43legacy_register_led(dev, &dev->led_radio, name,
 				 b43legacy_rfkill_led_name(dev),
 				 led_index, activelow);
@@ -172,7 +172,7 @@ static void b43legacy_map_led(struct b43
 	case B43legacy_LED_WEIRD:
 	case B43legacy_LED_ASSOC:
 		snprintf(name, sizeof(name),
-			 "b43legacy-%s:assoc", wiphy_name(hw->wiphy));
+			 "b43legacy-%s::assoc", wiphy_name(hw->wiphy));
 		b43legacy_register_led(dev, &dev->led_assoc, name,
 				 ieee80211_get_assoc_led_name(hw),
 				 led_index, activelow);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 18:04:11.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/b43legacy/main.c	2013-05-03 16:48:03.000000000 -0400
@@ -2648,7 +2648,7 @@ out_unlock_mutex:
 	return err;
 }
 
-static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
+static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u32 brates)
 {
 	struct ieee80211_supported_band *sband =
 		dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211.h linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211.h	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
 #define HOSTAP_80211_H
 
 #include <linux/types.h>
-#include <net/ieee80211.h>
+#include <linux/skbuff.h>
 
 struct hostap_ieee80211_mgmt {
 	__le16 frame_control;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211_rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/etherdevice.h>
 #include <net/lib80211.h>
+#include <linux/if_arp.h>
 
 #include "hostap_80211.h"
 #include "hostap.h"
@@ -17,10 +18,10 @@ static unsigned char bridge_tunnel_heade
 void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats)
 {
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u16 fc;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
 	       "jiffies=%ld\n",
@@ -30,9 +31,10 @@ void hostap_dump_rx_80211(const char *na
 	if (skb->len < 2)
 		return;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
+	fc = le16_to_cpu(hdr->frame_control);
 	printk(KERN_DEBUG "   FC=0x%04x (type=%d:%d)%s%s",
-	       fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+	       fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+	       (fc & IEEE80211_FCTL_STYPE) >> 4,
 	       fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
 	       fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
 
@@ -42,7 +44,7 @@ void hostap_dump_rx_80211(const char *na
 	}
 
 	printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
-	       le16_to_cpu(hdr->seq_ctl));
+	       le16_to_cpu(hdr->seq_ctrl));
 
 	printk(KERN_DEBUG "   A1=%pM", hdr->addr1);
 	printk(" A2=%pM", hdr->addr2);
@@ -63,7 +65,7 @@ int prism2_rx_80211(struct net_device *d
 	int hdrlen, phdrlen, head_need, tail_need;
 	u16 fc;
 	int prism_header, ret;
-	struct ieee80211_hdr_4addr *fhdr;
+	struct ieee80211_hdr *fhdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -84,8 +86,8 @@ int prism2_rx_80211(struct net_device *d
 		phdrlen = 0;
 	}
 
-	fhdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(fhdr->frame_ctl);
+	fhdr = (struct ieee80211_hdr *) skb->data;
+	fc = le16_to_cpu(fhdr->frame_control);
 
 	if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
 		printk(KERN_DEBUG "%s: dropped management frame with header "
@@ -94,7 +96,7 @@ int prism2_rx_80211(struct net_device *d
 		return 0;
 	}
 
-	hdrlen = hostap_80211_get_hdrlen(fc);
+	hdrlen = hostap_80211_get_hdrlen(fhdr->frame_control);
 
 	/* check if there is enough room for extra data; if not, expand skb
 	 * buffer to be large enough for the changes */
@@ -193,7 +195,7 @@ hdr->f.status = s; hdr->f.len = l; hdr->
 	if (prism_header)
 		skb_pull(skb, phdrlen);
 	skb->pkt_type = PACKET_OTHERHOST;
-	skb->protocol = __constant_htons(ETH_P_802_2);
+	skb->protocol = cpu_to_be16(ETH_P_802_2);
 	memset(skb->cb, 0, sizeof(skb->cb));
 	netif_rx(skb);
 
@@ -205,13 +207,11 @@ hdr->f.status = s; hdr->f.len = l; hdr->
 static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
 		       struct hostap_80211_rx_status *rx_stats)
 {
-	struct net_device_stats *stats;
 	int len;
 
 	len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
-	stats = hostap_get_stats(dev);
-	stats->rx_packets++;
-	stats->rx_bytes += len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += len;
 }
 
 
@@ -247,21 +247,21 @@ prism2_frag_cache_find(local_info_t *loc
 
 /* Called only as a tasklet (software IRQ) */
 static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
 {
 	struct sk_buff *skb = NULL;
 	u16 sc;
 	unsigned int frag, seq;
 	struct prism2_frag_entry *entry;
 
-	sc = le16_to_cpu(hdr->seq_ctl);
-	frag = WLAN_GET_SEQ_FRAG(sc);
-	seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+	sc = le16_to_cpu(hdr->seq_ctrl);
+	frag = sc & IEEE80211_SCTL_FRAG;
+	seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
 
 	if (frag == 0) {
 		/* Reserve enough space to fit maximum frame length */
 		skb = dev_alloc_skb(local->dev->mtu +
-				    sizeof(struct ieee80211_hdr_4addr) +
+				    sizeof(struct ieee80211_hdr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
 				    8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -299,14 +299,14 @@ prism2_frag_cache_get(local_info_t *loca
 
 /* Called only as a tasklet (software IRQ) */
 static int prism2_frag_cache_invalidate(local_info_t *local,
-					struct ieee80211_hdr_4addr *hdr)
+					struct ieee80211_hdr *hdr)
 {
 	u16 sc;
 	unsigned int seq;
 	struct prism2_frag_entry *entry;
 
-	sc = le16_to_cpu(hdr->seq_ctl);
-	seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+	sc = le16_to_cpu(hdr->seq_ctrl);
+	seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
 
 	entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
 
@@ -472,10 +472,8 @@ hostap_rx_frame_mgmt(local_info_t *local
 		     struct hostap_80211_rx_status *rx_stats, u16 type,
 		     u16 stype)
 {
-	if (local->iw_mode == IW_MODE_MASTER) {
-		hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
-				     skb->data);
-	}
+	if (local->iw_mode == IW_MODE_MASTER)
+		hostap_update_sta_ps(local, (struct ieee80211_hdr *) skb->data);
 
 	if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
 		if (stype == IEEE80211_STYPE_BEACON &&
@@ -552,8 +550,8 @@ static struct net_device *prism2_rx_get_
 
 
 static int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
-		    u16 fc, struct net_device **wds)
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc,
+		    struct net_device **wds)
 {
 	/* FIX: is this really supposed to accept WDS frames only in Master
 	 * mode? What about Repeater or Managed with WDS frames? */
@@ -611,14 +609,14 @@ static int hostap_is_eapol_frame(local_i
 {
 	struct net_device *dev = local->dev;
 	u16 fc, ethertype;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
 
 	/* check that the frame is unicast frame to us */
 	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -651,14 +649,14 @@ static int
 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
 			struct lib80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdr = (struct ieee80211_hdr *) skb->data;
+	hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
 
 	if (local->tkip_countermeasures &&
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
@@ -689,14 +687,14 @@ static int
 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
 			     int keyidx, struct lib80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdr = (struct ieee80211_hdr *) skb->data;
+	hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
 
 	atomic_inc(&crypt->refcnt);
 	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -720,11 +718,10 @@ void hostap_80211_rx(struct net_device *
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
 	struct net_device *wds = NULL;
-	struct net_device_stats *stats;
 	unsigned int frag;
 	u8 *payload;
 	struct sk_buff *skb2 = NULL;
@@ -747,18 +744,17 @@ void hostap_80211_rx(struct net_device *
 	dev = local->ddev;
 	iface = netdev_priv(dev);
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	stats = hostap_get_stats(dev);
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	if (skb->len < 10)
 		goto rx_dropped;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
-	type = WLAN_FC_GET_TYPE(fc);
-	stype = WLAN_FC_GET_STYPE(fc);
-	sc = le16_to_cpu(hdr->seq_ctl);
-	frag = WLAN_GET_SEQ_FRAG(sc);
-	hdrlen = hostap_80211_get_hdrlen(fc);
+	fc = le16_to_cpu(hdr->frame_control);
+	type = fc & IEEE80211_FCTL_FTYPE;
+	stype = fc & IEEE80211_FCTL_STYPE;
+	sc = le16_to_cpu(hdr->seq_ctrl);
+	frag = sc & IEEE80211_SCTL_FRAG;
+	hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
 
 	/* Put this code here so that we avoid duplicating it in all
 	 * Rx paths. - Jean II */
@@ -866,10 +862,8 @@ void hostap_80211_rx(struct net_device *
 
 	if (hostap_rx_frame_wds(local, hdr, fc, &wds))
 		goto rx_dropped;
-	if (wds) {
+	if (wds)
 		skb->dev = dev = wds;
-		stats = hostap_get_stats(dev);
-	}
 
 	if (local->iw_mode == IW_MODE_MASTER && !wds &&
 	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -878,7 +872,6 @@ void hostap_80211_rx(struct net_device *
 	    memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
 		/* Frame from BSSID of the AP for which we are a client */
 		skb->dev = dev = local->stadev;
-		stats = hostap_get_stats(dev);
 		from_assoc_ap = 1;
 	}
 
@@ -918,7 +911,7 @@ void hostap_80211_rx(struct net_device *
 	if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 	    (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
 		goto rx_dropped;
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 
@@ -931,7 +924,7 @@ void hostap_80211_rx(struct net_device *
 			printk(KERN_DEBUG "%s: Rx cannot get skb from "
 			       "fragment cache (morefrag=%d seq=%u frag=%u)\n",
 			       dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
-			       WLAN_GET_SEQ_SEQ(sc) >> 4, frag);
+			       (sc & IEEE80211_SCTL_SEQ) >> 4, frag);
 			goto rx_dropped;
 		}
 
@@ -972,7 +965,7 @@ void hostap_80211_rx(struct net_device *
 		/* this was the last fragment and the frame will be
 		 * delivered, so remove skb from fragment cache */
 		skb = frag_skb;
-		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+		hdr = (struct ieee80211_hdr *) skb->data;
 		prism2_frag_cache_invalidate(local, hdr);
 	}
 
@@ -983,7 +976,7 @@ void hostap_80211_rx(struct net_device *
 	    hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
 		if (local->ieee_802_1x &&
 		    hostap_is_eapol_frame(local, skb)) {
@@ -1069,8 +1062,8 @@ void hostap_80211_rx(struct net_device *
 		skb_trim(skb, skb->len - ETH_ALEN);
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
 
 	if (local->iw_mode == IW_MODE_MASTER && !wds &&
 	    local->ap->bridge_packets) {
@@ -1094,7 +1087,7 @@ void hostap_80211_rx(struct net_device *
 	if (skb2 != NULL) {
 		/* send to wireless media */
 		skb2->dev = dev;
-		skb2->protocol = __constant_htons(ETH_P_802_3);
+		skb2->protocol = cpu_to_be16(ETH_P_802_3);
 		skb_reset_mac_header(skb2);
 		skb_reset_network_header(skb2);
 		/* skb2->network_header += ETH_HLEN; */
@@ -1115,7 +1108,7 @@ void hostap_80211_rx(struct net_device *
  rx_dropped:
 	dev_kfree_skb(skb);
 
-	stats->rx_dropped++;
+	dev->stats.rx_dropped++;
 	goto rx_exit;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_80211_tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,10 +15,10 @@ static unsigned char bridge_tunnel_heade
 
 void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 {
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u16 fc;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
 	       name, skb->len, jiffies);
@@ -26,9 +26,10 @@ void hostap_dump_tx_80211(const char *na
 	if (skb->len < 2)
 		return;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
+	fc = le16_to_cpu(hdr->frame_control);
 	printk(KERN_DEBUG "   FC=0x%04x (type=%d:%d)%s%s",
-	       fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+	       fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+	       (fc & IEEE80211_FCTL_STYPE) >> 4,
 	       fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
 	       fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
 
@@ -38,7 +39,7 @@ void hostap_dump_tx_80211(const char *na
 	}
 
 	printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
-	       le16_to_cpu(hdr->seq_ctl));
+	       le16_to_cpu(hdr->seq_ctrl));
 
 	printk(KERN_DEBUG "   A1=%pM", hdr->addr1);
 	printk(" A2=%pM", hdr->addr2);
@@ -57,7 +58,7 @@ int hostap_data_start_xmit(struct sk_buf
 	struct hostap_interface *iface;
 	local_info_t *local;
 	int need_headroom, need_tailroom = 0;
-	struct ieee80211_hdr_4addr hdr;
+	struct ieee80211_hdr hdr;
 	u16 fc, ethertype = 0;
 	enum {
 		WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -201,7 +202,7 @@ int hostap_data_start_xmit(struct sk_buf
 		memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
 	}
 
-	hdr.frame_ctl = cpu_to_le16(fc);
+	hdr.frame_control = cpu_to_le16(fc);
 
 	skb_pull(skb, skip_header_bytes);
 	need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
@@ -265,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buf
 	struct hostap_interface *iface;
 	local_info_t *local;
 	struct hostap_skb_tx_data *meta;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u16 fc;
 
 	iface = netdev_priv(dev);
@@ -287,10 +288,10 @@ int hostap_mgmt_start_xmit(struct sk_buf
 	meta->iface = iface;
 
 	if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
-		hdr = (struct ieee80211_hdr_4addr *) skb->data;
-		fc = le16_to_cpu(hdr->frame_ctl);
-		if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
-		    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
+		hdr = (struct ieee80211_hdr *) skb->data;
+		fc = le16_to_cpu(hdr->frame_control);
+		if (ieee80211_is_data(hdr->frame_control) &&
+		    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DATA) {
 			u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
 					     sizeof(rfc1042_header)];
 			meta->ethertype = (pos[0] << 8) | pos[1];
@@ -310,8 +311,7 @@ static struct sk_buff * hostap_tx_encryp
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr_4addr *hdr;
-	u16 fc;
+	struct ieee80211_hdr *hdr;
 	int prefix_len, postfix_len, hdr_len, res;
 
 	iface = netdev_priv(skb->dev);
@@ -324,7 +324,7 @@ static struct sk_buff * hostap_tx_encryp
 
 	if (local->tkip_countermeasures &&
 	    strcmp(crypt->ops->name, "TKIP") == 0) {
-		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+		hdr = (struct ieee80211_hdr *) skb->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "TX packet to %pM\n",
@@ -349,9 +349,8 @@ static struct sk_buff * hostap_tx_encryp
 		return NULL;
 	}
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
- 	fc = le16_to_cpu(hdr->frame_ctl);
-	hdr_len = hostap_80211_get_hdrlen(fc);
+	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr_len = hostap_80211_get_hdrlen(hdr->frame_control);
 
 	/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
 	 * call both MSDU and MPDU encryption functions from here. */
@@ -384,7 +383,7 @@ int hostap_master_start_xmit(struct sk_b
 	ap_tx_ret tx_ret;
 	struct hostap_skb_tx_data *meta;
 	int no_encrypt = 0;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -427,14 +426,14 @@ int hostap_master_start_xmit(struct sk_b
 	tx_ret = hostap_handle_sta_tx(local, &tx);
 	skb = tx.skb;
 	meta = (struct hostap_skb_tx_data *) skb->cb;
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
- 	fc = le16_to_cpu(hdr->frame_ctl);
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
 	switch (tx_ret) {
 	case AP_TX_CONTINUE:
 		break;
 	case AP_TX_CONTINUE_NOT_AUTHORIZED:
 		if (local->ieee_802_1x &&
-		    WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+		    ieee80211_is_data(hdr->frame_control) &&
 		    meta->ethertype != ETH_P_PAE &&
 		    !(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
 			printk(KERN_DEBUG "%s: dropped frame to unauthorized "
@@ -469,10 +468,10 @@ int hostap_master_start_xmit(struct sk_b
 
 		/* remove special version from the frame header */
 		fc &= ~IEEE80211_FCTL_VERS;
-		hdr->frame_ctl = cpu_to_le16(fc);
+		hdr->frame_control = cpu_to_le16(fc);
 	}
 
-	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_DATA) {
+	if (!ieee80211_is_data(hdr->frame_control)) {
 		no_encrypt = 1;
 		tx.crypt = NULL;
 	}
@@ -493,9 +492,9 @@ int hostap_master_start_xmit(struct sk_b
 		/* Add ISWEP flag both for firmware and host based encryption
 		 */
 		fc |= IEEE80211_FCTL_PROTECTED;
-		hdr->frame_ctl = cpu_to_le16(fc);
+		hdr->frame_control = cpu_to_le16(fc);
 	} else if (local->drop_unencrypted &&
-		   WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+		   ieee80211_is_data(hdr->frame_control) &&
 		   meta->ethertype != ETH_P_PAE) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: dropped unencrypted TX data "
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ap.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ap.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ap.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
 #include <linux/random.h>
+#include <linux/if_arp.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
@@ -588,28 +589,24 @@ void hostap_check_sta_fw_version(struct
 static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
 {
 	struct ap_data *ap = data;
-	u16 fc;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 
 	if (!ap->local->hostapd || !ap->local->apdev) {
 		dev_kfree_skb(skb);
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
-
 	/* Pass the TX callback frame to the hostapd; use 802.11 header version
 	 * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
 
-	fc &= ~IEEE80211_FCTL_VERS;
-	fc |= ok ? BIT(1) : BIT(0);
-	hdr->frame_ctl = cpu_to_le16(fc);
+	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_VERS);
+	hdr->frame_control |= cpu_to_le16(ok ? BIT(1) : BIT(0));
 
 	skb->dev = ap->local->apdev;
-	skb_pull(skb, hostap_80211_get_hdrlen(fc));
+	skb_pull(skb, hostap_80211_get_hdrlen(hdr->frame_control));
 	skb->pkt_type = PACKET_OTHERHOST;
-	skb->protocol = __constant_htons(ETH_P_802_2);
+	skb->protocol = cpu_to_be16(ETH_P_802_2);
 	memset(skb->cb, 0, sizeof(skb->cb));
 	netif_rx(skb);
 }
@@ -621,8 +618,8 @@ static void hostap_ap_tx_cb_auth(struct
 {
 	struct ap_data *ap = data;
 	struct net_device *dev = ap->local->dev;
-	struct ieee80211_hdr_4addr *hdr;
-	u16 fc, auth_alg, auth_transaction, status;
+	struct ieee80211_hdr *hdr;
+	u16 auth_alg, auth_transaction, status;
 	__le16 *pos;
 	struct sta_info *sta = NULL;
 	char *txt = NULL;
@@ -632,10 +629,8 @@ static void hostap_ap_tx_cb_auth(struct
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
-	    WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
+	hdr = (struct ieee80211_hdr *) skb->data;
+	if (!ieee80211_is_auth(hdr->frame_control) ||
 	    skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
 		printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
 		       "frame\n", dev->name);
@@ -691,7 +686,7 @@ static void hostap_ap_tx_cb_assoc(struct
 {
 	struct ap_data *ap = data;
 	struct net_device *dev = ap->local->dev;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u16 fc, status;
 	__le16 *pos;
 	struct sta_info *sta = NULL;
@@ -702,11 +697,10 @@ static void hostap_ap_tx_cb_assoc(struct
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
-	    (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
-	     WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
+	if ((!ieee80211_is_assoc_resp(hdr->frame_control) &&
+	     !ieee80211_is_reassoc_resp(hdr->frame_control)) ||
 	    skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
 		printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
 		       "frame\n", dev->name);
@@ -757,12 +751,12 @@ static void hostap_ap_tx_cb_assoc(struct
 static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
 {
 	struct ap_data *ap = data;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	struct sta_info *sta;
 
 	if (skb->len < 24)
 		goto fail;
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 	if (ok) {
 		spin_lock(&ap->sta_table_lock);
 		sta = ap_get_sta(ap, hdr->addr1);
@@ -917,7 +911,7 @@ static void prism2_send_mgmt(struct net_
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	u16 fc;
 	struct sk_buff *skb;
 	struct hostap_skb_tx_data *meta;
@@ -942,8 +936,8 @@ static void prism2_send_mgmt(struct net_
 	}
 
 	fc = type_subtype;
-	hdrlen = hostap_80211_get_hdrlen(fc);
-	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
+	hdrlen = hostap_80211_get_hdrlen(cpu_to_le16(type_subtype));
+	hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
 	if (body)
 		memcpy(skb_put(skb, body_len), body, body_len);
 
@@ -954,11 +948,11 @@ static void prism2_send_mgmt(struct net_
 
 
 	memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
-	if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
+	if (ieee80211_is_data(hdr->frame_control)) {
 		fc |= IEEE80211_FCTL_FROMDS;
 		memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
 		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
-	} else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
+	} else if (ieee80211_is_ctl(hdr->frame_control)) {
 		/* control:ACK does not have addr2 or addr3 */
 		memset(hdr->addr2, 0, ETH_ALEN);
 		memset(hdr->addr3, 0, ETH_ALEN);
@@ -967,7 +961,7 @@ static void prism2_send_mgmt(struct net_
 		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
 	}
 
-	hdr->frame_ctl = cpu_to_le16(fc);
+	hdr->frame_control = cpu_to_le16(fc);
 
 	meta = (struct hostap_skb_tx_data *) skb->cb;
 	memset(meta, 0, sizeof(*meta));
@@ -1284,22 +1278,21 @@ static void handle_authen(local_info_t *
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	size_t hdrlen;
 	struct ap_data *ap = local->ap;
 	char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
 	int len, olen;
 	u16 auth_alg, auth_transaction, status_code;
 	__le16 *pos;
-	u16 resp = WLAN_STATUS_SUCCESS, fc;
+	u16 resp = WLAN_STATUS_SUCCESS;
 	struct sta_info *sta = NULL;
 	struct lib80211_crypt_data *crypt;
 	char *txt = "";
 
 	len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
-	hdrlen = hostap_80211_get_hdrlen(fc);
+	hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
 
 	if (len < 6) {
 		PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
@@ -1435,7 +1428,7 @@ static void handle_authen(local_info_t *
 			    challenge == NULL ||
 			    memcmp(sta->u.sta.challenge, challenge,
 				   WLAN_AUTH_CHALLENGE_LEN) != 0 ||
-			    !(fc & IEEE80211_FCTL_PROTECTED)) {
+			    !ieee80211_has_protected(hdr->frame_control)) {
 				txt = "challenge response incorrect";
 				resp = WLAN_STATUS_CHALLENGE_FAIL;
 				goto fail;
@@ -1488,7 +1481,7 @@ static void handle_authen(local_info_t *
 		       "trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
 		       dev->name, hdr->addr2,
 		       auth_alg, auth_transaction, status_code, len,
-		       fc, resp, txt);
+		       le16_to_cpu(hdr->frame_control), resp, txt);
 	}
 }
 
@@ -1498,7 +1491,7 @@ static void handle_assoc(local_info_t *l
 			 struct hostap_80211_rx_status *rx_stats, int reassoc)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	char body[12], *p, *lpos;
 	int len, left;
 	__le16 *pos;
@@ -1707,7 +1700,7 @@ static void handle_deauth(local_info_t *
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
 	int len;
 	u16 reason_code;
@@ -1749,7 +1742,7 @@ static void handle_disassoc(local_info_t
 			    struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
 	int len;
 	u16 reason_code;
@@ -1788,7 +1781,7 @@ static void handle_disassoc(local_info_t
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_data_nullfunc(local_info_t *local,
-				    struct ieee80211_hdr_4addr *hdr)
+				    struct ieee80211_hdr *hdr)
 {
 	struct net_device *dev = local->dev;
 
@@ -1805,7 +1798,7 @@ static void ap_handle_data_nullfunc(loca
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_dropped_data(local_info_t *local,
-				   struct ieee80211_hdr_4addr *hdr)
+				   struct ieee80211_hdr *hdr)
 {
 	struct net_device *dev = local->dev;
 	struct sta_info *sta;
@@ -1863,7 +1856,7 @@ static void pspoll_send_buffered(local_i
 
 /* Called only as a scheduled task for pending AP frames. */
 static void handle_pspoll(local_info_t *local,
-			  struct ieee80211_hdr_4addr *hdr,
+			  struct ieee80211_hdr *hdr,
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
@@ -1872,8 +1865,7 @@ static void handle_pspoll(local_info_t *
 	struct sk_buff *skb;
 
 	PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
-	       hdr->addr1, hdr->addr2,
-	       !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
+	       hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control));
 
 	if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
 		PDEBUG(DEBUG_AP,
@@ -1984,7 +1976,7 @@ static void handle_wds_oper_queue(struct
 static void handle_beacon(local_info_t *local, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats)
 {
-	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
 	int len, left;
 	u16 beacon_int, capability;
@@ -2143,14 +2135,14 @@ static void handle_ap_item(local_info_t
 	struct net_device *dev = local->dev;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 	u16 fc, type, stype;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 
 	/* FIX: should give skb->len to handler functions and check that the
 	 * buffer is long enough */
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	type = WLAN_FC_GET_TYPE(fc);
-	stype = WLAN_FC_GET_STYPE(fc);
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
+	type = fc & IEEE80211_FCTL_FTYPE;
+	stype = fc & IEEE80211_FCTL_STYPE;
 
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
 	if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
@@ -2262,8 +2254,7 @@ void hostap_rx(struct net_device *dev, s
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	u16 fc;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -2271,17 +2262,15 @@ void hostap_rx(struct net_device *dev, s
 	if (skb->len < 16)
 		goto drop;
 
-	local->stats.rx_packets++;
+	dev->stats.rx_packets++;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
-	fc = le16_to_cpu(hdr->frame_ctl);
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
-	    WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
-	    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
+	    ieee80211_is_beacon(hdr->frame_control))
 		goto drop;
 
-	skb->protocol = __constant_htons(ETH_P_HOSTAP);
+	skb->protocol = cpu_to_be16(ETH_P_HOSTAP);
 	handle_ap_item(local, skb, rx_stats);
 	return;
 
@@ -2294,7 +2283,7 @@ void hostap_rx(struct net_device *dev, s
 static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
 {
 	struct sk_buff *skb;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	struct hostap_80211_rx_status rx_stats;
 
 	if (skb_queue_empty(&sta->tx_buf))
@@ -2307,10 +2296,10 @@ static void schedule_packet_send(local_i
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
+	hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
 
 	/* Generate a fake pspoll frame to start packet delivery */
-	hdr->frame_ctl = __constant_cpu_to_le16(
+	hdr->frame_control = cpu_to_le16(
 		IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
 	memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
 	memcpy(hdr->addr2, sta->addr, ETH_ALEN);
@@ -2689,7 +2678,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
 	struct sta_info *sta = NULL;
 	struct sk_buff *skb = tx->skb;
 	int set_tim, ret;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	struct hostap_skb_tx_data *meta;
 
 	meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2698,7 +2687,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
 	    meta->iface->type == HOSTAP_INTERFACE_STA)
 		goto out;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 
 	if (hdr->addr1[0] & 0x01) {
 		/* broadcast/multicast frame - no AP related processing */
@@ -2753,8 +2742,8 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
 
 	if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
 		/* indicate to STA that more frames follow */
-		hdr->frame_ctl |=
-			__constant_cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+		hdr->frame_control |=
+			cpu_to_le16(IEEE80211_FCTL_MOREDATA);
 	}
 
 	if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
@@ -2828,10 +2817,10 @@ void hostap_handle_sta_release(void *ptr
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 {
 	struct sta_info *sta;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 	struct hostap_skb_tx_data *meta;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 	meta = (struct hostap_skb_tx_data *) skb->cb;
 
 	spin_lock(&local->ap->sta_table_lock);
@@ -2898,8 +2887,8 @@ static void hostap_update_sta_ps2(local_
 
 
 /* Called only as a tasklet (software IRQ). Called for each RX frame to update
- * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+ * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
 {
 	struct sta_info *sta;
 	u16 fc;
@@ -2913,9 +2902,10 @@ int hostap_update_sta_ps(local_info_t *l
 	if (!sta)
 		return -1;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
+	fc = le16_to_cpu(hdr->frame_control);
 	hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
-			      WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
+			      fc & IEEE80211_FCTL_FTYPE,
+			      fc & IEEE80211_FCTL_STYPE);
 
 	atomic_dec(&sta->users);
 	return 0;
@@ -2932,16 +2922,16 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 	int ret;
 	struct sta_info *sta;
 	u16 fc, type, stype;
-	struct ieee80211_hdr_4addr *hdr;
+	struct ieee80211_hdr *hdr;
 
 	if (local->ap == NULL)
 		return AP_RX_CONTINUE;
 
-	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdr = (struct ieee80211_hdr *) skb->data;
 
-	fc = le16_to_cpu(hdr->frame_ctl);
-	type = WLAN_FC_GET_TYPE(fc);
-	stype = WLAN_FC_GET_STYPE(fc);
+	fc = le16_to_cpu(hdr->frame_control);
+	type = fc & IEEE80211_FCTL_FTYPE;
+	stype = fc & IEEE80211_FCTL_STYPE;
 
 	spin_lock(&local->ap->sta_table_lock);
 	sta = ap_get_sta(local->ap, hdr->addr2);
@@ -3064,7 +3054,7 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_handle_sta_crypto(local_info_t *local,
-			     struct ieee80211_hdr_4addr *hdr,
+			     struct ieee80211_hdr *hdr,
 			     struct lib80211_crypt_data **crypt,
 			     void **sta_ptr)
 {
@@ -3166,7 +3156,7 @@ int hostap_add_sta(struct ap_data *ap, u
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_update_rx_stats(struct ap_data *ap,
-			   struct ieee80211_hdr_4addr *hdr,
+			   struct ieee80211_hdr *hdr,
 			   struct hostap_80211_rx_status *rx_stats)
 {
 	struct sta_info *sta;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ap.h linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ap.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ap.h	2009-06-09 23:05:27.000000000 -0400
@@ -235,7 +235,7 @@ struct hostap_tx_data {
 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
 void hostap_handle_sta_release(void *ptr);
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
 typedef enum {
 	AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
 } ap_rx_ret;
@@ -243,13 +243,13 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 			       struct sk_buff *skb,
 			       struct hostap_80211_rx_status *rx_stats,
 			       int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
 			     struct lib80211_crypt_data **crypt,
 			     void **sta_ptr);
 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
 int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
 int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
 			   struct hostap_80211_rx_status *rx_stats);
 void hostap_update_rates(local_info_t *local);
 void hostap_add_wds_links(local_info_t *local);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap.h linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap.h	2009-06-09 23:05:27.000000000 -0400
@@ -31,7 +31,7 @@ void hostap_dump_rx_header(const char *n
 void hostap_dump_tx_header(const char *name,
 			   const struct hfa384x_tx_frame *tx);
 extern const struct header_ops hostap_80211_ops;
-int hostap_80211_get_hdrlen(u16 fc);
+int hostap_80211_get_hdrlen(__le16 fc);
 struct net_device_stats *hostap_get_stats(struct net_device *dev);
 void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 		      int type);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_hw.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_hw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_hw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
 #include <net/lib80211.h>
 #include <asm/irq.h>
 
@@ -1683,7 +1682,7 @@ static int prism2_get_txfid_idx(local_in
 
 	PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
 	       "packet dropped\n");
-	local->stats.tx_dropped++;
+	local->dev->stats.tx_dropped++;
 
 	return -1;
 }
@@ -1788,11 +1787,9 @@ static int prism2_transmit(struct net_de
 		prism2_transmit_cb, (long) idx);
 
 	if (res) {
-		struct net_device_stats *stats;
 		printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
 		       "failed (res=%d)\n", dev->name, res);
-		stats = hostap_get_stats(dev);
-		stats->tx_dropped++;
+		dev->stats.tx_dropped++;
 		netif_wake_queue(dev);
 		return -1;
 	}
@@ -1840,8 +1837,8 @@ static int prism2_tx_80211(struct sk_buf
 	hdr_len = 24;
 	skb_copy_from_linear_data(skb, &txdesc.frame_control, hdr_len);
  	fc = le16_to_cpu(txdesc.frame_control);
-	if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
-	    (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
+	if (ieee80211_is_data(txdesc.frame_control) &&
+	    ieee80211_has_a4(txdesc.frame_control) &&
 	    skb->len >= 30) {
 		/* Addr4 */
 		skb_copy_from_linear_data_offset(skb, hdr_len, txdesc.addr4,
@@ -1940,12 +1937,10 @@ static void prism2_rx(local_info_t *loca
 	struct net_device *dev = local->dev;
 	int res, rx_pending = 0;
 	u16 len, hdr_len, rxfid, status, macport;
-	struct net_device_stats *stats;
 	struct hfa384x_rx_frame rxdesc;
 	struct sk_buff *skb = NULL;
 
 	prism2_callback(local, PRISM2_CALLBACK_RX_START);
-	stats = hostap_get_stats(dev);
 
 	rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
 #ifndef final_version
@@ -2032,7 +2027,7 @@ static void prism2_rx(local_info_t *loca
 	return;
 
  rx_dropped:
-	stats->rx_dropped++;
+	dev->stats.rx_dropped++;
 	if (skb)
 		dev_kfree_skb(skb);
 	goto rx_exit;
@@ -2082,7 +2077,7 @@ static void hostap_rx_skb(local_info_t *
 	stats.rate = rxdesc->rate;
 
 	/* Convert Prism2 RX structure into IEEE 802.11 header */
-	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
+	hdrlen = hostap_80211_get_hdrlen(rxdesc->frame_control);
 	if (hdrlen > rx_hdrlen)
 		hdrlen = rx_hdrlen;
 
@@ -2204,7 +2199,7 @@ static void hostap_tx_callback(local_inf
 		return;
 	}
 
-	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
+	hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
 	len = le16_to_cpu(txdesc->data_len);
 	skb = dev_alloc_skb(hdrlen + len);
 	if (skb == NULL) {
@@ -2315,8 +2310,7 @@ static void hostap_sta_tx_exc_tasklet(un
 		if (skb->len >= sizeof(*txdesc)) {
 			/* Convert Prism2 RX structure into IEEE 802.11 header
 			 */
-			u16 fc = le16_to_cpu(txdesc->frame_control);
-			int hdrlen = hostap_80211_get_hdrlen(fc);
+			int hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
 			memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
 				&txdesc->frame_control, hdrlen);
 
@@ -2337,7 +2331,7 @@ static void prism2_txexc(local_info_t *l
 	struct hfa384x_tx_frame txdesc;
 
 	show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
-	local->stats.tx_errors++;
+	dev->stats.tx_errors++;
 
 	res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
 	HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
@@ -2394,12 +2388,12 @@ static void prism2_txexc(local_info_t *l
 	PDEBUG(DEBUG_EXTRA, "   retry_count=%d tx_rate=%d fc=0x%04x "
 	       "(%s%s%s::%d%s%s)\n",
 	       txdesc.retry_count, txdesc.tx_rate, fc,
-	       WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
-	       WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
-	       WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
-	       WLAN_FC_GET_STYPE(fc) >> 4,
-	       fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
-	       fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
+	       ieee80211_is_mgmt(txdesc.frame_control) ? "Mgmt" : "",
+	       ieee80211_is_ctl(txdesc.frame_control) ? "Ctrl" : "",
+	       ieee80211_is_data(txdesc.frame_control) ? "Data" : "",
+	       (fc & IEEE80211_FCTL_STYPE) >> 4,
+	       ieee80211_has_tods(txdesc.frame_control) ? " ToDS" : "",
+	       ieee80211_has_fromds(txdesc.frame_control) ? " FromDS" : "");
 	PDEBUG(DEBUG_EXTRA, "   A1=%pM A2=%pM A3=%pM A4=%pM\n",
 	       txdesc.addr1, txdesc.addr2,
 	       txdesc.addr3, txdesc.addr4);
@@ -3228,7 +3222,6 @@ while (0)
 
 	hostap_setup_dev(dev, local, HOSTAP_INTERFACE_MASTER);
 
-	dev->hard_start_xmit = hostap_master_start_xmit;
 	dev->type = ARPHRD_IEEE80211;
 	dev->header_ops = &hostap_80211_ops;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_info.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_info.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_info.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_info.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,6 @@
 /* Host AP driver Info Frame processing (part of hostap.o module) */
 
+#include <linux/if_arp.h>
 #include "hostap_wlan.h"
 #include "hostap.h"
 #include "hostap_ap.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/ethtool.h>
+#include <linux/if_arp.h>
 #include <net/lib80211.h>
 
 #include "hostap_wlan.h"
@@ -1638,7 +1639,7 @@ static int prism2_request_hostscan(struc
 	memset(&scan_req, 0, sizeof(scan_req));
 	scan_req.channel_list = cpu_to_le16(local->channel_mask &
 					    local->scan_channel_mask);
-	scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+	scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
 	if (ssid) {
 		if (ssid_len > 32)
 			return -EINVAL;
@@ -1668,7 +1669,7 @@ static int prism2_request_scan(struct ne
 	memset(&scan_req, 0, sizeof(scan_req));
 	scan_req.channel_list = cpu_to_le16(local->channel_mask &
 					    local->scan_channel_mask);
-	scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+	scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
 
 	/* FIX:
 	 * It seems to be enough to set roaming mode for a short moment to
@@ -2514,7 +2515,7 @@ static int prism2_ioctl_priv_prism2_para
 		u16 rate;
 
 		memset(&scan_req, 0, sizeof(scan_req));
-		scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
+		scan_req.channel_list = cpu_to_le16(0x3fff);
 		switch (value) {
 		case 1: rate = HFA384X_RATES_1MBPS; break;
 		case 2: rate = HFA384X_RATES_2MBPS; break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/etherdevice.h>
 #include <net/net_namespace.h>
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
 #include <net/lib80211.h>
 #include <asm/uaccess.h>
 
@@ -543,7 +542,8 @@ void hostap_dump_rx_header(const char *n
 	fc = __le16_to_cpu(rx->frame_control);
 	printk(KERN_DEBUG "   FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
 	       "data_len=%d%s%s\n",
-	       fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+	       fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+	       (fc & IEEE80211_FCTL_STYPE) >> 4,
 	       __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
 	       __le16_to_cpu(rx->data_len),
 	       fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -570,7 +570,8 @@ void hostap_dump_tx_header(const char *n
 	fc = __le16_to_cpu(tx->frame_control);
 	printk(KERN_DEBUG "   FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
 	       "data_len=%d%s%s\n",
-	       fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+	       fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+	       (fc & IEEE80211_FCTL_STYPE) >> 4,
 	       __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
 	       __le16_to_cpu(tx->data_len),
 	       fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -593,37 +594,16 @@ static int hostap_80211_header_parse(con
 }
 
 
-int hostap_80211_get_hdrlen(u16 fc)
+int hostap_80211_get_hdrlen(__le16 fc)
 {
-	int hdrlen = 24;
-
-	switch (WLAN_FC_GET_TYPE(fc)) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = 30; /* Addr4 */
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (WLAN_FC_GET_STYPE(fc)) {
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
-			break;
-		default:
-			hdrlen = 16;
-			break;
-		}
-		break;
-	}
-
-	return hdrlen;
-}
-
+	if (ieee80211_is_data(fc) && ieee80211_has_a4 (fc))
+		return 30; /* Addr4 */
+	else if (ieee80211_is_cts(fc) || ieee80211_is_ack(fc))
+		return 10;
+	else if (ieee80211_is_ctl(fc))
+		return 16;
 
-struct net_device_stats *hostap_get_stats(struct net_device *dev)
-{
-	struct hostap_interface *iface;
-	iface = netdev_priv(dev);
-	return &iface->stats;
+	return 24;
 }
 
 
@@ -835,6 +815,46 @@ const struct header_ops hostap_80211_ops
 };
 EXPORT_SYMBOL(hostap_80211_ops);
 
+
+static const struct net_device_ops hostap_netdev_ops = {
+	.ndo_start_xmit		= hostap_data_start_xmit,
+
+	.ndo_open		= prism2_open,
+	.ndo_stop		= prism2_close,
+	.ndo_do_ioctl		= hostap_ioctl,
+	.ndo_set_mac_address	= prism2_set_mac_address,
+	.ndo_set_multicast_list = hostap_set_multicast_list,
+	.ndo_change_mtu 	= prism2_change_mtu,
+	.ndo_tx_timeout 	= prism2_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_mgmt_netdev_ops = {
+	.ndo_start_xmit		= hostap_mgmt_start_xmit,
+
+	.ndo_open		= prism2_open,
+	.ndo_stop		= prism2_close,
+	.ndo_do_ioctl		= hostap_ioctl,
+	.ndo_set_mac_address	= prism2_set_mac_address,
+	.ndo_set_multicast_list = hostap_set_multicast_list,
+	.ndo_change_mtu 	= prism2_change_mtu,
+	.ndo_tx_timeout 	= prism2_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_master_ops = {
+	.ndo_start_xmit 	= hostap_master_start_xmit,
+
+	.ndo_open		= prism2_open,
+	.ndo_stop		= prism2_close,
+	.ndo_do_ioctl		= hostap_ioctl,
+	.ndo_set_mac_address	= prism2_set_mac_address,
+	.ndo_set_multicast_list = hostap_set_multicast_list,
+	.ndo_change_mtu 	= prism2_change_mtu,
+	.ndo_tx_timeout 	= prism2_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 		      int type)
 {
@@ -844,37 +864,31 @@ void hostap_setup_dev(struct net_device
 	ether_setup(dev);
 
 	/* kernel callbacks */
-	dev->get_stats = hostap_get_stats;
 	if (iface) {
 		/* Currently, we point to the proper spy_data only on
 		 * the main_dev. This could be fixed. Jean II */
 		iface->wireless_data.spy_data = &iface->spy_data;
 		dev->wireless_data = &iface->wireless_data;
 	}
-	dev->wireless_handlers =
-		(struct iw_handler_def *) &hostap_iw_handler_def;
-	dev->do_ioctl = hostap_ioctl;
-	dev->open = prism2_open;
-	dev->stop = prism2_close;
-	dev->set_mac_address = prism2_set_mac_address;
-	dev->set_multicast_list = hostap_set_multicast_list;
-	dev->change_mtu = prism2_change_mtu;
-	dev->tx_timeout = prism2_tx_timeout;
+	dev->wireless_handlers = &hostap_iw_handler_def;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-	if (type == HOSTAP_INTERFACE_AP) {
-		dev->hard_start_xmit = hostap_mgmt_start_xmit;
+	switch(type) {
+	case HOSTAP_INTERFACE_AP:
+		dev->netdev_ops = &hostap_mgmt_netdev_ops;
 		dev->type = ARPHRD_IEEE80211;
 		dev->header_ops = &hostap_80211_ops;
-	} else {
-		dev->hard_start_xmit = hostap_data_start_xmit;
+		break;
+	case HOSTAP_INTERFACE_MASTER:
+		dev->tx_queue_len = 0;	/* use main radio device queue */
+		dev->netdev_ops = &hostap_master_ops;
+		break;
+	default:
+		dev->netdev_ops = &hostap_netdev_ops;
 	}
 
 	dev->mtu = local->mtu;
-	if (type != HOSTAP_INTERFACE_MASTER) {
-		/* use main radio device queue */
-		dev->tx_queue_len = 0;
-	}
+
 
 	SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
 
@@ -1124,7 +1138,6 @@ EXPORT_SYMBOL(hostap_set_auth_algs);
 EXPORT_SYMBOL(hostap_dump_rx_header);
 EXPORT_SYMBOL(hostap_dump_tx_header);
 EXPORT_SYMBOL(hostap_80211_get_hdrlen);
-EXPORT_SYMBOL(hostap_get_stats);
 EXPORT_SYMBOL(hostap_setup_dev);
 EXPORT_SYMBOL(hostap_set_multicast_list_queue);
 EXPORT_SYMBOL(hostap_set_hostapd);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_wlan.h linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_wlan.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/hostap/hostap_wlan.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/hostap/hostap_wlan.h	2009-06-09 23:05:27.000000000 -0400
@@ -684,7 +684,6 @@ struct local_info {
 	u16 channel_mask; /* mask of allowed channels */
 	u16 scan_channel_mask; /* mask of channels to be scanned */
 	struct comm_tallies_sums comm_tallies;
-	struct net_device_stats stats;
 	struct proc_dir_entry *proc;
 	int iw_mode; /* operating mode (IW_MODE_*) */
 	int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ieee80211.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ieee80211.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ieee80211.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ieee80211.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,1087 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <j@w1.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004-2005, 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. See README and COPYING for
+ * more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
+ *          various structure changes, and crypto API init method
+ */
+#ifndef IEEE80211_H
+#define IEEE80211_H
+#include <linux/if_ether.h>	/* ETH_ALEN */
+#include <linux/kernel.h>	/* ARRAY_SIZE */
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+
+#include <net/lib80211.h>
+
+#define IEEE80211_VERSION "git-1.1.13"
+
+#define IEEE80211_DATA_LEN		2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+   6.2.1.1.2.
+
+   The figure in section 7.1.2 suggests a body size of up to 2312
+   bytes is allowed, which is a bit confusing, I suspect this
+   represents the 2304 bytes of real data, plus a possible 8 bytes of
+   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN    4
+#define IEEE80211_HLEN			(IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+#define MIN_FRAG_THRESHOLD     256U
+#define	MAX_FRAG_THRESHOLD     2346U
+
+/* QOS control */
+#define IEEE80211_QCTL_TID		0x000F
+
+/* debug macros */
+
+#ifdef CONFIG_LIBIPW_DEBUG
+extern u32 ieee80211_debug_level;
+#define IEEE80211_DEBUG(level, fmt, args...) \
+do { if (ieee80211_debug_level & (level)) \
+  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
+         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+static inline bool ieee80211_ratelimit_debug(u32 level)
+{
+	return (ieee80211_debug_level & level) && net_ratelimit();
+}
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+static inline bool ieee80211_ratelimit_debug(u32 level)
+{
+	return false;
+}
+#endif				/* CONFIG_LIBIPW_DEBUG */
+
+/*
+ * To use the debug system:
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IEEE80211_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
+ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ieee80211/debug_level
+ *
+ * you simply need to add your entry to the ieee80211_debug_level array.
+ *
+ * If you do not see debug_level in /proc/net/ieee80211 then you do not have
+ * CONFIG_LIBIPW_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IEEE80211_DL_INFO          (1<<0)
+#define IEEE80211_DL_WX            (1<<1)
+#define IEEE80211_DL_SCAN          (1<<2)
+#define IEEE80211_DL_STATE         (1<<3)
+#define IEEE80211_DL_MGMT          (1<<4)
+#define IEEE80211_DL_FRAG          (1<<5)
+#define IEEE80211_DL_DROP          (1<<7)
+
+#define IEEE80211_DL_TX            (1<<8)
+#define IEEE80211_DL_RX            (1<<9)
+#define IEEE80211_DL_QOS           (1<<31)
+
+#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
+
+#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
+#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
+#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
+#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
+#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
+#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>	/* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY		/* enable iwspy support */
+#endif
+#include <net/iw_handler.h>	/* new driver API */
+
+#define ETH_P_PREAUTH 0x88C7	/* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct ieee80211_snap_hdr {
+
+	u8 dsap;		/* always 0xAA */
+	u8 ssap;		/* always 0xAA */
+	u8 ctrl;		/* always 0x03 */
+	u8 oui[P80211_OUI_LEN];	/* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+#define IEEE80211_STATMASK_SIGNAL (1<<0)
+#define IEEE80211_STATMASK_RSSI (1<<1)
+#define IEEE80211_STATMASK_NOISE (1<<2)
+#define IEEE80211_STATMASK_RATE (1<<3)
+#define IEEE80211_STATMASK_WEMASK 0x7
+
+#define IEEE80211_CCK_MODULATION    (1<<0)
+#define IEEE80211_OFDM_MODULATION   (1<<1)
+
+#define IEEE80211_24GHZ_BAND     (1<<0)
+#define IEEE80211_52GHZ_BAND     (1<<1)
+
+#define IEEE80211_CCK_RATE_1MB		        0x02
+#define IEEE80211_CCK_RATE_2MB		        0x04
+#define IEEE80211_CCK_RATE_5MB		        0x0B
+#define IEEE80211_CCK_RATE_11MB		        0x16
+#define IEEE80211_OFDM_RATE_6MB		        0x0C
+#define IEEE80211_OFDM_RATE_9MB		        0x12
+#define IEEE80211_OFDM_RATE_12MB		0x18
+#define IEEE80211_OFDM_RATE_18MB		0x24
+#define IEEE80211_OFDM_RATE_24MB		0x30
+#define IEEE80211_OFDM_RATE_36MB		0x48
+#define IEEE80211_OFDM_RATE_48MB		0x60
+#define IEEE80211_OFDM_RATE_54MB		0x6C
+#define IEEE80211_BASIC_RATE_MASK		0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define IEEE80211_CCK_RATES_MASK	        0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
+	IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
+        IEEE80211_CCK_RATE_5MB_MASK | \
+        IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
+	IEEE80211_OFDM_RATE_12MB_MASK | \
+	IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
+	IEEE80211_OFDM_RATE_9MB_MASK  | \
+	IEEE80211_OFDM_RATE_18MB_MASK | \
+	IEEE80211_OFDM_RATE_36MB_MASK | \
+	IEEE80211_OFDM_RATE_48MB_MASK | \
+	IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+#define IEEE80211_NUM_OFDM_RATES	    8
+#define IEEE80211_NUM_CCK_RATES	            4
+#define IEEE80211_OFDM_SHIFT_MASK_A         4
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ *       information for frames received.
+ *       For ieee80211_rx_mgt, you need to set at least the 'len' parameter.
+ */
+struct ieee80211_rx_stats {
+	u32 mac_time;
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate;		/* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define IEEE80211_FRAG_CACHE_LEN 4
+
+struct ieee80211_frag_entry {
+	unsigned long first_frag_time;
+	unsigned int seq;
+	unsigned int last_frag;
+	struct sk_buff *skb;
+	u8 src_addr[ETH_ALEN];
+	u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+	unsigned int tx_unicast_frames;
+	unsigned int tx_multicast_frames;
+	unsigned int tx_fragments;
+	unsigned int tx_unicast_octets;
+	unsigned int tx_multicast_octets;
+	unsigned int tx_deferred_transmissions;
+	unsigned int tx_single_retry_frames;
+	unsigned int tx_multiple_retry_frames;
+	unsigned int tx_retry_limit_exceeded;
+	unsigned int tx_discards;
+	unsigned int rx_unicast_frames;
+	unsigned int rx_multicast_frames;
+	unsigned int rx_fragments;
+	unsigned int rx_unicast_octets;
+	unsigned int rx_multicast_octets;
+	unsigned int rx_fcs_errors;
+	unsigned int rx_discards_no_buffer;
+	unsigned int tx_discards_wrong_sa;
+	unsigned int rx_discards_undecryptable;
+	unsigned int rx_message_in_msg_fragments;
+	unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_device;
+
+#define SEC_KEY_1		(1<<0)
+#define SEC_KEY_2		(1<<1)
+#define SEC_KEY_3		(1<<2)
+#define SEC_KEY_4		(1<<3)
+#define SEC_ACTIVE_KEY		(1<<4)
+#define SEC_AUTH_MODE		(1<<5)
+#define SEC_UNICAST_GROUP	(1<<6)
+#define SEC_LEVEL		(1<<7)
+#define SEC_ENABLED		(1<<8)
+#define SEC_ENCRYPT		(1<<9)
+
+#define SEC_LEVEL_0		0	/* None */
+#define SEC_LEVEL_1		1	/* WEP 40 and 104 bit */
+#define SEC_LEVEL_2		2	/* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP	3	/* Level 1 + CKIP */
+#define SEC_LEVEL_3		4	/* Level 2 + CCMP */
+
+#define SEC_ALG_NONE		0
+#define SEC_ALG_WEP		1
+#define SEC_ALG_TKIP		2
+#define SEC_ALG_CCMP		3
+
+#define WEP_KEYS		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN		32
+#define SCM_TEMPORAL_KEY_LENGTH	16
+
+struct ieee80211_security {
+	u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
+	u8 auth_mode;
+	u8 encode_alg[WEP_KEYS];
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	u8 level;
+	u16 flags;
+} __attribute__ ((packed));
+
+/*
+
+ 802.11 data frame from AP
+
+      ,-------------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `-------------------------------------------------------------------'
+
+Total: 28-2340 bytes
+
+*/
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_hdr_1addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+struct ieee80211_auth {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/* challenge */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_channel_switch {
+	u8 id;
+	u8 len;
+	u8 mode;
+	u8 channel;
+	u8 count;
+} __attribute__ ((packed));
+
+struct ieee80211_action {
+	struct ieee80211_hdr_3addr header;
+	u8 category;
+	u8 action;
+	union {
+		struct ieee80211_action_exchange {
+			u8 token;
+			struct ieee80211_info_element info_element[0];
+		} exchange;
+		struct ieee80211_channel_switch channel_switch;
+
+	} format;
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+	struct ieee80211_hdr_3addr header;
+	__le16 reason;
+} __attribute__ ((packed));
+
+/* Alias deauth for disassoc */
+#define ieee80211_deauth ieee80211_disassoc
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	__le32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	/* SSID, supported rates, FH params, DS params,
+	 * CF params, IBSS params, TIM (if beacon), RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_reassoc_request {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	/* supported rates */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 rts_included;
+	u8 reserved;
+	u16 frag_size;
+	u16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+/* SWEEP TABLE ENTRIES NUMBER */
+#define MAX_SWEEP_TAB_ENTRIES		  42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH                  ((u8)12)
+#define MAX_RATES_EX_LENGTH               ((u8)16)
+#define MAX_NETWORK_COUNT                  128
+
+#define CRC_LENGTH                 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_HAS_OFDM       (1<<1)
+#define NETWORK_HAS_CCK        (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+					 NETWORK_HAS_QOS_INFORMATION)
+
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+
+struct ieee80211_qos_information_element {
+	u8 elementID;
+	u8 length;
+	u8 qui[QOS_OUI_LEN];
+	u8 qui_type;
+	u8 qui_subtype;
+	u8 version;
+	u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+	u8 aci_aifsn;
+	u8 ecw_min_max;
+	__le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+	struct ieee80211_qos_information_element info_element;
+	u8 reserved;
+	struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+	__le16 cw_min[QOS_QUEUE_NUM];
+	__le16 cw_max[QOS_QUEUE_NUM];
+	u8 aifs[QOS_QUEUE_NUM];
+	u8 flag[QOS_QUEUE_NUM];
+	__le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+	struct ieee80211_qos_parameters parameters;
+	int active;
+	int supported;
+	u8 param_count;
+	u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+	u8 tim_count;
+	u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
+
+enum {				/* ieee80211_basic_report.map */
+	IEEE80211_BASIC_MAP_BSS = (1 << 0),
+	IEEE80211_BASIC_MAP_OFDM = (1 << 1),
+	IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
+	IEEE80211_BASIC_MAP_RADAR = (1 << 3),
+	IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
+	/* Bits 5-7 are reserved */
+
+};
+struct ieee80211_basic_report {
+	u8 channel;
+	__le64 start_time;
+	__le16 duration;
+	u8 map;
+} __attribute__ ((packed));
+
+enum {				/* ieee80211_measurement_request.mode */
+	/* Bit 0 is reserved */
+	IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
+	IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
+	IEEE80211_MEASUREMENT_REPORT = (1 << 3),
+	/* Bits 4-7 are reserved */
+};
+
+enum {
+	IEEE80211_REPORT_BASIC = 0,	/* required */
+	IEEE80211_REPORT_CCA = 1,	/* optional */
+	IEEE80211_REPORT_RPI = 2,	/* optional */
+	/* 3-255 reserved */
+};
+
+struct ieee80211_measurement_params {
+	u8 channel;
+	__le64 start_time;
+	__le16 duration;
+} __attribute__ ((packed));
+
+struct ieee80211_measurement_request {
+	struct ieee80211_info_element ie;
+	u8 token;
+	u8 mode;
+	u8 type;
+	struct ieee80211_measurement_params params[0];
+} __attribute__ ((packed));
+
+struct ieee80211_measurement_report {
+	struct ieee80211_info_element ie;
+	u8 token;
+	u8 mode;
+	u8 type;
+	union {
+		struct ieee80211_basic_report basic[0];
+	} u;
+} __attribute__ ((packed));
+
+struct ieee80211_tpc_report {
+	u8 transmit_power;
+	u8 link_margin;
+} __attribute__ ((packed));
+
+struct ieee80211_channel_map {
+	u8 channel;
+	u8 map;
+} __attribute__ ((packed));
+
+struct ieee80211_ibss_dfs {
+	struct ieee80211_info_element ie;
+	u8 owner[ETH_ALEN];
+	u8 recovery_interval;
+	struct ieee80211_channel_map channel_map[0];
+};
+
+struct ieee80211_csa {
+	u8 mode;
+	u8 channel;
+	u8 count;
+} __attribute__ ((packed));
+
+struct ieee80211_quiet {
+	u8 count;
+	u8 period;
+	u8 duration;
+	u8 offset;
+} __attribute__ ((packed));
+
+struct ieee80211_network {
+	/* These entries are used to identify a unique network */
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	/* Ensure null-terminated for any debug msgs */
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+
+	struct ieee80211_qos_data qos_data;
+
+	/* These are network statistics */
+	struct ieee80211_rx_stats stats;
+	u16 capability;
+	u8 rates[MAX_RATES_LENGTH];
+	u8 rates_len;
+	u8 rates_ex[MAX_RATES_EX_LENGTH];
+	u8 rates_ex_len;
+	unsigned long last_scanned;
+	u8 mode;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8 erp_value;
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8 rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+	struct ieee80211_tim_parameters tim;
+
+	/* 802.11h info */
+
+	/* Power Constraint - mandatory if spctrm mgmt required */
+	u8 power_constraint;
+
+	/* TPC Report - mandatory if spctrm mgmt required */
+	struct ieee80211_tpc_report tpc_report;
+
+	/* IBSS DFS - mandatory if spctrm mgmt required and IBSS
+	 * NOTE: This is variable length and so must be allocated dynamically */
+	struct ieee80211_ibss_dfs *ibss_dfs;
+
+	/* Channel Switch Announcement - optional if spctrm mgmt required */
+	struct ieee80211_csa csa;
+
+	/* Quiet - optional if spctrm mgmt required */
+	struct ieee80211_quiet quiet;
+
+	struct list_head list;
+};
+
+enum ieee80211_state {
+	IEEE80211_UNINITIALIZED = 0,
+	IEEE80211_INITIALIZED,
+	IEEE80211_ASSOCIATING,
+	IEEE80211_ASSOCIATED,
+	IEEE80211_AUTHENTICATING,
+	IEEE80211_AUTHENTICATED,
+	IEEE80211_SHUTDOWN
+};
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+				  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+				  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+enum {
+	IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+	IEEE80211_CH_80211H_RULES = (1 << 1),
+	IEEE80211_CH_B_ONLY = (1 << 2),
+	IEEE80211_CH_NO_IBSS = (1 << 3),
+	IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
+	IEEE80211_CH_RADAR_DETECT = (1 << 5),
+	IEEE80211_CH_INVALID = (1 << 6),
+};
+
+struct ieee80211_channel {
+	u32 freq;	/* in MHz */
+	u8 channel;
+	u8 flags;
+	u8 max_power;	/* in dBm */
+};
+
+struct ieee80211_geo {
+	u8 name[4];
+	u8 bg_channels;
+	u8 a_channels;
+	struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
+	struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
+};
+
+struct ieee80211_device {
+	struct net_device *dev;
+	struct ieee80211_security sec;
+
+	/* Bookkeeping structures */
+	struct ieee80211_stats ieee_stats;
+
+	struct ieee80211_geo geo;
+
+	/* Probe / Beacon management */
+	struct list_head network_free_list;
+	struct list_head network_list;
+	struct ieee80211_network *networks;
+	int scans;
+	int scan_age;
+
+	int iw_mode;		/* operating mode (IW_MODE_*) */
+	struct iw_spy_data spy_data;	/* iwspy support */
+
+	spinlock_t lock;
+
+	int tx_headroom;	/* Set to size of any additional room needed at front
+				 * of allocated Tx SKBs */
+	u32 config;
+
+	/* WEP and other encryption related settings at the device level */
+	int open_wep;		/* Set to 1 to allow unencrypted frames */
+
+	int reset_on_keychange;	/* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_encrypt_msdu;
+	int host_decrypt;
+	/* host performs multicast decryption */
+	int host_mc_decrypt;
+
+	/* host should strip IV and ICV from protected frames */
+	/* meaningful only when hardware decryption is being used */
+	int host_strip_iv_icv;
+
+	int host_open_frag;
+	int host_build_iv;
+	int ieee802_1x;		/* is IEEE 802.1X used */
+
+	/* WPA data */
+	int wpa_enabled;
+	int drop_unencrypted;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+
+	struct lib80211_crypt_info crypt_info;
+
+	int bcrx_sta_key;	/* use individual keys to override default keys even
+				 * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx;
+	u16 fts;		/* Fragmentation Threshold */
+	u16 rts;		/* RTS threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	enum ieee80211_state state;
+
+	int mode;		/* A, B, G */
+	int modulation;		/* CCK, OFDM */
+	int freq_band;		/* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_true;		/* ABG flag              */
+
+	int perfect_rssi;
+	int worst_rssi;
+
+	u16 prev_seq_ctl;	/* used to drop duplicate frames */
+
+	/* Callback functions */
+	void (*set_security) (struct net_device * dev,
+			      struct ieee80211_security * sec);
+	int (*hard_start_xmit) (struct ieee80211_txb * txb,
+				struct net_device * dev, int pri);
+	int (*reset_port) (struct net_device * dev);
+	int (*is_queue_full) (struct net_device * dev, int pri);
+
+	int (*handle_management) (struct net_device * dev,
+				  struct ieee80211_network * network, u16 type);
+	int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Typical STA methods */
+	int (*handle_auth) (struct net_device * dev,
+			    struct ieee80211_auth * auth);
+	int (*handle_deauth) (struct net_device * dev,
+			      struct ieee80211_deauth * auth);
+	int (*handle_action) (struct net_device * dev,
+			      struct ieee80211_action * action,
+			      struct ieee80211_rx_stats * stats);
+	int (*handle_disassoc) (struct net_device * dev,
+				struct ieee80211_disassoc * assoc);
+	int (*handle_beacon) (struct net_device * dev,
+			      struct ieee80211_beacon * beacon,
+			      struct ieee80211_network * network);
+	int (*handle_probe_response) (struct net_device * dev,
+				      struct ieee80211_probe_response * resp,
+				      struct ieee80211_network * network);
+	int (*handle_probe_request) (struct net_device * dev,
+				     struct ieee80211_probe_request * req,
+				     struct ieee80211_rx_stats * stats);
+	int (*handle_assoc_response) (struct net_device * dev,
+				      struct ieee80211_assoc_response * resp,
+				      struct ieee80211_network * network);
+
+	/* Typical AP methods */
+	int (*handle_assoc_request) (struct net_device * dev);
+	int (*handle_reassoc_request) (struct net_device * dev,
+				       struct ieee80211_reassoc_request * req);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+static inline void *ieee80211_priv(struct net_device *dev)
+{
+	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+}
+
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+					  int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+static inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+	u16 stype = WLAN_FC_GET_STYPE(fc);
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN;
+		if (stype & IEEE80211_STYPE_QOS_DATA)
+			hdrlen += 2;
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+	switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))) {
+	case IEEE80211_1ADDR_LEN:
+		return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+	case IEEE80211_2ADDR_LEN:
+		return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+	case IEEE80211_3ADDR_LEN:
+		return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+	case IEEE80211_4ADDR_LEN:
+		return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+	}
+	return NULL;
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+	case IEEE80211_OFDM_RATE_6MB:
+	case IEEE80211_OFDM_RATE_9MB:
+	case IEEE80211_OFDM_RATE_12MB:
+	case IEEE80211_OFDM_RATE_18MB:
+	case IEEE80211_OFDM_RATE_24MB:
+	case IEEE80211_OFDM_RATE_36MB:
+	case IEEE80211_OFDM_RATE_48MB:
+	case IEEE80211_OFDM_RATE_54MB:
+		return 1;
+	}
+	return 0;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+	case IEEE80211_CCK_RATE_1MB:
+	case IEEE80211_CCK_RATE_2MB:
+	case IEEE80211_CCK_RATE_5MB:
+	case IEEE80211_CCK_RATE_11MB:
+		return 1;
+	}
+	return 0;
+}
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+extern int ieee80211_change_mtu(struct net_device *dev, int new_mtu);
+
+extern void ieee80211_networks_age(struct ieee80211_device *ieee,
+				   unsigned long age_secs);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+/* ieee80211_rx.c */
+extern void ieee80211_rx_any(struct ieee80211_device *ieee,
+		     struct sk_buff *skb, struct ieee80211_rx_stats *stats);
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats);
+/* make sure to set stats->len */
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+			     struct ieee80211_hdr_4addr *header,
+			     struct ieee80211_rx_stats *stats);
+extern void ieee80211_network_reset(struct ieee80211_network *network);
+
+/* ieee80211_geo.c */
+extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
+						     *ieee);
+extern int ieee80211_set_geo(struct ieee80211_device *ieee,
+			     const struct ieee80211_geo *geo);
+
+extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
+				      u8 channel);
+extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
+				      u8 channel);
+extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
+extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee,
+				      u8 channel);
+extern const struct ieee80211_channel *ieee80211_get_channel(struct
+							     ieee80211_device
+							     *ieee, u8 channel);
+extern u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee,
+				      u8 channel);
+
+/* ieee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu, char *extra);
+
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+	ieee->scans++;
+}
+
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+	return ieee->scans;
+}
+
+#endif				/* IEEE80211_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 18:04:20.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2100.c	2013-05-03 16:48:10.000000000 -0400
@@ -1692,7 +1692,13 @@ static int ipw2100_up(struct ipw2100_pri
 	u32 lock;
 	u32 ord_len = sizeof(lock);
 
-	/* Quite if manually disabled. */
+	/* Age scan list entries found before suspend */
+	if (priv->suspend_time) {
+		ieee80211_networks_age(priv->ieee, priv->suspend_time);
+		priv->suspend_time = 0;
+	}
+
+	/* Quiet if manually disabled. */
 	if (priv->status & STATUS_RF_KILL_SW) {
 		IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
 			       "switch\n", priv->net_dev->name);
@@ -1910,7 +1916,8 @@ static void isr_indicate_associated(stru
 {
 
 #define MAC_ASSOCIATION_READ_DELAY (HZ)
-	int ret, len, essid_len;
+	int ret;
+	unsigned int len, essid_len;
 	char essid[IW_ESSID_MAX_SIZE];
 	u32 txrate;
 	u32 chan;
@@ -2355,7 +2362,7 @@ static void ipw2100_corruption_detected(
 		       i * sizeof(struct ipw2100_status));
 
 #ifdef IPW2100_DEBUG_C3
-	/* Halt the fimrware so we can get a good image */
+	/* Halt the firmware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
 		       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
 	j = 5;
@@ -2384,13 +2391,14 @@ static void ipw2100_corruption_detected(
 #endif
 
 	priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
-	priv->ieee->stats.rx_errors++;
+	priv->net_dev->stats.rx_errors++;
 	schedule_reset(priv);
 }
 
 static void isr_rx(struct ipw2100_priv *priv, int i,
 			  struct ieee80211_rx_stats *stats)
 {
+	struct net_device *dev = priv->net_dev;
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
 	struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
 
@@ -2399,14 +2407,14 @@ static void isr_rx(struct ipw2100_priv *
 	if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
 		IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
 			       "  Dropping.\n",
-			       priv->net_dev->name,
+			       dev->name,
 			       status->frame_size, skb_tailroom(packet->skb));
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		return;
 	}
 
-	if (unlikely(!netif_running(priv->net_dev))) {
-		priv->ieee->stats.rx_errors++;
+	if (unlikely(!netif_running(dev))) {
+		dev->stats.rx_errors++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
@@ -2436,10 +2444,10 @@ static void isr_rx(struct ipw2100_priv *
 	if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
 #ifdef IPW2100_RX_DEBUG
 		IPW_DEBUG_DROP("%s: Non consumed packet:\n",
-			       priv->net_dev->name);
+			       dev->name);
 		printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
 #endif
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 
 		/* ieee80211_rx failed, so it didn't free the SKB */
 		dev_kfree_skb_any(packet->skb);
@@ -2450,7 +2458,7 @@ static void isr_rx(struct ipw2100_priv *
 	if (unlikely(ipw2100_alloc_skb(priv, packet))) {
 		printk(KERN_WARNING DRV_NAME ": "
 		       "%s: Unable to allocate SKB onto RBD ring - disabling "
-		       "adapter.\n", priv->net_dev->name);
+		       "adapter.\n", dev->name);
 		/* TODO: schedule adapter shutdown */
 		IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
 	}
@@ -2464,6 +2472,7 @@ static void isr_rx(struct ipw2100_priv *
 static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
 		   struct ieee80211_rx_stats *stats)
 {
+	struct net_device *dev = priv->net_dev;
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
 	struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
 
@@ -2481,15 +2490,15 @@ static void isr_rx_monitor(struct ipw210
 				sizeof(struct ipw_rt_hdr))) {
 		IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
 			       "  Dropping.\n",
-			       priv->net_dev->name,
+			       dev->name,
 			       status->frame_size,
 			       skb_tailroom(packet->skb));
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		return;
 	}
 
-	if (unlikely(!netif_running(priv->net_dev))) {
-		priv->ieee->stats.rx_errors++;
+	if (unlikely(!netif_running(dev))) {
+		dev->stats.rx_errors++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
@@ -2498,7 +2507,7 @@ static void isr_rx_monitor(struct ipw210
 	if (unlikely(priv->config & CFG_CRC_CHECK &&
 		     status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
 		IPW_DEBUG_RX("CRC error in packet.  Dropping.\n");
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		return;
 	}
 
@@ -2520,7 +2529,7 @@ static void isr_rx_monitor(struct ipw210
 	skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
 
 	if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 
 		/* ieee80211_rx failed, so it didn't free the SKB */
 		dev_kfree_skb_any(packet->skb);
@@ -2531,7 +2540,7 @@ static void isr_rx_monitor(struct ipw210
 	if (unlikely(ipw2100_alloc_skb(priv, packet))) {
 		IPW_DEBUG_WARNING(
 			"%s: Unable to allocate SKB onto RBD ring - disabling "
-			"adapter.\n", priv->net_dev->name);
+			"adapter.\n", dev->name);
 		/* TODO: schedule adapter shutdown */
 		IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
 	}
@@ -3333,7 +3342,7 @@ static int ipw2100_tx(struct ieee80211_t
 
 	if (!(priv->status & STATUS_ASSOCIATED)) {
 		IPW_DEBUG_INFO("Can not transmit when not connected.\n");
-		priv->ieee->stats.tx_carrier_errors++;
+		priv->net_dev->stats.tx_carrier_errors++;
 		netif_stop_queue(dev);
 		goto fail_unlock;
 	}
@@ -4058,7 +4067,7 @@ static ssize_t show_bssinfo(struct devic
 	u8 bssid[ETH_ALEN];
 	u32 chan = 0;
 	char *out = buf;
-	int length;
+	unsigned int length;
 	int ret;
 
 	if (priv->status & STATUS_RF_KILL_MASK)
@@ -5829,7 +5838,7 @@ static void ipw2100_tx_timeout(struct ne
 {
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 
-	priv->ieee->stats.tx_errors++;
+	dev->stats.tx_errors++;
 
 #ifdef CONFIG_IPW2100_MONITOR
 	if (priv->ieee->iw_mode == IW_MODE_MONITOR)
@@ -5999,6 +6008,17 @@ static void ipw2100_rf_kill(struct work_
 
 static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
 
+static const struct net_device_ops ipw2100_netdev_ops = {
+	.ndo_open		= ipw2100_open,
+	.ndo_stop		= ipw2100_close,
+	.ndo_start_xmit		= ieee80211_xmit,
+	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_init		= ipw2100_net_init,
+	.ndo_tx_timeout		= ipw2100_tx_timeout,
+	.ndo_set_mac_address	= ipw2100_set_address,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* Look into using netdev destructor to shutdown ieee80211? */
 
 static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
@@ -6023,15 +6043,11 @@ static struct net_device *ipw2100_alloc_
 	priv->ieee->perfect_rssi = -20;
 	priv->ieee->worst_rssi = -85;
 
-	dev->open = ipw2100_open;
-	dev->stop = ipw2100_close;
-	dev->init = ipw2100_net_init;
+	dev->netdev_ops = &ipw2100_netdev_ops;
 	dev->ethtool_ops = &ipw2100_ethtool_ops;
-	dev->tx_timeout = ipw2100_tx_timeout;
 	dev->wireless_handlers = &ipw2100_wx_handler_def;
 	priv->wireless_data.ieee80211 = priv->ieee;
 	dev->wireless_data = &priv->wireless_data;
-	dev->set_mac_address = ipw2100_set_address;
 	dev->watchdog_timeo = 3 * HZ;
 	dev->irq = 0;
 
@@ -6191,7 +6207,7 @@ static int ipw2100_pci_init_one(struct p
 	pci_set_master(pci_dev);
 	pci_set_drvdata(pci_dev, priv);
 
-	err = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
 	if (err) {
 		printk(KERN_WARNING DRV_NAME
 		       "Error calling pci_set_dma_mask.\n");
@@ -6414,6 +6430,8 @@ static int ipw2100_suspend(struct pci_de
 	pci_disable_device(pci_dev);
 	pci_set_power_state(pci_dev, PCI_D3hot);
 
+	priv->suspend_at = get_seconds();
+
 	mutex_unlock(&priv->action_mutex);
 
 	return 0;
@@ -6457,6 +6475,8 @@ static int ipw2100_resume(struct pci_dev
 	 * the queue of needed */
 	netif_device_attach(dev);
 
+	priv->suspend_time = get_seconds() - priv->suspend_at;
+
 	/* Bring the device back up */
 	if (!(priv->status & STATUS_RF_KILL_SW))
 		ipw2100_up(priv, 0);
@@ -7122,7 +7142,7 @@ static int ipw2100_wx_get_rate(struct ne
 {
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 	int val;
-	int len = sizeof(val);
+	unsigned int len = sizeof(val);
 	int err = 0;
 
 	if (!(priv->status & STATUS_ENABLED) ||
@@ -8297,7 +8317,7 @@ static void ipw2100_wx_event_work(struct
 	struct ipw2100_priv *priv =
 		container_of(work, struct ipw2100_priv, wx_event_work.work);
 	union iwreq_data wrqu;
-	int len = ETH_ALEN;
+	unsigned int len = ETH_ALEN;
 
 	if (priv->status & STATUS_STOPPING)
 		return;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2100.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2100.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2100.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2100.h	2009-06-09 23:05:27.000000000 -0400
@@ -39,8 +39,6 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>	// new driver API
 
-#include <net/ieee80211.h>
-
 #ifdef CONFIG_IPW2100_MONITOR
 #include <net/ieee80211_radiotap.h>
 #endif
@@ -48,6 +46,8 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 
+#include "ieee80211.h"
+
 struct ipw2100_priv;
 struct ipw2100_tx_packet;
 struct ipw2100_rx_packet;
@@ -591,6 +591,10 @@ struct ipw2100_priv {
 
 	int user_requested_scan;
 
+	/* Track time in suspend */
+	unsigned long suspend_at;
+	unsigned long suspend_time;
+
 	u32 interrupts;
 	int tx_interrupts;
 	int rx_interrupts;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 18:04:26.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2200.c	2013-05-03 16:48:17.000000000 -0400
@@ -301,88 +301,102 @@ static inline void ipw_write_reg32(struc
 }
 
 /* 8-bit direct write (low 4K) */
-#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
+		u8 val)
+{
+	writeb(val, ipw->hw_base + ofs);
+}
 
 /* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
 #define ipw_write8(ipw, ofs, val) do { \
- IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write8(ipw, ofs, val); \
- } while (0)
+	IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
+			__LINE__, (u32)(ofs), (u32)(val)); \
+	_ipw_write8(ipw, ofs, val); \
+} while (0)
 
 /* 16-bit direct write (low 4K) */
-#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
+		u16 val)
+{
+	writew(val, ipw->hw_base + ofs);
+}
 
 /* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write16(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write16(ipw, ofs, val)
+#define ipw_write16(ipw, ofs, val) do { \
+	IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
+			__LINE__, (u32)(ofs), (u32)(val)); \
+	_ipw_write16(ipw, ofs, val); \
+} while (0)
 
 /* 32-bit direct write (low 4K) */
-#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
+		u32 val)
+{
+	writel(val, ipw->hw_base + ofs);
+}
 
 /* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write32(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write32(ipw, ofs, val)
+#define ipw_write32(ipw, ofs, val) do { \
+	IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
+			__LINE__, (u32)(ofs), (u32)(val)); \
+	_ipw_write32(ipw, ofs, val); \
+} while (0)
 
 /* 8-bit direct read (low 4K) */
-#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
-
-/* 8-bit direct read (low 4K), with debug wrapper */
-static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
 {
-	IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
-	return _ipw_read8(ipw, ofs);
+	return readb(ipw->hw_base + ofs);
 }
 
 /* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read8(ipw, ofs) ({ \
+	IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
+			(u32)(ofs)); \
+	_ipw_read8(ipw, ofs); \
+})
 
 /* 16-bit direct read (low 4K) */
-#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
-
-/* 16-bit direct read (low 4K), with debug wrapper */
-static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
 {
-	IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
-	return _ipw_read16(ipw, ofs);
+	return readw(ipw->hw_base + ofs);
 }
 
 /* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read16(ipw, ofs) ({ \
+	IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
+			(u32)(ofs)); \
+	_ipw_read16(ipw, ofs); \
+})
 
 /* 32-bit direct read (low 4K) */
-#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
-
-/* 32-bit direct read (low 4K), with debug wrapper */
-static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
 {
-	IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
-	return _ipw_read32(ipw, ofs);
+	return readl(ipw->hw_base + ofs);
 }
 
 /* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read32(ipw, ofs) ({ \
+	IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
+			(u32)(ofs)); \
+	_ipw_read32(ipw, ofs); \
+})
 
-/* multi-byte read (above 4K), with debug wrapper */
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-static inline void __ipw_read_indirect(const char *f, int l,
-				       struct ipw_priv *a, u32 b, u8 * c, int d)
-{
-	IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
-		     d);
-	_ipw_read_indirect(a, b, c, d);
-}
-
 /* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
-#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
+#define ipw_read_indirect(a, b, c, d) ({ \
+	IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
+			__LINE__, (u32)(b), (u32)(d)); \
+	_ipw_read_indirect(a, b, c, d); \
+})
 
 /* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
 				int num);
-#define ipw_write_indirect(a, b, c, d) \
-	IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
-	_ipw_write_indirect(a, b, c, d)
+#define ipw_write_indirect(a, b, c, d) do { \
+	IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
+			__LINE__, (u32)(b), (u32)(d)); \
+	_ipw_write_indirect(a, b, c, d); \
+} while (0)
 
 /* 32-bit indirect write (above 4K) */
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
@@ -7717,22 +7731,23 @@ static void ipw_handle_data_packet(struc
 				   struct ipw_rx_mem_buffer *rxb,
 				   struct ieee80211_rx_stats *stats)
 {
+	struct net_device *dev = priv->net_dev;
 	struct ieee80211_hdr_4addr *hdr;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 
 	/* We received data from the HW, so stop the watchdog */
-	priv->net_dev->trans_start = jiffies;
+	dev->trans_start = jiffies;
 
 	/* We only process data packets if the
 	 * interface is open */
 	if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
 		     skb_tailroom(rxb->skb))) {
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
 		return;
 	} else if (unlikely(!netif_running(priv->net_dev))) {
-		priv->ieee->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
@@ -7754,7 +7769,7 @@ static void ipw_handle_data_packet(struc
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
 	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
 		rxb->skb = NULL;
 		__ipw_led_activity_on(priv);
@@ -7766,6 +7781,7 @@ static void ipw_handle_data_packet_monit
 					   struct ipw_rx_mem_buffer *rxb,
 					   struct ieee80211_rx_stats *stats)
 {
+	struct net_device *dev = priv->net_dev;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 	struct ipw_rx_frame *frame = &pkt->u.frame;
 
@@ -7783,18 +7799,18 @@ static void ipw_handle_data_packet_monit
 	short len = le16_to_cpu(pkt->u.frame.length);
 
 	/* We received data from the HW, so stop the watchdog */
-	priv->net_dev->trans_start = jiffies;
+	dev->trans_start = jiffies;
 
 	/* We only process data packets if the
 	 * interface is open */
 	if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
 		     skb_tailroom(rxb->skb))) {
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
 		return;
 	} else if (unlikely(!netif_running(priv->net_dev))) {
-		priv->ieee->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
@@ -7804,7 +7820,7 @@ static void ipw_handle_data_packet_monit
 	 * that now */
 	if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
 		/* FIXME: Should alloc bigger skb instead */
-		priv->ieee->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		priv->wstats.discard.misc++;
 		IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
 		return;
@@ -7910,7 +7926,7 @@ static void ipw_handle_data_packet_monit
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
 	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
-		priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
 		rxb->skb = NULL;
 		/* no LED during capture */
@@ -7942,6 +7958,7 @@ static void ipw_handle_promiscuous_rx(st
 				      struct ipw_rx_mem_buffer *rxb,
 				      struct ieee80211_rx_stats *stats)
 {
+	struct net_device *dev = priv->prom_net_dev;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 	struct ipw_rx_frame *frame = &pkt->u.frame;
 	struct ipw_rt_hdr *ipw_rt;
@@ -7964,17 +7981,17 @@ static void ipw_handle_promiscuous_rx(st
 		return;
 
 	/* We received data from the HW, so stop the watchdog */
-	priv->prom_net_dev->trans_start = jiffies;
+	dev->trans_start = jiffies;
 
 	if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
-		priv->prom_priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
 		return;
 	}
 
 	/* We only process data packets if the interface is open */
-	if (unlikely(!netif_running(priv->prom_net_dev))) {
-		priv->prom_priv->ieee->stats.rx_dropped++;
+	if (unlikely(!netif_running(dev))) {
+		dev->stats.rx_dropped++;
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
 	}
@@ -7983,7 +8000,7 @@ static void ipw_handle_promiscuous_rx(st
 	 * that now */
 	if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
 		/* FIXME: Should alloc bigger skb instead */
-		priv->prom_priv->ieee->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
 		return;
 	}
@@ -8115,7 +8132,7 @@ static void ipw_handle_promiscuous_rx(st
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
 
 	if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
-		priv->prom_priv->ieee->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		dev_kfree_skb_any(skb);
 	}
 }
@@ -8272,7 +8289,7 @@ static void ipw_handle_mgmt_packet(struc
 		skb_reset_mac_header(skb);
 
 		skb->pkt_type = PACKET_OTHERHOST;
-		skb->protocol = __constant_htons(ETH_P_80211_STATS);
+		skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
 		memset(skb->cb, 0, sizeof(rxb->skb->cb));
 		netif_rx(skb);
 		rxb->skb = NULL;
@@ -8399,7 +8416,7 @@ static void ipw_rx(struct ipw_priv *priv
 					IPW_DEBUG_DROP
 					    ("Received packet is too small. "
 					     "Dropping.\n");
-					priv->ieee->stats.rx_errors++;
+					priv->net_dev->stats.rx_errors++;
 					priv->wstats.discard.misc++;
 					break;
 				}
@@ -8827,7 +8844,7 @@ static int ipw_wx_set_mode(struct net_de
 #endif				/* CONFIG_IPW2200_MONITOR */
 
 	/* Free the existing firmware and reset the fw_loaded
-	 * flag so ipw_load() will bring in the new firmawre */
+	 * flag so ipw_load() will bring in the new firmware */
 	free_firmware();
 
 	priv->ieee->iw_mode = wrqu->mode;
@@ -10470,15 +10487,6 @@ static int ipw_net_hard_start_xmit(struc
 	return ret;
 }
 
-static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
-{
-	struct ipw_priv *priv = ieee80211_priv(dev);
-
-	priv->ieee->stats.tx_packets = priv->tx_packets;
-	priv->ieee->stats.rx_packets = priv->rx_packets;
-	return &priv->ieee->stats;
-}
-
 static void ipw_net_set_multicast_list(struct net_device *dev)
 {
 
@@ -11224,6 +11232,12 @@ static int ipw_up(struct ipw_priv *priv)
 {
 	int rc, i, j;
 
+	/* Age scan list entries found before suspend */
+	if (priv->suspend_time) {
+		ieee80211_networks_age(priv->ieee, priv->suspend_time);
+		priv->suspend_time = 0;
+	}
+
 	if (priv->status & STATUS_EXIT_PENDING)
 		return -EIO;
 
@@ -11515,11 +11529,14 @@ static int ipw_prom_hard_start_xmit(stru
 	return -EOPNOTSUPP;
 }
 
-static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
-{
-	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
-	return &prom_priv->ieee->stats;
-}
+static const struct net_device_ops ipw_prom_netdev_ops = {
+	.ndo_open 		= ipw_prom_open,
+	.ndo_stop		= ipw_prom_stop,
+	.ndo_start_xmit		= ipw_prom_hard_start_xmit,
+	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 static int ipw_prom_alloc(struct ipw_priv *priv)
 {
@@ -11540,10 +11557,7 @@ static int ipw_prom_alloc(struct ipw_pri
 	memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
 	priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-	priv->prom_net_dev->open = ipw_prom_open;
-	priv->prom_net_dev->stop = ipw_prom_stop;
-	priv->prom_net_dev->get_stats = ipw_prom_get_stats;
-	priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
+	priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
 
 	priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
 	SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
@@ -11571,6 +11585,16 @@ static void ipw_prom_free(struct ipw_pri
 
 #endif
 
+static const struct net_device_ops ipw_netdev_ops = {
+	.ndo_init		= ipw_net_init,
+	.ndo_open		= ipw_net_open,
+	.ndo_stop		= ipw_net_stop,
+	.ndo_set_multicast_list	= ipw_net_set_multicast_list,
+	.ndo_set_mac_address	= ipw_net_set_mac_address,
+	.ndo_start_xmit		= ieee80211_xmit,
+	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 static int __devinit ipw_pci_probe(struct pci_dev *pdev,
 				   const struct pci_device_id *ent)
@@ -11607,9 +11631,9 @@ static int __devinit ipw_pci_probe(struc
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (!err)
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
 		printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
 		goto out_pci_disable_device;
@@ -11672,12 +11696,7 @@ static int __devinit ipw_pci_probe(struc
 	priv->ieee->perfect_rssi = -20;
 	priv->ieee->worst_rssi = -85;
 
-	net_dev->open = ipw_net_open;
-	net_dev->stop = ipw_net_stop;
-	net_dev->init = ipw_net_init;
-	net_dev->get_stats = ipw_net_get_stats;
-	net_dev->set_multicast_list = ipw_net_set_multicast_list;
-	net_dev->set_mac_address = ipw_net_set_mac_address;
+	net_dev->netdev_ops = &ipw_netdev_ops;
 	priv->wireless_data.spy_data = &priv->ieee->spy_data;
 	net_dev->wireless_data = &priv->wireless_data;
 	net_dev->wireless_handlers = &ipw_wx_handler_def;
@@ -11824,6 +11843,8 @@ static int ipw_pci_suspend(struct pci_de
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
+	priv->suspend_at = get_seconds();
+
 	return 0;
 }
 
@@ -11859,6 +11880,8 @@ static int ipw_pci_resume(struct pci_dev
 	 * the queue of needed */
 	netif_device_attach(dev);
 
+	priv->suspend_time = get_seconds() - priv->suspend_at;
+
 	/* Bring the device back up */
 	queue_work(priv->workqueue, &priv->up);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2200.h linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2200.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/ipw2200.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/ipw2200.h	2009-06-09 23:05:27.000000000 -0400
@@ -49,13 +49,14 @@
 #include <asm/io.h>
 
 #include <net/lib80211.h>
-#include <net/ieee80211.h>
 #include <net/ieee80211_radiotap.h>
 
 #define DRV_NAME	"ipw2200"
 
 #include <linux/workqueue.h>
 
+#include "ieee80211.h"
+
 /* Authentication  and Association States */
 enum connection_manager_assoc_states {
 	CMAS_INIT = 0,
@@ -1346,6 +1347,10 @@ struct ipw_priv {
 
 	s8 tx_power;
 
+	/* Track time in suspend */
+	unsigned long suspend_at;
+	unsigned long suspend_time;
+
 #ifdef CONFIG_PM
 	u32 pm_state[16];
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -150,6 +150,7 @@ config IPW2200_DEBUG
 
 config LIBIPW
 	tristate
+	depends on PCI && WLAN_80211
 	select WIRELESS_EXT
 	select CRYPTO
 	select CRYPTO_ARC4
@@ -185,7 +186,7 @@ config LIBIPW_DEBUG
 	  % echo 0x00000FFO > /proc/net/ieee80211/debug_level
 
 	  For a list of values you can assign to debug_level, you
-	  can look at the bit mask values in <net/ieee80211.h>
+	  can look at the bit mask values in ieee80211.h
 
 	  If you are not trying to debug or develop the libipw
 	  component, you most likely want to say N here.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_geo.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 
-#include <net/ieee80211.h>
+#include "ieee80211.h"
 
 int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_module.c	2009-06-09 23:05:27.000000000 -0400
@@ -50,7 +50,7 @@
 #include <net/net_namespace.h>
 #include <net/arp.h>
 
-#include <net/ieee80211.h>
+#include "ieee80211.h"
 
 #define DRV_DESCRIPTION "802.11 data/management/control stack"
 #define DRV_NAME        "ieee80211"
@@ -105,6 +105,21 @@ static inline void ieee80211_networks_fr
 	ieee->networks = NULL;
 }
 
+void ieee80211_networks_age(struct ieee80211_device *ieee,
+                            unsigned long age_secs)
+{
+	struct ieee80211_network *network = NULL;
+	unsigned long flags;
+	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	list_for_each_entry(network, &ieee->network_list, list) {
+		network->last_scanned -= age_jiffies;
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+EXPORT_SYMBOL(ieee80211_networks_age);
+
 static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
 {
 	int i;
@@ -116,20 +131,14 @@ static void ieee80211_networks_initializ
 			      &ieee->network_free_list);
 }
 
-static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
 }
-
-static struct net_device_stats *ieee80211_generic_get_stats(
-	struct net_device *dev)
-{
-	struct ieee80211_device *ieee = netdev_priv(dev);
-	return &ieee->stats;
-}
+EXPORT_SYMBOL(ieee80211_change_mtu);
 
 struct net_device *alloc_ieee80211(int sizeof_priv)
 {
@@ -145,12 +154,10 @@ struct net_device *alloc_ieee80211(int s
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
 	dev->hard_start_xmit = ieee80211_xmit;
 	dev->change_mtu = ieee80211_change_mtu;
-
-	/* Drivers are free to override this if the generic implementation
-	 * does not meet their needs. */
-	dev->get_stats = ieee80211_generic_get_stats;
+#endif
 
 	ieee->dev = dev;
 
@@ -206,7 +213,7 @@ void free_ieee80211(struct net_device *d
 	free_netdev(dev);
 }
 
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 
 static int debug = 0;
 u32 ieee80211_debug_level = 0;
@@ -237,11 +244,11 @@ static int store_debug_level(struct file
 
 	return strnlen(buf, len);
 }
-#endif				/* CONFIG_IEEE80211_DEBUG */
+#endif				/* CONFIG_LIBIPW_DEBUG */
 
 static int __init ieee80211_init(void)
 {
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 	struct proc_dir_entry *e;
 
 	ieee80211_debug_level = debug;
@@ -261,7 +268,7 @@ static int __init ieee80211_init(void)
 	e->read_proc = show_debug_level;
 	e->write_proc = store_debug_level;
 	e->data = NULL;
-#endif				/* CONFIG_IEEE80211_DEBUG */
+#endif				/* CONFIG_LIBIPW_DEBUG */
 
 	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
 	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
@@ -271,20 +278,20 @@ static int __init ieee80211_init(void)
 
 static void __exit ieee80211_exit(void)
 {
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 	if (ieee80211_proc) {
 		remove_proc_entry("debug_level", ieee80211_proc);
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
 		ieee80211_proc = NULL;
 	}
-#endif				/* CONFIG_IEEE80211_DEBUG */
+#endif				/* CONFIG_LIBIPW_DEBUG */
 }
 
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
-#endif				/* CONFIG_IEEE80211_DEBUG */
+#endif				/* CONFIG_LIBIPW_DEBUG */
 
 module_exit(ieee80211_exit);
 module_init(ieee80211_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -33,7 +33,8 @@
 #include <linux/ctype.h>
 
 #include <net/lib80211.h>
-#include <net/ieee80211.h>
+
+#include "ieee80211.h"
 
 static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 					struct sk_buff *skb,
@@ -334,7 +335,6 @@ int ieee80211_rx(struct ieee80211_device
 	struct ieee80211_hdr_4addr *hdr;
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
-	struct net_device_stats *stats;
 	unsigned int frag;
 	u8 *payload;
 	u16 ethertype;
@@ -353,8 +353,6 @@ int ieee80211_rx(struct ieee80211_device
 	int can_be_decrypted = 0;
 
 	hdr = (struct ieee80211_hdr_4addr *)skb->data;
-	stats = &ieee->stats;
-
 	if (skb->len < 10) {
 		printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
 		goto rx_dropped;
@@ -411,8 +409,8 @@ int ieee80211_rx(struct ieee80211_device
 #endif
 
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
-		stats->rx_packets++;
-		stats->rx_bytes += skb->len;
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += skb->len;
 		ieee80211_monitor_rx(ieee, skb, rx_stats);
 		return 1;
 	}
@@ -768,8 +766,8 @@ int ieee80211_rx(struct ieee80211_device
 	}
 #endif
 
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
 
 #ifdef NOT_YET
 	if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
@@ -811,7 +809,7 @@ int ieee80211_rx(struct ieee80211_device
 			 * in our stats. */
 			IEEE80211_DEBUG_DROP
 			    ("RX: netif_rx dropped the packet\n");
-			stats->rx_dropped++;
+			dev->stats.rx_dropped++;
 		}
 	}
 
@@ -823,7 +821,7 @@ int ieee80211_rx(struct ieee80211_device
 	return 1;
 
       rx_dropped:
-	stats->rx_dropped++;
+	dev->stats.rx_dropped++;
 
 	/* Returning 0 indicates to caller that we have not handled the SKB--
 	 * so it is still allocated and can be used again by underlying
@@ -918,7 +916,7 @@ void ieee80211_rx_any(struct ieee80211_d
 
 drop_free:
 	dev_kfree_skb_irq(skb);
-	ieee->stats.rx_dropped++;
+	ieee->dev->stats.rx_dropped++;
 	return;
 }
 
@@ -1079,37 +1077,37 @@ static int ieee80211_parse_qos_info_para
 	return rc;
 }
 
-#ifdef CONFIG_IEEE80211_DEBUG
-#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+#ifdef CONFIG_LIBIPW_DEBUG
+#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
 
 static const char *get_info_element_string(u16 id)
 {
 	switch (id) {
 		MFIE_STRING(SSID);
-		MFIE_STRING(RATES);
-		MFIE_STRING(FH_SET);
-		MFIE_STRING(DS_SET);
-		MFIE_STRING(CF_SET);
+		MFIE_STRING(SUPP_RATES);
+		MFIE_STRING(FH_PARAMS);
+		MFIE_STRING(DS_PARAMS);
+		MFIE_STRING(CF_PARAMS);
 		MFIE_STRING(TIM);
-		MFIE_STRING(IBSS_SET);
+		MFIE_STRING(IBSS_PARAMS);
 		MFIE_STRING(COUNTRY);
-		MFIE_STRING(HOP_PARAMS);
-		MFIE_STRING(HOP_TABLE);
+		MFIE_STRING(HP_PARAMS);
+		MFIE_STRING(HP_TABLE);
 		MFIE_STRING(REQUEST);
 		MFIE_STRING(CHALLENGE);
-		MFIE_STRING(POWER_CONSTRAINT);
-		MFIE_STRING(POWER_CAPABILITY);
+		MFIE_STRING(PWR_CONSTRAINT);
+		MFIE_STRING(PWR_CAPABILITY);
 		MFIE_STRING(TPC_REQUEST);
 		MFIE_STRING(TPC_REPORT);
-		MFIE_STRING(SUPP_CHANNELS);
-		MFIE_STRING(CSA);
+		MFIE_STRING(SUPPORTED_CHANNELS);
+		MFIE_STRING(CHANNEL_SWITCH);
 		MFIE_STRING(MEASURE_REQUEST);
 		MFIE_STRING(MEASURE_REPORT);
 		MFIE_STRING(QUIET);
 		MFIE_STRING(IBSS_DFS);
 		MFIE_STRING(ERP_INFO);
 		MFIE_STRING(RSN);
-		MFIE_STRING(RATES_EX);
+		MFIE_STRING(EXT_SUPP_RATES);
 		MFIE_STRING(GENERIC);
 		MFIE_STRING(QOS_PARAMETER);
 	default:
@@ -1124,7 +1122,7 @@ static int ieee80211_parse_info_param(st
 {
 	DECLARE_SSID_BUF(ssid);
 	u8 i;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 	char rates_str[64];
 	char *p;
 #endif
@@ -1144,7 +1142,7 @@ static int ieee80211_parse_info_param(st
 		}
 
 		switch (info_element->id) {
-		case MFIE_TYPE_SSID:
+		case WLAN_EID_SSID:
 			network->ssid_len = min(info_element->len,
 						(u8) IW_ESSID_MAX_SIZE);
 			memcpy(network->ssid, info_element->data,
@@ -1153,21 +1151,21 @@ static int ieee80211_parse_info_param(st
 				memset(network->ssid + network->ssid_len, 0,
 				       IW_ESSID_MAX_SIZE - network->ssid_len);
 
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
+			IEEE80211_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
 					     print_ssid(ssid, network->ssid,
 							network->ssid_len),
 					     network->ssid_len);
 			break;
 
-		case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
+		case WLAN_EID_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
 			p = rates_str;
 #endif
 			network->rates_len = min(info_element->len,
 						 MAX_RATES_LENGTH);
 			for (i = 0; i < network->rates_len; i++) {
 				network->rates[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 				p += snprintf(p, sizeof(rates_str) -
 					      (p - rates_str), "%02X ",
 					      network->rates[i]);
@@ -1182,19 +1180,19 @@ static int ieee80211_parse_info_param(st
 				}
 			}
 
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
+			IEEE80211_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
 					     rates_str, network->rates_len);
 			break;
 
-		case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
+		case WLAN_EID_EXT_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
 			p = rates_str;
 #endif
 			network->rates_ex_len = min(info_element->len,
 						    MAX_RATES_EX_LENGTH);
 			for (i = 0; i < network->rates_ex_len; i++) {
 				network->rates_ex[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 				p += snprintf(p, sizeof(rates_str) -
 					      (p - rates_str), "%02X ",
 					      network->rates[i]);
@@ -1209,49 +1207,49 @@ static int ieee80211_parse_info_param(st
 				}
 			}
 
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+			IEEE80211_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
 					     rates_str, network->rates_ex_len);
 			break;
 
-		case MFIE_TYPE_DS_SET:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+		case WLAN_EID_DS_PARAMS:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
 					     info_element->data[0]);
 			network->channel = info_element->data[0];
 			break;
 
-		case MFIE_TYPE_FH_SET:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+		case WLAN_EID_FH_PARAMS:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
 			break;
 
-		case MFIE_TYPE_CF_SET:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+		case WLAN_EID_CF_PARAMS:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
 			break;
 
-		case MFIE_TYPE_TIM:
+		case WLAN_EID_TIM:
 			network->tim.tim_count = info_element->data[0];
 			network->tim.tim_period = info_element->data[1];
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+			IEEE80211_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
 			break;
 
-		case MFIE_TYPE_ERP_INFO:
+		case WLAN_EID_ERP_INFO:
 			network->erp_value = info_element->data[0];
 			network->flags |= NETWORK_HAS_ERP_VALUE;
 			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
 					     network->erp_value);
 			break;
 
-		case MFIE_TYPE_IBSS_SET:
+		case WLAN_EID_IBSS_PARAMS:
 			network->atim_window = info_element->data[0];
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+			IEEE80211_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
 					     network->atim_window);
 			break;
 
-		case MFIE_TYPE_CHALLENGE:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+		case WLAN_EID_CHALLENGE:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
 			break;
 
-		case MFIE_TYPE_GENERIC:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+		case WLAN_EID_GENERIC:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
 					     info_element->len);
 			if (!ieee80211_parse_qos_info_param_IE(info_element,
 							       network))
@@ -1269,8 +1267,8 @@ static int ieee80211_parse_info_param(st
 			}
 			break;
 
-		case MFIE_TYPE_RSN:
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
+		case WLAN_EID_RSN:
+			IEEE80211_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
 					     info_element->len);
 			network->rsn_ie_len = min(info_element->len + 2,
 						  MAX_WPA_IE_LEN);
@@ -1278,22 +1276,22 @@ static int ieee80211_parse_info_param(st
 			       network->rsn_ie_len);
 			break;
 
-		case MFIE_TYPE_QOS_PARAMETER:
+		case WLAN_EID_QOS_PARAMETER:
 			printk(KERN_ERR
 			       "QoS Error need to parse QOS_PARAMETER IE\n");
 			break;
 			/* 802.11h */
-		case MFIE_TYPE_POWER_CONSTRAINT:
+		case WLAN_EID_PWR_CONSTRAINT:
 			network->power_constraint = info_element->data[0];
 			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
 			break;
 
-		case MFIE_TYPE_CSA:
+		case WLAN_EID_CHANNEL_SWITCH:
 			network->power_constraint = info_element->data[0];
 			network->flags |= NETWORK_HAS_CSA;
 			break;
 
-		case MFIE_TYPE_QUIET:
+		case WLAN_EID_QUIET:
 			network->quiet.count = info_element->data[0];
 			network->quiet.period = info_element->data[1];
 			network->quiet.duration = info_element->data[2];
@@ -1301,7 +1299,7 @@ static int ieee80211_parse_info_param(st
 			network->flags |= NETWORK_HAS_QUIET;
 			break;
 
-		case MFIE_TYPE_IBSS_DFS:
+		case WLAN_EID_IBSS_DFS:
 			if (network->ibss_dfs)
 				break;
 			network->ibss_dfs = kmemdup(info_element->data,
@@ -1312,7 +1310,7 @@ static int ieee80211_parse_info_param(st
 			network->flags |= NETWORK_HAS_IBSS_DFS;
 			break;
 
-		case MFIE_TYPE_TPC_REPORT:
+		case WLAN_EID_TPC_REPORT:
 			network->tpc_report.transmit_power =
 			    info_element->data[0];
 			network->tpc_report.link_margin = info_element->data[1];
@@ -1561,7 +1559,7 @@ static void ieee80211_process_probe_resp
 	};
 	struct ieee80211_network *target;
 	struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 	struct ieee80211_info_element *info_element = beacon->info_element;
 #endif
 	unsigned long flags;
@@ -1615,7 +1613,7 @@ static void ieee80211_process_probe_resp
 			break;
 
 		if ((oldest == NULL) ||
-		    (target->last_scanned < oldest->last_scanned))
+		    time_before(target->last_scanned, oldest->last_scanned))
 			oldest = target;
 	}
 
@@ -1639,7 +1637,7 @@ static void ieee80211_process_probe_resp
 			list_del(ieee->network_free_list.next);
 		}
 
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     print_ssid(ssid, network.ssid,
 						 network.ssid_len),
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_tx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -41,7 +41,7 @@
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 
-#include <net/ieee80211.h>
+#include "ieee80211.h"
 
 /*
 
@@ -260,7 +260,6 @@ int ieee80211_xmit(struct sk_buff *skb,
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
 	    rts_required;
 	unsigned long flags;
-	struct net_device_stats *stats = &ieee->stats;
 	int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
 	__be16 ether_type;
 	int bytes, fc, hdr_len;
@@ -306,7 +305,7 @@ int ieee80211_xmit(struct sk_buff *skb,
 
 	if (!encrypt && ieee->ieee802_1x &&
 	    ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
-		stats->tx_dropped++;
+		dev->stats.tx_dropped++;
 		goto success;
 	}
 
@@ -526,8 +525,8 @@ int ieee80211_xmit(struct sk_buff *skb,
 	if (txb) {
 		int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
 		if (ret == 0) {
-			stats->tx_packets++;
-			stats->tx_bytes += txb->payload_size;
+			dev->stats.tx_packets++;
+			dev->stats.tx_bytes += txb->payload_size;
 			return 0;
 		}
 
@@ -539,8 +538,9 @@ int ieee80211_xmit(struct sk_buff *skb,
       failed:
 	spin_unlock_irqrestore(&ieee->lock, flags);
 	netif_stop_queue(dev);
-	stats->tx_errors++;
+	dev->stats.tx_errors++;
 	return 1;
 }
+EXPORT_SYMBOL(ieee80211_xmit);
 
 EXPORT_SYMBOL(ieee80211_txb_free);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ipw2x00/libipw_wx.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,13 +35,24 @@
 #include <linux/jiffies.h>
 
 #include <net/lib80211.h>
-#include <net/ieee80211.h>
 #include <linux/wireless.h>
 
+#include "ieee80211.h"
+
 static const char *ieee80211_modes[] = {
 	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
 };
 
+static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
+{
+	unsigned long end = jiffies;
+
+	if (end >= start)
+		return jiffies_to_msecs(end - start);
+
+	return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
+}
+
 #define MAX_CUSTOM_LEN 64
 static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 				      char *start, char *stop,
@@ -215,8 +226,8 @@ static char *ieee80211_translate_scan(st
 	iwe.cmd = IWEVCUSTOM;
 	p = custom;
 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-		      " Last beacon: %dms ago",
-		      jiffies_to_msecs(jiffies - network->last_scanned));
+		      " Last beacon: %ums ago",
+		      elapsed_jiffies_msecs(network->last_scanned));
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
 		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
@@ -276,15 +287,15 @@ int ieee80211_wx_get_scan(struct ieee802
 		    time_after(network->last_scanned + ieee->scan_age, jiffies))
 			ev = ieee80211_translate_scan(ieee, ev, stop, network,
 						      info);
-		else
+		else {
 			IEEE80211_DEBUG_SCAN("Not showing network '%s ("
-					     "%pM)' due to age (%dms).\n",
+					     "%pM)' due to age (%ums).\n",
 					     print_ssid(ssid, network->ssid,
 							 network->ssid_len),
 					     network->bssid,
-					     jiffies_to_msecs(jiffies -
-							      network->
-							      last_scanned));
+					     elapsed_jiffies_msecs(
+					               network->last_scanned));
+		}
 	}
 
 	spin_unlock_irqrestore(&ieee->lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-05-03 16:48:35.000000000 -0400
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-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-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL1000_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL1000_UCODE_API_MIN 1
+
+#define IWL1000_FW_PRE "/*(DEBLOBBED)*/"
+#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE /*(DEBLOBBED)*/
+#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+
+struct iwl_cfg iwl1000_bgn_cfg = {
+	.name = "1000 Series BGN",
+	.fw_name_pre = IWL1000_FW_PRE,
+	.ucode_api_max = IWL1000_UCODE_API_MAX,
+	.ucode_api_min = IWL1000_UCODE_API_MIN,
+	.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,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_A,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = true,
+};
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 18:04:31.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 16:48:21.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -46,40 +46,25 @@
 
 #include <asm/div64.h>
 
-#include "iwl-3945-core.h"
+#define DRV_NAME	"iwl3945"
+
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
 #include "iwl-3945.h"
 #include "iwl-helpers.h"
-
-#ifdef CONFIG_IWL3945_DEBUG
-u32 iwl3945_debug_level;
-#endif
-
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
-				  struct iwl3945_tx_queue *txq);
-
-/******************************************************************************
- *
- * module boiler plate
- *
- ******************************************************************************/
-
-/* module parameters */
-static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
-static u32 iwl3945_param_debug;    /* def: 0 = minimal debug log messages */
-static int iwl3945_param_disable;  /* def: 0 = enable radio */
-static int iwl3945_param_antenna;  /* def: 0 = both antennas (use diversity) */
-int iwl3945_param_hwcrypto;        /* def: 0 = use software encryption */
-int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
+#include "iwl-core.h"
+#include "iwl-dev.h"
 
 /*
  * module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
  */
 
 #define DRV_DESCRIPTION	\
 "Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
 
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 #define VD "d"
 #else
 #define VD
@@ -91,10 +76,10 @@ int iwl3945_param_queues_num = IWL39_MAX
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "1.2.26k" VD VS
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2008 Intel Corporation"
+#define IWL39_VERSION "1.2.26k" VD VS
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
-#define DRV_VERSION     IWLWIFI_VERSION
+#define DRV_VERSION     IWL39_VERSION
 
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -102,235 +87,13 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
-static const struct ieee80211_supported_band *iwl3945_get_band(
-		struct iwl3945_priv *priv, enum ieee80211_band band)
-{
-	return priv->hw->wiphy->bands[band];
-}
-
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill.  Driver and device exchange status of each
- * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues:  One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA.  An additional 2 HCCA queues are unused.
- ***************************************************/
-
-int iwl3945_queue_space(const struct iwl3945_queue *q)
-{
-	int s = q->read_ptr - q->write_ptr;
-
-	if (q->read_ptr > q->write_ptr)
-		s -= q->n_bd;
-
-	if (s <= 0)
-		s += q->n_window;
-	/* keep some reserve to not confuse empty and full situations */
-	s -= 2;
-	if (s < 0)
-		s = 0;
-	return s;
-}
-
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
-{
-	return q->write_ptr > q->read_ptr ?
-		(i >= q->read_ptr && i < q->write_ptr) :
-		!(i < q->read_ptr && i >= q->write_ptr);
-}
-
-
-static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
-{
-	/* This is for scan command, the big buffer at end of command array */
-	if (is_huge)
-		return q->n_window;	/* must be power of 2 */
-
-	/* Otherwise, use normal size buffers */
-	return index & (q->n_window - 1);
-}
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
-			  int count, int slots_num, u32 id)
-{
-	q->n_bd = count;
-	q->n_window = slots_num;
-	q->id = id;
-
-	/* count must be power-of-two size, otherwise iwl_queue_inc_wrap
-	 * and iwl_queue_dec_wrap are broken. */
-	BUG_ON(!is_power_of_2(count));
-
-	/* slots_num must be power-of-two size, otherwise
-	 * get_cmd_index is broken. */
-	BUG_ON(!is_power_of_2(slots_num));
-
-	q->low_mark = q->n_window / 4;
-	if (q->low_mark < 4)
-		q->low_mark = 4;
-
-	q->high_mark = q->n_window / 8;
-	if (q->high_mark < 2)
-		q->high_mark = 2;
-
-	q->write_ptr = q->read_ptr = 0;
-
-	return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
-			      struct iwl3945_tx_queue *txq, u32 id)
-{
-	struct pci_dev *dev = priv->pci_dev;
-
-	/* Driver private data, only for Tx (not command) queues,
-	 * not shared with device. */
-	if (id != IWL_CMD_QUEUE_NUM) {
-		txq->txb = kmalloc(sizeof(txq->txb[0]) *
-				   TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
-		if (!txq->txb) {
-			IWL_ERROR("kmalloc for auxiliary BD "
-				  "structures failed\n");
-			goto error;
-		}
-	} else
-		txq->txb = NULL;
-
-	/* Circular buffer of transmit frame descriptors (TFDs),
-	 * shared with device */
-	txq->bd = pci_alloc_consistent(dev,
-			sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
-			&txq->q.dma_addr);
-
-	if (!txq->bd) {
-		IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
-			  sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
-		goto error;
-	}
-	txq->q.id = id;
-
-	return 0;
-
- error:
-	kfree(txq->txb);
-	txq->txb = NULL;
-
-	return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
-		      struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
-{
-	struct pci_dev *dev = priv->pci_dev;
-	int len;
-	int rc = 0;
-
-	/*
-	 * Alloc buffer array for commands (Tx or other types of commands).
-	 * For the command queue (#4), allocate command space + one big
-	 * command for scan, since scan command is very huge; the system will
-	 * not have two scans at the same time, so only one is needed.
-	 * For data Tx queues (all other queues), no super-size command
-	 * space is needed.
-	 */
-	len = sizeof(struct iwl3945_cmd) * slots_num;
-	if (txq_id == IWL_CMD_QUEUE_NUM)
-		len +=  IWL_MAX_SCAN_SIZE;
-	txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
-	if (!txq->cmd)
-		return -ENOMEM;
-
-	/* Alloc driver data array and TFD circular buffer */
-	rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
-	if (rc) {
-		pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
-		return -ENOMEM;
-	}
-	txq->need_update = 0;
-
-	/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-	 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
-	BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
-	/* Initialize queue high/low-water, head/tail indexes */
-	iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
-	/* Tell device where to find queue, enable DMA channel. */
-	iwl3945_hw_tx_queue_init(priv, txq);
-
-	return 0;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
-{
-	struct iwl3945_queue *q = &txq->q;
-	struct pci_dev *dev = priv->pci_dev;
-	int len;
-
-	if (q->n_bd == 0)
-		return;
-
-	/* first, empty all BD's */
-	for (; q->write_ptr != q->read_ptr;
-	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
-		iwl3945_hw_txq_free_tfd(priv, txq);
-
-	len = sizeof(struct iwl3945_cmd) * q->n_window;
-	if (q->id == IWL_CMD_QUEUE_NUM)
-		len += IWL_MAX_SCAN_SIZE;
-
-	/* De-alloc array of command/tx buffers */
-	pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
-	/* De-alloc circular buffer of TFDs */
-	if (txq->q.n_bd)
-		pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
-				    txq->q.n_bd, txq->bd, txq->q.dma_addr);
-
-	/* De-alloc array of per-TFD driver data */
-	kfree(txq->txb);
-	txq->txb = NULL;
-
-	/* 0-fill queue descriptor structure */
-	memset(txq, 0, sizeof(*txq));
-}
-
-const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ /* module parameters */
+struct iwl_mod_params iwl3945_mod_params = {
+	.num_of_queues = IWL39_MAX_NUM_QUEUES,
+	.sw_crypto = 1,
+	.restart_fw = 1,
+	/* the rest are 0 by default */
+};
 
 /*************** STATION TABLE MANAGEMENT ****
  * mac80211 should be examined to determine if sta_info is duplicating
@@ -344,7 +107,7 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN
  *
  * NOTE:  This does not remove station from device's station table.
  */
-static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap)
+static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
 	int index = IWL_INVALID_STATION;
 	int i;
@@ -355,11 +118,11 @@ static u8 iwl3945_remove_station(struct
 	if (is_ap)
 		index = IWL_AP_ID;
 	else if (is_broadcast_ether_addr(addr))
-		index = priv->hw_setting.bcast_sta_id;
+		index = priv->hw_params.bcast_sta_id;
 	else
-		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
-			if (priv->stations[i].used &&
-			    !compare_ether_addr(priv->stations[i].sta.sta.addr,
+		for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
+			if (priv->stations_39[i].used &&
+			    !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
 						addr)) {
 				index = i;
 				break;
@@ -368,8 +131,8 @@ static u8 iwl3945_remove_station(struct
 	if (unlikely(index == IWL_INVALID_STATION))
 		goto out;
 
-	if (priv->stations[index].used) {
-		priv->stations[index].used = 0;
+	if (priv->stations_39[index].used) {
+		priv->stations_39[index].used = 0;
 		priv->num_stations--;
 	}
 
@@ -386,14 +149,14 @@ out:
  *
  * NOTE:  This does not clear or otherwise alter the device's station table.
  */
-static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
+static void iwl3945_clear_stations_table(struct iwl_priv *priv)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
 	priv->num_stations = 0;
-	memset(priv->stations, 0, sizeof(priv->stations));
+	memset(priv->stations_39, 0, sizeof(priv->stations_39));
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
@@ -401,7 +164,7 @@ static void iwl3945_clear_stations_table
 /**
  * iwl3945_add_station - Add station to station tables in driver and device
  */
-u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
+u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
 {
 	int i;
 	int index = IWL_INVALID_STATION;
@@ -413,16 +176,16 @@ u8 iwl3945_add_station(struct iwl3945_pr
 	if (is_ap)
 		index = IWL_AP_ID;
 	else if (is_broadcast_ether_addr(addr))
-		index = priv->hw_setting.bcast_sta_id;
+		index = priv->hw_params.bcast_sta_id;
 	else
-		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
-			if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+		for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
+			if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
 						addr)) {
 				index = i;
 				break;
 			}
 
-			if (!priv->stations[i].used &&
+			if (!priv->stations_39[i].used &&
 			    index == IWL_INVALID_STATION)
 				index = i;
 		}
@@ -434,14 +197,14 @@ u8 iwl3945_add_station(struct iwl3945_pr
 		return index;
 	}
 
-	if (priv->stations[index].used &&
-	   !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
+	if (priv->stations_39[index].used &&
+	   !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
 		spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 		return index;
 	}
 
-	IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr);
-	station = &priv->stations[index];
+	IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
+	station = &priv->stations_39[index];
 	station->used = 1;
 	priv->num_stations++;
 
@@ -460,531 +223,35 @@ u8 iwl3945_add_station(struct iwl3945_pr
 	/* Turn on both antennas for the station... */
 	station->sta.rate_n_flags =
 			iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
-	station->current_rate.rate_n_flags =
-			le16_to_cpu(station->sta.rate_n_flags);
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
 	/* Add station to device's station table */
-	iwl3945_send_add_station(priv, &station->sta, flags);
+	iwl_send_add_sta(priv,
+			 (struct iwl_addsta_cmd *)&station->sta, flags);
 	return index;
 
 }
 
-/*************** DRIVER STATUS FUNCTIONS   *****/
-
-static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
-{
-	/* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
-	 * set but EXIT_PENDING is not */
-	return test_bit(STATUS_READY, &priv->status) &&
-	       test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
-	       !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
-{
-	return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl3945_is_init(struct iwl3945_priv *priv)
-{
-	return test_bit(STATUS_INIT, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
-{
-	return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
-{
-	return test_bit(STATUS_RF_KILL_HW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
-{
-	return iwl3945_is_rfkill_hw(priv) ||
-		iwl3945_is_rfkill_sw(priv);
-}
-
-static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
-{
-
-	if (iwl3945_is_rfkill(priv))
-		return 0;
-
-	return iwl3945_is_ready(priv);
-}
-
-/*************** HOST COMMAND QUEUE FUNCTIONS   *****/
-
-#define IWL_CMD(x) case x: return #x
-
-static const char *get_cmd_string(u8 cmd)
-{
-	switch (cmd) {
-		IWL_CMD(REPLY_ALIVE);
-		IWL_CMD(REPLY_ERROR);
-		IWL_CMD(REPLY_RXON);
-		IWL_CMD(REPLY_RXON_ASSOC);
-		IWL_CMD(REPLY_QOS_PARAM);
-		IWL_CMD(REPLY_RXON_TIMING);
-		IWL_CMD(REPLY_ADD_STA);
-		IWL_CMD(REPLY_REMOVE_STA);
-		IWL_CMD(REPLY_REMOVE_ALL_STA);
-		IWL_CMD(REPLY_3945_RX);
-		IWL_CMD(REPLY_TX);
-		IWL_CMD(REPLY_RATE_SCALE);
-		IWL_CMD(REPLY_LEDS_CMD);
-		IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
-		IWL_CMD(RADAR_NOTIFICATION);
-		IWL_CMD(REPLY_QUIET_CMD);
-		IWL_CMD(REPLY_CHANNEL_SWITCH);
-		IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
-		IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
-		IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
-		IWL_CMD(POWER_TABLE_CMD);
-		IWL_CMD(PM_SLEEP_NOTIFICATION);
-		IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
-		IWL_CMD(REPLY_SCAN_CMD);
-		IWL_CMD(REPLY_SCAN_ABORT_CMD);
-		IWL_CMD(SCAN_START_NOTIFICATION);
-		IWL_CMD(SCAN_RESULTS_NOTIFICATION);
-		IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
-		IWL_CMD(BEACON_NOTIFICATION);
-		IWL_CMD(REPLY_TX_BEACON);
-		IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
-		IWL_CMD(QUIET_NOTIFICATION);
-		IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
-		IWL_CMD(MEASURE_ABORT_NOTIFICATION);
-		IWL_CMD(REPLY_BT_CONFIG);
-		IWL_CMD(REPLY_STATISTICS_CMD);
-		IWL_CMD(STATISTICS_NOTIFICATION);
-		IWL_CMD(REPLY_CARD_STATE_CMD);
-		IWL_CMD(CARD_STATE_NOTIFICATION);
-		IWL_CMD(MISSED_BEACONS_NOTIFICATION);
-	default:
-		return "UNKNOWN";
-
-	}
-}
-
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
-/**
- * iwl3945_enqueue_hcmd - enqueue a uCode command
- * @priv: device private data point
- * @cmd: a point to the ucode command structure
- *
- * The function returns < 0 values to indicate the operation is
- * failed. On success, it turns the index (> 0) of command in the
- * command queue.
- */
-static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
-	struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
-	struct iwl3945_queue *q = &txq->q;
-	struct iwl3945_tfd_frame *tfd;
-	u32 *control_flags;
-	struct iwl3945_cmd *out_cmd;
-	u32 idx;
-	u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
-	dma_addr_t phys_addr;
-	int pad;
-	u16 count;
-	int ret;
-	unsigned long flags;
-
-	/* If any of the command structures end up being larger than
-	 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
-	 * we will need to increase the size of the TFD entries */
-	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
-	       !(cmd->meta.flags & CMD_SIZE_HUGE));
-
-
-	if (iwl3945_is_rfkill(priv)) {
-		IWL_DEBUG_INFO("Not sending command - RF KILL");
-		return -EIO;
-	}
-
-	if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
-		IWL_ERROR("No space for Tx\n");
-		return -ENOSPC;
-	}
-
-	spin_lock_irqsave(&priv->hcmd_lock, flags);
-
-	tfd = &txq->bd[q->write_ptr];
-	memset(tfd, 0, sizeof(*tfd));
-
-	control_flags = (u32 *) tfd;
-
-	idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
-	out_cmd = &txq->cmd[idx];
-
-	out_cmd->hdr.cmd = cmd->id;
-	memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
-	memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
-	/* At this point, the out_cmd now has all of the incoming cmd
-	 * information */
-
-	out_cmd->hdr.flags = 0;
-	out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
-			INDEX_TO_SEQ(q->write_ptr));
-	if (out_cmd->meta.flags & CMD_SIZE_HUGE)
-		out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
-	phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
-			offsetof(struct iwl3945_cmd, hdr);
-	iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
-
-	pad = U32_PAD(cmd->len);
-	count = TFD_CTL_COUNT_GET(*control_flags);
-	*control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad);
-
-	IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
-		     "%d bytes at %d[%d]:%d\n",
-		     get_cmd_string(out_cmd->hdr.cmd),
-		     out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
-		     fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
-
-	txq->need_update = 1;
-
-	/* Increment and update queue's write index */
-	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
-	ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
-
-	spin_unlock_irqrestore(&priv->hcmd_lock, flags);
-	return ret ? ret : idx;
-}
-
-static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
-	int ret;
-
-	BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
-
-	/* An asynchronous command can not expect an SKB to be set. */
-	BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
-
-	/* An asynchronous command MUST have a callback. */
-	BUG_ON(!cmd->meta.u.callback);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return -EBUSY;
-
-	ret = iwl3945_enqueue_hcmd(priv, cmd);
-	if (ret < 0) {
-		IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
-			  get_cmd_string(cmd->id), ret);
-		return ret;
-	}
-	return 0;
-}
-
-static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
-	int cmd_idx;
-	int ret;
-
-	BUG_ON(cmd->meta.flags & CMD_ASYNC);
-
-	 /* A synchronous command can not have a callback set. */
-	BUG_ON(cmd->meta.u.callback != NULL);
-
-	if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
-		IWL_ERROR("Error sending %s: Already sending a host command\n",
-			  get_cmd_string(cmd->id));
-		ret = -EBUSY;
-		goto out;
-	}
-
-	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-	if (cmd->meta.flags & CMD_WANT_SKB)
-		cmd->meta.source = &cmd->meta;
-
-	cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
-	if (cmd_idx < 0) {
-		ret = cmd_idx;
-		IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
-			  get_cmd_string(cmd->id), ret);
-		goto out;
-	}
-
-	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-			!test_bit(STATUS_HCMD_ACTIVE, &priv->status),
-			HOST_COMPLETE_TIMEOUT);
-	if (!ret) {
-		if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
-			IWL_ERROR("Error sending %s: time out after %dms.\n",
-				  get_cmd_string(cmd->id),
-				  jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-
-			clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-			ret = -ETIMEDOUT;
-			goto cancel;
-		}
-	}
-
-	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-		IWL_DEBUG_INFO("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("Command %s failed: FW Error\n",
-			       get_cmd_string(cmd->id));
-		ret = -EIO;
-		goto fail;
-	}
-	if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
-		IWL_ERROR("Error: Response NULL in '%s'\n",
-			  get_cmd_string(cmd->id));
-		ret = -EIO;
-		goto cancel;
-	}
-
-	ret = 0;
-	goto out;
-
-cancel:
-	if (cmd->meta.flags & CMD_WANT_SKB) {
-		struct iwl3945_cmd *qcmd;
-
-		/* Cancel the CMD_WANT_SKB flag for the cmd in the
-		 * TX cmd queue. Otherwise in case the cmd comes
-		 * in later, it will possibly set an invalid
-		 * address (cmd->meta.source). */
-		qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
-		qcmd->meta.flags &= ~CMD_WANT_SKB;
-	}
-fail:
-	if (cmd->meta.u.skb) {
-		dev_kfree_skb_any(cmd->meta.u.skb);
-		cmd->meta.u.skb = NULL;
-	}
-out:
-	clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
-	return ret;
-}
-
-int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
-	if (cmd->meta.flags & CMD_ASYNC)
-		return iwl3945_send_cmd_async(priv, cmd);
-
-	return iwl3945_send_cmd_sync(priv, cmd);
-}
-
-int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
-{
-	struct iwl3945_host_cmd cmd = {
-		.id = id,
-		.len = len,
-		.data = data,
-	};
-
-	return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
-{
-	struct iwl3945_host_cmd cmd = {
-		.id = id,
-		.len = sizeof(val),
-		.data = &val,
-	};
-
-	return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
-{
-	return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
-}
-
-/**
- * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @band: 2.4 or 5 GHz band
- * @channel: Any channel valid for the requested band
-
- * In addition to setting the staging RXON, priv->band is also set.
- *
- * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the band
- */
-static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
-				    enum ieee80211_band band,
-				    u16 channel)
-{
-	if (!iwl3945_get_channel_info(priv, band, channel)) {
-		IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
-			       channel, band);
-		return -EINVAL;
-	}
-
-	if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
-	    (priv->band == band))
-		return 0;
-
-	priv->staging_rxon.channel = cpu_to_le16(channel);
-	if (band == IEEE80211_BAND_5GHZ)
-		priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
-	else
-		priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
-
-	priv->band = band;
-
-	IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
-
-	return 0;
-}
-
-/**
- * iwl3945_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE:  This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
-{
-	int error = 0;
-	int counter = 1;
-
-	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
-		error |= le32_to_cpu(rxon->flags &
-				(RXON_FLG_TGJ_NARROW_BAND_MSK |
-				 RXON_FLG_RADAR_DETECT_MSK));
-		if (error)
-			IWL_WARNING("check 24G fields %d | %d\n",
-				    counter++, error);
-	} else {
-		error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
-				0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
-		if (error)
-			IWL_WARNING("check 52 fields %d | %d\n",
-				    counter++, error);
-		error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
-		if (error)
-			IWL_WARNING("check 52 CCK %d | %d\n",
-				    counter++, error);
-	}
-	error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
-	if (error)
-		IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
-	/* make sure basic rates 6Mbps and 1Mbps are supported */
-	error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
-		  ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
-	if (error)
-		IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
-	error |= (le16_to_cpu(rxon->assoc_id) > 2007);
-	if (error)
-		IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
-	if (error)
-		IWL_WARNING("check CCK and short slot %d | %d\n",
-			    counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
-	if (error)
-		IWL_WARNING("check CCK & auto detect %d | %d\n",
-			    counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
-			RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
-	if (error)
-		IWL_WARNING("check TGG and auto detect %d | %d\n",
-			    counter++, error);
-
-	if ((rxon->flags & RXON_FLG_DIS_DIV_MSK))
-		error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK |
-				RXON_FLG_ANT_A_MSK)) == 0);
-	if (error)
-		IWL_WARNING("check antenna %d %d\n", counter++, error);
-
-	if (error)
-		IWL_WARNING("Tuning to channel %d\n",
-			    le16_to_cpu(rxon->channel));
-
-	if (error) {
-		IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
-		return -1;
-	}
-	return 0;
-}
-
-/**
- * iwl3945_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
-{
-
-	/* These items are only settable from the full RXON command */
-	if (!(iwl3945_is_associated(priv)) ||
-	    compare_ether_addr(priv->staging_rxon.bssid_addr,
-			       priv->active_rxon.bssid_addr) ||
-	    compare_ether_addr(priv->staging_rxon.node_addr,
-			       priv->active_rxon.node_addr) ||
-	    compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
-			       priv->active_rxon.wlap_bssid_addr) ||
-	    (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
-	    (priv->staging_rxon.channel != priv->active_rxon.channel) ||
-	    (priv->staging_rxon.air_propagation !=
-	     priv->active_rxon.air_propagation) ||
-	    (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
-		return 1;
-
-	/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
-	 * be updated with the RXON_ASSOC command -- however only some
-	 * flag transitions are allowed using RXON_ASSOC */
-
-	/* Check if we are not switching bands */
-	if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
-	    (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
-		return 1;
-
-	/* Check if we are switching association toggle */
-	if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
-		(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
-		return 1;
-
-	return 0;
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
 {
 	int rc = 0;
-	struct iwl3945_rx_packet *res = NULL;
+	struct iwl_rx_packet *res = NULL;
 	struct iwl3945_rxon_assoc_cmd rxon_assoc;
-	struct iwl3945_host_cmd cmd = {
+	struct iwl_host_cmd cmd = {
 		.id = REPLY_RXON_ASSOC,
 		.len = sizeof(rxon_assoc),
 		.meta.flags = CMD_WANT_SKB,
 		.data = &rxon_assoc,
 	};
-	const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
-	const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
+	const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+	const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
 
 	if ((rxon1->flags == rxon2->flags) &&
 	    (rxon1->filter_flags == rxon2->filter_flags) &&
 	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
 	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
-		IWL_DEBUG_INFO("Using current RXON_ASSOC.  Not resending.\n");
+		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
 		return 0;
 	}
 
@@ -994,13 +261,13 @@ static int iwl3945_send_rxon_assoc(struc
 	rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
 	rxon_assoc.reserved = 0;
 
-	rc = iwl3945_send_cmd_sync(priv, &cmd);
+	rc = iwl_send_cmd_sync(priv, &cmd);
 	if (rc)
 		return rc;
 
-	res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
+		IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
 		rc = -EIO;
 	}
 
@@ -1011,6 +278,43 @@ static int iwl3945_send_rxon_assoc(struc
 }
 
 /**
+ * iwl3945_get_antenna_flags - Get antenna flags for RXON command
+ * @priv: eeprom and antenna fields are used to determine antenna flags
+ *
+ * priv->eeprom39  is used to determine if antenna AUX/MAIN are reversed
+ * iwl3945_mod_params.antenna specifies the antenna diversity mode:
+ *
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
+ * IWL_ANTENNA_MAIN      - Force MAIN antenna
+ * IWL_ANTENNA_AUX       - Force AUX antenna
+ */
+__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+{
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+	switch (iwl3945_mod_params.antenna) {
+	case IWL_ANTENNA_DIVERSITY:
+		return 0;
+
+	case IWL_ANTENNA_MAIN:
+		if (eeprom->antenna_switch_type)
+			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+
+	case IWL_ANTENNA_AUX:
+		if (eeprom->antenna_switch_type)
+			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+	}
+
+	/* bad antenna selector value */
+	IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
+		iwl3945_mod_params.antenna);
+
+	return 0;		/* "diversity" is default if error */
+}
+
+/**
  * iwl3945_commit_rxon - commit staging_rxon to hardware
  *
  * The RXON command in staging_rxon is committed to the hardware and
@@ -1018,41 +322,44 @@ static int iwl3945_send_rxon_assoc(struc
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
 {
 	/* cast away the const for active_rxon in this function */
 	struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+	struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
 	int rc = 0;
+	bool new_assoc =
+		!!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
 
-	if (!iwl3945_is_alive(priv))
+	if (!iwl_is_alive(priv))
 		return -1;
 
 	/* always get timestamp with Rx frame */
-	priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+	staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
 
 	/* select antenna */
-	priv->staging_rxon.flags &=
+	staging_rxon->flags &=
 	    ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
-	priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
+	staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
 
-	rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
+	rc = iwl_check_rxon_cmd(priv);
 	if (rc) {
-		IWL_ERROR("Invalid RXON configuration.  Not committing.\n");
+		IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
 		return -EINVAL;
 	}
 
 	/* If we don't need to send a full RXON, we can use
 	 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
 	 * and other flags for the current radio configuration. */
-	if (!iwl3945_full_rxon_required(priv)) {
+	if (!iwl_full_rxon_required(priv)) {
 		rc = iwl3945_send_rxon_assoc(priv);
 		if (rc) {
-			IWL_ERROR("Error setting RXON_ASSOC "
+			IWL_ERR(priv, "Error setting RXON_ASSOC "
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
 
-		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+		memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
 		return 0;
 	}
@@ -1061,12 +368,17 @@ static int iwl3945_commit_rxon(struct iw
 	 * an RXON_ASSOC and the new config wants the associated mask enabled,
 	 * we must clear the associated from the active configuration
 	 * before we apply the new config */
-	if (iwl3945_is_associated(priv) &&
-	    (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
-		IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
+	if (iwl_is_associated(priv) && new_assoc) {
+		IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
-		rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+		/*
+		 * reserved4 and 5 could have been filled by the iwlcore code.
+		 * Let's clear them before pushing to the 3945.
+		 */
+		active_rxon->reserved4 = 0;
+		active_rxon->reserved5 = 0;
+		rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
 				      sizeof(struct iwl3945_rxon_cmd),
 				      &priv->active_rxon);
 
@@ -1074,290 +386,213 @@ static int iwl3945_commit_rxon(struct iw
 		 * active_rxon back to what it was previously */
 		if (rc) {
 			active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
-			IWL_ERROR("Error clearing ASSOC_MSK on current "
+			IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
 	}
 
-	IWL_DEBUG_INFO("Sending RXON\n"
+	IWL_DEBUG_INFO(priv, "Sending RXON\n"
 		       "* with%s RXON_FILTER_ASSOC_MSK\n"
 		       "* channel = %d\n"
 		       "* bssid = %pM\n",
-		       ((priv->staging_rxon.filter_flags &
-			 RXON_FILTER_ASSOC_MSK) ? "" : "out"),
-		       le16_to_cpu(priv->staging_rxon.channel),
-		       priv->staging_rxon.bssid_addr);
+		       (new_assoc ? "" : "out"),
+		       le16_to_cpu(staging_rxon->channel),
+		       staging_rxon->bssid_addr);
+
+	/*
+	 * reserved4 and 5 could have been filled by the iwlcore code.
+	 * Let's clear them before pushing to the 3945.
+	 */
+	staging_rxon->reserved4 = 0;
+	staging_rxon->reserved5 = 0;
+
+	iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
 
 	/* Apply the new configuration */
-	rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
-			      sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
+	rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+			      sizeof(struct iwl3945_rxon_cmd),
+			      staging_rxon);
 	if (rc) {
-		IWL_ERROR("Error setting new configuration (%d).\n", rc);
+		IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
 		return rc;
 	}
 
-	memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+	memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
 	iwl3945_clear_stations_table(priv);
 
 	/* If we issue a new RXON command which required a tune then we must
 	 * send a new TXPOWER command or we won't be able to Tx any frames */
-	rc = iwl3945_hw_reg_send_txpower(priv);
+	rc = priv->cfg->ops->lib->send_tx_power(priv);
 	if (rc) {
-		IWL_ERROR("Error setting Tx power (%d).\n", rc);
+		IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
 		return rc;
 	}
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) ==
+	if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
 	    IWL_INVALID_STATION) {
-		IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
 		return -EIO;
 	}
 
 	/* If we have set the ASSOC_MSK and we are in BSS mode then
 	 * add the IWL_AP_ID to the station rate table */
-	if (iwl3945_is_associated(priv) &&
+	if (iwl_is_associated(priv) &&
 	    (priv->iw_mode == NL80211_IFTYPE_STATION))
-		if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
+		if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
+					1, 0)
 		    == IWL_INVALID_STATION) {
-			IWL_ERROR("Error adding AP address for transmit.\n");
+			IWL_ERR(priv, "Error adding AP address for transmit\n");
 			return -EIO;
 		}
 
 	/* Init the hardware's rate fallback order based on the band */
 	rc = iwl3945_init_hw_rate_table(priv);
 	if (rc) {
-		IWL_ERROR("Error setting HW rate table: %02X\n", rc);
+		IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
 		return -EIO;
 	}
 
 	return 0;
 }
 
-static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
+static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+				   struct ieee80211_key_conf *keyconf,
+				   u8 sta_id)
 {
-	struct iwl3945_bt_cmd bt_cmd = {
-		.flags = 3,
-		.lead_time = 0xAA,
-		.max_kill = 1,
-		.kill_ack_mask = 0,
-		.kill_cts_mask = 0,
-	};
+	unsigned long flags;
+	__le16 key_flags = 0;
+	int ret;
 
-	return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-				sizeof(struct iwl3945_bt_cmd), &bt_cmd);
-}
+	key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
 
-static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
-{
-	int rc = 0;
-	struct iwl3945_rx_packet *res;
-	struct iwl3945_host_cmd cmd = {
-		.id = REPLY_SCAN_ABORT_CMD,
-		.meta.flags = CMD_WANT_SKB,
-	};
+	if (sta_id == priv->hw_params.bcast_sta_id)
+		key_flags |= STA_KEY_MULTICAST_MSK;
 
-	/* If there isn't a scan actively going on in the hardware
-	 * then we are in between scan bands and not actually
-	 * actively scanning, so don't send the abort command */
-	if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		return 0;
-	}
+	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+	keyconf->hw_key_idx = keyconf->keyidx;
+	key_flags &= ~STA_KEY_FLG_INVALID;
 
-	rc = iwl3945_send_cmd_sync(priv, &cmd);
-	if (rc) {
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		return rc;
-	}
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
+	priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
+	memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
+	       keyconf->keylen);
 
-	res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
-	if (res->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("SCAN_ABORT returned %d.\n", res->u.status);
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		clear_bit(STATUS_SCAN_HW, &priv->status);
-	}
+	memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+	       keyconf->keylen);
 
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+			== STA_KEY_FLG_NO_ENC)
+		priv->stations_39[sta_id].sta.key.key_offset =
+				 iwl_get_free_ucode_key_index(priv);
+	/* else, we are overriding an existing key => no need to allocated room
+	* in uCode. */
 
-	return rc;
-}
+	WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+		"no space for a new key");
 
-static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
-					struct iwl3945_cmd *cmd,
-					struct sk_buff *skb)
-{
-	return 1;
-}
+	priv->stations_39[sta_id].sta.key.key_flags = key_flags;
+	priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
 
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
-{
-	struct iwl3945_host_cmd cmd = {
-		.id = REPLY_CARD_STATE_CMD,
-		.len = sizeof(u32),
-		.data = &flags,
-		.meta.flags = meta_flag,
-	};
+	IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
 
-	if (meta_flag & CMD_ASYNC)
-		cmd.meta.u.callback = iwl3945_card_state_sync_callback;
+	ret = iwl_send_add_sta(priv,
+		(struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
 
-	return iwl3945_send_cmd(priv, &cmd);
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	return ret;
 }
 
-static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
-				     struct iwl3945_cmd *cmd, struct sk_buff *skb)
+static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+				  struct ieee80211_key_conf *keyconf,
+				  u8 sta_id)
 {
-	struct iwl3945_rx_packet *res = NULL;
-
-	if (!skb) {
-		IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
-		return 1;
-	}
-
-	res = (struct iwl3945_rx_packet *)skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  res->hdr.flags);
-		return 1;
-	}
-
-	switch (res->u.add_sta.status) {
-	case ADD_STA_SUCCESS_MSK:
-		break;
-	default:
-		break;
-	}
-
-	/* We didn't cache the SKB; let the caller free it */
-	return 1;
+	return -EOPNOTSUPP;
 }
 
-int iwl3945_send_add_station(struct iwl3945_priv *priv,
-			 struct iwl3945_addsta_cmd *sta, u8 flags)
+static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
+				  struct ieee80211_key_conf *keyconf,
+				  u8 sta_id)
 {
-	struct iwl3945_rx_packet *res = NULL;
-	int rc = 0;
-	struct iwl3945_host_cmd cmd = {
-		.id = REPLY_ADD_STA,
-		.len = sizeof(struct iwl3945_addsta_cmd),
-		.meta.flags = flags,
-		.data = sta,
-	};
-
-	if (flags & CMD_ASYNC)
-		cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
-	else
-		cmd.meta.flags |= CMD_WANT_SKB;
-
-	rc = iwl3945_send_cmd(priv, &cmd);
-
-	if (rc || (flags & CMD_ASYNC))
-		return rc;
-
-	res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
-	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
-			  res->hdr.flags);
-		rc = -EIO;
-	}
+	return -EOPNOTSUPP;
+}
 
-	if (rc == 0) {
-		switch (res->u.add_sta.status) {
-		case ADD_STA_SUCCESS_MSK:
-			IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
-			break;
-		default:
-			rc = -EIO;
-			IWL_WARNING("REPLY_ADD_STA failed\n");
-			break;
-		}
-	}
+static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
+{
+	unsigned long flags;
 
-	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
+	memset(&priv->stations_39[sta_id].sta.key, 0,
+		sizeof(struct iwl4965_keyinfo));
+	priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+	priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+	priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-	return rc;
+	IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
+	iwl_send_add_sta(priv,
+		(struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
+	return 0;
 }
 
-static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
-				   struct ieee80211_key_conf *keyconf,
-				   u8 sta_id)
+static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
+			struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
-	unsigned long flags;
-	__le16 key_flags = 0;
+	int ret = 0;
+
+	keyconf->hw_key_idx = HW_KEY_DYNAMIC;
 
 	switch (keyconf->alg) {
 	case ALG_CCMP:
-		key_flags |= STA_KEY_FLG_CCMP;
-		key_flags |= cpu_to_le16(
-				keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-		key_flags &= ~STA_KEY_FLG_INVALID;
+		ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
 		break;
 	case ALG_TKIP:
+		ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
+		break;
 	case ALG_WEP:
+		ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
+		break;
 	default:
-		return -EINVAL;
+		IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+		ret = -EINVAL;
 	}
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	priv->stations[sta_id].keyinfo.alg = keyconf->alg;
-	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
-	       keyconf->keylen);
-
-	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
-	       keyconf->keylen);
-	priv->stations[sta_id].sta.key.key_flags = key_flags;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
 
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
+	IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+		      keyconf->alg, keyconf->keylen, keyconf->keyidx,
+		      sta_id, ret);
 
-	IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
-	iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
-	return 0;
+	return ret;
 }
 
-static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
+static int iwl3945_remove_static_key(struct iwl_priv *priv)
 {
-	unsigned long flags;
+	int ret = -EOPNOTSUPP;
 
-	spin_lock_irqsave(&priv->sta_lock, flags);
-	memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
-	memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo));
-	priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
-	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
+	return ret;
+}
 
-	IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
-	iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
-	return 0;
+static int iwl3945_set_static_key(struct iwl_priv *priv,
+				struct ieee80211_key_conf *key)
+{
+	if (key->alg == ALG_WEP)
+		return -EOPNOTSUPP;
+
+	IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+	return -EINVAL;
 }
 
-static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
+static void iwl3945_clear_free_frames(struct iwl_priv *priv)
 {
 	struct list_head *element;
 
-	IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
 		       priv->frames_count);
 
 	while (!list_empty(&priv->free_frames)) {
@@ -1368,20 +603,20 @@ static void iwl3945_clear_free_frames(st
 	}
 
 	if (priv->frames_count) {
-		IWL_WARNING("%d frames still in use.  Did we lose one?\n",
+		IWL_WARN(priv, "%d frames still in use.  Did we lose one?\n",
 			    priv->frames_count);
 		priv->frames_count = 0;
 	}
 }
 
-static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
+static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv)
 {
 	struct iwl3945_frame *frame;
 	struct list_head *element;
 	if (list_empty(&priv->free_frames)) {
 		frame = kzalloc(sizeof(*frame), GFP_KERNEL);
 		if (!frame) {
-			IWL_ERROR("Could not allocate frame!\n");
+			IWL_ERR(priv, "Could not allocate frame!\n");
 			return NULL;
 		}
 
@@ -1394,18 +629,18 @@ static struct iwl3945_frame *iwl3945_get
 	return list_entry(element, struct iwl3945_frame, list);
 }
 
-static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
+static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame)
 {
 	memset(frame, 0, sizeof(*frame));
 	list_add(&frame->list, &priv->free_frames);
 }
 
-unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
 				struct ieee80211_hdr *hdr,
 				int left)
 {
 
-	if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
+	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
 	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
 	     (priv->iw_mode != NL80211_IFTYPE_AP)))
 		return 0;
@@ -1418,31 +653,7 @@ unsigned int iwl3945_fill_beacon_frame(s
 	return priv->ibss_beacon->len;
 }
 
-static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
-{
-	u8 i;
-	int rate_mask;
-
-	/* Set rate mask*/
-	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
-		rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
-	else
-		rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
-	for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
-	     i = iwl3945_rates[i].next_ieee) {
-		if (rate_mask & (1 << i))
-			return iwl3945_rates[i].plcp;
-	}
-
-	/* No valid rate was found. Assign the lowest one */
-	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
-		return IWL_RATE_1M_PLCP;
-	else
-		return IWL_RATE_6M_PLCP;
-}
-
-static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
+static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
 {
 	struct iwl3945_frame *frame;
 	unsigned int frame_size;
@@ -1452,16 +663,16 @@ static int iwl3945_send_beacon_cmd(struc
 	frame = iwl3945_get_free_frame(priv);
 
 	if (!frame) {
-		IWL_ERROR("Could not obtain free frame buffer for beacon "
+		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
 			  "command.\n");
 		return -ENOMEM;
 	}
 
-	rate = iwl3945_rate_get_lowest_plcp(priv);
+	rate = iwl_rate_get_lowest_plcp(priv);
 
 	frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
 
-	rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
 			      &frame->u.cmd[0]);
 
 	iwl3945_free_frame(priv, frame);
@@ -1469,566 +680,17 @@ static int iwl3945_send_beacon_cmd(struc
 	return rc;
 }
 
-/******************************************************************************
- *
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
-{
-	memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism.  Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
-	_iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
-	return 0;
-}
-
-/**
- * iwl3945_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE:  This routine uses the non-debug IO access functions.
- */
-int iwl3945_eeprom_init(struct iwl3945_priv *priv)
-{
-	u16 *e = (u16 *)&priv->eeprom;
-	u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
-	int sz = sizeof(priv->eeprom);
-	int ret;
-	u16 addr;
-
-	/* The EEPROM structure has several padding buffers within it
-	 * and when adding new EEPROM maps is subject to programmer errors
-	 * which may be very difficult to identify without explicitly
-	 * checking the resulting size of the eeprom map. */
-	BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
-	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
-		return -ENOENT;
-	}
-
-	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
-	ret = iwl3945_eeprom_acquire_semaphore(priv);
-	if (ret < 0) {
-		IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
-		return -ENOENT;
-	}
-
-	/* eeprom is an array of 16bit values */
-	for (addr = 0; addr < sz; addr += sizeof(u16)) {
-		u32 r;
-
-		_iwl3945_write32(priv, CSR_EEPROM_REG,
-				 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-		_iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
-		ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
-					      CSR_EEPROM_REG_READ_VALID_MSK,
-					      IWL_EEPROM_ACCESS_TIMEOUT);
-		if (ret < 0) {
-			IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
-			return ret;
-		}
-
-		r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
-		e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
-	}
-
-	return 0;
-}
-
-static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
+static void iwl3945_unset_hw_params(struct iwl_priv *priv)
 {
-	if (priv->hw_setting.shared_virt)
+	if (priv->shared_virt)
 		pci_free_consistent(priv->pci_dev,
 				    sizeof(struct iwl3945_shared),
-				    priv->hw_setting.shared_virt,
-				    priv->hw_setting.shared_phys);
-}
-
-/**
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-				    u16 basic_rate, int *left)
-{
-	u16 ret_rates = 0, bit;
-	int i;
-	u8 *cnt = ie;
-	u8 *rates = ie + 1;
-
-	for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
-		if (bit & supported_rate) {
-			ret_rates |= bit;
-			rates[*cnt] = iwl3945_rates[i].ieee |
-				((bit & basic_rate) ? 0x80 : 0x00);
-			(*cnt)++;
-			(*left)--;
-			if ((*left <= 0) ||
-			    (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
-				break;
-		}
-	}
-
-	return ret_rates;
-}
-
-/**
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
-			      struct ieee80211_mgmt *frame,
-			      int left)
-{
-	int len = 0;
-	u8 *pos = NULL;
-	u16 active_rates, ret_rates, cck_rates;
-
-	/* Make sure there is enough space for the probe request,
-	 * two mandatory IEs and the data */
-	left -= 24;
-	if (left < 0)
-		return 0;
-	len += 24;
-
-	frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-	memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
-	memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
-	memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
-	frame->seq_ctrl = 0;
-
-	/* fill in our indirect SSID IE */
-	/* ...next IE... */
-
-	left -= 2;
-	if (left < 0)
-		return 0;
-	len += 2;
-	pos = &(frame->u.probe_req.variable[0]);
-	*pos++ = WLAN_EID_SSID;
-	*pos++ = 0;
-
-	/* fill in supported rate */
-	/* ...next IE... */
-	left -= 2;
-	if (left < 0)
-		return 0;
-
-	/* ... fill it in... */
-	*pos++ = WLAN_EID_SUPP_RATES;
-	*pos = 0;
-
-	priv->active_rate = priv->rates_mask;
-	active_rates = priv->active_rate;
-	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
-
-	cck_rates = IWL_CCK_RATES_MASK & active_rates;
-	ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
-			priv->active_rate_basic, &left);
-	active_rates &= ~ret_rates;
-
-	ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
-				 priv->active_rate_basic, &left);
-	active_rates &= ~ret_rates;
-
-	len += 2 + *pos;
-	pos += (*pos) + 1;
-	if (active_rates == 0)
-		goto fill_end;
-
-	/* fill in supported extended rate */
-	/* ...next IE... */
-	left -= 2;
-	if (left < 0)
-		return 0;
-	/* ... fill it in... */
-	*pos++ = WLAN_EID_EXT_SUPP_RATES;
-	*pos = 0;
-	iwl3945_supported_rate_to_ie(pos, active_rates,
-				 priv->active_rate_basic, &left);
-	if (*pos > 0)
-		len += 2 + *pos;
-
- fill_end:
-	return (u16)len;
-}
-
-/*
- * QoS  support
-*/
-static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
-				       struct iwl3945_qosparam_cmd *qos)
-{
-
-	return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
-				sizeof(struct iwl3945_qosparam_cmd), qos);
-}
-
-static void iwl3945_reset_qos(struct iwl3945_priv *priv)
-{
-	u16 cw_min = 15;
-	u16 cw_max = 1023;
-	u8 aifs = 2;
-	u8 is_legacy = 0;
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->qos_data.qos_active = 0;
-
-	/* QoS always active in AP and ADHOC mode
-	 * In STA mode wait for association
-	 */
-	if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
-	    priv->iw_mode == NL80211_IFTYPE_AP)
-		priv->qos_data.qos_active = 1;
-	else
-		priv->qos_data.qos_active = 0;
-
-
-	/* check for legacy mode */
-	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
-	     (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
-	    (priv->iw_mode == NL80211_IFTYPE_STATION &&
-	     (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
-		cw_min = 31;
-		is_legacy = 1;
-	}
-
-	if (priv->qos_data.qos_active)
-		aifs = 3;
-
-	priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
-	priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
-	priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
-	priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
-	priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
-
-	if (priv->qos_data.qos_active) {
-		i = 1;
-		priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
-		priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
-		priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
-		priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
-		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
-		i = 2;
-		priv->qos_data.def_qos_parm.ac[i].cw_min =
-			cpu_to_le16((cw_min + 1) / 2 - 1);
-		priv->qos_data.def_qos_parm.ac[i].cw_max =
-			cpu_to_le16(cw_max);
-		priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
-		if (is_legacy)
-			priv->qos_data.def_qos_parm.ac[i].edca_txop =
-				cpu_to_le16(6016);
-		else
-			priv->qos_data.def_qos_parm.ac[i].edca_txop =
-				cpu_to_le16(3008);
-		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
-		i = 3;
-		priv->qos_data.def_qos_parm.ac[i].cw_min =
-			cpu_to_le16((cw_min + 1) / 4 - 1);
-		priv->qos_data.def_qos_parm.ac[i].cw_max =
-			cpu_to_le16((cw_max + 1) / 2 - 1);
-		priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
-		priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-		if (is_legacy)
-			priv->qos_data.def_qos_parm.ac[i].edca_txop =
-				cpu_to_le16(3264);
-		else
-			priv->qos_data.def_qos_parm.ac[i].edca_txop =
-				cpu_to_le16(1504);
-	} else {
-		for (i = 1; i < 4; i++) {
-			priv->qos_data.def_qos_parm.ac[i].cw_min =
-				cpu_to_le16(cw_min);
-			priv->qos_data.def_qos_parm.ac[i].cw_max =
-				cpu_to_le16(cw_max);
-			priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
-			priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
-			priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-		}
-	}
-	IWL_DEBUG_QOS("set QoS to default \n");
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
-{
-	unsigned long flags;
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->qos_data.def_qos_parm.qos_flags = 0;
-
-	if (priv->qos_data.qos_cap.q_AP.queue_request &&
-	    !priv->qos_data.qos_cap.q_AP.txop_request)
-		priv->qos_data.def_qos_parm.qos_flags |=
-			QOS_PARAM_FLG_TXOP_TYPE_MSK;
-
-	if (priv->qos_data.qos_active)
-		priv->qos_data.def_qos_parm.qos_flags |=
-			QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	if (force || iwl3945_is_associated(priv)) {
-		IWL_DEBUG_QOS("send QoS cmd with QoS active %d \n",
-			      priv->qos_data.qos_active);
-
-		iwl3945_send_qos_params_command(priv,
-				&(priv->qos_data.def_qos_parm));
-	}
-}
-
-/*
- * Power management (not Tx power!) functions
- */
-#define MSEC_TO_USEC 1024
-
-#define NOSLP __constant_cpu_to_le32(0)
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK
-#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
-				     __constant_cpu_to_le32(X1), \
-				     __constant_cpu_to_le32(X2), \
-				     __constant_cpu_to_le32(X3), \
-				     __constant_cpu_to_le32(X4)}
-
-
-/* default power management (not Tx power) table values */
-/* for TIM  0-10 */
-static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
-	{{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
-	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
-	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
-	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
-	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
-	{{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
-};
-
-/* for TIM > 10 */
-static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
-	{{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
-	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
-		 SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
-	{{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
-		 SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
-	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
-		 SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
-	{{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
-	{{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
-		 SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
-};
-
-int iwl3945_power_init_handle(struct iwl3945_priv *priv)
-{
-	int rc = 0, i;
-	struct iwl3945_power_mgr *pow_data;
-	int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
-	u16 pci_pm;
-
-	IWL_DEBUG_POWER("Initialize power \n");
-
-	pow_data = &(priv->power_data);
-
-	memset(pow_data, 0, sizeof(*pow_data));
-
-	pow_data->active_index = IWL_POWER_RANGE_0;
-	pow_data->dtim_val = 0xffff;
-
-	memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
-	memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
-
-	rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
-	if (rc != 0)
-		return 0;
-	else {
-		struct iwl3945_powertable_cmd *cmd;
-
-		IWL_DEBUG_POWER("adjust power command flags\n");
-
-		for (i = 0; i < IWL_POWER_AC; i++) {
-			cmd = &pow_data->pwr_range_0[i].cmd;
-
-			if (pci_pm & 0x1)
-				cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
-			else
-				cmd->flags |= IWL_POWER_PCI_PM_MSK;
-		}
-	}
-	return rc;
-}
-
-static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
-				struct iwl3945_powertable_cmd *cmd, u32 mode)
-{
-	int rc = 0, i;
-	u8 skip;
-	u32 max_sleep = 0;
-	struct iwl3945_power_vec_entry *range;
-	u8 period = 0;
-	struct iwl3945_power_mgr *pow_data;
-
-	if (mode > IWL_POWER_INDEX_5) {
-		IWL_DEBUG_POWER("Error invalid power mode \n");
-		return -1;
-	}
-	pow_data = &(priv->power_data);
-
-	if (pow_data->active_index == IWL_POWER_RANGE_0)
-		range = &pow_data->pwr_range_0[0];
-	else
-		range = &pow_data->pwr_range_1[1];
-
-	memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
-
-#ifdef IWL_MAC80211_DISABLE
-	if (priv->assoc_network != NULL) {
-		unsigned long flags;
-
-		period = priv->assoc_network->tim.tim_period;
-	}
-#endif	/*IWL_MAC80211_DISABLE */
-	skip = range[mode].no_dtim;
-
-	if (period == 0) {
-		period = 1;
-		skip = 0;
-	}
-
-	if (skip == 0) {
-		max_sleep = period;
-		cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
-	} else {
-		__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
-		max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
-		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);
-	}
-
-	IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
-	IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
-	IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
-	IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
-			le32_to_cpu(cmd->sleep_interval[0]),
-			le32_to_cpu(cmd->sleep_interval[1]),
-			le32_to_cpu(cmd->sleep_interval[2]),
-			le32_to_cpu(cmd->sleep_interval[3]),
-			le32_to_cpu(cmd->sleep_interval[4]));
-
-	return rc;
-}
-
-static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
-{
-	u32 uninitialized_var(final_mode);
-	int rc;
-	struct iwl3945_powertable_cmd cmd;
-
-	/* If on battery, set to 3,
-	 * if plugged into AC power, set to CAM ("continuously aware mode"),
-	 * else user level */
-	switch (mode) {
-	case IWL_POWER_BATTERY:
-		final_mode = IWL_POWER_INDEX_3;
-		break;
-	case IWL_POWER_AC:
-		final_mode = IWL_POWER_MODE_CAM;
-		break;
-	default:
-		final_mode = mode;
-		break;
-	}
-
-	iwl3945_update_power_cmd(priv, &cmd, final_mode);
-
-	rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
-
-	if (final_mode == IWL_POWER_MODE_CAM)
-		clear_bit(STATUS_POWER_PMI, &priv->status);
-	else
-		set_bit(STATUS_POWER_PMI, &priv->status);
-
-	return rc;
-}
-
-/**
- * iwl3945_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
-{
-	if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
-		clear_bit(STATUS_SCANNING, &priv->status);
-		return 0;
-	}
-
-	if (test_bit(STATUS_SCANNING, &priv->status)) {
-		if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-			IWL_DEBUG_SCAN("Queuing scan abort.\n");
-			set_bit(STATUS_SCAN_ABORTING, &priv->status);
-			queue_work(priv->workqueue, &priv->abort_scan);
-
-		} else
-			IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
-		return test_bit(STATUS_SCANNING, &priv->status);
-	}
-
-	return 0;
-}
-
-/**
- * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
-{
-	unsigned long now = jiffies;
-	int ret;
-
-	ret = iwl3945_scan_cancel(priv);
-	if (ret && ms) {
-		mutex_unlock(&priv->mutex);
-		while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
-				test_bit(STATUS_SCANNING, &priv->status))
-			msleep(1);
-		mutex_lock(&priv->mutex);
-
-		return test_bit(STATUS_SCANNING, &priv->status);
-	}
-
-	return ret;
+				    priv->shared_virt,
+				    priv->shared_phys);
 }
 
 #define MAX_UCODE_BEACON_INTERVAL	1024
-#define INTEL_CONN_LISTEN_INTERVAL	__constant_cpu_to_le16(0xA)
+#define INTEL_CONN_LISTEN_INTERVAL	cpu_to_le16(0xA)
 
 static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
 {
@@ -2043,7 +705,7 @@ static __le16 iwl3945_adjust_beacon_inte
 	return cpu_to_le16(new_val);
 }
 
-static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
+static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
 {
 	u64 interval_tm_unit;
 	u64 tsf, result;
@@ -2054,13 +716,10 @@ static void iwl3945_setup_rxon_timing(st
 	conf = ieee80211_get_hw_conf(priv->hw);
 
 	spin_lock_irqsave(&priv->lock, flags);
-	priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
-	priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
-
+	priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
 	priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
 
-	tsf = priv->timestamp1;
-	tsf = ((tsf << 32) | priv->timestamp0);
+	tsf = priv->timestamp;
 
 	beacon_int = priv->beacon_int;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -2092,234 +751,77 @@ static void iwl3945_setup_rxon_timing(st
 	priv->rxon_timing.beacon_init_val =
 	    cpu_to_le32((u32) ((u64) interval_tm_unit - result));
 
-	IWL_DEBUG_ASSOC
-	    ("beacon interval %d beacon timer %d beacon tim %d\n",
+	IWL_DEBUG_ASSOC(priv,
+		"beacon interval %d beacon timer %d beacon tim %d\n",
 		le16_to_cpu(priv->rxon_timing.beacon_interval),
 		le32_to_cpu(priv->rxon_timing.beacon_init_val),
 		le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
-{
-	if (!iwl3945_is_ready_rf(priv)) {
-		IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
-		return -EIO;
-	}
-
-	if (test_bit(STATUS_SCANNING, &priv->status)) {
-		IWL_DEBUG_SCAN("Scan already in progress.\n");
-		return -EAGAIN;
-	}
-
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN("Scan request while abort pending.  "
-			       "Queuing.\n");
-		return -EAGAIN;
-	}
-
-	IWL_DEBUG_INFO("Starting scan...\n");
-	if (priv->cfg->sku & IWL_SKU_G)
-		priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
-	if (priv->cfg->sku & IWL_SKU_A)
-		priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
-	set_bit(STATUS_SCANNING, &priv->status);
-	priv->scan_start = jiffies;
-	priv->scan_pass_start = priv->scan_start;
-
-	queue_work(priv->workqueue, &priv->request_scan);
-
-	return 0;
-}
-
-static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
-{
-	struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
-
-	if (hw_decrypt)
-		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
-	else
-		rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
-	return 0;
-}
-
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
-					  enum ieee80211_band band)
-{
-	if (band == IEEE80211_BAND_5GHZ) {
-		priv->staging_rxon.flags &=
-		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
-		      | RXON_FLG_CCK_MSK);
-		priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
-	} else {
-		/* Copied from iwl3945_bg_post_associate() */
-		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
-			priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
-		else
-			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
-		if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
-			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
-		priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
-		priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
-		priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
-	}
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
-					      int mode)
-{
-	const struct iwl3945_channel_info *ch_info;
-
-	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
-	switch (mode) {
-	case NL80211_IFTYPE_AP:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
-		break;
-
-	case NL80211_IFTYPE_STATION:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
-		priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-
-	case NL80211_IFTYPE_ADHOC:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
-		priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
-		priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
-						  RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-
-	case NL80211_IFTYPE_MONITOR:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
-		priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
-		    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-	default:
-		IWL_ERROR("Unsupported interface type %d\n", mode);
-		break;
-	}
-
-#if 0
-	/* TODO:  Figure out when short_preamble would be set and cache from
-	 * that */
-	if (!hw_to_local(priv->hw)->short_preamble)
-		priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
-	else
-		priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
-	ch_info = iwl3945_get_channel_info(priv, priv->band,
-				       le16_to_cpu(priv->active_rxon.channel));
-
-	if (!ch_info)
-		ch_info = &priv->channel_info[0];
-
-	/*
-	 * in some case A channels are all non IBSS
-	 * in this case force B/G channel
-	 */
-	if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
-		ch_info = &priv->channel_info[0];
-
-	priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
-	if (is_channel_a_band(ch_info))
-		priv->band = IEEE80211_BAND_5GHZ;
-	else
-		priv->band = IEEE80211_BAND_2GHZ;
-
-	iwl3945_set_flags_for_phymode(priv, priv->band);
-
-	priv->staging_rxon.ofdm_basic_rates =
-	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-	priv->staging_rxon.cck_basic_rates =
-	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-}
-
-static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
+static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
 {
 	if (mode == NL80211_IFTYPE_ADHOC) {
-		const struct iwl3945_channel_info *ch_info;
+		const struct iwl_channel_info *ch_info;
 
-		ch_info = iwl3945_get_channel_info(priv,
+		ch_info = iwl_get_channel_info(priv,
 			priv->band,
 			le16_to_cpu(priv->staging_rxon.channel));
 
 		if (!ch_info || !is_channel_ibss(ch_info)) {
-			IWL_ERROR("channel %d not IBSS channel\n",
+			IWL_ERR(priv, "channel %d not IBSS channel\n",
 				  le16_to_cpu(priv->staging_rxon.channel));
 			return -EINVAL;
 		}
 	}
 
-	iwl3945_connection_init_rx_config(priv, mode);
-	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+	iwl_connection_init_rx_config(priv, mode);
 
 	iwl3945_clear_stations_table(priv);
 
 	/* don't commit rxon if rf-kill is on*/
-	if (!iwl3945_is_ready_rf(priv))
-		return -EAGAIN;
-
-	cancel_delayed_work(&priv->scan_check);
-	if (iwl3945_scan_cancel_timeout(priv, 100)) {
-		IWL_WARNING("Aborted scan still in progress after 100ms\n");
-		IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+	if (!iwl_is_ready_rf(priv))
 		return -EAGAIN;
-	}
 
 	iwl3945_commit_rxon(priv);
 
 	return 0;
 }
 
-static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
+static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
 				      struct ieee80211_tx_info *info,
-				      struct iwl3945_cmd *cmd,
+				      struct iwl_cmd *cmd,
 				      struct sk_buff *skb_frag,
-				      int last_frag)
+				      int sta_id)
 {
+	struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 	struct iwl3945_hw_key *keyinfo =
-	    &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
+	    &priv->stations_39[sta_id].keyinfo;
 
 	switch (keyinfo->alg) {
 	case ALG_CCMP:
-		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
-		memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
-		IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+		tx->sec_ctl = TX_CMD_SEC_CCM;
+		memcpy(tx->key, keyinfo->key, keyinfo->keylen);
+		IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
 		break;
 
 	case ALG_TKIP:
-#if 0
-		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
-
-		if (last_frag)
-			memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8,
-			       8);
-		else
-			memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
-#endif
 		break;
 
 	case ALG_WEP:
-		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
+		tx->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)
-			cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+			tx->sec_ctl |= TX_CMD_SEC_KEY128;
 
-		memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
+		memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
 
-		IWL_DEBUG_TX("Configuring packet for WEP encryption "
+		IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
 			     "with key %d\n", info->control.hw_key->hw_key_idx);
 		break;
 
 	default:
-		printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
+		IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
 		break;
 	}
 }
@@ -2327,17 +829,17 @@ static void iwl3945_build_tx_cmd_hwcrypt
 /*
  * handle build REPLY_TX command notification.
  */
-static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
-				  struct iwl3945_cmd *cmd,
+static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
+				  struct iwl_cmd *cmd,
 				  struct ieee80211_tx_info *info,
-				  struct ieee80211_hdr *hdr,
-				  int is_unicast, u8 std_id)
+				  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;
 	__le16 fc = hdr->frame_control;
-	__le32 tx_flags = cmd->cmd.tx.tx_flags;
 	u8 rc_flags = info->control.rates[0].flags;
 
-	cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+	tx->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))
@@ -2350,13 +852,13 @@ static void iwl3945_build_tx_cmd_basic(s
 		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
 	}
 
-	cmd->cmd.tx.sta_id = std_id;
+	tx->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);
-		cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
+		tx->tid_tspec = qc[0] & 0xf;
 		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
 	} else {
 		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -2376,25 +878,25 @@ 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))
-			cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
+			tx->timeout.pm_frame_timeout = cpu_to_le16(3);
 		else
-			cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
+			tx->timeout.pm_frame_timeout = cpu_to_le16(2);
 	} else {
-		cmd->cmd.tx.timeout.pm_frame_timeout = 0;
-#ifdef CONFIG_IWL3945_LEDS
+		tx->timeout.pm_frame_timeout = 0;
+#ifdef CONFIG_IWLWIFI_LEDS
 		priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
 #endif
 	}
 
-	cmd->cmd.tx.driver_txop = 0;
-	cmd->cmd.tx.tx_flags = tx_flags;
-	cmd->cmd.tx.next_frame_len = 0;
+	tx->driver_txop = 0;
+	tx->tx_flags = tx_flags;
+	tx->next_frame_len = 0;
 }
 
 /**
  * iwl3945_get_sta_id - Find station's index within station table
  */
-static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
+static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 {
 	int sta_id;
 	u16 fc = le16_to_cpu(hdr->frame_control);
@@ -2402,7 +904,7 @@ static int iwl3945_get_sta_id(struct iwl
 	/* If this frame is broadcast or management, use broadcast station id */
 	if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
 	    is_multicast_ether_addr(hdr->addr1))
-		return priv->hw_setting.bcast_sta_id;
+		return priv->hw_params.bcast_sta_id;
 
 	switch (priv->iw_mode) {
 
@@ -2416,7 +918,7 @@ static int iwl3945_get_sta_id(struct iwl
 		sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
 		if (sta_id != IWL_INVALID_STATION)
 			return sta_id;
-		return priv->hw_setting.bcast_sta_id;
+		return priv->hw_params.bcast_sta_id;
 
 	/* If this frame is going out to an IBSS network, find the station,
 	 * or create a new station table entry */
@@ -2431,39 +933,39 @@ static int iwl3945_get_sta_id(struct iwl
 		if (sta_id != IWL_INVALID_STATION)
 			return sta_id;
 
-		IWL_DEBUG_DROP("Station %pM not in station map. "
+		IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
 			       "Defaulting to broadcast...\n",
 			       hdr->addr1);
-		iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
-		return priv->hw_setting.bcast_sta_id;
+		iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+		return priv->hw_params.bcast_sta_id;
 	}
 	/* If we are in monitor mode, use BCAST. This is required for
 	 * packet injection. */
 	case NL80211_IFTYPE_MONITOR:
-		return priv->hw_setting.bcast_sta_id;
+		return priv->hw_params.bcast_sta_id;
 
 	default:
-		IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
-		return priv->hw_setting.bcast_sta_id;
+		IWL_WARN(priv, "Unknown mode of operation: %d\n",
+			priv->iw_mode);
+		return priv->hw_params.bcast_sta_id;
 	}
 }
 
 /*
  * start REPLY_TX command process
  */
-static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
+static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct iwl3945_tfd_frame *tfd;
-	u32 *control_flags;
-	int txq_id = skb_get_queue_mapping(skb);
-	struct iwl3945_tx_queue *txq = NULL;
-	struct iwl3945_queue *q = NULL;
+	struct iwl3945_tx_cmd *tx;
+	struct iwl_tx_queue *txq = NULL;
+	struct iwl_queue *q = NULL;
+	struct iwl_cmd *out_cmd = NULL;
 	dma_addr_t phys_addr;
 	dma_addr_t txcmd_phys;
-	struct iwl3945_cmd *out_cmd = NULL;
-	u16 len, idx, len_org, hdr_len;
+	int txq_id = skb_get_queue_mapping(skb);
+	u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
 	u8 id;
 	u8 unicast;
 	u8 sta_id;
@@ -2476,13 +978,13 @@ static int iwl3945_tx_skb(struct iwl3945
 	int rc;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (iwl3945_is_rfkill(priv)) {
-		IWL_DEBUG_DROP("Dropping - RF KILL\n");
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
 		goto drop_unlock;
 	}
 
 	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
-		IWL_ERROR("ERROR: No TX rate available.\n");
+		IWL_ERR(priv, "ERROR: No TX rate available.\n");
 		goto drop_unlock;
 	}
 
@@ -2491,21 +993,21 @@ static int iwl3945_tx_skb(struct iwl3945
 
 	fc = hdr->frame_control;
 
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 	if (ieee80211_is_auth(fc))
-		IWL_DEBUG_TX("Sending AUTH frame\n");
+		IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
 	else if (ieee80211_is_assoc_req(fc))
-		IWL_DEBUG_TX("Sending ASSOC frame\n");
+		IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
 	else if (ieee80211_is_reassoc_req(fc))
-		IWL_DEBUG_TX("Sending REASSOC frame\n");
+		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
 #endif
 
 	/* drop all data frame if we are not associated */
 	if (ieee80211_is_data(fc) &&
 	    (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
-	    (!iwl3945_is_associated(priv) ||
+	    (!iwl_is_associated(priv) ||
 	     ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
-		IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
+		IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
 		goto drop_unlock;
 	}
 
@@ -2516,21 +1018,21 @@ static int iwl3945_tx_skb(struct iwl3945
 	/* Find (or create) index into station table for destination station */
 	sta_id = iwl3945_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
-		IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
 		goto drop;
 	}
 
-	IWL_DEBUG_RATE("station Id %d\n", sta_id);
+	IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
 
 	if (ieee80211_is_data_qos(fc)) {
 		qc = ieee80211_get_qos_ctl(hdr);
 		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
-		seq_number = priv->stations[sta_id].tid[tid].seq_number &
+		seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
 				IEEE80211_SCTL_SEQ;
 		hdr->seq_ctrl = cpu_to_le16(seq_number) |
 			(hdr->seq_ctrl &
-				__constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
+				cpu_to_le16(IEEE80211_SCTL_FRAG));
 		seq_number += 0x10;
 	}
 
@@ -2540,20 +1042,17 @@ static int iwl3945_tx_skb(struct iwl3945
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	/* Set up first empty TFD within this queue's circular TFD buffer */
-	tfd = &txq->bd[q->write_ptr];
-	memset(tfd, 0, sizeof(*tfd));
-	control_flags = (u32 *) tfd;
 	idx = get_cmd_index(q, q->write_ptr, 0);
 
 	/* Set up driver data for this TFD */
-	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
+	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
 	txq->txb[q->write_ptr].skb[0] = skb;
 
 	/* Init first empty entry in queue's array of Tx/cmd buffers */
-	out_cmd = &txq->cmd[idx];
+	out_cmd = txq->cmd[idx];
+	tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
-	memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+	memset(tx, 0, sizeof(*tx));
 
 	/*
 	 * Set up the Tx-command (not MAC!) header.
@@ -2566,7 +1065,41 @@ static int iwl3945_tx_skb(struct iwl3945
 				INDEX_TO_SEQ(q->write_ptr)));
 
 	/* Copy MAC header from skb into command buffer */
-	memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
+	memcpy(tx->hdr, hdr, hdr_len);
+
+
+	if (info->control.hw_key)
+		iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
+
+	/* TODO need this for burst mode later on */
+	iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
+
+	/* set is_hcca to 0; it probably will never be implemented */
+	iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
+
+	/* Total # bytes to be transmitted */
+	len = (u16)skb->len;
+	tx->len = cpu_to_le16(len);
+
+
+	tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+	tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+
+	if (!ieee80211_has_morefrags(hdr->frame_control)) {
+		txq->need_update = 1;
+		if (qc)
+			priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+	} else {
+		wait_write_ptr = 1;
+		txq->need_update = 0;
+	}
+
+	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,
+			   ieee80211_hdrlen(fc));
 
 	/*
 	 * Use the first empty entry in this queue's command buffer array
@@ -2577,8 +1110,8 @@ static int iwl3945_tx_skb(struct iwl3945
 	 * of the MAC header (device reads on dword boundaries).
 	 * We'll tell device about this padding later.
 	 */
-	len = priv->hw_setting.tx_cmd_len +
-		sizeof(struct iwl3945_cmd_header) + hdr_len;
+	len = sizeof(struct iwl3945_tx_cmd) +
+			sizeof(struct iwl_cmd_header) + hdr_len;
 
 	len_org = len;
 	len = (len + 3) & ~3;
@@ -2590,15 +1123,18 @@ static int iwl3945_tx_skb(struct iwl3945
 
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
-	txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
-		     offsetof(struct iwl3945_cmd, hdr);
+	txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+				    len, PCI_DMA_TODEVICE);
+	/* we do not map meta data ... so we can safely access address to
+	 * provide to unmap command*/
+	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
+	pci_unmap_len_set(&out_cmd->meta, len, len);
 
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
-	iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+						   txcmd_phys, len, 1, 0);
 
-	if (info->control.hw_key)
-		iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
@@ -2606,64 +1142,30 @@ static int iwl3945_tx_skb(struct iwl3945
 	if (len) {
 		phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
 					   len, PCI_DMA_TODEVICE);
-		iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
-	}
-
-	if (!len)
-		/* If there is no payload, then we use only one Tx buffer */
-		*control_flags = TFD_CTL_COUNT_SET(1);
-	else
-		/* Else use 2 buffers.
-		 * Tell 3945 about any padding after MAC header */
-		*control_flags = TFD_CTL_COUNT_SET(2) |
-			TFD_CTL_PAD_SET(U32_PAD(len));
-
-	/* Total # bytes to be transmitted */
-	len = (u16)skb->len;
-	out_cmd->cmd.tx.len = cpu_to_le16(len);
-
-	/* TODO need this for burst mode later on */
-	iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
-
-	/* set is_hcca to 0; it probably will never be implemented */
-	iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
-
-	out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
-	out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
-
-	if (!ieee80211_has_morefrags(hdr->frame_control)) {
-		txq->need_update = 1;
-		if (qc)
-			priv->stations[sta_id].tid[tid].seq_number = seq_number;
-	} else {
-		wait_write_ptr = 1;
-		txq->need_update = 0;
+		priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+							   phys_addr, len,
+							   0, U32_PAD(len));
 	}
 
-	iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
-			   sizeof(out_cmd->cmd.tx));
-
-	iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
-			   ieee80211_hdrlen(fc));
 
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
-	rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
+	rc = iwl_txq_update_write_ptr(priv, txq);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	if (rc)
 		return rc;
 
-	if ((iwl3945_queue_space(q) < q->high_mark)
+	if ((iwl_queue_space(q) < q->high_mark)
 	    && priv->mac80211_registered) {
 		if (wait_write_ptr) {
 			spin_lock_irqsave(&priv->lock, flags);
 			txq->need_update = 1;
-			iwl3945_tx_queue_update_write_ptr(priv, txq);
+			iwl_txq_update_write_ptr(priv, txq);
 			spin_unlock_irqrestore(&priv->lock, flags);
 		}
 
-		ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
+		iwl_stop_queue(priv, skb_get_queue_mapping(skb));
 	}
 
 	return 0;
@@ -2674,142 +1176,6 @@ drop:
 	return -1;
 }
 
-static void iwl3945_set_rate(struct iwl3945_priv *priv)
-{
-	const struct ieee80211_supported_band *sband = NULL;
-	struct ieee80211_rate *rate;
-	int i;
-
-	sband = iwl3945_get_band(priv, priv->band);
-	if (!sband) {
-		IWL_ERROR("Failed to set rate: unable to get hw mode\n");
-		return;
-	}
-
-	priv->active_rate = 0;
-	priv->active_rate_basic = 0;
-
-	IWL_DEBUG_RATE("Setting rates for %s GHz\n",
-		       sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5");
-
-	for (i = 0; i < sband->n_bitrates; i++) {
-		rate = &sband->bitrates[i];
-		if ((rate->hw_value < IWL_RATE_COUNT) &&
-		    !(rate->flags & IEEE80211_CHAN_DISABLED)) {
-			IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n",
-				       rate->hw_value, iwl3945_rates[rate->hw_value].plcp);
-			priv->active_rate |= (1 << rate->hw_value);
-		}
-	}
-
-	IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
-		       priv->active_rate, priv->active_rate_basic);
-
-	/*
-	 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
-	 * otherwise set it to the default of all CCK rates and 6, 12, 24 for
-	 * OFDM
-	 */
-	if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
-		priv->staging_rxon.cck_basic_rates =
-		    ((priv->active_rate_basic &
-		      IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
-	else
-		priv->staging_rxon.cck_basic_rates =
-		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
-	if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
-		priv->staging_rxon.ofdm_basic_rates =
-		    ((priv->active_rate_basic &
-		      (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
-		      IWL_FIRST_OFDM_RATE) & 0xFF;
-	else
-		priv->staging_rxon.ofdm_basic_rates =
-		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
-{
-	unsigned long flags;
-
-	if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
-		return;
-
-	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
-			  disable_radio ? "OFF" : "ON");
-
-	if (disable_radio) {
-		iwl3945_scan_cancel(priv);
-		/* FIXME: This is a workaround for AP */
-		if (priv->iw_mode != NL80211_IFTYPE_AP) {
-			spin_lock_irqsave(&priv->lock, flags);
-			iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
-				    CSR_UCODE_SW_BIT_RFKILL);
-			spin_unlock_irqrestore(&priv->lock, flags);
-			iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
-			set_bit(STATUS_RF_KILL_SW, &priv->status);
-		}
-		return;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
-	clear_bit(STATUS_RF_KILL_SW, &priv->status);
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	/* wake up ucode */
-	msleep(10);
-
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-	if (!iwl3945_grab_nic_access(priv))
-		iwl3945_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-		IWL_DEBUG_RF_KILL("Can not turn radio back on - "
-				  "disabled by HW switch\n");
-		return;
-	}
-
-	if (priv->is_open)
-		queue_work(priv->workqueue, &priv->restart);
-	return;
-}
-
-void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
-			    u32 decrypt_res, struct ieee80211_rx_status *stats)
-{
-	u16 fc =
-	    le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
-
-	if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
-		return;
-
-	if (!(fc & IEEE80211_FCTL_PROTECTED))
-		return;
-
-	IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
-	switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
-	case RX_RES_STATUS_SEC_TYPE_TKIP:
-		if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
-		    RX_RES_STATUS_BAD_ICV_MIC)
-			stats->flag |= RX_FLAG_MMIC_ERROR;
-	case RX_RES_STATUS_SEC_TYPE_WEP:
-	case RX_RES_STATUS_SEC_TYPE_CCMP:
-		if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
-		    RX_RES_STATUS_DECRYPT_OK) {
-			IWL_DEBUG_RX("hw decrypt successfully!!!\n");
-			stats->flag |= RX_FLAG_DECRYPTED;
-		}
-		break;
-
-	default:
-		break;
-	}
-}
-
 #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 
 #include "iwl-spectrum.h"
@@ -2863,13 +1229,13 @@ static __le32 iwl3945_add_beacon_time(u3
 	return cpu_to_le32(res);
 }
 
-static int iwl3945_get_measurement(struct iwl3945_priv *priv,
+static int iwl3945_get_measurement(struct iwl_priv *priv,
 			       struct ieee80211_measurement_params *params,
 			       u8 type)
 {
-	struct iwl3945_spectrum_cmd spectrum;
-	struct iwl3945_rx_packet *res;
-	struct iwl3945_host_cmd cmd = {
+	struct iwl_spectrum_cmd spectrum;
+	struct iwl_rx_packet *res;
+	struct iwl_host_cmd cmd = {
 		.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
 		.data = (void *)&spectrum,
 		.meta.flags = CMD_WANT_SKB,
@@ -2879,7 +1245,7 @@ static int iwl3945_get_measurement(struc
 	int spectrum_resp_status;
 	int duration = le16_to_cpu(params->duration);
 
-	if (iwl3945_is_associated(priv))
+	if (iwl_is_associated(priv))
 		add_time =
 		    iwl3945_usecs_to_beacons(
 			le64_to_cpu(params->start_time) - priv->last_tsf,
@@ -2894,7 +1260,7 @@ static int iwl3945_get_measurement(struc
 	cmd.len = sizeof(spectrum);
 	spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
 
-	if (iwl3945_is_associated(priv))
+	if (iwl_is_associated(priv))
 		spectrum.start_time =
 		    iwl3945_add_beacon_time(priv->last_beacon_time,
 				add_time,
@@ -2909,13 +1275,13 @@ static int iwl3945_get_measurement(struc
 		spectrum.flags |= RXON_FLG_BAND_24G_MSK |
 		    RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
 
-	rc = iwl3945_send_cmd_sync(priv, &cmd);
+	rc = iwl_send_cmd_sync(priv, &cmd);
 	if (rc)
 		return rc;
 
-	res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
 		rc = -EIO;
 	}
 
@@ -2923,7 +1289,7 @@ static int iwl3945_get_measurement(struc
 	switch (spectrum_resp_status) {
 	case 0:		/* Command will be handled */
 		if (res->u.spectrum.id != 0xff) {
-			IWL_DEBUG_INFO("Replaced existing measurement: %d\n",
+			IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
 						res->u.spectrum.id);
 			priv->measurement_status &= ~MEASUREMENT_READY;
 		}
@@ -2942,30 +1308,29 @@ static int iwl3945_get_measurement(struc
 }
 #endif
 
-static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
-			       struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
+			       struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_alive_resp *palive;
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_alive_resp *palive;
 	struct delayed_work *pwork;
 
 	palive = &pkt->u.alive_frame;
 
-	IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
 		       "0x%01X 0x%01X\n",
 		       palive->is_valid, palive->ver_type,
 		       palive->ver_subtype);
 
 	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
-		IWL_DEBUG_INFO("Initialization Alive received.\n");
-		memcpy(&priv->card_alive_init,
-		       &pkt->u.alive_frame,
-		       sizeof(struct iwl3945_init_alive_resp));
+		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
+		memcpy(&priv->card_alive_init, &pkt->u.alive_frame,
+		       sizeof(struct iwl_alive_resp));
 		pwork = &priv->init_alive_start;
 	} else {
-		IWL_DEBUG_INFO("Runtime Alive received.\n");
+		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 		memcpy(&priv->card_alive, &pkt->u.alive_frame,
-		       sizeof(struct iwl3945_alive_resp));
+		       sizeof(struct iwl_alive_resp));
 		pwork = &priv->alive_start;
 		iwl3945_disable_events(priv);
 	}
@@ -2976,95 +1341,31 @@ static void iwl3945_rx_reply_alive(struc
 		queue_delayed_work(priv->workqueue, pwork,
 				   msecs_to_jiffies(5));
 	else
-		IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
-				 struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
-	IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
-	return;
-}
-
-static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
-			       struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
-	IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
-		"seq 0x%04X ser 0x%08X\n",
-		le32_to_cpu(pkt->u.err_resp.error_type),
-		get_cmd_string(pkt->u.err_resp.cmd_id),
-		pkt->u.err_resp.cmd_id,
-		le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
-		le32_to_cpu(pkt->u.err_resp.error_info));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
-	struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
-	IWL_DEBUG_11H("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;
-}
-
-static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
-					  struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
-
-	if (!report->state) {
-		IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
-			  "Spectrum Measure Notification: Start\n");
-		return;
-	}
-
-	memcpy(&priv->measure_report, report, sizeof(*report));
-	priv->measurement_status |= MEASUREMENT_READY;
-#endif
+		IWL_WARN(priv, "uCode did not respond OK.\n");
 }
 
-static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
-				  struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
+				 struct iwl_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWL3945_DEBUG
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
-	IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
-		     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#ifdef CONFIG_IWLWIFI_DEBUG
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 #endif
-}
 
-static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
-					     struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
-			"notification for %s:\n",
-			le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-	iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+	IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
+	return;
 }
 
 static void iwl3945_bg_beacon_update(struct work_struct *work)
 {
-	struct iwl3945_priv *priv =
-		container_of(work, struct iwl3945_priv, beacon_update);
+	struct iwl_priv *priv =
+		container_of(work, struct iwl_priv, beacon_update);
 	struct sk_buff *beacon;
 
 	/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
 	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
 
 	if (!beacon) {
-		IWL_ERROR("update beacon failed\n");
+		IWL_ERR(priv, "update beacon failed\n");
 		return;
 	}
 
@@ -3079,15 +1380,15 @@ static void iwl3945_bg_beacon_update(str
 	iwl3945_send_beacon_cmd(priv);
 }
 
-static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
-				struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
+				struct iwl_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWL3945_DEBUG
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_DEBUG
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
 	u8 rate = beacon->beacon_notify_hdr.rate;
 
-	IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
 		"tsf %d %d rate %d\n",
 		le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
 		beacon->beacon_notify_hdr.failure_frame,
@@ -3101,137 +1402,20 @@ static void iwl3945_rx_beacon_notif(stru
 		queue_work(priv->workqueue, &priv->beacon_update);
 }
 
-/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
-			      struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_DEBUG
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_scanreq_notification *notif =
-	    (struct iwl3945_scanreq_notification *)pkt->u.raw;
-
-	IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
-#endif
-}
-
-/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
-				    struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_scanstart_notification *notif =
-	    (struct iwl3945_scanstart_notification *)pkt->u.raw;
-	priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
-	IWL_DEBUG_SCAN("Scan start: "
-		       "%d [802.11%s] "
-		       "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
-		       notif->channel,
-		       notif->band ? "bg" : "a",
-		       notif->tsf_high,
-		       notif->tsf_low, notif->status, notif->beacon_timer);
-}
-
-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
-				      struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_scanresults_notification *notif =
-	    (struct iwl3945_scanresults_notification *)pkt->u.raw;
-
-	IWL_DEBUG_SCAN("Scan ch.res: "
-		       "%d [802.11%s] "
-		       "(TSF: 0x%08X:%08X) - %d "
-		       "elapsed=%lu usec (%dms since last)\n",
-		       notif->channel,
-		       notif->band ? "bg" : "a",
-		       le32_to_cpu(notif->tsf_high),
-		       le32_to_cpu(notif->tsf_low),
-		       le32_to_cpu(notif->statistics[0]),
-		       le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
-		       jiffies_to_msecs(elapsed_jiffies
-					(priv->last_scan_jiffies, jiffies)));
-
-	priv->last_scan_jiffies = jiffies;
-	priv->next_scan_jiffies = 0;
-}
-
-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
-				       struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
-
-	IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
-		       scan_notif->scanned_channels,
-		       scan_notif->tsf_low,
-		       scan_notif->tsf_high, scan_notif->status);
-
-	/* The HW is no longer scanning */
-	clear_bit(STATUS_SCAN_HW, &priv->status);
-
-	/* The scan completion notification came in, so kill that timer... */
-	cancel_delayed_work(&priv->scan_check);
-
-	IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
-		       (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
-							"2.4" : "5.2",
-		       jiffies_to_msecs(elapsed_jiffies
-					(priv->scan_pass_start, jiffies)));
-
-	/* Remove this scanned band from the list of pending
-	 * bands to scan, band G precedes A in order of scanning
-	 * as seen in iwl3945_bg_request_scan */
-	if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
-		priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
-	else if (priv->scan_bands &  BIT(IEEE80211_BAND_5GHZ))
-		priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
-
-	/* If a request to abort was given, or the scan did not succeed
-	 * then we reset the scan state machine and terminate,
-	 * re-queuing another scan if one has been requested */
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_INFO("Aborted scan completed.\n");
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-	} else {
-		/* If there are more bands on this scan pass reschedule */
-		if (priv->scan_bands > 0)
-			goto reschedule;
-	}
-
-	priv->last_scan_jiffies = jiffies;
-	priv->next_scan_jiffies = 0;
-	IWL_DEBUG_INFO("Setting scan to off\n");
-
-	clear_bit(STATUS_SCANNING, &priv->status);
-
-	IWL_DEBUG_INFO("Scan took %dms\n",
-		jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
-	queue_work(priv->workqueue, &priv->scan_completed);
-
-	return;
-
-reschedule:
-	priv->scan_pass_start = jiffies;
-	queue_work(priv->workqueue, &priv->request_scan);
-}
-
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
-static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
-				    struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
+				    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
 
-	IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
 			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
 			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");
 
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
 	if (flags & HW_CARD_DISABLED)
@@ -3245,7 +1429,7 @@ static void iwl3945_rx_card_state_notif(
 	else
 		clear_bit(STATUS_RF_KILL_SW, &priv->status);
 
-	iwl3945_scan_cancel(priv);
+	iwl_scan_cancel(priv);
 
 	if ((test_bit(STATUS_RF_KILL_HW, &status) !=
 	     test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3265,17 +1449,15 @@ static void iwl3945_rx_card_state_notif(
  * This function chains into the hardware specific files for them to setup
  * any hardware specific handlers as well.
  */
-static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
+static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
 {
 	priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
 	priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
-	priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error;
-	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa;
-	priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-	    iwl3945_rx_spectrum_measure_notif;
-	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif;
+	priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
+	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
 	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
-	    iwl3945_rx_pm_debug_statistics_notif;
+	    iwl_rx_pm_debug_statistics_notif;
 	priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
 
 	/*
@@ -3286,90 +1468,14 @@ static void iwl3945_setup_rx_handlers(st
 	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
 	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
 
-	priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan;
-	priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif;
-	priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
-	    iwl3945_rx_scan_results_notif;
-	priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
-	    iwl3945_rx_scan_complete_notif;
+	iwl_setup_spectrum_handlers(priv);
+	iwl_setup_rx_scan_handlers(priv);
 	priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
 
 	/* Set up hardware specific Rx handlers */
 	iwl3945_hw_rx_handler_setup(priv);
 }
 
-/**
- * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
- * When FW advances 'R' index, all entries between old and new 'R' index
- * need to be reclaimed.
- */
-static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
-				      int txq_id, int index)
-{
-	struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
-	struct iwl3945_queue *q = &txq->q;
-	int nfreed = 0;
-
-	if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
-			  "is out of range [0-%d] %d %d.\n", txq_id,
-			  index, q->n_bd, q->write_ptr, q->read_ptr);
-		return;
-	}
-
-	for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
-		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
-		if (nfreed > 1) {
-			IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
-					q->write_ptr, q->read_ptr);
-			queue_work(priv->workqueue, &priv->restart);
-			break;
-		}
-		nfreed++;
-	}
-}
-
-
-/**
- * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
- * @rxb: Rx buffer to reclaim
- *
- * If an Rx buffer has an async callback associated with it the callback
- * will be executed.  The attached skb (if present) will only be freed
- * if the callback returns 1
- */
-static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
-				struct iwl3945_rx_mem_buffer *rxb)
-{
-	struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
-	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
-	int txq_id = SEQ_TO_QUEUE(sequence);
-	int index = SEQ_TO_INDEX(sequence);
-	int huge = sequence & SEQ_HUGE_FRAME;
-	int cmd_index;
-	struct iwl3945_cmd *cmd;
-
-	BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
-
-	cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-	cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-
-	/* Input error checking is done when commands are added to queue. */
-	if (cmd->meta.flags & CMD_WANT_SKB) {
-		cmd->meta.source->u.skb = rxb->skb;
-		rxb->skb = NULL;
-	} else if (cmd->meta.u.callback &&
-		   !cmd->meta.u.callback(priv, cmd, rxb->skb))
-		rxb->skb = NULL;
-
-	iwl3945_cmd_queue_reclaim(priv, txq_id, index);
-
-	if (!(cmd->meta.flags & CMD_ASYNC)) {
-		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-		wake_up_interruptible(&priv->wait_command_queue);
-	}
-}
-
 /************************** RX-FUNCTIONS ****************************/
 /*
  * Rx theory of operation
@@ -3417,7 +1523,6 @@ static void iwl3945_tx_cmd_complete(stru
  *
  * Driver sequence:
  *
- * iwl3945_rx_queue_alloc()   Allocates rx_free
  * iwl3945_rx_replenish()     Replenishes rx_free list from rx_used, and calls
  *                            iwl3945_rx_queue_restock
  * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
@@ -3426,7 +1531,7 @@ static void iwl3945_tx_cmd_complete(stru
  *                            are available, schedules iwl3945_rx_replenish
  *
  * -- enable interrupts --
- * ISR - iwl3945_rx()         Detach iwl3945_rx_mem_buffers from pool up to the
+ * ISR - iwl3945_rx()         Detach iwl_rx_mem_buffers from pool up to the
  *                            READ INDEX, detaching the SKB from the pool.
  *                            Moves the packet buffer from queue to rx_used.
  *                            Calls iwl3945_rx_queue_restock to refill any empty
@@ -3436,70 +1541,9 @@ static void iwl3945_tx_cmd_complete(stru
  */
 
 /**
- * iwl3945_rx_queue_space - Return number of free slots available in queue.
- */
-static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
-{
-	int s = q->read - q->write;
-	if (s <= 0)
-		s += RX_QUEUE_SIZE;
-	/* keep some buffer to not confuse full and empty queue */
-	s -= 2;
-	if (s < 0)
-		s = 0;
-	return s;
-}
-
-/**
- * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
-{
-	u32 reg = 0;
-	int rc = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&q->lock, flags);
-
-	if (q->need_update == 0)
-		goto exit_unlock;
-
-	/* If power-saving is in use, make sure device is awake */
-	if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-		reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
-		if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-			iwl3945_set_bit(priv, CSR_GP_CNTRL,
-				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-			goto exit_unlock;
-		}
-
-		rc = iwl3945_grab_nic_access(priv);
-		if (rc)
-			goto exit_unlock;
-
-		/* Device expects a multiple of 8 */
-		iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
-				     q->write & ~0x7);
-		iwl3945_release_nic_access(priv);
-
-	/* Else device is assumed to be awake */
-	} else
-		/* Device expects a multiple of 8 */
-		iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
-
-	q->need_update = 0;
-
- exit_unlock:
-	spin_unlock_irqrestore(&q->lock, flags);
-	return rc;
-}
-
-/**
  * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
  */
-static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
+static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
 					  dma_addr_t dma_addr)
 {
 	return cpu_to_le32((u32)dma_addr);
@@ -3516,24 +1560,24 @@ static inline __le32 iwl3945_dma_addr2rb
  * also updates the memory address in the firmware to reference the new
  * target buffer.
  */
-static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
+static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
 {
-	struct iwl3945_rx_queue *rxq = &priv->rxq;
+	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
-	struct iwl3945_rx_mem_buffer *rxb;
+	struct iwl_rx_mem_buffer *rxb;
 	unsigned long flags;
 	int write, rc;
 
 	spin_lock_irqsave(&rxq->lock, flags);
 	write = rxq->write & ~0x7;
-	while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+	while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
 		/* Get next free Rx buffer, remove from free list */
 		element = rxq->rx_free.next;
-		rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
 		list_del(element);
 
 		/* Point to Rx buffer via next RBD in circular buffer */
-		rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+		rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
 		rxq->queue[rxq->write] = rxb;
 		rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
 		rxq->free_count--;
@@ -3552,7 +1596,7 @@ static int iwl3945_rx_queue_restock(stru
 		spin_lock_irqsave(&rxq->lock, flags);
 		rxq->need_update = 1;
 		spin_unlock_irqrestore(&rxq->lock, flags);
-		rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
+		rc = iwl_rx_queue_update_write_ptr(priv, rxq);
 		if (rc)
 			return rc;
 	}
@@ -3568,24 +1612,24 @@ static int iwl3945_rx_queue_restock(stru
  * Also restock the Rx queue via iwl3945_rx_queue_restock.
  * This is called as a scheduled work item (except for during initialization)
  */
-static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv)
 {
-	struct iwl3945_rx_queue *rxq = &priv->rxq;
+	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
-	struct iwl3945_rx_mem_buffer *rxb;
+	struct iwl_rx_mem_buffer *rxb;
 	unsigned long flags;
 	spin_lock_irqsave(&rxq->lock, flags);
 	while (!list_empty(&rxq->rx_used)) {
 		element = rxq->rx_used.next;
-		rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
 
 		/* Alloc a new receive buffer */
 		rxb->skb =
-		    alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
+		    alloc_skb(priv->hw_params.rx_buf_size,
+				__GFP_NOWARN | GFP_ATOMIC);
 		if (!rxb->skb) {
 			if (net_ratelimit())
-				printk(KERN_CRIT DRV_NAME
-				       ": Can not allocate SKB buffers\n");
+				IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
 			 * more buffers it will schedule replenish */
@@ -3604,21 +1648,52 @@ static void iwl3945_rx_allocate(struct i
 		list_del(element);
 
 		/* Get physical address of RB/SKB */
-		rxb->dma_addr =
-		    pci_map_single(priv->pci_dev, rxb->skb->data,
-				   IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+		rxb->real_dma_addr = pci_map_single(priv->pci_dev,
+						rxb->skb->data,
+						priv->hw_params.rx_buf_size,
+						PCI_DMA_FROMDEVICE);
 		list_add_tail(&rxb->list, &rxq->rx_free);
 		rxq->free_count++;
 	}
 	spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
+void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+	unsigned long flags;
+	int i;
+	spin_lock_irqsave(&rxq->lock, flags);
+	INIT_LIST_HEAD(&rxq->rx_free);
+	INIT_LIST_HEAD(&rxq->rx_used);
+	/* Fill the rx_used queue with _all_ of the Rx buffers */
+	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;
+		}
+		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+	}
+
+	/* 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;
+	spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
 /*
  * this should be called while priv->lock is locked
  */
 static void __iwl3945_rx_replenish(void *data)
 {
-	struct iwl3945_priv *priv = data;
+	struct iwl_priv *priv = data;
 
 	iwl3945_rx_allocate(priv);
 	iwl3945_rx_queue_restock(priv);
@@ -3627,7 +1702,7 @@ static void __iwl3945_rx_replenish(void
 
 void iwl3945_rx_replenish(void *data)
 {
-	struct iwl3945_priv *priv = data;
+	struct iwl_priv *priv = data;
 	unsigned long flags;
 
 	iwl3945_rx_allocate(priv);
@@ -3642,78 +1717,27 @@ void iwl3945_rx_replenish(void *data)
  * This free routine walks the list of POOL entries and if SKB is set to
  * non NULL it is unmapped and freed
  */
-static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
+static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
 	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].dma_addr,
-					 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+					 rxq->pool[i].real_dma_addr,
+					 priv->hw_params.rx_buf_size,
+					 PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(rxq->pool[i].skb);
 		}
 	}
 
 	pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
 			    rxq->dma_addr);
+	pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
+			    rxq->rb_stts, rxq->rb_stts_dma);
 	rxq->bd = NULL;
+	rxq->rb_stts  = NULL;
 }
 
-int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
-{
-	struct iwl3945_rx_queue *rxq = &priv->rxq;
-	struct pci_dev *dev = priv->pci_dev;
-	int i;
-
-	spin_lock_init(&rxq->lock);
-	INIT_LIST_HEAD(&rxq->rx_free);
-	INIT_LIST_HEAD(&rxq->rx_used);
-
-	/* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
-	rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
-	if (!rxq->bd)
-		return -ENOMEM;
-
-	/* Fill the rx_used queue with _all_ of the Rx buffers */
-	for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
-		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-
-	/* 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->need_update = 0;
-	return 0;
-}
-
-void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
-	unsigned long flags;
-	int i;
-	spin_lock_irqsave(&rxq->lock, flags);
-	INIT_LIST_HEAD(&rxq->rx_free);
-	INIT_LIST_HEAD(&rxq->rx_used);
-	/* Fill the rx_used queue with _all_ of the Rx buffers */
-	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].dma_addr,
-					 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-			priv->alloc_rxb_skb--;
-			dev_kfree_skb(rxq->pool[i].skb);
-			rxq->pool[i].skb = NULL;
-		}
-		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-	}
-
-	/* 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;
-	spin_unlock_irqrestore(&rxq->lock, flags);
-}
 
 /* Convert linear signal-to-noise ratio into dB */
 static u8 ratio2dB[100] = {
@@ -3800,11 +1824,11 @@ int iwl3945_calc_sig_qual(int rssi_dbm,
  * the appropriate handlers, including command responses,
  * frame-received notifications, and other notifications.
  */
-static void iwl3945_rx_handle(struct iwl3945_priv *priv)
+static void iwl3945_rx_handle(struct iwl_priv *priv)
 {
-	struct iwl3945_rx_mem_buffer *rxb;
-	struct iwl3945_rx_packet *pkt;
-	struct iwl3945_rx_queue *rxq = &priv->rxq;
+	struct iwl_rx_mem_buffer *rxb;
+	struct iwl_rx_packet *pkt;
+	struct iwl_rx_queue *rxq = &priv->rxq;
 	u32 r, i;
 	int reclaim;
 	unsigned long flags;
@@ -3813,14 +1837,14 @@ static void iwl3945_rx_handle(struct iwl
 
 	/* uCode's read index (stored in shared DRAM) indicates the last Rx
 	 * buffer that the driver may process (last buffer filled by ucode). */
-	r = iwl3945_hw_get_rx_read(priv);
+	r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
 	i = rxq->read;
 
-	if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+	if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
 		fill_rx = 1;
 	/* Rx interrupt, but nothing sent from uCode */
 	if (i == r)
-		IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
+		IWL_DEBUG(priv, IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
 
 	while (i != r) {
 		rxb = rxq->queue[i];
@@ -3832,10 +1856,10 @@ static void iwl3945_rx_handle(struct iwl
 
 		rxq->queue[i] = NULL;
 
-		pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
-					    IWL_RX_BUF_SIZE,
-					    PCI_DMA_FROMDEVICE);
-		pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+		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;
 
 		/* Reclaim a command buffer only if this packet is a response
 		 *   to a (driver-originated) command.
@@ -3851,13 +1875,13 @@ static void iwl3945_rx_handle(struct iwl
 		 *   handle those that need handling via function in
 		 *   rx_handlers table.  See iwl3945_setup_rx_handlers() */
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
-			IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+			IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
 				"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);
 		} else {
 			/* No handling needed */
-			IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+			IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
 				"r %d i %d No handler needed for %s, 0x%02x\n",
 				r, i, get_cmd_string(pkt->hdr.cmd),
 				pkt->hdr.cmd);
@@ -3865,12 +1889,12 @@ static void iwl3945_rx_handle(struct iwl
 
 		if (reclaim) {
 			/* Invoke any callbacks, transfer the skb to caller, and
-			 * fire off the (possibly) blocking iwl3945_send_cmd()
+			 * fire off the (possibly) blocking iwl_send_cmd()
 			 * as we reclaim the driver command queue */
 			if (rxb && rxb->skb)
-				iwl3945_tx_cmd_complete(priv, rxb);
+				iwl_tx_cmd_complete(priv, rxb);
 			else
-				IWL_WARNING("Claim null rxb?\n");
+				IWL_WARN(priv, "Claim null rxb?\n");
 		}
 
 		/* For now we just don't re-use anything.  We can tweak this
@@ -3882,8 +1906,6 @@ static void iwl3945_rx_handle(struct iwl
 			rxb->skb = NULL;
 		}
 
-		pci_unmap_single(priv->pci_dev, rxb->dma_addr,
-				 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 		spin_lock_irqsave(&rxq->lock, flags);
 		list_add_tail(&rxb->list, &priv->rxq.rx_used);
 		spin_unlock_irqrestore(&rxq->lock, flags);
@@ -3905,102 +1927,14 @@ static void iwl3945_rx_handle(struct iwl
 	iwl3945_rx_queue_restock(priv);
 }
 
-/**
- * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
- */
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
-				  struct iwl3945_tx_queue *txq)
-{
-	u32 reg = 0;
-	int rc = 0;
-	int txq_id = txq->q.id;
-
-	if (txq->need_update == 0)
-		return rc;
-
-	/* if we're trying to save power */
-	if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-		/* wake up nic if it's powered down ...
-		 * uCode will wake up, and interrupt us again, so next
-		 * time we'll skip this part. */
-		reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
-		if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-			IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
-			iwl3945_set_bit(priv, CSR_GP_CNTRL,
-				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-			return rc;
-		}
-
-		/* restore this queue's parameters in nic hardware. */
-		rc = iwl3945_grab_nic_access(priv);
-		if (rc)
-			return rc;
-		iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
-				     txq->q.write_ptr | (txq_id << 8));
-		iwl3945_release_nic_access(priv);
-
-	/* else not in power-save mode, uCode will never sleep when we're
-	 * trying to tx (during RFKILL, we're not trying to tx). */
-	} else
-		iwl3945_write32(priv, HBUS_TARG_WRPTR,
-			    txq->q.write_ptr | (txq_id << 8));
-
-	txq->need_update = 0;
-
-	return rc;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
-{
-	IWL_DEBUG_RADIO("RX CONFIG:\n");
-	iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
-	IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
-	IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
-	IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
-			le32_to_cpu(rxon->filter_flags));
-	IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
-	IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
-			rxon->ofdm_basic_rates);
-	IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
-	IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
-	IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
-	IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
-static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
-{
-	IWL_DEBUG_ISR("Enabling interrupts\n");
-	set_bit(STATUS_INT_ENABLED, &priv->status);
-	iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
-}
-
-
 /* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
 {
 	/* wait to make sure we flush pending tasklet*/
 	synchronize_irq(priv->pci_dev->irq);
 	tasklet_kill(&priv->irq_tasklet);
 }
 
-
-static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
-{
-	clear_bit(STATUS_INT_ENABLED, &priv->status);
-
-	/* disable interrupts from uCode/NIC to host */
-	iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
-	/* acknowledge/clear/reset any interrupts still pending
-	 * from uCode or flow handler (Rx/Tx DMA) */
-	iwl3945_write32(priv, CSR_INT, 0xffffffff);
-	iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
-	IWL_DEBUG_ISR("Disabled interrupts\n");
-}
-
 static const char *desc_lookup(int i)
 {
 	switch (i) {
@@ -4024,7 +1958,7 @@ static const char *desc_lookup(int i)
 #define ERROR_START_OFFSET  (1 * sizeof(u32))
 #define ERROR_ELEM_SIZE     (7 * sizeof(u32))
 
-static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
 {
 	u32 i;
 	u32 desc, time, count, base, data1;
@@ -4034,49 +1968,50 @@ static void iwl3945_dump_nic_error_log(s
 	base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
 	if (!iwl3945_hw_valid_rtc_data_addr(base)) {
-		IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+		IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
 		return;
 	}
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
-		IWL_WARNING("Can not read from adapter at this time.\n");
+		IWL_WARN(priv, "Can not read from adapter at this time.\n");
 		return;
 	}
 
-	count = iwl3945_read_targ_mem(priv, base);
+	count = iwl_read_targ_mem(priv, base);
 
 	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
-		IWL_ERROR("Start IWL Error Log Dump:\n");
-		IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+		IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+		IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+			priv->status, count);
 	}
 
-	IWL_ERROR("Desc       Time       asrtPC  blink2 "
+	IWL_ERR(priv, "Desc       Time       asrtPC  blink2 "
 		  "ilink1  nmiPC   Line\n");
 	for (i = ERROR_START_OFFSET;
 	     i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
 	     i += ERROR_ELEM_SIZE) {
-		desc = iwl3945_read_targ_mem(priv, base + i);
+		desc = iwl_read_targ_mem(priv, base + i);
 		time =
-		    iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32));
 		blink1 =
-		    iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32));
 		blink2 =
-		    iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32));
 		ilink1 =
-		    iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32));
 		ilink2 =
-		    iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32));
 		data1 =
-		    iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
+		    iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32));
 
-		IWL_ERROR
-		    ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
-		     desc_lookup(desc), desc, time, blink1, blink2,
-		     ilink1, ilink2, data1);
+		IWL_ERR(priv,
+			"%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
+			desc_lookup(desc), desc, time, blink1, blink2,
+			ilink1, ilink2, data1);
 	}
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 
 }
 
@@ -4085,9 +2020,9 @@ static void iwl3945_dump_nic_error_log(s
 /**
  * iwl3945_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl3945_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
  */
-static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
+static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
 				u32 num_events, u32 mode)
 {
 	u32 i;
@@ -4111,21 +2046,22 @@ static void iwl3945_print_event_log(stru
 	/* "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 = iwl3945_read_targ_mem(priv, ptr);
+		ev = iwl_read_targ_mem(priv, ptr);
 		ptr += sizeof(u32);
-		time = iwl3945_read_targ_mem(priv, ptr);
+		time = iwl_read_targ_mem(priv, ptr);
 		ptr += sizeof(u32);
-		if (mode == 0)
-			IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
-		else {
-			data = iwl3945_read_targ_mem(priv, ptr);
+		if (mode == 0) {
+			/* data, ev */
+			IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+		} else {
+			data = iwl_read_targ_mem(priv, ptr);
 			ptr += sizeof(u32);
-			IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
+			IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
 		}
 	}
 }
 
-static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
 {
 	int rc;
 	u32 base;       /* SRAM byte address of event log header */
@@ -4137,32 +2073,32 @@ static void iwl3945_dump_nic_event_log(s
 
 	base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 	if (!iwl3945_hw_valid_rtc_data_addr(base)) {
-		IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
 		return;
 	}
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
-		IWL_WARNING("Can not read from adapter at this time.\n");
+		IWL_WARN(priv, "Can not read from adapter at this time.\n");
 		return;
 	}
 
 	/* event log header */
-	capacity = iwl3945_read_targ_mem(priv, base);
-	mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
-	num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
-	next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32)));
+	capacity = iwl_read_targ_mem(priv, base);
+	mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+	num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+	next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
 	size = num_wraps ? capacity : next_entry;
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
-		iwl3945_release_nic_access(priv);
+		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+		iwl_release_nic_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+	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,
@@ -4174,48 +2110,10 @@ static void iwl3945_dump_nic_event_log(s
 	/* (then/else) start at top of log */
 	iwl3945_print_event_log(priv, 0, next_entry, mode);
 
-	iwl3945_release_nic_access(priv);
-}
-
-/**
- * iwl3945_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
-{
-	/* Set the FW error flag -- cleared on iwl3945_down */
-	set_bit(STATUS_FW_ERROR, &priv->status);
-
-	/* Cancel currently queued command. */
-	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWL3945_DEBUG
-	if (iwl3945_debug_level & IWL_DL_FW_ERRORS) {
-		iwl3945_dump_nic_error_log(priv);
-		iwl3945_dump_nic_event_log(priv);
-		iwl3945_print_rx_config_cmd(&priv->staging_rxon);
-	}
-#endif
-
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	/* Keep the restart process from trying to send host
-	 * commands by clearing the INIT status bit */
-	clear_bit(STATUS_READY, &priv->status);
-
-	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
-			  "Restarting adapter due to uCode error.\n");
-
-		if (iwl3945_is_associated(priv)) {
-			memcpy(&priv->recovery_rxon, &priv->active_rxon,
-			       sizeof(priv->recovery_rxon));
-			priv->error_recovering = 1;
-		}
-		queue_work(priv->workqueue, &priv->restart);
-	}
+	iwl_release_nic_access(priv);
 }
 
-static void iwl3945_error_recovery(struct iwl3945_priv *priv)
+static void iwl3945_error_recovery(struct iwl_priv *priv)
 {
 	unsigned long flags;
 
@@ -4232,12 +2130,12 @@ static void iwl3945_error_recovery(struc
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
+static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 {
 	u32 inta, handled = 0;
 	u32 inta_fh;
 	unsigned long flags;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 	u32 inta_mask;
 #endif
 
@@ -4246,20 +2144,20 @@ static void iwl3945_irq_tasklet(struct i
 	/* Ack/clear/reset pending uCode interrupts.
 	 * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
 	 *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
-	inta = iwl3945_read32(priv, CSR_INT);
-	iwl3945_write32(priv, CSR_INT, inta);
+	inta = iwl_read32(priv, CSR_INT);
+	iwl_write32(priv, CSR_INT, inta);
 
 	/* Ack/clear/reset pending flow-handler (DMA) interrupts.
 	 * Any new interrupts that happen after this, either while we're
 	 * in this tasklet, or later, will show up in next ISR/tasklet. */
-	inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
-	iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
-#ifdef CONFIG_IWL3945_DEBUG
-	if (iwl3945_debug_level & IWL_DL_ISR) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (priv->debug_level & IWL_DL_ISR) {
 		/* just for debug */
-		inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
-		IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+		inta_mask = iwl_read32(priv, CSR_INT_MASK);
+		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
 			      inta, inta_mask, inta_fh);
 	}
 #endif
@@ -4275,12 +2173,12 @@ static void iwl3945_irq_tasklet(struct i
 
 	/* Now service all interrupt bits discovered above. */
 	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERROR("Microcode HW error detected.  Restarting.\n");
+		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
 
 		/* Tell the device to stop sending interrupts */
-		iwl3945_disable_interrupts(priv);
+		iwl_disable_interrupts(priv);
 
-		iwl3945_irq_handle_error(priv);
+		iwl_irq_handle_error(priv);
 
 		handled |= CSR_INT_BIT_HW_ERR;
 
@@ -4289,16 +2187,16 @@ static void iwl3945_irq_tasklet(struct i
 		return;
 	}
 
-#ifdef CONFIG_IWL3945_DEBUG
-	if (iwl3945_debug_level & (IWL_DL_ISR)) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (priv->debug_level & (IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD)
-			IWL_DEBUG_ISR("Scheduler finished to transmit "
+			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
 				      "the frame/frames.\n");
 
 		/* Alive notification via Rx interrupt will do the real work */
 		if (inta & CSR_INT_BIT_ALIVE)
-			IWL_DEBUG_ISR("Alive interrupt\n");
+			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
 	}
 #endif
 	/* Safely ignore these bits for debug checks below */
@@ -4306,22 +2204,22 @@ static void iwl3945_irq_tasklet(struct i
 
 	/* Error detected by uCode */
 	if (inta & CSR_INT_BIT_SW_ERR) {
-		IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
-			  inta);
-		iwl3945_irq_handle_error(priv);
+		IWL_ERR(priv, "Microcode SW error detected. "
+			"Restarting 0x%X.\n", inta);
+		iwl_irq_handle_error(priv);
 		handled |= CSR_INT_BIT_SW_ERR;
 	}
 
 	/* uCode wakes up after power-down sleep */
 	if (inta & CSR_INT_BIT_WAKEUP) {
-		IWL_DEBUG_ISR("Wakeup interrupt\n");
-		iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
-		iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+		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]);
 
 		handled |= CSR_INT_BIT_WAKEUP;
 	}
@@ -4335,432 +2233,63 @@ static void iwl3945_irq_tasklet(struct i
 	}
 
 	if (inta & CSR_INT_BIT_FH_TX) {
-		IWL_DEBUG_ISR("Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
 
-		iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
-		if (!iwl3945_grab_nic_access(priv)) {
-			iwl3945_write_direct32(priv,
-					     FH_TCSR_CREDIT
-					     (ALM_FH_SRVC_CHNL), 0x0);
-			iwl3945_release_nic_access(priv);
+		iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
+		if (!iwl_grab_nic_access(priv)) {
+			iwl_write_direct32(priv, FH39_TCSR_CREDIT
+					     (FH39_SRVC_CHNL), 0x0);
+			iwl_release_nic_access(priv);
 		}
 		handled |= CSR_INT_BIT_FH_TX;
 	}
 
 	if (inta & ~handled)
-		IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+		IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
 
 	if (inta & ~CSR_INI_SET_MASK) {
-		IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+		IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
 			 inta & ~CSR_INI_SET_MASK);
-		IWL_WARNING("   with FH_INT = 0x%08x\n", inta_fh);
+		IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
 	}
 
 	/* Re-enable all interrupts */
 	/* only Re-enable if disabled by irq */
 	if (test_bit(STATUS_INT_ENABLED, &priv->status))
-		iwl3945_enable_interrupts(priv);
+		iwl_enable_interrupts(priv);
 
-#ifdef CONFIG_IWL3945_DEBUG
-	if (iwl3945_debug_level & (IWL_DL_ISR)) {
-		inta = iwl3945_read32(priv, CSR_INT);
-		inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
-		inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
-		IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (priv->debug_level & (IWL_DL_ISR)) {
+		inta = iwl_read32(priv, CSR_INT);
+		inta_mask = iwl_read32(priv, CSR_INT_MASK);
+		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+		IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
 			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
 	}
 #endif
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static irqreturn_t iwl3945_isr(int irq, void *data)
-{
-	struct iwl3945_priv *priv = data;
-	u32 inta, inta_mask;
-	u32 inta_fh;
-	if (!priv)
-		return IRQ_NONE;
-
-	spin_lock(&priv->lock);
-
-	/* Disable (but don't clear!) interrupts here to avoid
-	 *    back-to-back ISRs and sporadic interrupts from our NIC.
-	 * If we have something to service, the tasklet will re-enable ints.
-	 * If we *don't* have something, we'll re-enable before leaving here. */
-	inta_mask = iwl3945_read32(priv, CSR_INT_MASK);  /* just for debug */
-	iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
-	/* Discover which interrupts are active/pending */
-	inta = iwl3945_read32(priv, CSR_INT);
-	inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
-
-	/* Ignore interrupt if there's nothing in NIC to service.
-	 * This may be due to IRQ shared with another device,
-	 * or due to sporadic interrupts thrown from our NIC. */
-	if (!inta && !inta_fh) {
-		IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
-		goto none;
-	}
-
-	if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
-		/* Hardware disappeared */
-		IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
-		goto unplugged;
-	}
-
-	IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
-		      inta, inta_mask, inta_fh);
-
-	inta &= ~CSR_INT_BIT_SCD;
-
-	/* iwl3945_irq_tasklet() will service interrupts and re-enable them */
-	if (likely(inta || inta_fh))
-		tasklet_schedule(&priv->irq_tasklet);
-unplugged:
-	spin_unlock(&priv->lock);
-
-	return IRQ_HANDLED;
-
- none:
-	/* re-enable interrupts here since we don't have anything to service. */
-	/* only Re-enable if disabled by irq */
-	if (test_bit(STATUS_INT_ENABLED, &priv->status))
-		iwl3945_enable_interrupts(priv);
-	spin_unlock(&priv->lock);
-	return IRQ_NONE;
-}
-
-/************************** EEPROM BANDS ****************************
- *
- * The iwl3945_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel.  We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware.  This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel.  There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/* 2.4 GHz */
-static const u8 iwl3945_eeprom_band_1[14] = {
-	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-};
-
-/* 5.2 GHz bands */
-static const u8 iwl3945_eeprom_band_2[] = {	/* 4915-5080MHz */
-	183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
-};
-
-static const u8 iwl3945_eeprom_band_3[] = {	/* 5170-5320MHz */
-	34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
-};
-
-static const u8 iwl3945_eeprom_band_4[] = {	/* 5500-5700MHz */
-	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-};
-
-static const u8 iwl3945_eeprom_band_5[] = {	/* 5725-5825MHz */
-	145, 149, 153, 157, 161, 165
-};
-
-static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band,
-				    int *eeprom_ch_count,
-				    const struct iwl3945_eeprom_channel
-				    **eeprom_ch_info,
-				    const u8 **eeprom_ch_index)
-{
-	switch (band) {
-	case 1:		/* 2.4GHz band */
-		*eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
-		*eeprom_ch_info = priv->eeprom.band_1_channels;
-		*eeprom_ch_index = iwl3945_eeprom_band_1;
-		break;
-	case 2:		/* 4.9GHz band */
-		*eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
-		*eeprom_ch_info = priv->eeprom.band_2_channels;
-		*eeprom_ch_index = iwl3945_eeprom_band_2;
-		break;
-	case 3:		/* 5.2GHz band */
-		*eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
-		*eeprom_ch_info = priv->eeprom.band_3_channels;
-		*eeprom_ch_index = iwl3945_eeprom_band_3;
-		break;
-	case 4:		/* 5.5GHz band */
-		*eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
-		*eeprom_ch_info = priv->eeprom.band_4_channels;
-		*eeprom_ch_index = iwl3945_eeprom_band_4;
-		break;
-	case 5:		/* 5.7GHz band */
-		*eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
-		*eeprom_ch_info = priv->eeprom.band_5_channels;
-		*eeprom_ch_index = iwl3945_eeprom_band_5;
-		break;
-	default:
-		BUG();
-		return;
-	}
-}
-
-/**
- * iwl3945_get_channel_info - Find driver's private channel info
- *
- * Based on band and channel number.
- */
-const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
-						    enum ieee80211_band band, u16 channel)
-{
-	int i;
-
-	switch (band) {
-	case IEEE80211_BAND_5GHZ:
-		for (i = 14; i < priv->channel_count; i++) {
-			if (priv->channel_info[i].channel == channel)
-				return &priv->channel_info[i];
-		}
-		break;
-
-	case IEEE80211_BAND_2GHZ:
-		if (channel >= 1 && channel <= 14)
-			return &priv->channel_info[channel - 1];
-		break;
-	case IEEE80211_NUM_BANDS:
-		WARN_ON(1);
-	}
-
-	return NULL;
-}
-
-#define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
-			    ? # x " " : "")
-
-/**
- * iwl3945_init_channel_map - Set up driver's info for all possible channels
- */
-static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
-{
-	int eeprom_ch_count = 0;
-	const u8 *eeprom_ch_index = NULL;
-	const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL;
-	int band, ch;
-	struct iwl3945_channel_info *ch_info;
-
-	if (priv->channel_count) {
-		IWL_DEBUG_INFO("Channel map already initialized.\n");
-		return 0;
-	}
-
-	if (priv->eeprom.version < 0x2f) {
-		IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
-			    priv->eeprom.version);
-		return -EINVAL;
-	}
-
-	IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
-
-	priv->channel_count =
-	    ARRAY_SIZE(iwl3945_eeprom_band_1) +
-	    ARRAY_SIZE(iwl3945_eeprom_band_2) +
-	    ARRAY_SIZE(iwl3945_eeprom_band_3) +
-	    ARRAY_SIZE(iwl3945_eeprom_band_4) +
-	    ARRAY_SIZE(iwl3945_eeprom_band_5);
-
-	IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
-
-	priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) *
-				     priv->channel_count, GFP_KERNEL);
-	if (!priv->channel_info) {
-		IWL_ERROR("Could not allocate channel_info\n");
-		priv->channel_count = 0;
-		return -ENOMEM;
-	}
-
-	ch_info = priv->channel_info;
-
-	/* Loop through the 5 EEPROM bands adding them in order to the
-	 * channel map we maintain (that contains additional information than
-	 * what just in the EEPROM) */
-	for (band = 1; band <= 5; band++) {
-
-		iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
-					&eeprom_ch_info, &eeprom_ch_index);
-
-		/* Loop through each band adding each of the channels */
-		for (ch = 0; ch < eeprom_ch_count; ch++) {
-			ch_info->channel = eeprom_ch_index[ch];
-			ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
-			    IEEE80211_BAND_5GHZ;
-
-			/* permanently store EEPROM's channel regulatory flags
-			 *   and max power in channel info database. */
-			ch_info->eeprom = eeprom_ch_info[ch];
-
-			/* Copy the run-time flags so they are there even on
-			 * invalid channels */
-			ch_info->flags = eeprom_ch_info[ch].flags;
-
-			if (!(is_channel_valid(ch_info))) {
-				IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
-					       "No traffic\n",
-					       ch_info->channel,
-					       ch_info->flags,
-					       is_channel_a_band(ch_info) ?
-					       "5.2" : "2.4");
-				ch_info++;
-				continue;
-			}
-
-			/* Initialize regulatory-based run-time data */
-			ch_info->max_power_avg = ch_info->curr_txpow =
-			    eeprom_ch_info[ch].max_power_avg;
-			ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
-			ch_info->min_power = 0;
-
-			IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
-				       " %ddBm): Ad-Hoc %ssupported\n",
-				       ch_info->channel,
-				       is_channel_a_band(ch_info) ?
-				       "5.2" : "2.4",
-				       CHECK_AND_PRINT(VALID),
-				       CHECK_AND_PRINT(IBSS),
-				       CHECK_AND_PRINT(ACTIVE),
-				       CHECK_AND_PRINT(RADAR),
-				       CHECK_AND_PRINT(WIDE),
-				       CHECK_AND_PRINT(DFS),
-				       eeprom_ch_info[ch].flags,
-				       eeprom_ch_info[ch].max_power_avg,
-				       ((eeprom_ch_info[ch].
-					 flags & EEPROM_CHANNEL_IBSS)
-					&& !(eeprom_ch_info[ch].
-					     flags & EEPROM_CHANNEL_RADAR))
-				       ? "" : "not ");
-
-			/* Set the user_txpower_limit to the highest power
-			 * supported by any channel */
-			if (eeprom_ch_info[ch].max_power_avg >
-			    priv->user_txpower_limit)
-				priv->user_txpower_limit =
-				    eeprom_ch_info[ch].max_power_avg;
-
-			ch_info++;
-		}
-	}
-
-	/* Set up txpower settings in driver for all channels */
-	if (iwl3945_txpower_set_from_eeprom(priv))
-		return -EIO;
-
-	return 0;
-}
-
-/*
- * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
- */
-static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
-{
-	kfree(priv->channel_info);
-	priv->channel_count = 0;
-}
-
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req.  This should be set long enough to hear probe responses
- * from more than one AP.  */
-#define IWL_ACTIVE_DWELL_TIME_24    (30)	/* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52    (20)
-
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request.  This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH       __constant_cpu_to_le16(1)	/* packets */
-#define IWL_ACTIVE_QUIET_TIME       __constant_cpu_to_le16(10)	/* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24   (20)	/* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52   (10)
-#define IWL_PASSIVE_DWELL_BASE      (100)
-#define IWL_CHANNEL_TUNE_TIME       5
-
-#define IWL_SCAN_PROBE_MASK(n)	 (BIT(n) | (BIT(n) - BIT(1)))
-
-static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
-						enum ieee80211_band band,
-						u8 n_probes)
-{
-	if (band == IEEE80211_BAND_5GHZ)
-		return IWL_ACTIVE_DWELL_TIME_52 +
-			IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
-	else
-		return IWL_ACTIVE_DWELL_TIME_24 +
-			IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
-}
-
-static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
-					  enum ieee80211_band band)
-{
-	u16 passive = (band == IEEE80211_BAND_2GHZ) ?
-	    IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
-	    IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
-	if (iwl3945_is_associated(priv)) {
-		/* If we're associated, we clamp the maximum passive
-		 * dwell time to be 98% of the beacon interval (minus
-		 * 2 * channel tune time) */
-		passive = priv->beacon_int;
-		if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
-			passive = IWL_PASSIVE_DWELL_BASE;
-		passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
-	}
-
-	return passive;
-}
-
-static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
+static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
 					 enum ieee80211_band band,
 				     u8 is_active, u8 n_probes,
 				     struct iwl3945_scan_channel *scan_ch)
 {
 	const struct ieee80211_channel *channels = NULL;
 	const struct ieee80211_supported_band *sband;
-	const struct iwl3945_channel_info *ch_info;
+	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
 	u16 active_dwell = 0;
 	int added, i;
 
-	sband = iwl3945_get_band(priv, band);
+	sband = iwl_get_hw_mode(priv, band);
 	if (!sband)
 		return 0;
 
 	channels = sband->channels;
 
-	active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
-	passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
+	active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+	passive_dwell = iwl_get_passive_dwell_time(priv, band);
 
 	if (passive_dwell <= active_dwell)
 		passive_dwell = active_dwell + 1;
@@ -4771,9 +2300,9 @@ static int iwl3945_get_channels_for_scan
 
 		scan_ch->channel = channels[i].hw_value;
 
-		ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
+		ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
 		if (!is_channel_valid(ch_info)) {
-			IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+			IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
 				       scan_ch->channel);
 			continue;
 		}
@@ -4798,12 +2327,12 @@ static int iwl3945_get_channels_for_scan
 		 * hearing clear Rx packet).*/
 		if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
 			if (n_probes)
-				scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+				scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
 		} else {
 			/* uCode v1 does not allow setting direct probe bits on
 			 * passive channel. */
 			if ((scan_ch->type & 1) && n_probes)
-				scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+				scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
 		}
 
 		/* Set txpower levels to defaults */
@@ -4821,7 +2350,7 @@ static int iwl3945_get_channels_for_scan
 			 */
 		}
 
-		IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
+		IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n",
 			       scan_ch->channel,
 			       (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
 			       (scan_ch->type & 1) ?
@@ -4831,11 +2360,11 @@ static int iwl3945_get_channels_for_scan
 		added++;
 	}
 
-	IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+	IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
 	return added;
 }
 
-static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
+static void iwl3945_init_hw_rates(struct iwl_priv *priv,
 			      struct ieee80211_rate *rates)
 {
 	int i;
@@ -4845,7 +2374,7 @@ static void iwl3945_init_hw_rates(struct
 		rates[i].hw_value = i; /* Rate scaling will work on indexes */
 		rates[i].hw_value_short = i;
 		rates[i].flags = 0;
-		if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+		if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
 			/*
 			 * If CCK != 1M then set short preamble rate flag.
 			 */
@@ -4855,145 +2384,13 @@ static void iwl3945_init_hw_rates(struct
 	}
 }
 
-/**
- * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-static int iwl3945_init_geos(struct iwl3945_priv *priv)
-{
-	struct iwl3945_channel_info *ch;
-	struct ieee80211_supported_band *sband;
-	struct ieee80211_channel *channels;
-	struct ieee80211_channel *geo_ch;
-	struct ieee80211_rate *rates;
-	int i = 0;
-
-	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
-	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
-		IWL_DEBUG_INFO("Geography modes already initialized.\n");
-		set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-		return 0;
-	}
-
-	channels = kzalloc(sizeof(struct ieee80211_channel) *
-			   priv->channel_count, GFP_KERNEL);
-	if (!channels)
-		return -ENOMEM;
-
-	rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
-			GFP_KERNEL);
-	if (!rates) {
-		kfree(channels);
-		return -ENOMEM;
-	}
-
-	/* 5.2GHz channels start after the 2.4GHz channels */
-	sband = &priv->bands[IEEE80211_BAND_5GHZ];
-	sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
-	/* just OFDM */
-	sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
-	sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
-	sband = &priv->bands[IEEE80211_BAND_2GHZ];
-	sband->channels = channels;
-	/* OFDM & CCK */
-	sband->bitrates = rates;
-	sband->n_bitrates = IWL_RATE_COUNT;
-
-	priv->ieee_channels = channels;
-	priv->ieee_rates = rates;
-
-	iwl3945_init_hw_rates(priv, rates);
-
-	for (i = 0;  i < priv->channel_count; i++) {
-		ch = &priv->channel_info[i];
-
-		/* FIXME: might be removed if scan is OK*/
-		if (!is_channel_valid(ch))
-			continue;
-
-		if (is_channel_a_band(ch))
-			sband =  &priv->bands[IEEE80211_BAND_5GHZ];
-		else
-			sband =  &priv->bands[IEEE80211_BAND_2GHZ];
-
-		geo_ch = &sband->channels[sband->n_channels++];
-
-		geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
-		geo_ch->max_power = ch->max_power_avg;
-		geo_ch->max_antenna_gain = 0xff;
-		geo_ch->hw_value = ch->channel;
-
-		if (is_channel_valid(ch)) {
-			if (!(ch->flags & EEPROM_CHANNEL_IBSS))
-				geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
-			if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
-				geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
-			if (ch->flags & EEPROM_CHANNEL_RADAR)
-				geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
-			if (ch->max_power_avg > priv->max_channel_txpower_limit)
-				priv->max_channel_txpower_limit =
-				    ch->max_power_avg;
-		} else {
-			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
-		}
-
-		/* Save flags for reg domain usage */
-		geo_ch->orig_flags = geo_ch->flags;
-
-		IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
-				ch->channel, geo_ch->center_freq,
-				is_channel_a_band(ch) ?  "5.2" : "2.4",
-				geo_ch->flags & IEEE80211_CHAN_DISABLED ?
-				"restricted" : "valid",
-				 geo_ch->flags);
-	}
-
-	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
-	     priv->cfg->sku & IWL_SKU_A) {
-		printk(KERN_INFO DRV_NAME
-		       ": Incorrectly detected BG card as ABG.  Please send "
-		       "your PCI ID 0x%04X:0x%04X to maintainer.\n",
-		       priv->pci_dev->device, priv->pci_dev->subsystem_device);
-		 priv->cfg->sku &= ~IWL_SKU_A;
-	}
-
-	printk(KERN_INFO DRV_NAME
-	       ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
-	       priv->bands[IEEE80211_BAND_2GHZ].n_channels,
-	       priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
-	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];
-
-	set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
-	return 0;
-}
-
-/*
- * iwl3945_free_geos - undo allocations in iwl3945_init_geos
- */
-static void iwl3945_free_geos(struct iwl3945_priv *priv)
-{
-	kfree(priv->ieee_channels);
-	kfree(priv->ieee_rates);
-	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
 /******************************************************************************
  *
  * uCode download functions
  *
  ******************************************************************************/
 
-static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
+static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv)
 {
 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
@@ -5007,29 +2404,30 @@ static void iwl3945_dealloc_ucode_pci(st
  * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
  *     looking at all data.
  */
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len)
 {
 	u32 val;
 	u32 save_len = len;
 	int rc = 0;
 	u32 errcnt;
 
-	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc)
 		return rc;
 
-	iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+	iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+			       IWL39_RTC_INST_LOWER_BOUND);
 
 	errcnt = 0;
 	for (; len > 0; len -= sizeof(u32), image++) {
 		/* read data comes through single port, auto-incr addr */
 		/* NOTE: Use the debugless read so we don't flood kernel log
 		 * if IWL_DL_IO is set */
-		val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
-			IWL_ERROR("uCode INST section is invalid at "
+			IWL_ERR(priv, "uCode INST section is invalid at "
 				  "offset 0x%x, is 0x%x, s/b 0x%x\n",
 				  save_len - len, val, le32_to_cpu(*image));
 			rc = -EIO;
@@ -5039,10 +2437,11 @@ static int iwl3945_verify_inst_full(stru
 		}
 	}
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 
 	if (!errcnt)
-		IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n");
+		IWL_DEBUG_INFO(priv,
+			"ucode image in INSTRUCTION memory is good\n");
 
 	return rc;
 }
@@ -5053,16 +2452,16 @@ static int iwl3945_verify_inst_full(stru
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
 {
 	u32 val;
 	int rc = 0;
 	u32 errcnt = 0;
 	u32 i;
 
-	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc)
 		return rc;
 
@@ -5070,12 +2469,12 @@ static int iwl3945_verify_inst_sparse(st
 		/* read data comes through single port, auto-incr addr */
 		/* NOTE: Use the debugless read so we don't flood kernel log
 		 * if IWL_DL_IO is set */
-		iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR,
-			i + RTC_INST_LOWER_BOUND);
-		val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+			i + IWL39_RTC_INST_LOWER_BOUND);
+		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
 #if 0 /* Enable this if you want to see details */
-			IWL_ERROR("uCode INST section is invalid at "
+			IWL_ERR(priv, "uCode INST section is invalid at "
 				  "offset 0x%x, is 0x%x, s/b 0x%x\n",
 				  i, val, *image);
 #endif
@@ -5086,7 +2485,7 @@ static int iwl3945_verify_inst_sparse(st
 		}
 	}
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 
 	return rc;
 }
@@ -5096,7 +2495,7 @@ static int iwl3945_verify_inst_sparse(st
  * iwl3945_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
+static int iwl3945_verify_ucode(struct iwl_priv *priv)
 {
 	__le32 *image;
 	u32 len;
@@ -5107,7 +2506,7 @@ static int iwl3945_verify_ucode(struct i
 	len = priv->ucode_boot.len;
 	rc = iwl3945_verify_inst_sparse(priv, image, len);
 	if (rc == 0) {
-		IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
 		return 0;
 	}
 
@@ -5116,7 +2515,7 @@ static int iwl3945_verify_ucode(struct i
 	len = priv->ucode_init.len;
 	rc = iwl3945_verify_inst_sparse(priv, image, len);
 	if (rc == 0) {
-		IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
 		return 0;
 	}
 
@@ -5125,11 +2524,11 @@ static int iwl3945_verify_ucode(struct i
 	len = priv->ucode_code.len;
 	rc = iwl3945_verify_inst_sparse(priv, image, len);
 	if (rc == 0) {
-		IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
 		return 0;
 	}
 
-	IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+	IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
 
 	/* Since nothing seems to match, show first several data entries in
 	 * instruction SRAM, so maybe visual inspection will give a clue.
@@ -5141,160 +2540,10 @@ static int iwl3945_verify_ucode(struct i
 	return rc;
 }
 
-
-/* check contents of special bootstrap uCode SRAM */
-static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
-{
-	__le32 *image = priv->ucode_boot.v_addr;
-	u32 len = priv->ucode_boot.len;
-	u32 reg;
-	u32 val;
-
-	IWL_DEBUG_INFO("Begin verify bsm\n");
-
-	/* verify BSM SRAM contents */
-	val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
-	for (reg = BSM_SRAM_LOWER_BOUND;
-	     reg < BSM_SRAM_LOWER_BOUND + len;
-	     reg += sizeof(u32), image++) {
-		val = iwl3945_read_prph(priv, reg);
-		if (val != le32_to_cpu(*image)) {
-			IWL_ERROR("BSM uCode verification failed at "
-				  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
-				  BSM_SRAM_LOWER_BOUND,
-				  reg - BSM_SRAM_LOWER_BOUND, len,
-				  val, le32_to_cpu(*image));
-			return -EIO;
-		}
-	}
-
-	IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
-
-	return 0;
-}
-
-/**
- * iwl3945_load_bsm - Load bootstrap instructions
- *
- * BSM operation:
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down during RFKILL.  When powering back
- * up after power-saving sleeps (or during initial uCode load), the BSM loads
- * the bootstrap program into the on-board processor, and starts it.
- *
- * The bootstrap program loads (via DMA) instructions and data for a new
- * program from host DRAM locations indicated by the host driver in the
- * BSM_DRAM_* registers.  Once the new program is loaded, it starts
- * automatically.
- *
- * When initializing the NIC, the host driver points the BSM to the
- * "initialize" uCode image.  This uCode sets up some internal data, then
- * notifies host via "initialize alive" that it is complete.
- *
- * The host then replaces the BSM_DRAM_* pointer values to point to the
- * normal runtime uCode instructions and a backup uCode data cache buffer
- * (filled initially with starting data values for the on-board processor),
- * then triggers the "initialize" uCode to load and launch the runtime uCode,
- * which begins normal operation.
- *
- * When doing a power-save shutdown, runtime uCode saves data SRAM into
- * the backup data cache in DRAM before SRAM is powered down.
- *
- * When powering back up, the BSM loads the bootstrap program.  This reloads
- * the runtime uCode instructions and the backup data cache into SRAM,
- * and re-launches the runtime uCode from where it left off.
- */
-static int iwl3945_load_bsm(struct iwl3945_priv *priv)
-{
-	__le32 *image = priv->ucode_boot.v_addr;
-	u32 len = priv->ucode_boot.len;
-	dma_addr_t pinst;
-	dma_addr_t pdata;
-	u32 inst_len;
-	u32 data_len;
-	int rc;
-	int i;
-	u32 done;
-	u32 reg_offset;
-
-	IWL_DEBUG_INFO("Begin load bsm\n");
-
-	/* make sure bootstrap program is no larger than BSM's SRAM size */
-	if (len > IWL_MAX_BSM_SIZE)
-		return -EINVAL;
-
-	/* Tell bootstrap uCode where to find the "Initialize" uCode
-	 *   in host DRAM ... host DRAM physical address bits 31:0 for 3945.
-	 * NOTE:  iwl3945_initialize_alive_start() will replace these values,
-	 *        after the "initialize" uCode has run, to point to
-	 *        runtime/protocol instructions and backup data cache. */
-	pinst = priv->ucode_init.p_addr;
-	pdata = priv->ucode_init_data.p_addr;
-	inst_len = priv->ucode_init.len;
-	data_len = priv->ucode_init_data.len;
-
-	rc = iwl3945_grab_nic_access(priv);
-	if (rc)
-		return rc;
-
-	iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
-	iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-	iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
-	iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
-
-	/* Fill BSM memory with bootstrap instructions */
-	for (reg_offset = BSM_SRAM_LOWER_BOUND;
-	     reg_offset < BSM_SRAM_LOWER_BOUND + len;
-	     reg_offset += sizeof(u32), image++)
-		_iwl3945_write_prph(priv, reg_offset,
-					  le32_to_cpu(*image));
-
-	rc = iwl3945_verify_bsm(priv);
-	if (rc) {
-		iwl3945_release_nic_access(priv);
-		return rc;
-	}
-
-	/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
-	iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
-	iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG,
-				 RTC_INST_LOWER_BOUND);
-	iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
-
-	/* Load bootstrap code into instruction SRAM now,
-	 *   to prepare to load "initialize" uCode */
-	iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
-		BSM_WR_CTRL_REG_BIT_START);
-
-	/* Wait for load of bootstrap uCode to finish */
-	for (i = 0; i < 100; i++) {
-		done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG);
-		if (!(done & BSM_WR_CTRL_REG_BIT_START))
-			break;
-		udelay(10);
-	}
-	if (i < 100)
-		IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
-	else {
-		IWL_ERROR("BSM write did not complete!\n");
-		return -EIO;
-	}
-
-	/* Enable future boot loads whenever power management unit triggers it
-	 *   (e.g. when powering back up after power-save shutdown) */
-	iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
-		BSM_WR_CTRL_REG_BIT_START_EN);
-
-	iwl3945_release_nic_access(priv);
-
-	return 0;
-}
-
-static void iwl3945_nic_start(struct iwl3945_priv *priv)
+static void iwl3945_nic_start(struct iwl_priv *priv)
 {
 	/* Remove all resets to allow NIC to operate */
-	iwl3945_write32(priv, CSR_RESET, 0);
+	iwl_write32(priv, CSR_RESET, 0);
 }
 
 /**
@@ -5302,9 +2551,9 @@ static void iwl3945_nic_start(struct iwl
  *
  * Copy into buffers for card to fetch via bus-mastering
  */
-static int iwl3945_read_ucode(struct iwl3945_priv *priv)
+static int iwl3945_read_ucode(struct iwl_priv *priv)
 {
-	struct iwl3945_ucode *ucode;
+	struct iwl_ucode *ucode;
 	int ret = -EINVAL, index;
 	const struct firmware *ucode_raw;
 	/* firmware file name contains uCode/driver compatibility version */
@@ -5322,7 +2571,7 @@ static int iwl3945_read_ucode(struct iwl
 		sprintf(buf, "/*(DEBLOBBED)*/");
 		ret = reject_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
 		if (ret < 0) {
-			IWL_ERROR("%s firmware file req failed: Reason %d\n",
+			IWL_ERR(priv, "%s firmware file req failed: %d\n",
 				  buf, ret);
 			if (ret == -ENOENT)
 				continue;
@@ -5330,9 +2579,12 @@ static int iwl3945_read_ucode(struct iwl
 				goto error;
 		} else {
 			if (index < api_max)
-				IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+				IWL_ERR(priv, "Loaded firmware %s, "
+					"which is deprecated. "
+					" Please use API v%u instead.\n",
 					  buf, api_max);
-			IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+			IWL_DEBUG_INFO(priv, "Got firmware '%s' file "
+				       "(%zd bytes) from disk\n",
 				       buf, ucode_raw->size);
 			break;
 		}
@@ -5343,7 +2595,7 @@ static int iwl3945_read_ucode(struct iwl
 
 	/* Make sure that we got at least our header! */
 	if (ucode_raw->size < sizeof(*ucode)) {
-		IWL_ERROR("File size way too small!\n");
+		IWL_ERR(priv, "File size way too small!\n");
 		ret = -EINVAL;
 		goto err_release;
 	}
@@ -5361,10 +2613,10 @@ static int iwl3945_read_ucode(struct iwl
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
-	 * on the API version read from firware header from here on forward */
+	 * on the API version read from firmware header from here on forward */
 
 	if (api_ver < api_min || api_ver > api_max) {
-		IWL_ERROR("Driver unable to support your firmware API. "
+		IWL_ERR(priv, "Driver unable to support your firmware API. "
 			  "Driver supports v%u, firmware is v%u.\n",
 			  api_max, api_ver);
 		priv->ucode_ver = 0;
@@ -5372,23 +2624,29 @@ static int iwl3945_read_ucode(struct iwl
 		goto err_release;
 	}
 	if (api_ver != api_max)
-		IWL_ERROR("Firmware has old API version. Expected %u, "
+		IWL_ERR(priv, "Firmware has old API version. Expected %u, "
 			  "got %u. New firmware can be obtained "
 			  "from http://www.intellinuxwireless.org.\n",
 			  api_max, api_ver);
 
-	printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
-		       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("f/w package hdr ucode version raw = 0x%x\n",
+	IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+		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("f/w package hdr runtime inst size = %u\n", inst_size);
-	IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
-	IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
-	IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
-	IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
+		       inst_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
+		       data_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
+		       init_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
+		       init_data_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
+		       boot_size);
 
 
 	/* Verify size of file vs. image size info in file's header */
@@ -5396,40 +2654,43 @@ static int iwl3945_read_ucode(struct iwl
 		inst_size + data_size + init_size +
 		init_data_size + boot_size) {
 
-		IWL_DEBUG_INFO("uCode file size %d too small\n",
-			       (int)ucode_raw->size);
+		IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n",
+			       ucode_raw->size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 
 	/* Verify that uCode images will fit in card's SRAM */
-	if (inst_size > IWL_MAX_INST_SIZE) {
-		IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+	if (inst_size > IWL39_MAX_INST_SIZE) {
+		IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
 			       inst_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 
-	if (data_size > IWL_MAX_DATA_SIZE) {
-		IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+	if (data_size > IWL39_MAX_DATA_SIZE) {
+		IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
 			       data_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
-	if (init_size > IWL_MAX_INST_SIZE) {
-		IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n",
+	if (init_size > IWL39_MAX_INST_SIZE) {
+		IWL_DEBUG_INFO(priv,
+				"uCode init instr len %d too large to fit in\n",
 				init_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
-	if (init_data_size > IWL_MAX_DATA_SIZE) {
-		IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n",
+	if (init_data_size > IWL39_MAX_DATA_SIZE) {
+		IWL_DEBUG_INFO(priv,
+				"uCode init data len %d too large to fit in\n",
 				init_data_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
-	if (boot_size > IWL_MAX_BSM_SIZE) {
-		IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n",
+	if (boot_size > IWL39_MAX_BSM_SIZE) {
+		IWL_DEBUG_INFO(priv,
+				"uCode boot instr len %d too large to fit in\n",
 				boot_size);
 		ret = -EINVAL;
 		goto err_release;
@@ -5479,16 +2740,18 @@ static int iwl3945_read_ucode(struct iwl
 	/* Runtime instructions (first block of data in file) */
 	src = &ucode->data[0];
 	len = priv->ucode_code.len;
-	IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+	IWL_DEBUG_INFO(priv,
+		"Copying (but not loading) uCode instr len %zd\n", len);
 	memcpy(priv->ucode_code.v_addr, src, len);
-	IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
 		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
 	/* Runtime data (2nd block)
 	 * NOTE:  Copy into backup buffer will be done in iwl3945_up()  */
 	src = &ucode->data[inst_size];
 	len = priv->ucode_data.len;
-	IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+	IWL_DEBUG_INFO(priv,
+		"Copying (but not loading) uCode data len %zd\n", len);
 	memcpy(priv->ucode_data.v_addr, src, len);
 	memcpy(priv->ucode_data_backup.v_addr, src, len);
 
@@ -5496,8 +2759,8 @@ static int iwl3945_read_ucode(struct iwl
 	if (init_size) {
 		src = &ucode->data[inst_size + data_size];
 		len = priv->ucode_init.len;
-		IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
-			       len);
+		IWL_DEBUG_INFO(priv,
+			"Copying (but not loading) init instr len %zd\n", len);
 		memcpy(priv->ucode_init.v_addr, src, len);
 	}
 
@@ -5505,16 +2768,16 @@ static int iwl3945_read_ucode(struct iwl
 	if (init_data_size) {
 		src = &ucode->data[inst_size + data_size + init_size];
 		len = priv->ucode_init_data.len;
-		IWL_DEBUG_INFO("Copying (but not loading) init data len %d\n",
-			       (int)len);
+		IWL_DEBUG_INFO(priv,
+			"Copying (but not loading) init data len %zd\n", len);
 		memcpy(priv->ucode_init_data.v_addr, src, len);
 	}
 
 	/* Bootstrap instructions (5th block) */
 	src = &ucode->data[inst_size + data_size + init_size + init_data_size];
 	len = priv->ucode_boot.len;
-	IWL_DEBUG_INFO("Copying (but not loading) boot instr len %d\n",
-		       (int)len);
+	IWL_DEBUG_INFO(priv,
+		"Copying (but not loading) boot instr len %zd\n", len);
 	memcpy(priv->ucode_boot.v_addr, src, len);
 
 	/* We have our copies now, allow OS release its copies */
@@ -5522,7 +2785,7 @@ static int iwl3945_read_ucode(struct iwl
 	return 0;
 
  err_pci_alloc:
-	IWL_ERROR("failed to allocate pci memory\n");
+	IWL_ERR(priv, "failed to allocate pci memory\n");
 	ret = -ENOMEM;
 	iwl3945_dealloc_ucode_pci(priv);
 
@@ -5543,7 +2806,7 @@ static int iwl3945_read_ucode(struct iwl
  * We need to replace them to load runtime uCode inst and data,
  * and to save runtime data when powering down.
  */
-static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
+static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
 {
 	dma_addr_t pinst;
 	dma_addr_t pdata;
@@ -5555,28 +2818,28 @@ static int iwl3945_set_ucode_ptrs(struct
 	pdata = priv->ucode_data_backup.p_addr;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
 
 	/* Tell bootstrap uCode where to find image to load */
-	iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
-	iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-	iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+	iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+	iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+	iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
 				 priv->ucode_data.len);
 
 	/* Inst byte count must be last to set up, bit 31 signals uCode
 	 *   that all new ptr/size info is in place */
-	iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+	iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
 				 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+	IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
 
 	return rc;
 }
@@ -5588,13 +2851,13 @@ static int iwl3945_set_ucode_ptrs(struct
  *
  * Tell "initialize" uCode to go ahead and load the runtime uCode.
  */
-static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_init_alive_start(struct iwl_priv *priv)
 {
 	/* Check alive response for "valid" sign from uCode */
 	if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
 		/* We had an error bringing up the hardware, so take it
 		 * all the way back down so we can try again */
-		IWL_DEBUG_INFO("Initialize Alive failed.\n");
+		IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
 		goto restart;
 	}
 
@@ -5604,18 +2867,18 @@ static void iwl3945_init_alive_start(str
 	if (iwl3945_verify_ucode(priv)) {
 		/* Runtime instruction load was bad;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+		IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
 		goto restart;
 	}
 
 	/* Send pointers to protocol/runtime uCode image ... init code will
 	 * load and launch runtime uCode, which will send us another "Alive"
 	 * notification. */
-	IWL_DEBUG_INFO("Initialization Alive received.\n");
+	IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
 	if (iwl3945_set_ucode_ptrs(priv)) {
 		/* Runtime instruction load won't happen;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+		IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
 		goto restart;
 	}
 	return;
@@ -5634,18 +2897,18 @@ static int iwl3945_mac_beacon_update(str
  *                   from protocol/runtime uCode (initialization uCode's
  *                   Alive gets handled by iwl3945_init_alive_start()).
  */
-static void iwl3945_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_alive_start(struct iwl_priv *priv)
 {
 	int rc = 0;
 	int thermal_spin = 0;
 	u32 rfkill;
 
-	IWL_DEBUG_INFO("Runtime Alive received.\n");
+	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
 	if (priv->card_alive.is_valid != UCODE_VALID_OK) {
 		/* We had an error bringing up the hardware, so take it
 		 * all the way back down so we can try again */
-		IWL_DEBUG_INFO("Alive failed.\n");
+		IWL_DEBUG_INFO(priv, "Alive failed.\n");
 		goto restart;
 	}
 
@@ -5655,21 +2918,21 @@ static void iwl3945_alive_start(struct i
 	if (iwl3945_verify_ucode(priv)) {
 		/* Runtime instruction load was bad;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+		IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
 		goto restart;
 	}
 
 	iwl3945_clear_stations_table(priv);
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
-		IWL_WARNING("Can not read RFKILL status from adapter\n");
+		IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
 		return;
 	}
 
-	rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG);
-	IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill);
-	iwl3945_release_nic_access(priv);
+	rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
+	IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
+	iwl_release_nic_access(priv);
 
 	if (rfkill & 0x1) {
 		clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5681,7 +2944,7 @@ static void iwl3945_alive_start(struct i
 		}
 
 		if (thermal_spin)
-			IWL_DEBUG_INFO("Thermal calibration took %dus\n",
+			IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n",
 				       thermal_spin * 10);
 	} else
 		set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5692,7 +2955,7 @@ static void iwl3945_alive_start(struct i
 	/* Clear out the uCode error bit if it is set */
 	clear_bit(STATUS_FW_ERROR, &priv->status);
 
-	if (iwl3945_is_rfkill(priv))
+	if (iwl_is_rfkill(priv))
 		return;
 
 	ieee80211_wake_queues(priv->hw);
@@ -5700,9 +2963,9 @@ static void iwl3945_alive_start(struct i
 	priv->active_rate = priv->rates_mask;
 	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-	iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
+	iwl_power_update_mode(priv, false);
 
-	if (iwl3945_is_associated(priv)) {
+	if (iwl_is_associated(priv)) {
 		struct iwl3945_rxon_cmd *active_rxon =
 				(struct iwl3945_rxon_cmd *)(&priv->active_rxon);
 
@@ -5711,12 +2974,11 @@ static void iwl3945_alive_start(struct i
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	} else {
 		/* Initialize our rx_config data */
-		iwl3945_connection_init_rx_config(priv, priv->iw_mode);
-		memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+		iwl_connection_init_rx_config(priv, priv->iw_mode);
 	}
 
 	/* Configure Bluetooth device coexistence support */
-	iwl3945_send_bt_config(priv);
+	iwl_send_bt_config(priv);
 
 	/* Configure the adapter for unassociated operation */
 	iwl3945_commit_rxon(priv);
@@ -5725,7 +2987,7 @@ static void iwl3945_alive_start(struct i
 
 	iwl3945_led_register(priv);
 
-	IWL_DEBUG_INFO("ALIVE processing complete.\n");
+	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
 	set_bit(STATUS_READY, &priv->status);
 	wake_up_interruptible(&priv->wait_command_queue);
 
@@ -5746,15 +3008,15 @@ static void iwl3945_alive_start(struct i
 	queue_work(priv->workqueue, &priv->restart);
 }
 
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv);
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
 
-static void __iwl3945_down(struct iwl3945_priv *priv)
+static void __iwl3945_down(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
 	struct ieee80211_conf *conf = NULL;
 
-	IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
 	conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -5773,11 +3035,11 @@ static void __iwl3945_down(struct iwl394
 		clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
 	/* stop and reset the on-board processor */
-	iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 
 	/* tell the device to stop sending interrupts */
 	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_disable_interrupts(priv);
+	iwl_disable_interrupts(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 	iwl_synchronize_irq(priv);
 
@@ -5786,7 +3048,7 @@ static void __iwl3945_down(struct iwl394
 
 	/* If we have not previously called iwl3945_init() then
 	 * clear all bits but the RF Kill and SUSPEND bits and return */
-	if (!iwl3945_is_init(priv)) {
+	if (!iwl_is_init(priv)) {
 		priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
 					STATUS_RF_KILL_HW |
 			       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
@@ -5815,29 +3077,31 @@ static void __iwl3945_down(struct iwl394
 			test_bit(STATUS_EXIT_PENDING, &priv->status) <<
 				STATUS_EXIT_PENDING;
 
+	priv->cfg->ops->lib->apm_ops.reset(priv);
 	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+	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);
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (!iwl3945_grab_nic_access(priv)) {
-		iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
+	if (!iwl_grab_nic_access(priv)) {
+		iwl_write_prph(priv, APMG_CLK_DIS_REG,
 					 APMG_CLK_VAL_DMA_CLK_RQT);
-		iwl3945_release_nic_access(priv);
+		iwl_release_nic_access(priv);
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	udelay(5);
 
-	iwl3945_hw_nic_stop_master(priv);
-	iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-	iwl3945_hw_nic_reset(priv);
+	if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+		priv->cfg->ops->lib->apm_ops.stop(priv);
+	else
+		priv->cfg->ops->lib->apm_ops.reset(priv);
 
  exit:
-	memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp));
+	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
 	if (priv->ibss_beacon)
 		dev_kfree_skb(priv->ibss_beacon);
@@ -5847,7 +3111,7 @@ static void __iwl3945_down(struct iwl394
 	iwl3945_clear_free_frames(priv);
 }
 
-static void iwl3945_down(struct iwl3945_priv *priv)
+static void iwl3945_down(struct iwl_priv *priv)
 {
 	mutex_lock(&priv->mutex);
 	__iwl3945_down(priv);
@@ -5858,58 +3122,58 @@ static void iwl3945_down(struct iwl3945_
 
 #define MAX_HW_RESTARTS 5
 
-static int __iwl3945_up(struct iwl3945_priv *priv)
+static int __iwl3945_up(struct iwl_priv *priv)
 {
 	int rc, i;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_WARNING("Exit pending; will not bring the NIC up\n");
+		IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
 		return -EIO;
 	}
 
 	if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
-		IWL_WARNING("Radio disabled by SW RF kill (module "
+		IWL_WARN(priv, "Radio disabled by SW RF kill (module "
 			    "parameter)\n");
 		return -ENODEV;
 	}
 
 	if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
-		IWL_ERROR("ucode not available for device bring up\n");
+		IWL_ERR(priv, "ucode not available for device bring up\n");
 		return -EIO;
 	}
 
 	/* If platform's RF_KILL switch is NOT set to KILL */
-	if (iwl3945_read32(priv, CSR_GP_CNTRL) &
+	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 (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
-			IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+			IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
 			return -ENODEV;
 		}
 	}
 
-	iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
 
 	rc = iwl3945_hw_nic_init(priv);
 	if (rc) {
-		IWL_ERROR("Unable to int nic\n");
+		IWL_ERR(priv, "Unable to int nic\n");
 		return rc;
 	}
 
 	/* make sure rfkill handshake bits are cleared */
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
 	/* clear (again), then enable host interrupts */
-	iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
-	iwl3945_enable_interrupts(priv);
+	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+	iwl_enable_interrupts(priv);
 
 	/* really make sure rfkill handshake bits are cleared */
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
 	/* Copy original ucode data image from disk into backup cache.
 	 * This will be used to initialize the on-board processor's
@@ -5928,17 +3192,18 @@ static int __iwl3945_up(struct iwl3945_p
 		/* load bootstrap state machine,
 		 * load bootstrap program into processor's memory,
 		 * prepare to load the "initialize" uCode */
-		rc = iwl3945_load_bsm(priv);
+		priv->cfg->ops->lib->load_ucode(priv);
 
 		if (rc) {
-			IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
+			IWL_ERR(priv,
+				"Unable to set up bootstrap uCode: %d\n", rc);
 			continue;
 		}
 
 		/* start card; "initialize" will load runtime ucode */
 		iwl3945_nic_start(priv);
 
-		IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+		IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
 
 		return 0;
 	}
@@ -5949,7 +3214,7 @@ static int __iwl3945_up(struct iwl3945_p
 
 	/* tried to restart and config the device for as long as our
 	 * patience could withstand */
-	IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+	IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
 	return -EIO;
 }
 
@@ -5962,8 +3227,8 @@ static int __iwl3945_up(struct iwl3945_p
 
 static void iwl3945_bg_init_alive_start(struct work_struct *data)
 {
-	struct iwl3945_priv *priv =
-	    container_of(data, struct iwl3945_priv, init_alive_start.work);
+	struct iwl_priv *priv =
+	    container_of(data, struct iwl_priv, init_alive_start.work);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -5975,8 +3240,8 @@ static void iwl3945_bg_init_alive_start(
 
 static void iwl3945_bg_alive_start(struct work_struct *data)
 {
-	struct iwl3945_priv *priv =
-	    container_of(data, struct iwl3945_priv, alive_start.work);
+	struct iwl_priv *priv =
+	    container_of(data, struct iwl_priv, alive_start.work);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -5986,66 +3251,31 @@ static void iwl3945_bg_alive_start(struc
 	mutex_unlock(&priv->mutex);
 }
 
-static void iwl3945_bg_rf_kill(struct work_struct *work)
+static void iwl3945_rfkill_poll(struct work_struct *data)
 {
-	struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill);
-
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+	struct iwl_priv *priv =
+	    container_of(data, struct iwl_priv, rfkill_poll.work);
+	unsigned long status = priv->status;
 
-	mutex_lock(&priv->mutex);
+	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 (!iwl3945_is_rfkill(priv)) {
-		IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
-			  "HW and/or SW RF Kill no longer active, restarting "
-			  "device\n");
-		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-			queue_work(priv->workqueue, &priv->restart);
-	} else {
+	if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
+		queue_work(priv->workqueue, &priv->rf_kill);
 
-		if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
-			IWL_DEBUG_RF_KILL("Can not turn radio back on - "
-					  "disabled by SW switch\n");
-		else
-			IWL_WARNING("Radio Frequency Kill Switch is On:\n"
-				    "Kill switch must be turned off for "
-				    "wireless networking to work.\n");
-	}
+	queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+			   round_jiffies_relative(2 * HZ));
 
-	mutex_unlock(&priv->mutex);
-	iwl3945_rfkill_set_hw_state(priv);
 }
 
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl3945_bg_scan_check(struct work_struct *data)
-{
-	struct iwl3945_priv *priv =
-	    container_of(data, struct iwl3945_priv, scan_check.work);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	mutex_lock(&priv->mutex);
-	if (test_bit(STATUS_SCANNING, &priv->status) ||
-	    test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
-			  "Scan completion watchdog resetting adapter (%dms)\n",
-			  jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
-		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-			iwl3945_send_scan_abort(priv);
-	}
-	mutex_unlock(&priv->mutex);
-}
-
 static void iwl3945_bg_request_scan(struct work_struct *data)
 {
-	struct iwl3945_priv *priv =
-	    container_of(data, struct iwl3945_priv, request_scan);
-	struct iwl3945_host_cmd cmd = {
+	struct iwl_priv *priv =
+	    container_of(data, struct iwl_priv, request_scan);
+	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
 		.len = sizeof(struct iwl3945_scan_cmd),
 		.meta.flags = CMD_SIZE_HUGE,
@@ -6061,8 +3291,10 @@ static void iwl3945_bg_request_scan(stru
 
 	mutex_lock(&priv->mutex);
 
-	if (!iwl3945_is_ready(priv)) {
-		IWL_WARNING("request scan called when driver not ready.\n");
+	cancel_delayed_work(&priv->scan_check);
+
+	if (!iwl_is_ready(priv)) {
+		IWL_WARN(priv, "request scan called when driver not ready.\n");
 		goto done;
 	}
 
@@ -6074,34 +3306,36 @@ static void iwl3945_bg_request_scan(stru
 	/* This should never be called or scheduled if there is currently
 	 * a scan active in the hardware. */
 	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
-			       "Ignoring second request.\n");
+		IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests  "
+				"Ignoring second request.\n");
 		rc = -EIO;
 		goto done;
 	}
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
 		goto done;
 	}
 
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC("Scan request while abort pending.  Queuing.\n");
+		IWL_DEBUG_HC(priv,
+			"Scan request while abort pending. Queuing.\n");
 		goto done;
 	}
 
-	if (iwl3945_is_rfkill(priv)) {
-		IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
 		goto done;
 	}
 
 	if (!test_bit(STATUS_READY, &priv->status)) {
-		IWL_DEBUG_HC("Scan request while uninitialized.  Queuing.\n");
+		IWL_DEBUG_HC(priv,
+			"Scan request while uninitialized. Queuing.\n");
 		goto done;
 	}
 
 	if (!priv->scan_bands) {
-		IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+		IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
 		goto done;
 	}
 
@@ -6119,14 +3353,14 @@ static void iwl3945_bg_request_scan(stru
 	scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
 	scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 
-	if (iwl3945_is_associated(priv)) {
+	if (iwl_is_associated(priv)) {
 		u16 interval = 0;
 		u32 extra;
 		u32 suspend_time = 100;
 		u32 scan_suspend_time = 100;
 		unsigned long flags;
 
-		IWL_DEBUG_INFO("Scanning while associated...\n");
+		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 
 		spin_lock_irqsave(&priv->lock, flags);
 		interval = priv->beacon_int;
@@ -6148,15 +3382,14 @@ static void iwl3945_bg_request_scan(stru
 		    (extra | ((suspend_time % interval) * 1024));
 
 		scan->suspend_time = cpu_to_le32(scan_suspend_time);
-		IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+		IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
 			       scan_suspend_time, interval);
 	}
 
 	/* We should add the ability for user to lock to PASSIVE ONLY */
 	if (priv->one_direct_scan) {
-		IWL_DEBUG_SCAN
-		    ("Kicking off one direct scan for '%s'\n",
-		     print_ssid(ssid, priv->direct_ssid,
+		IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
+				print_ssid(ssid, priv->direct_ssid,
 				priv->direct_ssid_len));
 		scan->direct_scan[0].id = WLAN_EID_SSID;
 		scan->direct_scan[0].len = priv->direct_ssid_len;
@@ -6164,15 +3397,12 @@ static void iwl3945_bg_request_scan(stru
 		       priv->direct_ssid, priv->direct_ssid_len);
 		n_probes++;
 	} else
-		IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
+		IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
 
 	/* We don't build a direct scan probe request; the uCode will do
 	 * that based on the direct_mask added to each channel entry */
-	scan->tx_cmd.len = cpu_to_le16(
-		iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
-			IWL_MAX_SCAN_SIZE - sizeof(*scan)));
 	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-	scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
+	scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
 	scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
 	/* flags + rate selection */
@@ -6187,10 +3417,15 @@ static void iwl3945_bg_request_scan(stru
 		scan->good_CRC_th = IWL_GOOD_CRC_TH;
 		band = IEEE80211_BAND_5GHZ;
 	} else {
-		IWL_WARNING("Invalid scan band count\n");
+		IWL_WARN(priv, "Invalid scan band count\n");
 		goto done;
 	}
 
+	scan->tx_cmd.len = cpu_to_le16(
+		iwl_fill_probe_req(priv, band,
+				   (struct ieee80211_mgmt *)scan->data,
+				   IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+
 	/* select Rx antennas */
 	scan->flags |= iwl3945_get_antenna_flags(priv);
 
@@ -6203,7 +3438,7 @@ static void iwl3945_bg_request_scan(stru
 			(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
 	if (scan->channel_count == 0) {
-		IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
 		goto done;
 	}
 
@@ -6213,7 +3448,7 @@ static void iwl3945_bg_request_scan(stru
 	scan->len = cpu_to_le16(cmd.len);
 
 	set_bit(STATUS_SCAN_HW, &priv->status);
-	rc = iwl3945_send_cmd_sync(priv, &cmd);
+	rc = iwl_send_cmd_sync(priv, &cmd);
 	if (rc)
 		goto done;
 
@@ -6239,7 +3474,7 @@ static void iwl3945_bg_request_scan(stru
 
 static void iwl3945_bg_up(struct work_struct *data)
 {
-	struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up);
+	struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -6247,12 +3482,12 @@ static void iwl3945_bg_up(struct work_st
 	mutex_lock(&priv->mutex);
 	__iwl3945_up(priv);
 	mutex_unlock(&priv->mutex);
-	iwl3945_rfkill_set_hw_state(priv);
+	iwl_rfkill_set_hw_state(priv);
 }
 
 static void iwl3945_bg_restart(struct work_struct *data)
 {
-	struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart);
+	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -6263,8 +3498,8 @@ static void iwl3945_bg_restart(struct wo
 
 static void iwl3945_bg_rx_replenish(struct work_struct *data)
 {
-	struct iwl3945_priv *priv =
-	    container_of(data, struct iwl3945_priv, rx_replenish);
+	struct iwl_priv *priv =
+	    container_of(data, struct iwl_priv, rx_replenish);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
@@ -6276,18 +3511,18 @@ static void iwl3945_bg_rx_replenish(stru
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
-static void iwl3945_post_associate(struct iwl3945_priv *priv)
+static void iwl3945_post_associate(struct iwl_priv *priv)
 {
 	int rc = 0;
 	struct ieee80211_conf *conf = NULL;
 
 	if (priv->iw_mode == NL80211_IFTYPE_AP) {
-		IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+		IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
 		return;
 	}
 
 
-	IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+	IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
 			priv->assoc_id, priv->active_rxon.bssid_addr);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -6296,26 +3531,26 @@ static void iwl3945_post_associate(struc
 	if (!priv->vif || !priv->is_open)
 		return;
 
-	iwl3945_scan_cancel_timeout(priv, 200);
+	iwl_scan_cancel_timeout(priv, 200);
 
 	conf = ieee80211_get_hw_conf(priv->hw);
 
 	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	iwl3945_commit_rxon(priv);
 
-	memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+	memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
 	iwl3945_setup_rxon_timing(priv);
-	rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+	rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
 			      sizeof(priv->rxon_timing), &priv->rxon_timing);
 	if (rc)
-		IWL_WARNING("REPLY_RXON_TIMING failed - "
+		IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
 			    "Attempting to continue.\n");
 
 	priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
 	priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
 
-	IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+	IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
 			priv->assoc_id, priv->beacon_int);
 
 	if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -6355,56 +3590,19 @@ static void iwl3945_post_associate(struc
 		break;
 
 	default:
-		 IWL_ERROR("%s Should not be called in %d mode\n",
+		 IWL_ERR(priv, "%s Should not be called in %d mode\n",
 			   __func__, priv->iw_mode);
 		break;
 	}
 
-	iwl3945_activate_qos(priv, 0);
+	iwl_activate_qos(priv, 0);
 
 	/* we have just associated, don't start scan too early */
 	priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
 }
 
-static void iwl3945_bg_abort_scan(struct work_struct *work)
-{
-	struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
-
-	if (!iwl3945_is_ready(priv))
-		return;
-
-	mutex_lock(&priv->mutex);
-
-	set_bit(STATUS_SCAN_ABORTING, &priv->status);
-	iwl3945_send_scan_abort(priv);
-
-	mutex_unlock(&priv->mutex);
-}
-
 static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
 
-static void iwl3945_bg_scan_completed(struct work_struct *work)
-{
-	struct iwl3945_priv *priv =
-	    container_of(work, struct iwl3945_priv, scan_completed);
-
-	IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	if (test_bit(STATUS_CONF_PENDING, &priv->status))
-		iwl3945_mac_config(priv->hw, 0);
-
-	ieee80211_scan_completed(priv->hw);
-
-	/* Since setting the TXPOWER may have been deferred while
-	 * performing the scan, fire one off */
-	mutex_lock(&priv->mutex);
-	iwl3945_hw_reg_send_txpower(priv);
-	mutex_unlock(&priv->mutex);
-}
-
 /*****************************************************************************
  *
  * mac80211 entry point functions
@@ -6415,36 +3613,22 @@ static void iwl3945_bg_scan_completed(st
 
 static int iwl3945_mac_start(struct ieee80211_hw *hw)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	int ret;
 
-	IWL_DEBUG_MAC80211("enter\n");
-
-	if (pci_enable_device(priv->pci_dev)) {
-		IWL_ERROR("Fail to pci_enable_device\n");
-		return -ENODEV;
-	}
-	pci_restore_state(priv->pci_dev);
-	pci_enable_msi(priv->pci_dev);
-
-	ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
-			  DRV_NAME, priv);
-	if (ret) {
-		IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
-		goto out_disable_msi;
-	}
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	/* we should be verifying the device is ready to be opened */
 	mutex_lock(&priv->mutex);
 
-	memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
+	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 	/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
 	 * ucode filename and max sizes are card-specific. */
 
 	if (!priv->ucode_code.len) {
 		ret = iwl3945_read_ucode(priv);
 		if (ret) {
-			IWL_ERROR("Could not read microcode: %d\n", ret);
+			IWL_ERR(priv, "Could not read microcode: %d\n", ret);
 			mutex_unlock(&priv->mutex);
 			goto out_release_irq;
 		}
@@ -6454,12 +3638,12 @@ static int iwl3945_mac_start(struct ieee
 
 	mutex_unlock(&priv->mutex);
 
-	iwl3945_rfkill_set_hw_state(priv);
+	iwl_rfkill_set_hw_state(priv);
 
 	if (ret)
 		goto out_release_irq;
 
-	IWL_DEBUG_INFO("Start UP work.\n");
+	IWL_DEBUG_INFO(priv, "Start UP work.\n");
 
 	if (test_bit(STATUS_IN_SUSPEND, &priv->status))
 		return 0;
@@ -6471,86 +3655,87 @@ static int iwl3945_mac_start(struct ieee
 			UCODE_READY_TIMEOUT);
 	if (!ret) {
 		if (!test_bit(STATUS_READY, &priv->status)) {
-			IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
-				  jiffies_to_msecs(UCODE_READY_TIMEOUT));
+			IWL_ERR(priv,
+				"Wait for START_ALIVE timeout after %dms.\n",
+				jiffies_to_msecs(UCODE_READY_TIMEOUT));
 			ret = -ETIMEDOUT;
 			goto out_release_irq;
 		}
 	}
 
+	/* ucode is running and will send rfkill notifications,
+	 * no need to poll the killswitch state anymore */
+	cancel_delayed_work(&priv->rfkill_poll);
+
 	priv->is_open = 1;
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 
 out_release_irq:
-	free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
-	pci_disable_msi(priv->pci_dev);
-	pci_disable_device(priv->pci_dev);
 	priv->is_open = 0;
-	IWL_DEBUG_MAC80211("leave - failed\n");
+	IWL_DEBUG_MAC80211(priv, "leave - failed\n");
 	return ret;
 }
 
 static void iwl3945_mac_stop(struct ieee80211_hw *hw)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (!priv->is_open) {
-		IWL_DEBUG_MAC80211("leave - skip\n");
+		IWL_DEBUG_MAC80211(priv, "leave - skip\n");
 		return;
 	}
 
 	priv->is_open = 0;
 
-	if (iwl3945_is_ready_rf(priv)) {
+	if (iwl_is_ready_rf(priv)) {
 		/* stop mac, cancel any scan request and clear
 		 * RXON_FILTER_ASSOC_MSK BIT
 		 */
 		mutex_lock(&priv->mutex);
-		iwl3945_scan_cancel_timeout(priv, 100);
+		iwl_scan_cancel_timeout(priv, 100);
 		mutex_unlock(&priv->mutex);
 	}
 
 	iwl3945_down(priv);
 
 	flush_workqueue(priv->workqueue);
-	free_irq(priv->pci_dev->irq, priv);
-	pci_disable_msi(priv->pci_dev);
-	pci_save_state(priv->pci_dev);
-	pci_disable_device(priv->pci_dev);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	/* start polling the killswitch state again */
+	queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+			   round_jiffies_relative(2 * HZ));
+
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+	IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
 	if (iwl3945_tx_skb(priv, skb))
 		dev_kfree_skb_any(skb);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return NETDEV_TX_OK;
 }
 
 static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 				 struct ieee80211_if_init_conf *conf)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
 
-	IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+	IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
 
 	if (priv->vif) {
-		IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+		IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
 		return -EOPNOTSUPP;
 	}
 
@@ -6563,16 +3748,16 @@ static int iwl3945_mac_add_interface(str
 	mutex_lock(&priv->mutex);
 
 	if (conf->mac_addr) {
-		IWL_DEBUG_MAC80211("Set: %pM\n", conf->mac_addr);
+		IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
 		memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
 	}
 
-	if (iwl3945_is_ready(priv))
+	if (iwl_is_ready(priv))
 		iwl3945_set_mode(priv, conf->type);
 
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 }
 
@@ -6585,24 +3770,25 @@ static int iwl3945_mac_add_interface(str
  */
 static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
-	struct iwl3945_priv *priv = hw->priv;
-	const struct iwl3945_channel_info *ch_info;
+	struct iwl_priv *priv = hw->priv;
+	const struct iwl_channel_info *ch_info;
 	struct ieee80211_conf *conf = &hw->conf;
 	unsigned long flags;
 	int ret = 0;
 
 	mutex_lock(&priv->mutex);
-	IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
+	IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
+				conf->channel->hw_value);
 
-	if (!iwl3945_is_ready(priv)) {
-		IWL_DEBUG_MAC80211("leave - not ready\n");
+	if (!iwl_is_ready(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		ret = -EIO;
 		goto out;
 	}
 
-	if (unlikely(!iwl3945_param_disable_hw_scan &&
+	if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
 		     test_bit(STATUS_SCANNING, &priv->status))) {
-		IWL_DEBUG_MAC80211("leave - scanning\n");
+		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
 		set_bit(STATUS_CONF_PENDING, &priv->status);
 		mutex_unlock(&priv->mutex);
 		return 0;
@@ -6610,25 +3796,26 @@ static int iwl3945_mac_config(struct iee
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
-					   conf->channel->hw_value);
+	ch_info = iwl_get_channel_info(priv, conf->channel->band,
+				       conf->channel->hw_value);
 	if (!is_channel_valid(ch_info)) {
-		IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
-			       conf->channel->hw_value, conf->channel->band);
-		IWL_DEBUG_MAC80211("leave - invalid channel\n");
+		IWL_DEBUG_SCAN(priv,
+				"Channel %d [%d] is INVALID for this band.\n",
+				conf->channel->hw_value, conf->channel->band);
+		IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
 		ret = -EINVAL;
 		goto out;
 	}
 
-	iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value);
+	iwl_set_rxon_channel(priv, conf->channel);
 
-	iwl3945_set_flags_for_phymode(priv, conf->channel->band);
+	iwl_set_flags_for_band(priv, conf->channel->band);
 
 	/* The list of supported rates and rate mask can be different
 	 * for each phymode; since the phymode may have changed, reset
 	 * the rate mask to what mac80211 lists */
-	iwl3945_set_rate(priv);
+	iwl_set_rate(priv);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -6639,28 +3826,36 @@ static int iwl3945_mac_config(struct iee
 	}
 #endif
 
-	iwl3945_radio_kill_sw(priv, !conf->radio_enabled);
+	if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+		if (conf->radio_enabled &&
+		    iwl_radio_kill_sw_enable_radio(priv)) {
+			IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
+						 "waiting for uCode\n");
+			goto out;
+		}
 
-	if (!conf->radio_enabled) {
-		IWL_DEBUG_MAC80211("leave - radio disabled\n");
-		goto out;
+		if (!conf->radio_enabled) {
+			iwl_radio_kill_sw_disable_radio(priv);
+			IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
+			goto out;
+		}
 	}
 
-	if (iwl3945_is_rfkill(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF kill\n");
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
 		ret = -EIO;
 		goto out;
 	}
 
-	iwl3945_set_rate(priv);
+	iwl_set_rate(priv);
 
 	if (memcmp(&priv->active_rxon,
 		   &priv->staging_rxon, sizeof(priv->staging_rxon)))
 		iwl3945_commit_rxon(priv);
 	else
-		IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+		IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 out:
 	clear_bit(STATUS_CONF_PENDING, &priv->status);
@@ -6668,7 +3863,7 @@ out:
 	return ret;
 }
 
-static void iwl3945_config_ap(struct iwl3945_priv *priv)
+static void iwl3945_config_ap(struct iwl_priv *priv)
 {
 	int rc = 0;
 
@@ -6676,19 +3871,20 @@ static void iwl3945_config_ap(struct iwl
 		return;
 
 	/* The following should be done only at AP bring up */
-	if (!(iwl3945_is_associated(priv))) {
+	if (!(iwl_is_associated(priv))) {
 
 		/* RXON - unassoc (to set timing command) */
 		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		iwl3945_commit_rxon(priv);
 
 		/* RXON Timing */
-		memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+		memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
 		iwl3945_setup_rxon_timing(priv);
-		rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
-				sizeof(priv->rxon_timing), &priv->rxon_timing);
+		rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+				      sizeof(priv->rxon_timing),
+				      &priv->rxon_timing);
 		if (rc)
-			IWL_WARNING("REPLY_RXON_TIMING failed - "
+			IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
 					"Attempting to continue.\n");
 
 		/* FIXME: what should be the assoc_id for AP? */
@@ -6716,7 +3912,7 @@ static void iwl3945_config_ap(struct iwl
 		/* restore RXON assoc */
 		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		iwl3945_commit_rxon(priv);
-		iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+		iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
 	}
 	iwl3945_send_beacon_cmd(priv);
 
@@ -6727,16 +3923,16 @@ static void iwl3945_config_ap(struct iwl
 
 static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
 					struct ieee80211_vif *vif,
-				    struct ieee80211_if_conf *conf)
+					struct ieee80211_if_conf *conf)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	int rc;
 
 	if (conf == NULL)
 		return -EIO;
 
 	if (priv->vif != vif) {
-		IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+		IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
 		return 0;
 	}
 
@@ -6753,13 +3949,13 @@ static int iwl3945_mac_config_interface(
 			return rc;
 	}
 
-	if (!iwl3945_is_alive(priv))
+	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	mutex_lock(&priv->mutex);
 
 	if (conf->bssid)
-		IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+		IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
 
 /*
  * very dubious code was here; the probe filtering flag is never set:
@@ -6772,7 +3968,7 @@ static int iwl3945_mac_config_interface(
 		if (!conf->bssid) {
 			conf->bssid = priv->mac_addr;
 			memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-			IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+			IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
 					   conf->bssid);
 		}
 		if (priv->ibss_beacon)
@@ -6781,17 +3977,17 @@ static int iwl3945_mac_config_interface(
 		priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
 	}
 
-	if (iwl3945_is_rfkill(priv))
+	if (iwl_is_rfkill(priv))
 		goto done;
 
 	if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
 	    !is_multicast_ether_addr(conf->bssid)) {
 		/* If there is currently a HW scan going on in the background
 		 * then we need to cancel it else the RXON below will fail. */
-		if (iwl3945_scan_cancel_timeout(priv, 100)) {
-			IWL_WARNING("Aborted scan still in progress "
+		if (iwl_scan_cancel_timeout(priv, 100)) {
+			IWL_WARN(priv, "Aborted scan still in progress "
 				    "after 100ms\n");
-			IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+			IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
 			mutex_unlock(&priv->mutex);
 			return -EAGAIN;
 		}
@@ -6813,75 +4009,29 @@ static int iwl3945_mac_config_interface(
 		}
 
 	} else {
-		iwl3945_scan_cancel_timeout(priv, 100);
+		iwl_scan_cancel_timeout(priv, 100);
 		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		iwl3945_commit_rxon(priv);
 	}
 
  done:
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	mutex_unlock(&priv->mutex);
 
 	return 0;
 }
 
-static void iwl3945_configure_filter(struct ieee80211_hw *hw,
-				 unsigned int changed_flags,
-				 unsigned int *total_flags,
-				 int mc_count, struct dev_addr_list *mc_list)
-{
-	struct iwl3945_priv *priv = hw->priv;
-	__le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
-	IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
-			changed_flags, *total_flags);
-
-	if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
-		if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
-			*filter_flags |= RXON_FILTER_PROMISC_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
-	}
-	if (changed_flags & FIF_ALLMULTI) {
-		if (*total_flags & FIF_ALLMULTI)
-			*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
-	}
-	if (changed_flags & FIF_CONTROL) {
-		if (*total_flags & FIF_CONTROL)
-			*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
-	}
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
-			*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
-	}
-
-	/* We avoid iwl_commit_rxon here to commit the new filter flags
-	 * since mac80211 will call ieee80211_hw_config immediately.
-	 * (mc_list is not supported at this time). Otherwise, we need to
-	 * queue a background iwl_commit_rxon work.
-	 */
-
-	*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
-			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
 static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
 				     struct ieee80211_if_init_conf *conf)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	mutex_lock(&priv->mutex);
 
-	if (iwl3945_is_ready_rf(priv)) {
-		iwl3945_scan_cancel_timeout(priv, 100);
+	if (iwl_is_ready_rf(priv)) {
+		iwl_scan_cancel_timeout(priv, 100);
 		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		iwl3945_commit_rxon(priv);
 	}
@@ -6891,7 +4041,7 @@ static void iwl3945_mac_remove_interface
 	}
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@ -6901,21 +4051,23 @@ static void iwl3945_bss_info_changed(str
 				     struct ieee80211_bss_conf *bss_conf,
 				     u32 changes)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+	IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
 
 	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
-		IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+		IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
 				   bss_conf->use_short_preamble);
 		if (bss_conf->use_short_preamble)
 			priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 		else
-			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+			priv->staging_rxon.flags &=
+				~RXON_FLG_SHORT_PREAMBLE_MSK;
 	}
 
 	if (changes & BSS_CHANGED_ERP_CTS_PROT) {
-		IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+		IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n",
+				   bss_conf->use_cts_prot);
 		if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
 			priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
 		else
@@ -6923,7 +4075,7 @@ static void iwl3945_bss_info_changed(str
 	}
 
 	if (changes & BSS_CHANGED_ASSOC) {
-		IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+		IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
 		/* This should never happen as this function should
 		 * never be called from interrupt context. */
 		if (WARN_ON_ONCE(in_interrupt()))
@@ -6931,10 +4083,9 @@ static void iwl3945_bss_info_changed(str
 		if (bss_conf->assoc) {
 			priv->assoc_id = bss_conf->aid;
 			priv->beacon_int = bss_conf->beacon_int;
-			priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
-			priv->timestamp1 = (bss_conf->timestamp >> 32) &
-					     0xFFFFFFFF;
+			priv->timestamp = bss_conf->timestamp;
 			priv->assoc_capability = bss_conf->assoc_capability;
+			priv->power_data.dtim_period = bss_conf->dtim_period;
 			priv->next_scan_jiffies = jiffies +
 					IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
 			mutex_lock(&priv->mutex);
@@ -6942,143 +4093,91 @@ static void iwl3945_bss_info_changed(str
 			mutex_unlock(&priv->mutex);
 		} else {
 			priv->assoc_id = 0;
-			IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+			IWL_DEBUG_MAC80211(priv,
+					"DISASSOC %d\n", bss_conf->assoc);
 		}
-	} else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
-			IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+	} else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+			IWL_DEBUG_MAC80211(priv,
+					"Associated Changes %d\n", changes);
 			iwl3945_send_rxon_assoc(priv);
 	}
 
 }
 
-static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
-	int rc = 0;
-	unsigned long flags;
-	struct iwl3945_priv *priv = hw->priv;
-	DECLARE_SSID_BUF(ssid_buf);
-
-	IWL_DEBUG_MAC80211("enter\n");
-
-	mutex_lock(&priv->mutex);
-	spin_lock_irqsave(&priv->lock, flags);
-
-	if (!iwl3945_is_ready_rf(priv)) {
-		rc = -EIO;
-		IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
-		goto out_unlock;
-	}
-
-	/* we don't schedule scan within next_scan_jiffies period */
-	if (priv->next_scan_jiffies &&
-			time_after(priv->next_scan_jiffies, jiffies)) {
-		rc = -EAGAIN;
-		goto out_unlock;
-	}
-	/* if we just finished scan ask for delay for a broadcast scan */
-	if ((len == 0) && priv->last_scan_jiffies &&
-	    time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
-		       jiffies)) {
-		rc = -EAGAIN;
-		goto out_unlock;
-	}
-	if (len) {
-		IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
-			       print_ssid(ssid_buf, ssid, len), (int)len);
-
-		priv->one_direct_scan = 1;
-		priv->direct_ssid_len = (u8)
-		    min((u8) len, (u8) IW_ESSID_MAX_SIZE);
-		memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-	} else
-		priv->one_direct_scan = 0;
-
-	rc = iwl3945_scan_initiate(priv);
-
-	IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
-	spin_unlock_irqrestore(&priv->lock, flags);
-	mutex_unlock(&priv->mutex);
-
-	return rc;
-}
-
 static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-			   const u8 *local_addr, const u8 *addr,
-			   struct ieee80211_key_conf *key)
+			       struct ieee80211_vif *vif,
+			       struct ieee80211_sta *sta,
+			       struct ieee80211_key_conf *key)
 {
-	struct iwl3945_priv *priv = hw->priv;
-	int rc = 0;
-	u8 sta_id;
+	struct iwl_priv *priv = hw->priv;
+	const u8 *addr;
+	int ret = 0;
+	u8 sta_id = IWL_INVALID_STATION;
+	u8 static_key;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (!iwl3945_param_hwcrypto) {
-		IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+	if (iwl3945_mod_params.sw_crypto) {
+		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
 		return -EOPNOTSUPP;
 	}
 
-	if (is_zero_ether_addr(addr))
-		/* only support pairwise keys */
-		return -EOPNOTSUPP;
+	addr = sta ? sta->addr : iwl_bcast_addr;
+	static_key = !iwl_is_associated(priv);
 
-	sta_id = iwl3945_hw_find_station(priv, addr);
-	if (sta_id == IWL_INVALID_STATION) {
-		IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
-				   addr);
-		return -EINVAL;
+	if (!static_key) {
+		sta_id = iwl3945_hw_find_station(priv, addr);
+		if (sta_id == IWL_INVALID_STATION) {
+			IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
+					    addr);
+			return -EINVAL;
+		}
 	}
 
 	mutex_lock(&priv->mutex);
-
-	iwl3945_scan_cancel_timeout(priv, 100);
+	iwl_scan_cancel_timeout(priv, 100);
+	mutex_unlock(&priv->mutex);
 
 	switch (cmd) {
-	case  SET_KEY:
-		rc = iwl3945_update_sta_key_info(priv, key, sta_id);
-		if (!rc) {
-			iwl3945_set_rxon_hwcrypto(priv, 1);
-			iwl3945_commit_rxon(priv);
-			key->hw_key_idx = sta_id;
-			IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
-			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-		}
+	case SET_KEY:
+		if (static_key)
+			ret = iwl3945_set_static_key(priv, key);
+		else
+			ret = iwl3945_set_dynamic_key(priv, key, sta_id);
+		IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
 		break;
 	case DISABLE_KEY:
-		rc = iwl3945_clear_sta_key_info(priv, sta_id);
-		if (!rc) {
-			iwl3945_set_rxon_hwcrypto(priv, 0);
-			iwl3945_commit_rxon(priv);
-			IWL_DEBUG_MAC80211("disable hwcrypto key\n");
-		}
+		if (static_key)
+			ret = iwl3945_remove_static_key(priv);
+		else
+			ret = iwl3945_clear_sta_key_info(priv, sta_id);
+		IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
 		break;
 	default:
-		rc = -EINVAL;
+		ret = -EINVAL;
 	}
 
-	IWL_DEBUG_MAC80211("leave\n");
-	mutex_unlock(&priv->mutex);
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
-	return rc;
+	return ret;
 }
 
 static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			   const struct ieee80211_tx_queue_params *params)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
 	int q;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (!iwl3945_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
 	if (queue >= AC_NUM) {
-		IWL_DEBUG_MAC80211("leave - queue >= AC_NUM %d\n", queue);
+		IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
 		return 0;
 	}
 
@@ -7099,29 +4198,29 @@ static int iwl3945_mac_conf_tx(struct ie
 
 	mutex_lock(&priv->mutex);
 	if (priv->iw_mode == NL80211_IFTYPE_AP)
-		iwl3945_activate_qos(priv, 1);
-	else if (priv->assoc_id && iwl3945_is_associated(priv))
-		iwl3945_activate_qos(priv, 0);
+		iwl_activate_qos(priv, 1);
+	else if (priv->assoc_id && iwl_is_associated(priv))
+		iwl_activate_qos(priv, 0);
 
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 }
 
 static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
 				struct ieee80211_tx_queue_stats *stats)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	int i, avail;
-	struct iwl3945_tx_queue *txq;
-	struct iwl3945_queue *q;
+	struct iwl_tx_queue *txq;
+	struct iwl_queue *q;
 	unsigned long flags;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (!iwl3945_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
@@ -7130,7 +4229,7 @@ static int iwl3945_mac_get_tx_stats(stru
 	for (i = 0; i < AC_NUM; i++) {
 		txq = &priv->txq[i];
 		q = &txq->q;
-		avail = iwl3945_queue_space(q);
+		avail = iwl_queue_space(q);
 
 		stats[i].len = q->n_window - avail;
 		stats[i].limit = q->n_window - q->high_mark;
@@ -7139,34 +4238,24 @@ static int iwl3945_mac_get_tx_stats(stru
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_MAC80211("leave\n");
-
-	return 0;
-}
-
-static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
-			     struct ieee80211_low_level_stats *stats)
-{
-	IWL_DEBUG_MAC80211("enter\n");
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 	return 0;
 }
 
 static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
 
 	mutex_lock(&priv->mutex);
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	iwl3945_reset_qos(priv);
+	iwl_reset_qos(priv);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->assoc_id = 0;
 	priv->assoc_capability = 0;
-	priv->call_post_assoc_from_beacon = 0;
 
 	/* new association get rid of ibss beacon skb */
 	if (priv->ibss_beacon)
@@ -7175,15 +4264,14 @@ static void iwl3945_mac_reset_tsf(struct
 	priv->ibss_beacon = NULL;
 
 	priv->beacon_int = priv->hw->conf.beacon_int;
-	priv->timestamp1 = 0;
-	priv->timestamp0 = 0;
+	priv->timestamp = 0;
 	if ((priv->iw_mode == NL80211_IFTYPE_STATION))
 		priv->beacon_int = 0;
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (!iwl3945_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - not ready\n");
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		mutex_unlock(&priv->mutex);
 		return;
 	}
@@ -7192,7 +4280,7 @@ static void iwl3945_mac_reset_tsf(struct
 	 * clear RXON_FILTER_ASSOC_MSK bit
 	*/
 	if (priv->iw_mode != NL80211_IFTYPE_AP) {
-		iwl3945_scan_cancel_timeout(priv, 100);
+		iwl_scan_cancel_timeout(priv, 100);
 		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		iwl3945_commit_rxon(priv);
 	}
@@ -7200,33 +4288,34 @@ static void iwl3945_mac_reset_tsf(struct
 	/* Per mac80211.h: This is only used in IBSS mode... */
 	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
 
-		IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+		IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
 		mutex_unlock(&priv->mutex);
 		return;
 	}
 
-	iwl3945_set_rate(priv);
+	iwl_set_rate(priv);
 
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 }
 
 static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
+	__le64 timestamp;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (!iwl3945_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+	if (!iwl_is_ready_rf(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
 	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-		IWL_DEBUG_MAC80211("leave - not IBSS\n");
+		IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
 		return -EIO;
 	}
 
@@ -7238,11 +4327,13 @@ static int iwl3945_mac_beacon_update(str
 	priv->ibss_beacon = skb;
 
 	priv->assoc_id = 0;
+	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+	priv->timestamp = le64_to_cpu(timestamp);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	iwl3945_reset_qos(priv);
+	iwl_reset_qos(priv);
 
 	iwl3945_post_associate(priv);
 
@@ -7256,7 +4347,7 @@ static int iwl3945_mac_beacon_update(str
  *
  *****************************************************************************/
 
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 
 /*
  * The following adds a new attribute to the sysfs representation
@@ -7265,38 +4356,41 @@ static int iwl3945_mac_beacon_update(str
  *
  * See the level definitions in iwl for details.
  */
-
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
+static ssize_t show_debug_level(struct device *d,
+				struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "0x%08X\n", iwl3945_debug_level);
+	struct iwl_priv *priv = d->driver_data;
+
+	return sprintf(buf, "0x%08X\n", priv->debug_level);
 }
-static ssize_t store_debug_level(struct device_driver *d,
+static ssize_t store_debug_level(struct device *d,
+				struct device_attribute *attr,
 				 const char *buf, size_t count)
 {
-	char *p = (char *)buf;
-	u32 val;
+	struct iwl_priv *priv = d->driver_data;
+	unsigned long val;
+	int ret;
 
-	val = simple_strtoul(p, &p, 0);
-	if (p == buf)
-		printk(KERN_INFO DRV_NAME
-		       ": %s is not in hex or decimal form.\n", buf);
+	ret = strict_strtoul(buf, 0, &val);
+	if (ret)
+		IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
 	else
-		iwl3945_debug_level = val;
+		priv->debug_level = val;
 
 	return strnlen(buf, count);
 }
 
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
-		   show_debug_level, store_debug_level);
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+			show_debug_level, store_debug_level);
 
-#endif /* CONFIG_IWL3945_DEBUG */
+#endif /* CONFIG_IWLWIFI_DEBUG */
 
 static ssize_t show_temperature(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 
-	if (!iwl3945_is_alive(priv))
+	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv));
@@ -7307,22 +4401,21 @@ static DEVICE_ATTR(temperature, S_IRUGO,
 static ssize_t show_tx_power(struct device *d,
 			     struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
-	return sprintf(buf, "%d\n", priv->user_txpower_limit);
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+	return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
 }
 
 static ssize_t store_tx_power(struct device *d,
 			      struct device_attribute *attr,
 			      const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 	char *p = (char *)buf;
 	u32 val;
 
 	val = simple_strtoul(p, &p, 10);
 	if (p == buf)
-		printk(KERN_INFO DRV_NAME
-		       ": %s is not in decimal form.\n", buf);
+		IWL_INFO(priv, ": %s is not in decimal form.\n", buf);
 	else
 		iwl3945_hw_reg_set_txpower(priv, val);
 
@@ -7334,7 +4427,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S
 static ssize_t show_flags(struct device *d,
 			  struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 
 	return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -7343,16 +4436,16 @@ static ssize_t store_flags(struct device
 			   struct device_attribute *attr,
 			   const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 	u32 flags = simple_strtoul(buf, NULL, 0);
 
 	mutex_lock(&priv->mutex);
 	if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
 		/* Cancel any currently running scans... */
-		if (iwl3945_scan_cancel_timeout(priv, 100))
-			IWL_WARNING("Could not cancel scan.\n");
+		if (iwl_scan_cancel_timeout(priv, 100))
+			IWL_WARN(priv, "Could not cancel scan.\n");
 		else {
-			IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
+			IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
 				       flags);
 			priv->staging_rxon.flags = cpu_to_le32(flags);
 			iwl3945_commit_rxon(priv);
@@ -7368,7 +4461,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IR
 static ssize_t show_filter_flags(struct device *d,
 				 struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 
 	return sprintf(buf, "0x%04X\n",
 		le32_to_cpu(priv->active_rxon.filter_flags));
@@ -7378,16 +4471,16 @@ static ssize_t store_filter_flags(struct
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
 	u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
 	mutex_lock(&priv->mutex);
 	if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
 		/* Cancel any currently running scans... */
-		if (iwl3945_scan_cancel_timeout(priv, 100))
-			IWL_WARNING("Could not cancel scan.\n");
+		if (iwl_scan_cancel_timeout(priv, 100))
+			IWL_WARN(priv, "Could not cancel scan.\n");
 		else {
-			IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+			IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
 				       "0x%04X\n", filter_flags);
 			priv->staging_rxon.filter_flags =
 				cpu_to_le32(filter_flags);
@@ -7407,8 +4500,8 @@ static DEVICE_ATTR(filter_flags, S_IWUSR
 static ssize_t show_measurement(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
-	struct iwl3945_spectrum_notification measure_report;
+	struct iwl_priv *priv = dev_get_drvdata(d);
+	struct iwl_spectrum_notification measure_report;
 	u32 size = sizeof(measure_report), len = 0, ofs = 0;
 	u8 *data = (u8 *)&measure_report;
 	unsigned long flags;
@@ -7440,7 +4533,7 @@ static ssize_t store_measurement(struct
 				 struct device_attribute *attr,
 				 const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
+	struct iwl_priv *priv = dev_get_drvdata(d);
 	struct ieee80211_measurement_params params = {
 		.channel = le16_to_cpu(priv->active_rxon.channel),
 		.start_time = cpu_to_le64(priv->last_tsf),
@@ -7464,7 +4557,7 @@ static ssize_t store_measurement(struct
 			type = simple_strtoul(p + 1, NULL, 0);
 	}
 
-	IWL_DEBUG_INFO("Invoking measurement of type %d on "
+	IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on "
 		       "channel %d (for '%s')\n", type, params.channel, buf);
 	iwl3945_get_measurement(priv, &params, type);
 
@@ -7479,7 +4572,7 @@ static ssize_t store_retry_rate(struct d
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
+	struct iwl_priv *priv = dev_get_drvdata(d);
 
 	priv->retry_rate = simple_strtoul(buf, NULL, 0);
 	if (priv->retry_rate <= 0)
@@ -7491,50 +4584,72 @@ static ssize_t store_retry_rate(struct d
 static ssize_t show_retry_rate(struct device *d,
 			       struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
+	struct iwl_priv *priv = dev_get_drvdata(d);
 	return sprintf(buf, "%d", priv->retry_rate);
 }
 
 static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
 		   store_retry_rate);
 
+
 static ssize_t store_power_level(struct device *d,
 				 struct device_attribute *attr,
 				 const char *buf, size_t count)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
-	int rc;
-	int mode;
+	struct iwl_priv *priv = dev_get_drvdata(d);
+	int ret;
+	unsigned long mode;
+
 
-	mode = simple_strtoul(buf, NULL, 0);
 	mutex_lock(&priv->mutex);
 
-	if (!iwl3945_is_ready(priv)) {
-		rc = -EAGAIN;
+	ret = strict_strtoul(buf, 10, &mode);
+	if (ret)
 		goto out;
-	}
-
-	if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC))
-		mode = IWL_POWER_AC;
-	else
-		mode |= IWL_POWER_ENABLED;
 
-	if (mode != priv->power_mode) {
-		rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode));
-		if (rc) {
-			IWL_DEBUG_MAC80211("failed setting power mode.\n");
-			goto out;
-		}
-		priv->power_mode = mode;
+	ret = iwl_power_set_user_mode(priv, mode);
+	if (ret) {
+		IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
+		goto out;
 	}
-
-	rc = count;
+	ret = count;
 
  out:
 	mutex_unlock(&priv->mutex);
-	return rc;
+	return ret;
 }
 
+static ssize_t show_power_level(struct device *d,
+				struct device_attribute *attr, char *buf)
+{
+	struct iwl_priv *priv = dev_get_drvdata(d);
+	int mode = priv->power_data.user_power_setting;
+	int system = priv->power_data.system_power_setting;
+	int level = priv->power_data.power_mode;
+	char *p = buf;
+
+	switch (system) {
+	case IWL_POWER_SYS_AUTO:
+		p += sprintf(p, "SYSTEM:auto");
+		break;
+	case IWL_POWER_SYS_AC:
+		p += sprintf(p, "SYSTEM:ac");
+		break;
+	case IWL_POWER_SYS_BATTERY:
+		p += sprintf(p, "SYSTEM:battery");
+		break;
+	}
+
+	p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
+			"fixed" : "auto");
+	p += sprintf(p, "\tINDEX:%d", level);
+	p += sprintf(p, "\n");
+	return p - buf + 1;
+}
+
+static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
+		   show_power_level, store_power_level);
+
 #define MAX_WX_STRING 80
 
 /* Values are in microsecond */
@@ -7553,41 +4668,6 @@ static const s32 period_duration[] = {
 	1000000
 };
 
-static ssize_t show_power_level(struct device *d,
-				struct device_attribute *attr, char *buf)
-{
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
-	int level = IWL_POWER_LEVEL(priv->power_mode);
-	char *p = buf;
-
-	p += sprintf(p, "%d ", level);
-	switch (level) {
-	case IWL_POWER_MODE_CAM:
-	case IWL_POWER_AC:
-		p += sprintf(p, "(AC)");
-		break;
-	case IWL_POWER_BATTERY:
-		p += sprintf(p, "(BATTERY)");
-		break;
-	default:
-		p += sprintf(p,
-			     "(Timeout %dms, Period %dms)",
-			     timeout_duration[level - 1] / 1000,
-			     period_duration[level - 1] / 1000);
-	}
-
-	if (!(priv->power_mode & IWL_POWER_ENABLED))
-		p += sprintf(p, " OFF\n");
-	else
-		p += sprintf(p, " \n");
-
-	return p - buf + 1;
-
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
-		   store_power_level);
-
 static ssize_t show_channels(struct device *d,
 			     struct device_attribute *attr, char *buf)
 {
@@ -7600,17 +4680,17 @@ static DEVICE_ATTR(channels, S_IRUSR, sh
 static ssize_t show_statistics(struct device *d,
 			       struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
+	struct iwl_priv *priv = dev_get_drvdata(d);
 	u32 size = sizeof(struct iwl3945_notif_statistics);
 	u32 len = 0, ofs = 0;
-	u8 *data = (u8 *)&priv->statistics;
+	u8 *data = (u8 *)&priv->statistics_39;
 	int rc = 0;
 
-	if (!iwl3945_is_alive(priv))
+	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
 	mutex_lock(&priv->mutex);
-	rc = iwl3945_send_statistics_request(priv);
+	rc = iwl_send_statistics_request(priv, 0);
 	mutex_unlock(&priv->mutex);
 
 	if (rc) {
@@ -7638,34 +4718,34 @@ static DEVICE_ATTR(statistics, S_IRUGO,
 static ssize_t show_antenna(struct device *d,
 			    struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
+	struct iwl_priv *priv = dev_get_drvdata(d);
 
-	if (!iwl3945_is_alive(priv))
+	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 
-	return sprintf(buf, "%d\n", priv->antenna);
+	return sprintf(buf, "%d\n", iwl3945_mod_params.antenna);
 }
 
 static ssize_t store_antenna(struct device *d,
 			     struct device_attribute *attr,
 			     const char *buf, size_t count)
 {
+	struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d);
 	int ant;
-	struct iwl3945_priv *priv = dev_get_drvdata(d);
 
 	if (count == 0)
 		return 0;
 
 	if (sscanf(buf, "%1i", &ant) != 1) {
-		IWL_DEBUG_INFO("not in hex or decimal form.\n");
+		IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n");
 		return count;
 	}
 
 	if ((ant >= 0) && (ant <= 2)) {
-		IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
-		priv->antenna = (enum iwl3945_antenna)ant;
+		IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant);
+		iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant;
 	} else
-		IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
+		IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant);
 
 
 	return count;
@@ -7676,8 +4756,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_
 static ssize_t show_status(struct device *d,
 			   struct device_attribute *attr, char *buf)
 {
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
-	if (!iwl3945_is_alive(priv))
+	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+	if (!iwl_is_alive(priv))
 		return -EAGAIN;
 	return sprintf(buf, "0x%08x\n", (int)priv->status);
 }
@@ -7691,7 +4771,7 @@ static ssize_t dump_error_log(struct dev
 	char *p = (char *)buf;
 
 	if (p[0] == '1')
-		iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data);
+		iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
 
 	return strnlen(buf, count);
 }
@@ -7705,7 +4785,7 @@ static ssize_t dump_event_log(struct dev
 	char *p = (char *)buf;
 
 	if (p[0] == '1')
-		iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data);
+		iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
 
 	return strnlen(buf, count);
 }
@@ -7718,23 +4798,24 @@ static DEVICE_ATTR(dump_events, S_IWUSR,
  *
  *****************************************************************************/
 
-static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
 {
-	priv->workqueue = create_workqueue(DRV_NAME);
+	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
 
 	init_waitqueue_head(&priv->wait_command_queue);
 
 	INIT_WORK(&priv->up, iwl3945_bg_up);
 	INIT_WORK(&priv->restart, iwl3945_bg_restart);
 	INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
-	INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed);
-	INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
-	INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
-	INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
+	INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
 	INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
 	INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
 	INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
-	INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
+	INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
+	INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+	INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+	INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+	INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
 
 	iwl3945_hw_setup_deferred_work(priv);
 
@@ -7742,7 +4823,7 @@ static void iwl3945_setup_deferred_work(
 		     iwl3945_irq_tasklet, (unsigned long)priv);
 }
 
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
 {
 	iwl3945_hw_cancel_deferred_work(priv);
 
@@ -7768,7 +4849,9 @@ static struct attribute *iwl3945_sysfs_e
 	&dev_attr_status.attr,
 	&dev_attr_temperature.attr,
 	&dev_attr_tx_power.attr,
-
+#ifdef CONFIG_IWLWIFI_DEBUG
+	&dev_attr_debug_level.attr,
+#endif
 	NULL
 };
 
@@ -7785,83 +4868,181 @@ static struct ieee80211_ops iwl3945_hw_o
 	.remove_interface = iwl3945_mac_remove_interface,
 	.config = iwl3945_mac_config,
 	.config_interface = iwl3945_mac_config_interface,
-	.configure_filter = iwl3945_configure_filter,
+	.configure_filter = iwl_configure_filter,
 	.set_key = iwl3945_mac_set_key,
-	.get_stats = iwl3945_mac_get_stats,
 	.get_tx_stats = iwl3945_mac_get_tx_stats,
 	.conf_tx = iwl3945_mac_conf_tx,
 	.reset_tsf = iwl3945_mac_reset_tsf,
 	.bss_info_changed = iwl3945_bss_info_changed,
-	.hw_scan = iwl3945_mac_hw_scan
+	.hw_scan = iwl_mac_hw_scan
 };
 
-static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl3945_init_drv(struct iwl_priv *priv)
 {
-	int err = 0;
-	struct iwl3945_priv *priv;
-	struct ieee80211_hw *hw;
-	struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
-	unsigned long flags;
+	int ret;
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 
-	/***********************
-	 * 1. Allocating HW data
-	 * ********************/
+	priv->retry_rate = 1;
+	priv->ibss_beacon = NULL;
 
-	/* Disabling hardware scan means that mac80211 will perform scans
-	 * "the hard way", rather than using device's scan. */
-	if (iwl3945_param_disable_hw_scan) {
-		IWL_DEBUG_INFO("Disabling hw_scan\n");
-		iwl3945_hw_ops.hw_scan = NULL;
+	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->power_data.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 */
+	iwl3945_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;
+
+	iwl_reset_qos(priv);
+
+	priv->qos_data.qos_active = 0;
+	priv->qos_data.qos_cap.val = 0;
+
+	priv->rates_mask = IWL_RATES_MASK;
+	/* If power management is turned on, default to CAM mode */
+	priv->power_mode = IWL_POWER_MODE_CAM;
+	priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+
+	if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
+		IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
+			 eeprom->version);
+		ret = -EINVAL;
+		goto err;
+	}
+	ret = iwl_init_channel_map(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+		goto err;
 	}
 
-	if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) ||
-	    (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) {
-		IWL_ERROR("invalid queues_num, should be between %d and %d\n",
-			  IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
-		err = -EINVAL;
-		goto out;
+	/* Set up txpower settings in driver for all channels */
+	if (iwl3945_txpower_set_from_eeprom(priv)) {
+		ret = -EIO;
+		goto err_free_channel_map;
 	}
 
-	/* mac80211 allocates memory for this device instance, including
-	 *   space for this driver's private structure */
-	hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops);
-	if (hw == NULL) {
-		IWL_ERROR("Can not allocate network device\n");
-		err = -ENOMEM;
-		goto out;
+	ret = iwlcore_init_geos(priv);
+	if (ret) {
+		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+		goto err_free_channel_map;
 	}
+	iwl3945_init_hw_rates(priv, priv->ieee_rates);
 
-	SET_IEEE80211_DEV(hw, &pdev->dev);
+	return 0;
 
-	priv = hw->priv;
-	priv->hw = hw;
-	priv->pci_dev = pdev;
-	priv->cfg = cfg;
+err_free_channel_map:
+	iwl_free_channel_map(priv);
+err:
+	return ret;
+}
+
+static int iwl3945_setup_mac(struct iwl_priv *priv)
+{
+	int ret;
+	struct ieee80211_hw *hw = priv->hw;
 
-	IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
 	hw->rate_control_algorithm = "iwl-3945-rs";
 	hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
 
-	/* Select antenna (may be helpful if only one antenna is connected) */
-	priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
-#ifdef CONFIG_IWL3945_DEBUG
-	iwl3945_debug_level = iwl3945_param_debug;
-	atomic_set(&priv->restrict_refcnt, 0);
-#endif
-
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		    IEEE80211_HW_NOISE_DBM;
+		    IEEE80211_HW_NOISE_DBM |
+		    IEEE80211_HW_SPECTRUM_MGMT;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->wiphy->fw_handles_regulatory = true;
+	hw->wiphy->custom_regulatory = true;
 
-	/* 4 EDCA QOS priorities */
+	hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+
+	/* Default value; 4 EDCA QOS priorities */
 	hw->queues = 4;
 
+	hw->conf.beacon_int = 100;
+
+	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 iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int err = 0;
+	struct iwl_priv *priv;
+	struct ieee80211_hw *hw;
+	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+	struct iwl3945_eeprom *eeprom;
+	unsigned long flags;
+
+	/***********************
+	 * 1. Allocating HW data
+	 * ********************/
+
+	/* mac80211 allocates memory for this device instance, including
+	 *   space for this driver's private structure */
+	hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+	if (hw == NULL) {
+		printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
+		err = -ENOMEM;
+		goto out;
+	}
+	priv = hw->priv;
+	SET_IEEE80211_DEV(hw, &pdev->dev);
+
+	if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
+	     (iwl3945_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, IWL39_MAX_NUM_QUEUES);
+		err = -EINVAL;
+		goto out_ieee80211_free_hw;
+	}
+
+	/*
+	 * Disabling hardware scan means that mac80211 will perform scans
+	 * "the hard way", rather than using device's scan.
+	 */
+	if (iwl3945_mod_params.disable_hw_scan) {
+		IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
+		iwl3945_hw_ops.hw_scan = NULL;
+	}
+
+
+	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
+	priv->cfg = cfg;
+	priv->pci_dev = pdev;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+	priv->debug_level = iwl3945_mod_params.debug;
+	atomic_set(&priv->restrict_refcnt, 0);
+#endif
+
 	/***************************
 	 * 2. Initializing PCI bus
 	 * *************************/
@@ -7872,11 +5053,11 @@ static int iwl3945_pci_probe(struct pci_
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (!err)
-		err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (err) {
-		printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
+		IWL_WARN(priv, "No suitable DMA available.\n");
 		goto out_pci_disable_device;
 	}
 
@@ -7894,98 +5075,58 @@ static int iwl3945_pci_probe(struct pci_
 		goto out_pci_release_regions;
 	}
 
-	IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+	IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
 			(unsigned long long) pci_resource_len(pdev, 0));
-	IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+	IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
 
 	/* We disable the RETRY_TIMEOUT register (0x41) to keep
 	 * PCI Tx retries from interfering with C3 CPU state */
 	pci_write_config_byte(pdev, 0x41, 0x00);
 
-	/* nic init */
-	iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-	err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
-				CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+	/* amp init */
+	err = priv->cfg->ops->lib->apm_ops.init(priv);
 	if (err < 0) {
-		IWL_DEBUG_INFO("Failed to init the card\n");
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 		goto out_iounmap;
 	}
 
 	/***********************
 	 * 4. Read EEPROM
 	 * ********************/
+
 	/* Read the EEPROM */
-	err = iwl3945_eeprom_init(priv);
+	err = iwl_eeprom_init(priv);
 	if (err) {
-		IWL_ERROR("Unable to init EEPROM\n");
+		IWL_ERR(priv, "Unable to init EEPROM\n");
 		goto out_iounmap;
 	}
 	/* MAC Address location in EEPROM same for 3945/4965 */
-	get_eeprom_mac(priv, priv->mac_addr);
-	IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+	eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+	memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN);
+	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
 	SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
 	/***********************
 	 * 5. Setup HW Constants
 	 * ********************/
 	/* Device-specific setup */
-	if (iwl3945_hw_set_hw_setting(priv)) {
-		IWL_ERROR("failed to set hw settings\n");
-		goto out_iounmap;
+	if (iwl3945_hw_set_hw_params(priv)) {
+		IWL_ERR(priv, "failed to set hw settings\n");
+		goto out_eeprom_free;
 	}
 
 	/***********************
 	 * 6. Setup priv
 	 * ********************/
-	priv->retry_rate = 1;
-	priv->ibss_beacon = NULL;
-
-	spin_lock_init(&priv->lock);
-	spin_lock_init(&priv->power_data.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 */
-	iwl3945_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;
-
-	iwl3945_reset_qos(priv);
-
-	priv->qos_data.qos_active = 0;
-	priv->qos_data.qos_cap.val = 0;
-
-
-	priv->rates_mask = IWL_RATES_MASK;
-	/* If power management is turned on, default to AC mode */
-	priv->power_mode = IWL_POWER_AC;
-	priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
-
-	err = iwl3945_init_channel_map(priv);
-	if (err) {
-		IWL_ERROR("initializing regulatory failed: %d\n", err);
-		goto out_unset_hw_setting;
-	}
-
-	err = iwl3945_init_geos(priv);
+	err = iwl3945_init_drv(priv);
 	if (err) {
-		IWL_ERROR("initializing geos failed: %d\n", err);
-		goto out_free_channel_map;
+		IWL_ERR(priv, "initializing driver failed\n");
+		goto out_unset_hw_params;
 	}
 
-	printk(KERN_INFO DRV_NAME
-		": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+	IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
+		priv->cfg->name);
 
 	/***********************************
 	 * 7. Initialize Module Parameters
@@ -7993,9 +5134,9 @@ static int iwl3945_pci_probe(struct pci_
 
 	/* Initialize module parameter values here */
 	/* Disable radio (SW RF KILL) via parameter when loading driver */
-	if (iwl3945_param_disable) {
+	if (iwl3945_mod_params.disable) {
 		set_bit(STATUS_RF_KILL_SW, &priv->status);
-		IWL_DEBUG_INFO("Radio disabled.\n");
+		IWL_DEBUG_INFO(priv, "Radio disabled.\n");
 	}
 
 
@@ -8004,43 +5145,49 @@ static int iwl3945_pci_probe(struct pci_
 	 * ********************/
 
 	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_disable_interrupts(priv);
+	iwl_disable_interrupts(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	pci_enable_msi(priv->pci_dev);
+
+	err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+			  DRV_NAME, priv);
+	if (err) {
+		IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+		goto out_disable_msi;
+	}
+
 	err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 	if (err) {
-		IWL_ERROR("failed to create sysfs device attributes\n");
-		goto out_free_geos;
+		IWL_ERR(priv, "failed to create sysfs device attributes\n");
+		goto out_release_irq;
 	}
 
-	iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+	iwl_set_rxon_channel(priv,
+			     &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
 	iwl3945_setup_deferred_work(priv);
 	iwl3945_setup_rx_handlers(priv);
 
-	/***********************
-	 * 9. Conclude
-	 * ********************/
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-
 	/*********************************
-	 * 10. Setup and Register mac80211
+	 * 9. Setup and Register mac80211
 	 * *******************************/
 
-	err = ieee80211_register_hw(priv->hw);
-	if (err) {
-		IWL_ERROR("Failed to register network device (error %d)\n", err);
-		goto  out_remove_sysfs;
-	}
-
-	priv->hw->conf.beacon_int = 100;
-	priv->mac80211_registered = 1;
+	iwl_enable_interrupts(priv);
 
+	err = iwl3945_setup_mac(priv);
+	if (err)
+		goto  out_remove_sysfs;
 
-	err = iwl3945_rfkill_init(priv);
+	err = iwl_rfkill_init(priv);
 	if (err)
-		IWL_ERROR("Unable to initialize RFKILL system. "
+		IWL_ERR(priv, "Unable to initialize RFKILL system. "
 				  "Ignoring error: %d\n", err);
+	else
+		iwl_rfkill_set_hw_state(priv);
+
+	/* Start monitoring the killswitch */
+	queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+			   2 * HZ);
 
 	return 0;
 
@@ -8048,12 +5195,16 @@ static int iwl3945_pci_probe(struct pci_
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 	sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- out_free_geos:
-	iwl3945_free_geos(priv);
- out_free_channel_map:
-	iwl3945_free_channel_map(priv);
- out_unset_hw_setting:
-	iwl3945_unset_hw_setting(priv);
+ out_release_irq:
+	free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+	pci_disable_msi(priv->pci_dev);
+	iwlcore_free_geos(priv);
+	iwl_free_channel_map(priv);
+ out_unset_hw_params:
+	iwl3945_unset_hw_params(priv);
+ out_eeprom_free:
+	iwl_eeprom_free(priv);
  out_iounmap:
 	pci_iounmap(pdev, priv->hw_base);
  out_pci_release_regions:
@@ -8069,42 +5220,46 @@ static int iwl3945_pci_probe(struct pci_
 
 static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 {
-	struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+	struct iwl_priv *priv = pci_get_drvdata(pdev);
 	unsigned long flags;
 
 	if (!priv)
 		return;
 
-	IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+	IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
 	set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	iwl3945_down(priv);
+	if (priv->mac80211_registered) {
+		ieee80211_unregister_hw(priv->hw);
+		priv->mac80211_registered = 0;
+	} else {
+		iwl3945_down(priv);
+	}
 
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
 	 */
 	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_disable_interrupts(priv);
+	iwl_disable_interrupts(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	iwl_synchronize_irq(priv);
 
 	sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
-	iwl3945_rfkill_unregister(priv);
+	iwl_rfkill_unregister(priv);
+	cancel_delayed_work_sync(&priv->rfkill_poll);
+
 	iwl3945_dealloc_ucode_pci(priv);
 
 	if (priv->rxq.bd)
 		iwl3945_rx_queue_free(priv, &priv->rxq);
 	iwl3945_hw_txq_ctx_free(priv);
 
-	iwl3945_unset_hw_setting(priv);
+	iwl3945_unset_hw_params(priv);
 	iwl3945_clear_stations_table(priv);
 
-	if (priv->mac80211_registered)
-		ieee80211_unregister_hw(priv->hw);
-
 	/*netif_stop_queue(dev); */
 	flush_workqueue(priv->workqueue);
 
@@ -8114,13 +5269,16 @@ static void __devexit iwl3945_pci_remove
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 
+	free_irq(pdev->irq, priv);
+	pci_disable_msi(pdev);
+
 	pci_iounmap(pdev, priv->hw_base);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 
-	iwl3945_free_channel_map(priv);
-	iwl3945_free_geos(priv);
+	iwl_free_channel_map(priv);
+	iwlcore_free_geos(priv);
 	kfree(priv->scan);
 	if (priv->ibss_beacon)
 		dev_kfree_skb(priv->ibss_beacon);
@@ -8132,27 +5290,15 @@ static void __devexit iwl3945_pci_remove
 
 static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+	struct iwl_priv *priv = pci_get_drvdata(pdev);
 
 	if (priv->is_open) {
 		set_bit(STATUS_IN_SUSPEND, &priv->status);
 		iwl3945_mac_stop(priv->hw);
 		priv->is_open = 1;
 	}
-
-	/* pci driver assumes state will be saved in this function.
-	 * pci state is saved and device disabled when interface is
-	 * stopped, so at this time pci device will always be disabled -
-	 * whether interface was started or not. saving pci state now will
-	 * cause saved state be that of a disabled device, which will cause
-	 * problems during resume in that we will end up with a disabled device.
-	 *
-	 * indicate that the current saved state (from when interface was
-	 * stopped) is valid. if interface was never up at time of suspend
-	 * then the saved state will still be valid as it was saved during
-	 * .probe. */
-	pdev->state_saved = true;
-
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
@@ -8160,9 +5306,14 @@ static int iwl3945_pci_suspend(struct pc
 
 static int iwl3945_pci_resume(struct pci_dev *pdev)
 {
-	struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+	struct iwl_priv *priv = pci_get_drvdata(pdev);
+	int ret;
 
 	pci_set_power_state(pdev, PCI_D0);
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
+	pci_restore_state(pdev);
 
 	if (priv->is_open)
 		iwl3945_mac_start(priv->hw);
@@ -8173,114 +5324,6 @@ static int iwl3945_pci_resume(struct pci
 
 #endif /* CONFIG_PM */
 
-/*************** RFKILL FUNCTIONS **********/
-#ifdef CONFIG_IWL3945_RFKILL
-/* software rf-kill from user */
-static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
-	struct iwl3945_priv *priv = data;
-	int err = 0;
-
-	if (!priv->rfkill)
-	return 0;
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return 0;
-
-	IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
-	mutex_lock(&priv->mutex);
-
-	switch (state) {
-	case RFKILL_STATE_UNBLOCKED:
-		if (iwl3945_is_rfkill_hw(priv)) {
-			err = -EBUSY;
-			goto out_unlock;
-		}
-		iwl3945_radio_kill_sw(priv, 0);
-		break;
-	case RFKILL_STATE_SOFT_BLOCKED:
-		iwl3945_radio_kill_sw(priv, 1);
-		break;
-	default:
-		IWL_WARNING("we received unexpected RFKILL state %d\n", state);
-		break;
-	}
-out_unlock:
-	mutex_unlock(&priv->mutex);
-
-	return err;
-}
-
-int iwl3945_rfkill_init(struct iwl3945_priv *priv)
-{
-	struct device *device = wiphy_dev(priv->hw->wiphy);
-	int ret = 0;
-
-	BUG_ON(device == NULL);
-
-	IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
-	priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
-	if (!priv->rfkill) {
-		IWL_ERROR("Unable to allocate rfkill device.\n");
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	priv->rfkill->name = priv->cfg->name;
-	priv->rfkill->data = priv;
-	priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
-	priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
-	priv->rfkill->user_claim_unsupported = 1;
-
-	priv->rfkill->dev.class->suspend = NULL;
-	priv->rfkill->dev.class->resume = NULL;
-
-	ret = rfkill_register(priv->rfkill);
-	if (ret) {
-		IWL_ERROR("Unable to register rfkill: %d\n", ret);
-		goto freed_rfkill;
-	}
-
-	IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
-	return ret;
-
-freed_rfkill:
-	if (priv->rfkill != NULL)
-		rfkill_free(priv->rfkill);
-	priv->rfkill = NULL;
-
-error:
-	IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
-	return ret;
-}
-
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
-{
-	if (priv->rfkill)
-		rfkill_unregister(priv->rfkill);
-
-	priv->rfkill = NULL;
-}
-
-/* set rf-kill to the right state. */
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
-{
-
-	if (!priv->rfkill)
-		return;
-
-	if (iwl3945_is_rfkill_hw(priv)) {
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
-		return;
-	}
-
-	if (!iwl3945_is_rfkill_sw(priv))
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
-	else
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-#endif
-
 /*****************************************************************************
  *
  * driver and module entry point
@@ -8307,29 +5350,19 @@ static int __init iwl3945_init(void)
 
 	ret = iwl3945_rate_control_register();
 	if (ret) {
-		IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+		printk(KERN_ERR DRV_NAME
+		       "Unable to register rate control algorithm: %d\n", ret);
 		return ret;
 	}
 
 	ret = pci_register_driver(&iwl3945_driver);
 	if (ret) {
-		IWL_ERROR("Unable to initialize PCI module\n");
+		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
 		goto error_register;
 	}
-#ifdef CONFIG_IWL3945_DEBUG
-	ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level);
-	if (ret) {
-		IWL_ERROR("Unable to create driver sysfs file\n");
-		goto error_debug;
-	}
-#endif
 
 	return ret;
 
-#ifdef CONFIG_IWL3945_DEBUG
-error_debug:
-	pci_unregister_driver(&iwl3945_driver);
-#endif
 error_register:
 	iwl3945_rate_control_unregister();
 	return ret;
@@ -8337,29 +5370,29 @@ error_register:
 
 static void __exit iwl3945_exit(void)
 {
-#ifdef CONFIG_IWL3945_DEBUG
-	driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level);
-#endif
 	pci_unregister_driver(&iwl3945_driver);
 	iwl3945_rate_control_unregister();
 }
 
 /*(DEBLOBBED)*/
 
-module_param_named(antenna, iwl3945_param_antenna, int, 0444);
+module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_param_disable, int, 0444);
+module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
-module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
-MODULE_PARM_DESC(hwcrypto,
-		 "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl3945_param_debug, uint, 0444);
+module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
+MODULE_PARM_DESC(swcrypto,
+		 "using software crypto (default 1 [software])\n");
+module_param_named(debug, iwl3945_mod_params.debug, uint, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 
-module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
 
+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
+
 module_exit(iwl3945_exit);
 module_init(iwl3945_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -38,10 +38,15 @@
 #include <asm/unaligned.h>
 #include <net/mac80211.h>
 
-#include "iwl-3945-core.h"
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
 #include "iwl-3945.h"
+#include "iwl-eeprom.h"
 #include "iwl-helpers.h"
-#include "iwl-3945-rs.h"
+#include "iwl-core.h"
+#include "iwl-agn-rs.h"
 
 #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
 	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,   \
@@ -63,7 +68,7 @@
  * maps to IWL_RATE_INVALID
  *
  */
-const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
+const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
 	IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),    /*  1mbps */
 	IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),          /*  2mbps */
 	IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
@@ -91,7 +96,7 @@ const struct iwl3945_rate_info iwl3945_r
  * Use for only special debugging.  This function is just a placeholder as-is,
  *   you'll need to provide the special bits! ...
  *   ... and set IWL_EVT_DISABLE to 1. */
-void iwl3945_disable_events(struct iwl3945_priv *priv)
+void iwl3945_disable_events(struct iwl_priv *priv)
 {
 	int ret;
 	int i;
@@ -150,34 +155,34 @@ void iwl3945_disable_events(struct iwl39
 
 	base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 	if (!iwl3945_hw_valid_rtc_data_addr(base)) {
-		IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
 		return;
 	}
 
-	ret = iwl3945_grab_nic_access(priv);
+	ret = iwl_grab_nic_access(priv);
 	if (ret) {
-		IWL_WARNING("Can not read from adapter at this time.\n");
+		IWL_WARN(priv, "Can not read from adapter at this time.\n");
 		return;
 	}
 
-	disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
-	array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
-	iwl3945_release_nic_access(priv);
+	disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
+	array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
+	iwl_release_nic_access(priv);
 
 	if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
-		IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n",
+		IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
 			       disable_ptr);
-		ret = iwl3945_grab_nic_access(priv);
+		ret = iwl_grab_nic_access(priv);
 		for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
-			iwl3945_write_targ_mem(priv,
+			iwl_write_targ_mem(priv,
 					   disable_ptr + (i * sizeof(u32)),
 					   evt_disable[i]);
 
-		iwl3945_release_nic_access(priv);
+		iwl_release_nic_access(priv);
 	} else {
-		IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
-		IWL_DEBUG_INFO("  by writing \"1\"s into disable bitmap\n");
-		IWL_DEBUG_INFO("  in SRAM at 0x%x, size %d u32s\n",
+		IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
+		IWL_DEBUG_INFO(priv, "  by writing \"1\"s into disable bitmap\n");
+		IWL_DEBUG_INFO(priv, "  in SRAM at 0x%x, size %d u32s\n",
 			       disable_ptr, array_size);
 	}
 
@@ -193,40 +198,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8
 	return -1;
 }
 
-/**
- * iwl3945_get_antenna_flags - Get antenna flags for RXON command
- * @priv: eeprom and antenna fields are used to determine antenna flags
- *
- * priv->eeprom  is used to determine if antenna AUX/MAIN are reversed
- * priv->antenna specifies the antenna diversity mode:
- *
- * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
- * IWL_ANTENNA_MAIN      - Force MAIN antenna
- * IWL_ANTENNA_AUX       - Force AUX antenna
- */
-__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
-{
-	switch (priv->antenna) {
-	case IWL_ANTENNA_DIVERSITY:
-		return 0;
-
-	case IWL_ANTENNA_MAIN:
-		if (priv->eeprom.antenna_switch_type)
-			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
-		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-
-	case IWL_ANTENNA_AUX:
-		if (priv->eeprom.antenna_switch_type)
-			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
-	}
-
-	/* bad antenna selector value */
-	IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna);
-	return 0;		/* "diversity" is default if error */
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
 static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -266,7 +238,7 @@ static inline const char *iwl3945_get_tx
  * for A and B mode we need to overright prev
  * value
  */
-int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
+int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
 {
 	int next_rate = iwl3945_get_prev_ieee_rate(rate);
 
@@ -279,7 +251,7 @@ int iwl3945_rs_next_rate(struct iwl3945_
 		break;
 	case IEEE80211_BAND_2GHZ:
 		if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
-		    iwl3945_is_associated(priv)) {
+		    iwl_is_associated(priv)) {
 			if (rate == IWL_RATE_11M_INDEX)
 				next_rate = IWL_RATE_5M_INDEX;
 		}
@@ -300,12 +272,12 @@ int iwl3945_rs_next_rate(struct iwl3945_
  * need to be reclaimed. As result, some free space forms. If there is
  * enough free space (> low mark), wake the stack that feeds us.
  */
-static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
+static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
 				     int txq_id, int index)
 {
-	struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
-	struct iwl3945_queue *q = &txq->q;
-	struct iwl3945_tx_info *tx_info;
+	struct iwl_tx_queue *txq = &priv->txq[txq_id];
+	struct iwl_queue *q = &txq->q;
+	struct iwl_tx_info *tx_info;
 
 	BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
 
@@ -315,34 +287,34 @@ static void iwl3945_tx_queue_reclaim(str
 		tx_info = &txq->txb[txq->q.read_ptr];
 		ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
 		tx_info->skb[0] = NULL;
-		iwl3945_hw_txq_free_tfd(priv, txq);
+		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 	}
 
-	if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+	if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
 			(txq_id != IWL_CMD_QUEUE_NUM) &&
 			priv->mac80211_registered)
-		ieee80211_wake_queue(priv->hw, txq_id);
+		iwl_wake_queue(priv, txq_id);
 }
 
 /**
  * iwl3945_rx_reply_tx - Handle Tx response
  */
-static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
-			    struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
+			    struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	u16 sequence = le16_to_cpu(pkt->hdr.sequence);
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
-	struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct ieee80211_tx_info *info;
 	struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
 	u32  status = le32_to_cpu(tx_resp->status);
 	int rate_idx;
 	int fail;
 
-	if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+	if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+		IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
 			  "is out of range [0-%d] %d %d\n", txq_id,
 			  index, txq->q.n_bd, txq->q.write_ptr,
 			  txq->q.read_ptr);
@@ -366,15 +338,15 @@ static void iwl3945_rx_reply_tx(struct i
 	info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
 				IEEE80211_TX_STAT_ACK : 0;
 
-	IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
+	IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
 			txq_id, iwl3945_get_tx_fail_reason(status), status,
 			tx_resp->rate, tx_resp->failure_frame);
 
-	IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+	IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
 	iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
-		IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
+		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
 
@@ -387,14 +359,14 @@ static void iwl3945_rx_reply_tx(struct i
  *
  *****************************************************************************/
 
-void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-	IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(struct iwl3945_notif_statistics),
 		     le32_to_cpu(pkt->len));
 
-	memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
+	memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
 
 	iwl3945_led_background(priv);
 
@@ -406,7 +378,7 @@ void iwl3945_hw_rx_statistics(struct iwl
  * Misc. internal state and helper functions
  *
  ******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
 
 /**
  * iwl3945_report_frame - dump frame to syslog during debug sessions
@@ -415,8 +387,8 @@ void iwl3945_hw_rx_statistics(struct iwl
  * including selective frame dumps.
  * group100 parameter selects whether to show 1 out of 100 good frames.
  */
-static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
-		      struct iwl3945_rx_packet *pkt,
+static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
+		      struct iwl_rx_packet *pkt,
 		      struct ieee80211_hdr *header, int group100)
 {
 	u32 to_us;
@@ -524,13 +496,13 @@ static void iwl3945_dbg_report_frame(str
 		 * MAC addresses show just the last byte (for brevity),
 		 *    but you can hack it to show more, if you'd like to. */
 		if (dataframe)
-			IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+			IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
 				     "len=%u, rssi=%d, chnl=%d, rate=%d, \n",
 				     title, le16_to_cpu(fc), header->addr1[5],
 				     length, rssi, channel, rate);
 		else {
 			/* src/dst addresses assume managed mode */
-			IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
+			IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, "
 				     "src=0x%02x, rssi=%u, tim=%lu usec, "
 				     "phy=0x%02x, chnl=%d\n",
 				     title, le16_to_cpu(fc), header->addr1[5],
@@ -540,18 +512,27 @@ static void iwl3945_dbg_report_frame(str
 		}
 	}
 	if (print_dump)
-		iwl3945_print_hex_dump(IWL_DL_RX, data, length);
+		iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
+}
+
+static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+		      struct iwl_rx_packet *pkt,
+		      struct ieee80211_hdr *header, int group100)
+{
+	if (priv->debug_level & IWL_DL_RX)
+		_iwl3945_dbg_report_frame(priv, pkt, header, group100);
 }
+
 #else
-static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
-		      struct iwl3945_rx_packet *pkt,
+static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+		      struct iwl_rx_packet *pkt,
 		      struct ieee80211_hdr *header, int group100)
 {
 }
 #endif
 
 /* This is necessary only for a number of statistics, see the caller. */
-static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+static int iwl3945_is_network_packet(struct iwl_priv *priv,
 		struct ieee80211_hdr *header)
 {
 	/* Filter incoming packets to determine if they are targeted toward
@@ -568,12 +549,12 @@ static int iwl3945_is_network_packet(str
 	}
 }
 
-static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
-				   struct iwl3945_rx_mem_buffer *rxb,
+static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
+				   struct iwl_rx_mem_buffer *rxb,
 				   struct ieee80211_rx_status *stats)
 {
-	struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
-#ifdef CONFIG_IWL3945_LEDS
+	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_LEDS
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
 #endif
 	struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
@@ -581,15 +562,15 @@ static void iwl3945_pass_packet_to_mac80
 	short len = le16_to_cpu(rx_hdr->len);
 
 	/* We received data from the HW, so stop the watchdog */
-	if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
-		IWL_DEBUG_DROP("Corruption detected!\n");
+	if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+		IWL_DEBUG_DROP(priv, "Corruption detected!\n");
 		return;
 	}
 
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
-		IWL_DEBUG_DROP_LIMIT
-		    ("Dropping packet while interface is not open.\n");
+		IWL_DEBUG_DROP_LIMIT(priv,
+			"Dropping packet while interface is not open.\n");
 		return;
 	}
 
@@ -597,11 +578,12 @@ static void iwl3945_pass_packet_to_mac80
 	/* Set the size of the skb to the size of the frame */
 	skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
 
-	if (iwl3945_param_hwcrypto)
-		iwl3945_set_decrypted_flag(priv, rxb->skb,
+	if (!iwl3945_mod_params.sw_crypto)
+		iwl_set_decrypted_flag(priv,
+				       (struct ieee80211_hdr *)rxb->skb->data,
 				       le32_to_cpu(rx_end->status), stats);
 
-#ifdef CONFIG_IWL3945_LEDS
+#ifdef CONFIG_IWLWIFI_LEDS
 	if (ieee80211_is_data(hdr->frame_control))
 		priv->rxtxpackets += len;
 #endif
@@ -611,12 +593,12 @@ static void iwl3945_pass_packet_to_mac80
 
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 
-static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
-				struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
+				struct iwl_rx_mem_buffer *rxb)
 {
 	struct ieee80211_hdr *header;
 	struct ieee80211_rx_status rx_status;
-	struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	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);
@@ -644,22 +626,21 @@ static void iwl3945_rx_reply_rx(struct i
 		rx_status.flag |= RX_FLAG_SHORTPRE;
 
 	if ((unlikely(rx_stats->phy_count > 20))) {
-		IWL_DEBUG_DROP
-		    ("dsp size out of range [0,20]: "
-		     "%d/n", rx_stats->phy_count);
+		IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
+				rx_stats->phy_count);
 		return;
 	}
 
 	if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR)
 	    || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
-		IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
+		IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
 		return;
 	}
 
 
 
 	/* Convert 3945's rssi indicator to dBm */
-	rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
+	rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
 
 	/* Set default noise value to -127 */
 	if (priv->last_rx_noise == 0)
@@ -691,7 +672,7 @@ static void iwl3945_rx_reply_rx(struct i
 	}
 
 
-	IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
+	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,
 			rx_stats_sig_avg, rx_stats_noise_diff);
 
@@ -699,17 +680,14 @@ static void iwl3945_rx_reply_rx(struct i
 
 	network_packet = iwl3945_is_network_packet(priv, header);
 
-	IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
+	IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
 			      network_packet ? '*' : ' ',
 			      le16_to_cpu(rx_hdr->channel),
 			      rx_status.signal, rx_status.signal,
 			      rx_status.noise, rx_status.rate_idx);
 
-#ifdef CONFIG_IWL3945_DEBUG
-	if (iwl3945_debug_level & (IWL_DL_RX))
-		/* Set "1" to report good data frames in groups of 100 */
-		iwl3945_dbg_report_frame(priv, pkt, header, 1);
-#endif
+	/* Set "1" to report good data frames in groups of 100 */
+	iwl3945_dbg_report_frame(priv, pkt, header, 1);
 
 	if (network_packet) {
 		priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
@@ -721,24 +699,31 @@ static void iwl3945_rx_reply_rx(struct i
 	iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
 }
 
-int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
-				 dma_addr_t addr, u16 len)
+int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+				     struct iwl_tx_queue *txq,
+				     dma_addr_t addr, u16 len, u8 reset, u8 pad)
 {
 	int count;
-	u32 pad;
-	struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
+	struct iwl_queue *q;
+	struct iwl3945_tfd *tfd, *tfd_tmp;
+
+	q = &txq->q;
+	tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+	tfd = &tfd_tmp[q->write_ptr];
+
+	if (reset)
+		memset(tfd, 0, sizeof(*tfd));
 
 	count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
-	pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
 
 	if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
-		IWL_ERROR("Error can not send more than %d chunks\n",
+		IWL_ERR(priv, "Error can not send more than %d chunks\n",
 			  NUM_TFD_CHUNKS);
 		return -EINVAL;
 	}
 
-	tfd->pa[count].addr = cpu_to_le32(addr);
-	tfd->pa[count].len = cpu_to_le32(len);
+	tfd->tbs[count].addr = cpu_to_le32(addr);
+	tfd->tbs[count].len = cpu_to_le32(len);
 
 	count++;
 
@@ -753,32 +738,35 @@ int iwl3945_hw_txq_attach_buf_to_tfd(str
  *
  * Does NOT advance any indexes
  */
-int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 {
-	struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
-	struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+	struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+	int index = txq->q.read_ptr;
+	struct iwl3945_tfd *tfd = &tfd_tmp[index];
 	struct pci_dev *dev = priv->pci_dev;
 	int i;
 	int counter;
 
-	/* classify bd */
-	if (txq->q.id == IWL_CMD_QUEUE_NUM)
-		/* nothing to cleanup after for host commands */
-		return 0;
-
 	/* sanity check */
-	counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags));
+	counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
 	if (counter > NUM_TFD_CHUNKS) {
-		IWL_ERROR("Too many chunks: %i\n", counter);
+		IWL_ERR(priv, "Too many chunks: %i\n", counter);
 		/* @todo issue fatal error, it is quite serious situation */
-		return 0;
+		return;
 	}
 
+	/* Unmap tx_cmd */
+	if (counter)
+		pci_unmap_single(dev,
+				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+				pci_unmap_len(&txq->cmd[index]->meta, len),
+				PCI_DMA_TODEVICE);
+
 	/* unmap chunks if any */
 
 	for (i = 1; i < counter; i++) {
-		pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
-				 le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
+		pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
+			 le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
 		if (txq->txb[txq->q.read_ptr].skb[0]) {
 			struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
 			if (txq->txb[txq->q.read_ptr].skb[0]) {
@@ -788,10 +776,10 @@ int iwl3945_hw_txq_free_tfd(struct iwl39
 			}
 		}
 	}
-	return 0;
+	return ;
 }
 
-u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
+u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
 {
 	int i, start = IWL_AP_ID;
 	int ret = IWL_INVALID_STATION;
@@ -802,18 +790,18 @@ u8 iwl3945_hw_find_station(struct iwl394
 		start = IWL_STA_ID;
 
 	if (is_broadcast_ether_addr(addr))
-		return priv->hw_setting.bcast_sta_id;
+		return priv->hw_params.bcast_sta_id;
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
-	for (i = start; i < priv->hw_setting.max_stations; i++)
-		if ((priv->stations[i].used) &&
+	for (i = start; i < priv->hw_params.max_stations; i++)
+		if ((priv->stations_39[i].used) &&
 		    (!compare_ether_addr
-		     (priv->stations[i].sta.sta.addr, addr))) {
+		     (priv->stations_39[i].sta.sta.addr, addr))) {
 			ret = i;
 			goto out;
 		}
 
-	IWL_DEBUG_INFO("can not find STA %pM (total %d)\n",
+	IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
 		       addr, priv->num_stations);
  out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -824,12 +812,10 @@ u8 iwl3945_hw_find_station(struct iwl394
  * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
  *
 */
-void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
-			      struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
 			      struct ieee80211_tx_info *info,
 			      struct ieee80211_hdr *hdr, int sta_id, int tx_id)
 {
-	unsigned long flags;
 	u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
 	u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
 	u16 rate_mask;
@@ -838,25 +824,15 @@ 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;
 
 	rate = iwl3945_rates[rate_index].plcp;
-	tx_flags = cmd->cmd.tx.tx_flags;
+	tx_flags = tx->tx_flags;
 
 	/* We need to figure out how to get the sta->supp_rates while
 	 * in this running context */
 	rate_mask = IWL_RATES_MASK;
 
-	spin_lock_irqsave(&priv->sta_lock, flags);
-
-	priv->stations[sta_id].current_rate.rate_n_flags = rate;
-
-	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
-	    (sta_id != priv->hw_setting.bcast_sta_id) &&
-		(sta_id != IWL_MULTICAST_ID))
-		priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
-
-	spin_unlock_irqrestore(&priv->sta_lock, flags);
-
 	if (tx_id >= IWL_CMD_QUEUE_NUM)
 		rts_retry_limit = 3;
 	else
@@ -888,25 +864,25 @@ void iwl3945_hw_build_tx_cmd_rate(struct
 		}
 	}
 
-	cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
-	cmd->cmd.tx.data_retry_limit = data_retry_limit;
-	cmd->cmd.tx.rate = rate;
-	cmd->cmd.tx.tx_flags = tx_flags;
+	tx->rts_retry_limit = rts_retry_limit;
+	tx->data_retry_limit = data_retry_limit;
+	tx->rate = rate;
+	tx->tx_flags = tx_flags;
 
 	/* OFDM */
-	cmd->cmd.tx.supp_rates[0] =
+	tx->supp_rates[0] =
 	   ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
 
 	/* CCK */
-	cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
+	tx->supp_rates[1] = (rate_mask & 0xF);
 
-	IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
+	IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
 		       "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
-		       cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags),
-		       cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
+		       tx->rate, le32_to_cpu(tx->tx_flags),
+		       tx->supp_rates[1], tx->supp_rates[0]);
 }
 
-u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 {
 	unsigned long flags_spin;
 	struct iwl3945_station_entry *station;
@@ -915,138 +891,133 @@ u8 iwl3945_sync_sta(struct iwl3945_priv
 		return IWL_INVALID_STATION;
 
 	spin_lock_irqsave(&priv->sta_lock, flags_spin);
-	station = &priv->stations[sta_id];
+	station = &priv->stations_39[sta_id];
 
 	station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
 	station->sta.rate_n_flags = cpu_to_le16(tx_rate);
-	station->current_rate.rate_n_flags = tx_rate;
 	station->sta.mode = STA_CONTROL_MODIFY_MSK;
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
-	iwl3945_send_add_station(priv, &station->sta, flags);
-	IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
+	iwl_send_add_sta(priv,
+			 (struct iwl_addsta_cmd *)&station->sta, flags);
+	IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
 			sta_id, tx_rate);
 	return sta_id;
 }
 
-static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
+static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 {
-	int rc;
+	int ret;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
-	if (rc) {
+	ret = iwl_grab_nic_access(priv);
+	if (ret) {
 		spin_unlock_irqrestore(&priv->lock, flags);
-		return rc;
+		return ret;
 	}
 
-	if (!pwr_max) {
-		u32 val;
-
-		rc = pci_read_config_dword(priv->pci_dev,
-				PCI_POWER_SOURCE, &val);
-		if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
-			iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+	if (src == IWL_PWR_SRC_VAUX) {
+		if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
+			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 					APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
 					~APMG_PS_CTRL_MSK_PWR_SRC);
-			iwl3945_release_nic_access(priv);
+			iwl_release_nic_access(priv);
 
-			iwl3945_poll_bit(priv, CSR_GPIO_IN,
+			iwl_poll_bit(priv, CSR_GPIO_IN,
 				     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
 				     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
-		} else
-			iwl3945_release_nic_access(priv);
+		} else {
+			iwl_release_nic_access(priv);
+		}
 	} else {
-		iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 				APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
 				~APMG_PS_CTRL_MSK_PWR_SRC);
 
-		iwl3945_release_nic_access(priv);
-		iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+		iwl_release_nic_access(priv);
+		iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
 			     CSR_GPIO_IN_BIT_AUX_POWER, 5000);	/* uS */
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return rc;
+	return ret;
 }
 
-static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
+static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
 	int rc;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
 
-	iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
-	iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
-			     priv->hw_setting.shared_phys +
-			     offsetof(struct iwl3945_shared, rx_read_ptr[0]));
-	iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
-	iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
-		ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
-		ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
-		ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
-		ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
-		(RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
-		ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
-		(1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
-		ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
+	iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
+	iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
+	iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
+	iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
+		FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
+		FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
+		FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
+		FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
+		(RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
+		FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
+		(1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
+		FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
 
 	/* fake read to flush all prev I/O */
-	iwl3945_read_direct32(priv, FH_RSSR_CTRL);
+	iwl_read_direct32(priv, FH39_RSSR_CTRL);
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
 }
 
-static int iwl3945_tx_reset(struct iwl3945_priv *priv)
+static int iwl3945_tx_reset(struct iwl_priv *priv)
 {
 	int rc;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
 
 	/* bypass mode */
-	iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
+	iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
 
 	/* RA 0 is active */
-	iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
+	iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
 
 	/* all 6 fifo are active */
-	iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
+	iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
 
-	iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
-	iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
-	iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
-	iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
+	iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+	iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+	iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+	iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
 
-	iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
-			     priv->hw_setting.shared_phys);
+	iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
+			     priv->shared_phys);
 
-	iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
-		ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
+	iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
+		FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
@@ -1057,7 +1028,7 @@ static int iwl3945_tx_reset(struct iwl39
  *
  * Destroys all DMA structures and initialize them again
  */
-static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
+static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
 {
 	int rc;
 	int txq_id, slots_num;
@@ -1070,13 +1041,13 @@ static int iwl3945_txq_ctx_reset(struct
 		goto error;
 
 	/* Tx queue(s) */
-	for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
+	for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
 		slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
 				TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-		rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
-				txq_id);
+		rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+				       txq_id);
 		if (rc) {
-			IWL_ERROR("Tx %d queue init failed\n", txq_id);
+			IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
 			goto error;
 		}
 	}
@@ -1088,107 +1059,136 @@ static int iwl3945_txq_ctx_reset(struct
 	return rc;
 }
 
-int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
+static int iwl3945_apm_init(struct iwl_priv *priv)
 {
-	u8 rev_id;
-	int rc;
-	unsigned long flags;
-	struct iwl3945_rx_queue *rxq = &priv->rxq;
+	int ret = 0;
 
-	iwl3945_power_init_handle(priv);
+	iwl_power_initialize(priv);
 
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
-	iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 
-	iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-	rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (rc < 0) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		IWL_DEBUG_INFO("Failed to init the card\n");
-		return rc;
-	}
+	/* 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);
 
-	rc = iwl3945_grab_nic_access(priv);
-	if (rc) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return rc;
+	/* 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;
 	}
-	iwl3945_write_prph(priv, APMG_CLK_EN_REG,
-				 APMG_CLK_VAL_DMA_CLK_RQT |
-				 APMG_CLK_VAL_BSM_CLK_RQT);
+
+	ret = iwl_grab_nic_access(priv);
+	if (ret)
+		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);
-	iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-				    APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-	iwl3945_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* Determine HW type */
-	rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
-	if (rc)
-		return rc;
-	IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
+	/* disable L1-Active */
+	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+	iwl_release_nic_access(priv);
+out:
+	return ret;
+}
+
+static void iwl3945_nic_config(struct iwl_priv *priv)
+{
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+	unsigned long flags;
+	u8 rev_id = 0;
 
-	iwl3945_nic_set_pwr_src(priv, 1);
 	spin_lock_irqsave(&priv->lock, flags);
 
 	if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
-		IWL_DEBUG_INFO("RTP type \n");
+		IWL_DEBUG_INFO(priv, "RTP type \n");
 	else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
-		IWL_DEBUG_INFO("3945 RADIO-MB type\n");
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
 	} else {
-		IWL_DEBUG_INFO("3945 RADIO-MM type\n");
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n");
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
 	}
 
-	if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
-		IWL_DEBUG_INFO("SKU OP mode is mrc\n");
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+	if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
+		IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n");
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
 	} else
-		IWL_DEBUG_INFO("SKU OP mode is basic\n");
+		IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n");
 
-	if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
-		IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
-			       priv->eeprom.board_revision);
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+	if ((eeprom->board_revision & 0xF0) == 0xD0) {
+		IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+			       eeprom->board_revision);
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
 	} else {
-		IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
-			       priv->eeprom.board_revision);
-		iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+		IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+			       eeprom->board_revision);
+		iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
 			      CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
 	}
 
-	if (priv->eeprom.almgor_m_version <= 1) {
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+	if (eeprom->almgor_m_version <= 1) {
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
-		IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
-			       priv->eeprom.almgor_m_version);
+		IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n",
+			       eeprom->almgor_m_version);
 	} else {
-		IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
-			       priv->eeprom.almgor_m_version);
-		iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n",
+			       eeprom->almgor_m_version);
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			    CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
-		IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
+	if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
+		IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n");
 
-	if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
-		IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
+	if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
+		IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n");
+}
+
+int iwl3945_hw_nic_init(struct iwl_priv *priv)
+{
+	u8 rev_id;
+	int rc;
+	unsigned long flags;
+	struct iwl_rx_queue *rxq = &priv->rxq;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->cfg->ops->lib->apm_ops.init(priv);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	/* Determine HW type */
+	rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+	if (rc)
+		return rc;
+	IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+
+	rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+	if (rc)
+		return rc;
+
+	priv->cfg->ops->lib->apm_ops.config(priv);
 
 	/* Allocate the RX queue, or reset if it is already allocated */
 	if (!rxq->bd) {
-		rc = iwl3945_rx_queue_alloc(priv);
+		rc = iwl_rx_queue_alloc(priv);
 		if (rc) {
-			IWL_ERROR("Unable to initialize Rx queue\n");
+			IWL_ERR(priv, "Unable to initialize Rx queue\n");
 			return -ENOMEM;
 		}
 	} else
@@ -1202,16 +1202,16 @@ int iwl3945_hw_nic_init(struct iwl3945_p
 
 	/* Look at using this instead:
 	rxq->need_update = 1;
-	iwl3945_rx_queue_update_write_ptr(priv, rxq);
+	iwl_rx_queue_update_write_ptr(priv, rxq);
 	*/
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
-	iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
-	iwl3945_release_nic_access(priv);
+	iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
+	iwl_release_nic_access(priv);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1229,116 +1229,125 @@ int iwl3945_hw_nic_init(struct iwl3945_p
  *
  * Destroy all TX DMA queues and structures
  */
-void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
 {
 	int txq_id;
 
 	/* Tx queues */
-	for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
-		iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
+	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);
+
 }
 
-void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
 {
-	int queue;
+	int txq_id;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (iwl3945_grab_nic_access(priv)) {
+	if (iwl_grab_nic_access(priv)) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		iwl3945_hw_txq_ctx_free(priv);
 		return;
 	}
 
 	/* stop SCD */
-	iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
+	iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
 
 	/* reset TFD queues */
-	for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
-		iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
-		iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
-				ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
+	for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
+		iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
+		iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
+				FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
 				1000);
 	}
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	iwl3945_hw_txq_ctx_free(priv);
 }
 
-int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
+static int iwl3945_apm_stop_master(struct iwl_priv *priv)
 {
-	int rc = 0;
-	u32 reg_val;
+	int ret = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
 	/* set stop master bit */
-	iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-	reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
+	iwl_poll_direct_bit(priv, CSR_RESET,
+			    CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 
-	if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
-	    (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
-		IWL_DEBUG_INFO("Card in power save, master is already "
-			       "stopped\n");
-	else {
-		rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
-				  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-		if (rc < 0) {
-			spin_unlock_irqrestore(&priv->lock, flags);
-			return rc;
-		}
-	}
+	if (ret < 0)
+		goto out;
 
+out:
 	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO("stop master\n");
+	IWL_DEBUG_INFO(priv, "stop master\n");
 
-	return rc;
+	return ret;
 }
 
-int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
+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)
 {
 	int rc;
 	unsigned long flags;
 
-	iwl3945_hw_nic_stop_master(priv);
+	iwl3945_apm_stop_master(priv);
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+	udelay(10);
 
-	iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+	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);
 
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (!rc) {
-		iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
+		iwl_write_prph(priv, APMG_CLK_CTRL_REG,
 					 APMG_CLK_VAL_BSM_CLK_RQT);
 
-		udelay(10);
-
-		iwl3945_set_bit(priv, CSR_GP_CNTRL,
-			    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-		iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
-		iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG,
+		iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+		iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
 					0xFFFFFFFF);
 
 		/* enable DMA */
-		iwl3945_write_prph(priv, APMG_CLK_EN_REG,
+		iwl_write_prph(priv, APMG_CLK_EN_REG,
 					 APMG_CLK_VAL_DMA_CLK_RQT |
 					 APMG_CLK_VAL_BSM_CLK_RQT);
 		udelay(10);
 
-		iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG,
+		iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
 				APMG_PS_CTRL_VAL_RESET_REQ);
 		udelay(5);
-		iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+		iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
 				APMG_PS_CTRL_VAL_RESET_REQ);
-		iwl3945_release_nic_access(priv);
+		iwl_release_nic_access(priv);
 	}
 
 	/* Clear the 'host command active' bit... */
@@ -1367,33 +1376,34 @@ static inline int iwl3945_hw_reg_temp_ou
 	return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
 }
 
-int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
+int iwl3945_hw_get_temperature(struct iwl_priv *priv)
 {
-	return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
+	return iwl_read32(priv, CSR_UCODE_DRV_GP2);
 }
 
 /**
  * iwl3945_hw_reg_txpower_get_temperature
  * get the current temperature by reading from NIC
 */
-static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
 {
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 	int temperature;
 
 	temperature = iwl3945_hw_get_temperature(priv);
 
 	/* driver's okay range is -260 to +25.
 	 *   human readable okay range is 0 to +285 */
-	IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
+	IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
 
 	/* handle insane temp reading */
 	if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
-		IWL_ERROR("Error bad temperature value  %d\n", temperature);
+		IWL_ERR(priv, "Error bad temperature value  %d\n", temperature);
 
 		/* if really really hot(?),
 		 *   substitute the 3rd band/group's temp measured at factory */
 		if (priv->last_temperature > 100)
-			temperature = priv->eeprom.groups[2].temperature;
+			temperature = eeprom->groups[2].temperature;
 		else /* else use most recent "sane" value from driver */
 			temperature = priv->last_temperature;
 	}
@@ -1412,7 +1422,7 @@ static int iwl3945_hw_reg_txpower_get_te
  * records new temperature in tx_mgr->temperature.
  * replaces tx_mgr->last_temperature *only* if calib needed
  *    (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl3945_priv *priv)
+static int is_temp_calib_needed(struct iwl_priv *priv)
 {
 	int temp_diff;
 
@@ -1421,20 +1431,20 @@ static int is_temp_calib_needed(struct i
 
 	/* get absolute value */
 	if (temp_diff < 0) {
-		IWL_DEBUG_POWER("Getting cooler, delta %d,\n", temp_diff);
+		IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff);
 		temp_diff = -temp_diff;
 	} else if (temp_diff == 0)
-		IWL_DEBUG_POWER("Same temp,\n");
+		IWL_DEBUG_POWER(priv, "Same temp,\n");
 	else
-		IWL_DEBUG_POWER("Getting warmer, delta %d,\n", temp_diff);
+		IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff);
 
 	/* if we don't need calibration, *don't* update last_temperature */
 	if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) {
-		IWL_DEBUG_POWER("Timed thermal calib not needed\n");
+		IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n");
 		return 0;
 	}
 
-	IWL_DEBUG_POWER("Timed thermal calib needed\n");
+	IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n");
 
 	/* assume that caller will actually do calib ...
 	 *   update the "last temperature" value */
@@ -1627,9 +1637,9 @@ static inline u8 iwl3945_hw_reg_fix_powe
  * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
  * or 6 Mbit (OFDM) rates.
  */
-static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
+static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
 			       s32 rate_index, const s8 *clip_pwrs,
-			       struct iwl3945_channel_info *ch_info,
+			       struct iwl_channel_info *ch_info,
 			       int band_index)
 {
 	struct iwl3945_scan_power_info *scan_power_info;
@@ -1646,7 +1656,7 @@ static void iwl3945_hw_reg_set_scan_powe
 	/* further limit to user's max power preference.
 	 * FIXME:  Other spectrum management power limitations do not
 	 *   seem to apply?? */
-	power = min(power, priv->user_txpower_limit);
+	power = min(power, priv->tx_power_user_lmt);
 	scan_power_info->requested_power = power;
 
 	/* find difference between new scan *power* and current "normal"
@@ -1678,32 +1688,32 @@ static void iwl3945_hw_reg_set_scan_powe
 }
 
 /**
- * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_send_tx_power - fill in Tx Power command with gain settings
  *
  * Configures power settings for all rates for the current channel,
  * using values from channel info struct, and send to NIC
  */
-int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
+static int iwl3945_send_tx_power(struct iwl_priv *priv)
 {
 	int rate_idx, i;
-	const struct iwl3945_channel_info *ch_info = NULL;
+	const struct iwl_channel_info *ch_info = NULL;
 	struct iwl3945_txpowertable_cmd txpower = {
 		.channel = priv->active_rxon.channel,
 	};
 
 	txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
-	ch_info = iwl3945_get_channel_info(priv,
+	ch_info = iwl_get_channel_info(priv,
 				       priv->band,
 				       le16_to_cpu(priv->active_rxon.channel));
 	if (!ch_info) {
-		IWL_ERROR
-		    ("Failed to get channel info for channel %d [%d]\n",
-		     le16_to_cpu(priv->active_rxon.channel), priv->band);
+		IWL_ERR(priv,
+			"Failed to get channel info for channel %d [%d]\n",
+			le16_to_cpu(priv->active_rxon.channel), priv->band);
 		return -EINVAL;
 	}
 
 	if (!is_channel_valid(ch_info)) {
-		IWL_DEBUG_POWER("Not calling TX_PWR_TABLE_CMD on "
+		IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on "
 				"non-Tx channel.\n");
 		return 0;
 	}
@@ -1711,12 +1721,12 @@ int iwl3945_hw_reg_send_txpower(struct i
 	/* fill cmd with power settings for all rates for current channel */
 	/* Fill OFDM rate */
 	for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
-	     rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
+	     rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) {
 
 		txpower.power[i].tpc = ch_info->power_info[i].tpc;
 		txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
-		IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+		IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
 				le16_to_cpu(txpower.channel),
 				txpower.band,
 				txpower.power[i].tpc.tx_gain,
@@ -1729,7 +1739,7 @@ int iwl3945_hw_reg_send_txpower(struct i
 		txpower.power[i].tpc = ch_info->power_info[i].tpc;
 		txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
-		IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+		IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
 				le16_to_cpu(txpower.channel),
 				txpower.band,
 				txpower.power[i].tpc.tx_gain,
@@ -1737,8 +1747,9 @@ int iwl3945_hw_reg_send_txpower(struct i
 				txpower.power[i].rate);
 	}
 
-	return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
-			sizeof(struct iwl3945_txpowertable_cmd), &txpower);
+	return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+				sizeof(struct iwl3945_txpowertable_cmd),
+				&txpower);
 
 }
 
@@ -1758,8 +1769,8 @@ int iwl3945_hw_reg_send_txpower(struct i
  *	 properly fill out the scan powers, and actual h/w gain settings,
  *	 and send changes to NIC
  */
-static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
-			     struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
+			     struct iwl_channel_info *ch_info)
 {
 	struct iwl3945_channel_power_info *power_info;
 	int power_changed = 0;
@@ -1768,7 +1779,7 @@ static int iwl3945_hw_reg_set_new_power(
 	int power;
 
 	/* Get this chnlgrp's rate-to-max/clip-powers table */
-	clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+	clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
 
 	/* Get this channel's rate-to-current-power settings table */
 	power_info = ch_info->power_info;
@@ -1821,7 +1832,7 @@ static int iwl3945_hw_reg_set_new_power(
  *	 based strictly on regulatory (eeprom and spectrum mgt) limitations
  *	 (no consideration for h/w clipping limitations).
  */
-static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
 {
 	s8 max_power;
 
@@ -1849,9 +1860,10 @@ static int iwl3945_hw_reg_get_ch_txpower
  *
  * If RxOn is "associated", this sends the new Txpower to NIC!
  */
-static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
 {
-	struct iwl3945_channel_info *ch_info = NULL;
+	struct iwl_channel_info *ch_info = NULL;
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 	int delta_index;
 	const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
 	u8 a_band;
@@ -1867,7 +1879,7 @@ static int iwl3945_hw_reg_comp_txpower_t
 		a_band = is_channel_a_band(ch_info);
 
 		/* Get this chnlgrp's factory calibration temperature */
-		ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
+		ref_temp = (s16)eeprom->groups[ch_info->group_index].
 		    temperature;
 
 		/* get power index adjustment based on current and factory
@@ -1893,7 +1905,7 @@ static int iwl3945_hw_reg_comp_txpower_t
 		}
 
 		/* Get this chnlgrp's rate-to-max/clip-powers table */
-		clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+		clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
 
 		/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
 		for (scan_tbl_index = 0;
@@ -1907,24 +1919,24 @@ static int iwl3945_hw_reg_comp_txpower_t
 	}
 
 	/* send Txpower command for current channel to ucode */
-	return iwl3945_hw_reg_send_txpower(priv);
+	return priv->cfg->ops->lib->send_tx_power(priv);
 }
 
-int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
+int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
 {
-	struct iwl3945_channel_info *ch_info;
+	struct iwl_channel_info *ch_info;
 	s8 max_power;
 	u8 a_band;
 	u8 i;
 
-	if (priv->user_txpower_limit == power) {
-		IWL_DEBUG_POWER("Requested Tx power same as current "
+	if (priv->tx_power_user_lmt == power) {
+		IWL_DEBUG_POWER(priv, "Requested Tx power same as current "
 				"limit: %ddBm.\n", power);
 		return 0;
 	}
 
-	IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power);
-	priv->user_txpower_limit = power;
+	IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power);
+	priv->tx_power_user_lmt = power;
 
 	/* set up new Tx powers for each and every channel, 2.4 and 5.x */
 
@@ -1953,7 +1965,7 @@ int iwl3945_hw_reg_set_txpower(struct iw
 }
 
 /* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
+int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
 	return 0;
 }
@@ -1968,7 +1980,7 @@ int iwl3945_hw_channel_switch(struct iwl
  *     -- send new set of gain settings to NIC
  * NOTE:  This should continue working, even when we're not associated,
  *   so we can keep our internal table of scan powers current. */
-void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
+void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
 {
 	/* This will kick in the "brute force"
 	 * iwl3945_hw_reg_comp_txpower_temp() below */
@@ -1987,7 +1999,7 @@ void iwl3945_reg_txpower_periodic(struct
 
 static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
 {
-	struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
+	struct iwl_priv *priv = container_of(work, struct iwl_priv,
 					     thermal_periodic.work);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2009,10 +2021,11 @@ static void iwl3945_bg_reg_txpower_perio
  *	 on A-band, EEPROM's "group frequency" entries represent the top
  *	 channel in each group 1-4.  Group 5 All B/G channels are in group 0.
  */
-static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
-				       const struct iwl3945_channel_info *ch_info)
+static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
+				       const struct iwl_channel_info *ch_info)
 {
-	struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+	struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
 	u8 group;
 	u16 group_index = 0;	/* based on factory calib frequencies */
 	u8 grp_channel;
@@ -2032,7 +2045,7 @@ static u16 iwl3945_hw_reg_get_ch_grp_ind
 	} else
 		group_index = 0;	/* 2.4 GHz, group 0 */
 
-	IWL_DEBUG_POWER("Chnl %d mapped to grp %d\n", ch_info->channel,
+	IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel,
 			group_index);
 	return group_index;
 }
@@ -2043,11 +2056,12 @@ static u16 iwl3945_hw_reg_get_ch_grp_ind
  * Interpolate to get nominal (i.e. at factory calibration temperature) index
  *   into radio/DSP gain settings table for requested power.
  */
-static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
+static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
 				       s8 requested_power,
 				       s32 setting_index, s32 *new_index)
 {
 	const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 	s32 index0, index1;
 	s32 power = 2 * requested_power;
 	s32 i;
@@ -2056,7 +2070,7 @@ static int iwl3945_hw_reg_get_matched_po
 	s32 res;
 	s32 denominator;
 
-	chnl_grp = &priv->eeprom.groups[setting_index];
+	chnl_grp = &eeprom->groups[setting_index];
 	samples = chnl_grp->samples;
 	for (i = 0; i < 5; i++) {
 		if (power == samples[i].power) {
@@ -2091,22 +2105,23 @@ static int iwl3945_hw_reg_get_matched_po
 	return 0;
 }
 
-static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
+static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
 {
 	u32 i;
 	s32 rate_index;
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 	const struct iwl3945_eeprom_txpower_group *group;
 
-	IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
+	IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n");
 
 	for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
 		s8 *clip_pwrs;	/* table of power levels for each rate */
 		s8 satur_pwr;	/* saturation power for each chnl group */
-		group = &priv->eeprom.groups[i];
+		group = &eeprom->groups[i];
 
 		/* sanity check on factory saturation power value */
 		if (group->saturation_power < 40) {
-			IWL_WARNING("Error: saturation power is %d, "
+			IWL_WARN(priv, "Error: saturation power is %d, "
 				    "less than minimum expected 40\n",
 				    group->saturation_power);
 			return;
@@ -2121,7 +2136,7 @@ static void iwl3945_hw_reg_init_channel_
 		 *   power peaks, without too much distortion (clipping).
 		 */
 		/* we'll fill in this array with h/w max power levels */
-		clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers;
+		clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers;
 
 		/* divide factory saturation power by 2 to find -3dB level */
 		satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2171,10 +2186,11 @@ static void iwl3945_hw_reg_init_channel_
  *
  * This does *not* write values to NIC, just sets up our internal table.
  */
-int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
+int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
 {
-	struct iwl3945_channel_info *ch_info = NULL;
+	struct iwl_channel_info *ch_info = NULL;
 	struct iwl3945_channel_power_info *pwr_info;
+	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
 	int delta_index;
 	u8 rate_index;
 	u8 scan_tbl_index;
@@ -2204,15 +2220,15 @@ int iwl3945_txpower_set_from_eeprom(stru
 			iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
 
 		/* Get this chnlgrp's rate->max/clip-powers table */
-		clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+		clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
 
 		/* calculate power index *adjustment* value according to
 		 *  diff between current temperature and factory temperature */
 		delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
-				priv->eeprom.groups[ch_info->group_index].
+				eeprom->groups[ch_info->group_index].
 				temperature);
 
-		IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
+		IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n",
 				ch_info->channel, delta_index, temperature +
 				IWL_TEMP_CONVERT);
 
@@ -2235,7 +2251,7 @@ int iwl3945_txpower_set_from_eeprom(stru
 							 ch_info->group_index,
 							 &power_idx);
 			if (rc) {
-				IWL_ERROR("Invalid power index\n");
+				IWL_ERR(priv, "Invalid power index\n");
 				return rc;
 			}
 			pwr_info->base_power_index = (u8) power_idx;
@@ -2295,75 +2311,90 @@ int iwl3945_txpower_set_from_eeprom(stru
 	return 0;
 }
 
-int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
+int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
 {
 	int rc;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
 
-	iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
-	rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
-			FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+	iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
+	rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
+			FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
 	if (rc < 0)
-		IWL_ERROR("Can't stop Rx DMA.\n");
+		IWL_ERR(priv, "Can't stop Rx DMA.\n");
 
-	iwl3945_release_nic_access(priv);
+	iwl_release_nic_access(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
 }
 
-int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 {
 	int rc;
 	unsigned long flags;
 	int txq_id = txq->q.id;
 
-	struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+	struct iwl3945_shared *shared_data = priv->shared_virt;
 
 	shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
 
 	spin_lock_irqsave(&priv->lock, flags);
-	rc = iwl3945_grab_nic_access(priv);
+	rc = iwl_grab_nic_access(priv);
 	if (rc) {
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
-	iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
-	iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
+	iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
+	iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
 
-	iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
-		ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
-		ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
-		ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
-		ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
-		ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
-	iwl3945_release_nic_access(priv);
+	iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
+		FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
+		FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
+		FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
+		FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
+		FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
+	iwl_release_nic_access(priv);
 
 	/* fake read to flush all prev. writes */
-	iwl3945_read32(priv, FH_TSSR_CBB_BASE);
+	iwl_read32(priv, FH39_TSSR_CBB_BASE);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
 }
 
-int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
+/*
+ * HCMD utils
+ */
+static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
 {
-	struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+	switch (cmd_id) {
+	case REPLY_RXON:
+		return sizeof(struct iwl3945_rxon_cmd);
+	case POWER_TABLE_CMD:
+		return sizeof(struct iwl3945_powertable_cmd);
+	default:
+		return len;
+	}
+}
 
-	return le32_to_cpu(shared_data->rx_read_ptr[0]);
+static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+	u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
+	memcpy(data, cmd, size);
+	return size;
 }
 
 /**
  * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
  */
-int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
+int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
 {
 	int rc, i, index, prev_index;
 	struct iwl3945_rate_scaling_cmd rate_cmd = {
@@ -2384,7 +2415,7 @@ int iwl3945_init_hw_rate_table(struct iw
 
 	switch (priv->band) {
 	case IEEE80211_BAND_5GHZ:
-		IWL_DEBUG_RATE("Select A mode rate scale\n");
+		IWL_DEBUG_RATE(priv, "Select A mode rate scale\n");
 		/* If one of the following CCK rates is used,
 		 * have it fall back to the 6M OFDM rate */
 		for (i = IWL_RATE_1M_INDEX_TABLE;
@@ -2402,12 +2433,12 @@ int iwl3945_init_hw_rate_table(struct iw
 		break;
 
 	case IEEE80211_BAND_2GHZ:
-		IWL_DEBUG_RATE("Select B/G mode rate scale\n");
+		IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n");
 		/* If an OFDM rate is used, have it fall back to the
 		 * 1M CCK rates */
 
 		if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
-		    iwl3945_is_associated(priv)) {
+		    iwl_is_associated(priv)) {
 
 			index = IWL_FIRST_CCK_RATE;
 			for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2428,47 +2459,51 @@ int iwl3945_init_hw_rate_table(struct iw
 
 	/* Update the rate scaling for control frame Tx */
 	rate_cmd.table_id = 0;
-	rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+	rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
 			      &rate_cmd);
 	if (rc)
 		return rc;
 
 	/* Update the rate scaling for data frame Tx */
 	rate_cmd.table_id = 1;
-	return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+	return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
 				&rate_cmd);
 }
 
 /* Called when initializing driver */
-int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
+int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
 {
-	memset((void *)&priv->hw_setting, 0,
-	       sizeof(struct iwl3945_driver_hw_info));
+	memset((void *)&priv->hw_params, 0,
+	       sizeof(struct iwl_hw_params));
 
-	priv->hw_setting.shared_virt =
+	priv->shared_virt =
 	    pci_alloc_consistent(priv->pci_dev,
 				 sizeof(struct iwl3945_shared),
-				 &priv->hw_setting.shared_phys);
+				 &priv->shared_phys);
 
-	if (!priv->hw_setting.shared_virt) {
-		IWL_ERROR("failed to allocate pci memory\n");
+	if (!priv->shared_virt) {
+		IWL_ERR(priv, "failed to allocate pci memory\n");
 		mutex_unlock(&priv->mutex);
 		return -ENOMEM;
 	}
 
-	priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE;
-	priv->hw_setting.max_pkt_size = 2342;
-	priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
-	priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
-	priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
-	priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
-	priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
+	/* Assign number of Usable TX queues */
+	priv->hw_params.max_txq_num = TFD_QUEUE_MAX;
+
+	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.max_rxq_size = RX_QUEUE_SIZE;
+	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+	priv->hw_params.max_stations = IWL3945_STATION_COUNT;
+	priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+
+	priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
 
-	priv->hw_setting.tx_ant_num = 2;
 	return 0;
 }
 
-unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
 			  struct iwl3945_frame *frame, u8 rate)
 {
 	struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
@@ -2477,7 +2512,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(s
 	tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
 	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
-	tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
+	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;
 
 	frame_size = iwl3945_fill_beacon_frame(priv,
@@ -2501,37 +2536,262 @@ unsigned int iwl3945_hw_get_beacon_cmd(s
 	return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
 }
 
-void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
+void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
 {
 	priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
 	priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
 }
 
-void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
 {
 	INIT_DELAYED_WORK(&priv->thermal_periodic,
 			  iwl3945_bg_reg_txpower_periodic);
 }
 
-void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
 {
 	cancel_delayed_work(&priv->thermal_periodic);
 }
 
-static struct iwl_3945_cfg iwl3945_bg_cfg = {
+/* check contents of special bootstrap uCode SRAM */
+static int iwl3945_verify_bsm(struct iwl_priv *priv)
+ {
+	__le32 *image = priv->ucode_boot.v_addr;
+	u32 len = priv->ucode_boot.len;
+	u32 reg;
+	u32 val;
+
+	IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
+
+	/* verify BSM SRAM contents */
+	val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
+	for (reg = BSM_SRAM_LOWER_BOUND;
+	     reg < BSM_SRAM_LOWER_BOUND + len;
+	     reg += sizeof(u32), image++) {
+		val = iwl_read_prph(priv, reg);
+		if (val != le32_to_cpu(*image)) {
+			IWL_ERR(priv, "BSM uCode verification failed at "
+				  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
+				  BSM_SRAM_LOWER_BOUND,
+				  reg - BSM_SRAM_LOWER_BOUND, len,
+				  val, le32_to_cpu(*image));
+			return -EIO;
+		}
+	}
+
+	IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
+
+	return 0;
+}
+
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+ ******************************************************************************/
+
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism.  Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+	_iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+	return 0;
+}
+
+
+static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+	return;
+}
+
+ /**
+  * iwl3945_load_bsm - Load bootstrap instructions
+  *
+  * BSM operation:
+  *
+  * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
+  * in special SRAM that does not power down during RFKILL.  When powering back
+  * up after power-saving sleeps (or during initial uCode load), the BSM loads
+  * the bootstrap program into the on-board processor, and starts it.
+  *
+  * The bootstrap program loads (via DMA) instructions and data for a new
+  * program from host DRAM locations indicated by the host driver in the
+  * BSM_DRAM_* registers.  Once the new program is loaded, it starts
+  * automatically.
+  *
+  * When initializing the NIC, the host driver points the BSM to the
+  * "initialize" uCode image.  This uCode sets up some internal data, then
+  * notifies host via "initialize alive" that it is complete.
+  *
+  * The host then replaces the BSM_DRAM_* pointer values to point to the
+  * normal runtime uCode instructions and a backup uCode data cache buffer
+  * (filled initially with starting data values for the on-board processor),
+  * then triggers the "initialize" uCode to load and launch the runtime uCode,
+  * which begins normal operation.
+  *
+  * When doing a power-save shutdown, runtime uCode saves data SRAM into
+  * the backup data cache in DRAM before SRAM is powered down.
+  *
+  * When powering back up, the BSM loads the bootstrap program.  This reloads
+  * the runtime uCode instructions and the backup data cache into SRAM,
+  * and re-launches the runtime uCode from where it left off.
+  */
+static int iwl3945_load_bsm(struct iwl_priv *priv)
+{
+	__le32 *image = priv->ucode_boot.v_addr;
+	u32 len = priv->ucode_boot.len;
+	dma_addr_t pinst;
+	dma_addr_t pdata;
+	u32 inst_len;
+	u32 data_len;
+	int rc;
+	int i;
+	u32 done;
+	u32 reg_offset;
+
+	IWL_DEBUG_INFO(priv, "Begin load bsm\n");
+
+	/* make sure bootstrap program is no larger than BSM's SRAM size */
+	if (len > IWL39_MAX_BSM_SIZE)
+		return -EINVAL;
+
+	/* Tell bootstrap uCode where to find the "Initialize" uCode
+	*   in host DRAM ... host DRAM physical address bits 31:0 for 3945.
+	* NOTE:  iwl3945_initialize_alive_start() will replace these values,
+	*        after the "initialize" uCode has run, to point to
+	*        runtime/protocol instructions and backup data cache. */
+	pinst = priv->ucode_init.p_addr;
+	pdata = priv->ucode_init_data.p_addr;
+	inst_len = priv->ucode_init.len;
+	data_len = priv->ucode_init_data.len;
+
+	rc = iwl_grab_nic_access(priv);
+	if (rc)
+		return rc;
+
+	iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+	iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+	iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+	iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+
+	/* Fill BSM memory with bootstrap instructions */
+	for (reg_offset = BSM_SRAM_LOWER_BOUND;
+	     reg_offset < BSM_SRAM_LOWER_BOUND + len;
+	     reg_offset += sizeof(u32), image++)
+		_iwl_write_prph(priv, reg_offset,
+					  le32_to_cpu(*image));
+
+	rc = iwl3945_verify_bsm(priv);
+	if (rc) {
+		iwl_release_nic_access(priv);
+		return rc;
+	}
+
+	/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
+	iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+	iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
+				 IWL39_RTC_INST_LOWER_BOUND);
+	iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+
+	/* Load bootstrap code into instruction SRAM now,
+	 *   to prepare to load "initialize" uCode */
+	iwl_write_prph(priv, BSM_WR_CTRL_REG,
+		BSM_WR_CTRL_REG_BIT_START);
+
+	/* Wait for load of bootstrap uCode to finish */
+	for (i = 0; i < 100; i++) {
+		done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
+		if (!(done & BSM_WR_CTRL_REG_BIT_START))
+			break;
+		udelay(10);
+	}
+	if (i < 100)
+		IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
+	else {
+		IWL_ERR(priv, "BSM write did not complete!\n");
+		return -EIO;
+	}
+
+	/* Enable future boot loads whenever power management unit triggers it
+	 *   (e.g. when powering back up after power-save shutdown) */
+	iwl_write_prph(priv, BSM_WR_CTRL_REG,
+		BSM_WR_CTRL_REG_BIT_START_EN);
+
+	iwl_release_nic_access(priv);
+
+	return 0;
+}
+
+static struct iwl_lib_ops iwl3945_lib = {
+	.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
+	.txq_free_tfd = iwl3945_hw_txq_free_tfd,
+	.txq_init = iwl3945_hw_tx_queue_init,
+	.load_ucode = iwl3945_load_bsm,
+	.apm_ops = {
+		.init = iwl3945_apm_init,
+		.reset = iwl3945_apm_reset,
+		.stop = iwl3945_apm_stop,
+		.config = iwl3945_nic_config,
+		.set_pwr_src = iwl3945_set_pwr_src,
+	},
+	.eeprom_ops = {
+		.regulatory_bands = {
+			EEPROM_REGULATORY_BAND_1_CHANNELS,
+			EEPROM_REGULATORY_BAND_2_CHANNELS,
+			EEPROM_REGULATORY_BAND_3_CHANNELS,
+			EEPROM_REGULATORY_BAND_4_CHANNELS,
+			EEPROM_REGULATORY_BAND_5_CHANNELS,
+			EEPROM_REGULATORY_BAND_NO_FAT,
+			EEPROM_REGULATORY_BAND_NO_FAT,
+		},
+		.verify_signature  = iwlcore_eeprom_verify_signature,
+		.acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
+		.release_semaphore = iwl3945_eeprom_release_semaphore,
+		.query_addr = iwlcore_eeprom_query_addr,
+	},
+	.send_tx_power	= iwl3945_send_tx_power,
+	.is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+};
+
+static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+	.get_hcmd_size = iwl3945_get_hcmd_size,
+	.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+};
+
+static struct iwl_ops iwl3945_ops = {
+	.lib = &iwl3945_lib,
+	.utils = &iwl3945_hcmd_utils,
+};
+
+static struct iwl_cfg iwl3945_bg_cfg = {
 	.name = "3945BG",
 	.fw_name_pre = IWL3945_FW_PRE,
 	.ucode_api_max = IWL3945_UCODE_API_MAX,
 	.ucode_api_min = IWL3945_UCODE_API_MIN,
 	.sku = IWL_SKU_G,
+	.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+	.ops = &iwl3945_ops,
+	.mod_params = &iwl3945_mod_params
 };
 
-static struct iwl_3945_cfg iwl3945_abg_cfg = {
+static struct iwl_cfg iwl3945_abg_cfg = {
 	.name = "3945ABG",
 	.fw_name_pre = IWL3945_FW_PRE,
 	.ucode_api_max = IWL3945_UCODE_API_MAX,
 	.ucode_api_min = IWL3945_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G,
+	.eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+	.ops = &iwl3945_ops,
+	.mod_params = &iwl3945_mod_params
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-commands.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-commands.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-commands.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1702 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2008 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.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-/*
- * Please use this file (iwl-3945-commands.h) only for uCode API definitions.
- * Please use iwl-3945-hw.h for hardware-related definitions.
- * Please use iwl-3945.h for driver implementation definitions.
- */
-
-#ifndef __iwl_3945_commands_h__
-#define __iwl_3945_commands_h__
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver)	(((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver)	(((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver)	(((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver)	((ver) & 0x000000FF)
-
-enum {
-	REPLY_ALIVE = 0x1,
-	REPLY_ERROR = 0x2,
-
-	/* RXON and QOS commands */
-	REPLY_RXON = 0x10,
-	REPLY_RXON_ASSOC = 0x11,
-	REPLY_QOS_PARAM = 0x13,
-	REPLY_RXON_TIMING = 0x14,
-
-	/* Multi-Station support */
-	REPLY_ADD_STA = 0x18,
-	REPLY_REMOVE_STA = 0x19,	/* not used */
-	REPLY_REMOVE_ALL_STA = 0x1a,	/* not used */
-
-	/* RX, TX, LEDs */
-	REPLY_3945_RX = 0x1b,		/* 3945 only */
-	REPLY_TX = 0x1c,
-	REPLY_RATE_SCALE = 0x47,	/* 3945 only */
-	REPLY_LEDS_CMD = 0x48,
-	REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
-
-	/* 802.11h related */
-	RADAR_NOTIFICATION = 0x70,	/* not used */
-	REPLY_QUIET_CMD = 0x71,		/* not used */
-	REPLY_CHANNEL_SWITCH = 0x72,
-	CHANNEL_SWITCH_NOTIFICATION = 0x73,
-	REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
-	SPECTRUM_MEASURE_NOTIFICATION = 0x75,
-
-	/* Power Management */
-	POWER_TABLE_CMD = 0x77,
-	PM_SLEEP_NOTIFICATION = 0x7A,
-	PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
-
-	/* Scan commands and notifications */
-	REPLY_SCAN_CMD = 0x80,
-	REPLY_SCAN_ABORT_CMD = 0x81,
-	SCAN_START_NOTIFICATION = 0x82,
-	SCAN_RESULTS_NOTIFICATION = 0x83,
-	SCAN_COMPLETE_NOTIFICATION = 0x84,
-
-	/* IBSS/AP commands */
-	BEACON_NOTIFICATION = 0x90,
-	REPLY_TX_BEACON = 0x91,
-	WHO_IS_AWAKE_NOTIFICATION = 0x94,	/* not used */
-
-	/* Miscellaneous commands */
-	QUIET_NOTIFICATION = 0x96,		/* not used */
-	REPLY_TX_PWR_TABLE_CMD = 0x97,
-	MEASURE_ABORT_NOTIFICATION = 0x99,	/* not used */
-
-	/* Bluetooth device coexistence config command */
-	REPLY_BT_CONFIG = 0x9b,
-
-	/* Statistics */
-	REPLY_STATISTICS_CMD = 0x9c,
-	STATISTICS_NOTIFICATION = 0x9d,
-
-	/* RF-KILL commands and notifications */
-	REPLY_CARD_STATE_CMD = 0xa0,
-	CARD_STATE_NOTIFICATION = 0xa1,
-
-	/* Missed beacons notification */
-	MISSED_BEACONS_NOTIFICATION = 0xa2,
-
-	REPLY_MAX = 0xff
-};
-
-/******************************************************************************
- * (0)
- * Commonly used structures and definitions:
- * Command header, txpower
- *
- *****************************************************************************/
-
-/* iwl3945_cmd_header flags value */
-#define IWL_CMD_FAILED_MSK 0x40
-
-/**
- * struct iwl3945_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl3945_cmd_header {
-	u8 cmd;		/* Command ID:  REPLY_RXON, etc. */
-	u8 flags;	/* IWL_CMD_* */
-	/*
-	 * The driver sets up the sequence number to values of its choosing.
-	 * uCode does not use this value, but passes it back to the driver
-	 * when sending the response to each driver-originated command, so
-	 * the driver can match the response to the command.  Since the values
-	 * don't get used by uCode, the driver may set up an arbitrary format.
-	 *
-	 * There is one exception:  uCode sets bit 15 when it originates
-	 * the response/notification, i.e. when the response/notification
-	 * is not a direct response to a command sent by the driver.  For
-	 * example, uCode issues REPLY_3945_RX when it sends a received frame
-	 * to the driver; it is not a direct response to any driver command.
-	 *
-	 * The Linux driver uses the following format:
-	 *
-	 *  0:7    index/position within Tx queue
-	 *  8:13   Tx queue selection
-	 * 14:14   driver sets this to indicate command is in the 'huge'
-	 *         storage at the end of the command buffers, i.e. scan cmd
-	 * 15:15   uCode sets this in uCode-originated response/notification
-	 */
-	__le16 sequence;
-
-	/* command or response/notification data follows immediately */
-	u8 data[0];
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
- *     linear value that multiplies the output of the digital signal processor,
- *     before being sent to the analog radio.
- * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
- *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
-	u8 tx_gain;		/* gain for analog radio */
-	u8 dsp_atten;		/* gain for DSP */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
-	u8 rate;		/* plcp */
-	struct iwl3945_tx_power tpc;
-	u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (0a)
- * Alive and Error Commands & Responses:
- *
- *****************************************************************************/
-
-#define UCODE_VALID_OK	cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE    (9)
-
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- */
-struct iwl3945_init_alive_resp {
-	u8 ucode_minor;
-	u8 ucode_major;
-	__le16 reserved1;
-	u8 sw_rev[8];
-	u8 ver_type;
-	u8 ver_subtype;			/* "9" for initialize alive */
-	__le16 reserved2;
-	__le32 log_event_table_ptr;
-	__le32 error_event_table_ptr;
-	__le32 timestamp;
-	__le32 is_valid;
-} __attribute__ ((packed));
-
-
-/**
- * REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "alive" notification once the runtime image is ready
- * to receive commands from the driver.  This is the *second* "alive"
- * notification that the driver will receive after rebooting uCode;
- * this "alive" is indicated by subtype field != 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * This response includes two pointers to structures within the device's
- * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
- *
- * 1)  log_event_table_ptr indicates base of the event log.  This traces
- *     a 256-entry history of uCode execution within a circular buffer.
- *
- * 2)  error_event_table_ptr indicates base of the error log.  This contains
- *     information about any uCode error that occurs.
- *
- * The Linux driver can print both logs to the system log when a uCode error
- * occurs.
- */
-struct iwl3945_alive_resp {
-	u8 ucode_minor;
-	u8 ucode_major;
-	__le16 reserved1;
-	u8 sw_rev[8];
-	u8 ver_type;
-	u8 ver_subtype;			/* not "9" for runtime alive */
-	__le16 reserved2;
-	__le32 log_event_table_ptr;	/* SRAM address for event log */
-	__le32 error_event_table_ptr;	/* SRAM address for error log */
-	__le32 timestamp;
-	__le32 is_valid;
-} __attribute__ ((packed));
-
-union tsf {
-	u8 byte[8];
-	__le16 word[4];
-	__le32 dw[2];
-};
-
-/*
- * REPLY_ERROR = 0x2 (response only, not a command)
- */
-struct iwl3945_error_resp {
-	__le32 error_type;
-	u8 cmd_id;
-	u8 reserved1;
-	__le16 bad_cmd_seq_num;
-	__le16 reserved2;
-	__le32 error_info;
-	union tsf timestamp;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (1)
- * RXON Commands & Responses:
- *
- *****************************************************************************/
-
-/*
- * Rx config defines & structure
- */
-/* rx_config device types  */
-enum {
-	RXON_DEV_TYPE_AP = 1,
-	RXON_DEV_TYPE_ESS = 3,
-	RXON_DEV_TYPE_IBSS = 4,
-	RXON_DEV_TYPE_SNIFFER = 6,
-};
-
-/* rx_config flags */
-/* band & modulation selection */
-#define RXON_FLG_BAND_24G_MSK           cpu_to_le32(1 << 0)
-#define RXON_FLG_CCK_MSK                cpu_to_le32(1 << 1)
-/* auto detection enable */
-#define RXON_FLG_AUTO_DETECT_MSK        cpu_to_le32(1 << 2)
-/* TGg protection when tx */
-#define RXON_FLG_TGG_PROTECT_MSK        cpu_to_le32(1 << 3)
-/* cck short slot & preamble */
-#define RXON_FLG_SHORT_SLOT_MSK          cpu_to_le32(1 << 4)
-#define RXON_FLG_SHORT_PREAMBLE_MSK     cpu_to_le32(1 << 5)
-/* antenna selection */
-#define RXON_FLG_DIS_DIV_MSK            cpu_to_le32(1 << 7)
-#define RXON_FLG_ANT_SEL_MSK            cpu_to_le32(0x0f00)
-#define RXON_FLG_ANT_A_MSK              cpu_to_le32(1 << 8)
-#define RXON_FLG_ANT_B_MSK              cpu_to_le32(1 << 9)
-/* radar detection enable */
-#define RXON_FLG_RADAR_DETECT_MSK       cpu_to_le32(1 << 12)
-#define RXON_FLG_TGJ_NARROW_BAND_MSK    cpu_to_le32(1 << 13)
-/* rx response to host with 8-byte TSF
-* (according to ON_AIR deassertion) */
-#define RXON_FLG_TSF2HOST_MSK           cpu_to_le32(1 << 15)
-
-/* rx_config filter flags */
-/* accept all data frames */
-#define RXON_FILTER_PROMISC_MSK         cpu_to_le32(1 << 0)
-/* pass control & management to host */
-#define RXON_FILTER_CTL2HOST_MSK        cpu_to_le32(1 << 1)
-/* accept multi-cast */
-#define RXON_FILTER_ACCEPT_GRP_MSK      cpu_to_le32(1 << 2)
-/* don't decrypt uni-cast frames */
-#define RXON_FILTER_DIS_DECRYPT_MSK     cpu_to_le32(1 << 3)
-/* don't decrypt multi-cast frames */
-#define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4)
-/* STA is associated */
-#define RXON_FILTER_ASSOC_MSK           cpu_to_le32(1 << 5)
-/* transfer to host non bssid beacons in associated state */
-#define RXON_FILTER_BCON_AWARE_MSK      cpu_to_le32(1 << 6)
-
-/**
- * REPLY_RXON = 0x10 (command, has simple generic response)
- *
- * RXON tunes the radio tuner to a service channel, and sets up a number
- * of parameters that are used primarily for Rx, but also for Tx operations.
- *
- * NOTE:  When tuning to a new channel, driver must set the
- *        RXON_FILTER_ASSOC_MSK to 0.  This will clear station-dependent
- *        info within the device, including the station tables, tx retry
- *        rate tables, and txpower tables.  Driver must build a new station
- *        table and txpower table before transmitting anything on the RXON
- *        channel.
- *
- * NOTE:  All RXONs wipe clean the internal txpower table.  Driver must
- *        issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
- *        regardless of whether RXON_FILTER_ASSOC_MSK is set.
- */
-struct iwl3945_rxon_cmd {
-	u8 node_addr[6];
-	__le16 reserved1;
-	u8 bssid_addr[6];
-	__le16 reserved2;
-	u8 wlap_bssid_addr[6];
-	__le16 reserved3;
-	u8 dev_type;
-	u8 air_propagation;
-	__le16 reserved4;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	__le16 assoc_id;
-	__le32 flags;
-	__le32 filter_flags;
-	__le16 channel;
-	__le16 reserved5;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl3945_rxon_assoc_cmd {
-	__le32 flags;
-	__le32 filter_flags;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	__le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
- */
-struct iwl3945_rxon_time_cmd {
-	union tsf timestamp;
-	__le16 beacon_interval;
-	__le16 atim_window;
-	__le32 beacon_init_val;
-	__le16 listen_interval;
-	__le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
- */
-struct iwl3945_channel_switch_cmd {
-	u8 band;
-	u8 expect_beacon;
-	__le16 channel;
-	__le32 rxon_flags;
-	__le32 rxon_filter_flags;
-	__le32 switch_time;
-	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
- */
-struct iwl3945_csa_notification {
-	__le16 band;
-	__le16 channel;
-	__le32 status;		/* 0 - OK, 1 - fail */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (2)
- * Quality-of-Service (QOS) Commands & Responses:
- *
- *****************************************************************************/
-
-/**
- * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
- * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
- *
- * @cw_min: Contention window, start value in numbers of slots.
- *          Should be a power-of-2, minus 1.  Device's default is 0x0f.
- * @cw_max: Contention window, max value in numbers of slots.
- *          Should be a power-of-2, minus 1.  Device's default is 0x3f.
- * @aifsn:  Number of slots in Arbitration Interframe Space (before
- *          performing random backoff timing prior to Tx).  Device default 1.
- * @edca_txop:  Length of Tx opportunity, in uSecs.  Device default is 0.
- *
- * Device will automatically increase contention window by (2*CW) + 1 for each
- * transmission retry.  Device uses cw_max as a bit mask, ANDed with new CW
- * value, to cap the CW value.
- */
-struct iwl3945_ac_qos {
-	__le16 cw_min;
-	__le16 cw_max;
-	u8 aifsn;
-	u8 reserved1;
-	__le16 edca_txop;
-} __attribute__ ((packed));
-
-/* QoS flags defines */
-#define QOS_PARAM_FLG_UPDATE_EDCA_MSK	cpu_to_le32(0x01)
-#define QOS_PARAM_FLG_TGN_MSK		cpu_to_le32(0x02)
-#define QOS_PARAM_FLG_TXOP_TYPE_MSK	cpu_to_le32(0x10)
-
-/* Number of Access Categories (AC) (EDCA), queues 0..3 */
-#define AC_NUM                4
-
-/*
- * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
- *
- * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
- * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
- */
-struct iwl3945_qosparam_cmd {
-	__le32 qos_flags;
-	struct iwl3945_ac_qos ac[AC_NUM];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (3)
- * Add/Modify Stations Commands & Responses:
- *
- *****************************************************************************/
-/*
- * Multi station support
- */
-
-/* Special, dedicated locations within device's station table */
-#define	IWL_AP_ID		0
-#define IWL_MULTICAST_ID	1
-#define	IWL_STA_ID		2
-#define	IWL3945_BROADCAST_ID	24
-#define IWL3945_STATION_COUNT	25
-
-#define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
-#define	IWL_INVALID_STATION 	255
-
-#define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2);
-#define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
-
-/* Use in mode field.  1: modify existing entry, 0: add new station entry */
-#define STA_CONTROL_MODIFY_MSK		0x01
-
-/* key flags __le16*/
-#define STA_KEY_FLG_ENCRYPT_MSK	cpu_to_le16(0x0007)
-#define STA_KEY_FLG_NO_ENC	cpu_to_le16(0x0000)
-#define STA_KEY_FLG_WEP		cpu_to_le16(0x0001)
-#define STA_KEY_FLG_CCMP	cpu_to_le16(0x0002)
-#define STA_KEY_FLG_TKIP	cpu_to_le16(0x0003)
-
-#define STA_KEY_FLG_KEYID_POS	8
-#define STA_KEY_FLG_INVALID 	cpu_to_le16(0x0800)
-/* wep key is either from global key (0) or from station info array (1) */
-#define STA_KEY_FLG_WEP_KEY_MAP_MSK  cpu_to_le16(0x0008)
-
-/* wep key in STA: 5-bytes (0) or 13-bytes (1) */
-#define STA_KEY_FLG_KEY_SIZE_MSK     cpu_to_le16(0x1000)
-#define STA_KEY_MULTICAST_MSK        cpu_to_le16(0x4000)
-
-/* Flags indicate whether to modify vs. don't change various station params */
-#define	STA_MODIFY_KEY_MASK		0x01
-#define	STA_MODIFY_TID_DISABLE_TX	0x02
-#define	STA_MODIFY_TX_RATE_MSK		0x04
-
-/*
- * Antenna masks:
- * bit14:15 01 B inactive, A active
- *          10 B active, A inactive
- *          11 Both active
- */
-#define RATE_MCS_ANT_A_POS	14
-#define RATE_MCS_ANT_B_POS	15
-#define RATE_MCS_ANT_A_MSK	0x4000
-#define RATE_MCS_ANT_B_MSK	0x8000
-#define RATE_MCS_ANT_AB_MSK	0xc000
-
-struct iwl3945_keyinfo {
-	__le16 key_flags;
-	u8 tkip_rx_tsc_byte2;	/* TSC[2] for key mix ph1 detection */
-	u8 reserved1;
-	__le16 tkip_rx_ttak[5];	/* 10-byte unicast TKIP TTAK */
-	u8 key_offset;
-	u8 reserved2;
-	u8 key[16];		/* 16-byte unicast decryption key */
-} __attribute__ ((packed));
-
-/**
- * struct sta_id_modify
- * @addr[ETH_ALEN]: station's MAC address
- * @sta_id: index of station in uCode's station table
- * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
- *
- * Driver selects unused table index when adding new station,
- * or the index to a pre-existing station entry when modifying that station.
- * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
- *
- * modify_mask flags select which parameters to modify vs. leave alone.
- */
-struct sta_id_modify {
-	u8 addr[ETH_ALEN];
-	__le16 reserved1;
-	u8 sta_id;
-	u8 modify_mask;
-	__le16 reserved2;
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (command)
- *
- * The device contains an internal table of per-station information,
- * with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
- *
- * REPLY_ADD_STA sets up the table entry for one station, either creating
- * a new entry, or modifying a pre-existing one.
- *
- * NOTE:  RXON command (without "associated" bit set) wipes the station table
- *        clean.  Moving into RF_KILL state does this also.  Driver must set up
- *        new station table before transmitting anything on the RXON channel
- *        (except active scans or active measurements; those commands carry
- *        their own txpower/rate setup data).
- *
- *        When getting started on a new channel, driver must set up the
- *        IWL_BROADCAST_ID entry (last entry in the table).  For a client
- *        station in a BSS, once an AP is selected, driver sets up the AP STA
- *        in the IWL_AP_ID entry (1st entry in the table).  BROADCAST and AP
- *        are all that are needed for a BSS client station.  If the device is
- *        used as AP, or in an IBSS network, driver must set up station table
- *        entries for all STAs in network, starting with index IWL_STA_ID.
- */
-struct iwl3945_addsta_cmd {
-	u8 mode;		/* 1: modify existing, 0: add new station */
-	u8 reserved[3];
-	struct sta_id_modify sta;
-	struct iwl3945_keyinfo key;
-	__le32 station_flags;		/* STA_FLG_* */
-	__le32 station_flags_msk;	/* STA_FLG_* */
-
-	/* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
-	 * corresponding to bit (e.g. bit 5 controls TID 5).
-	 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
-	__le16 tid_disable_tx;
-
-	__le16 rate_n_flags;
-
-	/* TID for which to add block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	u8 add_immediate_ba_tid;
-
-	/* TID for which to remove block-ack support.
-	 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
-	u8 remove_immediate_ba_tid;
-
-	/* Starting Sequence Number for added block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	__le16 add_immediate_ba_ssn;
-} __attribute__ ((packed));
-
-#define ADD_STA_SUCCESS_MSK		0x1
-#define ADD_STA_NO_ROOM_IN_TABLE	0x2
-#define ADD_STA_NO_BLOCK_ACK_RESOURCE	0x4
-/*
- * REPLY_ADD_STA = 0x18 (response)
- */
-struct iwl3945_add_sta_resp {
-	u8 status;	/* ADD_STA_* */
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (4)
- * Rx Responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_frame_stats {
-	u8 phy_count;
-	u8 id;
-	u8 rssi;
-	u8 agc;
-	__le16 sig_avg;
-	__le16 noise_diff;
-	u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl3945_rx_frame_hdr {
-	__le16 channel;
-	__le16 phy_flags;
-	u8 reserved1;
-	u8 rate;
-	__le16 len;
-	u8 payload[0];
-} __attribute__ ((packed));
-
-#define RX_RES_STATUS_NO_CRC32_ERROR	cpu_to_le32(1 << 0)
-#define RX_RES_STATUS_NO_RXE_OVERFLOW	cpu_to_le32(1 << 1)
-
-#define RX_RES_PHY_FLAGS_BAND_24_MSK	cpu_to_le16(1 << 0)
-#define RX_RES_PHY_FLAGS_MOD_CCK_MSK		cpu_to_le16(1 << 1)
-#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK	cpu_to_le16(1 << 2)
-#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK	cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK		cpu_to_le16(0xf0)
-
-#define RX_RES_STATUS_SEC_TYPE_MSK	(0x7 << 8)
-#define RX_RES_STATUS_SEC_TYPE_NONE	(0x0 << 8)
-#define RX_RES_STATUS_SEC_TYPE_WEP	(0x1 << 8)
-#define RX_RES_STATUS_SEC_TYPE_CCMP	(0x2 << 8)
-#define RX_RES_STATUS_SEC_TYPE_TKIP	(0x3 << 8)
-
-#define RX_RES_STATUS_DECRYPT_TYPE_MSK	(0x3 << 11)
-#define RX_RES_STATUS_NOT_DECRYPT	(0x0 << 11)
-#define RX_RES_STATUS_DECRYPT_OK	(0x3 << 11)
-#define RX_RES_STATUS_BAD_ICV_MIC	(0x1 << 11)
-#define RX_RES_STATUS_BAD_KEY_TTAK	(0x2 << 11)
-
-struct iwl3945_rx_frame_end {
-	__le32 status;
-	__le64 timestamp;
-	__le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE:  DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
-	struct iwl3945_rx_frame_stats stats;
-	struct iwl3945_rx_frame_hdr hdr;
-	struct iwl3945_rx_frame_end end;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (5)
- * Tx Commands & Responses:
- *
- * Driver must place each REPLY_TX command into one of the prioritized Tx
- * queues in host DRAM, shared between driver and device.  When the device's
- * Tx scheduler and uCode are preparing to transmit, the device pulls the
- * Tx command over the PCI bus via one of the device's Tx DMA channels,
- * to fill an internal FIFO from which data will be transmitted.
- *
- * uCode handles all timing and protocol related to control frames
- * (RTS/CTS/ACK), based on flags in the Tx command.
- *
- * uCode handles retrying Tx when an ACK is expected but not received.
- * This includes trying lower data rates than the one requested in the Tx
- * command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
- *
- * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
- * This command must be executed after every RXON command, before Tx can occur.
- *****************************************************************************/
-
-/* REPLY_TX Tx flags field */
-
-/* 1: Use Request-To-Send protocol before this frame.
- * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
-#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
-
-/* 1: Transmit Clear-To-Send to self before this frame.
- * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
- * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
-#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
-
-/* 1: Expect ACK from receiving station
- * 0: Don't expect ACK (MAC header's duration field s/b 0)
- * Set this for unicast frames, but not broadcast/multicast. */
-#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-
-/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
- *    Tx command's initial_rate_index indicates first rate to try;
- *    uCode walks through table for additional Tx attempts.
- * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
- *    This rate will be used for all Tx attempts; it will not be scaled. */
-#define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4)
-
-/* 1: Expect immediate block-ack.
- * Set when Txing a block-ack request frame.  Also set TX_CMD_FLG_ACK_MSK. */
-#define TX_CMD_FLG_IMM_BA_RSP_MASK  cpu_to_le32(1 << 6)
-
-/* 1: Frame requires full Tx-Op protection.
- * Set this if either RTS or CTS Tx Flag gets set. */
-#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
- * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
-#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
-#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-
-/* 1: Ignore Bluetooth priority for this frame.
- * 0: Delay Tx until Bluetooth device is done (normal usage). */
-#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
-
-/* 1: uCode overrides sequence control field in MAC header.
- * 0: Driver provides sequence control field in MAC header.
- * Set this for management frames, non-QOS data frames, non-unicast frames,
- * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
-#define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13)
-
-/* 1: This frame is non-last MPDU; more fragments are coming.
- * 0: Last fragment, or not using fragmentation. */
-#define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14)
-
-/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
- * 0: No TSF required in outgoing frame.
- * Set this for transmitting beacons and probe responses. */
-#define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16)
-
-/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
- *    alignment of frame's payload data field.
- * 0: No pad
- * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
- * field (but not both).  Driver must align frame data (i.e. data following
- * MAC header) to DWORD boundary. */
-#define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20)
-
-/* HCCA-AP - disable duration overwriting. */
-#define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25)
-
-/*
- * TX command security control
- */
-#define TX_CMD_SEC_WEP  	0x01
-#define TX_CMD_SEC_CCM  	0x02
-#define TX_CMD_SEC_TKIP		0x03
-#define TX_CMD_SEC_MSK		0x03
-#define TX_CMD_SEC_SHIFT	6
-#define TX_CMD_SEC_KEY128	0x08
-
-/*
- * REPLY_TX = 0x1c (command)
- */
-struct iwl3945_tx_cmd {
-	/*
-	 * MPDU byte count:
-	 * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
-	 * + 8 byte IV for CCM or TKIP (not used for WEP)
-	 * + Data payload
-	 * + 8-byte MIC (not used for CCM/WEP)
-	 * NOTE:  Does not include Tx command bytes, post-MAC pad bytes,
-	 *        MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
-	 * Range: 14-2342 bytes.
-	 */
-	__le16 len;
-
-	/*
-	 * MPDU or MSDU byte count for next frame.
-	 * Used for fragmentation and bursting, but not 11n aggregation.
-	 * Same as "len", but for next frame.  Set to 0 if not applicable.
-	 */
-	__le16 next_frame_len;
-
-	__le32 tx_flags;	/* TX_CMD_FLG_* */
-
-	u8 rate;
-
-	/* Index of recipient station in uCode's station table */
-	u8 sta_id;
-	u8 tid_tspec;
-	u8 sec_ctl;
-	u8 key[16];
-	union {
-		u8 byte[8];
-		__le16 word[4];
-		__le32 dw[2];
-	} tkip_mic;
-	__le32 next_frame_info;
-	union {
-		__le32 life_time;
-		__le32 attempt;
-	} stop_time;
-	u8 supp_rates[2];
-	u8 rts_retry_limit;	/*byte 50 */
-	u8 data_retry_limit;	/*byte 51 */
-	union {
-		__le16 pm_frame_timeout;
-		__le16 attempt_duration;
-	} timeout;
-
-	/*
-	 * Duration of EDCA burst Tx Opportunity, in 32-usec units.
-	 * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
-	 */
-	__le16 driver_txop;
-
-	/*
-	 * MAC header goes here, followed by 2 bytes padding if MAC header
-	 * length is 26 or 30 bytes, followed by payload data
-	 */
-	u8 payload[0];
-	struct ieee80211_hdr hdr[0];
-} __attribute__ ((packed));
-
-/* TX command response is sent after *all* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required.  This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response.  This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared.  The host must then deactivate the TX Abort
- * control line.  Receiving is still allowed in this case.
- */
-enum {
-	TX_STATUS_SUCCESS = 0x01,
-	TX_STATUS_DIRECT_DONE = 0x02,
-	TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
-	TX_STATUS_FAIL_LONG_LIMIT = 0x83,
-	TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
-	TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
-	TX_STATUS_FAIL_NEXT_FRAG = 0x86,
-	TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
-	TX_STATUS_FAIL_DEST_PS = 0x88,
-	TX_STATUS_FAIL_ABORTED = 0x89,
-	TX_STATUS_FAIL_BT_RETRY = 0x8a,
-	TX_STATUS_FAIL_STA_INVALID = 0x8b,
-	TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
-	TX_STATUS_FAIL_TID_DISABLE = 0x8d,
-	TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
-	TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
-	TX_STATUS_FAIL_TX_LOCKED = 0x90,
-	TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
-#define	TX_PACKET_MODE_REGULAR		0x0000
-#define	TX_PACKET_MODE_BURST_SEQ	0x0100
-#define	TX_PACKET_MODE_BURST_FIRST	0x0200
-
-enum {
-	TX_POWER_PA_NOT_ACTIVE = 0x0,
-};
-
-enum {
-	TX_STATUS_MSK = 0x000000ff,	/* bits 0:7 */
-	TX_STATUS_DELAY_MSK = 0x00000040,
-	TX_STATUS_ABORT_MSK = 0x00000080,
-	TX_PACKET_MODE_MSK = 0x0000ff00,	/* bits 8:15 */
-	TX_FIFO_NUMBER_MSK = 0x00070000,	/* bits 16:18 */
-	TX_RESERVED = 0x00780000,	/* bits 19:22 */
-	TX_POWER_PA_DETECT_MSK = 0x7f800000,	/* bits 23:30 */
-	TX_ABORT_REQUIRED_MSK = 0x80000000,	/* bits 31:31 */
-};
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
-	u8 failure_rts;
-	u8 failure_frame;
-	u8 bt_kill_count;
-	u8 rate;
-	__le32 wireless_media_time;
-	__le32 status;		/* TX status */
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
- */
-struct iwl3945_txpowertable_cmd {
-	u8 band;		/* 0: 5 GHz, 1: 2.4 GHz */
-	u8 reserved;
-	__le16 channel;
-	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-struct iwl3945_rate_scaling_info {
-	__le16 rate_n_flags;
-	u8 try_cnt;
-	u8 next_rate_index;
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
- */
-struct iwl3945_rate_scaling_cmd {
-	u8 table_id;
-	u8 reserved[3];
-	struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
- *
- * 3945 and 4965 support hardware handshake with Bluetooth device on
- * same platform.  Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accommodate.
- */
-struct iwl3945_bt_cmd {
-	u8 flags;
-	u8 lead_time;
-	u8 max_kill;
-	u8 reserved;
-	__le32 kill_ack_mask;
-	__le32 kill_cts_mask;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (6)
- * Spectrum Management (802.11h) Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/*
- * Spectrum Management
- */
-#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK         | \
-				 RXON_FILTER_CTL2HOST_MSK        | \
-				 RXON_FILTER_ACCEPT_GRP_MSK      | \
-				 RXON_FILTER_DIS_DECRYPT_MSK     | \
-				 RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
-				 RXON_FILTER_ASSOC_MSK           | \
-				 RXON_FILTER_BCON_AWARE_MSK)
-
-struct iwl3945_measure_channel {
-	__le32 duration;	/* measurement duration in extended beacon
-				 * format */
-	u8 channel;		/* channel to measure */
-	u8 type;		/* see enum iwl3945_measure_type */
-	__le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
- */
-struct iwl3945_spectrum_cmd {
-	__le16 len;		/* number of bytes starting from token */
-	u8 token;		/* token id */
-	u8 id;			/* measurement id -- 0 or 1 */
-	u8 origin;		/* 0 = TGh, 1 = other, 2 = TGk */
-	u8 periodic;		/* 1 = periodic */
-	__le16 path_loss_timeout;
-	__le32 start_time;	/* start time in extended beacon format */
-	__le32 reserved2;
-	__le32 flags;		/* rxon flags */
-	__le32 filter_flags;	/* rxon filter flags */
-	__le16 channel_count;	/* minimum 1, maximum 10 */
-	__le16 reserved3;
-	struct iwl3945_measure_channel channels[10];
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
- */
-struct iwl3945_spectrum_resp {
-	u8 token;
-	u8 id;			/* id of the prior command replaced, or 0xff */
-	__le16 status;		/* 0 - command will be handled
-				 * 1 - cannot handle (conflicts with another
-				 *     measurement) */
-} __attribute__ ((packed));
-
-enum iwl3945_measurement_state {
-	IWL_MEASUREMENT_START = 0,
-	IWL_MEASUREMENT_STOP = 1,
-};
-
-enum iwl3945_measurement_status {
-	IWL_MEASUREMENT_OK = 0,
-	IWL_MEASUREMENT_CONCURRENT = 1,
-	IWL_MEASUREMENT_CSA_CONFLICT = 2,
-	IWL_MEASUREMENT_TGH_CONFLICT = 3,
-	/* 4-5 reserved */
-	IWL_MEASUREMENT_STOPPED = 6,
-	IWL_MEASUREMENT_TIMEOUT = 7,
-	IWL_MEASUREMENT_PERIODIC_FAILED = 8,
-};
-
-#define NUM_ELEMENTS_IN_HISTOGRAM 8
-
-struct iwl3945_measurement_histogram {
-	__le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM];	/* in 0.8usec counts */
-	__le32 cck[NUM_ELEMENTS_IN_HISTOGRAM];	/* in 1usec counts */
-} __attribute__ ((packed));
-
-/* clear channel availability counters */
-struct iwl3945_measurement_cca_counters {
-	__le32 ofdm;
-	__le32 cck;
-} __attribute__ ((packed));
-
-enum iwl3945_measure_type {
-	IWL_MEASURE_BASIC = (1 << 0),
-	IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
-	IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
-	IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
-	IWL_MEASURE_FRAME = (1 << 4),
-	/* bits 5:6 are reserved */
-	IWL_MEASURE_IDLE = (1 << 7),
-};
-
-/*
- * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
- */
-struct iwl3945_spectrum_notification {
-	u8 id;			/* measurement id -- 0 or 1 */
-	u8 token;
-	u8 channel_index;	/* index in measurement channel list */
-	u8 state;		/* 0 - start, 1 - stop */
-	__le32 start_time;	/* lower 32-bits of TSF */
-	u8 band;		/* 0 - 5.2GHz, 1 - 2.4GHz */
-	u8 channel;
-	u8 type;		/* see enum iwl3945_measurement_type */
-	u8 reserved1;
-	/* NOTE:  cca_ofdm, cca_cck, basic_type, and histogram are only only
-	 * valid if applicable for measurement type requested. */
-	__le32 cca_ofdm;	/* cca fraction time in 40Mhz clock periods */
-	__le32 cca_cck;		/* cca fraction time in 44Mhz clock periods */
-	__le32 cca_time;	/* channel load time in usecs */
-	u8 basic_type;		/* 0 - bss, 1 - ofdm preamble, 2 -
-				 * unidentified */
-	u8 reserved2[3];
-	struct iwl3945_measurement_histogram histogram;
-	__le32 stop_time;	/* lower 32-bits of TSF */
-	__le32 status;		/* see iwl3945_measurement_status */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (7)
- * Power Management Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_powertable_cmd - Power Table Command
- * @flags: See below:
- *
- * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
- *
- * PM allow:
- *   bit 0 - '0' Driver not allow power management
- *           '1' Driver allow PM (use rest of parameters)
- * uCode send sleep notifications:
- *   bit 1 - '0' Don't send sleep notification
- *           '1' send sleep notification (SEND_PM_NOTIFICATION)
- * Sleep over DTIM
- *   bit 2 - '0' PM have to walk up every DTIM
- *           '1' PM could sleep over DTIM till listen Interval.
- * PCI power managed
- *   bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- *           '1' !(PCI_LINK_CTRL & 0x1)
- * Force sleep Modes
- *   bit 31/30- '00' use both mac/xtal sleeps
- *              '01' force Mac sleep
- *              '10' force xtal sleep
- *              '11' Illegal set
- *
- * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
- * for every DTIM.
- */
-#define IWL_POWER_VEC_SIZE 5
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK	cpu_to_le32(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK		cpu_to_le32(1 << 2)
-#define IWL_POWER_PCI_PM_MSK			cpu_to_le32(1 << 3)
-struct iwl3945_powertable_cmd {
-	__le32 flags;
-	__le32 rx_data_timeout;
-	__le32 tx_data_timeout;
-	__le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __attribute__((packed));
-
-/*
- * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
- */
-struct iwl3945_sleep_notification {
-	u8 pm_sleep_mode;
-	u8 pm_wakeup_src;
-	__le16 reserved;
-	__le32 sleep_time;
-	__le32 tsf_low;
-	__le32 bcon_timer;
-} __attribute__ ((packed));
-
-/* Sleep states.  3945 and 4965 identical. */
-enum {
-	IWL_PM_NO_SLEEP = 0,
-	IWL_PM_SLP_MAC = 1,
-	IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
-	IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
-	IWL_PM_SLP_PHY = 4,
-	IWL_PM_SLP_REPENT = 5,
-	IWL_PM_WAKEUP_BY_TIMER = 6,
-	IWL_PM_WAKEUP_BY_DRIVER = 7,
-	IWL_PM_WAKEUP_BY_RFKILL = 8,
-	/* 3 reserved */
-	IWL_PM_NUM_OF_MODES = 12,
-};
-
-/*
- * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
- */
-#define CARD_STATE_CMD_DISABLE 0x00	/* Put card to sleep */
-#define CARD_STATE_CMD_ENABLE  0x01	/* Wake up card */
-#define CARD_STATE_CMD_HALT    0x02	/* Power down permanently */
-struct iwl3945_card_state_cmd {
-	__le32 status;		/* CARD_STATE_CMD_* request new power state */
-} __attribute__ ((packed));
-
-/*
- * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
- */
-struct iwl3945_card_state_notif {
-	__le32 flags;
-} __attribute__ ((packed));
-
-#define HW_CARD_DISABLED   0x01
-#define SW_CARD_DISABLED   0x02
-#define RF_CARD_DISABLED   0x04
-#define RXON_CARD_DISABLED 0x10
-
-struct iwl3945_ct_kill_config {
-	__le32   reserved;
-	__le32   critical_temperature_M;
-	__le32   critical_temperature_R;
-}  __attribute__ ((packed));
-
-/******************************************************************************
- * (8)
- * Scan Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table
- *
- * One for each channel in the scan list.
- * Each channel can independently select:
- * 1)  SSID for directed active scans
- * 2)  Txpower setting (for rate specified within Tx command)
- * 3)  How long to stay on-channel (behavior may be modified by quiet_time,
- *     quiet_plcp_th, good_CRC_th)
- *
- * To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl3945_scan_cmd about max_out_time and quiet_time):
- * 1)  If using passive_dwell (i.e. passive_dwell != 0):
- *     active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
- * 2)  quiet_time <= active_dwell
- * 3)  If restricting off-channel time (i.e. max_out_time !=0):
- *     passive_dwell < max_out_time
- *     active_dwell < max_out_time
- */
-struct iwl3945_scan_channel {
-	/*
-	 * type is defined as:
-	 * 0:0 1 = active, 0 = passive
-	 * 1:4 SSID direct bit map; if a bit is set, then corresponding
-	 *     SSID IE is transmitted in probe request.
-	 * 5:7 reserved
-	 */
-	u8 type;
-	u8 channel;	/* band is selected by iwl3945_scan_cmd "flags" field */
-	struct iwl3945_tx_power tpc;
-	__le16 active_dwell;	/* in 1024-uSec TU (time units), typ 5-50 */
-	__le16 passive_dwell;	/* in 1024-uSec TU (time units), typ 20-500 */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_ssid_ie - directed scan network information element
- *
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl3945_scan_channel; each channel may select different ssids from
- * among the 4 entries.  SSID IEs get transmitted in reverse order of entry.
- */
-struct iwl3945_ssid_ie {
-	u8 id;
-	u8 len;
-	u8 ssid[32];
-} __attribute__ ((packed));
-
-#define PROBE_OPTION_MAX        0x4
-#define TX_CMD_LIFE_TIME_INFINITE	cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH		cpu_to_le16(1)
-#define IWL_MAX_SCAN_SIZE 1024
-
-/*
- * REPLY_SCAN_CMD = 0x80 (command)
- *
- * The hardware scan command is very powerful; the driver can set it up to
- * maintain (relatively) normal network traffic while doing a scan in the
- * background.  The max_out_time and suspend_time control the ratio of how
- * long the device stays on an associated network channel ("service channel")
- * vs. how long it's away from the service channel, tuned to other channels
- * for scanning.
- *
- * max_out_time is the max time off-channel (in usec), and suspend_time
- * is how long (in "extended beacon" format) that the scan is "suspended"
- * after returning to the service channel.  That is, suspend_time is the
- * time that we stay on the service channel, doing normal work, between
- * scan segments.  The driver may set these parameters differently to support
- * scanning when associated vs. not associated, and light vs. heavy traffic
- * loads when associated.
- *
- * After receiving this command, the device's scan engine does the following;
- *
- * 1)  Sends SCAN_START notification to driver
- * 2)  Checks to see if it has time to do scan for one channel
- * 3)  Sends NULL packet, with power-save (PS) bit set to 1,
- *     to tell AP that we're going off-channel
- * 4)  Tunes to first channel in scan list, does active or passive scan
- * 5)  Sends SCAN_RESULT notification to driver
- * 6)  Checks to see if it has time to do scan on *next* channel in list
- * 7)  Repeats 4-6 until it no longer has time to scan the next channel
- *     before max_out_time expires
- * 8)  Returns to service channel
- * 9)  Sends NULL packet with PS=0 to tell AP that we're back
- * 10) Stays on service channel until suspend_time expires
- * 11) Repeats entire process 2-10 until list is complete
- * 12) Sends SCAN_COMPLETE notification
- *
- * For fast, efficient scans, the scan command also has support for staying on
- * a channel for just a short time, if doing active scanning and getting no
- * responses to the transmitted probe request.  This time is controlled by
- * quiet_time, and the number of received packets below which a channel is
- * considered "quiet" is controlled by quiet_plcp_threshold.
- *
- * For active scanning on channels that have regulatory restrictions against
- * blindly transmitting, the scan can listen before transmitting, to make sure
- * that there is already legitimate activity on the channel.  If enough
- * packets are cleanly received on the channel (controlled by good_CRC_th,
- * typical value 1), the scan engine starts transmitting probe requests.
- *
- * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
- *
- * To avoid uCode errors, see timing restrictions described under
- * struct iwl3945_scan_channel.
- */
-struct iwl3945_scan_cmd {
-	__le16 len;
-	u8 reserved0;
-	u8 channel_count;	/* # channels in channel list */
-	__le16 quiet_time;	/* dwell only this # millisecs on quiet channel
-				 * (only for active scan) */
-	__le16 quiet_plcp_th;	/* quiet chnl is < this # pkts (typ. 1) */
-	__le16 good_CRC_th;	/* passive -> active promotion threshold */
-	__le16 reserved1;
-	__le32 max_out_time;	/* max usec to be away from associated (service)
-				 * channel */
-	__le32 suspend_time;	/* pause scan this long (in "extended beacon
-				 * format") when returning to service channel:
-				 * 3945; 31:24 # beacons, 19:0 additional usec,
-				 * 4965; 31:22 # beacons, 21:0 additional usec.
-				 */
-	__le32 flags;		/* RXON_FLG_* */
-	__le32 filter_flags;	/* RXON_FILTER_* */
-
-	/* For active scans (set to all-0s for passive scans).
-	 * Does not include payload.  Must specify Tx rate; no rate scaling. */
-	struct iwl3945_tx_cmd tx_cmd;
-
-	/* For directed active scans (set to all-0s otherwise) */
-	struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX];
-
-	/*
-	 * Probe request frame, followed by channel list.
-	 *
-	 * Size of probe request frame is specified by byte count in tx_cmd.
-	 * Channel list follows immediately after probe request frame.
-	 * Number of channels in list is specified by channel_count.
-	 * Each channel in list is of type:
-	 *
-	 * struct iwl3945_scan_channel channels[0];
-	 *
-	 * NOTE:  Only one band of channels can be scanned per pass.  You
-	 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
-	 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
-	 * before requesting another scan.
-	 */
-	u8 data[0];
-} __attribute__ ((packed));
-
-/* Can abort will notify by complete notification with abort status. */
-#define CAN_ABORT_STATUS	cpu_to_le32(0x1)
-/* complete notification statuses */
-#define ABORT_STATUS            0x2
-
-/*
- * REPLY_SCAN_CMD = 0x80 (response)
- */
-struct iwl3945_scanreq_notification {
-	__le32 status;		/* 1: okay, 2: cannot fulfill request */
-} __attribute__ ((packed));
-
-/*
- * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
- */
-struct iwl3945_scanstart_notification {
-	__le32 tsf_low;
-	__le32 tsf_high;
-	__le32 beacon_timer;
-	u8 channel;
-	u8 band;
-	u8 reserved[2];
-	__le32 status;
-} __attribute__ ((packed));
-
-#define  SCAN_OWNER_STATUS 0x1;
-#define  MEASURE_OWNER_STATUS 0x2;
-
-#define NUMBER_OF_STATISTICS 1	/* first __le32 is good CRC */
-/*
- * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
- */
-struct iwl3945_scanresults_notification {
-	u8 channel;
-	u8 band;
-	u8 reserved[2];
-	__le32 tsf_low;
-	__le32 tsf_high;
-	__le32 statistics[NUMBER_OF_STATISTICS];
-} __attribute__ ((packed));
-
-/*
- * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
- */
-struct iwl3945_scancomplete_notification {
-	u8 scanned_channels;
-	u8 status;
-	u8 reserved;
-	u8 last_channel;
-	__le32 tsf_low;
-	__le32 tsf_high;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (9)
- * IBSS/AP Commands and Notifications:
- *
- *****************************************************************************/
-
-/*
- * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
- */
-struct iwl3945_beacon_notif {
-	struct iwl3945_tx_resp beacon_notify_hdr;
-	__le32 low_tsf;
-	__le32 high_tsf;
-	__le32 ibss_mgr_status;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
- */
-struct iwl3945_tx_beacon_cmd {
-	struct iwl3945_tx_cmd tx;
-	__le16 tim_idx;
-	u8 tim_size;
-	u8 reserved1;
-	struct ieee80211_hdr frame[0];	/* beacon frame */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (10)
- * Statistics Commands and Notifications:
- *
- *****************************************************************************/
-
-#define IWL_TEMP_CONVERT 260
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
-
-/* Used for passing to driver number of successes and failures per rate */
-struct rate_histogram {
-	union {
-		__le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-		__le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-		__le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
-	} success;
-	union {
-		__le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-		__le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-		__le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
-	} failed;
-} __attribute__ ((packed));
-
-/* statistics command response */
-
-struct statistics_rx_phy {
-	__le32 ina_cnt;
-	__le32 fina_cnt;
-	__le32 plcp_err;
-	__le32 crc32_err;
-	__le32 overrun_err;
-	__le32 early_overrun_err;
-	__le32 crc32_good;
-	__le32 false_alarm_cnt;
-	__le32 fina_sync_err_cnt;
-	__le32 sfd_timeout;
-	__le32 fina_timeout;
-	__le32 unresponded_rts;
-	__le32 rxe_frame_limit_overrun;
-	__le32 sent_ack_cnt;
-	__le32 sent_cts_cnt;
-} __attribute__ ((packed));
-
-struct statistics_rx_non_phy {
-	__le32 bogus_cts;	/* CTS received when not expecting CTS */
-	__le32 bogus_ack;	/* ACK received when not expecting ACK */
-	__le32 non_bssid_frames;	/* number of frames with BSSID that
-					 * doesn't belong to the STA BSSID */
-	__le32 filtered_frames;	/* count frames that were dumped in the
-				 * filtering process */
-	__le32 non_channel_beacons;	/* beacons with our bss id but not on
-					 * our serving channel */
-} __attribute__ ((packed));
-
-struct statistics_rx {
-	struct statistics_rx_phy ofdm;
-	struct statistics_rx_phy cck;
-	struct statistics_rx_non_phy general;
-} __attribute__ ((packed));
-
-struct statistics_tx {
-	__le32 preamble_cnt;
-	__le32 rx_detected_cnt;
-	__le32 bt_prio_defer_cnt;
-	__le32 bt_prio_kill_cnt;
-	__le32 few_bytes_cnt;
-	__le32 cts_timeout;
-	__le32 ack_timeout;
-	__le32 expected_ack_cnt;
-	__le32 actual_ack_cnt;
-} __attribute__ ((packed));
-
-struct statistics_dbg {
-	__le32 burst_check;
-	__le32 burst_count;
-	__le32 reserved[4];
-} __attribute__ ((packed));
-
-struct statistics_div {
-	__le32 tx_on_a;
-	__le32 tx_on_b;
-	__le32 exec_time;
-	__le32 probe_time;
-} __attribute__ ((packed));
-
-struct statistics_general {
-	__le32 temperature;
-	struct statistics_dbg dbg;
-	__le32 sleep_time;
-	__le32 slots_out;
-	__le32 slots_idle;
-	__le32 ttl_timestamp;
-	struct statistics_div div;
-} __attribute__ ((packed));
-
-/*
- * REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
- *
- * This command triggers an immediate response containing uCode statistics.
- * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
- *
- * If the CLEAR_STATS configuration flag is set, uCode will clear its
- * internal copy of the statistics (counters) after issuing the response.
- * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
- *
- * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
- * STATISTICS_NOTIFICATIONs after received beacons (see below).  This flag
- * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
- */
-#define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1)	/* see above */
-#define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */
-struct iwl3945_statistics_cmd {
-	__le32 configuration_flags;	/* IWL_STATS_CONF_* */
-} __attribute__ ((packed));
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans.  uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-#define STATISTICS_REPLY_FLG_BAND_24G_MSK         cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK         cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
-	__le32 flag;
-	struct statistics_rx rx;
-	struct statistics_tx tx;
-	struct statistics_general general;
-} __attribute__ ((packed));
-
-
-/*
- * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
- */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
-
-struct iwl3945_missed_beacon_notif {
-	__le32 consequtive_missed_beacons;
-	__le32 total_missed_becons;
-	__le32 num_expected_beacons;
-	__le32 num_recvd_beacons;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (11)
- * Rx Calibration Commands:
- *
- *****************************************************************************/
-
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-#define HD_TABLE_SIZE  (11)
-
-struct iwl3945_sensitivity_cmd {
-	__le16 control;
-	__le16 table[HD_TABLE_SIZE];
-} __attribute__ ((packed));
-
-struct iwl3945_calibration_cmd {
-	u8 opCode;
-	u8 flags;
-	__le16 reserved;
-	s8 diff_gain_a;
-	s8 diff_gain_b;
-	s8 diff_gain_c;
-	u8 reserved1;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (12)
- * Miscellaneous Commands:
- *
- *****************************************************************************/
-
-/*
- * LEDs Command & Response
- * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
- *
- * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
- * this command turns it on or off, or sets up a periodic blinking cycle.
- */
-struct iwl3945_led_cmd {
-	__le32 interval;	/* "interval" in uSec */
-	u8 id;			/* 1: Activity, 2: Link, 3: Tech */
-	u8 off;			/* # intervals off while blinking;
-				 * "0", with >0 "on" value, turns LED on */
-	u8 on;			/* # intervals on while blinking;
-				 * "0", regardless of "off", turns LED off */
-	u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_packet {
-	__le32 len;
-	struct iwl3945_cmd_header hdr;
-	union {
-		struct iwl3945_alive_resp alive_frame;
-		struct iwl3945_rx_frame rx_frame;
-		struct iwl3945_tx_resp tx_resp;
-		struct iwl3945_spectrum_notification spectrum_notif;
-		struct iwl3945_csa_notification csa_notif;
-		struct iwl3945_error_resp err_resp;
-		struct iwl3945_card_state_notif card_state_notif;
-		struct iwl3945_beacon_notif beacon_status;
-		struct iwl3945_add_sta_resp add_sta;
-		struct iwl3945_sleep_notification sleep_notif;
-		struct iwl3945_spectrum_resp spectrum;
-		struct iwl3945_notif_statistics stats;
-		__le32 status;
-		u8 raw[0];
-	} u;
-} __attribute__ ((packed));
-
-#define IWL_RX_FRAME_SIZE        (4 + sizeof(struct iwl3945_rx_frame))
-
-#endif				/* __iwl3945_3945_commands_h__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-core.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-core.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,104 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 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.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-#ifndef __iwl_3945_dev_h__
-#define __iwl_3945_dev_h__
-
-#define IWL_PCI_DEVICE(dev, subdev, cfg) \
-	.vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
-	.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
-	.driver_data = (kernel_ulong_t)&(cfg)
-
-#define IWL_SKU_G       0x1
-#define IWL_SKU_A       0x2
-
-/**
- * struct iwl_3945_cfg
- * @fw_name_pre: Firmware filename prefix. The api version and extension
- * 	(.ucode) will be added to filename before loading from disk. The
- * 	filename is constructed as fw_name_pre<api>.ucode.
- * @ucode_api_max: Highest version of uCode API supported by driver.
- * @ucode_api_min: Lowest version of uCode API supported by driver.
- *
- * We enable the driver to be backward compatible wrt API version. The
- * driver specifies which APIs it supports (with @ucode_api_max being the
- * highest and @ucode_api_min the lowest). Firmware will only be loaded if
- * it has a supported API version. The firmware's API version will be
- * stored in @iwl_priv, enabling the driver to make runtime changes based
- * on firmware version used.
- *
- * For example,
- * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
- * 	Driver interacts with Firmware API version >= 2.
- * } else {
- * 	Driver interacts with Firmware API version 1.
- * }
- */
-struct iwl_3945_cfg {
-	const char *name;
-	const char *fw_name_pre;
-	const unsigned int ucode_api_max;
-	const unsigned int ucode_api_min;
-	unsigned int sku;
-};
-
-#endif /* __iwl_dev_h__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-debug.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-debug.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-debug.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,167 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * 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 __iwl3945_debug_h__
-#define __iwl3945_debug_h__
-
-#ifdef CONFIG_IWL3945_DEBUG
-extern u32 iwl3945_debug_level;
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl3945_debug_level & (level)) \
-  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
-  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-	if (!(iwl3945_debug_level & level))
-		return;
-
-	print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
-			p, len, 1);
-}
-#else
-static inline void IWL_DEBUG(int level, const char *fmt, ...)
-{
-}
-static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
-{
-}
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-}
-#endif	/* CONFIG_IWL3945_DEBUG */
-
-
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IWL_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
- * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/iwl/debug_level
- *
- * you simply need to add your entry to the iwl3945_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWL3945_DEBUG defined in your kernel configuration
- *
- */
-
-#define IWL_DL_INFO          (1 << 0)
-#define IWL_DL_MAC80211      (1 << 1)
-#define IWL_DL_HOST_COMMAND  (1 << 2)
-#define IWL_DL_STATE         (1 << 3)
-
-#define IWL_DL_RADIO         (1 << 7)
-#define IWL_DL_POWER         (1 << 8)
-#define IWL_DL_TEMP          (1 << 9)
-
-#define IWL_DL_NOTIF         (1 << 10)
-#define IWL_DL_SCAN          (1 << 11)
-#define IWL_DL_ASSOC         (1 << 12)
-#define IWL_DL_DROP          (1 << 13)
-
-#define IWL_DL_TXPOWER       (1 << 14)
-
-#define IWL_DL_AP            (1 << 15)
-
-#define IWL_DL_FW            (1 << 16)
-#define IWL_DL_RF_KILL       (1 << 17)
-#define IWL_DL_FW_ERRORS     (1 << 18)
-
-#define IWL_DL_LED           (1 << 19)
-
-#define IWL_DL_RATE          (1 << 20)
-
-#define IWL_DL_CALIB         (1 << 21)
-#define IWL_DL_WEP           (1 << 22)
-#define IWL_DL_TX            (1 << 23)
-#define IWL_DL_RX            (1 << 24)
-#define IWL_DL_ISR           (1 << 25)
-#define IWL_DL_HT            (1 << 26)
-#define IWL_DL_IO            (1 << 27)
-#define IWL_DL_11H           (1 << 28)
-
-#define IWL_DL_STATS         (1 << 29)
-#define IWL_DL_TX_REPLY      (1 << 30)
-#define IWL_DL_QOS           (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...)    IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...)     IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...)   IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...)   IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...)     IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...)     IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...)    IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...)    IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
-	IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...)  IWL_DEBUG(IWL_DL_11H, f, ## a)
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-fh.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 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.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_3945_fh_h__
+#define __iwl_3945_fh_h__
+
+/************************************/
+/* iwl3945 Flow Handler Definitions */
+/************************************/
+
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
+#define FH39_MEM_LOWER_BOUND                   (0x0800)
+#define FH39_MEM_UPPER_BOUND                   (0x1000)
+
+#define FH39_CBCC_TABLE		(FH39_MEM_LOWER_BOUND + 0x140)
+#define FH39_TFDB_TABLE		(FH39_MEM_LOWER_BOUND + 0x180)
+#define FH39_RCSR_TABLE		(FH39_MEM_LOWER_BOUND + 0x400)
+#define FH39_RSSR_TABLE		(FH39_MEM_LOWER_BOUND + 0x4c0)
+#define FH39_TCSR_TABLE		(FH39_MEM_LOWER_BOUND + 0x500)
+#define FH39_TSSR_TABLE		(FH39_MEM_LOWER_BOUND + 0x680)
+
+/* TFDB (Transmit Frame Buffer Descriptor) */
+#define FH39_TFDB(_ch, buf)			(FH39_TFDB_TABLE + \
+						 ((_ch) * 2 + (buf)) * 0x28)
+#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch)	(FH39_TFDB_TABLE + 0x50 * (_ch))
+
+/* CBCC channel is [0,2] */
+#define FH39_CBCC(_ch)		(FH39_CBCC_TABLE + (_ch) * 0x8)
+#define FH39_CBCC_CTRL(_ch)	(FH39_CBCC(_ch) + 0x00)
+#define FH39_CBCC_BASE(_ch)	(FH39_CBCC(_ch) + 0x04)
+
+/* RCSR channel is [0,2] */
+#define FH39_RCSR(_ch)			(FH39_RCSR_TABLE + (_ch) * 0x40)
+#define FH39_RCSR_CONFIG(_ch)		(FH39_RCSR(_ch) + 0x00)
+#define FH39_RCSR_RBD_BASE(_ch)		(FH39_RCSR(_ch) + 0x04)
+#define FH39_RCSR_WPTR(_ch)		(FH39_RCSR(_ch) + 0x20)
+#define FH39_RCSR_RPTR_ADDR(_ch)	(FH39_RCSR(_ch) + 0x24)
+
+#define FH39_RSCSR_CHNL0_WPTR		(FH39_RCSR_WPTR(0))
+
+/* RSSR */
+#define FH39_RSSR_CTRL			(FH39_RSSR_TABLE + 0x000)
+#define FH39_RSSR_STATUS		(FH39_RSSR_TABLE + 0x004)
+
+/* TCSR */
+#define FH39_TCSR(_ch)			(FH39_TCSR_TABLE + (_ch) * 0x20)
+#define FH39_TCSR_CONFIG(_ch)		(FH39_TCSR(_ch) + 0x00)
+#define FH39_TCSR_CREDIT(_ch)		(FH39_TCSR(_ch) + 0x04)
+#define FH39_TCSR_BUFF_STTS(_ch)	(FH39_TCSR(_ch) + 0x08)
+
+/* TSSR */
+#define FH39_TSSR_CBB_BASE        (FH39_TSSR_TABLE + 0x000)
+#define FH39_TSSR_MSG_CONFIG      (FH39_TSSR_TABLE + 0x008)
+#define FH39_TSSR_TX_STATUS       (FH39_TSSR_TABLE + 0x010)
+
+
+/* DBM */
+
+#define FH39_SRVC_CHNL                            (6)
+
+#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE     (20)
+#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH      (4)
+
+#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN    (0x08000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE        (0x80000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE           (0x20000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128		(0x01000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST		(0x00001000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH			(0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF		(0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER		(0x00000001)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL	(0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL	(0x00000008)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD		(0x00200000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT		(0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE		(0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE		(0x80000000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID		(0x00004000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR		(0x00000001)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON	(0xFF000000)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON	(0x00FF0000)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B	(0x00000400)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON		(0x00000100)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON		(0x00000080)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH	(0x00000020)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH		(0x00000005)
+
+#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch)	(BIT(_ch) << 24)
+#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)	(BIT(_ch) << 16)
+
+#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \
+	(FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \
+	 FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch))
+
+#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE			(0x01000000)
+
+struct iwl3945_tfd_tb {
+	__le32 addr;
+	__le32 len;
+} __attribute__ ((packed));
+
+struct iwl3945_tfd {
+	__le32 control_flags;
+	struct iwl3945_tfd_tb tbs[4];
+	u8 __pad[28];
+} __attribute__ ((packed));
+
+
+#endif /* __iwl_3945_fh_h__ */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 18:04:34.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945.h	2013-05-03 16:48:23.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -43,11 +43,13 @@
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 extern struct pci_device_id iwl3945_hw_card_ids[];
 
-#define DRV_NAME	"iwl3945"
 #include "iwl-csr.h"
 #include "iwl-prph.h"
+#include "iwl-fh.h"
 #include "iwl-3945-hw.h"
-#include "iwl-3945-debug.h"
+#include "iwl-debug.h"
+#include "iwl-power.h"
+#include "iwl-dev.h"
 #include "iwl-3945-led.h"
 
 /* Highest firmware API version supported */
@@ -74,8 +76,7 @@ extern struct pci_device_id iwl3945_hw_c
 #define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
 
 /* Module parameters accessible from iwl-*.c */
-extern int iwl3945_param_hwcrypto;
-extern int iwl3945_param_queues_num;
+extern struct iwl_mod_params iwl3945_mod_params;
 
 struct iwl3945_sta_priv {
 	struct iwl3945_rs_sta *rs_sta;
@@ -95,7 +96,6 @@ enum iwl3945_antenna {
  * else RTS for data/management frames where MPDU is larger
  *   than RTS value.
  */
-#define IWL_RX_BUF_SIZE           3000U
 #define DEFAULT_RTS_THRESHOLD     2347U
 #define MIN_RTS_THRESHOLD         0U
 #define MAX_RTS_THRESHOLD         2347U
@@ -105,136 +105,7 @@ enum iwl3945_antenna {
 #define	DEFAULT_SHORT_RETRY_LIMIT 7U
 #define	DEFAULT_LONG_RETRY_LIMIT  4U
 
-struct iwl3945_rx_mem_buffer {
-	dma_addr_t dma_addr;
-	struct sk_buff *skb;
-	struct list_head list;
-};
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-struct iwl3945_queue {
-	int n_bd;              /* number of BDs in this queue */
-	int write_ptr;       /* 1-st empty entry (index) host_w*/
-	int read_ptr;         /* last used entry (index) host_r*/
-	dma_addr_t dma_addr;   /* physical addr for BD's */
-	int n_window;	       /* safe queue window */
-	u32 id;
-	int low_mark;	       /* low watermark, resume queue if free
-				* space more than this */
-	int high_mark;         /* high watermark, stop queue if free
-				* space less than this */
-} __attribute__ ((packed));
-
-int iwl3945_queue_space(const struct iwl3945_queue *q);
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
-
-#define MAX_NUM_OF_TBS          (20)
-
-/* One for each TFD */
-struct iwl3945_tx_info {
-	struct sk_buff *skb[MAX_NUM_OF_TBS];
-};
-
-/**
- * struct iwl3945_tx_queue - Tx Queue for DMA
- * @q: generic Rx/Tx queue descriptor
- * @bd: base of circular buffer of TFDs
- * @cmd: array of command/Tx buffers
- * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
- * @need_update: indicates need to update read/write index
- *
- * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
- * descriptors) and required locking structures.
- */
-struct iwl3945_tx_queue {
-	struct iwl3945_queue q;
-	struct iwl3945_tfd_frame *bd;
-	struct iwl3945_cmd *cmd;
-	dma_addr_t dma_addr_cmd;
-	struct iwl3945_tx_info *txb;
-	int need_update;
-	int active;
-};
-
-#define IWL_NUM_SCAN_RATES         (2)
-
-struct iwl3945_channel_tgd_info {
-	u8 type;
-	s8 max_power;
-};
-
-struct iwl3945_channel_tgh_info {
-	s64 last_radar_time;
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
-	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
-	s8 power_table_index;	/* actual (compenst'd) index into gain table */
-	s8 base_power_index;	/* gain index for power at factory temp. */
-	s8 requested_power;	/* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
-	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
-	s8 power_table_index;	/* actual (compenst'd) index into gain table */
-	s8 requested_power;	/* scan pwr (dBm) requested for chnl/rate */
-};
-
-/*
- * One for each channel, holds all channel setup data
- * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
- *     with one another!
- */
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_channel_info {
-	struct iwl3945_channel_tgd_info tgd;
-	struct iwl3945_channel_tgh_info tgh;
-	struct iwl3945_eeprom_channel eeprom;	/* EEPROM regulatory limit */
-	struct iwl3945_eeprom_channel fat_eeprom;	/* EEPROM regulatory limit for
-						 * FAT channel */
-
-	u8 channel;	  /* channel number */
-	u8 flags;	  /* flags copied from EEPROM */
-	s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
-	s8 curr_txpow;	  /* (dBm) regulatory/spectrum/user (not h/w) */
-	s8 min_power;	  /* always 0 */
-	s8 scan_power;	  /* (dBm) regul. eeprom, direct scans, any rate */
-
-	u8 group_index;	  /* 0-4, maps channel to group1/2/3/4/5 */
-	u8 band_index;	  /* 0-4, maps channel to band1/2/3/4/5 */
-	enum ieee80211_band band;
-
-	/* Radio/DSP gain settings for each "normal" data Tx rate.
-	 * These include, in addition to RF and DSP gain, a few fields for
-	 *   remembering/modifying gain settings (indexes). */
-	struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
-	/* Radio/DSP gain settings for each scan rate, for directed scans. */
-	struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
-};
-
-struct iwl3945_clip_group {
-	/* maximum power level to prevent clipping for each rate, derived by
-	 *   us from this band's saturation power in EEPROM */
-	const s8 clip_powers[IWL_MAX_RATES];
-};
-
-#include "iwl-3945-rs.h"
+#include "iwl-agn-rs.h"
 
 #define IWL_TX_FIFO_AC0	0
 #define IWL_TX_FIFO_AC1	1
@@ -247,33 +118,6 @@ struct iwl3945_clip_group {
 /* Minimum number of queues. MAX_NUM is defined in hw specific files */
 #define IWL_MIN_NUM_QUEUES	4
 
-/* Power management (not Tx power) structures */
-
-struct iwl3945_power_vec_entry {
-	struct iwl3945_powertable_cmd cmd;
-	u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0  (0)
-#define IWL_POWER_RANGE_1  (1)
-
-#define IWL_POWER_MODE_CAM	0x00	/* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3	0x03
-#define IWL_POWER_INDEX_5	0x05
-#define IWL_POWER_AC		0x06
-#define IWL_POWER_BATTERY	0x07
-#define IWL_POWER_LIMIT		0x07
-#define IWL_POWER_MASK		0x0F
-#define IWL_POWER_ENABLED	0x10
-#define IWL_POWER_LEVEL(x)	((x) & IWL_POWER_MASK)
-
-struct iwl3945_power_mgr {
-	spinlock_t lock;
-	struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC];
-	struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC];
-	u8 active_index;
-	u32 dtim_val;
-};
-
 #define IEEE80211_DATA_LEN              2304
 #define IEEE80211_4ADDR_LEN             30
 #define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
@@ -289,81 +133,10 @@ struct iwl3945_frame {
 	struct list_head list;
 };
 
-#define SEQ_TO_QUEUE(x)  ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x)  ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
-#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
-#define SEQ_HUGE_FRAME  (0x4000)
-#define SEQ_RX_FRAME    __constant_cpu_to_le16(0x8000)
 #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
 
-enum {
-	/* CMD_SIZE_NORMAL = 0, */
-	CMD_SIZE_HUGE = (1 << 0),
-	/* CMD_SYNC = 0, */
-	CMD_ASYNC = (1 << 1),
-	/* CMD_NO_SKB = 0, */
-	CMD_WANT_SKB = (1 << 2),
-};
-
-struct iwl3945_cmd;
-struct iwl3945_priv;
-
-struct iwl3945_cmd_meta {
-	struct iwl3945_cmd_meta *source;
-	union {
-		struct sk_buff *skb;
-		int (*callback)(struct iwl3945_priv *priv,
-				struct iwl3945_cmd *cmd, struct sk_buff *skb);
-	} __attribute__ ((packed)) u;
-
-	/* The CMD_SIZE_HUGE flag bit indicates that the command
-	 * structure is stored at the end of the shared queue memory. */
-	u32 flags;
-
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_cmd
- *
- * For allocation of the command and tx queues, this establishes the overall
- * size of the largest command we send to uCode, except for a scan command
- * (which is relatively huge; space is allocated separately).
- */
-struct iwl3945_cmd {
-	struct iwl3945_cmd_meta meta;
-	struct iwl3945_cmd_header hdr;
-	union {
-		struct iwl3945_addsta_cmd addsta;
-		struct iwl3945_led_cmd led;
-		u32 flags;
-		u8 val8;
-		u16 val16;
-		u32 val32;
-		struct iwl3945_bt_cmd bt;
-		struct iwl3945_rxon_time_cmd rxon_time;
-		struct iwl3945_powertable_cmd powertable;
-		struct iwl3945_qosparam_cmd qosparam;
-		struct iwl3945_tx_cmd tx;
-		struct iwl3945_tx_beacon_cmd tx_beacon;
-		struct iwl3945_rxon_assoc_cmd rxon_assoc;
-		u8 *indirect;
-		u8 payload[360];
-	} __attribute__ ((packed)) cmd;
-} __attribute__ ((packed));
-
-struct iwl3945_host_cmd {
-	u8 id;
-	u16 len;
-	struct iwl3945_cmd_meta meta;
-	const void *data;
-};
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
-			      sizeof(struct iwl3945_cmd_meta))
-
 /*
  * RX related structures and functions
  */
@@ -374,33 +147,6 @@ struct iwl3945_host_cmd {
 #define SUP_RATE_11B_MAX_NUM_CHANNELS  4
 #define SUP_RATE_11G_MAX_NUM_CHANNELS  12
 
-/**
- * struct iwl3945_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
- * @read: Shared index to newest available Rx buffer
- * @write: Shared index to oldest written Rx packet
- * @free_count: Number of pre-allocated buffers in rx_free
- * @rx_free: list of free SKBs for use
- * @rx_used: List of Rx buffers with no SKB
- * @need_update: flag to indicate we need to update read/write index
- *
- * NOTE:  rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers
- */
-struct iwl3945_rx_queue {
-	__le32 *bd;
-	dma_addr_t dma_addr;
-	struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
-	struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE];
-	u32 processed;
-	u32 read;
-	u32 write;
-	u32 free_count;
-	struct list_head rx_free;
-	struct list_head rx_used;
-	int need_update;
-	spinlock_t lock;
-};
-
 #define IWL_SUPPORTED_RATES_IE_LEN         8
 
 #define SCAN_INTERVAL 100
@@ -430,87 +176,9 @@ struct iwl3945_rx_queue {
 #define IWL_INVALID_RATE     0xFF
 #define IWL_INVALID_VALUE    -1
 
-struct iwl3945_tid_data {
-	u16 seq_number;
-};
-
-struct iwl3945_hw_key {
-	enum ieee80211_key_alg alg;
-	int keylen;
-	u8 key[32];
-};
-
-union iwl3945_ht_rate_supp {
-	u16 rates;
-	struct {
-		u8 siso_rate;
-		u8 mimo_rate;
-	};
-};
-
-union iwl3945_qos_capabity {
-	struct {
-		u8 edca_count:4;	/* bit 0-3 */
-		u8 q_ack:1;		/* bit 4 */
-		u8 queue_request:1;	/* bit 5 */
-		u8 txop_request:1;	/* bit 6 */
-		u8 reserved:1;		/* bit 7 */
-	} q_AP;
-	struct {
-		u8 acvo_APSD:1;		/* bit 0 */
-		u8 acvi_APSD:1;		/* bit 1 */
-		u8 ac_bk_APSD:1;	/* bit 2 */
-		u8 ac_be_APSD:1;	/* bit 3 */
-		u8 q_ack:1;		/* bit 4 */
-		u8 max_len:2;		/* bit 5-6 */
-		u8 more_data_ack:1;	/* bit 7 */
-	} q_STA;
-	u8 val;
-};
-
-/* QoS structures */
-struct iwl3945_qos_info {
-	int qos_active;
-	union iwl3945_qos_capabity qos_cap;
-	struct iwl3945_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 iwl3945_tid_data tid[MAX_TID_COUNT];
-	union {
-		struct {
-			u8 rate;
-			u8 flags;
-		} s;
-		u16 rate_n_flags;
-	} current_rate;
-	u8 used;
-	u8 ps_status;
-	struct iwl3945_hw_key keyinfo;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
-	void *v_addr;		/* access by driver */
-	dma_addr_t p_addr;	/* access by card's busmaster DMA */
-	u32 len;		/* bytes */
-};
-
-/* uCode file layout */
-struct iwl3945_ucode {
-	__le32 ver;		/* major/minor/API/serial */
-	__le32 inst_size;	/* bytes of runtime instructions */
-	__le32 data_size;	/* bytes of runtime data */
-	__le32 init_size;	/* bytes of initialization instructions */
-	__le32 init_data_size;	/* bytes of initialization data */
-	__le32 boot_size;	/* bytes of bootstrap instructions */
-	u8 data[0];		/* data in same order as "size" elements */
-};
-
 struct iwl3945_ibss_seq {
 	u8 mac[ETH_ALEN];
 	u16 seq_num;
@@ -519,34 +187,6 @@ struct iwl3945_ibss_seq {
 	struct list_head list;
 };
 
-/**
- * struct iwl3945_driver_hw_info
- * @max_txq_num: Max # Tx queues supported
- * @tx_cmd_len: Size of Tx command (but not including frame itself)
- * @tx_ant_num: Number of TX antennas
- * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
- * @rx_buf_size:
- * @max_pkt_size:
- * @max_rxq_log: Log-base-2 of max_rxq_size
- * @max_stations:
- * @bcast_sta_id:
- * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
- * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
- */
-struct iwl3945_driver_hw_info {
-	u16 max_txq_num;
-	u16 tx_cmd_len;
-	u16 tx_ant_num;
-	u16 max_rxq_size;
-	u32 rx_buf_size;
-	u32 max_pkt_size;
-	u16 max_rxq_log;
-	u8  max_stations;
-	u8  bcast_sta_id;
-	void *shared_virt;
-	dma_addr_t shared_phys;
-};
-
 #define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\
 		       x->u.rx_frame.stats.payload + \
 		       x->u.rx_frame.stats.phy_count))
@@ -564,40 +204,31 @@ struct iwl3945_driver_hw_info {
  *
  *****************************************************************************/
 struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
+extern int iwl3945_send_add_station(struct iwl_priv *priv,
 				struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
+extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
 			  int is_ap, u8 flags);
-extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
-extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
-extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
-extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
-			       struct iwl3945_rx_queue *rxq);
+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 iwl3945_priv *priv,
-			     struct iwl3945_tx_queue *txq, int count, u32 id);
+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_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
+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 iwl3945_priv *priv,
-		struct iwl3945_host_cmd *cmd);
-extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+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 int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
-					 struct iwl3945_rx_queue *q);
-extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
-extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
-				   u32 decrypt_res,
-				   struct ieee80211_rx_status *stats);
-extern const u8 iwl3945_broadcast_addr[ETH_ALEN];
 
 /*
  * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
  * call this... todo... fix that.
 */
-extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
+extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
 			   u16 tx_rate, u8 flags);
 
 /******************************************************************************
@@ -616,36 +247,37 @@ extern u8 iwl3945_sync_station(struct iw
  * iwl3945_mac_     <-- mac80211 callback
  *
  ****************************************************************************/
-extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv);
-extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv);
-extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
-extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv);
-extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd,
-					dma_addr_t addr, u16 len);
-extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv);
-extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv,
-				struct iwl3945_tx_queue *txq);
-extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv);
+extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv);
+extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv);
+extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_init(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_reset(struct iwl_priv *priv);
+extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+					    struct iwl_tx_queue *txq,
+					    dma_addr_t addr, u16 len,
+					    u8 reset, u8 pad);
+extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv,
+				    struct iwl_tx_queue *txq);
+extern int iwl3945_hw_get_temperature(struct iwl_priv *priv);
+extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
+				struct iwl_tx_queue *txq);
+extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
 				 struct iwl3945_frame *frame, u8 rate);
-extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
-extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
-				     struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
 				     struct ieee80211_tx_info *info,
 				     struct ieee80211_hdr *hdr,
 				     int sta_id, int tx_id);
-extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
-extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power);
-extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv,
-				 struct iwl3945_rx_mem_buffer *rxb);
-extern void iwl3945_disable_events(struct iwl3945_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
+extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
+extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
+extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
+				 struct iwl_rx_mem_buffer *rxb);
+extern void iwl3945_disable_events(struct iwl_priv *priv);
+extern int iwl4965_get_temperature(const struct iwl_priv *priv);
 
 /**
  * iwl3945_hw_find_station - Find station id for a given BSSID
@@ -655,302 +287,26 @@ extern int iwl4965_get_temperature(const
  * not yet been merged into a single common layer for managing the
  * station tables.
  */
-extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid);
+extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
 
-extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
+extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
 
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
-extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
-extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
-extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
-extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id,
+extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
+extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
+extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
+extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
+extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
 		 u16 tx_rate, u8 flags);
 
+extern const struct iwl_channel_info *iwl3945_get_channel_info(
+	const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
 
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
-enum {
-	MEASUREMENT_READY = (1 << 0),
-	MEASUREMENT_ACTIVE = (1 << 1),
-};
-
-#endif
-
-#ifdef CONFIG_IWL3945_RFKILL
-struct iwl3945_priv;
-
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
-int iwl3945_rfkill_init(struct iwl3945_priv *priv);
-#else
-static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {}
-static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {}
-static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; }
-#endif
-
-#define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES
-
-struct iwl3945_priv {
-
-	/* ieee device used by generic ieee processing code */
-	struct ieee80211_hw *hw;
-	struct ieee80211_channel *ieee_channels;
-	struct ieee80211_rate *ieee_rates;
-	struct iwl_3945_cfg *cfg; /* device configuration */
-
-	/* temporary frame storage list */
-	struct list_head free_frames;
-	int frames_count;
-
-	enum ieee80211_band band;
-	int alloc_rxb_skb;
-
-	void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
-				       struct iwl3945_rx_mem_buffer *rxb);
-
-	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-	/* spectrum measurement report caching */
-	struct iwl3945_spectrum_notification measure_report;
-	u8 measurement_status;
-#endif
-	/* ucode beacon time */
-	u32 ucode_beacon_time;
-
-	/* we allocate array of iwl3945_channel_info for NIC's valid channels.
-	 *    Access via channel # using indirect index array */
-	struct iwl3945_channel_info *channel_info;	/* channel info array */
-	u8 channel_count;	/* # of channels */
-
-	/* each calibration channel group in the EEPROM has a derived
-	 * clip setting for each rate. */
-	const struct iwl3945_clip_group clip_groups[5];
-
-	/* thermal calibration */
-	s32 temperature;	/* degrees Kelvin */
-	s32 last_temperature;
-
-	/* Scan related variables */
-	unsigned long last_scan_jiffies;
-	unsigned long next_scan_jiffies;
-	unsigned long scan_start;
-	unsigned long scan_pass_start;
-	unsigned long scan_start_tsf;
-	int scan_bands;
-	int one_direct_scan;
-	u8 direct_ssid_len;
-	u8 direct_ssid[IW_ESSID_MAX_SIZE];
-	struct iwl3945_scan_cmd *scan;
-
-	/* spinlock */
-	spinlock_t lock;	/* protect general shared data */
-	spinlock_t hcmd_lock;	/* protect hcmd */
-	struct mutex mutex;
-
-	/* basic pci-network driver stuff */
-	struct pci_dev *pci_dev;
-
-	/* pci hardware address support */
-	void __iomem *hw_base;
-
-	/* uCode images, save to reload in case of failure */
-	u32 ucode_ver;			/* ucode version, copy of
-					   iwl3945_ucode.ver */
-	struct fw_desc ucode_code;	/* runtime inst */
-	struct fw_desc ucode_data;	/* runtime data original */
-	struct fw_desc ucode_data_backup;	/* runtime data save/restore */
-	struct fw_desc ucode_init;	/* initialization inst */
-	struct fw_desc ucode_init_data;	/* initialization data */
-	struct fw_desc ucode_boot;	/* bootstrap inst */
-
-
-	struct iwl3945_rxon_time_cmd rxon_timing;
-
-	/* We declare this const so it can only be
-	 * changed via explicit cast within the
-	 * routines that actually update the physical
-	 * hardware */
-	const struct iwl3945_rxon_cmd active_rxon;
-	struct iwl3945_rxon_cmd staging_rxon;
-
-	int error_recovering;
-	struct iwl3945_rxon_cmd recovery_rxon;
-
-	/* 1st responses from initialize and runtime uCode images.
-	 * 4965's initialize alive response contains some calibration data. */
-	struct iwl3945_init_alive_resp card_alive_init;
-	struct iwl3945_alive_resp card_alive;
-
-#ifdef CONFIG_IWL3945_RFKILL
-	struct rfkill *rfkill;
-#endif
-
-#ifdef CONFIG_IWL3945_LEDS
-	struct iwl3945_led led[IWL_LED_TRG_MAX];
-	unsigned long last_blink_time;
-	u8 last_blink_rate;
-	u8 allow_blinking;
-	unsigned int rxtxpackets;
-	u64 led_tpt;
-#endif
-
-
-	u16 active_rate;
-	u16 active_rate_basic;
-
-	u32 sta_supp_rates;
-
-	u8 call_post_assoc_from_beacon;
-	/* Rate scaling data */
-	s8 data_retry_limit;
-	u8 retry_rate;
-
-	wait_queue_head_t wait_command_queue;
-
-	int activity_timer_active;
-
-	/* Rx and Tx DMA processing queues */
-	struct iwl3945_rx_queue rxq;
-	struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
-
-	unsigned long status;
-
-	int last_rx_rssi;	/* From Rx packet statisitics */
-	int last_rx_noise;	/* From beacon statistics */
-
-	struct iwl3945_power_mgr power_data;
-
-	struct iwl3945_notif_statistics statistics;
-	unsigned long last_statistics_time;
-
-	/* context information */
-	u16 rates_mask;
-
-	u32 power_mode;
-	u32 antenna;
-	u8 bssid[ETH_ALEN];
-	u16 rts_threshold;
-	u8 mac_addr[ETH_ALEN];
-
-	/*station table variables */
-	spinlock_t sta_lock;
-	int num_stations;
-	struct iwl3945_station_entry stations[IWL_STATION_COUNT];
-
-	/* Indication if ieee80211_ops->open has been called */
-	u8 is_open;
-
-	u8 mac80211_registered;
-
-	/* Rx'd packet timing information */
-	u32 last_beacon_time;
-	u64 last_tsf;
-
-	/* eeprom */
-	struct iwl3945_eeprom eeprom;
-
-	enum nl80211_iftype iw_mode;
-
-	struct sk_buff *ibss_beacon;
-
-	/* Last Rx'd beacon timestamp */
-	u32 timestamp0;
-	u32 timestamp1;
-	u16 beacon_int;
-	struct iwl3945_driver_hw_info hw_setting;
-	struct ieee80211_vif *vif;
-
-	/* Current association information needed to configure the
-	 * hardware */
-	u16 assoc_id;
-	u16 assoc_capability;
-	u8 ps_mode;
-
-	struct iwl3945_qos_info qos_data;
-
-	struct workqueue_struct *workqueue;
-
-	struct work_struct up;
-	struct work_struct restart;
-	struct work_struct calibrated_work;
-	struct work_struct scan_completed;
-	struct work_struct rx_replenish;
-	struct work_struct rf_kill;
-	struct work_struct abort_scan;
-	struct work_struct update_link_led;
-	struct work_struct auth_work;
-	struct work_struct report_work;
-	struct work_struct request_scan;
-	struct work_struct beacon_update;
-
-	struct tasklet_struct irq_tasklet;
-
-	struct delayed_work init_alive_start;
-	struct delayed_work alive_start;
-	struct delayed_work activity_timer;
-	struct delayed_work thermal_periodic;
-	struct delayed_work gather_stats;
-	struct delayed_work scan_check;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
-	s8 user_txpower_limit;
-	s8 max_channel_txpower_limit;
-
-
-#ifdef CONFIG_IWL3945_DEBUG
-	/* debugging info */
-	u32 framecnt_to_us;
-	atomic_t restrict_refcnt;
-#endif
-};				/*iwl3945_priv */
-
-static inline int iwl3945_is_associated(struct iwl3945_priv *priv)
-{
-	return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
-{
-	if (ch_info == NULL)
-		return 0;
-	return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
-}
-
-static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
-{
-	return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
-}
-
-static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
-{
-	return ch_info->band == IEEE80211_BAND_5GHZ;
-}
-
-static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
-{
-	return ch_info->band == IEEE80211_BAND_2GHZ;
-}
-
-static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
-{
-	return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
-}
-
-static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
-{
-	return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
-}
-
-extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
-	const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
-
-extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate);
+extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
 
-/* Requires full declaration of iwl3945_priv before including */
-#include "iwl-3945-io.h"
+/* Requires full declaration of iwl_priv before including */
+#include "iwl-io.h"
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,77 +69,26 @@
 #ifndef __iwl_3945_hw__
 #define __iwl_3945_hw__
 
+#include "iwl-eeprom.h"
+
 /*
  * uCode queue management definitions ...
  * Queue #4 is the command queue for 3945 and 4965.
  */
-#define IWL_CMD_QUEUE_NUM       4
-
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-#define IWL_HT_RATES 0
-#define IWL_MAX_RATES  (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+#define IWL_CMD_QUEUE_NUM	4
 
 /* Time constants */
 #define SHORT_SLOT_TIME 9
 #define LONG_SLOT_TIME 20
 
 /* RSSI to dBm */
-#define IWL_RSSI_OFFSET	95
+#define IWL39_RSSI_OFFSET	95
 
 /*
  * EEPROM related constants, enums, and structures.
  */
-
-/*
- * EEPROM access time values:
- *
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- *   then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- *   CSR_EEPROM_REG_BIT_CMD (0x2).
- * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
- * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
- * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
- */
-#define IWL_EEPROM_ACCESS_TIMEOUT	5000 /* uSec */
-
-/*
- * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
- *
- * IBSS and/or AP operation is allowed *only* on those channels with
- * (VALID && IBSS && ACTIVE && !RADAR).  This restriction is in place because
- * RADAR detection is not supported by the 3945 driver, but is a
- * requirement for establishing a new network for legal operation on channels
- * requiring RADAR detection or restricting ACTIVE scanning.
- *
- * NOTE:  "WIDE" flag indicates that 20 MHz channel is supported;
- *        3945 does not support FAT 40 MHz-wide channels.
- *
- * NOTE:  Using a channel inappropriately will result in a uCode error!
- */
-enum {
-	EEPROM_CHANNEL_VALID = (1 << 0),	/* usable for this SKU/geo */
-	EEPROM_CHANNEL_IBSS = (1 << 1),		/* usable as an IBSS channel */
-	/* Bit 2 Reserved */
-	EEPROM_CHANNEL_ACTIVE = (1 << 3),	/* active scanning allowed */
-	EEPROM_CHANNEL_RADAR = (1 << 4),	/* radar detection required */
-	EEPROM_CHANNEL_WIDE = (1 << 5),		/* 20 MHz channel okay */
-	/* Bit 6 Reserved (was Narrow Channel) */
-	EEPROM_CHANNEL_DFS = (1 << 7),	/* dynamic freq selection candidate */
-};
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE                (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
 #define EEPROM_SKU_CAP_OP_MODE_MRC                      (1 << 7)
 
-/* *regulatory* channel data from eeprom, one for each channel */
-struct iwl3945_eeprom_channel {
-	u8 flags;		/* flags copied from EEPROM */
-	s8 max_power_avg;	/* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
 /*
  * Mapping of a Tx power level, at factory calibration temperature,
  *   to a radio/DSP gain table index.
@@ -233,7 +182,7 @@ struct iwl3945_eeprom {
  * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
  */
 	u16 band_1_count;	/* abs.ofs: 196 */
-	struct iwl3945_eeprom_channel band_1_channels[14];  /* abs.ofs: 196 */
+	struct iwl_eeprom_channel band_1_channels[14];  /* abs.ofs: 198 */
 
 /*
  * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
@@ -241,28 +190,28 @@ struct iwl3945_eeprom {
  * (4915-5080MHz) (none of these is ever supported)
  */
 	u16 band_2_count;	/* abs.ofs: 226 */
-	struct iwl3945_eeprom_channel band_2_channels[13];  /* abs.ofs: 228 */
+	struct iwl_eeprom_channel band_2_channels[13];  /* abs.ofs: 228 */
 
 /*
  * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
  * (5170-5320MHz)
  */
 	u16 band_3_count;	/* abs.ofs: 254 */
-	struct iwl3945_eeprom_channel band_3_channels[12];  /* abs.ofs: 256 */
+	struct iwl_eeprom_channel band_3_channels[12];  /* abs.ofs: 256 */
 
 /*
  * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
  * (5500-5700MHz)
  */
 	u16 band_4_count;	/* abs.ofs: 280 */
-	struct iwl3945_eeprom_channel band_4_channels[11];  /* abs.ofs: 282 */
+	struct iwl_eeprom_channel band_4_channels[11];  /* abs.ofs: 282 */
 
 /*
  * 5.7 GHz channels 145, 149, 153, 157, 161, 165
  * (5725-5825MHz)
  */
 	u16 band_5_count;	/* abs.ofs: 304 */
-	struct iwl3945_eeprom_channel band_5_channels[6];  /* abs.ofs: 306 */
+	struct iwl_eeprom_channel band_5_channels[6];  /* abs.ofs: 306 */
 
 	u8 reserved9[194];
 
@@ -276,125 +225,15 @@ struct iwl3945_eeprom {
 	u8 reserved16[172];	/* fill out to full 1024 byte block */
 } __attribute__ ((packed));
 
-#define IWL_EEPROM_IMAGE_SIZE 1024
+#define IWL3945_EEPROM_IMG_SIZE 1024
 
 /* End of EEPROM */
 
-
-#include "iwl-3945-commands.h"
-
-#define PCI_LINK_CTRL      0x0F0
-#define PCI_POWER_SOURCE   0x0C8
-#define PCI_REG_WUM8       0x0E8
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
-
-/*=== FH (data Flow Handler) ===*/
-#define FH_BASE     (0x800)
-
-#define FH_CBCC_TABLE           (FH_BASE+0x140)
-#define FH_TFDB_TABLE           (FH_BASE+0x180)
-#define FH_RCSR_TABLE           (FH_BASE+0x400)
-#define FH_RSSR_TABLE           (FH_BASE+0x4c0)
-#define FH_TCSR_TABLE           (FH_BASE+0x500)
-#define FH_TSSR_TABLE           (FH_BASE+0x680)
-
-/* TFDB (Transmit Frame Buffer Descriptor) */
-#define FH_TFDB(_channel, buf) \
-	(FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
-#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
-	(FH_TFDB_TABLE + 0x50 * _channel)
-/* CBCC _channel is [0,2] */
-#define FH_CBCC(_channel)           (FH_CBCC_TABLE+(_channel)*0x8)
-#define FH_CBCC_CTRL(_channel)      (FH_CBCC(_channel)+0x00)
-#define FH_CBCC_BASE(_channel)      (FH_CBCC(_channel)+0x04)
-
-/* RCSR _channel is [0,2] */
-#define FH_RCSR(_channel)           (FH_RCSR_TABLE+(_channel)*0x40)
-#define FH_RCSR_CONFIG(_channel)    (FH_RCSR(_channel)+0x00)
-#define FH_RCSR_RBD_BASE(_channel)  (FH_RCSR(_channel)+0x04)
-#define FH_RCSR_WPTR(_channel)      (FH_RCSR(_channel)+0x20)
-#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
-
-#define FH_RSCSR_CHNL0_WPTR        (FH_RCSR_WPTR(0))
-
-/* RSSR */
-#define FH_RSSR_CTRL            (FH_RSSR_TABLE+0x000)
-#define FH_RSSR_STATUS          (FH_RSSR_TABLE+0x004)
-#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE	(0x01000000)
-/* TCSR */
-#define FH_TCSR(_channel)           (FH_TCSR_TABLE+(_channel)*0x20)
-#define FH_TCSR_CONFIG(_channel)    (FH_TCSR(_channel)+0x00)
-#define FH_TCSR_CREDIT(_channel)    (FH_TCSR(_channel)+0x04)
-#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
-/* TSSR */
-#define FH_TSSR_CBB_BASE        (FH_TSSR_TABLE+0x000)
-#define FH_TSSR_MSG_CONFIG      (FH_TSSR_TABLE+0x008)
-#define FH_TSSR_TX_STATUS       (FH_TSSR_TABLE+0x010)
-
-
-/* DBM */
-
-#define ALM_FH_SRVC_CHNL                            (6)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE     (20)
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH      (4)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN    (0x08000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE        (0x80000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE           (0x20000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128         (0x01000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST         (0x00001000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH               (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF              (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER           (0x00000001)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD           (0x00200000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT            (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID          (0x00004000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR           (0x00000001)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON      (0xFF000000)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON      (0x00FF0000)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B    (0x00000400)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON       (0x00000100)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON       (0x00000080)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH     (0x00000020)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH           (0x00000005)
-
-#define ALM_TB_MAX_BYTES_COUNT      (0xFFF0)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
-	((1LU << _channel) << 24)
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
-	((1LU << _channel) << 16)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
-	(ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
-	 ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
 #define PCI_CFG_REV_ID_BIT_BASIC_SKU                (0x40)	/* bit 6    */
 #define PCI_CFG_REV_ID_BIT_RTP                      (0x80)	/* bit 7    */
 
 #define TFD_QUEUE_MIN           0
-#define TFD_QUEUE_MAX           6
-#define TFD_QUEUE_SIZE_MAX      (256)
+#define TFD_QUEUE_MAX           5	/* 4 DATA + 1 CMD */
 
 #define IWL_NUM_SCAN_RATES         (2)
 
@@ -416,12 +255,6 @@ struct iwl3945_eeprom {
 #define TFD_CTL_PAD_SET(n)         (n << 28)
 #define TFD_CTL_PAD_GET(ctl)       (ctl >> 28)
 
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
-			      sizeof(struct iwl3945_cmd_meta))
-
 /*
  * RX related structures and functions
  */
@@ -430,45 +263,35 @@ struct iwl3945_eeprom {
 
 /* Sizes and addresses for instruction and data memory (SRAM) in
  * 3945's embedded processor.  Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND			(0x000000)
-#define ALM_RTC_INST_UPPER_BOUND		(0x014000)
+#define IWL39_RTC_INST_LOWER_BOUND		(0x000000)
+#define IWL39_RTC_INST_UPPER_BOUND		(0x014000)
 
-#define RTC_DATA_LOWER_BOUND			(0x800000)
-#define ALM_RTC_DATA_UPPER_BOUND		(0x808000)
+#define IWL39_RTC_DATA_LOWER_BOUND		(0x800000)
+#define IWL39_RTC_DATA_UPPER_BOUND		(0x808000)
 
-#define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \
+				IWL39_RTC_INST_LOWER_BOUND)
+#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \
+				IWL39_RTC_DATA_LOWER_BOUND)
 
-#define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE
+#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE
+#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE
 
 /* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
+#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
 
 #define IWL39_MAX_NUM_QUEUES	8
 
 static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
 {
-	return (addr >= RTC_DATA_LOWER_BOUND) &&
-	       (addr < ALM_RTC_DATA_UPPER_BOUND);
+	return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
+	       (addr < IWL39_RTC_DATA_UPPER_BOUND);
 }
 
 /* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE
  * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
 struct iwl3945_shared {
 	__le32 tx_base_ptr[8];
-	__le32 rx_read_ptr[3];
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame_data {
-	__le32 addr;
-	__le32 len;
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame {
-	__le32 control_flags;
-	struct iwl3945_tfd_frame_data pa[4];
-	u8 reserved[28];
 } __attribute__ ((packed));
 
 static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-io.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-io.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,404 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * 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 __iwl3945_io_h__
-#define __iwl3945_io_h__
-
-#include <linux/io.h>
-
-#include "iwl-3945-debug.h"
-
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number is printed in addition to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's __LINE__ to the double prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl3945_read_direct32 calls the non-check version of
- * _iwl3945_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O.  In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
-				 u32 ofs, u32 val)
-{
-	IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
-	_iwl3945_write32(priv, ofs, val);
-}
-#define iwl3945_write32(priv, ofs, val) \
-	__iwl3945_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
-#endif
-
-#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
-{
-	IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
-	return _iwl3945_read32(priv, ofs);
-}
-#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
-#endif
-
-static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
-				u32 bits, u32 mask, int timeout)
-{
-	int i = 0;
-
-	do {
-		if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
-			return i;
-		udelay(10);
-		i += 10;
-	} while (i < timeout);
-
-	return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_bit(const char *f, u32 l,
-				 struct iwl3945_priv *priv, u32 addr,
-				 u32 bits, u32 mask, int timeout)
-{
-	int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
-	IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
-		      addr, bits, mask,
-		      unlikely(ret  == -ETIMEDOUT) ? "timeout" : "", f, l);
-	return ret;
-}
-#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
-	__iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
-	_iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bit(const char *f, u32 l,
-				 struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
-	u32 val = _iwl3945_read32(priv, reg) | mask;
-	IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
-	_iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
-#endif
-
-static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
-	_iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_clear_bit(const char *f, u32 l,
-				   struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
-	u32 val = _iwl3945_read32(priv, reg) & ~mask;
-	IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
-	_iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
-#endif
-
-static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
-{
-	int ret;
-#ifdef CONFIG_IWL3945_DEBUG
-	if (atomic_read(&priv->restrict_refcnt))
-		return 0;
-#endif
-	/* this bit wakes up the NIC */
-	_iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-	ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
-			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
-			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
-	if (ret < 0) {
-		IWL_ERROR("MAC is in deep sleep!\n");
-		return -EIO;
-	}
-
-#ifdef CONFIG_IWL3945_DEBUG
-	atomic_inc(&priv->restrict_refcnt);
-#endif
-	return 0;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
-					       struct iwl3945_priv *priv)
-{
-	if (atomic_read(&priv->restrict_refcnt))
-		IWL_DEBUG_INFO("Grabbing access while already held at "
-			       "line %d.\n", l);
-
-	IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
-	return _iwl3945_grab_nic_access(priv);
-}
-#define iwl3945_grab_nic_access(priv) \
-	__iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_grab_nic_access(priv) \
-	_iwl3945_grab_nic_access(priv)
-#endif
-
-static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
-{
-#ifdef CONFIG_IWL3945_DEBUG
-	if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
-		_iwl3945_clear_bit(priv, CSR_GP_CNTRL,
-			       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_release_nic_access(const char *f, u32 l,
-					    struct iwl3945_priv *priv)
-{
-	if (atomic_read(&priv->restrict_refcnt) <= 0)
-		IWL_ERROR("Release unheld nic access at line %d.\n", l);
-
-	IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
-	_iwl3945_release_nic_access(priv);
-}
-#define iwl3945_release_nic_access(priv) \
-	__iwl3945_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_release_nic_access(priv) \
-	_iwl3945_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
-{
-	return _iwl3945_read32(priv, reg);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
-					struct iwl3945_priv *priv, u32 reg)
-{
-	u32 value = _iwl3945_read_direct32(priv, reg);
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s %d\n", f, l);
-	IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
-		     f, l);
-	return value;
-}
-#define iwl3945_read_direct32(priv, reg) \
-	__iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
-#else
-#define iwl3945_read_direct32 _iwl3945_read_direct32
-#endif
-
-static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
-					 u32 reg, u32 value)
-{
-	_iwl3945_write32(priv, reg, value);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static void __iwl3945_write_direct32(u32 line,
-				   struct iwl3945_priv *priv, u32 reg, u32 value)
-{
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from line %d\n", line);
-	_iwl3945_write_direct32(priv, reg, value);
-}
-#define iwl3945_write_direct32(priv, reg, value) \
-	__iwl3945_write_direct32(__LINE__, priv, reg, value)
-#else
-#define iwl3945_write_direct32 _iwl3945_write_direct32
-#endif
-
-static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
-					       u32 reg, u32 len, u32 *values)
-{
-	u32 count = sizeof(u32);
-
-	if ((priv != NULL) && (values != NULL)) {
-		for (; 0 < len; len -= count, reg += count, values++)
-			_iwl3945_write_direct32(priv, reg, *values);
-	}
-}
-
-static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
-					   u32 addr, u32 mask, int timeout)
-{
-	return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
-					    struct iwl3945_priv *priv,
-					    u32 addr, u32 mask, int timeout)
-{
-	int ret  = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
-
-	if (unlikely(ret == -ETIMEDOUT))
-		IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
-			     "timedout - %s %d\n", addr, mask, f, l);
-	else
-		IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
-			     "- %s %d\n", addr, mask, ret, f, l);
-	return ret;
-}
-#define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \
-	__iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
-#endif
-
-static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
-{
-	_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-	rmb();
-	return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
-{
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from line %d\n", line);
-	return _iwl3945_read_prph(priv, reg);
-}
-
-#define iwl3945_read_prph(priv, reg) \
-	__iwl3945_read_prph(__LINE__, priv, reg)
-#else
-#define iwl3945_read_prph _iwl3945_read_prph
-#endif
-
-static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
-					     u32 addr, u32 val)
-{
-	_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
-			      ((addr & 0x0000FFFF) | (3 << 24)));
-	wmb();
-	_iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
-					      u32 addr, u32 val)
-{
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access from line %d\n", line);
-	_iwl3945_write_prph(priv, addr, val);
-}
-
-#define iwl3945_write_prph(priv, addr, val) \
-	__iwl3945_write_prph(__LINE__, priv, addr, val);
-#else
-#define iwl3945_write_prph _iwl3945_write_prph
-#endif
-
-#define _iwl3945_set_bits_prph(priv, reg, mask) \
-	_iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
-					u32 reg, u32 mask)
-{
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from line %d\n", line);
-
-	_iwl3945_set_bits_prph(priv, reg, mask);
-}
-#define iwl3945_set_bits_prph(priv, reg, mask) \
-	__iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
-#else
-#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
-#endif
-
-#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
-	_iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_mask_prph(u32 line,
-		struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
-{
-	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from line %d\n", line);
-	_iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
-}
-#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
-	__iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
-#else
-#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
-#endif
-
-static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
-						 *priv, u32 reg, u32 mask)
-{
-	u32 val = _iwl3945_read_prph(priv, reg);
-	_iwl3945_write_prph(priv, reg, (val & ~mask));
-}
-
-static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
-{
-	iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
-	rmb();
-	return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-}
-
-static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
-{
-	iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-	wmb();
-	iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
-}
-
-static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
-					  u32 len, u32 *values)
-{
-	iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-	wmb();
-	for (; 0 < len; len -= sizeof(u32), values++)
-		iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-}
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -24,6 +24,7 @@
  *
  *****************************************************************************/
 
+#ifdef CONFIG_IWLWIFI_LEDS
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -38,8 +39,10 @@
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 
+#include "iwl-commands.h"
 #include "iwl-3945.h"
-#include "iwl-helpers.h"
+#include "iwl-core.h"
+#include "iwl-dev.h"
 
 
 static const struct {
@@ -67,8 +70,8 @@ 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)
 
-static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
-				    struct iwl3945_cmd *cmd,
+static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
+				    struct iwl_cmd *cmd,
 				    struct sk_buff *skb)
 {
 	return 1;
@@ -80,27 +83,27 @@ static inline int iwl3945_brightness_to_
 }
 
 /* Send led command */
-static int iwl_send_led_cmd(struct iwl3945_priv *priv,
-			    struct iwl3945_led_cmd *led_cmd)
+static int iwl_send_led_cmd(struct iwl_priv *priv,
+			    struct iwl_led_cmd *led_cmd)
 {
-	struct iwl3945_host_cmd cmd = {
+	struct iwl_host_cmd cmd = {
 		.id = REPLY_LEDS_CMD,
-		.len = sizeof(struct iwl3945_led_cmd),
+		.len = sizeof(struct iwl_led_cmd),
 		.data = led_cmd,
 		.meta.flags = CMD_ASYNC,
 		.meta.u.callback = iwl3945_led_cmd_callback,
 	};
 
-	return iwl3945_send_cmd(priv, &cmd);
+	return iwl_send_cmd(priv, &cmd);
 }
 
 
 
 /* Set led on command */
-static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
+static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
 			       unsigned int idx)
 {
-	struct iwl3945_led_cmd led_cmd = {
+	struct iwl_led_cmd led_cmd = {
 		.id = led_id,
 		.interval = IWL_DEF_LED_INTRVL
 	};
@@ -114,11 +117,10 @@ static int iwl3945_led_pattern(struct iw
 }
 
 
-#if 1
 /* Set led on command */
-static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_on(struct iwl_priv *priv, int led_id)
 {
-	struct iwl3945_led_cmd led_cmd = {
+	struct iwl_led_cmd led_cmd = {
 		.id = led_id,
 		.on = IWL_LED_SOLID,
 		.off = 0,
@@ -128,24 +130,22 @@ static int iwl3945_led_on(struct iwl3945
 }
 
 /* Set led off command */
-static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
 {
-	struct iwl3945_led_cmd led_cmd = {
+	struct iwl_led_cmd led_cmd = {
 		.id = led_id,
 		.on = 0,
 		.off = 0,
 		.interval = IWL_DEF_LED_INTRVL
 	};
-	IWL_DEBUG_LED("led off %d\n", led_id);
+	IWL_DEBUG_LED(priv, "led off %d\n", led_id);
 	return iwl_send_led_cmd(priv, &led_cmd);
 }
-#endif
-
 
 /*
  * brightness call back function for Tx/Rx LED
  */
-static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
+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))
@@ -164,9 +164,9 @@ static int iwl3945_led_associated(struct
 static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
 				enum led_brightness brightness)
 {
-	struct iwl3945_led *led = container_of(led_cdev,
-					       struct iwl3945_led, led_dev);
-	struct iwl3945_priv *priv = led->priv;
+	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;
@@ -175,7 +175,7 @@ static void iwl3945_led_brightness_set(s
 	case LED_FULL:
 		if (led->type == IWL_LED_TRG_ASSOC) {
 			priv->allow_blinking = 1;
-			IWL_DEBUG_LED("MAC is  associated\n");
+			IWL_DEBUG_LED(priv, "MAC is  associated\n");
 		}
 		if (led->led_on)
 			led->led_on(priv, IWL_LED_LINK);
@@ -183,7 +183,7 @@ static void iwl3945_led_brightness_set(s
 	case LED_OFF:
 		if (led->type == IWL_LED_TRG_ASSOC) {
 			priv->allow_blinking = 0;
-			IWL_DEBUG_LED("MAC is disassociated\n");
+			IWL_DEBUG_LED(priv, "MAC is disassociated\n");
 		}
 		if (led->led_off)
 			led->led_off(priv, IWL_LED_LINK);
@@ -202,8 +202,8 @@ static void iwl3945_led_brightness_set(s
 /*
  * Register led class with the system
  */
-static int iwl3945_led_register_led(struct iwl3945_priv *priv,
-				   struct iwl3945_led *led,
+static int iwl3945_led_register_led(struct iwl_priv *priv,
+				   struct iwl_led *led,
 				   enum led_type type, u8 set_led,
 				   char *trigger)
 {
@@ -219,7 +219,7 @@ static int iwl3945_led_register_led(stru
 
 	ret = led_classdev_register(device, &led->led_dev);
 	if (ret) {
-		IWL_ERROR("Error: failed to register led handler.\n");
+		IWL_ERR(priv, "Error: failed to register led handler.\n");
 		return ret;
 	}
 
@@ -234,7 +234,7 @@ static int iwl3945_led_register_led(stru
 /*
  * calculate blink rate according to last 2 sec Tx/Rx activities
  */
-static inline u8 get_blink_rate(struct iwl3945_priv *priv)
+static inline u8 get_blink_rate(struct iwl_priv *priv)
 {
 	int index;
 	u64 current_tpt = priv->rxtxpackets;
@@ -253,7 +253,7 @@ static inline u8 get_blink_rate(struct i
 	return index;
 }
 
-static inline int is_rf_kill(struct iwl3945_priv *priv)
+static inline int is_rf_kill(struct iwl_priv *priv)
 {
 	return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
 		test_bit(STATUS_RF_KILL_SW, &priv->status);
@@ -264,7 +264,7 @@ static inline int is_rf_kill(struct iwl3
  * happen very frequent we postpone led command to be called from
  * REPLY handler so we know ucode is up
  */
-void iwl3945_led_background(struct iwl3945_priv *priv)
+void iwl3945_led_background(struct iwl_priv *priv)
 {
 	u8 blink_idx;
 
@@ -304,7 +304,7 @@ void iwl3945_led_background(struct iwl39
 
 
 /* Register all led handler */
-int iwl3945_led_register(struct iwl3945_priv *priv)
+int iwl3945_led_register(struct iwl_priv *priv)
 {
 	char *trigger;
 	int ret;
@@ -317,7 +317,7 @@ int iwl3945_led_register(struct iwl3945_
 
 	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",
+		 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;
@@ -333,7 +333,7 @@ int iwl3945_led_register(struct iwl3945_
 
 	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",
+		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl3945_led_register_led(priv,
@@ -350,7 +350,7 @@ int iwl3945_led_register(struct iwl3945_
 
 	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",
+		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl3945_led_register_led(priv,
@@ -366,7 +366,7 @@ int iwl3945_led_register(struct iwl3945_
 
 	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",
+		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl3945_led_register_led(priv,
@@ -389,7 +389,7 @@ exit_fail:
 
 
 /* unregister led class */
-static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
+static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
 {
 	if (!led->registered)
 		return;
@@ -402,7 +402,7 @@ static void iwl3945_led_unregister_led(s
 }
 
 /* Unregister all led handlers */
-void iwl3945_led_unregister(struct iwl3945_priv *priv)
+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);
@@ -410,3 +410,4 @@ void iwl3945_led_unregister(struct iwl39
 	iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
 }
 
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-led.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -27,48 +27,20 @@
 #ifndef IWL3945_LEDS_H
 #define IWL3945_LEDS_H
 
-struct iwl3945_priv;
-
-#ifdef CONFIG_IWL3945_LEDS
-#define IWL_LED_SOLID 11
-#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
-
-#define IWL_LED_ACTIVITY       (0<<1)
-#define IWL_LED_LINK           (1<<1)
-
-enum led_type {
-	IWL_LED_TRG_TX,
-	IWL_LED_TRG_RX,
-	IWL_LED_TRG_ASSOC,
-	IWL_LED_TRG_RADIO,
-	IWL_LED_TRG_MAX,
-};
-
-#include <linux/leds.h>
-
-struct iwl3945_led {
-	struct iwl3945_priv *priv;
-	struct led_classdev led_dev;
-	char name[32];
+struct iwl_priv;
 
-	int (*led_on) (struct iwl3945_priv *priv, int led_id);
-	int (*led_off) (struct iwl3945_priv *priv, int led_id);
-	int (*led_pattern) (struct iwl3945_priv *priv, int led_id,
-			    unsigned int idx);
+#ifdef CONFIG_IWLWIFI_LEDS
 
-	enum led_type type;
-	unsigned int registered;
-};
+#include "iwl-led.h"
 
-extern int iwl3945_led_register(struct iwl3945_priv *priv);
-extern void iwl3945_led_unregister(struct iwl3945_priv *priv);
-extern void iwl3945_led_background(struct iwl3945_priv *priv);
+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);
 
 #else
-static inline int iwl3945_led_register(struct iwl3945_priv *priv) { return 0; }
-static inline void iwl3945_led_unregister(struct iwl3945_priv *priv) {}
-static inline void iwl3945_led_background(struct iwl3945_priv *priv) {}
-#endif /* CONFIG_IWL3945_LEDS */
+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) {}
 
+#endif /* IWLWIFI_LEDS*/
 #endif /* IWL3945_LEDS_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -36,6 +36,7 @@
 
 #include <linux/workqueue.h>
 
+#include "iwl-commands.h"
 #include "iwl-3945.h"
 
 #define RS_NAME "iwl-3945-rs"
@@ -51,6 +52,7 @@ struct iwl3945_rate_scale_data {
 
 struct iwl3945_rs_sta {
 	spinlock_t lock;
+	struct iwl_priv *priv;
 	s32 *expected_tpt;
 	unsigned long last_partial_flush;
 	unsigned long last_flush;
@@ -62,7 +64,7 @@ struct iwl3945_rs_sta {
 	u8 start_rate;
 	u8 ibss_sta_added;
 	struct timer_list rate_scale_flush;
-	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
+	struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
 #ifdef CONFIG_MAC80211_DEBUGFS
 	struct dentry *rs_sta_dbgfs_stats_table_file;
 #endif
@@ -71,19 +73,19 @@ struct iwl3945_rs_sta {
 	int last_txrate_idx;
 };
 
-static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
 	7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
 };
 
-static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = {
 	7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
 };
 
-static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = {
 	0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
 };
 
-static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = {
 	7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
@@ -119,12 +121,13 @@ static struct iwl3945_tpt_entry iwl3945_
 #define IWL_RATE_MAX_WINDOW          62
 #define IWL_RATE_FLUSH       	 (3*HZ)
 #define IWL_RATE_WIN_FLUSH       (HZ/2)
-#define IWL_RATE_HIGH_TH          11520
+#define IWL39_RATE_HIGH_TH          11520
 #define IWL_SUCCESS_UP_TH	   8960
 #define IWL_SUCCESS_DOWN_TH	  10880
-#define IWL_RATE_MIN_FAILURE_TH       8
+#define IWL_RATE_MIN_FAILURE_TH       6
 #define IWL_RATE_MIN_SUCCESS_TH       8
 #define IWL_RATE_DECREASE_TH       1920
+#define IWL_RATE_RETRY_TH	     15
 
 static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
 {
@@ -165,7 +168,7 @@ static void iwl3945_clear_window(struct
 	window->success_counter = 0;
 	window->success_ratio = -1;
 	window->counter = 0;
-	window->average_tpt = IWL_INV_TPT;
+	window->average_tpt = IWL_INVALID_VALUE;
 	window->stamp = 0;
 }
 
@@ -181,20 +184,21 @@ static int iwl3945_rate_scale_flush_wind
 	int unflushed = 0;
 	int i;
 	unsigned long flags;
+	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
 	/*
 	 * For each rate, if we have collected data on that rate
 	 * and it has been more than IWL_RATE_WIN_FLUSH
 	 * since we flushed, clear out the gathered statistics
 	 */
-	for (i = 0; i < IWL_RATE_COUNT; i++) {
+	for (i = 0; i < IWL_RATE_COUNT_3945; i++) {
 		if (!rs_sta->win[i].counter)
 			continue;
 
 		spin_lock_irqsave(&rs_sta->lock, flags);
 		if (time_after(jiffies, rs_sta->win[i].stamp +
 			       IWL_RATE_WIN_FLUSH)) {
-			IWL_DEBUG_RATE("flushing %d samples of rate "
+			IWL_DEBUG_RATE(priv, "flushing %d samples of rate "
 				       "index %d\n",
 				       rs_sta->win[i].counter, i);
 			iwl3945_clear_window(&rs_sta->win[i]);
@@ -213,11 +217,12 @@ static int iwl3945_rate_scale_flush_wind
 static void iwl3945_bg_rate_scale_flush(unsigned long data)
 {
 	struct iwl3945_rs_sta *rs_sta = (void *)data;
+	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 	int unflushed = 0;
 	unsigned long flags;
 	u32 packet_count, duration, pps;
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	unflushed = iwl3945_rate_scale_flush_windows(rs_sta);
 
@@ -232,7 +237,7 @@ static void iwl3945_bg_rate_scale_flush(
 		duration =
 		    jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);
 
-		IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
+		IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n",
 			       packet_count, duration);
 
 		/* Determine packets per second */
@@ -252,7 +257,7 @@ static void iwl3945_bg_rate_scale_flush(
 
 		rs_sta->flush_time = msecs_to_jiffies(duration);
 
-		IWL_DEBUG_RATE("new flush period: %d msec ave %d\n",
+		IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n",
 			       duration, packet_count);
 
 		mod_timer(&rs_sta->rate_scale_flush, jiffies +
@@ -270,7 +275,7 @@ static void iwl3945_bg_rate_scale_flush(
 
 	spin_unlock_irqrestore(&rs_sta->lock, flags);
 
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
 /**
@@ -286,50 +291,70 @@ static void iwl3945_collect_tx_data(stru
 {
 	unsigned long flags;
 	s32 fail_count;
+	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
 	if (!retries) {
-		IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
+		IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n");
 		return;
 	}
 
 	spin_lock_irqsave(&rs_sta->lock, flags);
-	while (retries--) {
 
-		/* If we have filled up the window then subtract one from the
-		 * success counter if the high-bit is counting toward
-		 * success */
-		if (window->counter == IWL_RATE_MAX_WINDOW) {
-			if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1)))
-				window->success_counter--;
-		} else
-			window->counter++;
+	/*
+	 * Keep track of only the latest 62 tx frame attempts in this rate's
+	 * history window; anything older isn't really relevant any more.
+	 * If we have filled up the sliding window, drop the oldest attempt;
+	 * if the oldest attempt (highest bit in bitmap) shows "success",
+	 * subtract "1" from the success counter (this is the main reason
+	 * we keep these bitmaps!).
+	 * */
+	while (retries > 0) {
+		if (window->counter >= IWL_RATE_MAX_WINDOW) {
 
-		/* Slide the window to the left one bit */
-		window->data = (window->data << 1);
+			/* remove earliest */
+			window->counter = IWL_RATE_MAX_WINDOW - 1;
 
-		/* If this packet was a success then set the low bit high */
-		if (success) {
-			window->success_counter++;
-			window->data |= 1;
+			if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) {
+				window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1));
+				window->success_counter--;
+			}
 		}
 
-		/* window->counter can't be 0 -- it is either >0 or
-		 * IWL_RATE_MAX_WINDOW */
-		window->success_ratio = 12800 * window->success_counter /
-		    window->counter;
+		/* Increment frames-attempted counter */
+		window->counter++;
 
-		/* Tag this window as having been updated */
-		window->stamp = jiffies;
+		/* Shift bitmap by one frame (throw away oldest history),
+		 * OR in "1", and increment "success" if this
+		 * frame was successful. */
+		window->data <<= 1;
+		if (success > 0) {
+			window->success_counter++;
+			window->data |= 0x1;
+			success--;
+		}
 
+		retries--;
 	}
 
+	/* Calculate current success ratio, avoid divide-by-0! */
+	if (window->counter > 0)
+		window->success_ratio = 128 * (100 * window->success_counter)
+					/ window->counter;
+	else
+		window->success_ratio = IWL_INVALID_VALUE;
+
 	fail_count = window->counter - window->success_counter;
+
+	/* Calculate average throughput, if we have enough history. */
 	if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
 	    (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
 		window->average_tpt = ((window->success_ratio *
 				rs_sta->expected_tpt[index] + 64) / 128);
 	else
-		window->average_tpt = IWL_INV_TPT;
+		window->average_tpt = IWL_INVALID_VALUE;
+
+	/* Tag this window as having been updated */
+	window->stamp = jiffies;
 
 	spin_unlock_irqrestore(&rs_sta->lock, flags);
 
@@ -339,10 +364,10 @@ static void rs_rate_init(void *priv_r, s
 			 struct ieee80211_sta *sta, void *priv_sta)
 {
 	struct iwl3945_rs_sta *rs_sta = priv_sta;
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	int i;
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	/* TODO: what is a good starting rate for STA? About middle? Maybe not
 	 * the lowest or the highest rate.. Could consider using RSSI from
@@ -365,7 +390,7 @@ static void rs_rate_init(void *priv_r, s
 	}
 
 
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
 static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -379,10 +404,11 @@ static void rs_free(void *priv)
 	return;
 }
 
-static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
 	struct iwl3945_rs_sta *rs_sta;
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
+	struct iwl_priv *priv = iwl_priv;
 	int i;
 
 	/*
@@ -390,11 +416,11 @@ static void *rs_alloc_sta(void *priv, st
 	 *	as well just put all the information there.
 	 */
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
 	if (!rs_sta) {
-		IWL_DEBUG_RATE("leave: ENOMEM\n");
+		IWL_DEBUG_RATE(priv, "leave: ENOMEM\n");
 		return NULL;
 	}
 
@@ -402,6 +428,8 @@ static void *rs_alloc_sta(void *priv, st
 
 	spin_lock_init(&rs_sta->lock);
 
+	rs_sta->priv = priv;
+
 	rs_sta->start_rate = IWL_RATE_INVALID;
 
 	/* default to just 802.11b */
@@ -417,33 +445,34 @@ static void *rs_alloc_sta(void *priv, st
 	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; i++)
+	for (i = 0; i < IWL_RATE_COUNT_3945; i++)
 		iwl3945_clear_window(&rs_sta->win[i]);
 
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 
 	return rs_sta;
 }
 
-static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
 			void *priv_sta)
 {
 	struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
 	struct iwl3945_rs_sta *rs_sta = priv_sta;
+	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
 	psta->rs_sta = NULL;
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 	del_timer_sync(&rs_sta->rate_scale_flush);
 	kfree(rs_sta);
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
 
 /**
  * rs_tx_status - Update rate control values based on Tx results
  *
- * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
+ * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
  * the hardware for each rate.
  */
 static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
@@ -453,22 +482,25 @@ static void rs_tx_status(void *priv_rate
 	s8 retries = 0, current_count;
 	int scale_rate_index, first_index, last_index;
 	unsigned long flags;
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
 	struct iwl3945_rs_sta *rs_sta = priv_sta;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	retries = info->status.rates[0].count;
+	/* Sanity Check for retries */
+	if (retries > IWL_RATE_RETRY_TH)
+		retries = IWL_RATE_RETRY_TH;
 
 	first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
-	if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
-		IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
+	if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
+		IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index);
 		return;
 	}
 
 	if (!priv_sta) {
-		IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+		IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
 		return;
 	}
 
@@ -502,7 +534,7 @@ static void rs_tx_status(void *priv_rate
 		iwl3945_collect_tx_data(rs_sta,
 				    &rs_sta->win[scale_rate_index],
 				    0, current_count, scale_rate_index);
-		IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
+		IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n",
 			       scale_rate_index, current_count);
 
 		retries -= current_count;
@@ -512,7 +544,7 @@ static void rs_tx_status(void *priv_rate
 
 
 	/* Update the last index window with success/failure based on ACK */
-	IWL_DEBUG_RATE("Update rate %d with %s.\n",
+	IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n",
 		       last_index,
 		       (info->flags & IEEE80211_TX_STAT_ACK) ?
 		       "success" : "failure");
@@ -537,7 +569,7 @@ static void rs_tx_status(void *priv_rate
 
 	spin_unlock_irqrestore(&rs_sta->lock, flags);
 
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 
 	return;
 }
@@ -547,6 +579,7 @@ static u16 iwl3945_get_adjacent_rate(str
 {
 	u8 high = IWL_RATE_INVALID;
 	u8 low = IWL_RATE_INVALID;
+	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
 
 	/* 802.11A walks to the next literal adjacent rate in
 	 * the rate table */
@@ -565,7 +598,8 @@ static u16 iwl3945_get_adjacent_rate(str
 
 		/* Find the next rate that is in the rate mask */
 		i = index + 1;
-		for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
+		for (mask = (1 << i); i < IWL_RATE_COUNT_3945;
+		     i++, mask <<= 1) {
 			if (rate_mask & mask) {
 				high = i;
 				break;
@@ -585,7 +619,7 @@ static u16 iwl3945_get_adjacent_rate(str
 			break;
 		if (rate_mask & (1 << low))
 			break;
-		IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+		IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
 	}
 
 	high = index;
@@ -598,7 +632,7 @@ static u16 iwl3945_get_adjacent_rate(str
 			break;
 		if (rate_mask & (1 << high))
 			break;
-		IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+		IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
 	}
 
 	return (high << 8) | low;
@@ -631,19 +665,20 @@ static void rs_get_rate(void *priv_r, st
 	int index;
 	struct iwl3945_rs_sta *rs_sta = priv_sta;
 	struct iwl3945_rate_scale_data *window = NULL;
-	int current_tpt = IWL_INV_TPT;
-	int low_tpt = IWL_INV_TPT;
-	int high_tpt = IWL_INV_TPT;
+	int current_tpt = IWL_INVALID_VALUE;
+	int low_tpt = IWL_INVALID_VALUE;
+	int high_tpt = IWL_INVALID_VALUE;
 	u32 fail_count;
 	s8 scale_action = 0;
 	unsigned long flags;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	u16 fc;
 	u16 rate_mask = 0;
-	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+	s8 max_rate_idx = -1;
+	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	if (sta)
 		rate_mask = sta->supp_rates[sband->band];
@@ -654,7 +689,7 @@ static void rs_get_rate(void *priv_r, st
 	if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
 	    is_multicast_ether_addr(hdr->addr1) ||
 	    !sta || !priv_sta) {
-		IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+		IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
 		if (!rate_mask)
 			info->control.rates[0].idx =
 					rate_lowest_index(sband, NULL);
@@ -664,7 +699,14 @@ static void rs_get_rate(void *priv_r, st
 		return;
 	}
 
-	index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
+	/* get user max rate if set */
+	max_rate_idx = txrc->max_rate_idx;
+	if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1))
+		max_rate_idx += IWL_FIRST_OFDM_RATE;
+	if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT))
+		max_rate_idx = -1;
+
+	index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1);
 
 	if (sband->band == IEEE80211_BAND_5GHZ)
 		rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
@@ -674,7 +716,7 @@ static void rs_get_rate(void *priv_r, st
 		u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
 
 		if (sta_id == IWL_INVALID_STATION) {
-			IWL_DEBUG_RATE("LQ: ADD station %pm\n",
+			IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
 				       hdr->addr1);
 			sta_id = iwl3945_add_station(priv,
 				    hdr->addr1, 0, CMD_ASYNC);
@@ -695,21 +737,30 @@ static void rs_get_rate(void *priv_r, st
 		rs_sta->start_rate = IWL_RATE_INVALID;
 	}
 
+	/* force user max rate if set by user */
+	if ((max_rate_idx != -1) && (max_rate_idx < index)) {
+		if (rate_mask & (1 << max_rate_idx))
+			index = max_rate_idx;
+	}
+
 	window = &(rs_sta->win[index]);
 
 	fail_count = window->counter - window->success_counter;
 
-	if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
+	if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
 	     (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
 		spin_unlock_irqrestore(&rs_sta->lock, flags);
 
-		IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
+		IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: "
 			       "counter: %d, success_counter: %d, "
 			       "expected_tpt is %sNULL\n",
 			       index,
 			       window->counter,
 			       window->success_counter,
 			       rs_sta->expected_tpt ? "not " : "");
+
+	   /* Can't calculate this yet; not enough history */
+		window->average_tpt = IWL_INVALID_VALUE;
 		goto out;
 
 	}
@@ -721,6 +772,11 @@ static void rs_get_rate(void *priv_r, st
 	low = high_low & 0xff;
 	high = (high_low >> 8) & 0xff;
 
+	/* If user set max rate, dont allow higher than user constrain */
+	if ((max_rate_idx != -1) && (max_rate_idx < high))
+		high = IWL_RATE_INVALID;
+
+	/* Collect Measured throughputs of adjacent rates */
 	if (low != IWL_RATE_INVALID)
 		low_tpt = rs_sta->win[low].average_tpt;
 
@@ -729,56 +785,78 @@ static void rs_get_rate(void *priv_r, st
 
 	spin_unlock_irqrestore(&rs_sta->lock, flags);
 
-	scale_action = 1;
+	scale_action = 0;
 
+	/* Low success ratio , need to drop the rate */
 	if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
-		IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+		IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
 		scale_action = -1;
-	} else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT))
-		scale_action = 1;
-	else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) &&
+	/* No throughput measured yet for adjacent rates,
+	 * try increase */
+	} else if ((low_tpt == IWL_INVALID_VALUE) &&
+		   (high_tpt == IWL_INVALID_VALUE)) {
+
+		if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH)
+			scale_action = 1;
+		else if (low != IWL_RATE_INVALID)
+			scale_action = 0;
+
+	/* Both adjacent throughputs are measured, but neither one has
+	 * better throughput; we're using the best rate, don't change
+	 * it! */
+	} else if ((low_tpt != IWL_INVALID_VALUE) &&
+		 (high_tpt != IWL_INVALID_VALUE) &&
 		 (low_tpt < current_tpt) && (high_tpt < current_tpt)) {
-		IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
+
+		IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < "
 			       "current_tpt [%d]\n",
 			       low_tpt, high_tpt, current_tpt);
 		scale_action = 0;
+
+	/* At least one of the rates has better throughput */
 	} else {
-		if (high_tpt != IWL_INV_TPT) {
-			if (high_tpt > current_tpt)
+		if (high_tpt != IWL_INVALID_VALUE) {
+
+			/* High rate has better throughput, Increase
+			 * rate */
+			if (high_tpt > current_tpt &&
+				window->success_ratio >= IWL_RATE_INCREASE_TH)
 				scale_action = 1;
 			else {
-				IWL_DEBUG_RATE
-				    ("decrease rate because of high tpt\n");
-				scale_action = -1;
+				IWL_DEBUG_RATE(priv,
+				    "decrease rate because of high tpt\n");
+				scale_action = 0;
 			}
-		} else if (low_tpt != IWL_INV_TPT) {
+		} else if (low_tpt != IWL_INVALID_VALUE) {
 			if (low_tpt > current_tpt) {
-				IWL_DEBUG_RATE
-				    ("decrease rate because of low tpt\n");
+				IWL_DEBUG_RATE(priv,
+				    "decrease rate because of low tpt\n");
 				scale_action = -1;
-			} else
+			} else if (window->success_ratio >= IWL_RATE_INCREASE_TH) {
+				/* Lower rate has better
+				 * throughput,decrease rate */
 				scale_action = 1;
+			}
 		}
 	}
 
-	if (scale_action == -1) {
-		if (window->success_ratio > IWL_SUCCESS_DOWN_TH)
-			scale_action = 0;
-	} else if (scale_action == 1) {
-		if (window->success_ratio < IWL_SUCCESS_UP_TH) {
-			IWL_DEBUG_RATE("No action -- success_ratio [%d] < "
-			       "SUCCESS UP\n", window->success_ratio);
-			scale_action = 0;
-		}
-	}
+	/* Sanity check; asked for decrease, but success rate or throughput
+	 * has been good at old rate.  Don't change it. */
+	if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
+		    ((window->success_ratio > IWL_RATE_HIGH_TH) ||
+		     (current_tpt > (100 * rs_sta->expected_tpt[low]))))
+		scale_action = 0;
 
 	switch (scale_action) {
 	case -1:
+
+		/* Decrese rate */
 		if (low != IWL_RATE_INVALID)
 			index = low;
 		break;
 
 	case 1:
+		/* Increase rate */
 		if (high != IWL_RATE_INVALID)
 			index = high;
 
@@ -786,10 +864,11 @@ static void rs_get_rate(void *priv_r, st
 
 	case 0:
 	default:
+		/* No change */
 		break;
 	}
 
-	IWL_DEBUG_RATE("Selected %d (action %d) - low %d high %d\n",
+	IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n",
 		       index, scale_action, low, high);
 
  out:
@@ -801,7 +880,7 @@ static void rs_get_rate(void *priv_r, st
 	else
 		info->control.rates[0].idx = rs_sta->last_txrate_idx;
 
-	IWL_DEBUG_RATE("leave: %d\n", index);
+	IWL_DEBUG_RATE(priv, "leave: %d\n", index);
 }
 
 #ifdef CONFIG_MAC80211_DEBUGFS
@@ -815,24 +894,31 @@ static ssize_t iwl3945_sta_dbgfs_stats_t
 						  char __user *user_buf,
 						  size_t count, loff_t *ppos)
 {
-	char buff[1024];
+	char *buff;
 	int desc = 0;
 	int j;
+	ssize_t ret;
 	struct iwl3945_rs_sta *lq_sta = file->private_data;
 
+	buff = kmalloc(1024, GFP_KERNEL);
+	if (!buff)
+		return -ENOMEM;
+
 	desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n"
 			"rate=0x%X flush time %d\n",
 			lq_sta->tx_packets,
 			lq_sta->last_txrate_idx,
 			lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time));
-	for (j = 0; j < IWL_RATE_COUNT; j++) {
+	for (j = 0; j < IWL_RATE_COUNT_3945; j++) {
 		desc += sprintf(buff+desc,
 				"counter=%d success=%d %%=%d\n",
 				lq_sta->win[j].counter,
 				lq_sta->win[j].success_counter,
 				lq_sta->win[j].success_ratio);
 	}
-	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	kfree(buff);
+	return ret;
 }
 
 static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
@@ -877,18 +963,18 @@ static struct rate_control_ops rs_ops =
 
 void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 {
-	struct iwl3945_priv *priv = hw->priv;
+	struct iwl_priv *priv = hw->priv;
 	s32 rssi = 0;
 	unsigned long flags;
 	struct iwl3945_rs_sta *rs_sta;
 	struct ieee80211_sta *sta;
 	struct iwl3945_sta_priv *psta;
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+	sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
@@ -924,11 +1010,11 @@ void iwl3945_rate_scale_init(struct ieee
 	if (rssi == 0)
 		rssi = IWL_MIN_RSSI_VAL;
 
-	IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
+	IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi);
 
 	rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band);
 
-	IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
+	IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: "
 		       "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
 		       iwl3945_rates[rs_sta->start_rate].plcp);
 	rcu_read_unlock();
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-3945-rs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,206 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2005 - 2008 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_3945_rs_h__
-#define __iwl_3945_rs_h__
-
-struct iwl3945_rate_info {
-	u8 plcp;		/* uCode API:  IWL_RATE_6M_PLCP, etc. */
-	u8 ieee;		/* MAC header:  IWL_RATE_6M_IEEE, etc. */
-	u8 prev_ieee;		/* previous rate in IEEE speeds */
-	u8 next_ieee;		/* next rate in IEEE speeds */
-	u8 prev_rs;		/* previous rate used in rs algo */
-	u8 next_rs;		/* next rate used in rs algo */
-	u8 prev_rs_tgg;		/* previous rate used in TGG rs algo */
-	u8 next_rs_tgg;		/* next rate used in TGG rs algo */
-	u8 table_rs_index;	/* index in rate scale table cmd */
-	u8 prev_table_rs;	/* prev in rate table cmd */
-};
-
-/*
- * These serve as indexes into
- * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
- */
-enum {
-	IWL_RATE_1M_INDEX = 0,
-	IWL_RATE_2M_INDEX,
-	IWL_RATE_5M_INDEX,
-	IWL_RATE_11M_INDEX,
-	IWL_RATE_6M_INDEX,
-	IWL_RATE_9M_INDEX,
-	IWL_RATE_12M_INDEX,
-	IWL_RATE_18M_INDEX,
-	IWL_RATE_24M_INDEX,
-	IWL_RATE_36M_INDEX,
-	IWL_RATE_48M_INDEX,
-	IWL_RATE_54M_INDEX,
-	IWL_RATE_COUNT,
-	IWL_RATE_INVM_INDEX,
-	IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
-};
-
-enum {
-	IWL_RATE_6M_INDEX_TABLE = 0,
-	IWL_RATE_9M_INDEX_TABLE,
-	IWL_RATE_12M_INDEX_TABLE,
-	IWL_RATE_18M_INDEX_TABLE,
-	IWL_RATE_24M_INDEX_TABLE,
-	IWL_RATE_36M_INDEX_TABLE,
-	IWL_RATE_48M_INDEX_TABLE,
-	IWL_RATE_54M_INDEX_TABLE,
-	IWL_RATE_1M_INDEX_TABLE,
-	IWL_RATE_2M_INDEX_TABLE,
-	IWL_RATE_5M_INDEX_TABLE,
-	IWL_RATE_11M_INDEX_TABLE,
-	IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
-};
-
-enum {
-	IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
-	IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
-	IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
-	IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
-};
-
-/* #define vs. enum to keep from defaulting to 'large integer' */
-#define	IWL_RATE_6M_MASK   (1 << IWL_RATE_6M_INDEX)
-#define	IWL_RATE_9M_MASK   (1 << IWL_RATE_9M_INDEX)
-#define	IWL_RATE_12M_MASK  (1 << IWL_RATE_12M_INDEX)
-#define	IWL_RATE_18M_MASK  (1 << IWL_RATE_18M_INDEX)
-#define	IWL_RATE_24M_MASK  (1 << IWL_RATE_24M_INDEX)
-#define	IWL_RATE_36M_MASK  (1 << IWL_RATE_36M_INDEX)
-#define	IWL_RATE_48M_MASK  (1 << IWL_RATE_48M_INDEX)
-#define	IWL_RATE_54M_MASK  (1 << IWL_RATE_54M_INDEX)
-#define	IWL_RATE_1M_MASK   (1 << IWL_RATE_1M_INDEX)
-#define	IWL_RATE_2M_MASK   (1 << IWL_RATE_2M_INDEX)
-#define	IWL_RATE_5M_MASK   (1 << IWL_RATE_5M_INDEX)
-#define	IWL_RATE_11M_MASK  (1 << IWL_RATE_11M_INDEX)
-
-/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */
-enum {
-	IWL_RATE_6M_PLCP = 13,
-	IWL_RATE_9M_PLCP = 15,
-	IWL_RATE_12M_PLCP = 5,
-	IWL_RATE_18M_PLCP = 7,
-	IWL_RATE_24M_PLCP = 9,
-	IWL_RATE_36M_PLCP = 11,
-	IWL_RATE_48M_PLCP = 1,
-	IWL_RATE_54M_PLCP = 3,
-	IWL_RATE_1M_PLCP = 10,
-	IWL_RATE_2M_PLCP = 20,
-	IWL_RATE_5M_PLCP = 55,
-	IWL_RATE_11M_PLCP = 110,
-};
-
-/* MAC header values for bit rates */
-enum {
-	IWL_RATE_6M_IEEE = 12,
-	IWL_RATE_9M_IEEE = 18,
-	IWL_RATE_12M_IEEE = 24,
-	IWL_RATE_18M_IEEE = 36,
-	IWL_RATE_24M_IEEE = 48,
-	IWL_RATE_36M_IEEE = 72,
-	IWL_RATE_48M_IEEE = 96,
-	IWL_RATE_54M_IEEE = 108,
-	IWL_RATE_1M_IEEE = 2,
-	IWL_RATE_2M_IEEE = 4,
-	IWL_RATE_5M_IEEE = 11,
-	IWL_RATE_11M_IEEE = 22,
-};
-
-#define IWL_CCK_BASIC_RATES_MASK    \
-       (IWL_RATE_1M_MASK          | \
-	IWL_RATE_2M_MASK)
-
-#define IWL_CCK_RATES_MASK          \
-       (IWL_BASIC_RATES_MASK      | \
-	IWL_RATE_5M_MASK          | \
-	IWL_RATE_11M_MASK)
-
-#define IWL_OFDM_BASIC_RATES_MASK   \
-	(IWL_RATE_6M_MASK         | \
-	IWL_RATE_12M_MASK         | \
-	IWL_RATE_24M_MASK)
-
-#define IWL_OFDM_RATES_MASK         \
-       (IWL_OFDM_BASIC_RATES_MASK | \
-	IWL_RATE_9M_MASK          | \
-	IWL_RATE_18M_MASK         | \
-	IWL_RATE_36M_MASK         | \
-	IWL_RATE_48M_MASK         | \
-	IWL_RATE_54M_MASK)
-
-#define IWL_BASIC_RATES_MASK         \
-	(IWL_OFDM_BASIC_RATES_MASK | \
-	 IWL_CCK_BASIC_RATES_MASK)
-
-#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-
-#define IWL_INV_TPT    -1
-
-#define IWL_MIN_RSSI_VAL                 -100
-#define IWL_MAX_RSSI_VAL                    0
-
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
-
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
-	u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
-	if (rate == IWL_RATE_INVALID)
-		rate = rate_index;
-	return rate;
-}
-
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
-/**
- * iwl3945_rate_control_register - Register the rate control algorithm callbacks
- *
- * Since the rate control algorithm is hardware specific, there is no need
- * or reason to place it as a stand alone module.  The driver can call
- * iwl3945_rate_control_register in order to register the rate control callbacks
- * with the mac80211 subsystem.  This should be performed prior to calling
- * ieee80211_register_hw
- *
- */
-extern int iwl3945_rate_control_register(void);
-
-/**
- * iwl3945_rate_control_unregister - Unregister the rate control callbacks
- *
- * This should be called after calling ieee80211_unregister_hw, but before
- * the driver is unloaded.
- */
-extern void iwl3945_rate_control_unregister(void);
-
-#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 18:04:40.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-4965.c	2013-05-03 16:48:28.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -76,7 +76,7 @@ static int iwl4965_verify_bsm(struct iwl
 	u32 reg;
 	u32 val;
 
-	IWL_DEBUG_INFO("Begin verify bsm\n");
+	IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
 
 	/* verify BSM SRAM contents */
 	val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
@@ -85,7 +85,7 @@ static int iwl4965_verify_bsm(struct iwl
 	     reg += sizeof(u32), image++) {
 		val = iwl_read_prph(priv, reg);
 		if (val != le32_to_cpu(*image)) {
-			IWL_ERROR("BSM uCode verification failed at "
+			IWL_ERR(priv, "BSM uCode verification failed at "
 				  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
 				  BSM_SRAM_LOWER_BOUND,
 				  reg - BSM_SRAM_LOWER_BOUND, len,
@@ -94,7 +94,7 @@ static int iwl4965_verify_bsm(struct iwl
 		}
 	}
 
-	IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
+	IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
 
 	return 0;
 }
@@ -144,12 +144,12 @@ static int iwl4965_load_bsm(struct iwl_p
 	u32 reg_offset;
 	int ret;
 
-	IWL_DEBUG_INFO("Begin load bsm\n");
+	IWL_DEBUG_INFO(priv, "Begin load bsm\n");
 
 	priv->ucode_type = UCODE_RT;
 
 	/* make sure bootstrap program is no larger than BSM's SRAM size */
-	if (len > IWL_MAX_BSM_SIZE)
+	if (len > IWL49_MAX_BSM_SIZE)
 		return -EINVAL;
 
 	/* Tell bootstrap uCode where to find the "Initialize" uCode
@@ -186,7 +186,7 @@ static int iwl4965_load_bsm(struct iwl_p
 
 	/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
 	iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
-	iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND);
+	iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND);
 	iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
 
 	/* Load bootstrap code into instruction SRAM now,
@@ -201,9 +201,9 @@ static int iwl4965_load_bsm(struct iwl_p
 		udelay(10);
 	}
 	if (i < 100)
-		IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
+		IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
 	else {
-		IWL_ERROR("BSM write did not complete!\n");
+		IWL_ERR(priv, "BSM write did not complete!\n");
 		return -EIO;
 	}
 
@@ -257,7 +257,7 @@ static int iwl4965_set_ucode_ptrs(struct
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+	IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
 
 	return ret;
 }
@@ -279,7 +279,7 @@ static void iwl4965_init_alive_start(str
 	if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
 		/* We had an error bringing up the hardware, so take it
 		 * all the way back down so we can try again */
-		IWL_DEBUG_INFO("Initialize Alive failed.\n");
+		IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
 		goto restart;
 	}
 
@@ -289,7 +289,7 @@ static void iwl4965_init_alive_start(str
 	if (iwl_verify_ucode(priv)) {
 		/* Runtime instruction load was bad;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+		IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
 		goto restart;
 	}
 
@@ -299,11 +299,11 @@ static void iwl4965_init_alive_start(str
 	/* Send pointers to protocol/runtime uCode image ... init code will
 	 * load and launch runtime uCode, which will send us another "Alive"
 	 * notification. */
-	IWL_DEBUG_INFO("Initialization Alive received.\n");
+	IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
 	if (iwl4965_set_ucode_ptrs(priv)) {
 		/* Runtime instruction load won't happen;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+		IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
 		goto restart;
 	}
 	return;
@@ -354,7 +354,7 @@ static int iwl4965_apm_init(struct iwl_p
 	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 	if (ret < 0) {
-		IWL_DEBUG_INFO("Failed to init the card\n");
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 		goto out;
 	}
 
@@ -381,27 +381,20 @@ out:
 static void iwl4965_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
-	u32 val;
 	u16 radio_cfg;
-	u16 link;
+	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) {
-		pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
-		/* Enable No Snoop field */
-		pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
-				       val & ~(1 << 11));
-	}
-
-	pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+	lctl = iwl_pcie_link_ctl(priv);
 
-	/* L1 is enabled by BIOS */
-	if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* disable L0S disabled L1A enabled */
+	/* 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
-		/* L0S enabled L1A disabled */
+		/* 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);
@@ -437,7 +430,7 @@ static int iwl4965_apm_stop_master(struc
 			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO("stop master\n");
+	IWL_DEBUG_INFO(priv, "stop master\n");
 
 	return 0;
 }
@@ -523,9 +516,10 @@ static void iwl4965_chain_noise_reset(st
 		cmd.diff_gain_c = 0;
 		if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
 				 sizeof(cmd), &cmd))
-			IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+			IWL_ERR(priv,
+				"Could not send REPLY_PHY_CALIBRATION_CMD\n");
 		data->state = IWL_CHAIN_NOISE_ACCUMULATE;
-		IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+		IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
 	}
 }
 
@@ -557,7 +551,7 @@ static void iwl4965_gain_computation(str
 			data->delta_gain_code[i] = 0;
 		}
 	}
-	IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
+	IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n",
 		     data->delta_gain_code[0],
 		     data->delta_gain_code[1],
 		     data->delta_gain_code[2]);
@@ -575,7 +569,7 @@ static void iwl4965_gain_computation(str
 		ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
 				      sizeof(cmd), &cmd);
 		if (ret)
-			IWL_DEBUG_CALIB("fail sending cmd "
+			IWL_DEBUG_CALIB(priv, "fail sending cmd "
 				     "REPLY_PHY_CALIBRATION_CMD \n");
 
 		/* TODO we might want recalculate
@@ -668,7 +662,7 @@ static void iwl4965_tx_queue_set_status(
 
 	txq->sched_retry = scd_retry;
 
-	IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+	IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
 		       active ? "Activate" : "Deactivate",
 		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
@@ -804,8 +798,9 @@ static int iwl4965_hw_set_hw_params(stru
 
 	if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
 	    (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
-		IWL_ERROR("invalid queues_num, should be between %d and %d\n",
-			  IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
+		IWL_ERR(priv,
+			"invalid queues_num, should be between %d and %d\n",
+			IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
 		return -EINVAL;
 	}
 
@@ -813,6 +808,7 @@ static int iwl4965_hw_set_hw_params(stru
 	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->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;
 	priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -820,6 +816,8 @@ static int iwl4965_hw_set_hw_params(stru
 	priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
 	priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
 
+	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;
@@ -902,7 +900,6 @@ static s32 iwl4965_get_tx_atten_grp(u16
 	    channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
 		return CALIB_CH_GROUP_4;
 
-	IWL_ERROR("Can't find txatten group for channel %d.\n", channel);
 	return -1;
 }
 
@@ -956,7 +953,7 @@ static int iwl4965_interpolate_chan(stru
 
 	s = iwl4965_get_sub_band(priv, channel);
 	if (s >= EEPROM_TX_POWER_BANDS) {
-		IWL_ERROR("Tx Power can not find channel %d\n", channel);
+		IWL_ERR(priv, "Tx Power can not find channel %d\n", channel);
 		return -1;
 	}
 
@@ -964,7 +961,7 @@ static int iwl4965_interpolate_chan(stru
 	ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
 	chan_info->ch_num = (u8) channel;
 
-	IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
+	IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n",
 			  channel, s, ch_i1, ch_i2);
 
 	for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
@@ -994,19 +991,19 @@ static int iwl4965_interpolate_chan(stru
 							   m1->pa_det, ch_i2,
 							   m2->pa_det);
 
-			IWL_DEBUG_TXPOWER
-			    ("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
-			     m1->actual_pow, m2->actual_pow, omeas->actual_pow);
-			IWL_DEBUG_TXPOWER
-			    ("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
-			     m1->gain_idx, m2->gain_idx, omeas->gain_idx);
-			IWL_DEBUG_TXPOWER
-			    ("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
-			     m1->pa_det, m2->pa_det, omeas->pa_det);
-			IWL_DEBUG_TXPOWER
-			    ("chain %d meas %d  T1=%d  T2=%d  T=%d\n", c, m,
-			     m1->temperature, m2->temperature,
-			     omeas->temperature);
+			IWL_DEBUG_TXPOWER(priv,
+				"chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
+				m1->actual_pow, m2->actual_pow, omeas->actual_pow);
+			IWL_DEBUG_TXPOWER(priv,
+				"chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
+				m1->gain_idx, m2->gain_idx, omeas->gain_idx);
+			IWL_DEBUG_TXPOWER(priv,
+				"chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
+				m1->pa_det, m2->pa_det, omeas->pa_det);
+			IWL_DEBUG_TXPOWER(priv,
+				"chain %d meas %d  T1=%d  T2=%d  T=%d\n", c, m,
+				m1->temperature, m2->temperature,
+				omeas->temperature);
 		}
 	}
 
@@ -1303,12 +1300,12 @@ static int iwl4965_fill_txpower_tbl(stru
 	s32 factory_actual_pwr[2];
 	s32 power_index;
 
-	/* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
+	/* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units
 	 *   are used for indexing into txpower table) */
 	user_target_power = 2 * priv->tx_power_user_lmt;
 
 	/* Get current (RXON) channel, band, width */
-	IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
+	IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_fat %d\n", channel, band,
 			  is_fat);
 
 	ch_info = iwl_get_channel_info(priv, priv->band, channel);
@@ -1319,10 +1316,13 @@ static int iwl4965_fill_txpower_tbl(stru
 	/* get txatten group, used to select 1) thermal txpower adjustment
 	 *   and 2) mimo txpower balance between Tx chains. */
 	txatten_grp = iwl4965_get_tx_atten_grp(channel);
-	if (txatten_grp < 0)
+	if (txatten_grp < 0) {
+		IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
+			  channel);
 		return -EINVAL;
+	}
 
-	IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",
+	IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
 			  channel, txatten_grp);
 
 	if (is_fat) {
@@ -1372,7 +1372,7 @@ static int iwl4965_fill_txpower_tbl(stru
 	voltage_compensation =
 	    iwl4965_get_voltage_compensation(voltage, init_voltage);
 
-	IWL_DEBUG_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n",
+	IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n",
 			  init_voltage,
 			  voltage, voltage_compensation);
 
@@ -1403,13 +1403,13 @@ static int iwl4965_fill_txpower_tbl(stru
 		factory_gain_index[c] = measurement->gain_idx;
 		factory_actual_pwr[c] = measurement->actual_pow;
 
-		IWL_DEBUG_TXPOWER("chain = %d\n", c);
-		IWL_DEBUG_TXPOWER("fctry tmp %d, "
+		IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c);
+		IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, "
 				  "curr tmp %d, comp %d steps\n",
 				  factory_temp, current_temp,
 				  temperature_comp[c]);
 
-		IWL_DEBUG_TXPOWER("fctry idx %d, fctry pwr %d\n",
+		IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n",
 				  factory_gain_index[c],
 				  factory_actual_pwr[c]);
 	}
@@ -1442,7 +1442,7 @@ static int iwl4965_fill_txpower_tbl(stru
 		if (target_power > power_limit)
 			target_power = power_limit;
 
-		IWL_DEBUG_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n",
+		IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n",
 				  i, saturation_power - back_off_table[i],
 				  current_regulatory, user_target_power,
 				  target_power);
@@ -1466,7 +1466,7 @@ static int iwl4965_fill_txpower_tbl(stru
 					    voltage_compensation +
 					    atten_value);
 
-/*			IWL_DEBUG_TXPOWER("calculated txpower index %d\n",
+/*			IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n",
 						power_index); */
 
 			if (power_index < get_min_power_index(i, band))
@@ -1483,12 +1483,12 @@ static int iwl4965_fill_txpower_tbl(stru
 
 			/* stay within the table! */
 			if (power_index > 107) {
-				IWL_WARNING("txpower index %d > 107\n",
+				IWL_WARN(priv, "txpower index %d > 107\n",
 					    power_index);
 				power_index = 107;
 			}
 			if (power_index < 0) {
-				IWL_WARNING("txpower index %d < 0\n",
+				IWL_WARN(priv, "txpower index %d < 0\n",
 					    power_index);
 				power_index = 0;
 			}
@@ -1499,7 +1499,7 @@ static int iwl4965_fill_txpower_tbl(stru
 			tx_power.s.dsp_predis_atten[c] =
 				gain_table[band][power_index].dsp;
 
-			IWL_DEBUG_TXPOWER("chain %d mimo %d index %d "
+			IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d "
 					  "gain 0x%02x dsp %d\n",
 					  c, atten_value, power_index,
 					tx_power.s.radio_tx_gain[c],
@@ -1531,7 +1531,7 @@ static int iwl4965_send_tx_power(struct
 		/* If this gets hit a lot, switch it to a BUG() and catch
 		 * the stack trace to find out who is calling this during
 		 * a scan. */
-		IWL_WARNING("TX Power requested while scanning!\n");
+		IWL_WARN(priv, "TX Power requested while scanning!\n");
 		return -EAGAIN;
 	}
 
@@ -1574,7 +1574,7 @@ static int iwl4965_send_rxon_assoc(struc
 	     rxon2->ofdm_ht_dual_stream_basic_rates) &&
 	    (rxon1->rx_chain == rxon2->rx_chain) &&
 	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
-		IWL_DEBUG_INFO("Using current RXON_ASSOC.  Not resending.\n");
+		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
 		return 0;
 	}
 
@@ -1631,7 +1631,7 @@ static int iwl4965_hw_channel_switch(str
 	rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat,
 				      ctrl_chan_high, &cmd.tx_power);
 	if (rc) {
-		IWL_DEBUG_11H("error:%d  fill txpower_tbl\n", rc);
+		IWL_DEBUG_11H(priv, "error:%d  fill txpower_tbl\n", rc);
 		return rc;
 	}
 
@@ -1696,13 +1696,13 @@ static int iwl4965_hw_get_temperature(co
 
 	if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
 		(priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) {
-		IWL_DEBUG_TEMP("Running FAT temperature calibration\n");
+		IWL_DEBUG_TEMP(priv, "Running FAT temperature calibration\n");
 		R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
 		R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
 		R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
 		R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]);
 	} else {
-		IWL_DEBUG_TEMP("Running temperature calibration\n");
+		IWL_DEBUG_TEMP(priv, "Running temperature calibration\n");
 		R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
 		R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
 		R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
@@ -1722,10 +1722,10 @@ static int iwl4965_hw_get_temperature(co
 		vt = sign_extend(
 			le32_to_cpu(priv->statistics.general.temperature), 23);
 
-	IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
+	IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
 
 	if (R3 == R1) {
-		IWL_ERROR("Calibration conflict R1 == R3\n");
+		IWL_ERR(priv, "Calibration conflict R1 == R3\n");
 		return -1;
 	}
 
@@ -1735,7 +1735,7 @@ static int iwl4965_hw_get_temperature(co
 	temperature /= (R3 - R1);
 	temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
 
-	IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+	IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n",
 			temperature, KELVIN_TO_CELSIUS(temperature));
 
 	return temperature;
@@ -1758,7 +1758,7 @@ static int iwl4965_is_temp_calib_needed(
 	int temp_diff;
 
 	if (!test_bit(STATUS_STATISTICS, &priv->status)) {
-		IWL_DEBUG_TEMP("Temperature not updated -- no statistics.\n");
+		IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n");
 		return 0;
 	}
 
@@ -1766,19 +1766,19 @@ static int iwl4965_is_temp_calib_needed(
 
 	/* get absolute value */
 	if (temp_diff < 0) {
-		IWL_DEBUG_POWER("Getting cooler, delta %d, \n", temp_diff);
+		IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff);
 		temp_diff = -temp_diff;
 	} else if (temp_diff == 0)
-		IWL_DEBUG_POWER("Same temp, \n");
+		IWL_DEBUG_POWER(priv, "Same temp, \n");
 	else
-		IWL_DEBUG_POWER("Getting warmer, delta %d, \n", temp_diff);
+		IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff);
 
 	if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
-		IWL_DEBUG_POWER("Thermal txpower calib not needed\n");
+		IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n");
 		return 0;
 	}
 
-	IWL_DEBUG_POWER("Thermal txpower calib needed\n");
+	IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n");
 
 	return 1;
 }
@@ -1793,12 +1793,12 @@ static void iwl4965_temperature_calib(st
 
 	if (priv->temperature != temp) {
 		if (priv->temperature)
-			IWL_DEBUG_TEMP("Temperature changed "
+			IWL_DEBUG_TEMP(priv, "Temperature changed "
 				       "from %dC to %dC\n",
 				       KELVIN_TO_CELSIUS(priv->temperature),
 				       KELVIN_TO_CELSIUS(temp));
 		else
-			IWL_DEBUG_TEMP("Temperature "
+			IWL_DEBUG_TEMP(priv, "Temperature "
 				       "initialized to %dC\n",
 				       KELVIN_TO_CELSIUS(temp));
 	}
@@ -1837,7 +1837,8 @@ static int iwl4965_txq_agg_disable(struc
 
 	if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
-		IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+		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);
 		return -EINVAL;
@@ -1908,7 +1909,8 @@ static int iwl4965_txq_agg_enable(struct
 
 	if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
-		IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+		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);
 		return -EINVAL;
@@ -1986,8 +1988,8 @@ 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->reserved1 = __constant_cpu_to_le16(0);
-	addsta->reserved2 = __constant_cpu_to_le32(0);
+	addsta->reserved1 = cpu_to_le16(0);
+	addsta->reserved2 = cpu_to_le32(0);
 
 	return (u16)sizeof(struct iwl4965_addsta_cmd);
 }
@@ -2013,7 +2015,7 @@ static int iwl4965_tx_status_reply_tx(st
 	int i, sh, idx;
 	u16 seq;
 	if (agg->wait_for_ba)
-		IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+		IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
 
 	agg->frame_count = tx_resp->frame_count;
 	agg->start_idx = start_idx;
@@ -2027,7 +2029,7 @@ static int iwl4965_tx_status_reply_tx(st
 		idx = start_idx;
 
 		/* FIXME: code repetition */
-		IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+		IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
 				   agg->frame_count, agg->start_idx, idx);
 
 		info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -2038,9 +2040,9 @@ static int iwl4965_tx_status_reply_tx(st
 		iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
 		/* FIXME: code repetition end */
 
-		IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+		IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
 				    status & 0xff, tx_resp->failure_frame);
-		IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+		IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
 
 		agg->wait_for_ba = 0;
 	} else {
@@ -2060,21 +2062,21 @@ static int iwl4965_tx_status_reply_tx(st
 				      AGG_TX_STATE_ABORT_MSK))
 				continue;
 
-			IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+			IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
 					   agg->frame_count, txq_id, idx);
 
 			hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
 
 			sc = le16_to_cpu(hdr->seq_ctrl);
 			if (idx != (SEQ_TO_SN(sc) & 0xff)) {
-				IWL_ERROR("BUG_ON idx doesn't match seq control"
-					  " idx=%d, seq_idx=%d, seq=%d\n",
-					  idx, SEQ_TO_SN(sc),
-					  hdr->seq_ctrl);
+				IWL_ERR(priv,
+					"BUG_ON idx doesn't match seq control"
+					" idx=%d, seq_idx=%d, seq=%d\n",
+					idx, SEQ_TO_SN(sc), hdr->seq_ctrl);
 				return -1;
 			}
 
-			IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+			IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
 					   i, idx, SEQ_TO_SN(sc));
 
 			sh = idx - start;
@@ -2092,13 +2094,13 @@ static int iwl4965_tx_status_reply_tx(st
 				sh = 0;
 			}
 			bitmap |= 1ULL << sh;
-			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+			IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
 					   start, (unsigned long long)bitmap);
 		}
 
 		agg->bitmap = bitmap;
 		agg->start_idx = start;
-		IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+		IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
 				   agg->frame_count, agg->start_idx,
 				   (unsigned long long)agg->bitmap);
 
@@ -2129,7 +2131,7 @@ static void iwl4965_rx_reply_tx(struct i
 	u8 *qc = NULL;
 
 	if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+		IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
 			  "is out of range [0-%d] %d %d\n", txq_id,
 			  index, txq->q.n_bd, txq->q.write_ptr,
 			  txq->q.read_ptr);
@@ -2147,7 +2149,7 @@ static void iwl4965_rx_reply_tx(struct i
 
 	sta_id = iwl_get_ra_sta_id(priv, hdr);
 	if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
-		IWL_ERROR("Station not known\n");
+		IWL_ERR(priv, "Station not known\n");
 		return;
 	}
 
@@ -2167,7 +2169,7 @@ static void iwl4965_rx_reply_tx(struct i
 
 		if (txq->q.read_ptr != (scd_ssn & 0xff)) {
 			index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
-			IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
+			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;
@@ -2176,10 +2178,9 @@ static void iwl4965_rx_reply_tx(struct i
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 			    (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
 				if (agg->state == IWL_AGG_OFF)
-					ieee80211_wake_queue(priv->hw, txq_id);
+					iwl_wake_queue(priv, txq_id);
 				else
-					ieee80211_wake_queue(priv->hw,
-							     txq->swq_id);
+					iwl_wake_queue(priv, txq->swq_id);
 			}
 		}
 	} else {
@@ -2190,7 +2191,7 @@ static void iwl4965_rx_reply_tx(struct i
 					le32_to_cpu(tx_resp->rate_n_flags),
 					info);
 
-		IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
+		IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) "
 				   "rate_n_flags 0x%x retries %d\n",
 				   txq_id,
 				   iwl_get_tx_fail_reason(status), status,
@@ -2203,14 +2204,14 @@ static void iwl4965_rx_reply_tx(struct i
 
 		if (priv->mac80211_registered &&
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
-			ieee80211_wake_queue(priv->hw, txq_id);
+			iwl_wake_queue(priv, txq_id);
 	}
 
 	if (qc && likely(sta_id != IWL_INVALID_STATION))
 		iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
-		IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
+		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
 static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2238,13 +2239,13 @@ static int iwl4965_calc_rssi(struct iwl_
 		if (valid_antennae & (1 << i))
 			max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
 
-	IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+	IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
 		ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
 		max_rssi, agc);
 
 	/* dBm = max_rssi dB - agc dB - constant.
 	 * Higher AGC (higher radio gain) means lower signal. */
-	return max_rssi - agc - IWL_RSSI_OFFSET;
+	return max_rssi - agc - IWL49_RSSI_OFFSET;
 }
 
 
@@ -2287,6 +2288,9 @@ static struct iwl_lib_ops iwl4965_lib =
 	.txq_set_sched = iwl4965_txq_set_sched,
 	.txq_agg_enable = iwl4965_txq_agg_enable,
 	.txq_agg_disable = iwl4965_txq_agg_disable,
+	.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+	.txq_free_tfd = iwl_hw_txq_free_tfd,
+	.txq_init = iwl_hw_tx_queue_init,
 	.rx_handler_setup = iwl4965_rx_handler_setup,
 	.setup_deferred_work = iwl4965_setup_deferred_work,
 	.cancel_deferred_work = iwl4965_cancel_deferred_work,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-4965-hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,64 +89,43 @@
 #define LONG_SLOT_TIME 20
 
 /* RSSI to dBm */
-#define IWL_RSSI_OFFSET	44
-
+#define IWL49_RSSI_OFFSET	44
 
 
 /* PCI registers */
 #define PCI_CFG_RETRY_TIMEOUT	0x041
-#define PCI_CFG_POWER_SOURCE	0x0C8
-#define PCI_REG_WUM8		0x0E8
-#define PCI_CFG_LINK_CTRL	0x0F0
 
 /* PCI register values */
 #define PCI_CFG_LINK_CTRL_VAL_L0S_EN	0x01
 #define PCI_CFG_LINK_CTRL_VAL_L1_EN	0x02
-#define PCI_CFG_CMD_REG_INT_DIS_MSK	0x04
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
-
 
 #define IWL_NUM_SCAN_RATES         (2)
 
 #define IWL_DEFAULT_TX_RETRY  15
 
-#define RX_QUEUE_SIZE                         256
-#define RX_QUEUE_MASK                         255
-#define RX_QUEUE_SIZE_LOG                     8
-
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_4K (4 * 1024)
-#define IWL_RX_BUF_SIZE_8K (8 * 1024)
 
 /* Sizes and addresses for instruction and data memory (SRAM) in
  * 4965's embedded processor.  Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND			(0x000000)
+#define IWL49_RTC_INST_LOWER_BOUND		(0x000000)
 #define IWL49_RTC_INST_UPPER_BOUND		(0x018000)
 
-#define RTC_DATA_LOWER_BOUND			(0x800000)
+#define IWL49_RTC_DATA_LOWER_BOUND		(0x800000)
 #define IWL49_RTC_DATA_UPPER_BOUND		(0x80A000)
 
-#define IWL49_RTC_INST_SIZE  (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL49_RTC_DATA_SIZE  (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL49_RTC_INST_SIZE  (IWL49_RTC_INST_UPPER_BOUND - \
+				IWL49_RTC_INST_LOWER_BOUND)
+#define IWL49_RTC_DATA_SIZE  (IWL49_RTC_DATA_UPPER_BOUND - \
+				IWL49_RTC_DATA_LOWER_BOUND)
 
-#define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
+#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE
+#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
 
 /* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE
 
 static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
 {
-	return (addr >= RTC_DATA_LOWER_BOUND) &&
+	return (addr >= IWL49_RTC_DATA_LOWER_BOUND) &&
 	       (addr < IWL49_RTC_DATA_UPPER_BOUND);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 18:04:42.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-05-03 16:48:31.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 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
@@ -43,10 +43,11 @@
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
 #include "iwl-5000-hw.h"
+#include "iwl-6000-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL5000_UCODE_API_MAX 1
-#define IWL5150_UCODE_API_MAX 1
+#define IWL5000_UCODE_API_MAX 2
+#define IWL5150_UCODE_API_MAX 2
 
 /* Lowest firmware API version supported */
 #define IWL5000_UCODE_API_MIN 1
@@ -84,7 +85,7 @@ static int iwl5000_apm_stop_master(struc
 				  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_INFO("stop master\n");
+	IWL_DEBUG_INFO(priv, "stop master\n");
 
 	return 0;
 }
@@ -108,7 +109,8 @@ static int iwl5000_apm_init(struct iwl_p
 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 
-	iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+	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 */
@@ -118,7 +120,7 @@ static int iwl5000_apm_init(struct iwl_p
 	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 	if (ret < 0) {
-		IWL_DEBUG_INFO("Failed to init the card\n");
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 		return ret;
 	}
 
@@ -176,7 +178,8 @@ static int iwl5000_apm_reset(struct iwl_
 
 	/* FIXME: put here L1A -L0S w/a */
 
-	iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+	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 */
@@ -186,7 +189,7 @@ static int iwl5000_apm_reset(struct iwl_
 	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 	if (ret < 0) {
-		IWL_DEBUG_INFO("Failed to init the card\n");
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 		goto out;
 	}
 
@@ -216,18 +219,19 @@ static void iwl5000_nic_config(struct iw
 {
 	unsigned long flags;
 	u16 radio_cfg;
-	u16 link;
+	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+	lctl = iwl_pcie_link_ctl(priv);
 
-	/* L1 is enabled by BIOS */
-	if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* disable L0S disabled L1A enabled */
+	/* 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
-		/* L0S enabled L1A disabled */
+		/* 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);
@@ -289,7 +293,7 @@ static u32 eeprom_indirect_address(const
 		offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
 		break;
 	default:
-		IWL_ERROR("illegal indirect type: 0x%X\n",
+		IWL_ERR(priv, "illegal indirect type: 0x%X\n",
 		address & INDIRECT_TYPE_MSK);
 		break;
 	}
@@ -338,7 +342,7 @@ static void iwl5000_gain_computation(str
 			data->delta_gain_code[i] |= (1 << 2);
 	}
 
-	IWL_DEBUG_CALIB("Delta gains: ANT_B = %d  ANT_C = %d\n",
+	IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d  ANT_C = %d\n",
 			data->delta_gain_code[1], data->delta_gain_code[2]);
 
 	if (!data->radio_write) {
@@ -384,13 +388,14 @@ static void iwl5000_chain_noise_reset(st
 		ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
 					sizeof(cmd), &cmd);
 		if (ret)
-			IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+			IWL_ERR(priv,
+				"Could not send REPLY_PHY_CALIBRATION_CMD\n");
 		data->state = IWL_CHAIN_NOISE_ACCUMULATE;
-		IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+		IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
 	}
 }
 
-static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 			__le32 *tx_flags)
 {
 	if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
@@ -507,7 +512,7 @@ static void iwl5000_rx_calib_result(stru
 		index = IWL_CALIB_BASE_BAND;
 		break;
 	default:
-		IWL_ERROR("Unknown calibration notification %d\n",
+		IWL_ERR(priv, "Unknown calibration notification %d\n",
 			  hdr->op_code);
 		return;
 	}
@@ -517,7 +522,7 @@ static void iwl5000_rx_calib_result(stru
 static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
 			       struct iwl_rx_mem_buffer *rxb)
 {
-	IWL_DEBUG_INFO("Init. calibration is completed, restarting fw.\n");
+	IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
 	queue_work(priv->workqueue, &priv->restart);
 }
 
@@ -580,40 +585,41 @@ static int iwl5000_load_given_ucode(stru
 {
 	int ret = 0;
 
-	ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND);
+	ret = iwl5000_load_section(priv, inst_image,
+				   IWL50_RTC_INST_LOWER_BOUND);
 	if (ret)
 		return ret;
 
-	IWL_DEBUG_INFO("INST uCode section being loaded...\n");
+	IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
 	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
 					priv->ucode_write_complete, 5 * HZ);
 	if (ret == -ERESTARTSYS) {
-		IWL_ERROR("Could not load the INST uCode section due "
+		IWL_ERR(priv, "Could not load the INST uCode section due "
 			"to interrupt\n");
 		return ret;
 	}
 	if (!ret) {
-		IWL_ERROR("Could not load the INST uCode section\n");
+		IWL_ERR(priv, "Could not load the INST uCode section\n");
 		return -ETIMEDOUT;
 	}
 
 	priv->ucode_write_complete = 0;
 
 	ret = iwl5000_load_section(
-		priv, data_image, RTC_DATA_LOWER_BOUND);
+		priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
 	if (ret)
 		return ret;
 
-	IWL_DEBUG_INFO("DATA uCode section being loaded...\n");
+	IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
 
 	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
 				priv->ucode_write_complete, 5 * HZ);
 	if (ret == -ERESTARTSYS) {
-		IWL_ERROR("Could not load the INST uCode section due "
+		IWL_ERR(priv, "Could not load the INST uCode section due "
 			"to interrupt\n");
 		return ret;
 	} else if (!ret) {
-		IWL_ERROR("Could not load the DATA uCode section\n");
+		IWL_ERR(priv, "Could not load the DATA uCode section\n");
 		return -ETIMEDOUT;
 	} else
 		ret = 0;
@@ -629,20 +635,20 @@ static int iwl5000_load_ucode(struct iwl
 
 	/* check whether init ucode should be loaded, or rather runtime ucode */
 	if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
-		IWL_DEBUG_INFO("Init ucode found. Loading init ucode...\n");
+		IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
 		ret = iwl5000_load_given_ucode(priv,
 			&priv->ucode_init, &priv->ucode_init_data);
 		if (!ret) {
-			IWL_DEBUG_INFO("Init ucode load complete.\n");
+			IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
 			priv->ucode_type = UCODE_INIT;
 		}
 	} else {
-		IWL_DEBUG_INFO("Init ucode not found, or already loaded. "
+		IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
 			"Loading runtime ucode...\n");
 		ret = iwl5000_load_given_ucode(priv,
 			&priv->ucode_code, &priv->ucode_data);
 		if (!ret) {
-			IWL_DEBUG_INFO("Runtime ucode load complete.\n");
+			IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
 			priv->ucode_type = UCODE_RT;
 		}
 	}
@@ -658,7 +664,7 @@ static void iwl5000_init_alive_start(str
 	if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
 		/* We had an error bringing up the hardware, so take it
 		 * all the way back down so we can try again */
-		IWL_DEBUG_INFO("Initialize Alive failed.\n");
+		IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
 		goto restart;
 	}
 
@@ -668,14 +674,15 @@ static void iwl5000_init_alive_start(str
 	if (iwl_verify_ucode(priv)) {
 		/* Runtime instruction load was bad;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+		IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
 		goto restart;
 	}
 
 	iwl_clear_stations_table(priv);
 	ret = priv->cfg->ops->lib->alive_notify(priv);
 	if (ret) {
-		IWL_WARNING("Could not complete ALIVE transition: %d\n", ret);
+		IWL_WARN(priv,
+			"Could not complete ALIVE transition: %d\n", ret);
 		goto restart;
 	}
 
@@ -710,7 +717,7 @@ static void iwl5000_tx_queue_set_status(
 
 	txq->sched_retry = scd_retry;
 
-	IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+	IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
 		       active ? "Activate" : "Deactivate",
 		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
@@ -824,8 +831,9 @@ static int iwl5000_hw_set_hw_params(stru
 {
 	if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
 	    (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
-		IWL_ERROR("invalid queues_num, should be between %d and %d\n",
-			  IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
+		IWL_ERR(priv,
+			"invalid queues_num, should be between %d and %d\n",
+			IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
 		return -EINVAL;
 	}
 
@@ -833,70 +841,62 @@ static int iwl5000_hw_set_hw_params(stru
 	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->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 = IWL50_RTC_DATA_SIZE;
-	priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+
+	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_bsm_size = 0;
 	priv->hw_params.fat_channel =  BIT(IEEE80211_BAND_2GHZ) |
 					BIT(IEEE80211_BAND_5GHZ);
+	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
 	priv->hw_params.sens = &iwl5000_sensitivity;
 
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_5100:
-		priv->hw_params.tx_chains_num = 1;
-		priv->hw_params.rx_chains_num = 2;
-		priv->hw_params.valid_tx_ant = ANT_B;
-		priv->hw_params.valid_rx_ant = ANT_AB;
-		break;
-	case CSR_HW_REV_TYPE_5150:
-		priv->hw_params.tx_chains_num = 1;
-		priv->hw_params.rx_chains_num = 2;
-		priv->hw_params.valid_tx_ant = ANT_A;
-		priv->hw_params.valid_rx_ant = ANT_AB;
-		break;
-	case CSR_HW_REV_TYPE_5300:
-	case CSR_HW_REV_TYPE_5350:
-		priv->hw_params.tx_chains_num = 3;
-		priv->hw_params.rx_chains_num = 3;
-		priv->hw_params.valid_tx_ant = ANT_ABC;
-		priv->hw_params.valid_rx_ant = ANT_ABC;
-		break;
-	}
+	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;
 
 	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_5100:
-	case CSR_HW_REV_TYPE_5300:
-	case CSR_HW_REV_TYPE_5350:
-		/* 5X00 and 5350 wants in Celsius */
-		priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
-		break;
 	case CSR_HW_REV_TYPE_5150:
 		/* 5150 wants in Kelvin */
 		priv->hw_params.ct_kill_threshold =
 				iwl5150_get_ct_threshold(priv);
 		break;
+	default:
+		/* all others want Celsius */
+		priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
+		break;
 	}
 
 	/* Set initial calibration set */
 	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_5100:
-	case CSR_HW_REV_TYPE_5300:
-	case CSR_HW_REV_TYPE_5350:
+	case CSR_HW_REV_TYPE_5150:
 		priv->hw_params.calib_init_cfg =
-			BIT(IWL_CALIB_XTAL)		|
+			BIT(IWL_CALIB_DC)		|
 			BIT(IWL_CALIB_LO)		|
 			BIT(IWL_CALIB_TX_IQ) 		|
-			BIT(IWL_CALIB_TX_IQ_PERD)	|
 			BIT(IWL_CALIB_BASE_BAND);
+
 		break;
-	case CSR_HW_REV_TYPE_5150:
+	default:
 		priv->hw_params.calib_init_cfg =
-			BIT(IWL_CALIB_DC)		|
+			BIT(IWL_CALIB_XTAL)		|
 			BIT(IWL_CALIB_LO)		|
 			BIT(IWL_CALIB_TX_IQ) 		|
+			BIT(IWL_CALIB_TX_IQ_PERD)	|
 			BIT(IWL_CALIB_BASE_BAND);
-
 		break;
 	}
 
@@ -1011,7 +1011,8 @@ static int iwl5000_txq_agg_enable(struct
 
 	if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
-		IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+		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);
 		return -EINVAL;
@@ -1076,7 +1077,8 @@ static int iwl5000_txq_agg_disable(struc
 
 	if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
-		IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+		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);
 		return -EINVAL;
@@ -1104,7 +1106,7 @@ static int iwl5000_txq_agg_disable(struc
 	return 0;
 }
 
-static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 {
 	u16 size = (u16)sizeof(struct iwl_addsta_cmd);
 	memcpy(data, cmd, size);
@@ -1142,7 +1144,7 @@ static int iwl5000_tx_status_reply_tx(st
 	u16 seq;
 
 	if (agg->wait_for_ba)
-		IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+		IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
 
 	agg->frame_count = tx_resp->frame_count;
 	agg->start_idx = start_idx;
@@ -1156,7 +1158,7 @@ static int iwl5000_tx_status_reply_tx(st
 		idx = start_idx;
 
 		/* FIXME: code repetition */
-		IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+		IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
 				   agg->frame_count, agg->start_idx, idx);
 
 		info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -1168,9 +1170,9 @@ static int iwl5000_tx_status_reply_tx(st
 
 		/* FIXME: code repetition end */
 
-		IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+		IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
 				    status & 0xff, tx_resp->failure_frame);
-		IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+		IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
 
 		agg->wait_for_ba = 0;
 	} else {
@@ -1190,21 +1192,22 @@ static int iwl5000_tx_status_reply_tx(st
 				      AGG_TX_STATE_ABORT_MSK))
 				continue;
 
-			IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+			IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
 					   agg->frame_count, txq_id, idx);
 
 			hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
 
 			sc = le16_to_cpu(hdr->seq_ctrl);
 			if (idx != (SEQ_TO_SN(sc) & 0xff)) {
-				IWL_ERROR("BUG_ON idx doesn't match seq control"
-					  " idx=%d, seq_idx=%d, seq=%d\n",
+				IWL_ERR(priv,
+					"BUG_ON idx doesn't match seq control"
+					" idx=%d, seq_idx=%d, seq=%d\n",
 					  idx, SEQ_TO_SN(sc),
 					  hdr->seq_ctrl);
 				return -1;
 			}
 
-			IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+			IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
 					   i, idx, SEQ_TO_SN(sc));
 
 			sh = idx - start;
@@ -1222,13 +1225,13 @@ static int iwl5000_tx_status_reply_tx(st
 				sh = 0;
 			}
 			bitmap |= 1ULL << sh;
-			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+			IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
 					   start, (unsigned long long)bitmap);
 		}
 
 		agg->bitmap = bitmap;
 		agg->start_idx = start;
-		IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+		IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
 				   agg->frame_count, agg->start_idx,
 				   (unsigned long long)agg->bitmap);
 
@@ -1254,7 +1257,7 @@ static void iwl5000_rx_reply_tx(struct i
 	int freed;
 
 	if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+		IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
 			  "is out of range [0-%d] %d %d\n", txq_id,
 			  index, txq->q.n_bd, txq->q.write_ptr,
 			  txq->q.read_ptr);
@@ -1281,7 +1284,7 @@ static void iwl5000_rx_reply_tx(struct i
 
 		if (txq->q.read_ptr != (scd_ssn & 0xff)) {
 			index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
-			IWL_DEBUG_TX_REPLY("Retry scheduler reclaim "
+			IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
 					"scd_ssn=%d idx=%d txq=%d swq=%d\n",
 					scd_ssn , index, txq_id, txq->swq_id);
 
@@ -1292,10 +1295,9 @@ static void iwl5000_rx_reply_tx(struct i
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 			    (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
 				if (agg->state == IWL_AGG_OFF)
-					ieee80211_wake_queue(priv->hw, txq_id);
+					iwl_wake_queue(priv, txq_id);
 				else
-					ieee80211_wake_queue(priv->hw,
-							     txq->swq_id);
+					iwl_wake_queue(priv, txq->swq_id);
 			}
 		}
 	} else {
@@ -1308,7 +1310,7 @@ static void iwl5000_rx_reply_tx(struct i
 					le32_to_cpu(tx_resp->rate_n_flags),
 					info);
 
-		IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags "
+		IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
 				   "0x%x retries %d\n",
 				   txq_id,
 				   iwl_get_tx_fail_reason(status), status,
@@ -1321,18 +1323,18 @@ static void iwl5000_rx_reply_tx(struct i
 
 		if (priv->mac80211_registered &&
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
-			ieee80211_wake_queue(priv->hw, txq_id);
+			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);
 
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
-		IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
+		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
 /* Currently 5000 is the superset of everything */
-static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
+u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
 {
 	return len;
 }
@@ -1356,7 +1358,7 @@ static void iwl5000_rx_handler_setup(str
 
 static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
 {
-	return (addr >= RTC_DATA_LOWER_BOUND) &&
+	return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
 		(addr < IWL50_RTC_DATA_UPPER_BOUND);
 }
 
@@ -1379,7 +1381,7 @@ static int iwl5000_send_rxon_assoc(struc
 	    (rxon1->acquisition_data == rxon2->acquisition_data) &&
 	    (rxon1->rx_chain == rxon2->rx_chain) &&
 	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
-		IWL_DEBUG_INFO("Using current RXON_ASSOC.  Not resending.\n");
+		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
 		return 0;
 	}
 
@@ -1409,12 +1411,19 @@ static int iwl5000_send_rxon_assoc(struc
 static int  iwl5000_send_tx_power(struct iwl_priv *priv)
 {
 	struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+	u8 tx_ant_cfg_cmd;
 
 	/* half dBm need to multiply */
 	tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
 	tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
 	tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
-	return  iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
+
+	if (IWL_UCODE_API(priv->ucode_ver) == 1)
+		tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
+	else
+		tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
+
+	return  iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
 				       sizeof(tx_power_cmd), &tx_power_cmd,
 				       NULL);
 }
@@ -1426,7 +1435,7 @@ static void iwl5000_temperature(struct i
 }
 
 /* Calc max signal level (dBm) among 3 possible receivers */
-static int iwl5000_calc_rssi(struct iwl_priv *priv,
+int iwl5000_calc_rssi(struct iwl_priv *priv,
 			     struct iwl_rx_phy_res *rx_resp)
 {
 	/* data from PHY/DSP regarding signal strength, etc.,
@@ -1455,19 +1464,19 @@ static int iwl5000_calc_rssi(struct iwl_
 	max_rssi = max_t(u32, rssi_a, rssi_b);
 	max_rssi = max_t(u32, max_rssi, rssi_c);
 
-	IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+	IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
 		rssi_a, rssi_b, rssi_c, max_rssi, agc);
 
 	/* dBm = max_rssi dB - agc dB - constant.
 	 * Higher AGC (higher radio gain) means lower signal. */
-	return max_rssi - agc - IWL_RSSI_OFFSET;
+	return max_rssi - agc - IWL49_RSSI_OFFSET;
 }
 
-static struct iwl_hcmd_ops iwl5000_hcmd = {
+struct iwl_hcmd_ops iwl5000_hcmd = {
 	.rxon_assoc = iwl5000_send_rxon_assoc,
 };
 
-static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
+struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
 	.get_hcmd_size = iwl5000_get_hcmd_size,
 	.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
 	.gain_computation = iwl5000_gain_computation,
@@ -1476,13 +1485,16 @@ static struct iwl_hcmd_utils_ops iwl5000
 	.calc_rssi = iwl5000_calc_rssi,
 };
 
-static struct iwl_lib_ops iwl5000_lib = {
+struct iwl_lib_ops iwl5000_lib = {
 	.set_hw_params = iwl5000_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,
 	.txq_agg_enable = iwl5000_txq_agg_enable,
 	.txq_agg_disable = iwl5000_txq_agg_disable,
+	.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+	.txq_free_tfd = iwl_hw_txq_free_tfd,
+	.txq_init = iwl_hw_tx_queue_init,
 	.rx_handler_setup = iwl5000_rx_handler_setup,
 	.setup_deferred_work = iwl5000_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
@@ -1517,13 +1529,13 @@ static struct iwl_lib_ops iwl5000_lib =
 	},
 };
 
-static struct iwl_ops iwl5000_ops = {
+struct iwl_ops iwl5000_ops = {
 	.lib = &iwl5000_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
 };
 
-static struct iwl_mod_params iwl50_mod_params = {
+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,
@@ -1543,6 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_ABC,
+	.valid_rx_ant = ANT_ABC,
+	.need_pll_cfg = true,
 };
 
 struct iwl_cfg iwl5100_bg_cfg = {
@@ -1556,6 +1571,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_B,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = true,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
@@ -1569,6 +1587,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_B,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = true,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
@@ -1582,6 +1603,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_B,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = true,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
@@ -1595,6 +1619,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_ABC,
+	.valid_rx_ant = ANT_ABC,
+	.need_pll_cfg = true,
 };
 
 struct iwl_cfg iwl5150_agn_cfg = {
@@ -1608,6 +1635,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_A,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = true,
 };
 
 /*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,10 +68,16 @@
 #ifndef __iwl_5000_hw_h__
 #define __iwl_5000_hw_h__
 
+#define IWL50_RTC_INST_LOWER_BOUND		(0x000000)
 #define IWL50_RTC_INST_UPPER_BOUND		(0x020000)
+
+#define IWL50_RTC_DATA_LOWER_BOUND		(0x800000)
 #define IWL50_RTC_DATA_UPPER_BOUND		(0x80C000)
-#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+
+#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
+				IWL50_RTC_INST_LOWER_BOUND)
+#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
+				IWL50_RTC_DATA_LOWER_BOUND)
 
 /* EEPROM */
 #define IWL_5000_EEPROM_IMG_SIZE			2048
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-05-03 16:48:33.000000000 -0400
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-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-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL6000_UCODE_API_MAX 2
+#define IWL6050_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL6000_UCODE_API_MIN 1
+#define IWL6050_UCODE_API_MIN 1
+
+#define IWL6000_FW_PRE "/*(DEBLOBBED)*/"
+#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE /*(DEBLOBBED)*/
+#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+
+#define IWL6050_FW_PRE "/*(DEBLOBBED)*/"
+#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE /*(DEBLOBBED)*/
+#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+
+static struct iwl_hcmd_utils_ops iwl6000_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 = {
+	.lib = &iwl5000_lib,
+	.hcmd = &iwl5000_hcmd,
+	.utils = &iwl6000_hcmd_utils,
+};
+
+struct iwl_cfg iwl6000_2ag_cfg = {
+	.name = "6000 Series 2x2 AG",
+	.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,
+	.ops = &iwl6000_ops,
+	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_BC,
+	.valid_rx_ant = ANT_BC,
+	.need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6000_2agn_cfg = {
+	.name = "6000 Series 2x2 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 = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6050_2agn_cfg = {
+	.name = "6050 Series 2x2 AGN",
+	.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|IWL_SKU_N,
+	.ops = &iwl6000_ops,
+	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_AB,
+	.need_pll_cfg = false,
+};
+
+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 = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_ABC,
+	.valid_rx_ant = ANT_ABC,
+	.need_pll_cfg = false,
+};
+
+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,
+	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+	.ops = &iwl6000_ops,
+	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+	.mod_params = &iwl50_mod_params,
+	.valid_tx_ant = ANT_ABC,
+	.valid_rx_ant = ANT_ABC,
+	.need_pll_cfg = false,
+};
+
+/*(DEBLOBBED)*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 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.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+/*
+ * Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
+ * Use iwl-5000-commands.h for uCode API definitions.
+ */
+
+#ifndef __iwl_6000_hw_h__
+#define __iwl_6000_hw_h__
+
+#define IWL60_RTC_INST_LOWER_BOUND		(0x000000)
+#define IWL60_RTC_INST_UPPER_BOUND		(0x040000)
+#define IWL60_RTC_DATA_LOWER_BOUND		(0x800000)
+#define IWL60_RTC_DATA_UPPER_BOUND		(0x814000)
+#define IWL60_RTC_INST_SIZE \
+	(IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
+#define IWL60_RTC_DATA_SIZE \
+	(IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
+
+#endif /* __iwl_6000_hw_h__ */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 18:04:37.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 16:48:26.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -44,6 +44,8 @@
 
 #include <asm/div64.h>
 
+#define DRV_NAME        "iwlagn"
+
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
@@ -61,9 +63,7 @@
 
 /*
  * module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
  */
-
 #define DRV_DESCRIPTION	"Intel(R) Wireless WiFi Link AGN driver for Linux"
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -72,7 +72,7 @@
 #define VD
 #endif
 
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
 #define VS "s"
 #else
 #define VS
@@ -94,66 +94,6 @@ MODULE_ALIAS("iwl4965");
 
 /**************************************************************/
 
-
-
-static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
-{
-	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
-	if (hw_decrypt)
-		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
-	else
-		rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
-}
-
-/**
- * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl_full_rxon_required(struct iwl_priv *priv)
-{
-
-	/* These items are only settable from the full RXON command */
-	if (!(iwl_is_associated(priv)) ||
-	    compare_ether_addr(priv->staging_rxon.bssid_addr,
-			       priv->active_rxon.bssid_addr) ||
-	    compare_ether_addr(priv->staging_rxon.node_addr,
-			       priv->active_rxon.node_addr) ||
-	    compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
-			       priv->active_rxon.wlap_bssid_addr) ||
-	    (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
-	    (priv->staging_rxon.channel != priv->active_rxon.channel) ||
-	    (priv->staging_rxon.air_propagation !=
-	     priv->active_rxon.air_propagation) ||
-	    (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
-	     priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
-	    (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
-	     priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
-	    (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
-		return 1;
-
-	/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
-	 * be updated with the RXON_ASSOC command -- however only some
-	 * flag transitions are allowed using RXON_ASSOC */
-
-	/* Check if we are not switching bands */
-	if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
-	    (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
-		return 1;
-
-	/* Check if we are switching association toggle */
-	if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
-		(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
-		return 1;
-
-	return 0;
-}
-
 /**
  * iwl_commit_rxon - commit staging_rxon to hardware
  *
@@ -179,9 +119,9 @@ static int iwl_commit_rxon(struct iwl_pr
 	 * 5000, but will not damage 4965 */
 	priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
 
-	ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon);
+	ret = iwl_check_rxon_cmd(priv);
 	if (ret) {
-		IWL_ERROR("Invalid RXON configuration.  Not committing.\n");
+		IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
 		return -EINVAL;
 	}
 
@@ -191,7 +131,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	if (!iwl_full_rxon_required(priv)) {
 		ret = iwl_send_rxon_assoc(priv);
 		if (ret) {
-			IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
+			IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
 			return ret;
 		}
 
@@ -207,7 +147,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	 * we must clear the associated from the active configuration
 	 * before we apply the new config */
 	if (iwl_is_associated(priv) && new_assoc) {
-		IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
+		IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
 		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -218,12 +158,12 @@ static int iwl_commit_rxon(struct iwl_pr
 		 * active_rxon back to what it was previously */
 		if (ret) {
 			active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
-			IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret);
+			IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
 			return ret;
 		}
 	}
 
-	IWL_DEBUG_INFO("Sending RXON\n"
+	IWL_DEBUG_INFO(priv, "Sending RXON\n"
 		       "* with%s RXON_FILTER_ASSOC_MSK\n"
 		       "* channel = %d\n"
 		       "* bssid = %pM\n",
@@ -242,7 +182,7 @@ static int iwl_commit_rxon(struct iwl_pr
 		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
 			      sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
 		if (ret) {
-			IWL_ERROR("Error setting new RXON (%d)\n", ret);
+			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
 			return ret;
 		}
 		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -256,7 +196,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	/* Add the broadcast address so we can send broadcast frames */
 	if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
 						IWL_INVALID_STATION) {
-		IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
 		return -EIO;
 	}
 
@@ -267,13 +207,15 @@ static int iwl_commit_rxon(struct iwl_pr
 			ret = iwl_rxon_add_station(priv,
 					   priv->active_rxon.bssid_addr, 1);
 			if (ret == IWL_INVALID_STATION) {
-				IWL_ERROR("Error adding AP address for TX.\n");
+				IWL_ERR(priv,
+					"Error adding AP address for TX.\n");
 				return -EIO;
 			}
 			priv->assoc_station_added = 1;
 			if (priv->default_wep_key &&
 			    iwl_send_static_wepkey_cmd(priv, 0))
-				IWL_ERROR("Could not send WEP static key.\n");
+				IWL_ERR(priv,
+					"Could not send WEP static key.\n");
 		}
 
 		/* Apply the new configuration
@@ -282,7 +224,7 @@ static int iwl_commit_rxon(struct iwl_pr
 		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
 			      sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
 		if (ret) {
-			IWL_ERROR("Error setting new RXON (%d)\n", ret);
+			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
 			return ret;
 		}
 		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -294,7 +236,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	 * send a new TXPOWER command or we won't be able to Tx any frames */
 	ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
 	if (ret) {
-		IWL_ERROR("Error sending TX power (%d)\n", ret);
+		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
 		return ret;
 	}
 
@@ -308,25 +250,11 @@ void iwl_update_chain_flags(struct iwl_p
 	iwl_commit_rxon(priv);
 }
 
-static int iwl_send_bt_config(struct iwl_priv *priv)
-{
-	struct iwl_bt_cmd bt_cmd = {
-		.flags = 3,
-		.lead_time = 0xAA,
-		.max_kill = 1,
-		.kill_ack_mask = 0,
-		.kill_cts_mask = 0,
-	};
-
-	return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-				sizeof(struct iwl_bt_cmd), &bt_cmd);
-}
-
 static void iwl_clear_free_frames(struct iwl_priv *priv)
 {
 	struct list_head *element;
 
-	IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
 		       priv->frames_count);
 
 	while (!list_empty(&priv->free_frames)) {
@@ -337,7 +265,7 @@ static void iwl_clear_free_frames(struct
 	}
 
 	if (priv->frames_count) {
-		IWL_WARNING("%d frames still in use.  Did we lose one?\n",
+		IWL_WARN(priv, "%d frames still in use.  Did we lose one?\n",
 			    priv->frames_count);
 		priv->frames_count = 0;
 	}
@@ -350,7 +278,7 @@ static struct iwl_frame *iwl_get_free_fr
 	if (list_empty(&priv->free_frames)) {
 		frame = kzalloc(sizeof(*frame), GFP_KERNEL);
 		if (!frame) {
-			IWL_ERROR("Could not allocate frame!\n");
+			IWL_ERR(priv, "Could not allocate frame!\n");
 			return NULL;
 		}
 
@@ -386,31 +314,6 @@ static unsigned int iwl_fill_beacon_fram
 	return priv->ibss_beacon->len;
 }
 
-static u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
-{
-	int i;
-	int rate_mask;
-
-	/* Set rate mask*/
-	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
-		rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
-	else
-		rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
-	/* Find lowest valid rate */
-	for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
-					i = iwl_rates[i].next_ieee) {
-		if (rate_mask & (1 << i))
-			return iwl_rates[i].plcp;
-	}
-
-	/* No valid rate was found. Assign the lowest one */
-	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
-		return IWL_RATE_1M_PLCP;
-	else
-		return IWL_RATE_6M_PLCP;
-}
-
 static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
 				       struct iwl_frame *frame, u8 rate)
 {
@@ -452,7 +355,7 @@ static int iwl_send_beacon_cmd(struct iw
 	frame = iwl_get_free_frame(priv);
 
 	if (!frame) {
-		IWL_ERROR("Could not obtain free frame buffer for beacon "
+		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
 			  "command.\n");
 		return -ENOMEM;
 	}
@@ -469,6 +372,159 @@ static int iwl_send_beacon_cmd(struct iw
 	return rc;
 }
 
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+	dma_addr_t addr = get_unaligned_le32(&tb->lo);
+	if (sizeof(dma_addr_t) > sizeof(u32))
+		addr |=
+		((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+	return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+	return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+				  dma_addr_t addr, u16 len)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+	u16 hi_n_len = len << 4;
+
+	put_unaligned_le32(addr, &tb->lo);
+	if (sizeof(dma_addr_t) > sizeof(u32))
+		hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+	tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+	tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+	return tfd->num_tbs & 0x1f;
+}
+
+/**
+ * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+	struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
+	struct iwl_tfd *tfd;
+	struct pci_dev *dev = priv->pci_dev;
+	int index = txq->q.read_ptr;
+	int i;
+	int num_tbs;
+
+	tfd = &tfd_tmp[index];
+
+	/* Sanity check on number of chunks */
+	num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+	if (num_tbs >= IWL_NUM_OF_TBS) {
+		IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
+		/* @todo issue fatal error, it is quite serious situation */
+		return;
+	}
+
+	/* Unmap tx_cmd */
+	if (num_tbs)
+		pci_unmap_single(dev,
+				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+				pci_unmap_len(&txq->cmd[index]->meta, len),
+				PCI_DMA_BIDIRECTIONAL);
+
+	/* Unmap chunks, if any. */
+	for (i = 1; i < num_tbs; i++) {
+		pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+				iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
+
+		if (txq->txb) {
+			dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
+			txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
+		}
+	}
+}
+
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+				 struct iwl_tx_queue *txq,
+				 dma_addr_t addr, u16 len,
+				 u8 reset, u8 pad)
+{
+	struct iwl_queue *q;
+	struct iwl_tfd *tfd, *tfd_tmp;
+	u32 num_tbs;
+
+	q = &txq->q;
+	tfd_tmp = (struct iwl_tfd *)txq->tfds;
+	tfd = &tfd_tmp[q->write_ptr];
+
+	if (reset)
+		memset(tfd, 0, sizeof(*tfd));
+
+	num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+	/* Each TFD can point to a maximum 20 Tx buffers */
+	if (num_tbs >= IWL_NUM_OF_TBS) {
+		IWL_ERR(priv, "Error can not send more than %d chunks\n",
+			  IWL_NUM_OF_TBS);
+		return -EINVAL;
+	}
+
+	BUG_ON(addr & ~DMA_BIT_MASK(36));
+	if (unlikely(addr & ~IWL_TX_DMA_MASK))
+		IWL_ERR(priv, "Unaligned address = %llx\n",
+			  (unsigned long long)addr);
+
+	iwl_tfd_set_tb(tfd, num_tbs, addr, len);
+
+	return 0;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+			 struct iwl_tx_queue *txq)
+{
+	int ret;
+	unsigned long flags;
+	int txq_id = txq->q.id;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	ret = iwl_grab_nic_access(priv);
+	if (ret) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return ret;
+	}
+
+	/* Circular buffer (TFD queue in DRAM) physical base address */
+	iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+			     txq->q.dma_addr >> 8);
+
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+
 /******************************************************************************
  *
  * Misc. internal state and helper functions
@@ -482,7 +538,7 @@ static void iwl_ht_conf(struct iwl_priv
 	struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
 	struct ieee80211_sta *sta;
 
-	IWL_DEBUG_MAC80211("enter: \n");
+	IWL_DEBUG_MAC80211(priv, "enter: \n");
 
 	if (!iwl_conf->is_ht)
 		return;
@@ -520,9 +576,9 @@ static void iwl_ht_conf(struct iwl_priv
 	 */
 
 	iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
-	if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS)
+	if (conf_is_ht40_minus(&priv->hw->conf))
 		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-	else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS)
+	else if (conf_is_ht40_plus(&priv->hw->conf))
 		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
 
 	/* If no above or below channel supplied disable FAT channel */
@@ -542,39 +598,7 @@ static void iwl_ht_conf(struct iwl_priv
 
 	rcu_read_unlock();
 
-	IWL_DEBUG_MAC80211("leave\n");
-}
-
-/*
- * QoS  support
-*/
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
-{
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	priv->qos_data.def_qos_parm.qos_flags = 0;
-
-	if (priv->qos_data.qos_cap.q_AP.queue_request &&
-	    !priv->qos_data.qos_cap.q_AP.txop_request)
-		priv->qos_data.def_qos_parm.qos_flags |=
-			QOS_PARAM_FLG_TXOP_TYPE_MSK;
-	if (priv->qos_data.qos_active)
-		priv->qos_data.def_qos_parm.qos_flags |=
-			QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
-	if (priv->current_ht_config.is_ht)
-		priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
-	if (force || iwl_is_associated(priv)) {
-		IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
-				priv->qos_data.qos_active,
-				priv->qos_data.def_qos_parm.qos_flags);
-
-		iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
-				       sizeof(struct iwl_qosparam_cmd),
-				       &priv->qos_data.def_qos_parm, NULL);
-	}
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 #define MAX_UCODE_BEACON_INTERVAL	4096
@@ -588,6 +612,9 @@ static u16 iwl_adjust_beacon_interval(u1
 					/ MAX_UCODE_BEACON_INTERVAL;
 	new_val = beacon_val / beacon_factor;
 
+	if (!new_val)
+		new_val = MAX_UCODE_BEACON_INTERVAL;
+
 	return new_val;
 }
 
@@ -624,117 +651,16 @@ static void iwl_setup_rxon_timing(struct
 	priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
+	IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
 			le16_to_cpu(priv->rxon_timing.beacon_interval),
 			le32_to_cpu(priv->rxon_timing.beacon_init_val),
 			le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static void iwl_set_flags_for_band(struct iwl_priv *priv,
-				   enum ieee80211_band band)
-{
-	if (band == IEEE80211_BAND_5GHZ) {
-		priv->staging_rxon.flags &=
-		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
-		      | RXON_FLG_CCK_MSK);
-		priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
-	} else {
-		/* Copied from iwl_post_associate() */
-		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
-			priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
-		else
-			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
-		if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
-			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
-		priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
-		priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
-		priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
-	}
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
-{
-	const struct iwl_channel_info *ch_info;
-
-	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
-	switch (mode) {
-	case NL80211_IFTYPE_AP:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
-		break;
-
-	case NL80211_IFTYPE_STATION:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
-		priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-
-	case NL80211_IFTYPE_ADHOC:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
-		priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
-		priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
-						  RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-
-	case NL80211_IFTYPE_MONITOR:
-		priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
-		priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
-		    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
-		break;
-	default:
-		IWL_ERROR("Unsupported interface type %d\n", mode);
-		break;
-	}
-
-#if 0
-	/* TODO:  Figure out when short_preamble would be set and cache from
-	 * that */
-	if (!hw_to_local(priv->hw)->short_preamble)
-		priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
-	else
-		priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
-	ch_info = iwl_get_channel_info(priv, priv->band,
-				       le16_to_cpu(priv->active_rxon.channel));
-
-	if (!ch_info)
-		ch_info = &priv->channel_info[0];
-
-	/*
-	 * in some case A channels are all non IBSS
-	 * in this case force B/G channel
-	 */
-	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
-	    !(is_channel_ibss(ch_info)))
-		ch_info = &priv->channel_info[0];
-
-	priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
-	priv->band = ch_info->band;
-
-	iwl_set_flags_for_band(priv, priv->band);
-
-	priv->staging_rxon.ofdm_basic_rates =
-	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-	priv->staging_rxon.cck_basic_rates =
-	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
-	priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
-					RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
-	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-	memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
-	priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
-	priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
-	iwl_set_rxon_chain(priv);
-}
-
 static int iwl_set_mode(struct iwl_priv *priv, int mode)
 {
 	iwl_connection_init_rx_config(priv, mode);
+	iwl_set_rxon_chain(priv);
 	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
 
 	iwl_clear_stations_table(priv);
@@ -743,66 +669,11 @@ static int iwl_set_mode(struct iwl_priv
 	if (!iwl_is_ready_rf(priv))
 		return -EAGAIN;
 
-	cancel_delayed_work(&priv->scan_check);
-	if (iwl_scan_cancel_timeout(priv, 100)) {
-		IWL_WARNING("Aborted scan still in progress after 100ms\n");
-		IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
-		return -EAGAIN;
-	}
-
 	iwl_commit_rxon(priv);
 
 	return 0;
 }
 
-static void iwl_set_rate(struct iwl_priv *priv)
-{
-	const struct ieee80211_supported_band *hw = NULL;
-	struct ieee80211_rate *rate;
-	int i;
-
-	hw = iwl_get_hw_mode(priv, priv->band);
-	if (!hw) {
-		IWL_ERROR("Failed to set rate: unable to get hw mode\n");
-		return;
-	}
-
-	priv->active_rate = 0;
-	priv->active_rate_basic = 0;
-
-	for (i = 0; i < hw->n_bitrates; i++) {
-		rate = &(hw->bitrates[i]);
-		if (rate->hw_value < IWL_RATE_COUNT)
-			priv->active_rate |= (1 << rate->hw_value);
-	}
-
-	IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
-		       priv->active_rate, priv->active_rate_basic);
-
-	/*
-	 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
-	 * otherwise set it to the default of all CCK rates and 6, 12, 24 for
-	 * OFDM
-	 */
-	if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
-		priv->staging_rxon.cck_basic_rates =
-		    ((priv->active_rate_basic &
-		      IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
-	else
-		priv->staging_rxon.cck_basic_rates =
-		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
-	if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
-		priv->staging_rxon.ofdm_basic_rates =
-		    ((priv->active_rate_basic &
-		      (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
-		      IWL_FIRST_OFDM_RATE) & 0xFF;
-	else
-		priv->staging_rxon.ofdm_basic_rates =
-		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-
 /******************************************************************************
  *
  * Generic RX handler implementations
@@ -817,19 +688,19 @@ static void iwl_rx_reply_alive(struct iw
 
 	palive = &pkt->u.alive_frame;
 
-	IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
 		       "0x%01X 0x%01X\n",
 		       palive->is_valid, palive->ver_type,
 		       palive->ver_subtype);
 
 	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
-		IWL_DEBUG_INFO("Initialization Alive received.\n");
+		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
 		memcpy(&priv->card_alive_init,
 		       &pkt->u.alive_frame,
 		       sizeof(struct iwl_init_alive_resp));
 		pwork = &priv->init_alive_start;
 	} else {
-		IWL_DEBUG_INFO("Runtime Alive received.\n");
+		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 		memcpy(&priv->card_alive, &pkt->u.alive_frame,
 		       sizeof(struct iwl_alive_resp));
 		pwork = &priv->alive_start;
@@ -841,55 +712,7 @@ static void iwl_rx_reply_alive(struct iw
 		queue_delayed_work(priv->workqueue, pwork,
 				   msecs_to_jiffies(5));
 	else
-		IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static 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;
-
-	IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
-		"seq 0x%04X ser 0x%08X\n",
-		le32_to_cpu(pkt->u.err_resp.error_type),
-		get_cmd_string(pkt->u.err_resp.cmd_id),
-		pkt->u.err_resp.cmd_id,
-		le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
-		le32_to_cpu(pkt->u.err_resp.error_info));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static 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_rxon_cmd *rxon = (void *)&priv->active_rxon;
-	struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
-	IWL_DEBUG_11H("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;
-}
-
-static void iwl_rx_pm_sleep_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_sleep_notification *sleep = &(pkt->u.sleep_notif);
-	IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
-		     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
-#endif
-}
-
-static 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;
-	IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
-			"notification for %s:\n",
-			le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-	iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+		IWL_WARN(priv, "uCode did not respond OK.\n");
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -902,7 +725,7 @@ static void iwl_bg_beacon_update(struct
 	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
 
 	if (!beacon) {
-		IWL_ERROR("update beacon failed\n");
+		IWL_ERR(priv, "update beacon failed\n");
 		return;
 	}
 
@@ -950,7 +773,7 @@ static void iwl_rx_beacon_notif(struct i
 		(struct iwl4965_beacon_notif *)pkt->u.raw;
 	u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
 
-	IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
 		"tsf %d %d rate %d\n",
 		le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
 		beacon->beacon_notify_hdr.failure_frame,
@@ -973,7 +796,7 @@ static void iwl_rx_card_state_notif(stru
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
 
-	IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
 			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
 			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");
 
@@ -1046,11 +869,7 @@ int iwl_set_pwr_src(struct iwl_priv *pri
 		goto err;
 
 	if (src == IWL_PWR_SRC_VAUX) {
-		u32 val;
-		ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
-					    &val);
-
-		if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
+		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
 			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
 					       ~APMG_PS_CTRL_MSK_PWR_SRC);
@@ -1135,7 +954,7 @@ void iwl_rx_handle(struct iwl_priv *priv
 
 	/* Rx interrupt, but nothing sent from uCode */
 	if (i == r)
-		IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i);
+		IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
 
 	if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
 		fill_rx = 1;
@@ -1150,11 +969,9 @@ void iwl_rx_handle(struct iwl_priv *priv
 
 		rxq->queue[i] = NULL;
 
-		dma_sync_single_range_for_cpu(
-				&priv->pci_dev->dev, rxb->real_dma_addr,
-				rxb->aligned_dma_addr - rxb->real_dma_addr,
-				priv->hw_params.rx_buf_size,
-				PCI_DMA_FROMDEVICE);
+		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;
 
 		/* Reclaim a command buffer only if this packet is a response
@@ -1175,12 +992,12 @@ void iwl_rx_handle(struct iwl_priv *priv
 		 *   handle those that need handling via function in
 		 *   rx_handlers table.  See iwl_setup_rx_handlers() */
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
-			IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r,
+			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);
 		} else {
 			/* No handling needed */
-			IWL_DEBUG(IWL_DL_RX,
+			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);
@@ -1193,7 +1010,7 @@ void iwl_rx_handle(struct iwl_priv *priv
 			if (rxb && rxb->skb)
 				iwl_tx_cmd_complete(priv, rxb);
 			else
-				IWL_WARNING("Claim null rxb?\n");
+				IWL_WARN(priv, "Claim null rxb?\n");
 		}
 
 		/* For now we just don't re-use anything.  We can tweak this
@@ -1205,9 +1022,6 @@ void iwl_rx_handle(struct iwl_priv *priv
 			rxb->skb = NULL;
 		}
 
-		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
-				 priv->hw_params.rx_buf_size + 256,
-				 PCI_DMA_FROMDEVICE);
 		spin_lock_irqsave(&rxq->lock, flags);
 		list_add_tail(&rxb->list, &priv->rxq.rx_used);
 		spin_unlock_irqrestore(&rxq->lock, flags);
@@ -1229,27 +1043,6 @@ void iwl_rx_handle(struct iwl_priv *priv
 	iwl_rx_queue_restock(priv);
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
-{
-	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
-	IWL_DEBUG_RADIO("RX CONFIG:\n");
-	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
-	IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
-	IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
-	IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
-			le32_to_cpu(rxon->filter_flags));
-	IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
-	IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
-			rxon->ofdm_basic_rates);
-	IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
-	IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
-	IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
-	IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
 /* call this function to flush any scheduled tasklet */
 static inline void iwl_synchronize_irq(struct iwl_priv *priv)
 {
@@ -1258,45 +1051,6 @@ static inline void iwl_synchronize_irq(s
 	tasklet_kill(&priv->irq_tasklet);
 }
 
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl_irq_handle_error(struct iwl_priv *priv)
-{
-	/* Set the FW error flag -- cleared on iwl_down */
-	set_bit(STATUS_FW_ERROR, &priv->status);
-
-	/* Cancel currently queued command. */
-	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & IWL_DL_FW_ERRORS) {
-		iwl_dump_nic_error_log(priv);
-		iwl_dump_nic_event_log(priv);
-		iwl_print_rx_config_cmd(priv);
-	}
-#endif
-
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	/* Keep the restart process from trying to send host
-	 * commands by clearing the INIT status bit */
-	clear_bit(STATUS_READY, &priv->status);
-
-	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG(IWL_DL_FW_ERRORS,
-			  "Restarting adapter due to uCode error.\n");
-
-		if (iwl_is_associated(priv)) {
-			memcpy(&priv->recovery_rxon, &priv->active_rxon,
-			       sizeof(priv->recovery_rxon));
-			priv->error_recovering = 1;
-		}
-		if (priv->cfg->mod_params->restart_fw)
-			queue_work(priv->workqueue, &priv->restart);
-	}
-}
-
 static void iwl_error_recovery(struct iwl_priv *priv)
 {
 	unsigned long flags;
@@ -1341,7 +1095,7 @@ static void iwl_irq_tasklet(struct iwl_p
 	if (priv->debug_level & IWL_DL_ISR) {
 		/* just for debug */
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
-		IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
 			      inta, inta_mask, inta_fh);
 	}
 #endif
@@ -1357,7 +1111,7 @@ static void iwl_irq_tasklet(struct iwl_p
 
 	/* Now service all interrupt bits discovered above. */
 	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERROR("Microcode HW error detected.  Restarting.\n");
+		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
 
 		/* Tell the device to stop sending interrupts */
 		iwl_disable_interrupts(priv);
@@ -1375,12 +1129,12 @@ static void iwl_irq_tasklet(struct iwl_p
 	if (priv->debug_level & (IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD)
-			IWL_DEBUG_ISR("Scheduler finished to transmit "
+			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
 				      "the frame/frames.\n");
 
 		/* Alive notification via Rx interrupt will do the real work */
 		if (inta & CSR_INT_BIT_ALIVE)
-			IWL_DEBUG_ISR("Alive interrupt\n");
+			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
 	}
 #endif
 	/* Safely ignore these bits for debug checks below */
@@ -1393,17 +1147,20 @@ static void iwl_irq_tasklet(struct iwl_p
 				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
 			hw_rf_kill = 1;
 
-		IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n",
+		IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
 				hw_rf_kill ? "disable radio" : "enable radio");
 
 		/* driver only loads ucode once setting the interface up.
-		 * the driver as well won't allow loading if RFKILL is set
-		 * therefore no need to restart the driver from this handler
+		 * the driver allows loading the ucode even if the radio
+		 * is killed. Hence update the killswitch state here. The
+		 * rfkill handler will care about restarting if needed.
 		 */
-		if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
-			clear_bit(STATUS_RF_KILL_HW, &priv->status);
-			if (priv->is_open && !iwl_is_rfkill(priv))
-				queue_work(priv->workqueue, &priv->up);
+		if (!test_bit(STATUS_ALIVE, &priv->status)) {
+			if (hw_rf_kill)
+				set_bit(STATUS_RF_KILL_HW, &priv->status);
+			else
+				clear_bit(STATUS_RF_KILL_HW, &priv->status);
+			queue_work(priv->workqueue, &priv->rf_kill);
 		}
 
 		handled |= CSR_INT_BIT_RF_KILL;
@@ -1411,21 +1168,21 @@ static void iwl_irq_tasklet(struct iwl_p
 
 	/* Chip got too hot and stopped itself */
 	if (inta & CSR_INT_BIT_CT_KILL) {
-		IWL_ERROR("Microcode CT kill error detected.\n");
+		IWL_ERR(priv, "Microcode CT kill error detected.\n");
 		handled |= CSR_INT_BIT_CT_KILL;
 	}
 
 	/* Error detected by uCode */
 	if (inta & CSR_INT_BIT_SW_ERR) {
-		IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
-			  inta);
+		IWL_ERR(priv, "Microcode SW error detected. "
+			" Restarting 0x%X.\n", inta);
 		iwl_irq_handle_error(priv);
 		handled |= CSR_INT_BIT_SW_ERR;
 	}
 
 	/* uCode wakes up after power-down sleep */
 	if (inta & CSR_INT_BIT_WAKEUP) {
-		IWL_DEBUG_ISR("Wakeup interrupt\n");
+		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]);
@@ -1446,7 +1203,7 @@ static void iwl_irq_tasklet(struct iwl_p
 	}
 
 	if (inta & CSR_INT_BIT_FH_TX) {
-		IWL_DEBUG_ISR("Tx interrupt\n");
+		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
 		handled |= CSR_INT_BIT_FH_TX;
 		/* FH finished to write, send event */
 		priv->ucode_write_complete = 1;
@@ -1454,12 +1211,12 @@ static void iwl_irq_tasklet(struct iwl_p
 	}
 
 	if (inta & ~handled)
-		IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+		IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
 
 	if (inta & ~CSR_INI_SET_MASK) {
-		IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+		IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
 			 inta & ~CSR_INI_SET_MASK);
-		IWL_WARNING("   with FH_INT = 0x%08x\n", inta_fh);
+		IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
 	}
 
 	/* Re-enable all interrupts */
@@ -1472,71 +1229,13 @@ static void iwl_irq_tasklet(struct iwl_p
 		inta = iwl_read32(priv, CSR_INT);
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-		IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+		IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
 			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
 	}
 #endif
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static irqreturn_t iwl_isr(int irq, void *data)
-{
-	struct iwl_priv *priv = data;
-	u32 inta, inta_mask;
-	u32 inta_fh;
-	if (!priv)
-		return IRQ_NONE;
-
-	spin_lock(&priv->lock);
-
-	/* Disable (but don't clear!) interrupts here to avoid
-	 *    back-to-back ISRs and sporadic interrupts from our NIC.
-	 * If we have something to service, the tasklet will re-enable ints.
-	 * If we *don't* have something, we'll re-enable before leaving here. */
-	inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
-	iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
-	/* Discover which interrupts are active/pending */
-	inta = iwl_read32(priv, CSR_INT);
-	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-
-	/* Ignore interrupt if there's nothing in NIC to service.
-	 * This may be due to IRQ shared with another device,
-	 * or due to sporadic interrupts thrown from our NIC. */
-	if (!inta && !inta_fh) {
-		IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
-		goto none;
-	}
-
-	if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
-		/* Hardware disappeared. It might have already raised
-		 * an interrupt */
-		IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
-		goto unplugged;
-	}
-
-	IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
-		      inta, inta_mask, inta_fh);
-
-	inta &= ~CSR_INT_BIT_SCD;
-
-	/* iwl_irq_tasklet() will service interrupts and re-enable them */
-	if (likely(inta || inta_fh))
-		tasklet_schedule(&priv->irq_tasklet);
-
- unplugged:
-	spin_unlock(&priv->lock);
-	return IRQ_HANDLED;
-
- none:
-	/* re-enable interrupts here since we don't have anything to service. */
-	/* only Re-enable if diabled by irq */
-	if (test_bit(STATUS_INT_ENABLED, &priv->status))
-		iwl_enable_interrupts(priv);
-	spin_unlock(&priv->lock);
-	return IRQ_NONE;
-}
-
 /******************************************************************************
  *
  * uCode download functions
@@ -1584,7 +1283,7 @@ static int iwl_read_ucode(struct iwl_pri
 		sprintf(buf, "/*(DEBLOBBED)*/");
 		ret = reject_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
 		if (ret < 0) {
-			IWL_ERROR("%s firmware file req failed: Reason %d\n",
+			IWL_ERR(priv, "%s firmware file req failed: %d\n",
 				  buf, ret);
 			if (ret == -ENOENT)
 				continue;
@@ -1592,9 +1291,12 @@ static int iwl_read_ucode(struct iwl_pri
 				goto error;
 		} else {
 			if (index < api_max)
-				IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+				IWL_ERR(priv, "Loaded firmware %s, "
+					"which is deprecated. "
+					"Please use API v%u instead.\n",
 					  buf, api_max);
-			IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+
+			IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
 				       buf, ucode_raw->size);
 			break;
 		}
@@ -1605,7 +1307,7 @@ static int iwl_read_ucode(struct iwl_pri
 
 	/* Make sure that we got at least our header! */
 	if (ucode_raw->size < sizeof(*ucode)) {
-		IWL_ERROR("File size way too small!\n");
+		IWL_ERR(priv, "File size way too small!\n");
 		ret = -EINVAL;
 		goto err_release;
 	}
@@ -1623,10 +1325,10 @@ static int iwl_read_ucode(struct iwl_pri
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
-	 * on the API version read from firware header from here on forward */
+	 * on the API version read from firmware header from here on forward */
 
 	if (api_ver < api_min || api_ver > api_max) {
-		IWL_ERROR("Driver unable to support your firmware API. "
+		IWL_ERR(priv, "Driver unable to support your firmware API. "
 			  "Driver supports v%u, firmware is v%u.\n",
 			  api_max, api_ver);
 		priv->ucode_ver = 0;
@@ -1634,28 +1336,28 @@ static int iwl_read_ucode(struct iwl_pri
 		goto err_release;
 	}
 	if (api_ver != api_max)
-		IWL_ERROR("Firmware has old API version. Expected v%u, "
+		IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
 			  "got v%u. New firmware can be obtained "
 			  "from http://www.intellinuxwireless.org.\n",
 			  api_max, api_ver);
 
-	printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
-		       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_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+	       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("f/w package hdr ucode version raw = 0x%x\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
 		       priv->ucode_ver);
-	IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
 		       inst_size);
-	IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
 		       data_size);
-	IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
 		       init_size);
-	IWL_DEBUG_INFO("f/w package hdr init data size = %u\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
 		       init_data_size);
-	IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n",
+	IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
 		       boot_size);
 
 	/* Verify size of file vs. image size info in file's header */
@@ -1663,7 +1365,7 @@ static int iwl_read_ucode(struct iwl_pri
 		inst_size + data_size + init_size +
 		init_data_size + boot_size) {
 
-		IWL_DEBUG_INFO("uCode file size %d too small\n",
+		IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
 			       (int)ucode_raw->size);
 		ret = -EINVAL;
 		goto err_release;
@@ -1671,36 +1373,33 @@ static int iwl_read_ucode(struct iwl_pri
 
 	/* Verify that uCode images will fit in card's SRAM */
 	if (inst_size > priv->hw_params.max_inst_size) {
-		IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+		IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
 			       inst_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 
 	if (data_size > priv->hw_params.max_data_size) {
-		IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+		IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
 				data_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 	if (init_size > priv->hw_params.max_inst_size) {
-		IWL_DEBUG_INFO
-		    ("uCode init instr len %d too large to fit in\n",
-		      init_size);
+		IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
+			init_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 	if (init_data_size > priv->hw_params.max_data_size) {
-		IWL_DEBUG_INFO
-		    ("uCode init data len %d too large to fit in\n",
+		IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
 		      init_data_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
 	if (boot_size > priv->hw_params.max_bsm_size) {
-		IWL_DEBUG_INFO
-		    ("uCode boot instr len %d too large to fit in\n",
-		      boot_size);
+		IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
+			boot_size);
 		ret = -EINVAL;
 		goto err_release;
 	}
@@ -1749,16 +1448,16 @@ static int iwl_read_ucode(struct iwl_pri
 	/* Runtime instructions (first block of data in file) */
 	src = &ucode->data[0];
 	len = priv->ucode_code.len;
-	IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
 	memcpy(priv->ucode_code.v_addr, src, len);
-	IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
 		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
 	/* Runtime data (2nd block)
 	 * NOTE:  Copy into backup buffer will be done in iwl_up()  */
 	src = &ucode->data[inst_size];
 	len = priv->ucode_data.len;
-	IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
 	memcpy(priv->ucode_data.v_addr, src, len);
 	memcpy(priv->ucode_data_backup.v_addr, src, len);
 
@@ -1766,7 +1465,7 @@ static int iwl_read_ucode(struct iwl_pri
 	if (init_size) {
 		src = &ucode->data[inst_size + data_size];
 		len = priv->ucode_init.len;
-		IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
+		IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
 				len);
 		memcpy(priv->ucode_init.v_addr, src, len);
 	}
@@ -1775,7 +1474,7 @@ static int iwl_read_ucode(struct iwl_pri
 	if (init_data_size) {
 		src = &ucode->data[inst_size + data_size + init_size];
 		len = priv->ucode_init_data.len;
-		IWL_DEBUG_INFO("Copying (but not loading) init data len %Zd\n",
+		IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
 			       len);
 		memcpy(priv->ucode_init_data.v_addr, src, len);
 	}
@@ -1783,7 +1482,7 @@ static int iwl_read_ucode(struct iwl_pri
 	/* Bootstrap instructions (5th block) */
 	src = &ucode->data[inst_size + data_size + init_size + init_data_size];
 	len = priv->ucode_boot.len;
-	IWL_DEBUG_INFO("Copying (but not loading) boot instr len %Zd\n", len);
+	IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
 	memcpy(priv->ucode_boot.v_addr, src, len);
 
 	/* We have our copies now, allow OS release its copies */
@@ -1791,7 +1490,7 @@ static int iwl_read_ucode(struct iwl_pri
 	return 0;
 
  err_pci_alloc:
-	IWL_ERROR("failed to allocate pci memory\n");
+	IWL_ERR(priv, "failed to allocate pci memory\n");
 	ret = -ENOMEM;
 	iwl_dealloc_ucode_pci(priv);
 
@@ -1815,12 +1514,12 @@ static void iwl_alive_start(struct iwl_p
 {
 	int ret = 0;
 
-	IWL_DEBUG_INFO("Runtime Alive received.\n");
+	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
 	if (priv->card_alive.is_valid != UCODE_VALID_OK) {
 		/* We had an error bringing up the hardware, so take it
 		 * all the way back down so we can try again */
-		IWL_DEBUG_INFO("Alive failed.\n");
+		IWL_DEBUG_INFO(priv, "Alive failed.\n");
 		goto restart;
 	}
 
@@ -1830,15 +1529,15 @@ static void iwl_alive_start(struct iwl_p
 	if (iwl_verify_ucode(priv)) {
 		/* Runtime instruction load was bad;
 		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+		IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
 		goto restart;
 	}
 
 	iwl_clear_stations_table(priv);
 	ret = priv->cfg->ops->lib->alive_notify(priv);
 	if (ret) {
-		IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n",
-			    ret);
+		IWL_WARN(priv,
+			"Could not complete ALIVE transition [ntf]: %d\n", ret);
 		goto restart;
 	}
 
@@ -1856,13 +1555,13 @@ static void iwl_alive_start(struct iwl_p
 	if (iwl_is_associated(priv)) {
 		struct iwl_rxon_cmd *active_rxon =
 				(struct iwl_rxon_cmd *)&priv->active_rxon;
-
-		memcpy(&priv->staging_rxon, &priv->active_rxon,
-		       sizeof(priv->staging_rxon));
+		/* apply any changes in staging */
+		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	} else {
 		/* Initialize our rx_config data */
 		iwl_connection_init_rx_config(priv, priv->iw_mode);
+		iwl_set_rxon_chain(priv);
 		memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
 	}
 
@@ -1879,7 +1578,7 @@ static void iwl_alive_start(struct iwl_p
 
 	iwl_leds_register(priv);
 
-	IWL_DEBUG_INFO("ALIVE processing complete.\n");
+	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
 	set_bit(STATUS_READY, &priv->status);
 	wake_up_interruptible(&priv->wait_command_queue);
 
@@ -1913,7 +1612,7 @@ static void __iwl_down(struct iwl_priv *
 	unsigned long flags;
 	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
 	if (!exit_pending)
 		set_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -2024,12 +1723,12 @@ static int __iwl_up(struct iwl_priv *pri
 	int ret;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_WARNING("Exit pending; will not bring the NIC up\n");
+		IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
 		return -EIO;
 	}
 
 	if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
-		IWL_ERROR("ucode not available for device bringup\n");
+		IWL_ERR(priv, "ucode not available for device bringup\n");
 		return -EIO;
 	}
 
@@ -2041,7 +1740,7 @@ static int __iwl_up(struct iwl_priv *pri
 
 	if (iwl_is_rfkill(priv)) {
 		iwl_enable_interrupts(priv);
-		IWL_WARNING("Radio disabled by %s RF Kill switch\n",
+		IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
 		    test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
 		return 0;
 	}
@@ -2050,7 +1749,7 @@ static int __iwl_up(struct iwl_priv *pri
 
 	ret = iwl_hw_nic_init(priv);
 	if (ret) {
-		IWL_ERROR("Unable to init nic\n");
+		IWL_ERR(priv, "Unable to init nic\n");
 		return ret;
 	}
 
@@ -2083,7 +1782,8 @@ static int __iwl_up(struct iwl_priv *pri
 		ret = priv->cfg->ops->lib->load_ucode(priv);
 
 		if (ret) {
-			IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret);
+			IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
+				ret);
 			continue;
 		}
 
@@ -2093,7 +1793,7 @@ static int __iwl_up(struct iwl_priv *pri
 		/* start card; "initialize" will load runtime ucode */
 		iwl_nic_start(priv);
 
-		IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+		IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
 
 		return 0;
 	}
@@ -2104,7 +1804,7 @@ static int __iwl_up(struct iwl_priv *pri
 
 	/* tried to restart and config the device for as long as our
 	 * patience could withstand */
-	IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+	IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
 	return -EIO;
 }
 
@@ -2141,40 +1841,6 @@ static void iwl_bg_alive_start(struct wo
 	mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_rf_kill(struct work_struct *work)
-{
-	struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
-
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	mutex_lock(&priv->mutex);
-
-	if (!iwl_is_rfkill(priv)) {
-		IWL_DEBUG(IWL_DL_RF_KILL,
-			  "HW and/or SW RF Kill no longer active, restarting "
-			  "device\n");
-		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-			queue_work(priv->workqueue, &priv->restart);
-	} else {
-		/* make sure mac80211 stop sending Tx frame */
-		if (priv->mac80211_registered)
-			ieee80211_stop_queues(priv->hw);
-
-		if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
-			IWL_DEBUG_RF_KILL("Can not turn radio back on - "
-					  "disabled by SW switch\n");
-		else
-			IWL_WARNING("Radio Frequency Kill Switch is On:\n"
-				    "Kill switch must be turned off for "
-				    "wireless networking to work.\n");
-	}
-	mutex_unlock(&priv->mutex);
-	iwl_rfkill_set_hw_state(priv);
-}
-
 static void iwl_bg_run_time_calib_work(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2244,11 +1910,11 @@ static void iwl_post_associate(struct iw
 	unsigned long flags;
 
 	if (priv->iw_mode == NL80211_IFTYPE_AP) {
-		IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+		IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
 		return;
 	}
 
-	IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+	IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
 			priv->assoc_id, priv->active_rxon.bssid_addr);
 
 
@@ -2271,7 +1937,7 @@ static void iwl_post_associate(struct iw
 	ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
 			      sizeof(priv->rxon_timing), &priv->rxon_timing);
 	if (ret)
-		IWL_WARNING("REPLY_RXON_TIMING failed - "
+		IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
 			    "Attempting to continue.\n");
 
 	priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -2281,7 +1947,7 @@ static void iwl_post_associate(struct iw
 	iwl_set_rxon_chain(priv);
 	priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
 
-	IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+	IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
 			priv->assoc_id, priv->beacon_int);
 
 	if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -2317,7 +1983,7 @@ static void iwl_post_associate(struct iw
 		break;
 
 	default:
-		IWL_ERROR("%s Should not be called in %d mode\n",
+		IWL_ERR(priv, "%s Should not be called in %d mode\n",
 			  __func__, priv->iw_mode);
 		break;
 	}
@@ -2353,30 +2019,8 @@ static int iwl_mac_start(struct ieee8021
 {
 	struct iwl_priv *priv = hw->priv;
 	int ret;
-	u16 pci_cmd;
-
-	IWL_DEBUG_MAC80211("enter\n");
-
-	if (pci_enable_device(priv->pci_dev)) {
-		IWL_ERROR("Fail to pci_enable_device\n");
-		return -ENODEV;
-	}
-	pci_restore_state(priv->pci_dev);
-	pci_enable_msi(priv->pci_dev);
-
-	/* enable interrupts if needed: hw bug w/a */
-	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
-	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
-		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
-		pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
-	}
 
-	ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
-			  DRV_NAME, priv);
-	if (ret) {
-		IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
-		goto out_disable_msi;
-	}
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	/* we should be verifying the device is ready to be opened */
 	mutex_lock(&priv->mutex);
@@ -2388,9 +2032,9 @@ static int iwl_mac_start(struct ieee8021
 	if (!priv->ucode_code.len) {
 		ret = iwl_read_ucode(priv);
 		if (ret) {
-			IWL_ERROR("Could not read microcode: %d\n", ret);
+			IWL_ERR(priv, "Could not read microcode: %d\n", ret);
 			mutex_unlock(&priv->mutex);
-			goto out_release_irq;
+			return ret;
 		}
 	}
 
@@ -2401,12 +2045,12 @@ static int iwl_mac_start(struct ieee8021
 	iwl_rfkill_set_hw_state(priv);
 
 	if (ret)
-		goto out_release_irq;
+		return ret;
 
 	if (iwl_is_rfkill(priv))
 		goto out;
 
-	IWL_DEBUG_INFO("Start UP work done.\n");
+	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
 	if (test_bit(STATUS_IN_SUSPEND, &priv->status))
 		return 0;
@@ -2418,36 +2062,26 @@ static int iwl_mac_start(struct ieee8021
 			UCODE_READY_TIMEOUT);
 	if (!ret) {
 		if (!test_bit(STATUS_READY, &priv->status)) {
-			IWL_ERROR("START_ALIVE timeout after %dms.\n",
+			IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
 				jiffies_to_msecs(UCODE_READY_TIMEOUT));
-			ret = -ETIMEDOUT;
-			goto out_release_irq;
+			return -ETIMEDOUT;
 		}
 	}
 
 out:
 	priv->is_open = 1;
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
-
-out_release_irq:
-	free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
-	pci_disable_msi(priv->pci_dev);
-	pci_disable_device(priv->pci_dev);
-	priv->is_open = 0;
-	IWL_DEBUG_MAC80211("leave - failed\n");
-	return ret;
 }
 
 static void iwl_mac_stop(struct ieee80211_hw *hw)
 {
 	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (!priv->is_open) {
-		IWL_DEBUG_MAC80211("leave - skip\n");
+		IWL_DEBUG_MAC80211(priv, "leave - skip\n");
 		return;
 	}
 
@@ -2465,27 +2099,27 @@ static void iwl_mac_stop(struct ieee8021
 	iwl_down(priv);
 
 	flush_workqueue(priv->workqueue);
-	free_irq(priv->pci_dev->irq, priv);
-	pci_disable_msi(priv->pci_dev);
-	pci_save_state(priv->pci_dev);
-	pci_disable_device(priv->pci_dev);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	/* enable interrupts again in order to receive rfkill changes */
+	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+	iwl_enable_interrupts(priv);
+
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MACDUMP("enter\n");
+	IWL_DEBUG_MACDUMP(priv, "enter\n");
 
-	IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+	IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
 	if (iwl_tx_skb(priv, skb))
 		dev_kfree_skb_any(skb);
 
-	IWL_DEBUG_MACDUMP("leave\n");
+	IWL_DEBUG_MACDUMP(priv, "leave\n");
 	return NETDEV_TX_OK;
 }
 
@@ -2495,10 +2129,10 @@ static int iwl_mac_add_interface(struct
 	struct iwl_priv *priv = hw->priv;
 	unsigned long flags;
 
-	IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+	IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
 
 	if (priv->vif) {
-		IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+		IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
 		return -EOPNOTSUPP;
 	}
 
@@ -2511,7 +2145,7 @@ static int iwl_mac_add_interface(struct
 	mutex_lock(&priv->mutex);
 
 	if (conf->mac_addr) {
-		IWL_DEBUG_MAC80211("Set %pM\n", conf->mac_addr);
+		IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
 		memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
 	}
 
@@ -2521,7 +2155,7 @@ static int iwl_mac_add_interface(struct
 
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 }
 
@@ -2537,117 +2171,122 @@ static int iwl_mac_config(struct ieee802
 	struct iwl_priv *priv = hw->priv;
 	const struct iwl_channel_info *ch_info;
 	struct ieee80211_conf *conf = &hw->conf;
-	unsigned long flags;
+	unsigned long flags = 0;
 	int ret = 0;
-	u16 channel;
+	u16 ch;
+	int scan_active = 0;
 
 	mutex_lock(&priv->mutex);
-	IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
-
-	priv->current_ht_config.is_ht = conf->ht.enabled;
+	IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+					conf->channel->hw_value, changed);
 
-	if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
-		goto out;
+	if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+			test_bit(STATUS_SCANNING, &priv->status))) {
+		scan_active = 1;
+		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
 	}
 
-	if (!conf->radio_enabled)
-		iwl_radio_kill_sw_disable_radio(priv);
 
-	if (!iwl_is_ready(priv)) {
-		IWL_DEBUG_MAC80211("leave - not ready\n");
-		ret = -EIO;
-		goto out;
-	}
+	/* during scanning mac80211 will delay channel setting until
+	 * scan finish with changed = 0
+	 */
+	if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+		if (scan_active)
+			goto set_ch_out;
 
-	if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
-		     test_bit(STATUS_SCANNING, &priv->status))) {
-		IWL_DEBUG_MAC80211("leave - scanning\n");
-		mutex_unlock(&priv->mutex);
-		return 0;
-	}
+		ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
+		ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+		if (!is_channel_valid(ch_info)) {
+			IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+			ret = -EINVAL;
+			goto set_ch_out;
+		}
 
-	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-	ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
-	if (!is_channel_valid(ch_info)) {
-		IWL_DEBUG_MAC80211("leave - invalid channel\n");
-		ret = -EINVAL;
-		goto out;
-	}
+		if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+			!is_channel_ibss(ch_info)) {
+			IWL_ERR(priv, "channel %d in band %d not "
+				"IBSS channel\n",
+				conf->channel->hw_value, conf->channel->band);
+			ret = -EINVAL;
+			goto set_ch_out;
+		}
 
-	if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
-	    !is_channel_ibss(ch_info)) {
-		IWL_ERROR("channel %d in band %d not IBSS channel\n",
-			conf->channel->hw_value, conf->channel->band);
-		ret = -EINVAL;
-		goto out;
-	}
+		priv->current_ht_config.is_ht = conf_is_ht(conf);
 
-	spin_lock_irqsave(&priv->lock, flags);
+		spin_lock_irqsave(&priv->lock, flags);
 
 
-	/* if we are switching from ht to 2.4 clear flags
-	 * from any ht related info since 2.4 does not
-	 * support ht */
-	if ((le16_to_cpu(priv->staging_rxon.channel) != channel)
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
-	    && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
-#endif
-	)
-		priv->staging_rxon.flags = 0;
+		/* if we are switching from ht to 2.4 clear flags
+		 * from any ht related info since 2.4 does not
+		 * support ht */
+		if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+			priv->staging_rxon.flags = 0;
 
-	iwl_set_rxon_channel(priv, conf->channel);
+		iwl_set_rxon_channel(priv, conf->channel);
 
-	iwl_set_flags_for_band(priv, conf->channel->band);
+		iwl_set_flags_for_band(priv, conf->channel->band);
+		spin_unlock_irqrestore(&priv->lock, flags);
+ set_ch_out:
+		/* The list of supported rates and rate mask can be different
+		 * for each band; since the band may have changed, reset
+		 * the rate mask to what mac80211 lists */
+		iwl_set_rate(priv);
+	}
 
-	/* The list of supported rates and rate mask can be different
-	 * for each band; since the band may have changed, reset
-	 * the rate mask to what mac80211 lists */
-	iwl_set_rate(priv);
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		if (conf->flags & IEEE80211_CONF_PS)
+			ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
+		else
+			ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
+		if (ret)
+			IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+	}
 
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
-	if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
-		iwl_hw_channel_switch(priv, conf->channel);
-		goto out;
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+		IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+			priv->tx_power_user_lmt, conf->power_level);
+
+		iwl_set_tx_power(priv, conf->power_level, false);
+	}
+
+	/* call to ensure that 4965 rx_chain is set properly in monitor mode */
+	iwl_set_rxon_chain(priv);
+
+	if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+		if (conf->radio_enabled &&
+			iwl_radio_kill_sw_enable_radio(priv)) {
+			IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
+						"waiting for uCode\n");
+			goto out;
+		}
+
+		if (!conf->radio_enabled)
+			iwl_radio_kill_sw_disable_radio(priv);
 	}
-#endif
 
 	if (!conf->radio_enabled) {
-		IWL_DEBUG_MAC80211("leave - radio disabled\n");
+		IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
 		goto out;
 	}
 
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF kill\n");
-		ret = -EIO;
+	if (!iwl_is_ready(priv)) {
+		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		goto out;
 	}
 
-	if (conf->flags & IEEE80211_CONF_PS)
-		ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
-	else
-		ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
-	if (ret)
-		IWL_DEBUG_MAC80211("Error setting power level\n");
-
-	IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
-			   priv->tx_power_user_lmt, conf->power_level);
-
-	iwl_set_tx_power(priv, conf->power_level, false);
-
-	iwl_set_rate(priv);
+	if (scan_active)
+		goto out;
 
 	if (memcmp(&priv->active_rxon,
 		   &priv->staging_rxon, sizeof(priv->staging_rxon)))
 		iwl_commit_rxon(priv);
 	else
-		IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+		IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
 
-	IWL_DEBUG_MAC80211("leave\n");
 
 out:
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	mutex_unlock(&priv->mutex);
 	return ret;
 }
@@ -2672,7 +2311,7 @@ static void iwl_config_ap(struct iwl_pri
 		ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
 				sizeof(priv->rxon_timing), &priv->rxon_timing);
 		if (ret)
-			IWL_WARNING("REPLY_RXON_TIMING failed - "
+			IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
 					"Attempting to continue.\n");
 
 		iwl_set_rxon_chain(priv);
@@ -2726,7 +2365,7 @@ static int iwl_mac_config_interface(stru
 		return -EIO;
 
 	if (priv->vif != vif) {
-		IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+		IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
 		return 0;
 	}
 
@@ -2748,7 +2387,7 @@ static int iwl_mac_config_interface(stru
 	mutex_lock(&priv->mutex);
 
 	if (conf->bssid)
-		IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+		IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
 
 /*
  * very dubious code was here; the probe filtering flag is never set:
@@ -2761,7 +2400,7 @@ static int iwl_mac_config_interface(stru
 		if (!conf->bssid) {
 			conf->bssid = priv->mac_addr;
 			memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-			IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+			IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
 					   conf->bssid);
 		}
 		if (priv->ibss_beacon)
@@ -2778,9 +2417,9 @@ static int iwl_mac_config_interface(stru
 		/* If there is currently a HW scan going on in the background
 		 * then we need to cancel it else the RXON below will fail. */
 		if (iwl_scan_cancel_timeout(priv, 100)) {
-			IWL_WARNING("Aborted scan still in progress "
+			IWL_WARN(priv, "Aborted scan still in progress "
 				    "after 100ms\n");
-			IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+			IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
 			mutex_unlock(&priv->mutex);
 			return -EAGAIN;
 		}
@@ -2808,64 +2447,18 @@ static int iwl_mac_config_interface(stru
 	}
 
  done:
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	mutex_unlock(&priv->mutex);
 
 	return 0;
 }
 
-static void iwl_configure_filter(struct ieee80211_hw *hw,
-				 unsigned int changed_flags,
-				 unsigned int *total_flags,
-				 int mc_count, struct dev_addr_list *mc_list)
-{
-	struct iwl_priv *priv = hw->priv;
-	__le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
-	IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
-			changed_flags, *total_flags);
-
-	if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
-		if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
-			*filter_flags |= RXON_FILTER_PROMISC_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
-	}
-	if (changed_flags & FIF_ALLMULTI) {
-		if (*total_flags & FIF_ALLMULTI)
-			*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
-	}
-	if (changed_flags & FIF_CONTROL) {
-		if (*total_flags & FIF_CONTROL)
-			*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
-	}
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
-			*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
-		else
-			*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
-	}
-
-	/* We avoid iwl_commit_rxon here to commit the new filter flags
-	 * since mac80211 will call ieee80211_hw_config immediately.
-	 * (mc_list is not supported at this time). Otherwise, we need to
-	 * queue a background iwl_commit_rxon work.
-	 */
-
-	*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
-			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
 static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 				     struct ieee80211_if_init_conf *conf)
 {
 	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	mutex_lock(&priv->mutex);
 
@@ -2880,7 +2473,7 @@ static void iwl_mac_remove_interface(str
 	}
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 }
 
@@ -2892,10 +2485,10 @@ static void iwl_bss_info_changed(struct
 {
 	struct iwl_priv *priv = hw->priv;
 
-	IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+	IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
 
 	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
-		IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+		IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
 				   bss_conf->use_short_preamble);
 		if (bss_conf->use_short_preamble)
 			priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
@@ -2904,7 +2497,7 @@ static void iwl_bss_info_changed(struct
 	}
 
 	if (changes & BSS_CHANGED_ERP_CTS_PROT) {
-		IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+		IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
 		if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
 			priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
 		else
@@ -2917,7 +2510,7 @@ static void iwl_bss_info_changed(struct
 	}
 
 	if (changes & BSS_CHANGED_ASSOC) {
-		IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+		IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
 		/* This should never happen as this function should
 		 * never be called from interrupt context. */
 		if (WARN_ON_ONCE(in_interrupt()))
@@ -2939,108 +2532,49 @@ static void iwl_bss_info_changed(struct
 			mutex_unlock(&priv->mutex);
 		} else {
 			priv->assoc_id = 0;
-			IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+			IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
 		}
 	} else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
-			IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+			IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
 			iwl_send_rxon_assoc(priv);
 	}
 
 }
 
-static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
-{
-	unsigned long flags;
-	struct iwl_priv *priv = hw->priv;
-	int ret;
-
-	IWL_DEBUG_MAC80211("enter\n");
-
-	mutex_lock(&priv->mutex);
-	spin_lock_irqsave(&priv->lock, flags);
-
-	if (!iwl_is_ready_rf(priv)) {
-		ret = -EIO;
-		IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
-		goto out_unlock;
-	}
-
-	/* We don't schedule scan within next_scan_jiffies period.
-	 * Avoid scanning during possible EAPOL exchange, return
-	 * success immediately.
-	 */
-	if (priv->next_scan_jiffies &&
-	    time_after(priv->next_scan_jiffies, jiffies)) {
-		IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
-		queue_work(priv->workqueue, &priv->scan_completed);
-		ret = 0;
-		goto out_unlock;
-	}
-
-	/* if we just finished scan ask for delay */
-	if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
-	    time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
-		IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
-		queue_work(priv->workqueue, &priv->scan_completed);
-		ret = 0;
-		goto out_unlock;
-	}
-
-	if (ssid_len) {
-		priv->one_direct_scan = 1;
-		priv->direct_ssid_len =  min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
-		memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-	} else {
-		priv->one_direct_scan = 0;
-	}
-
-	ret = iwl_scan_initiate(priv);
-
-	IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
-	spin_unlock_irqrestore(&priv->lock, flags);
-	mutex_unlock(&priv->mutex);
-
-	return ret;
-}
-
 static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
 			struct ieee80211_key_conf *keyconf, const u8 *addr,
 			u32 iv32, u16 *phase1key)
 {
 
 	struct iwl_priv *priv = hw->priv;
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-			   const u8 *local_addr, const u8 *addr,
+			   struct ieee80211_vif *vif,
+			   struct ieee80211_sta *sta,
 			   struct ieee80211_key_conf *key)
 {
 	struct iwl_priv *priv = hw->priv;
-	int ret = 0;
-	u8 sta_id = IWL_INVALID_STATION;
-	u8 is_default_wep_key = 0;
+	const u8 *addr;
+	int ret;
+	u8 sta_id;
+	bool is_default_wep_key = false;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (priv->hw_params.sw_crypto) {
-		IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
 		return -EOPNOTSUPP;
 	}
-
-	if (is_zero_ether_addr(addr))
-		/* only support pairwise keys */
-		return -EOPNOTSUPP;
-
+	addr = sta ? sta->addr : iwl_bcast_addr;
 	sta_id = iwl_find_station(priv, addr);
 	if (sta_id == IWL_INVALID_STATION) {
-		IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+		IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
 				   addr);
 		return -EINVAL;
 
@@ -3070,7 +2604,7 @@ static int iwl_mac_set_key(struct ieee80
 		else
 			ret = iwl_set_dynamic_key(priv, key, sta_id);
 
-		IWL_DEBUG_MAC80211("enable hwcrypto key\n");
+		IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
 		break;
 	case DISABLE_KEY:
 		if (is_default_wep_key)
@@ -3078,13 +2612,13 @@ static int iwl_mac_set_key(struct ieee80
 		else
 			ret = iwl_remove_dynamic_key(priv, key, sta_id);
 
-		IWL_DEBUG_MAC80211("disable hwcrypto key\n");
+		IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
 		break;
 	default:
 		ret = -EINVAL;
 	}
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 	return ret;
 }
@@ -3096,15 +2630,15 @@ static int iwl_mac_conf_tx(struct ieee80
 	unsigned long flags;
 	int q;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
 	if (queue >= AC_NUM) {
-		IWL_DEBUG_MAC80211("leave - queue >= AC_NUM %d\n", queue);
+		IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
 		return 0;
 	}
 
@@ -3128,7 +2662,7 @@ static int iwl_mac_conf_tx(struct ieee80
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 }
 
@@ -3137,8 +2671,9 @@ static int iwl_mac_ampdu_action(struct i
 			     struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
 	struct iwl_priv *priv = hw->priv;
+	int ret;
 
-	IWL_DEBUG_HT("A-MPDU action on addr %pM tid %d\n",
+	IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
 		     sta->addr, tid);
 
 	if (!(priv->cfg->sku & IWL_SKU_N))
@@ -3146,19 +2681,27 @@ static int iwl_mac_ampdu_action(struct i
 
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
-		IWL_DEBUG_HT("start Rx\n");
+		IWL_DEBUG_HT(priv, "start Rx\n");
 		return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
 	case IEEE80211_AMPDU_RX_STOP:
-		IWL_DEBUG_HT("stop Rx\n");
-		return iwl_sta_rx_agg_stop(priv, sta->addr, tid);
+		IWL_DEBUG_HT(priv, "stop Rx\n");
+		ret = iwl_sta_rx_agg_stop(priv, sta->addr, tid);
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+			return 0;
+		else
+			return ret;
 	case IEEE80211_AMPDU_TX_START:
-		IWL_DEBUG_HT("start Tx\n");
+		IWL_DEBUG_HT(priv, "start Tx\n");
 		return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
 	case IEEE80211_AMPDU_TX_STOP:
-		IWL_DEBUG_HT("stop Tx\n");
-		return iwl_tx_agg_stop(priv, sta->addr, tid);
+		IWL_DEBUG_HT(priv, "stop Tx\n");
+		ret = iwl_tx_agg_stop(priv, sta->addr, tid);
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+			return 0;
+		else
+			return ret;
 	default:
-		IWL_DEBUG_HT("unknown\n");
+		IWL_DEBUG_HT(priv, "unknown\n");
 		return -EINVAL;
 		break;
 	}
@@ -3174,10 +2717,10 @@ static int iwl_mac_get_tx_stats(struct i
 	struct iwl_queue *q;
 	unsigned long flags;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
@@ -3195,7 +2738,7 @@ static int iwl_mac_get_tx_stats(struct i
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 	return 0;
 }
@@ -3206,8 +2749,8 @@ static int iwl_mac_get_stats(struct ieee
 	struct iwl_priv *priv = hw->priv;
 
 	priv = hw->priv;
-	IWL_DEBUG_MAC80211("enter\n");
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 	return 0;
 }
@@ -3218,7 +2761,7 @@ static void iwl_mac_reset_tsf(struct iee
 	unsigned long flags;
 
 	mutex_lock(&priv->mutex);
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	spin_lock_irqsave(&priv->lock, flags);
 	memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
@@ -3245,7 +2788,7 @@ static void iwl_mac_reset_tsf(struct iee
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - not ready\n");
+		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		mutex_unlock(&priv->mutex);
 		return;
 	}
@@ -3274,7 +2817,7 @@ static void iwl_mac_reset_tsf(struct iee
 						     IEEE80211_CHAN_RADAR))
 				iwl_power_disable_management(priv, 3000);
 
-		IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+		IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
 		mutex_unlock(&priv->mutex);
 		return;
 	}
@@ -3283,7 +2826,7 @@ static void iwl_mac_reset_tsf(struct iee
 
 	mutex_unlock(&priv->mutex);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
 static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -3292,15 +2835,15 @@ static int iwl_mac_beacon_update(struct
 	unsigned long flags;
 	__le64 timestamp;
 
-	IWL_DEBUG_MAC80211("enter\n");
+	IWL_DEBUG_MAC80211(priv, "enter\n");
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_MAC80211("leave - RF not ready\n");
+		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 		return -EIO;
 	}
 
 	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-		IWL_DEBUG_MAC80211("leave - not IBSS\n");
+		IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
 		return -EIO;
 	}
 
@@ -3315,7 +2858,7 @@ static int iwl_mac_beacon_update(struct
 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
 	priv->timestamp = le64_to_cpu(timestamp);
 
-	IWL_DEBUG_MAC80211("leave\n");
+	IWL_DEBUG_MAC80211(priv, "leave\n");
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	iwl_reset_qos(priv);
@@ -3359,8 +2902,7 @@ static ssize_t store_debug_level(struct
 
 	ret = strict_strtoul(buf, 0, &val);
 	if (ret)
-		printk(KERN_INFO DRV_NAME
-		       ": %s is not in hex or decimal form.\n", buf);
+		IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
 	else
 		priv->debug_level = val;
 
@@ -3439,8 +2981,7 @@ static ssize_t store_tx_power(struct dev
 
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
-		printk(KERN_INFO DRV_NAME
-		       ": %s is not in decimal form.\n", buf);
+		IWL_INFO(priv, "%s is not in decimal form.\n", buf);
 	else
 		iwl_set_tx_power(priv, val, false);
 
@@ -3473,9 +3014,9 @@ static ssize_t store_flags(struct device
 	if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
 		/* Cancel any currently running scans... */
 		if (iwl_scan_cancel_timeout(priv, 100))
-			IWL_WARNING("Could not cancel scan.\n");
+			IWL_WARN(priv, "Could not cancel scan.\n");
 		else {
-			IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
+			IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
 			priv->staging_rxon.flags = cpu_to_le32(flags);
 			iwl_commit_rxon(priv);
 		}
@@ -3512,9 +3053,9 @@ static ssize_t store_filter_flags(struct
 	if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
 		/* Cancel any currently running scans... */
 		if (iwl_scan_cancel_timeout(priv, 100))
-			IWL_WARNING("Could not cancel scan.\n");
+			IWL_WARN(priv, "Could not cancel scan.\n");
 		else {
-			IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+			IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
 				       "0x%04X\n", filter_flags);
 			priv->staging_rxon.filter_flags =
 				cpu_to_le32(filter_flags);
@@ -3529,31 +3070,6 @@ static ssize_t store_filter_flags(struct
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 		   store_filter_flags);
 
-static ssize_t store_retry_rate(struct device *d,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	long val;
-	int ret  = strict_strtol(buf, 10, &val);
-	if (!ret)
-		return ret;
-
-	priv->retry_rate = (val > 0) ? val : 1;
-
-	return count;
-}
-
-static ssize_t show_retry_rate(struct device *d,
-			       struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	return sprintf(buf, "%d", priv->retry_rate);
-}
-
-static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
-		   store_retry_rate);
-
 static ssize_t store_power_level(struct device *d,
 				 struct device_attribute *attr,
 				 const char *buf, size_t count)
@@ -3565,18 +3081,13 @@ static ssize_t store_power_level(struct
 
 	mutex_lock(&priv->mutex);
 
-	if (!iwl_is_ready(priv)) {
-		ret = -EAGAIN;
-		goto out;
-	}
-
 	ret = strict_strtoul(buf, 10, &mode);
 	if (ret)
 		goto out;
 
 	ret = iwl_power_set_user_mode(priv, mode);
 	if (ret) {
-		IWL_DEBUG_MAC80211("failed setting power mode.\n");
+		IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
 		goto out;
 	}
 	ret = count;
@@ -3656,16 +3167,6 @@ static ssize_t show_statistics(struct de
 
 static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
 
-static ssize_t show_status(struct device *d,
-			   struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-	if (!iwl_is_alive(priv))
-		return -EAGAIN;
-	return sprintf(buf, "0x%08x\n", (int)priv->status);
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
 /*****************************************************************************
  *
@@ -3675,7 +3176,7 @@ static DEVICE_ATTR(status, S_IRUGO, show
 
 static void iwl_setup_deferred_work(struct iwl_priv *priv)
 {
-	priv->workqueue = create_workqueue(DRV_NAME);
+	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
 
 	init_waitqueue_head(&priv->wait_command_queue);
 
@@ -3719,9 +3220,7 @@ static struct attribute *iwl_sysfs_entri
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
 	&dev_attr_power_level.attr,
-	&dev_attr_retry_rate.attr,
 	&dev_attr_statistics.attr,
-	&dev_attr_status.attr,
 	&dev_attr_temperature.attr,
 	&dev_attr_tx_power.attr,
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -3764,6 +3263,7 @@ static int iwl_pci_probe(struct pci_dev
 	struct ieee80211_hw *hw;
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	unsigned long flags;
+	u16 pci_cmd;
 
 	/************************
 	 * 1. Allocating HW data
@@ -3788,7 +3288,7 @@ static int iwl_pci_probe(struct pci_dev
 
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 
-	IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
+	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
 	priv->cfg = cfg;
 	priv->pci_dev = pdev;
 
@@ -3816,8 +3316,7 @@ static int iwl_pci_probe(struct pci_dev
 			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
 		/* both attempts failed: */
 		if (err) {
-			printk(KERN_WARNING "%s: No suitable DMA available.\n",
-				DRV_NAME);
+			IWL_WARN(priv, "No suitable DMA available.\n");
 			goto out_pci_disable_device;
 		}
 	}
@@ -3838,13 +3337,12 @@ static int iwl_pci_probe(struct pci_dev
 		goto out_pci_release_regions;
 	}
 
-	IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+	IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
 		(unsigned long long) pci_resource_len(pdev, 0));
-	IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+	IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
 
 	iwl_hw_detect(priv);
-	printk(KERN_INFO DRV_NAME
-		": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
+	IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
 		priv->cfg->name, priv->hw_rev);
 
 	/* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3854,7 +3352,7 @@ static int iwl_pci_probe(struct pci_dev
 	/* amp init */
 	err = priv->cfg->ops->lib->apm_ops.init(priv);
 	if (err < 0) {
-		IWL_DEBUG_INFO("Failed to init APMG\n");
+		IWL_ERR(priv, "Failed to init APMG\n");
 		goto out_iounmap;
 	}
 	/*****************
@@ -3863,7 +3361,7 @@ static int iwl_pci_probe(struct pci_dev
 	/* Read the EEPROM */
 	err = iwl_eeprom_init(priv);
 	if (err) {
-		IWL_ERROR("Unable to init EEPROM\n");
+		IWL_ERR(priv, "Unable to init EEPROM\n");
 		goto out_iounmap;
 	}
 	err = iwl_eeprom_check_version(priv);
@@ -3872,14 +3370,14 @@ static int iwl_pci_probe(struct pci_dev
 
 	/* extract MAC Address */
 	iwl_eeprom_get_mac(priv, priv->mac_addr);
-	IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
 	SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
 	/************************
 	 * 5. Setup HW constants
 	 ************************/
 	if (iwl_set_hw_params(priv)) {
-		IWL_ERROR("failed to set hw parameters\n");
+		IWL_ERR(priv, "failed to set hw parameters\n");
 		goto out_free_eeprom;
 	}
 
@@ -3899,7 +3397,7 @@ static int iwl_pci_probe(struct pci_dev
 	/* Disable radio (SW RF KILL) via parameter when loading driver */
 	if (priv->cfg->mod_params->disable) {
 		set_bit(STATUS_RF_KILL_SW, &priv->status);
-		IWL_DEBUG_INFO("Radio disabled.\n");
+		IWL_DEBUG_INFO(priv, "Radio disabled.\n");
 	}
 
 	/********************
@@ -3909,38 +3407,57 @@ static int iwl_pci_probe(struct pci_dev
 	iwl_disable_interrupts(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	pci_enable_msi(priv->pci_dev);
+
+	err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+			  DRV_NAME, priv);
+	if (err) {
+		IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+		goto out_disable_msi;
+	}
 	err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
 	if (err) {
-		IWL_ERROR("failed to create sysfs device attributes\n");
-		goto out_uninit_drv;
+		IWL_ERR(priv, "failed to create sysfs device attributes\n");
+		goto out_free_irq;
 	}
 
-
 	iwl_setup_deferred_work(priv);
 	iwl_setup_rx_handlers(priv);
 
-	/********************
-	 * 9. Conclude
-	 ********************/
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-
 	/**********************************
-	 * 10. Setup and register mac80211
+	 * 9. Setup and register mac80211
 	 **********************************/
 
+	/* enable interrupts if needed: hw bug w/a */
+	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+		pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+	}
+
+	iwl_enable_interrupts(priv);
+
 	err = iwl_setup_mac(priv);
 	if (err)
 		goto out_remove_sysfs;
 
 	err = iwl_dbgfs_register(priv, DRV_NAME);
 	if (err)
-		IWL_ERROR("failed to create debugfs files\n");
+		IWL_ERR(priv, "failed to create debugfs files\n");
+
+	/* If platform's RF_KILL switch is NOT set to KILL */
+	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);
 
 	err = iwl_rfkill_init(priv);
 	if (err)
-		IWL_ERROR("Unable to initialize RFKILL system. "
+		IWL_ERR(priv, "Unable to initialize RFKILL system. "
 				  "Ignoring error: %d\n", err);
+	else
+		iwl_rfkill_set_hw_state(priv);
+
 	iwl_power_initialize(priv);
 	return 0;
 
@@ -3948,7 +3465,10 @@ static int iwl_pci_probe(struct pci_dev
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 	sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
- out_uninit_drv:
+ out_free_irq:
+	free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+	pci_disable_msi(priv->pci_dev);
 	iwl_uninit_drv(priv);
  out_free_eeprom:
 	iwl_eeprom_free(priv);
@@ -3973,7 +3493,7 @@ static void __devexit iwl_pci_remove(str
 	if (!priv)
 		return;
 
-	IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+	IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
 	iwl_dbgfs_unregister(priv);
 	sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
@@ -4019,6 +3539,8 @@ static void __devexit iwl_pci_remove(str
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 
+	free_irq(priv->pci_dev->irq, priv);
+	pci_disable_msi(priv->pci_dev);
 	pci_iounmap(pdev, priv->hw_base);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -4044,19 +3566,8 @@ static int iwl_pci_suspend(struct pci_de
 		priv->is_open = 1;
 	}
 
-	/* pci driver assumes state will be saved in this function.
-	 * pci state is saved and device disabled when interface is
-	 * stopped, so at this time pci device will always be disabled -
-	 * whether interface was started or not. saving pci state now will
-	 * cause saved state be that of a disabled device, which will cause
-	 * problems during resume in that we will end up with a disabled device.
-	 *
-	 * indicate that the current saved state (from when interface was
-	 * stopped) is valid. if interface was never up at time of suspend
-	 * then the saved state will still be valid as it was saved during
-	 * .probe. */
-	pdev->state_saved = true;
-
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
@@ -4065,8 +3576,14 @@ static int iwl_pci_suspend(struct pci_de
 static int iwl_pci_resume(struct pci_dev *pdev)
 {
 	struct iwl_priv *priv = pci_get_drvdata(pdev);
+	int ret;
 
 	pci_set_power_state(pdev, PCI_D0);
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
+	pci_restore_state(pdev);
+	iwl_enable_interrupts(priv);
 
 	if (priv->is_open)
 		iwl_mac_start(priv->hw);
@@ -4107,6 +3624,23 @@ static struct pci_device_id iwl_hw_card_
 /* 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(0x0082, 0x1102, iwl6000_2ag_cfg)},
+	{IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
+	{IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+	{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_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)},
+/* 1000 Series WiFi */
+	{IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
 #endif /* CONFIG_IWL5000 */
 
 	{0}
@@ -4133,13 +3667,14 @@ static int __init iwl_init(void)
 
 	ret = iwlagn_rate_control_register();
 	if (ret) {
-		IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+		printk(KERN_ERR DRV_NAME
+		       "Unable to register rate control algorithm: %d\n", ret);
 		return ret;
 	}
 
 	ret = pci_register_driver(&iwl_driver);
 	if (ret) {
-		IWL_ERROR("Unable to initialize PCI module\n");
+		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
 		goto error_register;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 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.GPL.
- *
- * 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 <net/mac80211.h>
-#include "iwl-dev.h"
-#include "iwl-debug.h"
-#include "iwl-commands.h"
-
-
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE:  This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
-{
-	int error = 0;
-	int counter = 1;
-
-	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
-		error |= le32_to_cpu(rxon->flags &
-				(RXON_FLG_TGJ_NARROW_BAND_MSK |
-				 RXON_FLG_RADAR_DETECT_MSK));
-		if (error)
-			IWL_WARNING("check 24G fields %d | %d\n",
-				    counter++, error);
-	} else {
-		error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
-				0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
-		if (error)
-			IWL_WARNING("check 52 fields %d | %d\n",
-				    counter++, error);
-		error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
-		if (error)
-			IWL_WARNING("check 52 CCK %d | %d\n",
-				    counter++, error);
-	}
-	error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
-	if (error)
-		IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
-	/* make sure basic rates 6Mbps and 1Mbps are supported */
-	error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
-		  ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
-	if (error)
-		IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
-	error |= (le16_to_cpu(rxon->assoc_id) > 2007);
-	if (error)
-		IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
-	if (error)
-		IWL_WARNING("check CCK and short slot %d | %d\n",
-			    counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
-			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
-	if (error)
-		IWL_WARNING("check CCK & auto detect %d | %d\n",
-			    counter++, error);
-
-	error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
-			RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
-	if (error)
-		IWL_WARNING("check TGG and auto detect %d | %d\n",
-			    counter++, error);
-
-	if (error)
-		IWL_WARNING("Tuning to channel %d\n",
-			    le16_to_cpu(rxon->channel));
-
-	if (error) {
-		IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
-		return -1;
-	}
-	return 0;
-}
-
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -49,6 +49,8 @@
 #define IWL_RATE_MIN_FAILURE_TH		6	/* min failures to calc tpt */
 #define IWL_RATE_MIN_SUCCESS_TH		8	/* min successes to calc tpt */
 
+/* max allowed rate miss before sync LQ cmd */
+#define IWL_MISSED_RATE_MAX		15
 /* max time to accum history 2 seconds */
 #define IWL_RATE_SCALE_FLUSH_INTVL   (2*HZ)
 
@@ -148,6 +150,8 @@ struct iwl_lq_sta {
 	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" */
@@ -356,7 +360,7 @@ static void rs_tl_turn_on_agg_for_tid(st
 				      struct ieee80211_sta *sta)
 {
 	if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
-		IWL_DEBUG_HT("Starting Tx agg: STA: %pM tid: %d\n",
+		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);
 	}
@@ -463,8 +467,9 @@ static int rs_collect_tx_data(struct iwl
  * Fill uCode API rate_n_flags field, based on "search" or "active" table.
  */
 /* FIXME:RS:remove this function and put the flags statically in the table */
-static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
-				       int index, u8 use_green)
+static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
+				 struct iwl_scale_tbl_info *tbl,
+				 int index, u8 use_green)
 {
 	u32 rate_n_flags = 0;
 
@@ -475,7 +480,7 @@ static u32 rate_n_flags_from_tbl(struct
 
 	} else if (is_Ht(tbl->lq_type)) {
 		if (index > IWL_LAST_OFDM_RATE) {
-			IWL_ERROR("invalid HT rate index %d\n", index);
+			IWL_ERR(priv, "Invalid HT rate index %d\n", index);
 			index = IWL_LAST_OFDM_RATE;
 		}
 		rate_n_flags = RATE_MCS_HT_MSK;
@@ -487,7 +492,7 @@ static u32 rate_n_flags_from_tbl(struct
 		else
 			rate_n_flags |=	iwl_rates[index].plcp_mimo3;
 	} else {
-		IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
+		IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);
 	}
 
 	rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
@@ -507,7 +512,7 @@ static u32 rate_n_flags_from_tbl(struct
 			rate_n_flags |= RATE_MCS_GF_MSK;
 			if (is_siso(tbl->lq_type) && tbl->is_SGI) {
 				rate_n_flags &= ~RATE_MCS_SGI_MSK;
-				IWL_ERROR("GF was set with SGI:SISO\n");
+				IWL_ERR(priv, "GF was set with SGI:SISO\n");
 			}
 		}
 	}
@@ -688,7 +693,7 @@ static u16 rs_get_adjacent_rate(struct i
 			break;
 		if (rate_mask & (1 << low))
 			break;
-		IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+		IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
 	}
 
 	high = index;
@@ -698,7 +703,7 @@ static u16 rs_get_adjacent_rate(struct i
 			break;
 		if (rate_mask & (1 << high))
 			break;
-		IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+		IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
 	}
 
 	return (high << 8) | low;
@@ -758,7 +763,7 @@ static u32 rs_get_lower_rate(struct iwl_
 		low = scale_index;
 
 out:
-	return rate_n_flags_from_tbl(tbl, low, is_green);
+	return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
 }
 
 /*
@@ -785,7 +790,7 @@ static void rs_tx_status(void *priv_r, s
 	u8 active_index = 0;
 	s32 tpt = 0;
 
-	IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
+	IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
 	if (!ieee80211_is_data(hdr->frame_control) ||
 	    is_multicast_ether_addr(hdr->addr1))
@@ -796,7 +801,10 @@ static void rs_tx_status(void *priv_r, s
 	    !(info->flags & IEEE80211_TX_STAT_AMPDU))
 		return;
 
-	retries = info->status.rates[0].count - 1;
+	if (info->flags & IEEE80211_TX_STAT_AMPDU)
+		retries = 0;
+	else
+		retries = info->status.rates[0].count - 1;
 
 	if (retries > 15)
 		retries = 15;
@@ -835,14 +843,19 @@ static void rs_tx_status(void *priv_r, s
 	    (!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
 	    (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
 	     hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
-		IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
+		IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate);
 		/* the last LQ command could failed so the LQ in ucode not
 		 * the same in driver sync up
 		 */
-		iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+		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.
@@ -903,7 +916,7 @@ static void rs_tx_status(void *priv_r, s
 			tpt = search_tbl->expected_tpt[rs_index];
 		else
 			tpt = 0;
-		if (info->flags & IEEE80211_TX_CTL_AMPDU)
+		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);
@@ -919,7 +932,7 @@ static void rs_tx_status(void *priv_r, s
 			tpt = curr_tbl->expected_tpt[rs_index];
 		else
 			tpt = 0;
-		if (info->flags & IEEE80211_TX_CTL_AMPDU)
+		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);
@@ -931,7 +944,7 @@ static void rs_tx_status(void *priv_r, s
 	/* 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_CTL_AMPDU) {
+		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);
@@ -961,7 +974,7 @@ out:
 static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
 				 struct iwl_lq_sta *lq_sta)
 {
-	IWL_DEBUG_RATE("we are staying in the same table\n");
+	IWL_DEBUG_RATE(priv, "we are staying in the same table\n");
 	lq_sta->stay_in_tbl = 1;	/* only place this gets set */
 	if (is_legacy) {
 		lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
@@ -1129,7 +1142,7 @@ static int rs_switch_to_mimo2(struct iwl
 	s32 rate;
 	s8 is_green = lq_sta->is_green;
 
-	if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+	if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
 		return -1;
 
 	if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
@@ -1140,7 +1153,7 @@ static int rs_switch_to_mimo2(struct iwl
 	if (priv->hw_params.tx_chains_num < 2)
 		return -1;
 
-	IWL_DEBUG_RATE("LQ: try to switch to MIMO2\n");
+	IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");
 
 	tbl->lq_type = LQ_MIMO2;
 	tbl->is_dup = lq_sta->is_dup;
@@ -1169,16 +1182,16 @@ static int rs_switch_to_mimo2(struct iwl
 
 	rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
 
-	IWL_DEBUG_RATE("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+	IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
 
 	if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
-		IWL_DEBUG_RATE("Can't switch with index %d rate mask %x\n",
+		IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
 						rate, rate_mask);
 		return -1;
 	}
-	tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
+	tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
 
-	IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+	IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
 		     tbl->current_rate, is_green);
 	return 0;
 }
@@ -1196,10 +1209,10 @@ static int rs_switch_to_siso(struct iwl_
 	u8 is_green = lq_sta->is_green;
 	s32 rate;
 
-	if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+	if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
 		return -1;
 
-	IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
+	IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n");
 
 	tbl->is_dup = lq_sta->is_dup;
 	tbl->lq_type = LQ_SISO;
@@ -1230,14 +1243,14 @@ static int rs_switch_to_siso(struct iwl_
 	rs_set_expected_tpt_table(lq_sta, tbl);
 	rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
 
-	IWL_DEBUG_RATE("LQ: get best rate %d mask %X\n", rate, rate_mask);
+	IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask);
 	if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
-		IWL_DEBUG_RATE("can not switch with index %d rate mask %x\n",
+		IWL_DEBUG_RATE(priv, "can not switch with index %d rate mask %x\n",
 			     rate, rate_mask);
 		return -1;
 	}
-	tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
-	IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+	tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
+	IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
 		     tbl->current_rate, is_green);
 	return 0;
 }
@@ -1266,7 +1279,7 @@ static int rs_move_legacy_other(struct i
 		switch (tbl->action) {
 		case IWL_LEGACY_SWITCH_ANTENNA1:
 		case IWL_LEGACY_SWITCH_ANTENNA2:
-			IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
+			IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
 
 			lq_sta->action_counter++;
 
@@ -1290,7 +1303,7 @@ static int rs_move_legacy_other(struct i
 			}
 			break;
 		case IWL_LEGACY_SWITCH_SISO:
-			IWL_DEBUG_RATE("LQ: Legacy switch to SISO\n");
+			IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n");
 
 			/* Set up search table to try SISO */
 			memcpy(search_tbl, tbl, sz);
@@ -1306,7 +1319,7 @@ static int rs_move_legacy_other(struct i
 		case IWL_LEGACY_SWITCH_MIMO2_AB:
 		case IWL_LEGACY_SWITCH_MIMO2_AC:
 		case IWL_LEGACY_SWITCH_MIMO2_BC:
-			IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
+			IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n");
 
 			/* Set up search table to try MIMO */
 			memcpy(search_tbl, tbl, sz);
@@ -1375,7 +1388,7 @@ static int rs_move_siso_to_other(struct
 		switch (tbl->action) {
 		case IWL_SISO_SWITCH_ANTENNA1:
 		case IWL_SISO_SWITCH_ANTENNA2:
-			IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
+			IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
 
 			if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
 							tx_chains_num <= 1) ||
@@ -1394,7 +1407,7 @@ static int rs_move_siso_to_other(struct
 		case IWL_SISO_SWITCH_MIMO2_AB:
 		case IWL_SISO_SWITCH_MIMO2_AC:
 		case IWL_SISO_SWITCH_MIMO2_BC:
-			IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
+			IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n");
 			memcpy(search_tbl, tbl, sz);
 			search_tbl->is_SGI = 0;
 
@@ -1423,14 +1436,15 @@ static int rs_move_siso_to_other(struct
 						HT_SHORT_GI_40MHZ))
 				break;
 
-			IWL_DEBUG_RATE("LQ: SISO toggle SGI/NGI\n");
+			IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
 
 			memcpy(search_tbl, tbl, sz);
 			if (is_green) {
 				if (!tbl->is_SGI)
 					break;
 				else
-					IWL_ERROR("SGI was set in GF+SISO\n");
+					IWL_ERR(priv,
+						"SGI was set in GF+SISO\n");
 			}
 			search_tbl->is_SGI = !tbl->is_SGI;
 			rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1439,8 +1453,9 @@ static int rs_move_siso_to_other(struct
 				if (tpt >= search_tbl->expected_tpt[index])
 					break;
 			}
-			search_tbl->current_rate = rate_n_flags_from_tbl(
-						search_tbl, index, is_green);
+			search_tbl->current_rate =
+				rate_n_flags_from_tbl(priv, search_tbl,
+						      index, is_green);
 			goto out;
 		}
 		tbl->action++;
@@ -1486,7 +1501,7 @@ static int rs_move_mimo_to_other(struct
 		switch (tbl->action) {
 		case IWL_MIMO2_SWITCH_ANTENNA1:
 		case IWL_MIMO2_SWITCH_ANTENNA2:
-			IWL_DEBUG_RATE("LQ: MIMO toggle Antennas\n");
+			IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
 
 			if (tx_chains_num <= 2)
 				break;
@@ -1502,7 +1517,7 @@ static int rs_move_mimo_to_other(struct
 		case IWL_MIMO2_SWITCH_SISO_A:
 		case IWL_MIMO2_SWITCH_SISO_B:
 		case IWL_MIMO2_SWITCH_SISO_C:
-			IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
+			IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n");
 
 			/* Set up new search table for SISO */
 			memcpy(search_tbl, tbl, sz);
@@ -1534,7 +1549,7 @@ static int rs_move_mimo_to_other(struct
 						HT_SHORT_GI_40MHZ))
 				break;
 
-			IWL_DEBUG_RATE("LQ: MIMO toggle SGI/NGI\n");
+			IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
 
 			/* Set up new search table for MIMO */
 			memcpy(search_tbl, tbl, sz);
@@ -1551,8 +1566,9 @@ static int rs_move_mimo_to_other(struct
 				if (tpt >= search_tbl->expected_tpt[index])
 					break;
 			}
-			search_tbl->current_rate = rate_n_flags_from_tbl(
-						search_tbl, index, is_green);
+			search_tbl->current_rate =
+				rate_n_flags_from_tbl(priv, search_tbl,
+						      index, is_green);
 			goto out;
 
 		}
@@ -1616,7 +1632,7 @@ static void rs_stay_in_table(struct iwl_
 		    (lq_sta->total_success > lq_sta->max_success_limit) ||
 		    ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
 		     && (flush_interval_passed))) {
-			IWL_DEBUG_RATE("LQ: stay is expired %d %d %d\n:",
+			IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n:",
 				     lq_sta->total_failed,
 				     lq_sta->total_success,
 				     flush_interval_passed);
@@ -1639,7 +1655,7 @@ static void rs_stay_in_table(struct iwl_
 			    lq_sta->table_count_limit) {
 				lq_sta->table_count = 0;
 
-				IWL_DEBUG_RATE("LQ: stay in table clear win\n");
+				IWL_DEBUG_RATE(priv, "LQ: stay in table clear win\n");
 				for (i = 0; i < IWL_RATE_COUNT; i++)
 					rs_rate_scale_clear_window(
 						&(tbl->win[i]));
@@ -1687,8 +1703,9 @@ static void rs_rate_scale_perform(struct
 	u16 high_low;
 	s32 sr;
 	u8 tid = MAX_TID_COUNT;
+	struct iwl_tid_data *tid_data;
 
-	IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
+	IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
 
 	/* Send management frames and broadcast/multicast data using
 	 * lowest rate. */
@@ -1720,13 +1737,13 @@ static void rs_rate_scale_perform(struct
 	/* current tx rate */
 	index = lq_sta->last_txrate_idx;
 
-	IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
+	IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index,
 		       tbl->lq_type);
 
 	/* rates available for this association, and for modulation mode */
 	rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
 
-	IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
+	IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask);
 
 	/* mask with station rate restriction */
 	if (is_legacy(tbl->lq_type)) {
@@ -1745,16 +1762,25 @@ static void rs_rate_scale_perform(struct
 		rate_scale_index_msk = rate_mask;
 
 	if (!((1 << index) & rate_scale_index_msk)) {
-		IWL_ERROR("Current Rate is not valid\n");
+		IWL_ERR(priv, "Current Rate is not valid\n");
 		return;
 	}
 
 	/* Get expected throughput table and history window for current rate */
 	if (!tbl->expected_tpt) {
-		IWL_ERROR("tbl->expected_tpt is NULL\n");
+		IWL_ERR(priv, "tbl->expected_tpt is NULL\n");
 		return;
 	}
 
+	/* force user max rate if set by user */
+	if ((lq_sta->max_rate_idx != -1) &&
+	    (lq_sta->max_rate_idx < index)) {
+		index = lq_sta->max_rate_idx;
+		update_lq = 1;
+		window = &(tbl->win[index]);
+		goto lq_update;
+	}
+
 	window = &(tbl->win[index]);
 
 	/*
@@ -1767,7 +1793,7 @@ static void rs_rate_scale_perform(struct
 	fail_count = window->counter - window->success_counter;
 	if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
 			(window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
-		IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d "
+		IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d "
 			       "for index %d\n",
 			       window->success_counter, window->counter, index);
 
@@ -1795,7 +1821,7 @@ static void rs_rate_scale_perform(struct
 		 * continuing to use the setup that we've been trying. */
 		if (window->average_tpt > lq_sta->last_tpt) {
 
-			IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
+			IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE "
 					"suc=%d cur-tpt=%d old-tpt=%d\n",
 					window->success_ratio,
 					window->average_tpt,
@@ -1811,7 +1837,7 @@ static void rs_rate_scale_perform(struct
 		/* Else poor success; go back to mode in "active" table */
 		} else {
 
-			IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE "
+			IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE "
 					"suc=%d cur-tpt=%d old-tpt=%d\n",
 					window->success_ratio,
 					window->average_tpt,
@@ -1846,6 +1872,11 @@ static void rs_rate_scale_perform(struct
 	low = high_low & 0xff;
 	high = (high_low >> 8) & 0xff;
 
+	/* If user set max rate, dont allow higher than user constrain */
+	if ((lq_sta->max_rate_idx != -1) &&
+	    (lq_sta->max_rate_idx < high))
+		high = IWL_RATE_INVALID;
+
 	sr = window->success_ratio;
 
 	/* Collect measured throughputs for current and adjacent rates */
@@ -1859,7 +1890,7 @@ static void rs_rate_scale_perform(struct
 
 	/* Too many failures, decrease rate */
 	if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
-		IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+		IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
 		scale_action = -1;
 
 	/* No throughput measured yet for adjacent rates; try increase. */
@@ -1869,7 +1900,7 @@ static void rs_rate_scale_perform(struct
 		if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
 			scale_action = 1;
 		else if (low != IWL_RATE_INVALID)
-			scale_action = -1;
+			scale_action = 0;
 	}
 
 	/* Both adjacent throughputs are measured, but neither one has better
@@ -1890,17 +1921,15 @@ static void rs_rate_scale_perform(struct
 					sr >= IWL_RATE_INCREASE_TH) {
 				scale_action = 1;
 			} else {
-				IWL_DEBUG_RATE
-				    ("decrease rate because of high tpt\n");
-				scale_action = -1;
+				scale_action = 0;
 			}
 
 		/* Lower adjacent rate's throughput is measured */
 		} else if (low_tpt != IWL_INVALID_VALUE) {
 			/* Lower rate has better throughput */
 			if (low_tpt > current_tpt) {
-				IWL_DEBUG_RATE
-				    ("decrease rate because of low tpt\n");
+				IWL_DEBUG_RATE(priv,
+				    "decrease rate because of low tpt\n");
 				scale_action = -1;
 			} else if (sr >= IWL_RATE_INCREASE_TH) {
 				scale_action = 1;
@@ -1937,14 +1966,14 @@ static void rs_rate_scale_perform(struct
 		break;
 	}
 
-	IWL_DEBUG_RATE("choose rate scale index %d action %d low %d "
+	IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d "
 		    "high %d type %d\n",
 		     index, scale_action, low, high, tbl->lq_type);
 
 lq_update:
 	/* Replace uCode's rate table for the destination station. */
 	if (update_lq) {
-		rate = rate_n_flags_from_tbl(tbl, index, is_green);
+		rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
 		rs_fill_link_cmd(priv, lq_sta, rate);
 		iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 	}
@@ -1981,7 +2010,7 @@ lq_update:
 			/* Use new "search" start rate */
 			index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
 
-			IWL_DEBUG_RATE("Switch current  mcs: %X index: %d\n",
+			IWL_DEBUG_RATE(priv, "Switch current  mcs: %X index: %d\n",
 				     tbl->current_rate, index);
 			rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
 			iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
@@ -1993,10 +2022,10 @@ lq_update:
 		 * stay with best antenna legacy modulation for a while
 		 * before next round of mode comparisons. */
 		tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
-		if (is_legacy(tbl1->lq_type) && !conf->ht.enabled &&
+		if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
 		    lq_sta->action_counter >= 1) {
 			lq_sta->action_counter = 0;
-			IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
+			IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
 			rs_set_stay_in_table(priv, 1, lq_sta);
 		}
 
@@ -2008,8 +2037,15 @@ lq_update:
 			if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
 			    (lq_sta->tx_agg_tid_en & (1 << tid)) &&
 			    (tid != MAX_TID_COUNT)) {
-				IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
-				rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
+				tid_data =
+				   &priv->stations[lq_sta->lq.sta_id].tid[tid];
+				if (tid_data->agg.state == IWL_AGG_OFF) {
+					IWL_DEBUG_RATE(priv,
+						       "try to aggregate tid %d\n",
+						       tid);
+					rs_tl_turn_on_agg(priv, tid,
+							  lq_sta, sta);
+				}
 			}
 			lq_sta->action_counter = 0;
 			rs_set_stay_in_table(priv, 0, lq_sta);
@@ -2028,7 +2064,7 @@ lq_update:
 	}
 
 out:
-	tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
+	tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
 	i = index;
 	lq_sta->last_txrate_idx = i;
 
@@ -2081,7 +2117,7 @@ static void rs_initialize_lq(struct iwl_
 	if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
 	    rs_toggle_antenna(valid_tx_ant, &rate, tbl);
 
-	rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
+	rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
 	tbl->current_rate = rate;
 	rs_set_expected_tpt_table(lq_sta, tbl);
 	rs_fill_link_cmd(NULL, lq_sta, rate);
@@ -2104,7 +2140,18 @@ static void rs_get_rate(void *priv_r, st
 	int rate_idx;
 	u64 mask_bit = 0;
 
-	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
+	IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
+
+	/* Get max rate if user set max rate */
+	if (lq_sta) {
+		lq_sta->max_rate_idx = txrc->max_rate_idx;
+		if ((sband->band == IEEE80211_BAND_5GHZ) &&
+		    (lq_sta->max_rate_idx != -1))
+			lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
+		if ((lq_sta->max_rate_idx < 0) ||
+		    (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
+			lq_sta->max_rate_idx = -1;
+	}
 
 	if (sta)
 		mask_bit = sta->supp_rates[sband->band];
@@ -2129,7 +2176,7 @@ static void rs_get_rate(void *priv_r, st
 		u8 sta_id = iwl_find_station(priv, hdr->addr1);
 
 		if (sta_id == IWL_INVALID_STATION) {
-			IWL_DEBUG_RATE("LQ: ADD station %pM\n",
+			IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
 				       hdr->addr1);
 			sta_id = iwl_add_station_flags(priv, hdr->addr1,
 							0, CMD_ASYNC, NULL);
@@ -2158,7 +2205,7 @@ static void *rs_alloc_sta(void *priv_rat
 	int i, j;
 
 	priv = (struct iwl_priv *)priv_rate;
-	IWL_DEBUG_RATE("create station rate scale window\n");
+	IWL_DEBUG_RATE(priv, "create station rate scale window\n");
 
 	lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
 
@@ -2182,6 +2229,8 @@ static void rs_rate_init(void *priv_r, s
 	struct ieee80211_conf *conf = &priv->hw->conf;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	u16 mask_bit = 0;
+	int count;
+	int start_rate = 0;
 
 	lq_sta->flush_timer = 0;
 	lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2189,7 +2238,7 @@ static void rs_rate_init(void *priv_r, s
 		for (i = 0; i < IWL_RATE_COUNT; i++)
 			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
 
-	IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
+	IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n");
 	/* 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
@@ -2200,10 +2249,10 @@ static void rs_rate_init(void *priv_r, s
 		u8 sta_id = iwl_find_station(priv, sta->addr);
 
 		/* for IBSS the call are from tasklet */
-		IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+		IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
 
 		if (sta_id == IWL_INVALID_STATION) {
-			IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+			IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
 			sta_id = iwl_add_station_flags(priv, sta->addr,
 							0, CMD_ASYNC, NULL);
 		}
@@ -2216,6 +2265,8 @@ static void rs_rate_init(void *priv_r, s
 	}
 
 	lq_sta->is_dup = 0;
+	lq_sta->max_rate_idx = -1;
+	lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
 	lq_sta->is_green = rs_use_green(priv, conf);
 	lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
 	lq_sta->active_rate_basic = priv->active_rate_basic;
@@ -2240,7 +2291,7 @@ static void rs_rate_init(void *priv_r, s
 	lq_sta->active_mimo3_rate &= ~((u16)0x2);
 	lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
 
-	IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
+	IWL_DEBUG_RATE(priv, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
 		     lq_sta->active_siso_rate,
 		     lq_sta->active_mimo2_rate,
 		     lq_sta->active_mimo3_rate);
@@ -2254,16 +2305,20 @@ static void rs_rate_init(void *priv_r, s
 	lq_sta->drv = priv;
 
 	/* Find highest tx rate supported by hardware and destination station */
-	mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
-	lq_sta->last_txrate_idx = 3;
-	for (i = 0; i < sband->n_bitrates; i++)
+	mask_bit = sta->supp_rates[sband->band];
+	count = sband->n_bitrates;
+	if (sband->band == IEEE80211_BAND_5GHZ) {
+		count += IWL_FIRST_OFDM_RATE;
+		start_rate = IWL_FIRST_OFDM_RATE;
+		mask_bit <<= IWL_FIRST_OFDM_RATE;
+	}
+
+	mask_bit = mask_bit & lq_sta->active_legacy_rate;
+	lq_sta->last_txrate_idx = 4;
+	for (i = start_rate; i < count; i++)
 		if (mask_bit & BIT(i))
 			lq_sta->last_txrate_idx = i;
 
-	/* For MODE_IEEE80211A, skip over cck rates in global rate table */
-	if (sband->band == IEEE80211_BAND_5GHZ)
-		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
 	rs_initialize_lq(priv, conf, sta, lq_sta);
 }
 
@@ -2402,9 +2457,9 @@ static void rs_free_sta(void *priv_r, st
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_priv *priv __maybe_unused = priv_r;
 
-	IWL_DEBUG_RATE("enter\n");
+	IWL_DEBUG_RATE(priv, "enter\n");
 	kfree(lq_sta);
-	IWL_DEBUG_RATE("leave\n");
+	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
 
@@ -2418,20 +2473,27 @@ static void rs_dbgfs_set_mcs(struct iwl_
 			     u32 *rate_n_flags, int index)
 {
 	struct iwl_priv *priv;
+	u8 valid_tx_ant;
+	u8 ant_sel_tx;
 
 	priv = lq_sta->drv;
+	valid_tx_ant = priv->hw_params.valid_tx_ant;
 	if (lq_sta->dbg_fixed_rate) {
-		if (index < 12) {
+		ant_sel_tx =
+		  ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
+		  >> RATE_MCS_ANT_POS);
+		if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
 			*rate_n_flags = lq_sta->dbg_fixed_rate;
+			IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
 		} else {
-			if (lq_sta->band == IEEE80211_BAND_5GHZ)
-				*rate_n_flags = 0x800D;
-			else
-				*rate_n_flags = 0x820A;
+			lq_sta->dbg_fixed_rate = 0;
+			IWL_ERR(priv,
+			    "Invalid antenna selection 0x%X, Valid is 0x%X\n",
+			    ant_sel_tx, valid_tx_ant);
+			IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
 		}
-		IWL_DEBUG_RATE("Fixed rate ON\n");
 	} else {
-		IWL_DEBUG_RATE("Fixed rate OFF\n");
+		IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
 	}
 }
 
@@ -2460,7 +2522,7 @@ static ssize_t rs_sta_dbgfs_scale_table_
 	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 
-	IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
+	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
 		lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
 
 	if (lq_sta->dbg_fixed_rate) {
@@ -2474,11 +2536,19 @@ static ssize_t rs_sta_dbgfs_scale_table_
 static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 			char __user *user_buf, size_t count, loff_t *ppos)
 {
-	char buff[1024];
+	char *buff;
 	int desc = 0;
 	int i = 0;
+	ssize_t ret;
 
 	struct iwl_lq_sta *lq_sta = file->private_data;
+	struct iwl_priv *priv;
+	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+
+	priv = lq_sta->drv;
+	buff = kmalloc(1024, GFP_KERNEL);
+	if (!buff)
+		return -ENOMEM;
 
 	desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
 	desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
@@ -2486,6 +2556,20 @@ static ssize_t rs_sta_dbgfs_scale_table_
 			lq_sta->active_legacy_rate);
 	desc += sprintf(buff+desc, "fixed rate 0x%X\n",
 			lq_sta->dbg_fixed_rate);
+	desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
+	    (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
+	    (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
+	    (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
+	desc += sprintf(buff+desc, "lq type %s\n",
+	   (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
+	if (is_Ht(tbl->lq_type)) {
+		desc += sprintf(buff+desc, " %s",
+		   (is_siso(tbl->lq_type)) ? "SISO" :
+		   ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
+		   desc += sprintf(buff+desc, " %s",
+		   (tbl->is_fat) ? "40MHz" : "20MHz");
+		desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
+	}
 	desc += sprintf(buff+desc, "general:"
 		"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
 		lq_sta->lq.general_params.flags,
@@ -2511,7 +2595,9 @@ static ssize_t rs_sta_dbgfs_scale_table_
 		desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
 			i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
 
-	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	kfree(buff);
+	return ret;
 }
 
 static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
@@ -2522,11 +2608,17 @@ static const struct file_operations rs_s
 static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
 			char __user *user_buf, size_t count, loff_t *ppos)
 {
-	char buff[1024];
+	char *buff;
 	int desc = 0;
 	int i, j;
+	ssize_t ret;
 
 	struct iwl_lq_sta *lq_sta = file->private_data;
+
+	buff = kmalloc(1024, GFP_KERNEL);
+	if (!buff)
+		return -ENOMEM;
+
 	for (i = 0; i < LQ_SIZE; i++) {
 		desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
 				"rate=0x%X\n",
@@ -2544,7 +2636,9 @@ static ssize_t rs_sta_dbgfs_stats_table_
 				lq_sta->lq_info[i].win[j].success_ratio);
 		}
 	}
-	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+	kfree(buff);
+	return ret;
 }
 
 static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -27,8 +27,6 @@
 #ifndef __iwl_agn_rs_h__
 #define __iwl_agn_rs_h__
 
-#include "iwl-dev.h"
-
 struct iwl_rate_info {
 	u8 plcp;	/* uCode API:  IWL_RATE_6M_PLCP, etc. */
 	u8 plcp_siso;	/* uCode API:  IWL_RATE_SISO_6M_PLCP, etc. */
@@ -43,6 +41,19 @@ struct iwl_rate_info {
 	u8 next_rs_tgg;  /* next rate used in TGG rs algo */
 };
 
+struct iwl3945_rate_info {
+	u8 plcp;		/* uCode API:  IWL_RATE_6M_PLCP, etc. */
+	u8 ieee;		/* MAC header:  IWL_RATE_6M_IEEE, etc. */
+	u8 prev_ieee;		/* previous rate in IEEE speeds */
+	u8 next_ieee;		/* next rate in IEEE speeds */
+	u8 prev_rs;		/* previous rate used in rs algo */
+	u8 next_rs;		/* next rate used in rs algo */
+	u8 prev_rs_tgg;		/* previous rate used in TGG rs algo */
+	u8 next_rs_tgg;		/* next rate used in TGG rs algo */
+	u8 table_rs_index;	/* index in rate scale table cmd */
+	u8 prev_table_rs;	/* prev in rate table cmd */
+};
+
 /*
  * These serve as indexes into
  * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -62,12 +73,30 @@ enum {
 	IWL_RATE_54M_INDEX,
 	IWL_RATE_60M_INDEX,
 	IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
+	IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
 	IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
 	IWL_RATE_INVALID = IWL_RATE_COUNT,
 };
 
 enum {
+	IWL_RATE_6M_INDEX_TABLE = 0,
+	IWL_RATE_9M_INDEX_TABLE,
+	IWL_RATE_12M_INDEX_TABLE,
+	IWL_RATE_18M_INDEX_TABLE,
+	IWL_RATE_24M_INDEX_TABLE,
+	IWL_RATE_36M_INDEX_TABLE,
+	IWL_RATE_48M_INDEX_TABLE,
+	IWL_RATE_54M_INDEX_TABLE,
+	IWL_RATE_1M_INDEX_TABLE,
+	IWL_RATE_2M_INDEX_TABLE,
+	IWL_RATE_5M_INDEX_TABLE,
+	IWL_RATE_11M_INDEX_TABLE,
+	IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
+};
+
+enum {
 	IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
+	IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
 	IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
 	IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
 	IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -202,7 +231,7 @@ enum {
 #define IWL_RS_GOOD_RATIO		12800	/* 100% */
 #define IWL_RATE_SCALE_SWITCH		10880	/*  85% */
 #define IWL_RATE_HIGH_TH		10880	/*  85% */
-#define IWL_RATE_INCREASE_TH            8960	/*  70% */
+#define IWL_RATE_INCREASE_TH		6400	/*  50% */
 #define IWL_RATE_DECREASE_TH		1920	/*  15% */
 
 /* possible actions when in legacy mode */
@@ -248,6 +277,7 @@ enum {
 #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
 
 extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
 
 enum iwl_table_type {
 	LQ_NONE,
@@ -303,6 +333,23 @@ static inline u8 iwl_get_prev_ieee_rate(
 	return rate;
 }
 
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+	u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+	if (rate == IWL_RATE_INVALID)
+		rate = rate_index;
+	return rate;
+}
+
+/**
+ * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
+ *
+ * The specific throughput table used is based on the type of network
+ * the associated with, including A, B, G, and G w/ TGG protection
+ */
+extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+
 /**
  * iwl_rate_control_register - Register the rate control algorithm callbacks
  *
@@ -314,6 +361,7 @@ static inline u8 iwl_get_prev_ieee_rate(
  *
  */
 extern int iwlagn_rate_control_register(void);
+extern int iwl3945_rate_control_register(void);
 
 /**
  * iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -322,5 +370,6 @@ extern int iwlagn_rate_control_register(
  * the driver is unloaded.
  */
 extern void iwlagn_rate_control_unregister(void);
+extern void iwl3945_rate_control_unregister(void);
 
 #endif /* __iwl_agn__rs__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ int iwl_send_calib_results(struct iwl_pr
 
 	return 0;
 err:
-	IWL_ERROR("Error %d iteration %d\n", ret, i);
+	IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
 	return ret;
 }
 EXPORT_SYMBOL(iwl_send_calib_results);
@@ -202,7 +202,7 @@ static int iwl_sens_energy_cck(struct iw
 		val = data->nrg_silence_rssi[i];
 		silence_ref = max(silence_ref, val);
 	}
-	IWL_DEBUG_CALIB("silence a %u, b %u, c %u, 20-bcn max %u\n",
+	IWL_DEBUG_CALIB(priv, "silence a %u, b %u, c %u, 20-bcn max %u\n",
 			silence_rssi_a, silence_rssi_b, silence_rssi_c,
 			silence_ref);
 
@@ -226,7 +226,7 @@ static int iwl_sens_energy_cck(struct iw
 		max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
 	max_nrg_cck += 6;
 
-	IWL_DEBUG_CALIB("rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
+	IWL_DEBUG_CALIB(priv, "rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
 			rx_info->beacon_energy_a, rx_info->beacon_energy_b,
 			rx_info->beacon_energy_c, max_nrg_cck - 6);
 
@@ -236,15 +236,15 @@ static int iwl_sens_energy_cck(struct iw
 		data->num_in_cck_no_fa++;
 	else
 		data->num_in_cck_no_fa = 0;
-	IWL_DEBUG_CALIB("consecutive bcns with few false alarms = %u\n",
+	IWL_DEBUG_CALIB(priv, "consecutive bcns with few false alarms = %u\n",
 			data->num_in_cck_no_fa);
 
 	/* If we got too many false alarms this time, reduce sensitivity */
 	if ((false_alarms > max_false_alarms) &&
 		(data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) {
-		IWL_DEBUG_CALIB("norm FA %u > max FA %u\n",
+		IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u\n",
 		     false_alarms, max_false_alarms);
-		IWL_DEBUG_CALIB("... reducing sensitivity\n");
+		IWL_DEBUG_CALIB(priv, "... reducing sensitivity\n");
 		data->nrg_curr_state = IWL_FA_TOO_MANY;
 		/* Store for "fewer than desired" on later beacon */
 		data->nrg_silence_ref = silence_ref;
@@ -266,7 +266,7 @@ static int iwl_sens_energy_cck(struct iw
 		data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
 						   (s32)silence_ref;
 
-		IWL_DEBUG_CALIB("norm FA %u < min FA %u, silence diff %d\n",
+		IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u, silence diff %d\n",
 			 false_alarms, min_false_alarms,
 			 data->nrg_auto_corr_silence_diff);
 
@@ -280,17 +280,17 @@ static int iwl_sens_energy_cck(struct iw
 			((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
 			(data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
 
-			IWL_DEBUG_CALIB("... increasing sensitivity\n");
+			IWL_DEBUG_CALIB(priv, "... increasing sensitivity\n");
 			/* Increase nrg value to increase sensitivity */
 			val = data->nrg_th_cck + NRG_STEP_CCK;
 			data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val);
 		} else {
-			IWL_DEBUG_CALIB("... but not changing sensitivity\n");
+			IWL_DEBUG_CALIB(priv, "... but not changing sensitivity\n");
 		}
 
 	/* Else we got a healthy number of false alarms, keep status quo */
 	} else {
-		IWL_DEBUG_CALIB(" FA in safe zone\n");
+		IWL_DEBUG_CALIB(priv, " FA in safe zone\n");
 		data->nrg_curr_state = IWL_FA_GOOD_RANGE;
 
 		/* Store for use in "fewer than desired" with later beacon */
@@ -300,7 +300,7 @@ static int iwl_sens_energy_cck(struct iw
 		 *   give it some extra margin by reducing sensitivity again
 		 *   (but don't go below measured energy of desired Rx) */
 		if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
-			IWL_DEBUG_CALIB("... increasing margin\n");
+			IWL_DEBUG_CALIB(priv, "... increasing margin\n");
 			if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
 				data->nrg_th_cck -= NRG_MARGIN;
 			else
@@ -314,7 +314,7 @@ static int iwl_sens_energy_cck(struct iw
 	 * Lower value is higher energy, so we use max()!
 	 */
 	data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
-	IWL_DEBUG_CALIB("new nrg_th_cck %u\n", data->nrg_th_cck);
+	IWL_DEBUG_CALIB(priv, "new nrg_th_cck %u\n", data->nrg_th_cck);
 
 	data->nrg_prev_state = data->nrg_curr_state;
 
@@ -367,7 +367,7 @@ static int iwl_sens_auto_corr_ofdm(struc
 	/* If we got too many false alarms this time, reduce sensitivity */
 	if (false_alarms > max_false_alarms) {
 
-		IWL_DEBUG_CALIB("norm FA %u > max FA %u)\n",
+		IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u)\n",
 			     false_alarms, max_false_alarms);
 
 		val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
@@ -390,7 +390,7 @@ static int iwl_sens_auto_corr_ofdm(struc
 	/* Else if we got fewer than desired, increase sensitivity */
 	else if (false_alarms < min_false_alarms) {
 
-		IWL_DEBUG_CALIB("norm FA %u < min FA %u\n",
+		IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u\n",
 			     false_alarms, min_false_alarms);
 
 		val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
@@ -409,7 +409,7 @@ static int iwl_sens_auto_corr_ofdm(struc
 		data->auto_corr_ofdm_mrc_x1 =
 			max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val);
 	} else {
-		IWL_DEBUG_CALIB("min FA %u < norm FA %u < max FA %u OK\n",
+		IWL_DEBUG_CALIB(priv, "min FA %u < norm FA %u < max FA %u OK\n",
 			 min_false_alarms, false_alarms, max_false_alarms);
 	}
 	return 0;
@@ -452,18 +452,18 @@ static int iwl_sensitivity_write(struct
 				cpu_to_le16((u16)data->nrg_th_ofdm);
 
 	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
-				__constant_cpu_to_le16(190);
+				cpu_to_le16(190);
 	cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
-				__constant_cpu_to_le16(390);
+				cpu_to_le16(390);
 	cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
-				__constant_cpu_to_le16(62);
+				cpu_to_le16(62);
 
-	IWL_DEBUG_CALIB("ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
+	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,
 			data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
 			data->nrg_th_ofdm);
 
-	IWL_DEBUG_CALIB("cck: ac %u mrc %u thresh %u\n",
+	IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
 			data->auto_corr_cck, data->auto_corr_cck_mrc,
 			data->nrg_th_cck);
 
@@ -473,7 +473,7 @@ static int iwl_sensitivity_write(struct
 	/* Don't send command to uCode if nothing has changed */
 	if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
 		    sizeof(u16)*HD_TABLE_SIZE)) {
-		IWL_DEBUG_CALIB("No change in SENSITIVITY_CMD\n");
+		IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
 		return 0;
 	}
 
@@ -483,7 +483,7 @@ static int iwl_sensitivity_write(struct
 
 	ret = iwl_send_cmd(priv, &cmd_out);
 	if (ret)
-		IWL_ERROR("SENSITIVITY_CMD failed\n");
+		IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
 
 	return ret;
 }
@@ -498,7 +498,7 @@ void iwl_init_sensitivity(struct iwl_pri
 	if (priv->disable_sens_cal)
 		return;
 
-	IWL_DEBUG_CALIB("Start iwl_init_sensitivity\n");
+	IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n");
 
 	/* Clear driver's sensitivity algo data */
 	data = &(priv->sensitivity_data);
@@ -536,7 +536,7 @@ void iwl_init_sensitivity(struct iwl_pri
 	data->last_fa_cnt_cck = 0;
 
 	ret |= iwl_sensitivity_write(priv);
-	IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
+	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
 }
 EXPORT_SYMBOL(iwl_init_sensitivity);
 
@@ -562,13 +562,13 @@ void iwl_sensitivity_calibration(struct
 	data = &(priv->sensitivity_data);
 
 	if (!iwl_is_associated(priv)) {
-		IWL_DEBUG_CALIB("<< - not associated\n");
+		IWL_DEBUG_CALIB(priv, "<< - not associated\n");
 		return;
 	}
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
-		IWL_DEBUG_CALIB("<< invalid data.\n");
+		IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
 	}
@@ -595,10 +595,10 @@ void iwl_sensitivity_calibration(struct
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	IWL_DEBUG_CALIB("rx_enable_time = %u usecs\n", rx_enable_time);
+	IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
 
 	if (!rx_enable_time) {
-		IWL_DEBUG_CALIB("<< RX Enable Time == 0! \n");
+		IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0! \n");
 		return;
 	}
 
@@ -637,7 +637,7 @@ void iwl_sensitivity_calibration(struct
 	norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
 	norm_fa_cck = fa_cck + bad_plcp_cck;
 
-	IWL_DEBUG_CALIB("cck: fa %u badp %u  ofdm: fa %u badp %u\n", fa_cck,
+	IWL_DEBUG_CALIB(priv, "cck: fa %u badp %u  ofdm: fa %u badp %u\n", fa_cck,
 			bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
 
 	iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
@@ -690,13 +690,13 @@ void iwl_chain_noise_calibration(struct
 	 *   then we're done forever. */
 	if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
 		if (data->state == IWL_CHAIN_NOISE_ALIVE)
-			IWL_DEBUG_CALIB("Wait for noise calib reset\n");
+			IWL_DEBUG_CALIB(priv, "Wait for noise calib reset\n");
 		return;
 	}
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
-		IWL_DEBUG_CALIB(" << Interference data unavailable\n");
+		IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
 	}
@@ -709,7 +709,7 @@ void iwl_chain_noise_calibration(struct
 	/* Make sure we accumulate data for just the associated channel
 	 *   (even if scanning). */
 	if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
-		IWL_DEBUG_CALIB("Stats not from chan=%d, band24=%d\n",
+		IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n",
 				rxon_chnum, rxon_band24);
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
@@ -739,11 +739,11 @@ void iwl_chain_noise_calibration(struct
 	data->chain_signal_b = (chain_sig_b + data->chain_signal_b);
 	data->chain_signal_c = (chain_sig_c + data->chain_signal_c);
 
-	IWL_DEBUG_CALIB("chan=%d, band24=%d, beacon=%d\n",
+	IWL_DEBUG_CALIB(priv, "chan=%d, band24=%d, beacon=%d\n",
 			rxon_chnum, rxon_band24, data->beacon_count);
-	IWL_DEBUG_CALIB("chain_sig: a %d b %d c %d\n",
+	IWL_DEBUG_CALIB(priv, "chain_sig: a %d b %d c %d\n",
 			chain_sig_a, chain_sig_b, chain_sig_c);
-	IWL_DEBUG_CALIB("chain_noise: a %d b %d c %d\n",
+	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:
@@ -773,9 +773,9 @@ void iwl_chain_noise_calibration(struct
 		active_chains = (1 << max_average_sig_antenna_i);
 	}
 
-	IWL_DEBUG_CALIB("average_sig: a %d b %d c %d\n",
+	IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
 		     average_sig[0], average_sig[1], average_sig[2]);
-	IWL_DEBUG_CALIB("max_average_sig = %d, antenna %d\n",
+	IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
 		     max_average_sig, max_average_sig_antenna_i);
 
 	/* Compare signal strengths for all 3 receivers. */
@@ -789,7 +789,7 @@ void iwl_chain_noise_calibration(struct
 				data->disconn_array[i] = 1;
 			else
 				active_chains |= (1 << i);
-			IWL_DEBUG_CALIB("i = %d  rssiDelta = %d  "
+			IWL_DEBUG_CALIB(priv, "i = %d  rssiDelta = %d  "
 			     "disconn_array[i] = %d\n",
 			     i, rssi_delta, data->disconn_array[i]);
 		}
@@ -813,7 +813,7 @@ void iwl_chain_noise_calibration(struct
 			 * disconnected connect it anyway */
 			data->disconn_array[i] = 0;
 			active_chains |= ant_msk;
-			IWL_DEBUG_CALIB("All Tx chains are disconnected W/A - "
+			IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - "
 				"declare %d as connected\n", i);
 			break;
 		}
@@ -821,7 +821,7 @@ void iwl_chain_noise_calibration(struct
 
 	/* Save for use within RXON, TX, SCAN commands, etc. */
 	priv->chain_noise_data.active_chains = active_chains;
-	IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
+	IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
 			active_chains);
 
 	/* Analyze noise for rx balance */
@@ -839,15 +839,16 @@ void iwl_chain_noise_calibration(struct
 		}
 	}
 
-	IWL_DEBUG_CALIB("average_noise: a %d b %d c %d\n",
+	IWL_DEBUG_CALIB(priv, "average_noise: a %d b %d c %d\n",
 			average_noise[0], average_noise[1],
 			average_noise[2]);
 
-	IWL_DEBUG_CALIB("min_average_noise = %d, antenna %d\n",
+	IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n",
 			min_average_noise, min_average_noise_antenna_i);
 
-	priv->cfg->ops->utils->gain_computation(priv, average_noise,
-		min_average_noise_antenna_i, min_average_noise);
+	if (priv->cfg->ops->utils->gain_computation)
+		priv->cfg->ops->utils->gain_computation(priv, average_noise,
+			min_average_noise_antenna_i, min_average_noise);
 
 	/* Some power changes may have been made during the calibration.
 	 * Update and commit the RXON
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-calib.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-commands.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,12 +69,20 @@
 #ifndef __iwl_commands_h__
 #define __iwl_commands_h__
 
+struct iwl_priv;
+
 /* uCode version contains 4 values: Major/Minor/API/Serial */
 #define IWL_UCODE_MAJOR(ver)	(((ver) & 0xFF000000) >> 24)
 #define IWL_UCODE_MINOR(ver)	(((ver) & 0x00FF0000) >> 16)
 #define IWL_UCODE_API(ver)	(((ver) & 0x0000FF00) >> 8)
 #define IWL_UCODE_SERIAL(ver)	((ver) & 0x000000FF)
 
+
+/* Tx rates */
+#define IWL_CCK_RATES	4
+#define IWL_OFDM_RATES	8
+#define IWL_MAX_RATES	(IWL_CCK_RATES + IWL_OFDM_RATES)
+
 enum {
 	REPLY_ALIVE = 0x1,
 	REPLY_ERROR = 0x2,
@@ -136,9 +144,11 @@ enum {
 	WHO_IS_AWAKE_NOTIFICATION = 0x94,	/* not used */
 
 	/* Miscellaneous commands */
+	REPLY_TX_POWER_DBM_CMD = 0x95,
 	QUIET_NOTIFICATION = 0x96,		/* not used */
 	REPLY_TX_PWR_TABLE_CMD = 0x97,
-	REPLY_TX_POWER_DBM_CMD = 0x98,
+	REPLY_TX_POWER_DBM_CMD_V1 = 0x98,	/* old version of API */
+	TX_ANT_CONFIGURATION_CMD = 0x98,	/* not used */
 	MEASURE_ABORT_NOTIFICATION = 0x99,	/* not used */
 
 	/* Bluetooth device coexistence config command */
@@ -219,6 +229,37 @@ struct iwl_cmd_header {
 	u8 data[0];
 } __attribute__ ((packed));
 
+
+/**
+ * struct iwl3945_tx_power
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Each entry contains two values:
+ * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
+ *     linear value that multiplies the output of the digital signal processor,
+ *     before being sent to the analog radio.
+ * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
+ *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
+ */
+struct iwl3945_tx_power {
+	u8 tx_gain;		/* gain for analog radio */
+	u8 dsp_atten;		/* gain for DSP */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_power_per_rate
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl3945_power_per_rate {
+	u8 rate;		/* plcp */
+	struct iwl3945_tx_power tpc;
+	u8 reserved;
+} __attribute__ ((packed));
+
 /**
  * iwlagn rate_n_flags bit fields
  *
@@ -300,11 +341,12 @@ struct iwl_cmd_header {
  * 5350 has 3 transmitters
  * bit14:16
  */
-#define RATE_MCS_ANT_POS      14
-#define RATE_MCS_ANT_A_MSK    0x04000
-#define RATE_MCS_ANT_B_MSK    0x08000
-#define RATE_MCS_ANT_C_MSK    0x10000
-#define RATE_MCS_ANT_ABC_MSK  0x1C000
+#define RATE_MCS_ANT_POS	14
+#define RATE_MCS_ANT_A_MSK	0x04000
+#define RATE_MCS_ANT_B_MSK	0x08000
+#define RATE_MCS_ANT_C_MSK	0x10000
+#define RATE_MCS_ANT_AB_MSK	(RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK)
+#define RATE_MCS_ANT_ABC_MSK	(RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK)
 #define RATE_ANT_NUM 3
 
 #define POWER_TABLE_NUM_ENTRIES			33
@@ -492,8 +534,6 @@ struct iwl_alive_resp {
 	__le32 is_valid;
 } __attribute__ ((packed));
 
-
-
 /*
  * REPLY_ERROR = 0x2 (response only, not a command)
  */
@@ -525,6 +565,7 @@ enum {
 
 
 #define RXON_RX_CHAIN_DRIVER_FORCE_MSK		cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_DRIVER_FORCE_POS		(0)
 #define RXON_RX_CHAIN_VALID_MSK			cpu_to_le16(0x7 << 1)
 #define RXON_RX_CHAIN_VALID_POS			(1)
 #define RXON_RX_CHAIN_FORCE_SEL_MSK		cpu_to_le16(0x7 << 4)
@@ -611,6 +652,26 @@ enum {
  *        issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
  *        regardless of whether RXON_FILTER_ASSOC_MSK is set.
  */
+
+struct iwl3945_rxon_cmd {
+	u8 node_addr[6];
+	__le16 reserved1;
+	u8 bssid_addr[6];
+	__le16 reserved2;
+	u8 wlap_bssid_addr[6];
+	__le16 reserved3;
+	u8 dev_type;
+	u8 air_propagation;
+	__le16 reserved4;
+	u8 ofdm_basic_rates;
+	u8 cck_basic_rates;
+	__le16 assoc_id;
+	__le32 flags;
+	__le32 filter_flags;
+	__le16 channel;
+	__le16 reserved5;
+} __attribute__ ((packed));
+
 struct iwl4965_rxon_cmd {
 	u8 node_addr[6];
 	__le16 reserved1;
@@ -656,33 +717,41 @@ struct iwl_rxon_cmd {
 	__le16 reserved6;
 } __attribute__ ((packed));
 
-struct iwl5000_rxon_assoc_cmd {
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl3945_rxon_assoc_cmd {
+	__le32 flags;
+	__le32 filter_flags;
+	u8 ofdm_basic_rates;
+	u8 cck_basic_rates;
+	__le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl4965_rxon_assoc_cmd {
 	__le32 flags;
 	__le32 filter_flags;
 	u8 ofdm_basic_rates;
 	u8 cck_basic_rates;
-	__le16 reserved1;
 	u8 ofdm_ht_single_stream_basic_rates;
 	u8 ofdm_ht_dual_stream_basic_rates;
-	u8 ofdm_ht_triple_stream_basic_rates;
-	u8 reserved2;
 	__le16 rx_chain_select_flags;
-	__le16 acquisition_data;
-	__le32 reserved3;
+	__le16 reserved;
 } __attribute__ ((packed));
 
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl4965_rxon_assoc_cmd {
+struct iwl5000_rxon_assoc_cmd {
 	__le32 flags;
 	__le32 filter_flags;
 	u8 ofdm_basic_rates;
 	u8 cck_basic_rates;
+	__le16 reserved1;
 	u8 ofdm_ht_single_stream_basic_rates;
 	u8 ofdm_ht_dual_stream_basic_rates;
+	u8 ofdm_ht_triple_stream_basic_rates;
+	u8 reserved2;
 	__le16 rx_chain_select_flags;
-	__le16 reserved;
+	__le16 acquisition_data;
+	__le32 reserved3;
 } __attribute__ ((packed));
 
 #define IWL_CONN_MAX_LISTEN_INTERVAL	10
@@ -702,6 +771,16 @@ struct iwl_rxon_time_cmd {
 /*
  * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
  */
+struct iwl3945_channel_switch_cmd {
+	u8 band;
+	u8 expect_beacon;
+	__le16 channel;
+	__le32 rxon_flags;
+	__le32 rxon_filter_flags;
+	__le32 switch_time;
+	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
 struct iwl_channel_switch_cmd {
 	u8 band;
 	u8 expect_beacon;
@@ -783,6 +862,8 @@ struct iwl_qosparam_cmd {
 #define	IWL_AP_ID		0
 #define IWL_MULTICAST_ID	1
 #define	IWL_STA_ID		2
+#define	IWL3945_BROADCAST_ID	24
+#define IWL3945_STATION_COUNT	25
 #define IWL4965_BROADCAST_ID	31
 #define	IWL4965_STATION_COUNT	32
 #define IWL5000_BROADCAST_ID	15
@@ -791,6 +872,8 @@ struct iwl_qosparam_cmd {
 #define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
 #define	IWL_INVALID_STATION 	255
 
+#define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2);
+#define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
 #define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
 #define STA_FLG_RTS_MIMO_PROT_MSK	cpu_to_le32(1 << 17)
 #define STA_FLG_AGG_MPDU_8US_MSK	cpu_to_le32(1 << 18)
@@ -901,6 +984,35 @@ struct sta_id_modify {
  *        used as AP, or in an IBSS network, driver must set up station table
  *        entries for all STAs in network, starting with index IWL_STA_ID.
  */
+
+struct iwl3945_addsta_cmd {
+	u8 mode;		/* 1: modify existing, 0: add new station */
+	u8 reserved[3];
+	struct sta_id_modify sta;
+	struct iwl4965_keyinfo key;
+	__le32 station_flags;		/* STA_FLG_* */
+	__le32 station_flags_msk;	/* STA_FLG_* */
+
+	/* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+	 * corresponding to bit (e.g. bit 5 controls TID 5).
+	 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+	__le16 tid_disable_tx;
+
+	__le16 rate_n_flags;
+
+	/* TID for which to add block-ack support.
+	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+	u8 add_immediate_ba_tid;
+
+	/* TID for which to remove block-ack support.
+	 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+	u8 remove_immediate_ba_tid;
+
+	/* Starting Sequence Number for added block-ack support.
+	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+	__le16 add_immediate_ba_ssn;
+} __attribute__ ((packed));
+
 struct iwl4965_addsta_cmd {
 	u8 mode;		/* 1: modify existing, 0: add new station */
 	u8 reserved[3];
@@ -1054,6 +1166,48 @@ struct iwl_wep_cmd {
 #define RX_MPDU_RES_STATUS_TTAK_OK	(1 << 7)
 #define RX_MPDU_RES_STATUS_DEC_DONE_MSK	(0x800)
 
+
+struct iwl3945_rx_frame_stats {
+	u8 phy_count;
+	u8 id;
+	u8 rssi;
+	u8 agc;
+	__le16 sig_avg;
+	__le16 noise_diff;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_hdr {
+	__le16 channel;
+	__le16 phy_flags;
+	u8 reserved1;
+	u8 rate;
+	__le16 len;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_end {
+	__le32 status;
+	__le64 timestamp;
+	__le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE:  DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl3945_rx_frame {
+	struct iwl3945_rx_frame_stats stats;
+	struct iwl3945_rx_frame_hdr hdr;
+	struct iwl3945_rx_frame_end end;
+} __attribute__ ((packed));
+
+#define IWL39_RX_FRAME_SIZE	(4 + sizeof(struct iwl3945_rx_frame))
+
 /* Fixed (non-configurable) rx data from phy */
 
 #define IWL49_RX_RES_PHY_CNT 14
@@ -1234,6 +1388,84 @@ struct iwl4965_rx_mpdu_res_start {
 #define TKIP_ICV_LEN 4
 
 /*
+ * REPLY_TX = 0x1c (command)
+ */
+
+struct iwl3945_tx_cmd {
+	/*
+	 * MPDU byte count:
+	 * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+	 * + 8 byte IV for CCM or TKIP (not used for WEP)
+	 * + Data payload
+	 * + 8-byte MIC (not used for CCM/WEP)
+	 * NOTE:  Does not include Tx command bytes, post-MAC pad bytes,
+	 *        MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+	 * Range: 14-2342 bytes.
+	 */
+	__le16 len;
+
+	/*
+	 * MPDU or MSDU byte count for next frame.
+	 * Used for fragmentation and bursting, but not 11n aggregation.
+	 * Same as "len", but for next frame.  Set to 0 if not applicable.
+	 */
+	__le16 next_frame_len;
+
+	__le32 tx_flags;	/* TX_CMD_FLG_* */
+
+	u8 rate;
+
+	/* Index of recipient station in uCode's station table */
+	u8 sta_id;
+	u8 tid_tspec;
+	u8 sec_ctl;
+	u8 key[16];
+	union {
+		u8 byte[8];
+		__le16 word[4];
+		__le32 dw[2];
+	} tkip_mic;
+	__le32 next_frame_info;
+	union {
+		__le32 life_time;
+		__le32 attempt;
+	} stop_time;
+	u8 supp_rates[2];
+	u8 rts_retry_limit;	/*byte 50 */
+	u8 data_retry_limit;	/*byte 51 */
+	union {
+		__le16 pm_frame_timeout;
+		__le16 attempt_duration;
+	} timeout;
+
+	/*
+	 * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+	 * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+	 */
+	__le16 driver_txop;
+
+	/*
+	 * MAC header goes here, followed by 2 bytes padding if MAC header
+	 * length is 26 or 30 bytes, followed by payload data
+	 */
+	u8 payload[0];
+	struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX = 0x1c (response)
+ */
+struct iwl3945_tx_resp {
+	u8 failure_rts;
+	u8 failure_frame;
+	u8 bt_kill_count;
+	u8 rate;
+	__le32 wireless_media_time;
+	__le32 status;		/* TX status */
+} __attribute__ ((packed));
+
+
+/*
  * 4965 uCode updates these Tx attempt count values in host DRAM.
  * Used for managing Tx retries when expecting block-acks.
  * Driver should set these fields to 0.
@@ -1244,9 +1476,6 @@ struct iwl_dram_scratch {
 	__le16 reserved;
 } __attribute__ ((packed));
 
-/*
- * REPLY_TX = 0x1c (command)
- */
 struct iwl_tx_cmd {
 	/*
 	 * MPDU byte count:
@@ -1584,6 +1813,14 @@ struct iwl_compressed_ba_resp {
  *
  * See details under "TXPOWER" in iwl-4965-hw.h.
  */
+
+struct iwl3945_txpowertable_cmd {
+	u8 band;		/* 0: 5 GHz, 1: 2.4 GHz */
+	u8 reserved;
+	__le16 channel;
+	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
 struct iwl4965_txpowertable_cmd {
 	u8 band;		/* 0: 5 GHz, 1: 2.4 GHz */
 	u8 reserved;
@@ -1591,6 +1828,35 @@ struct iwl4965_txpowertable_cmd {
 	struct iwl4965_tx_power_db tx_power;
 } __attribute__ ((packed));
 
+
+/**
+ * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
+ *
+ * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
+ *
+ * NOTE: The table of rates passed to the uCode via the
+ * RATE_SCALE command sets up the corresponding order of
+ * rates used for all related commands, including rate
+ * masks, etc.
+ *
+ * For example, if you set 9MB (PLCP 0x0f) as the first
+ * rate in the rate table, the bit mask for that rate
+ * when passed through ofdm_basic_rates on the REPLY_RXON
+ * command would be bit 0 (1 << 0)
+ */
+struct iwl3945_rate_scaling_info {
+	__le16 rate_n_flags;
+	u8 try_cnt;
+	u8 next_rate_index;
+} __attribute__ ((packed));
+
+struct iwl3945_rate_scaling_cmd {
+	u8 table_id;
+	u8 reserved[3];
+	struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+
 /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
 #define  LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK	(1 << 0)
 
@@ -2044,15 +2310,23 @@ struct iwl_spectrum_notification {
  */
 #define IWL_POWER_VEC_SIZE 5
 
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK	cpu_to_le16(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK		cpu_to_le16(1 << 2)
-#define IWL_POWER_PCI_PM_MSK			cpu_to_le16(1 << 3)
-#define IWL_POWER_FAST_PD			cpu_to_le16(1 << 4)
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK	cpu_to_le16(BIT(0))
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK		cpu_to_le16(BIT(2))
+#define IWL_POWER_PCI_PM_MSK			cpu_to_le16(BIT(3))
+#define IWL_POWER_FAST_PD			cpu_to_le16(BIT(4))
+
+struct iwl3945_powertable_cmd {
+	__le16 flags;
+	u8 reserved[2];
+	__le32 rx_data_timeout;
+	__le32 tx_data_timeout;
+	__le32 sleep_interval[IWL_POWER_VEC_SIZE];
+} __attribute__ ((packed));
 
 struct iwl_powertable_cmd {
 	__le16 flags;
-	u8 keep_alive_seconds;
-	u8 debug_flags;
+	u8 keep_alive_seconds;		/* 3945 reserved */
+	u8 debug_flags;			/* 3945 reserved */
 	__le32 rx_data_timeout;
 	__le32 tx_data_timeout;
 	__le32 sleep_interval[IWL_POWER_VEC_SIZE];
@@ -2143,6 +2417,26 @@ struct iwl_ct_kill_config {
  *     passive_dwell < max_out_time
  *     active_dwell < max_out_time
  */
+
+/* FIXME: rename to AP1, remove tpc */
+struct iwl3945_scan_channel {
+	/*
+	 * type is defined as:
+	 * 0:0 1 = active, 0 = passive
+	 * 1:4 SSID direct bit map; if a bit is set, then corresponding
+	 *     SSID IE is transmitted in probe request.
+	 * 5:7 reserved
+	 */
+	u8 type;
+	u8 channel;	/* band is selected by iwl3945_scan_cmd "flags" field */
+	struct iwl3945_tx_power tpc;
+	__le16 active_dwell;	/* in 1024-uSec TU (time units), typ 5-50 */
+	__le16 passive_dwell;	/* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/* set number of direct probes u8 type */
+#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
+
 struct iwl_scan_channel {
 	/*
 	 * type is defined as:
@@ -2159,6 +2453,9 @@ struct iwl_scan_channel {
 	__le16 passive_dwell;	/* in 1024-uSec TU (time units), typ 20-500 */
 } __attribute__ ((packed));
 
+/* set number of direct probes __le32 type */
+#define IWL_SCAN_PROBE_MASK(n) 	cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
 /**
  * struct iwl_ssid_ie - directed scan network information element
  *
@@ -2172,6 +2469,7 @@ struct iwl_ssid_ie {
 	u8 ssid[32];
 } __attribute__ ((packed));
 
+#define PROBE_OPTION_MAX_API1		0x4
 #define PROBE_OPTION_MAX        	0x14
 #define TX_CMD_LIFE_TIME_INFINITE	cpu_to_le32(0xFFFFFFFF)
 #define IWL_GOOD_CRC_TH			cpu_to_le16(1)
@@ -2229,6 +2527,51 @@ struct iwl_ssid_ie {
  * To avoid uCode errors, see timing restrictions described under
  * struct iwl_scan_channel.
  */
+
+struct iwl3945_scan_cmd {
+	__le16 len;
+	u8 reserved0;
+	u8 channel_count;	/* # channels in channel list */
+	__le16 quiet_time;	/* dwell only this # millisecs on quiet channel
+				 * (only for active scan) */
+	__le16 quiet_plcp_th;	/* quiet chnl is < this # pkts (typ. 1) */
+	__le16 good_CRC_th;	/* passive -> active promotion threshold */
+	__le16 reserved1;
+	__le32 max_out_time;	/* max usec to be away from associated (service)
+				 * channel */
+	__le32 suspend_time;	/* pause scan this long (in "extended beacon
+				 * format") when returning to service channel:
+				 * 3945; 31:24 # beacons, 19:0 additional usec,
+				 * 4965; 31:22 # beacons, 21:0 additional usec.
+				 */
+	__le32 flags;		/* RXON_FLG_* */
+	__le32 filter_flags;	/* RXON_FILTER_* */
+
+	/* For active scans (set to all-0s for passive scans).
+	 * Does not include payload.  Must specify Tx rate; no rate scaling. */
+	struct iwl3945_tx_cmd tx_cmd;
+
+	/* For directed active scans (set to all-0s otherwise) */
+	struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+
+	/*
+	 * Probe request frame, followed by channel list.
+	 *
+	 * Size of probe request frame is specified by byte count in tx_cmd.
+	 * Channel list follows immediately after probe request frame.
+	 * Number of channels in list is specified by channel_count.
+	 * Each channel in list is of type:
+	 *
+	 * struct iwl3945_scan_channel channels[0];
+	 *
+	 * NOTE:  Only one band of channels can be scanned per pass.  You
+	 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+	 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+	 * before requesting another scan.
+	 */
+	u8 data[0];
+} __attribute__ ((packed));
+
 struct iwl_scan_cmd {
 	__le16 len;
 	u8 reserved0;
@@ -2336,6 +2679,14 @@ struct iwl_scancomplete_notification {
 /*
  * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
  */
+
+struct iwl3945_beacon_notif {
+	struct iwl3945_tx_resp beacon_notify_hdr;
+	__le32 low_tsf;
+	__le32 high_tsf;
+	__le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
 struct iwl4965_beacon_notif {
 	struct iwl4965_tx_resp beacon_notify_hdr;
 	__le32 low_tsf;
@@ -2346,6 +2697,15 @@ struct iwl4965_beacon_notif {
 /*
  * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
  */
+
+struct iwl3945_tx_beacon_cmd {
+	struct iwl3945_tx_cmd tx;
+	__le16 tim_idx;
+	u8 tim_size;
+	u8 reserved1;
+	struct ieee80211_hdr frame[0];	/* beacon frame */
+} __attribute__ ((packed));
+
 struct iwl_tx_beacon_cmd {
 	struct iwl_tx_cmd tx;
 	__le16 tim_idx;
@@ -2382,6 +2742,76 @@ struct rate_histogram {
 
 /* statistics command response */
 
+struct iwl39_statistics_rx_phy {
+	__le32 ina_cnt;
+	__le32 fina_cnt;
+	__le32 plcp_err;
+	__le32 crc32_err;
+	__le32 overrun_err;
+	__le32 early_overrun_err;
+	__le32 crc32_good;
+	__le32 false_alarm_cnt;
+	__le32 fina_sync_err_cnt;
+	__le32 sfd_timeout;
+	__le32 fina_timeout;
+	__le32 unresponded_rts;
+	__le32 rxe_frame_limit_overrun;
+	__le32 sent_ack_cnt;
+	__le32 sent_cts_cnt;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx_non_phy {
+	__le32 bogus_cts;	/* CTS received when not expecting CTS */
+	__le32 bogus_ack;	/* ACK received when not expecting ACK */
+	__le32 non_bssid_frames;	/* number of frames with BSSID that
+					 * doesn't belong to the STA BSSID */
+	__le32 filtered_frames;	/* count frames that were dumped in the
+				 * filtering process */
+	__le32 non_channel_beacons;	/* beacons with our bss id but not on
+					 * our serving channel */
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx {
+	struct iwl39_statistics_rx_phy ofdm;
+	struct iwl39_statistics_rx_phy cck;
+	struct iwl39_statistics_rx_non_phy general;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_tx {
+	__le32 preamble_cnt;
+	__le32 rx_detected_cnt;
+	__le32 bt_prio_defer_cnt;
+	__le32 bt_prio_kill_cnt;
+	__le32 few_bytes_cnt;
+	__le32 cts_timeout;
+	__le32 ack_timeout;
+	__le32 expected_ack_cnt;
+	__le32 actual_ack_cnt;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+	__le32 burst_check;
+	__le32 burst_count;
+	__le32 reserved[4];
+} __attribute__ ((packed));
+
+struct iwl39_statistics_div {
+	__le32 tx_on_a;
+	__le32 tx_on_b;
+	__le32 exec_time;
+	__le32 probe_time;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_general {
+	__le32 temperature;
+	struct statistics_dbg dbg;
+	__le32 sleep_time;
+	__le32 slots_out;
+	__le32 slots_idle;
+	__le32 ttl_timestamp;
+	struct iwl39_statistics_div div;
+} __attribute__ ((packed));
+
 struct statistics_rx_phy {
 	__le32 ina_cnt;
 	__le32 fina_cnt;
@@ -2418,7 +2848,7 @@ struct statistics_rx_ht_phy {
 	__le32 reserved2;
 } __attribute__ ((packed));
 
-#define INTERFERENCE_DATA_AVAILABLE      __constant_cpu_to_le32(1)
+#define INTERFERENCE_DATA_AVAILABLE      cpu_to_le32(1)
 
 struct statistics_rx_non_phy {
 	__le32 bogus_cts;	/* CTS received when not expecting CTS */
@@ -2493,11 +2923,6 @@ struct statistics_tx {
 	struct statistics_tx_non_phy_agg agg;
 } __attribute__ ((packed));
 
-struct statistics_dbg {
-	__le32 burst_check;
-	__le32 burst_count;
-	__le32 reserved[4];
-} __attribute__ ((packed));
 
 struct statistics_div {
 	__le32 tx_on_a;
@@ -2561,6 +2986,14 @@ struct iwl_statistics_cmd {
  */
 #define STATISTICS_REPLY_FLG_BAND_24G_MSK         cpu_to_le32(0x2)
 #define STATISTICS_REPLY_FLG_FAT_MODE_MSK         cpu_to_le32(0x8)
+
+struct iwl3945_notif_statistics {
+	__le32 flag;
+	struct iwl39_statistics_rx rx;
+	struct iwl39_statistics_tx tx;
+	struct iwl39_statistics_general general;
+} __attribute__ ((packed));
+
 struct iwl_notif_statistics {
 	__le32 flag;
 	struct statistics_rx rx;
@@ -3012,6 +3445,10 @@ struct iwl_rx_packet {
 	__le32 len;
 	struct iwl_cmd_header hdr;
 	union {
+		struct iwl3945_rx_frame rx_frame;
+		struct iwl3945_tx_resp tx_resp;
+		struct iwl3945_beacon_notif beacon_status;
+
 		struct iwl_alive_resp alive_frame;
 		struct iwl_spectrum_notification spectrum_notif;
 		struct iwl_csa_notification csa_notif;
@@ -3029,6 +3466,6 @@ struct iwl_rx_packet {
 	} u;
 } __attribute__ ((packed));
 
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
+int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
 
 #endif				/* __iwl_commands_h__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-core.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
@@ -170,7 +171,8 @@ struct ieee80211_hw *iwl_alloc_all(struc
 	struct ieee80211_hw *hw =
 		ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
 	if (hw == NULL) {
-		IWL_ERROR("Can not allocate network device\n");
+		printk(KERN_ERR "%s: Can not allocate network device\n",
+		       cfg->name);
 		goto out;
 	}
 
@@ -210,7 +212,7 @@ int iwl_hw_nic_init(struct iwl_priv *pri
 	if (!rxq->bd) {
 		ret = iwl_rx_queue_alloc(priv);
 		if (ret) {
-			IWL_ERROR("Unable to initialize Rx queue\n");
+			IWL_ERR(priv, "Unable to initialize Rx queue\n");
 			return -ENOMEM;
 		}
 	} else
@@ -238,6 +240,39 @@ int iwl_hw_nic_init(struct iwl_priv *pri
 }
 EXPORT_SYMBOL(iwl_hw_nic_init);
 
+/*
+ * QoS  support
+*/
+void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+{
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	priv->qos_data.def_qos_parm.qos_flags = 0;
+
+	if (priv->qos_data.qos_cap.q_AP.queue_request &&
+	    !priv->qos_data.qos_cap.q_AP.txop_request)
+		priv->qos_data.def_qos_parm.qos_flags |=
+			QOS_PARAM_FLG_TXOP_TYPE_MSK;
+	if (priv->qos_data.qos_active)
+		priv->qos_data.def_qos_parm.qos_flags |=
+			QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+	if (priv->current_ht_config.is_ht)
+		priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+	if (force || iwl_is_associated(priv)) {
+		IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+				priv->qos_data.qos_active,
+				priv->qos_data.def_qos_parm.qos_flags);
+
+		iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+				       sizeof(struct iwl_qosparam_cmd),
+				       &priv->qos_data.def_qos_parm, NULL);
+	}
+}
+EXPORT_SYMBOL(iwl_activate_qos);
+
 void iwl_reset_qos(struct iwl_priv *priv)
 {
 	u16 cw_min = 15;
@@ -321,7 +356,7 @@ void iwl_reset_qos(struct iwl_priv *priv
 			priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
 		}
 	}
-	IWL_DEBUG_QOS("set QoS to default \n");
+	IWL_DEBUG_QOS(priv, "set QoS to default \n");
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
@@ -402,10 +437,11 @@ static void iwlcore_init_hw_rates(struct
 	}
 }
 
+
 /**
  * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
  */
-static int iwlcore_init_geos(struct iwl_priv *priv)
+int iwlcore_init_geos(struct iwl_priv *priv)
 {
 	struct iwl_channel_info *ch;
 	struct ieee80211_supported_band *sband;
@@ -416,7 +452,7 @@ static int iwlcore_init_geos(struct iwl_
 
 	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
 	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
-		IWL_DEBUG_INFO("Geography modes already initialized.\n");
+		IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
 		set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 		return 0;
 	}
@@ -457,8 +493,6 @@ static int iwlcore_init_geos(struct iwl_
 	priv->ieee_channels = channels;
 	priv->ieee_rates = rates;
 
-	iwlcore_init_hw_rates(priv, rates);
-
 	for (i = 0;  i < priv->channel_count; i++) {
 		ch = &priv->channel_info[i];
 
@@ -500,7 +534,7 @@ static int iwlcore_init_geos(struct iwl_
 		/* Save flags for reg domain usage */
 		geo_ch->orig_flags = geo_ch->flags;
 
-		IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
+		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
 				ch->channel, geo_ch->center_freq,
 				is_channel_a_band(ch) ?  "5.2" : "2.4",
 				geo_ch->flags & IEEE80211_CHAN_DISABLED ?
@@ -510,33 +544,33 @@ static int iwlcore_init_geos(struct iwl_
 
 	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
 	     priv->cfg->sku & IWL_SKU_A) {
-		printk(KERN_INFO DRV_NAME
-		       ": Incorrectly detected BG card as ABG.  Please send "
-		       "your PCI ID 0x%04X:0x%04X to maintainer.\n",
-		       priv->pci_dev->device, priv->pci_dev->subsystem_device);
+		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
+			"Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
+			   priv->pci_dev->device,
+			   priv->pci_dev->subsystem_device);
 		priv->cfg->sku &= ~IWL_SKU_A;
 	}
 
-	printk(KERN_INFO DRV_NAME
-	       ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
-	       priv->bands[IEEE80211_BAND_2GHZ].n_channels,
-	       priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
+	IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
+		   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+		   priv->bands[IEEE80211_BAND_5GHZ].n_channels);
 
 	set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 
 	return 0;
 }
+EXPORT_SYMBOL(iwlcore_init_geos);
 
 /*
  * iwlcore_free_geos - undo allocations in iwlcore_init_geos
  */
-static void iwlcore_free_geos(struct iwl_priv *priv)
+void iwlcore_free_geos(struct iwl_priv *priv)
 {
 	kfree(priv->ieee_channels);
 	kfree(priv->ieee_rates);
 	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
 }
+EXPORT_SYMBOL(iwlcore_free_geos);
 
 static bool is_single_rx_stream(struct iwl_priv *priv)
 {
@@ -587,6 +621,167 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv
 }
 EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
 
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+{
+	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+	if (hw_decrypt)
+		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
+	else
+		rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
+
+}
+EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
+
+/**
+ * iwl_check_rxon_cmd - validate RXON structure is valid
+ *
+ * NOTE:  This is really only useful during development and can eventually
+ * be #ifdef'd out once the driver is stable and folks aren't actively
+ * making changes
+ */
+int iwl_check_rxon_cmd(struct iwl_priv *priv)
+{
+	int error = 0;
+	int counter = 1;
+	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
+		error |= le32_to_cpu(rxon->flags &
+				(RXON_FLG_TGJ_NARROW_BAND_MSK |
+				 RXON_FLG_RADAR_DETECT_MSK));
+		if (error)
+			IWL_WARN(priv, "check 24G fields %d | %d\n",
+				    counter++, error);
+	} else {
+		error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
+				0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
+		if (error)
+			IWL_WARN(priv, "check 52 fields %d | %d\n",
+				    counter++, error);
+		error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
+		if (error)
+			IWL_WARN(priv, "check 52 CCK %d | %d\n",
+				    counter++, error);
+	}
+	error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
+	if (error)
+		IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+
+	/* make sure basic rates 6Mbps and 1Mbps are supported */
+	error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
+		  ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
+	if (error)
+		IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+
+	error |= (le16_to_cpu(rxon->assoc_id) > 2007);
+	if (error)
+		IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+
+	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
+			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
+	if (error)
+		IWL_WARN(priv, "check CCK and short slot %d | %d\n",
+			    counter++, error);
+
+	error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
+			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
+	if (error)
+		IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
+			    counter++, error);
+
+	error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
+			RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
+	if (error)
+		IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
+			    counter++, error);
+
+	if (error)
+		IWL_WARN(priv, "Tuning to channel %d\n",
+			    le16_to_cpu(rxon->channel));
+
+	if (error) {
+		IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
+		return -1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(iwl_check_rxon_cmd);
+
+/**
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * @priv: staging_rxon is compared to active_rxon
+ *
+ * If the RXON structure is changing enough to require a new tune,
+ * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
+ * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
+ */
+int iwl_full_rxon_required(struct iwl_priv *priv)
+{
+
+	/* These items are only settable from the full RXON command */
+	if (!(iwl_is_associated(priv)) ||
+	    compare_ether_addr(priv->staging_rxon.bssid_addr,
+			       priv->active_rxon.bssid_addr) ||
+	    compare_ether_addr(priv->staging_rxon.node_addr,
+			       priv->active_rxon.node_addr) ||
+	    compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
+			       priv->active_rxon.wlap_bssid_addr) ||
+	    (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
+	    (priv->staging_rxon.channel != priv->active_rxon.channel) ||
+	    (priv->staging_rxon.air_propagation !=
+	     priv->active_rxon.air_propagation) ||
+	    (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
+	     priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
+	    (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
+	     priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+	    (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
+		return 1;
+
+	/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
+	 * be updated with the RXON_ASSOC command -- however only some
+	 * flag transitions are allowed using RXON_ASSOC */
+
+	/* Check if we are not switching bands */
+	if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
+	    (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
+		return 1;
+
+	/* Check if we are switching association toggle */
+	if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
+		(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(iwl_full_rxon_required);
+
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
+{
+	int i;
+	int rate_mask;
+
+	/* Set rate mask*/
+	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+		rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
+	else
+		rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
+
+	/* Find lowest valid rate */
+	for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
+					i = iwl_rates[i].next_ieee) {
+		if (rate_mask & (1 << i))
+			return iwl_rates[i].plcp;
+	}
+
+	/* No valid rate was found. Assign the lowest one */
+	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+		return IWL_RATE_1M_PLCP;
+	else
+		return IWL_RATE_6M_PLCP;
+}
+EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
+
 void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 {
 	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
@@ -628,7 +823,7 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
 
 	iwl_set_rxon_chain(priv);
 
-	IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
+	IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
 			"rxon flags 0x%X operation mode :0x%X "
 			"extension channel offset 0x%x\n",
 			ht_info->mcs.rx_mask[0],
@@ -679,7 +874,7 @@ static int iwl_get_idle_rx_chain_count(s
 		break;
 	case WLAN_HT_CAP_SM_PS_INVALID:
 	default:
-		IWL_ERROR("invalid mimo ps mode %d\n",
+		IWL_ERR(priv, "invalid mimo ps mode %d\n",
 			   priv->current_ht_config.sm_ps);
 		WARN_ON(1);
 		idle_cnt = -1;
@@ -700,6 +895,18 @@ static u8 iwl_count_chain_bitmap(u32 cha
 }
 
 /**
+ * iwl_is_monitor_mode - Determine if interface in monitor mode
+ *
+ * priv->iw_mode is set in add_interface, but add_interface is
+ * never called for monitor mode. The only way mac80211 informs us about
+ * monitor mode is through configuring filters (call to configure_filter).
+ */
+static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+{
+	return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
+}
+
+/**
  * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
  *
  * Selects how many and which Rx receivers/antennas/chains to use.
@@ -742,6 +949,19 @@ void iwl_set_rxon_chain(struct iwl_priv
 	rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
 	rx_chain |= idle_rx_cnt  << RXON_RX_CHAIN_CNT_POS;
 
+	/* copied from 'iwl_bg_request_scan()' */
+	/* Force use of chains B and C (0x6) for Rx for 4965
+	 * Avoid A (0x1) because of its off-channel reception on A-band.
+	 * MIMO is not used here, but value is required */
+	if (iwl_is_monitor_mode(priv) &&
+	    !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
+	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
+		rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
+		rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
+		rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+		rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+	}
+
 	priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
 
 	if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -749,7 +969,7 @@ void iwl_set_rxon_chain(struct iwl_priv
 	else
 		priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
 
-	IWL_DEBUG_ASSOC("rx_chain=0x%X active=%d idle=%d\n",
+	IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
 			priv->staging_rxon.rx_chain,
 			active_rx_cnt, idle_rx_cnt);
 
@@ -774,7 +994,7 @@ int iwl_set_rxon_channel(struct iwl_priv
 	u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
 
 	if (!iwl_get_channel_info(priv, band, channel)) {
-		IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
+		IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n",
 			       channel, band);
 		return -EINVAL;
 	}
@@ -791,12 +1011,283 @@ int iwl_set_rxon_channel(struct iwl_priv
 
 	priv->band = band;
 
-	IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
+	IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
 
 	return 0;
 }
 EXPORT_SYMBOL(iwl_set_rxon_channel);
 
+void iwl_set_flags_for_band(struct iwl_priv *priv,
+			    enum ieee80211_band band)
+{
+	if (band == IEEE80211_BAND_5GHZ) {
+		priv->staging_rxon.flags &=
+		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
+		      | RXON_FLG_CCK_MSK);
+		priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+	} else {
+		/* Copied from iwl_post_associate() */
+		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+			priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+		else
+			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+		if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+		priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+		priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
+		priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+	}
+}
+EXPORT_SYMBOL(iwl_set_flags_for_band);
+
+/*
+ * initialize rxon structure with default values from eeprom
+ */
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
+{
+	const struct iwl_channel_info *ch_info;
+
+	memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
+
+	switch (mode) {
+	case NL80211_IFTYPE_AP:
+		priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+		break;
+
+	case NL80211_IFTYPE_STATION:
+		priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
+		priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+		break;
+
+	case NL80211_IFTYPE_ADHOC:
+		priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
+		priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+		priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+						  RXON_FILTER_ACCEPT_GRP_MSK;
+		break;
+
+	case NL80211_IFTYPE_MONITOR:
+		priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
+		priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
+		    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
+		break;
+	default:
+		IWL_ERR(priv, "Unsupported interface type %d\n", mode);
+		break;
+	}
+
+#if 0
+	/* TODO:  Figure out when short_preamble would be set and cache from
+	 * that */
+	if (!hw_to_local(priv->hw)->short_preamble)
+		priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+	else
+		priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+#endif
+
+	ch_info = iwl_get_channel_info(priv, priv->band,
+				       le16_to_cpu(priv->active_rxon.channel));
+
+	if (!ch_info)
+		ch_info = &priv->channel_info[0];
+
+	/*
+	 * in some case A channels are all non IBSS
+	 * in this case force B/G channel
+	 */
+	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
+	    !(is_channel_ibss(ch_info)))
+		ch_info = &priv->channel_info[0];
+
+	priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+	priv->band = ch_info->band;
+
+	iwl_set_flags_for_band(priv, priv->band);
+
+	priv->staging_rxon.ofdm_basic_rates =
+	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+	priv->staging_rxon.cck_basic_rates =
+	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+
+	priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
+					RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
+	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+	memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
+	priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
+	priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
+}
+EXPORT_SYMBOL(iwl_connection_init_rx_config);
+
+void iwl_set_rate(struct iwl_priv *priv)
+{
+	const struct ieee80211_supported_band *hw = NULL;
+	struct ieee80211_rate *rate;
+	int i;
+
+	hw = iwl_get_hw_mode(priv, priv->band);
+	if (!hw) {
+		IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
+		return;
+	}
+
+	priv->active_rate = 0;
+	priv->active_rate_basic = 0;
+
+	for (i = 0; i < hw->n_bitrates; i++) {
+		rate = &(hw->bitrates[i]);
+		if (rate->hw_value < IWL_RATE_COUNT)
+			priv->active_rate |= (1 << rate->hw_value);
+	}
+
+	IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n",
+		       priv->active_rate, priv->active_rate_basic);
+
+	/*
+	 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
+	 * otherwise set it to the default of all CCK rates and 6, 12, 24 for
+	 * OFDM
+	 */
+	if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
+		priv->staging_rxon.cck_basic_rates =
+		    ((priv->active_rate_basic &
+		      IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
+	else
+		priv->staging_rxon.cck_basic_rates =
+		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+
+	if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
+		priv->staging_rxon.ofdm_basic_rates =
+		    ((priv->active_rate_basic &
+		      (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
+		      IWL_FIRST_OFDM_RATE) & 0xFF;
+	else
+		priv->staging_rxon.ofdm_basic_rates =
+		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+}
+EXPORT_SYMBOL(iwl_set_rate);
+
+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_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;
+}
+EXPORT_SYMBOL(iwl_rx_csa);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+{
+	struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+	IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
+	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+	IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
+	IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
+	IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
+			le32_to_cpu(rxon->filter_flags));
+	IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
+	IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
+			rxon->ofdm_basic_rates);
+	IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
+	IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
+	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));
+}
+#endif
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
+	/* Set the FW error flag -- cleared on iwl_down */
+	set_bit(STATUS_FW_ERROR, &priv->status);
+
+	/* Cancel currently queued command. */
+	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (priv->debug_level & IWL_DL_FW_ERRORS) {
+		iwl_dump_nic_error_log(priv);
+		iwl_dump_nic_event_log(priv);
+		iwl_print_rx_config_cmd(priv);
+	}
+#endif
+
+	wake_up_interruptible(&priv->wait_command_queue);
+
+	/* Keep the restart process from trying to send host
+	 * commands by clearing the INIT status bit */
+	clear_bit(STATUS_READY, &priv->status);
+
+	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+		IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+			  "Restarting adapter due to uCode error.\n");
+
+		if (iwl_is_associated(priv)) {
+			memcpy(&priv->recovery_rxon, &priv->active_rxon,
+			       sizeof(priv->recovery_rxon));
+			priv->error_recovering = 1;
+		}
+		if (priv->cfg->mod_params->restart_fw)
+			queue_work(priv->workqueue, &priv->restart);
+	}
+}
+EXPORT_SYMBOL(iwl_irq_handle_error);
+
+void iwl_configure_filter(struct ieee80211_hw *hw,
+			  unsigned int changed_flags,
+			  unsigned int *total_flags,
+			  int mc_count, struct dev_addr_list *mc_list)
+{
+	struct iwl_priv *priv = hw->priv;
+	__le32 *filter_flags = &priv->staging_rxon.filter_flags;
+
+	IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
+			changed_flags, *total_flags);
+
+	if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+		if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+			*filter_flags |= RXON_FILTER_PROMISC_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+	}
+	if (changed_flags & FIF_ALLMULTI) {
+		if (*total_flags & FIF_ALLMULTI)
+			*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
+	}
+	if (changed_flags & FIF_CONTROL) {
+		if (*total_flags & FIF_CONTROL)
+			*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+	}
+	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+			*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+		else
+			*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
+	}
+
+	/* We avoid iwl_commit_rxon here to commit the new filter flags
+	 * since mac80211 will call ieee80211_hw_config immediately.
+	 * (mc_list is not supported at this time). Otherwise, we need to
+	 * queue a background iwl_commit_rxon work.
+	 */
+
+	*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
+			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
+}
+EXPORT_SYMBOL(iwl_configure_filter);
+
 int iwl_setup_mac(struct iwl_priv *priv)
 {
 	int ret;
@@ -806,18 +1297,18 @@ int iwl_setup_mac(struct iwl_priv *priv)
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		    IEEE80211_HW_NOISE_DBM |
-		    IEEE80211_HW_AMPDU_AGGREGATION;
+		    IEEE80211_HW_AMPDU_AGGREGATION |
+		    IEEE80211_HW_SPECTRUM_MGMT |
+		    IEEE80211_HW_SUPPORTS_PS;
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->wiphy->fw_handles_regulatory = true;
+	hw->wiphy->custom_regulatory = true;
+	hw->wiphy->max_scan_ssids = 1;
 
 	/* Default value; 4 EDCA QOS priorities */
 	hw->queues = 4;
-	/* queues to support 11n aggregation */
-	if (priv->cfg->sku & IWL_SKU_N)
-		hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
 
 	hw->conf.beacon_int = 100;
 	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
@@ -831,7 +1322,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
 
 	ret = ieee80211_register_hw(priv->hw);
 	if (ret) {
-		IWL_ERROR("Failed to register hw (error %d)\n", ret);
+		IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
 		return ret;
 	}
 	priv->mac80211_registered = 1;
@@ -863,7 +1354,6 @@ int iwl_init_drv(struct iwl_priv *priv)
 {
 	int ret;
 
-	priv->retry_rate = 1;
 	priv->ibss_beacon = NULL;
 
 	spin_lock_init(&priv->lock);
@@ -897,21 +1387,22 @@ int iwl_init_drv(struct iwl_priv *priv)
 	priv->qos_data.qos_cap.val = 0;
 
 	priv->rates_mask = IWL_RATES_MASK;
-	/* If power management is turned on, default to AC mode */
-	priv->power_mode = IWL_POWER_AC;
+	/* If power management is turned on, default to CAM mode */
+	priv->power_mode = IWL_POWER_MODE_CAM;
 	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
 
 	ret = iwl_init_channel_map(priv);
 	if (ret) {
-		IWL_ERROR("initializing regulatory failed: %d\n", ret);
+		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
 		goto err;
 	}
 
 	ret = iwlcore_init_geos(priv);
 	if (ret) {
-		IWL_ERROR("initializing geos failed: %d\n", 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;
 
@@ -926,14 +1417,16 @@ int iwl_set_tx_power(struct iwl_priv *pr
 {
 	int ret = 0;
 	if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
-		IWL_WARNING("Requested user TXPOWER %d below limit.\n",
-			    priv->tx_power_user_lmt);
+		IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n",
+			 tx_power,
+			 IWL_TX_POWER_TARGET_POWER_MIN);
 		return -EINVAL;
 	}
 
 	if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
-		IWL_WARNING("Requested user TXPOWER %d above limit.\n",
-			    priv->tx_power_user_lmt);
+		IWL_WARN(priv, "Requested user TXPOWER %d above upper limit %d.\n",
+			 tx_power,
+			 IWL_TX_POWER_TARGET_POWER_MAX);
 		return -EINVAL;
 	}
 
@@ -942,6 +1435,10 @@ int iwl_set_tx_power(struct iwl_priv *pr
 
 	priv->tx_power_user_lmt = tx_power;
 
+	/* if nic is not up don't send command */
+	if (!iwl_is_ready_rf(priv))
+		return ret;
+
 	if (force && priv->cfg->ops->lib->send_tx_power)
 		ret = priv->cfg->ops->lib->send_tx_power(priv);
 
@@ -970,18 +1467,92 @@ void iwl_disable_interrupts(struct iwl_p
 	 * from uCode or flow handler (Rx/Tx DMA) */
 	iwl_write32(priv, CSR_INT, 0xffffffff);
 	iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
-	IWL_DEBUG_ISR("Disabled interrupts\n");
+	IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
 }
 EXPORT_SYMBOL(iwl_disable_interrupts);
 
 void iwl_enable_interrupts(struct iwl_priv *priv)
 {
-	IWL_DEBUG_ISR("Enabling interrupts\n");
+	IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
 	set_bit(STATUS_INT_ENABLED, &priv->status);
 	iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
 }
 EXPORT_SYMBOL(iwl_enable_interrupts);
 
+irqreturn_t iwl_isr(int irq, void *data)
+{
+	struct iwl_priv *priv = data;
+	u32 inta, inta_mask;
+	u32 inta_fh;
+	if (!priv)
+		return IRQ_NONE;
+
+	spin_lock(&priv->lock);
+
+	/* Disable (but don't clear!) interrupts here to avoid
+	 *    back-to-back ISRs and sporadic interrupts from our NIC.
+	 * If we have something to service, the tasklet will re-enable ints.
+	 * If we *don't* have something, we'll re-enable before leaving here. */
+	inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+	iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+	/* Discover which interrupts are active/pending */
+	inta = iwl_read32(priv, CSR_INT);
+	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+
+	/* Ignore interrupt if there's nothing in NIC to service.
+	 * This may be due to IRQ shared with another device,
+	 * or due to sporadic interrupts thrown from our NIC. */
+	if (!inta && !inta_fh) {
+		IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n");
+		goto none;
+	}
+
+	if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+		/* Hardware disappeared. It might have already raised
+		 * an interrupt */
+		IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+		goto unplugged;
+	}
+
+	IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+		      inta, inta_mask, inta_fh);
+
+	inta &= ~CSR_INT_BIT_SCD;
+
+	/* iwl_irq_tasklet() will service interrupts and re-enable them */
+	if (likely(inta || inta_fh))
+		tasklet_schedule(&priv->irq_tasklet);
+
+ unplugged:
+	spin_unlock(&priv->lock);
+	return IRQ_HANDLED;
+
+ none:
+	/* re-enable interrupts here since we don't have anything to service. */
+	/* only Re-enable if diabled by irq */
+	if (test_bit(STATUS_INT_ENABLED, &priv->status))
+		iwl_enable_interrupts(priv);
+	spin_unlock(&priv->lock);
+	return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr);
+
+int iwl_send_bt_config(struct iwl_priv *priv)
+{
+	struct iwl_bt_cmd bt_cmd = {
+		.flags = 3,
+		.lead_time = 0xAA,
+		.max_kill = 1,
+		.kill_ack_mask = 0,
+		.kill_cts_mask = 0,
+	};
+
+	return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+				sizeof(struct iwl_bt_cmd), &bt_cmd);
+}
+EXPORT_SYMBOL(iwl_send_bt_config);
+
 int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
 {
 	u32 stat_flags = 0;
@@ -1007,7 +1578,7 @@ static int iwlcore_verify_inst_sparse(st
 	u32 errcnt = 0;
 	u32 i;
 
-	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
 	ret = iwl_grab_nic_access(priv);
 	if (ret)
@@ -1018,7 +1589,7 @@ static int iwlcore_verify_inst_sparse(st
 		/* NOTE: Use the debugless read so we don't flood kernel log
 		 * if IWL_DL_IO is set */
 		iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
-			i + RTC_INST_LOWER_BOUND);
+			i + IWL49_RTC_INST_LOWER_BOUND);
 		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
 			ret = -EIO;
@@ -1045,13 +1616,14 @@ static int iwl_verify_inst_full(struct i
 	int ret = 0;
 	u32 errcnt;
 
-	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
 	ret = iwl_grab_nic_access(priv);
 	if (ret)
 		return ret;
 
-	iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+	iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+			   IWL49_RTC_INST_LOWER_BOUND);
 
 	errcnt = 0;
 	for (; len > 0; len -= sizeof(u32), image++) {
@@ -1060,7 +1632,7 @@ static int iwl_verify_inst_full(struct i
 		 * if IWL_DL_IO is set */
 		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
-			IWL_ERROR("uCode INST section is invalid at "
+			IWL_ERR(priv, "uCode INST section is invalid at "
 				  "offset 0x%x, is 0x%x, s/b 0x%x\n",
 				  save_len - len, val, le32_to_cpu(*image));
 			ret = -EIO;
@@ -1073,8 +1645,8 @@ static int iwl_verify_inst_full(struct i
 	iwl_release_nic_access(priv);
 
 	if (!errcnt)
-		IWL_DEBUG_INFO
-		    ("ucode image in INSTRUCTION memory is good\n");
+		IWL_DEBUG_INFO(priv,
+		    "ucode image in INSTRUCTION memory is good\n");
 
 	return ret;
 }
@@ -1094,7 +1666,7 @@ int iwl_verify_ucode(struct iwl_priv *pr
 	len = priv->ucode_boot.len;
 	ret = iwlcore_verify_inst_sparse(priv, image, len);
 	if (!ret) {
-		IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
 		return 0;
 	}
 
@@ -1103,7 +1675,7 @@ int iwl_verify_ucode(struct iwl_priv *pr
 	len = priv->ucode_init.len;
 	ret = iwlcore_verify_inst_sparse(priv, image, len);
 	if (!ret) {
-		IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
 		return 0;
 	}
 
@@ -1112,11 +1684,11 @@ int iwl_verify_ucode(struct iwl_priv *pr
 	len = priv->ucode_code.len;
 	ret = iwlcore_verify_inst_sparse(priv, image, len);
 	if (!ret) {
-		IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+		IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
 		return 0;
 	}
 
-	IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+	IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
 
 	/* Since nothing seems to match, show first several data entries in
 	 * instruction SRAM, so maybe visual inspection will give a clue.
@@ -1188,21 +1760,22 @@ 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_ERROR("Not valid error log pointer 0x%08X\n", base);
+		IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
 		return;
 	}
 
 	ret = iwl_grab_nic_access(priv);
 	if (ret) {
-		IWL_WARNING("Can not read from adapter at this time.\n");
+		IWL_WARN(priv, "Can not read from adapter at this time.\n");
 		return;
 	}
 
 	count = iwl_read_targ_mem(priv, base);
 
 	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
-		IWL_ERROR("Start IWL Error Log Dump:\n");
-		IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+		IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+		IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+			priv->status, count);
 	}
 
 	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -1215,12 +1788,12 @@ 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));
 
-	IWL_ERROR("Desc                               Time       "
+	IWL_ERR(priv, "Desc                               Time       "
 		"data1      data2      line\n");
-	IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+	IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
 		desc_lookup(desc), desc, time, data1, data2, line);
-	IWL_ERROR("blink1  blink2  ilink1  ilink2\n");
-	IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+	IWL_ERR(priv, "blink1  blink2  ilink1  ilink2\n");
+	IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
 		ilink1, ilink2);
 
 	iwl_release_nic_access(priv);
@@ -1266,11 +1839,11 @@ static void iwl_print_event_log(struct i
 		ptr += sizeof(u32);
 		if (mode == 0) {
 			/* data, ev */
-			IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+			IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
 		} else {
 			data = iwl_read_targ_mem(priv, ptr);
 			ptr += sizeof(u32);
-			IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+			IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
 					time, data, ev);
 		}
 	}
@@ -1292,13 +1865,13 @@ 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_ERROR("Invalid event log pointer 0x%08X\n", base);
+		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
 		return;
 	}
 
 	ret = iwl_grab_nic_access(priv);
 	if (ret) {
-		IWL_WARNING("Can not read from adapter at this time.\n");
+		IWL_WARN(priv, "Can not read from adapter at this time.\n");
 		return;
 	}
 
@@ -1312,12 +1885,12 @@ void iwl_dump_nic_event_log(struct iwl_p
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
+		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
 		iwl_release_nic_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+	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,
@@ -1349,9 +1922,9 @@ void iwl_rf_kill_ct_config(struct iwl_pr
 	ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
 			       sizeof(cmd), &cmd);
 	if (ret)
-		IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+		IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
 	else
-		IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
+		IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD succeeded, "
 			"critical temperature is %d\n",
 			cmd.critical_temperature_R);
 }
@@ -1368,7 +1941,7 @@ EXPORT_SYMBOL(iwl_rf_kill_ct_config);
  * When in the 'halt' state, the card is shut down and must be fully
  * restarted to come back on.
  */
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
 {
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_CARD_STATE_CMD,
@@ -1379,6 +1952,7 @@ static int iwl_send_card_state(struct iw
 
 	return iwl_send_cmd(priv, &cmd);
 }
+EXPORT_SYMBOL(iwl_send_card_state);
 
 void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
 {
@@ -1387,7 +1961,7 @@ void iwl_radio_kill_sw_disable_radio(str
 	if (test_bit(STATUS_RF_KILL_SW, &priv->status))
 		return;
 
-	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n");
+	IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");
 
 	iwl_scan_cancel(priv);
 	/* FIXME: This is a workaround for AP */
@@ -1416,7 +1990,7 @@ int iwl_radio_kill_sw_enable_radio(struc
 	if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
 		return 0;
 
-	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");
+	IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");
 
 	spin_lock_irqsave(&priv->lock, flags);
 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
@@ -1441,7 +2015,7 @@ int iwl_radio_kill_sw_enable_radio(struc
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-		IWL_DEBUG_RF_KILL("Can not turn radio back on - "
+		IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
 				  "disabled by HW switch\n");
 		return 0;
 	}
@@ -1463,3 +2037,78 @@ int iwl_radio_kill_sw_enable_radio(struc
 	return 1;
 }
 EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
+
+void iwl_bg_rf_kill(struct work_struct *work)
+{
+	struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+
+	wake_up_interruptible(&priv->wait_command_queue);
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	mutex_lock(&priv->mutex);
+
+	if (!iwl_is_rfkill(priv)) {
+		IWL_DEBUG_RF_KILL(priv,
+			  "HW and/or SW RF Kill no longer active, restarting "
+			  "device\n");
+		if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
+		    test_bit(STATUS_ALIVE, &priv->status))
+			queue_work(priv->workqueue, &priv->restart);
+	} else {
+		/* make sure mac80211 stop sending Tx frame */
+		if (priv->mac80211_registered)
+			ieee80211_stop_queues(priv->hw);
+
+		if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+			IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
+					  "disabled by SW switch\n");
+		else
+			IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
+				    "Kill switch must be turned off for "
+				    "wireless networking to work.\n");
+	}
+	mutex_unlock(&priv->mutex);
+	iwl_rfkill_set_hw_state(priv);
+}
+EXPORT_SYMBOL(iwl_bg_rf_kill);
+
+void iwl_rx_pm_sleep_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_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);
+#endif
+}
+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;
+	IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
+			"notification for %s:\n",
+			le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
+	iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+}
+EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
+
+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;
+
+	IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
+		"seq 0x%04X ser 0x%08X\n",
+		le32_to_cpu(pkt->u.err_resp.error_type),
+		get_cmd_string(pkt->u.err_resp.cmd_id),
+		pkt->u.err_resp.cmd_id,
+		le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
+		le32_to_cpu(pkt->u.err_resp.error_info));
+}
+EXPORT_SYMBOL(iwl_rx_reply_error);
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-core.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ struct iwl_cmd;
 
 
 #define IWLWIFI_VERSION "1.3.27k"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2009 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -110,6 +110,14 @@ struct iwl_lib_ops {
 	void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
 				       struct iwl_tx_queue *txq);
 	void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+	int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
+				     struct iwl_tx_queue *txq,
+				     dma_addr_t addr,
+				     u16 len, u8 reset, u8 pad);
+	void (*txq_free_tfd)(struct iwl_priv *priv,
+			     struct iwl_tx_queue *txq);
+	int (*txq_init)(struct iwl_priv *priv,
+			struct iwl_tx_queue *txq);
 	/* aggregations */
 	int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
 			      int sta_id, int tid, u16 ssn_idx);
@@ -203,6 +211,9 @@ struct iwl_cfg {
 	u16  eeprom_calib_ver;
 	const struct iwl_ops *ops;
 	const struct iwl_mod_params *mod_params;
+	u8   valid_tx_ant;
+	u8   valid_rx_ant;
+	bool need_pll_cfg;
 };
 
 /***************************
@@ -213,11 +224,26 @@ struct ieee80211_hw *iwl_alloc_all(struc
 		struct ieee80211_ops *hw_ops);
 void iwl_hw_detect(struct iwl_priv *priv);
 void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *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);
 u8 iwl_is_fat_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);
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+			   struct ieee80211_hdr *hdr,
+			   u32 decrypt_res,
+			   struct ieee80211_rx_status *stats);
+void iwl_irq_handle_error(struct iwl_priv *priv);
+void iwl_configure_filter(struct ieee80211_hw *hw,
+			  unsigned int changed_flags,
+			  unsigned int *total_flags,
+			  int mc_count, struct dev_addr_list *mc_list);
 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);
@@ -225,9 +251,20 @@ int iwl_init_drv(struct iwl_priv *priv);
 void iwl_uninit_drv(struct iwl_priv *priv);
 
 /*****************************************************
+ * RX handlers.
+ * **************************************************/
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+			   struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+				      struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_reply_error(struct iwl_priv *priv,
+			struct iwl_rx_mem_buffer *rxb);
+
+/*****************************************************
 * RX
 ******************************************************/
 void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
+void iwl_cmd_queue_free(struct iwl_priv *priv);
 int iwl_rx_queue_alloc(struct iwl_priv *priv);
 void iwl_rx_handle(struct iwl_priv *priv);
 int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
@@ -245,6 +282,7 @@ 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_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 
 /* TX helpers */
 
@@ -252,9 +290,18 @@ void iwl_rx_statistics(struct iwl_priv *
 * TX
 ******************************************************/
 int iwl_txq_ctx_reset(struct iwl_priv *priv);
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+				 struct iwl_tx_queue *txq,
+				 dma_addr_t addr, u16 len, u8 reset, u8 pad);
 int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
 void iwl_hw_txq_ctx_free(struct iwl_priv *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);
+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);
 int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
 int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
 int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
@@ -267,7 +314,7 @@ int iwl_set_tx_power(struct iwl_priv *pr
  * RF -Kill - here and not in iwl-rfkill.h to be available when
  * RF-kill subsystem is not compiled.
  ****************************************************/
-void iwl_rf_kill(struct iwl_priv *priv);
+void iwl_bg_rf_kill(struct work_struct *work);
 void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
 int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
 
@@ -279,6 +326,10 @@ void iwl_hwrate_to_tx_control(struct iwl
 			      struct ieee80211_tx_info *info);
 int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
 
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
+
+void iwl_set_rate(struct iwl_priv *priv);
+
 u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
 
 static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -306,8 +357,30 @@ void iwl_init_scan_params(struct iwl_pri
 int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 int iwl_scan_initiate(struct iwl_priv *priv);
+int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
+		       struct ieee80211_mgmt *frame, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+			      enum ieee80211_band band,
+			      u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+			       enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request.  This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME       cpu_to_le16(10)  /* msec */
+#define IWL_PLCP_QUIET_THRESH       cpu_to_le16(1)  /* packets */
+
 
 /*******************************************************************************
  * Calibrations - implemented in iwl-calib.c
@@ -319,7 +392,7 @@ void iwl_calib_free_results(struct iwl_p
 /*******************************************************************************
  * Spectrum Measureemtns in  iwl-spectrum.c
  ******************************************************************************/
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
 void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
 #else
 static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
@@ -342,11 +415,23 @@ int iwl_send_cmd_pdu_async(struct iwl_pr
 
 int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
 
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
+			u8 meta_flag);
+
 /*****************************************************
  * PCI						     *
  *****************************************************/
 void iwl_disable_interrupts(struct iwl_priv *priv);
 void iwl_enable_interrupts(struct iwl_priv *priv);
+irqreturn_t iwl_isr(int irq, void *data);
+static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
+{
+	int pos;
+	u16 pci_lnk_ctl;
+	pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
+	pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+	return pci_lnk_ctl;
+}
 
 /*****************************************************
 *  Error Handling Debugging
@@ -354,6 +439,11 @@ void iwl_enable_interrupts(struct iwl_pr
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 void iwl_dump_nic_event_log(struct iwl_priv *priv);
 
+/*****************************************************
+*  GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);
 
 /*************** DRIVER STATUS FUNCTIONS   *****/
 
@@ -422,6 +512,7 @@ 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_verify_ucode(struct iwl_priv *priv);
 extern int iwl_send_lq_cmd(struct iwl_priv *priv,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-csr.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -211,6 +211,9 @@
 #define CSR_HW_REV_TYPE_5350           (0x0000030)
 #define CSR_HW_REV_TYPE_5100           (0x0000050)
 #define CSR_HW_REV_TYPE_5150           (0x0000040)
+#define CSR_HW_REV_TYPE_1000           (0x0000060)
+#define CSR_HW_REV_TYPE_6x00           (0x0000070)
+#define CSR_HW_REV_TYPE_6x50           (0x0000080)
 #define CSR_HW_REV_TYPE_NONE           (0x00000F0)
 
 /* EEPROM REG */
@@ -220,7 +223,7 @@
 #define CSR_EEPROM_REG_MSK_DATA		(0xFFFF0000)
 
 /* EEPROM GP */
-#define CSR_EEPROM_GP_VALID_MSK		(0x00000006)
+#define CSR_EEPROM_GP_VALID_MSK		(0x00000007)
 #define CSR_EEPROM_GP_BAD_SIGNATURE	(0x00000000)
 #define CSR_EEPROM_GP_IF_OWNER_MSK	(0x00000180)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -63,6 +63,14 @@
 		goto err;                                               \
 } while (0)
 
+#define DEBUGFS_ADD_X32(name, parent, ptr) do {                        \
+	dbgfs->dbgfs_##parent##_files.file_##name =                     \
+	debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr);     \
+	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
+			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
+		goto err;                                               \
+} while (0)
+
 #define DEBUGFS_REMOVE(name)  do {              \
 	debugfs_remove(name);                   \
 	name = NULL;                            \
@@ -164,9 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struc
 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
 	const size_t bufsz = sizeof(buf);
 
-	printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n",
-	priv->dbgfs->sram_offset, priv->dbgfs->sram_len);
-
 	iwl_grab_nic_access(priv);
 	for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
 		val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
@@ -301,14 +306,14 @@ static ssize_t iwl_dbgfs_eeprom_read(str
 	buf_size = 4 * eeprom_len + 256;
 
 	if (eeprom_len % 16) {
-		IWL_ERROR("EEPROM size is not multiple of 16.\n");
+		IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
 		return -ENODATA;
 	}
 
 	/* 4 characters for byte 0xYY */
 	buf = kzalloc(buf_size, GFP_KERNEL);
 	if (!buf) {
-		IWL_ERROR("Can not allocate Buffer\n");
+		IWL_ERR(priv, "Can not allocate Buffer\n");
 		return -ENOMEM;
 	}
 
@@ -365,7 +370,7 @@ static ssize_t iwl_dbgfs_channels_read(s
 
 	buf = kzalloc(bufsz, GFP_KERNEL);
 	if (!buf) {
-		IWL_ERROR("Can not allocate Buffer\n");
+		IWL_ERR(priv, "Can not allocate Buffer\n");
 		return -ENOMEM;
 	}
 
@@ -420,6 +425,55 @@ static ssize_t iwl_dbgfs_channels_read(s
 	return ret;
 }
 
+static ssize_t iwl_dbgfs_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[512];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
+		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
+		test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
+		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_RF_KILL_SW:\t %d\n",
+		test_bit(STATUS_RF_KILL_SW, &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",
+		test_bit(STATUS_ALIVE, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
+		test_bit(STATUS_READY, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
+		test_bit(STATUS_TEMPERATURE, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
+		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
+		test_bit(STATUS_EXIT_PENDING, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
+		test_bit(STATUS_IN_SUSPEND, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
+		test_bit(STATUS_STATISTICS, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
+		test_bit(STATUS_SCANNING, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
+		test_bit(STATUS_SCAN_ABORTING, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
+		test_bit(STATUS_SCAN_HW, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
+		test_bit(STATUS_POWER_PMI, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
+		test_bit(STATUS_FW_ERROR, &priv->status));
+	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
+		test_bit(STATUS_MODE_PENDING, &priv->status));
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
 
 DEBUGFS_READ_WRITE_FILE_OPS(sram);
 DEBUGFS_WRITE_FILE_OPS(log_event);
@@ -428,6 +482,7 @@ DEBUGFS_READ_FILE_OPS(stations);
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_FILE_OPS(channels);
+DEBUGFS_READ_FILE_OPS(status);
 
 /*
  * Create the debugfs files and directories
@@ -462,6 +517,7 @@ int iwl_dbgfs_register(struct iwl_priv *
 	DEBUGFS_ADD_FILE(rx_statistics, data);
 	DEBUGFS_ADD_FILE(tx_statistics, data);
 	DEBUGFS_ADD_FILE(channels, data);
+	DEBUGFS_ADD_FILE(status, data);
 	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
 	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
 			 &priv->disable_chain_noise_cal);
@@ -469,7 +525,7 @@ int iwl_dbgfs_register(struct iwl_priv *
 	return 0;
 
 err:
-	IWL_ERROR("Can't open the debugfs directory\n");
+	IWL_ERR(priv, "Can't open the debugfs directory\n");
 	iwl_dbgfs_unregister(priv);
 	return ret;
 }
@@ -491,6 +547,7 @@ void iwl_dbgfs_unregister(struct iwl_pri
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
 	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-debug.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -29,16 +29,29 @@
 #ifndef __iwl_debug_h__
 #define __iwl_debug_h__
 
+struct iwl_priv;
+
+#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
+#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
+#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a)
+#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a)
+
 #ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (priv->debug_level & (level)) \
-  dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG(__priv, level, fmt, args...)				\
+do {									\
+	if (__priv->debug_level & (level))				\
+		dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev),		\
+			 "%c %s " fmt, in_interrupt() ? 'I' : 'U',	\
+			__func__ , ## args);				\
+} while (0)
 
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((priv->debug_level & (level)) && net_ratelimit()) \
-  dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)			\
+do {									\
+	if ((__priv->debug_level & (level)) && net_ratelimit())		\
+		dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev),		\
+			"%c %s " fmt, in_interrupt() ? 'I' : 'U',	\
+			 __func__ , ## args);				\
+} while (0)
 
 #define iwl_print_hex_dump(priv, level, p, len) 			\
 do {                                            			\
@@ -61,6 +74,7 @@ struct iwl_debugfs {
 		struct dentry *file_tx_statistics;
 		struct dentry *file_log_event;
 		struct dentry *file_channels;
+		struct dentry *file_status;
 	} dbgfs_data_files;
 	struct dir_rf_files {
 		struct dentry *file_disable_sensitivity;
@@ -76,8 +90,8 @@ void iwl_dbgfs_unregister(struct iwl_pri
 #endif
 
 #else
-#define IWL_DEBUG(level, fmt, args...)
-#define IWL_DEBUG_LIMIT(level, fmt, args...)
+#define IWL_DEBUG(__priv, level, fmt, args...)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
 static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
 				      void *p, u32 len)
 {}
@@ -117,84 +131,85 @@ static inline void iwl_dbgfs_unregister(
  * when CONFIG_IWLWIFI_DEBUG=y.
  */
 
+/* 0x0000000F - 0x00000001 */
 #define IWL_DL_INFO		(1 << 0)
 #define IWL_DL_MAC80211		(1 << 1)
 #define IWL_DL_HCMD		(1 << 2)
 #define IWL_DL_STATE		(1 << 3)
+/* 0x000000F0 - 0x00000010 */
 #define IWL_DL_MACDUMP		(1 << 4)
 #define IWL_DL_HCMD_DUMP	(1 << 5)
-#define IWL_DL_RADIO         (1 << 7)
-#define IWL_DL_POWER         (1 << 8)
-#define IWL_DL_TEMP          (1 << 9)
-
-#define IWL_DL_NOTIF         (1 << 10)
-#define IWL_DL_SCAN          (1 << 11)
-#define IWL_DL_ASSOC         (1 << 12)
-#define IWL_DL_DROP          (1 << 13)
-
-#define IWL_DL_TXPOWER       (1 << 14)
-
-#define IWL_DL_AP            (1 << 15)
-
-#define IWL_DL_FW            (1 << 16)
-#define IWL_DL_RF_KILL       (1 << 17)
-#define IWL_DL_FW_ERRORS     (1 << 18)
-
-#define IWL_DL_LED           (1 << 19)
-
-#define IWL_DL_RATE          (1 << 20)
-
-#define IWL_DL_CALIB         (1 << 21)
-#define IWL_DL_WEP           (1 << 22)
-#define IWL_DL_TX            (1 << 23)
-#define IWL_DL_RX            (1 << 24)
-#define IWL_DL_ISR           (1 << 25)
-#define IWL_DL_HT            (1 << 26)
-#define IWL_DL_IO            (1 << 27)
-#define IWL_DL_11H           (1 << 28)
-
-#define IWL_DL_STATS         (1 << 29)
-#define IWL_DL_TX_REPLY      (1 << 30)
-#define IWL_DL_QOS           (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...)    IWL_DEBUG(IWL_DL_INFO, f, ## a)
+#define IWL_DL_RADIO		(1 << 7)
+/* 0x00000F00 - 0x00000100 */
+#define IWL_DL_POWER		(1 << 8)
+#define IWL_DL_TEMP		(1 << 9)
+#define IWL_DL_NOTIF		(1 << 10)
+#define IWL_DL_SCAN		(1 << 11)
+/* 0x0000F000 - 0x00001000 */
+#define IWL_DL_ASSOC		(1 << 12)
+#define IWL_DL_DROP		(1 << 13)
+#define IWL_DL_TXPOWER		(1 << 14)
+#define IWL_DL_AP		(1 << 15)
+/* 0x000F0000 - 0x00010000 */
+#define IWL_DL_FW		(1 << 16)
+#define IWL_DL_RF_KILL		(1 << 17)
+#define IWL_DL_FW_ERRORS	(1 << 18)
+#define IWL_DL_LED		(1 << 19)
+/* 0x00F00000 - 0x00100000 */
+#define IWL_DL_RATE		(1 << 20)
+#define IWL_DL_CALIB		(1 << 21)
+#define IWL_DL_WEP		(1 << 22)
+#define IWL_DL_TX		(1 << 23)
+/* 0x0F000000 - 0x01000000 */
+#define IWL_DL_RX		(1 << 24)
+#define IWL_DL_ISR		(1 << 25)
+#define IWL_DL_HT		(1 << 26)
+#define IWL_DL_IO		(1 << 27)
+/* 0xF0000000 - 0x10000000 */
+#define IWL_DL_11H		(1 << 28)
+#define IWL_DL_STATS		(1 << 29)
+#define IWL_DL_TX_REPLY		(1 << 30)
+#define IWL_DL_QOS		(1 << 31)
 
-#define IWL_DEBUG_MAC80211(f, a...)     IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_MACDUMP(f, a...)     IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...)   IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...)   IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...)     IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...)     IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...)    IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...)    IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a)
-#define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
-	IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
-	IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...)  IWL_DEBUG(IWL_DL_11H, f, ## a)
+#define IWL_DEBUG_INFO(p, f, a...)	IWL_DEBUG(p, IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_MAC80211(p, f, a...)	IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_MACDUMP(p, f, a...)	IWL_DEBUG(p, IWL_DL_MACDUMP, f, ## a)
+#define IWL_DEBUG_TEMP(p, f, a...)	IWL_DEBUG(p, IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(p, f, a...)	IWL_DEBUG(p, IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(p, f, a...)	IWL_DEBUG(p, IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(p, f, a...)	IWL_DEBUG(p, IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(p, f, a...)	IWL_DEBUG(p, IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(p, f, a...)	IWL_DEBUG(p, IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(p, f, a...)	IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(p, f, a...)	IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
+#define IWL_DEBUG_HC_DUMP(p, f, a...)	IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
+#define IWL_DEBUG_CALIB(p, f, a...)	IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(p, f, a...)	IWL_DEBUG(p, IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(p, f, a...)	IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(p, f, a...)	IWL_DEBUG(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(p, f, a...)	\
+		IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(p, f, a...)	IWL_DEBUG(p, IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(p, f, a...)	IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(p, f, a...)	IWL_DEBUG(p, IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(p, f, a...)	IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(p, f, a...)	\
+		IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(p, f, a...)	IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(p, f, a...)	\
+		IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(p, f, a...)	\
+		IWL_DEBUG_LIMIT(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(p, f, a...)	IWL_DEBUG(p, IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(p, f, a...)	IWL_DEBUG(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_STATS_LIMIT(p, f, a...)	\
+		IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(p, f, a...)	IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \
+		IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(p, f, a...)	IWL_DEBUG(p, IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(p, f, a...)	IWL_DEBUG(p, IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(p, f, a...)	IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(p, f, a...)	IWL_DEBUG(p, IWL_DL_11H, f, ## a)
 
 #endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-dev.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -36,13 +36,15 @@
 #include <linux/kernel.h>
 #include <net/ieee80211_radiotap.h>
 
-#define DRV_NAME        "iwlagn"
-#include "iwl-rfkill.h"
 #include "iwl-eeprom.h"
-#include "iwl-4965-hw.h"
 #include "iwl-csr.h"
 #include "iwl-prph.h"
+#include "iwl-fh.h"
 #include "iwl-debug.h"
+#include "iwl-rfkill.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"
@@ -55,6 +57,28 @@ extern struct iwl_cfg iwl5350_agn_cfg;
 extern struct iwl_cfg iwl5100_bg_cfg;
 extern struct iwl_cfg iwl5100_abg_cfg;
 extern struct iwl_cfg iwl5150_agn_cfg;
+extern struct iwl_cfg iwl6000_2ag_cfg;
+extern struct iwl_cfg iwl6000_2agn_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 iwl1000_bgn_cfg;
+
+/* shared structures from iwl-5000.c */
+extern struct iwl_mod_params iwl50_mod_params;
+extern struct iwl_ops iwl5000_ops;
+extern struct iwl_lib_ops iwl5000_lib;
+extern struct iwl_hcmd_ops iwl5000_hcmd;
+extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
+
+/* shared functions from iwl-5000.c */
+extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
+extern u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd,
+				     u8 *data);
+extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+				    __le32 *tx_flags);
+extern int iwl5000_calc_rssi(struct iwl_priv *priv,
+			     struct iwl_rx_phy_res *rx_resp);
 
 /* CT-KILL constants */
 #define CT_KILL_THRESHOLD	110 /* in Celsius */
@@ -132,9 +156,12 @@ struct iwl_tx_info {
  * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
  * descriptors) and required locking structures.
  */
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
 struct iwl_tx_queue {
 	struct iwl_queue q;
-	struct iwl_tfd *tfds;
+	void *tfds;
 	struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
 	struct iwl_tx_info *txb;
 	u8 need_update;
@@ -154,6 +181,36 @@ struct iwl4965_channel_tgh_info {
 	s64 last_radar_time;
 };
 
+#define IWL4965_MAX_RATE (33)
+
+struct iwl3945_clip_group {
+	/* maximum power level to prevent clipping for each rate, derived by
+	 *   us from this band's saturation power in EEPROM */
+	const s8 clip_powers[IWL_MAX_RATES];
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl3945_channel_power_info {
+	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
+	s8 power_table_index;	/* actual (compenst'd) index into gain table */
+	s8 base_power_index;	/* gain index for power at factory temp. */
+	s8 requested_power;	/* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl3945_scan_power_info {
+	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
+	s8 power_table_index;	/* actual (compenst'd) index into gain table */
+	s8 requested_power;	/* scan pwr (dBm) requested for chnl/rate */
+};
+
 /*
  * One for each channel, holds all channel setup data
  * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -184,8 +241,15 @@ struct iwl_channel_info {
 	s8 fat_scan_power;	/* (dBm) eeprom, direct scans, any rate */
 	u8 fat_flags;		/* flags copied from EEPROM */
 	u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-};
 
+	/* Radio/DSP gain settings for each "normal" data Tx rate.
+	 * These include, in addition to RF and DSP gain, a few fields for
+	 *   remembering/modifying gain settings (indexes). */
+	struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
+
+	/* Radio/DSP gain settings for each scan rate, for directed scans. */
+	struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
 
 #define IWL_TX_FIFO_AC0	0
 #define IWL_TX_FIFO_AC1	1
@@ -296,12 +360,16 @@ struct iwl_host_cmd {
 
 /**
  * struct iwl_rx_queue - Rx queue
+ * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
+ * @dma_addr: bus address of buffer of receive buffer descriptors (rbd)
  * @read: Shared index to newest available Rx buffer
  * @write: Shared index to oldest written Rx packet
  * @free_count: Number of pre-allocated buffers in rx_free
  * @rx_free: list of free SKBs for use
  * @rx_used: List of Rx buffers with no SKB
  * @need_update: flag to indicate we need to update read/write index
+ * @rb_stts: driver's pointer to receive buffer status
+ * @rb_stts_dma: bus address of receive buffer status
  *
  * NOTE:  rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
  */
@@ -370,7 +438,7 @@ struct iwl_hw_key {
 	u8 key[32];
 };
 
-union iwl4965_ht_rate_supp {
+union iwl_ht_rate_supp {
 	u16 rates;
 	struct {
 		u8 siso_rate;
@@ -430,6 +498,24 @@ struct iwl_qos_info {
 #define STA_PS_STATUS_WAKE             0
 #define STA_PS_STATUS_SLEEP            1
 
+struct iwl3945_tid_data {
+	u16 seq_number;
+};
+
+struct iwl3945_hw_key {
+	enum ieee80211_key_alg alg;
+	int keylen;
+	u8 key[32];
+};
+
+struct iwl3945_station_entry {
+	struct iwl3945_addsta_cmd sta;
+	struct iwl3945_tid_data tid[MAX_TID_COUNT];
+	u8 used;
+	u8 ps_status;
+	struct iwl3945_hw_key keyinfo;
+};
+
 struct iwl_station_entry {
 	struct iwl_addsta_cmd sta;
 	struct iwl_tid_data tid[MAX_TID_COUNT];
@@ -497,11 +583,13 @@ struct iwl_sensitivity_ranges {
  * @max_txq_num: Max # Tx queues supported
  * @dma_chnl_num: Number of Tx DMA/FIFO channels
  * @scd_bc_tbls_size: size of scheduler byte count tables
+ * @tfd_size: TFD size
  * @tx/rx_chains_num: Number of TX/RX chains
  * @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_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
  * @max_stations:
  * @bcast_sta_id:
  * @fat_channel: is 40MHz width possible in band 2.4
@@ -516,6 +604,7 @@ struct iwl_hw_params {
 	u8 max_txq_num;
 	u8 dma_chnl_num;
 	u16 scd_bc_tbls_size;
+	u32 tfd_size;
 	u8  tx_chains_num;
 	u8  rx_chains_num;
 	u8  valid_tx_ant;
@@ -523,6 +612,7 @@ struct iwl_hw_params {
 	u16 max_rxq_size;
 	u16 max_rxq_log;
 	u32 rx_buf_size;
+	u32 rx_wrt_ptr_reg;
 	u32 max_pkt_size;
 	u8  max_stations;
 	u8  bcast_sta_id;
@@ -755,7 +845,7 @@ struct iwl_priv {
 
 	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
 	/* spectrum measurement report caching */
 	struct iwl_spectrum_notification measure_report;
 	u8 measurement_status;
@@ -768,6 +858,10 @@ struct iwl_priv {
 	struct iwl_channel_info *channel_info;	/* channel info array */
 	u8 channel_count;	/* # of channels */
 
+	/* each calibration channel group in the EEPROM has a derived
+	 * clip setting for each rate. 3945 only.*/
+	const struct iwl3945_clip_group clip39_groups[5];
+
 	/* thermal calibration */
 	s32 temperature;	/* degrees Kelvin */
 	s32 last_temperature;
@@ -781,7 +875,7 @@ struct iwl_priv {
 	unsigned long scan_start;
 	unsigned long scan_pass_start;
 	unsigned long scan_start_tsf;
-	struct iwl_scan_cmd *scan;
+	void *scan;
 	int scan_bands;
 	int one_direct_scan;
 	u8 direct_ssid_len;
@@ -832,18 +926,18 @@ struct iwl_priv {
 	 * 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_RFKILL
+#if defined(CONFIG_IWLWIFI_RFKILL)
 	struct rfkill *rfkill;
 #endif
 
 #ifdef CONFIG_IWLWIFI_LEDS
-	struct iwl_led led[IWL_LED_TRG_MAX];
 	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;
 
@@ -893,7 +987,6 @@ struct iwl_priv {
 	u16 rates_mask;
 
 	u32 power_mode;
-	u32 antenna;
 	u8 bssid[ETH_ALEN];
 	u16 rts_threshold;
 	u8 mac_addr[ETH_ALEN];
@@ -907,6 +1000,12 @@ struct iwl_priv {
 	u8 key_mapping_key;
 	unsigned long ucode_key_table;
 
+	/* queue refcounts */
+#define IWL_MAX_HW_QUEUES	32
+	unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
+	/* for each AC */
+	atomic_t queue_stop_count[4];
+
 	/* Indication if ieee80211_ops->open has been called */
 	u8 is_open;
 
@@ -929,6 +1028,10 @@ struct iwl_priv {
 	u16 beacon_int;
 	struct ieee80211_vif *vif;
 
+	/*Added for 3945 */
+	void *shared_virt;
+	dma_addr_t shared_phys;
+	/*End*/
 	struct iwl_hw_params hw_params;
 
 
@@ -960,6 +1063,11 @@ struct iwl_priv {
 	struct delayed_work init_alive_start;
 	struct delayed_work alive_start;
 	struct delayed_work scan_check;
+
+	/*For 3945 only*/
+	struct delayed_work thermal_periodic;
+	struct delayed_work rfkill_poll;
+
 	/* TX Power */
 	s8 tx_power_user_lmt;
 	s8 tx_power_channel_lmt;
@@ -982,6 +1090,15 @@ struct iwl_priv {
 	u32 disable_tx_power_cal;
 	struct work_struct run_time_calib_work;
 	struct timer_list statistics_periodic;
+
+	/*For 3945*/
+#define IWL_DEFAULT_TX_POWER 0x0F
+
+	struct iwl3945_notif_statistics statistics_39;
+
+	struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
+
+	u32 sta_supp_rates;
 }; /*iwl_priv */
 
 static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -145,7 +145,7 @@ int iwlcore_eeprom_verify_signature(stru
 {
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
 	if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		return -ENOENT;
 	}
 	return 0;
@@ -173,7 +173,7 @@ int iwlcore_eeprom_acquire_semaphore(str
 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
 				EEPROM_SEM_TIMEOUT);
 		if (ret >= 0) {
-			IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
+			IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
 				count+1);
 			return ret;
 		}
@@ -223,7 +223,7 @@ int iwl_eeprom_init(struct iwl_priv *pri
 
 	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
 	if (ret < 0) {
-		IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
 		ret = -ENOENT;
 		goto err;
 	}
@@ -231,7 +231,7 @@ int iwl_eeprom_init(struct iwl_priv *pri
 	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
 	ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
 	if (ret < 0) {
-		IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
+		IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
 		ret = -ENOENT;
 		goto err;
 	}
@@ -247,7 +247,7 @@ int iwl_eeprom_init(struct iwl_priv *pri
 					  CSR_EEPROM_REG_READ_VALID_MSK,
 					  IWL_EEPROM_ACCESS_TIMEOUT);
 		if (ret < 0) {
-			IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
+			IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
 			goto done;
 		}
 		r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_
 
 	return 0;
 err:
-	IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+	IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
 		  eeprom_ver, priv->cfg->eeprom_ver,
 		  calib_ver,  priv->cfg->eeprom_calib_ver);
 	return -EINVAL;
@@ -390,7 +390,7 @@ static int iwl_set_fat_chan_info(struct
 	if (!is_channel_valid(ch_info))
 		return -1;
 
-	IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+	IWL_DEBUG_INFO(priv, "FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
 			" Ad-Hoc %ssupported\n",
 			ch_info->channel,
 			is_channel_a_band(ch_info) ?
@@ -432,11 +432,11 @@ int iwl_init_channel_map(struct iwl_priv
 	struct iwl_channel_info *ch_info;
 
 	if (priv->channel_count) {
-		IWL_DEBUG_INFO("Channel map already initialized.\n");
+		IWL_DEBUG_INFO(priv, "Channel map already initialized.\n");
 		return 0;
 	}
 
-	IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
+	IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n");
 
 	priv->channel_count =
 	    ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -445,12 +445,12 @@ int iwl_init_channel_map(struct iwl_priv
 	    ARRAY_SIZE(iwl_eeprom_band_4) +
 	    ARRAY_SIZE(iwl_eeprom_band_5);
 
-	IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
+	IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count);
 
 	priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
 				     priv->channel_count, GFP_KERNEL);
 	if (!priv->channel_info) {
-		IWL_ERROR("Could not allocate channel_info\n");
+		IWL_ERR(priv, "Could not allocate channel_info\n");
 		priv->channel_count = 0;
 		return -ENOMEM;
 	}
@@ -485,7 +485,7 @@ int iwl_init_channel_map(struct iwl_priv
 				 IEEE80211_CHAN_NO_FAT_BELOW);
 
 			if (!(is_channel_valid(ch_info))) {
-				IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
+				IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
 					       "No traffic\n",
 					       ch_info->channel,
 					       ch_info->flags,
@@ -501,7 +501,7 @@ int iwl_init_channel_map(struct iwl_priv
 			ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
 			ch_info->min_power = 0;
 
-			IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+			IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
 				       " Ad-Hoc %ssupported\n",
 				       ch_info->channel,
 				       is_channel_a_band(ch_info) ?
@@ -520,7 +520,7 @@ int iwl_init_channel_map(struct iwl_priv
 					     flags & EEPROM_CHANNEL_RADAR))
 				       ? "" : "not ");
 
-			/* Set the user_txpower_limit to the highest power
+			/* Set the tx_power_user_lmt to the highest power
 			 * supported by any channel */
 			if (eeprom_ch_info[ch].max_power_avg >
 						priv->tx_power_user_lmt)
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv
 		}
 	}
 
+	/* Check if we do have FAT channels */
+	if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
+	    EEPROM_REGULATORY_BAND_NO_FAT &&
+	    priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
+	    EEPROM_REGULATORY_BAND_NO_FAT)
+		return 0;
+
 	/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
 	for (band = 6; band <= 7; band++) {
 		enum ieee80211_band ieeeband;
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_pri
 	kfree(priv->channel_info);
 	priv->channel_count = 0;
 }
+EXPORT_SYMBOL(iwl_free_channel_map);
 
 /**
  * iwl_get_channel_info - Find driver's private channel info
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel {
 	s8 max_power_avg;	/* max power (dBm) on this chnl, limit 31 */
 } __attribute__ ((packed));
 
+/* 3945 Specific */
+#define EEPROM_3945_EEPROM_VERSION	(0x2f)
+
 /* 4965 has two radio transmitters (and 3 radio receivers) */
 #define EEPROM_TX_POWER_TX_CHAINS      (2)
 
@@ -367,6 +370,8 @@ struct iwl_eeprom_calib_info {
  */
 #define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8)	/* 22 bytes */
 
+#define EEPROM_REGULATORY_BAND_NO_FAT			(0)
+
 struct iwl_eeprom_ops {
 	const u32 regulatory_bands[7];
 	int (*verify_signature) (struct iwl_priv *priv);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-fh.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -399,6 +399,21 @@
  */
 #define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN	(0x00000002)
 
+#define RX_QUEUE_SIZE                         256
+#define RX_QUEUE_MASK                         255
+#define RX_QUEUE_SIZE_LOG                     8
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Size of one Rx buffer in host DRAM */
+#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
+#define IWL_RX_BUF_SIZE_4K (4 * 1024)
+#define IWL_RX_BUF_SIZE_8K (8 * 1024)
+
 /**
  * struct iwl_rb_status - reseve buffer status
  * 	host memory mapped FH registers
@@ -414,6 +429,7 @@ struct iwl_rb_status {
 	__le16 closed_fr_num;
 	__le16 finished_rb_num;
 	__le16 finished_fr_nam;
+	__le32 __unused; /* 3945 only */
 } __attribute__ ((packed));
 
 
@@ -477,7 +493,6 @@ struct iwl_tfd {
 	__le32 __pad;
 } __attribute__ ((packed));
 
-
 /* Keep Warm Size */
 #define IWL_KW_SIZE 0x1000	/* 4k */
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -109,14 +109,14 @@ static int iwl_generic_cmd_callback(stru
 	struct iwl_rx_packet *pkt = NULL;
 
 	if (!skb) {
-		IWL_ERROR("Error: Response NULL in %s.\n",
+		IWL_ERR(priv, "Error: Response NULL in %s.\n",
 				get_cmd_string(cmd->hdr.cmd));
 		return 1;
 	}
 
 	pkt = (struct iwl_rx_packet *)skb->data;
 	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from %s (0x%08X)\n",
+		IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
 			get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
 		return 1;
 	}
@@ -125,11 +125,11 @@ static int iwl_generic_cmd_callback(stru
 	switch (cmd->hdr.cmd) {
 	case REPLY_TX_LINK_QUALITY_CMD:
 	case SENSITIVITY_CMD:
-		IWL_DEBUG_HC_DUMP("back from %s (0x%08X)\n",
+		IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
 				get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
 				break;
 	default:
-		IWL_DEBUG_HC("back from %s (0x%08X)\n",
+		IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
 				get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
 	}
 #endif
@@ -156,7 +156,7 @@ static int iwl_send_cmd_async(struct iwl
 
 	ret = iwl_enqueue_hcmd(priv, cmd);
 	if (ret < 0) {
-		IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+		IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
 			  get_cmd_string(cmd->id), ret);
 		return ret;
 	}
@@ -174,8 +174,9 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 	BUG_ON(cmd->meta.u.callback != NULL);
 
 	if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
-		IWL_ERROR("Error sending %s: Already sending a host command\n",
-			  get_cmd_string(cmd->id));
+		IWL_ERR(priv,
+			"Error sending %s: Already sending a host command\n",
+			get_cmd_string(cmd->id));
 		ret = -EBUSY;
 		goto out;
 	}
@@ -188,7 +189,7 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
 	if (cmd_idx < 0) {
 		ret = cmd_idx;
-		IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+		IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
 			  get_cmd_string(cmd->id), ret);
 		goto out;
 	}
@@ -198,9 +199,10 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 			HOST_COMPLETE_TIMEOUT);
 	if (!ret) {
 		if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
-			IWL_ERROR("Error sending %s: time out after %dms.\n",
-				  get_cmd_string(cmd->id),
-				  jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+			IWL_ERR(priv,
+				"Error sending %s: time out after %dms.\n",
+				get_cmd_string(cmd->id),
+				jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
 			clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 			ret = -ETIMEDOUT;
@@ -209,19 +211,19 @@ int iwl_send_cmd_sync(struct iwl_priv *p
 	}
 
 	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-		IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
+		IWL_DEBUG_INFO(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("Command %s failed: FW Error\n",
+		IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
 			       get_cmd_string(cmd->id));
 		ret = -EIO;
 		goto fail;
 	}
 	if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
-		IWL_ERROR("Error: Response NULL in '%s'\n",
+		IWL_ERR(priv, "Error: Response NULL in '%s'\n",
 			  get_cmd_string(cmd->id));
 		ret = -EIO;
 		goto cancel;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-helpers.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -93,4 +93,56 @@ static inline int iwl_alloc_fw_desc(stru
 	return (desc->v_addr != NULL) ? 0 : -ENOMEM;
 }
 
+/*
+ * we have 8 bits used like this:
+ *
+ * 7 6 5 4 3 2 1 0
+ * | | | | | | | |
+ * | | | | | | +-+-------- AC queue (0-3)
+ * | | | | | |
+ * | +-+-+-+-+------------ HW A-MPDU queue
+ * |
+ * +---------------------- indicates agg queue
+ */
+static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
+{
+	BUG_ON(ac > 3);   /* only have 2 bits */
+	BUG_ON(hwq > 31); /* only have 5 bits */
+
+	return 0x80 | (hwq << 2) | ac;
+}
+
+static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
+{
+	u8 ac = queue;
+	u8 hwq = queue;
+
+	if (queue & 0x80) {
+		ac = queue & 3;
+		hwq = (queue >> 2) & 0x1f;
+	}
+
+	if (test_and_clear_bit(hwq, priv->queue_stopped))
+		if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
+			ieee80211_wake_queue(priv->hw, ac);
+}
+
+static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
+{
+	u8 ac = queue;
+	u8 hwq = queue;
+
+	if (queue & 0x80) {
+		ac = queue & 3;
+		hwq = (queue >> 2) & 0x1f;
+	}
+
+	if (!test_and_set_bit(hwq, priv->queue_stopped))
+		if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
+			ieee80211_stop_queue(priv->hw, ac);
+}
+
+#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
+#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
+
 #endif				/* __iwl_helpers_h__ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-io.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -66,7 +66,7 @@
 static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
 				 u32 ofs, u32 val)
 {
-	IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
+	IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
 	_iwl_write32(priv, ofs, val);
 }
 #define iwl_write32(priv, ofs, val) \
@@ -79,7 +79,7 @@ static inline void __iwl_write32(const c
 #ifdef CONFIG_IWLWIFI_DEBUG
 static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
 {
-	IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
+	IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
 	return _iwl_read32(priv, ofs);
 }
 #define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
@@ -108,7 +108,7 @@ static inline int __iwl_poll_bit(const c
 				 u32 bits, u32 mask, int timeout)
 {
 	int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
-	IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
+	IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
 		     addr, bits, mask,
 		     unlikely(ret  == -ETIMEDOUT) ? "timeout" : "", f, l);
 	return ret;
@@ -128,7 +128,7 @@ static inline void __iwl_set_bit(const c
 				 struct iwl_priv *priv, u32 reg, u32 mask)
 {
 	u32 val = _iwl_read32(priv, reg) | mask;
-	IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+	IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
 	_iwl_write32(priv, reg, val);
 }
 #define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m)
@@ -145,7 +145,7 @@ static inline void __iwl_clear_bit(const
 				   struct iwl_priv *priv, u32 reg, u32 mask)
 {
 	u32 val = _iwl_read32(priv, reg) & ~mask;
-	IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+	IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
 	_iwl_write32(priv, reg, val);
 }
 #define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m)
@@ -156,6 +156,7 @@ static inline void __iwl_clear_bit(const
 static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
 {
 	int ret;
+	u32 val;
 #ifdef CONFIG_IWLWIFI_DEBUG
 	if (atomic_read(&priv->restrict_refcnt))
 		return 0;
@@ -165,9 +166,10 @@ static inline int _iwl_grab_nic_access(s
 	ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
 			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
 			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
 	if (ret < 0) {
-		IWL_ERROR("MAC is in deep sleep!\n");
+		val = _iwl_read32(priv, CSR_GP_CNTRL);
+		IWL_ERR(priv, "MAC is in deep sleep!.  CSR_GP_CNTRL = 0x%08X\n", val);
 		return -EIO;
 	}
 
@@ -182,9 +184,9 @@ static inline int __iwl_grab_nic_access(
 					       struct iwl_priv *priv)
 {
 	if (atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Grabbing access while already held %s %d.\n", f, l);
+		IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
 
-	IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
+	IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
 	return _iwl_grab_nic_access(priv);
 }
 #define iwl_grab_nic_access(priv) \
@@ -207,9 +209,9 @@ static inline void __iwl_release_nic_acc
 					    struct iwl_priv *priv)
 {
 	if (atomic_read(&priv->restrict_refcnt) <= 0)
-		IWL_ERROR("Release unheld nic access at line %s %d.\n", f, l);
+		IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
 
-	IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
+	IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
 	_iwl_release_nic_access(priv);
 }
 #define iwl_release_nic_access(priv) \
@@ -229,8 +231,8 @@ static inline u32 __iwl_read_direct32(co
 {
 	u32 value = _iwl_read_direct32(priv, reg);
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s %d\n", f, l);
-	IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
+		IWL_ERR(priv, "Nic access not held from %s %d\n", f, l);
+	IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
 		     f, l);
 	return value;
 }
@@ -250,7 +252,7 @@ static void __iwl_write_direct32(const c
 				   struct iwl_priv *priv, u32 reg, u32 value)
 {
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+		IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
 	_iwl_write_direct32(priv, reg, value);
 }
 #define iwl_write_direct32(priv, reg, value) \
@@ -284,10 +286,10 @@ static inline int __iwl_poll_direct_bit(
 	int ret  = _iwl_poll_direct_bit(priv, addr, mask, timeout);
 
 	if (unlikely(ret == -ETIMEDOUT))
-		IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
+		IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
 			     "timedout - %s %d\n", addr, mask, f, l);
 	else
-		IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
+		IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
 			     "- %s %d\n", addr, mask, ret, f, l);
 	return ret;
 }
@@ -308,7 +310,7 @@ static inline u32 __iwl_read_prph(const
 				  struct iwl_priv *priv, u32 reg)
 {
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+		IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
 	return _iwl_read_prph(priv, reg);
 }
 
@@ -331,7 +333,7 @@ static inline void __iwl_write_prph(cons
 				    struct iwl_priv *priv, u32 addr, u32 val)
 {
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+		IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
 	_iwl_write_prph(priv, addr, val);
 }
 
@@ -349,7 +351,7 @@ static inline void __iwl_set_bits_prph(c
 				       u32 reg, u32 mask)
 {
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+		IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
 
 	_iwl_set_bits_prph(priv, reg, mask);
 }
@@ -367,7 +369,7 @@ static inline void __iwl_set_bits_mask_p
 		struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
 {
 	if (!atomic_read(&priv->restrict_refcnt))
-		IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+		IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
 	_iwl_set_bits_mask_prph(priv, reg, bits, mask);
 }
 #define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-led.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -123,7 +123,7 @@ static int iwl4965_led_pattern(struct iw
 /* Set led register off */
 static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
 {
-	IWL_DEBUG_LED("led on %d\n", 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;
 }
@@ -150,7 +150,7 @@ int iwl4965_led_off(struct iwl_priv *pri
 		.off = 0,
 		.interval = IWL_DEF_LED_INTRVL
 	};
-	IWL_DEBUG_LED("led off %d\n", led_id);
+	IWL_DEBUG_LED(priv, "led off %d\n", led_id);
 	return iwl_send_led_cmd(priv, &led_cmd);
 }
 #endif
@@ -159,7 +159,7 @@ int iwl4965_led_off(struct iwl_priv *pri
 /* Set led register off */
 static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
 {
-	IWL_DEBUG_LED("LED Reg off\n");
+	IWL_DEBUG_LED(priv, "LED Reg off\n");
 	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
 	return 0;
 }
@@ -169,7 +169,7 @@ static int iwl4965_led_off_reg(struct iw
  */
 static int iwl_led_associate(struct iwl_priv *priv, int led_id)
 {
-	IWL_DEBUG_LED("Associated\n");
+	IWL_DEBUG_LED(priv, "Associated\n");
 	priv->allow_blinking = 1;
 	return iwl4965_led_on_reg(priv, led_id);
 }
@@ -213,7 +213,7 @@ static void iwl_led_brightness_set(struc
 		return;
 
 
-	IWL_DEBUG_LED("Led type = %s brightness = %d\n",
+	IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
 			led_type_str[led->type], brightness);
 	switch (brightness) {
 	case LED_FULL:
@@ -254,7 +254,7 @@ static int iwl_leds_register_led(struct
 
 	ret = led_classdev_register(device, &led->led_dev);
 	if (ret) {
-		IWL_ERROR("Error: failed to register led handler.\n");
+		IWL_ERR(priv, "Error: failed to register led handler.\n");
 		return ret;
 	}
 
@@ -280,7 +280,7 @@ static int iwl_get_blink_rate(struct iwl
 	if (tpt < 0) /* wraparound */
 		tpt = -tpt;
 
-	IWL_DEBUG_LED("tpt %lld current_tpt %llu\n",
+	IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n",
 		(long long)tpt,
 		(unsigned long long)current_tpt);
 	priv->led_tpt = current_tpt;
@@ -292,7 +292,7 @@ static int iwl_get_blink_rate(struct iwl
 			if (tpt  > (blink_tbl[i].tpt * IWL_1MB_RATE))
 				break;
 
-	IWL_DEBUG_LED("LED BLINK IDX=%d\n", i);
+	IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
 	return i;
 }
 
@@ -352,7 +352,7 @@ int iwl_leds_register(struct iwl_priv *p
 
 	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",
+		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
 		 wiphy_name(priv->hw->wiphy));
 
 	priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
@@ -366,7 +366,7 @@ int iwl_leds_register(struct iwl_priv *p
 
 	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",
+		 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],
@@ -382,7 +382,7 @@ int iwl_leds_register(struct iwl_priv *p
 
 	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",
+		 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],
@@ -397,7 +397,7 @@ int iwl_leds_register(struct iwl_priv *p
 
 	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",
+		 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],
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-led.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * 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
@@ -35,7 +35,7 @@ struct iwl_priv;
 
 #define IWL_LED_SOLID 11
 #define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
+#define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
 
 #define IWL_LED_ACTIVITY       (0<<1)
 #define IWL_LED_LINK           (1<<1)
@@ -47,7 +47,9 @@ enum led_type {
 	IWL_LED_TRG_RADIO,
 	IWL_LED_TRG_MAX,
 };
+#endif
 
+#ifdef CONFIG_IWLWIFI_LEDS
 
 struct iwl_led {
 	struct iwl_priv *priv;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-power.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -60,14 +60,6 @@
 #define IWL_POWER_RANGE_1_MAX  (10)
 
 
-#define NOSLP __constant_cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
-				     __constant_cpu_to_le32(X1), \
-				     __constant_cpu_to_le32(X2), \
-				     __constant_cpu_to_le32(X3), \
-				     __constant_cpu_to_le32(X4)}
 
 #define IWL_POWER_ON_BATTERY		IWL_POWER_INDEX_5
 #define IWL_POWER_ON_AC_DISASSOC	IWL_POWER_MODE_CAM
@@ -110,6 +102,7 @@ static struct iwl_power_vec_entry range_
 	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 };
 
+
 /* set card power command */
 static int iwl_set_power(struct iwl_priv *priv, void *cmd)
 {
@@ -134,13 +127,6 @@ static u16 iwl_get_auto_power_mode(struc
 		else
 			mode = IWL_POWER_ON_AC_DISASSOC;
 		break;
-	/* FIXME: remove battery and ac from here */
-	case IWL_POWER_BATTERY:
-		mode = IWL_POWER_INDEX_3;
-		break;
-	case IWL_POWER_AC:
-		mode = IWL_POWER_MODE_CAM;
-		break;
 	default:
 		mode = priv->power_data.user_power_setting;
 		break;
@@ -149,17 +135,17 @@ static u16 iwl_get_auto_power_mode(struc
 }
 
 /* initialize to default */
-static int iwl_power_init_handle(struct iwl_priv *priv)
+static void iwl_power_init_handle(struct iwl_priv *priv)
 {
 	struct iwl_power_mgr *pow_data;
 	int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
 	struct iwl_powertable_cmd *cmd;
 	int i;
-	u16 pci_pm;
+	u16 lctl;
 
-	IWL_DEBUG_POWER("Initialize power \n");
+	IWL_DEBUG_POWER(priv, "Initialize power \n");
 
-	pow_data = &(priv->power_data);
+	pow_data = &priv->power_data;
 
 	memset(pow_data, 0, sizeof(*pow_data));
 
@@ -167,38 +153,37 @@ static int iwl_power_init_handle(struct
 	memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
 	memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
 
-	pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm);
+	lctl = iwl_pcie_link_ctl(priv);
 
-	IWL_DEBUG_POWER("adjust power command flags\n");
+	IWL_DEBUG_POWER(priv, "adjust power command flags\n");
 
 	for (i = 0; i < IWL_POWER_MAX; i++) {
 		cmd = &pow_data->pwr_range_0[i].cmd;
 
-		if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
+		if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
 			cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
 		else
 			cmd->flags |= IWL_POWER_PCI_PM_MSK;
 	}
-	return 0;
 }
 
 /* adjust power command according to DTIM period and power level*/
-static int iwl_update_power_command(struct iwl_priv *priv,
-				    struct iwl_powertable_cmd *cmd,
-				    u16 mode)
+static int iwl_update_power_cmd(struct iwl_priv *priv,
+				struct iwl_powertable_cmd *cmd, u16 mode)
 {
-	int ret = 0, i;
-	u8 skip;
-	u32 max_sleep = 0;
 	struct iwl_power_vec_entry *range;
-	u8 period = 0;
 	struct iwl_power_mgr *pow_data;
+	int i;
+	u32 max_sleep = 0;
+	u8 period;
+	bool skip;
 
 	if (mode > IWL_POWER_INDEX_5) {
-		IWL_DEBUG_POWER("Error invalid power mode \n");
-		return -1;
+		IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
+		return -EINVAL;
 	}
-	pow_data = &(priv->power_data);
+
+	pow_data = &priv->power_data;
 
 	if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
 		range = &pow_data->pwr_range_0[0];
@@ -212,14 +197,12 @@ static int iwl_update_power_command(stru
 
 	if (period == 0) {
 		period = 1;
-		skip = 0;
-	} else
-		skip = range[mode].no_dtim;
-
-	if (skip == 0) {
-		max_sleep = period;
-		cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+		skip = false;
 	} else {
+		skip = !!range[mode].no_dtim;
+	}
+
+	if (skip) {
 		__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
 		max_sleep = le32_to_cpu(slp_itrvl);
 		if (max_sleep == 0xFF)
@@ -227,24 +210,26 @@ static int iwl_update_power_command(stru
 		else if (max_sleep >  period)
 			max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
 		cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+	} else {
+		max_sleep = period;
+		cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
 	}
 
-	for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+	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);
-	}
 
-	IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
-	IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
-	IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
-	IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
+	IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
+	IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
+	IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
+	IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n",
 			le32_to_cpu(cmd->sleep_interval[0]),
 			le32_to_cpu(cmd->sleep_interval[1]),
 			le32_to_cpu(cmd->sleep_interval[2]),
 			le32_to_cpu(cmd->sleep_interval[3]),
 			le32_to_cpu(cmd->sleep_interval[4]));
 
-	return ret;
+	return 0;
 }
 
 
@@ -288,14 +273,14 @@ int iwl_power_update_mode(struct iwl_pri
 	if (priv->iw_mode != NL80211_IFTYPE_STATION)
 		final_mode = IWL_POWER_MODE_CAM;
 
-	if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
+	if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
 	    ((setting->power_mode != final_mode) || force)) {
 		struct iwl_powertable_cmd cmd;
 
 		if (final_mode != IWL_POWER_MODE_CAM)
 			set_bit(STATUS_POWER_PMI, &priv->status);
 
-		iwl_update_power_command(priv, &cmd, final_mode);
+		iwl_update_power_cmd(priv, &cmd, final_mode);
 		cmd.keep_alive_beacons = 0;
 
 		if (final_mode == IWL_POWER_INDEX_5)
@@ -311,7 +296,7 @@ int iwl_power_update_mode(struct iwl_pri
 		if (priv->cfg->ops->lib->update_chain_flags && update_chains)
 			priv->cfg->ops->lib->update_chain_flags(priv);
 		else
-			IWL_DEBUG_POWER("Cannot update the power, chain noise "
+			IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise "
 					"calibration running: %d\n",
 					priv->chain_noise_data.state);
 		if (!ret)
@@ -366,7 +351,7 @@ EXPORT_SYMBOL(iwl_power_enable_managemen
 /* set user_power_setting */
 int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
 {
-	if (mode > IWL_POWER_LIMIT)
+	if (mode > IWL_POWER_MAX)
 		return -EINVAL;
 
 	priv->power_data.user_power_setting = mode;
@@ -380,11 +365,10 @@ EXPORT_SYMBOL(iwl_power_set_user_mode);
  */
 int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
 {
-	if (mode > IWL_POWER_LIMIT)
+	if (mode < IWL_POWER_SYS_MAX)
+		priv->power_data.system_power_setting = mode;
+	else
 		return -EINVAL;
-
-	priv->power_data.system_power_setting = mode;
-
 	return iwl_power_update_mode(priv, 0);
 }
 EXPORT_SYMBOL(iwl_power_set_system_mode);
@@ -392,13 +376,11 @@ EXPORT_SYMBOL(iwl_power_set_system_mode)
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-
 	iwl_power_init_handle(priv);
 	priv->power_data.user_power_setting = IWL_POWER_AUTO;
-	priv->power_data.power_disabled = 0;
 	priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
-	priv->power_data.is_battery_active = 0;
 	priv->power_data.power_disabled = 0;
+	priv->power_data.is_battery_active = 0;
 	priv->power_data.critical_power_setting = 0;
 }
 EXPORT_SYMBOL(iwl_power_initialize);
@@ -407,8 +389,8 @@ EXPORT_SYMBOL(iwl_power_initialize);
 int iwl_power_temperature_change(struct iwl_priv *priv)
 {
 	int ret = 0;
-	u16 new_critical = priv->power_data.critical_power_setting;
 	s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
+	u16 new_critical = priv->power_data.critical_power_setting;
 
 	if (temperature > IWL_CT_KILL_TEMPERATURE)
 		return 0;
@@ -434,7 +416,7 @@ static void iwl_bg_set_power_save(struct
 {
 	struct iwl_priv *priv = container_of(work,
 				struct iwl_priv, set_power_save.work);
-	IWL_DEBUG(IWL_DL_STATE, "update power\n");
+	IWL_DEBUG_POWER(priv, "update power\n");
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-power.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -42,22 +42,26 @@ enum {
 	IWL_POWER_INDEX_5,
 	IWL_POWER_AUTO,
 	IWL_POWER_MAX = IWL_POWER_AUTO,
-	IWL_POWER_AC,
-	IWL_POWER_BATTERY,
 };
 
 enum {
 	IWL_POWER_SYS_AUTO,
 	IWL_POWER_SYS_AC,
 	IWL_POWER_SYS_BATTERY,
+	IWL_POWER_SYS_MAX,
 };
 
-#define IWL_POWER_LIMIT		0x08
-#define IWL_POWER_MASK		0x0F
-#define IWL_POWER_ENABLED	0x10
 
 /* Power management (not Tx power) structures */
 
+#define NOSLP cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
+				     cpu_to_le32(X1), \
+				     cpu_to_le32(X2), \
+				     cpu_to_le32(X3), \
+				     cpu_to_le32(X4)}
 struct iwl_power_vec_entry {
 	struct iwl_powertable_cmd cmd;
 	u8 no_dtim;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-prph.h	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 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
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -47,7 +47,7 @@ static int iwl_rfkill_soft_rf_kill(void
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return 0;
 
-	IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
+	IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state);
 	mutex_lock(&priv->mutex);
 
 	switch (state) {
@@ -62,7 +62,8 @@ static int iwl_rfkill_soft_rf_kill(void
 		iwl_radio_kill_sw_disable_radio(priv);
 		break;
 	default:
-		IWL_WARNING("we received unexpected RFKILL state %d\n", state);
+		IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
+			state);
 		break;
 	}
 out_unlock:
@@ -78,10 +79,10 @@ int iwl_rfkill_init(struct iwl_priv *pri
 
 	BUG_ON(device == NULL);
 
-	IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
+	IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
 	priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
 	if (!priv->rfkill) {
-		IWL_ERROR("Unable to allocate RFKILL device.\n");
+		IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
 		ret = -ENOMEM;
 		goto error;
 	}
@@ -97,11 +98,11 @@ int iwl_rfkill_init(struct iwl_priv *pri
 
 	ret = rfkill_register(priv->rfkill);
 	if (ret) {
-		IWL_ERROR("Unable to register RFKILL: %d\n", ret);
+		IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
 		goto free_rfkill;
 	}
 
-	IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+	IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
 	return ret;
 
 free_rfkill:
@@ -110,7 +111,7 @@ free_rfkill:
 	priv->rfkill = NULL;
 
 error:
-	IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+	IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
 	return ret;
 }
 EXPORT_SYMBOL(iwl_rfkill_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -125,9 +125,10 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
  */
 int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
 {
-	u32 reg = 0;
-	int ret = 0;
 	unsigned long flags;
+	u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
+	u32 reg;
+	int ret = 0;
 
 	spin_lock_irqsave(&q->lock, flags);
 
@@ -149,15 +150,14 @@ int iwl_rx_queue_update_write_ptr(struct
 			goto exit_unlock;
 
 		/* Device expects a multiple of 8 */
-		iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
-				     q->write & ~0x7);
+		iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
 		iwl_release_nic_access(priv);
 
 	/* Else device is assumed to be awake */
-	} else
+	} else {
 		/* Device expects a multiple of 8 */
-		iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
+		iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+	}
 
 	q->need_update = 0;
 
@@ -262,8 +262,7 @@ void iwl_rx_allocate(struct iwl_priv *pr
 		rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
 				     GFP_KERNEL);
 		if (!rxb->skb) {
-			printk(KERN_CRIT DRV_NAME
-				   "Can not allocate SKB buffers\n");
+			IWL_CRIT(priv, "Can not allocate SKB buffers\n");
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
 			 * more buffers it will schedule replenish */
@@ -495,7 +494,7 @@ void iwl_rx_missed_beacon_notif(struct i
 
 	missed_beacon = &pkt->u.missed_beacon;
 	if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
-		IWL_DEBUG_CALIB("missed bcn cnsq %d totl %d rcd %d expctd %d\n",
+		IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
 		    le32_to_cpu(missed_beacon->consequtive_missed_beacons),
 		    le32_to_cpu(missed_beacon->total_missed_becons),
 		    le32_to_cpu(missed_beacon->num_recvd_beacons),
@@ -542,7 +541,7 @@ static void iwl_rx_calc_noise(struct iwl
 	else
 		priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
-	IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
+	IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
 			bcn_silence_a, bcn_silence_b, bcn_silence_c,
 			priv->last_rx_noise);
 }
@@ -555,7 +554,7 @@ void iwl_rx_statistics(struct iwl_priv *
 	int change;
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
-	IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(priv->statistics), pkt->len);
 
 	change = ((priv->statistics.general.temperature !=
@@ -742,13 +741,13 @@ static void iwl_dbg_report_frame(struct
 		 * MAC addresses show just the last byte (for brevity),
 		 *    but you can hack it to show more, if you'd like to. */
 		if (dataframe)
-			IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+			IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
 				     "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
 				     title, le16_to_cpu(fc), header->addr1[5],
 				     length, rssi, channel, bitrate);
 		else {
 			/* src/dst addresses assume managed mode */
-			IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, src=0x%02x, "
+			IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
 				     "len=%u, rssi=%d, tim=%lu usec, "
 				     "phy=0x%02x, chnl=%d\n",
 				     title, le16_to_cpu(fc), header->addr1[5],
@@ -773,10 +772,10 @@ static void iwl_update_rx_stats(struct i
 /*
  * returns non-zero if packet should be dropped
  */
-static int iwl_set_decrypted_flag(struct iwl_priv *priv,
-				      struct ieee80211_hdr *hdr,
-				      u32 decrypt_res,
-				      struct ieee80211_rx_status *stats)
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+			   struct ieee80211_hdr *hdr,
+			   u32 decrypt_res,
+			   struct ieee80211_rx_status *stats)
 {
 	u16 fc = le16_to_cpu(hdr->frame_control);
 
@@ -786,7 +785,7 @@ static int iwl_set_decrypted_flag(struct
 	if (!(fc & IEEE80211_FCTL_PROTECTED))
 		return 0;
 
-	IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
+	IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res);
 	switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
 	case RX_RES_STATUS_SEC_TYPE_TKIP:
 		/* The uCode has got a bad phase 1 Key, pushes the packet.
@@ -800,13 +799,13 @@ static int iwl_set_decrypted_flag(struct
 		    RX_RES_STATUS_BAD_ICV_MIC) {
 			/* bad ICV, the packet is destroyed since the
 			 * decryption is inplace, drop it */
-			IWL_DEBUG_RX("Packet destroyed\n");
+			IWL_DEBUG_RX(priv, "Packet destroyed\n");
 			return -1;
 		}
 	case RX_RES_STATUS_SEC_TYPE_CCMP:
 		if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
 		    RX_RES_STATUS_DECRYPT_OK) {
-			IWL_DEBUG_RX("hw decrypt successfully!!!\n");
+			IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n");
 			stats->flag |= RX_FLAG_DECRYPTED;
 		}
 		break;
@@ -816,6 +815,7 @@ static int iwl_set_decrypted_flag(struct
 	}
 	return 0;
 }
+EXPORT_SYMBOL(iwl_set_decrypted_flag);
 
 static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
 {
@@ -870,7 +870,7 @@ static u32 iwl_translate_rx_status(struc
 		break;
 	};
 
-	IWL_DEBUG_RX("decrypt_in:0x%x  decrypt_out = 0x%x\n",
+	IWL_DEBUG_RX(priv, "decrypt_in:0x%x  decrypt_out = 0x%x\n",
 					decrypt_in, decrypt_out);
 
 	return decrypt_out;
@@ -895,7 +895,7 @@ static void iwl_pass_packet_to_mac80211(
 		rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
 
 	if (!rx_start) {
-		IWL_ERROR("MPDU frame without a PHY data\n");
+		IWL_ERR(priv, "MPDU frame without a PHY data\n");
 		return;
 	}
 	if (include_phy) {
@@ -934,8 +934,8 @@ static void iwl_pass_packet_to_mac80211(
 
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
-		IWL_DEBUG_DROP_LIMIT
-		    ("Dropping packet while interface is not open.\n");
+		IWL_DEBUG_DROP_LIMIT(priv,
+		    "Dropping packet while interface is not open.\n");
 		return;
 	}
 
@@ -1007,7 +1007,7 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 	/*rx_status.flag |= RX_FLAG_TSFT;*/
 
 	if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
-		IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
+		IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
 				rx_start->cfg_phy_cnt);
 		return;
 	}
@@ -1021,7 +1021,7 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 	}
 
 	if (!rx_start) {
-		IWL_ERROR("MPDU frame without a PHY data\n");
+		IWL_ERR(priv, "MPDU frame without a PHY data\n");
 		return;
 	}
 
@@ -1045,7 +1045,7 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 
 	if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
 	    !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
-		IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
+		IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
 				le32_to_cpu(*rx_end));
 		return;
 	}
@@ -1078,7 +1078,7 @@ void iwl_rx_reply_rx(struct iwl_priv *pr
 	if (unlikely(priv->debug_level & IWL_DL_RX))
 		iwl_dbg_report_frame(priv, rx_start, len, header, 1);
 #endif
-	IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
+	IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
 		rx_status.signal, rx_status.noise, rx_status.signal,
 		(unsigned long long)rx_status.mactime);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 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
@@ -46,15 +46,6 @@
 #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
 #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
 
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request.  This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH       __constant_cpu_to_le16(1)  /* packets */
-#define IWL_ACTIVE_QUIET_TIME       __constant_cpu_to_le16(10)  /* msec */
-
 /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
  * Must be set longer than active dwell time.
  * For the most reliable scan, set > AP beacon interval (typically 100msec). */
@@ -63,7 +54,6 @@
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-#define IWL_SCAN_PROBE_MASK(n) 	cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
 
 
 /**
@@ -80,12 +70,12 @@ int iwl_scan_cancel(struct iwl_priv *pri
 
 	if (test_bit(STATUS_SCANNING, &priv->status)) {
 		if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-			IWL_DEBUG_SCAN("Queuing scan abort.\n");
+			IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
 			set_bit(STATUS_SCAN_ABORTING, &priv->status);
 			queue_work(priv->workqueue, &priv->abort_scan);
 
 		} else
-			IWL_DEBUG_SCAN("Scan abort already in progress.\n");
+			IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
 
 		return test_bit(STATUS_SCANNING, &priv->status);
 	}
@@ -119,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_p
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+int iwl_send_scan_abort(struct iwl_priv *priv)
 {
 	int ret = 0;
 	struct iwl_rx_packet *res;
@@ -150,7 +140,7 @@ static int iwl_send_scan_abort(struct iw
 		 * can occur if we send the scan abort before we
 		 * the microcode has notified us that a scan is
 		 * completed. */
-		IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
+		IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status);
 		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 		clear_bit(STATUS_SCAN_HW, &priv->status);
 	}
@@ -160,7 +150,7 @@ static int iwl_send_scan_abort(struct iw
 
 	return ret;
 }
-
+EXPORT_SYMBOL(iwl_send_scan_abort);
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
 static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -171,7 +161,7 @@ static void iwl_rx_reply_scan(struct iwl
 	struct iwl_scanreq_notification *notif =
 	    (struct iwl_scanreq_notification *)pkt->u.raw;
 
-	IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
+	IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
 }
 
@@ -183,7 +173,7 @@ static void iwl_rx_scan_start_notif(stru
 	struct iwl_scanstart_notification *notif =
 	    (struct iwl_scanstart_notification *)pkt->u.raw;
 	priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
-	IWL_DEBUG_SCAN("Scan start: "
+	IWL_DEBUG_SCAN(priv, "Scan start: "
 		       "%d [802.11%s] "
 		       "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
 		       notif->channel,
@@ -202,7 +192,7 @@ static void iwl_rx_scan_results_notif(st
 	struct iwl_scanresults_notification *notif =
 	    (struct iwl_scanresults_notification *)pkt->u.raw;
 
-	IWL_DEBUG_SCAN("Scan ch.res: "
+	IWL_DEBUG_SCAN(priv, "Scan ch.res: "
 		       "%d [802.11%s] "
 		       "(TSF: 0x%08X:%08X) - %d "
 		       "elapsed=%lu usec (%dms since last)\n",
@@ -228,7 +218,7 @@ static void iwl_rx_scan_complete_notif(s
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 	struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
 
-	IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
+	IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
 		       scan_notif->scanned_channels,
 		       scan_notif->tsf_low,
 		       scan_notif->tsf_high, scan_notif->status);
@@ -237,10 +227,7 @@ static void iwl_rx_scan_complete_notif(s
 	/* The HW is no longer scanning */
 	clear_bit(STATUS_SCAN_HW, &priv->status);
 
-	/* The scan completion notification came in, so kill that timer... */
-	cancel_delayed_work(&priv->scan_check);
-
-	IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
+	IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
 		       (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
 						"2.4" : "5.2",
 		       jiffies_to_msecs(elapsed_jiffies
@@ -258,7 +245,7 @@ static void iwl_rx_scan_complete_notif(s
 	 * then we reset the scan state machine and terminate,
 	 * re-queuing another scan if one has been requested */
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_INFO("Aborted scan completed.\n");
+		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
 		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 	} else {
 		/* If there are more bands on this scan pass reschedule */
@@ -268,11 +255,11 @@ static void iwl_rx_scan_complete_notif(s
 
 	priv->last_scan_jiffies = jiffies;
 	priv->next_scan_jiffies = 0;
-	IWL_DEBUG_INFO("Setting scan to off\n");
+	IWL_DEBUG_INFO(priv, "Setting scan to off\n");
 
 	clear_bit(STATUS_SCANNING, &priv->status);
 
-	IWL_DEBUG_INFO("Scan took %dms\n",
+	IWL_DEBUG_INFO(priv, "Scan took %dms\n",
 		jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
 
 	queue_work(priv->workqueue, &priv->scan_completed);
@@ -296,9 +283,9 @@ void iwl_setup_rx_scan_handlers(struct i
 }
 EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
 
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
-					    enum ieee80211_band band,
-					    u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+				     enum ieee80211_band band,
+				     u8 n_probes)
 {
 	if (band == IEEE80211_BAND_5GHZ)
 		return IWL_ACTIVE_DWELL_TIME_52 +
@@ -307,9 +294,10 @@ static inline u16 iwl_get_active_dwell_t
 		return IWL_ACTIVE_DWELL_TIME_24 +
 			IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
 }
+EXPORT_SYMBOL(iwl_get_active_dwell_time);
 
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
-				      enum ieee80211_band band)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+			       enum ieee80211_band band)
 {
 	u16 passive = (band == IEEE80211_BAND_2GHZ) ?
 	    IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -327,6 +315,7 @@ static u16 iwl_get_passive_dwell_time(st
 
 	return passive;
 }
+EXPORT_SYMBOL(iwl_get_passive_dwell_time);
 
 static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 				     enum ieee80211_band band,
@@ -363,7 +352,7 @@ static int iwl_get_channels_for_scan(str
 
 		ch_info = iwl_get_channel_info(priv, band, channel);
 		if (!is_channel_valid(ch_info)) {
-			IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+			IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
 					channel);
 			continue;
 		}
@@ -392,7 +381,7 @@ static int iwl_get_channels_for_scan(str
 		else
 			scan_ch->tx_gain = ((1 << 5) | (5 << 3));
 
-		IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n",
+		IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
 			       channel, le32_to_cpu(scan_ch->type),
 			       (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
 				"ACTIVE" : "PASSIVE",
@@ -403,7 +392,7 @@ static int iwl_get_channels_for_scan(str
 		added++;
 	}
 
-	IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+	IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
 	return added;
 }
 
@@ -419,21 +408,21 @@ void iwl_init_scan_params(struct iwl_pri
 int iwl_scan_initiate(struct iwl_priv *priv)
 {
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+		IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
 		return -EIO;
 	}
 
 	if (test_bit(STATUS_SCANNING, &priv->status)) {
-		IWL_DEBUG_SCAN("Scan already in progress.\n");
+		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
 		return -EAGAIN;
 	}
 
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN("Scan request while abort pending\n");
+		IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
 		return -EAGAIN;
 	}
 
-	IWL_DEBUG_INFO("Starting scan...\n");
+	IWL_DEBUG_INFO(priv, "Starting scan...\n");
 	if (priv->cfg->sku & IWL_SKU_G)
 		priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
 	if (priv->cfg->sku & IWL_SKU_A)
@@ -448,9 +437,77 @@ int iwl_scan_initiate(struct iwl_priv *p
 }
 EXPORT_SYMBOL(iwl_scan_initiate);
 
+#define IWL_DELAY_NEXT_SCAN (HZ*2)
+
+int iwl_mac_hw_scan(struct ieee80211_hw *hw,
+		     struct cfg80211_scan_request *req)
+{
+	unsigned long flags;
+	struct iwl_priv *priv = hw->priv;
+	int ret;
+	u8 *ssid = NULL;
+	size_t ssid_len = 0;
+
+	if (req->n_ssids) {
+		ssid = req->ssids[0].ssid;
+		ssid_len = req->ssids[0].ssid_len;
+	}
+
+	IWL_DEBUG_MAC80211(priv, "enter\n");
+
+	mutex_lock(&priv->mutex);
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (!iwl_is_ready_rf(priv)) {
+		ret = -EIO;
+		IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
+		goto out_unlock;
+	}
+
+	/* We don't schedule scan within next_scan_jiffies period.
+	 * Avoid scanning during possible EAPOL exchange, return
+	 * success immediately.
+	 */
+	if (priv->next_scan_jiffies &&
+	    time_after(priv->next_scan_jiffies, jiffies)) {
+		IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
+		queue_work(priv->workqueue, &priv->scan_completed);
+		ret = 0;
+		goto out_unlock;
+	}
+
+	/* if we just finished scan ask for delay */
+	if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
+	    time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+		IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
+		queue_work(priv->workqueue, &priv->scan_completed);
+		ret = 0;
+		goto out_unlock;
+	}
+
+	if (ssid_len) {
+		priv->one_direct_scan = 1;
+		priv->direct_ssid_len =  ssid_len;
+		memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
+	} else {
+		priv->one_direct_scan = 0;
+	}
+
+	ret = iwl_scan_initiate(priv);
+
+	IWL_DEBUG_MAC80211(priv, "leave\n");
+
+out_unlock:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	mutex_unlock(&priv->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(iwl_mac_hw_scan);
+
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
-static void iwl_bg_scan_check(struct work_struct *data)
+void iwl_bg_scan_check(struct work_struct *data)
 {
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, scan_check.work);
@@ -461,7 +518,7 @@ static void iwl_bg_scan_check(struct wor
 	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_SCANNING, &priv->status) ||
 	    test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
+		IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
 			"adapter (%dms)\n",
 			jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
 
@@ -470,6 +527,8 @@ static void iwl_bg_scan_check(struct wor
 	}
 	mutex_unlock(&priv->mutex);
 }
+EXPORT_SYMBOL(iwl_bg_scan_check);
+
 /**
  * iwl_supported_rate_to_ie - fill in the supported rate in IE field
  *
@@ -527,10 +586,10 @@ static void iwl_ht_cap_to_ie(const struc
  * iwl_fill_probe_req - fill in all required fields and IE for probe request
  */
 
-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
-				  enum ieee80211_band band,
-				  struct ieee80211_mgmt *frame,
-				  int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv,
+		       enum ieee80211_band band,
+		       struct ieee80211_mgmt *frame,
+		       int left)
 {
 	int len = 0;
 	u8 *pos = NULL;
@@ -624,6 +683,7 @@ static u16 iwl_fill_probe_req(struct iwl
 
 	return (u16)len;
 }
+EXPORT_SYMBOL(iwl_fill_probe_req);
 
 static void iwl_bg_request_scan(struct work_struct *data)
 {
@@ -649,8 +709,10 @@ static void iwl_bg_request_scan(struct w
 
 	mutex_lock(&priv->mutex);
 
+	cancel_delayed_work(&priv->scan_check);
+
 	if (!iwl_is_ready(priv)) {
-		IWL_WARNING("request scan called when driver not ready.\n");
+		IWL_WARN(priv, "request scan called when driver not ready.\n");
 		goto done;
 	}
 
@@ -662,34 +724,34 @@ static void iwl_bg_request_scan(struct w
 	/* This should never be called or scheduled if there is currently
 	 * a scan active in the hardware. */
 	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
+		IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
 			       "Ignoring second request.\n");
 		ret = -EIO;
 		goto done;
 	}
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
 		goto done;
 	}
 
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC("Scan request while abort pending.  Queuing.\n");
+		IWL_DEBUG_HC(priv, "Scan request while abort pending.  Queuing.\n");
 		goto done;
 	}
 
 	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
 		goto done;
 	}
 
 	if (!test_bit(STATUS_READY, &priv->status)) {
-		IWL_DEBUG_HC("Scan request while uninitialized.  Queuing.\n");
+		IWL_DEBUG_HC(priv, "Scan request while uninitialized.  Queuing.\n");
 		goto done;
 	}
 
 	if (!priv->scan_bands) {
-		IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+		IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
 		goto done;
 	}
 
@@ -714,7 +776,7 @@ static void iwl_bg_request_scan(struct w
 		u32 scan_suspend_time = 100;
 		unsigned long flags;
 
-		IWL_DEBUG_INFO("Scanning while associated...\n");
+		IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
 
 		spin_lock_irqsave(&priv->lock, flags);
 		interval = priv->beacon_int;
@@ -729,13 +791,13 @@ static void iwl_bg_request_scan(struct w
 		scan_suspend_time = (extra |
 		    ((suspend_time % interval) * 1024));
 		scan->suspend_time = cpu_to_le32(scan_suspend_time);
-		IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+		IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
 			       scan_suspend_time, interval);
 	}
 
 	/* We should add the ability for user to lock to PASSIVE ONLY */
 	if (priv->one_direct_scan) {
-		IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
+		IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n",
 				print_ssid(ssid, priv->direct_ssid,
 					   priv->direct_ssid_len));
 		scan->direct_scan[0].id = WLAN_EID_SSID;
@@ -744,7 +806,7 @@ static void iwl_bg_request_scan(struct w
 		       priv->direct_ssid, priv->direct_ssid_len);
 		n_probes++;
 	} else {
-		IWL_DEBUG_SCAN("Start indirect scan.\n");
+		IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
 	}
 
 	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
@@ -773,7 +835,7 @@ static void iwl_bg_request_scan(struct w
 		if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
 			rx_chain = 0x6;
 	} else {
-		IWL_WARNING("Invalid scan band count\n");
+		IWL_WARN(priv, "Invalid scan band count\n");
 		goto done;
 	}
 
@@ -806,7 +868,7 @@ static void iwl_bg_request_scan(struct w
 			(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
 	if (scan->channel_count == 0) {
-		IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
 		goto done;
 	}
 
@@ -839,7 +901,7 @@ static void iwl_bg_request_scan(struct w
 	mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_abort_scan(struct work_struct *work)
+void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
@@ -853,26 +915,29 @@ static void iwl_bg_abort_scan(struct wor
 
 	mutex_unlock(&priv->mutex);
 }
+EXPORT_SYMBOL(iwl_bg_abort_scan);
 
-static void iwl_bg_scan_completed(struct work_struct *work)
+void iwl_bg_scan_completed(struct work_struct *work)
 {
 	struct iwl_priv *priv =
 	    container_of(work, struct iwl_priv, scan_completed);
 
-	IWL_DEBUG_SCAN("SCAN complete scan\n");
+	IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
+
+	cancel_delayed_work(&priv->scan_check);
+
+	ieee80211_scan_completed(priv->hw, false);
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
 
-	ieee80211_scan_completed(priv->hw);
-
 	/* Since setting the TXPOWER may have been deferred while
 	 * performing the scan, fire one off */
 	mutex_lock(&priv->mutex);
 	iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
 	mutex_unlock(&priv->mutex);
 }
-
+EXPORT_SYMBOL(iwl_bg_scan_completed);
 
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -146,7 +146,7 @@ static int iwl_get_measurement(struct iw
 
 	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
 		rc = -EIO;
 	}
 
@@ -154,9 +154,9 @@ static int iwl_get_measurement(struct iw
 	switch (spectrum_resp_status) {
 	case 0:		/* Command will be handled */
 		if (res->u.spectrum.id != 0xff) {
-			IWL_DEBUG_INFO
-			    ("Replaced existing measurement: %d\n",
-			     res->u.spectrum.id);
+			IWL_DEBUG_INFO(priv,
+				"Replaced existing measurement: %d\n",
+				res->u.spectrum.id);
 			priv->measurement_status &= ~MEASUREMENT_READY;
 		}
 		priv->measurement_status |= MEASUREMENT_ACTIVE;
@@ -181,7 +181,7 @@ static void iwl_rx_spectrum_measure_noti
 	struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
 
 	if (!report->state) {
-		IWL_DEBUG(IWL_DL_11H,
+		IWL_DEBUG_11H(priv,
 			"Spectrum Measure Notification: Start\n");
 		return;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-spectrum.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ieee80211 subsystem header files.
  *
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -60,7 +60,7 @@ u8 iwl_find_station(struct iwl_priv *pri
 			goto out;
 		}
 
-	IWL_DEBUG_ASSOC_LIMIT("can not find STA %pM total %d\n",
+	IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
 			      addr, priv->num_stations);
 
  out:
@@ -86,11 +86,13 @@ static void iwl_sta_ucode_activate(struc
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
-	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
-		IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
+	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
+	    !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+		IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
+			sta_id);
 
 	priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
-	IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n",
+	IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
 			priv->stations[sta_id].sta.sta.addr);
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -105,13 +107,13 @@ static int iwl_add_sta_callback(struct i
 	u8 sta_id = addsta->sta.sta_id;
 
 	if (!skb) {
-		IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
+		IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
 		return 1;
 	}
 
 	res = (struct iwl_rx_packet *)skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
 			  res->hdr.flags);
 		return 1;
 	}
@@ -121,7 +123,7 @@ static int iwl_add_sta_callback(struct i
 		iwl_sta_ucode_activate(priv, sta_id);
 		 /* fall through */
 	default:
-		IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n",
+		IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
 			     res->u.add_sta.status);
 		break;
 	}
@@ -130,7 +132,7 @@ static int iwl_add_sta_callback(struct i
 	return 1;
 }
 
-static int iwl_send_add_sta(struct iwl_priv *priv,
+int iwl_send_add_sta(struct iwl_priv *priv,
 		     struct iwl_addsta_cmd *sta, u8 flags)
 {
 	struct iwl_rx_packet *res = NULL;
@@ -155,7 +157,7 @@ static int iwl_send_add_sta(struct iwl_p
 
 	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
 			  res->hdr.flags);
 		ret = -EIO;
 	}
@@ -164,11 +166,11 @@ static int iwl_send_add_sta(struct iwl_p
 		switch (res->u.add_sta.status) {
 		case ADD_STA_SUCCESS_MSK:
 			iwl_sta_ucode_activate(priv, sta->sta.sta_id);
-			IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
+			IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
 			break;
 		default:
 			ret = -EIO;
-			IWL_WARNING("REPLY_ADD_STA failed\n");
+			IWL_WARN(priv, "REPLY_ADD_STA failed\n");
 			break;
 		}
 	}
@@ -178,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_p
 
 	return ret;
 }
+EXPORT_SYMBOL(iwl_send_add_sta);
 
 static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 				   struct ieee80211_sta_ht_cap *sta_ht_inf)
@@ -204,7 +207,7 @@ static void iwl_set_ht_add_station(struc
 	case WLAN_HT_CAP_SM_PS_DISABLED:
 		break;
 	default:
-		IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+		IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
 		break;
 	}
 
@@ -269,7 +272,7 @@ u8 iwl_add_station_flags(struct iwl_priv
 
 	station = &priv->stations[sta_id];
 	station->used = IWL_STA_DRIVER_ACTIVE;
-	IWL_DEBUG_ASSOC("Add STA to driver ID %d: %pM\n",
+	IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
 			sta_id, addr);
 	priv->num_stations++;
 
@@ -301,13 +304,13 @@ static void iwl_sta_ucode_deactivate(str
 
 	BUG_ON(sta_id == IWL_INVALID_STATION);
 
-	IWL_DEBUG_ASSOC("Removed STA from Ucode: %pM\n", addr);
+	IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr);
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
 	/* Ucode must be active and driver must be non active */
 	if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
-		IWL_ERROR("removed non active STA %d\n", sta_id);
+		IWL_ERR(priv, "removed non active STA %d\n", sta_id);
 
 	priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
 
@@ -324,13 +327,13 @@ static int iwl_remove_sta_callback(struc
 	const char *addr = rm_sta->addr;
 
 	if (!skb) {
-		IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
+		IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
 		return 1;
 	}
 
 	res = (struct iwl_rx_packet *)skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
 		res->hdr.flags);
 		return 1;
 	}
@@ -340,7 +343,7 @@ static int iwl_remove_sta_callback(struc
 		iwl_sta_ucode_deactivate(priv, addr);
 		break;
 	default:
-		IWL_ERROR("REPLY_REMOVE_STA failed\n");
+		IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
 		break;
 	}
 
@@ -378,7 +381,7 @@ static int iwl_send_remove_station(struc
 
 	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-		IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
 			  res->hdr.flags);
 		ret = -EIO;
 	}
@@ -387,11 +390,11 @@ static int iwl_send_remove_station(struc
 		switch (res->u.rem_sta.status) {
 		case REM_STA_SUCCESS_MSK:
 			iwl_sta_ucode_deactivate(priv, addr);
-			IWL_DEBUG_ASSOC("REPLY_REMOVE_STA PASSED\n");
+			IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
 			break;
 		default:
 			ret = -EIO;
-			IWL_ERROR("REPLY_REMOVE_STA failed\n");
+			IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
 			break;
 		}
 	}
@@ -429,17 +432,17 @@ int iwl_remove_station(struct iwl_priv *
 	if (unlikely(sta_id == IWL_INVALID_STATION))
 		goto out;
 
-	IWL_DEBUG_ASSOC("Removing STA from driver:%d  %pM\n",
+	IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d  %pM\n",
 		sta_id, addr);
 
 	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-		IWL_ERROR("Removing %pM but non DRIVER active\n",
+		IWL_ERR(priv, "Removing %pM but non DRIVER active\n",
 				addr);
 		goto out;
 	}
 
 	if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
-		IWL_ERROR("Removing %pM but non UCODE active\n",
+		IWL_ERR(priv, "Removing %pM but non UCODE active\n",
 				addr);
 		goto out;
 	}
@@ -469,13 +472,14 @@ EXPORT_SYMBOL(iwl_remove_station);
 void iwl_clear_stations_table(struct iwl_priv *priv)
 {
 	unsigned long flags;
+	int i;
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
 	if (iwl_is_alive(priv) &&
 	   !test_bit(STATUS_EXIT_PENDING, &priv->status) &&
 	   iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
-		IWL_ERROR("Couldn't clear the station table\n");
+		IWL_ERR(priv, "Couldn't clear the station table\n");
 
 	priv->num_stations = 0;
 	memset(priv->stations, 0, sizeof(priv->stations));
@@ -483,11 +487,17 @@ void iwl_clear_stations_table(struct iwl
 	/* clean ucode key table bit map */
 	priv->ucode_key_table = 0;
 
+	/* keep track of static keys */
+	for (i = 0; i < WEP_KEYS_MAX ; i++) {
+		if (priv->wep_keys[i].key_size)
+			test_and_set_bit(i, &priv->ucode_key_table);
+	}
+
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 EXPORT_SYMBOL(iwl_clear_stations_table);
 
-static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
 {
 	int i;
 
@@ -497,6 +507,7 @@ static int iwl_get_free_ucode_key_index(
 
 	return WEP_INVALID_OFFSET;
 }
+EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
 
 int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
 {
@@ -551,13 +562,13 @@ int iwl_remove_default_wep_key(struct iw
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
 	if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
-		IWL_ERROR("index %d not used in uCode key table.\n",
+		IWL_ERR(priv, "index %d not used in uCode key table.\n",
 			  keyconf->keyidx);
 
 	priv->default_wep_key--;
 	memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
 	ret = iwl_send_static_wepkey_cmd(priv, 1);
-	IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
+	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
 		      keyconf->keyidx, ret);
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
@@ -573,7 +584,7 @@ int iwl_set_default_wep_key(struct iwl_p
 
 	if (keyconf->keylen != WEP_KEY_LEN_128 &&
 	    keyconf->keylen != WEP_KEY_LEN_64) {
-		IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
+		IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
 		return -EINVAL;
 	}
 
@@ -585,7 +596,7 @@ int iwl_set_default_wep_key(struct iwl_p
 	priv->default_wep_key++;
 
 	if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
-		IWL_ERROR("index %d already used in uCode key table.\n",
+		IWL_ERR(priv, "index %d already used in uCode key table.\n",
 			keyconf->keyidx);
 
 	priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
@@ -593,7 +604,7 @@ int iwl_set_default_wep_key(struct iwl_p
 							keyconf->keylen);
 
 	ret = iwl_send_static_wepkey_cmd(priv, 0);
-	IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
+	IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
 		keyconf->keylen, keyconf->keyidx, ret);
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
@@ -641,7 +652,7 @@ static int iwl_set_wep_dynamic_key_info(
 	 * in uCode. */
 
 	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for new kew");
+		"no space for a new key");
 
 	priv->stations[sta_id].sta.key.key_flags = key_flags;
 	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -689,7 +700,7 @@ static int iwl_set_ccmp_dynamic_key_info
 	 * in uCode. */
 
 	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for new kew");
+		"no space for a new key");
 
 	priv->stations[sta_id].sta.key.key_flags = key_flags;
 	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -708,6 +719,14 @@ static int iwl_set_tkip_dynamic_key_info
 {
 	unsigned long flags;
 	int ret = 0;
+	__le16 key_flags = 0;
+
+	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+	key_flags &= ~STA_KEY_FLG_INVALID;
+
+	if (sta_id == priv->hw_params.bcast_sta_id)
+		key_flags |= STA_KEY_MULTICAST_MSK;
 
 	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
@@ -725,7 +744,10 @@ static int iwl_set_tkip_dynamic_key_info
 	 * in uCode. */
 
 	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-		"no space for new kew");
+		"no space for a new key");
+
+	priv->stations[sta_id].sta.key.key_flags = key_flags;
+
 
 	/* This copy is acutally not needed: we get the key with each TX */
 	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -743,13 +765,11 @@ void iwl_update_tkip_key(struct iwl_priv
 {
 	u8 sta_id = IWL_INVALID_STATION;
 	unsigned long flags;
-	__le16 key_flags = 0;
 	int i;
-	DECLARE_MAC_BUF(mac);
 
 	sta_id = iwl_find_station(priv, addr);
 	if (sta_id == IWL_INVALID_STATION) {
-		IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+		IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
 				   addr);
 		return;
 	}
@@ -760,16 +780,8 @@ void iwl_update_tkip_key(struct iwl_priv
 		return;
 	}
 
-	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
-	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-	key_flags &= ~STA_KEY_FLG_INVALID;
-
-	if (sta_id == priv->hw_params.bcast_sta_id)
-		key_flags |= STA_KEY_MULTICAST_MSK;
-
 	spin_lock_irqsave(&priv->sta_lock, flags);
 
-	priv->stations[sta_id].sta.key.key_flags = key_flags;
 	priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
 
 	for (i = 0; i < 5; i++)
@@ -801,7 +813,7 @@ int iwl_remove_dynamic_key(struct iwl_pr
 	key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
 	keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
 
-	IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
+	IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
 		      keyconf->keyidx, sta_id);
 
 	if (keyconf->keyidx != keyidx) {
@@ -815,7 +827,7 @@ int iwl_remove_dynamic_key(struct iwl_pr
 	}
 
 	if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
-		IWL_WARNING("Removing wrong key %d 0x%x\n",
+		IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
 			    keyconf->keyidx, key_flags);
 		spin_unlock_irqrestore(&priv->sta_lock, flags);
 		return 0;
@@ -823,7 +835,7 @@ int iwl_remove_dynamic_key(struct iwl_pr
 
 	if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
 		&priv->ucode_key_table))
-		IWL_ERROR("index %d not used in uCode key table.\n",
+		IWL_ERR(priv, "index %d not used in uCode key table.\n",
 			priv->stations[sta_id].sta.key.key_offset);
 	memset(&priv->stations[sta_id].keyinfo, 0,
 					sizeof(struct iwl_hw_key));
@@ -860,11 +872,12 @@ int iwl_set_dynamic_key(struct iwl_priv
 		ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
 		break;
 	default:
-		IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+		IWL_ERR(priv,
+			"Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
 		ret = -EINVAL;
 	}
 
-	IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+	IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
 		      keyconf->alg, keyconf->keylen, keyconf->keyidx,
 		      sta_id, ret);
 
@@ -877,13 +890,13 @@ static void iwl_dump_lq_cmd(struct iwl_p
 			   struct iwl_link_quality_cmd *lq)
 {
 	int i;
-	IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
-	IWL_DEBUG_RATE("lq ant 0x%X 0x%X\n",
+	IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
+	IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
 		       lq->general_params.single_stream_ant_msk,
 		       lq->general_params.dual_stream_ant_msk);
 
 	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
-		IWL_DEBUG_RATE("lq index %d 0x%X\n",
+		IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
 			       i, lq->rs_table[i].rate_n_flags);
 }
 #else
@@ -1060,7 +1073,7 @@ int iwl_get_sta_id(struct iwl_priv *priv
 		if (sta_id != IWL_INVALID_STATION)
 			return sta_id;
 
-		IWL_DEBUG_DROP("Station %pM not in station map. "
+		IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
 			       "Defaulting to broadcast...\n",
 			       hdr->addr1);
 		iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
@@ -1072,7 +1085,8 @@ int iwl_get_sta_id(struct iwl_priv *priv
 		return priv->hw_params.bcast_sta_id;
 
 	default:
-		IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
+		IWL_WARN(priv, "Unknown mode of operation: %d\n",
+			priv->iw_mode);
 		return priv->hw_params.bcast_sta_id;
 	}
 }
@@ -1125,8 +1139,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv
 	int sta_id;
 
 	sta_id = iwl_find_station(priv, addr);
-	if (sta_id == IWL_INVALID_STATION)
+	if (sta_id == IWL_INVALID_STATION) {
+		IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
 		return -ENXIO;
+	}
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
 	priv->stations[sta_id].sta.station_flags_msk = 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -54,8 +54,11 @@ void iwl_update_tkip_key(struct iwl_priv
 int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
 int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
 void iwl_clear_stations_table(struct iwl_priv *priv);
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
 int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
 int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
+int iwl_send_add_sta(struct iwl_priv *priv,
+		     struct iwl_addsta_cmd *sta, u8 flags);
 u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
 			int is_ap, u8 flags,
 			struct ieee80211_sta_ht_cap *ht_info);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -76,116 +76,6 @@ static inline void iwl_free_dma_ptr(stru
 	memset(ptr, 0, sizeof(*ptr));
 }
 
-static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
-	dma_addr_t addr = get_unaligned_le32(&tb->lo);
-	if (sizeof(dma_addr_t) > sizeof(u32))
-		addr |=
-		((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
-
-	return addr;
-}
-
-static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
-	return le16_to_cpu(tb->hi_n_len) >> 4;
-}
-
-static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
-				  dma_addr_t addr, u16 len)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-	u16 hi_n_len = len << 4;
-
-	put_unaligned_le32(addr, &tb->lo);
-	if (sizeof(dma_addr_t) > sizeof(u32))
-		hi_n_len |= ((addr >> 16) >> 16) & 0xF;
-
-	tb->hi_n_len = cpu_to_le16(hi_n_len);
-
-	tfd->num_tbs = idx + 1;
-}
-
-static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
-{
-	return tfd->num_tbs & 0x1f;
-}
-
-/**
- * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- * @priv - driver private data
- * @txq - tx queue
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
-	struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
-	struct iwl_tfd *tfd;
-	struct pci_dev *dev = priv->pci_dev;
-	int index = txq->q.read_ptr;
-	int i;
-	int num_tbs;
-
-	tfd = &tfd_tmp[index];
-
-	/* Sanity check on number of chunks */
-	num_tbs = iwl_tfd_get_num_tbs(tfd);
-
-	if (num_tbs >= IWL_NUM_OF_TBS) {
-		IWL_ERROR("Too many chunks: %i\n", num_tbs);
-		/* @todo issue fatal error, it is quite serious situation */
-		return;
-	}
-
-	/* Unmap tx_cmd */
-	if (num_tbs)
-		pci_unmap_single(dev,
-				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
-				pci_unmap_len(&txq->cmd[index]->meta, len),
-				PCI_DMA_BIDIRECTIONAL);
-
-	/* Unmap chunks, if any. */
-	for (i = 1; i < num_tbs; i++) {
-		pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
-				iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
-
-		if (txq->txb) {
-			dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
-			txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
-		}
-	}
-}
-
-static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
-					struct iwl_tfd *tfd,
-					dma_addr_t addr, u16 len)
-{
-
-	u32 num_tbs = iwl_tfd_get_num_tbs(tfd);
-
-	/* Each TFD can point to a maximum 20 Tx buffers */
-	if (num_tbs >= IWL_NUM_OF_TBS) {
-		IWL_ERROR("Error can not send more than %d chunks\n",
-			  IWL_NUM_OF_TBS);
-		return -EINVAL;
-	}
-
-	BUG_ON(addr & ~DMA_BIT_MASK(36));
-	if (unlikely(addr & ~IWL_TX_DMA_MASK))
-		IWL_ERROR("Unaligned address = %llx\n",
-			  (unsigned long long)addr);
-
-	iwl_tfd_set_tb(tfd, num_tbs, addr, len);
-
-	return 0;
-}
-
 /**
  * iwl_txq_update_write_ptr - Send new write index to hardware
  */
@@ -206,7 +96,7 @@ 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("Requesting wakeup, GP1 = 0x%x\n", reg);
+			IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
 			iwl_set_bit(priv, CSR_GP_CNTRL,
 				    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 			return ret;
@@ -241,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
  * Free all buffers.
  * 0-fill, but do not free "txq" descriptor structure.
  */
-static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
 {
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
@@ -254,7 +144,7 @@ static void iwl_tx_queue_free(struct iwl
 	/* first, empty all BD's */
 	for (; q->write_ptr != q->read_ptr;
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
-		iwl_hw_txq_free_tfd(priv, txq);
+		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 
 	len = sizeof(struct iwl_cmd) * q->n_window;
 
@@ -264,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl
 
 	/* De-alloc circular buffer of TFDs */
 	if (txq->q.n_bd)
-		pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+		pci_free_consistent(dev, priv->hw_params.tfd_size *
 				    txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 
 	/* De-alloc array of per-TFD driver data */
@@ -274,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl
 	/* 0-fill queue descriptor structure */
 	memset(txq, 0, sizeof(*txq));
 }
-
+EXPORT_SYMBOL(iwl_tx_queue_free);
 
 /**
  * iwl_cmd_queue_free - Deallocate DMA queue.
@@ -284,7 +174,7 @@ static void iwl_tx_queue_free(struct iwl
  * Free all buffers.
  * 0-fill, but do not free "txq" descriptor structure.
  */
-static void iwl_cmd_queue_free(struct iwl_priv *priv)
+void iwl_cmd_queue_free(struct iwl_priv *priv)
 {
 	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 	struct iwl_queue *q = &txq->q;
@@ -303,12 +193,14 @@ static void iwl_cmd_queue_free(struct iw
 
 	/* De-alloc circular buffer of TFDs */
 	if (txq->q.n_bd)
-		pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+		pci_free_consistent(dev, priv->hw_params.tfd_size *
 				    txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 
 	/* 0-fill queue descriptor structure */
 	memset(txq, 0, sizeof(*txq));
 }
+EXPORT_SYMBOL(iwl_cmd_queue_free);
+
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -388,6 +280,7 @@ static int iwl_tx_queue_alloc(struct iwl
 			      struct iwl_tx_queue *txq, u32 id)
 {
 	struct pci_dev *dev = priv->pci_dev;
+	size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
 
 	/* Driver private data, only for Tx (not command) queues,
 	 * not shared with device. */
@@ -395,22 +288,20 @@ static int iwl_tx_queue_alloc(struct iwl
 		txq->txb = kmalloc(sizeof(txq->txb[0]) *
 				   TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
 		if (!txq->txb) {
-			IWL_ERROR("kmalloc for auxiliary BD "
+			IWL_ERR(priv, "kmalloc for auxiliary BD "
 				  "structures failed\n");
 			goto error;
 		}
-	} else
+	} else {
 		txq->txb = NULL;
+	}
 
 	/* Circular buffer of transmit frame descriptors (TFDs),
 	 * shared with device */
-	txq->tfds = pci_alloc_consistent(dev,
-			sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
-			&txq->q.dma_addr);
+	txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
 
 	if (!txq->tfds) {
-		IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
-			  sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
+		IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
 		goto error;
 	}
 	txq->q.id = id;
@@ -424,42 +315,11 @@ static int iwl_tx_queue_alloc(struct iwl
 	return -ENOMEM;
 }
 
-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-				struct iwl_tx_queue *txq)
-{
-	int ret;
-	unsigned long flags;
-	int txq_id = txq->q.id;
-
-	spin_lock_irqsave(&priv->lock, flags);
-	ret = iwl_grab_nic_access(priv);
-	if (ret) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return ret;
-	}
-
-	/* Circular buffer (TFD queue in DRAM) physical base address */
-	iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
-			     txq->q.dma_addr >> 8);
-
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
-}
-
 /**
  * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
  */
-static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
-			     int slots_num, u32 txq_id)
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+		      int slots_num, u32 txq_id)
 {
 	int i, len;
 	int ret;
@@ -501,7 +361,7 @@ static int iwl_tx_queue_init(struct iwl_
 	iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 
 	/* Tell device where to find queue */
-	iwl_hw_tx_queue_init(priv, txq);
+	priv->cfg->ops->lib->txq_init(priv, txq);
 
 	return 0;
 err:
@@ -516,6 +376,8 @@ err:
 	}
 	return -ENOMEM;
 }
+EXPORT_SYMBOL(iwl_tx_queue_init);
+
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
  *
@@ -557,13 +419,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *p
 	ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
 				priv->hw_params.scd_bc_tbls_size);
 	if (ret) {
-		IWL_ERROR("Scheduler BC Table allocation failed\n");
+		IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
 		goto error_bc_tbls;
 	}
 	/* Alloc keep-warm buffer */
 	ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
 	if (ret) {
-		IWL_ERROR("Keep Warm allocation failed\n");
+		IWL_ERR(priv, "Keep Warm allocation failed\n");
 		goto error_kw;
 	}
 	spin_lock_irqsave(&priv->lock, flags);
@@ -589,7 +451,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *p
 		ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
 				       txq_id);
 		if (ret) {
-			IWL_ERROR("Tx %d queue init failed\n", txq_id);
+			IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
 			goto error;
 		}
 	}
@@ -778,14 +640,14 @@ static void iwl_tx_cmd_build_hwcrypto(st
 		memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
 		if (info->flags & IEEE80211_TX_CTL_AMPDU)
 			tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
-		IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+		IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
 		break;
 
 	case ALG_TKIP:
 		tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
 		ieee80211_get_tkip_key(keyconf, skb_frag,
 			IEEE80211_TKIP_P2_KEY, tx_cmd->key);
-		IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n");
+		IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
 		break;
 
 	case ALG_WEP:
@@ -797,12 +659,12 @@ static void iwl_tx_cmd_build_hwcrypto(st
 
 		memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
 
-		IWL_DEBUG_TX("Configuring packet for WEP encryption "
+		IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
 			     "with key %d\n", keyconf->keyidx);
 		break;
 
 	default:
-		printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg);
+		IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
 		break;
 	}
 }
@@ -822,7 +684,6 @@ 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 iwl_tfd *tfd;
 	struct iwl_tx_queue *txq;
 	struct iwl_queue *q;
 	struct iwl_cmd *out_cmd;
@@ -844,13 +705,13 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_DROP("Dropping - RF KILL\n");
+		IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
 		goto drop_unlock;
 	}
 
 	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
 	     IWL_INVALID_RATE) {
-		IWL_ERROR("ERROR: No TX rate available.\n");
+		IWL_ERR(priv, "ERROR: No TX rate available.\n");
 		goto drop_unlock;
 	}
 
@@ -858,11 +719,11 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	if (ieee80211_is_auth(fc))
-		IWL_DEBUG_TX("Sending AUTH frame\n");
+		IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
 	else if (ieee80211_is_assoc_req(fc))
-		IWL_DEBUG_TX("Sending ASSOC frame\n");
+		IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
 	else if (ieee80211_is_reassoc_req(fc))
-		IWL_DEBUG_TX("Sending REASSOC frame\n");
+		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
 #endif
 
 	/* drop all data frame if we are not associated */
@@ -872,7 +733,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	    (!iwl_is_associated(priv) ||
 	     ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
 	     !priv->assoc_station_added)) {
-		IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+		IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
 		goto drop_unlock;
 	}
 
@@ -883,12 +744,12 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	/* Find (or create) index into station table for destination station */
 	sta_id = iwl_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
-		IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
 		goto drop;
 	}
 
-	IWL_DEBUG_TX("station Id %d\n", sta_id);
+	IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
 
 	swq_id = skb_get_queue_mapping(skb);
 	txq_id = swq_id;
@@ -898,12 +759,14 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 		seq_number = priv->stations[sta_id].tid[tid].seq_number;
 		seq_number &= IEEE80211_SCTL_SEQ;
 		hdr->seq_ctrl = hdr->seq_ctrl &
-				__constant_cpu_to_le16(IEEE80211_SCTL_FRAG);
+				cpu_to_le16(IEEE80211_SCTL_FRAG);
 		hdr->seq_ctrl |= cpu_to_le16(seq_number);
 		seq_number += 0x10;
 		/* aggregation is on for this <sta,tid> */
-		if (info->flags & IEEE80211_TX_CTL_AMPDU)
+		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+			swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
+		}
 		priv->stations[sta_id].tid[tid].tfds_in_queue++;
 	}
 
@@ -913,10 +776,6 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	/* Set up first empty TFD within this queue's circular TFD buffer */
-	tfd = &txq->tfds[q->write_ptr];
-	memset(tfd, 0, sizeof(*tfd));
-
 	/* Set up driver data for this TFD */
 	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
 	txq->txb[q->write_ptr].skb[0] = skb;
@@ -940,6 +799,22 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	/* Copy MAC header from skb into command buffer */
 	memcpy(tx_cmd->hdr, hdr, hdr_len);
 
+
+	/* Total # bytes to be transmitted */
+	len = (u16)skb->len;
+	tx_cmd->len = cpu_to_le16(len);
+
+	if (info->control.hw_key)
+		iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+
+	/* TODO need this for burst mode later on */
+	iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+
+	/* set is_hcca to 0; it probably will never be implemented */
+	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
+
+	iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
+
 	/*
 	 * Use the first empty entry in this queue's command buffer array
 	 * to contain the Tx command and MAC header concatenated together
@@ -960,20 +835,30 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	else
 		len_org = 0;
 
+	/* Tell NIC about any 2-byte padding after MAC header */
+	if (len_org)
+		tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
 	txcmd_phys = pci_map_single(priv->pci_dev,
-				    out_cmd, sizeof(struct iwl_cmd),
+				    &out_cmd->hdr, len,
 				    PCI_DMA_BIDIRECTIONAL);
 	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
-	pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+	pci_unmap_len_set(&out_cmd->meta, len, len);
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
-	txcmd_phys += offsetof(struct iwl_cmd, hdr);
-	iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+						   txcmd_phys, len, 1, 0);
 
-	if (info->control.hw_key)
-		iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+	if (!ieee80211_has_morefrags(hdr->frame_control)) {
+		txq->need_update = 1;
+		if (qc)
+			priv->stations[sta_id].tid[tid].seq_number = seq_number;
+	} else {
+		wait_write_ptr = 1;
+		txq->need_update = 0;
+	}
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
@@ -981,44 +866,34 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	if (len) {
 		phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
 					   len, PCI_DMA_TODEVICE);
-		iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+		priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+							   phys_addr, len,
+							   0, 0);
 	}
 
-	/* Tell NIC about any 2-byte padding after MAC header */
-	if (len_org)
-		tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
-
-	/* Total # bytes to be transmitted */
-	len = (u16)skb->len;
-	tx_cmd->len = cpu_to_le16(len);
-	/* TODO need this for burst mode later on */
-	iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
-
-	/* set is_hcca to 0; it probably will never be implemented */
-	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
-
-	iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
-
 	scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-		offsetof(struct iwl_tx_cmd, scratch);
+				offsetof(struct iwl_tx_cmd, scratch);
+
+	len = sizeof(struct iwl_tx_cmd) +
+		sizeof(struct iwl_cmd_header) + hdr_len;
+	/* take back ownership of DMA buffer to enable update */
+	pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
+				    len, PCI_DMA_BIDIRECTIONAL);
 	tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
 	tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
 
-	if (!ieee80211_has_morefrags(hdr->frame_control)) {
-		txq->need_update = 1;
-		if (qc)
-			priv->stations[sta_id].tid[tid].seq_number = seq_number;
-	} else {
-		wait_write_ptr = 1;
-		txq->need_update = 0;
-	}
-
+	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_cmd->tx_flags));
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
-
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
 
 	/* Set up entry for this TFD in Tx byte-count array */
-	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
+	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
+						     le16_to_cpu(tx_cmd->len));
+
+	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
+				       len, PCI_DMA_BIDIRECTIONAL);
 
 	/* Tell device the write index *just past* this latest filled TFD */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1035,7 +910,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 			iwl_txq_update_write_ptr(priv, txq);
 			spin_unlock_irqrestore(&priv->lock, flags);
 		} else {
-			ieee80211_stop_queue(priv->hw, txq->swq_id);
+			iwl_stop_queue(priv, txq->swq_id);
 		}
 	}
 
@@ -1063,7 +938,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 {
 	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 	struct iwl_queue *q = &txq->q;
-	struct iwl_tfd *tfd;
 	struct iwl_cmd *out_cmd;
 	dma_addr_t phys_addr;
 	unsigned long flags;
@@ -1081,21 +955,17 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 	       !(cmd->meta.flags & CMD_SIZE_HUGE));
 
 	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_INFO("Not sending command - RF KILL");
+		IWL_DEBUG_INFO(priv, "Not sending command - RF KILL");
 		return -EIO;
 	}
 
 	if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
-		IWL_ERROR("No space for Tx\n");
+		IWL_ERR(priv, "No space for Tx\n");
 		return -ENOSPC;
 	}
 
 	spin_lock_irqsave(&priv->hcmd_lock, flags);
 
-	tfd = &txq->tfds[q->write_ptr];
-	memset(tfd, 0, sizeof(*tfd));
-
-
 	idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
 	out_cmd = txq->cmd[idx];
 
@@ -1111,22 +981,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 			INDEX_TO_SEQ(q->write_ptr));
 	if (out_cmd->meta.flags & CMD_SIZE_HUGE)
 		out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
-	len = (idx == TFD_CMD_SLOTS) ?
-			IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
-
-	phys_addr = pci_map_single(priv->pci_dev, out_cmd,
-				   len, PCI_DMA_BIDIRECTIONAL);
-	pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
-	pci_unmap_len_set(&out_cmd->meta, len, len);
-	phys_addr += offsetof(struct iwl_cmd, hdr);
+	len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta);
+	len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
 
-	iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	switch (out_cmd->hdr.cmd) {
 	case REPLY_TX_LINK_QUALITY_CMD:
 	case SENSITIVITY_CMD:
-		IWL_DEBUG_HC_DUMP("Sending command %s (#%x), seq: 0x%04X, "
+		IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, "
 				"%d bytes at %d[%d]:%d\n",
 				get_cmd_string(out_cmd->hdr.cmd),
 				out_cmd->hdr.cmd,
@@ -1134,7 +997,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 				q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
 				break;
 	default:
-		IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
+		IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
 				"%d bytes at %d[%d]:%d\n",
 				get_cmd_string(out_cmd->hdr.cmd),
 				out_cmd->hdr.cmd,
@@ -1144,8 +1007,18 @@ int iwl_enqueue_hcmd(struct iwl_priv *pr
 #endif
 	txq->need_update = 1;
 
-	/* Set up entry in queue's byte count circular buffer */
-	priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+	if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
+		/* Set up entry in queue's byte count circular buffer */
+		priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+
+	phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
+				   fix_size, PCI_DMA_BIDIRECTIONAL);
+	pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
+	pci_unmap_len_set(&out_cmd->meta, len, fix_size);
+
+	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+						   phys_addr, fix_size, 1,
+						   U32_PAD(cmd->len));
 
 	/* Increment and update queue's write index */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1163,7 +1036,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv
 	int nfreed = 0;
 
 	if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+		IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
 			  "is out of range [0-%d] %d %d.\n", txq_id,
 			  index, q->n_bd, q->write_ptr, q->read_ptr);
 		return 0;
@@ -1180,7 +1053,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv
 		if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
 			priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
 
-		iwl_hw_txq_free_tfd(priv, txq);
+		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 		nfreed++;
 	}
 	return nfreed;
@@ -1203,7 +1076,7 @@ static void iwl_hcmd_queue_reclaim(struc
 	int nfreed = 0;
 
 	if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
-		IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+		IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
 			  "is out of range [0-%d] %d %d.\n", txq_id,
 			  idx, q->n_bd, q->write_ptr, q->read_ptr);
 		return;
@@ -1218,7 +1091,7 @@ static void iwl_hcmd_queue_reclaim(struc
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
 		if (nfreed++ > 0) {
-			IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx,
+			IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
 					q->write_ptr, q->read_ptr);
 			queue_work(priv->workqueue, &priv->restart);
 		}
@@ -1306,7 +1179,7 @@ int iwl_tx_agg_start(struct iwl_priv *pr
 	else
 		return -EINVAL;
 
-	IWL_WARNING("%s on ra = %pM tid = %d\n",
+	IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
 			__func__, ra, tid);
 
 	sta_id = iwl_find_station(priv, ra);
@@ -1314,7 +1187,7 @@ int iwl_tx_agg_start(struct iwl_priv *pr
 		return -ENXIO;
 
 	if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
-		IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
+		IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
 		return -ENXIO;
 	}
 
@@ -1334,11 +1207,11 @@ int iwl_tx_agg_start(struct iwl_priv *pr
 		return ret;
 
 	if (tid_data->tfds_in_queue == 0) {
-		printk(KERN_ERR "HW queue is empty\n");
+		IWL_ERR(priv, "HW queue is empty\n");
 		tid_data->agg.state = IWL_AGG_ON;
 		ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
 	} else {
-		IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
+		IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
 			     tid_data->tfds_in_queue);
 		tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
 	}
@@ -1354,7 +1227,7 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 	unsigned long flags;
 
 	if (!ra) {
-		IWL_ERROR("ra = NULL\n");
+		IWL_ERR(priv, "ra = NULL\n");
 		return -EINVAL;
 	}
 
@@ -1365,11 +1238,13 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 
 	sta_id = iwl_find_station(priv, ra);
 
-	if (sta_id == IWL_INVALID_STATION)
+	if (sta_id == IWL_INVALID_STATION) {
+		IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
 		return -ENXIO;
+	}
 
 	if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
-		IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+		IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
 
 	tid_data = &priv->stations[sta_id].tid[tid];
 	ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
@@ -1379,13 +1254,13 @@ int iwl_tx_agg_stop(struct iwl_priv *pri
 
 	/* The queue is not empty */
 	if (write_ptr != read_ptr) {
-		IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n");
+		IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
 		priv->stations[sta_id].tid[tid].agg.state =
 				IWL_EMPTYING_HW_QUEUE_DELBA;
 		return 0;
 	}
 
-	IWL_DEBUG_HT("HW queue is empty\n");
+	IWL_DEBUG_HT(priv, "HW queue is empty\n");
 	priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -1416,7 +1291,7 @@ int iwl_txq_check_empty(struct iwl_priv
 		    (q->read_ptr == q->write_ptr)) {
 			u16 ssn = SEQ_TO_SN(tid_data->seq_number);
 			int tx_fifo = default_tid_to_tx_fifo[tid];
-			IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
+			IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
 			priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
 							     ssn, tx_fifo);
 			tid_data->agg.state = IWL_AGG_OFF;
@@ -1426,7 +1301,7 @@ int iwl_txq_check_empty(struct iwl_priv
 	case IWL_EMPTYING_HW_QUEUE_ADDBA:
 		/* We are reclaiming the last packet of the queue */
 		if (tid_data->tfds_in_queue == 0) {
-			IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n");
+			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);
 		}
@@ -1455,13 +1330,13 @@ static int iwl_tx_status_reply_compresse
 	struct ieee80211_tx_info *info;
 
 	if (unlikely(!agg->wait_for_ba))  {
-		IWL_ERROR("Received BA when not expected\n");
+		IWL_ERR(priv, "Received BA when not expected\n");
 		return -EINVAL;
 	}
 
 	/* Mark that the expected block-ack response arrived */
 	agg->wait_for_ba = 0;
-	IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
+	IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
 
 	/* Calculate shift to align block-ack bits with our Tx window bits */
 	sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
@@ -1472,7 +1347,7 @@ static int iwl_tx_status_reply_compresse
 	bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
 
 	if (agg->frame_count > (64 - sh)) {
-		IWL_DEBUG_TX_REPLY("more frames than bitmap size");
+		IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
 		return -1;
 	}
 
@@ -1485,7 +1360,7 @@ static int iwl_tx_status_reply_compresse
 	for (i = 0; i < agg->frame_count ; i++) {
 		ack = bitmap & (1ULL << i);
 		successes += !!ack;
-		IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
+		IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
 			ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
 			agg->start_idx + i);
 	}
@@ -1498,7 +1373,7 @@ static int iwl_tx_status_reply_compresse
 	info->status.ampdu_ack_len = agg->frame_count;
 	iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
 
-	IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
+	IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
 
 	return 0;
 }
@@ -1528,7 +1403,8 @@ void iwl_rx_reply_compressed_ba(struct i
 	u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 
 	if (scd_flow >= priv->hw_params.max_txq_num) {
-		IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
+		IWL_ERR(priv,
+			"BUG_ON scd_flow is bigger than number of queues\n");
 		return;
 	}
 
@@ -1542,19 +1418,19 @@ void iwl_rx_reply_compressed_ba(struct i
 
 	/* TODO: Need to get this copy more safely - now good for debug */
 
-	IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
+	IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
 			   "sta_id = %d\n",
 			   agg->wait_for_ba,
 			   (u8 *) &ba_resp->sta_addr_lo32,
 			   ba_resp->sta_id);
-	IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
+	IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
 			   "%d, scd_ssn = %d\n",
 			   ba_resp->tid,
 			   ba_resp->seq_ctl,
 			   (unsigned long long)le64_to_cpu(ba_resp->bitmap),
 			   ba_resp->scd_flow,
 			   ba_resp->scd_ssn);
-	IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
+	IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx \n",
 			   agg->start_idx,
 			   (unsigned long long)agg->bitmap);
 
@@ -1572,7 +1448,7 @@ void iwl_rx_reply_compressed_ba(struct i
 		if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 		    priv->mac80211_registered &&
 		    (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
-			ieee80211_wake_queue(priv->hw, txq->swq_id);
+			iwl_wake_queue(priv, txq->swq_id);
 
 		iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,26 +1,29 @@
 config IWLWIFI
-	tristate
-
-config IWLCORE
-	tristate "Intel Wireless Wifi Core"
+	tristate "Intel Wireless Wifi"
 	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
 	select LIB80211
-	select IWLWIFI
+	select FW_LOADER
 	select MAC80211_LEDS if IWLWIFI_LEDS
 	select LEDS_CLASS if IWLWIFI_LEDS
 	select RFKILL if IWLWIFI_RFKILL
 
 config IWLWIFI_LEDS
-	bool
-	default n
+	bool "Enable LED support in iwlagn and iwl3945 drivers"
+	depends on IWLWIFI
 
 config IWLWIFI_RFKILL
-	boolean "Iwlwifi RF kill support"
-	depends on IWLCORE
+	bool "Enable RF kill support in iwlagn and iwl3945 drivers"
+	depends on IWLWIFI
+
+config IWLWIFI_SPECTRUM_MEASUREMENT
+	bool "Enable Spectrum Measurement in iwlagn driver"
+	depends on IWLWIFI
+	---help---
+	  This option will enable spectrum measurement for the iwlagn driver.
 
 config IWLWIFI_DEBUG
-	bool "Enable full debugging output in iwlagn driver"
-	depends on IWLCORE
+	bool "Enable full debugging output in iwlagn and iwl3945 drivers"
+	depends on IWLWIFI
 	---help---
 	  This option will enable debug tracing output for the iwlwifi drivers
 
@@ -44,16 +47,14 @@ config IWLWIFI_DEBUG
 	  any problems you may encounter.
 
 config IWLWIFI_DEBUGFS
-        bool "Iwlwifi debugfs support"
-        depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
+        bool "iwlagn debugfs support"
+        depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS
         ---help---
 	  Enable creation of debugfs files for the iwlwifi drivers.
 
 config IWLAGN
-	tristate "Intel Wireless WiFi Next Gen AGN"
-	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-	select FW_LOADER
-	select IWLCORE
+	tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
+	depends on IWLWIFI
 	---help---
 	  Select to build the driver supporting the:
 
@@ -76,19 +77,6 @@ config IWLAGN
 	  say M here and read <file:Documentation/kbuild/modules.txt>.  The
 	  module will be called iwlagn.ko.
 
-config IWLAGN_SPECTRUM_MEASUREMENT
-	bool "Enable Spectrum Measurement in iwlagn driver"
-	depends on IWLAGN
-	---help---
-	  This option will enable spectrum measurement for the iwlagn driver.
-
-config IWLAGN_LEDS
-	bool "Enable LEDS features in iwlagn driver"
-	depends on IWLAGN
-	select IWLWIFI_LEDS
-	---help---
-	  This option enables LEDS for the iwlagn drivers
-
 
 config IWL4965
 	bool "Intel Wireless WiFi 4965AGN"
@@ -97,20 +85,14 @@ config IWL4965
 	  This option enables support for Intel Wireless WiFi Link 4965AGN
 
 config IWL5000
-	bool "Intel Wireless WiFi 5000AGN"
+	bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series"
 	depends on IWLAGN
 	---help---
 	  This option enables support for Intel Wireless WiFi Link 5000AGN Family
 
 config IWL3945
-	tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
-	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-	select FW_LOADER
-	select LIB80211
-	select IWLWIFI
-	select MAC80211_LEDS if IWL3945_LEDS
-	select LEDS_CLASS if IWL3945_LEDS
-	select RFKILL if IWL3945_RFKILL
+	tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
+	depends on IWLWIFI
 	---help---
 	  Select to build the driver supporting the:
 
@@ -133,45 +115,8 @@ config IWL3945
 	  say M here and read <file:Documentation/kbuild/modules.txt>.  The
 	  module will be called iwl3945.ko.
 
-config IWL3945_RFKILL
-	bool "Enable RF kill support in iwl3945 drivers"
-	depends on IWL3945
-
 config IWL3945_SPECTRUM_MEASUREMENT
-	bool "Enable Spectrum Measurement in iwl3945 drivers"
+	bool "Enable Spectrum Measurement in iwl3945 driver"
 	depends on IWL3945
 	---help---
 	  This option will enable spectrum measurement for the iwl3945 driver.
-
-config IWL3945_LEDS
-	bool "Enable LEDS features in iwl3945 driver"
-	depends on IWL3945
-	---help---
-	  This option enables LEDS for the iwl3945 driver.
-
-config IWL3945_DEBUG
-	bool "Enable full debugging output in iwl3945 driver"
-	depends on IWL3945
-	---help---
-	  This option will enable debug tracing output for the iwl3945
-	  driver.
-
-	  This will result in the kernel module being ~100k larger.  You can
-	  control which debug output is sent to the kernel log by setting the
-	  value in
-
-	          /sys/bus/pci/drivers/${DRIVER}/debug_level
-
-	  This entry will only exist if this option is enabled.
-
-	  To set a value, simply echo an 8-byte hex value to the same file:
-
-		  % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
-
-	  You can find the list of debug mask values in:
-		  drivers/net/wireless/iwlwifi/iwl-3945-debug.h
-
-	  If this is your first time using this driver, you should say Y here
-	  as the debug information can assist others in helping you resolve
-	  any problems you may encounter.
-
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/iwlwifi/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,20 +1,21 @@
-obj-$(CONFIG_IWLCORE)	+= iwlcore.o
+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-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
-iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
+iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
 
 obj-$(CONFIG_IWLAGN)	+= iwlagn.o
-iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o
+iwlagn-objs		:= iwl-agn.o iwl-agn-rs.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
 
 obj-$(CONFIG_IWL3945)	+= iwl3945.o
-iwl3945-objs		:= iwl3945-base.o iwl-3945.o iwl-3945-rs.o
-iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
+iwl3945-objs		:= iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/Kconfig	2013-05-03 18:05:00.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/Kconfig	2013-05-03 16:49:00.000000000 -0400
@@ -151,6 +151,12 @@ config LIBERTAS_SDIO
 	---help---
 	  A driver for Marvell Libertas 8385 and 8686 SDIO devices.
 
+config LIBERTAS_SPI
+	tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
+	depends on LIBERTAS && SPI && GENERIC_GPIO
+	---help---
+	  A driver for Marvell Libertas 8686 SPI devices.
+
 config LIBERTAS_DEBUG
 	bool "Enable full debugging output in the Libertas module."
 	depends on LIBERTAS
@@ -188,127 +194,6 @@ config AIRO
 
 	  The driver can be compiled as a module and will be named "airo".
 
-config HERMES
-	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
-	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
-	select WIRELESS_EXT
-	select FW_LOADER
-	select CRYPTO
-	select CRYPTO_MICHAEL_MIC
-	---help---
-	  A driver for 802.11b wireless cards based on the "Hermes" or
-	  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
-	  majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
-	  - except for the Cisco/Aironet cards.  Cards supported include the
-	  Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
-	  Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
-	  IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
-	  MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
-	  IPW2011, and Symbol Spectrum24 High Rate amongst others.
-
-	  This option includes the guts of the driver, but in order to
-	  actually use a card you will also need to enable support for PCMCIA
-	  Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
-
-	  You will also very likely also need the Wireless Tools in order to
-	  configure your card and that /etc/pcmcia/wireless.opts works :
-	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
-
-config HERMES_CACHE_FW_ON_INIT
-	bool "Cache Hermes firmware on driver initialisation"
-	depends on HERMES
-	default y
-	---help---
-	  Say Y to cache any firmware required by the Hermes drivers
-	  on startup.  The firmware will remain cached until the
-	  driver is unloaded.  The cache uses 64K of RAM.
-
-	  Otherwise load the firmware from userspace as required.  In
-	  this case the driver should be unloaded and restarted
-	  whenever the firmware is changed.
-
-	  If you are not sure, say Y.
-
-config APPLE_AIRPORT
-	tristate "Apple Airport support (built-in)"
-	depends on PPC_PMAC && HERMES
-	help
-	  Say Y here to support the Airport 802.11b wireless Ethernet hardware
-	  built into the Macintosh iBook and other recent PowerPC-based
-	  Macintosh machines. This is essentially a Lucent Orinoco card with 
-	  a non-standard interface.
-
-	  This driver does not support the Airport Extreme (802.11b/g). Use
-	  the BCM43xx driver for Airport Extreme cards.
-
-config PLX_HERMES
-	tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
-	depends on PCI && HERMES
-	help
-	  Enable support for PCMCIA cards supported by the "Hermes" (aka
-	  orinoco) driver when used in PLX9052 based PCI adaptors.  These
-	  adaptors are not a full PCMCIA controller but act as a more limited
-	  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
-	  802.11b PCMCIA cards can be used in desktop machines.  The Netgear
-	  MA301 is such an adaptor.
-
-config TMD_HERMES
-	tristate "Hermes in TMD7160 based PCI adaptor support"
-	depends on PCI && HERMES
-	help
-	  Enable support for PCMCIA cards supported by the "Hermes" (aka
-	  orinoco) driver when used in TMD7160 based PCI adaptors.  These
-	  adaptors are not a full PCMCIA controller but act as a more limited
-	  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
-	  802.11b PCMCIA cards can be used in desktop machines.
-
-config NORTEL_HERMES
-	tristate "Nortel emobility PCI adaptor support"
-	depends on PCI && HERMES
-	help
-	  Enable support for PCMCIA cards supported by the "Hermes" (aka
-	  orinoco) driver when used in Nortel emobility PCI adaptors.  These
-	  adaptors are not full PCMCIA controllers, but act as a more limited
-	  PCI <-> PCMCIA bridge.
-
-config PCI_HERMES
-	tristate "Prism 2.5 PCI 802.11b adaptor support"
-	depends on PCI && HERMES
-	help
-	  Enable support for PCI and mini-PCI 802.11b wireless NICs based on
-	  the Prism 2.5 chipset.  These are true PCI cards, not the 802.11b
-	  PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
-	  common.  Some of the built-in wireless adaptors in laptops are of
-	  this variety.
-
-config PCMCIA_HERMES
-	tristate "Hermes PCMCIA card support"
-	depends on PCMCIA && HERMES
-	---help---
-	  A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
-	  as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
-	  EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
-	  others).  It should also be usable on various Prism II based cards
-	  such as the Linksys, D-Link and Farallon Skyline.  It should also
-	  work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
-
-	  You will very likely need the Wireless Tools in order to
-	  configure your card and that /etc/pcmcia/wireless.opts works:
-	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-
-config PCMCIA_SPECTRUM
-	tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
-	depends on PCMCIA && HERMES
-	---help---
-
-	  This is a driver for 802.11b cards using RAM-loadable Symbol
-	  firmware, such as Symbol Wireless Networker LA4100, CompactFlash
-	  cards by Socket Communications and Intel PRO/Wireless 2011B.
-
-	  This driver requires firmware download on startup.  Utilities
-	  for downloading Symbol firmware are available at
-	  <http://sourceforge.net/projects/orinoco/>
-
 config ATMEL
       tristate "Atmel at76c50x chipset  802.11b support"
       depends on (PCI || PCMCIA) && WLAN_80211
@@ -343,6 +228,14 @@ config PCMCIA_ATMEL
 	  Enable support for PCMCIA cards containing the
 	  Atmel at76c502 and at76c504 chips.
 
+config AT76C50X_USB
+        tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+        depends on MAC80211 && WLAN_80211 && USB
+        select FW_LOADER
+        ---help---
+          Enable support for USB Wireless devices using Atmel at76c503,
+          at76c505 or at76c505a chips.
+
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
 	depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
@@ -530,6 +423,7 @@ config RTL8187
 	  ASUS P5B Deluxe
 	  Toshiba Satellite Pro series of laptops
 	  Asus Wireless Link
+	  Linksys WUSB54GC-EU
 
 	  Thanks to Realtek for their support!
 
@@ -573,9 +467,19 @@ config MAC80211_HWSIM
 	  To compile this driver as a module, choose M here: the module will be
 	  called mac80211_hwsim.  If unsure, say N.
 
+config MWL8K
+	tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
+	depends on MAC80211 && PCI && WLAN_80211 && 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/ath5k/Kconfig"
 source "drivers/net/wireless/ath9k/Kconfig"
+source "drivers/net/wireless/ar9170/Kconfig"
 source "drivers/net/wireless/ipw2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
@@ -583,5 +487,6 @@ 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/orinoco/Kconfig"
 
 endmenu
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/cmd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/cmd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/cmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/cmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -1649,7 +1649,7 @@ static struct cmd_ctrl_node *lbs_get_cmd
 
 /**
  *  @brief This function executes next command in command
- *  pending queue. It will put fimware back to PS mode
+ *  pending queue. It will put firmware back to PS mode
  *  if applicable.
  *
  *  @param priv     A pointer to struct lbs_private structure
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/debugfs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/debugfs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/debugfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/debugfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -629,7 +629,7 @@ static ssize_t lbs_rdrf_write(struct fil
 		res = -EFAULT;
 		goto out_unlock;
 	}
-	priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
+	priv->rf_offset = simple_strtoul(buf, NULL, 16);
 	res = count;
 out_unlock:
 	free_page(addr);
@@ -680,12 +680,12 @@ out_unlock:
 }
 
 struct lbs_debugfs_files {
-	char *name;
+	const char *name;
 	int perm;
 	struct file_operations fops;
 };
 
-static struct lbs_debugfs_files debugfs_files[] = {
+static const struct lbs_debugfs_files debugfs_files[] = {
 	{ "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
 	{ "getscantable", 0444, FOPS(lbs_getscantable,
 					write_file_dummy), },
@@ -693,7 +693,7 @@ static struct lbs_debugfs_files debugfs_
 				lbs_sleepparams_write), },
 };
 
-static struct lbs_debugfs_files debugfs_events_files[] = {
+static const struct lbs_debugfs_files debugfs_events_files[] = {
 	{"low_rssi", 0644, FOPS(lbs_lowrssi_read,
 				lbs_lowrssi_write), },
 	{"low_snr", 0644, FOPS(lbs_lowsnr_read,
@@ -708,7 +708,7 @@ static struct lbs_debugfs_files debugfs_
 				lbs_highsnr_write), },
 };
 
-static struct lbs_debugfs_files debugfs_regs_files[] = {
+static const struct lbs_debugfs_files debugfs_regs_files[] = {
 	{"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
 	{"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
 	{"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
@@ -735,7 +735,7 @@ void lbs_debugfs_remove(void)
 void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
 {
 	int i;
-	struct lbs_debugfs_files *files;
+	const struct lbs_debugfs_files *files;
 	if (!lbs_dir)
 		goto exit;
 
@@ -938,7 +938,7 @@ static ssize_t lbs_debugfs_write(struct
 	return (ssize_t)cnt;
 }
 
-static struct file_operations lbs_debug_fops = {
+static const struct file_operations lbs_debug_fops = {
 	.owner = THIS_MODULE,
 	.open = open_file_generic,
 	.write = lbs_debugfs_write,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/defs.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/defs.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/defs.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/defs.h	2009-06-09 23:05:27.000000000 -0400
@@ -41,6 +41,7 @@
 #define LBS_DEB_HEX	0x00200000
 #define LBS_DEB_SDIO	0x00400000
 #define LBS_DEB_SYSFS	0x00800000
+#define LBS_DEB_SPI	0x01000000
 
 extern unsigned int lbs_debug;
 
@@ -84,6 +85,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \
 #define lbs_deb_thread(fmt, args...)    LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
 #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_pr_info(format, args...) \
 	printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -263,6 +265,7 @@ static inline void lbs_deb_hex(unsigned
 
 #define	CMD_F_HOSTCMD		(1 << 0)
 #define FW_CAPINFO_WPA  	(1 << 0)
+#define FW_CAPINFO_PS  		(1 << 1)
 #define FW_CAPINFO_FIRMWARE_UPGRADE	(1 << 13)
 #define FW_CAPINFO_BOOT2_UPGRADE	(1<<14)
 #define FW_CAPINFO_PERSISTENT_CONFIG	(1<<15)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/dev.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/dev.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/dev.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/dev.h	2009-06-09 23:05:27.000000000 -0400
@@ -109,7 +109,6 @@ struct lbs_private {
 	void *card;
 	struct net_device *dev;
 
-	struct net_device_stats stats;
 	struct net_device *mesh_dev; /* Virtual device */
 	struct net_device *rtap_net_dev;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/hostcmd.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/hostcmd.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/hostcmd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/hostcmd.h	2009-06-09 23:05:27.000000000 -0400
@@ -221,6 +221,14 @@ struct cmd_ds_mac_multicast_adr {
 	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 {
 	u8 macaddr[ETH_ALEN];
 	u8 authtype;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/host.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/host.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/host.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/host.h	2009-06-09 23:05:27.000000000 -0400
@@ -66,6 +66,7 @@
 #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
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 18:04:44.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_cs.c	2013-05-03 16:48:37.000000000 -0400
@@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(
 	for (i = 0; i < 100000; i++) {
 		u8 val = if_cs_read8(card, addr);
 		if (val == reg)
-			return i;
+			return 0;
 		udelay(5);
 	}
 	return -ETIME;
@@ -421,7 +421,7 @@ static struct sk_buff *if_cs_receive_dat
 	len = if_cs_read16(priv->card, IF_CS_READ_LEN);
 	if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
 		lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
-		priv->stats.rx_dropped++;
+		priv->dev->stats.rx_dropped++;
 		goto dat_err;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_sdio.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_sdio.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 18:04:46.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_sdio.c	2013-05-03 16:48:39.000000000 -0400
@@ -93,6 +93,8 @@ struct if_sdio_card {
 
 	spinlock_t		lock;
 	struct if_sdio_packet	*packets;
+
+	struct workqueue_struct	*workqueue;
 	struct work_struct	packet_worker;
 };
 
@@ -207,6 +209,9 @@ static int if_sdio_handle_event(struct i
 		event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
 		if (ret)
 			goto out;
+
+		/* right shift 3 bits to get the event id */
+		event >>= 3;
 	} else {
 		if (size < 4) {
 			lbs_deb_sdio("event packet too small (%d bytes)\n",
@@ -741,7 +746,7 @@ static int if_sdio_host_to_card(struct l
 
 	spin_unlock_irqrestore(&card->lock, flags);
 
-	schedule_work(&card->packet_worker);
+	queue_work(card->workqueue, &card->packet_worker);
 
 	ret = 0;
 
@@ -831,6 +836,7 @@ static int if_sdio_probe(struct sdio_fun
 	card->func = func;
 	card->model = model;
 	spin_lock_init(&card->lock);
+	card->workqueue = create_workqueue("libertas_sdio");
 	INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
 
 	for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -919,15 +925,17 @@ static int if_sdio_probe(struct sdio_fun
 	if (ret)
 		goto err_activate_card;
 
+	if (priv->fwcapinfo & FW_CAPINFO_PS)
+		priv->ps_supported = 1;
+
 out:
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
 	return ret;
 
 err_activate_card:
-	flush_scheduled_work();
-	free_netdev(priv->dev);
-	kfree(priv);
+	flush_workqueue(card->workqueue);
+	lbs_remove_card(priv);
 reclaim:
 	sdio_claim_host(func);
 release_int:
@@ -937,6 +945,7 @@ disable:
 release:
 	sdio_release_host(func);
 free:
+	destroy_workqueue(card->workqueue);
 	while (card->packets) {
 		packet = card->packets;
 		card->packets = card->packets->next;
@@ -963,7 +972,8 @@ static void if_sdio_remove(struct sdio_f
 	lbs_stop_card(card->priv);
 	lbs_remove_card(card->priv);
 
-	flush_scheduled_work();
+	flush_workqueue(card->workqueue);
+	destroy_workqueue(card->workqueue);
 
 	sdio_claim_host(func);
 	sdio_release_irq(func);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_spi.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_spi.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_spi.c	2013-05-03 16:48:41.000000000 -0400
@@ -0,0 +1,1218 @@
+/*
+ *	linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ *	Driver for Marvell SPI WLAN cards.
+ *
+ *	Copyright 2008 Analog Devices Inc.
+ *
+ *	Authors:
+ *	Andrey Yurovsky <andrey@cozybit.com>
+ *	Colin McCabe <colin@cozybit.com>
+ *
+ *	Inspired by if_sdio.c, Copyright 2007-2008 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/jiffies.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/spi.h>
+
+#include "host.h"
+#include "decl.h"
+#include "defs.h"
+#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;
+	struct libertas_spi_platform_data *pdata;
+
+	char				helper_fw_name[FIRMWARE_NAME_MAX];
+	char				main_fw_name[FIRMWARE_NAME_MAX];
+
+	/* The card ID and card revision, as reported by the hardware. */
+	u16				card_id;
+	u8				card_rev;
+
+	/* Pin number for our GPIO chip-select. */
+	/* TODO: Once the generic SPI layer has some additional features, we
+	 * should take this out and use the normal chip select here.
+	 * We need support for chip select delays, and not dropping chipselect
+	 * after each word. */
+	int				gpio_cs;
+
+	/* The last time that we initiated an SPU operation */
+	unsigned long			prev_xfer_time;
+
+	int				use_dummy_writes;
+	unsigned long			spu_port_delay;
+	unsigned long			spu_reg_delay;
+
+	/* Handles all SPI communication (except for FW load) */
+	struct task_struct		*spi_thread;
+	int				run_thread;
+
+	/* Used to wake up the spi_thread */
+	struct semaphore		spi_ready;
+	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);
+}
+
+static struct chip_ident chip_id_to_device_name[] = {
+	{ .chip_id = 0x04, .name = 8385 },
+	{ .chip_id = 0x0b, .name = 8686 },
+};
+
+/*
+ * SPI Interface Unit Routines
+ *
+ * The SPU sits between the host and the WLAN module.
+ * All communication with the firmware is through SPU transactions.
+ *
+ * First we have to put a SPU register name on the bus. Then we can
+ * either read from or write to that register.
+ *
+ * For 16-bit transactions, byte order on the bus is big-endian.
+ * We don't have to worry about that here, though.
+ * The translation takes place in the SPI routines.
+ */
+
+static void spu_transaction_init(struct if_spi_card *card)
+{
+	if (!time_after(jiffies, card->prev_xfer_time + 1)) {
+		/* Unfortunately, the SPU requires a delay between successive
+		 * transactions. If our last transaction was more than a jiffy
+		 * ago, we have obviously already delayed enough.
+		 * If not, we have to busy-wait to be on the safe side. */
+		ndelay(400);
+	}
+	gpio_set_value(card->gpio_cs, 0); /* assert CS */
+}
+
+static void spu_transaction_finish(struct if_spi_card *card)
+{
+	gpio_set_value(card->gpio_cs, 1); /* drop CS */
+	card->prev_xfer_time = jiffies;
+}
+
+/* Write out a byte buffer to an SPI register,
+ * using a series of 16-bit transfers. */
+static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
+{
+	int err = 0;
+	u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;
+
+	/* You must give an even number of bytes to the SPU, even if it
+	 * doesn't care about the last one.  */
+	BUG_ON(len & 0x1);
+
+	spu_transaction_init(card);
+
+	/* write SPU register index */
+	err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+	if (err)
+		goto out;
+
+	err = spi_write(card->spi, buf, len);
+
+out:
+	spu_transaction_finish(card);
+	return err;
+}
+
+static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
+{
+	return spu_write(card, reg, (u8 *)&val, sizeof(u16));
+}
+
+static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val)
+{
+	/* The lower 16 bits are written first. */
+	u16 out[2];
+	out[0] = val & 0xffff;
+	out[1] = (val & 0xffff0000) >> 16;
+	return spu_write(card, reg, (u8 *)&out, sizeof(u32));
+}
+
+static inline int spu_reg_is_port_reg(u16 reg)
+{
+	switch (reg) {
+	case IF_SPI_IO_RDWRPORT_REG:
+	case IF_SPI_CMD_RDWRPORT_REG:
+	case IF_SPI_DATA_RDWRPORT_REG:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
+{
+	unsigned int i, delay;
+	int err = 0;
+	u16 zero = 0;
+	u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;
+
+	/* You must take an even number of bytes from the SPU, even if you
+	 * don't care about the last one.  */
+	BUG_ON(len & 0x1);
+
+	spu_transaction_init(card);
+
+	/* write SPU register index */
+	err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+	if (err)
+		goto out;
+
+	delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
+						card->spu_reg_delay;
+	if (card->use_dummy_writes) {
+		/* Clock in dummy cycles while the SPU fills the FIFO */
+		for (i = 0; i < delay / 16; ++i) {
+			err = spi_write(card->spi, (u8 *)&zero, sizeof(u16));
+			if (err)
+				return err;
+		}
+	} else {
+		/* Busy-wait while the SPU fills the FIFO */
+		ndelay(100 + (delay * 10));
+	}
+
+	/* read in data */
+	err = spi_read(card->spi, buf, len);
+
+out:
+	spu_transaction_finish(card);
+	return err;
+}
+
+/* Read 16 bits from an SPI register */
+static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
+{
+	return spu_read(card, reg, (u8 *)val, sizeof(u16));
+}
+
+/* Read 32 bits from an SPI register.
+ * The low 16 bits are read first. */
+static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
+{
+	u16 buf[2];
+	int err;
+	err = spu_read(card, reg, (u8 *)buf, sizeof(u32));
+	if (!err)
+		*val = buf[0] | (buf[1] << 16);
+	return err;
+}
+
+/* Keep reading 16 bits from an SPI register until you get the correct result.
+ *
+ * If mask = 0, the correct result is any non-zero number.
+ * If mask != 0, the correct result is any number where
+ * number & target_mask == target
+ *
+ * Returns -ETIMEDOUT if a second passes without the correct result. */
+static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
+			u16 target_mask, u16 target)
+{
+	int err;
+	unsigned long timeout = jiffies + 5*HZ;
+	while (1) {
+		u16 val;
+		err = spu_read_u16(card, reg, &val);
+		if (err)
+			return err;
+		if (target_mask) {
+			if ((val & target_mask) == target)
+				return 0;
+		} else {
+			if (val)
+				return 0;
+		}
+		udelay(100);
+		if (time_after(jiffies, timeout)) {
+			lbs_pr_err("%s: timeout with val=%02x, "
+			       "target_mask=%02x, target=%02x\n",
+			       __func__, val, target_mask, target);
+			return -ETIMEDOUT;
+		}
+	}
+}
+
+/* Read 16 bits from an SPI register until you receive a specific value.
+ * Returns -ETIMEDOUT if a 4 tries pass without success. */
+static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
+{
+	int err, try;
+	for (try = 0; try < 4; ++try) {
+		u32 val = 0;
+		err = spu_read_u32(card, reg, &val);
+		if (err)
+			return err;
+		if (val == target)
+			return 0;
+		mdelay(100);
+	}
+	return -ETIMEDOUT;
+}
+
+static int spu_set_interrupt_mode(struct if_spi_card *card,
+			   int suppress_host_int,
+			   int auto_int)
+{
+	int err = 0;
+
+	/* We can suppress a host interrupt by clearing the appropriate
+	 * bit in the "host interrupt status mask" register */
+	if (suppress_host_int) {
+		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+		if (err)
+			return err;
+	} else {
+		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG,
+			      IF_SPI_HISM_TX_DOWNLOAD_RDY |
+			      IF_SPI_HISM_RX_UPLOAD_RDY |
+			      IF_SPI_HISM_CMD_DOWNLOAD_RDY |
+			      IF_SPI_HISM_CARDEVENT |
+			      IF_SPI_HISM_CMD_UPLOAD_RDY);
+		if (err)
+			return err;
+	}
+
+	/* If auto-interrupts are on, the completion of certain transactions
+	 * will trigger an interrupt automatically. If auto-interrupts
+	 * are off, we need to set the "Card Interrupt Cause" register to
+	 * trigger a card interrupt. */
+	if (auto_int) {
+		err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
+				IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
+				IF_SPI_HICT_RX_UPLOAD_OVER_AUTO |
+				IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO |
+				IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO);
+		if (err)
+			return err;
+	} else {
+		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+		if (err)
+			return err;
+	}
+	return err;
+}
+
+static int spu_get_chip_revision(struct if_spi_card *card,
+				  u16 *card_id, u8 *card_rev)
+{
+	int err = 0;
+	u32 dev_ctrl;
+	err = spu_read_u32(card, IF_SPI_DEVICEID_CTRL_REG, &dev_ctrl);
+	if (err)
+		return err;
+	*card_id = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dev_ctrl);
+	*card_rev = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dev_ctrl);
+	return err;
+}
+
+static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
+{
+	int err = 0;
+	u16 rval;
+	/* set bus mode */
+	err = spu_write_u16(card, IF_SPI_SPU_BUS_MODE_REG, mode);
+	if (err)
+		return err;
+	/* Check that we were able to read back what we just wrote. */
+	err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
+	if (err)
+		return err;
+	if (rval != mode) {
+		lbs_pr_err("Can't read bus mode register.\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int spu_init(struct if_spi_card *card, int use_dummy_writes)
+{
+	int err = 0;
+	u32 delay;
+
+	/* We have to start up in timed delay mode so that we can safely
+	 * read the Delay Read Register. */
+	card->use_dummy_writes = 0;
+	err = spu_set_bus_mode(card,
+				IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+				IF_SPI_BUS_MODE_DELAY_METHOD_TIMED |
+				IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+	if (err)
+		return err;
+	card->spu_port_delay = 1000;
+	card->spu_reg_delay = 1000;
+	err = spu_read_u32(card, IF_SPI_DELAY_READ_REG, &delay);
+	if (err)
+		return err;
+	card->spu_port_delay = delay & 0x0000ffff;
+	card->spu_reg_delay = (delay & 0xffff0000) >> 16;
+
+	/* If dummy clock delay mode has been requested, switch to it now */
+	if (use_dummy_writes) {
+		card->use_dummy_writes = 1;
+		err = spu_set_bus_mode(card,
+				IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+				IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK |
+				IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+		if (err)
+			return err;
+	}
+
+	lbs_deb_spi("Initialized SPU unit. "
+		    "spu_port_delay=0x%04lx, spu_reg_delay=0x%04lx\n",
+		    card->spu_port_delay, card->spu_reg_delay);
+	return err;
+}
+
+/*
+ * Firmware Loading
+ */
+
+static int if_spi_prog_helper_firmware(struct if_spi_card *card)
+{
+	int err = 0;
+	const struct firmware *firmware = NULL;
+	int bytes_remaining;
+	const u8 *fw;
+	u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
+	struct spi_device *spi = card->spi;
+
+	lbs_deb_enter(LBS_DEB_SPI);
+
+	err = spu_set_interrupt_mode(card, 1, 0);
+	if (err)
+		goto out;
+	/* Get helper firmware image */
+	err = reject_firmware(&firmware, card->helper_fw_name, &spi->dev);
+	if (err) {
+		lbs_pr_err("reject_firmware failed with err = %d\n", err);
+		goto out;
+	}
+	bytes_remaining = firmware->size;
+	fw = firmware->data;
+
+	/* Load helper firmware image */
+	while (bytes_remaining > 0) {
+		/* Scratch pad 1 should contain the number of bytes we
+		 * want to download to the firmware */
+		err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
+					HELPER_FW_LOAD_CHUNK_SZ);
+		if (err)
+			goto release_firmware;
+
+		err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+					IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+					IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+		if (err)
+			goto release_firmware;
+
+		/* Feed the data into the command read/write port reg
+		 * in chunks of 64 bytes */
+		memset(temp, 0, sizeof(temp));
+		memcpy(temp, fw,
+		       min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
+		mdelay(10);
+		err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+					temp, HELPER_FW_LOAD_CHUNK_SZ);
+		if (err)
+			goto release_firmware;
+
+		/* Interrupt the boot code */
+		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+		if (err)
+			goto release_firmware;
+		err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+				       IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+		if (err)
+			goto release_firmware;
+		bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
+		fw += HELPER_FW_LOAD_CHUNK_SZ;
+	}
+
+	/* Once the helper / single stage firmware download is complete,
+	 * write 0 to scratch pad 1 and interrupt the
+	 * bootloader. This completes the helper download. */
+	err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
+	if (err)
+		goto release_firmware;
+	err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+	if (err)
+		goto release_firmware;
+	err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+				IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+		goto release_firmware;
+
+	lbs_deb_spi("waiting for helper to boot...\n");
+
+release_firmware:
+	release_firmware(firmware);
+out:
+	if (err)
+		lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
+	lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+	return err;
+}
+
+/* Returns the length of the next packet the firmware expects us to send
+ * Sets crc_err if the previous transfer had a CRC error. */
+static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
+						int *crc_err)
+{
+	u16 len;
+	int err = 0;
+
+	/* wait until the host interrupt status register indicates
+	 * that we are ready to download */
+	err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+				IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+				IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+	if (err) {
+		lbs_pr_err("timed out waiting for host_int_status\n");
+		return err;
+	}
+
+	/* Ask the device how many bytes of firmware it wants. */
+	err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+	if (err)
+		return err;
+
+	if (len > IF_SPI_CMD_BUF_SIZE) {
+		lbs_pr_err("firmware load device requested a larger "
+			   "tranfer than we are prepared to "
+			   "handle. (len = %d)\n", len);
+		return -EIO;
+	}
+	if (len & 0x1) {
+		lbs_deb_spi("%s: crc error\n", __func__);
+		len &= ~0x1;
+		*crc_err = 1;
+	} else
+		*crc_err = 0;
+
+	return len;
+}
+
+static int if_spi_prog_main_firmware(struct if_spi_card *card)
+{
+	int len, prev_len;
+	int bytes, crc_err = 0, err = 0;
+	const struct firmware *firmware = NULL;
+	const u8 *fw;
+	struct spi_device *spi = card->spi;
+	u16 num_crc_errs;
+
+	lbs_deb_enter(LBS_DEB_SPI);
+
+	err = spu_set_interrupt_mode(card, 1, 0);
+	if (err)
+		goto out;
+
+	/* Get firmware image */
+	err = reject_firmware(&firmware, card->main_fw_name, &spi->dev);
+	if (err) {
+		lbs_pr_err("%s: can't get firmware '%s' from kernel. "
+			"err = %d\n", __func__, card->main_fw_name, err);
+		goto out;
+	}
+
+	err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
+	if (err) {
+		lbs_pr_err("%s: timed out waiting for initial "
+			   "scratch reg = 0\n", __func__);
+		goto release_firmware;
+	}
+
+	num_crc_errs = 0;
+	prev_len = 0;
+	bytes = firmware->size;
+	fw = firmware->data;
+	while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
+		if (len < 0) {
+			err = len;
+			goto release_firmware;
+		}
+		if (bytes < 0) {
+			/* If there are no more bytes left, we would normally
+			 * expect to have terminated with len = 0 */
+			lbs_pr_err("Firmware load wants more bytes "
+				   "than we have to offer.\n");
+			break;
+		}
+		if (crc_err) {
+			/* Previous transfer failed. */
+			if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
+				lbs_pr_err("Too many CRC errors encountered "
+					   "in firmware load.\n");
+				err = -EIO;
+				goto release_firmware;
+			}
+		} else {
+			/* Previous transfer succeeded. Advance counters. */
+			bytes -= prev_len;
+			fw += prev_len;
+		}
+		if (bytes < len) {
+			memset(card->cmd_buffer, 0, len);
+			memcpy(card->cmd_buffer, fw, bytes);
+		} else
+			memcpy(card->cmd_buffer, fw, len);
+
+		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+		if (err)
+			goto release_firmware;
+		err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+				card->cmd_buffer, len);
+		if (err)
+			goto release_firmware;
+		err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
+					IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+		if (err)
+			goto release_firmware;
+		prev_len = len;
+	}
+	if (bytes > prev_len) {
+		lbs_pr_err("firmware load wants fewer bytes than "
+			   "we have to offer.\n");
+	}
+
+	/* Confirm firmware download */
+	err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
+					SUCCESSFUL_FW_DOWNLOAD_MAGIC);
+	if (err) {
+		lbs_pr_err("failed to confirm the firmware download\n");
+		goto release_firmware;
+	}
+
+release_firmware:
+	release_firmware(firmware);
+
+out:
+	if (err)
+		lbs_pr_err("failed to load firmware (err=%d)\n", err);
+	lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+	return err;
+}
+
+/*
+ * SPI Transfer Thread
+ *
+ * The SPI thread handles all SPI transfers, so there is no need for a lock.
+ */
+
+/* Move a command from the card to the host */
+static int if_spi_c2h_cmd(struct if_spi_card *card)
+{
+	struct lbs_private *priv = card->priv;
+	unsigned long flags;
+	int err = 0;
+	u16 len;
+	u8 i;
+
+	/* We need a buffer big enough to handle whatever people send to
+	 * hw_host_to_card */
+	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
+	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
+
+	/* It's just annoying if the buffer size isn't a multiple of 4, because
+	 * then we might have len <  IF_SPI_CMD_BUF_SIZE but
+	 * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
+	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
+
+	lbs_deb_enter(LBS_DEB_SPI);
+
+	/* How many bytes are there to read? */
+	err = spu_read_u16(card, IF_SPI_SCRATCH_2_REG, &len);
+	if (err)
+		goto out;
+	if (!len) {
+		lbs_pr_err("%s: error: card has no data for host\n",
+			   __func__);
+		err = -EINVAL;
+		goto out;
+	} else if (len > IF_SPI_CMD_BUF_SIZE) {
+		lbs_pr_err("%s: error: response packet too large: "
+			   "%d bytes, but maximum is %d\n",
+			   __func__, len, IF_SPI_CMD_BUF_SIZE);
+		err = -EINVAL;
+		goto out;
+	}
+
+	/* Read the data from the WLAN module into our command buffer */
+	err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG,
+				card->cmd_buffer, ALIGN(len, 4));
+	if (err)
+		goto out;
+
+	spin_lock_irqsave(&priv->driver_lock, flags);
+	i = (priv->resp_idx == 0) ? 1 : 0;
+	BUG_ON(priv->resp_len[i]);
+	priv->resp_len[i] = len;
+	memcpy(priv->resp_buf[i], card->cmd_buffer, len);
+	lbs_notify_command_response(priv, i);
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+	if (err)
+		lbs_pr_err("%s: err=%d\n", __func__, err);
+	lbs_deb_leave(LBS_DEB_SPI);
+	return err;
+}
+
+/* Move data from the card to the host */
+static int if_spi_c2h_data(struct if_spi_card *card)
+{
+	struct sk_buff *skb;
+	char *data;
+	u16 len;
+	int err = 0;
+
+	lbs_deb_enter(LBS_DEB_SPI);
+
+	/* How many bytes are there to read? */
+	err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+	if (err)
+		goto out;
+	if (!len) {
+		lbs_pr_err("%s: error: card has no data for host\n",
+			   __func__);
+		err = -EINVAL;
+		goto out;
+	} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
+		lbs_pr_err("%s: error: card has %d bytes of data, but "
+			   "our maximum skb size is %u\n",
+			   __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+		err = -EINVAL;
+		goto out;
+	}
+
+	/* TODO: should we allocate a smaller skb if we have less data? */
+	skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+	if (!skb) {
+		err = -ENOBUFS;
+		goto out;
+	}
+	skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
+	data = skb_put(skb, len);
+
+	/* Read the data from the WLAN module into our skb... */
+	err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
+	if (err)
+		goto free_skb;
+
+	/* pass the SKB to libertas */
+	err = lbs_process_rxed_packet(card->priv, skb);
+	if (err)
+		goto free_skb;
+
+	/* success */
+	goto out;
+
+free_skb:
+	dev_kfree_skb(skb);
+out:
+	if (err)
+		lbs_pr_err("%s: err=%d\n", __func__, err);
+	lbs_deb_leave(LBS_DEB_SPI);
+	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)
+{
+	int err = 0;
+	unsigned long flags;
+	u32 cause;
+	struct lbs_private *priv = card->priv;
+
+	err = spu_read_u32(card, IF_SPI_SCRATCH_3_REG, &cause);
+	if (err)
+		goto out;
+
+	spin_lock_irqsave(&priv->driver_lock, flags);
+	lbs_queue_event(priv, cause & 0xff);
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+	if (err)
+		lbs_pr_err("%s: error %d\n", __func__, err);
+}
+
+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
+		 * could tell us that something happened on the WLAN.
+		 * Secondly, libertas could call hw_host_to_card with more
+		 * data, which we might be able to send.
+		 */
+		do {
+			err = down_interruptible(&card->spi_ready);
+			if (!card->run_thread) {
+				up(&card->spi_thread_terminated);
+				do_exit(0);
+			}
+		} while (err == EINTR);
+
+		/* Read the host interrupt status register to see what we
+		 * can do. */
+		err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+					&hiStatus);
+		if (err) {
+			lbs_pr_err("I/O error\n");
+			goto err;
+		}
+
+		if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY)
+			err = if_spi_c2h_cmd(card);
+			if (err)
+				goto err;
+		if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY)
+			err = if_spi_c2h_data(card);
+			if (err)
+				goto err;
+		if (hiStatus & IF_SPI_HIST_CMD_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);
+
+err:
+		if (err)
+			lbs_pr_err("%s: got error %d\n", __func__, err);
+	}
+}
+
+/* Block until lbs_spi_thread thread has terminated */
+static void if_spi_terminate_spi_thread(struct if_spi_card *card)
+{
+	/* It would be nice to use kthread_stop here, but that function
+	 * can't wake threads waiting for a semaphore. */
+	card->run_thread = 0;
+	up(&card->spi_ready);
+	down(&card->spi_thread_terminated);
+}
+
+/*
+ * Host to Card
+ *
+ * Called from Libertas to transfer some data to the WLAN device
+ * We can't sleep here. */
+static int if_spi_host_to_card(struct lbs_private *priv,
+				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);
+
+	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);
+		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);
+		break;
+	default:
+		lbs_pr_err("can't transfer buffer of type %d", type);
+		err = -EINVAL;
+		break;
+	}
+
+	/* Wake up the spi thread */
+	up(&card->spi_ready);
+out:
+	lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
+	return err;
+}
+
+/*
+ * Host Interrupts
+ *
+ * Service incoming interrupts from the WLAN device. We can't sleep here, so
+ * don't try to talk on the SPI bus, just wake up the SPI thread.
+ */
+static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
+{
+	struct if_spi_card *card = dev_id;
+
+	up(&card->spi_ready);
+	return IRQ_HANDLED;
+}
+
+/*
+ * SPI callbacks
+ */
+
+static int if_spi_calculate_fw_names(u16 card_id,
+			      char *helper_fw, char *main_fw)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
+		if (card_id == chip_id_to_device_name[i].chip_id)
+			break;
+	}
+	if (i == ARRAY_SIZE(chip_id_to_device_name)) {
+		lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
+		return -EAFNOSUPPORT;
+	}
+	snprintf(helper_fw, FIRMWARE_NAME_MAX, "/*(DEBLOBBED)*/",
+		 chip_id_to_device_name[i].name);
+	snprintf(main_fw, FIRMWARE_NAME_MAX, "/*(DEBLOBBED)*/",
+		 chip_id_to_device_name[i].name);
+	return 0;
+}
+
+static int __devinit if_spi_probe(struct spi_device *spi)
+{
+	struct if_spi_card *card;
+	struct lbs_private *priv = NULL;
+	struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
+	int err = 0;
+	u32 scratch;
+
+	lbs_deb_enter(LBS_DEB_SPI);
+
+	if (!pdata) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if (pdata->setup) {
+		err = pdata->setup(spi);
+		if (err)
+			goto out;
+	}
+
+	/* Allocate card structure to represent this specific device */
+	card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL);
+	if (!card) {
+		err = -ENOMEM;
+		goto out;
+	}
+	spi_set_drvdata(spi, card);
+	card->pdata = pdata;
+	card->spi = spi;
+	card->gpio_cs = pdata->gpio_cs;
+	card->prev_xfer_time = jiffies;
+
+	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);
+
+	/* set up GPIO CS line. TODO: use  regular CS line */
+	err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select");
+	if (err)
+		goto free_card;
+	err = gpio_direction_output(card->gpio_cs, 1);
+	if (err)
+		goto free_gpio;
+
+	/* Initialize the SPI Interface Unit */
+	err = spu_init(card, pdata->use_dummy_writes);
+	if (err)
+		goto free_gpio;
+	err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
+	if (err)
+		goto free_gpio;
+
+	/* Firmware load */
+	err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
+	if (err)
+		goto free_gpio;
+	if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
+		lbs_deb_spi("Firmware is already loaded for "
+			    "Marvell WLAN 802.11 adapter\n");
+	else {
+		err = if_spi_calculate_fw_names(card->card_id,
+				card->helper_fw_name, card->main_fw_name);
+		if (err)
+			goto free_gpio;
+
+		lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
+				"(chip_id = 0x%04x, chip_rev = 0x%02x) "
+				"attached to SPI bus_num %d, chip_select %d. "
+				"spi->max_speed_hz=%d\n",
+				card->card_id, card->card_rev,
+				spi->master->bus_num, spi->chip_select,
+				spi->max_speed_hz);
+		err = if_spi_prog_helper_firmware(card);
+		if (err)
+			goto free_gpio;
+		err = if_spi_prog_main_firmware(card);
+		if (err)
+			goto free_gpio;
+		lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
+	}
+
+	err = spu_set_interrupt_mode(card, 0, 1);
+	if (err)
+		goto free_gpio;
+
+	/* Register our card with libertas.
+	 * This will call alloc_etherdev */
+	priv = lbs_add_card(card, &spi->dev);
+	if (!priv) {
+		err = -ENOMEM;
+		goto free_gpio;
+	}
+	card->priv = priv;
+	priv->card = card;
+	priv->hw_host_to_card = if_spi_host_to_card;
+	priv->fw_ready = 1;
+	priv->ps_supported = 1;
+
+	/* Initialize interrupt handling stuff. */
+	card->run_thread = 1;
+	card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread");
+	if (IS_ERR(card->spi_thread)) {
+		card->run_thread = 0;
+		err = PTR_ERR(card->spi_thread);
+		lbs_pr_err("error creating SPI thread: err=%d\n", err);
+		goto remove_card;
+	}
+	err = request_irq(spi->irq, if_spi_host_interrupt,
+			IRQF_TRIGGER_FALLING, "libertas_spi", card);
+	if (err) {
+		lbs_pr_err("can't get host irq line-- request_irq failed\n");
+		goto terminate_thread;
+	}
+
+	/* Start the card.
+	 * This will call register_netdev, and we'll start
+	 * getting interrupts... */
+	err = lbs_start_card(priv);
+	if (err)
+		goto release_irq;
+
+	lbs_deb_spi("Finished initializing WLAN module.\n");
+
+	/* successful exit */
+	goto out;
+
+release_irq:
+	free_irq(spi->irq, card);
+terminate_thread:
+	if_spi_terminate_spi_thread(card);
+remove_card:
+	lbs_remove_card(priv); /* will call free_netdev */
+free_gpio:
+	gpio_free(card->gpio_cs);
+free_card:
+	free_if_spi_card(card);
+out:
+	lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
+	return err;
+}
+
+static int __devexit libertas_spi_remove(struct spi_device *spi)
+{
+	struct if_spi_card *card = spi_get_drvdata(spi);
+	struct lbs_private *priv = card->priv;
+
+	lbs_deb_spi("libertas_spi_remove\n");
+	lbs_deb_enter(LBS_DEB_SPI);
+	priv->surpriseremoved = 1;
+
+	lbs_stop_card(priv);
+	free_irq(spi->irq, card);
+	if_spi_terminate_spi_thread(card);
+	lbs_remove_card(priv); /* will call free_netdev */
+	gpio_free(card->gpio_cs);
+	if (card->pdata->teardown)
+		card->pdata->teardown(spi);
+	free_if_spi_card(card);
+	lbs_deb_leave(LBS_DEB_SPI);
+	return 0;
+}
+
+static struct spi_driver libertas_spi_driver = {
+	.probe	= if_spi_probe,
+	.remove = __devexit_p(libertas_spi_remove),
+	.driver = {
+		.name	= "libertas_spi",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+};
+
+/*
+ * Module functions
+ */
+
+static int __init if_spi_init_module(void)
+{
+	int ret = 0;
+	lbs_deb_enter(LBS_DEB_SPI);
+	printk(KERN_INFO "libertas_spi: Libertas SPI driver\n");
+	ret = spi_register_driver(&libertas_spi_driver);
+	lbs_deb_leave(LBS_DEB_SPI);
+	return ret;
+}
+
+static void __exit if_spi_exit_module(void)
+{
+	lbs_deb_enter(LBS_DEB_SPI);
+	spi_unregister_driver(&libertas_spi_driver);
+	lbs_deb_leave(LBS_DEB_SPI);
+}
+
+module_init(if_spi_init_module);
+module_exit(if_spi_exit_module);
+
+MODULE_DESCRIPTION("Libertas SPI WLAN Driver");
+MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, "
+	      "Colin McCabe <colin@cozybit.com>");
+MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_spi.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_spi.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/if_spi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/if_spi.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,208 @@
+/*
+ *	linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ *	Driver for Marvell SPI WLAN cards.
+ *
+ *	Copyright 2008 Analog Devices Inc.
+ *
+ *	Authors:
+ *	Andrey Yurovsky <andrey@cozybit.com>
+ *	Colin McCabe <colin@cozybit.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 _LBS_IF_SPI_H_
+#define _LBS_IF_SPI_H_
+
+#define IPFIELD_ALIGN_OFFSET 2
+#define IF_SPI_CMD_BUF_SIZE 2400
+
+/***************** Firmware *****************/
+struct chip_ident {
+	u16 chip_id;
+	u16 name;
+};
+
+#define MAX_MAIN_FW_LOAD_CRC_ERR 10
+
+/* Chunk size when loading the helper firmware */
+#define HELPER_FW_LOAD_CHUNK_SZ 64
+
+/* Value to write to indicate end of helper firmware dnld */
+#define FIRMWARE_DNLD_OK 0x0000
+
+/* Value to check once the main firmware is downloaded */
+#define SUCCESSFUL_FW_DOWNLOAD_MAGIC 0x88888888
+
+/***************** SPI Interface Unit *****************/
+/* Masks used in SPI register read/write operations */
+#define IF_SPI_READ_OPERATION_MASK 0x0
+#define IF_SPI_WRITE_OPERATION_MASK 0x8000
+
+/* SPI register offsets. 4-byte aligned. */
+#define IF_SPI_DEVICEID_CTRL_REG 0x00	/* DeviceID controller reg */
+#define IF_SPI_IO_READBASE_REG 0x04 	/* Read I/O base reg */
+#define IF_SPI_IO_WRITEBASE_REG 0x08	/* Write I/O base reg */
+#define IF_SPI_IO_RDWRPORT_REG 0x0C	/* Read/Write I/O port reg */
+
+#define IF_SPI_CMD_READBASE_REG 0x10	/* Read command base reg */
+#define IF_SPI_CMD_WRITEBASE_REG 0x14	/* Write command base reg */
+#define IF_SPI_CMD_RDWRPORT_REG 0x18	/* Read/Write command port reg */
+
+#define IF_SPI_DATA_READBASE_REG 0x1C	/* Read data base reg */
+#define IF_SPI_DATA_WRITEBASE_REG 0x20	/* Write data base reg */
+#define IF_SPI_DATA_RDWRPORT_REG 0x24	/* Read/Write data port reg */
+
+#define IF_SPI_SCRATCH_1_REG 0x28	/* Scratch reg 1 */
+#define IF_SPI_SCRATCH_2_REG 0x2C	/* Scratch reg 2 */
+#define IF_SPI_SCRATCH_3_REG 0x30	/* Scratch reg 3 */
+#define IF_SPI_SCRATCH_4_REG 0x34	/* Scratch reg 4 */
+
+#define IF_SPI_TX_FRAME_SEQ_NUM_REG 0x38 /* Tx frame sequence number reg */
+#define IF_SPI_TX_FRAME_STATUS_REG 0x3C	/* Tx frame status reg */
+
+#define IF_SPI_HOST_INT_CTRL_REG 0x40	/* Host interrupt controller reg */
+
+#define IF_SPI_CARD_INT_CAUSE_REG 0x44	/* Card interrupt cause reg */
+#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interupt status reg */
+#define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */
+#define IF_SPI_CARD_INT_STATUS_MASK_REG	0x50 /* Card interrupt status mask */
+
+#define IF_SPI_CARD_INT_RESET_SELECT_REG 0x54 /* Card interrupt reset select */
+
+#define IF_SPI_HOST_INT_CAUSE_REG 0x58	/* Host interrupt cause reg */
+#define IF_SPI_HOST_INT_STATUS_REG 0x5C	/* Host interrupt status reg */
+#define IF_SPI_HOST_INT_EVENT_MASK_REG 0x60 /* Host interrupt event mask */
+#define IF_SPI_HOST_INT_STATUS_MASK_REG	0x64 /* Host interrupt status mask */
+#define IF_SPI_HOST_INT_RESET_SELECT_REG 0x68 /* Host interrupt reset select */
+
+#define IF_SPI_DELAY_READ_REG 0x6C	/* Delay read reg */
+#define IF_SPI_SPU_BUS_MODE_REG 0x70	/* SPU BUS mode reg */
+
+/***************** IF_SPI_DEVICEID_CTRL_REG *****************/
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dc) ((dc & 0xffff0000)>>16)
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
+
+/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
+/** Host Interrupt Control bit : Wake up */
+#define IF_SPI_HICT_WAKE_UP				(1<<0)
+/** Host Interrupt Control bit : WLAN ready */
+#define IF_SPI_HICT_WLAN_READY				(1<<1)
+/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY		(1<<2) */
+/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY		(1<<3) */
+/*#define IF_SPI_HICT_IRQSRC_WLAN			(1<<4) */
+/** Host Interrupt Control bit : Tx auto download */
+#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO		(1<<5)
+/** Host Interrupt Control bit : Rx auto upload */
+#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO			(1<<6)
+/** Host Interrupt Control bit : Command auto download */
+#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO		(1<<7)
+/** Host Interrupt Control bit : Command auto upload */
+#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO		(1<<8)
+
+/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
+/** Card Interrupt Case bit : Tx download over */
+#define IF_SPI_CIC_TX_DOWNLOAD_OVER			(1<<0)
+/** Card Interrupt Case bit : Rx upload over */
+#define IF_SPI_CIC_RX_UPLOAD_OVER			(1<<1)
+/** Card Interrupt Case bit : Command download over */
+#define IF_SPI_CIC_CMD_DOWNLOAD_OVER			(1<<2)
+/** Card Interrupt Case bit : Host event */
+#define IF_SPI_CIC_HOST_EVENT				(1<<3)
+/** Card Interrupt Case bit : Command upload over */
+#define IF_SPI_CIC_CMD_UPLOAD_OVER			(1<<4)
+/** Card Interrupt Case bit : Power down */
+#define IF_SPI_CIC_POWER_DOWN				(1<<5)
+
+/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
+#define IF_SPI_CIS_TX_DOWNLOAD_OVER			(1<<0)
+#define IF_SPI_CIS_RX_UPLOAD_OVER			(1<<1)
+#define IF_SPI_CIS_CMD_DOWNLOAD_OVER			(1<<2)
+#define IF_SPI_CIS_HOST_EVENT				(1<<3)
+#define IF_SPI_CIS_CMD_UPLOAD_OVER			(1<<4)
+#define IF_SPI_CIS_POWER_DOWN				(1<<5)
+
+/***************** IF_SPI_HOST_INT_CAUSE_REG *****************/
+#define IF_SPI_HICU_TX_DOWNLOAD_RDY			(1<<0)
+#define IF_SPI_HICU_RX_UPLOAD_RDY			(1<<1)
+#define IF_SPI_HICU_CMD_DOWNLOAD_RDY			(1<<2)
+#define IF_SPI_HICU_CARD_EVENT				(1<<3)
+#define IF_SPI_HICU_CMD_UPLOAD_RDY			(1<<4)
+#define IF_SPI_HICU_IO_WR_FIFO_OVERFLOW			(1<<5)
+#define IF_SPI_HICU_IO_RD_FIFO_UNDERFLOW		(1<<6)
+#define IF_SPI_HICU_DATA_WR_FIFO_OVERFLOW		(1<<7)
+#define IF_SPI_HICU_DATA_RD_FIFO_UNDERFLOW		(1<<8)
+#define IF_SPI_HICU_CMD_WR_FIFO_OVERFLOW		(1<<9)
+#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW		(1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
+/** Host Interrupt Status bit : Tx download ready */
+#define IF_SPI_HIST_TX_DOWNLOAD_RDY			(1<<0)
+/** Host Interrupt Status bit : Rx upload ready */
+#define IF_SPI_HIST_RX_UPLOAD_RDY			(1<<1)
+/** Host Interrupt Status bit : Command download ready */
+#define IF_SPI_HIST_CMD_DOWNLOAD_RDY			(1<<2)
+/** Host Interrupt Status bit : Card event */
+#define IF_SPI_HIST_CARD_EVENT				(1<<3)
+/** Host Interrupt Status bit : Command upload ready */
+#define IF_SPI_HIST_CMD_UPLOAD_RDY			(1<<4)
+/** Host Interrupt Status bit : I/O write FIFO overflow */
+#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW			(1<<5)
+/** Host Interrupt Status bit : I/O read FIFO underflow */
+#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW			(1<<6)
+/** Host Interrupt Status bit : Data write FIFO overflow */
+#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW		(1<<7)
+/** Host Interrupt Status bit : Data read FIFO underflow */
+#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW		(1<<8)
+/** Host Interrupt Status bit : Command write FIFO overflow */
+#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW		(1<<9)
+/** Host Interrupt Status bit : Command read FIFO underflow */
+#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW		(1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
+/** Host Interrupt Status Mask bit : Tx download ready */
+#define IF_SPI_HISM_TX_DOWNLOAD_RDY			(1<<0)
+/** Host Interrupt Status Mask bit : Rx upload ready */
+#define IF_SPI_HISM_RX_UPLOAD_RDY			(1<<1)
+/** Host Interrupt Status Mask bit : Command download ready */
+#define IF_SPI_HISM_CMD_DOWNLOAD_RDY			(1<<2)
+/** Host Interrupt Status Mask bit : Card event */
+#define IF_SPI_HISM_CARDEVENT				(1<<3)
+/** Host Interrupt Status Mask bit : Command upload ready */
+#define IF_SPI_HISM_CMD_UPLOAD_RDY			(1<<4)
+/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
+#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW			(1<<5)
+/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
+#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW		(1<<6)
+/** Host Interrupt Status Mask bit : Data write FIFO overflow */
+#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW		(1<<7)
+/** Host Interrupt Status Mask bit : Data write FIFO underflow */
+#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW		(1<<8)
+/** Host Interrupt Status Mask bit : Command write FIFO overflow */
+#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW		(1<<9)
+/** Host Interrupt Status Mask bit : Command write FIFO underflow */
+#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW		(1<<10)
+
+/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
+/* SCK edge on which the WLAN module outputs data on MISO */
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_FALLING 0x8
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING 0x0
+
+/* In a SPU read operation, there is a delay between writing the SPU
+ * register name and getting back data from the WLAN module.
+ * This can be specified in terms of nanoseconds or in terms of dummy
+ * clock cycles which the master must output before receiving a response. */
+#define IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK 0x4
+#define IF_SPI_BUS_MODE_DELAY_METHOD_TIMED 0x0
+
+/* Some different modes of SPI operation */
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_16_BIT_DATA 0x00
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_32_BIT_DATA 0x01
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA 0x02
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_32_BIT_DATA 0x03
+
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -582,20 +582,6 @@ void lbs_host_to_card_done(struct lbs_pr
 }
 EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
 
-/**
- *  @brief This function returns the network statistics
- *
- *  @param dev     A pointer to struct lbs_private structure
- *  @return 	   A pointer to net_device_stats structure
- */
-static struct net_device_stats *lbs_get_stats(struct net_device *dev)
-{
-	struct lbs_private *priv = dev->ml_priv;
-
-	lbs_deb_enter(LBS_DEB_NET);
-	return &priv->stats;
-}
-
 static int lbs_set_mac_address(struct net_device *dev, void *addr)
 {
 	int ret = 0;
@@ -1006,9 +992,8 @@ void lbs_resume(struct lbs_private *priv
 EXPORT_SYMBOL_GPL(lbs_resume);
 
 /**
- *  @brief This function downloads firmware image, gets
- *  HW spec from firmware and set basic parameters to
- *  firmware.
+ * @brief This function gets the HW spec from the firmware and sets
+ *        some basic parameters.
  *
  *  @param priv    A pointer to struct lbs_private structure
  *  @return 	   0 or -1
@@ -1163,6 +1148,17 @@ static void lbs_free_adapter(struct lbs_
 	lbs_deb_leave(LBS_DEB_MAIN);
 }
 
+static const struct net_device_ops lbs_netdev_ops = {
+	.ndo_open 		= lbs_dev_open,
+	.ndo_stop		= lbs_eth_stop,
+	.ndo_start_xmit		= lbs_hard_start_xmit,
+	.ndo_set_mac_address	= lbs_set_mac_address,
+	.ndo_tx_timeout 	= lbs_tx_timeout,
+	.ndo_set_multicast_list = lbs_set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /**
  * @brief This function adds the card. it will probe the
  * card, allocate the lbs_priv and initialize the device.
@@ -1197,19 +1193,13 @@ struct lbs_private *lbs_add_card(void *c
 	priv->infra_open = 0;
 
 	/* Setup the OS Interface to our functions */
-	dev->open = lbs_dev_open;
-	dev->hard_start_xmit = lbs_hard_start_xmit;
-	dev->stop = lbs_eth_stop;
-	dev->set_mac_address = lbs_set_mac_address;
-	dev->tx_timeout = lbs_tx_timeout;
-	dev->get_stats = lbs_get_stats;
+ 	dev->netdev_ops = &lbs_netdev_ops;
 	dev->watchdog_timeo = 5 * HZ;
 	dev->ethtool_ops = &lbs_ethtool_ops;
 #ifdef	WIRELESS_EXT
-	dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
+	dev->wireless_handlers = &lbs_handler_def;
 #endif
 	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-	dev->set_multicast_list = lbs_set_multicast_list;
 
 	SET_NETDEV_DEV(dev, dmdev);
 
@@ -1419,6 +1409,14 @@ 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
  *
@@ -1441,11 +1439,7 @@ static int lbs_add_mesh(struct lbs_priva
 	mesh_dev->ml_priv = priv;
 	priv->mesh_dev = mesh_dev;
 
-	mesh_dev->open = lbs_dev_open;
-	mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
-	mesh_dev->stop = lbs_mesh_stop;
-	mesh_dev->get_stats = lbs_get_stats;
-	mesh_dev->set_mac_address = lbs_set_mac_address;
+	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));
@@ -1456,7 +1450,6 @@ static int lbs_add_mesh(struct lbs_priva
 	mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
 #endif
 	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-	mesh_dev->set_multicast_list = lbs_set_multicast_list;
 	/* Register virtual mesh interface */
 	ret = register_netdev(mesh_dev);
 	if (ret) {
@@ -1649,14 +1642,6 @@ static int lbs_rtap_hard_start_xmit(stru
 	return NETDEV_TX_BUSY;
 }
 
-static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
-{
-	struct lbs_private *priv = dev->ml_priv;
-	lbs_deb_enter(LBS_DEB_NET);
-	return &priv->stats;
-}
-
-
 static void lbs_remove_rtap(struct lbs_private *priv)
 {
 	lbs_deb_enter(LBS_DEB_MAIN);
@@ -1669,6 +1654,12 @@ out:
 	lbs_deb_leave(LBS_DEB_MAIN);
 }
 
+static const struct net_device_ops rtap_netdev_ops = {
+	.ndo_open = lbs_rtap_open,
+	.ndo_stop = lbs_rtap_stop,
+	.ndo_start_xmit = lbs_rtap_hard_start_xmit,
+};
+
 static int lbs_add_rtap(struct lbs_private *priv)
 {
 	int ret = 0;
@@ -1688,10 +1679,7 @@ static int lbs_add_rtap(struct lbs_priva
 
 	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
 	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-	rtap_dev->open = lbs_rtap_open;
-	rtap_dev->stop = lbs_rtap_stop;
-	rtap_dev->get_stats = lbs_rtap_get_stats;
-	rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
+	rtap_dev->netdev_ops = &rtap_netdev_ops;
 	rtap_dev->ml_priv = priv;
 	SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -4,8 +4,10 @@ libertas-objs := main.o wext.o rx.o tx.o
 usb8xxx-objs += if_usb.o
 libertas_cs-objs += if_cs.o
 libertas_sdio-objs += if_sdio.o
+libertas_spi-objs += if_spi.o
 
 obj-$(CONFIG_LIBERTAS)     += libertas.o
 obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
 obj-$(CONFIG_LIBERTAS_CS)  += libertas_cs.o
 obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
+obj-$(CONFIG_LIBERTAS_SPI) += libertas_spi.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/radiotap.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/radiotap.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/radiotap.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/radiotap.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,22 +33,12 @@ struct rx_radiotap_hdr {
 	struct ieee80211_radiotap_header hdr;
 	u8 flags;
 	u8 rate;
-	u16 chan_freq;
-	u16 chan_flags;
-	u8 antenna;
 	u8 antsignal;
-	u16 rx_flags;
-#if 0
-	u8 pad[IEEE80211_RADIOTAP_HDRLEN - 18];
-#endif
 } __attribute__ ((packed));
 
 #define RX_RADIOTAP_PRESENT (			\
 	(1 << IEEE80211_RADIOTAP_FLAGS) |	\
 	(1 << IEEE80211_RADIOTAP_RATE) |	\
-	(1 << IEEE80211_RADIOTAP_CHANNEL) |	\
-	(1 << IEEE80211_RADIOTAP_ANTENNA) |	\
 	(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\
-	(1 << IEEE80211_RADIOTAP_RX_FLAGS) |	\
 	0)
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/rx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/rx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/rx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/rx.c	2009-06-09 23:05:27.000000000 -0400
@@ -168,8 +168,9 @@ int lbs_process_rxed_packet(struct lbs_p
 
 	if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
 		lbs_deb_rx("rx err: frame received with bad length\n");
-		priv->stats.rx_length_errors++;
+		dev->stats.rx_length_errors++;
 		ret = 0;
+		dev_kfree_skb(skb);
 		goto done;
 	}
 
@@ -179,8 +180,9 @@ int lbs_process_rxed_packet(struct lbs_p
 	if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
 		lbs_deb_rx("rx err: frame received with bad status\n");
 		lbs_pr_alert("rxpd not ok\n");
-		priv->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		ret = 0;
+		dev_kfree_skb(skb);
 		goto done;
 	}
 
@@ -243,8 +245,8 @@ int lbs_process_rxed_packet(struct lbs_p
 	lbs_compute_rssi(priv, p_rx_pd);
 
 	lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
-	priv->stats.rx_bytes += skb->len;
-	priv->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_packets++;
 
 	skb->protocol = eth_type_trans(skb, dev);
 	if (in_interrupt())
@@ -311,7 +313,7 @@ static int process_rxed_802_11_packet(st
 	struct sk_buff *skb)
 {
 	int ret = 0;
-
+	struct net_device *dev = priv->dev;
 	struct rx80211packethdr *p_rx_pkt;
 	struct rxpd *prxpd;
 	struct rx_radiotap_hdr radiotap_hdr;
@@ -326,7 +328,7 @@ static int process_rxed_802_11_packet(st
 
 	if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
 		lbs_deb_rx("rx err: frame received with bad length\n");
-		priv->stats.rx_length_errors++;
+		dev->stats.rx_length_errors++;
 		ret = -EINVAL;
 		kfree_skb(skb);
 		goto done;
@@ -337,7 +339,7 @@ static int process_rxed_802_11_packet(st
 	 */
 	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
 		//lbs_deb_rx("rx err: frame received with bad status\n");
-		priv->stats.rx_errors++;
+		dev->stats.rx_errors++;
 	}
 
 	lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
@@ -351,19 +353,11 @@ static int process_rxed_802_11_packet(st
 	radiotap_hdr.hdr.it_pad = 0;
 	radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
 	radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
-	/* unknown values */
-	radiotap_hdr.flags = 0;
-	radiotap_hdr.chan_freq = 0;
-	radiotap_hdr.chan_flags = 0;
-	radiotap_hdr.antenna = 0;
-	/* known values */
+	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
+		radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
 	radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
 	/* XXX must check no carryout */
 	radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
-	radiotap_hdr.rx_flags = 0;
-	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
-		radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
-	//memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
 
 	/* chop the rxpd */
 	skb_pull(skb, sizeof(struct rxpd));
@@ -389,8 +383,8 @@ static int process_rxed_802_11_packet(st
 	lbs_compute_rssi(priv, prxpd);
 
 	lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
-	priv->stats.rx_bytes += skb->len;
-	priv->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_packets++;
 
 	skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
 	netif_rx(skb);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/scan.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/scan.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/scan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -692,7 +692,7 @@ static int lbs_process_bss(struct bss_de
 					    bss->wpa_ie_len);
 			} else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
 				   pos[2] == 0x00 && pos[3] == 0x50 &&
-				   pos[4] == 0x43 && pos[4] == 0x04) {
+				   pos[4] == 0x43 && pos[5] == 0x04) {
 				lbs_deb_scan("got mesh IE\n");
 				bss->mesh = 1;
 			} else {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/tx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/tx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/tx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/tx.c	2009-06-09 23:05:27.000000000 -0400
@@ -82,8 +82,8 @@ int lbs_hard_start_xmit(struct sk_buff *
 		       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
 		/* We'll never manage to send this one; drop it and return 'OK' */
 
-		priv->stats.tx_dropped++;
-		priv->stats.tx_errors++;
+		dev->stats.tx_dropped++;
+		dev->stats.tx_errors++;
 		goto free;
 	}
 
@@ -146,8 +146,8 @@ int lbs_hard_start_xmit(struct sk_buff *
 
 	lbs_deb_tx("%s lined up packet\n", __func__);
 
-	priv->stats.tx_packets++;
-	priv->stats.tx_bytes += skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
 
 	dev->trans_start = jiffies;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/wext.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/wext.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas/wext.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas/wext.c	2009-06-09 23:05:27.000000000 -0400
@@ -830,7 +830,7 @@ static struct iw_statistics *lbs_get_wir
 	quality = rssi_qual;
 
 	/* Quality by TX errors */
-	priv->wstats.discard.retries = priv->stats.tx_errors;
+	priv->wstats.discard.retries = dev->stats.tx_errors;
 
 	memset(&log, 0, sizeof(log));
 	log.hdr.size = cpu_to_le16(sizeof(log));
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas_tf/cmd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas_tf/cmd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas_tf/cmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas_tf/cmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -286,7 +286,7 @@ void lbtf_set_mode(struct lbtf_private *
 	lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
 }
 
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid)
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
 {
 	struct cmd_ds_set_bssid cmd;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas_tf/libertas_tf.h linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas_tf/libertas_tf.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/libertas_tf/libertas_tf.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/libertas_tf/libertas_tf.h	2009-06-09 23:05:27.000000000 -0400
@@ -463,7 +463,7 @@ int lbtf_set_radio_control(struct lbtf_p
 int lbtf_update_hw_spec(struct lbtf_private *priv);
 int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv);
 void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode);
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid);
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid);
 int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr);
 
 int lbtf_set_channel(struct lbtf_private *priv, u8 channel);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/mac80211_hwsim.c linux-libre-2.6.30-gnu1/drivers/net/wireless/mac80211_hwsim.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/mac80211_hwsim.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/mac80211_hwsim.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,7 +10,6 @@
 /*
  * TODO:
  * - IBSS mode simulation (Beacon transmission with competition for "air time")
- * - IEEE 802.11a and 802.11n modes
  * - RX filtering based on filter configuration (data->rx_filter)
  */
 
@@ -31,6 +30,112 @@ static int radios = 2;
 module_param(radios, int, 0444);
 MODULE_PARM_DESC(radios, "Number of simulated radios");
 
+/**
+ * enum hwsim_regtest - the type of regulatory tests we offer
+ *
+ * These are the different values you can use for the regtest
+ * module parameter. This is useful to help test world roaming
+ * and the driver regulatory_hint() call and combinations of these.
+ * If you want to do specific alpha2 regulatory domain tests simply
+ * use the userspace regulatory request as that will be respected as
+ * well without the need of this module parameter. This is designed
+ * only for testing the driver regulatory request, world roaming
+ * and all possible combinations.
+ *
+ * @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
+ * 	this is the default value.
+ * @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
+ *	hint, only one driver regulatory hint will be sent as such the
+ * 	secondary radios are expected to follow.
+ * @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
+ * 	request with all radios reporting the same regulatory domain.
+ * @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
+ * 	different regulatory domains requests. Expected behaviour is for
+ * 	an intersection to occur but each device will still use their
+ * 	respective regulatory requested domains. Subsequent radios will
+ * 	use the resulting intersection.
+ * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We acomplish
+ *	this by using a custom beacon-capable regulatory domain for the first
+ *	radio. All other device world roam.
+ * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
+ * 	domain requests. All radios will adhere to this custom world regulatory
+ * 	domain.
+ * @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
+ * 	domain requests. The first radio will adhere to the first custom world
+ * 	regulatory domain, the second one to the second custom world regulatory
+ * 	domain. All other devices will world roam.
+ * @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
+ *	settings, only the first radio will send a regulatory domain request
+ *	and use strict settings. The rest of the radios are expected to follow.
+ * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
+ *	settings. All radios will adhere to this.
+ * @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
+ *	domain settings, combined with secondary driver regulatory domain
+ *	settings. The first radio will get a strict regulatory domain setting
+ *	using the first driver regulatory request and the second radio will use
+ *	non-strict settings using the second driver regulatory request. All
+ *	other devices should follow the intersection created between the
+ *	first two.
+ * @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
+ * 	at least 6 radios for a complete test. We will test in this order:
+ * 	1 - driver custom world regulatory domain
+ * 	2 - second custom world regulatory domain
+ * 	3 - first driver regulatory domain request
+ * 	4 - second driver regulatory domain request
+ * 	5 - strict regulatory domain settings using the third driver regulatory
+ * 	    domain request
+ * 	6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
+ * 	           regulatory requests.
+ */
+enum hwsim_regtest {
+	HWSIM_REGTEST_DISABLED = 0,
+	HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
+	HWSIM_REGTEST_DRIVER_REG_ALL = 2,
+	HWSIM_REGTEST_DIFF_COUNTRY = 3,
+	HWSIM_REGTEST_WORLD_ROAM = 4,
+	HWSIM_REGTEST_CUSTOM_WORLD = 5,
+	HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
+	HWSIM_REGTEST_STRICT_FOLLOW = 7,
+	HWSIM_REGTEST_STRICT_ALL = 8,
+	HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
+	HWSIM_REGTEST_ALL = 10,
+};
+
+/* Set to one of the HWSIM_REGTEST_* values above */
+static int regtest = HWSIM_REGTEST_DISABLED;
+module_param(regtest, int, 0444);
+MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
+
+static const char *hwsim_alpha2s[] = {
+	"FI",
+	"AL",
+	"US",
+	"DE",
+	"JP",
+	"AL",
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
+	.n_reg_rules = 4,
+	.alpha2 =  "99",
+	.reg_rules = {
+		REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+		REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
+		REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
+		REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
+	}
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
+	.n_reg_rules = 2,
+	.alpha2 =  "99",
+	.reg_rules = {
+		REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+		REG_RULE(5725-10, 5850+10, 40, 0, 30,
+			NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+	}
+};
+
 struct hwsim_vif_priv {
 	u32 magic;
 	u8 bssid[ETH_ALEN];
@@ -86,22 +191,65 @@ static struct class *hwsim_class;
 
 static struct net_device *hwsim_mon; /* global monitor netdev */
 
+#define CHAN2G(_freq)  { \
+	.band = IEEE80211_BAND_2GHZ, \
+	.center_freq = (_freq), \
+	.hw_value = (_freq), \
+	.max_power = 20, \
+}
 
-static const struct ieee80211_channel hwsim_channels[] = {
-	{ .center_freq = 2412 },
-	{ .center_freq = 2417 },
-	{ .center_freq = 2422 },
-	{ .center_freq = 2427 },
-	{ .center_freq = 2432 },
-	{ .center_freq = 2437 },
-	{ .center_freq = 2442 },
-	{ .center_freq = 2447 },
-	{ .center_freq = 2452 },
-	{ .center_freq = 2457 },
-	{ .center_freq = 2462 },
-	{ .center_freq = 2467 },
-	{ .center_freq = 2472 },
-	{ .center_freq = 2484 },
+#define CHAN5G(_freq) { \
+	.band = IEEE80211_BAND_5GHZ, \
+	.center_freq = (_freq), \
+	.hw_value = (_freq), \
+	.max_power = 20, \
+}
+
+static const struct ieee80211_channel hwsim_channels_2ghz[] = {
+	CHAN2G(2412), /* Channel 1 */
+	CHAN2G(2417), /* Channel 2 */
+	CHAN2G(2422), /* Channel 3 */
+	CHAN2G(2427), /* Channel 4 */
+	CHAN2G(2432), /* Channel 5 */
+	CHAN2G(2437), /* Channel 6 */
+	CHAN2G(2442), /* Channel 7 */
+	CHAN2G(2447), /* Channel 8 */
+	CHAN2G(2452), /* Channel 9 */
+	CHAN2G(2457), /* Channel 10 */
+	CHAN2G(2462), /* Channel 11 */
+	CHAN2G(2467), /* Channel 12 */
+	CHAN2G(2472), /* Channel 13 */
+	CHAN2G(2484), /* Channel 14 */
+};
+
+static const struct ieee80211_channel hwsim_channels_5ghz[] = {
+	CHAN5G(5180), /* Channel 36 */
+	CHAN5G(5200), /* Channel 40 */
+	CHAN5G(5220), /* Channel 44 */
+	CHAN5G(5240), /* Channel 48 */
+
+	CHAN5G(5260), /* Channel 52 */
+	CHAN5G(5280), /* Channel 56 */
+	CHAN5G(5300), /* Channel 60 */
+	CHAN5G(5320), /* Channel 64 */
+
+	CHAN5G(5500), /* Channel 100 */
+	CHAN5G(5520), /* Channel 104 */
+	CHAN5G(5540), /* Channel 108 */
+	CHAN5G(5560), /* Channel 112 */
+	CHAN5G(5580), /* Channel 116 */
+	CHAN5G(5600), /* Channel 120 */
+	CHAN5G(5620), /* Channel 124 */
+	CHAN5G(5640), /* Channel 128 */
+	CHAN5G(5660), /* Channel 132 */
+	CHAN5G(5680), /* Channel 136 */
+	CHAN5G(5700), /* Channel 140 */
+
+	CHAN5G(5745), /* Channel 149 */
+	CHAN5G(5765), /* Channel 153 */
+	CHAN5G(5785), /* Channel 157 */
+	CHAN5G(5805), /* Channel 161 */
+	CHAN5G(5825), /* Channel 165 */
 };
 
 static const struct ieee80211_rate hwsim_rates[] = {
@@ -126,8 +274,9 @@ struct mac80211_hwsim_data {
 	struct list_head list;
 	struct ieee80211_hw *hw;
 	struct device *dev;
-	struct ieee80211_supported_band band;
-	struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)];
+	struct ieee80211_supported_band bands[2];
+	struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
+	struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
 	struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
 
 	struct ieee80211_channel *channel;
@@ -590,10 +739,16 @@ static struct device_driver mac80211_hws
 	.name = "mac80211_hwsim"
 };
 
+static const struct net_device_ops hwsim_netdev_ops = {
+	.ndo_start_xmit 	= hwsim_mon_xmit,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 static void hwsim_mon_setup(struct net_device *dev)
 {
-	dev->hard_start_xmit = hwsim_mon_xmit;
+	dev->netdev_ops = &hwsim_netdev_ops;
 	dev->destructor = free_netdev;
 	ether_setup(dev);
 	dev->tx_queue_len = 0;
@@ -728,6 +883,7 @@ static int __init init_mac80211_hwsim(vo
 	u8 addr[ETH_ALEN];
 	struct mac80211_hwsim_data *data;
 	struct ieee80211_hw *hw;
+	enum ieee80211_band band;
 
 	if (radios < 1 || radios > 100)
 		return -EINVAL;
@@ -777,32 +933,116 @@ static int __init init_mac80211_hwsim(vo
 			BIT(NL80211_IFTYPE_STATION) |
 			BIT(NL80211_IFTYPE_AP) |
 			BIT(NL80211_IFTYPE_MESH_POINT);
-		hw->ampdu_queues = 1;
+
+		hw->flags = IEEE80211_HW_MFP_CAPABLE;
 
 		/* ask mac80211 to reserve space for magic */
 		hw->vif_data_size = sizeof(struct hwsim_vif_priv);
 		hw->sta_data_size = sizeof(struct hwsim_sta_priv);
 
-		memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
+		memcpy(data->channels_2ghz, hwsim_channels_2ghz,
+			sizeof(hwsim_channels_2ghz));
+		memcpy(data->channels_5ghz, hwsim_channels_5ghz,
+			sizeof(hwsim_channels_5ghz));
 		memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
-		data->band.channels = data->channels;
-		data->band.n_channels = ARRAY_SIZE(hwsim_channels);
-		data->band.bitrates = data->rates;
-		data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
-		data->band.ht_cap.ht_supported = true;
-		data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-			IEEE80211_HT_CAP_GRN_FLD |
-			IEEE80211_HT_CAP_SGI_40 |
-			IEEE80211_HT_CAP_DSSSCCK40;
-		data->band.ht_cap.ampdu_factor = 0x3;
-		data->band.ht_cap.ampdu_density = 0x6;
-		memset(&data->band.ht_cap.mcs, 0,
-		       sizeof(data->band.ht_cap.mcs));
-		data->band.ht_cap.mcs.rx_mask[0] = 0xff;
-		data->band.ht_cap.mcs.rx_mask[1] = 0xff;
-		data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
 
+		for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
+			struct ieee80211_supported_band *sband = &data->bands[band];
+			switch (band) {
+			case IEEE80211_BAND_2GHZ:
+				sband->channels = data->channels_2ghz;
+				sband->n_channels =
+					ARRAY_SIZE(hwsim_channels_2ghz);
+				break;
+			case IEEE80211_BAND_5GHZ:
+				sband->channels = data->channels_5ghz;
+				sband->n_channels =
+					ARRAY_SIZE(hwsim_channels_5ghz);
+				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 |
+				IEEE80211_HT_CAP_SGI_40 |
+				IEEE80211_HT_CAP_DSSSCCK40;
+			sband->ht_cap.ampdu_factor = 0x3;
+			sband->ht_cap.ampdu_density = 0x6;
+			memset(&sband->ht_cap.mcs, 0,
+			       sizeof(sband->ht_cap.mcs));
+			sband->ht_cap.mcs.rx_mask[0] = 0xff;
+			sband->ht_cap.mcs.rx_mask[1] = 0xff;
+			sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+			hw->wiphy->bands[band] = sband;
+		}
+
+		/* Work to be done prior to ieee80211_register_hw() */
+		switch (regtest) {
+		case HWSIM_REGTEST_DISABLED:
+		case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+		case HWSIM_REGTEST_DRIVER_REG_ALL:
+		case HWSIM_REGTEST_DIFF_COUNTRY:
+			/*
+			 * Nothing to be done for driver regulatory domain
+			 * hints prior to ieee80211_register_hw()
+			 */
+			break;
+		case HWSIM_REGTEST_WORLD_ROAM:
+			if (i == 0) {
+				hw->wiphy->custom_regulatory = true;
+				wiphy_apply_custom_regulatory(hw->wiphy,
+					&hwsim_world_regdom_custom_01);
+			}
+			break;
+		case HWSIM_REGTEST_CUSTOM_WORLD:
+			hw->wiphy->custom_regulatory = true;
+			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;
+				wiphy_apply_custom_regulatory(hw->wiphy,
+					&hwsim_world_regdom_custom_01);
+			} else if (i == 1) {
+				hw->wiphy->custom_regulatory = true;
+				wiphy_apply_custom_regulatory(hw->wiphy,
+					&hwsim_world_regdom_custom_02);
+			}
+			break;
+		case HWSIM_REGTEST_STRICT_ALL:
+			hw->wiphy->strict_regulatory = true;
+			break;
+		case HWSIM_REGTEST_STRICT_FOLLOW:
+		case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+			if (i == 0)
+				hw->wiphy->strict_regulatory = true;
+			break;
+		case HWSIM_REGTEST_ALL:
+			if (i == 0) {
+				hw->wiphy->custom_regulatory = true;
+				wiphy_apply_custom_regulatory(hw->wiphy,
+					&hwsim_world_regdom_custom_01);
+			} else if (i == 1) {
+				hw->wiphy->custom_regulatory = true;
+				wiphy_apply_custom_regulatory(hw->wiphy,
+					&hwsim_world_regdom_custom_02);
+			} else if (i == 4)
+				hw->wiphy->strict_regulatory = true;
+			break;
+		default:
+			break;
+		}
+
+		/* give the regulatory workqueue a chance to run */
+		if (regtest)
+			schedule_timeout_interruptible(1);
 		err = ieee80211_register_hw(hw);
 		if (err < 0) {
 			printk(KERN_DEBUG "mac80211_hwsim: "
@@ -810,6 +1050,52 @@ static int __init init_mac80211_hwsim(vo
 			goto failed_hw;
 		}
 
+		/* Work to be done after to ieee80211_register_hw() */
+		switch (regtest) {
+		case HWSIM_REGTEST_WORLD_ROAM:
+		case HWSIM_REGTEST_DISABLED:
+			break;
+		case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+			if (!i)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+			break;
+		case HWSIM_REGTEST_DRIVER_REG_ALL:
+		case HWSIM_REGTEST_STRICT_ALL:
+			regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+			break;
+		case HWSIM_REGTEST_DIFF_COUNTRY:
+			if (i < ARRAY_SIZE(hwsim_alpha2s))
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[i]);
+			break;
+		case HWSIM_REGTEST_CUSTOM_WORLD:
+		case HWSIM_REGTEST_CUSTOM_WORLD_2:
+			/*
+			 * Nothing to be done for custom world regulatory
+			 * domains after to ieee80211_register_hw
+			 */
+			break;
+		case HWSIM_REGTEST_STRICT_FOLLOW:
+			if (i == 0)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+			break;
+		case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+			if (i == 0)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+			else if (i == 1)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+			break;
+		case HWSIM_REGTEST_ALL:
+			if (i == 2)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+			else if (i == 3)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+			else if (i == 4)
+				regulatory_hint(hw->wiphy, hwsim_alpha2s[2]);
+			break;
+		default:
+			break;
+		}
+
 		printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
 		       wiphy_name(hw->wiphy),
 		       hw->wiphy->perm_addr);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,8 @@ obj-$(CONFIG_ATMEL)             += atmel
 obj-$(CONFIG_PCI_ATMEL)         += atmel_pci.o 
 obj-$(CONFIG_PCMCIA_ATMEL)      += atmel_cs.o
 
+obj-$(CONFIG_AT76C50X_USB)      += at76c50x-usb.o
+
 obj-$(CONFIG_PRISM54)		+= prism54/
 
 obj-$(CONFIG_HOSTAP)		+= hostap/
@@ -46,6 +48,8 @@ obj-$(CONFIG_LIBERTAS_THINFIRM)	+= liber
 
 obj-$(CONFIG_ADM8211)	+= adm8211.o
 
+obj-$(CONFIG_MWL8K)	+= mwl8k.o
+
 obj-$(CONFIG_IWLWIFI)	+= iwlwifi/
 obj-$(CONFIG_RT2X00)	+= rt2x00/
 
@@ -53,5 +57,6 @@ obj-$(CONFIG_P54_COMMON)	+= p54/
 
 obj-$(CONFIG_ATH5K)	+= ath5k/
 obj-$(CONFIG_ATH9K)	+= ath9k/
+obj-$(CONFIG_AR9170_USB)	+= ar9170/
 
 obj-$(CONFIG_MAC80211_HWSIM)	+= mac80211_hwsim.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/mwl8k.c linux-libre-2.6.30-gnu1/drivers/net/wireless/mwl8k.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/mwl8k.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/mwl8k.c	2013-05-03 16:48:50.000000000 -0400
@@ -0,0 +1,3788 @@
+/*
+ * drivers/net/wireless/mwl8k.c driver for Marvell TOPDOG 802.11 Wireless cards
+ *
+ * Copyright (C) 2008 Marvell Semiconductor Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/workqueue.h>
+
+#define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
+#define MWL8K_NAME	KBUILD_MODNAME
+#define MWL8K_VERSION	"0.9.1"
+
+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);
+
+#define IEEE80211_ADDR_LEN			ETH_ALEN
+
+/* Register definitions */
+#define MWL8K_HIU_GEN_PTR			0x00000c10
+#define  MWL8K_MODE_STA				0x0000005a
+#define  MWL8K_MODE_AP				0x000000a5
+#define MWL8K_HIU_INT_CODE			0x00000c14
+#define  MWL8K_FWSTA_READY			0xf0f1f2f4
+#define  MWL8K_FWAP_READY			0xf1f2f4a5
+#define  MWL8K_INT_CODE_CMD_FINISHED		0x00000005
+#define MWL8K_HIU_SCRATCH			0x00000c40
+
+/* Host->device communications */
+#define MWL8K_HIU_H2A_INTERRUPT_EVENTS		0x00000c18
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS		0x00000c1c
+#define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
+#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
+#define  MWL8K_H2A_INT_DUMMY			(1 << 20)
+#define  MWL8K_H2A_INT_RESET			(1 << 15)
+#define  MWL8K_H2A_INT_PS			(1 << 2)
+#define  MWL8K_H2A_INT_DOORBELL			(1 << 1)
+#define  MWL8K_H2A_INT_PPA_READY		(1 << 0)
+
+/* Device->host communications */
+#define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS		0x00000c30
+#define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
+#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
+#define  MWL8K_A2H_INT_DUMMY			(1 << 20)
+#define  MWL8K_A2H_INT_CHNL_SWITCHED		(1 << 11)
+#define  MWL8K_A2H_INT_QUEUE_EMPTY		(1 << 10)
+#define  MWL8K_A2H_INT_RADAR_DETECT		(1 << 7)
+#define  MWL8K_A2H_INT_RADIO_ON			(1 << 6)
+#define  MWL8K_A2H_INT_RADIO_OFF		(1 << 5)
+#define  MWL8K_A2H_INT_MAC_EVENT		(1 << 3)
+#define  MWL8K_A2H_INT_OPC_DONE			(1 << 2)
+#define  MWL8K_A2H_INT_RX_READY			(1 << 1)
+#define  MWL8K_A2H_INT_TX_DONE			(1 << 0)
+
+#define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
+				 MWL8K_A2H_INT_CHNL_SWITCHED | \
+				 MWL8K_A2H_INT_QUEUE_EMPTY | \
+				 MWL8K_A2H_INT_RADAR_DETECT | \
+				 MWL8K_A2H_INT_RADIO_ON | \
+				 MWL8K_A2H_INT_RADIO_OFF | \
+				 MWL8K_A2H_INT_MAC_EVENT | \
+				 MWL8K_A2H_INT_OPC_DONE | \
+				 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 mwl8k_rx_queue {
+	int rx_desc_count;
+
+	/* hw receives here */
+	int rx_head;
+
+	/* refill descs here */
+	int rx_tail;
+
+	struct mwl8k_rx_desc *rx_desc_area;
+	dma_addr_t rx_desc_dma;
+	struct sk_buff **rx_skb;
+};
+
+struct mwl8k_skb {
+	/*
+	 * The DMA engine requires a modification to the payload.
+	 * If the skbuff is shared/cloned, it needs to be unshared.
+	 * This method is used to ensure the stack always gets back
+	 * the skbuff it sent for transmission.
+	 */
+	struct sk_buff *clone;
+	struct sk_buff *skb;
+};
+
+struct mwl8k_tx_queue {
+	/* hw transmits here */
+	int tx_head;
+
+	/* sw appends here */
+	int tx_tail;
+
+	struct ieee80211_tx_queue_stats tx_stats;
+	struct mwl8k_tx_desc *tx_desc_area;
+	dma_addr_t tx_desc_dma;
+	struct mwl8k_skb *tx_skb;
+};
+
+/* Pointers to the firmware data and meta information about it.  */
+struct mwl8k_firmware {
+	/* Microcode */
+	struct firmware *ucode;
+
+	/* Boot helper code */
+	struct firmware *helper;
+};
+
+struct mwl8k_priv {
+	void __iomem *regs;
+	struct ieee80211_hw *hw;
+
+	struct pci_dev *pdev;
+	u8 name[16];
+	/* firmware access lock */
+	spinlock_t fw_lock;
+
+	/* firmware files and meta data */
+	struct mwl8k_firmware fw;
+	u32 part_num;
+
+	/* lock held over TX and TX reap */
+	spinlock_t tx_lock;
+	u32 int_mask;
+
+	struct ieee80211_vif *vif;
+	struct list_head vif_list;
+
+	struct ieee80211_channel *current_channel;
+
+	/* power management status cookie from firmware */
+	u32 *cookie;
+	dma_addr_t cookie_dma;
+
+	u16 num_mcaddrs;
+	u16 region_code;
+	u8 hw_rev;
+	__le32 fw_rev;
+	u32 wep_enabled;
+
+	/*
+	 * Running count of TX packets in flight, to avoid
+	 * iterating over the transmit rings each time.
+	 */
+	int pending_tx_pkts;
+
+	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
+	struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
+
+	/* PHY parameters */
+	struct ieee80211_supported_band band;
+	struct ieee80211_channel channels[14];
+	struct ieee80211_rate rates[12];
+
+	/* RF preamble: Short, Long or Auto */
+	u8	radio_preamble;
+	u8	radio_state;
+
+	/* WMM MODE 1 for enabled; 0 for disabled */
+	bool wmm_mode;
+
+	/* Set if PHY config is in progress */
+	bool inconfig;
+
+	/* XXX need to convert this to handle multiple interfaces */
+	bool capture_beacon;
+	u8 capture_bssid[IEEE80211_ADDR_LEN];
+	struct sk_buff *beacon_skb;
+
+	/*
+	 * This FJ worker has to be global as it is scheduled from the
+	 * RX handler.  At this point we don't know which interface it
+	 * belongs to until the list of bssids waiting to complete join
+	 * is checked.
+	 */
+	struct work_struct finalize_join_worker;
+
+	/* 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;
+	struct completion *hostcmd_wait;
+	struct completion *tx_wait;
+};
+
+/* Per interface specific private data */
+struct mwl8k_vif {
+	struct list_head node;
+
+	/* backpointer to parent config block */
+	struct mwl8k_priv *priv;
+
+	/* BSS config of AP or IBSS from mac80211*/
+	struct ieee80211_bss_conf bss_info;
+
+	/* BSSID of AP or IBSS */
+	u8	bssid[IEEE80211_ADDR_LEN];
+	u8	mac_addr[IEEE80211_ADDR_LEN];
+
+	/*
+	 * 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;
+
+	/* Number of supported MCS rates. Work in progress */
+	u8	mcs_nrates;
+
+	 /* Index into station database.Returned by update_sta_db call */
+	u8	peer_id;
+
+	/* Non AMPDU sequence number assigned by driver */
+	u16	seqno;
+
+	/* Note:There is no channel info,
+	 * refer to the master channel info in priv
+	 */
+};
+
+#define MWL8K_VIF(_vif) (struct mwl8k_vif *)(&((_vif)->drv_priv))
+
+static const struct ieee80211_channel mwl8k_channels[] = {
+	{ .center_freq = 2412, .hw_value = 1, },
+	{ .center_freq = 2417, .hw_value = 2, },
+	{ .center_freq = 2422, .hw_value = 3, },
+	{ .center_freq = 2427, .hw_value = 4, },
+	{ .center_freq = 2432, .hw_value = 5, },
+	{ .center_freq = 2437, .hw_value = 6, },
+	{ .center_freq = 2442, .hw_value = 7, },
+	{ .center_freq = 2447, .hw_value = 8, },
+	{ .center_freq = 2452, .hw_value = 9, },
+	{ .center_freq = 2457, .hw_value = 10, },
+	{ .center_freq = 2462, .hw_value = 11, },
+};
+
+static const struct ieee80211_rate mwl8k_rates[] = {
+	{ .bitrate = 10, .hw_value = 2, },
+	{ .bitrate = 20, .hw_value = 4, },
+	{ .bitrate = 55, .hw_value = 11, },
+	{ .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, },
+};
+
+/* Radio settings */
+#define MWL8K_RADIO_FORCE		0x2
+#define MWL8K_RADIO_ENABLE		0x1
+#define MWL8K_RADIO_DISABLE		0x0
+#define MWL8K_RADIO_AUTO_PREAMBLE	0x0005
+#define MWL8K_RADIO_SHORT_PREAMBLE	0x0003
+#define MWL8K_RADIO_LONG_PREAMBLE	0x0001
+
+/* WMM */
+#define MWL8K_WMM_ENABLE		1
+#define MWL8K_WMM_DISABLE		0
+
+#define MWL8K_RADIO_DEFAULT_PREAMBLE	MWL8K_RADIO_LONG_PREAMBLE
+
+/* Slot time */
+
+/* Short Slot: 9us slot time */
+#define MWL8K_SHORT_SLOTTIME		1
+
+/* Long slot: 20us slot time */
+#define MWL8K_LONG_SLOTTIME		0
+
+/* Set or get info from Firmware */
+#define MWL8K_CMD_SET			0x0001
+#define MWL8K_CMD_GET			0x0000
+
+/* Firmware command codes */
+#define MWL8K_CMD_CODE_DNLD		0x0001
+#define MWL8K_CMD_GET_HW_SPEC		0x0003
+#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_SET_PRE_SCAN		0x0107
+#define MWL8K_CMD_SET_POST_SCAN		0x0108
+#define MWL8K_CMD_SET_RF_CHANNEL	0x010A
+#define MWL8K_CMD_SET_SLOT		0x0114
+#define MWL8K_CMD_MIMO_CONFIG		0x0125
+#define MWL8K_CMD_ENABLE_SNIFFER	0x0150
+#define MWL8K_CMD_SET_WMM_MODE		0x0123
+#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
+#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
+#define MWL8K_CMD_UPDATE_STADB		0x1123
+#define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
+#define MWL8K_CMD_SET_LINKADAPT_MODE	0x0129
+#define MWL8K_CMD_SET_AID		0x010d
+#define MWL8K_CMD_SET_RATE		0x0110
+#define MWL8K_CMD_USE_FIXED_RATE	0x0126
+#define MWL8K_CMD_RTS_THRESHOLD		0x0113
+#define MWL8K_CMD_ENCRYPTION		0x1122
+
+static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
+{
+#define MWL8K_CMDNAME(x)	case MWL8K_CMD_##x: do {\
+					snprintf(buf, bufsize, "%s", #x);\
+					return buf;\
+					} while (0)
+	switch (cmd & (~0x8000)) {
+		MWL8K_CMDNAME(CODE_DNLD);
+		MWL8K_CMDNAME(GET_HW_SPEC);
+		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
+		MWL8K_CMDNAME(GET_STAT);
+		MWL8K_CMDNAME(RADIO_CONTROL);
+		MWL8K_CMDNAME(RF_TX_POWER);
+		MWL8K_CMDNAME(SET_PRE_SCAN);
+		MWL8K_CMDNAME(SET_POST_SCAN);
+		MWL8K_CMDNAME(SET_RF_CHANNEL);
+		MWL8K_CMDNAME(SET_SLOT);
+		MWL8K_CMDNAME(MIMO_CONFIG);
+		MWL8K_CMDNAME(ENABLE_SNIFFER);
+		MWL8K_CMDNAME(SET_WMM_MODE);
+		MWL8K_CMDNAME(SET_EDCA_PARAMS);
+		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
+		MWL8K_CMDNAME(UPDATE_STADB);
+		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
+		MWL8K_CMDNAME(SET_LINKADAPT_MODE);
+		MWL8K_CMDNAME(SET_AID);
+		MWL8K_CMDNAME(SET_RATE);
+		MWL8K_CMDNAME(USE_FIXED_RATE);
+		MWL8K_CMDNAME(RTS_THRESHOLD);
+		MWL8K_CMDNAME(ENCRYPTION);
+	default:
+		snprintf(buf, bufsize, "0x%x", cmd);
+	}
+#undef MWL8K_CMDNAME
+
+	return buf;
+}
+
+/* Hardware and firmware reset */
+static void mwl8k_hw_reset(struct mwl8k_priv *priv)
+{
+	iowrite32(MWL8K_H2A_INT_RESET,
+		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	iowrite32(MWL8K_H2A_INT_RESET,
+		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	msleep(20);
+}
+
+/* Release fw image */
+static void mwl8k_release_fw(struct firmware **fw)
+{
+	if (*fw == NULL)
+		return;
+	release_firmware(*fw);
+	*fw = NULL;
+}
+
+static void mwl8k_release_firmware(struct mwl8k_priv *priv)
+{
+	mwl8k_release_fw(&priv->fw.ucode);
+	mwl8k_release_fw(&priv->fw.helper);
+}
+
+/* Request fw image */
+static int mwl8k_request_fw(struct mwl8k_priv *priv,
+				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);
+}
+
+static int mwl8k_reject_firmware(struct mwl8k_priv *priv, u32 part_num)
+{
+	u8 filename[64];
+	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;
+	}
+
+	snprintf(filename, sizeof(filename),
+		 "/*(DEBLOBBED)*/", priv->part_num);
+
+	rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
+	if (rc) {
+		printk(KERN_ERR "%s Error requesting firmware file %s\n",
+					pci_name(priv->pdev), filename);
+		mwl8k_release_fw(&priv->fw.helper);
+		return rc;
+	}
+
+	return 0;
+}
+
+struct mwl8k_cmd_pkt {
+	__le16	code;
+	__le16	length;
+	__le16	seq_num;
+	__le16	result;
+	char	payload[0];
+} __attribute__((packed));
+
+/*
+ * Firmware loading.
+ */
+static int
+mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
+{
+	void __iomem *regs = priv->regs;
+	dma_addr_t dma_addr;
+	int rc;
+	int loops;
+
+	dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(priv->pdev, dma_addr))
+		return -ENOMEM;
+
+	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+	iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+	iowrite32(MWL8K_H2A_INT_DOORBELL,
+		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	iowrite32(MWL8K_H2A_INT_DUMMY,
+		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+
+	rc = -ETIMEDOUT;
+	loops = 1000;
+	do {
+		u32 int_code;
+
+		int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
+		if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
+			iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+			rc = 0;
+			break;
+		}
+
+		udelay(1);
+	} while (--loops);
+
+	pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
+
+	/*
+	 * Clear 'command done' interrupt bit.
+	 */
+	loops = 1000;
+	do {
+		u32 status;
+
+		status = ioread32(priv->regs +
+				MWL8K_HIU_A2H_INTERRUPT_STATUS);
+		if (status & MWL8K_A2H_INT_OPC_DONE) {
+			iowrite32(~MWL8K_A2H_INT_OPC_DONE,
+				priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+			ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+			break;
+		}
+
+		udelay(1);
+	} while (--loops);
+
+	return rc;
+}
+
+static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
+				const u8 *data, size_t length)
+{
+	struct mwl8k_cmd_pkt *cmd;
+	int done;
+	int rc = 0;
+
+	cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
+	cmd->seq_num = 0;
+	cmd->result = 0;
+
+	done = 0;
+	while (length) {
+		int block_size = length > 256 ? 256 : length;
+
+		memcpy(cmd->payload, data + done, block_size);
+		cmd->length = cpu_to_le16(block_size);
+
+		rc = mwl8k_send_fw_load_cmd(priv, cmd,
+						sizeof(*cmd) + block_size);
+		if (rc)
+			break;
+
+		done += block_size;
+		length -= block_size;
+	}
+
+	if (!rc) {
+		cmd->length = 0;
+		rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
+	}
+
+	kfree(cmd);
+
+	return rc;
+}
+
+static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
+				const u8 *data, size_t length)
+{
+	unsigned char *buffer;
+	int may_continue, rc = 0;
+	u32 done, prev_block_size;
+
+	buffer = kmalloc(1024, GFP_KERNEL);
+	if (buffer == NULL)
+		return -ENOMEM;
+
+	done = 0;
+	prev_block_size = 0;
+	may_continue = 1000;
+	while (may_continue > 0) {
+		u32 block_size;
+
+		block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
+		if (block_size & 1) {
+			block_size &= ~1;
+			may_continue--;
+		} else {
+			done += prev_block_size;
+			length -= prev_block_size;
+		}
+
+		if (block_size > 1024 || block_size > length) {
+			rc = -EOVERFLOW;
+			break;
+		}
+
+		if (length == 0) {
+			rc = 0;
+			break;
+		}
+
+		if (block_size == 0) {
+			rc = -EPROTO;
+			may_continue--;
+			udelay(1);
+			continue;
+		}
+
+		prev_block_size = block_size;
+		memcpy(buffer, data + done, block_size);
+
+		rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
+		if (rc)
+			break;
+	}
+
+	if (!rc && length != 0)
+		rc = -EREMOTEIO;
+
+	kfree(buffer);
+
+	return rc;
+}
+
+static int mwl8k_load_firmware(struct mwl8k_priv *priv)
+{
+	int loops, rc;
+
+	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(ucode, "\x01\x00\x00\x00", 4)) {
+		rc = mwl8k_load_fw_image(priv, helper, helper_len);
+		if (rc) {
+			printk(KERN_ERR "%s: unable to load firmware "
+				"helper image\n", pci_name(priv->pdev));
+			return rc;
+		}
+		msleep(1);
+
+		rc = mwl8k_feed_fw_image(priv, ucode, ucode_len);
+	} else {
+		rc = mwl8k_load_fw_image(priv, ucode, ucode_len);
+	}
+
+	if (rc) {
+		printk(KERN_ERR "%s: unable to load firmware data\n",
+			pci_name(priv->pdev));
+		return rc;
+	}
+
+	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
+	msleep(1);
+
+	loops = 200000;
+	do {
+		if (ioread32(priv->regs + MWL8K_HIU_INT_CODE)
+						== MWL8K_FWSTA_READY)
+			break;
+		udelay(1);
+	} while (--loops);
+
+	return loops ? 0 : -ETIMEDOUT;
+}
+
+
+/*
+ * Defines shared between transmission and reception.
+ */
+/* HT control fields for firmware */
+struct ewc_ht_info {
+	__le16	control1;
+	__le16	control2;
+	__le16	control3;
+} __attribute__((packed));
+
+/* Firmware Station database operations */
+#define MWL8K_STA_DB_ADD_ENTRY		0
+#define MWL8K_STA_DB_MODIFY_ENTRY	1
+#define MWL8K_STA_DB_DEL_ENTRY		2
+#define MWL8K_STA_DB_FLUSH		3
+
+/* Peer Entry flags - used to define the type of the peer node */
+#define MWL8K_PEER_TYPE_ACCESSPOINT	2
+#define MWL8K_PEER_TYPE_ADHOC_STATION	4
+
+#define MWL8K_IEEE_LEGACY_DATA_RATES	12
+#define MWL8K_MCS_BITMAP_SIZE		16
+#define pad_size			16
+
+struct peer_capability_info {
+	/* Peer type - AP vs. STA.  */
+	__u8	peer_type;
+
+	/* Basic 802.11 capabilities from assoc resp.  */
+	__le16	basic_caps;
+
+	/* Set if peer supports 802.11n high throughput (HT).  */
+	__u8	ht_support;
+
+	/* Valid if HT is supported.  */
+	__le16	ht_caps;
+	__u8	extended_ht_caps;
+	struct ewc_ht_info	ewc_info;
+
+	/* Legacy rate table. Intersection of our rates and peer rates.  */
+	__u8	legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES];
+
+	/* HT rate table. Intersection of our rates and peer rates.  */
+	__u8	ht_rates[MWL8K_MCS_BITMAP_SIZE];
+	__u8	pad[pad_size];
+
+	/* If set, interoperability mode, no proprietary extensions.  */
+	__u8	interop;
+	__u8	pad2;
+	__u8	station_id;
+	__le16	amsdu_enabled;
+} __attribute__((packed));
+
+/* Inline functions to manipulate QoS field in data descriptor.  */
+static inline u16 mwl8k_qos_setbit_tid(u16 qos, u8 tid)
+{
+	u16 val_mask = 0x000f;
+	u16 qos_mask = ~val_mask;
+
+	/* TID bits 0-3 */
+	return (qos & qos_mask) | (tid & val_mask);
+}
+
+static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
+{
+	u16 val_mask = 1 << 4;
+
+	/* End of Service Period Bit 4 */
+	return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy)
+{
+	u16 val_mask = 0x3;
+	u8	shift = 5;
+	u16 qos_mask = ~(val_mask << shift);
+
+	/* Ack Policy Bit 5-6 */
+	return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
+}
+
+static inline u16 mwl8k_qos_setbit_amsdu(u16 qos)
+{
+	u16 val_mask = 1 << 7;
+
+	/* AMSDU present Bit 7 */
+	return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len)
+{
+	u16 val_mask = 0xff;
+	u8	shift = 8;
+	u16 qos_mask = ~(val_mask << shift);
+
+	/* Queue Length Bits 8-15 */
+	return (qos & qos_mask) | ((len & val_mask) << shift);
+}
+
+/* DMA header used by firmware and hardware.  */
+struct mwl8k_dma_data {
+	__le16 fwlen;
+	struct ieee80211_hdr wh;
+} __attribute__((packed));
+
+/* Routines to add/remove DMA header from skb.  */
+static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
+{
+	struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data);
+	void *dst, *src = &tr->wh;
+	__le16 fc = tr->wh.frame_control;
+	int hdrlen = ieee80211_hdrlen(fc);
+	u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
+
+	dst = (void *)tr + space;
+	if (dst != src) {
+		memmove(dst, src, hdrlen);
+		skb_pull(skb, space);
+	}
+
+	return 0;
+}
+
+static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *wh;
+	u32 hdrlen, pktlen;
+	struct mwl8k_dma_data *tr;
+
+	wh = (struct ieee80211_hdr *)skb->data;
+	hdrlen = ieee80211_hdrlen(wh->frame_control);
+	pktlen = skb->len;
+
+	/*
+	 * 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);
+
+	tr = (struct mwl8k_dma_data *)skb->data;
+	if (wh != &tr->wh)
+		memmove(&tr->wh, wh, hdrlen);
+
+	/* Clear addr4 */
+	memset(tr->wh.addr4, 0, IEEE80211_ADDR_LEN);
+
+	/*
+	 * 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);
+
+	return skb;
+}
+
+
+/*
+ * Packet reception.
+ */
+#define MWL8K_RX_CTRL_KEY_INDEX_MASK	0x30
+#define MWL8K_RX_CTRL_OWNED_BY_HOST	0x02
+#define MWL8K_RX_CTRL_AMPDU		0x01
+
+struct mwl8k_rx_desc {
+	__le16 pkt_len;
+	__u8 link_quality;
+	__u8 noise_level;
+	__le32 pkt_phys_addr;
+	__le32 next_rx_desc_phys_addr;
+	__le16 qos_control;
+	__le16 rate_info;
+	__le32 pad0[4];
+	__u8 rssi;
+	__u8 channel;
+	__le16 pad1;
+	__u8 rx_ctrl;
+	__u8 rx_status;
+	__u8 pad2[2];
+} __attribute__((packed));
+
+#define MWL8K_RX_DESCS		256
+#define MWL8K_RX_MAXSZ		3800
+
+static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_rx_queue *rxq = priv->rxq + index;
+	int size;
+	int i;
+
+	rxq->rx_desc_count = 0;
+	rxq->rx_head = 0;
+	rxq->rx_tail = 0;
+
+	size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc);
+
+	rxq->rx_desc_area =
+		pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma);
+	if (rxq->rx_desc_area == NULL) {
+		printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
+		       priv->name);
+		return -ENOMEM;
+	}
+	memset(rxq->rx_desc_area, 0, size);
+
+	rxq->rx_skb = kmalloc(MWL8K_RX_DESCS *
+				sizeof(*rxq->rx_skb), GFP_KERNEL);
+	if (rxq->rx_skb == 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);
+		return -ENOMEM;
+	}
+	memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb));
+
+	for (i = 0; i < MWL8K_RX_DESCS; i++) {
+		struct mwl8k_rx_desc *rx_desc;
+		int nexti;
+
+		rx_desc = rxq->rx_desc_area + i;
+		nexti = (i + 1) % MWL8K_RX_DESCS;
+
+		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;
+	}
+
+	return 0;
+}
+
+static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_rx_queue *rxq = priv->rxq + index;
+	int refilled;
+
+	refilled = 0;
+	while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) {
+		struct sk_buff *skb;
+		int rx;
+
+		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;
+
+		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->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;
+
+		refilled++;
+	}
+
+	return refilled;
+}
+
+/* Must be called only when the card's reception is completely halted */
+static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_rx_queue *rxq = priv->rxq + index;
+	int i;
+
+	for (i = 0; i < MWL8K_RX_DESCS; i++) {
+		if (rxq->rx_skb[i] != NULL) {
+			unsigned long addr;
+
+			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(rxq->rx_skb);
+	rxq->rx_skb = 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;
+}
+
+
+/*
+ * Scan a list of BSSIDs to process for finalize join.
+ * Allows for extension to process multiple BSSIDs.
+ */
+static inline int
+mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
+{
+	return priv->capture_beacon &&
+		ieee80211_is_beacon(wh->frame_control) &&
+		!compare_ether_addr(wh->addr3, priv->capture_bssid);
+}
+
+static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
+							struct sk_buff *skb)
+{
+	priv->capture_beacon = false;
+	memset(priv->capture_bssid, 0, IEEE80211_ADDR_LEN);
+
+	/*
+	 * Use GFP_ATOMIC as rxq_process is called from
+	 * the primary interrupt handler, memory allocation call
+	 * must not sleep.
+	 */
+	priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
+	if (priv->beacon_skb != NULL)
+		queue_work(priv->config_wq,
+				&priv->finalize_join_worker);
+}
+
+static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_rx_queue *rxq = priv->rxq + index;
+	int processed;
+
+	processed = 0;
+	while (rxq->rx_desc_count && limit--) {
+		struct mwl8k_rx_desc *rx_desc;
+		struct sk_buff *skb;
+		struct ieee80211_rx_status status;
+		unsigned long addr;
+		struct ieee80211_hdr *wh;
+
+		rx_desc = rxq->rx_desc_area + rxq->rx_head;
+		if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST))
+			break;
+		rmb();
+
+		skb = rxq->rx_skb[rxq->rx_head];
+		rxq->rx_skb[rxq->rx_head] = NULL;
+
+		rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
+		rxq->rx_desc_count--;
+
+		addr = le32_to_cpu(rx_desc->pkt_phys_addr);
+		pci_unmap_single(priv->pdev, addr,
+					MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+
+		skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
+		if (mwl8k_remove_dma_header(skb)) {
+			dev_kfree_skb(skb);
+			continue;
+		}
+
+		wh = (struct ieee80211_hdr *)skb->data;
+
+		/*
+		 * Check for pending join operation. save a copy of
+		 * the beacon and schedule a tasklet to send finalize
+		 * join command to the firmware.
+		 */
+		if (mwl8k_capture_bssid(priv, wh))
+			mwl8k_save_beacon(priv, 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);
+		ieee80211_rx_irqsafe(hw, skb, &status);
+
+		processed++;
+	}
+
+	return processed;
+}
+
+
+/*
+ * 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_NONE		1
+#define MWL8K_TXD_ACK_POLICY_NO_EXPLICIT	2
+#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_IDLE			0x00000000
+#define MWL8K_TXD_STATUS_USED			0x00000001
+#define MWL8K_TXD_STATUS_OK			0x00000001
+#define MWL8K_TXD_STATUS_OK_RETRY		0x00000002
+#define MWL8K_TXD_STATUS_OK_MORE_RETRY		0x00000004
+#define MWL8K_TXD_STATUS_MULTICAST_TX		0x00000008
+#define MWL8K_TXD_STATUS_BROADCAST_TX		0x00000010
+#define MWL8K_TXD_STATUS_FAILED_LINK_ERROR	0x00000020
+#define MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT	0x00000040
+#define MWL8K_TXD_STATUS_FAILED_AGING		0x00000080
+#define MWL8K_TXD_STATUS_HOST_CMD		0x40000000
+#define MWL8K_TXD_STATUS_FW_OWNED		0x80000000
+#define  MWL8K_TXD_SOFTSTALE				0x80
+#define  MWL8K_TXD_SOFTSTALE_MGMT_RETRY			0x01
+
+struct mwl8k_tx_desc {
+	__le32 status;
+	__u8 data_rate;
+	__u8 tx_priority;
+	__le16 qos_control;
+	__le32 pkt_phys_addr;
+	__le16 pkt_len;
+	__u8 dest_MAC_addr[IEEE80211_ADDR_LEN];
+	__le32 next_tx_desc_phys_addr;
+	__le32 reserved;
+	__le16 rate_info;
+	__u8 peer_id;
+	__u8 tx_frag_cnt;
+} __attribute__((packed));
+
+#define MWL8K_TX_DESCS		128
+
+static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_tx_queue *txq = priv->txq + index;
+	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;
+
+	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) {
+		printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
+		       priv->name);
+		return -ENOMEM;
+	}
+	memset(txq->tx_desc_area, 0, size);
+
+	txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb),
+								GFP_KERNEL);
+	if (txq->tx_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);
+		return -ENOMEM;
+	}
+	memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb));
+
+	for (i = 0; i < MWL8K_TX_DESCS; i++) {
+		struct mwl8k_tx_desc *tx_desc;
+		int nexti;
+
+		tx_desc = txq->tx_desc_area + 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));
+	}
+
+	return 0;
+}
+
+static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
+{
+	iowrite32(MWL8K_H2A_INT_PPA_READY,
+		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	iowrite32(MWL8K_H2A_INT_DUMMY,
+		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	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[],
+				u32 num_queues)
+{
+	int count, desc, status;
+	struct mwl8k_tx_queue *txq;
+	struct mwl8k_tx_desc *tx_desc;
+	int ndescs = 0;
+
+	memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info));
+	spin_lock_bh(&priv->tx_lock);
+	for (count = 0; count < num_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);
+
+			if (status & MWL8K_TXD_STATUS_FW_OWNED)
+				txinfo[count].fw_owned++;
+			else
+				txinfo[count].drv_owned++;
+
+			if (tx_desc->pkt_len == 0)
+				txinfo[count].unused++;
+		}
+	}
+	spin_unlock_bh(&priv->tx_lock);
+
+	return ndescs;
+}
+
+static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
+{
+	u32 count = 0;
+	unsigned long timeout = 0;
+	struct mwl8k_priv *priv = hw->priv;
+	DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+	might_sleep();
+
+	if (priv->tx_wait != NULL)
+		printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
+
+	spin_lock_bh(&priv->tx_lock);
+	count = mwl8k_txq_busy(priv);
+	if (count) {
+		priv->tx_wait = &cmd_wait;
+		if (priv->radio_state)
+			mwl8k_tx_start(priv);
+	}
+	spin_unlock_bh(&priv->tx_lock);
+
+	if (count) {
+		struct mwl8k_txq_info txinfo[4];
+		int index;
+		int newcount;
+
+		timeout = wait_for_completion_timeout(&cmd_wait,
+					msecs_to_jiffies(delay_ms));
+		if (timeout)
+			return 0;
+
+		spin_lock_bh(&priv->tx_lock);
+		priv->tx_wait = NULL;
+		newcount = mwl8k_txq_busy(priv);
+		spin_unlock_bh(&priv->tx_lock);
+
+		printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n",
+		       __func__, __LINE__, delay_ms, count, newcount);
+
+		mwl8k_scan_tx_ring(priv, txinfo, 4);
+		for (index = 0 ; index < 4; 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);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+#define MWL8K_TXD_OK	(MWL8K_TXD_STATUS_OK | \
+			 MWL8K_TXD_STATUS_OK_RETRY | \
+			 MWL8K_TXD_STATUS_OK_MORE_RETRY)
+#define MWL8K_TXD_SUCCESS(stat)		((stat) & MWL8K_TXD_OK)
+#define MWL8K_TXD_FAIL_RETRY(stat)	\
+	((stat) & (MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT))
+
+static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_tx_queue *txq = priv->txq + index;
+	int wake = 0;
+
+	while (txq->tx_stats.len > 0) {
+		int tx;
+		int rc;
+		struct mwl8k_tx_desc *tx_desc;
+		unsigned long addr;
+		size_t size;
+		struct sk_buff *skb;
+		struct ieee80211_tx_info *info;
+		u32 status;
+
+		rc = 0;
+		tx = txq->tx_head;
+		tx_desc = txq->tx_desc_area + tx;
+
+		status = le32_to_cpu(tx_desc->status);
+
+		if (status & MWL8K_TXD_STATUS_FW_OWNED) {
+			if (!force)
+				break;
+			tx_desc->status &=
+				~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--;
+		priv->pending_tx_pkts--;
+
+		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
+		size = (u32)(le16_to_cpu(tx_desc->pkt_len));
+		skb = txq->tx_skb[tx].skb;
+		txq->tx_skb[tx].skb = NULL;
+
+		BUG_ON(skb == NULL);
+		pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
+
+		rc = mwl8k_remove_dma_header(skb);
+
+		/* Mark descriptor as unused */
+		tx_desc->pkt_phys_addr = 0;
+		tx_desc->pkt_len = 0;
+
+		if (txq->tx_skb[tx].clone) {
+			/* Replace with original skb
+			 * before returning to stack
+			 * as buffer has been cloned
+			 */
+			dev_kfree_skb(skb);
+			skb = txq->tx_skb[tx].clone;
+			txq->tx_skb[tx].clone = NULL;
+		}
+
+		if (rc) {
+			/* Something has gone wrong here.
+			 * Failed to remove DMA header.
+			 * Print error message and drop packet.
+			 */
+			printk(KERN_ERR "%s: Error removing DMA header from "
+					"tx skb 0x%p.\n", priv->name, skb);
+
+			dev_kfree_skb(skb);
+			continue;
+		}
+
+		info = IEEE80211_SKB_CB(skb);
+		ieee80211_tx_info_clear_status(info);
+
+		/* Convert firmware status stuff into tx_status */
+		if (MWL8K_TXD_SUCCESS(status)) {
+			/* Transmit OK */
+			info->flags |= IEEE80211_TX_STAT_ACK;
+		}
+
+		ieee80211_tx_status_irqsafe(hw, skb);
+
+		wake = !priv->inconfig && priv->radio_state;
+	}
+
+	if (wake)
+		ieee80211_wake_queue(hw, index);
+}
+
+/* must be called only when the card's transmit is completely halted */
+static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_tx_queue *txq = priv->txq + index;
+
+	mwl8k_txq_reclaim(hw, index, 1);
+
+	kfree(txq->tx_skb);
+	txq->tx_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;
+}
+
+static int
+mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct ieee80211_tx_info *tx_info;
+	struct ieee80211_hdr *wh;
+	struct mwl8k_tx_queue *txq;
+	struct mwl8k_tx_desc *tx;
+	struct mwl8k_dma_data *tr;
+	struct mwl8k_vif *mwl8k_vif;
+	struct sk_buff *org_skb = skb;
+	dma_addr_t dma;
+	u16 qos = 0;
+	bool qosframe = false, ampduframe = false;
+	bool mcframe = false, eapolframe = false;
+	bool amsduframe = false;
+	__le16 fc;
+
+	txq = priv->txq + index;
+	tx = txq->tx_desc_area + txq->tx_tail;
+
+	BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL);
+
+	/*
+	 * Append HW DMA header to start of packet.  Drop packet if
+	 * there is not enough space or a failure to unshare/unclone
+	 * the skb.
+	 */
+	skb = mwl8k_add_dma_header(skb);
+
+	if (skb == NULL) {
+		printk(KERN_DEBUG "%s: failed to prepend HW DMA "
+			"header, dropping TX frame.\n", priv->name);
+		dev_kfree_skb(org_skb);
+		return NETDEV_TX_OK;
+	}
+
+	tx_info = IEEE80211_SKB_CB(skb);
+	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
+	tr = (struct mwl8k_dma_data *)skb->data;
+	wh = &tr->wh;
+	fc = wh->frame_control;
+	qosframe = ieee80211_is_data_qos(fc);
+	mcframe = is_multicast_ether_addr(wh->addr1);
+	ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+
+	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+		u16 seqno = mwl8k_vif->seqno;
+		wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+		wh->seq_ctrl |= cpu_to_le16(seqno << 4);
+		mwl8k_vif->seqno = seqno++ % 4096;
+	}
+
+	if (qosframe)
+		qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
+
+	dma = pci_map_single(priv->pdev, skb->data,
+				skb->len, PCI_DMA_TODEVICE);
+
+	if (pci_dma_mapping_error(priv->pdev, dma)) {
+		printk(KERN_DEBUG "%s: failed to dma map skb, "
+			"dropping TX frame.\n", priv->name);
+
+		if (org_skb != NULL)
+			dev_kfree_skb(org_skb);
+		if (skb != NULL)
+			dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	/* Set desc header, cpu bit order.  */
+	tx->status = 0;
+	tx->data_rate = 0;
+	tx->tx_priority = index;
+	tx->qos_control = 0;
+	tx->rate_info = 0;
+	tx->peer_id = mwl8k_vif->peer_id;
+
+	amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
+
+	/* Setup firmware control bit fields for each frame type.  */
+	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
+		tx->data_rate = 0;
+		qos = mwl8k_qos_setbit_eosp(qos);
+		/* Set Queue size to unspecified */
+		qos = mwl8k_qos_setbit_qlen(qos, 0xff);
+	} else if (ieee80211_is_data(fc)) {
+		tx->data_rate = 1;
+		if (mcframe)
+			tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
+
+		/*
+		 * Tell firmware to not send EAPOL pkts in an
+		 * aggregate.  Verify against mac80211 tx path.  If
+		 * stack turns off AMPDU for an EAPOL frame this
+		 * check will be removed.
+		 */
+		if (eapolframe) {
+			qos = mwl8k_qos_setbit_ack(qos,
+				MWL8K_TXD_ACK_POLICY_NORMAL);
+		} else {
+			/* Send pkt in an aggregate if AMPDU frame.  */
+			if (ampduframe)
+				qos = mwl8k_qos_setbit_ack(qos,
+					MWL8K_TXD_ACK_POLICY_BLOCKACK);
+			else
+				qos = mwl8k_qos_setbit_ack(qos,
+					MWL8K_TXD_ACK_POLICY_NORMAL);
+
+			if (amsduframe)
+				qos = mwl8k_qos_setbit_amsdu(qos);
+		}
+	}
+
+	/* Convert to little endian */
+	tx->qos_control = cpu_to_le16(qos);
+	tx->status = cpu_to_le32(tx->status);
+	tx->pkt_phys_addr = cpu_to_le32(dma);
+	tx->pkt_len = cpu_to_le16(skb->len);
+
+	txq->tx_skb[txq->tx_tail].skb = skb;
+	txq->tx_skb[txq->tx_tail].clone =
+		skb == org_skb ? NULL : org_skb;
+
+	spin_lock_bh(&priv->tx_lock);
+
+	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
+					MWL8K_TXD_STATUS_FW_OWNED);
+	wmb();
+	txq->tx_stats.len++;
+	priv->pending_tx_pkts++;
+	txq->tx_stats.count++;
+	txq->tx_tail++;
+
+	if (txq->tx_tail == MWL8K_TX_DESCS)
+		txq->tx_tail = 0;
+	if (txq->tx_head == txq->tx_tail)
+		ieee80211_stop_queue(hw, index);
+
+	if (priv->inconfig) {
+		/*
+		 * Silently queue packet when we are in the middle of
+		 * a config cycle.  Notify firmware only if we are
+		 * waiting for TXQs to empty.  If a packet is sent
+		 * before .config() is complete, perhaps it is better
+		 * to drop the packet, as the channel is being changed
+		 * and the packet will end up on the wrong channel.
+		 */
+		printk(KERN_ERR "%s(): WARNING TX activity while "
+			"in config\n", __func__);
+
+		if (priv->tx_wait != NULL)
+			mwl8k_tx_start(priv);
+	} else
+		mwl8k_tx_start(priv);
+
+	spin_unlock_bh(&priv->tx_lock);
+
+	return NETDEV_TX_OK;
+}
+
+
+/*
+ * Command processing.
+ */
+
+/* Timeout firmware commands after 2000ms */
+#define MWL8K_CMD_TIMEOUT_MS	2000
+
+static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
+{
+	DECLARE_COMPLETION_ONSTACK(cmd_wait);
+	struct mwl8k_priv *priv = hw->priv;
+	void __iomem *regs = priv->regs;
+	dma_addr_t dma_addr;
+	unsigned int dma_size;
+	int rc;
+	u16 __iomem *result;
+	unsigned long timeout = 0;
+	u8 buf[32];
+
+	cmd->result = 0xFFFF;
+	dma_size = le16_to_cpu(cmd->length);
+	dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
+				  PCI_DMA_BIDIRECTIONAL);
+	if (pci_dma_mapping_error(priv->pdev, dma_addr))
+		return -ENOMEM;
+
+	if (priv->hostcmd_wait != NULL)
+		printk(KERN_ERR "WARNING host command in progress\n");
+
+	spin_lock_irq(&priv->fw_lock);
+	priv->hostcmd_wait = &cmd_wait;
+	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+	iowrite32(MWL8K_H2A_INT_DOORBELL,
+		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	iowrite32(MWL8K_H2A_INT_DUMMY,
+		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+	spin_unlock_irq(&priv->fw_lock);
+
+	timeout = wait_for_completion_timeout(&cmd_wait,
+				msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
+
+	result = &cmd->result;
+	if (!timeout) {
+		spin_lock_irq(&priv->fw_lock);
+		priv->hostcmd_wait = NULL;
+		spin_unlock_irq(&priv->fw_lock);
+		printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
+		       priv->name,
+		       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+		       MWL8K_CMD_TIMEOUT_MS);
+		rc = -ETIMEDOUT;
+	} else {
+		rc = *result ? -EINVAL : 0;
+		if (rc)
+			printk(KERN_ERR "%s: Command %s error 0x%x\n",
+			       priv->name,
+			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+			       *result);
+	}
+
+	pci_unmap_single(priv->pdev, dma_addr, dma_size,
+					PCI_DMA_BIDIRECTIONAL);
+	return rc;
+}
+
+/*
+ * GET_HW_SPEC.
+ */
+struct mwl8k_cmd_get_hw_spec {
+	struct mwl8k_cmd_pkt header;
+	__u8 hw_rev;
+	__u8 host_interface;
+	__le16 num_mcaddrs;
+	__u8 perm_addr[IEEE80211_ADDR_LEN];
+	__le16 region_code;
+	__le32 fw_rev;
+	__le32 ps_cookie;
+	__le32 caps;
+	__u8 mcs_bitmap[16];
+	__le32 rx_queue_ptr;
+	__le32 num_tx_queues;
+	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+	__le32 caps2;
+	__le32 num_tx_desc_per_queue;
+	__le32 total_rx_desc;
+} __attribute__((packed));
+
+static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_get_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_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);
+	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
+	cmd->num_tx_queues = 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->num_tx_desc_per_queue = MWL8K_TX_DESCS;
+	cmd->total_rx_desc = 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 = cmd->fw_rev;
+		priv->hw_rev = cmd->hw_rev;
+		priv->region_code = le16_to_cpu(cmd->region_code);
+	}
+
+	kfree(cmd);
+	return rc;
+}
+
+/*
+ * CMD_MAC_MULTICAST_ADR.
+ */
+struct mwl8k_cmd_mac_multicast_adr {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 numaddr;
+	__u8 addr[1][IEEE80211_ADDR_LEN];
+};
+
+#define MWL8K_ENABLE_RX_MULTICAST 0x000F
+static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+					int mc_count,
+					struct dev_addr_list *mclist)
+{
+	struct mwl8k_cmd_mac_multicast_adr *cmd;
+	int index = 0;
+	int rc;
+	int size = sizeof(*cmd) + ((mc_count - 1) * IEEE80211_ADDR_LEN);
+	cmd = kzalloc(size, GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	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);
+	while ((index < mc_count) && mclist) {
+		if (mclist->da_addrlen != IEEE80211_ADDR_LEN) {
+			rc = -EINVAL;
+			goto mwl8k_cmd_mac_multicast_adr_exit;
+		}
+		memcpy(cmd->addr[index], mclist->da_addr, IEEE80211_ADDR_LEN);
+		index++;
+		mclist = mclist->next;
+	}
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+
+mwl8k_cmd_mac_multicast_adr_exit:
+	kfree(cmd);
+	return rc;
+}
+
+/*
+ * CMD_802_11_GET_STAT.
+ */
+struct mwl8k_cmd_802_11_get_stat {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le32 stats[64];
+} __attribute__((packed));
+
+#define MWL8K_STAT_ACK_FAILURE	9
+#define MWL8K_STAT_RTS_FAILURE	12
+#define MWL8K_STAT_FCS_ERROR	24
+#define MWL8K_STAT_RTS_SUCCESS	11
+
+static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
+				struct ieee80211_low_level_stats *stats)
+{
+	struct mwl8k_cmd_802_11_get_stat *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	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) {
+		stats->dot11ACKFailureCount =
+			le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
+		stats->dot11RTSFailureCount =
+			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
+		stats->dot11FCSErrorCount =
+			le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
+		stats->dot11RTSSuccessCount =
+			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
+	}
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_802_11_RADIO_CONTROL.
+ */
+struct mwl8k_cmd_802_11_radio_control {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 control;
+	__le16 radio_on;
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_802_11_radio_control *cmd;
+	int rc;
+
+	if (((enable & MWL8K_RADIO_ENABLE) == priv->radio_state) &&
+	    !(enable & MWL8K_RADIO_FORCE))
+		return 0;
+
+	enable &= MWL8K_RADIO_ENABLE;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->control = cpu_to_le16(priv->radio_preamble);
+	cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	if (!rc)
+		priv->radio_state = enable;
+
+	return rc;
+}
+
+static int
+mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
+{
+	struct mwl8k_priv *priv;
+
+	if (hw == NULL || hw->priv == NULL)
+		return -EINVAL;
+	priv = hw->priv;
+
+	priv->radio_preamble = (short_preamble ?
+		MWL8K_RADIO_SHORT_PREAMBLE :
+		MWL8K_RADIO_LONG_PREAMBLE);
+
+	return mwl8k_cmd_802_11_radio_control(hw,
+			MWL8K_RADIO_ENABLE | MWL8K_RADIO_FORCE);
+}
+
+/*
+ * CMD_802_11_RF_TX_POWER.
+ */
+#define MWL8K_TX_POWER_LEVEL_TOTAL	8
+
+struct mwl8k_cmd_802_11_rf_tx_power {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 support_level;
+	__le16 current_level;
+	__le16 reserved;
+	__le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
+{
+	struct mwl8k_cmd_802_11_rf_tx_power *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->support_level = cpu_to_le16(dBm);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_PRE_SCAN.
+ */
+struct mwl8k_cmd_set_pre_scan {
+	struct mwl8k_cmd_pkt header;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
+{
+	struct mwl8k_cmd_set_pre_scan *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_POST_SCAN.
+ */
+struct mwl8k_cmd_set_post_scan {
+	struct mwl8k_cmd_pkt header;
+	__le32 isibss;
+	__u8 bssid[IEEE80211_ADDR_LEN];
+} __attribute__((packed));
+
+static int
+mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
+{
+	struct mwl8k_cmd_set_post_scan *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->isibss = 0;
+	memcpy(cmd->bssid, mac, IEEE80211_ADDR_LEN);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_RF_CHANNEL.
+ */
+struct mwl8k_cmd_set_rf_channel {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__u8 current_channel;
+	__le32 channel_flags;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
+				    struct ieee80211_channel *channel)
+{
+	struct mwl8k_cmd_set_rf_channel *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->current_channel = channel->hw_value;
+	if (channel->band == IEEE80211_BAND_2GHZ)
+		cmd->channel_flags = cpu_to_le32(0x00000081);
+	else
+		cmd->channel_flags = cpu_to_le32(0x00000000);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_SLOT.
+ */
+struct mwl8k_cmd_set_slot {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__u8 short_slot;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
+{
+	struct mwl8k_cmd_set_slot *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->short_slot = slot_time == MWL8K_SHORT_SLOTTIME ? 1 : 0;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_MIMO_CONFIG.
+ */
+struct mwl8k_cmd_mimo_config {
+	struct mwl8k_cmd_pkt header;
+	__le32 action;
+	__u8 rx_antenna_map;
+	__u8 tx_antenna_map;
+} __attribute__((packed));
+
+static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
+{
+	struct mwl8k_cmd_mimo_config *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
+	cmd->rx_antenna_map = rx;
+	cmd->tx_antenna_map = tx;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_ENABLE_SNIFFER.
+ */
+struct mwl8k_cmd_enable_sniffer {
+	struct mwl8k_cmd_pkt header;
+	__le32 action;
+} __attribute__((packed));
+
+static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
+{
+	struct mwl8k_cmd_enable_sniffer *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = enable ? cpu_to_le32((u32)MWL8K_CMD_SET) : 0;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_RATE_ADAPT_MODE.
+ */
+struct mwl8k_cmd_set_rate_adapt_mode {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 mode;
+} __attribute__((packed));
+
+static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
+{
+	struct mwl8k_cmd_set_rate_adapt_mode *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+	cmd->mode = cpu_to_le16(mode);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_WMM_MODE.
+ */
+struct mwl8k_cmd_set_wmm {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+} __attribute__((packed));
+
+static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_set_wmm *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = enable ? cpu_to_le16(MWL8K_CMD_SET) : 0;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	if (!rc)
+		priv->wmm_mode = enable;
+
+	return rc;
+}
+
+/*
+ * CMD_SET_RTS_THRESHOLD.
+ */
+struct mwl8k_cmd_rts_threshold {
+	struct mwl8k_cmd_pkt header;
+	__le16 action;
+	__le16 threshold;
+} __attribute__((packed));
+
+static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
+			       u16 action, u16 *threshold)
+{
+	struct mwl8k_cmd_rts_threshold *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le16(action);
+	cmd->threshold = cpu_to_le16(*threshold);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_EDCA_PARAMS.
+ */
+struct mwl8k_cmd_set_edca_params {
+	struct mwl8k_cmd_pkt header;
+
+	/* See MWL8K_SET_EDCA_XXX below */
+	__le16 action;
+
+	/* TX opportunity in units of 32 us */
+	__le16 txop;
+
+	/* 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;
+} __attribute__((packed));
+
+#define MWL8K_GET_EDCA_ALL	0
+#define MWL8K_SET_EDCA_CW	0x01
+#define MWL8K_SET_EDCA_TXOP	0x02
+#define MWL8K_SET_EDCA_AIFS	0x04
+
+#define MWL8K_SET_EDCA_ALL	(MWL8K_SET_EDCA_CW | \
+				 MWL8K_SET_EDCA_TXOP | \
+				 MWL8K_SET_EDCA_AIFS)
+
+static int
+mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
+		__u16 cw_min, __u16 cw_max,
+		__u8 aifs, __u16 txop)
+{
+	struct mwl8k_cmd_set_edca_params *cmd;
+	u32 log_cw_min, log_cw_max;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	log_cw_min = ilog2(cw_min+1);
+	log_cw_max = ilog2(cw_max+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)log_cw_max;
+	cmd->log_cw_min = (u8)log_cw_min;
+	cmd->aifs = aifs;
+	cmd->txq = qnum;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_FINALIZE_JOIN.
+ */
+
+/* FJ beacon buffer size is compiled into the firmware.  */
+#define MWL8K_FJ_BEACON_MAXLEN	128
+
+struct mwl8k_cmd_finalize_join {
+	struct mwl8k_cmd_pkt header;
+	__le32 sleep_interval;	/* Number of beacon periods to sleep */
+	__u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
+} __attribute__((packed));
+
+static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
+				__u16 framelen, __u16 dtim)
+{
+	struct mwl8k_cmd_finalize_join *cmd;
+	struct ieee80211_mgmt *payload = frame;
+	u16 hdrlen;
+	u32 payload_len;
+	int rc;
+
+	if (frame == NULL)
+		return -EINVAL;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	if (dtim)
+		cmd->sleep_interval = cpu_to_le32(dtim);
+	else
+		cmd->sleep_interval = cpu_to_le32(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);
+
+	payload_len = payload_len > MWL8K_FJ_BEACON_MAXLEN ?
+				MWL8K_FJ_BEACON_MAXLEN : payload_len;
+
+	if (payload && payload_len)
+		memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+	return rc;
+}
+
+/*
+ * CMD_UPDATE_STADB.
+ */
+struct mwl8k_cmd_update_sta_db {
+	struct mwl8k_cmd_pkt header;
+
+	/* See STADB_ACTION_TYPE */
+	__le32	action;
+
+	/* Peer MAC address */
+	__u8	peer_addr[IEEE80211_ADDR_LEN];
+
+	__le32	reserved;
+
+	/* Peer info - valid during add/update.  */
+	struct peer_capability_info	peer_info;
+} __attribute__((packed));
+
+static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
+		struct ieee80211_vif *vif, __u32 action)
+{
+	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+	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;
+	DECLARE_MAC_BUF(mac);
+	int rc;
+	__u8 count, *rates;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	cmd->action = cpu_to_le32(action);
+	peer_info = &cmd->peer_info;
+	memcpy(cmd->peer_addr, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+	switch (action) {
+	case MWL8K_STA_DB_ADD_ENTRY:
+	case MWL8K_STA_DB_MODIFY_ENTRY:
+		/* Build peer_info block */
+		peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
+		peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
+		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;
+
+		break;
+
+	case MWL8K_STA_DB_DEL_ENTRY:
+	case MWL8K_STA_DB_FLUSH:
+	default:
+		rc = mwl8k_post_cmd(hw, &cmd->header);
+		if (rc == 0)
+			mv_vif->peer_id = 0;
+		break;
+	}
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_AID.
+ */
+#define IEEE80211_OPMODE_DISABLED			0x00
+#define IEEE80211_OPMODE_NON_MEMBER_PROT_MODE		0x01
+#define IEEE80211_OPMODE_ONE_20MHZ_STA_PROT_MODE	0x02
+#define IEEE80211_OPMODE_HTMIXED_PROT_MODE		0x03
+
+#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
+#define MWL8K_FRAME_PROT_11N_HT_ALL			0x06
+#define MWL8K_FRAME_PROT_MASK				0x07
+
+struct mwl8k_cmd_update_set_aid {
+	struct	mwl8k_cmd_pkt header;
+	__le16	aid;
+
+	 /* AP's MAC address (BSSID) */
+	__u8	bssid[IEEE80211_ADDR_LEN];
+	__le16	protection_mode;
+	__u8	supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
+					struct ieee80211_vif *vif)
+{
+	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;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->aid = cpu_to_le16(info->aid);
+
+	memcpy(cmd->bssid, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+	prot_mode = MWL8K_FRAME_PROT_DISABLED;
+
+	if (info->use_cts_prot) {
+		prot_mode = MWL8K_FRAME_PROT_11G;
+	} else {
+		switch (info->ht.operation_mode &
+			IEEE80211_HT_OP_MODE_PROTECTION) {
+		case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+			prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
+			break;
+		case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+			prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
+			break;
+		default:
+			prot_mode = MWL8K_FRAME_PROT_DISABLED;
+			break;
+		}
+	}
+
+	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;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_SET_RATE.
+ */
+struct mwl8k_cmd_update_rateset {
+	struct	mwl8k_cmd_pkt header;
+	__u8	legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+
+	/* Bitmap for supported MCS codes.  */
+	__u8	mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES];
+	__u8	reserved[MWL8K_IEEE_LEGACY_DATA_RATES];
+} __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);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	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;
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+/*
+ * CMD_USE_FIXED_RATE.
+ */
+#define MWL8K_RATE_TABLE_SIZE	8
+#define MWL8K_UCAST_RATE	0
+#define MWL8K_MCAST_RATE	1
+#define MWL8K_BCAST_RATE	2
+
+#define MWL8K_USE_FIXED_RATE	0x0001
+#define MWL8K_USE_AUTO_RATE	0x0002
+
+struct mwl8k_rate_entry {
+	/* Set to 1 if HT rate, 0 if legacy.  */
+	__le32	is_ht_rate;
+
+	/* Set to 1 to use retry_count field.  */
+	__le32	enable_retry;
+
+	/* Specified legacy rate or MCS.  */
+	__le32	rate;
+
+	/* Number of allowed retries.  */
+	__le32	retry_count;
+} __attribute__((packed));
+
+struct mwl8k_rate_table {
+	/* 1 to allow specified rate and below */
+	__le32	allow_rate_drop;
+	__le32	num_rates;
+	struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE];
+} __attribute__((packed));
+
+struct mwl8k_cmd_use_fixed_rate {
+	struct	mwl8k_cmd_pkt header;
+	__le32	action;
+	struct mwl8k_rate_table rate_table;
+
+	/* Unicast, Broadcast or Multicast */
+	__le32	rate_type;
+	__le32	reserved1;
+	__le32	reserved2;
+} __attribute__((packed));
+
+static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
+	u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table)
+{
+	struct mwl8k_cmd_use_fixed_rate *cmd;
+	int count;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	cmd->action = cpu_to_le32(action);
+	cmd->rate_type = cpu_to_le32(rate_type);
+
+	if (rate_table != NULL) {
+		/* Copy over each field manually so
+		* that bitflipping can be done
+		*/
+		cmd->rate_table.allow_rate_drop =
+				cpu_to_le32(rate_table->allow_rate_drop);
+		cmd->rate_table.num_rates =
+				cpu_to_le32(rate_table->num_rates);
+
+		for (count = 0; count < rate_table->num_rates; count++) {
+			struct mwl8k_rate_entry *dst =
+				&cmd->rate_table.rate_entry[count];
+			struct mwl8k_rate_entry *src =
+				&rate_table->rate_entry[count];
+
+			dst->is_ht_rate = cpu_to_le32(src->is_ht_rate);
+			dst->enable_retry = cpu_to_le32(src->enable_retry);
+			dst->rate = cpu_to_le32(src->rate);
+			dst->retry_count = cpu_to_le32(src->retry_count);
+		}
+	}
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	kfree(cmd);
+
+	return rc;
+}
+
+
+/*
+ * Interrupt handling.
+ */
+static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
+{
+	struct ieee80211_hw *hw = dev_id;
+	struct mwl8k_priv *priv = hw->priv;
+	u32 status;
+
+	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+	iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+
+	status &= priv->int_mask;
+	if (!status)
+		return IRQ_NONE;
+
+	if (status & MWL8K_A2H_INT_TX_DONE)
+		tasklet_schedule(&priv->tx_reclaim_task);
+
+	if (status & MWL8K_A2H_INT_RX_READY) {
+		while (rxq_process(hw, 0, 1))
+			rxq_refill(hw, 0, 1);
+	}
+
+	if (status & MWL8K_A2H_INT_OPC_DONE) {
+		if (priv->hostcmd_wait != NULL) {
+			complete(priv->hostcmd_wait);
+			priv->hostcmd_wait = NULL;
+		}
+	}
+
+	if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
+		if (!priv->inconfig &&
+			priv->radio_state &&
+			mwl8k_txq_busy(priv))
+				mwl8k_tx_start(priv);
+	}
+
+	return IRQ_HANDLED;
+}
+
+
+/*
+ * Core driver operations.
+ */
+static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	int index = skb_get_queue_mapping(skb);
+	int rc;
+
+	if (priv->current_channel == NULL) {
+		printk(KERN_DEBUG "%s: dropped TX frame since radio "
+		       "disabled\n", priv->name);
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	rc = mwl8k_txq_xmit(hw, index, skb);
+
+	return rc;
+}
+
+struct mwl8k_work_struct {
+	/* Initialized by mwl8k_queue_work().  */
+	struct work_struct wt;
+
+	/* Required field passed in to mwl8k_queue_work().  */
+	struct ieee80211_hw *hw;
+
+	/* Required field passed in to mwl8k_queue_work().  */
+	int (*wfunc)(struct work_struct *w);
+
+	/* Initialized by mwl8k_queue_work().  */
+	struct completion *cmd_wait;
+
+	/* Result code.  */
+	int rc;
+
+	/*
+	 * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
+	 * flags for explanation.  Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
+	 */
+	u32 options;
+
+	/* Optional field.  Defaults to MWL8K_CONFIG_TIMEOUT_MS.  */
+	unsigned long timeout_ms;
+
+	/* Optional field.  Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS.  */
+	u32 txwait_attempts;
+
+	/* Optional field.  Defaults to MWL8K_TXWAIT_MS.  */
+	u32 tx_timeout_ms;
+	u32 step;
+};
+
+/* Flags controlling behavior of config queue requests */
+
+/* Caller spins while waiting for completion.  */
+#define MWL8K_WQ_SPIN			0x00000001
+
+/* Wait for TX queues to empty before proceeding with configuration.  */
+#define MWL8K_WQ_TX_WAIT_EMPTY		0x00000002
+
+/* Queue request and return immediately.  */
+#define MWL8K_WQ_POST_REQUEST		0x00000004
+
+/*
+ * Caller sleeps and waits for task complete notification.
+ * Do not use in atomic context.
+ */
+#define MWL8K_WQ_SLEEP			0x00000008
+
+/* Free work struct when task is done.  */
+#define MWL8K_WQ_FREE_WORKSTRUCT	0x00000010
+
+/*
+ * Config request is queued and returns to caller imediately.  Use
+ * this in atomic context. Work struct is freed by mwl8k_queue_work()
+ * when this flag is set.
+ */
+#define MWL8K_WQ_QUEUE_ONLY	(MWL8K_WQ_POST_REQUEST | \
+				 MWL8K_WQ_FREE_WORKSTRUCT)
+
+/* Default work queue behavior is to sleep and wait for tx completion.  */
+#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
+
+/*
+ * Default config request timeout.  Add adjustments to make sure the
+ * config thread waits long enough for both tx wait and cmd wait before
+ * timing out.
+ */
+
+/* Time to wait for all TXQs to drain.  TX Doorbell is pressed each time.  */
+#define MWL8K_TXWAIT_TIMEOUT_MS		1000
+
+/* Default number of TX wait attempts.  */
+#define MWL8K_WQ_TXWAIT_ATTEMPTS	4
+
+/* Total time to wait for TXQ to drain.  */
+#define MWL8K_TXWAIT_MS			(MWL8K_TXWAIT_TIMEOUT_MS * \
+						MWL8K_WQ_TXWAIT_ATTEMPTS)
+
+/* Scheduling slop.  */
+#define MWL8K_OS_SCHEDULE_OVERHEAD_MS	200
+
+#define MWL8K_CONFIG_TIMEOUT_MS	(MWL8K_CMD_TIMEOUT_MS + \
+				 MWL8K_TXWAIT_MS + \
+				 MWL8K_OS_SCHEDULE_OVERHEAD_MS)
+
+static void mwl8k_config_thread(struct work_struct *wt)
+{
+	struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
+	struct ieee80211_hw *hw = worker->hw;
+	struct mwl8k_priv *priv = hw->priv;
+	int rc = 0;
+
+	spin_lock_irq(&priv->tx_lock);
+	priv->inconfig = true;
+	spin_unlock_irq(&priv->tx_lock);
+
+	ieee80211_stop_queues(hw);
+
+	/*
+	 * Wait for host queues to drain before doing PHY
+	 * reconfiguration. This avoids interrupting any in-flight
+	 * DMA transfers to the hardware.
+	 */
+	if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
+		u32 timeout;
+		u32 time_remaining;
+		u32 iter;
+		u32 tx_wait_attempts = worker->txwait_attempts;
+
+		time_remaining = worker->tx_timeout_ms;
+		if (!tx_wait_attempts)
+			tx_wait_attempts = 1;
+
+		timeout = worker->tx_timeout_ms/tx_wait_attempts;
+		if (!timeout)
+			timeout = 1;
+
+		iter = tx_wait_attempts;
+		do {
+			int wait_time;
+
+			if (time_remaining > timeout) {
+				time_remaining -= timeout;
+				wait_time = timeout;
+			} else
+				wait_time = time_remaining;
+
+			if (!wait_time)
+				wait_time = 1;
+
+			rc = mwl8k_tx_wait_empty(hw, wait_time);
+			if (rc)
+				printk(KERN_ERR "%s() txwait timeout=%ums "
+					"Retry:%u/%u\n", __func__, timeout,
+					tx_wait_attempts - iter + 1,
+					tx_wait_attempts);
+
+		} while (rc && --iter);
+
+		rc = iter ? 0 : -ETIMEDOUT;
+	}
+	if (!rc)
+		rc = worker->wfunc(wt);
+
+	spin_lock_irq(&priv->tx_lock);
+	priv->inconfig = false;
+	if (priv->pending_tx_pkts && priv->radio_state)
+		mwl8k_tx_start(priv);
+	spin_unlock_irq(&priv->tx_lock);
+	ieee80211_wake_queues(hw);
+
+	worker->rc = rc;
+	if (worker->options & MWL8K_WQ_SLEEP)
+		complete(worker->cmd_wait);
+
+	if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
+		kfree(wt);
+}
+
+static int mwl8k_queue_work(struct ieee80211_hw *hw,
+				struct mwl8k_work_struct *worker,
+				struct workqueue_struct *wqueue,
+				int (*wfunc)(struct work_struct *w))
+{
+	unsigned long timeout = 0;
+	int rc = 0;
+
+	DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+	if (!worker->timeout_ms)
+		worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
+
+	if (!worker->options)
+		worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
+
+	if (!worker->txwait_attempts)
+		worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
+
+	if (!worker->tx_timeout_ms)
+		worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
+
+	worker->hw = hw;
+	worker->cmd_wait = &cmd_wait;
+	worker->rc = 1;
+	worker->wfunc = wfunc;
+
+	INIT_WORK(&worker->wt, mwl8k_config_thread);
+	queue_work(wqueue, &worker->wt);
+
+	if (worker->options & MWL8K_WQ_POST_REQUEST) {
+		rc = 0;
+	} else {
+		if (worker->options & MWL8K_WQ_SPIN) {
+			timeout = worker->timeout_ms;
+			while (timeout && (worker->rc > 0)) {
+				mdelay(1);
+				timeout--;
+			}
+		} else if (worker->options & MWL8K_WQ_SLEEP)
+			timeout = wait_for_completion_timeout(&cmd_wait,
+				msecs_to_jiffies(worker->timeout_ms));
+
+		if (timeout)
+			rc = worker->rc;
+		else {
+			cancel_work_sync(&worker->wt);
+			rc = -ETIMEDOUT;
+		}
+	}
+
+	return rc;
+}
+
+struct mwl8k_start_worker {
+	struct mwl8k_work_struct header;
+};
+
+static int mwl8k_start_wt(struct work_struct *wt)
+{
+	struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
+	struct ieee80211_hw *hw = worker->header.hw;
+	struct mwl8k_priv *priv = hw->priv;
+	int rc = 0;
+
+	if (priv->vif != NULL) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	/* Turn on radio */
+	if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	/* Purge TX/RX HW queues */
+	if (mwl8k_cmd_set_pre_scan(hw)) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	/* Enable firmware rate adaptation */
+	if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	/* Disable WMM. WMM gets enabled when stack sends WMM parms */
+	if (mwl8k_set_wmm(hw, MWL8K_WMM_DISABLE)) {
+		rc = -EIO;
+		goto mwl8k_start_exit;
+	}
+
+	/* Disable sniffer mode */
+	if (mwl8k_enable_sniffer(hw, 0))
+		rc = -EIO;
+
+mwl8k_start_exit:
+	return rc;
+}
+
+static int mwl8k_start(struct ieee80211_hw *hw)
+{
+	struct mwl8k_start_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+	int rc;
+
+	/* Enable tx reclaim tasklet */
+	tasklet_enable(&priv->tx_reclaim_task);
+
+	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);
+		rc = -EIO;
+		goto mwl8k_start_disable_tasklet;
+	}
+
+	/* Enable interrupts */
+	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL) {
+		rc = -ENOMEM;
+		goto mwl8k_start_disable_irq;
+	}
+
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq, mwl8k_start_wt);
+	kfree(worker);
+	if (!rc)
+		return rc;
+
+	if (rc == -ETIMEDOUT)
+		printk(KERN_ERR "%s() timed out\n", __func__);
+
+	rc = -EIO;
+
+mwl8k_start_disable_irq:
+	spin_lock_irq(&priv->tx_lock);
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	spin_unlock_irq(&priv->tx_lock);
+	free_irq(priv->pdev->irq, hw);
+
+mwl8k_start_disable_tasklet:
+	tasklet_disable(&priv->tx_reclaim_task);
+
+	return rc;
+}
+
+struct mwl8k_stop_worker {
+	struct mwl8k_work_struct header;
+};
+
+static int mwl8k_stop_wt(struct work_struct *wt)
+{
+	struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
+	struct ieee80211_hw *hw = worker->header.hw;
+	int rc;
+
+	rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+
+	return rc;
+}
+
+static void mwl8k_stop(struct ieee80211_hw *hw)
+{
+	int rc;
+	struct mwl8k_stop_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+	int i;
+
+	if (priv->vif != NULL)
+		return;
+
+	ieee80211_stop_queues(hw);
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return;
+
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq, mwl8k_stop_wt);
+	kfree(worker);
+	if (rc == -ETIMEDOUT)
+		printk(KERN_ERR "%s() timed out\n", __func__);
+
+	/* Disable interrupts */
+	spin_lock_irq(&priv->tx_lock);
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	spin_unlock_irq(&priv->tx_lock);
+	free_irq(priv->pdev->irq, hw);
+
+	/* Stop finalize join worker */
+	cancel_work_sync(&priv->finalize_join_worker);
+	if (priv->beacon_skb != NULL)
+		dev_kfree_skb(priv->beacon_skb);
+
+	/* 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);
+}
+
+static int mwl8k_add_interface(struct ieee80211_hw *hw,
+				struct ieee80211_if_init_conf *conf)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mwl8k_vif;
+
+	/*
+	 * We only support one active interface at a time.
+	 */
+	if (priv->vif != NULL)
+		return -EBUSY;
+
+	/*
+	 * We only support managed interfaces for now.
+	 */
+	if (conf->type != NL80211_IFTYPE_STATION &&
+	    conf->type != NL80211_IFTYPE_MONITOR)
+		return -EINVAL;
+
+	/* Clean out driver private area */
+	mwl8k_vif = MWL8K_VIF(conf->vif);
+	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
+
+	/* Save the mac address */
+	memcpy(mwl8k_vif->mac_addr, conf->mac_addr, IEEE80211_ADDR_LEN);
+
+	/* 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;
+
+	priv->vif = conf->vif;
+	priv->current_channel = NULL;
+
+	return 0;
+}
+
+static void mwl8k_remove_interface(struct ieee80211_hw *hw,
+				   struct ieee80211_if_init_conf *conf)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if (priv->vif == NULL)
+		return;
+
+	priv->vif = NULL;
+}
+
+struct mwl8k_config_worker {
+	struct mwl8k_work_struct header;
+	u32 changed;
+};
+
+static int mwl8k_config_wt(struct work_struct *wt)
+{
+	struct mwl8k_config_worker *worker =
+		(struct mwl8k_config_worker *)wt;
+	struct ieee80211_hw *hw = worker->header.hw;
+	struct ieee80211_conf *conf = &hw->conf;
+	struct mwl8k_priv *priv = hw->priv;
+	int rc = 0;
+
+	if (!conf->radio_enabled) {
+		mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+		priv->current_channel = NULL;
+		rc = 0;
+		goto mwl8k_config_exit;
+	}
+
+	if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+		rc = -EINVAL;
+		goto mwl8k_config_exit;
+	}
+
+	priv->current_channel = conf->channel;
+
+	if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
+		rc = -EINVAL;
+		goto mwl8k_config_exit;
+	}
+
+	if (conf->power_level > 18)
+		conf->power_level = 18;
+	if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
+		rc = -EINVAL;
+		goto mwl8k_config_exit;
+	}
+
+	if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
+		rc = -EINVAL;
+
+mwl8k_config_exit:
+	return rc;
+}
+
+static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
+{
+	int rc = 0;
+	struct mwl8k_config_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return -ENOMEM;
+
+	worker->changed = changed;
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq, mwl8k_config_wt);
+	if (rc == -ETIMEDOUT) {
+		printk(KERN_ERR "%s() timed out.\n", __func__);
+		rc = -EINVAL;
+	}
+
+	kfree(worker);
+
+	/*
+	 * mac80211 will crash on anything other than -EINVAL on
+	 * error. Looks like wireless extensions which calls mac80211
+	 * may be the actual culprit...
+	 */
+	return rc ? -EINVAL : 0;
+}
+
+static int mwl8k_config_interface(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif,
+				  struct ieee80211_if_conf *conf)
+{
+	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+	u32 changed = conf->changed;
+
+	if (changed & IEEE80211_IFCC_BSSID)
+		memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
+
+	return 0;
+}
+
+struct mwl8k_bss_info_changed_worker {
+	struct mwl8k_work_struct header;
+	struct ieee80211_vif *vif;
+	struct ieee80211_bss_conf *info;
+	u32 changed;
+};
+
+static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
+{
+	struct mwl8k_bss_info_changed_worker *worker =
+		(struct mwl8k_bss_info_changed_worker *)wt;
+	struct ieee80211_hw *hw = worker->header.hw;
+	struct ieee80211_vif *vif = worker->vif;
+	struct ieee80211_bss_conf *info = worker->info;
+	u32 changed;
+	int rc;
+
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+	changed = worker->changed;
+	priv->capture_beacon = false;
+
+	if (info->assoc) {
+		memcpy(&mwl8k_vif->bss_info, info,
+			sizeof(struct ieee80211_bss_conf));
+
+		/* Install rates */
+		if (mwl8k_update_rateset(hw, vif))
+			goto mwl8k_bss_info_changed_exit;
+
+		/* Turn on rate adaptation */
+		if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+			MWL8K_UCAST_RATE, NULL))
+			goto mwl8k_bss_info_changed_exit;
+
+		/* Set radio preamble */
+		if (mwl8k_set_radio_preamble(hw,
+				info->use_short_preamble))
+			goto mwl8k_bss_info_changed_exit;
+
+		/* Set slot time */
+		if (mwl8k_cmd_set_slot(hw, info->use_short_slot ?
+				MWL8K_SHORT_SLOTTIME : MWL8K_LONG_SLOTTIME))
+			goto mwl8k_bss_info_changed_exit;
+
+		/* Update peer rate info */
+		if (mwl8k_cmd_update_sta_db(hw, vif,
+				MWL8K_STA_DB_MODIFY_ENTRY))
+			goto mwl8k_bss_info_changed_exit;
+
+		/* Set AID */
+		if (mwl8k_cmd_set_aid(hw, vif))
+			goto mwl8k_bss_info_changed_exit;
+
+		/*
+		 * Finalize the join.  Tell rx handler to process
+		 * next beacon from our BSSID.
+		 */
+		memcpy(priv->capture_bssid,
+				mwl8k_vif->bssid, IEEE80211_ADDR_LEN);
+		priv->capture_beacon = true;
+	} else {
+		mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+		memset(&mwl8k_vif->bss_info, 0,
+			sizeof(struct ieee80211_bss_conf));
+		memset(mwl8k_vif->bssid, 0, IEEE80211_ADDR_LEN);
+	}
+
+mwl8k_bss_info_changed_exit:
+	rc = 0;
+	return rc;
+}
+
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_bss_conf *info,
+				   u32 changed)
+{
+	struct mwl8k_bss_info_changed_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+	int rc;
+
+	if ((changed & BSS_CHANGED_ASSOC) == 0)
+		return;
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return;
+
+	worker->vif = vif;
+	worker->info = info;
+	worker->changed = changed;
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq,
+			      mwl8k_bss_info_changed_wt);
+	kfree(worker);
+	if (rc == -ETIMEDOUT)
+		printk(KERN_ERR "%s() timed out\n", __func__);
+}
+
+struct mwl8k_configure_filter_worker {
+	struct mwl8k_work_struct header;
+	unsigned int changed_flags;
+	unsigned int *total_flags;
+	int mc_count;
+	struct dev_addr_list *mclist;
+};
+
+#define MWL8K_SUPPORTED_IF_FLAGS	FIF_BCN_PRBRESP_PROMISC
+
+static int mwl8k_configure_filter_wt(struct work_struct *wt)
+{
+	struct mwl8k_configure_filter_worker *worker =
+		(struct mwl8k_configure_filter_worker *)wt;
+
+	struct ieee80211_hw *hw = worker->header.hw;
+	unsigned int changed_flags = worker->changed_flags;
+	unsigned int *total_flags = worker->total_flags;
+	int mc_count = worker->mc_count;
+	struct dev_addr_list *mclist = worker->mclist;
+
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_vif *mv_vif;
+	int rc = 0;
+
+	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+			rc = mwl8k_cmd_set_pre_scan(hw);
+		else {
+			mv_vif = MWL8K_VIF(priv->vif);
+			rc = mwl8k_cmd_set_post_scan(hw, mv_vif->bssid);
+		}
+	}
+
+	if (rc)
+		goto mwl8k_configure_filter_exit;
+	if (mc_count) {
+		mc_count = mc_count < priv->num_mcaddrs ?
+				mc_count : priv->num_mcaddrs;
+		rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
+		if (rc)
+			printk(KERN_ERR
+			"%s()Error setting multicast addresses\n",
+			__func__);
+	}
+
+mwl8k_configure_filter_exit:
+	return rc;
+}
+
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+				   unsigned int changed_flags,
+				   unsigned int *total_flags,
+				   int mc_count,
+				   struct dev_addr_list *mclist)
+{
+
+	struct mwl8k_configure_filter_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+
+	/* Clear unsupported feature flags */
+	*total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
+
+	if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
+		return;
+
+	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
+	if (worker == NULL)
+		return;
+
+	worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
+	worker->changed_flags = changed_flags;
+	worker->total_flags = total_flags;
+	worker->mc_count = mc_count;
+	worker->mclist = mclist;
+
+	mwl8k_queue_work(hw, &worker->header, priv->config_wq,
+			 mwl8k_configure_filter_wt);
+}
+
+struct mwl8k_set_rts_threshold_worker {
+	struct mwl8k_work_struct header;
+	u32 value;
+};
+
+static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
+{
+	struct mwl8k_set_rts_threshold_worker *worker =
+		(struct mwl8k_set_rts_threshold_worker *)wt;
+
+	struct ieee80211_hw *hw = worker->header.hw;
+	u16 threshold = (u16)(worker->value);
+	int rc;
+
+	rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
+
+	return rc;
+}
+
+static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	int rc;
+	struct mwl8k_set_rts_threshold_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return -ENOMEM;
+
+	worker->value = value;
+
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq,
+			      mwl8k_set_rts_threshold_wt);
+	kfree(worker);
+
+	if (rc == -ETIMEDOUT) {
+		printk(KERN_ERR "%s() timed out\n", __func__);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+struct mwl8k_conf_tx_worker {
+	struct mwl8k_work_struct header;
+	u16 queue;
+	const struct ieee80211_tx_queue_params *params;
+};
+
+static int mwl8k_conf_tx_wt(struct work_struct *wt)
+{
+	struct mwl8k_conf_tx_worker *worker =
+	(struct mwl8k_conf_tx_worker *)wt;
+
+	struct ieee80211_hw *hw = worker->header.hw;
+	u16 queue = worker->queue;
+	const struct ieee80211_tx_queue_params *params = worker->params;
+
+	struct mwl8k_priv *priv = hw->priv;
+	int rc = 0;
+
+	if (priv->wmm_mode == MWL8K_WMM_DISABLE)
+		if (mwl8k_set_wmm(hw, MWL8K_WMM_ENABLE)) {
+			rc = -EINVAL;
+			goto mwl8k_conf_tx_exit;
+	}
+
+	if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
+		params->cw_max, params->aifs, params->txop))
+			rc = -EINVAL;
+mwl8k_conf_tx_exit:
+	return rc;
+}
+
+static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+			 const struct ieee80211_tx_queue_params *params)
+{
+	int rc;
+	struct mwl8k_conf_tx_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return -ENOMEM;
+
+	worker->queue = queue;
+	worker->params = params;
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq, mwl8k_conf_tx_wt);
+	kfree(worker);
+	if (rc == -ETIMEDOUT) {
+		printk(KERN_ERR "%s() timed out\n", __func__);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
+			      struct ieee80211_tx_queue_stats *stats)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_tx_queue *txq;
+	int index;
+
+	spin_lock_bh(&priv->tx_lock);
+	for (index = 0; index < MWL8K_TX_QUEUES; index++) {
+		txq = priv->txq + index;
+		memcpy(&stats[index], &txq->tx_stats,
+			sizeof(struct ieee80211_tx_queue_stats));
+	}
+	spin_unlock_bh(&priv->tx_lock);
+	return 0;
+}
+
+struct mwl8k_get_stats_worker {
+	struct mwl8k_work_struct header;
+	struct ieee80211_low_level_stats *stats;
+};
+
+static int mwl8k_get_stats_wt(struct work_struct *wt)
+{
+	struct mwl8k_get_stats_worker *worker =
+		(struct mwl8k_get_stats_worker *)wt;
+
+	return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+}
+
+static int mwl8k_get_stats(struct ieee80211_hw *hw,
+			   struct ieee80211_low_level_stats *stats)
+{
+	int rc;
+	struct mwl8k_get_stats_worker *worker;
+	struct mwl8k_priv *priv = hw->priv;
+
+	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+	if (worker == NULL)
+		return -ENOMEM;
+
+	worker->stats = stats;
+	rc = mwl8k_queue_work(hw, &worker->header,
+			      priv->config_wq, mwl8k_get_stats_wt);
+
+	kfree(worker);
+	if (rc == -ETIMEDOUT) {
+		printk(KERN_ERR "%s() timed out\n", __func__);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static const struct ieee80211_ops mwl8k_ops = {
+	.tx			= mwl8k_tx,
+	.start			= mwl8k_start,
+	.stop			= mwl8k_stop,
+	.add_interface		= mwl8k_add_interface,
+	.remove_interface	= mwl8k_remove_interface,
+	.config			= mwl8k_config,
+	.config_interface	= mwl8k_config_interface,
+	.bss_info_changed	= mwl8k_bss_info_changed,
+	.configure_filter	= mwl8k_configure_filter,
+	.set_rts_threshold	= mwl8k_set_rts_threshold,
+	.conf_tx		= mwl8k_conf_tx,
+	.get_tx_stats		= mwl8k_get_tx_stats,
+	.get_stats		= mwl8k_get_stats,
+};
+
+static void mwl8k_tx_reclaim_handler(unsigned long data)
+{
+	int i;
+	struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
+	struct mwl8k_priv *priv = hw->priv;
+
+	spin_lock_bh(&priv->tx_lock);
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		mwl8k_txq_reclaim(hw, i, 0);
+
+	if (priv->tx_wait != NULL) {
+		int count = mwl8k_txq_busy(priv);
+		if (count == 0) {
+			complete(priv->tx_wait);
+			priv->tx_wait = NULL;
+		}
+	}
+	spin_unlock_bh(&priv->tx_lock);
+}
+
+static void mwl8k_finalize_join_worker(struct work_struct *work)
+{
+	struct mwl8k_priv *priv =
+		container_of(work, struct mwl8k_priv, finalize_join_worker);
+	struct sk_buff *skb = priv->beacon_skb;
+	u8 dtim = (MWL8K_VIF(priv->vif))->bss_info.dtim_period;
+
+	mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
+	dev_kfree_skb(skb);
+
+	priv->beacon_skb = NULL;
+}
+
+static int __devinit mwl8k_probe(struct pci_dev *pdev,
+				 const struct pci_device_id *id)
+{
+	struct ieee80211_hw *hw;
+	struct mwl8k_priv *priv;
+	DECLARE_MAC_BUF(mac);
+	int rc;
+	int i;
+	u8 *fw;
+
+	rc = pci_enable_device(pdev);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot enable new PCI device\n",
+		       MWL8K_NAME);
+		return rc;
+	}
+
+	rc = pci_request_regions(pdev, MWL8K_NAME);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
+		       MWL8K_NAME);
+		return rc;
+	}
+
+	pci_set_master(pdev);
+
+	hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
+	if (hw == NULL) {
+		printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
+		rc = -ENOMEM;
+		goto err_free_reg;
+	}
+
+	priv = hw->priv;
+	priv->hw = hw;
+	priv->pdev = pdev;
+	priv->hostcmd_wait = NULL;
+	priv->tx_wait = NULL;
+	priv->inconfig = false;
+	priv->wep_enabled = 0;
+	priv->wmm_mode = false;
+	priv->pending_tx_pkts = 0;
+	strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
+
+	spin_lock_init(&priv->fw_lock);
+
+	SET_IEEE80211_DEV(hw, &pdev->dev);
+	pci_set_drvdata(pdev, hw);
+
+	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;
+	}
+
+	memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
+	priv->band.band = IEEE80211_BAND_2GHZ;
+	priv->band.channels = priv->channels;
+	priv->band.n_channels = ARRAY_SIZE(mwl8k_channels);
+	priv->band.bitrates = priv->rates;
+	priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates);
+	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+
+	BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates));
+	memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates));
+
+	/*
+	 * Extra headroom is the size of the required DMA header
+	 * minus the size of the smallest 802.11 frame (CTS frame).
+	 */
+	hw->extra_tx_headroom =
+		sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+
+	hw->channel_change_time = 10;
+
+	hw->queues = MWL8K_TX_QUEUES;
+
+	hw->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_MONITOR);
+
+	/* Set rssi and noise values to dBm */
+	hw->flags |= (IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM);
+	hw->vif_data_size = sizeof(struct mwl8k_vif);
+	priv->vif = NULL;
+
+	/* Set default radio state and preamble */
+	priv->radio_preamble = MWL8K_RADIO_DEFAULT_PREAMBLE;
+	priv->radio_state = MWL8K_RADIO_DISABLE;
+
+	/* Finalize join worker */
+	INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+
+	/* TX reclaim tasklet */
+	tasklet_init(&priv->tx_reclaim_task,
+			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)
+		goto err_iounmap;
+
+	rc = mwl8k_rxq_init(hw, 0);
+	if (rc)
+		goto err_iounmap;
+	rxq_refill(hw, 0, INT_MAX);
+
+	spin_lock_init(&priv->tx_lock);
+
+	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+		rc = mwl8k_txq_init(hw, i);
+		if (rc)
+			goto err_free_queues;
+	}
+
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+	priv->int_mask = 0;
+	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	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,
+			 IRQF_SHARED, MWL8K_NAME, hw);
+	if (rc) {
+		printk(KERN_ERR "%s: failed to register IRQ handler\n",
+		       priv->name);
+		goto err_free_queues;
+	}
+
+	/* Reset firmware and hardware */
+	mwl8k_hw_reset(priv);
+
+	/* Ask userland hotplug daemon for the device firmware */
+	rc = mwl8k_reject_firmware(priv, (u32)id->driver_data);
+	if (rc) {
+		printk(KERN_ERR "%s: Firmware files not found\n", priv->name);
+		goto err_free_irq;
+	}
+
+	/* Load firmware into hardware */
+	rc = mwl8k_load_firmware(priv);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot start firmware\n", priv->name);
+		goto err_stop_firmware;
+	}
+
+	/* Reclaim memory once firmware is successfully loaded */
+	mwl8k_release_firmware(priv);
+
+	/*
+	 * Temporarily enable interrupts.  Initial firmware host
+	 * commands use interrupts and avoids polling.  Disable
+	 * interrupts when done.
+	 */
+	priv->int_mask |= MWL8K_A2H_EVENTS;
+
+	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+	/* Get config data, mac addrs etc */
+	rc = mwl8k_cmd_get_hw_spec(hw);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name);
+		goto err_stop_firmware;
+	}
+
+	/* Turn radio off */
+	rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot disable\n", priv->name);
+		goto err_stop_firmware;
+	}
+
+	/* Disable interrupts */
+	spin_lock_irq(&priv->tx_lock);
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	spin_unlock_irq(&priv->tx_lock);
+	free_irq(priv->pdev->irq, hw);
+
+	rc = ieee80211_register_hw(hw);
+	if (rc) {
+		printk(KERN_ERR "%s: Cannot register device\n", priv->name);
+		goto err_stop_firmware;
+	}
+
+	fw = (u8 *)&priv->fw_rev;
+	printk(KERN_INFO "%s: 88W%u %s\n", priv->name, priv->part_num,
+		MWL8K_DESC);
+	printk(KERN_INFO "%s: Driver Ver:%s  Firmware Ver:%u.%u.%u.%u\n",
+		priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]);
+	printk(KERN_INFO "%s: MAC Address: %s\n", priv->name,
+	       print_mac(mac, hw->wiphy->perm_addr));
+
+	return 0;
+
+err_stop_firmware:
+	mwl8k_hw_reset(priv);
+	mwl8k_release_firmware(priv);
+
+err_free_irq:
+	spin_lock_irq(&priv->tx_lock);
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	spin_unlock_irq(&priv->tx_lock);
+	free_irq(priv->pdev->irq, hw);
+
+err_free_queues:
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		mwl8k_txq_deinit(hw, i);
+	mwl8k_rxq_deinit(hw, 0);
+
+err_iounmap:
+	if (priv->cookie != NULL)
+		pci_free_consistent(priv->pdev, 4,
+				priv->cookie, priv->cookie_dma);
+
+	if (priv->regs != NULL)
+		pci_iounmap(pdev, priv->regs);
+
+	if (priv->config_wq != NULL)
+		destroy_workqueue(priv->config_wq);
+
+	pci_set_drvdata(pdev, NULL);
+	ieee80211_free_hw(hw);
+
+err_free_reg:
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+	return rc;
+}
+
+static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
+{
+	printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
+}
+
+static void __devexit mwl8k_remove(struct pci_dev *pdev)
+{
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct mwl8k_priv *priv;
+	int i;
+
+	if (hw == NULL)
+		return;
+	priv = hw->priv;
+
+	ieee80211_stop_queues(hw);
+
+	/* Remove tx reclaim tasklet */
+	tasklet_kill(&priv->tx_reclaim_task);
+
+	/* Stop config thread */
+	destroy_workqueue(priv->config_wq);
+
+	/* Stop hardware */
+	mwl8k_hw_reset(priv);
+
+	/* Return all skbs to mac80211 */
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		mwl8k_txq_reclaim(hw, i, 1);
+
+	ieee80211_unregister_hw(hw);
+
+	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+		mwl8k_txq_deinit(hw, i);
+
+	mwl8k_rxq_deinit(hw, 0);
+
+	pci_free_consistent(priv->pdev, 4,
+				priv->cookie, priv->cookie_dma);
+
+	pci_iounmap(pdev, priv->regs);
+	pci_set_drvdata(pdev, NULL);
+	ieee80211_free_hw(hw);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static struct pci_driver mwl8k_driver = {
+	.name		= MWL8K_NAME,
+	.id_table	= mwl8k_table,
+	.probe		= mwl8k_probe,
+	.remove		= __devexit_p(mwl8k_remove),
+	.shutdown	= __devexit_p(mwl8k_shutdown),
+};
+
+static int __init mwl8k_init(void)
+{
+	return pci_register_driver(&mwl8k_driver);
+}
+
+static void __exit mwl8k_exit(void)
+{
+	pci_unregister_driver(&mwl8k_driver);
+}
+
+module_init(mwl8k_init);
+module_exit(mwl8k_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/netwave_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/netwave_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/netwave_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/netwave_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -210,10 +210,6 @@ static int netwave_rx( struct net_device
 static irqreturn_t netwave_interrupt(int irq, void *dev_id);
 static void netwave_watchdog(struct net_device *);
 
-/* Statistics */
-static void update_stats(struct net_device *dev);
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-
 /* Wireless extensions */
 static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
 
@@ -275,14 +271,9 @@ typedef struct netwave_private {
     int        lastExec;
     struct timer_list      watchdog;	/* To avoid blocking state */
     struct site_survey     nss;
-    struct net_device_stats stats;
     struct iw_statistics   iw_stats;    /* Wireless stats */
 } netwave_private;
 
-#ifdef NETWAVE_STATS
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-#endif
-
 /*
  * The Netwave card is little-endian, so won't work for big endian
  * systems.
@@ -364,6 +355,17 @@ static struct iw_statistics *netwave_get
     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)
  *
@@ -412,17 +414,12 @@ static int netwave_probe(struct pcmcia_d
     spin_lock_init(&priv->spinlock);
 
     /* Netwave specific entries in the device structure */
-    dev->hard_start_xmit = &netwave_start_xmit;
-    dev->get_stats  = &netwave_get_stats;
-    dev->set_multicast_list = &set_multicast_list;
+    dev->netdev_ops = &netwave_netdev_ops;
     /* wireless extensions */
-    dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
+    dev->wireless_handlers = &netwave_handler_def;
 
-    dev->tx_timeout = &netwave_watchdog;
     dev->watchdog_timeo = TX_TIMEOUT;
 
-    dev->open = &netwave_open;
-    dev->stop = &netwave_close;
     link->irq.Instance = dev;
 
     return netwave_pcmcia_config( link);
@@ -988,7 +985,7 @@ static int netwave_hw_xmit(unsigned char
 	return 1;
     }
 
-    priv->stats.tx_bytes += len;
+    dev->stats.tx_bytes += len;
 
     DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
 	  readb(ramBase + NETWAVE_EREG_SPCQ),
@@ -1107,11 +1104,11 @@ static irqreturn_t netwave_interrupt(int
 	    rser = readb(ramBase + NETWAVE_EREG_RSER);			
 	    
 	    if (rser & 0x04) {
-		++priv->stats.rx_dropped; 
-		++priv->stats.rx_crc_errors;
+		++dev->stats.rx_dropped;
+		++dev->stats.rx_crc_errors;
 	    }
 	    if (rser & 0x02)
-		++priv->stats.rx_frame_errors;
+		++dev->stats.rx_frame_errors;
 			
 	    /* Clear the RxErr bit in RSER. RSER+4 is the
 	     * write part. Also clear the RxCRC (0x04) and 
@@ -1125,8 +1122,8 @@ static irqreturn_t netwave_interrupt(int
 	    wait_WOC(iobase);
 	    writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
 
-	    /* Remember to count up priv->stats on error packets */
-	    ++priv->stats.rx_errors;
+	    /* Remember to count up dev->stats on error packets */
+	    ++dev->stats.rx_errors;
 	}
 	/* TxDN */
 	if (status & 0x20) {
@@ -1140,17 +1137,17 @@ static irqreturn_t netwave_interrupt(int
 		/* Transmitting was okay, clear bits */
 		wait_WOC(iobase);
 		writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
-		++priv->stats.tx_packets;
+		++dev->stats.tx_packets;
 	    }
 			
 	    if (txStatus & 0xd0) {
 		if (txStatus & 0x80) {
-		    ++priv->stats.collisions; /* Because of /proc/net/dev*/
-		    /* ++priv->stats.tx_aborted_errors; */
+		    ++dev->stats.collisions; /* Because of /proc/net/dev*/
+		    /* ++dev->stats.tx_aborted_errors; */
 		    /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
 		}
 		if (txStatus & 0x40) 
-		    ++priv->stats.tx_carrier_errors;
+		    ++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 
@@ -1163,7 +1160,7 @@ static irqreturn_t netwave_interrupt(int
 		/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
 		wait_WOC(iobase);
 		writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
-		++priv->stats.tx_errors;
+		++dev->stats.tx_errors;
 	    }
 	    DEBUG(3, "New status is TSER %x ASR %x\n",
 		  readb(ramBase + NETWAVE_EREG_TSER),
@@ -1197,40 +1194,6 @@ static void netwave_watchdog(struct net_
     netif_wake_queue(dev);
 } /* netwave_watchdog */
 
-static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
-    netwave_private *priv = netdev_priv(dev);
-
-    update_stats(dev);
-
-    DEBUG(2, "netwave: SPCQ %x SPU %x LIF %x ISPLQ %x MHS %x rxtx %x"
-	  " %x tx %x %x %x %x\n", 
-	  readb(priv->ramBase + NETWAVE_EREG_SPCQ),
-	  readb(priv->ramBase + NETWAVE_EREG_SPU),
-	  readb(priv->ramBase + NETWAVE_EREG_LIF),
-	  readb(priv->ramBase + NETWAVE_EREG_ISPLQ),
-	  readb(priv->ramBase + NETWAVE_EREG_MHS),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0xe),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0xf),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0x18),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0x19),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0x1a),
-	  readb(priv->ramBase + NETWAVE_EREG_EC + 0x1b));
-
-    return &priv->stats;
-}
-
-static void update_stats(struct net_device *dev) {
-    //unsigned long flags;
-/*     netwave_private *priv = netdev_priv(dev); */
-
-    //spin_lock_irqsave(&priv->spinlock, flags);
-
-/*    priv->stats.rx_packets = readb(priv->ramBase + 0x18e); 
-    priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
-
-    //spin_unlock_irqrestore(&priv->spinlock, flags);
-}
-
 static int netwave_rx(struct net_device *dev)
 {
     netwave_private *priv = netdev_priv(dev);
@@ -1274,7 +1237,7 @@ static int netwave_rx(struct net_device
 	if (skb == NULL) {
 	    DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
 		  "length %d\n", rcvLen);
-	    ++priv->stats.rx_dropped; 
+	    ++dev->stats.rx_dropped;
 	    /* Tell the adapter to skip the packet */
 	    wait_WOC(iobase);
 	    writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
@@ -1307,8 +1270,8 @@ static int netwave_rx(struct net_device
 	/* Queue packet for network layer */
 	netif_rx(skb);
 
-	priv->stats.rx_packets++;
-	priv->stats.rx_bytes += rcvLen;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += rcvLen;
 
 	/* Got the packet, tell the adapter to skip it */
 	wait_WOC(iobase);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/airport.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/airport.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/airport.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/airport.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,10 +3,10 @@
  * A driver for "Hermes" chipset based Apple Airport wireless
  * card.
  *
- * Copyright notice & release notes in file orinoco.c
- * 
+ * Copyright notice & release notes in file main.c
+ *
  * Note specific to airport stub:
- * 
+ *
  *  0.05 : first version of the new split driver
  *  0.06 : fix possible hang on powerup, add sleep support
  */
@@ -60,7 +60,8 @@ airport_suspend(struct macio_dev *mdev,
 	orinoco_unlock(priv, &flags);
 
 	disable_irq(dev->irq);
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(mdev), 0, 0);
 
 	return 0;
 }
@@ -75,7 +76,8 @@ airport_resume(struct macio_dev *mdev)
 
 	printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
 
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(mdev), 0, 1);
 	msleep(200);
 
 	enable_irq(dev->irq);
@@ -93,7 +95,7 @@ airport_resume(struct macio_dev *mdev)
 
 	priv->hw_unavailable--;
 
-	if (priv->open && (! priv->hw_unavailable)) {
+	if (priv->open && (!priv->hw_unavailable)) {
 		err = __orinoco_up(dev);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
@@ -127,7 +129,8 @@ airport_detach(struct macio_dev *mdev)
 
 	macio_release_resource(mdev, 0);
 
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(mdev), 0, 0);
 	ssleep(1);
 
 	macio_set_drvdata(mdev, NULL);
@@ -153,9 +156,11 @@ static int airport_hard_reset(struct ori
 	 * off. */
 	disable_irq(dev->irq);
 
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(card->mdev), 0, 0);
 	ssleep(1);
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(card->mdev), 0, 1);
 	ssleep(1);
 
 	enable_irq(dev->irq);
@@ -182,7 +187,7 @@ airport_attach(struct macio_dev *mdev, c
 	/* Allocate space for private device-specific data */
 	dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
 			       airport_hard_reset, NULL);
-	if (! dev) {
+	if (!dev) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		return -ENODEV;
 	}
@@ -214,9 +219,10 @@ airport_attach(struct macio_dev *mdev, c
 	}
 
 	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
-		
+
 	/* Power up card */
-	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+			  macio_get_of_node(mdev), 0, 1);
 	ssleep(1);
 
 	/* Reset it before we get the interrupt */
@@ -248,7 +254,7 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <b
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 
-static struct of_device_id airport_match[] = 
+static struct of_device_id airport_match[] =
 {
 	{
 	.name 		= "radio",
@@ -256,10 +262,9 @@ static struct of_device_id airport_match
 	{},
 };
 
-MODULE_DEVICE_TABLE (of, airport_match);
+MODULE_DEVICE_TABLE(of, airport_match);
 
-static struct macio_driver airport_driver = 
-{
+static struct macio_driver airport_driver = {
 	.name 		= DRIVER_NAME,
 	.match_table	= airport_match,
 	.probe		= airport_attach,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/fw.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/fw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/fw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/fw.c	2013-05-03 16:48:05.000000000 -0400
@@ -0,0 +1,390 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+
+#include "hermes.h"
+#include "hermes_dld.h"
+#include "orinoco.h"
+
+#include "fw.h"
+
+/* End markers (for Symbol firmware only) */
+#define TEXT_END	0x1A		/* End of text header */
+
+struct fw_info {
+	char *pri_fw;
+	char *sta_fw;
+	char *ap_fw;
+	u32 pda_addr;
+	u16 pda_size;
+};
+
+static const struct fw_info orinoco_fw[] = {
+	{ NULL, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", 0x00390000, 1000 },
+	{ NULL, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", 0, 1024 },
+	{ "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", NULL, 0x00003100, 512 }
+};
+
+/* Structure used to access fields in FW
+ * Make sure LE decoding macros are used
+ */
+struct orinoco_fw_header {
+	char hdr_vers[6];       /* ASCII string for header version */
+	__le16 headersize;      /* Total length of header */
+	__le32 entry_point;     /* NIC entry point */
+	__le32 blocks;          /* Number of blocks to program */
+	__le32 block_offset;    /* Offset of block data from eof header */
+	__le32 pdr_offset;      /* Offset to PDR data from eof header */
+	__le32 pri_offset;      /* Offset to primary plug data */
+	__le32 compat_offset;   /* Offset to compatibility data*/
+	char signature[0];      /* FW signature length headersize-20 */
+} __attribute__ ((packed));
+
+/* Check the range of various header entries. Return a pointer to a
+ * description of the problem, or NULL if everything checks out. */
+static const char *validate_fw(const struct orinoco_fw_header *hdr, size_t len)
+{
+	u16 hdrsize;
+
+	if (len < sizeof(*hdr))
+		return "image too small";
+	if (memcmp(hdr->hdr_vers, "HFW", 3) != 0)
+		return "format not recognised";
+
+	hdrsize = le16_to_cpu(hdr->headersize);
+	if (hdrsize > len)
+		return "bad headersize";
+	if ((hdrsize + le32_to_cpu(hdr->block_offset)) > len)
+		return "bad block offset";
+	if ((hdrsize + le32_to_cpu(hdr->pdr_offset)) > len)
+		return "bad PDR offset";
+	if ((hdrsize + le32_to_cpu(hdr->pri_offset)) > len)
+		return "bad PRI offset";
+	if ((hdrsize + le32_to_cpu(hdr->compat_offset)) > len)
+		return "bad compat offset";
+
+	/* TODO: consider adding a checksum or CRC to the firmware format */
+	return NULL;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+static inline const struct firmware *
+orinoco_cached_fw_get(struct orinoco_private *priv, bool primary)
+{
+	if (primary)
+		return priv->cached_pri_fw;
+	else
+		return priv->cached_fw;
+}
+#else
+#define orinoco_cached_fw_get(priv, primary) (NULL)
+#endif
+
+/* Download either STA or AP firmware into the card. */
+static int
+orinoco_dl_firmware(struct orinoco_private *priv,
+		    const struct fw_info *fw,
+		    int ap)
+{
+	/* Plug Data Area (PDA) */
+	__le16 *pda;
+
+	hermes_t *hw = &priv->hw;
+	const struct firmware *fw_entry;
+	const struct orinoco_fw_header *hdr;
+	const unsigned char *first_block;
+	const void *end;
+	const char *firmware;
+	const char *fw_err;
+	struct net_device *dev = priv->ndev;
+	int err = 0;
+
+	pda = kzalloc(fw->pda_size, GFP_KERNEL);
+	if (!pda)
+		return -ENOMEM;
+
+	if (ap)
+		firmware = fw->ap_fw;
+	else
+		firmware = fw->sta_fw;
+
+	printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
+	       dev->name, firmware);
+
+	/* Read current plug data */
+	err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
+	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+	if (err)
+		goto free;
+
+	if (!orinoco_cached_fw_get(priv, false)) {
+		err = reject_firmware(&fw_entry, firmware, priv->dev);
+
+		if (err) {
+			printk(KERN_ERR "%s: Cannot find firmware %s\n",
+			       dev->name, firmware);
+			err = -ENOENT;
+			goto free;
+		}
+	} else
+		fw_entry = orinoco_cached_fw_get(priv, false);
+
+	hdr = (const struct orinoco_fw_header *) fw_entry->data;
+
+	fw_err = validate_fw(hdr, fw_entry->size);
+	if (fw_err) {
+		printk(KERN_WARNING "%s: Invalid firmware image detected (%s). "
+		       "Aborting download\n",
+		       dev->name, fw_err);
+		err = -EINVAL;
+		goto abort;
+	}
+
+	/* Enable aux port to allow programming */
+	err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
+	printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+	if (err != 0)
+		goto abort;
+
+	/* Program data */
+	first_block = (fw_entry->data +
+		       le16_to_cpu(hdr->headersize) +
+		       le32_to_cpu(hdr->block_offset));
+	end = fw_entry->data + fw_entry->size;
+
+	err = hermes_program(hw, first_block, end);
+	printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+	if (err != 0)
+		goto abort;
+
+	/* Update production data */
+	first_block = (fw_entry->data +
+		       le16_to_cpu(hdr->headersize) +
+		       le32_to_cpu(hdr->pdr_offset));
+
+	err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
+					     &pda[fw->pda_size / sizeof(*pda)]);
+	printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+	if (err)
+		goto abort;
+
+	/* Tell card we've finished */
+	err = hermesi_program_end(hw);
+	printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+	if (err != 0)
+		goto abort;
+
+	/* Check if we're running */
+	printk(KERN_DEBUG "%s: hermes_present returned %d\n",
+	       dev->name, hermes_present(hw));
+
+abort:
+	/* If we requested the firmware, release it. */
+	if (!orinoco_cached_fw_get(priv, false))
+		release_firmware(fw_entry);
+
+free:
+	kfree(pda);
+	return err;
+}
+
+/*
+ * Process a firmware image - stop the card, load the firmware, reset
+ * the card and make sure it responds.  For the secondary firmware take
+ * care of the PDA - read it and then write it on top of the firmware.
+ */
+static int
+symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
+		const unsigned char *image, const void *end,
+		int secondary)
+{
+	hermes_t *hw = &priv->hw;
+	int ret = 0;
+	const unsigned char *ptr;
+	const unsigned char *first_block;
+
+	/* Plug Data Area (PDA) */
+	__le16 *pda = NULL;
+
+	/* Binary block begins after the 0x1A marker */
+	ptr = image;
+	while (*ptr++ != TEXT_END);
+	first_block = ptr;
+
+	/* Read the PDA from EEPROM */
+	if (secondary) {
+		pda = kzalloc(fw->pda_size, GFP_KERNEL);
+		if (!pda)
+			return -ENOMEM;
+
+		ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
+		if (ret)
+			goto free;
+	}
+
+	/* Stop the firmware, so that it can be safely rewritten */
+	if (priv->stop_fw) {
+		ret = priv->stop_fw(priv, 1);
+		if (ret)
+			goto free;
+	}
+
+	/* Program the adapter with new firmware */
+	ret = hermes_program(hw, first_block, end);
+	if (ret)
+		goto free;
+
+	/* Write the PDA to the adapter */
+	if (secondary) {
+		size_t len = hermes_blocks_length(first_block, end);
+		ptr = first_block + len;
+		ret = hermes_apply_pda(hw, ptr, end, pda,
+				       &pda[fw->pda_size / sizeof(*pda)]);
+		kfree(pda);
+		if (ret)
+			return ret;
+	}
+
+	/* Run the firmware */
+	if (priv->stop_fw) {
+		ret = priv->stop_fw(priv, 0);
+		if (ret)
+			return ret;
+	}
+
+	/* Reset hermes chip and make sure it responds */
+	ret = hermes_init(hw);
+
+	/* hermes_reset() should return 0 with the secondary firmware */
+	if (secondary && ret != 0)
+		return -ENODEV;
+
+	/* And this should work with any firmware */
+	if (!hermes_present(hw))
+		return -ENODEV;
+
+	return 0;
+
+free:
+	kfree(pda);
+	return ret;
+}
+
+
+/*
+ * Download the firmware into the card, this also does a PCMCIA soft
+ * reset on the card, to make sure it's in a sane state.
+ */
+static int
+symbol_dl_firmware(struct orinoco_private *priv,
+		   const struct fw_info *fw)
+{
+	struct net_device *dev = priv->ndev;
+	int ret;
+	const struct firmware *fw_entry;
+
+	if (!orinoco_cached_fw_get(priv, true)) {
+		if (reject_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
+			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+			       dev->name, fw->pri_fw);
+			return -ENOENT;
+		}
+	} else
+		fw_entry = orinoco_cached_fw_get(priv, true);
+
+	/* Load primary firmware */
+	ret = symbol_dl_image(priv, fw, fw_entry->data,
+			      fw_entry->data + fw_entry->size, 0);
+
+	if (!orinoco_cached_fw_get(priv, true))
+		release_firmware(fw_entry);
+	if (ret) {
+		printk(KERN_ERR "%s: Primary firmware download failed\n",
+		       dev->name);
+		return ret;
+	}
+
+	if (!orinoco_cached_fw_get(priv, false)) {
+		if (reject_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
+			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+			       dev->name, fw->sta_fw);
+			return -ENOENT;
+		}
+	} else
+		fw_entry = orinoco_cached_fw_get(priv, false);
+
+	/* Load secondary firmware */
+	ret = symbol_dl_image(priv, fw, fw_entry->data,
+			      fw_entry->data + fw_entry->size, 1);
+	if (!orinoco_cached_fw_get(priv, false))
+		release_firmware(fw_entry);
+	if (ret) {
+		printk(KERN_ERR "%s: Secondary firmware download failed\n",
+		       dev->name);
+	}
+
+	return ret;
+}
+
+int orinoco_download(struct orinoco_private *priv)
+{
+	int err = 0;
+	/* Reload firmware */
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		/* case FIRMWARE_TYPE_INTERSIL: */
+		err = orinoco_dl_firmware(priv,
+					  &orinoco_fw[priv->firmware_type], 0);
+		break;
+
+	case FIRMWARE_TYPE_SYMBOL:
+		err = symbol_dl_firmware(priv,
+					 &orinoco_fw[priv->firmware_type]);
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		break;
+	}
+	/* TODO: if we fail we probably need to reinitialise
+	 * the driver */
+
+	return err;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap)
+{
+	const struct firmware *fw_entry = NULL;
+	const char *pri_fw;
+	const char *fw;
+
+	pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
+	if (ap)
+		fw = orinoco_fw[priv->firmware_type].ap_fw;
+	else
+		fw = orinoco_fw[priv->firmware_type].sta_fw;
+
+	if (pri_fw) {
+		if (reject_firmware(&fw_entry, pri_fw, priv->dev) == 0)
+			priv->cached_pri_fw = fw_entry;
+	}
+
+	if (fw) {
+		if (reject_firmware(&fw_entry, fw, priv->dev) == 0)
+			priv->cached_fw = fw_entry;
+	}
+}
+
+void orinoco_uncache_fw(struct orinoco_private *priv)
+{
+	if (priv->cached_pri_fw)
+		release_firmware(priv->cached_pri_fw);
+	if (priv->cached_fw)
+		release_firmware(priv->cached_fw);
+
+	priv->cached_pri_fw = NULL;
+	priv->cached_fw = NULL;
+}
+#endif
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/fw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/fw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/fw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/fw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,21 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_FW_H_
+#define _ORINOCO_FW_H_
+
+/* Forward declations */
+struct orinoco_private;
+
+int orinoco_download(struct orinoco_private *priv);
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap);
+void orinoco_uncache_fw(struct orinoco_private *priv);
+#else
+#define orinoco_cache_fw(priv, ap) do { } while(0)
+#define orinoco_uncache_fw(priv) do { } while (0)
+#endif
+
+#endif /* _ORINOCO_FW_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,7 @@
  *
  * Copyright (C) 2000, David Gibson, Linuxcare Australia.
  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
- * 
+ *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * compliance with the License. You may obtain a copy of the License
@@ -45,11 +45,6 @@
 
 #include "hermes.h"
 
-MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
-	" & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_LICENSE("Dual MPL/GPL");
-
 /* These are maximum timeouts. Most often, card wil react much faster */
 #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
 #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
@@ -61,13 +56,13 @@ MODULE_LICENSE("Dual MPL/GPL");
  */
 
 #define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
-			printk(stuff);} while (0)
+			printk(stuff); } while (0)
 
 #undef HERMES_DEBUG
 #ifdef HERMES_DEBUG
 #include <stdarg.h>
 
-#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
+#define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff)
 
 #else /* ! HERMES_DEBUG */
 
@@ -95,20 +90,19 @@ static int hermes_issue_cmd(hermes_t *hw
 
 	/* First wait for the command register to unbusy */
 	reg = hermes_read_regn(hw, CMD);
-	while ( (reg & HERMES_CMD_BUSY) && k ) {
+	while ((reg & HERMES_CMD_BUSY) && k) {
 		k--;
 		udelay(1);
 		reg = hermes_read_regn(hw, CMD);
 	}
-	if (reg & HERMES_CMD_BUSY) {
+	if (reg & HERMES_CMD_BUSY)
 		return -EBUSY;
-	}
 
 	hermes_write_regn(hw, PARAM2, param2);
 	hermes_write_regn(hw, PARAM1, param1);
 	hermes_write_regn(hw, PARAM0, param0);
 	hermes_write_regn(hw, CMD, cmd);
-	
+
 	return 0;
 }
 
@@ -191,23 +185,23 @@ int hermes_init(hermes_t *hw)
 	hermes_write_regn(hw, EVACK, 0xffff);
 
 	/* Normally it's a "can't happen" for the command register to
-           be busy when we go to issue a command because we are
-           serializing all commands.  However we want to have some
-           chance of resetting the card even if it gets into a stupid
-           state, so we actually wait to see if the command register
-           will unbusy itself here. */
+	   be busy when we go to issue a command because we are
+	   serializing all commands.  However we want to have some
+	   chance of resetting the card even if it gets into a stupid
+	   state, so we actually wait to see if the command register
+	   will unbusy itself here. */
 	k = CMD_BUSY_TIMEOUT;
 	reg = hermes_read_regn(hw, CMD);
 	while (k && (reg & HERMES_CMD_BUSY)) {
-		if (reg == 0xffff) /* Special case - the card has probably been removed,
-				      so don't wait for the timeout */
+		if (reg == 0xffff) /* Special case - the card has probably been
+				      removed, so don't wait for the timeout */
 			return -ENODEV;
 
 		k--;
 		udelay(1);
 		reg = hermes_read_regn(hw, CMD);
 	}
-	
+
 	/* No need to explicitly handle the timeout - if we've timed
 	   out hermes_issue_cmd() will probably return -EBUSY below */
 
@@ -228,7 +222,10 @@ EXPORT_SYMBOL(hermes_init);
 /* Issue a command to the chip, and (busy!) wait for it to
  * complete.
  *
- * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
+ * Returns:
+ *     < 0 on internal error
+ *       0 on success
+ *     > 0 on error returned by the firmware
  *
  * Callable from any context, but locking is your problem. */
 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
@@ -241,13 +238,13 @@ int hermes_docmd_wait(hermes_t *hw, u16
 
 	err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
 	if (err) {
-		if (! hermes_present(hw)) {
+		if (!hermes_present(hw)) {
 			if (net_ratelimit())
 				printk(KERN_WARNING "hermes @ %p: "
 				       "Card removed while issuing command "
 				       "0x%04x.\n", hw->iobase, cmd);
 			err = -ENODEV;
-		} else 
+		} else
 			if (net_ratelimit())
 				printk(KERN_ERR "hermes @ %p: "
 				       "Error %d issuing command 0x%04x.\n",
@@ -257,21 +254,21 @@ int hermes_docmd_wait(hermes_t *hw, u16
 
 	reg = hermes_read_regn(hw, EVSTAT);
 	k = CMD_COMPL_TIMEOUT;
-	while ( (! (reg & HERMES_EV_CMD)) && k) {
+	while ((!(reg & HERMES_EV_CMD)) && k) {
 		k--;
 		udelay(10);
 		reg = hermes_read_regn(hw, EVSTAT);
 	}
 
-	if (! hermes_present(hw)) {
+	if (!hermes_present(hw)) {
 		printk(KERN_WARNING "hermes @ %p: Card removed "
 		       "while waiting for command 0x%04x completion.\n",
 		       hw->iobase, cmd);
 		err = -ENODEV;
 		goto out;
 	}
-		
-	if (! (reg & HERMES_EV_CMD)) {
+
+	if (!(reg & HERMES_EV_CMD)) {
 		printk(KERN_ERR "hermes @ %p: Timeout waiting for "
 		       "command 0x%04x completion.\n", hw->iobase, cmd);
 		err = -ETIMEDOUT;
@@ -301,31 +298,30 @@ int hermes_allocate(hermes_t *hw, u16 si
 	int err = 0;
 	int k;
 	u16 reg;
-	
-	if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
+
+	if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX))
 		return -EINVAL;
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
-	if (err) {
+	if (err)
 		return err;
-	}
 
 	reg = hermes_read_regn(hw, EVSTAT);
 	k = ALLOC_COMPL_TIMEOUT;
-	while ( (! (reg & HERMES_EV_ALLOC)) && k) {
+	while ((!(reg & HERMES_EV_ALLOC)) && k) {
 		k--;
 		udelay(10);
 		reg = hermes_read_regn(hw, EVSTAT);
 	}
-	
-	if (! hermes_present(hw)) {
+
+	if (!hermes_present(hw)) {
 		printk(KERN_WARNING "hermes @ %p: "
 		       "Card removed waiting for frame allocation.\n",
 		       hw->iobase);
 		return -ENODEV;
 	}
-		
-	if (! (reg & HERMES_EV_ALLOC)) {
+
+	if (!(reg & HERMES_EV_ALLOC)) {
 		printk(KERN_ERR "hermes @ %p: "
 		       "Timeout waiting for frame allocation\n",
 		       hw->iobase);
@@ -334,14 +330,17 @@ int hermes_allocate(hermes_t *hw, u16 si
 
 	*fid = hermes_read_regn(hw, ALLOCFID);
 	hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
-	
+
 	return 0;
 }
 EXPORT_SYMBOL(hermes_allocate);
 
 /* Set up a BAP to read a particular chunk of data from card's internal buffer.
  *
- * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
+ * Returns:
+ *     < 0 on internal failure (errno)
+ *       0 on success
+ *     > 0 on error
  * from firmware
  *
  * Callable from any context */
@@ -353,7 +352,7 @@ static int hermes_bap_seek(hermes_t *hw,
 	u16 reg;
 
 	/* Paranoia.. */
-	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
+	if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
 		return -EINVAL;
 
 	k = HERMES_BAP_BUSY_TIMEOUT;
@@ -374,7 +373,7 @@ static int hermes_bap_seek(hermes_t *hw,
 	/* Wait for the BAP to be ready */
 	k = HERMES_BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
-	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
+	while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
 		k--;
 		udelay(1);
 		reg = hermes_read_reg(hw, oreg);
@@ -386,9 +385,8 @@ static int hermes_bap_seek(hermes_t *hw,
 		       (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
 		       reg, id, offset);
 
-		if (reg & HERMES_OFFSET_BUSY) {
+		if (reg & HERMES_OFFSET_BUSY)
 			return -ETIMEDOUT;
-		}
 
 		return -EIO;		/* error or wrong offset */
 	}
@@ -400,7 +398,10 @@ static int hermes_bap_seek(hermes_t *hw,
  * BAP. Synchronization/serialization is the caller's problem.  len
  * must be even.
  *
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ *     < 0 on internal failure (errno)
+ *       0 on success
+ *     > 0 on error from firmware
  */
 int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
 		     u16 id, u16 offset)
@@ -408,7 +409,7 @@ int hermes_bap_pread(hermes_t *hw, int b
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
 
-	if ( (len < 0) || (len % 2) )
+	if ((len < 0) || (len % 2))
 		return -EINVAL;
 
 	err = hermes_bap_seek(hw, bap, id, offset);
@@ -426,7 +427,10 @@ EXPORT_SYMBOL(hermes_bap_pread);
 /* Write a block of data to the chip's buffer, via the
  * BAP. Synchronization/serialization is the caller's problem.
  *
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ *     < 0 on internal failure (errno)
+ *       0 on success
+ *     > 0 on error from firmware
  */
 int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
 		      u16 id, u16 offset)
@@ -440,11 +444,11 @@ int hermes_bap_pwrite(hermes_t *hw, int
 	err = hermes_bap_seek(hw, bap, id, offset);
 	if (err)
 		goto out;
-	
+
 	/* Actually do the transfer */
 	hermes_write_bytes(hw, dreg, buf, len);
 
- out:	
+ out:
 	return err;
 }
 EXPORT_SYMBOL(hermes_bap_pwrite);
@@ -465,7 +469,7 @@ int hermes_read_ltv(hermes_t *hw, int ba
 	u16 rlength, rtype;
 	unsigned nwords;
 
-	if ( (bufsize < 0) || (bufsize % 2) )
+	if ((bufsize < 0) || (bufsize % 2))
 		return -EINVAL;
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
@@ -478,7 +482,7 @@ int hermes_read_ltv(hermes_t *hw, int ba
 
 	rlength = hermes_read_reg(hw, dreg);
 
-	if (! rlength)
+	if (!rlength)
 		return -ENODATA;
 
 	rtype = hermes_read_reg(hw, dreg);
@@ -503,7 +507,7 @@ int hermes_read_ltv(hermes_t *hw, int ba
 }
 EXPORT_SYMBOL(hermes_read_ltv);
 
-int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
 		     u16 length, const void *value)
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -530,15 +534,3 @@ int hermes_write_ltv(hermes_t *hw, int b
 	return err;
 }
 EXPORT_SYMBOL(hermes_write_ltv);
-
-static int __init init_hermes(void)
-{
-	return 0;
-}
-
-static void __exit exit_hermes(void)
-{
-}
-
-module_init(init_hermes);
-module_exit(exit_hermes);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes_dld.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes_dld.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes_dld.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes_dld.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,13 +1,7 @@
 /*
- * Hermes download helper driver.
- *
- * This could be entirely merged into hermes.c.
- *
- * I'm keeping it separate to minimise the amount of merging between
- * kernel upgrades. It also means the memory overhead for drivers that
- * don't need firmware download low.
+ * Hermes download helper.
  *
- * This driver:
+ * This helper:
  *  - is capable of writing to the volatile area of the hermes device
  *  - is currently not capable of writing to non-volatile areas
  *  - provide helpers to identify and update plugin data
@@ -50,10 +44,6 @@
 #include "hermes.h"
 #include "hermes_dld.h"
 
-MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
-MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
-MODULE_LICENSE("Dual MPL/GPL");
-
 #define PFX "hermes_dld: "
 
 /*
@@ -81,18 +71,6 @@ MODULE_LICENSE("Dual MPL/GPL");
 #define BLOCK_END	0xFFFFFFFF	/* Last image block */
 #define TEXT_END	0x1A		/* End of text header */
 
-/*
- * PDA == Production Data Area
- *
- * In principle, the max. size of the PDA is is 4096 words. Currently,
- * however, only about 500 bytes of this area are used.
- *
- * Some USB implementations can't handle sizes in excess of 1016. Note
- * that PDA is not actually used in those USB environments, but may be
- * retrieved by common code.
- */
-#define MAX_PDA_SIZE	1000
-
 /* Limit the amout we try to download in a single shot.
  * Size is in bytes.
  */
@@ -228,13 +206,14 @@ hermes_aux_control(hermes_t *hw, int ena
  * Scan PDR for the record with the specified RECORD_ID.
  * If it's not found, return NULL.
  */
-static struct pdr *
-hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
+static const struct pdr *
+hermes_find_pdr(const struct pdr *first_pdr, u32 record_id, const void *end)
 {
-	struct pdr *pdr = first_pdr;
-	void *end = (void *)first_pdr + MAX_PDA_SIZE;
+	const struct pdr *pdr = first_pdr;
 
-	while (((void *)pdr < end) &&
+	end -= sizeof(struct pdr);
+
+	while (((void *) pdr <= end) &&
 	       (pdr_id(pdr) != PDI_END)) {
 		/*
 		 * PDR area is currently not terminated by PDI_END.
@@ -254,12 +233,15 @@ hermes_find_pdr(struct pdr *first_pdr, u
 }
 
 /* Scan production data items for a particular entry */
-static struct pdi *
-hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
+static const struct pdi *
+hermes_find_pdi(const struct pdi *first_pdi, u32 record_id, const void *end)
 {
-	struct pdi *pdi = first_pdi;
+	const struct pdi *pdi = first_pdi;
 
-	while (pdi_id(pdi) != PDI_END) {
+	end -= sizeof(struct pdi);
+
+	while (((void *) pdi <= end) &&
+	       (pdi_id(pdi) != PDI_END)) {
 
 		/* If the record ID matches, we are done */
 		if (pdi_id(pdi) == record_id)
@@ -272,12 +254,13 @@ hermes_find_pdi(struct pdi *first_pdi, u
 
 /* Process one Plug Data Item - find corresponding PDR and plug it */
 static int
-hermes_plug_pdi(hermes_t *hw, struct pdr *first_pdr, const struct pdi *pdi)
+hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
+		const struct pdi *pdi, const void *pdr_end)
 {
-	struct pdr *pdr;
+	const struct pdr *pdr;
 
 	/* Find the PDR corresponding to this PDI */
-	pdr = hermes_find_pdr(first_pdr, pdi_id(pdi));
+	pdr = hermes_find_pdr(first_pdr, pdi_id(pdi), pdr_end);
 
 	/* No match is found, safe to ignore */
 	if (!pdr)
@@ -347,7 +330,6 @@ int hermes_read_pda(hermes_t *hw,
 
 	return 0;
 }
-EXPORT_SYMBOL(hermes_read_pda);
 
 /* Parse PDA and write the records into the adapter
  *
@@ -356,18 +338,22 @@ EXPORT_SYMBOL(hermes_read_pda);
  */
 int hermes_apply_pda(hermes_t *hw,
 		     const char *first_pdr,
-		     const __le16 *pda)
+		     const void *pdr_end,
+		     const __le16 *pda,
+		     const void *pda_end)
 {
 	int ret;
 	const struct pdi *pdi;
-	struct pdr *pdr;
+	const struct pdr *pdr;
 
-	pdr = (struct pdr *) first_pdr;
+	pdr = (const struct pdr *) first_pdr;
+	pda_end -= sizeof(struct pdi);
 
 	/* Go through every PDI and plug them into the adapter */
 	pdi = (const struct pdi *) (pda + 2);
-	while (pdi_id(pdi) != PDI_END) {
-		ret = hermes_plug_pdi(hw, pdr, pdi);
+	while (((void *) pdi <= pda_end) &&
+	       (pdi_id(pdi) != PDI_END)) {
+		ret = hermes_plug_pdi(hw, pdr, pdi, pdr_end);
 		if (ret)
 			return ret;
 
@@ -376,21 +362,23 @@ int hermes_apply_pda(hermes_t *hw,
 	}
 	return 0;
 }
-EXPORT_SYMBOL(hermes_apply_pda);
 
 /* Identify the total number of bytes in all blocks
  * including the header data.
  */
 size_t
-hermes_blocks_length(const char *first_block)
+hermes_blocks_length(const char *first_block, const void *end)
 {
 	const struct dblock *blk = (const struct dblock *) first_block;
 	int total_len = 0;
 	int len;
 
+	end -= sizeof(*blk);
+
 	/* Skip all blocks to locate Plug Data References
 	 * (Spectrum CS) */
-	while (dblock_addr(blk) != BLOCK_END) {
+	while (((void *) blk <= end) &&
+	       (dblock_addr(blk) != BLOCK_END)) {
 		len = dblock_len(blk);
 		total_len += sizeof(*blk) + len;
 		blk = (struct dblock *) &blk->data[len];
@@ -398,7 +386,6 @@ hermes_blocks_length(const char *first_b
 
 	return total_len;
 }
-EXPORT_SYMBOL(hermes_blocks_length);
 
 /*** Hermes programming ***/
 
@@ -452,7 +439,6 @@ int hermesi_program_init(hermes_t *hw, u
 
 	return err;
 }
-EXPORT_SYMBOL(hermesi_program_init);
 
 /* Done programming data (Hermes I)
  *
@@ -488,10 +474,9 @@ int hermesi_program_end(hermes_t *hw)
 
 	return rc ? rc : err;
 }
-EXPORT_SYMBOL(hermesi_program_end);
 
 /* Program the data blocks */
-int hermes_program(hermes_t *hw, const char *first_block, const char *end)
+int hermes_program(hermes_t *hw, const char *first_block, const void *end)
 {
 	const struct dblock *blk;
 	u32 blkaddr;
@@ -503,14 +488,14 @@ int hermes_program(hermes_t *hw, const c
 
 	blk = (const struct dblock *) first_block;
 
-	if ((const char *) blk > (end - sizeof(*blk)))
+	if ((void *) blk > (end - sizeof(*blk)))
 		return -EIO;
 
 	blkaddr = dblock_addr(blk);
 	blklen = dblock_len(blk);
 
 	while ((blkaddr != BLOCK_END) &&
-	       (((const char *) blk + blklen) <= end)) {
+	       (((void *) blk + blklen) <= end)) {
 		printk(KERN_DEBUG PFX
 		       "Programming block of length %d to address 0x%08x\n",
 		       blklen, blkaddr);
@@ -542,7 +527,7 @@ int hermes_program(hermes_t *hw, const c
 #endif
 		blk = (const struct dblock *) &blk->data[blklen];
 
-		if ((const char *) blk > (end - sizeof(*blk)))
+		if ((void *) blk > (end - sizeof(*blk)))
 			return -EIO;
 
 		blkaddr = dblock_addr(blk);
@@ -550,19 +535,6 @@ int hermes_program(hermes_t *hw, const c
 	}
 	return 0;
 }
-EXPORT_SYMBOL(hermes_program);
-
-static int __init init_hermes_dld(void)
-{
-	return 0;
-}
-
-static void __exit exit_hermes_dld(void)
-{
-}
-
-module_init(init_hermes_dld);
-module_exit(exit_hermes_dld);
 
 /*** Default plugging data for Hermes I ***/
 /* Values from wl_lkm_718/hcf/dhf.c */
@@ -573,9 +545,9 @@ static const struct {							\
 	__le16 id;							\
 	u8 val[length];							\
 } __attribute__ ((packed)) default_pdr_data_##pid = {			\
-	__constant_cpu_to_le16((sizeof(default_pdr_data_##pid)/		\
+	cpu_to_le16((sizeof(default_pdr_data_##pid)/			\
 				sizeof(__le16)) - 1),			\
-	__constant_cpu_to_le16(pid),					\
+	cpu_to_le16(pid),						\
 	data								\
 }
 
@@ -644,17 +616,20 @@ DEFINE_DEFAULT_PDR(0x0161, 256,
  */
 int hermes_apply_pda_with_defaults(hermes_t *hw,
 				   const char *first_pdr,
-				   const __le16 *pda)
+				   const void *pdr_end,
+				   const __le16 *pda,
+				   const void *pda_end)
 {
 	const struct pdr *pdr = (const struct pdr *) first_pdr;
-	struct pdi *first_pdi = (struct pdi *) &pda[2];
-	struct pdi *pdi;
-	struct pdi *default_pdi = NULL;
-	struct pdi *outdoor_pdi;
-	void *end = (void *)first_pdr + MAX_PDA_SIZE;
+	const struct pdi *first_pdi = (const struct pdi *) &pda[2];
+	const struct pdi *pdi;
+	const struct pdi *default_pdi = NULL;
+	const struct pdi *outdoor_pdi;
 	int record_id;
 
-	while (((void *)pdr < end) &&
+	pdr_end -= sizeof(struct pdr);
+
+	while (((void *) pdr <= pdr_end) &&
 	       (pdr_id(pdr) != PDI_END)) {
 		/*
 		 * For spectrum_cs firmwares,
@@ -666,7 +641,7 @@ int hermes_apply_pda_with_defaults(herme
 			break;
 		record_id = pdr_id(pdr);
 
-		pdi = hermes_find_pdi(first_pdi, record_id);
+		pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
 		if (pdi)
 			printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
 			       record_id, pdi);
@@ -674,7 +649,8 @@ int hermes_apply_pda_with_defaults(herme
 		switch (record_id) {
 		case 0x110: /* Modem REFDAC values */
 		case 0x120: /* Modem VGDAC values */
-			outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1);
+			outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1,
+						      pda_end);
 			default_pdi = NULL;
 			if (outdoor_pdi) {
 				pdi = outdoor_pdi;
@@ -715,7 +691,8 @@ int hermes_apply_pda_with_defaults(herme
 
 		if (pdi) {
 			/* Lengths of the data in PDI and PDR must match */
-			if (pdi_len(pdi) == pdr_len(pdr)) {
+			if ((pdi_len(pdi) == pdr_len(pdr)) &&
+			    ((void *) pdi->data + pdi_len(pdi) < pda_end)) {
 				/* do the actual plugging */
 				hermes_aux_setaddr(hw, pdr_addr(pdr));
 				hermes_write_bytes(hw, HERMES_AUXDATA,
@@ -727,4 +704,3 @@ int hermes_apply_pda_with_defaults(herme
 	}
 	return 0;
 }
-EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes_dld.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes_dld.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes_dld.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes_dld.h	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@
 
 int hermesi_program_init(hermes_t *hw, u32 offset);
 int hermesi_program_end(hermes_t *hw);
-int hermes_program(hermes_t *hw, const char *first_block, const char *end);
+int hermes_program(hermes_t *hw, const char *first_block, const void *end);
 
 int hermes_read_pda(hermes_t *hw,
 		    __le16 *pda,
@@ -38,11 +38,15 @@ int hermes_read_pda(hermes_t *hw,
 		    int use_eeprom);
 int hermes_apply_pda(hermes_t *hw,
 		     const char *first_pdr,
-		     const __le16 *pda);
+		     const void *pdr_end,
+		     const __le16 *pda,
+		     const void *pda_end);
 int hermes_apply_pda_with_defaults(hermes_t *hw,
 				   const char *first_pdr,
-				   const __le16 *pda);
+				   const void *pdr_end,
+				   const __le16 *pda,
+				   const void *pda_end);
 
-size_t hermes_blocks_length(const char *first_block);
+size_t hermes_blocks_length(const char *first_block, const void *end);
 
 #endif /* _HERMES_DLD_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hermes.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hermes.h	2009-06-09 23:05:27.000000000 -0400
@@ -15,7 +15,8 @@
  * Copyright (C) 2000, David Gibson, Linuxcare Australia.
  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
  *
- * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ * Portions taken from hfa384x.h.
+ * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
  *
  * This file distributed under the GPL, version 2.
  */
@@ -31,7 +32,7 @@
 */
 
 #include <linux/if_ether.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /*
  * Limits and constants
@@ -203,7 +204,7 @@ struct hermes_tx_descriptor {
 	__le32 sw_support;
 	u8 retry_count;
 	u8 tx_rate;
-	__le16 tx_control;	
+	__le16 tx_control;
 } __attribute__ ((packed));
 
 #define HERMES_TXSTAT_RETRYERR		(0x0001)
@@ -298,7 +299,7 @@ struct symbol_scan_apinfo {
 	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
 	__le16 essid_len;	/* ESSID length */
 	u8 essid[32];		/* ESSID of the network */
-    	__le16 rates[5];	/* Bit rate supported */
+	__le16 rates[5];	/* Bit rate supported */
 	__le16 basic_rates;	/* Basic rates bitmask */
 	u8 unknown2[6];		/* Always FF:FF:FF:FF:00:00 */
 	u8 unknown3[8];		/* Always 0, appeared in f/w 3.91-68 */
@@ -344,14 +345,14 @@ struct agere_ext_scan_info {
 	u8	data[316];
 } __attribute__ ((packed));
 
-#define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)  
+#define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)
 #define HERMES_LINKSTATUS_CONNECTED       (0x0001)
 #define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
 #define HERMES_LINKSTATUS_AP_CHANGE       (0x0003)
 #define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
 #define HERMES_LINKSTATUS_AP_IN_RANGE     (0x0005)
 #define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
-  
+
 struct hermes_linkstatus {
 	__le16 linkstatus;         /* Link status */
 } __attribute__ ((packed));
@@ -384,11 +385,12 @@ typedef struct hermes {
 
 /* Register access convenience macros */
 #define hermes_read_reg(hw, off) \
-	(ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+	(ioread16((hw)->iobase + ((off) << (hw)->reg_spacing)))
 #define hermes_write_reg(hw, off, val) \
 	(iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
 #define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
-#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
+#define hermes_write_regn(hw, name, val) \
+	hermes_write_reg((hw), HERMES_##name, (val))
 
 /* Function prototypes */
 void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
@@ -430,7 +432,7 @@ static inline int hermes_enable_port(her
 
 static inline int hermes_disable_port(hermes_t *hw, int port)
 {
-	return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
+	return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
 				 0, NULL);
 }
 
@@ -441,11 +443,12 @@ static inline int hermes_inquire(hermes_
 	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
 }
 
-#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
-#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
+#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
+#define HERMES_RECLEN_TO_BYTES(n) (((n)-1) * 2)
 
 /* Note that for the next two, the count is in 16-bit words, not bytes */
-static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
+static inline void hermes_read_words(struct hermes *hw, int off,
+				     void *buf, unsigned count)
 {
 	off = off << hw->reg_spacing;
 	ioread16_rep(hw->iobase + off, buf, count);
@@ -460,7 +463,8 @@ static inline void hermes_write_bytes(st
 		iowrite8(buf[count - 1], hw->iobase + off);
 }
 
-static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
+static inline void hermes_clear_words(struct hermes *hw, int off,
+				      unsigned count)
 {
 	unsigned i;
 
@@ -471,9 +475,10 @@ static inline void hermes_clear_words(st
 }
 
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
-	(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
+	(hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
 #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
-	(hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
+	(hermes_write_ltv((hw), (bap), (rid), \
+			  HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
 
 static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hw.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hw.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hw.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,584 @@
+/* Encapsulate basic setting changes and retrieval on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+
+/********************************************************************/
+/* Data tables                                                      */
+/********************************************************************/
+
+/* This tables gives the actual meanings of the bitrate IDs returned
+ * by the firmware. */
+static const struct {
+	int bitrate; /* in 100s of kilobits */
+	int automatic;
+	u16 agere_txratectrl;
+	u16 intersil_txratectrl;
+} bitrate_table[] = {
+	{110, 1,  3, 15}, /* Entry 0 is the default */
+	{10,  0,  1,  1},
+	{10,  1,  1,  1},
+	{20,  0,  2,  2},
+	{20,  1,  6,  3},
+	{55,  0,  4,  4},
+	{55,  1,  7,  7},
+	{110, 0,  5,  8},
+};
+#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
+
+int orinoco_get_bitratemode(int bitrate, int automatic)
+{
+	int ratemode = -1;
+	int i;
+
+	if ((bitrate != 10) && (bitrate != 20) &&
+	    (bitrate != 55) && (bitrate != 110))
+		return ratemode;
+
+	for (i = 0; i < BITRATE_TABLE_SIZE; i++) {
+		if ((bitrate_table[i].bitrate == bitrate) &&
+		    (bitrate_table[i].automatic == automatic)) {
+			ratemode = i;
+			break;
+		}
+	}
+	return ratemode;
+}
+
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
+{
+	BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
+
+	*bitrate = bitrate_table[ratemode].bitrate * 100000;
+	*automatic = bitrate_table[ratemode].automatic;
+}
+
+/* Get tsc from the firmware */
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
+
+	if ((key < 0) || (key > 4))
+		return -EINVAL;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
+			      sizeof(tsc_arr), NULL, &tsc_arr);
+	if (!err)
+		memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
+
+	return err;
+}
+
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	int ratemode = priv->bitratemode;
+	int err = 0;
+
+	if (ratemode >= BITRATE_TABLE_SIZE) {
+		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
+		       priv->ndev->name, ratemode);
+		return -EINVAL;
+	}
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		err = hermes_write_wordrec(hw, USER_BAP,
+				HERMES_RID_CNFTXRATECONTROL,
+				bitrate_table[ratemode].agere_txratectrl);
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+	case FIRMWARE_TYPE_SYMBOL:
+		err = hermes_write_wordrec(hw, USER_BAP,
+				HERMES_RID_CNFTXRATECONTROL,
+				bitrate_table[ratemode].intersil_txratectrl);
+		break;
+	default:
+		BUG();
+	}
+
+	return err;
+}
+
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
+{
+	hermes_t *hw = &priv->hw;
+	int i;
+	int err = 0;
+	u16 val;
+
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CURRENTTXRATE, &val);
+	if (err)
+		return err;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
+		/* Note : in Lucent firmware, the return value of
+		 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
+		 * and therefore is totally different from the
+		 * encoding of HERMES_RID_CNFTXRATECONTROL.
+		 * Don't forget that 6Mb/s is really 5.5Mb/s */
+		if (val == 6)
+			*bitrate = 5500000;
+		else
+			*bitrate = val * 1000000;
+		break;
+	case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
+	case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
+		for (i = 0; i < BITRATE_TABLE_SIZE; i++)
+			if (bitrate_table[i].intersil_txratectrl == val)
+				break;
+
+		if (i >= BITRATE_TABLE_SIZE)
+			printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
+			       priv->ndev->name, val);
+
+		*bitrate = bitrate_table[i].bitrate * 100000;
+		break;
+	default:
+		BUG();
+	}
+
+	return err;
+}
+
+/* Set fixed AP address */
+int __orinoco_hw_set_wap(struct orinoco_private *priv)
+{
+	int roaming_flag;
+	int err = 0;
+	hermes_t *hw = &priv->hw;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		/* not supported */
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		if (priv->bssid_fixed)
+			roaming_flag = 2;
+		else
+			roaming_flag = 1;
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFROAMINGMODE,
+					   roaming_flag);
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		err = HERMES_WRITE_RECORD(hw, USER_BAP,
+					  HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
+					  &priv->desired_bssid);
+		break;
+	}
+	return err;
+}
+
+/* Change the WEP keys and/or the current keys.  Can be called
+ * either from __orinoco_hw_setup_enc() or directly from
+ * orinoco_ioctl_setiwencode().  In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		err = HERMES_WRITE_RECORD(hw, USER_BAP,
+					  HERMES_RID_CNFWEPKEYS_AGERE,
+					  &priv->keys);
+		if (err)
+			return err;
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFTXKEY_AGERE,
+					   priv->tx_key);
+		if (err)
+			return err;
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+	case FIRMWARE_TYPE_SYMBOL:
+		{
+			int keylen;
+			int i;
+
+			/* Force uniform key length to work around
+			 * firmware bugs */
+			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
+
+			if (keylen > LARGE_KEY_SIZE) {
+				printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+				       priv->ndev->name, priv->tx_key, keylen);
+				return -E2BIG;
+			}
+
+			/* Write all 4 keys */
+			for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+				err = hermes_write_ltv(hw, USER_BAP,
+						HERMES_RID_CNFDEFAULTKEY0 + i,
+						HERMES_BYTES_TO_RECLEN(keylen),
+						priv->keys[i].data);
+				if (err)
+					return err;
+			}
+
+			/* Write the index of the key used in transmission */
+			err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFWEPDEFAULTKEYID,
+						priv->tx_key);
+			if (err)
+				return err;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+int __orinoco_hw_setup_enc(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	int master_wep_flag;
+	int auth_flag;
+	int enc_flag;
+
+	/* Setup WEP keys for WEP and WPA */
+	if (priv->encode_alg)
+		__orinoco_hw_setup_wepkeys(priv);
+
+	if (priv->wep_restrict)
+		auth_flag = HERMES_AUTH_SHARED_KEY;
+	else
+		auth_flag = HERMES_AUTH_OPEN;
+
+	if (priv->wpa_enabled)
+		enc_flag = 2;
+	else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
+		enc_flag = 1;
+	else
+		enc_flag = 0;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+			/* Enable the shared-key authentication. */
+			err = hermes_write_wordrec(hw, USER_BAP,
+					HERMES_RID_CNFAUTHENTICATION_AGERE,
+					auth_flag);
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFWEPENABLED_AGERE,
+					   enc_flag);
+		if (err)
+			return err;
+
+		if (priv->has_wpa) {
+			/* Set WPA key management */
+			err = hermes_write_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
+				  priv->key_mgmt);
+			if (err)
+				return err;
+		}
+
+		break;
+
+	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+			if (priv->wep_restrict ||
+			    (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+						  HERMES_WEP_EXCL_UNENCRYPTED;
+			else
+				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
+
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFAUTHENTICATION,
+						   auth_flag);
+			if (err)
+				return err;
+		} else
+			master_wep_flag = 0;
+
+		if (priv->iw_mode == IW_MODE_MONITOR)
+			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
+
+		/* Master WEP setting : on/off */
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFWEPFLAGS_INTERSIL,
+					   master_wep_flag);
+		if (err)
+			return err;
+
+		break;
+	}
+
+	return 0;
+}
+
+/* key must be 32 bytes, including the tx and rx MIC keys.
+ * rsc must be 8 bytes
+ * tsc must be 8 bytes or NULL
+ */
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+			      u8 *key, u8 *rsc, u8 *tsc)
+{
+	struct {
+		__le16 idx;
+		u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
+		u8 key[TKIP_KEYLEN];
+		u8 tx_mic[MIC_KEYLEN];
+		u8 rx_mic[MIC_KEYLEN];
+		u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+	} __attribute__ ((packed)) buf;
+	int ret;
+	int err;
+	int k;
+	u16 xmitting;
+
+	key_idx &= 0x3;
+
+	if (set_tx)
+		key_idx |= 0x8000;
+
+	buf.idx = cpu_to_le16(key_idx);
+	memcpy(buf.key, key,
+	       sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
+
+	if (rsc == NULL)
+		memset(buf.rsc, 0, sizeof(buf.rsc));
+	else
+		memcpy(buf.rsc, rsc, sizeof(buf.rsc));
+
+	if (tsc == NULL) {
+		memset(buf.tsc, 0, sizeof(buf.tsc));
+		buf.tsc[4] = 0x10;
+	} else {
+		memcpy(buf.tsc, tsc, sizeof(buf.tsc));
+	}
+
+	/* Wait upto 100ms for tx queue to empty */
+	for (k = 100; k > 0; k--) {
+		udelay(1000);
+		ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
+					  &xmitting);
+		if (ret || !xmitting)
+			break;
+	}
+
+	if (k == 0)
+		ret = -ETIMEDOUT;
+
+	err = HERMES_WRITE_RECORD(hw, USER_BAP,
+				  HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
+				  &buf);
+
+	return ret ? ret : err;
+}
+
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
+{
+	hermes_t *hw = &priv->hw;
+	int err;
+
+	memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
+	err = hermes_write_wordrec(hw, USER_BAP,
+				   HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
+				   key_idx);
+	if (err)
+		printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
+		       priv->ndev->name, err, key_idx);
+	return err;
+}
+
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+				    struct dev_addr_list *mc_list,
+				    int mc_count, int promisc)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+
+	if (promisc != priv->promiscuous) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPROMISCUOUSMODE,
+					   promisc);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+			       priv->ndev->name, err);
+		} else
+			priv->promiscuous = promisc;
+	}
+
+	/* If we're not in promiscuous mode, then we need to set the
+	 * group address if either we want to multicast, or if we were
+	 * multicasting and want to stop */
+	if (!promisc && (mc_count || priv->mc_count)) {
+		struct dev_mc_list *p = mc_list;
+		struct hermes_multicast mclist;
+		int i;
+
+		for (i = 0; i < mc_count; i++) {
+			/* paranoia: is list shorter than mc_count? */
+			BUG_ON(!p);
+			/* paranoia: bad address size in list? */
+			BUG_ON(p->dmi_addrlen != ETH_ALEN);
+
+			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+			p = p->next;
+		}
+
+		if (p)
+			printk(KERN_WARNING "%s: Multicast list is "
+			       "longer than mc_count\n", priv->ndev->name);
+
+		err = hermes_write_ltv(hw, USER_BAP,
+				   HERMES_RID_CNFGROUPADDRESSES,
+				   HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
+				   &mclist);
+		if (err)
+			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+			       priv->ndev->name, err);
+		else
+			priv->mc_count = mc_count;
+	}
+	return err;
+}
+
+/* Return : < 0 -> error code ; >= 0 -> length */
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+			 char buf[IW_ESSID_MAX_SIZE+1])
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	struct hermes_idstring essidbuf;
+	char *p = (char *)(&essidbuf.val);
+	int len;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (strlen(priv->desired_essid) > 0) {
+		/* We read the desired SSID from the hardware rather
+		   than from priv->desired_essid, just in case the
+		   firmware is allowed to change it on us. I'm not
+		   sure about this */
+		/* My guess is that the OWNSSID should always be whatever
+		 * we set to the card, whereas CURRENT_SSID is the one that
+		 * may change... - Jean II */
+		u16 rid;
+
+		*active = 1;
+
+		rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
+			HERMES_RID_CNFDESIREDSSID;
+
+		err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
+				      NULL, &essidbuf);
+		if (err)
+			goto fail_unlock;
+	} else {
+		*active = 0;
+
+		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
+				      sizeof(essidbuf), NULL, &essidbuf);
+		if (err)
+			goto fail_unlock;
+	}
+
+	len = le16_to_cpu(essidbuf.len);
+	BUG_ON(len > IW_ESSID_MAX_SIZE);
+
+	memset(buf, 0, IW_ESSID_MAX_SIZE);
+	memcpy(buf, p, len);
+	err = len;
+
+ fail_unlock:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+int orinoco_hw_get_freq(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	u16 channel;
+	int freq = 0;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
+				  &channel);
+	if (err)
+		goto out;
+
+	/* Intersil firmware 1.3.5 returns 0 when the interface is down */
+	if (channel == 0) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	if ((channel < 1) || (channel > NUM_CHANNELS)) {
+		printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
+		       priv->ndev->name, channel);
+		err = -EBUSY;
+		goto out;
+
+	}
+	freq = ieee80211_dsss_chan_to_freq(channel);
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	if (err > 0)
+		err = -EBUSY;
+	return err ? err : freq;
+}
+
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+			       int *numrates, s32 *rates, int max)
+{
+	hermes_t *hw = &priv->hw;
+	struct hermes_idstring list;
+	unsigned char *p = (unsigned char *)&list.val;
+	int err = 0;
+	int num;
+	int i;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
+			      sizeof(list), NULL, &list);
+	orinoco_unlock(priv, &flags);
+
+	if (err)
+		return err;
+
+	num = le16_to_cpu(list.len);
+	*numrates = num;
+	num = min(num, max);
+
+	for (i = 0; i < num; i++)
+		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hw.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hw.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/hw.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,47 @@
+/* Encapsulate basic setting changes on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_HW_H_
+#define _ORINOCO_HW_H_
+
+#include <linux/types.h>
+#include <linux/wireless.h>
+
+/* Hardware BAPs */
+#define USER_BAP 0
+#define IRQ_BAP  1
+
+/* WEP key sizes */
+#define SMALL_KEY_SIZE 5
+#define LARGE_KEY_SIZE 13
+
+/* Number of supported channels */
+#define NUM_CHANNELS 14
+
+/* Forward declarations */
+struct orinoco_private;
+struct dev_addr_list;
+
+int orinoco_get_bitratemode(int bitrate, int automatic);
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
+
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
+int __orinoco_hw_set_wap(struct orinoco_private *priv);
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
+int __orinoco_hw_setup_enc(struct orinoco_private *priv);
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+			      u8 *key, u8 *rsc, u8 *tsc);
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+				    struct dev_addr_list *mc_list,
+				    int mc_count, int promisc);
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+			 char buf[IW_ESSID_MAX_SIZE+1]);
+int orinoco_hw_get_freq(struct orinoco_private *priv);
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+			       int *numrates, s32 *rates, int max);
+
+#endif /* _ORINOCO_HW_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,120 @@
+config HERMES
+	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
+	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+	select WIRELESS_EXT
+	select FW_LOADER
+	select CRYPTO
+	select CRYPTO_MICHAEL_MIC
+	---help---
+	  A driver for 802.11b wireless cards based on the "Hermes" or
+	  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
+	  majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
+	  - except for the Cisco/Aironet cards.  Cards supported include the
+	  Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
+	  Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
+	  IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
+	  MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
+	  IPW2011, and Symbol Spectrum24 High Rate amongst others.
+
+	  This option includes the guts of the driver, but in order to
+	  actually use a card you will also need to enable support for PCMCIA
+	  Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
+
+	  You will also very likely also need the Wireless Tools in order to
+	  configure your card and that /etc/pcmcia/wireless.opts works :
+	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
+
+config HERMES_CACHE_FW_ON_INIT
+	bool "Cache Hermes firmware on driver initialisation"
+	depends on HERMES
+	default y
+	---help---
+	  Say Y to cache any firmware required by the Hermes drivers
+	  on startup.  The firmware will remain cached until the
+	  driver is unloaded.  The cache uses 64K of RAM.
+
+	  Otherwise load the firmware from userspace as required.  In
+	  this case the driver should be unloaded and restarted
+	  whenever the firmware is changed.
+
+	  If you are not sure, say Y.
+
+config APPLE_AIRPORT
+	tristate "Apple Airport support (built-in)"
+	depends on PPC_PMAC && HERMES
+	help
+	  Say Y here to support the Airport 802.11b wireless Ethernet hardware
+	  built into the Macintosh iBook and other recent PowerPC-based
+	  Macintosh machines. This is essentially a Lucent Orinoco card with
+	  a non-standard interface.
+
+	  This driver does not support the Airport Extreme (802.11b/g). Use
+	  the BCM43xx driver for Airport Extreme cards.
+
+config PLX_HERMES
+	tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
+	depends on PCI && HERMES
+	help
+	  Enable support for PCMCIA cards supported by the "Hermes" (aka
+	  orinoco) driver when used in PLX9052 based PCI adaptors.  These
+	  adaptors are not a full PCMCIA controller but act as a more limited
+	  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
+	  802.11b PCMCIA cards can be used in desktop machines.  The Netgear
+	  MA301 is such an adaptor.
+
+config TMD_HERMES
+	tristate "Hermes in TMD7160 based PCI adaptor support"
+	depends on PCI && HERMES
+	help
+	  Enable support for PCMCIA cards supported by the "Hermes" (aka
+	  orinoco) driver when used in TMD7160 based PCI adaptors.  These
+	  adaptors are not a full PCMCIA controller but act as a more limited
+	  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
+	  802.11b PCMCIA cards can be used in desktop machines.
+
+config NORTEL_HERMES
+	tristate "Nortel emobility PCI adaptor support"
+	depends on PCI && HERMES
+	help
+	  Enable support for PCMCIA cards supported by the "Hermes" (aka
+	  orinoco) driver when used in Nortel emobility PCI adaptors.  These
+	  adaptors are not full PCMCIA controllers, but act as a more limited
+	  PCI <-> PCMCIA bridge.
+
+config PCI_HERMES
+	tristate "Prism 2.5 PCI 802.11b adaptor support"
+	depends on PCI && HERMES
+	help
+	  Enable support for PCI and mini-PCI 802.11b wireless NICs based on
+	  the Prism 2.5 chipset.  These are true PCI cards, not the 802.11b
+	  PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
+	  common.  Some of the built-in wireless adaptors in laptops are of
+	  this variety.
+
+config PCMCIA_HERMES
+	tristate "Hermes PCMCIA card support"
+	depends on PCMCIA && HERMES
+	---help---
+	  A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
+	  as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
+	  EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
+	  others).  It should also be usable on various Prism II based cards
+	  such as the Linksys, D-Link and Farallon Skyline.  It should also
+	  work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
+
+	  You will very likely need the Wireless Tools in order to
+	  configure your card and that /etc/pcmcia/wireless.opts works:
+	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+config PCMCIA_SPECTRUM
+	tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
+	depends on PCMCIA && HERMES
+	---help---
+
+	  This is a driver for 802.11b cards using RAM-loadable Symbol
+	  firmware, such as Symbol Wireless Networker LA4100, CompactFlash
+	  cards by Socket Communications and Intel PRO/Wireless 2011B.
+
+	  This driver requires firmware download on startup.  Utilities
+	  for downloading Symbol firmware are available at
+	  <http://sourceforge.net/projects/orinoco/>
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/main.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2667 @@
+/* main.c - (formerly known as dldwd_cs.c, orinoco_cs.c and orinoco.c)
+ *
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
+ *
+ * Current maintainers (as of 29 September 2003) are:
+ * 	Pavel Roskin <proski AT gnu.org>
+ * and	David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * (C) Copyright David Gibson, IBM Corporation 2001-2003.
+ * Copyright (C) 2000 David Gibson, Linuxcare Australia.
+ *	With some help from :
+ * Copyright (C) 2001 Jean Tourrilhes, HP Labs
+ * Copyright (C) 2001 Benjamin Herrenschmidt
+ *
+ * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
+ *
+ * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
+ * AT fasta.fh-dortmund.de>
+ *      http://www.stud.fh-dortmund.de/~andy/wvlan/
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds AT users.sourceforge.net>.  Portions created by David
+ * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
+ * Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.  */
+
+/*
+ * TODO
+ *	o Handle de-encapsulation within network layer, provide 802.11
+ *	  headers (patch from Thomas 'Dent' Mirlacher)
+ *	o Fix possible races in SPY handling.
+ *	o Disconnect wireless extensions from fundamental configuration.
+ *	o (maybe) Software WEP support (patch from Stano Meduna).
+ *	o (maybe) Use multiple Tx buffers - driver handling queue
+ *	  rather than firmware.
+ */
+
+/* Locking and synchronization:
+ *
+ * The basic principle is that everything is serialized through a
+ * single spinlock, priv->lock.  The lock is used in user, bh and irq
+ * context, so when taken outside hardirq context it should always be
+ * taken with interrupts disabled.  The lock protects both the
+ * hardware and the struct orinoco_private.
+ *
+ * Another flag, priv->hw_unavailable indicates that the hardware is
+ * unavailable for an extended period of time (e.g. suspended, or in
+ * the middle of a hard reset).  This flag is protected by the
+ * spinlock.  All code which touches the hardware should check the
+ * flag after taking the lock, and if it is set, give up on whatever
+ * they are doing and drop the lock again.  The orinoco_lock()
+ * function handles this (it unlocks and returns -EBUSY if
+ * hw_unavailable is non-zero).
+ */
+
+#define DRIVER_NAME "orinoco"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.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>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes_rid.h"
+#include "hermes_dld.h"
+#include "hw.h"
+#include "scan.h"
+#include "mic.h"
+#include "fw.h"
+#include "wext.h"
+#include "main.h"
+
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module information                                               */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & "
+	      "David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based "
+		   "and similar wireless cards");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Level of debugging. Used in the macros in orinoco.h */
+#ifdef ORINOCO_DEBUG
+int orinoco_debug = ORINOCO_DEBUG;
+EXPORT_SYMBOL(orinoco_debug);
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
+#endif
+
+static int suppress_linkstatus; /* = 0 */
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect,
+		 "Don't report lost link to the network layer");
+
+int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
+
+/********************************************************************/
+/* Internal constants                                               */
+/********************************************************************/
+
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
+
+#define ORINOCO_MIN_MTU		256
+#define ORINOCO_MAX_MTU		(IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
+
+#define SYMBOL_MAX_VER_LEN	(14)
+#define MAX_IRQLOOPS_PER_IRQ	10
+#define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ) /* Based on a guestimate of
+					    * how many events the
+					    * device could
+					    * legitimately generate */
+#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
+
+#define DUMMY_FID		0xFFFF
+
+/*#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+  HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv)	(HERMES_MAX_MULTICAST)
+
+#define ORINOCO_INTEN	 	(HERMES_EV_RX | HERMES_EV_ALLOC \
+				 | HERMES_EV_TX | HERMES_EV_TXEXC \
+				 | HERMES_EV_WTERR | HERMES_EV_INFO \
+				 | HERMES_EV_INFDROP)
+
+static const struct ethtool_ops orinoco_ethtool_ops;
+
+/********************************************************************/
+/* Data types                                                       */
+/********************************************************************/
+
+/* Beginning of the Tx descriptor, used in TxExc handling */
+struct hermes_txexc_data {
+	struct hermes_tx_descriptor desc;
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+} __attribute__ ((packed));
+
+/* Rx frame header except compatibility 802.3 header */
+struct hermes_rx_descriptor {
+	/* Control */
+	__le16 status;
+	__le32 time;
+	u8 silence;
+	u8 signal;
+	u8 rate;
+	u8 rxflow;
+	__le32 reserved;
+
+	/* 802.11 header */
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+
+	/* Data length */
+	__le16 data_len;
+} __attribute__ ((packed));
+
+struct orinoco_rx_data {
+	struct hermes_rx_descriptor *desc;
+	struct sk_buff *skb;
+	struct list_head list;
+};
+
+/********************************************************************/
+/* Function prototypes                                              */
+/********************************************************************/
+
+static void __orinoco_set_multicast_list(struct net_device *dev);
+
+/********************************************************************/
+/* Internal helper functions                                        */
+/********************************************************************/
+
+void set_port_type(struct orinoco_private *priv)
+{
+	switch (priv->iw_mode) {
+	case IW_MODE_INFRA:
+		priv->port_type = 1;
+		priv->createibss = 0;
+		break;
+	case IW_MODE_ADHOC:
+		if (priv->prefer_port3) {
+			priv->port_type = 3;
+			priv->createibss = 0;
+		} else {
+			priv->port_type = priv->ibss_port;
+			priv->createibss = 1;
+		}
+		break;
+	case IW_MODE_MONITOR:
+		priv->port_type = 3;
+		priv->createibss = 0;
+		break;
+	default:
+		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
+		       priv->ndev->name);
+	}
+}
+
+/********************************************************************/
+/* Device methods                                                   */
+/********************************************************************/
+
+static int orinoco_open(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = __orinoco_up(dev);
+
+	if (!err)
+		priv->open = 1;
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_stop(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+
+	/* We mustn't use orinoco_lock() here, because we need to be
+	   able to close the interface even if hw_unavailable is set
+	   (e.g. as we're released after a PC Card removal) */
+	spin_lock_irq(&priv->lock);
+
+	priv->open = 0;
+
+	err = __orinoco_down(dev);
+
+	spin_unlock_irq(&priv->lock);
+
+	return err;
+}
+
+static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	return &priv->stats;
+}
+
+static void orinoco_set_multicast_list(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
+		       "called when hw_unavailable\n", dev->name);
+		return;
+	}
+
+	__orinoco_set_multicast_list(dev);
+	orinoco_unlock(priv, &flags);
+}
+
+static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
+		return -EINVAL;
+
+	/* MTU + encapsulation + header length */
+	if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
+	     (priv->nicbuf_size - ETH_HLEN))
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+
+	return 0;
+}
+
+/********************************************************************/
+/* Tx path                                                          */
+/********************************************************************/
+
+static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	u16 txfid = priv->txfid;
+	struct ethhdr *eh;
+	int tx_control;
+	unsigned long flags;
+
+	if (!netif_running(dev)) {
+		printk(KERN_ERR "%s: Tx on stopped device!\n",
+		       dev->name);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (netif_queue_stopped(dev)) {
+		printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
+		       dev->name);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
+		       dev->name);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+		/* Oops, the firmware hasn't established a connection,
+		   silently drop the packet (this seems to be the
+		   safest approach). */
+		goto drop;
+	}
+
+	/* Check packet length */
+	if (skb->len < ETH_HLEN)
+		goto drop;
+
+	tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
+
+	if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
+		tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
+			HERMES_TXCTRL_MIC;
+
+	if (priv->has_alt_txcntl) {
+		/* WPA enabled firmwares have tx_cntl at the end of
+		 * the 802.11 header.  So write zeroed descriptor and
+		 * 802.11 header at the same time
+		 */
+		char desc[HERMES_802_3_OFFSET];
+		__le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
+
+		memset(&desc, 0, sizeof(desc));
+
+		*txcntl = cpu_to_le16(tx_control);
+		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+					txfid, 0);
+		if (err) {
+			if (net_ratelimit())
+				printk(KERN_ERR "%s: Error %d writing Tx "
+				       "descriptor to BAP\n", dev->name, err);
+			goto busy;
+		}
+	} else {
+		struct hermes_tx_descriptor desc;
+
+		memset(&desc, 0, sizeof(desc));
+
+		desc.tx_control = cpu_to_le16(tx_control);
+		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+					txfid, 0);
+		if (err) {
+			if (net_ratelimit())
+				printk(KERN_ERR "%s: Error %d writing Tx "
+				       "descriptor to BAP\n", dev->name, err);
+			goto busy;
+		}
+
+		/* Clear the 802.11 header and data length fields - some
+		 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
+		 * if this isn't done. */
+		hermes_clear_words(hw, HERMES_DATA0,
+				   HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
+	}
+
+	eh = (struct ethhdr *)skb->data;
+
+	/* Encapsulate Ethernet-II frames */
+	if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
+		struct header_struct {
+			struct ethhdr eth;	/* 802.3 header */
+			u8 encap[6];		/* 802.2 header */
+		} __attribute__ ((packed)) hdr;
+
+		/* Strip destination and source from the data */
+		skb_pull(skb, 2 * ETH_ALEN);
+
+		/* And move them to a separate header */
+		memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+		hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
+		memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+		/* Insert the SNAP header */
+		if (skb_headroom(skb) < sizeof(hdr)) {
+			printk(KERN_ERR
+			       "%s: Not enough headroom for 802.2 headers %d\n",
+			       dev->name, skb_headroom(skb));
+			goto drop;
+		}
+		eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
+		memcpy(eh, &hdr, sizeof(hdr));
+	}
+
+	err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
+				txfid, HERMES_802_3_OFFSET);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
+		       dev->name, err);
+		goto busy;
+	}
+
+	/* Calculate Michael MIC */
+	if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
+		u8 mic_buf[MICHAEL_MIC_LEN + 1];
+		u8 *mic;
+		size_t offset;
+		size_t len;
+
+		if (skb->len % 2) {
+			/* MIC start is on an odd boundary */
+			mic_buf[0] = skb->data[skb->len - 1];
+			mic = &mic_buf[1];
+			offset = skb->len - 1;
+			len = MICHAEL_MIC_LEN + 1;
+		} else {
+			mic = &mic_buf[0];
+			offset = skb->len;
+			len = MICHAEL_MIC_LEN;
+		}
+
+		orinoco_mic(priv->tx_tfm_mic,
+			    priv->tkip_key[priv->tx_key].tx_mic,
+			    eh->h_dest, eh->h_source, 0 /* priority */,
+			    skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
+
+		/* Write the MIC */
+		err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
+					txfid, HERMES_802_3_OFFSET + offset);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
+			       dev->name, err);
+			goto busy;
+		}
+	}
+
+	/* Finally, we actually initiate the send */
+	netif_stop_queue(dev);
+
+	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
+				txfid, NULL);
+	if (err) {
+		netif_start_queue(dev);
+		if (net_ratelimit())
+			printk(KERN_ERR "%s: Error %d transmitting packet\n",
+				dev->name, err);
+		goto busy;
+	}
+
+	dev->trans_start = jiffies;
+	stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
+	goto ok;
+
+ drop:
+	stats->tx_errors++;
+	stats->tx_dropped++;
+
+ ok:
+	orinoco_unlock(priv, &flags);
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+
+ busy:
+	if (err == -EIO)
+		schedule_work(&priv->reset_work);
+	orinoco_unlock(priv, &flags);
+	return NETDEV_TX_BUSY;
+}
+
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	u16 fid = hermes_read_regn(hw, ALLOCFID);
+
+	if (fid != priv->txfid) {
+		if (fid != DUMMY_FID)
+			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
+			       dev->name, fid);
+		return;
+	}
+
+	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+
+	stats->tx_packets++;
+
+	netif_wake_queue(dev);
+
+	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+	u16 status;
+	struct hermes_txexc_data hdr;
+	int err = 0;
+
+	if (fid == DUMMY_FID)
+		return; /* Nothing's really happened */
+
+	/* Read part of the frame header - we need status and addr1 */
+	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+			       sizeof(struct hermes_txexc_data),
+			       fid, 0);
+
+	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+	stats->tx_errors++;
+
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
+		       "(FID=%04X error %d)\n",
+		       dev->name, fid, err);
+		return;
+	}
+
+	DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
+	      err, fid);
+
+	/* We produce a TXDROP event only for retry or lifetime
+	 * exceeded, because that's the only status that really mean
+	 * that this particular node went away.
+	 * Other errors means that *we* screwed up. - Jean II */
+	status = le16_to_cpu(hdr.desc.status);
+	if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+		union iwreq_data	wrqu;
+
+		/* Copy 802.11 dest address.
+		 * We use the 802.11 header because the frame may
+		 * not be 802.3 or may be mangled...
+		 * In Ad-Hoc mode, it will be the node address.
+		 * In managed mode, it will be most likely the AP addr
+		 * User space will figure out how to convert it to
+		 * whatever it needs (IP address or else).
+		 * - Jean II */
+		memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
+		wrqu.addr.sa_family = ARPHRD_ETHER;
+
+		/* Send event to user space */
+		wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
+	}
+
+	netif_wake_queue(dev);
+}
+
+static void orinoco_tx_timeout(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	struct hermes *hw = &priv->hw;
+
+	printk(KERN_WARNING "%s: Tx timeout! "
+	       "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
+	       dev->name, hermes_read_regn(hw, ALLOCFID),
+	       hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
+
+	stats->tx_errors++;
+
+	schedule_work(&priv->reset_work);
+}
+
+/********************************************************************/
+/* Rx path (data frames)                                            */
+/********************************************************************/
+
+/* Does the frame have a SNAP header indicating it should be
+ * de-encapsulated to Ethernet-II? */
+static inline int is_ethersnap(void *_hdr)
+{
+	u8 *hdr = _hdr;
+
+	/* We de-encapsulate all packets which, a) have SNAP headers
+	 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
+	 * and where b) the OUI of the SNAP header is 00:00:00 or
+	 * 00:00:f8 - we need both because different APs appear to use
+	 * different OUIs for some reason */
+	return (memcmp(hdr, &encaps_hdr, 5) == 0)
+		&& ((hdr[5] == 0x00) || (hdr[5] == 0xf8));
+}
+
+static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
+				      int level, int noise)
+{
+	struct iw_quality wstats;
+	wstats.level = level - 0x95;
+	wstats.noise = noise - 0x95;
+	wstats.qual = (level > noise) ? (level - noise) : 0;
+	wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+	/* Update spy records */
+	wireless_spy_update(dev, mac, &wstats);
+}
+
+static void orinoco_stat_gather(struct net_device *dev,
+				struct sk_buff *skb,
+				struct hermes_rx_descriptor *desc)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	/* Using spy support with lots of Rx packets, like in an
+	 * infrastructure (AP), will really slow down everything, because
+	 * the MAC address must be compared to each entry of the spy list.
+	 * If the user really asks for it (set some address in the
+	 * spy list), we do it, but he will pay the price.
+	 * Note that to get here, you need both WIRELESS_SPY
+	 * compiled in AND some addresses in the list !!!
+	 */
+	/* Note : gcc will optimise the whole section away if
+	 * WIRELESS_SPY is not defined... - Jean II */
+	if (SPY_NUMBER(priv)) {
+		orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
+				   desc->signal, desc->silence);
+	}
+}
+
+/*
+ * orinoco_rx_monitor - handle received monitor frames.
+ *
+ * Arguments:
+ *	dev		network device
+ *	rxfid		received FID
+ *	desc		rx descriptor of the frame
+ *
+ * Call context: interrupt
+ */
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
+			       struct hermes_rx_descriptor *desc)
+{
+	u32 hdrlen = 30;	/* return full header by default */
+	u32 datalen = 0;
+	u16 fc;
+	int err;
+	int len;
+	struct sk_buff *skb;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	hermes_t *hw = &priv->hw;
+
+	len = le16_to_cpu(desc->data_len);
+
+	/* Determine the size of the header and the data */
+	fc = le16_to_cpu(desc->frame_ctl);
+	switch (fc & IEEE80211_FCTL_FTYPE) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_TODS)
+		    && (fc & IEEE80211_FCTL_FROMDS))
+			hdrlen = 30;
+		else
+			hdrlen = 24;
+		datalen = len;
+		break;
+	case IEEE80211_FTYPE_MGMT:
+		hdrlen = 24;
+		datalen = len;
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_PSPOLL:
+		case IEEE80211_STYPE_RTS:
+		case IEEE80211_STYPE_CFEND:
+		case IEEE80211_STYPE_CFENDACK:
+			hdrlen = 16;
+			break;
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = 10;
+			break;
+		}
+		break;
+	default:
+		/* Unknown frame type */
+		break;
+	}
+
+	/* sanity check the length */
+	if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
+		printk(KERN_DEBUG "%s: oversized monitor frame, "
+		       "data length = %d\n", dev->name, datalen);
+		stats->rx_length_errors++;
+		goto update_stats;
+	}
+
+	skb = dev_alloc_skb(hdrlen + datalen);
+	if (!skb) {
+		printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
+		       dev->name);
+		goto update_stats;
+	}
+
+	/* Copy the 802.11 header to the skb */
+	memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
+	skb_reset_mac_header(skb);
+
+	/* If any, copy the data from the card to the skb */
+	if (datalen > 0) {
+		err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+				       ALIGN(datalen, 2), rxfid,
+				       HERMES_802_2_OFFSET);
+		if (err) {
+			printk(KERN_ERR "%s: error %d reading monitor frame\n",
+			       dev->name, err);
+			goto drop;
+		}
+	}
+
+	skb->dev = dev;
+	skb->ip_summed = CHECKSUM_NONE;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = cpu_to_be16(ETH_P_802_2);
+
+	stats->rx_packets++;
+	stats->rx_bytes += skb->len;
+
+	netif_rx(skb);
+	return;
+
+ drop:
+	dev_kfree_skb_irq(skb);
+ update_stats:
+	stats->rx_errors++;
+	stats->rx_dropped++;
+}
+
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	struct iw_statistics *wstats = &priv->wstats;
+	struct sk_buff *skb = NULL;
+	u16 rxfid, status;
+	int length;
+	struct hermes_rx_descriptor *desc;
+	struct orinoco_rx_data *rx_data;
+	int err;
+
+	desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
+	if (!desc) {
+		printk(KERN_WARNING
+		       "%s: Can't allocate space for RX descriptor\n",
+		       dev->name);
+		goto update_stats;
+	}
+
+	rxfid = hermes_read_regn(hw, RXFID);
+
+	err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
+			       rxfid, 0);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
+		       "Frame dropped.\n", dev->name, err);
+		goto update_stats;
+	}
+
+	status = le16_to_cpu(desc->status);
+
+	if (status & HERMES_RXSTAT_BADCRC) {
+		DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
+		      dev->name);
+		stats->rx_crc_errors++;
+		goto update_stats;
+	}
+
+	/* Handle frames in monitor mode */
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		orinoco_rx_monitor(dev, rxfid, desc);
+		goto out;
+	}
+
+	if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+		DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
+		      dev->name);
+		wstats->discard.code++;
+		goto update_stats;
+	}
+
+	length = le16_to_cpu(desc->data_len);
+
+	/* Sanity checks */
+	if (length < 3) { /* No for even an 802.2 LLC header */
+		/* At least on Symbol firmware with PCF we get quite a
+		   lot of these legitimately - Poll frames with no
+		   data. */
+		goto out;
+	}
+	if (length > IEEE80211_MAX_DATA_LEN) {
+		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
+		       dev->name, length);
+		stats->rx_length_errors++;
+		goto update_stats;
+	}
+
+	/* Payload size does not include Michael MIC. Increase payload
+	 * size to read it together with the data. */
+	if (status & HERMES_RXSTAT_MIC)
+		length += MICHAEL_MIC_LEN;
+
+	/* We need space for the packet data itself, plus an ethernet
+	   header, plus 2 bytes so we can align the IP header on a
+	   32bit boundary, plus 1 byte so we can read in odd length
+	   packets from the card, which has an IO granularity of 16
+	   bits */
+	skb = dev_alloc_skb(length+ETH_HLEN+2+1);
+	if (!skb) {
+		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
+		       dev->name);
+		goto update_stats;
+	}
+
+	/* We'll prepend the header, so reserve space for it.  The worst
+	   case is no decapsulation, when 802.3 header is prepended and
+	   nothing is removed.  2 is for aligning the IP header.  */
+	skb_reserve(skb, ETH_HLEN + 2);
+
+	err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
+			       ALIGN(length, 2), rxfid,
+			       HERMES_802_2_OFFSET);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading frame. "
+		       "Frame dropped.\n", dev->name, err);
+		goto drop;
+	}
+
+	/* Add desc and skb to rx queue */
+	rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
+	if (!rx_data) {
+		printk(KERN_WARNING "%s: Can't allocate RX packet\n",
+			dev->name);
+		goto drop;
+	}
+	rx_data->desc = desc;
+	rx_data->skb = skb;
+	list_add_tail(&rx_data->list, &priv->rx_list);
+	tasklet_schedule(&priv->rx_tasklet);
+
+	return;
+
+drop:
+	dev_kfree_skb_irq(skb);
+update_stats:
+	stats->rx_errors++;
+	stats->rx_dropped++;
+out:
+	kfree(desc);
+}
+
+static void orinoco_rx(struct net_device *dev,
+		       struct hermes_rx_descriptor *desc,
+		       struct sk_buff *skb)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	u16 status, fc;
+	int length;
+	struct ethhdr *hdr;
+
+	status = le16_to_cpu(desc->status);
+	length = le16_to_cpu(desc->data_len);
+	fc = le16_to_cpu(desc->frame_ctl);
+
+	/* Calculate and check MIC */
+	if (status & HERMES_RXSTAT_MIC) {
+		int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
+			      HERMES_MIC_KEY_ID_SHIFT);
+		u8 mic[MICHAEL_MIC_LEN];
+		u8 *rxmic;
+		u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
+			desc->addr3 : desc->addr2;
+
+		/* Extract Michael MIC from payload */
+		rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
+
+		skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+		length -= MICHAEL_MIC_LEN;
+
+		orinoco_mic(priv->rx_tfm_mic,
+			    priv->tkip_key[key_id].rx_mic,
+			    desc->addr1,
+			    src,
+			    0, /* priority or QoS? */
+			    skb->data,
+			    skb->len,
+			    &mic[0]);
+
+		if (memcmp(mic, rxmic,
+			   MICHAEL_MIC_LEN)) {
+			union iwreq_data wrqu;
+			struct iw_michaelmicfailure wxmic;
+
+			printk(KERN_WARNING "%s: "
+			       "Invalid Michael MIC in data frame from %pM, "
+			       "using key %i\n",
+			       dev->name, src, key_id);
+
+			/* TODO: update stats */
+
+			/* Notify userspace */
+			memset(&wxmic, 0, sizeof(wxmic));
+			wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
+			wxmic.flags |= (desc->addr1[0] & 1) ?
+				IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
+			wxmic.src_addr.sa_family = ARPHRD_ETHER;
+			memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
+
+			(void) orinoco_hw_get_tkip_iv(priv, key_id,
+						      &wxmic.tsc[0]);
+
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = sizeof(wxmic);
+			wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
+					    (char *) &wxmic);
+
+			goto drop;
+		}
+	}
+
+	/* Handle decapsulation
+	 * In most cases, the firmware tell us about SNAP frames.
+	 * For some reason, the SNAP frames sent by LinkSys APs
+	 * are not properly recognised by most firmwares.
+	 * So, check ourselves */
+	if (length >= ENCAPS_OVERHEAD &&
+	    (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
+	     ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
+	     is_ethersnap(skb->data))) {
+		/* These indicate a SNAP within 802.2 LLC within
+		   802.11 frame which we'll need to de-encapsulate to
+		   the original EthernetII frame. */
+		hdr = (struct ethhdr *)skb_push(skb,
+						ETH_HLEN - ENCAPS_OVERHEAD);
+	} else {
+		/* 802.3 frame - prepend 802.3 header as is */
+		hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+		hdr->h_proto = htons(length);
+	}
+	memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
+	if (fc & IEEE80211_FCTL_FROMDS)
+		memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
+	else
+		memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	skb->ip_summed = CHECKSUM_NONE;
+	if (fc & IEEE80211_FCTL_TODS)
+		skb->pkt_type = PACKET_OTHERHOST;
+
+	/* Process the wireless stats if needed */
+	orinoco_stat_gather(dev, skb, desc);
+
+	/* Pass the packet to the networking stack */
+	netif_rx(skb);
+	stats->rx_packets++;
+	stats->rx_bytes += length;
+
+	return;
+
+ drop:
+	dev_kfree_skb(skb);
+	stats->rx_errors++;
+	stats->rx_dropped++;
+}
+
+static void orinoco_rx_isr_tasklet(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_rx_data *rx_data, *temp;
+	struct hermes_rx_descriptor *desc;
+	struct sk_buff *skb;
+	unsigned long flags;
+
+	/* orinoco_rx requires the driver lock, and we also need to
+	 * protect priv->rx_list, so just hold the lock over the
+	 * lot.
+	 *
+	 * If orinoco_lock fails, we've unplugged the card. In this
+	 * case just abort. */
+	if (orinoco_lock(priv, &flags) != 0)
+		return;
+
+	/* extract desc and skb from queue */
+	list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+		desc = rx_data->desc;
+		skb = rx_data->skb;
+		list_del(&rx_data->list);
+		kfree(rx_data);
+
+		orinoco_rx(dev, desc, skb);
+
+		kfree(desc);
+	}
+
+	orinoco_unlock(priv, &flags);
+}
+
+/********************************************************************/
+/* Rx path (info frames)                                            */
+/********************************************************************/
+
+static void print_linkstatus(struct net_device *dev, u16 status)
+{
+	char *s;
+
+	if (suppress_linkstatus)
+		return;
+
+	switch (status) {
+	case HERMES_LINKSTATUS_NOT_CONNECTED:
+		s = "Not Connected";
+		break;
+	case HERMES_LINKSTATUS_CONNECTED:
+		s = "Connected";
+		break;
+	case HERMES_LINKSTATUS_DISCONNECTED:
+		s = "Disconnected";
+		break;
+	case HERMES_LINKSTATUS_AP_CHANGE:
+		s = "AP Changed";
+		break;
+	case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
+		s = "AP Out of Range";
+		break;
+	case HERMES_LINKSTATUS_AP_IN_RANGE:
+		s = "AP In Range";
+		break;
+	case HERMES_LINKSTATUS_ASSOC_FAILED:
+		s = "Association Failed";
+		break;
+	default:
+		s = "UNKNOWN";
+	}
+
+	printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
+	       dev->name, s, status);
+}
+
+/* Search scan results for requested BSSID, join it if found */
+static void orinoco_join_ap(struct work_struct *work)
+{
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, join_work);
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	int err;
+	unsigned long flags;
+	struct join_req {
+		u8 bssid[ETH_ALEN];
+		__le16 channel;
+	} __attribute__ ((packed)) req;
+	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+	struct prism2_scan_apinfo *atom = NULL;
+	int offset = 4;
+	int found = 0;
+	u8 *buf;
+	u16 len;
+
+	/* Allocate buffer for scan results */
+	buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
+	if (!buf)
+		return;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		goto fail_lock;
+
+	/* Sanity checks in case user changed something in the meantime */
+	if (!priv->bssid_fixed)
+		goto out;
+
+	if (strlen(priv->desired_essid) == 0)
+		goto out;
+
+	/* Read scan results from the firmware */
+	err = hermes_read_ltv(hw, USER_BAP,
+			      HERMES_RID_SCANRESULTSTABLE,
+			      MAX_SCAN_LEN, &len, buf);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read scan results\n",
+		       dev->name);
+		goto out;
+	}
+
+	len = HERMES_RECLEN_TO_BYTES(len);
+
+	/* Go through the scan results looking for the channel of the AP
+	 * we were requested to join */
+	for (; offset + atom_len <= len; offset += atom_len) {
+		atom = (struct prism2_scan_apinfo *) (buf + offset);
+		if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		DEBUG(1, "%s: Requested AP not found in scan results\n",
+		      dev->name);
+		goto out;
+	}
+
+	memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
+	req.channel = atom->channel;	/* both are little-endian */
+	err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
+				  &req);
+	if (err)
+		printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+ fail_lock:
+	kfree(buf);
+}
+
+/* Send new BSSID to userspace */
+static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	union iwreq_data wrqu;
+	int err;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+	if (err != 0)
+		return;
+
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+	/* Send event to user space */
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	union iwreq_data wrqu;
+	int err;
+	u8 buf[88];
+	u8 *ie;
+
+	if (!priv->has_wpa)
+		return;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+			      sizeof(buf), NULL, &buf);
+	if (err != 0)
+		return;
+
+	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+	if (ie) {
+		int rem = sizeof(buf) - (ie - &buf[0]);
+		wrqu.data.length = ie[1] + 2;
+		if (wrqu.data.length > rem)
+			wrqu.data.length = rem;
+
+		if (wrqu.data.length)
+			/* Send event to user space */
+			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
+	}
+}
+
+static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	union iwreq_data wrqu;
+	int err;
+	u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
+	u8 *ie;
+
+	if (!priv->has_wpa)
+		return;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+			      sizeof(buf), NULL, &buf);
+	if (err != 0)
+		return;
+
+	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+	if (ie) {
+		int rem = sizeof(buf) - (ie - &buf[0]);
+		wrqu.data.length = ie[1] + 2;
+		if (wrqu.data.length > rem)
+			wrqu.data.length = rem;
+
+		if (wrqu.data.length)
+			/* Send event to user space */
+			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+	}
+}
+
+static void orinoco_send_wevents(struct work_struct *work)
+{
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, wevent_work);
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return;
+
+	orinoco_send_assocreqie_wevent(priv);
+	orinoco_send_assocrespie_wevent(priv);
+	orinoco_send_bssid_wevent(priv);
+
+	orinoco_unlock(priv, &flags);
+}
+
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	u16 infofid;
+	struct {
+		__le16 len;
+		__le16 type;
+	} __attribute__ ((packed)) info;
+	int len, type;
+	int err;
+
+	/* This is an answer to an INQUIRE command that we did earlier,
+	 * or an information "event" generated by the card
+	 * The controller return to us a pseudo frame containing
+	 * the information in question - Jean II */
+	infofid = hermes_read_regn(hw, INFOFID);
+
+	/* Read the info frame header - don't try too hard */
+	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
+			       infofid, 0);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading info frame. "
+		       "Frame dropped.\n", dev->name, err);
+		return;
+	}
+
+	len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
+	type = le16_to_cpu(info.type);
+
+	switch (type) {
+	case HERMES_INQ_TALLIES: {
+		struct hermes_tallies_frame tallies;
+		struct iw_statistics *wstats = &priv->wstats;
+
+		if (len > sizeof(tallies)) {
+			printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
+			       dev->name, len);
+			len = sizeof(tallies);
+		}
+
+		err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+				       infofid, sizeof(info));
+		if (err)
+			break;
+
+		/* Increment our various counters */
+		/* wstats->discard.nwid - no wrong BSSID stuff */
+		wstats->discard.code +=
+			le16_to_cpu(tallies.RxWEPUndecryptable);
+		if (len == sizeof(tallies))
+			wstats->discard.code +=
+				le16_to_cpu(tallies.RxDiscards_WEPICVError) +
+				le16_to_cpu(tallies.RxDiscards_WEPExcluded);
+		wstats->discard.misc +=
+			le16_to_cpu(tallies.TxDiscardsWrongSA);
+		wstats->discard.fragment +=
+			le16_to_cpu(tallies.RxMsgInBadMsgFragments);
+		wstats->discard.retries +=
+			le16_to_cpu(tallies.TxRetryLimitExceeded);
+		/* wstats->miss.beacon - no match */
+	}
+	break;
+	case HERMES_INQ_LINKSTATUS: {
+		struct hermes_linkstatus linkstatus;
+		u16 newstatus;
+		int connected;
+
+		if (priv->iw_mode == IW_MODE_MONITOR)
+			break;
+
+		if (len != sizeof(linkstatus)) {
+			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
+			       dev->name, len);
+			break;
+		}
+
+		err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+				       infofid, sizeof(info));
+		if (err)
+			break;
+		newstatus = le16_to_cpu(linkstatus.linkstatus);
+
+		/* Symbol firmware uses "out of range" to signal that
+		 * the hostscan frame can be requested.  */
+		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
+		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
+		    priv->has_hostscan && priv->scan_inprogress) {
+			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
+			break;
+		}
+
+		connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+			|| (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+			|| (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+		if (connected)
+			netif_carrier_on(dev);
+		else if (!ignore_disconnect)
+			netif_carrier_off(dev);
+
+		if (newstatus != priv->last_linkstatus) {
+			priv->last_linkstatus = newstatus;
+			print_linkstatus(dev, newstatus);
+			/* The info frame contains only one word which is the
+			 * status (see hermes.h). The status is pretty boring
+			 * in itself, that's why we export the new BSSID...
+			 * Jean II */
+			schedule_work(&priv->wevent_work);
+		}
+	}
+	break;
+	case HERMES_INQ_SCAN:
+		if (!priv->scan_inprogress && priv->bssid_fixed &&
+		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
+			schedule_work(&priv->join_work);
+			break;
+		}
+		/* fall through */
+	case HERMES_INQ_HOSTSCAN:
+	case HERMES_INQ_HOSTSCAN_SYMBOL: {
+		/* Result of a scanning. Contains information about
+		 * cells in the vicinity - Jean II */
+		union iwreq_data	wrqu;
+		unsigned char *buf;
+
+		/* Scan is no longer in progress */
+		priv->scan_inprogress = 0;
+
+		/* Sanity check */
+		if (len > 4096) {
+			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
+			       dev->name, len);
+			break;
+		}
+
+		/* Allocate buffer for results */
+		buf = kmalloc(len, GFP_ATOMIC);
+		if (buf == NULL)
+			/* No memory, so can't printk()... */
+			break;
+
+		/* Read scan data */
+		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
+				       infofid, sizeof(info));
+		if (err) {
+			kfree(buf);
+			break;
+		}
+
+#ifdef ORINOCO_DEBUG
+		{
+			int	i;
+			printk(KERN_DEBUG "Scan result [%02X", buf[0]);
+			for (i = 1; i < (len * 2); i++)
+				printk(":%02X", buf[i]);
+			printk("]\n");
+		}
+#endif	/* ORINOCO_DEBUG */
+
+		if (orinoco_process_scan_results(priv, buf, len) == 0) {
+			/* Send an empty event to user space.
+			 * We don't send the received data on the event because
+			 * it would require us to do complex transcoding, and
+			 * we want to minimise the work done in the irq handler
+			 * Use a request to extract the data - Jean II */
+			wrqu.data.length = 0;
+			wrqu.data.flags = 0;
+			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+		}
+		kfree(buf);
+	}
+	break;
+	case HERMES_INQ_CHANNELINFO:
+	{
+		struct agere_ext_scan_info *bss;
+
+		if (!priv->scan_inprogress) {
+			printk(KERN_DEBUG "%s: Got chaninfo without scan, "
+			       "len=%d\n", dev->name, len);
+			break;
+		}
+
+		/* An empty result indicates that the scan is complete */
+		if (len == 0) {
+			union iwreq_data	wrqu;
+
+			/* Scan is no longer in progress */
+			priv->scan_inprogress = 0;
+
+			wrqu.data.length = 0;
+			wrqu.data.flags = 0;
+			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+			break;
+		}
+
+		/* Sanity check */
+		else if (len > sizeof(*bss)) {
+			printk(KERN_WARNING
+			       "%s: Ext scan results too large (%d bytes). "
+			       "Truncating results to %zd bytes.\n",
+			       dev->name, len, sizeof(*bss));
+			len = sizeof(*bss);
+		} else if (len < (offsetof(struct agere_ext_scan_info,
+					   data) + 2)) {
+			/* Drop this result now so we don't have to
+			 * keep checking later */
+			printk(KERN_WARNING
+			       "%s: Ext scan results too short (%d bytes)\n",
+			       dev->name, len);
+			break;
+		}
+
+		bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+		if (bss == NULL)
+			break;
+
+		/* Read scan data */
+		err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
+				       infofid, sizeof(info));
+		if (err) {
+			kfree(bss);
+			break;
+		}
+
+		orinoco_add_ext_scan_result(priv, bss);
+
+		kfree(bss);
+		break;
+	}
+	case HERMES_INQ_SEC_STAT_AGERE:
+		/* Security status (Agere specific) */
+		/* Ignore this frame for now */
+		if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+			break;
+		/* fall through */
+	default:
+		printk(KERN_DEBUG "%s: Unknown information frame received: "
+		       "type 0x%04x, length %d\n", dev->name, type, len);
+		/* We don't actually do anything about it */
+		break;
+	}
+}
+
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
+{
+	if (net_ratelimit())
+		printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
+}
+
+/********************************************************************/
+/* Internal hardware control routines                               */
+/********************************************************************/
+
+int __orinoco_up(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	netif_carrier_off(dev); /* just to make sure */
+
+	err = __orinoco_program_rids(dev);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d configuring card\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Fire things up again */
+	hermes_set_irqmask(hw, ORINOCO_INTEN);
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d enabling MAC port\n",
+		       dev->name, err);
+		return err;
+	}
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+EXPORT_SYMBOL(__orinoco_up);
+
+int __orinoco_down(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	netif_stop_queue(dev);
+
+	if (!priv->hw_unavailable) {
+		if (!priv->broken_disableport) {
+			err = hermes_disable_port(hw, 0);
+			if (err) {
+				/* Some firmwares (e.g. Intersil 1.3.x) seem
+				 * to have problems disabling the port, oh
+				 * well, too bad. */
+				printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
+				       dev->name, err);
+				priv->broken_disableport = 1;
+			}
+		}
+		hermes_set_irqmask(hw, 0);
+		hermes_write_regn(hw, EVACK, 0xffff);
+	}
+
+	/* firmware will have to reassociate */
+	netif_carrier_off(dev);
+	priv->last_linkstatus = 0xffff;
+
+	return 0;
+}
+EXPORT_SYMBOL(__orinoco_down);
+
+static int orinoco_allocate_fid(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+		/* Try workaround for old Symbol firmware bug */
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+
+		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+		       "(old Symbol firmware?). Work around %s\n",
+		       dev->name, err ? "failed!" : "ok.");
+	}
+
+	return err;
+}
+
+int orinoco_reinit_firmware(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	err = hermes_init(hw);
+	if (priv->do_fw_download && !err) {
+		err = orinoco_download(priv);
+		if (err)
+			priv->do_fw_download = 0;
+	}
+	if (!err)
+		err = orinoco_allocate_fid(dev);
+
+	return err;
+}
+EXPORT_SYMBOL(orinoco_reinit_firmware);
+
+int __orinoco_program_rids(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct hermes_idstring idbuf;
+
+	/* Set the MAC address */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting MAC address\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set up the link mode */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+				   priv->port_type);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting port type\n",
+		       dev->name, err);
+		return err;
+	}
+	/* Set the channel/frequency */
+	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFOWNCHANNEL,
+					   priv->channel);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting channel %d\n",
+			       dev->name, err, priv->channel);
+			return err;
+		}
+	}
+
+	if (priv->has_ibss) {
+		u16 createibss;
+
+		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+			printk(KERN_WARNING "%s: This firmware requires an "
+			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+			/* With wvlan_cs, in this case, we would crash.
+			 * hopefully, this driver will behave better...
+			 * Jean II */
+			createibss = 0;
+		} else {
+			createibss = priv->createibss;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFCREATEIBSS,
+					   createibss);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set the desired BSSID */
+	err = __orinoco_hw_set_wap(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting AP address\n",
+		       dev->name, err);
+		return err;
+	}
+	/* Set the desired ESSID */
+	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+		       dev->name, err);
+		return err;
+	}
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set the station name */
+	idbuf.len = cpu_to_le16(strlen(priv->nick));
+	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+			       &idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting nickname\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set AP density */
+	if (priv->has_sensitivity) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFSYSTEMSCALE,
+					   priv->ap_density);
+		if (err) {
+			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
+			       "Disabling sensitivity control\n",
+			       dev->name, err);
+
+			priv->has_sensitivity = 0;
+		}
+	}
+
+	/* Set RTS threshold */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				   priv->rts_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set fragmentation threshold or MWO robustness */
+	if (priv->has_mwo)
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMWOROBUST_AGERE,
+					   priv->mwo_robust);
+	else
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					   priv->frag_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set bitrate */
+	err = __orinoco_hw_set_bitrate(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting bitrate\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set power management */
+	if (priv->has_pm) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMENABLED,
+					   priv->pm_on);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMULTICASTRECEIVE,
+					   priv->pm_mcast);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMAXSLEEPDURATION,
+					   priv->pm_period);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMHOLDOVERDURATION,
+					   priv->pm_timeout);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set preamble - only for Symbol so far... */
+	if (priv->has_preamble) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPREAMBLE_SYMBOL,
+					   priv->preamble);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting preamble\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set up encryption */
+	if (priv->has_wep || priv->has_wpa) {
+		err = __orinoco_hw_setup_enc(priv);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating encryption\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		/* Enable monitor mode */
+		dev->type = ARPHRD_IEEE80211;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_MONITOR, 0, NULL);
+	} else {
+		/* Disable monitor mode */
+		dev->type = ARPHRD_ETHER;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_STOP, 0, NULL);
+	}
+	if (err)
+		return err;
+
+	/* Set promiscuity / multicast*/
+	priv->promiscuous = 0;
+	priv->mc_count = 0;
+
+	/* FIXME: what about netif_tx_lock */
+	__orinoco_set_multicast_list(dev);
+
+	return 0;
+}
+
+/* FIXME: return int? */
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	int promisc, mc_count;
+
+	/* The Hermes doesn't seem to have an allmulti mode, so we go
+	 * into promiscuous mode and let the upper levels deal. */
+	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+	    (dev->mc_count > MAX_MULTICAST(priv))) {
+		promisc = 1;
+		mc_count = 0;
+	} else {
+		promisc = 0;
+		mc_count = dev->mc_count;
+	}
+
+	err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
+					      promisc);
+}
+
+/* This must be called from user context, without locks held - use
+ * schedule_work() */
+void orinoco_reset(struct work_struct *work)
+{
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, reset_work);
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	int err;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		/* When the hardware becomes available again, whatever
+		 * detects that is responsible for re-initializing
+		 * it. So no need for anything further */
+		return;
+
+	netif_stop_queue(dev);
+
+	/* Shut off interrupts.  Depending on what state the hardware
+	 * is in, this might not work, but we'll try anyway */
+	hermes_set_irqmask(hw, 0);
+	hermes_write_regn(hw, EVACK, 0xffff);
+
+	priv->hw_unavailable++;
+	priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
+	netif_carrier_off(dev);
+
+	orinoco_unlock(priv, &flags);
+
+	/* Scanning support: Cleanup of driver struct */
+	orinoco_clear_scan_results(priv, 0);
+	priv->scan_inprogress = 0;
+
+	if (priv->hard_reset) {
+		err = (*priv->hard_reset)(priv);
+		if (err) {
+			printk(KERN_ERR "%s: orinoco_reset: Error %d "
+			       "performing hard reset\n", dev->name, err);
+			goto disable;
+		}
+	}
+
+	err = orinoco_reinit_firmware(dev);
+	if (err) {
+		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
+		       dev->name, err);
+		goto disable;
+	}
+
+	/* This has to be called from user context */
+	spin_lock_irq(&priv->lock);
+
+	priv->hw_unavailable--;
+
+	/* priv->open or priv->hw_unavailable might have changed while
+	 * we dropped the lock */
+	if (priv->open && (!priv->hw_unavailable)) {
+		err = __orinoco_up(dev);
+		if (err) {
+			printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+			       dev->name, err);
+		} else
+			dev->trans_start = jiffies;
+	}
+
+	spin_unlock_irq(&priv->lock);
+
+	return;
+ disable:
+	hermes_set_irqmask(hw, 0);
+	netif_device_detach(dev);
+	printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
+}
+
+/********************************************************************/
+/* Interrupt handler                                                */
+/********************************************************************/
+
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
+{
+	printk(KERN_DEBUG "%s: TICK\n", dev->name);
+}
+
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
+{
+	/* This seems to happen a fair bit under load, but ignoring it
+	   seems to work fine...*/
+	printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
+	       dev->name);
+}
+
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int count = MAX_IRQLOOPS_PER_IRQ;
+	u16 evstat, events;
+	/* These are used to detect a runaway interrupt situation.
+	 *
+	 * If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
+	 * we panic and shut down the hardware
+	 */
+	/* jiffies value the last time we were called */
+	static int last_irq_jiffy; /* = 0 */
+	static int loops_this_jiffy; /* = 0 */
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		/* If hw is unavailable - we don't know if the irq was
+		 * for us or not */
+		return IRQ_HANDLED;
+	}
+
+	evstat = hermes_read_regn(hw, EVSTAT);
+	events = evstat & hw->inten;
+	if (!events) {
+		orinoco_unlock(priv, &flags);
+		return IRQ_NONE;
+	}
+
+	if (jiffies != last_irq_jiffy)
+		loops_this_jiffy = 0;
+	last_irq_jiffy = jiffies;
+
+	while (events && count--) {
+		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
+			printk(KERN_WARNING "%s: IRQ handler is looping too "
+			       "much! Resetting.\n", dev->name);
+			/* Disable interrupts for now */
+			hermes_set_irqmask(hw, 0);
+			schedule_work(&priv->reset_work);
+			break;
+		}
+
+		/* Check the card hasn't been removed */
+		if (!hermes_present(hw)) {
+			DEBUG(0, "orinoco_interrupt(): card removed\n");
+			break;
+		}
+
+		if (events & HERMES_EV_TICK)
+			__orinoco_ev_tick(dev, hw);
+		if (events & HERMES_EV_WTERR)
+			__orinoco_ev_wterr(dev, hw);
+		if (events & HERMES_EV_INFDROP)
+			__orinoco_ev_infdrop(dev, hw);
+		if (events & HERMES_EV_INFO)
+			__orinoco_ev_info(dev, hw);
+		if (events & HERMES_EV_RX)
+			__orinoco_ev_rx(dev, hw);
+		if (events & HERMES_EV_TXEXC)
+			__orinoco_ev_txexc(dev, hw);
+		if (events & HERMES_EV_TX)
+			__orinoco_ev_tx(dev, hw);
+		if (events & HERMES_EV_ALLOC)
+			__orinoco_ev_alloc(dev, hw);
+
+		hermes_write_regn(hw, EVACK, evstat);
+
+		evstat = hermes_read_regn(hw, EVSTAT);
+		events = evstat & hw->inten;
+	};
+
+	orinoco_unlock(priv, &flags);
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(orinoco_interrupt);
+
+/********************************************************************/
+/* Power management                                                 */
+/********************************************************************/
+#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
+static int orinoco_pm_notifier(struct notifier_block *notifier,
+			       unsigned long pm_event,
+			       void *unused)
+{
+	struct orinoco_private *priv = container_of(notifier,
+						    struct orinoco_private,
+						    pm_notifier);
+
+	/* All we need to do is cache the firmware before suspend, and
+	 * release it when we come out.
+	 *
+	 * Only need to do this if we're downloading firmware. */
+	if (!priv->do_fw_download)
+		return NOTIFY_DONE;
+
+	switch (pm_event) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		orinoco_cache_fw(priv, 0);
+		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:
+		orinoco_uncache_fw(priv);
+		break;
+
+	case PM_RESTORE_PREPARE:
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static void orinoco_register_pm_notifier(struct orinoco_private *priv)
+{
+	priv->pm_notifier.notifier_call = orinoco_pm_notifier;
+	register_pm_notifier(&priv->pm_notifier);
+}
+
+static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
+{
+	unregister_pm_notifier(&priv->pm_notifier);
+}
+#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
+#define orinoco_register_pm_notifier(priv) do { } while(0)
+#define orinoco_unregister_pm_notifier(priv) do { } while(0)
+#endif
+
+/********************************************************************/
+/* Initialization                                                   */
+/********************************************************************/
+
+struct comp_id {
+	u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+	if (nic_id->id < 0x8000)
+		return FIRMWARE_TYPE_AGERE;
+	else if (nic_id->id == 0x8000 && nic_id->major == 0)
+		return FIRMWARE_TYPE_SYMBOL;
+	else
+		return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct comp_id nic_id, sta_id;
+	unsigned int firmver;
+	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+	/* Get the hardware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+		       dev->name, err);
+		return err;
+	}
+
+	le16_to_cpus(&nic_id.id);
+	le16_to_cpus(&nic_id.variant);
+	le16_to_cpus(&nic_id.major);
+	le16_to_cpus(&nic_id.minor);
+	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+	       dev->name, nic_id.id, nic_id.variant,
+	       nic_id.major, nic_id.minor);
+
+	priv->firmware_type = determine_firmware_type(&nic_id);
+
+	/* Get the firmware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
+		       dev->name, err);
+		return err;
+	}
+
+	le16_to_cpus(&sta_id.id);
+	le16_to_cpus(&sta_id.variant);
+	le16_to_cpus(&sta_id.major);
+	le16_to_cpus(&sta_id.minor);
+	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
+	       dev->name, sta_id.id, sta_id.variant,
+	       sta_id.major, sta_id.minor);
+
+	switch (sta_id.id) {
+	case 0x15:
+		printk(KERN_ERR "%s: Primary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x14b:
+		printk(KERN_ERR "%s: Tertiary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
+	case 0x21:	/* Symbol Spectrum24 Trilogy */
+		break;
+	default:
+		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+		       dev->name);
+		break;
+	}
+
+	/* Default capabilities */
+	priv->has_sensitivity = 1;
+	priv->has_mwo = 0;
+	priv->has_preamble = 0;
+	priv->has_port3 = 1;
+	priv->has_ibss = 1;
+	priv->has_wep = 0;
+	priv->has_big_wep = 0;
+	priv->has_alt_txcntl = 0;
+	priv->has_ext_scan = 0;
+	priv->has_wpa = 0;
+	priv->do_fw_download = 0;
+
+	/* Determine capabilities from the firmware version */
+	switch (priv->firmware_type) {
+	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);
+
+		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+		priv->has_ibss = (firmver >= 0x60006);
+		priv->has_wep = (firmver >= 0x40020);
+		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+					  Gold cards from the others? */
+		priv->has_mwo = (firmver >= 0x60000);
+		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+		priv->ibss_port = 1;
+		priv->has_hostscan = (firmver >= 0x8000a);
+		priv->do_fw_download = 1;
+		priv->broken_monitor = (firmver >= 0x80000);
+		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_wpa = (firmver >= 0x9002a);
+		/* Tested with Agere firmware :
+		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+		 * Tested CableTron firmware : 4.32 => Anton */
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+		/* Intel MAC : 00:02:B3:* */
+		/* 3Com MAC : 00:50:DA:* */
+		memset(tmp, 0, sizeof(tmp));
+		/* Get the Symbol firmware version */
+		err = hermes_read_ltv(hw, USER_BAP,
+				      HERMES_RID_SECONDARYVERSION_SYMBOL,
+				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
+		if (err) {
+			printk(KERN_WARNING
+			       "%s: Error %d reading Symbol firmware info. "
+			       "Wildly guessing capabilities...\n",
+			       dev->name, err);
+			firmver = 0;
+			tmp[0] = '\0';
+		} else {
+			/* The firmware revision is a string, the format is
+			 * something like : "V2.20-01".
+			 * Quick and dirty parsing... - Jean II
+			 */
+			firmver = ((tmp[1] - '0') << 16)
+				| ((tmp[3] - '0') << 12)
+				| ((tmp[4] - '0') << 8)
+				| ((tmp[6] - '0') << 4)
+				| (tmp[7] - '0');
+
+			tmp[SYMBOL_MAX_VER_LEN] = '\0';
+		}
+
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Symbol %s", tmp);
+
+		priv->has_ibss = (firmver >= 0x20000);
+		priv->has_wep = (firmver >= 0x15012);
+		priv->has_big_wep = (firmver >= 0x20000);
+		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+			       (firmver >= 0x29000 && firmver < 0x30000) ||
+			       firmver >= 0x31000;
+		priv->has_preamble = (firmver >= 0x20000);
+		priv->ibss_port = 4;
+
+		/* Symbol firmware is found on various cards, but
+		 * there has been no attempt to check firmware
+		 * download on non-spectrum_cs based cards.
+		 *
+		 * Given that the Agere firmware download works
+		 * differently, we should avoid doing a firmware
+		 * download with the Symbol algorithm on non-spectrum
+		 * cards.
+		 *
+		 * For now we can identify a spectrum_cs based card
+		 * because it has a firmware reset function.
+		 */
+		priv->do_fw_download = (priv->stop_fw != NULL);
+
+		priv->broken_disableport = (firmver == 0x25013) ||
+				(firmver >= 0x30000 && firmver <= 0x31000);
+		priv->has_hostscan = (firmver >= 0x31001) ||
+				     (firmver >= 0x29057 && firmver < 0x30000);
+		/* Tested with Intel firmware : 0x20015 => Jean II */
+		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
+		 * Samsung, Compaq 100/200 and Proxim are slightly
+		 * 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);
+
+		firmver = ((unsigned long)sta_id.major << 16) |
+			((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+		priv->has_pm = (firmver >= 0x000700);
+		priv->has_hostscan = (firmver >= 0x010301);
+
+		if (firmver >= 0x000800)
+			priv->ibss_port = 0;
+		else {
+			printk(KERN_NOTICE "%s: Intersil firmware earlier "
+			       "than v0.8.x - several features not supported\n",
+			       dev->name);
+			priv->ibss_port = 1;
+		}
+		break;
+	}
+	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+	       priv->fw_name);
+
+	return 0;
+}
+
+static int orinoco_init(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	struct hermes_idstring nickbuf;
+	u16 reclen;
+	int len;
+
+	/* No need to lock, the hw_unavailable flag is already set in
+	 * alloc_orinocodev() */
+	priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
+
+	/* Initialize the firmware */
+	err = hermes_init(hw);
+	if (err != 0) {
+		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
+		       dev->name, err);
+		goto out;
+	}
+
+	err = determine_firmware(dev);
+	if (err != 0) {
+		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+		       dev->name);
+		goto out;
+	}
+
+	if (priv->do_fw_download) {
+#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
+		orinoco_cache_fw(priv, 0);
+#endif
+
+		err = orinoco_download(priv);
+		if (err)
+			priv->do_fw_download = 0;
+
+		/* Check firmware version again */
+		err = determine_firmware(dev);
+		if (err != 0) {
+			printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+			       dev->name);
+			goto out;
+		}
+	}
+
+	if (priv->has_port3)
+		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
+		       dev->name);
+	if (priv->has_ibss)
+		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
+		       dev->name);
+	if (priv->has_wep) {
+		printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
+		       priv->has_big_wep ? "104" : "40");
+	}
+	if (priv->has_wpa) {
+		printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+		if (orinoco_mic_init(priv)) {
+			printk(KERN_ERR "%s: Failed to setup MIC crypto "
+			       "algorithm. Disabling WPA support\n", dev->name);
+			priv->has_wpa = 0;
+		}
+	}
+
+	/* Now we have the firmware capabilities, allocate appropiate
+	 * sized scan buffers */
+	if (orinoco_bss_data_allocate(priv))
+		goto out;
+	orinoco_bss_data_init(priv);
+
+	/* Get the MAC address */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			      ETH_ALEN, NULL, dev->dev_addr);
+	if (err) {
+		printk(KERN_WARNING "%s: failed to read MAC address!\n",
+		       dev->name);
+		goto out;
+	}
+
+	printk(KERN_DEBUG "%s: MAC address %pM\n",
+	       dev->name, dev->dev_addr);
+
+	/* Get the station name */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			      sizeof(nickbuf), &reclen, &nickbuf);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read station name\n",
+		       dev->name);
+		goto out;
+	}
+	if (nickbuf.len)
+		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+	else
+		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+	memcpy(priv->nick, &nickbuf.val, len);
+	priv->nick[len] = '\0';
+
+	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+	err = orinoco_allocate_fid(dev);
+	if (err) {
+		printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Get allowed channels */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+				  &priv->channel_mask);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read channel list!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Get initial AP density */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+				  &priv->ap_density);
+	if (err || priv->ap_density < 1 || priv->ap_density > 3)
+		priv->has_sensitivity = 0;
+
+	/* Get initial RTS threshold */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				  &priv->rts_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Get initial fragmentation settings */
+	if (priv->has_mwo)
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMWOROBUST_AGERE,
+					  &priv->mwo_robust);
+	else
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					  &priv->frag_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Power management setup */
+	if (priv->has_pm) {
+		priv->pm_on = 0;
+		priv->pm_mcast = 1;
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMAXSLEEPDURATION,
+					  &priv->pm_period);
+		if (err) {
+			printk(KERN_ERR "%s: failed to read power management period!\n",
+			       dev->name);
+			goto out;
+		}
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPMHOLDOVERDURATION,
+					  &priv->pm_timeout);
+		if (err) {
+			printk(KERN_ERR "%s: failed to read power management timeout!\n",
+			       dev->name);
+			goto out;
+		}
+	}
+
+	/* Preamble setup */
+	if (priv->has_preamble) {
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPREAMBLE_SYMBOL,
+					  &priv->preamble);
+		if (err)
+			goto out;
+	}
+
+	/* Set up the default configuration */
+	priv->iw_mode = IW_MODE_INFRA;
+	/* By default use IEEE/IBSS ad-hoc mode if we have it */
+	priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
+	set_port_type(priv);
+	priv->channel = 0; /* use firmware default */
+
+	priv->promiscuous = 0;
+	priv->encode_alg = IW_ENCODE_ALG_NONE;
+	priv->tx_key = 0;
+	priv->wpa_enabled = 0;
+	priv->tkip_cm_active = 0;
+	priv->key_mgmt = 0;
+	priv->wpa_ie_len = 0;
+	priv->wpa_ie = NULL;
+
+	/* Make the hardware available, as long as it hasn't been
+	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
+	spin_lock_irq(&priv->lock);
+	priv->hw_unavailable--;
+	spin_unlock_irq(&priv->lock);
+
+	printk(KERN_DEBUG "%s: ready\n", dev->name);
+
+ out:
+	return err;
+}
+
+static const struct net_device_ops orinoco_netdev_ops = {
+	.ndo_init		= orinoco_init,
+	.ndo_open		= orinoco_open,
+	.ndo_stop		= orinoco_stop,
+	.ndo_start_xmit		= orinoco_xmit,
+	.ndo_set_multicast_list	= orinoco_set_multicast_list,
+	.ndo_change_mtu		= orinoco_change_mtu,
+	.ndo_tx_timeout		= orinoco_tx_timeout,
+	.ndo_get_stats		= orinoco_get_stats,
+};
+
+struct net_device
+*alloc_orinocodev(int sizeof_card,
+		  struct device *device,
+		  int (*hard_reset)(struct orinoco_private *),
+		  int (*stop_fw)(struct orinoco_private *, int))
+{
+	struct net_device *dev;
+	struct orinoco_private *priv;
+
+	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+	if (!dev)
+		return NULL;
+	priv = netdev_priv(dev);
+	priv->ndev = dev;
+	if (sizeof_card)
+		priv->card = (void *)((unsigned long)priv
+				      + sizeof(struct orinoco_private));
+	else
+		priv->card = NULL;
+	priv->dev = device;
+
+	/* Setup / override net_device fields */
+	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
+	priv->wireless_data.spy_data = &priv->spy_data;
+	dev->wireless_data = &priv->wireless_data;
+#endif
+	/* we use the default eth_mac_addr for setting the MAC addr */
+
+	/* Reserve space in skb for the SNAP header */
+	dev->hard_header_len += ENCAPS_OVERHEAD;
+
+	/* Set up default callbacks */
+	priv->hard_reset = hard_reset;
+	priv->stop_fw = stop_fw;
+
+	spin_lock_init(&priv->lock);
+	priv->open = 0;
+	priv->hw_unavailable = 1; /* orinoco_init() must clear this
+				   * before anything else touches the
+				   * hardware */
+	INIT_WORK(&priv->reset_work, orinoco_reset);
+	INIT_WORK(&priv->join_work, orinoco_join_ap);
+	INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
+
+	INIT_LIST_HEAD(&priv->rx_list);
+	tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
+		     (unsigned long) dev);
+
+	netif_carrier_off(dev);
+	priv->last_linkstatus = 0xffff;
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+	priv->cached_pri_fw = NULL;
+	priv->cached_fw = NULL;
+#endif
+
+	/* Register PM notifiers */
+	orinoco_register_pm_notifier(priv);
+
+	return dev;
+}
+EXPORT_SYMBOL(alloc_orinocodev);
+
+void free_orinocodev(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_rx_data *rx_data, *temp;
+
+	/* If the tasklet is scheduled when we call tasklet_kill it
+	 * will run one final time. However the tasklet will only
+	 * drain priv->rx_list if the hw is still available. */
+	tasklet_kill(&priv->rx_tasklet);
+
+	/* Explicitly drain priv->rx_list */
+	list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+		list_del(&rx_data->list);
+
+		dev_kfree_skb(rx_data->skb);
+		kfree(rx_data->desc);
+		kfree(rx_data);
+	}
+
+	orinoco_unregister_pm_notifier(priv);
+	orinoco_uncache_fw(priv);
+
+	priv->wpa_ie_len = 0;
+	kfree(priv->wpa_ie);
+	orinoco_mic_free(priv);
+	orinoco_bss_data_free(priv);
+	free_netdev(dev);
+}
+EXPORT_SYMBOL(free_orinocodev);
+
+static void orinoco_get_drvinfo(struct net_device *dev,
+				struct ethtool_drvinfo *info)
+{
+	struct orinoco_private *priv = netdev_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                                            */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+	" (David Gibson <hermes@gibson.dropbear.id.au>, "
+	"Pavel Roskin <proski@gnu.org>, et al)";
+
+static int __init init_orinoco(void)
+{
+	printk(KERN_DEBUG "%s\n", version);
+	return 0;
+}
+
+static void __exit exit_orinoco(void)
+{
+}
+
+module_init(init_orinoco);
+module_exit(exit_orinoco);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/main.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/main.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,63 @@
+/* Exports from main to helper modules
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MAIN_H_
+#define _ORINOCO_MAIN_H_
+
+#include <linux/ieee80211.h>
+#include "orinoco.h"
+
+/********************************************************************/
+/* Compile time configuration and compatibility stuff               */
+/********************************************************************/
+
+/* We do this this way to avoid ifdefs in the actual code */
+#ifdef WIRELESS_SPY
+#define SPY_NUMBER(priv)	(priv->spy_data.spy_number)
+#else
+#define SPY_NUMBER(priv)	0
+#endif /* WIRELESS_SPY */
+
+/********************************************************************/
+
+/* Export module parameter */
+extern int force_monitor;
+
+/* Forward declarations */
+struct net_device;
+struct work_struct;
+
+void set_port_type(struct orinoco_private *priv);
+int __orinoco_program_rids(struct net_device *dev);
+void orinoco_reset(struct work_struct *work);
+
+
+/* Information element helpers - find a home for these... */
+static inline u8 *orinoco_get_ie(u8 *data, size_t len,
+				 enum ieee80211_eid eid)
+{
+	u8 *p = data;
+	while ((p + 2) < (data + len)) {
+		if (p[0] == eid)
+			return p;
+		p += p[1] + 2;
+	}
+	return NULL;
+}
+
+#define WPA_OUI_TYPE	"\x00\x50\xF2\x01"
+#define WPA_SELECTOR_LEN 4
+static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
+{
+	u8 *p = data;
+	while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
+		if ((p[0] == WLAN_EID_GENERIC) &&
+		    (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
+			return p;
+		p += p[1] + 2;
+	}
+	return NULL;
+}
+
+#endif /* _ORINOCO_MAIN_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,8 +1,9 @@
 #
 # Makefile for the orinoco wireless device drivers.
 #
+orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
 
-obj-$(CONFIG_HERMES)		+= orinoco.o hermes.o hermes_dld.o
+obj-$(CONFIG_HERMES)		+= orinoco.o
 obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
 obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o
 obj-$(CONFIG_PLX_HERMES)	+= orinoco_plx.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/mic.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/mic.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/mic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/mic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,79 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/if_ether.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+
+#include "orinoco.h"
+#include "mic.h"
+
+/********************************************************************/
+/* Michael MIC crypto setup                                         */
+/********************************************************************/
+int orinoco_mic_init(struct orinoco_private *priv)
+{
+	priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+	if (IS_ERR(priv->tx_tfm_mic)) {
+		printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+		       "crypto API michael_mic\n");
+		priv->tx_tfm_mic = NULL;
+		return -ENOMEM;
+	}
+
+	priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+	if (IS_ERR(priv->rx_tfm_mic)) {
+		printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+		       "crypto API michael_mic\n");
+		priv->rx_tfm_mic = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void orinoco_mic_free(struct orinoco_private *priv)
+{
+	if (priv->tx_tfm_mic)
+		crypto_free_hash(priv->tx_tfm_mic);
+	if (priv->rx_tfm_mic)
+		crypto_free_hash(priv->rx_tfm_mic);
+}
+
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+		u8 *da, u8 *sa, u8 priority,
+		u8 *data, size_t data_len, u8 *mic)
+{
+	struct hash_desc desc;
+	struct scatterlist sg[2];
+	u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
+
+	if (tfm_michael == NULL) {
+		printk(KERN_WARNING "orinoco_mic: tfm_michael == NULL\n");
+		return -1;
+	}
+
+	/* Copy header into buffer. We need the padding on the end zeroed */
+	memcpy(&hdr[0], da, ETH_ALEN);
+	memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
+	hdr[ETH_ALEN*2] = priority;
+	hdr[ETH_ALEN*2+1] = 0;
+	hdr[ETH_ALEN*2+2] = 0;
+	hdr[ETH_ALEN*2+3] = 0;
+
+	/* Use scatter gather to MIC header and data in one go */
+	sg_init_table(sg, 2);
+	sg_set_buf(&sg[0], hdr, sizeof(hdr));
+	sg_set_buf(&sg[1], data, data_len);
+
+	if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
+		return -1;
+
+	desc.tfm = tfm_michael;
+	desc.flags = 0;
+	return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
+				  mic);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/mic.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/mic.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/mic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/mic.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,22 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MIC_H_
+#define _ORINOCO_MIC_H_
+
+#include <linux/types.h>
+
+#define MICHAEL_MIC_LEN 8
+
+/* Forward declarations */
+struct orinoco_private;
+struct crypto_hash;
+
+int orinoco_mic_init(struct orinoco_private *priv);
+void orinoco_mic_free(struct orinoco_private *priv);
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+		u8 *da, u8 *sa, u8 priority,
+		u8 *data, size_t data_len, u8 *mic);
+
+#endif /* ORINOCO_MIC_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco.c	2013-05-03 18:04:15.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,6159 +0,0 @@
-/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
- *
- * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
- * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
- *
- * Current maintainers (as of 29 September 2003) are:
- * 	Pavel Roskin <proski AT gnu.org>
- * and	David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * (C) Copyright David Gibson, IBM Corporation 2001-2003.
- * Copyright (C) 2000 David Gibson, Linuxcare Australia.
- *	With some help from :
- * Copyright (C) 2001 Jean Tourrilhes, HP Labs
- * Copyright (C) 2001 Benjamin Herrenschmidt
- *
- * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
- *
- * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
- * AT fasta.fh-dortmund.de>
- *      http://www.stud.fh-dortmund.de/~andy/wvlan/
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds AT users.sourceforge.net>.  Portions created by David
- * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
- * Reserved.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.  */
-
-/*
- * TODO
- *	o Handle de-encapsulation within network layer, provide 802.11
- *	  headers (patch from Thomas 'Dent' Mirlacher)
- *	o Fix possible races in SPY handling.
- *	o Disconnect wireless extensions from fundamental configuration.
- *	o (maybe) Software WEP support (patch from Stano Meduna).
- *	o (maybe) Use multiple Tx buffers - driver handling queue
- *	  rather than firmware.
- */
-
-/* Locking and synchronization:
- *
- * The basic principle is that everything is serialized through a
- * single spinlock, priv->lock.  The lock is used in user, bh and irq
- * context, so when taken outside hardirq context it should always be
- * taken with interrupts disabled.  The lock protects both the
- * hardware and the struct orinoco_private.
- *
- * Another flag, priv->hw_unavailable indicates that the hardware is
- * unavailable for an extended period of time (e.g. suspended, or in
- * the middle of a hard reset).  This flag is protected by the
- * spinlock.  All code which touches the hardware should check the
- * flag after taking the lock, and if it is set, give up on whatever
- * they are doing and drop the lock again.  The orinoco_lock()
- * function handles this (it unlocks and returns -EBUSY if
- * hw_unavailable is non-zero).
- */
-
-#define DRIVER_NAME "orinoco"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/firmware.h>
-#include <linux/suspend.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <net/iw_handler.h>
-
-#include <linux/scatterlist.h>
-#include <linux/crypto.h>
-
-#include "hermes_rid.h"
-#include "hermes_dld.h"
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module information                                               */
-/********************************************************************/
-
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Level of debugging. Used in the macros in orinoco.h */
-#ifdef ORINOCO_DEBUG
-int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0644);
-MODULE_PARM_DESC(orinoco_debug, "Debug level");
-EXPORT_SYMBOL(orinoco_debug);
-#endif
-
-static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0644);
-MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
-static int ignore_disconnect; /* = 0 */
-module_param(ignore_disconnect, int, 0644);
-MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
-
-static int force_monitor; /* = 0 */
-module_param(force_monitor, int, 0644);
-MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
-
-/********************************************************************/
-/* Compile time configuration and compatibility stuff               */
-/********************************************************************/
-
-/* We do this this way to avoid ifdefs in the actual code */
-#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv)	(priv->spy_data.spy_number)
-#else
-#define SPY_NUMBER(priv)	0
-#endif /* WIRELESS_SPY */
-
-/********************************************************************/
-/* Internal constants                                               */
-/********************************************************************/
-
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
-
-#define ORINOCO_MIN_MTU		256
-#define ORINOCO_MAX_MTU		(IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
-
-#define SYMBOL_MAX_VER_LEN	(14)
-#define USER_BAP		0
-#define IRQ_BAP			1
-#define MAX_IRQLOOPS_PER_IRQ	10
-#define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ) /* Based on a guestimate of
-					    * how many events the
-					    * device could
-					    * legitimately generate */
-#define SMALL_KEY_SIZE		5
-#define LARGE_KEY_SIZE		13
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
-
-#define DUMMY_FID		0xFFFF
-
-/*#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
-  HERMES_MAX_MULTICAST : 0)*/
-#define MAX_MULTICAST(priv)	(HERMES_MAX_MULTICAST)
-
-#define ORINOCO_INTEN	 	(HERMES_EV_RX | HERMES_EV_ALLOC \
-				 | HERMES_EV_TX | HERMES_EV_TXEXC \
-				 | HERMES_EV_WTERR | HERMES_EV_INFO \
-				 | HERMES_EV_INFDROP )
-
-#define MAX_RID_LEN 1024
-
-static const struct iw_handler_def orinoco_handler_def;
-static const struct ethtool_ops orinoco_ethtool_ops;
-
-/********************************************************************/
-/* Data tables                                                      */
-/********************************************************************/
-
-/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
-	2412, 2417, 2422, 2427, 2432, 2437, 2442,
-	2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
-
-/* This tables gives the actual meanings of the bitrate IDs returned
- * by the firmware. */
-static struct {
-	int bitrate; /* in 100s of kilobits */
-	int automatic;
-	u16 agere_txratectrl;
-	u16 intersil_txratectrl;
-} bitrate_table[] = {
-	{110, 1,  3, 15}, /* Entry 0 is the default */
-	{10,  0,  1,  1},
-	{10,  1,  1,  1},
-	{20,  0,  2,  2},
-	{20,  1,  6,  3},
-	{55,  0,  4,  4},
-	{55,  1,  7,  7},
-	{110, 0,  5,  8},
-};
-#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
-
-/********************************************************************/
-/* Data types                                                       */
-/********************************************************************/
-
-/* Beginning of the Tx descriptor, used in TxExc handling */
-struct hermes_txexc_data {
-	struct hermes_tx_descriptor desc;
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-} __attribute__ ((packed));
-
-/* Rx frame header except compatibility 802.3 header */
-struct hermes_rx_descriptor {
-	/* Control */
-	__le16 status;
-	__le32 time;
-	u8 silence;
-	u8 signal;
-	u8 rate;
-	u8 rxflow;
-	__le32 reserved;
-
-	/* 802.11 header */
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-
-	/* Data length */
-	__le16 data_len;
-} __attribute__ ((packed));
-
-/********************************************************************/
-/* Function prototypes                                              */
-/********************************************************************/
-
-static int __orinoco_program_rids(struct net_device *dev);
-static void __orinoco_set_multicast_list(struct net_device *dev);
-
-/********************************************************************/
-/* Michael MIC crypto setup                                         */
-/********************************************************************/
-#define MICHAEL_MIC_LEN 8
-static int orinoco_mic_init(struct orinoco_private *priv)
-{
-	priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
-	if (IS_ERR(priv->tx_tfm_mic)) {
-		printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
-		       "crypto API michael_mic\n");
-		priv->tx_tfm_mic = NULL;
-		return -ENOMEM;
-	}
-
-	priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
-	if (IS_ERR(priv->rx_tfm_mic)) {
-		printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
-		       "crypto API michael_mic\n");
-		priv->rx_tfm_mic = NULL;
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void orinoco_mic_free(struct orinoco_private *priv)
-{
-	if (priv->tx_tfm_mic)
-		crypto_free_hash(priv->tx_tfm_mic);
-	if (priv->rx_tfm_mic)
-		crypto_free_hash(priv->rx_tfm_mic);
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
-		       u8 *da, u8 *sa, u8 priority,
-		       u8 *data, size_t data_len, u8 *mic)
-{
-	struct hash_desc desc;
-	struct scatterlist sg[2];
-	u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
-
-	if (tfm_michael == NULL) {
-		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-		return -1;
-	}
-
-	/* Copy header into buffer. We need the padding on the end zeroed */
-	memcpy(&hdr[0], da, ETH_ALEN);
-	memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
-	hdr[ETH_ALEN*2] = priority;
-	hdr[ETH_ALEN*2+1] = 0;
-	hdr[ETH_ALEN*2+2] = 0;
-	hdr[ETH_ALEN*2+3] = 0;
-
-	/* Use scatter gather to MIC header and data in one go */
-	sg_init_table(sg, 2);
-	sg_set_buf(&sg[0], hdr, sizeof(hdr));
-	sg_set_buf(&sg[1], data, data_len);
-
-	if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
-		return -1;
-
-	desc.tfm = tfm_michael;
-	desc.flags = 0;
-	return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
-				  mic);
-}
-
-/********************************************************************/
-/* Internal helper functions                                        */
-/********************************************************************/
-
-static inline void set_port_type(struct orinoco_private *priv)
-{
-	switch (priv->iw_mode) {
-	case IW_MODE_INFRA:
-		priv->port_type = 1;
-		priv->createibss = 0;
-		break;
-	case IW_MODE_ADHOC:
-		if (priv->prefer_port3) {
-			priv->port_type = 3;
-			priv->createibss = 0;
-		} else {
-			priv->port_type = priv->ibss_port;
-			priv->createibss = 1;
-		}
-		break;
-	case IW_MODE_MONITOR:
-		priv->port_type = 3;
-		priv->createibss = 0;
-		break;
-	default:
-		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
-		       priv->ndev->name);
-	}
-}
-
-#define ORINOCO_MAX_BSS_COUNT	64
-static int orinoco_bss_data_allocate(struct orinoco_private *priv)
-{
-	if (priv->bss_xbss_data)
-		return 0;
-
-	if (priv->has_ext_scan)
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct xbss_element),
-					      GFP_KERNEL);
-	else
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct bss_element),
-					      GFP_KERNEL);
-
-	if (!priv->bss_xbss_data) {
-		printk(KERN_WARNING "Out of memory allocating beacons");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-static void orinoco_bss_data_free(struct orinoco_private *priv)
-{
-	kfree(priv->bss_xbss_data);
-	priv->bss_xbss_data = NULL;
-}
-
-#define PRIV_BSS	((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS	((struct xbss_element *)priv->bss_xbss_data)
-static void orinoco_bss_data_init(struct orinoco_private *priv)
-{
-	int i;
-
-	INIT_LIST_HEAD(&priv->bss_free_list);
-	INIT_LIST_HEAD(&priv->bss_list);
-	if (priv->has_ext_scan)
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_XBSS[i].list),
-				      &priv->bss_free_list);
-	else
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_BSS[i].list),
-				      &priv->bss_free_list);
-
-}
-
-static inline u8 *orinoco_get_ie(u8 *data, size_t len,
-				 enum ieee80211_eid eid)
-{
-	u8 *p = data;
-	while ((p + 2) < (data + len)) {
-		if (p[0] == eid)
-			return p;
-		p += p[1] + 2;
-	}
-	return NULL;
-}
-
-#define WPA_OUI_TYPE	"\x00\x50\xF2\x01"
-#define WPA_SELECTOR_LEN 4
-static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
-{
-	u8 *p = data;
-	while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
-		if ((p[0] == WLAN_EID_GENERIC) &&
-		    (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
-			return p;
-		p += p[1] + 2;
-	}
-	return NULL;
-}
-
-
-/********************************************************************/
-/* Download functionality                                           */
-/********************************************************************/
-
-struct fw_info {
-	char *pri_fw;
-	char *sta_fw;
-	char *ap_fw;
-	u32 pda_addr;
-	u16 pda_size;
-};
-
-const static struct fw_info orinoco_fw[] = {
-	{ NULL, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", 0x00390000, 1000 },
-	{ NULL, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", 0, 1024 },
-	{ "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/", NULL, 0x00003100, 512 }
-};
-
-/* Structure used to access fields in FW
- * Make sure LE decoding macros are used
- */
-struct orinoco_fw_header {
-	char hdr_vers[6];       /* ASCII string for header version */
-	__le16 headersize;      /* Total length of header */
-	__le32 entry_point;     /* NIC entry point */
-	__le32 blocks;          /* Number of blocks to program */
-	__le32 block_offset;    /* Offset of block data from eof header */
-	__le32 pdr_offset;      /* Offset to PDR data from eof header */
-	__le32 pri_offset;      /* Offset to primary plug data */
-	__le32 compat_offset;   /* Offset to compatibility data*/
-	char signature[0];      /* FW signature length headersize-20 */
-} __attribute__ ((packed));
-
-/* Download either STA or AP firmware into the card. */
-static int
-orinoco_dl_firmware(struct orinoco_private *priv,
-		    const struct fw_info *fw,
-		    int ap)
-{
-	/* Plug Data Area (PDA) */
-	__le16 *pda;
-
-	hermes_t *hw = &priv->hw;
-	const struct firmware *fw_entry;
-	const struct orinoco_fw_header *hdr;
-	const unsigned char *first_block;
-	const unsigned char *end;
-	const char *firmware;
-	struct net_device *dev = priv->ndev;
-	int err = 0;
-
-	pda = kzalloc(fw->pda_size, GFP_KERNEL);
-	if (!pda)
-		return -ENOMEM;
-
-	if (ap)
-		firmware = fw->ap_fw;
-	else
-		firmware = fw->sta_fw;
-
-	printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
-	       dev->name, firmware);
-
-	/* Read current plug data */
-	err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
-	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
-	if (err)
-		goto free;
-
-	if (!priv->cached_fw) {
-		err = reject_firmware(&fw_entry, firmware, priv->dev);
-
-		if (err) {
-			printk(KERN_ERR "%s: Cannot find firmware %s\n",
-			       dev->name, firmware);
-			err = -ENOENT;
-			goto free;
-		}
-	} else
-		fw_entry = priv->cached_fw;
-
-	hdr = (const struct orinoco_fw_header *) fw_entry->data;
-
-	/* Enable aux port to allow programming */
-	err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
-	printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
-	if (err != 0)
-		goto abort;
-
-	/* Program data */
-	first_block = (fw_entry->data +
-		       le16_to_cpu(hdr->headersize) +
-		       le32_to_cpu(hdr->block_offset));
-	end = fw_entry->data + fw_entry->size;
-
-	err = hermes_program(hw, first_block, end);
-	printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
-	if (err != 0)
-		goto abort;
-
-	/* Update production data */
-	first_block = (fw_entry->data +
-		       le16_to_cpu(hdr->headersize) +
-		       le32_to_cpu(hdr->pdr_offset));
-
-	err = hermes_apply_pda_with_defaults(hw, first_block, pda);
-	printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
-	if (err)
-		goto abort;
-
-	/* Tell card we've finished */
-	err = hermesi_program_end(hw);
-	printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
-	if (err != 0)
-		goto abort;
-
-	/* Check if we're running */
-	printk(KERN_DEBUG "%s: hermes_present returned %d\n",
-	       dev->name, hermes_present(hw));
-
-abort:
-	/* If we requested the firmware, release it. */
-	if (!priv->cached_fw)
-		release_firmware(fw_entry);
-
-free:
-	kfree(pda);
-	return err;
-}
-
-/* End markers */
-#define TEXT_END	0x1A		/* End of text header */
-
-/*
- * Process a firmware image - stop the card, load the firmware, reset
- * the card and make sure it responds.  For the secondary firmware take
- * care of the PDA - read it and then write it on top of the firmware.
- */
-static int
-symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
-		const unsigned char *image, const unsigned char *end,
-		int secondary)
-{
-	hermes_t *hw = &priv->hw;
-	int ret = 0;
-	const unsigned char *ptr;
-	const unsigned char *first_block;
-
-	/* Plug Data Area (PDA) */
-	__le16 *pda = NULL;
-
-	/* Binary block begins after the 0x1A marker */
-	ptr = image;
-	while (*ptr++ != TEXT_END);
-	first_block = ptr;
-
-	/* Read the PDA from EEPROM */
-	if (secondary) {
-		pda = kzalloc(fw->pda_size, GFP_KERNEL);
-		if (!pda)
-			return -ENOMEM;
-
-		ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
-		if (ret)
-			goto free;
-	}
-
-	/* Stop the firmware, so that it can be safely rewritten */
-	if (priv->stop_fw) {
-		ret = priv->stop_fw(priv, 1);
-		if (ret)
-			goto free;
-	}
-
-	/* Program the adapter with new firmware */
-	ret = hermes_program(hw, first_block, end);
-	if (ret)
-		goto free;
-
-	/* Write the PDA to the adapter */
-	if (secondary) {
-		size_t len = hermes_blocks_length(first_block);
-		ptr = first_block + len;
-		ret = hermes_apply_pda(hw, ptr, pda);
-		kfree(pda);
-		if (ret)
-			return ret;
-	}
-
-	/* Run the firmware */
-	if (priv->stop_fw) {
-		ret = priv->stop_fw(priv, 0);
-		if (ret)
-			return ret;
-	}
-
-	/* Reset hermes chip and make sure it responds */
-	ret = hermes_init(hw);
-
-	/* hermes_reset() should return 0 with the secondary firmware */
-	if (secondary && ret != 0)
-		return -ENODEV;
-
-	/* And this should work with any firmware */
-	if (!hermes_present(hw))
-		return -ENODEV;
-
-	return 0;
-
-free:
-	kfree(pda);
-	return ret;
-}
-
-
-/*
- * Download the firmware into the card, this also does a PCMCIA soft
- * reset on the card, to make sure it's in a sane state.
- */
-static int
-symbol_dl_firmware(struct orinoco_private *priv,
-		   const struct fw_info *fw)
-{
-	struct net_device *dev = priv->ndev;
-	int ret;
-	const struct firmware *fw_entry;
-
-	if (!priv->cached_pri_fw) {
-		if (reject_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->pri_fw);
-			return -ENOENT;
-		}
-	} else
-		fw_entry = priv->cached_pri_fw;
-
-	/* Load primary firmware */
-	ret = symbol_dl_image(priv, fw, fw_entry->data,
-			      fw_entry->data + fw_entry->size, 0);
-
-	if (!priv->cached_pri_fw)
-		release_firmware(fw_entry);
-	if (ret) {
-		printk(KERN_ERR "%s: Primary firmware download failed\n",
-		       dev->name);
-		return ret;
-	}
-
-	if (!priv->cached_fw) {
-		if (reject_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->sta_fw);
-			return -ENOENT;
-		}
-	} else
-		fw_entry = priv->cached_fw;
-
-	/* Load secondary firmware */
-	ret = symbol_dl_image(priv, fw, fw_entry->data,
-			      fw_entry->data + fw_entry->size, 1);
-	if (!priv->cached_fw)
-		release_firmware(fw_entry);
-	if (ret) {
-		printk(KERN_ERR "%s: Secondary firmware download failed\n",
-		       dev->name);
-	}
-
-	return ret;
-}
-
-static int orinoco_download(struct orinoco_private *priv)
-{
-	int err = 0;
-	/* Reload firmware */
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		/* case FIRMWARE_TYPE_INTERSIL: */
-		err = orinoco_dl_firmware(priv,
-					  &orinoco_fw[priv->firmware_type], 0);
-		break;
-
-	case FIRMWARE_TYPE_SYMBOL:
-		err = symbol_dl_firmware(priv,
-					 &orinoco_fw[priv->firmware_type]);
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		break;
-	}
-	/* TODO: if we fail we probably need to reinitialise
-	 * the driver */
-
-	return err;
-}
-
-#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
-static void orinoco_cache_fw(struct orinoco_private *priv, int ap)
-{
-	const struct firmware *fw_entry = NULL;
-	const char *pri_fw;
-	const char *fw;
-
-	pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
-	if (ap)
-		fw = orinoco_fw[priv->firmware_type].ap_fw;
-	else
-		fw = orinoco_fw[priv->firmware_type].sta_fw;
-
-	if (pri_fw) {
-		if (reject_firmware(&fw_entry, pri_fw, priv->dev) == 0)
-			priv->cached_pri_fw = fw_entry;
-	}
-
-	if (fw) {
-		if (reject_firmware(&fw_entry, fw, priv->dev) == 0)
-			priv->cached_fw = fw_entry;
-	}
-}
-
-static void orinoco_uncache_fw(struct orinoco_private *priv)
-{
-	if (priv->cached_pri_fw)
-		release_firmware(priv->cached_pri_fw);
-	if (priv->cached_fw)
-		release_firmware(priv->cached_fw);
-
-	priv->cached_pri_fw = NULL;
-	priv->cached_fw = NULL;
-}
-#else
-#define orinoco_cache_fw(priv, ap)
-#define orinoco_uncache_fw(priv)
-#endif
-
-/********************************************************************/
-/* Device methods                                                   */
-/********************************************************************/
-
-static int orinoco_open(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-	int err;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	err = __orinoco_up(dev);
-
-	if (! err)
-		priv->open = 1;
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_stop(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-
-	/* We mustn't use orinoco_lock() here, because we need to be
-	   able to close the interface even if hw_unavailable is set
-	   (e.g. as we're released after a PC Card removal) */
-	spin_lock_irq(&priv->lock);
-
-	priv->open = 0;
-
-	err = __orinoco_down(dev);
-
-	spin_unlock_irq(&priv->lock);
-
-	return err;
-}
-
-static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	
-	return &priv->stats;
-}
-
-static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_statistics *wstats = &priv->wstats;
-	int err;
-	unsigned long flags;
-
-	if (! netif_device_present(dev)) {
-		printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
-		       dev->name);
-		return NULL; /* FIXME: Can we do better than this? */
-	}
-
-	/* If busy, return the old stats.  Returning NULL may cause
-	 * the interface to disappear from /proc/net/wireless */
-	if (orinoco_lock(priv, &flags) != 0)
-		return wstats;
-
-	/* We can't really wait for the tallies inquiry command to
-	 * complete, so we just use the previous results and trigger
-	 * a new tallies inquiry command for next time - Jean II */
-	/* FIXME: Really we should wait for the inquiry to come back -
-	 * as it is the stats we give don't make a whole lot of sense.
-	 * Unfortunately, it's not clear how to do that within the
-	 * wireless extensions framework: I think we're in user
-	 * context, but a lock seems to be held by the time we get in
-	 * here so we're not safe to sleep here. */
-	hermes_inquire(hw, HERMES_INQ_TALLIES);
-
-	if (priv->iw_mode == IW_MODE_ADHOC) {
-		memset(&wstats->qual, 0, sizeof(wstats->qual));
-		/* If a spy address is defined, we report stats of the
-		 * first spy address - Jean II */
-		if (SPY_NUMBER(priv)) {
-			wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
-			wstats->qual.level = priv->spy_data.spy_stat[0].level;
-			wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
-			wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
-		}
-	} else {
-		struct {
-			__le16 qual, signal, noise, unused;
-		} __attribute__ ((packed)) cq;
-
-		err = HERMES_READ_RECORD(hw, USER_BAP,
-					 HERMES_RID_COMMSQUALITY, &cq);
-
-		if (!err) {
-			wstats->qual.qual = (int)le16_to_cpu(cq.qual);
-			wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
-			wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
-			wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-		}
-	}
-
-	orinoco_unlock(priv, &flags);
-	return wstats;
-}
-
-static void orinoco_set_multicast_list(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0) {
-		printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
-		       "called when hw_unavailable\n", dev->name);
-		return;
-	}
-
-	__orinoco_set_multicast_list(dev);
-	orinoco_unlock(priv, &flags);
-}
-
-static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
-		return -EINVAL;
-
-	/* MTU + encapsulation + header length */
-	if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
-	     (priv->nicbuf_size - ETH_HLEN) )
-		return -EINVAL;
-
-	dev->mtu = new_mtu;
-
-	return 0;
-}
-
-/********************************************************************/
-/* Tx path                                                          */
-/********************************************************************/
-
-static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	u16 txfid = priv->txfid;
-	struct ethhdr *eh;
-	int tx_control;
-	unsigned long flags;
-
-	if (! netif_running(dev)) {
-		printk(KERN_ERR "%s: Tx on stopped device!\n",
-		       dev->name);
-		return NETDEV_TX_BUSY;
-	}
-	
-	if (netif_queue_stopped(dev)) {
-		printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
-		       dev->name);
-		return NETDEV_TX_BUSY;
-	}
-	
-	if (orinoco_lock(priv, &flags) != 0) {
-		printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
-		       dev->name);
-		return NETDEV_TX_BUSY;
-	}
-
-	if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
-		/* Oops, the firmware hasn't established a connection,
-                   silently drop the packet (this seems to be the
-                   safest approach). */
-		goto drop;
-	}
-
-	/* Check packet length */
-	if (skb->len < ETH_HLEN)
-		goto drop;
-
-	tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
-
-	if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
-		tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
-			HERMES_TXCTRL_MIC;
-
-	if (priv->has_alt_txcntl) {
-		/* WPA enabled firmwares have tx_cntl at the end of
-		 * the 802.11 header.  So write zeroed descriptor and
-		 * 802.11 header at the same time
-		 */
-		char desc[HERMES_802_3_OFFSET];
-		__le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
-
-		memset(&desc, 0, sizeof(desc));
-
-		*txcntl = cpu_to_le16(tx_control);
-		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
-					txfid, 0);
-		if (err) {
-			if (net_ratelimit())
-				printk(KERN_ERR "%s: Error %d writing Tx "
-				       "descriptor to BAP\n", dev->name, err);
-			goto busy;
-		}
-	} else {
-		struct hermes_tx_descriptor desc;
-
-		memset(&desc, 0, sizeof(desc));
-
-		desc.tx_control = cpu_to_le16(tx_control);
-		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
-					txfid, 0);
-		if (err) {
-			if (net_ratelimit())
-				printk(KERN_ERR "%s: Error %d writing Tx "
-				       "descriptor to BAP\n", dev->name, err);
-			goto busy;
-		}
-
-		/* Clear the 802.11 header and data length fields - some
-		 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
-		 * if this isn't done. */
-		hermes_clear_words(hw, HERMES_DATA0,
-				   HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
-	}
-
-	eh = (struct ethhdr *)skb->data;
-
-	/* Encapsulate Ethernet-II frames */
-	if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
-		struct header_struct {
-			struct ethhdr eth;	/* 802.3 header */
-			u8 encap[6];		/* 802.2 header */
-		} __attribute__ ((packed)) hdr;
-
-		/* Strip destination and source from the data */
-		skb_pull(skb, 2 * ETH_ALEN);
-
-		/* And move them to a separate header */
-		memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
-		hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
-		memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
-
-		/* Insert the SNAP header */
-		if (skb_headroom(skb) < sizeof(hdr)) {
-			printk(KERN_ERR
-			       "%s: Not enough headroom for 802.2 headers %d\n",
-			       dev->name, skb_headroom(skb));
-			goto drop;
-		}
-		eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
-		memcpy(eh, &hdr, sizeof(hdr));
-	}
-
-	err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
-				txfid, HERMES_802_3_OFFSET);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
-		       dev->name, err);
-		goto busy;
-	}
-
-	/* Calculate Michael MIC */
-	if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
-		u8 mic_buf[MICHAEL_MIC_LEN + 1];
-		u8 *mic;
-		size_t offset;
-		size_t len;
-
-		if (skb->len % 2) {
-			/* MIC start is on an odd boundary */
-			mic_buf[0] = skb->data[skb->len - 1];
-			mic = &mic_buf[1];
-			offset = skb->len - 1;
-			len = MICHAEL_MIC_LEN + 1;
-		} else {
-			mic = &mic_buf[0];
-			offset = skb->len;
-			len = MICHAEL_MIC_LEN;
-		}
-
-		michael_mic(priv->tx_tfm_mic,
-			    priv->tkip_key[priv->tx_key].tx_mic,
-			    eh->h_dest, eh->h_source, 0 /* priority */,
-			    skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
-
-		/* Write the MIC */
-		err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
-					txfid, HERMES_802_3_OFFSET + offset);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
-			       dev->name, err);
-			goto busy;
-		}
-	}
-
-	/* Finally, we actually initiate the send */
-	netif_stop_queue(dev);
-
-	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
-				txfid, NULL);
-	if (err) {
-		netif_start_queue(dev);
-		if (net_ratelimit())
-			printk(KERN_ERR "%s: Error %d transmitting packet\n",
-				dev->name, err);
-		goto busy;
-	}
-
-	dev->trans_start = jiffies;
-	stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
-	goto ok;
-
- drop:
-	stats->tx_errors++;
-	stats->tx_dropped++;
-
- ok:
-	orinoco_unlock(priv, &flags);
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
-
- busy:
-	if (err == -EIO)
-		schedule_work(&priv->reset_work);
-	orinoco_unlock(priv, &flags);
-	return NETDEV_TX_BUSY;
-}
-
-static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	u16 fid = hermes_read_regn(hw, ALLOCFID);
-
-	if (fid != priv->txfid) {
-		if (fid != DUMMY_FID)
-			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
-			       dev->name, fid);
-		return;
-	}
-
-	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-
-	stats->tx_packets++;
-
-	netif_wake_queue(dev);
-
-	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
-	u16 status;
-	struct hermes_txexc_data hdr;
-	int err = 0;
-
-	if (fid == DUMMY_FID)
-		return; /* Nothing's really happened */
-
-	/* Read part of the frame header - we need status and addr1 */
-	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
-			       sizeof(struct hermes_txexc_data),
-			       fid, 0);
-
-	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-	stats->tx_errors++;
-
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
-		       "(FID=%04X error %d)\n",
-		       dev->name, fid, err);
-		return;
-	}
-	
-	DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
-	      err, fid);
-    
-	/* We produce a TXDROP event only for retry or lifetime
-	 * exceeded, because that's the only status that really mean
-	 * that this particular node went away.
-	 * Other errors means that *we* screwed up. - Jean II */
-	status = le16_to_cpu(hdr.desc.status);
-	if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
-		union iwreq_data	wrqu;
-
-		/* Copy 802.11 dest address.
-		 * We use the 802.11 header because the frame may
-		 * not be 802.3 or may be mangled...
-		 * In Ad-Hoc mode, it will be the node address.
-		 * In managed mode, it will be most likely the AP addr
-		 * User space will figure out how to convert it to
-		 * whatever it needs (IP address or else).
-		 * - Jean II */
-		memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
-		wrqu.addr.sa_family = ARPHRD_ETHER;
-
-		/* Send event to user space */
-		wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
-	}
-
-	netif_wake_queue(dev);
-}
-
-static void orinoco_tx_timeout(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	struct hermes *hw = &priv->hw;
-
-	printk(KERN_WARNING "%s: Tx timeout! "
-	       "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
-	       dev->name, hermes_read_regn(hw, ALLOCFID),
-	       hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
-
-	stats->tx_errors++;
-
-	schedule_work(&priv->reset_work);
-}
-
-/********************************************************************/
-/* Rx path (data frames)                                            */
-/********************************************************************/
-
-/* Does the frame have a SNAP header indicating it should be
- * de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(void *_hdr)
-{
-	u8 *hdr = _hdr;
-
-	/* We de-encapsulate all packets which, a) have SNAP headers
-	 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
-	 * and where b) the OUI of the SNAP header is 00:00:00 or
-	 * 00:00:f8 - we need both because different APs appear to use
-	 * different OUIs for some reason */
-	return (memcmp(hdr, &encaps_hdr, 5) == 0)
-		&& ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
-}
-
-static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
-				      int level, int noise)
-{
-	struct iw_quality wstats;
-	wstats.level = level - 0x95;
-	wstats.noise = noise - 0x95;
-	wstats.qual = (level > noise) ? (level - noise) : 0;
-	wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-	/* Update spy records */
-	wireless_spy_update(dev, mac, &wstats);
-}
-
-static void orinoco_stat_gather(struct net_device *dev,
-				struct sk_buff *skb,
-				struct hermes_rx_descriptor *desc)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	/* Using spy support with lots of Rx packets, like in an
-	 * infrastructure (AP), will really slow down everything, because
-	 * the MAC address must be compared to each entry of the spy list.
-	 * If the user really asks for it (set some address in the
-	 * spy list), we do it, but he will pay the price.
-	 * Note that to get here, you need both WIRELESS_SPY
-	 * compiled in AND some addresses in the list !!!
-	 */
-	/* Note : gcc will optimise the whole section away if
-	 * WIRELESS_SPY is not defined... - Jean II */
-	if (SPY_NUMBER(priv)) {
-		orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
-				   desc->signal, desc->silence);
-	}
-}
-
-/*
- * orinoco_rx_monitor - handle received monitor frames.
- *
- * Arguments:
- *	dev		network device
- *	rxfid		received FID
- *	desc		rx descriptor of the frame
- *
- * Call context: interrupt
- */
-static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
-			       struct hermes_rx_descriptor *desc)
-{
-	u32 hdrlen = 30;	/* return full header by default */
-	u32 datalen = 0;
-	u16 fc;
-	int err;
-	int len;
-	struct sk_buff *skb;
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	hermes_t *hw = &priv->hw;
-
-	len = le16_to_cpu(desc->data_len);
-
-	/* Determine the size of the header and the data */
-	fc = le16_to_cpu(desc->frame_ctl);
-	switch (fc & IEEE80211_FCTL_FTYPE) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_TODS)
-		    && (fc & IEEE80211_FCTL_FROMDS))
-			hdrlen = 30;
-		else
-			hdrlen = 24;
-		datalen = len;
-		break;
-	case IEEE80211_FTYPE_MGMT:
-		hdrlen = 24;
-		datalen = len;
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (fc & IEEE80211_FCTL_STYPE) {
-		case IEEE80211_STYPE_PSPOLL:
-		case IEEE80211_STYPE_RTS:
-		case IEEE80211_STYPE_CFEND:
-		case IEEE80211_STYPE_CFENDACK:
-			hdrlen = 16;
-			break;
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
-			break;
-		}
-		break;
-	default:
-		/* Unknown frame type */
-		break;
-	}
-
-	/* sanity check the length */
-	if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
-		printk(KERN_DEBUG "%s: oversized monitor frame, "
-		       "data length = %d\n", dev->name, datalen);
-		stats->rx_length_errors++;
-		goto update_stats;
-	}
-
-	skb = dev_alloc_skb(hdrlen + datalen);
-	if (!skb) {
-		printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
-		       dev->name);
-		goto update_stats;
-	}
-
-	/* Copy the 802.11 header to the skb */
-	memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
-	skb_reset_mac_header(skb);
-
-	/* If any, copy the data from the card to the skb */
-	if (datalen > 0) {
-		err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
-				       ALIGN(datalen, 2), rxfid,
-				       HERMES_802_2_OFFSET);
-		if (err) {
-			printk(KERN_ERR "%s: error %d reading monitor frame\n",
-			       dev->name, err);
-			goto drop;
-		}
-	}
-
-	skb->dev = dev;
-	skb->ip_summed = CHECKSUM_NONE;
-	skb->pkt_type = PACKET_OTHERHOST;
-	skb->protocol = __constant_htons(ETH_P_802_2);
-	
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	netif_rx(skb);
-	return;
-
- drop:
-	dev_kfree_skb_irq(skb);
- update_stats:
-	stats->rx_errors++;
-	stats->rx_dropped++;
-}
-
-/* Get tsc from the firmware */
-static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
-				  u8 *tsc)
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
-
-	if ((key < 0) || (key > 4))
-		return -EINVAL;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
-			      sizeof(tsc_arr), NULL, &tsc_arr);
-	if (!err)
-		memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
-
-	return err;
-}
-
-static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	struct iw_statistics *wstats = &priv->wstats;
-	struct sk_buff *skb = NULL;
-	u16 rxfid, status;
-	int length;
-	struct hermes_rx_descriptor *desc;
-	struct orinoco_rx_data *rx_data;
-	int err;
-
-	desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
-	if (!desc) {
-		printk(KERN_WARNING
-		       "%s: Can't allocate space for RX descriptor\n",
-		       dev->name);
-		goto update_stats;
-	}
-
-	rxfid = hermes_read_regn(hw, RXFID);
-
-	err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
-			       rxfid, 0);
-	if (err) {
-		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
-		       "Frame dropped.\n", dev->name, err);
-		goto update_stats;
-	}
-
-	status = le16_to_cpu(desc->status);
-
-	if (status & HERMES_RXSTAT_BADCRC) {
-		DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
-		      dev->name);
-		stats->rx_crc_errors++;
-		goto update_stats;
-	}
-
-	/* Handle frames in monitor mode */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		orinoco_rx_monitor(dev, rxfid, desc);
-		goto out;
-	}
-
-	if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
-		DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
-		      dev->name);
-		wstats->discard.code++;
-		goto update_stats;
-	}
-
-	length = le16_to_cpu(desc->data_len);
-
-	/* Sanity checks */
-	if (length < 3) { /* No for even an 802.2 LLC header */
-		/* At least on Symbol firmware with PCF we get quite a
-                   lot of these legitimately - Poll frames with no
-                   data. */
-		goto out;
-	}
-	if (length > IEEE80211_MAX_DATA_LEN) {
-		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
-		       dev->name, length);
-		stats->rx_length_errors++;
-		goto update_stats;
-	}
-
-	/* Payload size does not include Michael MIC. Increase payload
-	 * size to read it together with the data. */
-	if (status & HERMES_RXSTAT_MIC)
-		length += MICHAEL_MIC_LEN;
-
-	/* We need space for the packet data itself, plus an ethernet
-	   header, plus 2 bytes so we can align the IP header on a
-	   32bit boundary, plus 1 byte so we can read in odd length
-	   packets from the card, which has an IO granularity of 16
-	   bits */  
-	skb = dev_alloc_skb(length+ETH_HLEN+2+1);
-	if (!skb) {
-		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
-		       dev->name);
-		goto update_stats;
-	}
-
-	/* We'll prepend the header, so reserve space for it.  The worst
-	   case is no decapsulation, when 802.3 header is prepended and
-	   nothing is removed.  2 is for aligning the IP header.  */
-	skb_reserve(skb, ETH_HLEN + 2);
-
-	err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
-			       ALIGN(length, 2), rxfid,
-			       HERMES_802_2_OFFSET);
-	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame. "
-		       "Frame dropped.\n", dev->name, err);
-		goto drop;
-	}
-
-	/* Add desc and skb to rx queue */
-	rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
-	if (!rx_data) {
-		printk(KERN_WARNING "%s: Can't allocate RX packet\n",
-			dev->name);
-		goto drop;
-	}
-	rx_data->desc = desc;
-	rx_data->skb = skb;
-	list_add_tail(&rx_data->list, &priv->rx_list);
-	tasklet_schedule(&priv->rx_tasklet);
-
-	return;
-
-drop:
-	dev_kfree_skb_irq(skb);
-update_stats:
-	stats->rx_errors++;
-	stats->rx_dropped++;
-out:
-	kfree(desc);
-}
-
-static void orinoco_rx(struct net_device *dev,
-		       struct hermes_rx_descriptor *desc,
-		       struct sk_buff *skb)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &priv->stats;
-	u16 status, fc;
-	int length;
-	struct ethhdr *hdr;
-
-	status = le16_to_cpu(desc->status);
-	length = le16_to_cpu(desc->data_len);
-	fc = le16_to_cpu(desc->frame_ctl);
-
-	/* Calculate and check MIC */
-	if (status & HERMES_RXSTAT_MIC) {
-		int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
-			      HERMES_MIC_KEY_ID_SHIFT);
-		u8 mic[MICHAEL_MIC_LEN];
-		u8 *rxmic;
-		u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
-			desc->addr3 : desc->addr2;
-
-		/* Extract Michael MIC from payload */
-		rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
-
-		skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
-		length -= MICHAEL_MIC_LEN;
-
-		michael_mic(priv->rx_tfm_mic,
-			    priv->tkip_key[key_id].rx_mic,
-			    desc->addr1,
-			    src,
-			    0, /* priority or QoS? */
-			    skb->data,
-			    skb->len,
-			    &mic[0]);
-
-		if (memcmp(mic, rxmic,
-			   MICHAEL_MIC_LEN)) {
-			union iwreq_data wrqu;
-			struct iw_michaelmicfailure wxmic;
-
-			printk(KERN_WARNING "%s: "
-			       "Invalid Michael MIC in data frame from %pM, "
-			       "using key %i\n",
-			       dev->name, src, key_id);
-
-			/* TODO: update stats */
-
-			/* Notify userspace */
-			memset(&wxmic, 0, sizeof(wxmic));
-			wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
-			wxmic.flags |= (desc->addr1[0] & 1) ?
-				IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
-			wxmic.src_addr.sa_family = ARPHRD_ETHER;
-			memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
-
-			(void) orinoco_hw_get_tkip_iv(priv, key_id,
-						      &wxmic.tsc[0]);
-
-			memset(&wrqu, 0, sizeof(wrqu));
-			wrqu.data.length = sizeof(wxmic);
-			wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
-					    (char *) &wxmic);
-
-			goto drop;
-		}
-	}
-
-	/* Handle decapsulation
-	 * In most cases, the firmware tell us about SNAP frames.
-	 * For some reason, the SNAP frames sent by LinkSys APs
-	 * are not properly recognised by most firmwares.
-	 * So, check ourselves */
-	if (length >= ENCAPS_OVERHEAD &&
-	    (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
-	     ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-	     is_ethersnap(skb->data))) {
-		/* These indicate a SNAP within 802.2 LLC within
-		   802.11 frame which we'll need to de-encapsulate to
-		   the original EthernetII frame. */
-		hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
-	} else {
-		/* 802.3 frame - prepend 802.3 header as is */
-		hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
-		hdr->h_proto = htons(length);
-	}
-	memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
-	if (fc & IEEE80211_FCTL_FROMDS)
-		memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
-	else
-		memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
-
-	skb->protocol = eth_type_trans(skb, dev);
-	skb->ip_summed = CHECKSUM_NONE;
-	if (fc & IEEE80211_FCTL_TODS)
-		skb->pkt_type = PACKET_OTHERHOST;
-	
-	/* Process the wireless stats if needed */
-	orinoco_stat_gather(dev, skb, desc);
-
-	/* Pass the packet to the networking stack */
-	netif_rx(skb);
-	stats->rx_packets++;
-	stats->rx_bytes += length;
-
-	return;
-
- drop:
-	dev_kfree_skb(skb);
-	stats->rx_errors++;
-	stats->rx_dropped++;
-}
-
-static void orinoco_rx_isr_tasklet(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *) data;
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct orinoco_rx_data *rx_data, *temp;
-	struct hermes_rx_descriptor *desc;
-	struct sk_buff *skb;
-	unsigned long flags;
-
-	/* orinoco_rx requires the driver lock, and we also need to
-	 * protect priv->rx_list, so just hold the lock over the
-	 * lot.
-	 *
-	 * If orinoco_lock fails, we've unplugged the card. In this
-	 * case just abort. */
-	if (orinoco_lock(priv, &flags) != 0)
-		return;
-
-	/* extract desc and skb from queue */
-	list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
-		desc = rx_data->desc;
-		skb = rx_data->skb;
-		list_del(&rx_data->list);
-		kfree(rx_data);
-
-		orinoco_rx(dev, desc, skb);
-
-		kfree(desc);
-	}
-
-	orinoco_unlock(priv, &flags);
-}
-
-/********************************************************************/
-/* Rx path (info frames)                                            */
-/********************************************************************/
-
-static void print_linkstatus(struct net_device *dev, u16 status)
-{
-	char * s;
-
-	if (suppress_linkstatus)
-		return;
-
-	switch (status) {
-	case HERMES_LINKSTATUS_NOT_CONNECTED:
-		s = "Not Connected";
-		break;
-	case HERMES_LINKSTATUS_CONNECTED:
-		s = "Connected";
-		break;
-	case HERMES_LINKSTATUS_DISCONNECTED:
-		s = "Disconnected";
-		break;
-	case HERMES_LINKSTATUS_AP_CHANGE:
-		s = "AP Changed";
-		break;
-	case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
-		s = "AP Out of Range";
-		break;
-	case HERMES_LINKSTATUS_AP_IN_RANGE:
-		s = "AP In Range";
-		break;
-	case HERMES_LINKSTATUS_ASSOC_FAILED:
-		s = "Association Failed";
-		break;
-	default:
-		s = "UNKNOWN";
-	}
-	
-	printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
-	       dev->name, s, status);
-}
-
-/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct work_struct *work)
-{
-	struct orinoco_private *priv =
-		container_of(work, struct orinoco_private, join_work);
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	int err;
-	unsigned long flags;
-	struct join_req {
-		u8 bssid[ETH_ALEN];
-		__le16 channel;
-	} __attribute__ ((packed)) req;
-	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
-	struct prism2_scan_apinfo *atom = NULL;
-	int offset = 4;
-	int found = 0;
-	u8 *buf;
-	u16 len;
-
-	/* Allocate buffer for scan results */
-	buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
-	if (! buf)
-		return;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		goto fail_lock;
-
-	/* Sanity checks in case user changed something in the meantime */
-	if (! priv->bssid_fixed)
-		goto out;
-
-	if (strlen(priv->desired_essid) == 0)
-		goto out;
-
-	/* Read scan results from the firmware */
-	err = hermes_read_ltv(hw, USER_BAP,
-			      HERMES_RID_SCANRESULTSTABLE,
-			      MAX_SCAN_LEN, &len, buf);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read scan results\n",
-		       dev->name);
-		goto out;
-	}
-
-	len = HERMES_RECLEN_TO_BYTES(len);
-
-	/* Go through the scan results looking for the channel of the AP
-	 * we were requested to join */
-	for (; offset + atom_len <= len; offset += atom_len) {
-		atom = (struct prism2_scan_apinfo *) (buf + offset);
-		if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
-			found = 1;
-			break;
-		}
-	}
-
-	if (! found) {
-		DEBUG(1, "%s: Requested AP not found in scan results\n",
-		      dev->name);
-		goto out;
-	}
-
-	memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
-	req.channel = atom->channel;	/* both are little-endian */
-	err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
-				  &req);
-	if (err)
-		printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
-
- out:
-	orinoco_unlock(priv, &flags);
-
- fail_lock:
-	kfree(buf);
-}
-
-/* Send new BSSID to userspace */
-static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
-{
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
-	int err;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
-	if (err != 0)
-		return;
-
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
-	/* Send event to user space */
-	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
-{
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
-	int err;
-	u8 buf[88];
-	u8 *ie;
-
-	if (!priv->has_wpa)
-		return;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
-			      sizeof(buf), NULL, &buf);
-	if (err != 0)
-		return;
-
-	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-	if (ie) {
-		int rem = sizeof(buf) - (ie - &buf[0]);
-		wrqu.data.length = ie[1] + 2;
-		if (wrqu.data.length > rem)
-			wrqu.data.length = rem;
-
-		if (wrqu.data.length)
-			/* Send event to user space */
-			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
-	}
-}
-
-static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
-{
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
-	int err;
-	u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
-	u8 *ie;
-
-	if (!priv->has_wpa)
-		return;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
-			      sizeof(buf), NULL, &buf);
-	if (err != 0)
-		return;
-
-	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-	if (ie) {
-		int rem = sizeof(buf) - (ie - &buf[0]);
-		wrqu.data.length = ie[1] + 2;
-		if (wrqu.data.length > rem)
-			wrqu.data.length = rem;
-
-		if (wrqu.data.length)
-			/* Send event to user space */
-			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
-	}
-}
-
-static void orinoco_send_wevents(struct work_struct *work)
-{
-	struct orinoco_private *priv =
-		container_of(work, struct orinoco_private, wevent_work);
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return;
-
-	orinoco_send_assocreqie_wevent(priv);
-	orinoco_send_assocrespie_wevent(priv);
-	orinoco_send_bssid_wevent(priv);
-
-	orinoco_unlock(priv, &flags);
-}
-
-static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
-					      unsigned long scan_age)
-{
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-		struct xbss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
-		}
-	} else {
-		struct bss_element *bss;
-		struct bss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
-		}
-	}
-}
-
-static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-					struct agere_ext_scan_info *atom)
-{
-	struct xbss_element *bss = NULL;
-	int found = 0;
-
-	/* Try to update an existing bss first */
-	list_for_each_entry(bss, &priv->bss_list, list) {
-		if (compare_ether_addr(bss->bss.bssid, atom->bssid))
-			continue;
-		/* ESSID lengths */
-		if (bss->bss.data[1] != atom->data[1])
-			continue;
-		if (memcmp(&bss->bss.data[2], &atom->data[2],
-			   atom->data[1]))
-			continue;
-		found = 1;
-		break;
-	}
-
-	/* Grab a bss off the free list */
-	if (!found && !list_empty(&priv->bss_free_list)) {
-		bss = list_entry(priv->bss_free_list.next,
-				 struct xbss_element, list);
-		list_del(priv->bss_free_list.next);
-
-		list_add_tail(&bss->list, &priv->bss_list);
-	}
-
-	if (bss) {
-		/* Always update the BSS to get latest beacon info */
-		memcpy(&bss->bss, atom, sizeof(bss->bss));
-		bss->last_scanned = jiffies;
-	}
-}
-
-static int orinoco_process_scan_results(struct net_device *dev,
-					unsigned char *buf,
-					int len)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int			offset;		/* In the scan data */
-	union hermes_scan_info *atom;
-	int			atom_len;
-
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		atom_len = sizeof(struct agere_scan_apinfo);
-		offset = 0;
-		break;
-	case FIRMWARE_TYPE_SYMBOL:
-		/* Lack of documentation necessitates this hack.
-		 * Different firmwares have 68 or 76 byte long atoms.
-		 * We try modulo first.  If the length divides by both,
-		 * we check what would be the channel in the second
-		 * frame for a 68-byte atom.  76-byte atoms have 0 there.
-		 * Valid channel cannot be 0.  */
-		if (len % 76)
-			atom_len = 68;
-		else if (len % 68)
-			atom_len = 76;
-		else if (len >= 1292 && buf[68] == 0)
-			atom_len = 76;
-		else
-			atom_len = 68;
-		offset = 0;
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		offset = 4;
-		if (priv->has_hostscan) {
-			atom_len = le16_to_cpup((__le16 *)buf);
-			/* Sanity check for atom_len */
-			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
-				printk(KERN_ERR "%s: Invalid atom_len in scan "
-				       "data: %d\n", dev->name, atom_len);
-				return -EIO;
-			}
-		} else
-			atom_len = offsetof(struct prism2_scan_apinfo, atim);
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	/* Check that we got an whole number of atoms */
-	if ((len - offset) % atom_len) {
-		printk(KERN_ERR "%s: Unexpected scan data length %d, "
-		       "atom_len %d, offset %d\n", dev->name, len,
-		       atom_len, offset);
-		return -EIO;
-	}
-
-	orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
-	/* Read the entries one by one */
-	for (; offset + atom_len <= len; offset += atom_len) {
-		int found = 0;
-		struct bss_element *bss = NULL;
-
-		/* Get next atom */
-		atom = (union hermes_scan_info *) (buf + offset);
-
-		/* Try to update an existing bss first */
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
-				continue;
-			if (le16_to_cpu(bss->bss.a.essid_len) !=
-			      le16_to_cpu(atom->a.essid_len))
-				continue;
-			if (memcmp(bss->bss.a.essid, atom->a.essid,
-			      le16_to_cpu(atom->a.essid_len)))
-				continue;
-			found = 1;
-			break;
-		}
-
-		/* Grab a bss off the free list */
-		if (!found && !list_empty(&priv->bss_free_list)) {
-			bss = list_entry(priv->bss_free_list.next,
-					 struct bss_element, list);
-			list_del(priv->bss_free_list.next);
-
-			list_add_tail(&bss->list, &priv->bss_list);
-		}
-
-		if (bss) {
-			/* Always update the BSS to get latest beacon info */
-			memcpy(&bss->bss, atom, sizeof(bss->bss));
-			bss->last_scanned = jiffies;
-		}
-	}
-
-	return 0;
-}
-
-static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	u16 infofid;
-	struct {
-		__le16 len;
-		__le16 type;
-	} __attribute__ ((packed)) info;
-	int len, type;
-	int err;
-
-	/* This is an answer to an INQUIRE command that we did earlier,
-	 * or an information "event" generated by the card
-	 * The controller return to us a pseudo frame containing
-	 * the information in question - Jean II */
-	infofid = hermes_read_regn(hw, INFOFID);
-
-	/* Read the info frame header - don't try too hard */
-	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
-			       infofid, 0);
-	if (err) {
-		printk(KERN_ERR "%s: error %d reading info frame. "
-		       "Frame dropped.\n", dev->name, err);
-		return;
-	}
-	
-	len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
-	type = le16_to_cpu(info.type);
-
-	switch (type) {
-	case HERMES_INQ_TALLIES: {
-		struct hermes_tallies_frame tallies;
-		struct iw_statistics *wstats = &priv->wstats;
-		
-		if (len > sizeof(tallies)) {
-			printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
-			       dev->name, len);
-			len = sizeof(tallies);
-		}
-		
-		err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
-				       infofid, sizeof(info));
-		if (err)
-			break;
-		
-		/* Increment our various counters */
-		/* wstats->discard.nwid - no wrong BSSID stuff */
-		wstats->discard.code +=
-			le16_to_cpu(tallies.RxWEPUndecryptable);
-		if (len == sizeof(tallies))  
-			wstats->discard.code +=
-				le16_to_cpu(tallies.RxDiscards_WEPICVError) +
-				le16_to_cpu(tallies.RxDiscards_WEPExcluded);
-		wstats->discard.misc +=
-			le16_to_cpu(tallies.TxDiscardsWrongSA);
-		wstats->discard.fragment +=
-			le16_to_cpu(tallies.RxMsgInBadMsgFragments);
-		wstats->discard.retries +=
-			le16_to_cpu(tallies.TxRetryLimitExceeded);
-		/* wstats->miss.beacon - no match */
-	}
-	break;
-	case HERMES_INQ_LINKSTATUS: {
-		struct hermes_linkstatus linkstatus;
-		u16 newstatus;
-		int connected;
-
-		if (priv->iw_mode == IW_MODE_MONITOR)
-			break;
-
-		if (len != sizeof(linkstatus)) {
-			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
-			       dev->name, len);
-			break;
-		}
-
-		err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
-				       infofid, sizeof(info));
-		if (err)
-			break;
-		newstatus = le16_to_cpu(linkstatus.linkstatus);
-
-		/* Symbol firmware uses "out of range" to signal that
-		 * the hostscan frame can be requested.  */
-		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
-		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
-		    priv->has_hostscan && priv->scan_inprogress) {
-			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
-			break;
-		}
-
-		connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
-			|| (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
-			|| (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
-
-		if (connected)
-			netif_carrier_on(dev);
-		else if (!ignore_disconnect)
-			netif_carrier_off(dev);
-
-		if (newstatus != priv->last_linkstatus) {
-			priv->last_linkstatus = newstatus;
-			print_linkstatus(dev, newstatus);
-			/* The info frame contains only one word which is the
-			 * status (see hermes.h). The status is pretty boring
-			 * in itself, that's why we export the new BSSID...
-			 * Jean II */
-			schedule_work(&priv->wevent_work);
-		}
-	}
-	break;
-	case HERMES_INQ_SCAN:
-		if (!priv->scan_inprogress && priv->bssid_fixed &&
-		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
-			schedule_work(&priv->join_work);
-			break;
-		}
-		/* fall through */
-	case HERMES_INQ_HOSTSCAN:
-	case HERMES_INQ_HOSTSCAN_SYMBOL: {
-		/* Result of a scanning. Contains information about
-		 * cells in the vicinity - Jean II */
-		union iwreq_data	wrqu;
-		unsigned char *buf;
-
-		/* Scan is no longer in progress */
-		priv->scan_inprogress = 0;
-
-		/* Sanity check */
-		if (len > 4096) {
-			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
-			       dev->name, len);
-			break;
-		}
-
-		/* Allocate buffer for results */
-		buf = kmalloc(len, GFP_ATOMIC);
-		if (buf == NULL)
-			/* No memory, so can't printk()... */
-			break;
-
-		/* Read scan data */
-		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
-				       infofid, sizeof(info));
-		if (err) {
-			kfree(buf);
-			break;
-		}
-
-#ifdef ORINOCO_DEBUG
-		{
-			int	i;
-			printk(KERN_DEBUG "Scan result [%02X", buf[0]);
-			for(i = 1; i < (len * 2); i++)
-				printk(":%02X", buf[i]);
-			printk("]\n");
-		}
-#endif	/* ORINOCO_DEBUG */
-
-		if (orinoco_process_scan_results(dev, buf, len) == 0) {
-			/* Send an empty event to user space.
-			 * We don't send the received data on the event because
-			 * it would require us to do complex transcoding, and
-			 * we want to minimise the work done in the irq handler
-			 * Use a request to extract the data - Jean II */
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-		}
-		kfree(buf);
-	}
-	break;
-	case HERMES_INQ_CHANNELINFO:
-	{
-		struct agere_ext_scan_info *bss;
-
-		if (!priv->scan_inprogress) {
-			printk(KERN_DEBUG "%s: Got chaninfo without scan, "
-			       "len=%d\n", dev->name, len);
-			break;
-		}
-
-		/* An empty result indicates that the scan is complete */
-		if (len == 0) {
-			union iwreq_data	wrqu;
-
-			/* Scan is no longer in progress */
-			priv->scan_inprogress = 0;
-
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-			break;
-		}
-
-		/* Sanity check */
-		else if (len > sizeof(*bss)) {
-			printk(KERN_WARNING
-			       "%s: Ext scan results too large (%d bytes). "
-			       "Truncating results to %zd bytes.\n",
-			       dev->name, len, sizeof(*bss));
-			len = sizeof(*bss);
-		} else if (len < (offsetof(struct agere_ext_scan_info,
-					   data) + 2)) {
-			/* Drop this result now so we don't have to
-			 * keep checking later */
-			printk(KERN_WARNING
-			       "%s: Ext scan results too short (%d bytes)\n",
-			       dev->name, len);
-			break;
-		}
-
-		bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
-		if (bss == NULL)
-			break;
-
-		/* Read scan data */
-		err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
-				       infofid, sizeof(info));
-		if (err) {
-			kfree(bss);
-			break;
-		}
-
-		orinoco_add_ext_scan_result(priv, bss);
-
-		kfree(bss);
-		break;
-	}
-	case HERMES_INQ_SEC_STAT_AGERE:
-		/* Security status (Agere specific) */
-		/* Ignore this frame for now */
-		if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-			break;
-		/* fall through */
-	default:
-		printk(KERN_DEBUG "%s: Unknown information frame received: "
-		       "type 0x%04x, length %d\n", dev->name, type, len);
-		/* We don't actually do anything about it */
-		break;
-	}
-}
-
-static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
-{
-	if (net_ratelimit())
-		printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
-}
-
-/********************************************************************/
-/* Internal hardware control routines                               */
-/********************************************************************/
-
-int __orinoco_up(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	netif_carrier_off(dev); /* just to make sure */
-
-	err = __orinoco_program_rids(dev);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d configuring card\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Fire things up again */
-	hermes_set_irqmask(hw, ORINOCO_INTEN);
-	err = hermes_enable_port(hw, 0);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d enabling MAC port\n",
-		       dev->name, err);
-		return err;
-	}
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-int __orinoco_down(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	netif_stop_queue(dev);
-
-	if (! priv->hw_unavailable) {
-		if (! priv->broken_disableport) {
-			err = hermes_disable_port(hw, 0);
-			if (err) {
-				/* Some firmwares (e.g. Intersil 1.3.x) seem
-				 * to have problems disabling the port, oh
-				 * well, too bad. */
-				printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
-				       dev->name, err);
-				priv->broken_disableport = 1;
-			}
-		}
-		hermes_set_irqmask(hw, 0);
-		hermes_write_regn(hw, EVACK, 0xffff);
-	}
-	
-	/* firmware will have to reassociate */
-	netif_carrier_off(dev);
-	priv->last_linkstatus = 0xffff;
-
-	return 0;
-}
-
-static int orinoco_allocate_fid(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
-		/* Try workaround for old Symbol firmware bug */
-		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-		       "(old Symbol firmware?). Trying to work around... ",
-		       dev->name);
-		
-		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-		if (err)
-			printk("failed!\n");
-		else
-			printk("ok.\n");
-	}
-
-	return err;
-}
-
-int orinoco_reinit_firmware(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	err = hermes_init(hw);
-	if (priv->do_fw_download && !err) {
-		err = orinoco_download(priv);
-		if (err)
-			priv->do_fw_download = 0;
-	}
-	if (!err)
-		err = orinoco_allocate_fid(dev);
-
-	return err;
-}
-
-static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-
-	if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
-		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
-		       priv->ndev->name, priv->bitratemode);
-		return -EINVAL;
-	}
-
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFTXRATECONTROL,
-					   bitrate_table[priv->bitratemode].agere_txratectrl);
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-	case FIRMWARE_TYPE_SYMBOL:
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFTXRATECONTROL,
-					   bitrate_table[priv->bitratemode].intersil_txratectrl);
-		break;
-	default:
-		BUG();
-	}
-
-	return err;
-}
-
-/* Set fixed AP address */
-static int __orinoco_hw_set_wap(struct orinoco_private *priv)
-{
-	int roaming_flag;
-	int err = 0;
-	hermes_t *hw = &priv->hw;
-
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		/* not supported */
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		if (priv->bssid_fixed)
-			roaming_flag = 2;
-		else
-			roaming_flag = 1;
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFROAMINGMODE,
-					   roaming_flag);
-		break;
-	case FIRMWARE_TYPE_SYMBOL:
-		err = HERMES_WRITE_RECORD(hw, USER_BAP,
-					  HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
-					  &priv->desired_bssid);
-		break;
-	}
-	return err;
-}
-
-/* Change the WEP keys and/or the current keys.  Can be called
- * either from __orinoco_hw_setup_enc() or directly from
- * orinoco_ioctl_setiwencode().  In the later case the association
- * with the AP is not broken (if the firmware can handle it),
- * which is needed for 802.1x implementations. */
-static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		err = HERMES_WRITE_RECORD(hw, USER_BAP,
-					  HERMES_RID_CNFWEPKEYS_AGERE,
-					  &priv->keys);
-		if (err)
-			return err;
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFTXKEY_AGERE,
-					   priv->tx_key);
-		if (err)
-			return err;
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-	case FIRMWARE_TYPE_SYMBOL:
-		{
-			int keylen;
-			int i;
-
-			/* Force uniform key length to work around firmware bugs */
-			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-			
-			if (keylen > LARGE_KEY_SIZE) {
-				printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
-				       priv->ndev->name, priv->tx_key, keylen);
-				return -E2BIG;
-			}
-
-			/* Write all 4 keys */
-			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
-				err = hermes_write_ltv(hw, USER_BAP,
-						       HERMES_RID_CNFDEFAULTKEY0 + i,
-						       HERMES_BYTES_TO_RECLEN(keylen),
-						       priv->keys[i].data);
-				if (err)
-					return err;
-			}
-
-			/* Write the index of the key used in transmission */
-			err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFWEPDEFAULTKEYID,
-						   priv->tx_key);
-			if (err)
-				return err;
-		}
-		break;
-	}
-
-	return 0;
-}
-
-static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	int master_wep_flag;
-	int auth_flag;
-	int enc_flag;
-
-	/* Setup WEP keys for WEP and WPA */
-	if (priv->encode_alg)
-		__orinoco_hw_setup_wepkeys(priv);
-
-	if (priv->wep_restrict)
-		auth_flag = HERMES_AUTH_SHARED_KEY;
-	else
-		auth_flag = HERMES_AUTH_OPEN;
-
-	if (priv->wpa_enabled)
-		enc_flag = 2;
-	else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
-		enc_flag = 1;
-	else
-		enc_flag = 0;
-
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
-		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
-			/* Enable the shared-key authentication. */
-			err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFAUTHENTICATION_AGERE,
-						   auth_flag);
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFWEPENABLED_AGERE,
-					   enc_flag);
-		if (err)
-			return err;
-
-		if (priv->has_wpa) {
-			/* Set WPA key management */
-			err = hermes_write_wordrec(hw, USER_BAP,
-				  HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
-				  priv->key_mgmt);
-			if (err)
-				return err;
-		}
-
-		break;
-
-	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
-	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
-		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
-			if (priv->wep_restrict ||
-			    (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
-				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
-						  HERMES_WEP_EXCL_UNENCRYPTED;
-			else
-				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
-
-			err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFAUTHENTICATION,
-						   auth_flag);
-			if (err)
-				return err;
-		} else
-			master_wep_flag = 0;
-
-		if (priv->iw_mode == IW_MODE_MONITOR)
-			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
-
-		/* Master WEP setting : on/off */
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFWEPFLAGS_INTERSIL,
-					   master_wep_flag);
-		if (err)
-			return err;	
-
-		break;
-	}
-
-	return 0;
-}
-
-/* key must be 32 bytes, including the tx and rx MIC keys.
- * rsc must be 8 bytes
- * tsc must be 8 bytes or NULL
- */
-static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-				     u8 *key, u8 *rsc, u8 *tsc)
-{
-	struct {
-		__le16 idx;
-		u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
-		u8 key[TKIP_KEYLEN];
-		u8 tx_mic[MIC_KEYLEN];
-		u8 rx_mic[MIC_KEYLEN];
-		u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
-	} __attribute__ ((packed)) buf;
-	int ret;
-	int err;
-	int k;
-	u16 xmitting;
-
-	key_idx &= 0x3;
-
-	if (set_tx)
-		key_idx |= 0x8000;
-
-	buf.idx = cpu_to_le16(key_idx);
-	memcpy(buf.key, key,
-	       sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
-
-	if (rsc == NULL)
-		memset(buf.rsc, 0, sizeof(buf.rsc));
-	else
-		memcpy(buf.rsc, rsc, sizeof(buf.rsc));
-
-	if (tsc == NULL) {
-		memset(buf.tsc, 0, sizeof(buf.tsc));
-		buf.tsc[4] = 0x10;
-	} else {
-		memcpy(buf.tsc, tsc, sizeof(buf.tsc));
-	}
-
-	/* Wait upto 100ms for tx queue to empty */
-	k = 100;
-	do {
-		k--;
-		udelay(1000);
-		ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
-					  &xmitting);
-		if (ret)
-			break;
-	} while ((k > 0) && xmitting);
-
-	if (k == 0)
-		ret = -ETIMEDOUT;
-
-	err = HERMES_WRITE_RECORD(hw, USER_BAP,
-				  HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
-				  &buf);
-
-	return ret ? ret : err;
-}
-
-static int orinoco_clear_tkip_key(struct orinoco_private *priv,
-				  int key_idx)
-{
-	hermes_t *hw = &priv->hw;
-	int err;
-
-	memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
-	err = hermes_write_wordrec(hw, USER_BAP,
-				   HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
-				   key_idx);
-	if (err)
-		printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
-		       priv->ndev->name, err, key_idx);
-	return err;
-}
-
-static int __orinoco_program_rids(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct hermes_idstring idbuf;
-
-	/* Set the MAC address */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting MAC address\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set up the link mode */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
-				   priv->port_type);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting port type\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the channel/frequency */
-	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFOWNCHANNEL,
-					   priv->channel);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting channel %d\n",
-			       dev->name, err, priv->channel);
-			return err;
-		}
-	}
-
-	if (priv->has_ibss) {
-		u16 createibss;
-
-		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
-			printk(KERN_WARNING "%s: This firmware requires an "
-			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
-			/* With wvlan_cs, in this case, we would crash.
-			 * hopefully, this driver will behave better...
-			 * Jean II */
-			createibss = 0;
-		} else {
-			createibss = priv->createibss;
-		}
-		
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFCREATEIBSS,
-					   createibss);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set the desired BSSID */
-	err = __orinoco_hw_set_wap(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting AP address\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the desired ESSID */
-	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
-	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
-			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			       &idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
-		       dev->name, err);
-		return err;
-	}
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
-			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			       &idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set the station name */
-	idbuf.len = cpu_to_le16(strlen(priv->nick));
-	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
-			       &idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting nickname\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set AP density */
-	if (priv->has_sensitivity) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFSYSTEMSCALE,
-					   priv->ap_density);
-		if (err) {
-			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
-			       "Disabling sensitivity control\n",
-			       dev->name, err);
-
-			priv->has_sensitivity = 0;
-		}
-	}
-
-	/* Set RTS threshold */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				   priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set fragmentation threshold or MWO robustness */
-	if (priv->has_mwo)
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMWOROBUST_AGERE,
-					   priv->mwo_robust);
-	else
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					   priv->frag_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set bitrate */
-	err = __orinoco_hw_set_bitrate(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting bitrate\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set power management */
-	if (priv->has_pm) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMENABLED,
-					   priv->pm_on);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMULTICASTRECEIVE,
-					   priv->pm_mcast);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMAXSLEEPDURATION,
-					   priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMHOLDOVERDURATION,
-					   priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set preamble - only for Symbol so far... */
-	if (priv->has_preamble) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPREAMBLE_SYMBOL,
-					   priv->preamble);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting preamble\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set up encryption */
-	if (priv->has_wep || priv->has_wpa) {
-		err = __orinoco_hw_setup_enc(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d activating encryption\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		/* Enable monitor mode */
-		dev->type = ARPHRD_IEEE80211;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
-					    HERMES_TEST_MONITOR, 0, NULL);
-	} else {
-		/* Disable monitor mode */
-		dev->type = ARPHRD_ETHER;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_STOP, 0, NULL);
-	}
-	if (err)
-		return err;
-
-	/* Set promiscuity / multicast*/
-	priv->promiscuous = 0;
-	priv->mc_count = 0;
-
-	/* FIXME: what about netif_tx_lock */
-	__orinoco_set_multicast_list(dev);
-
-	return 0;
-}
-
-/* FIXME: return int? */
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	int promisc, mc_count;
-
-	/* The Hermes doesn't seem to have an allmulti mode, so we go
-	 * into promiscuous mode and let the upper levels deal. */
-	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
-	     (dev->mc_count > MAX_MULTICAST(priv)) ) {
-		promisc = 1;
-		mc_count = 0;
-	} else {
-		promisc = 0;
-		mc_count = dev->mc_count;
-	}
-
-	if (promisc != priv->promiscuous) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPROMISCUOUSMODE,
-					   promisc);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
-			       dev->name, err);
-		} else 
-			priv->promiscuous = promisc;
-	}
-
-	/* If we're not in promiscuous mode, then we need to set the
-	 * group address if either we want to multicast, or if we were
-	 * multicasting and want to stop */
-	if (! promisc && (mc_count || priv->mc_count) ) {
-		struct dev_mc_list *p = dev->mc_list;
-		struct hermes_multicast mclist;
-		int i;
-
-		for (i = 0; i < mc_count; i++) {
-			/* paranoia: is list shorter than mc_count? */
-			BUG_ON(! p);
-			/* paranoia: bad address size in list? */
-			BUG_ON(p->dmi_addrlen != ETH_ALEN);
-			
-			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
-			p = p->next;
-		}
-		
-		if (p)
-			printk(KERN_WARNING "%s: Multicast list is "
-			       "longer than mc_count\n", dev->name);
-
-		err = hermes_write_ltv(hw, USER_BAP,
-				   HERMES_RID_CNFGROUPADDRESSES,
-				   HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
-				   &mclist);
-		if (err)
-			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
-			       dev->name, err);
-		else
-			priv->mc_count = mc_count;
-	}
-}
-
-/* This must be called from user context, without locks held - use
- * schedule_work() */
-static void orinoco_reset(struct work_struct *work)
-{
-	struct orinoco_private *priv =
-		container_of(work, struct orinoco_private, reset_work);
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	int err;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		/* When the hardware becomes available again, whatever
-		 * detects that is responsible for re-initializing
-		 * it. So no need for anything further */
-		return;
-
-	netif_stop_queue(dev);
-
-	/* Shut off interrupts.  Depending on what state the hardware
-	 * is in, this might not work, but we'll try anyway */
-	hermes_set_irqmask(hw, 0);
-	hermes_write_regn(hw, EVACK, 0xffff);
-
-	priv->hw_unavailable++;
-	priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
-	netif_carrier_off(dev);
-
-	orinoco_unlock(priv, &flags);
-
- 	/* Scanning support: Cleanup of driver struct */
-	orinoco_clear_scan_results(priv, 0);
-	priv->scan_inprogress = 0;
-
-	if (priv->hard_reset) {
-		err = (*priv->hard_reset)(priv);
-		if (err) {
-			printk(KERN_ERR "%s: orinoco_reset: Error %d "
-			       "performing hard reset\n", dev->name, err);
-			goto disable;
-		}
-	}
-
-	err = orinoco_reinit_firmware(dev);
-	if (err) {
-		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
-		       dev->name, err);
-		goto disable;
-	}
-
-	spin_lock_irq(&priv->lock); /* This has to be called from user context */
-
-	priv->hw_unavailable--;
-
-	/* priv->open or priv->hw_unavailable might have changed while
-	 * we dropped the lock */
-	if (priv->open && (! priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
-		if (err) {
-			printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
-			       dev->name, err);
-		} else
-			dev->trans_start = jiffies;
-	}
-
-	spin_unlock_irq(&priv->lock);
-
-	return;
- disable:
-	hermes_set_irqmask(hw, 0);
-	netif_device_detach(dev);
-	printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
-}
-
-/********************************************************************/
-/* Interrupt handler                                                */
-/********************************************************************/
-
-static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
-{
-	printk(KERN_DEBUG "%s: TICK\n", dev->name);
-}
-
-static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
-{
-	/* This seems to happen a fair bit under load, but ignoring it
-	   seems to work fine...*/
-	printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
-	       dev->name);
-}
-
-irqreturn_t orinoco_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int count = MAX_IRQLOOPS_PER_IRQ;
-	u16 evstat, events;
-	/* These are used to detect a runaway interrupt situation */
-	/* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
-	 * we panic and shut down the hardware */
-	static int last_irq_jiffy = 0; /* jiffies value the last time
-					* we were called */
-	static int loops_this_jiffy = 0;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0) {
-		/* If hw is unavailable - we don't know if the irq was
-		 * for us or not */
-		return IRQ_HANDLED;
-	}
-
-	evstat = hermes_read_regn(hw, EVSTAT);
-	events = evstat & hw->inten;
-	if (! events) {
-		orinoco_unlock(priv, &flags);
-		return IRQ_NONE;
-	}
-	
-	if (jiffies != last_irq_jiffy)
-		loops_this_jiffy = 0;
-	last_irq_jiffy = jiffies;
-
-	while (events && count--) {
-		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
-			printk(KERN_WARNING "%s: IRQ handler is looping too "
-			       "much! Resetting.\n", dev->name);
-			/* Disable interrupts for now */
-			hermes_set_irqmask(hw, 0);
-			schedule_work(&priv->reset_work);
-			break;
-		}
-
-		/* Check the card hasn't been removed */
-		if (! hermes_present(hw)) {
-			DEBUG(0, "orinoco_interrupt(): card removed\n");
-			break;
-		}
-
-		if (events & HERMES_EV_TICK)
-			__orinoco_ev_tick(dev, hw);
-		if (events & HERMES_EV_WTERR)
-			__orinoco_ev_wterr(dev, hw);
-		if (events & HERMES_EV_INFDROP)
-			__orinoco_ev_infdrop(dev, hw);
-		if (events & HERMES_EV_INFO)
-			__orinoco_ev_info(dev, hw);
-		if (events & HERMES_EV_RX)
-			__orinoco_ev_rx(dev, hw);
-		if (events & HERMES_EV_TXEXC)
-			__orinoco_ev_txexc(dev, hw);
-		if (events & HERMES_EV_TX)
-			__orinoco_ev_tx(dev, hw);
-		if (events & HERMES_EV_ALLOC)
-			__orinoco_ev_alloc(dev, hw);
-		
-		hermes_write_regn(hw, EVACK, evstat);
-
-		evstat = hermes_read_regn(hw, EVSTAT);
-		events = evstat & hw->inten;
-	};
-
-	orinoco_unlock(priv, &flags);
-	return IRQ_HANDLED;
-}
-
-/********************************************************************/
-/* Power management                                                 */
-/********************************************************************/
-#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
-static int orinoco_pm_notifier(struct notifier_block *notifier,
-			       unsigned long pm_event,
-			       void *unused)
-{
-	struct orinoco_private *priv = container_of(notifier,
-						    struct orinoco_private,
-						    pm_notifier);
-
-	/* All we need to do is cache the firmware before suspend, and
-	 * release it when we come out.
-	 *
-	 * Only need to do this if we're downloading firmware. */
-	if (!priv->do_fw_download)
-		return NOTIFY_DONE;
-
-	switch (pm_event) {
-	case PM_HIBERNATION_PREPARE:
-	case PM_SUSPEND_PREPARE:
-		orinoco_cache_fw(priv, 0);
-		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:
-		orinoco_uncache_fw(priv);
-		break;
-
-	case PM_RESTORE_PREPARE:
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static void orinoco_register_pm_notifier(struct orinoco_private *priv)
-{
-	priv->pm_notifier.notifier_call = orinoco_pm_notifier;
-	register_pm_notifier(&priv->pm_notifier);
-}
-
-static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
-{
-	unregister_pm_notifier(&priv->pm_notifier);
-}
-#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_register_pm_notifier(priv) do { } while(0)
-#define orinoco_unregister_pm_notifier(priv) do { } while(0)
-#endif
-
-/********************************************************************/
-/* Initialization                                                   */
-/********************************************************************/
-
-struct comp_id {
-	u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
-	if (nic_id->id < 0x8000)
-		return FIRMWARE_TYPE_AGERE;
-	else if (nic_id->id == 0x8000 && nic_id->major == 0)
-		return FIRMWARE_TYPE_SYMBOL;
-	else
-		return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct comp_id nic_id, sta_id;
-	unsigned int firmver;
-	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
-	/* Get the hardware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&nic_id.id);
-	le16_to_cpus(&nic_id.variant);
-	le16_to_cpus(&nic_id.major);
-	le16_to_cpus(&nic_id.minor);
-	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
-	       dev->name, nic_id.id, nic_id.variant,
-	       nic_id.major, nic_id.minor);
-
-	priv->firmware_type = determine_firmware_type(&nic_id);
-
-	/* Get the firmware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&sta_id.id);
-	le16_to_cpus(&sta_id.variant);
-	le16_to_cpus(&sta_id.major);
-	le16_to_cpus(&sta_id.minor);
-	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
-	       dev->name, sta_id.id, sta_id.variant,
-	       sta_id.major, sta_id.minor);
-
-	switch (sta_id.id) {
-	case 0x15:
-		printk(KERN_ERR "%s: Primary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x14b:
-		printk(KERN_ERR "%s: Tertiary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
-	case 0x21:	/* Symbol Spectrum24 Trilogy */
-		break;
-	default:
-		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
-		       dev->name);
-		break;
-	}
-
-	/* Default capabilities */
-	priv->has_sensitivity = 1;
-	priv->has_mwo = 0;
-	priv->has_preamble = 0;
-	priv->has_port3 = 1;
-	priv->has_ibss = 1;
-	priv->has_wep = 0;
-	priv->has_big_wep = 0;
-	priv->has_alt_txcntl = 0;
-	priv->has_ext_scan = 0;
-	priv->has_wpa = 0;
-	priv->do_fw_download = 0;
-
-	/* Determine capabilities from the firmware version */
-	switch (priv->firmware_type) {
-	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);
-
-		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
-		priv->has_ibss = (firmver >= 0x60006);
-		priv->has_wep = (firmver >= 0x40020);
-		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
-					  Gold cards from the others? */
-		priv->has_mwo = (firmver >= 0x60000);
-		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-		priv->ibss_port = 1;
-		priv->has_hostscan = (firmver >= 0x8000a);
-		priv->do_fw_download = 1;
-		priv->broken_monitor = (firmver >= 0x80000);
-		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_wpa = (firmver >= 0x9002a);
-		/* Tested with Agere firmware :
-		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
-		 * Tested CableTron firmware : 4.32 => Anton */
-		break;
-	case FIRMWARE_TYPE_SYMBOL:
-		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
-		/* Intel MAC : 00:02:B3:* */
-		/* 3Com MAC : 00:50:DA:* */
-		memset(tmp, 0, sizeof(tmp));
-		/* Get the Symbol firmware version */
-		err = hermes_read_ltv(hw, USER_BAP,
-				      HERMES_RID_SECONDARYVERSION_SYMBOL,
-				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
-		if (err) {
-			printk(KERN_WARNING
-			       "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
-			       dev->name, err);
-			firmver = 0;
-			tmp[0] = '\0';
-		} else {
-			/* The firmware revision is a string, the format is
-			 * something like : "V2.20-01".
-			 * Quick and dirty parsing... - Jean II
-			 */
-			firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
-				| ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
-				| (tmp[7] - '0');
-
-			tmp[SYMBOL_MAX_VER_LEN] = '\0';
-		}
-
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Symbol %s", tmp);
-
-		priv->has_ibss = (firmver >= 0x20000);
-		priv->has_wep = (firmver >= 0x15012);
-		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
-			       (firmver >= 0x29000 && firmver < 0x30000) ||
-			       firmver >= 0x31000;
-		priv->has_preamble = (firmver >= 0x20000);
-		priv->ibss_port = 4;
-
-		/* Symbol firmware is found on various cards, but
-		 * there has been no attempt to check firmware
-		 * download on non-spectrum_cs based cards.
-		 *
-		 * Given that the Agere firmware download works
-		 * differently, we should avoid doing a firmware
-		 * download with the Symbol algorithm on non-spectrum
-		 * cards.
-		 *
-		 * For now we can identify a spectrum_cs based card
-		 * because it has a firmware reset function.
-		 */
-		priv->do_fw_download = (priv->stop_fw != NULL);
-
- 		priv->broken_disableport = (firmver == 0x25013) ||
- 					   (firmver >= 0x30000 && firmver <= 0x31000);
-		priv->has_hostscan = (firmver >= 0x31001) ||
-				     (firmver >= 0x29057 && firmver < 0x30000);
-		/* Tested with Intel firmware : 0x20015 => Jean II */
-		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
-		 * Samsung, Compaq 100/200 and Proxim are slightly
-		 * 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);
-
-		firmver = ((unsigned long)sta_id.major << 16) |
-			((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
-		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
-		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
-		priv->has_pm = (firmver >= 0x000700);
-		priv->has_hostscan = (firmver >= 0x010301);
-
-		if (firmver >= 0x000800)
-			priv->ibss_port = 0;
-		else {
-			printk(KERN_NOTICE "%s: Intersil firmware earlier "
-			       "than v0.8.x - several features not supported\n",
-			       dev->name);
-			priv->ibss_port = 1;
-		}
-		break;
-	}
-	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
-	       priv->fw_name);
-
-	return 0;
-}
-
-static int orinoco_init(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	struct hermes_idstring nickbuf;
-	u16 reclen;
-	int len;
-
-	/* No need to lock, the hw_unavailable flag is already set in
-	 * alloc_orinocodev() */
-	priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
-
-	/* Initialize the firmware */
-	err = hermes_init(hw);
-	if (err != 0) {
-		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
-		       dev->name, err);
-		goto out;
-	}
-
-	err = determine_firmware(dev);
-	if (err != 0) {
-		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-		       dev->name);
-		goto out;
-	}
-
-	if (priv->do_fw_download) {
-#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
-		orinoco_cache_fw(priv, 0);
-#endif
-
-		err = orinoco_download(priv);
-		if (err)
-			priv->do_fw_download = 0;
-
-		/* Check firmware version again */
-		err = determine_firmware(dev);
-		if (err != 0) {
-			printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-			       dev->name);
-			goto out;
-		}
-	}
-
-	if (priv->has_port3)
-		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
-	if (priv->has_ibss)
-		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
-		       dev->name);
-	if (priv->has_wep) {
-		printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
-		if (priv->has_big_wep)
-			printk("104-bit key\n");
-		else
-			printk("40-bit key\n");
-	}
-	if (priv->has_wpa) {
-		printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
-		if (orinoco_mic_init(priv)) {
-			printk(KERN_ERR "%s: Failed to setup MIC crypto "
-			       "algorithm. Disabling WPA support\n", dev->name);
-			priv->has_wpa = 0;
-		}
-	}
-
-	/* Now we have the firmware capabilities, allocate appropiate
-	 * sized scan buffers */
-	if (orinoco_bss_data_allocate(priv))
-		goto out;
-	orinoco_bss_data_init(priv);
-
-	/* Get the MAC address */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			      ETH_ALEN, NULL, dev->dev_addr);
-	if (err) {
-		printk(KERN_WARNING "%s: failed to read MAC address!\n",
-		       dev->name);
-		goto out;
-	}
-
-	printk(KERN_DEBUG "%s: MAC address %pM\n",
-	       dev->name, dev->dev_addr);
-
-	/* Get the station name */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			      sizeof(nickbuf), &reclen, &nickbuf);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read station name\n",
-		       dev->name);
-		goto out;
-	}
-	if (nickbuf.len)
-		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
-	else
-		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
-	memcpy(priv->nick, &nickbuf.val, len);
-	priv->nick[len] = '\0';
-
-	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
-
-	err = orinoco_allocate_fid(dev);
-	if (err) {
-		printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get allowed channels */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
-				  &priv->channel_mask);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read channel list!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get initial AP density */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
-				  &priv->ap_density);
-	if (err || priv->ap_density < 1 || priv->ap_density > 3) {
-		priv->has_sensitivity = 0;
-	}
-
-	/* Get initial RTS threshold */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				  &priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get initial fragmentation settings */
-	if (priv->has_mwo)
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMWOROBUST_AGERE,
-					  &priv->mwo_robust);
-	else
-		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					  &priv->frag_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Power management setup */
-	if (priv->has_pm) {
-		priv->pm_on = 0;
-		priv->pm_mcast = 1;
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMAXSLEEPDURATION,
-					  &priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management period!\n",
-			       dev->name);
-			goto out;
-		}
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPMHOLDOVERDURATION,
-					  &priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management timeout!\n",
-			       dev->name);
-			goto out;
-		}
-	}
-
-	/* Preamble setup */
-	if (priv->has_preamble) {
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPREAMBLE_SYMBOL,
-					  &priv->preamble);
-		if (err)
-			goto out;
-	}
-		
-	/* Set up the default configuration */
-	priv->iw_mode = IW_MODE_INFRA;
-	/* By default use IEEE/IBSS ad-hoc mode if we have it */
-	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
-	set_port_type(priv);
-	priv->channel = 0; /* use firmware default */
-
-	priv->promiscuous = 0;
-	priv->encode_alg = IW_ENCODE_ALG_NONE;
-	priv->tx_key = 0;
-	priv->wpa_enabled = 0;
-	priv->tkip_cm_active = 0;
-	priv->key_mgmt = 0;
-	priv->wpa_ie_len = 0;
-	priv->wpa_ie = NULL;
-
-	/* Make the hardware available, as long as it hasn't been
-	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
-	spin_lock_irq(&priv->lock);
-	priv->hw_unavailable--;
-	spin_unlock_irq(&priv->lock);
-
-	printk(KERN_DEBUG "%s: ready\n", dev->name);
-
- out:
-	return err;
-}
-
-struct net_device
-*alloc_orinocodev(int sizeof_card,
-		  struct device *device,
-		  int (*hard_reset)(struct orinoco_private *),
-		  int (*stop_fw)(struct orinoco_private *, int))
-{
-	struct net_device *dev;
-	struct orinoco_private *priv;
-
-	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
-	if (! dev)
-		return NULL;
-	priv = netdev_priv(dev);
-	priv->ndev = dev;
-	if (sizeof_card)
-		priv->card = (void *)((unsigned long)priv
-				      + sizeof(struct orinoco_private));
-	else
-		priv->card = NULL;
-	priv->dev = device;
-
-	/* Setup / override net_device fields */
-	dev->init = orinoco_init;
-	dev->hard_start_xmit = orinoco_xmit;
-	dev->tx_timeout = orinoco_tx_timeout;
-	dev->watchdog_timeo = HZ; /* 1 second timeout */
-	dev->get_stats = orinoco_get_stats;
-	dev->ethtool_ops = &orinoco_ethtool_ops;
-	dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
-#ifdef WIRELESS_SPY
-	priv->wireless_data.spy_data = &priv->spy_data;
-	dev->wireless_data = &priv->wireless_data;
-#endif
-	dev->change_mtu = orinoco_change_mtu;
-	dev->set_multicast_list = orinoco_set_multicast_list;
-	/* we use the default eth_mac_addr for setting the MAC addr */
-
-	/* Reserve space in skb for the SNAP header */
-	dev->hard_header_len += ENCAPS_OVERHEAD;
-
-	/* Set up default callbacks */
-	dev->open = orinoco_open;
-	dev->stop = orinoco_stop;
-	priv->hard_reset = hard_reset;
-	priv->stop_fw = stop_fw;
-
-	spin_lock_init(&priv->lock);
-	priv->open = 0;
-	priv->hw_unavailable = 1; /* orinoco_init() must clear this
-				   * before anything else touches the
-				   * hardware */
-	INIT_WORK(&priv->reset_work, orinoco_reset);
-	INIT_WORK(&priv->join_work, orinoco_join_ap);
-	INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
-
-	INIT_LIST_HEAD(&priv->rx_list);
-	tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
-		     (unsigned long) dev);
-
-	netif_carrier_off(dev);
-	priv->last_linkstatus = 0xffff;
-
-	priv->cached_pri_fw = NULL;
-	priv->cached_fw = NULL;
-
-	/* Register PM notifiers */
-	orinoco_register_pm_notifier(priv);
-
-	return dev;
-}
-
-void free_orinocodev(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct orinoco_rx_data *rx_data, *temp;
-
-	/* If the tasklet is scheduled when we call tasklet_kill it
-	 * will run one final time. However the tasklet will only
-	 * drain priv->rx_list if the hw is still available. */
-	tasklet_kill(&priv->rx_tasklet);
-
-	/* Explicitly drain priv->rx_list */
-	list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
-		list_del(&rx_data->list);
-
-		dev_kfree_skb(rx_data->skb);
-		kfree(rx_data->desc);
-		kfree(rx_data);
-	}
-
-	orinoco_unregister_pm_notifier(priv);
-	orinoco_uncache_fw(priv);
-
-	priv->wpa_ie_len = 0;
-	kfree(priv->wpa_ie);
-	orinoco_mic_free(priv);
-	orinoco_bss_data_free(priv);
-	free_netdev(dev);
-}
-
-/********************************************************************/
-/* Wireless extensions                                              */
-/********************************************************************/
-
-/* Return : < 0 -> error code ; >= 0 -> length */
-static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-				char buf[IW_ESSID_MAX_SIZE+1])
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	struct hermes_idstring essidbuf;
-	char *p = (char *)(&essidbuf.val);
-	int len;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (strlen(priv->desired_essid) > 0) {
-		/* We read the desired SSID from the hardware rather
-		   than from priv->desired_essid, just in case the
-		   firmware is allowed to change it on us. I'm not
-		   sure about this */
-		/* My guess is that the OWNSSID should always be whatever
-		 * we set to the card, whereas CURRENT_SSID is the one that
-		 * may change... - Jean II */
-		u16 rid;
-
-		*active = 1;
-
-		rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
-			HERMES_RID_CNFDESIREDSSID;
-		
-		err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
-				      NULL, &essidbuf);
-		if (err)
-			goto fail_unlock;
-	} else {
-		*active = 0;
-
-		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
-				      sizeof(essidbuf), NULL, &essidbuf);
-		if (err)
-			goto fail_unlock;
-	}
-
-	len = le16_to_cpu(essidbuf.len);
-	BUG_ON(len > IW_ESSID_MAX_SIZE);
-
-	memset(buf, 0, IW_ESSID_MAX_SIZE);
-	memcpy(buf, p, len);
-	err = len;
-
- fail_unlock:
-	orinoco_unlock(priv, &flags);
-
-	return err;       
-}
-
-static long orinoco_hw_get_freq(struct orinoco_private *priv)
-{
-	
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	u16 channel;
-	long freq = 0;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
-	if (err)
-		goto out;
-
-	/* Intersil firmware 1.3.5 returns 0 when the interface is down */
-	if (channel == 0) {
-		err = -EBUSY;
-		goto out;
-	}
-
-	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-		printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
-		       priv->ndev->name, channel);
-		err = -EBUSY;
-		goto out;
-
-	}
-	freq = channel_frequency[channel-1] * 100000;
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	if (err > 0)
-		err = -EBUSY;
-	return err ? err : freq;
-}
-
-static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
-				      int *numrates, s32 *rates, int max)
-{
-	hermes_t *hw = &priv->hw;
-	struct hermes_idstring list;
-	unsigned char *p = (unsigned char *)&list.val;
-	int err = 0;
-	int num;
-	int i;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
-			      sizeof(list), NULL, &list);
-	orinoco_unlock(priv, &flags);
-
-	if (err)
-		return err;
-	
-	num = le16_to_cpu(list.len);
-	*numrates = num;
-	num = min(num, max);
-
-	for (i = 0; i < num; i++) {
-		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
-	}
-
-	return 0;
-}
-
-static int orinoco_ioctl_getname(struct net_device *dev,
-				 struct iw_request_info *info,
-				 char *name,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int numrates;
-	int err;
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
-	if (!err && (numrates > 2))
-		strcpy(name, "IEEE 802.11b");
-	else
-		strcpy(name, "IEEE 802.11-DS");
-
-	return 0;
-}
-
-static int orinoco_ioctl_setwap(struct net_device *dev,
-				struct iw_request_info *info,
-				struct sockaddr *ap_addr,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-	static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-	static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Enable automatic roaming - no sanity checks are needed */
-	if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
-	    memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
-		priv->bssid_fixed = 0;
-		memset(priv->desired_bssid, 0, ETH_ALEN);
-
-		/* "off" means keep existing connection */
-		if (ap_addr->sa_data[0] == 0) {
-			__orinoco_hw_set_wap(priv);
-			err = 0;
-		}
-		goto out;
-	}
-
-	if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
-		printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
-		       "support manual roaming\n",
-		       dev->name);
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	if (priv->iw_mode != IW_MODE_INFRA) {
-		printk(KERN_WARNING "%s: Manual roaming supported only in "
-		       "managed mode\n", dev->name);
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* Intersil firmware hangs without Desired ESSID */
-	if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
-	    strlen(priv->desired_essid) == 0) {
-		printk(KERN_WARNING "%s: Desired ESSID must be set for "
-		       "manual roaming\n", dev->name);
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* Finally, enable manual roaming */
-	priv->bssid_fixed = 1;
-	memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
-
- out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-static int orinoco_ioctl_getwap(struct net_device *dev,
-				struct iw_request_info *info,
-				struct sockaddr *ap_addr,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	ap_addr->sa_family = ARPHRD_ETHER;
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-			      ETH_ALEN, NULL, ap_addr->sa_data);
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_setmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (priv->iw_mode == *mode)
-		return 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (*mode) {
-	case IW_MODE_ADHOC:
-		if (!priv->has_ibss && !priv->has_port3)
-			err = -EOPNOTSUPP;
-		break;
-
-	case IW_MODE_INFRA:
-		break;
-
-	case IW_MODE_MONITOR:
-		if (priv->broken_monitor && !force_monitor) {
-			printk(KERN_WARNING "%s: Monitor mode support is "
-			       "buggy in this firmware, not enabling\n",
-			       dev->name);
-			err = -EOPNOTSUPP;
-		}
-		break;
-
-	default:
-		err = -EOPNOTSUPP;
-		break;
-	}
-
-	if (err == -EINPROGRESS) {
-		priv->iw_mode = *mode;
-		set_port_type(priv);
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	*mode = priv->iw_mode;
-	return 0;
-}
-
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *rrq,
-				    char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-	struct iw_range *range = (struct iw_range *) extra;
-	int numrates;
-	int i, k;
-
-	rrq->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 22;
-
-	/* Set available channels/frequencies */
-	range->num_channels = NUM_CHANNELS;
-	k = 0;
-	for (i = 0; i < NUM_CHANNELS; i++) {
-		if (priv->channel_mask & (1 << i)) {
-			range->freq[k].i = i + 1;
-			range->freq[k].m = channel_frequency[i] * 100000;
-			range->freq[k].e = 1;
-			k++;
-		}
-		
-		if (k >= IW_MAX_FREQUENCIES)
-			break;
-	}
-	range->num_frequency = k;
-	range->sensitivity = 3;
-
-	if (priv->has_wep) {
-		range->max_encoding_tokens = ORINOCO_MAX_KEYS;
-		range->encoding_size[0] = SMALL_KEY_SIZE;
-		range->num_encoding_sizes = 1;
-
-		if (priv->has_big_wep) {
-			range->encoding_size[1] = LARGE_KEY_SIZE;
-			range->num_encoding_sizes = 2;
-		}
-	}
-
-	if (priv->has_wpa)
-		range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
-	if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
-		/* Quality stats meaningless in ad-hoc mode */
-	} else {
-		range->max_qual.qual = 0x8b - 0x2f;
-		range->max_qual.level = 0x2f - 0x95 - 1;
-		range->max_qual.noise = 0x2f - 0x95 - 1;
-		/* Need to get better values */
-		range->avg_qual.qual = 0x24;
-		range->avg_qual.level = 0xC2;
-		range->avg_qual.noise = 0x9E;
-	}
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates,
-					 range->bitrate, IW_MAX_BITRATES);
-	if (err)
-		return err;
-	range->num_bitrates = numrates;
-
-	/* Set an indication of the max TCP throughput in bit/s that we can
-	 * expect using this interface. May be use for QoS stuff...
-	 * Jean II */
-	if (numrates > 2)
-		range->throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
-	else
-		range->throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
-
-	range->min_rts = 0;
-	range->max_rts = 2347;
-	range->min_frag = 256;
-	range->max_frag = 2346;
-
-	range->min_pmp = 0;
-	range->max_pmp = 65535000;
-	range->min_pmt = 0;
-	range->max_pmt = 65535 * 1000;	/* ??? */
-	range->pmp_flags = IW_POWER_PERIOD;
-	range->pmt_flags = IW_POWER_TIMEOUT;
-	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
-
-	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->r_time_flags = IW_RETRY_LIFETIME;
-	range->min_retry = 0;
-	range->max_retry = 65535;	/* ??? */
-	range->min_r_time = 0;
-	range->max_r_time = 65535 * 1000;	/* ??? */
-
-	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-		range->scan_capa = IW_SCAN_CAPA_ESSID;
-	else
-		range->scan_capa = IW_SCAN_CAPA_NONE;
-
-	/* Event capability (kernel) */
-	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
-	/* Event capability (driver) */
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
-	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
-	return 0;
-}
-
-static int orinoco_ioctl_setiwencode(struct net_device *dev,
-				     struct iw_request_info *info,
-				     struct iw_point *erq,
-				     char *keybuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-	int setindex = priv->tx_key;
-	int encode_alg = priv->encode_alg;
-	int restricted = priv->wep_restrict;
-	u16 xlen = 0;
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (! priv->has_wep)
-		return -EOPNOTSUPP;
-
-	if (erq->pointer) {
-		/* We actually have a key to set - check its length */
-		if (erq->length > LARGE_KEY_SIZE)
-			return -E2BIG;
-
-		if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
-			return -E2BIG;
-	}
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Clear any TKIP key we have */
-	if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
-		(void) orinoco_clear_tkip_key(priv, setindex);
-
-	if (erq->length > 0) {
-		if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
-			index = priv->tx_key;
-
-		/* Adjust key length to a supported value */
-		if (erq->length > SMALL_KEY_SIZE) {
-			xlen = LARGE_KEY_SIZE;
-		} else if (erq->length > 0) {
-			xlen = SMALL_KEY_SIZE;
-		} else
-			xlen = 0;
-
-		/* Switch on WEP if off */
-		if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
-			setindex = index;
-			encode_alg = IW_ENCODE_ALG_WEP;
-		}
-	} else {
-		/* Important note : if the user do "iwconfig eth0 enc off",
-		 * we will arrive there with an index of -1. This is valid
-		 * but need to be taken care off... Jean II */
-		if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
-			if((index != -1) || (erq->flags == 0)) {
-				err = -EINVAL;
-				goto out;
-			}
-		} else {
-			/* Set the index : Check that the key is valid */
-			if(priv->keys[index].len == 0) {
-				err = -EINVAL;
-				goto out;
-			}
-			setindex = index;
-		}
-	}
-
-	if (erq->flags & IW_ENCODE_DISABLED)
-		encode_alg = IW_ENCODE_ALG_NONE;
-	if (erq->flags & IW_ENCODE_OPEN)
-		restricted = 0;
-	if (erq->flags & IW_ENCODE_RESTRICTED)
-		restricted = 1;
-
-	if (erq->pointer && erq->length > 0) {
-		priv->keys[index].len = cpu_to_le16(xlen);
-		memset(priv->keys[index].data, 0,
-		       sizeof(priv->keys[index].data));
-		memcpy(priv->keys[index].data, keybuf, erq->length);
-	}
-	priv->tx_key = setindex;
-
-	/* Try fast key change if connected and only keys are changed */
-	if ((priv->encode_alg == encode_alg) &&
-	    (priv->wep_restrict == restricted) &&
-	    netif_carrier_ok(dev)) {
-		err = __orinoco_hw_setup_wepkeys(priv);
-		/* No need to commit if successful */
-		goto out;
-	}
-
-	priv->encode_alg = encode_alg;
-	priv->wep_restrict = restricted;
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getiwencode(struct net_device *dev,
-				     struct iw_request_info *info,
-				     struct iw_point *erq,
-				     char *keybuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-	u16 xlen = 0;
-	unsigned long flags;
-
-	if (! priv->has_wep)
-		return -EOPNOTSUPP;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
-		index = priv->tx_key;
-
-	erq->flags = 0;
-	if (!priv->encode_alg)
-		erq->flags |= IW_ENCODE_DISABLED;
-	erq->flags |= index + 1;
-
-	if (priv->wep_restrict)
-		erq->flags |= IW_ENCODE_RESTRICTED;
-	else
-		erq->flags |= IW_ENCODE_OPEN;
-
-	xlen = le16_to_cpu(priv->keys[index].len);
-
-	erq->length = xlen;
-
-	memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
-
-	orinoco_unlock(priv, &flags);
-	return 0;
-}
-
-static int orinoco_ioctl_setessid(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_point *erq,
-				  char *essidbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
-	 * anyway... - Jean II */
-
-	/* Hum... Should not use Wireless Extension constant (may change),
-	 * should use our own... - Jean II */
-	if (erq->length > IW_ESSID_MAX_SIZE)
-		return -E2BIG;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
-	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
-
-	/* If not ANY, get the new ESSID */
-	if (erq->flags) {
-		memcpy(priv->desired_essid, essidbuf, erq->length);
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getessid(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_point *erq,
-				  char *essidbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int active;
-	int err = 0;
-	unsigned long flags;
-
-	if (netif_running(dev)) {
-		err = orinoco_hw_get_essid(priv, &active, essidbuf);
-		if (err < 0)
-			return err;
-		erq->length = err;
-	} else {
-		if (orinoco_lock(priv, &flags) != 0)
-			return -EBUSY;
-		memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
-		erq->length = strlen(priv->desired_essid);
-		orinoco_unlock(priv, &flags);
-	}
-
-	erq->flags = 1;
-
-	return 0;
-}
-
-static int orinoco_ioctl_setnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	if (nrq->length > IW_ESSID_MAX_SIZE)
-		return -E2BIG;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memset(priv->nick, 0, sizeof(priv->nick));
-	memcpy(priv->nick, nickbuf, nrq->length);
-
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
-	orinoco_unlock(priv, &flags);
-
-	nrq->length = strlen(priv->nick);
-
-	return 0;
-}
-
-static int orinoco_ioctl_setfreq(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_freq *frq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int chan = -1;
-	unsigned long flags;
-	int err = -EINPROGRESS;		/* Call commit handler */
-
-	/* In infrastructure mode the AP sets the channel */
-	if (priv->iw_mode == IW_MODE_INFRA)
-		return -EBUSY;
-
-	if ( (frq->e == 0) && (frq->m <= 1000) ) {
-		/* Setting by channel number */
-		chan = frq->m;
-	} else {
-		/* Setting by frequency - search the table */
-		int mult = 1;
-		int i;
-
-		for (i = 0; i < (6 - frq->e); i++)
-			mult *= 10;
-
-		for (i = 0; i < NUM_CHANNELS; i++)
-			if (frq->m == (channel_frequency[i] * mult))
-				chan = i+1;
-	}
-
-	if ( (chan < 1) || (chan > NUM_CHANNELS) ||
-	     ! (priv->channel_mask & (1 << (chan-1)) ) )
-		return -EINVAL;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	priv->channel = chan;
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		/* Fast channel change - no commit if successful */
-		hermes_t *hw = &priv->hw;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_SET_CHANNEL,
-					chan, NULL);
-	}
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getfreq(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_freq *frq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int tmp;
-
-	/* Locking done in there */
-	tmp = orinoco_hw_get_freq(priv);
-	if (tmp < 0) {
-		return tmp;
-	}
-
-	frq->m = tmp;
-	frq->e = 1;
-
-	return 0;
-}
-
-static int orinoco_ioctl_getsens(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	u16 val;
-	int err;
-	unsigned long flags;
-
-	if (!priv->has_sensitivity)
-		return -EOPNOTSUPP;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	err = hermes_read_wordrec(hw, USER_BAP,
-				  HERMES_RID_CNFSYSTEMSCALE, &val);
-	orinoco_unlock(priv, &flags);
-
-	if (err)
-		return err;
-
-	srq->value = val;
-	srq->fixed = 0; /* auto */
-
-	return 0;
-}
-
-static int orinoco_ioctl_setsens(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int val = srq->value;
-	unsigned long flags;
-
-	if (!priv->has_sensitivity)
-		return -EOPNOTSUPP;
-
-	if ((val < 1) || (val > 3))
-		return -EINVAL;
-	
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	priv->ap_density = val;
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_setrts(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_param *rrq,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int val = rrq->value;
-	unsigned long flags;
-
-	if (rrq->disabled)
-		val = 2347;
-
-	if ( (val < 0) || (val > 2347) )
-		return -EINVAL;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	priv->rts_thresh = val;
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getrts(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_param *rrq,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	rrq->value = priv->rts_thresh;
-	rrq->disabled = (rrq->value == 2347);
-	rrq->fixed = 1;
-
-	return 0;
-}
-
-static int orinoco_ioctl_setfrag(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *frq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (priv->has_mwo) {
-		if (frq->disabled)
-			priv->mwo_robust = 0;
-		else {
-			if (frq->fixed)
-				printk(KERN_WARNING "%s: Fixed fragmentation is "
-				       "not supported on this firmware. "
-				       "Using MWO robust instead.\n", dev->name);
-			priv->mwo_robust = 1;
-		}
-	} else {
-		if (frq->disabled)
-			priv->frag_thresh = 2346;
-		else {
-			if ( (frq->value < 256) || (frq->value > 2346) )
-				err = -EINVAL;
-			else
-				priv->frag_thresh = frq->value & ~0x1; /* must be even */
-		}
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getfrag(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *frq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	u16 val;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	
-	if (priv->has_mwo) {
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMWOROBUST_AGERE,
-					  &val);
-		if (err)
-			val = 0;
-
-		frq->value = val ? 2347 : 0;
-		frq->disabled = ! val;
-		frq->fixed = 0;
-	} else {
-		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					  &val);
-		if (err)
-			val = 0;
-
-		frq->value = val;
-		frq->disabled = (val >= 2346);
-		frq->fixed = 1;
-	}
-
-	orinoco_unlock(priv, &flags);
-	
-	return err;
-}
-
-static int orinoco_ioctl_setrate(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *rrq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int ratemode = -1;
-	int bitrate; /* 100s of kilobits */
-	int i;
-	unsigned long flags;
-	
-	/* As the user space doesn't know our highest rate, it uses -1
-	 * to ask us to set the highest rate.  Test it using "iwconfig
-	 * ethX rate auto" - Jean II */
-	if (rrq->value == -1)
-		bitrate = 110;
-	else {
-		if (rrq->value % 100000)
-			return -EINVAL;
-		bitrate = rrq->value / 100000;
-	}
-
-	if ( (bitrate != 10) && (bitrate != 20) &&
-	     (bitrate != 55) && (bitrate != 110) )
-		return -EINVAL;
-
-	for (i = 0; i < BITRATE_TABLE_SIZE; i++)
-		if ( (bitrate_table[i].bitrate == bitrate) &&
-		     (bitrate_table[i].automatic == ! rrq->fixed) ) {
-			ratemode = i;
-			break;
-		}
-	
-	if (ratemode == -1)
-		return -EINVAL;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	priv->bitratemode = ratemode;
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;
-}
-
-static int orinoco_ioctl_getrate(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_param *rrq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	int ratemode;
-	int i;
-	u16 val;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	ratemode = priv->bitratemode;
-
-	BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
-
-	rrq->value = bitrate_table[ratemode].bitrate * 100000;
-	rrq->fixed = ! bitrate_table[ratemode].automatic;
-	rrq->disabled = 0;
-
-	/* If the interface is running we try to find more about the
-	   current mode */
-	if (netif_running(dev)) {
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CURRENTTXRATE, &val);
-		if (err)
-			goto out;
-		
-		switch (priv->firmware_type) {
-		case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
-			/* Note : in Lucent firmware, the return value of
-			 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
-			 * and therefore is totally different from the
-			 * encoding of HERMES_RID_CNFTXRATECONTROL.
-			 * Don't forget that 6Mb/s is really 5.5Mb/s */
-			if (val == 6)
-				rrq->value = 5500000;
-			else
-				rrq->value = val * 1000000;
-			break;
-		case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
-		case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
-			for (i = 0; i < BITRATE_TABLE_SIZE; i++)
-				if (bitrate_table[i].intersil_txratectrl == val) {
-					ratemode = i;
-					break;
-				}
-			if (i >= BITRATE_TABLE_SIZE)
-				printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
-				       dev->name, val);
-
-			rrq->value = bitrate_table[ratemode].bitrate * 100000;
-			break;
-		default:
-			BUG();
-		}
-	}
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_setpower(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *prq,
-				  char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (prq->disabled) {
-		priv->pm_on = 0;
-	} else {
-		switch (prq->flags & IW_POWER_MODE) {
-		case IW_POWER_UNICAST_R:
-			priv->pm_mcast = 0;
-			priv->pm_on = 1;
-			break;
-		case IW_POWER_ALL_R:
-			priv->pm_mcast = 1;
-			priv->pm_on = 1;
-			break;
-		case IW_POWER_ON:
-			/* No flags : but we may have a value - Jean II */
-			break;
-		default:
-			err = -EINVAL;
-			goto out;
-		}
-		
-		if (prq->flags & IW_POWER_TIMEOUT) {
-			priv->pm_on = 1;
-			priv->pm_timeout = prq->value / 1000;
-		}
-		if (prq->flags & IW_POWER_PERIOD) {
-			priv->pm_on = 1;
-			priv->pm_period = prq->value / 1000;
-		}
-		/* It's valid to not have a value if we are just toggling
-		 * the flags... Jean II */
-		if(!priv->pm_on) {
-			err = -EINVAL;
-			goto out;
-		}			
-	}
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getpower(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *prq,
-				  char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	u16 enable, period, timeout, mcast;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
-	if (err)
-		goto out;
-
-	err = hermes_read_wordrec(hw, USER_BAP,
-				  HERMES_RID_CNFMAXSLEEPDURATION, &period);
-	if (err)
-		goto out;
-
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
-	if (err)
-		goto out;
-
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
-	if (err)
-		goto out;
-
-	prq->disabled = !enable;
-	/* Note : by default, display the period */
-	if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-		prq->flags = IW_POWER_TIMEOUT;
-		prq->value = timeout * 1000;
-	} else {
-		prq->flags = IW_POWER_PERIOD;
-		prq->value = period * 1000;
-	}
-	if (mcast)
-		prq->flags |= IW_POWER_ALL_R;
-	else
-		prq->flags |= IW_POWER_UNICAST_R;
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_set_encodeext(struct net_device *dev,
-				       struct iw_request_info *info,
-				       union iwreq_data *wrqu,
-				       char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int idx, alg = ext->alg, set_key = 1;
-	unsigned long flags;
-	int err = -EINVAL;
-	u16 key_len;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Determine and validate the key index */
-	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx) {
-		if ((idx < 1) || (idx > 4))
-			goto out;
-		idx--;
-	} else
-		idx = priv->tx_key;
-
-	if (encoding->flags & IW_ENCODE_DISABLED)
-	    alg = IW_ENCODE_ALG_NONE;
-
-	if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
-		/* Clear any TKIP TX key we had */
-		(void) orinoco_clear_tkip_key(priv, priv->tx_key);
-	}
-
-	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-		priv->tx_key = idx;
-		set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
-			   (ext->key_len > 0)) ? 1 : 0;
-	}
-
-	if (set_key) {
-		/* Set the requested key first */
-		switch (alg) {
-		case IW_ENCODE_ALG_NONE:
-			priv->encode_alg = alg;
-			priv->keys[idx].len = 0;
-			break;
-
-		case IW_ENCODE_ALG_WEP:
-			if (ext->key_len > SMALL_KEY_SIZE)
-				key_len = LARGE_KEY_SIZE;
-			else if (ext->key_len > 0)
-				key_len = SMALL_KEY_SIZE;
-			else
-				goto out;
-
-			priv->encode_alg = alg;
-			priv->keys[idx].len = cpu_to_le16(key_len);
-
-			key_len = min(ext->key_len, key_len);
-
-			memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
-			memcpy(priv->keys[idx].data, ext->key, key_len);
-			break;
-
-		case IW_ENCODE_ALG_TKIP:
-		{
-			hermes_t *hw = &priv->hw;
-			u8 *tkip_iv = NULL;
-
-			if (!priv->has_wpa ||
-			    (ext->key_len > sizeof(priv->tkip_key[0])))
-				goto out;
-
-			priv->encode_alg = alg;
-			memset(&priv->tkip_key[idx], 0,
-			       sizeof(priv->tkip_key[idx]));
-			memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
-
-			if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-				tkip_iv = &ext->rx_seq[0];
-
-			err = __orinoco_hw_set_tkip_key(hw, idx,
-				 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
-				 (u8 *) &priv->tkip_key[idx],
-				 tkip_iv, NULL);
-			if (err)
-				printk(KERN_ERR "%s: Error %d setting TKIP key"
-				       "\n", dev->name, err);
-
-			goto out;
-		}
-		default:
-			goto out;
-		}
-	}
-	err = -EINPROGRESS;
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_get_encodeext(struct net_device *dev,
-				       struct iw_request_info *info,
-				       union iwreq_data *wrqu,
-				       char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int idx, max_key_len;
-	unsigned long flags;
-	int err;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	err = -EINVAL;
-	max_key_len = encoding->length - sizeof(*ext);
-	if (max_key_len < 0)
-		goto out;
-
-	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx) {
-		if ((idx < 1) || (idx > 4))
-			goto out;
-		idx--;
-	} else
-		idx = priv->tx_key;
-
-	encoding->flags = idx + 1;
-	memset(ext, 0, sizeof(*ext));
-
-	ext->alg = priv->encode_alg;
-	switch (priv->encode_alg) {
-	case IW_ENCODE_ALG_NONE:
-		ext->key_len = 0;
-		encoding->flags |= IW_ENCODE_DISABLED;
-		break;
-	case IW_ENCODE_ALG_WEP:
-		ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
-				     max_key_len);
-		memcpy(ext->key, priv->keys[idx].data, ext->key_len);
-		encoding->flags |= IW_ENCODE_ENABLED;
-		break;
-	case IW_ENCODE_ALG_TKIP:
-		ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
-				     max_key_len);
-		memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
-		encoding->flags |= IW_ENCODE_ENABLED;
-		break;
-	}
-
-	err = 0;
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_set_auth(struct net_device *dev,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_param *param = &wrqu->param;
-	unsigned long flags;
-	int ret = -EINPROGRESS;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-	case IW_AUTH_CIPHER_PAIRWISE:
-	case IW_AUTH_CIPHER_GROUP:
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-	case IW_AUTH_PRIVACY_INVOKED:
-	case IW_AUTH_DROP_UNENCRYPTED:
-		/*
-		 * orinoco does not use these parameters
-		 */
-		break;
-
-	case IW_AUTH_KEY_MGMT:
-		/* wl_lkm implies value 2 == PSK for Hermes I
-		 * which ties in with WEXT
-		 * no other hints tho :(
-		 */
-		priv->key_mgmt = param->value;
-		break;
-
-	case IW_AUTH_TKIP_COUNTERMEASURES:
-		/* When countermeasures are enabled, shut down the
-		 * card; when disabled, re-enable the card. This must
-		 * take effect immediately.
-		 *
-		 * TODO: Make sure that the EAPOL message is getting
-		 *       out before card disabled
-		 */
-		if (param->value) {
-			priv->tkip_cm_active = 1;
-			ret = hermes_enable_port(hw, 0);
-		} else {
-			priv->tkip_cm_active = 0;
-			ret = hermes_disable_port(hw, 0);
-		}
-		break;
-
-	case IW_AUTH_80211_AUTH_ALG:
-		if (param->value & IW_AUTH_ALG_SHARED_KEY)
-			priv->wep_restrict = 1;
-		else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
-			priv->wep_restrict = 0;
-		else
-			ret = -EINVAL;
-		break;
-
-	case IW_AUTH_WPA_ENABLED:
-		if (priv->has_wpa) {
-			priv->wpa_enabled = param->value ? 1 : 0;
-		} else {
-			if (param->value)
-				ret = -EOPNOTSUPP;
-			/* else silently accept disable of WPA */
-			priv->wpa_enabled = 0;
-		}
-		break;
-
-	default:
-		ret = -EOPNOTSUPP;
-	}
-
-	orinoco_unlock(priv, &flags);
-	return ret;
-}
-
-static int orinoco_ioctl_get_auth(struct net_device *dev,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct iw_param *param = &wrqu->param;
-	unsigned long flags;
-	int ret = 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_KEY_MGMT:
-		param->value = priv->key_mgmt;
-		break;
-
-	case IW_AUTH_TKIP_COUNTERMEASURES:
-		param->value = priv->tkip_cm_active;
-		break;
-
-	case IW_AUTH_80211_AUTH_ALG:
-		if (priv->wep_restrict)
-			param->value = IW_AUTH_ALG_SHARED_KEY;
-		else
-			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
-		break;
-
-	case IW_AUTH_WPA_ENABLED:
-		param->value = priv->wpa_enabled;
-		break;
-
-	default:
-		ret = -EOPNOTSUPP;
-	}
-
-	orinoco_unlock(priv, &flags);
-	return ret;
-}
-
-static int orinoco_ioctl_set_genie(struct net_device *dev,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	u8 *buf;
-	unsigned long flags;
-
-	/* cut off at IEEE80211_MAX_DATA_LEN */
-	if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
-	    (wrqu->data.length && (extra == NULL)))
-		return -EINVAL;
-
-	if (wrqu->data.length) {
-		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
-		if (buf == NULL)
-			return -ENOMEM;
-
-		memcpy(buf, extra, wrqu->data.length);
-	} else
-		buf = NULL;
-
-	if (orinoco_lock(priv, &flags) != 0) {
-		kfree(buf);
-		return -EBUSY;
-	}
-
-	kfree(priv->wpa_ie);
-	priv->wpa_ie = buf;
-	priv->wpa_ie_len = wrqu->data.length;
-
-	if (priv->wpa_ie) {
-		/* Looks like wl_lkm wants to check the auth alg, and
-		 * somehow pass it to the firmware.
-		 * Instead it just calls the key mgmt rid
-		 *   - we do this in set auth.
-		 */
-	}
-
-	orinoco_unlock(priv, &flags);
-	return 0;
-}
-
-static int orinoco_ioctl_get_genie(struct net_device *dev,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-	int err = 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
-		wrqu->data.length = 0;
-		goto out;
-	}
-
-	if (wrqu->data.length < priv->wpa_ie_len) {
-		err = -E2BIG;
-		goto out;
-	}
-
-	wrqu->data.length = priv->wpa_ie_len;
-	memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
-
-out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-static int orinoco_ioctl_set_mlme(struct net_device *dev,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_mlme *mlme = (struct iw_mlme *)extra;
-	unsigned long flags;
-	int ret = 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (mlme->cmd) {
-	case IW_MLME_DEAUTH:
-		/* silently ignore */
-		break;
-
-	case IW_MLME_DISASSOC:
-	{
-		struct {
-			u8 addr[ETH_ALEN];
-			__le16 reason_code;
-		} __attribute__ ((packed)) buf;
-
-		memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
-		buf.reason_code = cpu_to_le16(mlme->reason_code);
-		ret = HERMES_WRITE_RECORD(hw, USER_BAP,
-					  HERMES_RID_CNFDISASSOCIATE,
-					  &buf);
-		break;
-	}
-	default:
-		ret = -EOPNOTSUPP;
-	}
-
-	orinoco_unlock(priv, &flags);
-	return ret;
-}
-
-static int orinoco_ioctl_getretry(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *rrq,
-				  char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	u16 short_limit, long_limit, lifetime;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
-				  &short_limit);
-	if (err)
-		goto out;
-
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
-				  &long_limit);
-	if (err)
-		goto out;
-
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
-				  &lifetime);
-	if (err)
-		goto out;
-
-	rrq->disabled = 0;		/* Can't be disabled */
-
-	/* Note : by default, display the retry number */
-	if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-		rrq->flags = IW_RETRY_LIFETIME;
-		rrq->value = lifetime * 1000;	/* ??? */
-	} else {
-		/* By default, display the min number */
-		if ((rrq->flags & IW_RETRY_LONG)) {
-			rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-			rrq->value = long_limit;
-		} else {
-			rrq->flags = IW_RETRY_LIMIT;
-			rrq->value = short_limit;
-			if(short_limit != long_limit)
-				rrq->flags |= IW_RETRY_SHORT;
-		}
-	}
-
- out:
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_reset(struct net_device *dev,
-			       struct iw_request_info *info,
-			       void *wrqu,
-			       char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	if (! capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
-		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-
-		/* Firmware reset */
-		orinoco_reset(&priv->reset_work);
-	} else {
-		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
-
-		schedule_work(&priv->reset_work);
-	}
-
-	return 0;
-}
-
-static int orinoco_ioctl_setibssport(struct net_device *dev,
-				     struct iw_request_info *info,
-				     void *wrqu,
-				     char *extra)
-
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int val = *( (int *) extra );
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	priv->ibss_port = val ;
-
-	/* Actually update the mode we are using */
-	set_port_type(priv);
-
-	orinoco_unlock(priv, &flags);
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getibssport(struct net_device *dev,
-				     struct iw_request_info *info,
-				     void *wrqu,
-				     char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int *val = (int *) extra;
-
-	*val = priv->ibss_port;
-	return 0;
-}
-
-static int orinoco_ioctl_setport3(struct net_device *dev,
-				  struct iw_request_info *info,
-				  void *wrqu,
-				  char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int val = *( (int *) extra );
-	int err = 0;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (val) {
-	case 0: /* Try to do IEEE ad-hoc mode */
-		if (! priv->has_ibss) {
-			err = -EINVAL;
-			break;
-		}
-		priv->prefer_port3 = 0;
-			
-		break;
-
-	case 1: /* Try to do Lucent proprietary ad-hoc mode */
-		if (! priv->has_port3) {
-			err = -EINVAL;
-			break;
-		}
-		priv->prefer_port3 = 1;
-		break;
-
-	default:
-		err = -EINVAL;
-	}
-
-	if (! err) {
-		/* Actually update the mode we are using */
-		set_port_type(priv);
-		err = -EINPROGRESS;
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getport3(struct net_device *dev,
-				  struct iw_request_info *info,
-				  void *wrqu,
-				  char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int *val = (int *) extra;
-
-	*val = priv->prefer_port3;
-	return 0;
-}
-
-static int orinoco_ioctl_setpreamble(struct net_device *dev,
-				     struct iw_request_info *info,
-				     void *wrqu,
-				     char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-	int val;
-
-	if (! priv->has_preamble)
-		return -EOPNOTSUPP;
-
-	/* 802.11b has recently defined some short preamble.
-	 * Basically, the Phy header has been reduced in size.
-	 * This increase performance, especially at high rates
-	 * (the preamble is transmitted at 1Mb/s), unfortunately
-	 * this give compatibility troubles... - Jean II */
-	val = *( (int *) extra );
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (val)
-		priv->preamble = 1;
-	else
-		priv->preamble = 0;
-
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getpreamble(struct net_device *dev,
-				     struct iw_request_info *info,
-				     void *wrqu,
-				     char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int *val = (int *) extra;
-
-	if (! priv->has_preamble)
-		return -EOPNOTSUPP;
-
-	*val = priv->preamble;
-	return 0;
-}
-
-/* ioctl interface to hermes_read_ltv()
- * To use with iwpriv, pass the RID as the token argument, e.g.
- * iwpriv get_rid [0xfc00]
- * At least Wireless Tools 25 is required to use iwpriv.
- * For Wireless Tools 25 and 26 append "dummy" are the end. */
-static int orinoco_ioctl_getrid(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_point *data,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int rid = data->flags;
-	u16 length;
-	int err;
-	unsigned long flags;
-
-	/* It's a "get" function, but we don't want users to access the
-	 * WEP key and other raw firmware data */
-	if (! capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (rid < 0xfc00 || rid > 0xffff)
-		return -EINVAL;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
-			      extra);
-	if (err)
-		goto out;
-
-	data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
-			     MAX_RID_LEN);
-
- out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-/* Trigger a scan (look for other cells in the vicinity) */
-static int orinoco_ioctl_setscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_scan_req *si = (struct iw_scan_req *) extra;
-	int err = 0;
-	unsigned long flags;
-
-	/* Note : you may have realised that, as this is a SET operation,
-	 * this is privileged and therefore a normal user can't
-	 * perform scanning.
-	 * This is not an error, while the device perform scanning,
-	 * traffic doesn't flow, so it's a perfect DoS...
-	 * Jean II */
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Scanning with port 0 disabled would fail */
-	if (!netif_running(dev)) {
-		err = -ENETDOWN;
-		goto out;
-	}
-
-	/* In monitor mode, the scan results are always empty.
-	 * Probe responses are passed to the driver as received
-	 * frames and could be processed in software. */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* Note : because we don't lock out the irq handler, the way
-	 * we access scan variables in priv is critical.
-	 *	o scan_inprogress : not touched by irq handler
-	 *	o scan_mode : not touched by irq handler
-	 * Before modifying anything on those variables, please think hard !
-	 * Jean II */
-
-	/* Save flags */
-	priv->scan_mode = srq->flags;
-
-	/* Always trigger scanning, even if it's in progress.
-	 * This way, if the info frame get lost, we will recover somewhat
-	 * gracefully  - Jean II */
-
-	if (priv->has_hostscan) {
-		switch (priv->firmware_type) {
-		case FIRMWARE_TYPE_SYMBOL:
-			err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFHOSTSCAN_SYMBOL,
-						   HERMES_HOSTSCAN_SYMBOL_ONCE |
-						   HERMES_HOSTSCAN_SYMBOL_BCAST);
-			break;
-		case FIRMWARE_TYPE_INTERSIL: {
-			__le16 req[3];
-
-			req[0] = cpu_to_le16(0x3fff);	/* All channels */
-			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
-			req[2] = 0;			/* Any ESSID */
-			err = HERMES_WRITE_RECORD(hw, USER_BAP,
-						  HERMES_RID_CNFHOSTSCAN, &req);
-		}
-		break;
-		case FIRMWARE_TYPE_AGERE:
-			if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
-				struct hermes_idstring idbuf;
-				size_t len = min(sizeof(idbuf.val),
-						 (size_t) si->essid_len);
-				idbuf.len = cpu_to_le16(len);
-				memcpy(idbuf.val, si->essid, len);
-
-				err = hermes_write_ltv(hw, USER_BAP,
-					       HERMES_RID_CNFSCANSSID_AGERE,
-					       HERMES_BYTES_TO_RECLEN(len + 2),
-					       &idbuf);
-			} else
-				err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFSCANSSID_AGERE,
-						   0);	/* Any ESSID */
-			if (err)
-				break;
-
-			if (priv->has_ext_scan) {
-				/* Clear scan results at the start of
-				 * an extended scan */
-				orinoco_clear_scan_results(priv,
-						msecs_to_jiffies(15000));
-
-				/* TODO: Is this available on older firmware?
-				 *   Can we use it to scan specific channels
-				 *   for IW_SCAN_THIS_FREQ? */
-				err = hermes_write_wordrec(hw, USER_BAP,
-						HERMES_RID_CNFSCANCHANNELS2GHZ,
-						0x7FFF);
-				if (err)
-					goto out;
-
-				err = hermes_inquire(hw,
-						     HERMES_INQ_CHANNELINFO);
-			} else
-				err = hermes_inquire(hw, HERMES_INQ_SCAN);
-			break;
-		}
-	} else
-		err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
-	/* One more client */
-	if (! err)
-		priv->scan_inprogress = 1;
-
- out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
-					   struct iw_request_info *info,
-					   char *current_ev,
-					   char *end_buf,
-					   union hermes_scan_info *bss,
-					   unsigned long last_scanned)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* First entry *MUST* be the AP MAC address */
-	iwe.cmd = SIOCGIWAP;
-	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
-	if (iwe.u.data.length > 32)
-		iwe.u.data.length = 32;
-	iwe.cmd = SIOCGIWESSID;
-	iwe.u.data.flags = 1;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, bss->a.essid);
-
-	/* Add mode */
-	iwe.cmd = SIOCGIWMODE;
-	capabilities = le16_to_cpu(bss->a.capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			iwe.u.mode = IW_MODE_MASTER;
-		else
-			iwe.u.mode = IW_MODE_ADHOC;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_UINT_LEN);
-	}
-
-	channel = bss->s.channel;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = channel_frequency[channel-1] * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
-	iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-	else
-		iwe.u.data.flags = IW_ENCODE_DISABLED;
-	iwe.u.data.length = 0;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, NULL);
-
-	/* Bit rate is not available in Lucent/Agere firmwares */
-	if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-		char *current_val = current_ev + iwe_stream_lcp_len(info);
-		int i;
-		int step;
-
-		if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-			step = 2;
-		else
-			step = 1;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-		/* Max 10 values */
-		for (i = 0; i < 10; i += step) {
-			/* NULL terminated */
-			if (bss->p.rates[i] == 0x0)
-				break;
-			/* Bit rate given in 500 kb/s units (+ 0x80) */
-			iwe.u.bitrate.value =
-				((bss->p.rates[i] & 0x7f) * 500000);
-			current_val = iwe_stream_add_value(info, current_ev,
-							   current_val,
-							   end_buf, &iwe,
-							   IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if ((current_val - current_ev) > iwe_stream_lcp_len(info))
-			current_ev = current_val;
-	}
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->a.beacon_interv));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
-					       struct iw_request_info *info,
-					       char *current_ev,
-					       char *end_buf,
-					       struct agere_ext_scan_info *bss,
-					       unsigned long last_scanned)
-{
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-	u8 *ie;
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* First entry *MUST* be the AP MAC address */
-	iwe.cmd = SIOCGIWAP;
-	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	ie = bss->data;
-	iwe.u.data.length = ie[1];
-	if (iwe.u.data.length) {
-		if (iwe.u.data.length > 32)
-			iwe.u.data.length = 32;
-		iwe.cmd = SIOCGIWESSID;
-		iwe.u.data.flags = 1;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, &ie[2]);
-	}
-
-	/* Add mode */
-	capabilities = le16_to_cpu(bss->capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		iwe.cmd = SIOCGIWMODE;
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			iwe.u.mode = IW_MODE_MASTER;
-		else
-			iwe.u.mode = IW_MODE_ADHOC;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_UINT_LEN);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
-	channel = ie ? ie[2] : 0;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = channel_frequency[channel-1] * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = bss->level - 0x95;
-	iwe.u.qual.noise = bss->noise - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-	else
-		iwe.u.data.flags = IW_ENCODE_DISABLED;
-	iwe.u.data.length = 0;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, NULL);
-
-	/* WPA IE */
-	ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	/* RSN IE */
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
-	if (ie) {
-		char *p = current_ev + iwe_stream_lcp_len(info);
-		int i;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
-		for (i = 2; i < (ie[1] + 2); i++) {
-			iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
-			p = iwe_stream_add_value(info, current_ev, p, end_buf,
-						 &iwe, IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if (p > (current_ev + iwe_stream_lcp_len(info)))
-			current_ev = p;
-	}
-
-	/* Timestamp */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length =
-		snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
-			 (unsigned long long) le64_to_cpu(bss->timestamp));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->beacon_interval));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-	unsigned long flags;
-	char *current_ev = extra;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (priv->scan_inprogress) {
-		/* Important note : we don't want to block the caller
-		 * until results are ready for various reasons.
-		 * First, managing wait queues is complex and racy.
-		 * Second, we grab some rtnetlink lock before comming
-		 * here (in dev_ioctl()).
-		 * Third, we generate an Wireless Event, so the
-		 * caller can wait itself on that - Jean II */
-		err = -EAGAIN;
-		goto out;
-	}
-
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev =
-				orinoco_translate_ext_scan(dev, info,
-							   current_ev,
-							   extra + srq->length,
-							   &bss->bss,
-							   bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-
-	} else {
-		struct bss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev = orinoco_translate_scan(dev, info,
-							    current_ev,
-							    extra + srq->length,
-							    &bss->bss,
-							    bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-	}
-
-	srq->length = (current_ev - extra);
-	srq->flags = (__u16) priv->scan_mode;
-
-out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-/* Commit handler, called after set operations */
-static int orinoco_ioctl_commit(struct net_device *dev,
-				struct iw_request_info *info,
-				void *wrqu,
-				char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	unsigned long flags;
-	int err = 0;
-
-	if (!priv->open)
-		return 0;
-
-	if (priv->broken_disableport) {
-		orinoco_reset(&priv->reset_work);
-		return 0;
-	}
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return err;
-
-	err = hermes_disable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to disable port "
-		       "while reconfiguring card\n", dev->name);
-		priv->broken_disableport = 1;
-		goto out;
-	}
-
-	err = __orinoco_program_rids(dev);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-		       dev->name);
-		goto out;
-	}
-
-	err = hermes_enable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-		       dev->name);
-		goto out;
-	}
-
- out:
-	if (err) {
-		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-		schedule_work(&priv->reset_work);
-		err = 0;
-	}
-
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-static const struct iw_priv_args orinoco_privtab[] = {
-	{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
-	{ SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
-	{ SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  0, "set_port3" },
-	{ SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  "get_port3" },
-	{ SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  0, "set_preamble" },
-	{ SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  "get_preamble" },
-	{ SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  0, "set_ibssport" },
-	{ SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	  "get_ibssport" },
-	{ SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
-	  "get_rid" },
-};
-
-
-/*
- * Structures to export the Wireless Handlers
- */
-
-#define STD_IW_HANDLER(id, func) \
-	[IW_IOCTL_IDX(id)] = (iw_handler) func
-static const iw_handler	orinoco_handler[] = {
-	STD_IW_HANDLER(SIOCSIWCOMMIT,	orinoco_ioctl_commit),
-	STD_IW_HANDLER(SIOCGIWNAME,	orinoco_ioctl_getname),
-	STD_IW_HANDLER(SIOCSIWFREQ,	orinoco_ioctl_setfreq),
-	STD_IW_HANDLER(SIOCGIWFREQ,	orinoco_ioctl_getfreq),
-	STD_IW_HANDLER(SIOCSIWMODE,	orinoco_ioctl_setmode),
-	STD_IW_HANDLER(SIOCGIWMODE,	orinoco_ioctl_getmode),
-	STD_IW_HANDLER(SIOCSIWSENS,	orinoco_ioctl_setsens),
-	STD_IW_HANDLER(SIOCGIWSENS,	orinoco_ioctl_getsens),
-	STD_IW_HANDLER(SIOCGIWRANGE,	orinoco_ioctl_getiwrange),
-	STD_IW_HANDLER(SIOCSIWSPY,	iw_handler_set_spy),
-	STD_IW_HANDLER(SIOCGIWSPY,	iw_handler_get_spy),
-	STD_IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
-	STD_IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
-	STD_IW_HANDLER(SIOCSIWAP,	orinoco_ioctl_setwap),
-	STD_IW_HANDLER(SIOCGIWAP,	orinoco_ioctl_getwap),
-	STD_IW_HANDLER(SIOCSIWSCAN,	orinoco_ioctl_setscan),
-	STD_IW_HANDLER(SIOCGIWSCAN,	orinoco_ioctl_getscan),
-	STD_IW_HANDLER(SIOCSIWESSID,	orinoco_ioctl_setessid),
-	STD_IW_HANDLER(SIOCGIWESSID,	orinoco_ioctl_getessid),
-	STD_IW_HANDLER(SIOCSIWNICKN,	orinoco_ioctl_setnick),
-	STD_IW_HANDLER(SIOCGIWNICKN,	orinoco_ioctl_getnick),
-	STD_IW_HANDLER(SIOCSIWRATE,	orinoco_ioctl_setrate),
-	STD_IW_HANDLER(SIOCGIWRATE,	orinoco_ioctl_getrate),
-	STD_IW_HANDLER(SIOCSIWRTS,	orinoco_ioctl_setrts),
-	STD_IW_HANDLER(SIOCGIWRTS,	orinoco_ioctl_getrts),
-	STD_IW_HANDLER(SIOCSIWFRAG,	orinoco_ioctl_setfrag),
-	STD_IW_HANDLER(SIOCGIWFRAG,	orinoco_ioctl_getfrag),
-	STD_IW_HANDLER(SIOCGIWRETRY,	orinoco_ioctl_getretry),
-	STD_IW_HANDLER(SIOCSIWENCODE,	orinoco_ioctl_setiwencode),
-	STD_IW_HANDLER(SIOCGIWENCODE,	orinoco_ioctl_getiwencode),
-	STD_IW_HANDLER(SIOCSIWPOWER,	orinoco_ioctl_setpower),
-	STD_IW_HANDLER(SIOCGIWPOWER,	orinoco_ioctl_getpower),
-	STD_IW_HANDLER(SIOCSIWGENIE,	orinoco_ioctl_set_genie),
-	STD_IW_HANDLER(SIOCGIWGENIE,	orinoco_ioctl_get_genie),
-	STD_IW_HANDLER(SIOCSIWMLME,	orinoco_ioctl_set_mlme),
-	STD_IW_HANDLER(SIOCSIWAUTH,	orinoco_ioctl_set_auth),
-	STD_IW_HANDLER(SIOCGIWAUTH,	orinoco_ioctl_get_auth),
-	STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
-	STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
-};
-
-
-/*
-  Added typecasting since we no longer use iwreq_data -- Moustafa
- */
-static const iw_handler	orinoco_private_handler[] = {
-	[0] = (iw_handler) orinoco_ioctl_reset,
-	[1] = (iw_handler) orinoco_ioctl_reset,
-	[2] = (iw_handler) orinoco_ioctl_setport3,
-	[3] = (iw_handler) orinoco_ioctl_getport3,
-	[4] = (iw_handler) orinoco_ioctl_setpreamble,
-	[5] = (iw_handler) orinoco_ioctl_getpreamble,
-	[6] = (iw_handler) orinoco_ioctl_setibssport,
-	[7] = (iw_handler) orinoco_ioctl_getibssport,
-	[9] = (iw_handler) orinoco_ioctl_getrid,
-};
-
-static const struct iw_handler_def orinoco_handler_def = {
-	.num_standard = ARRAY_SIZE(orinoco_handler),
-	.num_private = ARRAY_SIZE(orinoco_private_handler),
-	.num_private_args = ARRAY_SIZE(orinoco_privtab),
-	.standard = orinoco_handler,
-	.private = orinoco_private_handler,
-	.private_args = orinoco_privtab,
-	.get_wireless_stats = orinoco_get_wireless_stats,
-};
-
-static void orinoco_get_drvinfo(struct net_device *dev,
-				struct ethtool_drvinfo *info)
-{
-	struct orinoco_private *priv = netdev_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                                            */
-/********************************************************************/
-
-EXPORT_SYMBOL(alloc_orinocodev);
-EXPORT_SYMBOL(free_orinocodev);
-
-EXPORT_SYMBOL(__orinoco_up);
-EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_reinit_firmware);
-
-EXPORT_SYMBOL(orinoco_interrupt);
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-	" (David Gibson <hermes@gibson.dropbear.id.au>, "
-	"Pavel Roskin <proski@gnu.org>, et al)";
-
-static int __init init_orinoco(void)
-{
-	printk(KERN_DEBUG "%s\n", version);
-	return 0;
-}
-
-static void __exit exit_orinoco(void)
-{
-}
-
-module_init(init_orinoco);
-module_exit(exit_orinoco);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,8 +6,8 @@
  * It should also be usable on various Prism II based cards such as the
  * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
  * cards such as the 3Com AirConnect and Ericsson WLAN.
- * 
- * Copyright notice & release notes in file orinoco.c
+ *
+ * Copyright notice & release notes in file main.c
  */
 
 #define DRIVER_NAME "orinoco_cs"
@@ -30,7 +30,8 @@
 /********************************************************************/
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
+MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco,"
+		   " Prism II based and similar wireless cards");
 MODULE_LICENSE("Dual MPL/GPL");
 
 /* Module parameters */
@@ -53,8 +54,8 @@ struct orinoco_pccard {
 
 	/* Used to handle hard reset */
 	/* yuck, we need this hack to work around the insanity of the
-         * PCMCIA layer */
-	unsigned long hard_reset_in_progress; 
+	 * PCMCIA layer */
+	unsigned long hard_reset_in_progress;
 };
 
 
@@ -98,7 +99,7 @@ orinoco_cs_hard_reset(struct orinoco_pri
  * This 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.  */
@@ -111,7 +112,7 @@ orinoco_cs_probe(struct pcmcia_device *l
 
 	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
 			       orinoco_cs_hard_reset, NULL);
-	if (! dev)
+	if (!dev)
 		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
@@ -124,7 +125,7 @@ orinoco_cs_probe(struct pcmcia_device *l
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev; 
+	link->irq.Instance = dev;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -162,8 +163,10 @@ static void orinoco_cs_detach(struct pcm
  */
 
 #define CS_CHECK(fn, ret) do { \
-		last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
-	} while (0)
+	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,
@@ -307,8 +310,8 @@ orinoco_cs_config(struct pcmcia_device *
 	 * initialized and arranged in a linked list at link->dev_node. */
 	strcpy(card->node.dev_name, dev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
-                                    used to indicate that the
-                                    net_device has been registered */
+				       * used to indicate that the
+				       * net_device has been registered */
 
 	/* Finally, report what we've done */
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
@@ -359,7 +362,7 @@ static int orinoco_cs_suspend(struct pcm
 	/* This is probably racy, but I can't think of
 	   a better way, short of rewriting the PCMCIA
 	   layer to not suck :-( */
-	if (! test_bit(0, &card->hard_reset_in_progress)) {
+	if (!test_bit(0, &card->hard_reset_in_progress)) {
 		spin_lock_irqsave(&priv->lock, flags);
 
 		err = __orinoco_down(dev);
@@ -384,7 +387,7 @@ static int orinoco_cs_resume(struct pcmc
 	int err = 0;
 	unsigned long flags;
 
-	if (! test_bit(0, &card->hard_reset_in_progress)) {
+	if (!test_bit(0, &card->hard_reset_in_progress)) {
 		err = orinoco_reinit_firmware(dev);
 		if (err) {
 			printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
@@ -397,7 +400,7 @@ static int orinoco_cs_resume(struct pcmc
 		netif_device_attach(dev);
 		priv->hw_unavailable--;
 
-		if (priv->open && ! priv->hw_unavailable) {
+		if (priv->open && !priv->hw_unavailable) {
 			err = __orinoco_up(dev);
 			if (err)
 				printk(KERN_ERR "%s: Error %d restarting card\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /* orinoco.h
- * 
+ *
  * Common definitions to all pieces of the various orinoco
  * drivers
  */
@@ -18,9 +18,9 @@
 #include "hermes.h"
 
 /* To enable debug messages */
-//#define ORINOCO_DEBUG		3
+/*#define ORINOCO_DEBUG		3*/
 
-#define WIRELESS_SPY		// enable iwspy support
+#define WIRELESS_SPY		/* enable iwspy support */
 
 #define MAX_SCAN_LEN		4096
 
@@ -59,14 +59,6 @@ struct xbss_element {
 	struct list_head list;
 };
 
-struct hermes_rx_descriptor;
-
-struct orinoco_rx_data {
-	struct hermes_rx_descriptor *desc;
-	struct sk_buff *skb;
-	struct list_head list;
-};
-
 struct firmware;
 
 struct orinoco_private {
@@ -83,7 +75,6 @@ struct orinoco_private {
 	/* Interrupt tasklets */
 	struct tasklet_struct rx_tasklet;
 	struct list_head rx_list;
-	struct orinoco_rx_data *rx_data;
 
 	/* driver state */
 	int open;
@@ -130,7 +121,7 @@ struct orinoco_private {
 	u16 encode_alg, wep_restrict, tx_key;
 	struct orinoco_key keys[ORINOCO_MAX_KEYS];
 	int bitratemode;
- 	char nick[IW_ESSID_MAX_SIZE+1];
+	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
 	char desired_bssid[ETH_ALEN];
 	int bssid_fixed;
@@ -140,7 +131,7 @@ struct orinoco_private {
 	u16 pm_on, pm_mcast, pm_period, pm_timeout;
 	u16 preamble;
 #ifdef WIRELESS_SPY
- 	struct iw_spy_data spy_data; /* iwspy support */
+	struct iw_spy_data spy_data; /* iwspy support */
 	struct iw_public_data	wireless_data;
 #endif
 
@@ -168,16 +159,21 @@ struct orinoco_private {
 	unsigned int tkip_cm_active:1;
 	unsigned int key_mgmt:3;
 
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
 	/* Cached in memory firmware to use during ->resume. */
 	const struct firmware *cached_pri_fw;
 	const struct firmware *cached_fw;
+#endif
 
 	struct notifier_block pm_notifier;
 };
 
 #ifdef ORINOCO_DEBUG
 extern int orinoco_debug;
-#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
+#define DEBUG(n, args...) do { \
+	if (orinoco_debug > (n)) \
+		printk(KERN_DEBUG args); \
+} while (0)
 #else
 #define DEBUG(n, args...) do { } while (0)
 #endif	/* ORINOCO_DEBUG */
@@ -194,7 +190,7 @@ extern void free_orinocodev(struct net_d
 extern int __orinoco_up(struct net_device *dev);
 extern int __orinoco_down(struct net_device *dev);
 extern int orinoco_reinit_firmware(struct net_device *dev);
-extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
+extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
 
 /********************************************************************/
 /* Locking and synchronization functions                            */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_nortel.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,12 +9,12 @@
  *
  * Some of this code is borrowed from orinoco_plx.c
  *	Copyright (C) 2001 Daniel Barlow
- * Some of this code is borrowed from orinoco_pci.c 
+ * Some of this code is borrowed from orinoco_pci.c
  *  Copyright (C) 2001 Jean Tourrilhes
  * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
  * has been copied from it. linux-wlan-ng-0.1.10 is originally :
  *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
- * 
+ *
  * The contents of this file are subject to the Mozilla Public License
  * Version 1.1 (the "License"); you may not use this file except in
  * compliance with the License. You may obtain a copy of the License
@@ -103,9 +103,8 @@ static int orinoco_nortel_hw_init(struct
 	iowrite16(0x8, card->bridge_io + 2);
 	for (i = 0; i < 30; i++) {
 		mdelay(30);
-		if (ioread16(card->bridge_io) & 0x10) {
+		if (ioread16(card->bridge_io) & 0x10)
 			break;
-		}
 	}
 	if (i == 30) {
 		printk(KERN_ERR PFX "brg1 timed out\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /* orinoco_pci.c
- * 
+ *
  * Driver for Prism 2.5/3 devices that have a direct PCI interface
  * (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
  * The card contains only one PCI region, which contains all the usual
@@ -237,7 +237,8 @@ static char version[] __initdata = DRIVE
 	" (Pavel Roskin <proski@gnu.org>,"
 	" David Gibson <hermes@gibson.dropbear.id.au> &"
 	" Jean Tourrilhes <jt@hpl.hp.com>)";
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> &"
+	      " David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
 MODULE_LICENSE("Dual MPL/GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_pci.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_pci.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,10 +1,10 @@
 /* orinoco_pci.h
- * 
+ *
  * Common code for all Orinoco drivers for PCI devices, including
  * both native PCI and PCMCIA-to-PCI bridges.
  *
  * Copyright (C) 2005, Pavel Roskin.
- * See orinoco.c for license.
+ * See main.c for license.
  */
 
 #ifndef _ORINOCO_PCI_H
@@ -37,11 +37,11 @@ static int orinoco_pci_suspend(struct pc
 	if (err)
 		printk(KERN_WARNING "%s: error %d bringing interface down "
 		       "for suspend\n", dev->name, err);
-	
+
 	netif_device_detach(dev);
 
 	priv->hw_unavailable++;
-	
+
 	orinoco_unlock(priv, &flags);
 
 	free_irq(pdev->irq, dev);
@@ -90,13 +90,13 @@ static int orinoco_pci_resume(struct pci
 
 	priv->hw_unavailable--;
 
-	if (priv->open && (! priv->hw_unavailable)) {
+	if (priv->open && (!priv->hw_unavailable)) {
 		err = __orinoco_up(dev);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card on resume\n",
 			       dev->name, err);
 	}
-	
+
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_plx.c	2009-06-09 23:05:27.000000000 -0400
@@ -146,9 +146,8 @@ static int orinoco_plx_hw_init(struct or
 	};
 
 	printk(KERN_DEBUG PFX "CIS: ");
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < 16; i++)
 		printk("%02X:", ioread8(card->attr_io + (i << 1)));
-	}
 	printk("\n");
 
 	/* Verify whether a supported PC card is present */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/orinoco_tmd.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /* orinoco_tmd.c
  *
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a TMD7160. 
+ * but are connected to the PCI bus by a TMD7160.
  *
  * Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
  * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
@@ -27,7 +27,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the MPL or the GPL.
  *
- * The actual driving is done by orinoco.c, this is just resource
+ * The actual driving is done by main.c, this is just resource
  * allocation stuff.
  *
  * This driver is modeled after the orinoco_plx driver. The main
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/scan.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/scan.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/scan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,233 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+#include "scan.h"
+
+#define ORINOCO_MAX_BSS_COUNT	64
+
+#define PRIV_BSS	((struct bss_element *)priv->bss_xbss_data)
+#define PRIV_XBSS	((struct xbss_element *)priv->bss_xbss_data)
+
+int orinoco_bss_data_allocate(struct orinoco_private *priv)
+{
+	if (priv->bss_xbss_data)
+		return 0;
+
+	if (priv->has_ext_scan)
+		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+					      sizeof(struct xbss_element),
+					      GFP_KERNEL);
+	else
+		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+					      sizeof(struct bss_element),
+					      GFP_KERNEL);
+
+	if (!priv->bss_xbss_data) {
+		printk(KERN_WARNING "Out of memory allocating beacons");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+void orinoco_bss_data_free(struct orinoco_private *priv)
+{
+	kfree(priv->bss_xbss_data);
+	priv->bss_xbss_data = NULL;
+}
+
+void orinoco_bss_data_init(struct orinoco_private *priv)
+{
+	int i;
+
+	INIT_LIST_HEAD(&priv->bss_free_list);
+	INIT_LIST_HEAD(&priv->bss_list);
+	if (priv->has_ext_scan)
+		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+			list_add_tail(&(PRIV_XBSS[i].list),
+				      &priv->bss_free_list);
+	else
+		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+			list_add_tail(&(PRIV_BSS[i].list),
+				      &priv->bss_free_list);
+
+}
+
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+				unsigned long scan_age)
+{
+	if (priv->has_ext_scan) {
+		struct xbss_element *bss;
+		struct xbss_element *tmp_bss;
+
+		/* Blow away current list of scan results */
+		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+			if (!scan_age ||
+			    time_after(jiffies, bss->last_scanned + scan_age)) {
+				list_move_tail(&bss->list,
+					       &priv->bss_free_list);
+				/* Don't blow away ->list, just BSS data */
+				memset(&bss->bss, 0, sizeof(bss->bss));
+				bss->last_scanned = 0;
+			}
+		}
+	} else {
+		struct bss_element *bss;
+		struct bss_element *tmp_bss;
+
+		/* Blow away current list of scan results */
+		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+			if (!scan_age ||
+			    time_after(jiffies, bss->last_scanned + scan_age)) {
+				list_move_tail(&bss->list,
+					       &priv->bss_free_list);
+				/* Don't blow away ->list, just BSS data */
+				memset(&bss->bss, 0, sizeof(bss->bss));
+				bss->last_scanned = 0;
+			}
+		}
+	}
+}
+
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+				 struct agere_ext_scan_info *atom)
+{
+	struct xbss_element *bss = NULL;
+	int found = 0;
+
+	/* Try to update an existing bss first */
+	list_for_each_entry(bss, &priv->bss_list, list) {
+		if (compare_ether_addr(bss->bss.bssid, atom->bssid))
+			continue;
+		/* ESSID lengths */
+		if (bss->bss.data[1] != atom->data[1])
+			continue;
+		if (memcmp(&bss->bss.data[2], &atom->data[2],
+			   atom->data[1]))
+			continue;
+		found = 1;
+		break;
+	}
+
+	/* Grab a bss off the free list */
+	if (!found && !list_empty(&priv->bss_free_list)) {
+		bss = list_entry(priv->bss_free_list.next,
+				 struct xbss_element, list);
+		list_del(priv->bss_free_list.next);
+
+		list_add_tail(&bss->list, &priv->bss_list);
+	}
+
+	if (bss) {
+		/* Always update the BSS to get latest beacon info */
+		memcpy(&bss->bss, atom, sizeof(bss->bss));
+		bss->last_scanned = jiffies;
+	}
+}
+
+int orinoco_process_scan_results(struct orinoco_private *priv,
+				 unsigned char *buf,
+				 int len)
+{
+	int			offset;		/* In the scan data */
+	union hermes_scan_info *atom;
+	int			atom_len;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		atom_len = sizeof(struct agere_scan_apinfo);
+		offset = 0;
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		/* Lack of documentation necessitates this hack.
+		 * Different firmwares have 68 or 76 byte long atoms.
+		 * We try modulo first.  If the length divides by both,
+		 * we check what would be the channel in the second
+		 * frame for a 68-byte atom.  76-byte atoms have 0 there.
+		 * Valid channel cannot be 0.  */
+		if (len % 76)
+			atom_len = 68;
+		else if (len % 68)
+			atom_len = 76;
+		else if (len >= 1292 && buf[68] == 0)
+			atom_len = 76;
+		else
+			atom_len = 68;
+		offset = 0;
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		offset = 4;
+		if (priv->has_hostscan) {
+			atom_len = le16_to_cpup((__le16 *)buf);
+			/* Sanity check for atom_len */
+			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+				printk(KERN_ERR "%s: Invalid atom_len in scan "
+				       "data: %d\n", priv->ndev->name,
+				       atom_len);
+				return -EIO;
+			}
+		} else
+			atom_len = offsetof(struct prism2_scan_apinfo, atim);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	/* Check that we got an whole number of atoms */
+	if ((len - offset) % atom_len) {
+		printk(KERN_ERR "%s: Unexpected scan data length %d, "
+		       "atom_len %d, offset %d\n", priv->ndev->name, len,
+		       atom_len, offset);
+		return -EIO;
+	}
+
+	orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
+
+	/* Read the entries one by one */
+	for (; offset + atom_len <= len; offset += atom_len) {
+		int found = 0;
+		struct bss_element *bss = NULL;
+
+		/* Get next atom */
+		atom = (union hermes_scan_info *) (buf + offset);
+
+		/* Try to update an existing bss first */
+		list_for_each_entry(bss, &priv->bss_list, list) {
+			if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
+				continue;
+			if (le16_to_cpu(bss->bss.a.essid_len) !=
+			      le16_to_cpu(atom->a.essid_len))
+				continue;
+			if (memcmp(bss->bss.a.essid, atom->a.essid,
+			      le16_to_cpu(atom->a.essid_len)))
+				continue;
+			found = 1;
+			break;
+		}
+
+		/* Grab a bss off the free list */
+		if (!found && !list_empty(&priv->bss_free_list)) {
+			bss = list_entry(priv->bss_free_list.next,
+					 struct bss_element, list);
+			list_del(priv->bss_free_list.next);
+
+			list_add_tail(&bss->list, &priv->bss_list);
+		}
+
+		if (bss) {
+			/* Always update the BSS to get latest beacon info */
+			memcpy(&bss->bss, atom, sizeof(bss->bss));
+			bss->last_scanned = jiffies;
+		}
+	}
+
+	return 0;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/scan.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/scan.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/scan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/scan.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,29 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_SCAN_H_
+#define _ORINOCO_SCAN_H_
+
+/* Forward declarations */
+struct orinoco_private;
+struct agere_ext_scan_info;
+
+/* Setup and free memory for scan results */
+int orinoco_bss_data_allocate(struct orinoco_private *priv);
+void orinoco_bss_data_free(struct orinoco_private *priv);
+void orinoco_bss_data_init(struct orinoco_private *priv);
+
+/* Add scan results */
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+				 struct agere_ext_scan_info *atom);
+int orinoco_process_scan_results(struct orinoco_private *dev,
+				 unsigned char *buf,
+				 int len);
+
+/* Clear scan results */
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+				unsigned long scan_age);
+
+
+#endif /* _ORINOCO_SCAN_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/spectrum_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -4,7 +4,7 @@
  * Communications and Intel PRO/Wireless 2011B.
  *
  * The driver implements Symbol firmware download.  The rest is handled
- * in hermes.c and orinoco.c.
+ * in hermes.c and main.c.
  *
  * Utilities for downloading the Symbol firmware are available at
  * http://sourceforge.net/projects/orinoco/
@@ -15,7 +15,7 @@
  * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
  * 	Copyright (C) Symbol Technologies.
  *
- * See copyright notice in file orinoco.c.
+ * See copyright notice in file main.c.
  */
 
 #define DRIVER_NAME "spectrum_cs"
@@ -133,7 +133,7 @@ spectrum_reset(struct pcmcia_device *lin
 	udelay(1000);
 	return 0;
 
-      cs_failed:
+cs_failed:
 	cs_error(link, last_fn, last_ret);
 	return -ENODEV;
 }
@@ -171,7 +171,7 @@ spectrum_cs_stop_firmware(struct orinoco
  * This 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.  */
@@ -185,7 +185,7 @@ spectrum_cs_probe(struct pcmcia_device *
 	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
 			       spectrum_cs_hard_reset,
 			       spectrum_cs_stop_firmware);
-	if (! dev)
+	if (!dev)
 		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
@@ -198,7 +198,7 @@ spectrum_cs_probe(struct pcmcia_device *
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev; 
+	link->irq.Instance = dev;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -367,9 +367,8 @@ spectrum_cs_config(struct pcmcia_device
 	card->node.major = card->node.minor = 0;
 
 	/* Reset card */
-	if (spectrum_cs_hard_reset(priv) != 0) {
+	if (spectrum_cs_hard_reset(priv) != 0)
 		goto failed;
-	}
 
 	SET_NETDEV_DEV(dev, &handle_to_dev(link));
 	/* Tell the stack we exist */
@@ -382,8 +381,8 @@ spectrum_cs_config(struct pcmcia_device
 	 * initialized and arranged in a linked list at link->dev_node. */
 	strcpy(card->node.dev_name, dev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
-                                    used to indicate that the
-                                    net_device has been registered */
+				       * used to indicate that the
+				       * net_device has been registered */
 
 	/* Finally, report what we've done */
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/wext.c linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/wext.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/wext.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/wext.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,2325 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+#include "mic.h"
+#include "scan.h"
+#include "main.h"
+
+#include "wext.h"
+
+#define MAX_RID_LEN 1024
+
+static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	struct iw_statistics *wstats = &priv->wstats;
+	int err;
+	unsigned long flags;
+
+	if (!netif_device_present(dev)) {
+		printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
+		       dev->name);
+		return NULL; /* FIXME: Can we do better than this? */
+	}
+
+	/* If busy, return the old stats.  Returning NULL may cause
+	 * the interface to disappear from /proc/net/wireless */
+	if (orinoco_lock(priv, &flags) != 0)
+		return wstats;
+
+	/* We can't really wait for the tallies inquiry command to
+	 * complete, so we just use the previous results and trigger
+	 * a new tallies inquiry command for next time - Jean II */
+	/* FIXME: Really we should wait for the inquiry to come back -
+	 * as it is the stats we give don't make a whole lot of sense.
+	 * Unfortunately, it's not clear how to do that within the
+	 * wireless extensions framework: I think we're in user
+	 * context, but a lock seems to be held by the time we get in
+	 * here so we're not safe to sleep here. */
+	hermes_inquire(hw, HERMES_INQ_TALLIES);
+
+	if (priv->iw_mode == IW_MODE_ADHOC) {
+		memset(&wstats->qual, 0, sizeof(wstats->qual));
+		/* If a spy address is defined, we report stats of the
+		 * first spy address - Jean II */
+		if (SPY_NUMBER(priv)) {
+			wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+			wstats->qual.level = priv->spy_data.spy_stat[0].level;
+			wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+			wstats->qual.updated =
+				priv->spy_data.spy_stat[0].updated;
+		}
+	} else {
+		struct {
+			__le16 qual, signal, noise, unused;
+		} __attribute__ ((packed)) cq;
+
+		err = HERMES_READ_RECORD(hw, USER_BAP,
+					 HERMES_RID_COMMSQUALITY, &cq);
+
+		if (!err) {
+			wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+			wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+			wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+			wstats->qual.updated =
+				IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+		}
+	}
+
+	orinoco_unlock(priv, &flags);
+	return wstats;
+}
+
+/********************************************************************/
+/* Wireless extensions                                              */
+/********************************************************************/
+
+static int orinoco_ioctl_getname(struct net_device *dev,
+				 struct iw_request_info *info,
+				 char *name,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int numrates;
+	int err;
+
+	err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
+
+	if (!err && (numrates > 2))
+		strcpy(name, "IEEE 802.11b");
+	else
+		strcpy(name, "IEEE 802.11-DS");
+
+	return 0;
+}
+
+static int orinoco_ioctl_setwap(struct net_device *dev,
+				struct iw_request_info *info,
+				struct sockaddr *ap_addr,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
+	static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Enable automatic roaming - no sanity checks are needed */
+	if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
+	    memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
+		priv->bssid_fixed = 0;
+		memset(priv->desired_bssid, 0, ETH_ALEN);
+
+		/* "off" means keep existing connection */
+		if (ap_addr->sa_data[0] == 0) {
+			__orinoco_hw_set_wap(priv);
+			err = 0;
+		}
+		goto out;
+	}
+
+	if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
+		printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
+		       "support manual roaming\n",
+		       dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (priv->iw_mode != IW_MODE_INFRA) {
+		printk(KERN_WARNING "%s: Manual roaming supported only in "
+		       "managed mode\n", dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Intersil firmware hangs without Desired ESSID */
+	if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
+	    strlen(priv->desired_essid) == 0) {
+		printk(KERN_WARNING "%s: Desired ESSID must be set for "
+		       "manual roaming\n", dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Finally, enable manual roaming */
+	priv->bssid_fixed = 1;
+	memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+static int orinoco_ioctl_getwap(struct net_device *dev,
+				struct iw_request_info *info,
+				struct sockaddr *ap_addr,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	ap_addr->sa_family = ARPHRD_ETHER;
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, ap_addr->sa_data);
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_setmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
+
+	if (priv->iw_mode == *mode)
+		return 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	switch (*mode) {
+	case IW_MODE_ADHOC:
+		if (!priv->has_ibss && !priv->has_port3)
+			err = -EOPNOTSUPP;
+		break;
+
+	case IW_MODE_INFRA:
+		break;
+
+	case IW_MODE_MONITOR:
+		if (priv->broken_monitor && !force_monitor) {
+			printk(KERN_WARNING "%s: Monitor mode support is "
+			       "buggy in this firmware, not enabling\n",
+			       dev->name);
+			err = -EOPNOTSUPP;
+		}
+		break;
+
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
+
+	if (err == -EINPROGRESS) {
+		priv->iw_mode = *mode;
+		set_port_type(priv);
+	}
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	*mode = priv->iw_mode;
+	return 0;
+}
+
+static int orinoco_ioctl_getiwrange(struct net_device *dev,
+				    struct iw_request_info *info,
+				    struct iw_point *rrq,
+				    char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	struct iw_range *range = (struct iw_range *) extra;
+	int numrates;
+	int i, k;
+
+	rrq->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
+
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 22;
+
+	/* Set available channels/frequencies */
+	range->num_channels = NUM_CHANNELS;
+	k = 0;
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (priv->channel_mask & (1 << i)) {
+			range->freq[k].i = i + 1;
+			range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
+					    100000);
+			range->freq[k].e = 1;
+			k++;
+		}
+
+		if (k >= IW_MAX_FREQUENCIES)
+			break;
+	}
+	range->num_frequency = k;
+	range->sensitivity = 3;
+
+	if (priv->has_wep) {
+		range->max_encoding_tokens = ORINOCO_MAX_KEYS;
+		range->encoding_size[0] = SMALL_KEY_SIZE;
+		range->num_encoding_sizes = 1;
+
+		if (priv->has_big_wep) {
+			range->encoding_size[1] = LARGE_KEY_SIZE;
+			range->num_encoding_sizes = 2;
+		}
+	}
+
+	if (priv->has_wpa)
+		range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+
+	if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
+		/* Quality stats meaningless in ad-hoc mode */
+	} else {
+		range->max_qual.qual = 0x8b - 0x2f;
+		range->max_qual.level = 0x2f - 0x95 - 1;
+		range->max_qual.noise = 0x2f - 0x95 - 1;
+		/* Need to get better values */
+		range->avg_qual.qual = 0x24;
+		range->avg_qual.level = 0xC2;
+		range->avg_qual.noise = 0x9E;
+	}
+
+	err = orinoco_hw_get_bitratelist(priv, &numrates,
+					 range->bitrate, IW_MAX_BITRATES);
+	if (err)
+		return err;
+	range->num_bitrates = numrates;
+
+	/* Set an indication of the max TCP throughput in bit/s that we can
+	 * expect using this interface. May be use for QoS stuff...
+	 * Jean II */
+	if (numrates > 2)
+		range->throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
+	else
+		range->throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
+
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+
+	range->min_pmp = 0;
+	range->max_pmp = 65535000;
+	range->min_pmt = 0;
+	range->max_pmt = 65535 * 1000;	/* ??? */
+	range->pmp_flags = IW_POWER_PERIOD;
+	range->pmt_flags = IW_POWER_TIMEOUT;
+	range->pm_capa = (IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+			  IW_POWER_UNICAST_R);
+
+	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->r_time_flags = IW_RETRY_LIFETIME;
+	range->min_retry = 0;
+	range->max_retry = 65535;	/* ??? */
+	range->min_r_time = 0;
+	range->max_r_time = 65535 * 1000;	/* ??? */
+
+	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+		range->scan_capa = IW_SCAN_CAPA_ESSID;
+	else
+		range->scan_capa = IW_SCAN_CAPA_NONE;
+
+	/* Event capability (kernel) */
+	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+	/* Event capability (driver) */
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
+	return 0;
+}
+
+static int orinoco_ioctl_setiwencode(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *erq,
+				     char *keybuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+	int setindex = priv->tx_key;
+	int encode_alg = priv->encode_alg;
+	int restricted = priv->wep_restrict;
+	u16 xlen = 0;
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
+
+	if (!priv->has_wep)
+		return -EOPNOTSUPP;
+
+	if (erq->pointer) {
+		/* We actually have a key to set - check its length */
+		if (erq->length > LARGE_KEY_SIZE)
+			return -E2BIG;
+
+		if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep)
+			return -E2BIG;
+	}
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Clear any TKIP key we have */
+	if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
+		(void) orinoco_clear_tkip_key(priv, setindex);
+
+	if (erq->length > 0) {
+		if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+			index = priv->tx_key;
+
+		/* Adjust key length to a supported value */
+		if (erq->length > SMALL_KEY_SIZE)
+			xlen = LARGE_KEY_SIZE;
+		else if (erq->length > 0)
+			xlen = SMALL_KEY_SIZE;
+		else
+			xlen = 0;
+
+		/* Switch on WEP if off */
+		if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
+			setindex = index;
+			encode_alg = IW_ENCODE_ALG_WEP;
+		}
+	} else {
+		/* Important note : if the user do "iwconfig eth0 enc off",
+		 * we will arrive there with an index of -1. This is valid
+		 * but need to be taken care off... Jean II */
+		if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
+			if ((index != -1) || (erq->flags == 0)) {
+				err = -EINVAL;
+				goto out;
+			}
+		} else {
+			/* Set the index : Check that the key is valid */
+			if (priv->keys[index].len == 0) {
+				err = -EINVAL;
+				goto out;
+			}
+			setindex = index;
+		}
+	}
+
+	if (erq->flags & IW_ENCODE_DISABLED)
+		encode_alg = IW_ENCODE_ALG_NONE;
+	if (erq->flags & IW_ENCODE_OPEN)
+		restricted = 0;
+	if (erq->flags & IW_ENCODE_RESTRICTED)
+		restricted = 1;
+
+	if (erq->pointer && erq->length > 0) {
+		priv->keys[index].len = cpu_to_le16(xlen);
+		memset(priv->keys[index].data, 0,
+		       sizeof(priv->keys[index].data));
+		memcpy(priv->keys[index].data, keybuf, erq->length);
+	}
+	priv->tx_key = setindex;
+
+	/* Try fast key change if connected and only keys are changed */
+	if ((priv->encode_alg == encode_alg) &&
+	    (priv->wep_restrict == restricted) &&
+	    netif_carrier_ok(dev)) {
+		err = __orinoco_hw_setup_wepkeys(priv);
+		/* No need to commit if successful */
+		goto out;
+	}
+
+	priv->encode_alg = encode_alg;
+	priv->wep_restrict = restricted;
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getiwencode(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *erq,
+				     char *keybuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+	u16 xlen = 0;
+	unsigned long flags;
+
+	if (!priv->has_wep)
+		return -EOPNOTSUPP;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+		index = priv->tx_key;
+
+	erq->flags = 0;
+	if (!priv->encode_alg)
+		erq->flags |= IW_ENCODE_DISABLED;
+	erq->flags |= index + 1;
+
+	if (priv->wep_restrict)
+		erq->flags |= IW_ENCODE_RESTRICTED;
+	else
+		erq->flags |= IW_ENCODE_OPEN;
+
+	xlen = le16_to_cpu(priv->keys[index].len);
+
+	erq->length = xlen;
+
+	memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
+	orinoco_unlock(priv, &flags);
+	return 0;
+}
+
+static int orinoco_ioctl_setessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *erq,
+				  char *essidbuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
+	 * anyway... - Jean II */
+
+	/* Hum... Should not use Wireless Extension constant (may change),
+	 * should use our own... - Jean II */
+	if (erq->length > IW_ESSID_MAX_SIZE)
+		return -E2BIG;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
+	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+	/* If not ANY, get the new ESSID */
+	if (erq->flags)
+		memcpy(priv->desired_essid, essidbuf, erq->length);
+
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *erq,
+				  char *essidbuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int active;
+	int err = 0;
+	unsigned long flags;
+
+	if (netif_running(dev)) {
+		err = orinoco_hw_get_essid(priv, &active, essidbuf);
+		if (err < 0)
+			return err;
+		erq->length = err;
+	} else {
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
+		memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+		erq->length = strlen(priv->desired_essid);
+		orinoco_unlock(priv, &flags);
+	}
+
+	erq->flags = 1;
+
+	return 0;
+}
+
+static int orinoco_ioctl_setnick(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *nrq,
+				 char *nickbuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	if (nrq->length > IW_ESSID_MAX_SIZE)
+		return -E2BIG;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	memset(priv->nick, 0, sizeof(priv->nick));
+	memcpy(priv->nick, nickbuf, nrq->length);
+
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getnick(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *nrq,
+				 char *nickbuf)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
+	orinoco_unlock(priv, &flags);
+
+	nrq->length = strlen(priv->nick);
+
+	return 0;
+}
+
+static int orinoco_ioctl_setfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *frq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int chan = -1;
+	unsigned long flags;
+	int err = -EINPROGRESS;		/* Call commit handler */
+
+	/* In infrastructure mode the AP sets the channel */
+	if (priv->iw_mode == IW_MODE_INFRA)
+		return -EBUSY;
+
+	if ((frq->e == 0) && (frq->m <= 1000)) {
+		/* Setting by channel number */
+		chan = frq->m;
+	} else {
+		/* Setting by frequency */
+		int denom = 1;
+		int i;
+
+		/* Calculate denominator to rescale to MHz */
+		for (i = 0; i < (6 - frq->e); i++)
+			denom *= 10;
+
+		chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
+	}
+
+	if ((chan < 1) || (chan > NUM_CHANNELS) ||
+	     !(priv->channel_mask & (1 << (chan-1))))
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	priv->channel = chan;
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		/* Fast channel change - no commit if successful */
+		hermes_t *hw = &priv->hw;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_SET_CHANNEL,
+					chan, NULL);
+	}
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *frq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int tmp;
+
+	/* Locking done in there */
+	tmp = orinoco_hw_get_freq(priv);
+	if (tmp < 0)
+		return tmp;
+
+	frq->m = tmp * 100000;
+	frq->e = 1;
+
+	return 0;
+}
+
+static int orinoco_ioctl_getsens(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *srq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	u16 val;
+	int err;
+	unsigned long flags;
+
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFSYSTEMSCALE, &val);
+	orinoco_unlock(priv, &flags);
+
+	if (err)
+		return err;
+
+	srq->value = val;
+	srq->fixed = 0; /* auto */
+
+	return 0;
+}
+
+static int orinoco_ioctl_setsens(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *srq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int val = srq->value;
+	unsigned long flags;
+
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
+	if ((val < 1) || (val > 3))
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+	priv->ap_density = val;
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_setrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rrq,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int val = rrq->value;
+	unsigned long flags;
+
+	if (rrq->disabled)
+		val = 2347;
+
+	if ((val < 0) || (val > 2347))
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	priv->rts_thresh = val;
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rrq,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	rrq->value = priv->rts_thresh;
+	rrq->disabled = (rrq->value == 2347);
+	rrq->fixed = 1;
+
+	return 0;
+}
+
+static int orinoco_ioctl_setfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (priv->has_mwo) {
+		if (frq->disabled)
+			priv->mwo_robust = 0;
+		else {
+			if (frq->fixed)
+				printk(KERN_WARNING "%s: Fixed fragmentation "
+				       "is not supported on this firmware. "
+				       "Using MWO robust instead.\n",
+				       dev->name);
+			priv->mwo_robust = 1;
+		}
+	} else {
+		if (frq->disabled)
+			priv->frag_thresh = 2346;
+		else {
+			if ((frq->value < 256) || (frq->value > 2346))
+				err = -EINVAL;
+			else
+				/* must be even */
+				priv->frag_thresh = frq->value & ~0x1;
+		}
+	}
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err;
+	u16 val;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (priv->has_mwo) {
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMWOROBUST_AGERE,
+					  &val);
+		if (err)
+			val = 0;
+
+		frq->value = val ? 2347 : 0;
+		frq->disabled = !val;
+		frq->fixed = 0;
+	} else {
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					  &val);
+		if (err)
+			val = 0;
+
+		frq->value = val;
+		frq->disabled = (val >= 2346);
+		frq->fixed = 1;
+	}
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_setrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rrq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int ratemode;
+	int bitrate; /* 100s of kilobits */
+	unsigned long flags;
+
+	/* As the user space doesn't know our highest rate, it uses -1
+	 * to ask us to set the highest rate.  Test it using "iwconfig
+	 * ethX rate auto" - Jean II */
+	if (rrq->value == -1)
+		bitrate = 110;
+	else {
+		if (rrq->value % 100000)
+			return -EINVAL;
+		bitrate = rrq->value / 100000;
+	}
+
+	ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed);
+
+	if (ratemode == -1)
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+	priv->bitratemode = ratemode;
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;
+}
+
+static int orinoco_ioctl_getrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rrq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	int bitrate, automatic;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic);
+
+	/* If the interface is running we try to find more about the
+	   current mode */
+	if (netif_running(dev))
+		err = orinoco_hw_get_act_bitrate(priv, &bitrate);
+
+	orinoco_unlock(priv, &flags);
+
+	rrq->value = bitrate;
+	rrq->fixed = !automatic;
+	rrq->disabled = 0;
+
+	return err;
+}
+
+static int orinoco_ioctl_setpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *prq,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (prq->disabled) {
+		priv->pm_on = 0;
+	} else {
+		switch (prq->flags & IW_POWER_MODE) {
+		case IW_POWER_UNICAST_R:
+			priv->pm_mcast = 0;
+			priv->pm_on = 1;
+			break;
+		case IW_POWER_ALL_R:
+			priv->pm_mcast = 1;
+			priv->pm_on = 1;
+			break;
+		case IW_POWER_ON:
+			/* No flags : but we may have a value - Jean II */
+			break;
+		default:
+			err = -EINVAL;
+			goto out;
+		}
+
+		if (prq->flags & IW_POWER_TIMEOUT) {
+			priv->pm_on = 1;
+			priv->pm_timeout = prq->value / 1000;
+		}
+		if (prq->flags & IW_POWER_PERIOD) {
+			priv->pm_on = 1;
+			priv->pm_period = prq->value / 1000;
+		}
+		/* It's valid to not have a value if we are just toggling
+		 * the flags... Jean II */
+		if (!priv->pm_on) {
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *prq,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	u16 enable, period, timeout, mcast;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFPMENABLED, &enable);
+	if (err)
+		goto out;
+
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFMAXSLEEPDURATION, &period);
+	if (err)
+		goto out;
+
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
+	if (err)
+		goto out;
+
+	err = hermes_read_wordrec(hw, USER_BAP,
+				  HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
+	if (err)
+		goto out;
+
+	prq->disabled = !enable;
+	/* Note : by default, display the period */
+	if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+		prq->flags = IW_POWER_TIMEOUT;
+		prq->value = timeout * 1000;
+	} else {
+		prq->flags = IW_POWER_PERIOD;
+		prq->value = period * 1000;
+	}
+	if (mcast)
+		prq->flags |= IW_POWER_ALL_R;
+	else
+		prq->flags |= IW_POWER_UNICAST_R;
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_set_encodeext(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu,
+				       char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	int idx, alg = ext->alg, set_key = 1;
+	unsigned long flags;
+	int err = -EINVAL;
+	u16 key_len;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Determine and validate the key index */
+	idx = encoding->flags & IW_ENCODE_INDEX;
+	if (idx) {
+		if ((idx < 1) || (idx > 4))
+			goto out;
+		idx--;
+	} else
+		idx = priv->tx_key;
+
+	if (encoding->flags & IW_ENCODE_DISABLED)
+		alg = IW_ENCODE_ALG_NONE;
+
+	if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
+		/* Clear any TKIP TX key we had */
+		(void) orinoco_clear_tkip_key(priv, priv->tx_key);
+	}
+
+	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+		priv->tx_key = idx;
+		set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
+			   (ext->key_len > 0)) ? 1 : 0;
+	}
+
+	if (set_key) {
+		/* Set the requested key first */
+		switch (alg) {
+		case IW_ENCODE_ALG_NONE:
+			priv->encode_alg = alg;
+			priv->keys[idx].len = 0;
+			break;
+
+		case IW_ENCODE_ALG_WEP:
+			if (ext->key_len > SMALL_KEY_SIZE)
+				key_len = LARGE_KEY_SIZE;
+			else if (ext->key_len > 0)
+				key_len = SMALL_KEY_SIZE;
+			else
+				goto out;
+
+			priv->encode_alg = alg;
+			priv->keys[idx].len = cpu_to_le16(key_len);
+
+			key_len = min(ext->key_len, key_len);
+
+			memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
+			memcpy(priv->keys[idx].data, ext->key, key_len);
+			break;
+
+		case IW_ENCODE_ALG_TKIP:
+		{
+			hermes_t *hw = &priv->hw;
+			u8 *tkip_iv = NULL;
+
+			if (!priv->has_wpa ||
+			    (ext->key_len > sizeof(priv->tkip_key[0])))
+				goto out;
+
+			priv->encode_alg = alg;
+			memset(&priv->tkip_key[idx], 0,
+			       sizeof(priv->tkip_key[idx]));
+			memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
+
+			if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+				tkip_iv = &ext->rx_seq[0];
+
+			err = __orinoco_hw_set_tkip_key(hw, idx,
+				 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+				 (u8 *) &priv->tkip_key[idx],
+				 tkip_iv, NULL);
+			if (err)
+				printk(KERN_ERR "%s: Error %d setting TKIP key"
+				       "\n", dev->name, err);
+
+			goto out;
+		}
+		default:
+			goto out;
+		}
+	}
+	err = -EINPROGRESS;
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_get_encodeext(struct net_device *dev,
+				       struct iw_request_info *info,
+				       union iwreq_data *wrqu,
+				       char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	int idx, max_key_len;
+	unsigned long flags;
+	int err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = -EINVAL;
+	max_key_len = encoding->length - sizeof(*ext);
+	if (max_key_len < 0)
+		goto out;
+
+	idx = encoding->flags & IW_ENCODE_INDEX;
+	if (idx) {
+		if ((idx < 1) || (idx > 4))
+			goto out;
+		idx--;
+	} else
+		idx = priv->tx_key;
+
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	ext->alg = priv->encode_alg;
+	switch (priv->encode_alg) {
+	case IW_ENCODE_ALG_NONE:
+		ext->key_len = 0;
+		encoding->flags |= IW_ENCODE_DISABLED;
+		break;
+	case IW_ENCODE_ALG_WEP:
+		ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
+				     max_key_len);
+		memcpy(ext->key, priv->keys[idx].data, ext->key_len);
+		encoding->flags |= IW_ENCODE_ENABLED;
+		break;
+	case IW_ENCODE_ALG_TKIP:
+		ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
+				     max_key_len);
+		memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
+		encoding->flags |= IW_ENCODE_ENABLED;
+		break;
+	}
+
+	err = 0;
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_set_auth(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	struct iw_param *param = &wrqu->param;
+	unsigned long flags;
+	int ret = -EINPROGRESS;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+	case IW_AUTH_PRIVACY_INVOKED:
+	case IW_AUTH_DROP_UNENCRYPTED:
+		/*
+		 * orinoco does not use these parameters
+		 */
+		break;
+
+	case IW_AUTH_KEY_MGMT:
+		/* wl_lkm implies value 2 == PSK for Hermes I
+		 * which ties in with WEXT
+		 * no other hints tho :(
+		 */
+		priv->key_mgmt = param->value;
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		/* When countermeasures are enabled, shut down the
+		 * card; when disabled, re-enable the card. This must
+		 * take effect immediately.
+		 *
+		 * TODO: Make sure that the EAPOL message is getting
+		 *       out before card disabled
+		 */
+		if (param->value) {
+			priv->tkip_cm_active = 1;
+			ret = hermes_enable_port(hw, 0);
+		} else {
+			priv->tkip_cm_active = 0;
+			ret = hermes_disable_port(hw, 0);
+		}
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		if (param->value & IW_AUTH_ALG_SHARED_KEY)
+			priv->wep_restrict = 1;
+		else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+			priv->wep_restrict = 0;
+		else
+			ret = -EINVAL;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		if (priv->has_wpa) {
+			priv->wpa_enabled = param->value ? 1 : 0;
+		} else {
+			if (param->value)
+				ret = -EOPNOTSUPP;
+			/* else silently accept disable of WPA */
+			priv->wpa_enabled = 0;
+		}
+		break;
+
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	orinoco_unlock(priv, &flags);
+	return ret;
+}
+
+static int orinoco_ioctl_get_auth(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct iw_param *param = &wrqu->param;
+	unsigned long flags;
+	int ret = 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_KEY_MGMT:
+		param->value = priv->key_mgmt;
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		param->value = priv->tkip_cm_active;
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		if (priv->wep_restrict)
+			param->value = IW_AUTH_ALG_SHARED_KEY;
+		else
+			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		param->value = priv->wpa_enabled;
+		break;
+
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	orinoco_unlock(priv, &flags);
+	return ret;
+}
+
+static int orinoco_ioctl_set_genie(struct net_device *dev,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	u8 *buf;
+	unsigned long flags;
+
+	/* cut off at IEEE80211_MAX_DATA_LEN */
+	if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
+	    (wrqu->data.length && (extra == NULL)))
+		return -EINVAL;
+
+	if (wrqu->data.length) {
+		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, extra, wrqu->data.length);
+	} else
+		buf = NULL;
+
+	if (orinoco_lock(priv, &flags) != 0) {
+		kfree(buf);
+		return -EBUSY;
+	}
+
+	kfree(priv->wpa_ie);
+	priv->wpa_ie = buf;
+	priv->wpa_ie_len = wrqu->data.length;
+
+	if (priv->wpa_ie) {
+		/* Looks like wl_lkm wants to check the auth alg, and
+		 * somehow pass it to the firmware.
+		 * Instead it just calls the key mgmt rid
+		 *   - we do this in set auth.
+		 */
+	}
+
+	orinoco_unlock(priv, &flags);
+	return 0;
+}
+
+static int orinoco_ioctl_get_genie(struct net_device *dev,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
+		wrqu->data.length = 0;
+		goto out;
+	}
+
+	if (wrqu->data.length < priv->wpa_ie_len) {
+		err = -E2BIG;
+		goto out;
+	}
+
+	wrqu->data.length = priv->wpa_ie_len;
+	memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+static int orinoco_ioctl_set_mlme(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	unsigned long flags;
+	int ret = 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	switch (mlme->cmd) {
+	case IW_MLME_DEAUTH:
+		/* silently ignore */
+		break;
+
+	case IW_MLME_DISASSOC:
+	{
+		struct {
+			u8 addr[ETH_ALEN];
+			__le16 reason_code;
+		} __attribute__ ((packed)) buf;
+
+		memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
+		buf.reason_code = cpu_to_le16(mlme->reason_code);
+		ret = HERMES_WRITE_RECORD(hw, USER_BAP,
+					  HERMES_RID_CNFDISASSOCIATE,
+					  &buf);
+		break;
+	}
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	orinoco_unlock(priv, &flags);
+	return ret;
+}
+
+static int orinoco_ioctl_getretry(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *rrq,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	u16 short_limit, long_limit, lifetime;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
+				  &short_limit);
+	if (err)
+		goto out;
+
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
+				  &long_limit);
+	if (err)
+		goto out;
+
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
+				  &lifetime);
+	if (err)
+		goto out;
+
+	rrq->disabled = 0;		/* Can't be disabled */
+
+	/* Note : by default, display the retry number */
+	if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+		rrq->flags = IW_RETRY_LIFETIME;
+		rrq->value = lifetime * 1000;	/* ??? */
+	} else {
+		/* By default, display the min number */
+		if ((rrq->flags & IW_RETRY_LONG)) {
+			rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+			rrq->value = long_limit;
+		} else {
+			rrq->flags = IW_RETRY_LIMIT;
+			rrq->value = short_limit;
+			if (short_limit != long_limit)
+				rrq->flags |= IW_RETRY_SHORT;
+		}
+	}
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_reset(struct net_device *dev,
+			       struct iw_request_info *info,
+			       void *wrqu,
+			       char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
+		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+
+		/* Firmware reset */
+		orinoco_reset(&priv->reset_work);
+	} else {
+		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
+
+		schedule_work(&priv->reset_work);
+	}
+
+	return 0;
+}
+
+static int orinoco_ioctl_setibssport(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int val = *((int *) extra);
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	priv->ibss_port = val ;
+
+	/* Actually update the mode we are using */
+	set_port_type(priv);
+
+	orinoco_unlock(priv, &flags);
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getibssport(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int *val = (int *) extra;
+
+	*val = priv->ibss_port;
+	return 0;
+}
+
+static int orinoco_ioctl_setport3(struct net_device *dev,
+				  struct iw_request_info *info,
+				  void *wrqu,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int val = *((int *) extra);
+	int err = 0;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	switch (val) {
+	case 0: /* Try to do IEEE ad-hoc mode */
+		if (!priv->has_ibss) {
+			err = -EINVAL;
+			break;
+		}
+		priv->prefer_port3 = 0;
+
+		break;
+
+	case 1: /* Try to do Lucent proprietary ad-hoc mode */
+		if (!priv->has_port3) {
+			err = -EINVAL;
+			break;
+		}
+		priv->prefer_port3 = 1;
+		break;
+
+	default:
+		err = -EINVAL;
+	}
+
+	if (!err) {
+		/* Actually update the mode we are using */
+		set_port_type(priv);
+		err = -EINPROGRESS;
+	}
+
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_getport3(struct net_device *dev,
+				  struct iw_request_info *info,
+				  void *wrqu,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int *val = (int *) extra;
+
+	*val = priv->prefer_port3;
+	return 0;
+}
+
+static int orinoco_ioctl_setpreamble(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	int val;
+
+	if (!priv->has_preamble)
+		return -EOPNOTSUPP;
+
+	/* 802.11b has recently defined some short preamble.
+	 * Basically, the Phy header has been reduced in size.
+	 * This increase performance, especially at high rates
+	 * (the preamble is transmitted at 1Mb/s), unfortunately
+	 * this give compatibility troubles... - Jean II */
+	val = *((int *) extra);
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (val)
+		priv->preamble = 1;
+	else
+		priv->preamble = 0;
+
+	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getpreamble(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int *val = (int *) extra;
+
+	if (!priv->has_preamble)
+		return -EOPNOTSUPP;
+
+	*val = priv->preamble;
+	return 0;
+}
+
+/* ioctl interface to hermes_read_ltv()
+ * To use with iwpriv, pass the RID as the token argument, e.g.
+ * iwpriv get_rid [0xfc00]
+ * At least Wireless Tools 25 is required to use iwpriv.
+ * For Wireless Tools 25 and 26 append "dummy" are the end. */
+static int orinoco_ioctl_getrid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int rid = data->flags;
+	u16 length;
+	int err;
+	unsigned long flags;
+
+	/* It's a "get" function, but we don't want users to access the
+	 * WEP key and other raw firmware data */
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (rid < 0xfc00 || rid > 0xffff)
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
+			      extra);
+	if (err)
+		goto out;
+
+	data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
+			     MAX_RID_LEN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+/* Trigger a scan (look for other cells in the vicinity) */
+static int orinoco_ioctl_setscan(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *srq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	struct iw_scan_req *si = (struct iw_scan_req *) extra;
+	int err = 0;
+	unsigned long flags;
+
+	/* Note : you may have realised that, as this is a SET operation,
+	 * this is privileged and therefore a normal user can't
+	 * perform scanning.
+	 * This is not an error, while the device perform scanning,
+	 * traffic doesn't flow, so it's a perfect DoS...
+	 * Jean II */
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Scanning with port 0 disabled would fail */
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	/* In monitor mode, the scan results are always empty.
+	 * Probe responses are passed to the driver as received
+	 * frames and could be processed in software. */
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Note : because we don't lock out the irq handler, the way
+	 * we access scan variables in priv is critical.
+	 *	o scan_inprogress : not touched by irq handler
+	 *	o scan_mode : not touched by irq handler
+	 * Before modifying anything on those variables, please think hard !
+	 * Jean II */
+
+	/* Save flags */
+	priv->scan_mode = srq->flags;
+
+	/* Always trigger scanning, even if it's in progress.
+	 * This way, if the info frame get lost, we will recover somewhat
+	 * gracefully  - Jean II */
+
+	if (priv->has_hostscan) {
+		switch (priv->firmware_type) {
+		case FIRMWARE_TYPE_SYMBOL:
+			err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFHOSTSCAN_SYMBOL,
+						HERMES_HOSTSCAN_SYMBOL_ONCE |
+						HERMES_HOSTSCAN_SYMBOL_BCAST);
+			break;
+		case FIRMWARE_TYPE_INTERSIL: {
+			__le16 req[3];
+
+			req[0] = cpu_to_le16(0x3fff);	/* All channels */
+			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
+			req[2] = 0;			/* Any ESSID */
+			err = HERMES_WRITE_RECORD(hw, USER_BAP,
+						  HERMES_RID_CNFHOSTSCAN, &req);
+		}
+		break;
+		case FIRMWARE_TYPE_AGERE:
+			if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
+				struct hermes_idstring idbuf;
+				size_t len = min(sizeof(idbuf.val),
+						 (size_t) si->essid_len);
+				idbuf.len = cpu_to_le16(len);
+				memcpy(idbuf.val, si->essid, len);
+
+				err = hermes_write_ltv(hw, USER_BAP,
+					       HERMES_RID_CNFSCANSSID_AGERE,
+					       HERMES_BYTES_TO_RECLEN(len + 2),
+					       &idbuf);
+			} else
+				err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFSCANSSID_AGERE,
+						   0);	/* Any ESSID */
+			if (err)
+				break;
+
+			if (priv->has_ext_scan) {
+				/* Clear scan results at the start of
+				 * an extended scan */
+				orinoco_clear_scan_results(priv,
+						msecs_to_jiffies(15000));
+
+				/* TODO: Is this available on older firmware?
+				 *   Can we use it to scan specific channels
+				 *   for IW_SCAN_THIS_FREQ? */
+				err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFSCANCHANNELS2GHZ,
+						0x7FFF);
+				if (err)
+					goto out;
+
+				err = hermes_inquire(hw,
+						     HERMES_INQ_CHANNELINFO);
+			} else
+				err = hermes_inquire(hw, HERMES_INQ_SCAN);
+			break;
+		}
+	} else
+		err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+	/* One more client */
+	if (!err)
+		priv->scan_inprogress = 1;
+
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+#define MAX_CUSTOM_LEN 64
+
+/* Translate scan data returned from the card to a card independant
+ * format that the Wireless Tools will understand - Jean II */
+static inline char *orinoco_translate_scan(struct net_device *dev,
+					   struct iw_request_info *info,
+					   char *current_ev,
+					   char *end_buf,
+					   union hermes_scan_info *bss,
+					   unsigned long last_scanned)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	u16			capabilities;
+	u16			channel;
+	struct iw_event		iwe;		/* Temporary buffer */
+	char custom[MAX_CUSTOM_LEN];
+
+	memset(&iwe, 0, sizeof(iwe));
+
+	/* First entry *MUST* be the AP MAC address */
+	iwe.cmd = SIOCGIWAP;
+	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
+	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+					  &iwe, IW_EV_ADDR_LEN);
+
+	/* Other entries will be displayed in the order we give them */
+
+	/* Add the ESSID */
+	iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
+	if (iwe.u.data.length > 32)
+		iwe.u.data.length = 32;
+	iwe.cmd = SIOCGIWESSID;
+	iwe.u.data.flags = 1;
+	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+					  &iwe, bss->a.essid);
+
+	/* Add mode */
+	iwe.cmd = SIOCGIWMODE;
+	capabilities = le16_to_cpu(bss->a.capabilities);
+	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+		if (capabilities & WLAN_CAPABILITY_ESS)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_UINT_LEN);
+	}
+
+	channel = bss->s.channel;
+	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+		/* Add channel and frequency */
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.u.freq.m = channel;
+		iwe.u.freq.e = 0;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_FREQ_LEN);
+
+		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+		iwe.u.freq.e = 1;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_FREQ_LEN);
+	}
+
+	/* Add quality statistics. level and noise in dB. No link quality */
+	iwe.cmd = IWEVQUAL;
+	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+	iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
+	iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
+	/* Wireless tools prior to 27.pre22 will show link quality
+	 * anyway, so we provide a reasonable value. */
+	if (iwe.u.qual.level > iwe.u.qual.noise)
+		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+	else
+		iwe.u.qual.qual = 0;
+	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+					  &iwe, IW_EV_QUAL_LEN);
+
+	/* Add encryption capability */
+	iwe.cmd = SIOCGIWENCODE;
+	if (capabilities & WLAN_CAPABILITY_PRIVACY)
+		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+	else
+		iwe.u.data.flags = IW_ENCODE_DISABLED;
+	iwe.u.data.length = 0;
+	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+					  &iwe, NULL);
+
+	/* Bit rate is not available in Lucent/Agere firmwares */
+	if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+		char *current_val = current_ev + iwe_stream_lcp_len(info);
+		int i;
+		int step;
+
+		if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+			step = 2;
+		else
+			step = 1;
+
+		iwe.cmd = SIOCGIWRATE;
+		/* Those two flags are ignored... */
+		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+		/* Max 10 values */
+		for (i = 0; i < 10; i += step) {
+			/* NULL terminated */
+			if (bss->p.rates[i] == 0x0)
+				break;
+			/* Bit rate given in 500 kb/s units (+ 0x80) */
+			iwe.u.bitrate.value =
+				((bss->p.rates[i] & 0x7f) * 500000);
+			current_val = iwe_stream_add_value(info, current_ev,
+							   current_val,
+							   end_buf, &iwe,
+							   IW_EV_PARAM_LEN);
+		}
+		/* Check if we added any event */
+		if ((current_val - current_ev) > iwe_stream_lcp_len(info))
+			current_ev = current_val;
+	}
+
+	/* Beacon interval */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     "bcn_int=%d",
+				     le16_to_cpu(bss->a.beacon_interv));
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	/* Capabilites */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     "capab=0x%04x",
+				     capabilities);
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	/* Add EXTRA: Age to display seconds since last beacon/probe response
+	 * for given network. */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     " Last beacon: %dms ago",
+				     jiffies_to_msecs(jiffies - last_scanned));
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	return current_ev;
+}
+
+static inline char *orinoco_translate_ext_scan(struct net_device *dev,
+					       struct iw_request_info *info,
+					       char *current_ev,
+					       char *end_buf,
+					       struct agere_ext_scan_info *bss,
+					       unsigned long last_scanned)
+{
+	u16			capabilities;
+	u16			channel;
+	struct iw_event		iwe;		/* Temporary buffer */
+	char custom[MAX_CUSTOM_LEN];
+	u8 *ie;
+
+	memset(&iwe, 0, sizeof(iwe));
+
+	/* First entry *MUST* be the AP MAC address */
+	iwe.cmd = SIOCGIWAP;
+	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
+	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+					  &iwe, IW_EV_ADDR_LEN);
+
+	/* Other entries will be displayed in the order we give them */
+
+	/* Add the ESSID */
+	ie = bss->data;
+	iwe.u.data.length = ie[1];
+	if (iwe.u.data.length) {
+		if (iwe.u.data.length > 32)
+			iwe.u.data.length = 32;
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.flags = 1;
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, &ie[2]);
+	}
+
+	/* Add mode */
+	capabilities = le16_to_cpu(bss->capabilities);
+	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+		iwe.cmd = SIOCGIWMODE;
+		if (capabilities & WLAN_CAPABILITY_ESS)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_UINT_LEN);
+	}
+
+	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
+	channel = ie ? ie[2] : 0;
+	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+		/* Add channel and frequency */
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.u.freq.m = channel;
+		iwe.u.freq.e = 0;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_FREQ_LEN);
+
+		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+		iwe.u.freq.e = 1;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+						  &iwe, IW_EV_FREQ_LEN);
+	}
+
+	/* Add quality statistics. level and noise in dB. No link quality */
+	iwe.cmd = IWEVQUAL;
+	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+	iwe.u.qual.level = bss->level - 0x95;
+	iwe.u.qual.noise = bss->noise - 0x95;
+	/* Wireless tools prior to 27.pre22 will show link quality
+	 * anyway, so we provide a reasonable value. */
+	if (iwe.u.qual.level > iwe.u.qual.noise)
+		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+	else
+		iwe.u.qual.qual = 0;
+	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+					  &iwe, IW_EV_QUAL_LEN);
+
+	/* Add encryption capability */
+	iwe.cmd = SIOCGIWENCODE;
+	if (capabilities & WLAN_CAPABILITY_PRIVACY)
+		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+	else
+		iwe.u.data.flags = IW_ENCODE_DISABLED;
+	iwe.u.data.length = 0;
+	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+					  &iwe, NULL);
+
+	/* WPA IE */
+	ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
+	if (ie) {
+		iwe.cmd = IWEVGENIE;
+		iwe.u.data.length = ie[1] + 2;
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, ie);
+	}
+
+	/* RSN IE */
+	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
+	if (ie) {
+		iwe.cmd = IWEVGENIE;
+		iwe.u.data.length = ie[1] + 2;
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, ie);
+	}
+
+	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
+	if (ie) {
+		char *p = current_ev + iwe_stream_lcp_len(info);
+		int i;
+
+		iwe.cmd = SIOCGIWRATE;
+		/* Those two flags are ignored... */
+		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+		for (i = 2; i < (ie[1] + 2); i++) {
+			iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
+			p = iwe_stream_add_value(info, current_ev, p, end_buf,
+						 &iwe, IW_EV_PARAM_LEN);
+		}
+		/* Check if we added any event */
+		if (p > (current_ev + iwe_stream_lcp_len(info)))
+			current_ev = p;
+	}
+
+	/* Timestamp */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length =
+		snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
+			 (unsigned long long) le64_to_cpu(bss->timestamp));
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	/* Beacon interval */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     "bcn_int=%d",
+				     le16_to_cpu(bss->beacon_interval));
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	/* Capabilites */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     "capab=0x%04x",
+				     capabilities);
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	/* Add EXTRA: Age to display seconds since last beacon/probe response
+	 * for given network. */
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+				     " Last beacon: %dms ago",
+				     jiffies_to_msecs(jiffies - last_scanned));
+	if (iwe.u.data.length)
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+						  &iwe, custom);
+
+	return current_ev;
+}
+
+/* Return results of a scan */
+static int orinoco_ioctl_getscan(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *srq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	unsigned long flags;
+	char *current_ev = extra;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	if (priv->scan_inprogress) {
+		/* Important note : we don't want to block the caller
+		 * until results are ready for various reasons.
+		 * First, managing wait queues is complex and racy.
+		 * Second, we grab some rtnetlink lock before comming
+		 * here (in dev_ioctl()).
+		 * Third, we generate an Wireless Event, so the
+		 * caller can wait itself on that - Jean II */
+		err = -EAGAIN;
+		goto out;
+	}
+
+	if (priv->has_ext_scan) {
+		struct xbss_element *bss;
+
+		list_for_each_entry(bss, &priv->bss_list, list) {
+			/* Translate this entry to WE format */
+			current_ev =
+				orinoco_translate_ext_scan(dev, info,
+							   current_ev,
+							   extra + srq->length,
+							   &bss->bss,
+							   bss->last_scanned);
+
+			/* Check if there is space for one more entry */
+			if ((extra + srq->length - current_ev)
+			    <= IW_EV_ADDR_LEN) {
+				/* Ask user space to try again with a
+				 * bigger buffer */
+				err = -E2BIG;
+				goto out;
+			}
+		}
+
+	} else {
+		struct bss_element *bss;
+
+		list_for_each_entry(bss, &priv->bss_list, list) {
+			/* Translate this entry to WE format */
+			current_ev = orinoco_translate_scan(dev, info,
+							    current_ev,
+							    extra + srq->length,
+							    &bss->bss,
+							    bss->last_scanned);
+
+			/* Check if there is space for one more entry */
+			if ((extra + srq->length - current_ev)
+			    <= IW_EV_ADDR_LEN) {
+				/* Ask user space to try again with a
+				 * bigger buffer */
+				err = -E2BIG;
+				goto out;
+			}
+		}
+	}
+
+	srq->length = (current_ev - extra);
+	srq->flags = (__u16) priv->scan_mode;
+
+out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+/* Commit handler, called after set operations */
+static int orinoco_ioctl_commit(struct net_device *dev,
+				struct iw_request_info *info,
+				void *wrqu,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	unsigned long flags;
+	int err = 0;
+
+	if (!priv->open)
+		return 0;
+
+	if (priv->broken_disableport) {
+		orinoco_reset(&priv->reset_work);
+		return 0;
+	}
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return err;
+
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to disable port "
+		       "while reconfiguring card\n", dev->name);
+		priv->broken_disableport = 1;
+		goto out;
+	}
+
+	err = __orinoco_program_rids(dev);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+		       dev->name);
+		goto out;
+	}
+
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+		       dev->name);
+		goto out;
+	}
+
+ out:
+	if (err) {
+		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+		schedule_work(&priv->reset_work);
+		err = 0;
+	}
+
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+static const struct iw_priv_args orinoco_privtab[] = {
+	{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
+	{ SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
+	{ SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_port3" },
+	{ SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_port3" },
+	{ SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_preamble" },
+	{ SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_preamble" },
+	{ SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_ibssport" },
+	{ SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_ibssport" },
+	{ SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
+	  "get_rid" },
+};
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+#define STD_IW_HANDLER(id, func) \
+	[IW_IOCTL_IDX(id)] = (iw_handler) func
+static const iw_handler	orinoco_handler[] = {
+	STD_IW_HANDLER(SIOCSIWCOMMIT,	orinoco_ioctl_commit),
+	STD_IW_HANDLER(SIOCGIWNAME,	orinoco_ioctl_getname),
+	STD_IW_HANDLER(SIOCSIWFREQ,	orinoco_ioctl_setfreq),
+	STD_IW_HANDLER(SIOCGIWFREQ,	orinoco_ioctl_getfreq),
+	STD_IW_HANDLER(SIOCSIWMODE,	orinoco_ioctl_setmode),
+	STD_IW_HANDLER(SIOCGIWMODE,	orinoco_ioctl_getmode),
+	STD_IW_HANDLER(SIOCSIWSENS,	orinoco_ioctl_setsens),
+	STD_IW_HANDLER(SIOCGIWSENS,	orinoco_ioctl_getsens),
+	STD_IW_HANDLER(SIOCGIWRANGE,	orinoco_ioctl_getiwrange),
+	STD_IW_HANDLER(SIOCSIWSPY,	iw_handler_set_spy),
+	STD_IW_HANDLER(SIOCGIWSPY,	iw_handler_get_spy),
+	STD_IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
+	STD_IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
+	STD_IW_HANDLER(SIOCSIWAP,	orinoco_ioctl_setwap),
+	STD_IW_HANDLER(SIOCGIWAP,	orinoco_ioctl_getwap),
+	STD_IW_HANDLER(SIOCSIWSCAN,	orinoco_ioctl_setscan),
+	STD_IW_HANDLER(SIOCGIWSCAN,	orinoco_ioctl_getscan),
+	STD_IW_HANDLER(SIOCSIWESSID,	orinoco_ioctl_setessid),
+	STD_IW_HANDLER(SIOCGIWESSID,	orinoco_ioctl_getessid),
+	STD_IW_HANDLER(SIOCSIWNICKN,	orinoco_ioctl_setnick),
+	STD_IW_HANDLER(SIOCGIWNICKN,	orinoco_ioctl_getnick),
+	STD_IW_HANDLER(SIOCSIWRATE,	orinoco_ioctl_setrate),
+	STD_IW_HANDLER(SIOCGIWRATE,	orinoco_ioctl_getrate),
+	STD_IW_HANDLER(SIOCSIWRTS,	orinoco_ioctl_setrts),
+	STD_IW_HANDLER(SIOCGIWRTS,	orinoco_ioctl_getrts),
+	STD_IW_HANDLER(SIOCSIWFRAG,	orinoco_ioctl_setfrag),
+	STD_IW_HANDLER(SIOCGIWFRAG,	orinoco_ioctl_getfrag),
+	STD_IW_HANDLER(SIOCGIWRETRY,	orinoco_ioctl_getretry),
+	STD_IW_HANDLER(SIOCSIWENCODE,	orinoco_ioctl_setiwencode),
+	STD_IW_HANDLER(SIOCGIWENCODE,	orinoco_ioctl_getiwencode),
+	STD_IW_HANDLER(SIOCSIWPOWER,	orinoco_ioctl_setpower),
+	STD_IW_HANDLER(SIOCGIWPOWER,	orinoco_ioctl_getpower),
+	STD_IW_HANDLER(SIOCSIWGENIE,	orinoco_ioctl_set_genie),
+	STD_IW_HANDLER(SIOCGIWGENIE,	orinoco_ioctl_get_genie),
+	STD_IW_HANDLER(SIOCSIWMLME,	orinoco_ioctl_set_mlme),
+	STD_IW_HANDLER(SIOCSIWAUTH,	orinoco_ioctl_set_auth),
+	STD_IW_HANDLER(SIOCGIWAUTH,	orinoco_ioctl_get_auth),
+	STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
+	STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
+};
+
+
+/*
+  Added typecasting since we no longer use iwreq_data -- Moustafa
+ */
+static const iw_handler	orinoco_private_handler[] = {
+	[0] = (iw_handler) orinoco_ioctl_reset,
+	[1] = (iw_handler) orinoco_ioctl_reset,
+	[2] = (iw_handler) orinoco_ioctl_setport3,
+	[3] = (iw_handler) orinoco_ioctl_getport3,
+	[4] = (iw_handler) orinoco_ioctl_setpreamble,
+	[5] = (iw_handler) orinoco_ioctl_getpreamble,
+	[6] = (iw_handler) orinoco_ioctl_setibssport,
+	[7] = (iw_handler) orinoco_ioctl_getibssport,
+	[9] = (iw_handler) orinoco_ioctl_getrid,
+};
+
+const struct iw_handler_def orinoco_handler_def = {
+	.num_standard = ARRAY_SIZE(orinoco_handler),
+	.num_private = ARRAY_SIZE(orinoco_private_handler),
+	.num_private_args = ARRAY_SIZE(orinoco_privtab),
+	.standard = orinoco_handler,
+	.private = orinoco_private_handler,
+	.private_args = orinoco_privtab,
+	.get_wireless_stats = orinoco_get_wireless_stats,
+};
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/wext.h linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/wext.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/orinoco/wext.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/wext.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,13 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_WEXT_H_
+#define _ORINOCO_WEXT_H_
+
+#include <net/iw_handler.h>
+
+/* Structure defining all our WEXT handlers */
+extern const struct iw_handler_def orinoco_handler_def;
+
+#endif /* _ORINOCO_WEXT_H_ */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -1,9 +1,10 @@
 config P54_COMMON
 	tristate "Softmac Prism54 support"
-	depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL
+	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+	select FW_LOADER
 	---help---
-	  This is common code for isl38xx based cards.
-	  This module does nothing by itself - the USB/PCI frontends
+	  This is common code for isl38xx/stlc45xx based modules.
+	  This module does nothing by itself - the USB/PCI/SPI front-ends
 	  also need to be enabled in order to support any devices.
 
 	  These devices require softmac firmware which can be found at
@@ -17,31 +18,6 @@ config P54_USB
 	select CRC32
 	---help---
 	  This driver is for USB isl38xx based wireless cards.
-	  These are USB based adapters found in devices such as:
-
-	  3COM 3CRWE254G72
-	  SMC 2862W-G
-	  Accton 802.11g WN4501 USB
-	  Siemens Gigaset USB
-	  Netgear WG121
-	  Netgear WG111
-	  Medion 40900, Roper Europe
-	  Shuttle PN15, Airvast WM168g, IOGear GWU513
-	  Linksys WUSB54G
-	  Linksys WUSB54G Portable
-	  DLink DWL-G120 Spinnaker
-	  DLink DWL-G122
-	  Belkin F5D7050 ver 1000
-	  Cohiba Proto board
-	  SMC 2862W-G version 2
-	  U.S. Robotics U5 802.11g Adapter
-	  FUJITSU E-5400 USB D1700
-	  Sagem XG703A
-	  DLink DWL-G120 Cohiba
-	  Spinnaker Proto board
-	  Linksys WUSB54AG
-	  Inventel UR054G
-	  Spinnaker DUT
 
 	  These devices require softmac firmware which can be found at
 	  http://prism54.org/
@@ -61,3 +37,18 @@ config P54_PCI
 	  http://prism54.org/
 
 	  If you choose to build a module, it'll be called p54pci.
+
+config P54_SPI
+	tristate "Prism54 SPI (stlc45xx) support"
+	depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS
+	---help---
+	  This driver is for stlc4550 or stlc4560 based wireless chips.
+	  This driver is experimental, untested and will probably only work on
+	  Nokia's N800/N810 Portable Internet Tablet.
+
+	  If you choose to build a module, it'll be called p54spi.
+
+config P54_LEDS
+	bool
+	depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
+	default y
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -1,3 +1,4 @@
 obj-$(CONFIG_P54_COMMON)	+= p54common.o
 obj-$(CONFIG_P54_USB)		+= p54usb.o
 obj-$(CONFIG_P54_PCI)		+= p54pci.o
+obj-$(CONFIG_P54_SPI)		+= p54spi.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54common.c linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54common.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54common.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,9 @@
 #include <linux/etherdevice.h>
 
 #include <net/mac80211.h>
+#ifdef CONFIG_P54_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_P54_LEDS */
 
 #include "p54.h"
 #include "p54common.h"
@@ -239,11 +242,11 @@ int p54_parse_firmware(struct ieee80211_
 
 	if (priv->fw_var >= 0x300) {
 		/* Firmware supports QoS, use it! */
-		priv->tx_stats[4].limit = 3;		/* AC_VO */
-		priv->tx_stats[5].limit = 4;		/* AC_VI */
-		priv->tx_stats[6].limit = 3;		/* AC_BE */
-		priv->tx_stats[7].limit = 2;		/* AC_BK */
-		dev->queues = 4;
+		priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
+		priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
+		priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
+		priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
+		dev->queues = P54_QUEUE_AC_NUM;
 	}
 
 	if (!modparam_nohwcrypt)
@@ -272,13 +275,19 @@ static int p54_convert_rev0(struct ieee8
 	unsigned int i, j;
 	void *source, *target;
 
-	priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+	priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
+				   GFP_KERNEL);
 	if (!priv->curve_data)
 		return -ENOMEM;
 
-	memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+	priv->curve_data->entries = curve_data->channels;
+	priv->curve_data->entry_size = sizeof(__le16) +
+		sizeof(*dst) * curve_data->points_per_channel;
+	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+	priv->curve_data->len = cd_len;
+	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
 	source = curve_data->data;
-	target = priv->curve_data->data;
+	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
 	for (i = 0; i < curve_data->channels; i++) {
 		__le16 *freq = source;
 		source += sizeof(__le16);
@@ -318,13 +327,19 @@ static int p54_convert_rev1(struct ieee8
 	unsigned int i, j;
 	void *source, *target;
 
-	priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+	priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
+				   GFP_KERNEL);
 	if (!priv->curve_data)
 		return -ENOMEM;
 
-	memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+	priv->curve_data->entries = curve_data->channels;
+	priv->curve_data->entry_size = sizeof(__le16) +
+		sizeof(*dst) * curve_data->points_per_channel;
+	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+	priv->curve_data->len = cd_len;
+	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
 	source = curve_data->data;
-	target = priv->curve_data->data;
+	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
 	for (i = 0; i < curve_data->channels; i++) {
 		__le16 *freq = source;
 		source += sizeof(__le16);
@@ -376,7 +391,102 @@ static void p54_parse_rssical(struct iee
 	}
 }
 
-static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
+static void p54_parse_default_country(struct ieee80211_hw *dev,
+				      void *data, int len)
+{
+	struct pda_country *country;
+
+	if (len != sizeof(*country)) {
+		printk(KERN_ERR "%s: found possible invalid default country "
+				"eeprom entry. (entry size: %d)\n",
+		       wiphy_name(dev->wiphy), len);
+
+		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
+				     data, len);
+
+		printk(KERN_ERR "%s: please report this issue.\n",
+			wiphy_name(dev->wiphy));
+		return;
+	}
+
+	country = (struct pda_country *) data;
+	if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
+		regulatory_hint(dev->wiphy, country->alpha2);
+	else {
+		/* TODO:
+		 * write a shared/common function that converts
+		 * "Regulatory domain codes" (802.11-2007 14.8.2.2)
+		 * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
+		 */
+	}
+}
+
+static int p54_convert_output_limits(struct ieee80211_hw *dev,
+				     u8 *data, size_t len)
+{
+	struct p54_common *priv = dev->priv;
+
+	if (len < 2)
+		return -EINVAL;
+
+	if (data[0] != 0) {
+		printk(KERN_ERR "%s: unknown output power db revision:%x\n",
+		       wiphy_name(dev->wiphy), data[0]);
+		return -EINVAL;
+	}
+
+	if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
+		return -EINVAL;
+
+	priv->output_limit = kmalloc(data[1] *
+		sizeof(struct pda_channel_output_limit) +
+		sizeof(*priv->output_limit), GFP_KERNEL);
+
+	if (!priv->output_limit)
+		return -ENOMEM;
+
+	priv->output_limit->offset = 0;
+	priv->output_limit->entries = data[1];
+	priv->output_limit->entry_size =
+		sizeof(struct pda_channel_output_limit);
+	priv->output_limit->len = priv->output_limit->entry_size *
+				  priv->output_limit->entries +
+				  priv->output_limit->offset;
+
+	memcpy(priv->output_limit->data, &data[2],
+	       data[1] * sizeof(struct pda_channel_output_limit));
+
+	return 0;
+}
+
+static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
+					       size_t total_len)
+{
+	struct p54_cal_database *dst;
+	size_t payload_len, entries, entry_size, offset;
+
+	payload_len = le16_to_cpu(src->len);
+	entries = le16_to_cpu(src->entries);
+	entry_size = le16_to_cpu(src->entry_size);
+	offset = le16_to_cpu(src->offset);
+	if (((entries * entry_size + offset) != payload_len) ||
+	     (payload_len + sizeof(*src) != total_len))
+		return NULL;
+
+	dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
+	if (!dst)
+		return NULL;
+
+	dst->entries = entries;
+	dst->entry_size = entry_size;
+	dst->offset = offset;
+	dst->len = payload_len;
+
+	memcpy(dst->data, src->data, payload_len);
+	return dst;
+}
+
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 {
 	struct p54_common *priv = dev->priv;
 	struct eeprom_pda_wrap *wrap = NULL;
@@ -401,30 +511,17 @@ static int p54_parse_eeprom(struct ieee8
 
 		switch (le16_to_cpu(entry->code)) {
 		case PDR_MAC_ADDRESS:
+			if (data_len != ETH_ALEN)
+				break;
 			SET_IEEE80211_PERM_ADDR(dev, entry->data);
 			break;
 		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
-			if (data_len < 2) {
-				err = -EINVAL;
-				goto err;
-			}
-
-			if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) {
-				err = -EINVAL;
-				goto err;
-			}
-
-			priv->output_limit = kmalloc(entry->data[1] *
-				sizeof(*priv->output_limit), GFP_KERNEL);
-
-			if (!priv->output_limit) {
-				err = -ENOMEM;
+			if (priv->output_limit)
+				break;
+			err = p54_convert_output_limits(dev, entry->data,
+							data_len);
+			if (err)
 				goto err;
-			}
-
-			memcpy(priv->output_limit, &entry->data[2],
-			       entry->data[1]*sizeof(*priv->output_limit));
-			priv->output_limit_len = entry->data[1];
 			break;
 		case PDR_PRISM_PA_CAL_CURVE_DATA: {
 			struct pda_pa_curve_data *curve_data =
@@ -463,6 +560,9 @@ static int p54_parse_eeprom(struct ieee8
 			memcpy(priv->iq_autocal, entry->data, data_len);
 			priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
 			break;
+		case PDR_DEFAULT_COUNTRY:
+			p54_parse_default_country(dev, entry->data, data_len);
+			break;
 		case PDR_INTERFACE_LIST:
 			tmp = entry->data;
 			while ((u8 *)tmp < entry->data + data_len) {
@@ -473,6 +573,8 @@ static int p54_parse_eeprom(struct ieee8
 			}
 			break;
 		case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
+			if (data_len < 2)
+				break;
 			priv->version = *(u8 *)(entry->data + 1);
 			break;
 		case PDR_RSSI_LINEAR_APPROXIMATION:
@@ -481,6 +583,34 @@ static int p54_parse_eeprom(struct ieee8
 			p54_parse_rssical(dev, entry->data, data_len,
 					  le16_to_cpu(entry->code));
 			break;
+		case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
+			__le16 *src = (void *) entry->data;
+			s16 *dst = (void *) &priv->rssical_db;
+			int i;
+
+			if (data_len != sizeof(priv->rssical_db)) {
+				err = -EINVAL;
+				goto err;
+			}
+			for (i = 0; i < sizeof(priv->rssical_db) /
+					sizeof(*src); i++)
+				*(dst++) = (s16) le16_to_cpu(*(src++));
+			}
+			break;
+		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
+			struct pda_custom_wrapper *pda = (void *) entry->data;
+			if (priv->output_limit || data_len < sizeof(*pda))
+				break;
+			priv->output_limit = p54_convert_db(pda, data_len);
+			}
+			break;
+		case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
+			struct pda_custom_wrapper *pda = (void *) entry->data;
+			if (priv->curve_data || data_len < sizeof(*pda))
+				break;
+			priv->curve_data = p54_convert_db(pda, data_len);
+			}
+			break;
 		case PDR_END:
 			/* make it overrun */
 			entry_len = len;
@@ -497,7 +627,6 @@ static int p54_parse_eeprom(struct ieee8
 		case PDR_UTF8_OEM_NAME:
 		case PDR_UTF8_PRODUCT_NAME:
 		case PDR_COUNTRY_LIST:
-		case PDR_DEFAULT_COUNTRY:
 		case PDR_ANTENNA_GAIN:
 		case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
 		case PDR_REGULATORY_POWER_LIMITS:
@@ -525,12 +654,16 @@ static int p54_parse_eeprom(struct ieee8
 	}
 
 	priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
-	if (priv->rxhw == 4)
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
 		p54_init_xbow_synth(dev);
 	if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
 		dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
 	if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
 		dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
+	if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
+		priv->rx_diversity_mask = 3;
+	if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
+		priv->tx_diversity_mask = 3;
 
 	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
 		u8 perm_addr[ETH_ALEN];
@@ -568,13 +701,21 @@ static int p54_parse_eeprom(struct ieee8
 		wiphy_name(dev->wiphy));
 	return err;
 }
+EXPORT_SYMBOL_GPL(p54_parse_eeprom);
 
 static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
 {
 	struct p54_common *priv = dev->priv;
 	int band = dev->conf.channel->band;
 
-	return ((rssi * priv->rssical_db[band].mul) / 64 +
+	if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW)
+		return ((rssi * priv->rssical_db[band].mul) / 64 +
+			 priv->rssical_db[band].add) / 4;
+	else
+		/*
+		 * TODO: find the correct formula
+		 */
+		return ((rssi * priv->rssical_db[band].mul) / 64 +
 			 priv->rssical_db[band].add) / 4;
 }
 
@@ -597,10 +738,7 @@ static int p54_rx_data(struct ieee80211_
 		return 0;
 
 	if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
-		if (priv->filter_flags & FIF_FCSFAIL)
-			rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
-		else
-			return 0;
+		return 0;
 	}
 
 	if (hdr->decrypt_status == P54_DECRYPT_OK)
@@ -655,7 +793,8 @@ static void inline p54_wake_free_queues(
 		return ;
 
 	for (i = 0; i < dev->queues; i++)
-		if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
+		if (priv->tx_stats[i + P54_QUEUE_DATA].len <
+		    priv->tx_stats[i + P54_QUEUE_DATA].limit)
 			ieee80211_wake_queue(dev, i);
 }
 
@@ -663,7 +802,7 @@ void p54_free_skb(struct ieee80211_hw *d
 {
 	struct p54_common *priv = dev->priv;
 	struct ieee80211_tx_info *info;
-	struct memrecord *range;
+	struct p54_tx_info *range;
 	unsigned long flags;
 	u32 freed = 0, last_addr = priv->rx_start;
 
@@ -681,18 +820,18 @@ void p54_free_skb(struct ieee80211_hw *d
 	range = (void *)info->rate_driver_data;
 	if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
 		struct ieee80211_tx_info *ni;
-		struct memrecord *mr;
+		struct p54_tx_info *mr;
 
 		ni = IEEE80211_SKB_CB(skb->prev);
-		mr = (struct memrecord *)ni->rate_driver_data;
+		mr = (struct p54_tx_info *)ni->rate_driver_data;
 		last_addr = mr->end_addr;
 	}
 	if (skb->next != (struct sk_buff *)&priv->tx_queue) {
 		struct ieee80211_tx_info *ni;
-		struct memrecord *mr;
+		struct p54_tx_info *mr;
 
 		ni = IEEE80211_SKB_CB(skb->next);
-		mr = (struct memrecord *)ni->rate_driver_data;
+		mr = (struct p54_tx_info *)ni->rate_driver_data;
 		freed = mr->start_addr - last_addr;
 	} else
 		freed = priv->rx_end - last_addr;
@@ -735,7 +874,7 @@ static void p54_rx_frame_sent(struct iee
 	struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
 	struct sk_buff *entry;
 	u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
-	struct memrecord *range = NULL;
+	struct p54_tx_info *range = NULL;
 	u32 freed = 0;
 	u32 last_addr = priv->rx_start;
 	unsigned long flags;
@@ -758,10 +897,10 @@ static void p54_rx_frame_sent(struct iee
 
 		if (entry->next != (struct sk_buff *)&priv->tx_queue) {
 			struct ieee80211_tx_info *ni;
-			struct memrecord *mr;
+			struct p54_tx_info *mr;
 
 			ni = IEEE80211_SKB_CB(entry->next);
-			mr = (struct memrecord *)ni->rate_driver_data;
+			mr = (struct p54_tx_info *)ni->rate_driver_data;
 			freed = mr->start_addr - last_addr;
 		} else
 			freed = priv->rx_end - last_addr;
@@ -776,9 +915,16 @@ static void p54_rx_frame_sent(struct iee
 		priv->tx_stats[entry_data->hw_queue].len--;
 		priv->stats.dot11ACKFailureCount += payload->tries - 1;
 
-		if (unlikely(entry == priv->cached_beacon)) {
+		/*
+		 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
+		 * generated by the driver. Therefore tx_status is bogus
+		 * and we don't want to confuse the mac80211 stack.
+		 */
+		if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
+			if (entry_data->hw_queue == P54_QUEUE_BEACON)
+				priv->cached_beacon = NULL;
+
 			kfree_skb(entry);
-			priv->cached_beacon = NULL;
 			goto out;
 		}
 
@@ -971,8 +1117,8 @@ EXPORT_SYMBOL_GPL(p54_rx);
  * can find some unused memory to upload our packets to. However, data that we
  * want the card to TX needs to stay intact until the card has told us that
  * it is done with it. This function finds empty places we can upload to and
- * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
- * allocated areas.
+ * marks allocated areas as reserved if necessary. p54_rx_frame_sent or
+ * p54_free_skb frees allocated areas.
  */
 static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
 			       struct p54_hdr *data, u32 len)
@@ -981,7 +1127,7 @@ static int p54_assign_address(struct iee
 	struct sk_buff *entry;
 	struct sk_buff *target_skb = NULL;
 	struct ieee80211_tx_info *info;
-	struct memrecord *range;
+	struct p54_tx_info *range;
 	u32 last_addr = priv->rx_start;
 	u32 largest_hole = 0;
 	u32 target_addr = priv->rx_start;
@@ -1063,25 +1209,29 @@ static int p54_assign_address(struct iee
 	return 0;
 }
 
-static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
-		u16 hdr_flags, u16 len, u16 type, gfp_t memflags)
+static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags,
+				     u16 payload_len, u16 type, gfp_t memflags)
 {
 	struct p54_common *priv = dev->priv;
 	struct p54_hdr *hdr;
 	struct sk_buff *skb;
+	size_t frame_len = sizeof(*hdr) + payload_len;
 
-	skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags);
+	if (frame_len > P54_MAX_CTRL_FRAME_LEN)
+		return NULL;
+
+	skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
 	if (!skb)
 		return NULL;
 	skb_reserve(skb, priv->tx_hdr_len);
 
 	hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
 	hdr->flags = cpu_to_le16(hdr_flags);
-	hdr->len = cpu_to_le16(len - sizeof(*hdr));
+	hdr->len = cpu_to_le16(payload_len);
 	hdr->type = cpu_to_le16(type);
 	hdr->tries = hdr->rts_tries = 0;
 
-	if (unlikely(p54_assign_address(dev, skb, hdr, len))) {
+	if (p54_assign_address(dev, skb, hdr, frame_len)) {
 		kfree_skb(skb);
 		return NULL;
 	}
@@ -1091,7 +1241,6 @@ static struct sk_buff *p54_alloc_skb(str
 int p54_read_eeprom(struct ieee80211_hw *dev)
 {
 	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr = NULL;
 	struct p54_eeprom_lm86 *eeprom_hdr;
 	struct sk_buff *skb;
 	size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
@@ -1104,9 +1253,9 @@ int p54_read_eeprom(struct ieee80211_hw
 	else
 		maxblocksize -= 0x4;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) +
-			    sizeof(*eeprom_hdr) + maxblocksize,
-			    P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) +
+			    maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK,
+			    GFP_KERNEL);
 	if (!skb)
 		goto free;
 	priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
@@ -1162,9 +1311,8 @@ static int p54_set_tim(struct ieee80211_
 	struct sk_buff *skb;
 	struct p54_tim *tim;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
-		      sizeof(struct p54_hdr) + sizeof(*tim),
-		      P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
+			    P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1181,9 +1329,8 @@ static int p54_sta_unlock(struct ieee802
 	struct sk_buff *skb;
 	struct p54_sta_unlock *sta;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
-		sizeof(struct p54_hdr) + sizeof(*sta),
-		P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
+			    P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1223,9 +1370,8 @@ static int p54_tx_cancel(struct ieee8021
 	struct p54_hdr *hdr;
 	struct p54_txcancel *cancel;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
-		sizeof(struct p54_hdr) + sizeof(*cancel),
-		P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
+			    P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1242,46 +1388,73 @@ static int p54_tx_fill(struct ieee80211_
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct p54_common *priv = dev->priv;
-	int ret = 0;
-
-	if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
-		if (ieee80211_is_beacon(hdr->frame_control)) {
-			*aid = 0;
-			*queue = 0;
-			*extra_len = IEEE80211_MAX_TIM_LEN;
-			*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
-			return 0;
-		} else if (ieee80211_is_probe_resp(hdr->frame_control)) {
-			*aid = 0;
-			*queue = 2;
-			*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
-				 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
-			return 0;
-		} else {
-			*queue = 2;
-			ret = 0;
-		}
-	} else {
-		*queue += 4;
-		ret = 1;
-	}
+	int ret = 1;
 
 	switch (priv->mode) {
+	case NL80211_IFTYPE_MONITOR:
+		/*
+		 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
+		 * every frame in promiscuous/monitor mode.
+		 * see STSW45x0C LMAC API - page 12.
+		 */
+		*aid = 0;
+		*flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
+		*queue += P54_QUEUE_DATA;
+		break;
 	case NL80211_IFTYPE_STATION:
 		*aid = 1;
+		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+			*queue = P54_QUEUE_MGMT;
+			ret = 0;
+		} else
+			*queue += P54_QUEUE_DATA;
 		break;
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
 		if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
 			*aid = 0;
-			*queue = 3;
+			*queue = P54_QUEUE_CAB;
 			return 0;
 		}
+
+		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+			if (ieee80211_is_probe_resp(hdr->frame_control)) {
+				*aid = 0;
+				*queue = P54_QUEUE_MGMT;
+				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+					 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+				return 0;
+			} else if (ieee80211_is_beacon(hdr->frame_control)) {
+				*aid = 0;
+
+				if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+					/*
+					 * Injecting beacons on top of a AP is
+					 * not a good idea... nevertheless,
+					 * it should be doable.
+					 */
+
+					*queue += P54_QUEUE_DATA;
+					return 1;
+				}
+
+				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+				*queue = P54_QUEUE_BEACON;
+				*extra_len = IEEE80211_MAX_TIM_LEN;
+				return 0;
+			} else {
+				*queue = P54_QUEUE_MGMT;
+				ret = 0;
+			}
+		} else
+			*queue += P54_QUEUE_DATA;
+
 		if (info->control.sta)
 			*aid = info->control.sta->aid;
 		else
 			*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+		break;
 	}
 	return ret;
 }
@@ -1303,7 +1476,7 @@ static u8 p54_convert_algo(enum ieee8021
 static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_tx_queue_stats *current_queue = NULL;
+	struct ieee80211_tx_queue_stats *current_queue;
 	struct p54_common *priv = dev->priv;
 	struct p54_hdr *hdr;
 	struct p54_tx_data *txhdr;
@@ -1446,15 +1619,17 @@ static int p54_tx(struct ieee80211_hw *d
 	}
 	txhdr->crypt_offset = crypt_offset;
 	txhdr->hw_queue = queue;
-	if (current_queue)
-		txhdr->backlog = current_queue->len;
-	else
-		txhdr->backlog = 0;
+	txhdr->backlog = current_queue->len;
 	memset(txhdr->durations, 0, sizeof(txhdr->durations));
-	txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
-		2 : info->antenna_sel_tx - 1;
-	txhdr->output_power = priv->output_power;
-	txhdr->cts_rate = cts_rate;
+	txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
+		2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+		txhdr->longbow.cts_rate = cts_rate;
+		txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
+	} else {
+		txhdr->normal.output_power = priv->output_power;
+		txhdr->normal.cts_rate = cts_rate;
+	}
 	if (padding)
 		txhdr->align[0] = padding;
 
@@ -1467,14 +1642,12 @@ static int p54_tx(struct ieee80211_hw *d
 	queue_delayed_work(dev->workqueue, &priv->work,
 			   msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
 
-	return 0;
+	return NETDEV_TX_OK;
 
  err:
 	skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
-	if (current_queue) {
-		current_queue->len--;
-		current_queue->count--;
-	}
+	current_queue->len--;
+	current_queue->count--;
 	return NETDEV_TX_BUSY;
 }
 
@@ -1485,9 +1658,8 @@ static int p54_setup_mac(struct ieee8021
 	struct p54_setup_mac *setup;
 	u16 mode;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) +
-			    sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP,
-			    GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
+			    P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1504,19 +1676,29 @@ static int p54_setup_mac(struct ieee8021
 		case NL80211_IFTYPE_MESH_POINT:
 			mode = P54_FILTER_TYPE_IBSS;
 			break;
+		case NL80211_IFTYPE_MONITOR:
+			mode = P54_FILTER_TYPE_PROMISCUOUS;
+			break;
 		default:
-			mode = P54_FILTER_TYPE_NONE;
+			mode = P54_FILTER_TYPE_HIBERNATE;
 			break;
 		}
-		if (priv->filter_flags & FIF_PROMISC_IN_BSS)
+
+		/*
+		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
+		 * STSW45X0C LMAC API - page 12
+		 */
+		if (((priv->filter_flags & FIF_PROMISC_IN_BSS) ||
+		     (priv->filter_flags & FIF_OTHER_BSS)) &&
+		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
 			mode |= P54_FILTER_TYPE_TRANSPARENT;
 	} else
-		mode = P54_FILTER_TYPE_RX_DISABLED;
+		mode = P54_FILTER_TYPE_HIBERNATE;
 
 	setup->mac_mode = cpu_to_le16(mode);
 	memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
 	memcpy(setup->bssid, priv->bssid, ETH_ALEN);
-	setup->rx_antenna = 2; /* automatic */
+	setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
 	setup->rx_align = 0;
 	if (priv->fw_var < 0x500) {
 		setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
@@ -1549,79 +1731,137 @@ static int p54_scan(struct ieee80211_hw
 {
 	struct p54_common *priv = dev->priv;
 	struct sk_buff *skb;
-	struct p54_scan *chan;
+	struct p54_hdr *hdr;
+	struct p54_scan_head *head;
+	struct p54_iq_autocal_entry *iq_autocal;
+	union p54_scan_body_union *body;
+	struct p54_scan_tail_rate *rate;
+	struct pda_rssi_cal_entry *rssi;
 	unsigned int i;
 	void *entry;
-	__le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
 	int band = dev->conf.channel->band;
+	__le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
-			    sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
-			    GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
+			    2 + sizeof(*iq_autocal) + sizeof(*body) +
+			    sizeof(*rate) + 2 * sizeof(*rssi),
+			    P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
-	chan = (struct p54_scan *) skb_put(skb, sizeof(*chan));
-	memset(chan->padding1, 0, sizeof(chan->padding1));
-	chan->mode = cpu_to_le16(mode);
-	chan->dwell = cpu_to_le16(dwell);
+	head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
+	memset(head->scan_params, 0, sizeof(head->scan_params));
+	head->mode = cpu_to_le16(mode);
+	head->dwell = cpu_to_le16(dwell);
+	head->freq = freq;
+
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+		__le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
+		*pa_power_points = cpu_to_le16(0x0c);
+	}
 
+	iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
 	for (i = 0; i < priv->iq_autocal_len; i++) {
 		if (priv->iq_autocal[i].freq != freq)
 			continue;
 
-		memcpy(&chan->iq_autocal, &priv->iq_autocal[i],
-		       sizeof(*priv->iq_autocal));
+		memcpy(iq_autocal, &priv->iq_autocal[i].params,
+		       sizeof(struct p54_iq_autocal_entry));
 		break;
 	}
 	if (i == priv->iq_autocal_len)
 		goto err;
 
-	for (i = 0; i < priv->output_limit_len; i++) {
-		if (priv->output_limit[i].freq != freq)
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
+		body = (void *) skb_put(skb, sizeof(body->longbow));
+	else
+		body = (void *) skb_put(skb, sizeof(body->normal));
+
+	for (i = 0; i < priv->output_limit->entries; i++) {
+		__le16 *entry_freq = (void *) (priv->output_limit->data +
+				     priv->output_limit->entry_size * i);
+
+		if (*entry_freq != freq)
 			continue;
 
-		chan->val_barker = 0x38;
-		chan->val_bpsk = chan->dup_bpsk =
-			priv->output_limit[i].val_bpsk;
-		chan->val_qpsk = chan->dup_qpsk =
-			priv->output_limit[i].val_qpsk;
-		chan->val_16qam = chan->dup_16qam =
-			priv->output_limit[i].val_16qam;
-		chan->val_64qam = chan->dup_64qam =
-			priv->output_limit[i].val_64qam;
+		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+			memcpy(&body->longbow.power_limits,
+			       (void *) entry_freq + sizeof(__le16),
+			       priv->output_limit->entry_size);
+		} else {
+			struct pda_channel_output_limit *limits =
+			       (void *) entry_freq;
+
+			body->normal.val_barker = 0x38;
+			body->normal.val_bpsk = body->normal.dup_bpsk =
+				limits->val_bpsk;
+			body->normal.val_qpsk = body->normal.dup_qpsk =
+				limits->val_qpsk;
+			body->normal.val_16qam = body->normal.dup_16qam =
+				limits->val_16qam;
+			body->normal.val_64qam = body->normal.dup_64qam =
+				limits->val_64qam;
+		}
 		break;
 	}
-	if (i == priv->output_limit_len)
+	if (i == priv->output_limit->entries)
 		goto err;
 
-	entry = priv->curve_data->data;
-	for (i = 0; i < priv->curve_data->channels; i++) {
+	entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
+	for (i = 0; i < priv->curve_data->entries; i++) {
 		if (*((__le16 *)entry) != freq) {
-			entry += sizeof(__le16);
-			entry += sizeof(struct p54_pa_curve_data_sample) *
-				 priv->curve_data->points_per_channel;
+			entry += priv->curve_data->entry_size;
 			continue;
 		}
 
-		entry += sizeof(__le16);
-		chan->pa_points_per_curve = 8;
-		memset(chan->curve_data, 0, sizeof(*chan->curve_data));
-		memcpy(chan->curve_data, entry,
-		       sizeof(struct p54_pa_curve_data_sample) *
-		       min((u8)8, priv->curve_data->points_per_channel));
+		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+			memcpy(&body->longbow.curve_data,
+				(void *) entry + sizeof(__le16),
+				priv->curve_data->entry_size);
+		} else {
+			struct p54_scan_body *chan = &body->normal;
+			struct pda_pa_curve_data *curve_data =
+				(void *) priv->curve_data->data;
+
+			entry += sizeof(__le16);
+			chan->pa_points_per_curve = 8;
+			memset(chan->curve_data, 0, sizeof(*chan->curve_data));
+			memcpy(chan->curve_data, entry,
+			       sizeof(struct p54_pa_curve_data_sample) *
+			       min((u8)8, curve_data->points_per_channel));
+		}
 		break;
 	}
+	if (i == priv->curve_data->entries)
+		goto err;
 
-	if (priv->fw_var < 0x500) {
-		chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
-		chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
-	} else {
-		chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
-		chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
-		chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
-		memset(chan->v2.rts_rates, 0, 8);
+	if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
+		rate = (void *) skb_put(skb, sizeof(*rate));
+		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		for (i = 0; i < sizeof(rate->rts_rates); i++)
+			rate->rts_rates[i] = i;
 	}
+
+	rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
+	rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
+	rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+		/* Longbow frontend needs ever more */
+		rssi = (void *) skb_put(skb, sizeof(*rssi));
+		rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
+		rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+	}
+
+	if (priv->fw_var >= 0x509) {
+		rate = (void *) skb_put(skb, sizeof(*rate));
+		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		for (i = 0; i < sizeof(rate->rts_rates); i++)
+			rate->rts_rates[i] = i;
+	}
+
+	hdr = (struct p54_hdr *) skb->data;
+	hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
+
 	priv->tx(dev, skb);
 	return 0;
 
@@ -1631,23 +1871,22 @@ static int p54_scan(struct ieee80211_hw
 	return -EINVAL;
 }
 
-static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
+static int p54_set_leds(struct ieee80211_hw *dev)
 {
 	struct p54_common *priv = dev->priv;
 	struct sk_buff *skb;
 	struct p54_led *led;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) +
-			sizeof(struct p54_hdr),	P54_CONTROL_TYPE_LED,
-			GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
+			    P54_CONTROL_TYPE_LED, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
-	led = (struct p54_led *)skb_put(skb, sizeof(*led));
-	led->mode = cpu_to_le16(mode);
-	led->led_permanent = cpu_to_le16(link);
-	led->led_temporary = cpu_to_le16(act);
-	led->duration = cpu_to_le16(1000);
+	led = (struct p54_led *) skb_put(skb, sizeof(*led));
+	led->flags = cpu_to_le16(0x0003);
+	led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
+	led->delay[0] = cpu_to_le16(1);
+	led->delay[1] = cpu_to_le16(0);
 	priv->tx(dev, skb);
 	return 0;
 }
@@ -1666,9 +1905,8 @@ static int p54_set_edcf(struct ieee80211
 	struct sk_buff *skb;
 	struct p54_edcf *edcf;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) +
-			sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT,
-			GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
+			    P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1692,6 +1930,42 @@ static int p54_set_edcf(struct ieee80211
 	return 0;
 }
 
+static int p54_set_ps(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	struct sk_buff *skb;
+	struct p54_psm *psm;
+	u16 mode;
+	int i;
+
+	if (dev->conf.flags & IEEE80211_CONF_PS)
+		mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+	else
+		mode = P54_PSM_CAM;
+
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
+			    P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	psm = (struct p54_psm *)skb_put(skb, sizeof(*psm));
+	psm->mode = cpu_to_le16(mode);
+	psm->aid = cpu_to_le16(priv->aid);
+	for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
+		psm->intervals[i].interval =
+			cpu_to_le16(dev->conf.listen_interval);
+		psm->intervals[i].periods = cpu_to_le16(1);
+	}
+
+	psm->beacon_rssi_skip_max = 60;
+	psm->rssi_delta_threshold = 0;
+	psm->nr = 0;
+
+	priv->tx(dev, skb);
+
+	return 0;
+}
+
 static int p54_beacon_tim(struct sk_buff *skb)
 {
 	/*
@@ -1796,6 +2070,9 @@ static int p54_start(struct ieee80211_hw
 
 	queue_delayed_work(dev->workqueue, &priv->work, 0);
 
+	priv->softled_state = 0;
+	err = p54_set_leds(dev);
+
 out:
 	mutex_unlock(&priv->conf_mutex);
 	return err;
@@ -1808,6 +2085,9 @@ static void p54_stop(struct ieee80211_hw
 
 	mutex_lock(&priv->conf_mutex);
 	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+	priv->softled_state = 0;
+	p54_set_leds(dev);
+
 	cancel_delayed_work_sync(&priv->work);
 	if (priv->cached_beacon)
 		p54_tx_cancel(dev, priv->cached_beacon);
@@ -1845,7 +2125,6 @@ static int p54_add_interface(struct ieee
 
 	memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
 	p54_setup_mac(dev);
-	p54_set_leds(dev, 1, 0, 0);
 	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
@@ -1884,6 +2163,11 @@ static int p54_config(struct ieee80211_h
 		if (ret)
 			goto out;
 	}
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		ret = p54_set_ps(dev);
+		if (ret)
+			goto out;
+	}
 
 out:
 	mutex_unlock(&priv->conf_mutex);
@@ -1920,8 +2204,6 @@ static int p54_config_interface(struct i
 			goto out;
 	}
 
-	ret = p54_set_leds(dev, 1, !is_multicast_ether_addr(priv->bssid), 0);
-
 out:
 	mutex_unlock(&priv->conf_mutex);
 	return ret;
@@ -1935,12 +2217,11 @@ static void p54_configure_filter(struct
 	struct p54_common *priv = dev->priv;
 
 	*total_flags &= FIF_PROMISC_IN_BSS |
-			(*total_flags & FIF_PROMISC_IN_BSS) ?
-				FIF_FCSFAIL : 0;
+			FIF_OTHER_BSS;
 
 	priv->filter_flags = *total_flags;
 
-	if (changed_flags & FIF_PROMISC_IN_BSS)
+	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
 		p54_setup_mac(dev);
 }
 
@@ -1967,10 +2248,8 @@ static int p54_init_xbow_synth(struct ie
 	struct sk_buff *skb;
 	struct p54_xbow_synth *xbow;
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) +
-			    sizeof(struct p54_hdr),
-			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
-			    GFP_KERNEL);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
+			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 
@@ -1999,7 +2278,7 @@ static void p54_work(struct work_struct
 	 *      2. cancel stuck frames / reset the device if necessary.
 	 */
 
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) +
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
 			    sizeof(struct p54_statistics),
 			    P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
 	if (!skb)
@@ -2022,8 +2301,8 @@ static int p54_get_tx_stats(struct ieee8
 {
 	struct p54_common *priv = dev->priv;
 
-	memcpy(stats, &priv->tx_stats[4], sizeof(stats[0]) * dev->queues);
-
+	memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
+	       sizeof(stats[0]) * dev->queues);
 	return 0;
 }
 
@@ -2059,7 +2338,7 @@ static void p54_bss_info_changed(struct
 }
 
 static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
-		       const u8 *local_address, const u8 *address,
+		       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 		       struct ieee80211_key_conf *key)
 {
 	struct p54_common *priv = dev->priv;
@@ -2110,9 +2389,8 @@ static int p54_set_key(struct ieee80211_
 	}
 
 	mutex_lock(&priv->conf_mutex);
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) +
-			sizeof(struct p54_hdr),	P54_CONTROL_TYPE_RX_KEYCACHE,
-			GFP_ATOMIC);
+	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
+			    P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
 	if (!skb) {
 		mutex_unlock(&priv->conf_mutex);
 		return -ENOMEM;
@@ -2123,8 +2401,8 @@ static int p54_set_key(struct ieee80211_
 	rxkey->entry = key->keyidx;
 	rxkey->key_id = key->keyidx;
 	rxkey->key_type = algo;
-	if (address)
-		memcpy(rxkey->mac, address, ETH_ALEN);
+	if (sta)
+		memcpy(rxkey->mac, sta->addr, ETH_ALEN);
 	else
 		memset(rxkey->mac, ~0, ETH_ALEN);
 	if (key->alg != ALG_TKIP) {
@@ -2142,6 +2420,96 @@ static int p54_set_key(struct ieee80211_
 	return 0;
 }
 
+#ifdef CONFIG_P54_LEDS
+static void p54_led_brightness_set(struct led_classdev *led_dev,
+				   enum led_brightness brightness)
+{
+	struct p54_led_dev *led = container_of(led_dev, struct p54_led_dev,
+					       led_dev);
+	struct ieee80211_hw *dev = led->hw_dev;
+	struct p54_common *priv = dev->priv;
+	int err;
+
+	/* Don't toggle the LED, when the device is down. */
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		return ;
+
+	if (brightness != LED_OFF)
+		priv->softled_state |= BIT(led->index);
+	else
+		priv->softled_state &= ~BIT(led->index);
+
+	err = p54_set_leds(dev);
+	if (err && net_ratelimit())
+		printk(KERN_ERR "%s: failed to update %s LED.\n",
+			wiphy_name(dev->wiphy), led_dev->name);
+}
+
+static int p54_register_led(struct ieee80211_hw *dev,
+			    struct p54_led_dev *led,
+			    unsigned int led_index,
+			    char *name, char *trigger)
+{
+	int err;
+
+	if (led->registered)
+		return -EEXIST;
+
+	snprintf(led->name, sizeof(led->name), "p54-%s::%s",
+		 wiphy_name(dev->wiphy), name);
+	led->hw_dev = dev;
+	led->index = led_index;
+	led->led_dev.name = led->name;
+	led->led_dev.default_trigger = trigger;
+	led->led_dev.brightness_set = p54_led_brightness_set;
+
+	err = led_classdev_register(wiphy_dev(dev->wiphy), &led->led_dev);
+	if (err)
+		printk(KERN_ERR "%s: Failed to register %s LED.\n",
+			wiphy_name(dev->wiphy), name);
+	else
+		led->registered = 1;
+
+	return err;
+}
+
+static int p54_init_leds(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	int err;
+
+	/*
+	 * TODO:
+	 * Figure out if the EEPROM contains some hints about the number
+	 * of available/programmable LEDs of the device.
+	 * But for now, we can assume that we have two programmable LEDs.
+	 */
+
+	err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
+			       ieee80211_get_assoc_led_name(dev));
+	if (err)
+		return err;
+
+	err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+			       ieee80211_get_tx_led_name(dev));
+	if (err)
+		return err;
+
+	err = p54_set_leds(dev);
+	return err;
+}
+
+static void p54_unregister_leds(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+
+	if (priv->tx_led.registered)
+		led_classdev_unregister(&priv->tx_led.led_dev);
+	if (priv->assoc_led.registered)
+		led_classdev_unregister(&priv->assoc_led.led_dev);
+}
+#endif /* CONFIG_P54_LEDS */
+
 static const struct ieee80211_ops p54_ops = {
 	.tx			= p54_tx,
 	.start			= p54_start,
@@ -2184,11 +2552,11 @@ struct ieee80211_hw *p54_init_common(siz
 				      BIT(NL80211_IFTYPE_MESH_POINT);
 
 	dev->channel_change_time = 1000;	/* TODO: find actual value */
-	priv->tx_stats[0].limit = 1;		/* Beacon queue */
-	priv->tx_stats[1].limit = 1;		/* Probe queue for HW scan */
-	priv->tx_stats[2].limit = 3;		/* queue for MLMEs */
-	priv->tx_stats[3].limit = 3;		/* Broadcast / MC queue */
-	priv->tx_stats[4].limit = 5;		/* Data */
+	priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
+	priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
+	priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
+	priv->tx_stats[P54_QUEUE_CAB].limit = 3;
+	priv->tx_stats[P54_QUEUE_DATA].limit = 5;
 	dev->queues = 1;
 	priv->noise = -94;
 	/*
@@ -2212,12 +2580,37 @@ struct ieee80211_hw *p54_init_common(siz
 }
 EXPORT_SYMBOL_GPL(p54_init_common);
 
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
+{
+	int err;
+
+	err = ieee80211_register_hw(dev);
+	if (err) {
+		dev_err(pdev, "Cannot register device (%d).\n", err);
+		return err;
+	}
+
+#ifdef CONFIG_P54_LEDS
+	err = p54_init_leds(dev);
+	if (err)
+		return err;
+#endif /* CONFIG_P54_LEDS */
+
+	dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
+	return 0;
+}
+EXPORT_SYMBOL_GPL(p54_register_common);
+
 void p54_free_common(struct ieee80211_hw *dev)
 {
 	struct p54_common *priv = dev->priv;
 	kfree(priv->iq_autocal);
 	kfree(priv->output_limit);
 	kfree(priv->curve_data);
+
+#ifdef CONFIG_P54_LEDS
+	p54_unregister_leds(dev);
+#endif /* CONFIG_P54_LEDS */
 }
 EXPORT_SYMBOL_GPL(p54_free_common);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54common.h linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54common.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54common.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,12 +26,17 @@ struct bootrec {
 } __attribute__((packed));
 
 #define PDR_SYNTH_FRONTEND_MASK		0x0007
+#define PDR_SYNTH_FRONTEND_DUETTE3	0x0001
+#define PDR_SYNTH_FRONTEND_DUETTE2	0x0002
+#define PDR_SYNTH_FRONTEND_FRISBEE	0x0003
+#define PDR_SYNTH_FRONTEND_XBOW		0x0004
+#define PDR_SYNTH_FRONTEND_LONGBOW	0x0005
 #define PDR_SYNTH_IQ_CAL_MASK		0x0018
 #define PDR_SYNTH_IQ_CAL_PA_DETECTOR	0x0000
 #define PDR_SYNTH_IQ_CAL_DISABLED	0x0008
 #define PDR_SYNTH_IQ_CAL_ZIF		0x0010
 #define PDR_SYNTH_FAA_SWITCH_MASK	0x0020
-#define PDR_SYNTH_FAA_SWITCH_ENABLED	0x0001
+#define PDR_SYNTH_FAA_SWITCH_ENABLED	0x0020
 #define PDR_SYNTH_24_GHZ_MASK		0x0040
 #define PDR_SYNTH_24_GHZ_DISABLED	0x0040
 #define PDR_SYNTH_5_GHZ_MASK		0x0080
@@ -125,9 +130,13 @@ struct eeprom_pda_wrap {
 	u8 data[0];
 } __attribute__ ((packed));
 
+struct p54_iq_autocal_entry {
+	__le16 iq_param[4];
+} __attribute__ ((packed));
+
 struct pda_iq_autocal_entry {
         __le16 freq;
-        __le16 iq_param[4];
+	struct p54_iq_autocal_entry params;
 } __attribute__ ((packed));
 
 struct pda_channel_output_limit {
@@ -180,6 +189,35 @@ struct pda_rssi_cal_entry {
 	__le16 add;
 } __attribute__ ((packed));
 
+struct pda_country {
+	u8 regdomain;
+	u8 alpha2[2];
+	u8 flags;
+} __attribute__ ((packed));
+
+/*
+ * Warning: Longbow's structures are bogus.
+ */
+struct p54_channel_output_limit_longbow {
+	__le16 rf_power_points[12];
+} __attribute__ ((packed));
+
+struct p54_pa_curve_data_sample_longbow {
+	__le16 rf_power;
+	__le16 pa_detector;
+	struct {
+		__le16 data[4];
+	} points[3] __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct pda_custom_wrapper {
+	__le16 entries;
+	__le16 entry_size;
+	__le16 offset;
+	__le16 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
 /*
  * this defines the PDR codes used to build PDAs as defined in document
  * number 553155. The current implementation mirrors version 1.1 of the
@@ -225,8 +263,13 @@ struct pda_rssi_cal_entry {
 /* reserved range (0x2000 - 0x7fff) */
 
 /* customer range (0x8000 - 0xffff) */
-#define PDR_BASEBAND_REGISTERS			0x8000
-#define PDR_PER_CHANNEL_BASEBAND_REGISTERS	0x8001
+#define PDR_BASEBAND_REGISTERS				0x8000
+#define PDR_PER_CHANNEL_BASEBAND_REGISTERS		0x8001
+
+/* used by our modificated eeprom image */
+#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM		0xDEAD
+#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM	0xBEEF
+#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM		0xB05D
 
 /* PDR definitions for default country & country list */
 #define PDR_COUNTRY_CERT_CODE		0x80
@@ -241,12 +284,6 @@ struct pda_rssi_cal_entry {
 #define PDR_COUNTRY_CERT_IODOOR_OUTDOOR	0x30
 #define PDR_COUNTRY_CERT_INDEX		0x0F
 
-/* stored in skb->cb */
-struct memrecord {
-	u32 start_addr;
-	u32 end_addr;
-};
-
 struct p54_eeprom_lm86 {
 	union {
 		struct {
@@ -329,7 +366,7 @@ struct p54_frame_sent {
 	u8 padding;
 } __attribute__ ((packed));
 
-enum  p54_tx_data_crypt {
+enum p54_tx_data_crypt {
 	P54_CRYPTO_NONE = 0,
 	P54_CRYPTO_WEP,
 	P54_CRYPTO_TKIP,
@@ -340,6 +377,23 @@ enum  p54_tx_data_crypt {
 	P54_CRYPTO_AESCCMP
 };
 
+enum p54_tx_data_queue {
+	P54_QUEUE_BEACON	= 0,
+	P54_QUEUE_FWSCAN	= 1,
+	P54_QUEUE_MGMT		= 2,
+	P54_QUEUE_CAB		= 3,
+	P54_QUEUE_DATA		= 4,
+
+	P54_QUEUE_AC_NUM	= 4,
+	P54_QUEUE_AC_VO		= 4,
+	P54_QUEUE_AC_VI		= 5,
+	P54_QUEUE_AC_BE		= 6,
+	P54_QUEUE_AC_BK		= 7,
+
+	/* keep last */
+	P54_QUEUE_NUM		= 8,
+};
+
 struct p54_tx_data {
 	u8 rateset[8];
 	u8 rts_rate_idx;
@@ -351,9 +405,18 @@ struct p54_tx_data {
 	u8 backlog;
 	__le16 durations[4];
 	u8 tx_antenna;
-	u8 output_power;
-	u8 cts_rate;
-	u8 unalloc2[3];
+	union {
+		struct {
+			u8 cts_rate;
+			__le16 output_power;
+		} __attribute__((packed)) longbow;
+		struct {
+			u8 output_power;
+			u8 cts_rate;
+			u8 unalloc;
+		} __attribute__ ((packed)) normal;
+	} __attribute__ ((packed));
+	u8 unalloc2[2];
 	u8 align[0];
 } __attribute__ ((packed));
 
@@ -414,11 +477,14 @@ struct p54_setup_mac {
 #define P54_SCAN_ACTIVE BIT(2)
 #define P54_SCAN_FILTER BIT(3)
 
-struct p54_scan {
+struct p54_scan_head {
 	__le16 mode;
 	__le16 dwell;
-	u8 padding1[20];
-	struct pda_iq_autocal_entry iq_autocal;
+	u8 scan_params[20];
+	__le16 freq;
+} __attribute__ ((packed));
+
+struct p54_scan_body {
 	u8 pa_points_per_curve;
 	u8 val_barker;
 	u8 val_bpsk;
@@ -430,25 +496,28 @@ struct p54_scan {
 	u8 dup_qpsk;
 	u8 dup_16qam;
 	u8 dup_64qam;
-	union {
-		struct pda_rssi_cal_entry v1_rssi;
+} __attribute__ ((packed));
 
-		struct {
-			__le32 basic_rate_mask;
-			u8 rts_rates[8];
-			struct pda_rssi_cal_entry rssi;
-		} v2 __attribute__ ((packed));
-	} __attribute__ ((packed));
+struct p54_scan_body_longbow {
+	struct p54_channel_output_limit_longbow power_limits;
+	struct p54_pa_curve_data_sample_longbow curve_data[8];
+	__le16 unkn[6];		/* maybe more power_limits or rate_mask */
 } __attribute__ ((packed));
 
-#define P54_SCAN_V1_LEN 0x70
-#define P54_SCAN_V2_LEN 0x7c
+union p54_scan_body_union {
+	struct p54_scan_body normal;
+	struct p54_scan_body_longbow longbow;
+} __attribute__ ((packed));
+
+struct p54_scan_tail_rate {
+	__le32 basic_rate_mask;
+	u8 rts_rates[8];
+} __attribute__ ((packed));
 
 struct p54_led {
-	__le16 mode;
-	__le16 led_temporary;
-	__le16 led_permanent;
-	__le16 duration;
+	__le16 flags;
+	__le16 mask[2];
+	__le16 delay[2];
 } __attribute__ ((packed));
 
 struct p54_edcf {
@@ -511,6 +580,7 @@ struct p54_psm_interval {
 	__le16 periods;
 } __attribute__ ((packed));
 
+#define P54_PSM_CAM			0
 #define P54_PSM				BIT(0)
 #define P54_PSM_DTIM			BIT(1)
 #define P54_PSM_MCBC			BIT(2)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54.h linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54.h	2009-06-09 23:05:27.000000000 -0400
@@ -14,6 +14,10 @@
  * published by the Free Software Foundation.
  */
 
+#ifdef CONFIG_P54_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_P54_LEDS */
+
 enum p54_control_frame_types {
 	P54_CONTROL_TYPE_SETUP = 0,
 	P54_CONTROL_TYPE_SCAN,
@@ -44,6 +48,18 @@ enum p54_control_frame_types {
 	P54_CONTROL_TYPE_BT_OPTIONS = 35
 };
 
+/* provide 16 bytes for the transport back-end */
+#define P54_TX_INFO_DATA_SIZE		16
+
+/* stored in ieee80211_tx_info's rate_driver_data */
+struct p54_tx_info {
+	u32 start_addr;
+	u32 end_addr;
+	void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)];
+};
+
+#define P54_MAX_CTRL_FRAME_LEN		0x1000
+
 #define P54_HDR_FLAG_CONTROL		BIT(15)
 #define P54_HDR_FLAG_CONTROL_OPSET	(BIT(15) + BIT(0))
 
@@ -75,6 +91,14 @@ struct p54_rssi_linear_approximation {
 	s16 longbow_unk2;
 };
 
+struct p54_cal_database {
+	size_t entries;
+	size_t entry_size;
+	size_t offset;
+	size_t len;
+	u8 data[0];
+};
+
 #define EEPROM_READBACK_LEN 0x3fc
 
 #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -84,6 +108,29 @@ struct p54_rssi_linear_approximation {
 #define FW_LM87 0x4c4d3837
 #define FW_LM20 0x4c4d3230
 
+enum fw_state {
+	FW_STATE_OFF,
+	FW_STATE_BOOTING,
+	FW_STATE_READY,
+	FW_STATE_RESET,
+	FW_STATE_RESETTING,
+};
+
+#ifdef CONFIG_P54_LEDS
+
+#define P54_LED_MAX_NAME_LEN 31
+
+struct p54_led_dev {
+	struct ieee80211_hw *hw_dev;
+	struct led_classdev led_dev;
+	char name[P54_LED_MAX_NAME_LEN + 1];
+
+	unsigned int index;
+	unsigned int registered;
+};
+
+#endif /* CONFIG_P54_LEDS */
+
 struct p54_common {
 	struct ieee80211_hw *hw;
 	u32 rx_start;
@@ -99,11 +146,12 @@ struct p54_common {
 	struct mutex conf_mutex;
 	u8 mac_addr[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
+	u8 rx_diversity_mask;
+	u8 tx_diversity_mask;
 	struct pda_iq_autocal_entry *iq_autocal;
 	unsigned int iq_autocal_len;
-	struct pda_channel_output_limit *output_limit;
-	unsigned int output_limit_len;
-	struct pda_pa_curve_data *curve_data;
+	struct p54_cal_database *output_limit;
+	struct p54_cal_database *curve_data;
 	struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
 	unsigned int filter_flags;
 	bool use_short_slot;
@@ -115,7 +163,7 @@ struct p54_common {
 	unsigned int output_power;
 	u32 tsf_low32;
 	u32 tsf_high32;
-	u64 basic_rate_mask;
+	u32 basic_rate_mask;
 	u16 wakeup_timer;
 	u16 aid;
 	struct ieee80211_tx_queue_stats tx_stats[8];
@@ -128,13 +176,21 @@ struct p54_common {
 	struct completion eeprom_comp;
 	u8 privacy_caps;
 	u8 rx_keycache_size;
+	/* LED management */
+#ifdef CONFIG_P54_LEDS
+	struct p54_led_dev assoc_led;
+	struct p54_led_dev tx_led;
+#endif /* CONFIG_P54_LEDS */
+	u16 softled_state;		/* bit field of glowing LEDs */
 };
 
 int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
 void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb);
 int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
 int p54_read_eeprom(struct ieee80211_hw *dev);
 struct ieee80211_hw *p54_init_common(size_t priv_data_len);
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev);
 void p54_free_common(struct ieee80211_hw *dev);
 
 #endif /* P54_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 18:04:54.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54pci.c	2013-05-03 16:48:52.000000000 -0400
@@ -79,6 +79,12 @@ static int p54p_upload_firmware(struct i
 	if (err)
 		return err;
 
+	if (priv->common.fw_interface != FW_LM86) {
+		dev_err(&priv->pdev->dev, "wrong firmware, "
+			"please get a LM86(PCI) firmware a try again.\n");
+		return -EINVAL;
+	}
+
 	data = (__le32 *) priv->firmware->data;
 	remains = priv->firmware->size;
 	device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
@@ -407,8 +413,7 @@ static int p54p_open(struct ieee80211_hw
 	err = request_irq(priv->pdev->irq, &p54p_interrupt,
 			  IRQF_SHARED, "p54pci", dev);
 	if (err) {
-		printk(KERN_ERR "%s: failed to register IRQ handler\n",
-		       wiphy_name(dev->wiphy));
+		dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
 		return err;
 	}
 
@@ -470,30 +475,26 @@ static int __devinit p54p_probe(struct p
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		printk(KERN_ERR "%s (p54pci): Cannot enable new PCI device\n",
-		       pci_name(pdev));
+		dev_err(&pdev->dev, "Cannot enable new PCI device\n");
 		return err;
 	}
 
 	mem_addr = pci_resource_start(pdev, 0);
 	mem_len = pci_resource_len(pdev, 0);
 	if (mem_len < sizeof(struct p54p_csr)) {
-		printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
-		       pci_name(pdev));
+		dev_err(&pdev->dev, "Too short PCI resources\n");
 		goto err_disable_dev;
 	}
 
 	err = pci_request_regions(pdev, "p54pci");
 	if (err) {
-		printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
-		       pci_name(pdev));
+		dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
 		goto err_disable_dev;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
-	    pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
-		printk(KERN_ERR "%s (p54pci): No suitable DMA available\n",
-		       pci_name(pdev));
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
+	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+		dev_err(&pdev->dev, "No suitable DMA available\n");
 		goto err_free_reg;
 	}
 
@@ -505,8 +506,7 @@ static int __devinit p54p_probe(struct p
 
 	dev = p54_init_common(sizeof(*priv));
 	if (!dev) {
-		printk(KERN_ERR "%s (p54pci): ieee80211 alloc failed\n",
-		       pci_name(pdev));
+		dev_err(&pdev->dev, "ieee80211 alloc failed\n");
 		err = -ENOMEM;
 		goto err_free_reg;
 	}
@@ -519,17 +519,15 @@ static int __devinit p54p_probe(struct p
 
 	priv->map = ioremap(mem_addr, mem_len);
 	if (!priv->map) {
-		printk(KERN_ERR "%s (p54pci): Cannot map device memory\n",
-		       pci_name(pdev));
-		err = -EINVAL;	// TODO: use a better error code?
+		dev_err(&pdev->dev, "Cannot map device memory\n");
+		err = -ENOMEM;
 		goto err_free_dev;
 	}
 
 	priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
 						  &priv->ring_control_dma);
 	if (!priv->ring_control) {
-		printk(KERN_ERR "%s (p54pci): Cannot allocate rings\n",
-		       pci_name(pdev));
+		dev_err(&pdev->dev, "Cannot allocate rings\n");
 		err = -ENOMEM;
 		goto err_iounmap;
 	}
@@ -543,8 +541,7 @@ static int __devinit p54p_probe(struct p
 	err = reject_firmware(&priv->firmware, "/*(DEBLOBBED)*/",
 			       &priv->pdev->dev);
 	if (err) {
-		printk(KERN_ERR "%s (p54pci): cannot find firmware "
-			"(/*(DEBLOBBED)*/)\n", pci_name(priv->pdev));
+		dev_err(&pdev->dev, "Cannot find firmware (/*(DEBLOBBED)*/)\n");
 		err = reject_firmware(&priv->firmware, "/*(DEBLOBBED)*/",
 				       &priv->pdev->dev);
 		if (err)
@@ -559,12 +556,9 @@ static int __devinit p54p_probe(struct p
 	if (err)
 		goto err_free_common;
 
-	err = ieee80211_register_hw(dev);
-	if (err) {
-		printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n",
-		       pci_name(pdev));
+	err = p54_register_common(dev, &pdev->dev);
+	if (err)
 		goto err_free_common;
-	}
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi.c linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi.c	2013-05-03 16:48:54.000000000 -0400
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008       Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This driver is a port from stlc45xx:
+ *	Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You 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/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+
+#include "p54spi.h"
+#include "p54spi_eeprom.h"
+#include "p54.h"
+
+#include "p54common.h"
+
+/*(DEBLOBBED)*/
+MODULE_ALIAS("stlc45xx");
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for p54spi to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+
+static int p54spi_gpio_power = 97;
+module_param(p54spi_gpio_power, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");
+
+static int p54spi_gpio_irq = 87;
+module_param(p54spi_gpio_irq, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");
+
+static void p54spi_spi_read(struct p54s_priv *priv, u8 address,
+			      void *buf, size_t len)
+{
+	struct spi_transfer t[2];
+	struct spi_message m;
+	__le16 addr;
+
+	/* We first push the address */
+	addr = cpu_to_le16(address << 8 | SPI_ADRS_READ_BIT_15);
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = &addr;
+	t[0].len = sizeof(addr);
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].rx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	spi_sync(priv->spi, &m);
+}
+
+
+static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
+			     const void *buf, size_t len)
+{
+	struct spi_transfer t[3];
+	struct spi_message m;
+	__le16 addr;
+
+	/* We first push the address */
+	addr = cpu_to_le16(address << 8);
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = &addr;
+	t[0].len = sizeof(addr);
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].tx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	if (len % 2) {
+		__le16 last_word;
+		last_word = cpu_to_le16(((u8 *)buf)[len - 1]);
+
+		t[2].tx_buf = &last_word;
+		t[2].len = sizeof(last_word);
+		spi_message_add_tail(&t[2], &m);
+	}
+
+	spi_sync(priv->spi, &m);
+}
+
+static u16 p54spi_read16(struct p54s_priv *priv, u8 addr)
+{
+	__le16 val;
+
+	p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+	return le16_to_cpu(val);
+}
+
+static u32 p54spi_read32(struct p54s_priv *priv, u8 addr)
+{
+	__le32 val;
+
+	p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+	return le32_to_cpu(val);
+}
+
+static inline void p54spi_write16(struct p54s_priv *priv, u8 addr, __le16 val)
+{
+	p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+static inline void p54spi_write32(struct p54s_priv *priv, u8 addr, __le32 val)
+{
+	p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+struct p54spi_spi_reg {
+	u16 address;		/* __le16 ? */
+	u16 length;
+	char *name;
+};
+
+static const struct p54spi_spi_reg p54spi_registers_array[] =
+{
+	{ SPI_ADRS_ARM_INTERRUPTS,	32, "ARM_INT     " },
+	{ SPI_ADRS_ARM_INT_EN,		32, "ARM_INT_ENA " },
+	{ SPI_ADRS_HOST_INTERRUPTS,	32, "HOST_INT    " },
+	{ SPI_ADRS_HOST_INT_EN,		32, "HOST_INT_ENA" },
+	{ SPI_ADRS_HOST_INT_ACK,	32, "HOST_INT_ACK" },
+	{ SPI_ADRS_GEN_PURP_1,		32, "GP1_COMM    " },
+	{ SPI_ADRS_GEN_PURP_2,		32, "GP2_COMM    " },
+	{ SPI_ADRS_DEV_CTRL_STAT,	32, "DEV_CTRL_STA" },
+	{ SPI_ADRS_DMA_DATA,		16, "DMA_DATA    " },
+	{ SPI_ADRS_DMA_WRITE_CTRL,	16, "DMA_WR_CTRL " },
+	{ SPI_ADRS_DMA_WRITE_LEN,	16, "DMA_WR_LEN  " },
+	{ SPI_ADRS_DMA_WRITE_BASE,	32, "DMA_WR_BASE " },
+	{ SPI_ADRS_DMA_READ_CTRL,	16, "DMA_RD_CTRL " },
+	{ SPI_ADRS_DMA_READ_LEN,	16, "DMA_RD_LEN  " },
+	{ SPI_ADRS_DMA_WRITE_BASE,	32, "DMA_RD_BASE " }
+};
+
+static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
+{
+	int i;
+	__le32 buffer;
+
+	for (i = 0; i < 2000; i++) {
+		p54spi_spi_read(priv, reg, &buffer, sizeof(buffer));
+		if (buffer == bits)
+			return 1;
+
+		msleep(1);
+	}
+	return 0;
+}
+
+static int p54spi_reject_firmware(struct ieee80211_hw *dev)
+{
+	struct p54s_priv *priv = dev->priv;
+	int ret;
+
+	/* FIXME: should driver use it's own struct device? */
+	ret = reject_firmware(&priv->firmware, "/*(DEBLOBBED)*/", &priv->spi->dev);
+
+	if (ret < 0) {
+		dev_err(&priv->spi->dev, "reject_firmware() failed: %d", ret);
+		return ret;
+	}
+
+	ret = p54_parse_firmware(dev, priv->firmware);
+	if (ret) {
+		release_firmware(priv->firmware);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int p54spi_request_eeprom(struct ieee80211_hw *dev)
+{
+	struct p54s_priv *priv = dev->priv;
+	const struct firmware *eeprom;
+	int ret;
+
+	/*
+	 * allow users to customize their eeprom.
+	 */
+
+	ret = reject_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
+	if (ret < 0) {
+		dev_info(&priv->spi->dev, "loading default eeprom...\n");
+		ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
+				       sizeof(p54spi_eeprom));
+	} else {
+		dev_info(&priv->spi->dev, "loading user eeprom...\n");
+		ret = p54_parse_eeprom(dev, (void *) eeprom->data,
+				       (int)eeprom->size);
+		release_firmware(eeprom);
+	}
+	return ret;
+}
+
+static int p54spi_upload_firmware(struct ieee80211_hw *dev)
+{
+	struct p54s_priv *priv = dev->priv;
+	unsigned long fw_len, fw_addr;
+	long _fw_len;
+
+	/* stop the device */
+	p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+		       SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+		       SPI_CTRL_STAT_START_HALTED));
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+		       SPI_CTRL_STAT_HOST_OVERRIDE |
+		       SPI_CTRL_STAT_START_HALTED));
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	fw_addr = ISL38XX_DEV_FIRMWARE_ADDR;
+	fw_len = priv->firmware->size;
+
+	while (fw_len > 0) {
+		_fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE);
+
+		p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
+			       cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
+
+		if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
+				    cpu_to_le32(HOST_ALLOWED)) == 0) {
+			dev_err(&priv->spi->dev, "fw_upload not allowed "
+				"to DMA write.");
+			return -EAGAIN;
+		}
+
+		p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN,
+			       cpu_to_le16(_fw_len));
+		p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE,
+			       cpu_to_le32(fw_addr));
+
+		p54spi_spi_write(priv, SPI_ADRS_DMA_DATA,
+				 &priv->firmware->data, _fw_len);
+
+		fw_len -= _fw_len;
+		fw_addr += _fw_len;
+
+		/* FIXME: I think this doesn't work if firmware is large,
+		 * this loop goes to second round. fw->data is not
+		 * increased at all! */
+	}
+
+	BUG_ON(fw_len != 0);
+
+	/* enable host interrupts */
+	p54spi_write32(priv, SPI_ADRS_HOST_INT_EN,
+		       cpu_to_le32(SPI_HOST_INTS_DEFAULT));
+
+	/* boot the device */
+	p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+		       SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+		       SPI_CTRL_STAT_RAM_BOOT));
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+		       SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
+	msleep(TARGET_BOOT_SLEEP);
+	return 0;
+}
+
+static void p54spi_power_off(struct p54s_priv *priv)
+{
+	disable_irq(gpio_to_irq(p54spi_gpio_irq));
+	gpio_set_value(p54spi_gpio_power, 0);
+}
+
+static void p54spi_power_on(struct p54s_priv *priv)
+{
+	gpio_set_value(p54spi_gpio_power, 1);
+	enable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+	/*
+	 * need to wait a while before device can be accessed, the lenght
+	 * is just a guess
+	 */
+	msleep(10);
+}
+
+static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val)
+{
+	p54spi_write32(priv, SPI_ADRS_HOST_INT_ACK, cpu_to_le32(val));
+}
+
+static void p54spi_wakeup(struct p54s_priv *priv)
+{
+	unsigned long timeout;
+	u32 ints;
+
+	/* wake the chip */
+	p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
+		       cpu_to_le32(SPI_TARGET_INT_WAKEUP));
+
+	/* And wait for the READY interrupt */
+	timeout = jiffies + HZ;
+
+	ints =  p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+	while (!(ints & SPI_HOST_INT_READY)) {
+		if (time_after(jiffies, timeout))
+				goto out;
+		ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+	}
+
+	p54spi_int_ack(priv, SPI_HOST_INT_READY);
+
+out:
+	return;
+}
+
+static inline void p54spi_sleep(struct p54s_priv *priv)
+{
+	p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
+		       cpu_to_le32(SPI_TARGET_INT_SLEEP));
+}
+
+static void p54spi_int_ready(struct p54s_priv *priv)
+{
+	p54spi_write32(priv, SPI_ADRS_HOST_INT_EN, cpu_to_le32(
+		       SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE));
+
+	switch (priv->fw_state) {
+	case FW_STATE_BOOTING:
+		priv->fw_state = FW_STATE_READY;
+		complete(&priv->fw_comp);
+		break;
+	case FW_STATE_RESETTING:
+		priv->fw_state = FW_STATE_READY;
+		/* TODO: reinitialize state */
+		break;
+	default:
+		break;
+	}
+}
+
+static int p54spi_rx(struct p54s_priv *priv)
+{
+	struct sk_buff *skb;
+	u16 len;
+
+	p54spi_wakeup(priv);
+
+	/* dummy read to flush SPI DMA controller bug */
+	p54spi_read16(priv, SPI_ADRS_GEN_PURP_1);
+
+	len = p54spi_read16(priv, SPI_ADRS_DMA_DATA);
+
+	if (len == 0) {
+		dev_err(&priv->spi->dev, "rx request of zero bytes");
+		return 0;
+	}
+
+	skb = dev_alloc_skb(len);
+	if (!skb) {
+		dev_err(&priv->spi->dev, "could not alloc skb");
+		return 0;
+	}
+
+	p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+	p54spi_sleep(priv);
+
+	if (p54_rx(priv->hw, skb) == 0)
+		dev_kfree_skb(skb);
+
+	return 0;
+}
+
+
+static irqreturn_t p54spi_interrupt(int irq, void *config)
+{
+	struct spi_device *spi = config;
+	struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+	queue_work(priv->hw->workqueue, &priv->work);
+
+	return IRQ_HANDLED;
+}
+
+static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+	struct p54s_dma_regs dma_regs;
+	unsigned long timeout;
+	int ret = 0;
+	u32 ints;
+
+	p54spi_wakeup(priv);
+
+	dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE);
+	dma_regs.len = cpu_to_le16(skb->len);
+	dma_regs.addr = hdr->req_id;
+
+	p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
+			   sizeof(dma_regs));
+
+	p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len);
+
+	timeout = jiffies + 2 * HZ;
+	ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+	while (!(ints & SPI_HOST_INT_WR_READY)) {
+		if (time_after(jiffies, timeout)) {
+			dev_err(&priv->spi->dev, "WR_READY timeout");
+			ret = -1;
+			goto out;
+		}
+		ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+	}
+
+	p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
+	p54spi_sleep(priv);
+
+out:
+	if (FREE_AFTER_TX(skb))
+		p54_free_skb(priv->hw, skb);
+	return ret;
+}
+
+static int p54spi_wq_tx(struct p54s_priv *priv)
+{
+	struct p54s_tx_info *entry;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *info;
+	struct p54_tx_info *minfo;
+	struct p54s_tx_info *dinfo;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&priv->tx_lock, flags);
+
+	while (!list_empty(&priv->tx_pending)) {
+		entry = list_entry(priv->tx_pending.next,
+				   struct p54s_tx_info, tx_list);
+
+		list_del_init(&entry->tx_list);
+
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+		dinfo = container_of((void *) entry, struct p54s_tx_info,
+				     tx_list);
+		minfo = container_of((void *) dinfo, struct p54_tx_info,
+				     data);
+		info = container_of((void *) minfo, struct ieee80211_tx_info,
+				    rate_driver_data);
+		skb = container_of((void *) info, struct sk_buff, cb);
+
+		ret = p54spi_tx_frame(priv, skb);
+
+		if (ret < 0) {
+			p54_free_skb(priv->hw, skb);
+			return ret;
+		}
+
+		spin_lock_irqsave(&priv->tx_lock, flags);
+	}
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+	return ret;
+}
+
+static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+	struct p54s_priv *priv = dev->priv;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data;
+	struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data;
+	unsigned long flags;
+
+	BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data)));
+
+	spin_lock_irqsave(&priv->tx_lock, flags);
+	list_add_tail(&di->tx_list, &priv->tx_pending);
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+	queue_work(priv->hw->workqueue, &priv->work);
+}
+
+static void p54spi_work(struct work_struct *work)
+{
+	struct p54s_priv *priv = container_of(work, struct p54s_priv, work);
+	u32 ints;
+	int ret;
+
+	mutex_lock(&priv->mutex);
+
+	if (priv->fw_state == FW_STATE_OFF &&
+	    priv->fw_state == FW_STATE_RESET)
+		goto out;
+
+	ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+	if (ints & SPI_HOST_INT_READY) {
+		p54spi_int_ready(priv);
+		p54spi_int_ack(priv, SPI_HOST_INT_READY);
+	}
+
+	if (priv->fw_state != FW_STATE_READY)
+		goto out;
+
+	if (ints & SPI_HOST_INT_UPDATE) {
+		p54spi_int_ack(priv, SPI_HOST_INT_UPDATE);
+		ret = p54spi_rx(priv);
+		if (ret < 0)
+			goto out;
+	}
+	if (ints & SPI_HOST_INT_SW_UPDATE) {
+		p54spi_int_ack(priv, SPI_HOST_INT_SW_UPDATE);
+		ret = p54spi_rx(priv);
+		if (ret < 0)
+			goto out;
+	}
+
+	ret = p54spi_wq_tx(priv);
+	if (ret < 0)
+		goto out;
+
+	ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+out:
+	mutex_unlock(&priv->mutex);
+}
+
+static int p54spi_op_start(struct ieee80211_hw *dev)
+{
+	struct p54s_priv *priv = dev->priv;
+	unsigned long timeout;
+	int ret = 0;
+
+	if (mutex_lock_interruptible(&priv->mutex)) {
+		ret = -EINTR;
+		goto out;
+	}
+
+	priv->fw_state = FW_STATE_BOOTING;
+
+	p54spi_power_on(priv);
+
+	ret = p54spi_upload_firmware(dev);
+	if (ret < 0) {
+		p54spi_power_off(priv);
+		goto out_unlock;
+	}
+
+	mutex_unlock(&priv->mutex);
+
+	timeout = msecs_to_jiffies(2000);
+	timeout = wait_for_completion_interruptible_timeout(&priv->fw_comp,
+							    timeout);
+	if (!timeout) {
+		dev_err(&priv->spi->dev, "firmware boot failed");
+		p54spi_power_off(priv);
+		ret = -1;
+		goto out;
+	}
+
+	if (mutex_lock_interruptible(&priv->mutex)) {
+		ret = -EINTR;
+		p54spi_power_off(priv);
+		goto out;
+	}
+
+	WARN_ON(priv->fw_state != FW_STATE_READY);
+
+out_unlock:
+	mutex_unlock(&priv->mutex);
+
+out:
+	return ret;
+}
+
+static void p54spi_op_stop(struct ieee80211_hw *dev)
+{
+	struct p54s_priv *priv = dev->priv;
+	unsigned long flags;
+
+	if (mutex_lock_interruptible(&priv->mutex)) {
+		/* FIXME: how to handle this error? */
+		return;
+	}
+
+	WARN_ON(priv->fw_state != FW_STATE_READY);
+
+	cancel_work_sync(&priv->work);
+
+	p54spi_power_off(priv);
+	spin_lock_irqsave(&priv->tx_lock, flags);
+	INIT_LIST_HEAD(&priv->tx_pending);
+	spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+	priv->fw_state = FW_STATE_OFF;
+	mutex_unlock(&priv->mutex);
+}
+
+static int __devinit p54spi_probe(struct spi_device *spi)
+{
+	struct p54s_priv *priv = NULL;
+	struct ieee80211_hw *hw;
+	int ret = -EINVAL;
+
+	hw = p54_init_common(sizeof(*priv));
+	if (!hw) {
+		dev_err(&priv->spi->dev, "could not alloc ieee80211_hw");
+		return -ENOMEM;
+	}
+
+	priv = hw->priv;
+	priv->hw = hw;
+	dev_set_drvdata(&spi->dev, priv);
+	priv->spi = spi;
+
+	spi->bits_per_word = 16;
+	spi->max_speed_hz = 24000000;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&priv->spi->dev, "spi_setup failed");
+		goto err_free_common;
+	}
+
+	ret = gpio_request(p54spi_gpio_power, "p54spi power");
+	if (ret < 0) {
+		dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+		goto err_free_common;
+	}
+
+	ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
+	if (ret < 0) {
+		dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
+		goto err_free_common;
+	}
+
+	gpio_direction_output(p54spi_gpio_power, 0);
+	gpio_direction_input(p54spi_gpio_irq);
+
+	ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
+			  p54spi_interrupt, IRQF_DISABLED, "p54spi",
+			  priv->spi);
+	if (ret < 0) {
+		dev_err(&priv->spi->dev, "request_irq() failed");
+		goto err_free_common;
+	}
+
+	set_irq_type(gpio_to_irq(p54spi_gpio_irq),
+		     IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+	INIT_WORK(&priv->work, p54spi_work);
+	init_completion(&priv->fw_comp);
+	INIT_LIST_HEAD(&priv->tx_pending);
+	mutex_init(&priv->mutex);
+	SET_IEEE80211_DEV(hw, &spi->dev);
+	priv->common.open = p54spi_op_start;
+	priv->common.stop = p54spi_op_stop;
+	priv->common.tx = p54spi_op_tx;
+
+	ret = p54spi_reject_firmware(hw);
+	if (ret < 0)
+		goto err_free_common;
+
+	ret = p54spi_request_eeprom(hw);
+	if (ret)
+		goto err_free_common;
+
+	ret = p54_register_common(hw, &priv->spi->dev);
+	if (ret)
+		goto err_free_common;
+
+	return 0;
+
+err_free_common:
+	p54_free_common(priv->hw);
+	return ret;
+}
+
+static int __devexit p54spi_remove(struct spi_device *spi)
+{
+	struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+	ieee80211_unregister_hw(priv->hw);
+
+	free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+
+	gpio_free(p54spi_gpio_power);
+	gpio_free(p54spi_gpio_irq);
+	release_firmware(priv->firmware);
+
+	mutex_destroy(&priv->mutex);
+
+	p54_free_common(priv->hw);
+	ieee80211_free_hw(priv->hw);
+
+	return 0;
+}
+
+
+static struct spi_driver p54spi_driver = {
+	.driver = {
+		/* use cx3110x name because board-n800.c uses that for the
+		 * SPI port */
+		.name		= "cx3110x",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= p54spi_probe,
+	.remove		= __devexit_p(p54spi_remove),
+};
+
+static int __init p54spi_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&p54spi_driver);
+	if (ret < 0) {
+		printk(KERN_ERR "failed to register SPI driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit p54spi_exit(void)
+{
+	spi_unregister_driver(&p54spi_driver);
+}
+
+module_init(p54spi_init);
+module_exit(p54spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi_eeprom.h linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi_eeprom.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi_eeprom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi_eeprom.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2003 Conexant Americas Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2005, 2006 Nokia Corporation
+ * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * based on:
+ *  - cx3110x's pda.h from Nokia
+ *  - cx3110-transfer.log by Johannes Berg
+ *
+ * This program is free software; you can 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 P54SPI_EEPROM_H
+#define P54SPI_EEPROM_H
+
+static unsigned char p54spi_eeprom[] = {
+
+/* struct eeprom_pda_wrap */
+0x47, 0x4d, 0x55, 0xaa,	/* magic */
+0x00, 0x00,		/* pad */
+0x00, 0x00,		/* eeprom_pda_data_wrap length */
+0x00, 0x00, 0x00, 0x00,	/* arm opcode */
+
+/* bogus MAC address */
+0x04, 0x00, 0x01, 0x01,		/* PDR_MAC_ADDRESS */
+	0x00, 0x02, 0xee, 0xc0, 0xff, 0xee,
+
+/* struct bootrec_exp_if */
+0x06, 0x00, 0x01, 0x10,		/* PDR_INTERFACE_LIST */
+	0x00, 0x00,			/* role */
+	0x0f, 0x00,			/* if_id */
+	0x85, 0x00,			/* variant = Longbow RF, 2GHz */
+	0x01, 0x00,			/* btm_compat */
+	0x1f, 0x00,			/* top_compat */
+
+0x03, 0x00, 0x02, 0x10,		/* PDR_HARDWARE_PLATFORM_COMPONENT_ID */
+	0x03, 0x20, 0x00, 0x43,
+
+/* struct pda_country[6] */
+0x0d, 0x00, 0x07, 0x10,		/* PDR_COUNTRY_LIST */
+	0x10, 0x00, 0x00, 0x00,
+	0x20, 0x00, 0x00, 0x00,
+	0x30, 0x00, 0x00, 0x00,
+	0x31, 0x00, 0x00, 0x00,
+	0x32, 0x00, 0x00, 0x00,
+	0x40, 0x00, 0x00, 0x00,
+
+/* struct pda_country */
+0x03, 0x00, 0x08, 0x10,		/* PDR_DEFAULT_COUNTRY */
+	0x30, 0x00, 0x00, 0x00,		/* ETSI */
+
+0x03, 0x00, 0x00, 0x11,		/* PDR_ANTENNA_GAIN */
+	0x08, 0x08, 0x08, 0x08,
+
+0x09, 0x00, 0xad, 0xde,		/* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */
+	0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+/* struct pda_custom_wrapper */
+0x10, 0x06, 0x5d, 0xb0,		/* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
+	0x0d, 0x00, 0xee, 0x00,		/* 13 entries, 238 bytes per entry */
+	0x00, 0x00, 0x16, 0x0c,		/* no offset, 3094 total len */
+		/* 2412 MHz */
+		0x6c, 0x09,
+			0x10, 0x01, 0x9a, 0x84,
+				0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a,
+				0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+				0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+			0xf0, 0x00, 0x94, 0x6c,
+				0x99, 0x82, 0x99, 0x82, 0x99, 0x82, 0x99, 0x82,
+				0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+				0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+			0xd0, 0x00, 0xaa, 0x5a,
+				0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a,
+				0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+				0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+			0xa0, 0x00, 0xf3, 0x47,
+				0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+				0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+				0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+			0x50, 0x00, 0x59, 0x36,
+				0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a,
+				0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+				0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+			0x00, 0x00, 0xe4, 0x2d,
+				0x18, 0x46, 0x18, 0x46, 0x18, 0x46, 0x18, 0x46,
+				0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+				0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2417 MHz */
+		0x71, 0x09,
+			0x10, 0x01, 0xb9, 0x83,
+				0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+				0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+				0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+			0xf0, 0x00, 0x2e, 0x6c,
+				0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+				0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+				0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+			0xd0, 0x00, 0x8d, 0x5a,
+				0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+				0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+				0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+			0xa0, 0x00, 0x0a, 0x48,
+				0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+				0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+				0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+			0x50, 0x00, 0x7c, 0x36,
+				0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+				0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+				0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+			0x00, 0x00, 0xf5, 0x2d,
+				0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+				0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+				0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2422 MHz */
+		0x76, 0x09,
+			0x10, 0x01, 0xb9, 0x83,
+				0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+				0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+				0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+			0xf0, 0x00, 0x2e, 0x6c,
+				0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+				0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+				0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+			0xd0, 0x00, 0x8d, 0x5a,
+				0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+				0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+				0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+			0xa0, 0x00, 0x0a, 0x48,
+				0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+				0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+				0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+			0x50, 0x00, 0x7c, 0x36,
+				0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+				0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+				0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+			0x00, 0x00, 0xf5, 0x2d,
+				0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+				0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+				0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2427 MHz */
+		0x7b, 0x09,
+			0x10, 0x01, 0x48, 0x83,
+				0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a,
+				0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+				0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+			0xf0, 0x00, 0xfb, 0x6b,
+				0x50, 0x82, 0x50, 0x82, 0x50, 0x82, 0x50, 0x82,
+				0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+				0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+			0xd0, 0x00, 0x7e, 0x5a,
+				0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a,
+				0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+				0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+			0xa0, 0x00, 0x15, 0x48,
+				0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e,
+				0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+				0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+			0x50, 0x00, 0x8e, 0x36,
+				0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59,
+				0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+				0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+			0x00, 0x00, 0xfe, 0x2d,
+				0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45,
+				0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+				0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2432 MHz */
+		0x80, 0x09,
+			0x10, 0x01, 0xd7, 0x82,
+				0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a,
+				0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+				0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+			0xf0, 0x00, 0xc8, 0x6b,
+				0x37, 0x82, 0x37, 0x82, 0x37, 0x82, 0x37, 0x82,
+				0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+				0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+			0xd0, 0x00, 0x6f, 0x5a,
+				0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a,
+				0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+				0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+			0xa0, 0x00, 0x20, 0x48,
+				0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d,
+				0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+				0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+			0x50, 0x00, 0x9f, 0x36,
+				0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59,
+				0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+				0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+			0x00, 0x00, 0x06, 0x2e,
+				0x74, 0x45, 0x74, 0x45, 0x74, 0x45, 0x74, 0x45,
+				0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+				0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2437 MHz */
+		0x85, 0x09,
+			0x10, 0x01, 0x67, 0x82,
+				0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a,
+				0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+				0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+			0xf0, 0x00, 0x95, 0x6b,
+				0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82,
+				0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+				0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+			0xd0, 0x00, 0x61, 0x5a,
+				0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a,
+				0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+				0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+			0xa0, 0x00, 0x2c, 0x48,
+				0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d,
+				0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+				0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+			0x50, 0x00, 0xb1, 0x36,
+				0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+				0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+				0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+			0x00, 0x00, 0x0f, 0x2e,
+				0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45,
+				0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+				0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2442 MHz */
+		0x8a, 0x09,
+			0x10, 0x01, 0xf6, 0x81,
+				0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a,
+				0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+				0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+			0xf0, 0x00, 0x62, 0x6b,
+				0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82,
+				0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+				0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+			0xd0, 0x00, 0x52, 0x5a,
+				0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79,
+				0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+				0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+			0xa0, 0x00, 0x37, 0x48,
+				0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d,
+				0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+				0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+			0x50, 0x00, 0xc2, 0x36,
+				0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59,
+				0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+				0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+			0x00, 0x00, 0x17, 0x2e,
+				0x22, 0x45, 0x22, 0x45, 0x22, 0x45, 0x22, 0x45,
+				0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+				0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2447 MHz */
+		0x8f, 0x09,
+			0x10, 0x01, 0x75, 0x83,
+				0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a,
+				0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+				0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+			0xf0, 0x00, 0x4b, 0x6c,
+				0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82,
+				0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+				0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+			0xd0, 0x00, 0xda, 0x5a,
+				0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a,
+				0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+				0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+			0xa0, 0x00, 0x6d, 0x48,
+				0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d,
+				0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+				0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+			0x50, 0x00, 0xc6, 0x36,
+				0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+				0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+				0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+			0x00, 0x00, 0x15, 0x2e,
+				0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45,
+				0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+				0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2452 MHz */
+		0x94, 0x09,
+			0x10, 0x01, 0xf4, 0x84,
+				0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a,
+				0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+				0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+			0xf0, 0x00, 0x34, 0x6d,
+				0x77, 0x82, 0x77, 0x82, 0x77, 0x82, 0x77, 0x82,
+				0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+				0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+			0xd0, 0x00, 0x62, 0x5b,
+				0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a,
+				0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+				0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+			0xa0, 0x00, 0xa2, 0x48,
+				0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e,
+				0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+				0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+			0x50, 0x00, 0xc9, 0x36,
+				0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59,
+				0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+				0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+			0x00, 0x00, 0x12, 0x2e,
+				0x57, 0x45, 0x57, 0x45, 0x57, 0x45, 0x57, 0x45,
+				0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+				0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2452 MHz */
+		0x99, 0x09,
+			0x10, 0x01, 0x74, 0x86,
+				0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a,
+				0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+				0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+			0xf0, 0x00, 0x1e, 0x6e,
+				0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82,
+				0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+				0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+			0xd0, 0x00, 0xeb, 0x5b,
+				0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a,
+				0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+				0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+			0xa0, 0x00, 0xd8, 0x48,
+				0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e,
+				0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+				0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+			0x50, 0x00, 0xcd, 0x36,
+				0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59,
+				0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+				0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+			0x00, 0x00, 0x10, 0x2e,
+				0x71, 0x45, 0x71, 0x45, 0x71, 0x45, 0x71, 0x45,
+				0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+				0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2557 MHz */
+		0x9e, 0x09,
+			0x10, 0x01, 0xf3, 0x87,
+				0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b,
+				0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+				0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+			0xf0, 0x00, 0x07, 0x6f,
+				0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82,
+				0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+				0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+			0xd0, 0x00, 0x73, 0x5c,
+				0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a,
+				0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+				0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+			0xa0, 0x00, 0x0d, 0x49,
+				0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e,
+				0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+				0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+			0x50, 0x00, 0xd1, 0x36,
+				0xff, 0x59, 0xff, 0x59, 0xff, 0x59, 0xff, 0x59,
+				0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+				0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+			0x00, 0x00, 0x0e, 0x2e,
+				0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45,
+				0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+				0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2562 MHz */
+		0xa3, 0x09,
+			0x10, 0x01, 0x72, 0x89,
+				0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b,
+				0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+				0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+			0xf0, 0x00, 0xf0, 0x6f,
+				0x21, 0x83, 0x21, 0x83, 0x21, 0x83, 0x21, 0x83,
+				0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+				0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+			0xd0, 0x00, 0xfb, 0x5c,
+				0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a,
+				0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+				0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+			0xa0, 0x00, 0x43, 0x49,
+				0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e,
+				0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+				0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+			0x50, 0x00, 0xd4, 0x36,
+				0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a,
+				0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+				0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+			0x00, 0x00, 0x0b, 0x2e,
+				0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45,
+				0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+				0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+		/* 2572 MHz */
+		0xa8, 0x09,
+			0x10, 0x01, 0xf1, 0x8a,
+				0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b,
+				0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+				0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+			0xf0, 0x00, 0xd9, 0x70,
+				0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83,
+				0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+				0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+			0xd0, 0x00, 0x83, 0x5d,
+				0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b,
+				0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+				0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+			0xa0, 0x00, 0x78, 0x49,
+				0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e,
+				0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+				0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+			0x50, 0x00, 0xd8, 0x36,
+				0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a,
+				0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+				0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+			0x00, 0x00, 0x09, 0x2e,
+				0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45,
+				0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+				0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x80, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+/*
+ * Not really sure if this is actually the power_limit database,
+ * it looks a bit "related" to PDR_PRISM_ZIF_TX_IQ_CALIBRATION
+ */
+/* struct pda_custom_wrapper */
+0xae, 0x00, 0xef, 0xbe,      /* PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM */
+	0x0d, 0x00, 0x1a, 0x00,		/* 13 entries, 26 bytes per entry */
+	0x00, 0x00, 0x52, 0x01,		/* no offset, 338 bytes total */
+
+		/* 2412 MHz */
+		0x6c, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2417 MHz */
+		0x71, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2422 MHz */
+		0x76, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2427 MHz */
+		0x7b, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2432 MHz */
+		0x80, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2437 MHz */
+		0x85, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2442 MHz */
+		0x8a, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2447 MHz */
+		0x8f, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2452 MHz */
+		0x94, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2457 MHz */
+		0x99, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2462 MHz */
+		0x9e, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2467 MHz */
+		0xa3, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+		/* 2472 MHz */
+		0xa8, 0x09,
+			0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+			0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+			0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+/* struct pda_iq_autocal_entry[13] */
+0x42, 0x00, 0x06, 0x19,		/* PDR_PRISM_ZIF_TX_IQ_CALIBRATION */
+	/* 2412 MHz */
+	0x6c, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2417 MHz */
+	0x71, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2422 MHz */
+	0x76, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2427 MHz */
+	0x7b, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2432 MHz */
+	0x80, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2437 MHz */
+	0x85, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2442 MHz */
+	0x8a, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2447 MHz */
+	0x8f, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2452 MHz */
+	0x94, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+	/* 2457 MHz */
+	0x99, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+	/* 2462 MHz */
+	0x9e, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+	/* 2467 MHz */
+	0xa3, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+	/* 2472 MHz */
+	0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+
+0x02, 0x00, 0x00, 0x00,		/* PDR_END */
+	0xa8, 0xf5			/* bogus data */
+};
+
+#endif /* P54SPI_EEPROM_H */
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi.h linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54spi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54spi.h	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * This driver is a port from stlc45xx:
+ *	Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You 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 P54SPI_H
+#define P54SPI_H
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "p54.h"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define SPI_ADRS_READ_BIT_15		0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS		0x00
+#define SPI_ADRS_ARM_INT_EN		0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS	0x08
+#define SPI_ADRS_HOST_INT_EN		0x0c
+#define SPI_ADRS_HOST_INT_ACK		0x10
+
+#define SPI_ADRS_GEN_PURP_1		0x14
+#define SPI_ADRS_GEN_PURP_2		0x18
+
+#define SPI_ADRS_DEV_CTRL_STAT		0x26    /* high word */
+
+#define SPI_ADRS_DMA_DATA		0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL		0x2c
+#define SPI_ADRS_DMA_WRITE_LEN		0x2e
+#define SPI_ADRS_DMA_WRITE_BASE		0x30
+
+#define SPI_ADRS_DMA_READ_CTRL		0x34
+#define SPI_ADRS_DMA_READ_LEN		0x36
+#define SPI_ADRS_DMA_READ_BASE		0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE	0x8000
+#define SPI_CTRL_STAT_START_HALTED	0x4000
+#define SPI_CTRL_STAT_RAM_BOOT		0x2000
+#define SPI_CTRL_STAT_HOST_RESET	0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN	0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE	0x0001
+#define SPI_DMA_READ_CTRL_ENABLE	0x0001
+#define HOST_ALLOWED			(1 << 7)
+
+#define SPI_TIMEOUT			100         /* msec */
+
+#define SPI_MAX_TX_PACKETS		32
+
+#define SPI_MAX_PACKET_SIZE		32767
+
+#define SPI_TARGET_INT_WAKEUP		0x00000001
+#define SPI_TARGET_INT_SLEEP		0x00000002
+#define SPI_TARGET_INT_RDDONE		0x00000004
+
+#define SPI_TARGET_INT_CTS		0x00004000
+#define SPI_TARGET_INT_DR		0x00008000
+
+#define SPI_HOST_INT_READY		0x00000001
+#define SPI_HOST_INT_WR_READY		0x00000002
+#define SPI_HOST_INT_SW_UPDATE		0x00000004
+#define SPI_HOST_INT_UPDATE		0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CR			0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR			0x00008000
+
+#define SPI_HOST_INTS_DEFAULT 						    \
+	(SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+struct p54s_dma_regs {
+	__le16 cmd;
+	__le16 len;
+	__le32 addr;
+} __attribute__ ((packed));
+
+struct p54s_tx_info {
+	struct list_head tx_list;
+};
+
+struct p54s_priv {
+	/* p54_common has to be the first entry */
+	struct p54_common common;
+	struct ieee80211_hw *hw;
+	struct spi_device *spi;
+
+	struct work_struct work;
+
+	struct mutex mutex;
+	struct completion fw_comp;
+
+	spinlock_t tx_lock;
+
+	/* protected by tx_lock */
+	struct list_head tx_pending;
+
+	enum fw_state fw_state;
+	const struct firmware *firmware;
+};
+
+#endif /* P54SPI_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 18:04:56.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 16:48:56.000000000 -0400
@@ -70,6 +70,7 @@ static struct usb_device_id p54u_table[]
 	{USB_DEVICE(0x1260, 0xee22)},	/* SMC 2862W-G version 2 */
 	{USB_DEVICE(0x13b1, 0x000a)},	/* Linksys WUSB54G ver 2 */
 	{USB_DEVICE(0x13B1, 0x000C)},	/* Linksys WUSB54AG */
+	{USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */
 	{USB_DEVICE(0x1435, 0x0427)},	/* Inventel UR054G */
 	{USB_DEVICE(0x2001, 0x3704)},	/* DLink DWL-G122 rev A2 */
 	{USB_DEVICE(0x413c, 0x8102)},	/* Spinnaker DUT */
@@ -423,9 +424,46 @@ static int p54u_bulk_msg(struct p54u_pri
 			    data, len, &alen, 2000);
 }
 
+static const char p54u_romboot_3887[] = "~~~~";
+static const char p54u_firmware_upload_3887[] = "<\r";
+
+static int p54u_device_reset_3887(struct ieee80211_hw *dev)
+{
+	struct p54u_priv *priv = dev->priv;
+	int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
+	u8 buf[4];
+
+	if (lock) {
+		ret = usb_lock_device_for_reset(priv->udev, priv->intf);
+		if (ret < 0) {
+			dev_err(&priv->udev->dev, "(p54usb) unable to lock "
+				" device for reset: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = usb_reset_device(priv->udev);
+	if (lock)
+		usb_unlock_device(priv->udev);
+
+	if (ret) {
+		dev_err(&priv->udev->dev, "(p54usb) unable to reset "
+			"device: %d\n", ret);
+		return ret;
+	}
+
+	memcpy(&buf, p54u_romboot_3887, sizeof(buf));
+	ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
+			    buf, sizeof(buf));
+	if (ret)
+		dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
+			"boot ROM: %d\n", ret);
+
+	return ret;
+}
+
 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
 {
-	static char start_string[] = "~~~~<\r";
 	struct p54u_priv *priv = dev->priv;
 	const struct firmware *fw_entry = NULL;
 	int err, alen;
@@ -444,12 +482,9 @@ static int p54u_upload_firmware_3887(str
 		goto err_bufalloc;
 	}
 
-	memcpy(buf, start_string, 4);
-	err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
-	if (err) {
-		dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err);
+	err = p54u_device_reset_3887(dev);
+	if (err)
 		goto err_reset;
-	}
 
 	err = reject_firmware(&fw_entry, "/*(DEBLOBBED)*/", &priv->udev->dev);
 	if (err) {
@@ -465,15 +500,22 @@ static int p54u_upload_firmware_3887(str
 	if (err)
 		goto err_upload_failed;
 
+	if (priv->common.fw_interface != FW_LM87) {
+		dev_err(&priv->udev->dev, "wrong firmware, "
+			"please get a LM87 firmware and try again.\n");
+		err = -EINVAL;
+		goto err_upload_failed;
+	}
+
 	left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
-	strcpy(buf, start_string);
-	left -= strlen(start_string);
-	tmp += strlen(start_string);
+	strcpy(buf, p54u_firmware_upload_3887);
+	left -= strlen(p54u_firmware_upload_3887);
+	tmp += strlen(p54u_firmware_upload_3887);
 
 	data = fw_entry->data;
 	remains = fw_entry->size;
 
-	hdr = (struct x2_header *)(buf + strlen(start_string));
+	hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
 	memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
 	hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
 	hdr->fw_length = cpu_to_le32(fw_entry->size);
@@ -615,6 +657,14 @@ static int p54u_upload_firmware_net2280(
 		return err;
 	}
 
+	if (priv->common.fw_interface != FW_LM86) {
+		dev_err(&priv->udev->dev, "wrong firmware, "
+			"please get a LM86(USB) firmware and try again.\n");
+		kfree(buf);
+		release_firmware(fw_entry);
+		return -EINVAL;
+	}
+
 #define P54U_WRITE(type, addr, data) \
 	do {\
 		err = p54u_write(priv, buf, type,\
@@ -875,6 +925,9 @@ static int __devinit p54u_probe(struct u
 	SET_IEEE80211_DEV(dev, &intf->dev);
 	usb_set_intfdata(intf, dev);
 	priv->udev = udev;
+	priv->intf = intf;
+	skb_queue_head_init(&priv->rx_queue);
+	init_usb_anchor(&priv->submitted);
 
 	usb_get_dev(udev);
 
@@ -917,20 +970,15 @@ static int __devinit p54u_probe(struct u
 	if (err)
 		goto err_free_dev;
 
-	skb_queue_head_init(&priv->rx_queue);
-	init_usb_anchor(&priv->submitted);
-
 	p54u_open(dev);
 	err = p54_read_eeprom(dev);
 	p54u_stop(dev);
 	if (err)
 		goto err_free_dev;
 
-	err = ieee80211_register_hw(dev);
-	if (err) {
-		dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
+	err = p54_register_common(dev, &udev->dev);
+	if (err)
 		goto err_free_dev;
-	}
 
 	return 0;
 
@@ -957,11 +1005,24 @@ static void __devexit p54u_disconnect(st
 	ieee80211_free_hw(dev);
 }
 
+static int p54u_pre_reset(struct usb_interface *intf)
+{
+	return 0;
+}
+
+static int p54u_post_reset(struct usb_interface *intf)
+{
+	return 0;
+}
+
 static struct usb_driver p54u_driver = {
 	.name	= "p54usb",
 	.id_table = p54u_table,
 	.probe = p54u_probe,
 	.disconnect = p54u_disconnect,
+	.pre_reset = p54u_pre_reset,
+	.post_reset = p54u_post_reset,
+	.soft_unbind = 1,
 };
 
 static int __init p54u_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/p54/p54usb.h	2013-05-03 18:04:58.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.h	2013-05-03 16:48:58.000000000 -0400
@@ -126,6 +126,7 @@ struct p54u_rx_info {
 struct p54u_priv {
 	struct p54_common common;
 	struct usb_device *udev;
+	struct usb_interface *intf;
 	enum {
 		P54U_NET2280 = 0,
 		P54U_3887
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/isl_ioctl.c linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/isl_ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/isl_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -2981,7 +2981,8 @@ prism54_set_spy(struct net_device *ndev,
 		union iwreq_data *uwrq, char *extra)
 {
 	islpci_private *priv = netdev_priv(ndev);
-	u32 u, oid = OID_INL_CONFIG;
+	u32 u;
+	enum oid_num_t oid = OID_INL_CONFIG;
 
 	down_write(&priv->mib_sem);
 	mgt_get(priv, OID_INL_CONFIG, &u);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_dev.c linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_dev.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 18:05:00.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_dev.c	2013-05-03 16:49:00.000000000 -0400
@@ -43,7 +43,6 @@
 
 static int prism54_bring_down(islpci_private *);
 static int islpci_alloc_memory(islpci_private *);
-static struct net_device_stats *islpci_statistics(struct net_device *);
 
 /* Temporary dummy MAC address to use until firmware is loaded.
  * The idea there is that some tools (such as nameif) may query
@@ -614,18 +613,6 @@ islpci_reset(islpci_private *priv, int r
 	return rc;
 }
 
-static struct net_device_stats *
-islpci_statistics(struct net_device *ndev)
-{
-	islpci_private *priv = netdev_priv(ndev);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
-	DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
-#endif
-
-	return &priv->statistics;
-}
-
 /******************************************************************************
     Network device configuration functions
 ******************************************************************************/
@@ -804,10 +791,21 @@ static void islpci_ethtool_get_drvinfo(s
 	strcpy(info->version, DRV_VERSION);
 }
 
-static struct ethtool_ops islpci_ethtool_ops = {
+static const struct ethtool_ops islpci_ethtool_ops = {
 	.get_drvinfo = islpci_ethtool_get_drvinfo,
 };
 
+static const struct net_device_ops islpci_netdev_ops = {
+	.ndo_open 		= islpci_open,
+	.ndo_stop		= islpci_close,
+	.ndo_do_ioctl		= prism54_ioctl,
+	.ndo_start_xmit		= islpci_eth_transmit,
+	.ndo_tx_timeout		= islpci_eth_tx_timeout,
+	.ndo_set_mac_address 	= prism54_set_mac_address,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 struct net_device *
 islpci_setup(struct pci_dev *pdev)
 {
@@ -827,25 +825,16 @@ islpci_setup(struct pci_dev *pdev)
 	ndev->irq = pdev->irq;
 
 	/* initialize the function pointers */
-	ndev->open = &islpci_open;
-	ndev->stop = &islpci_close;
-	ndev->get_stats = &islpci_statistics;
-	ndev->do_ioctl = &prism54_ioctl;
-	ndev->wireless_handlers =
-	    (struct iw_handler_def *) &prism54_handler_def;
+	ndev->netdev_ops = &islpci_netdev_ops;
+	ndev->wireless_handlers = &prism54_handler_def;
 	ndev->ethtool_ops = &islpci_ethtool_ops;
 
-	ndev->hard_start_xmit = &islpci_eth_transmit;
 	/* ndev->set_multicast_list = &islpci_set_multicast_list; */
 	ndev->addr_len = ETH_ALEN;
-	ndev->set_mac_address = &prism54_set_mac_address;
 	/* Get a non-zero dummy MAC address for nameif. Jean II */
 	memcpy(ndev->dev_addr, dummy_mac, 6);
 
-#ifdef HAVE_TX_TIMEOUT
 	ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
-	ndev->tx_timeout = &islpci_eth_tx_timeout;
-#endif
 
 	/* allocate a private device structure to the network device  */
 	priv = netdev_priv(ndev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_dev.h linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_dev.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_dev.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_dev.h	2009-06-09 23:05:27.000000000 -0400
@@ -158,9 +158,6 @@ typedef struct {
 	dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
 	dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
 
-	/* driver network interface members */
-	struct net_device_stats statistics;
-
 	/* wait for a reset interrupt */
 	wait_queue_head_t reset_done;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_eth.c linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_eth.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_eth.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_eth.c	2009-06-09 23:05:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <asm/byteorder.h>
 
 #include "prismcompat.h"
 #include "isl_38xx.h"
@@ -230,8 +231,8 @@ islpci_eth_transmit(struct sk_buff *skb,
 
 	/* set the transmission time */
 	ndev->trans_start = jiffies;
-	priv->statistics.tx_packets++;
-	priv->statistics.tx_bytes += skb->len;
+	ndev->stats.tx_packets++;
+	ndev->stats.tx_bytes += skb->len;
 
 	/* trigger the device */
 	islpci_trigger(priv);
@@ -242,7 +243,7 @@ islpci_eth_transmit(struct sk_buff *skb,
 	return 0;
 
       drop_free:
-	priv->statistics.tx_dropped++;
+	ndev->stats.tx_dropped++;
 	spin_unlock_irqrestore(&priv->slock, flags);
 	dev_kfree_skb(skb);
 	return err;
@@ -407,8 +408,8 @@ islpci_eth_receive(islpci_private *priv)
 		skb->protocol = eth_type_trans(skb, ndev);
 	}
 	skb->ip_summed = CHECKSUM_NONE;
-	priv->statistics.rx_packets++;
-	priv->statistics.rx_bytes += size;
+	ndev->stats.rx_packets++;
+	ndev->stats.rx_bytes += size;
 
 	/* deliver the skb to the network layer */
 #ifdef ISLPCI_ETH_DEBUG
@@ -471,8 +472,8 @@ islpci_eth_receive(islpci_private *priv)
 		wmb();
 
 		/* increment the driver read pointer */
-		add_le32p(&control_block->
-			  driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
+		le32_add_cpu(&control_block->
+			     driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
 	}
 
 	/* trigger the device */
@@ -496,10 +497,9 @@ void
 islpci_eth_tx_timeout(struct net_device *ndev)
 {
 	islpci_private *priv = netdev_priv(ndev);
-	struct net_device_stats *statistics = &priv->statistics;
 
 	/* increment the transmit error counter */
-	statistics->tx_errors++;
+	ndev->stats.tx_errors++;
 
 	if (!priv->reset_task_pending) {
 		printk(KERN_WARNING
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_hotplug.c	2009-06-09 23:05:27.000000000 -0400
@@ -120,7 +120,7 @@ prism54_probe(struct pci_dev *pdev, cons
 	}
 
 	/* enable PCI DMA */
-	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
 		goto do_pci_disable_device;
         }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_mgt.h linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_mgt.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/islpci_mgt.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/islpci_mgt.h	2009-06-09 23:05:27.000000000 -0400
@@ -85,12 +85,6 @@ extern int pc_debug;
 #define PIMFOR_FLAG_APPLIC_ORIGIN               0x01
 #define PIMFOR_FLAG_LITTLE_ENDIAN               0x02
 
-static inline void
-add_le32p(__le32 * le_number, u32 add)
-{
-	*le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
-}
-
 void display_buffer(char *, int);
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/oid_mgt.c linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/oid_mgt.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/prism54/oid_mgt.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/prism54/oid_mgt.c	2009-06-09 23:05:27.000000000 -0400
@@ -698,7 +698,7 @@ int
 mgt_commit(islpci_private *priv)
 {
 	int rvalue;
-	u32 u;
+	enum oid_num_t u;
 
 	if (islpci_get_state(priv) < PRV_STATE_INIT)
 		return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/ray_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/ray_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/ray_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/ray_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@
  * Copyright (c) 1998  Corey Thomas (corey@world.std.com)
  *
  * This driver is free software; you can redistribute it and/or modify
- * it under the terms of version 2 only of the GNU General Public License as 
+ * it under the terms of version 2 only of the GNU General Public License as
  * published by the Free Software Foundation.
  *
  * It is distributed in the hope that it will be useful,
@@ -27,7 +27,7 @@
  *
  * Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
  * - Audit copy_to_user in ioctl(SIOCGIWESSID)
- * 
+ *
 =============================================================================*/
 
 #include <linux/module.h>
@@ -65,8 +65,8 @@
 /* Warning : these stuff will slow down the driver... */
 #define WIRELESS_SPY		/* Enable spying addresses */
 /* Definitions we need for spy */
-typedef struct iw_statistics	iw_stats;
-typedef u_char	mac_addr[ETH_ALEN];	/* Hardware address */
+typedef struct iw_statistics iw_stats;
+typedef u_char mac_addr[ETH_ALEN];	/* Hardware address */
 
 #include "rayctl.h"
 #include "ray_cs.h"
@@ -86,7 +86,7 @@ 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);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
 #else
 #define DEBUG(n, args...)
 #endif
@@ -108,12 +108,12 @@ static int ray_dev_start_xmit(struct sk_
 static void set_multicast_list(struct net_device *dev);
 static void ray_update_multi_list(struct net_device *dev, int all);
 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
-                unsigned char *data, int len);
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
-                unsigned char *data);
+			   unsigned char *data, int len);
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+			     UCHAR msg_type, unsigned char *data);
 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
-static iw_stats * ray_get_wireless_stats(struct net_device *	dev);
-static const struct iw_handler_def	ray_handler_def;
+static iw_stats *ray_get_wireless_stats(struct net_device *dev);
+static const struct iw_handler_def ray_handler_def;
 
 /***** Prototypes for raylink functions **************************************/
 static int asc_to_int(char a);
@@ -124,7 +124,7 @@ static int get_free_ccs(ray_dev_t *local
 static int get_free_tx_ccs(ray_dev_t *local);
 static void init_startup_params(ray_dev_t *local);
 static int parse_addr(char *in_str, UCHAR *out);
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, UCHAR type);
 static int ray_init(struct net_device *dev);
 static int interrupt_ecf(ray_dev_t *local, int ccs);
 static void ray_reset(struct net_device *dev);
@@ -132,17 +132,17 @@ static void ray_update_parm(struct net_d
 static void verify_dl_startup(u_long);
 
 /* Prototypes for interrpt time functions **********************************/
-static irqreturn_t ray_interrupt (int reg, void *dev_id);
+static irqreturn_t ray_interrupt(int reg, void *dev_id);
 static void clear_interrupt(ray_dev_t *local);
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, 
-                       unsigned int pkt_addr, int rx_len);
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+			      unsigned int pkt_addr, int rx_len);
 static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
 static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
 static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
 static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
-                     unsigned int pkt_addr, int rx_len);
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr, 
-             int rx_len);
+			    unsigned int pkt_addr, int rx_len);
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+		    unsigned int pkt_addr, int rx_len);
 static void associate(ray_dev_t *local);
 
 /* Card command functions */
@@ -219,82 +219,97 @@ module_param(phy_addr, charp, 0);
 module_param(ray_mem_speed, int, 0);
 
 static UCHAR b5_default_startup_parms[] = {
-    0,   0,                         /* Adhoc station */
-   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */
-    0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,
-    1,  0,                          /* Active scan, CA Mode */
-    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */
-    0x7f, 0xff,                     /* Frag threshold */
-    0x00, 0x80,                     /* Hop time 128 Kus*/
-    0x01, 0x00,                     /* Beacon period 256 Kus */
-    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/
-    0x1d, 0x82, 0x4e,               /* SIFS, DIFS, PIFS */
-    0x7f, 0xff,                     /* RTS threshold */
-    0x04, 0xe2, 0x38, 0xA4,         /* scan_dwell, max_scan_dwell */
-    0x05,                           /* assoc resp timeout thresh */
-    0x08, 0x02, 0x08,               /* adhoc, infra, super cycle max*/
-    0,                              /* Promiscuous mode */
-    0x0c, 0x0bd,                    /* Unique word */
-    0x32,                           /* Slot time */
-    0xff, 0xff,                     /* roam-low snr, low snr count */
-    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */
-    0x01, 0x0b, 0x4f,               /* USA, hop pattern, hop pat length */
+	0, 0,			/* Adhoc station */
+	'L', 'I', 'N', 'U', 'X', 0, 0, 0,	/* 32 char ESSID */
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 0,			/* Active scan, CA Mode */
+	0, 0, 0, 0, 0, 0,	/* No default MAC addr  */
+	0x7f, 0xff,		/* Frag threshold */
+	0x00, 0x80,		/* Hop time 128 Kus */
+	0x01, 0x00,		/* Beacon period 256 Kus */
+	0x01, 0x07, 0xa3,	/* DTIM, retries, ack timeout */
+	0x1d, 0x82, 0x4e,	/* SIFS, DIFS, PIFS */
+	0x7f, 0xff,		/* RTS threshold */
+	0x04, 0xe2, 0x38, 0xA4,	/* scan_dwell, max_scan_dwell */
+	0x05,			/* assoc resp timeout thresh */
+	0x08, 0x02, 0x08,	/* adhoc, infra, super cycle max */
+	0,			/* Promiscuous mode */
+	0x0c, 0x0bd,		/* Unique word */
+	0x32,			/* Slot time */
+	0xff, 0xff,		/* roam-low snr, low snr count */
+	0x05, 0xff,		/* Infra, adhoc missed bcn thresh */
+	0x01, 0x0b, 0x4f,	/* USA, hop pattern, hop pat length */
 /* b4 - b5 differences start here */
-    0x00, 0x3f,                     /* CW max */
-    0x00, 0x0f,                     /* CW min */
-    0x04, 0x08,                     /* Noise gain, limit offset */
-    0x28, 0x28,                     /* det rssi, med busy offsets */
-    7,                              /* det sync thresh */
-    0, 2, 2,                        /* test mode, min, max */
-    0,                              /* allow broadcast SSID probe resp */
-    0, 0,                           /* privacy must start, can join */
-    2, 0, 0, 0, 0, 0, 0, 0          /* basic rate set */
+	0x00, 0x3f,		/* CW max */
+	0x00, 0x0f,		/* CW min */
+	0x04, 0x08,		/* Noise gain, limit offset */
+	0x28, 0x28,		/* det rssi, med busy offsets */
+	7,			/* det sync thresh */
+	0, 2, 2,		/* test mode, min, max */
+	0,			/* allow broadcast SSID probe resp */
+	0, 0,			/* privacy must start, can join */
+	2, 0, 0, 0, 0, 0, 0, 0	/* basic rate set */
 };
 
 static UCHAR b4_default_startup_parms[] = {
-    0,   0,                         /* Adhoc station */
-   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */
-    0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,
-    1,  0,                          /* Active scan, CA Mode */
-    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */
-    0x7f, 0xff,                     /* Frag threshold */
-    0x02, 0x00,                     /* Hop time */
-    0x00, 0x01,                     /* Beacon period */
-    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/
-    0x1d, 0x82, 0xce,               /* SIFS, DIFS, PIFS */
-    0x7f, 0xff,                     /* RTS threshold */
-    0xfb, 0x1e, 0xc7, 0x5c,         /* scan_dwell, max_scan_dwell */
-    0x05,                           /* assoc resp timeout thresh */
-    0x04, 0x02, 0x4,                /* adhoc, infra, super cycle max*/
-    0,                              /* Promiscuous mode */
-    0x0c, 0x0bd,                    /* Unique word */
-    0x4e,                           /* Slot time (TBD seems wrong)*/
-    0xff, 0xff,                     /* roam-low snr, low snr count */
-    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */
-    0x01, 0x0b, 0x4e,               /* USA, hop pattern, hop pat length */
+	0, 0,			/* Adhoc station */
+	'L', 'I', 'N', 'U', 'X', 0, 0, 0,	/* 32 char ESSID */
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 0,			/* Active scan, CA Mode */
+	0, 0, 0, 0, 0, 0,	/* No default MAC addr  */
+	0x7f, 0xff,		/* Frag threshold */
+	0x02, 0x00,		/* Hop time */
+	0x00, 0x01,		/* Beacon period */
+	0x01, 0x07, 0xa3,	/* DTIM, retries, ack timeout */
+	0x1d, 0x82, 0xce,	/* SIFS, DIFS, PIFS */
+	0x7f, 0xff,		/* RTS threshold */
+	0xfb, 0x1e, 0xc7, 0x5c,	/* scan_dwell, max_scan_dwell */
+	0x05,			/* assoc resp timeout thresh */
+	0x04, 0x02, 0x4,	/* adhoc, infra, super cycle max */
+	0,			/* Promiscuous mode */
+	0x0c, 0x0bd,		/* Unique word */
+	0x4e,			/* Slot time (TBD seems wrong) */
+	0xff, 0xff,		/* roam-low snr, low snr count */
+	0x05, 0xff,		/* Infra, adhoc missed bcn thresh */
+	0x01, 0x0b, 0x4e,	/* USA, hop pattern, hop pat length */
 /* b4 - b5 differences start here */
-    0x3f, 0x0f,                     /* CW max, min */
-    0x04, 0x08,                     /* Noise gain, limit offset */
-    0x28, 0x28,                     /* det rssi, med busy offsets */
-    7,                              /* det sync thresh */
-    0, 2, 2                         /* test mode, min, max*/
+	0x3f, 0x0f,		/* CW max, min */
+	0x04, 0x08,		/* Noise gain, limit offset */
+	0x28, 0x28,		/* det rssi, med busy offsets */
+	7,			/* det sync thresh */
+	0, 2, 2			/* test mode, min, max */
 };
+
 /*===========================================================================*/
-static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
+static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
 
 static char hop_pattern_length[] = { 1,
-	     USA_HOP_MOD,             EUROPE_HOP_MOD,
-	     JAPAN_HOP_MOD,           KOREA_HOP_MOD,
-	     SPAIN_HOP_MOD,           FRANCE_HOP_MOD,
-	     ISRAEL_HOP_MOD,          AUSTRALIA_HOP_MOD,
-	     JAPAN_TEST_HOP_MOD
+	USA_HOP_MOD, EUROPE_HOP_MOD,
+	JAPAN_HOP_MOD, KOREA_HOP_MOD,
+	SPAIN_HOP_MOD, FRANCE_HOP_MOD,
+	ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
+	JAPAN_TEST_HOP_MOD
 };
 
-static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+static char rcsid[] =
+    "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+
+static const struct net_device_ops ray_netdev_ops = {
+	.ndo_init 		= ray_dev_init,
+	.ndo_open 		= ray_open,
+	.ndo_stop 		= ray_dev_close,
+	.ndo_start_xmit		= ray_dev_start_xmit,
+	.ndo_set_config		= ray_dev_config,
+	.ndo_get_stats		= ray_get_stats,
+	.ndo_set_multicast_list = set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
 
 /*=============================================================================
     ray_attach() creates an "instance" of the driver, allocating
@@ -306,71 +321,66 @@ static char rcsid[] = "Raylink/WebGear w
 =============================================================================*/
 static int ray_probe(struct pcmcia_device *p_dev)
 {
-    ray_dev_t *local;
-    struct net_device *dev;
+	ray_dev_t *local;
+	struct net_device *dev;
 
-    DEBUG(1, "ray_attach()\n");
+	DEBUG(1, "ray_attach()\n");
 
-    /* Allocate space for private device-specific data */
-    dev = alloc_etherdev(sizeof(ray_dev_t));
-    if (!dev)
-	    goto fail_alloc_dev;
+	/* Allocate space for private device-specific data */
+	dev = alloc_etherdev(sizeof(ray_dev_t));
+	if (!dev)
+		goto fail_alloc_dev;
 
-    local = netdev_priv(dev);
-    local->finder = p_dev;
+	local = netdev_priv(dev);
+	local->finder = p_dev;
 
-    /* The io structure describes IO port mapping. None used here */
-    p_dev->io.NumPorts1 = 0;
-    p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    p_dev->io.IOAddrLines = 5;
+	/* The io structure describes IO port mapping. None used here */
+	p_dev->io.NumPorts1 = 0;
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+	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.Handler = &ray_interrupt;
+	/* 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.Handler = &ray_interrupt;
 
-    /* General socket configuration */
-    p_dev->conf.Attributes = CONF_ENABLE_IRQ;
-    p_dev->conf.IntType = INT_MEMORY_AND_IO;
-    p_dev->conf.ConfigIndex = 1;
+	/* General socket configuration */
+	p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+	p_dev->conf.IntType = INT_MEMORY_AND_IO;
+	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",
-          p_dev,dev,local,&ray_interrupt);
+	p_dev->priv = dev;
+	p_dev->irq.Instance = dev;
 
-    /* Raylink entries in the device structure */
-    dev->hard_start_xmit = &ray_dev_start_xmit;
-    dev->set_config = &ray_dev_config;
-    dev->get_stats  = &ray_get_stats;
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    dev->wireless_handlers = &ray_handler_def;
+	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",
+	      p_dev, dev, local, &ray_interrupt);
+
+	/* Raylink entries in the device structure */
+	dev->netdev_ops = &ray_netdev_ops;
+	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+	dev->wireless_handlers = &ray_handler_def;
 #ifdef WIRELESS_SPY
-    local->wireless_data.spy_data = &local->spy_data;
-    dev->wireless_data = &local->wireless_data;
-#endif	/* WIRELESS_SPY */
+	local->wireless_data.spy_data = &local->spy_data;
+	dev->wireless_data = &local->wireless_data;
+#endif /* WIRELESS_SPY */
 
-    dev->set_multicast_list = &set_multicast_list;
 
-    DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
-    dev->init = &ray_dev_init;
-    dev->open = &ray_open;
-    dev->stop = &ray_dev_close;
-    netif_stop_queue(dev);
+	DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+	netif_stop_queue(dev);
 
-    init_timer(&local->timer);
+	init_timer(&local->timer);
 
-    this_device = p_dev;
-    return ray_config(p_dev);
+	this_device = p_dev;
+	return ray_config(p_dev);
 
 fail_alloc_dev:
-    return -ENOMEM;
+	return -ENOMEM;
 } /* ray_attach */
+
 /*=============================================================================
     This deletes a driver "instance".  The device is de-registered
     with Card Services.  If it has been released, all local data
@@ -379,25 +389,27 @@ fail_alloc_dev:
 =============================================================================*/
 static void ray_detach(struct pcmcia_device *link)
 {
-    struct net_device *dev;
-    ray_dev_t *local;
+	struct net_device *dev;
+	ray_dev_t *local;
 
-    DEBUG(1, "ray_detach(0x%p)\n", link);
+	DEBUG(1, "ray_detach(0x%p)\n", link);
 
-    this_device = NULL;
-    dev = link->priv;
+	this_device = NULL;
+	dev = link->priv;
 
-    ray_release(link);
+	ray_release(link);
 
-    local = netdev_priv(dev);
-    del_timer(&local->timer);
+	local = netdev_priv(dev);
+	del_timer(&local->timer);
 
-    if (link->priv) {
-	if (link->dev_node) unregister_netdev(dev);
-        free_netdev(dev);
-    }
-    DEBUG(2,"ray_cs ray_detach ending\n");
+	if (link->priv) {
+		if (link->dev_node)
+			unregister_netdev(dev);
+		free_netdev(dev);
+	}
+	DEBUG(2, "ray_cs ray_detach ending\n");
 } /* ray_detach */
+
 /*=============================================================================
     ray_config() is run after a CARD_INSERTION event
     is received, to configure the PCMCIA socket, and to make the
@@ -408,92 +420,101 @@ do { last_fn = (fn); if ((last_ret = (re
 #define MAX_TUPLE_SIZE 128
 static int ray_config(struct pcmcia_device *link)
 {
-    int last_fn = 0, last_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);
+	int last_fn = 0, last_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);
+	DEBUG(1, "ray_config(0x%p)\n", link);
 
-    /* Determine card type and firmware version */
-    printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
-	   link->prod_id[0] ? link->prod_id[0] : " ",
-	   link->prod_id[1] ? link->prod_id[1] : " ",
-	   link->prod_id[2] ? link->prod_id[2] : " ",
-	   link->prod_id[3] ? link->prod_id[3] : " ");
+	/* Determine card type and firmware version */
+	printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
+	       link->prod_id[0] ? link->prod_id[0] : " ",
+	       link->prod_id[1] ? link->prod_id[1] : " ",
+	       link->prod_id[2] ? link->prod_id[2] : " ",
+	       link->prod_id[3] ? link->prod_id[3] : " ");
 
-    /* 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));
-    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));
+	/* 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));
+	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));
 
 /*** Set up 32k window for shared memory (transmit and control) ************/
-    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
-    req.Base = 0;
-    req.Size = 0x8000;
-    req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
-    mem.CardOffset = 0x0000; mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
-    local->sram = ioremap(req.Base,req.Size);
+	req.Attributes =
+	    WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+	req.Base = 0;
+	req.Size = 0x8000;
+	req.AccessSpeed = ray_mem_speed;
+	CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+	mem.CardOffset = 0x0000;
+	mem.Page = 0;
+	CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+	local->sram = ioremap(req.Base, req.Size);
 
 /*** Set up 16k window for shared memory (receive buffer) ***************/
-    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
-    req.Base = 0;
-    req.Size = 0x4000;
-    req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
-    mem.CardOffset = 0x8000; mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
-    local->rmem = ioremap(req.Base,req.Size);
+	req.Attributes =
+	    WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+	req.Base = 0;
+	req.Size = 0x4000;
+	req.AccessSpeed = ray_mem_speed;
+	CS_CHECK(RequestWindow,
+		 pcmcia_request_window(&link, &req, &local->rmem_handle));
+	mem.CardOffset = 0x8000;
+	mem.Page = 0;
+	CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+	local->rmem = ioremap(req.Base, req.Size);
 
 /*** Set up window for attribute memory ***********************************/
-    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
-    req.Base = 0;
-    req.Size = 0x1000;
-    req.AccessSpeed = ray_mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
-    mem.CardOffset = 0x0000; mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
-    local->amem = ioremap(req.Base,req.Size);
+	req.Attributes =
+	    WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
+	req.Base = 0;
+	req.Size = 0x1000;
+	req.AccessSpeed = ray_mem_speed;
+	CS_CHECK(RequestWindow,
+		 pcmcia_request_window(&link, &req, &local->amem_handle));
+	mem.CardOffset = 0x0000;
+	mem.Page = 0;
+	CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+	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);
-    if (ray_init(dev) < 0) {
-        ray_release(link);
-        return -ENODEV;
-    }
+	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);
+	if (ray_init(dev) < 0) {
+		ray_release(link);
+		return -ENODEV;
+	}
 
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
-    i = register_netdev(dev);
-    if (i != 0) {
-        printk("ray_config register_netdev() failed\n");
-        ray_release(link);
-        return i;
-    }
+	SET_NETDEV_DEV(dev, &handle_to_dev(link));
+	i = register_netdev(dev);
+	if (i != 0) {
+		printk("ray_config register_netdev() failed\n");
+		ray_release(link);
+		return i;
+	}
 
-    strcpy(local->node.dev_name, dev->name);
-    link->dev_node = &local->node;
+	strcpy(local->node.dev_name, dev->name);
+	link->dev_node = &local->node;
 
-    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
-       dev->name, dev->irq, dev->dev_addr);
+	printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
+	       dev->name, dev->irq, dev->dev_addr);
 
-    return 0;
+	return 0;
 
 cs_failed:
-    cs_error(link, last_fn, last_ret);
+	cs_error(link, last_fn, last_ret);
 
-    ray_release(link);
-    return -ENODEV;
+	ray_release(link);
+	return -ENODEV;
 } /* ray_config */
 
 static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
@@ -516,267 +537,278 @@ static inline struct rcs __iomem *rcs_ba
 /*===========================================================================*/
 static int ray_init(struct net_device *dev)
 {
-    int i;
-    UCHAR *p;
-    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);
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(0,"ray_init - device not present\n");
-        return -1;
-    }
+	int i;
+	UCHAR *p;
+	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);
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(0, "ray_init - device not present\n");
+		return -1;
+	}
 
-    local->net_type = net_type;
-    local->sta_type = TYPE_STA;
+	local->net_type = net_type;
+	local->sta_type = TYPE_STA;
 
-    /* Copy the startup results to local memory */
-    memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
-           sizeof(struct startup_res_6));
+	/* Copy the startup results to local memory */
+	memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,
+		      sizeof(struct startup_res_6));
 
-    /* Check Power up test status and get mac address from card */
-    if (local->startup_res.startup_word != 0x80) {
-    printk(KERN_INFO "ray_init ERROR card status = %2x\n",
-           local->startup_res.startup_word);
-        local->card_status = CARD_INIT_ERROR;
-        return -1;
-    }
+	/* Check Power up test status and get mac address from card */
+	if (local->startup_res.startup_word != 0x80) {
+		printk(KERN_INFO "ray_init ERROR card status = %2x\n",
+		       local->startup_res.startup_word);
+		local->card_status = CARD_INIT_ERROR;
+		return -1;
+	}
 
-    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, local->fw_bld);
+	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,
+	      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);
-    /* Initialize CCS's to buffer free state */
-    pccs = ccs_base(local);
-    for (i=0;  i<NUMBER_OF_CCS;  i++) {
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-    }
-    init_startup_params(local);
+	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);
+	/* Initialize CCS's to buffer free state */
+	pccs = ccs_base(local);
+	for (i = 0; i < NUMBER_OF_CCS; i++) {
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+	}
+	init_startup_params(local);
 
-    /* copy mac address to startup parameters */
-    if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
-    {
-        p = local->sparm.b4.a_mac_addr;
-    }
-    else
-    {
-        memcpy(&local->sparm.b4.a_mac_addr,
-               &local->startup_res.station_addr, ADDRLEN);
-        p = local->sparm.b4.a_mac_addr;
-    }
+	/* copy mac address to startup parameters */
+	if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) {
+		p = local->sparm.b4.a_mac_addr;
+	} else {
+		memcpy(&local->sparm.b4.a_mac_addr,
+		       &local->startup_res.station_addr, ADDRLEN);
+		p = local->sparm.b4.a_mac_addr;
+	}
 
-    clear_interrupt(local); /* Clear any interrupt from the card */
-    local->card_status = CARD_AWAITING_PARAM;
-    DEBUG(2,"ray_init ending\n");
-    return 0;
+	clear_interrupt(local);	/* Clear any interrupt from the card */
+	local->card_status = CARD_AWAITING_PARAM;
+	DEBUG(2, "ray_init ending\n");
+	return 0;
 } /* ray_init */
+
 /*===========================================================================*/
 /* Download startup parameters to the card and command it to read them       */
 static int dl_startup_params(struct net_device *dev)
 {
-    int ccsindex;
-    ray_dev_t *local = netdev_priv(dev);
-    struct ccs __iomem *pccs;
-    struct pcmcia_device *link = local->finder;
+	int ccsindex;
+	ray_dev_t *local = netdev_priv(dev);
+	struct ccs __iomem *pccs;
+	struct pcmcia_device *link = local->finder;
 
-    DEBUG(1,"dl_startup_params entered\n");
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs dl_startup_params - device not present\n");
-        return -1;
-    }
-    
-    /* Copy parameters to host to ECF area */
-    if (local->fw_ver == 0x55) 
-        memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
-               sizeof(struct b4_startup_params));
-    else
-        memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
-               sizeof(struct b5_startup_params));
+	DEBUG(1, "dl_startup_params entered\n");
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+		return -1;
+	}
 
-    
-    /* Fill in the CCS fields for the ECF */
-    if ((ccsindex = get_free_ccs(local)) < 0) return -1;
-    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", local->dl_param_ccs);
-    /* Interrupt the firmware to process the command */
-    if (interrupt_ecf(local, ccsindex)) {
-        printk(KERN_INFO "ray dl_startup_params failed - "
-           "ECF not ready for intr\n");
-        local->card_status = CARD_DL_PARAM_ERROR;
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-        return -2;
-    }
-    local->card_status = CARD_DL_PARAM;
-    /* Start kernel timer to wait for dl startup to complete. */
-    local->timer.expires = jiffies + HZ/2;
-    local->timer.data = (long)local;
-    local->timer.function = &verify_dl_startup;
-    add_timer(&local->timer);
-    DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
-    return 0;
+	/* Copy parameters to host to ECF area */
+	if (local->fw_ver == 0x55)
+		memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
+			    sizeof(struct b4_startup_params));
+	else
+		memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
+			    sizeof(struct b5_startup_params));
+
+	/* Fill in the CCS fields for the ECF */
+	if ((ccsindex = get_free_ccs(local)) < 0)
+		return -1;
+	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",
+	      local->dl_param_ccs);
+	/* Interrupt the firmware to process the command */
+	if (interrupt_ecf(local, ccsindex)) {
+		printk(KERN_INFO "ray dl_startup_params failed - "
+		       "ECF not ready for intr\n");
+		local->card_status = CARD_DL_PARAM_ERROR;
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+		return -2;
+	}
+	local->card_status = CARD_DL_PARAM;
+	/* Start kernel timer to wait for dl startup to complete. */
+	local->timer.expires = jiffies + HZ / 2;
+	local->timer.data = (long)local;
+	local->timer.function = &verify_dl_startup;
+	add_timer(&local->timer);
+	DEBUG(2,
+	      "ray_cs dl_startup_params started timer for verify_dl_startup\n");
+	return 0;
 } /* dl_startup_params */
+
 /*===========================================================================*/
 static void init_startup_params(ray_dev_t *local)
 {
-    int i; 
+	int i;
 
-    if (country > JAPAN_TEST) country = USA;
-    else
-        if (country < USA) country = USA;
-    /* structure for hop time and beacon period is defined here using 
-     * New 802.11D6.1 format.  Card firmware is still using old format
-     * until version 6.
-     *    Before                    After
-     *    a_hop_time ms byte        a_hop_time ms byte
-     *    a_hop_time 2s byte        a_hop_time ls byte
-     *    a_hop_time ls byte        a_beacon_period ms byte
-     *    a_beacon_period           a_beacon_period ls byte
-     *
-     *    a_hop_time = uS           a_hop_time = KuS
-     *    a_beacon_period = hops    a_beacon_period = KuS
-     */                             /* 64ms = 010000 */
-    if (local->fw_ver == 0x55)  {
-        memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms, 
-               sizeof(struct b4_startup_params));
-        /* Translate sane kus input values to old build 4/5 format */
-        /* i = hop time in uS truncated to 3 bytes */
-        i = (hop_dwell * 1024) & 0xffffff;
-        local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
-        local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
-        local->sparm.b4.a_beacon_period[0] = 0;
-        local->sparm.b4.a_beacon_period[1] =
-            ((beacon_period/hop_dwell) - 1) & 0xff;
-        local->sparm.b4.a_curr_country_code = country;
-        local->sparm.b4.a_hop_pattern_length = 
-            hop_pattern_length[(int)country] - 1;
-        if (bc)
-        {
-            local->sparm.b4.a_ack_timeout = 0x50;
-            local->sparm.b4.a_sifs = 0x3f;
-        }
-    }
-    else {    /* Version 5 uses real kus values */
-        memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms, 
-               sizeof(struct b5_startup_params));
+	if (country > JAPAN_TEST)
+		country = USA;
+	else if (country < USA)
+		country = USA;
+	/* structure for hop time and beacon period is defined here using
+	 * New 802.11D6.1 format.  Card firmware is still using old format
+	 * until version 6.
+	 *    Before                    After
+	 *    a_hop_time ms byte        a_hop_time ms byte
+	 *    a_hop_time 2s byte        a_hop_time ls byte
+	 *    a_hop_time ls byte        a_beacon_period ms byte
+	 *    a_beacon_period           a_beacon_period ls byte
+	 *
+	 *    a_hop_time = uS           a_hop_time = KuS
+	 *    a_beacon_period = hops    a_beacon_period = KuS
+	 *//* 64ms = 010000 */
+	if (local->fw_ver == 0x55) {
+		memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms,
+		       sizeof(struct b4_startup_params));
+		/* Translate sane kus input values to old build 4/5 format */
+		/* i = hop time in uS truncated to 3 bytes */
+		i = (hop_dwell * 1024) & 0xffffff;
+		local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
+		local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
+		local->sparm.b4.a_beacon_period[0] = 0;
+		local->sparm.b4.a_beacon_period[1] =
+		    ((beacon_period / hop_dwell) - 1) & 0xff;
+		local->sparm.b4.a_curr_country_code = country;
+		local->sparm.b4.a_hop_pattern_length =
+		    hop_pattern_length[(int)country] - 1;
+		if (bc) {
+			local->sparm.b4.a_ack_timeout = 0x50;
+			local->sparm.b4.a_sifs = 0x3f;
+		}
+	} else { /* Version 5 uses real kus values */
+		memcpy((UCHAR *) &local->sparm.b5, b5_default_startup_parms,
+		       sizeof(struct b5_startup_params));
 
-        local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
-        local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
-        local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
-        local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
-        if (psm)
-            local->sparm.b5.a_power_mgt_state = 1;
-        local->sparm.b5.a_curr_country_code = country;
-        local->sparm.b5.a_hop_pattern_length = 
-            hop_pattern_length[(int)country];
-    }
-    
-    local->sparm.b4.a_network_type = net_type & 0x01;
-    local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
+		local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
+		local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
+		local->sparm.b5.a_beacon_period[0] =
+		    (beacon_period >> 8) & 0xff;
+		local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
+		if (psm)
+			local->sparm.b5.a_power_mgt_state = 1;
+		local->sparm.b5.a_curr_country_code = country;
+		local->sparm.b5.a_hop_pattern_length =
+		    hop_pattern_length[(int)country];
+	}
+
+	local->sparm.b4.a_network_type = net_type & 0x01;
+	local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
+
+	if (essid != NULL)
+		strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
+} /* init_startup_params */
 
-    if (essid != NULL)
-        strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
-} /* init_startup_params */ 
 /*===========================================================================*/
 static void verify_dl_startup(u_long data)
 {
-    ray_dev_t *local = (ray_dev_t *)data;
-    struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
-    UCHAR status;
-    struct pcmcia_device *link = local->finder;
+	ray_dev_t *local = (ray_dev_t *) data;
+	struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
+	UCHAR status;
+	struct pcmcia_device *link = local->finder;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
-        return;
-    }
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+		return;
+	}
 #ifdef PCMCIA_DEBUG
-    if (pc_debug > 2) {
-    int i;
-    printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",
-           local->dl_param_ccs);
-        for (i=0; i<sizeof(struct b5_startup_params); i++) {
-            printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));
-        }
-    printk("\n");
-    }
+	if (pc_debug > 2) {
+		int i;
+		printk(KERN_DEBUG
+		       "verify_dl_startup parameters sent via ccs %d:\n",
+		       local->dl_param_ccs);
+		for (i = 0; i < sizeof(struct b5_startup_params); i++) {
+			printk(" %2x",
+			       (unsigned int)readb(local->sram +
+						   HOST_TO_ECF_BASE + i));
+		}
+		printk("\n");
+	}
 #endif
 
-    status = readb(&pccs->buffer_status);
-    if (status!= CCS_BUFFER_FREE)
-    {
-        printk(KERN_INFO "Download startup params failed.  Status = %d\n",
-           status);
-        local->card_status = CARD_DL_PARAM_ERROR;
-        return;
-    }
-    if (local->sparm.b4.a_network_type == ADHOC)
-        start_net((u_long)local);
-    else
-        join_net((u_long)local);
+	status = readb(&pccs->buffer_status);
+	if (status != CCS_BUFFER_FREE) {
+		printk(KERN_INFO
+		       "Download startup params failed.  Status = %d\n",
+		       status);
+		local->card_status = CARD_DL_PARAM_ERROR;
+		return;
+	}
+	if (local->sparm.b4.a_network_type == ADHOC)
+		start_net((u_long) local);
+	else
+		join_net((u_long) local);
 
-    return;
+	return;
 } /* end verify_dl_startup */
+
 /*===========================================================================*/
 /* Command card to start a network */
 static void start_net(u_long data)
 {
-    ray_dev_t *local = (ray_dev_t *)data;
-    struct ccs __iomem *pccs;
-    int ccsindex;
-    struct pcmcia_device *link = local->finder;
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs start_net - device not present\n");
-        return;
-    }
-    /* Fill in the CCS fields for the ECF */
-    if ((ccsindex = get_free_ccs(local)) < 0) return;
-    pccs = ccs_base(local) + ccsindex;
-    writeb(CCS_START_NETWORK, &pccs->cmd);
-    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");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-        return;
-    }
-    local->card_status = CARD_DOING_ACQ;
-    return;
+	ray_dev_t *local = (ray_dev_t *) data;
+	struct ccs __iomem *pccs;
+	int ccsindex;
+	struct pcmcia_device *link = local->finder;
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs start_net - device not present\n");
+		return;
+	}
+	/* Fill in the CCS fields for the ECF */
+	if ((ccsindex = get_free_ccs(local)) < 0)
+		return;
+	pccs = ccs_base(local) + ccsindex;
+	writeb(CCS_START_NETWORK, &pccs->cmd);
+	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");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+		return;
+	}
+	local->card_status = CARD_DOING_ACQ;
+	return;
 } /* end start_net */
+
 /*===========================================================================*/
 /* Command card to join a network */
 static void join_net(u_long data)
 {
-    ray_dev_t *local = (ray_dev_t *)data;
+	ray_dev_t *local = (ray_dev_t *) data;
 
-    struct ccs __iomem *pccs;
-    int ccsindex;
-    struct pcmcia_device *link = local->finder;
-    
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs join_net - device not present\n");
-        return;
-    }
-    /* Fill in the CCS fields for the ECF */
-    if ((ccsindex = get_free_ccs(local)) < 0) return;
-    pccs = ccs_base(local) + ccsindex;
-    writeb(CCS_JOIN_NETWORK, &pccs->cmd);
-    writeb(0, &pccs->var.join_network.update_param);
-    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");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-        return;
-    }
-    local->card_status = CARD_DOING_ACQ;
-    return;
+	struct ccs __iomem *pccs;
+	int ccsindex;
+	struct pcmcia_device *link = local->finder;
+
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs join_net - device not present\n");
+		return;
+	}
+	/* Fill in the CCS fields for the ECF */
+	if ((ccsindex = get_free_ccs(local)) < 0)
+		return;
+	pccs = ccs_base(local) + ccsindex;
+	writeb(CCS_JOIN_NETWORK, &pccs->cmd);
+	writeb(0, &pccs->var.join_network.update_param);
+	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");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+		return;
+	}
+	local->card_status = CARD_DOING_ACQ;
+	return;
 }
+
 /*============================================================================
     After a card is removed, ray_release() will unregister the net
     device, and release the PCMCIA configuration.  If the device is
@@ -784,25 +816,27 @@ static void join_net(u_long data)
 =============================================================================*/
 static void ray_release(struct pcmcia_device *link)
 {
-    struct net_device *dev = link->priv; 
-    ray_dev_t *local = netdev_priv(dev);
-    int i;
-    
-    DEBUG(1, "ray_release(0x%p)\n", link);
+	struct net_device *dev = link->priv;
+	ray_dev_t *local = netdev_priv(dev);
+	int i;
 
-    del_timer(&local->timer);
+	DEBUG(1, "ray_release(0x%p)\n", link);
 
-    iounmap(local->sram);
-    iounmap(local->rmem);
-    iounmap(local->amem);
-    /* Do bother checking to see if these succeed or not */
-    i = pcmcia_release_window(local->amem_handle);
-    if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
-    i = pcmcia_release_window(local->rmem_handle);
-    if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
-    pcmcia_disable_device(link);
+	del_timer(&local->timer);
 
-    DEBUG(2,"ray_release ending\n");
+	iounmap(local->sram);
+	iounmap(local->rmem);
+	iounmap(local->amem);
+	/* Do bother checking to see if these succeed or not */
+	i = pcmcia_release_window(local->amem_handle);
+	if (i != 0)
+		DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
+	i = pcmcia_release_window(local->rmem_handle);
+	if (i != 0)
+		DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+	pcmcia_disable_device(link);
+
+	DEBUG(2, "ray_release ending\n");
 }
 
 static int ray_suspend(struct pcmcia_device *link)
@@ -831,236 +865,242 @@ static int ray_resume(struct pcmcia_devi
 static int ray_dev_init(struct net_device *dev)
 {
 #ifdef RAY_IMMEDIATE_INIT
-    int i;
-#endif	/* RAY_IMMEDIATE_INIT */
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link = local->finder;
+	int i;
+#endif /* RAY_IMMEDIATE_INIT */
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link = local->finder;
 
-    DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_dev_init - device not present\n");
-        return -1;
-    }
+	DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_dev_init - device not present\n");
+		return -1;
+	}
 #ifdef RAY_IMMEDIATE_INIT
-    /* Download startup parameters */
-    if ( (i = dl_startup_params(dev)) < 0)
-    {
-        printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
-           "returns 0x%x\n",i);
-        return -1;
-    }
-#else	/* RAY_IMMEDIATE_INIT */
-    /* 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,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
-	  local->card_status);
-#endif	/* RAY_IMMEDIATE_INIT */
+	/* Download startup parameters */
+	if ((i = dl_startup_params(dev)) < 0) {
+		printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
+		       "returns 0x%x\n", i);
+		return -1;
+	}
+#else /* RAY_IMMEDIATE_INIT */
+	/* 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,
+	      "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
+	      local->card_status);
+#endif /* RAY_IMMEDIATE_INIT */
 
-    /* copy mac and broadcast addresses to linux device */
-    memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
-    memset(dev->broadcast, 0xff, ETH_ALEN);
+	/* copy mac and broadcast addresses to linux device */
+	memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+	memset(dev->broadcast, 0xff, ETH_ALEN);
 
-    DEBUG(2,"ray_dev_init ending\n");
-    return 0;
+	DEBUG(2, "ray_dev_init ending\n");
+	return 0;
 }
+
 /*===========================================================================*/
 static int ray_dev_config(struct net_device *dev, struct ifmap *map)
 {
-    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);
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_dev_config - device not present\n");
-        return -1;
-    }
+	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);
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_dev_config - device not present\n");
+		return -1;
+	}
 
-    return 0;
+	return 0;
 }
+
 /*===========================================================================*/
 static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link = local->finder;
-    short length = skb->len;
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link = local->finder;
+	short length = skb->len;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_dev_start_xmit - device not present\n");
-        return -1;
-    }
-    DEBUG(3,"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");
-        if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
-            local->authentication_state = AUTHENTICATED;
-            netif_stop_queue(dev);
-            return 1;
-        }
-    }
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_dev_start_xmit - device not present\n");
+		return -1;
+	}
+	DEBUG(3, "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");
+		if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
+			local->authentication_state = AUTHENTICATED;
+			netif_stop_queue(dev);
+			return 1;
+		}
+	}
 
-    if (length < ETH_ZLEN)
-    {
-    	if (skb_padto(skb, ETH_ZLEN))
-    		return 0;
-    	length = ETH_ZLEN;
-    }
-    switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
-        case XMIT_NO_CCS:
-        case XMIT_NEED_AUTH:
-	    netif_stop_queue(dev);
-            return 1;
-        case XMIT_NO_INTR:
-        case XMIT_MSG_BAD:
-        case XMIT_OK:
-        default:
-            dev->trans_start = jiffies;
-            dev_kfree_skb(skb);
-            return 0;
-    }
-    return 0;
+	if (length < ETH_ZLEN) {
+		if (skb_padto(skb, ETH_ZLEN))
+			return 0;
+		length = ETH_ZLEN;
+	}
+	switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
+	case XMIT_NO_CCS:
+	case XMIT_NEED_AUTH:
+		netif_stop_queue(dev);
+		return 1;
+	case XMIT_NO_INTR:
+	case XMIT_MSG_BAD:
+	case XMIT_OK:
+	default:
+		dev->trans_start = jiffies;
+		dev_kfree_skb(skb);
+		return 0;
+	}
+	return 0;
 } /* ray_dev_start_xmit */
+
 /*===========================================================================*/
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, 
-                UCHAR msg_type)
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
+		       UCHAR msg_type)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    struct ccs __iomem *pccs;
-    int ccsindex;
-    int offset;
-    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);
-    if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
-    {
-        printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);
-        return XMIT_MSG_BAD;
-    }
+	ray_dev_t *local = netdev_priv(dev);
+	struct ccs __iomem *pccs;
+	int ccsindex;
+	int offset;
+	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);
+	if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
+		printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
+		       len);
+		return XMIT_MSG_BAD;
+	}
 	switch (ccsindex = get_free_tx_ccs(local)) {
 	case ECCSBUSY:
-		DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");
+		DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
 	case ECCSFULL:
-        DEBUG(2,"ray_hw_xmit No free tx ccs\n");
+		DEBUG(2, "ray_hw_xmit No free tx ccs\n");
 	case ECARDGONE:
-	netif_stop_queue(dev);
-        return XMIT_NO_CCS;
+		netif_stop_queue(dev);
+		return XMIT_NO_CCS;
 	default:
 		break;
 	}
-    addr = TX_BUF_BASE + (ccsindex << 11);
+	addr = TX_BUF_BASE + (ccsindex << 11);
 
-    if (msg_type == DATA_TYPE) {
-        local->stats.tx_bytes += len;
-        local->stats.tx_packets++;
-    }
+	if (msg_type == DATA_TYPE) {
+		local->stats.tx_bytes += len;
+		local->stats.tx_packets++;
+	}
 
-    ptx = local->sram + addr;
+	ptx = local->sram + addr;
 
-    ray_build_header(local, ptx, msg_type, data);
-    if (translate) {
-        offset = translate_frame(local, ptx, data, len);
-    }
-    else { /* Encapsulate frame */
-        /* TBD TIB length will move address of ptx->var */
-        memcpy_toio(&ptx->var, data, len);
-        offset = 0;
-    }
+	ray_build_header(local, ptx, msg_type, data);
+	if (translate) {
+		offset = translate_frame(local, ptx, data, len);
+	} else { /* Encapsulate frame */
+		/* TBD TIB length will move address of ptx->var */
+		memcpy_toio(&ptx->var, data, len);
+		offset = 0;
+	}
 
-    /* fill in the CCS */
-    pccs = ccs_base(local) + ccsindex;
-    len += TX_HEADER_LENGTH + offset;
-    writeb(CCS_TX_REQUEST, &pccs->cmd);
-    writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
-    writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
-    writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
-    writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
+	/* fill in the CCS */
+	pccs = ccs_base(local) + ccsindex;
+	len += TX_HEADER_LENGTH + offset;
+	writeb(CCS_TX_REQUEST, &pccs->cmd);
+	writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
+	writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
+	writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
+	writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
 /* TBD still need psm_cam? */
-    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",\
-          local->net_default_tx_rate);
+	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",
+	      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");
+	/* Interrupt the firmware to process the command */
+	if (interrupt_ecf(local, ccsindex)) {
+		DEBUG(2, "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?
 */
-        writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
-        return XMIT_NO_INTR;
-    }
-    return XMIT_OK;
+		writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+		return XMIT_NO_INTR;
+	}
+	return XMIT_OK;
 } /* end ray_hw_xmit */
+
 /*===========================================================================*/
-static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
-                    int len)
+static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
+			   unsigned char *data, int len)
 {
-    __be16 proto = ((struct ethhdr *)data)->h_proto;
-    if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
-        DEBUG(3,"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), (UCHAR *)&proto, 2);
-        if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
-            /* This is the selective translation table, only 2 entries */
-            writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
-        }
-        /* Copy body of ethernet packet without ethernet header */
-        memcpy_toio((void __iomem *)&ptx->var + sizeof(struct snaphdr_t), \
-                    data + ETH_HLEN,  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");
-        if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
-        DEBUG(3,"ray_cs translate_frame evil IPX\n");
-            memcpy_toio(&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
-            return 0 - ETH_HLEN;
-        }
-        memcpy_toio(&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
-        return 0 - ETH_HLEN;
-    }
-    /* TBD do other frame types */
+	__be16 proto = ((struct ethhdr *)data)->h_proto;
+	if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
+		DEBUG(3, "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),
+			    (UCHAR *) &proto, 2);
+		if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
+			/* This is the selective translation table, only 2 entries */
+			writeb(0xf8,
+			       &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
+		}
+		/* Copy body of ethernet packet without ethernet header */
+		memcpy_toio((void __iomem *)&ptx->var +
+			    sizeof(struct snaphdr_t), data + ETH_HLEN,
+			    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");
+		if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
+			DEBUG(3, "ray_cs translate_frame evil IPX\n");
+			memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+			return 0 - ETH_HLEN;
+		}
+		memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+		return 0 - ETH_HLEN;
+	}
+	/* TBD do other frame types */
 } /* end translate_frame */
+
 /*===========================================================================*/
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
-                unsigned char *data)
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+			     UCHAR msg_type, unsigned char *data)
 {
-    writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
+	writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
 /*** IEEE 802.11 Address field assignments *************
-                TODS FROMDS   addr_1     addr_2          addr_3   addr_4
-Adhoc           0    0        dest       src (terminal)  BSSID    N/A
-AP to Terminal  0    1        dest       AP(BSSID)       source   N/A
-Terminal to AP  1    0        AP(BSSID)  src (terminal)  dest     N/A
-AP to AP        1    1        dest AP    src AP          dest     source      
+		TODS	FROMDS	addr_1		addr_2		addr_3	addr_4
+Adhoc		0	0	dest		src (terminal)	BSSID	N/A
+AP to Terminal	0	1	dest		AP(BSSID)	source	N/A
+Terminal to AP	1	0	AP(BSSID)	src (terminal)	dest	N/A
+AP to AP	1	1	dest AP		src AP		dest	source
 *******************************************************/
-    if (local->net_type == ADHOC) {   
-        writeb(0, &ptx->mac.frame_ctl_2);
-        memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
-        memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
-    }
-    else /* infrastructure */
-    {
-        if (local->sparm.b4.a_acting_as_ap_status)
-        {
-            writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
-            memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
-            memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
-            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
-        }
-        else /* Terminal */
-        {
-            writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
-            memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
-            memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
-            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
-        }
-    }
-} /* end encapsulate_frame */
+	if (local->net_type == ADHOC) {
+		writeb(0, &ptx->mac.frame_ctl_2);
+		memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest,
+			    2 * ADDRLEN);
+		memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+	} else { /* infrastructure */
+
+		if (local->sparm.b4.a_acting_as_ap_status) {
+			writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
+			memcpy_toio(ptx->mac.addr_1,
+				    ((struct ethhdr *)data)->h_dest, ADDRLEN);
+			memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
+			memcpy_toio(ptx->mac.addr_3,
+				    ((struct ethhdr *)data)->h_source, ADDRLEN);
+		} else { /* Terminal */
 
+			writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
+			memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
+			memcpy_toio(ptx->mac.addr_2,
+				    ((struct ethhdr *)data)->h_source, ADDRLEN);
+			memcpy_toio(ptx->mac.addr_3,
+				    ((struct ethhdr *)data)->h_dest, ADDRLEN);
+		}
+	}
+} /* end encapsulate_frame */
 
 /*===========================================================================*/
 
@@ -1071,7 +1111,7 @@ static void netdev_get_drvinfo(struct ne
 }
 
 static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
+	.get_drvinfo = netdev_get_drvinfo,
 };
 
 /*====================================================================*/
@@ -1081,9 +1121,7 @@ static const struct ethtool_ops netdev_e
  * Wireless Handler : get protocol name
  */
 static int ray_get_name(struct net_device *dev,
-			struct iw_request_info *info,
-			char *cwrq,
-			char *extra)
+			struct iw_request_info *info, char *cwrq, char *extra)
 {
 	strcpy(cwrq, "IEEE 802.11-FH");
 	return 0;
@@ -1095,14 +1133,13 @@ static int ray_get_name(struct net_devic
  */
 static int ray_set_freq(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_freq *fwrq,
-			char *extra)
+			struct iw_freq *fwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
+	int err = -EINPROGRESS;	/* Call commit handler */
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
 	/* Setting by channel number */
@@ -1113,15 +1150,14 @@ static int ray_set_freq(struct net_devic
 
 	return err;
 }
- 
+
 /*------------------------------------------------------------------*/
 /*
  * Wireless Handler : get frequency
  */
 static int ray_get_freq(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_freq *fwrq,
-			char *extra)
+			struct iw_freq *fwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
@@ -1136,22 +1172,21 @@ static int ray_get_freq(struct net_devic
  */
 static int ray_set_essid(struct net_device *dev,
 			 struct iw_request_info *info,
-			 struct iw_point *dwrq,
-			 char *extra)
+			 struct iw_point *dwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
 	/* Check if we asked for `any' */
-	if(dwrq->flags == 0) {
+	if (dwrq->flags == 0) {
 		/* Corey : can you do that ? */
 		return -EOPNOTSUPP;
 	} else {
 		/* Check the size of the string */
-		if(dwrq->length > IW_ESSID_MAX_SIZE) {
+		if (dwrq->length > IW_ESSID_MAX_SIZE) {
 			return -E2BIG;
 		}
 
@@ -1160,7 +1195,7 @@ static int ray_set_essid(struct net_devi
 		memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length);
 	}
 
-	return -EINPROGRESS;		/* Call commit handler */
+	return -EINPROGRESS;	/* Call commit handler */
 }
 
 /*------------------------------------------------------------------*/
@@ -1169,8 +1204,7 @@ static int ray_set_essid(struct net_devi
  */
 static int ray_get_essid(struct net_device *dev,
 			 struct iw_request_info *info,
-			 struct iw_point *dwrq,
-			 char *extra)
+			 struct iw_point *dwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
@@ -1179,7 +1213,7 @@ static int ray_get_essid(struct net_devi
 
 	/* Push it out ! */
 	dwrq->length = strlen(extra);
-	dwrq->flags = 1; /* active */
+	dwrq->flags = 1;	/* active */
 
 	return 0;
 }
@@ -1189,9 +1223,8 @@ static int ray_get_essid(struct net_devi
  * Wireless Handler : get AP address
  */
 static int ray_get_wap(struct net_device *dev,
-			struct iw_request_info *info,
-			struct sockaddr *awrq,
-			char *extra)
+		       struct iw_request_info *info,
+		       struct sockaddr *awrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
@@ -1207,25 +1240,24 @@ static int ray_get_wap(struct net_device
  */
 static int ray_set_rate(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_param *vwrq,
-			char *extra)
+			struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
 	/* Check if rate is in range */
-	if((vwrq->value != 1000000) && (vwrq->value != 2000000))
+	if ((vwrq->value != 1000000) && (vwrq->value != 2000000))
 		return -EINVAL;
 
 	/* Hack for 1.5 Mb/s instead of 2 Mb/s */
-	if((local->fw_ver == 0x55) &&		/* Please check */
-	   (vwrq->value == 2000000))
+	if ((local->fw_ver == 0x55) &&	/* Please check */
+	    (vwrq->value == 2000000))
 		local->net_default_tx_rate = 3;
 	else
-		local->net_default_tx_rate = vwrq->value/500000;
+		local->net_default_tx_rate = vwrq->value / 500000;
 
 	return 0;
 }
@@ -1236,16 +1268,15 @@ static int ray_set_rate(struct net_devic
  */
 static int ray_get_rate(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_param *vwrq,
-			char *extra)
+			struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
-	if(local->net_default_tx_rate == 3)
-		vwrq->value = 2000000;		/* Hum... */
+	if (local->net_default_tx_rate == 3)
+		vwrq->value = 2000000;	/* Hum... */
 	else
 		vwrq->value = local->net_default_tx_rate * 500000;
-	vwrq->fixed = 0;		/* We are in auto mode */
+	vwrq->fixed = 0;	/* We are in auto mode */
 
 	return 0;
 }
@@ -1256,43 +1287,40 @@ static int ray_get_rate(struct net_devic
  */
 static int ray_set_rts(struct net_device *dev,
 		       struct iw_request_info *info,
-		       struct iw_param *vwrq,
-		       char *extra)
+		       struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 	int rthr = vwrq->value;
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
 	/* if(wrq->u.rts.fixed == 0) we should complain */
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		rthr = 32767;
 	else {
-		if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
+		if ((rthr < 0) || (rthr > 2347))   /* What's the max packet size ??? */
 			return -EINVAL;
 	}
 	local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
 	local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
 
-	return -EINPROGRESS;		/* Call commit handler */
+	return -EINPROGRESS;	/* Call commit handler */
 }
 
-
 /*------------------------------------------------------------------*/
 /*
  * Wireless Handler : get RTS threshold
  */
 static int ray_get_rts(struct net_device *dev,
 		       struct iw_request_info *info,
-		       struct iw_param *vwrq,
-		       char *extra)
+		       struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
 	vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8)
-		+ local->sparm.b5.a_rts_threshold[1];
+	    + local->sparm.b5.a_rts_threshold[1];
 	vwrq->disabled = (vwrq->value == 32767);
 	vwrq->fixed = 1;
 
@@ -1305,27 +1333,26 @@ static int ray_get_rts(struct net_device
  */
 static int ray_set_frag(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_param *vwrq,
-			char *extra)
+			struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 	int fthr = vwrq->value;
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
 	/* if(wrq->u.frag.fixed == 0) should complain */
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		fthr = 32767;
 	else {
-		if((fthr < 256) || (fthr > 2347)) /* To check out ! */
+		if ((fthr < 256) || (fthr > 2347))	/* To check out ! */
 			return -EINVAL;
 	}
 	local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
 	local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
 
-	return -EINPROGRESS;		/* Call commit handler */
+	return -EINPROGRESS;	/* Call commit handler */
 }
 
 /*------------------------------------------------------------------*/
@@ -1334,13 +1361,12 @@ static int ray_set_frag(struct net_devic
  */
 static int ray_get_frag(struct net_device *dev,
 			struct iw_request_info *info,
-			struct iw_param *vwrq,
-			char *extra)
+			struct iw_param *vwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
 	vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8)
-		+ local->sparm.b5.a_frag_threshold[1];
+	    + local->sparm.b5.a_frag_threshold[1];
 	vwrq->disabled = (vwrq->value == 32767);
 	vwrq->fixed = 1;
 
@@ -1352,23 +1378,20 @@ static int ray_get_frag(struct net_devic
  * Wireless Handler : set Mode of Operation
  */
 static int ray_set_mode(struct net_device *dev,
-			struct iw_request_info *info,
-			__u32 *uwrq,
-			char *extra)
+			struct iw_request_info *info, __u32 *uwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
+	int err = -EINPROGRESS;	/* Call commit handler */
 	char card_mode = 1;
 
 	/* Reject if card is already initialised */
-	if(local->card_status != CARD_AWAITING_PARAM)
+	if (local->card_status != CARD_AWAITING_PARAM)
 		return -EBUSY;
 
-	switch (*uwrq)
-	{
+	switch (*uwrq) {
 	case IW_MODE_ADHOC:
 		card_mode = 0;
-		// Fall through
+		/* Fall through */
 	case IW_MODE_INFRA:
 		local->sparm.b5.a_network_type = card_mode;
 		break;
@@ -1384,13 +1407,11 @@ static int ray_set_mode(struct net_devic
  * Wireless Handler : get Mode of Operation
  */
 static int ray_get_mode(struct net_device *dev,
-			struct iw_request_info *info,
-			__u32 *uwrq,
-			char *extra)
+			struct iw_request_info *info, __u32 *uwrq, char *extra)
 {
 	ray_dev_t *local = netdev_priv(dev);
 
-	if(local->sparm.b5.a_network_type)
+	if (local->sparm.b5.a_network_type)
 		*uwrq = IW_MODE_INFRA;
 	else
 		*uwrq = IW_MODE_ADHOC;
@@ -1404,12 +1425,11 @@ static int ray_get_mode(struct net_devic
  */
 static int ray_get_range(struct net_device *dev,
 			 struct iw_request_info *info,
-			 struct iw_point *dwrq,
-			 char *extra)
+			 struct iw_point *dwrq, char *extra)
 {
-	struct iw_range *range = (struct iw_range *) extra;
+	struct iw_range *range = (struct iw_range *)extra;
 
-	memset((char *) range, 0, sizeof(struct iw_range));
+	memset((char *)range, 0, sizeof(struct iw_range));
 
 	/* Set the length (very important for backward compatibility) */
 	dwrq->length = sizeof(struct iw_range);
@@ -1420,7 +1440,7 @@ static int ray_get_range(struct net_devi
 
 	/* Set information in the range struct */
 	range->throughput = 1.1 * 1000 * 1000;	/* Put the right number here */
-	range->num_channels = hop_pattern_length[(int)country]; 
+	range->num_channels = hop_pattern_length[(int)country];
 	range->num_frequency = 0;
 	range->max_qual.qual = 0;
 	range->max_qual.level = 255;	/* What's the correct value ? */
@@ -1437,8 +1457,7 @@ static int ray_get_range(struct net_devi
  */
 static int ray_set_framing(struct net_device *dev,
 			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
+			   union iwreq_data *wrqu, char *extra)
 {
 	translate = *(extra);	/* Set framing mode */
 
@@ -1451,8 +1470,7 @@ static int ray_set_framing(struct net_de
  */
 static int ray_get_framing(struct net_device *dev,
 			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
+			   union iwreq_data *wrqu, char *extra)
 {
 	*(extra) = translate;
 
@@ -1465,8 +1483,7 @@ static int ray_get_framing(struct net_de
  */
 static int ray_get_country(struct net_device *dev,
 			   struct iw_request_info *info,
-			   union iwreq_data *wrqu,
-			   char *extra)
+			   union iwreq_data *wrqu, char *extra)
 {
 	*(extra) = country;
 
@@ -1477,11 +1494,10 @@ static int ray_get_country(struct net_de
 /*
  * Commit handler : called after a bunch of SET operations
  */
-static int ray_commit(struct net_device *dev,
-		      struct iw_request_info *info,	/* NULL */
-		      void *zwrq,			/* NULL */
-		      char *extra)			/* NULL */
-{
+static int ray_commit(struct net_device *dev, struct iw_request_info *info,	/* NULL */
+		      void *zwrq,	/* NULL */
+		      char *extra)
+{ /* NULL */
 	return 0;
 }
 
@@ -1489,33 +1505,34 @@ static int ray_commit(struct net_device
 /*
  * Stats handler : return Wireless Stats
  */
-static iw_stats * ray_get_wireless_stats(struct net_device *	dev)
+static iw_stats *ray_get_wireless_stats(struct net_device *dev)
 {
-  ray_dev_t *	local = netdev_priv(dev);
-  struct pcmcia_device *link = local->finder;
-  struct status __iomem *p = local->sram + STATUS_BASE;
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link = local->finder;
+	struct status __iomem *p = local->sram + STATUS_BASE;
 
-  if(local == (ray_dev_t *) NULL)
-    return (iw_stats *) NULL;
+	if (local == (ray_dev_t *) NULL)
+		return (iw_stats *) NULL;
 
-  local->wstats.status = local->card_status;
+	local->wstats.status = local->card_status;
 #ifdef WIRELESS_SPY
-  if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0))
-    {
-      /* Get it from the first node in spy list */
-      local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
-      local->wstats.qual.level = local->spy_data.spy_stat[0].level;
-      local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
-      local->wstats.qual.updated = local->spy_data.spy_stat[0].updated;
-    }
+	if ((local->spy_data.spy_number > 0)
+	    && (local->sparm.b5.a_network_type == 0)) {
+		/* Get it from the first node in spy list */
+		local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
+		local->wstats.qual.level = local->spy_data.spy_stat[0].level;
+		local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
+		local->wstats.qual.updated =
+		    local->spy_data.spy_stat[0].updated;
+	}
 #endif /* WIRELESS_SPY */
 
-  if(pcmcia_dev_present(link)) {
-    local->wstats.qual.noise = readb(&p->rxnoise);
-    local->wstats.qual.updated |= 4;
-  }
+	if (pcmcia_dev_present(link)) {
+		local->wstats.qual.noise = readb(&p->rxnoise);
+		local->wstats.qual.updated |= 4;
+	}
 
-  return &local->wstats;
+	return &local->wstats;
 } /* end ray_get_wireless_stats */
 
 /*------------------------------------------------------------------*/
@@ -1523,1159 +1540,1264 @@ static iw_stats * ray_get_wireless_stats
  * Structures to export the Wireless Handlers
  */
 
-static const iw_handler	ray_handler[] = {
-	[SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
-	[SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) ray_get_name,
-	[SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_set_freq,
-	[SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_get_freq,
-	[SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) ray_set_mode,
-	[SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) ray_get_mode,
-	[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
+static const iw_handler ray_handler[] = {
+	[SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit,
+	[SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name,
+	[SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq,
+	[SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq,
+	[SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode,
+	[SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode,
+	[SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range,
 #ifdef WIRELESS_SPY
- 	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
-	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
-	[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
-	[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
-#endif	/* WIRELESS_SPY */
-	[SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) ray_get_wap,
-	[SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
-	[SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
-	[SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) ray_set_rate,
-	[SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) ray_get_rate,
-	[SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) ray_set_rts,
-	[SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) ray_get_rts,
-	[SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_set_frag,
-	[SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_get_frag,
+	[SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+	[SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+	[SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+	[SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
+#endif /* WIRELESS_SPY */
+	[SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap,
+	[SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid,
+	[SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid,
+	[SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate,
+	[SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate,
+	[SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts,
+	[SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts,
+	[SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag,
+	[SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag,
 };
 
-#define SIOCSIPFRAMING	SIOCIWFIRSTPRIV		/* Set framing mode */
+#define SIOCSIPFRAMING	SIOCIWFIRSTPRIV	/* Set framing mode */
 #define SIOCGIPFRAMING	SIOCIWFIRSTPRIV + 1	/* Get framing mode */
 #define SIOCGIPCOUNTRY	SIOCIWFIRSTPRIV + 3	/* Get country code */
 
-static const iw_handler	ray_private_handler[] = {
+static const iw_handler ray_private_handler[] = {
 	[0] = (iw_handler) ray_set_framing,
 	[1] = (iw_handler) ray_get_framing,
 	[3] = (iw_handler) ray_get_country,
 };
 
-static const struct iw_priv_args	ray_private_args[] = {
+static const struct iw_priv_args ray_private_args[] = {
 /* cmd,		set_args,	get_args,	name */
-{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
-{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
-{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
+	{SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
+	 "set_framing"},
+	{SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+	 "get_framing"},
+	{SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+	 "get_country"},
 };
 
-static const struct iw_handler_def	ray_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(ray_handler),
-	.num_private	= ARRAY_SIZE(ray_private_handler),
+static const struct iw_handler_def ray_handler_def = {
+	.num_standard = ARRAY_SIZE(ray_handler),
+	.num_private = ARRAY_SIZE(ray_private_handler),
 	.num_private_args = ARRAY_SIZE(ray_private_args),
-	.standard	= ray_handler,
-	.private	= ray_private_handler,
-	.private_args	= ray_private_args,
+	.standard = ray_handler,
+	.private = ray_private_handler,
+	.private_args = ray_private_args,
 	.get_wireless_stats = ray_get_wireless_stats,
 };
 
 /*===========================================================================*/
 static int ray_open(struct net_device *dev)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link;
-    link = local->finder;
-    
-    DEBUG(1, "ray_open('%s')\n", dev->name);
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link;
+	link = local->finder;
 
-    if (link->open == 0)
-	    local->num_multi = 0;
-    link->open++;
+	DEBUG(1, "ray_open('%s')\n", dev->name);
 
-    /* If the card is not started, time to start it ! - Jean II */
-    if(local->card_status == CARD_AWAITING_PARAM) {
-	int i;
+	if (link->open == 0)
+		local->num_multi = 0;
+	link->open++;
 
-	DEBUG(1,"ray_open: doing init now !\n");
+	/* If the card is not started, time to start it ! - Jean II */
+	if (local->card_status == CARD_AWAITING_PARAM) {
+		int i;
 
-	/* Download startup parameters */
-	if ( (i = dl_startup_params(dev)) < 0)
-	  {
-	    printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
-		   "returns 0x%x\n",i);
-	    return -1;
-	  }
-     }
+		DEBUG(1, "ray_open: doing init now !\n");
 
-    if (sniffer) netif_stop_queue(dev);
-    else         netif_start_queue(dev);
+		/* Download startup parameters */
+		if ((i = dl_startup_params(dev)) < 0) {
+			printk(KERN_INFO
+			       "ray_dev_init dl_startup_params failed - "
+			       "returns 0x%x\n", i);
+			return -1;
+		}
+	}
 
-    DEBUG(2,"ray_open ending\n");
-    return 0;
+	if (sniffer)
+		netif_stop_queue(dev);
+	else
+		netif_start_queue(dev);
+
+	DEBUG(2, "ray_open ending\n");
+	return 0;
 } /* end ray_open */
+
 /*===========================================================================*/
 static int ray_dev_close(struct net_device *dev)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link;
-    link = local->finder;
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link;
+	link = local->finder;
 
-    DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+	DEBUG(1, "ray_dev_close('%s')\n", dev->name);
 
-    link->open--;
-    netif_stop_queue(dev);
+	link->open--;
+	netif_stop_queue(dev);
 
-    /* In here, we should stop the hardware (stop card from beeing active)
-     * and set local->card_status to CARD_AWAITING_PARAM, so that while the
-     * card is closed we can chage its configuration.
-     * Probably also need a COR reset to get sane state - Jean II */
+	/* In here, we should stop the hardware (stop card from beeing active)
+	 * and set local->card_status to CARD_AWAITING_PARAM, so that while the
+	 * card is closed we can chage its configuration.
+	 * Probably also need a COR reset to get sane state - Jean II */
 
-    return 0;
+	return 0;
 } /* end ray_dev_close */
+
 /*===========================================================================*/
-static void ray_reset(struct net_device *dev) {
-    DEBUG(1,"ray_reset entered\n");
-    return;
+static void ray_reset(struct net_device *dev)
+{
+	DEBUG(1, "ray_reset entered\n");
+	return;
 }
+
 /*===========================================================================*/
 /* Cause a firmware interrupt if it is ready for one                         */
 /* Return nonzero if not ready                                               */
 static int interrupt_ecf(ray_dev_t *local, int ccs)
 {
-    int i = 50;
-    struct pcmcia_device *link = local->finder;
+	int i = 50;
+	struct pcmcia_device *link = local->finder;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
-        return -1;
-    }
-    DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+		return -1;
+	}
+	DEBUG(2, "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");
-        return -1;
-    }
+	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");
+		return -1;
+	}
 	/* Fill the mailbox, then kick the card */
-    writeb(ccs, local->sram + SCB_BASE);
-    writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
-    return 0;
+	writeb(ccs, local->sram + SCB_BASE);
+	writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
+	return 0;
 } /* interrupt_ecf */
+
 /*===========================================================================*/
 /* Get next free transmit CCS                                                */
 /* Return - index of current tx ccs                                          */
 static int get_free_tx_ccs(ray_dev_t *local)
 {
-    int i;
-    struct ccs __iomem *pccs = ccs_base(local);
-    struct pcmcia_device *link = local->finder;
+	int i;
+	struct ccs __iomem *pccs = ccs_base(local);
+	struct pcmcia_device *link = local->finder;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
-        return ECARDGONE;
-    }
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "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");
-        return ECCSBUSY;
-    } 
+	if (test_and_set_bit(0, &local->tx_ccs_lock)) {
+		DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+		return ECCSBUSY;
+	}
 
-    for (i=0; i < NUMBER_OF_TX_CCS; i++) {
-        if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
-            writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
-            writeb(CCS_END_LIST, &(pccs+i)->link);
+	for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
+		if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+			writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+			writeb(CCS_END_LIST, &(pccs + i)->link);
 			local->tx_ccs_lock = 0;
-            return i;
-        }
-    }
+			return i;
+		}
+	}
 	local->tx_ccs_lock = 0;
-    DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n");
-    return ECCSFULL;
+	DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+	return ECCSFULL;
 } /* get_free_tx_ccs */
+
 /*===========================================================================*/
 /* Get next free CCS                                                         */
 /* Return - index of current ccs                                             */
 static int get_free_ccs(ray_dev_t *local)
 {
-    int i;
-    struct ccs __iomem *pccs = ccs_base(local);
-    struct pcmcia_device *link = local->finder;
+	int i;
+	struct ccs __iomem *pccs = ccs_base(local);
+	struct pcmcia_device *link = local->finder;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"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");
-        return ECCSBUSY;
-    } 
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "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");
+		return ECCSBUSY;
+	}
 
-    for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
-        if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
-            writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
-            writeb(CCS_END_LIST, &(pccs+i)->link);
+	for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
+		if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+			writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+			writeb(CCS_END_LIST, &(pccs + i)->link);
 			local->ccs_lock = 0;
-            return i;
-        }
-    }
+			return i;
+		}
+	}
 	local->ccs_lock = 0;
-    DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
-    return ECCSFULL;
+	DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+	return ECCSFULL;
 } /* get_free_ccs */
+
 /*===========================================================================*/
 static void authenticate_timeout(u_long data)
 {
-    ray_dev_t *local = (ray_dev_t *)data;
-    del_timer(&local->timer);
-    printk(KERN_INFO "ray_cs Authentication with access point failed"
-       " - timeout\n");
-    join_net((u_long)local);
+	ray_dev_t *local = (ray_dev_t *) data;
+	del_timer(&local->timer);
+	printk(KERN_INFO "ray_cs Authentication with access point failed"
+	       " - timeout\n");
+	join_net((u_long) local);
 }
+
 /*===========================================================================*/
 static int asc_to_int(char a)
 {
-    if (a < '0') return -1;
-    if (a <= '9') return (a - '0');
-    if (a < 'A') return -1;
-    if (a <= 'F') return (10 + a - 'A');
-    if (a < 'a') return -1;
-    if (a <= 'f') return (10 + a - 'a');
-    return -1;
+	if (a < '0')
+		return -1;
+	if (a <= '9')
+		return (a - '0');
+	if (a < 'A')
+		return -1;
+	if (a <= 'F')
+		return (10 + a - 'A');
+	if (a < 'a')
+		return -1;
+	if (a <= 'f')
+		return (10 + a - 'a');
+	return -1;
 }
+
 /*===========================================================================*/
 static int parse_addr(char *in_str, UCHAR *out)
 {
-    int len;
-    int i,j,k;
-    int status;
-    
-    if (in_str == NULL) return 0;
-    if ((len = strlen(in_str)) < 2) return 0;
-    memset(out, 0, ADDRLEN);
+	int len;
+	int i, j, k;
+	int status;
 
-    status = 1;
-    j = len - 1;
-    if (j > 12) j = 12;
-    i = 5;
-    
-    while (j > 0)
-    {
-        if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
-        else return 0;
+	if (in_str == NULL)
+		return 0;
+	if ((len = strlen(in_str)) < 2)
+		return 0;
+	memset(out, 0, ADDRLEN);
 
-        if (j == 0) break;
-        if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
-        else return 0;
-        if (!i--) break;
-    }
-    return status;
+	status = 1;
+	j = len - 1;
+	if (j > 12)
+		j = 12;
+	i = 5;
+
+	while (j > 0) {
+		if ((k = asc_to_int(in_str[j--])) != -1)
+			out[i] = k;
+		else
+			return 0;
+
+		if (j == 0)
+			break;
+		if ((k = asc_to_int(in_str[j--])) != -1)
+			out[i] += k << 4;
+		else
+			return 0;
+		if (!i--)
+			break;
+	}
+	return status;
 }
+
 /*===========================================================================*/
 static struct net_device_stats *ray_get_stats(struct net_device *dev)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    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");
-        return &local->stats;
-    }
-    if (readb(&p->mrx_overflow_for_host))
-    {
-        local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
-        writeb(0,&p->mrx_overflow);
-        writeb(0,&p->mrx_overflow_for_host);
-    }
-    if (readb(&p->mrx_checksum_error_for_host))
-    {
-        local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
-        writeb(0,&p->mrx_checksum_error);
-        writeb(0,&p->mrx_checksum_error_for_host);
-    }
-    if (readb(&p->rx_hec_error_for_host))
-    {
-        local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
-        writeb(0,&p->rx_hec_error);
-        writeb(0,&p->rx_hec_error_for_host);
-    }
-    return &local->stats;
+	ray_dev_t *local = netdev_priv(dev);
+	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");
+		return &local->stats;
+	}
+	if (readb(&p->mrx_overflow_for_host)) {
+		local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
+		writeb(0, &p->mrx_overflow);
+		writeb(0, &p->mrx_overflow_for_host);
+	}
+	if (readb(&p->mrx_checksum_error_for_host)) {
+		local->stats.rx_crc_errors +=
+		    swab16(readw(&p->mrx_checksum_error));
+		writeb(0, &p->mrx_checksum_error);
+		writeb(0, &p->mrx_checksum_error_for_host);
+	}
+	if (readb(&p->rx_hec_error_for_host)) {
+		local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
+		writeb(0, &p->rx_hec_error);
+		writeb(0, &p->rx_hec_error_for_host);
+	}
+	return &local->stats;
 }
+
 /*===========================================================================*/
-static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
+static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
+			    int len)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link = local->finder;
-    int ccsindex;
-    int i;
-    struct ccs __iomem *pccs;
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link = local->finder;
+	int ccsindex;
+	int i;
+	struct ccs __iomem *pccs;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_update_parm - device not present\n");
-        return;
-    }
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_update_parm - device not present\n");
+		return;
+	}
 
-    if ((ccsindex = get_free_ccs(local)) < 0)
-    {
-        DEBUG(0,"ray_update_parm - No free ccs\n");
-        return;
-    }
-    pccs = ccs_base(local) + ccsindex;
-    writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
-    writeb(objid, &pccs->var.update_param.object_id);
-    writeb(1, &pccs->var.update_param.number_objects);
-    writeb(0, &pccs->var.update_param.failure_cause);
-    for (i=0; i<len; i++) {
-        writeb(value[i], local->sram + HOST_TO_ECF_BASE);
-    }
-    /* Interrupt the firmware to process the command */
-    if (interrupt_ecf(local, ccsindex)) {
-        DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-    }
+	if ((ccsindex = get_free_ccs(local)) < 0) {
+		DEBUG(0, "ray_update_parm - No free ccs\n");
+		return;
+	}
+	pccs = ccs_base(local) + ccsindex;
+	writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
+	writeb(objid, &pccs->var.update_param.object_id);
+	writeb(1, &pccs->var.update_param.number_objects);
+	writeb(0, &pccs->var.update_param.failure_cause);
+	for (i = 0; i < len; i++) {
+		writeb(value[i], local->sram + HOST_TO_ECF_BASE);
+	}
+	/* Interrupt the firmware to process the command */
+	if (interrupt_ecf(local, ccsindex)) {
+		DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+	}
 }
+
 /*===========================================================================*/
 static void ray_update_multi_list(struct net_device *dev, int all)
 {
-    struct dev_mc_list *dmi, **dmip;
-    int ccsindex;
-    struct ccs __iomem *pccs;
-    int i = 0;
-    ray_dev_t *local = netdev_priv(dev);
-    struct pcmcia_device *link = local->finder;
-    void __iomem *p = local->sram + HOST_TO_ECF_BASE;
+	struct dev_mc_list *dmi, **dmip;
+	int ccsindex;
+	struct ccs __iomem *pccs;
+	int i = 0;
+	ray_dev_t *local = netdev_priv(dev);
+	struct pcmcia_device *link = local->finder;
+	void __iomem *p = local->sram + HOST_TO_ECF_BASE;
 
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_update_multi_list - device not present\n");
-        return;
-    }
-    else 
-        DEBUG(2,"ray_update_multi_list(%p)\n",dev);
-    if ((ccsindex = get_free_ccs(local)) < 0)
-    {
-        DEBUG(1,"ray_update_multi - No free ccs\n");
-        return;
-    }
-    pccs = ccs_base(local) + ccsindex;
-    writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_update_multi_list - device not present\n");
+		return;
+	} else
+		DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+	if ((ccsindex = get_free_ccs(local)) < 0) {
+		DEBUG(1, "ray_update_multi - No free ccs\n");
+		return;
+	}
+	pccs = ccs_base(local) + ccsindex;
+	writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
 
-    if (all) {
-        writeb(0xff, &pccs->var);
-        local->num_multi = 0xff;
-    }
-    else {
-        /* Copy the kernel's list of MC addresses to card */
-        for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
-            memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
-            DEBUG(1,"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],dmi->dmi_addr[4],dmi->dmi_addr[5]);
-            p += ETH_ALEN;
-            i++;
-        }
-        if (i > 256/ADDRLEN) i = 256/ADDRLEN;
-        writeb((UCHAR)i, &pccs->var);
-        DEBUG(1,"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,"ray_cs update_multi failed - ECF not ready for intr\n");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-    }
+	if (all) {
+		writeb(0xff, &pccs->var);
+		local->num_multi = 0xff;
+	} else {
+		/* Copy the kernel's list of MC addresses to card */
+		for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
+		     dmip = &dmi->next) {
+			memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
+			DEBUG(1,
+			      "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],
+			      dmi->dmi_addr[4], dmi->dmi_addr[5]);
+			p += ETH_ALEN;
+			i++;
+		}
+		if (i > 256 / ADDRLEN)
+			i = 256 / ADDRLEN;
+		writeb((UCHAR) i, &pccs->var);
+		DEBUG(1, "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,
+		      "ray_cs update_multi failed - ECF not ready for intr\n");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+	}
 } /* end ray_update_multi_list */
+
 /*===========================================================================*/
 static void set_multicast_list(struct net_device *dev)
 {
-    ray_dev_t *local = netdev_priv(dev);
-    UCHAR promisc;
+	ray_dev_t *local = netdev_priv(dev);
+	UCHAR promisc;
 
-    DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
+	DEBUG(2, "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");
-            local->sparm.b5.a_promiscuous_mode = 1;
-            promisc = 1;
-            ray_update_parm(dev,  OBJID_promiscuous_mode, \
-                            &promisc, sizeof(promisc));
-        }
-    }
-    else {
-        if (local->sparm.b5.a_promiscuous_mode == 1) {
-            DEBUG(1,"ray_cs set_multicast_list promisc off\n");
-            local->sparm.b5.a_promiscuous_mode = 0;
-            promisc = 0;
-            ray_update_parm(dev,  OBJID_promiscuous_mode, \
-                            &promisc, sizeof(promisc));
-        }
-    }
+	if (dev->flags & IFF_PROMISC) {
+		if (local->sparm.b5.a_promiscuous_mode == 0) {
+			DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+			local->sparm.b5.a_promiscuous_mode = 1;
+			promisc = 1;
+			ray_update_parm(dev, OBJID_promiscuous_mode,
+					&promisc, sizeof(promisc));
+		}
+	} else {
+		if (local->sparm.b5.a_promiscuous_mode == 1) {
+			DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+			local->sparm.b5.a_promiscuous_mode = 0;
+			promisc = 0;
+			ray_update_parm(dev, OBJID_promiscuous_mode,
+					&promisc, sizeof(promisc));
+		}
+	}
 
-    if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
-    else
-    {
-        if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
-    }
+	if (dev->flags & IFF_ALLMULTI)
+		ray_update_multi_list(dev, 1);
+	else {
+		if (local->num_multi != dev->mc_count)
+			ray_update_multi_list(dev, 0);
+	}
 } /* end set_multicast_list */
+
 /*=============================================================================
  * All routines below here are run at interrupt time.
 =============================================================================*/
 static irqreturn_t ray_interrupt(int irq, void *dev_id)
 {
-    struct net_device *dev = (struct net_device *)dev_id;
-    struct pcmcia_device *link;
-    ray_dev_t *local;
-    struct ccs __iomem *pccs;
-    struct rcs __iomem *prcs;
-    UCHAR rcsindex;
-    UCHAR tmp;
-    UCHAR cmd;
-    UCHAR status;
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct pcmcia_device *link;
+	ray_dev_t *local;
+	struct ccs __iomem *pccs;
+	struct rcs __iomem *prcs;
+	UCHAR rcsindex;
+	UCHAR tmp;
+	UCHAR cmd;
+	UCHAR status;
 
-    if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
-	return IRQ_NONE;
+	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);
+	DEBUG(4, "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");
-        return IRQ_NONE;
-    }
-    rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
+	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");
+		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);
-        clear_interrupt(local);
-        return IRQ_HANDLED;
-    }
-    if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
-    {
-        pccs = ccs_base(local) + rcsindex;
-        cmd = readb(&pccs->cmd);
-        status = readb(&pccs->buffer_status);
-        switch (cmd)
-        {
-        case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
-            del_timer(&local->timer);
-            if (status == CCS_COMMAND_COMPLETE) {
-                DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
-            }
-            else {
-                DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
-            }
-            break;
-        case CCS_UPDATE_PARAMS:
-            DEBUG(1,"ray_cs interrupt update params done\n");
-            if (status != CCS_COMMAND_COMPLETE) {
-                tmp = readb(&pccs->var.update_param.failure_cause);
-            DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
-            }
-            break;
-        case CCS_REPORT_PARAMS:
-            DEBUG(1,"ray_cs interrupt report params done\n");
-            break;
-        case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
-            DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
-            break;
-        case CCS_UPDATE_POWER_SAVINGS_MODE:
-            DEBUG(1,"ray_cs interrupt update power save mode done\n");
-            break;
-        case CCS_START_NETWORK:
-        case CCS_JOIN_NETWORK:
-            if (status == CCS_COMMAND_COMPLETE) {
-                if (readb(&pccs->var.start_network.net_initiated) == 1) {
-                    DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\
-                          local->sparm.b4.a_current_ess_id);
-                }
-                else {
-                    DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
-                          local->sparm.b4.a_current_ess_id);
-                }
-                memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
+	if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
+		DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+		clear_interrupt(local);
+		return IRQ_HANDLED;
+	}
+	if (rcsindex < NUMBER_OF_CCS) { /* If it's a returned CCS */
+		pccs = ccs_base(local) + rcsindex;
+		cmd = readb(&pccs->cmd);
+		status = readb(&pccs->buffer_status);
+		switch (cmd) {
+		case CCS_DOWNLOAD_STARTUP_PARAMS:	/* Happens in firmware someday */
+			del_timer(&local->timer);
+			if (status == CCS_COMMAND_COMPLETE) {
+				DEBUG(1,
+				      "ray_cs interrupt download_startup_parameters OK\n");
+			} else {
+				DEBUG(1,
+				      "ray_cs interrupt download_startup_parameters fail\n");
+			}
+			break;
+		case CCS_UPDATE_PARAMS:
+			DEBUG(1, "ray_cs interrupt update params done\n");
+			if (status != CCS_COMMAND_COMPLETE) {
+				tmp =
+				    readb(&pccs->var.update_param.
+					  failure_cause);
+				DEBUG(0,
+				      "ray_cs interrupt update params failed - reason %d\n",
+				      tmp);
+			}
+			break;
+		case CCS_REPORT_PARAMS:
+			DEBUG(1, "ray_cs interrupt report params done\n");
+			break;
+		case CCS_UPDATE_MULTICAST_LIST:	/* Note that this CCS isn't returned */
+			DEBUG(1,
+			      "ray_cs interrupt CCS Update Multicast List done\n");
+			break;
+		case CCS_UPDATE_POWER_SAVINGS_MODE:
+			DEBUG(1,
+			      "ray_cs interrupt update power save mode done\n");
+			break;
+		case CCS_START_NETWORK:
+		case CCS_JOIN_NETWORK:
+			if (status == CCS_COMMAND_COMPLETE) {
+				if (readb
+				    (&pccs->var.start_network.net_initiated) ==
+				    1) {
+					DEBUG(0,
+					      "ray_cs interrupt network \"%s\" started\n",
+					      local->sparm.b4.a_current_ess_id);
+				} else {
+					DEBUG(0,
+					      "ray_cs interrupt network \"%s\" joined\n",
+					      local->sparm.b4.a_current_ess_id);
+				}
+				memcpy_fromio(&local->bss_id,
+					      pccs->var.start_network.bssid,
+					      ADDRLEN);
 
-                if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
-                else local->net_default_tx_rate = 
-                         readb(&pccs->var.start_network.net_default_tx_rate);
-                local->encryption = readb(&pccs->var.start_network.encryption);
-                if (!sniffer && (local->net_type == INFRA)
-                    && !(local->sparm.b4.a_acting_as_ap_status)) {
-                    authenticate(local);
-                }
-                local->card_status = CARD_ACQ_COMPLETE;
-            }
-            else {
-                local->card_status = CARD_ACQ_FAILED;
+				if (local->fw_ver == 0x55)
+					local->net_default_tx_rate = 3;
+				else
+					local->net_default_tx_rate =
+					    readb(&pccs->var.start_network.
+						  net_default_tx_rate);
+				local->encryption =
+				    readb(&pccs->var.start_network.encryption);
+				if (!sniffer && (local->net_type == INFRA)
+				    && !(local->sparm.b4.a_acting_as_ap_status)) {
+					authenticate(local);
+				}
+				local->card_status = CARD_ACQ_COMPLETE;
+			} else {
+				local->card_status = CARD_ACQ_FAILED;
 
-                del_timer(&local->timer);
-                local->timer.expires = jiffies + HZ*5;
-                local->timer.data = (long)local;
-                if (status == CCS_START_NETWORK) {
-                    DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
-                          local->sparm.b4.a_current_ess_id);
-                    local->timer.function = &start_net;
-                }
-                else {
-                    DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
-                          local->sparm.b4.a_current_ess_id);
-                    local->timer.function = &join_net;
-                }
-                add_timer(&local->timer);
-            }
-            break;
-        case CCS_START_ASSOCIATION:
-            if (status == CCS_COMMAND_COMPLETE) {
-                local->card_status = CARD_ASSOC_COMPLETE;
-                DEBUG(0,"ray_cs association successful\n");
-            }
-            else
-            {
-                DEBUG(0,"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,"ray_cs interrupt tx request complete\n");
-            }
-            else {
-                DEBUG(1,"ray_cs interrupt tx request failed\n");
-            }
-            if (!sniffer) netif_start_queue(dev);
-            netif_wake_queue(dev);
-            break;
-        case CCS_TEST_MEMORY:
-            DEBUG(1,"ray_cs interrupt mem test done\n");
-            break;
-        case CCS_SHUTDOWN:
-            DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
-            break;
-        case CCS_DUMP_MEMORY:
-            DEBUG(1,"ray_cs interrupt dump memory done\n");
-            break;
-        case CCS_START_TIMER:
-            DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
-            break;
-        default:
-            DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
-                  rcsindex, cmd);
-        }
-        writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
-    }
-    else /* It's an RCS */
-    {
-        prcs = rcs_base(local) + rcsindex;
-    
-        switch (readb(&prcs->interrupt_id))
-        {
-        case PROCESS_RX_PACKET:
-            ray_rx(dev, local, prcs);
-            break;
-        case REJOIN_NET_COMPLETE:
-            DEBUG(1,"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) {
-                if (!sniffer) netif_start_queue(dev);
-            }
-            else {
-                memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
-                DEBUG(1,"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], local->bss_id[4], local->bss_id[5]);
-                if (!sniffer) authenticate(local);
-            }
-            break;
-        case ROAMING_INITIATED:
-            DEBUG(1,"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");
-            break;
-        default:
-            DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
-                  rcsindex, (unsigned int) readb(&prcs->interrupt_id));
-            break;
-        }
-        writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
-    }
-    clear_interrupt(local);
-    return IRQ_HANDLED;
+				del_timer(&local->timer);
+				local->timer.expires = jiffies + HZ * 5;
+				local->timer.data = (long)local;
+				if (status == CCS_START_NETWORK) {
+					DEBUG(0,
+					      "ray_cs interrupt network \"%s\" start failed\n",
+					      local->sparm.b4.a_current_ess_id);
+					local->timer.function = &start_net;
+				} else {
+					DEBUG(0,
+					      "ray_cs interrupt network \"%s\" join failed\n",
+					      local->sparm.b4.a_current_ess_id);
+					local->timer.function = &join_net;
+				}
+				add_timer(&local->timer);
+			}
+			break;
+		case CCS_START_ASSOCIATION:
+			if (status == CCS_COMMAND_COMPLETE) {
+				local->card_status = CARD_ASSOC_COMPLETE;
+				DEBUG(0, "ray_cs association successful\n");
+			} else {
+				DEBUG(0, "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,
+				      "ray_cs interrupt tx request complete\n");
+			} else {
+				DEBUG(1,
+				      "ray_cs interrupt tx request failed\n");
+			}
+			if (!sniffer)
+				netif_start_queue(dev);
+			netif_wake_queue(dev);
+			break;
+		case CCS_TEST_MEMORY:
+			DEBUG(1, "ray_cs interrupt mem test done\n");
+			break;
+		case CCS_SHUTDOWN:
+			DEBUG(1,
+			      "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
+			break;
+		case CCS_DUMP_MEMORY:
+			DEBUG(1, "ray_cs interrupt dump memory done\n");
+			break;
+		case CCS_START_TIMER:
+			DEBUG(2,
+			      "ray_cs interrupt DING - raylink timer expired\n");
+			break;
+		default:
+			DEBUG(1,
+			      "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
+			      rcsindex, cmd);
+		}
+		writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+	} else { /* It's an RCS */
+
+		prcs = rcs_base(local) + rcsindex;
+
+		switch (readb(&prcs->interrupt_id)) {
+		case PROCESS_RX_PACKET:
+			ray_rx(dev, local, prcs);
+			break;
+		case REJOIN_NET_COMPLETE:
+			DEBUG(1, "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) {
+				if (!sniffer)
+					netif_start_queue(dev);
+			} else {
+				memcpy_fromio(&local->bss_id,
+					      prcs->var.rejoin_net_complete.
+					      bssid, ADDRLEN);
+				DEBUG(1,
+				      "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],
+				      local->bss_id[4], local->bss_id[5]);
+				if (!sniffer)
+					authenticate(local);
+			}
+			break;
+		case ROAMING_INITIATED:
+			DEBUG(1, "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");
+			break;
+		default:
+			DEBUG(1,
+			      "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
+			      rcsindex,
+			      (unsigned int)readb(&prcs->interrupt_id));
+			break;
+		}
+		writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
+	}
+	clear_interrupt(local);
+	return IRQ_HANDLED;
 } /* ray_interrupt */
+
 /*===========================================================================*/
-static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs)
+static void ray_rx(struct net_device *dev, ray_dev_t *local,
+		   struct rcs __iomem *prcs)
 {
-    int rx_len;
-    unsigned int pkt_addr;
-    void __iomem *pmsg;
-    DEBUG(4,"ray_rx process rx packet\n");
+	int rx_len;
+	unsigned int pkt_addr;
+	void __iomem *pmsg;
+	DEBUG(4, "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)
-                + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
-    /* Length of first packet fragment */
-    rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
-        + readb(&prcs->var.rx_packet.rx_data_length[1]);
+	/* Calculate address of packet within Rx buffer */
+	pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
+		    + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
+	/* Length of first packet fragment */
+	rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
+	    + readb(&prcs->var.rx_packet.rx_data_length[1]);
 
-    local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
-    pmsg = local->rmem + pkt_addr;
-    switch(readb(pmsg))
-    {
-    case DATA_TYPE:
-        DEBUG(4,"ray_rx data type\n");
-        rx_data(dev, prcs, pkt_addr, rx_len);
-        break;
-    case AUTHENTIC_TYPE:
-        DEBUG(4,"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");
-        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");
-        break;
-    case BEACON_TYPE:
-        DEBUG(4,"ray_rx beacon type\n");
-        if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
+	local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
+	pmsg = local->rmem + pkt_addr;
+	switch (readb(pmsg)) {
+	case DATA_TYPE:
+		DEBUG(4, "ray_rx data type\n");
+		rx_data(dev, prcs, pkt_addr, rx_len);
+		break;
+	case AUTHENTIC_TYPE:
+		DEBUG(4, "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");
+		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");
+		break;
+	case BEACON_TYPE:
+		DEBUG(4, "ray_rx beacon type\n");
+		if (sniffer)
+			rx_data(dev, prcs, pkt_addr, rx_len);
 
-        copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr, 
-                          rx_len < sizeof(struct beacon_rx) ? 
-                          rx_len : sizeof(struct beacon_rx));
+		copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
+				  rx_len < sizeof(struct beacon_rx) ?
+				  rx_len : sizeof(struct beacon_rx));
 
-	local->beacon_rxed = 1;
-        /* Get the statistics so the card counters never overflow */
-        ray_get_stats(dev);
-            break;
-    default:
-        DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg));
-        break;
-    }
+		local->beacon_rxed = 1;
+		/* Get the statistics so the card counters never overflow */
+		ray_get_stats(dev);
+		break;
+	default:
+		DEBUG(0, "ray_cs unknown pkt type %2x\n",
+		      (unsigned int)readb(pmsg));
+		break;
+	}
 
 } /* end ray_rx */
+
 /*===========================================================================*/
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr, 
-             int rx_len)
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+		    unsigned int pkt_addr, int rx_len)
 {
-    struct sk_buff *skb = NULL;
-    struct rcs __iomem *prcslink = prcs;
-    ray_dev_t *local = netdev_priv(dev);
-    UCHAR *rx_ptr;
-    int total_len;
-    int tmp;
+	struct sk_buff *skb = NULL;
+	struct rcs __iomem *prcslink = prcs;
+	ray_dev_t *local = netdev_priv(dev);
+	UCHAR *rx_ptr;
+	int total_len;
+	int tmp;
 #ifdef WIRELESS_SPY
-    int siglev = local->last_rsl;
-    u_char linksrcaddr[ETH_ALEN];	/* Other end of the wireless link */
+	int siglev = local->last_rsl;
+	u_char linksrcaddr[ETH_ALEN];	/* Other end of the wireless link */
 #endif
 
-    if (!sniffer) {
-        if (translate) {
+	if (!sniffer) {
+		if (translate) {
 /* TBD length needs fixing for translated header */
-            if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
-                rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN)) 
-            {
-                DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
-                return;
-            }
-        }
-        else /* encapsulated ethernet */ {
-            if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
-                rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
-            {
-                DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
-                return;
-            }
-        }
-    }
-    DEBUG(4,"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");
-        tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
-            +  readb(&prcs->var.rx_packet.totalpacketlength[1]);
-        total_len = tmp;
-        prcslink = prcs;
-        do {
-            tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
-                +   readb(&prcslink->var.rx_packet.rx_data_length[1]);
-            if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
-                || tmp < 0) break;
-            prcslink = rcs_base(local)
-                + readb(&prcslink->link_field);
-        } while (1);
+			if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+			    rx_len >
+			    (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+			     FCS_LEN)) {
+				DEBUG(0,
+				      "ray_cs invalid packet length %d received \n",
+				      rx_len);
+				return;
+			}
+		} else { /* encapsulated ethernet */
 
-        if (tmp < 0)
-        {
-            DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
-            local->stats.rx_dropped++; 
-            release_frag_chain(local, prcs);
-            return;
-        }
-    }
-    else { /* Single unfragmented packet */
-        total_len = rx_len;
-    }
+			if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+			    rx_len >
+			    (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+			     FCS_LEN)) {
+				DEBUG(0,
+				      "ray_cs invalid packet length %d received \n",
+				      rx_len);
+				return;
+			}
+		}
+	}
+	DEBUG(4, "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");
+		tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
+		    + readb(&prcs->var.rx_packet.totalpacketlength[1]);
+		total_len = tmp;
+		prcslink = prcs;
+		do {
+			tmp -=
+			    (readb(&prcslink->var.rx_packet.rx_data_length[0])
+			     << 8)
+			    + readb(&prcslink->var.rx_packet.rx_data_length[1]);
+			if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
+			    == 0xFF || tmp < 0)
+				break;
+			prcslink = rcs_base(local)
+			    + readb(&prcslink->link_field);
+		} while (1);
 
-    skb = dev_alloc_skb( total_len+5 );
-    if (skb == NULL)
-    {
-        DEBUG(0,"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);
-        return;
-    }
-    skb_reserve( skb, 2);   /* Align IP on 16 byte (TBD check this)*/
+		if (tmp < 0) {
+			DEBUG(0,
+			      "ray_cs rx_data fragment lengths don't add up\n");
+			local->stats.rx_dropped++;
+			release_frag_chain(local, prcs);
+			return;
+		}
+	} else { /* Single unfragmented packet */
+		total_len = rx_len;
+	}
 
-    DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
+	skb = dev_alloc_skb(total_len + 5);
+	if (skb == NULL) {
+		DEBUG(0, "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);
+		return;
+	}
+	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,
+	      rx_len);
 
 /************************/
-    /* Reserve enough room for the whole damn packet. */
-    rx_ptr = skb_put( skb, total_len);
-    /* Copy the whole packet to sk_buff */
-    rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
-    /* Get source address */
+	/* Reserve enough room for the whole damn packet. */
+	rx_ptr = skb_put(skb, total_len);
+	/* Copy the whole packet to sk_buff */
+	rx_ptr +=
+	    copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
+	/* Get source address */
 #ifdef WIRELESS_SPY
-    skb_copy_from_linear_data_offset(skb, offsetof(struct mac_header, addr_2),
-				     linksrcaddr, ETH_ALEN);
+	skb_copy_from_linear_data_offset(skb,
+					 offsetof(struct mac_header, addr_2),
+					 linksrcaddr, ETH_ALEN);
 #endif
-    /* Now, deal with encapsulation/translation/sniffer */
-    if (!sniffer) {
-        if (!translate) { 
-            /* Encapsulated ethernet, so just lop off 802.11 MAC header */
+	/* Now, deal with encapsulation/translation/sniffer */
+	if (!sniffer) {
+		if (!translate) {
+			/* Encapsulated ethernet, so just lop off 802.11 MAC header */
 /* TBD reserve            skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
-            skb_pull( skb, RX_MAC_HEADER_LENGTH);
-        }
-        else {
-            /* Do translation */
-            untranslate(local, skb, total_len);
-        }
-    }
-    else 
-    {  /* sniffer mode, so just pass whole packet */  };
+			skb_pull(skb, RX_MAC_HEADER_LENGTH);
+		} else {
+			/* Do translation */
+			untranslate(local, skb, total_len);
+		}
+	} else { /* sniffer mode, so just pass whole packet */
+	};
 
 /************************/
-    /* Now pick up the rest of the fragments if any */
-    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");
-        do {
-            prcslink = rcs_base(local)
-                + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
-            rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
-                      + readb(&prcslink->var.rx_packet.rx_data_length[1]))
-                & RX_BUFF_END;
-            pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
-                        + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
-                & RX_BUFF_END;
+	/* Now pick up the rest of the fragments if any */
+	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");
+		do {
+			prcslink = rcs_base(local)
+			    +
+			    readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+			rx_len =
+			    ((readb(&prcslink->var.rx_packet.rx_data_length[0])
+			      << 8)
+			     +
+			     readb(&prcslink->var.rx_packet.rx_data_length[1]))
+			    & RX_BUFF_END;
+			pkt_addr =
+			    ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
+			      8)
+			     + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
+			    & RX_BUFF_END;
 
-            rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
+			rx_ptr +=
+			    copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
 
-        } while (tmp-- && 
-                 readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
-        release_frag_chain(local, prcs);
-    }
+		} while (tmp-- &&
+			 readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
+			 0xFF);
+		release_frag_chain(local, prcs);
+	}
 
-    skb->protocol = eth_type_trans(skb,dev);
-    netif_rx(skb);
-    local->stats.rx_packets++;
-    local->stats.rx_bytes += total_len;
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	local->stats.rx_packets++;
+	local->stats.rx_bytes += total_len;
 
-    /* Gather signal strength per address */
+	/* Gather signal strength per address */
 #ifdef WIRELESS_SPY
-    /* For the Access Point or the node having started the ad-hoc net
-     * note : ad-hoc work only in some specific configurations, but we
-     * kludge in ray_get_wireless_stats... */
-    if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN))
-      {
-	/* Update statistics */
-	/*local->wstats.qual.qual = none ? */
-	local->wstats.qual.level = siglev;
-	/*local->wstats.qual.noise = none ? */
-	local->wstats.qual.updated = 0x2;
-      }
-    /* Now, update the spy stuff */
-    {
-	struct iw_quality wstats;
-	wstats.level = siglev;
-	/* wstats.noise = none ? */
-	/* wstats.qual = none ? */
-	wstats.updated = 0x2;
-	/* Update spy records */
-	wireless_spy_update(dev, linksrcaddr, &wstats);
-    }
-#endif	/* WIRELESS_SPY */
+	/* For the Access Point or the node having started the ad-hoc net
+	 * note : ad-hoc work only in some specific configurations, but we
+	 * kludge in ray_get_wireless_stats... */
+	if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
+		/* Update statistics */
+		/*local->wstats.qual.qual = none ? */
+		local->wstats.qual.level = siglev;
+		/*local->wstats.qual.noise = none ? */
+		local->wstats.qual.updated = 0x2;
+	}
+	/* Now, update the spy stuff */
+	{
+		struct iw_quality wstats;
+		wstats.level = siglev;
+		/* wstats.noise = none ? */
+		/* wstats.qual = none ? */
+		wstats.updated = 0x2;
+		/* Update spy records */
+		wireless_spy_update(dev, linksrcaddr, &wstats);
+	}
+#endif /* WIRELESS_SPY */
 } /* end rx_data */
+
 /*===========================================================================*/
 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
 {
-    snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
-    struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
-    __be16 type = *(__be16 *)psnap->ethertype;
-    int delta;
-    struct ethhdr *peth;
-    UCHAR srcaddr[ADDRLEN];
-    UCHAR destaddr[ADDRLEN];
-    static UCHAR org_bridge[3] = {0, 0, 0xf8};
-    static UCHAR org_1042[3] = {0, 0, 0};
+	snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
+	struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+	__be16 type = *(__be16 *) psnap->ethertype;
+	int delta;
+	struct ethhdr *peth;
+	UCHAR srcaddr[ADDRLEN];
+	UCHAR destaddr[ADDRLEN];
+	static UCHAR org_bridge[3] = { 0, 0, 0xf8 };
+	static UCHAR org_1042[3] = { 0, 0, 0 };
 
-    memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
-    memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
+	memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+	memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
 
 #ifdef PCMCIA_DEBUG
-    if (pc_debug > 3) {
-    int i;
-    printk(KERN_DEBUG "skb->data before untranslate");
-    for (i=0;i<64;i++) 
-        printk("%02x ",skb->data[i]);
-    printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
-           ntohs(type),
-	   psnap->dsap, psnap->ssap, psnap->ctrl,
-	   psnap->org[0], psnap->org[1], psnap->org[2]);
-    printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
-    }
+	if (pc_debug > 3) {
+		int i;
+		printk(KERN_DEBUG "skb->data before untranslate");
+		for (i = 0; i < 64; i++)
+			printk("%02x ", skb->data[i]);
+		printk("\n" KERN_DEBUG
+		       "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+		       ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
+		       psnap->org[0], psnap->org[1], psnap->org[2]);
+		printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
+	}
 #endif
 
-    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",
-		psnap->dsap, psnap->ssap, psnap->ctrl);
+	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",
+		      psnap->dsap, psnap->ssap, psnap->ctrl);
 
-        delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
-        peth = (struct ethhdr *)(skb->data + delta);
-        peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
-    }
-    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");
-            delta = RX_MAC_HEADER_LENGTH 
-                + sizeof(struct snaphdr_t) - ETH_HLEN;
-            peth = (struct ethhdr *)(skb->data + delta);
-            peth->h_proto = type;
-	} else if (memcmp(psnap->org, org_1042, 3) == 0) {
-                switch (ntohs(type)) {
-                case ETH_P_IPX:
-                case ETH_P_AARP:
-                    DEBUG(3,"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");
-                    delta = RX_MAC_HEADER_LENGTH + 
-                        sizeof(struct snaphdr_t) - ETH_HLEN;
-                    peth = (struct ethhdr *)(skb->data + delta);
-                    peth->h_proto = type;
-                    break;
-                }
-	} else {
-                printk("ray_cs untranslate very confused by packet\n");
-                delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
-                peth = (struct ethhdr *)(skb->data + delta);
-                peth->h_proto = type;
+		delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+		peth = (struct ethhdr *)(skb->data + delta);
+		peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
+	} 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");
+			delta = RX_MAC_HEADER_LENGTH
+			    + sizeof(struct snaphdr_t) - ETH_HLEN;
+			peth = (struct ethhdr *)(skb->data + delta);
+			peth->h_proto = type;
+		} else if (memcmp(psnap->org, org_1042, 3) == 0) {
+			switch (ntohs(type)) {
+			case ETH_P_IPX:
+			case ETH_P_AARP:
+				DEBUG(3, "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");
+				delta = RX_MAC_HEADER_LENGTH +
+				    sizeof(struct snaphdr_t) - ETH_HLEN;
+				peth = (struct ethhdr *)(skb->data + delta);
+				peth->h_proto = type;
+				break;
+			}
+		} else {
+			printk("ray_cs untranslate very confused by packet\n");
+			delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+			peth = (struct ethhdr *)(skb->data + delta);
+			peth->h_proto = type;
+		}
 	}
-    }
 /* TBD reserve  skb_reserve(skb, delta); */
-    skb_pull(skb, delta);
-    DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
-    memcpy(peth->h_dest, destaddr, ADDRLEN);
-    memcpy(peth->h_source, srcaddr, ADDRLEN);
+	skb_pull(skb, delta);
+	DEBUG(3, "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) {
-    int i;
-    printk(KERN_DEBUG "skb->data after untranslate:");
-    for (i=0;i<64;i++)
-        printk("%02x ",skb->data[i]);
-    printk("\n");
-    }
+	if (pc_debug > 3) {
+		int i;
+		printk(KERN_DEBUG "skb->data after untranslate:");
+		for (i = 0; i < 64; i++)
+			printk("%02x ", skb->data[i]);
+		printk("\n");
+	}
 #endif
 } /* end untranslate */
+
 /*===========================================================================*/
 /* Copy data from circular receive buffer to PC memory.
  * dest     = destination address in PC memory
  * pkt_addr = source address in receive buffer
  * len      = length of packet to copy
  */
-static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
+static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
+			     int length)
 {
-    int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
-    if (wrap_bytes <= 0)
-    {
-        memcpy_fromio(dest,local->rmem + pkt_addr,length);
-    }
-    else /* Packet wrapped in circular buffer */
-    {
-        memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
-        memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
-    }
-    return length;
+	int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
+	if (wrap_bytes <= 0) {
+		memcpy_fromio(dest, local->rmem + pkt_addr, length);
+	} else { /* Packet wrapped in circular buffer */
+
+		memcpy_fromio(dest, local->rmem + pkt_addr,
+			      length - wrap_bytes);
+		memcpy_fromio(dest + length - wrap_bytes, local->rmem,
+			      wrap_bytes);
+	}
+	return length;
 }
+
 /*===========================================================================*/
-static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
+static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
 {
-    struct rcs __iomem *prcslink = prcs;
-    int tmp = 17;
-    unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
+	struct rcs __iomem *prcslink = prcs;
+	int tmp = 17;
+	unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
 
-    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",rcsindex);
-            break;      
-        }   
-        prcslink = rcs_base(local) + rcsindex;
-        rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
-    }
-    writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
+	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",
+			      rcsindex);
+			break;
+		}
+		prcslink = rcs_base(local) + rcsindex;
+		rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+	}
+	writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
 }
+
 /*===========================================================================*/
 static void authenticate(ray_dev_t *local)
 {
-    struct pcmcia_device *link = local->finder;
-    DEBUG(0,"ray_cs Starting authentication.\n");
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs authenticate - device not present\n");
-        return;
-    }
+	struct pcmcia_device *link = local->finder;
+	DEBUG(0, "ray_cs Starting authentication.\n");
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "ray_cs authenticate - device not present\n");
+		return;
+	}
 
-    del_timer(&local->timer);
-    if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
-        local->timer.function = &join_net;
-    }
-    else {
-        local->timer.function = &authenticate_timeout;
-    }
-    local->timer.expires = jiffies + HZ*2;
-    local->timer.data = (long)local;
-    add_timer(&local->timer);
-    local->authentication_state = AWAITING_RESPONSE;
+	del_timer(&local->timer);
+	if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
+		local->timer.function = &join_net;
+	} else {
+		local->timer.function = &authenticate_timeout;
+	}
+	local->timer.expires = jiffies + HZ * 2;
+	local->timer.data = (long)local;
+	add_timer(&local->timer);
+	local->authentication_state = AWAITING_RESPONSE;
 } /* end authenticate */
+
 /*===========================================================================*/
 static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
-                     unsigned int pkt_addr, int rx_len)
+			    unsigned int pkt_addr, int rx_len)
 {
-    UCHAR buff[256];
-    struct rx_msg *msg = (struct rx_msg *)buff;
-    
-    del_timer(&local->timer);
+	UCHAR buff[256];
+	struct rx_msg *msg = (struct rx_msg *)buff;
 
-    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", 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");
-                    if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
-                        local->authentication_state = NEED_TO_AUTH;
-                        memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
-                    }
-        }
-    }
-    else /* Infrastructure network */
-    {
-        if (local->authentication_state == AWAITING_RESPONSE) {
-            /* Verify authentication sequence #2 and success */
-            if (msg->var[2] == 2) {
-                if ((msg->var[3] | msg->var[4]) == 0) {
-                    DEBUG(1,"Authentication successful\n");
-                    local->card_status = CARD_AUTH_COMPLETE;
-                    associate(local);
-                    local->authentication_state = AUTHENTICATED;
-                }
-                else {
-                    DEBUG(0,"Authentication refused\n");
-                    local->card_status = CARD_AUTH_REFUSED;
-                    join_net((u_long)local);
-                    local->authentication_state = UNAUTHENTICATED;
-                }
-            }
-        }
-    }
+	del_timer(&local->timer);
+
+	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",
+		      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");
+			if (!build_auth_frame
+			    (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
+				local->authentication_state = NEED_TO_AUTH;
+				memcpy(local->auth_id, msg->mac.addr_2,
+				       ADDRLEN);
+			}
+		}
+	} else { /* Infrastructure network */
+
+		if (local->authentication_state == AWAITING_RESPONSE) {
+			/* Verify authentication sequence #2 and success */
+			if (msg->var[2] == 2) {
+				if ((msg->var[3] | msg->var[4]) == 0) {
+					DEBUG(1, "Authentication successful\n");
+					local->card_status = CARD_AUTH_COMPLETE;
+					associate(local);
+					local->authentication_state =
+					    AUTHENTICATED;
+				} else {
+					DEBUG(0, "Authentication refused\n");
+					local->card_status = CARD_AUTH_REFUSED;
+					join_net((u_long) local);
+					local->authentication_state =
+					    UNAUTHENTICATED;
+				}
+			}
+		}
+	}
 
 } /* end rx_authenticate */
+
 /*===========================================================================*/
 static void associate(ray_dev_t *local)
 {
-    struct ccs __iomem *pccs;
-    struct pcmcia_device *link = local->finder;
-    struct net_device *dev = link->priv;
-    int ccsindex;
-    if (!(pcmcia_dev_present(link))) {
-        DEBUG(2,"ray_cs associate - device not present\n");
-        return;
-    }
-    /* If no tx buffers available, return*/
-    if ((ccsindex = get_free_ccs(local)) < 0)
-    {
+	struct ccs __iomem *pccs;
+	struct pcmcia_device *link = local->finder;
+	struct net_device *dev = link->priv;
+	int ccsindex;
+	if (!(pcmcia_dev_present(link))) {
+		DEBUG(2, "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");
-        return;
-    }
-    DEBUG(1,"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");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+		DEBUG(1, "ray_cs associate - No free ccs\n");
+		return;
+	}
+	DEBUG(1, "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");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 
-        del_timer(&local->timer);
-        local->timer.expires = jiffies + HZ*2;
-        local->timer.data = (long)local;
-        local->timer.function = &join_net;
-        add_timer(&local->timer);
-        local->card_status = CARD_ASSOC_FAILED;
-        return;
-    }
-    if (!sniffer) netif_start_queue(dev);
+		del_timer(&local->timer);
+		local->timer.expires = jiffies + HZ * 2;
+		local->timer.data = (long)local;
+		local->timer.function = &join_net;
+		add_timer(&local->timer);
+		local->card_status = CARD_ASSOC_FAILED;
+		return;
+	}
+	if (!sniffer)
+		netif_start_queue(dev);
 
 } /* end associate */
+
 /*===========================================================================*/
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, 
-                       unsigned int pkt_addr, int rx_len)
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+			      unsigned int pkt_addr, int rx_len)
 {
 /*  UCHAR buff[256];
     struct rx_msg *msg = (struct rx_msg *)buff;
 */
-    DEBUG(0,"Deauthentication frame received\n");
-    local->authentication_state = UNAUTHENTICATED;
-    /* Need to reauthenticate or rejoin depending on reason code */
+	DEBUG(0, "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);
  */
 }
+
 /*===========================================================================*/
 static void clear_interrupt(ray_dev_t *local)
 {
-    writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
+	writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
 }
+
 /*===========================================================================*/
 #ifdef CONFIG_PROC_FS
 #define MAXDATA (PAGE_SIZE - 80)
 
 static char *card_status[] = {
-    "Card inserted - uninitialized",     /* 0 */
-    "Card not downloaded",               /* 1 */
-    "Waiting for download parameters",   /* 2 */
-    "Card doing acquisition",            /* 3 */
-    "Acquisition complete",              /* 4 */
-    "Authentication complete",           /* 5 */
-    "Association complete",              /* 6 */
-    "???", "???", "???", "???",          /* 7 8 9 10 undefined */
-    "Card init error",                   /* 11 */
-    "Download parameters error",         /* 12 */
-    "???",                               /* 13 */
-    "Acquisition failed",                /* 14 */
-    "Authentication refused",            /* 15 */
-    "Association failed"                 /* 16 */
+	"Card inserted - uninitialized",	/* 0 */
+	"Card not downloaded",			/* 1 */
+	"Waiting for download parameters",	/* 2 */
+	"Card doing acquisition",		/* 3 */
+	"Acquisition complete",			/* 4 */
+	"Authentication complete",		/* 5 */
+	"Association complete",			/* 6 */
+	"???", "???", "???", "???",		/* 7 8 9 10 undefined */
+	"Card init error",			/* 11 */
+	"Download parameters error",		/* 12 */
+	"???",					/* 13 */
+	"Acquisition failed",			/* 14 */
+	"Authentication refused",		/* 15 */
+	"Association failed"			/* 16 */
 };
 
-static char *nettype[] = {"Adhoc", "Infra "};
-static char *framing[] = {"Encapsulation", "Translation"}
+static char *nettype[] = { "Adhoc", "Infra " };
+static char *framing[] = { "Encapsulation", "Translation" }
+
 ;
 /*===========================================================================*/
 static int ray_cs_proc_show(struct seq_file *m, void *v)
 {
 /* Print current values which are not available via other means
- * eg ifconfig 
+ * eg ifconfig
  */
-    int i;
-    struct pcmcia_device *link;
-    struct net_device *dev;
-    ray_dev_t *local;
-    UCHAR *p;
-    struct freq_hop_element *pfh;
-    UCHAR c[33];
+	int i;
+	struct pcmcia_device *link;
+	struct net_device *dev;
+	ray_dev_t *local;
+	UCHAR *p;
+	struct freq_hop_element *pfh;
+	UCHAR c[33];
 
-    link = this_device;
-    if (!link)
-    	return 0;
-    dev = (struct net_device *)link->priv;
-    if (!dev)
-    	return 0;
-    local = netdev_priv(dev);
-    if (!local)
-    	return 0;
+	link = this_device;
+	if (!link)
+		return 0;
+	dev = (struct net_device *)link->priv;
+	if (!dev)
+		return 0;
+	local = netdev_priv(dev);
+	if (!local)
+		return 0;
 
-    seq_puts(m, "Raylink Wireless LAN driver status\n");
-    seq_printf(m, "%s\n", rcsid);
-    /* build 4 does not report version, and field is 0x55 after memtest */
-    seq_puts(m, "Firmware version     = ");
-    if (local->fw_ver == 0x55)
-        seq_puts(m, "4 - Use dump_cis for more details\n");
-    else
-        seq_printf(m, "%2d.%02d.%02d\n",
-                   local->fw_ver, local->fw_bld, local->fw_var);
+	seq_puts(m, "Raylink Wireless LAN driver status\n");
+	seq_printf(m, "%s\n", rcsid);
+	/* build 4 does not report version, and field is 0x55 after memtest */
+	seq_puts(m, "Firmware version     = ");
+	if (local->fw_ver == 0x55)
+		seq_puts(m, "4 - Use dump_cis for more details\n");
+	else
+		seq_printf(m, "%2d.%02d.%02d\n",
+			   local->fw_ver, local->fw_bld, local->fw_var);
 
-    for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
-    c[32] = 0;
-    seq_printf(m, "%s network ESSID = \"%s\"\n",
-                   nettype[local->sparm.b5.a_network_type], c);
+	for (i = 0; i < 32; i++)
+		c[i] = local->sparm.b5.a_current_ess_id[i];
+	c[32] = 0;
+	seq_printf(m, "%s network ESSID = \"%s\"\n",
+		   nettype[local->sparm.b5.a_network_type], c);
 
-    p = local->bss_id;
-    seq_printf(m, "BSSID                = %pM\n", p);
+	p = local->bss_id;
+	seq_printf(m, "BSSID                = %pM\n", p);
 
-    seq_printf(m, "Country code         = %d\n",
-                   local->sparm.b5.a_curr_country_code);
+	seq_printf(m, "Country code         = %d\n",
+		   local->sparm.b5.a_curr_country_code);
 
-    i = local->card_status;
-    if (i < 0) i = 10;
-    if (i > 16) i = 10;
-    seq_printf(m, "Card status          = %s\n", card_status[i]);
+	i = local->card_status;
+	if (i < 0)
+		i = 10;
+	if (i > 16)
+		i = 10;
+	seq_printf(m, "Card status          = %s\n", card_status[i]);
 
-    seq_printf(m, "Framing mode         = %s\n",framing[translate]);
+	seq_printf(m, "Framing mode         = %s\n", framing[translate]);
 
-    seq_printf(m, "Last pkt signal lvl  = %d\n", local->last_rsl);
+	seq_printf(m, "Last pkt signal lvl  = %d\n", local->last_rsl);
 
-    if (local->beacon_rxed) {
-	/* Pull some fields out of last beacon received */
-	seq_printf(m, "Beacon Interval      = %d Kus\n",
-		       local->last_bcn.beacon_intvl[0]
-		       + 256 * local->last_bcn.beacon_intvl[1]);
-    
-    p = local->last_bcn.elements;
-    if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
-    else {
-        seq_printf(m, "Parse beacon failed at essid element id = %d\n",p[0]);
-        return 0;
-    }
+	if (local->beacon_rxed) {
+		/* Pull some fields out of last beacon received */
+		seq_printf(m, "Beacon Interval      = %d Kus\n",
+			   local->last_bcn.beacon_intvl[0]
+			   + 256 * local->last_bcn.beacon_intvl[1]);
 
-    if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
-        seq_puts(m, "Supported rate codes = ");
-        for (i=2; i<p[1] + 2; i++) 
-            seq_printf(m, "0x%02x ", p[i]);
-        seq_putc(m, '\n');
-        p += p[1] + 2;
-    }
-    else {
-        seq_puts(m, "Parse beacon failed at rates element\n");
-        return 0;
-    }
+		p = local->last_bcn.elements;
+		if (p[0] == C_ESSID_ELEMENT_ID)
+			p += p[1] + 2;
+		else {
+			seq_printf(m,
+				   "Parse beacon failed at essid element id = %d\n",
+				   p[0]);
+			return 0;
+		}
 
-	if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
-	    pfh = (struct freq_hop_element *)p;
-	    seq_printf(m, "Hop dwell            = %d Kus\n",
-			   pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
-	    seq_printf(m, "Hop set              = %d \n", pfh->hop_set);
-	    seq_printf(m, "Hop pattern          = %d \n", pfh->hop_pattern);
-	    seq_printf(m, "Hop index            = %d \n", pfh->hop_index);
-	    p += p[1] + 2;
-	}
-	else {
-	    seq_puts(m, "Parse beacon failed at FH param element\n");
-	    return 0;
+		if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
+			seq_puts(m, "Supported rate codes = ");
+			for (i = 2; i < p[1] + 2; i++)
+				seq_printf(m, "0x%02x ", p[i]);
+			seq_putc(m, '\n');
+			p += p[1] + 2;
+		} else {
+			seq_puts(m, "Parse beacon failed at rates element\n");
+			return 0;
+		}
+
+		if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
+			pfh = (struct freq_hop_element *)p;
+			seq_printf(m, "Hop dwell            = %d Kus\n",
+				   pfh->dwell_time[0] +
+				   256 * pfh->dwell_time[1]);
+			seq_printf(m, "Hop set              = %d \n",
+				   pfh->hop_set);
+			seq_printf(m, "Hop pattern          = %d \n",
+				   pfh->hop_pattern);
+			seq_printf(m, "Hop index            = %d \n",
+				   pfh->hop_index);
+			p += p[1] + 2;
+		} else {
+			seq_puts(m,
+				 "Parse beacon failed at FH param element\n");
+			return 0;
+		}
+	} else {
+		seq_puts(m, "No beacons received\n");
 	}
-    } else {
-	seq_puts(m, "No beacons received\n");
-    }
-    return 0;
+	return 0;
 }
 
 static int ray_cs_proc_open(struct inode *inode, struct file *file)
@@ -2684,74 +2806,77 @@ static int ray_cs_proc_open(struct inode
 }
 
 static const struct file_operations ray_cs_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= ray_cs_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
+	.owner = THIS_MODULE,
+	.open = ray_cs_proc_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
 };
 #endif
 /*===========================================================================*/
 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
 {
-    int addr;
-    struct ccs __iomem *pccs;
-    struct tx_msg __iomem *ptx;
-    int ccsindex;
+	int addr;
+	struct ccs __iomem *pccs;
+	struct tx_msg __iomem *ptx;
+	int ccsindex;
 
-    /* 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");
-        return -1;
-    }
+	/* 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");
+		return -1;
+	}
 
-    pccs = ccs_base(local) + ccsindex;
+	pccs = ccs_base(local) + ccsindex;
 
-    /* Address in card space */
-    addr = TX_BUF_BASE + (ccsindex << 11);
-    /* fill in the CCS */
-    writeb(CCS_TX_REQUEST, &pccs->cmd);
-    writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
-    writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
-    writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
-    writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
-    writeb(0, &pccs->var.tx_request.pow_sav_mode);
+	/* Address in card space */
+	addr = TX_BUF_BASE + (ccsindex << 11);
+	/* fill in the CCS */
+	writeb(CCS_TX_REQUEST, &pccs->cmd);
+	writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
+	writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
+	writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
+	writeb(TX_AUTHENTICATE_LENGTH_LSB,
+	       pccs->var.tx_request.tx_data_length + 1);
+	writeb(0, &pccs->var.tx_request.pow_sav_mode);
 
-    ptx = local->sram + addr;
-    /* fill in the mac header */
-    writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
-    writeb(0, &ptx->mac.frame_ctl_2);
+	ptx = local->sram + addr;
+	/* fill in the mac header */
+	writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
+	writeb(0, &ptx->mac.frame_ctl_2);
 
-    memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
-    memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
-    memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+	memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
+	memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
+	memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
 
-    /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
-    memset_io(ptx->var, 0, 6);
-    writeb(auth_type & 0xff, ptx->var + 2);
+	/* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
+	memset_io(ptx->var, 0, 6);
+	writeb(auth_type & 0xff, ptx->var + 2);
 
-    /* Interrupt the firmware to process the command */
-    if (interrupt_ecf(local, ccsindex)) {
-        DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
-        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-        return -1;
-    }
-    return 0;
+	/* Interrupt the firmware to process the command */
+	if (interrupt_ecf(local, ccsindex)) {
+		DEBUG(1,
+		      "ray_cs send authentication request failed - ECF not ready for intr\n");
+		writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+		return -1;
+	}
+	return 0;
 } /* End build_auth_frame */
 
 /*===========================================================================*/
 #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);
+	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 int write_essid(struct file *file, const char __user *buffer,
+		       unsigned long count, void *data)
 {
 	static char proc_essid[33];
 	int len = count;
@@ -2765,7 +2890,8 @@ 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 int write_int(struct file *file, const char __user *buffer,
+		     unsigned long count, void *data)
 {
 	static char proc_number[10];
 	char *p;
@@ -2785,7 +2911,7 @@ static int write_int(struct file *file,
 		unsigned int c = *p - '0';
 		if (c > 9)
 			return -EINVAL;
-		nr = nr*10 + c;
+		nr = nr * 10 + c;
 		p++;
 	} while (--len);
 	*(int *)data = nr;
@@ -2797,55 +2923,58 @@ static struct pcmcia_device_id ray_ids[]
 	PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
 	PCMCIA_DEVICE_NULL,
 };
+
 MODULE_DEVICE_TABLE(pcmcia, ray_ids);
 
 static struct pcmcia_driver ray_driver = {
-	.owner		= THIS_MODULE,
-	.drv		= {
-		.name	= "ray_cs",
-	},
-	.probe		= ray_probe,
-	.remove		= ray_detach,
-	.id_table       = ray_ids,
-	.suspend	= ray_suspend,
-	.resume		= ray_resume,
+	.owner = THIS_MODULE,
+	.drv = {
+		.name = "ray_cs",
+		},
+	.probe = ray_probe,
+	.remove = ray_detach,
+	.id_table = ray_ids,
+	.suspend = ray_suspend,
+	.resume = ray_resume,
 };
 
 static int __init init_ray_cs(void)
 {
-    int rc;
-    
-    DEBUG(1, "%s\n", rcsid);
-    rc = pcmcia_register_driver(&ray_driver);
-    DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
+	int rc;
+
+	DEBUG(1, "%s\n", rcsid);
+	rc = pcmcia_register_driver(&ray_driver);
+	DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+	      rc);
 
 #ifdef CONFIG_PROC_FS
-    proc_mkdir("driver/ray_cs", NULL);
+	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/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);
 #endif
-    if (translate != 0) translate = 1;
-    return 0;
+	if (translate != 0)
+		translate = 1;
+	return 0;
 } /* init_ray_cs */
 
 /*===========================================================================*/
 
 static void __exit exit_ray_cs(void)
 {
-    DEBUG(0, "ray_cs: cleanup_module\n");
+	DEBUG(0, "ray_cs: cleanup_module\n");
 
 #ifdef CONFIG_PROC_FS
-    remove_proc_entry("driver/ray_cs/ray_cs", NULL);
-    remove_proc_entry("driver/ray_cs/essid", NULL);
-    remove_proc_entry("driver/ray_cs/net_type", NULL);
-    remove_proc_entry("driver/ray_cs/translate", NULL);
-    remove_proc_entry("driver/ray_cs", NULL);
+	remove_proc_entry("driver/ray_cs/ray_cs", NULL);
+	remove_proc_entry("driver/ray_cs/essid", NULL);
+	remove_proc_entry("driver/ray_cs/net_type", NULL);
+	remove_proc_entry("driver/ray_cs/translate", NULL);
+	remove_proc_entry("driver/ray_cs", NULL);
 #endif
 
-    pcmcia_unregister_driver(&ray_driver);
+	pcmcia_unregister_driver(&ray_driver);
 } /* exit_ray_cs */
 
 module_init(init_ray_cs);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rndis_wlan.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rndis_wlan.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rndis_wlan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rndis_wlan.c	2009-06-09 23:05:27.000000000 -0400
@@ -90,44 +90,44 @@ MODULE_PARM_DESC(workaround_interval,
 
 
 /* various RNDIS OID defs */
-#define OID_GEN_LINK_SPEED			ccpu2(0x00010107)
-#define OID_GEN_RNDIS_CONFIG_PARAMETER		ccpu2(0x0001021b)
+#define OID_GEN_LINK_SPEED			cpu_to_le32(0x00010107)
+#define OID_GEN_RNDIS_CONFIG_PARAMETER		cpu_to_le32(0x0001021b)
 
-#define OID_GEN_XMIT_OK				ccpu2(0x00020101)
-#define OID_GEN_RCV_OK				ccpu2(0x00020102)
-#define OID_GEN_XMIT_ERROR			ccpu2(0x00020103)
-#define OID_GEN_RCV_ERROR			ccpu2(0x00020104)
-#define OID_GEN_RCV_NO_BUFFER			ccpu2(0x00020105)
+#define OID_GEN_XMIT_OK				cpu_to_le32(0x00020101)
+#define OID_GEN_RCV_OK				cpu_to_le32(0x00020102)
+#define OID_GEN_XMIT_ERROR			cpu_to_le32(0x00020103)
+#define OID_GEN_RCV_ERROR			cpu_to_le32(0x00020104)
+#define OID_GEN_RCV_NO_BUFFER			cpu_to_le32(0x00020105)
 
-#define OID_802_3_PERMANENT_ADDRESS		ccpu2(0x01010101)
-#define OID_802_3_CURRENT_ADDRESS		ccpu2(0x01010102)
-#define OID_802_3_MULTICAST_LIST		ccpu2(0x01010103)
-#define OID_802_3_MAXIMUM_LIST_SIZE		ccpu2(0x01010104)
+#define OID_802_3_PERMANENT_ADDRESS		cpu_to_le32(0x01010101)
+#define OID_802_3_CURRENT_ADDRESS		cpu_to_le32(0x01010102)
+#define OID_802_3_MULTICAST_LIST		cpu_to_le32(0x01010103)
+#define OID_802_3_MAXIMUM_LIST_SIZE		cpu_to_le32(0x01010104)
 
-#define OID_802_11_BSSID			ccpu2(0x0d010101)
-#define OID_802_11_SSID				ccpu2(0x0d010102)
-#define OID_802_11_INFRASTRUCTURE_MODE		ccpu2(0x0d010108)
-#define OID_802_11_ADD_WEP			ccpu2(0x0d010113)
-#define OID_802_11_REMOVE_WEP			ccpu2(0x0d010114)
-#define OID_802_11_DISASSOCIATE			ccpu2(0x0d010115)
-#define OID_802_11_AUTHENTICATION_MODE		ccpu2(0x0d010118)
-#define OID_802_11_PRIVACY_FILTER		ccpu2(0x0d010119)
-#define OID_802_11_BSSID_LIST_SCAN		ccpu2(0x0d01011a)
-#define OID_802_11_ENCRYPTION_STATUS		ccpu2(0x0d01011b)
-#define OID_802_11_ADD_KEY			ccpu2(0x0d01011d)
-#define OID_802_11_REMOVE_KEY			ccpu2(0x0d01011e)
-#define OID_802_11_ASSOCIATION_INFORMATION	ccpu2(0x0d01011f)
-#define OID_802_11_PMKID			ccpu2(0x0d010123)
-#define OID_802_11_NETWORK_TYPES_SUPPORTED	ccpu2(0x0d010203)
-#define OID_802_11_NETWORK_TYPE_IN_USE		ccpu2(0x0d010204)
-#define OID_802_11_TX_POWER_LEVEL		ccpu2(0x0d010205)
-#define OID_802_11_RSSI				ccpu2(0x0d010206)
-#define OID_802_11_RSSI_TRIGGER			ccpu2(0x0d010207)
-#define OID_802_11_FRAGMENTATION_THRESHOLD	ccpu2(0x0d010209)
-#define OID_802_11_RTS_THRESHOLD		ccpu2(0x0d01020a)
-#define OID_802_11_SUPPORTED_RATES		ccpu2(0x0d01020e)
-#define OID_802_11_CONFIGURATION		ccpu2(0x0d010211)
-#define OID_802_11_BSSID_LIST			ccpu2(0x0d010217)
+#define OID_802_11_BSSID			cpu_to_le32(0x0d010101)
+#define OID_802_11_SSID				cpu_to_le32(0x0d010102)
+#define OID_802_11_INFRASTRUCTURE_MODE		cpu_to_le32(0x0d010108)
+#define OID_802_11_ADD_WEP			cpu_to_le32(0x0d010113)
+#define OID_802_11_REMOVE_WEP			cpu_to_le32(0x0d010114)
+#define OID_802_11_DISASSOCIATE			cpu_to_le32(0x0d010115)
+#define OID_802_11_AUTHENTICATION_MODE		cpu_to_le32(0x0d010118)
+#define OID_802_11_PRIVACY_FILTER		cpu_to_le32(0x0d010119)
+#define OID_802_11_BSSID_LIST_SCAN		cpu_to_le32(0x0d01011a)
+#define OID_802_11_ENCRYPTION_STATUS		cpu_to_le32(0x0d01011b)
+#define OID_802_11_ADD_KEY			cpu_to_le32(0x0d01011d)
+#define OID_802_11_REMOVE_KEY			cpu_to_le32(0x0d01011e)
+#define OID_802_11_ASSOCIATION_INFORMATION	cpu_to_le32(0x0d01011f)
+#define OID_802_11_PMKID			cpu_to_le32(0x0d010123)
+#define OID_802_11_NETWORK_TYPES_SUPPORTED	cpu_to_le32(0x0d010203)
+#define OID_802_11_NETWORK_TYPE_IN_USE		cpu_to_le32(0x0d010204)
+#define OID_802_11_TX_POWER_LEVEL		cpu_to_le32(0x0d010205)
+#define OID_802_11_RSSI				cpu_to_le32(0x0d010206)
+#define OID_802_11_RSSI_TRIGGER			cpu_to_le32(0x0d010207)
+#define OID_802_11_FRAGMENTATION_THRESHOLD	cpu_to_le32(0x0d010209)
+#define OID_802_11_RTS_THRESHOLD		cpu_to_le32(0x0d01020a)
+#define OID_802_11_SUPPORTED_RATES		cpu_to_le32(0x0d01020e)
+#define OID_802_11_CONFIGURATION		cpu_to_le32(0x0d010211)
+#define OID_802_11_BSSID_LIST			cpu_to_le32(0x0d010217)
 
 
 /* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
@@ -144,8 +144,8 @@ MODULE_PARM_DESC(workaround_interval,
 
 
 /* codes for "status" field of completion messages */
-#define RNDIS_STATUS_ADAPTER_NOT_READY		ccpu2(0xc0010011)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN		ccpu2(0xc0010012)
+#define RNDIS_STATUS_ADAPTER_NOT_READY		cpu_to_le32(0xc0010011)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN		cpu_to_le32(0xc0010012)
 
 
 /* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
@@ -369,9 +369,6 @@ struct rndis_wext_private {
 };
 
 
-static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
-				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
 static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
 
 static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
@@ -445,7 +442,7 @@ static int rndis_query_oid(struct usbnet
 
 	memset(u.get, 0, sizeof *u.get);
 	u.get->msg_type = RNDIS_MSG_QUERY;
-	u.get->msg_len = ccpu2(sizeof *u.get);
+	u.get->msg_len = cpu_to_le32(sizeof *u.get);
 	u.get->oid = oid;
 
 	ret = rndis_command(dev, u.header, buflen);
@@ -494,8 +491,8 @@ static int rndis_set_oid(struct usbnet *
 	u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
 	u.set->oid = oid;
 	u.set->len = cpu_to_le32(len);
-	u.set->offset = ccpu2(sizeof(*u.set) - 8);
-	u.set->handle = ccpu2(0);
+	u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
+	u.set->handle = cpu_to_le32(0);
 	memcpy(u.buf + sizeof(*u.set), data, len);
 
 	ret = rndis_command(dev, u.header, buflen);
@@ -640,8 +637,8 @@ static void dsconfig_to_freq(unsigned in
 static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
 {
 	if (freq->m < 1000 && freq->e == 0) {
-		if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan))
-			*dsconfig = freq_chan[freq->m - 1] * 1000;
+		if (freq->m >= 1 && freq->m <= 14)
+			*dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
 		else
 			return -1;
 	} else {
@@ -1178,11 +1175,11 @@ static int rndis_iw_get_range(struct net
 		range->throughput = 11 * 1000 * 1000 / 2;
 	}
 
-	range->num_channels = ARRAY_SIZE(freq_chan);
+	range->num_channels = 14;
 
-	for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) {
+	for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
 		range->freq[i].i = i + 1;
-		range->freq[i].m = freq_chan[i] * 100000;
+		range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
 		range->freq[i].e = 1;
 	}
 	range->num_frequency = i;
@@ -1633,7 +1630,7 @@ static int rndis_iw_set_scan(struct net_
 	devdbg(usbdev, "SIOCSIWSCAN");
 
 	if (wrqu->data.flags == 0) {
-		tmp = ccpu2(1);
+		tmp = cpu_to_le32(1);
 		ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
 								sizeof(tmp));
 		evt.data.flags = 0;
@@ -2431,7 +2428,7 @@ static void rndis_update_wireless_stats(
 		/* Send scan OID. Use of both OIDs is required to get device
 		 * working.
 		 */
-		tmp = ccpu2(1);
+		tmp = cpu_to_le32(1);
 		rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
 								sizeof(tmp));
 
@@ -2527,6 +2524,17 @@ static int bcm4320_early_init(struct usb
 	return 0;
 }
 
+/* same as rndis_netdev_ops but with local multicast handler */
+static const struct net_device_ops rndis_wext_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_multicast_list	= rndis_wext_set_multicast_list,
+};
+
 
 static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
 {
@@ -2550,6 +2558,11 @@ static int rndis_wext_bind(struct usbnet
 	mutex_init(&priv->command_lock);
 	spin_lock_init(&priv->stats_lock);
 
+	/* because rndis_command() sleeps we need to use workqueue */
+	priv->workqueue = create_singlethread_workqueue("rndis_wlan");
+	INIT_WORK(&priv->work, rndis_wext_worker);
+	INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+
 	/* try bind rndis_host */
 	retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
 	if (retval < 0)
@@ -2562,7 +2575,8 @@ static int rndis_wext_bind(struct usbnet
 	 * rndis_host wants to avoid all OID as much as possible
 	 * so do promisc/multicast handling in rndis_wext.
 	 */
-	usbdev->net->set_multicast_list = rndis_wext_set_multicast_list;
+	usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
+
 	tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
 	retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
 								sizeof(tmp));
@@ -2594,16 +2608,17 @@ static int rndis_wext_bind(struct usbnet
 	disassociate(usbdev, 1);
 	netif_carrier_off(usbdev->net);
 
-	/* because rndis_command() sleeps we need to use workqueue */
-	priv->workqueue = create_singlethread_workqueue("rndis_wlan");
-	INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
 	queue_delayed_work(priv->workqueue, &priv->stats_work,
 		round_jiffies_relative(STATS_UPDATE_JIFFIES));
-	INIT_WORK(&priv->work, rndis_wext_worker);
 
 	return 0;
 
 fail:
+	cancel_delayed_work_sync(&priv->stats_work);
+	cancel_work_sync(&priv->work);
+	flush_workqueue(priv->workqueue);
+	destroy_workqueue(priv->workqueue);
+
 	kfree(priv);
 	return retval;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/Kconfig linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -97,10 +97,11 @@ config RT2X00_LIB_CRYPTO
 
 config RT2X00_LIB_RFKILL
 	boolean
-	default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n)
+	default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n)
+	select INPUT_POLLDEV
 
-comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00"
-	depends on RT2X00_LIB=y && RFKILL=m
+comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00"
+	depends on RT2X00_LIB=y && INPUT=m
 
 config RT2X00_LIB_LEDS
 	boolean
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/Makefile linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/Makefile
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,6 +2,7 @@ rt2x00lib-y				+= rt2x00dev.o
 rt2x00lib-y				+= rt2x00mac.o
 rt2x00lib-y				+= rt2x00config.o
 rt2x00lib-y				+= rt2x00queue.o
+rt2x00lib-y				+= rt2x00link.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS)	+= rt2x00debug.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO)	+= rt2x00crypto.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL)	+= rt2x00rfkill.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2400pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2400pci_rf_write(struct rt
 {
 	u32 reg;
 
-	if (!word)
-		return;
-
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -524,6 +521,32 @@ static void rt2400pci_config_duration(st
 	rt2x00pci_register_write(rt2x00dev, CSR12, reg);
 }
 
+static void rt2400pci_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) {
+		rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+		rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+				   (libconf->conf->beacon_int - 20) * 16);
+		rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+				   libconf->conf->listen_interval - 1);
+
+		/* We must first disable autowake before it can be enabled */
+		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+	}
+
+	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
 static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
 			     struct rt2x00lib_conf *libconf,
 			     const unsigned int flags)
@@ -537,6 +560,8 @@ static void rt2400pci_config(struct rt2x
 		rt2400pci_config_retry_limit(rt2x00dev, libconf);
 	if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
 		rt2400pci_config_duration(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt2400pci_config_ps(rt2x00dev, libconf);
 }
 
 static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
@@ -572,35 +597,37 @@ static void rt2400pci_link_stats(struct
 	qual->false_cca = bbp;
 }
 
-static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+				     struct link_qual *qual, u8 vgc_level)
 {
-	rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
-	rt2x00dev->link.vgc_level = 0x08;
+	rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+	qual->vgc_level = vgc_level;
+	qual->vgc_level_reg = vgc_level;
 }
 
-static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+				  struct link_qual *qual)
 {
-	u8 reg;
+	rt2400pci_set_vgc(rt2x00dev, qual, 0x08);
+}
 
+static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+				 struct link_qual *qual, const u32 count)
+{
 	/*
 	 * The link tuner should not run longer then 60 seconds,
 	 * and should run once every 2 seconds.
 	 */
-	if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+	if (count > 60 || !(count & 1))
 		return;
 
 	/*
 	 * Base r13 link tuning on the false cca count.
 	 */
-	rt2400pci_bbp_read(rt2x00dev, 13, &reg);
-
-	if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
-		rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
-		rt2x00dev->link.vgc_level = reg;
-	} else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
-		rt2400pci_bbp_write(rt2x00dev, 13, --reg);
-		rt2x00dev->link.vgc_level = reg;
-	}
+	if ((qual->false_cca > 512) && (qual->vgc_level < 0x20))
+		rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+	else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08))
+		rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
 }
 
 /*
@@ -904,21 +931,10 @@ static int rt2400pci_enable_radio(struct
 
 static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
-	u32 reg;
-
-	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
 	/*
-	 * Disable synchronisation.
-	 */
-	rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
-	/*
-	 * Cancel RX and TX.
+	 * Disable power
 	 */
-	rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-	rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
-	rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
 }
 
 static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1115,6 +1131,20 @@ static void rt2400pci_kick_tx_queue(stru
 	rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 }
 
+static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+				    const enum data_queue_qid qid)
+{
+	u32 reg;
+
+	if (qid == QID_BEACON) {
+		rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+	} else {
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+	}
+}
+
 /*
  * RX control handlers
  */
@@ -1365,7 +1395,9 @@ static int rt2400pci_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
 
 	rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
-	if (value == LED_MODE_TXRX_ACTIVITY)
+	if (value == LED_MODE_TXRX_ACTIVITY ||
+	    value == LED_MODE_DEFAULT ||
+	    value == LED_MODE_ASUS)
 		rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
 				   LED_TYPE_ACTIVITY);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1419,7 +1451,9 @@ static int rt2400pci_probe_hw_mode(struc
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-			       IEEE80211_HW_SIGNAL_DBM;
+			       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);
@@ -1572,6 +1606,7 @@ static const struct rt2x00lib_ops rt2400
 	.write_tx_data		= rt2x00pci_write_tx_data,
 	.write_beacon		= rt2400pci_write_beacon,
 	.kick_tx_queue		= rt2400pci_kick_tx_queue,
+	.kill_tx_queue		= rt2400pci_kill_tx_queue,
 	.fill_rxdone		= rt2400pci_fill_rxdone,
 	.config_filter		= rt2400pci_config_filter,
 	.config_intf		= rt2400pci_config_intf,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2400pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -48,8 +48,8 @@
 #define EEPROM_SIZE			0x0100
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x0020
-#define RF_BASE				0x0000
-#define RF_SIZE				0x0010
+#define RF_BASE				0x0004
+#define RF_SIZE				0x000c
 
 /*
  * Number of TX queues.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2500pci_rf_write(struct rt
 {
 	u32 reg;
 
-	if (!word)
-		return;
-
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -573,6 +570,32 @@ static void rt2500pci_config_duration(st
 	rt2x00pci_register_write(rt2x00dev, CSR12, reg);
 }
 
+static void rt2500pci_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) {
+		rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+		rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+				   (libconf->conf->beacon_int - 20) * 16);
+		rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+				   libconf->conf->listen_interval - 1);
+
+		/* We must first disable autowake before it can be enabled */
+		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+		rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+		rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+	}
+
+	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
 static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
 			     struct rt2x00lib_conf *libconf,
 			     const unsigned int flags)
@@ -588,6 +611,8 @@ static void rt2500pci_config(struct rt2x
 		rt2500pci_config_retry_limit(rt2x00dev, libconf);
 	if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
 		rt2500pci_config_duration(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt2500pci_config_ps(rt2x00dev, libconf);
 }
 
 /*
@@ -611,29 +636,33 @@ static void rt2500pci_link_stats(struct
 	qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
 }
 
-static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+				     struct link_qual *qual, u8 vgc_level)
 {
-	rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
-	rt2x00dev->link.vgc_level = 0x48;
+	if (qual->vgc_level_reg != vgc_level) {
+		rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+		qual->vgc_level_reg = vgc_level;
+	}
 }
 
-static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+				  struct link_qual *qual)
 {
-	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-	u8 r17;
+	rt2500pci_set_vgc(rt2x00dev, qual, 0x48);
+}
 
+static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+				 struct link_qual *qual, const u32 count)
+{
 	/*
 	 * To prevent collisions with MAC ASIC on chipsets
 	 * up to version C the link tuning should halt after 20
 	 * seconds while being associated.
 	 */
 	if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
-	    rt2x00dev->intf_associated &&
-	    rt2x00dev->link.count > 20)
+	    rt2x00dev->intf_associated && count > 20)
 		return;
 
-	rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
 	/*
 	 * Chipset versions C and lower should directly continue
 	 * to the dynamic CCA tuning. Chipset version D and higher
@@ -649,29 +678,25 @@ static void rt2500pci_link_tuner(struct
 	 * 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 < -80 && rt2x00dev->link.count > 20) {
-		if (r17 >= 0x41) {
-			r17 = rt2x00dev->link.vgc_level;
-			rt2500pci_bbp_write(rt2x00dev, 17, r17);
-		}
+	if (qual->rssi < -80 && count > 20) {
+		if (qual->vgc_level_reg >= 0x41)
+			rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
 		return;
 	}
 
 	/*
 	 * Special big-R17 for short distance
 	 */
-	if (rssi >= -58) {
-		if (r17 != 0x50)
-			rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+	if (qual->rssi >= -58) {
+		rt2500pci_set_vgc(rt2x00dev, qual, 0x50);
 		return;
 	}
 
 	/*
 	 * Special mid-R17 for middle distance
 	 */
-	if (rssi >= -74) {
-		if (r17 != 0x41)
-			rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+	if (qual->rssi >= -74) {
+		rt2500pci_set_vgc(rt2x00dev, qual, 0x41);
 		return;
 	}
 
@@ -679,8 +704,8 @@ static void rt2500pci_link_tuner(struct
 	 * Leave short or middle distance condition, restore r17
 	 * to the dynamic tuning range.
 	 */
-	if (r17 >= 0x41) {
-		rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+	if (qual->vgc_level_reg >= 0x41) {
+		rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
 		return;
 	}
 
@@ -690,12 +715,12 @@ 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 < 0x40) {
-		rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
-		rt2x00dev->link.vgc_level = r17;
-	} else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
-		rt2500pci_bbp_write(rt2x00dev, 17, --r17);
-		rt2x00dev->link.vgc_level = r17;
+	if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) {
+		rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg);
+		qual->vgc_level = qual->vgc_level_reg;
+	} else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) {
+		rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
+		qual->vgc_level = qual->vgc_level_reg;
 	}
 }
 
@@ -1065,21 +1090,10 @@ static int rt2500pci_enable_radio(struct
 
 static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
-	u32 reg;
-
-	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
 	/*
-	 * Disable synchronisation.
-	 */
-	rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
-	/*
-	 * Cancel RX and TX.
+	 * Disable power
 	 */
-	rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-	rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
-	rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+	rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
 }
 
 static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1205,7 +1219,7 @@ static void rt2500pci_write_tx_desc(stru
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+			   (txdesc->rate_mode == RATE_MODE_OFDM));
 	rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
@@ -1275,6 +1289,20 @@ static void rt2500pci_kick_tx_queue(stru
 	rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 }
 
+static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+				    const enum data_queue_qid qid)
+{
+	u32 reg;
+
+	if (qid == QID_BEACON) {
+		rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+	} else {
+		rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+		rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+		rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+	}
+}
+
 /*
  * RX control handlers
  */
@@ -1524,7 +1552,9 @@ static int rt2500pci_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
 
 	rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
-	if (value == LED_MODE_TXRX_ACTIVITY)
+	if (value == LED_MODE_TXRX_ACTIVITY ||
+	    value == LED_MODE_DEFAULT ||
+	    value == LED_MODE_ASUS)
 		rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
 				   LED_TYPE_ACTIVITY);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1721,7 +1751,9 @@ static int rt2500pci_probe_hw_mode(struc
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-			       IEEE80211_HW_SIGNAL_DBM;
+			       IEEE80211_HW_SIGNAL_DBM |
+			       IEEE80211_HW_SUPPORTS_PS |
+			       IEEE80211_HW_PS_NULLFUNC_STACK;
 
 	rt2x00dev->hw->extra_tx_headroom = 0;
 
@@ -1873,6 +1905,7 @@ static const struct rt2x00lib_ops rt2500
 	.write_tx_data		= rt2x00pci_write_tx_data,
 	.write_beacon		= rt2500pci_write_beacon,
 	.kick_tx_queue		= rt2500pci_kick_tx_queue,
+	.kill_tx_queue		= rt2500pci_kill_tx_queue,
 	.fill_rxdone		= rt2500pci_fill_rxdone,
 	.config_filter		= rt2500pci_config_filter,
 	.config_intf		= rt2500pci_config_intf,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
 #define EEPROM_SIZE			0x0200
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x0040
-#define RF_BASE				0x0000
-#define RF_SIZE				0x0014
+#define RF_BASE				0x0004
+#define RF_SIZE				0x0010
 
 /*
  * Number of TX queues.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -204,9 +204,6 @@ static void rt2500usb_rf_write(struct rt
 {
 	u16 reg;
 
-	if (!word)
-		return;
-
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -280,6 +277,18 @@ static const struct rt2x00debug rt2500us
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+	u16 reg;
+
+	rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+	return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+}
+#else
+#define rt2500usb_rfkill_poll	NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
 				     enum led_brightness brightness)
@@ -634,6 +643,32 @@ static void rt2500usb_config_duration(st
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
 }
 
+static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
+				struct rt2x00lib_conf *libconf)
+{
+	enum dev_state state =
+	    (libconf->conf->flags & IEEE80211_CONF_PS) ?
+		STATE_SLEEP : STATE_AWAKE;
+	u16 reg;
+
+	if (state == STATE_SLEEP) {
+		rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
+		rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
+				   libconf->conf->beacon_int - 20);
+		rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
+				   libconf->conf->listen_interval - 1);
+
+		/* We must first disable autowake before it can be enabled */
+		rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 0);
+		rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+
+		rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1);
+		rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+	}
+
+	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
 static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
 			     struct rt2x00lib_conf *libconf,
 			     const unsigned int flags)
@@ -647,6 +682,8 @@ static void rt2500usb_config(struct rt2x
 					 libconf->conf->power_level);
 	if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
 		rt2500usb_config_duration(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt2500usb_config_ps(rt2x00dev, libconf);
 }
 
 /*
@@ -670,7 +707,8 @@ static void rt2500usb_link_stats(struct
 	qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
 }
 
-static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+				  struct link_qual *qual)
 {
 	u16 eeprom;
 	u16 value;
@@ -691,7 +729,7 @@ static void rt2500usb_reset_tuner(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER);
 	rt2500usb_bbp_write(rt2x00dev, 17, value);
 
-	rt2x00dev->link.vgc_level = value;
+	qual->vgc_level = value;
 }
 
 /*
@@ -1176,7 +1214,7 @@ static void rt2500usb_write_tx_desc(stru
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+			   (txdesc->rate_mode == RATE_MODE_OFDM));
 	rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
 			   test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
@@ -1562,12 +1600,22 @@ static int rt2500usb_init_eeprom(struct
 	value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
 
 	rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
-	if (value == LED_MODE_TXRX_ACTIVITY)
+	if (value == LED_MODE_TXRX_ACTIVITY ||
+	    value == LED_MODE_DEFAULT ||
+	    value == LED_MODE_ASUS)
 		rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
 				   LED_TYPE_ACTIVITY);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
 	/*
+	 * Detect if this device has an hardware controlled radio.
+	 */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+	/*
 	 * Check if the BBP tuning should be disabled.
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
@@ -1752,7 +1800,9 @@ static int rt2500usb_probe_hw_mode(struc
 	rt2x00dev->hw->flags =
 	    IEEE80211_HW_RX_INCLUDES_FCS |
 	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-	    IEEE80211_HW_SIGNAL_DBM;
+	    IEEE80211_HW_SIGNAL_DBM |
+	    IEEE80211_HW_SUPPORTS_PS |
+	    IEEE80211_HW_PS_NULLFUNC_STACK;
 
 	rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
 
@@ -1839,7 +1889,7 @@ static int rt2500usb_probe_hw(struct rt2
 	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt) {
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-		__set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags);
+		__set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
 	}
 	__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
 
@@ -1873,6 +1923,7 @@ static const struct rt2x00lib_ops rt2500
 	.uninitialize		= rt2x00usb_uninitialize,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.set_device_state	= rt2500usb_set_device_state,
+	.rfkill_poll		= rt2500usb_rfkill_poll,
 	.link_stats		= rt2500usb_link_stats,
 	.reset_tuner		= rt2500usb_reset_tuner,
 	.link_tuner		= rt2500usb_link_tuner,
@@ -1881,6 +1932,7 @@ static const struct rt2x00lib_ops rt2500
 	.write_beacon		= rt2500usb_write_beacon,
 	.get_tx_data_len	= rt2500usb_get_tx_data_len,
 	.kick_tx_queue		= rt2500usb_kick_tx_queue,
+	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt2500usb_fill_rxdone,
 	.config_shared_key	= rt2500usb_config_key,
 	.config_pairwise_key	= rt2500usb_config_key,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2500usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
 #define EEPROM_SIZE			0x006a
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x0060
-#define RF_BASE				0x0000
-#define RF_SIZE				0x0014
+#define RF_BASE				0x0004
+#define RF_SIZE				0x0010
 
 /*
  * Number of TX queues.
@@ -189,6 +189,14 @@
  * MAC_CSR19: GPIO control register.
  */
 #define MAC_CSR19			0x0426
+#define MAC_CSR19_BIT0			FIELD32(0x0001)
+#define MAC_CSR19_BIT1			FIELD32(0x0002)
+#define MAC_CSR19_BIT2			FIELD32(0x0004)
+#define MAC_CSR19_BIT3			FIELD32(0x0008)
+#define MAC_CSR19_BIT4			FIELD32(0x0010)
+#define MAC_CSR19_BIT5			FIELD32(0x0020)
+#define MAC_CSR19_BIT6			FIELD32(0x0040)
+#define MAC_CSR19_BIT7			FIELD32(0x0080)
 
 /*
  * MAC_CSR20: LED control register.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00config.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
 void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
 			   struct rt2x00_intf *intf,
 			   enum nl80211_iftype type,
-			   u8 *mac, u8 *bssid)
+			   const u8 *mac, const u8 *bssid)
 {
 	struct rt2x00intf_conf conf;
 	unsigned int flags = 0;
@@ -42,6 +42,8 @@ void rt2x00lib_config_intf(struct rt2x00
 	switch (type) {
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
+	case NL80211_IFTYPE_WDS:
 		conf.sync = TSF_SYNC_BEACON;
 		break;
 	case NL80211_IFTYPE_STATION:
@@ -152,8 +154,7 @@ void rt2x00lib_config_antenna(struct rt2
 	 */
 	rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
 
-	rt2x00lib_reset_link_tuner(rt2x00dev);
-	rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
+	rt2x00link_reset_tuner(rt2x00dev, true);
 
 	memcpy(active, ant, sizeof(*ant));
 
@@ -191,7 +192,7 @@ void rt2x00lib_config(struct rt2x00_dev
 	 * which means we need to reset the link tuner.
 	 */
 	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
-		rt2x00lib_reset_link_tuner(rt2x00dev);
+		rt2x00link_reset_tuner(rt2x00dev, false);
 
 	rt2x00dev->curr_band = conf->channel->band;
 	rt2x00dev->tx_power = conf->power_level;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00crypto.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(s
 void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
 				       struct txentry_desc *txdesc)
 {
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
 
+	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+	    !hw_key || entry->skb->do_not_encrypt)
+		return;
+
 	__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
 
 	txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(s
 		__set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
 }
 
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+				      struct sk_buff *skb)
 {
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_key_conf *key = tx_info->control.hw_key;
 	unsigned int overhead = 0;
 
+	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+	    !key || skb->do_not_encrypt)
+		return overhead;
+
 	/*
 	 * Extend frame length to include IV/EIV/ICV/MMIC,
 	 * note that these lengths should only be added when
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -130,13 +130,15 @@ struct rt2x00debug_intf {
 };
 
 void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
-			       enum cipher cipher, enum rx_crypto status)
+			       struct rxdone_entry_desc *rxdesc)
 {
 	struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
+	enum cipher cipher = rxdesc->cipher;
+	enum rx_crypto status = rxdesc->cipher_status;
 
 	if (cipher == CIPHER_TKIP_NO_MIC)
 		cipher = CIPHER_TKIP;
-	if (cipher == CIPHER_NONE || cipher > CIPHER_MAX)
+	if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX)
 		return;
 
 	/* Remove CIPHER_NONE index */
@@ -433,11 +435,12 @@ static ssize_t rt2x00debug_read_##__name
 	if (index >= debug->__name.word_count)			\
 		return -EINVAL;					\
 								\
+	index += (debug->__name.word_base /			\
+		  debug->__name.word_size);			\
+								\
 	if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)		\
 		index *= debug->__name.word_size;		\
 								\
-	index += debug->__name.word_base;			\
-								\
 	debug->__name.read(intf->rt2x00dev, index, &value);	\
 								\
 	size = sprintf(line, __format, value);			\
@@ -474,11 +477,12 @@ static ssize_t rt2x00debug_write_##__nam
 	size = strlen(line);					\
 	value = simple_strtoul(line, NULL, 0);			\
 								\
+	index += (debug->__name.word_base /			\
+		  debug->__name.word_size);			\
+								\
 	if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)		\
 		index *= debug->__name.word_size;		\
 								\
-	index += debug->__name.word_base;			\
-								\
 	debug->__name.write(intf->rt2x00dev, index, value);	\
 								\
 	*offset += size;					\
@@ -543,9 +547,9 @@ static struct dentry *rt2x00debug_create
 		return NULL;
 
 	blob->data = data;
-	data += sprintf(data, "driver: %s\n", intf->rt2x00dev->ops->name);
-	data += sprintf(data, "version: %s\n", DRV_VERSION);
-	data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
+	data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
+	data += sprintf(data, "version:\t%s\n", DRV_VERSION);
+	data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
 	blob->size = strlen(blob->data);
 
 	return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -566,14 +570,27 @@ static struct dentry *rt2x00debug_create
 		return NULL;
 
 	blob->data = data;
-	data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt);
-	data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf);
-	data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev);
+	data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
+	data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
+	data += sprintf(data, "revision:\t%08x\n", intf->rt2x00dev->chip.rev);
 	data += sprintf(data, "\n");
-	data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
-	data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
-	data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
-	data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
+	data += sprintf(data, "register\tbase\twords\twordsize\n");
+	data += sprintf(data, "csr\t%d\t%d\t%d\n",
+			debug->csr.word_base,
+			debug->csr.word_count,
+			debug->csr.word_size);
+	data += sprintf(data, "eeprom\t%d\t%d\t%d\n",
+			debug->eeprom.word_base,
+			debug->eeprom.word_count,
+			debug->eeprom.word_size);
+	data += sprintf(data, "bbp\t%d\t%d\t%d\n",
+			debug->bbp.word_base,
+			debug->bbp.word_count,
+			debug->bbp.word_size);
+	data += sprintf(data, "rf\t%d\t%d\t%d\n",
+			debug->rf.word_base,
+			debug->rf.word_count,
+			debug->rf.word_size);
 	blob->size = strlen(blob->data);
 
 	return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00debug.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00dev.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -30,60 +30,6 @@
 #include "rt2x00lib.h"
 
 /*
- * Link tuning handlers
- */
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
-	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		return;
-
-	/*
-	 * Reset link information.
-	 * Both the currently active vgc level as well as
-	 * the link tuner counter should be reset. Resetting
-	 * the counter is important for devices where the
-	 * device should only perform link tuning during the
-	 * first minute after being enabled.
-	 */
-	rt2x00dev->link.count = 0;
-	rt2x00dev->link.vgc_level = 0;
-
-	/*
-	 * Reset the link tuner.
-	 */
-	rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
-	/*
-	 * Clear all (possibly) pre-existing quality statistics.
-	 */
-	memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
-
-	/*
-	 * The RX and TX percentage should start at 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.
-	 */
-	rt2x00dev->link.qual.rx_percentage = 50;
-	rt2x00dev->link.qual.tx_percentage = 50;
-
-	rt2x00lib_reset_link_tuner(rt2x00dev);
-
-	queue_delayed_work(rt2x00dev->hw->workqueue,
-			   &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
-}
-
-static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
-	cancel_delayed_work_sync(&rt2x00dev->link.work);
-}
-
-/*
  * Radio control handlers.
  */
 int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
@@ -137,9 +83,10 @@ void rt2x00lib_disable_radio(struct rt2x
 		return;
 
 	/*
-	 * Stop the TX queues.
+	 * Stop the TX queues in mac80211.
 	 */
 	ieee80211_stop_queues(rt2x00dev->hw);
+	rt2x00queue_stop_queues(rt2x00dev);
 
 	/*
 	 * Disable RX.
@@ -161,238 +108,15 @@ void rt2x00lib_toggle_rx(struct rt2x00_d
 	 * When we are disabling the RX, we should also stop the link tuner.
 	 */
 	if (state == STATE_RADIO_RX_OFF)
-		rt2x00lib_stop_link_tuner(rt2x00dev);
+		rt2x00link_stop_tuner(rt2x00dev);
 
 	rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
 
 	/*
 	 * When we are enabling the RX, we should also start the link tuner.
 	 */
-	if (state == STATE_RADIO_RX_ON &&
-	    (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count))
-		rt2x00lib_start_link_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
-{
-	struct antenna_setup ant;
-	int sample_a =
-	    rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
-	int sample_b =
-	    rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
-
-	memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
-	/*
-	 * We are done sampling. Now we should evaluate the results.
-	 */
-	rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
-
-	/*
-	 * During the last period we have sampled the RSSI
-	 * from both antenna's. It now is time to determine
-	 * which antenna demonstrated the best performance.
-	 * When we are already on the antenna with the best
-	 * performance, then there really is nothing for us
-	 * left to do.
-	 */
-	if (sample_a == sample_b)
-		return;
-
-	if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
-		ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
-	if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
-		ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
-	rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
-{
-	struct antenna_setup ant;
-	int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
-	int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
-
-	memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
-	/*
-	 * Legacy driver indicates that we should swap antenna's
-	 * when the difference in RSSI is greater that 5. This
-	 * also should be done when the RSSI was actually better
-	 * then the previous sample.
-	 * When the difference exceeds the threshold we should
-	 * sample the rssi from the other antenna to make a valid
-	 * comparison between the 2 antennas.
-	 */
-	if (abs(rssi_curr - rssi_old) < 5)
-		return;
-
-	rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
-
-	if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
-		ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
-	if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
-		ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
-	rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
-{
-	/*
-	 * Determine if software diversity is enabled for
-	 * either the TX or RX antenna (or both).
-	 * Always perform this check since within the link
-	 * tuner interval the configuration might have changed.
-	 */
-	rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
-	rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
-
-	if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
-		rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
-	if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
-		rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
-
-	if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
-	    !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
-		rt2x00dev->link.ant.flags = 0;
-		return;
-	}
-
-	/*
-	 * If we have only sampled the data over the last period
-	 * we should now harvest the data. Otherwise just evaluate
-	 * the data. The latter should only be performed once
-	 * every 2 seconds.
-	 */
-	if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE)
-		rt2x00lib_evaluate_antenna_sample(rt2x00dev);
-	else if (rt2x00dev->link.count & 1)
-		rt2x00lib_evaluate_antenna_eval(rt2x00dev);
-}
-
-static void rt2x00lib_update_link_stats(struct link *link, int rssi)
-{
-	int avg_rssi = rssi;
-
-	/*
-	 * Update global RSSI
-	 */
-	if (link->qual.avg_rssi)
-		avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8);
-	link->qual.avg_rssi = avg_rssi;
-
-	/*
-	 * Update antenna RSSI
-	 */
-	if (link->ant.rssi_ant)
-		rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8);
-	link->ant.rssi_ant = rssi;
-}
-
-static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
-{
-	if (qual->rx_failed || qual->rx_success)
-		qual->rx_percentage =
-		    (qual->rx_success * 100) /
-		    (qual->rx_failed + qual->rx_success);
-	else
-		qual->rx_percentage = 50;
-
-	if (qual->tx_failed || qual->tx_success)
-		qual->tx_percentage =
-		    (qual->tx_success * 100) /
-		    (qual->tx_failed + qual->tx_success);
-	else
-		qual->tx_percentage = 50;
-
-	qual->rx_success = 0;
-	qual->rx_failed = 0;
-	qual->tx_success = 0;
-	qual->tx_failed = 0;
-}
-
-static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
-					   int rssi)
-{
-	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.
-	 */
-	if (rt2x00dev->rssi_offset)
-		rssi_percentage = (rssi * 100) / 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 * rt2x00dev->link.qual.tx_percentage) +
-		  (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
-
-	return (signal > 100) ? 100 : signal;
-}
-
-static void rt2x00lib_link_tuner(struct work_struct *work)
-{
-	struct rt2x00_dev *rt2x00dev =
-	    container_of(work, struct rt2x00_dev, link.work.work);
-
-	/*
-	 * When the radio is shutting down we should
-	 * immediately cease all link tuning.
-	 */
-	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		return;
-
-	/*
-	 * Update statistics.
-	 */
-	rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
-	rt2x00dev->low_level_stats.dot11FCSErrorCount +=
-	    rt2x00dev->link.qual.rx_failed;
-
-	/*
-	 * Only perform the link tuning when Link tuning
-	 * has been enabled (This could have been disabled from the EEPROM).
-	 */
-	if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->link_tuner(rt2x00dev);
-
-	/*
-	 * Precalculate a portion of the link signal which is
-	 * in based on the tx/rx success/failure counters.
-	 */
-	rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
-
-	/*
-	 * Send a signal to the led to update the led signal strength.
-	 */
-	rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi);
-
-	/*
-	 * Evaluate antenna setup, make this the last step since this could
-	 * possibly reset some statistics.
-	 */
-	rt2x00lib_evaluate_antenna(rt2x00dev);
-
-	/*
-	 * Increase tuner counter, and reschedule the next link tuner run.
-	 */
-	rt2x00dev->link.count++;
-	queue_delayed_work(rt2x00dev->hw->workqueue,
-			   &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
+	if (state == STATE_RADIO_RX_ON)
+		rt2x00link_start_tuner(rt2x00dev);
 }
 
 static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -434,7 +158,7 @@ static void rt2x00lib_intf_scheduled_ite
 		return;
 
 	if (delayed_flags & DELAYED_UPDATE_BEACON)
-		rt2x00queue_update_beacon(rt2x00dev, vif);
+		rt2x00queue_update_beacon(rt2x00dev, vif, true);
 
 	if (delayed_flags & DELAYED_CONFIG_ERP)
 		rt2x00lib_config_erp(rt2x00dev, intf, &conf);
@@ -467,7 +191,9 @@ static void rt2x00lib_beacondone_iter(vo
 	struct rt2x00_intf *intf = vif_to_intf(vif);
 
 	if (vif->type != NL80211_IFTYPE_AP &&
-	    vif->type != NL80211_IFTYPE_ADHOC)
+	    vif->type != NL80211_IFTYPE_ADHOC &&
+	    vif->type != NL80211_IFTYPE_MESH_POINT &&
+	    vif->type != NL80211_IFTYPE_WDS)
 		return;
 
 	/*
@@ -490,7 +216,7 @@ void rt2x00lib_beacondone(struct rt2x00_
 						   rt2x00lib_beacondone_iter,
 						   rt2x00dev);
 
-	schedule_work(&rt2x00dev->intf_work);
+	queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
 
@@ -597,7 +323,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev
 	struct sk_buff *skb;
 	struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
 	struct ieee80211_supported_band *sband;
-	struct ieee80211_hdr *hdr;
 	const struct rt2x00_rate *rate;
 	unsigned int header_length;
 	unsigned int align;
@@ -668,30 +393,22 @@ void rt2x00lib_rxdone(struct rt2x00_dev
 
 	if (idx < 0) {
 		WARNING(rt2x00dev, "Frame received with unrecognized signal,"
-			"signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
-			!!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
+			"signal=0x%.2x, type=%d.\n", rxdesc.signal,
+			(rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
 		idx = 0;
 	}
 
 	/*
-	 * Only update link status if this is a beacon frame carrying our bssid.
+	 * Update extra components
 	 */
-	hdr = (struct ieee80211_hdr *)entry->skb->data;
-	if (ieee80211_is_beacon(hdr->frame_control) &&
-	    (rxdesc.dev_flags & RXDONE_MY_BSS))
-		rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
-
-	rt2x00debug_update_crypto(rt2x00dev,
-				  rxdesc.cipher,
-				  rxdesc.cipher_status);
-
-	rt2x00dev->link.qual.rx_success++;
+	rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
+	rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
 
 	rx_status->mactime = rxdesc.timestamp;
 	rx_status->rate_idx = idx;
-	rx_status->qual =
-	    rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
+	rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
 	rx_status->signal = rxdesc.rssi;
+	rx_status->noise = rxdesc.noise;
 	rx_status->flag = rxdesc.flags;
 	rx_status->antenna = rt2x00dev->link.ant.active.rx;
 
@@ -929,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2
 	 * Register HW.
 	 */
 	status = ieee80211_register_hw(rt2x00dev->hw);
-	if (status) {
-		rt2x00lib_remove_hw(rt2x00dev);
+	if (status)
 		return status;
-	}
 
 	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);
 
@@ -1067,7 +782,9 @@ int rt2x00lib_probe_dev(struct rt2x00_de
 	if (rt2x00dev->ops->bcn->entry_num > 0)
 		rt2x00dev->hw->wiphy->interface_modes |=
 		    BIT(NL80211_IFTYPE_ADHOC) |
-		    BIT(NL80211_IFTYPE_AP);
+		    BIT(NL80211_IFTYPE_AP) |
+		    BIT(NL80211_IFTYPE_MESH_POINT) |
+		    BIT(NL80211_IFTYPE_WDS);
 
 	/*
 	 * Let the driver probe the device to detect the capabilities.
@@ -1083,7 +800,6 @@ int rt2x00lib_probe_dev(struct rt2x00_de
 	 */
 	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
 	INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
-	INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
 
 	/*
 	 * Allocate queue array.
@@ -1104,6 +820,7 @@ int rt2x00lib_probe_dev(struct rt2x00_de
 	/*
 	 * Register extra components.
 	 */
+	rt2x00link_register(rt2x00dev);
 	rt2x00leds_register(rt2x00dev);
 	rt2x00rfkill_allocate(rt2x00dev);
 	rt2x00debug_register(rt2x00dev);
@@ -1163,23 +880,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
 #ifdef CONFIG_PM
 int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
 {
-	int retval;
-
 	NOTICE(rt2x00dev, "Going to sleep.\n");
 
 	/*
-	 * Only continue if mac80211 has open interfaces.
+	 * Prevent mac80211 from accessing driver while suspended.
 	 */
-	if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
-	    !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
-		goto exit;
-
-	set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
+	if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+		return 0;
 
 	/*
-	 * Disable radio.
+	 * Cleanup as much as possible.
 	 */
-	rt2x00lib_stop(rt2x00dev);
 	rt2x00lib_uninitialize(rt2x00dev);
 
 	/*
@@ -1188,7 +899,6 @@ int rt2x00lib_suspend(struct rt2x00_dev
 	rt2x00leds_suspend(rt2x00dev);
 	rt2x00debug_deregister(rt2x00dev);
 
-exit:
 	/*
 	 * Set device mode to sleep for power management,
 	 * on some hardware this call seems to consistently fail.
@@ -1200,8 +910,7 @@ exit:
 	 * the radio and the other components already disabled the
 	 * device is as good as disabled.
 	 */
-	retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
-	if (retval)
+	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP))
 		WARNING(rt2x00dev, "Device failed to enter sleep state, "
 			"continue suspending.\n");
 
@@ -1209,32 +918,8 @@ exit:
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
 
-static void rt2x00lib_resume_intf(void *data, u8 *mac,
-				  struct ieee80211_vif *vif)
-{
-	struct rt2x00_dev *rt2x00dev = data;
-	struct rt2x00_intf *intf = vif_to_intf(vif);
-
-	spin_lock(&intf->lock);
-
-	rt2x00lib_config_intf(rt2x00dev, intf,
-			      vif->type, intf->mac, intf->bssid);
-
-
-	/*
-	 * Master or Ad-hoc mode require a new beacon update.
-	 */
-	if (vif->type == NL80211_IFTYPE_AP ||
-	    vif->type == NL80211_IFTYPE_ADHOC)
-		intf->delayed_flags |= DELAYED_UPDATE_BEACON;
-
-	spin_unlock(&intf->lock);
-}
-
 int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
 {
-	int retval;
-
 	NOTICE(rt2x00dev, "Waking up.\n");
 
 	/*
@@ -1244,60 +929,11 @@ int rt2x00lib_resume(struct rt2x00_dev *
 	rt2x00leds_resume(rt2x00dev);
 
 	/*
-	 * Only continue if mac80211 had open interfaces.
-	 */
-	if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
-		return 0;
-
-	/*
-	 * Reinitialize device and all active interfaces.
-	 */
-	retval = rt2x00lib_start(rt2x00dev);
-	if (retval)
-		goto exit;
-
-	/*
-	 * Reconfigure device.
-	 */
-	retval = rt2x00mac_config(rt2x00dev->hw, ~0);
-	if (retval)
-		goto exit;
-
-	/*
-	 * Iterator over each active interface to
-	 * reconfigure the hardware.
-	 */
-	ieee80211_iterate_active_interfaces(rt2x00dev->hw,
-					    rt2x00lib_resume_intf, rt2x00dev);
-
-	/*
 	 * We are ready again to receive requests from mac80211.
 	 */
 	set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
 
-	/*
-	 * It is possible that during that mac80211 has attempted
-	 * to send frames while we were suspending or resuming.
-	 * In that case we have disabled the TX queue and should
-	 * now enable it again
-	 */
-	ieee80211_wake_queues(rt2x00dev->hw);
-
-	/*
-	 * During interface iteration we might have changed the
-	 * delayed_flags, time to handles the event by calling
-	 * the work handler directly.
-	 */
-	rt2x00lib_intf_scheduled(&rt2x00dev->intf_work);
-
 	return 0;
-
-exit:
-	rt2x00lib_stop(rt2x00dev);
-	rt2x00lib_uninitialize(rt2x00dev);
-	rt2x00debug_deregister(rt2x00dev);
-
-	return retval;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_resume);
 #endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00dump.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c	2013-05-03 18:05:00.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00firmware.c	2013-05-03 16:49:00.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,6 @@ static int rt2x00lib_reject_firmware(str
 	const struct firmware *fw;
 	char *fw_name;
 	int retval;
-	u16 crc;
 
 	/*
 	 * Read correct firmware from harddisk.
@@ -61,16 +60,26 @@ static int rt2x00lib_reject_firmware(str
 		return -ENOENT;
 	}
 
-	crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size);
-	if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
-		ERROR(rt2x00dev, "Firmware checksum error.\n");
-		retval = -ENOENT;
-		goto exit;
-	}
-
 	INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
 	     fw->data[fw->size - 4], fw->data[fw->size - 3]);
 
+	retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
+	switch (retval) {
+	case FW_OK:
+		break;
+	case FW_BAD_CRC:
+		ERROR(rt2x00dev, "Firmware checksum error.\n");
+		goto exit;
+	case FW_BAD_LENGTH:
+		ERROR(rt2x00dev,
+		      "Invalid firmware file length (len=%zu)\n", fw->size);
+		goto exit;
+	case FW_BAD_VERSION:
+		ERROR(rt2x00dev,
+		      "Current firmware does not support detected chipset.\n");
+		goto exit;
+	};
+
 	rt2x00dev->fw = fw;
 
 	return 0;
@@ -78,7 +87,7 @@ static int rt2x00lib_reject_firmware(str
 exit:
 	release_firmware(fw);
 
-	return retval;
+	return -ENOENT;
 }
 
 int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -33,6 +33,7 @@
 #include <linux/leds.h>
 #include <linux/mutex.h>
 #include <linux/etherdevice.h>
+#include <linux/input-polldev.h>
 
 #include <net/mac80211.h>
 
@@ -44,7 +45,7 @@
 /*
  * Module information.
  */
-#define DRV_VERSION	"2.2.3"
+#define DRV_VERSION	"2.3.0"
 #define DRV_PROJECT	"http://rt2x00.serialmonkey.com"
 
 /*
@@ -177,52 +178,41 @@ struct antenna_setup {
  */
 struct link_qual {
 	/*
-	 * Statistics required for Link tuning.
-	 * For the average RSSI value we use the "Walking average" approach.
-	 * When adding RSSI to the average value the following calculation
-	 * is needed:
-	 *
-	 *        avg_rssi = ((avg_rssi * 7) + rssi) / 8;
-	 *
-	 * The advantage of this approach is that we only need 1 variable
-	 * to store the average in (No need for a count and a total).
-	 * But more importantly, normal average values will over time
-	 * move less and less towards newly added values this results
-	 * that with link tuning, the device can have a very good RSSI
-	 * for a few minutes but when the device is moved away from the AP
-	 * the average will not decrease fast enough to compensate.
-	 * The walking average compensates this and will move towards
-	 * the new values correctly allowing a effective link tuning.
+	 * Statistics required for Link tuning by driver
+	 * The rssi value is provided by rt2x00lib during the
+	 * link_tuner() callback function.
+	 * The false_cca field is filled during the link_stats()
+	 * callback function and could be used during the
+	 * link_tuner() callback function.
 	 */
-	int avg_rssi;
+	int rssi;
 	int false_cca;
 
 	/*
-	 * Statistics required for Signal quality calculation.
-	 * For calculating the Signal quality we have to determine
-	 * the total number of success and failed RX and TX frames.
-	 * After that we also use the average RSSI value to help
-	 * determining the signal quality.
-	 * For the calculation we will use 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
+	 * VGC levels
+	 * Hardware driver will tune the VGC level during each call
+	 * to the link_tuner() callback function. This vgc_level is
+	 * is determined based on the link quality statistics like
+	 * average RSSI and the false CCA count.
 	 *
-	 * This value should then be checked to not be greated then 100.
+	 * In some cases the drivers need to differentiate between
+	 * the currently "desired" VGC level and the level configured
+	 * in the hardware. The latter is important to reduce the
+	 * number of BBP register reads to reduce register access
+	 * overhead. For this reason we store both values here.
+	 */
+	u8 vgc_level;
+	u8 vgc_level_reg;
+
+	/*
+	 * Statistics required for Signal quality calculation.
+	 * These fields might be changed during the link_stats()
+	 * callback function.
 	 */
-	int rx_percentage;
 	int rx_success;
 	int rx_failed;
-	int tx_percentage;
 	int tx_success;
 	int tx_failed;
-#define WEIGHT_RSSI	20
-#define WEIGHT_RX	40
-#define WEIGHT_TX	40
 };
 
 /*
@@ -286,9 +276,16 @@ struct link {
 	struct link_ant ant;
 
 	/*
-	 * Active VGC level
+	 * Currently active average RSSI value
 	 */
-	int vgc_level;
+	int avg_rssi;
+
+	/*
+	 * Currently precalculated percentages of successful
+	 * TX and RX frames.
+	 */
+	int rx_percentage;
+	int tx_percentage;
 
 	/*
 	 * Work structure for scheduling periodic link tuning.
@@ -297,55 +294,6 @@ struct link {
 };
 
 /*
- * Small helper macro to work with moving/walking averages.
- */
-#define MOVING_AVERAGE(__avg, __val, __samples) \
-	( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
-
-/*
- * When we lack RSSI information return something less then -80 to
- * tell the driver to tune the device to maximum sensitivity.
- */
-#define DEFAULT_RSSI	( -128 )
-
-/*
- * Link quality access functions.
- */
-static inline int rt2x00_get_link_rssi(struct link *link)
-{
-	if (link->qual.avg_rssi && link->qual.rx_success)
-		return link->qual.avg_rssi;
-	return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_get_link_ant_rssi(struct link *link)
-{
-	if (link->ant.rssi_ant && link->qual.rx_success)
-		return link->ant.rssi_ant;
-	return DEFAULT_RSSI;
-}
-
-static inline void rt2x00_reset_link_ant_rssi(struct link *link)
-{
-	link->ant.rssi_ant = 0;
-}
-
-static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
-						   enum antenna ant)
-{
-	if (link->ant.rssi_history[ant - ANTENNA_A])
-		return link->ant.rssi_history[ant - ANTENNA_A];
-	return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
-{
-	int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
-	link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
-	return old_rssi;
-}
-
-/*
  * Interface structure
  * Per interface configuration details, this structure
  * is allocated as the private data for ieee80211_vif.
@@ -448,7 +396,7 @@ struct rt2x00lib_erp {
 	int ack_timeout;
 	int ack_consume_time;
 
-	u64 basic_rates;
+	u32 basic_rates;
 
 	int slot_time;
 
@@ -520,9 +468,10 @@ struct rt2x00lib_ops {
 	 */
 	int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
 	char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
-	u16 (*get_firmware_crc) (const void *data, const size_t len);
-	int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data,
-			      const size_t len);
+	int (*check_firmware) (struct rt2x00_dev *rt2x00dev,
+			       const u8 *data, const size_t len);
+	int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
+			      const u8 *data, const size_t len);
 
 	/*
 	 * Device initialization/deinitialization handlers.
@@ -544,8 +493,10 @@ struct rt2x00lib_ops {
 	int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
 	void (*link_stats) (struct rt2x00_dev *rt2x00dev,
 			    struct link_qual *qual);
-	void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
-	void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
+	void (*reset_tuner) (struct rt2x00_dev *rt2x00dev,
+			     struct link_qual *qual);
+	void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
+			    struct link_qual *qual, const u32 count);
 
 	/*
 	 * TX control handlers
@@ -558,6 +509,8 @@ struct rt2x00lib_ops {
 	int (*get_tx_data_len) (struct queue_entry *entry);
 	void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
 			       const enum data_queue_qid queue);
+	void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
+			       const enum data_queue_qid queue);
 
 	/*
 	 * RX control handlers
@@ -625,7 +578,6 @@ enum rt2x00_flags {
 	DEVICE_STATE_REGISTERED_HW,
 	DEVICE_STATE_INITIALIZED,
 	DEVICE_STATE_STARTED,
-	DEVICE_STATE_STARTED_SUSPEND,
 	DEVICE_STATE_ENABLED_RADIO,
 	DEVICE_STATE_DISABLED_RADIO_HW,
 
@@ -637,6 +589,7 @@ enum rt2x00_flags {
 	DRIVER_REQUIRE_ATIM_QUEUE,
 	DRIVER_REQUIRE_SCHEDULED,
 	DRIVER_REQUIRE_DMA,
+	DRIVER_REQUIRE_COPY_IV,
 
 	/*
 	 * Driver features
@@ -653,7 +606,6 @@ enum rt2x00_flags {
 	CONFIG_EXTERNAL_LNA_BG,
 	CONFIG_DOUBLE_ANTENNA,
 	CONFIG_DISABLE_LINK_TUNING,
-	CONFIG_CRYPTO_COPY_IV,
 };
 
 /*
@@ -689,8 +641,8 @@ struct rt2x00_dev {
 	unsigned long rfkill_state;
 #define RFKILL_STATE_ALLOCATED		1
 #define RFKILL_STATE_REGISTERED		2
-	struct rfkill *rfkill;
-	struct delayed_work rfkill_work;
+#define RFKILL_STATE_BLOCKED		3
+	struct input_polled_dev *rfkill_poll_dev;
 #endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
@@ -918,7 +870,7 @@ static inline char rt2x00_rf(const struc
 	return (chipset->rf == chip);
 }
 
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
+static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
 {
 	return chipset->rev;
 }
@@ -982,7 +934,7 @@ void rt2x00mac_configure_filter(struct i
 				int mc_count, struct dev_addr_list *mc_list);
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
 int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-		      const u8 *local_address, const u8 *address,
+		      struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 		      struct ieee80211_key_conf *key);
 #else
 #define rt2x00mac_set_key	NULL
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -134,7 +134,7 @@ void rt2x00leds_register(struct rt2x00_d
 		 rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy));
 
 	if (rt2x00dev->led_radio.flags & LED_INITIALIZED) {
-		snprintf(name, sizeof(name), "%s:radio", dev_name);
+		snprintf(name, sizeof(name), "%s::radio", dev_name);
 
 		retval = rt2x00leds_register_led(rt2x00dev,
 						 &rt2x00dev->led_radio,
@@ -144,7 +144,7 @@ void rt2x00leds_register(struct rt2x00_d
 	}
 
 	if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) {
-		snprintf(name, sizeof(name), "%s:assoc", dev_name);
+		snprintf(name, sizeof(name), "%s::assoc", dev_name);
 
 		retval = rt2x00leds_register_led(rt2x00dev,
 						 &rt2x00dev->led_assoc,
@@ -154,7 +154,7 @@ void rt2x00leds_register(struct rt2x00_d
 	}
 
 	if (rt2x00dev->led_qual.flags & LED_INITIALIZED) {
-		snprintf(name, sizeof(name), "%s:quality", dev_name);
+		snprintf(name, sizeof(name), "%s::quality", dev_name);
 
 		retval = rt2x00leds_register_led(rt2x00dev,
 						 &rt2x00dev->led_qual,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00leds.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00lib.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -33,7 +33,7 @@
  * Both the link tuner as the rfkill will be called once per second.
  */
 #define LINK_TUNE_INTERVAL	( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL	( round_jiffies_relative(HZ) )
+#define RFKILL_POLL_INTERVAL	( 1000 )
 
 /*
  * rt2x00_rate: Per rate device information
@@ -63,7 +63,6 @@ static inline const struct rt2x00_rate *
 int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
 
 /*
  * Initialization handlers.
@@ -77,7 +76,7 @@ void rt2x00lib_stop(struct rt2x00_dev *r
 void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
 			   struct rt2x00_intf *intf,
 			   enum nl80211_iftype type,
-			   u8 *mac, u8 *bssid);
+			   const u8 *mac, const u8 *bssid);
 void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 			  struct rt2x00_intf *intf,
 			  struct ieee80211_bss_conf *conf);
@@ -124,9 +123,11 @@ int rt2x00queue_write_tx_frame(struct da
  * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  * @vif: Interface for which the beacon should be updated.
+ * @enable_beacon: Enable beaconing
  */
 int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
-			      struct ieee80211_vif *vif);
+			      struct ieee80211_vif *vif,
+			      const bool enable_beacon);
 
 /**
  * rt2x00queue_index_inc - Index incrementation function
@@ -140,6 +141,15 @@ int rt2x00queue_update_beacon(struct rt2
 void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
 
 /**
+ * rt2x00queue_stop_queues - Halt all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to stop
+ * any pending outgoing frames.
+ */
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
  * rt2x00queue_init_queues - Initialize all data queues
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  *
@@ -154,6 +164,81 @@ void rt2x00queue_uninitialize(struct rt2
 int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
 void rt2x00queue_free(struct rt2x00_dev *rt2x00dev);
 
+/**
+ * rt2x00link_update_stats - Update link statistics from RX frame
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: Received frame
+ * @rxdesc: Received frame descriptor
+ *
+ * Update link statistics based on the information from the
+ * received frame descriptor.
+ */
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+			     struct sk_buff *skb,
+			     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.
+ *
+ * This start the link tuner periodic work, this work will
+ * be executed periodically until &rt2x00link_stop_tuner has
+ * been called.
+ */
+void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_stop_tuner - Stop periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * After this function completed the link tuner will not
+ * be running until &rt2x00link_start_tuner is called.
+ */
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_reset_tuner - Reset periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @antenna: Should the antenna tuning also be reset
+ *
+ * The VGC limit configured in the hardware will be reset to 0
+ * which forces the driver to rediscover the correct value for
+ * the current association. This is needed when configuration
+ * options have changed which could drastically change the
+ * SNR level or link quality (i.e. changing the antenna setting).
+ *
+ * Resetting the link tuner will also cause the periodic work counter
+ * to be reset. Any driver which has a fixed limit on the number
+ * of rounds the link tuner is supposed to work will accept the
+ * tuner actions again if this limit was previously reached.
+ *
+ * If @antenna is set to true a the software antenna diversity
+ * tuning will also be reset.
+ */
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna);
+
+/**
+ * rt2x00link_register - Initialize link tuning functionality
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * Initialize work structure and all link tuning related
+ * paramters. This will not start the link tuning process itself.
+ */
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev);
+
 /*
  * Firmware handlers.
  */
@@ -179,7 +264,7 @@ void rt2x00debug_deregister(struct rt2x0
 void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
 			    enum rt2x00_dump_type type, struct sk_buff *skb);
 void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
-			       enum cipher cipher, enum rx_crypto status);
+			       struct rxdone_entry_desc *rxdesc);
 #else
 static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 {
@@ -196,8 +281,7 @@ static inline void rt2x00debug_dump_fram
 }
 
 static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
-					     enum cipher cipher,
-					     enum rx_crypto status)
+					     struct rxdone_entry_desc *rxdesc)
 {
 }
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
@@ -209,7 +293,8 @@ static inline void rt2x00debug_update_cr
 enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key);
 void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
 				       struct txentry_desc *txdesc);
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info);
+unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+				      struct sk_buff *skb);
 void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
 void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
 void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
@@ -227,7 +312,8 @@ static inline void rt2x00crypto_create_t
 {
 }
 
-static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+						    struct sk_buff *skb)
 {
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00link.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,471 @@
+/*
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+	<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: rt2x00lib
+	Abstract: rt2x00 generic link tuning routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+/*
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
+ */
+#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 to work with moving/walking averages.
+ * When adding a value to the average value the following calculation
+ * is needed:
+ *
+ *        avg_rssi = ((avg_rssi * 7) + rssi) / 8;
+ *
+ * The advantage of this approach is that we only need 1 variable
+ * to store the average in (No need for a count and a total).
+ * But more importantly, normal average values will over time
+ * move less and less towards newly added values this results
+ * that with link tuning, the device can have a very good RSSI
+ * for a few minutes but when the device is moved away from the AP
+ * the average will not decrease fast enough to compensate.
+ * The walking average compensates this and will move towards
+ * the new values correctly allowing a effective link tuning.
+ */
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+	( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
+
+/*
+ * 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) )
+
+/*
+ * 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;
+
+	if (ant->rssi_ant && rt2x00dev->link.qual.rx_success)
+		return ant->rssi_ant;
+	return DEFAULT_RSSI;
+}
+
+static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev,
+					       enum antenna antenna)
+{
+	struct link_ant *ant = &rt2x00dev->link.ant;
+
+	if (ant->rssi_history[antenna - ANTENNA_A])
+		return ant->rssi_history[antenna - ANTENNA_A];
+	return DEFAULT_RSSI;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_get_rssi_rx_history(__dev) \
+	rt2x00link_antenna_get_rssi_history((__dev), \
+					    (__dev)->link.ant.active.rx)
+#define rt2x00link_antenna_get_rssi_tx_history(__dev) \
+	rt2x00link_antenna_get_rssi_history((__dev), \
+					    (__dev)->link.ant.active.tx)
+
+static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
+						   enum antenna antenna,
+						   int rssi)
+{
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \
+	rt2x00link_antenna_update_rssi_history((__dev), \
+					       (__dev)->link.ant.active.rx, \
+					       (__rssi))
+#define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \
+	rt2x00link_antenna_update_rssi_history((__dev), \
+					       (__dev)->link.ant.active.tx, \
+					       (__rssi))
+
+static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
+{
+	rt2x00dev->link.ant.rssi_ant = 0;
+}
+
+static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
+{
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	struct antenna_setup new_ant;
+	int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A);
+	int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B);
+
+	memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+	/*
+	 * We are done sampling. Now we should evaluate the results.
+	 */
+	ant->flags &= ~ANTENNA_MODE_SAMPLE;
+
+	/*
+	 * During the last period we have sampled the RSSI
+	 * from both antenna's. It now is time to determine
+	 * which antenna demonstrated the best performance.
+	 * When we are already on the antenna with the best
+	 * performance, then there really is nothing for us
+	 * left to do.
+	 */
+	if (sample_a == sample_b)
+		return;
+
+	if (ant->flags & ANTENNA_RX_DIVERSITY)
+		new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+	if (ant->flags & ANTENNA_TX_DIVERSITY)
+		new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+	rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
+{
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	struct antenna_setup new_ant;
+	int rssi_curr;
+	int rssi_old;
+
+	memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+	/*
+	 * Get current RSSI value along with the historical value,
+	 * after that update the history with the current value.
+	 */
+	rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
+	rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev);
+	rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr);
+
+	/*
+	 * Legacy driver indicates that we should swap antenna's
+	 * when the difference in RSSI is greater that 5. This
+	 * also should be done when the RSSI was actually better
+	 * then the previous sample.
+	 * When the difference exceeds the threshold we should
+	 * sample the rssi from the other antenna to make a valid
+	 * comparison between the 2 antennas.
+	 */
+	if (abs(rssi_curr - rssi_old) < 5)
+		return;
+
+	ant->flags |= ANTENNA_MODE_SAMPLE;
+
+	if (ant->flags & ANTENNA_RX_DIVERSITY)
+		new_ant.rx = (new_ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+	if (ant->flags & ANTENNA_TX_DIVERSITY)
+		new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+	rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
+{
+	struct link_ant *ant = &rt2x00dev->link.ant;
+
+	/*
+	 * Determine if software diversity is enabled for
+	 * either the TX or RX antenna (or both).
+	 * Always perform this check since within the link
+	 * tuner interval the configuration might have changed.
+	 */
+	ant->flags &= ~ANTENNA_RX_DIVERSITY;
+	ant->flags &= ~ANTENNA_TX_DIVERSITY;
+
+	if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+		ant->flags |= ANTENNA_RX_DIVERSITY;
+	if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+		ant->flags |= ANTENNA_TX_DIVERSITY;
+
+	if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
+	    !(ant->flags & ANTENNA_TX_DIVERSITY)) {
+		ant->flags = 0;
+		return;
+	}
+
+	/*
+	 * If we have only sampled the data over the last period
+	 * we should now harvest the data. Otherwise just evaluate
+	 * the data. The latter should only be performed once
+	 * every 2 seconds.
+	 */
+	if (ant->flags & ANTENNA_MODE_SAMPLE)
+		rt2x00lib_antenna_diversity_sample(rt2x00dev);
+	else if (rt2x00dev->link.count & 1)
+		rt2x00lib_antenna_diversity_eval(rt2x00dev);
+}
+
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+			     struct sk_buff *skb,
+			     struct rxdone_entry_desc *rxdesc)
+{
+	struct link *link = &rt2x00dev->link;
+	struct link_qual *qual = &rt2x00dev->link.qual;
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	int avg_rssi = rxdesc->rssi;
+	int ant_rssi = rxdesc->rssi;
+
+	/*
+	 * Frame was received successfully since non-succesfull
+	 * frames would have been dropped by the hardware.
+	 */
+	qual->rx_success++;
+
+	/*
+	 * We are only interested in quality statistics from
+	 * beacons which came from the BSS which we are
+	 * associated with.
+	 */
+	if (!ieee80211_is_beacon(hdr->frame_control) ||
+	    !(rxdesc->dev_flags & RXDONE_MY_BSS))
+		return;
+
+	/*
+	 * Update global RSSI
+	 */
+	if (link->avg_rssi)
+		avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8);
+	link->avg_rssi = avg_rssi;
+
+	/*
+	 * Update antenna RSSI
+	 */
+	if (ant->rssi_ant)
+		ant_rssi = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi, 8);
+	ant->rssi_ant = ant_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;
+
+	/*
+	 * Link tuning should only be performed when
+	 * an active sta or master interface exists.
+	 * Single monitor mode interfaces should never have
+	 * work with link tuners.
+	 */
+	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);
+
+	queue_delayed_work(rt2x00dev->hw->workqueue,
+			   &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
+{
+	cancel_delayed_work_sync(&rt2x00dev->link.work);
+}
+
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
+{
+	struct link_qual *qual = &rt2x00dev->link.qual;
+
+	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+		return;
+
+	/*
+	 * Reset link information.
+	 * Both the currently active vgc level as well as
+	 * the link tuner counter should be reset. Resetting
+	 * the counter is important for devices where the
+	 * device should only perform link tuning during the
+	 * first minute after being enabled.
+	 */
+	rt2x00dev->link.count = 0;
+	memset(qual, 0, sizeof(*qual));
+
+	/*
+	 * Reset the link tuner.
+	 */
+	rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual);
+
+	if (antenna)
+		rt2x00link_antenna_reset(rt2x00dev);
+}
+
+void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+{
+	struct link_qual *qual = &rt2x00dev->link.qual;
+
+	qual->rx_success = 0;
+	qual->rx_failed = 0;
+	qual->tx_success = 0;
+	qual->tx_failed = 0;
+}
+
+static void rt2x00link_tuner(struct work_struct *work)
+{
+	struct rt2x00_dev *rt2x00dev =
+	    container_of(work, struct rt2x00_dev, link.work.work);
+	struct link *link = &rt2x00dev->link;
+	struct link_qual *qual = &rt2x00dev->link.qual;
+
+	/*
+	 * When the radio is shutting down we should
+	 * immediately cease all link tuning.
+	 */
+	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+		return;
+
+	/*
+	 * Update statistics.
+	 */
+	rt2x00dev->ops->lib->link_stats(rt2x00dev, qual);
+	rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed;
+
+	/*
+	 * Update quality RSSI for link tuning,
+	 * when we have received some frames and we managed to
+	 * collect the RSSI data we could use this. Otherwise we
+	 * must fallback to the default RSSI value.
+	 */
+	if (!link->avg_rssi || !qual->rx_success)
+		qual->rssi = DEFAULT_RSSI;
+	else
+		qual->rssi = link->avg_rssi;
+
+	/*
+	 * Only perform the link tuning when Link tuning
+	 * has been enabled (This could have been disabled from the EEPROM).
+	 */
+	if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
+		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, link->avg_rssi);
+
+	/*
+	 * Evaluate antenna setup, make this the last step since this could
+	 * possibly reset some statistics.
+	 */
+	rt2x00lib_antenna_diversity(rt2x00dev);
+
+	/*
+	 * Reset the quality counters which recounted during each period.
+	 */
+	rt2x00link_reset_qual(rt2x00dev);
+
+	/*
+	 * Increase tuner counter, and reschedule the next link tuner run.
+	 */
+	link->count++;
+	queue_delayed_work(rt2x00dev->hw->workqueue,
+			   &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
+{
+	INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct r
 	 * RTS/CTS frame should use the length of the frame plus any
 	 * encryption overhead that will be added by the hardware.
 	 */
-	if (!frag_skb->do_not_encrypt)
-		data_length += rt2x00crypto_tx_overhead(tx_info);
+	data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb);
 
 	if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
 		ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
@@ -226,6 +225,8 @@ int rt2x00mac_add_interface(struct ieee8
 		break;
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
+	case NL80211_IFTYPE_WDS:
 		/*
 		 * We don't support mixed combinations of
 		 * sta and ap interfaces.
@@ -430,8 +431,10 @@ int rt2x00mac_config_interface(struct ie
 	/*
 	 * Update the beacon.
 	 */
-	if (conf->changed & IEEE80211_IFCC_BEACON)
-		status = rt2x00queue_update_beacon(rt2x00dev, vif);
+	if (conf->changed & (IEEE80211_IFCC_BEACON |
+			     IEEE80211_IFCC_BEACON_ENABLED))
+		status = rt2x00queue_update_beacon(rt2x00dev, vif,
+						   conf->enable_beacon);
 
 	return status;
 }
@@ -482,16 +485,36 @@ void rt2x00mac_configure_filter(struct i
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
+static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
+{
+	if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
+		memcpy(&crypto->key,
+		       &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
+		       sizeof(crypto->key));
+
+	if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
+		memcpy(&crypto->tx_mic,
+		       &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
+		       sizeof(crypto->tx_mic));
+
+	if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
+		memcpy(&crypto->rx_mic,
+		       &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
+		       sizeof(crypto->rx_mic));
+}
+
 int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-		      const u8 *local_address, const u8 *address,
+		      struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 		      struct ieee80211_key_conf *key)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct ieee80211_sta *sta;
+	struct rt2x00_intf *intf = vif_to_intf(vif);
 	int (*set_key) (struct rt2x00_dev *rt2x00dev,
 			struct rt2x00lib_crypto *crypto,
 			struct ieee80211_key_conf *key);
 	struct rt2x00lib_crypto crypto;
+	static const u8 bcast_addr[ETH_ALEN] =
+		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
 
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
 		return 0;
@@ -509,45 +532,25 @@ int rt2x00mac_set_key(struct ieee80211_h
 	if (rt2x00dev->intf_sta_count)
 		crypto.bssidx = 0;
 	else
-		crypto.bssidx =
-		    local_address[5] & (rt2x00dev->ops->max_ap_intf - 1);
+		crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1);
 
 	crypto.cipher = rt2x00crypto_key_to_cipher(key);
 	if (crypto.cipher == CIPHER_NONE)
 		return -EOPNOTSUPP;
 
 	crypto.cmd = cmd;
-	crypto.address = address;
-
-	if (crypto.cipher == CIPHER_TKIP) {
-		if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
-			memcpy(&crypto.key,
-			       &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
-			       sizeof(crypto.key));
-
-		if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
-			memcpy(&crypto.tx_mic,
-			       &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
-			       sizeof(crypto.tx_mic));
-
-		if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
-			memcpy(&crypto.rx_mic,
-			       &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
-			       sizeof(crypto.rx_mic));
-	} else
-		memcpy(&crypto.key, &key->key[0], key->keylen);
 
-	/*
-	 * Discover the Association ID from mac80211.
-	 * Some drivers need this information when updating the
-	 * hardware key (either adding or removing).
-	 */
-	rcu_read_lock();
-	sta = ieee80211_find_sta(hw, address);
-	if (sta)
+	if (sta) {
+		/* some drivers need the AID */
 		crypto.aid = sta->aid;
-	rcu_read_unlock();
+		crypto.address = sta->addr;
+	} else
+		crypto.address = bcast_addr;
 
+	if (crypto.cipher == CIPHER_TKIP)
+		memcpy_tkip(&crypto, &key->key[0], key->keylen);
+	else
+		memcpy(&crypto.key, &key->key[0], key->keylen);
 	/*
 	 * Each BSS has a maximum of 4 shared keys.
 	 * Shared key index values:
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -288,7 +288,7 @@ int rt2x00pci_probe(struct pci_dev *pci_
 	if (pci_set_mwi(pci_dev))
 		ERROR_PROBE("MWI not available.\n");
 
-	if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) {
+	if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
 		ERROR_PROBE("PCI DMA not supported.\n");
 		retval = -EIO;
 		goto exit_disable_device;
@@ -369,8 +369,6 @@ int rt2x00pci_suspend(struct pci_dev *pc
 	if (retval)
 		return retval;
 
-	rt2x00pci_free_reg(rt2x00dev);
-
 	pci_save_state(pci_dev);
 	pci_disable_device(pci_dev);
 	return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
@@ -381,7 +379,6 @@ int rt2x00pci_resume(struct pci_dev *pci
 {
 	struct ieee80211_hw *hw = pci_get_drvdata(pci_dev);
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	int retval;
 
 	if (pci_set_power_state(pci_dev, PCI_D0) ||
 	    pci_enable_device(pci_dev) ||
@@ -390,20 +387,7 @@ int rt2x00pci_resume(struct pci_dev *pci
 		return -EIO;
 	}
 
-	retval = rt2x00pci_alloc_reg(rt2x00dev);
-	if (retval)
-		return retval;
-
-	retval = rt2x00lib_resume(rt2x00dev);
-	if (retval)
-		goto exit_free_reg;
-
-	return 0;
-
-exit_free_reg:
-	rt2x00pci_free_reg(rt2x00dev);
-
-	return retval;
+	return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_resume);
 #endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -148,20 +148,105 @@ void rt2x00queue_free_skb(struct rt2x00_
 	dev_kfree_skb_any(skb);
 }
 
+static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
+						 struct txentry_desc *txdesc)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+	struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
+	unsigned long irqflags;
+
+	if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ||
+	    unlikely(!tx_info->control.vif))
+		return;
+
+	/*
+	 * Hardware should insert sequence counter.
+	 * FIXME: We insert a software sequence counter first for
+	 * hardware that doesn't support hardware sequence counting.
+	 *
+	 * This is wrong because beacons are not getting sequence
+	 * numbers assigned properly.
+	 *
+	 * A secondary problem exists for drivers that cannot toggle
+	 * sequence counting per-frame, since those will override the
+	 * sequence counter given by mac80211.
+	 */
+	spin_lock_irqsave(&intf->seqlock, irqflags);
+
+	if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
+		intf->seqno += 0x10;
+	hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+	hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
+
+	spin_unlock_irqrestore(&intf->seqlock, irqflags);
+
+	__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
+}
+
+static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
+						  struct txentry_desc *txdesc,
+						  const struct rt2x00_rate *hwrate)
+{
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+	struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+	unsigned int data_length;
+	unsigned int duration;
+	unsigned int residual;
+
+	/* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */
+	data_length = entry->skb->len + 4;
+	data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb);
+
+	/*
+	 * PLCP setup
+	 * Length calculation depends on OFDM/CCK rate.
+	 */
+	txdesc->signal = hwrate->plcp;
+	txdesc->service = 0x04;
+
+	if (hwrate->flags & DEV_RATE_OFDM) {
+		txdesc->length_high = (data_length >> 6) & 0x3f;
+		txdesc->length_low = data_length & 0x3f;
+	} else {
+		/*
+		 * Convert length to microseconds.
+		 */
+		residual = GET_DURATION_RES(data_length, hwrate->bitrate);
+		duration = GET_DURATION(data_length, hwrate->bitrate);
+
+		if (residual != 0) {
+			duration++;
+
+			/*
+			 * Check if we need to set the Length Extension
+			 */
+			if (hwrate->bitrate == 110 && residual <= 30)
+				txdesc->service |= 0x80;
+		}
+
+		txdesc->length_high = (duration >> 8) & 0xff;
+		txdesc->length_low = duration & 0xff;
+
+		/*
+		 * When preamble is enabled we should set the
+		 * preamble bit for the signal.
+		 */
+		if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+			txdesc->signal |= 0x08;
+	}
+}
+
 static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 					     struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
-	struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
 	struct ieee80211_rate *rate =
 	    ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
 	const struct rt2x00_rate *hwrate;
-	unsigned int data_length;
-	unsigned int duration;
-	unsigned int residual;
-	unsigned long irqflags;
 
 	memset(txdesc, 0, sizeof(*txdesc));
 
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descri
 	txdesc->cw_max = entry->queue->cw_max;
 	txdesc->aifs = entry->queue->aifs;
 
-	/* Data length + CRC */
-	data_length = entry->skb->len + 4;
-
 	/*
 	 * Check whether this frame is to be acked.
 	 */
 	if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
 		__set_bit(ENTRY_TXD_ACK, &txdesc->flags);
 
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
-	    !entry->skb->do_not_encrypt) {
-		/* Apply crypto specific descriptor information */
-		rt2x00crypto_create_tx_descriptor(entry, txdesc);
-
-		/*
-		 * Extend frame length to include all encryption overhead
-		 * that will be added by the hardware.
-		 */
-		data_length += rt2x00crypto_tx_overhead(tx_info);
-	}
-
 	/*
 	 * Check if this is a RTS/CTS frame
 	 */
@@ -237,86 +307,27 @@ static void rt2x00queue_create_tx_descri
 	 * Set ifs to IFS_SIFS when the this is not the first fragment,
 	 * or this fragment came after RTS/CTS.
 	 */
-	if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
-		txdesc->ifs = IFS_SIFS;
-	} else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+	if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) &&
+	    !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
 		__set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
 		txdesc->ifs = IFS_BACKOFF;
-	} else {
+	} else
 		txdesc->ifs = IFS_SIFS;
-	}
 
 	/*
-	 * Hardware should insert sequence counter.
-	 * FIXME: We insert a software sequence counter first for
-	 * hardware that doesn't support hardware sequence counting.
-	 *
-	 * This is wrong because beacons are not getting sequence
-	 * numbers assigned properly.
-	 *
-	 * A secondary problem exists for drivers that cannot toggle
-	 * sequence counting per-frame, since those will override the
-	 * sequence counter given by mac80211.
+	 * Determine rate modulation.
 	 */
-	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		if (likely(tx_info->control.vif)) {
-			struct rt2x00_intf *intf;
-
-			intf = vif_to_intf(tx_info->control.vif);
-
-			spin_lock_irqsave(&intf->seqlock, irqflags);
-
-			if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
-				intf->seqno += 0x10;
-			hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-			hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
-
-			spin_unlock_irqrestore(&intf->seqlock, irqflags);
-
-			__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
-		}
-	}
+	hwrate = rt2x00_get_rate(rate->hw_value);
+	txdesc->rate_mode = RATE_MODE_CCK;
+	if (hwrate->flags & DEV_RATE_OFDM)
+		txdesc->rate_mode = RATE_MODE_OFDM;
 
 	/*
-	 * PLCP setup
-	 * Length calculation depends on OFDM/CCK rate.
+	 * Apply TX descriptor handling by components
 	 */
-	hwrate = rt2x00_get_rate(rate->hw_value);
-	txdesc->signal = hwrate->plcp;
-	txdesc->service = 0x04;
-
-	if (hwrate->flags & DEV_RATE_OFDM) {
-		__set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
-
-		txdesc->length_high = (data_length >> 6) & 0x3f;
-		txdesc->length_low = data_length & 0x3f;
-	} else {
-		/*
-		 * Convert length to microseconds.
-		 */
-		residual = GET_DURATION_RES(data_length, hwrate->bitrate);
-		duration = GET_DURATION(data_length, hwrate->bitrate);
-
-		if (residual != 0) {
-			duration++;
-
-			/*
-			 * Check if we need to set the Length Extension
-			 */
-			if (hwrate->bitrate == 110 && residual <= 30)
-				txdesc->service |= 0x80;
-		}
-
-		txdesc->length_high = (duration >> 8) & 0xff;
-		txdesc->length_low = duration & 0xff;
-
-		/*
-		 * When preamble is enabled we should set the
-		 * preamble bit for the signal.
-		 */
-		if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-			txdesc->signal |= 0x08;
-	}
+	rt2x00crypto_create_tx_descriptor(entry, txdesc);
+	rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
+	rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
 }
 
 static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
@@ -403,7 +414,7 @@ int rt2x00queue_write_tx_frame(struct da
 	 */
 	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
 	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
-		if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags))
+		if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
 			rt2x00crypto_tx_copy_iv(skb, iv_len);
 		else
 			rt2x00crypto_tx_remove_iv(skb, iv_len);
@@ -432,7 +443,8 @@ int rt2x00queue_write_tx_frame(struct da
 }
 
 int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
-			      struct ieee80211_vif *vif)
+			      struct ieee80211_vif *vif,
+			      const bool enable_beacon)
 {
 	struct rt2x00_intf *intf = vif_to_intf(vif);
 	struct skb_frame_desc *skbdesc;
@@ -442,6 +454,11 @@ int rt2x00queue_update_beacon(struct rt2
 	if (unlikely(!intf->beacon))
 		return -ENOBUFS;
 
+	if (!enable_beacon) {
+		rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+		return 0;
+	}
+
 	intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
 	if (!intf->beacon->skb)
 		return -ENOMEM;
@@ -490,6 +507,9 @@ struct data_queue *rt2x00queue_get_queue
 {
 	int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
 
+	if (queue == QID_RX)
+		return rt2x00dev->rx;
+
 	if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx)
 		return &rt2x00dev->tx[queue];
 
@@ -566,6 +586,14 @@ static void rt2x00queue_reset(struct dat
 	spin_unlock_irqrestore(&queue->lock, irqflags);
 }
 
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
+{
+	struct data_queue *queue;
+
+	txall_queue_for_each(rt2x00dev, queue)
+		rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+}
+
 void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00queue.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -158,6 +158,14 @@ enum rxdone_entry_desc_flags {
 };
 
 /**
+ * RXDONE_SIGNAL_MASK - Define to mask off all &rxdone_entry_desc_flags flags
+ * except for the RXDONE_SIGNAL_* flags. This is useful to convert the dev_flags
+ * from &rxdone_entry_desc to a signal value type.
+ */
+#define RXDONE_SIGNAL_MASK \
+       ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+
+/**
  * struct rxdone_entry_desc: RX Entry descriptor
  *
  * Summary of information that has been read from the RX frame descriptor.
@@ -165,6 +173,7 @@ enum rxdone_entry_desc_flags {
  * @timestamp: RX Timestamp
  * @signal: Signal of the received frame.
  * @rssi: RSSI of the received frame.
+ * @noise: Measured noise during frame reception.
  * @size: Data size of the received frame.
  * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
  * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
@@ -177,6 +186,7 @@ struct rxdone_entry_desc {
 	u64 timestamp;
 	int signal;
 	int rssi;
+	int noise;
 	int size;
 	int flags;
 	int dev_flags;
@@ -222,7 +232,6 @@ struct txdone_entry_desc {
  *
  * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
  * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
- * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
  * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter.
  * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
  * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
@@ -238,7 +247,6 @@ struct txdone_entry_desc {
 enum txentry_desc_flags {
 	ENTRY_TXD_RTS_FRAME,
 	ENTRY_TXD_CTS_FRAME,
-	ENTRY_TXD_OFDM_RATE,
 	ENTRY_TXD_GENERATE_SEQ,
 	ENTRY_TXD_FIRST_FRAGMENT,
 	ENTRY_TXD_MORE_FRAG,
@@ -263,6 +271,7 @@ enum txentry_desc_flags {
  * @length_low: PLCP length low word.
  * @signal: PLCP signal.
  * @service: PLCP service.
+ * @rate_mode: Rate mode (See @enum rate_modulation).
  * @retry_limit: Max number of retries.
  * @aifs: AIFS value.
  * @ifs: IFS value.
@@ -282,6 +291,8 @@ struct txentry_desc {
 	u16 signal;
 	u16 service;
 
+	u16 rate_mode;
+
 	short retry_limit;
 	short aifs;
 	short ifs;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00reg.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -125,6 +125,26 @@ enum cipher {
 };
 
 /*
+ * Rate modulations
+ */
+enum rate_modulation {
+	RATE_MODE_CCK = 0,
+	RATE_MODE_OFDM = 1,
+	RATE_MODE_HT_MIX = 2,
+	RATE_MODE_HT_GREENFIELD = 3,
+};
+
+/*
+ * Firmware validation error codes
+ */
+enum firmware_errors {
+	FW_OK,
+	FW_BAD_CRC,
+	FW_BAD_LENGTH,
+	FW_BAD_VERSION,
+};
+
+/*
  * Register handlers.
  * We store the position of a register field inside a field structure,
  * This will simplify the process of setting and reading a certain field
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00rfkill.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00rfkill.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00rfkill.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00rfkill.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -25,73 +25,30 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/rfkill.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
 
-static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
-{
-	struct rt2x00_dev *rt2x00dev = data;
-	int retval = 0;
-
-	if (unlikely(!rt2x00dev))
-		return 0;
-
-	/*
-	 * Only continue if there are enabled interfaces.
-	 */
-	if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
-		return 0;
-
-	if (state == RFKILL_STATE_UNBLOCKED) {
-		INFO(rt2x00dev, "RFKILL event: enabling radio.\n");
-		clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
-		retval = rt2x00lib_enable_radio(rt2x00dev);
-	} else if (state == RFKILL_STATE_SOFT_BLOCKED) {
-		INFO(rt2x00dev, "RFKILL event: disabling radio.\n");
-		set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
-		rt2x00lib_disable_radio(rt2x00dev);
-	} else {
-		WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state);
-	}
-
-	return retval;
-}
-
-static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
-{
-	struct rt2x00_dev *rt2x00dev = data;
-
-	/*
-	 * rfkill_poll reports 1 when the key has been pressed and the
-	 * radio should be blocked.
-	 */
-	*state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
-	    RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
-
-	return 0;
-}
-
-static void rt2x00rfkill_poll(struct work_struct *work)
+static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
 {
-	struct rt2x00_dev *rt2x00dev =
-	    container_of(work, struct rt2x00_dev, rfkill_work.work);
-	enum rfkill_state state;
+	struct rt2x00_dev *rt2x00dev = poll_dev->private;
+	int state, old_state;
 
 	if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) ||
 	    !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
 		return;
 
 	/*
-	 * Poll latest state and report it to rfkill who should sort
-	 * out if the state should be toggled or not.
+	 * Poll latest state, if the state is different then the previous state,
+	 * we should generate an input event.
 	 */
-	if (!rt2x00rfkill_get_state(rt2x00dev, &state))
-		rfkill_force_state(rt2x00dev->rfkill, state);
+	state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+	old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
 
-	queue_delayed_work(rt2x00dev->hw->workqueue,
-			   &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
+	if (old_state != state) {
+		input_report_switch(poll_dev->input, SW_RFKILL_ALL, state);
+		change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
+	}
 }
 
 void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -100,8 +57,8 @@ void rt2x00rfkill_register(struct rt2x00
 	    test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
 		return;
 
-	if (rfkill_register(rt2x00dev->rfkill)) {
-		ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
+	if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) {
+		ERROR(rt2x00dev, "Failed to register polled device.\n");
 		return;
 	}
 
@@ -109,10 +66,10 @@ void rt2x00rfkill_register(struct rt2x00
 
 	/*
 	 * Force initial poll which will detect the initial device state,
-	 * and correctly sends the signal to the rfkill layer about this
+	 * and correctly sends the signal to the input layer about this
 	 * state.
 	 */
-	rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
+	rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev);
 }
 
 void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -121,52 +78,50 @@ void rt2x00rfkill_unregister(struct rt2x
 	    !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
 		return;
 
-	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
-	rfkill_unregister(rt2x00dev->rfkill);
+	input_unregister_polled_device(rt2x00dev->rfkill_poll_dev);
 
 	__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
 }
 
 void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
 {
-	struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
+	struct input_polled_dev *poll_dev;
 
-	if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+	if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
+	    !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
 		return;
 
-	rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
-	if (!rt2x00dev->rfkill) {
-		ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev) {
+		ERROR(rt2x00dev, "Failed to allocate polled device.\n");
 		return;
 	}
 
-	__set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
+	poll_dev->private = rt2x00dev;
+	poll_dev->poll = rt2x00rfkill_poll;
+	poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
 
-	rt2x00dev->rfkill->name = rt2x00dev->ops->name;
-	rt2x00dev->rfkill->data = rt2x00dev;
-	rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
-	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
-		rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
-		rt2x00dev->rfkill->state =
-			rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
-			    RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
-	} else {
-		rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
-	}
+	poll_dev->input->name = rt2x00dev->ops->name;
+	poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+	poll_dev->input->id.bustype = BUS_HOST;
+	poll_dev->input->id.vendor = 0x1814;
+	poll_dev->input->id.product = rt2x00dev->chip.rt;
+	poll_dev->input->id.version = rt2x00dev->chip.rev;
+	poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
+	poll_dev->input->evbit[0] = BIT(EV_SW);
+	poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL);
 
-	INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
+	rt2x00dev->rfkill_poll_dev = poll_dev;
 
-	return;
+	__set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
 }
 
 void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
 {
-	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+	if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED,
+				  &rt2x00dev->rfkill_state))
 		return;
 
-	cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
-	rfkill_free(rt2x00dev->rfkill);
-	rt2x00dev->rfkill = NULL;
+	input_free_polled_device(rt2x00dev->rfkill_poll_dev);
+	rt2x00dev->rfkill_poll_dev = NULL;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -296,6 +296,41 @@ void rt2x00usb_kick_tx_queue(struct rt2x
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
 
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+			     const enum data_queue_qid qid)
+{
+	struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
+	struct queue_entry_priv_usb *entry_priv;
+	struct queue_entry_priv_usb_bcn *bcn_priv;
+	unsigned int i;
+	bool kill_guard;
+
+	/*
+	 * When killing the beacon queue, we must also kill
+	 * the beacon guard byte.
+	 */
+	kill_guard =
+	    (qid == QID_BEACON) &&
+	    (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags));
+
+	/*
+	 * Cancel all entries.
+	 */
+	for (i = 0; i < queue->limit; i++) {
+		entry_priv = queue->entries[i].priv_data;
+		usb_kill_urb(entry_priv->urb);
+
+		/*
+		 * Kill guardian urb (if required by driver).
+		 */
+		if (kill_guard) {
+			bcn_priv = queue->entries[i].priv_data;
+			usb_kill_urb(bcn_priv->guardian_urb);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
+
 /*
  * RX data handlers.
  */
@@ -338,35 +373,14 @@ static void rt2x00usb_interrupt_rxdone(s
  */
 void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
-	struct queue_entry_priv_usb *entry_priv;
-	struct queue_entry_priv_usb_bcn *bcn_priv;
-	struct data_queue *queue;
-	unsigned int i;
-
 	rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
 				    REGISTER_TIMEOUT);
 
 	/*
-	 * Cancel all queues.
-	 */
-	queue_for_each(rt2x00dev, queue) {
-		for (i = 0; i < queue->limit; i++) {
-			entry_priv = queue->entries[i].priv_data;
-			usb_kill_urb(entry_priv->urb);
-		}
-	}
-
-	/*
-	 * Kill guardian urb (if required by driver).
+	 * The USB version of kill_tx_queue also works
+	 * on the RX queue.
 	 */
-	if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
-		return;
-
-	for (i = 0; i < rt2x00dev->bcn->limit; i++) {
-		bcn_priv = rt2x00dev->bcn->entries[i].priv_data;
-		if (bcn_priv->guardian_urb)
-			usb_kill_urb(bcn_priv->guardian_urb);
-	}
+	rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
 
@@ -688,8 +702,6 @@ int rt2x00usb_suspend(struct usb_interfa
 	if (retval)
 		return retval;
 
-	rt2x00usb_free_reg(rt2x00dev);
-
 	/*
 	 * Decrease usbdev refcount.
 	 */
@@ -703,24 +715,10 @@ int rt2x00usb_resume(struct usb_interfac
 {
 	struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	int retval;
 
 	usb_get_dev(interface_to_usbdev(usb_intf));
 
-	retval = rt2x00usb_alloc_reg(rt2x00dev);
-	if (retval)
-		return retval;
-
-	retval = rt2x00lib_resume(rt2x00dev);
-	if (retval)
-		goto exit_free_reg;
-
-	return 0;
-
-exit_free_reg:
-	rt2x00usb_free_reg(rt2x00dev);
-
-	return retval;
+	return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_resume);
 #endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00usb.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -419,6 +419,17 @@ struct queue_entry_priv_usb_bcn {
 void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 			     const enum data_queue_qid qid);
 
+/**
+ * rt2x00usb_kill_tx_queue - Kill data queue
+ * @rt2x00dev: Pointer to &struct rt2x00_dev
+ * @qid: Data queue to kill
+ *
+ * This will walk through all entries of the queue and kill all
+ * previously kicked frames before they can be send.
+ */
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+			      const enum data_queue_qid qid);
+
 /*
  * Device initialization handlers.
  */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt61pci.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 18:05:05.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt61pci.c	2013-05-03 16:49:06.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -123,9 +123,6 @@ static void rt61pci_rf_write(struct rt2x
 {
 	u32 reg;
 
-	if (!word)
-		return;
-
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -146,12 +143,6 @@ static void rt61pci_rf_write(struct rt2x
 	mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
-#ifdef CONFIG_RT2X00_LIB_LEDS
-/*
- * This function is only called from rt61pci_led_brightness()
- * make gcc happy by placing this function inside the
- * same ifdef statement as the caller.
- */
 static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
 				const u8 command, const u8 token,
 				const u8 arg0, const u8 arg1)
@@ -180,7 +171,6 @@ static void rt61pci_mcu_request(struct r
 	mutex_unlock(&rt2x00dev->csr_mutex);
 
 }
-#endif /* CONFIG_RT2X00_LIB_LEDS */
 
 static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
 {
@@ -967,6 +957,50 @@ static void rt61pci_config_duration(stru
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
 }
 
+static void rt61pci_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) {
+		rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+		rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+				   libconf->conf->beacon_int - 10);
+		rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
+				   libconf->conf->listen_interval - 1);
+		rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
+
+		/* We must first disable autowake before it can be enabled */
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+		rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+		rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+		rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005);
+		rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c);
+		rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060);
+
+		rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0);
+	} else {
+		rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+		rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+		rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+		rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
+		rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018);
+		rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020);
+
+		rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+	}
+}
+
 static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
 			   struct rt2x00lib_conf *libconf,
 			   const unsigned int flags)
@@ -984,6 +1018,8 @@ static void rt61pci_config(struct rt2x00
 		rt61pci_config_retry_limit(rt2x00dev, libconf);
 	if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
 		rt61pci_config_duration(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt61pci_config_ps(rt2x00dev, libconf);
 }
 
 /*
@@ -1007,21 +1043,28 @@ static void rt61pci_link_stats(struct rt
 	qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
-static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+				   struct link_qual *qual, u8 vgc_level)
 {
-	rt61pci_bbp_write(rt2x00dev, 17, 0x20);
-	rt2x00dev->link.vgc_level = 0x20;
+	if (qual->vgc_level != vgc_level) {
+		rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+		qual->vgc_level = vgc_level;
+		qual->vgc_level_reg = vgc_level;
+	}
 }
 
-static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+				struct link_qual *qual)
+{
+	rt61pci_set_vgc(rt2x00dev, qual, 0x20);
+}
+
+static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+			       struct link_qual *qual, const u32 count)
 {
-	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-	u8 r17;
 	u8 up_bound;
 	u8 low_bound;
 
-	rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
 	/*
 	 * Determine r17 bounds.
 	 */
@@ -1051,38 +1094,32 @@ static void rt61pci_link_tuner(struct rt
 	/*
 	 * Special big-R17 for very short distance
 	 */
-	if (rssi >= -35) {
-		if (r17 != 0x60)
-			rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+	if (qual->rssi >= -35) {
+		rt61pci_set_vgc(rt2x00dev, qual, 0x60);
 		return;
 	}
 
 	/*
 	 * Special big-R17 for short distance
 	 */
-	if (rssi >= -58) {
-		if (r17 != up_bound)
-			rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+	if (qual->rssi >= -58) {
+		rt61pci_set_vgc(rt2x00dev, qual, up_bound);
 		return;
 	}
 
 	/*
 	 * Special big-R17 for middle-short distance
 	 */
-	if (rssi >= -66) {
-		low_bound += 0x10;
-		if (r17 != low_bound)
-			rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+	if (qual->rssi >= -66) {
+		rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x10);
 		return;
 	}
 
 	/*
 	 * Special mid-R17 for middle distance
 	 */
-	if (rssi >= -74) {
-		low_bound += 0x08;
-		if (r17 != low_bound)
-			rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+	if (qual->rssi >= -74) {
+		rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x08);
 		return;
 	}
 
@@ -1090,12 +1127,12 @@ static void rt61pci_link_tuner(struct rt
 	 * Special case: Change up_bound based on the rssi.
 	 * Lower up_bound when rssi is weaker then -74 dBm.
 	 */
-	up_bound -= 2 * (-74 - rssi);
+	up_bound -= 2 * (-74 - qual->rssi);
 	if (low_bound > up_bound)
 		up_bound = low_bound;
 
-	if (r17 > up_bound) {
-		rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+	if (qual->vgc_level > up_bound) {
+		rt61pci_set_vgc(rt2x00dev, qual, up_bound);
 		return;
 	}
 
@@ -1105,15 +1142,10 @@ dynamic_cca_tune:
 	 * r17 does not yet exceed upper limit, continue and base
 	 * the r17 tuning on the false CCA count.
 	 */
-	if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
-		if (++r17 > up_bound)
-			r17 = up_bound;
-		rt61pci_bbp_write(rt2x00dev, 17, r17);
-	} else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
-		if (--r17 < low_bound)
-			r17 = low_bound;
-		rt61pci_bbp_write(rt2x00dev, 17, r17);
-	}
+	if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+		rt61pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+	else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+		rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
 }
 
 /*
@@ -1141,25 +1173,37 @@ static char *rt61pci_get_firmware_name(s
 	return fw_name;
 }
 
-static u16 rt61pci_get_firmware_crc(const void *data, const size_t len)
+static int rt61pci_check_firmware(struct rt2x00_dev *rt2x00dev,
+				  const u8 *data, const size_t len)
 {
+	u16 fw_crc;
 	u16 crc;
 
 	/*
-	 * Use the crc itu-t algorithm.
+	 * 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 itu-t algorithm.
+	 */
 	crc = crc_itu_t(0, data, len - 2);
 	crc = crc_itu_t_byte(crc, 0);
 	crc = crc_itu_t_byte(crc, 0);
 
-	return crc;
+	return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
 }
 
-static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
-				 const size_t len)
+static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev,
+				 const u8 *data, const size_t len)
 {
 	int i;
 	u32 reg;
@@ -1656,24 +1700,10 @@ static int rt61pci_enable_radio(struct r
 
 static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
-	u32 reg;
-
-	rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
-
 	/*
-	 * Disable synchronisation.
-	 */
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
-
-	/*
-	 * Cancel RX and TX.
+	 * Disable power
 	 */
-	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
-	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
-	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
-	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
-	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
-	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+	rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
 }
 
 static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
@@ -1812,7 +1842,7 @@ static void rt61pci_write_tx_desc(struct
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+			   (txdesc->rate_mode == RATE_MODE_OFDM));
 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1896,6 +1926,24 @@ static void rt61pci_kick_tx_queue(struct
 	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 }
 
+static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+				  const enum data_queue_qid qid)
+{
+	u32 reg;
+
+	if (qid == QID_BEACON) {
+		rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
+		return;
+	}
+
+	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
+	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
+	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
+	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO));
+	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+}
+
 /*
  * RX control handlers
  */
@@ -2195,7 +2243,8 @@ static int rt61pci_validate_eeprom(struc
 	if (word == 0xffff) {
 		rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0);
 		rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0);
-		rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_RX_FIXED, 0);
+		rt2x00_set_field16(&word, EEPROM_NIC_TX_FIXED, 0);
 		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
 		rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
 		rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
@@ -2339,24 +2388,10 @@ static int rt61pci_init_eeprom(struct rt
 	 */
 	if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
 	    !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
-		switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
-		case 0:
-			rt2x00dev->default_ant.tx = ANTENNA_B;
-			rt2x00dev->default_ant.rx = ANTENNA_A;
-			break;
-		case 1:
-			rt2x00dev->default_ant.tx = ANTENNA_B;
-			rt2x00dev->default_ant.rx = ANTENNA_B;
-			break;
-		case 2:
-			rt2x00dev->default_ant.tx = ANTENNA_A;
-			rt2x00dev->default_ant.rx = ANTENNA_A;
-			break;
-		case 3:
-			rt2x00dev->default_ant.tx = ANTENNA_A;
-			rt2x00dev->default_ant.rx = ANTENNA_B;
-			break;
-		}
+		rt2x00dev->default_ant.rx =
+		    ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
+		rt2x00dev->default_ant.tx =
+		    ANTENNA_B - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_FIXED);
 
 		if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
 			rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
@@ -2534,7 +2569,9 @@ static int rt61pci_probe_hw_mode(struct
 	 */
 	rt2x00dev->hw->flags =
 	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-	    IEEE80211_HW_SIGNAL_DBM;
+	    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);
@@ -2633,6 +2670,7 @@ static int rt61pci_conf_tx(struct ieee80
 	struct rt2x00_field32 field;
 	int retval;
 	u32 reg;
+	u32 offset;
 
 	/*
 	 * First pass the configuration through rt2x00lib, that will
@@ -2644,24 +2682,23 @@ static int rt61pci_conf_tx(struct ieee80
 	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 */
-	if (queue_idx < 2) {
-		field.bit_offset = queue_idx * 16;
-		field.bit_mask = 0xffff << field.bit_offset;
-
-		rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
-		rt2x00_set_field32(&reg, field, queue->txop);
-		rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
-	} else if (queue_idx < 4) {
-		field.bit_offset = (queue_idx - 2) * 16;
-		field.bit_mask = 0xffff << field.bit_offset;
+	offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+	field.bit_offset = (queue_idx & 1) * 16;
+	field.bit_mask = 0xffff << field.bit_offset;
 
-		rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
-		rt2x00_set_field32(&reg, field, queue->txop);
-		rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
-	}
+	rt2x00pci_register_read(rt2x00dev, offset, &reg);
+	rt2x00_set_field32(&reg, field, queue->txop);
+	rt2x00pci_register_write(rt2x00dev, offset, reg);
 
 	/* Update WMM registers */
 	field.bit_offset = queue_idx * 4;
@@ -2717,7 +2754,7 @@ static const struct rt2x00lib_ops rt61pc
 	.irq_handler		= rt61pci_interrupt,
 	.probe_hw		= rt61pci_probe_hw,
 	.get_firmware_name	= rt61pci_get_firmware_name,
-	.get_firmware_crc	= rt61pci_get_firmware_crc,
+	.check_firmware		= rt61pci_check_firmware,
 	.load_firmware		= rt61pci_load_firmware,
 	.initialize		= rt2x00pci_initialize,
 	.uninitialize		= rt2x00pci_uninitialize,
@@ -2732,6 +2769,7 @@ static const struct rt2x00lib_ops rt61pc
 	.write_tx_data		= rt2x00pci_write_tx_data,
 	.write_beacon		= rt61pci_write_beacon,
 	.kick_tx_queue		= rt61pci_kick_tx_queue,
+	.kill_tx_queue		= rt61pci_kill_tx_queue,
 	.fill_rxdone		= rt61pci_fill_rxdone,
 	.config_shared_key	= rt61pci_config_shared_key,
 	.config_pairwise_key	= rt61pci_config_pairwise_key,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt61pci.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt61pci.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 18:05:02.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt61pci.h	2013-05-03 16:49:03.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
 #define EEPROM_SIZE			0x0100
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x0080
-#define RF_BASE				0x0000
-#define RF_SIZE				0x0014
+#define RF_BASE				0x0004
+#define RF_SIZE				0x0010
 
 /*
  * Number of TX queues.
@@ -88,8 +88,10 @@
 
 /*
  * SOFT_RESET_CSR
+ * FORCE_CLOCK_ON: Host force MAC clock ON
  */
 #define SOFT_RESET_CSR			0x0010
+#define SOFT_RESET_CSR_FORCE_CLOCK_ON	FIELD32(0x00000002)
 
 /*
  * MCU_INT_SOURCE_CSR: MCU interrupt source/mask register.
@@ -1054,8 +1056,10 @@ struct hw_pairwise_ta_entry {
 
 /*
  * IO_CNTL_CSR
+ * RF_PS: Set RF interface value to power save
  */
 #define IO_CNTL_CSR			0x3498
+#define IO_CNTL_CSR_RF_PS		FIELD32(0x00000004)
 
 /*
  * UART_INT_SOURCE_CSR
@@ -1186,7 +1190,8 @@ struct hw_pairwise_ta_entry {
 #define EEPROM_NIC			0x0011
 #define EEPROM_NIC_ENABLE_DIVERSITY	FIELD16(0x0001)
 #define EEPROM_NIC_TX_DIVERSITY		FIELD16(0x0002)
-#define EEPROM_NIC_TX_RX_FIXED		FIELD16(0x000c)
+#define EEPROM_NIC_RX_FIXED		FIELD16(0x0004)
+#define EEPROM_NIC_TX_FIXED		FIELD16(0x0008)
 #define EEPROM_NIC_EXTERNAL_LNA_BG	FIELD16(0x0010)
 #define EEPROM_NIC_CARDBUS_ACCEL	FIELD16(0x0020)
 #define EEPROM_NIC_EXTERNAL_LNA_A	FIELD16(0x0040)
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt73usb.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 18:05:10.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt73usb.c	2013-05-03 16:49:10.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -122,9 +122,6 @@ static void rt73usb_rf_write(struct rt2x
 {
 	u32 reg;
 
-	if (!word)
-		return;
-
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -186,6 +183,18 @@ static const struct rt2x00debug rt73usb_
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+	return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+}
+#else
+#define rt73usb_rfkill_poll	NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
 				   enum led_brightness brightness)
@@ -844,6 +853,44 @@ static void rt73usb_config_duration(stru
 	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 }
 
+static void rt73usb_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_read(rt2x00dev, MAC_CSR11, &reg);
+		rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+				   libconf->conf->beacon_int - 10);
+		rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
+				   libconf->conf->listen_interval - 1);
+		rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
+
+		/* We must first disable autowake before it can be enabled */
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+		rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+		rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+		rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+					    USB_MODE_SLEEP, REGISTER_TIMEOUT);
+	} else {
+		rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+					    USB_MODE_WAKEUP, REGISTER_TIMEOUT);
+
+		rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+		rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+		rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+		rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+	}
+}
+
 static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
 			   struct rt2x00lib_conf *libconf,
 			   const unsigned int flags)
@@ -861,6 +908,8 @@ static void rt73usb_config(struct rt2x00
 		rt73usb_config_retry_limit(rt2x00dev, libconf);
 	if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
 		rt73usb_config_duration(rt2x00dev, libconf);
+	if (flags & IEEE80211_CONF_CHANGE_PS)
+		rt73usb_config_ps(rt2x00dev, libconf);
 }
 
 /*
@@ -884,21 +933,28 @@ static void rt73usb_link_stats(struct rt
 	qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
-static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+				   struct link_qual *qual, u8 vgc_level)
 {
-	rt73usb_bbp_write(rt2x00dev, 17, 0x20);
-	rt2x00dev->link.vgc_level = 0x20;
+	if (qual->vgc_level != vgc_level) {
+		rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+		qual->vgc_level = vgc_level;
+		qual->vgc_level_reg = vgc_level;
+	}
 }
 
-static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+				struct link_qual *qual)
+{
+	rt73usb_set_vgc(rt2x00dev, qual, 0x20);
+}
+
+static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+			       struct link_qual *qual, const u32 count)
 {
-	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
-	u8 r17;
 	u8 up_bound;
 	u8 low_bound;
 
-	rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
 	/*
 	 * Determine r17 bounds.
 	 */
@@ -911,10 +967,10 @@ static void rt73usb_link_tuner(struct rt
 			up_bound += 0x10;
 		}
 	} else {
-		if (rssi > -82) {
+		if (qual->rssi > -82) {
 			low_bound = 0x1c;
 			up_bound = 0x40;
-		} else if (rssi > -84) {
+		} else if (qual->rssi > -84) {
 			low_bound = 0x1c;
 			up_bound = 0x20;
 		} else {
@@ -938,37 +994,32 @@ static void rt73usb_link_tuner(struct rt
 	/*
 	 * Special big-R17 for very short distance
 	 */
-	if (rssi > -35) {
-		if (r17 != 0x60)
-			rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+	if (qual->rssi > -35) {
+		rt73usb_set_vgc(rt2x00dev, qual, 0x60);
 		return;
 	}
 
 	/*
 	 * Special big-R17 for short distance
 	 */
-	if (rssi >= -58) {
-		if (r17 != up_bound)
-			rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+	if (qual->rssi >= -58) {
+		rt73usb_set_vgc(rt2x00dev, qual, up_bound);
 		return;
 	}
 
 	/*
 	 * Special big-R17 for middle-short distance
 	 */
-	if (rssi >= -66) {
-		low_bound += 0x10;
-		if (r17 != low_bound)
-			rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+	if (qual->rssi >= -66) {
+		rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x10);
 		return;
 	}
 
 	/*
 	 * Special mid-R17 for middle distance
 	 */
-	if (rssi >= -74) {
-		if (r17 != (low_bound + 0x10))
-			rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+	if (qual->rssi >= -74) {
+		rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08);
 		return;
 	}
 
@@ -976,12 +1027,12 @@ static void rt73usb_link_tuner(struct rt
 	 * Special case: Change up_bound based on the rssi.
 	 * Lower up_bound when rssi is weaker then -74 dBm.
 	 */
-	up_bound -= 2 * (-74 - rssi);
+	up_bound -= 2 * (-74 - qual->rssi);
 	if (low_bound > up_bound)
 		up_bound = low_bound;
 
-	if (r17 > up_bound) {
-		rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+	if (qual->vgc_level > up_bound) {
+		rt73usb_set_vgc(rt2x00dev, qual, up_bound);
 		return;
 	}
 
@@ -991,17 +1042,12 @@ dynamic_cca_tune:
 	 * r17 does not yet exceed upper limit, continue and base
 	 * the r17 tuning on the false CCA count.
 	 */
-	if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
-		r17 += 4;
-		if (r17 > up_bound)
-			r17 = up_bound;
-		rt73usb_bbp_write(rt2x00dev, 17, r17);
-	} else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
-		r17 -= 4;
-		if (r17 < low_bound)
-			r17 = low_bound;
-		rt73usb_bbp_write(rt2x00dev, 17, r17);
-	}
+	if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+		rt73usb_set_vgc(rt2x00dev, qual,
+				min_t(u8, qual->vgc_level + 4, up_bound));
+	else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+		rt73usb_set_vgc(rt2x00dev, qual,
+				max_t(u8, qual->vgc_level - 4, low_bound));
 }
 
 /*
@@ -1012,25 +1058,37 @@ static char *rt73usb_get_firmware_name(s
 	return FIRMWARE_RT2571;
 }
 
-static u16 rt73usb_get_firmware_crc(const void *data, const size_t len)
+static int rt73usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+				  const u8 *data, const size_t len)
 {
+	u16 fw_crc;
 	u16 crc;
 
 	/*
-	 * Use the crc itu-t algorithm.
+	 * Only support 2kb firmware files.
+	 */
+	if (len != 2048)
+		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 itu-t algorithm.
+	 */
 	crc = crc_itu_t(0, data, len - 2);
 	crc = crc_itu_t_byte(crc, 0);
 	crc = crc_itu_t_byte(crc, 0);
 
-	return crc;
+	return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
 }
 
-static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
-				 const size_t len)
+static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+				 const u8 *data, const size_t len)
 {
 	unsigned int i;
 	int status;
@@ -1449,7 +1507,7 @@ static void rt73usb_write_tx_desc(struct
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
 			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+			   (txdesc->rate_mode == RATE_MODE_OFDM));
 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1816,6 +1874,14 @@ static int rt73usb_init_eeprom(struct rt
 		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 
 	/*
+	 * Detect if this device has an hardware controlled radio.
+	 */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+	/*
 	 * Read frequency offset.
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
@@ -2020,7 +2086,9 @@ static int rt73usb_probe_hw_mode(struct
 	 */
 	rt2x00dev->hw->flags =
 	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-	    IEEE80211_HW_SIGNAL_DBM;
+	    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);
@@ -2121,6 +2189,7 @@ static int rt73usb_conf_tx(struct ieee80
 	struct rt2x00_field32 field;
 	int retval;
 	u32 reg;
+	u32 offset;
 
 	/*
 	 * First pass the configuration through rt2x00lib, that will
@@ -2132,24 +2201,23 @@ static int rt73usb_conf_tx(struct ieee80
 	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 */
-	if (queue_idx < 2) {
-		field.bit_offset = queue_idx * 16;
-		field.bit_mask = 0xffff << field.bit_offset;
-
-		rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
-		rt2x00_set_field32(&reg, field, queue->txop);
-		rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
-	} else if (queue_idx < 4) {
-		field.bit_offset = (queue_idx - 2) * 16;
-		field.bit_mask = 0xffff << field.bit_offset;
+	offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+	field.bit_offset = (queue_idx & 1) * 16;
+	field.bit_mask = 0xffff << field.bit_offset;
 
-		rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
-		rt2x00_set_field32(&reg, field, queue->txop);
-		rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
-	}
+	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;
@@ -2170,13 +2238,6 @@ static int rt73usb_conf_tx(struct ieee80
 	return 0;
 }
 
-#if 0
-/*
- * Mac80211 demands get_tsf must be atomic.
- * This is not possible for rt73usb since all register access
- * functions require sleeping. Untill mac80211 no longer needs
- * get_tsf to be atomic, this function should be disabled.
- */
 static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2190,9 +2251,6 @@ static u64 rt73usb_get_tsf(struct ieee80
 
 	return tsf;
 }
-#else
-#define rt73usb_get_tsf	NULL
-#endif
 
 static const struct ieee80211_ops rt73usb_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
@@ -2214,12 +2272,13 @@ static const struct ieee80211_ops rt73us
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 	.probe_hw		= rt73usb_probe_hw,
 	.get_firmware_name	= rt73usb_get_firmware_name,
-	.get_firmware_crc	= rt73usb_get_firmware_crc,
+	.check_firmware		= rt73usb_check_firmware,
 	.load_firmware		= rt73usb_load_firmware,
 	.initialize		= rt2x00usb_initialize,
 	.uninitialize		= rt2x00usb_uninitialize,
 	.clear_entry		= rt2x00usb_clear_entry,
 	.set_device_state	= rt73usb_set_device_state,
+	.rfkill_poll		= rt73usb_rfkill_poll,
 	.link_stats		= rt73usb_link_stats,
 	.reset_tuner		= rt73usb_reset_tuner,
 	.link_tuner		= rt73usb_link_tuner,
@@ -2228,6 +2287,7 @@ static const struct rt2x00lib_ops rt73us
 	.write_beacon		= rt73usb_write_beacon,
 	.get_tx_data_len	= rt73usb_get_tx_data_len,
 	.kick_tx_queue		= rt73usb_kick_tx_queue,
+	.kill_tx_queue		= rt2x00usb_kill_tx_queue,
 	.fill_rxdone		= rt73usb_fill_rxdone,
 	.config_shared_key	= rt73usb_config_shared_key,
 	.config_pairwise_key	= rt73usb_config_pairwise_key,
@@ -2309,6 +2369,8 @@ static struct usb_device_id rt73usb_devi
 	/* Buffalo */
 	{ USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* CNet */
 	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
@@ -2365,6 +2427,8 @@ static struct usb_device_id rt73usb_devi
 	{ USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Surecom */
 	{ USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+	/* Tilgin */
+	{ USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Philips */
 	{ USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Planex */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt73usb.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt73usb.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 18:05:08.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt73usb.h	2013-05-03 16:49:08.000000000 -0400
@@ -1,5 +1,5 @@
 /*
-	Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 	<http://rt2x00.serialmonkey.com>
 
 	This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
 #define EEPROM_SIZE			0x0100
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x0080
-#define RF_BASE				0x0000
-#define RF_SIZE				0x0014
+#define RF_BASE				0x0004
+#define RF_SIZE				0x0010
 
 /*
  * Number of TX queues.
@@ -267,6 +267,19 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR13: GPIO.
  */
 #define MAC_CSR13			0x3034
+#define MAC_CSR13_BIT0			FIELD32(0x00000001)
+#define MAC_CSR13_BIT1			FIELD32(0x00000002)
+#define MAC_CSR13_BIT2			FIELD32(0x00000004)
+#define MAC_CSR13_BIT3			FIELD32(0x00000008)
+#define MAC_CSR13_BIT4			FIELD32(0x00000010)
+#define MAC_CSR13_BIT5			FIELD32(0x00000020)
+#define MAC_CSR13_BIT6			FIELD32(0x00000040)
+#define MAC_CSR13_BIT7			FIELD32(0x00000080)
+#define MAC_CSR13_BIT8			FIELD32(0x00000100)
+#define MAC_CSR13_BIT9			FIELD32(0x00000200)
+#define MAC_CSR13_BIT10			FIELD32(0x00000400)
+#define MAC_CSR13_BIT11			FIELD32(0x00000800)
+#define MAC_CSR13_BIT12			FIELD32(0x00001000)
 
 /*
  * MAC_CSR14: LED control register.
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187_dev.c	2009-06-09 23:05:27.000000000 -0400
@@ -71,6 +71,8 @@ static struct usb_device_id rtl8187_tabl
 	{USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
 	/* AirLive */
 	{USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
+	/* Linksys */
+	{USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B},
 	{}
 };
 
@@ -189,25 +191,33 @@ static void rtl8187_tx_cb(struct urb *ur
 					  sizeof(struct rtl8187_tx_hdr));
 	ieee80211_tx_info_clear_status(info);
 
-	if (!urb->status &&
-	    !(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-	    priv->is_rtl8187b) {
-		skb_queue_tail(&priv->b_tx_status.queue, skb);
+	if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+		if (priv->is_rtl8187b) {
+			skb_queue_tail(&priv->b_tx_status.queue, skb);
 
-		/* queue is "full", discard last items */
-		while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
-			struct sk_buff *old_skb;
+			/* queue is "full", discard last items */
+			while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
+				struct sk_buff *old_skb;
 
-			dev_dbg(&priv->udev->dev,
-				"transmit status queue full\n");
+				dev_dbg(&priv->udev->dev,
+					"transmit status queue full\n");
 
-			old_skb = skb_dequeue(&priv->b_tx_status.queue);
-			ieee80211_tx_status_irqsafe(hw, old_skb);
-		}
-	} else {
-		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status)
+				old_skb = skb_dequeue(&priv->b_tx_status.queue);
+				ieee80211_tx_status_irqsafe(hw, old_skb);
+			}
+			return;
+		} else {
 			info->flags |= IEEE80211_TX_STAT_ACK;
+		}
+	}
+	if (priv->is_rtl8187b)
 		ieee80211_tx_status_irqsafe(hw, skb);
+	else {
+		/* Retry information for the RTI8187 is only available by
+		 * reading a register in the device. We are in interrupt mode
+		 * here, thus queue the skb and finish on a work queue. */
+		skb_queue_tail(&priv->b_tx_status.queue, skb);
+		queue_delayed_work(hw->workqueue, &priv->work, 0);
 	}
 }
 
@@ -403,7 +413,7 @@ static int rtl8187_init_urbs(struct ieee
 	struct rtl8187_rx_info *info;
 	int ret = 0;
 
-	while (skb_queue_len(&priv->rx_queue) < 8) {
+	while (skb_queue_len(&priv->rx_queue) < 16) {
 		skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
 		if (!skb) {
 			ret = -ENOMEM;
@@ -657,7 +667,7 @@ static int rtl8187_init_hw(struct ieee80
 
 	rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
 	rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
-	rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+	rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
 
 	// TODO: set RESP_RATE and BRSR properly
 	rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
@@ -777,9 +787,6 @@ static int rtl8187b_init_hw(struct ieee8
 	rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
 
 	rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
-	reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
-	reg |= RTL818X_RATE_FALLBACK_ENABLE;
-	rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
 
 	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
 	rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -867,6 +874,34 @@ static int rtl8187b_init_hw(struct ieee8
 	return 0;
 }
 
+static void rtl8187_work(struct work_struct *work)
+{
+	/* The RTL8187 returns the retry count through register 0xFFFA. In
+	 * addition, it appears to be a cumulative retry count, not the
+	 * value for the current TX packet. When multiple TX entries are
+	 * queued, the retry count will be valid for the last one in the queue.
+	 * The "error" should not matter for purposes of rate setting. */
+	struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+				    work.work);
+	struct ieee80211_tx_info *info;
+	struct ieee80211_hw *dev = priv->dev;
+	static u16 retry;
+	u16 tmp;
+
+	mutex_lock(&priv->conf_mutex);
+	tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
+	while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
+		struct sk_buff *old_skb;
+
+		old_skb = skb_dequeue(&priv->b_tx_status.queue);
+		info = IEEE80211_SKB_CB(old_skb);
+		info->status.rates[0].count = tmp - retry + 1;
+		ieee80211_tx_status_irqsafe(dev, old_skb);
+	}
+	retry = tmp;
+	mutex_unlock(&priv->conf_mutex);
+}
+
 static int rtl8187_start(struct ieee80211_hw *dev)
 {
 	struct rtl8187_priv *priv = dev->priv;
@@ -881,6 +916,7 @@ static int rtl8187_start(struct ieee8021
 	mutex_lock(&priv->conf_mutex);
 
 	init_usb_anchor(&priv->anchored);
+	priv->dev = dev;
 
 	if (priv->is_rtl8187b) {
 		reg = RTL818X_RX_CONF_MGMT |
@@ -948,6 +984,7 @@ static int rtl8187_start(struct ieee8021
 	reg |= RTL818X_CMD_TX_ENABLE;
 	reg |= RTL818X_CMD_RX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+	INIT_DELAYED_WORK(&priv->work, rtl8187_work);
 	mutex_unlock(&priv->conf_mutex);
 
 	return 0;
@@ -978,6 +1015,8 @@ static void rtl8187_stop(struct ieee8021
 		dev_kfree_skb_any(skb);
 
 	usb_kill_anchored_urbs(&priv->anchored);
+	if (!priv->is_rtl8187b)
+		cancel_delayed_work_sync(&priv->work);
 	mutex_unlock(&priv->conf_mutex);
 }
 
@@ -986,19 +1025,21 @@ static int rtl8187_add_interface(struct
 {
 	struct rtl8187_priv *priv = dev->priv;
 	int i;
+	int ret = -EOPNOTSUPP;
 
+	mutex_lock(&priv->conf_mutex);
 	if (priv->mode != NL80211_IFTYPE_MONITOR)
-		return -EOPNOTSUPP;
+		goto exit;
 
 	switch (conf->type) {
 	case NL80211_IFTYPE_STATION:
 		priv->mode = conf->type;
 		break;
 	default:
-		return -EOPNOTSUPP;
+		goto exit;
 	}
 
-	mutex_lock(&priv->conf_mutex);
+	ret = 0;
 	priv->vif = conf->vif;
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -1007,8 +1048,9 @@ static int rtl8187_add_interface(struct
 				 ((u8 *)conf->mac_addr)[i]);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
+exit:
 	mutex_unlock(&priv->conf_mutex);
-	return 0;
+	return ret;
 }
 
 static void rtl8187_remove_interface(struct ieee80211_hw *dev,
@@ -1289,6 +1331,14 @@ static int __devinit rtl8187_probe(struc
 	priv = dev->priv;
 	priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
 
+	/* allocate "DMA aware" buffer for register accesses */
+	priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL);
+	if (!priv->io_dmabuf) {
+		err = -ENOMEM;
+		goto err_free_dev;
+	}
+	mutex_init(&priv->io_mutex);
+
 	SET_IEEE80211_DEV(dev, &intf->dev);
 	usb_set_intfdata(intf, dev);
 	priv->udev = udev;
@@ -1455,7 +1505,7 @@ static int __devinit rtl8187_probe(struc
 	err = ieee80211_register_hw(dev);
 	if (err) {
 		printk(KERN_ERR "rtl8187: Cannot register device\n");
-		goto err_free_dev;
+		goto err_free_dmabuf;
 	}
 	mutex_init(&priv->conf_mutex);
 	skb_queue_head_init(&priv->b_tx_status.queue);
@@ -1466,6 +1516,8 @@ static int __devinit rtl8187_probe(struc
 
 	return 0;
 
+ err_free_dmabuf:
+	kfree(priv->io_dmabuf);
  err_free_dev:
 	ieee80211_free_hw(dev);
 	usb_set_intfdata(intf, NULL);
@@ -1486,6 +1538,7 @@ static void __devexit rtl8187_disconnect
 	priv = dev->priv;
 	usb_reset_device(priv->udev);
 	usb_put_dev(interface_to_usbdev(intf));
+	kfree(priv->io_dmabuf);
 	ieee80211_free_hw(dev);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187.h linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187.h	2009-06-09 23:05:27.000000000 -0400
@@ -100,6 +100,8 @@ struct rtl8187_priv {
 	struct usb_device *udev;
 	u32 rx_conf;
 	struct usb_anchor anchored;
+	struct delayed_work work;
+	struct ieee80211_hw *dev;
 	u16 txpwr_base;
 	u8 asic_rev;
 	u8 is_rtl8187b;
@@ -117,7 +119,13 @@ struct rtl8187_priv {
 	struct {
 		__le64 buf;
 		struct sk_buff_head queue;
-	} b_tx_status;
+	} b_tx_status; /* This queue is used by both -b and non-b devices */
+	struct mutex io_mutex;
+	union {
+		u8 bits8;
+		__le16 bits16;
+		__le32 bits32;
+	} *io_dmabuf;
 };
 
 void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
@@ -127,10 +135,14 @@ static inline u8 rtl818x_ioread8_idx(str
 {
 	u8 val;
 
+	mutex_lock(&priv->io_mutex);
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, idx & 0x03, &val,
-			sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
+
+	val = priv->io_dmabuf->bits8;
+	mutex_unlock(&priv->io_mutex);
 
 	return val;
 }
@@ -145,10 +157,14 @@ static inline u16 rtl818x_ioread16_idx(s
 {
 	__le16 val;
 
+	mutex_lock(&priv->io_mutex);
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, idx & 0x03, &val,
-			sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
+
+	val = priv->io_dmabuf->bits16;
+	mutex_unlock(&priv->io_mutex);
 
 	return le16_to_cpu(val);
 }
@@ -163,10 +179,14 @@ static inline u32 rtl818x_ioread32_idx(s
 {
 	__le32 val;
 
+	mutex_lock(&priv->io_mutex);
 	usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
 			RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
-			(unsigned long)addr, idx & 0x03, &val,
-			sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
+
+	val = priv->io_dmabuf->bits32;
+	mutex_unlock(&priv->io_mutex);
 
 	return le32_to_cpu(val);
 }
@@ -179,10 +199,15 @@ static inline u32 rtl818x_ioread32(struc
 static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
 					u8 *addr, u8 val, u8 idx)
 {
+	mutex_lock(&priv->io_mutex);
+
+	priv->io_dmabuf->bits8 = val;
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, idx & 0x03, &val,
-			sizeof(val), HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
+
+	mutex_unlock(&priv->io_mutex);
 }
 
 static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
@@ -193,12 +218,15 @@ static inline void rtl818x_iowrite8(stru
 static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
 					 __le16 *addr, u16 val, u8 idx)
 {
-	__le16 buf = cpu_to_le16(val);
+	mutex_lock(&priv->io_mutex);
 
+	priv->io_dmabuf->bits16 = cpu_to_le16(val);
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
-			HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
+
+	mutex_unlock(&priv->io_mutex);
 }
 
 static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
@@ -210,12 +238,15 @@ static inline void rtl818x_iowrite16(str
 static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
 					 __le32 *addr, u32 val, u8 idx)
 {
-	__le32 buf = cpu_to_le32(val);
+	mutex_lock(&priv->io_mutex);
 
+	priv->io_dmabuf->bits32 = cpu_to_le32(val);
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			(unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
-			HZ / 2);
+			(unsigned long)addr, idx & 0x03,
+			&priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
+
+	mutex_unlock(&priv->io_mutex);
 }
 
 static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c	2009-06-09 23:05:27.000000000 -0400
@@ -88,9 +88,15 @@ static void rtl8225_write_8051(struct ie
 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
 	udelay(10);
 
+	mutex_lock(&priv->io_mutex);
+
+	priv->io_dmabuf->bits16 = data;
 	usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
 			RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
-			addr, 0x8225, &data, sizeof(data), HZ / 2);
+			addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data),
+			HZ / 2);
+
+	mutex_unlock(&priv->io_mutex);
 
 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
 	udelay(10);
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/strip.c linux-libre-2.6.30-gnu1/drivers/net/wireless/strip.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/strip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/strip.c	2009-06-09 23:05:27.000000000 -0400
@@ -950,6 +950,7 @@ static struct strip *strip_get_idx(loff_
 }
 
 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;
@@ -973,6 +974,7 @@ static void *strip_seq_next(struct seq_f
 }
 
 static void strip_seq_stop(struct seq_file *seq, void *v)
+	__releases(RCU)
 {
 	rcu_read_unlock();
 }
@@ -1125,7 +1127,7 @@ static int strip_seq_show(struct seq_fil
 }
 
 
-static struct seq_operations strip_seq_ops = {
+static const struct seq_operations strip_seq_ops = {
 	.start = strip_seq_start,
 	.next  = strip_seq_next,
 	.stop  = strip_seq_stop,
@@ -2475,6 +2477,16 @@ static const struct header_ops strip_hea
 	.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
@@ -2501,18 +2513,8 @@ static void strip_dev_setup(struct net_d
 	dev->dev_addr[0] = 0;
 	dev->addr_len = sizeof(MetricomAddress);
 
-	/*
-	 * Pointers to interface service routines.
-	 */
-
-	dev->open = strip_open_low;
-	dev->stop = strip_close_low;
-	dev->hard_start_xmit = strip_xmit;
-	dev->header_ops = &strip_header_ops;
-
-	dev->set_mac_address = strip_set_mac_address;
-	dev->get_stats = strip_get_stats;
-	dev->change_mtu = strip_change_mtu;
+	dev->header_ops = &strip_header_ops,
+	dev->netdev_ops = &strip_netdev_ops;
 }
 
 /*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan.c linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan.c	2009-06-09 23:05:27.000000000 -0400
@@ -40,11 +40,11 @@ static u8 wv_irq_to_psa(int irq)
  */
 static int __init wv_psa_to_irq(u8 irqval)
 {
-	int irq;
+	int i;
 
-	for (irq = 0; irq < ARRAY_SIZE(irqvals); irq++)
-		if (irqvals[irq] == irqval)
-			return irq;
+	for (i = 0; i < ARRAY_SIZE(irqvals); i++)
+		if (irqvals[i] == irqval)
+			return i;
 
 	return -1;
 }
@@ -735,9 +735,9 @@ if (lp->tx_n_in_use > 0)
 		if (tx_status & AC_SFLD_OK) {
 			int ncollisions;
 
-			lp->stats.tx_packets++;
+			dev->stats.tx_packets++;
 			ncollisions = tx_status & AC_SFLD_MAXCOL;
-			lp->stats.collisions += ncollisions;
+			dev->stats.collisions += ncollisions;
 #ifdef DEBUG_TX_INFO
 			if (ncollisions > 0)
 				printk(KERN_DEBUG
@@ -745,9 +745,9 @@ if (lp->tx_n_in_use > 0)
 				       dev->name, ncollisions);
 #endif
 		} else {
-			lp->stats.tx_errors++;
+			dev->stats.tx_errors++;
 			if (tx_status & AC_SFLD_S10) {
-				lp->stats.tx_carrier_errors++;
+				dev->stats.tx_carrier_errors++;
 #ifdef DEBUG_TX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_complete(): tx error: no CS.\n",
@@ -755,7 +755,7 @@ if (lp->tx_n_in_use > 0)
 #endif
 			}
 			if (tx_status & AC_SFLD_S9) {
-				lp->stats.tx_carrier_errors++;
+				dev->stats.tx_carrier_errors++;
 #ifdef DEBUG_TX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_complete(): tx error: lost CTS.\n",
@@ -763,7 +763,7 @@ if (lp->tx_n_in_use > 0)
 #endif
 			}
 			if (tx_status & AC_SFLD_S8) {
-				lp->stats.tx_fifo_errors++;
+				dev->stats.tx_fifo_errors++;
 #ifdef DEBUG_TX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_complete(): tx error: slow DMA.\n",
@@ -771,7 +771,7 @@ if (lp->tx_n_in_use > 0)
 #endif
 			}
 			if (tx_status & AC_SFLD_S6) {
-				lp->stats.tx_heartbeat_errors++;
+				dev->stats.tx_heartbeat_errors++;
 #ifdef DEBUG_TX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_complete(): tx error: heart beat.\n",
@@ -779,7 +779,7 @@ if (lp->tx_n_in_use > 0)
 #endif
 			}
 			if (tx_status & AC_SFLD_S5) {
-				lp->stats.tx_aborted_errors++;
+				dev->stats.tx_aborted_errors++;
 #ifdef DEBUG_TX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_complete(): tx error: too many collisions.\n",
@@ -1346,20 +1346,6 @@ static void wv_init_info(struct net_devi
  * or wireless extensions
  */
 
-/*------------------------------------------------------------------*/
-/*
- * Get the current Ethernet statistics. This may be called with the
- * card open or closed.
- * Used when the user read /proc/net/dev
- */
-static en_stats *wavelan_get_stats(struct net_device * dev)
-{
-#ifdef DEBUG_IOCTL_TRACE
-	printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
-#endif
-
-	return &((net_local *)netdev_priv(dev))->stats;
-}
 
 /*------------------------------------------------------------------*/
 /*
@@ -2466,7 +2452,7 @@ wv_packet_read(struct net_device * dev,
 		       "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n",
 		       dev->name, sksize);
 #endif
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 
@@ -2526,8 +2512,8 @@ wv_packet_read(struct net_device * dev,
 	netif_rx(skb);
 
 	/* Keep statistics up to date */
-	lp->stats.rx_packets++;
-	lp->stats.rx_bytes += sksize;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += sksize;
 
 #ifdef DEBUG_RX_TRACE
 	printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2608,7 +2594,7 @@ static void wv_receive(struct net_device
 #endif
 		} else {	/* If reception was no successful */
 
-			lp->stats.rx_errors++;
+			dev->stats.rx_errors++;
 
 #ifdef DEBUG_RX_INFO
 			printk(KERN_DEBUG
@@ -2624,7 +2610,7 @@ static void wv_receive(struct net_device
 #endif
 
 			if ((fd.fd_status & FD_STATUS_S7) != 0) {
-				lp->stats.rx_length_errors++;
+				dev->stats.rx_length_errors++;
 #ifdef DEBUG_RX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_receive(): frame too short.\n",
@@ -2633,7 +2619,7 @@ static void wv_receive(struct net_device
 			}
 
 			if ((fd.fd_status & FD_STATUS_S8) != 0) {
-				lp->stats.rx_over_errors++;
+				dev->stats.rx_over_errors++;
 #ifdef DEBUG_RX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_receive(): rx DMA overrun.\n",
@@ -2642,7 +2628,7 @@ static void wv_receive(struct net_device
 			}
 
 			if ((fd.fd_status & FD_STATUS_S9) != 0) {
-				lp->stats.rx_fifo_errors++;
+				dev->stats.rx_fifo_errors++;
 #ifdef DEBUG_RX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_receive(): ran out of resources.\n",
@@ -2651,7 +2637,7 @@ static void wv_receive(struct net_device
 			}
 
 			if ((fd.fd_status & FD_STATUS_S10) != 0) {
-				lp->stats.rx_frame_errors++;
+				dev->stats.rx_frame_errors++;
 #ifdef DEBUG_RX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_receive(): alignment error.\n",
@@ -2660,7 +2646,7 @@ static void wv_receive(struct net_device
 			}
 
 			if ((fd.fd_status & FD_STATUS_S11) != 0) {
-				lp->stats.rx_crc_errors++;
+				dev->stats.rx_crc_errors++;
 #ifdef DEBUG_RX_FAIL
 				printk(KERN_DEBUG
 				       "%s: wv_receive(): CRC error.\n",
@@ -2826,7 +2812,7 @@ static int wv_packet_write(struct net_de
 	dev->trans_start = jiffies;
 
 	/* Keep stats up to date. */
-	lp->stats.tx_bytes += length;
+	dev->stats.tx_bytes += length;
 
 	if (lp->tx_first_in_use == I82586NULL)
 		lp->tx_first_in_use = txblock;
@@ -4038,6 +4024,22 @@ static int wavelan_close(struct net_devi
 	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
@@ -4130,17 +4132,8 @@ static int __init wavelan_config(struct
 	/* Init spinlock */
 	spin_lock_init(&lp->spinlock);
 
-	dev->open = wavelan_open;
-	dev->stop = wavelan_close;
-	dev->hard_start_xmit = wavelan_packet_xmit;
-	dev->get_stats = wavelan_get_stats;
-	dev->set_multicast_list = &wavelan_set_multicast_list;
-        dev->tx_timeout		= &wavelan_watchdog;
-        dev->watchdog_timeo	= WATCHDOG_JIFFIES;
-#ifdef SET_MAC_ADDRESS
-	dev->set_mac_address = &wavelan_set_mac_address;
-#endif				/* SET_MAC_ADDRESS */
-
+	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;
@@ -4281,8 +4274,7 @@ int __init init_module(void)
 
 
 	/* Loop on all possible base addresses. */
-	i = -1;
-	while ((io[++i] != 0) && (i < ARRAY_SIZE(io))) {
+	for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) {
 		struct net_device *dev = alloc_etherdev(sizeof(net_local));
 		if (!dev)
 			break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -838,9 +838,8 @@ wv_82593_cmd(struct net_device *	dev,
     }
   while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
 
-  /* If the interrupt hasn't be posted */
-  if(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);
@@ -1353,21 +1352,6 @@ wv_init_info(struct net_device *	dev)
  * or wireless extensions
  */
 
-/*------------------------------------------------------------------*/
-/*
- * Get the current ethernet statistics. This may be called with the
- * card open or closed.
- * Used when the user read /proc/net/dev
- */
-static en_stats	*
-wavelan_get_stats(struct net_device *	dev)
-{
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
-#endif
-
-  return(&((net_local *)netdev_priv(dev))->stats);
-}
 
 /*------------------------------------------------------------------*/
 /*
@@ -2818,7 +2802,7 @@ wv_packet_read(struct net_device *		dev,
       printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
 	     dev->name, sksize);
 #endif
-      lp->stats.rx_dropped++;
+      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.
@@ -2878,8 +2862,8 @@ wv_packet_read(struct net_device *		dev,
   netif_rx(skb);
 
   /* Keep stats up to date */
-  lp->stats.rx_packets++;
-  lp->stats.rx_bytes += sksize;
+  dev->stats.rx_packets++;
+  dev->stats.rx_bytes += sksize;
 
 #ifdef DEBUG_RX_TRACE
   printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2981,13 +2965,13 @@ wv_packet_rcv(struct net_device *	dev)
       /* Check status */
       if((status & RX_RCV_OK) != RX_RCV_OK)
 	{
-	  lp->stats.rx_errors++;
+	  dev->stats.rx_errors++;
 	  if(status & RX_NO_SFD)
-	    lp->stats.rx_frame_errors++;
+	    dev->stats.rx_frame_errors++;
 	  if(status & RX_CRC_ERR)
-	    lp->stats.rx_crc_errors++;
+	    dev->stats.rx_crc_errors++;
 	  if(status & RX_OVRRUN)
-	    lp->stats.rx_over_errors++;
+	    dev->stats.rx_over_errors++;
 
 #ifdef DEBUG_RX_FAIL
 	  printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
@@ -3074,7 +3058,7 @@ wv_packet_write(struct net_device *	dev,
   dev->trans_start = jiffies;
 
   /* Keep stats up to date */
-  lp->stats.tx_bytes += length;
+  dev->stats.tx_bytes += length;
 
   spin_unlock_irqrestore(&lp->spinlock, flags);
 
@@ -4107,7 +4091,7 @@ wavelan_interrupt(int		irq,
 	      printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
 		     dev->name);
 #endif
-	      lp->stats.rx_over_errors++;
+	      dev->stats.rx_over_errors++;
 	      lp->overrunning = 1;
       	    }
 
@@ -4156,7 +4140,7 @@ wavelan_interrupt(int		irq,
 	  /* Check for possible errors */
 	  if((tx_status & TX_OK) != TX_OK)
 	    {
-	      lp->stats.tx_errors++;
+	      dev->stats.tx_errors++;
 
 	      if(tx_status & TX_FRTL)
 		{
@@ -4171,14 +4155,14 @@ wavelan_interrupt(int		irq,
 		  printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
 			 dev->name);
 #endif
-		  lp->stats.tx_aborted_errors++;
+		  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
-		  lp->stats.tx_carrier_errors++;
+		  dev->stats.tx_carrier_errors++;
 		}
 	      if(tx_status & TX_LOST_CRS)
 		{
@@ -4186,14 +4170,14 @@ wavelan_interrupt(int		irq,
 		  printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
 			 dev->name);
 #endif
-		  lp->stats.tx_carrier_errors++;
+		  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
-		  lp->stats.tx_heartbeat_errors++;
+		  dev->stats.tx_heartbeat_errors++;
 		}
 	      if(tx_status & TX_DEFER)
 		{
@@ -4217,14 +4201,14 @@ wavelan_interrupt(int		irq,
 #endif
 		      if(!(tx_status & TX_NCOL_MASK))
 			{
-			  lp->stats.collisions += 0x10;
+			  dev->stats.collisions += 0x10;
 			}
 		    }
 		}
 	    }	/* if(!(tx_status & TX_OK)) */
 
-	  lp->stats.collisions += (tx_status & TX_NCOL_MASK);
-	  lp->stats.tx_packets++;
+	  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 */
@@ -4452,6 +4436,19 @@ wavelan_close(struct net_device *	dev)
   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
@@ -4512,17 +4509,7 @@ wavelan_probe(struct pcmcia_device *p_de
   lp->dev = dev;
 
   /* wavelan NET3 callbacks */
-  dev->open = &wavelan_open;
-  dev->stop = &wavelan_close;
-  dev->hard_start_xmit = &wavelan_packet_xmit;
-  dev->get_stats = &wavelan_get_stats;
-  dev->set_multicast_list = &wavelan_set_multicast_list;
-#ifdef SET_MAC_ADDRESS
-  dev->set_mac_address = &wavelan_set_mac_address;
-#endif	/* SET_MAC_ADDRESS */
-
-  /* Set the watchdog timer */
-  dev->tx_timeout	= &wavelan_watchdog;
+  dev->netdev_ops = &wavelan_netdev_ops;
   dev->watchdog_timeo	= WATCHDOG_JIFFIES;
   SET_ETHTOOL_OPS(dev, &ops);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan_cs.p.h linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan_cs.p.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan_cs.p.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan_cs.p.h	2009-06-09 23:05:27.000000000 -0400
@@ -576,7 +576,6 @@ struct wavepoint_table
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
-typedef struct net_device_stats	en_stats;
 typedef struct iw_statistics	iw_stats;
 typedef struct iw_quality	iw_qual;
 typedef struct iw_freq		iw_freq;
@@ -592,8 +591,6 @@ typedef u_char		mac_addr[WAVELAN_ADDR_SI
  * 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.
- * Note that some of this specific data is in fact generic (en_stats, for
- * example).
  */
 struct net_local
 {
@@ -601,7 +598,6 @@ struct net_local
   struct net_device *	dev;		/* Reverse link... */
   spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
   struct pcmcia_device *	link;		/* pcmcia structure */
-  en_stats	stats;		/* Ethernet interface statistics */
   int		nresets;	/* Number of hw resets */
   u_char	configured;	/* If it is configured */
   u_char	reconfig_82593;	/* Need to reconfigure the controller */
@@ -694,8 +690,6 @@ static void
 static void
 	wv_init_info(struct net_device *);	/* display startup info */
 /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static en_stats	*
-	wavelan_get_stats(struct net_device *);	/* Give stats /proc/net/dev */
 static iw_stats *
 	wavelan_get_wireless_stats(struct net_device *);
 /* ----------------------- PACKET RECEPTION ----------------------- */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan.p.h linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan.p.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wavelan.p.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wavelan.p.h	2009-06-09 23:05:27.000000000 -0400
@@ -459,11 +459,9 @@ static const char	*version	= "wavelan.c
 /****************************** TYPES ******************************/
 
 /* Shortcuts */
-typedef struct net_device_stats	en_stats;
 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 iw_freq		iw_freq;typedef struct net_local	net_local;
 typedef struct timer_list	timer_list;
 
 /* Basic types */
@@ -475,15 +473,12 @@ typedef u_char		mac_addr[WAVELAN_ADDR_SI
  * 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.
- * Note that some of this specific data is in fact generic (en_stats, for
- * example).
  */
 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) */
-  en_stats	stats;		/* Ethernet interface statistics */
   int		nresets;	/* number of hardware resets */
   u_char	reconfig_82586;	/* We need to reconfigure the controller. */
   u_char	promiscuous;	/* promiscuous mode */
@@ -601,8 +596,6 @@ static void
 static inline void
 	wv_init_info(struct net_device *);	/* display startup info */
 /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static en_stats	*
-	wavelan_get_stats(struct net_device *);	/* Give stats /proc/net/dev */
 static iw_stats *
 	wavelan_get_wireless_stats(struct net_device *);
 static void
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wl3501_cs.c linux-libre-2.6.30-gnu1/drivers/net/wireless/wl3501_cs.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wl3501_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wl3501_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
 
 #include <net/iw_handler.h>
 
@@ -111,12 +112,6 @@ static void wl3501_release(struct pcmcia
  */
 static dev_info_t wl3501_dev_info = "wl3501_cs";
 
-static int wl3501_chan2freq[] = {
-	[0]  = 2412, [1]  = 2417, [2]  = 2422, [3]  = 2427, [4] = 2432,
-	[5]  = 2437, [6]  = 2442, [7]  = 2447, [8]  = 2452, [9] = 2457,
-	[10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477,
-};
-
 static const struct {
 	int reg_domain;
 	int min, max, deflt;
@@ -1005,7 +1000,7 @@ static inline void wl3501_md_ind_interru
 	if (!skb) {
 		printk(KERN_WARNING "%s: Can't alloc a sk_buff of size %d.\n",
 		       dev->name, pkt_len);
-		this->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 	} else {
 		skb->dev = dev;
 		skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
@@ -1013,8 +1008,8 @@ static inline void wl3501_md_ind_interru
 		wl3501_receive(this, skb->data, pkt_len);
 		skb_put(skb, pkt_len);
 		skb->protocol	= eth_type_trans(skb, dev);
-		this->stats.rx_packets++;
-		this->stats.rx_bytes += skb->len;
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += skb->len;
 		netif_rx(skb);
 	}
 }
@@ -1316,7 +1311,7 @@ out:
 static void wl3501_tx_timeout(struct net_device *dev)
 {
 	struct wl3501_card *this = netdev_priv(dev);
-	struct net_device_stats *stats = &this->stats;
+	struct net_device_stats *stats = &dev->stats;
 	unsigned long flags;
 	int rc;
 
@@ -1351,11 +1346,11 @@ static int wl3501_hard_start_xmit(struct
 	if (enabled)
 		wl3501_unblock_interrupt(this);
 	if (rc) {
-		++this->stats.tx_dropped;
+		++dev->stats.tx_dropped;
 		netif_stop_queue(dev);
 	} else {
-		++this->stats.tx_packets;
-		this->stats.tx_bytes += skb->len;
+		++dev->stats.tx_packets;
+		dev->stats.tx_bytes += skb->len;
 		kfree_skb(skb);
 
 		if (this->tx_buffer_cnt < 2)
@@ -1405,13 +1400,6 @@ fail:
 	goto out;
 }
 
-static struct net_device_stats *wl3501_get_stats(struct net_device *dev)
-{
-	struct wl3501_card *this = netdev_priv(dev);
-
-	return &this->stats;
-}
-
 static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
 {
 	struct wl3501_card *this = netdev_priv(dev);
@@ -1510,7 +1498,7 @@ static int wl3501_get_freq(struct net_de
 {
 	struct wl3501_card *this = netdev_priv(dev);
 
-	wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000;
+	wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000;
 	wrqu->freq.e = 1;
 	return 0;
 }
@@ -1895,6 +1883,16 @@ static const struct iw_handler_def wl350
 	.get_wireless_stats = wl3501_get_wireless_stats,
 };
 
+static const struct net_device_ops wl3501_netdev_ops = {
+	.ndo_open		= wl3501_open,
+	.ndo_stop		= wl3501_close,
+	.ndo_start_xmit		= wl3501_hard_start_xmit,
+	.ndo_tx_timeout		= wl3501_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /**
  * wl3501_attach - creates an "instance" of the driver
  *
@@ -1927,17 +1925,16 @@ static int wl3501_probe(struct pcmcia_de
 	dev = alloc_etherdev(sizeof(struct wl3501_card));
 	if (!dev)
 		goto out_link;
-	dev->open		= wl3501_open;
-	dev->stop		= wl3501_close;
-	dev->hard_start_xmit	= wl3501_hard_start_xmit;
-	dev->tx_timeout		= wl3501_tx_timeout;
+
+
+	dev->netdev_ops		= &wl3501_netdev_ops;
 	dev->watchdog_timeo	= 5 * HZ;
-	dev->get_stats		= wl3501_get_stats;
+
 	this = netdev_priv(dev);
 	this->wireless_data.spy_data = &this->spy_data;
 	this->p_dev = p_dev;
 	dev->wireless_data	= &this->wireless_data;
-	dev->wireless_handlers	= (struct iw_handler_def *)&wl3501_handler_def;
+	dev->wireless_handlers	= &wl3501_handler_def;
 	SET_ETHTOOL_OPS(dev, &ops);
 	netif_stop_queue(dev);
 	p_dev->priv = p_dev->irq.Instance = dev;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/wl3501.h linux-libre-2.6.30-gnu1/drivers/net/wireless/wl3501.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/wl3501.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/wl3501.h	2009-06-09 23:05:27.000000000 -0400
@@ -606,7 +606,7 @@ struct wl3501_card {
 	u8				reg_domain;
 	u8				version[2];
 	struct wl3501_scan_confirm	bss_set[20];
-	struct net_device_stats 	stats;
+
 	struct iw_statistics		wstats;
 	struct iw_spy_data		spy_data;
 	struct iw_public_data		wireless_data;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1201.c linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1201.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 18:05:13.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1201.c	2013-05-03 16:49:13.000000000 -0400
@@ -328,8 +328,8 @@ static void zd1201_usbrx(struct urb *urb
 			memcpy(skb_put(skb, 2), &data[datalen-24], 2);
 			memcpy(skb_put(skb, len), data, len);
 			skb->protocol = eth_type_trans(skb, zd->dev);
-			zd->stats.rx_packets++;
-			zd->stats.rx_bytes += skb->len;
+			zd->dev->stats.rx_packets++;
+			zd->dev->stats.rx_bytes += skb->len;
 			netif_rx(skb);
 			goto resubmit;
 		}
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb
 			memcpy(skb_put(skb, len), data+8, len);
 		}
 		skb->protocol = eth_type_trans(skb, zd->dev);
-		zd->stats.rx_packets++;
-		zd->stats.rx_bytes += skb->len;
+		zd->dev->stats.rx_packets++;
+		zd->dev->stats.rx_bytes += skb->len;
 		netif_rx(skb);
 	}
 resubmit:
@@ -787,7 +787,7 @@ static int zd1201_hard_start_xmit(struct
 	struct urb *urb = zd->tx_urb;
 
 	if (!zd->mac_enabled || zd->monitor) {
-		zd->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		kfree_skb(skb);
 		return 0;
 	}
@@ -817,12 +817,12 @@ static int zd1201_hard_start_xmit(struct
 
 	err = usb_submit_urb(zd->tx_urb, GFP_ATOMIC);
 	if (err) {
-		zd->stats.tx_errors++;
+		dev->stats.tx_errors++;
 		netif_start_queue(dev);
 		return err;
 	}
-	zd->stats.tx_packets++;
-	zd->stats.tx_bytes += skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
 	kfree_skb(skb);
 
@@ -838,7 +838,7 @@ static void zd1201_tx_timeout(struct net
 	dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
 	    dev->name);
 	usb_unlink_urb(zd->tx_urb);
-	zd->stats.tx_errors++;
+	dev->stats.tx_errors++;
 	/* Restart the timeout to quiet the watchdog: */
 	dev->trans_start = jiffies;
 }
@@ -861,13 +861,6 @@ static int zd1201_set_mac_address(struct
 	return zd1201_mac_reset(zd);
 }
 
-static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
-{
-	struct zd1201 *zd = netdev_priv(dev);
-
-	return &zd->stats;
-}
-
 static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
 {
 	struct zd1201 *zd = netdev_priv(dev);
@@ -919,10 +912,9 @@ static int zd1201_set_freq(struct net_de
 	if (freq->e == 0)
 		channel = freq->m;
 	else {
-		if (freq->m >= 2482)
-			channel = 14;
-		if (freq->m >= 2407)
-			channel = (freq->m-2407)/5;
+		channel = ieee80211_freq_to_dsss_chan(freq->m);
+		if (channel < 0)
+			channel = 0;
 	}
 
 	err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
@@ -1725,6 +1717,17 @@ static const struct iw_handler_def zd120
 	.get_wireless_stats	= zd1201_get_wireless_stats,
 };
 
+static const struct net_device_ops zd1201_netdev_ops = {
+	.ndo_open		= zd1201_net_open,
+	.ndo_stop		= zd1201_net_stop,
+	.ndo_start_xmit		= zd1201_hard_start_xmit,
+	.ndo_tx_timeout		= zd1201_tx_timeout,
+	.ndo_set_multicast_list = zd1201_set_multicast,
+	.ndo_set_mac_address	= zd1201_set_mac_address,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 static int zd1201_probe(struct usb_interface *interface,
 			const struct usb_device_id *id)
 {
@@ -1777,16 +1780,9 @@ static int zd1201_probe(struct usb_inter
 	if (err)
 		goto err_start;
 
-	dev->open = zd1201_net_open;
-	dev->stop = zd1201_net_stop;
-	dev->get_stats = zd1201_get_stats;
-	dev->wireless_handlers =
-	    (struct iw_handler_def *)&zd1201_iw_handlers;
-	dev->hard_start_xmit = zd1201_hard_start_xmit;
+	dev->netdev_ops = &zd1201_netdev_ops;
+	dev->wireless_handlers = &zd1201_iw_handlers;
 	dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
-	dev->tx_timeout = zd1201_tx_timeout;
-	dev->set_multicast_list = zd1201_set_multicast;
-	dev->set_mac_address = zd1201_set_mac_address;
 	strcpy(dev->name, "wlan%d");
 
 	err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR, 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1201.h linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1201.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1201.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1201.h	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@ struct zd1201 {
 	struct usb_device	*usb;
 	int			removed;
 	struct net_device	*dev;
-	struct net_device_stats stats;
 	struct iw_statistics	iwstats;
 
 	int			endp_in;
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_chip.c	2009-06-09 23:05:27.000000000 -0400
@@ -1616,3 +1616,24 @@ int zd_chip_set_multicast_hash(struct zd
 
 	return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
 }
+
+u64 zd_chip_get_tsf(struct zd_chip *chip)
+{
+	int r;
+	static const zd_addr_t aw_pt_bi_addr[] =
+		{ CR_TSF_LOW_PART, CR_TSF_HIGH_PART };
+	u32 values[2];
+	u64 tsf;
+
+	mutex_lock(&chip->mutex);
+	r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
+	                        ARRAY_SIZE(aw_pt_bi_addr));
+	mutex_unlock(&chip->mutex);
+	if (r)
+		return 0;
+
+	tsf = values[1];
+	tsf = (tsf << 32) | values[0];
+
+	return tsf;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_chip.h	2009-06-09 23:05:27.000000000 -0400
@@ -950,4 +950,6 @@ static inline void zd_mc_add_addr(struct
 int zd_chip_set_multicast_hash(struct zd_chip *chip,
 	                       struct zd_mc_hash *hash);
 
+u64 zd_chip_get_tsf(struct zd_chip *chip);
+
 #endif /* _ZD_CHIP_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_def.h linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_def.h
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_def.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_def.h	2009-06-09 23:05:27.000000000 -0400
@@ -33,8 +33,13 @@ typedef u16 __nocast zd_addr_t;
 #ifdef DEBUG
 #  define dev_dbg_f(dev, fmt, args...) \
 	  dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
+#  define dev_dbg_f_limit(dev, fmt, args...) do { \
+	if (net_ratelimit()) \
+		dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
+} while (0)
 #else
 #  define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
+#  define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
 #endif /* DEBUG */
 
 #ifdef DEBUG
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c
--- linux-libre-2.6.29-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/wireless/zd1211rw/zd_mac.c	2009-06-09 23:05:27.000000000 -0400
@@ -170,10 +170,10 @@ int zd_mac_init_hw(struct ieee80211_hw *
 		goto disable_int;
 
 	r = zd_reg2alpha2(mac->regdomain, alpha2);
-	if (!r)
-		regulatory_hint(hw->wiphy, alpha2);
+	if (r)
+		goto disable_int;
 
-	r = 0;
+	r = regulatory_hint(hw->wiphy, alpha2);
 disable_int:
 	zd_chip_disable_int(chip);
 out:
@@ -772,13 +772,23 @@ static int zd_op_config_interface(struct
 			if (!beacon)
 				return -ENOMEM;
 			r = zd_mac_config_beacon(hw, beacon);
+			kfree_skb(beacon);
+
 			if (r < 0)
 				return r;
-			r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
-					hw->conf.beacon_int);
+		}
+
+		if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
+			u32 interval;
+
+			if (conf->enable_beacon)
+				interval = BCN_MODE_IBSS | hw->conf.beacon_int;
+			else
+				interval = 0;
+
+			r = zd_set_beacon_interval(&mac->chip, interval);
 			if (r < 0)
 				return r;
-			kfree_skb(beacon);
 		}
 	} else
 		associated = is_valid_ether_addr(conf->bssid);
@@ -797,10 +807,9 @@ static void zd_process_intr(struct work_
 	struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
 
 	int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
-	if (int_status & INT_CFG_NEXT_BCN) {
-		if (net_ratelimit())
-			dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
-	} else
+	if (int_status & INT_CFG_NEXT_BCN)
+		dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
+	else
 		dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
 
 	zd_chip_enable_hwint(&mac->chip);
@@ -930,6 +939,12 @@ static void zd_op_bss_info_changed(struc
 	}
 }
 
+static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
+{
+	struct zd_mac *mac = zd_hw_mac(hw);
+	return zd_chip_get_tsf(&mac->chip);
+}
+
 static const struct ieee80211_ops zd_ops = {
 	.tx			= zd_op_tx,
 	.start			= zd_op_start,
@@ -940,6 +955,7 @@ static const struct ieee80211_ops zd_ops
 	.config_interface	= zd_op_config_interface,
 	.configure_filter	= zd_op_configure_filter,
 	.bss_info_changed	= zd_op_bss_info_changed,
+	.get_tsf		= zd_op_get_tsf,
 };
 
 struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
@@ -971,7 +987,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(str
 	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
 
 	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-		    IEEE80211_HW_SIGNAL_DB;
+		    IEEE80211_HW_SIGNAL_UNSPEC;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_MESH_POINT) |
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/xen-netfront.c linux-libre-2.6.30-gnu1/drivers/net/xen-netfront.c
--- linux-libre-2.6.29-gnu1/drivers/net/xen-netfront.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/xen-netfront.c	2009-06-09 23:05:27.000000000 -0400
@@ -196,7 +196,7 @@ static void rx_refill_timeout(unsigned l
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct netfront_info *np = netdev_priv(dev);
-	netif_rx_schedule(&np->napi);
+	napi_schedule(&np->napi);
 }
 
 static int netfront_tx_slot_available(struct netfront_info *np)
@@ -328,7 +328,7 @@ static int xennet_open(struct net_device
 		xennet_alloc_rx_buffers(dev);
 		np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
 		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-			netif_rx_schedule(&np->napi);
+			napi_schedule(&np->napi);
 	}
 	spin_unlock_bh(&np->rx_lock);
 
@@ -979,7 +979,7 @@ err:
 
 		RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
 		if (!more_to_do)
-			__netif_rx_complete(napi);
+			__napi_complete(napi);
 
 		local_irq_restore(flags);
 	}
@@ -1317,7 +1317,7 @@ static irqreturn_t xennet_interrupt(int
 		xennet_tx_buf_gc(dev);
 		/* Under tx_lock: protects access to rx shared-ring indexes. */
 		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-			netif_rx_schedule(&np->napi);
+			napi_schedule(&np->napi);
 	}
 
 	spin_unlock_irqrestore(&np->tx_lock, flags);
@@ -1511,7 +1511,7 @@ static int xennet_set_tso(struct net_dev
 static void xennet_set_features(struct net_device *dev)
 {
 	/* Turn off all GSO bits except ROBUST. */
-	dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
+	dev->features &= ~NETIF_F_GSO_MASK;
 	dev->features |= NETIF_F_GSO_ROBUST;
 	xennet_set_sg(dev, 0);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/xtsonic.c linux-libre-2.6.30-gnu1/drivers/net/xtsonic.c
--- linux-libre-2.6.29-gnu1/drivers/net/xtsonic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/xtsonic.c	2009-06-09 23:05:27.000000000 -0400
@@ -108,6 +108,18 @@ static int xtsonic_close(struct net_devi
 	return err;
 }
 
+static const struct net_device_ops xtsonic_netdev_ops = {
+	.ndo_open		= xtsonic_open,
+	.ndo_stop		= xtsonic_close,
+	.ndo_start_xmit		= sonic_send_packet,
+	.ndo_get_stats		= sonic_get_stats,
+	.ndo_set_multicast_list	= sonic_multicast_list,
+	.ndo_tx_timeout		= sonic_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
 static int __init sonic_probe1(struct net_device *dev)
 {
 	static unsigned version_printed = 0;
@@ -183,7 +195,7 @@ static int __init sonic_probe1(struct ne
 
 	if (lp->descriptors == NULL) {
 		printk(KERN_ERR "%s: couldn't alloc DMA memory for "
-				" descriptors.\n", lp->device->bus_id);
+				" descriptors.\n", dev_name(lp->device));
 		goto out;
 	}
 
@@ -205,12 +217,7 @@ static int __init sonic_probe1(struct ne
 	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 					 * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-	dev->open = xtsonic_open;
-	dev->stop = xtsonic_close;
-	dev->hard_start_xmit	= sonic_send_packet;
-	dev->get_stats		= sonic_get_stats;
-	dev->set_multicast_list	= &sonic_multicast_list;
-	dev->tx_timeout		= sonic_tx_timeout;
+	dev->netdev_ops		= &xtsonic_netdev_ops;
 	dev->watchdog_timeo	= TX_TIMEOUT;
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/yellowfin.c linux-libre-2.6.30-gnu1/drivers/net/yellowfin.c
--- linux-libre-2.6.29-gnu1/drivers/net/yellowfin.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/yellowfin.c	2009-06-09 23:05:27.000000000 -0400
@@ -107,9 +107,9 @@ static int gx_fix;
 #include <asm/io.h>
 
 /* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.05  1/09/2001  Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO "  (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
+static const char version[] __devinitconst =
+  KERN_INFO DRV_NAME ".c:v1.05  1/09/2001  Written by Donald Becker <becker@scyld.com>\n"
+  KERN_INFO "  (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/net/znet.c linux-libre-2.6.30-gnu1/drivers/net/znet.c
--- linux-libre-2.6.29-gnu1/drivers/net/znet.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/net/znet.c	2009-06-09 23:05:27.000000000 -0400
@@ -358,6 +358,17 @@ static void znet_set_multicast_list (str
 	 * multicast address configured isn't equal to IFF_ALLMULTI */
 }
 
+static const struct net_device_ops znet_netdev_ops = {
+	.ndo_open		= znet_open,
+	.ndo_stop		= znet_close,
+	.ndo_start_xmit		= znet_send_packet,
+	.ndo_set_multicast_list = znet_set_multicast_list,
+	.ndo_tx_timeout		= znet_tx_timeout,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
 /* The Z-Note probe is pretty easy.  The NETIDBLK exists in the safe-to-probe
    BIOS area.  We just scan for the signature, and pull the vital parameters
    out of the structure. */
@@ -440,11 +451,7 @@ static int __init znet_probe (void)
 	znet->tx_end = znet->tx_start + znet->tx_buf_len;
 
 	/* The ZNET-specific entries in the device structure. */
-	dev->open = &znet_open;
-	dev->hard_start_xmit = &znet_send_packet;
-	dev->stop = &znet_close;
-	dev->set_multicast_list = &znet_set_multicast_list;
-	dev->tx_timeout = znet_tx_timeout;
+	dev->netdev_ops = &znet_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	err = register_netdev(dev);
 	if (err)
diff -druNp linux-libre-2.6.29-gnu1/drivers/of/base.c linux-libre-2.6.30-gnu1/drivers/of/base.c
--- linux-libre-2.6.29-gnu1/drivers/of/base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/of/base.c	2009-06-09 23:05:27.000000000 -0400
@@ -446,6 +446,7 @@ struct of_modalias_table {
 };
 static struct of_modalias_table of_modalias_table[] = {
 	{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
+	{ "mmc-spi-slot", "mmc_spi" },
 };
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/oprofile/buffer_sync.c linux-libre-2.6.30-gnu1/drivers/oprofile/buffer_sync.c
--- linux-libre-2.6.29-gnu1/drivers/oprofile/buffer_sync.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/oprofile/buffer_sync.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@
 
 static LIST_HEAD(dying_tasks);
 static LIST_HEAD(dead_tasks);
-static cpumask_t marked_cpus = CPU_MASK_NONE;
+static cpumask_var_t marked_cpus;
 static DEFINE_SPINLOCK(task_mortuary);
 static void process_task_mortuary(void);
 
@@ -154,6 +154,10 @@ int sync_start(void)
 {
 	int err;
 
+	if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+		return -ENOMEM;
+	cpumask_clear(marked_cpus);
+
 	start_cpu_work();
 
 	err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@ out2:
 	task_handoff_unregister(&task_free_nb);
 out1:
 	end_sync();
+	free_cpumask_var(marked_cpus);
 	goto out;
 }
 
@@ -190,6 +195,7 @@ void sync_stop(void)
 	profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
 	task_handoff_unregister(&task_free_nb);
 	end_sync();
+	free_cpumask_var(marked_cpus);
 }
 
 
@@ -456,10 +462,10 @@ static void mark_done(int cpu)
 {
 	int i;
 
-	cpu_set(cpu, marked_cpus);
+	cpumask_set_cpu(cpu, marked_cpus);
 
 	for_each_online_cpu(i) {
-		if (!cpu_isset(i, marked_cpus))
+		if (!cpumask_test_cpu(i, marked_cpus))
 			return;
 	}
 
@@ -468,7 +474,7 @@ static void mark_done(int cpu)
 	 */
 	process_task_mortuary();
 
-	cpus_clear(marked_cpus);
+	cpumask_clear(marked_cpus);
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/oprofile/cpu_buffer.c linux-libre-2.6.30-gnu1/drivers/oprofile/cpu_buffer.c
--- linux-libre-2.6.29-gnu1/drivers/oprofile/cpu_buffer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/oprofile/cpu_buffer.c	2009-06-09 23:05:27.000000000 -0400
@@ -78,16 +78,20 @@ void free_cpu_buffers(void)
 	op_ring_buffer_write = NULL;
 }
 
+#define RB_EVENT_HDR_SIZE 4
+
 int alloc_cpu_buffers(void)
 {
 	int i;
 
 	unsigned long buffer_size = oprofile_cpu_buffer_size;
+	unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
+						 RB_EVENT_HDR_SIZE);
 
-	op_ring_buffer_read = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+	op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
 	if (!op_ring_buffer_read)
 		goto fail;
-	op_ring_buffer_write = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+	op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
 	if (!op_ring_buffer_write)
 		goto fail;
 
@@ -161,7 +165,7 @@ struct op_sample
 {
 	entry->event = ring_buffer_lock_reserve
 		(op_ring_buffer_write, sizeof(struct op_sample) +
-		 size * sizeof(entry->sample->data[0]), &entry->irq_flags);
+		 size * sizeof(entry->sample->data[0]));
 	if (entry->event)
 		entry->sample = ring_buffer_event_data(entry->event);
 	else
@@ -178,8 +182,7 @@ struct op_sample
 
 int op_cpu_buffer_write_commit(struct op_entry *entry)
 {
-	return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event,
-					 entry->irq_flags);
+	return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
 }
 
 struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/asp.c linux-libre-2.6.30-gnu1/drivers/parisc/asp.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/asp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/asp.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,7 +81,7 @@ static int __init asp_init_chip(struct p
 	asp.hpa = ASP_INTERRUPT_ADDR;
 
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
-		asp.name, asp.version, dev->hpa.start);
+		asp.name, asp.version, (unsigned long)dev->hpa.start);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/ccio-dma.c linux-libre-2.6.30-gnu1/drivers/parisc/ccio-dma.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/ccio-dma.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/ccio-dma.c	2009-06-09 23:05:27.000000000 -0400
@@ -406,8 +406,6 @@ resource_found:
 	}
 	ioc->avg_search[ioc->avg_idx++] = cr_start;
 	ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_COLLECT_STATS
 	ioc->used_pages += pages_needed;
 #endif
 	/* 
@@ -453,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_add
 		unsigned long mask = ~(~0UL >> pages_mapped);
 		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
 #else
-		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
 #endif
 	} else if(pages_mapped <= 16) {
-		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
 	} else if(pages_mapped <= 32) {
 		CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
 #ifdef __LP64__
@@ -1028,8 +1026,10 @@ static int ccio_proc_info(struct seq_fil
 
 	while (ioc != NULL) {
 		unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
 		unsigned long avg = 0, min, max;
 		int j;
+#endif
 
 		len += seq_printf(m, "%s\n", ioc->name);
 		
@@ -1060,8 +1060,7 @@ static int ccio_proc_info(struct seq_fil
 		avg /= CCIO_SEARCH_SAMPLE;
 		len += seq_printf(m, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
 				  min, avg, max);
-#endif
-#ifdef CCIO_COLLECT_STATS
+
 		len += seq_printf(m, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
 				  ioc->msingle_calls, ioc->msingle_pages,
 				  (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1400,7 +1399,7 @@ ccio_init_resource(struct resource *res,
 	result = insert_resource(&iomem_resource, res);
 	if (result < 0) {
 		printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", 
-			__func__, res->start, res->end);
+			__func__, (unsigned long)res->start, (unsigned long)res->end);
 	}
 }
 
@@ -1551,7 +1550,8 @@ static int __init ccio_probe(struct pari
 
 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
-	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+		(unsigned long)dev->hpa.start);
 
 	for (i = 0; i < ioc_count; i++) {
 		ioc_p = &(*ioc_p)->next;
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/dino.c linux-libre-2.6.30-gnu1/drivers/parisc/dino.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/dino.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/dino.c	2009-06-09 23:05:27.000000000 -0400
@@ -819,7 +819,9 @@ dino_bridge_init(struct dino_device *din
 
 		result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
 		if (result < 0) {
-			printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+			printk(KERN_ERR "%s: failed to claim PCI Bus address "
+			       "space %d (0x%lx-0x%lx)!\n", name, i,
+			       (unsigned long)res[i].start, (unsigned long)res[i].end);
 			return result;
 		}
 	}
@@ -899,7 +901,8 @@ static int __init dino_common_init(struc
 	if (request_resource(&ioport_resource, res) < 0) {
 		printk(KERN_ERR "%s: request I/O Port region failed "
 		       "0x%lx/%lx (hpa 0x%p)\n",
-		       name, res->start, res->end, dino_dev->hba.base_addr);
+		       name, (unsigned long)res->start, (unsigned long)res->end,
+		       dino_dev->hba.base_addr);
 		return 1;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/eisa.c linux-libre-2.6.30-gnu1/drivers/parisc/eisa.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/eisa.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/eisa.c	2009-06-09 23:05:27.000000000 -0400
@@ -314,7 +314,7 @@ static int __init eisa_probe(struct pari
 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
 
 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
-		name, dev->hpa.start);
+		name, (unsigned long)dev->hpa.start);
 
 	eisa_dev.hba.dev = dev;
 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/eisa_enumerator.c linux-libre-2.6.30-gnu1/drivers/parisc/eisa_enumerator.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/eisa_enumerator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/eisa_enumerator.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,7 +98,7 @@ static int configure_memory(const unsign
 			res->start = mem_parent->start + get_24(buf+len+2);
 			res->end = res->start + get_16(buf+len+5)*1024;
 			res->flags = IORESOURCE_MEM;
-			printk("memory %lx-%lx ", res->start, res->end);
+			printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
 			result = request_resource(mem_parent, res);
 			if (result < 0) {
 				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -188,7 +188,7 @@ static int configure_port(const unsigned
 			res->start = get_16(buf+len+1);
 			res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
 			res->flags = IORESOURCE_IO;
-			printk("ioports %lx-%lx ", res->start, res->end);
+			printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
 			result = request_resource(io_parent, res);
 			if (result < 0) {
 				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/iosapic.c linux-libre-2.6.30-gnu1/drivers/parisc/iosapic.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/iosapic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/iosapic.c	2009-06-09 23:05:27.000000000 -0400
@@ -714,7 +714,7 @@ static void iosapic_set_affinity_irq(uns
 	if (dest_cpu < 0)
 		return;
 
-	irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+	cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
 	vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
 
 	spin_lock_irqsave(&iosapic_lock, flags);
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/led.c linux-libre-2.6.30-gnu1/drivers/parisc/led.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/led.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/led.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  *
  *      (c) Copyright 2000 Red Hat Software
  *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- *      (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ *      (c) Copyright 2001-2009 Helge Deller <deller@gmx.de>
  *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -243,13 +243,11 @@ static int __init led_create_procfs(void
 
 	proc_pdc_root = proc_mkdir("pdc", 0);
 	if (!proc_pdc_root) return -1;
-	proc_pdc_root->owner = THIS_MODULE;
 	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
 	if (!ent) return -1;
 	ent->data = (void *)LED_NOLCD; /* LED */
 	ent->read_proc = led_proc_read;
 	ent->write_proc = led_proc_write;
-	ent->owner = THIS_MODULE;
 
 	if (led_type == LED_HASLCD)
 	{
@@ -258,7 +256,6 @@ static int __init led_create_procfs(void
 		ent->data = (void *)LED_HASLCD; /* LCD */
 		ent->read_proc = led_proc_read;
 		ent->write_proc = led_proc_write;
-		ent->owner = THIS_MODULE;
 	}
 
 	return 0;
@@ -463,9 +460,20 @@ static void led_work_func (struct work_s
 	if (likely(led_lanrxtx))  currentleds |= led_get_net_activity();
 	if (likely(led_diskio))   currentleds |= led_get_diskio_activity();
 
-	/* blink all LEDs twice a second if we got an Oops (HPMC) */
-	if (unlikely(oops_in_progress)) 
-		currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+	/* blink LEDs if we got an Oops (HPMC) */
+	if (unlikely(oops_in_progress)) {
+		if (boot_cpu_data.cpu_type >= pcxl2) {
+			/* newer machines don't have loadavg. LEDs, so we
+			 * let all LEDs blink twice per second instead */
+			currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+		} else {
+			/* old machines: blink loadavg. LEDs twice per second */
+			if (count_HZ <= (HZ/2))
+				currentleds &= ~(LED4|LED5|LED6|LED7);
+			else
+				currentleds |= (LED4|LED5|LED6|LED7);
+		}
+	}
 
 	if (currentleds != lastleds)
 	{
@@ -511,7 +519,7 @@ static int led_halt(struct notifier_bloc
 	
 	/* Cancel the work item and delete the queue */
 	if (led_wq) {
-		cancel_rearming_delayed_workqueue(led_wq, &led_task);
+		cancel_delayed_work_sync(&led_task);
 		destroy_workqueue(led_wq);
 		led_wq = NULL;
 	}
@@ -630,7 +638,7 @@ int lcd_print( const char *str )
 	
 	/* temporarily disable the led work task */
 	if (led_wq)
-		cancel_rearming_delayed_workqueue(led_wq, &led_task);
+		cancel_delayed_work_sync(&led_task);
 
 	/* copy display string to buffer for procfs */
 	strlcpy(lcd_text, str, sizeof(lcd_text));
diff -druNp linux-libre-2.6.29-gnu1/drivers/parisc/superio.c linux-libre-2.6.30-gnu1/drivers/parisc/superio.c
--- linux-libre-2.6.29-gnu1/drivers/parisc/superio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parisc/superio.c	2009-06-09 23:05:27.000000000 -0400
@@ -434,7 +434,8 @@ static void __init superio_parport_init(
 			0 /*base_hi*/,
 			PAR_IRQ, 
 			PARPORT_DMA_NONE /* dma */,
-			NULL /*struct pci_dev* */) )
+			NULL /*struct pci_dev* */),
+			0 /* shared irq flags */ )
 
 		printk(KERN_WARNING PFX "Probing parallel port failed.\n");
 #endif	/* CONFIG_PARPORT_PC */
diff -druNp linux-libre-2.6.29-gnu1/drivers/parport/parport_cs.c linux-libre-2.6.30-gnu1/drivers/parport/parport_cs.c
--- linux-libre-2.6.29-gnu1/drivers/parport/parport_cs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parport/parport_cs.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/major.h>
+#include <linux/interrupt.h>
 
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
@@ -192,7 +193,7 @@ static int parport_config(struct pcmcia_
 
     p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
 			      link->irq.AssignedIRQ, PARPORT_DMA_NONE,
-			      &link->dev);
+			      &link->dev, IRQF_SHARED);
     if (p == NULL) {
 	printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
 	       "0x%3x, irq %u failed\n", link->io.BasePort1,
diff -druNp linux-libre-2.6.29-gnu1/drivers/parport/parport_gsc.c linux-libre-2.6.30-gnu1/drivers/parport/parport_gsc.c
--- linux-libre-2.6.29-gnu1/drivers/parport/parport_gsc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parport/parport_gsc.c	2009-06-09 23:05:27.000000000 -0400
@@ -352,8 +352,8 @@ static int __devinit parport_init_chip(s
 	unsigned long port;
 
 	if (!dev->irq) {
-		printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
-			dev->hpa.start);
+		printk(KERN_WARNING "IRQ not found for parallel device at 0x%llx\n",
+			(unsigned long long)dev->hpa.start);
 		return -ENODEV;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/parport/parport_pc.c linux-libre-2.6.30-gnu1/drivers/parport/parport_pc.c
--- linux-libre-2.6.29-gnu1/drivers/parport/parport_pc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parport/parport_pc.c	2009-06-09 23:05:27.000000000 -0400
@@ -2170,10 +2170,11 @@ static int parport_dma_probe (struct par
 static LIST_HEAD(ports_list);
 static DEFINE_SPINLOCK(ports_lock);
 
-struct parport *parport_pc_probe_port (unsigned long int base,
-				       unsigned long int base_hi,
-				       int irq, int dma,
-				       struct device *dev)
+struct parport *parport_pc_probe_port(unsigned long int base,
+				      unsigned long int base_hi,
+				      int irq, int dma,
+				      struct device *dev,
+				      int irqflags)
 {
 	struct parport_pc_private *priv;
 	struct parport_operations *ops;
@@ -2194,11 +2195,11 @@ struct parport *parport_pc_probe_port (u
 		dev = &pdev->dev;
 	}
 
-	ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
+	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
 	if (!ops)
 		goto out1;
 
-	priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
+	priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL);
 	if (!priv)
 		goto out2;
 
@@ -2325,8 +2326,8 @@ struct parport *parport_pc_probe_port (u
 		EPP_res = NULL;
 	}
 	if (p->irq != PARPORT_IRQ_NONE) {
-		if (request_irq (p->irq, parport_irq_handler,
-				 0, p->name, p)) {
+		if (request_irq(p->irq, parport_irq_handler,
+				 irqflags, p->name, p)) {
 			printk (KERN_WARNING "%s: irq %d in use, "
 				"resorting to polled operation\n",
 				p->name, p->irq);
@@ -2530,7 +2531,7 @@ static int __devinit sio_ite_8872_probe
 	 */
 	release_resource(base_res);
 	if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
-				   irq, PARPORT_DMA_NONE, &pdev->dev)) {
+				   irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
 		printk (KERN_INFO
 			"parport_pc: ITE 8872 parallel port: io=0x%X",
 			ite8872_lpt);
@@ -2713,7 +2714,7 @@ static int __devinit sio_via_probe (stru
 	}
 
 	/* finally, do the probe with values obtained */
-	if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
+	if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev, 0)) {
 		printk (KERN_INFO
 			"parport_pc: VIA parallel port: io=0x%X", port1);
 		if (irq != PARPORT_IRQ_NONE)
@@ -3018,6 +3019,7 @@ static int parport_pc_pci_probe (struct
 	for (n = 0; n < cards[i].numports; n++) {
 		int lo = cards[i].addr[n].lo;
 		int hi = cards[i].addr[n].hi;
+		int irq;
 		unsigned long io_lo, io_hi;
 		io_lo = pci_resource_start (dev, lo);
 		io_hi = 0;
@@ -3028,13 +3030,25 @@ static int parport_pc_pci_probe (struct
                                         "hi" as an offset (see SYBA
                                         def.) */
 		/* TODO: test if sharing interrupts works */
-		printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
-			"I/O at %#lx(%#lx)\n",
-			parport_pc_pci_tbl[i + last_sio].vendor,
-			parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
+		irq = dev->irq;
+		if (irq == IRQ_NONE) {
+			printk (KERN_DEBUG
+	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
+				parport_pc_pci_tbl[i + last_sio].vendor,
+				parport_pc_pci_tbl[i + last_sio].device,
+				io_lo, io_hi);
+			irq = PARPORT_IRQ_NONE;
+		} else {
+			printk (KERN_DEBUG
+	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
+				parport_pc_pci_tbl[i + last_sio].vendor,
+				parport_pc_pci_tbl[i + last_sio].device,
+				io_lo, io_hi, irq);
+		}
 		data->ports[count] =
-			parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
-					       PARPORT_DMA_NONE, &dev->dev);
+			parport_pc_probe_port(io_lo, io_hi, irq,
+					       PARPORT_DMA_NONE, &dev->dev,
+					       IRQF_SHARED);
 		if (data->ports[count])
 			count++;
 	}
@@ -3143,7 +3157,8 @@ static int parport_pc_pnp_probe(struct p
 		dma = PARPORT_DMA_NONE;
 
 	dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
-	if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
+	if (!(pdata = parport_pc_probe_port(io_lo, io_hi,
+					irq, dma, &dev->dev, 0)))
 		return -ENODEV;
 
 	pnp_set_drvdata(dev,pdata);
@@ -3192,11 +3207,11 @@ parport_pc_find_isa_ports (int autoirq,
 {
 	int count = 0;
 
-	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL))
+	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
 		count++;
-	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL))
+	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
 		count++;
-	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL))
+	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
 		count++;
 
 	return count;
@@ -3481,7 +3496,7 @@ static int __init parport_pc_init(void)
 			if ((io_hi[i]) == PARPORT_IOHI_AUTO)
 			       io_hi[i] = 0x400 + io[i];
 			parport_pc_probe_port(io[i], io_hi[i],
-						  irqval[i], dmaval[i], NULL);
+					  irqval[i], dmaval[i], NULL, 0);
 		}
 	} else
 		parport_pc_find_ports (irqval[0], dmaval[0]);
diff -druNp linux-libre-2.6.29-gnu1/drivers/parport/parport_serial.c linux-libre-2.6.30-gnu1/drivers/parport/parport_serial.c
--- linux-libre-2.6.29-gnu1/drivers/parport/parport_serial.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parport/parport_serial.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
 #include <linux/8250_pci.h>
@@ -30,6 +31,7 @@ enum parport_pc_pci_cards {
 	titan_210l,
 	netmos_9xx5_combo,
 	netmos_9855,
+	netmos_9855_2p,
 	avlab_1s1p,
 	avlab_1s2p,
 	avlab_2s1p,
@@ -62,7 +64,7 @@ struct parport_pc_pci {
 				struct parport_pc_pci *card, int failed);
 };
 
-static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
+static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
 {
 	/* the rule described below doesn't hold for this device */
 	if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
@@ -74,9 +76,17 @@ static int __devinit netmos_parallel_ini
 	 * and serial ports.  The form is 0x00PS, where <P> is the number of
 	 * parallel ports and <S> is the number of serial ports.
 	 */
-	card->numports = (dev->subsystem_device & 0xf0) >> 4;
-	if (card->numports > ARRAY_SIZE(card->addr))
-		card->numports = ARRAY_SIZE(card->addr);
+	par->numports = (dev->subsystem_device & 0xf0) >> 4;
+	if (par->numports > ARRAY_SIZE(par->addr))
+		par->numports = ARRAY_SIZE(par->addr);
+	/*
+	 * This function is currently only called for cards with up to
+	 * one parallel port.
+	 * Parallel port BAR is either before or after serial ports BARS;
+	 * hence, lo should be either 0 or equal to the number of serial ports.
+	 */
+	if (par->addr[0].lo != 0)
+		par->addr[0].lo = dev->subsystem_device & 0xf;
 	return 0;
 }
 
@@ -84,7 +94,8 @@ static struct parport_pc_pci cards[] __d
 	/* titan_110l */		{ 1, { { 3, -1 }, } },
 	/* titan_210l */		{ 1, { { 3, -1 }, } },
 	/* netmos_9xx5_combo */		{ 1, { { 2, -1 }, }, netmos_parallel_init },
-	/* netmos_9855 */		{ 1, { { 2, -1 }, }, netmos_parallel_init },
+	/* netmos_9855 */		{ 1, { { 0, -1 }, }, netmos_parallel_init },
+	/* netmos_9855_2p */		{ 2, { { 0, -1 }, { 2, -1 }, } },
 	/* avlab_1s1p     */		{ 1, { { 1, 2}, } },
 	/* avlab_1s2p     */		{ 2, { { 1, 2}, { 3, 4 },} },
 	/* avlab_2s1p     */		{ 1, { { 2, 3}, } },
@@ -110,6 +121,10 @@ static struct pci_device_id parport_seri
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+	  0x1000, 0x0020, 0, 0, netmos_9855_2p },
+	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+	  0x1000, 0x0022, 0, 0, netmos_9855_2p },
+	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
 	/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
 	{ PCI_VENDOR_ID_AFAVLAB, 0x2110,
@@ -192,6 +207,12 @@ static struct pciserial_board pci_parpor
 		.uart_offset	= 8,
 	},
 	[netmos_9855] = {
+		.flags		= FL_BASE2 | FL_BASE_BARS,
+		.num_ports	= 1,
+		.base_baud	= 115200,
+		.uart_offset	= 8,
+	},
+	[netmos_9855_2p] = {
 		.flags		= FL_BASE4 | FL_BASE_BARS,
 		.num_ports	= 1,
 		.base_baud	= 115200,
@@ -291,6 +312,7 @@ static int __devinit parport_register (s
 		int lo = card->addr[n].lo;
 		int hi = card->addr[n].hi;
 		unsigned long io_lo, io_hi;
+		int irq;
 
 		if (priv->num_par == ARRAY_SIZE (priv->port)) {
 			printk (KERN_WARNING
@@ -309,10 +331,20 @@ static int __devinit parport_register (s
                                         "hi" as an offset (see SYBA
                                         def.) */
 		/* TODO: test if sharing interrupts works */
-		dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
-			"%#lx(%#lx)\n", io_lo, io_hi);
-		port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
-					      PARPORT_DMA_NONE, &dev->dev);
+		irq = dev->irq;
+		if (irq == IRQ_NONE) {
+			dev_dbg(&dev->dev,
+			"PCI parallel port detected: I/O at %#lx(%#lx)\n",
+				io_lo, io_hi);
+			irq = PARPORT_IRQ_NONE;
+		} else {
+			dev_dbg(&dev->dev,
+		"PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
+				io_lo, io_hi, irq);
+			irq = PARPORT_IRQ_NONE;
+		}
+		port = parport_pc_probe_port (io_lo, io_hi, irq,
+			      PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
 		if (port) {
 			priv->port[priv->num_par++] = port;
 			success = 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/parport/share.c linux-libre-2.6.30-gnu1/drivers/parport/share.c
--- linux-libre-2.6.29-gnu1/drivers/parport/share.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/parport/share.c	2009-06-09 23:05:27.000000000 -0400
@@ -614,7 +614,10 @@ parport_register_device(struct parport *
 	 * pardevice fields. -arca
 	 */
 	port->ops->init_state(tmp, tmp->state);
-	parport_device_proc_register(tmp);
+	if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) {
+		port->proc_device = tmp;
+		parport_device_proc_register(tmp);
+	}
 	return tmp;
 
  out_free_all:
@@ -646,10 +649,14 @@ void parport_unregister_device(struct pa
 	}
 #endif
 
-	parport_device_proc_unregister(dev);
-
 	port = dev->port->physport;
 
+	if (port->proc_device == dev) {
+		port->proc_device = NULL;
+		clear_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags);
+		parport_device_proc_unregister(dev);
+	}
+
 	if (port->cad == dev) {
 		printk(KERN_DEBUG "%s: %s forgot to release port\n",
 		       port->name, dev->name);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/access.c linux-libre-2.6.30-gnu1/drivers/pci/access.c
--- linux-libre-2.6.29-gnu1/drivers/pci/access.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/access.c	2009-06-09 23:05:27.000000000 -0400
@@ -87,8 +87,8 @@ EXPORT_SYMBOL(pci_read_vpd);
  * pci_write_vpd - Write entry to Vital Product Data
  * @dev:	pci device struct
  * @pos:	offset in vpd space
- * @count:	number of bytes to read
- * @val:	value to write
+ * @count:	number of bytes to write
+ * @buf:	buffer containing write data
  *
  */
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf)
@@ -356,7 +356,8 @@ int pci_vpd_truncate(struct pci_dev *dev
 		return -EINVAL;
 
 	dev->vpd->len = size;
-	dev->vpd->attr->size = size;
+	if (dev->vpd->attr)
+		dev->vpd->attr->size = size;
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/bus.c linux-libre-2.6.30-gnu1/drivers/pci/bus.c
--- linux-libre-2.6.29-gnu1/drivers/pci/bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -133,7 +133,7 @@ int pci_bus_add_child(struct pci_bus *bu
  *
  * Call hotplug for each new devices.
  */
-void pci_bus_add_devices(struct pci_bus *bus)
+void pci_bus_add_devices(const struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 	struct pci_bus *child;
@@ -184,8 +184,10 @@ void pci_enable_bridges(struct pci_bus *
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		if (dev->subordinate) {
-			retval = pci_enable_device(dev);
-			pci_set_master(dev);
+			if (!pci_is_enabled(dev)) {
+				retval = pci_enable_device(dev);
+				pci_set_master(dev);
+			}
 			pci_enable_bridges(dev->subordinate);
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/dmar.c linux-libre-2.6.30-gnu1/drivers/pci/dmar.c
--- linux-libre-2.6.29-gnu1/drivers/pci/dmar.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/dmar.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,8 @@
 #include <linux/iova.h>
 #include <linux/intel-iommu.h>
 #include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #undef PREFIX
 #define PREFIX "DMAR:"
@@ -42,6 +44,7 @@
 LIST_HEAD(dmar_drhd_units);
 
 static struct acpi_table_header * __initdata dmar_tbl;
+static acpi_size dmar_tbl_size;
 
 static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
 {
@@ -170,13 +173,23 @@ dmar_parse_one_drhd(struct acpi_dmar_hea
 	struct dmar_drhd_unit *dmaru;
 	int ret = 0;
 
+	drhd = (struct acpi_dmar_hardware_unit *)header;
+	if (!drhd->address) {
+		/* Promote an attitude of violence to a BIOS engineer today */
+		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));
+		return -ENODEV;
+	}
 	dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
 	if (!dmaru)
 		return -ENOMEM;
 
 	dmaru->hdr = header;
-	drhd = (struct acpi_dmar_hardware_unit *)header;
 	dmaru->reg_base_addr = drhd->address;
+	dmaru->segment = drhd->segment;
 	dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
 
 	ret = alloc_iommu(dmaru);
@@ -288,8 +301,9 @@ static int __init dmar_table_detect(void
 	acpi_status status = AE_OK;
 
 	/* if we could find DMAR table, then there are DMAR devices */
-	status = acpi_get_table(ACPI_SIG_DMAR, 0,
-				(struct acpi_table_header **)&dmar_tbl);
+	status = acpi_get_table_with_size(ACPI_SIG_DMAR, 0,
+				(struct acpi_table_header **)&dmar_tbl,
+				&dmar_tbl_size);
 
 	if (ACPI_SUCCESS(status) && !dmar_tbl) {
 		printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
@@ -489,6 +503,7 @@ void __init detect_intel_iommu(void)
 			iommu_detected = 1;
 #endif
 	}
+	early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
 	dmar_tbl = NULL;
 }
 
@@ -506,6 +521,7 @@ int alloc_iommu(struct dmar_drhd_unit *d
 		return -ENOMEM;
 
 	iommu->seq_id = iommu_allocated++;
+	sprintf (iommu->name, "dmar%d", iommu->seq_id);
 
 	iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE);
 	if (!iommu->reg) {
@@ -748,14 +764,77 @@ int qi_flush_iotlb(struct intel_iommu *i
 }
 
 /*
+ * Disable Queued Invalidation interface.
+ */
+void dmar_disable_qi(struct intel_iommu *iommu)
+{
+	unsigned long flags;
+	u32 sts;
+	cycles_t start_time = get_cycles();
+
+	if (!ecap_qis(iommu->ecap))
+		return;
+
+	spin_lock_irqsave(&iommu->register_lock, flags);
+
+	sts =  dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	if (!(sts & DMA_GSTS_QIES))
+		goto end;
+
+	/*
+	 * Give a chance to HW to complete the pending invalidation requests.
+	 */
+	while ((readl(iommu->reg + DMAR_IQT_REG) !=
+		readl(iommu->reg + DMAR_IQH_REG)) &&
+		(DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time)))
+		cpu_relax();
+
+	iommu->gcmd &= ~DMA_GCMD_QIE;
+
+	writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
+		      !(sts & DMA_GSTS_QIES), sts);
+end:
+	spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
+ * Enable queued invalidation.
+ */
+static void __dmar_enable_qi(struct intel_iommu *iommu)
+{
+	u32 cmd, sts;
+	unsigned long flags;
+	struct q_inval *qi = iommu->qi;
+
+	qi->free_head = qi->free_tail = 0;
+	qi->free_cnt = QI_LENGTH;
+
+	spin_lock_irqsave(&iommu->register_lock, flags);
+
+	/* write zero to the tail reg */
+	writel(0, iommu->reg + DMAR_IQT_REG);
+
+	dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+
+	cmd = iommu->gcmd | DMA_GCMD_QIE;
+	iommu->gcmd |= DMA_GCMD_QIE;
+	writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
  * Enable Queued Invalidation interface. This is a must to support
  * interrupt-remapping. Also used by DMA-remapping, which replaces
  * register based IOTLB invalidation.
  */
 int dmar_enable_qi(struct intel_iommu *iommu)
 {
-	u32 cmd, sts;
-	unsigned long flags;
 	struct q_inval *qi;
 
 	if (!ecap_qis(iommu->ecap))
@@ -767,20 +846,20 @@ int dmar_enable_qi(struct intel_iommu *i
 	if (iommu->qi)
 		return 0;
 
-	iommu->qi = kmalloc(sizeof(*qi), GFP_KERNEL);
+	iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC);
 	if (!iommu->qi)
 		return -ENOMEM;
 
 	qi = iommu->qi;
 
-	qi->desc = (void *)(get_zeroed_page(GFP_KERNEL));
+	qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC));
 	if (!qi->desc) {
 		kfree(qi);
 		iommu->qi = 0;
 		return -ENOMEM;
 	}
 
-	qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_KERNEL);
+	qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
 	if (!qi->desc_status) {
 		free_page((unsigned long) qi->desc);
 		kfree(qi);
@@ -793,19 +872,283 @@ int dmar_enable_qi(struct intel_iommu *i
 
 	spin_lock_init(&qi->q_lock);
 
-	spin_lock_irqsave(&iommu->register_lock, flags);
-	/* write zero to the tail reg */
-	writel(0, iommu->reg + DMAR_IQT_REG);
+	__dmar_enable_qi(iommu);
 
-	dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+	return 0;
+}
 
-	cmd = iommu->gcmd | DMA_GCMD_QIE;
-	iommu->gcmd |= DMA_GCMD_QIE;
-	writel(cmd, iommu->reg + DMAR_GCMD_REG);
+/* iommu interrupt handling. Most stuff are MSI-like. */
 
-	/* Make sure hardware complete it */
-	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
-	spin_unlock_irqrestore(&iommu->register_lock, flags);
+enum faulttype {
+	DMA_REMAP,
+	INTR_REMAP,
+	UNKNOWN,
+};
+
+static const char *dma_remap_fault_reasons[] =
+{
+	"Software",
+	"Present bit in root entry is clear",
+	"Present bit in context entry is clear",
+	"Invalid context entry",
+	"Access beyond MGAW",
+	"PTE Write access is not set",
+	"PTE Read access is not set",
+	"Next page table ptr is invalid",
+	"Root table address invalid",
+	"Context table ptr is invalid",
+	"non-zero reserved fields in RTP",
+	"non-zero reserved fields in CTP",
+	"non-zero reserved fields in PTE",
+};
+
+static const char *intr_remap_fault_reasons[] =
+{
+	"Detected reserved fields in the decoded interrupt-remapped request",
+	"Interrupt index exceeded the interrupt-remapping table size",
+	"Present field in the IRTE entry is clear",
+	"Error accessing interrupt-remapping table pointed by IRTA_REG",
+	"Detected reserved fields in the IRTE entry",
+	"Blocked a compatibility format interrupt request",
+	"Blocked an interrupt request due to source-id verification failure",
+};
+
+#define MAX_FAULT_REASON_IDX 	(ARRAY_SIZE(fault_reason_strings) - 1)
+
+const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
+{
+	if (fault_reason >= 0x20 && (fault_reason <= 0x20 +
+				     ARRAY_SIZE(intr_remap_fault_reasons))) {
+		*fault_type = INTR_REMAP;
+		return intr_remap_fault_reasons[fault_reason - 0x20];
+	} else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
+		*fault_type = DMA_REMAP;
+		return dma_remap_fault_reasons[fault_reason];
+	} else {
+		*fault_type = UNKNOWN;
+		return "Unknown";
+	}
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	/* unmask it */
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(0, iommu->reg + DMAR_FECTL_REG);
+	/* Read a reg to force flush the post write */
+	readl(iommu->reg + DMAR_FECTL_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+	unsigned long flag;
+	struct intel_iommu *iommu = get_irq_data(irq);
+
+	/* mask it */
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+	/* Read a reg to force flush the post write */
+	readl(iommu->reg + DMAR_FECTL_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+	writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+	writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+	msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+	msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
+		u8 fault_reason, u16 source_id, unsigned long long addr)
+{
+	const char *reason;
+	int fault_type;
+
+	reason = dmar_get_fault_reason(fault_reason, &fault_type);
+
+	if (fault_type == INTR_REMAP)
+		printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] "
+		       "fault index %llx\n"
+			"INTR-REMAP:[fault reason %02d] %s\n",
+			(source_id >> 8), PCI_SLOT(source_id & 0xFF),
+			PCI_FUNC(source_id & 0xFF), addr >> 48,
+			fault_reason, reason);
+	else
+		printk(KERN_ERR
+		       "DMAR:[%s] Request device [%02x:%02x.%d] "
+		       "fault addr %llx \n"
+		       "DMAR:[fault reason %02d] %s\n",
+		       (type ? "DMA Read" : "DMA Write"),
+		       (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+		       PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+	return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+irqreturn_t dmar_fault(int irq, void *dev_id)
+{
+	struct intel_iommu *iommu = dev_id;
+	int reg, fault_index;
+	u32 fault_status;
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+	if (fault_status)
+		printk(KERN_ERR "DRHD: handling fault status reg %x\n",
+		       fault_status);
+
+	/* TBD: ignore advanced fault log currently */
+	if (!(fault_status & DMA_FSTS_PPF))
+		goto clear_rest;
+
+	fault_index = dma_fsts_fault_record_index(fault_status);
+	reg = cap_fault_reg_offset(iommu->cap);
+	while (1) {
+		u8 fault_reason;
+		u16 source_id;
+		u64 guest_addr;
+		int type;
+		u32 data;
+
+		/* highest 32 bits */
+		data = readl(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN + 12);
+		if (!(data & DMA_FRCD_F))
+			break;
+
+		fault_reason = dma_frcd_fault_reason(data);
+		type = dma_frcd_type(data);
+
+		data = readl(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN + 8);
+		source_id = dma_frcd_source_id(data);
+
+		guest_addr = dmar_readq(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN);
+		guest_addr = dma_frcd_page_addr(guest_addr);
+		/* clear the fault */
+		writel(DMA_FRCD_F, iommu->reg + reg +
+			fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+		spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+		dmar_fault_do_one(iommu, type, fault_reason,
+				source_id, guest_addr);
+
+		fault_index++;
+		if (fault_index > cap_num_fault_regs(iommu->cap))
+			fault_index = 0;
+		spin_lock_irqsave(&iommu->register_lock, flag);
+	}
+clear_rest:
+	/* clear all the other faults */
+	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+	writel(fault_status, iommu->reg + DMAR_FSTS_REG);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+	return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+	int irq, ret;
+
+	/*
+	 * Check if the fault interrupt is already initialized.
+	 */
+	if (iommu->irq)
+		return 0;
+
+	irq = create_irq();
+	if (!irq) {
+		printk(KERN_ERR "IOMMU: no free vectors\n");
+		return -EINVAL;
+	}
+
+	set_irq_data(irq, iommu);
+	iommu->irq = irq;
+
+	ret = arch_setup_dmar_msi(irq);
+	if (ret) {
+		set_irq_data(irq, NULL);
+		iommu->irq = 0;
+		destroy_irq(irq);
+		return 0;
+	}
+
+	ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu);
+	if (ret)
+		printk(KERN_ERR "IOMMU: can't request irq\n");
+	return ret;
+}
+
+int __init enable_drhd_fault_handling(void)
+{
+	struct dmar_drhd_unit *drhd;
+
+	/*
+	 * Enable fault control interrupt.
+	 */
+	for_each_drhd_unit(drhd) {
+		int ret;
+		struct intel_iommu *iommu = drhd->iommu;
+		ret = dmar_set_interrupt(iommu);
+
+		if (ret) {
+			printk(KERN_ERR "DRHD %Lx: failed to enable fault, "
+			       " interrupt, ret %d\n",
+			       (unsigned long long)drhd->reg_base_addr, ret);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Re-enable Queued Invalidation interface.
+ */
+int dmar_reenable_qi(struct intel_iommu *iommu)
+{
+	if (!ecap_qis(iommu->ecap))
+		return -ENOENT;
+
+	if (!iommu->qi)
+		return -ENOENT;
+
+	/*
+	 * First disable queued invalidation.
+	 */
+	dmar_disable_qi(iommu);
+	/*
+	 * Then enable queued invalidation again. Since there is no pending
+	 * invalidation requests now, it's safe to re-enable queued
+	 * invalidation.
+	 */
+	__dmar_enable_qi(iommu);
 
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpi_pcihp.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpi_pcihp.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpi_pcihp.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,9 +30,8 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/acpi.h>
 #include <linux/pci-acpi.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
 
 #define MY_NAME	"acpi_pcihp"
 
@@ -333,19 +332,14 @@ acpi_status acpi_get_hp_params_from_firm
 {
 	acpi_status status = AE_NOT_FOUND;
 	acpi_handle handle, phandle;
-	struct pci_bus *pbus = bus;
-	struct pci_dev *pdev;
+	struct pci_bus *pbus;
 
-	do {
-		pdev = pbus->self;
-		if (!pdev) {
-			handle = acpi_get_pci_rootbridge_handle(
-				pci_domain_nr(pbus), pbus->number);
+	handle = NULL;
+	for (pbus = bus; pbus; pbus = pbus->parent) {
+		handle = acpi_pci_get_bridge_handle(pbus);
+		if (handle)
 			break;
-		}
-		handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
-		pbus = pbus->parent;
-	} while (!handle);
+	}
 
 	/*
 	 * _HPP settings apply to all child buses, until another _HPP is
@@ -378,12 +372,10 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_fro
  *
  * Attempt to take hotplug control from firmware.
  */
-int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
+int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
 {
 	acpi_status status;
 	acpi_handle chandle, handle;
-	struct pci_dev *pdev = dev;
-	struct pci_bus *parent;
 	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
 
 	flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
@@ -408,33 +400,25 @@ int acpi_get_hp_hw_control_from_firmware
 		acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
 		dbg("Trying to get hotplug control for %s\n",
 				(char *)string.pointer);
-		status = pci_osc_control_set(handle, flags);
+		status = acpi_pci_osc_control_set(handle, flags);
 		if (ACPI_SUCCESS(status))
 			goto got_one;
 		kfree(string.pointer);
 		string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
 	}
 
-	pdev = dev;
-	handle = DEVICE_ACPI_HANDLE(&dev->dev);
-	while (!handle) {
+	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+	if (!handle) {
 		/*
 		 * This hotplug controller was not listed in the ACPI name
 		 * space at all. Try to get acpi handle of parent pci bus.
 		 */
-		if (!pdev || !pdev->bus->parent)
-			break;
-		parent = pdev->bus->parent;
-		dbg("Could not find %s in acpi namespace, trying parent\n",
-		    pci_name(pdev));
-		if (!parent->self)
-			/* Parent must be a host bridge */
-			handle = acpi_get_pci_rootbridge_handle(
-					pci_domain_nr(parent),
-					parent->number);
-		else
-			handle = DEVICE_ACPI_HANDLE(&(parent->self->dev));
-		pdev = parent->self;
+		struct pci_bus *pbus;
+		for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
+			handle = acpi_pci_get_bridge_handle(pbus);
+			if (handle)
+				break;
+		}
 	}
 
 	while (handle) {
@@ -453,13 +437,13 @@ int acpi_get_hp_hw_control_from_firmware
 	}
 
 	dbg("Cannot get control of hotplug hardware for pci %s\n",
-	    pci_name(dev));
+	    pci_name(pdev));
 
 	kfree(string.pointer);
 	return -ENODEV;
 got_one:
-	dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
-			(char *)string.pointer);
+	dbg("Gained control for hotplug HW for pci %s (%s)\n",
+	    pci_name(pdev), (char *)string.pointer);
 	kfree(string.pointer);
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpiphp_glue.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpiphp_glue.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,12 +32,11 @@
 
 /*
  * Lifetime rules for pci_dev:
- *  - The one in acpiphp_func has its refcount elevated by pci_get_slot()
- *    when the driver is loaded or when an insertion event occurs.  It loses
- *    a refcount when its ejected or the driver unloads.
  *  - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
  *    when the bridge is scanned and it loses a refcount when the bridge
  *    is removed.
+ *  - When a P2P bridge is present, we elevate the refcount on the subordinate
+ *    bus. It loses the refcount when the the driver unloads.
  */
 
 #include <linux/init.h>
@@ -128,6 +127,7 @@ register_slot(acpi_handle handle, u32 lv
 	unsigned long long adr, sun;
 	int device, function, retval;
 	struct pci_bus *pbus = bridge->pci_bus;
+	struct pci_dev *pdev;
 
 	if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
 		return AE_OK;
@@ -211,10 +211,10 @@ register_slot(acpi_handle handle, u32 lv
 	newfunc->slot = slot;
 	list_add_tail(&newfunc->sibling, &slot->funcs);
 
-	/* associate corresponding pci_dev */
-	newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function));
-	if (newfunc->pci_dev) {
+	pdev = pci_get_slot(pbus, PCI_DEVFN(device, function));
+	if (pdev) {
 		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
+		pci_dev_put(pdev);
 	}
 
 	if (is_dock_device(handle)) {
@@ -440,6 +440,12 @@ static void add_p2p_bridge(acpi_handle *
 		goto err;
 	}
 
+	/*
+	 * Grab a ref to the subordinate PCI bus in case the bus is
+	 * removed via PCI core logical hotplug. The ref pins the bus
+	 * (which we access during module unload).
+	 */
+	get_device(&bridge->pci_bus->dev);
 	spin_lock_init(&bridge->res_lock);
 
 	init_bridge_misc(bridge);
@@ -609,7 +615,6 @@ static void cleanup_bridge(struct acpiph
 				if (ACPI_FAILURE(status))
 					err("failed to remove notify handler\n");
 			}
-			pci_dev_put(func->pci_dev);
 			list_del(list);
 			kfree(func);
 		}
@@ -619,6 +624,12 @@ static void cleanup_bridge(struct acpiph
 		slot = next;
 	}
 
+	/*
+	 * Only P2P bridges have a pci_dev
+	 */
+	if (bridge->pci_dev)
+		put_device(&bridge->pci_bus->dev);
+
 	pci_dev_put(bridge->pci_dev);
 	list_del(&bridge->list);
 	kfree(bridge);
@@ -1087,22 +1098,24 @@ static int __ref enable_device(struct ac
 	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
-	/* associate pci_dev to our representation */
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
-		func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
-							func->function));
-		if (!func->pci_dev)
+		dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+						  func->function));
+		if (!dev)
 			continue;
 
-		if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
-		    func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
+		if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
+		    dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
+			pci_dev_put(dev);
 			continue;
+		}
 
 		status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
 		if (ACPI_FAILURE(status))
 			warn("find_p2p_bridge failed (error code = 0x%x)\n",
 				status);
+		pci_dev_put(dev);
 	}
 
 	slot->flags |= SLOT_ENABLED;
@@ -1128,17 +1141,14 @@ static void disable_bridges(struct pci_b
  */
 static int disable_device(struct acpiphp_slot *slot)
 {
-	int retval = 0;
 	struct acpiphp_func *func;
-	struct list_head *l;
+	struct pci_dev *pdev;
 
 	/* is this slot already disabled? */
 	if (!(slot->flags & SLOT_ENABLED))
 		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->bridge) {
 			/* cleanup p2p bridges under this P2P bridge */
 			cleanup_p2p_bridge(func->bridge->handle,
@@ -1146,35 +1156,28 @@ static int disable_device(struct acpiphp
 			func->bridge = NULL;
 		}
 
-		if (func->pci_dev) {
-			pci_stop_bus_device(func->pci_dev);
-			if (func->pci_dev->subordinate) {
-				disable_bridges(func->pci_dev->subordinate);
-				pci_disable_device(func->pci_dev);
+		pdev = pci_get_slot(slot->bridge->pci_bus,
+				    PCI_DEVFN(slot->device, func->function));
+		if (pdev) {
+			pci_stop_bus_device(pdev);
+			if (pdev->subordinate) {
+				disable_bridges(pdev->subordinate);
+				pci_disable_device(pdev);
 			}
+			pci_remove_bus_device(pdev);
+			pci_dev_put(pdev);
 		}
 	}
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
+	list_for_each_entry(func, &slot->funcs, sibling) {
 		acpiphp_unconfigure_ioapics(func->handle);
 		acpiphp_bus_trim(func->handle);
-		/* try to remove anyway.
-		 * acpiphp_bus_add might have been failed */
-
-		if (!func->pci_dev)
-			continue;
-
-		pci_remove_bus_device(func->pci_dev);
-		pci_dev_put(func->pci_dev);
-		func->pci_dev = NULL;
 	}
 
 	slot->flags &= (~SLOT_ENABLED);
 
- err_exit:
-	return retval;
+err_exit:
+	return 0;
 }
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpiphp.h linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpiphp.h
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/acpiphp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/acpiphp.h	2009-06-09 23:05:27.000000000 -0400
@@ -129,7 +129,6 @@ struct acpiphp_func {
 	struct acpiphp_bridge *bridge;	/* Ejectable PCI-to-PCI bridge */
 
 	struct list_head sibling;
-	struct pci_dev *pci_dev;
 	struct notifier_block nb;
 	acpi_handle	handle;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/cpqphp_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void)
 
 void cpqhp_create_debugfs_files(struct controller *ctrl)
 {
-	ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+	ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
+					   S_IRUGO, root, ctrl, &debug_ops);
 }
 
 void cpqhp_remove_debugfs_files(struct controller *ctrl)
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/fakephp.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/fakephp.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/fakephp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/fakephp.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,395 +1,163 @@
-/*
- * Fake PCI Hot Plug Controller Driver
- *
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003 IBM Corp.
- * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
- *
- * Based on ideas and code from:
- * 	Vladimir Kondratiev <vladimir.kondratiev@intel.com>
- *	Rolf Eike Beer <eike-kernel@sf-tec.de>
+/* Works like the fakephp driver used to, except a little better.
  *
- * All rights reserved.
+ * - It's possible to remove devices with subordinate busses.
+ * - New PCI devices that appear via any method, not just a fakephp triggered
+ *   rescan, will be noticed.
+ * - Devices that are removed via any method, not just a fakephp triggered
+ *   removal, will also be noticed.
  *
- * This program is free software; 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.
+ * Uses nothing from the pci-hotplug subsystem.
  *
- * Send feedback to <greg@kroah.com>
  */
 
-/*
- *
- * This driver will "emulate" removing PCI devices from the system.  If
- * the "power" file is written to with "0" then the specified PCI device
- * will be completely removed from the kernel.
- *
- * WARNING, this does NOT turn off the power to the PCI device.  This is
- * a "logical" removal, not a physical or electrical removal.
- *
- * Use this module at your own risk, you have been warned!
- *
- * Enabling PCI devices is left as an exercise for the reader...
- *
- */
-#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/pci_hotplug.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/device.h>
 #include "../pci.h"
 
-#if !defined(MODULE)
-	#define MY_NAME	"fakephp"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if (debug)					\
-			printk(KERN_DEBUG "%s: " format,	\
-				MY_NAME , ## arg); 		\
-	} while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC	"Fake PCI Hot Plug Controller Driver"
-
-struct dummy_slot {
-	struct list_head node;
-	struct hotplug_slot *slot;
-	struct pci_dev *dev;
-	struct work_struct remove_work;
-	unsigned long removed;
+struct legacy_slot {
+	struct kobject		kobj;
+	struct pci_dev		*dev;
+	struct list_head	list;
 };
 
-static int debug;
-static int dup_slots;
-static LIST_HEAD(slot_list);
-static struct workqueue_struct *dummyphp_wq;
-
-static void pci_rescan_worker(struct work_struct *work);
-static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
-
-static int enable_slot (struct hotplug_slot *slot);
-static int disable_slot (struct hotplug_slot *slot);
-
-static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
-	.owner			= THIS_MODULE,
-	.enable_slot		= enable_slot,
-	.disable_slot		= disable_slot,
-};
+static LIST_HEAD(legacy_list);
 
-static void dummy_release(struct hotplug_slot *slot)
+static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
+			   char *buf)
 {
-	struct dummy_slot *dslot = slot->private;
-
-	list_del(&dslot->node);
-	kfree(dslot->slot->info);
-	kfree(dslot->slot);
-	pci_dev_put(dslot->dev);
-	kfree(dslot);
+	struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+	strcpy(buf, "1\n");
+	return 2;
 }
 
-#define SLOT_NAME_SIZE	8
-
-static int add_slot(struct pci_dev *dev)
+static void remove_callback(void *data)
 {
-	struct dummy_slot *dslot;
-	struct hotplug_slot *slot;
-	char name[SLOT_NAME_SIZE];
-	int retval = -ENOMEM;
-	static int count = 1;
-
-	slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
-	if (!slot)
-		goto error;
-
-	slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
-	if (!slot->info)
-		goto error_slot;
-
-	slot->info->power_status = 1;
-	slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
-	slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
-
-	dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
-	if (!dslot)
-		goto error_info;
-
-	if (dup_slots)
-		snprintf(name, SLOT_NAME_SIZE, "fake");
-	else
-		snprintf(name, SLOT_NAME_SIZE, "fake%d", count++);
-	dbg("slot->name = %s\n", name);
-	slot->ops = &dummy_hotplug_slot_ops;
-	slot->release = &dummy_release;
-	slot->private = dslot;
-
-	retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name);
-	if (retval) {
-		err("pci_hp_register failed with error %d\n", retval);
-		goto error_dslot;
-	}
-
-	dbg("slot->name = %s\n", hotplug_slot_name(slot));
-	dslot->slot = slot;
-	dslot->dev = pci_dev_get(dev);
-	list_add (&dslot->node, &slot_list);
-	return retval;
-
-error_dslot:
-	kfree(dslot);
-error_info:
-	kfree(slot->info);
-error_slot:
-	kfree(slot);
-error:
-	return retval;
+	pci_remove_bus_device((struct pci_dev *)data);
 }
 
-static int __init pci_scan_buses(void)
+static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
+			    const char *buf, size_t len)
 {
-	struct pci_dev *dev = NULL;
-	int lastslot = 0;
-
-	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (PCI_FUNC(dev->devfn) > 0 &&
-				lastslot == PCI_SLOT(dev->devfn))
-			continue;
-		lastslot = PCI_SLOT(dev->devfn);
-		add_slot(dev);
-	}
-
-	return 0;
-}
+	struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+	unsigned long val;
 
-static void remove_slot(struct dummy_slot *dslot)
-{
-	int retval;
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
 
-	dbg("removing slot %s\n", hotplug_slot_name(dslot->slot));
-	retval = pci_hp_deregister(dslot->slot);
-	if (retval)
-		err("Problem unregistering a slot %s\n",
-			hotplug_slot_name(dslot->slot));
+	if (val)
+		pci_rescan_bus(slot->dev->bus);
+	else
+		sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
+					slot->dev, THIS_MODULE);
+	return len;
 }
 
-/* called from the single-threaded workqueue handler to remove a slot */
-static void remove_slot_worker(struct work_struct *work)
-{
-	struct dummy_slot *dslot =
-		container_of(work, struct dummy_slot, remove_work);
-	remove_slot(dslot);
-}
+static struct attribute *legacy_attrs[] = {
+	&(struct attribute){ .name = "power", .mode = 0644 },
+	NULL,
+};
 
-/**
- * pci_rescan_slot - Rescan slot
- * @temp: Device template. Should be set: bus and devfn.
- *
- * Tries hard not to re-enable already existing devices;
- * also handles scanning of subfunctions.
- */
-static int pci_rescan_slot(struct pci_dev *temp)
+static void legacy_release(struct kobject *kobj)
 {
-	struct pci_bus *bus = temp->bus;
-	struct pci_dev *dev;
-	int func;
-	u8 hdr_type;
-	int count = 0;
-
-	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
-		temp->hdr_type = hdr_type & 0x7f;
-		if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
-			pci_dev_put(dev);
-		else {
-			dev = pci_scan_single_device(bus, temp->devfn);
-			if (dev) {
-				dbg("New device on %s function %x:%x\n",
-					bus->name, temp->devfn >> 3,
-					temp->devfn & 7);
-				count++;
-			}
-		}
-		/* multifunction device? */
-		if (!(hdr_type & 0x80))
-			return count;
-
-		/* continue scanning for other functions */
-		for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
-			if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
-				continue;
-			temp->hdr_type = hdr_type & 0x7f;
-
-			if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
-				pci_dev_put(dev);
-			else {
-				dev = pci_scan_single_device(bus, temp->devfn);
-				if (dev) {
-					dbg("New device on %s function %x:%x\n",
-						bus->name, temp->devfn >> 3,
-						temp->devfn & 7);
-					count++;
-				}
-			}
-		}
-	}
+	struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
 
-	return count;
+	pci_dev_put(slot->dev);
+	kfree(slot);
 }
 
+static struct kobj_type legacy_ktype = {
+	.sysfs_ops = &(struct sysfs_ops){
+		.store = legacy_store, .show = legacy_show
+	},
+	.release = &legacy_release,
+	.default_attrs = legacy_attrs,
+};
 
-/**
- * pci_rescan_bus - Rescan PCI bus
- * @bus: the PCI bus to rescan
- *
- * Call pci_rescan_slot for each possible function of the bus.
- */
-static void pci_rescan_bus(const struct pci_bus *bus)
+static int legacy_add_slot(struct pci_dev *pdev)
 {
-	unsigned int devfn;
-	struct pci_dev *dev;
-	int retval;
-	int found = 0;
-	dev = alloc_pci_dev();
-	if (!dev)
-		return;
-
-	dev->bus = (struct pci_bus*)bus;
-	dev->sysdata = bus->sysdata;
-	for (devfn = 0; devfn < 0x100; devfn += 8) {
-		dev->devfn = devfn;
-		found += pci_rescan_slot(dev);
-	}
+	struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 
-	if (found) {
-		pci_bus_assign_resources(bus);
-		list_for_each_entry(dev, &bus->devices, bus_list) {
-			/* Skip already-added devices */
-			if (dev->is_added)
-					continue;
-			retval = pci_bus_add_device(dev);
-			if (retval)
-				dev_err(&dev->dev,
-					"Error adding device, continuing\n");
-			else
-				add_slot(dev);
-		}
-		pci_bus_add_devices(bus);
-	}
-	kfree(dev);
-}
+	if (!slot)
+		return -ENOMEM;
 
-/* recursively scan all buses */
-static void pci_rescan_buses(const struct list_head *list)
-{
-	const struct list_head *l;
-	list_for_each(l,list) {
-		const struct pci_bus *b = pci_bus_b(l);
-		pci_rescan_bus(b);
-		pci_rescan_buses(&b->children);
+	if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
+				 &pci_slots_kset->kobj, "%s",
+				 dev_name(&pdev->dev))) {
+		dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
+		return -EINVAL;
 	}
-}
-
-/* initiate rescan of all pci buses */
-static inline void pci_rescan(void) {
-	pci_rescan_buses(&pci_root_buses);
-}
+	slot->dev = pci_dev_get(pdev);
 
-/* called from the single-threaded workqueue handler to rescan all pci buses */
-static void pci_rescan_worker(struct work_struct *work)
-{
-	pci_rescan();
-}
+	list_add(&slot->list, &legacy_list);
 
-static int enable_slot(struct hotplug_slot *hotplug_slot)
-{
-	/* mis-use enable_slot for rescanning of the pci bus */
-	cancel_work_sync(&pci_rescan_work);
-	queue_work(dummyphp_wq, &pci_rescan_work);
 	return 0;
 }
 
-static int disable_slot(struct hotplug_slot *slot)
+static int legacy_notify(struct notifier_block *nb,
+			 unsigned long action, void *data)
 {
-	struct dummy_slot *dslot;
-	struct pci_dev *dev;
-	int func;
-
-	if (!slot)
-		return -ENODEV;
-	dslot = slot->private;
-
-	dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot));
-
-	for (func = 7; func >= 0; func--) {
-		dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
-		if (!dev)
-			continue;
-
-		if (test_and_set_bit(0, &dslot->removed)) {
-			dbg("Slot already scheduled for removal\n");
-			pci_dev_put(dev);
-			return -ENODEV;
-		}
+	struct pci_dev *pdev = to_pci_dev(data);
 
-		/* remove the device from the pci core */
-		pci_remove_bus_device(dev);
+	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		legacy_add_slot(pdev);
+	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
+		struct legacy_slot *slot;
 
-		/* queue work item to blow away this sysfs entry and other
-		 * parts.
-		 */
-		INIT_WORK(&dslot->remove_work, remove_slot_worker);
-		queue_work(dummyphp_wq, &dslot->remove_work);
+		list_for_each_entry(slot, &legacy_list, list)
+			if (slot->dev == pdev)
+				goto found;
 
-		pci_dev_put(dev);
+		dev_warn(&pdev->dev, "Missing legacy fake slot?");
+		return -ENODEV;
+found:
+		kobject_del(&slot->kobj);
+		list_del(&slot->list);
+		kobject_put(&slot->kobj);
 	}
+
 	return 0;
 }
 
-static void cleanup_slots (void)
-{
-	struct list_head *tmp;
-	struct list_head *next;
-	struct dummy_slot *dslot;
-
-	destroy_workqueue(dummyphp_wq);
-	list_for_each_safe (tmp, next, &slot_list) {
-		dslot = list_entry (tmp, struct dummy_slot, node);
-		remove_slot(dslot);
-	}
-	
-}
+static struct notifier_block legacy_notifier = {
+	.notifier_call = legacy_notify
+};
 
-static int __init dummyphp_init(void)
+static int __init init_legacy(void)
 {
-	info(DRIVER_DESC "\n");
+	struct pci_dev *pdev = NULL;
 
-	dummyphp_wq = create_singlethread_workqueue(MY_NAME);
-	if (!dummyphp_wq)
-		return -ENOMEM;
+	/* Add existing devices */
+	while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)))
+		legacy_add_slot(pdev);
 
-	return pci_scan_buses();
+	/* Be alerted of any new ones */
+	bus_register_notifier(&pci_bus_type, &legacy_notifier);
+	return 0;
 }
+module_init(init_legacy);
 
-
-static void __exit dummyphp_exit(void)
+static void __exit remove_legacy(void)
 {
-	cleanup_slots();
+	struct legacy_slot *slot, *tmp;
+
+	bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
+
+	list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
+		list_del(&slot->list);
+		kobject_del(&slot->kobj);
+		kobject_put(&slot->kobj);
+	}
 }
+module_exit(remove_legacy);
 
-module_init(dummyphp_init);
-module_exit(dummyphp_exit);
 
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
+MODULE_DESCRIPTION("Legacy version of the fakephp interface");
 MODULE_LICENSE("GPL");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-module_param(dup_slots, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dup_slots, "Force duplicate slot names for debugging");
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_acpi.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -67,37 +67,27 @@ static int __init parse_detect_mode(void
 	return PCIEHP_DETECT_DEFAULT;
 }
 
-static struct pcie_port_service_id __initdata port_pci_ids[] = {
-	{
-		.vendor = PCI_ANY_ID,
-		.device = PCI_ANY_ID,
-		.port_type = PCIE_ANY_PORT,
-		.service_type = PCIE_PORT_SERVICE_HP,
-		.driver_data =  0,
-        }, { /* end: all zeroes */ }
-};
-
 static int __initdata dup_slot_id;
 static int __initdata acpi_slot_detected;
 static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
 
 /* Dummy driver for dumplicate name detection */
-static int __init dummy_probe(struct pcie_device *dev,
-			      const struct pcie_port_service_id *id)
+static int __init dummy_probe(struct pcie_device *dev)
 {
 	int pos;
 	u32 slot_cap;
 	struct slot *slot, *tmp;
 	struct pci_dev *pdev = dev->port;
 	struct pci_bus *pbus = pdev->subordinate;
-	if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
-		return -ENOMEM;
 	/* 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)))
 		return -ENODEV;
 	pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+	if (!slot)
+		return -ENOMEM;
 	slot->number = slot_cap >> 19;
 	list_for_each_entry(tmp, &dummy_slots, slot_list) {
 		if (tmp->number == slot->number)
@@ -111,7 +101,8 @@ static int __init dummy_probe(struct pci
 
 static struct pcie_port_service_driver __initdata dummy_driver = {
         .name           = "pciehp_dummy",
-        .id_table       = port_pci_ids,
+	.port_type	= PCIE_ANY_PORT,
+	.service	= PCIE_PORT_SERVICE_HP,
         .probe          = dummy_probe,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_core.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_core.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -401,7 +401,7 @@ static int get_cur_bus_speed(struct hotp
 	return 0;
 }
 
-static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
+static int pciehp_probe(struct pcie_device *dev)
 {
 	int rc;
 	struct controller *ctrl;
@@ -475,7 +475,7 @@ static void pciehp_remove (struct pcie_d
 }
 
 #ifdef CONFIG_PM
-static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
+static int pciehp_suspend (struct pcie_device *dev)
 {
 	dev_info(&dev->device, "%s ENTRY\n", __func__);
 	return 0;
@@ -503,20 +503,12 @@ static int pciehp_resume (struct pcie_de
 	}
 	return 0;
 }
-#endif
-
-static struct pcie_port_service_id port_pci_ids[] = { {
-	.vendor = PCI_ANY_ID,
-	.device = PCI_ANY_ID,
-	.port_type = PCIE_ANY_PORT,
-	.service_type = PCIE_PORT_SERVICE_HP,
-	.driver_data =	0,
-	}, { /* end: all zeroes */ }
-};
+#endif /* PM */
 
 static struct pcie_port_service_driver hpdriver_portdrv = {
 	.name		= PCIE_MODULE_NAME,
-	.id_table	= &port_pci_ids[0],
+	.port_type	= PCIE_ANY_PORT,
+	.service	= PCIE_PORT_SERVICE_HP,
 
 	.probe		= pciehp_probe,
 	.remove		= pciehp_remove,
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp.h linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp.h
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp.h	2009-06-09 23:05:27.000000000 -0400
@@ -46,10 +46,10 @@ extern int pciehp_force;
 extern struct workqueue_struct *pciehp_wq;
 
 #define dbg(format, arg...)						\
-	do {								\
-		if (pciehp_debug)					\
-			printk("%s: " format, MY_NAME , ## arg);	\
-	} while (0)
+do {									\
+	if (pciehp_debug)						\
+		printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg);	\
+} while (0)
 #define err(format, arg...)						\
 	printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
 #define info(format, arg...)						\
@@ -60,7 +60,7 @@ extern struct workqueue_struct *pciehp_w
 #define ctrl_dbg(ctrl, format, arg...)					\
 	do {								\
 		if (pciehp_debug)					\
-			dev_printk(, &ctrl->pcie->device,		\
+			dev_printk(KERN_DEBUG, &ctrl->pcie->device,	\
 					format, ## arg);		\
 	} while (0)
 #define ctrl_err(ctrl, format, arg...)					\
@@ -108,10 +108,11 @@ struct controller {
 	u32 slot_cap;
 	u8 cap_base;
 	struct timer_list poll_timer;
-	int cmd_busy;
+	unsigned int cmd_busy:1;
 	unsigned int no_cmd_complete:1;
 	unsigned int link_active_reporting:1;
 	unsigned int notification_enabled:1;
+	unsigned int power_fault_detected;
 };
 
 #define INT_BUTTON_IGNORE		0
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_hpc.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_hpc.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/pciehp_hpc.c	2009-06-09 23:05:27.000000000 -0400
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot
 
 	slot_cmd = POWER_ON;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	/* Enable detection that we turned off at slot power-off time */
 	if (!pciehp_poll_mode) {
-		slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
-			     PCI_EXP_SLTCTL_PDCE);
-		cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
-			     PCI_EXP_SLTCTL_PDCE);
+		/* 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 -1;
+		return retval;
 	}
 	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
 		 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
 
+	ctrl->power_fault_detected = 0;
 	return retval;
 }
 
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slo
 
 	slot_cmd = POWER_OFF;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
-	/*
-	 * If we get MRL or presence detect interrupts now, the isr
-	 * will notice the sticky power-fault bit too and issue power
-	 * indicator change commands. This will lead to an endless loop
-	 * of command completions, since the power-fault bit remains on
-	 * till the slot is powered on again.
-	 */
 	if (!pciehp_poll_mode) {
-		slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
-			      PCI_EXP_SLTCTL_PDCE);
-		cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
-			     PCI_EXP_SLTCTL_PDCE);
+		/* 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);
@@ -672,10 +662,11 @@ static irqreturn_t pcie_isr(int irq, voi
 		detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
 			     PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
 			     PCI_EXP_SLTSTA_CC);
+		detected &= ~intr_loc;
 		intr_loc |= detected;
 		if (!intr_loc)
 			return IRQ_NONE;
-		if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) {
+		if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) {
 			ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
 				 __func__);
 			return IRQ_NONE;
@@ -709,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, voi
 		pciehp_handle_presence_change(p_slot);
 
 	/* Check Power Fault Detected */
-	if (intr_loc & PCI_EXP_SLTSTA_PFD)
+	if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
+		ctrl->power_fault_detected = 1;
 		pciehp_handle_power_fault(p_slot);
-
+	}
 	return IRQ_HANDLED;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/shpchp.h linux-libre-2.6.30-gnu1/drivers/pci/hotplug/shpchp.h
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/shpchp.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/shpchp.h	2009-06-09 23:05:27.000000000 -0400
@@ -48,10 +48,10 @@ extern int shpchp_debug;
 extern struct workqueue_struct *shpchp_wq;
 
 #define dbg(format, arg...)						\
-	do {								\
-		if (shpchp_debug)					\
-			printk("%s: " format, MY_NAME , ## arg);	\
-	} while (0)
+do {									\
+	if (shpchp_debug)						\
+		printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg);	\
+} while (0)
 #define err(format, arg...)						\
 	printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
 #define info(format, arg...)						\
@@ -62,7 +62,7 @@ extern struct workqueue_struct *shpchp_w
 #define ctrl_dbg(ctrl, format, arg...)					\
 	do {								\
 		if (shpchp_debug)					\
-			dev_printk(, &ctrl->pci_dev->dev,		\
+			dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev,	\
 					format, ## arg);		\
 	} while (0)
 #define ctrl_err(ctrl, format, arg...)					\
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/hotplug/shpchp_pci.c linux-libre-2.6.30-gnu1/drivers/pci/hotplug/shpchp_pci.c
--- linux-libre-2.6.29-gnu1/drivers/pci/hotplug/shpchp_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/hotplug/shpchp_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,7 +137,7 @@ int __ref shpchp_configure_device(struct
 							busnr))
 					break;
 			}
-			if (busnr >= end) {
+			if (busnr > end) {
 				ctrl_err(ctrl,
 					 "No free bus for hot-added bridge\n");
 				pci_dev_put(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/htirq.c linux-libre-2.6.30-gnu1/drivers/pci/htirq.c
--- linux-libre-2.6.29-gnu1/drivers/pci/htirq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/htirq.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,6 +158,7 @@ int ht_create_irq(struct pci_dev *dev, i
 
 /**
  * ht_destroy_irq - destroy an irq created with ht_create_irq
+ * @irq: irq to be destroyed
  *
  * This reverses ht_create_irq removing the specified irq from
  * existence.  The irq should be free before this happens.
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/intel-iommu.c linux-libre-2.6.30-gnu1/drivers/pci/intel-iommu.c
--- linux-libre-2.6.29-gnu1/drivers/pci/intel-iommu.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/intel-iommu.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/iova.h>
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
+#include <linux/sysdev.h>
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
 #include "pci.h"
@@ -55,8 +56,12 @@
 #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
 
 #define IOVA_PFN(addr)		((addr) >> PAGE_SHIFT)
-#define DMA_32BIT_PFN		IOVA_PFN(DMA_32BIT_MASK)
-#define DMA_64BIT_PFN		IOVA_PFN(DMA_64BIT_MASK)
+#define DMA_32BIT_PFN		IOVA_PFN(DMA_BIT_MASK(32))
+#define DMA_64BIT_PFN		IOVA_PFN(DMA_BIT_MASK(64))
+
+#ifndef PHYSICAL_PAGE_MASK
+#define PHYSICAL_PAGE_MASK PAGE_MASK
+#endif
 
 /* global iommu list, set NULL for ignored DMAR units */
 static struct intel_iommu **g_iommus;
@@ -164,7 +169,8 @@ static inline void context_clear_entry(s
  * 1: writable
  * 2-6: reserved
  * 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
  * 12-63: Host physcial address
  */
 struct dma_pte {
@@ -186,6 +192,11 @@ static inline void dma_set_pte_writable(
 	pte->val |= DMA_PTE_WRITE;
 }
 
+static inline void dma_set_pte_snp(struct dma_pte *pte)
+{
+	pte->val |= DMA_PTE_SNP;
+}
+
 static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
 {
 	pte->val = (pte->val & ~3) | (prot & 3);
@@ -231,6 +242,7 @@ struct dmar_domain {
 	int		flags;		/* flags to find out type of domain */
 
 	int		iommu_coherency;/* indicate coherency of iommu access */
+	int		iommu_snooping; /* indicate snooping control feature*/
 	int		iommu_count;	/* reference count of iommu */
 	spinlock_t	iommu_lock;	/* protect iommu set in domain */
 	u64		max_addr;	/* maximum mapped address */
@@ -240,7 +252,8 @@ struct dmar_domain {
 struct device_domain_info {
 	struct list_head link;	/* link to domain siblings */
 	struct list_head global; /* link to global list */
-	u8 bus;			/* PCI bus numer */
+	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 dmar_domain *domain; /* pointer to domain */
@@ -421,7 +434,6 @@ static struct intel_iommu *domain_get_io
 	return g_iommus[iommu_id];
 }
 
-/* "Coherency" capability may be different across iommus */
 static void domain_update_iommu_coherency(struct dmar_domain *domain)
 {
 	int i;
@@ -438,7 +450,30 @@ static void domain_update_iommu_coherenc
 	}
 }
 
-static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
+static void domain_update_iommu_snooping(struct dmar_domain *domain)
+{
+	int i;
+
+	domain->iommu_snooping = 1;
+
+	i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+	for (; i < g_num_of_iommus; ) {
+		if (!ecap_sc_support(g_iommus[i]->ecap)) {
+			domain->iommu_snooping = 0;
+			break;
+		}
+		i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+	}
+}
+
+/* Some capabilities may be different across iommus */
+static void domain_update_iommu_cap(struct dmar_domain *domain)
+{
+	domain_update_iommu_coherency(domain);
+	domain_update_iommu_snooping(domain);
+}
+
+static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
 {
 	struct dmar_drhd_unit *drhd = NULL;
 	int i;
@@ -446,12 +481,20 @@ static struct intel_iommu *device_to_iom
 	for_each_drhd_unit(drhd) {
 		if (drhd->ignored)
 			continue;
+		if (segment != drhd->segment)
+			continue;
 
-		for (i = 0; i < drhd->devices_cnt; i++)
+		for (i = 0; i < drhd->devices_cnt; i++) {
 			if (drhd->devices[i] &&
 			    drhd->devices[i]->bus->number == bus &&
 			    drhd->devices[i]->devfn == devfn)
 				return drhd->iommu;
+			if (drhd->devices[i] &&
+			    drhd->devices[i]->subordinate &&
+			    drhd->devices[i]->subordinate->number <= bus &&
+			    drhd->devices[i]->subordinate->subordinate >= bus)
+				return drhd->iommu;
+		}
 
 		if (drhd->include_all)
 			return drhd->iommu;
@@ -689,15 +732,17 @@ static void dma_pte_clear_one(struct dma
 static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
 {
 	int addr_width = agaw_to_width(domain->agaw);
+	int npages;
 
 	start &= (((u64)1) << addr_width) - 1;
 	end &= (((u64)1) << addr_width) - 1;
 	/* in case it's partial page */
-	start = PAGE_ALIGN(start);
-	end &= PAGE_MASK;
+	start &= PAGE_MASK;
+	end = PAGE_ALIGN(end);
+	npages = (end - start) / VTD_PAGE_SIZE;
 
 	/* we don't need lock here, nobody else touches the iova range */
-	while (start < end) {
+	while (npages--) {
 		dma_pte_clear_one(domain, start);
 		start += VTD_PAGE_SIZE;
 	}
@@ -1004,194 +1049,6 @@ static int iommu_disable_translation(str
 	return 0;
 }
 
-/* iommu interrupt handling. Most stuff are MSI-like. */
-
-static const char *fault_reason_strings[] =
-{
-	"Software",
-	"Present bit in root entry is clear",
-	"Present bit in context entry is clear",
-	"Invalid context entry",
-	"Access beyond MGAW",
-	"PTE Write access is not set",
-	"PTE Read access is not set",
-	"Next page table ptr is invalid",
-	"Root table address invalid",
-	"Context table ptr is invalid",
-	"non-zero reserved fields in RTP",
-	"non-zero reserved fields in CTP",
-	"non-zero reserved fields in PTE",
-};
-#define MAX_FAULT_REASON_IDX 	(ARRAY_SIZE(fault_reason_strings) - 1)
-
-const char *dmar_get_fault_reason(u8 fault_reason)
-{
-	if (fault_reason > MAX_FAULT_REASON_IDX)
-		return "Unknown";
-	else
-		return fault_reason_strings[fault_reason];
-}
-
-void dmar_msi_unmask(unsigned int irq)
-{
-	struct intel_iommu *iommu = get_irq_data(irq);
-	unsigned long flag;
-
-	/* unmask it */
-	spin_lock_irqsave(&iommu->register_lock, flag);
-	writel(0, iommu->reg + DMAR_FECTL_REG);
-	/* Read a reg to force flush the post write */
-	readl(iommu->reg + DMAR_FECTL_REG);
-	spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_mask(unsigned int irq)
-{
-	unsigned long flag;
-	struct intel_iommu *iommu = get_irq_data(irq);
-
-	/* mask it */
-	spin_lock_irqsave(&iommu->register_lock, flag);
-	writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
-	/* Read a reg to force flush the post write */
-	readl(iommu->reg + DMAR_FECTL_REG);
-	spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_write(int irq, struct msi_msg *msg)
-{
-	struct intel_iommu *iommu = get_irq_data(irq);
-	unsigned long flag;
-
-	spin_lock_irqsave(&iommu->register_lock, flag);
-	writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
-	writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
-	writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
-	spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_read(int irq, struct msi_msg *msg)
-{
-	struct intel_iommu *iommu = get_irq_data(irq);
-	unsigned long flag;
-
-	spin_lock_irqsave(&iommu->register_lock, flag);
-	msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
-	msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
-	msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
-	spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
-		u8 fault_reason, u16 source_id, unsigned long long addr)
-{
-	const char *reason;
-
-	reason = dmar_get_fault_reason(fault_reason);
-
-	printk(KERN_ERR
-		"DMAR:[%s] Request device [%02x:%02x.%d] "
-		"fault addr %llx \n"
-		"DMAR:[fault reason %02d] %s\n",
-		(type ? "DMA Read" : "DMA Write"),
-		(source_id >> 8), PCI_SLOT(source_id & 0xFF),
-		PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
-	return 0;
-}
-
-#define PRIMARY_FAULT_REG_LEN (16)
-static irqreturn_t iommu_page_fault(int irq, void *dev_id)
-{
-	struct intel_iommu *iommu = dev_id;
-	int reg, fault_index;
-	u32 fault_status;
-	unsigned long flag;
-
-	spin_lock_irqsave(&iommu->register_lock, flag);
-	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
-
-	/* TBD: ignore advanced fault log currently */
-	if (!(fault_status & DMA_FSTS_PPF))
-		goto clear_overflow;
-
-	fault_index = dma_fsts_fault_record_index(fault_status);
-	reg = cap_fault_reg_offset(iommu->cap);
-	while (1) {
-		u8 fault_reason;
-		u16 source_id;
-		u64 guest_addr;
-		int type;
-		u32 data;
-
-		/* highest 32 bits */
-		data = readl(iommu->reg + reg +
-				fault_index * PRIMARY_FAULT_REG_LEN + 12);
-		if (!(data & DMA_FRCD_F))
-			break;
-
-		fault_reason = dma_frcd_fault_reason(data);
-		type = dma_frcd_type(data);
-
-		data = readl(iommu->reg + reg +
-				fault_index * PRIMARY_FAULT_REG_LEN + 8);
-		source_id = dma_frcd_source_id(data);
-
-		guest_addr = dmar_readq(iommu->reg + reg +
-				fault_index * PRIMARY_FAULT_REG_LEN);
-		guest_addr = dma_frcd_page_addr(guest_addr);
-		/* clear the fault */
-		writel(DMA_FRCD_F, iommu->reg + reg +
-			fault_index * PRIMARY_FAULT_REG_LEN + 12);
-
-		spin_unlock_irqrestore(&iommu->register_lock, flag);
-
-		iommu_page_fault_do_one(iommu, type, fault_reason,
-				source_id, guest_addr);
-
-		fault_index++;
-		if (fault_index > cap_num_fault_regs(iommu->cap))
-			fault_index = 0;
-		spin_lock_irqsave(&iommu->register_lock, flag);
-	}
-clear_overflow:
-	/* clear primary fault overflow */
-	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
-	if (fault_status & DMA_FSTS_PFO)
-		writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
-
-	spin_unlock_irqrestore(&iommu->register_lock, flag);
-	return IRQ_HANDLED;
-}
-
-int dmar_set_interrupt(struct intel_iommu *iommu)
-{
-	int irq, ret;
-
-	irq = create_irq();
-	if (!irq) {
-		printk(KERN_ERR "IOMMU: no free vectors\n");
-		return -EINVAL;
-	}
-
-	set_irq_data(irq, iommu);
-	iommu->irq = irq;
-
-	ret = arch_setup_dmar_msi(irq);
-	if (ret) {
-		set_irq_data(irq, NULL);
-		iommu->irq = 0;
-		destroy_irq(irq);
-		return 0;
-	}
-
-	/* Force fault register is cleared */
-	iommu_page_fault(irq, iommu);
-
-	ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
-	if (ret)
-		printk(KERN_ERR "IOMMU: can't request irq\n");
-	return ret;
-}
 
 static int iommu_init_domains(struct intel_iommu *iommu)
 {
@@ -1363,7 +1220,7 @@ static void dmar_init_reserved_ranges(vo
 			if (!r->flags || !(r->flags & IORESOURCE_MEM))
 				continue;
 			addr = r->start;
-			addr &= PAGE_MASK;
+			addr &= PHYSICAL_PAGE_MASK;
 			size = r->end - addr;
 			size = PAGE_ALIGN(size);
 			iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
@@ -1429,6 +1286,11 @@ static int domain_init(struct dmar_domai
 	else
 		domain->iommu_coherency = 0;
 
+	if (ecap_sc_support(iommu->ecap))
+		domain->iommu_snooping = 1;
+	else
+		domain->iommu_snooping = 0;
+
 	domain->iommu_count = 1;
 
 	/* always allocate the top pgd */
@@ -1464,7 +1326,7 @@ static void domain_exit(struct dmar_doma
 }
 
 static int domain_context_mapping_one(struct dmar_domain *domain,
-		u8 bus, u8 devfn)
+				      int segment, u8 bus, u8 devfn)
 {
 	struct context_entry *context;
 	unsigned long flags;
@@ -1479,7 +1341,7 @@ static int domain_context_mapping_one(st
 		bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 	BUG_ON(!domain->pgd);
 
-	iommu = device_to_iommu(bus, devfn);
+	iommu = device_to_iommu(segment, bus, devfn);
 	if (!iommu)
 		return -ENODEV;
 
@@ -1557,7 +1419,7 @@ 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++;
-		domain_update_iommu_coherency(domain);
+		domain_update_iommu_cap(domain);
 	}
 	spin_unlock_irqrestore(&domain->iommu_lock, flags);
 	return 0;
@@ -1569,8 +1431,8 @@ domain_context_mapping(struct dmar_domai
 	int ret;
 	struct pci_dev *tmp, *parent;
 
-	ret = domain_context_mapping_one(domain, pdev->bus->number,
-		pdev->devfn);
+	ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
+					 pdev->bus->number, pdev->devfn);
 	if (ret)
 		return ret;
 
@@ -1581,18 +1443,23 @@ domain_context_mapping(struct dmar_domai
 	/* Secondary interface's bus number and devfn 0 */
 	parent = pdev->bus->self;
 	while (parent != tmp) {
-		ret = domain_context_mapping_one(domain, parent->bus->number,
-			parent->devfn);
+		ret = domain_context_mapping_one(domain,
+						 pci_domain_nr(parent->bus),
+						 parent->bus->number,
+						 parent->devfn);
 		if (ret)
 			return ret;
 		parent = parent->bus->self;
 	}
 	if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
 		return domain_context_mapping_one(domain,
-			tmp->subordinate->number, 0);
+					pci_domain_nr(tmp->subordinate),
+					tmp->subordinate->number, 0);
 	else /* this is a legacy PCI bridge */
 		return domain_context_mapping_one(domain,
-			tmp->bus->number, tmp->devfn);
+						  pci_domain_nr(tmp->bus),
+						  tmp->bus->number,
+						  tmp->devfn);
 }
 
 static int domain_context_mapped(struct pci_dev *pdev)
@@ -1601,12 +1468,12 @@ static int domain_context_mapped(struct
 	struct pci_dev *tmp, *parent;
 	struct intel_iommu *iommu;
 
-	iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+	iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+				pdev->devfn);
 	if (!iommu)
 		return -ENODEV;
 
-	ret = device_context_mapped(iommu,
-		pdev->bus->number, pdev->devfn);
+	ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn);
 	if (!ret)
 		return ret;
 	/* dependent device mapping */
@@ -1617,17 +1484,17 @@ static int domain_context_mapped(struct
 	parent = pdev->bus->self;
 	while (parent != tmp) {
 		ret = device_context_mapped(iommu, parent->bus->number,
-			parent->devfn);
+					    parent->devfn);
 		if (!ret)
 			return ret;
 		parent = parent->bus->self;
 	}
 	if (tmp->is_pcie)
-		return device_context_mapped(iommu,
-			tmp->subordinate->number, 0);
+		return device_context_mapped(iommu, tmp->subordinate->number,
+					     0);
 	else
-		return device_context_mapped(iommu,
-			tmp->bus->number, tmp->devfn);
+		return device_context_mapped(iommu, tmp->bus->number,
+					     tmp->devfn);
 }
 
 static int
@@ -1657,6 +1524,8 @@ domain_page_mapping(struct dmar_domain *
 		BUG_ON(dma_pte_addr(pte));
 		dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
 		dma_set_pte_prot(pte, prot);
+		if (prot & DMA_PTE_SNP)
+			dma_set_pte_snp(pte);
 		domain_flush_cache(domain, pte, sizeof(*pte));
 		start_pfn++;
 		index++;
@@ -1692,7 +1561,7 @@ static void domain_remove_dev_info(struc
 			info->dev->dev.archdata.iommu = NULL;
 		spin_unlock_irqrestore(&device_domain_lock, flags);
 
-		iommu = device_to_iommu(info->bus, info->devfn);
+		iommu = device_to_iommu(info->segment, info->bus, info->devfn);
 		iommu_detach_dev(iommu, info->bus, info->devfn);
 		free_devinfo_mem(info);
 
@@ -1727,11 +1596,14 @@ static struct dmar_domain *get_domain_fo
 	struct pci_dev *dev_tmp;
 	unsigned long flags;
 	int bus = 0, devfn = 0;
+	int segment;
 
 	domain = find_domain(pdev);
 	if (domain)
 		return domain;
 
+	segment = pci_domain_nr(pdev->bus);
+
 	dev_tmp = pci_find_upstream_pcie_bridge(pdev);
 	if (dev_tmp) {
 		if (dev_tmp->is_pcie) {
@@ -1743,7 +1615,8 @@ static struct dmar_domain *get_domain_fo
 		}
 		spin_lock_irqsave(&device_domain_lock, flags);
 		list_for_each_entry(info, &device_domain_list, global) {
-			if (info->bus == bus && info->devfn == devfn) {
+			if (info->segment == segment &&
+			    info->bus == bus && info->devfn == devfn) {
 				found = info->domain;
 				break;
 			}
@@ -1781,6 +1654,7 @@ static struct dmar_domain *get_domain_fo
 			domain_exit(domain);
 			goto error;
 		}
+		info->segment = segment;
 		info->bus = bus;
 		info->devfn = devfn;
 		info->dev = NULL;
@@ -1792,7 +1666,8 @@ static struct dmar_domain *get_domain_fo
 		found = NULL;
 		spin_lock_irqsave(&device_domain_lock, flags);
 		list_for_each_entry(tmp, &device_domain_list, global) {
-			if (tmp->bus == bus && tmp->devfn == devfn) {
+			if (tmp->segment == segment &&
+			    tmp->bus == bus && tmp->devfn == devfn) {
 				found = tmp->domain;
 				break;
 			}
@@ -1812,6 +1687,7 @@ found_domain:
 	info = alloc_devinfo_mem();
 	if (!info)
 		goto error;
+	info->segment = segment;
 	info->bus = pdev->bus->number;
 	info->devfn = pdev->devfn;
 	info->dev = pdev;
@@ -1970,7 +1846,7 @@ static inline void iommu_prepare_isa(voi
 	ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
 
 	if (ret)
-		printk("IOMMU: Failed to create 0-64M identity map, "
+		printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
 			"floppy might not work\n");
 
 }
@@ -1987,7 +1863,7 @@ static int __init init_dmars(void)
 	struct dmar_rmrr_unit *rmrr;
 	struct pci_dev *pdev;
 	struct intel_iommu *iommu;
-	int i, ret, unit = 0;
+	int i, ret;
 
 	/*
 	 * for each drhd
@@ -2043,11 +1919,40 @@ static int __init init_dmars(void)
 		}
 	}
 
+	/*
+	 * Start from the sane iommu hardware state.
+	 */
 	for_each_drhd_unit(drhd) {
 		if (drhd->ignored)
 			continue;
 
 		iommu = drhd->iommu;
+
+		/*
+		 * If the queued invalidation is already initialized by us
+		 * (for example, while enabling interrupt-remapping) then
+		 * we got the things already rolling from a sane state.
+		 */
+		if (iommu->qi)
+			continue;
+
+		/*
+		 * Clear any previous faults.
+		 */
+		dmar_fault(-1, iommu);
+		/*
+		 * Disable queued invalidation if supported and already enabled
+		 * before OS handover.
+		 */
+		dmar_disable_qi(iommu);
+	}
+
+	for_each_drhd_unit(drhd) {
+		if (drhd->ignored)
+			continue;
+
+		iommu = drhd->iommu;
+
 		if (dmar_enable_qi(iommu)) {
 			/*
 			 * Queued Invalidate not enabled, use Register Based
@@ -2067,6 +1972,15 @@ static int __init init_dmars(void)
 		}
 	}
 
+#ifdef CONFIG_INTR_REMAP
+	if (!intr_remapping_enabled) {
+		ret = enable_intr_remapping(0);
+		if (ret)
+			printk(KERN_ERR
+			       "IOMMU: enable interrupt remapping failed\n");
+	}
+#endif
+
 	/*
 	 * For each rmrr
 	 *   for each dev attached to rmrr
@@ -2109,7 +2023,6 @@ static int __init init_dmars(void)
 		if (drhd->ignored)
 			continue;
 		iommu = drhd->iommu;
-		sprintf (iommu->name, "dmar%d", unit++);
 
 		iommu_flush_write_buffer(iommu);
 
@@ -2171,15 +2084,15 @@ __intel_alloc_iova(struct device *dev, s
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct iova *iova = NULL;
 
-	if (dma_mask <= DMA_32BIT_MASK || dmar_forcedac)
+	if (dma_mask <= DMA_BIT_MASK(32) || dmar_forcedac)
 		iova = iommu_alloc_iova(domain, size, dma_mask);
 	else {
 		/*
 		 * First try to allocate an io virtual address in
-		 * DMA_32BIT_MASK and if that fails then try allocating
+		 * DMA_BIT_MASK(32) and if that fails then try allocating
 		 * from higher range
 		 */
-		iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
+		iova = iommu_alloc_iova(domain, size, DMA_BIT_MASK(32));
 		if (!iova)
 			iova = iommu_alloc_iova(domain, size, dma_mask);
 	}
@@ -2264,7 +2177,8 @@ static dma_addr_t __intel_map_single(str
 	 * is not a big problem
 	 */
 	ret = domain_page_mapping(domain, start_paddr,
-		((u64)paddr) & PAGE_MASK, size, prot);
+				  ((u64)paddr) & PHYSICAL_PAGE_MASK,
+				  size, prot);
 	if (ret)
 		goto error;
 
@@ -2279,16 +2193,18 @@ static dma_addr_t __intel_map_single(str
 error:
 	if (iova)
 		__free_iova(&domain->iovad, iova);
-	printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+	printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
 		pci_name(pdev), size, (unsigned long long)paddr, dir);
 	return 0;
 }
 
-dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr,
-			    size_t size, int dir)
+static dma_addr_t intel_map_page(struct device *dev, struct page *page,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction dir,
+				 struct dma_attrs *attrs)
 {
-	return __intel_map_single(hwdev, paddr, size, dir,
-				  to_pci_dev(hwdev)->dma_mask);
+	return __intel_map_single(dev, page_to_phys(page) + offset, size,
+				  dir, to_pci_dev(dev)->dma_mask);
 }
 
 static void flush_unmaps(void)
@@ -2352,8 +2268,9 @@ static void add_unmap(struct dmar_domain
 	spin_unlock_irqrestore(&async_umap_flush_lock, flags);
 }
 
-void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
-			int dir)
+static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+			     size_t size, enum dma_data_direction dir,
+			     struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct dmar_domain *domain;
@@ -2375,7 +2292,7 @@ void intel_unmap_single(struct device *d
 	start_addr = iova->pfn_lo << PAGE_SHIFT;
 	size = aligned_size((u64)dev_addr, size);
 
-	pr_debug("Device %s unmapping: %lx@%llx\n",
+	pr_debug("Device %s unmapping: %zx@%llx\n",
 		pci_name(pdev), size, (unsigned long long)start_addr);
 
 	/*  clear the whole page */
@@ -2397,8 +2314,14 @@ void intel_unmap_single(struct device *d
 	}
 }
 
-void *intel_alloc_coherent(struct device *hwdev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flags)
+static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
+			       int dir)
+{
+	intel_unmap_page(dev, dev_addr, size, dir, NULL);
+}
+
+static void *intel_alloc_coherent(struct device *hwdev, size_t size,
+				  dma_addr_t *dma_handle, gfp_t flags)
 {
 	void *vaddr;
 	int order;
@@ -2421,8 +2344,8 @@ void *intel_alloc_coherent(struct device
 	return NULL;
 }
 
-void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			 dma_addr_t dma_handle)
+static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+				dma_addr_t dma_handle)
 {
 	int order;
 
@@ -2433,10 +2356,9 @@ void intel_free_coherent(struct device *
 	free_pages((unsigned long)vaddr, order);
 }
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(sg_virt((sg)))
-
-void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
-		    int nelems, int dir)
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+			   int nelems, enum dma_data_direction dir,
+			   struct dma_attrs *attrs)
 {
 	int i;
 	struct pci_dev *pdev = to_pci_dev(hwdev);
@@ -2444,7 +2366,7 @@ void intel_unmap_sg(struct device *hwdev
 	unsigned long start_addr;
 	struct iova *iova;
 	size_t size = 0;
-	void *addr;
+	phys_addr_t addr;
 	struct scatterlist *sg;
 	struct intel_iommu *iommu;
 
@@ -2460,7 +2382,7 @@ void intel_unmap_sg(struct device *hwdev
 	if (!iova)
 		return;
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size += aligned_size((u64)addr, sg->length);
 	}
 
@@ -2487,16 +2409,16 @@ static int intel_nontranslate_map_sg(str
 
 	for_each_sg(sglist, sg, nelems, i) {
 		BUG_ON(!sg_page(sg));
-		sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 		sg->dma_length = sg->length;
 	}
 	return nelems;
 }
 
-int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
-		 int dir)
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+			enum dma_data_direction dir, struct dma_attrs *attrs)
 {
-	void *addr;
+	phys_addr_t addr;
 	int i;
 	struct pci_dev *pdev = to_pci_dev(hwdev);
 	struct dmar_domain *domain;
@@ -2520,8 +2442,7 @@ int intel_map_sg(struct device *hwdev, s
 	iommu = domain_get_iommu(domain);
 
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
-		addr = (void *)virt_to_phys(addr);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size += aligned_size((u64)addr, sg->length);
 	}
 
@@ -2544,12 +2465,11 @@ int intel_map_sg(struct device *hwdev, s
 	start_addr = iova->pfn_lo << PAGE_SHIFT;
 	offset = 0;
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
-		addr = (void *)virt_to_phys(addr);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size = aligned_size((u64)addr, sg->length);
 		ret = domain_page_mapping(domain, start_addr + offset,
-			((u64)addr) & PAGE_MASK,
-			size, prot);
+					  ((u64)addr) & PHYSICAL_PAGE_MASK,
+					  size, prot);
 		if (ret) {
 			/*  clear the page */
 			dma_pte_clear_range(domain, start_addr,
@@ -2574,13 +2494,19 @@ int intel_map_sg(struct device *hwdev, s
 	return nelems;
 }
 
-static struct dma_mapping_ops intel_dma_ops = {
+static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return !dma_addr;
+}
+
+struct dma_map_ops intel_dma_ops = {
 	.alloc_coherent = intel_alloc_coherent,
 	.free_coherent = intel_free_coherent,
-	.map_single = intel_map_single,
-	.unmap_single = intel_unmap_single,
 	.map_sg = intel_map_sg,
 	.unmap_sg = intel_unmap_sg,
+	.map_page = intel_map_page,
+	.unmap_page = intel_unmap_page,
+	.mapping_error = intel_mapping_error,
 };
 
 static inline int iommu_domain_cache_init(void)
@@ -2707,6 +2633,150 @@ static void __init init_no_remapping_dev
 	}
 }
 
+#ifdef CONFIG_SUSPEND
+static int init_iommu_hw(void)
+{
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu = NULL;
+
+	for_each_active_iommu(iommu, drhd)
+		if (iommu->qi)
+			dmar_reenable_qi(iommu);
+
+	for_each_active_iommu(iommu, drhd) {
+		iommu_flush_write_buffer(iommu);
+
+		iommu_set_root_entry(iommu);
+
+		iommu->flush.flush_context(iommu, 0, 0, 0,
+						DMA_CCMD_GLOBAL_INVL, 0);
+		iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+						DMA_TLB_GLOBAL_FLUSH, 0);
+		iommu_disable_protect_mem_regions(iommu);
+		iommu_enable_translation(iommu);
+	}
+
+	return 0;
+}
+
+static void iommu_flush_all(void)
+{
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu;
+
+	for_each_active_iommu(iommu, drhd) {
+		iommu->flush.flush_context(iommu, 0, 0, 0,
+						DMA_CCMD_GLOBAL_INVL, 0);
+		iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+						DMA_TLB_GLOBAL_FLUSH, 0);
+	}
+}
+
+static int iommu_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu = NULL;
+	unsigned long flag;
+
+	for_each_active_iommu(iommu, drhd) {
+		iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
+						 GFP_ATOMIC);
+		if (!iommu->iommu_state)
+			goto nomem;
+	}
+
+	iommu_flush_all();
+
+	for_each_active_iommu(iommu, drhd) {
+		iommu_disable_translation(iommu);
+
+		spin_lock_irqsave(&iommu->register_lock, flag);
+
+		iommu->iommu_state[SR_DMAR_FECTL_REG] =
+			readl(iommu->reg + DMAR_FECTL_REG);
+		iommu->iommu_state[SR_DMAR_FEDATA_REG] =
+			readl(iommu->reg + DMAR_FEDATA_REG);
+		iommu->iommu_state[SR_DMAR_FEADDR_REG] =
+			readl(iommu->reg + DMAR_FEADDR_REG);
+		iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
+			readl(iommu->reg + DMAR_FEUADDR_REG);
+
+		spin_unlock_irqrestore(&iommu->register_lock, flag);
+	}
+	return 0;
+
+nomem:
+	for_each_active_iommu(iommu, drhd)
+		kfree(iommu->iommu_state);
+
+	return -ENOMEM;
+}
+
+static int iommu_resume(struct sys_device *dev)
+{
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu = NULL;
+	unsigned long flag;
+
+	if (init_iommu_hw()) {
+		WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+		return -EIO;
+	}
+
+	for_each_active_iommu(iommu, drhd) {
+
+		spin_lock_irqsave(&iommu->register_lock, flag);
+
+		writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
+			iommu->reg + DMAR_FECTL_REG);
+		writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
+			iommu->reg + DMAR_FEDATA_REG);
+		writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
+			iommu->reg + DMAR_FEADDR_REG);
+		writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
+			iommu->reg + DMAR_FEUADDR_REG);
+
+		spin_unlock_irqrestore(&iommu->register_lock, flag);
+	}
+
+	for_each_active_iommu(iommu, drhd)
+		kfree(iommu->iommu_state);
+
+	return 0;
+}
+
+static struct sysdev_class iommu_sysclass = {
+	.name		= "iommu",
+	.resume		= iommu_resume,
+	.suspend	= iommu_suspend,
+};
+
+static struct sys_device device_iommu = {
+	.cls	= &iommu_sysclass,
+};
+
+static int __init init_iommu_sysfs(void)
+{
+	int error;
+
+	error = sysdev_class_register(&iommu_sysclass);
+	if (error)
+		return error;
+
+	error = sysdev_register(&device_iommu);
+	if (error)
+		sysdev_class_unregister(&iommu_sysclass);
+
+	return error;
+}
+
+#else
+static int __init init_iommu_sysfs(void)
+{
+	return 0;
+}
+#endif	/* CONFIG_PM */
+
 int __init intel_iommu_init(void)
 {
 	int ret = 0;
@@ -2742,6 +2812,7 @@ int __init intel_iommu_init(void)
 	init_timer(&unmap_timer);
 	force_iommu = 1;
 	dma_ops = &intel_dma_ops;
+	init_iommu_sysfs();
 
 	register_iommu(&intel_iommu_ops);
 
@@ -2758,6 +2829,7 @@ static int vm_domain_add_dev_info(struct
 	if (!info)
 		return -ENOMEM;
 
+	info->segment = pci_domain_nr(pdev->bus);
 	info->bus = pdev->bus->number;
 	info->devfn = pdev->devfn;
 	info->dev = pdev;
@@ -2772,6 +2844,33 @@ static int vm_domain_add_dev_info(struct
 	return 0;
 }
 
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+					   struct pci_dev *pdev)
+{
+	struct pci_dev *tmp, *parent;
+
+	if (!iommu || !pdev)
+		return;
+
+	/* dependent device detach */
+	tmp = pci_find_upstream_pcie_bridge(pdev);
+	/* Secondary interface's bus number and devfn 0 */
+	if (tmp) {
+		parent = pdev->bus->self;
+		while (parent != tmp) {
+			iommu_detach_dev(iommu, parent->bus->number,
+					 parent->devfn);
+			parent = parent->bus->self;
+		}
+		if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+			iommu_detach_dev(iommu,
+				tmp->subordinate->number, 0);
+		else /* this is a legacy PCI bridge */
+			iommu_detach_dev(iommu, tmp->bus->number,
+					 tmp->devfn);
+	}
+}
+
 static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
 					  struct pci_dev *pdev)
 {
@@ -2781,13 +2880,15 @@ static void vm_domain_remove_one_dev_inf
 	int found = 0;
 	struct list_head *entry, *tmp;
 
-	iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+	iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+				pdev->devfn);
 	if (!iommu)
 		return;
 
 	spin_lock_irqsave(&device_domain_lock, flags);
 	list_for_each_safe(entry, tmp, &domain->devices) {
 		info = list_entry(entry, struct device_domain_info, link);
+		/* No need to compare PCI domain; it has to be the same */
 		if (info->bus == pdev->bus->number &&
 		    info->devfn == pdev->devfn) {
 			list_del(&info->link);
@@ -2797,6 +2898,7 @@ static void vm_domain_remove_one_dev_inf
 			spin_unlock_irqrestore(&device_domain_lock, flags);
 
 			iommu_detach_dev(iommu, info->bus, info->devfn);
+			iommu_detach_dependent_devices(iommu, pdev);
 			free_devinfo_mem(info);
 
 			spin_lock_irqsave(&device_domain_lock, flags);
@@ -2811,7 +2913,8 @@ static void vm_domain_remove_one_dev_inf
 		 * owned by this domain, clear this iommu in iommu_bmp
 		 * update iommu count and coherency
 		 */
-		if (device_to_iommu(info->bus, info->devfn) == iommu)
+		if (iommu == device_to_iommu(info->segment, info->bus,
+					    info->devfn))
 			found = 1;
 	}
 
@@ -2820,7 +2923,7 @@ static void vm_domain_remove_one_dev_inf
 		spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
 		clear_bit(iommu->seq_id, &domain->iommu_bmp);
 		domain->iommu_count--;
-		domain_update_iommu_coherency(domain);
+		domain_update_iommu_cap(domain);
 		spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
 	}
 
@@ -2844,17 +2947,18 @@ static void vm_domain_remove_all_dev_inf
 
 		spin_unlock_irqrestore(&device_domain_lock, flags1);
 
-		iommu = device_to_iommu(info->bus, info->devfn);
+		iommu = device_to_iommu(info->segment, info->bus, info->devfn);
 		iommu_detach_dev(iommu, info->bus, info->devfn);
+		iommu_detach_dependent_devices(iommu, info->dev);
 
 		/* clear this iommu in iommu_bmp, update iommu count
-		 * and coherency
+		 * and capabilities
 		 */
 		spin_lock_irqsave(&domain->iommu_lock, flags2);
 		if (test_and_clear_bit(iommu->seq_id,
 				       &domain->iommu_bmp)) {
 			domain->iommu_count--;
-			domain_update_iommu_coherency(domain);
+			domain_update_iommu_cap(domain);
 		}
 		spin_unlock_irqrestore(&domain->iommu_lock, flags2);
 
@@ -3031,7 +3135,8 @@ static int intel_iommu_attach_device(str
 		}
 	}
 
-	iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+	iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+				pdev->devfn);
 	if (!iommu)
 		return -ENODEV;
 
@@ -3077,6 +3182,8 @@ static int intel_iommu_map_range(struct
 		prot |= DMA_PTE_READ;
 	if (iommu_prot & IOMMU_WRITE)
 		prot |= DMA_PTE_WRITE;
+	if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+		prot |= DMA_PTE_SNP;
 
 	max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
 	if (dmar_domain->max_addr < max_addr) {
@@ -3130,6 +3237,17 @@ static phys_addr_t intel_iommu_iova_to_p
 	return phys;
 }
 
+static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+				      unsigned long cap)
+{
+	struct dmar_domain *dmar_domain = domain->priv;
+
+	if (cap == IOMMU_CAP_CACHE_COHERENCY)
+		return dmar_domain->iommu_snooping;
+
+	return 0;
+}
+
 static struct iommu_ops intel_iommu_ops = {
 	.domain_init	= intel_iommu_domain_init,
 	.domain_destroy = intel_iommu_domain_destroy,
@@ -3138,6 +3256,7 @@ static struct iommu_ops intel_iommu_ops
 	.map		= intel_iommu_map_range,
 	.unmap		= intel_iommu_unmap_range,
 	.iova_to_phys	= intel_iommu_iova_to_phys,
+	.domain_has_cap = intel_iommu_domain_has_cap,
 };
 
 static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/intr_remapping.c linux-libre-2.6.30-gnu1/drivers/pci/intr_remapping.c
--- linux-libre-2.6.29-gnu1/drivers/pci/intr_remapping.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/intr_remapping.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,8 +6,10 @@
 #include <linux/irq.h>
 #include <asm/io_apic.h>
 #include <asm/smp.h>
+#include <asm/cpu.h>
 #include <linux/intel-iommu.h>
 #include "intr_remapping.h"
+#include <acpi/acpi.h>
 
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static int ir_ioapic_num;
@@ -20,7 +22,7 @@ struct irq_2_iommu {
 	u8  irte_mask;
 };
 
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
 static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
 {
 	struct irq_2_iommu *iommu;
@@ -116,21 +118,22 @@ int get_irte(int irq, struct irte *entry
 {
 	int index;
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
 	if (!entry)
 		return -1;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
 	index = irq_iommu->irte_index + irq_iommu->sub_handle;
 	*entry = *(irq_iommu->iommu->ir_table->base + index);
 
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 	return 0;
 }
 
@@ -140,6 +143,7 @@ int alloc_irte(struct intel_iommu *iommu
 	struct irq_2_iommu *irq_iommu;
 	u16 index, start_index;
 	unsigned int mask = 0;
+	unsigned long flags;
 	int i;
 
 	if (!count)
@@ -169,7 +173,7 @@ int alloc_irte(struct intel_iommu *iommu
 		return -1;
 	}
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	do {
 		for (i = index; i < index + count; i++)
 			if  (table->base[i].present)
@@ -181,7 +185,7 @@ int alloc_irte(struct intel_iommu *iommu
 		index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
 
 		if (index == start_index) {
-			spin_unlock(&irq_2_ir_lock);
+			spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 			printk(KERN_ERR "can't allocate an IRTE\n");
 			return -1;
 		}
@@ -192,7 +196,7 @@ int alloc_irte(struct intel_iommu *iommu
 
 	irq_iommu = irq_2_iommu_alloc(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		printk(KERN_ERR "can't allocate irq_2_iommu\n");
 		return -1;
 	}
@@ -202,7 +206,7 @@ int alloc_irte(struct intel_iommu *iommu
 	irq_iommu->sub_handle = 0;
 	irq_iommu->irte_mask = mask;
 
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return index;
 }
@@ -222,30 +226,32 @@ int map_irq_to_irte_handle(int irq, u16
 {
 	int index;
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
 	*sub_handle = irq_iommu->sub_handle;
 	index = irq_iommu->irte_index;
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 	return index;
 }
 
 int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
 {
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 
 	irq_iommu = irq_2_iommu_alloc(irq);
 
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		printk(KERN_ERR "can't allocate irq_2_iommu\n");
 		return -1;
 	}
@@ -255,7 +261,7 @@ int set_irte_irq(int irq, struct intel_i
 	irq_iommu->sub_handle = subhandle;
 	irq_iommu->irte_mask = 0;
 
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return 0;
 }
@@ -263,11 +269,12 @@ int set_irte_irq(int irq, struct intel_i
 int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
 {
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
@@ -276,7 +283,7 @@ int clear_irte_irq(int irq, struct intel
 	irq_iommu->sub_handle = 0;
 	irq_2_iommu(irq)->irte_mask = 0;
 
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return 0;
 }
@@ -288,11 +295,12 @@ int modify_irte(int irq, struct irte *ir
 	struct irte *irte;
 	struct intel_iommu *iommu;
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
@@ -301,11 +309,11 @@ int modify_irte(int irq, struct irte *ir
 	index = irq_iommu->irte_index + irq_iommu->sub_handle;
 	irte = &iommu->ir_table->base[index];
 
-	set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
+	set_64bit((unsigned long *)irte, irte_modified->low);
 	__iommu_flush_cache(iommu, irte, sizeof(*irte));
 
 	rc = qi_flush_iec(iommu, index, 0);
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return rc;
 }
@@ -316,11 +324,12 @@ int flush_irte(int irq)
 	int index;
 	struct intel_iommu *iommu;
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
@@ -329,7 +338,7 @@ int flush_irte(int irq)
 	index = irq_iommu->irte_index + irq_iommu->sub_handle;
 
 	rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return rc;
 }
@@ -362,11 +371,12 @@ int free_irte(int irq)
 	struct irte *irte;
 	struct intel_iommu *iommu;
 	struct irq_2_iommu *irq_iommu;
+	unsigned long flags;
 
-	spin_lock(&irq_2_ir_lock);
+	spin_lock_irqsave(&irq_2_ir_lock, flags);
 	irq_iommu = valid_irq_2_iommu(irq);
 	if (!irq_iommu) {
-		spin_unlock(&irq_2_ir_lock);
+		spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 		return -1;
 	}
 
@@ -377,7 +387,7 @@ int free_irte(int irq)
 
 	if (!irq_iommu->sub_handle) {
 		for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
-			set_64bit((unsigned long *)irte, 0);
+			set_64bit((unsigned long *)(irte + i), 0);
 		rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
 	}
 
@@ -386,7 +396,7 @@ int free_irte(int irq)
 	irq_iommu->sub_handle = 0;
 	irq_iommu->irte_mask = 0;
 
-	spin_unlock(&irq_2_ir_lock);
+	spin_unlock_irqrestore(&irq_2_ir_lock, flags);
 
 	return rc;
 }
@@ -406,12 +416,27 @@ static void iommu_set_intr_remapping(str
 
 	/* Set interrupt-remapping table pointer */
 	cmd = iommu->gcmd | DMA_GCMD_SIRTP;
+	iommu->gcmd |= DMA_GCMD_SIRTP;
 	writel(cmd, iommu->reg + DMAR_GCMD_REG);
 
 	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
 		      readl, (sts & DMA_GSTS_IRTPS), sts);
 	spin_unlock_irqrestore(&iommu->register_lock, flags);
 
+	if (mode == 0) {
+		spin_lock_irqsave(&iommu->register_lock, flags);
+
+		/* enable comaptiblity format interrupt pass through */
+		cmd = iommu->gcmd | DMA_GCMD_CFI;
+		iommu->gcmd |= DMA_GCMD_CFI;
+		writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+		IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+			      readl, (sts & DMA_GSTS_CFIS), sts);
+
+		spin_unlock_irqrestore(&iommu->register_lock, flags);
+	}
+
 	/*
 	 * global invalidation of interrupt entry cache before enabling
 	 * interrupt-remapping.
@@ -438,12 +463,12 @@ static int setup_intr_remapping(struct i
 	struct page *pages;
 
 	ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
-					     GFP_KERNEL);
+					     GFP_ATOMIC);
 
 	if (!iommu->ir_table)
 		return -ENOMEM;
 
-	pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
+	pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
 
 	if (!pages) {
 		printk(KERN_ERR "failed to allocate pages of order %d\n",
@@ -458,11 +483,68 @@ static int setup_intr_remapping(struct i
 	return 0;
 }
 
+/*
+ * Disable Interrupt Remapping.
+ */
+static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
+{
+	unsigned long flags;
+	u32 sts;
+
+	if (!ecap_ir_support(iommu->ecap))
+		return;
+
+	/*
+	 * global invalidation of interrupt entry cache before disabling
+	 * interrupt-remapping.
+	 */
+	qi_global_iec(iommu);
+
+	spin_lock_irqsave(&iommu->register_lock, flags);
+
+	sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+	if (!(sts & DMA_GSTS_IRES))
+		goto end;
+
+	iommu->gcmd &= ~DMA_GCMD_IRE;
+	writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+		      readl, !(sts & DMA_GSTS_IRES), sts);
+
+end:
+	spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
 int __init enable_intr_remapping(int eim)
 {
 	struct dmar_drhd_unit *drhd;
 	int setup = 0;
 
+	for_each_drhd_unit(drhd) {
+		struct intel_iommu *iommu = drhd->iommu;
+
+		/*
+		 * If the queued invalidation is already initialized,
+		 * shouldn't disable it.
+		 */
+		if (iommu->qi)
+			continue;
+
+		/*
+		 * Clear previous faults.
+		 */
+		dmar_fault(-1, iommu);
+
+		/*
+		 * Disable intr remapping and queued invalidation, if already
+		 * enabled prior to OS handover.
+		 */
+		iommu_disable_intr_remapping(iommu);
+
+		dmar_disable_qi(iommu);
+	}
+
 	/*
 	 * check for the Interrupt-remapping support
 	 */
@@ -586,3 +668,54 @@ int __init parse_ioapics_under_ir(void)
 
 	return ir_supported;
 }
+
+void disable_intr_remapping(void)
+{
+	struct dmar_drhd_unit *drhd;
+	struct intel_iommu *iommu = NULL;
+
+	/*
+	 * Disable Interrupt-remapping for all the DRHD's now.
+	 */
+	for_each_iommu(iommu, drhd) {
+		if (!ecap_ir_support(iommu->ecap))
+			continue;
+
+		iommu_disable_intr_remapping(iommu);
+	}
+}
+
+int reenable_intr_remapping(int eim)
+{
+	struct dmar_drhd_unit *drhd;
+	int setup = 0;
+	struct intel_iommu *iommu = NULL;
+
+	for_each_iommu(iommu, drhd)
+		if (iommu->qi)
+			dmar_reenable_qi(iommu);
+
+	/*
+	 * Setup Interrupt-remapping for all the DRHD's now.
+	 */
+	for_each_iommu(iommu, drhd) {
+		if (!ecap_ir_support(iommu->ecap))
+			continue;
+
+		/* Set up interrupt remapping for iommu.*/
+		iommu_set_intr_remapping(iommu, eim);
+		setup = 1;
+	}
+
+	if (!setup)
+		goto error;
+
+	return 0;
+
+error:
+	/*
+	 * handle error condition gracefully here!
+	 */
+	return -1;
+}
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/iov.c linux-libre-2.6.30-gnu1/drivers/pci/iov.c
--- linux-libre-2.6.29-gnu1/drivers/pci/iov.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/pci/iov.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,681 @@
+/*
+ * drivers/pci/iov.c
+ *
+ * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
+ *
+ * PCI Express I/O Virtualization (IOV) support.
+ *   Single Root IOV 1.0
+ */
+
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include "pci.h"
+
+#define VIRTFN_ID_LEN	16
+
+static inline u8 virtfn_bus(struct pci_dev *dev, int id)
+{
+	return dev->bus->number + ((dev->devfn + dev->sriov->offset +
+				    dev->sriov->stride * id) >> 8);
+}
+
+static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
+{
+	return (dev->devfn + dev->sriov->offset +
+		dev->sriov->stride * id) & 0xff;
+}
+
+static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
+{
+	int rc;
+	struct pci_bus *child;
+
+	if (bus->number == busnr)
+		return bus;
+
+	child = pci_find_bus(pci_domain_nr(bus), busnr);
+	if (child)
+		return child;
+
+	child = pci_add_new_bus(bus, NULL, busnr);
+	if (!child)
+		return NULL;
+
+	child->subordinate = busnr;
+	child->dev.parent = bus->bridge;
+	rc = pci_bus_add_child(child);
+	if (rc) {
+		pci_remove_bus(child);
+		return NULL;
+	}
+
+	return child;
+}
+
+static void virtfn_remove_bus(struct pci_bus *bus, int busnr)
+{
+	struct pci_bus *child;
+
+	if (bus->number == busnr)
+		return;
+
+	child = pci_find_bus(pci_domain_nr(bus), busnr);
+	BUG_ON(!child);
+
+	if (list_empty(&child->devices))
+		pci_remove_bus(child);
+}
+
+static int virtfn_add(struct pci_dev *dev, int id, int reset)
+{
+	int i;
+	int rc;
+	u64 size;
+	char buf[VIRTFN_ID_LEN];
+	struct pci_dev *virtfn;
+	struct resource *res;
+	struct pci_sriov *iov = dev->sriov;
+
+	virtfn = alloc_pci_dev();
+	if (!virtfn)
+		return -ENOMEM;
+
+	mutex_lock(&iov->dev->sriov->lock);
+	virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+	if (!virtfn->bus) {
+		kfree(virtfn);
+		mutex_unlock(&iov->dev->sriov->lock);
+		return -ENOMEM;
+	}
+	virtfn->devfn = virtfn_devfn(dev, id);
+	virtfn->vendor = dev->vendor;
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
+	pci_setup_device(virtfn);
+	virtfn->dev.parent = dev->dev.parent;
+
+	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+		res = dev->resource + PCI_IOV_RESOURCES + i;
+		if (!res->parent)
+			continue;
+		virtfn->resource[i].name = pci_name(virtfn);
+		virtfn->resource[i].flags = res->flags;
+		size = resource_size(res);
+		do_div(size, iov->total);
+		virtfn->resource[i].start = res->start + size * id;
+		virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
+		rc = request_resource(res, &virtfn->resource[i]);
+		BUG_ON(rc);
+	}
+
+	if (reset)
+		pci_execute_reset_function(virtfn);
+
+	pci_device_add(virtfn, virtfn->bus);
+	mutex_unlock(&iov->dev->sriov->lock);
+
+	virtfn->physfn = pci_dev_get(dev);
+	virtfn->is_virtfn = 1;
+
+	rc = pci_bus_add_device(virtfn);
+	if (rc)
+		goto failed1;
+	sprintf(buf, "virtfn%u", id);
+	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+	if (rc)
+		goto failed1;
+	rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
+	if (rc)
+		goto failed2;
+
+	kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
+
+	return 0;
+
+failed2:
+	sysfs_remove_link(&dev->dev.kobj, buf);
+failed1:
+	pci_dev_put(dev);
+	mutex_lock(&iov->dev->sriov->lock);
+	pci_remove_bus_device(virtfn);
+	virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+	mutex_unlock(&iov->dev->sriov->lock);
+
+	return rc;
+}
+
+static void virtfn_remove(struct pci_dev *dev, int id, int reset)
+{
+	char buf[VIRTFN_ID_LEN];
+	struct pci_bus *bus;
+	struct pci_dev *virtfn;
+	struct pci_sriov *iov = dev->sriov;
+
+	bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id));
+	if (!bus)
+		return;
+
+	virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
+	if (!virtfn)
+		return;
+
+	pci_dev_put(virtfn);
+
+	if (reset) {
+		device_release_driver(&virtfn->dev);
+		pci_execute_reset_function(virtfn);
+	}
+
+	sprintf(buf, "virtfn%u", id);
+	sysfs_remove_link(&dev->dev.kobj, buf);
+	sysfs_remove_link(&virtfn->dev.kobj, "physfn");
+
+	mutex_lock(&iov->dev->sriov->lock);
+	pci_remove_bus_device(virtfn);
+	virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+	mutex_unlock(&iov->dev->sriov->lock);
+
+	pci_dev_put(dev);
+}
+
+static int sriov_migration(struct pci_dev *dev)
+{
+	u16 status;
+	struct pci_sriov *iov = dev->sriov;
+
+	if (!iov->nr_virtfn)
+		return 0;
+
+	if (!(iov->cap & PCI_SRIOV_CAP_VFM))
+		return 0;
+
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status);
+	if (!(status & PCI_SRIOV_STATUS_VFM))
+		return 0;
+
+	schedule_work(&iov->mtask);
+
+	return 1;
+}
+
+static void sriov_migration_task(struct work_struct *work)
+{
+	int i;
+	u8 state;
+	u16 status;
+	struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask);
+
+	for (i = iov->initial; i < iov->nr_virtfn; i++) {
+		state = readb(iov->mstate + i);
+		if (state == PCI_SRIOV_VFM_MI) {
+			writeb(PCI_SRIOV_VFM_AV, iov->mstate + i);
+			state = readb(iov->mstate + i);
+			if (state == PCI_SRIOV_VFM_AV)
+				virtfn_add(iov->self, i, 1);
+		} else if (state == PCI_SRIOV_VFM_MO) {
+			virtfn_remove(iov->self, i, 1);
+			writeb(PCI_SRIOV_VFM_UA, iov->mstate + i);
+			state = readb(iov->mstate + i);
+			if (state == PCI_SRIOV_VFM_AV)
+				virtfn_add(iov->self, i, 0);
+		}
+	}
+
+	pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status);
+	status &= ~PCI_SRIOV_STATUS_VFM;
+	pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status);
+}
+
+static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn)
+{
+	int bir;
+	u32 table;
+	resource_size_t pa;
+	struct pci_sriov *iov = dev->sriov;
+
+	if (nr_virtfn <= iov->initial)
+		return 0;
+
+	pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table);
+	bir = PCI_SRIOV_VFM_BIR(table);
+	if (bir > PCI_STD_RESOURCE_END)
+		return -EIO;
+
+	table = PCI_SRIOV_VFM_OFFSET(table);
+	if (table + nr_virtfn > pci_resource_len(dev, bir))
+		return -EIO;
+
+	pa = pci_resource_start(dev, bir) + table;
+	iov->mstate = ioremap(pa, nr_virtfn);
+	if (!iov->mstate)
+		return -ENOMEM;
+
+	INIT_WORK(&iov->mtask, sriov_migration_task);
+
+	iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR;
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+	return 0;
+}
+
+static void sriov_disable_migration(struct pci_dev *dev)
+{
+	struct pci_sriov *iov = dev->sriov;
+
+	iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+	cancel_work_sync(&iov->mtask);
+	iounmap(iov->mstate);
+}
+
+static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
+{
+	int rc;
+	int i, j;
+	int nres;
+	u16 offset, stride, initial;
+	struct resource *res;
+	struct pci_dev *pdev;
+	struct pci_sriov *iov = dev->sriov;
+
+	if (!nr_virtfn)
+		return 0;
+
+	if (iov->nr_virtfn)
+		return -EINVAL;
+
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial);
+	if (initial > iov->total ||
+	    (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total)))
+		return -EIO;
+
+	if (nr_virtfn < 0 || nr_virtfn > iov->total ||
+	    (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial)))
+		return -EINVAL;
+
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn);
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &offset);
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &stride);
+	if (!offset || (nr_virtfn > 1 && !stride))
+		return -EIO;
+
+	nres = 0;
+	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+		res = dev->resource + PCI_IOV_RESOURCES + i;
+		if (res->parent)
+			nres++;
+	}
+	if (nres != iov->nres) {
+		dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n");
+		return -ENOMEM;
+	}
+
+	iov->offset = offset;
+	iov->stride = stride;
+
+	if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) {
+		dev_err(&dev->dev, "SR-IOV: bus number out of range\n");
+		return -ENOMEM;
+	}
+
+	if (iov->link != dev->devfn) {
+		pdev = pci_get_slot(dev->bus, iov->link);
+		if (!pdev)
+			return -ENODEV;
+
+		pci_dev_put(pdev);
+
+		if (!pdev->is_physfn)
+			return -ENODEV;
+
+		rc = sysfs_create_link(&dev->dev.kobj,
+					&pdev->dev.kobj, "dep_link");
+		if (rc)
+			return rc;
+	}
+
+	iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
+	pci_block_user_cfg_access(dev);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+	msleep(100);
+	pci_unblock_user_cfg_access(dev);
+
+	iov->initial = initial;
+	if (nr_virtfn < initial)
+		initial = nr_virtfn;
+
+	for (i = 0; i < initial; i++) {
+		rc = virtfn_add(dev, i, 0);
+		if (rc)
+			goto failed;
+	}
+
+	if (iov->cap & PCI_SRIOV_CAP_VFM) {
+		rc = sriov_enable_migration(dev, nr_virtfn);
+		if (rc)
+			goto failed;
+	}
+
+	kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE);
+	iov->nr_virtfn = nr_virtfn;
+
+	return 0;
+
+failed:
+	for (j = 0; j < i; j++)
+		virtfn_remove(dev, j, 0);
+
+	iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+	pci_block_user_cfg_access(dev);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+	ssleep(1);
+	pci_unblock_user_cfg_access(dev);
+
+	if (iov->link != dev->devfn)
+		sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+	return rc;
+}
+
+static void sriov_disable(struct pci_dev *dev)
+{
+	int i;
+	struct pci_sriov *iov = dev->sriov;
+
+	if (!iov->nr_virtfn)
+		return;
+
+	if (iov->cap & PCI_SRIOV_CAP_VFM)
+		sriov_disable_migration(dev);
+
+	for (i = 0; i < iov->nr_virtfn; i++)
+		virtfn_remove(dev, i, 0);
+
+	iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+	pci_block_user_cfg_access(dev);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+	ssleep(1);
+	pci_unblock_user_cfg_access(dev);
+
+	if (iov->link != dev->devfn)
+		sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+	iov->nr_virtfn = 0;
+}
+
+static int sriov_init(struct pci_dev *dev, int pos)
+{
+	int i;
+	int rc;
+	int nres;
+	u32 pgsz;
+	u16 ctrl, total, offset, stride;
+	struct pci_sriov *iov;
+	struct resource *res;
+	struct pci_dev *pdev;
+
+	if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
+	    dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
+		return -ENODEV;
+
+	pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
+	if (ctrl & PCI_SRIOV_CTRL_VFE) {
+		pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0);
+		ssleep(1);
+	}
+
+	pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &total);
+	if (!total)
+		return 0;
+
+	ctrl = 0;
+	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
+		if (pdev->is_physfn)
+			goto found;
+
+	pdev = NULL;
+	if (pci_ari_enabled(dev->bus))
+		ctrl |= PCI_SRIOV_CTRL_ARI;
+
+found:
+	pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
+	pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
+	pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
+	pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
+	if (!offset || (total > 1 && !stride))
+		return -EIO;
+
+	pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &pgsz);
+	i = PAGE_SHIFT > 12 ? PAGE_SHIFT - 12 : 0;
+	pgsz &= ~((1 << i) - 1);
+	if (!pgsz)
+		return -EIO;
+
+	pgsz &= ~(pgsz - 1);
+	pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
+
+	nres = 0;
+	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+		res = dev->resource + PCI_IOV_RESOURCES + i;
+		i += __pci_read_base(dev, pci_bar_unknown, res,
+				     pos + PCI_SRIOV_BAR + i * 4);
+		if (!res->flags)
+			continue;
+		if (resource_size(res) & (PAGE_SIZE - 1)) {
+			rc = -EIO;
+			goto failed;
+		}
+		res->end = res->start + resource_size(res) * total - 1;
+		nres++;
+	}
+
+	iov = kzalloc(sizeof(*iov), GFP_KERNEL);
+	if (!iov) {
+		rc = -ENOMEM;
+		goto failed;
+	}
+
+	iov->pos = pos;
+	iov->nres = nres;
+	iov->ctrl = ctrl;
+	iov->total = total;
+	iov->offset = offset;
+	iov->stride = stride;
+	iov->pgsz = pgsz;
+	iov->self = dev;
+	pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
+	pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
+
+	if (pdev)
+		iov->dev = pci_dev_get(pdev);
+	else {
+		iov->dev = dev;
+		mutex_init(&iov->lock);
+	}
+
+	dev->sriov = iov;
+	dev->is_physfn = 1;
+
+	return 0;
+
+failed:
+	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+		res = dev->resource + PCI_IOV_RESOURCES + i;
+		res->flags = 0;
+	}
+
+	return rc;
+}
+
+static void sriov_release(struct pci_dev *dev)
+{
+	BUG_ON(dev->sriov->nr_virtfn);
+
+	if (dev == dev->sriov->dev)
+		mutex_destroy(&dev->sriov->lock);
+	else
+		pci_dev_put(dev->sriov->dev);
+
+	kfree(dev->sriov);
+	dev->sriov = NULL;
+}
+
+static void sriov_restore_state(struct pci_dev *dev)
+{
+	int i;
+	u16 ctrl;
+	struct pci_sriov *iov = dev->sriov;
+
+	pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &ctrl);
+	if (ctrl & PCI_SRIOV_CTRL_VFE)
+		return;
+
+	for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
+		pci_update_resource(dev, i);
+
+	pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+	if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
+		msleep(100);
+}
+
+/**
+ * pci_iov_init - initialize the IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_iov_init(struct pci_dev *dev)
+{
+	int pos;
+
+	if (!dev->is_pcie)
+		return -ENODEV;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+	if (pos)
+		return sriov_init(dev, pos);
+
+	return -ENODEV;
+}
+
+/**
+ * pci_iov_release - release resources used by the IOV capability
+ * @dev: the PCI device
+ */
+void pci_iov_release(struct pci_dev *dev)
+{
+	if (dev->is_physfn)
+		sriov_release(dev);
+}
+
+/**
+ * pci_iov_resource_bar - get position of the SR-IOV BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ * @type: the BAR type to be filled in
+ *
+ * Returns position of the BAR encapsulated in the SR-IOV capability.
+ */
+int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+			 enum pci_bar_type *type)
+{
+	if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
+		return 0;
+
+	BUG_ON(!dev->is_physfn);
+
+	*type = pci_bar_unknown;
+
+	return dev->sriov->pos + PCI_SRIOV_BAR +
+		4 * (resno - PCI_IOV_RESOURCES);
+}
+
+/**
+ * pci_restore_iov_state - restore the state of the IOV capability
+ * @dev: the PCI device
+ */
+void pci_restore_iov_state(struct pci_dev *dev)
+{
+	if (dev->is_physfn)
+		sriov_restore_state(dev);
+}
+
+/**
+ * pci_iov_bus_range - find bus range used by Virtual Function
+ * @bus: the PCI bus
+ *
+ * Returns max number of buses (exclude current one) used by Virtual
+ * Functions.
+ */
+int pci_iov_bus_range(struct pci_bus *bus)
+{
+	int max = 0;
+	u8 busnr;
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		if (!dev->is_physfn)
+			continue;
+		busnr = virtfn_bus(dev, dev->sriov->total - 1);
+		if (busnr > max)
+			max = busnr;
+	}
+
+	return max ? max - bus->number : 0;
+}
+
+/**
+ * pci_enable_sriov - enable the SR-IOV capability
+ * @dev: the PCI device
+ * @nr_virtfn: number of virtual functions to enable
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
+{
+	might_sleep();
+
+	if (!dev->is_physfn)
+		return -ENODEV;
+
+	return sriov_enable(dev, nr_virtfn);
+}
+EXPORT_SYMBOL_GPL(pci_enable_sriov);
+
+/**
+ * pci_disable_sriov - disable the SR-IOV capability
+ * @dev: the PCI device
+ */
+void pci_disable_sriov(struct pci_dev *dev)
+{
+	might_sleep();
+
+	if (!dev->is_physfn)
+		return;
+
+	sriov_disable(dev);
+}
+EXPORT_SYMBOL_GPL(pci_disable_sriov);
+
+/**
+ * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration
+ * @dev: the PCI device
+ *
+ * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not.
+ *
+ * Physical Function driver is responsible to register IRQ handler using
+ * VF Migration Interrupt Message Number, and call this function when the
+ * interrupt is generated by the hardware.
+ */
+irqreturn_t pci_sriov_migration(struct pci_dev *dev)
+{
+	if (!dev->is_physfn)
+		return IRQ_NONE;
+
+	return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_migration);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/Kconfig linux-libre-2.6.30-gnu1/drivers/pci/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/pci/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -59,3 +59,13 @@ config HT_IRQ
 	   This allows native hypertransport devices to use interrupts.
 
 	   If unsure say Y.
+
+config PCI_IOV
+	bool "PCI IOV support"
+	depends on PCI
+	help
+	  I/O Virtualization is a PCI feature supported by some devices
+	  which allows them to create virtual devices which share their
+	  physical resources.
+
+	  If unsure, say N.
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/Makefile linux-libre-2.6.30-gnu1/drivers/pci/Makefile
--- linux-libre-2.6.29-gnu1/drivers/pci/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -29,6 +29,8 @@ obj-$(CONFIG_DMAR) += dmar.o iova.o inte
 
 obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o
 
+obj-$(CONFIG_PCI_IOV) += iov.o
+
 #
 # Some architectures use the generic PCI setup functions
 #
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/msi.c linux-libre-2.6.30-gnu1/drivers/pci/msi.c
--- linux-libre-2.6.29-gnu1/drivers/pci/msi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/msi.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,48 +27,53 @@ static int pci_msi_enable = 1;
 
 /* Arch hooks */
 
-int __attribute__ ((weak))
-arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
-{
-	return 0;
-}
-
-int __attribute__ ((weak))
-arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
+#ifndef arch_msi_check_device
+int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
 {
 	return 0;
 }
+#endif
 
-int __attribute__ ((weak))
-arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_setup_msi_irqs
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
 	struct msi_desc *entry;
 	int ret;
 
+	/*
+	 * If an architecture wants to support multiple MSI, it needs to
+	 * override arch_setup_msi_irqs()
+	 */
+	if (type == PCI_CAP_ID_MSI && nvec > 1)
+		return 1;
+
 	list_for_each_entry(entry, &dev->msi_list, list) {
 		ret = arch_setup_msi_irq(dev, entry);
-		if (ret)
+		if (ret < 0)
 			return ret;
+		if (ret > 0)
+			return -ENOSPC;
 	}
 
 	return 0;
 }
+#endif
 
-void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
-{
-	return;
-}
-
-void __attribute__ ((weak))
-arch_teardown_msi_irqs(struct pci_dev *dev)
+#ifndef arch_teardown_msi_irqs
+void arch_teardown_msi_irqs(struct pci_dev *dev)
 {
 	struct msi_desc *entry;
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		if (entry->irq != 0)
-			arch_teardown_msi_irq(entry->irq);
+		int i, nvec;
+		if (entry->irq == 0)
+			continue;
+		nvec = 1 << entry->msi_attrib.multiple;
+		for (i = 0; i < nvec; i++)
+			arch_teardown_msi_irq(entry->irq + i);
 	}
 }
+#endif
 
 static void __msi_set_enable(struct pci_dev *dev, int pos, int enable)
 {
@@ -111,27 +116,14 @@ static inline __attribute_const__ u32 ms
 	return (1 << (1 << x)) - 1;
 }
 
-static void msix_flush_writes(struct irq_desc *desc)
+static inline __attribute_const__ u32 msi_capable_mask(u16 control)
 {
-	struct msi_desc *entry;
+	return msi_mask((control >> 1) & 7);
+}
 
-	entry = get_irq_desc_msi(desc);
-	BUG_ON(!entry || !entry->dev);
-	switch (entry->msi_attrib.type) {
-	case PCI_CAP_ID_MSI:
-		/* nothing to do */
-		break;
-	case PCI_CAP_ID_MSIX:
-	{
-		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
-		readl(entry->mask_base + offset);
-		break;
-	}
-	default:
-		BUG();
-		break;
-	}
+static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
+{
+	return msi_mask((control >> 4) & 7);
 }
 
 /*
@@ -143,49 +135,71 @@ static void msix_flush_writes(struct irq
  * Returns 1 if it succeeded in masking the interrupt and 0 if the device
  * doesn't support MSI masking.
  */
-static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag)
+static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
 {
-	struct msi_desc *entry;
+	u32 mask_bits = desc->masked;
 
-	entry = get_irq_desc_msi(desc);
-	BUG_ON(!entry || !entry->dev);
-	switch (entry->msi_attrib.type) {
-	case PCI_CAP_ID_MSI:
-		if (entry->msi_attrib.maskbit) {
-			int pos;
-			u32 mask_bits;
+	if (!desc->msi_attrib.maskbit)
+		return;
 
-			pos = (long)entry->mask_base;
-			pci_read_config_dword(entry->dev, pos, &mask_bits);
-			mask_bits &= ~(mask);
-			mask_bits |= flag & mask;
-			pci_write_config_dword(entry->dev, pos, mask_bits);
-		} else {
-			return 0;
-		}
-		break;
-	case PCI_CAP_ID_MSIX:
-	{
-		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
-			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
-		writel(flag, entry->mask_base + offset);
-		readl(entry->mask_base + offset);
-		break;
-	}
-	default:
-		BUG();
-		break;
+	mask_bits &= ~mask;
+	mask_bits |= flag;
+	pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
+	desc->masked = mask_bits;
+}
+
+/*
+ * This internal function does not flush PCI writes to the device.
+ * All users must ensure that they read from the device before either
+ * assuming that the device state is up to date, or returning out of this
+ * file.  This saves a few milliseconds when initialising devices with lots
+ * of MSI-X interrupts.
+ */
+static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+{
+	u32 mask_bits = desc->masked;
+	unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
+					PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+	mask_bits &= ~1;
+	mask_bits |= flag;
+	writel(mask_bits, desc->mask_base + offset);
+	desc->masked = mask_bits;
+}
+
+static void msi_set_mask_bit(unsigned irq, u32 flag)
+{
+	struct msi_desc *desc = get_irq_msi(irq);
+
+	if (desc->msi_attrib.is_msix) {
+		msix_mask_irq(desc, flag);
+		readl(desc->mask_base);		/* Flush write to device */
+	} else {
+		unsigned offset = irq - desc->dev->irq;
+		msi_mask_irq(desc, 1 << offset, flag << offset);
 	}
-	entry->msi_attrib.masked = !!flag;
-	return 1;
+}
+
+void mask_msi_irq(unsigned int irq)
+{
+	msi_set_mask_bit(irq, 1);
+}
+
+void unmask_msi_irq(unsigned int irq)
+{
+	msi_set_mask_bit(irq, 0);
 }
 
 void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 {
 	struct msi_desc *entry = get_irq_desc_msi(desc);
-	switch(entry->msi_attrib.type) {
-	case PCI_CAP_ID_MSI:
-	{
+	if (entry->msi_attrib.is_msix) {
+		void __iomem *base = entry->mask_base +
+			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+		msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+		msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+		msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+	} else {
 		struct pci_dev *dev = entry->dev;
 		int pos = entry->msi_attrib.pos;
 		u16 data;
@@ -201,21 +215,6 @@ void read_msi_msg_desc(struct irq_desc *
 			pci_read_config_word(dev, msi_data_reg(pos, 0), &data);
 		}
 		msg->data = data;
-		break;
-	}
-	case PCI_CAP_ID_MSIX:
-	{
-		void __iomem *base;
-		base = entry->mask_base +
-			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
-		msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
- 		break;
- 	}
- 	default:
-		BUG();
 	}
 }
 
@@ -229,11 +228,25 @@ void read_msi_msg(unsigned int irq, stru
 void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
 {
 	struct msi_desc *entry = get_irq_desc_msi(desc);
-	switch (entry->msi_attrib.type) {
-	case PCI_CAP_ID_MSI:
-	{
+	if (entry->msi_attrib.is_msix) {
+		void __iomem *base;
+		base = entry->mask_base +
+			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+		writel(msg->address_lo,
+			base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+		writel(msg->address_hi,
+			base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+		writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
+	} else {
 		struct pci_dev *dev = entry->dev;
 		int pos = entry->msi_attrib.pos;
+		u16 msgctl;
+
+		pci_read_config_word(dev, msi_control_reg(pos), &msgctl);
+		msgctl &= ~PCI_MSI_FLAGS_QSIZE;
+		msgctl |= entry->msi_attrib.multiple << 4;
+		pci_write_config_word(dev, msi_control_reg(pos), msgctl);
 
 		pci_write_config_dword(dev, msi_lower_address_reg(pos),
 					msg->address_lo);
@@ -246,23 +259,6 @@ void write_msi_msg_desc(struct irq_desc
 			pci_write_config_word(dev, msi_data_reg(pos, 0),
 						msg->data);
 		}
-		break;
-	}
-	case PCI_CAP_ID_MSIX:
-	{
-		void __iomem *base;
-		base = entry->mask_base +
-			entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
-		writel(msg->address_lo,
-			base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		writel(msg->address_hi,
-			base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
-		break;
-	}
-	default:
-		BUG();
 	}
 	entry->msg = *msg;
 }
@@ -274,37 +270,18 @@ void write_msi_msg(unsigned int irq, str
 	write_msi_msg_desc(desc, msg);
 }
 
-void mask_msi_irq(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	msi_set_mask_bits(desc, 1, 1);
-	msix_flush_writes(desc);
-}
-
-void unmask_msi_irq(unsigned int irq)
-{
-	struct irq_desc *desc = irq_to_desc(irq);
-
-	msi_set_mask_bits(desc, 1, 0);
-	msix_flush_writes(desc);
-}
-
 static int msi_free_irqs(struct pci_dev* dev);
 
-static struct msi_desc* alloc_msi_entry(void)
+static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
 {
-	struct msi_desc *entry;
-
-	entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL);
-	if (!entry)
+	struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc)
 		return NULL;
 
-	INIT_LIST_HEAD(&entry->list);
-	entry->irq = 0;
-	entry->dev = NULL;
+	INIT_LIST_HEAD(&desc->list);
+	desc->dev = dev;
 
-	return entry;
+	return desc;
 }
 
 static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -328,15 +305,11 @@ static void __pci_restore_msi_state(stru
 	pci_intx_for_msi(dev, 0);
 	msi_set_enable(dev, 0);
 	write_msi_msg(dev->irq, &entry->msg);
-	if (entry->msi_attrib.maskbit) {
-		struct irq_desc *desc = irq_to_desc(dev->irq);
-		msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask,
-				  entry->msi_attrib.masked);
-	}
 
 	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+	msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
 	control &= ~PCI_MSI_FLAGS_QSIZE;
-	control |= PCI_MSI_FLAGS_ENABLE;
+	control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE;
 	pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
 }
 
@@ -354,9 +327,8 @@ static void __pci_restore_msix_state(str
 	msix_set_enable(dev, 0);
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		struct irq_desc *desc = irq_to_desc(entry->irq);
 		write_msi_msg(entry->irq, &entry->msg);
-		msi_set_mask_bits(desc, 1, entry->msi_attrib.masked);
+		msix_mask_irq(entry, entry->masked);
 	}
 
 	BUG_ON(list_empty(&dev->msi_list));
@@ -378,52 +350,48 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state)
 /**
  * msi_capability_init - configure device's MSI capability structure
  * @dev: pointer to the pci_dev data structure of MSI device function
+ * @nvec: number of interrupts to allocate
  *
- * Setup the MSI capability structure of device function with a single
- * MSI irq, regardless of device function is capable of handling
- * multiple messages. A return of zero indicates the successful setup
- * of an entry zero with the new MSI irq or non-zero for otherwise.
- **/
-static int msi_capability_init(struct pci_dev *dev)
+ * Setup the MSI capability structure of the device with the requested
+ * number of interrupts.  A return value of zero indicates the successful
+ * setup of an entry with the new MSI irq.  A negative return value indicates
+ * an error, and a positive return value indicates the number of interrupts
+ * which could have been allocated.
+ */
+static int msi_capability_init(struct pci_dev *dev, int nvec)
 {
 	struct msi_desc *entry;
 	int pos, ret;
 	u16 control;
+	unsigned mask;
 
 	msi_set_enable(dev, 0);	/* Ensure msi is disabled as I set it up */
 
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
 	/* MSI Entry Initialization */
-	entry = alloc_msi_entry();
+	entry = alloc_msi_entry(dev);
 	if (!entry)
 		return -ENOMEM;
 
-	entry->msi_attrib.type = PCI_CAP_ID_MSI;
+	entry->msi_attrib.is_msix = 0;
 	entry->msi_attrib.is_64 = is_64bit_address(control);
 	entry->msi_attrib.entry_nr = 0;
 	entry->msi_attrib.maskbit = is_mask_bit_support(control);
-	entry->msi_attrib.masked = 1;
 	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
 	entry->msi_attrib.pos = pos;
-	entry->dev = dev;
-	if (entry->msi_attrib.maskbit) {
-		unsigned int base, maskbits, temp;
 
-		base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
-		entry->mask_base = (void __iomem *)(long)base;
+	entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+	/* All MSIs are unmasked by default, Mask them all */
+	if (entry->msi_attrib.maskbit)
+		pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
+	mask = msi_capable_mask(control);
+	msi_mask_irq(entry, mask, mask);
 
-		/* All MSIs are unmasked by default, Mask them all */
-		pci_read_config_dword(dev, base, &maskbits);
-		temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
-		maskbits |= temp;
-		pci_write_config_dword(dev, base, maskbits);
-		entry->msi_attrib.maskbits_mask = temp;
-	}
 	list_add_tail(&entry->list, &dev->msi_list);
 
 	/* Configure MSI capability structure */
-	ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI);
+	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
 	if (ret) {
 		msi_free_irqs(dev);
 		return ret;
@@ -476,26 +444,26 @@ static int msix_capability_init(struct p
 
 	/* MSI-X Table Initialization */
 	for (i = 0; i < nvec; i++) {
-		entry = alloc_msi_entry();
+		entry = alloc_msi_entry(dev);
 		if (!entry)
 			break;
 
  		j = entries[i].entry;
-		entry->msi_attrib.type = PCI_CAP_ID_MSIX;
+		entry->msi_attrib.is_msix = 1;
 		entry->msi_attrib.is_64 = 1;
 		entry->msi_attrib.entry_nr = j;
-		entry->msi_attrib.maskbit = 1;
-		entry->msi_attrib.masked = 1;
 		entry->msi_attrib.default_irq = dev->irq;
 		entry->msi_attrib.pos = pos;
-		entry->dev = dev;
 		entry->mask_base = base;
+		msix_mask_irq(entry, 1);
 
 		list_add_tail(&entry->list, &dev->msi_list);
 	}
 
 	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
-	if (ret) {
+	if (ret < 0) {
+		/* If we had some success report the number of irqs
+		 * we succeeded in setting up. */
 		int avail = 0;
 		list_for_each_entry(entry, &dev->msi_list, list) {
 			if (entry->irq != 0) {
@@ -503,14 +471,13 @@ static int msix_capability_init(struct p
 			}
 		}
 
-		msi_free_irqs(dev);
+		if (avail != 0)
+			ret = avail;
+	}
 
-		/* If we had some success report the number of irqs
-		 * we succeeded in setting up.
-		 */
-		if (avail == 0)
-			avail = ret;
-		return avail;
+	if (ret) {
+		msi_free_irqs(dev);
+		return ret;
 	}
 
 	i = 0;
@@ -524,6 +491,12 @@ static int msix_capability_init(struct p
 	msix_set_enable(dev, 1);
 	dev->msix_enabled = 1;
 
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		int vector = entry->msi_attrib.entry_nr;
+		entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE +
+					PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+	}
+
 	return 0;
 }
 
@@ -575,39 +548,54 @@ static int pci_msi_check_device(struct p
 }
 
 /**
- * pci_enable_msi - configure device's MSI capability structure
- * @dev: pointer to the pci_dev data structure of MSI device function
+ * pci_enable_msi_block - configure device's MSI capability structure
+ * @dev: device to configure
+ * @nvec: number of interrupts to configure
  *
- * Setup the MSI capability structure of device function with
- * a single MSI irq upon its software driver call to request for
- * MSI mode enabled on its hardware device function. A return of zero
- * indicates the successful setup of an entry zero with the new MSI
- * irq or non-zero for otherwise.
- **/
-int pci_enable_msi(struct pci_dev* dev)
+ * Allocate IRQs for a device with the MSI capability.
+ * This function returns a negative errno if an error occurs.  If it
+ * is unable to allocate the number of interrupts requested, it returns
+ * the number of interrupts it might be able to allocate.  If it successfully
+ * allocates at least the number of interrupts requested, it returns 0 and
+ * updates the @dev's irq member to the lowest new interrupt number; the
+ * other interrupt numbers allocated to this device are consecutive.
+ */
+int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec)
 {
-	int status;
+	int status, pos, maxvec;
+	u16 msgctl;
 
-	status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI);
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+	if (!pos)
+		return -EINVAL;
+	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
+	maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1);
+	if (nvec > maxvec)
+		return maxvec;
+
+	status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
 	if (status)
 		return status;
 
 	WARN_ON(!!dev->msi_enabled);
 
-	/* Check whether driver already requested for MSI-X irqs */
+	/* Check whether driver already requested MSI-X irqs */
 	if (dev->msix_enabled) {
 		dev_info(&dev->dev, "can't enable MSI "
 			 "(MSI-X already enabled)\n");
 		return -EINVAL;
 	}
-	status = msi_capability_init(dev);
+
+	status = msi_capability_init(dev, nvec);
 	return status;
 }
-EXPORT_SYMBOL(pci_enable_msi);
+EXPORT_SYMBOL(pci_enable_msi_block);
 
-void pci_msi_shutdown(struct pci_dev* dev)
+void pci_msi_shutdown(struct pci_dev *dev)
 {
-	struct msi_desc *entry;
+	struct msi_desc *desc;
+	u32 mask;
+	u16 ctrl;
 
 	if (!pci_msi_enable || !dev || !dev->msi_enabled)
 		return;
@@ -617,19 +605,15 @@ void pci_msi_shutdown(struct pci_dev* de
 	dev->msi_enabled = 0;
 
 	BUG_ON(list_empty(&dev->msi_list));
-	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
-	/* Return the the pci reset with msi irqs unmasked */
-	if (entry->msi_attrib.maskbit) {
-		u32 mask = entry->msi_attrib.maskbits_mask;
-		struct irq_desc *desc = irq_to_desc(dev->irq);
-		msi_set_mask_bits(desc, mask, ~mask);
-	}
-	if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
-		return;
+	desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+	pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl);
+	mask = msi_capable_mask(ctrl);
+	msi_mask_irq(desc, mask, ~mask);
 
 	/* Restore dev->irq to its default pin-assertion irq */
-	dev->irq = entry->msi_attrib.default_irq;
+	dev->irq = desc->msi_attrib.default_irq;
 }
+
 void pci_disable_msi(struct pci_dev* dev)
 {
 	struct msi_desc *entry;
@@ -640,7 +624,7 @@ void pci_disable_msi(struct pci_dev* dev
 	pci_msi_shutdown(dev);
 
 	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
-	if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
+	if (entry->msi_attrib.is_msix)
 		return;
 
 	msi_free_irqs(dev);
@@ -652,14 +636,18 @@ static int msi_free_irqs(struct pci_dev*
 	struct msi_desc *entry, *tmp;
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		if (entry->irq)
-			BUG_ON(irq_has_action(entry->irq));
+		int i, nvec;
+		if (!entry->irq)
+			continue;
+		nvec = 1 << entry->msi_attrib.multiple;
+		for (i = 0; i < nvec; i++)
+			BUG_ON(irq_has_action(entry->irq + i));
 	}
 
 	arch_teardown_msi_irqs(dev);
 
 	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
-		if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) {
+		if (entry->msi_attrib.is_msix) {
 			writel(1, entry->mask_base + entry->msi_attrib.entry_nr
 				  * PCI_MSIX_ENTRY_SIZE
 				  + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
@@ -675,6 +663,23 @@ static int msi_free_irqs(struct pci_dev*
 }
 
 /**
+ * pci_msix_table_size - return the number of device's MSI-X table entries
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ */
+int pci_msix_table_size(struct pci_dev *dev)
+{
+	int pos;
+	u16 control;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (!pos)
+		return 0;
+
+	pci_read_config_word(dev, msi_control_reg(pos), &control);
+	return multi_msix_capable(control);
+}
+
+/**
  * pci_enable_msix - configure device's MSI-X capability structure
  * @dev: pointer to the pci_dev data structure of MSI-X device function
  * @entries: pointer to an array of MSI-X entries
@@ -691,9 +696,8 @@ static int msi_free_irqs(struct pci_dev*
  **/
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
-	int status, pos, nr_entries;
+	int status, nr_entries;
 	int i, j;
-	u16 control;
 
 	if (!entries)
  		return -EINVAL;
@@ -702,9 +706,7 @@ int pci_enable_msix(struct pci_dev* dev,
 	if (status)
 		return status;
 
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	pci_read_config_word(dev, msi_control_reg(pos), &control);
-	nr_entries = multi_msix_capable(control);
+	nr_entries = pci_msix_table_size(dev);
 	if (nvec > nr_entries)
 		return -EINVAL;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/msi.h linux-libre-2.6.30-gnu1/drivers/pci/msi.h
--- linux-libre-2.6.29-gnu1/drivers/pci/msi.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/msi.h	2009-06-09 23:05:27.000000000 -0400
@@ -20,14 +20,8 @@
 #define msi_mask_bits_reg(base, is64bit) \
 	( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
 #define msi_disable(control)		control &= ~PCI_MSI_FLAGS_ENABLE
-#define multi_msi_capable(control) \
-	(1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
-#define multi_msi_enable(control, num) \
-	control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
 #define is_64bit_address(control)	(!!(control & PCI_MSI_FLAGS_64BIT))
 #define is_mask_bit_support(control)	(!!(control & PCI_MSI_FLAGS_MASKBIT))
-#define msi_enable(control, num) multi_msi_enable(control, num); \
-	control |= PCI_MSI_FLAGS_ENABLE
 
 #define msix_table_offset_reg(base)	(base + 0x04)
 #define msix_pba_offset_reg(base)	(base + 0x08)
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pci-acpi.c linux-libre-2.6.30-gnu1/drivers/pci/pci-acpi.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pci-acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pci-acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,221 +18,6 @@
 #include <linux/pci-acpi.h>
 #include "pci.h"
 
-struct acpi_osc_data {
-	acpi_handle handle;
-	u32 support_set;
-	u32 control_set;
-	u32 control_query;
-	int is_queried;
-	struct list_head sibiling;
-};
-static LIST_HEAD(acpi_osc_data_list);
-
-struct acpi_osc_args {
-	u32 capbuf[3];
-};
-
-static DEFINE_MUTEX(pci_acpi_lock);
-
-static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
-{
-	struct acpi_osc_data *data;
-
-	list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
-		if (data->handle == handle)
-			return data;
-	}
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return NULL;
-	INIT_LIST_HEAD(&data->sibiling);
-	data->handle = handle;
-	list_add_tail(&data->sibiling, &acpi_osc_data_list);
-	return data;
-}
-
-static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
-			  0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
-
-static acpi_status acpi_run_osc(acpi_handle handle,
-				struct acpi_osc_args *osc_args, u32 *retval)
-{
-	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, flags = osc_args->capbuf[OSC_QUERY_TYPE];
-
-	/* 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 *)osc_args->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 "Evaluate _OSC returns 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 fails\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 (flags & OSC_QUERY_ENABLE)
-				goto out_success;
-			printk(KERN_DEBUG "_OSC FW not grant req. control\n");
-			status = AE_SUPPORT;
-			goto out_kfree;
-		}
-		status = AE_ERROR;
-		goto out_kfree;
-	}
-out_success:
-	*retval = *((u32 *)(out_obj->buffer.pointer + 8));
-	status = AE_OK;
-
-out_kfree:
-	kfree(output.pointer);
-	return status;
-}
-
-static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
-{
-	acpi_status status;
-	u32 support_set, result;
-	struct acpi_osc_args osc_args;
-
-	/* do _OSC query for all possible controls */
-	support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
-	osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-	osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
-	osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
-
-	status = acpi_run_osc(osc_data->handle, &osc_args, &result);
-	if (ACPI_SUCCESS(status)) {
-		osc_data->support_set = support_set;
-		osc_data->control_query = result;
-		osc_data->is_queried = 1;
-	}
-
-	return status;
-}
-
-/*
- * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
- * @flags: Bitmask of flags to support
- *
- * See the ACPI spec for the definition of the flags
- */
-int pci_acpi_osc_support(acpi_handle handle, u32 flags)
-{
-	acpi_status status;
-	acpi_handle tmp;
-	struct acpi_osc_data *osc_data;
-	int rc = 0;
-
-	status = acpi_get_handle(handle, "_OSC", &tmp);
-	if (ACPI_FAILURE(status))
-		return -ENOTTY;
-
-	mutex_lock(&pci_acpi_lock);
-	osc_data = acpi_get_osc_data(handle);
-	if (!osc_data) {
-		printk(KERN_ERR "acpi osc data array is full\n");
-		rc = -ENOMEM;
-		goto out;
-	}
-
-	__acpi_query_osc(flags, osc_data);
-out:
-	mutex_unlock(&pci_acpi_lock);
-	return rc;
-}
-
-/**
- * pci_osc_control_set - commit requested control to Firmware
- * @handle: acpi_handle for the target ACPI object
- * @flags: driver's requested control bits
- *
- * Attempt to take control from Firmware on requested control bits.
- **/
-acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
-{
-	acpi_status status;
-	u32 control_req, control_set, result;
-	acpi_handle tmp;
-	struct acpi_osc_data *osc_data;
-	struct acpi_osc_args osc_args;
-
-	status = acpi_get_handle(handle, "_OSC", &tmp);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	mutex_lock(&pci_acpi_lock);
-	osc_data = acpi_get_osc_data(handle);
-	if (!osc_data) {
-		printk(KERN_ERR "acpi osc data array is full\n");
-		status = AE_ERROR;
-		goto out;
-	}
-
-	control_req = (flags & OSC_CONTROL_MASKS);
-	if (!control_req) {
-		status = AE_TYPE;
-		goto out;
-	}
-
-	/* No need to evaluate _OSC if the control was already granted. */
-	if ((osc_data->control_set & control_req) == control_req)
-		goto out;
-
-	if (!osc_data->is_queried) {
-		status = __acpi_query_osc(osc_data->support_set, osc_data);
-		if (ACPI_FAILURE(status))
-			goto out;
-	}
-
-	if ((osc_data->control_query & control_req) != control_req) {
-		status = AE_SUPPORT;
-		goto out;
-	}
-
-	control_set = osc_data->control_set | control_req;
-	osc_args.capbuf[OSC_QUERY_TYPE] = 0;
-	osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
-	osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
-	status = acpi_run_osc(handle, &osc_args, &result);
-	if (ACPI_SUCCESS(status))
-		osc_data->control_set = result;
-out:
-	mutex_unlock(&pci_acpi_lock);
-	return status;
-}
-EXPORT_SYMBOL(pci_osc_control_set);
-
 /*
  * _SxD returns the D-state with the highest power
  * (lowest D-state number) supported in the S-state "x".
@@ -386,12 +171,12 @@ static int __init acpi_pci_init(void)
 {
 	int ret;
 
-	if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
 		pci_no_msi();
 	}
 
-	if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
 		pcie_no_aspm();
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pci.c linux-libre-2.6.30-gnu1/drivers/pci/pci.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,6 +20,8 @@
 #include <linux/pm_wakeup.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
+#include <linux/device.h>
+#include <asm/setup.h>
 #include "pci.h"
 
 unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
@@ -426,7 +428,6 @@ static inline int platform_pci_sleep_wak
  *                           given PCI device
  * @dev: PCI device to handle.
  * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
- * @wait: If 'true', wait for the device to change its power state
  *
  * RETURN VALUE:
  * -EINVAL if the requested state is invalid.
@@ -435,12 +436,15 @@ static inline int platform_pci_sleep_wak
  * 0 if device already is in the requested state.
  * 0 if device's power state has been successfully changed.
  */
-static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
+static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
 	u16 pmcsr;
 	bool need_restore = false;
 
+	/* Check if we're already there */
+	if (dev->current_state == state)
+		return 0;
+
 	if (!dev->pm_cap)
 		return -EIO;
 
@@ -451,10 +455,7 @@ pci_raw_set_power_state(struct pci_dev *
 	 * Can enter D0 from any state, but if we can only go deeper 
 	 * to sleep if we're already in a low power state
 	 */
-	if (dev->current_state == state) {
-		/* we're already there */
-		return 0;
-	} else if (state != PCI_D0 && dev->current_state <= PCI_D3cold
+	if (state != PCI_D0 && dev->current_state <= PCI_D3cold
 	    && dev->current_state > state) {
 		dev_err(&dev->dev, "invalid power transition "
 			"(from state %d to %d)\n", dev->current_state, state);
@@ -481,10 +482,8 @@ pci_raw_set_power_state(struct pci_dev *
 		break;
 	case PCI_UNKNOWN: /* Boot-up */
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
-		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
+		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
 			need_restore = true;
-			wait = true;
-		}
 		/* Fall-through: force to D0 */
 	default:
 		pmcsr = 0;
@@ -494,9 +493,6 @@ pci_raw_set_power_state(struct pci_dev *
 	/* enter specified state */
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
 
-	if (!wait)
-		return 0;
-
 	/* Mandatory power management transition delays */
 	/* see PCI PM 1.1 5.6.1 table 18 */
 	if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
@@ -521,7 +517,7 @@ pci_raw_set_power_state(struct pci_dev *
 	if (need_restore)
 		pci_restore_bars(dev);
 
-	if (wait && dev->bus->self)
+	if (dev->bus->self)
 		pcie_aspm_pm_state_change(dev->bus->self);
 
 	return 0;
@@ -546,11 +542,59 @@ void pci_update_current_state(struct pci
 }
 
 /**
+ * pci_platform_power_transition - Use platform to change device power state
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+	int error;
+
+	if (platform_pci_power_manageable(dev)) {
+		error = platform_pci_set_power_state(dev, state);
+		if (!error)
+			pci_update_current_state(dev, state);
+	} else {
+		error = -ENODEV;
+		/* Fall back to PCI_D0 if native PM is not supported */
+		if (!dev->pm_cap)
+			dev->current_state = PCI_D0;
+	}
+
+	return error;
+}
+
+/**
+ * __pci_start_power_transition - Start power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+	if (state == PCI_D0)
+		pci_platform_power_transition(dev, PCI_D0);
+}
+
+/**
+ * __pci_complete_power_transition - Complete power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ *
+ * This function should not be called directly by device drivers.
+ */
+int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+	return state > PCI_D0 ?
+			pci_platform_power_transition(dev, state) : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to handle.
  * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
  *
- * Transition a device to a new power state, using the platform formware and/or
+ * Transition a device to a new power state, using the platform firmware and/or
  * the device's PCI PM registers.
  *
  * RETURN VALUE:
@@ -577,30 +621,21 @@ int pci_set_power_state(struct pci_dev *
 		 */
 		return 0;
 
-	if (state == PCI_D0 && platform_pci_power_manageable(dev)) {
-		/*
-		 * Allow the platform to change the state, for example via ACPI
-		 * _PR0, _PS0 and some such, but do not trust it.
-		 */
-		int ret = platform_pci_set_power_state(dev, PCI_D0);
-		if (!ret)
-			pci_update_current_state(dev, PCI_D0);
-	}
+	/* Check if we're already there */
+	if (dev->current_state == state)
+		return 0;
+
+	__pci_start_power_transition(dev, state);
+
 	/* This device is quirked not to be put into D3, so
 	   don't put it in D3 */
 	if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
 		return 0;
 
-	error = pci_raw_set_power_state(dev, state, true);
+	error = pci_raw_set_power_state(dev, state);
 
-	if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
-		/* Allow the platform to finalize the transition */
-		int ret = platform_pci_set_power_state(dev, state);
-		if (!ret) {
-			pci_update_current_state(dev, state);
-			error = 0;
-		}
-	}
+	if (!__pci_complete_power_transition(dev, state))
+		error = 0;
 
 	return error;
 }
@@ -645,11 +680,36 @@ pci_power_t pci_choose_state(struct pci_
 
 EXPORT_SYMBOL(pci_choose_state);
 
+#define PCI_EXP_SAVE_REGS	7
+
+#define pcie_cap_has_devctl(type, flags)	1
+#define pcie_cap_has_lnkctl(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 (type == PCI_EXP_TYPE_ROOT_PORT ||	\
+		  type == PCI_EXP_TYPE_ENDPOINT ||	\
+		  type == PCI_EXP_TYPE_LEG_END))
+#define pcie_cap_has_sltctl(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 ((type == PCI_EXP_TYPE_ROOT_PORT) ||	\
+		  (type == PCI_EXP_TYPE_DOWNSTREAM &&	\
+		   (flags & PCI_EXP_FLAGS_SLOT))))
+#define pcie_cap_has_rtctl(type, flags)			\
+		((flags & PCI_EXP_FLAGS_VERS) > 1 ||	\
+		 (type == PCI_EXP_TYPE_ROOT_PORT ||	\
+		  type == PCI_EXP_TYPE_RC_EC))
+#define pcie_cap_has_devctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+#define pcie_cap_has_lnkctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+#define pcie_cap_has_sltctl2(type, flags)		\
+		((flags & PCI_EXP_FLAGS_VERS) > 1)
+
 static int pci_save_pcie_state(struct pci_dev *dev)
 {
 	int pos, i = 0;
 	struct pci_cap_saved_state *save_state;
 	u16 *cap;
+	u16 flags;
 
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	if (pos <= 0)
@@ -657,15 +717,27 @@ static int pci_save_pcie_state(struct pc
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
 	if (!save_state) {
-		dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+		dev_err(&dev->dev, "buffer not found in %s\n", __func__);
 		return -ENOMEM;
 	}
 	cap = (u16 *)&save_state->data[0];
 
-	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
-	pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
+
+	if (pcie_cap_has_devctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]);
+	if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
+	if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
+	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
+	if (pcie_cap_has_devctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
+	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
+	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
+		pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
 
 	return 0;
 }
@@ -675,6 +747,7 @@ static void pci_restore_pcie_state(struc
 	int i = 0, pos;
 	struct pci_cap_saved_state *save_state;
 	u16 *cap;
+	u16 flags;
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
@@ -682,10 +755,22 @@ static void pci_restore_pcie_state(struc
 		return;
 	cap = (u16 *)&save_state->data[0];
 
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
-	pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
+	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
+
+	if (pcie_cap_has_devctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]);
+	if (pcie_cap_has_lnkctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
+	if (pcie_cap_has_sltctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
+	if (pcie_cap_has_rtctl(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
+	if (pcie_cap_has_devctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
+	if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
+	if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
+		pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
 }
 
 
@@ -700,7 +785,7 @@ static int pci_save_pcix_state(struct pc
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
 	if (!save_state) {
-		dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+		dev_err(&dev->dev, "buffer not found in %s\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -773,6 +858,7 @@ pci_restore_state(struct pci_dev *dev)
 	}
 	pci_restore_pcix_state(dev);
 	pci_restore_msi_state(dev);
+	pci_restore_iov_state(dev);
 
 	return 0;
 }
@@ -801,7 +887,7 @@ static int do_pci_enable_device(struct p
  */
 int pci_reenable_device(struct pci_dev *dev)
 {
-	if (atomic_read(&dev->enable_cnt))
+	if (pci_is_enabled(dev))
 		return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
 	return 0;
 }
@@ -999,7 +1085,7 @@ static void do_pci_disable_device(struct
  */
 void pci_disable_enabled_device(struct pci_dev *dev)
 {
-	if (atomic_read(&dev->enable_cnt))
+	if (pci_is_enabled(dev))
 		do_pci_disable_device(dev);
 }
 
@@ -1231,7 +1317,7 @@ int pci_prepare_to_sleep(struct pci_dev
 	if (target_state == PCI_POWER_ERROR)
 		return -EIO;
 
-	pci_enable_wake(dev, target_state, true);
+	pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
 
 	error = pci_set_power_state(dev, target_state);
 
@@ -1369,7 +1455,8 @@ void pci_allocate_cap_save_buffers(struc
 {
 	int error;
 
-	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16));
+	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
+					PCI_EXP_SAVE_REGS * sizeof(u16));
 	if (error)
 		dev_err(&dev->dev,
 			"unable to preallocate PCI Express save buffer\n");
@@ -1381,50 +1468,6 @@ void pci_allocate_cap_save_buffers(struc
 }
 
 /**
- * pci_restore_standard_config - restore standard config registers of PCI device
- * @dev: PCI device to handle
- *
- * This function assumes that the device's configuration space is accessible.
- * If the device needs to be powered up, the function will wait for it to
- * change the state.
- */
-int pci_restore_standard_config(struct pci_dev *dev)
-{
-	pci_power_t prev_state;
-	int error;
-
-	pci_update_current_state(dev, PCI_D0);
-
-	prev_state = dev->current_state;
-	if (prev_state == PCI_D0)
-		goto Restore;
-
-	error = pci_raw_set_power_state(dev, PCI_D0, false);
-	if (error)
-		return error;
-
-	/*
-	 * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
-	 * we've made this assumption forever and it appears to be universally
-	 * satisfied.
-	 */
-	switch(prev_state) {
-	case PCI_D3cold:
-	case PCI_D3hot:
-		mdelay(pci_pm_d3_delay);
-		break;
-	case PCI_D2:
-		udelay(PCI_PM_D2_DELAY);
-		break;
-	}
-
-	pci_update_current_state(dev, PCI_D0);
-
- Restore:
-	return dev->state_saved ? pci_restore_state(dev) : 0;
-}
-
-/**
  * pci_enable_ari - enable ARI forwarding if hardware support it
  * @dev: the PCI device
  */
@@ -1484,7 +1527,7 @@ pci_get_interrupt_pin(struct pci_dev *de
 	if (!pin)
 		return -1;
 
-	while (dev->bus->self) {
+	while (dev->bus->parent) {
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		dev = dev->bus->self;
 	}
@@ -1504,7 +1547,7 @@ u8 pci_common_swizzle(struct pci_dev *de
 {
 	u8 pin = *pinp;
 
-	while (dev->bus->self) {
+	while (dev->bus->parent) {
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		dev = dev->bus->self;
 	}
@@ -2028,18 +2071,24 @@ static int __pcie_flr(struct pci_dev *de
 	pci_block_user_cfg_access(dev);
 
 	/* Wait for Transaction Pending bit clean */
+	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+	if (!(status & PCI_EXP_DEVSTA_TRPND))
+		goto transaction_done;
+
 	msleep(100);
 	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-	if (status & PCI_EXP_DEVSTA_TRPND) {
-		dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+	if (!(status & PCI_EXP_DEVSTA_TRPND))
+		goto transaction_done;
+
+	dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
 			"sleeping for 1 second\n");
-		ssleep(1);
-		pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-		if (status & PCI_EXP_DEVSTA_TRPND)
-			dev_info(&dev->dev, "Still busy after 1s; "
+	ssleep(1);
+	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+	if (status & PCI_EXP_DEVSTA_TRPND)
+		dev_info(&dev->dev, "Still busy after 1s; "
 				"proceeding with reset anyway\n");
-	}
 
+transaction_done:
 	pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
 				PCI_EXP_DEVCTL_BCR_FLR);
 	mdelay(100);
@@ -2066,18 +2115,24 @@ static int __pci_af_flr(struct pci_dev *
 	pci_block_user_cfg_access(dev);
 
 	/* Wait for Transaction Pending bit clean */
+	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+	if (!(status & PCI_AF_STATUS_TP))
+		goto transaction_done;
+
 	msleep(100);
 	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-	if (status & PCI_AF_STATUS_TP) {
-		dev_info(&dev->dev, "Busy after 100ms while trying to"
-				" reset; sleeping for 1 second\n");
-		ssleep(1);
-		pci_read_config_byte(dev,
-				cappos + PCI_AF_STATUS, &status);
-		if (status & PCI_AF_STATUS_TP)
-			dev_info(&dev->dev, "Still busy after 1s; "
-					"proceeding with reset anyway\n");
-	}
+	if (!(status & PCI_AF_STATUS_TP))
+		goto transaction_done;
+
+	dev_info(&dev->dev, "Busy after 100ms while trying to"
+			" reset; sleeping for 1 second\n");
+	ssleep(1);
+	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+	if (status & PCI_AF_STATUS_TP)
+		dev_info(&dev->dev, "Still busy after 1s; "
+				"proceeding with reset anyway\n");
+
+transaction_done:
 	pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
 	mdelay(100);
 
@@ -2346,18 +2401,140 @@ int pci_select_bars(struct pci_dev *dev,
  */
 int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 {
+	int reg;
+
 	if (resno < PCI_ROM_RESOURCE) {
 		*type = pci_bar_unknown;
 		return PCI_BASE_ADDRESS_0 + 4 * resno;
 	} else if (resno == PCI_ROM_RESOURCE) {
 		*type = pci_bar_mem32;
 		return dev->rom_base_reg;
+	} else if (resno < PCI_BRIDGE_RESOURCES) {
+		/* device specific resource */
+		reg = pci_iov_resource_bar(dev, resno, type);
+		if (reg)
+			return reg;
 	}
 
 	dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
 	return 0;
 }
 
+#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;
+
+/**
+ * pci_specified_resource_alignment - get resource alignment specified by user.
+ * @dev: the PCI device to get
+ *
+ * RETURNS: Resource alignment if it is specified.
+ *          Zero if it is not specified.
+ */
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
+{
+	int seg, bus, slot, func, align_order, count;
+	resource_size_t align = 0;
+	char *p;
+
+	spin_lock(&resource_alignment_lock);
+	p = resource_alignment_param;
+	while (*p) {
+		count = 0;
+		if (sscanf(p, "%d%n", &align_order, &count) == 1 &&
+							p[count] == '@') {
+			p += count + 1;
+		} else {
+			align_order = -1;
+		}
+		if (sscanf(p, "%x:%x:%x.%x%n",
+			&seg, &bus, &slot, &func, &count) != 4) {
+			seg = 0;
+			if (sscanf(p, "%x:%x.%x%n",
+					&bus, &slot, &func, &count) != 3) {
+				/* Invalid format */
+				printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
+					p);
+				break;
+			}
+		}
+		p += count;
+		if (seg == pci_domain_nr(dev->bus) &&
+			bus == dev->bus->number &&
+			slot == PCI_SLOT(dev->devfn) &&
+			func == PCI_FUNC(dev->devfn)) {
+			if (align_order == -1) {
+				align = PAGE_SIZE;
+			} else {
+				align = 1 << align_order;
+			}
+			/* Found */
+			break;
+		}
+		if (*p != ';' && *p != ',') {
+			/* End of param or invalid format */
+			break;
+		}
+		p++;
+	}
+	spin_unlock(&resource_alignment_lock);
+	return align;
+}
+
+/**
+ * pci_is_reassigndev - check if specified PCI is target device to reassign
+ * @dev: the PCI device to check
+ *
+ * RETURNS: non-zero for PCI device is a target device to reassign,
+ *          or zero is not.
+ */
+int pci_is_reassigndev(struct pci_dev *dev)
+{
+	return (pci_specified_resource_alignment(dev) != 0);
+}
+
+ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)
+{
+	if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)
+		count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1;
+	spin_lock(&resource_alignment_lock);
+	strncpy(resource_alignment_param, buf, count);
+	resource_alignment_param[count] = '\0';
+	spin_unlock(&resource_alignment_lock);
+	return count;
+}
+
+ssize_t pci_get_resource_alignment_param(char *buf, size_t size)
+{
+	size_t count;
+	spin_lock(&resource_alignment_lock);
+	count = snprintf(buf, size, "%s", resource_alignment_param);
+	spin_unlock(&resource_alignment_lock);
+	return count;
+}
+
+static ssize_t pci_resource_alignment_show(struct bus_type *bus, char *buf)
+{
+	return pci_get_resource_alignment_param(buf, PAGE_SIZE);
+}
+
+static ssize_t pci_resource_alignment_store(struct bus_type *bus,
+					const char *buf, size_t count)
+{
+	return pci_set_resource_alignment_param(buf, count);
+}
+
+BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show,
+					pci_resource_alignment_store);
+
+static int __init pci_resource_alignment_sysfs_init(void)
+{
+	return bus_create_file(&pci_bus_type,
+					&bus_attr_resource_alignment);
+}
+
+late_initcall(pci_resource_alignment_sysfs_init);
+
 static void __devinit pci_no_domains(void)
 {
 #ifdef CONFIG_PCI_DOMAINS
@@ -2406,6 +2583,9 @@ static int __init pci_setup(char *str)
 				pci_cardbus_io_size = memparse(str + 9, &str);
 			} else if (!strncmp(str, "cbmemsize=", 10)) {
 				pci_cardbus_mem_size = memparse(str + 10, &str);
+			} else if (!strncmp(str, "resource_alignment=", 19)) {
+				pci_set_resource_alignment_param(str + 19,
+							strlen(str + 19));
 			} else {
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 						str);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pci-driver.c linux-libre-2.6.30-gnu1/drivers/pci/pci-driver.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pci-driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pci-driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -99,6 +99,52 @@ store_new_id(struct device_driver *drive
 }
 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
 
+/**
+ * store_remove_id - remove a PCI device ID from this driver
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
+ *
+ * Removes a dynamic pci device ID to this driver.
+ */
+static ssize_t
+store_remove_id(struct device_driver *driver, const char *buf, size_t count)
+{
+	struct pci_dynid *dynid, *n;
+	struct pci_driver *pdrv = to_pci_driver(driver);
+	__u32 vendor, device, subvendor = PCI_ANY_ID,
+		subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
+	int fields = 0;
+	int retval = -ENODEV;
+
+	fields = sscanf(buf, "%x %x %x %x %x %x",
+			&vendor, &device, &subvendor, &subdevice,
+			&class, &class_mask);
+	if (fields < 2)
+		return -EINVAL;
+
+	spin_lock(&pdrv->dynids.lock);
+	list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
+		struct pci_device_id *id = &dynid->id;
+		if ((id->vendor == vendor) &&
+		    (id->device == device) &&
+		    (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
+		    (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
+		    !((id->class ^ class) & class_mask)) {
+			list_del(&dynid->node);
+			kfree(dynid);
+			retval = 0;
+			break;
+		}
+	}
+	spin_unlock(&pdrv->dynids.lock);
+
+	if (retval)
+		return retval;
+	return count;
+}
+static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
+
 static void
 pci_free_dynids(struct pci_driver *drv)
 {
@@ -125,6 +171,20 @@ static void pci_remove_newid_file(struct
 {
 	driver_remove_file(&drv->driver, &driver_attr_new_id);
 }
+
+static int
+pci_create_removeid_file(struct pci_driver *drv)
+{
+	int error = 0;
+	if (drv->probe != NULL)
+		error = driver_create_file(&drv->driver,&driver_attr_remove_id);
+	return error;
+}
+
+static void pci_remove_removeid_file(struct pci_driver *drv)
+{
+	driver_remove_file(&drv->driver, &driver_attr_remove_id);
+}
 #else /* !CONFIG_HOTPLUG */
 static inline void pci_free_dynids(struct pci_driver *drv) {}
 static inline int pci_create_newid_file(struct pci_driver *drv)
@@ -132,6 +192,11 @@ static inline int pci_create_newid_file(
 	return 0;
 }
 static inline void pci_remove_newid_file(struct pci_driver *drv) {}
+static inline int pci_create_removeid_file(struct pci_driver *drv)
+{
+	return 0;
+}
+static inline void pci_remove_removeid_file(struct pci_driver *drv) {}
 #endif
 
 /**
@@ -212,10 +277,9 @@ static int pci_call_probe(struct pci_dri
 	node = dev_to_node(&dev->dev);
 	if (node >= 0) {
 		int cpu;
-		node_to_cpumask_ptr(nodecpumask, node);
 
 		get_online_cpus();
-		cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
+		cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
 		if (cpu < nr_cpu_ids)
 			error = work_on_cpu(cpu, local_pci_probe, &ddi);
 		else
@@ -352,53 +416,60 @@ static int pci_legacy_suspend(struct dev
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
-	int i = 0;
+
+	pci_dev->state_saved = false;
 
 	if (drv && drv->suspend) {
 		pci_power_t prev = pci_dev->current_state;
+		int error;
 
-		pci_dev->state_saved = false;
-
-		i = drv->suspend(pci_dev, state);
-		suspend_report_result(drv->suspend, i);
-		if (i)
-			return i;
-
-		if (pci_dev->state_saved)
-			goto Fixup;
+		error = drv->suspend(pci_dev, state);
+		suspend_report_result(drv->suspend, error);
+		if (error)
+			return error;
 
-		if (pci_dev->current_state != PCI_D0
+		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
 		    && pci_dev->current_state != PCI_UNKNOWN) {
 			WARN_ONCE(pci_dev->current_state != prev,
 				"PCI PM: Device state not saved by %pF\n",
 				drv->suspend);
-			goto Fixup;
 		}
 	}
 
-	pci_save_state(pci_dev);
-	/*
-	 * This is for compatibility with existing code with legacy PM support.
-	 */
-	pci_pm_set_unknown_state(pci_dev);
-
- Fixup:
 	pci_fixup_device(pci_fixup_suspend, pci_dev);
 
-	return i;
+	return 0;
 }
 
 static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
-	int i = 0;
 
 	if (drv && drv->suspend_late) {
-		i = drv->suspend_late(pci_dev, state);
-		suspend_report_result(drv->suspend_late, i);
+		pci_power_t prev = pci_dev->current_state;
+		int error;
+
+		error = drv->suspend_late(pci_dev, state);
+		suspend_report_result(drv->suspend_late, error);
+		if (error)
+			return error;
+
+		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+		    && pci_dev->current_state != PCI_UNKNOWN) {
+			WARN_ONCE(pci_dev->current_state != prev,
+				"PCI PM: Device state not saved by %pF\n",
+				drv->suspend_late);
+			return 0;
+		}
 	}
-	return i;
+
+	if (!pci_dev->state_saved)
+		pci_save_state(pci_dev);
+
+	pci_pm_set_unknown_state(pci_dev);
+
+	return 0;
 }
 
 static int pci_legacy_resume_early(struct device *dev)
@@ -423,6 +494,23 @@ static int pci_legacy_resume(struct devi
 
 /* Auxiliary functions used by the new power management framework */
 
+/**
+ * pci_restore_standard_config - restore standard config registers of PCI device
+ * @pci_dev: PCI device to handle
+ */
+static int pci_restore_standard_config(struct pci_dev *pci_dev)
+{
+	pci_update_current_state(pci_dev, PCI_UNKNOWN);
+
+	if (pci_dev->current_state != PCI_D0) {
+		int error = pci_set_power_state(pci_dev, PCI_D0);
+		if (error)
+			return error;
+	}
+
+	return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
+}
+
 static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
 {
 	pci_restore_standard_config(pci_dev);
@@ -443,7 +531,6 @@ static void pci_pm_default_suspend(struc
 	/* Disable non-bridge devices without PM support */
 	if (!pci_is_bridge(pci_dev))
 		pci_disable_enabled_device(pci_dev);
-	pci_save_state(pci_dev);
 }
 
 static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -493,13 +580,13 @@ static int pci_pm_suspend(struct device
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_SUSPEND);
 
+	pci_dev->state_saved = false;
+
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		goto Fixup;
 	}
 
-	pci_dev->state_saved = false;
-
 	if (pm->suspend) {
 		pci_power_t prev = pci_dev->current_state;
 		int error;
@@ -509,24 +596,14 @@ static int pci_pm_suspend(struct device
 		if (error)
 			return error;
 
-		if (pci_dev->state_saved)
-			goto Fixup;
-
-		if (pci_dev->current_state != PCI_D0
+		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
 		    && pci_dev->current_state != PCI_UNKNOWN) {
 			WARN_ONCE(pci_dev->current_state != prev,
 				"PCI PM: State of device not saved by %pF\n",
 				pm->suspend);
-			goto Fixup;
 		}
 	}
 
-	if (!pci_dev->state_saved) {
-		pci_save_state(pci_dev);
-		if (!pci_is_bridge(pci_dev))
-			pci_prepare_to_sleep(pci_dev);
-	}
-
  Fixup:
 	pci_fixup_device(pci_fixup_suspend, pci_dev);
 
@@ -536,21 +613,43 @@ static int pci_pm_suspend(struct device
 static int pci_pm_suspend_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
 
-	if (drv && drv->pm && drv->pm->suspend_noirq) {
-		error = drv->pm->suspend_noirq(dev);
-		suspend_report_result(drv->pm->suspend_noirq, error);
+	if (!pm) {
+		pci_save_state(pci_dev);
+		return 0;
 	}
 
-	if (!error)
-		pci_pm_set_unknown_state(pci_dev);
+	if (pm->suspend_noirq) {
+		pci_power_t prev = pci_dev->current_state;
+		int error;
 
-	return error;
+		error = pm->suspend_noirq(dev);
+		suspend_report_result(pm->suspend_noirq, error);
+		if (error)
+			return error;
+
+		if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+		    && pci_dev->current_state != PCI_UNKNOWN) {
+			WARN_ONCE(pci_dev->current_state != prev,
+				"PCI PM: State of device not saved by %pF\n",
+				pm->suspend_noirq);
+			return 0;
+		}
+	}
+
+	if (!pci_dev->state_saved) {
+		pci_save_state(pci_dev);
+		if (!pci_is_bridge(pci_dev))
+			pci_prepare_to_sleep(pci_dev);
+	}
+
+	pci_pm_set_unknown_state(pci_dev);
+
+	return 0;
 }
 
 static int pci_pm_resume_noirq(struct device *dev)
@@ -617,13 +716,13 @@ static int pci_pm_freeze(struct device *
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_FREEZE);
 
+	pci_dev->state_saved = false;
+
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		return 0;
 	}
 
-	pci_dev->state_saved = false;
-
 	if (pm->freeze) {
 		int error;
 
@@ -633,9 +732,6 @@ static int pci_pm_freeze(struct device *
 			return error;
 	}
 
-	if (!pci_dev->state_saved)
-		pci_save_state(pci_dev);
-
 	return 0;
 }
 
@@ -643,20 +739,25 @@ static int pci_pm_freeze_noirq(struct de
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	struct device_driver *drv = dev->driver;
-	int error = 0;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend_late(dev, PMSG_FREEZE);
 
 	if (drv && drv->pm && drv->pm->freeze_noirq) {
+		int error;
+
 		error = drv->pm->freeze_noirq(dev);
 		suspend_report_result(drv->pm->freeze_noirq, error);
+		if (error)
+			return error;
 	}
 
-	if (!error)
-		pci_pm_set_unknown_state(pci_dev);
+	if (!pci_dev->state_saved)
+		pci_save_state(pci_dev);
 
-	return error;
+	pci_pm_set_unknown_state(pci_dev);
+
+	return 0;
 }
 
 static int pci_pm_thaw_noirq(struct device *dev)
@@ -699,46 +800,56 @@ static int pci_pm_poweroff(struct device
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int error = 0;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
 
+	pci_dev->state_saved = false;
+
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		goto Fixup;
 	}
 
-	pci_dev->state_saved = false;
-
 	if (pm->poweroff) {
+		int error;
+
 		error = pm->poweroff(dev);
 		suspend_report_result(pm->poweroff, error);
+		if (error)
+			return error;
 	}
 
-	if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
-		pci_prepare_to_sleep(pci_dev);
-
  Fixup:
 	pci_fixup_device(pci_fixup_suspend, pci_dev);
 
-	return error;
+	return 0;
 }
 
 static int pci_pm_poweroff_noirq(struct device *dev)
 {
+	struct pci_dev *pci_dev = to_pci_dev(dev);
 	struct device_driver *drv = dev->driver;
-	int error = 0;
 
 	if (pci_has_legacy_pm_support(to_pci_dev(dev)))
 		return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
 
-	if (drv && drv->pm && drv->pm->poweroff_noirq) {
+	if (!drv || !drv->pm)
+		return 0;
+
+	if (drv->pm->poweroff_noirq) {
+		int error;
+
 		error = drv->pm->poweroff_noirq(dev);
 		suspend_report_result(drv->pm->poweroff_noirq, error);
+		if (error)
+			return error;
 	}
 
-	return error;
+	if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+		pci_prepare_to_sleep(pci_dev);
+
+	return 0;
 }
 
 static int pci_pm_restore_noirq(struct device *dev)
@@ -852,13 +963,23 @@ int __pci_register_driver(struct pci_dri
 	/* register with core */
 	error = driver_register(&drv->driver);
 	if (error)
-		return error;
+		goto out;
 
 	error = pci_create_newid_file(drv);
 	if (error)
-		driver_unregister(&drv->driver);
+		goto out_newid;
 
+	error = pci_create_removeid_file(drv);
+	if (error)
+		goto out_removeid;
+out:
 	return error;
+
+out_removeid:
+	pci_remove_newid_file(drv);
+out_newid:
+	driver_unregister(&drv->driver);
+	goto out;
 }
 
 /**
@@ -874,6 +995,7 @@ int __pci_register_driver(struct pci_dri
 void
 pci_unregister_driver(struct pci_driver *drv)
 {
+	pci_remove_removeid_file(drv);
 	pci_remove_newid_file(drv);
 	driver_unregister(&drv->driver);
 	pci_free_dynids(drv);
@@ -973,6 +1095,7 @@ struct bus_type pci_bus_type = {
 	.remove		= pci_device_remove,
 	.shutdown	= pci_device_shutdown,
 	.dev_attrs	= pci_dev_attrs,
+	.bus_attrs	= pci_bus_attrs,
 	.pm		= PCI_PM_OPS_PTR,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,7 +38,7 @@ int aer_osc_setup(struct pcie_device *pc
 
 	handle = acpi_find_root_bridge_handle(pdev);
 	if (handle) {
-		status = pci_osc_control_set(handle,
+		status = acpi_pci_osc_control_set(handle,
 					OSC_PCI_EXPRESS_AER_CONTROL |
 					OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv.c	2009-06-09 23:05:27.000000000 -0400
@@ -38,30 +38,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static int __devinit aer_probe (struct pcie_device *dev,
-	const struct pcie_port_service_id *id );
+static int __devinit aer_probe (struct pcie_device *dev);
 static void aer_remove(struct pcie_device *dev);
-static int aer_suspend(struct pcie_device *dev, pm_message_t state)
-{return 0;}
-static int aer_resume(struct pcie_device *dev) {return 0;}
 static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
 	enum pci_channel_state error);
 static void aer_error_resume(struct pci_dev *dev);
 static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
 
-/*
- * PCI Express bus's AER Root service driver data structure
- */
-static struct pcie_port_service_id aer_id[] = {
-	{
-	.vendor 	= PCI_ANY_ID,
-	.device 	= PCI_ANY_ID,
-	.port_type 	= PCIE_RC_PORT,
-	.service_type 	= PCIE_PORT_SERVICE_AER,
-	},
-	{ /* end: all zeroes */ }
-};
-
 static struct pci_error_handlers aer_error_handlers = {
 	.error_detected = aer_error_detected,
 	.resume = aer_error_resume,
@@ -69,14 +52,12 @@ static struct pci_error_handlers aer_err
 
 static struct pcie_port_service_driver aerdriver = {
 	.name		= "aer",
-	.id_table	= &aer_id[0],
+	.port_type	= PCIE_ANY_PORT,
+	.service	= PCIE_PORT_SERVICE_AER,
 
 	.probe		= aer_probe,
 	.remove		= aer_remove,
 
-	.suspend	= aer_suspend,
-	.resume		= aer_resume,
-
 	.err_handler	= &aer_error_handlers,
 
 	.reset_link	= aer_root_reset,
@@ -207,8 +188,7 @@ static void aer_remove(struct pcie_devic
  *
  * Invoked when PCI Express bus loads AER service driver.
  **/
-static int __devinit aer_probe (struct pcie_device *dev,
-				const struct pcie_port_service_id *id )
+static int __devinit aer_probe (struct pcie_device *dev)
 {
 	int status;
 	struct aer_rpc *rpc;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv_core.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv_core.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -351,21 +351,21 @@ static int find_aer_service_iter(struct
 {
 	struct device_driver *driver;
 	struct pcie_port_service_driver *service_driver;
-	struct pcie_device *pcie_dev;
 	struct find_aer_service_data *result;
 
 	result = (struct find_aer_service_data *) data;
 
 	if (device->bus == &pcie_port_bus_type) {
-		pcie_dev = to_pcie_device(device);
-		if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT)
+		struct pcie_port_data *port_data;
+
+		port_data = pci_get_drvdata(to_pcie_device(device)->port);
+		if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
 			result->is_downstream = 1;
 
 		driver = device->driver;
 		if (driver) {
 			service_driver = to_service_driver(driver);
-			if (service_driver->id_table->service_type ==
-					PCIE_PORT_SERVICE_AER) {
+			if (service_driver->service == PCIE_PORT_SERVICE_AER) {
 				result->aer_driver = service_driver;
 				return 1;
 			}
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv.h linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv.h
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/aer/aerdrv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/aer/aerdrv.h	2009-06-09 23:05:27.000000000 -0400
@@ -95,6 +95,9 @@ struct aer_broadcast_data {
 static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
 		enum pci_ers_result new)
 {
+	if (new == PCI_ERS_RESULT_NONE)
+		return orig;
+
 	switch (orig) {
 	case PCI_ERS_RESULT_CAN_RECOVER:
 	case PCI_ERS_RESULT_RECOVERED:
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_bus.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_bus.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,20 +26,22 @@ 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)
 		return 0;
-	
+
 	pciedev = to_pcie_device(dev);
 	driver = to_service_driver(drv);
-	if (   (driver->id_table->vendor != PCI_ANY_ID && 
-		driver->id_table->vendor != pciedev->id.vendor) ||
-	       (driver->id_table->device != PCI_ANY_ID &&
-		driver->id_table->device != pciedev->id.device) ||	
-	       (driver->id_table->port_type != PCIE_ANY_PORT &&
-		driver->id_table->port_type != pciedev->id.port_type) ||
-		driver->id_table->service_type != pciedev->id.service_type )
+
+	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)
 		return 0;
 
 	return 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_core.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_core.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -15,10 +15,9 @@
 #include <linux/slab.h>
 #include <linux/pcieport_if.h>
 
+#include "../pci.h"
 #include "portdrv.h"
 
-extern int pcie_mch_quirk;	/* MSI-quirk Indicator */
-
 /**
  * release_pcie_device - free PCI Express port service device structure
  * @dev: Port service device to release
@@ -31,26 +30,150 @@ static void release_pcie_device(struct d
 	kfree(to_pcie_device(dev));			
 }
 
-static int is_msi_quirked(struct pci_dev *dev)
+/**
+ * pcie_port_msix_add_entry - add entry to given array of MSI-X entries
+ * @entries: Array of MSI-X entries
+ * @new_entry: Index of the entry to add to the array
+ * @nr_entries: Number of entries aleady in the array
+ *
+ * Return value: Position of the added entry in the array
+ */
+static int pcie_port_msix_add_entry(
+	struct msix_entry *entries, int new_entry, int nr_entries)
 {
-	int port_type, quirk = 0;
+	int j;
+
+	for (j = 0; j < nr_entries; j++)
+		if (entries[j].entry == new_entry)
+			return j;
+
+	entries[j].entry = new_entry;
+	return j;
+}
+
+/**
+ * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port
+ * @dev: PCI Express port to handle
+ * @vectors: Array of interrupt vectors to populate
+ * @mask: Bitmask of port capabilities returned by get_port_device_capability()
+ *
+ * Return value: 0 on success, error code on failure
+ */
+static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
+{
+	struct msix_entry *msix_entries;
+	int idx[PCIE_PORT_DEVICE_MAXSERVICES];
+	int nr_entries, status, pos, i, nvec;
 	u16 reg16;
+	u32 reg32;
 
-	pci_read_config_word(dev, 
-		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
-		PCIE_CAPABILITIES_REG, &reg16);
-	port_type = (reg16 >> 4) & PORT_TYPE_MASK;
-	switch(port_type) {
-	case PCIE_RC_PORT:
-		if (pcie_mch_quirk == 1)
-			quirk = 1;
-		break;
-	case PCIE_SW_UPSTREAM_PORT:
-	case PCIE_SW_DOWNSTREAM_PORT:
-	default:
-		break;	
+	nr_entries = pci_msix_table_size(dev);
+	if (!nr_entries)
+		return -EINVAL;
+	if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
+		nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
+
+	msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL);
+	if (!msix_entries)
+		return -ENOMEM;
+
+	/*
+	 * Allocate as many entries as the port wants, so that we can check
+	 * which of them will be useful.  Moreover, if nr_entries is correctly
+	 * equal to the number of entries this port actually uses, we'll happily
+	 * go through without any tricks.
+	 */
+	for (i = 0; i < nr_entries; i++)
+		msix_entries[i].entry = i;
+
+	status = pci_enable_msix(dev, msix_entries, nr_entries);
+	if (status)
+		goto Exit;
+
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+		idx[i] = -1;
+	status = -EIO;
+	nvec = 0;
+
+	if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) {
+		int entry;
+
+		/*
+		 * The code below follows the PCI Express Base Specification 2.0
+		 * stating in Section 6.1.6 that "PME and Hot-Plug Event
+		 * interrupts (when both are implemented) always share the same
+		 * MSI or MSI-X vector, as indicated by the Interrupt Message
+		 * Number field in the PCI Express Capabilities register", where
+		 * according to Section 7.8.2 of the specification "For MSI-X,
+		 * 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;
+		if (entry >= nr_entries)
+			goto Error;
+
+		i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+		if (i == nvec)
+			nvec++;
+
+		idx[PCIE_PORT_SERVICE_PME_SHIFT] = i;
+		idx[PCIE_PORT_SERVICE_HP_SHIFT] = i;
 	}
-	return quirk;
+
+	if (mask & PCIE_PORT_SERVICE_AER) {
+		int entry;
+
+		/*
+		 * The code below follows Section 7.10.10 of the PCI Express
+		 * Base Specification 2.0 stating that bits 31-27 of the Root
+		 * Error Status Register contain a value indicating which of the
+		 * MSI/MSI-X vectors assigned to the port is going to be used
+		 * for AER, where "For MSI-X, the value in this register
+		 * indicates which MSI-X Table entry is used to generate the
+		 * interrupt message."
+		 */
+		pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+		pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
+		entry = reg32 >> 27;
+		if (entry >= nr_entries)
+			goto Error;
+
+		i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+		if (i == nvec)
+			nvec++;
+
+		idx[PCIE_PORT_SERVICE_AER_SHIFT] = i;
+	}
+
+	/*
+	 * If nvec is equal to the allocated number of entries, we can just use
+	 * what we have.  Otherwise, the port has some extra entries not for the
+	 * services we know and we need to work around that.
+	 */
+	if (nvec == nr_entries) {
+		status = 0;
+	} else {
+		/* Drop the temporary MSI-X setup */
+		pci_disable_msix(dev);
+
+		/* Now allocate the MSI-X vectors for real */
+		status = pci_enable_msix(dev, msix_entries, nvec);
+		if (status)
+			goto Exit;
+	}
+
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+		vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1;
+
+ Exit:
+	kfree(msix_entries);
+	return status;
+
+ Error:
+	pci_disable_msix(dev);
+	goto Exit;
 }
 
 /**
@@ -64,47 +187,32 @@ static int is_msi_quirked(struct pci_dev
  */
 static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
 {
-	int i, pos, nvec, status = -EINVAL;
-	int interrupt_mode = PCIE_PORT_INTx_MODE;
+	struct pcie_port_data *port_data = pci_get_drvdata(dev);
+	int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
+	int i;
 
-	/* Set INTx as default */
-	for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
-		if (mask & (1 << i)) 
-			nvec++;
-		vectors[i] = dev->irq;
-	}
-	
 	/* Check MSI quirk */
-	if (is_msi_quirked(dev))
-		return interrupt_mode;
+	if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
+		goto Fallback;
 
-	/* Select MSI-X over MSI if supported */		
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos) {
-		struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 
-			{{0, 0}, {0, 1}, {0, 2}, {0, 3}};
-		status = pci_enable_msix(dev, msix_entries, nvec);
-		if (!status) {
-			int j = 0;
+	/* Try to use MSI-X if supported */
+	if (!pcie_port_enable_msix(dev, vectors, mask))
+		return PCIE_PORT_MSIX_MODE;
+
+	/* 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;
+
+ Fallback:
+	if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
+		interrupt_mode = PCIE_PORT_INTx_MODE;
+
+	irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+		vectors[i] = irq;
+
+	vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
 
-			interrupt_mode = PCIE_PORT_MSIX_MODE;
-			for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
-				if (mask & (1 << i)) 
-					vectors[i] = msix_entries[j++].vector;
-			}
-		}
-	} 
-	if (status) {
-		pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-		if (pos) {
-			status = pci_enable_msi(dev);
-			if (!status) {
-				interrupt_mode = PCIE_PORT_MSI_MODE;
-				for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
-					vectors[i] = dev->irq;
-			}
-		}
-	} 
 	return interrupt_mode;
 }
 
@@ -132,13 +240,11 @@ static int get_port_device_capability(st
 			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
 		if (reg32 & SLOT_HP_CAPABLE_MASK)
 			services |= PCIE_PORT_SERVICE_HP;
-	} 
-	/* PME Capable - root port capability */
-	if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
-		services |= PCIE_PORT_SERVICE_PME;
-
+	}
+	/* AER capable */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
 		services |= PCIE_PORT_SERVICE_AER;
+	/* VC support */
 	if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
 		services |= PCIE_PORT_SERVICE_VC;
 
@@ -152,20 +258,17 @@ static int get_port_device_capability(st
  * @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
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
  */
 static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 
-	int port_type, int service_type, int irq, int irq_mode)
+	int service_type, int irq)
 {
+	struct pcie_port_data *port_data = pci_get_drvdata(parent);
 	struct device *device;
+	int port_type = port_data->port_type;
 
 	dev->port = parent;
-	dev->interrupt_mode = irq_mode;
 	dev->irq = irq;
-	dev->id.vendor = parent->vendor;
-	dev->id.device = parent->device;
-	dev->id.port_type = port_type;
-	dev->id.service_type = (1 << service_type);
+	dev->service = service_type;
 
 	/* Initialize generic device interface */
 	device = &dev->device;
@@ -185,10 +288,9 @@ static void pcie_device_init(struct pci_
  * @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
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
  */
 static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
-	int port_type, int service_type, int irq, int irq_mode)
+	int service_type, int irq)
 {
 	struct pcie_device *device;
 
@@ -196,7 +298,7 @@ static struct pcie_device* alloc_pcie_de
 	if (!device)
 		return NULL;
 
-	pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+	pcie_device_init(parent, device, service_type, irq);
 	return device;
 }
 
@@ -230,63 +332,90 @@ int pcie_port_device_probe(struct pci_de
  */
 int pcie_port_device_register(struct pci_dev *dev)
 {
-	struct pcie_port_device_ext *p_ext;
-	int status, type, capabilities, irq_mode, i;
+	struct pcie_port_data *port_data;
+	int status, capabilities, irq_mode, i, nr_serv;
 	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
 	u16 reg16;
 
-	/* Allocate port device extension */
-	if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+	port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
+	if (!port_data)
 		return -ENOMEM;
-
-	pci_set_drvdata(dev, p_ext);
+	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);
-	type = (reg16 >> 4) & PORT_TYPE_MASK;
+	port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
 
-	/* Now get 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);
-	p_ext->interrupt_mode = irq_mode;
+	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;
+
+	status = pci_enable_device(dev);
+	if (status)
+		goto Error;
+	pci_set_master(dev);
 
 	/* Allocate child services if any */
-	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+	for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
 		struct pcie_device *child;
+		int service = 1 << i;
 
-		if (capabilities & (1 << i)) {
-			child = alloc_pcie_device(
-				dev, 		/* parent */
-				type,		/* port type */
-				i,		/* service type */
-				vectors[i],	/* irq */
-				irq_mode	/* interrupt mode */);
-			if (child) {
-				status = device_register(&child->device);
-				if (status) {
-					kfree(child);
-					continue;
-				}
-				get_device(&child->device);
-			}
+		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;
 	}
+
 	return 0;
+
+ Error:
+	kfree(port_data);
+	return status;
 }
 
 #ifdef CONFIG_PM
 static int suspend_iter(struct device *dev, void *data)
 {
 	struct pcie_port_service_driver *service_driver;
-	pm_message_t state = * (pm_message_t *) data;
 
  	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), state);
+ 			service_driver->suspend(to_pcie_device(dev));
   	}
 	return 0;
 }
@@ -294,11 +423,10 @@ static int suspend_iter(struct device *d
 /**
  * pcie_port_device_suspend - suspend port services associated with a PCIe port
  * @dev: PCI Express port to handle
- * @state: Representation of system power management transition in progress
  */
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+int pcie_port_device_suspend(struct device *dev)
 {
-	return device_for_each_child(&dev->dev, &state, suspend_iter);
+	return device_for_each_child(dev, NULL, suspend_iter);
 }
 
 static int resume_iter(struct device *dev, void *data)
@@ -318,24 +446,17 @@ static int resume_iter(struct device *de
  * pcie_port_device_suspend - resume port services associated with a PCIe port
  * @dev: PCI Express port to handle
  */
-int pcie_port_device_resume(struct pci_dev *dev)
+int pcie_port_device_resume(struct device *dev)
 {
-	return device_for_each_child(&dev->dev, NULL, resume_iter);
+	return device_for_each_child(dev, NULL, resume_iter);
 }
-#endif
+#endif /* PM */
 
 static int remove_iter(struct device *dev, void *data)
 {
-	struct pcie_port_service_driver *service_driver;
-
 	if (dev->bus == &pcie_port_bus_type) {
-		if (dev->driver) {
-			service_driver = to_service_driver(dev->driver);
-			if (service_driver->remove)
-				service_driver->remove(to_pcie_device(dev));
-		}
-		*(unsigned long*)data = (unsigned long)dev;
-		return 1;
+		put_device(dev);
+		device_unregister(dev);
 	}
 	return 0;
 }
@@ -349,25 +470,21 @@ static int remove_iter(struct device *de
  */
 void pcie_port_device_remove(struct pci_dev *dev)
 {
-	struct device *device;
-	unsigned long device_addr;
-	int interrupt_mode = PCIE_PORT_INTx_MODE;
-	int status;
+	struct pcie_port_data *port_data = pci_get_drvdata(dev);
 
-	do {
-		status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
-		if (status) {
-			device = (struct device*)device_addr;
-			interrupt_mode = (to_pcie_device(device))->interrupt_mode;
-			put_device(device);
-			device_unregister(device);
-		}
-	} while (status);
-	/* Switch to INTx by default if MSI enabled */
-	if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+	device_for_each_child(&dev->dev, NULL, remove_iter);
+	pci_disable_device(dev);
+
+	switch (port_data->port_irq_mode) {
+	case PCIE_PORT_MSIX_MODE:
 		pci_disable_msix(dev);
-	else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+		break;
+	case PCIE_PORT_MSI_MODE:
 		pci_disable_msi(dev);
+		break;
+	}
+
+	kfree(port_data);
 }
 
 /**
@@ -392,7 +509,7 @@ static int pcie_port_probe_service(struc
 		return -ENODEV;
 
 	pciedev = to_pcie_device(dev);
-	status = driver->probe(pciedev, driver->id_table);
+	status = driver->probe(pciedev);
 	if (!status) {
 		dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
 			driver->name);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv.h linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv.h
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv.h	2009-06-09 23:05:27.000000000 -0400
@@ -25,19 +25,21 @@
 #define PCIE_CAPABILITIES_REG		0x2
 #define PCIE_SLOT_CAPABILITIES_REG	0x14
 #define PCIE_PORT_DEVICE_MAXSERVICES	4
+#define PCIE_PORT_MSI_VECTOR_MASK	0x1f
+/*
+ * 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)
 
-struct pcie_port_device_ext {
-	int interrupt_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */
-};
-
 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 pci_dev *dev, pm_message_t state);
-extern int pcie_port_device_resume(struct pci_dev *dev);
+extern int pcie_port_device_suspend(struct device *dev);
+extern int pcie_port_device_resume(struct device *dev);
 #endif
 extern void pcie_port_device_remove(struct pci_dev *dev);
 extern int __must_check pcie_port_bus_register(void);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_pci.c linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_pci.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pcie/portdrv_pci.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pcie/portdrv_pci.c	2009-06-09 23:05:27.000000000 -0400
@@ -32,11 +32,6 @@ MODULE_LICENSE("GPL");
 /* global data */
 static const char device_name[] = "pcieport-driver";
 
-static int pcie_portdrv_save_config(struct pci_dev *dev)
-{
-	return pci_save_state(dev);
-}
-
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
 	int retval;
@@ -49,21 +44,21 @@ static int pcie_portdrv_restore_config(s
 }
 
 #ifdef CONFIG_PM
-static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
-{
-	return pcie_port_device_suspend(dev, state);
+static struct dev_pm_ops pcie_portdrv_pm_ops = {
+	.suspend	= pcie_port_device_suspend,
+	.resume		= pcie_port_device_resume,
+	.freeze		= pcie_port_device_suspend,
+	.thaw		= pcie_port_device_resume,
+	.poweroff	= pcie_port_device_suspend,
+	.restore	= pcie_port_device_resume,
+};
 
-}
+#define PCIE_PORTDRV_PM_OPS	(&pcie_portdrv_pm_ops)
 
-static int pcie_portdrv_resume(struct pci_dev *dev)
-{
-	pci_set_master(dev);
-	return pcie_port_device_resume(dev);
-}
-#else
-#define pcie_portdrv_suspend NULL
-#define pcie_portdrv_resume NULL
-#endif
+#else /* !PM */
+
+#define PCIE_PORTDRV_PM_OPS	NULL
+#endif /* !PM */
 
 /*
  * pcie_portdrv_probe - Probe PCI-Express port devices
@@ -82,20 +77,15 @@ static int __devinit pcie_portdrv_probe
 	if (status)
 		return status;
 
-	if (pci_enable_device(dev) < 0) 
-		return -ENODEV;
-	
-	pci_set_master(dev);
         if (!dev->irq && dev->pin) {
 		dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
 			 "check vendor BIOS\n", dev->vendor, dev->device);
 	}
-	if (pcie_port_device_register(dev)) {
-		pci_disable_device(dev);
-		return -ENOMEM;
-	}
+	status = pcie_port_device_register(dev);
+	if (status)
+		return status;
 
-	pcie_portdrv_save_config(dev);
+	pci_save_state(dev);
 
 	return 0;
 }
@@ -104,7 +94,6 @@ static void pcie_portdrv_remove (struct
 {
 	pcie_port_device_remove(dev);
 	pci_disable_device(dev);
-	kfree(pci_get_drvdata(dev));
 }
 
 static int error_detected_iter(struct device *device, void *data)
@@ -211,7 +200,7 @@ static int slot_reset_iter(struct device
 
 static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
 {
-	pci_ers_result_t status = PCI_ERS_RESULT_NONE;
+	pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
 	int retval;
 
 	/* If fatal, restore cfg space for possible link reset at upstream */
@@ -278,10 +267,9 @@ static struct pci_driver pcie_portdriver
 	.probe		= pcie_portdrv_probe,
 	.remove		= pcie_portdrv_remove,
 
-	.suspend	= pcie_portdrv_suspend,
-	.resume		= pcie_portdrv_resume,
-
 	.err_handler 	= &pcie_portdrv_err_handler,
+
+	.driver.pm 	= PCIE_PORTDRV_PM_OPS,
 };
 
 static int __init pcie_portdrv_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pci.h linux-libre-2.6.30-gnu1/drivers/pci/pci.h
--- linux-libre-2.6.29-gnu1/drivers/pci/pci.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pci.h	2009-06-09 23:05:27.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef DRIVERS_PCI_H
 #define DRIVERS_PCI_H
 
+#include <linux/workqueue.h>
+
 #define PCI_CFG_SPACE_SIZE	256
 #define PCI_CFG_SPACE_EXP_SIZE	4096
 
@@ -49,7 +51,6 @@ extern void pci_disable_enabled_device(s
 extern void pci_pm_init(struct pci_dev *dev);
 extern void platform_pci_wakeup_init(struct pci_dev *dev);
 extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
-extern int pci_restore_standard_config(struct pci_dev *dev);
 
 static inline bool pci_is_bridge(struct pci_dev *pci_dev)
 {
@@ -136,6 +137,12 @@ extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
 extern struct device_attribute dev_attr_cpuaffinity;
 extern struct device_attribute dev_attr_cpulistaffinity;
+#ifdef CONFIG_HOTPLUG
+extern struct bus_attribute pci_bus_attrs[];
+#else
+#define pci_bus_attrs	NULL
+#endif
+
 
 /**
  * pci_match_one_device - Tell if a PCI device structure has a matching
@@ -178,6 +185,7 @@ enum pci_bar_type {
 	pci_bar_mem64,		/* A 64-bit memory BAR */
 };
 
+extern int pci_setup_device(struct pci_dev *dev);
 extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 				struct resource *res, unsigned int reg);
 extern int pci_resource_bar(struct pci_dev *dev, int resno,
@@ -195,4 +203,60 @@ static inline int pci_ari_enabled(struct
 	return bus->self && bus->self->ari_enabled;
 }
 
+#ifdef CONFIG_PCI_QUIRKS
+extern int pci_is_reassigndev(struct pci_dev *dev);
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev);
+extern void pci_disable_bridge_window(struct pci_dev *dev);
+#endif
+
+/* Single Root I/O Virtualization */
+struct pci_sriov {
+	int pos;		/* capability position */
+	int nres;		/* number of resources */
+	u32 cap;		/* SR-IOV Capabilities */
+	u16 ctrl;		/* SR-IOV Control */
+	u16 total;		/* total VFs associated with the PF */
+	u16 initial;		/* initial VFs associated with the PF */
+	u16 nr_virtfn;		/* number of VFs available */
+	u16 offset;		/* first VF Routing ID offset */
+	u16 stride;		/* following VF stride */
+	u32 pgsz;		/* page size for BAR alignment */
+	u8 link;		/* Function Dependency Link */
+	struct pci_dev *dev;	/* lowest numbered PF */
+	struct pci_dev *self;	/* this PF */
+	struct mutex lock;	/* lock for VF bus */
+	struct work_struct mtask; /* VF Migration task */
+	u8 __iomem *mstate;	/* VF Migration State Array */
+};
+
+#ifdef CONFIG_PCI_IOV
+extern int pci_iov_init(struct pci_dev *dev);
+extern void pci_iov_release(struct pci_dev *dev);
+extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+				enum pci_bar_type *type);
+extern void pci_restore_iov_state(struct pci_dev *dev);
+extern int pci_iov_bus_range(struct pci_bus *bus);
+#else
+static inline int pci_iov_init(struct pci_dev *dev)
+{
+	return -ENODEV;
+}
+static inline void pci_iov_release(struct pci_dev *dev)
+
+{
+}
+static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+				       enum pci_bar_type *type)
+{
+	return 0;
+}
+static inline void pci_restore_iov_state(struct pci_dev *dev)
+{
+}
+static inline int pci_iov_bus_range(struct pci_bus *bus)
+{
+	return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+
 #endif /* DRIVERS_PCI_H */
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/pci-sysfs.c linux-libre-2.6.30-gnu1/drivers/pci/pci-sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/pci/pci-sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/pci-sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -148,7 +148,7 @@ static ssize_t is_enabled_store(struct d
 		return -EPERM;
 
 	if (!val) {
-		if (atomic_read(&pdev->enable_cnt) != 0)
+		if (pci_is_enabled(pdev))
 			pci_disable_device(pdev);
 		else
 			result = -EIO;
@@ -219,6 +219,79 @@ msi_bus_store(struct device *dev, struct
 	return count;
 }
 
+#ifdef CONFIG_HOTPLUG
+static DEFINE_MUTEX(pci_remove_rescan_mutex);
+static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
+				size_t count)
+{
+	unsigned long val;
+	struct pci_bus *b = NULL;
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val) {
+		mutex_lock(&pci_remove_rescan_mutex);
+		while ((b = pci_find_next_bus(b)) != NULL)
+			pci_rescan_bus(b);
+		mutex_unlock(&pci_remove_rescan_mutex);
+	}
+	return count;
+}
+
+struct bus_attribute pci_bus_attrs[] = {
+	__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
+	__ATTR_NULL
+};
+
+static ssize_t
+dev_rescan_store(struct device *dev, struct device_attribute *attr,
+		 const char *buf, size_t count)
+{
+	unsigned long val;
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val) {
+		mutex_lock(&pci_remove_rescan_mutex);
+		pci_rescan_bus(pdev->bus);
+		mutex_unlock(&pci_remove_rescan_mutex);
+	}
+	return count;
+}
+
+static void remove_callback(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	mutex_lock(&pci_remove_rescan_mutex);
+	pci_remove_bus_device(pdev);
+	mutex_unlock(&pci_remove_rescan_mutex);
+}
+
+static ssize_t
+remove_store(struct device *dev, struct device_attribute *dummy,
+	     const char *buf, size_t count)
+{
+	int ret = 0;
+	unsigned long val;
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	/* An attribute cannot be unregistered by one of its own methods,
+	 * so we have to use this roundabout approach.
+	 */
+	if (val)
+		ret = device_schedule_callback(dev, remove_callback);
+	if (ret)
+		count = ret;
+	return count;
+}
+#endif
+
 struct device_attribute pci_dev_attrs[] = {
 	__ATTR_RO(resource),
 	__ATTR_RO(vendor),
@@ -237,10 +310,25 @@ struct device_attribute pci_dev_attrs[]
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
 	__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
+#ifdef CONFIG_HOTPLUG
+	__ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
+	__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
+#endif
 	__ATTR_NULL,
 };
 
 static ssize_t
+boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return sprintf(buf, "%u\n",
+		!!(pdev->resource[PCI_ROM_RESOURCE].flags &
+		   IORESOURCE_ROM_SHADOW));
+}
+struct device_attribute vga_attr = __ATTR_RO(boot_vga);
+
+static ssize_t
 pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
 		char *buf, loff_t off, size_t count)
 {
@@ -404,6 +492,7 @@ write_vpd_attr(struct kobject *kobj, str
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
  * @kobj: kobject corresponding to file to read from
+ * @bin_attr: struct bin_attribute for this file
  * @buf: buffer to store results
  * @off: offset into legacy I/O port space
  * @count: number of bytes to read
@@ -429,6 +518,7 @@ pci_read_legacy_io(struct kobject *kobj,
 /**
  * pci_write_legacy_io - write byte(s) to legacy I/O port space
  * @kobj: kobject corresponding to file to read from
+ * @bin_attr: struct bin_attribute for this file
  * @buf: buffer containing value to be written
  * @off: offset into legacy I/O port space
  * @count: number of bytes to write
@@ -493,6 +583,19 @@ pci_mmap_legacy_io(struct kobject *kobj,
 }
 
 /**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Stub implementation. Can be overridden by arch if necessary.
+ */
+void __weak
+pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type)
+{
+	return;
+}
+
+/**
  * pci_create_legacy_files - create legacy I/O port and memory files
  * @b: bus to create files under
  *
@@ -518,6 +621,7 @@ void pci_create_legacy_files(struct pci_
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
+	pci_adjust_legacy_attr(b, pci_mmap_io);
 	error = device_create_bin_file(&b->dev, b->legacy_io);
 	if (error)
 		goto legacy_io_err;
@@ -528,6 +632,7 @@ void pci_create_legacy_files(struct pci_
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
 	if (error)
 		goto legacy_mem_err;
@@ -630,9 +735,9 @@ pci_mmap_resource_wc(struct kobject *kob
 
 /**
  * pci_remove_resource_files - cleanup resource files
- * @dev: dev to cleanup
+ * @pdev: dev to cleanup
  *
- * If we created resource files for @dev, remove them from sysfs and
+ * If we created resource files for @pdev, remove them from sysfs and
  * free their resources.
  */
 static void
@@ -690,9 +795,9 @@ static int pci_create_attr(struct pci_de
 
 /**
  * pci_create_resource_files - create resource files in sysfs for @dev
- * @dev: dev in question
+ * @pdev: dev in question
  *
- * Walk the resources in @dev creating files for each resource available.
+ * Walk the resources in @pdev creating files for each resource available.
  */
 static int pci_create_resource_files(struct pci_dev *pdev)
 {
@@ -719,13 +824,14 @@ static int pci_create_resource_files(str
 	return 0;
 }
 #else /* !HAVE_PCI_MMAP */
-static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; }
-static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
+void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
 #endif /* HAVE_PCI_MMAP */
 
 /**
  * pci_write_rom - used to enable access to the PCI ROM display
  * @kobj: kernel object handle
+ * @bin_attr: struct bin_attribute for this file
  * @buf: user input
  * @off: file offset
  * @count: number of byte in input
@@ -749,6 +855,7 @@ pci_write_rom(struct kobject *kobj, stru
 /**
  * pci_read_rom - read a PCI ROM
  * @kobj: kernel object handle
+ * @bin_attr: struct bin_attribute for this file
  * @buf: where to put the data we read from the ROM
  * @off: file offset
  * @count: number of bytes to read
@@ -884,18 +991,27 @@ int __must_check pci_create_sysfs_dev_fi
 		pdev->rom_attr = attr;
 	}
 
+	if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+		retval = device_create_file(&pdev->dev, &vga_attr);
+		if (retval)
+			goto err_rom_file;
+	}
+
 	/* add platform-specific attributes */
 	retval = pcibios_add_platform_entries(pdev);
 	if (retval)
-		goto err_rom_file;
+		goto err_vga_file;
 
 	/* add sysfs entries for various capabilities */
 	retval = pci_create_capabilities_sysfs(pdev);
 	if (retval)
-		goto err_rom_file;
+		goto err_vga_file;
 
 	return 0;
 
+err_vga_file:
+	if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+		device_remove_file(&pdev->dev, &vga_attr);
 err_rom_file:
 	if (rom_size) {
 		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/probe.c linux-libre-2.6.30-gnu1/drivers/pci/probe.c
--- linux-libre-2.6.29-gnu1/drivers/pci/probe.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/probe.c	2009-06-09 23:05:27.000000000 -0400
@@ -287,7 +287,7 @@ void __devinit pci_read_bridge_bases(str
 	struct resource *res;
 	int i;
 
-	if (!dev)		/* It's a host bus, nothing to read */
+	if (!child->parent)	/* It's a host bus, nothing to read */
 		return;
 
 	if (dev->transparent) {
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci
 
 		/*
 		 * If we already got to this bus through a different bridge,
-		 * ignore it.  This can happen with the i450NX chipset.
+		 * don't re-add it. This can happen with the i450NX chipset.
+		 *
+		 * However, we continue to descend down the hierarchy and
+		 * scan remaining child buses.
 		 */
-		if (pci_find_bus(pci_domain_nr(bus), busnr)) {
-			dev_info(&dev->dev, "bus %04x:%02x already known\n",
-				 pci_domain_nr(bus), busnr);
-			goto out;
+		child = pci_find_bus(pci_domain_nr(bus), busnr);
+		if (!child) {
+			child = pci_add_new_bus(bus, dev, busnr);
+			if (!child)
+				goto out;
+			child->primary = buses & 0xFF;
+			child->subordinate = (buses >> 16) & 0xFF;
+			child->bridge_ctl = bctl;
 		}
 
-		child = pci_add_new_bus(bus, dev, busnr);
-		if (!child)
-			goto out;
-		child->primary = buses & 0xFF;
-		child->subordinate = (buses >> 16) & 0xFF;
-		child->bridge_ctl = bctl;
-
 		cmax = pci_scan_child_bus(child);
 		if (cmax > max)
 			max = cmax;
@@ -674,6 +674,19 @@ static void pci_read_irq(struct pci_dev
 	dev->irq = irq;
 }
 
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+	int pos;
+	u16 reg16;
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return;
+	pdev->is_pcie = 1;
+	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
 #define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
 /**
@@ -683,12 +696,33 @@ static void pci_read_irq(struct pci_dev
  * Initialize the device structure with information about the device's 
  * vendor,class,memory and IO-space addresses,IRQ lines etc.
  * Called at initialisation of the PCI subsystem and by CardBus services.
- * Returns 0 on success and -1 if unknown type of device (not normal, bridge
- * or CardBus).
+ * Returns 0 on success and negative if unknown type of device (not normal,
+ * bridge or CardBus).
  */
-static int pci_setup_device(struct pci_dev * dev)
+int pci_setup_device(struct pci_dev *dev)
 {
 	u32 class;
+	u8 hdr_type;
+	struct pci_slot *slot;
+
+	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
+		return -EIO;
+
+	dev->sysdata = dev->bus->sysdata;
+	dev->dev.parent = dev->bus->bridge;
+	dev->dev.bus = &pci_bus_type;
+	dev->hdr_type = hdr_type & 0x7f;
+	dev->multifunction = !!(hdr_type & 0x80);
+	dev->error_state = pci_channel_io_normal;
+	set_pcie_port_type(dev);
+
+	list_for_each_entry(slot, &dev->bus->slots, list)
+		if (PCI_SLOT(dev->devfn) == slot->number)
+			dev->slot = slot;
+
+	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+	   set this higher, assuming the system even supports it.  */
+	dev->dma_mask = 0xffffffff;
 
 	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
 		     dev->bus->number, PCI_SLOT(dev->devfn),
@@ -703,11 +737,15 @@ static int pci_setup_device(struct pci_d
 	dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
 		 dev->vendor, dev->device, class, dev->hdr_type);
 
+	/* need to have dev->class ready */
+	dev->cfg_size = pci_cfg_space_size(dev);
+
 	/* "Unknown power state" */
 	dev->current_state = PCI_UNKNOWN;
 
 	/* Early fixups, before probing the BARs */
 	pci_fixup_device(pci_fixup_early, dev);
+	/* device class may be changed after fixup */
 	class = dev->class >> 8;
 
 	switch (dev->hdr_type) {		    /* header type */
@@ -770,7 +808,7 @@ static int pci_setup_device(struct pci_d
 	default:				    /* unknown header */
 		dev_err(&dev->dev, "unknown header type %02x, "
 			"ignoring device\n", dev->hdr_type);
-		return -1;
+		return -EIO;
 
 	bad:
 		dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
@@ -785,6 +823,7 @@ static int pci_setup_device(struct pci_d
 static void pci_release_capabilities(struct pci_dev *dev)
 {
 	pci_vpd_release(dev);
+	pci_iov_release(dev);
 }
 
 /**
@@ -803,19 +842,6 @@ static void pci_release_dev(struct devic
 	kfree(pci_dev);
 }
 
-static void set_pcie_port_type(struct pci_dev *pdev)
-{
-	int pos;
-	u16 reg16;
-
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	if (!pos)
-		return;
-	pdev->is_pcie = 1;
-	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
-	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
-}
-
 /**
  * pci_cfg_space_size - get the configuration space size of the PCI device.
  * @dev: PCI device
@@ -847,6 +873,11 @@ int pci_cfg_space_size(struct pci_dev *d
 {
 	int pos;
 	u32 status;
+	u16 class;
+
+	class = dev->class >> 8;
+	if (class == PCI_CLASS_BRIDGE_HOST)
+		return pci_cfg_space_size_ext(dev);
 
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	if (!pos) {
@@ -891,9 +922,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
 static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
 {
 	struct pci_dev *dev;
-	struct pci_slot *slot;
 	u32 l;
-	u8 hdr_type;
 	int delay = 1;
 
 	if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
@@ -920,34 +949,16 @@ static struct pci_dev *pci_scan_device(s
 		}
 	}
 
-	if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
-		return NULL;
-
 	dev = alloc_pci_dev();
 	if (!dev)
 		return NULL;
 
 	dev->bus = bus;
-	dev->sysdata = bus->sysdata;
-	dev->dev.parent = bus->bridge;
-	dev->dev.bus = &pci_bus_type;
 	dev->devfn = devfn;
-	dev->hdr_type = hdr_type & 0x7f;
-	dev->multifunction = !!(hdr_type & 0x80);
 	dev->vendor = l & 0xffff;
 	dev->device = (l >> 16) & 0xffff;
-	dev->cfg_size = pci_cfg_space_size(dev);
-	dev->error_state = pci_channel_io_normal;
-	set_pcie_port_type(dev);
-
-	list_for_each_entry(slot, &bus->slots, list)
-		if (PCI_SLOT(devfn) == slot->number)
-			dev->slot = slot;
 
-	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
-	   set this higher, assuming the system even supports it.  */
-	dev->dma_mask = 0xffffffff;
-	if (pci_setup_device(dev) < 0) {
+	if (pci_setup_device(dev)) {
 		kfree(dev);
 		return NULL;
 	}
@@ -972,6 +983,9 @@ static void pci_init_capabilities(struct
 
 	/* Alternative Routing-ID Forwarding */
 	pci_enable_ari(dev);
+
+	/* Single Root I/O Virtualization */
+	pci_iov_init(dev);
 }
 
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1006,6 +1020,12 @@ struct pci_dev *__ref pci_scan_single_de
 {
 	struct pci_dev *dev;
 
+	dev = pci_get_slot(bus, devfn);
+	if (dev) {
+		pci_dev_put(dev);
+		return dev;
+	}
+
 	dev = pci_scan_device(bus, devfn);
 	if (!dev)
 		return NULL;
@@ -1024,35 +1044,27 @@ EXPORT_SYMBOL(pci_scan_single_device);
  * Scan a PCI slot on the specified PCI bus for devices, adding
  * discovered devices to the @bus->devices list.  New devices
  * will not have is_added set.
+ *
+ * Returns the number of new devices found.
  */
 int pci_scan_slot(struct pci_bus *bus, int devfn)
 {
-	int func, nr = 0;
-	int scan_all_fns;
-
-	scan_all_fns = pcibios_scan_all_fns(bus, devfn);
-
-	for (func = 0; func < 8; func++, devfn++) {
-		struct pci_dev *dev;
+	int fn, nr = 0;
+	struct pci_dev *dev;
 
-		dev = pci_scan_single_device(bus, devfn);
-		if (dev) {
-			nr++;
+	dev = pci_scan_single_device(bus, devfn);
+	if (dev && !dev->is_added)	/* new device? */
+		nr++;
 
-			/*
-		 	 * If this is a single function device,
-		 	 * don't scan past the first function.
-		 	 */
-			if (!dev->multifunction) {
-				if (func > 0) {
-					dev->multifunction = 1;
-				} else {
- 					break;
-				}
+	if ((dev && dev->multifunction) ||
+	    (!dev && pcibios_scan_all_fns(bus, devfn))) {
+		for (fn = 1; fn < 8; fn++) {
+			dev = pci_scan_single_device(bus, devfn + fn);
+			if (dev) {
+				if (!dev->is_added)
+					nr++;
+				dev->multifunction = 1;
 			}
-		} else {
-			if (func == 0 && !scan_all_fns)
-				break;
 		}
 	}
 
@@ -1074,12 +1086,21 @@ unsigned int __devinit pci_scan_child_bu
 	for (devfn = 0; devfn < 0x100; devfn += 8)
 		pci_scan_slot(bus, devfn);
 
+	/* Reserve buses for SR-IOV capability. */
+	max += pci_iov_bus_range(bus);
+
 	/*
 	 * After performing arch-dependent fixup of the bus, look behind
 	 * all PCI-to-PCI bridges on this bus.
 	 */
-	pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
-	pcibios_fixup_bus(bus);
+	if (!bus->is_added) {
+		pr_debug("PCI: Fixups for bus %04x:%02x\n",
+			 pci_domain_nr(bus), bus->number);
+		pcibios_fixup_bus(bus);
+		if (pci_is_root_bus(bus))
+			bus->is_added = 1;
+	}
+
 	for (pass=0; pass < 2; pass++)
 		list_for_each_entry(dev, &bus->devices, bus_list) {
 			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
@@ -1099,10 +1120,6 @@ unsigned int __devinit pci_scan_child_bu
 	return max;
 }
 
-void __attribute__((weak)) set_pci_bus_resources_arch_default(struct pci_bus *b)
-{
-}
-
 struct pci_bus * pci_create_bus(struct device *parent,
 		int bus, struct pci_ops *ops, void *sysdata)
 {
@@ -1114,7 +1131,7 @@ struct pci_bus * pci_create_bus(struct d
 	if (!b)
 		return NULL;
 
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev){
 		kfree(b);
 		return NULL;
@@ -1133,7 +1150,6 @@ struct pci_bus * pci_create_bus(struct d
 	list_add_tail(&b->node, &pci_root_buses);
 	up_write(&pci_bus_sem);
 
-	memset(dev, 0, sizeof(*dev));
 	dev->parent = parent;
 	dev->release = pci_release_bus_bridge_dev;
 	dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -1162,8 +1178,6 @@ struct pci_bus * pci_create_bus(struct d
 	b->resource[0] = &ioport_resource;
 	b->resource[1] = &iomem_resource;
 
-	set_pci_bus_resources_arch_default(b);
-
 	return b;
 
 dev_create_file_err:
@@ -1193,6 +1207,38 @@ struct pci_bus * __devinit pci_scan_bus_
 EXPORT_SYMBOL(pci_scan_bus_parented);
 
 #ifdef CONFIG_HOTPLUG
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+{
+	unsigned int max;
+	struct pci_dev *dev;
+
+	max = pci_scan_child_bus(bus);
+
+	down_read(&pci_bus_sem);
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+			if (dev->subordinate)
+				pci_bus_size_bridges(dev->subordinate);
+	up_read(&pci_bus_sem);
+
+	pci_bus_assign_resources(bus);
+	pci_enable_bridges(bus);
+	pci_bus_add_devices(bus);
+
+	return max;
+}
+EXPORT_SYMBOL_GPL(pci_rescan_bus);
+
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_scan_slot);
 EXPORT_SYMBOL(pci_scan_bridge);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/quirks.c linux-libre-2.6.30-gnu1/drivers/pci/quirks.c
--- linux-libre-2.6.29-gnu1/drivers/pci/quirks.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/quirks.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/kallsyms.h>
 #include <linux/dmi.h>
 #include <linux/pci-aspm.h>
+#include <linux/ioport.h>
 #include "pci.h"
 
 int isa_dma_bridge_buggy;
@@ -34,6 +35,69 @@ int pcie_mch_quirk;
 EXPORT_SYMBOL(pcie_mch_quirk);
 
 #ifdef CONFIG_PCI_QUIRKS
+/*
+ * This quirk function disables memory decoding and releases memory resources
+ * of the device specified by kernel's boot parameter 'pci=resource_alignment='.
+ * It also rounds up size to specified alignment.
+ * Later on, the kernel will assign page-aligned memory resource back
+ * to the device.
+ */
+static void __devinit quirk_resource_alignment(struct pci_dev *dev)
+{
+	int i;
+	struct resource *r;
+	resource_size_t align, size;
+	u16 command;
+
+	if (!pci_is_reassigndev(dev))
+		return;
+
+	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
+	    (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+		dev_warn(&dev->dev,
+			"Can't reassign resources to host bridge.\n");
+		return;
+	}
+
+	dev_info(&dev->dev,
+		"Disabling memory decoding and releasing memory resources.\n");
+	pci_read_config_word(dev, PCI_COMMAND, &command);
+	command &= ~PCI_COMMAND_MEMORY;
+	pci_write_config_word(dev, PCI_COMMAND, command);
+
+	align = pci_specified_resource_alignment(dev);
+	for (i=0; i < PCI_BRIDGE_RESOURCES; i++) {
+		r = &dev->resource[i];
+		if (!(r->flags & IORESOURCE_MEM))
+			continue;
+		size = resource_size(r);
+		if (size < align) {
+			size = align;
+			dev_info(&dev->dev,
+				"Rounding up size of resource #%d to %#llx.\n",
+				i, (unsigned long long)size);
+		}
+		r->end = size - 1;
+		r->start = 0;
+	}
+	/* Need to disable bridge's resource window,
+	 * to enable the kernel to reassign new resource
+	 * window later on.
+	 */
+	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+			r = &dev->resource[i];
+			if (!(r->flags & IORESOURCE_MEM))
+				continue;
+			r->end = resource_size(r) - 1;
+			r->start = 0;
+		}
+		pci_disable_bridge_window(dev);
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment);
+
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
  * PCI scanning code to "skip" this now blacklisted device.
@@ -1126,10 +1190,15 @@ static void __init asus_hides_smbus_host
 				 * its on-board VGA controller */
 				asus_hides_smbus = 1;
 			}
-		else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_IG)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_2)
 			switch(dev->subsystem_device) {
 			case 0x00b8: /* Compaq Evo D510 CMT */
 			case 0x00b9: /* Compaq Evo D510 SFF */
+				/* Motherboard doesn't have Host bridge
+				 * subvendor/subdevice IDs and on-board VGA
+				 * controller is disabled if an AGP card is
+				 * inserted, therefore checking USB UHCI
+				 * Controller #1 */
 				asus_hides_smbus = 1;
 			}
 		else if (dev->device == PCI_DEVICE_ID_INTEL_82815_CGC)
@@ -1154,7 +1223,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge);
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82810_IG3,	asus_hides_smbus_hostbridge);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82845G_IG,	asus_hides_smbus_hostbridge);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801DB_2,	asus_hides_smbus_hostbridge);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82815_CGC,	asus_hides_smbus_hostbridge);
 
 static void asus_hides_smbus_lpc(struct pci_dev *dev)
@@ -1664,9 +1733,13 @@ static void __devinit quirk_netmos(struc
 	 * of parallel ports and <S> is the number of serial ports.
 	 */
 	switch (dev->device) {
+	case PCI_DEVICE_ID_NETMOS_9835:
+		/* Well, this rule doesn't hold for the following 9835 device */
+		if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+				dev->subsystem_device == 0x0299)
+			return;
 	case PCI_DEVICE_ID_NETMOS_9735:
 	case PCI_DEVICE_ID_NETMOS_9745:
-	case PCI_DEVICE_ID_NETMOS_9835:
 	case PCI_DEVICE_ID_NETMOS_9845:
 	case PCI_DEVICE_ID_NETMOS_9855:
 		if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
@@ -1960,6 +2033,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AT
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
 
 /* Disable MSI on chipsets that are known to not support it */
 static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -2078,6 +2152,92 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NV
 			PCI_DEVICE_ID_NVIDIA_NVENET_15,
 			nvenet_msi_disable);
 
+static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+{
+	int pos, ttl = 48;
+	int found = 0;
+
+	/* check if there is HT MSI cap or enabled on this device */
+	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+	while (pos && ttl--) {
+		u8 flags;
+
+		if (found < 1)
+			found = 1;
+		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+					 &flags) == 0) {
+			if (flags & HT_MSI_FLAGS_ENABLE) {
+				if (found < 2) {
+					found = 2;
+					break;
+				}
+			}
+		}
+		pos = pci_find_next_ht_capability(dev, pos,
+						  HT_CAPTYPE_MSI_MAPPING);
+	}
+
+	return found;
+}
+
+static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge)
+{
+	struct pci_dev *dev;
+	int pos;
+	int i, dev_no;
+	int found = 0;
+
+	dev_no = host_bridge->devfn >> 3;
+	for (i = dev_no + 1; i < 0x20; i++) {
+		dev = pci_get_slot(host_bridge->bus, PCI_DEVFN(i, 0));
+		if (!dev)
+			continue;
+
+		/* found next host bridge ?*/
+		pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+		if (pos != 0) {
+			pci_dev_put(dev);
+			break;
+		}
+
+		if (ht_check_msi_mapping(dev)) {
+			found = 1;
+			pci_dev_put(dev);
+			break;
+		}
+		pci_dev_put(dev);
+	}
+
+	return found;
+}
+
+#define PCI_HT_CAP_SLAVE_CTRL0     4    /* link control */
+#define PCI_HT_CAP_SLAVE_CTRL1     8    /* link control to */
+
+static int __devinit is_end_of_ht_chain(struct pci_dev *dev)
+{
+	int pos, ctrl_off;
+	int end = 0;
+	u16 flags, ctrl;
+
+	pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+
+	if (!pos)
+		goto out;
+
+	pci_read_config_word(dev, pos + PCI_CAP_FLAGS, &flags);
+
+	ctrl_off = ((flags >> 10) & 1) ?
+			PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1;
+	pci_read_config_word(dev, pos + ctrl_off, &ctrl);
+
+	if (ctrl & (1 << 6))
+		end = 1;
+
+out:
+	return end;
+}
+
 static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
 {
 	struct pci_dev *host_bridge;
@@ -2102,6 +2262,11 @@ static void __devinit nv_ht_enable_msi_m
 	if (!found)
 		return;
 
+	/* don't enable end_device/host_bridge with leaf directly here */
+	if (host_bridge == dev && is_end_of_ht_chain(host_bridge) &&
+	    host_bridge_with_leaf(host_bridge))
+		goto out;
+
 	/* root did that ! */
 	if (msi_ht_cap_enabled(host_bridge))
 		goto out;
@@ -2132,44 +2297,12 @@ static void __devinit ht_disable_msi_map
 	}
 }
 
-static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
-{
-	int pos, ttl = 48;
-	int found = 0;
-
-	/* check if there is HT MSI cap or enabled on this device */
-	pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
-	while (pos && ttl--) {
-		u8 flags;
-
-		if (found < 1)
-			found = 1;
-		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
-					 &flags) == 0) {
-			if (flags & HT_MSI_FLAGS_ENABLE) {
-				if (found < 2) {
-					found = 2;
-					break;
-				}
-			}
-		}
-		pos = pci_find_next_ht_capability(dev, pos,
-						  HT_CAPTYPE_MSI_MAPPING);
-	}
-
-	return found;
-}
-
-static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
 {
 	struct pci_dev *host_bridge;
 	int pos;
 	int found;
 
-	/* Enabling HT MSI mapping on this device breaks MCP51 */
-	if (dev->device == 0x270)
-		return;
-
 	/* check if there is HT MSI cap or enabled on this device */
 	found = ht_check_msi_mapping(dev);
 
@@ -2193,7 +2326,10 @@ static void __devinit nv_msi_ht_cap_quir
 		/* Host bridge is to HT */
 		if (found == 1) {
 			/* it is not enabled, try to enable it */
-			nv_ht_enable_msi_mapping(dev);
+			if (all)
+				ht_enable_msi_mapping(dev);
+			else
+				nv_ht_enable_msi_mapping(dev);
 		}
 		return;
 	}
@@ -2205,8 +2341,20 @@ static void __devinit nv_msi_ht_cap_quir
 	/* Host bridge is not to HT, disable HT MSI mapping on this device */
 	ht_disable_msi_mapping(dev);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+
+static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev)
+{
+	return __nv_msi_ht_cap_quirk(dev, 1);
+}
+
+static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
+{
+	return __nv_msi_ht_cap_quirk(dev, 0);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {
@@ -2268,6 +2416,54 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AT
 
 #endif /* CONFIG_PCI_MSI */
 
+#ifdef CONFIG_PCI_IOV
+
+/*
+ * For Intel 82576 SR-IOV NIC, if BIOS doesn't allocate resources for the
+ * SR-IOV BARs, zero the Flash BAR and program the SR-IOV BARs to use the
+ * old Flash Memory Space.
+ */
+static void __devinit quirk_i82576_sriov(struct pci_dev *dev)
+{
+	int pos, flags;
+	u32 bar, start, size;
+
+	if (PAGE_SIZE > 0x10000)
+		return;
+
+	flags = pci_resource_flags(dev, 0);
+	if ((flags & PCI_BASE_ADDRESS_SPACE) !=
+			PCI_BASE_ADDRESS_SPACE_MEMORY ||
+	    (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) !=
+			PCI_BASE_ADDRESS_MEM_TYPE_32)
+		return;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+	if (!pos)
+		return;
+
+	pci_read_config_dword(dev, pos + PCI_SRIOV_BAR, &bar);
+	if (bar & PCI_BASE_ADDRESS_MEM_MASK)
+		return;
+
+	start = pci_resource_start(dev, 1);
+	size = pci_resource_len(dev, 1);
+	if (!start || size != 0x400000 || start & (size - 1))
+		return;
+
+	pci_resource_flags(dev, 1) = 0;
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
+	pci_write_config_dword(dev, pos + PCI_SRIOV_BAR, start);
+	pci_write_config_dword(dev, pos + PCI_SRIOV_BAR + 12, start + size / 2);
+
+	dev_info(&dev->dev, "use Flash Memory Space for SR-IOV BARs\n");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
+
+#endif	/* CONFIG_PCI_IOV */
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 			  struct pci_fixup *end)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/remove.c linux-libre-2.6.30-gnu1/drivers/pci/remove.c
--- linux-libre-2.6.29-gnu1/drivers/pci/remove.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/remove.c	2009-06-09 23:05:27.000000000 -0400
@@ -71,6 +71,9 @@ void pci_remove_bus(struct pci_bus *pci_
 	down_write(&pci_bus_sem);
 	list_del(&pci_bus->node);
 	up_write(&pci_bus_sem);
+	if (!pci_bus->is_added)
+		return;
+
 	pci_remove_legacy_files(pci_bus);
 	device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
 	device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
@@ -92,6 +95,7 @@ EXPORT_SYMBOL(pci_remove_bus);
  */
 void pci_remove_bus_device(struct pci_dev *dev)
 {
+	pci_stop_bus_device(dev);
 	if (dev->subordinate) {
 		struct pci_bus *b = dev->subordinate;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/search.c linux-libre-2.6.30-gnu1/drivers/pci/search.c
--- linux-libre-2.6.29-gnu1/drivers/pci/search.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/search.c	2009-06-09 23:05:27.000000000 -0400
@@ -29,7 +29,7 @@ pci_find_upstream_pcie_bridge(struct pci
 	if (pdev->is_pcie)
 		return NULL;
 	while (1) {
-		if (!pdev->bus->self)
+		if (!pdev->bus->parent)
 			break;
 		pdev = pdev->bus->self;
 		/* a p2p bridge */
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/setup-bus.c linux-libre-2.6.30-gnu1/drivers/pci/setup-bus.c
--- linux-libre-2.6.29-gnu1/drivers/pci/setup-bus.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/setup-bus.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 
 
-static void pbus_assign_resources_sorted(struct pci_bus *bus)
+static void pbus_assign_resources_sorted(const struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 	struct resource *res;
@@ -144,6 +144,9 @@ static void pci_setup_bridge(struct pci_
 	struct pci_bus_region region;
 	u32 l, bu, lu, io_upper16;
 
+	if (pci_is_enabled(bridge))
+		return;
+
 	dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
 		 pci_domain_nr(bus), bus->number);
 
@@ -495,7 +498,7 @@ void __ref pci_bus_size_bridges(struct p
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
-void __ref pci_bus_assign_resources(struct pci_bus *bus)
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
 {
 	struct pci_bus *b;
 	struct pci_dev *dev;
@@ -533,11 +536,13 @@ static void pci_bus_dump_res(struct pci_
 
         for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
                 struct resource *res = bus->resource[i];
-                if (!res)
+                if (!res || !res->end)
                         continue;
 
 		dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i,
-			   (res->flags & IORESOURCE_IO) ? "io: " : "mem:", res);
+			   (res->flags & IORESOURCE_IO) ? "io: " :
+			    ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"),
+			   res);
         }
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/setup-res.c linux-libre-2.6.30-gnu1/drivers/pci/setup-res.c
--- linux-libre-2.6.29-gnu1/drivers/pci/setup-res.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/setup-res.c	2009-06-09 23:05:27.000000000 -0400
@@ -120,6 +120,21 @@ int pci_claim_resource(struct pci_dev *d
 	return err;
 }
 
+#ifdef CONFIG_PCI_QUIRKS
+void pci_disable_bridge_window(struct pci_dev *dev)
+{
+	dev_dbg(&dev->dev, "Disabling bridge window.\n");
+
+	/* MMIO Base/Limit */
+	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
+
+	/* Prefetchable MMIO Base/Limit */
+	pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
+	pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
+	pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
+}
+#endif	/* CONFIG_PCI_QUIRKS */
+
 int pci_assign_resource(struct pci_dev *dev, int resno)
 {
 	struct pci_bus *bus = dev->bus;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pci/slot.c linux-libre-2.6.30-gnu1/drivers/pci/slot.c
--- linux-libre-2.6.29-gnu1/drivers/pci/slot.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pci/slot.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * drivers/pci/slot.c
  * Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
- * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P.
- * 	Alex Chiang <achiang@hp.com>
+ * Copyright (C) 2006-2009 Hewlett-Packard Development Company, L.P.
+ *	Alex Chiang <achiang@hp.com>
  */
 
 #include <linux/kobject.h>
@@ -52,8 +52,8 @@ static void pci_slot_release(struct kobj
 	struct pci_dev *dev;
 	struct pci_slot *slot = to_pci_slot(kobj);
 
-	pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
-		 slot->bus->number, slot->number);
+	dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
+		slot->number, pci_slot_name(slot));
 
 	list_for_each_entry(dev, &slot->bus->devices, bus_list)
 		if (PCI_SLOT(dev->devfn) == slot->number)
@@ -248,9 +248,8 @@ placeholder:
 		if (PCI_SLOT(dev->devfn) == slot_nr)
 			dev->slot = slot;
 
-	/* Don't care if debug printk has a -1 for slot_nr */
-	pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
-		 __func__, pci_domain_nr(parent), parent->number, slot_nr);
+	dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
+		slot_nr, pci_slot_name(slot));
 
 out:
 	kfree(slot_name);
@@ -265,8 +264,8 @@ EXPORT_SYMBOL_GPL(pci_create_slot);
 
 /**
  * pci_renumber_slot - update %struct pci_slot -> number
- * @slot - %struct pci_slot to update
- * @slot_nr - new number for slot
+ * @slot: &struct pci_slot to update
+ * @slot_nr: new number for slot
  *
  * The primary purpose of this interface is to allow callers who earlier
  * created a placeholder slot in pci_create_slot() by passing a -1 as
@@ -299,9 +298,8 @@ EXPORT_SYMBOL_GPL(pci_renumber_slot);
  */
 void pci_destroy_slot(struct pci_slot *slot)
 {
-	pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
-		 atomic_read(&slot->kobj.kref.refcount) - 1,
-		 pci_domain_nr(slot->bus), slot->bus->number, slot->number);
+	dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
+		slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
 
 	down_write(&pci_bus_sem);
 	kobject_put(&slot->kobj);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/au1000_generic.c linux-libre-2.6.30-gnu1/drivers/pcmcia/au1000_generic.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/au1000_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/au1000_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -468,13 +468,13 @@ out:
 	return ret;
 }
 
-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
 {
-	struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
 	int i;
 
 	mutex_lock(&pcmcia_sockets_lock);
-	dev_set_drvdata(dev, NULL);
+	platform_set_drvdata(dev, NULL);
 
 	for (i = 0; i < sinfo->nskt; i++) {
 		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct devi
  * PCMCIA "Driver" API
  */
 
-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
 {
 	int i, ret = -ENODEV;
 
 	mutex_lock(&pcmcia_sockets_lock);
 	for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
-		ret = au1x00_pcmcia_hw_init[i](dev);
+		ret = au1x00_pcmcia_hw_init[i](&dev->dev);
 		if (ret == 0)
 			break;
 	}
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struc
 	return ret;
 }
 
+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
 
-static struct device_driver au1x00_pcmcia_driver = {
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver au1x00_pcmcia_driver = {
+	.driver = {
+		.name		= "au1x00-pcmcia",
+		.owner		= THIS_MODULE,
+	},
 	.probe		= au1x00_drv_pcmcia_probe,
 	.remove		= au1x00_drv_pcmcia_remove,
-	.name		= "au1x00-pcmcia",
-	.bus		= &platform_bus_type,
-	.suspend	= pcmcia_socket_dev_suspend,
-	.resume		= pcmcia_socket_dev_resume,
+	.suspend 	= au1x00_drv_pcmcia_suspend,
+	.resume 	= au1x00_drv_pcmcia_resume,
 };
 
 
@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmci
 static int __init au1x00_pcmcia_init(void)
 {
 	int error = 0;
-	if ((error = driver_register(&au1x00_pcmcia_driver)))
-		return error;
+	error = platform_driver_register(&au1x00_pcmcia_driver);
 	return error;
 }
 
@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(voi
  */
 static void __exit au1x00_pcmcia_exit(void)
 {
-	driver_unregister(&au1x00_pcmcia_driver);
+	platform_driver_unregister(&au1x00_pcmcia_driver);
 }
 
 module_init(au1x00_pcmcia_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/i82365.c linux-libre-2.6.30-gnu1/drivers/pcmcia/i82365.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/i82365.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/i82365.c	2009-06-09 23:05:27.000000000 -0400
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socke
 	return 0;
 }
 
+static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
 static struct pccard_operations pcic_operations = {
 	.init			= pcic_init,
 	.get_status		= pcic_get_status,
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_ope
 
 /*====================================================================*/
 
-static struct device_driver i82365_driver = {
-	.name = "i82365",
-	.bus = &platform_bus_type,
-	.suspend = pcmcia_socket_dev_suspend,
-	.resume = pcmcia_socket_dev_resume,
+static struct platform_driver i82365_driver = {
+	.driver = {
+		.name = "i82365",
+		.owner		= THIS_MODULE,
+	},
+	.suspend 	= i82365_drv_pcmcia_suspend,
+	.resume 	= i82365_drv_pcmcia_resume,
 };
 
 static struct platform_device *i82365_device;
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void)
 {
     int i, ret;
 
-    ret = driver_register(&i82365_driver);
+    ret = platform_driver_register(&i82365_driver);
     if (ret)
 	goto err_out;
 
@@ -1337,7 +1349,7 @@ err_dev_unregister:
 	pnp_disable_dev(i82365_pnpdev);
 #endif
 err_driver_unregister:
-    driver_unregister(&i82365_driver);
+    platform_driver_unregister(&i82365_driver);
 err_out:
     return ret;
 } /* init_i82365 */
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void)
     if (i82365_pnpdev)
     		pnp_disable_dev(i82365_pnpdev);
 #endif
-    driver_unregister(&i82365_driver);
+    platform_driver_unregister(&i82365_driver);
 } /* exit_i82365 */
 
 module_init(init_i82365);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/m32r_cfc.c linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_cfc.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/m32r_cfc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_cfc.c	2009-06-09 23:05:27.000000000 -0400
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_oper
 	.set_mem_map		= pcc_set_mem_map,
 };
 
+static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
 /*====================================================================*/
 
-static struct device_driver pcc_driver = {
-	.name = "cfc",
-	.bus = &platform_bus_type,
-	.suspend = pcmcia_socket_dev_suspend,
-	.resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+	.driver = {
+		.name		= "cfc",
+		.owner		= THIS_MODULE,
+	},
+	.suspend 	= cfc_drv_pcmcia_suspend,
+	.resume 	= cfc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void)
 {
 	int i, ret;
 
-	ret = driver_register(&pcc_driver);
+	ret = platform_driver_register(&pcc_driver);
 	if (ret)
 		return ret;
 
 	ret = platform_device_register(&pcc_device);
 	if (ret){
-		driver_unregister(&pcc_driver);
+		platform_driver_unregister(&pcc_driver);
 		return ret;
 	}
 
@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void)
 	if (pcc_sockets == 0) {
 		printk("socket is not found.\n");
 		platform_device_unregister(&pcc_device);
-		driver_unregister(&pcc_driver);
+		platform_driver_unregister(&pcc_driver);
 		return -ENODEV;
 	}
 
@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void)
 	if (poll_interval != 0)
 		del_timer_sync(&poll_timer);
 
-	driver_unregister(&pcc_driver);
+	platform_driver_unregister(&pcc_driver);
 } /* exit_m32r_pcc */
 
 module_init(init_m32r_pcc);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/m32r_pcc.c linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_pcc.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/m32r_pcc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_pcc.c	2009-06-09 23:05:27.000000000 -0400
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_oper
 	.set_mem_map		= pcc_set_mem_map,
 };
 
+static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
 /*====================================================================*/
 
-static struct device_driver pcc_driver = {
-	.name = "pcc",
-	.bus = &platform_bus_type,
-	.suspend = pcmcia_socket_dev_suspend,
-	.resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+	.driver = {
+		.name		= "pcc",
+		.owner		= THIS_MODULE,
+	},
+	.suspend 	= pcc_drv_pcmcia_suspend,
+	.resume 	= pcc_drv_pcmcia_resume,
 };
 
 static struct platform_device pcc_device = {
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void)
 {
 	int i, ret;
 
-	ret = driver_register(&pcc_driver);
+	ret = platform_driver_register(&pcc_driver);
 	if (ret)
 		return ret;
 
 	ret = platform_device_register(&pcc_device);
 	if (ret){
-		driver_unregister(&pcc_driver);
+		platform_driver_unregister(&pcc_driver);
 		return ret;
 	}
 
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void)
 	if (pcc_sockets == 0) {
 		printk("socket is not found.\n");
 		platform_device_unregister(&pcc_device);
-		driver_unregister(&pcc_driver);
+		platform_driver_unregister(&pcc_driver);
 		return -ENODEV;
 	}
 
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void)
 	if (poll_interval != 0)
 		del_timer_sync(&poll_timer);
 
-	driver_unregister(&pcc_driver);
+	platform_driver_unregister(&pcc_driver);
 } /* exit_m32r_pcc */
 
 module_init(init_m32r_pcc);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_base.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_base.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,7 +28,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <mach/pxa-regs.h>
 #include <mach/pxa2xx-regs.h>
 #include <asm/mach-types.h>
 
@@ -39,6 +38,44 @@
 #include "soc_common.h"
 #include "pxa2xx_base.h"
 
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp	0x04000000	/* PCMCIA Partition Space [byte]   */
+#define PCMCIASp	(4*PCMCIAPrtSp)	/* PCMCIA Space [byte]             */
+#define PCMCIAIOSp	PCMCIAPrtSp	/* PCMCIA I/O Space [byte]         */
+#define PCMCIAAttrSp	PCMCIAPrtSp	/* PCMCIA Attribute Space [byte]   */
+#define PCMCIAMemSp	PCMCIAPrtSp	/* PCMCIA Memory Space [byte]      */
+
+#define PCMCIA0Sp	PCMCIASp	/* PCMCIA 0 Space [byte]           */
+#define PCMCIA0IOSp	PCMCIAIOSp	/* PCMCIA 0 I/O Space [byte]       */
+#define PCMCIA0AttrSp	PCMCIAAttrSp	/* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp	PCMCIAMemSp	/* PCMCIA 0 Memory Space [byte]    */
+
+#define PCMCIA1Sp	PCMCIASp	/* PCMCIA 1 Space [byte]           */
+#define PCMCIA1IOSp	PCMCIAIOSp	/* PCMCIA 1 I/O Space [byte]       */
+#define PCMCIA1AttrSp	PCMCIAAttrSp	/* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp	PCMCIAMemSp	/* PCMCIA 1 Memory Space [byte]    */
+
+#define _PCMCIA(Nb)			/* PCMCIA [0..1]                   */ \
+			(0x20000000 + (Nb) * PCMCIASp)
+#define _PCMCIAIO(Nb)	_PCMCIA(Nb)	/* PCMCIA I/O [0..1]               */
+#define _PCMCIAAttr(Nb)			/* PCMCIA Attribute [0..1]         */ \
+			(_PCMCIA(Nb) + 2 * PCMCIAPrtSp)
+#define _PCMCIAMem(Nb)			/* PCMCIA Memory [0..1]            */ \
+			(_PCMCIA(Nb) + 3 * PCMCIAPrtSp)
+
+#define _PCMCIA0	_PCMCIA(0)	/* PCMCIA 0                        */
+#define _PCMCIA0IO	_PCMCIAIO(0)	/* PCMCIA 0 I/O                    */
+#define _PCMCIA0Attr	_PCMCIAAttr(0)	/* PCMCIA 0 Attribute              */
+#define _PCMCIA0Mem	_PCMCIAMem(0)	/* PCMCIA 0 Memory                 */
+
+#define _PCMCIA1	_PCMCIA(1)	/* PCMCIA 1                        */
+#define _PCMCIA1IO	_PCMCIAIO(1)	/* PCMCIA 1 I/O                    */
+#define _PCMCIA1Attr	_PCMCIAAttr(1)	/* PCMCIA 1 Attribute              */
+#define _PCMCIA1Mem	_PCMCIAMem(1)	/* PCMCIA 1 Memory                 */
+
 
 #define MCXX_SETUP_MASK     (0x7f)
 #define MCXX_ASST_MASK      (0x1f)
@@ -177,29 +214,73 @@ static void pxa2xx_configure_sockets(str
 	MECR |= MECR_CIT;
 
 	/* Set MECR:NOS (Number Of Sockets) */
-	if (ops->nr > 1 || machine_is_viper())
+	if ((ops->first + ops->nr) > 1 || machine_is_viper())
 		MECR |= MECR_NOS;
 	else
 		MECR &= ~MECR_NOS;
 }
 
+static const char *skt_names[] = {
+	"PCMCIA socket 0",
+	"PCMCIA socket 1",
+};
+
+#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 ret;
+	int i, ret;
 	struct pcmcia_low_level *ops;
+	struct skt_dev_info *sinfo;
+	struct soc_pcmcia_socket *skt;
 
 	if (!dev || !dev->platform_data)
 		return -ENODEV;
 
 	ops = (struct pcmcia_low_level *)dev->platform_data;
 
+	sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
+	if (!sinfo)
+		return -ENOMEM;
+
+	sinfo->nskt = ops->nr;
+
+	/* Initialize processor specific parameters */
+	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->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;
+	}
+
 	/* 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, ops->first, ops->nr);
+	ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
 
 	if (!ret)
 		pxa2xx_configure_sockets(dev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_cm_x255.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/gpio.h>
 
 #include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
 
 #include "soc_common.h"
 
@@ -64,7 +63,7 @@ static void cmx255_pcmcia_socket_state(s
 				       struct pcmcia_state *state)
 {
 	int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
-	int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+	int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
 
 	state->detect = !gpio_get_value(cd);
 	state->ready  = !!gpio_get_value(rdy);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_cm_x270.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/gpio.h>
 
 #include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
 
 #include "soc_common.h"
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_e740.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_e740.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_e740.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_e740.c	2009-06-09 23:05:27.000000000 -0400
@@ -16,8 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
 #include <mach/eseries-gpio.h>
 
 #include <asm/irq.h>
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_lubbock.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_lubbock.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_lubbock.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_lubbock.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,7 +24,6 @@
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
 #include <mach/lubbock.h>
 
 #include "sa1111_generic.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_mainstone.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_mainstone.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_mainstone.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_mainstone.c	2009-06-09 23:05:27.000000000 -0400
@@ -21,11 +21,10 @@
 
 #include <pcmcia/ss.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
 
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
 #include <mach/mainstone.h>
 
 #include "soc_common.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_palmld.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_palmld.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_palmld.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_palmld.c	2009-06-09 23:05:27.000000000 -0400
@@ -98,8 +98,8 @@ static void palmld_pcmcia_socket_suspend
 static struct pcmcia_low_level palmld_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 
-	.first			= 0,
-	.nr			= 2,
+	.first			= 1,
+	.nr			= 1,
 
 	.hw_init		= palmld_pcmcia_hw_init,
 	.hw_shutdown		= palmld_pcmcia_hw_shutdown,
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_sharpsl.c	2009-06-09 23:05:27.000000000 -0400
@@ -255,6 +255,9 @@ static int __init sharpsl_pcmcia_init(vo
 {
 	int ret;
 
+	if (!platform_scoop_config)
+		return -ENODEV;
+
 	sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs;
 	sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_trizeps4.c	2009-06-09 23:05:27.000000000 -0400
@@ -22,8 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/irq.h>
 
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
 #include <mach/trizeps4.h>
 
 #include "soc_common.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_viper.c linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_viper.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/pxa2xx_viper.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_viper.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,7 +26,6 @@
 
 #include <asm/irq.h>
 
-#include <mach/pxa-regs.h>
 #include <mach/viper.h>
 #include <asm/mach-types.h>
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/rsrc_mgr.c linux-libre-2.6.30-gnu1/drivers/pcmcia/rsrc_mgr.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/rsrc_mgr.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/rsrc_mgr.c	2009-06-09 23:05:27.000000000 -0400
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_re
 		unsigned long align, struct pcmcia_socket *s)
 {
 	struct resource *res = make_resource(0, num, IORESOURCE_IO,
-					     s->dev.bus_id);
+					     dev_name(&s->dev));
 	struct pcmcia_align_data data;
 	unsigned long min = base;
 	int ret;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1100_generic.c linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_generic.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1100_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(st
 #endif
 };
 
-static int sa11x0_drv_pcmcia_probe(struct device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
 {
 	int i, ret = -ENODEV;
 
@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struc
 	 * Initialise any "on-board" PCMCIA sockets.
 	 */
 	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
-		ret = sa11x0_pcmcia_hw_init[i](dev);
+		ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
 		if (ret == 0)
 			break;
 	}
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struc
 	return ret;
 }
 
-static struct device_driver sa11x0_pcmcia_driver = {
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+	return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver sa11x0_pcmcia_driver = {
+	.driver = {
+		.name		= "sa11x0-pcmcia",
+		.owner		= THIS_MODULE,
+	},
 	.probe		= sa11x0_drv_pcmcia_probe,
-	.remove		= soc_common_drv_pcmcia_remove,
-	.name		= "sa11x0-pcmcia",
-	.bus		= &platform_bus_type,
-	.suspend 	= pcmcia_socket_dev_suspend,
-	.resume 	= pcmcia_socket_dev_resume,
+	.remove		= sa11x0_drv_pcmcia_remove,
+	.suspend 	= sa11x0_drv_pcmcia_suspend,
+	.resume 	= sa11x0_drv_pcmcia_resume,
 };
 
 /* sa11x0_pcmcia_init()
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmci
  */
 static int __init sa11x0_pcmcia_init(void)
 {
-	return driver_register(&sa11x0_pcmcia_driver);
+	return platform_driver_register(&sa11x0_pcmcia_driver);
 }
 
 /* sa11x0_pcmcia_exit()
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(voi
  */
 static void __exit sa11x0_pcmcia_exit(void)
 {
-	driver_unregister(&sa11x0_pcmcia_driver);
+	platform_driver_unregister(&sa11x0_pcmcia_driver);
 }
 
 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1100_h3600.c linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_h3600.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1100_h3600.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_h3600.c	2009-06-09 23:05:27.000000000 -0400
@@ -37,9 +37,9 @@ static void h3600_pcmcia_hw_shutdown(str
 	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
   
 	/* Disable CF bus: */
-	clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
-	clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-	set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+	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);
 }
 
 static void
@@ -79,10 +79,7 @@ h3600_pcmcia_configure_socket(struct soc
 		return -1;
 	}
 
-	if (state->flags & SS_RESET)
-		set_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
-	else
-		clr_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
+	assign_h3600_egpio(IPAQ_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
 
 	/* Silently ignore Vpp, output enable, speaker enable. */
 
@@ -92,9 +89,9 @@ h3600_pcmcia_configure_socket(struct soc
 static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 {
 	/* Enable CF bus: */
-	set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
-	set_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-	clr_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+	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);
 
 	msleep(10);
 
@@ -112,10 +109,10 @@ static void h3600_pcmcia_socket_suspend(
 	 * socket 0 then socket 1.
 	 */
 	if (skt->nr == 1) {
-		clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-		clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+		assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
+		assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
 		/* hmm, does this suck power? */
-		set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+		assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
 	}
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1111_generic.c linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1111_generic.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/sa1111_generic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1111_generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,12 +11,12 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/io.h>
 
 #include <pcmcia/ss.h>
 
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include "sa1111_generic.h"
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/sa11xx_base.c linux-libre-2.6.30-gnu1/drivers/pcmcia/sa11xx_base.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/sa11xx_base.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/sa11xx_base.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,9 +36,9 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 
@@ -163,9 +163,55 @@ sa1100_pcmcia_show_timing(struct soc_pcm
 	return p - buf;
 }
 
+static const char *skt_names[] = {
+	"PCMCIA socket 0",
+	"PCMCIA socket 1",
+};
+
+#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)
 {
+	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_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;
+	}
+
 	/*
 	 * set default MECR calculation if the board specific
 	 * code did not specify one...
@@ -180,7 +226,7 @@ int sa11xx_drv_pcmcia_probe(struct devic
 	ops->frequency_change = sa1100_pcmcia_frequency_change;
 #endif
 
-	return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
+	return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
 }
 EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/soc_common.c linux-libre-2.6.30-gnu1/drivers/pcmcia/soc_common.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/soc_common.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/soc_common.c	2009-06-09 23:05:27.000000000 -0400
@@ -49,11 +49,6 @@
 
 #include "soc_common.h"
 
-/* FIXME: platform dependent resource declaration has to move out of this file */
-#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
-#endif
-
 #ifdef CONFIG_PCMCIA_DEBUG
 
 static int pc_debug;
@@ -581,19 +576,6 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
 LIST_HEAD(soc_pcmcia_sockets);
 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
-static const char *skt_names[] = {
-	"PCMCIA socket 0",
-	"PCMCIA socket 1",
-};
-
-struct skt_dev_info {
-	int nskt;
-	struct soc_pcmcia_socket skt[0];
-};
-
-#define SKT_DEV_INFO_SIZE(n) \
-	(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
-
 #ifdef CONFIG_CPU_FREQ
 static int
 soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
@@ -637,26 +619,18 @@ static int soc_pcmcia_cpufreq_register(v
 static void soc_pcmcia_cpufreq_unregister(void) {}
 #endif
 
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
+int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
+				struct skt_dev_info *sinfo)
 {
-	struct skt_dev_info *sinfo;
 	struct soc_pcmcia_socket *skt;
 	int ret, i;
 
 	mutex_lock(&soc_pcmcia_sockets_lock);
 
-	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
-	if (!sinfo) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	sinfo->nskt = nr;
-
 	/*
 	 * Initialise the per-socket structure.
 	 */
-	for (i = 0; i < nr; i++) {
+	for (i = 0; i < sinfo->nskt; i++) {
 		skt = &sinfo->skt[i];
 
 		skt->socket.ops = &soc_common_pcmcia_operations;
@@ -668,43 +642,21 @@ int soc_common_drv_pcmcia_probe(struct d
 		skt->poll_timer.data = (unsigned long)skt;
 		skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
 
-		skt->nr		= first + i;
-		skt->irq	= NO_IRQ;
 		skt->dev	= dev;
 		skt->ops	= ops;
 
-		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;
-
 		ret = request_resource(&iomem_resource, &skt->res_skt);
 		if (ret)
 			goto out_err_1;
 
-		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;
-
 		ret = request_resource(&skt->res_skt, &skt->res_io);
 		if (ret)
 			goto out_err_2;
 
-		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;
-
 		ret = request_resource(&skt->res_skt, &skt->res_mem);
 		if (ret)
 			goto out_err_3;
 
-		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 = request_resource(&skt->res_skt, &skt->res_attr);
 		if (ret)
 			goto out_err_4;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/soc_common.h linux-libre-2.6.30-gnu1/drivers/pcmcia/soc_common.h
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/soc_common.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/soc_common.h	2009-06-09 23:05:27.000000000 -0400
@@ -58,6 +58,11 @@ struct soc_pcmcia_socket {
 	struct list_head	node;
 };
 
+struct skt_dev_info {
+	int nskt;
+	struct soc_pcmcia_socket skt[0];
+};
+
 struct pcmcia_state {
   unsigned detect: 1,
             ready: 1,
@@ -132,7 +137,7 @@ extern void soc_common_pcmcia_get_timing
 
 extern struct list_head soc_pcmcia_sockets;
 
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
+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);
 
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/tcic.c linux-libre-2.6.30-gnu1/drivers/pcmcia/tcic.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/tcic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/tcic.c	2009-06-09 23:05:27.000000000 -0400
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void)
     return id;
 }
 
+static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
 /*====================================================================*/
 
-static struct device_driver tcic_driver = {
-	.name = "tcic-pcmcia",
-	.bus = &platform_bus_type,
-	.suspend = pcmcia_socket_dev_suspend,
-	.resume = pcmcia_socket_dev_resume,
+static struct platform_driver tcic_driver = {
+	.driver = {
+		.name = "tcic-pcmcia",
+		.owner		= THIS_MODULE,
+	},
+	.suspend 	= tcic_drv_pcmcia_suspend,
+	.resume 	= tcic_drv_pcmcia_resume,
 };
 
 static struct platform_device tcic_device = {
@@ -383,7 +395,7 @@ static int __init init_tcic(void)
     int i, sock, ret = 0;
     u_int mask, scan;
 
-    if (driver_register(&tcic_driver))
+    if (platform_driver_register(&tcic_driver))
 	return -1;
     
     printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
@@ -391,7 +403,7 @@ static int __init init_tcic(void)
 
     if (!request_region(tcic_base, 16, "tcic-2")) {
 	printk("could not allocate ports,\n ");
-	driver_unregister(&tcic_driver);
+	platform_driver_unregister(&tcic_driver);
 	return -ENODEV;
     }
     else {
@@ -414,7 +426,7 @@ static int __init init_tcic(void)
     if (sock == 0) {
 	printk("not found.\n");
 	release_region(tcic_base, 16);
-	driver_unregister(&tcic_driver);
+	platform_driver_unregister(&tcic_driver);
 	return -ENODEV;
     }
 
@@ -542,7 +554,7 @@ static void __exit exit_tcic(void)
     }
 
     platform_device_unregister(&tcic_device);
-    driver_unregister(&tcic_driver);
+    platform_driver_unregister(&tcic_driver);
 } /* exit_tcic */
 
 /*====================================================================*/
diff -druNp linux-libre-2.6.29-gnu1/drivers/pcmcia/vrc4171_card.c linux-libre-2.6.30-gnu1/drivers/pcmcia/vrc4171_card.c
--- linux-libre-2.6.29-gnu1/drivers/pcmcia/vrc4171_card.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pcmcia/vrc4171_card.c	2009-06-09 23:05:27.000000000 -0400
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(
 
 __setup("vrc4171_card=", vrc4171_card_setup);
 
-static struct device_driver vrc4171_card_driver = {
-	.name		= vrc4171_card_name,
-	.bus		= &platform_bus_type,
-	.suspend	= pcmcia_socket_dev_suspend,
-	.resume		= pcmcia_socket_dev_resume,
+static int vrc4171_card_suspend(struct platform_device *dev,
+				     pm_message_t state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int vrc4171_card_resume(struct platform_device *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver vrc4171_card_driver = {
+	.driver = {
+		.name		= vrc4171_card_name,
+		.owner		= THIS_MODULE,
+	},
+	.suspend	= vrc4171_card_suspend,
+	.resume		= vrc4171_card_resume,
 };
 
 static int __devinit vrc4171_card_init(void)
 {
 	int retval;
 
-	retval = driver_register(&vrc4171_card_driver);
+	retval = platform_driver_register(&vrc4171_card_driver);
 	if (retval < 0)
 		return retval;
 
 	retval = platform_device_register(&vrc4171_card_device);
 	if (retval < 0) {
-		driver_unregister(&vrc4171_card_driver);
+		platform_driver_unregister(&vrc4171_card_driver);
 		return retval;
 	}
 
@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(v
 	if (retval < 0) {
 		vrc4171_remove_sockets();
 		platform_device_unregister(&vrc4171_card_device);
-		driver_unregister(&vrc4171_card_driver);
+		platform_driver_unregister(&vrc4171_card_driver);
 		return retval;
 	}
 
-	printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq);
+	printk(KERN_INFO "%s, connected to IRQ %d\n",
+		vrc4171_card_driver.driver.name, vrc4171_irq);
 
 	return 0;
 }
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(
 	free_irq(vrc4171_irq, vrc4171_sockets);
 	vrc4171_remove_sockets();
 	platform_device_unregister(&vrc4171_card_device);
-	driver_unregister(&vrc4171_card_driver);
+	platform_driver_unregister(&vrc4171_card_driver);
 }
 
 module_init(vrc4171_card_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/acer-wmi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/acer-wmi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/acer-wmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/acer-wmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  Acer WMI Laptop Extras
  *
- *  Copyright (C) 2007-2008	Carlos Corbacho <carlos@strangeworlds.co.uk>
+ *  Copyright (C) 2007-2009	Carlos Corbacho <carlos@strangeworlds.co.uk>
  *
  *  Based on acer_acpi:
  *    Copyright (C) 2005-2007	E.M. Smith
@@ -225,6 +225,25 @@ static struct quirk_entry quirk_fujitsu_
 	.wireless = 2,
 };
 
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+	{
+		.ident = "Acer Aspire One (SSD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+		},
+	},
+	{
+		.ident = "Acer Aspire One (HDD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+		},
+	},
+	{}
+};
+
 static struct dmi_system_id acer_quirks[] = {
 	{
 		.callback = dmi_matched,
@@ -1117,11 +1136,17 @@ static int __devinit acer_platform_probe
 	}
 
 	err = acer_rfkill_init(&device->dev);
+	if (err)
+		goto error_rfkill;
 
 	return err;
 
+error_rfkill:
+	if (has_cap(ACER_CAP_BRIGHTNESS))
+		acer_backlight_exit();
 error_brightness:
-	acer_led_exit();
+	if (has_cap(ACER_CAP_MAILLED))
+		acer_led_exit();
 error_mailled:
 	return err;
 }
@@ -1254,6 +1279,12 @@ static int __init acer_wmi_init(void)
 
 	printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
 
+	if (dmi_check_system(acer_blacklist)) {
+		printk(ACER_INFO "Blacklisted hardware detected - "
+				"not loading\n");
+		return -ENODEV;
+	}
+
 	find_quirks();
 
 	/*
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/asus_acpi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/asus_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/asus_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/asus_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -987,7 +987,6 @@ asus_proc_add(char *name, proc_writefunc
 	proc->write_proc = writefunc;
 	proc->read_proc = readfunc;
 	proc->data = acpi_driver_data(device);
-	proc->owner = THIS_MODULE;
 	proc->uid = asus_uid;
 	proc->gid = asus_gid;
 	return 0;
@@ -1020,7 +1019,6 @@ static int asus_hotk_add_fs(struct acpi_
 	if (proc) {
 		proc->read_proc = proc_read_info;
 		proc->data = acpi_driver_data(device);
-		proc->owner = THIS_MODULE;
 		proc->uid = asus_uid;
 		proc->gid = asus_gid;
 	} else {
@@ -1436,7 +1434,6 @@ static int __init asus_acpi_init(void)
 		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
 		return -ENODEV;
 	}
-	asus_proc_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&asus_hotk_driver);
 	if (result < 0) {
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/asus-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/asus-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/asus-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/asus-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] =
 	{KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
 	{KE_KEY, 0x40, KEY_PREVIOUSSONG},
 	{KE_KEY, 0x41, KEY_NEXTSONG},
-	{KE_KEY, 0x43, KEY_STOP},
+	{KE_KEY, 0x43, KEY_STOPCD},
 	{KE_KEY, 0x45, KEY_PLAYPAUSE},
 	{KE_KEY, 0x50, KEY_EMAIL},
 	{KE_KEY, 0x51, KEY_WWW},
-	{KE_KEY, 0x5C, BTN_EXTRA},  /* Performance */
+	{KE_KEY, 0x5C, KEY_SCREENLOCK},  /* Screenlock */
 	{KE_KEY, 0x5D, KEY_WLAN},
 	{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
 	{KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
 	{KE_KEY, 0x82, KEY_CAMERA},
-	{KE_KEY, 0x8A, KEY_TV},
+	{KE_KEY, 0x8A, KEY_PROG1},
 	{KE_KEY, 0x95, KEY_MEDIA},
 	{KE_KEY, 0x99, KEY_PHONE},
 	{KE_END, 0},
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/dell-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/dell-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/dell-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/dell-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -103,7 +103,7 @@ static void parse_da_table(const struct
 	da_num_tokens += tokens;
 }
 
-static void find_tokens(const struct dmi_header *dm)
+static void find_tokens(const struct dmi_header *dm, void *dummy)
 {
 	switch (dm->type) {
 	case 0xd4: /* Indexed IO */
@@ -356,7 +356,7 @@ static int __init dell_init(void)
 	if (!dmi_check_system(dell_device_table))
 		return -ENODEV;
 
-	dmi_walk(find_tokens);
+	dmi_walk(find_tokens, NULL);
 
 	if (!da_tokens)  {
 		printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/dell-wmi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/dell-wmi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/dell-wmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/dell-wmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,210 @@
+/*
+ * Dell WMI hotkeys
+ *
+ * Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ *
+ * Portions based on wistron_btns.c:
+ * 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 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/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
+
+struct key_entry {
+	char type;		/* See KE_* below */
+	u16 code;
+	u16 keycode;
+};
+
+enum { KE_KEY, KE_SW, KE_END };
+
+static struct key_entry dell_wmi_keymap[] = {
+	{KE_KEY, 0xe045, KEY_PROG1},
+	{KE_END, 0}
+};
+
+static struct input_dev *dell_wmi_input_dev;
+
+static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+{
+	struct key_entry *key;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+
+static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+{
+	struct key_entry *key;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++)
+		if (key->type == KE_KEY && keycode == key->keycode)
+			return key;
+
+	return NULL;
+}
+
+static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
+			       int *keycode)
+{
+	struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int dell_wmi_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 = dell_wmi_get_entry_by_scancode(scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!dell_wmi_get_entry_by_keycode(old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static void dell_wmi_notify(u32 value, void *context)
+{
+	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+	static struct key_entry *key;
+	union acpi_object *obj;
+
+	wmi_get_event_data(value, &response);
+
+	obj = (union acpi_object *)response.pointer;
+
+	if (obj && obj->type == ACPI_TYPE_BUFFER) {
+		int *buffer = (int *)obj->buffer.pointer;
+		key = dell_wmi_get_entry_by_scancode(buffer[1]);
+		if (key) {
+			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
+			printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+			       buffer[1]);
+	}
+}
+
+static int __init dell_wmi_input_setup(void)
+{
+	struct key_entry *key;
+	int err;
+
+	dell_wmi_input_dev = input_allocate_device();
+
+	if (!dell_wmi_input_dev)
+		return -ENOMEM;
+
+	dell_wmi_input_dev->name = "Dell WMI hotkeys";
+	dell_wmi_input_dev->phys = "wmi/input0";
+	dell_wmi_input_dev->id.bustype = BUS_HOST;
+	dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
+	dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_KEY:
+			set_bit(EV_KEY, dell_wmi_input_dev->evbit);
+			set_bit(key->keycode, dell_wmi_input_dev->keybit);
+			break;
+		case KE_SW:
+			set_bit(EV_SW, dell_wmi_input_dev->evbit);
+			set_bit(key->keycode, dell_wmi_input_dev->swbit);
+			break;
+		}
+	}
+
+	err = input_register_device(dell_wmi_input_dev);
+
+	if (err) {
+		input_free_device(dell_wmi_input_dev);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __init dell_wmi_init(void)
+{
+	int err;
+
+	if (wmi_has_guid(DELL_EVENT_GUID)) {
+		err = dell_wmi_input_setup();
+
+		if (err)
+			return err;
+
+		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;
+		}
+
+	} else
+		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+
+	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);
+	}
+}
+
+module_init(dell_wmi_init);
+module_exit(dell_wmi_exit);
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/eeepc-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/eeepc-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/eeepc-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/eeepc-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -158,6 +158,7 @@ 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 },
@@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] =
 	{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 },
@@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, cha
 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(cpufv, CM_ASL_CPUFV);
 
 static struct attribute *platform_attributes[] = {
 	&dev_attr_camera.attr,
 	&dev_attr_cardr.attr,
 	&dev_attr_disp.attr,
+	&dev_attr_cpufv.attr,
 	NULL
 };
 
@@ -512,15 +517,21 @@ static int eeepc_hotk_check(void)
 	return 0;
 }
 
-static void notify_brn(void)
+static int notify_brn(void)
 {
+	/* returns the *previous* brightness, or -1 */
 	struct backlight_device *bd = eeepc_backlight_device;
-	if (bd)
+	if (bd) {
+		int old = bd->props.brightness;
 		bd->props.brightness = read_brightness(bd);
+		return old;
+	}
+	return -1;
 }
 
 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 {
+	enum rfkill_state state;
 	struct pci_dev *dev;
 	struct pci_bus *bus = pci_find_bus(0, 1);
 
@@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_han
 		return;
 	}
 
-	if (get_acpi(CM_ASL_WLAN) == 1) {
+	eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state);
+
+	if (state == RFKILL_STATE_UNBLOCKED) {
 		dev = pci_get_slot(bus, 0);
 		if (dev) {
 			/* Device already present */
@@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_han
 			pci_dev_put(dev);
 		}
 	}
+
+	rfkill_force_state(ehotk->eeepc_wlan_rfkill, state);
 }
 
 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
 {
 	static struct key_entry *key;
 	u16 count;
+	int brn = -ENODEV;
 
 	if (!ehotk)
 		return;
 	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
-		notify_brn();
+		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) {
@@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_de
 	if (ACPI_FAILURE(status))
 		printk(EEEPC_ERR "Error installing notify handler\n");
 
+	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
+	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
+
 	if (get_acpi(CM_ASL_WLAN) != -1) {
 		ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
 							   RFKILL_TYPE_WLAN);
@@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_de
 			goto bluetooth_fail;
 	}
 
-	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
-	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
-
 	return 0;
 
  bluetooth_fail:
@@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_de
  wlan_fail:
 	if (ehotk->eeepc_wlan_rfkill)
 		rfkill_free(ehotk->eeepc_wlan_rfkill);
+	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
+	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
  ehotk_fail:
 	kfree(ehotk);
 	ehotk = NULL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/fujitsu-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/fujitsu-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/fujitsu-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/fujitsu-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -174,8 +174,7 @@ struct fujitsu_hotkey_t {
 
 static struct fujitsu_hotkey_t *fujitsu_hotkey;
 
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
-				       void *data);
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event);
 
 #ifdef CONFIG_LEDS_CLASS
 static enum led_brightness logolamp_get(struct led_classdev *cdev);
@@ -203,7 +202,7 @@ struct led_classdev kblamps_led = {
 static u32 dbg_level = 0x03;
 #endif
 
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event);
 
 /* Fujitsu ACPI interface function */
 
@@ -658,7 +657,6 @@ static struct dmi_system_id fujitsu_dmi_
 
 static int acpi_fujitsu_add(struct acpi_device *device)
 {
-	acpi_status status;
 	acpi_handle handle;
 	int result = 0;
 	int state = 0;
@@ -673,20 +671,10 @@ static int acpi_fujitsu_add(struct acpi_
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 	device->driver_data = fujitsu;
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_fujitsu_notify, fujitsu);
-
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop;
-	}
-
 	fujitsu->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_stop;
 	}
 
 	snprintf(fujitsu->phys, sizeof(fujitsu->phys),
@@ -743,9 +731,6 @@ static int acpi_fujitsu_add(struct acpi_
 end:
 err_free_input_dev:
 	input_free_device(input);
-err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_fujitsu_notify);
 err_stop:
 
 	return result;
@@ -753,7 +738,6 @@ err_stop:
 
 static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct fujitsu_t *fujitsu = NULL;
 
 	if (!device || !acpi_driver_data(device))
@@ -761,10 +745,6 @@ static int acpi_fujitsu_remove(struct ac
 
 	fujitsu = acpi_driver_data(device);
 
-	status = acpi_remove_notify_handler(fujitsu->acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_fujitsu_notify);
-
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
@@ -775,7 +755,7 @@ static int acpi_fujitsu_remove(struct ac
 
 /* Brightness notify */
 
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event)
 {
 	struct input_dev *input;
 	int keycode;
@@ -829,15 +809,12 @@ static void acpi_fujitsu_notify(acpi_han
 		input_report_key(input, keycode, 0);
 		input_sync(input);
 	}
-
-	return;
 }
 
 /* ACPI device for hotkey handling */
 
 static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 {
-	acpi_status status;
 	acpi_handle handle;
 	int result = 0;
 	int state = 0;
@@ -854,17 +831,6 @@ static int acpi_fujitsu_hotkey_add(struc
 	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
 	device->driver_data = fujitsu_hotkey;
 
-	status = acpi_install_notify_handler(device->handle,
-					     ACPI_DEVICE_NOTIFY,
-					     acpi_fujitsu_hotkey_notify,
-					     fujitsu_hotkey);
-
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR "Error installing notify handler\n");
-		error = -ENODEV;
-		goto err_stop;
-	}
-
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
 	fujitsu_hotkey->fifo =
@@ -879,7 +845,7 @@ static int acpi_fujitsu_hotkey_add(struc
 	fujitsu_hotkey->input = input = input_allocate_device();
 	if (!input) {
 		error = -ENOMEM;
-		goto err_uninstall_notify;
+		goto err_free_fifo;
 	}
 
 	snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
@@ -975,9 +941,7 @@ static int acpi_fujitsu_hotkey_add(struc
 end:
 err_free_input_dev:
 	input_free_device(input);
-err_uninstall_notify:
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_fujitsu_hotkey_notify);
+err_free_fifo:
 	kfifo_free(fujitsu_hotkey->fifo);
 err_stop:
 
@@ -986,7 +950,6 @@ err_stop:
 
 static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
 
 	if (!device || !acpi_driver_data(device))
@@ -994,10 +957,6 @@ static int acpi_fujitsu_hotkey_remove(st
 
 	fujitsu_hotkey = acpi_driver_data(device);
 
-	status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    acpi_fujitsu_hotkey_notify);
-
 	fujitsu_hotkey->acpi_handle = NULL;
 
 	kfifo_free(fujitsu_hotkey->fifo);
@@ -1005,8 +964,7 @@ static int acpi_fujitsu_hotkey_remove(st
 	return 0;
 }
 
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
-				       void *data)
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
 {
 	struct input_dev *input;
 	int keycode, keycode_r;
@@ -1089,8 +1047,6 @@ static void acpi_fujitsu_hotkey_notify(a
 		input_sync(input);
 		break;
 	}
-
-	return;
 }
 
 /* Initialization */
@@ -1107,6 +1063,7 @@ static struct acpi_driver acpi_fujitsu_d
 	.ops = {
 		.add = acpi_fujitsu_add,
 		.remove = acpi_fujitsu_remove,
+		.notify = acpi_fujitsu_notify,
 		},
 };
 
@@ -1122,6 +1079,7 @@ static struct acpi_driver acpi_fujitsu_h
 	.ops = {
 		.add = acpi_fujitsu_hotkey_add,
 		.remove = acpi_fujitsu_hotkey_remove,
+		.notify = acpi_fujitsu_hotkey_notify,
 		},
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/hp-wmi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/hp-wmi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/hp-wmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/hp-wmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE9
 
 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 platform_device *device);
 
 struct bios_args {
 	u32 signature;
@@ -101,6 +102,7 @@ static struct platform_driver hp_wmi_dri
 	},
 	.probe = hp_wmi_bios_setup,
 	.remove = hp_wmi_bios_remove,
+	.resume = hp_wmi_resume_handler,
 };
 
 static int hp_wmi_perform_query(int query, int write, int value)
@@ -486,6 +488,29 @@ static int __exit hp_wmi_bios_remove(str
 
 	return 0;
 }
+
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+	struct key_entry *key;
+
+	/*
+	 * Docking state may have changed while suspended, so trigger
+	 * an input event for the current state. As this is a switch,
+	 * the input layer will only actually pass it on if the state
+	 * changed.
+	 */
+	for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_SW:
+			input_report_switch(hp_wmi_input_dev, key->keycode,
+					    hp_wmi_dock_state());
+			input_sync(hp_wmi_input_dev);
+			break;
+		}
+	}
+
+	return 0;
+}
 
 static int __init hp_wmi_init(void)
 {
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/intel_menlow.c linux-libre-2.6.30-gnu1/drivers/platform/x86/intel_menlow.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/intel_menlow.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/intel_menlow.c	2009-06-09 23:05:27.000000000 -0400
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL");
  * In that case max_cstate would be n-1
  * GTHS returning '0' would mean that no bandwidth control states are supported
  */
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
-					unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+				    unsigned long *max_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(
 	return 0;
 }
 
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
-{
-	unsigned long value;
-	if (memory_get_int_max_bandwidth(cdev, &value))
-		return -EINVAL;
-
-	return sprintf(buf, "%ld\n", value);
-}
-
 static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
+				    unsigned long *value)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
-	unsigned long long value;
+	unsigned long long result;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(stru
 	arg.type = ACPI_TYPE_INTEGER;
 	arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
 	status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
-				       &arg_list, &value);
+				       &arg_list, &result);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
-	return sprintf(buf, "%llu\n", value);
+	*value = result;
+	return 0;
 }
 
 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    unsigned int state)
+				    unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(stru
 	unsigned long long temp;
 	unsigned long max_state;
 
-	if (memory_get_int_max_bandwidth(cdev, &max_state))
+	if (memory_get_max_bandwidth(cdev, &max_state))
 		return -EFAULT;
 
 	if (state > max_state)
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(stru
 				  &temp);
 
 	printk(KERN_INFO
-	       "Bandwidth value was %d: status is %d\n", state, status);
+	       "Bandwidth value was %ld: status is %d\n", state, status);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/Kconfig linux-libre-2.6.30-gnu1/drivers/platform/x86/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -67,6 +67,16 @@ config DELL_LAPTOP
 	This driver adds support for rfkill and backlight control to Dell
 	laptops.
 
+config DELL_WMI
+	tristate "Dell WMI extras"
+	depends on ACPI_WMI
+	depends on INPUT
+	---help---
+	  Say Y here if you want to support WMI-based hotkeys on Dell laptops.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dell-wmi.
+
 config FUJITSU_LAPTOP
 	tristate "Fujitsu Laptop Extras"
 	depends on ACPI
@@ -165,6 +175,7 @@ config SONY_LAPTOP
 	depends on ACPI
 	select BACKLIGHT_CLASS_DEVICE
 	depends on INPUT
+	depends on RFKILL
 	  ---help---
 	  This mini-driver drives the SNC and SPIC devices present in the ACPI
 	  BIOS of the Sony Vaio laptops.
@@ -226,6 +237,30 @@ config THINKPAD_ACPI_DEBUG
 
 	  If you are not sure, say N here.
 
+config THINKPAD_ACPI_UNSAFE_LEDS
+	bool "Allow control of important LEDs (unsafe)"
+	depends on THINKPAD_ACPI
+	default n
+	---help---
+	  Overriding LED state on ThinkPads can mask important
+	  firmware alerts (like critical battery condition), or misled
+	  the user into damaging the hardware (undocking or ejecting
+	  the bay while buses are still active), etc.
+
+	  LED control on the ThinkPad is write-only (with very few
+	  exceptions on very ancient models), which makes it
+	  impossible to know beforehand if important information will
+	  be lost when one changes LED state.
+
+	  Users that know what they are doing can enable this option
+	  and the driver will allow control of every LED, including
+	  the ones on the dock stations.
+
+	  Never enable this option on a distribution kernel.
+
+	  Say N here, unless you are building a kernel for your own
+	  use, and need to control the important firmware LEDs.
+
 config THINKPAD_ACPI_DOCK
 	bool "Legacy Docking Station Support"
 	depends on THINKPAD_ACPI
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/Makefile linux-libre-2.6.30-gnu1/drivers/platform/x86/Makefile
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,7 @@ obj-$(CONFIG_EEEPC_LAPTOP)	+= eeepc-lapt
 obj-$(CONFIG_MSI_LAPTOP)	+= msi-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)	+= compal-laptop.o
 obj-$(CONFIG_DELL_LAPTOP)	+= dell-laptop.o
+obj-$(CONFIG_DELL_WMI)		+= dell-wmi.o
 obj-$(CONFIG_ACER_WMI)		+= acer-wmi.o
 obj-$(CONFIG_HP_WMI)		+= hp-wmi.o
 obj-$(CONFIG_TC1100_WMI)	+= tc1100-wmi.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/panasonic-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/panasonic-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/panasonic-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/panasonic-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -176,6 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
 static int acpi_pcc_hotkey_add(struct acpi_device *device);
 static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
 static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id pcc_device_ids[] = {
 	{ "MAT0012", 0},
@@ -184,6 +185,7 @@ static const struct acpi_device_id pcc_d
 	{ "MAT0019", 0},
 	{ "", 0},
 };
+MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
 
 static struct acpi_driver acpi_pcc_driver = {
 	.name =		ACPI_PCC_DRIVER_NAME,
@@ -193,6 +195,7 @@ static struct acpi_driver acpi_pcc_drive
 				.add =		acpi_pcc_hotkey_add,
 				.remove =	acpi_pcc_hotkey_remove,
 				.resume =       acpi_pcc_hotkey_resume,
+				.notify =	acpi_pcc_hotkey_notify,
 			},
 };
 
@@ -270,7 +273,7 @@ static int acpi_pcc_retrieve_biosdata(st
 	union acpi_object *hkey = NULL;
 	int i;
 
-	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+	status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, NULL,
 				      &buffer);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -366,7 +369,7 @@ static ssize_t show_numbatt(struct devic
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
 }
 
 static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
@@ -378,7 +381,7 @@ static ssize_t show_lcdtype(struct devic
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
 }
 
 static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
@@ -390,7 +393,7 @@ static ssize_t show_mute(struct device *
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
 }
 
 static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
@@ -402,7 +405,7 @@ static ssize_t show_sticky(struct device
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
 }
 
 static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
@@ -526,9 +529,9 @@ static void acpi_pcc_generate_keyinput(s
 	return;
 }
 
-static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
 {
-	struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+	struct pcc_acpi *pcc = acpi_driver_data(device);
 
 	switch (event) {
 	case HKEY_NOTIFY:
@@ -598,7 +601,6 @@ static int acpi_pcc_hotkey_resume(struct
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
-	acpi_status status;
 	struct pcc_acpi *pcc;
 	int num_sifr, result;
 
@@ -639,22 +641,11 @@ static int acpi_pcc_hotkey_add(struct ac
 		goto out_sinf;
 	}
 
-	/* initialize hotkey input device */
-	status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-					     acpi_pcc_hotkey_notify, pcc);
-
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Error installing notify handler\n"));
-		result = -ENODEV;
-		goto out_input;
-	}
-
 	/* initialize backlight */
 	pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
 						   &pcc_backlight_ops);
 	if (IS_ERR(pcc->backlight))
-		goto out_notify;
+		goto out_input;
 
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -679,9 +670,6 @@ static int acpi_pcc_hotkey_add(struct ac
 
 out_backlight:
 	backlight_device_unregister(pcc->backlight);
-out_notify:
-	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_pcc_hotkey_notify);
 out_input:
 	input_unregister_device(pcc->input_dev);
 	/* no need to input_free_device() since core input API refcount and
@@ -722,9 +710,6 @@ static int acpi_pcc_hotkey_remove(struct
 
 	backlight_device_unregister(pcc->backlight);
 
-	acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
-				   acpi_pcc_hotkey_notify);
-
 	input_unregister_device(pcc->input_dev);
 	/* no need to input_free_device() since core input API refcount and
 	 * free()s the device */
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/sony-laptop.c linux-libre-2.6.30-gnu1/drivers/platform/x86/sony-laptop.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/sony-laptop.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/sony-laptop.c	2009-06-09 23:05:27.000000000 -0400
@@ -2,7 +2,7 @@
  * ACPI Sony Notebook Control Driver (SNC and SPIC)
  *
  * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
- * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
  *
  * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
  * which are copyrighted by their respective authors.
@@ -46,7 +46,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
@@ -64,6 +63,7 @@
 #include <asm/uaccess.h>
 #include <linux/sonypi.h>
 #include <linux/sony-laptop.h>
+#include <linux/rfkill.h>
 #ifdef CONFIG_SONYPI_COMPAT
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor,
 		 "default is -1 (automatic)");
 #endif
 
+enum sony_nc_rfkill {
+	SONY_WIFI,
+	SONY_BLUETOOTH,
+	SONY_WWAN,
+	SONY_WIMAX,
+	SONY_RFKILL_MAX,
+};
+
+static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
+static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static void sony_nc_rfkill_update(void);
+
 /*********** Input Devices ***********/
 
 #define SONY_LAPTOP_BUF_SIZE	128
@@ -134,6 +146,7 @@ struct sony_laptop_input_s {
 	spinlock_t		fifo_lock;
 	struct workqueue_struct	*wq;
 };
+
 static struct sony_laptop_input_s sony_laptop_input = {
 	.users = ATOMIC_INIT(0),
 };
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = {
 	48,	/* 61 SONYPI_EVENT_WIRELESS_OFF */
 	49,	/* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
 	50,	/* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	51,	/* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
+	52,	/* 65 SONYPI_EVENT_MODEKEY_PRESSED */
+	53,	/* 66 SONYPI_EVENT_PKEY_P4 */
+	54,	/* 67 SONYPI_EVENT_PKEY_P5 */
+	55,	/* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
+	56,	/* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
+	57,	/* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+	-1,	/* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
 };
 
 static int sony_laptop_input_keycode_map[] = {
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map
 	KEY_WLAN,	/* 47 SONYPI_EVENT_WIRELESS_ON */
 	KEY_WLAN,	/* 48 SONYPI_EVENT_WIRELESS_OFF */
 	KEY_ZOOMIN,	/* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
-	KEY_ZOOMOUT	/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	KEY_ZOOMOUT,	/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	KEY_EJECTCD,	/* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
+	KEY_F13,	/* 52 SONYPI_EVENT_MODEKEY_PRESSED */
+	KEY_PROG4,	/* 53 SONYPI_EVENT_PKEY_P4 */
+	KEY_F14,	/* 54 SONYPI_EVENT_PKEY_P5 */
+	KEY_F15,	/* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
+	KEY_VOLUMEUP,	/* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
+	KEY_VOLUMEDOWN,	/* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
 };
 
 /* release buttons after a short delay if pressed */
@@ -289,7 +317,8 @@ static void sony_laptop_report_input_eve
 	struct input_dev *key_dev = sony_laptop_input.key_dev;
 	struct sony_laptop_keypress kp = { NULL };
 
-	if (event == SONYPI_EVENT_FNKEY_RELEASED) {
+	if (event == SONYPI_EVENT_FNKEY_RELEASED ||
+			event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
 		/* Nothing, not all VAIOs generate this event */
 		return;
 	}
@@ -369,7 +398,7 @@ static int sony_laptop_setup_input(struc
 	sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
 	if (!sony_laptop_input.wq) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create workqueue.\n");
+				"Unable to create workqueue.\n");
 		error = -ENXIO;
 		goto err_free_kfifo;
 	}
@@ -689,6 +718,31 @@ static int acpi_callsetfunc(acpi_handle
 	return -1;
 }
 
+static int sony_find_snc_handle(int handle)
+{
+	int i;
+	int result;
+
+	for (i = 0x20; i < 0x30; i++) {
+		acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
+		if (result == handle)
+			return i-0x20;
+	}
+
+	return -1;
+}
+
+static int sony_call_snc_handle(int handle, int argument, int *result)
+{
+	int offset = sony_find_snc_handle(handle);
+
+	if (offset < 0)
+		return -1;
+
+	return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+				result);
+}
+
 /*
  * sony_nc_values input/output validate functions
  */
@@ -809,126 +863,112 @@ struct sony_nc_event {
 	u8	event;
 };
 
-static struct sony_nc_event *sony_nc_events;
-
-/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
- * for Fn keys
- */
-static int sony_nc_C_enable(const struct dmi_system_id *id)
-{
-	int result = 0;
-
-	printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
-
-	sony_nc_events = id->driver_data;
-
-	if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
-		printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
-				"functionalities may be missing\n");
-		return 1;
-	}
-	return 0;
-}
-
-static struct sony_nc_event sony_C_events[] = {
+static struct sony_nc_event sony_100_events[] = {
+	{ 0x90, SONYPI_EVENT_PKEY_P1 },
+	{ 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x91, SONYPI_EVENT_PKEY_P2 },
+	{ 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0x81, SONYPI_EVENT_FNKEY_F1 },
 	{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x82, SONYPI_EVENT_FNKEY_F2 },
+	{ 0x02, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x83, SONYPI_EVENT_FNKEY_F3 },
+	{ 0x03, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x84, SONYPI_EVENT_FNKEY_F4 },
+	{ 0x04, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x85, SONYPI_EVENT_FNKEY_F5 },
 	{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x86, SONYPI_EVENT_FNKEY_F6 },
 	{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x87, SONYPI_EVENT_FNKEY_F7 },
 	{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x89, SONYPI_EVENT_FNKEY_F9 },
+	{ 0x09, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x8A, SONYPI_EVENT_FNKEY_F10 },
 	{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x8C, SONYPI_EVENT_FNKEY_F12 },
 	{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
+	{ 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0, 0 },
 };
 
-/* SNC-only model map */
-static const struct dmi_system_id sony_nc_ids[] = {
-		{
-			.ident = "Sony Vaio FE Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
-			},
-		},
-		{
-			.ident = "Sony Vaio FZ Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
-			},
-		},
-		{
-			.ident = "Sony Vaio C Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
-			},
-		},
-		{
-			.ident = "Sony Vaio N Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
-			},
-		},
-		{ }
+static struct sony_nc_event sony_127_events[] = {
+	{ 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
+	{ 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x82, SONYPI_EVENT_PKEY_P1 },
+	{ 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x83, SONYPI_EVENT_PKEY_P2 },
+	{ 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x84, SONYPI_EVENT_PKEY_P3 },
+	{ 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x85, SONYPI_EVENT_PKEY_P4 },
+	{ 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x86, SONYPI_EVENT_PKEY_P5 },
+	{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
+	{ 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0, 0 },
 };
 
 /*
  * ACPI callbacks
  */
-static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+static void sony_nc_notify(struct acpi_device *device, u32 event)
 {
-	struct sony_nc_event *evmap;
 	u32 ev = event;
-	int result;
 
-	if (ev == 0x92) {
-		/* read the key pressed from EC.GECR
-		 * A call to SN07 with 0x0202 will do it as well respecting
-		 * the current protocol on different OSes
-		 *
-		 * Note: the path for GECR may be
-		 *   \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
-		 *   \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
-		 *
-		 * TODO: we may want to do the same for the older GHKE -need
-		 *       dmi list- so this snippet may become one more callback.
-		 */
-		if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
-			dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
-		else
-			ev = result & 0xFF;
-	}
+	if (ev >= 0x90) {
+		/* New-style event */
+		int result;
+		int key_handle = 0;
+		ev -= 0x90;
 
-	if (sony_nc_events)
-		for (evmap = sony_nc_events; evmap->event; evmap++) {
-			if (evmap->data == ev) {
-				ev = evmap->event;
-				break;
+		if (sony_find_snc_handle(0x100) == ev)
+			key_handle = 0x100;
+		if (sony_find_snc_handle(0x127) == ev)
+			key_handle = 0x127;
+
+		if (key_handle) {
+			struct sony_nc_event *key_event;
+
+			if (sony_call_snc_handle(key_handle, 0x200, &result)) {
+				dprintk("sony_nc_notify, unable to decode"
+					" event 0x%.2x 0x%.2x\n", key_handle,
+					ev);
+				/* restore the original event */
+				ev = event;
+			} else {
+				ev = result & 0xFF;
+
+				if (key_handle == 0x100)
+					key_event = sony_100_events;
+				else
+					key_event = sony_127_events;
+
+				for (; key_event->data; key_event++) {
+					if (key_event->data == ev) {
+						ev = key_event->event;
+						break;
+					}
+				}
+
+				if (!key_event->data)
+					printk(KERN_INFO DRV_PFX
+							"Unknown event: 0x%x 0x%x\n",
+							key_handle,
+							ev);
+				else
+					sony_laptop_report_input_event(ev);
 			}
+		} else if (sony_find_snc_handle(0x124) == ev) {
+			sony_nc_rfkill_update();
+			return;
 		}
+	} else
+		sony_laptop_report_input_event(ev);
 
-	dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
-	sony_laptop_report_input_event(ev);
+	dprintk("sony_nc_notify, event: 0x%.2x\n", ev);
 	acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
 }
 
@@ -953,9 +993,26 @@ static acpi_status sony_walk_callback(ac
 /*
  * ACPI device
  */
+static int sony_nc_function_setup(struct acpi_device *device)
+{
+	int result;
+
+	/* Enable all events */
+	acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
+
+	/* Setup hotkeys */
+	sony_call_snc_handle(0x0100, 0, &result);
+	sony_call_snc_handle(0x0101, 0, &result);
+	sony_call_snc_handle(0x0102, 0x100, &result);
+	sony_call_snc_handle(0x0127, 0, &result);
+
+	return 0;
+}
+
 static int sony_nc_resume(struct acpi_device *device)
 {
 	struct sony_nc_value *item;
+	acpi_handle handle;
 
 	for (item = sony_nc_values; item->name; item++) {
 		int ret;
@@ -970,13 +1027,200 @@ static int sony_nc_resume(struct acpi_de
 		}
 	}
 
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+					 &handle))) {
+		if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+			dprintk("ECON Method failed\n");
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+					 &handle))) {
+		dprintk("Doing SNC setup\n");
+		sony_nc_function_setup(device);
+	}
+
 	/* set the last requested brightness level */
 	if (sony_backlight_device &&
-			!sony_backlight_update_status(sony_backlight_device))
+			sony_backlight_update_status(sony_backlight_device) < 0)
 		printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
 
-	/* re-initialize models with specific requirements */
-	dmi_check_system(sony_nc_ids);
+	return 0;
+}
+
+static void sony_nc_rfkill_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < SONY_RFKILL_MAX; i++) {
+		if (sony_rfkill_devices[i])
+			rfkill_unregister(sony_rfkill_devices[i]);
+	}
+}
+
+static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
+{
+	int result;
+	int argument = sony_rfkill_address[(long) data];
+
+	sony_call_snc_handle(0x124, 0x200, &result);
+	if (result & 0x1) {
+		sony_call_snc_handle(0x124, argument, &result);
+		if (result & 0xf)
+			*state = RFKILL_STATE_UNBLOCKED;
+		else
+			*state = RFKILL_STATE_SOFT_BLOCKED;
+	} else {
+		*state = RFKILL_STATE_HARD_BLOCKED;
+	}
+
+	return 0;
+}
+
+static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+{
+	int result;
+	int argument = sony_rfkill_address[(long) data] + 0x100;
+
+	if (state == RFKILL_STATE_UNBLOCKED)
+		argument |= 0xff0000;
+
+	return sony_call_snc_handle(0x124, argument, &result);
+}
+
+static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wifi_rfkill;
+
+	sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
+	if (!sony_wifi_rfkill)
+		return -1;
+	sony_wifi_rfkill->name = "sony-wifi";
+	sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wifi_rfkill->user_claim_unsupported = 1;
+	sony_wifi_rfkill->data = (void *)SONY_WIFI;
+	err = rfkill_register(sony_wifi_rfkill);
+	if (err)
+		rfkill_free(sony_wifi_rfkill);
+	else {
+		sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+		sony_nc_rfkill_set(sony_wifi_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
+	return err;
+}
+
+static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_bluetooth_rfkill;
+
+	sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
+						RFKILL_TYPE_BLUETOOTH);
+	if (!sony_bluetooth_rfkill)
+		return -1;
+	sony_bluetooth_rfkill->name = "sony-bluetooth";
+	sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
+	sony_bluetooth_rfkill->user_claim_unsupported = 1;
+	sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
+	err = rfkill_register(sony_bluetooth_rfkill);
+	if (err)
+		rfkill_free(sony_bluetooth_rfkill);
+	else {
+		sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+		sony_nc_rfkill_set(sony_bluetooth_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
+	return err;
+}
+
+static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wwan_rfkill;
+
+	sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
+	if (!sony_wwan_rfkill)
+		return -1;
+	sony_wwan_rfkill->name = "sony-wwan";
+	sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wwan_rfkill->user_claim_unsupported = 1;
+	sony_wwan_rfkill->data = (void *)SONY_WWAN;
+	err = rfkill_register(sony_wwan_rfkill);
+	if (err)
+		rfkill_free(sony_wwan_rfkill);
+	else {
+		sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+		sony_nc_rfkill_set(sony_wwan_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
+	return err;
+}
+
+static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wimax_rfkill;
+
+	sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
+	if (!sony_wimax_rfkill)
+		return -1;
+	sony_wimax_rfkill->name = "sony-wimax";
+	sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wimax_rfkill->user_claim_unsupported = 1;
+	sony_wimax_rfkill->data = (void *)SONY_WIMAX;
+	err = rfkill_register(sony_wimax_rfkill);
+	if (err)
+		rfkill_free(sony_wimax_rfkill);
+	else {
+		sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+		sony_nc_rfkill_set(sony_wimax_rfkill->data,
+				RFKILL_STATE_UNBLOCKED);
+	}
+	return err;
+}
+
+static void sony_nc_rfkill_update()
+{
+	int i;
+	enum rfkill_state state;
+
+	for (i = 0; i < SONY_RFKILL_MAX; i++) {
+		if (sony_rfkill_devices[i]) {
+			sony_rfkill_devices[i]->
+				get_state(sony_rfkill_devices[i]->data,
+					  &state);
+			rfkill_force_state(sony_rfkill_devices[i], state);
+		}
+	}
+}
+
+static int sony_nc_rfkill_setup(struct acpi_device *device)
+{
+	int result, ret;
+
+	if (sony_find_snc_handle(0x124) == -1)
+		return -1;
+
+	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;
+	}
+
+	if (result & 0x1)
+		sony_nc_setup_wifi_rfkill(device);
+	if (result & 0x2)
+		sony_nc_setup_bluetooth_rfkill(device);
+	if (result & 0x1c)
+		sony_nc_setup_wwan_rfkill(device);
+	if (result & 0x20)
+		sony_nc_setup_wimax_rfkill(device);
 
 	return 0;
 }
@@ -1024,23 +1268,27 @@ static int sony_nc_add(struct acpi_devic
 			dprintk("_INI Method failed\n");
 	}
 
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+					 &handle))) {
+		if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+			dprintk("ECON Method failed\n");
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+					 &handle))) {
+		dprintk("Doing SNC setup\n");
+		sony_nc_function_setup(device);
+		sony_nc_rfkill_setup(device);
+	}
+
 	/* setup input devices and helper fifo */
 	result = sony_laptop_setup_input(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create input devices.\n");
+				"Unable to create input devices.\n");
 		goto outwalk;
 	}
 
-	status = acpi_install_notify_handler(sony_nc_acpi_handle,
-					     ACPI_DEVICE_NOTIFY,
-					     sony_acpi_notify, NULL);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
-		result = -ENODEV;
-		goto outinput;
-	}
-
 	if (acpi_video_backlight_support()) {
 		printk(KERN_INFO DRV_PFX "brightness ignored, must be "
 		       "controlled by ACPI video driver\n");
@@ -1063,9 +1311,6 @@ static int sony_nc_add(struct acpi_devic
 
 	}
 
-	/* initialize models with specific requirements */
-	dmi_check_system(sony_nc_ids);
-
 	result = sony_pf_add();
 	if (result)
 		goto outbacklight;
@@ -1121,22 +1366,15 @@ static int sony_nc_add(struct acpi_devic
 	if (sony_backlight_device)
 		backlight_device_unregister(sony_backlight_device);
 
-	status = acpi_remove_notify_handler(sony_nc_acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    sony_acpi_notify);
-	if (ACPI_FAILURE(status))
-		printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
-      outinput:
 	sony_laptop_remove_input();
 
       outwalk:
+	sony_nc_rfkill_cleanup();
 	return result;
 }
 
 static int sony_nc_remove(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct sony_nc_value *item;
 
 	if (sony_backlight_device)
@@ -1144,18 +1382,13 @@ static int sony_nc_remove(struct acpi_de
 
 	sony_nc_acpi_device = NULL;
 
-	status = acpi_remove_notify_handler(sony_nc_acpi_handle,
-					    ACPI_DEVICE_NOTIFY,
-					    sony_acpi_notify);
-	if (ACPI_FAILURE(status))
-		printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
 	for (item = sony_nc_values; item->name; ++item) {
 		device_remove_file(&sony_pf_device->dev, &item->devattr);
 	}
 
 	sony_pf_remove();
 	sony_laptop_remove_input();
+	sony_nc_rfkill_cleanup();
 	dprintk(SONY_NC_DRIVER_NAME " removed.\n");
 
 	return 0;
@@ -1182,6 +1415,7 @@ static struct acpi_driver sony_nc_driver
 		.add = sony_nc_add,
 		.remove = sony_nc_remove,
 		.resume = sony_nc_resume,
+		.notify = sony_nc_notify,
 		},
 };
 
@@ -1195,7 +1429,6 @@ static struct acpi_driver sony_nc_driver
 #define SONYPI_TYPE1_OFFSET	0x04
 #define SONYPI_TYPE2_OFFSET	0x12
 #define SONYPI_TYPE3_OFFSET	0x12
-#define SONYPI_TYPE4_OFFSET	0x12
 
 struct sony_pic_ioport {
 	struct acpi_resource_io	io1;
@@ -1328,6 +1561,7 @@ static struct sonypi_event sonypi_pkeyev
 	{ 0x01, SONYPI_EVENT_PKEY_P1 },
 	{ 0x02, SONYPI_EVENT_PKEY_P2 },
 	{ 0x04, SONYPI_EVENT_PKEY_P3 },
+	{ 0x20, SONYPI_EVENT_PKEY_P1 },
 	{ 0, 0 }
 };
 
@@ -1371,6 +1605,7 @@ static struct sonypi_event sonypi_zoomev
 	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
 	{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
 	{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
+	{ 0x04, SONYPI_EVENT_ZOOM_PRESSED },
 	{ 0, 0 }
 };
 
@@ -1401,6 +1636,19 @@ static struct sonypi_event sonypi_batter
 	{ 0, 0 }
 };
 
+/* The set of possible volume events */
+static struct sonypi_event sonypi_volumeev[] = {
+	{ 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
+	{ 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible brightness events */
+static struct sonypi_event sonypi_brightnessev[] = {
+	{ 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
+	{ 0, 0 }
+};
+
 static struct sonypi_eventtypes type1_events[] = {
 	{ 0, 0xffffffff, sonypi_releaseev },
 	{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@ -1438,17 +1686,11 @@ static struct sonypi_eventtypes type3_ev
 	{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
 	{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
 	{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
-	{ 0 },
-};
-static struct sonypi_eventtypes type4_events[] = {
-	{ 0, 0xffffffff, sonypi_releaseev },
-	{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
-	{ 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
-	{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
-	{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
 	{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
 	{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
 	{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
+	{ 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
+	{ 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
 	{ 0 },
 };
 
@@ -1511,11 +1753,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn,
 /*
  * minidrivers for SPIC models
  */
-static int type4_handle_irq(const u8 data_mask, const u8 ev)
+static int type3_handle_irq(const u8 data_mask, const u8 ev)
 {
 	/*
 	 * 0x31 could mean we have to take some extra action and wait for
-	 * the next irq for some Type4 models, it will generate a new
+	 * the next irq for some Type3 models, it will generate a new
 	 * irq and we can read new data from the device:
 	 *  - 0x5c and 0x5f requires 0xA0
 	 *  - 0x61 requires 0xB3
@@ -1545,16 +1787,10 @@ static struct device_ctrl spic_types[] =
 	},
 	{
 		.model = SONYPI_DEVICE_TYPE3,
-		.handle_irq = NULL,
+		.handle_irq = type3_handle_irq,
 		.evport_offset = SONYPI_TYPE3_OFFSET,
 		.event_types = type3_events,
 	},
-	{
-		.model = SONYPI_DEVICE_TYPE4,
-		.handle_irq = type4_handle_irq,
-		.evport_offset = SONYPI_TYPE4_OFFSET,
-		.event_types = type4_events,
-	},
 };
 
 static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
@@ -1578,14 +1814,21 @@ static void sony_pic_detect_device_type(
 	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
 			PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
 	if (pcidev) {
-		dev->control = &spic_types[3];
+		dev->control = &spic_types[2];
 		goto out;
 	}
 
 	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
 			PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
 	if (pcidev) {
-		dev->control = &spic_types[3];
+		dev->control = &spic_types[2];
+		goto out;
+	}
+
+	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+			PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
+	if (pcidev) {
+		dev->control = &spic_types[2];
 		goto out;
 	}
 
@@ -1598,8 +1841,7 @@ out:
 
 	printk(KERN_INFO DRV_PFX "detected Type%d model\n",
 			dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
-			dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
-			dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
+			dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
 }
 
 /* camera tests and poweron/poweroff */
@@ -1754,17 +1996,14 @@ int sony_pic_camera_command(int command,
 EXPORT_SYMBOL(sony_pic_camera_command);
 
 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
-static void sony_pic_set_wwanpower(u8 state)
+static void __sony_pic_set_wwanpower(u8 state)
 {
 	state = !!state;
-	mutex_lock(&spic_dev.lock);
-	if (spic_dev.wwan_power == state) {
-		mutex_unlock(&spic_dev.lock);
+	if (spic_dev.wwan_power == state)
 		return;
-	}
 	sony_pic_call2(0xB0, state);
+	sony_pic_call1(0x82);
 	spic_dev.wwan_power = state;
-	mutex_unlock(&spic_dev.lock);
 }
 
 static ssize_t sony_pic_wwanpower_store(struct device *dev,
@@ -1776,7 +2015,9 @@ static ssize_t sony_pic_wwanpower_store(
 		return -EINVAL;
 
 	value = simple_strtoul(buffer, NULL, 10);
-	sony_pic_set_wwanpower(value);
+	mutex_lock(&spic_dev.lock);
+	__sony_pic_set_wwanpower(value);
+	mutex_unlock(&spic_dev.lock);
 
 	return count;
 }
@@ -1917,12 +2158,7 @@ static struct sonypi_compat_s sonypi_com
 
 static int sonypi_misc_fasync(int fd, struct file *filp, int on)
 {
-	int retval;
-
-	retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
-	if (retval < 0)
-		return retval;
-	return 0;
+	return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
 }
 
 static int sonypi_misc_release(struct inode *inode, struct file *file)
@@ -1934,10 +2170,15 @@ static int sonypi_misc_release(struct in
 static int sonypi_misc_open(struct inode *inode, struct file *file)
 {
 	/* Flush input queue on first open */
-	lock_kernel();
+	unsigned long flags;
+
+	spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+
 	if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-		kfifo_reset(sonypi_compat.fifo);
-	unlock_kernel();
+		__kfifo_reset(sonypi_compat.fifo);
+
+	spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+
 	return 0;
 }
 
@@ -1990,8 +2231,8 @@ static int ec_read16(u8 addr, u16 *value
 	return 0;
 }
 
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
-			     unsigned int cmd, unsigned long arg)
+static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
+							unsigned long arg)
 {
 	int ret = 0;
 	void __user *argp = (void __user *)arg;
@@ -2125,7 +2366,7 @@ 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,
 };
 
 static struct miscdevice sonypi_misc_device = {
@@ -2566,7 +2807,7 @@ static int sony_pic_add(struct acpi_devi
 	result = sony_pic_possible_resources(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to read possible resources.\n");
+				"Unable to read possible resources.\n");
 		goto err_free_resources;
 	}
 
@@ -2574,7 +2815,7 @@ static int sony_pic_add(struct acpi_devi
 	result = sony_laptop_setup_input(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create input devices.\n");
+				"Unable to create input devices.\n");
 		goto err_free_resources;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/tc1100-wmi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/tc1100-wmi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/tc1100-wmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/tc1100-wmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,9 +94,8 @@ static int get_state(u32 *out, u8 instan
 		return -ENODEV;
 
 	obj = (union acpi_object *) result.pointer;
-	if (obj && obj->type == ACPI_TYPE_BUFFER &&
-		obj->buffer.length == sizeof(u32)) {
-		tmp = *((u32 *) obj->buffer.pointer);
+	if (obj && obj->type == ACPI_TYPE_INTEGER) {
+		tmp = obj->integer.value;
 	} else {
 		tmp = 0;
 	}
@@ -109,7 +108,7 @@ static int get_state(u32 *out, u8 instan
 		*out = (tmp == 3) ? 1 : 0;
 		return 0;
 	case TC1100_INSTANCE_JOGDIAL:
-		*out = (tmp == 1) ? 1 : 0;
+		*out = (tmp == 1) ? 0 : 1;
 		return 0;
 	default:
 		return -ENODEV;
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/thinkpad_acpi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/thinkpad_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/thinkpad_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/thinkpad_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- *  Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ *  Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.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
@@ -21,8 +21,8 @@
  *  02110-1301, USA.
  */
 
-#define TPACPI_VERSION "0.22"
-#define TPACPI_SYSFS_VERSION 0x020200
+#define TPACPI_VERSION "0.23"
+#define TPACPI_SYSFS_VERSION 0x020300
 
 /*
  *  Changelog:
@@ -54,6 +54,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
@@ -172,29 +173,26 @@ enum {
 	TPACPI_RFK_UWB_SW_ID,
 };
 
-/* Debugging */
+/* printk headers */
 #define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ALERT	KERN_ALERT  TPACPI_LOG
-#define TPACPI_CRIT	KERN_CRIT   TPACPI_LOG
-#define TPACPI_ERR	KERN_ERR    TPACPI_LOG
-#define TPACPI_NOTICE	KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO	KERN_INFO   TPACPI_LOG
-#define TPACPI_DEBUG	KERN_DEBUG  TPACPI_LOG
+#define TPACPI_EMERG	KERN_EMERG	TPACPI_LOG
+#define TPACPI_ALERT	KERN_ALERT	TPACPI_LOG
+#define TPACPI_CRIT	KERN_CRIT	TPACPI_LOG
+#define TPACPI_ERR	KERN_ERR	TPACPI_LOG
+#define TPACPI_WARN	KERN_WARNING	TPACPI_LOG
+#define TPACPI_NOTICE	KERN_NOTICE	TPACPI_LOG
+#define TPACPI_INFO	KERN_INFO	TPACPI_LOG
+#define TPACPI_DEBUG	KERN_DEBUG	TPACPI_LOG
 
+/* Debugging printk groups */
 #define TPACPI_DBG_ALL		0xffff
+#define TPACPI_DBG_DISCLOSETASK	0x8000
 #define TPACPI_DBG_INIT		0x0001
 #define TPACPI_DBG_EXIT		0x0002
-#define dbg_printk(a_dbg_level, format, arg...) \
-	do { if (dbg_level & a_dbg_level) \
-		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
-	} while (0)
-#ifdef CONFIG_THINKPAD_ACPI_DEBUG
-#define vdbg_printk(a_dbg_level, format, arg...) \
-	dbg_printk(a_dbg_level, format, ## arg)
-static const char *str_supported(int is_supported);
-#else
-#define vdbg_printk(a_dbg_level, format, arg...)
-#endif
+#define TPACPI_DBG_RFKILL	0x0004
+#define TPACPI_DBG_HKEY		0x0008
+#define TPACPI_DBG_FAN		0x0010
+#define TPACPI_DBG_BRGHT	0x0020
 
 #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@ static struct {
 
 static struct {
 	u16 hotkey_mask_ff:1;
-	u16 bright_cmos_ec_unsync:1;
 } tp_warned;
 
 struct thinkpad_id_data {
@@ -306,11 +303,17 @@ static u32 dbg_level;
 
 static struct workqueue_struct *tpacpi_wq;
 
+enum led_status_t {
+	TPACPI_LED_OFF = 0,
+	TPACPI_LED_ON,
+	TPACPI_LED_BLINK,
+};
+
 /* Special LED class that can defer work */
 struct tpacpi_led_classdev {
 	struct led_classdev led_classdev;
 	struct work_struct work;
-	enum led_brightness new_brightness;
+	enum led_status_t new_state;
 	unsigned int led;
 };
 
@@ -326,6 +329,39 @@ static int tpacpi_uwb_emulstate;
 #endif
 
 
+/*************************************************************************
+ *  Debugging helpers
+ */
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+	do { if (dbg_level & (a_dbg_level)) \
+		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
+	} while (0)
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk dbg_printk
+static const char *str_supported(int is_supported);
+#else
+#define vdbg_printk(a_dbg_level, format, arg...) \
+	do { } while (0)
+#endif
+
+static void tpacpi_log_usertask(const char * const what)
+{
+	printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
+		what, task_tgid_vnr(current));
+}
+
+#define tpacpi_disclose_usertask(what, format, arg...) \
+	do { \
+		if (unlikely( \
+		    (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
+		    (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
+			printk(TPACPI_DEBUG "%s: PID %d: " format, \
+				what, task_tgid_vnr(current), ## arg); \
+		} \
+	} while (0)
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -989,10 +1025,13 @@ static int __init tpacpi_new_rfkill(cons
 		/* try to set the initial state as the default for the rfkill
 		 * type, since we ask the firmware to preserve it across S5 in
 		 * NVRAM */
-		rfkill_set_default(rfktype,
+		if (rfkill_set_default(rfktype,
 				(initial_state == RFKILL_STATE_UNBLOCKED) ?
 					RFKILL_STATE_UNBLOCKED :
-					RFKILL_STATE_SOFT_BLOCKED);
+					RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
+			vdbg_printk(TPACPI_DBG_RFKILL,
+				    "Default state for %s cannot be changed\n",
+				    name);
 	}
 
 	*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1059,21 @@ static int __init tpacpi_new_rfkill(cons
 	return 0;
 }
 
+static void printk_deprecated_attribute(const char * const what,
+					const char * const details)
+{
+	tpacpi_log_usertask("deprecated sysfs attribute");
+	printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+		"will be removed. %s\n",
+		what, details);
+}
+
+static void printk_deprecated_rfkill_attribute(const char * const what)
+{
+	printk_deprecated_attribute(what,
+			"Please switch to generic rfkill before year 2010");
+}
+
 /*************************************************************************
  * thinkpad-acpi driver attributes
  */
@@ -1382,7 +1436,6 @@ static enum {	/* Reasons for waking up *
 
 static int hotkey_autosleep_ack;
 
-static int hotkey_orig_status;
 static u32 hotkey_orig_mask;
 static u32 hotkey_all_mask;
 static u32 hotkey_reserved_mask;
@@ -1529,9 +1582,9 @@ static int hotkey_status_get(int *status
 	return 0;
 }
 
-static int hotkey_status_set(int status)
+static int hotkey_status_set(bool enable)
 {
-	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
 		return -EIO;
 
 	return 0;
@@ -1847,6 +1900,9 @@ static ssize_t hotkey_enable_show(struct
 {
 	int res, status;
 
+	printk_deprecated_attribute("hotkey_enable",
+			"Hotkey reporting is always enabled");
+
 	res = hotkey_status_get(&status);
 	if (res)
 		return res;
@@ -1859,14 +1915,17 @@ static ssize_t hotkey_enable_store(struc
 			    const char *buf, size_t count)
 {
 	unsigned long t;
-	int res;
+
+	printk_deprecated_attribute("hotkey_enable",
+			"Hotkeys can be disabled through hotkey_mask");
 
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
-	res = hotkey_status_set(t);
+	if (t == 0)
+		return -EPERM;
 
-	return (res) ? res : count;
+	return count;
 }
 
 static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1969,8 @@ static ssize_t hotkey_mask_store(struct
 
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
+
 	return (res) ? res : count;
 }
 
@@ -1922,7 +1983,7 @@ static ssize_t hotkey_bios_enabled_show(
 			   struct device_attribute *attr,
 			   char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+	return sprintf(buf, "0\n");
 }
 
 static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2057,8 @@ static ssize_t hotkey_source_mask_store(
 
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
+
 	return count;
 }
 
@@ -2028,6 +2091,8 @@ static ssize_t hotkey_poll_freq_store(st
 	hotkey_poll_setup(1);
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
+
 	return count;
 }
 
@@ -2197,11 +2262,11 @@ static void hotkey_exit(void)
 	kfree(hotkey_keycode_map);
 
 	if (tp_features.hotkey) {
-		dbg_printk(TPACPI_DBG_EXIT,
+		dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
 			   "restoring original hot key mask\n");
 		/* no short-circuit boolean operator below! */
 		if ((hotkey_mask_set(hotkey_orig_mask) |
-		     hotkey_status_set(hotkey_orig_status)) != 0)
+		     hotkey_status_set(false)) != 0)
 			printk(TPACPI_ERR
 			       "failed to restore hot key mask "
 			       "to BIOS defaults\n");
@@ -2327,7 +2392,8 @@ static int __init hotkey_init(struct ibm
 	int status;
 	int hkeyv;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"initializing hotkey subdriver\n");
 
 	BUG_ON(!tpacpi_inputdev);
 	BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2410,8 @@ static int __init hotkey_init(struct ibm
 	/* hotkey not supported on 570 */
 	tp_features.hotkey = hkey_handle != NULL;
 
-	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+		"hotkeys are %s\n",
 		str_supported(tp_features.hotkey));
 
 	if (!tp_features.hotkey)
@@ -2376,10 +2443,14 @@ static int __init hotkey_init(struct ibm
 			 * T4x, X31, and later
 			 */
 			tp_features.hotkey_mask = 1;
+			vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+				"firmware HKEY interface version: 0x%x\n",
+				hkeyv);
 		}
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+		"hotkey masks are %s\n",
 		str_supported(tp_features.hotkey_mask));
 
 	if (tp_features.hotkey_mask) {
@@ -2396,10 +2467,6 @@ static int __init hotkey_init(struct ibm
 
 	/* hotkey_source_mask *must* be zero for
 	 * the first hotkey_mask_get */
-	res = hotkey_status_get(&hotkey_orig_status);
-	if (res)
-		goto err_exit;
-
 	if (tp_features.hotkey_mask) {
 		res = hotkey_mask_get();
 		if (res)
@@ -2422,7 +2489,7 @@ static int __init hotkey_init(struct ibm
 		hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT,
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 		    "hotkey source mask 0x%08x, polling freq %d\n",
 		    hotkey_source_mask, hotkey_poll_freq);
 #endif
@@ -2476,12 +2543,12 @@ static int __init hotkey_init(struct ibm
 	}
 
 	if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 			   "using Lenovo default hot key map\n");
 		memcpy(hotkey_keycode_map, &lenovo_keycode_map,
 			TPACPI_HOTKEY_MAP_SIZE);
 	} else {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 			   "using IBM default hot key map\n");
 		memcpy(hotkey_keycode_map, &ibm_keycode_map,
 			TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2605,9 @@ static int __init hotkey_init(struct ibm
 			| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
 	}
 
-	dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
-	res = hotkey_status_set(1);
+	dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"enabling firmware HKEY event interface...\n");
+	res = hotkey_status_set(true);
 	if (res) {
 		hotkey_exit();
 		return res;
@@ -2552,8 +2620,8 @@ static int __init hotkey_init(struct ibm
 		return res;
 	}
 
-	dbg_printk(TPACPI_DBG_INIT,
-			"legacy hot key reporting over procfs %s\n",
+	dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"legacy ibm/hotkey event reporting over procfs %s\n",
 			(hotkey_report_mode < 2) ?
 				"enabled" : "disabled");
 
@@ -2884,9 +2952,23 @@ static int hotkey_read(char *p)
 	return len;
 }
 
+static void hotkey_enabledisable_warn(bool enable)
+{
+	tpacpi_log_usertask("procfs hotkey enable/disable");
+	if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
+			TPACPI_WARN
+			"hotkey enable/disable functionality has been "
+			"removed from the driver.  Hotkeys are always "
+			"enabled\n"))
+		printk(TPACPI_ERR
+			"Please remove the hotkey=enable module "
+			"parameter, it is deprecated.  Hotkeys are always "
+			"enabled\n");
+}
+
 static int hotkey_write(char *buf)
 {
-	int res, status;
+	int res;
 	u32 mask;
 	char *cmd;
 
@@ -2896,17 +2978,16 @@ static int hotkey_write(char *buf)
 	if (mutex_lock_killable(&hotkey_mutex))
 		return -ERESTARTSYS;
 
-	status = -1;
 	mask = hotkey_mask;
 
 	res = 0;
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			status = 1;
+			hotkey_enabledisable_warn(1);
 		} else if (strlencmp(cmd, "disable") == 0) {
-			status = 0;
+			hotkey_enabledisable_warn(0);
+			res = -EPERM;
 		} else if (strlencmp(cmd, "reset") == 0) {
-			status = hotkey_orig_status;
 			mask = hotkey_orig_mask;
 		} else if (sscanf(cmd, "0x%x", &mask) == 1) {
 			/* mask set */
@@ -2917,8 +2998,10 @@ static int hotkey_write(char *buf)
 			goto errexit;
 		}
 	}
-	if (status != -1)
-		res = hotkey_status_set(status);
+
+	if (!res)
+		tpacpi_disclose_usertask("procfs hotkey",
+			"set mask to 0x%08x\n", mask);
 
 	if (!res && mask != hotkey_mask)
 		res = hotkey_mask_set(mask);
@@ -2971,13 +3054,17 @@ enum {
 	TP_ACPI_BLTH_SAVE_STATE		= 0x05, /* Save state for S4/S5 */
 };
 
+#define TPACPI_RFK_BLUETOOTH_SW_NAME	"tpacpi_bluetooth_sw"
+
 static struct rfkill *tpacpi_bluetooth_rfkill;
 
 static void bluetooth_suspend(pm_message_t state)
 {
 	/* Try to make sure radio will resume powered off */
-	acpi_evalf(NULL, NULL, "\\BLTH", "vd",
-		   TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+	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_radiosw(void)
@@ -3015,6 +3102,10 @@ static void bluetooth_update_rfk(void)
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_bluetooth_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3121,9 @@ static int bluetooth_set_radiosw(int rad
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"will %s bluetooth\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_bluetoothemul) {
 		tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3154,8 @@ static ssize_t bluetooth_enable_show(str
 {
 	int status;
 
+	printk_deprecated_rfkill_attribute("bluetooth_enable");
+
 	status = bluetooth_get_radiosw();
 	if (status < 0)
 		return status;
@@ -3075,9 +3171,13 @@ static ssize_t bluetooth_enable_store(st
 	unsigned long t;
 	int res;
 
+	printk_deprecated_rfkill_attribute("bluetooth_enable");
+
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
+
 	res = bluetooth_set_radiosw(t, 1);
 
 	return (res) ? res : count;
@@ -3111,6 +3211,8 @@ static int tpacpi_bluetooth_rfk_get(void
 
 static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3121,6 +3223,9 @@ static void bluetooth_shutdown(void)
 			TP_ACPI_BLTH_SAVE_STATE))
 		printk(TPACPI_NOTICE
 			"failed to save bluetooth state to NVRAM\n");
+	else
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"bluestooth state saved to NVRAM\n");
 }
 
 static void bluetooth_exit(void)
@@ -3139,7 +3244,8 @@ static int __init bluetooth_init(struct
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing bluetooth subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
@@ -3148,7 +3254,8 @@ static int __init bluetooth_init(struct
 	tp_features.bluetooth = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GBDC", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"bluetooth is %s, status 0x%02x\n",
 		str_supported(tp_features.bluetooth),
 		status);
 
@@ -3163,7 +3270,7 @@ static int __init bluetooth_init(struct
 	    !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
 		/* no bluetooth hardware present in system */
 		tp_features.bluetooth = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 			   "bluetooth hardware not installed\n");
 	}
 
@@ -3178,7 +3285,7 @@ static int __init bluetooth_init(struct
 	res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
 				&tpacpi_bluetooth_rfkill,
 				RFKILL_TYPE_BLUETOOTH,
-				"tpacpi_bluetooth_sw",
+				TPACPI_RFK_BLUETOOTH_SW_NAME,
 				true,
 				tpacpi_bluetooth_rfk_set,
 				tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3318,27 @@ static int bluetooth_read(char *p)
 static int bluetooth_write(char *buf)
 {
 	char *cmd;
+	int state = -1;
 
 	if (!tp_features.bluetooth)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			bluetooth_set_radiosw(1, 1);
+			state = 1;
 		} else if (strlencmp(cmd, "disable") == 0) {
-			bluetooth_set_radiosw(0, 1);
+			state = 0;
 		} else
 			return -EINVAL;
 	}
 
+	if (state != -1) {
+		tpacpi_disclose_usertask("procfs bluetooth",
+			"attempt to %s\n",
+			state ? "enable" : "disable");
+		bluetooth_set_radiosw(state, 1);
+	}
+
 	return 0;
 }
 
@@ -3248,13 +3363,17 @@ enum {
 						   off / last state */
 };
 
+#define TPACPI_RFK_WWAN_SW_NAME		"tpacpi_wwan_sw"
+
 static struct rfkill *tpacpi_wan_rfkill;
 
 static void wan_suspend(pm_message_t state)
 {
 	/* Try to make sure radio will resume powered off */
-	acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
-		   TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+	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_radiosw(void)
@@ -3292,6 +3411,10 @@ static void wan_update_rfk(void)
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_wan_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3430,9 @@ static int wan_set_radiosw(int radio_on,
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"will %s WWAN\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_wwanemul) {
 		tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3463,8 @@ static ssize_t wan_enable_show(struct de
 {
 	int status;
 
+	printk_deprecated_rfkill_attribute("wwan_enable");
+
 	status = wan_get_radiosw();
 	if (status < 0)
 		return status;
@@ -3352,9 +3480,13 @@ static ssize_t wan_enable_store(struct d
 	unsigned long t;
 	int res;
 
+	printk_deprecated_rfkill_attribute("wwan_enable");
+
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
+
 	res = wan_set_radiosw(t, 1);
 
 	return (res) ? res : count;
@@ -3388,6 +3520,8 @@ static int tpacpi_wan_rfk_get(void *data
 
 static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3398,6 +3532,9 @@ static void wan_shutdown(void)
 			TP_ACPI_WGSV_SAVE_STATE))
 		printk(TPACPI_NOTICE
 			"failed to save WWAN state to NVRAM\n");
+	else
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"WWAN state saved to NVRAM\n");
 }
 
 static void wan_exit(void)
@@ -3416,14 +3553,16 @@ static int __init wan_init(struct ibm_in
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing wan subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
 	tp_features.wan = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GWAN", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"wan is %s, status 0x%02x\n",
 		str_supported(tp_features.wan),
 		status);
 
@@ -3438,7 +3577,7 @@ static int __init wan_init(struct ibm_in
 	    !(status & TP_ACPI_WANCARD_HWPRESENT)) {
 		/* no wan hardware present in system */
 		tp_features.wan = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 			   "wan hardware not installed\n");
 	}
 
@@ -3453,7 +3592,7 @@ static int __init wan_init(struct ibm_in
 	res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
 				&tpacpi_wan_rfkill,
 				RFKILL_TYPE_WWAN,
-				"tpacpi_wwan_sw",
+				TPACPI_RFK_WWAN_SW_NAME,
 				true,
 				tpacpi_wan_rfk_set,
 				tpacpi_wan_rfk_get);
@@ -3471,6 +3610,8 @@ static int wan_read(char *p)
 	int len = 0;
 	int status = wan_get_radiosw();
 
+	tpacpi_disclose_usertask("procfs wan", "read");
+
 	if (!tp_features.wan)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	else {
@@ -3486,19 +3627,27 @@ static int wan_read(char *p)
 static int wan_write(char *buf)
 {
 	char *cmd;
+	int state = -1;
 
 	if (!tp_features.wan)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			wan_set_radiosw(1, 1);
+			state = 1;
 		} else if (strlencmp(cmd, "disable") == 0) {
-			wan_set_radiosw(0, 1);
+			state = 0;
 		} else
 			return -EINVAL;
 	}
 
+	if (state != -1) {
+		tpacpi_disclose_usertask("procfs wan",
+			"attempt to %s\n",
+			state ? "enable" : "disable");
+		wan_set_radiosw(state, 1);
+	}
+
 	return 0;
 }
 
@@ -3521,6 +3670,8 @@ enum {
 	TP_ACPI_UWB_RADIOSSW	= 0x02,	/* UWB radio enabled */
 };
 
+#define TPACPI_RFK_UWB_SW_NAME	"tpacpi_uwb_sw"
+
 static struct rfkill *tpacpi_uwb_rfkill;
 
 static int uwb_get_radiosw(void)
@@ -3558,6 +3709,10 @@ static void uwb_update_rfk(void)
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_uwb_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3728,9 @@ static int uwb_set_radiosw(int radio_on,
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+			"will %s UWB\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_uwbemul) {
 		tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3765,8 @@ static int tpacpi_uwb_rfk_get(void *data
 
 static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3621,14 +3781,16 @@ static int __init uwb_init(struct ibm_in
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing uwb subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
 	tp_features.uwb = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GUWB", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"uwb is %s, status 0x%02x\n",
 		str_supported(tp_features.uwb),
 		status);
 
@@ -3653,7 +3815,7 @@ static int __init uwb_init(struct ibm_in
 	res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
 				&tpacpi_uwb_rfkill,
 				RFKILL_TYPE_UWB,
-				"tpacpi_uwb_sw",
+				TPACPI_RFK_UWB_SW_NAME,
 				false,
 				tpacpi_uwb_rfk_set,
 				tpacpi_uwb_rfk_get);
@@ -4057,7 +4219,7 @@ static void light_set_status_worker(stru
 			container_of(work, struct tpacpi_led_classdev, work);
 
 	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
-		light_set_status((data->new_brightness != LED_OFF));
+		light_set_status((data->new_state != TPACPI_LED_OFF));
 }
 
 static void light_sysfs_set(struct led_classdev *led_cdev,
@@ -4067,7 +4229,8 @@ static void light_sysfs_set(struct led_c
 		container_of(led_cdev,
 			     struct tpacpi_led_classdev,
 			     led_classdev);
-	data->new_brightness = brightness;
+	data->new_state = (brightness != LED_OFF) ?
+				TPACPI_LED_ON : TPACPI_LED_OFF;
 	queue_work(tpacpi_wq, &data->work);
 }
 
@@ -4574,12 +4737,6 @@ enum {	/* For TPACPI_LED_OLD */
 	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
 };
 
-enum led_status_t {
-	TPACPI_LED_OFF = 0,
-	TPACPI_LED_ON,
-	TPACPI_LED_BLINK,
-};
-
 static enum led_access_mode led_supported;
 
 TPACPI_HANDLE(led, ec, "SLED",	/* 570 */
@@ -4602,6 +4759,16 @@ static const char * const tpacpi_led_nam
 	"tpacpi::unknown_led",
 	"tpacpi::standby",
 };
+#define TPACPI_SAFE_LEDS	0x0081U
+
+static inline bool tpacpi_is_led_restricted(const unsigned int led)
+{
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+	return false;
+#else
+	return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
+#endif
+}
 
 static int led_get_status(const unsigned int led)
 {
@@ -4639,16 +4806,20 @@ static int led_set_status(const unsigned
 	switch (led_supported) {
 	case TPACPI_LED_570:
 		/* 570 */
-		if (led > 7)
+		if (unlikely(led > 7))
 			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 				(1 << led), led_sled_arg1[ledstatus]))
 			rc = -EIO;
 		break;
 	case TPACPI_LED_OLD:
 		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
-		if (led > 7)
+		if (unlikely(led > 7))
 			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
 		if (rc >= 0)
 			rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4830,10 @@ static int led_set_status(const unsigned
 		break;
 	case TPACPI_LED_NEW:
 		/* all others */
+		if (unlikely(led >= TPACPI_LED_NUMLEDS))
+			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 				led, led_led_arg1[ledstatus]))
 			rc = -EIO;
@@ -4673,23 +4848,13 @@ static int led_set_status(const unsigned
 	return rc;
 }
 
-static void led_sysfs_set_status(unsigned int led,
-				 enum led_brightness brightness)
-{
-	led_set_status(led,
-			(brightness == LED_OFF) ?
-			TPACPI_LED_OFF :
-			(tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
-				TPACPI_LED_BLINK : TPACPI_LED_ON);
-}
-
 static void led_set_status_worker(struct work_struct *work)
 {
 	struct tpacpi_led_classdev *data =
 		container_of(work, struct tpacpi_led_classdev, work);
 
 	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
-		led_sysfs_set_status(data->led, data->new_brightness);
+		led_set_status(data->led, data->new_state);
 }
 
 static void led_sysfs_set(struct led_classdev *led_cdev,
@@ -4698,7 +4863,13 @@ static void led_sysfs_set(struct led_cla
 	struct tpacpi_led_classdev *data = container_of(led_cdev,
 			     struct tpacpi_led_classdev, led_classdev);
 
-	data->new_brightness = brightness;
+	if (brightness == LED_OFF)
+		data->new_state = TPACPI_LED_OFF;
+	else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
+		data->new_state = TPACPI_LED_ON;
+	else
+		data->new_state = TPACPI_LED_BLINK;
+
 	queue_work(tpacpi_wq, &data->work);
 }
 
@@ -4716,7 +4887,7 @@ static int led_sysfs_blink_set(struct le
 	} else if ((*delay_on != 500) || (*delay_off != 500))
 		return -EINVAL;
 
-	data->new_brightness = TPACPI_LED_BLINK;
+	data->new_state = TPACPI_LED_BLINK;
 	queue_work(tpacpi_wq, &data->work);
 
 	return 0;
@@ -4751,6 +4922,30 @@ static void led_exit(void)
 	kfree(tpacpi_leds);
 }
 
+static int __init tpacpi_init_led(unsigned int led)
+{
+	int rc;
+
+	tpacpi_leds[led].led = led;
+
+	tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
+	tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
+	if (led_supported == TPACPI_LED_570)
+		tpacpi_leds[led].led_classdev.brightness_get =
+						&led_sysfs_get;
+
+	tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
+
+	INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
+
+	rc = led_classdev_register(&tpacpi_pdev->dev,
+				&tpacpi_leds[led].led_classdev);
+	if (rc < 0)
+		tpacpi_leds[led].led_classdev.name = NULL;
+
+	return rc;
+}
+
 static int __init led_init(struct ibm_init_struct *iibm)
 {
 	unsigned int i;
@@ -4784,27 +4979,21 @@ static int __init led_init(struct ibm_in
 	}
 
 	for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
-		tpacpi_leds[i].led = i;
-
-		tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
-		tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
-		if (led_supported == TPACPI_LED_570)
-			tpacpi_leds[i].led_classdev.brightness_get =
-							&led_sysfs_get;
-
-		tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
-
-		INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
-
-		rc = led_classdev_register(&tpacpi_pdev->dev,
-					   &tpacpi_leds[i].led_classdev);
-		if (rc < 0) {
-			tpacpi_leds[i].led_classdev.name = NULL;
-			led_exit();
-			return rc;
+		if (!tpacpi_is_led_restricted(i)) {
+			rc = tpacpi_init_led(i);
+			if (rc < 0) {
+				led_exit();
+				return rc;
+			}
 		}
 	}
 
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+	if (led_supported != TPACPI_LED_NONE)
+		printk(TPACPI_NOTICE
+			"warning: userspace override of important "
+			"firmware LEDs is enabled\n");
+#endif
 	return (led_supported != TPACPI_LED_NONE)? 0 : 1;
 }
 
@@ -5340,6 +5529,20 @@ static struct ibm_struct ecdump_driver_d
 
 #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
 
+/*
+ * ThinkPads can read brightness from two places: EC HBRV (0x31), or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC HBRV (0x31) has the following layout
+ *   Bit 7: unknown function
+ *   Bit 6: unknown function
+ *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ *   Bit 4: must be set to zero to avoid problems
+ *   Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the HBRV layout
+ */
+
 enum {
 	TP_EC_BACKLIGHT = 0x31,
 
@@ -5349,108 +5552,164 @@ enum {
 	TP_EC_BACKLIGHT_MAPSW = 0x20,
 };
 
+enum tpacpi_brightness_access_mode {
+	TPACPI_BRGHT_MODE_AUTO = 0,	/* Not implemented yet */
+	TPACPI_BRGHT_MODE_EC,		/* EC control */
+	TPACPI_BRGHT_MODE_UCMS_STEP,	/* UCMS step-based control */
+	TPACPI_BRGHT_MODE_ECNVRAM,	/* EC control w/ NVRAM store */
+	TPACPI_BRGHT_MODE_MAX
+};
+
 static struct backlight_device *ibm_backlight_device;
-static int brightness_mode;
+
+static enum tpacpi_brightness_access_mode brightness_mode =
+		TPACPI_BRGHT_MODE_MAX;
+
 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
 
 static struct mutex brightness_mutex;
 
-/*
- * ThinkPads can read brightness from two places: EC 0x31, or
- * CMOS NVRAM byte 0x5E, bits 0-3.
- *
- * EC 0x31 has the following layout
- *   Bit 7: unknown function
- *   Bit 6: unknown function
- *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
- *   Bit 4: must be set to zero to avoid problems
- *   Bit 3-0: backlight brightness level
- *
- * brightness_get_raw returns status data in the EC 0x31 layout
- */
-static int brightness_get_raw(int *status)
+/* NVRAM brightness access,
+ * call with brightness_mutex held! */
+static unsigned int tpacpi_brightness_nvram_get(void)
 {
-	u8 lec = 0, lcmos = 0, level = 0;
+	u8 lnvram;
 
-	if (brightness_mode & 1) {
-		if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
+	lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+		  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+		  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+	lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
+
+	return lnvram;
+}
+
+static void tpacpi_brightness_checkpoint_nvram(void)
+{
+	u8 lec = 0;
+	u8 b_nvram;
+
+	if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
+		return;
+
+	vdbg_printk(TPACPI_DBG_BRGHT,
+		"trying to checkpoint backlight level to NVRAM...\n");
+
+	if (mutex_lock_killable(&brightness_mutex) < 0)
+		return;
+
+	if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+		goto unlock;
+	lec &= TP_EC_BACKLIGHT_LVLMSK;
+	b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+
+	if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+			     >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
+		/* NVRAM needs update */
+		b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
+				TP_NVRAM_POS_LEVEL_BRIGHTNESS);
+		b_nvram |= lec;
+		nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+		dbg_printk(TPACPI_DBG_BRGHT,
+			   "updated NVRAM backlight level to %u (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
+	} else
+		vdbg_printk(TPACPI_DBG_BRGHT,
+			   "NVRAM backlight level already is %u (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
+
+unlock:
+	mutex_unlock(&brightness_mutex);
+}
+
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_get_raw(int *status)
+{
+	u8 lec = 0;
+
+	switch (brightness_mode) {
+	case TPACPI_BRGHT_MODE_UCMS_STEP:
+		*status = tpacpi_brightness_nvram_get();
+		return 0;
+	case TPACPI_BRGHT_MODE_EC:
+	case TPACPI_BRGHT_MODE_ECNVRAM:
+		if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
 			return -EIO;
-		level = lec & TP_EC_BACKLIGHT_LVLMSK;
-	};
-	if (brightness_mode & 2) {
-		lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
-			 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
-			>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
-		lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
-		level = lcmos;
+		*status = lec;
+		return 0;
+	default:
+		return -ENXIO;
 	}
+}
 
-	if (brightness_mode == 3) {
-		*status = lec;	/* Prefer EC, CMOS is just a backing store */
-		lec &= TP_EC_BACKLIGHT_LVLMSK;
-		if (lec == lcmos)
-			tp_warned.bright_cmos_ec_unsync = 0;
-		else {
-			if (!tp_warned.bright_cmos_ec_unsync) {
-				printk(TPACPI_ERR
-					"CMOS NVRAM (%u) and EC (%u) do not "
-					"agree on display brightness level\n",
-					(unsigned int) lcmos,
-					(unsigned int) lec);
-				tp_warned.bright_cmos_ec_unsync = 1;
-			}
+/* call with brightness_mutex held! */
+/* do NOT call with illegal backlight level value */
+static int tpacpi_brightness_set_ec(unsigned int value)
+{
+	u8 lec = 0;
+
+	if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+		return -EIO;
+
+	if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
+				(lec & TP_EC_BACKLIGHT_CMDMSK) |
+				(value & TP_EC_BACKLIGHT_LVLMSK))))
+		return -EIO;
+
+	return 0;
+}
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_set_ucmsstep(unsigned int value)
+{
+	int cmos_cmd, inc;
+	unsigned int current_value, i;
+
+	current_value = tpacpi_brightness_nvram_get();
+
+	if (value == current_value)
+		return 0;
+
+	cmos_cmd = (value > current_value) ?
+			TP_CMOS_BRIGHTNESS_UP :
+			TP_CMOS_BRIGHTNESS_DOWN;
+	inc = (value > current_value) ? 1 : -1;
+
+	for (i = current_value; i != value; i += inc)
+		if (issue_thinkpad_cmos_command(cmos_cmd))
 			return -EIO;
-		}
-	} else {
-		*status = level;
-	}
 
 	return 0;
 }
 
 /* May return EINTR which can always be mapped to ERESTARTSYS */
-static int brightness_set(int value)
+static int brightness_set(unsigned int value)
 {
-	int cmos_cmd, inc, i, res;
-	int current_value;
-	int command_bits;
+	int res;
 
 	if (value > ((tp_features.bright_16levels)? 15 : 7) ||
 	    value < 0)
 		return -EINVAL;
 
+	vdbg_printk(TPACPI_DBG_BRGHT,
+			"set backlight level to %d\n", value);
+
 	res = mutex_lock_killable(&brightness_mutex);
 	if (res < 0)
 		return res;
 
-	res = brightness_get_raw(&current_value);
-	if (res < 0)
-		goto errout;
-
-	command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
-	current_value &= TP_EC_BACKLIGHT_LVLMSK;
-
-	cmos_cmd = value > current_value ?
-			TP_CMOS_BRIGHTNESS_UP :
-			TP_CMOS_BRIGHTNESS_DOWN;
-	inc = (value > current_value)? 1 : -1;
-
-	res = 0;
-	for (i = current_value; i != value; i += inc) {
-		if ((brightness_mode & 2) &&
-		    issue_thinkpad_cmos_command(cmos_cmd)) {
-			res = -EIO;
-			goto errout;
-		}
-		if ((brightness_mode & 1) &&
-		    !acpi_ec_write(TP_EC_BACKLIGHT,
-				   (i + inc) | command_bits)) {
-			res = -EIO;
-			goto errout;;
-		}
+	switch (brightness_mode) {
+	case TPACPI_BRGHT_MODE_EC:
+	case TPACPI_BRGHT_MODE_ECNVRAM:
+		res = tpacpi_brightness_set_ec(value);
+		break;
+	case TPACPI_BRGHT_MODE_UCMS_STEP:
+		res = tpacpi_brightness_set_ucmsstep(value);
+		break;
+	default:
+		res = -ENXIO;
 	}
 
-errout:
 	mutex_unlock(&brightness_mutex);
 	return res;
 }
@@ -5459,21 +5718,34 @@ errout:
 
 static int brightness_update_status(struct backlight_device *bd)
 {
-	/* it is the backlight class's job (caller) to handle
-	 * EINTR and other errors properly */
-	return brightness_set(
+	unsigned int level =
 		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
 		 bd->props.power == FB_BLANK_UNBLANK) ?
-				bd->props.brightness : 0);
+				bd->props.brightness : 0;
+
+	dbg_printk(TPACPI_DBG_BRGHT,
+			"backlight: attempt to set level to %d\n",
+			level);
+
+	/* it is the backlight class's job (caller) to handle
+	 * EINTR and other errors properly */
+	return brightness_set(level);
 }
 
 static int brightness_get(struct backlight_device *bd)
 {
 	int status, res;
 
-	res = brightness_get_raw(&status);
+	res = mutex_lock_killable(&brightness_mutex);
 	if (res < 0)
-		return 0; /* FIXME: teach backlight about error handling */
+		return 0;
+
+	res = tpacpi_brightness_get_raw(&status);
+
+	mutex_unlock(&brightness_mutex);
+
+	if (res < 0)
+		return 0;
 
 	return status & TP_EC_BACKLIGHT_LVLMSK;
 }
@@ -5523,7 +5795,7 @@ static int __init brightness_init(struct
 	}
 
 	if (!brightness_enable) {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
 			   "brightness support disabled by "
 			   "module parameter\n");
 		return 1;
@@ -5538,20 +5810,38 @@ static int __init brightness_init(struct
 	if (b == 16)
 		tp_features.bright_16levels = 1;
 
-	if (!brightness_mode) {
-		if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
-			brightness_mode = 2;
-		else
-			brightness_mode = 3;
+	/*
+	 * Check for module parameter bogosity, note that we
+	 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
+	 * able to detect "unspecified"
+	 */
+	if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
+		return -EINVAL;
 
-		dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
-			brightness_mode);
-	}
+	/* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
+	if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
+	    brightness_mode == TPACPI_BRGHT_MODE_MAX) {
+		if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
+			/*
+			 * IBM models that define HBRV probably have
+			 * EC-based backlight level control
+			 */
+			if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
+				/* T40-T43, R50-R52, R50e, R51e, X31-X41 */
+				brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+			else
+				/* all other IBM ThinkPads */
+				brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+		} else
+			/* All Lenovo ThinkPads */
+			brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
 
-	if (brightness_mode > 3)
-		return -EINVAL;
+		dbg_printk(TPACPI_DBG_BRGHT,
+			   "selected brightness_mode=%d\n",
+			   brightness_mode);
+	}
 
-	if (brightness_get_raw(&b) < 0)
+	if (tpacpi_brightness_get_raw(&b) < 0)
 		return 1;
 
 	if (tp_features.bright_16levels)
@@ -5565,7 +5855,8 @@ static int __init brightness_init(struct
 		printk(TPACPI_ERR "Could not register backlight device\n");
 		return PTR_ERR(ibm_backlight_device);
 	}
-	vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+			"brightness is supported\n");
 
 	ibm_backlight_device->props.max_brightness =
 				(tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5866,25 @@ static int __init brightness_init(struct
 	return 0;
 }
 
+static void brightness_suspend(pm_message_t state)
+{
+	tpacpi_brightness_checkpoint_nvram();
+}
+
+static void brightness_shutdown(void)
+{
+	tpacpi_brightness_checkpoint_nvram();
+}
+
 static void brightness_exit(void)
 {
 	if (ibm_backlight_device) {
-		vdbg_printk(TPACPI_DBG_EXIT,
+		vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
 			    "calling backlight_device_unregister()\n");
 		backlight_device_unregister(ibm_backlight_device);
 	}
+
+	tpacpi_brightness_checkpoint_nvram();
 }
 
 static int brightness_read(char *p)
@@ -5628,6 +5931,9 @@ static int brightness_write(char *buf)
 			return -EINVAL;
 	}
 
+	tpacpi_disclose_usertask("procfs brightness",
+			"set level to %d\n", level);
+
 	/*
 	 * Now we know what the final level should be, so we try to set it.
 	 * Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5947,8 @@ static struct ibm_struct brightness_driv
 	.read = brightness_read,
 	.write = brightness_write,
 	.exit = brightness_exit,
+	.suspend = brightness_suspend,
+	.shutdown = brightness_shutdown,
 };
 
 /*************************************************************************
@@ -5811,7 +6119,7 @@ static struct ibm_struct volume_driver_d
  *	ThinkPads from this same time period (and earlier) probably lack the
  *	tachometer as well.
  *
- *	Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ *	Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
  *	was never fixed by IBM to report the EC firmware version string
  *	probably support the tachometer (like the early X models), so
  *	detecting it is quite hard.  We need more data to know for sure.
@@ -6086,6 +6394,9 @@ static int fan_set_level(int level)
 	default:
 		return -ENXIO;
 	}
+
+	vdbg_printk(TPACPI_DBG_FAN,
+		"fan control: set fan control register to 0x%02x\n", level);
 	return 0;
 }
 
@@ -6163,6 +6474,11 @@ static int fan_set_enable(void)
 	}
 
 	mutex_unlock(&fan_mutex);
+
+	if (!rc)
+		vdbg_printk(TPACPI_DBG_FAN,
+			"fan control: set fan control register to 0x%02x\n",
+			s);
 	return rc;
 }
 
@@ -6199,6 +6515,9 @@ static int fan_set_disable(void)
 		rc = -ENXIO;
 	}
 
+	if (!rc)
+		vdbg_printk(TPACPI_DBG_FAN,
+			"fan control: set fan control register to 0\n");
 
 	mutex_unlock(&fan_mutex);
 	return rc;
@@ -6327,6 +6646,9 @@ static ssize_t fan_pwm1_enable_store(str
 	if (parse_strtoul(buf, 2, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("hwmon pwm1_enable",
+			"set fan mode to %lu\n", t);
+
 	switch (t) {
 	case 0:
 		level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6714,9 @@ static ssize_t fan_pwm1_store(struct dev
 	if (parse_strtoul(buf, 255, &s))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("hwmon pwm1",
+			"set fan speed to %lu\n", s);
+
 	/* scale down from 0-255 to 0-7 */
 	newlevel = (s >> 5) & 0x07;
 
@@ -6458,6 +6783,8 @@ static ssize_t fan_fan_watchdog_store(st
 	fan_watchdog_maxinterval = t;
 	fan_watchdog_reset();
 
+	tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
+
 	return count;
 }
 
@@ -6479,7 +6806,8 @@ static int __init fan_init(struct ibm_in
 {
 	int rc;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+			"initializing fan subdriver\n");
 
 	mutex_init(&fan_mutex);
 	fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6866,8 @@ static int __init fan_init(struct ibm_in
 		}
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+		"fan is %s, modes %d, %d\n",
 		str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
 		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
 		fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6876,7 @@ static int __init fan_init(struct ibm_in
 	if (!fan_control_allowed) {
 		fan_control_access_mode = TPACPI_FAN_WR_NONE;
 		fan_control_commands = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
 			   "fan control features disabled by parameter\n");
 	}
 
@@ -6576,7 +6905,7 @@ static int __init fan_init(struct ibm_in
 
 static void fan_exit(void)
 {
-	vdbg_printk(TPACPI_DBG_EXIT,
+	vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
 		    "cancelling any pending fan watchdog tasks\n");
 
 	/* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7086,9 @@ static int fan_write_cmd_level(const cha
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "level command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan",
+			"set level to %d\n", level);
 
 	return 1;
 }
@@ -6770,6 +7102,8 @@ static int fan_write_cmd_enable(const ch
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "enable command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan", "enable\n");
 
 	return 1;
 }
@@ -6783,6 +7117,8 @@ static int fan_write_cmd_disable(const c
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "disable command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan", "disable\n");
 
 	return 1;
 }
@@ -6801,6 +7137,9 @@ static int fan_write_cmd_speed(const cha
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "speed command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan",
+			"set speed to %d\n", speed);
 
 	return 1;
 }
@@ -6814,8 +7153,12 @@ static int fan_write_cmd_watchdog(const
 
 	if (interval < 0 || interval > 120)
 		*rc = -EINVAL;
-	else
+	else {
 		fan_watchdog_maxinterval = interval;
+		tpacpi_disclose_usertask("procfs fan",
+			"set watchdog timer to %d\n",
+			interval);
+	}
 
 	return 1;
 }
@@ -6992,7 +7335,6 @@ static int __init ibm_init(struct ibm_in
 			ret = -ENODEV;
 			goto err_out;
 		}
-		entry->owner = THIS_MODULE;
 		entry->data = ibm;
 		entry->read_proc = &dispatch_procfs_read;
 		if (ibm->write)
@@ -7244,10 +7586,10 @@ module_param_named(fan_control, fan_cont
 MODULE_PARM_DESC(fan_control,
 		 "Enables setting fan parameters features when true");
 
-module_param_named(brightness_mode, brightness_mode, int, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0);
 MODULE_PARM_DESC(brightness_mode,
 		 "Selects brightness control strategy: "
-		 "0=auto, 1=EC, 2=CMOS, 3=both");
+		 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
 
 module_param(brightness_enable, uint, 0);
 MODULE_PARM_DESC(brightness_enable,
@@ -7405,7 +7747,6 @@ static int __init thinkpad_acpi_module_i
 		thinkpad_acpi_module_exit();
 		return -ENODEV;
 	}
-	proc_dir->owner = THIS_MODULE;
 
 	ret = platform_driver_register(&tpacpi_pdriver);
 	if (ret) {
@@ -7517,12 +7858,18 @@ static int __init thinkpad_acpi_module_i
 	return 0;
 }
 
-/* Please remove this in year 2009 */
-MODULE_ALIAS("ibm_acpi");
-
 MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
 
 /*
+ * This will autoload the driver in almost every ThinkPad
+ * in widespread use.
+ *
+ * Only _VERY_ old models, like the 240, 240x and 570 lack
+ * the HKEY event interface.
+ */
+MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);
+
+/*
  * DMI matching for module autoloading
  *
  * See http://thinkwiki.org/wiki/List_of_DMI_IDs
@@ -7534,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
 #define IBM_BIOS_MODULE_ALIAS(__type) \
 	MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
 
-/* Non-ancient thinkpads */
-MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
-MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
-
 /* Ancient thinkpad BIOSes have to be identified by
  * BIOS type or model number, and there are far less
  * BIOS types than model numbers... */
-IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]");
-IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
-IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
+IBM_BIOS_MODULE_ALIAS("I[MU]");		/* 570, 570e */
 
-MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
+MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
+MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
 MODULE_DESCRIPTION(TPACPI_DESC);
 MODULE_VERSION(TPACPI_VERSION);
 MODULE_LICENSE("GPL");
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/toshiba_acpi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/toshiba_acpi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/toshiba_acpi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/toshiba_acpi.c	2009-06-09 23:05:27.000000000 -0400
@@ -679,8 +679,6 @@ static acpi_status __init add_device(voi
 					      toshiba_proc_dir,
 					      (read_proc_t *) dispatch_read,
 					      item);
-		if (proc)
-			proc->owner = THIS_MODULE;
 		if (proc && item->write_func)
 			proc->write_proc = (write_proc_t *) dispatch_write;
 	}
@@ -772,7 +770,6 @@ static int __init toshiba_acpi_init(void
 		toshiba_acpi_exit();
 		return -ENODEV;
 	} else {
-		toshiba_proc_dir->owner = THIS_MODULE;
 		status = add_device();
 		if (ACPI_FAILURE(status)) {
 			toshiba_acpi_exit();
diff -druNp linux-libre-2.6.29-gnu1/drivers/platform/x86/wmi.c linux-libre-2.6.30-gnu1/drivers/platform/x86/wmi.c
--- linux-libre-2.6.29-gnu1/drivers/platform/x86/wmi.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/platform/x86/wmi.c	2009-06-09 23:05:27.000000000 -0400
@@ -81,6 +81,7 @@ static struct wmi_block wmi_blocks;
 
 static int acpi_wmi_remove(struct acpi_device *device, int type);
 static int acpi_wmi_add(struct acpi_device *device);
+static void acpi_wmi_notify(struct acpi_device *device, u32 event);
 
 static const struct acpi_device_id wmi_device_ids[] = {
 	{"PNP0C14", 0},
@@ -96,6 +97,7 @@ static struct acpi_driver acpi_wmi_drive
 	.ops = {
 		.add = acpi_wmi_add,
 		.remove = acpi_wmi_remove,
+		.notify = acpi_wmi_notify,
 		},
 };
 
@@ -643,12 +645,11 @@ acpi_wmi_ec_space_handler(u32 function,
 	}
 }
 
-static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_wmi_notify(struct acpi_device *device, u32 event)
 {
 	struct guid_block *block;
 	struct wmi_block *wblock;
 	struct list_head *p;
-	struct acpi_device *device = data;
 
 	list_for_each(p, &wmi_blocks.list) {
 		wblock = list_entry(p, struct wmi_block, list);
@@ -669,9 +670,6 @@ static void acpi_wmi_notify(acpi_handle
 
 static int acpi_wmi_remove(struct acpi_device *device, int type)
 {
-	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-		acpi_wmi_notify);
-
 	acpi_remove_address_space_handler(device->handle,
 				ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
 
@@ -683,13 +681,6 @@ static int __init acpi_wmi_add(struct ac
 	acpi_status status;
 	int result = 0;
 
-	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-		acpi_wmi_notify, device);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Error installing notify handler\n");
-		return -ENODEV;
-	}
-
 	status = acpi_install_address_space_handler(device->handle,
 						    ACPI_ADR_SPACE_EC,
 						    &acpi_wmi_ec_space_handler,
diff -druNp linux-libre-2.6.29-gnu1/drivers/pnp/card.c linux-libre-2.6.30-gnu1/drivers/pnp/card.c
--- linux-libre-2.6.29-gnu1/drivers/pnp/card.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pnp/card.c	2009-06-09 23:05:27.000000000 -0400
@@ -167,7 +167,7 @@ struct pnp_card *pnp_alloc_card(struct p
 	card->dev.parent = &card->protocol->dev;
 	dev_set_name(&card->dev, "%02x:%02x", card->protocol->number, card->number);
 
-	card->dev.coherent_dma_mask = DMA_24BIT_MASK;
+	card->dev.coherent_dma_mask = DMA_BIT_MASK(24);
 	card->dev.dma_mask = &card->dev.coherent_dma_mask;
 
 	dev_id = pnp_add_card_id(card, pnpid);
diff -druNp linux-libre-2.6.29-gnu1/drivers/pnp/core.c linux-libre-2.6.30-gnu1/drivers/pnp/core.c
--- linux-libre-2.6.29-gnu1/drivers/pnp/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pnp/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -137,7 +137,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp
 	INIT_LIST_HEAD(&dev->options);
 	dev->protocol = protocol;
 	dev->number = id;
-	dev->dma_mask = DMA_24BIT_MASK;
+	dev->dma_mask = DMA_BIT_MASK(24);
 
 	dev->dev.parent = &dev->protocol->dev;
 	dev->dev.bus = &pnp_bus_type;
diff -druNp linux-libre-2.6.29-gnu1/drivers/pnp/pnpacpi/core.c linux-libre-2.6.30-gnu1/drivers/pnp/pnpacpi/core.c
--- linux-libre-2.6.29-gnu1/drivers/pnp/pnpacpi/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pnp/pnpacpi/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,7 +83,6 @@ static int pnpacpi_set_resources(struct
 	acpi_handle handle = dev->data;
 	struct acpi_buffer buffer;
 	int ret;
-	acpi_status status;
 
 	pnp_dbg(&dev->dev, "set resources\n");
 	ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -94,21 +93,29 @@ static int pnpacpi_set_resources(struct
 		kfree(buffer.pointer);
 		return ret;
 	}
-	status = acpi_set_current_resources(handle, &buffer);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
 		ret = -EINVAL;
+	else if (acpi_bus_power_manageable(handle))
+		ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
 	kfree(buffer.pointer);
 	return ret;
 }
 
 static int pnpacpi_disable_resources(struct pnp_dev *dev)
 {
-	acpi_status status;
+	acpi_handle handle = dev->data;
+	int ret;
+
+	dev_dbg(&dev->dev, "disable resources\n");
 
 	/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
-	status = acpi_evaluate_object((acpi_handle) dev->data,
-				      "_DIS", NULL, NULL);
-	return ACPI_FAILURE(status) ? -ENODEV : 0;
+	ret = 0;
+	if (acpi_bus_power_manageable(handle))
+		acpi_bus_set_power(handle, ACPI_STATE_D3);
+		/* continue even if acpi_bus_set_power() fails */
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+		ret = -ENODEV;
+	return ret;
 }
 
 #ifdef CONFIG_ACPI_SLEEP
diff -druNp linux-libre-2.6.29-gnu1/drivers/pnp/pnpbios/core.c linux-libre-2.6.30-gnu1/drivers/pnp/pnpbios/core.c
--- linux-libre-2.6.29-gnu1/drivers/pnp/pnpbios/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/pnp/pnpbios/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -94,7 +94,6 @@ struct pnp_dev_node_info node_info;
 
 #ifdef CONFIG_HOTPLUG
 
-static int unloading = 0;
 static struct completion unload_sem;
 
 /*
@@ -158,7 +157,7 @@ static int pnp_dock_thread(void *unused)
 	int docked = -1, d = 0;
 
 	set_freezable();
-	while (!unloading) {
+	while (1) {
 		int status;
 
 		/*
@@ -575,8 +574,6 @@ fs_initcall(pnpbios_init);
 
 static int __init pnpbios_thread_init(void)
 {
-	struct task_struct *task;
-
 #if defined(CONFIG_PPC)
 	if (check_legacy_ioport(PNPBIOS_BASE))
 		return 0;
@@ -584,10 +581,13 @@ static int __init pnpbios_thread_init(vo
 	if (pnpbios_disabled)
 		return 0;
 #ifdef CONFIG_HOTPLUG
-	init_completion(&unload_sem);
-	task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
-	if (!IS_ERR(task))
-		unloading = 0;
+	{
+		struct task_struct *task;
+		init_completion(&unload_sem);
+		task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+		if (IS_ERR(task))
+			return PTR_ERR(task);
+	}
 #endif
 	return 0;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/power/bq27x00_battery.c linux-libre-2.6.30-gnu1/drivers/power/bq27x00_battery.c
--- linux-libre-2.6.29-gnu1/drivers/power/bq27x00_battery.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/power/bq27x00_battery.c	2009-06-09 23:05:27.000000000 -0400
@@ -83,7 +83,7 @@ static int bq27x00_read(u8 reg, int *rt_
 }
 
 /*
- * Return the battery temperature in Celcius degrees
+ * Return the battery temperature in Celsius degrees
  * Or < 0 if something fails.
  */
 static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
diff -druNp linux-libre-2.6.29-gnu1/drivers/power/pcf50633-charger.c linux-libre-2.6.30-gnu1/drivers/power/pcf50633-charger.c
--- linux-libre-2.6.29-gnu1/drivers/power/pcf50633-charger.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/power/pcf50633-charger.c	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,8 @@ struct pcf50633_mbc {
 
 	struct power_supply usb;
 	struct power_supply adapter;
+
+	struct delayed_work charging_restart_work;
 };
 
 int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
@@ -43,6 +45,8 @@ int pcf50633_mbc_usb_curlim_set(struct p
 	struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
 	int ret = 0;
 	u8 bits;
+	int charging_start = 1;
+	u8 mbcs2, chgmod;
 
 	if (ma >= 1000)
 		bits = PCF50633_MBCC7_USB_1000mA;
@@ -50,8 +54,10 @@ int pcf50633_mbc_usb_curlim_set(struct p
 		bits = PCF50633_MBCC7_USB_500mA;
 	else if (ma >= 100)
 		bits = PCF50633_MBCC7_USB_100mA;
-	else
+	else {
 		bits = PCF50633_MBCC7_USB_SUSPEND;
+		charging_start = 0;
+	}
 
 	ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
 					PCF50633_MBCC7_USB_MASK, bits);
@@ -60,6 +66,22 @@ 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);
+	chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+	/* If chgmod == BATFULL, setting chgena has no effect.
+	 * We need to set resume instead.
+	 */
+	if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL)
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA);
+	else
+		pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1,
+				PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
+
+	mbc->usb_active = charging_start;
+
 	power_supply_changed(&mbc->usb);
 
 	return ret;
@@ -84,21 +106,6 @@ int pcf50633_mbc_get_status(struct pcf50
 }
 EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
 
-void pcf50633_mbc_set_status(struct pcf50633 *pcf, int what, int status)
-{
-	struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
-
-	if (what & PCF50633_MBC_USB_ONLINE)
-		mbc->usb_online = !!status;
-	if (what & PCF50633_MBC_USB_ACTIVE)
-		mbc->usb_active = !!status;
-	if (what & PCF50633_MBC_ADAPTER_ONLINE)
-		mbc->adapter_online = !!status;
-	if (what & PCF50633_MBC_ADAPTER_ACTIVE)
-		mbc->adapter_active = !!status;
-}
-EXPORT_SYMBOL_GPL(pcf50633_mbc_set_status);
-
 static ssize_t
 show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -160,10 +167,44 @@ 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) {
@@ -172,6 +213,7 @@ pcf50633_mbc_irq_handler(int irq, void *
 		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 */
@@ -186,7 +228,14 @@ pcf50633_mbc_irq_handler(int irq, void *
 	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->usb);
 	power_supply_changed(&mbc->adapter);
@@ -303,6 +352,9 @@ static int __devinit pcf50633_mbc_probe(
 		return ret;
 	}
 
+	INIT_DELAYED_WORK(&mbc->charging_restart_work,
+				pcf50633_mbc_charging_restart);
+
 	ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
 	if (ret)
 		dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
@@ -328,6 +380,8 @@ static int __devexit pcf50633_mbc_remove
 	power_supply_unregister(&mbc->usb);
 	power_supply_unregister(&mbc->adapter);
 
+	cancel_delayed_work_sync(&mbc->charging_restart_work);
+
 	kfree(mbc);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/power/pda_power.c linux-libre-2.6.30-gnu1/drivers/power/pda_power.c
--- linux-libre-2.6.29-gnu1/drivers/power/pda_power.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/power/pda_power.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,11 +12,14 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/power_supply.h>
 #include <linux/pda_power.h>
+#include <linux/regulator/consumer.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
+#include <linux/usb/otg.h>
 
 static inline unsigned int get_irq_flags(struct resource *res)
 {
@@ -35,6 +38,11 @@ static struct timer_list supply_timer;
 static struct timer_list polling_timer;
 static int polling;
 
+#ifdef CONFIG_USB_OTG_UTILS
+static struct otg_transceiver *transceiver;
+#endif
+static struct regulator *ac_draw;
+
 enum {
 	PDA_PSY_OFFLINE = 0,
 	PDA_PSY_ONLINE = 1,
@@ -104,18 +112,35 @@ static void update_status(void)
 
 static void update_charger(void)
 {
-	if (!pdata->set_charge)
-		return;
+	static int regulator_enabled;
+	int max_uA = pdata->ac_max_uA;
 
-	if (new_ac_status > 0) {
-		dev_dbg(dev, "charger on (AC)\n");
-		pdata->set_charge(PDA_POWER_CHARGE_AC);
-	} else if (new_usb_status > 0) {
-		dev_dbg(dev, "charger on (USB)\n");
-		pdata->set_charge(PDA_POWER_CHARGE_USB);
-	} else {
-		dev_dbg(dev, "charger off\n");
-		pdata->set_charge(0);
+	if (pdata->set_charge) {
+		if (new_ac_status > 0) {
+			dev_dbg(dev, "charger on (AC)\n");
+			pdata->set_charge(PDA_POWER_CHARGE_AC);
+		} else if (new_usb_status > 0) {
+			dev_dbg(dev, "charger on (USB)\n");
+			pdata->set_charge(PDA_POWER_CHARGE_USB);
+		} else {
+			dev_dbg(dev, "charger off\n");
+			pdata->set_charge(0);
+		}
+	} else if (ac_draw) {
+		if (new_ac_status > 0) {
+			regulator_set_current_limit(ac_draw, max_uA, max_uA);
+			if (!regulator_enabled) {
+				dev_dbg(dev, "charger on (AC)\n");
+				regulator_enable(ac_draw);
+				regulator_enabled = 1;
+			}
+		} else {
+			if (regulator_enabled) {
+				dev_dbg(dev, "charger off\n");
+				regulator_disable(ac_draw);
+				regulator_enabled = 0;
+			}
+		}
 	}
 }
 
@@ -194,6 +219,13 @@ static void polling_timer_func(unsigned
 		  jiffies + msecs_to_jiffies(pdata->polling_interval));
 }
 
+#ifdef CONFIG_USB_OTG_UTILS
+static int otg_is_usb_online(void)
+{
+	return (transceiver->state == OTG_STATE_B_PERIPHERAL);
+}
+#endif
+
 static int pda_power_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -227,6 +259,9 @@ static int pda_power_probe(struct platfo
 	if (!pdata->polling_interval)
 		pdata->polling_interval = 2000;
 
+	if (!pdata->ac_max_uA)
+		pdata->ac_max_uA = 500000;
+
 	setup_timer(&charger_timer, charger_timer_func, 0);
 	setup_timer(&supply_timer, supply_timer_func, 0);
 
@@ -240,6 +275,13 @@ static int pda_power_probe(struct platfo
 		pda_psy_usb.num_supplicants = pdata->num_supplicants;
 	}
 
+	ac_draw = regulator_get(dev, "ac_draw");
+	if (IS_ERR(ac_draw)) {
+		dev_dbg(dev, "couldn't get ac_draw regulator\n");
+		ac_draw = NULL;
+		ret = PTR_ERR(ac_draw);
+	}
+
 	if (pdata->is_ac_online) {
 		ret = power_supply_register(&pdev->dev, &pda_psy_ac);
 		if (ret) {
@@ -261,6 +303,13 @@ static int pda_power_probe(struct platfo
 		}
 	}
 
+#ifdef CONFIG_USB_OTG_UTILS
+	transceiver = otg_get_transceiver();
+	if (transceiver && !pdata->is_usb_online) {
+		pdata->is_usb_online = otg_is_usb_online;
+	}
+#endif
+
 	if (pdata->is_usb_online) {
 		ret = power_supply_register(&pdev->dev, &pda_psy_usb);
 		if (ret) {
@@ -300,10 +349,18 @@ usb_irq_failed:
 usb_supply_failed:
 	if (pdata->is_ac_online && ac_irq)
 		free_irq(ac_irq->start, &pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+	if (transceiver)
+		otg_put_transceiver(transceiver);
+#endif
 ac_irq_failed:
 	if (pdata->is_ac_online)
 		power_supply_unregister(&pda_psy_ac);
 ac_supply_failed:
+	if (ac_draw) {
+		regulator_put(ac_draw);
+		ac_draw = NULL;
+	}
 	if (pdata->exit)
 		pdata->exit(dev);
 init_failed:
@@ -327,6 +384,14 @@ static int pda_power_remove(struct platf
 		power_supply_unregister(&pda_psy_usb);
 	if (pdata->is_ac_online)
 		power_supply_unregister(&pda_psy_ac);
+#ifdef CONFIG_USB_OTG_UTILS
+	if (transceiver)
+		otg_put_transceiver(transceiver);
+#endif
+	if (ac_draw) {
+		regulator_put(ac_draw);
+		ac_draw = NULL;
+	}
 	if (pdata->exit)
 		pdata->exit(dev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/power/power_supply_sysfs.c linux-libre-2.6.30-gnu1/drivers/power/power_supply_sysfs.c
--- linux-libre-2.6.29-gnu1/drivers/power/power_supply_sysfs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/power/power_supply_sysfs.c	2009-06-09 23:05:27.000000000 -0400
@@ -93,6 +93,8 @@ static struct device_attribute power_sup
 	POWER_SUPPLY_ATTR(voltage_avg),
 	POWER_SUPPLY_ATTR(current_now),
 	POWER_SUPPLY_ATTR(current_avg),
+	POWER_SUPPLY_ATTR(power_now),
+	POWER_SUPPLY_ATTR(power_avg),
 	POWER_SUPPLY_ATTR(charge_full_design),
 	POWER_SUPPLY_ATTR(charge_empty_design),
 	POWER_SUPPLY_ATTR(charge_full),
diff -druNp linux-libre-2.6.29-gnu1/drivers/ps3/ps3av.c linux-libre-2.6.30-gnu1/drivers/ps3/ps3av.c
--- linux-libre-2.6.29-gnu1/drivers/ps3/ps3av.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/ps3/ps3av.c	2009-06-09 23:05:27.000000000 -0400
@@ -838,7 +838,7 @@ static int ps3av_get_hw_conf(struct ps3a
 }
 
 /* set mode using id */
-int ps3av_set_video_mode(u32 id)
+int ps3av_set_video_mode(int id)
 {
 	int size;
 	u32 option;
@@ -940,7 +940,7 @@ EXPORT_SYMBOL_GPL(ps3av_audio_mute);
 static int ps3av_probe(struct ps3_system_bus_device *dev)
 {
 	int res;
-	u32 id;
+	int id;
 
 	dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
 	dev_dbg(&dev->core, "  timeout=%d\n", timeout);
@@ -962,8 +962,10 @@ static int ps3av_probe(struct ps3_system
 	init_completion(&ps3av->done);
 	complete(&ps3av->done);
 	ps3av->wq = create_singlethread_workqueue("ps3avd");
-	if (!ps3av->wq)
+	if (!ps3av->wq) {
+		res = -ENOMEM;
 		goto fail;
+	}
 
 	switch (ps3_os_area_get_av_multi_out()) {
 	case PS3_PARAM_AV_MULTI_OUT_NTSC:
@@ -994,6 +996,12 @@ static int ps3av_probe(struct ps3_system
 		safe_mode = 1;
 #endif /* CONFIG_FB */
 	id = ps3av_auto_videomode(&ps3av->av_hw_conf);
+	if (id < 0) {
+		printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
+		res = -EINVAL;
+		goto fail;
+	}
+
 	safe_mode = 0;
 
 	mutex_lock(&ps3av->mutex);
@@ -1007,7 +1015,7 @@ static int ps3av_probe(struct ps3_system
 fail:
 	kfree(ps3av);
 	ps3av = NULL;
-	return -ENOMEM;
+	return res;
 }
 
 static int ps3av_remove(struct ps3_system_bus_device *dev)
diff -druNp linux-libre-2.6.29-gnu1/drivers/rapidio/rio-driver.c linux-libre-2.6.30-gnu1/drivers/rapidio/rio-driver.c
--- linux-libre-2.6.29-gnu1/drivers/rapidio/rio-driver.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rapidio/rio-driver.c	2009-06-09 23:05:27.000000000 -0400
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *
 }
 
 static struct device rio_bus = {
-	.bus_id = "rapidio",
+	.init_name = "rapidio",
 };
 
 struct bus_type rio_bus_type = {
diff -druNp linux-libre-2.6.29-gnu1/drivers/rapidio/rio-scan.c linux-libre-2.6.30-gnu1/drivers/rapidio/rio-scan.c
--- linux-libre-2.6.29-gnu1/drivers/rapidio/rio-scan.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rapidio/rio-scan.c	2009-06-09 23:05:27.000000000 -0400
@@ -381,9 +381,9 @@ static struct rio_dev *rio_setup_device(
 	rdev->dev.release = rio_release_dev;
 	rio_dev_get(rdev);
 
-	rdev->dma_mask = DMA_32BIT_MASK;
+	rdev->dma_mask = DMA_BIT_MASK(32);
 	rdev->dev.dma_mask = &rdev->dma_mask;
-	rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+	rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
 	    (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/bq24022.c linux-libre-2.6.30-gnu1/drivers/regulator/bq24022.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/bq24022.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/bq24022.c	2009-06-09 23:05:27.000000000 -0400
@@ -61,8 +61,7 @@ static int bq24022_disable(struct regula
 
 static int bq24022_is_enabled(struct regulator_dev *rdev)
 {
-	struct platform_device *pdev = rdev_get_drvdata(rdev);
-	struct bq24022_mach_info *pdata = pdev->dev.platform_data;
+	struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
 
 	return !gpio_get_value(pdata->gpio_nce);
 }
@@ -105,7 +104,8 @@ static int __init bq24022_probe(struct p
 	ret = gpio_direction_output(pdata->gpio_iset2, 0);
 	ret = gpio_direction_output(pdata->gpio_nce, 1);
 
-	bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata);
+	bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
+				     pdata->init_data, pdata);
 	if (IS_ERR(bq24022)) {
 		dev_dbg(&pdev->dev, "couldn't register regulator\n");
 		ret = PTR_ERR(bq24022);
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/core.c linux-libre-2.6.30-gnu1/drivers/regulator/core.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/core.c	2009-06-09 23:05:27.000000000 -0400
@@ -28,33 +28,7 @@
 static DEFINE_MUTEX(regulator_list_mutex);
 static LIST_HEAD(regulator_list);
 static LIST_HEAD(regulator_map_list);
-
-/*
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
-	struct regulator_desc *desc;
-	int use_count;
-
-	/* lists we belong to */
-	struct list_head list; /* list of all regulators */
-	struct list_head slist; /* list of supplied regulators */
-
-	/* lists we own */
-	struct list_head consumer_list; /* consumers we supply */
-	struct list_head supply_list; /* regulators we supply */
-
-	struct blocking_notifier_head notifier;
-	struct mutex mutex; /* consumer lock */
-	struct module *owner;
-	struct device dev;
-	struct regulation_constraints *constraints;
-	struct regulator_dev *supply;	/* for tree */
-
-	void *reg_data;		/* regulator_dev data */
-};
+static int has_full_constraints;
 
 /*
  * struct regulator_map
@@ -79,7 +53,6 @@ struct regulator {
 	int uA_load;
 	int min_uV;
 	int max_uV;
-	int enabled; /* count of client enables */
 	char *supply_name;
 	struct device_attribute dev_attr;
 	struct regulator_dev *rdev;
@@ -312,6 +285,47 @@ static ssize_t regulator_state_show(stru
 }
 static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
 
+static ssize_t regulator_status_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct regulator_dev *rdev = dev_get_drvdata(dev);
+	int status;
+	char *label;
+
+	status = rdev->desc->ops->get_status(rdev);
+	if (status < 0)
+		return status;
+
+	switch (status) {
+	case REGULATOR_STATUS_OFF:
+		label = "off";
+		break;
+	case REGULATOR_STATUS_ON:
+		label = "on";
+		break;
+	case REGULATOR_STATUS_ERROR:
+		label = "error";
+		break;
+	case REGULATOR_STATUS_FAST:
+		label = "fast";
+		break;
+	case REGULATOR_STATUS_NORMAL:
+		label = "normal";
+		break;
+	case REGULATOR_STATUS_IDLE:
+		label = "idle";
+		break;
+	case REGULATOR_STATUS_STANDBY:
+		label = "standby";
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	return sprintf(buf, "%s\n", label);
+}
+static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
+
 static ssize_t regulator_min_uA_show(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
@@ -526,8 +540,8 @@ static void drms_uA_update(struct regula
 
 	err = regulator_check_drms(rdev);
 	if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
-	    !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode);
-	return;
+	    !rdev->desc->ops->get_voltage || !rdev->desc->ops->set_mode)
+		return;
 
 	/* get output voltage */
 	output_uV = rdev->desc->ops->get_voltage(rdev);
@@ -678,6 +692,76 @@ static int set_machine_constraints(struc
 	else
 		name = "regulator";
 
+	/* constrain machine-level voltage specs to fit
+	 * the actual range supported by this regulator.
+	 */
+	if (ops->list_voltage && rdev->desc->n_voltages) {
+		int	count = rdev->desc->n_voltages;
+		int	i;
+		int	min_uV = INT_MAX;
+		int	max_uV = INT_MIN;
+		int	cmin = constraints->min_uV;
+		int	cmax = constraints->max_uV;
+
+		/* it's safe to autoconfigure fixed-voltage supplies
+		   and the constraints are used by list_voltage. */
+		if (count == 1 && !cmin) {
+			cmin = 1;
+			cmax = INT_MAX;
+			constraints->min_uV = cmin;
+			constraints->max_uV = cmax;
+		}
+
+		/* voltage constraints are optional */
+		if ((cmin == 0) && (cmax == 0))
+			goto out;
+
+		/* 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;
+		}
+
+		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
+		for (i = 0; i < count; i++) {
+			int	value;
+
+			value = ops->list_voltage(rdev, i);
+			if (value <= 0)
+				continue;
+
+			/* maybe adjust [min_uV..max_uV] */
+			if (value >= cmin && value < min_uV)
+				min_uV = value;
+			if (value <= cmax && value > max_uV)
+				max_uV = value;
+		}
+
+		/* final: [min_uV..max_uV] valid iff constraints valid */
+		if (max_uV < min_uV) {
+			pr_err("%s: %s '%s' voltage constraints\n",
+				       __func__, "unsupportable", name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* use regulator's subset of machine constraints */
+		if (constraints->min_uV < min_uV) {
+			pr_debug("%s: override '%s' %s, %d -> %d\n",
+				       __func__, name, "min_uV",
+					constraints->min_uV, min_uV);
+			constraints->min_uV = min_uV;
+		}
+		if (constraints->max_uV > max_uV) {
+			pr_debug("%s: override '%s' %s, %d -> %d\n",
+				       __func__, name, "max_uV",
+					constraints->max_uV, max_uV);
+			constraints->max_uV = max_uV;
+		}
+	}
+
 	rdev->constraints = constraints;
 
 	/* do we need to apply the constraint voltage */
@@ -695,10 +779,6 @@ static int set_machine_constraints(struc
 			}
 	}
 
-	/* are we enabled at boot time by firmware / bootloader */
-	if (rdev->constraints->boot_on)
-		rdev->use_count = 1;
-
 	/* do we need to setup our suspend state */
 	if (constraints->initial_state) {
 		ret = suspend_prepare(rdev, constraints->initial_state);
@@ -710,11 +790,27 @@ static int set_machine_constraints(struc
 		}
 	}
 
-	/* if always_on is set then turn the regulator on if it's not
-	 * already on. */
-	if (constraints->always_on && ops->enable &&
-	    ((ops->is_enabled && !ops->is_enabled(rdev)) ||
-	     (!ops->is_enabled && !constraints->boot_on))) {
+	if (constraints->initial_mode) {
+		if (!ops->set_mode) {
+			printk(KERN_ERR "%s: no set_mode operation for %s\n",
+			       __func__, name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ret = ops->set_mode(rdev, constraints->initial_mode);
+		if (ret < 0) {
+			printk(KERN_ERR
+			       "%s: failed to set initial mode for %s: %d\n",
+			       __func__, name, ret);
+			goto out;
+		}
+	}
+
+	/* If the constraints say the regulator should be on at this point
+	 * and we have control then make sure it is enabled.
+	 */
+	if ((constraints->always_on || constraints->boot_on) && ops->enable) {
 		ret = ops->enable(rdev);
 		if (ret < 0) {
 			printk(KERN_ERR "%s: failed to enable %s\n",
@@ -817,6 +913,19 @@ static void unset_consumer_device_supply
 	}
 }
 
+static void unset_regulator_supplies(struct regulator_dev *rdev)
+{
+	struct regulator_map *node, *n;
+
+	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
+		if (rdev == node->regulator) {
+			list_del(&node->list);
+			kfree(node);
+			return;
+		}
+	}
+}
+
 #define REG_STR_SIZE	32
 
 static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -898,9 +1007,12 @@ overflow_err:
  * @id: Supply name or regulator ID.
  *
  * Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno.  Use of supply names
- * configured via regulator_set_device_supply() is strongly
- * encouraged.
+ * or IS_ERR() condition containing errno.
+ *
+ * Use of supply names configured via regulator_set_device_supply() is
+ * strongly encouraged.  It is recommended that the supply name used
+ * should match the name used for the supply and/or the relevant
+ * device pins in the datasheet.
  */
 struct regulator *regulator_get(struct device *dev, const char *id)
 {
@@ -922,8 +1034,6 @@ struct regulator *regulator_get(struct d
 			goto found;
 		}
 	}
-	printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
-	       id);
 	mutex_unlock(&regulator_list_mutex);
 	return regulator;
 
@@ -961,10 +1071,6 @@ void regulator_put(struct regulator *reg
 	mutex_lock(&regulator_list_mutex);
 	rdev = regulator->rdev;
 
-	if (WARN(regulator->enabled, "Releasing supply %s while enabled\n",
-			       regulator->supply_name))
-		_regulator_disable(rdev);
-
 	/* remove any sysfs entries */
 	if (regulator->dev) {
 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
@@ -1039,12 +1145,7 @@ int regulator_enable(struct regulator *r
 	int ret = 0;
 
 	mutex_lock(&rdev->mutex);
-	if (regulator->enabled == 0)
-		ret = _regulator_enable(rdev);
-	else if (regulator->enabled < 0)
-		ret = -EIO;
-	if (ret == 0)
-		regulator->enabled++;
+	ret = _regulator_enable(rdev);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1055,6 +1156,11 @@ static int _regulator_disable(struct reg
 {
 	int ret = 0;
 
+	if (WARN(rdev->use_count <= 0,
+			"unbalanced disables for %s\n",
+			rdev->desc->name))
+		return -EIO;
+
 	/* are we the last user and permitted to disable ? */
 	if (rdev->use_count == 1 && !rdev->constraints->always_on) {
 
@@ -1103,16 +1209,7 @@ int regulator_disable(struct regulator *
 	int ret = 0;
 
 	mutex_lock(&rdev->mutex);
-	if (regulator->enabled == 1) {
-		ret = _regulator_disable(rdev);
-		if (ret == 0)
-			regulator->uA_load = 0;
-	} else if (WARN(regulator->enabled <= 0,
-			"unbalanced disables for supply %s\n",
-			regulator->supply_name))
-		ret = -EIO;
-	if (ret == 0)
-		regulator->enabled--;
+	ret = _regulator_disable(rdev);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1159,7 +1256,6 @@ int regulator_force_disable(struct regul
 	int ret;
 
 	mutex_lock(&regulator->rdev->mutex);
-	regulator->enabled = 0;
 	regulator->uA_load = 0;
 	ret = _regulator_force_disable(regulator->rdev);
 	mutex_unlock(&regulator->rdev->mutex);
@@ -1204,6 +1300,56 @@ int regulator_is_enabled(struct regulato
 EXPORT_SYMBOL_GPL(regulator_is_enabled);
 
 /**
+ * regulator_count_voltages - count regulator_list_voltage() selectors
+ * @regulator: regulator source
+ *
+ * Returns number of selectors, or negative errno.  Selectors are
+ * numbered starting at zero, and typically correspond to bitfields
+ * in hardware registers.
+ */
+int regulator_count_voltages(struct regulator *regulator)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+
+	return rdev->desc->n_voltages ? : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_count_voltages);
+
+/**
+ * regulator_list_voltage - enumerate supported voltages
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ * Context: can sleep
+ *
+ * Returns a voltage that can be passed to @regulator_set_voltage(),
+ * zero if this selector code can't be used on this sytem, or a
+ * negative errno.
+ */
+int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+	int			ret;
+
+	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	mutex_lock(&rdev->mutex);
+	ret = ops->list_voltage(rdev, selector);
+	mutex_unlock(&rdev->mutex);
+
+	if (ret > 0) {
+		if (ret < rdev->constraints->min_uV)
+			ret = 0;
+		else if (ret > rdev->constraints->max_uV)
+			ret = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage);
+
+/**
  * regulator_set_voltage - set regulator output voltage
  * @regulator: regulator source
  * @min_uV: Minimum required voltage in uV
@@ -1243,6 +1389,7 @@ int regulator_set_voltage(struct regulat
 	ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
 
 out:
+	_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1543,20 +1690,23 @@ int regulator_unregister_notifier(struct
 }
 EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
 
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
 static void _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data)
 {
 	struct regulator_dev *_rdev;
 
 	/* call rdev chain first */
-	mutex_lock(&rdev->mutex);
 	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
-	mutex_unlock(&rdev->mutex);
 
 	/* now notify regulator we supply */
-	list_for_each_entry(_rdev, &rdev->supply_list, slist)
-		_notifier_call_chain(_rdev, event, data);
+	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+	  mutex_lock(&_rdev->mutex);
+	  _notifier_call_chain(_rdev, event, data);
+	  mutex_unlock(&_rdev->mutex);
+	}
 }
 
 /**
@@ -1703,6 +1853,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
  *
  * Called by regulator drivers to notify clients a regulator event has
  * occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
  */
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data)
@@ -1744,6 +1895,11 @@ static int add_regulator_attributes(stru
 		if (status < 0)
 			return status;
 	}
+	if (ops->get_status) {
+		status = device_create_file(dev, &dev_attr_status);
+		if (status < 0)
+			return status;
+	}
 
 	/* some attributes are type-specific */
 	if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -1828,17 +1984,18 @@ static int add_regulator_attributes(stru
  * regulator_register - register regulator
  * @regulator_desc: regulator to register
  * @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
  * @driver_data: private regulator data
  *
  * Called by regulator drivers to register a regulator.
  * Returns 0 on success.
  */
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-	struct device *dev, void *driver_data)
+	struct device *dev, struct regulator_init_data *init_data,
+	void *driver_data)
 {
 	static atomic_t regulator_no = ATOMIC_INIT(0);
 	struct regulator_dev *rdev;
-	struct regulator_init_data *init_data = dev->platform_data;
 	int ret, i;
 
 	if (regulator_desc == NULL)
@@ -1847,8 +2004,8 @@ struct regulator_dev *regulator_register
 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
 		return ERR_PTR(-EINVAL);
 
-	if (!regulator_desc->type == REGULATOR_VOLTAGE &&
-	    !regulator_desc->type == REGULATOR_CURRENT)
+	if (regulator_desc->type != REGULATOR_VOLTAGE &&
+	    regulator_desc->type != REGULATOR_CURRENT)
 		return ERR_PTR(-EINVAL);
 
 	if (!init_data)
@@ -1926,6 +2083,10 @@ out:
 
 scrub:
 	device_unregister(&rdev->dev);
+	/* device core frees rdev */
+	rdev = ERR_PTR(ret);
+	goto out;
+
 clean:
 	kfree(rdev);
 	rdev = ERR_PTR(ret);
@@ -1945,6 +2106,7 @@ void regulator_unregister(struct regulat
 		return;
 
 	mutex_lock(&regulator_list_mutex);
+	unset_regulator_supplies(rdev);
 	list_del(&rdev->list);
 	if (rdev->supply)
 		sysfs_remove_link(&rdev->dev.kobj, "supply");
@@ -1989,6 +2151,23 @@ out:
 EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
 
 /**
+ * regulator_has_full_constraints - the system has fully specified constraints
+ *
+ * Calling this function will cause the regulator API to disable all
+ * regulators which have a zero use count and don't have an always_on
+ * constraint in a late_initcall.
+ *
+ * The intention is that this will become the default behaviour in a
+ * future kernel release so users are encouraged to use this facility
+ * now.
+ */
+void regulator_has_full_constraints(void)
+{
+	has_full_constraints = 1;
+}
+EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
+
+/**
  * rdev_get_drvdata - get rdev regulator driver data
  * @rdev: regulator
  *
@@ -2055,3 +2234,77 @@ static int __init regulator_init(void)
 
 /* init early to allow our consumers to complete system booting */
 core_initcall(regulator_init);
+
+static int __init regulator_init_complete(void)
+{
+	struct regulator_dev *rdev;
+	struct regulator_ops *ops;
+	struct regulation_constraints *c;
+	int enabled, ret;
+	const char *name;
+
+	mutex_lock(&regulator_list_mutex);
+
+	/* If we have a full configuration then disable any regulators
+	 * which are not in use or always_on.  This will become the
+	 * default behaviour in the future.
+	 */
+	list_for_each_entry(rdev, &regulator_list, list) {
+		ops = rdev->desc->ops;
+		c = rdev->constraints;
+
+		if (c->name)
+			name = c->name;
+		else if (rdev->desc->name)
+			name = rdev->desc->name;
+		else
+			name = "regulator";
+
+		if (!ops->disable || c->always_on)
+			continue;
+
+		mutex_lock(&rdev->mutex);
+
+		if (rdev->use_count)
+			goto unlock;
+
+		/* If we can't read the status assume it's on. */
+		if (ops->is_enabled)
+			enabled = ops->is_enabled(rdev);
+		else
+			enabled = 1;
+
+		if (!enabled)
+			goto unlock;
+
+		if (has_full_constraints) {
+			/* We log since this may kill the system if it
+			 * goes wrong. */
+			printk(KERN_INFO "%s: disabling %s\n",
+			       __func__, name);
+			ret = ops->disable(rdev);
+			if (ret != 0) {
+				printk(KERN_ERR
+				       "%s: couldn't disable %s: %d\n",
+				       __func__, name, ret);
+			}
+		} else {
+			/* The intention is that in future we will
+			 * assume that full constraints are provided
+			 * so warn even if we aren't going to do
+			 * anything here.
+			 */
+			printk(KERN_WARNING
+			       "%s: incomplete constraints, leaving %s on\n",
+			       __func__, name);
+		}
+
+unlock:
+		mutex_unlock(&rdev->mutex);
+	}
+
+	mutex_unlock(&regulator_list_mutex);
+
+	return 0;
+}
+late_initcall(regulator_init_complete);
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/da903x.c linux-libre-2.6.30-gnu1/drivers/regulator/da903x.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/da903x.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/da903x.c	2009-06-09 23:05:27.000000000 -0400
@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_pr
 	if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
 		ri->desc.ops = &da9030_regulator_ldo1_15_ops;
 
-	rdev = regulator_register(&ri->desc, &pdev->dev, ri);
+	rdev = regulator_register(&ri->desc, &pdev->dev,
+				  pdev->dev.platform_data, ri);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
@@ -496,7 +497,7 @@ static struct platform_driver da903x_reg
 		.owner	= THIS_MODULE,
 	},
 	.probe		= da903x_regulator_probe,
-	.remove		= da903x_regulator_remove,
+	.remove		= __devexit_p(da903x_regulator_remove),
 };
 
 static int __init da903x_regulator_init(void)
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/fixed.c linux-libre-2.6.30-gnu1/drivers/regulator/fixed.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/fixed.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/fixed.c	2009-06-09 23:05:27.000000000 -0400
@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe
 
 	drvdata->microvolts = config->microvolts;
 
-	drvdata->dev = regulator_register(&drvdata->desc, drvdata);
+	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+					  config->init_data, drvdata);
 	if (IS_ERR(drvdata->dev)) {
 		ret = PTR_ERR(drvdata->dev);
 		goto err_name;
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/Kconfig linux-libre-2.6.30-gnu1/drivers/regulator/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/regulator/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -29,8 +29,12 @@ config REGULATOR_DEBUG
 	  Say yes here to enable debugging support.
 
 config REGULATOR_FIXED_VOLTAGE
-	tristate
+	tristate "Fixed voltage regulator support"
 	default n
+	help
+	  This driver provides support for fixed voltage regulators,
+	  useful for systems which use a combination of software
+	  managed regulators and simple non-configurable regulators.
 
 config REGULATOR_VIRTUAL_CONSUMER
 	tristate "Virtual regulator consumer support"
@@ -52,6 +56,13 @@ config REGULATOR_BQ24022
 	  charging select between 100 mA and 500 mA charging current
 	  limit.
 
+config REGULATOR_TWL4030
+	bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+	depends on TWL4030_CORE
+	help
+	  This driver supports the voltage regulators provided by
+	  this family of companion chips.
+
 config REGULATOR_WM8350
 	tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
 	depends on MFD_WM8350
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/Makefile linux-libre-2.6.30-gnu1/drivers/regulator/Makefile
--- linux-libre-2.6.29-gnu1/drivers/regulator/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) +=
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/pcf50633-regulator.c linux-libre-2.6.30-gnu1/drivers/regulator/pcf50633-regulator.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/pcf50633-regulator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/pcf50633-regulator.c	2009-06-09 23:05:27.000000000 -0400
@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_
 	/* Already set by core driver */
 	pcf = platform_get_drvdata(pdev);
 
-	rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+				  pdev->dev.platform_data, pcf);
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/twl4030-regulator.c linux-libre-2.6.30-gnu1/drivers/regulator/twl4030-regulator.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/twl4030-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/regulator/twl4030-regulator.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,500 @@
+/*
+ * 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.29-gnu1/drivers/regulator/virtual.c linux-libre-2.6.30-gnu1/drivers/regulator/virtual.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/virtual.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/virtual.c	2009-06-09 23:05:27.000000000 -0400
@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *d
 	unsigned int mode;
 	int ret;
 
-	if (strncmp(buf, "fast", strlen("fast")) == 0)
+	/*
+	 * sysfs_streq() doesn't need the \n's, but we add them so the strings
+	 * will be shared with show_mode(), above.
+	 */
+	if (sysfs_streq(buf, "fast\n"))
 		mode = REGULATOR_MODE_FAST;
-	else if (strncmp(buf, "normal", strlen("normal")) == 0)
+	else if (sysfs_streq(buf, "normal\n"))
 		mode = REGULATOR_MODE_NORMAL;
-	else if (strncmp(buf, "idle", strlen("idle")) == 0)
+	else if (sysfs_streq(buf, "idle\n"))
 		mode = REGULATOR_MODE_IDLE;
-	else if (strncmp(buf, "standby", strlen("standby")) == 0)
+	else if (sysfs_streq(buf, "standby\n"))
 		mode = REGULATOR_MODE_STANDBY;
 	else {
 		dev_err(dev, "Configuring invalid mode\n");
@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666,
 static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
 static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
 
-struct device_attribute *attributes[] = {
+static struct device_attribute *attributes[] = {
 	&dev_attr_min_microvolts,
 	&dev_attr_max_microvolts,
 	&dev_attr_min_microamps,
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/wm8350-regulator.c linux-libre-2.6.30-gnu1/drivers/regulator/wm8350-regulator.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/wm8350-regulator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/wm8350-regulator.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,6 +24,9 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+/* Maximum value possible for VSEL */
+#define WM8350_DCDC_MAX_VSEL 0x66
+
 /* Microamps */
 static const int isink_cur[] = {
 	4,
@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struc
 	return wm8350_dcdc_val_to_mvolts(val) * 1000;
 }
 
+static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
+				    unsigned selector)
+{
+	if (selector > WM8350_DCDC_MAX_VSEL)
+		return -EINVAL;
+	return wm8350_dcdc_val_to_mvolts(selector) * 1000;
+}
+
 static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 {
 	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct
 	return wm8350_ldo_val_to_mvolts(val) * 1000;
 }
 
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+				    unsigned selector)
+{
+	if (selector > WM8350_LDO1_VSEL_MASK)
+		return -EINVAL;
+	return wm8350_ldo_val_to_mvolts(selector) * 1000;
+}
+
 int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
 			 u16 stop, u16 fault)
 {
@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode
 	int dcdc = rdev_get_id(rdev);
 	u16 mask, sleep, active, force;
 	int mode = REGULATOR_MODE_NORMAL;
+	int reg;
 
-	if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
-		return -EINVAL;
-
-	if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
+	switch (dcdc) {
+	case WM8350_DCDC_1:
+		reg = WM8350_DCDC1_FORCE_PWM;
+		break;
+	case WM8350_DCDC_3:
+		reg = WM8350_DCDC3_FORCE_PWM;
+		break;
+	case WM8350_DCDC_4:
+		reg = WM8350_DCDC4_FORCE_PWM;
+		break;
+	case WM8350_DCDC_6:
+		reg = WM8350_DCDC6_FORCE_PWM;
+		break;
+	default:
 		return -EINVAL;
+	}
 
 	mask = 1 << (dcdc - WM8350_DCDC_1);
 	active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
+	force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
 	sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
-	force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
-	    & WM8350_DCDC1_FORCE_PWM_ENA;
+
 	dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
 		mask, active, sleep, force);
 
@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct
 static struct regulator_ops wm8350_dcdc_ops = {
 	.set_voltage = wm8350_dcdc_set_voltage,
 	.get_voltage = wm8350_dcdc_get_voltage,
+	.list_voltage = wm8350_dcdc_list_voltage,
 	.enable = wm8350_dcdc_enable,
 	.disable = wm8350_dcdc_disable,
 	.get_mode = wm8350_dcdc_get_mode,
@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2
 static struct regulator_ops wm8350_ldo_ops = {
 	.set_voltage = wm8350_ldo_set_voltage,
 	.get_voltage = wm8350_ldo_get_voltage,
+	.list_voltage = wm8350_ldo_list_voltage,
 	.enable = wm8350_ldo_enable,
 	.disable = wm8350_ldo_disable,
 	.is_enabled = wm8350_ldo_is_enabled,
@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC1,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC3,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC4,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC6,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO1,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO1_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO2,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO2_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO3,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO3_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO4,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO4_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm835
 {
 	struct regulator_dev *rdev = (struct regulator_dev *)data;
 
+	mutex_lock(&rdev->mutex);
 	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
 		regulator_notifier_call_chain(rdev,
 					      REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm835
 		regulator_notifier_call_chain(rdev,
 					      REGULATOR_EVENT_UNDER_VOLTAGE,
 					      wm8350);
+	mutex_unlock(&rdev->mutex);
 }
 
 static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct
 		break;
 	}
 
-
 	/* register regulator */
 	rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
+				  pdev->dev.platform_data,
 				  dev_get_drvdata(&pdev->dev));
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register %s\n",
diff -druNp linux-libre-2.6.29-gnu1/drivers/regulator/wm8400-regulator.c linux-libre-2.6.30-gnu1/drivers/regulator/wm8400-regulator.c
--- linux-libre-2.6.29-gnu1/drivers/regulator/wm8400-regulator.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/regulator/wm8400-regulator.c	2009-06-09 23:05:27.000000000 -0400
@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct reg
 			       WM8400_LDO1_ENA, 0);
 }
 
+static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
+				   unsigned selector)
+{
+	if (selector > WM8400_LDO1_VSEL_MASK)
+		return -EINVAL;
+
+	if (selector < 15)
+		return 900000 + (selector * 50000);
+	else
+		return 1600000 + ((selector - 14) * 100000);
+}
+
 static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct
 	val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
 	val &= WM8400_LDO1_VSEL_MASK;
 
-	if (val < 15)
-		return 900000 + (val * 50000);
-	else
-		return 1600000 + ((val - 14) * 100000);
+	return wm8400_ldo_list_voltage(dev, val);
 }
 
 static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_o
 	.is_enabled = wm8400_ldo_is_enabled,
 	.enable = wm8400_ldo_enable,
 	.disable = wm8400_ldo_disable,
+	.list_voltage = wm8400_ldo_list_voltage,
 	.get_voltage = wm8400_ldo_get_voltage,
 	.set_voltage = wm8400_ldo_set_voltage,
 };
@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct re
 			       WM8400_DC1_ENA, 0);
 }
 
+static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
+				    unsigned selector)
+{
+	if (selector > WM8400_DC1_VSEL_MASK)
+		return -EINVAL;
+
+	return 850000 + (selector * 25000);
+}
+
 static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_
 	.is_enabled = wm8400_dcdc_is_enabled,
 	.enable = wm8400_dcdc_enable,
 	.disable = wm8400_dcdc_disable,
+	.list_voltage = wm8400_dcdc_list_voltage,
 	.get_voltage = wm8400_dcdc_get_voltage,
 	.set_voltage = wm8400_dcdc_set_voltage,
 	.get_mode = wm8400_dcdc_get_mode,
@@ -249,6 +269,7 @@ static struct regulator_desc regulators[
 		.name = "LDO1",
 		.id = WM8400_LDO1,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO1_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -256,6 +277,7 @@ static struct regulator_desc regulators[
 		.name = "LDO2",
 		.id = WM8400_LDO2,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO2_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -263,6 +285,7 @@ static struct regulator_desc regulators[
 		.name = "LDO3",
 		.id = WM8400_LDO3,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO3_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -270,6 +293,7 @@ static struct regulator_desc regulators[
 		.name = "LDO4",
 		.id = WM8400_LDO4,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO4_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -277,6 +301,7 @@ static struct regulator_desc regulators[
 		.name = "DCDC1",
 		.id = WM8400_DCDC1,
 		.ops = &wm8400_dcdc_ops,
+		.n_voltages = WM8400_DC1_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -284,6 +309,7 @@ static struct regulator_desc regulators[
 		.name = "DCDC2",
 		.id = WM8400_DCDC2,
 		.ops = &wm8400_dcdc_ops,
+		.n_voltages = WM8400_DC2_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_pr
 	struct regulator_dev *rdev;
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-		pdev->dev.driver_data);
+		pdev->dev.platform_data, pdev->dev.driver_data);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/Kconfig linux-libre-2.6.30-gnu1/drivers/rtc/Kconfig
--- linux-libre-2.6.29-gnu1/drivers/rtc/Kconfig	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/Kconfig	2009-06-09 23:05:27.000000000 -0400
@@ -129,13 +129,14 @@ comment "I2C RTC drivers"
 if I2C
 
 config RTC_DRV_DS1307
-	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
+	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
 	help
 	  If you say yes here you get support for various compatible RTC
 	  chips (often with battery backup) connected with I2C. This driver
 	  should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
-	  and probably other chips. In some cases the RTC must already
-	  have been initialized (by manufacturing or a bootloader).
+	  EPSON RX-8025 and probably other chips. In some cases the RTC
+	  must already have been initialized (by manufacturing or a
+	  bootloader).
 
 	  The first seven registers on these chips hold an RTC, and other
 	  registers may add features such as NVRAM, a trickle charger for
@@ -224,11 +225,11 @@ config RTC_DRV_PCF8583
 	  will be called rtc-pcf8583.
 
 config RTC_DRV_M41T80
-	tristate "ST M41T65/M41T80/81/82/83/84/85/87"
+	tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
 	help
 	  If you say Y here you will get support for the ST M41T60
 	  and M41T80 RTC chips series. Currently, the following chips are
-	  supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
+	  supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
 	  M41ST85, and M41ST87.
 
 	  This driver can also be built as a module. If so, the module
@@ -440,6 +441,16 @@ config RTC_DRV_DS1742
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-ds1742.
 
+config RTC_DRV_EFI
+	tristate "EFI RTC"
+	depends on IA64
+	help
+	  If you say yes here you will get support for the EFI
+	  Real Time Clock.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-efi.
+
 config RTC_DRV_STK17TA8
 	tristate "Simtek STK17TA8"
 	depends on RTC_CLASS
@@ -562,7 +573,7 @@ config RTC_DRV_SA1100
 
 config RTC_DRV_SH
 	tristate "SuperH On-Chip RTC"
-	depends on RTC_CLASS && SUPERH
+	depends on RTC_CLASS && SUPERH && HAVE_CLK
 	help
 	  Say Y here to enable support for the on-chip RTC found in
 	  most SuperH processors.
@@ -677,22 +688,16 @@ config RTC_DRV_RS5C313
 	help
 	  If you say yes here you get support for the Ricoh RS5C313 RTC chips.
 
-config RTC_DRV_PARISC
-	tristate "PA-RISC firmware RTC support"
-	depends on PARISC
+config RTC_DRV_GENERIC
+	tristate "Generic RTC support"
+	# Please consider writing a new RTC driver instead of using the generic
+	# RTC abstraction
+	depends on PARISC || M68K || PPC
 	help
-	  Say Y or M here to enable RTC support on PA-RISC systems using
-	  firmware calls. If you do not know what you are doing, you should
+	  Say Y or M here to enable RTC support on systems using the generic
+	  RTC abstraction. If you do not know what you are doing, you should
 	  just say Y.
 
-config RTC_DRV_PPC
-       tristate "PowerPC machine dependent RTC support"
-       depends on PPC
-       help
-	 The PowerPC kernel has machine-specific functions for accessing
-	 the RTC. This exposes that functionality through the generic RTC
-	 class.
-
 config RTC_DRV_PXA
        tristate "PXA27x/PXA3xx"
        depends on ARCH_PXA
@@ -736,4 +741,13 @@ config RTC_DRV_MV
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-mv.
 
+config RTC_DRV_PS3
+	tristate "PS3 RTC"
+	depends on PPC_PS3
+	help
+	  If you say yes here you will get support for the RTC on PS3.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ps3.
+
 endif # RTC_CLASS
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/Makefile linux-libre-2.6.30-gnu1/drivers/rtc/Makefile
--- linux-libre-2.6.29-gnu1/drivers/rtc/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -36,6 +36,7 @@ obj-$(CONFIG_RTC_DRV_DS1553)	+= rtc-ds15
 obj-$(CONFIG_RTC_DRV_DS1672)	+= rtc-ds1672.o
 obj-$(CONFIG_RTC_DRV_DS1742)	+= rtc-ds1742.o
 obj-$(CONFIG_RTC_DRV_DS3234)	+= rtc-ds3234.o
+obj-$(CONFIG_RTC_DRV_EFI)	+= rtc-efi.o
 obj-$(CONFIG_RTC_DRV_EP93XX)	+= rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)	+= rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
@@ -55,8 +56,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563)	+= rtc-pcf
 obj-$(CONFIG_RTC_DRV_PCF8583)	+= rtc-pcf8583.o
 obj-$(CONFIG_RTC_DRV_PL030)	+= rtc-pl030.o
 obj-$(CONFIG_RTC_DRV_PL031)	+= rtc-pl031.o
-obj-$(CONFIG_RTC_DRV_PARISC)	+= rtc-parisc.o
-obj-$(CONFIG_RTC_DRV_PPC)	+= rtc-ppc.o
+obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
 obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
@@ -76,3 +76,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
+obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-at91sam9.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-at91sam9.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-at91sam9.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-at91sam9.c	2009-06-09 23:05:27.000000000 -0400
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct
 	/* register irq handler after we know what name we'll use */
 	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
 				IRQF_DISABLED | IRQF_SHARED,
-				rtc->rtcdev->dev.bus_id, rtc);
+				dev_name(&rtc->rtcdev->dev), rtc);
 	if (ret) {
 		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
 		rtc_device_unregister(rtc->rtcdev);
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct
 
 	if (gpbr_readl(rtc) == 0)
 		dev_warn(&pdev->dev, "%s: SET TIME!\n",
-				rtc->rtcdev->dev.bus_id);
+				dev_name(&rtc->rtcdev->dev));
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-cmos.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-cmos.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-cmos.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-cmos.c	2009-06-09 23:05:27.000000000 -0400
@@ -797,17 +797,15 @@ cmos_do_probe(struct device *dev, struct
 		goto cleanup2;
 	}
 
-	pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n",
-			dev_name(&cmos_rtc.rtc->dev),
-			is_valid_irq(rtc_irq)
-				?  (cmos_rtc.mon_alrm
-					? "year"
-					: (cmos_rtc.day_alrm
-						? "month" : "day"))
-				: "no",
-			cmos_rtc.century ? ", y3k" : "",
-			nvram.size,
-			is_hpet_enabled() ? ", hpet irqs" : "");
+	pr_info("%s: %s%s, %zd bytes nvram%s\n",
+		dev_name(&cmos_rtc.rtc->dev),
+		!is_valid_irq(rtc_irq) ? "no alarms" :
+			cmos_rtc.mon_alrm ? "alarms up to one year" :
+			cmos_rtc.day_alrm ? "alarms up to one month" :
+			"alarms up to one day",
+		cmos_rtc.century ? ", y3k" : "",
+		nvram.size,
+		is_hpet_enabled() ? ", hpet irqs" : "");
 
 	return 0;
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ds1307.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ds1307.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ds1307.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ds1307.c	2009-06-09 23:05:27.000000000 -0400
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2005 James Chapman (ds1337 core)
  *  Copyright (C) 2006 David Brownell
+ *  Copyright (C) 2009 Matthias Fuchs (rx8025 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
@@ -31,6 +32,7 @@ enum ds_type {
 	ds_1339,
 	ds_1340,
 	m41t00,
+	rx_8025,
 	// rs5c372 too?  different address...
 };
 
@@ -83,6 +85,12 @@ enum ds_type {
 #define DS1339_REG_ALARM1_SECS	0x07
 #define DS1339_REG_TRICKLE	0x10
 
+#define RX8025_REG_CTRL1	0x0e
+#	define RX8025_BIT_2412		0x20
+#define RX8025_REG_CTRL2	0x0f
+#	define RX8025_BIT_PON		0x10
+#	define RX8025_BIT_VDET		0x40
+#	define RX8025_BIT_XST		0x20
 
 
 struct ds1307 {
@@ -94,6 +102,10 @@ struct ds1307 {
 	struct i2c_client	*client;
 	struct rtc_device	*rtc;
 	struct work_struct	work;
+	s32 (*read_block_data)(struct i2c_client *client, u8 command,
+			       u8 length, u8 *values);
+	s32 (*write_block_data)(struct i2c_client *client, u8 command,
+				u8 length, const u8 *values);
 };
 
 struct chip_desc {
@@ -117,6 +129,8 @@ static const struct chip_desc chips[] =
 [ds_1340] = {
 },
 [m41t00] = {
+},
+[rx_8025] = {
 }, };
 
 static const struct i2c_device_id ds1307_id[] = {
@@ -126,12 +140,86 @@ static const struct i2c_device_id ds1307
 	{ "ds1339", ds_1339 },
 	{ "ds1340", ds_1340 },
 	{ "m41t00", m41t00 },
+	{ "rx8025", rx_8025 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
 /*----------------------------------------------------------------------*/
 
+#define BLOCK_DATA_MAX_TRIES 10
+
+static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command,
+				  u8 length, u8 *values)
+{
+	s32 i, data;
+
+	for (i = 0; i < length; i++) {
+		data = i2c_smbus_read_byte_data(client, command + i);
+		if (data < 0)
+			return data;
+		values[i] = data;
+	}
+	return i;
+}
+
+static s32 ds1307_read_block_data(struct i2c_client *client, u8 command,
+				  u8 length, u8 *values)
+{
+	u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
+	s32 ret;
+	int tries = 0;
+
+	dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length);
+	ret = ds1307_read_block_data_once(client, command, length, values);
+	if (ret < 0)
+		return ret;
+	do {
+		if (++tries > BLOCK_DATA_MAX_TRIES) {
+			dev_err(&client->dev,
+				"ds1307_read_block_data failed\n");
+			return -EIO;
+		}
+		memcpy(oldvalues, values, length);
+		ret = ds1307_read_block_data_once(client, command, length,
+						  values);
+		if (ret < 0)
+			return ret;
+	} while (memcmp(oldvalues, values, length));
+	return length;
+}
+
+static s32 ds1307_write_block_data(struct i2c_client *client, u8 command,
+				   u8 length, const u8 *values)
+{
+	u8 currvalues[I2C_SMBUS_BLOCK_MAX];
+	int tries = 0;
+
+	dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
+	do {
+		s32 i, ret;
+
+		if (++tries > BLOCK_DATA_MAX_TRIES) {
+			dev_err(&client->dev,
+				"ds1307_write_block_data failed\n");
+			return -EIO;
+		}
+		for (i = 0; i < length; i++) {
+			ret = i2c_smbus_write_byte_data(client, command + i,
+							values[i]);
+			if (ret < 0)
+				return ret;
+		}
+		ret = ds1307_read_block_data_once(client, command, length,
+						  currvalues);
+		if (ret < 0)
+			return ret;
+	} while (memcmp(currvalues, values, length));
+	return length;
+}
+
+/*----------------------------------------------------------------------*/
+
 /*
  * The IRQ logic includes a "real" handler running in IRQ context just
  * long enough to schedule this workqueue entry.   We need a task context
@@ -202,7 +290,7 @@ static int ds1307_get_time(struct device
 	int		tmp;
 
 	/* read the RTC date and time registers all at once */
-	tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+	tmp = ds1307->read_block_data(ds1307->client,
 		DS1307_REG_SECS, 7, ds1307->regs);
 	if (tmp != 7) {
 		dev_err(dev, "%s error %d\n", "read", tmp);
@@ -279,7 +367,7 @@ static int ds1307_set_time(struct device
 		"write", buf[0], buf[1], buf[2], buf[3],
 		buf[4], buf[5], buf[6]);
 
-	result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf);
+	result = ds1307->write_block_data(ds1307->client, 0, 7, buf);
 	if (result < 0) {
 		dev_err(dev, "%s error %d\n", "write", result);
 		return result;
@@ -297,7 +385,7 @@ static int ds1337_read_alarm(struct devi
 		return -EINVAL;
 
 	/* read all ALARM1, ALARM2, and status registers at once */
-	ret = i2c_smbus_read_i2c_block_data(client,
+	ret = ds1307->read_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
 	if (ret != 9) {
 		dev_err(dev, "%s error %d\n", "alarm read", ret);
@@ -356,7 +444,7 @@ static int ds1337_set_alarm(struct devic
 		t->enabled, t->pending);
 
 	/* read current status of both alarms and the chip */
-	ret = i2c_smbus_read_i2c_block_data(client,
+	ret = ds1307->read_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, buf);
 	if (ret != 9) {
 		dev_err(dev, "%s error %d\n", "alarm write", ret);
@@ -391,7 +479,7 @@ static int ds1337_set_alarm(struct devic
 	}
 	buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
 
-	ret = i2c_smbus_write_i2c_block_data(client,
+	ret = ds1307->write_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, buf);
 	if (ret < 0) {
 		dev_err(dev, "can't set alarm time\n");
@@ -479,7 +567,7 @@ ds1307_nvram_read(struct kobject *kobj,
 	if (unlikely(!count))
 		return count;
 
-	result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf);
+	result = ds1307->read_block_data(client, 8 + off, count, buf);
 	if (result < 0)
 		dev_err(&client->dev, "%s error %d\n", "nvram read", result);
 	return result;
@@ -490,9 +578,11 @@ ds1307_nvram_write(struct kobject *kobj,
 		char *buf, loff_t off, size_t count)
 {
 	struct i2c_client	*client;
+	struct ds1307		*ds1307;
 	int			result;
 
 	client = kobj_to_i2c_client(kobj);
+	ds1307 = i2c_get_clientdata(client);
 
 	if (unlikely(off >= NVRAM_SIZE))
 		return -EFBIG;
@@ -501,7 +591,7 @@ ds1307_nvram_write(struct kobject *kobj,
 	if (unlikely(!count))
 		return count;
 
-	result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf);
+	result = ds1307->write_block_data(client, 8 + off, count, buf);
 	if (result < 0) {
 		dev_err(&client->dev, "%s error %d\n", "nvram write", result);
 		return result;
@@ -535,9 +625,8 @@ static int __devinit ds1307_probe(struct
 	int			want_irq = false;
 	unsigned char		*buf;
 
-	if (!i2c_check_functionality(adapter,
-			I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
-			I2C_FUNC_SMBUS_I2C_BLOCK))
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
+	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -EIO;
 
 	if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -547,6 +636,13 @@ static int __devinit ds1307_probe(struct
 	i2c_set_clientdata(client, ds1307);
 	ds1307->type = id->driver_data;
 	buf = ds1307->regs;
+	if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+		ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
+		ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
+	} else {
+		ds1307->read_block_data = ds1307_read_block_data;
+		ds1307->write_block_data = ds1307_write_block_data;
+	}
 
 	switch (ds1307->type) {
 	case ds_1337:
@@ -557,7 +653,7 @@ static int __devinit ds1307_probe(struct
 			want_irq = true;
 		}
 		/* get registers that the "rtc" read below won't read... */
-		tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+		tmp = ds1307->read_block_data(ds1307->client,
 				DS1337_REG_CONTROL, 2, buf);
 		if (tmp != 2) {
 			pr_debug("read error %d\n", tmp);
@@ -589,13 +685,79 @@ static int __devinit ds1307_probe(struct
 			dev_warn(&client->dev, "SET TIME!\n");
 		}
 		break;
+
+	case rx_8025:
+		tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+				RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+		if (tmp != 2) {
+			pr_debug("read error %d\n", tmp);
+			err = -EIO;
+			goto exit_free;
+		}
+
+		/* oscillator off?  turn it on, so clock can tick. */
+		if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
+			ds1307->regs[1] |= RX8025_BIT_XST;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev,
+				 "oscillator stop detected - SET TIME!\n");
+		}
+
+		if (ds1307->regs[1] & RX8025_BIT_PON) {
+			ds1307->regs[1] &= ~RX8025_BIT_PON;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev, "power-on detected\n");
+		}
+
+		if (ds1307->regs[1] & RX8025_BIT_VDET) {
+			ds1307->regs[1] &= ~RX8025_BIT_VDET;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev, "voltage drop detected\n");
+		}
+
+		/* make sure we are running in 24hour mode */
+		if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+			u8 hour;
+
+			/* switch to 24 hour mode */
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL1 << 4 | 0x08,
+						  ds1307->regs[0] |
+						  RX8025_BIT_2412);
+
+			tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+					RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+			if (tmp != 2) {
+				pr_debug("read error %d\n", tmp);
+				err = -EIO;
+				goto exit_free;
+			}
+
+			/* correct hour */
+			hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+			if (hour == 12)
+				hour = 0;
+			if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+				hour += 12;
+
+			i2c_smbus_write_byte_data(client,
+						  DS1307_REG_HOUR << 4 | 0x08,
+						  hour);
+		}
+		break;
 	default:
 		break;
 	}
 
 read_rtc:
 	/* read RTC registers */
-	tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf);
+	tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
 	if (tmp != 8) {
 		pr_debug("read error %d\n", tmp);
 		err = -EIO;
@@ -649,6 +811,7 @@ read_rtc:
 			dev_warn(&client->dev, "SET TIME!\n");
 		}
 		break;
+	case rx_8025:
 	case ds_1337:
 	case ds_1339:
 		break;
@@ -662,6 +825,8 @@ read_rtc:
 		 * systems that will run through year 2100.
 		 */
 		break;
+	case rx_8025:
+		break;
 	default:
 		if (!(tmp & DS1307_BIT_12HR))
 			break;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ds1374.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ds1374.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ds1374.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ds1374.c	2009-06-09 23:05:27.000000000 -0400
@@ -222,16 +222,16 @@ static int ds1374_set_alarm(struct devic
 	rtc_tm_to_time(&alarm->time, &new_alarm);
 	rtc_tm_to_time(&now, &itime);
 
-	new_alarm -= itime;
-
 	/* This can happen due to races, in addition to dates that are
 	 * truly in the past.  To avoid requiring the caller to check for
 	 * races, dates in the past are assumed to be in the recent past
 	 * (i.e. not something that we'd rather the caller know about via
 	 * an error), and the alarm is set to go off as soon as possible.
 	 */
-	if (new_alarm <= 0)
+	if (time_before_eq(new_alarm, itime))
 		new_alarm = 1;
+	else
+		new_alarm -= itime;
 
 	mutex_lock(&ds1374->mutex);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-efi.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-efi.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-efi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-efi.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * rtc-efi: RTC Class Driver for EFI-based systems
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * Author: dann frazier <dannf@hp.com>
+ * Based on efirtc.c by Stephane Eranian
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the 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/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/efi.h>
+
+#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
+/*
+ * EFI Epoch is 1/1/1998
+ */
+#define EFI_RTC_EPOCH		1998
+
+/*
+ * returns day of the year [0-365]
+ */
+static inline int
+compute_yday(efi_time_t *eft)
+{
+	/* efi_time_t.month is in the [1-12] so, we need -1 */
+	return rtc_year_days(eft->day - 1, eft->month - 1, eft->year);
+}
+/*
+ * returns day of the week [0-6] 0=Sunday
+ *
+ * Don't try to provide a year that's before 1998, please !
+ */
+static int
+compute_wday(efi_time_t *eft)
+{
+	int y;
+	int ndays = 0;
+
+	if (eft->year < 1998) {
+		printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n");
+		return -1;
+	}
+
+	for (y = EFI_RTC_EPOCH; y < eft->year; y++)
+		ndays += 365 + (is_leap_year(y) ? 1 : 0);
+
+	ndays += compute_yday(eft);
+
+	/*
+	 * 4=1/1/1998 was a Thursday
+	 */
+	return (ndays + 4) % 7;
+}
+
+static void
+convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft)
+{
+	eft->year	= wtime->tm_year + 1900;
+	eft->month	= wtime->tm_mon + 1;
+	eft->day	= wtime->tm_mday;
+	eft->hour	= wtime->tm_hour;
+	eft->minute	= wtime->tm_min;
+	eft->second 	= wtime->tm_sec;
+	eft->nanosecond = 0;
+	eft->daylight	= wtime->tm_isdst ? EFI_ISDST : 0;
+	eft->timezone	= EFI_UNSPECIFIED_TIMEZONE;
+}
+
+static void
+convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
+{
+	memset(wtime, 0, sizeof(*wtime));
+	wtime->tm_sec  = eft->second;
+	wtime->tm_min  = eft->minute;
+	wtime->tm_hour = eft->hour;
+	wtime->tm_mday = eft->day;
+	wtime->tm_mon  = eft->month - 1;
+	wtime->tm_year = eft->year - 1900;
+
+	/* day of the week [0-6], Sunday=0 */
+	wtime->tm_wday = compute_wday(eft);
+
+	/* day in the year [1-365]*/
+	wtime->tm_yday = compute_yday(eft);
+
+
+	switch (eft->daylight & EFI_ISDST) {
+	case EFI_ISDST:
+		wtime->tm_isdst = 1;
+		break;
+	case EFI_TIME_ADJUST_DAYLIGHT:
+		wtime->tm_isdst = 0;
+		break;
+	default:
+		wtime->tm_isdst = -1;
+	}
+}
+
+static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	efi_time_t eft;
+	efi_status_t status;
+
+	/*
+	 * As of EFI v1.10, this call always returns an unsupported status
+	 */
+	status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled,
+				     (efi_bool_t *)&wkalrm->pending, &eft);
+
+	if (status != EFI_SUCCESS)
+		return -EINVAL;
+
+	convert_from_efi_time(&eft, &wkalrm->time);
+
+	return rtc_valid_tm(&wkalrm->time);
+}
+
+static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	efi_time_t eft;
+	efi_status_t status;
+
+	convert_to_efi_time(&wkalrm->time, &eft);
+
+	/*
+	 * XXX Fixme:
+	 * As of EFI 0.92 with the firmware I have on my
+	 * machine this call does not seem to work quite
+	 * right
+	 *
+	 * As of v1.10, this call always returns an unsupported status
+	 */
+	status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft);
+
+	printk(KERN_WARNING "write status is %d\n", (int)status);
+
+	return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static int efi_read_time(struct device *dev, struct rtc_time *tm)
+{
+	efi_status_t status;
+	efi_time_t eft;
+	efi_time_cap_t cap;
+
+	status = efi.get_time(&eft, &cap);
+
+	if (status != EFI_SUCCESS) {
+		/* should never happen */
+		printk(KERN_ERR "efitime: can't read time\n");
+		return -EINVAL;
+	}
+
+	convert_from_efi_time(&eft, tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int efi_set_time(struct device *dev, struct rtc_time *tm)
+{
+	efi_status_t status;
+	efi_time_t eft;
+
+	convert_to_efi_time(tm, &eft);
+
+	status = efi.set_time(&eft);
+
+	return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static const struct rtc_class_ops efi_rtc_ops = {
+	.read_time = efi_read_time,
+	.set_time = efi_set_time,
+	.read_alarm = efi_read_alarm,
+	.set_alarm = efi_set_alarm,
+};
+
+static int __init efi_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops,
+					THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+
+	return 0;
+}
+
+static int __exit efi_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct platform_driver efi_rtc_driver = {
+	.driver = {
+		.name = "rtc-efi",
+		.owner = THIS_MODULE,
+	},
+	.probe = efi_rtc_probe,
+	.remove = __exit_p(efi_rtc_remove),
+};
+
+static int __init efi_rtc_init(void)
+{
+	return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe);
+}
+
+static void __exit efi_rtc_exit(void)
+{
+	platform_driver_unregister(&efi_rtc_driver);
+}
+
+module_init(efi_rtc_init);
+module_exit(efi_rtc_exit);
+
+MODULE_AUTHOR("dann frazier <dannf@hp.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EFI RTC driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-generic.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-generic.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-generic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-generic.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,84 @@
+/* rtc-generic: RTC driver using the generic RTC abstraction
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+static int generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned int ret = get_rtc_time(tm);
+
+	if (ret & RTC_BATT_BAD)
+		return -EOPNOTSUPP;
+
+	return rtc_valid_tm(tm);
+}
+
+static int generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+	if (set_rtc_time(tm) < 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static const struct rtc_class_ops generic_rtc_ops = {
+	.read_time = generic_get_time,
+	.set_time = generic_set_time,
+};
+
+static int __init generic_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+
+	return 0;
+}
+
+static int __exit generic_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct platform_driver generic_rtc_driver = {
+	.driver = {
+		.name = "rtc-generic",
+		.owner = THIS_MODULE,
+	},
+	.remove = __exit_p(generic_rtc_remove),
+};
+
+static int __init generic_rtc_init(void)
+{
+	return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
+}
+
+static void __exit generic_rtc_fini(void)
+{
+	platform_driver_unregister(&generic_rtc_driver);
+}
+
+module_init(generic_rtc_init);
+module_exit(generic_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic RTC driver");
+MODULE_ALIAS("platform:rtc-generic");
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-lib.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-lib.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-lib.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-lib.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,14 +26,13 @@ static const unsigned short rtc_ydays[2]
 };
 
 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
 
 /*
  * The number of days in the month.
  */
 int rtc_month_days(unsigned int month, unsigned int year)
 {
-	return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
+	return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
 }
 EXPORT_SYMBOL(rtc_month_days);
 
@@ -42,7 +41,7 @@ EXPORT_SYMBOL(rtc_month_days);
  */
 int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
 {
-	return rtc_ydays[LEAP_YEAR(year)][month] + day-1;
+	return rtc_ydays[is_leap_year(year)][month] + day-1;
 }
 EXPORT_SYMBOL(rtc_year_days);
 
@@ -66,7 +65,7 @@ void rtc_time_to_tm(unsigned long time,
 		- LEAPS_THRU_END_OF(1970 - 1);
 	if (days < 0) {
 		year -= 1;
-		days += 365 + LEAP_YEAR(year);
+		days += 365 + is_leap_year(year);
 	}
 	tm->tm_year = year - 1900;
 	tm->tm_yday = days + 1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-m41t80.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-m41t80.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-m41t80.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-m41t80.c	2009-06-09 23:05:27.000000000 -0400
@@ -64,10 +64,12 @@
 #define M41T80_FEATURE_BL	(1 << 1)	/* Battery low indicator */
 #define M41T80_FEATURE_SQ	(1 << 2)	/* Squarewave feature */
 #define M41T80_FEATURE_WD	(1 << 3)	/* Extra watchdog resolution */
+#define M41T80_FEATURE_SQ_ALT	(1 << 4)	/* RSx bits are in reg 4 */
 
 #define DRV_VERSION "0.05"
 
 static const struct i2c_device_id m41t80_id[] = {
+	{ "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
 	{ "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
 	{ "m41t80", M41T80_FEATURE_SQ },
 	{ "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
@@ -393,12 +395,15 @@ static ssize_t m41t80_sysfs_show_sqwfreq
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
-	int val;
+	int val, reg_sqw;
 
 	if (!(clientdata->features & M41T80_FEATURE_SQ))
 		return -EINVAL;
 
-	val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+	reg_sqw = M41T80_REG_SQW;
+	if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+		reg_sqw = M41T80_REG_WDAY;
+	val = i2c_smbus_read_byte_data(client, reg_sqw);
 	if (val < 0)
 		return -EIO;
 	val = (val >> 4) & 0xf;
@@ -419,7 +424,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct m41t80_data *clientdata = i2c_get_clientdata(client);
-	int almon, sqw;
+	int almon, sqw, reg_sqw;
 	int val = simple_strtoul(buf, NULL, 0);
 
 	if (!(clientdata->features & M41T80_FEATURE_SQ))
@@ -440,13 +445,16 @@ static ssize_t m41t80_sysfs_set_sqwfreq(
 	almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
 	if (almon < 0)
 		return -EIO;
-	sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+	reg_sqw = M41T80_REG_SQW;
+	if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+		reg_sqw = M41T80_REG_WDAY;
+	sqw = i2c_smbus_read_byte_data(client, reg_sqw);
 	if (sqw < 0)
 		return -EIO;
 	sqw = (sqw & 0x0f) | (val << 4);
 	if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
 				      almon & ~M41T80_ALMON_SQWE) < 0 ||
-	    i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
+	    i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
 		return -EIO;
 	if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
 					     almon | M41T80_ALMON_SQWE) < 0)
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-mv.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-mv.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-mv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-mv.c	2009-06-09 23:05:27.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/bcd.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 
 
 #define RTC_TIME_REG_OFFS	0
@@ -119,6 +120,16 @@ static int __init mv_rtc_probe(struct pl
 		return -EINVAL;
 	}
 
+	/* make sure it is actually functional */
+	if (rtc_time == 0x01000000) {
+		ssleep(1);
+		rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
+		if (rtc_time == 0x01000000) {
+			dev_err(&pdev->dev, "internal RTC not ticking\n");
+			return -ENODEV;
+		}
+	}
+
 	platform_set_drvdata(pdev, pdata);
 	pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
 					 &mv_rtc_ops, THIS_MODULE);
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-omap.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-omap.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-omap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-omap.c	2009-06-09 23:05:27.000000000 -0400
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct
 
 	/* handle periodic and alarm irqs */
 	if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
-			rtc->dev.bus_id, rtc)) {
+			dev_name(&rtc->dev), rtc)) {
 		pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_timer);
 		goto fail0;
 	}
 	if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
-			rtc->dev.bus_id, rtc)) {
+			dev_name(&rtc->dev), rtc)) {
 		pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_alarm);
 		goto fail1;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-parisc.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-parisc.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-parisc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-parisc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,112 +0,0 @@
-/* rtc-parisc: RTC for HP PA-RISC firmware
- *
- * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-
-#include <asm/rtc.h>
-
-/* as simple as can be, and no simpler. */
-struct parisc_rtc {
-	struct rtc_device *rtc;
-	spinlock_t lock;
-};
-
-static int parisc_get_time(struct device *dev, struct rtc_time *tm)
-{
-	struct parisc_rtc *p = dev_get_drvdata(dev);
-	unsigned long flags, ret;
-
-	spin_lock_irqsave(&p->lock, flags);
-	ret = get_rtc_time(tm);
-	spin_unlock_irqrestore(&p->lock, flags);
-
-	if (ret & RTC_BATT_BAD)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
-static int parisc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	struct parisc_rtc *p = dev_get_drvdata(dev);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&p->lock, flags);
-	ret = set_rtc_time(tm);
-	spin_unlock_irqrestore(&p->lock, flags);
-
-	if (ret < 0)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
-static const struct rtc_class_ops parisc_rtc_ops = {
-	.read_time = parisc_get_time,
-	.set_time = parisc_set_time,
-};
-
-static int __devinit parisc_rtc_probe(struct platform_device *dev)
-{
-	struct parisc_rtc *p;
-
-	p = kzalloc(sizeof (*p), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
-
-	spin_lock_init(&p->lock);
-
-	p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
-					THIS_MODULE);
-	if (IS_ERR(p->rtc)) {
-		int err = PTR_ERR(p->rtc);
-		kfree(p);
-		return err;
-	}
-
-	platform_set_drvdata(dev, p);
-
-	return 0;
-}
-
-static int __devexit parisc_rtc_remove(struct platform_device *dev)
-{
-	struct parisc_rtc *p = platform_get_drvdata(dev);
-
-	rtc_device_unregister(p->rtc);
-	kfree(p);
-
-	return 0;
-}
-
-static struct platform_driver parisc_rtc_driver = {
-	.driver = {
-		.name = "rtc-parisc",
-		.owner = THIS_MODULE,
-	},
-	.probe = parisc_rtc_probe,
-	.remove = __devexit_p(parisc_rtc_remove),
-};
-
-static int __init parisc_rtc_init(void)
-{
-	return platform_driver_register(&parisc_rtc_driver);
-}
-
-static void __exit parisc_rtc_fini(void)
-{
-	platform_driver_unregister(&parisc_rtc_driver);
-}
-
-module_init(parisc_rtc_init);
-module_exit(parisc_rtc_fini);
-
-MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-pl030.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-pl030.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-pl030.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-pl030.c	2009-06-09 23:05:27.000000000 -0400
@@ -102,7 +102,7 @@ static const struct rtc_class_ops pl030_
 	.set_alarm	= pl030_set_alarm,
 };
 
-static int pl030_probe(struct amba_device *dev, void *id)
+static int pl030_probe(struct amba_device *dev, struct amba_id *id)
 {
 	struct pl030_rtc *rtc;
 	int ret;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-pl031.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-pl031.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-pl031.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-pl031.c	2009-06-09 23:05:27.000000000 -0400
@@ -127,7 +127,7 @@ static int pl031_remove(struct amba_devi
 	return 0;
 }
 
-static int pl031_probe(struct amba_device *adev, void *id)
+static int pl031_probe(struct amba_device *adev, struct amba_id *id)
 {
 	int ret;
 	struct pl031_local *ldata;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ppc.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ppc.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ppc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ppc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-/*
- * RTC driver for ppc_md RTC functions
- *
- * Â© 2007 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.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/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <asm/machdep.h>
-
-static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	ppc_md.get_rtc_time(tm);
-	return 0;
-}
-
-static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return ppc_md.set_rtc_time(tm);
-}
-
-static const struct rtc_class_ops ppc_rtc_ops = {
-	.set_time = ppc_rtc_set_time,
-	.read_time = ppc_rtc_read_time,
-};
-
-static struct rtc_device *rtc;
-static struct platform_device *ppc_rtc_pdev;
-
-static int __init ppc_rtc_init(void)
-{
-	if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
-		return -ENODEV;
-
-	ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
-	if (IS_ERR(ppc_rtc_pdev))
-		return PTR_ERR(ppc_rtc_pdev);
-
-	rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
-				  &ppc_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		platform_device_unregister(ppc_rtc_pdev);
-		return PTR_ERR(rtc);
-	}
-
-	return 0;
-}
-
-static void __exit ppc_rtc_exit(void)
-{
-	rtc_device_unregister(rtc);
-	platform_device_unregister(ppc_rtc_pdev);
-}
-
-module_init(ppc_rtc_init);
-module_exit(ppc_rtc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-proc.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-proc.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -105,14 +105,8 @@ static const struct file_operations rtc_
 
 void rtc_proc_add_device(struct rtc_device *rtc)
 {
-	if (rtc->id == 0) {
-		struct proc_dir_entry *ent;
-
-		ent = proc_create_data("driver/rtc", 0, NULL,
-				       &rtc_proc_fops, rtc);
-		if (ent)
-			ent->owner = rtc->owner;
-	}
+	if (rtc->id == 0)
+		proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
 }
 
 void rtc_proc_del_device(struct rtc_device *rtc)
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ps3.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ps3.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-ps3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-ps3.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * PS3 RTC Driver
+ *
+ * Copyright 2009 Sony 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+static u64 read_rtc(void)
+{
+	int result;
+	u64 rtc_val;
+	u64 tb_val;
+
+	result = lv1_get_rtc(&rtc_val, &tb_val);
+	BUG_ON(result);
+
+	return rtc_val;
+}
+
+static int ps3_get_time(struct device *dev, struct rtc_time *tm)
+{
+	rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
+	return rtc_valid_tm(tm);
+}
+
+static int ps3_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long now;
+
+	rtc_tm_to_time(tm, &now);
+	ps3_os_area_set_rtc_diff(now - read_rtc());
+	return 0;
+}
+
+static const struct rtc_class_ops ps3_rtc_ops = {
+	.read_time = ps3_get_time,
+	.set_time = ps3_set_time,
+};
+
+static int __init ps3_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+	return 0;
+}
+
+static int __exit ps3_rtc_remove(struct platform_device *dev)
+{
+	rtc_device_unregister(platform_get_drvdata(dev));
+	return 0;
+}
+
+static struct platform_driver ps3_rtc_driver = {
+	.driver = {
+		.name = "rtc-ps3",
+		.owner = THIS_MODULE,
+	},
+	.remove = __exit_p(ps3_rtc_remove),
+};
+
+static int __init ps3_rtc_init(void)
+{
+	return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
+}
+
+static void __exit ps3_rtc_fini(void)
+{
+	platform_driver_unregister(&ps3_rtc_driver);
+}
+
+module_init(ps3_rtc_init);
+module_exit(ps3_rtc_fini);
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ps3 RTC driver");
+MODULE_ALIAS("platform:rtc-ps3");
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-sa1100.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-sa1100.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-sa1100.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-sa1100.c	2009-06-09 23:05:27.000000000 -0400
@@ -35,7 +35,8 @@
 #include <asm/irq.h>
 
 #ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
+#include <mach/regs-rtc.h>
+#include <mach/regs-ost.h>
 #endif
 
 #define RTC_DEF_DIVIDER		32768 - 1
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-sh.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-sh.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-sh.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-sh.c	2009-06-09 23:05:27.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * SuperH On-Chip RTC Support
  *
- * Copyright (C) 2006, 2007, 2008  Paul Mundt
+ * Copyright (C) 2006 - 2009  Paul Mundt
  * Copyright (C) 2006  Jamie Lenehan
  * Copyright (C) 2008  Angelo Castello
  *
@@ -25,10 +25,11 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/log2.h>
+#include <linux/clk.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME	"sh-rtc"
-#define DRV_VERSION	"0.2.0"
+#define DRV_VERSION	"0.2.2"
 
 #define RTC_REG(r)	((r) * rtc_reg_size)
 
@@ -87,68 +88,64 @@
 #define RCR2_START	0x01	/* Start bit               */
 
 struct sh_rtc {
-	void __iomem *regbase;
-	unsigned long regsize;
-	struct resource *res;
-	int alarm_irq;
-	int periodic_irq;
-	int carry_irq;
-	struct rtc_device *rtc_dev;
-	spinlock_t lock;
-	unsigned long capabilities;	/* See asm-sh/rtc.h for cap bits */
-	unsigned short periodic_freq;
+	void __iomem		*regbase;
+	unsigned long		regsize;
+	struct resource		*res;
+	int			alarm_irq;
+	int			periodic_irq;
+	int			carry_irq;
+	struct clk		*clk;
+	struct rtc_device	*rtc_dev;
+	spinlock_t		lock;
+	unsigned long		capabilities;	/* See asm/rtc.h for cap bits */
+	unsigned short		periodic_freq;
 };
 
-static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+static int __sh_rtc_interrupt(struct sh_rtc *rtc)
 {
-	struct sh_rtc *rtc = dev_id;
-	unsigned int tmp;
-
-	spin_lock(&rtc->lock);
+	unsigned int tmp, pending;
 
 	tmp = readb(rtc->regbase + RCR1);
+	pending = tmp & RCR1_CF;
 	tmp &= ~RCR1_CF;
 	writeb(tmp, rtc->regbase + RCR1);
 
 	/* Users have requested One x Second IRQ */
-	if (rtc->periodic_freq & PF_OXS)
+	if (pending && rtc->periodic_freq & PF_OXS)
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
 
-	spin_unlock(&rtc->lock);
-
-	return IRQ_HANDLED;
+	return pending;
 }
 
-static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+static int __sh_rtc_alarm(struct sh_rtc *rtc)
 {
-	struct sh_rtc *rtc = dev_id;
-	unsigned int tmp;
-
-	spin_lock(&rtc->lock);
+	unsigned int tmp, pending;
 
 	tmp = readb(rtc->regbase + RCR1);
+	pending = tmp & RCR1_AF;
 	tmp &= ~(RCR1_AF | RCR1_AIE);
-		writeb(tmp, rtc->regbase + RCR1);
-
-	rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+	writeb(tmp, rtc->regbase + RCR1);
 
-	spin_unlock(&rtc->lock);
+	if (pending)
+		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
 
-	return IRQ_HANDLED;
+	return pending;
 }
 
-static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+static int __sh_rtc_periodic(struct sh_rtc *rtc)
 {
-	struct sh_rtc *rtc = dev_id;
 	struct rtc_device *rtc_dev = rtc->rtc_dev;
-	unsigned int tmp;
-
-	spin_lock(&rtc->lock);
+	struct rtc_task *irq_task;
+	unsigned int tmp, pending;
 
 	tmp = readb(rtc->regbase + RCR2);
+	pending = tmp & RCR2_PEF;
 	tmp &= ~RCR2_PEF;
 	writeb(tmp, rtc->regbase + RCR2);
 
+	if (!pending)
+		return 0;
+
 	/* Half period enabled than one skipped and the next notified */
 	if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT))
 		rtc->periodic_freq &= ~PF_COUNT;
@@ -157,16 +154,65 @@ static irqreturn_t sh_rtc_periodic(int i
 			rtc->periodic_freq |= PF_COUNT;
 		if (rtc->periodic_freq & PF_KOU) {
 			spin_lock(&rtc_dev->irq_task_lock);
-			if (rtc_dev->irq_task)
-				rtc_dev->irq_task->func(rtc_dev->irq_task->private_data);
+			irq_task = rtc_dev->irq_task;
+			if (irq_task)
+				irq_task->func(irq_task->private_data);
 			spin_unlock(&rtc_dev->irq_task_lock);
 		} else
 			rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
 	}
 
+	return pending;
+}
+
+static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+{
+	struct sh_rtc *rtc = dev_id;
+	int ret;
+
+	spin_lock(&rtc->lock);
+	ret = __sh_rtc_interrupt(rtc);
 	spin_unlock(&rtc->lock);
 
-	return IRQ_HANDLED;
+	return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+{
+	struct sh_rtc *rtc = dev_id;
+	int ret;
+
+	spin_lock(&rtc->lock);
+	ret = __sh_rtc_alarm(rtc);
+	spin_unlock(&rtc->lock);
+
+	return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+{
+	struct sh_rtc *rtc = dev_id;
+	int ret;
+
+	spin_lock(&rtc->lock);
+	ret = __sh_rtc_periodic(rtc);
+	spin_unlock(&rtc->lock);
+
+	return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
+{
+	struct sh_rtc *rtc = dev_id;
+	int ret;
+
+	spin_lock(&rtc->lock);
+	ret = __sh_rtc_interrupt(rtc);
+	ret |= __sh_rtc_alarm(rtc);
+	ret |= __sh_rtc_periodic(rtc);
+	spin_unlock(&rtc->lock);
+
+	return IRQ_RETVAL(ret);
 }
 
 static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
@@ -250,10 +296,10 @@ static inline void sh_rtc_setaie(struct
 
 	tmp = readb(rtc->regbase + RCR1);
 
-	if (!enable)
-		tmp &= ~RCR1_AIE;
-	else
+	if (enable)
 		tmp |= RCR1_AIE;
+	else
+		tmp &= ~RCR1_AIE;
 
 	writeb(tmp, rtc->regbase + RCR1);
 
@@ -275,6 +321,25 @@ static int sh_rtc_proc(struct device *de
 	return 0;
 }
 
+static inline void sh_rtc_setcie(struct device *dev, unsigned int enable)
+{
+	struct sh_rtc *rtc = dev_get_drvdata(dev);
+	unsigned int tmp;
+
+	spin_lock_irq(&rtc->lock);
+
+	tmp = readb(rtc->regbase + RCR1);
+
+	if (!enable)
+		tmp &= ~RCR1_CIE;
+	else
+		tmp |= RCR1_CIE;
+
+	writeb(tmp, rtc->regbase + RCR1);
+
+	spin_unlock_irq(&rtc->lock);
+}
+
 static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
 	struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -291,9 +356,11 @@ static int sh_rtc_ioctl(struct device *d
 		break;
 	case RTC_UIE_OFF:
 		rtc->periodic_freq &= ~PF_OXS;
+		sh_rtc_setcie(dev, 0);
 		break;
 	case RTC_UIE_ON:
 		rtc->periodic_freq |= PF_OXS;
+		sh_rtc_setcie(dev, 1);
 		break;
 	case RTC_IRQP_READ:
 		ret = put_user(rtc->rtc_dev->irq_freq,
@@ -356,18 +423,17 @@ static int sh_rtc_read_time(struct devic
 		tm->tm_sec--;
 #endif
 
+	/* only keep the carry interrupt enabled if UIE is on */
+	if (!(rtc->periodic_freq & PF_OXS))
+		sh_rtc_setcie(dev, 0);
+
 	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__func__,
 		tm->tm_sec, tm->tm_min, tm->tm_hour,
 		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
 
-	if (rtc_valid_tm(tm) < 0) {
-		dev_err(dev, "invalid date\n");
-		rtc_time_to_tm(0, tm);
-	}
-
-	return 0;
+	return rtc_valid_tm(tm);
 }
 
 static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -554,6 +620,7 @@ static int sh_rtc_irq_set_freq(struct de
 {
 	if (!is_power_of_2(freq))
 		return -EINVAL;
+
 	return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
 }
 
@@ -572,8 +639,9 @@ static int __devinit sh_rtc_probe(struct
 {
 	struct sh_rtc *rtc;
 	struct resource *res;
-	unsigned int tmp;
-	int ret;
+	struct rtc_time r;
+	char clk_name[6];
+	int clk_id, ret;
 
 	rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
 	if (unlikely(!rtc))
@@ -585,26 +653,13 @@ static int __devinit sh_rtc_probe(struct
 	ret = platform_get_irq(pdev, 0);
 	if (unlikely(ret <= 0)) {
 		ret = -ENOENT;
-		dev_err(&pdev->dev, "No IRQ for period\n");
-		goto err_badres;
-	}
-	rtc->periodic_irq = ret;
-
-	ret = platform_get_irq(pdev, 1);
-	if (unlikely(ret <= 0)) {
-		ret = -ENOENT;
-		dev_err(&pdev->dev, "No IRQ for carry\n");
+		dev_err(&pdev->dev, "No IRQ resource\n");
 		goto err_badres;
 	}
-	rtc->carry_irq = ret;
 
-	ret = platform_get_irq(pdev, 2);
-	if (unlikely(ret <= 0)) {
-		ret = -ENOENT;
-		dev_err(&pdev->dev, "No IRQ for alarm\n");
-		goto err_badres;
-	}
-	rtc->alarm_irq = ret;
+	rtc->periodic_irq = ret;
+	rtc->carry_irq = platform_get_irq(pdev, 1);
+	rtc->alarm_irq = platform_get_irq(pdev, 2);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	if (unlikely(res == NULL)) {
@@ -613,7 +668,7 @@ static int __devinit sh_rtc_probe(struct
 		goto err_badres;
 	}
 
-	rtc->regsize = res->end - res->start + 1;
+	rtc->regsize = resource_size(res);
 
 	rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name);
 	if (unlikely(!rtc->res)) {
@@ -627,6 +682,26 @@ static int __devinit sh_rtc_probe(struct
 		goto err_badmap;
 	}
 
+	clk_id = pdev->id;
+	/* With a single device, the clock id is still "rtc0" */
+	if (clk_id < 0)
+		clk_id = 0;
+
+	snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
+
+	rtc->clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(rtc->clk)) {
+		/*
+		 * No error handling for rtc->clk intentionally, not all
+		 * platforms will have a unique clock for the RTC, and
+		 * the clk API can handle the struct clk pointer being
+		 * NULL.
+		 */
+		rtc->clk = NULL;
+	}
+
+	clk_enable(rtc->clk);
+
 	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
 					   &sh_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
@@ -646,50 +721,71 @@ static int __devinit sh_rtc_probe(struct
 	}
 
 	rtc->rtc_dev->max_user_freq = 256;
-	rtc->rtc_dev->irq_freq = 1;
-	rtc->periodic_freq = 0x60;
 
 	platform_set_drvdata(pdev, rtc);
 
-	/* register periodic/carry/alarm irqs */
-	ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
-			  "sh-rtc period", rtc);
-	if (unlikely(ret)) {
-		dev_err(&pdev->dev,
-			"request period IRQ failed with %d, IRQ %d\n", ret,
-			rtc->periodic_irq);
-		goto err_unmap;
-	}
+	if (rtc->carry_irq <= 0) {
+		/* register shared periodic/carry/alarm irq */
+		ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
+				  IRQF_DISABLED, "sh-rtc", rtc);
+		if (unlikely(ret)) {
+			dev_err(&pdev->dev,
+				"request IRQ failed with %d, IRQ %d\n", ret,
+				rtc->periodic_irq);
+			goto err_unmap;
+		}
+	} else {
+		/* register periodic/carry/alarm irqs */
+		ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
+				  IRQF_DISABLED, "sh-rtc period", rtc);
+		if (unlikely(ret)) {
+			dev_err(&pdev->dev,
+				"request period IRQ failed with %d, IRQ %d\n",
+				ret, rtc->periodic_irq);
+			goto err_unmap;
+		}
 
-	ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
-			  "sh-rtc carry", rtc);
-	if (unlikely(ret)) {
-		dev_err(&pdev->dev,
-			"request carry IRQ failed with %d, IRQ %d\n", ret,
-			rtc->carry_irq);
-		free_irq(rtc->periodic_irq, rtc);
-		goto err_unmap;
-	}
+		ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
+				  IRQF_DISABLED, "sh-rtc carry", rtc);
+		if (unlikely(ret)) {
+			dev_err(&pdev->dev,
+				"request carry IRQ failed with %d, IRQ %d\n",
+				ret, rtc->carry_irq);
+			free_irq(rtc->periodic_irq, rtc);
+			goto err_unmap;
+		}
 
-	ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
-			  "sh-rtc alarm", rtc);
-	if (unlikely(ret)) {
-		dev_err(&pdev->dev,
-			"request alarm IRQ failed with %d, IRQ %d\n", ret,
-			rtc->alarm_irq);
-		free_irq(rtc->carry_irq, rtc);
-		free_irq(rtc->periodic_irq, rtc);
-		goto err_unmap;
+		ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
+				  IRQF_DISABLED, "sh-rtc alarm", rtc);
+		if (unlikely(ret)) {
+			dev_err(&pdev->dev,
+				"request alarm IRQ failed with %d, IRQ %d\n",
+				ret, rtc->alarm_irq);
+			free_irq(rtc->carry_irq, rtc);
+			free_irq(rtc->periodic_irq, rtc);
+			goto err_unmap;
+		}
 	}
 
-	tmp = readb(rtc->regbase + RCR1);
-	tmp &= ~RCR1_CF;
-	tmp |= RCR1_CIE;
-	writeb(tmp, rtc->regbase + RCR1);
+	/* everything disabled by default */
+	rtc->periodic_freq = 0;
+	rtc->rtc_dev->irq_freq = 0;
+	sh_rtc_setpie(&pdev->dev, 0);
+	sh_rtc_setaie(&pdev->dev, 0);
+	sh_rtc_setcie(&pdev->dev, 0);
 
+	/* reset rtc to epoch 0 if time is invalid */
+	if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
+		rtc_time_to_tm(0, &r);
+		rtc_set_time(rtc->rtc_dev, &r);
+	}
+
+	device_init_wakeup(&pdev->dev, 1);
 	return 0;
 
 err_unmap:
+	clk_disable(rtc->clk);
+	clk_put(rtc->clk);
 	iounmap(rtc->regbase);
 err_badmap:
 	release_resource(rtc->res);
@@ -708,25 +804,68 @@ static int __devexit sh_rtc_remove(struc
 
 	sh_rtc_setpie(&pdev->dev, 0);
 	sh_rtc_setaie(&pdev->dev, 0);
+	sh_rtc_setcie(&pdev->dev, 0);
 
-	free_irq(rtc->carry_irq, rtc);
 	free_irq(rtc->periodic_irq, rtc);
-	free_irq(rtc->alarm_irq, rtc);
+
+	if (rtc->carry_irq > 0) {
+		free_irq(rtc->carry_irq, rtc);
+		free_irq(rtc->alarm_irq, rtc);
+	}
 
 	release_resource(rtc->res);
 
 	iounmap(rtc->regbase);
 
+	clk_disable(rtc->clk);
+	clk_put(rtc->clk);
+
 	platform_set_drvdata(pdev, NULL);
 
 	kfree(rtc);
 
 	return 0;
 }
+
+static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_rtc *rtc = platform_get_drvdata(pdev);
+
+	set_irq_wake(rtc->periodic_irq, enabled);
+
+	if (rtc->carry_irq > 0) {
+		set_irq_wake(rtc->carry_irq, enabled);
+		set_irq_wake(rtc->alarm_irq, enabled);
+	}
+}
+
+static int sh_rtc_suspend(struct device *dev)
+{
+	if (device_may_wakeup(dev))
+		sh_rtc_set_irq_wake(dev, 1);
+
+	return 0;
+}
+
+static int sh_rtc_resume(struct device *dev)
+{
+	if (device_may_wakeup(dev))
+		sh_rtc_set_irq_wake(dev, 0);
+
+	return 0;
+}
+
+static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+	.suspend = sh_rtc_suspend,
+	.resume = sh_rtc_resume,
+};
+
 static struct platform_driver sh_rtc_platform_driver = {
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
+		.pm	= &sh_rtc_dev_pm_ops,
 	},
 	.probe		= sh_rtc_probe,
 	.remove		= __devexit_p(sh_rtc_remove),
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-twl4030.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-twl4030.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-twl4030.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-twl4030.c	2009-06-09 23:05:27.000000000 -0400
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(s
 
 	ret = request_irq(irq, twl4030_rtc_interrupt,
 				IRQF_TRIGGER_RISING,
-				rtc->dev.bus_id, rtc);
+				dev_name(&rtc->dev), rtc);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "IRQ is not free.\n");
 		goto out1;
@@ -495,9 +495,7 @@ static int twl4030_rtc_suspend(struct pl
 {
 	irqstat = rtc_irq_bits;
 
-	/* REVISIT alarm may need to wake us from sleep */
-	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
-			 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+	mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-v3020.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-v3020.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-v3020.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-v3020.c	2009-06-09 23:05:27.000000000 -0400
@@ -27,17 +27,162 @@
 #include <linux/bcd.h>
 #include <linux/rtc-v3020.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 #undef DEBUG
 
+struct v3020;
+
+struct v3020_chip_ops {
+	int (*map_io)(struct v3020 *chip, struct platform_device *pdev,
+		      struct v3020_platform_data *pdata);
+	void (*unmap_io)(struct v3020 *chip);
+	unsigned char (*read_bit)(struct v3020 *chip);
+	void (*write_bit)(struct v3020 *chip, unsigned char bit);
+};
+
+#define V3020_CS	0
+#define V3020_WR	1
+#define V3020_RD	2
+#define V3020_IO	3
+
+struct v3020_gpio {
+	const char *name;
+	unsigned int gpio;
+};
+
 struct v3020 {
+	/* MMIO access */
 	void __iomem *ioaddress;
 	int leftshift;
+
+	/* GPIO access */
+	struct v3020_gpio *gpio;
+
+	struct v3020_chip_ops *ops;
+
 	struct rtc_device *rtc;
 };
 
+
+static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev,
+			  struct v3020_platform_data *pdata)
+{
+	if (pdev->num_resources != 1)
+		return -EBUSY;
+
+	if (pdev->resource[0].flags != IORESOURCE_MEM)
+		return -EBUSY;
+
+	chip->leftshift = pdata->leftshift;
+	chip->ioaddress = ioremap(pdev->resource[0].start, 1);
+	if (chip->ioaddress == NULL)
+		return -EBUSY;
+
+	return 0;
+}
+
+static void v3020_mmio_unmap(struct v3020 *chip)
+{
+	iounmap(chip->ioaddress);
+}
+
+static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+	writel(bit << chip->leftshift, chip->ioaddress);
+}
+
+static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
+{
+	return readl(chip->ioaddress) & (1 << chip->leftshift);
+}
+
+static struct v3020_chip_ops v3020_mmio_ops = {
+	.map_io		= v3020_mmio_map,
+	.unmap_io	= v3020_mmio_unmap,
+	.read_bit	= v3020_mmio_read_bit,
+	.write_bit	= v3020_mmio_write_bit,
+};
+
+static struct v3020_gpio v3020_gpio[] = {
+	{ "RTC CS", 0 },
+	{ "RTC WR", 0 },
+	{ "RTC RD", 0 },
+	{ "RTC IO", 0 },
+};
+
+static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
+			  struct v3020_platform_data *pdata)
+{
+	int i, err;
+
+	v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
+	v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
+	v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
+	v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
+
+	for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) {
+		err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name);
+		if (err)
+			goto err_request;
+
+		gpio_direction_output(v3020_gpio[i].gpio, 1);
+	}
+
+	chip->gpio = v3020_gpio;
+
+	return 0;
+
+err_request:
+	while (--i >= 0)
+		gpio_free(v3020_gpio[i].gpio);
+
+	return err;
+}
+
+static void v3020_gpio_unmap(struct v3020 *chip)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++)
+		gpio_free(v3020_gpio[i].gpio);
+}
+
+static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+	gpio_direction_output(chip->gpio[V3020_IO].gpio, bit);
+	gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+	gpio_set_value(chip->gpio[V3020_WR].gpio, 0);
+	udelay(1);
+	gpio_set_value(chip->gpio[V3020_WR].gpio, 1);
+	gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+}
+
+static unsigned char v3020_gpio_read_bit(struct v3020 *chip)
+{
+	int bit;
+
+	gpio_direction_input(chip->gpio[V3020_IO].gpio);
+	gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+	gpio_set_value(chip->gpio[V3020_RD].gpio, 0);
+	udelay(1);
+	bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio);
+	udelay(1);
+	gpio_set_value(chip->gpio[V3020_RD].gpio, 1);
+	gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+
+	return bit;
+}
+
+static struct v3020_chip_ops v3020_gpio_ops = {
+	.map_io		= v3020_gpio_map,
+	.unmap_io	= v3020_gpio_unmap,
+	.read_bit	= v3020_gpio_read_bit,
+	.write_bit	= v3020_gpio_write_bit,
+};
+
 static void v3020_set_reg(struct v3020 *chip, unsigned char address,
 			unsigned char data)
 {
@@ -46,7 +191,7 @@ static void v3020_set_reg(struct v3020 *
 
 	tmp = address;
 	for (i = 0; i < 4; i++) {
-		writel((tmp & 1) << chip->leftshift, chip->ioaddress);
+		chip->ops->write_bit(chip, (tmp & 1));
 		tmp >>= 1;
 		udelay(1);
 	}
@@ -54,7 +199,7 @@ static void v3020_set_reg(struct v3020 *
 	/* Commands dont have data */
 	if (!V3020_IS_COMMAND(address)) {
 		for (i = 0; i < 8; i++) {
-			writel((data & 1) << chip->leftshift, chip->ioaddress);
+			chip->ops->write_bit(chip, (data & 1));
 			data >>= 1;
 			udelay(1);
 		}
@@ -63,18 +208,18 @@ static void v3020_set_reg(struct v3020 *
 
 static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
 {
-	unsigned int data=0;
+	unsigned int data = 0;
 	int i;
 
 	for (i = 0; i < 4; i++) {
-		writel((address & 1) << chip->leftshift, chip->ioaddress);
+		chip->ops->write_bit(chip, (address & 1));
 		address >>= 1;
 		udelay(1);
 	}
 
 	for (i = 0; i < 8; i++) {
 		data >>= 1;
-		if (readl(chip->ioaddress) & (1 << chip->leftshift))
+		if (chip->ops->read_bit(chip))
 			data |= 0x80;
 		udelay(1);
 	}
@@ -106,16 +251,14 @@ static int v3020_read_time(struct device
 	tmp = v3020_get_reg(chip, V3020_YEAR);
 	dt->tm_year = bcd2bin(tmp)+100;
 
-#ifdef DEBUG
-	printk("\n%s : Read RTC values\n",__func__);
-	printk("tm_hour: %i\n",dt->tm_hour);
-	printk("tm_min : %i\n",dt->tm_min);
-	printk("tm_sec : %i\n",dt->tm_sec);
-	printk("tm_year: %i\n",dt->tm_year);
-	printk("tm_mon : %i\n",dt->tm_mon);
-	printk("tm_mday: %i\n",dt->tm_mday);
-	printk("tm_wday: %i\n",dt->tm_wday);
-#endif
+	dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+	dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+	dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+	dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+	dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+	dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+	dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+	dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
 
 	return 0;
 }
@@ -125,15 +268,13 @@ static int v3020_set_time(struct device
 {
 	struct v3020 *chip = dev_get_drvdata(dev);
 
-#ifdef DEBUG
-	printk("\n%s : Setting RTC values\n",__func__);
-	printk("tm_sec : %i\n",dt->tm_sec);
-	printk("tm_min : %i\n",dt->tm_min);
-	printk("tm_hour: %i\n",dt->tm_hour);
-	printk("tm_mday: %i\n",dt->tm_mday);
-	printk("tm_wday: %i\n",dt->tm_wday);
-	printk("tm_year: %i\n",dt->tm_year);
-#endif
+	dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+	dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+	dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+	dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+	dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+	dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+	dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
 
 	/* Write all the values to ram... */
 	v3020_set_reg(chip, V3020_SECONDS, 	bin2bcd(dt->tm_sec));
@@ -168,30 +309,28 @@ static int rtc_probe(struct platform_dev
 	int i;
 	int temp;
 
-	if (pdev->num_resources != 1)
-		return -EBUSY;
-
-	if (pdev->resource[0].flags != IORESOURCE_MEM)
-		return -EBUSY;
-
 	chip = kzalloc(sizeof *chip, GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
-	chip->leftshift = pdata->leftshift;
-	chip->ioaddress = ioremap(pdev->resource[0].start, 1);
-	if (chip->ioaddress == NULL)
+	if (pdata->use_gpio)
+		chip->ops = &v3020_gpio_ops;
+	else
+		chip->ops = &v3020_mmio_ops;
+
+	retval = chip->ops->map_io(chip, pdev, pdata);
+	if (retval)
 		goto err_chip;
 
 	/* Make sure the v3020 expects a communication cycle
 	 * by reading 8 times */
 	for (i = 0; i < 8; i++)
-		temp = readl(chip->ioaddress);
+		temp = chip->ops->read_bit(chip);
 
 	/* Test chip by doing a write/read sequence
 	 * to the chip ram */
 	v3020_set_reg(chip, V3020_SECONDS, 0x33);
-	if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
+	if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
 		retval = -ENODEV;
 		goto err_io;
 	}
@@ -200,10 +339,17 @@ static int rtc_probe(struct platform_dev
 	 * are all disabled */
 	v3020_set_reg(chip, V3020_STATUS_0, 0x0);
 
-	dev_info(&pdev->dev, "Chip available at physical address 0x%llx,"
-		"data connected to D%d\n",
-		(unsigned long long)pdev->resource[0].start,
-		chip->leftshift);
+	if (pdata->use_gpio)
+		dev_info(&pdev->dev, "Chip available at GPIOs "
+			 "%d, %d, %d, %d\n",
+			 chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
+			 chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
+	else
+		dev_info(&pdev->dev, "Chip available at "
+			 "physical address 0x%llx,"
+			 "data connected to D%d\n",
+			 (unsigned long long)pdev->resource[0].start,
+			 chip->leftshift);
 
 	platform_set_drvdata(pdev, chip);
 
@@ -218,7 +364,7 @@ static int rtc_probe(struct platform_dev
 	return 0;
 
 err_io:
-	iounmap(chip->ioaddress);
+	chip->ops->unmap_io(chip);
 err_chip:
 	kfree(chip);
 
@@ -233,7 +379,7 @@ static int rtc_remove(struct platform_de
 	if (rtc)
 		rtc_device_unregister(rtc);
 
-	iounmap(chip->ioaddress);
+	chip->ops->unmap_io(chip);
 	kfree(chip);
 
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/rtc/rtc-wm8350.c linux-libre-2.6.30-gnu1/drivers/rtc/rtc-wm8350.c
--- linux-libre-2.6.29-gnu1/drivers/rtc/rtc-wm8350.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/rtc/rtc-wm8350.c	2009-06-09 23:05:27.000000000 -0400
@@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct dev
 	do {
 		rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 		schedule_timeout_uninterruptible(msecs_to_jiffies(1));
-	} while (retries-- && !(rtc_ctrl & WM8350_RTC_STS));
+	} while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
 
 	if (!retries) {
 		dev_err(dev, "timed out on set confirmation\n");
@@ -236,6 +236,17 @@ static int wm8350_rtc_start_alarm(struct
 	return 0;
 }
 
+static int wm8350_rtc_alarm_irq_enable(struct device *dev,
+				       unsigned int enabled)
+{
+	struct wm8350 *wm8350 = dev_get_drvdata(dev);
+
+	if (enabled)
+		return wm8350_rtc_start_alarm(wm8350);
+	else
+		return wm8350_rtc_stop_alarm(wm8350);
+}
+
 static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct wm8350 *wm8350 = dev_get_drvdata(dev);
@@ -291,30 +302,15 @@ static int wm8350_rtc_setalarm(struct de
 	return ret;
 }
 
-/*
- * Handle commands from user-space
- */
-static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd,
-			    unsigned long arg)
+static int wm8350_rtc_update_irq_enable(struct device *dev,
+					unsigned int enabled)
 {
 	struct wm8350 *wm8350 = dev_get_drvdata(dev);
 
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		return wm8350_rtc_stop_alarm(wm8350);
-	case RTC_AIE_ON:
-		return wm8350_rtc_start_alarm(wm8350);
-
-	case RTC_UIE_OFF:
-		wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-		break;
-	case RTC_UIE_ON:
+	if (enabled)
 		wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-		break;
-
-	default:
-		return -ENOIOCTLCMD;
-	}
+	else
+		wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 
 	return 0;
 }
@@ -345,11 +341,12 @@ static void wm8350_rtc_update_handler(st
 }
 
 static const struct rtc_class_ops wm8350_rtc_ops = {
-	.ioctl = wm8350_rtc_ioctl,
 	.read_time = wm8350_rtc_readtime,
 	.set_time = wm8350_rtc_settime,
 	.read_alarm = wm8350_rtc_readalarm,
 	.set_alarm = wm8350_rtc_setalarm,
+	.alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
+	.update_irq_enable = wm8350_rtc_update_irq_enable,
 };
 
 #ifdef CONFIG_PM
@@ -440,7 +437,7 @@ static int wm8350_rtc_probe(struct platf
 		do {
 			timectl = wm8350_reg_read(wm8350,
 						  WM8350_RTC_TIME_CONTROL);
-		} while (timectl & WM8350_RTC_STS && retries--);
+		} while (timectl & WM8350_RTC_STS && --retries);
 
 		if (retries == 0) {
 			dev_err(&pdev->dev, "failed to start: timeout\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_3990_erp.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_3990_erp.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_3990_erp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_3990_erp.c	2009-06-09 23:05:27.000000000 -0400
@@ -7,6 +7,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <asm/idals.h>
@@ -75,7 +77,7 @@ dasd_3990_erp_block_queue(struct dasd_cc
 	struct dasd_device *device = erp->startdev;
 	unsigned long flags;
 
-	DEV_MESSAGE(KERN_INFO, device,
+	DBF_DEV_EVENT(DBF_INFO, device,
 		    "blocking request queue for %is", expires/HZ);
 
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -114,9 +116,9 @@ dasd_3990_erp_int_req(struct dasd_ccw_re
 	} else {
 
 		/* issue a message and wait for 'device ready' interrupt */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
+		dev_err(&device->cdev->dev,
 			    "is offline or not installed - "
-			    "INTERVENTION REQUIRED!!");
+			    "INTERVENTION REQUIRED!!\n");
 
 		dasd_3990_erp_block_queue(erp, 60*HZ);
 	}
@@ -158,7 +160,7 @@ dasd_3990_erp_alternate_path(struct dasd
 
 	if ((erp->lpm & opm) != 0x00) {
 
-		DEV_MESSAGE(KERN_DEBUG, device,
+		DBF_DEV_EVENT(DBF_WARNING, device,
 			    "try alternate lpm=%x (lpum=%x / opm=%x)",
 			    erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
 
@@ -166,10 +168,9 @@ dasd_3990_erp_alternate_path(struct dasd
 		erp->status = DASD_CQR_FILLED;
 		erp->retries = 10;
 	} else {
-		DEV_MESSAGE(KERN_ERR, device,
-			    "No alternate channel path left (lpum=%x / "
-			    "opm=%x) -> permanent error",
-			    erp->irb.esw.esw0.sublog.lpum, opm);
+		dev_err(&device->cdev->dev,
+			"The DASD cannot be reached on any path (lpum=%x"
+			"/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
 
 		/* post request with permanent error */
 		erp->status = DASD_CQR_FAILED;
@@ -204,8 +205,8 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req *
 					  sizeof(struct DCTL_data),
 					  device);
 	if (IS_ERR(dctl_cqr)) {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Unable to allocate DCTL-CQR");
+		dev_err(&device->cdev->dev,
+			    "Unable to allocate DCTL-CQR\n");
 		erp->status = DASD_CQR_FAILED;
 		return erp;
 	}
@@ -294,7 +295,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_r
 	/* interrupt (this enables easier enqueing of the cqr)	    */
 	if (erp->function != dasd_3990_erp_action_4) {
 
-		DEV_MESSAGE(KERN_INFO, device, "%s",
+		DBF_DEV_EVENT(DBF_INFO, device, "%s",
 			    "dasd_3990_erp_action_4: first time retry");
 
 		erp->retries = 256;
@@ -303,7 +304,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_r
 	} else {
 		if (sense && (sense[25] == 0x1D)) { /* state change pending */
 
-			DEV_MESSAGE(KERN_INFO, device,
+			DBF_DEV_EVENT(DBF_INFO, device,
 				    "waiting for state change pending "
 				    "interrupt, %d retries left",
 				    erp->retries);
@@ -311,15 +312,14 @@ dasd_3990_erp_action_4(struct dasd_ccw_r
 			dasd_3990_erp_block_queue(erp, 30*HZ);
 
 		} else if (sense && (sense[25] == 0x1E)) {	/* busy */
-			DEV_MESSAGE(KERN_INFO, device,
+			DBF_DEV_EVENT(DBF_INFO, device,
 				    "busy - redriving request later, "
 				    "%d retries left",
 				    erp->retries);
                         dasd_3990_erp_block_queue(erp, HZ);
 		} else {
-
 			/* no state change pending - retry */
-			DEV_MESSAGE (KERN_INFO, device,
+			DBF_DEV_EVENT(DBF_INFO, device,
 				     "redriving request immediately, "
 				     "%d retries left",
 				     erp->retries);
@@ -384,6 +384,7 @@ dasd_3990_handle_env_data(struct dasd_cc
 	struct dasd_device *device = erp->startdev;
 	char msg_format = (sense[7] & 0xF0);
 	char msg_no = (sense[7] & 0x0F);
+	char errorstring[ERRORLENGTH];
 
 	switch (msg_format) {
 	case 0x00:		/* Format 0 - Program or System Checks */
@@ -394,95 +395,97 @@ dasd_3990_handle_env_data(struct dasd_cc
 			case 0x00:	/* No Message */
 				break;
 			case 0x01:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Invalid Command");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Invalid Command\n");
 				break;
 			case 0x02:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Invalid Command "
-					    "Sequence");
+					    "Sequence\n");
 				break;
 			case 0x03:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - CCW Count less than "
-					    "required");
+					    "required\n");
 				break;
 			case 0x04:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Invalid Parameter");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Invalid Parameter\n");
 				break;
 			case 0x05:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Diagnostic of Sepecial"
-					    " Command Violates File Mask");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Diagnostic of Special"
+					    " Command Violates File Mask\n");
 				break;
 			case 0x07:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Channel Returned with "
-					    "Incorrect retry CCW");
+					    "Incorrect retry CCW\n");
 				break;
 			case 0x08:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Reset Notification");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Reset Notification\n");
 				break;
 			case 0x09:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Storage Path Restart");
+				dev_warn(&device->cdev->dev,
+					 "FORMAT 0 - Storage Path Restart\n");
 				break;
 			case 0x0A:
-				DEV_MESSAGE(KERN_WARNING, device,
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Channel requested "
-					    "... %02x", sense[8]);
+					    "... %02x\n", sense[8]);
 				break;
 			case 0x0B:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Invalid Defective/"
-					    "Alternate Track Pointer");
+					    "Alternate Track Pointer\n");
 				break;
 			case 0x0C:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - DPS Installation "
-					    "Check");
+					    "Check\n");
 				break;
 			case 0x0E:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Command Invalid on "
-					    "Secondary Address");
+					    "Secondary Address\n");
 				break;
 			case 0x0F:
-				DEV_MESSAGE(KERN_WARNING, device,
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Status Not As "
-					    "Required: reason %02x", sense[8]);
+					    "Required: reason %02x\n",
+					 sense[8]);
 				break;
 			default:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Reseved");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Reserved\n");
 			}
 		} else {
 			switch (msg_no) {
 			case 0x00:	/* No Message */
 				break;
 			case 0x01:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Device Error Source");
+				dev_warn(&device->cdev->dev,
+					 "FORMAT 0 - Device Error "
+					 "Source\n");
 				break;
 			case 0x02:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Reserved");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Reserved\n");
 				break;
 			case 0x03:
-				DEV_MESSAGE(KERN_WARNING, device,
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Device Fenced - "
-					    "device = %02x", sense[4]);
+					    "device = %02x\n", sense[4]);
 				break;
 			case 0x04:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
+				dev_warn(&device->cdev->dev,
 					    "FORMAT 0 - Data Pinned for "
-					    "Device");
+					    "Device\n");
 				break;
 			default:
-				DEV_MESSAGE(KERN_WARNING, device, "%s",
-					    "FORMAT 0 - Reserved");
+				dev_warn(&device->cdev->dev,
+					    "FORMAT 0 - Reserved\n");
 			}
 		}
 		break;
@@ -492,348 +495,352 @@ dasd_3990_handle_env_data(struct dasd_cc
 		case 0x00:	/* No Message */
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Device Status 1 not as "
-				    "expected");
+				    "expected\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Index missing");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Index missing\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Interruption cannot be reset");
+			dev_warn(&device->cdev->dev,
+				 "FORMAT 1 - Interruption cannot be "
+				 "reset\n");
 			break;
 		case 0x05:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Device did not respond to "
-				    "selection");
+				    "selection\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Device check-2 error or Set "
-				    "Sector is not complete");
+				    "Sector is not complete\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Head address does not "
-				    "compare");
+				    "compare\n");
 			break;
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Device status 1 not valid");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Device status 1 not valid\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Device not ready");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Device not ready\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Track physical address did "
-				    "not compare");
+				    "not compare\n");
 			break;
 		case 0x0B:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Missing device address bit");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Missing device address bit\n");
 			break;
 		case 0x0C:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Drive motor switch is off");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Drive motor switch is off\n");
 			break;
 		case 0x0D:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Seek incomplete");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Seek incomplete\n");
 			break;
 		case 0x0E:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Cylinder address did not "
-				    "compare");
+				    "compare\n");
 			break;
 		case 0x0F:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 1 - Offset active cannot be "
-				    "reset");
+				    "reset\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 1 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 1 - Reserved\n");
 		}
 		break;
 
 	case 0x20:		/* Format 2 - 3990 Equipment Checks */
 		switch (msg_no) {
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 2 - 3990 check-2 error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 2 - 3990 check-2 error\n");
 			break;
 		case 0x0E:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 2 - Support facility errors");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 2 - Support facility errors\n");
 			break;
 		case 0x0F:
-			DEV_MESSAGE(KERN_WARNING, device,
-				    "FORMAT 2 - Microcode detected error %02x",
-				    sense[8]);
+			dev_warn(&device->cdev->dev,
+				 "FORMAT 2 - Microcode detected error "
+				 "%02x\n",
+				 sense[8]);
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 2 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 2 - Reserved\n");
 		}
 		break;
 
 	case 0x30:		/* Format 3 - 3990 Control Checks */
 		switch (msg_no) {
 		case 0x0F:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 3 - Allegiance terminated");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 3 - Allegiance terminated\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 3 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 3 - Reserved\n");
 		}
 		break;
 
 	case 0x40:		/* Format 4 - Data Checks */
 		switch (msg_no) {
 		case 0x00:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - Home address area error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - Home address area error\n");
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - Count area error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - Count area error\n");
 			break;
 		case 0x02:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - Key area error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - Key area error\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - Data area error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - Data area error\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No sync byte in home address "
-				    "area");
+				    "area\n");
 			break;
 		case 0x05:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No sync byte in count address "
-				    "area");
+				    "area\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - No sync byte in key area");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - No sync byte in key area\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - No sync byte in data area");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - No sync byte in data area\n");
 			break;
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - Home address area error; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - Count area error; offset "
-				    "active");
+				    "active\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - Key area error; offset "
-				    "active");
+				    "active\n");
 			break;
 		case 0x0B:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - Data area error; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		case 0x0C:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No sync byte in home "
-				    "address area; offset active");
+				    "address area; offset active\n");
 			break;
 		case 0x0D:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No syn byte in count "
-				    "address area; offset active");
+				    "address area; offset active\n");
 			break;
 		case 0x0E:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No sync byte in key area; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		case 0x0F:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 4 - No syn byte in data area; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 4 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 4 - Reserved\n");
 		}
 		break;
 
 	case 0x50:  /* Format 5 - Data Check with displacement information */
 		switch (msg_no) {
 		case 0x00:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 5 - Data Check in the "
-				    "home address area");
+				    "home address area\n");
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 5 - Data Check in the count area");
+			dev_warn(&device->cdev->dev,
+				 "FORMAT 5 - Data Check in the count "
+				 "area\n");
 			break;
 		case 0x02:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 5 - Data Check in the key area");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 5 - Data Check in the key area\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 5 - Data Check in the data area");
+			dev_warn(&device->cdev->dev,
+				 "FORMAT 5 - Data Check in the data "
+				 "area\n");
 			break;
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 5 - Data Check in the "
-				    "home address area; offset active");
+				    "home address area; offset active\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 5 - Data Check in the count area; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 5 - Data Check in the key area; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		case 0x0B:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 5 - Data Check in the data area; "
-				    "offset active");
+				    "offset active\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 5 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 5 - Reserved\n");
 		}
 		break;
 
 	case 0x60:  /* Format 6 - Usage Statistics/Overrun Errors */
 		switch (msg_no) {
 		case 0x00:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel A");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel A\n");
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel B");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel B\n");
 			break;
 		case 0x02:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel C");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel C\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel D");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel D\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel E");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel E\n");
 			break;
 		case 0x05:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel F");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel F\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel G");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel G\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Overrun on channel H");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Overrun on channel H\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 6 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 6 - Reserved\n");
 		}
 		break;
 
 	case 0x70:  /* Format 7 - Device Connection Control Checks */
 		switch (msg_no) {
 		case 0x00:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - RCC initiated by a connection "
-				    "check alert");
+				    "check alert\n");
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - RCC 1 sequence not "
-				    "successful");
+				    "successful\n");
 			break;
 		case 0x02:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - RCC 1 and RCC 2 sequences not "
-				    "successful");
+				    "successful\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Invalid tag-in during "
-				    "selection sequence");
+				    "selection sequence\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 7 - extra RCC required");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 7 - extra RCC required\n");
 			break;
 		case 0x05:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Invalid DCC selection "
-				    "response or timeout");
+				    "response or timeout\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Missing end operation; device "
-				    "transfer complete");
+				    "transfer complete\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Missing end operation; device "
-				    "transfer incomplete");
+				    "transfer incomplete\n");
 			break;
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Invalid tag-in for an "
-				    "immediate command sequence");
+				    "immediate command sequence\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Invalid tag-in for an "
-				    "extended command sequence");
+				    "extended command sequence\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - 3990 microcode time out when "
-				    "stopping selection");
+				    "stopping selection\n");
 			break;
 		case 0x0B:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - No response to selection "
-				    "after a poll interruption");
+				    "after a poll interruption\n");
 			break;
 		case 0x0C:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - Permanent path error (DASD "
-				    "controller not available)");
+				    "controller not available)\n");
 			break;
 		case 0x0D:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 7 - DASD controller not available"
-				    " on disconnected command chain");
+				    " on disconnected command chain\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 7 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 7 - Reserved\n");
 		}
 		break;
 
@@ -841,52 +848,52 @@ dasd_3990_handle_env_data(struct dasd_cc
 		switch (msg_no) {
 		case 0x00:	/* No Message */
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - Error correction code "
-				    "hardware fault");
+				    "hardware fault\n");
 			break;
 		case 0x03:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - Unexpected end operation "
-				    "response code");
+				    "response code\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - End operation with transfer "
-				    "count not zero");
+				    "count not zero\n");
 			break;
 		case 0x05:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - End operation with transfer "
-				    "count zero");
+				    "count zero\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - DPS checks after a system "
-				    "reset or selective reset");
+				    "reset or selective reset\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 8 - DPS cannot be filled");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 8 - DPS cannot be filled\n");
 			break;
 		case 0x08:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - Short busy time-out during "
-				    "device selection");
+				    "device selection\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - DASD controller failed to "
-				    "set or reset the long busy latch");
+				    "set or reset the long busy latch\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 8 - No interruption from device "
-				    "during a command chain");
+				    "during a command chain\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 8 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 8 - Reserved\n");
 		}
 		break;
 
@@ -895,97 +902,100 @@ dasd_3990_handle_env_data(struct dasd_cc
 		case 0x00:
 			break;	/* No Message */
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 9 - Device check-2 error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 9 - Device check-2 error\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 9 - Head address did not compare");
+			dev_warn(&device->cdev->dev,
+				 "FORMAT 9 - Head address did not "
+				 "compare\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 9 - Track physical address did "
-				    "not compare while oriented");
+				    "not compare while oriented\n");
 			break;
 		case 0x0E:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT 9 - Cylinder address did not "
-				    "compare");
+				    "compare\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT 9 - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT 9 - Reserved\n");
 		}
 		break;
 
 	case 0xF0:		/* Format F - Cache Storage Checks */
 		switch (msg_no) {
 		case 0x00:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Operation Terminated");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Operation Terminated\n");
 			break;
 		case 0x01:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Subsystem Processing Error");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Subsystem Processing Error\n");
 			break;
 		case 0x02:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT F - Cache or nonvolatile storage "
-				    "equipment failure");
+				    "equipment failure\n");
 			break;
 		case 0x04:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Caching terminated");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Caching terminated\n");
 			break;
 		case 0x06:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT F - Cache fast write access not "
-				    "authorized");
+				    "authorized\n");
 			break;
 		case 0x07:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Track format incorrect");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Track format incorrect\n");
 			break;
 		case 0x09:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Caching reinitiated");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Caching reinitiated\n");
 			break;
 		case 0x0A:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT F - Nonvolatile storage "
-				    "terminated");
+				    "terminated\n");
 			break;
 		case 0x0B:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Volume is suspended duplex");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Volume is suspended duplex\n");
 			/* call extended error reporting (EER) */
 			dasd_eer_write(device, erp->refers,
 				       DASD_EER_PPRCSUSPEND);
 			break;
 		case 0x0C:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - Subsystem status connot be "
-				    "determined");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - Subsystem status cannot be "
+				    "determined\n");
 			break;
 		case 0x0D:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
+			dev_warn(&device->cdev->dev,
 				    "FORMAT F - Caching status reset to "
-				    "default");
+				    "default\n");
 			break;
 		case 0x0E:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT F - DASD Fast Write inhibited");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT F - DASD Fast Write inhibited\n");
 			break;
 		default:
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "FORMAT D - Reserved");
+			dev_warn(&device->cdev->dev,
+				    "FORMAT D - Reserved\n");
 		}
 		break;
 
-	default:	/* unknown message format - should not happen */
-	        DEV_MESSAGE (KERN_WARNING, device,
-                             "unknown message format %02x",
-                             msg_format);
+	default:	/* unknown message format - should not happen
+			   internal error 03 - unknown message format */
+		snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+		dev_err(&device->cdev->dev,
+			 "An error occurred in the DASD device driver, "
+			 "reason=%s\n", errorstring);
 		break;
 	}			/* end switch message format */
 
@@ -1015,7 +1025,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_re
 	/* env data present (ACTION 10 - retry should work) */
 	if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Command Reject - environmental data present");
 
 		dasd_3990_handle_env_data(erp, sense);
@@ -1023,9 +1033,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_re
 		erp->retries = 5;
 
 	} else {
-		/* fatal error -  set status to FAILED */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Command Reject - Fatal error");
+		/* fatal error -  set status to FAILED
+		   internal error 09 - Command Reject */
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "09");
 
 		erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 	}
@@ -1061,7 +1072,7 @@ dasd_3990_erp_bus_out(struct dasd_ccw_re
 	} else {
 
 		/* issue a message and wait for 'device ready' interrupt */
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "bus out parity error or BOPC requested by "
 			    "channel");
 
@@ -1093,21 +1104,19 @@ dasd_3990_erp_equip_check(struct dasd_cc
 	erp->function = dasd_3990_erp_equip_check;
 
 	if (sense[1] & SNS1_WRITE_INHIBITED) {
+		dev_info(&device->cdev->dev,
+			    "Write inhibited path encountered\n");
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
-			    "Write inhibited path encountered");
-
-		/* vary path offline */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Path should be varied off-line. "
-			    "This is not implemented yet \n - please report "
-			    "to linux390@de.ibm.com");
+		/* vary path offline
+		   internal error 04 - Path should be varied off-line.*/
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "04");
 
 		erp = dasd_3990_erp_action_1(erp);
 
 	} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Equipment Check - " "environmental data present");
 
 		dasd_3990_handle_env_data(erp, sense);
@@ -1116,7 +1125,7 @@ dasd_3990_erp_equip_check(struct dasd_cc
 
 	} else if (sense[1] & SNS1_PERM_ERR) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Equipment Check - retry exhausted or "
 			    "undesirable");
 
@@ -1125,7 +1134,7 @@ dasd_3990_erp_equip_check(struct dasd_cc
 	} else {
 		/* all other equipment checks - Action 5 */
 		/* rest is done when retries == 0 */
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Equipment check or processing error");
 
 		erp = dasd_3990_erp_action_5(erp);
@@ -1156,9 +1165,9 @@ dasd_3990_erp_data_check(struct dasd_ccw
 	if (sense[2] & SNS2_CORRECTABLE) {	/* correctable data check */
 
 		/* issue message that the data has been corrected */
-		DEV_MESSAGE(KERN_EMERG, device, "%s",
+		dev_emerg(&device->cdev->dev,
 			    "Data recovered during retry with PCI "
-			    "fetch mode active");
+			    "fetch mode active\n");
 
 		/* not possible to handle this situation in Linux */
 		panic("No way to inform application about the possibly "
@@ -1166,7 +1175,7 @@ dasd_3990_erp_data_check(struct dasd_ccw
 
 	} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Uncorrectable data check recovered secondary "
 			    "addr of duplex pair");
 
@@ -1174,7 +1183,7 @@ dasd_3990_erp_data_check(struct dasd_ccw
 
 	} else if (sense[1] & SNS1_PERM_ERR) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Uncorrectable data check with internal "
 			    "retry exhausted");
 
@@ -1182,7 +1191,7 @@ dasd_3990_erp_data_check(struct dasd_ccw
 
 	} else {
 		/* all other data checks */
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Uncorrectable data check with retry count "
 			    "exhausted...");
 
@@ -1212,7 +1221,7 @@ dasd_3990_erp_overrun(struct dasd_ccw_re
 
 	erp->function = dasd_3990_erp_overrun;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Overrun - service overrun or overrun"
 		    " error requested by channel");
 
@@ -1243,7 +1252,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw
 
 	if (sense[2] & SNS2_ENV_DATA_PRESENT) {
 
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Track format error when destaging or "
 			    "staging data");
 
@@ -1252,8 +1261,10 @@ dasd_3990_erp_inv_format(struct dasd_ccw
 		erp = dasd_3990_erp_action_4(erp, sense);
 
 	} else {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Invalid Track Format - Fatal error");
+		/* internal error 06 - The track format is not valid*/
+		dev_err(&device->cdev->dev,
+			"An error occurred in the DASD device driver, "
+			"reason=%s\n", "06");
 
 		erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 	}
@@ -1279,8 +1290,8 @@ dasd_3990_erp_EOC(struct dasd_ccw_req *
 
 	struct dasd_device *device = default_erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s",
-		    "End-of-Cylinder - must never happen");
+	dev_err(&device->cdev->dev,
+		"The cylinder data for accessing the DASD is inconsistent\n");
 
 	/* implement action 7 - BUG */
 	return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1306,7 +1317,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_r
 
 	erp->function = dasd_3990_erp_env_data;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
 
 	dasd_3990_handle_env_data(erp, sense);
 
@@ -1339,8 +1350,8 @@ dasd_3990_erp_no_rec(struct dasd_ccw_req
 
 	struct dasd_device *device = default_erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s",
-		    "No Record Found - Fatal error ");
+	dev_err(&device->cdev->dev,
+		    "The specified record was not found\n");
 
 	return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 
@@ -1365,7 +1376,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_
 
 	struct dasd_device *device = erp->startdev;
 
-	DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+	dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+		"a hardware error\n");
 
 	return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 
@@ -1394,7 +1406,7 @@ static struct dasd_ccw_req *dasd_3990_er
 	if (cqr->block &&
 	    (cqr->block->base != cqr->startdev)) {
 		if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
-			DEV_MESSAGE(KERN_ERR, cqr->startdev,
+			DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
 				    "ERP on alias device for request %p,"
 				    " recover on base device %s", cqr,
 				    dev_name(&cqr->block->base->cdev->dev));
@@ -1511,7 +1523,7 @@ dasd_3990_erp_action_10_32(struct dasd_c
 	erp->retries = 256;
 	erp->function = dasd_3990_erp_action_10_32;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
 
 	return erp;
 
@@ -1549,7 +1561,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	char *LO_data;		/* LO_eckd_data_t */
 	struct ccw1 *ccw, *oldccw;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Write not finished because of unexpected condition");
 
 	default_erp->function = dasd_3990_erp_action_1B_32;
@@ -1561,10 +1573,16 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 		cqr = cqr->refers;
 	}
 
+	if (scsw_is_tm(&cqr->irb.scsw)) {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "32 bit sense, action 1B is not defined"
+			      " in transport mode - just retry");
+		return default_erp;
+	}
+
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Imprecise ending is set - just retry");
 
 		return default_erp;
@@ -1575,8 +1593,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	cpa = default_erp->refers->irb.scsw.cmd.cpa;
 
 	if (cpa == 0) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Unable to determine address of the CCW "
 			    "to be restarted");
 
@@ -1590,7 +1607,9 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 				     sizeof(struct LO_eckd_data), device);
 
 	if (IS_ERR(erp)) {
-		DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+		/* internal error 01 - Unable to allocate ERP */
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "01");
 		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 	}
 
@@ -1599,7 +1618,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	oldccw = cqr->cpaddr;
 	if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
 		PFX_data = cqr->data;
-		memcpy(DE_data, &PFX_data->define_extend,
+		memcpy(DE_data, &PFX_data->define_extent,
 		       sizeof(struct DE_eckd_data));
 	} else
 		memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1608,10 +1627,7 @@ dasd_3990_erp_action_1B_32(struct dasd_c
 	LO_data = erp->data + sizeof(struct DE_eckd_data);
 
 	if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "BUG - this should not happen");
-
+		/* should not */
 		return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
 	}
 
@@ -1701,7 +1717,7 @@ dasd_3990_update_1B(struct dasd_ccw_req
 	char *LO_data;		/* struct LO_eckd_data */
 	struct ccw1 *ccw;
 
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "Write not finished because of unexpected condition"
 		    " - follow on");
 
@@ -1712,10 +1728,16 @@ dasd_3990_update_1B(struct dasd_ccw_req
 		cqr = cqr->refers;
 	}
 
+	if (scsw_is_tm(&cqr->irb.scsw)) {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "32 bit sense, action 1B, update,"
+			      " in transport mode - just retry");
+		return previous_erp;
+	}
+
 	/* for imprecise ending just do default erp */
 	if (sense[1] & 0x01) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Imprecise ending is set - just retry");
 
 		previous_erp->status = DASD_CQR_FILLED;
@@ -1728,10 +1750,10 @@ dasd_3990_update_1B(struct dasd_ccw_req
 	cpa = previous_erp->irb.scsw.cmd.cpa;
 
 	if (cpa == 0) {
-
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
-			    "Unable to determine address of the CCW "
-			    "to be restarted");
+		/* internal error 02 -
+		   Unable to determine address of the CCW to be restarted */
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", "02");
 
 		previous_erp->status = DASD_CQR_FAILED;
 
@@ -1744,10 +1766,7 @@ dasd_3990_update_1B(struct dasd_ccw_req
 	LO_data = erp->data + sizeof(struct DE_eckd_data);
 
 	if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "BUG - this should not happen");
-
+		/* should not happen */
 		previous_erp->status = DASD_CQR_FAILED;
 
 		return previous_erp;
@@ -1935,14 +1954,13 @@ dasd_3990_erp_compound_config(struct das
 
 	if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
 
-		/* set to suspended duplex state then restart */
+		/* set to suspended duplex state then restart
+		   internal error 05 - Set device to suspended duplex state
+		   should be done */
 		struct dasd_device *device = erp->startdev;
-
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "Set device to suspended duplex state should be "
-			    "done!\n"
-			    "This is not implemented yet (for compound ERP)"
-			    " - please report to linux390@de.ibm.com");
+		dev_err(&device->cdev->dev,
+			"An error occurred in the DASD device driver, "
+			"reason=%s\n", "05");
 
 	}
 
@@ -2012,15 +2030,14 @@ dasd_3990_erp_handle_sim(struct dasd_dev
 {
 	/* print message according to log or message to operator mode */
 	if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
-
 		/* print SIM SRC from RefCode */
-		DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
-			    "%02x%02x%02x%02x", sense[22],
+		dev_err(&device->cdev->dev, "SIM - SRC: "
+			    "%02x%02x%02x%02x\n", sense[22],
 			    sense[23], sense[11], sense[12]);
 	} else if (sense[24] & DASD_SIM_LOG) {
 		/* print SIM SRC Refcode */
-		DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
-			    "%02x%02x%02x%02x", sense[22],
+		dev_warn(&device->cdev->dev, "log SIM - SRC: "
+			    "%02x%02x%02x%02x\n", sense[22],
 			    sense[23], sense[11], sense[12]);
 	}
 }
@@ -2063,14 +2080,14 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 		switch (sense[25]) {
 
 		case 0x00:	/* success - use default ERP for retries */
-		        DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 				    "ERP called for successful request"
 				    " - just retry");
 			break;
 
 		case 0x01:	/* fatal error */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "Retry not recommended - Fatal error");
+			dev_err(&device->cdev->dev,
+				    "ERP failed for the DASD\n");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2080,13 +2097,10 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			erp = dasd_3990_erp_int_req(erp);
 			break;
 
-		case 0x0F:  /* length mismatch during update write command */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "update write command error - should not "
-				    "happen;\n"
-				    "Please send this message together with "
-				    "the above sense data to linux390@de."
-				    "ibm.com");
+		case 0x0F:  /* length mismatch during update write command
+			       internal error 08 - update write command error*/
+			dev_err(&device->cdev->dev, "An error occurred in the "
+				"DASD device driver, reason=%s\n", "08");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2095,13 +2109,12 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			erp = dasd_3990_erp_action_10_32(erp, sense);
 			break;
 
-		case 0x15:	/* next track outside defined extend */
-			DEV_MESSAGE(KERN_ERR, device, "%s",
-				    "next track outside defined extend - "
-				    "should not happen;\n"
-				    "Please send this message together with "
-				    "the above sense data to linux390@de."
-				    "ibm.com");
+		case 0x15:	/* next track outside defined extend
+				   internal error 07 - The next track is not
+				   within the defined storage extent */
+			dev_err(&device->cdev->dev,
+				"An error occurred in the DASD device driver, "
+				"reason=%s\n", "07");
 
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
@@ -2112,9 +2125,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1C:	/* invalid data */
-			DEV_MESSAGE(KERN_EMERG, device, "%s",
+			dev_emerg(&device->cdev->dev,
 				    "Data recovered during retry with PCI "
-				    "fetch mode active");
+				    "fetch mode active\n");
 
 			/* not possible to handle this situation in Linux */
 			panic
@@ -2123,7 +2136,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1D:	/* state-change pending */
-			DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 				    "A State change pending condition exists "
 				    "for the subsystem or device");
 
@@ -2131,7 +2144,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw
 			break;
 
 		case 0x1E:	/* busy */
-                        DEV_MESSAGE(KERN_DEBUG, device, "%s",
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 				    "Busy condition exists "
 				    "for the subsystem or device");
                         erp = dasd_3990_erp_action_4(erp, sense);
@@ -2171,9 +2184,9 @@ dasd_3990_erp_control_check(struct dasd_
 {
 	struct dasd_device *device = erp->startdev;
 
-	if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
+	if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
 					   | SCHN_STAT_CHN_CTRL_CHK)) {
-		DEV_MESSAGE(KERN_DEBUG, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "channel or interface control check");
 		erp = dasd_3990_erp_action_4(erp, NULL);
 	}
@@ -2193,21 +2206,23 @@ dasd_3990_erp_control_check(struct dasd_
  *   erp_new		contens was possibly modified
  */
 static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
 {
 
 	struct dasd_ccw_req *erp_new = NULL;
-	/* sense data are located in the refers record of the */
-	/* already set up new ERP !			      */
-	char *sense = erp->refers->irb.ecw;
+	char *sense;
 
 	/* if this problem occured on an alias retry on base */
 	erp_new = dasd_3990_erp_inspect_alias(erp);
 	if (erp_new)
 		return erp_new;
 
-	/* check if no concurrent sens is available */
-	if (!erp->refers->irb.esw.esw0.erw.cons)
+	/* sense data are located in the refers record of the
+	 * already set up new ERP !
+	 * check if concurrent sens is available
+	 */
+	sense = dasd_get_sense(&erp->refers->irb);
+	if (!sense)
 		erp_new = dasd_3990_erp_control_check(erp);
 	/* distinguish between 24 and 32 byte sense data */
 	else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2231,7 +2246,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_re
  * DESCRIPTION
  *   This funtion adds an additional request block (ERP) to the head of
  *   the given cqr (or erp).
- *   This erp is initialized as an default erp (retry TIC)
+ *   For a command mode cqr the erp is initialized as an default erp
+ *   (retry TIC).
+ *   For transport mode we make a copy of the original TCW (points to
+ *   the original TCCB, TIDALs, etc.) but give it a fresh
+ *   TSB so the original sense data will not be changed.
  *
  * PARAMETER
  *   cqr		head of the current ERP-chain (or single cqr if
@@ -2239,25 +2258,35 @@ dasd_3990_erp_inspect(struct dasd_ccw_re
  * RETURN VALUES
  *   erp		pointer to new ERP-chain head
  */
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
 {
 
 	struct dasd_device *device = cqr->startdev;
 	struct ccw1 *ccw;
-
-	/* allocate additional request block */
 	struct dasd_ccw_req *erp;
+	int cplength, datasize;
+	struct tcw *tcw;
+	struct tsb *tsb;
 
-	erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
+	if (cqr->cpmode == 1) {
+		cplength = 0;
+		datasize = sizeof(struct tcw) + sizeof(struct tsb);
+	} else {
+		cplength = 2;
+		datasize = 0;
+	}
+
+	/* allocate additional request block */
+	erp = dasd_alloc_erp_request((char *) &cqr->magic,
+				     cplength, datasize, device);
 	if (IS_ERR(erp)) {
                 if (cqr->retries <= 0) {
-		        DEV_MESSAGE(KERN_ERR, device, "%s",
+			DBF_DEV_EVENT(DBF_ERR, device, "%s",
 				    "Unable to allocate ERP request");
 			cqr->status = DASD_CQR_FAILED;
                         cqr->stopclk = get_clock ();
 		} else {
-                        DEV_MESSAGE (KERN_ERR, device,
+			DBF_DEV_EVENT(DBF_ERR, device,
                                      "Unable to allocate ERP request "
 				     "(%i retries left)",
                                      cqr->retries);
@@ -2266,13 +2295,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_re
 		return cqr;
 	}
 
-	/* initialize request with default TIC to current ERP/CQR */
-	ccw = erp->cpaddr;
-	ccw->cmd_code = CCW_CMD_NOOP;
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	ccw->cmd_code = CCW_CMD_TIC;
-	ccw->cda      = (long)(cqr->cpaddr);
+	if (cqr->cpmode == 1) {
+		/* make a shallow copy of the original tcw but set new tsb */
+		erp->cpmode = 1;
+		erp->cpaddr = erp->data;
+		tcw = erp->data;
+		tsb = (struct tsb *) &tcw[1];
+		*tcw = *((struct tcw *)cqr->cpaddr);
+		tcw->tsb = (long)tsb;
+	} else {
+		/* initialize request with default TIC to current ERP/CQR */
+		ccw = erp->cpaddr;
+		ccw->cmd_code = CCW_CMD_NOOP;
+		ccw->flags = CCW_FLAG_CC;
+		ccw++;
+		ccw->cmd_code = CCW_CMD_TIC;
+		ccw->cda      = (long)(cqr->cpaddr);
+	}
+
 	erp->function = dasd_3990_erp_add_erp;
 	erp->refers   = cqr;
 	erp->startdev = device;
@@ -2282,7 +2322,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_re
 	erp->expires  = 0;
 	erp->retries  = 256;
 	erp->buildclk = get_clock();
-
 	erp->status = DASD_CQR_FILLED;
 
 	return erp;
@@ -2340,28 +2379,33 @@ dasd_3990_erp_additional_erp(struct dasd
  *   match		'boolean' for match found
  *			returns 1 if match found, otherwise 0.
  */
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
+				     struct dasd_ccw_req *cqr2)
 {
+	char *sense1, *sense2;
 
 	if (cqr1->startdev != cqr2->startdev)
 		return 0;
 
-	if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
-		return 0;
+	sense1 = dasd_get_sense(&cqr1->irb);
+	sense2 = dasd_get_sense(&cqr2->irb);
 
-	if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
-	    (cqr2->irb.esw.esw0.erw.cons == 0))	{
-		if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
-					     SCHN_STAT_CHN_CTRL_CHK)) ==
-		    (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
-					     SCHN_STAT_CHN_CTRL_CHK)))
+	/* one request has sense data, the other not -> no match, return 0 */
+	if (!sense1 != !sense2)
+		return 0;
+	/* no sense data in both cases -> check cstat for IFCC */
+	if (!sense1 && !sense2)	{
+		if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+						    SCHN_STAT_CHN_CTRL_CHK)) ==
+		    (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+						    SCHN_STAT_CHN_CTRL_CHK)))
 			return 1; /* match with ifcc*/
 	}
 	/* check sense data; byte 0-2,25,27 */
-	if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
-	      (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
-	      (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+	if (!(sense1 && sense2 &&
+	      (memcmp(sense1, sense2, 3) == 0) &&
+	      (sense1[27] == sense2[27]) &&
+	      (sense1[25] == sense2[25]))) {
 
 		return 0;	/* sense doesn't match */
 	}
@@ -2434,7 +2478,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 {
 
 	struct dasd_device *device = erp->startdev;
-	char *sense = erp->irb.ecw;
+	char *sense = dasd_get_sense(&erp->irb);
 
 	/* check for 24 byte sense ERP */
 	if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2449,7 +2493,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 		/* prepare erp for retry on different channel path */
 		erp = dasd_3990_erp_action_1(erp);
 
-		if (!(sense[2] & DASD_SENSE_BIT_0)) {
+		if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
 
 			/* issue a Diagnostic Control command with an
 			 * Inhibit Write subcommand */
@@ -2471,7 +2515,7 @@ dasd_3990_erp_further_erp(struct dasd_cc
 					break;
 				}
 			default:
-				DEV_MESSAGE(KERN_DEBUG, device,
+				DBF_DEV_EVENT(DBF_WARNING, device,
 					    "invalid subcommand modifier 0x%x "
 					    "for Diagnostic Control Command",
 					    sense[25]);
@@ -2479,19 +2523,21 @@ dasd_3990_erp_further_erp(struct dasd_cc
 		}
 
 		/* check for 32 byte sense ERP */
-	} else if ((erp->function == dasd_3990_erp_compound_retry) ||
-		   (erp->function == dasd_3990_erp_compound_path) ||
-		   (erp->function == dasd_3990_erp_compound_code) ||
-		   (erp->function == dasd_3990_erp_compound_config)) {
+	} else if (sense &&
+		   ((erp->function == dasd_3990_erp_compound_retry) ||
+		    (erp->function == dasd_3990_erp_compound_path) ||
+		    (erp->function == dasd_3990_erp_compound_code) ||
+		    (erp->function == dasd_3990_erp_compound_config))) {
 
 		erp = dasd_3990_erp_compound(erp, sense);
 
 	} else {
-		/* No retry left and no additional special handling */
-		/*necessary */
-		DEV_MESSAGE(KERN_ERR, device,
-			    "no retries left for erp %p - "
-			    "set status to FAILED", erp);
+		/*
+		 * No retry left and no additional special handling
+		 * necessary
+		 */
+		dev_err(&device->cdev->dev,
+			"ERP %p has run out of retries and failed\n", erp);
 
 		erp->status = DASD_CQR_FAILED;
 	}
@@ -2548,24 +2594,25 @@ dasd_3990_erp_handle_match_erp(struct da
 
 	if (erp->retries > 0) {
 
-		char *sense = erp->refers->irb.ecw;
+		char *sense = dasd_get_sense(&erp->refers->irb);
 
 		/* check for special retries */
-		if (erp->function == dasd_3990_erp_action_4) {
+		if (sense && erp->function == dasd_3990_erp_action_4) {
 
 			erp = dasd_3990_erp_action_4(erp, sense);
 
-		} else if (erp->function == dasd_3990_erp_action_1B_32) {
+		} else if (sense &&
+			   erp->function == dasd_3990_erp_action_1B_32) {
 
 			erp = dasd_3990_update_1B(erp, sense);
 
-		} else if (erp->function == dasd_3990_erp_int_req) {
+		} else if (sense && erp->function == dasd_3990_erp_int_req) {
 
 			erp = dasd_3990_erp_int_req(erp);
 
 		} else {
 			/* simple retry	  */
-			DEV_MESSAGE(KERN_DEBUG, device,
+			DBF_DEV_EVENT(DBF_DEBUG, device,
 				    "%i retries left for erp %p",
 				    erp->retries, erp);
 
@@ -2609,24 +2656,24 @@ dasd_3990_erp_action(struct dasd_ccw_req
 
 	if (device->features & DASD_FEATURE_ERPLOG) {
 		/* print current erp_chain */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "ERP chain at BEGINNING of ERP-ACTION");
+		dev_err(&device->cdev->dev,
+			    "ERP chain at BEGINNING of ERP-ACTION\n");
 		for (temp_erp = cqr;
 		     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-			DEV_MESSAGE(KERN_ERR, device,
-				    "   erp %p (%02x) refers to %p",
+			dev_err(&device->cdev->dev,
+				    "ERP %p (%02x) refers to %p\n",
 				    temp_erp, temp_erp->status,
 				    temp_erp->refers);
 		}
 	}
 
 	/* double-check if current erp/cqr was successful */
-	if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
-	    (cqr->irb.scsw.cmd.dstat ==
+	if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+	    (scsw_dstat(&cqr->irb.scsw) ==
 	     (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
 
-		DEV_MESSAGE(KERN_DEBUG, device,
+		DBF_DEV_EVENT(DBF_DEBUG, device,
 			    "ERP called for successful request %p"
 			    " - NO ERP necessary", cqr);
 
@@ -2648,13 +2695,13 @@ dasd_3990_erp_action(struct dasd_ccw_req
 
 	if (device->features & DASD_FEATURE_ERPLOG) {
 		/* print current erp_chain */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
-			    "ERP chain at END of ERP-ACTION");
+		dev_err(&device->cdev->dev,
+			    "ERP chain at END of ERP-ACTION\n");
 		for (temp_erp = erp;
 		     temp_erp != NULL; temp_erp = temp_erp->refers) {
 
-			DEV_MESSAGE(KERN_ERR, device,
-				    "   erp %p (%02x) refers to %p",
+			dev_err(&device->cdev->dev,
+				    "ERP %p (%02x) refers to %p\n",
 				    temp_erp, temp_erp->status,
 				    temp_erp->refers);
 		}
@@ -2667,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req
 		list_add_tail(&erp->blocklist, &cqr->blocklist);
 	}
 
+
+
 	return erp;
 
 }				/* end dasd_3990_erp_action */
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_alias.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_alias.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_alias.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_alias.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,6 +5,8 @@
  * Author(s): Stefan Weinhuber <wein@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/list.h>
 #include <asm/ebcdic.h>
 #include "dasd_int.h"
@@ -503,7 +505,7 @@ static void lcu_update_work(struct work_
 	 */
 	spin_lock_irqsave(&lcu->lock, flags);
 	if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
-		DEV_MESSAGE(KERN_WARNING, device, "could not update"
+		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
 			    " alias data in lcu (rc = %d), retry later", rc);
 		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
 	} else {
@@ -646,14 +648,16 @@ static int reset_summary_unit_check(stru
 {
 	struct dasd_ccw_req *cqr;
 	int rc = 0;
+	struct ccw1 *ccw;
 
 	cqr = lcu->rsu_cqr;
 	strncpy((char *) &cqr->magic, "ECKD", 4);
 	ASCEBC((char *) &cqr->magic, 4);
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
-	cqr->cpaddr->flags = 0 ;
-	cqr->cpaddr->count = 16;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+	ccw->flags = 0 ;
+	ccw->count = 16;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	((char *)cqr->data)[0] = reason;
 
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,16 +859,25 @@ void dasd_alias_handle_summary_unit_chec
 	struct alias_lcu *lcu;
 	char reason;
 	struct dasd_eckd_private *private;
+	char *sense;
 
 	private = (struct dasd_eckd_private *) device->private;
 
-	reason = irb->ecw[8];
-	DEV_MESSAGE(KERN_WARNING, device, "%s %x",
-		    "eckd handle summary unit check: reason", reason);
+	sense = dasd_get_sense(irb);
+	if (sense) {
+		reason = sense[8];
+		DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
+			    "eckd handle summary unit check: reason", reason);
+	} else {
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			    "eckd handle summary unit check:"
+			    " no reason code available");
+		return;
+	}
 
 	lcu = private->lcu;
 	if (!lcu) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "device not ready to handle summary"
 			    " unit check (no lcu structure)");
 		return;
@@ -877,7 +890,7 @@ void dasd_alias_handle_summary_unit_chec
 	 * the next interrupt on a different device
 	 */
 	if (list_empty(&device->alias_list)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "device is in offline processing,"
 			    " don't do summary unit check handling");
 		spin_unlock(&lcu->lock);
@@ -885,7 +898,7 @@ void dasd_alias_handle_summary_unit_chec
 	}
 	if (lcu->suc_data.device) {
 		/* already scheduled or running */
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "previous instance of summary unit check worker"
 			    " still pending");
 		spin_unlock(&lcu->lock);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,9 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -17,11 +20,13 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 #include <linux/hdreg.h>
+#include <linux/async.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
 #include <asm/todclk.h>
+#include <asm/itcw.h>
 
 /* This is ugly... */
 #define PRINTK_HEADER "dasd:"
@@ -221,7 +226,7 @@ static int dasd_state_known_to_basic(str
 			return rc;
 	}
 	/* register 'device' debug area, used for all DBF_DEV_XXX calls */
-	device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
+	device->debug_area = debug_register(dev_name(&device->cdev->dev), 4, 1,
 					    8 * sizeof(long));
 	debug_register_view(device->debug_area, &debug_sprintf_view);
 	debug_set_level(device->debug_area, DBF_WARNING);
@@ -476,8 +481,10 @@ static void dasd_change_state(struct das
         if (rc && rc != -EAGAIN)
                 device->target = device->state;
 
-	if (device->state == device->target)
+	if (device->state == device->target) {
 		wake_up(&dasd_init_waitq);
+		dasd_put_device(device);
+	}
 
 	/* let user-space know that the device status changed */
 	kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
@@ -509,12 +516,15 @@ void dasd_kick_device(struct dasd_device
  */
 void dasd_set_target_state(struct dasd_device *device, int target)
 {
+	dasd_get_device(device);
 	/* If we are in probeonly mode stop at DASD_STATE_READY. */
 	if (dasd_probeonly && target > DASD_STATE_READY)
 		target = DASD_STATE_READY;
 	if (device->target != target) {
-                if (device->state == target)
+		if (device->state == target) {
 			wake_up(&dasd_init_waitq);
+			dasd_put_device(device);
+		}
 		device->target = target;
 	}
 	if (device->state != device->target)
@@ -762,7 +772,7 @@ static inline int dasd_check_cqr(struct
 		return -EINVAL;
 	device = cqr->startdev;
 	if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) {
-		DEV_MESSAGE(KERN_WARNING, device,
+		DBF_DEV_EVENT(DBF_WARNING, device,
 			    " dasd_ccw_req 0x%08x magic doesn't match"
 			    " discipline 0x%08x",
 			    cqr->magic,
@@ -782,6 +792,7 @@ int dasd_term_IO(struct dasd_ccw_req *cq
 {
 	struct dasd_device *device;
 	int retries, rc;
+	char errorstring[ERRORLENGTH];
 
 	/* Check the cqr */
 	rc = dasd_check_cqr(cqr);
@@ -815,10 +826,10 @@ int dasd_term_IO(struct dasd_ccw_req *cq
 				      "device busy, retry later");
 			break;
 		default:
-			DEV_MESSAGE(KERN_ERR, device,
-				    "line %d unknown RC=%d, please "
-				    "report to linux390@de.ibm.com",
-				    __LINE__, rc);
+			/* internal error 10 - unknown rc*/
+			snprintf(errorstring, ERRORLENGTH, "10 %d", rc);
+			dev_err(&device->cdev->dev, "An error occurred in the "
+				"DASD device driver, reason=%s\n", errorstring);
 			BUG();
 			break;
 		}
@@ -836,6 +847,7 @@ int dasd_start_IO(struct dasd_ccw_req *c
 {
 	struct dasd_device *device;
 	int rc;
+	char errorstring[ERRORLENGTH];
 
 	/* Check the cqr */
 	rc = dasd_check_cqr(cqr);
@@ -843,17 +855,23 @@ int dasd_start_IO(struct dasd_ccw_req *c
 		return rc;
 	device = (struct dasd_device *) cqr->startdev;
 	if (cqr->retries < 0) {
-		DEV_MESSAGE(KERN_DEBUG, device,
-			    "start_IO: request %p (%02x/%i) - no retry left.",
-			    cqr, cqr->status, cqr->retries);
+		/* internal error 14 - start_IO run out of retries */
+		sprintf(errorstring, "14 %p", cqr);
+		dev_err(&device->cdev->dev, "An error occurred in the DASD "
+			"device driver, reason=%s\n", errorstring);
 		cqr->status = DASD_CQR_ERROR;
 		return -EIO;
 	}
 	cqr->startclk = get_clock();
 	cqr->starttime = jiffies;
 	cqr->retries--;
-	rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
-			      cqr->lpm, 0);
+	if (cqr->cpmode == 1) {
+		rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+					 (long) cqr, cqr->lpm);
+	} else {
+		rc = ccw_device_start(device->cdev, cqr->cpaddr,
+				      (long) cqr, cqr->lpm, 0);
+	}
 	switch (rc) {
 	case 0:
 		cqr->status = DASD_CQR_IN_IO;
@@ -862,11 +880,11 @@ int dasd_start_IO(struct dasd_ccw_req *c
 			      cqr);
 		break;
 	case -EBUSY:
-		DBF_DEV_EVENT(DBF_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 			      "start_IO: device busy, retry later");
 		break;
 	case -ETIMEDOUT:
-		DBF_DEV_EVENT(DBF_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 			      "start_IO: request timeout, retry later");
 		break;
 	case -EACCES:
@@ -876,19 +894,24 @@ int dasd_start_IO(struct dasd_ccw_req *c
 		 * Do a retry with all available pathes.
 		 */
 		cqr->lpm = LPM_ANYPATH;
-		DBF_DEV_EVENT(DBF_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
 			      "start_IO: selected pathes gone,"
 			      " retry on all pathes");
 		break;
 	case -ENODEV:
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+			      "start_IO: -ENODEV device gone, retry");
+		break;
 	case -EIO:
-		DBF_DEV_EVENT(DBF_ERR, device, "%s",
-			      "start_IO: device gone, retry");
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+			      "start_IO: -EIO device gone, retry");
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, device,
-			    "line %d unknown RC=%d, please report"
-			    " to linux390@de.ibm.com", __LINE__, rc);
+		/* internal error 11 - unknown rc */
+		snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
+		dev_err(&device->cdev->dev,
+			"An error occurred in the DASD device driver, "
+			"reason=%s\n", errorstring);
 		BUG();
 		break;
 	}
@@ -945,7 +968,7 @@ static void dasd_handle_killed_request(s
 		return;
 	cqr = (struct dasd_ccw_req *) intparm;
 	if (cqr->status != DASD_CQR_IN_IO) {
-		MESSAGE(KERN_DEBUG,
+		DBF_EVENT(DBF_DEBUG,
 			"invalid status in handle_killed_request: "
 			"bus_id %s, status %02x",
 			dev_name(&cdev->dev), cqr->status);
@@ -956,8 +979,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)) {
-		MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
-			dev_name(&cdev->dev));
+		DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+			      "bus_id %s", dev_name(&cdev->dev));
 		return;
 	}
 
@@ -996,11 +1019,11 @@ void dasd_int_handler(struct ccw_device
 		case -EIO:
 			break;
 		case -ETIMEDOUT:
-			printk(KERN_WARNING"%s(%s): request timed out\n",
+			DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
 			       __func__, dev_name(&cdev->dev));
 			break;
 		default:
-			printk(KERN_WARNING"%s(%s): unknown error %ld\n",
+			DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
 			       __func__, dev_name(&cdev->dev), PTR_ERR(irb));
 		}
 		dasd_handle_killed_request(cdev, intparm);
@@ -1009,15 +1032,11 @@ void dasd_int_handler(struct ccw_device
 
 	now = get_clock();
 
-	DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
-		  dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
-		  irb->scsw.cmd.dstat), (unsigned int) intparm);
-
 	/* check for unsolicited interrupts */
 	cqr = (struct dasd_ccw_req *) intparm;
-	if (!cqr || ((irb->scsw.cmd.cc == 1) &&
-		     (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
-		     (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
+	if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
+		     (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+		     (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
 		if (cqr && cqr->status == DASD_CQR_IN_IO)
 			cqr->status = DASD_CQR_QUEUED;
 		device = dasd_device_from_cdev_locked(cdev);
@@ -1033,14 +1052,14 @@ void dasd_int_handler(struct ccw_device
 	device = (struct dasd_device *) cqr->startdev;
 	if (!device ||
 	    strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
-			dev_name(&cdev->dev));
+		DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+			      "bus_id %s", dev_name(&cdev->dev));
 		return;
 	}
 
 	/* Check for clear pending */
 	if (cqr->status == DASD_CQR_CLEAR_PENDING &&
-	    irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
+	    scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
 		cqr->status = DASD_CQR_CLEARED;
 		dasd_device_clear_timer(device);
 		wake_up(&dasd_flush_wq);
@@ -1048,19 +1067,17 @@ void dasd_int_handler(struct ccw_device
 		return;
 	}
 
- 	/* check status - the request might have been killed by dyn detach */
+	/* check status - the request might have been killed by dyn detach */
 	if (cqr->status != DASD_CQR_IN_IO) {
-		MESSAGE(KERN_DEBUG,
-			"invalid status: bus_id %s, status %02x",
-			dev_name(&cdev->dev), cqr->status);
+		DBF_DEV_EVENT(DBF_DEBUG, device, "invalid status: bus_id %s, "
+			      "status %02x", dev_name(&cdev->dev), cqr->status);
 		return;
 	}
-	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
-		      ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
+
 	next = NULL;
 	expires = 0;
-	if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
-	    irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
+	if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+	    scsw_cstat(&irb->scsw) == 0) {
 		/* request was completed successfully */
 		cqr->status = DASD_CQR_SUCCESS;
 		cqr->stopclk = now;
@@ -1071,18 +1088,23 @@ void dasd_int_handler(struct ccw_device
 		}
 	} else {  /* error */
 		memcpy(&cqr->irb, irb, sizeof(struct irb));
+		/* log sense for every failed I/O to s390 debugfeature */
+		dasd_log_sense_dbf(cqr, irb);
 		if (device->features & DASD_FEATURE_ERPLOG) {
 			dasd_log_sense(cqr, irb);
 		}
+
 		/*
 		 * If we don't want complex ERP for this request, then just
 		 * reset this and retry it in the fastpath
 		 */
 		if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
 		    cqr->retries > 0) {
-			DEV_MESSAGE(KERN_DEBUG, device,
-				    "default ERP in fastpath (%i retries left)",
-				    cqr->retries);
+			if (cqr->lpm == LPM_ANYPATH)
+				DBF_DEV_EVENT(DBF_DEBUG, device,
+					      "default ERP in fastpath "
+					      "(%i retries left)",
+					      cqr->retries);
 			cqr->lpm    = LPM_ANYPATH;
 			cqr->status = DASD_CQR_QUEUED;
 			next = cqr;
@@ -1093,10 +1115,6 @@ void dasd_int_handler(struct ccw_device
 	    (!device->stopped)) {
 		if (device->discipline->start_IO(next) == 0)
 			expires = next->expires;
-		else
-			DEV_MESSAGE(KERN_DEBUG, device, "%s",
-				    "Interrupt fastpath "
-				    "failed!");
 	}
 	if (expires != 0)
 		dasd_device_set_timer(device, expires);
@@ -1169,6 +1187,7 @@ static void __dasd_device_process_final_
 	struct dasd_block *block;
 	void (*callback)(struct dasd_ccw_req *, void *data);
 	void *callback_data;
+	char errorstring[ERRORLENGTH];
 
 	list_for_each_safe(l, n, final_queue) {
 		cqr = list_entry(l, struct dasd_ccw_req, devlist);
@@ -1189,10 +1208,11 @@ static void __dasd_device_process_final_
 			cqr->status = DASD_CQR_TERMINATED;
 			break;
 		default:
-			DEV_MESSAGE(KERN_ERR, device,
-				    "wrong cqr status in __dasd_process_final_queue "
-				    "for cqr %p, status %x",
-				    cqr, cqr->status);
+			/* internal error 12 - wrong cqr status*/
+			snprintf(errorstring, ERRORLENGTH, "12 %p %x02", cqr, cqr->status);
+			dev_err(&device->cdev->dev,
+				"An error occurred in the DASD device driver, "
+				"reason=%s\n", errorstring);
 			BUG();
 		}
 		if (cqr->callback != NULL)
@@ -1217,18 +1237,17 @@ static void __dasd_device_check_expire(s
 	    (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
 		if (device->discipline->term_IO(cqr) != 0) {
 			/* Hmpf, try again in 5 sec */
-			DEV_MESSAGE(KERN_ERR, device,
-				    "internal error - timeout (%is) expired "
-				    "for cqr %p, termination failed, "
-				    "retrying in 5s",
-				    (cqr->expires/HZ), cqr);
+			dev_err(&device->cdev->dev,
+				"cqr %p timed out (%is) but cannot be "
+				"ended, retrying in 5 s\n",
+				cqr, (cqr->expires/HZ));
 			cqr->expires += 5*HZ;
 			dasd_device_set_timer(device, 5*HZ);
 		} else {
-			DEV_MESSAGE(KERN_ERR, device,
-				    "internal error - timeout (%is) expired "
-				    "for cqr %p (%i retries left)",
-				    (cqr->expires/HZ), cqr, cqr->retries);
+			dev_err(&device->cdev->dev,
+				"cqr %p timed out (%is), %i retries "
+				"remaining\n", cqr, (cqr->expires/HZ),
+				cqr->retries);
 		}
 	}
 }
@@ -1290,10 +1309,9 @@ int dasd_flush_device_queue(struct dasd_
 			rc = device->discipline->term_IO(cqr);
 			if (rc) {
 				/* unable to terminate requeust */
-				DEV_MESSAGE(KERN_ERR, device,
-					    "dasd flush ccw_queue is unable "
-					    " to terminate request %p",
-					    cqr);
+				dev_err(&device->cdev->dev,
+					"Flushing the DASD request queue "
+					"failed for request %p\n", cqr);
 				/* stop flush processing */
 				goto finished;
 			}
@@ -1537,10 +1555,9 @@ int dasd_cancel_req(struct dasd_ccw_req
 		/* request in IO - terminate IO and release again */
 		rc = device->discipline->term_IO(cqr);
 		if (rc) {
-			DEV_MESSAGE(KERN_ERR, device,
-				    "dasd_cancel_req is unable "
-				    " to terminate request %p, rc = %d",
-				    cqr, rc);
+			dev_err(&device->cdev->dev,
+				"Cancelling request %p failed with rc=%d\n",
+				cqr, rc);
 		} else {
 			cqr->stopclk = get_clock();
 			rc = 1;
@@ -1617,7 +1634,7 @@ static inline void __dasd_block_process_
 	if (cqr->status == DASD_CQR_DONE)
 		DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
 	else
-		DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful");
+		dev_err(&device->cdev->dev, "ERP failed for the DASD\n");
 	erp_fn = device->discipline->erp_postaction(cqr);
 	erp_fn(cqr);
 }
@@ -1991,8 +2008,11 @@ static void dasd_setup_queue(struct dasd
 	blk_queue_max_sectors(block->request_queue, max);
 	blk_queue_max_phys_segments(block->request_queue, -1L);
 	blk_queue_max_hw_segments(block->request_queue, -1L);
-	blk_queue_max_segment_size(block->request_queue, -1L);
-	blk_queue_segment_boundary(block->request_queue, -1L);
+	/* with page sized segments we can translate each segement into
+	 * one idaw/tidaw
+	 */
+	blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
+	blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
 	blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
 }
 
@@ -2043,8 +2063,9 @@ static int dasd_open(struct block_device
 	}
 
 	if (dasd_probeonly) {
-		DEV_MESSAGE(KERN_INFO, base, "%s",
-			    "No access to device due to probeonly mode");
+		dev_info(&base->cdev->dev,
+			 "Accessing the DASD failed because it is in "
+			 "probeonly mode\n");
 		rc = -EPERM;
 		goto out;
 	}
@@ -2101,7 +2122,8 @@ dasd_device_operations = {
 	.owner		= THIS_MODULE,
 	.open		= dasd_open,
 	.release	= dasd_release,
-	.locked_ioctl	= dasd_ioctl,
+	.ioctl		= dasd_ioctl,
+	.compat_ioctl	= dasd_ioctl,
 	.getgeo		= dasd_getgeo,
 };
 
@@ -2132,6 +2154,22 @@ dasd_exit(void)
  * SECTION: common functions for ccw_driver use
  */
 
+static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
+{
+	struct ccw_device *cdev = data;
+	int ret;
+
+	ret = ccw_device_set_online(cdev);
+	if (ret)
+		pr_warning("%s: Setting the DASD online failed with rc=%d\n",
+			   dev_name(&cdev->dev), ret);
+	else {
+		struct dasd_device *device = dasd_device_from_cdev(cdev);
+		wait_event(dasd_init_waitq, _wait_for_device(device));
+		dasd_put_device(device);
+	}
+}
+
 /*
  * Initial attempt at a probe function. this can be simplified once
  * the other detection code is gone.
@@ -2143,14 +2181,14 @@ int dasd_generic_probe(struct ccw_device
 
 	ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
 	if (ret) {
-		printk(KERN_WARNING
+		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) {
-		printk(KERN_WARNING
+		DBF_EVENT(DBF_WARNING,
 		       "dasd_generic_probe: could not add sysfs entries "
 		       "for %s\n", dev_name(&cdev->dev));
 		return ret;
@@ -2164,12 +2202,7 @@ int dasd_generic_probe(struct ccw_device
 	 */
 	if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
 	    (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
-		ret = ccw_device_set_online(cdev);
-	if (ret)
-		printk(KERN_WARNING
-		       "dasd_generic_probe: could not initially "
-		       "online ccw-device %s; return code: %d\n",
-		       dev_name(&cdev->dev), ret);
+		async_schedule(dasd_generic_auto_online, cdev);
 	return 0;
 }
 
@@ -2232,10 +2265,9 @@ int dasd_generic_set_online(struct ccw_d
 	discipline = base_discipline;
 	if (device->features & DASD_FEATURE_USEDIAG) {
 	  	if (!dasd_diag_discipline_pointer) {
-		        printk (KERN_WARNING
-				"dasd_generic couldn't online device %s "
-				"- discipline DIAG not available\n",
-				dev_name(&cdev->dev));
+			pr_warning("%s Setting the DASD online failed because "
+				   "of missing DIAG discipline\n",
+				   dev_name(&cdev->dev));
 			dasd_delete_device(device);
 			return -ENODEV;
 		}
@@ -2256,10 +2288,9 @@ int dasd_generic_set_online(struct ccw_d
 	/* check_device will allocate block device if necessary */
 	rc = discipline->check_device(device);
 	if (rc) {
-		printk (KERN_WARNING
-			"dasd_generic couldn't online device %s "
-			"with discipline %s rc=%i\n",
-			dev_name(&cdev->dev), discipline->name, rc);
+		pr_warning("%s Setting the DASD online with discipline %s "
+			   "failed with rc=%i\n",
+			   dev_name(&cdev->dev), discipline->name, rc);
 		module_put(discipline->owner);
 		module_put(base_discipline->owner);
 		dasd_delete_device(device);
@@ -2268,9 +2299,8 @@ int dasd_generic_set_online(struct ccw_d
 
 	dasd_set_target_state(device, DASD_STATE_ONLINE);
 	if (device->state <= DASD_STATE_KNOWN) {
-		printk (KERN_WARNING
-			"dasd_generic discipline not found for %s\n",
-			dev_name(&cdev->dev));
+		pr_warning("%s Setting the DASD online failed because of a "
+			   "missing discipline\n", dev_name(&cdev->dev));
 		rc = -ENODEV;
 		dasd_set_target_state(device, DASD_STATE_NEW);
 		if (device->block)
@@ -2279,13 +2309,7 @@ int dasd_generic_set_online(struct ccw_d
 	} else
 		pr_debug("dasd_generic device %s found\n",
 				dev_name(&cdev->dev));
-
-	/* FIXME: we have to wait for the root device but we don't want
-	 * to wait for each single device but for all at once. */
-	wait_event(dasd_init_waitq, _wait_for_device(device));
-
 	dasd_put_device(device);
-
 	return rc;
 }
 
@@ -2314,13 +2338,13 @@ int dasd_generic_set_offline(struct ccw_
 		open_count = atomic_read(&device->block->open_count);
 		if (open_count > max_count) {
 			if (open_count > 0)
-				printk(KERN_WARNING "Can't offline dasd "
-				       "device with open count = %i.\n",
-				       open_count);
+				pr_warning("%s: The DASD cannot be set offline "
+					   "with open count %i\n",
+					   dev_name(&cdev->dev), open_count);
 			else
-				printk(KERN_WARNING "%s",
-				       "Can't offline dasd device due "
-				       "to internal use\n");
+				pr_warning("%s: The DASD cannot be set offline "
+					   "while it is in use\n",
+					   dev_name(&cdev->dev));
 			clear_bit(DASD_FLAG_OFFLINE, &device->flags);
 			dasd_put_device(device);
 			return -EBUSY;
@@ -2352,6 +2376,7 @@ int dasd_generic_notify(struct ccw_devic
 	ret = 0;
 	switch (event) {
 	case CIO_GONE:
+	case CIO_BOXED:
 	case CIO_NO_PATH:
 		/* First of all call extended error reporting. */
 		dasd_eer_write(device, NULL, DASD_EER_NOPATH);
@@ -2393,8 +2418,10 @@ static struct dasd_ccw_req *dasd_generic
 	cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
 
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Could not allocate RDC request");
+		/* internal error 13 - Allocating the RDC request failed*/
+		dev_err(&device->cdev->dev,
+			 "An error occurred in the DASD device driver, "
+			 "reason=%s\n", "13");
 		return cqr;
 	}
 
@@ -2431,6 +2458,40 @@ int dasd_generic_read_dev_chars(struct d
 }
 EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
 
+/*
+ *   In command mode and transport mode we need to look for sense
+ *   data in different places. The sense data itself is allways
+ *   an array of 32 bytes, so we can unify the sense data access
+ *   for both modes.
+ */
+char *dasd_get_sense(struct irb *irb)
+{
+	struct tsb *tsb = NULL;
+	char *sense = NULL;
+
+	if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
+		if (irb->scsw.tm.tcw)
+			tsb = tcw_get_tsb((struct tcw *)(unsigned long)
+					  irb->scsw.tm.tcw);
+		if (tsb && tsb->length == 64 && tsb->flags)
+			switch (tsb->flags & 0x07) {
+			case 1:	/* tsa_iostat */
+				sense = tsb->tsa.iostat.sense;
+				break;
+			case 2: /* tsa_ddpc */
+				sense = tsb->tsa.ddpc.sense;
+				break;
+			default:
+				/* currently we don't use interrogate data */
+				break;
+			}
+	} else if (irb->esw.esw0.erw.cons) {
+		sense = irb->ecw;
+	}
+	return sense;
+}
+EXPORT_SYMBOL_GPL(dasd_get_sense);
+
 static int __init dasd_init(void)
 {
 	int rc;
@@ -2472,7 +2533,7 @@ static int __init dasd_init(void)
 
 	return 0;
 failed:
-	MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
+	pr_info("The DASD device driver could not be initialized\n");
 	dasd_exit();
 	return rc;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_devmap.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_devmap.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_devmap.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_devmap.c	2009-06-09 23:05:27.000000000 -0400
@@ -13,6 +13,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -67,6 +69,8 @@ int dasd_probeonly =  0;	/* is true, whe
 int dasd_autodetect = 0;	/* is true, when autodetection is active */
 int dasd_nopav = 0;		/* is true, when PAV is disabled */
 EXPORT_SYMBOL_GPL(dasd_nopav);
+int dasd_nofcx;			/* disable High Performance Ficon */
+EXPORT_SYMBOL_GPL(dasd_nofcx);
 
 /*
  * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -125,6 +129,7 @@ __setup ("dasd=", dasd_call_setup);
  * Read a device busid/devno from a string.
  */
 static int
+
 dasd_busid(char **str, int *id0, int *id1, int *devno)
 {
 	int val, old_style;
@@ -132,8 +137,7 @@ dasd_busid(char **str, int *id0, int *id
 	/* Interpret ipldev busid */
 	if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
 		if (ipl_info.type != IPL_TYPE_CCW) {
-			MESSAGE(KERN_ERR, "%s", "ipl device is not a ccw "
-				"device");
+			pr_err("The IPL device is not a CCW device\n");
 			return -EINVAL;
 		}
 		*id0 = 0;
@@ -209,9 +213,8 @@ dasd_feature_list(char *str, char **endp
 		else if (len == 8 && !strncmp(str, "failfast", 8))
 			features |= DASD_FEATURE_FAILFAST;
 		else {
-			MESSAGE(KERN_WARNING,
-				"unsupported feature: %*s, "
-				"ignoring setting", len, str);
+			pr_warning("%*s is not a supported device option\n",
+				   len, str);
 			rc = -EINVAL;
 		}
 		str += len;
@@ -220,8 +223,8 @@ dasd_feature_list(char *str, char **endp
 		str++;
 	}
 	if (*str != ')') {
-		MESSAGE(KERN_WARNING, "%s",
-			"missing ')' in dasd parameter string\n");
+		pr_warning("A closing parenthesis ')' is missing in the "
+			   "dasd= parameter\n");
 		rc = -EINVAL;
 	} else
 		str++;
@@ -253,25 +256,29 @@ dasd_parse_keyword( char *parsestring )
         }
 	if (strncmp("autodetect", parsestring, length) == 0) {
 		dasd_autodetect = 1;
-		MESSAGE (KERN_INFO, "%s",
-			 "turning to autodetection mode");
+		pr_info("The autodetection mode has been activated\n");
                 return residual_str;
         }
 	if (strncmp("probeonly", parsestring, length) == 0) {
 		dasd_probeonly = 1;
-		MESSAGE(KERN_INFO, "%s",
-			"turning to probeonly mode");
+		pr_info("The probeonly mode has been activated\n");
                 return residual_str;
         }
 	if (strncmp("nopav", parsestring, length) == 0) {
 		if (MACHINE_IS_VM)
-			MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM");
+			pr_info("'nopav' is not supported on z/VM\n");
 		else {
 			dasd_nopav = 1;
-			MESSAGE(KERN_INFO, "%s", "disable PAV mode");
+			pr_info("PAV support has be deactivated\n");
 		}
 		return residual_str;
 	}
+	if (strncmp("nofcx", parsestring, length) == 0) {
+		dasd_nofcx = 1;
+		pr_info("High Performance FICON support has been "
+			"deactivated\n");
+		return residual_str;
+	}
 	if (strncmp("fixedbuffers", parsestring, length) == 0) {
 		if (dasd_page_cache)
 			return residual_str;
@@ -280,10 +287,10 @@ dasd_parse_keyword( char *parsestring )
 					  PAGE_SIZE, SLAB_CACHE_DMA,
 					  NULL);
 		if (!dasd_page_cache)
-			MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
+			DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
 				"fixed buffer mode disabled.");
 		else
-			MESSAGE (KERN_INFO, "%s",
+			DBF_EVENT(DBF_INFO, "%s",
 				 "turning on fixed buffer mode");
                 return residual_str;
         }
@@ -321,7 +328,7 @@ dasd_parse_range( char *parsestring ) {
 	    (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
 		rc = -EINVAL;
 	if (rc) {
-		MESSAGE(KERN_ERR, "Invalid device range %s", parsestring);
+		pr_err("%s is not a valid device range\n", parsestring);
 		return ERR_PTR(rc);
 	}
 	features = dasd_feature_list(str, &str);
@@ -340,8 +347,8 @@ dasd_parse_range( char *parsestring ) {
 		return str + 1;
 	if (*str == '\0')
 		return str;
-	MESSAGE(KERN_WARNING,
-		"junk at end of dasd parameter string: %s\n", str);
+	pr_warning("The dasd= parameter value %s has an invalid ending\n",
+		   str);
 	return ERR_PTR(-EINVAL);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_diag.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_diag.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_diag.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_diag.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -144,8 +146,8 @@ dasd_diag_erp(struct dasd_device *device
 	mdsk_term_io(device);
 	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
 	if (rc)
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
-			    "rc=%d", rc);
+		dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+			    "rc=%d\n", rc);
 }
 
 /* Start a given request at the device. Return zero on success, non-zero
@@ -160,7 +162,7 @@ dasd_start_diag(struct dasd_ccw_req * cq
 
 	device = cqr->startdev;
 	if (cqr->retries < 0) {
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
+		DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
 			    "- no retry left)", cqr);
 		cqr->status = DASD_CQR_ERROR;
 		return -EIO;
@@ -195,7 +197,7 @@ dasd_start_diag(struct dasd_ccw_req * cq
 		break;
 	default: /* Error condition */
 		cqr->status = DASD_CQR_QUEUED;
-		DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
+		DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
 		dasd_diag_erp(device);
 		rc = -EIO;
 		break;
@@ -243,13 +245,14 @@ dasd_ext_handler(__u16 code)
 		return;
 	}
 	if (!ip) {		/* no intparm: unsolicited interrupt */
-		MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
+		DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited "
+			      "interrupt");
 		return;
 	}
 	cqr = (struct dasd_ccw_req *) ip;
 	device = (struct dasd_device *) cqr->startdev;
 	if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		DEV_MESSAGE(KERN_WARNING, device,
+		DBF_DEV_EVENT(DBF_WARNING, device,
 			    " magic number of dasd_ccw_req 0x%08X doesn't"
 			    " match discipline 0x%08X",
 			    cqr->magic, *(int *) (&device->discipline->name));
@@ -281,15 +284,11 @@ dasd_ext_handler(__u16 code)
 				rc = dasd_start_diag(next);
 				if (rc == 0)
 					expires = next->expires;
-				else if (rc != -EACCES)
-					DEV_MESSAGE(KERN_WARNING, device, "%s",
-						    "Interrupt fastpath "
-						    "failed!");
 			}
 		}
 	} else {
 		cqr->status = DASD_CQR_QUEUED;
-		DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
+		DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
 			    "request %p was %d (%d retries left)", cqr, status,
 			    cqr->retries);
 		dasd_diag_erp(device);
@@ -322,8 +321,9 @@ dasd_diag_check_device(struct dasd_devic
 	if (private == NULL) {
 		private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				"memory allocation failed for private data");
+			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+				"Allocating memory for private DASD data "
+				      "failed\n");
 			return -ENOMEM;
 		}
 		ccw_device_get_id(device->cdev, &private->dev_id);
@@ -331,7 +331,7 @@ dasd_diag_check_device(struct dasd_devic
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "could not allocate dasd block structure");
 		device->private = NULL;
 		kfree(private);
@@ -347,7 +347,7 @@ dasd_diag_check_device(struct dasd_devic
 
 	rc = diag210((struct diag210 *) rdc_data);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
+		DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
 			    "information (rc=%d)", rc);
 		rc = -EOPNOTSUPP;
 		goto out;
@@ -362,8 +362,8 @@ dasd_diag_check_device(struct dasd_devic
 		private->pt_block = 2;
 		break;
 	default:
-		DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
-			    "(class=%d)", private->rdc_data.vdev_class);
+		dev_warn(&device->cdev->dev, "Device type %d is not supported "
+			    "in DIAG mode\n", private->rdc_data.vdev_class);
 		rc = -EOPNOTSUPP;
 		goto out;
 	}
@@ -380,7 +380,7 @@ dasd_diag_check_device(struct dasd_devic
 	/* figure out blocksize of device */
 	label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
 	if (label == NULL)  {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "No memory to allocate initialization request");
 		rc = -ENOMEM;
 		goto out;
@@ -404,8 +404,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_MESSAGE(KERN_WARNING, device, "%s",
-				"DIAG call failed");
+			dev_warn(&device->cdev->dev,
+				"A 64-bit DIAG call failed\n");
 			rc = -EOPNOTSUPP;
 			goto out_label;
 		}
@@ -414,8 +414,8 @@ dasd_diag_check_device(struct dasd_devic
 			break;
 	}
 	if (bsize > PAGE_SIZE) {
-		DEV_MESSAGE(KERN_WARNING, device, "device access failed "
-			    "(rc=%d)", rc);
+		dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
+			 " of an incorrect format (rc=%d)\n", rc);
 		rc = -EIO;
 		goto out_label;
 	}
@@ -433,15 +433,15 @@ dasd_diag_check_device(struct dasd_devic
 		block->s2b_shift++;
 	rc = mdsk_init_io(device, block->bp_block, 0, NULL);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
-			"failed (rc=%d)", rc);
+		dev_warn(&device->cdev->dev, "DIAG initialization "
+			"failed with rc=%d\n", rc);
 		rc = -EIO;
 	} else {
-		DEV_MESSAGE(KERN_INFO, device,
-			    "(%ld B/blk): %ldkB",
-			    (unsigned long) block->bp_block,
-			    (unsigned long) (block->blocks <<
-				block->s2b_shift) >> 1);
+		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);
 	}
 out_label:
 	free_page((long) label);
@@ -595,7 +595,7 @@ static void
 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *stat)
 {
-	DEV_MESSAGE(KERN_ERR, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "dump sense not available for DIAG data");
 }
 
@@ -621,10 +621,8 @@ static int __init
 dasd_diag_init(void)
 {
 	if (!MACHINE_IS_VM) {
-		MESSAGE_LOG(KERN_INFO,
-			    "Machine is not VM: %s "
-			    "discipline not initializing",
-			    dasd_diag_discipline.name);
+		pr_info("Discipline %s cannot be used without z/VM\n",
+			dasd_diag_discipline.name);
 		return -ENODEV;
 	}
 	ASCEBC(dasd_diag_discipline.ebcname, 4);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eckd.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eckd.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eckd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eckd.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -27,9 +29,12 @@
 #include <asm/uaccess.h>
 #include <asm/cio.h>
 #include <asm/ccwdev.h>
+#include <asm/itcw.h>
 
 #include "dasd_int.h"
 #include "dasd_eckd.h"
+#include "../cio/chsc.h"
+
 
 #ifdef PRINTK_HEADER
 #undef PRINTK_HEADER
@@ -84,7 +89,7 @@ dasd_eckd_probe (struct ccw_device *cdev
 	/* set ECKD specific ccw-device options */
 	ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
 	if (ret) {
-		printk(KERN_WARNING
+		DBF_EVENT(DBF_WARNING,
 		       "dasd_eckd_probe: could not set ccw-device options "
 		       "for %s\n", dev_name(&cdev->dev));
 		return ret;
@@ -159,6 +164,14 @@ recs_per_track(struct dasd_eckd_characte
 	return 0;
 }
 
+static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
+{
+	geo->cyl = (__u16) cyl;
+	geo->head = cyl >> 16;
+	geo->head <<= 4;
+	geo->head |= head;
+}
+
 static int
 check_XRC (struct ccw1         *de_ccw,
            struct DE_eckd_data *data,
@@ -186,11 +199,12 @@ check_XRC (struct ccw1         *de_ccw,
 }
 
 static int
-define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
-	      int totrk, int cmd, struct dasd_device * device)
+define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
+	      unsigned int totrk, int cmd, struct dasd_device *device)
 {
 	struct dasd_eckd_private *private;
-	struct ch_t geo, beg, end;
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
 	int rc = 0;
 
 	private = (struct dasd_eckd_private *) device->private;
@@ -236,7 +250,8 @@ define_extent(struct ccw1 * ccw, struct
 		rc = check_XRC (ccw, data, device);
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+		dev_err(&device->cdev->dev,
+			"0x%x is not a known command\n", cmd);
 		break;
 	}
 
@@ -248,27 +263,24 @@ define_extent(struct ccw1 * ccw, struct
 	    && !(private->uses_cdl && trk < 2))
 		data->ga_extended |= 0x40; /* Regular Data Format Mode */
 
-	geo.cyl = private->rdc_data.no_cyl;
-	geo.head = private->rdc_data.trk_per_cyl;
-	beg.cyl = trk / geo.head;
-	beg.head = trk % geo.head;
-	end.cyl = totrk / geo.head;
-	end.head = totrk % geo.head;
+	heads = private->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
 
 	/* check for sequential prestage - enhance cylinder range */
 	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
 	    data->attributes.operation == DASD_SEQ_ACCESS) {
 
-		if (end.cyl + private->attrib.nr_cyl < geo.cyl)
-			end.cyl += private->attrib.nr_cyl;
+		if (endcyl + private->attrib.nr_cyl < private->real_cyl)
+			endcyl += private->attrib.nr_cyl;
 		else
-			end.cyl = (geo.cyl - 1);
+			endcyl = (private->real_cyl - 1);
 	}
 
-	data->beg_ext.cyl = beg.cyl;
-	data->beg_ext.head = beg.head;
-	data->end_ext.cyl = end.cyl;
-	data->end_ext.head = end.head;
+	set_ch_t(&data->beg_ext, begcyl, beghead);
+	set_ch_t(&data->end_ext, endcyl, endhead);
 	return rc;
 }
 
@@ -283,29 +295,145 @@ static int check_XRC_on_prefix(struct PF
 		return 0;
 
 	/* switch on System Time Stamp - needed for XRC Support */
-	pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid'   */
-	pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */
+	pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid'   */
+	pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
 	pfxdata->validity.time_stamp = 1;	    /* 'Time Stamp Valid'   */
 
-	rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time);
+	rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
 	/* Ignore return code if sync clock is switched off. */
 	if (rc == -ENOSYS || rc == -EACCES)
 		rc = 0;
 	return rc;
 }
 
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
-		  int totrk, int cmd, struct dasd_device *basedev,
-		  struct dasd_device *startdev)
+static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
+			  unsigned int rec_on_trk, int count, int cmd,
+			  struct dasd_device *device, unsigned int reclen,
+			  unsigned int tlf)
+{
+	struct dasd_eckd_private *private;
+	int sector;
+	int dn, d;
+
+	private = (struct dasd_eckd_private *) device->private;
+
+	memset(data, 0, sizeof(*data));
+	sector = 0;
+	if (rec_on_trk) {
+		switch (private->rdc_data.dev_type) {
+		case 0x3390:
+			dn = ceil_quot(reclen + 6, 232);
+			d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
+			sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+			break;
+		case 0x3380:
+			d = 7 + ceil_quot(reclen + 12, 32);
+			sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+			break;
+		}
+	}
+	data->sector = sector;
+	/* note: meaning of count depends on the operation
+	 *	 for record based I/O it's the number of records, but for
+	 *	 track based I/O it's the number of tracks
+	 */
+	data->count = count;
+	switch (cmd) {
+	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x03;
+		break;
+	case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x16;
+		break;
+	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+		data->operation.orientation = 0x1;
+		data->operation.operation = 0x03;
+		data->count++;
+		break;
+	case DASD_ECKD_CCW_READ_RECORD_ZERO:
+		data->operation.orientation = 0x3;
+		data->operation.operation = 0x16;
+		data->count++;
+		break;
+	case DASD_ECKD_CCW_WRITE:
+	case DASD_ECKD_CCW_WRITE_MT:
+	case DASD_ECKD_CCW_WRITE_KD:
+	case DASD_ECKD_CCW_WRITE_KD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x01;
+		break;
+	case DASD_ECKD_CCW_WRITE_CKD:
+	case DASD_ECKD_CCW_WRITE_CKD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x03;
+		break;
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;	/* not tlf, as one might think */
+		data->operation.operation = 0x3F;
+		data->extended_operation = 0x23;
+		break;
+	case DASD_ECKD_CCW_READ:
+	case DASD_ECKD_CCW_READ_MT:
+	case DASD_ECKD_CCW_READ_KD:
+	case DASD_ECKD_CCW_READ_KD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x06;
+		break;
+	case DASD_ECKD_CCW_READ_CKD:
+	case DASD_ECKD_CCW_READ_CKD_MT:
+		data->auxiliary.length_valid = 0x1;
+		data->length = reclen;
+		data->operation.operation = 0x16;
+		break;
+	case DASD_ECKD_CCW_READ_COUNT:
+		data->operation.operation = 0x06;
+		break;
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		data->auxiliary.length_valid = 0x1;
+		data->length = tlf;
+		data->operation.operation = 0x0C;
+		break;
+	case DASD_ECKD_CCW_ERASE:
+		data->length = reclen;
+		data->auxiliary.length_valid = 0x1;
+		data->operation.operation = 0x0b;
+		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, device,
+			    "fill LRE unknown opcode 0x%x", cmd);
+		BUG();
+	}
+	set_ch_t(&data->seek_addr,
+		 trk / private->rdc_data.trk_per_cyl,
+		 trk % private->rdc_data.trk_per_cyl);
+	data->search_arg.cyl = data->seek_addr.cyl;
+	data->search_arg.head = data->seek_addr.head;
+	data->search_arg.record = rec_on_trk;
+}
+
+static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+		      unsigned int trk, unsigned int totrk, int cmd,
+		      struct dasd_device *basedev, struct dasd_device *startdev,
+		      unsigned char format, unsigned int rec_on_trk, int count,
+		      unsigned int blksize, unsigned int tlf)
 {
 	struct dasd_eckd_private *basepriv, *startpriv;
-	struct DE_eckd_data *data;
-	struct ch_t geo, beg, end;
+	struct DE_eckd_data *dedata;
+	struct LRE_eckd_data *lredata;
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
 	int rc = 0;
 
 	basepriv = (struct dasd_eckd_private *) basedev->private;
 	startpriv = (struct dasd_eckd_private *) startdev->private;
-	data = &pfxdata->define_extend;
+	dedata = &pfxdata->define_extent;
+	lredata = &pfxdata->locate_record;
 
 	ccw->cmd_code = DASD_ECKD_CCW_PFX;
 	ccw->flags = 0;
@@ -314,10 +442,16 @@ static int prefix(struct ccw1 *ccw, stru
 
 	memset(pfxdata, 0, sizeof(*pfxdata));
 	/* prefix data */
-	pfxdata->format = 0;
+	if (format > 1) {
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			      "PFX LRE unknown format 0x%x", format);
+		BUG();
+		return -EINVAL;
+	}
+	pfxdata->format = format;
 	pfxdata->base_address = basepriv->ned->unit_addr;
 	pfxdata->base_lss = basepriv->ned->ID;
-	pfxdata->validity.define_extend = 1;
+	pfxdata->validity.define_extent = 1;
 
 	/* private uid is kept up to date, conf_data may be outdated */
 	if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -337,70 +471,94 @@ static int prefix(struct ccw1 *ccw, stru
 	case DASD_ECKD_CCW_READ_KD:
 	case DASD_ECKD_CCW_READ_KD_MT:
 	case DASD_ECKD_CCW_READ_COUNT:
-		data->mask.perm = 0x1;
-		data->attributes.operation = basepriv->attrib.operation;
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		break;
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = 0;
 		break;
 	case DASD_ECKD_CCW_WRITE:
 	case DASD_ECKD_CCW_WRITE_MT:
 	case DASD_ECKD_CCW_WRITE_KD:
 	case DASD_ECKD_CCW_WRITE_KD_MT:
-		data->mask.perm = 0x02;
-		data->attributes.operation = basepriv->attrib.operation;
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
 	case DASD_ECKD_CCW_WRITE_CKD:
 	case DASD_ECKD_CCW_WRITE_CKD_MT:
-		data->attributes.operation = DASD_BYPASS_CACHE;
+		dedata->attributes.operation = DASD_BYPASS_CACHE;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
 	case DASD_ECKD_CCW_ERASE:
 	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
 	case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
-		data->mask.perm = 0x3;
-		data->mask.auth = 0x1;
-		data->attributes.operation = DASD_BYPASS_CACHE;
+		dedata->mask.perm = 0x3;
+		dedata->mask.auth = 0x1;
+		dedata->attributes.operation = DASD_BYPASS_CACHE;
 		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
-	default:
-		DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd);
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		rc = check_XRC_on_prefix(pfxdata, basedev);
 		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			    "PFX LRE unknown opcode 0x%x", cmd);
+		BUG();
+		return -EINVAL;
 	}
 
-	data->attributes.mode = 0x3;	/* ECKD */
+	dedata->attributes.mode = 0x3;	/* ECKD */
 
 	if ((basepriv->rdc_data.cu_type == 0x2105 ||
 	     basepriv->rdc_data.cu_type == 0x2107 ||
 	     basepriv->rdc_data.cu_type == 0x1750)
 	    && !(basepriv->uses_cdl && trk < 2))
-		data->ga_extended |= 0x40; /* Regular Data Format Mode */
+		dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
 
-	geo.cyl = basepriv->rdc_data.no_cyl;
-	geo.head = basepriv->rdc_data.trk_per_cyl;
-	beg.cyl = trk / geo.head;
-	beg.head = trk % geo.head;
-	end.cyl = totrk / geo.head;
-	end.head = totrk % geo.head;
+	heads = basepriv->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
 
 	/* check for sequential prestage - enhance cylinder range */
-	if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
-	    data->attributes.operation == DASD_SEQ_ACCESS) {
+	if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+	    dedata->attributes.operation == DASD_SEQ_ACCESS) {
 
-		if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
-			end.cyl += basepriv->attrib.nr_cyl;
+		if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+			endcyl += basepriv->attrib.nr_cyl;
 		else
-			end.cyl = (geo.cyl - 1);
+			endcyl = (basepriv->real_cyl - 1);
+	}
+
+	set_ch_t(&dedata->beg_ext, begcyl, beghead);
+	set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+	if (format == 1) {
+		fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
+			      basedev, blksize, tlf);
 	}
 
-	data->beg_ext.cyl = beg.cyl;
-	data->beg_ext.head = beg.head;
-	data->end_ext.cyl = end.cyl;
-	data->end_ext.head = end.head;
 	return rc;
 }
 
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+		  unsigned int trk, unsigned int totrk, int cmd,
+		  struct dasd_device *basedev, struct dasd_device *startdev)
+{
+	return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
+			  0, 0, 0, 0, 0);
+}
+
 static void
-locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
-	      int rec_on_trk, int no_rec, int cmd,
+locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
+	      unsigned int rec_on_trk, int no_rec, int cmd,
 	      struct dasd_device * device, int reclen)
 {
 	struct dasd_eckd_private *private;
@@ -491,12 +649,14 @@ locate_record(struct ccw1 *ccw, struct L
 		data->operation.operation = 0x0b;
 		break;
 	default:
-		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+		DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
+			      "opcode 0x%x", cmd);
 	}
-	data->seek_addr.cyl = data->search_arg.cyl =
-		trk / private->rdc_data.trk_per_cyl;
-	data->seek_addr.head = data->search_arg.head =
-		trk % private->rdc_data.trk_per_cyl;
+	set_ch_t(&data->seek_addr,
+		 trk / private->rdc_data.trk_per_cyl,
+		 trk % private->rdc_data.trk_per_cyl);
+	data->search_arg.cyl = data->seek_addr.cyl;
+	data->search_arg.head = data->seek_addr.head;
 	data->search_arg.record = rec_on_trk;
 }
 
@@ -585,8 +745,8 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
 
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Could not allocate RCD request");
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "Could not allocate RCD request");
 		return cqr;
 	}
 
@@ -736,14 +896,16 @@ 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 */
-				MESSAGE(KERN_WARNING,
-					"Read configuration data returned "
-					"error %d", rc);
+				DBF_EVENT(DBF_WARNING,
+					  "Read configuration data returned "
+					  "error %d for device: %s", rc,
+					  dev_name(&device->cdev->dev));
 				return rc;
 			}
 			if (conf_data == NULL) {
-				MESSAGE(KERN_WARNING, "%s", "No configuration "
-					"data retrieved");
+				DBF_EVENT(DBF_WARNING, "No configuration "
+					  "data retrieved for device: %s",
+					  dev_name(&device->cdev->dev));
 				continue;	/* no error */
 			}
 			/* save first valid configuration data */
@@ -790,8 +952,9 @@ static int dasd_eckd_read_features(struc
 				    sizeof(struct dasd_rssd_features)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Could not allocate initialization request");
+		DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
+			  "request for device: %s",
+			  dev_name(&device->cdev->dev));
 		return PTR_ERR(cqr);
 	}
 	cqr->startdev = device;
@@ -840,7 +1003,8 @@ static int dasd_eckd_read_features(struc
 /*
  * Build CP for Perform Subsystem Function - SSC.
  */
-static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
+static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
+						    int enable_pav)
 {
 	struct dasd_ccw_req *cqr;
 	struct dasd_psf_ssc_data *psf_ssc_data;
@@ -851,15 +1015,17 @@ static struct dasd_ccw_req *dasd_eckd_bu
 				  device);
 
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			   "Could not allocate PSF-SSC request");
 		return cqr;
 	}
 	psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
 	psf_ssc_data->order = PSF_ORDER_SSC;
-	psf_ssc_data->suborder = 0x88;
-	psf_ssc_data->reserved[0] = 0x88;
-
+	psf_ssc_data->suborder = 0x40;
+	if (enable_pav) {
+		psf_ssc_data->suborder |= 0x88;
+		psf_ssc_data->reserved[0] = 0x88;
+	}
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_PSF;
 	ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -880,12 +1046,12 @@ static struct dasd_ccw_req *dasd_eckd_bu
  * call might change behaviour of DASD devices.
  */
 static int
-dasd_eckd_psf_ssc(struct dasd_device *device)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
 
-	cqr = dasd_eckd_build_psf_ssc(device);
+	cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
 	if (IS_ERR(cqr))
 		return PTR_ERR(cqr);
 
@@ -904,19 +1070,20 @@ static int dasd_eckd_validate_server(str
 {
 	int rc;
 	struct dasd_eckd_private *private;
+	int enable_pav;
 
-	/* Currently PAV is the only reason to 'validate' server on LPAR */
 	if (dasd_nopav || MACHINE_IS_VM)
-		return 0;
-
-	rc = dasd_eckd_psf_ssc(device);
+		enable_pav = 0;
+	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;
-	DEV_MESSAGE(KERN_INFO, device,
-		    "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
-		    private->uid.vendor, private->uid.serial,
-		    private->uid.ssid, rc);
+	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);
 }
@@ -938,9 +1105,9 @@ dasd_eckd_check_characteristics(struct d
 		private = kzalloc(sizeof(struct dasd_eckd_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "memory allocation failed for private "
-				    "data");
+			dev_warn(&device->cdev->dev,
+				 "Allocating memory for private DASD data "
+				 "failed\n");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -965,8 +1132,9 @@ dasd_eckd_check_characteristics(struct d
 	if (private->uid.type == UA_BASE_DEVICE) {
 		block = dasd_alloc_block();
 		if (IS_ERR(block)) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "could not allocate dasd block structure");
+			DBF_EVENT(DBF_WARNING, "could not allocate dasd "
+				  "block structure for device: %s",
+				  dev_name(&device->cdev->dev));
 			rc = PTR_ERR(block);
 			goto out_err1;
 		}
@@ -997,20 +1165,27 @@ dasd_eckd_check_characteristics(struct d
 	memset(rdc_data, 0, sizeof(rdc_data));
 	rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Read device characteristics returned "
-			    "rc=%d", rc);
+		DBF_EVENT(DBF_WARNING,
+			  "Read device characteristics failed, rc=%d for "
+			  "device: %s", rc, dev_name(&device->cdev->dev));
 		goto out_err3;
 	}
-	DEV_MESSAGE(KERN_INFO, device,
-		    "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
-		    private->rdc_data.dev_type,
-		    private->rdc_data.dev_model,
-		    private->rdc_data.cu_type,
-		    private->rdc_data.cu_model.model,
-		    private->rdc_data.no_cyl,
-		    private->rdc_data.trk_per_cyl,
-		    private->rdc_data.sec_per_trk);
+	/* find the vaild cylinder size */
+	if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
+	    private->rdc_data.long_no_cyl)
+		private->real_cyl = private->rdc_data.long_no_cyl;
+	else
+		private->real_cyl = private->rdc_data.no_cyl;
+
+	dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
+		 "with %d cylinders, %d heads, %d sectors\n",
+		 private->rdc_data.dev_type,
+		 private->rdc_data.dev_model,
+		 private->rdc_data.cu_type,
+		 private->rdc_data.cu_model.model,
+		    private->real_cyl,
+		 private->rdc_data.trk_per_cyl,
+		 private->rdc_data.sec_per_trk);
 	return 0;
 
 out_err3:
@@ -1151,14 +1326,12 @@ dasd_eckd_end_analysis(struct dasd_block
 	status = private->init_cqr_status;
 	private->init_cqr_status = -1;
 	if (status != DASD_CQR_DONE) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "volume analysis returned unformatted disk");
+		dev_warn(&device->cdev->dev,
+			    "The DASD is not formatted\n");
 		return -EMEDIUMTYPE;
 	}
 
 	private->uses_cdl = 1;
-	/* Calculate number of blocks/records per track. */
-	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
 	/* Check Track 0 for Compatible Disk Layout */
 	count_area = NULL;
 	for (i = 0; i < 3; i++) {
@@ -1182,8 +1355,8 @@ dasd_eckd_end_analysis(struct dasd_block
 			count_area = &private->count_area[0];
 	} else {
 		if (private->count_area[3].record == 1)
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "Trk 0: no records after VTOC!");
+			dev_warn(&device->cdev->dev,
+				 "Track 0 has no records following the VTOC\n");
 	}
 	if (count_area != NULL && count_area->kl == 0) {
 		/* we found notthing violating our disk layout */
@@ -1191,8 +1364,8 @@ dasd_eckd_end_analysis(struct dasd_block
 			block->bp_block = count_area->dl;
 	}
 	if (block->bp_block == 0) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "Volume has incompatible disk layout");
+		dev_warn(&device->cdev->dev,
+			 "The disk layout of the DASD is not supported\n");
 		return -EMEDIUMTYPE;
 	}
 	block->s2b_shift = 0;	/* bits to shift 512 to get a block */
@@ -1200,19 +1373,19 @@ dasd_eckd_end_analysis(struct dasd_block
 		block->s2b_shift++;
 
 	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
-	block->blocks = (private->rdc_data.no_cyl *
+	block->blocks = (private->real_cyl *
 			  private->rdc_data.trk_per_cyl *
 			  blk_per_trk);
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "(%dkB blks): %dkB at %dkB/trk %s",
-		    (block->bp_block >> 10),
-		    ((private->rdc_data.no_cyl *
-		      private->rdc_data.trk_per_cyl *
-		      blk_per_trk * (block->bp_block >> 9)) >> 1),
-		    ((blk_per_trk * block->bp_block) >> 10),
-		    private->uses_cdl ?
-		    "compatible disk layout" : "linux disk layout");
+	dev_info(&device->cdev->dev,
+		 "DASD with %d KB/block, %d KB total size, %d KB/track, "
+		 "%s\n", (block->bp_block >> 10),
+		 ((private->real_cyl *
+		   private->rdc_data.trk_per_cyl *
+		   blk_per_trk * (block->bp_block >> 9)) >> 1),
+		 ((blk_per_trk * block->bp_block) >> 10),
+		 private->uses_cdl ?
+		 "compatible disk layout" : "linux disk layout");
 
 	return 0;
 }
@@ -1262,31 +1435,35 @@ dasd_eckd_format_device(struct dasd_devi
 	struct eckd_count *ect;
 	struct ccw1 *ccw;
 	void *data;
-	int rpt, cyl, head;
+	int rpt;
+	struct ch_t address;
 	int cplength, datasize;
 	int i;
+	int intensity = 0;
+	int r0_perm;
 
 	private = (struct dasd_eckd_private *) device->private;
 	rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
-	cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
-	head = fdata->start_unit % private->rdc_data.trk_per_cyl;
+	set_ch_t(&address,
+		 fdata->start_unit / private->rdc_data.trk_per_cyl,
+		 fdata->start_unit % private->rdc_data.trk_per_cyl);
 
 	/* Sanity checks. */
 	if (fdata->start_unit >=
-	    (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
-		DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
-			    fdata->start_unit);
+	    (private->real_cyl * private->rdc_data.trk_per_cyl)) {
+		dev_warn(&device->cdev->dev, "Start track number %d used in "
+			 "formatting is too big\n", fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (fdata->start_unit > fdata->stop_unit) {
-		DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
-			    fdata->start_unit);
+		dev_warn(&device->cdev->dev, "Start track %d used in "
+			 "formatting exceeds end track\n", fdata->start_unit);
 		return ERR_PTR(-EINVAL);
 	}
 	if (dasd_check_blocksize(fdata->blksize) != 0) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Invalid blocksize %d...terminating!",
-			    fdata->blksize);
+		dev_warn(&device->cdev->dev,
+			 "The DASD cannot be formatted with block size %d\n",
+			 fdata->blksize);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1296,9 +1473,17 @@ dasd_eckd_format_device(struct dasd_devi
 	 *   Bit 1: write home address, currently not supported
 	 *   Bit 2: invalidate tracks
 	 *   Bit 3: use OS/390 compatible disk layout (cdl)
+	 *   Bit 4: do not allow storage subsystem to modify record zero
 	 * Only some bit combinations do make sense.
 	 */
-	switch (fdata->intensity) {
+	if (fdata->intensity & 0x10) {
+		r0_perm = 0;
+		intensity = fdata->intensity & ~0x10;
+	} else {
+		r0_perm = 1;
+		intensity = fdata->intensity;
+	}
+	switch (intensity) {
 	case 0x00:	/* Normal format */
 	case 0x08:	/* Normal format, use cdl. */
 		cplength = 2 + rpt;
@@ -1322,8 +1507,8 @@ dasd_eckd_format_device(struct dasd_devi
 			sizeof(struct eckd_count);
 		break;
 	default:
-		DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
-			    fdata->intensity);
+		dev_warn(&device->cdev->dev, "An I/O control call used "
+			 "incorrect flags 0x%x\n", fdata->intensity);
 		return ERR_PTR(-EINVAL);
 	}
 	/* Allocate the format ccw request. */
@@ -1335,11 +1520,14 @@ dasd_eckd_format_device(struct dasd_devi
 	data = fcp->data;
 	ccw = fcp->cpaddr;
 
-	switch (fdata->intensity & ~0x08) {
+	switch (intensity & ~0x08) {
 	case 0x00: /* Normal format. */
 		define_extent(ccw++, (struct DE_eckd_data *) data,
 			      fdata->start_unit, fdata->start_unit,
 			      DASD_ECKD_CCW_WRITE_CKD, device);
+		/* grant subsystem permission to format R0 */
+		if (r0_perm)
+			((struct DE_eckd_data *)data)->ga_extended |= 0x04;
 		data += sizeof(struct DE_eckd_data);
 		ccw[-1].flags |= CCW_FLAG_CC;
 		locate_record(ccw++, (struct LO_eckd_data *) data,
@@ -1373,11 +1561,11 @@ dasd_eckd_format_device(struct dasd_devi
 		data += sizeof(struct LO_eckd_data);
 		break;
 	}
-	if (fdata->intensity & 0x01) {	/* write record zero */
+	if (intensity & 0x01) {	/* write record zero */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
-		ect->cyl = cyl;
-		ect->head = head;
+		ect->cyl = address.cyl;
+		ect->head = address.head;
 		ect->record = 0;
 		ect->kl = 0;
 		ect->dl = 8;
@@ -1388,11 +1576,11 @@ dasd_eckd_format_device(struct dasd_devi
 		ccw->cda = (__u32)(addr_t) ect;
 		ccw++;
 	}
-	if ((fdata->intensity & ~0x08) & 0x04) {	/* erase track */
+	if ((intensity & ~0x08) & 0x04) {	/* erase track */
 		ect = (struct eckd_count *) data;
 		data += sizeof(struct eckd_count);
-		ect->cyl = cyl;
-		ect->head = head;
+		ect->cyl = address.cyl;
+		ect->head = address.head;
 		ect->record = 1;
 		ect->kl = 0;
 		ect->dl = 0;
@@ -1405,20 +1593,20 @@ dasd_eckd_format_device(struct dasd_devi
 		for (i = 0; i < rpt; i++) {
 			ect = (struct eckd_count *) data;
 			data += sizeof(struct eckd_count);
-			ect->cyl = cyl;
-			ect->head = head;
+			ect->cyl = address.cyl;
+			ect->head = address.head;
 			ect->record = i + 1;
 			ect->kl = 0;
 			ect->dl = fdata->blksize;
 			/* Check for special tracks 0-1 when formatting CDL */
-			if ((fdata->intensity & 0x08) &&
+			if ((intensity & 0x08) &&
 			    fdata->start_unit == 0) {
 				if (i < 3) {
 					ect->kl = 4;
 					ect->dl = sizes_trk0[i] - 4;
 				}
 			}
-			if ((fdata->intensity & 0x08) &&
+			if ((intensity & 0x08) &&
 			    fdata->start_unit == 1) {
 				ect->kl = 44;
 				ect->dl = LABEL_SIZE - 44;
@@ -1479,57 +1667,69 @@ static void dasd_eckd_handle_unsolicited
 						   struct irb *irb)
 {
 	char mask;
+	char *sense = NULL;
 
 	/* first of all check for state change pending interrupt */
 	mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
-	if ((irb->scsw.cmd.dstat & mask) == mask) {
+	if ((scsw_dstat(&irb->scsw) & mask) == mask) {
 		dasd_generic_handle_state_change(device);
 		return;
 	}
 
 	/* summary unit check */
-	if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
+	if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
 	    (irb->ecw[7] == 0x0D)) {
 		dasd_alias_handle_summary_unit_check(device, irb);
 		return;
 	}
 
-
+	sense = dasd_get_sense(irb);
 	/* service information message SIM */
-	if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) &&
-	    ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
-		dasd_3990_erp_handle_sim(device, irb->ecw);
+	if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+	    ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
+		dasd_3990_erp_handle_sim(device, sense);
 		dasd_schedule_device_bh(device);
 		return;
 	}
 
-	if ((irb->scsw.cmd.cc == 1) &&
-	    (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
-	    (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
-	    (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
+	if ((scsw_cc(&irb->scsw) == 1) &&
+	    (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+	    (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
+	    (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
 		/* fake irb do nothing, they are handled elsewhere */
 		dasd_schedule_device_bh(device);
 		return;
 	}
 
-	if (!(irb->esw.esw0.erw.cons)) {
+	if (!sense) {
 		/* just report other unsolicited interrupts */
-		DEV_MESSAGE(KERN_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_ERR, device, "%s",
 			    "unsolicited interrupt received");
 	} else {
-		DEV_MESSAGE(KERN_ERR, device, "%s",
+		DBF_DEV_EVENT(DBF_ERR, device, "%s",
 			    "unsolicited interrupt received "
 			    "(sense available)");
-		device->discipline->dump_sense(device, NULL, irb);
+		device->discipline->dump_sense_dbf(device, NULL, irb,
+						   "unsolicited");
 	}
 
 	dasd_schedule_device_bh(device);
 	return;
 };
 
-static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
+					       struct dasd_device *startdev,
 					       struct dasd_block *block,
-					       struct request *req)
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
 {
 	struct dasd_eckd_private *private;
 	unsigned long *idaws;
@@ -1539,11 +1739,9 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	struct req_iterator iter;
 	struct bio_vec *bv;
 	char *dst;
-	unsigned int blksize, blk_per_trk, off;
+	unsigned int off;
 	int count, cidaw, cplength, datasize;
-	sector_t recid, first_rec, last_rec;
-	sector_t first_trk, last_trk;
-	unsigned int first_offs, last_offs;
+	sector_t recid;
 	unsigned char cmd, rcmd;
 	int use_prefix;
 	struct dasd_device *basedev;
@@ -1556,15 +1754,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 		cmd = DASD_ECKD_CCW_WRITE_MT;
 	else
 		return ERR_PTR(-EINVAL);
-	/* Calculate number of blocks/records per track. */
-	blksize = block->bp_block;
-	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
-	/* Calculate record id of first and last block. */
-	first_rec = first_trk = req->sector >> block->s2b_shift;
-	first_offs = sector_div(first_trk, blk_per_trk);
-	last_rec = last_trk =
-		(req->sector + req->nr_sectors - 1) >> block->s2b_shift;
-	last_offs = sector_div(last_trk, blk_per_trk);
+
 	/* Check struct bio and count the number of blocks for the request. */
 	count = 0;
 	cidaw = 0;
@@ -1714,6 +1904,505 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	return cqr;
 }
 
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
+					       struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
+{
+	struct dasd_eckd_private *private;
+	unsigned long *idaws;
+	struct dasd_ccw_req *cqr;
+	struct ccw1 *ccw;
+	struct req_iterator iter;
+	struct bio_vec *bv;
+	char *dst, *idaw_dst;
+	unsigned int cidaw, cplength, datasize;
+	unsigned int tlf;
+	sector_t recid;
+	unsigned char cmd;
+	struct dasd_device *basedev;
+	unsigned int trkcount, count, count_to_trk_end;
+	unsigned int idaw_len, seg_len, part_len, len_to_track_end;
+	unsigned char new_track, end_idaw;
+	sector_t trkid;
+	unsigned int recoffs;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+	if (rq_data_dir(req) == READ)
+		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+	else if (rq_data_dir(req) == WRITE)
+		cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+	else
+		return ERR_PTR(-EINVAL);
+
+	/* Track based I/O needs IDAWs for each page, and not just for
+	 * 64 bit addresses. We need additional idals for pages
+	 * that get filled from two tracks, so we use the number
+	 * of records as upper limit.
+	 */
+	cidaw = last_rec - first_rec + 1;
+	trkcount = last_trk - first_trk + 1;
+
+	/* 1x prefix + one read/write ccw per track */
+	cplength = 1 + trkcount;
+
+	/* on 31-bit we need space for two 32 bit addresses per page
+	 * on 64-bit one 64 bit address
+	 */
+	datasize = sizeof(struct PFX_eckd_data) +
+		cidaw * sizeof(unsigned long long);
+
+	/* Allocate the ccw request. */
+	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+				   cplength, datasize, startdev);
+	if (IS_ERR(cqr))
+		return cqr;
+	ccw = cqr->cpaddr;
+	/* transfer length factor: how many bytes to read from the last track */
+	if (first_trk == last_trk)
+		tlf = last_offs - first_offs + 1;
+	else
+		tlf = last_offs + 1;
+	tlf *= blksize;
+
+	if (prefix_LRE(ccw++, cqr->data, first_trk,
+		       last_trk, cmd, basedev, startdev,
+		       1 /* format */, first_offs + 1,
+		       trkcount, blksize,
+		       tlf) == -EAGAIN) {
+		/* Clock not in sync and XRC is enabled.
+		 * Try again later.
+		 */
+		dasd_sfree_request(cqr, startdev);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	/*
+	 * The translation of request into ccw programs must meet the
+	 * following conditions:
+	 * - all idaws but the first and the last must address full pages
+	 *   (or 2K blocks on 31-bit)
+	 * - the scope of a ccw and it's idal ends with the track boundaries
+	 */
+	idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
+	recid = first_rec;
+	new_track = 1;
+	end_idaw = 0;
+	len_to_track_end = 0;
+	idaw_dst = 0;
+	idaw_len = 0;
+	rq_for_each_segment(bv, req, iter) {
+		dst = page_address(bv->bv_page) + bv->bv_offset;
+		seg_len = bv->bv_len;
+		while (seg_len) {
+			if (new_track) {
+				trkid = recid;
+				recoffs = sector_div(trkid, blk_per_trk);
+				count_to_trk_end = blk_per_trk - recoffs;
+				count = min((last_rec - recid + 1),
+					    (sector_t)count_to_trk_end);
+				len_to_track_end = count * blksize;
+				ccw[-1].flags |= CCW_FLAG_CC;
+				ccw->cmd_code = cmd;
+				ccw->count = len_to_track_end;
+				ccw->cda = (__u32)(addr_t)idaws;
+				ccw->flags = CCW_FLAG_IDA;
+				ccw++;
+				recid += count;
+				new_track = 0;
+				/* first idaw for a ccw may start anywhere */
+				if (!idaw_dst)
+					idaw_dst = dst;
+			}
+			/* If we start a new idaw, we must make sure that it
+			 * starts on an IDA_BLOCK_SIZE boundary.
+			 * If we continue an idaw, we must make sure that the
+			 * current segment begins where the so far accumulated
+			 * idaw ends
+			 */
+			if (!idaw_dst) {
+				if (__pa(dst) & (IDA_BLOCK_SIZE-1)) {
+					dasd_sfree_request(cqr, startdev);
+					return ERR_PTR(-ERANGE);
+				} else
+					idaw_dst = dst;
+			}
+			if ((idaw_dst + idaw_len) != dst) {
+				dasd_sfree_request(cqr, startdev);
+				return ERR_PTR(-ERANGE);
+			}
+			part_len = min(seg_len, len_to_track_end);
+			seg_len -= part_len;
+			dst += part_len;
+			idaw_len += part_len;
+			len_to_track_end -= part_len;
+			/* collected memory area ends on an IDA_BLOCK border,
+			 * -> create an idaw
+			 * idal_create_words will handle cases where idaw_len
+			 * is larger then IDA_BLOCK_SIZE
+			 */
+			if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
+				end_idaw = 1;
+			/* We also need to end the idaw at track end */
+			if (!len_to_track_end) {
+				new_track = 1;
+				end_idaw = 1;
+			}
+			if (end_idaw) {
+				idaws = idal_create_words(idaws, idaw_dst,
+							  idaw_len);
+				idaw_dst = 0;
+				idaw_len = 0;
+				end_idaw = 0;
+			}
+		}
+	}
+
+	if (blk_noretry_request(req) ||
+	    block->base->features & DASD_FEATURE_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
+	cqr->lpm = private->path_data.ppm;
+	cqr->retries = 256;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	return cqr;
+}
+
+static int prepare_itcw(struct itcw *itcw,
+			unsigned int trk, unsigned int totrk, int cmd,
+			struct dasd_device *basedev,
+			struct dasd_device *startdev,
+			unsigned int rec_on_trk, int count,
+			unsigned int blksize,
+			unsigned int total_data_size,
+			unsigned int tlf,
+			unsigned int blk_per_trk)
+{
+	struct PFX_eckd_data pfxdata;
+	struct dasd_eckd_private *basepriv, *startpriv;
+	struct DE_eckd_data *dedata;
+	struct LRE_eckd_data *lredata;
+	struct dcw *dcw;
+
+	u32 begcyl, endcyl;
+	u16 heads, beghead, endhead;
+	u8 pfx_cmd;
+
+	int rc = 0;
+	int sector = 0;
+	int dn, d;
+
+
+	/* setup prefix data */
+	basepriv = (struct dasd_eckd_private *) basedev->private;
+	startpriv = (struct dasd_eckd_private *) startdev->private;
+	dedata = &pfxdata.define_extent;
+	lredata = &pfxdata.locate_record;
+
+	memset(&pfxdata, 0, sizeof(pfxdata));
+	pfxdata.format = 1; /* PFX with LRE */
+	pfxdata.base_address = basepriv->ned->unit_addr;
+	pfxdata.base_lss = basepriv->ned->ID;
+	pfxdata.validity.define_extent = 1;
+
+	/* private uid is kept up to date, conf_data may be outdated */
+	if (startpriv->uid.type != UA_BASE_DEVICE) {
+		pfxdata.validity.verify_base = 1;
+		if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
+			pfxdata.validity.hyper_pav = 1;
+	}
+
+	switch (cmd) {
+	case DASD_ECKD_CCW_READ_TRACK_DATA:
+		dedata->mask.perm = 0x1;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		dedata->ga_extended |= 0x42;
+		lredata->operation.orientation = 0x0;
+		lredata->operation.operation = 0x0C;
+		lredata->auxiliary.check_bytes = 0x01;
+		pfx_cmd = DASD_ECKD_CCW_PFX_READ;
+		break;
+	case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+		dedata->mask.perm = 0x02;
+		dedata->attributes.operation = basepriv->attrib.operation;
+		dedata->blk_size = blksize;
+		rc = check_XRC_on_prefix(&pfxdata, basedev);
+		dedata->ga_extended |= 0x42;
+		lredata->operation.orientation = 0x0;
+		lredata->operation.operation = 0x3F;
+		lredata->extended_operation = 0x23;
+		lredata->auxiliary.check_bytes = 0x2;
+		pfx_cmd = DASD_ECKD_CCW_PFX;
+		break;
+	default:
+		DBF_DEV_EVENT(DBF_ERR, basedev,
+			      "prepare itcw, unknown opcode 0x%x", cmd);
+		BUG();
+		break;
+	}
+	if (rc)
+		return rc;
+
+	dedata->attributes.mode = 0x3;	/* ECKD */
+
+	heads = basepriv->rdc_data.trk_per_cyl;
+	begcyl = trk / heads;
+	beghead = trk % heads;
+	endcyl = totrk / heads;
+	endhead = totrk % heads;
+
+	/* check for sequential prestage - enhance cylinder range */
+	if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+	    dedata->attributes.operation == DASD_SEQ_ACCESS) {
+
+		if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+			endcyl += basepriv->attrib.nr_cyl;
+		else
+			endcyl = (basepriv->real_cyl - 1);
+	}
+
+	set_ch_t(&dedata->beg_ext, begcyl, beghead);
+	set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+	dedata->ep_format = 0x20; /* records per track is valid */
+	dedata->ep_rec_per_track = blk_per_trk;
+
+	if (rec_on_trk) {
+		switch (basepriv->rdc_data.dev_type) {
+		case 0x3390:
+			dn = ceil_quot(blksize + 6, 232);
+			d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
+			sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+			break;
+		case 0x3380:
+			d = 7 + ceil_quot(blksize + 12, 32);
+			sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+			break;
+		}
+	}
+
+	lredata->auxiliary.length_valid = 1;
+	lredata->auxiliary.length_scope = 1;
+	lredata->auxiliary.imbedded_ccw_valid = 1;
+	lredata->length = tlf;
+	lredata->imbedded_ccw = cmd;
+	lredata->count = count;
+	lredata->sector = sector;
+	set_ch_t(&lredata->seek_addr, begcyl, beghead);
+	lredata->search_arg.cyl = lredata->seek_addr.cyl;
+	lredata->search_arg.head = lredata->seek_addr.head;
+	lredata->search_arg.record = rec_on_trk;
+
+	dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
+		     &pfxdata, sizeof(pfxdata), total_data_size);
+
+	return rc;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
+					       struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req,
+					       sector_t first_rec,
+					       sector_t last_rec,
+					       sector_t first_trk,
+					       sector_t last_trk,
+					       unsigned int first_offs,
+					       unsigned int last_offs,
+					       unsigned int blk_per_trk,
+					       unsigned int blksize)
+{
+	struct dasd_eckd_private *private;
+	struct dasd_ccw_req *cqr;
+	struct req_iterator iter;
+	struct bio_vec *bv;
+	char *dst;
+	unsigned int trkcount, ctidaw;
+	unsigned char cmd;
+	struct dasd_device *basedev;
+	unsigned int tlf;
+	struct itcw *itcw;
+	struct tidaw *last_tidaw = NULL;
+	int itcw_op;
+	size_t itcw_size;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+	if (rq_data_dir(req) == READ) {
+		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+		itcw_op = ITCW_OP_READ;
+	} else if (rq_data_dir(req) == WRITE) {
+		cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+		itcw_op = ITCW_OP_WRITE;
+	} else
+		return ERR_PTR(-EINVAL);
+
+	/* trackbased I/O needs address all memory via TIDAWs,
+	 * not just for 64 bit addresses. This allows us to map
+	 * each segment directly to one tidaw.
+	 */
+	trkcount = last_trk - first_trk + 1;
+	ctidaw = 0;
+	rq_for_each_segment(bv, req, iter) {
+		++ctidaw;
+	}
+
+	/* Allocate the ccw request. */
+	itcw_size = itcw_calc_size(0, ctidaw, 0);
+	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+				   0, itcw_size, startdev);
+	if (IS_ERR(cqr))
+		return cqr;
+
+	cqr->cpmode = 1;
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 100*HZ;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	cqr->retries = 10;
+
+	/* transfer length factor: how many bytes to read from the last track */
+	if (first_trk == last_trk)
+		tlf = last_offs - first_offs + 1;
+	else
+		tlf = last_offs + 1;
+	tlf *= blksize;
+
+	itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+	cqr->cpaddr = itcw_get_tcw(itcw);
+
+	if (prepare_itcw(itcw, first_trk, last_trk,
+			 cmd, basedev, startdev,
+			 first_offs + 1,
+			 trkcount, blksize,
+			 (last_rec - first_rec + 1) * blksize,
+			 tlf, blk_per_trk) == -EAGAIN) {
+		/* Clock not in sync and XRC is enabled.
+		 * Try again later.
+		 */
+		dasd_sfree_request(cqr, startdev);
+		return ERR_PTR(-EAGAIN);
+	}
+
+	/*
+	 * A tidaw can address 4k of memory, but must not cross page boundaries
+	 * We can let the block layer handle this by setting
+	 * blk_queue_segment_boundary to page boundaries and
+	 * blk_max_segment_size to page size when setting up the request queue.
+	 */
+	rq_for_each_segment(bv, req, iter) {
+		dst = page_address(bv->bv_page) + bv->bv_offset;
+		last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
+		if (IS_ERR(last_tidaw))
+			return (struct dasd_ccw_req *)last_tidaw;
+	}
+
+	last_tidaw->flags |= 0x80;
+	itcw_finalize(itcw);
+
+	if (blk_noretry_request(req) ||
+	    block->base->features & DASD_FEATURE_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+	cqr->startdev = startdev;
+	cqr->memdev = startdev;
+	cqr->block = block;
+	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
+	cqr->lpm = private->path_data.ppm;
+	cqr->retries = 256;
+	cqr->buildclk = get_clock();
+	cqr->status = DASD_CQR_FILLED;
+	return cqr;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+					       struct dasd_block *block,
+					       struct request *req)
+{
+	int tpm, cmdrtd, cmdwtd;
+	int use_prefix;
+
+	struct dasd_eckd_private *private;
+	int fcx_in_css, fcx_in_gneq, fcx_in_features;
+	struct dasd_device *basedev;
+	sector_t first_rec, last_rec;
+	sector_t first_trk, last_trk;
+	unsigned int first_offs, last_offs;
+	unsigned int blk_per_trk, blksize;
+	int cdlspecial;
+	struct dasd_ccw_req *cqr;
+
+	basedev = block->base;
+	private = (struct dasd_eckd_private *) basedev->private;
+
+	/* Calculate number of blocks/records per track. */
+	blksize = block->bp_block;
+	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
+	/* Calculate record id of first and last block. */
+	first_rec = first_trk = req->sector >> block->s2b_shift;
+	first_offs = sector_div(first_trk, blk_per_trk);
+	last_rec = last_trk =
+		(req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+	last_offs = sector_div(last_trk, blk_per_trk);
+	cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
+
+	/* is transport mode supported ? */
+	fcx_in_css = css_general_characteristics.fcx;
+	fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+	fcx_in_features = private->features.feature[40] & 0x80;
+	tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+	/* is read track data and write track data in command mode supported? */
+	cmdrtd = private->features.feature[9] & 0x20;
+	cmdwtd = private->features.feature[12] & 0x40;
+	use_prefix = private->features.feature[8] & 0x01;
+
+	cqr = NULL;
+	if (cdlspecial || dasd_page_cache) {
+		/* do nothing, just fall through to the cmd mode single case */
+	} else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+		cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
+						    first_rec, last_rec,
+						    first_trk, last_trk,
+						    first_offs, last_offs,
+						    blk_per_trk, blksize);
+		if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+			cqr = NULL;
+	} else if (use_prefix &&
+		   (((rq_data_dir(req) == READ) && cmdrtd) ||
+		    ((rq_data_dir(req) == WRITE) && cmdwtd))) {
+		cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
+						   first_rec, last_rec,
+						   first_trk, last_trk,
+						   first_offs, last_offs,
+						   blk_per_trk, blksize);
+		if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+			cqr = NULL;
+	}
+	if (!cqr)
+		cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
+						    first_rec, last_rec,
+						    first_trk, last_trk,
+						    first_offs, last_offs,
+						    blk_per_trk, blksize);
+	return cqr;
+}
+
 static int
 dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
 {
@@ -1767,7 +2456,7 @@ out:
 }
 
 /*
- * Modify ccw chain in cqr so it can be started on a base device.
+ * Modify ccw/tcw in cqr so it can be started on a base device.
  *
  * Note that this is not enough to restart the cqr!
  * Either reset cqr->startdev as well (summary unit check handling)
@@ -1777,13 +2466,24 @@ void dasd_eckd_reset_ccw_to_base_io(stru
 {
 	struct ccw1 *ccw;
 	struct PFX_eckd_data *pfxdata;
+	struct tcw *tcw;
+	struct tccb *tccb;
+	struct dcw *dcw;
 
-	ccw = cqr->cpaddr;
-	pfxdata = cqr->data;
-
-	if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+	if (cqr->cpmode == 1) {
+		tcw = cqr->cpaddr;
+		tccb = tcw_get_tccb(tcw);
+		dcw = (struct dcw *)&tccb->tca[0];
+		pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
 		pfxdata->validity.verify_base = 0;
 		pfxdata->validity.hyper_pav = 0;
+	} else {
+		ccw = cqr->cpaddr;
+		pfxdata = cqr->data;
+		if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+			pfxdata->validity.verify_base = 0;
+			pfxdata->validity.hyper_pav = 0;
+		}
 	}
 }
 
@@ -1861,6 +2561,7 @@ dasd_eckd_release(struct dasd_device *de
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1868,14 +2569,15 @@ dasd_eckd_release(struct dasd_device *de
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1902,6 +2604,7 @@ dasd_eckd_reserve(struct dasd_device *de
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1909,14 +2612,15 @@ dasd_eckd_reserve(struct dasd_device *de
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1942,6 +2646,7 @@ dasd_eckd_steal_lock(struct dasd_device
 {
 	struct dasd_ccw_req *cqr;
 	int rc;
+	struct ccw1 *ccw;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -1949,14 +2654,15 @@ dasd_eckd_steal_lock(struct dasd_device
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
-        cqr->cpaddr->flags |= CCW_FLAG_SLI;
-        cqr->cpaddr->count = 32;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_SLCK;
+	ccw->flags |= CCW_FLAG_SLI;
+	ccw->count = 32;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 	cqr->startdev = device;
 	cqr->memdev = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1990,7 +2696,7 @@ dasd_eckd_performance(struct dasd_device
 				    sizeof(struct dasd_rssd_perf_stats_t)),
 				   device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
@@ -2080,9 +2786,9 @@ dasd_eckd_set_attrib(struct dasd_device
 		return -EFAULT;
 	private->attrib = attrib;
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "cache operation mode set to %x (%i cylinder prestage)",
-		    private->attrib.operation, private->attrib.nr_cyl);
+	dev_info(&device->cdev->dev,
+		 "The DASD cache mode was set to %x (%i cylinder prestage)\n",
+		 private->attrib.operation, private->attrib.nr_cyl);
 	return 0;
 }
 
@@ -2133,7 +2839,7 @@ static int dasd_symm_io(struct dasd_devi
 	/* setup CCWs for PSF + RSSD */
 	cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
 	if (IS_ERR(cqr)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			"Could not allocate initialization request");
 		rc = PTR_ERR(cqr);
 		goto out_free;
@@ -2242,11 +2948,54 @@ dasd_eckd_dump_ccw_range(struct ccw1 *fr
 	return len;
 }
 
+static void
+dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+			 struct irb *irb, char *reason)
+{
+	u64 *sense;
+	int sl;
+	struct tsb *tsb;
+
+	sense = NULL;
+	tsb = NULL;
+	if (req && scsw_is_tm(&req->irb.scsw)) {
+		if (irb->scsw.tm.tcw)
+			tsb = tcw_get_tsb(
+				(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+		if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+			switch (tsb->flags & 0x07) {
+			case 1:	/* tsa_iostat */
+				sense = (u64 *)tsb->tsa.iostat.sense;
+			break;
+			case 2: /* ts_ddpc */
+				sense = (u64 *)tsb->tsa.ddpc.sense;
+			break;
+			case 3: /* tsa_intrg */
+			break;
+			}
+		}
+	} else {
+		if (irb->esw.esw0.erw.cons)
+			sense = (u64 *)irb->ecw;
+	}
+	if (sense) {
+		for (sl = 0; sl < 4; sl++) {
+			DBF_DEV_EVENT(DBF_EMERG, device,
+				      "%s: %016llx %016llx %016llx %016llx",
+				      reason, sense[0], sense[1], sense[2],
+				      sense[3]);
+		}
+	} else {
+		DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+			      "SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+}
+
 /*
  * Print sense data and related channel program.
  * Parts are printed because printk buffer is only 1024 bytes.
  */
-static void dasd_eckd_dump_sense(struct dasd_device *device,
+static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
 				 struct dasd_ccw_req *req, struct irb *irb)
 {
 	char *page;
@@ -2255,8 +3004,8 @@ static void dasd_eckd_dump_sense(struct
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		DEV_MESSAGE(KERN_ERR, device, " %s",
-			    "No memory to dump sense data");
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+			      "No memory to dump sense data\n");
 		return;
 	}
 	/* dump the sense data */
@@ -2265,7 +3014,7 @@ static void dasd_eckd_dump_sense(struct
 		      dev_name(&device->cdev->dev));
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
-		       irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
+		       scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       " device %s: Failing CCW: %p\n",
 		       dev_name(&device->cdev->dev),
@@ -2341,6 +3090,147 @@ static void dasd_eckd_dump_sense(struct
 	free_page((unsigned long) page);
 }
 
+
+/*
+ * Print sense data from a tcw.
+ */
+static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
+				 struct dasd_ccw_req *req, struct irb *irb)
+{
+	char *page;
+	int len, sl, sct, residual;
+
+	struct tsb *tsb;
+	u8 *sense;
+
+
+	page = (char *) get_zeroed_page(GFP_ATOMIC);
+	if (page == NULL) {
+		DBF_DEV_EVENT(DBF_WARNING, device, " %s",
+			    "No memory to dump sense data");
+		return;
+	}
+	/* dump the sense data */
+	len = sprintf(page,  KERN_ERR PRINTK_HEADER
+		      " I/O status report for device %s:\n",
+		      dev_name(&device->cdev->dev));
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " in req: %p CS: 0x%02X DS: 0x%02X "
+		       "fcxs: 0x%02X schxs: 0x%02X\n", req,
+		       scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+		       irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " device %s: Failing TCW: %p\n",
+		       dev_name(&device->cdev->dev),
+		       (void *) (addr_t) irb->scsw.tm.tcw);
+
+	tsb = NULL;
+	sense = NULL;
+	if (irb->scsw.tm.tcw)
+		tsb = tcw_get_tsb(
+			(struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+
+	if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->length %d\n", tsb->length);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->flags %x\n", tsb->flags);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->dcw_offset %d\n", tsb->dcw_offset);
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->count %d\n", tsb->count);
+		residual = tsb->count - 28;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " residual %d\n", residual);
+
+		switch (tsb->flags & 0x07) {
+		case 1:	/* tsa_iostat */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_time %d\n",
+				       tsb->tsa.iostat.dev_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.def_time %d\n",
+				       tsb->tsa.iostat.def_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.queue_time %d\n",
+				       tsb->tsa.iostat.queue_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_busy_time %d\n",
+				       tsb->tsa.iostat.dev_busy_time);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.iostat.dev_act_time %d\n",
+				       tsb->tsa.iostat.dev_act_time);
+			sense = tsb->tsa.iostat.sense;
+			break;
+		case 2: /* ts_ddpc */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " tsb->tsa.ddpc.rcq:  ");
+			for (sl = 0; sl < 16; sl++) {
+				for (sct = 0; sct < 8; sct++) {
+					len += sprintf(page + len, " %02x",
+						       tsb->tsa.ddpc.rcq[sl]);
+				}
+				len += sprintf(page + len, "\n");
+			}
+			sense = tsb->tsa.ddpc.sense;
+			break;
+		case 3: /* tsa_intrg */
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+				      " tsb->tsa.intrg.: not supportet yet \n");
+			break;
+		}
+
+		if (sense) {
+			for (sl = 0; sl < 4; sl++) {
+				len += sprintf(page + len,
+					       KERN_ERR PRINTK_HEADER
+					       " Sense(hex) %2d-%2d:",
+					       (8 * sl), ((8 * sl) + 7));
+				for (sct = 0; sct < 8; sct++) {
+					len += sprintf(page + len, " %02x",
+						       sense[8 * sl + sct]);
+				}
+				len += sprintf(page + len, "\n");
+			}
+
+			if (sense[27] & DASD_SENSE_BIT_0) {
+				/* 24 Byte Sense Data */
+				sprintf(page + len, KERN_ERR PRINTK_HEADER
+					" 24 Byte: %x MSG %x, "
+					"%s MSGb to SYSOP\n",
+					sense[7] >> 4, sense[7] & 0x0f,
+					sense[1] & 0x10 ? "" : "no");
+			} else {
+				/* 32 Byte Sense Data */
+				sprintf(page + len, KERN_ERR PRINTK_HEADER
+					" 32 Byte: Format: %x "
+					"Exception class %x\n",
+					sense[6] & 0x0f, sense[22] >> 4);
+			}
+		} else {
+			sprintf(page + len, KERN_ERR PRINTK_HEADER
+				" SORRY - NO VALID SENSE AVAILABLE\n");
+		}
+	} else {
+		sprintf(page + len, KERN_ERR PRINTK_HEADER
+			" SORRY - NO TSB DATA AVAILABLE\n");
+	}
+	printk("%s", page);
+	free_page((unsigned long) page);
+}
+
+static void dasd_eckd_dump_sense(struct dasd_device *device,
+				 struct dasd_ccw_req *req, struct irb *irb)
+{
+	if (req && scsw_is_tm(&req->irb.scsw))
+		dasd_eckd_dump_sense_tcw(device, req, irb);
+	else
+		dasd_eckd_dump_sense_ccw(device, req, irb);
+}
+
+
 /*
  * max_blocks is dependent on the amount of storage that is available
  * in the static io buffer for each device. Currently each device has
@@ -2375,6 +3265,7 @@ static struct dasd_discipline dasd_eckd_
 	.build_cp = dasd_eckd_build_alias_cp,
 	.free_cp = dasd_eckd_free_alias_cp,
 	.dump_sense = dasd_eckd_dump_sense,
+	.dump_sense_dbf = dasd_eckd_dump_sense_dbf,
 	.fill_info = dasd_eckd_fill_info,
 	.ioctl = dasd_eckd_ioctl,
 };
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eckd.h linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eckd.h
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eckd.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eckd.h	2009-06-09 23:05:27.000000000 -0400
@@ -38,8 +38,11 @@
 #define DASD_ECKD_CCW_RELEASE		 0x94
 #define DASD_ECKD_CCW_READ_CKD_MT	 0x9e
 #define DASD_ECKD_CCW_WRITE_CKD_MT	 0x9d
+#define DASD_ECKD_CCW_WRITE_TRACK_DATA	 0xA5
+#define DASD_ECKD_CCW_READ_TRACK_DATA	 0xA6
 #define DASD_ECKD_CCW_RESERVE		 0xB4
 #define DASD_ECKD_CCW_PFX		 0xE7
+#define DASD_ECKD_CCW_PFX_READ		 0xEA
 #define DASD_ECKD_CCW_RSCK		 0xF9
 
 /*
@@ -48,6 +51,11 @@
 #define PSF_ORDER_PRSSD 0x18
 #define PSF_ORDER_SSC	0x1D
 
+/*
+ * Size that is reportet for large volumes in the old 16-bit no_cyl field
+ */
+#define LV_COMPAT_CYL 0xFFFE
+
 /*****************************************************************************
  * SECTION: Type Definitions
  ****************************************************************************/
@@ -118,7 +126,9 @@ struct DE_eckd_data {
 	unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
 	__u8 ep_format;        /* Extended Parameter format byte       */
 	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
-	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
+	__u8 ep_reserved1;     /* Extended Parameter Reserved	       */
+	__u8 ep_rec_per_track; /* Number of records on a track	       */
+	__u8 ep_reserved[4];   /* Extended Parameter Reserved	       */
 } __attribute__ ((packed));
 
 struct LO_eckd_data {
@@ -139,11 +149,37 @@ struct LO_eckd_data {
 	__u16 length;
 } __attribute__ ((packed));
 
+struct LRE_eckd_data {
+	struct {
+		unsigned char orientation:2;
+		unsigned char operation:6;
+	} __attribute__ ((packed)) operation;
+	struct {
+		unsigned char length_valid:1;
+		unsigned char length_scope:1;
+		unsigned char imbedded_ccw_valid:1;
+		unsigned char check_bytes:2;
+		unsigned char imbedded_count_valid:1;
+		unsigned char reserved:1;
+		unsigned char read_count_suffix:1;
+	} __attribute__ ((packed)) auxiliary;
+	__u8 imbedded_ccw;
+	__u8 count;
+	struct ch_t seek_addr;
+	struct chr_t search_arg;
+	__u8 sector;
+	__u16 length;
+	__u8 imbedded_count;
+	__u8 extended_operation;
+	__u16 extended_parameter_length;
+	__u8 extended_parameter[0];
+} __attribute__ ((packed));
+
 /* Prefix data for format 0x00 and 0x01 */
 struct PFX_eckd_data {
 	unsigned char format;
 	struct {
-		unsigned char define_extend:1;
+		unsigned char define_extent:1;
 		unsigned char time_stamp:1;
 		unsigned char verify_base:1;
 		unsigned char hyper_pav:1;
@@ -153,9 +189,8 @@ struct PFX_eckd_data {
 	__u8 aux;
 	__u8 base_lss;
 	__u8 reserved[7];
-	struct DE_eckd_data define_extend;
-	struct LO_eckd_data locate_record;
-	__u8 LO_extended_data[4];
+	struct DE_eckd_data define_extent;
+	struct LRE_eckd_data locate_record;
 } __attribute__ ((packed));
 
 struct dasd_eckd_characteristics {
@@ -228,7 +263,8 @@ struct dasd_eckd_characteristics {
 	__u8 factor7;
 	__u8 factor8;
 	__u8 reserved2[3];
-	__u8 reserved3[10];
+	__u8 reserved3[6];
+	__u32 long_no_cyl;
 } __attribute__ ((packed));
 
 /* elements of the configuration data */
@@ -406,6 +442,7 @@ struct dasd_eckd_private {
 	int uses_cdl;
 	struct attrib_data_t attrib;	/* e.g. cache operations */
 	struct dasd_rssd_features features;
+	u32 real_cyl;
 
 	/* alias managemnet */
 	struct dasd_uid uid;
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eer.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eer.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_eer.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_eer.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,8 @@
  *  Author(s): Stefan Weinhuber <wein@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -297,11 +299,12 @@ static void dasd_eer_write_standard_trig
 	struct dasd_eer_header header;
 	unsigned long flags;
 	struct eerbuffer *eerb;
+	char *sense;
 
 	/* go through cqr chain and count the valid sense data sets */
 	data_size = 0;
 	for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
-		if (temp_cqr->irb.esw.esw0.erw.cons)
+		if (dasd_get_sense(&temp_cqr->irb))
 			data_size += 32;
 
 	header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +319,11 @@ static void dasd_eer_write_standard_trig
 	list_for_each_entry(eerb, &bufferlist, list) {
 		dasd_eer_start_record(eerb, header.total_size);
 		dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
-		for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
-			if (temp_cqr->irb.esw.esw0.erw.cons)
-				dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+		for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+			sense = dasd_get_sense(&temp_cqr->irb);
+			if (sense)
+				dasd_eer_write_buffer(eerb, sense, 32);
+		}
 		dasd_eer_write_buffer(eerb, "EOR", 4);
 	}
 	spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +456,7 @@ int dasd_eer_enable(struct dasd_device *
 {
 	struct dasd_ccw_req *cqr;
 	unsigned long flags;
+	struct ccw1 *ccw;
 
 	if (device->eer_cqr)
 		return 0;
@@ -468,10 +474,11 @@ int dasd_eer_enable(struct dasd_device *
 	cqr->expires = 10 * HZ;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
 
-	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
-	cqr->cpaddr->count = SNSS_DATA_SIZE;
-	cqr->cpaddr->flags = 0;
-	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+	ccw = cqr->cpaddr;
+	ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+	ccw->count = SNSS_DATA_SIZE;
+	ccw->flags = 0;
+	ccw->cda = (__u32)(addr_t) cqr->data;
 
 	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
@@ -534,7 +541,7 @@ static int dasd_eer_open(struct inode *i
 	if (eerb->buffer_page_count < 1 ||
 	    eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
 		kfree(eerb);
-		MESSAGE(KERN_WARNING, "can't open device since module "
+		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();
@@ -687,7 +694,7 @@ int __init dasd_eer_init(void)
 	if (rc) {
 		kfree(dasd_eer_dev);
 		dasd_eer_dev = NULL;
-		MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+		DBF_EVENT(DBF_ERR, "%s", "dasd_eer_init could not "
 		       "register misc device");
 		return rc;
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_erp.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_erp.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_erp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_erp.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/ctype.h>
 #include <linux/init.h>
 
@@ -91,14 +93,14 @@ dasd_default_erp_action(struct dasd_ccw_
 
         /* just retry - there is nothing to save ... I got no sense data.... */
         if (cqr->retries > 0) {
-		DEV_MESSAGE (KERN_DEBUG, device,
+		DBF_DEV_EVENT(DBF_DEBUG, device,
                              "default ERP called (%i retries left)",
                              cqr->retries);
 		cqr->lpm    = LPM_ANYPATH;
 		cqr->status = DASD_CQR_FILLED;
         } else {
-                DEV_MESSAGE (KERN_WARNING, device, "%s",
-			     "default ERP called (NO retry left)");
+		dev_err(&device->cdev->dev,
+			"default ERP has run out of retries and failed\n");
 		cqr->status = DASD_CQR_FAILED;
 		cqr->stopclk = get_clock();
         }
@@ -162,8 +164,21 @@ dasd_log_sense(struct dasd_ccw_req *cqr,
 		device->discipline->dump_sense(device, cqr, irb);
 }
 
+void
+dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
+{
+	struct dasd_device *device;
+
+	device = cqr->startdev;
+	/* dump sense data to s390 debugfeature*/
+	if (device->discipline && device->discipline->dump_sense_dbf)
+		device->discipline->dump_sense_dbf(device, cqr, irb, "log");
+}
+EXPORT_SYMBOL(dasd_log_sense_dbf);
+
 EXPORT_SYMBOL(dasd_default_erp_action);
 EXPORT_SYMBOL(dasd_default_erp_postaction);
 EXPORT_SYMBOL(dasd_alloc_erp_request);
 EXPORT_SYMBOL(dasd_free_erp_request);
 EXPORT_SYMBOL(dasd_log_sense);
+
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_fba.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_fba.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_fba.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_fba.c	2009-06-09 23:05:27.000000000 -0400
@@ -6,6 +6,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <asm/debug.h>
@@ -128,17 +130,18 @@ dasd_fba_check_characteristics(struct da
 		private = kzalloc(sizeof(struct dasd_fba_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			DEV_MESSAGE(KERN_WARNING, device, "%s",
-				    "memory allocation failed for private "
-				    "data");
+			dev_warn(&device->cdev->dev,
+				 "Allocating memory for private DASD "
+				 "data failed\n");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
 	}
 	block = dasd_alloc_block();
 	if (IS_ERR(block)) {
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "could not allocate dasd block structure");
+		DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
+			  "structure for device: %s",
+			  dev_name(&device->cdev->dev));
 		device->private = NULL;
 		kfree(private);
 		return PTR_ERR(block);
@@ -150,9 +153,9 @@ dasd_fba_check_characteristics(struct da
 	rdc_data = (void *) &(private->rdc_data);
 	rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
 	if (rc) {
-		DEV_MESSAGE(KERN_WARNING, device,
-			    "Read device characteristics returned error %d",
-			    rc);
+		DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
+			  "error %d for device: %s",
+			  rc, dev_name(&device->cdev->dev));
 		device->block = NULL;
 		dasd_free_block(block);
 		device->private = NULL;
@@ -160,15 +163,16 @@ dasd_fba_check_characteristics(struct da
 		return rc;
 	}
 
-	DEV_MESSAGE(KERN_INFO, device,
-		    "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
-		    cdev->id.dev_type,
-		    cdev->id.dev_model,
-		    cdev->id.cu_type,
-		    cdev->id.cu_model,
-		    ((private->rdc_data.blk_bdsa *
-		      (private->rdc_data.blk_size >> 9)) >> 11),
-		    private->rdc_data.blk_size);
+	dev_info(&device->cdev->dev,
+		 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
+		 "and %d B/blk\n",
+		 cdev->id.dev_type,
+		 cdev->id.dev_model,
+		 cdev->id.cu_type,
+		 cdev->id.cu_model,
+		 ((private->rdc_data.blk_bdsa *
+		   (private->rdc_data.blk_size >> 9)) >> 11),
+		 private->rdc_data.blk_size);
 	return 0;
 }
 
@@ -180,7 +184,7 @@ static int dasd_fba_do_analysis(struct d
 	private = (struct dasd_fba_private *) block->base->private;
 	rc = dasd_check_blocksize(private->rdc_data.blk_size);
 	if (rc) {
-		DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d",
+		DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d",
 			    private->rdc_data.blk_size);
 		return rc;
 	}
@@ -215,7 +219,7 @@ dasd_fba_erp_postaction(struct dasd_ccw_
 	if (cqr->function == dasd_default_erp_action)
 		return dasd_default_erp_postaction;
 
-	DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p",
+	DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p",
 		    cqr->function);
 	return NULL;
 }
@@ -233,9 +237,9 @@ static void dasd_fba_handle_unsolicited_
 	}
 
 	/* check for unsolicited interrupts */
-	DEV_MESSAGE(KERN_DEBUG, device, "%s",
+	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 		    "unsolicited interrupt received");
-	device->discipline->dump_sense(device, NULL, irb);
+	device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
 	dasd_schedule_device_bh(device);
 	return;
 };
@@ -437,6 +441,25 @@ dasd_fba_fill_info(struct dasd_device *
 }
 
 static void
+dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+			 struct irb *irb, char *reason)
+{
+	int sl;
+	if (irb->esw.esw0.erw.cons) {
+		for (sl = 0; sl < 4; sl++) {
+			DBF_DEV_EVENT(DBF_EMERG, device,
+				      "%s: %08x %08x %08x %08x",
+				      reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+				      irb->ecw[8 * 2], irb->ecw[8 * 3]);
+		}
+	} else {
+		DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+			      "SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+}
+
+
+static void
 dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		    struct irb *irb)
 {
@@ -446,7 +469,7 @@ dasd_fba_dump_sense(struct dasd_device *
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		DEV_MESSAGE(KERN_ERR, device, " %s",
+		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
 			    "No memory to dump sense data");
 		return;
 	}
@@ -476,8 +499,7 @@ dasd_fba_dump_sense(struct dasd_device *
 	        len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 			       " SORRY - NO VALID SENSE AVAILABLE\n");
 	}
-	MESSAGE_LOG(KERN_ERR, "%s",
-		    page + sizeof(KERN_ERR PRINTK_HEADER));
+	printk(KERN_ERR "%s", page);
 
 	/* dump the Channel Program */
 	/* print first CCWs (maximum 8) */
@@ -498,8 +520,7 @@ dasd_fba_dump_sense(struct dasd_device *
 		len += sprintf(page + len, "\n");
 		act++;
 	}
-	MESSAGE_LOG(KERN_ERR, "%s",
-		    page + sizeof(KERN_ERR PRINTK_HEADER));
+	printk(KERN_ERR "%s", page);
 
 
 	/* print failing CCW area */
@@ -540,8 +561,7 @@ dasd_fba_dump_sense(struct dasd_device *
 		act++;
 	}
 	if (len > 0)
-		MESSAGE_LOG(KERN_ERR, "%s",
-			    page + sizeof(KERN_ERR PRINTK_HEADER));
+		printk(KERN_ERR "%s", page);
 	free_page((unsigned long) page);
 }
 
@@ -576,6 +596,7 @@ static struct dasd_discipline dasd_fba_d
 	.build_cp = dasd_fba_build_cp,
 	.free_cp = dasd_fba_free_cp,
 	.dump_sense = dasd_fba_dump_sense,
+	.dump_sense_dbf = dasd_fba_dump_sense_dbf,
 	.fill_info = dasd_fba_fill_info,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_genhd.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_genhd.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_genhd.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_genhd.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/interrupt.h>
 #include <linux/fs.h>
 #include <linux/blkpg.h>
@@ -163,9 +165,8 @@ int dasd_gendisk_init(void)
 	/* Register to static dasd major 94 */
 	rc = register_blkdev(DASD_MAJOR, "dasd");
 	if (rc != 0) {
-		MESSAGE(KERN_WARNING,
-			"Couldn't register successfully to "
-			"major no %d", DASD_MAJOR);
+		pr_warning("Registering the device driver with major number "
+			   "%d failed\n", DASD_MAJOR);
 		return rc;
 	}
 	return 0;
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_int.h linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_int.h
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_int.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_int.h	2009-06-09 23:05:27.000000000 -0400
@@ -112,6 +112,9 @@ do { \
 				d_data); \
 } while(0)
 
+/* limit size for an errorstring */
+#define ERRORLENGTH 30
+
 /* definition of dbf debug levels */
 #define	DBF_EMERG	0	/* system is unusable			*/
 #define	DBF_ALERT	1	/* action must be taken immediately	*/
@@ -157,7 +160,8 @@ struct dasd_ccw_req {
 	struct dasd_block *block;	/* the originating block device */
 	struct dasd_device *memdev;	/* the device used to allocate this */
 	struct dasd_device *startdev;	/* device the request is started on */
-	struct ccw1 *cpaddr;		/* address of channel program */
+	void *cpaddr;			/* address of ccw or tcw */
+	unsigned char cpmode;		/* 0 = cmd mode, 1 = itcw */
 	char status;			/* status of this request */
 	short retries;			/* A retry counter */
 	unsigned long flags;        	/* flags of this request */
@@ -280,6 +284,8 @@ struct dasd_discipline {
 	dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
 	void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
 			    struct irb *);
+	void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
+			    struct irb *, char *);
 
 	void (*handle_unsolicited_interrupt) (struct dasd_device *,
 					      struct irb *);
@@ -378,7 +384,7 @@ struct dasd_block {
 	struct block_device *bdev;
 	atomic_t open_count;
 
-	unsigned long blocks;	   /* size of volume in blocks */
+	unsigned long long blocks; /* size of volume in blocks */
 	unsigned int bp_block;	   /* bytes per block */
 	unsigned int s2b_shift;	   /* log2 (bp_block/512) */
 
@@ -573,12 +579,14 @@ int dasd_generic_notify(struct ccw_devic
 void dasd_generic_handle_state_change(struct dasd_device *);
 
 int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+char *dasd_get_sense(struct irb *);
 
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
 extern int dasd_probeonly;
 extern int dasd_autodetect;
 extern int dasd_nopav;
+extern int dasd_nofcx;
 
 int dasd_devmap_init(void);
 void dasd_devmap_exit(void);
@@ -623,6 +631,7 @@ struct dasd_ccw_req *dasd_alloc_erp_requ
 					    struct dasd_device *);
 void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
 void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
+void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
 
 /* externals in dasd_3990_erp.c */
 struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_ioctl.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_ioctl.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_ioctl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_ioctl.c	2009-06-09 23:05:27.000000000 -0400
@@ -9,6 +9,9 @@
  *
  * i/o controls for the dasd driver.
  */
+
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/fs.h>
@@ -94,7 +97,8 @@ static int dasd_ioctl_quiesce(struct das
 	if (!capable (CAP_SYS_ADMIN))
 		return -EACCES;
 
-	DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device");
+	dev_info(&base->cdev->dev, "The DASD has been put in the quiesce "
+		 "state\n");
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
 	base->stopped |= DASD_STOPPED_QUIESCE;
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -103,7 +107,7 @@ static int dasd_ioctl_quiesce(struct das
 
 
 /*
- * Quiesce device.
+ * Resume device.
  */
 static int dasd_ioctl_resume(struct dasd_block *block)
 {
@@ -114,7 +118,8 @@ static int dasd_ioctl_resume(struct dasd
 	if (!capable (CAP_SYS_ADMIN))
 		return -EACCES;
 
-	DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device");
+	dev_info(&base->cdev->dev, "I/O operations have been resumed "
+		 "on the DASD\n");
 	spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
 	base->stopped &= ~DASD_STOPPED_QUIESCE;
 	spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -140,13 +145,13 @@ static int dasd_format(struct dasd_block
 		return -EPERM;
 
 	if (base->state != DASD_STATE_BASIC) {
-		DEV_MESSAGE(KERN_WARNING, base, "%s",
-			    "dasd_format: device is not disabled! ");
+		dev_warn(&base->cdev->dev,
+			 "The DASD cannot be formatted while it is enabled\n");
 		return -EBUSY;
 	}
 
 	DBF_DEV_EVENT(DBF_NOTICE, base,
-		      "formatting units %d to %d (%d B blocks) flags %d",
+		      "formatting units %u to %u (%u B blocks) flags %u",
 		      fdata->start_unit,
 		      fdata->stop_unit, fdata->blksize, fdata->intensity);
 
@@ -169,10 +174,9 @@ static int dasd_format(struct dasd_block
 		dasd_sfree_request(cqr, cqr->memdev);
 		if (rc) {
 			if (rc != -ERESTARTSYS)
-				DEV_MESSAGE(KERN_ERR, base,
-					    " Formatting of unit %d failed "
-					    "with rc = %d",
-					    fdata->start_unit, rc);
+				dev_err(&base->cdev->dev,
+					"Formatting unit %d failed with "
+					"rc=%d\n", fdata->start_unit, rc);
 			return rc;
 		}
 		fdata->start_unit++;
@@ -199,8 +203,9 @@ dasd_ioctl_format(struct block_device *b
 	if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
 		return -EFAULT;
 	if (bdev != bdev->bd_contains) {
-		DEV_MESSAGE(KERN_WARNING, block->base, "%s",
-			    "Cannot low-level format a partition");
+		dev_warn(&block->base->cdev->dev,
+			 "The specified DASD is a partition and cannot be "
+			 "formatted\n");
 		return -EINVAL;
 	}
 	return dasd_format(block, &fdata);
@@ -365,9 +370,9 @@ static int dasd_ioctl_readall_cmb(struct
 	return ret;
 }
 
-int
-dasd_ioctl(struct block_device *bdev, fmode_t mode,
-	   unsigned int cmd, unsigned long arg)
+static int
+dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
+	      unsigned int cmd, unsigned long arg)
 {
 	struct dasd_block *block = bdev->bd_disk->private_data;
 	void __user *argp = (void __user *)arg;
@@ -420,3 +425,14 @@ dasd_ioctl(struct block_device *bdev, fm
 		return -EINVAL;
 	}
 }
+
+int dasd_ioctl(struct block_device *bdev, fmode_t mode,
+	       unsigned int cmd, unsigned long arg)
+{
+	int rc;
+
+	lock_kernel();
+	rc = dasd_do_ioctl(bdev, mode, cmd, arg);
+	unlock_kernel();
+	return rc;
+}
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_proc.c linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_proc.c
--- linux-libre-2.6.29-gnu1/drivers/s390/block/dasd_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/block/dasd_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,8 @@
  *
  */
 
+#define KMSG_COMPONENT "dasd"
+
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
@@ -112,7 +114,7 @@ dasd_devices_show(struct seq_file *m, vo
 			seq_printf(m, "n/f	 ");
 		else
 			seq_printf(m,
-				   "at blocksize: %d, %ld blocks, %ld MB",
+				   "at blocksize: %d, %lld blocks, %lld MB",
 				   block->bp_block, block->blocks,
 				   ((block->bp_block >> 9) *
 				    block->blocks) >> 11);
@@ -267,7 +269,7 @@ dasd_statistics_write(struct file *file,
 	buffer = dasd_get_user_string(user_buf, user_len);
 	if (IS_ERR(buffer))
 		return PTR_ERR(buffer);
-	MESSAGE_LOG(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
+	DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer);
 
 	/* check for valid verbs */
 	for (str = buffer; isspace(*str); str++);
@@ -277,33 +279,33 @@ dasd_statistics_write(struct file *file,
 		if (strcmp(str, "on") == 0) {
 			/* switch on statistics profiling */
 			dasd_profile_level = DASD_PROFILE_ON;
-			MESSAGE(KERN_INFO, "%s", "Statistics switched on");
+			pr_info("The statistics feature has been switched "
+				"on\n");
 		} else if (strcmp(str, "off") == 0) {
 			/* switch off and reset statistics profiling */
 			memset(&dasd_global_profile,
 			       0, sizeof (struct dasd_profile_info_t));
 			dasd_profile_level = DASD_PROFILE_OFF;
-			MESSAGE(KERN_INFO, "%s", "Statistics switched off");
+			pr_info("The statistics feature has been switched "
+				"off\n");
 		} else
 			goto out_error;
 	} else if (strncmp(str, "reset", 5) == 0) {
 		/* reset the statistics */
 		memset(&dasd_global_profile, 0,
 		       sizeof (struct dasd_profile_info_t));
-		MESSAGE(KERN_INFO, "%s", "Statistics reset");
+		pr_info("The statistics have been reset\n");
 	} else
 		goto out_error;
 	kfree(buffer);
 	return user_len;
 out_error:
-	MESSAGE(KERN_WARNING, "%s",
-		"/proc/dasd/statistics: only 'set on', 'set off' "
-		"and 'reset' are supported verbs");
+	pr_warning("%s is not a supported value for /proc/dasd/statistics\n",
+		str);
 	kfree(buffer);
 	return -EINVAL;
 #else
-	MESSAGE(KERN_WARNING, "%s",
-		"/proc/dasd/statistics: is not activated in this kernel");
+	pr_warning("/proc/dasd/statistics: is not activated in this kernel\n");
 	return user_len;
 #endif				/* CONFIG_DASD_PROFILE */
 }
@@ -318,7 +320,6 @@ dasd_proc_init(void)
 	dasd_proc_root_entry = proc_mkdir("dasd", NULL);
 	if (!dasd_proc_root_entry)
 		goto out_nodasd;
-	dasd_proc_root_entry->owner = THIS_MODULE;
 	dasd_devices_entry = proc_create("devices",
 					 S_IFREG | S_IRUGO | S_IWUSR,
 					 dasd_proc_root_entry,
@@ -332,7 +333,6 @@ dasd_proc_init(void)
 		goto out_nostatistics;
 	dasd_statistics_entry->read_proc = dasd_statistics_read;
 	dasd_statistics_entry->write_proc = dasd_statistics_write;
-	dasd_statistics_entry->owner = THIS_MODULE;
 	return 0;
 
  out_nostatistics:
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_34xx.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_34xx.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_34xx.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_34xx.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,6 +8,8 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/bio.h>
@@ -18,8 +20,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_34XX: "
-
 /*
  * Pointer to debug area.
  */
@@ -203,8 +203,7 @@ tape_34xx_unsolicited_irq(struct tape_de
 		tape_34xx_schedule_work(device, TO_MSEN);
 	} else {
 		DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
-		PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
-		tape_dump_sense(device, NULL, irb);
+		tape_dump_sense_dbf(device, NULL, irb);
 	}
 	return TAPE_IO_SUCCESS;
 }
@@ -226,9 +225,7 @@ tape_34xx_erp_read_opposite(struct tape_
 		tape_std_read_backward(device, request);
 		return tape_34xx_erp_retry(request);
 	}
-	if (request->op != TO_RBA)
-		PRINT_ERR("read_opposite called with state:%s\n",
-			  tape_op_verbose[request->op]);
+
 	/*
 	 * We tried to read forward and backward, but hat no
 	 * success -> failed.
@@ -241,13 +238,9 @@ tape_34xx_erp_bug(struct tape_device *de
 		  struct irb *irb, int no)
 {
 	if (request->op != TO_ASSIGN) {
-		PRINT_WARN("An unexpected condition #%d was caught in "
-			   "tape error recovery.\n", no);
-		PRINT_WARN("Please report this incident.\n");
-		if (request)
-			PRINT_WARN("Operation of tape:%s\n",
-				   tape_op_verbose[request->op]);
-		tape_dump_sense(device, request, irb);
+		dev_err(&device->cdev->dev, "An unexpected condition %d "
+			"occurred in tape error recovery\n", no);
+		tape_dump_sense_dbf(device, request, irb);
 	}
 	return tape_34xx_erp_failed(request, -EIO);
 }
@@ -261,9 +254,8 @@ tape_34xx_erp_overrun(struct tape_device
 		      struct irb *irb)
 {
 	if (irb->ecw[3] == 0x40) {
-		PRINT_WARN ("Data overrun error between control-unit "
-			    "and drive. Use a faster channel connection, "
-			    "if possible! \n");
+		dev_warn (&device->cdev->dev, "A data overrun occurred between"
+			" the control unit and tape unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	}
 	return tape_34xx_erp_bug(device, request, irb, -1);
@@ -280,7 +272,8 @@ tape_34xx_erp_sequence(struct tape_devic
 		/*
 		 * cu detected incorrect block-id sequence on tape.
 		 */
-		PRINT_WARN("Illegal block-id sequence found!\n");
+		dev_warn (&device->cdev->dev, "The block ID sequence on the "
+			"tape is incorrect\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	}
 	/*
@@ -393,8 +386,6 @@ tape_34xx_unit_check(struct tape_device
 			/* Writing at physical end of volume */
 			return tape_34xx_erp_failed(request, -ENOSPC);
 		default:
-			PRINT_ERR("Invalid op in %s:%i\n",
-				  __func__, __LINE__);
 			return tape_34xx_erp_failed(request, 0);
 		}
 	}
@@ -420,7 +411,8 @@ tape_34xx_unit_check(struct tape_device
 							 irb, -4);
 
 			/* data check is permanent, CU recovery has failed */
-			PRINT_WARN("Permanent read error\n");
+			dev_warn (&device->cdev->dev, "A read error occurred "
+				"that cannot be recovered\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x25:
 			// a write data check occurred
@@ -433,22 +425,26 @@ tape_34xx_unit_check(struct tape_device
 							 irb, -5);
 
 			// data check is permanent, cu-recovery has failed
-			PRINT_WARN("Permanent write error\n");
+			dev_warn (&device->cdev->dev, "A write error on the "
+				"tape cannot be recovered\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x26:
 			/* Data Check (read opposite) occurred. */
 			return tape_34xx_erp_read_opposite(device, request);
 		case 0x28:
 			/* ID-Mark at tape start couldn't be written */
-			PRINT_WARN("ID-Mark could not be written.\n");
+			dev_warn (&device->cdev->dev, "Writing the ID-mark "
+				"failed\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		case 0x31:
 			/* Tape void. Tried to read beyond end of device. */
-			PRINT_WARN("Read beyond end of recorded area.\n");
+			dev_warn (&device->cdev->dev, "Reading the tape beyond"
+				" the end of the recorded area failed\n");
 			return tape_34xx_erp_failed(request, -ENOSPC);
 		case 0x41:
 			/* Record sequence error. */
-			PRINT_WARN("Invalid block-id sequence found.\n");
+			dev_warn (&device->cdev->dev, "The tape contains an "
+				"incorrect block ID sequence\n");
 			return tape_34xx_erp_failed(request, -EIO);
 		default:
 			/* all data checks for 3480 should result in one of
@@ -470,16 +466,12 @@ tape_34xx_unit_check(struct tape_device
 	switch (sense[3]) {
 	case 0x00:
 		/* Unit check with erpa code 0. Report and ignore. */
-		PRINT_WARN("Non-error sense was found. "
-			   "Unit-check will be ignored.\n");
 		return TAPE_IO_SUCCESS;
 	case 0x21:
 		/*
 		 * Data streaming not operational. CU will switch to
 		 * interlock mode. Reissue the command.
 		 */
-		PRINT_WARN("Data streaming not operational. "
-			   "Switching to interlock-mode.\n");
 		return tape_34xx_erp_retry(request);
 	case 0x22:
 		/*
@@ -487,11 +479,8 @@ tape_34xx_unit_check(struct tape_device
 		 * error on the lower interface, internal path not usable,
 		 * or error during cartridge load.
 		 */
-		PRINT_WARN("A path equipment check occurred. One of the "
-			   "following conditions occurred:\n");
-		PRINT_WARN("drive adapter error, buffer error on the lower "
-			   "interface, internal path not usable, error "
-			   "during cartridge load.\n");
+		dev_warn (&device->cdev->dev, "A path equipment check occurred"
+			" for the tape device\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x24:
 		/*
@@ -514,7 +503,6 @@ tape_34xx_unit_check(struct tape_device
 		 * but the hardware isn't capable to do idrc, or a perform
 		 * subsystem func is issued and the CU is not on-line.
 		 */
-		PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x2a:
 		/*
@@ -552,23 +540,26 @@ tape_34xx_unit_check(struct tape_device
 		 * reading the format id mark or that that format specified
 		 * is not supported by the drive.
 		 */
-		PRINT_WARN("Drive not capable processing the tape format!\n");
+		dev_warn (&device->cdev->dev, "The tape unit cannot process "
+			"the tape format\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 	case 0x30:
 		/* The medium is write protected. */
-		PRINT_WARN("Medium is write protected!\n");
+		dev_warn (&device->cdev->dev, "The tape medium is write-"
+			"protected\n");
 		return tape_34xx_erp_failed(request, -EACCES);
 	case 0x32:
 		// Tension loss. We cannot recover this, it's an I/O error.
-		PRINT_WARN("The drive lost tape tension.\n");
+		dev_warn (&device->cdev->dev, "The tape does not have the "
+			"required tape tension\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x33:
 		/*
 		 * Load Failure. The cartridge was not inserted correctly or
 		 * the tape is not threaded correctly.
 		 */
-		PRINT_WARN("Cartridge load failure. Reload the cartridge "
-			   "and try again.\n");
+		dev_warn (&device->cdev->dev, "The tape unit failed to load"
+			" the cartridge\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x34:
@@ -576,8 +567,8 @@ tape_34xx_unit_check(struct tape_device
 		 * Unload failure. The drive cannot maintain tape tension
 		 * and control tape movement during an unload operation.
 		 */
-		PRINT_WARN("Failure during cartridge unload. "
-			   "Please try manually.\n");
+		dev_warn (&device->cdev->dev, "Automatic unloading of the tape"
+			" cartridge failed\n");
 		if (request->op == TO_RUN)
 			return tape_34xx_erp_failed(request, -EIO);
 		return tape_34xx_erp_bug(device, request, irb, sense[3]);
@@ -589,8 +580,8 @@ tape_34xx_unit_check(struct tape_device
 		 * - the cartridge loader does not respond correctly
 		 * - a failure occurs during an index, load, or unload cycle
 		 */
-		PRINT_WARN("Equipment check! Please check the drive and "
-			   "the cartridge loader.\n");
+		dev_warn (&device->cdev->dev, "An equipment check has occurred"
+			" on the tape unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x36:
 		if (device->cdev->id.driver_info == tape_3490)
@@ -603,7 +594,8 @@ tape_34xx_unit_check(struct tape_device
 		 * Tape length error. The tape is shorter than reported in
 		 * the beginning-of-tape data.
 		 */
-		PRINT_WARN("Tape length error.\n");
+		dev_warn (&device->cdev->dev, "The tape information states an"
+			" incorrect length\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x38:
 		/*
@@ -620,12 +612,12 @@ tape_34xx_unit_check(struct tape_device
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x3a:
 		/* Drive switched to not ready. */
-		PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
-			   "to ready position and try again.\n");
+		dev_warn (&device->cdev->dev, "The tape unit is not ready\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x3b:
 		/* Manual rewind or unload. This causes an I/O error. */
-		PRINT_WARN("Medium was rewound or unloaded manually.\n");
+		dev_warn (&device->cdev->dev, "The tape medium has been "
+			"rewound or unloaded manually\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x42:
@@ -633,7 +625,8 @@ tape_34xx_unit_check(struct tape_device
 		 * Degraded mode. A condition that can cause degraded
 		 * performance is detected.
 		 */
-		PRINT_WARN("Subsystem is running in degraded mode.\n");
+		dev_warn (&device->cdev->dev, "The tape subsystem is running "
+			"in degraded mode\n");
 		return tape_34xx_erp_retry(request);
 	case 0x43:
 		/* Drive not ready. */
@@ -652,7 +645,6 @@ tape_34xx_unit_check(struct tape_device
 					break;
 			}
 		}
-		PRINT_WARN("The drive is not ready.\n");
 		return tape_34xx_erp_failed(request, -ENOMEDIUM);
 	case 0x44:
 		/* Locate Block unsuccessful. */
@@ -663,7 +655,8 @@ tape_34xx_unit_check(struct tape_device
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x45:
 		/* The drive is assigned to a different channel path. */
-		PRINT_WARN("The drive is assigned elsewhere.\n");
+		dev_warn (&device->cdev->dev, "The tape unit is already "
+			"assigned\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x46:
 		/*
@@ -671,11 +664,12 @@ tape_34xx_unit_check(struct tape_device
 		 * the power supply may be switched off or
 		 * the drive address may not be set correctly.
 		 */
-		PRINT_WARN("The drive is not on-line.");
+		dev_warn (&device->cdev->dev, "The tape unit is not online\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x47:
 		/* Volume fenced. CU reports volume integrity is lost. */
-		PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+		dev_warn (&device->cdev->dev, "The control unit has fenced "
+			"access to the tape volume\n");
 		tape_34xx_delete_sbid_from(device, 0);
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x48:
@@ -683,20 +677,21 @@ tape_34xx_unit_check(struct tape_device
 		return tape_34xx_erp_retry(request);
 	case 0x49:
 		/* Bus out check. A parity check error on the bus was found. */
-		PRINT_WARN("Bus out check. A data transfer over the bus "
-			   "has been corrupted.\n");
+		dev_warn (&device->cdev->dev, "A parity error occurred on the "
+			"tape bus\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4a:
 		/* Control unit erp failed. */
-		PRINT_WARN("The control unit I/O error recovery failed.\n");
+		dev_warn (&device->cdev->dev, "I/O error recovery failed on "
+			"the tape control unit\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4b:
 		/*
 		 * CU and drive incompatible. The drive requests micro-program
 		 * patches, which are not available on the CU.
 		 */
-		PRINT_WARN("The drive needs microprogram patches from the "
-			   "control unit, which are not available.\n");
+		dev_warn (&device->cdev->dev, "The tape unit requires a "
+			"firmware update\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x4c:
 		/*
@@ -721,8 +716,8 @@ tape_34xx_unit_check(struct tape_device
 			 * the block to be written is larger than allowed for
 			 * buffered mode.
 			 */
-			PRINT_WARN("Maximum block size for buffered "
-				   "mode exceeded.\n");
+			dev_warn (&device->cdev->dev, "The maximum block size"
+				" for buffered mode is exceeded\n");
 			return tape_34xx_erp_failed(request, -ENOBUFS);
 		}
 		/* This erpa is reserved for 3480. */
@@ -759,22 +754,20 @@ tape_34xx_unit_check(struct tape_device
 		return tape_34xx_erp_retry(request);
 	case 0x55:
 		/* Channel interface recovery (permanent). */
-		PRINT_WARN("A permanent channel interface error occurred.\n");
+		dev_warn (&device->cdev->dev, "A channel interface error cannot be"
+			" recovered\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x56:
 		/* Channel protocol error. */
-		PRINT_WARN("A channel protocol error occurred.\n");
+		dev_warn (&device->cdev->dev, "A channel protocol error "
+			"occurred\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x57:
 		if (device->cdev->id.driver_info == tape_3480) {
 			/* Attention intercept. */
-			PRINT_WARN("An attention intercept occurred, "
-				   "which will be recovered.\n");
 			return tape_34xx_erp_retry(request);
 		} else {
 			/* Global status intercept. */
-			PRINT_WARN("An global status intercept was received, "
-				   "which will be recovered.\n");
 			return tape_34xx_erp_retry(request);
 		}
 	case 0x5a:
@@ -782,42 +775,31 @@ tape_34xx_unit_check(struct tape_device
 		 * Tape length incompatible. The tape inserted is too long,
 		 * which could cause damage to the tape or the drive.
 		 */
-		PRINT_WARN("Tape Length Incompatible\n");
-		PRINT_WARN("Tape length exceeds IBM enhanced capacity "
-			"cartdridge length or a medium\n");
-		PRINT_WARN("with EC-CST identification mark has been mounted "
-			"in a device that writes\n");
-		PRINT_WARN("3480 or 3480 XF format.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support "
+			"the tape length\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5b:
 		/* Format 3480 XF incompatible */
 		if (sense[1] & SENSE_BEGINNING_OF_TAPE)
 			/* The tape will get overwritten. */
 			return tape_34xx_erp_retry(request);
-		PRINT_WARN("Format 3480 XF Incompatible\n");
-		PRINT_WARN("Medium has been created in 3480 format. "
-			"To change the format writes\n");
-		PRINT_WARN("must be issued at BOT.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" format 3480 XF\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5c:
 		/* Format 3480-2 XF incompatible */
-		PRINT_WARN("Format 3480-2 XF Incompatible\n");
-		PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support tape "
+			"format 3480-2 XF\n");
 		return tape_34xx_erp_failed(request, -EIO);
 	case 0x5d:
 		/* Tape length violation. */
-		PRINT_WARN("Tape Length Violation\n");
-		PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "
-			"Cartdridge System Tape length.\n");
-		PRINT_WARN("This may cause damage to the drive or tape when "
-			"processing to the EOV\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" the current tape length\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 	case 0x5e:
 		/* Compaction algorithm incompatible. */
-		PRINT_WARN("Compaction Algorithm Incompatible\n");
-		PRINT_WARN("The volume is recorded using an incompatible "
-			"compaction algorithm,\n");
-		PRINT_WARN("which is not supported by the device.\n");
+		dev_warn (&device->cdev->dev, "The tape unit does not support"
+			" the compaction algorithm\n");
 		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
 
 		/* The following erpas should have been covered earlier. */
@@ -848,7 +830,6 @@ tape_34xx_irq(struct tape_device *device
 	    (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
 	    (request->op == TO_WRI)) {
 		/* Write at end of volume */
-		PRINT_INFO("End of volume\n"); /* XXX */
 		return tape_34xx_erp_failed(request, -ENOSPC);
 	}
 
@@ -869,9 +850,7 @@ tape_34xx_irq(struct tape_device *device
 	}
 
 	DBF_EVENT(6, "xunknownirq\n");
-	PRINT_ERR("Unexpected interrupt.\n");
-	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
-	tape_dump_sense(device, request, irb);
+	tape_dump_sense_dbf(device, request, irb);
 	return TAPE_IO_STOP;
 }
 
@@ -1315,12 +1294,6 @@ tape_34xx_online(struct ccw_device *cdev
 	);
 }
 
-static int
-tape_34xx_offline(struct ccw_device *cdev)
-{
-	return tape_generic_offline(cdev->dev.driver_data);
-}
-
 static struct ccw_driver tape_34xx_driver = {
 	.name = "tape_34xx",
 	.owner = THIS_MODULE,
@@ -1328,7 +1301,7 @@ static struct ccw_driver tape_34xx_drive
 	.probe = tape_generic_probe,
 	.remove = tape_generic_remove,
 	.set_online = tape_34xx_online,
-	.set_offline = tape_34xx_offline,
+	.set_offline = tape_generic_offline,
 };
 
 static int
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_3590.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_3590.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_3590.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_3590.c	2009-06-09 23:05:27.000000000 -0400
@@ -8,12 +8,15 @@
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/bio.h>
 #include <asm/ebcdic.h>
 
 #define TAPE_DBF_AREA	tape_3590_dbf
+#define BUFSIZE 512	/* size of buffers for dynamic generated messages */
 
 #include "tape.h"
 #include "tape_std.h"
@@ -36,7 +39,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
  * - Read Alternate:		 implemented
  *******************************************************************/
 
-#define PRINTK_HEADER "TAPE_3590: "
+#define KMSG_COMPONENT "tape"
 
 static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
 	[0x00] = "",
@@ -661,8 +664,7 @@ tape_3590_bread(struct tape_device *devi
 			ccw++;
 			dst += TAPEBLOCK_HSEC_SIZE;
 		}
-		if (off > bv->bv_len)
-			BUG();
+		BUG_ON(off > bv->bv_len);
 	}
 	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
 	DBF_EVENT(6, "xBREDccwg\n");
@@ -726,7 +728,7 @@ static void tape_3590_med_state_set(stru
 	}
 	c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
 	if (sense->flags & MSENSE_CRYPT_MASK) {
-		PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
+		DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
 		c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
 	} else	{
 		DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
@@ -847,8 +849,7 @@ tape_3590_unsolicited_irq(struct tape_de
 		tape_3590_schedule_work(device, TO_READ_ATTMSG);
 	} else {
 		DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
-		PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
-		tape_dump_sense(device, NULL, irb);
+		tape_dump_sense_dbf(device, NULL, irb);
 	}
 	/* check medium state */
 	tape_3590_schedule_work(device, TO_MSEN);
@@ -876,8 +877,6 @@ tape_3590_erp_basic(struct tape_device *
 	case SENSE_BRA_DRE:
 		return tape_3590_erp_failed(device, request, irb, rc);
 	default:
-		PRINT_ERR("Unknown BRA %x - This should not happen!\n",
-			  sense->bra);
 		BUG();
 		return TAPE_IO_STOP;
 	}
@@ -910,7 +909,8 @@ tape_3590_erp_swap(struct tape_device *d
 	 * should proceed with the new tape... this
 	 * should probably be done in user space!
 	 */
-	PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
+	dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
+		"different tape unit\n");
 	return tape_3590_erp_basic(device, request, irb, -EIO);
 }
 
@@ -985,8 +985,6 @@ tape_3590_erp_read_opposite(struct tape_
 		return tape_3590_erp_failed(device, request, irb, -EIO);
 		break;
 	default:
-		PRINT_WARN("read_opposite_recovery_called_with_op: %s\n",
-			   tape_op_verbose[request->op]);
 		return tape_3590_erp_failed(device, request, irb, -EIO);
 	}
 }
@@ -998,50 +996,61 @@ static void
 tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f70.emc) {
 	case 0x02:
-		PRINT_WARN("(%s): Data degraded\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Data degraded");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): Data degraded in partion %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+		snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+			sense->fmt.f70.mp);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): Medium degraded\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Medium degraded");
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): Medium degraded in partition %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+		snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
+			sense->fmt.f70.mp);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): Block 0 Error\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Block 0 Error");
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Medium Exception 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.md);
+		snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
+			sense->fmt.f70.md);
 		break;
 	default:
-		PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f70.emc);
 		break;
 	}
 	/* Service Message */
 	switch (sense->fmt.f70.smc) {
 	case 0x02:
-		PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.md);
+		snprintf(service, BUFSIZE, "Reference Media maintenance "
+			"procedure %i", sense->fmt.f70.md);
 		break;
 	default:
-		PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f70.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f70.smc);
 		break;
 	}
+
+	dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
+		"service %s\n", exception, service);
+
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1051,108 +1060,108 @@ static void
 tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f71.emc) {
 	case 0x01:
-		PRINT_WARN("(%s): Effect of failure is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Effect of failure is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): CU Exception - no performance impact\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "CU Exception - no performance "
+			"impact");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on channel "
+			"interface 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on device path "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on library path "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
+			sense->fmt.f71.md[0]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "CU Exception on partition "
+			"0x%02x", sense->fmt.f71.md[0]);
 		break;
 	default:
-		PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f71.emc);
 	}
 	/* Service Message */
 	switch (sense->fmt.f71.smc) {
 	case 0x01:
-		PRINT_WARN("(%s): Repair impact is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair impact is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): Repair will not impact cu performance\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will not impact cu "
+			"performance");
 		break;
 	case 0x03:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable node "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable node "
+				"0x%x on CU", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable nodes "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
+				sense->fmt.f71.md[2]);
 		break;
 	case 0x04:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable cannel path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path 0x%x on CU",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable cannel paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable cannel"
+				" paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x05:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable device path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable device"
+				" path 0x%x on CU", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable device paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable device"
+				" paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x06:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable library path "
-				   "0x%x on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"library path 0x%x on CU",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable library paths "
-				   "(0x%x-0x%x) on CU\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"library paths (0x%x-0x%x) on CU",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Repair will disable access to CU\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will disable access to CU");
 		break;
 	default:
-		PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f71.smc);
 	}
+
+	dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
+		" %s, service %s\n", exception, service);
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1162,111 +1171,109 @@ static void
 tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
 {
 	struct tape_3590_sense *sense;
+	char *exception, *service;
+
+	exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+	service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+	if (!exception || !service)
+		goto out_nomem;
 
 	sense = (struct tape_3590_sense *) irb->ecw;
 	/* Exception Message */
 	switch (sense->fmt.f71.emc) {
 	case 0x01:
-		PRINT_WARN("(%s): Effect of failure is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "Effect of failure is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): DV Exception - no performance impact\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception - no performance"
+			" impact");
 		break;
 	case 0x03:
-		PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on channel "
+			"interface 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x04:
-		PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
+			sense->fmt.f71.md[0]);
 		break;
 	case 0x05:
-		PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+		snprintf(exception, BUFSIZE, "DV Exception on message display"
+			" 0x%02x", sense->fmt.f71.md[0]);
 		break;
 	case 0x06:
-		PRINT_WARN("(%s): DV Exception in tape path\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception in tape path");
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): DV Exception in drive\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(exception, BUFSIZE, "DV Exception in drive");
 		break;
 	default:
-		PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+		snprintf(exception, BUFSIZE, "0x%02x",
+			sense->fmt.f71.emc);
 	}
 	/* Service Message */
 	switch (sense->fmt.f71.smc) {
 	case 0x01:
-		PRINT_WARN("(%s): Repair impact is unknown\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair impact is unknown");
 		break;
 	case 0x02:
-		PRINT_WARN("(%s): Repair will not impact device performance\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will not impact device "
+			"performance");
 		break;
 	case 0x03:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable channel path "
-				   "0x%x on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path 0x%x on DV",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable channel path "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"channel path (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x04:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable interface 0x%x "
-				   "on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"interface 0x%x on DV", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable interfaces "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"interfaces (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x05:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable loader 0x%x "
-				   "on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable loader"
+				" 0x%x on DV", sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable loader "
-				   "(0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable loader"
+				" (0x%x-0x%x) on DV",
+				sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x07:
-		PRINT_WARN("(%s): Repair will disable access to DV\n",
-			   dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Repair will disable access to DV");
 		break;
 	case 0x08:
 		if (sense->fmt.f71.mdf == 0)
-			PRINT_WARN("(%s): Repair will disable message "
-				   "display 0x%x on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"message display 0x%x on DV",
+				sense->fmt.f71.md[1]);
 		else
-			PRINT_WARN("(%s): Repair will disable message "
-				   "displays (0x%x-0x%x) on DV\n",
-				   dev_name(&device->cdev->dev),
-				   sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+			snprintf(service, BUFSIZE, "Repair will disable "
+				"message displays (0x%x-0x%x) on DV",
+				 sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
 		break;
 	case 0x09:
-		PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
+		snprintf(service, BUFSIZE, "Clean DV");
 		break;
 	default:
-		PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+		snprintf(service, BUFSIZE, "0x%02x",
+			sense->fmt.f71.smc);
 	}
+
+	dev_warn (&device->cdev->dev, "Device subsystem information: exception"
+		" %s, service %s\n", exception, service);
+out_nomem:
+	kfree(exception);
+	kfree(service);
 }
 
 /*
@@ -1282,46 +1289,44 @@ tape_3590_print_era_msg(struct tape_devi
 		return;
 	if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
 		if (tape_3590_msg[sense->mc] != NULL)
-			PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
-				   tape_3590_msg[sense->mc]);
-		else {
-			PRINT_WARN("(%s): Message Code 0x%x\n",
-				   dev_name(&device->cdev->dev), sense->mc);
-		}
+			dev_warn (&device->cdev->dev, "The tape unit has "
+				"issued sense message %s\n",
+				tape_3590_msg[sense->mc]);
+		else
+			dev_warn (&device->cdev->dev, "The tape unit has "
+				"issued an unknown sense message code 0x%x\n",
+				sense->mc);
 		return;
 	}
 	if (sense->mc == 0xf0) {
 		/* Standard Media Information Message */
-		PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
-			   "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
-			   sense->fmt.f70.sev, sense->mc,
-			   sense->fmt.f70.emc, sense->fmt.f70.smc,
-			   sense->fmt.f70.refcode, sense->fmt.f70.mid,
-			   sense->fmt.f70.fid);
+		dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
+			"RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
+			sense->fmt.f70.emc, sense->fmt.f70.smc,
+			sense->fmt.f70.refcode, sense->fmt.f70.mid,
+			sense->fmt.f70.fid);
 		tape_3590_print_mim_msg_f0(device, irb);
 		return;
 	}
 	if (sense->mc == 0xf1) {
 		/* Standard I/O Subsystem Service Information Message */
-		PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
-			   "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.sev,
-			   device->cdev->id.dev_model,
-			   sense->mc, sense->fmt.f71.emc,
-			   sense->fmt.f71.smc, sense->fmt.f71.refcode1,
-			   sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+		dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
+			" MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+			sense->fmt.f71.sev, device->cdev->id.dev_model,
+			sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+			sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+			sense->fmt.f71.refcode3);
 		tape_3590_print_io_sim_msg_f1(device, irb);
 		return;
 	}
 	if (sense->mc == 0xf2) {
 		/* Standard Device Service Information Message */
-		PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
-			   "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
-			   dev_name(&device->cdev->dev), sense->fmt.f71.sev,
-			   device->cdev->id.dev_model,
-			   sense->mc, sense->fmt.f71.emc,
-			   sense->fmt.f71.smc, sense->fmt.f71.refcode1,
-			   sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+		dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
+			", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+			sense->fmt.f71.sev, device->cdev->id.dev_model,
+			sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+			sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+			sense->fmt.f71.refcode3);
 		tape_3590_print_dev_sim_msg_f2(device, irb);
 		return;
 	}
@@ -1329,8 +1334,8 @@ tape_3590_print_era_msg(struct tape_devi
 		/* Standard Library Service Information Message */
 		return;
 	}
-	PRINT_WARN("(%s): Device Message(%x)\n",
-		   dev_name(&device->cdev->dev), sense->mc);
+	dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
+		"sense message code %x\n", sense->mc);
 }
 
 static int tape_3590_crypt_error(struct tape_device *device,
@@ -1355,9 +1360,8 @@ static int tape_3590_crypt_error(struct
 		/* No connection to EKM */
 		return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
 
-	PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
-	PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
-		drv_rc, ekm_rc1, ekm_rc2);
+	dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
+		"encryption key from EKM\n");
 
 	return tape_3590_erp_basic(device, request, irb, -ENOKEY);
 }
@@ -1443,8 +1447,6 @@ tape_3590_unit_check(struct tape_device
 		 * print additional msg since default msg
 		 * "device intervention" is not very meaningfull
 		 */
-		PRINT_WARN("(%s): Tape operation when medium not loaded\n",
-			   dev_name(&device->cdev->dev));
 		tape_med_state_set(device, MS_UNLOADED);
 		tape_3590_schedule_work(device, TO_CRYPT_OFF);
 		return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@@ -1490,19 +1492,13 @@ tape_3590_unit_check(struct tape_device
 		return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
 
 	case 0x6020:
-		PRINT_WARN("(%s): Cartridge of wrong type ?\n",
-			   dev_name(&device->cdev->dev));
 		return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
 
 	case 0x8011:
-		PRINT_WARN("(%s): Another host has reserved the tape device\n",
-			   dev_name(&device->cdev->dev));
 		return tape_3590_erp_basic(device, request, irb, -EPERM);
 	case 0x8013:
-		PRINT_WARN("(%s): Another host has privileged access to the "
-			   "tape device\n", dev_name(&device->cdev->dev));
-		PRINT_WARN("(%s): To solve the problem unload the current "
-			   "cartridge!\n", dev_name(&device->cdev->dev));
+		dev_warn (&device->cdev->dev, "A different host has privileged"
+			" access to the tape unit\n");
 		return tape_3590_erp_basic(device, request, irb, -EPERM);
 	default:
 		return tape_3590_erp_basic(device, request, irb, -EIO);
@@ -1552,9 +1548,7 @@ tape_3590_irq(struct tape_device *device
 	}
 
 	DBF_EVENT(6, "xunknownirq\n");
-	PRINT_ERR("Unexpected interrupt.\n");
-	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
-	tape_dump_sense(device, request, irb);
+	tape_dump_sense_dbf(device, request, irb);
 	return TAPE_IO_STOP;
 }
 
@@ -1609,7 +1603,6 @@ tape_3590_setup_device(struct tape_devic
 	if (rc)
 		goto fail_rdc_data;
 	if (rdc_data->data[31] == 0x13) {
-		PRINT_INFO("Device has crypto support\n");
 		data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
 		tape_3592_disable_crypt(device);
 	} else {
@@ -1714,19 +1707,13 @@ tape_3590_online(struct ccw_device *cdev
 				   &tape_discipline_3590);
 }
 
-static int
-tape_3590_offline(struct ccw_device *cdev)
-{
-	return tape_generic_offline(cdev->dev.driver_data);
-}
-
 static struct ccw_driver tape_3590_driver = {
 	.name = "tape_3590",
 	.owner = THIS_MODULE,
 	.ids = tape_3590_ids,
 	.probe = tape_generic_probe,
 	.remove = tape_generic_remove,
-	.set_offline = tape_3590_offline,
+	.set_offline = tape_generic_offline,
 	.set_online = tape_3590_online,
 };
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_block.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_block.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_block.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_block.c	2009-06-09 23:05:27.000000000 -0400
@@ -10,6 +10,8 @@
  *		 Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/blkdev.h>
@@ -23,8 +25,6 @@
 
 #include "tape.h"
 
-#define PRINTK_HEADER "TAPE_BLOCK: "
-
 #define TAPEBLOCK_MAX_SEC	100
 #define TAPEBLOCK_MIN_REQUEUE	3
 
@@ -279,8 +279,6 @@ tapeblock_cleanup_device(struct tape_dev
 	tape_put_device(device);
 
 	if (!device->blk_data.disk) {
-		PRINT_ERR("(%s): No gendisk to clean up!\n",
-			dev_name(&device->cdev->dev));
 		goto cleanup_queue;
 	}
 
@@ -314,7 +312,8 @@ tapeblock_revalidate_disk(struct gendisk
 	if (!device->blk_data.medium_changed)
 		return 0;
 
-	PRINT_INFO("Detecting media size...\n");
+	dev_info(&device->cdev->dev, "Determining the size of the recorded "
+		"area...\n");
 	rc = tape_mtop(device, MTFSFM, 1);
 	if (rc)
 		return rc;
@@ -341,7 +340,8 @@ tapeblock_revalidate_disk(struct gendisk
 	device->bof = rc;
 	nr_of_blks -= rc;
 
-	PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+	dev_info(&device->cdev->dev, "The size of the recorded area is %i "
+		"blocks\n", nr_of_blks);
 	set_capacity(device->blk_data.disk,
 		nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
 
@@ -376,8 +376,8 @@ tapeblock_open(struct block_device *bdev
 
 	if (device->required_tapemarks) {
 		DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
-		PRINT_ERR("TBLOCK: Refusing to open tape with missing"
-			" end of file marks.\n");
+		dev_warn(&device->cdev->dev, "Opening the tape failed because"
+			" of missing end-of-file marks\n");
 		rc = -EPERM;
 		goto put_device;
 	}
@@ -452,7 +452,6 @@ tapeblock_ioctl(
 			rc = -EINVAL;
 			break;
 		default:
-			PRINT_WARN("invalid ioctl 0x%x\n", command);
 			rc = -EINVAL;
 	}
 
@@ -474,7 +473,6 @@ tapeblock_init(void)
 
 	if (tapeblock_major == 0)
 		tapeblock_major = rc;
-	PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
 	return 0;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_char.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_char.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_char.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_char.c	2009-06-09 23:05:27.000000000 -0400
@@ -24,8 +24,6 @@
 #include "tape_std.h"
 #include "tape_class.h"
 
-#define PRINTK_HEADER "TAPE_CHAR: "
-
 #define TAPECHAR_MAJOR		0	/* get dynamic major */
 
 /*
@@ -102,8 +100,6 @@ tapechar_check_idalbuffer(struct tape_de
 	if (block_size > MAX_BLOCKSIZE) {
 		DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
 			block_size, MAX_BLOCKSIZE);
-		PRINT_ERR("Invalid blocksize (%zd> %d)\n",
-			block_size, MAX_BLOCKSIZE);
 		return -EINVAL;
 	}
 
@@ -485,7 +481,6 @@ tapechar_init (void)
 		return -1;
 
 	tapechar_major = MAJOR(dev);
-	PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
 
 	return 0;
 }
@@ -496,7 +491,5 @@ tapechar_init (void)
 void
 tapechar_exit(void)
 {
-	PRINT_INFO("tape releases major %d for character devices\n",
-		tapechar_major);
 	unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_core.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_core.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_core.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_core.c	2009-06-09 23:05:27.000000000 -0400
@@ -11,6 +11,7 @@
  *		 Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
 #include <linux/module.h>
 #include <linux/init.h>	     // for kernel parameters
 #include <linux/kmod.h>	     // for requesting modules
@@ -25,7 +26,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_CORE: "
 #define LONG_BUSY_TIMEOUT 180 /* seconds */
 
 static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
@@ -214,13 +214,13 @@ tape_med_state_set(struct tape_device *d
 	switch(newstate){
 	case MS_UNLOADED:
 		device->tape_generic_status |= GMT_DR_OPEN(~0);
-		PRINT_INFO("(%s): Tape is unloaded\n",
-			   dev_name(&device->cdev->dev));
+		dev_info(&device->cdev->dev, "The tape cartridge has been "
+			"successfully unloaded\n");
 		break;
 	case MS_LOADED:
 		device->tape_generic_status &= ~GMT_DR_OPEN(~0);
-		PRINT_INFO("(%s): Tape has been mounted\n",
-			   dev_name(&device->cdev->dev));
+		dev_info(&device->cdev->dev, "A tape cartridge has been "
+			"mounted\n");
 		break;
 	default:
 		// print nothing
@@ -333,7 +333,6 @@ tape_generic_online(struct tape_device *
 	/* Let the discipline have a go at the device. */
 	device->discipline = discipline;
 	if (!try_module_get(discipline->owner)) {
-		PRINT_ERR("Cannot get module. Module gone.\n");
 		return -EINVAL;
 	}
 
@@ -388,10 +387,12 @@ tape_cleanup_device(struct tape_device *
  * Manual offline is only allowed while the drive is not in use.
  */
 int
-tape_generic_offline(struct tape_device *device)
+tape_generic_offline(struct ccw_device *cdev)
 {
+	struct tape_device *device;
+
+	device = cdev->dev.driver_data;
 	if (!device) {
-		PRINT_ERR("tape_generic_offline: no such device\n");
 		return -ENODEV;
 	}
 
@@ -413,9 +414,6 @@ tape_generic_offline(struct tape_device
 			DBF_EVENT(3, "(%08x): Set offline failed "
 				"- drive in use.\n",
 				device->cdev_id);
-			PRINT_WARN("(%s): Set offline failed "
-				"- drive in use.\n",
-				dev_name(&device->cdev->dev));
 			spin_unlock_irq(get_ccwdev_lock(device->cdev));
 			return -EBUSY;
 	}
@@ -435,14 +433,11 @@ tape_alloc_device(void)
 	device = kzalloc(sizeof(struct tape_device), GFP_KERNEL);
 	if (device == NULL) {
 		DBF_EXCEPTION(2, "ti:no mem\n");
-		PRINT_INFO ("can't allocate memory for "
-			    "tape info structure\n");
 		return ERR_PTR(-ENOMEM);
 	}
 	device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA);
 	if (device->modeset_byte == NULL) {
 		DBF_EXCEPTION(2, "ti:no mem\n");
-		PRINT_INFO("can't allocate memory for modeset byte\n");
 		kfree(device);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -490,7 +485,6 @@ tape_put_device(struct tape_device *devi
 	} else {
 		if (remain < 0) {
 			DBF_EVENT(4, "put device without reference\n");
-			PRINT_ERR("put device without reference\n");
 		} else {
 			DBF_EVENT(4, "tape_free_device(%p)\n", device);
 			kfree(device->modeset_byte);
@@ -538,8 +532,6 @@ tape_generic_probe(struct ccw_device *cd
 	ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
 	if (ret) {
 		tape_put_device(device);
-		PRINT_ERR("probe failed for tape device %s\n",
-			  dev_name(&cdev->dev));
 		return ret;
 	}
 	cdev->dev.driver_data = device;
@@ -547,7 +539,6 @@ tape_generic_probe(struct ccw_device *cd
 	device->cdev = cdev;
 	ccw_device_get_id(cdev, &dev_id);
 	device->cdev_id = devid_to_int(&dev_id);
-	PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
 	return ret;
 }
 
@@ -584,7 +575,6 @@ tape_generic_remove(struct ccw_device *c
 
 	device = cdev->dev.driver_data;
 	if (!device) {
-		PRINT_ERR("No device pointer in tape_generic_remove!\n");
 		return;
 	}
 	DBF_LH(3, "(%08x): tape_generic_remove(%p)\n", device->cdev_id, cdev);
@@ -615,10 +605,8 @@ tape_generic_remove(struct ccw_device *c
 			 */
 			DBF_EVENT(3, "(%08x): Drive in use vanished!\n",
 				device->cdev_id);
-			PRINT_WARN("(%s): Drive in use vanished - "
-				"expect trouble!\n",
-				dev_name(&device->cdev->dev));
-			PRINT_WARN("State was %i\n", device->tape_state);
+			dev_warn(&device->cdev->dev, "A tape unit was detached"
+				" while in use\n");
 			tape_state_set(device, TS_NOT_OPER);
 			__tape_discard_requests(device);
 			spin_unlock_irq(get_ccwdev_lock(device->cdev));
@@ -639,8 +627,7 @@ tape_alloc_request(int cplength, int dat
 {
 	struct tape_request *request;
 
-	if (datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
-		BUG();
+	BUG_ON(datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
 
 	DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize);
 
@@ -797,8 +784,7 @@ static void tape_long_busy_timeout(unsig
 	device = (struct tape_device *) data;
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	request = list_entry(device->req_queue.next, struct tape_request, list);
-	if (request->status != TAPE_REQUEST_LONG_BUSY)
-		BUG();
+	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);
@@ -830,30 +816,6 @@ __tape_end_request(
 }
 
 /*
- * Write sense data to console/dbf
- */
-void
-tape_dump_sense(struct tape_device* device, struct tape_request *request,
-		struct irb *irb)
-{
-	unsigned int *sptr;
-
-	PRINT_INFO("-------------------------------------------------\n");
-	PRINT_INFO("DSTAT : %02x  CSTAT: %02x	CPA: %04x\n",
-		   irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
-	PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
-	if (request != NULL)
-		PRINT_INFO("OP	  : %s\n", tape_op_verbose[request->op]);
-
-	sptr = (unsigned int *) irb->ecw;
-	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
-		   sptr[0], sptr[1], sptr[2], sptr[3]);
-	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
-		   sptr[4], sptr[5], sptr[6], sptr[7]);
-	PRINT_INFO("--------------------------------------------------\n");
-}
-
-/*
  * Write sense data to dbf
  */
 void
@@ -1051,8 +1013,6 @@ __tape_do_irq (struct ccw_device *cdev,
 
 	device = (struct tape_device *) cdev->dev.driver_data;
 	if (device == NULL) {
-		PRINT_ERR("could not get device structure for %s "
-			  "in interrupt\n", dev_name(&cdev->dev));
 		return;
 	}
 	request = (struct tape_request *) intparm;
@@ -1064,13 +1024,13 @@ __tape_do_irq (struct ccw_device *cdev,
 		/* FIXME: What to do with the request? */
 		switch (PTR_ERR(irb)) {
 			case -ETIMEDOUT:
-				PRINT_WARN("(%s): Request timed out\n",
+				DBF_LH(1, "(%s): Request timed out\n",
 					dev_name(&cdev->dev));
 			case -EIO:
 				__tape_end_request(device, request, -EIO);
 				break;
 			default:
-				PRINT_ERR("(%s): Unexpected i/o error %li\n",
+				DBF_LH(1, "(%s): Unexpected i/o error %li\n",
 					dev_name(&cdev->dev),
 					PTR_ERR(irb));
 		}
@@ -1182,8 +1142,6 @@ __tape_do_irq (struct ccw_device *cdev,
 		default:
 			if (rc > 0) {
 				DBF_EVENT(6, "xunknownrc\n");
-				PRINT_ERR("Invalid return code from discipline "
-				  	"interrupt function.\n");
 				__tape_end_request(device, request, -EIO);
 			} else {
 				__tape_end_request(device, request, rc);
@@ -1323,7 +1281,6 @@ EXPORT_SYMBOL(tape_state_set);
 EXPORT_SYMBOL(tape_med_state_set);
 EXPORT_SYMBOL(tape_alloc_request);
 EXPORT_SYMBOL(tape_free_request);
-EXPORT_SYMBOL(tape_dump_sense);
 EXPORT_SYMBOL(tape_dump_sense_dbf);
 EXPORT_SYMBOL(tape_do_io);
 EXPORT_SYMBOL(tape_do_io_async);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape.h linux-libre-2.6.30-gnu1/drivers/s390/char/tape.h
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape.h	2009-06-09 23:05:27.000000000 -0400
@@ -285,7 +285,7 @@ extern int tape_mtop(struct tape_device
 extern void tape_state_set(struct tape_device *, enum tape_state);
 
 extern int tape_generic_online(struct tape_device *, struct tape_discipline *);
-extern int tape_generic_offline(struct tape_device *device);
+extern int tape_generic_offline(struct ccw_device *);
 
 /* Externals from tape_devmap.c */
 extern int tape_generic_probe(struct ccw_device *);
@@ -324,8 +324,6 @@ static inline void tape_proc_cleanup (vo
 #endif
 
 /* a function for dumping device sense info */
-extern void tape_dump_sense(struct tape_device *, struct tape_request *,
-			    struct irb *);
 extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
 				struct irb *);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_proc.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_proc.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_proc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_proc.c	2009-06-09 23:05:27.000000000 -0400
@@ -20,8 +20,6 @@
 
 #include "tape.h"
 
-#define PRINTK_HEADER "TAPE_PROC: "
-
 static const char *tape_med_st_verbose[MS_SIZE] =
 {
 	[MS_UNKNOWN] = "UNKNOWN ",
@@ -128,7 +126,6 @@ tape_proc_init(void)
 		proc_create("tapedevices", S_IFREG | S_IRUGO | S_IWUSR, NULL,
 			    &tape_proc_ops);
 	if (tape_proc_devices == NULL) {
-		PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
 		return;
 	}
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/tape_std.c linux-libre-2.6.30-gnu1/drivers/s390/char/tape_std.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/tape_std.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/tape_std.c	2009-06-09 23:05:27.000000000 -0400
@@ -26,8 +26,6 @@
 #include "tape.h"
 #include "tape_std.h"
 
-#define PRINTK_HEADER "TAPE_STD: "
-
 /*
  * tape_std_assign
  */
@@ -39,16 +37,15 @@ tape_std_assign_timeout(unsigned long da
 	int rc;
 
 	request = (struct tape_request *) data;
-	if ((device = request->device) == NULL)
-		BUG();
+	device = request->device;
+	BUG_ON(!device);
 
 	DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
 			device->cdev_id);
 	rc = tape_cancel_io(device, request);
 	if(rc)
-		PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
+		DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
 			dev_name(&device->cdev->dev), rc);
-
 }
 
 int
@@ -82,8 +79,6 @@ tape_std_assign(struct tape_device *devi
 	del_timer(&timeout);
 
 	if (rc != 0) {
-		PRINT_WARN("%s: assign failed - device might be busy\n",
-			dev_name(&device->cdev->dev));
 		DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
 			device->cdev_id);
 	} else {
@@ -105,8 +100,6 @@ tape_std_unassign (struct tape_device *d
 	if (device->tape_state == TS_NOT_OPER) {
 		DBF_EVENT(3, "(%08x): Can't unassign device\n",
 			device->cdev_id);
-		PRINT_WARN("(%s): Can't unassign device - device gone\n",
-			dev_name(&device->cdev->dev));
 		return -EIO;
 	}
 
@@ -120,8 +113,6 @@ tape_std_unassign (struct tape_device *d
 
 	if ((rc = tape_do_io(device, request)) != 0) {
 		DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
-		PRINT_WARN("%s: Unassign failed\n",
-			   dev_name(&device->cdev->dev));
 	} else {
 		DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
 	}
@@ -242,8 +233,6 @@ tape_std_mtsetblk(struct tape_device *de
 	if (count > MAX_BLOCKSIZE) {
 		DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
 			count, MAX_BLOCKSIZE);
-		PRINT_ERR("Invalid block size (%d > %d) given.\n",
-			count, MAX_BLOCKSIZE);
 		return -EINVAL;
 	}
 
@@ -633,14 +622,6 @@ tape_std_mtcompression(struct tape_devic
 
 	if (mt_count < 0 || mt_count > 1) {
 		DBF_EXCEPTION(6, "xcom parm\n");
-		if (*device->modeset_byte & 0x08)
-			PRINT_INFO("(%s) Compression is currently on\n",
-				   dev_name(&device->cdev->dev));
-		else
-			PRINT_INFO("(%s) Compression is currently off\n",
-				   dev_name(&device->cdev->dev));
-		PRINT_INFO("Use 1 to switch compression on, 0 to "
-			   "switch it off\n");
 		return -EINVAL;
 	}
 	request = tape_alloc_request(2, 0);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/char/zcore.c linux-libre-2.6.30-gnu1/drivers/s390/char/zcore.c
--- linux-libre-2.6.29-gnu1/drivers/s390/char/zcore.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/char/zcore.c	2009-06-09 23:05:27.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * For more information please refer to Documentation/s390/zfcpdump.txt
  *
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2008
  * Author(s): Michael Holzheu
  */
 
@@ -24,6 +24,7 @@
 #include <asm/debug.h>
 #include <asm/processor.h>
 #include <asm/irqflags.h>
+#include <asm/checksum.h>
 #include "sclp.h"
 
 #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
@@ -48,12 +49,19 @@ struct sys_info {
 	union save_area	lc_mask;
 };
 
+struct ipib_info {
+	unsigned long	ipib;
+	u32		checksum;
+}  __attribute__((packed));
+
 static struct sys_info sys_info;
 static struct debug_info *zcore_dbf;
 static int hsa_available;
 static struct dentry *zcore_dir;
 static struct dentry *zcore_file;
 static struct dentry *zcore_memmap_file;
+static struct dentry *zcore_reipl_file;
+static struct ipl_parameter_block *ipl_block;
 
 /*
  * Copy memory from HSA to kernel or user memory (not reentrant):
@@ -527,6 +535,33 @@ static const struct file_operations zcor
 	.release	= zcore_memmap_release,
 };
 
+static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	if (ipl_block) {
+		diag308(DIAG308_SET, ipl_block);
+		diag308(DIAG308_IPL, NULL);
+	}
+	return count;
+}
+
+static int zcore_reipl_open(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static int zcore_reipl_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static const struct file_operations zcore_reipl_fops = {
+	.owner		= THIS_MODULE,
+	.write		= zcore_reipl_write,
+	.open		= zcore_reipl_open,
+	.release	= zcore_reipl_release,
+};
+
 
 static void __init set_s390_lc_mask(union save_area *map)
 {
@@ -645,6 +680,40 @@ static int __init zcore_header_init(int
 	return 0;
 }
 
+/*
+ * Provide IPL parameter information block from either HSA or memory
+ * for future reipl
+ */
+static int __init zcore_reipl_init(void)
+{
+	struct ipib_info ipib_info;
+	int rc;
+
+	rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
+	if (rc)
+		return rc;
+	if (ipib_info.ipib == 0)
+		return 0;
+	ipl_block = (void *) __get_free_page(GFP_KERNEL);
+	if (!ipl_block)
+		return -ENOMEM;
+	if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+		rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
+	else
+		rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
+	if (rc) {
+		free_page((unsigned long) ipl_block);
+		return rc;
+	}
+	if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+	    ipib_info.checksum) {
+		TRACE("Checksum does not match\n");
+		free_page((unsigned long) ipl_block);
+		ipl_block = NULL;
+	}
+	return 0;
+}
+
 static int __init zcore_init(void)
 {
 	unsigned char arch;
@@ -690,6 +759,10 @@ static int __init zcore_init(void)
 	if (rc)
 		goto fail;
 
+	rc = zcore_reipl_init();
+	if (rc)
+		goto fail;
+
 	zcore_dir = debugfs_create_dir("zcore" , NULL);
 	if (!zcore_dir) {
 		rc = -ENOMEM;
@@ -707,9 +780,17 @@ static int __init zcore_init(void)
 		rc = -ENOMEM;
 		goto fail_file;
 	}
+	zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
+						NULL, &zcore_reipl_fops);
+	if (!zcore_reipl_file) {
+		rc = -ENOMEM;
+		goto fail_memmap_file;
+	}
 	hsa_available = 1;
 	return 0;
 
+fail_memmap_file:
+	debugfs_remove(zcore_memmap_file);
 fail_file:
 	debugfs_remove(zcore_file);
 fail_dir:
@@ -723,10 +804,15 @@ static void __exit zcore_exit(void)
 {
 	debug_unregister(zcore_dbf);
 	sclp_sdias_exit();
+	free_page((unsigned long) ipl_block);
+	debugfs_remove(zcore_reipl_file);
+	debugfs_remove(zcore_memmap_file);
+	debugfs_remove(zcore_file);
+	debugfs_remove(zcore_dir);
 	diag308(DIAG308_REL_HSA, NULL);
 }
 
-MODULE_AUTHOR("Copyright IBM Corp. 2003,2007");
+MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
 MODULE_DESCRIPTION("zcore module for zfcpdump support");
 MODULE_LICENSE("GPL");
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/airq.c linux-libre-2.6.30-gnu1/drivers/s390/cio/airq.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/airq.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/airq.c	2009-06-09 23:05:27.000000000 -0400
@@ -34,8 +34,8 @@ struct airq_t {
 	void *drv_data;
 };
 
-static union indicator_t indicators[MAX_ISC];
-static struct airq_t *airqs[MAX_ISC][NR_AIRQS];
+static union indicator_t indicators[MAX_ISC+1];
+static struct airq_t *airqs[MAX_ISC+1][NR_AIRQS];
 
 static int register_airq(struct airq_t *airq, u8 isc)
 {
@@ -133,6 +133,8 @@ void do_adapter_IO(u8 isc)
 		while (word) {
 			if (word & INDICATOR_MASK) {
 				airq = airqs[isc][i];
+				/* Make sure gcc reads from airqs only once. */
+				barrier();
 				if (likely(airq))
 					airq->handler(&indicators[isc].byte[i],
 						      airq->drv_data);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/blacklist.c linux-libre-2.6.30-gnu1/drivers/s390/cio/blacklist.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/blacklist.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/blacklist.c	2009-06-09 23:05:27.000000000 -0400
@@ -336,8 +336,7 @@ cio_ignore_write(struct file *file, cons
 		 size_t user_len, loff_t *offset)
 {
 	char *buf;
-	size_t i;
-	ssize_t rc, ret;
+	ssize_t rc, ret, i;
 
 	if (*offset)
 		return -EINVAL;
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/ccwgroup.c linux-libre-2.6.30-gnu1/drivers/s390/cio/ccwgroup.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/ccwgroup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/ccwgroup.c	2009-06-09 23:05:27.000000000 -0400
@@ -104,8 +104,9 @@ ccwgroup_ungroup_store(struct device *de
 	rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
 out:
 	if (rc) {
-		/* Release onoff "lock" when ungrouping failed. */
-		atomic_set(&gdev->onoff, 0);
+		if (rc != -EAGAIN)
+			/* Release onoff "lock" when ungrouping failed. */
+			atomic_set(&gdev->onoff, 0);
 		return rc;
 	}
 	return count;
@@ -314,16 +315,32 @@ error:
 }
 EXPORT_SYMBOL(ccwgroup_create_from_string);
 
-static int __init
-init_ccwgroup (void)
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+			     void *data);
+
+static struct notifier_block ccwgroup_nb = {
+	.notifier_call = ccwgroup_notifier
+};
+
+static int __init init_ccwgroup(void)
 {
-	return bus_register (&ccwgroup_bus_type);
+	int ret;
+
+	ret = bus_register(&ccwgroup_bus_type);
+	if (ret)
+		return ret;
+
+	ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+	if (ret)
+		bus_unregister(&ccwgroup_bus_type);
+
+	return ret;
 }
 
-static void __exit
-cleanup_ccwgroup (void)
+static void __exit cleanup_ccwgroup(void)
 {
-	bus_unregister (&ccwgroup_bus_type);
+	bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+	bus_unregister(&ccwgroup_bus_type);
 }
 
 module_init(init_ccwgroup);
@@ -391,27 +408,28 @@ ccwgroup_online_store (struct device *de
 	unsigned long value;
 	int ret;
 
-	gdev = to_ccwgroupdev(dev);
 	if (!dev->driver)
-		return count;
+		return -ENODEV;
+
+	gdev = to_ccwgroupdev(dev);
+	gdrv = to_ccwgroupdrv(dev->driver);
 
-	gdrv = to_ccwgroupdrv (gdev->dev.driver);
 	if (!try_module_get(gdrv->owner))
 		return -EINVAL;
 
 	ret = strict_strtoul(buf, 0, &value);
 	if (ret)
 		goto out;
-	ret = count;
+
 	if (value == 1)
-		ccwgroup_set_online(gdev);
+		ret = ccwgroup_set_online(gdev);
 	else if (value == 0)
-		ccwgroup_set_offline(gdev);
+		ret = ccwgroup_set_offline(gdev);
 	else
 		ret = -EINVAL;
 out:
 	module_put(gdrv->owner);
-	return ret;
+	return (ret == 0) ? count : ret;
 }
 
 static ssize_t
@@ -453,13 +471,18 @@ ccwgroup_remove (struct device *dev)
 	struct ccwgroup_device *gdev;
 	struct ccwgroup_driver *gdrv;
 
+	device_remove_file(dev, &dev_attr_online);
+	device_remove_file(dev, &dev_attr_ungroup);
+
+	if (!dev->driver)
+		return 0;
+
 	gdev = to_ccwgroupdev(dev);
 	gdrv = to_ccwgroupdrv(dev->driver);
 
-	device_remove_file(dev, &dev_attr_online);
-
-	if (gdrv && gdrv->remove)
+	if (gdrv->remove)
 		gdrv->remove(gdev);
+
 	return 0;
 }
 
@@ -468,9 +491,13 @@ static void ccwgroup_shutdown(struct dev
 	struct ccwgroup_device *gdev;
 	struct ccwgroup_driver *gdrv;
 
+	if (!dev->driver)
+		return;
+
 	gdev = to_ccwgroupdev(dev);
 	gdrv = to_ccwgroupdrv(dev->driver);
-	if (gdrv && gdrv->shutdown)
+
+	if (gdrv->shutdown)
 		gdrv->shutdown(gdev);
 }
 
@@ -483,6 +510,19 @@ static struct bus_type ccwgroup_bus_type
 	.shutdown = ccwgroup_shutdown,
 };
 
+
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+			     void *data)
+{
+	struct device *dev = data;
+
+	if (action == BUS_NOTIFY_UNBIND_DRIVER)
+		device_schedule_callback(dev, ccwgroup_ungroup_callback);
+
+	return NOTIFY_OK;
+}
+
+
 /**
  * ccwgroup_driver_register() - register a ccw group driver
  * @cdriver: driver to be registered
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/chp.c linux-libre-2.6.30-gnu1/drivers/s390/cio/chp.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/chp.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/chp.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,8 +17,8 @@
 #include <linux/errno.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "cio.h"
 #include "css.h"
 #include "ioasm.h"
@@ -706,12 +706,12 @@ static int __init chp_init(void)
 	struct chp_id chpid;
 	int ret;
 
-	ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw);
+	ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
 	if (ret)
 		return ret;
 	chp_wq = create_singlethread_workqueue("cio_chp");
 	if (!chp_wq) {
-		s390_unregister_crw_handler(CRW_RSC_CPATH);
+		crw_unregister_handler(CRW_RSC_CPATH);
 		return -ENOMEM;
 	}
 	INIT_WORK(&cfg_work, cfg_func);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/chsc.c linux-libre-2.6.30-gnu1/drivers/s390/cio/chsc.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/chsc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/chsc.c	2009-06-09 23:05:27.000000000 -0400
@@ -19,8 +19,8 @@
 #include <asm/cio.h>
 #include <asm/chpid.h>
 #include <asm/chsc.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "css.h"
 #include "cio.h"
 #include "cio_debug.h"
@@ -589,6 +589,7 @@ __chsc_do_secm(struct channel_subsystem
 	case 0x0102:
 	case 0x0103:
 		ret = -EINVAL;
+		break;
 	default:
 		ret = chsc_error_from_response(secm_area->response.code);
 	}
@@ -820,7 +821,7 @@ int __init chsc_alloc_sei_area(void)
 			      "chsc machine checks!\n");
 		return -ENOMEM;
 	}
-	ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw);
+	ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
 	if (ret)
 		kfree(sei_page);
 	return ret;
@@ -828,7 +829,7 @@ int __init chsc_alloc_sei_area(void)
 
 void __init chsc_free_sei_area(void)
 {
-	s390_unregister_crw_handler(CRW_RSC_CSS);
+	crw_unregister_handler(CRW_RSC_CSS);
 	kfree(sei_page);
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/chsc_sch.c linux-libre-2.6.30-gnu1/drivers/s390/cio/chsc_sch.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/chsc_sch.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/chsc_sch.c	2009-06-09 23:05:27.000000000 -0400
@@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct
 		kfree(private);
 	} else {
 		sch->private = private;
-		if (sch->dev.uevent_suppress) {
-			sch->dev.uevent_suppress = 0;
+		if (dev_get_uevent_suppress(&sch->dev)) {
+			dev_set_uevent_suppress(&sch->dev, 0);
 			kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
 		}
 	}
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/cio.c linux-libre-2.6.30-gnu1/drivers/s390/cio/cio.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/cio.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/cio.c	2009-06-09 23:05:27.000000000 -0400
@@ -30,6 +30,8 @@
 #include <asm/isc.h>
 #include <asm/cpu.h>
 #include <asm/fcx.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
 #include "cio.h"
 #include "css.h"
 #include "chsc.h"
@@ -38,7 +40,6 @@
 #include "blacklist.h"
 #include "cio_debug.h"
 #include "chp.h"
-#include "../s390mach.h"
 
 debug_info_t *cio_debug_msg_id;
 debug_info_t *cio_debug_trace_id;
@@ -471,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel)
 int cio_disable_subchannel(struct subchannel *sch)
 {
 	char dbf_txt[15];
+	int retry;
 	int ret;
 
 	CIO_TRACE_EVENT (2, "dissch");
@@ -481,16 +483,17 @@ int cio_disable_subchannel(struct subcha
 	if (cio_update_schib(sch))
 		return -ENODEV;
 
-	if (scsw_actl(&sch->schib.scsw) != 0)
-		/*
-		 * the disable function must not be called while there are
-		 *  requests pending for completion !
-		 */
-		return -EBUSY;
-
 	sch->config.ena = 0;
-	ret = cio_commit_config(sch);
 
+	for (retry = 0; retry < 3; retry++) {
+		ret = cio_commit_config(sch);
+		if (ret == -EBUSY) {
+			struct irb irb;
+			if (tsch(sch->schid, &irb) != 0)
+				break;
+		} else
+			break;
+	}
 	sprintf (dbf_txt, "ret:%d", ret);
 	CIO_TRACE_EVENT (2, dbf_txt);
 	return ret;
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/crw.c linux-libre-2.6.30-gnu1/drivers/s390/cio/crw.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/crw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/crw.c	2009-06-09 23:05:27.000000000 -0400
@@ -0,0 +1,159 @@
+/*
+ *   Channel report handling code
+ *
+ *    Copyright IBM Corp. 2000,2009
+ *    Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Cornelia Huck <cornelia.huck@de.ibm.com>,
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <asm/crw.h>
+
+static struct semaphore crw_semaphore;
+static DEFINE_MUTEX(crw_handler_mutex);
+static crw_handler_t crw_handlers[NR_RSCS];
+
+/**
+ * crw_register_handler() - register a channel report word handler
+ * @rsc: reporting source code to handle
+ * @handler: handler to be registered
+ *
+ * Returns %0 on success and a negative error value otherwise.
+ */
+int crw_register_handler(int rsc, crw_handler_t handler)
+{
+	int rc = 0;
+
+	if ((rsc < 0) || (rsc >= NR_RSCS))
+		return -EINVAL;
+	mutex_lock(&crw_handler_mutex);
+	if (crw_handlers[rsc])
+		rc = -EBUSY;
+	else
+		crw_handlers[rsc] = handler;
+	mutex_unlock(&crw_handler_mutex);
+	return rc;
+}
+
+/**
+ * crw_unregister_handler() - unregister a channel report word handler
+ * @rsc: reporting source code to handle
+ */
+void crw_unregister_handler(int rsc)
+{
+	if ((rsc < 0) || (rsc >= NR_RSCS))
+		return;
+	mutex_lock(&crw_handler_mutex);
+	crw_handlers[rsc] = NULL;
+	mutex_unlock(&crw_handler_mutex);
+}
+
+/*
+ * Retrieve CRWs and call function to handle event.
+ */
+static int crw_collect_info(void *unused)
+{
+	struct crw crw[2];
+	int ccode;
+	unsigned int chain;
+	int ignore;
+
+repeat:
+	ignore = down_interruptible(&crw_semaphore);
+	chain = 0;
+	while (1) {
+		crw_handler_t handler;
+
+		if (unlikely(chain > 1)) {
+			struct crw tmp_crw;
+
+			printk(KERN_WARNING"%s: Code does not support more "
+			       "than two chained crws; please report to "
+			       "linux390@de.ibm.com!\n", __func__);
+			ccode = stcrw(&tmp_crw);
+			printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
+			       "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+			       __func__, tmp_crw.slct, tmp_crw.oflw,
+			       tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
+			       tmp_crw.erc, tmp_crw.rsid);
+			printk(KERN_WARNING"%s: This was crw number %x in the "
+			       "chain\n", __func__, chain);
+			if (ccode != 0)
+				break;
+			chain = tmp_crw.chn ? chain + 1 : 0;
+			continue;
+		}
+		ccode = stcrw(&crw[chain]);
+		if (ccode != 0)
+			break;
+		printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
+		       "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+		       crw[chain].slct, crw[chain].oflw, crw[chain].chn,
+		       crw[chain].rsc, crw[chain].anc, crw[chain].erc,
+		       crw[chain].rsid);
+		/* Check for overflows. */
+		if (crw[chain].oflw) {
+			int i;
+
+			pr_debug("%s: crw overflow detected!\n", __func__);
+			mutex_lock(&crw_handler_mutex);
+			for (i = 0; i < NR_RSCS; i++) {
+				if (crw_handlers[i])
+					crw_handlers[i](NULL, NULL, 1);
+			}
+			mutex_unlock(&crw_handler_mutex);
+			chain = 0;
+			continue;
+		}
+		if (crw[0].chn && !chain) {
+			chain++;
+			continue;
+		}
+		mutex_lock(&crw_handler_mutex);
+		handler = crw_handlers[crw[chain].rsc];
+		if (handler)
+			handler(&crw[0], chain ? &crw[1] : NULL, 0);
+		mutex_unlock(&crw_handler_mutex);
+		/* chain is always 0 or 1 here. */
+		chain = crw[chain].chn ? chain + 1 : 0;
+	}
+	goto repeat;
+	return 0;
+}
+
+void crw_handle_channel_report(void)
+{
+	up(&crw_semaphore);
+}
+
+/*
+ * Separate initcall needed for semaphore initialization since
+ * crw_handle_channel_report might be called before crw_machine_check_init.
+ */
+static int __init crw_init_semaphore(void)
+{
+	init_MUTEX_LOCKED(&crw_semaphore);
+	return 0;
+}
+pure_initcall(crw_init_semaphore);
+
+/*
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
+ */
+static int __init crw_machine_check_init(void)
+{
+	struct task_struct *task;
+
+	task = kthread_run(crw_collect_info, NULL, "kmcheck");
+	if (IS_ERR(task))
+		return PTR_ERR(task);
+	ctl_set_bit(14, 28);	/* enable channel report MCH */
+	return 0;
+}
+device_initcall(crw_machine_check_init);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/css.c linux-libre-2.6.30-gnu1/drivers/s390/cio/css.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/css.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/css.c	2009-06-09 23:05:27.000000000 -0400
@@ -18,8 +18,8 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <asm/isc.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "css.h"
 #include "cio.h"
 #include "cio_debug.h"
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct su
 	return rc;
 }
 
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+	struct cb_data *cb = data;
+	struct subchannel *sch;
+	int rc = 0;
+
+	sch = get_subchannel_by_schid(schid);
+	if (sch) {
+		if (cb->fn_known_sch)
+			rc = cb->fn_known_sch(sch, cb->data);
+		put_device(&sch->dev);
+	} else {
+		if (cb->fn_unknown_sch)
+			rc = cb->fn_unknown_sch(schid, cb->data);
+	}
+
+	return rc;
+}
+
 int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
 			       int (*fn_unknown)(struct subchannel_id,
 			       void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_
 	struct cb_data cb;
 	int rc;
 
-	cb.set = idset_sch_new();
-	if (!cb.set)
-		return -ENOMEM;
-	idset_fill(cb.set);
 	cb.data = data;
 	cb.fn_known_sch = fn_known;
 	cb.fn_unknown_sch = fn_unknown;
+
+	cb.set = idset_sch_new();
+	if (!cb.set)
+		/* fall back to brute force scanning in case of oom */
+		return for_each_subchannel(call_fn_all_sch, &cb);
+
+	idset_fill(cb.set);
+
 	/* Process registered subchannels. */
 	rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
 	if (rc)
@@ -272,7 +295,7 @@ static int css_register_subchannel(struc
 	 * the subchannel driver can decide itself when it wants to inform
 	 * userspace of its existence.
 	 */
-	sch->dev.uevent_suppress = 1;
+	dev_set_uevent_suppress(&sch->dev, 1);
 	css_update_ssd_info(sch);
 	/* make it known to the system */
 	ret = css_sch_device_register(sch);
@@ -287,7 +310,7 @@ static int css_register_subchannel(struc
 		 * a fitting driver module may be loaded based on the
 		 * modalias.
 		 */
-		sch->dev.uevent_suppress = 0;
+		dev_set_uevent_suppress(&sch->dev, 0);
 		kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
 	}
 	return ret;
@@ -510,6 +533,17 @@ static int reprobe_subchannel(struct sub
 	return ret;
 }
 
+static void reprobe_after_idle(struct work_struct *unused)
+{
+	/* Make sure initial subchannel scan is done. */
+	wait_event(ccw_device_init_wq,
+		   atomic_read(&ccw_device_init_count) == 0);
+	if (need_reprobe)
+		css_schedule_reprobe();
+}
+
+static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
+
 /* Work function used to reprobe all unregistered subchannels. */
 static void reprobe_all(struct work_struct *unused)
 {
@@ -517,10 +551,12 @@ static void reprobe_all(struct work_stru
 
 	CIO_MSG_EVENT(4, "reprobe start\n");
 
-	need_reprobe = 0;
 	/* Make sure initial subchannel scan is done. */
-	wait_event(ccw_device_init_wq,
-		   atomic_read(&ccw_device_init_count) == 0);
+	if (atomic_read(&ccw_device_init_count) != 0) {
+		queue_work(ccw_device_work, &reprobe_idle_work);
+		return;
+	}
+	need_reprobe = 0;
 	ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
 
 	CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
@@ -619,7 +655,7 @@ css_generate_pgid(struct channel_subsyst
 		css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
 	} else {
 #ifdef CONFIG_SMP
-		css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
+		css->global_pgid.pgid_high.cpu_addr = stap();
 #else
 		css->global_pgid.pgid_high.cpu_addr = 0;
 #endif
@@ -765,7 +801,7 @@ init_channel_subsystem (void)
 	if (ret)
 		goto out;
 
-	ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+	ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
 	if (ret)
 		goto out;
 
@@ -845,7 +881,7 @@ out_unregister:
 out_bus:
 	bus_unregister(&css_bus_type);
 out:
-	s390_unregister_crw_handler(CRW_RSC_CSS);
+	crw_unregister_handler(CRW_RSC_CSS);
 	chsc_free_sei_area();
 	kfree(slow_subchannel_set);
 	pr_alert("The CSS device driver initialization failed with "
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/device.c linux-libre-2.6.30-gnu1/drivers/s390/cio/device.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/device.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/device.c	2009-06-09 23:05:27.000000000 -0400
@@ -310,8 +310,6 @@ static void ccw_device_remove_orphan_cb(
 	put_device(&cdev->dev);
 }
 
-static void ccw_device_call_sch_unregister(struct work_struct *work);
-
 static void
 ccw_device_remove_disconnected(struct ccw_device *cdev)
 {
@@ -335,11 +333,10 @@ ccw_device_remove_disconnected(struct cc
 		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. */
-		PREPARE_WORK(&cdev->private->kick_work,
-				ccw_device_call_sch_unregister);
-	queue_work(slow_path_wq, &cdev->private->kick_work);
+		ccw_device_schedule_sch_unregister(cdev);
 }
 
 /**
@@ -457,12 +454,13 @@ int ccw_device_set_online(struct ccw_dev
 	return (ret == 0) ? -ENODEV : ret;
 }
 
-static void online_store_handle_offline(struct ccw_device *cdev)
+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->drv && cdev->drv->set_offline)
-		ccw_device_set_offline(cdev);
+	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)
@@ -470,7 +468,7 @@ static int online_store_recog_and_online
 	int ret;
 
 	/* Do device recognition, if needed. */
-	if (cdev->id.cu_type == 0) {
+	if (cdev->private->state == DEV_STATE_BOXED) {
 		ret = ccw_device_recognition(cdev);
 		if (ret) {
 			CIO_MSG_EVENT(0, "Couldn't start recognition "
@@ -481,17 +479,21 @@ static int online_store_recog_and_online
 		}
 		wait_event(cdev->private->wait_q,
 			   cdev->private->flags.recog_done);
+		if (cdev->private->state != DEV_STATE_OFFLINE)
+			/* recognition failed */
+			return -EAGAIN;
 	}
 	if (cdev->drv && cdev->drv->set_online)
 		ccw_device_set_online(cdev);
 	return 0;
 }
+
 static int online_store_handle_online(struct ccw_device *cdev, int force)
 {
 	int ret;
 
 	ret = online_store_recog_and_online(cdev);
-	if (ret)
+	if (ret && !force)
 		return ret;
 	if (force && cdev->private->state == DEV_STATE_BOXED) {
 		ret = ccw_device_stlck(cdev);
@@ -499,7 +501,9 @@ static int online_store_handle_online(st
 			return ret;
 		if (cdev->id.cu_type == 0)
 			cdev->private->state = DEV_STATE_NOT_OPER;
-		online_store_recog_and_online(cdev);
+		ret = online_store_recog_and_online(cdev);
+		if (ret)
+			return ret;
 	}
 	return 0;
 }
@@ -511,7 +515,11 @@ static ssize_t online_store (struct devi
 	int force, ret;
 	unsigned long i;
 
-	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+	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)
 		return -EAGAIN;
 
 	if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -530,13 +538,10 @@ static ssize_t online_store (struct devi
 		goto out;
 	switch (i) {
 	case 0:
-		online_store_handle_offline(cdev);
-		ret = count;
+		ret = online_store_handle_offline(cdev);
 		break;
 	case 1:
 		ret = online_store_handle_online(cdev, force);
-		if (!ret)
-			ret = count;
 		break;
 	default:
 		ret = -EINVAL;
@@ -545,7 +550,7 @@ out:
 	if (cdev->drv)
 		module_put(cdev->drv->owner);
 	atomic_set(&cdev->private->onoff, 0);
-	return ret;
+	return (ret < 0) ? ret : count;
 }
 
 static ssize_t
@@ -681,35 +686,22 @@ get_orphaned_ccwdev_by_dev_id(struct cha
 	return dev ? to_ccwdev(dev) : NULL;
 }
 
-static void
-ccw_device_add_changed(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;
-	if (device_add(&cdev->dev)) {
-		put_device(&cdev->dev);
-		return;
-	}
-	set_bit(1, &cdev->private->registered);
-}
-
-void ccw_device_do_unreg_rereg(struct work_struct *work)
+void ccw_device_do_unbind_bind(struct work_struct *work)
 {
 	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);
 
-	ccw_device_unregister(cdev);
-	PREPARE_WORK(&cdev->private->kick_work,
-		     ccw_device_add_changed);
-	queue_work(ccw_device_work, &cdev->private->kick_work);
+	if (test_bit(1, &cdev->private->registered)) {
+		device_release_driver(&cdev->dev);
+		ret = device_attach(&cdev->dev);
+		WARN_ON(ret == -ENODEV);
+	}
 }
 
 static void
@@ -799,7 +791,7 @@ static void sch_attach_disconnected_devi
 		return;
 	other_sch = to_subchannel(cdev->dev.parent);
 	/* Note: device_move() changes cdev->dev.parent */
-	ret = device_move(&cdev->dev, &sch->dev);
+	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,
@@ -830,7 +822,7 @@ static void sch_attach_orphaned_device(s
 	 * Try to move the ccw device to its new subchannel.
 	 * Note: device_move() changes cdev->dev.parent
 	 */
-	ret = device_move(&cdev->dev, &sch->dev);
+	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",
@@ -897,7 +889,8 @@ void ccw_device_move_to_orphanage(struct
 	 * 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);
+	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,
@@ -981,7 +974,7 @@ io_subchannel_register(struct work_struc
 	 * Now we know this subchannel will stay, we can throw
 	 * our delayed uevent.
 	 */
-	sch->dev.uevent_suppress = 0;
+	dev_set_uevent_suppress(&sch->dev, 0);
 	kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
 	/* make it known to the system */
 	ret = ccw_device_register(cdev);
@@ -1028,33 +1021,35 @@ static void ccw_device_call_sch_unregist
 	put_device(&sch->dev);
 }
 
+void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
+{
+	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.
  */
 void
 io_subchannel_recog_done(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
-
 	if (css_init_done == 0) {
 		cdev->private->flags.recog_done = 1;
 		return;
 	}
 	switch (cdev->private->state) {
+	case DEV_STATE_BOXED:
+		/* Device did not respond in time. */
 	case DEV_STATE_NOT_OPER:
 		cdev->private->flags.recog_done = 1;
 		/* Remove device found not operational. */
 		if (!get_device(&cdev->dev))
 			break;
-		sch = to_subchannel(cdev->dev.parent);
-		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_call_sch_unregister);
-		queue_work(slow_path_wq, &cdev->private->kick_work);
+		ccw_device_schedule_sch_unregister(cdev);
 		if (atomic_dec_and_test(&ccw_device_init_count))
 			wake_up(&ccw_device_init_wq);
 		break;
-	case DEV_STATE_BOXED:
-		/* Device did not respond in time. */
 	case DEV_STATE_OFFLINE:
 		/* 
 		 * We can't register the device in interrupt context so
@@ -1129,7 +1124,7 @@ static void ccw_device_move_to_sch(struc
 	 * Try to move the ccw device to its new subchannel.
 	 * Note: device_move() changes cdev->dev.parent
 	 */
-	rc = device_move(&cdev->dev, &sch->dev);
+	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 "
@@ -1243,7 +1238,7 @@ static int io_subchannel_probe(struct su
 		 * the ccw_device and exit. This happens for all early
 		 * devices, e.g. the console.
 		 */
-		sch->dev.uevent_suppress = 0;
+		dev_set_uevent_suppress(&sch->dev, 0);
 		kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
 		cdev->dev.groups = ccwdev_attr_groups;
 		device_initialize(&cdev->dev);
@@ -1568,8 +1563,7 @@ static int purge_fn(struct device *dev,
 		goto out;
 	CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
 		      priv->dev_id.devno);
-	PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister);
-	queue_work(slow_path_wq, &cdev->private->kick_work);
+	ccw_device_schedule_sch_unregister(cdev);
 
 out:
 	/* Abort loop in case of pending signal. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/device_fsm.c linux-libre-2.6.30-gnu1/drivers/s390/cio/device_fsm.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/device_fsm.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/device_fsm.c	2009-06-09 23:05:27.000000000 -0400
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device
 	    cdev->id.dev_type != cdev->private->senseid.dev_type ||
 	    cdev->id.dev_model != cdev->private->senseid.dev_model) {
 		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_do_unreg_rereg);
+			     ccw_device_do_unbind_bind);
 		queue_work(ccw_device_work, &cdev->private->kick_work);
 		return 0;
 	}
@@ -256,13 +256,12 @@ ccw_device_recog_done(struct ccw_device
 		old_lpm = 0;
 	if (sch->lpm != old_lpm)
 		__recover_lost_chpids(sch, old_lpm);
-	if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
-		if (state == DEV_STATE_NOT_OPER) {
-			cdev->private->flags.recog_done = 1;
-			cdev->private->state = DEV_STATE_DISCONNECTED;
-			return;
-		}
-		/* Boxed devices don't need extra treatment. */
+	if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
+	    (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
+		cdev->private->flags.recog_done = 1;
+		cdev->private->state = DEV_STATE_DISCONNECTED;
+		wake_up(&cdev->private->wait_q);
+		return;
 	}
 	notify = 0;
 	same_dev = 0; /* Keep the compiler quiet... */
@@ -274,7 +273,7 @@ ccw_device_recog_done(struct ccw_device
 			      sch->schid.ssid, sch->schid.sch_no);
 		break;
 	case DEV_STATE_OFFLINE:
-		if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
+		if (cdev->online) {
 			same_dev = ccw_device_handle_oper(cdev);
 			notify = 1;
 		}
@@ -307,12 +306,17 @@ ccw_device_recog_done(struct ccw_device
 			      " 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;
+			wake_up(&cdev->private->wait_q);
+			return;
+		}
 		break;
 	}
 	cdev->private->state = state;
 	io_subchannel_recog_done(cdev);
-	if (state != DEV_STATE_NOT_OPER)
-		wake_up(&cdev->private->wait_q);
+	wake_up(&cdev->private->wait_q);
 }
 
 /*
@@ -366,7 +370,7 @@ static void ccw_device_oper_notify(struc
 	}
 	/* Driver doesn't want device back. */
 	ccw_device_set_notoper(cdev);
-	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
 	queue_work(ccw_device_work, &cdev->private->kick_work);
 }
 
@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev,
 
 	cdev->private->state = state;
 
-
-	if (state == DEV_STATE_BOXED)
+	if (state == DEV_STATE_BOXED) {
 		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);
+		cdev->private->flags.donotify = 0;
+	}
 
 	if (cdev->private->flags.donotify) {
 		cdev->private->flags.donotify = 0;
@@ -728,7 +735,7 @@ static void ccw_device_generic_notoper(s
 {
 	struct subchannel *sch;
 
-	cdev->private->state = DEV_STATE_NOT_OPER;
+	ccw_device_set_notoper(cdev);
 	sch = to_subchannel(cdev->dev.parent);
 	css_schedule_eval(sch->schid);
 }
@@ -1052,7 +1059,7 @@ ccw_device_offline_irq(struct ccw_device
 	sch = to_subchannel(cdev->dev.parent);
 	/*
 	 * An interrupt in state offline means a previous disable was not
-	 * successful. Try again.
+	 * successful - should not happen, but we try to disable again.
 	 */
 	cio_disable_subchannel(sch);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/device.h linux-libre-2.6.30-gnu1/drivers/s390/cio/device.h
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/device.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/device.h	2009-06-09 23:05:27.000000000 -0400
@@ -80,13 +80,14 @@ void io_subchannel_init_config(struct su
 
 int ccw_device_cancel_halt_clear(struct ccw_device *);
 
-void ccw_device_do_unreg_rereg(struct work_struct *);
+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 *);
 int ccw_device_online(struct ccw_device *);
 int ccw_device_offline(struct ccw_device *);
+void ccw_device_schedule_sch_unregister(struct ccw_device *);
 int ccw_purge_blacklisted(void);
 
 /* Function prototypes for device status and basic sense stuff. */
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/device_ops.c linux-libre-2.6.30-gnu1/drivers/s390/cio/device_ops.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/device_ops.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/device_ops.c	2009-06-09 23:05:27.000000000 -0400
@@ -680,7 +680,7 @@ int ccw_device_tm_intrg(struct ccw_devic
 	if (cdev->private->state != DEV_STATE_ONLINE)
 		return -EIO;
 	if (!scsw_is_tm(&sch->schib.scsw) ||
-	    !(scsw_actl(&sch->schib.scsw) | SCSW_ACTL_START_PEND))
+	    !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
 		return -EINVAL;
 	return cio_tm_intrg(sch);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/Makefile linux-libre-2.6.30-gnu1/drivers/s390/cio/Makefile
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \
-	fcx.o itcw.o
+	fcx.o itcw.o crw.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
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_debug.c linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_debug.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_debug.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_debug.c	2009-06-09 23:05:27.000000000 -0400
@@ -63,8 +63,9 @@ static int qstat_show(struct seq_file *m
 	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_ftc: %d\n", q->last_move_ftc);
+	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, "slsb buffer states:\n");
 	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio.h linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio.h
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio.h	2009-06-09 23:05:27.000000000 -0400
@@ -186,6 +186,9 @@ struct qdio_input_q {
 	/* input buffer acknowledgement flag */
 	int polling;
 
+	/* first ACK'ed buffer */
+	int ack_start;
+
 	/* how much sbals are acknowledged with qebsm */
 	int ack_count;
 
@@ -234,7 +237,7 @@ struct qdio_q {
 	int first_to_check;
 
 	/* first_to_check of the last time */
-	int last_move_ftc;
+	int last_move;
 
 	/* beginning position for calling the program */
 	int first_to_kick;
@@ -244,7 +247,6 @@ struct qdio_q {
 
 	struct qdio_irq *irq_ptr;
 	struct tasklet_struct tasklet;
-	spinlock_t lock;
 
 	/* error condition during a data transfer */
 	unsigned int qdio_error;
@@ -354,7 +356,7 @@ int get_buf_state(struct qdio_q *q, unsi
 		  int auto_ack);
 void qdio_check_outbound_after_thinint(struct qdio_q *q);
 int qdio_inbound_q_moved(struct qdio_q *q);
-void qdio_kick_inbound_handler(struct qdio_q *q);
+void qdio_kick_handler(struct qdio_q *q);
 void qdio_stop_polling(struct qdio_q *q);
 int qdio_siga_sync_q(struct qdio_q *q);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_main.c linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_main.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdi
 
 	/* show the card that we are not polling anymore */
 	if (is_qebsm(q)) {
-		set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+		set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
 			       q->u.in.ack_count);
 		q->u.in.ack_count = 0;
 	} else
-		set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
+		set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
 }
 
 static void announce_buffer_error(struct qdio_q *q, int count)
@@ -419,15 +419,15 @@ static inline void inbound_primed(struct
 		if (!q->u.in.polling) {
 			q->u.in.polling = 1;
 			q->u.in.ack_count = count;
-			q->last_move_ftc = q->first_to_check;
+			q->u.in.ack_start = q->first_to_check;
 			return;
 		}
 
 		/* delete the previous ACK's */
-		set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+		set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
 			       q->u.in.ack_count);
 		q->u.in.ack_count = count;
-		q->last_move_ftc = q->first_to_check;
+		q->u.in.ack_start = q->first_to_check;
 		return;
 	}
 
@@ -439,14 +439,13 @@ static inline void inbound_primed(struct
 	if (q->u.in.polling) {
 		/* reset the previous ACK but first set the new one */
 		set_buf_state(q, new, SLSB_P_INPUT_ACK);
-		set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
-	}
-	else {
+		set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
+	} else {
 		q->u.in.polling = 1;
-		set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
+		set_buf_state(q, new, SLSB_P_INPUT_ACK);
 	}
 
-	q->last_move_ftc = new;
+	q->u.in.ack_start = new;
 	count--;
 	if (!count)
 		return;
@@ -455,7 +454,7 @@ static inline void inbound_primed(struct
 	 * Need to change all PRIMED buffers to NOT_INIT, otherwise
 	 * we're loosing initiative in the thinint code.
 	 */
-	set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
+	set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
 		       count);
 }
 
@@ -523,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *
 
 	bufnr = get_inbound_buffer_frontier(q);
 
-	if ((bufnr != q->last_move_ftc) || q->qdio_error) {
+	if ((bufnr != q->last_move) || q->qdio_error) {
+		q->last_move = bufnr;
 		if (!need_siga_sync(q) && !pci_out_supported(q))
 			q->u.in.timestamp = get_usecs();
 
@@ -570,29 +570,30 @@ static int qdio_inbound_q_done(struct qd
 	}
 }
 
-void qdio_kick_inbound_handler(struct qdio_q *q)
+void qdio_kick_handler(struct qdio_q *q)
 {
-	int count, start, end;
-
-	qdio_perf_stat_inc(&perf_stats.inbound_handler);
-
-	start = q->first_to_kick;
-	end = q->first_to_check;
-	if (end >= start)
-		count = end - start;
-	else
-		count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
-	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+	int start = q->first_to_kick;
+	int end = q->first_to_check;
+	int count;
 
 	if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
 		return;
 
-	q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr,
-		   start, count, q->irq_ptr->int_parm);
+	count = sub_buf(end, start);
+
+	if (q->is_input_q) {
+		qdio_perf_stat_inc(&perf_stats.inbound_handler);
+		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+	} else {
+		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: nr:%1d", q->nr);
+		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
+	}
+
+	q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
+		   q->irq_ptr->int_parm);
 
 	/* for the next time */
-	q->first_to_kick = q->first_to_check;
+	q->first_to_kick = end;
 	q->qdio_error = 0;
 }
 
@@ -603,7 +604,7 @@ again:
 	if (!qdio_inbound_q_moved(q))
 		return;
 
-	qdio_kick_inbound_handler(q);
+	qdio_kick_handler(q);
 
 	if (!qdio_inbound_q_done(q))
 		/* means poll time is not yet over */
@@ -698,21 +699,21 @@ static inline int qdio_outbound_q_moved(
 
 	bufnr = get_outbound_buffer_frontier(q);
 
-	if ((bufnr != q->last_move_ftc) || q->qdio_error) {
-		q->last_move_ftc = bufnr;
+	if ((bufnr != q->last_move) || q->qdio_error) {
+		q->last_move = bufnr;
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
 		return 1;
 	} else
 		return 0;
 }
 
-static void qdio_kick_outbound_q(struct qdio_q *q)
+static int qdio_kick_outbound_q(struct qdio_q *q)
 {
 	unsigned int busy_bit;
 	int cc;
 
 	if (!need_siga_out(q))
-		return;
+		return 0;
 
 	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
 	qdio_perf_stat_inc(&perf_stats.siga_out);
@@ -724,75 +725,37 @@ static void qdio_kick_outbound_q(struct
 	case 2:
 		if (busy_bit) {
 			DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr);
-			q->qdio_error = cc | QDIO_ERROR_SIGA_BUSY;
-		} else {
-			DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d",
-				      q->nr);
-			q->qdio_error = cc;
-		}
+			cc |= QDIO_ERROR_SIGA_BUSY;
+		} else
+			DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
 		break;
 	case 1:
 	case 3:
 		DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
-		q->qdio_error = cc;
 		break;
 	}
-}
-
-static void qdio_kick_outbound_handler(struct qdio_q *q)
-{
-	int start, end, count;
-
-	start = q->first_to_kick;
-	end = q->last_move_ftc;
-	if (end >= start)
-		count = end - start;
-	else
-		count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
-	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kickouth: %1d", q->nr);
-	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
-
-	if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
-		return;
-
-	q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
-		   q->irq_ptr->int_parm);
-
-	/* for the next time: */
-	q->first_to_kick = q->last_move_ftc;
-	q->qdio_error = 0;
+	return cc;
 }
 
 static void __qdio_outbound_processing(struct qdio_q *q)
 {
-	unsigned long flags;
-
 	qdio_perf_stat_inc(&perf_stats.tasklet_outbound);
-	spin_lock_irqsave(&q->lock, flags);
-
 	BUG_ON(atomic_read(&q->nr_buf_used) < 0);
 
 	if (qdio_outbound_q_moved(q))
-		qdio_kick_outbound_handler(q);
-
-	spin_unlock_irqrestore(&q->lock, flags);
+		qdio_kick_handler(q);
 
-	if (queue_type(q) == QDIO_ZFCP_QFMT) {
+	if (queue_type(q) == QDIO_ZFCP_QFMT)
 		if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
-			tasklet_schedule(&q->tasklet);
-		return;
-	}
+			goto sched;
 
 	/* bail out for HiperSockets unicast queues */
 	if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
 		return;
 
 	if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
-	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
-		tasklet_schedule(&q->tasklet);
-		return;
-	}
+	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+		goto sched;
 
 	if (q->u.out.pci_out_enabled)
 		return;
@@ -810,6 +773,12 @@ static void __qdio_outbound_processing(s
 			qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
 		}
 	}
+	return;
+
+sched:
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
+	tasklet_schedule(&q->tasklet);
 }
 
 /* outbound tasklet */
@@ -822,6 +791,9 @@ void qdio_outbound_processing(unsigned l
 void qdio_outbound_timer(unsigned long data)
 {
 	struct qdio_q *q = (struct qdio_q *)data;
+
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
 	tasklet_schedule(&q->tasklet);
 }
 
@@ -863,6 +835,9 @@ static void qdio_int_handler_pci(struct
 	int i;
 	struct qdio_q *q;
 
+	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)
@@ -906,42 +881,6 @@ no_handler:
 	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 }
 
-static void qdio_call_shutdown(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;
-	qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
-	put_device(&cdev->dev);
-}
-
-static void qdio_int_error(struct ccw_device *cdev)
-{
-	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
-
-	switch (irq_ptr->state) {
-	case QDIO_IRQ_STATE_INACTIVE:
-	case QDIO_IRQ_STATE_CLEANUP:
-		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
-		break;
-	case QDIO_IRQ_STATE_ESTABLISHED:
-	case QDIO_IRQ_STATE_ACTIVE:
-		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
-		if (get_device(&cdev->dev)) {
-			/* Can't call shutdown from interrupt context. */
-			PREPARE_WORK(&cdev->private->kick_work,
-				     qdio_call_shutdown);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
-		}
-		break;
-	default:
-		WARN_ON(1);
-	}
-	wake_up(&cdev->private->wait_q);
-}
-
 static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat,
 				       int dstat)
 {
@@ -998,10 +937,8 @@ void qdio_int_handler(struct ccw_device
 		switch (PTR_ERR(irb)) {
 		case -EIO:
 			DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no);
-			return;
-		case -ETIMEDOUT:
-			DBF_ERROR("%4x IO timeout", irq_ptr->schid.sch_no);
-			qdio_int_error(cdev);
+			qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
+			wake_up(&cdev->private->wait_q);
 			return;
 		default:
 			WARN_ON(1);
@@ -1026,7 +963,6 @@ void qdio_int_handler(struct ccw_device
 	case QDIO_IRQ_STATE_ACTIVE:
 		if (cstat & SCHN_STAT_PCI) {
 			qdio_int_handler_pci(irq_ptr);
-			/* no state change so no need to wake up wait_q */
 			return;
 		}
 		if ((cstat & ~SCHN_STAT_PCI) || dstat) {
@@ -1065,8 +1001,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
  * @cdev: associated ccw device
  * @how: use halt or clear to shutdown
  *
- * This function calls qdio_shutdown() for @cdev with method @how
- * and on success qdio_free() for @cdev.
+ * This function calls qdio_shutdown() for @cdev with method @how.
+ * and qdio_free(). The qdio_free() return value is ignored since
+ * !irq_ptr is already checked.
  */
 int qdio_cleanup(struct ccw_device *cdev, int how)
 {
@@ -1077,8 +1014,8 @@ int qdio_cleanup(struct ccw_device *cdev
 		return -ENODEV;
 
 	rc = qdio_shutdown(cdev, how);
-	if (rc == 0)
-		rc = qdio_free(cdev);
+
+	qdio_free(cdev);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(qdio_cleanup);
@@ -1090,11 +1027,11 @@ static void qdio_shutdown_queues(struct
 	int i;
 
 	for_each_input_queue(irq_ptr, q, i)
-		tasklet_disable(&q->tasklet);
+		tasklet_kill(&q->tasklet);
 
 	for_each_output_queue(irq_ptr, q, i) {
-		tasklet_disable(&q->tasklet);
 		del_timer(&q->u.out.timer);
+		tasklet_kill(&q->tasklet);
 	}
 }
 
@@ -1112,6 +1049,7 @@ int qdio_shutdown(struct ccw_device *cde
 	if (!irq_ptr)
 		return -ENODEV;
 
+	BUG_ON(irqs_disabled());
 	DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
 
 	mutex_lock(&irq_ptr->setup_mutex);
@@ -1124,6 +1062,12 @@ int qdio_shutdown(struct ccw_device *cde
 		return 0;
 	}
 
+	/*
+	 * Indicate that the device is going down. Scheduling the queue
+	 * tasklets is forbidden from here on.
+	 */
+	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
 	tiqdio_remove_input_queues(irq_ptr);
 	qdio_shutdown_queues(cdev);
 	qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1403,9 +1347,8 @@ int qdio_activate(struct ccw_device *cde
 	switch (irq_ptr->state) {
 	case QDIO_IRQ_STATE_STOPPED:
 	case QDIO_IRQ_STATE_ERR:
-		mutex_unlock(&irq_ptr->setup_mutex);
-		qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
-		return -EIO;
+		rc = -EIO;
+		break;
 	default:
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
 		rc = 0;
@@ -1442,10 +1385,10 @@ static inline int buf_in_between(int buf
  * @bufnr: first buffer to process
  * @count: how many buffers are emptied
  */
-static void handle_inbound(struct qdio_q *q, unsigned int callflags,
-			   int bufnr, int count)
+static int handle_inbound(struct qdio_q *q, unsigned int callflags,
+			  int bufnr, int count)
 {
-	int used, cc, diff;
+	int used, diff;
 
 	if (!q->u.in.polling)
 		goto set;
@@ -1456,19 +1399,18 @@ static void handle_inbound(struct qdio_q
 		q->u.in.polling = 0;
 		q->u.in.ack_count = 0;
 		goto set;
-	} else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
+	} else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
 		if (is_qebsm(q)) {
-			/* partial overwrite, just update last_move_ftc */
+			/* partial overwrite, just update ack_start */
 			diff = add_buf(bufnr, count);
-			diff = sub_buf(diff, q->last_move_ftc);
+			diff = sub_buf(diff, q->u.in.ack_start);
 			q->u.in.ack_count -= diff;
 			if (q->u.in.ack_count <= 0) {
 				q->u.in.polling = 0;
 				q->u.in.ack_count = 0;
-				/* TODO: must we set last_move_ftc to something meaningful? */
 				goto set;
 			}
-			q->last_move_ftc = add_buf(q->last_move_ftc, diff);
+			q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
 		}
 		else
 			/* the only ACK will be deleted, so stop polling */
@@ -1483,13 +1425,11 @@ set:
 
 	/* no need to signal as long as the adapter had free buffers */
 	if (used)
-		return;
+		return 0;
 
-	if (need_siga_in(q)) {
-		cc = qdio_siga_input(q);
-		if (cc)
-			q->qdio_error = cc;
-	}
+	if (need_siga_in(q))
+		return qdio_siga_input(q);
+	return 0;
 }
 
 /**
@@ -1499,11 +1439,11 @@ set:
  * @bufnr: first buffer to process
  * @count: how many buffers are filled
  */
-static void handle_outbound(struct qdio_q *q, unsigned int callflags,
-			    int bufnr, int count)
+static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+			   int bufnr, int count)
 {
 	unsigned char state;
-	int used;
+	int used, rc = 0;
 
 	qdio_perf_stat_inc(&perf_stats.outbound_handler);
 
@@ -1518,27 +1458,26 @@ static void handle_outbound(struct qdio_
 
 	if (queue_type(q) == QDIO_IQDIO_QFMT) {
 		if (multicast_outbound(q))
-			qdio_kick_outbound_q(q);
+			rc = qdio_kick_outbound_q(q);
 		else
 			if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
 			    (count > 1) &&
 			    (count <= q->irq_ptr->ssqd_desc.mmwc)) {
 				/* exploit enhanced SIGA */
 				q->u.out.use_enh_siga = 1;
-				qdio_kick_outbound_q(q);
+				rc = qdio_kick_outbound_q(q);
 			} else {
 				/*
 				* One siga-w per buffer required for unicast
 				* HiperSockets.
 				*/
 				q->u.out.use_enh_siga = 0;
-				while (count--)
-					qdio_kick_outbound_q(q);
+				while (count--) {
+					rc = qdio_kick_outbound_q(q);
+					if (rc)
+						goto out;
+				}
 			}
-
-		/* report CC=2 conditions synchronously */
-		if (q->qdio_error)
-			__qdio_outbound_processing(q);
 		goto out;
 	}
 
@@ -1550,14 +1489,14 @@ static void handle_outbound(struct qdio_
 	/* try to fast requeue buffers */
 	get_buf_state(q, prev_buf(bufnr), &state, 0);
 	if (state != SLSB_CU_OUTPUT_PRIMED)
-		qdio_kick_outbound_q(q);
+		rc = qdio_kick_outbound_q(q);
 	else {
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req");
 		qdio_perf_stat_inc(&perf_stats.fast_requeue);
 	}
 out:
-	/* Fixme: could wait forever if called from process context */
 	tasklet_schedule(&q->tasklet);
+	return rc;
 }
 
 /**
@@ -1596,14 +1535,12 @@ int do_QDIO(struct ccw_device *cdev, uns
 		return -EBUSY;
 
 	if (callflags & QDIO_FLAG_SYNC_INPUT)
-		handle_inbound(irq_ptr->input_qs[q_nr], callflags, bufnr,
-			       count);
+		return handle_inbound(irq_ptr->input_qs[q_nr],
+				      callflags, bufnr, count);
 	else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
-		handle_outbound(irq_ptr->output_qs[q_nr], callflags, bufnr,
-				count);
-	else
-		return -EINVAL;
-	return 0;
+		return handle_outbound(irq_ptr->output_qs[q_nr],
+				       callflags, bufnr, count);
+	return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(do_QDIO);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_setup.c linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_setup.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_setup.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_setup.c	2009-06-09 23:05:27.000000000 -0400
@@ -117,7 +117,6 @@ static void setup_queues_misc(struct qdi
 	q->mask = 1 << (31 - i);
 	q->nr = i;
 	q->handler = handler;
-	spin_lock_init(&q->lock);
 }
 
 static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_thinint.c linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_thinint.c
--- linux-libre-2.6.29-gnu1/drivers/s390/cio/qdio_thinint.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/cio/qdio_thinint.c	2009-06-09 23:05:27.000000000 -0400
@@ -31,6 +31,7 @@
 
 /* list of thin interrupt input queues */
 static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
 
 /* adapter local summary indicator */
 static unsigned char *tiqdio_alsi;
@@ -95,12 +96,11 @@ void tiqdio_add_input_queues(struct qdio
 	if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
 		css_qdio_omit_svs = 1;
 
-	for_each_input_queue(irq_ptr, q, i) {
+	mutex_lock(&tiq_list_lock);
+	for_each_input_queue(irq_ptr, q, i)
 		list_add_rcu(&q->entry, &tiq_list);
-		synchronize_rcu();
-	}
+	mutex_unlock(&tiq_list_lock);
 	xchg(irq_ptr->dsci, 1);
-	tasklet_schedule(&tiqdio_tasklet);
 }
 
 /*
@@ -118,7 +118,10 @@ void tiqdio_remove_input_queues(struct q
 		/* if establish triggered an error */
 		if (!q || !q->entry.prev || !q->entry.next)
 			continue;
+
+		mutex_lock(&tiq_list_lock);
 		list_del_rcu(&q->entry);
+		mutex_unlock(&tiq_list_lock);
 		synchronize_rcu();
 	}
 }
@@ -155,15 +158,15 @@ static void __tiqdio_inbound_processing(
 	 */
 	qdio_check_outbound_after_thinint(q);
 
-again:
 	if (!qdio_inbound_q_moved(q))
 		return;
 
-	qdio_kick_inbound_handler(q);
+	qdio_kick_handler(q);
 
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 
 	qdio_stop_polling(q);
@@ -173,7 +176,8 @@ again:
 	 */
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 }
 
@@ -366,10 +370,11 @@ void qdio_shutdown_thinint(struct qdio_i
 
 void __exit tiqdio_unregister_thinints(void)
 {
-	tasklet_disable(&tiqdio_tasklet);
+	WARN_ON(!list_empty(&tiq_list));
 
 	if (tiqdio_alsi) {
 		s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
 		isc_unregister(QDIO_AIRQ_ISC);
 	}
+	tasklet_kill(&tiqdio_tasklet);
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/crypto/zcrypt_api.c linux-libre-2.6.30-gnu1/drivers/s390/crypto/zcrypt_api.c
--- linux-libre-2.6.29-gnu1/drivers/s390/crypto/zcrypt_api.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/crypto/zcrypt_api.c	2009-06-09 23:05:27.000000000 -0400
@@ -128,8 +128,7 @@ static void __zcrypt_increase_preference
 	if (l == zdev->list.prev)
 		return;
 	/* Move zdev behind l */
-	list_del(&zdev->list);
-	list_add(&zdev->list, l);
+	list_move(&zdev->list, l);
 }
 
 /**
@@ -157,8 +156,7 @@ static void __zcrypt_decrease_preference
 	if (l == zdev->list.next)
 		return;
 	/* Move zdev before l */
-	list_del(&zdev->list);
-	list_add_tail(&zdev->list, l);
+	list_move_tail(&zdev->list, l);
 }
 
 static void zcrypt_device_release(struct kref *kref)
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c linux-libre-2.6.30-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c
--- linux-libre-2.6.29-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/crypto/zcrypt_pcixcc.c	2009-06-09 23:05:27.000000000 -0400
@@ -781,8 +781,7 @@ static long zcrypt_pcixcc_send_cprb(stru
 		/* Signal pending. */
 		ap_cancel_message(zdev->ap_dev, &ap_msg);
 out_free:
-	memset(ap_msg.message, 0x0, ap_msg.length);
-	kfree(ap_msg.message);
+	kzfree(ap_msg.message);
 	return rc;
 }
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/ebcdic.c linux-libre-2.6.30-gnu1/drivers/s390/ebcdic.c
--- linux-libre-2.6.29-gnu1/drivers/s390/ebcdic.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/ebcdic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,246 +0,0 @@
-/*
- *  arch/s390/kernel/ebcdic.c
- *    ECBDIC -> ASCII, ASCII -> ECBDIC conversion tables.
- *
- *  S390 version
- *    Copyright (C) 1998 IBM Corporation
- *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <asm/types.h>
-
-/*
- * ASCII -> EBCDIC
- */
-__u8 _ascebc[256] =
-{
- /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
-     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08  BS    HT    LF    VT    FF    CR    SO    SI */
-     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10  DL    D1    D2    D3    D4    NK    SN    EB */
-     0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18  CN    EM    SB    EC    FS    GS    RS    US */
-     0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20  SP     !     "     #     $     %     &     ' */
-     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28   (     )     *     +     ,     -    .      / */
-     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30   0     1     2     3     4     5     6     7 */
-     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38   8     9     :     ;     <     =     >     ? */
-     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40   @     A     B     C     D     E     F     G */
-     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48   H     I     J     K     L     M     N     O */
-     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50   P     Q     R     S     T     U     V     W */
-     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58   X     Y     Z     [     \     ]     ^     _ */
-     0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60   `     a     b     c     d     e     f     g */
-     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68   h     i     j     k     l     m     n     o */
-     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70   p     q     r     s     t     u     v     w */
-     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78   x     y     z     {     |     }     ~    DL */
-     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC -> ASCII
- */
-__u8 _ebcasc[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           �ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           �ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     �Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     �°     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     �§  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           �ö              ---- */
-          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           �ü                   */
-          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     �Ö  ----  ----  ---- */
-          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     �Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
-/*
- * EBCDIC (capitals) -> ASCII (small case)
- */
-__u8 _ebcasc_reduce_case[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */ 
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-
- /* 0x40    SP   RSP           �ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
-
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-
- /* 0x58           �ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
-
- /* 0x60     -     /  ----     �Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x84, 0x07, 0x07, 0x07, 0x8F,
-
- /* 0x68              ----     ,     %     _     >     ? */ 
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-
- /* 0x90     �°     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xB0     ^                    ----     �§  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0xC8     H     I  ----           �ö              ---- */
-          0x68, 0x69, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0xD8     Q     R  ----           �ü                   */
-          0x71, 0x72, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xE8     Y     Z        ----     �Ö  ----  ----  ---- */
-          0x79, 0x7A, 0xFD, 0x07, 0x94, 0x07, 0x07, 0x07,
-
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
- /* 0xF8     8     9  ----  ----     �Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x81, 0x07, 0x07, 0x07
-};
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/Makefile linux-libre-2.6.30-gnu1/drivers/s390/Makefile
--- linux-libre-2.6.29-gnu1/drivers/s390/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -2,9 +2,6 @@
 # Makefile for the S/390 specific device drivers
 #
 
-CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
-
-obj-y += s390mach.o sysinfo.o
 obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
 
 drivers-y += drivers/s390/built-in.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/claw.c linux-libre-2.6.30-gnu1/drivers/s390/net/claw.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/claw.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/claw.c	2009-06-09 23:05:27.000000000 -0400
@@ -60,6 +60,9 @@
  *    1.25  Added Packing support
  *    1.5
  */
+
+#define KMSG_COMPONENT "claw"
+
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
 #include <asm/debug.h>
@@ -94,7 +97,7 @@
    CLAW uses the s390dbf file system  see claw_trace and claw_setup
 */
 
-
+static char version[] __initdata = "CLAW driver";
 static char debug_buffer[255];
 /**
  * Debug Facility Stuff
@@ -206,20 +209,30 @@ static struct net_device_stats *claw_sta
 static int pages_to_order_of_mag(int num_of_pages);
 static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
 /* sysfs Functions */
-static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_hname_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t claw_hname_write(struct device *dev,
+	struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_adname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_adname_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t claw_adname_write(struct device *dev,
+	struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_apname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_apname_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t claw_apname_write(struct device *dev,
+	struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_wbuff_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t claw_wbuff_write(struct device *dev,
+	struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_rbuff_show(struct device *dev,
+	struct device_attribute *attr, char *buf);
+static ssize_t claw_rbuff_write(struct device *dev,
+	struct device_attribute *attr,
 	const char *buf, size_t count);
 static int claw_add_files(struct device *dev);
 static void claw_remove_files(struct device *dev);
@@ -298,8 +311,8 @@ claw_probe(struct ccwgroup_device *cgdev
 	if (rc) {
 		probe_error(cgdev);
 		put_device(&cgdev->dev);
-		printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n",
-			dev_name(&cgdev->cdev[0]->dev), __func__, __LINE__);
+		dev_err(&cgdev->dev, "Creating the /proc files for a new"
+		" CLAW device failed\n");
 		CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
 		return rc;
 	}
@@ -335,6 +348,8 @@ claw_tx(struct sk_buff *skb, struct net_
         rc=claw_hw_tx( skb, dev, 1 );
         spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
 	CLAW_DBF_TEXT_(4, trace, "clawtx%d", rc);
+	if (rc)
+		rc = NETDEV_TX_BUSY;
         return rc;
 }   /*  end of claw_tx */
 
@@ -496,7 +511,8 @@ claw_open(struct net_device *dev)
            ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||
            (((privptr->channel[READ].flag |
 	   	privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) {
-                printk(KERN_INFO "%s: remote side is not ready\n", dev->name);
+		dev_info(&privptr->channel[READ].cdev->dev,
+			"%s: remote side is not ready\n", dev->name);
 		CLAW_DBF_TEXT(2, trace, "notrdy");
 
                 for ( i = 0; i < 2;  i++) {
@@ -582,10 +598,9 @@ claw_irq_handler(struct ccw_device *cdev
 	CLAW_DBF_TEXT(4, trace, "clawirq");
         /* Bypass all 'unsolicited interrupts' */
 	if (!cdev->dev.driver_data) {
-                printk(KERN_WARNING "claw: unsolicited interrupt for device:"
-		 	"%s received c-%02x d-%02x\n",
-		       dev_name(&cdev->dev), irb->scsw.cmd.cstat,
-		       irb->scsw.cmd.dstat);
+		dev_warn(&cdev->dev, "An uninitialized CLAW device received an"
+			" IRQ, c-%02x d-%02x\n",
+			irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
 		CLAW_DBF_TEXT(2, trace, "badirq");
                 return;
         }
@@ -597,8 +612,7 @@ claw_irq_handler(struct ccw_device *cdev
 	else if (privptr->channel[WRITE].cdev == cdev)
 		p_ch = &privptr->channel[WRITE];
 	else {
-		printk(KERN_WARNING "claw: Can't determine channel for "
-			"interrupt, device %s\n", dev_name(&cdev->dev));
+		dev_warn(&cdev->dev, "The device is not a CLAW device\n");
 		CLAW_DBF_TEXT(2, trace, "badchan");
 		return;
 	}
@@ -612,7 +626,8 @@ claw_irq_handler(struct ccw_device *cdev
 
 	/* Check for good subchannel return code, otherwise info message */
 	if (irb->scsw.cmd.cstat && !(irb->scsw.cmd.cstat & SCHN_STAT_PCI)) {
-                printk(KERN_INFO "%s: subchannel check for device: %04x -"
+		dev_info(&cdev->dev,
+			"%s: subchannel check for device: %04x -"
 			" Sch Stat %02x  Dev Stat %02x CPA - %04x\n",
                         dev->name, p_ch->devno,
 			irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
@@ -651,7 +666,7 @@ claw_irq_handler(struct ccw_device *cdev
 			wake_up(&p_ch->wait); /* wake claw_open (READ)*/
 		} else if (p_ch->flag == CLAW_WRITE) {
 			p_ch->claw_state = CLAW_START_WRITE;
-			/*	send SYSTEM_VALIDATE			*/
+			/*      send SYSTEM_VALIDATE                    */
 			claw_strt_read(dev, LOCK_NO);
 			claw_send_control(dev,
 				SYSTEM_VALIDATE_REQUEST,
@@ -659,10 +674,9 @@ claw_irq_handler(struct ccw_device *cdev
 				p_env->host_name,
 				p_env->adapter_name);
 		} else {
-			printk(KERN_WARNING "claw: unsolicited "
-				"interrupt for device:"
-				"%s received c-%02x d-%02x\n",
-				dev_name(&cdev->dev),
+			dev_warn(&cdev->dev, "The CLAW device received"
+				" an unexpected IRQ, "
+				"c-%02x d-%02x\n",
 				irb->scsw.cmd.cstat,
 				irb->scsw.cmd.dstat);
 			return;
@@ -677,8 +691,8 @@ claw_irq_handler(struct ccw_device *cdev
 			    (p_ch->irb->ecw[0] & 0x40) == 0x40 ||
 			    (p_ch->irb->ecw[0])        == 0) {
 				privptr->stats.rx_errors++;
-				printk(KERN_INFO "%s: Restart is "
-					"required after remote "
+				dev_info(&cdev->dev,
+					"%s: Restart is required after remote "
 					"side recovers \n",
 					dev->name);
 			}
@@ -713,11 +727,13 @@ claw_irq_handler(struct ccw_device *cdev
 		return;
 	case CLAW_START_WRITE:
 		if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
-			printk(KERN_INFO "%s: Unit Check Occured in "
+			dev_info(&cdev->dev,
+				"%s: Unit Check Occured in "
 				"write channel\n", dev->name);
 			clear_bit(0, (void *)&p_ch->IO_active);
 			if (p_ch->irb->ecw[0] & 0x80) {
-				printk(KERN_INFO "%s: Resetting Event "
+				dev_info(&cdev->dev,
+					"%s: Resetting Event "
 					"occurred:\n", dev->name);
 				init_timer(&p_ch->timer);
 				p_ch->timer.function =
@@ -725,7 +741,8 @@ claw_irq_handler(struct ccw_device *cdev
 				p_ch->timer.data = (unsigned long)p_ch;
 				p_ch->timer.expires = jiffies + 10*HZ;
 				add_timer(&p_ch->timer);
-				printk(KERN_INFO "%s: write connection "
+				dev_info(&cdev->dev,
+					"%s: write connection "
 					"restarting\n", dev->name);
 			}
 			CLAW_DBF_TEXT(4, trace, "rstrtwrt");
@@ -733,9 +750,10 @@ claw_irq_handler(struct ccw_device *cdev
 		}
 		if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
 			clear_bit(0, (void *)&p_ch->IO_active);
-			printk(KERN_INFO "%s: Unit Exception "
-			       "Occured in write channel\n",
-			       dev->name);
+			dev_info(&cdev->dev,
+				"%s: Unit Exception "
+				"occurred in write channel\n",
+				dev->name);
 		}
 		if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
 		(p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
@@ -757,8 +775,9 @@ claw_irq_handler(struct ccw_device *cdev
 		CLAW_DBF_TEXT(4, trace, "StWtExit");
 		return;
 	default:
-		printk(KERN_WARNING "%s: wrong selection code - irq "
-			"state=%d\n", dev->name, p_ch->claw_state);
+		dev_warn(&cdev->dev,
+			"The CLAW device for %s received an unexpected IRQ\n",
+			 dev->name);
 		CLAW_DBF_TEXT(2, trace, "badIRQ");
 		return;
         }
@@ -910,8 +929,10 @@ claw_release(struct net_device *dev)
         if (((privptr->channel[READ].last_dstat |
 		privptr->channel[WRITE].last_dstat) &
 		~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {
-                printk(KERN_WARNING "%s: channel problems during close - "
-			"read: %02x -  write: %02x\n",
+		dev_warn(&privptr->channel[READ].cdev->dev,
+			"Deactivating %s completed with incorrect"
+			" subchannel status "
+			"(read %02x, write %02x)\n",
                 dev->name,
 		privptr->channel[READ].last_dstat,
 		privptr->channel[WRITE].last_dstat);
@@ -1012,7 +1033,7 @@ static int
 pages_to_order_of_mag(int num_of_pages)
 {
 	int	order_of_mag=1;		/* assume 2 pages */
-	int	nump=2;
+	int	nump;
 
 	CLAW_DBF_TEXT_(5, trace, "pages%d", num_of_pages);
 	if (num_of_pages == 1)   {return 0; }  /* magnitude of 0 = 1 page */
@@ -1076,8 +1097,8 @@ add_claw_reads(struct net_device *dev, s
         }
 
         if ( privptr-> p_read_active_first ==NULL ) {
-                privptr-> p_read_active_first= p_first;  /*    set new first */
-                privptr-> p_read_active_last = p_last;   /*    set new last  */
+		privptr->p_read_active_first = p_first;  /*  set new first */
+		privptr->p_read_active_last  = p_last;   /*  set new last  */
         }
         else {
 
@@ -1113,7 +1134,7 @@ add_claw_reads(struct net_device *dev, s
                         privptr->p_read_active_last->r_TIC_2.cda=
 				(__u32)__pa(&p_first->read);
                 }
-                /*      chain in new set of blocks                              */
+		/*      chain in new set of blocks                         */
                 privptr->p_read_active_last->next = p_first;
                 privptr->p_read_active_last=p_last;
         } /* end of if ( privptr-> p_read_active_first ==NULL)  */
@@ -1135,21 +1156,18 @@ ccw_check_return_code(struct ccw_device
 		case -EBUSY: /* BUSY is a transient state no action needed */
 			break;
 		case -ENODEV:
-			printk(KERN_EMERG "%s: Missing device called "
-				"for IO ENODEV\n", dev_name(&cdev->dev));
-			break;
-		case -EIO:
-			printk(KERN_EMERG "%s: Status pending... EIO \n",
-				dev_name(&cdev->dev));
+			dev_err(&cdev->dev, "The remote channel adapter is not"
+				" available\n");
 			break;
 		case -EINVAL:
-			printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
-				dev_name(&cdev->dev));
+			dev_err(&cdev->dev,
+				"The status of the remote channel adapter"
+				" is not valid\n");
 			break;
 		default:
-			printk(KERN_EMERG "%s: Unknown error in "
-				 "Do_IO %d\n", dev_name(&cdev->dev),
-			       return_code);
+			dev_err(&cdev->dev, "The common device layer"
+				" returned error code %d\n",
+				  return_code);
 		}
 	}
 	CLAW_DBF_TEXT(4, trace, "ccwret");
@@ -1163,42 +1181,37 @@ static void
 ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
 {
 	struct net_device *ndev = p_ch->ndev;
+	struct device *dev = &p_ch->cdev->dev;
 
 	CLAW_DBF_TEXT(4, trace, "unitchek");
-        printk(KERN_INFO "%s: Unit Check with sense byte:0x%04x\n",
-	       ndev->name, sense);
+	dev_warn(dev, "The communication peer of %s disconnected\n",
+		ndev->name);
 
-        if (sense & 0x40) {
-                if (sense & 0x01) {
-                        printk(KERN_WARNING "%s: Interface disconnect or "
-				"Selective reset "
-				"occurred (remote side)\n", ndev->name);
-                }
-                else {
-                        printk(KERN_WARNING "%s: System reset occured"
-				" (remote side)\n", ndev->name);
-                }
-        }
-        else if (sense & 0x20) {
-                if (sense & 0x04) {
-                        printk(KERN_WARNING "%s: Data-streaming "
-				"timeout)\n", ndev->name);
-                }
-                else  {
-                        printk(KERN_WARNING "%s: Data-transfer parity"
-				" error\n", ndev->name);
-                }
-        }
-        else if (sense & 0x10) {
-                if (sense & 0x20) {
-                        printk(KERN_WARNING "%s: Hardware malfunction "
-				"(remote side)\n", ndev->name);
-                }
-                else {
-                        printk(KERN_WARNING "%s: read-data parity error "
-				"(remote side)\n", ndev->name);
-                }
-        }
+	if (sense & 0x40) {
+		if (sense & 0x01) {
+			dev_warn(dev, "The remote channel adapter for"
+				" %s has been reset\n",
+				ndev->name);
+		}
+	} else if (sense & 0x20) {
+		if (sense & 0x04) {
+			dev_warn(dev, "A data streaming timeout occurred"
+				" for %s\n",
+				ndev->name);
+		} else if (sense & 0x10) {
+			dev_warn(dev, "The remote channel adapter for %s"
+				" is faulty\n",
+				ndev->name);
+		} else {
+			dev_warn(dev, "A data transfer parity error occurred"
+				" for %s\n",
+				ndev->name);
+		}
+	} else if (sense & 0x10) {
+		dev_warn(dev, "A read data parity error occurred"
+			" for %s\n",
+			ndev->name);
+	}
 
 }   /*    end of ccw_check_unit_check    */
 
@@ -1235,7 +1248,7 @@ find_link(struct net_device *dev, char *
 			break;
 	}
 
-        return 0;
+	return rc;
 }    /*    end of find_link    */
 
 /*-------------------------------------------------------------------*
@@ -1347,7 +1360,10 @@ claw_hw_tx(struct sk_buff *skb, struct n
                 privptr->p_write_free_chain=p_this_ccw->next;
                 p_this_ccw->next=NULL;
                 --privptr->write_free_count; /* -1 */
-                bytesInThisBuffer=len_of_data;
+		if (len_of_data >= privptr->p_env->write_size)
+			bytesInThisBuffer = privptr->p_env->write_size;
+		else
+			bytesInThisBuffer = len_of_data;
                 memcpy( p_this_ccw->p_buffer,pDataAddress, bytesInThisBuffer);
                 len_of_data-=bytesInThisBuffer;
                 pDataAddress+=(unsigned long)bytesInThisBuffer;
@@ -1375,7 +1391,7 @@ claw_hw_tx(struct sk_buff *skb, struct n
         */
 
         if (p_first_ccw!=NULL) {
-                /*      setup ending ccw sequence for this segment              */
+		/*      setup ending ccw sequence for this segment           */
                 pEnd=privptr->p_end_ccw;
                 if (pEnd->write1) {
                         pEnd->write1=0x00;   /* second end ccw is now active */
@@ -1697,10 +1713,11 @@ init_ccw_bk(struct net_device *dev)
                         p_buf-> w_TIC_1.flags      = 0;
                         p_buf-> w_TIC_1.count      = 0;
 
-                        if (((unsigned long)p_buff+privptr->p_env->write_size) >=
+			if (((unsigned long)p_buff +
+					    privptr->p_env->write_size) >=
 			   ((unsigned long)(p_buff+2*
-				(privptr->p_env->write_size) -1) & PAGE_MASK)) {
-                        p_buff= p_buff+privptr->p_env->write_size;
+			    (privptr->p_env->write_size) - 1) & PAGE_MASK)) {
+				p_buff = p_buff+privptr->p_env->write_size;
                         }
                 }
            }
@@ -1840,15 +1857,16 @@ init_ccw_bk(struct net_device *dev)
                         p_buf->header.opcode=0xff;
                         p_buf->header.flag=CLAW_PENDING;
 
-                        if (((unsigned long)p_buff+privptr->p_env->read_size) >=
-				((unsigned long)(p_buff+2*(privptr->p_env->read_size) -1)
-				 & PAGE_MASK) ) {
+			if (((unsigned long)p_buff+privptr->p_env->read_size) >=
+			  ((unsigned long)(p_buff+2*(privptr->p_env->read_size)
+				 -1)
+			   & PAGE_MASK)) {
                                 p_buff= p_buff+privptr->p_env->read_size;
                         }
                         else {
                                 p_buff=
 				(void *)((unsigned long)
-					(p_buff+2*(privptr->p_env->read_size) -1)
+					(p_buff+2*(privptr->p_env->read_size)-1)
 					 & PAGE_MASK) ;
                         }
                 }   /* for read_buffers   */
@@ -1856,24 +1874,28 @@ init_ccw_bk(struct net_device *dev)
           else {  /* read Size >= PAGE_SIZE  */
                 for (i=0 ; i< privptr->p_env->read_buffers ; i++) {
                         p_buff = (void *)__get_free_pages(__GFP_DMA,
-				(int)pages_to_order_of_mag(privptr->p_buff_pages_perread) );
+				(int)pages_to_order_of_mag(
+					privptr->p_buff_pages_perread));
                         if (p_buff==NULL) {
                                 free_pages((unsigned long)privptr->p_buff_ccw,
-					(int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
+					(int)pages_to_order_of_mag(privptr->
+					p_buff_ccw_num));
 				/* free the write pages  */
 	                        p_buf=privptr->p_buff_write;
                                 while (p_buf!=NULL) {
-                                        free_pages((unsigned long)p_buf->p_buffer,
-						(int)pages_to_order_of_mag(
-						privptr->p_buff_pages_perwrite ));
+					free_pages(
+					    (unsigned long)p_buf->p_buffer,
+					    (int)pages_to_order_of_mag(
+					    privptr->p_buff_pages_perwrite));
                                         p_buf=p_buf->next;
                                 }
 				/* free any read pages already alloc  */
 	                        p_buf=privptr->p_buff_read;
                                 while (p_buf!=NULL) {
-                                        free_pages((unsigned long)p_buf->p_buffer,
-						(int)pages_to_order_of_mag(
-						privptr->p_buff_pages_perread ));
+					free_pages(
+					    (unsigned long)p_buf->p_buffer,
+					    (int)pages_to_order_of_mag(
+					     privptr->p_buff_pages_perread));
                                         p_buf=p_buf->next;
                                 }
                                 privptr->p_buff_ccw=NULL;
@@ -2003,7 +2025,7 @@ claw_process_control( struct net_device
 	tdev = &privptr->channel[READ].cdev->dev;
 	memcpy( &temp_host_name, p_env->host_name, 8);
         memcpy( &temp_ws_name, p_env->adapter_name , 8);
-        printk(KERN_INFO "%s: CLAW device %.8s: "
+	dev_info(tdev, "%s: CLAW device %.8s: "
 		"Received Control Packet\n",
 		dev->name, temp_ws_name);
         if (privptr->release_pend==1) {
@@ -2022,32 +2044,30 @@ claw_process_control( struct net_device
 		if (p_ctlbk->version != CLAW_VERSION_ID) {
 			claw_snd_sys_validate_rsp(dev, p_ctlbk,
 				CLAW_RC_WRONG_VERSION);
-			printk("%s: %d is wrong version id. "
-			       "Expected %d\n",
-			       dev->name, p_ctlbk->version,
-			       CLAW_VERSION_ID);
+			dev_warn(tdev, "The communication peer of %s"
+				" uses an incorrect API version %d\n",
+				dev->name, p_ctlbk->version);
 		}
 		p_sysval = (struct sysval *)&(p_ctlbk->data);
-		printk("%s: Recv Sys Validate Request: "
-		       "Vers=%d,link_id=%d,Corr=%d,WS name=%."
-		       "8s,Host name=%.8s\n",
-		       dev->name, p_ctlbk->version,
-		       p_ctlbk->linkid,
-		       p_ctlbk->correlator,
-		       p_sysval->WS_name,
-		       p_sysval->host_name);
+		dev_info(tdev, "%s: Recv Sys Validate Request: "
+			"Vers=%d,link_id=%d,Corr=%d,WS name=%.8s,"
+			"Host name=%.8s\n",
+			dev->name, p_ctlbk->version,
+			p_ctlbk->linkid,
+			p_ctlbk->correlator,
+			p_sysval->WS_name,
+			p_sysval->host_name);
 		if (memcmp(temp_host_name, p_sysval->host_name, 8)) {
 			claw_snd_sys_validate_rsp(dev, p_ctlbk,
 				CLAW_RC_NAME_MISMATCH);
 			CLAW_DBF_TEXT(2, setup, "HSTBAD");
 			CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->host_name);
 			CLAW_DBF_TEXT_(2, setup, "%s", temp_host_name);
-			printk(KERN_INFO "%s:  Host name mismatch\n",
-				dev->name);
-			printk(KERN_INFO "%s: Received :%s: "
-				"expected :%s: \n",
-				dev->name,
+			dev_warn(tdev,
+				"Host name %s for %s does not match the"
+				" remote adapter name %s\n",
 				p_sysval->host_name,
+				dev->name,
 				temp_host_name);
 		}
 		if (memcmp(temp_ws_name, p_sysval->WS_name, 8)) {
@@ -2056,35 +2076,38 @@ claw_process_control( struct net_device
 			CLAW_DBF_TEXT(2, setup, "WSNBAD");
 			CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->WS_name);
 			CLAW_DBF_TEXT_(2, setup, "%s", temp_ws_name);
-			printk(KERN_INFO "%s: WS name mismatch\n",
-				dev->name);
-			printk(KERN_INFO "%s: Received :%s: "
-			       "expected :%s: \n",
-			       dev->name,
-			       p_sysval->WS_name,
-			       temp_ws_name);
+			dev_warn(tdev, "Adapter name %s for %s does not match"
+				" the remote host name %s\n",
+				p_sysval->WS_name,
+				dev->name,
+				temp_ws_name);
 		}
 		if ((p_sysval->write_frame_size < p_env->write_size) &&
 		    (p_env->packing == 0)) {
 			claw_snd_sys_validate_rsp(dev, p_ctlbk,
 				CLAW_RC_HOST_RCV_TOO_SMALL);
-			printk(KERN_INFO "%s: host write size is too "
-				"small\n", dev->name);
+			dev_warn(tdev,
+				"The local write buffer is smaller than the"
+				" remote read buffer\n");
 			CLAW_DBF_TEXT(2, setup, "wrtszbad");
 		}
 		if ((p_sysval->read_frame_size < p_env->read_size) &&
 		    (p_env->packing == 0)) {
 			claw_snd_sys_validate_rsp(dev, p_ctlbk,
 				CLAW_RC_HOST_RCV_TOO_SMALL);
-			printk(KERN_INFO "%s: host read size is too "
-				"small\n", dev->name);
+			dev_warn(tdev,
+				"The local read buffer is smaller than the"
+				" remote write buffer\n");
 			CLAW_DBF_TEXT(2, setup, "rdsizbad");
 		}
 		claw_snd_sys_validate_rsp(dev, p_ctlbk, 0);
-		printk(KERN_INFO "%s: CLAW device %.8s: System validate "
-			"completed.\n", dev->name, temp_ws_name);
-		printk("%s: sys Validate Rsize:%d Wsize:%d\n", dev->name,
-			p_sysval->read_frame_size, p_sysval->write_frame_size);
+		dev_info(tdev,
+			"CLAW device %.8s: System validate"
+			" completed.\n", temp_ws_name);
+		dev_info(tdev,
+			"%s: sys Validate Rsize:%d Wsize:%d\n",
+			dev->name, p_sysval->read_frame_size,
+			p_sysval->write_frame_size);
 		privptr->system_validate_comp = 1;
 		if (strncmp(p_env->api_type, WS_APPL_NAME_PACKED, 6) == 0)
 			p_env->packing = PACKING_ASK;
@@ -2092,8 +2115,10 @@ claw_process_control( struct net_device
 		break;
 	case SYSTEM_VALIDATE_RESPONSE:
 		p_sysval = (struct sysval *)&(p_ctlbk->data);
-		printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d,"
-			"WS name=%.8s,Host name=%.8s\n",
+		dev_info(tdev,
+			"Settings for %s validated (version=%d, "
+			"remote device=%d, rc=%d, adapter name=%.8s, "
+			"host name=%.8s)\n",
 			dev->name,
 			p_ctlbk->version,
 			p_ctlbk->correlator,
@@ -2102,41 +2127,39 @@ claw_process_control( struct net_device
 			p_sysval->host_name);
 		switch (p_ctlbk->rc) {
 		case 0:
-			printk(KERN_INFO "%s: CLAW device "
-				"%.8s: System validate "
-				"completed.\n",
-			       dev->name, temp_ws_name);
+			dev_info(tdev, "%s: CLAW device "
+				"%.8s: System validate completed.\n",
+				dev->name, temp_ws_name);
 			if (privptr->system_validate_comp == 0)
 				claw_strt_conn_req(dev);
 			privptr->system_validate_comp = 1;
 			break;
 		case CLAW_RC_NAME_MISMATCH:
-			printk(KERN_INFO "%s: Sys Validate "
-				"Resp : Host, WS name is "
-				"mismatch\n",
-			       dev->name);
+			dev_warn(tdev, "Validating %s failed because of"
+				" a host or adapter name mismatch\n",
+				dev->name);
 			break;
 		case CLAW_RC_WRONG_VERSION:
-			printk(KERN_INFO "%s: Sys Validate "
-				"Resp : Wrong version\n",
+			dev_warn(tdev, "Validating %s failed because of a"
+				" version conflict\n",
 				dev->name);
 			break;
 		case CLAW_RC_HOST_RCV_TOO_SMALL:
-			printk(KERN_INFO "%s: Sys Validate "
-				"Resp : bad frame size\n",
+			dev_warn(tdev, "Validating %s failed because of a"
+				" frame size conflict\n",
 				dev->name);
 			break;
 		default:
-			printk(KERN_INFO "%s: Sys Validate "
-				"error code=%d \n",
-				 dev->name, p_ctlbk->rc);
+			dev_warn(tdev, "The communication peer of %s rejected"
+				" the connection\n",
+				 dev->name);
 			break;
 		}
 		break;
 
 	case CONNECTION_REQUEST:
 		p_connect = (struct conncmd *)&(p_ctlbk->data);
-		printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d,"
+		dev_info(tdev, "%s: Recv Conn Req: Vers=%d,link_id=%d,"
 			"Corr=%d,HOST appl=%.8s,WS appl=%.8s\n",
 			dev->name,
 			p_ctlbk->version,
@@ -2146,21 +2169,21 @@ claw_process_control( struct net_device
 			p_connect->WS_name);
 		if (privptr->active_link_ID != 0) {
 			claw_snd_disc(dev, p_ctlbk);
-			printk(KERN_INFO "%s: Conn Req error : "
-				"already logical link is active \n",
+			dev_info(tdev, "%s rejected a connection request"
+				" because it is already active\n",
 				dev->name);
 		}
 		if (p_ctlbk->linkid != 1) {
 			claw_snd_disc(dev, p_ctlbk);
-			printk(KERN_INFO "%s: Conn Req error : "
-				"req logical link id is not 1\n",
+			dev_info(tdev, "%s rejected a request to open multiple"
+				" connections\n",
 				dev->name);
 		}
 		rc = find_link(dev, p_connect->host_name, p_connect->WS_name);
 		if (rc != 0) {
 			claw_snd_disc(dev, p_ctlbk);
-			printk(KERN_INFO "%s: Conn Resp error: "
-				"req appl name does not match\n",
+			dev_info(tdev, "%s rejected a connection request"
+				" because of a type mismatch\n",
 				dev->name);
 		}
 		claw_send_control(dev,
@@ -2172,7 +2195,7 @@ claw_process_control( struct net_device
 			p_env->packing = PACK_SEND;
 			claw_snd_conn_req(dev, 0);
 		}
-		printk(KERN_INFO "%s: CLAW device %.8s: Connection "
+		dev_info(tdev, "%s: CLAW device %.8s: Connection "
 			"completed link_id=%d.\n",
 			dev->name, temp_ws_name,
 			p_ctlbk->linkid);
@@ -2182,7 +2205,7 @@ claw_process_control( struct net_device
 		break;
 	case CONNECTION_RESPONSE:
 		p_connect = (struct conncmd *)&(p_ctlbk->data);
-		printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d,"
+		dev_info(tdev, "%s: Recv Conn Resp: Vers=%d,link_id=%d,"
 			"Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n",
 			dev->name,
 			p_ctlbk->version,
@@ -2193,16 +2216,18 @@ claw_process_control( struct net_device
 			p_connect->WS_name);
 
 		if (p_ctlbk->rc != 0) {
-			printk(KERN_INFO "%s: Conn Resp error: rc=%d \n",
-				dev->name, p_ctlbk->rc);
+			dev_warn(tdev, "The communication peer of %s rejected"
+				" a connection request\n",
+				dev->name);
 			return 1;
 		}
 		rc = find_link(dev,
 			p_connect->host_name, p_connect->WS_name);
 		if (rc != 0) {
 			claw_snd_disc(dev, p_ctlbk);
-			printk(KERN_INFO "%s: Conn Resp error: "
-				"req appl name does not match\n",
+			dev_warn(tdev, "The communication peer of %s"
+				" rejected a connection "
+				"request because of a type mismatch\n",
 				 dev->name);
 		}
 		/* should be until CONNECTION_CONFIRM */
@@ -2210,7 +2235,8 @@ claw_process_control( struct net_device
 		break;
 	case CONNECTION_CONFIRM:
 		p_connect = (struct conncmd *)&(p_ctlbk->data);
-		printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
+		dev_info(tdev,
+			"%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
 			"Corr=%d,Host appl=%.8s,WS appl=%.8s\n",
 			dev->name,
 			p_ctlbk->version,
@@ -2221,21 +2247,21 @@ claw_process_control( struct net_device
 		if (p_ctlbk->linkid == -(privptr->active_link_ID)) {
 			privptr->active_link_ID = p_ctlbk->linkid;
 			if (p_env->packing > PACKING_ASK) {
-				printk(KERN_INFO "%s: Confirmed Now packing\n",
-					dev->name);
+				dev_info(tdev,
+				"%s: Confirmed Now packing\n", dev->name);
 				p_env->packing = DO_PACKED;
 			}
 			p_ch = &privptr->channel[WRITE];
 			wake_up(&p_ch->wait);
 		} else {
-		       printk(KERN_INFO "%s: Conn confirm: "
-				"unexpected linkid=%d \n",
+			dev_warn(tdev, "Activating %s failed because of"
+				" an incorrect link ID=%d\n",
 				dev->name, p_ctlbk->linkid);
 			claw_snd_disc(dev, p_ctlbk);
 		}
 		break;
 	case DISCONNECT:
-		printk(KERN_INFO "%s: Disconnect: "
+		dev_info(tdev, "%s: Disconnect: "
 			"Vers=%d,link_id=%d,Corr=%d\n",
 			dev->name, p_ctlbk->version,
 			p_ctlbk->linkid, p_ctlbk->correlator);
@@ -2247,12 +2273,13 @@ claw_process_control( struct net_device
 			privptr->active_link_ID = 0;
 		break;
 	case CLAW_ERROR:
-		printk(KERN_INFO "%s: CLAW ERROR detected\n",
+		dev_warn(tdev, "The communication peer of %s failed\n",
 			dev->name);
 		break;
 	default:
-		printk(KERN_INFO "%s:  Unexpected command code=%d \n",
-			dev->name,  p_ctlbk->command);
+		dev_warn(tdev, "The communication peer of %s sent"
+			" an unknown command code\n",
+			dev->name);
 		break;
         }
 
@@ -2294,12 +2321,14 @@ claw_send_control(struct net_device *dev
                         memcpy(&p_sysval->host_name, local_name, 8);
                         memcpy(&p_sysval->WS_name, remote_name, 8);
 			if (privptr->p_env->packing > 0) {
-                        	p_sysval->read_frame_size=DEF_PACK_BUFSIZE;
-	                        p_sysval->write_frame_size=DEF_PACK_BUFSIZE;
+				p_sysval->read_frame_size = DEF_PACK_BUFSIZE;
+				p_sysval->write_frame_size = DEF_PACK_BUFSIZE;
 			} else {
 				/* how big is the biggest group of packets */
-				p_sysval->read_frame_size=privptr->p_env->read_size;
-	                        p_sysval->write_frame_size=privptr->p_env->write_size;
+			   p_sysval->read_frame_size =
+				privptr->p_env->read_size;
+			   p_sysval->write_frame_size =
+				privptr->p_env->write_size;
 			}
                         memset(&p_sysval->reserved, 0x00, 4);
                         break;
@@ -2485,7 +2514,6 @@ unpack_read(struct net_device *dev )
 	p_dev = &privptr->channel[READ].cdev->dev;
 	p_env = privptr->p_env;
         p_this_ccw=privptr->p_read_active_first;
-        i=0;
 	while (p_this_ccw!=NULL && p_this_ccw->header.flag!=CLAW_PENDING) {
 		pack_off = 0;
 		p = 0;
@@ -2511,8 +2539,10 @@ unpack_read(struct net_device *dev )
                         mtc_this_frm=1;
                         if (p_this_ccw->header.length!=
 				privptr->p_env->read_size ) {
-                                printk(KERN_INFO " %s: Invalid frame detected "
-					"length is %02x\n" ,
+				dev_warn(p_dev,
+					"The communication peer of %s"
+					" sent a faulty"
+					" frame of length %02x\n",
                                         dev->name, p_this_ccw->header.length);
                         }
                 }
@@ -2544,7 +2574,7 @@ unpack_next:
 				goto NextFrame;
 			p_packd = p_this_ccw->p_buffer+pack_off;
 			p_packh = (struct clawph *) p_packd;
-			if ((p_packh->len == 0) || /* all done with this frame? */
+			if ((p_packh->len == 0) || /* done with this frame? */
 			    (p_packh->flag != 0))
 				goto NextFrame;
 			bytes_to_mov = p_packh->len;
@@ -2594,9 +2624,9 @@ unpack_next:
                                 netif_rx(skb);
                         }
                         else {
+				dev_info(p_dev, "Allocating a buffer for"
+					" incoming data failed\n");
                                 privptr->stats.rx_dropped++;
-                                printk(KERN_WARNING "%s: %s() low on memory\n",
-				dev->name,__func__);
                         }
                         privptr->mtc_offset=0;
                         privptr->mtc_logical_link=-1;
@@ -2720,8 +2750,8 @@ claw_strt_out_IO( struct net_device *dev
         if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) {
                 parm = (unsigned long) p_ch;
 		CLAW_DBF_TEXT(2, trace, "StWrtIO");
-                rc = ccw_device_start (p_ch->cdev,&p_first_ccw->write, parm,
-				       0xff, 0);
+		rc = ccw_device_start(p_ch->cdev, &p_first_ccw->write, parm,
+				      0xff, 0);
                 if (rc != 0) {
                         ccw_check_return_code(p_ch->cdev, rc);
                 }
@@ -2816,22 +2846,26 @@ claw_free_netdevice(struct net_device *
  * Initialize everything of the net device except the name and the
  * channel structs.
  */
+static const struct net_device_ops claw_netdev_ops = {
+	.ndo_open		= claw_open,
+	.ndo_stop		= claw_release,
+	.ndo_get_stats		= claw_stats,
+	.ndo_start_xmit		= claw_tx,
+	.ndo_change_mtu		= claw_change_mtu,
+};
+
 static void
 claw_init_netdevice(struct net_device * dev)
 {
 	CLAW_DBF_TEXT(2, setup, "init_dev");
 	CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
 	dev->mtu = CLAW_DEFAULT_MTU_SIZE;
-	dev->hard_start_xmit = claw_tx;
-	dev->open = claw_open;
-	dev->stop = claw_release;
-	dev->get_stats = claw_stats;
-	dev->change_mtu = claw_change_mtu;
 	dev->hard_header_len = 0;
 	dev->addr_len = 0;
 	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 1300;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+	dev->netdev_ops = &claw_netdev_ops;
 	CLAW_DBF_TEXT(2, setup, "initok");
 	return;
 }
@@ -2880,8 +2914,8 @@ claw_new_device(struct ccwgroup_device *
 	int ret;
 	struct ccw_dev_id dev_id;
 
-	printk(KERN_INFO "claw: add for %s\n",
-	       dev_name(&cgdev->cdev[READ]->dev));
+	dev_info(&cgdev->dev, "add for %s\n",
+		 dev_name(&cgdev->cdev[READ]->dev));
 	CLAW_DBF_TEXT(2, setup, "new_dev");
 	privptr = cgdev->dev.driver_data;
 	cgdev->cdev[READ]->dev.driver_data = privptr;
@@ -2897,29 +2931,28 @@ claw_new_device(struct ccwgroup_device *
 	if (ret == 0)
 		ret = add_channel(cgdev->cdev[1],1,privptr);
 	if (ret != 0) {
-		printk(KERN_WARNING
-			"add channel failed with ret = %d\n", ret);
+		dev_warn(&cgdev->dev, "Creating a CLAW group device"
+			" failed with error code %d\n", ret);
 		goto out;
 	}
 	ret = ccw_device_set_online(cgdev->cdev[READ]);
 	if (ret != 0) {
-		printk(KERN_WARNING
-			"claw: ccw_device_set_online %s READ failed "
-		       "with ret = %d\n", dev_name(&cgdev->cdev[READ]->dev),
-		       ret);
+		dev_warn(&cgdev->dev,
+			"Setting the read subchannel online"
+			" failed with error code %d\n", ret);
 		goto out;
 	}
 	ret = ccw_device_set_online(cgdev->cdev[WRITE]);
 	if (ret != 0) {
-		printk(KERN_WARNING
-			"claw: ccw_device_set_online %s WRITE failed "
-		       "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev),
-		       ret);
+		dev_warn(&cgdev->dev,
+			"Setting the write subchannel online "
+			"failed with error code %d\n", ret);
 		goto out;
 	}
 	dev = alloc_netdev(0,"claw%d",claw_init_netdevice);
 	if (!dev) {
-		printk(KERN_WARNING "%s:alloc_netdev failed\n",__func__);
+		dev_warn(&cgdev->dev,
+			"Activating the CLAW device failed\n");
 		goto out;
 	}
 	dev->ml_priv = privptr;
@@ -2947,13 +2980,13 @@ claw_new_device(struct ccwgroup_device *
 	privptr->channel[WRITE].ndev = dev;
 	privptr->p_env->ndev = dev;
 
-	printk(KERN_INFO "%s:readsize=%d  writesize=%d "
+	dev_info(&cgdev->dev, "%s:readsize=%d  writesize=%d "
 		"readbuffer=%d writebuffer=%d read=0x%04x write=0x%04x\n",
                 dev->name, p_env->read_size,
 		p_env->write_size, p_env->read_buffers,
                 p_env->write_buffers, p_env->devno[READ],
 		p_env->devno[WRITE]);
-        printk(KERN_INFO "%s:host_name:%.8s, adapter_name "
+	dev_info(&cgdev->dev, "%s:host_name:%.8s, adapter_name "
 		":%.8s api_type: %.8s\n",
                 dev->name, p_env->host_name,
 		p_env->adapter_name , p_env->api_type);
@@ -2997,8 +3030,8 @@ claw_shutdown_device(struct ccwgroup_dev
 	ndev = priv->channel[READ].ndev;
 	if (ndev) {
 		/* Close the device */
-		printk(KERN_INFO
-			"%s: shuting down \n",ndev->name);
+		dev_info(&cgdev->dev, "%s: shutting down \n",
+			ndev->name);
 		if (ndev->flags & IFF_RUNNING)
 			ret = claw_release(ndev);
 		ndev->flags &=~IFF_RUNNING;
@@ -3023,8 +3056,7 @@ claw_remove_device(struct ccwgroup_devic
 	CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
 	priv = cgdev->dev.driver_data;
 	BUG_ON(!priv);
-	printk(KERN_INFO "claw: %s() called %s will be removed.\n",
-			__func__, dev_name(&cgdev->cdev[0]->dev));
+	dev_info(&cgdev->dev, " will be removed.\n");
 	if (cgdev->state == CCWGROUP_ONLINE)
 		claw_shutdown_device(cgdev);
 	claw_remove_files(&cgdev->dev);
@@ -3063,7 +3095,8 @@ claw_hname_show(struct device *dev, stru
 }
 
 static ssize_t
-claw_hname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_hname_write(struct device *dev, struct device_attribute *attr,
+	 const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -3100,7 +3133,8 @@ claw_adname_show(struct device *dev, str
 }
 
 static ssize_t
-claw_adname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_adname_write(struct device *dev, struct device_attribute *attr,
+	 const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -3138,7 +3172,8 @@ claw_apname_show(struct device *dev, str
 }
 
 static ssize_t
-claw_apname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_apname_write(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -3185,7 +3220,8 @@ claw_wbuff_show(struct device *dev, stru
 }
 
 static ssize_t
-claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -3226,7 +3262,8 @@ claw_rbuff_show(struct device *dev, stru
 }
 
 static ssize_t
-claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *p_env;
@@ -3289,7 +3326,7 @@ claw_cleanup(void)
 {
 	unregister_cu3088_discipline(&claw_group_driver);
 	claw_unregister_debug_facility();
-	printk(KERN_INFO "claw: Driver unloaded\n");
+	pr_info("Driver unloaded\n");
 
 }
 
@@ -3303,12 +3340,12 @@ static int __init
 claw_init(void)
 {
 	int ret = 0;
-	printk(KERN_INFO "claw: starting driver\n");
 
+	pr_info("Loading %s\n", version);
 	ret = claw_register_debug_facility();
 	if (ret) {
-		printk(KERN_WARNING "claw: %s() debug_register failed %d\n",
-			__func__,ret);
+		pr_err("Registering with the S/390 debug feature"
+			" failed with error code %d\n", ret);
 		return ret;
 	}
 	CLAW_DBF_TEXT(2, setup, "init_mod");
@@ -3316,8 +3353,8 @@ claw_init(void)
 	if (ret) {
 		CLAW_DBF_TEXT(2, setup, "init_bad");
 		claw_unregister_debug_facility();
-		printk(KERN_WARNING "claw; %s() cu3088 register failed %d\n",
-			__func__,ret);
+		pr_err("Registering with the cu3088 device driver failed "
+			   "with error code %d\n", ret);
 	}
 	return ret;
 }
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_fsms.c linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_fsms.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_fsms.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_fsms.c	2009-06-09 23:05:27.000000000 -0400
@@ -410,9 +410,8 @@ static void chx_rx(fsm_instance *fi, int
 		priv->stats.rx_length_errors++;
 						goto again;
 	}
-	block_len -= 2;
-	if (block_len > 0) {
-		*((__u16 *)skb->data) = block_len;
+	if (block_len > 2) {
+		*((__u16 *)skb->data) = block_len - 2;
 		ctcm_unpack_skb(ch, skb);
 	}
  again:
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_main.c linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_main.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -105,7 +105,8 @@ void ctcm_unpack_skb(struct channel *ch,
 			return;
 		}
 		pskb->protocol = ntohs(header->type);
-		if (header->length <= LL_HEADER_LENGTH) {
+		if ((header->length <= LL_HEADER_LENGTH) ||
+		    (len <= LL_HEADER_LENGTH)) {
 			if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
 				CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
 					"%s(%s): Illegal packet size %d(%d,%d)"
@@ -167,11 +168,9 @@ void ctcm_unpack_skb(struct channel *ch,
 		if (len > 0) {
 			skb_pull(pskb, header->length);
 			if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
-				if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
-					CTCM_DBF_DEV_NAME(TRACE, dev,
-						"Overrun in ctcm_unpack_skb");
-					ch->logflags |= LOG_FLAG_OVERRUN;
-				}
+				CTCM_DBF_DEV_NAME(TRACE, dev,
+					"Overrun in ctcm_unpack_skb");
+				ch->logflags |= LOG_FLAG_OVERRUN;
 				return;
 			}
 			skb_put(pskb, LL_HEADER_LENGTH);
@@ -906,11 +905,11 @@ static int ctcm_tx(struct sk_buff *skb,
 	}
 
 	if (ctcm_test_and_set_busy(dev))
-		return -EBUSY;
+		return NETDEV_TX_BUSY;
 
 	dev->trans_start = jiffies;
 	if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
-		return 1;
+		return NETDEV_TX_BUSY;
 	return 0;
 }
 
@@ -1099,12 +1098,24 @@ static void ctcm_free_netdevice(struct n
 
 struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
 
+static const struct net_device_ops ctcm_netdev_ops = {
+	.ndo_open		= ctcm_open,
+	.ndo_stop		= ctcm_close,
+	.ndo_get_stats		= ctcm_stats,
+	.ndo_change_mtu	   	= ctcm_change_mtu,
+	.ndo_start_xmit		= ctcm_tx,
+};
+
+static const struct net_device_ops ctcm_mpc_netdev_ops = {
+	.ndo_open		= ctcm_open,
+	.ndo_stop		= ctcm_close,
+	.ndo_get_stats		= ctcm_stats,
+	.ndo_change_mtu	   	= ctcm_change_mtu,
+	.ndo_start_xmit		= ctcmpc_tx,
+};
+
 void static ctcm_dev_setup(struct net_device *dev)
 {
-	dev->open = ctcm_open;
-	dev->stop = ctcm_close;
-	dev->get_stats = ctcm_stats;
-	dev->change_mtu = ctcm_change_mtu;
 	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 100;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
@@ -1157,12 +1168,12 @@ static struct net_device *ctcm_init_netd
 		dev->mtu = MPC_BUFSIZE_DEFAULT -
 				TH_HEADER_LENGTH - PDU_HEADER_LENGTH;
 
-		dev->hard_start_xmit = ctcmpc_tx;
+		dev->netdev_ops = &ctcm_mpc_netdev_ops;
 		dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
 		priv->buffer_size = MPC_BUFSIZE_DEFAULT;
 	} else {
 		dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
-		dev->hard_start_xmit = ctcm_tx;
+		dev->netdev_ops = &ctcm_netdev_ops;
 		dev->hard_header_len = LL_HEADER_LENGTH + 2;
 	}
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_mpc.c linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_mpc.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/ctcm_mpc.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/ctcm_mpc.c	2009-06-09 23:05:27.000000000 -0400
@@ -393,7 +393,6 @@ int ctc_mpc_alloc_channel(int port_num,
 		} else {
 			/* there are problems...bail out	    */
 			/* there may be a state mismatch so restart */
-			grp->port_persist = 1;
 			fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
 			grp->allocchan_callback_retries = 0;
 		}
@@ -699,11 +698,9 @@ static void ctcmpc_send_sweep_resp(struc
 	return;
 
 done:
-	if (rc != 0) {
-		grp->in_sweep = 0;
-		ctcm_clear_busy_do(dev);
-		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-	}
+	grp->in_sweep = 0;
+	ctcm_clear_busy_do(dev);
+	fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
 
 	return;
 }
@@ -1118,7 +1115,6 @@ static void ctcmpc_unpack_skb(struct cha
 
 		if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
 					goto done;
-		pdu_last_seen = 0;
 		while ((pskb->len > 0) && !pdu_last_seen) {
 			curr_pdu = (struct pdu *)pskb->data;
 
@@ -1396,8 +1392,7 @@ static void mpc_action_go_inop(fsm_insta
 				CTCM_FUNTAIL, dev->name);
 	if ((grp->saved_state != MPCG_STATE_RESET) ||
 		/* dealloc_channel has been called */
-			((grp->saved_state == MPCG_STATE_RESET) &&
-						(grp->port_persist == 0)))
+		(grp->port_persist == 0))
 		fsm_deltimer(&priv->restart_timer);
 
 	wch = priv->channel[WRITE];
@@ -1917,10 +1912,8 @@ static void mpc_action_doxid7(fsm_instan
 
 	if (priv)
 		grp = priv->mpcg;
-	if (grp == NULL) {
-		fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+	if (grp == NULL)
 		return;
-	}
 
 	for (direction = READ; direction <= WRITE; direction++)	{
 		struct channel *ch = priv->channel[direction];
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/lcs.c linux-libre-2.6.30-gnu1/drivers/s390/net/lcs.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/lcs.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/lcs.c	2009-06-09 23:05:27.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/in.h>
 #include <linux/igmp.h>
 #include <linux/delay.h>
+#include <linux/kthread.h>
 #include <net/arp.h>
 #include <net/ip.h>
 
@@ -1259,7 +1260,6 @@ lcs_register_mc_addresses(void *data)
 	struct in_device *in4_dev;
 
 	card = (struct lcs_card *) data;
-	daemonize("regipm");
 
 	if (!lcs_do_run_thread(card, LCS_SET_MC_THREAD))
 		return 0;
@@ -1562,7 +1562,7 @@ __lcs_start_xmit(struct lcs_card *card,
 	if (skb == NULL) {
 		card->stats.tx_dropped++;
 		card->stats.tx_errors++;
-		return -EIO;
+		return 0;
 	}
 	if (card->state != DEV_STATE_UP) {
 		dev_kfree_skb(skb);
@@ -1587,7 +1587,7 @@ __lcs_start_xmit(struct lcs_card *card,
 		card->tx_buffer = lcs_get_buffer(&card->write);
 		if (card->tx_buffer == NULL) {
 			card->stats.tx_dropped++;
-			rc = -EBUSY;
+			rc = NETDEV_TX_BUSY;
 			goto out;
 		}
 		card->tx_buffer->callback = lcs_txbuffer_cb;
@@ -1753,11 +1753,10 @@ lcs_start_kernel_thread(struct work_stru
 	struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter);
 	LCS_DBF_TEXT(5, trace, "krnthrd");
 	if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
-		kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
+		kthread_run(lcs_recovery, card, "lcs_recover");
 #ifdef CONFIG_IP_MULTICAST
 	if (lcs_do_start_thread(card, LCS_SET_MC_THREAD))
-		kernel_thread(lcs_register_mc_addresses,
-				(void *) card, SIGCHLD);
+		kthread_run(lcs_register_mc_addresses, card, "regipm");
 #endif
 }
 
@@ -2101,6 +2100,20 @@ lcs_register_netdev(struct ccwgroup_devi
 /**
  * lcs_new_device will be called by setting the group device online.
  */
+static const struct net_device_ops lcs_netdev_ops = {
+	.ndo_open		= lcs_open_device,
+	.ndo_stop		= lcs_stop_device,
+	.ndo_get_stats		= lcs_getstats,
+	.ndo_start_xmit		= lcs_start_xmit,
+};
+
+static const struct net_device_ops lcs_mc_netdev_ops = {
+	.ndo_open		= lcs_open_device,
+	.ndo_stop		= lcs_stop_device,
+	.ndo_get_stats		= lcs_getstats,
+	.ndo_start_xmit		= lcs_start_xmit,
+	.ndo_set_multicast_list = lcs_set_multicast_list,
+};
 
 static int
 lcs_new_device(struct ccwgroup_device *ccwgdev)
@@ -2168,14 +2181,11 @@ lcs_new_device(struct ccwgroup_device *c
 		goto out;
 	card->dev = dev;
 	card->dev->ml_priv = card;
-	card->dev->open = lcs_open_device;
-	card->dev->stop = lcs_stop_device;
-	card->dev->hard_start_xmit = lcs_start_xmit;
-	card->dev->get_stats = lcs_getstats;
+	card->dev->netdev_ops = &lcs_netdev_ops;
 	memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
 #ifdef CONFIG_IP_MULTICAST
 	if (!lcs_check_multicast_support(card))
-		card->dev->set_multicast_list = lcs_set_multicast_list;
+		card->dev->netdev_ops = &lcs_mc_netdev_ops;
 #endif
 netdev_out:
 	lcs_set_allowed_threads(card,0xffffffff);
@@ -2258,7 +2268,6 @@ lcs_recovery(void *ptr)
         int rc;
 
 	card = (struct lcs_card *) ptr;
-	daemonize("lcs_recover");
 
 	LCS_DBF_TEXT(4, trace, "recover1");
 	if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD))
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/Makefile linux-libre-2.6.30-gnu1/drivers/s390/net/Makefile
--- linux-libre-2.6.29-gnu1/drivers/s390/net/Makefile	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/Makefile	2009-06-09 23:05:27.000000000 -0400
@@ -8,7 +8,7 @@ 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
-qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_core_offl.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
 obj-$(CONFIG_QETH_L2) += qeth_l2.o
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/netiucv.c linux-libre-2.6.30-gnu1/drivers/s390/net/netiucv.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/netiucv.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/netiucv.c	2009-06-09 23:05:27.000000000 -0400
@@ -1312,7 +1312,7 @@ static int netiucv_tx(struct sk_buff *sk
 
 	if (netiucv_test_and_set_busy(dev)) {
 		IUCV_DBF_TEXT(data, 2, "EBUSY from netiucv_tx\n");
-		return -EBUSY;
+		return NETDEV_TX_BUSY;
 	}
 	dev->trans_start = jiffies;
 	rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
@@ -1876,20 +1876,24 @@ static void netiucv_free_netdevice(struc
 /**
  * Initialize a net device. (Called from kernel in alloc_netdev())
  */
+static const struct net_device_ops netiucv_netdev_ops = {
+	.ndo_open		= netiucv_open,
+	.ndo_stop		= netiucv_close,
+	.ndo_get_stats		= netiucv_stats,
+	.ndo_start_xmit		= netiucv_tx,
+	.ndo_change_mtu	   	= netiucv_change_mtu,
+};
+
 static void netiucv_setup_netdevice(struct net_device *dev)
 {
 	dev->mtu	         = NETIUCV_MTU_DEFAULT;
-	dev->hard_start_xmit     = netiucv_tx;
-	dev->open	         = netiucv_open;
-	dev->stop	         = netiucv_close;
-	dev->get_stats	         = netiucv_stats;
-	dev->change_mtu          = netiucv_change_mtu;
 	dev->destructor          = netiucv_free_netdevice;
 	dev->hard_header_len     = NETIUCV_HDRLEN;
 	dev->addr_len            = 0;
 	dev->type                = ARPHRD_SLIP;
 	dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;
 	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;
+	dev->netdev_ops		 = &netiucv_netdev_ops;
 }
 
 /**
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core.h linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core.h
--- linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core.h	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core.h	2009-06-09 23:05:27.000000000 -0400
@@ -134,6 +134,7 @@ struct qeth_perf_stats {
 	unsigned int sg_skbs_rx;
 	unsigned int sg_frags_rx;
 	unsigned int sg_alloc_page_rx;
+	unsigned int tx_csum;
 };
 
 /* Routing stuff */
@@ -403,7 +404,6 @@ struct qeth_qdio_q {
 /* possible types of qeth large_send support */
 enum qeth_large_send_types {
 	QETH_LARGE_SEND_NO,
-	QETH_LARGE_SEND_EDDP,
 	QETH_LARGE_SEND_TSO,
 };
 
@@ -838,11 +838,9 @@ int qeth_get_cast_type(struct qeth_card
 int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
 int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
 int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
-			struct sk_buff *, struct qeth_hdr *, int,
-			struct qeth_eddp_context *, int, int);
+			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, struct qeth_eddp_context *);
+		    struct sk_buff *, struct qeth_hdr *, int);
 int qeth_core_get_stats_count(struct net_device *);
 void qeth_core_get_ethtool_stats(struct net_device *,
 				struct ethtool_stats *, u64 *);
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core_main.c linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core_main.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core_main.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core_main.c	2009-06-09 23:05:27.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/ip.h>
-#include <linux/ipv6.h>
 #include <linux/tcp.h>
 #include <linux/mii.h>
 #include <linux/kthread.h>
@@ -26,7 +25,6 @@
 #include <asm/io.h>
 
 #include "qeth_core.h"
-#include "qeth_core_offl.h"
 
 struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
 	/* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
@@ -285,17 +283,6 @@ int qeth_set_large_send(struct qeth_card
 		netif_tx_disable(card->dev);
 	card->options.large_send = type;
 	switch (card->options.large_send) {
-	case QETH_LARGE_SEND_EDDP:
-		if (card->info.type != QETH_CARD_TYPE_IQD) {
-			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;
 	case QETH_LARGE_SEND_TSO:
 		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
 			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
@@ -956,7 +943,6 @@ static void qeth_clear_output_buffer(str
 		dev_kfree_skb_any(skb);
 		skb = skb_dequeue(&buf->skb_list);
 	}
-	qeth_eddp_buf_release_contexts(buf);
 	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
 		if (buf->buffer->element[i].addr && buf->is_header[i])
 			kmem_cache_free(qeth_core_header_cache,
@@ -1690,7 +1676,7 @@ int qeth_send_control_data(struct qeth_c
 	int rc;
 	unsigned long flags;
 	struct qeth_reply *reply = NULL;
-	unsigned long timeout;
+	unsigned long timeout, event_timeout;
 	struct qeth_ipa_cmd *cmd;
 
 	QETH_DBF_TEXT(TRACE, 2, "sendctl");
@@ -1715,9 +1701,10 @@ int qeth_send_control_data(struct qeth_c
 	qeth_prepare_control_data(card, len, iob);
 
 	if (IS_IPA(iob->data))
-		timeout = jiffies + QETH_IPA_TIMEOUT;
+		event_timeout = QETH_IPA_TIMEOUT;
 	else
-		timeout = jiffies + QETH_TIMEOUT;
+		event_timeout = QETH_TIMEOUT;
+	timeout = jiffies + event_timeout;
 
 	QETH_DBF_TEXT(TRACE, 6, "noirqpnd");
 	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
@@ -1745,7 +1732,7 @@ int qeth_send_control_data(struct qeth_c
 	if ((cmd->hdr.command == IPA_CMD_SETIP) &&
 	    (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
 		if (!wait_event_timeout(reply->wait_q,
-		    atomic_read(&reply->received), timeout))
+		    atomic_read(&reply->received), event_timeout))
 			goto time_err;
 	} else {
 		while (!atomic_read(&reply->received)) {
@@ -2693,40 +2680,21 @@ static int qeth_handle_send_error(struct
 		struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
 {
 	int sbalf15 = buffer->buffer->element[15].flags & 0xff;
-	int cc = qdio_err & 3;
 
 	QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
 	qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
-	switch (cc) {
-	case 0:
-		if (qdio_err) {
-			QETH_DBF_TEXT(TRACE, 1, "lnkfail");
-			QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-			QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
-				       (u16)qdio_err, (u8)sbalf15);
-			return QETH_SEND_ERROR_LINK_FAILURE;
-		}
+
+	if (!qdio_err)
 		return QETH_SEND_ERROR_NONE;
-	case 2:
-		if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
-			QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
-			QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-			return QETH_SEND_ERROR_KICK_IT;
-		}
-		if ((sbalf15 >= 15) && (sbalf15 <= 31))
-			return QETH_SEND_ERROR_RETRY;
-		return QETH_SEND_ERROR_LINK_FAILURE;
-		/* look at qdio_error and sbalf 15 */
-	case 1:
-		QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
-		QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-		return QETH_SEND_ERROR_LINK_FAILURE;
-	case 3:
-	default:
-		QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
-		QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-		return QETH_SEND_ERROR_KICK_IT;
-	}
+
+	if ((sbalf15 >= 15) && (sbalf15 <= 31))
+		return QETH_SEND_ERROR_RETRY;
+
+	QETH_DBF_TEXT(TRACE, 1, "lnkfail");
+	QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
+	QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
+		       (u16)qdio_err, (u8)sbalf15);
+	return QETH_SEND_ERROR_LINK_FAILURE;
 }
 
 /*
@@ -2862,10 +2830,14 @@ static void qeth_flush_buffers(struct qe
 			qeth_get_micros() -
 			queue->card->perf_stats.outbound_do_qdio_start_time;
 	if (rc) {
+		queue->card->stats.tx_errors += count;
+		/* ignore temporary SIGA errors without busy condition */
+		if (rc == QDIO_ERROR_SIGA_TARGET)
+			return;
 		QETH_DBF_TEXT(TRACE, 2, "flushbuf");
 		QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
 		QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
-		queue->card->stats.tx_errors += count;
+
 		/* this must not happen under normal circumstances. if it
 		 * happens something is really wrong -> recover */
 		qeth_schedule_recovery(queue->card);
@@ -2940,13 +2912,7 @@ void qeth_qdio_output_handler(struct ccw
 	}
 	for (i = first_element; i < (first_element + count); ++i) {
 		buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-		/*we only handle the KICK_IT error by doing a recovery */
-		if (qeth_handle_send_error(card, buffer, qdio_error)
-				== QETH_SEND_ERROR_KICK_IT){
-			netif_stop_queue(card->dev);
-			qeth_schedule_recovery(card);
-			return;
-		}
+		qeth_handle_send_error(card, buffer, qdio_error);
 		qeth_clear_output_buffer(queue, buffer);
 	}
 	atomic_sub(count, &queue->used_buffers);
@@ -3187,11 +3153,9 @@ static inline int qeth_fill_buffer(struc
 int qeth_do_send_packet_fast(struct qeth_card *card,
 		struct qeth_qdio_out_q *queue, struct sk_buff *skb,
 		struct qeth_hdr *hdr, int elements_needed,
-		struct qeth_eddp_context *ctx, int offset, int hd_len)
+		int offset, int hd_len)
 {
 	struct qeth_qdio_out_buffer *buffer;
-	int buffers_needed = 0;
-	int flush_cnt = 0;
 	int index;
 
 	/* spin until we get the queue ... */
@@ -3206,27 +3170,11 @@ int qeth_do_send_packet_fast(struct qeth
 	 */
 	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
 		goto out;
-	if (ctx == NULL)
-		queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
+	queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
 					  QDIO_MAX_BUFFERS_PER_Q;
-	else {
-		buffers_needed = qeth_eddp_check_buffers_for_context(queue,
-									ctx);
-		if (buffers_needed < 0)
-			goto out;
-		queue->next_buf_to_fill =
-			(queue->next_buf_to_fill + buffers_needed) %
-			QDIO_MAX_BUFFERS_PER_Q;
-	}
 	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
-	if (ctx == NULL) {
-		qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
-		qeth_flush_buffers(queue, index, 1);
-	} else {
-		flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
-		WARN_ON(buffers_needed != flush_cnt);
-		qeth_flush_buffers(queue, index, flush_cnt);
-	}
+	qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
+	qeth_flush_buffers(queue, index, 1);
 	return 0;
 out:
 	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3236,7 +3184,7 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet_fa
 
 int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
 		struct sk_buff *skb, struct qeth_hdr *hdr,
-		int elements_needed, struct qeth_eddp_context *ctx)
+		int elements_needed)
 {
 	struct qeth_qdio_out_buffer *buffer;
 	int start_index;
@@ -3262,53 +3210,32 @@ int qeth_do_send_packet(struct qeth_card
 	qeth_switch_to_packing_if_needed(queue);
 	if (queue->do_pack) {
 		do_pack = 1;
-		if (ctx == NULL) {
-			/* does packet fit in current buffer? */
-			if ((QETH_MAX_BUFFER_ELEMENTS(card) -
-			    buffer->next_element_to_fill) < elements_needed) {
-				/* ... no -> set state PRIMED */
-				atomic_set(&buffer->state,
-					QETH_QDIO_BUF_PRIMED);
-				flush_count++;
-				queue->next_buf_to_fill =
-					(queue->next_buf_to_fill + 1) %
-					QDIO_MAX_BUFFERS_PER_Q;
-				buffer = &queue->bufs[queue->next_buf_to_fill];
-				/* we did a step forward, so check buffer state
-				 * again */
-				if (atomic_read(&buffer->state) !=
-						QETH_QDIO_BUF_EMPTY){
-					qeth_flush_buffers(queue, start_index,
+		/* does packet fit in current buffer? */
+		if ((QETH_MAX_BUFFER_ELEMENTS(card) -
+		    buffer->next_element_to_fill) < elements_needed) {
+			/* ... no -> set state PRIMED */
+			atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
+			flush_count++;
+			queue->next_buf_to_fill =
+				(queue->next_buf_to_fill + 1) %
+				QDIO_MAX_BUFFERS_PER_Q;
+			buffer = &queue->bufs[queue->next_buf_to_fill];
+			/* we did a step forward, so check buffer state
+			 * again */
+			if (atomic_read(&buffer->state) !=
+			    QETH_QDIO_BUF_EMPTY) {
+				qeth_flush_buffers(queue, start_index,
 							   flush_count);
-					atomic_set(&queue->state,
+				atomic_set(&queue->state,
 						QETH_OUT_Q_UNLOCKED);
-					return -EBUSY;
-				}
-			}
-		} else {
-			/* check if we have enough elements (including following
-			 * free buffers) to handle eddp context */
-			if (qeth_eddp_check_buffers_for_context(queue, ctx)
-				< 0) {
-				rc = -EBUSY;
-				goto out;
+				return -EBUSY;
 			}
 		}
 	}
-	if (ctx == NULL)
-		tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
-	else {
-		tmp = qeth_eddp_fill_buffer(queue, ctx,
-						queue->next_buf_to_fill);
-		if (tmp < 0) {
-			rc = -EBUSY;
-			goto out;
-		}
-	}
+	tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
 	queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
 				  QDIO_MAX_BUFFERS_PER_Q;
 	flush_count += tmp;
-out:
 	if (flush_count)
 		qeth_flush_buffers(queue, start_index, flush_count);
 	else if (!atomic_read(&queue->set_pci_flags_count))
@@ -4327,6 +4254,7 @@ static struct {
 /* 30 */{"tx count"},
 	{"tx do_QDIO time"},
 	{"tx do_QDIO count"},
+	{"tx csum"},
 };
 
 int qeth_core_get_stats_count(struct net_device *dev)
@@ -4378,6 +4306,7 @@ void qeth_core_get_ethtool_stats(struct
 	data[30] = card->perf_stats.outbound_cnt;
 	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;
 }
 EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
 
diff -druNp linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core_offl.c linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core_offl.c
--- linux-libre-2.6.29-gnu1/drivers/s390/net/qeth_core_offl.c	2009-03-23 19:12:14.000000000 -0400
+++ linux-libre-2.6.30-gnu1/drivers/s390/net/qeth_core_offl.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,699 +0,0 @@
-/*
- *  drivers/s390/net/qeth_core_offl.c
- *
- *    Copyright IBM Corp. 2007
- *    Author(s): Thomas Spatzier <tspat@de.ibm.com>,
- *		 Frank Blaschka <frank.blaschka@de.ibm.com>
- */
-
-#include <linux/errno.h>
-#include <linux/ip.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/kernel.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-#include <net/ip6_checksum.h>
-
-#include "qeth_core.h"
-#include "qeth_core_mpc.h"
-#include "qeth_core_offl.h"
-
-int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
-		struct qeth_eddp_context *ctx)
-{
-	int index = queue->next_buf_to_fill;
-	int elements_needed = ctx->num_elements;
-	int elements_in_buffer;
-	int skbs_in_buffer;
-	int buffers_needed = 0;
-
-	QETH_DBF_TEXT(TRACE, 5, "eddpcbfc");
-	while (elements_needed > 0) {
-		buffers_needed++;
-		if (atomic_read(&queue->bufs[index].state) !=
-				QETH_QDIO_BUF_EMPTY)
-			return -EBUSY;
-
-		elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
-				     queue->bufs[index].next_element_to_fill;
-		skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
-		elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
-		index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
-	}
-	return buffers_needed;
-}
-
-static void qeth_eddp_free_context(struct qeth_eddp_context *ctx)
-{
-	int i;
-
-	QETH_DBF_TEXT(TRACE, 5, "eddpfctx");
-	for (i = 0; i < ctx->num_pages; ++i)
-		free_page((unsigned long)ctx->pages[i]);
-	kfree(ctx->pages);
-	kfree(ctx->elements);
-	kfree(ctx);
-}
-
-
-static void qeth_eddp_get_context(struct qeth_eddp_context *ctx)
-{
-	atomic_inc(&ctx->refcnt);
-}
-
-void qeth_eddp_put_context(struct qeth_eddp_context *ctx)
-{
-	if (atomic_dec_return(&ctx->refcnt) == 0)
-		qeth_eddp_free_context(ctx);
-}
-EXPORT_SYMBOL_GPL(qeth_eddp_put_context);
-
-void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
-{
-	struct qeth_eddp_context_reference *ref;
-
-	QETH_DBF_TEXT(TRACE, 6, "eddprctx");
-	while (!list_empty(&buf->ctx_list)) {
-		ref = list_entry(buf->ctx_list.next,
-				 struct qeth_eddp_context_reference, list);
-		qeth_eddp_put_context(ref->ctx);
-		list_del(&ref->list);
-		kfree(ref);
-	}
-}
-
-static int qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
-		struct qeth_eddp_context *ctx)
-{
-	struct qeth_eddp_context_reference *ref;
-
-	QETH_DBF_TEXT(TRACE, 6, "eddprfcx");
-	ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
-	if (ref == NULL)
-		return -ENOMEM;
-	qeth_eddp_get_context(ctx);
-	ref->ctx = ctx;
-	list_add_tail(&ref->list, &buf->ctx_list);
-	return 0;
-}
-
-int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
-		struct qeth_eddp_context *ctx, int index)
-{
-	struct qeth_qdio_out_buffer *buf = NULL;
-	struct qdio_buffer *buffer;
-	int elements = ctx->num_elements;
-	int element = 0;
-	int flush_cnt = 0;
-	int must_refcnt = 1;
-	int i;
-
-	QETH_DBF_TEXT(TRACE, 5, "eddpfibu");
-	while (elements > 0) {
-		buf = &queue->bufs[index];
-		if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY) {
-			/* normally this should not happen since we checked for
-			 * available elements in qeth_check_elements_for_context
-			 */
-			if (element == 0)
-				return -EBUSY;
-			else {
-				QETH_DBF_MESSAGE(2, "could only partially fill"
-					"eddp buffer!\n");
-				goto out;
-			}
-		}
-		/* check if the whole next skb fits into current buffer */
-		if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
-					buf->next_element_to_fill)
-				< ctx->elements_per_skb){
-			/* no -> go to next buffer */
-			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-			index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
-			flush_cnt++;
-			/* new buffer, so we have to add ctx to buffer'ctx_list
-			 * and increment ctx's refcnt */
-			must_refcnt = 1;
-			continue;
-		}
-		if (must_refcnt) {
-			must_refcnt = 0;
-			if (qeth_eddp_buf_ref_context(buf, ctx)) {
-				goto out_check;
-			}
-		}
-		buffer = buf->buffer;
-		/* fill one skb into buffer */
-		for (i = 0; i < ctx->elements_per_skb; ++i) {
-			if (ctx->elements[element].length != 0) {
-				buffer->element[buf->next_element_to_fill].
-				addr = ctx->elements[element].addr;
-				buffer->element[buf->next_element_to_fill].
-				length = ctx->elements[element].length;
-				buffer->element[buf->next_element_to_fill].
-				flags = ctx->elements[element].flags;
-				buf->next_element_to_fill++;
-			}
-			element++;
-			elements--;
-		}
-	}
-out_check:
-	if (!queue->do_pack) {
-		QETH_DBF_TEXT(TRACE, 6, "fillbfnp");
-		/* set state to PRIMED -> will be flushed */
-		if (buf->next_element_to_fill > 0) {
-			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-			flush_cnt++;
-		}
-	} else {
-		if (queue->card->options.performance_stats)
-			queue->card->perf_stats.skbs_sent_pack++;
-		QETH_DBF_TEXT(TRACE, 6, "fillbfpa");
-		if (buf->next_element_to_fill >=
-				QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
-			/*
-			 * packed buffer if full -> set state PRIMED
-			 * -> will be flushed
-			 */
-			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-			flush_cnt++;
-		}
-	}
-out:
-	return flush_cnt;
-}
-
-static void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
-		struct qeth_eddp_data *eddp, int data_len)
-{
-	u8 *page;
-	int page_remainder;
-	int page_offset;
-	int pkt_len;
-	struct qeth_eddp_element *element;
-
-	QETH_DBF_TEXT(TRACE, 5, "eddpcrsh");
-	page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-	page_offset = ctx->offset % PAGE_SIZE;
-	element = &ctx->elements[ctx->num_elements];
-	pkt_len = eddp->nhl + eddp->thl + data_len;
-	/* FIXME: layer2 and VLAN !!! */
-	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
-		pkt_len += ETH_HLEN;
-	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
-		pkt_len += VLAN_HLEN;
-	/* does complete packet fit in current page ? */
-	page_remainder = PAGE_SIZE - page_offset;
-	if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)) {
-		/* no -> go to start of next page */
-		ctx->offset += page_remainder;
-		page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-		page_offset = 0;
-	}
-	memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
-	element->addr = page + page_offset;
-	element->length = sizeof(struct qeth_hdr);
-	ctx->offset += sizeof(struct qeth_hdr);
-	page_offset += sizeof(struct qeth_hdr);
-	/* add mac header (?) */
-	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
-		memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
-		element->length += ETH_HLEN;
-		ctx->offset += ETH_HLEN;
-		page_offset += ETH_HLEN;
-	}
-	/* add VLAN tag */
-	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
-		memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
-		element->length += VLAN_HLEN;
-		ctx->offset += VLAN_HLEN;
-		page_offset += VLAN_HLEN;
-	}
-	/* add network header */
-	memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
-	element->length += eddp->nhl;
-	eddp->nh_in_ctx = page + page_offset;
-	ctx->offset += eddp->nhl;
-	page_offset += eddp->nhl;
-	/* add transport header */
-	memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
-	element->length += eddp->thl;
-	eddp->th_in_ctx = page + page_offset;
-	ctx->offset += eddp->thl;
-}
-
-static void qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp,
-		int len, __wsum *hcsum)
-{
-	struct skb_frag_struct *frag;
-	int left_in_frag;
-	int copy_len;
-	u8 *src;
-
-	QETH_DBF_TEXT(TRACE, 5, "eddpcdtc");
-	if (skb_shinfo(eddp->skb)->nr_frags == 0) {
-		skb_copy_from_linear_data_offset(eddp->skb, eddp->skb_offset,
-						 dst, len);
-		*hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
-				      *hcsum);
-		eddp->skb_offset += len;
-	} else {
-		while (len > 0) {
-			if (eddp->frag < 0) {
-				/* we're in skb->data */
-				left_in_frag = (eddp->skb->len -
-						eddp->skb->data_len)
-						- eddp->skb_offset;
-				src = eddp->skb->data + eddp->skb_offset;
-			} else {
-				frag = &skb_shinfo(eddp->skb)->frags[
-					eddp->frag];
-				left_in_frag = frag->size - eddp->frag_offset;
-				src = (u8 *)((page_to_pfn(frag->page) <<
-					PAGE_SHIFT) + frag->page_offset +
-					eddp->frag_offset);
-			}
-			if (left_in_frag <= 0) {
-				eddp->frag++;
-				eddp->frag_offset = 0;
-				continue;
-			}
-			copy_len = min(left_in_frag, len);
-			memcpy(dst, src, copy_len);
-			*hcsum = csum_partial(src, copy_len, *hcsum);
-			dst += copy_len;
-			eddp->frag_offset += copy_len;
-			eddp->skb_offset += copy_len;
-			len -= copy_len;
-		}
-	}
-}
-
-static void qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
-		struct qeth_eddp_data *eddp, int data_len, __wsum hcsum)
-{
-	u8 *page;
-	int page_remainder;
-	int page_offset;
-	struct qeth_eddp_element *element;
-	int first_lap = 1;
-
-	QETH_DBF_